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

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