#include "../BasicCompiler_Common/common.h" #include "Opcode.h" void ExtendTypeTo64(int type,int reg){ if(type==DEF_LONG){ //movsxd reg64,reg32 op_movsxd(reg,reg); } else if(type==DEF_DWORD){ //and reg,00000000FFFFFFFFh } else if(type==DEF_INTEGER){ //movsx reg64,reg16 op_movsx64_FromReg16(reg,reg); } else if(type==DEF_WORD){ //and reg,000000000000FFFFh op_and64_value(reg,(int)0xFFFF); } else if(type==DEF_CHAR){ //movsx reg64,reg8 op_movsx64_FromReg8(reg,reg); } else if(type==DEF_BYTE){ //and reg,00000000000000FFh op_and64_value(reg,(int)0x00FF); } } void ExtendTypeTo32(int type,int reg){ if(type==DEF_INTEGER){ //movsx reg32,reg16 op_movsx32_FromReg16(reg,reg); } else if(type==DEF_WORD){ //and reg,0000FFFFh op_and32_value(reg,(int)0xFFFF); } else if(type==DEF_CHAR){ //movsx reg32,reg8 op_movsx32_FromReg8(reg,reg); } else if(type==DEF_BYTE){ //and reg,000000FFh op_and32_value(reg,(int)0xFF); } } void ExtendTypeTo16(int type,int reg){ if(type==DEF_CHAR){ //movsx reg16,reg8 op_movsx16_FromReg8(reg,reg); } else if(type==DEF_BYTE){ //and reg,000000FFh 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 op_cvtss2sd(xmm_reg,xmm_reg); } else if(Is64Type(type)){ //64ビット整数型 //cvtsi2sd xmm_reg,reg op_cvtsi2sd_reg(sizeof(_int64),xmm_reg,general_reg); if(type==DEF_QWORD){ //符号なし //test reg,reg op_test(general_reg,general_reg); //jge 9 OpBuffer[obp++]=(char)0x7D; OpBuffer[obp++]=(char)0x09; //addsd xmm_reg,qword ptr[offset] ※offset value:43f0000000000000 int temp; _int64 i64data=0x43f0000000000000; temp=AddDataTable((char *)&i64data,sizeof(_int64)); OpBuffer[obp++]=(char)0xF2; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x58; OpBuffer[obp++]=(char)(0x04 | REGISTER_OPERAND(xmm_reg)<<3); OpBuffer[obp++]=(char)0x25; *((long *)(OpBuffer+obp))=temp; pobj_DataTableSchedule->add(); obp+=sizeof(long); } } else if(type==DEF_DWORD){ //符号なし32ビット値 //64ビットにレジスタ値を拡張 ExtendTypeTo64(type,general_reg); //cvtsi2sd xmm_reg,reg op_cvtsi2sd_reg(sizeof(_int64),xmm_reg,general_reg); } else{ //その他整数 //32ビットにレジスタ値を拡張 ExtendTypeTo32(type,general_reg); //cvtsi2sd xmm_reg,reg 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 op_cvtsd2ss(xmm_reg,xmm_reg); } else if(type==DEF_SINGLE){ //なにもしない } else if(Is64Type(type)){ //64ビット整数型 //cvtsi2ss xmm_reg,reg op_cvtsi2ss_reg(sizeof(_int64),xmm_reg,general_reg); if(type==DEF_QWORD){ //符号なし //test reg,reg op_test(general_reg,general_reg); //jge 9 OpBuffer[obp++]=(char)0x7D; OpBuffer[obp++]=(char)0x09; //addss xmm_reg,dword ptr[offset] ※offset value:5f800000 int temp; long i32data=0x5f800000; temp=AddDataTable((char *)&i32data,sizeof(long)); OpBuffer[obp++]=(char)0xF3; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x58; OpBuffer[obp++]=(char)(0x04 | REGISTER_OPERAND(xmm_reg)<<3); OpBuffer[obp++]=(char)0x25; *((long *)(OpBuffer+obp))=temp; pobj_DataTableSchedule->add(); obp+=sizeof(long); } } else if(type==DEF_DWORD){ //符号なし32ビット値 //64ビットにレジスタ値を拡張 ExtendTypeTo64(type,general_reg); //cvtsi2ss xmm_reg,reg op_cvtsi2ss_reg(sizeof(_int64),xmm_reg,general_reg); } else{ //その他整数 //32ビットにレジスタ値を拡張 ExtendTypeTo32(type,general_reg); //cvtsi2ss xmm_reg,reg op_cvtsi2ss_reg(sizeof(long),xmm_reg,general_reg); } } void ChangeTypeToWhole(int OldType,int NewType,int reg,int xmm_reg){ if(OldType==DEF_DOUBLE){ if(Is64Type(NewType)){ //cvttsd2si reg,xmm_reg op_cvttsd2si_xmm(sizeof(_int64),reg,xmm_reg); } else{ //cvttsd2si reg,xmm_reg op_cvttsd2si_xmm(sizeof(long),reg,xmm_reg); } } else if(OldType==DEF_SINGLE){ if(Is64Type(NewType)){ //cvttss2si reg,xmm_reg op_cvttss2si_xmm(sizeof(_int64),reg,xmm_reg); } else{ //cvttss2si reg,xmm_reg op_cvttss2si_xmm(sizeof(long),reg,xmm_reg); } } else{ //整数から整数へ変換 if(Is64Type(NewType)){ ExtendTypeTo64(OldType,reg); } else if(GetTypeSize(NewType,-1)==sizeof(long)){ ExtendTypeTo32(OldType,reg); } else if(GetTypeSize(NewType,-1)==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 OpBuffer[obp++]=(char)0xF2; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x10; OpBuffer[obp++]=(char)(0xE8 | REGISTER_OPERAND(xmm_reg2)); } if(type[sp-1]==DEF_SINGLE){ //movss xmm5,xmm_reg OpBuffer[obp++]=(char)0xF3; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x10; OpBuffer[obp++]=(char)(0xE8 | REGISTER_OPERAND(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 CastType; CastType=type[sp-1]; if((CastType&FLAG_CAST)==0){ SetError(47,NULL,cp); return 0; } CastType=CastType&(~FLAG_CAST); int xmm_reg,reg; if(IsRealNumberType(CastType)){ //実数型へキャスト if(IsRealNumberType(type[sp-2])){ SetOneTermToReg_RealCalc(type[sp-2],&xmm_reg); } else{ if(Is64Type(type[sp-2])) SetOneTermToReg_Whole64Calc(type[sp-2],®); else if(IsWholeNumberType(type[sp-2])) SetOneTermToReg_Whole32Calc(type[sp-2],®); pobj_reg->UnlockReg(); xmm_reg=pobj_reg->LockXmmReg(); } if(CastType==DEF_DOUBLE){ //Double型にデータ変換 ChangeTypeToXmm_Double(type[sp-2],xmm_reg,reg); } else if(CastType==DEF_SINGLE){ //Single型にデータ変換 ChangeTypeToXmm_Single(type[sp-2],xmm_reg,reg); } if(xmm_reg==REG_XMM4){ //movsd qword ptr[rsp+offset],xmm4 ※スタックフレームを利用 pobj_sf->push(REG_XMM4,sizeof(double)); } } else{ //その他整数型へ変換 if(IsRealNumberType(type[sp-2])){ SetOneTermToReg_RealCalc(type[sp-2],&xmm_reg); pobj_reg->UnlockXmmReg(); reg=pobj_reg->LockReg(); //整数型へデータ変換 ChangeTypeToWhole(type[sp-2],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(type[sp-2],CastType,reg,0); if(reg==REG_R14){ //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用 pobj_sf->push(REG_R14); } } } type[sp-2]=CastType; index_stack[sp-2]=index_stack[sp-1]; sp--; *pStackPointer=sp; return 1; }