source: dev/trunk/ab5.0/abdev/compiler_x86/increment.cpp@ 603

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

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

File size: 5.1 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 RELATIVE_VAR VarRelativeVar;
31 if(!GetVarOffsetReadWrite(
32 lpszLeft,
33 &VarRelativeVar,
34 varType)) return;
35
36 if(IsUse_ecx(&VarRelativeVar)){
37 //push ecx
38 compiler.codeGenerator.op_push(REG_ECX);
39 }
40
41
42 ///////////////////////////////////
43 // レジスタへ変数の内容をコピー
44 ///////////////////////////////////
45
46 if( varType.IsReal() ){
47 //実数
48 SetReg_RealVariable(varType.GetBasicType(),&VarRelativeVar);
49 }
50 else{
51 //整数
52 SetReg_WholeVariable(varType,&VarRelativeVar,REG_EAX);
53 }
54
55
56 if(varType.IsWhole()&&lstrcmp(lpszRight,"1")==0&&
57 (idCalc==CALC_ADDITION||idCalc==CALC_SUBTRACTION)){
58 ////////////////////////////////////////////
59 // 整数型のインクリメント・デクリメント
60 ////////////////////////////////////////////
61
62 if( varType.Is64() ){
63 if(idCalc==CALC_ADDITION){
64 //64ビット インクリメント
65
66 //add eax,1
67 compiler.codeGenerator.op_add_RV8(REG_EAX,1);
68
69 //adc edx,0
70 compiler.codeGenerator.op_adc_RV8(REG_EDX,0);
71 }
72 else if(idCalc==CALC_SUBTRACTION){
73 //64ビット デクリメント
74
75 //sub eax,1
76 compiler.codeGenerator.op_sub_RV8(REG_EAX,1);
77
78 //sbb edx,0
79 compiler.codeGenerator.op_sbb_RV8(REG_EDX,0);
80 }
81 }
82 else{
83 if(idCalc==CALC_ADDITION){
84 //インクリメント
85 compiler.codeGenerator.op_inc(REG_EAX);
86 }
87 else if(idCalc==CALC_SUBTRACTION){
88 //デクリメント
89 compiler.codeGenerator.op_dec(REG_EAX);
90 }
91 }
92 }
93 else{
94 //変数オフセットを一時退避
95 //push ecx
96 compiler.codeGenerator.op_push(REG_ECX);
97
98 if( varType.IsDouble() ){
99 //sub esp,8
100 compiler.codeGenerator.op_sub_esp(8);
101
102 //fstp qword ptr[esp]
103 compiler.codeGenerator.op_fstp_basereg(varType.GetBasicType(),REG_ESP);
104 }
105 else if( varType.IsSingle() ){
106 //sub esp,4
107 compiler.codeGenerator.op_sub_esp(4);
108
109 //fstp dword ptr[esp]
110 compiler.codeGenerator.op_fstp_basereg(varType.GetBasicType(),REG_ESP);
111 }
112 else if( varType.Is64() ){
113 //push edx
114 compiler.codeGenerator.op_push(REG_EDX);
115
116 //push eax
117 compiler.codeGenerator.op_push(REG_EAX);
118 }
119 else{
120 //push eax
121 compiler.codeGenerator.op_push(REG_EAX);
122 }
123
124 Type calcType;
125 if( !NumOpe(lpszRight,varType,calcType) ){
126 return;
127 }
128
129 if( varType.IsDouble() ) ChangeTypeToDouble(calcType.GetBasicType());
130 else if( varType.IsSingle() ) ChangeTypeToSingle(calcType.GetBasicType());
131 else ChangeTypeToWhole( calcType, varType );
132
133 int type_stack[255],sp;
134 LONG_PTR index_stack[255];
135 type_stack[0]=varType.GetBasicType();
136 type_stack[1]=varType.GetBasicType();
137 index_stack[0]=varType.GetIndex();
138 index_stack[1]=varType.GetIndex();
139 sp=2;
140
141 switch(idCalc){
142 case CALC_XOR:
143 Calc_Xor(type_stack,index_stack,&sp);
144 break;
145 case CALC_OR:
146 Calc_Or(type_stack,index_stack,&sp);
147 break;
148 case CALC_AND:
149 Calc_And(type_stack,index_stack,&sp);
150 break;
151 case CALC_SHL:
152 Calc_SHL(type_stack,&sp);
153 break;
154 case CALC_SHR:
155 Calc_SHR(type_stack,&sp);
156 break;
157 case CALC_ADDITION:
158 case CALC_SUBTRACTION:
159 case CALC_PRODUCT:
160 CalcTwoTerm_Arithmetic(idCalc,type_stack,index_stack,&sp);
161 break;
162 case CALC_MOD:
163 Calc_Mod(type_stack,&sp);
164 break;
165 case CALC_QUOTIENT:
166 Calc_Divide(type_stack,&sp,varType.GetBasicType());
167 break;
168 case CALC_INTQUOTIENT:
169 Calc_IntDivide(type_stack,index_stack,&sp);
170 break;
171 case CALC_POWER:
172 Calc_Power(type_stack,&sp);
173 break;
174 }
175
176
177 if( varType.IsDouble() ){
178 //fld qword ptr[esp]
179 compiler.codeGenerator.op_fld_basereg(varType.GetBasicType(),REG_ESP);
180
181 //add esp,8
182 compiler.codeGenerator.op_add_esp(8);
183 }
184 else if( varType.IsSingle() ){
185 //fld dword ptr[esp]
186 compiler.codeGenerator.op_fld_basereg(varType.GetBasicType(),REG_ESP);
187
188 //add esp,4
189 compiler.codeGenerator.op_add_esp(4);
190 }
191 else if( varType.Is64() ){
192 //pop eax
193 compiler.codeGenerator.op_pop(REG_EAX);
194
195 //pop edx
196 compiler.codeGenerator.op_pop(REG_EDX);
197 }
198 else{
199 //pop eax
200 compiler.codeGenerator.op_pop(REG_EAX);
201 }
202
203
204 //変数オフセットを復元
205 //pop ecx
206 compiler.codeGenerator.op_pop(REG_ECX);
207 }
208
209
210 /////////////////////////////////////////////////
211 // レジスタの内容を変数にコピー
212 /////////////////////////////////////////////////
213
214 if(IsUse_ecx(&VarRelativeVar)){
215 //pop ecx
216 compiler.codeGenerator.op_pop(REG_ECX);
217 }
218
219 SetVariableFromEax(varType,varType.GetBasicType(),&VarRelativeVar);
220}
Note: See TracBrowser for help on using the repository browser.