source: dev/trunk/ab5.0/abdev/BasicCompiler32/Compile_Set_Var.cpp@ 461

Last change on this file since 461 was 461, checked in by dai_9181, 16 years ago

smoothieプロジェクトが不要になったため、破棄。

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