source: dev/trunk/ab5.0/abdev/compiler_x64/increment.cpp@ 673

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

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

File size: 4.3 KB
Line 
1#include "stdafx.h"
2
3#include <Compiler.h>
4
5#include "../BasicCompiler_Common/common.h"
6#include "Opcode.h"
7
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 }
26
27 ///////////////////////////
28 // 変数アドレスを取得
29 ///////////////////////////
30
31 RELATIVE_VAR VarRelativeVar;
32 if(!GetVarOffsetReadWrite(
33 lpszLeft,
34 &VarRelativeVar,
35 varType)) return;
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;
49 if( varType.IsDouble() ){
50 reg=REG_XMM0;
51 SetXmmReg_DoubleVariable(&VarRelativeVar,reg);
52 }
53 else if( varType.IsSingle() ){
54 reg=REG_XMM0;
55 SetXmmReg_SingleVariable(&VarRelativeVar,reg);
56 }
57 else{
58 reg=REG_RAX;
59 SetReg_WholeVariable(varType,&VarRelativeVar,reg);
60 }
61
62
63 if(varType.IsWhole()&&lstrcmp(lpszRight,"1")==0&&
64 (idCalc==CALC_ADDITION||idCalc==CALC_SUBTRACTION)){
65 if(idCalc==CALC_ADDITION){
66 //インクリメント
67 compiler.codeGenerator.op_inc(REG_RAX);
68 }
69 else if(idCalc==CALC_SUBTRACTION){
70 //デクリメント
71 compiler.codeGenerator.op_dec(REG_RAX);
72 }
73 }
74 else{
75 //結果を格納しているレジスタをブロッキング
76 pobj_BlockReg->lock(reg);
77
78 //右辺を計算
79 Type calcType;
80 if(reg==REG_RAX) reg=REG_RCX;
81 else reg=REG_RAX;
82 NumOpe(&reg,lpszRight,varType,calcType);
83
84 //レジスタのブロッキングを解除
85 pobj_BlockReg->clear();
86
87
88 if(varType.IsPointer()&&calcType.IsWhole()&&(!calcType.IsPointer())){
89 //左辺がポインタ型、右辺が整数型の場合は、エラーをださないようにする
90 calcType = varType;
91 }
92
93
94 /////////////////////////////////
95 // 右辺、左辺の型チェックを行う
96 /////////////////////////////////
97
98 CheckDifferentType(varType,calcType,0,0);
99
100
101 //レジスタ管理オブジェクトを生成
102 pobj_reg=new CRegister(REG_RAX);
103
104 //左辺用レジスタ
105 if(varType.IsReal())
106 pobj_reg->LockXmmReg();
107 else
108 pobj_reg->LockReg();
109
110 //右辺値レジスタ
111 if(varType.IsDouble())
112 {
113 ChangeTypeToXmm_Double(
114 calcType.GetBasicType(),
115 pobj_reg->LockXmmReg(),
116 pobj_reg->GetNextReg()
117 );
118 }
119 else if(varType.IsSingle())
120 {
121 ChangeTypeToXmm_Single(
122 calcType.GetBasicType(),
123 pobj_reg->LockXmmReg(),
124 pobj_reg->GetNextReg()
125 );
126 }
127 else
128 {
129 ChangeTypeToWhole(
130 calcType,
131 varType,
132 pobj_reg->LockReg(),
133 pobj_reg->GetNextXmmReg()
134 );
135 }
136
137 int type_stack[255],sp;
138 LONG_PTR index_stack[255];
139 type_stack[0]=varType.GetBasicType();
140 type_stack[1]=varType.GetBasicType();
141 index_stack[0]=varType.GetIndex();
142 index_stack[1]=varType.GetIndex();
143 sp=2;
144
145 switch(idCalc){
146 case CALC_XOR:
147 case CALC_OR:
148 case CALC_AND:
149 CalcTwoTerm_Logical(idCalc,type_stack,index_stack,&sp);
150 break;
151 case CALC_SHL:
152 case CALC_SHR:
153 Calc_Shift(idCalc,type_stack,&sp);
154 break;
155 case CALC_ADDITION:
156 case CALC_SUBTRACTION:
157 case CALC_PRODUCT:
158 CalcTwoTerm_Arithmetic(idCalc,type_stack,index_stack,&sp);
159 break;
160 case CALC_MOD:
161 Calc_Mod(type_stack,index_stack,&sp);
162 break;
163 case CALC_QUOTIENT:
164 Calc_Divide(type_stack,&sp,varType.GetBasicType());
165 break;
166 case CALC_INTQUOTIENT:
167 Calc_IntDivide(type_stack,index_stack,&sp);
168 break;
169 case CALC_POWER:
170 Calc_Power(type_stack,&sp);
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
190 SetVariableFromRax(varType,varType.GetBasicType(),&VarRelativeVar);
191}
Note: See TracBrowser for help on using the repository browser.