source: dev/trunk/ab5.0/abdev/BasicCompiler64/NumOpe_TypeOperation.cpp @ 463

Last change on this file since 463 was 463, checked in by dai_9181, 16 years ago

[461]を64bit版にマージ。

File size: 13.0 KB
Line 
1#include "stdafx.h"
2
3#include <Compiler.h>
4
5#include "../BasicCompiler_Common/common.h"
6#include "Opcode.h"
7
8void ExtendTypeTo64( const Type &oldType, int reg ){
9    if( oldType.IsLong() )
10    {
11        //movsxd reg64,reg32
12        compiler.codeGenerator.op_movsxd(reg,reg);
13    }
14    else if( oldType.IsDWord() )
15    {
16        //and reg,00000000FFFFFFFFh
17    }
18    else if( oldType.IsInteger() )
19    {
20        //movsx reg64,reg16
21        compiler.codeGenerator.op_movsx64_FromReg16(reg,reg);
22    }
23    else if( oldType.IsWord() )
24    {
25        //and reg,000000000000FFFFh
26        compiler.codeGenerator.op_and64_value(reg,(int)0xFFFF);
27    }
28    else if( oldType.IsSByte() )
29    {
30        //movsx reg64,reg8
31        compiler.codeGenerator.op_movsx64_FromReg8(reg,reg);
32    }
33    else if( oldType.IsByte() || oldType.IsBoolean() )
34    {
35        //and reg,00000000000000FFh
36        compiler.codeGenerator.op_and64_value(reg,(int)0x00FF);
37    }
38}
39void ExtendTypeTo32( const Type &oldType, int reg ){
40    if( oldType.IsInteger() )
41    {
42        //movsx reg32,reg16
43        compiler.codeGenerator.op_movsx32_FromReg16(reg,reg);
44    }
45    else if( oldType.IsWord() )
46    {
47        //and reg,0000FFFFh
48        compiler.codeGenerator.op_and32_value(reg,(int)0xFFFF);
49    }
50    else if( oldType.IsSByte() )
51    {
52        //movsx reg32,reg8
53        compiler.codeGenerator.op_movsx32_FromReg8(reg,reg);
54    }
55    else if( oldType.IsByte() || oldType.IsBoolean() )
56    {
57        //and reg,000000FFh
58        compiler.codeGenerator.op_and32_value(reg,(int)0xFF);
59    }
60}
61void ExtendTypeTo16( const Type &oldType, int reg ){
62    if( oldType.IsSByte() )
63    {
64        //movsx reg16,reg8
65        compiler.codeGenerator.op_movsx16_FromReg8(reg,reg);
66    }
67    else if( oldType.IsByte() || oldType.IsBoolean() )
68    {
69        //and reg,000000FFh
70        compiler.codeGenerator.op_and32_value(reg,(int)0xFF);
71    }
72}
73
74void ChangeTypeToXmm_Double(int type,int xmm_reg,int general_reg){
75    if(type==DEF_DOUBLE){
76        //なにもしない
77    }
78    else if(type==DEF_SINGLE){
79        //Single型
80
81        //cvtss2sd
82        compiler.codeGenerator.op_cvtss2sd(xmm_reg,xmm_reg);
83    }
84    else if(Is64Type(type)){
85        //64ビット整数型
86
87        //cvtsi2sd xmm_reg,reg
88        compiler.codeGenerator.op_cvtsi2sd_reg(sizeof(_int64),xmm_reg,general_reg);
89
90        if(type==DEF_QWORD){
91            //符号なし
92
93            //test reg,reg
94            compiler.codeGenerator.op_test(general_reg,general_reg);
95
96            //jge 9
97            compiler.codeGenerator.op_jge( 9 );
98
99            //addsd xmm_reg,qword ptr[offset]   ※offset value:43f0000000000000
100            _int64 i64data=0x43f0000000000000;
101            long temp=compiler.GetObjectModule().dataTable.Add( i64data );
102            compiler.codeGenerator.PutOld(
103                (char)0xF2,
104                (char)0x0F,
105                (char)0x58,
106                (char)(0x04 | REGISTER_OPERAND(xmm_reg)<<3),
107                (char)0x25
108            );
109            compiler.codeGenerator.PutOld(
110                temp,
111                Schedule::DataTable
112            );
113        }
114    }
115    else if(type==DEF_DWORD){
116        //符号なし32ビット値
117
118        //64ビットにレジスタ値を拡張
119        ExtendTypeTo64(type,general_reg);
120
121        //cvtsi2sd xmm_reg,reg
122        compiler.codeGenerator.op_cvtsi2sd_reg(sizeof(_int64),xmm_reg,general_reg);
123    }
124    else{
125        //その他整数
126
127        //32ビットにレジスタ値を拡張
128        ExtendTypeTo32(type,general_reg);
129
130        //cvtsi2sd xmm_reg,reg
131        compiler.codeGenerator.op_cvtsi2sd_reg(sizeof(long),xmm_reg,general_reg);
132    }
133}
134void ChangeTypeToXmm_Single(int type,int xmm_reg,int general_reg){
135    if(type==DEF_DOUBLE){
136        //Double型
137
138        //cvtsd2ss
139        compiler.codeGenerator.op_cvtsd2ss(xmm_reg,xmm_reg);
140    }
141    else if(type==DEF_SINGLE){
142        //なにもしない
143    }
144    else if(Is64Type(type)){
145        //64ビット整数型
146
147        //cvtsi2ss xmm_reg,reg
148        compiler.codeGenerator.op_cvtsi2ss_reg(sizeof(_int64),xmm_reg,general_reg);
149
150        if(type==DEF_QWORD){
151            //符号なし
152
153            //test reg,reg
154            compiler.codeGenerator.op_test(general_reg,general_reg);
155
156            //jge 9
157            compiler.codeGenerator.op_jge( 9 );
158
159            //addss xmm_reg,dword ptr[offset]   ※offset value:5f800000
160            long i32data=0x5f800000;
161            long temp=compiler.GetObjectModule().dataTable.Add( i32data );
162            compiler.codeGenerator.PutOld(
163                (char)0xF3,
164                (char)0x0F,
165                (char)0x58,
166                (char)(0x04 | REGISTER_OPERAND(xmm_reg)<<3),
167                (char)0x25
168            );
169            compiler.codeGenerator.PutOld(
170                temp,
171                Schedule::DataTable
172            );
173        }
174    }
175    else if(type==DEF_DWORD){
176        //符号なし32ビット値
177
178        //64ビットにレジスタ値を拡張
179        ExtendTypeTo64(type,general_reg);
180
181        //cvtsi2ss xmm_reg,reg
182        compiler.codeGenerator.op_cvtsi2ss_reg(sizeof(_int64),xmm_reg,general_reg);
183    }
184    else{
185        //その他整数
186
187        //32ビットにレジスタ値を拡張
188        ExtendTypeTo32(type,general_reg);
189
190        //cvtsi2ss xmm_reg,reg
191        compiler.codeGenerator.op_cvtsi2ss_reg(sizeof(long),xmm_reg,general_reg);
192    }
193}
194
195void ChangeTypeToWhole( const Type &oldType, const Type &newType, int reg, int xmm_reg )
196{
197    if( oldType.IsDouble() )
198    {
199        if( newType.Is64() )
200        {
201            //cvttsd2si reg,xmm_reg
202            compiler.codeGenerator.op_cvttsd2si_xmm(sizeof(_int64),reg,xmm_reg);
203        }
204        else
205        {
206            //cvttsd2si reg,xmm_reg
207            compiler.codeGenerator.op_cvttsd2si_xmm(sizeof(long),reg,xmm_reg);
208        }
209    }
210    if( oldType.IsSingle() )
211    {
212        if( newType.Is64() )
213        {
214            //cvttss2si reg,xmm_reg
215            compiler.codeGenerator.op_cvttss2si_xmm(sizeof(_int64),reg,xmm_reg);
216        }
217        else
218        {
219            //cvttss2si reg,xmm_reg
220            compiler.codeGenerator.op_cvttss2si_xmm(sizeof(long),reg,xmm_reg);
221        }
222    }
223    else{
224        //整数から整数へ変換
225
226        if( newType.Is64() )
227        {
228            ExtendTypeTo64(oldType,reg);
229        }
230        if( newType.GetSize() == sizeof(long) )
231        {
232            ExtendTypeTo32(oldType,reg);
233        }
234        if( newType.GetSize() == sizeof(short) )
235        {
236            ExtendTypeTo16(oldType,reg);
237        }
238    }
239}
240
241
242
243/////////////////////////////////////////
244// 1つの項を適切なレジスタへセット
245/////////////////////////////////////////
246
247void SetOneTermToReg_RealCalc(int TermType,int *pXmmReg){
248    int xmm_reg;
249
250    if(IsRealNumberType(TermType)){
251        //実数型
252        xmm_reg=pobj_reg->GetLockingXmmReg();
253
254        if(xmm_reg==REG_XMM4){
255            if(TermType==DEF_DOUBLE){
256                //movlpd xmm4,qword ptr[rsp+offset]     ※スタックフレームを利用
257                pobj_sf->pop(xmm_reg,sizeof(double));
258            }
259            if(TermType==DEF_SINGLE){
260                //movss xmm4,dword ptr[rsp+offset]      ※スタックフレームを利用
261                pobj_sf->pop(xmm_reg,sizeof(float));
262            }
263        }
264    }
265    else{
266        SetError(300,NULL,cp);
267    }
268
269    *pXmmReg=xmm_reg;
270}
271void SetOneTermToReg_Whole64Calc(int TermType,int *pReg){
272    //1つの項を適切なレジスタへセット(64ビット整数演算用)
273    int reg;
274
275    reg=pobj_reg->GetLockingReg();
276
277    if(reg==REG_R14){
278        //mov r14,qword ptr[rsp+offset]     ※スタックフレームを利用
279        pobj_sf->pop(REG_R14);
280    }
281
282    //レジスタ値を64ビットに拡張
283    ExtendTypeTo64(TermType,reg);
284
285    *pReg=reg;
286}
287void SetOneTermToReg_Whole32Calc(int TermType,int *pReg){
288    //1つの項を適切なレジスタへセット(32ビット整数演算用)
289    int reg;
290
291    reg=pobj_reg->GetLockingReg();
292
293    if(reg==REG_R14){
294        //mov r14,qword ptr[rsp+offset]     ※スタックフレームを利用
295        pobj_sf->pop(REG_R14);
296    }
297
298    //レジスタ値を32ビットに拡張
299    ExtendTypeTo32(TermType,reg);
300
301    *pReg=reg;
302}
303
304
305
306/////////////////////////////////////////
307// 2つの項を適切なレジスタへセット
308/////////////////////////////////////////
309
310void SetTowTermToReg_RealCalc(int AnswerType,int *type,int sp,int *pXmmReg1,int *pXmmReg2){
311    //2つの項を適切なレジスタへセット(Double演算用)
312    int xmm_reg1,xmm_reg2,temp_reg;
313
314
315    ///////////////////
316    // 第2項
317    ///////////////////
318
319    if(IsRealNumberType(type[sp-1])){
320        //実数型
321        xmm_reg2=pobj_reg->UnlockXmmReg();
322
323        if(xmm_reg2==REG_XMM4){
324            xmm_reg2=REG_XMM5;
325
326            if(type[sp-1]==DEF_DOUBLE){
327                //movlpd xmm5,qword ptr[rsp+offset]     ※スタックフレームを利用
328                pobj_sf->pop(xmm_reg2,sizeof(double));
329            }
330            if(type[sp-1]==DEF_SINGLE){
331                //movss xmm5,dword ptr[rsp+offset]      ※スタックフレームを利用
332                pobj_sf->pop(xmm_reg2,sizeof(float));
333            }
334        }
335        else{
336            if(!IsRealNumberType(type[sp-2])){
337                if(type[sp-1]==DEF_DOUBLE){
338                    //movsd xmm5,xmm_reg
339                    compiler.codeGenerator.op_movsd_RR( REG_XMM5, xmm_reg2 );
340                }
341                if(type[sp-1]==DEF_SINGLE){
342                    //movss xmm5,xmm_reg
343                    compiler.codeGenerator.op_movss_RR( REG_XMM5, xmm_reg2 );
344                }
345
346                xmm_reg2=REG_XMM5;
347            }
348        }
349    }
350    else{
351        //整数値
352
353        temp_reg=pobj_reg->UnlockReg();
354
355        if(temp_reg==REG_R14){
356            //mov r14,qword ptr[rsp+offset]     ※スタックフレームを利用
357            pobj_sf->pop(REG_R14);
358        }
359
360        xmm_reg2=REG_XMM5;
361    }
362
363    //汎用レジスタ(temp_reg)をXMMレジスタ(xmm_reg2)にコピー
364    if(AnswerType==DEF_DOUBLE)
365        ChangeTypeToXmm_Double(type[sp-1],xmm_reg2,temp_reg);
366    if(AnswerType==DEF_SINGLE)
367        ChangeTypeToXmm_Single(type[sp-1],xmm_reg2,temp_reg);
368
369
370    ///////////////////
371    // 第1項
372    ///////////////////
373
374    if(IsRealNumberType(type[sp-2])){
375        //実数
376        xmm_reg1=pobj_reg->GetLockingXmmReg();
377
378        if(xmm_reg1==REG_XMM4){
379            if(type[sp-2]==DEF_DOUBLE){
380                //movlpd xmm4,qword ptr[rsp+offset]     ※スタックフレームを利用
381                pobj_sf->pop(xmm_reg1,sizeof(double));
382            }
383            if(type[sp-2]==DEF_SINGLE){
384                //movss xmm4,dword ptr[rsp+offset]      ※スタックフレームを利用
385                pobj_sf->pop(xmm_reg1,sizeof(float));
386            }
387        }
388    }
389    else{
390        //整数
391
392        temp_reg=pobj_reg->UnlockReg();
393
394        if(temp_reg==REG_R14){
395            //mov r14,qword ptr[rsp+offset]     ※スタックフレームを利用
396            pobj_sf->pop(REG_R14);
397        }
398
399        xmm_reg1=pobj_reg->LockXmmReg();
400    }
401
402    //汎用レジスタ(temp_reg)をXMMレジスタ(xmm_reg1)にコピー
403    if(AnswerType==DEF_DOUBLE)
404        ChangeTypeToXmm_Double(type[sp-2],xmm_reg1,temp_reg);
405    if(AnswerType==DEF_SINGLE)
406        ChangeTypeToXmm_Single(type[sp-2],xmm_reg1,temp_reg);
407
408
409    *pXmmReg1=xmm_reg1;
410    *pXmmReg2=xmm_reg2;
411}
412void SetTowTermToReg_Whole64Calc(int *type,int sp,int *pReg1,int *pReg2){
413    //2つの項を適切なレジスタへセット(64ビット整数演算用)
414    int reg1,reg2;
415
416    //////////////////
417    // 第2項
418    //////////////////
419    reg2=pobj_reg->UnlockReg();
420
421    if(reg2==REG_R14){
422        //mov r15,qword ptr[rsp+offset]     ※スタックフレームを利用
423        pobj_sf->pop(REG_R15);
424
425        reg2=REG_R15;
426    }
427
428    //レジスタ値を64ビットに拡張
429    ExtendTypeTo64(type[sp-1],reg2);
430
431
432    //////////////////
433    // 第1項
434    //////////////////
435    reg1=pobj_reg->GetLockingReg();
436
437    if(reg1==REG_R14){
438        //mov r14,qword ptr[rsp+offset]     ※スタックフレームを利用
439        pobj_sf->pop(REG_R14);
440    }
441
442    //レジスタ値を64ビットに拡張
443    ExtendTypeTo64(type[sp-2],reg1);
444
445
446    *pReg1=reg1;
447    *pReg2=reg2;
448}
449void SetTowTermToReg_Whole32Calc(int *type,int sp,int *pReg1,int *pReg2){
450    //2つの項を適切なレジスタへセット(32ビット整数演算用)
451    int reg1,reg2;
452
453    //////////////////
454    // 第2項
455    //////////////////
456    reg2=pobj_reg->UnlockReg();
457
458    if(reg2==REG_R14){
459        //mov r15,qword ptr[rsp+offset]     ※スタックフレームを利用
460        pobj_sf->pop(REG_R15);
461
462        reg2=REG_R15;
463    }
464
465    //レジスタ値を32ビットに拡張
466    ExtendTypeTo32(type[sp-1],reg2);
467
468
469    //////////////////
470    // 第1項
471    //////////////////
472    reg1=pobj_reg->GetLockingReg();
473
474    if(reg1==REG_R14){
475        //mov r14,qword ptr[rsp+offset]     ※スタックフレームを利用
476        pobj_sf->pop(REG_R14);
477    }
478
479    //レジスタ値を32ビットに拡張
480    ExtendTypeTo32(type[sp-2],reg1);
481
482
483    *pReg1=reg1;
484    *pReg2=reg2;
485}
486
487
488
489////////////////////////////
490// As 演算子によるキャスト
491////////////////////////////
492
493BOOL Calc_Cast(int *type,LONG_PTR *index_stack,int *pStackPointer){
494    //キャスト
495
496    int sp;
497    sp=*pStackPointer;
498
499    int castBasicType = type[sp-1];
500    if((castBasicType&FLAG_CAST)==0){
501        SetError(47,NULL,cp);
502        return 0;
503    }
504    castBasicType = castBasicType&(~FLAG_CAST);
505
506    Type oldType( type[sp-2], index_stack[sp-2] );
507    Type castType( castBasicType, index_stack[sp-1] );
508
509    int xmm_reg,reg;
510    if( castType.IsReal() )
511    {
512        //実数型へキャスト
513
514        if( oldType.IsReal() )
515        {
516            SetOneTermToReg_RealCalc(oldType.GetBasicType(),&xmm_reg);
517        }
518        else
519        {
520            if( oldType.Is64() )
521            {
522                SetOneTermToReg_Whole64Calc(oldType.GetBasicType(),&reg);
523            }
524            else if( oldType.IsWhole() )
525            {
526                SetOneTermToReg_Whole32Calc(oldType.GetBasicType(),&reg);
527            }
528
529            pobj_reg->UnlockReg();
530
531            xmm_reg=pobj_reg->LockXmmReg();
532        }
533
534        if( castType.IsDouble() )
535        {
536            //Double型にデータ変換
537            ChangeTypeToXmm_Double(oldType.GetBasicType(),xmm_reg,reg);
538        }
539        else if( castType.IsSingle() )
540        {
541            //Single型にデータ変換
542            ChangeTypeToXmm_Single(oldType.GetBasicType(),xmm_reg,reg);
543        }
544
545        if(xmm_reg==REG_XMM4){
546            //movsd qword ptr[rsp+offset],xmm4      ※スタックフレームを利用
547            pobj_sf->push(REG_XMM4,sizeof(double));
548        }
549    }
550    else{
551        //その他整数型へ変換
552
553        if( oldType.IsReal() )
554        {
555            SetOneTermToReg_RealCalc(oldType.GetBasicType(),&xmm_reg);
556
557            pobj_reg->UnlockXmmReg();
558
559            reg=pobj_reg->LockReg();
560
561            //整数型へデータ変換
562            ChangeTypeToWhole(oldType,castType,reg,xmm_reg);
563
564            if(reg==REG_R14){
565                //mov qword ptr[rsp+offset],r14     ※スタックフレームを利用
566                pobj_sf->push(REG_R14);
567            }
568        }
569        else{
570            reg=pobj_reg->GetLockingReg();
571
572            if(reg==REG_R14){
573                //mov r14,qword ptr[rsp+offset]     ※スタックフレームを利用
574                pobj_sf->pop(REG_R14);
575            }
576
577            //整数型へデータ変換
578            ChangeTypeToWhole(oldType,castType,reg,0);
579
580            if(reg==REG_R14){
581                //mov qword ptr[rsp+offset],r14     ※スタックフレームを利用
582                pobj_sf->push(REG_R14);
583            }
584        }
585    }
586
587    type[sp-2] = castType.GetBasicType();
588    index_stack[sp-2] = castType.GetIndex();
589
590    sp--;
591
592    *pStackPointer=sp;
593    return 1;
594}
Note: See TracBrowser for help on using the repository browser.