#include "../BasicCompiler_Common/common.h" #include "Opcode.h" 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); } SetVariableFromEax(VarType,VarType,&VarRelativeVar); }