#include "../BasicCompiler_Common/common.h" #include "Opcode.h" BOOL IsUse_r11(RELATIVE_VAR *pRelativeVar){ if(pRelativeVar->bOffsetOffset||pRelativeVar->dwKind==VAR_DIRECTMEM) return 1; return 0; } void SetStructVariableFromRax(LONG_PTR lpVarIndex,int CalcType,LONG_PTR lpCalcIndex,RELATIVE_VAR *pRelativeVar,BOOL bUseHeap){ int RightTermReg; pobj_reg=new CRegister(REG_RCX); //VarRegにオブジェクトポインタをコピー int VarReg; VarReg=pobj_reg->LockReg(); SetVarPtrToReg(VarReg,pRelativeVar); //右辺 if(IsRealNumberType(CalcType)){ RightTermReg=pobj_reg->LockXmmReg(); if(CalcType==DEF_DOUBLE){ //movlsd RightTermReg,xmm0 op_movsd_RR(RightTermReg,REG_XMM0); } else if(CalcType==DEF_SINGLE){ //movlss RightTermReg,xmm0 op_movss_RR(RightTermReg,REG_XMM0); } } else{ RightTermReg=pobj_reg->LockReg(); //mov RightTermReg,rax op_mov_RR(RightTermReg,REG_RAX); } /* TODO: 消す /////////////////////////////////////////////////////////////////// // オペレータ '=' のオーバーロード関数を呼ぶ /////////////////////////////////////////////////////////////////// int type[10]; LONG_PTR index_stack[10]; BOOL array_bUseHeap[10]; int sp=2; //左辺 type[0]=DEF_OBJECT; index_stack[0]=lpVarIndex; array_bUseHeap[0]=0; //右辺 type[1]=CalcType; index_stack[1]=lpCalcIndex; array_bUseHeap[1]=bUseHeap; int iRet; iRet=CallOperatorProc(CALC_SUBSITUATION,NULL,type,index_stack,array_bUseHeap,sp); */ //右辺用レジスタを解除 if(IsRealNumberType(CalcType)) pobj_reg->UnlockXmmReg(); else pobj_reg->UnlockReg(); //左辺用レジスタを解除 pobj_reg->UnlockReg(); //レジスタ管理オブジェクトを破棄 delete pobj_reg; pobj_reg=0; if( CalcType == DEF_STRUCT ){ CClass *pVarClass = (CClass *)lpVarIndex; CClass *pCalcClass = (CClass *)lpCalcIndex; if( pVarClass->IsEquals( pCalcClass ) ){ //等しい //双方のオブジェクト型が一致、または派生・継承関係にあるとき //※コピーを行う //mov rsi,RightTermReg op_mov_RR(REG_RSI,RightTermReg); //mov rdi,VarReg op_mov_RR(REG_RDI,VarReg); CClass *pClass = (CClass *)lpVarIndex; int object_size = pClass->GetSize(); //mov rcx,object_size op_mov_RV(sizeof(_int64),REG_RCX,object_size); if(bUseHeap){ //mov rax,rsi op_mov_RR(REG_RAX,REG_RSI); } //rep movs byte ptr[rdi],byte ptr[rsi] op_rep_movs(sizeof(BYTE)); if(bUseHeap){ //mov rcx,rax op_mov_RR(REG_RCX,REG_RAX); //call free extern SUBINFO *pSub_free; op_call(pSub_free); } return; } } SetError(1,NULL,cp); } void SetDoubleVariable(int type,RELATIVE_VAR *pRelative){ ////////////////////////// // Double型変数に書き込む ////////////////////////// //xmm0に型変換 ChangeTypeToXmm_Double(type,REG_XMM0,REG_RAX); if(pRelative->dwKind==VAR_GLOBAL){ if(pRelative->bOffsetOffset){ //movsd qword ptr[r11+offset],xmm0 OpBuffer[obp++]=(char)0xF2; OpBuffer[obp++]=(char)0x41; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x11; OpBuffer[obp++]=(char)0x83; *((long *)(OpBuffer+obp))=(int)pRelative->offset; pobj_GlobalVarSchedule->add(); obp+=sizeof(long); } else{ //movsd qword ptr[offset],xmm0 OpBuffer[obp++]=(char)0xF2; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x11; OpBuffer[obp++]=(char)0x04; OpBuffer[obp++]=(char)0x25; *((long *)(OpBuffer+obp))=(int)pRelative->offset; pobj_GlobalVarSchedule->add(); obp+=sizeof(long); } } else if(pRelative->dwKind==VAR_REFGLOBAL){ SetError(300,NULL,cp); } else if(pRelative->dwKind==VAR_LOCAL){ if(pRelative->bOffsetOffset){ //movsd qword ptr[rsp+r11+offset],xmm0 OpBuffer[obp++]=(char)0xF2; OpBuffer[obp++]=(char)0x42; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x11; OpBuffer[obp++]=(char)0x84; OpBuffer[obp++]=(char)0x1C; *((long *)(OpBuffer+obp))=(int)pRelative->offset; AddLocalVarAddrSchedule(); obp+=sizeof(long); } else{ //movsd qword ptr[rsp+offset],xmm0 OpBuffer[obp++]=(char)0xF2; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x11; OpBuffer[obp++]=(char)0x84; OpBuffer[obp++]=(char)0x24; *((long *)(OpBuffer+obp))=(int)pRelative->offset; AddLocalVarAddrSchedule(); obp+=sizeof(long); } } else if( pRelative->dwKind == VAR_REFLOCAL ){ if(pRelative->bOffsetOffset){ //add r11,qword ptr[rsp+offset] OpBuffer[obp++]=(char)0x4C; OpBuffer[obp++]=(char)0x03; OpBuffer[obp++]=(char)0x9C; OpBuffer[obp++]=(char)0x24; *((long *)(OpBuffer+obp))=(int)pRelative->offset; AddLocalVarAddrSchedule(); obp+=sizeof(long); } else{ //mov r11,qword ptr[rsp+offset] op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32); obp-=sizeof(long); AddLocalVarAddrSchedule(); obp+=sizeof(long); } goto directmem; } else if(pRelative->dwKind==VAR_DIRECTMEM){ directmem: //movsd qword ptr[r11],xmm0 OpBuffer[obp++]=(char)0xF2; OpBuffer[obp++]=(char)0x41; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x11; OpBuffer[obp++]=(char)0x03; } } void SetSingleVariable(int type,RELATIVE_VAR *pRelative){ ////////////////////////// // Single型変数に書き込む ////////////////////////// //xmm0に型変換 ChangeTypeToXmm_Single(type,REG_XMM0,REG_RAX); if(pRelative->dwKind==VAR_GLOBAL){ if(pRelative->bOffsetOffset){ //movss dword ptr[r11+offset],xmm0 OpBuffer[obp++]=(char)0xF3; OpBuffer[obp++]=(char)0x41; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x11; OpBuffer[obp++]=(char)0x83; *((long *)(OpBuffer+obp))=(int)pRelative->offset; pobj_GlobalVarSchedule->add(); obp+=sizeof(long); } else{ //movss dword ptr[offset],xmm0 OpBuffer[obp++]=(char)0xF3; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x11; OpBuffer[obp++]=(char)0x04; OpBuffer[obp++]=(char)0x25; *((long *)(OpBuffer+obp))=(int)pRelative->offset; pobj_GlobalVarSchedule->add(); obp+=sizeof(long); } } else if(pRelative->dwKind==VAR_REFGLOBAL){ SetError(300,NULL,cp); } else if(pRelative->dwKind==VAR_LOCAL){ if(pRelative->bOffsetOffset){ //movss dword ptr[rsp+r11+offset],xmm0 OpBuffer[obp++]=(char)0xF3; OpBuffer[obp++]=(char)0x42; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x11; OpBuffer[obp++]=(char)0x84; OpBuffer[obp++]=(char)0x1C; *((long *)(OpBuffer+obp))=(int)pRelative->offset; AddLocalVarAddrSchedule(); obp+=sizeof(long); } else{ //movss dword ptr[rsp+offset],xmm0 OpBuffer[obp++]=(char)0xF3; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x11; OpBuffer[obp++]=(char)0x84; OpBuffer[obp++]=(char)0x24; *((long *)(OpBuffer+obp))=(int)pRelative->offset; AddLocalVarAddrSchedule(); obp+=sizeof(long); } } else if( pRelative->dwKind == VAR_REFLOCAL ){ if(pRelative->bOffsetOffset){ //add r11,qword ptr[rsp+offset] OpBuffer[obp++]=(char)0x4C; OpBuffer[obp++]=(char)0x03; OpBuffer[obp++]=(char)0x9C; OpBuffer[obp++]=(char)0x24; *((long *)(OpBuffer+obp))=(int)pRelative->offset; AddLocalVarAddrSchedule(); obp+=sizeof(long); } else{ //mov r11,qword ptr[rsp+offset] op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32); obp-=sizeof(long); AddLocalVarAddrSchedule(); obp+=sizeof(long); } goto directmem; } else if(pRelative->dwKind==VAR_DIRECTMEM){ directmem: //movss dword ptr[r11],xmm0 OpBuffer[obp++]=(char)0xF3; OpBuffer[obp++]=(char)0x41; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x11; OpBuffer[obp++]=(char)0x03; } } void SetRealVariable(int VarType, int CalcType, RELATIVE_VAR *pRelativeVar){ if(VarType==DEF_DOUBLE){ //Double型変数へスタックの内容を格納する SetDoubleVariable(CalcType,pRelativeVar); } else if(VarType==DEF_SINGLE){ //Single型変数へスタックの内容を格納する SetSingleVariable(CalcType,pRelativeVar); } } void SetBooleanVariable(int type,RELATIVE_VAR *pRelative){ if(type==DEF_DOUBLE){ //Double型 //cvttsd2si rax,xmm0 op_cvttsd2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0); } else if(type==DEF_SINGLE){ //Single型 //cvttss2si rax,xmm0 op_cvttss2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0); } //cmp rax,0 op_cmp_value(GetTypeSize(type,-1),REG_RAX,0); //setne al op_setne( REG_RAX ); SetWholeVariable( sizeof(char), DEF_BYTE, pRelative); } void SetWholeVariable(int var_size,int type,RELATIVE_VAR *pRelative){ if(type==DEF_DOUBLE){ //Double型 //cvttsd2si rax,xmm0 op_cvttsd2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0); } else if(type==DEF_SINGLE){ //Single型 //cvttss2si rax,xmm0 op_cvttss2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0); } else{ //その他の整数 if(var_size==sizeof(_int64)){ //レジスタの値を64ビット(rax)に拡張する ExtendTypeTo64(type,REG_RAX); } else if(var_size==sizeof(long)){ //レジスタの値を32ビット(eax)に拡張する ExtendTypeTo32(type,REG_RAX); } else if(var_size==sizeof(short)){ //レジスタの値を16ビット(ax)に拡張する ExtendTypeTo16(type,REG_RAX); } //8ビットは拡張なし } if(pRelative->dwKind==VAR_GLOBAL){ if(pRelative->bOffsetOffset){ //mov ptr[r11+offset],rax/eax/ax/al op_mov_MR(var_size,REG_RAX,REG_R11,(int)pRelative->offset,MOD_BASE_DISP32); obp-=sizeof(long); pobj_GlobalVarSchedule->add(); obp+=sizeof(long); } else{ //mov ptr[offset],rax/eax/ax/al op_mov_MR(var_size,REG_RAX,0,(int)pRelative->offset,MOD_DISP32); obp-=sizeof(long); pobj_GlobalVarSchedule->add(); obp+=sizeof(long); } } else if( pRelative->dwKind == VAR_REFGLOBAL ){ if(pRelative->bOffsetOffset){ //add r11,qword ptr[offset] op_add_RM( sizeof(_int64), REG_R11, REG_NON, (int)pRelative->offset, MOD_DISP32 ); obp-=sizeof(long); pobj_GlobalVarSchedule->add(); obp+=sizeof(long); } else{ //mov r11,qword ptr[offset] op_mov_RM(sizeof(_int64),REG_R11,REG_NON,(int)pRelative->offset,MOD_DISP32); obp-=sizeof(long); pobj_GlobalVarSchedule->add(); obp+=sizeof(long); } goto directmem; } else if(pRelative->dwKind==VAR_LOCAL){ if(pRelative->bOffsetOffset){ //mov ptr[rsp+r11+offset],rax/eax/ax/al op_mov_MR_ex(var_size,REG_RAX,REG_RSP,REG_R11,(int)pRelative->offset,USE_OFFSET); obp-=sizeof(long); AddLocalVarAddrSchedule(); obp+=sizeof(long); } else{ //mov ptr[rsp+offset],rax/eax/ax/al op_mov_MR(var_size,REG_RAX,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32); obp-=sizeof(long); AddLocalVarAddrSchedule(); obp+=sizeof(long); } } else if( pRelative->dwKind == VAR_REFLOCAL ){ if(pRelative->bOffsetOffset){ //add r11,qword ptr[rsp+offset] op_add_RM( sizeof(_int64), REG_R11, REG_RSP, (int)pRelative->offset, MOD_BASE_DISP32 ); obp-=sizeof(long); AddLocalVarAddrSchedule(); obp+=sizeof(long); } else{ //mov r11,qword ptr[rsp+offset] op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32); obp-=sizeof(long); AddLocalVarAddrSchedule(); obp+=sizeof(long); } goto directmem; } else if(pRelative->dwKind==VAR_DIRECTMEM){ directmem: //mov ptr[r11],rax/eax/ax/al op_mov_MR(var_size,REG_RAX,REG_R11,0,MOD_BASE); } }