source: dev/trunk/abdev/BasicCompiler32/Compile_Set_Var.cpp@ 225

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

CodeGeneratorクラスのベースを実装

File size: 9.9 KB
Line 
1#include "stdafx.h"
2
3#include <jenga/include/smoothie/Smoothie.h>
4
5#include <Compiler.h>
6
7#include "../BasicCompiler_Common/common.h"
8#include "Opcode.h"
9
10BOOL IsUse_ecx(RELATIVE_VAR *pRelativeVar){
11 if(pRelativeVar->bOffsetOffset||pRelativeVar->dwKind==VAR_DIRECTMEM) return 1;
12 return 0;
13}
14
15void SetStructVariable( const Type &varType, const Type &calcType, BOOL bUseHeap){
16 if( calcType.IsStruct() ){
17 if( varType.GetClass().IsEquals( &calcType.GetClass() ) ){ //等しい
18
19 //双方のオブジェクト型が一致、または派生・継承関係にあるとき
20 //※コピーを行う
21
22 int object_size = varType.GetClass().GetSize();
23
24 //mov ecx,object_size
25 compiler.codeGenerator.op_mov_RV(REG_ECX,object_size);
26
27 //pop esi
28 compiler.codeGenerator.op_pop(REG_ESI);
29
30 //pop edi
31 compiler.codeGenerator.op_pop(REG_EDI);
32
33 if(bUseHeap){
34 //mov eax,esi
35 compiler.codeGenerator.op_mov_RR(REG_EAX,REG_ESI);
36 }
37
38 //rep movs byte ptr[edi],byte ptr[esi]
39 compiler.codeGenerator.op_rep_movs(sizeof(BYTE));
40
41 if(bUseHeap){
42 //push eax
43 compiler.codeGenerator.op_push(REG_EAX);
44
45 //call free
46 extern const UserProc *pSub_free;
47 compiler.codeGenerator.op_call(pSub_free);
48 }
49
50 return;
51 }
52 }
53
54 SetError(1,NULL,cp);
55}
56
57
58void SetRealVariable(int VarType,int CalcType,RELATIVE_VAR *pRelativeVar){
59 if( !IsRealNumberType( CalcType ) ){
60 // 実数へ変換
61 // 64bit edx:eax -> st(0)
62 // 32bit eax -> st(0)
63
64 if( Is64Type( CalcType ) ){
65 //64ビット整数型
66
67 //push edx
68 compiler.codeGenerator.op_push( REG_EDX );
69
70 //push eax
71 compiler.codeGenerator.op_push( REG_EAX );
72
73 //fild qword ptr[esp]
74 compiler.codeGenerator.op_fld_ptr_esp(DEF_INT64);
75
76 //pop
77 compiler.codeGenerator.op_pop( REG_NON );
78
79 //pop
80 compiler.codeGenerator.op_pop( REG_NON );
81 }
82 else{
83 //push eax
84 compiler.codeGenerator.op_push( REG_EAX );
85
86 //fild qword ptr[esp]
87 compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);
88
89 //pop
90 compiler.codeGenerator.op_pop( REG_NON );
91 }
92 }
93
94 if(pRelativeVar->dwKind==VAR_GLOBAL){
95 if(pRelativeVar->bOffsetOffset){
96 //fstp ptr[ecx+offset]
97 compiler.codeGenerator.op_fstp_base_offset(VarType,REG_ECX,(int)pRelativeVar->offset);
98 obp-=sizeof(long);
99 pobj_GlobalVarSchedule->add();
100 obp+=sizeof(long);
101 }
102 else{
103 //mov ecx,offset
104 compiler.codeGenerator.op_mov_RV(REG_ECX,(int)pRelativeVar->offset);
105 obp-=sizeof(long);
106 pobj_GlobalVarSchedule->add();
107 obp+=sizeof(long);
108
109 //fstp ptr[ecx]
110 compiler.codeGenerator.op_fstp_basereg(VarType,REG_ECX);
111 }
112 }
113 else if(pRelativeVar->dwKind==VAR_REFGLOBAL){
114 if(pRelativeVar->bOffsetOffset){
115 //add ecx,qword ptr[offset]
116 compiler.codeGenerator.op_add_RM(sizeof(long),REG_ECX,REG_NON,(int)pRelativeVar->offset,MOD_DISP32);
117 }
118 else{
119 //mov ecx,qword ptr[offset]
120 compiler.codeGenerator.op_mov_RM(sizeof(long),REG_ECX,REG_NON,(int)pRelativeVar->offset,MOD_DISP32);
121 }
122 obp-=sizeof(long);
123 pobj_GlobalVarSchedule->add();
124 obp+=sizeof(long);
125
126 goto directmem;
127 }
128 else if(pRelativeVar->dwKind==VAR_LOCAL){
129 if(pRelativeVar->bOffsetOffset){
130 //fstp ptr[ebp+ecx+offset]
131 compiler.codeGenerator.op_fstp_base_offset_ex(VarType,REG_EBP,REG_ECX,(int)pRelativeVar->offset,USE_OFFSET);
132 }
133 else{
134 //fstp ptr[ebp+offset]
135 compiler.codeGenerator.op_fstp_base_offset(VarType,REG_EBP,(int)pRelativeVar->offset);
136 }
137 obp-=sizeof(long);
138 AddLocalVarAddrSchedule();
139 obp+=sizeof(long);
140 }
141 else if(pRelativeVar->dwKind==VAR_REFLOCAL){
142 if(pRelativeVar->bOffsetOffset){
143 //add ecx,qword ptr[ebp+offset]
144 compiler.codeGenerator.op_add_RM(sizeof(long),REG_ECX,REG_EBP,(int)pRelativeVar->offset,MOD_BASE_DISP32);
145 }
146 else{
147 //mov ecx,qword ptr[ebp+offset]
148 compiler.codeGenerator.op_mov_RM(sizeof(long),REG_ECX,REG_EBP,(int)pRelativeVar->offset,MOD_BASE_DISP32);
149 }
150 obp-=sizeof(long);
151 AddLocalVarAddrSchedule();
152 obp+=sizeof(long);
153
154 goto directmem;
155 }
156 else if(pRelativeVar->dwKind==VAR_DIRECTMEM){
157directmem:
158 //fstp ptr[ecx]
159 compiler.codeGenerator.op_fstp_basereg(VarType,REG_ECX);
160 }
161}
162
163void SetBooleanVariable(int type,RELATIVE_VAR *pRelative){
164 if(type==DEF_DOUBLE){
165 // TODO: 実装
166 SetError();
167 }
168 else if(type==DEF_SINGLE){
169 // TODO: 実装
170 SetError();
171 }
172 else if(type==DEF_INT64||type==DEF_QWORD){
173 //cmp eax,0
174 compiler.codeGenerator.op_cmp_value(GetTypeSize(type,-1),REG_EAX,0);
175
176 //setne al
177 compiler.codeGenerator.op_setne( REG_EAX );
178
179 //cmp edx,0
180 compiler.codeGenerator.op_cmp_value(GetTypeSize(type,-1),REG_EDX,0);
181
182 //setne cl
183 compiler.codeGenerator.op_setne( REG_ECX );
184
185 //or al,cl
186 compiler.codeGenerator.op_or_RR( sizeof( _int8 ), REG_EAX, REG_ECX );
187 }
188 else{
189 if(!IsWholeNumberType(type)){
190 //不正な型の場合
191 SetError(9,NULL,cp);
192 return;
193 }
194 }
195
196 //cmp eax,0
197 compiler.codeGenerator.op_cmp_value(GetTypeSize(type,-1),REG_EAX,0);
198
199 //setne al
200 compiler.codeGenerator.op_setne( REG_EAX );
201
202 SetWholeVariable( sizeof(char), DEF_BYTE, pRelative );
203}
204
205void ExtendTypeTo32(int type,int reg);
206void ExtendTypeTo64(int type){
207 if(Is64Type(type)) return;
208
209 ExtendTypeTo32(type,REG_EAX);
210
211 if(IsSignedType(type)){
212 //cdq
213 compiler.codeGenerator.op_cdq();
214 }
215 else{
216 //xor edx,edx
217 compiler.codeGenerator.op_zero_reg(REG_EDX);
218 }
219}
220void ExtendTypeTo32(int type,int reg){
221 if(type==DEF_INTEGER || (Smoothie::IsUnicode()&&type==DEF_CHAR)){
222 //movsx reg32,reg16
223 compiler.codeGenerator.op_movsx_R32R16(reg,reg);
224 }
225 else if(type==DEF_WORD){
226 //and reg,0000FFFFh
227 compiler.codeGenerator.op_and_RV(reg,(int)0x0000FFFF);
228 }
229 else if(type==DEF_SBYTE || (Smoothie::IsUnicode()==false&&type==DEF_CHAR)){
230 //movsx reg32,reg8
231 compiler.codeGenerator.op_movsx_R32R8(reg,reg);
232 }
233 else if(type==DEF_BYTE||type==DEF_BOOLEAN){
234 //and reg,000000FFh
235 compiler.codeGenerator.op_and_RV(reg,(int)0xFF);
236 }
237}
238void ExtendTypeTo16(int type,int reg){
239 if(type==DEF_SBYTE || (Smoothie::IsUnicode()==false&&type==DEF_CHAR)){
240 //movsx reg16,reg8
241 compiler.codeGenerator.op_movsx_R16R8(reg,reg);
242 }
243 else if(type==DEF_BYTE||type==DEF_BOOLEAN){
244 //and reg,000000FFh
245 compiler.codeGenerator.op_and_RV(reg,(int)0xFF);
246 }
247}
248
249void SetWholeVariable(int varSize,int calcType,RELATIVE_VAR *pRelative){
250 if( IsRealNumberType( calcType ) ){
251 // 実数型から整数型へ変換する
252
253 if( varSize == sizeof(_int64) ){
254 // 64bitへ
255 // st(0) -> edx:eax
256 breakpoint;
257
258 //push
259 //push
260 compiler.codeGenerator.op_sub_esp( PTR_SIZE * 2 );
261
262 //fistp qword ptr[esp]
263 compiler.codeGenerator.op_fistp_ptr_esp( sizeof(_int64) );
264
265 //pop eax
266 compiler.codeGenerator.op_pop( REG_EAX );
267
268 //pop edx
269 compiler.codeGenerator.op_pop( REG_EDX );
270 }
271 else{
272 // 32bit
273 // st(0) -> eax
274
275 //push
276 compiler.codeGenerator.op_push( REG_NON );
277
278 //fistp dword ptr[esp]
279 compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );
280
281 //pop eax
282 compiler.codeGenerator.op_pop( REG_EAX );
283 }
284 }
285 else{
286 //その他の整数
287
288 if(varSize==sizeof(_int64)){
289 //eaxの値を64ビット(edx:eax)に拡張する
290 ExtendTypeTo64(calcType);
291 }
292 else if(varSize==sizeof(long)){
293 //レジスタの値を32ビット(eax)に拡張する
294 ExtendTypeTo32(calcType,REG_EAX);
295 }
296 else if(varSize==sizeof(short)){
297 //レジスタの値を16ビット(ax)に拡張する
298 ExtendTypeTo16(calcType,REG_EAX);
299 }
300 //8ビットは拡張なし
301 }
302
303 if(varSize==sizeof(_int64)){
304 //下位32ビット
305 SetWholeVariable(sizeof(long),DEF_LONG,pRelative);
306
307 //上位32ビット
308
309 //直接参照に切り替え
310 SetVarPtrToEax(pRelative);
311 pRelative->dwKind=VAR_DIRECTMEM;
312
313 //mov ecx,eax
314 compiler.codeGenerator.op_mov_RR( REG_ECX, REG_EAX );
315
316 //add ecx,sizeof(long)
317 compiler.codeGenerator.op_add_RV8( REG_ECX, sizeof(long) );
318
319 //mov eax,edx
320 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_EDX );
321
322 SetWholeVariable(sizeof(long),DEF_LONG,pRelative);
323
324 return;
325 }
326
327 if(pRelative->dwKind==VAR_GLOBAL){
328 if(pRelative->bOffsetOffset){
329 //mov ptr[ecx+offset],eax/ax/al
330 compiler.codeGenerator.op_mov_MR(varSize,REG_EAX,REG_ECX,(int)pRelative->offset,MOD_BASE_DISP32);
331 }
332 else{
333 //mov ptr[offset],eax/ax/al
334 compiler.codeGenerator.op_mov_MR(varSize,REG_EAX,0,(int)pRelative->offset,MOD_DISP32);
335 }
336 obp-=sizeof(long);
337 pobj_GlobalVarSchedule->add();
338 obp+=sizeof(long);
339 }
340 else if(pRelative->dwKind==VAR_REFGLOBAL){
341 // 今は使われていない
342 SetError();
343
344 if(pRelative->bOffsetOffset){
345 //add ecx,qword ptr[offset]
346 compiler.codeGenerator.op_add_RM(varSize,REG_ECX,REG_NON,(int)pRelative->offset,MOD_DISP32);
347 }
348 else{
349 //mov ecx,qword ptr[offset]
350 compiler.codeGenerator.op_mov_RM(varSize,REG_ECX,REG_NON,(int)pRelative->offset,MOD_DISP32);
351 }
352 obp-=sizeof(long);
353 pobj_GlobalVarSchedule->add();
354 obp+=sizeof(long);
355
356 goto directmem;
357 }
358 else if(pRelative->dwKind==VAR_LOCAL){
359 if(pRelative->bOffsetOffset){
360 //mov ptr[ebp+ecx+offset],eax/ax/al
361 compiler.codeGenerator.op_mov_MR_ex(varSize,REG_EAX,REG_EBP,REG_ECX,(int)pRelative->offset,USE_OFFSET);
362 }
363 else{
364 //mov ptr[ebp+offset],eax/ax/al
365 compiler.codeGenerator.op_mov_MR(varSize,REG_EAX,REG_EBP,(int)pRelative->offset,MOD_BASE_DISP32);
366 }
367 obp-=sizeof(long);
368 AddLocalVarAddrSchedule();
369 obp+=sizeof(long);
370 }
371 else if(pRelative->dwKind==VAR_REFLOCAL){
372 if(pRelative->bOffsetOffset){
373 //add ecx,ptr[ebp+offset]
374 compiler.codeGenerator.op_add_RM(PTR_SIZE,REG_ECX,REG_EBP,(int)pRelative->offset,MOD_BASE_DISP32);
375 }
376 else{
377 //mov ecx,ptr[ebp+offset]
378 compiler.codeGenerator.op_mov_RM(PTR_SIZE,REG_ECX,REG_EBP,(int)pRelative->offset,MOD_BASE_DISP32);
379 }
380 obp-=sizeof(long);
381 AddLocalVarAddrSchedule();
382 obp+=sizeof(long);
383
384 goto directmem;
385 }
386 else if(pRelative->dwKind==VAR_DIRECTMEM){
387directmem:
388
389 //mov ptr[ecx],eax/ax/al
390 compiler.codeGenerator.op_mov_MR(varSize,REG_EAX,REG_ECX,0,MOD_BASE);
391 }
392}
Note: See TracBrowser for help on using the repository browser.