#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_r11(&VarRelativeVar)){ //mov qword ptr[rsp+offset],r11 ※スタックフレームを利用 pobj_sf->push(REG_R11); } /////////////////////////////////// // レジスタへ変数の内容をコピー /////////////////////////////////// int reg; if( varType.IsDouble() ){ reg=REG_XMM0; SetXmmReg_DoubleVariable(&VarRelativeVar,reg); } else if( varType.IsSingle() ){ reg=REG_XMM0; SetXmmReg_SingleVariable(&VarRelativeVar,reg); } else{ reg=REG_RAX; SetReg_WholeVariable(varType,&VarRelativeVar,reg); } if(varType.IsWhole()&&lstrcmp(lpszRight,"1")==0&& (idCalc==CALC_ADDITION||idCalc==CALC_SUBTRACTION)){ if(idCalc==CALC_ADDITION){ //インクリメント compiler.codeGenerator.op_inc(REG_RAX); } else if(idCalc==CALC_SUBTRACTION){ //デクリメント compiler.codeGenerator.op_dec(REG_RAX); } } else{ //結果を格納しているレジスタをブロッキング pobj_BlockReg->lock(reg); //右辺を計算 Type calcType; if(reg==REG_RAX) reg=REG_RCX; else reg=REG_RAX; NumOpe(®,lpszRight,varType,calcType); //レジスタのブロッキングを解除 pobj_BlockReg->clear(); if(varType.IsPointer()&&calcType.IsWhole()&&(!calcType.IsPointer())){ //左辺がポインタ型、右辺が整数型の場合は、エラーをださないようにする calcType = varType; } ///////////////////////////////// // 右辺、左辺の型チェックを行う ///////////////////////////////// CheckDifferentType(varType,calcType,0,0); //レジスタ管理オブジェクトを生成 pobj_reg=new CRegister(REG_RAX); //左辺用レジスタ if(varType.IsReal()) pobj_reg->LockXmmReg(); else pobj_reg->LockReg(); //右辺値レジスタ if(varType.IsDouble()) { ChangeTypeToXmm_Double( calcType.GetBasicType(), pobj_reg->LockXmmReg(), pobj_reg->GetNextReg() ); } else if(varType.IsSingle()) { ChangeTypeToXmm_Single( calcType.GetBasicType(), pobj_reg->LockXmmReg(), pobj_reg->GetNextReg() ); } else { ChangeTypeToWhole( calcType, varType, pobj_reg->LockReg(), pobj_reg->GetNextXmmReg() ); } 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: case CALC_OR: case CALC_AND: CalcTwoTerm_Logical(idCalc,type_stack,index_stack,&sp); break; case CALC_SHL: case CALC_SHR: Calc_Shift(idCalc,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,index_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; } //レジスタ管理オブジェクトを解放 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.GetBasicType(),&VarRelativeVar); }