source: dev/trunk/abdev/BasicCompiler64/NumOpe_Arithmetic.cpp@ 210

Last change on this file since 210 was 206, checked in by dai_9181, 17 years ago

コード全体のリファクタリングを実施

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