#include "../BasicCompiler_Common/common.h" #include "Opcode.h" void SetRealVariable(int type,RELATIVE_VAR *pRelativeVar){ if(pRelativeVar->dwKind==VAR_GLOBAL){ if(pRelativeVar->bOffsetOffset){ //fstp ptr[ecx+offset] op_fstp_base_offset(type,REG_ECX,(int)pRelativeVar->offset); obp-=sizeof(long); pobj_GlobalVarSchedule->add(); obp+=sizeof(long); } else{ //mov ecx,offset op_mov_RV(REG_ECX,(int)pRelativeVar->offset); obp-=sizeof(long); pobj_GlobalVarSchedule->add(); obp+=sizeof(long); //fstp ptr[ecx] op_fstp_basereg(type,REG_ECX); } } else if(pRelativeVar->dwKind==VAR_REFGLOBAL){ if(pRelativeVar->bOffsetOffset){ //add ecx,qword ptr[offset] op_add_RM(sizeof(long),REG_ECX,REG_NON,(int)pRelativeVar->offset,MOD_DISP32); } else{ //mov ecx,qword ptr[offset] op_mov_RM(sizeof(long),REG_ECX,REG_NON,(int)pRelativeVar->offset,MOD_DISP32); } obp-=sizeof(long); pobj_GlobalVarSchedule->add(); obp+=sizeof(long); goto directmem; } else if(pRelativeVar->dwKind==VAR_LOCAL){ if(pRelativeVar->bOffsetOffset){ //fstp ptr[ebp+ecx+offset] op_fstp_base_offset_ex(type,REG_EBP,REG_ECX,(int)pRelativeVar->offset,USE_OFFSET); } else{ //fstp ptr[ebp+offset] op_fstp_base_offset(type,REG_EBP,(int)pRelativeVar->offset); } obp-=sizeof(long); AddLocalVarAddrSchedule(); obp+=sizeof(long); } else if(pRelativeVar->dwKind==VAR_REFLOCAL){ if(pRelativeVar->bOffsetOffset){ //add ecx,qword ptr[ebp+offset] op_add_RM(sizeof(long),REG_ECX,REG_EBP,(int)pRelativeVar->offset,MOD_BASE_DISP32); } else{ //mov ecx,qword ptr[ebp+offset] op_mov_RM(sizeof(long),REG_ECX,REG_EBP,(int)pRelativeVar->offset,MOD_BASE_DISP32); } obp-=sizeof(long); AddLocalVarAddrSchedule(); obp+=sizeof(long); goto directmem; } else if(pRelativeVar->dwKind==VAR_DIRECTMEM){ directmem: //fstp ptr[ecx] op_fstp_basereg(type,REG_ECX); } } void ExtendTypeTo32(int type,int reg); void ExtendTypeTo64(int type){ if(Is64Type(type)) return; ExtendTypeTo32(type,REG_EAX); if(IsSignedType(type)){ //cdq op_cdq(); } else{ //xor edx,edx op_zero_reg(REG_EDX); } } void ExtendTypeTo32(int type,int reg){ if(type==DEF_INTEGER || (isUnicode&&type==DEF_CHAR)){ //movsx reg32,reg16 op_movsx_R32R16(reg,reg); } else if(type==DEF_WORD){ //and reg,0000FFFFh op_and_RV(reg,(int)0x0000FFFF); } else if(type==DEF_SBYTE || (isUnicode==false&&type==DEF_CHAR)){ //movsx reg32,reg8 op_movsx_R32R8(reg,reg); } else if(type==DEF_BYTE||type==DEF_BOOLEAN){ //and reg,000000FFh op_and_RV(reg,(int)0xFF); } } void ExtendTypeTo16(int type,int reg){ if(type==DEF_SBYTE || (isUnicode==false&&type==DEF_CHAR)){ //movsx reg16,reg8 op_movsx_R16R8(reg,reg); } else if(type==DEF_BYTE||type==DEF_BOOLEAN){ //and reg,000000FFh op_and_RV(reg,(int)0xFF); } } void SetWholeVariable(int var_size,int type,RELATIVE_VAR *pRelative,int reg){ if(type==DEF_DOUBLE){ //Double型 } else if(type==DEF_SINGLE){ //Single型 } else{ //その他の整数 if(var_size==sizeof(_int64)){ //eaxの値を64ビット(edx:eax)に拡張する ExtendTypeTo64(type); } else if(var_size==sizeof(long)){ //レジスタの値を32ビット(eax)に拡張する ExtendTypeTo32(type,reg); } else if(var_size==sizeof(short)){ //レジスタの値を16ビット(ax)に拡張する ExtendTypeTo16(type,reg); } //8ビットは拡張なし } if(var_size==sizeof(_int64)){ //下位32ビット SetWholeVariable(sizeof(long),DEF_LONG,pRelative,REG_EAX); //上位32ビット pRelative->offset+=sizeof(long); SetWholeVariable(sizeof(long),DEF_LONG,pRelative,REG_EDX); pRelative->offset-=sizeof(long); return; } if(pRelative->dwKind==VAR_GLOBAL){ if(pRelative->bOffsetOffset){ //mov ptr[ecx+offset],eax/ax/al op_mov_MR(var_size,reg,REG_ECX,(int)pRelative->offset,MOD_BASE_DISP32); } else{ //mov ptr[offset],eax/ax/al op_mov_MR(var_size,reg,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 ecx,qword ptr[offset] op_add_RM(var_size,REG_ECX,REG_NON,(int)pRelative->offset,MOD_DISP32); } else{ //mov ecx,qword ptr[offset] op_mov_RM(var_size,REG_ECX,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[ebp+ecx+offset],eax/ax/al op_mov_MR_ex(var_size,reg,REG_EBP,REG_ECX,(int)pRelative->offset,USE_OFFSET); } else{ //mov ptr[ebp+offset],eax/ax/al op_mov_MR(var_size,reg,REG_EBP,(int)pRelative->offset,MOD_BASE_DISP32); } obp-=sizeof(long); AddLocalVarAddrSchedule(); obp+=sizeof(long); } else if(pRelative->dwKind==VAR_REFLOCAL){ if(pRelative->bOffsetOffset){ //add ecx,qword ptr[ebp+offset] op_add_RM(var_size,REG_ECX,REG_EBP,(int)pRelative->offset,MOD_BASE_DISP32); } else{ //mov ecx,qword ptr[ebp+offset] op_mov_RM(var_size,REG_ECX,REG_EBP,(int)pRelative->offset,MOD_BASE_DISP32); } obp-=sizeof(long); AddLocalVarAddrSchedule(); obp+=sizeof(long); goto directmem; } else if(pRelative->dwKind==VAR_DIRECTMEM){ directmem: //mov ptr[ecx],eax/ax/al op_mov_MR(var_size,reg,REG_ECX,0,MOD_BASE); } } void SetVariableFromReg(int VarType,int CalcType,RELATIVE_VAR *pRelativeVar){ ///////////////////////////////////////////////// // raxの内容を変数にコピーするコードを抽出 ///////////////////////////////////////////////// if(VarType==DEF_DOUBLE){ //Double型変数へスタックの内容を格納する SetRealVariable(VarType,pRelativeVar); } else if(VarType==DEF_SINGLE){ //Single型変数へスタックの内容を格納する SetRealVariable(VarType,pRelativeVar); } else{ //整数型 SetWholeVariable(GetTypeSize(VarType,-1),CalcType,pRelativeVar,REG_EAX); } } void IncDec(int idCalc, char *lpszLeft, char *lpszRight){ int VarType; LONG_PTR lpVarIndex; RELATIVE_VAR VarRelativeVar; /////////////////////////// // 変数アドレスを取得 /////////////////////////// if(!GetVarOffsetReadWrite( lpszLeft, &VarType, &VarRelativeVar, &lpVarIndex)) return; if(IsUse_ecx(&VarRelativeVar)){ //push ecx op_push(REG_ECX); } /////////////////////////////////// // レジスタへ変数の内容をコピー /////////////////////////////////// if(IsRealNumberType(VarType)){ //実数 SetReg_RealVariable(VarType,&VarRelativeVar); } else{ //整数 SetReg_WholeVariable(VarType,&VarRelativeVar,REG_EAX); } if(IsWholeNumberType(VarType)&&lstrcmp(lpszRight,"1")==0&& (idCalc==CALC_ADDITION||idCalc==CALC_SUBTRACTION)){ //////////////////////////////////////////// // 整数型のインクリメント・デクリメント //////////////////////////////////////////// if(Is64Type(VarType)){ if(idCalc==CALC_ADDITION){ //64ビット インクリメント //add eax,1 op_add_RV8(REG_EAX,1); //adc edx,0 op_adc_RV8(REG_EDX,0); } else if(idCalc==CALC_SUBTRACTION){ //64ビット デクリメント //sub eax,1 op_sub_RV8(REG_EAX,1); //sbb edx,0 op_sbb_RV8(REG_EDX,0); } } else{ if(idCalc==CALC_ADDITION){ //インクリメント op_inc(REG_EAX); } else if(idCalc==CALC_SUBTRACTION){ //デクリメント op_dec(REG_EAX); } } } else{ //変数オフセットを一時退避 //push ecx op_push(REG_ECX); if(VarType==DEF_DOUBLE){ //sub esp,8 op_sub_esp(8); //fstp qword ptr[esp] op_fstp_basereg(VarType,REG_ESP); } else if(VarType==DEF_SINGLE){ //sub esp,4 op_sub_esp(4); //fstp dword ptr[esp] op_fstp_basereg(VarType,REG_ESP); } else if(Is64Type(VarType)){ //push edx op_push(REG_EDX); //push eax op_push(REG_EAX); } else{ //push eax op_push(REG_EAX); } int CalcType; CalcType=NumOpe(lpszRight,VarType,lpVarIndex,0); if(VarType==DEF_DOUBLE) ChangeTypeToDouble(CalcType); else if(VarType==DEF_SINGLE) ChangeTypeToSingle(CalcType); else ChangeTypeToWhole(CalcType,VarType); int type[255],sp; LONG_PTR index_stack[255]; type[0]=VarType; type[1]=VarType; index_stack[0]=lpVarIndex; index_stack[1]=lpVarIndex; sp=2; switch(idCalc){ case CALC_XOR: Calc_Xor(type,index_stack,&sp); break; case CALC_OR: Calc_Or(type,index_stack,&sp); break; case CALC_AND: Calc_And(type,index_stack,&sp); break; case CALC_SHL: Calc_SHL(type,&sp); break; case CALC_SHR: Calc_SHR(type,&sp); break; case CALC_ADDITION: case CALC_SUBTRACTION: case CALC_PRODUCT: CalcTwoTerm_Arithmetic(idCalc,type,index_stack,&sp); break; case CALC_MOD: Calc_Mod(type,&sp); break; case CALC_QUOTIENT: Calc_Divide(type,&sp,VarType); break; case CALC_INTQUOTIENT: Calc_IntDivide(type,index_stack,&sp); break; case CALC_POWER: Calc_Power(type,&sp); break; } if(VarType==DEF_DOUBLE){ //fld qword ptr[esp] op_fld_basereg(VarType,REG_ESP); //add esp,8 op_add_esp(8); } else if(VarType==DEF_SINGLE){ //fld dword ptr[esp] op_fld_basereg(VarType,REG_ESP); //add esp,4 op_add_esp(4); } else if(Is64Type(VarType)){ //pop eax op_pop(REG_EAX); //pop edx op_pop(REG_EDX); } else{ //pop eax op_pop(REG_EAX); } //変数オフセットを復元 //pop ecx op_pop(REG_ECX); } ///////////////////////////////////////////////// // レジスタの内容を変数にコピー ///////////////////////////////////////////////// if(IsUse_ecx(&VarRelativeVar)){ //pop ecx op_pop(REG_ECX); } SetVariableFromReg(VarType,VarType,&VarRelativeVar); }