source: dev/BasicCompiler32/increment.cpp@ 62

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

グローバル変数に対してByRefを指定できるようにした

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