source: dev/trunk/abdev/BasicCompiler64/increment.cpp@ 329

Last change on this file since 329 was 329, checked in by dai_9181, 17 years ago

"obj+=value" など、オブジェクトに対する代入演算の構文を "obj=obj+value" と置換して解釈するようにした。

File size: 4.3 KB
RevLine 
[206]1#include "stdafx.h"
2
[226]3#include <Compiler.h>
4
[3]5#include "../BasicCompiler_Common/common.h"
6#include "Opcode.h"
7
[329]8void IncDec(int idCalc, const char *lpszLeft, const char *lpszRight)
9{
10 Type varType;
11 if( GetVarType( lpszLeft, varType, false ) )
12 {
13 if( varType.IsObject() )
14 {
15 // オブジェクトが対象だったとき
16 char temporary[8192];
17 char calcStr[32];
18 GetCalcName( idCalc, calcStr );
19 sprintf( temporary, "%s=%s %s %s", lpszLeft, lpszLeft, calcStr, lpszRight );
20 SetEscapeSequenceFormat( temporary );
21 KillStringSpaces( temporary );
22 OpcodeCalc( temporary );
23 return;
24 }
25 }
[3]26
27 ///////////////////////////
28 // 変数アドレスを取得
29 ///////////////////////////
30
[75]31 RELATIVE_VAR VarRelativeVar;
[11]32 if(!GetVarOffsetReadWrite(
[3]33 lpszLeft,
34 &VarRelativeVar,
[75]35 varType)) return;
[3]36
37 //変数オフセットを一時退避
38 if(IsUse_r11(&VarRelativeVar)){
39 //mov qword ptr[rsp+offset],r11 ※スタックフレームを利用
40 pobj_sf->push(REG_R11);
41 }
42
43
44 ///////////////////////////////////
45 // レジスタへ変数の内容をコピー
46 ///////////////////////////////////
47
48 int reg;
[75]49 if( varType.IsDouble() ){
[3]50 reg=REG_XMM0;
51 SetXmmReg_DoubleVariable(&VarRelativeVar,reg);
52 }
[75]53 else if( varType.IsSingle() ){
[3]54 reg=REG_XMM0;
55 SetXmmReg_SingleVariable(&VarRelativeVar,reg);
56 }
57 else{
58 reg=REG_RAX;
[308]59 SetReg_WholeVariable(varType,&VarRelativeVar,reg);
[3]60 }
61
62
[75]63 if(varType.IsWhole()&&lstrcmp(lpszRight,"1")==0&&
[3]64 (idCalc==CALC_ADDITION||idCalc==CALC_SUBTRACTION)){
65 if(idCalc==CALC_ADDITION){
66 //インクリメント
[226]67 compiler.codeGenerator.op_inc(REG_RAX);
[3]68 }
69 else if(idCalc==CALC_SUBTRACTION){
70 //デクリメント
[226]71 compiler.codeGenerator.op_dec(REG_RAX);
[3]72 }
73 }
74 else{
75 //結果を格納しているレジスタをブロッキング
76 pobj_BlockReg->lock(reg);
77
78 //右辺を計算
[75]79 Type calcType;
[3]80 if(reg==REG_RAX) reg=REG_RCX;
81 else reg=REG_RAX;
[75]82 NumOpe(&reg,lpszRight,varType,calcType);
[3]83
84 //レジスタのブロッキングを解除
85 pobj_BlockReg->clear();
86
87
[75]88 if(varType.IsPointer()&&calcType.IsWhole()&&(!calcType.IsPointer())){
[3]89 //左辺がポインタ型、右辺が整数型の場合は、エラーをださないようにする
[75]90 calcType = varType;
[3]91 }
92
93
94 /////////////////////////////////
95 // 右辺、左辺の型チェックを行う
96 /////////////////////////////////
97
[75]98 CheckDifferentType(varType,calcType,0,0);
[3]99
100
101 //レジスタ管理オブジェクトを生成
102 pobj_reg=new CRegister(REG_RAX);
103
104 //左辺用レジスタ
[75]105 if(varType.IsReal())
[3]106 pobj_reg->LockXmmReg();
107 else
108 pobj_reg->LockReg();
109
110 //右辺値レジスタ
[75]111 if(varType.IsDouble())
[308]112 {
113 ChangeTypeToXmm_Double(
114 calcType.GetBasicType(),
[3]115 pobj_reg->LockXmmReg(),
[308]116 pobj_reg->GetNextReg()
117 );
118 }
[75]119 else if(varType.IsSingle())
[308]120 {
121 ChangeTypeToXmm_Single(
122 calcType.GetBasicType(),
[3]123 pobj_reg->LockXmmReg(),
[308]124 pobj_reg->GetNextReg()
125 );
126 }
[3]127 else
[308]128 {
129 ChangeTypeToWhole(
130 calcType,
131 varType,
[3]132 pobj_reg->LockReg(),
[308]133 pobj_reg->GetNextXmmReg()
134 );
135 }
[3]136
[75]137 int type_stack[255],sp;
[3]138 LONG_PTR index_stack[255];
[75]139 type_stack[0]=varType.GetBasicType();
140 type_stack[1]=varType.GetBasicType();
141 index_stack[0]=varType.GetIndex();
142 index_stack[1]=varType.GetIndex();
[3]143 sp=2;
144
145 switch(idCalc){
146 case CALC_XOR:
147 case CALC_OR:
148 case CALC_AND:
[75]149 CalcTwoTerm_Logical(idCalc,type_stack,index_stack,&sp);
[3]150 break;
151 case CALC_SHL:
152 case CALC_SHR:
[75]153 Calc_Shift(idCalc,type_stack,&sp);
[3]154 break;
155 case CALC_ADDITION:
156 case CALC_SUBTRACTION:
157 case CALC_PRODUCT:
[75]158 CalcTwoTerm_Arithmetic(idCalc,type_stack,index_stack,&sp);
[3]159 break;
160 case CALC_MOD:
[75]161 Calc_Mod(type_stack,index_stack,&sp);
[3]162 break;
163 case CALC_QUOTIENT:
[75]164 Calc_Divide(type_stack,&sp,varType.GetBasicType());
[3]165 break;
166 case CALC_INTQUOTIENT:
[75]167 Calc_IntDivide(type_stack,index_stack,&sp);
[3]168 break;
169 case CALC_POWER:
[75]170 Calc_Power(type_stack,&sp);
[3]171 break;
172 }
173
174 //レジスタ管理オブジェクトを解放
175 delete pobj_reg;
176 pobj_reg=0;
177 }
178
179
180 /////////////////////////////////////////////////
181 // rax(実数はxmm0)の内容を変数にコピー
182 /////////////////////////////////////////////////
183
184 //変数オフセットを復元
185 if(IsUse_r11(&VarRelativeVar)){
186 //mov r11,qword ptr[rsp+offset] ※スタックフレームを利用
187 pobj_sf->pop(REG_R11);
188 }
189
[308]190 SetVariableFromRax(varType,varType.GetBasicType(),&VarRelativeVar);
[3]191}
Note: See TracBrowser for help on using the repository browser.