source: dev/trunk/abdev/BasicCompiler64/NumOpe_TypeOperation.cpp @ 308

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

静的リンクライブラリにより、複数のグローバル領域が存在することになったのでそれぞれを関数ベースに分けた

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