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

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