#include "stdafx.h" #include #include "../BasicCompiler_Common/common.h" #include "Opcode.h" void IncDec(int idCalc, const char *lpszLeft, const char *lpszRight) { Type varType; if( GetVarType( lpszLeft, varType, false ) ) { if( varType.IsObject() ) { // オブジェクトが対象だったとき char temporary[8192]; char calcStr[32]; GetCalcName( idCalc, calcStr ); sprintf( temporary, "%s=%s %s %s", lpszLeft, lpszLeft, calcStr, lpszRight ); SetEscapeSequenceFormat( temporary ); KillStringSpaces( temporary ); OpcodeCalc( temporary ); return; } } /////////////////////////// // 変数アドレスを取得 /////////////////////////// RELATIVE_VAR VarRelativeVar; if(!GetVarOffsetReadWrite( lpszLeft, &VarRelativeVar, varType)) return; if(IsUse_ecx(&VarRelativeVar)){ //push ecx compiler.codeGenerator.op_push(REG_ECX); } /////////////////////////////////// // レジスタへ変数の内容をコピー /////////////////////////////////// if( varType.IsReal() ){ //実数 SetReg_RealVariable(varType.GetBasicType(),&VarRelativeVar); } else{ //整数 SetReg_WholeVariable(varType,&VarRelativeVar,REG_EAX); } if(varType.IsWhole()&&lstrcmp(lpszRight,"1")==0&& (idCalc==CALC_ADDITION||idCalc==CALC_SUBTRACTION)){ //////////////////////////////////////////// // 整数型のインクリメント・デクリメント //////////////////////////////////////////// if( varType.Is64() ){ if(idCalc==CALC_ADDITION){ //64ビット インクリメント //add eax,1 compiler.codeGenerator.op_add_RV8(REG_EAX,1); //adc edx,0 compiler.codeGenerator.op_adc_RV8(REG_EDX,0); } else if(idCalc==CALC_SUBTRACTION){ //64ビット デクリメント //sub eax,1 compiler.codeGenerator.op_sub_RV8(REG_EAX,1); //sbb edx,0 compiler.codeGenerator.op_sbb_RV8(REG_EDX,0); } } else{ if(idCalc==CALC_ADDITION){ //インクリメント compiler.codeGenerator.op_inc(REG_EAX); } else if(idCalc==CALC_SUBTRACTION){ //デクリメント compiler.codeGenerator.op_dec(REG_EAX); } } } else{ //変数オフセットを一時退避 //push ecx compiler.codeGenerator.op_push(REG_ECX); if( varType.IsDouble() ){ //sub esp,8 compiler.codeGenerator.op_sub_esp(8); //fstp qword ptr[esp] compiler.codeGenerator.op_fstp_basereg(varType.GetBasicType(),REG_ESP); } else if( varType.IsSingle() ){ //sub esp,4 compiler.codeGenerator.op_sub_esp(4); //fstp dword ptr[esp] compiler.codeGenerator.op_fstp_basereg(varType.GetBasicType(),REG_ESP); } else if( varType.Is64() ){ //push edx compiler.codeGenerator.op_push(REG_EDX); //push eax compiler.codeGenerator.op_push(REG_EAX); } else{ //push eax compiler.codeGenerator.op_push(REG_EAX); } Type calcType; if( !NumOpe(lpszRight,varType,calcType) ){ return; } if( varType.IsDouble() ) ChangeTypeToDouble(calcType.GetBasicType()); else if( varType.IsSingle() ) ChangeTypeToSingle(calcType.GetBasicType()); else ChangeTypeToWhole( calcType, varType ); int type_stack[255],sp; LONG_PTR index_stack[255]; type_stack[0]=varType.GetBasicType(); type_stack[1]=varType.GetBasicType(); index_stack[0]=varType.GetIndex(); index_stack[1]=varType.GetIndex(); sp=2; switch(idCalc){ case CALC_XOR: Calc_Xor(type_stack,index_stack,&sp); break; case CALC_OR: Calc_Or(type_stack,index_stack,&sp); break; case CALC_AND: Calc_And(type_stack,index_stack,&sp); break; case CALC_SHL: Calc_SHL(type_stack,&sp); break; case CALC_SHR: Calc_SHR(type_stack,&sp); break; case CALC_ADDITION: case CALC_SUBTRACTION: case CALC_PRODUCT: CalcTwoTerm_Arithmetic(idCalc,type_stack,index_stack,&sp); break; case CALC_MOD: Calc_Mod(type_stack,&sp); break; case CALC_QUOTIENT: Calc_Divide(type_stack,&sp,varType.GetBasicType()); break; case CALC_INTQUOTIENT: Calc_IntDivide(type_stack,index_stack,&sp); break; case CALC_POWER: Calc_Power(type_stack,&sp); break; } if( varType.IsDouble() ){ //fld qword ptr[esp] compiler.codeGenerator.op_fld_basereg(varType.GetBasicType(),REG_ESP); //add esp,8 compiler.codeGenerator.op_add_esp(8); } else if( varType.IsSingle() ){ //fld dword ptr[esp] compiler.codeGenerator.op_fld_basereg(varType.GetBasicType(),REG_ESP); //add esp,4 compiler.codeGenerator.op_add_esp(4); } else if( varType.Is64() ){ //pop eax compiler.codeGenerator.op_pop(REG_EAX); //pop edx compiler.codeGenerator.op_pop(REG_EDX); } else{ //pop eax compiler.codeGenerator.op_pop(REG_EAX); } //変数オフセットを復元 //pop ecx compiler.codeGenerator.op_pop(REG_ECX); } ///////////////////////////////////////////////// // レジスタの内容を変数にコピー ///////////////////////////////////////////////// if(IsUse_ecx(&VarRelativeVar)){ //pop ecx compiler.codeGenerator.op_pop(REG_ECX); } SetVariableFromEax(varType,varType.GetBasicType(),&VarRelativeVar); }