source: dev/BasicCompiler64/Compile_Set_Var.cpp@ 63

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

CClass::GetSize、CClass::GetMemberOffsetを追加

File size: 11.1 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "Opcode.h"
3
4BOOL IsUse_r11(RELATIVE_VAR *pRelativeVar){
5 if(pRelativeVar->bOffsetOffset||pRelativeVar->dwKind==VAR_DIRECTMEM) return 1;
6 return 0;
7}
8
9void SetObjectVariableFromRax(LONG_PTR lpVarIndex,int CalcType,LONG_PTR lpCalcIndex,RELATIVE_VAR *pRelativeVar,BOOL bUseHeap){
10 int RightTermReg;
11 pobj_reg=new CRegister(REG_RCX);
12
13 //VarRegにオブジェクトポインタをコピー
14 int VarReg;
15 VarReg=pobj_reg->LockReg();
16 SetVarPtrToReg(VarReg,pRelativeVar);
17
18 //右辺
19 if(IsRealNumberType(CalcType)){
20 RightTermReg=pobj_reg->LockXmmReg();
21
22 if(CalcType==DEF_DOUBLE){
23 //movlsd RightTermReg,xmm0
24 op_movsd_RR(RightTermReg,REG_XMM0);
25 }
26 else if(CalcType==DEF_SINGLE){
27 //movlss RightTermReg,xmm0
28 op_movss_RR(RightTermReg,REG_XMM0);
29 }
30 }
31 else{
32 RightTermReg=pobj_reg->LockReg();
33
34 //mov RightTermReg,rax
35 op_mov_RR(RightTermReg,REG_RAX);
36 }
37
38
39 ///////////////////////////////////////////////////////////////////
40 // オペレータ '=' のオーバーロード関数を呼ぶ
41 ///////////////////////////////////////////////////////////////////
42
43 int type[10];
44 LONG_PTR index_stack[10];
45 BOOL array_bUseHeap[10];
46 int sp=2;
47
48 //左辺
49 type[0]=DEF_OBJECT;
50 index_stack[0]=lpVarIndex;
51 array_bUseHeap[0]=0;
52
53 //右辺
54 type[1]=CalcType;
55 index_stack[1]=lpCalcIndex;
56 array_bUseHeap[1]=bUseHeap;
57
58
59 int iRet;
60 iRet=CallOperatorProc(CALC_SUBSITUATION,NULL,type,index_stack,array_bUseHeap,sp);
61
62 //右辺用レジスタを解除
63 if(IsRealNumberType(CalcType)) pobj_reg->UnlockXmmReg();
64 else pobj_reg->UnlockReg();
65
66 //左辺用レジスタを解除
67 pobj_reg->UnlockReg();
68
69 //レジスタ管理オブジェクトを破棄
70 delete pobj_reg;
71 pobj_reg=0;
72
73 if(iRet==-1||iRet==1){
74 //成功したとき、またはエラーが発行されたとき
75 return;
76 }
77
78
79 if( CalcType == DEF_OBJECT ){
80 CClass *pVarClass = (CClass *)lpVarIndex;
81 CClass *pCalcClass = (CClass *)lpCalcIndex;
82
83 if( pVarClass->IsEquals( pCalcClass ) //等しい
84 || pVarClass->IsSubClass( pCalcClass ) ){ //派生・継承関係
85
86 //双方のオブジェクト型が一致、または派生・継承関係にあるとき
87 //※コピーを行う
88
89 //mov rsi,RightTermReg
90 op_mov_RR(REG_RSI,RightTermReg);
91
92 //mov rdi,VarReg
93 op_mov_RR(REG_RDI,VarReg);
94
95 CClass *pClass = (CClass *)lpVarIndex;
96 int object_size = pClass->GetSize();
97
98 //mov rcx,object_size
99 op_mov_RV(sizeof(_int64),REG_RCX,object_size);
100
101 if(bUseHeap){
102 //mov rax,rsi
103 op_mov_RR(REG_RAX,REG_RSI);
104 }
105
106 //rep movs byte ptr[rdi],byte ptr[rsi]
107 op_rep_movs(sizeof(BYTE));
108
109 if(bUseHeap){
110 //mov rcx,rax
111 op_mov_RR(REG_RCX,REG_RAX);
112
113 //call free
114 extern SUBINFO *pSub_free;
115 op_call(pSub_free);
116 }
117
118 return;
119 }
120 }
121
122 SetError(1,NULL,cp);
123}
124
125void SetDoubleVariable(int type,RELATIVE_VAR *pRelative){
126 //////////////////////////
127 // Double型変数に書き込む
128 //////////////////////////
129
130 //xmm0に型変換
131 ChangeTypeToXmm_Double(type,REG_XMM0,REG_RAX);
132
133 if(pRelative->dwKind==VAR_GLOBAL){
134 if(pRelative->bOffsetOffset){
135 //movsd qword ptr[r11+offset],xmm0
136 OpBuffer[obp++]=(char)0xF2;
137 OpBuffer[obp++]=(char)0x41;
138 OpBuffer[obp++]=(char)0x0F;
139 OpBuffer[obp++]=(char)0x11;
140 OpBuffer[obp++]=(char)0x83;
141 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
142 pobj_GlobalVarSchedule->add();
143 obp+=sizeof(long);
144 }
145 else{
146 //movsd qword ptr[offset],xmm0
147 OpBuffer[obp++]=(char)0xF2;
148 OpBuffer[obp++]=(char)0x0F;
149 OpBuffer[obp++]=(char)0x11;
150 OpBuffer[obp++]=(char)0x04;
151 OpBuffer[obp++]=(char)0x25;
152 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
153 pobj_GlobalVarSchedule->add();
154 obp+=sizeof(long);
155 }
156 }
157 else if(pRelative->dwKind==VAR_REFGLOBAL){
158 SetError(300,NULL,cp);
159 }
160 else if(pRelative->dwKind==VAR_LOCAL){
161 if(pRelative->bOffsetOffset){
162 //movsd qword ptr[rsp+r11+offset],xmm0
163 OpBuffer[obp++]=(char)0xF2;
164 OpBuffer[obp++]=(char)0x42;
165 OpBuffer[obp++]=(char)0x0F;
166 OpBuffer[obp++]=(char)0x11;
167 OpBuffer[obp++]=(char)0x84;
168 OpBuffer[obp++]=(char)0x1C;
169 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
170 AddLocalVarAddrSchedule();
171 obp+=sizeof(long);
172 }
173 else{
174 //movsd qword ptr[rsp+offset],xmm0
175 OpBuffer[obp++]=(char)0xF2;
176 OpBuffer[obp++]=(char)0x0F;
177 OpBuffer[obp++]=(char)0x11;
178 OpBuffer[obp++]=(char)0x84;
179 OpBuffer[obp++]=(char)0x24;
180 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
181 AddLocalVarAddrSchedule();
182 obp+=sizeof(long);
183 }
184 }
185 else if( pRelative->dwKind == VAR_REFLOCAL ){
186 if(pRelative->bOffsetOffset){
187 //add r11,qword ptr[rsp+offset]
188 OpBuffer[obp++]=(char)0x4C;
189 OpBuffer[obp++]=(char)0x03;
190 OpBuffer[obp++]=(char)0x9C;
191 OpBuffer[obp++]=(char)0x24;
192 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
193 AddLocalVarAddrSchedule();
194 obp+=sizeof(long);
195 }
196 else{
197 //mov r11,qword ptr[rsp+offset]
198 op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32);
199 obp-=sizeof(long);
200 AddLocalVarAddrSchedule();
201 obp+=sizeof(long);
202 }
203
204 goto directmem;
205 }
206 else if(pRelative->dwKind==VAR_DIRECTMEM){
207directmem:
208 //movsd qword ptr[r11],xmm0
209 OpBuffer[obp++]=(char)0xF2;
210 OpBuffer[obp++]=(char)0x41;
211 OpBuffer[obp++]=(char)0x0F;
212 OpBuffer[obp++]=(char)0x11;
213 OpBuffer[obp++]=(char)0x03;
214 }
215}
216void SetSingleVariable(int type,RELATIVE_VAR *pRelative){
217 //////////////////////////
218 // Single型変数に書き込む
219 //////////////////////////
220
221 //xmm0に型変換
222 ChangeTypeToXmm_Single(type,REG_XMM0,REG_RAX);
223
224 if(pRelative->dwKind==VAR_GLOBAL){
225 if(pRelative->bOffsetOffset){
226 //movss dword ptr[r11+offset],xmm0
227 OpBuffer[obp++]=(char)0xF3;
228 OpBuffer[obp++]=(char)0x41;
229 OpBuffer[obp++]=(char)0x0F;
230 OpBuffer[obp++]=(char)0x11;
231 OpBuffer[obp++]=(char)0x83;
232 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
233 pobj_GlobalVarSchedule->add();
234 obp+=sizeof(long);
235 }
236 else{
237 //movss dword ptr[offset],xmm0
238 OpBuffer[obp++]=(char)0xF3;
239 OpBuffer[obp++]=(char)0x0F;
240 OpBuffer[obp++]=(char)0x11;
241 OpBuffer[obp++]=(char)0x04;
242 OpBuffer[obp++]=(char)0x25;
243 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
244 pobj_GlobalVarSchedule->add();
245 obp+=sizeof(long);
246 }
247 }
248 else if(pRelative->dwKind==VAR_REFGLOBAL){
249 SetError(300,NULL,cp);
250 }
251 else if(pRelative->dwKind==VAR_LOCAL){
252 if(pRelative->bOffsetOffset){
253 //movss dword ptr[rsp+r11+offset],xmm0
254 OpBuffer[obp++]=(char)0xF3;
255 OpBuffer[obp++]=(char)0x42;
256 OpBuffer[obp++]=(char)0x0F;
257 OpBuffer[obp++]=(char)0x11;
258 OpBuffer[obp++]=(char)0x84;
259 OpBuffer[obp++]=(char)0x1C;
260 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
261 AddLocalVarAddrSchedule();
262 obp+=sizeof(long);
263 }
264 else{
265 //movss dword ptr[rsp+offset],xmm0
266 OpBuffer[obp++]=(char)0xF3;
267 OpBuffer[obp++]=(char)0x0F;
268 OpBuffer[obp++]=(char)0x11;
269 OpBuffer[obp++]=(char)0x84;
270 OpBuffer[obp++]=(char)0x24;
271 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
272 AddLocalVarAddrSchedule();
273 obp+=sizeof(long);
274 }
275 }
276 else if( pRelative->dwKind == VAR_REFLOCAL ){
277 if(pRelative->bOffsetOffset){
278 //add r11,qword ptr[rsp+offset]
279 OpBuffer[obp++]=(char)0x4C;
280 OpBuffer[obp++]=(char)0x03;
281 OpBuffer[obp++]=(char)0x9C;
282 OpBuffer[obp++]=(char)0x24;
283 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
284 AddLocalVarAddrSchedule();
285 obp+=sizeof(long);
286 }
287 else{
288 //mov r11,qword ptr[rsp+offset]
289 op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32);
290 obp-=sizeof(long);
291 AddLocalVarAddrSchedule();
292 obp+=sizeof(long);
293 }
294
295 goto directmem;
296 }
297 else if(pRelative->dwKind==VAR_DIRECTMEM){
298directmem:
299 //movss dword ptr[r11],xmm0
300 OpBuffer[obp++]=(char)0xF3;
301 OpBuffer[obp++]=(char)0x41;
302 OpBuffer[obp++]=(char)0x0F;
303 OpBuffer[obp++]=(char)0x11;
304 OpBuffer[obp++]=(char)0x03;
305 }
306}
307void SetBooleanVariable(int type,RELATIVE_VAR *pRelative){
308 if(type==DEF_DOUBLE){
309 //Double型
310
311 //cvttsd2si rax,xmm0
312 op_cvttsd2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0);
313 }
314 else if(type==DEF_SINGLE){
315 //Single型
316
317 //cvttss2si rax,xmm0
318 op_cvttss2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0);
319 }
320
321 //cmp rax,0
322 op_cmp_value(GetTypeSize(type,-1),REG_RAX,0);
323
324 //setne al
325 op_setne( REG_RAX );
326
327 SetWholeVariable( sizeof(char), DEF_BYTE, pRelative);
328}
329void SetWholeVariable(int var_size,int type,RELATIVE_VAR *pRelative){
330 if(type==DEF_DOUBLE){
331 //Double型
332
333 //cvttsd2si rax,xmm0
334 op_cvttsd2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0);
335 }
336 else if(type==DEF_SINGLE){
337 //Single型
338
339 //cvttss2si rax,xmm0
340 op_cvttss2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0);
341 }
342 else{
343 //その他の整数
344
345 if(var_size==sizeof(_int64)){
346 //レジスタの値を64ビット(rax)に拡張する
347 ExtendTypeTo64(type,REG_RAX);
348 }
349 else if(var_size==sizeof(long)){
350 //レジスタの値を32ビット(eax)に拡張する
351 ExtendTypeTo32(type,REG_RAX);
352 }
353 else if(var_size==sizeof(short)){
354 //レジスタの値を16ビット(ax)に拡張する
355 ExtendTypeTo16(type,REG_RAX);
356 }
357 //8ビットは拡張なし
358 }
359
360 if(pRelative->dwKind==VAR_GLOBAL){
361 if(pRelative->bOffsetOffset){
362 //mov ptr[r11+offset],rax/eax/ax/al
363 op_mov_MR(var_size,REG_RAX,REG_R11,(int)pRelative->offset,MOD_BASE_DISP32);
364 obp-=sizeof(long);
365 pobj_GlobalVarSchedule->add();
366 obp+=sizeof(long);
367 }
368 else{
369 //mov ptr[offset],rax/eax/ax/al
370 op_mov_MR(var_size,REG_RAX,0,(int)pRelative->offset,MOD_DISP32);
371 obp-=sizeof(long);
372 pobj_GlobalVarSchedule->add();
373 obp+=sizeof(long);
374 }
375 }
376 else if( pRelative->dwKind == VAR_REFGLOBAL ){
377 if(pRelative->bOffsetOffset){
378 //add r11,qword ptr[offset]
379 op_add_RM( sizeof(_int64), REG_R11, REG_NON, (int)pRelative->offset, MOD_DISP32 );
380 obp-=sizeof(long);
381 pobj_GlobalVarSchedule->add();
382 obp+=sizeof(long);
383 }
384 else{
385 //mov r11,qword ptr[offset]
386 op_mov_RM(sizeof(_int64),REG_R11,REG_NON,(int)pRelative->offset,MOD_DISP32);
387 obp-=sizeof(long);
388 pobj_GlobalVarSchedule->add();
389 obp+=sizeof(long);
390 }
391
392 goto directmem;
393 }
394 else if(pRelative->dwKind==VAR_LOCAL){
395 if(pRelative->bOffsetOffset){
396 //mov ptr[rsp+r11+offset],rax/eax/ax/al
397 op_mov_MR_ex(var_size,REG_RAX,REG_RSP,REG_R11,(int)pRelative->offset,USE_OFFSET);
398 obp-=sizeof(long);
399 AddLocalVarAddrSchedule();
400 obp+=sizeof(long);
401 }
402 else{
403 //mov ptr[rsp+offset],rax/eax/ax/al
404 op_mov_MR(var_size,REG_RAX,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32);
405 obp-=sizeof(long);
406 AddLocalVarAddrSchedule();
407 obp+=sizeof(long);
408 }
409 }
410 else if( pRelative->dwKind == VAR_REFLOCAL ){
411 if(pRelative->bOffsetOffset){
412 //add r11,qword ptr[rsp+offset]
413 op_add_RM( sizeof(_int64), REG_R11, REG_RSP, (int)pRelative->offset, MOD_BASE_DISP32 );
414 obp-=sizeof(long);
415 AddLocalVarAddrSchedule();
416 obp+=sizeof(long);
417 }
418 else{
419 //mov r11,qword ptr[rsp+offset]
420 op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32);
421 obp-=sizeof(long);
422 AddLocalVarAddrSchedule();
423 obp+=sizeof(long);
424 }
425
426 goto directmem;
427 }
428 else if(pRelative->dwKind==VAR_DIRECTMEM){
429directmem:
430
431 //mov ptr[r11],rax/eax/ax/al
432 op_mov_MR(var_size,REG_RAX,REG_R11,0,MOD_BASE);
433 }
434}
Note: See TracBrowser for help on using the repository browser.