source: dev/BasicCompiler64/NumOpe_Arithmetic.cpp@ 145

Last change on this file since 145 was 75, checked in by dai_9181, 18 years ago

TYPEINFO→Typeへのリファクタリングを実施。64bitはほぼ完了。32bitが全般的に未完成。

File size: 15.1 KB
RevLine 
[3]1#include "../BasicCompiler_Common/common.h"
2#include "Opcode.h"
3
4BOOL CalcTwoTerm_Arithmetic(int idCalc,int *type,LONG_PTR *index_stack,int *pStackPointer){
5 /* value[sp-2] = value[sp-2] + value[sp-1]
6 value[sp-2] = value[sp-2] - value[sp-1]
7 value[sp-2] = value[sp-2] * value[sp-1] */
8
9 int reg1,reg2;
10
11 int sp;
12 sp=*pStackPointer;
13
14 int AnswerType;
15 AnswerType=NeutralizationType(type[sp-2],index_stack[sp-2],type[sp-1],index_stack[sp-1]);
16
17 if(type[sp-2]==DEF_DOUBLE||type[sp-2]==DEF_SINGLE||
18 type[sp-1]==DEF_DOUBLE||type[sp-1]==DEF_SINGLE){
19 /////////////
20 // 実数演算
21 /////////////
22
23 int xmm_reg1,xmm_reg2;
24
25 //2つの項を適切なレジスタにセット
26 SetTowTermToReg_RealCalc(AnswerType,type,sp,&xmm_reg1,&xmm_reg2);
27
28 if(AnswerType==DEF_DOUBLE){
29 ///////////////////////
30 // Double演算
31 ///////////////////////
32
33 if(idCalc==CALC_ADDITION){
34 //addsd xmm_reg1,xmm_reg2
35 OpBuffer[obp++]=(char)0xF2;
36 OpBuffer[obp++]=(char)0x0F;
37 OpBuffer[obp++]=(char)0x58;
38 OpBuffer[obp++]=(char)(0xC0 | REGISTER_OPERAND(xmm_reg1)<<3 | REGISTER_OPERAND(xmm_reg2));
39 }
40 else if(idCalc==CALC_SUBTRACTION){
41 //subsd xmm_reg1,xmm_reg2
42 OpBuffer[obp++]=(char)0xF2;
43 OpBuffer[obp++]=(char)0x0F;
44 OpBuffer[obp++]=(char)0x5C;
45 OpBuffer[obp++]=(char)(0xC0 | REGISTER_OPERAND(xmm_reg1)<<3 | REGISTER_OPERAND(xmm_reg2));
46 }
47 else if(idCalc==CALC_PRODUCT){
48 //mulsd xmm_reg1,xmm_reg2
49 OpBuffer[obp++]=(char)0xF2;
50 OpBuffer[obp++]=(char)0x0F;
51 OpBuffer[obp++]=(char)0x59;
52 OpBuffer[obp++]=(char)(0xC0 | REGISTER_OPERAND(xmm_reg1)<<3 | REGISTER_OPERAND(xmm_reg2));
53 }
54
55 if(xmm_reg1==REG_XMM4){
56 //movsd qword ptr[rsp+offset],xmm4 ※スタックフレームを利用
57 pobj_sf->push(REG_XMM4,sizeof(double));
58 }
59 }
60 if(AnswerType==DEF_SINGLE){
61 ///////////////////////
62 // Single演算
63 ///////////////////////
64
65 if(idCalc==CALC_ADDITION){
66 //addss xmm_reg1,xmm_reg2
67 OpBuffer[obp++]=(char)0xF3;
68 OpBuffer[obp++]=(char)0x0F;
69 OpBuffer[obp++]=(char)0x58;
70 OpBuffer[obp++]=(char)(0xC0 | REGISTER_OPERAND(xmm_reg1)<<3 | REGISTER_OPERAND(xmm_reg2));
71 }
72 else if(idCalc==CALC_SUBTRACTION){
73 //subss xmm_reg1,xmm_reg2
74 OpBuffer[obp++]=(char)0xF3;
75 OpBuffer[obp++]=(char)0x0F;
76 OpBuffer[obp++]=(char)0x5C;
77 OpBuffer[obp++]=(char)(0xC0 | REGISTER_OPERAND(xmm_reg1)<<3 | REGISTER_OPERAND(xmm_reg2));
78 }
79 else if(idCalc==CALC_PRODUCT){
80 //mulss xmm_reg1,xmm_reg2
81 OpBuffer[obp++]=(char)0xF3;
82 OpBuffer[obp++]=(char)0x0F;
83 OpBuffer[obp++]=(char)0x59;
84 OpBuffer[obp++]=(char)(0xC0 | REGISTER_OPERAND(xmm_reg1)<<3 | REGISTER_OPERAND(xmm_reg2));
85 }
86
87 if(xmm_reg1==REG_XMM4){
88 //movss dword ptr[rsp+offset],xmm4 ※スタックフレームを利用
89 pobj_sf->push(REG_XMM4,sizeof(float));
90 }
91 }
92 }
93 else if(Is64Type(type[sp-2])||Is64Type(type[sp-1])){
94 //////////////////////
95 // 64ビット整数演算
96 //////////////////////
97
98 SetTowTermToReg_Whole64Calc(type,sp,&reg1,&reg2);
99
100 if(idCalc==CALC_ADDITION){
101 //add reg1,reg2
102 op_add64_reg(reg1,reg2);
103 }
104 else if(idCalc==CALC_SUBTRACTION){
105 //sub reg1,reg2
106 op_sub64_reg(reg1,reg2);
107 }
108 else if(idCalc==CALC_PRODUCT){
109 //mul reg1,reg2
[64]110 op_imul_RR(sizeof(_int64),reg1,reg2);
[3]111 }
112
113 if(reg1==REG_R14){
114 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
115 pobj_sf->push(REG_R14);
116 }
117 }
118 else{
119 //32ビット以下の整数演算
120
121 SetTowTermToReg_Whole32Calc(type,sp,&reg1,&reg2);
122
123 if(idCalc==CALC_ADDITION){
124 //add reg1,reg2
125 op_add32_reg(reg1,reg2);
126 }
127 else if(idCalc==CALC_SUBTRACTION){
128 //sub reg1,reg2
129 op_sub32_reg(reg1,reg2);
130 }
131 else if(idCalc==CALC_PRODUCT){
132 //mul reg1,reg2
[64]133 op_imul_RR(sizeof(long),reg1,reg2);
[3]134 }
135
136 if(reg1==REG_R14){
137 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
138 pobj_sf->push(REG_R14);
139 }
140 }
141
142 sp--;
143 type[sp-1]=AnswerType;
144
145 *pStackPointer=sp;
146
147 return 1;
148}
149
150
151
152BOOL Calc_Mod(int *type,LONG_PTR *index_stack,int *pStackPointer){
153 //value[sp-2]%=value[sp-1]
154 //剰余演算
155
156 int reg1,reg2;
157 int AnswerType;
158
159 int sp;
160 sp=*pStackPointer;
161
162 if(IsRealNumberType(type[sp-2])||IsRealNumberType(type[sp-1])){
163 //実数演算は行えないため、エラー扱い
164 SetError(45,"mod",cp);
165 return 0;
166 }
167
168 /////////////////////////
169 // 64ビット整数演算のみ
170 /////////////////////////
171
172 AnswerType=NeutralizationType(type[sp-2],index_stack[sp-2],type[sp-1],index_stack[sp-1]);
173
174 //2つの項を適切なレジスタにセット
175 SetTowTermToReg_Whole64Calc(type,sp,&reg1,&reg2);
176
177 if(reg2==REG_RAX||reg2==REG_RDX){
178 //mov r15,reg2
[64]179 op_mov_RR(REG_R15,reg2);
[3]180
181 reg2=REG_R15;
182 }
183
[19]184 //raxまたはrdxが使用中かどうかを調べる( true/使用中, false/未使用 )
185 bool isUsingRax = pobj_reg->IsUsing( REG_RAX );
186 bool isUsingRdx = pobj_reg->IsUsing( REG_RDX );
[3]187
[19]188 if(reg1!=REG_RDX && isUsingRdx){
189 //結果レジスタがrdxでない場合(使用されている可能性があるとき)
190
[3]191 //mov qword ptr[rsp+offset],rdx ※スタックフレームを利用
192 pobj_sf->push(REG_RDX);
193 }
194
[19]195 if(reg1!=REG_RAX && isUsingRax){
196 //結果レジスタがraxでない場合(使用されている可能性があるとき)
[3]197
[19]198 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
199 pobj_sf->push(REG_RAX);
[3]200 }
201
[19]202 {
203
204 //mov rax,reg1
[64]205 op_mov_RR(REG_RAX,reg1);
[19]206
207 if(IsSignedType(type[sp-2])){
208 //符号拡張
209 //rdx:rax ← rax
210
211 //cqo
212 OpBuffer[obp++]=(char)0x48;
213 OpBuffer[obp++]=(char)0x99;
214 }
215 else{
216 //ビット拡張
217 //rdx:rax ← rax
218
219 //xor rdx,rdx
220 op_zero_reg(REG_RDX);
221 }
222
223 if(IsSignedType(AnswerType)){
224 //idiv reg2
225 op_idiv64_reg(reg2);
226 }
227 else{
228 //div reg2
229 op_div64_reg(reg2);
230 }
231
232 //mov reg1,rdx
[64]233 op_mov_RR(reg1,REG_RDX);
[19]234
[3]235 }
236
[19]237 if(reg1!=REG_RAX && isUsingRax){
238 //結果レジスタがraxでない場合(使用されている可能性があるとき)
239
240 //mov rax,qword ptr[rsp+offset] ※スタックフレームを利用
241 pobj_sf->pop(REG_RAX);
[3]242 }
243
[19]244 if(reg1!=REG_RDX && isUsingRdx){
245 //結果レジスタがrdxでない場合(使用されている可能性があるとき)
[3]246
247 //mov rdx,qword ptr[rsp+offset] ※スタックフレームを利用
248 pobj_sf->pop(REG_RDX);
249 }
250
[19]251
[3]252 if(reg1==REG_R14){
253 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
254 pobj_sf->push(REG_R14);
255 }
256
257 sp--;
258 type[sp-1]=AnswerType;
259
260
261 *pStackPointer=sp;
262
263 return 1;
264}
265
266BOOL Calc_Divide(int *type,int *pStackPointer,int BaseType){
267 //value[sp-2]/=value[sp-1];
268 //除算
269
270 int sp;
271 sp=*pStackPointer;
272
273 ///////////////////////
274 // 実数演算のみ
275 ///////////////////////
276
277 int AnswerType;
278 if(type[sp-2]==DEF_SINGLE&&type[sp-1]==DEF_SINGLE&&BaseType==DEF_SINGLE) AnswerType=DEF_SINGLE;
279 else AnswerType=DEF_DOUBLE;
280
281 int xmm_reg1,xmm_reg2;
282
283 //2つの項を適切なレジスタにセット
284 SetTowTermToReg_RealCalc(AnswerType,type,sp,&xmm_reg1,&xmm_reg2);
285
286 if(AnswerType==DEF_DOUBLE){
287 ///////////////////////
288 // Double演算
289 ///////////////////////
290
291 //divsd xmm_reg1,xmm_reg2
292 OpBuffer[obp++]=(char)0xF2;
293 OpBuffer[obp++]=(char)0x0F;
294 OpBuffer[obp++]=(char)0x5E;
295 OpBuffer[obp++]=(char)(0xC0 | REGISTER_OPERAND(xmm_reg1)<<3 | REGISTER_OPERAND(xmm_reg2));
296
297 if(xmm_reg1==REG_XMM4){
298 //movsd qword ptr[rsp+offset],xmm4 ※スタックフレームを利用
299 pobj_sf->push(REG_XMM4,sizeof(double));
300 }
301 }
302 if(AnswerType==DEF_SINGLE){
303 ///////////////////////
304 // Single演算
305 ///////////////////////
306
307 //divss xmm_reg1,xmm_reg2
308 OpBuffer[obp++]=(char)0xF3;
309 OpBuffer[obp++]=(char)0x0F;
310 OpBuffer[obp++]=(char)0x5E;
311 OpBuffer[obp++]=(char)(0xC0 | REGISTER_OPERAND(xmm_reg1)<<3 | REGISTER_OPERAND(xmm_reg2));
312
313 if(xmm_reg1==REG_XMM4){
314 //movss dword ptr[rsp+offset],xmm4 ※スタックフレームを利用
315 pobj_sf->push(REG_XMM4,sizeof(float));
316 }
317 }
318
319 sp--;
320 type[sp-1]=AnswerType;
321
322
323 *pStackPointer=sp;
324
325 return 1;
326}
327
328BOOL Calc_IntDivide(int *type,LONG_PTR *index_stack,int *pStackPointer){
329 //value[sp-2]/=value[sp-1]
330 //除算(整数)
331
332 int reg1,reg2;
333 int AnswerType;
334
335 int sp;
336 sp=*pStackPointer;
337
338 if(IsRealNumberType(type[sp-2])||IsRealNumberType(type[sp-1])){
339 //実数演算は行えないため、エラー扱い
340 SetError(45,"mod",cp);
341 return 0;
342 }
343
344 /////////////////////////
345 // 64ビット整数演算のみ
346 /////////////////////////
347
348 AnswerType=NeutralizationType(type[sp-2],index_stack[sp-2],type[sp-1],index_stack[sp-1]);
349
350 //2つの項を適切なレジスタにセット
351 SetTowTermToReg_Whole64Calc(type,sp,&reg1,&reg2);
352
353 if(reg2==REG_RAX||reg2==REG_RDX){
354 //mov r15,reg2
[64]355 op_mov_RR(REG_R15,reg2);
[3]356
357 reg2=REG_R15;
358 }
359
[19]360 //raxまたはrdxが使用中かどうかを調べる( true/使用中, false/未使用 )
361 bool isUsingRax = pobj_reg->IsUsing( REG_RAX );
362 bool isUsingRdx = pobj_reg->IsUsing( REG_RDX );
[3]363
[19]364 if(reg1!=REG_RDX && isUsingRdx){
365 //結果レジスタがrdxでない場合(使用されている可能性があるとき)
366
367 //mov qword ptr[rsp+offset],rdx ※スタックフレームを利用
368 pobj_sf->push(REG_RDX);
369 }
370
371 if(reg1!=REG_RAX && isUsingRax){
372 //結果レジスタがraxでない場合(使用されている可能性があるとき)
373
[3]374 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
375 pobj_sf->push(REG_RAX);
376 }
377
[19]378 {
[3]379
[19]380 //mov rax,reg1
[64]381 op_mov_RR(REG_RAX,reg1);
[3]382
[19]383 if(IsSignedType(type[sp-2])){
384 //符号拡張
385 //rdx:rax ← rax
[3]386
[19]387 //cqo
388 OpBuffer[obp++]=(char)0x48;
389 OpBuffer[obp++]=(char)0x99;
390 }
391 else{
392 //ビット拡張
393 //rdx:rax ← rax
[3]394
[19]395 //xor rdx,rdx
396 op_zero_reg(REG_RDX);
397 }
398
399 if(IsSignedType(AnswerType)){
400 //idiv reg2
401 op_idiv64_reg(reg2);
402 }
403 else{
404 //div reg2
405 op_div64_reg(reg2);
406 }
407
408 //mov reg1,rax
[64]409 op_mov_RR(reg1,REG_RAX);
[19]410
[3]411 }
412
[19]413 if(reg1!=REG_RAX && isUsingRax){
414 //結果レジスタがraxでない場合(使用されている可能性があるとき)
[3]415
416 //mov rax,qword ptr[rsp+offset] ※スタックフレームを利用
417 pobj_sf->pop(REG_RAX);
418 }
419
[19]420 if(reg1!=REG_RDX && isUsingRdx){
421 //結果レジスタがrdxでない場合(使用されている可能性があるとき)
[3]422
[19]423 //mov rdx,qword ptr[rsp+offset] ※スタックフレームを利用
424 pobj_sf->pop(REG_RDX);
425 }
[3]426
[19]427
[3]428 if(reg1==REG_R14){
429 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
430 pobj_sf->push(REG_R14);
431 }
432
433 sp--;
434 type[sp-1]=AnswerType;
435
436 *pStackPointer=sp;
437
438 return 1;
439}
440
441BOOL Calc_MinusMark(int *type,int sp){
442 //value[sp-1]=-value[sp-1]
443 //符号反転
444
445 int xmm_reg;
446 int reg;
447 int i32data;
448
449 if(type[sp-1]==DEF_DOUBLE){
450 SetOneTermToReg_RealCalc(type[sp-1],&xmm_reg);
451
452 double dbl;
453 dbl=-1;
[56]454 i32data = dataTable.Add( dbl );
[3]455
456 //mulsd xmm_reg,qword ptr[data table offset] ※data = -1
457 OpBuffer[obp++]=(char)0xF2;
458 OpBuffer[obp++]=(char)0x0F;
459 OpBuffer[obp++]=(char)0x59;
460 OpBuffer[obp++]=(char)(0x04 | REGISTER_OPERAND(xmm_reg)<<3);
461 OpBuffer[obp++]=(char)0x25;
462 *((long *)(OpBuffer+obp))=i32data;
463 pobj_DataTableSchedule->add();
464 obp+=sizeof(long);
465
466 if(xmm_reg==REG_XMM4){
467 //movsd qword ptr[rsp+offset],xmm4 ※スタックフレームを利用
468 pobj_sf->push(REG_XMM4,sizeof(double));
469 }
470 }
471 else if(type[sp-1]==DEF_SINGLE){
472 SetOneTermToReg_RealCalc(type[sp-1],&xmm_reg);
473
474 float flt;
475 flt=-1;
[56]476 i32data = dataTable.Add( flt );
[3]477
478 //mulss xmm_reg,dword ptr[data table offset] ※data = -1
479 OpBuffer[obp++]=(char)0xF3;
480 OpBuffer[obp++]=(char)0x0F;
481 OpBuffer[obp++]=(char)0x59;
482 OpBuffer[obp++]=(char)(0x04 | REGISTER_OPERAND(xmm_reg)<<3);
483 OpBuffer[obp++]=(char)0x25;
484 *((long *)(OpBuffer+obp))=i32data;
485 pobj_DataTableSchedule->add();
486 obp+=sizeof(long);
487
488 if(xmm_reg==REG_XMM4){
489 //movss dword ptr[rsp+offset],xmm4 ※スタックフレームを利用
490 pobj_sf->push(REG_XMM4,sizeof(float));
491 }
492 }
493 else if(type[sp-1]==DEF_INT64||type[sp-1]==DEF_QWORD){
494 SetOneTermToReg_Whole64Calc(type[sp-1],&reg);
495
496 //imul reg,-1
[64]497 op_imul_RV(sizeof(_int64),reg,-1);
[3]498
499 if(reg==REG_R14){
500 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
501 pobj_sf->push(REG_R14);
502 }
503
504 type[sp-1]=DEF_INT64; //QWordはInt64へ
505 }
506 else if(IsWholeNumberType(type[sp-1])){
507 SetOneTermToReg_Whole32Calc(type[sp-1],&reg);
508
509 //imul reg,-1
[64]510 op_imul_RV(sizeof(long),reg,-1);
[3]511
512 if(reg==REG_R14){
513 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
514 pobj_sf->push(REG_R14);
515 }
516
517 type[sp-1]=GetSignedType(type[sp-1]);
518 }
519
520 return 1;
521}
522
523BOOL Calc_Power(int *type,int *pStackPointer){
524 //べき乗(実数演算のみ)
525
526 int sp;
527 sp=*pStackPointer;
528
529
530 //2つの項を適切なレジスタにセット
531 int xmm_reg1,xmm_reg2;
532 SetTowTermToReg_RealCalc(DEF_DOUBLE,type,sp,&xmm_reg1,&xmm_reg2);
533
534
535 //////////////////////////////////////////////////////
536 ///// レジスタ資源のバックアップ
537 { BACKUP_REGISTER_RESOURCE
538 //////////////////////////////////////////////////////
539
540
541 ////////////////
542 // 呼び出し
543 ////////////////
544
545 if(xmm_reg1==REG_XMM1){
546 //movsd xmm0,xmm_reg1
547 op_movsd_RR(REG_XMM0,xmm_reg1);
548
549 //movsd xmm1,xmm_reg2
550 op_movsd_RR(REG_XMM1,xmm_reg2);
551 }
552 else{
553 //movsd xmm1,xmm_reg2
554 op_movsd_RR(REG_XMM1,xmm_reg2);
555
556 //movsd xmm0,xmm_reg1
557 op_movsd_RR(REG_XMM0,xmm_reg1);
558 }
559
560 //call pow
[75]561 extern UserProc *pSub_pow;
[3]562 op_call(pSub_pow);
563
564 //movsd xmm4,xmm0
565 op_movsd_RR(REG_XMM4,REG_XMM0);
566
567
568 /////////////////////////////////////////////
569 ////// レジスタ資源を復元
570 RESTORE_REGISTER_RESOURCE
571 }////////////////////////////////////////////
572
573
574 //////////////////////////////////
575 // 戻り値を所定のレジスタへ格納
576 //////////////////////////////////
577
578 if(xmm_reg1==REG_XMM4){
579 //movsd qword ptr[rsp+offset],xmm4 ※スタックフレームを利用
580 pobj_sf->push(REG_XMM0,sizeof(double));
581 }
582 else{
583 //movsd xmm_reg1,xmm4
584 op_movsd_RR(xmm_reg1,REG_XMM4);
585 }
586
587
588 sp--;
589 type[sp-1]=DEF_DOUBLE;
590
591 *pStackPointer=sp;
592 return 1;
593}
594
595BOOL Calc_Shift(int idCalc,int *type,int *pStackPointer){
596 //ビットシフト
597
598 int sp;
599 sp=*pStackPointer;
600
601 if(IsRealNumberType(type[sp-2])||IsRealNumberType(type[sp-1])){
602 //いずれかの項が実数のとき
603 SetError(45,"<<",cp);
604 return 0;
605 }
606
607
608 /////////////////////////
609 // 64ビット整数演算のみ
610 /////////////////////////
611 int reg1,reg2;
612
613 //2つの項を適切なレジスタにセット
614 SetTowTermToReg_Whole64Calc(type,sp,&reg1,&reg2);
615
616 int sw=0;
617 if(reg1==REG_RCX){
618 //mov r15,rcx
[64]619 op_mov_RR(REG_R15,REG_RCX);
[3]620
621 reg1=REG_R15;
622 }
623 else if(reg2!=REG_RCX){
624 sw=1;
625
626 //mov qword ptr[rsp+offset],rcx ※スタックフレームを利用
627 pobj_sf->push(REG_RCX);
628 }
629
630 //mov rcx,reg2
[64]631 op_mov_RR(REG_RCX,reg2);
[3]632
633 if(idCalc==CALC_SHL){
634 //左シフトは符号あり、なしは同様の動きをする
635
636 //32ビット型にする
637 if(!Is64Type(type[sp-2])){
638 ExtendTypeTo32(type[sp-2],reg1);
639
640 if(IsSignedType(type[sp-2])) type[sp-2]=DEF_LONG;
641 else type[sp-2]=DEF_DWORD;
642 }
643
644 //shl reg1,cl
645 op_shl_reg(GetTypeSize(type[sp-2],-1),reg1);
646 }
647 else if(idCalc==CALC_SHR){
648 if(IsSignedType(type[sp-2])){
649 //符号あり
650
651 //sar
652 op_sar_reg(GetTypeSize(type[sp-2],-1),reg1);
653 }
654 else{
655 //符号なし
656
657 //shr
658 op_shr_reg(GetTypeSize(type[sp-2],-1),reg1);
659 }
660 }
661
662 if(sw==0){
663 //mov rcx,r15
[64]664 op_mov_RR(REG_RCX,REG_R15);
[3]665 }
666 else{
667 //mov rcx,qword ptr[rsp+offset] ※スタックフレームを利用
668 pobj_sf->pop(REG_RCX);
669 }
670
671 if(reg1==REG_R14){
672 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
673 pobj_sf->push(REG_R14);
674 }
675
676 sp--;
677
678 *pStackPointer=sp;
679 return 1;
680}
Note: See TracBrowser for help on using the repository browser.