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

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

ジェネリクスのベースを実装

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