#include "stdafx.h" #include #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( const Type &varType, const Type &calcType, RELATIVE_VAR *pRelativeVar,BOOL bUseHeap){ int RightTermReg; pobj_reg=new CRegister(REG_RCX); //VarRegにオブジェクトポインタをコピー int VarReg; VarReg=pobj_reg->LockReg(); SetVarPtrToReg(VarReg,pRelativeVar); //右辺 if( calcType.IsReal() ){ RightTermReg=pobj_reg->LockXmmReg(); if( calcType.IsDouble() ){ //movlsd RightTermReg,xmm0 compiler.codeGenerator.op_movsd_RR(RightTermReg,REG_XMM0); } else if( calcType.IsSingle() ){ //movlss RightTermReg,xmm0 compiler.codeGenerator.op_movss_RR(RightTermReg,REG_XMM0); } } else{ RightTermReg=pobj_reg->LockReg(); //mov RightTermReg,rax compiler.codeGenerator.op_mov_RR(RightTermReg,REG_RAX); } //右辺用レジスタを解除 if( calcType.IsReal() ) pobj_reg->UnlockXmmReg(); else pobj_reg->UnlockReg(); //左辺用レジスタを解除 pobj_reg->UnlockReg(); //レジスタ管理オブジェクトを破棄 delete pobj_reg; pobj_reg=0; if( calcType.IsStruct() ){ if( varType.GetClass().IsEquals( &calcType.GetClass() ) ){ //等しい //双方のオブジェクト型が一致、または派生・継承関係にあるとき //※コピーを行う //mov rsi,RightTermReg compiler.codeGenerator.op_mov_RR(REG_RSI,RightTermReg); //mov rdi,VarReg compiler.codeGenerator.op_mov_RR(REG_RDI,VarReg); int object_size = varType.GetClass().GetSize(); //mov rcx,object_size compiler.codeGenerator.op_mov_RV(sizeof(_int64),REG_RCX,object_size); if(bUseHeap){ //mov rax,rsi compiler.codeGenerator.op_mov_RR(REG_RAX,REG_RSI); } //rep movs byte ptr[rdi],byte ptr[rsi] compiler.codeGenerator.op_rep_movs(sizeof(BYTE)); if(bUseHeap){ //mov rcx,rax compiler.codeGenerator.op_mov_RR(REG_RCX,REG_RAX); //call free extern const UserProc *pSub_free; compiler.codeGenerator.op_call(pSub_free); } return; } } compiler.errorMessenger.Output(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 compiler.codeGenerator.op_movsd_MR( REG_XMM0, REG_R11, (long)pRelative->offset, MOD_BASE_DISP32, Schedule::GlobalVar ); } else{ //movsd qword ptr[offset],xmm0 compiler.codeGenerator.op_movsd_MR( REG_XMM0, 0, (long)pRelative->offset, MOD_DISP32, Schedule::GlobalVar ); } } else if(pRelative->dwKind==VAR_REFGLOBAL){ compiler.errorMessenger.Output(300,NULL,cp); } else if(pRelative->dwKind==VAR_LOCAL){ if(pRelative->bOffsetOffset){ //movsd qword ptr[rsp+r11+offset],xmm0 compiler.codeGenerator.PutOld( (char)0xF2, (char)0x42, (char)0x0F, (char)0x11, (char)0x84, (char)0x1C ); compiler.codeGenerator.localVarPertialSchedules.push_back( compiler.codeGenerator.PutOld( (long)pRelative->offset, true ) ); } else{ //movsd qword ptr[rsp+offset],xmm0 compiler.codeGenerator.localVarPertialSchedules.push_back( compiler.codeGenerator.op_movsd_MR( REG_XMM0, REG_RSP, (long)pRelative->offset, MOD_BASE_DISP32, Schedule::None, true ) ); } } else if( pRelative->dwKind == VAR_REFLOCAL ){ if(pRelative->bOffsetOffset){ //add r11,qword ptr[rsp+offset] compiler.codeGenerator.localVarPertialSchedules.push_back( compiler.codeGenerator.op_add_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32, Schedule::None, true ) ); } else{ //mov r11,qword ptr[rsp+offset] compiler.codeGenerator.localVarPertialSchedules.push_back( compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32, Schedule::None, true ) ); } goto directmem; } else if(pRelative->dwKind==VAR_DIRECTMEM){ directmem: //movsd qword ptr[r11],xmm0 compiler.codeGenerator.op_movsd_MR( REG_XMM0, REG_R11, 0, MOD_BASE ); } } 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 compiler.codeGenerator.op_movss_MR( REG_XMM0, REG_R11, (long)pRelative->offset, MOD_BASE_DISP32, Schedule::GlobalVar ); } else{ //movss dword ptr[offset],xmm0 compiler.codeGenerator.op_movss_MR( REG_XMM0, 0, (long)pRelative->offset, MOD_DISP32, Schedule::GlobalVar ); } } else if(pRelative->dwKind==VAR_REFGLOBAL){ compiler.errorMessenger.Output(300,NULL,cp); } else if(pRelative->dwKind==VAR_LOCAL){ if(pRelative->bOffsetOffset){ //movss dword ptr[rsp+r11+offset],xmm0 compiler.codeGenerator.PutOld( (char)0xF3, (char)0x42, (char)0x0F, (char)0x11, (char)0x84, (char)0x1C ); compiler.codeGenerator.localVarPertialSchedules.push_back( compiler.codeGenerator.PutOld( (long)pRelative->offset, true ) ); } else{ //movss dword ptr[rsp+offset],xmm0 compiler.codeGenerator.localVarPertialSchedules.push_back( compiler.codeGenerator.op_movss_MR( REG_XMM0, REG_RSP, (long)pRelative->offset, MOD_BASE_DISP32, Schedule::None, true ) ); } } else if( pRelative->dwKind == VAR_REFLOCAL ){ if(pRelative->bOffsetOffset){ //add r11,qword ptr[rsp+offset] compiler.codeGenerator.localVarPertialSchedules.push_back( compiler.codeGenerator.op_add_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32, Schedule::None, true ) ); } else{ //mov r11,qword ptr[rsp+offset] compiler.codeGenerator.localVarPertialSchedules.push_back( compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32, Schedule::None, true ) ); } goto directmem; } else if(pRelative->dwKind==VAR_DIRECTMEM){ directmem: //movss dword ptr[r11],xmm0 compiler.codeGenerator.op_movss_MR( REG_XMM0, REG_R11, 0, MOD_BASE ); } } 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 compiler.codeGenerator.op_cvttsd2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0); } else if(type==DEF_SINGLE){ //Single型 //cvttss2si rax,xmm0 compiler.codeGenerator.op_cvttss2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0); } //cmp rax,0 compiler.codeGenerator.op_cmp_value(Type(type).GetSize(),REG_RAX,0); //setne al compiler.codeGenerator.op_setne( REG_RAX ); SetWholeVariable( sizeof(char), DEF_BYTE, pRelative); } void SetWholeVariable(int varSize,int type,RELATIVE_VAR *pRelative){ if(type==DEF_DOUBLE){ //Double型 //cvttsd2si rax,xmm0 compiler.codeGenerator.op_cvttsd2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0); } else if(type==DEF_SINGLE){ //Single型 //cvttss2si rax,xmm0 compiler.codeGenerator.op_cvttss2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0); } else{ //その他の整数 if(varSize==sizeof(_int64)){ //レジスタの値を64ビット(rax)に拡張する ExtendTypeTo64(type,REG_RAX); } else if(varSize==sizeof(long)){ //レジスタの値を32ビット(eax)に拡張する ExtendTypeTo32(type,REG_RAX); } else if(varSize==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 compiler.codeGenerator.op_mov_MR(varSize,REG_RAX,REG_R11,(int)pRelative->offset,MOD_BASE_DISP32, Schedule::GlobalVar ); } else{ //mov ptr[offset],rax/eax/ax/al compiler.codeGenerator.op_mov_MR(varSize,REG_RAX,0,(int)pRelative->offset,MOD_DISP32, Schedule::GlobalVar ); } } else if( pRelative->dwKind == VAR_REFGLOBAL ){ if(pRelative->bOffsetOffset){ //add r11,qword ptr[offset] compiler.codeGenerator.op_add_RM( sizeof(_int64), REG_R11, REG_NON, (int)pRelative->offset, MOD_DISP32, Schedule::GlobalVar ); } else{ //mov r11,qword ptr[offset] compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_R11,REG_NON,(int)pRelative->offset,MOD_DISP32, Schedule::GlobalVar ); } goto directmem; } else if(pRelative->dwKind==VAR_LOCAL){ if(pRelative->bOffsetOffset){ //mov ptr[rsp+r11+offset],rax/eax/ax/al compiler.codeGenerator.localVarPertialSchedules.push_back( compiler.codeGenerator.op_mov_MR_ex(varSize,REG_RAX,REG_RSP,REG_R11,(int)pRelative->offset,USE_OFFSET, Schedule::None, true ) ); } else{ //mov ptr[rsp+offset],rax/eax/ax/al compiler.codeGenerator.localVarPertialSchedules.push_back( compiler.codeGenerator.op_mov_MR(varSize,REG_RAX,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32, Schedule::None, true ) ); } } else if( pRelative->dwKind == VAR_REFLOCAL ){ if(pRelative->bOffsetOffset){ //add r11,qword ptr[rsp+offset] compiler.codeGenerator.localVarPertialSchedules.push_back( compiler.codeGenerator.op_add_RM( sizeof(_int64), REG_R11, REG_RSP, (int)pRelative->offset, MOD_BASE_DISP32, Schedule::None, true ) ); } else{ //mov r11,qword ptr[rsp+offset] compiler.codeGenerator.localVarPertialSchedules.push_back( compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32, Schedule::None, true ) ); } goto directmem; } else if(pRelative->dwKind==VAR_DIRECTMEM){ directmem: //mov ptr[r11],rax/eax/ax/al compiler.codeGenerator.op_mov_MR(varSize,REG_RAX,REG_R11,0,MOD_BASE); } }