#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(!GetVarOffset( 1, lpszLeft, &VarType, &VarRelativeVar, &lpVarIndex)) return; //変数オフセットを一時退避 if(IsUse_r11(&VarRelativeVar)){ //mov qword ptr[rsp+offset],r11 ※スタックフレームを利用 pobj_sf->push(REG_R11); } /////////////////////////////////// // レジスタへ変数の内容をコピー /////////////////////////////////// int reg; if(VarType==DEF_DOUBLE){ reg=REG_XMM0; SetXmmReg_DoubleVariable(&VarRelativeVar,reg); } else if(VarType==DEF_SINGLE){ reg=REG_XMM0; SetXmmReg_SingleVariable(&VarRelativeVar,reg); } else{ reg=REG_RAX; SetReg_WholeVariable(VarType,&VarRelativeVar,reg); } if(IsWholeNumberType(VarType)&&lstrcmp(lpszRight,"1")==0&& (idCalc==CALC_ADDITION||idCalc==CALC_SUBTRACTION)){ if(idCalc==CALC_ADDITION){ //インクリメント op_inc(REG_RAX); } else if(idCalc==CALC_SUBTRACTION){ //デクリメント op_dec(REG_RAX); } } else{ //結果を格納しているレジスタをブロッキング pobj_BlockReg->lock(reg); //右辺を計算 int CalcType; LONG_PTR lpCalcIndex; if(reg==REG_RAX) reg=REG_RCX; else reg=REG_RAX; CalcType=NumOpe(®,lpszRight,VarType,lpVarIndex,&lpCalcIndex); //レジスタのブロッキングを解除 pobj_BlockReg->clear(); if(IsPtrType(VarType)&&IsWholeNumberType(CalcType)&&(!IsPtrType(CalcType))){ //左辺がポインタ型、右辺が整数型の場合は、エラーをださないようにする CalcType=VarType; lpCalcIndex=lpVarIndex; } ///////////////////////////////// // 右辺、左辺の型チェックを行う ///////////////////////////////// CheckDifferentType(VarType,lpVarIndex,CalcType,lpCalcIndex,0,0); //レジスタ管理オブジェクトを生成 pobj_reg=new CRegister(REG_RAX); //左辺用レジスタ if(IsRealNumberType(VarType)) pobj_reg->LockXmmReg(); else pobj_reg->LockReg(); //右辺値レジスタ if(VarType==DEF_DOUBLE) ChangeTypeToXmm_Double(CalcType, pobj_reg->LockXmmReg(), pobj_reg->GetNextReg()); else if(VarType==DEF_SINGLE) ChangeTypeToXmm_Single(CalcType, pobj_reg->LockXmmReg(), pobj_reg->GetNextReg()); else ChangeTypeToWhole(CalcType,VarType, pobj_reg->LockReg(), pobj_reg->GetNextXmmReg()); 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: case CALC_OR: case CALC_AND: CalcTwoTerm_Logical(idCalc,type,index_stack,&sp); break; case CALC_SHL: case CALC_SHR: Calc_Shift(idCalc,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,index_stack,&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; } //レジスタ管理オブジェクトを解放 delete pobj_reg; pobj_reg=0; } ///////////////////////////////////////////////// // rax(実数はxmm0)の内容を変数にコピー ///////////////////////////////////////////////// //変数オフセットを復元 if(IsUse_r11(&VarRelativeVar)){ //mov r11,qword ptr[rsp+offset] ※スタックフレームを利用 pobj_sf->pop(REG_R11); } SetVariableFromRax(VarType,VarType,&VarRelativeVar); }