#include "stdafx.h" #include #include "../BasicCompiler_Common/common.h" #include "Opcode.h" void ExtendTypeTo64( const Type &oldType, int reg ){ if( oldType.IsLong() ) { //movsxd reg64,reg32 compiler.codeGenerator.op_movsxd(reg,reg); } else if( oldType.IsDWord() ) { //and reg,00000000FFFFFFFFh } else if( oldType.IsInteger() ) { //movsx reg64,reg16 compiler.codeGenerator.op_movsx64_FromReg16(reg,reg); } else if( oldType.IsWord() ) { //and reg,000000000000FFFFh compiler.codeGenerator.op_and64_value(reg,(int)0xFFFF); } else if( oldType.IsSByte() ) { //movsx reg64,reg8 compiler.codeGenerator.op_movsx64_FromReg8(reg,reg); } else if( oldType.IsByte() || oldType.IsBoolean() ) { //and reg,00000000000000FFh compiler.codeGenerator.op_and64_value(reg,(int)0x00FF); } } void ExtendTypeTo32( const Type &oldType, int reg ){ if( oldType.IsInteger() ) { //movsx reg32,reg16 compiler.codeGenerator.op_movsx32_FromReg16(reg,reg); } else if( oldType.IsWord() ) { //and reg,0000FFFFh compiler.codeGenerator.op_and32_value(reg,(int)0xFFFF); } else if( oldType.IsSByte() ) { //movsx reg32,reg8 compiler.codeGenerator.op_movsx32_FromReg8(reg,reg); } else if( oldType.IsByte() || oldType.IsBoolean() ) { //and reg,000000FFh compiler.codeGenerator.op_and32_value(reg,(int)0xFF); } } void ExtendTypeTo16( const Type &oldType, int reg ){ if( oldType.IsSByte() ) { //movsx reg16,reg8 compiler.codeGenerator.op_movsx16_FromReg8(reg,reg); } else if( oldType.IsByte() || oldType.IsBoolean() ) { //and reg,000000FFh compiler.codeGenerator.op_and32_value(reg,(int)0xFF); } } void ChangeTypeToXmm_Double(int type,int xmm_reg,int general_reg){ if(type==DEF_DOUBLE){ //なにもしない } else if(type==DEF_SINGLE){ //Single型 //cvtss2sd compiler.codeGenerator.op_cvtss2sd(xmm_reg,xmm_reg); } else if(Is64Type(type)){ //64ビット整数型 //cvtsi2sd xmm_reg,reg compiler.codeGenerator.op_cvtsi2sd_reg(sizeof(_int64),xmm_reg,general_reg); if(type==DEF_QWORD){ //符号なし //test reg,reg compiler.codeGenerator.op_test(general_reg,general_reg); //jge 9 compiler.codeGenerator.op_jge( 9 ); //addsd xmm_reg,qword ptr[offset] ※offset value:43f0000000000000 _int64 i64data=0x43f0000000000000; long temp=compiler.GetObjectModule().dataTable.Add( i64data ); compiler.codeGenerator.PutOld( (char)0xF2, (char)0x0F, (char)0x58, (char)(0x04 | REGISTER_OPERAND(xmm_reg)<<3), (char)0x25 ); compiler.codeGenerator.PutOld( temp, Schedule::DataTable ); } } else if(type==DEF_DWORD){ //符号なし32ビット値 //64ビットにレジスタ値を拡張 ExtendTypeTo64(type,general_reg); //cvtsi2sd xmm_reg,reg compiler.codeGenerator.op_cvtsi2sd_reg(sizeof(_int64),xmm_reg,general_reg); } else{ //その他整数 //32ビットにレジスタ値を拡張 ExtendTypeTo32(type,general_reg); //cvtsi2sd xmm_reg,reg compiler.codeGenerator.op_cvtsi2sd_reg(sizeof(long),xmm_reg,general_reg); } } void ChangeTypeToXmm_Single(int type,int xmm_reg,int general_reg){ if(type==DEF_DOUBLE){ //Double型 //cvtsd2ss compiler.codeGenerator.op_cvtsd2ss(xmm_reg,xmm_reg); } else if(type==DEF_SINGLE){ //なにもしない } else if(Is64Type(type)){ //64ビット整数型 //cvtsi2ss xmm_reg,reg compiler.codeGenerator.op_cvtsi2ss_reg(sizeof(_int64),xmm_reg,general_reg); if(type==DEF_QWORD){ //符号なし //test reg,reg compiler.codeGenerator.op_test(general_reg,general_reg); //jge 9 compiler.codeGenerator.op_jge( 9 ); //addss xmm_reg,dword ptr[offset] ※offset value:5f800000 long i32data=0x5f800000; long temp=compiler.GetObjectModule().dataTable.Add( i32data ); compiler.codeGenerator.PutOld( (char)0xF3, (char)0x0F, (char)0x58, (char)(0x04 | REGISTER_OPERAND(xmm_reg)<<3), (char)0x25 ); compiler.codeGenerator.PutOld( temp, Schedule::DataTable ); } } else if(type==DEF_DWORD){ //符号なし32ビット値 //64ビットにレジスタ値を拡張 ExtendTypeTo64(type,general_reg); //cvtsi2ss xmm_reg,reg compiler.codeGenerator.op_cvtsi2ss_reg(sizeof(_int64),xmm_reg,general_reg); } else{ //その他整数 //32ビットにレジスタ値を拡張 ExtendTypeTo32(type,general_reg); //cvtsi2ss xmm_reg,reg compiler.codeGenerator.op_cvtsi2ss_reg(sizeof(long),xmm_reg,general_reg); } } void ChangeTypeToWhole( const Type &oldType, const Type &newType, int reg, int xmm_reg ) { if( oldType.IsDouble() ) { if( newType.Is64() ) { //cvttsd2si reg,xmm_reg compiler.codeGenerator.op_cvttsd2si_xmm(sizeof(_int64),reg,xmm_reg); } else { //cvttsd2si reg,xmm_reg compiler.codeGenerator.op_cvttsd2si_xmm(sizeof(long),reg,xmm_reg); } } if( oldType.IsSingle() ) { if( newType.Is64() ) { //cvttss2si reg,xmm_reg compiler.codeGenerator.op_cvttss2si_xmm(sizeof(_int64),reg,xmm_reg); } else { //cvttss2si reg,xmm_reg compiler.codeGenerator.op_cvttss2si_xmm(sizeof(long),reg,xmm_reg); } } else{ //整数から整数へ変換 if( newType.Is64() ) { ExtendTypeTo64(oldType,reg); } if( newType.GetSize() == sizeof(long) ) { ExtendTypeTo32(oldType,reg); } if( newType.GetSize() == sizeof(short) ) { ExtendTypeTo16(oldType,reg); } } } ///////////////////////////////////////// // 1つの項を適切なレジスタへセット ///////////////////////////////////////// void SetOneTermToReg_RealCalc(int TermType,int *pXmmReg){ int xmm_reg; if(IsRealNumberType(TermType)){ //実数型 xmm_reg=pobj_reg->GetLockingXmmReg(); if(xmm_reg==REG_XMM4){ if(TermType==DEF_DOUBLE){ //movlpd xmm4,qword ptr[rsp+offset] ※スタックフレームを利用 pobj_sf->pop(xmm_reg,sizeof(double)); } if(TermType==DEF_SINGLE){ //movss xmm4,dword ptr[rsp+offset] ※スタックフレームを利用 pobj_sf->pop(xmm_reg,sizeof(float)); } } } else{ SetError(300,NULL,cp); } *pXmmReg=xmm_reg; } void SetOneTermToReg_Whole64Calc(int TermType,int *pReg){ //1つの項を適切なレジスタへセット(64ビット整数演算用) int reg; reg=pobj_reg->GetLockingReg(); if(reg==REG_R14){ //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用 pobj_sf->pop(REG_R14); } //レジスタ値を64ビットに拡張 ExtendTypeTo64(TermType,reg); *pReg=reg; } void SetOneTermToReg_Whole32Calc(int TermType,int *pReg){ //1つの項を適切なレジスタへセット(32ビット整数演算用) int reg; reg=pobj_reg->GetLockingReg(); if(reg==REG_R14){ //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用 pobj_sf->pop(REG_R14); } //レジスタ値を32ビットに拡張 ExtendTypeTo32(TermType,reg); *pReg=reg; } ///////////////////////////////////////// // 2つの項を適切なレジスタへセット ///////////////////////////////////////// void SetTowTermToReg_RealCalc(int AnswerType,int *type,int sp,int *pXmmReg1,int *pXmmReg2){ //2つの項を適切なレジスタへセット(Double演算用) int xmm_reg1,xmm_reg2,temp_reg; /////////////////// // 第2項 /////////////////// if(IsRealNumberType(type[sp-1])){ //実数型 xmm_reg2=pobj_reg->UnlockXmmReg(); if(xmm_reg2==REG_XMM4){ xmm_reg2=REG_XMM5; if(type[sp-1]==DEF_DOUBLE){ //movlpd xmm5,qword ptr[rsp+offset] ※スタックフレームを利用 pobj_sf->pop(xmm_reg2,sizeof(double)); } if(type[sp-1]==DEF_SINGLE){ //movss xmm5,dword ptr[rsp+offset] ※スタックフレームを利用 pobj_sf->pop(xmm_reg2,sizeof(float)); } } else{ if(!IsRealNumberType(type[sp-2])){ if(type[sp-1]==DEF_DOUBLE){ //movsd xmm5,xmm_reg compiler.codeGenerator.op_movsd_RR( REG_XMM5, xmm_reg2 ); } if(type[sp-1]==DEF_SINGLE){ //movss xmm5,xmm_reg compiler.codeGenerator.op_movss_RR( REG_XMM5, xmm_reg2 ); } xmm_reg2=REG_XMM5; } } } else{ //整数値 temp_reg=pobj_reg->UnlockReg(); if(temp_reg==REG_R14){ //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用 pobj_sf->pop(REG_R14); } xmm_reg2=REG_XMM5; } //汎用レジスタ(temp_reg)をXMMレジスタ(xmm_reg2)にコピー if(AnswerType==DEF_DOUBLE) ChangeTypeToXmm_Double(type[sp-1],xmm_reg2,temp_reg); if(AnswerType==DEF_SINGLE) ChangeTypeToXmm_Single(type[sp-1],xmm_reg2,temp_reg); /////////////////// // 第1項 /////////////////// if(IsRealNumberType(type[sp-2])){ //実数 xmm_reg1=pobj_reg->GetLockingXmmReg(); if(xmm_reg1==REG_XMM4){ if(type[sp-2]==DEF_DOUBLE){ //movlpd xmm4,qword ptr[rsp+offset] ※スタックフレームを利用 pobj_sf->pop(xmm_reg1,sizeof(double)); } if(type[sp-2]==DEF_SINGLE){ //movss xmm4,dword ptr[rsp+offset] ※スタックフレームを利用 pobj_sf->pop(xmm_reg1,sizeof(float)); } } } else{ //整数 temp_reg=pobj_reg->UnlockReg(); if(temp_reg==REG_R14){ //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用 pobj_sf->pop(REG_R14); } xmm_reg1=pobj_reg->LockXmmReg(); } //汎用レジスタ(temp_reg)をXMMレジスタ(xmm_reg1)にコピー if(AnswerType==DEF_DOUBLE) ChangeTypeToXmm_Double(type[sp-2],xmm_reg1,temp_reg); if(AnswerType==DEF_SINGLE) ChangeTypeToXmm_Single(type[sp-2],xmm_reg1,temp_reg); *pXmmReg1=xmm_reg1; *pXmmReg2=xmm_reg2; } void SetTowTermToReg_Whole64Calc(int *type,int sp,int *pReg1,int *pReg2){ //2つの項を適切なレジスタへセット(64ビット整数演算用) int reg1,reg2; ////////////////// // 第2項 ////////////////// reg2=pobj_reg->UnlockReg(); if(reg2==REG_R14){ //mov r15,qword ptr[rsp+offset] ※スタックフレームを利用 pobj_sf->pop(REG_R15); reg2=REG_R15; } //レジスタ値を64ビットに拡張 ExtendTypeTo64(type[sp-1],reg2); ////////////////// // 第1項 ////////////////// reg1=pobj_reg->GetLockingReg(); if(reg1==REG_R14){ //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用 pobj_sf->pop(REG_R14); } //レジスタ値を64ビットに拡張 ExtendTypeTo64(type[sp-2],reg1); *pReg1=reg1; *pReg2=reg2; } void SetTowTermToReg_Whole32Calc(int *type,int sp,int *pReg1,int *pReg2){ //2つの項を適切なレジスタへセット(32ビット整数演算用) int reg1,reg2; ////////////////// // 第2項 ////////////////// reg2=pobj_reg->UnlockReg(); if(reg2==REG_R14){ //mov r15,qword ptr[rsp+offset] ※スタックフレームを利用 pobj_sf->pop(REG_R15); reg2=REG_R15; } //レジスタ値を32ビットに拡張 ExtendTypeTo32(type[sp-1],reg2); ////////////////// // 第1項 ////////////////// reg1=pobj_reg->GetLockingReg(); if(reg1==REG_R14){ //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用 pobj_sf->pop(REG_R14); } //レジスタ値を32ビットに拡張 ExtendTypeTo32(type[sp-2],reg1); *pReg1=reg1; *pReg2=reg2; } //////////////////////////// // As 演算子によるキャスト //////////////////////////// BOOL Calc_Cast(int *type,LONG_PTR *index_stack,int *pStackPointer){ //キャスト int sp; sp=*pStackPointer; int castBasicType = type[sp-1]; if((castBasicType&FLAG_CAST)==0){ SetError(47,NULL,cp); return 0; } castBasicType = castBasicType&(~FLAG_CAST); Type oldType( type[sp-2], index_stack[sp-2] ); Type castType( castBasicType, index_stack[sp-1] ); int xmm_reg,reg; if( castType.IsReal() ) { //実数型へキャスト if( oldType.IsReal() ) { SetOneTermToReg_RealCalc(oldType.GetBasicType(),&xmm_reg); } else { if( oldType.Is64() ) { SetOneTermToReg_Whole64Calc(oldType.GetBasicType(),®); } else if( oldType.IsWhole() ) { SetOneTermToReg_Whole32Calc(oldType.GetBasicType(),®); } pobj_reg->UnlockReg(); xmm_reg=pobj_reg->LockXmmReg(); } if( castType.IsDouble() ) { //Double型にデータ変換 ChangeTypeToXmm_Double(oldType.GetBasicType(),xmm_reg,reg); } else if( castType.IsSingle() ) { //Single型にデータ変換 ChangeTypeToXmm_Single(oldType.GetBasicType(),xmm_reg,reg); } if(xmm_reg==REG_XMM4){ //movsd qword ptr[rsp+offset],xmm4 ※スタックフレームを利用 pobj_sf->push(REG_XMM4,sizeof(double)); } } else{ //その他整数型へ変換 if( oldType.IsReal() ) { SetOneTermToReg_RealCalc(oldType.GetBasicType(),&xmm_reg); pobj_reg->UnlockXmmReg(); reg=pobj_reg->LockReg(); //整数型へデータ変換 ChangeTypeToWhole(oldType,castType,reg,xmm_reg); if(reg==REG_R14){ //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用 pobj_sf->push(REG_R14); } } else{ reg=pobj_reg->GetLockingReg(); if(reg==REG_R14){ //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用 pobj_sf->pop(REG_R14); } //整数型へデータ変換 ChangeTypeToWhole(oldType,castType,reg,0); if(reg==REG_R14){ //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用 pobj_sf->push(REG_R14); } } } type[sp-2] = castType.GetBasicType(); index_stack[sp-2] = castType.GetIndex(); sp--; *pStackPointer=sp; return 1; }