source: dev/trunk/ab5.0/abdev/compiler_x64/NumOpe_Arithmetic.cpp

Last change on this file was 829, checked in by イグトランス (egtra), 13 years ago

svn:eol-styleとsvn:mime-type(文字コード指定含む)の設定

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/plain; charset=Shift_JIS
File size: 15.0 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 compiler.errorMessenger.Output(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 compiler.errorMessenger.Output(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.GetObjectModule().dataTable.Add( dbl );
473
474 //mulsd xmm_reg,qword ptr[data table offset] ※data = -1
475 compiler.codeGenerator.PutOld(
476 (char)0xF2,
477 (char)0x0F,
478 (char)0x59,
479 (char)(0x04 | REGISTER_OPERAND(xmm_reg)<<3),
480 (char)0x25
481 );
482 compiler.codeGenerator.PutOld(
483 (long)i32data,
484 Schedule::DataTable
485 );
486
487 if(xmm_reg==REG_XMM4){
488 //movsd qword ptr[rsp+offset],xmm4 ※スタックフレームを利用
489 pobj_sf->push(REG_XMM4,sizeof(double));
490 }
491 }
492 else if(type[sp-1]==DEF_SINGLE){
493 SetOneTermToReg_RealCalc(type[sp-1],&xmm_reg);
494
495 float flt;
496 flt=-1;
497 i32data = compiler.GetObjectModule().dataTable.Add( flt );
498
499 //mulss xmm_reg,dword ptr[data table offset] ※data = -1
500 compiler.codeGenerator.PutOld(
501 (char)0xF3,
502 (char)0x0F,
503 (char)0x59,
504 (char)(0x04 | REGISTER_OPERAND(xmm_reg)<<3),
505 (char)0x25
506 );
507 compiler.codeGenerator.PutOld(
508 (long)i32data,
509 Schedule::DataTable
510 );
511
512 if(xmm_reg==REG_XMM4){
513 //movss dword ptr[rsp+offset],xmm4 ※スタックフレームを利用
514 pobj_sf->push(REG_XMM4,sizeof(float));
515 }
516 }
517 else if(type[sp-1]==DEF_INT64||type[sp-1]==DEF_QWORD){
518 SetOneTermToReg_Whole64Calc(type[sp-1],&reg);
519
520 //imul reg,-1
521 compiler.codeGenerator.op_imul_RV(sizeof(_int64),reg,-1);
522
523 if(reg==REG_R14){
524 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
525 pobj_sf->push(REG_R14);
526 }
527
528 type[sp-1]=DEF_INT64; //QWordはInt64へ
529 }
530 else if(IsWholeNumberType(type[sp-1])){
531 SetOneTermToReg_Whole32Calc(type[sp-1],&reg);
532
533 //imul reg,-1
534 compiler.codeGenerator.op_imul_RV(sizeof(long),reg,-1);
535
536 if(reg==REG_R14){
537 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
538 pobj_sf->push(REG_R14);
539 }
540
541 type[sp-1]=GetSignedType(type[sp-1]);
542 }
543
544 return 1;
545}
546
547BOOL Calc_Power(int *type,int *pStackPointer){
548 //べき乗(実数演算のみ)
549
550 int sp;
551 sp=*pStackPointer;
552
553
554 //2つの項を適切なレジスタにセット
555 int xmm_reg1,xmm_reg2;
556 SetTowTermToReg_RealCalc(DEF_DOUBLE,type,sp,&xmm_reg1,&xmm_reg2);
557
558
559 //////////////////////////////////////////////////////
560 ///// レジスタ資源のバックアップ
561 { BACKUP_REGISTER_RESOURCE
562 //////////////////////////////////////////////////////
563
564
565 ////////////////
566 // 呼び出し
567 ////////////////
568
569 if(xmm_reg1==REG_XMM1){
570 //movsd xmm0,xmm_reg1
571 compiler.codeGenerator.op_movsd_RR(REG_XMM0,xmm_reg1);
572
573 //movsd xmm1,xmm_reg2
574 compiler.codeGenerator.op_movsd_RR(REG_XMM1,xmm_reg2);
575 }
576 else{
577 //movsd xmm1,xmm_reg2
578 compiler.codeGenerator.op_movsd_RR(REG_XMM1,xmm_reg2);
579
580 //movsd xmm0,xmm_reg1
581 compiler.codeGenerator.op_movsd_RR(REG_XMM0,xmm_reg1);
582 }
583
584 //call pow
585 extern const UserProc *pSub_pow;
586 compiler.codeGenerator.op_call(pSub_pow);
587
588 //movsd xmm4,xmm0
589 compiler.codeGenerator.op_movsd_RR(REG_XMM4,REG_XMM0);
590
591
592 /////////////////////////////////////////////
593 ////// レジスタ資源を復元
594 RESTORE_REGISTER_RESOURCE
595 }////////////////////////////////////////////
596
597
598 //////////////////////////////////
599 // 戻り値を所定のレジスタへ格納
600 //////////////////////////////////
601
602 if(xmm_reg1==REG_XMM4){
603 //movsd qword ptr[rsp+offset],xmm4 ※スタックフレームを利用
604 pobj_sf->push(REG_XMM0,sizeof(double));
605 }
606 else{
607 //movsd xmm_reg1,xmm4
608 compiler.codeGenerator.op_movsd_RR(xmm_reg1,REG_XMM4);
609 }
610
611
612 sp--;
613 type[sp-1]=DEF_DOUBLE;
614
615 *pStackPointer=sp;
616 return 1;
617}
618
619BOOL Calc_Shift(int idCalc,int *type,int *pStackPointer){
620 //ビットシフト
621
622 int sp;
623 sp=*pStackPointer;
624
625 if(IsRealNumberType(type[sp-2])||IsRealNumberType(type[sp-1])){
626 //いずれかの項が実数のとき
627 compiler.errorMessenger.Output(45,"<<",cp);
628 return 0;
629 }
630
631
632 /////////////////////////
633 // 64ビット整数演算のみ
634 /////////////////////////
635 int reg1,reg2;
636
637 //2つの項を適切なレジスタにセット
638 SetTowTermToReg_Whole64Calc(type,sp,&reg1,&reg2);
639
640 int sw=0;
641 if(reg1==REG_RCX){
642 //mov r15,rcx
643 compiler.codeGenerator.op_mov_RR(REG_R15,REG_RCX);
644
645 reg1=REG_R15;
646 }
647 else if(reg2!=REG_RCX){
648 sw=1;
649
650 //mov qword ptr[rsp+offset],rcx ※スタックフレームを利用
651 pobj_sf->push(REG_RCX);
652 }
653
654 //mov rcx,reg2
655 compiler.codeGenerator.op_mov_RR(REG_RCX,reg2);
656
657 if(idCalc==CALC_SHL){
658 //左シフトは符号あり、なしは同様の動きをする
659
660 //32ビット型にする
661 if(!Is64Type(type[sp-2])){
662 ExtendTypeTo32(type[sp-2],reg1);
663
664 if(IsSignedType(type[sp-2])) type[sp-2]=DEF_LONG;
665 else type[sp-2]=DEF_DWORD;
666 }
667
668 //shl reg1,cl
669 compiler.codeGenerator.op_shl_reg(Type(type[sp-2]).GetSize(),reg1);
670 }
671 else if(idCalc==CALC_SHR){
672 if(IsSignedType(type[sp-2])){
673 //符号あり
674
675 //sar
676 compiler.codeGenerator.op_sar_reg(Type(type[sp-2]).GetSize(),reg1);
677 }
678 else{
679 //符号なし
680
681 //shr
682 compiler.codeGenerator.op_shr_reg(Type(type[sp-2]).GetSize(),reg1);
683 }
684 }
685
686 if(sw==0){
687 //mov rcx,r15
688 compiler.codeGenerator.op_mov_RR(REG_RCX,REG_R15);
689 }
690 else{
691 //mov rcx,qword ptr[rsp+offset] ※スタックフレームを利用
692 pobj_sf->pop(REG_RCX);
693 }
694
695 if(reg1==REG_R14){
696 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
697 pobj_sf->push(REG_R14);
698 }
699
700 sp--;
701
702 *pStackPointer=sp;
703 return 1;
704}
Note: See TracBrowser for help on using the repository browser.