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

Last change on this file since 236 was 236, checked in by dai_9181, 17 years ago
File size: 9.5 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, Schedule::GlobalVar );
98 }
99 else{
100 //mov ecx,offset
101 compiler.codeGenerator.op_mov_RV(REG_ECX,(int)pRelativeVar->offset, Schedule::GlobalVar );
102
103 //fstp ptr[ecx]
104 compiler.codeGenerator.op_fstp_basereg(VarType,REG_ECX);
105 }
106 }
107 else if(pRelativeVar->dwKind==VAR_REFGLOBAL){
108 if(pRelativeVar->bOffsetOffset){
109 //add ecx,qword ptr[offset]
110 compiler.codeGenerator.op_add_RM(sizeof(long),REG_ECX,REG_NON,(int)pRelativeVar->offset,MOD_DISP32, Schedule::GlobalVar );
111 }
112 else{
113 //mov ecx,qword ptr[offset]
114 compiler.codeGenerator.op_mov_RM(sizeof(long),REG_ECX,REG_NON,(int)pRelativeVar->offset,MOD_DISP32, Schedule::GlobalVar );
115 }
116
117 goto directmem;
118 }
119 else if(pRelativeVar->dwKind==VAR_LOCAL){
120 if(pRelativeVar->bOffsetOffset){
121 //fstp ptr[ebp+ecx+offset]
122 compiler.codeGenerator.op_fstp_base_offset_ex(VarType,REG_EBP,REG_ECX,(int)pRelativeVar->offset,USE_OFFSET, Schedule::LocalVar );
123 }
124 else{
125 //fstp ptr[ebp+offset]
126 compiler.codeGenerator.op_fstp_base_offset(VarType,REG_EBP,(int)pRelativeVar->offset, Schedule::LocalVar );
127 }
128 }
129 else if(pRelativeVar->dwKind==VAR_REFLOCAL){
130 if(pRelativeVar->bOffsetOffset){
131 //add ecx,qword ptr[ebp+offset]
132 compiler.codeGenerator.op_add_RM(sizeof(long),REG_ECX,REG_EBP,(int)pRelativeVar->offset,MOD_BASE_DISP32, Schedule::LocalVar );
133 }
134 else{
135 //mov ecx,qword ptr[ebp+offset]
136 compiler.codeGenerator.op_mov_RM(sizeof(long),REG_ECX,REG_EBP,(int)pRelativeVar->offset,MOD_BASE_DISP32, Schedule::LocalVar );
137 }
138
139 goto directmem;
140 }
141 else if(pRelativeVar->dwKind==VAR_DIRECTMEM){
142directmem:
143 //fstp ptr[ecx]
144 compiler.codeGenerator.op_fstp_basereg(VarType,REG_ECX);
145 }
146}
147
148void SetBooleanVariable(int type,RELATIVE_VAR *pRelative){
149 if(type==DEF_DOUBLE){
150 // TODO: 実装
151 SetError();
152 }
153 else if(type==DEF_SINGLE){
154 // TODO: 実装
155 SetError();
156 }
157 else if(type==DEF_INT64||type==DEF_QWORD){
158 //cmp eax,0
159 compiler.codeGenerator.op_cmp_value(sizeof(long),REG_EAX,0);
160
161 //setne al
162 compiler.codeGenerator.op_setne( REG_EAX );
163
164 //cmp edx,0
165 compiler.codeGenerator.op_cmp_value(sizeof(long),REG_EDX,0);
166
167 //setne cl
168 compiler.codeGenerator.op_setne( REG_ECX );
169
170 //or al,cl
171 compiler.codeGenerator.op_or_RR( sizeof( _int8 ), REG_EAX, REG_ECX );
172 }
173 else{
174 if(!IsWholeNumberType(type)){
175 //不正な型の場合
176 SetError(9,NULL,cp);
177 return;
178 }
179 }
180
181 //cmp eax,0
182 compiler.codeGenerator.op_cmp_value(GetTypeSize(type,-1),REG_EAX,0);
183
184 //setne al
185 compiler.codeGenerator.op_setne( REG_EAX );
186
187 SetWholeVariable( sizeof(char), DEF_BYTE, pRelative );
188}
189
190void ExtendTypeTo32(int type,int reg);
191void ExtendTypeTo64(int type){
192 if(Is64Type(type)) return;
193
194 ExtendTypeTo32(type,REG_EAX);
195
196 if(IsSignedType(type)){
197 //cdq
198 compiler.codeGenerator.op_cdq();
199 }
200 else{
201 //xor edx,edx
202 compiler.codeGenerator.op_zero_reg(REG_EDX);
203 }
204}
205void ExtendTypeTo32(int type,int reg){
206 if(type==DEF_INTEGER || (Smoothie::IsUnicode()&&type==DEF_CHAR)){
207 //movsx reg32,reg16
208 compiler.codeGenerator.op_movsx_R32R16(reg,reg);
209 }
210 else if(type==DEF_WORD){
211 //and reg,0000FFFFh
212 compiler.codeGenerator.op_and_RV(reg,(int)0x0000FFFF);
213 }
214 else if(type==DEF_SBYTE || (Smoothie::IsUnicode()==false&&type==DEF_CHAR)){
215 //movsx reg32,reg8
216 compiler.codeGenerator.op_movsx_R32R8(reg,reg);
217 }
218 else if(type==DEF_BYTE||type==DEF_BOOLEAN){
219 //and reg,000000FFh
220 compiler.codeGenerator.op_and_RV(reg,(int)0xFF);
221 }
222}
223void ExtendTypeTo16(int type,int reg){
224 if(type==DEF_SBYTE || (Smoothie::IsUnicode()==false&&type==DEF_CHAR)){
225 //movsx reg16,reg8
226 compiler.codeGenerator.op_movsx_R16R8(reg,reg);
227 }
228 else if(type==DEF_BYTE||type==DEF_BOOLEAN){
229 //and reg,000000FFh
230 compiler.codeGenerator.op_and_RV(reg,(int)0xFF);
231 }
232}
233
234void SetWholeVariable(int varSize,int calcType,RELATIVE_VAR *pRelative){
235 if( IsRealNumberType( calcType ) ){
236 // 実数型から整数型へ変換する
237
238 if( varSize == sizeof(_int64) ){
239 // 64bitへ
240 // st(0) -> edx:eax
241 breakpoint;
242
243 //push
244 //push
245 compiler.codeGenerator.op_sub_esp( PTR_SIZE * 2 );
246
247 //fistp qword ptr[esp]
248 compiler.codeGenerator.op_fistp_ptr_esp( sizeof(_int64) );
249
250 //pop eax
251 compiler.codeGenerator.op_pop( REG_EAX );
252
253 //pop edx
254 compiler.codeGenerator.op_pop( REG_EDX );
255 }
256 else{
257 // 32bit
258 // st(0) -> eax
259
260 //push
261 compiler.codeGenerator.op_push( REG_NON );
262
263 //fistp dword ptr[esp]
264 compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );
265
266 //pop eax
267 compiler.codeGenerator.op_pop( REG_EAX );
268 }
269 }
270 else{
271 //その他の整数
272
273 if(varSize==sizeof(_int64)){
274 //eaxの値を64ビット(edx:eax)に拡張する
275 ExtendTypeTo64(calcType);
276 }
277 else if(varSize==sizeof(long)){
278 //レジスタの値を32ビット(eax)に拡張する
279 ExtendTypeTo32(calcType,REG_EAX);
280 }
281 else if(varSize==sizeof(short)){
282 //レジスタの値を16ビット(ax)に拡張する
283 ExtendTypeTo16(calcType,REG_EAX);
284 }
285 //8ビットは拡張なし
286 }
287
288 if(varSize==sizeof(_int64)){
289 //下位32ビット
290 SetWholeVariable(sizeof(long),DEF_LONG,pRelative);
291
292 //上位32ビット
293
294 //直接参照に切り替え
295 SetVarPtrToEax(pRelative);
296 pRelative->dwKind=VAR_DIRECTMEM;
297
298 //mov ecx,eax
299 compiler.codeGenerator.op_mov_RR( REG_ECX, REG_EAX );
300
301 //add ecx,sizeof(long)
302 compiler.codeGenerator.op_add_RV8( REG_ECX, sizeof(long) );
303
304 //mov eax,edx
305 compiler.codeGenerator.op_mov_RR( REG_EAX, REG_EDX );
306
307 SetWholeVariable(sizeof(long),DEF_LONG,pRelative);
308
309 return;
310 }
311
312 if(pRelative->dwKind==VAR_GLOBAL){
313 if(pRelative->bOffsetOffset){
314 //mov ptr[ecx+offset],eax/ax/al
315 compiler.codeGenerator.op_mov_MR(varSize,REG_EAX,REG_ECX,(int)pRelative->offset,MOD_BASE_DISP32, Schedule::GlobalVar );
316 }
317 else{
318 //mov ptr[offset],eax/ax/al
319 compiler.codeGenerator.op_mov_MR(varSize,REG_EAX,0,(int)pRelative->offset,MOD_DISP32, Schedule::GlobalVar );
320 }
321 }
322 else if(pRelative->dwKind==VAR_REFGLOBAL){
323 // 今は使われていない
324 SetError();
325
326 if(pRelative->bOffsetOffset){
327 //add ecx,qword ptr[offset]
328 compiler.codeGenerator.op_add_RM(varSize,REG_ECX,REG_NON,(int)pRelative->offset,MOD_DISP32, Schedule::GlobalVar );
329 }
330 else{
331 //mov ecx,qword ptr[offset]
332 compiler.codeGenerator.op_mov_RM(varSize,REG_ECX,REG_NON,(int)pRelative->offset,MOD_DISP32, Schedule::GlobalVar );
333 }
334
335 goto directmem;
336 }
337 else if(pRelative->dwKind==VAR_LOCAL){
338 if(pRelative->bOffsetOffset){
339 //mov ptr[ebp+ecx+offset],eax/ax/al
340 compiler.codeGenerator.op_mov_MR_ex(varSize,REG_EAX,REG_EBP,REG_ECX,(int)pRelative->offset,USE_OFFSET, Schedule::LocalVar );
341 }
342 else{
343 //mov ptr[ebp+offset],eax/ax/al
344 compiler.codeGenerator.op_mov_MR(varSize,REG_EAX,REG_EBP,(int)pRelative->offset,MOD_BASE_DISP32, Schedule::LocalVar );
345 }
346 }
347 else if(pRelative->dwKind==VAR_REFLOCAL){
348 if(pRelative->bOffsetOffset){
349 //add ecx,ptr[ebp+offset]
350 compiler.codeGenerator.op_add_RM(PTR_SIZE,REG_ECX,REG_EBP,(int)pRelative->offset,MOD_BASE_DISP32, Schedule::LocalVar );
351 }
352 else{
353 //mov ecx,ptr[ebp+offset]
354 compiler.codeGenerator.op_mov_RM(PTR_SIZE,REG_ECX,REG_EBP,(int)pRelative->offset,MOD_BASE_DISP32, Schedule::LocalVar );
355 }
356
357 goto directmem;
358 }
359 else if(pRelative->dwKind==VAR_DIRECTMEM){
360directmem:
361
362 //mov ptr[ecx],eax/ax/al
363 compiler.codeGenerator.op_mov_MR(varSize,REG_EAX,REG_ECX,0,MOD_BASE);
364 }
365}
Note: See TracBrowser for help on using the repository browser.