source: dev/BasicCompiler32/increment.cpp@ 47

Last change on this file since 47 was 36, checked in by dai_9181, 18 years ago

Boolean型に対応。

File size: 9.3 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "Opcode.h"
3
4
5void SetRealVariable(int type,RELATIVE_VAR *pRelativeVar){
6 if(pRelativeVar->dwKind==VAR_GLOBAL){
7 if(pRelativeVar->bOffsetOffset){
8 //fstp ptr[ecx+offset]
9 op_fstp_base_offset(type,REG_ECX,(int)pRelativeVar->offset);
10 obp-=sizeof(long);
11 pobj_GlobalVarSchedule->add();
12 obp+=sizeof(long);
13 }
14 else{
15 //mov ecx,offset
16 op_mov_RV(REG_ECX,(int)pRelativeVar->offset);
17 obp-=sizeof(long);
18 pobj_GlobalVarSchedule->add();
19 obp+=sizeof(long);
20
21 //fstp ptr[ecx]
22 op_fstp_basereg(type,REG_ECX);
23 }
24 }
25 else if(pRelativeVar->dwKind==VAR_LOCAL){
26 if(pRelativeVar->bOffsetOffset){
27 //fstp ptr[ebp+ecx+offset]
28 op_fstp_base_offset_ex(type,REG_EBP,REG_ECX,(int)pRelativeVar->offset,USE_OFFSET);
29 obp-=sizeof(long);
30 AddLocalVarAddrSchedule();
31 obp+=sizeof(long);
32 }
33 else{
34 //fstp ptr[ebp+offset]
35 op_fstp_base_offset(type,REG_EBP,(int)pRelativeVar->offset);
36 obp-=sizeof(long);
37 AddLocalVarAddrSchedule();
38 obp+=sizeof(long);
39 }
40 }
41 else if(pRelativeVar->dwKind==VAR_REFLOCAL){
42 if(pRelativeVar->bOffsetOffset){
43 //add ecx,qword ptr[ebp+offset]
44 op_add_RM(sizeof(long),REG_ECX,REG_EBP,(int)pRelativeVar->offset,MOD_BASE_DISP32);
45 obp-=sizeof(long);
46 AddLocalVarAddrSchedule();
47 obp+=sizeof(long);
48 }
49 else{
50 //mov ecx,qword ptr[ebp+offset]
51 op_mov_RM(sizeof(long),REG_ECX,REG_EBP,(int)pRelativeVar->offset,MOD_BASE_DISP32);
52 obp-=sizeof(long);
53 AddLocalVarAddrSchedule();
54 obp+=sizeof(long);
55 }
56
57 goto directmem;
58 }
59 else if(pRelativeVar->dwKind==VAR_DIRECTMEM){
60directmem:
61 //fstp ptr[ecx]
62 op_fstp_basereg(type,REG_ECX);
63 }
64}
65
66void ExtendTypeTo32(int type,int reg);
67void ExtendTypeTo64(int type){
68 if(Is64Type(type)) return;
69
70 ExtendTypeTo32(type,REG_EAX);
71
72 if(IsSignedType(type)){
73 //cdq
74 op_cdq();
75 }
76 else{
77 //xor edx,edx
78 op_zero_reg(REG_EDX);
79 }
80}
81void ExtendTypeTo32(int type,int reg){
82 if(type==DEF_INTEGER){
83 //movsx reg32,reg16
84 op_movsx_R32R16(reg,reg);
85 }
86 else if(type==DEF_WORD){
87 //and reg,0000FFFFh
88 op_and_RV(reg,(int)0x0000FFFF);
89 }
90 else if(type==DEF_CHAR){
91 //movsx reg32,reg8
92 op_movsx_R32R8(reg,reg);
93 }
94 else if(type==DEF_BYTE||type==DEF_BOOLEAN){
95 //and reg,000000FFh
96 op_and_RV(reg,(int)0xFF);
97 }
98}
99void ExtendTypeTo16(int type,int reg){
100 if(type==DEF_CHAR){
101 //movsx reg16,reg8
102 op_movsx_R16R8(reg,reg);
103 }
104 else if(type==DEF_BYTE||type==DEF_BOOLEAN){
105 //and reg,000000FFh
106 op_and_RV(reg,(int)0xFF);
107 }
108}
109
110void SetWholeVariable(int var_size,int type,RELATIVE_VAR *pRelative,int reg){
111 if(type==DEF_DOUBLE){
112 //Double型
113
114 }
115 else if(type==DEF_SINGLE){
116 //Single型
117
118 }
119 else{
120 //その他の整数
121
122 if(var_size==sizeof(_int64)){
123 //eaxの値を64ビット(edx:eax)に拡張する
124 ExtendTypeTo64(type);
125 }
126 else if(var_size==sizeof(long)){
127 //レジスタの値を32ビット(eax)に拡張する
128 ExtendTypeTo32(type,reg);
129 }
130 else if(var_size==sizeof(short)){
131 //レジスタの値を16ビット(ax)に拡張する
132 ExtendTypeTo16(type,reg);
133 }
134 //8ビットは拡張なし
135 }
136
137 if(var_size==sizeof(_int64)){
138 //下位32ビット
139 SetWholeVariable(sizeof(long),DEF_LONG,pRelative,REG_EAX);
140
141 //上位32ビット
142 pRelative->offset+=sizeof(long);
143 SetWholeVariable(sizeof(long),DEF_LONG,pRelative,REG_EDX);
144 pRelative->offset-=sizeof(long);
145
146 return;
147 }
148
149 if(pRelative->dwKind==VAR_GLOBAL){
150 if(pRelative->bOffsetOffset){
151 //mov ptr[ecx+offset],eax/ax/al
152 op_mov_MR(var_size,reg,REG_ECX,(int)pRelative->offset,MOD_BASE_DISP32);
153 obp-=sizeof(long);
154 pobj_GlobalVarSchedule->add();
155 obp+=sizeof(long);
156 }
157 else{
158 //mov ptr[offset],eax/ax/al
159 op_mov_MR(var_size,reg,0,(int)pRelative->offset,MOD_DISP32);
160 obp-=sizeof(long);
161 pobj_GlobalVarSchedule->add();
162 obp+=sizeof(long);
163 }
164 }
165 else if(pRelative->dwKind==VAR_LOCAL){
166 if(pRelative->bOffsetOffset){
167 //mov ptr[ebp+ecx+offset],eax/ax/al
168 op_mov_MR_ex(var_size,reg,REG_EBP,REG_ECX,(int)pRelative->offset,USE_OFFSET);
169 obp-=sizeof(long);
170 AddLocalVarAddrSchedule();
171 obp+=sizeof(long);
172 }
173 else{
174 //mov ptr[ebp+offset],eax/ax/al
175 op_mov_MR(var_size,reg,REG_EBP,(int)pRelative->offset,MOD_BASE_DISP32);
176 obp-=sizeof(long);
177 AddLocalVarAddrSchedule();
178 obp+=sizeof(long);
179 }
180 }
181 else if(pRelative->dwKind==VAR_REFLOCAL){
182 if(pRelative->bOffsetOffset){
183 //add ecx,qword ptr[ebp+offset]
184 op_add_RM(var_size,REG_ECX,REG_EBP,(int)pRelative->offset,MOD_BASE_DISP32);
185 obp-=sizeof(long);
186 AddLocalVarAddrSchedule();
187 obp+=sizeof(long);
188 }
189 else{
190 //mov ecx,qword ptr[ebp+offset]
191 op_mov_RM(var_size,REG_ECX,REG_EBP,(int)pRelative->offset,MOD_BASE_DISP32);
192 obp-=sizeof(long);
193 AddLocalVarAddrSchedule();
194 obp+=sizeof(long);
195 }
196
197 goto directmem;
198 }
199 else if(pRelative->dwKind==VAR_DIRECTMEM){
200directmem:
201
202 //mov ptr[ecx],eax/ax/al
203 op_mov_MR(var_size,reg,REG_ECX,0,MOD_BASE);
204 }
205}
206
207void SetVariableFromReg(int VarType,int CalcType,RELATIVE_VAR *pRelativeVar){
208 /////////////////////////////////////////////////
209 // raxの内容を変数にコピーするコードを抽出
210 /////////////////////////////////////////////////
211
212 if(VarType==DEF_DOUBLE){
213 //Double型変数へスタックの内容を格納する
214 SetRealVariable(VarType,pRelativeVar);
215 }
216 else if(VarType==DEF_SINGLE){
217 //Single型変数へスタックの内容を格納する
218 SetRealVariable(VarType,pRelativeVar);
219 }
220 else{
221 //整数型
222 SetWholeVariable(GetTypeSize(VarType,-1),CalcType,pRelativeVar,REG_EAX);
223 }
224}
225
226
227void IncDec(int idCalc, char *lpszLeft, char *lpszRight){
228 int VarType;
229 LONG_PTR lpVarIndex;
230 RELATIVE_VAR VarRelativeVar;
231
232
233 ///////////////////////////
234 // 変数アドレスを取得
235 ///////////////////////////
236
237 if(!GetVarOffsetReadWrite(
238 lpszLeft,
239 &VarType,
240 &VarRelativeVar,
241 &lpVarIndex)) return;
242
243 if(IsUse_ecx(&VarRelativeVar)){
244 //push ecx
245 op_push(REG_ECX);
246 }
247
248
249 ///////////////////////////////////
250 // レジスタへ変数の内容をコピー
251 ///////////////////////////////////
252
253 if(IsRealNumberType(VarType)){
254 //実数
255 SetReg_RealVariable(VarType,&VarRelativeVar);
256 }
257 else{
258 //整数
259 SetReg_WholeVariable(VarType,&VarRelativeVar,REG_EAX);
260 }
261
262
263 if(IsWholeNumberType(VarType)&&lstrcmp(lpszRight,"1")==0&&
264 (idCalc==CALC_ADDITION||idCalc==CALC_SUBTRACTION)){
265 ////////////////////////////////////////////
266 // 整数型のインクリメント・デクリメント
267 ////////////////////////////////////////////
268
269 if(Is64Type(VarType)){
270 if(idCalc==CALC_ADDITION){
271 //64ビット インクリメント
272
273 //add eax,1
274 op_add_RV8(REG_EAX,1);
275
276 //adc edx,0
277 op_adc_RV8(REG_EDX,0);
278 }
279 else if(idCalc==CALC_SUBTRACTION){
280 //64ビット デクリメント
281
282 //sub eax,1
283 op_sub_RV8(REG_EAX,1);
284
285 //sbb edx,0
286 op_sbb_RV8(REG_EDX,0);
287 }
288 }
289 else{
290 if(idCalc==CALC_ADDITION){
291 //インクリメント
292 op_inc(REG_EAX);
293 }
294 else if(idCalc==CALC_SUBTRACTION){
295 //デクリメント
296 op_dec(REG_EAX);
297 }
298 }
299 }
300 else{
301 //変数オフセットを一時退避
302 //push ecx
303 op_push(REG_ECX);
304
305
306 if(VarType==DEF_DOUBLE){
307 //sub esp,8
308 op_sub_esp(8);
309
310 //fstp qword ptr[esp]
311 op_fstp_basereg(VarType,REG_ESP);
312 }
313 else if(VarType==DEF_SINGLE){
314 //sub esp,4
315 op_sub_esp(4);
316
317 //fstp dword ptr[esp]
318 op_fstp_basereg(VarType,REG_ESP);
319 }
320 else if(Is64Type(VarType)){
321 //push edx
322 op_push(REG_EDX);
323
324 //push eax
325 op_push(REG_EAX);
326 }
327 else{
328 //push eax
329 op_push(REG_EAX);
330 }
331
332 int CalcType;
333 CalcType=NumOpe(lpszRight,VarType,lpVarIndex,0);
334
335 if(VarType==DEF_DOUBLE) ChangeTypeToDouble(CalcType);
336 else if(VarType==DEF_SINGLE) ChangeTypeToSingle(CalcType);
337 else ChangeTypeToWhole(CalcType,VarType);
338
339 int type[255],sp;
340 LONG_PTR index_stack[255];
341 type[0]=VarType;
342 type[1]=VarType;
343 index_stack[0]=lpVarIndex;
344 index_stack[1]=lpVarIndex;
345 sp=2;
346
347 switch(idCalc){
348 case CALC_XOR:
349 Calc_Xor(type,index_stack,&sp);
350 break;
351 case CALC_OR:
352 Calc_Or(type,index_stack,&sp);
353 break;
354 case CALC_AND:
355 Calc_And(type,index_stack,&sp);
356 break;
357 case CALC_SHL:
358 Calc_SHL(type,&sp);
359 break;
360 case CALC_SHR:
361 Calc_SHR(type,&sp);
362 break;
363 case CALC_ADDITION:
364 case CALC_SUBTRACTION:
365 case CALC_PRODUCT:
366 CalcTwoTerm_Arithmetic(idCalc,type,index_stack,&sp);
367 break;
368 case CALC_MOD:
369 Calc_Mod(type,&sp);
370 break;
371 case CALC_QUOTIENT:
372 Calc_Divide(type,&sp,VarType);
373 break;
374 case CALC_INTQUOTIENT:
375 Calc_IntDivide(type,index_stack,&sp);
376 break;
377 case CALC_POWER:
378 Calc_Power(type,&sp);
379 break;
380 }
381
382
383 if(VarType==DEF_DOUBLE){
384 //fld qword ptr[esp]
385 op_fld_basereg(VarType,REG_ESP);
386
387 //add esp,8
388 op_add_esp(8);
389 }
390 else if(VarType==DEF_SINGLE){
391 //fld dword ptr[esp]
392 op_fld_basereg(VarType,REG_ESP);
393
394 //add esp,4
395 op_add_esp(4);
396 }
397 else if(Is64Type(VarType)){
398 //pop eax
399 op_pop(REG_EAX);
400
401 //pop edx
402 op_pop(REG_EDX);
403 }
404 else{
405 //pop eax
406 op_pop(REG_EAX);
407 }
408
409
410 //変数オフセットを復元
411 //pop ecx
412 op_pop(REG_ECX);
413 }
414
415
416 /////////////////////////////////////////////////
417 // レジスタの内容を変数にコピー
418 /////////////////////////////////////////////////
419
420 if(IsUse_ecx(&VarRelativeVar)){
421 //pop ecx
422 op_pop(REG_ECX);
423 }
424
425 SetVariableFromReg(VarType,VarType,&VarRelativeVar);
426}
Note: See TracBrowser for help on using the repository browser.