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

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

コード全体のリファクタリングを実施

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