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

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