source: dev/BasicCompiler64/Compile_Set_Var.cpp@ 62

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

グローバル変数に対してByRefを指定できるようにした

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 int object_size = GetSizeOfClass((CClass *)lpVarIndex);
96
97 //mov rcx,object_size
98 op_mov_RV(sizeof(_int64),REG_RCX,object_size);
99
100 if(bUseHeap){
101 //mov rax,rsi
102 op_mov_RR(REG_RAX,REG_RSI);
103 }
104
105 //rep movs byte ptr[rdi],byte ptr[rsi]
106 op_rep_movs(sizeof(BYTE));
107
108 if(bUseHeap){
109 //mov rcx,rax
110 op_mov_RR(REG_RCX,REG_RAX);
111
112 //call free
113 extern SUBINFO *pSub_free;
114 op_call(pSub_free);
115 }
116
117 return;
118 }
119 }
120
121 SetError(1,NULL,cp);
122}
123
124void SetDoubleVariable(int type,RELATIVE_VAR *pRelative){
125 //////////////////////////
126 // Double型変数に書き込む
127 //////////////////////////
128
129 //xmm0に型変換
130 ChangeTypeToXmm_Double(type,REG_XMM0,REG_RAX);
131
132 if(pRelative->dwKind==VAR_GLOBAL){
133 if(pRelative->bOffsetOffset){
134 //movsd qword ptr[r11+offset],xmm0
135 OpBuffer[obp++]=(char)0xF2;
136 OpBuffer[obp++]=(char)0x41;
137 OpBuffer[obp++]=(char)0x0F;
138 OpBuffer[obp++]=(char)0x11;
139 OpBuffer[obp++]=(char)0x83;
140 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
141 pobj_GlobalVarSchedule->add();
142 obp+=sizeof(long);
143 }
144 else{
145 //movsd qword ptr[offset],xmm0
146 OpBuffer[obp++]=(char)0xF2;
147 OpBuffer[obp++]=(char)0x0F;
148 OpBuffer[obp++]=(char)0x11;
149 OpBuffer[obp++]=(char)0x04;
150 OpBuffer[obp++]=(char)0x25;
151 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
152 pobj_GlobalVarSchedule->add();
153 obp+=sizeof(long);
154 }
155 }
156 else if(pRelative->dwKind==VAR_REFGLOBAL){
157 SetError(300,NULL,cp);
158 }
159 else if(pRelative->dwKind==VAR_LOCAL){
160 if(pRelative->bOffsetOffset){
161 //movsd qword ptr[rsp+r11+offset],xmm0
162 OpBuffer[obp++]=(char)0xF2;
163 OpBuffer[obp++]=(char)0x42;
164 OpBuffer[obp++]=(char)0x0F;
165 OpBuffer[obp++]=(char)0x11;
166 OpBuffer[obp++]=(char)0x84;
167 OpBuffer[obp++]=(char)0x1C;
168 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
169 AddLocalVarAddrSchedule();
170 obp+=sizeof(long);
171 }
172 else{
173 //movsd qword ptr[rsp+offset],xmm0
174 OpBuffer[obp++]=(char)0xF2;
175 OpBuffer[obp++]=(char)0x0F;
176 OpBuffer[obp++]=(char)0x11;
177 OpBuffer[obp++]=(char)0x84;
178 OpBuffer[obp++]=(char)0x24;
179 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
180 AddLocalVarAddrSchedule();
181 obp+=sizeof(long);
182 }
183 }
184 else if( pRelative->dwKind == VAR_REFLOCAL ){
185 if(pRelative->bOffsetOffset){
186 //add r11,qword ptr[rsp+offset]
187 OpBuffer[obp++]=(char)0x4C;
188 OpBuffer[obp++]=(char)0x03;
189 OpBuffer[obp++]=(char)0x9C;
190 OpBuffer[obp++]=(char)0x24;
191 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
192 AddLocalVarAddrSchedule();
193 obp+=sizeof(long);
194 }
195 else{
196 //mov r11,qword ptr[rsp+offset]
197 op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32);
198 obp-=sizeof(long);
199 AddLocalVarAddrSchedule();
200 obp+=sizeof(long);
201 }
202
203 goto directmem;
204 }
205 else if(pRelative->dwKind==VAR_DIRECTMEM){
206directmem:
207 //movsd qword ptr[r11],xmm0
208 OpBuffer[obp++]=(char)0xF2;
209 OpBuffer[obp++]=(char)0x41;
210 OpBuffer[obp++]=(char)0x0F;
211 OpBuffer[obp++]=(char)0x11;
212 OpBuffer[obp++]=(char)0x03;
213 }
214}
215void SetSingleVariable(int type,RELATIVE_VAR *pRelative){
216 //////////////////////////
217 // Single型変数に書き込む
218 //////////////////////////
219
220 //xmm0に型変換
221 ChangeTypeToXmm_Single(type,REG_XMM0,REG_RAX);
222
223 if(pRelative->dwKind==VAR_GLOBAL){
224 if(pRelative->bOffsetOffset){
225 //movss dword ptr[r11+offset],xmm0
226 OpBuffer[obp++]=(char)0xF3;
227 OpBuffer[obp++]=(char)0x41;
228 OpBuffer[obp++]=(char)0x0F;
229 OpBuffer[obp++]=(char)0x11;
230 OpBuffer[obp++]=(char)0x83;
231 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
232 pobj_GlobalVarSchedule->add();
233 obp+=sizeof(long);
234 }
235 else{
236 //movss dword ptr[offset],xmm0
237 OpBuffer[obp++]=(char)0xF3;
238 OpBuffer[obp++]=(char)0x0F;
239 OpBuffer[obp++]=(char)0x11;
240 OpBuffer[obp++]=(char)0x04;
241 OpBuffer[obp++]=(char)0x25;
242 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
243 pobj_GlobalVarSchedule->add();
244 obp+=sizeof(long);
245 }
246 }
247 else if(pRelative->dwKind==VAR_REFGLOBAL){
248 SetError(300,NULL,cp);
249 }
250 else if(pRelative->dwKind==VAR_LOCAL){
251 if(pRelative->bOffsetOffset){
252 //movss dword ptr[rsp+r11+offset],xmm0
253 OpBuffer[obp++]=(char)0xF3;
254 OpBuffer[obp++]=(char)0x42;
255 OpBuffer[obp++]=(char)0x0F;
256 OpBuffer[obp++]=(char)0x11;
257 OpBuffer[obp++]=(char)0x84;
258 OpBuffer[obp++]=(char)0x1C;
259 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
260 AddLocalVarAddrSchedule();
261 obp+=sizeof(long);
262 }
263 else{
264 //movss dword ptr[rsp+offset],xmm0
265 OpBuffer[obp++]=(char)0xF3;
266 OpBuffer[obp++]=(char)0x0F;
267 OpBuffer[obp++]=(char)0x11;
268 OpBuffer[obp++]=(char)0x84;
269 OpBuffer[obp++]=(char)0x24;
270 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
271 AddLocalVarAddrSchedule();
272 obp+=sizeof(long);
273 }
274 }
275 else if( pRelative->dwKind == VAR_REFLOCAL ){
276 if(pRelative->bOffsetOffset){
277 //add r11,qword ptr[rsp+offset]
278 OpBuffer[obp++]=(char)0x4C;
279 OpBuffer[obp++]=(char)0x03;
280 OpBuffer[obp++]=(char)0x9C;
281 OpBuffer[obp++]=(char)0x24;
282 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
283 AddLocalVarAddrSchedule();
284 obp+=sizeof(long);
285 }
286 else{
287 //mov r11,qword ptr[rsp+offset]
288 op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32);
289 obp-=sizeof(long);
290 AddLocalVarAddrSchedule();
291 obp+=sizeof(long);
292 }
293
294 goto directmem;
295 }
296 else if(pRelative->dwKind==VAR_DIRECTMEM){
297directmem:
298 //movss dword ptr[r11],xmm0
299 OpBuffer[obp++]=(char)0xF3;
300 OpBuffer[obp++]=(char)0x41;
301 OpBuffer[obp++]=(char)0x0F;
302 OpBuffer[obp++]=(char)0x11;
303 OpBuffer[obp++]=(char)0x03;
304 }
305}
306void SetBooleanVariable(int type,RELATIVE_VAR *pRelative){
307 if(type==DEF_DOUBLE){
308 //Double型
309
310 //cvttsd2si rax,xmm0
311 op_cvttsd2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0);
312 }
313 else if(type==DEF_SINGLE){
314 //Single型
315
316 //cvttss2si rax,xmm0
317 op_cvttss2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0);
318 }
319
320 //cmp rax,0
321 op_cmp_value(GetTypeSize(type,-1),REG_RAX,0);
322
323 //setne al
324 op_setne( REG_RAX );
325
326 SetWholeVariable( sizeof(char), DEF_BYTE, pRelative);
327}
328void SetWholeVariable(int var_size,int type,RELATIVE_VAR *pRelative){
329 if(type==DEF_DOUBLE){
330 //Double型
331
332 //cvttsd2si rax,xmm0
333 op_cvttsd2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0);
334 }
335 else if(type==DEF_SINGLE){
336 //Single型
337
338 //cvttss2si rax,xmm0
339 op_cvttss2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0);
340 }
341 else{
342 //その他の整数
343
344 if(var_size==sizeof(_int64)){
345 //レジスタの値を64ビット(rax)に拡張する
346 ExtendTypeTo64(type,REG_RAX);
347 }
348 else if(var_size==sizeof(long)){
349 //レジスタの値を32ビット(eax)に拡張する
350 ExtendTypeTo32(type,REG_RAX);
351 }
352 else if(var_size==sizeof(short)){
353 //レジスタの値を16ビット(ax)に拡張する
354 ExtendTypeTo16(type,REG_RAX);
355 }
356 //8ビットは拡張なし
357 }
358
359 if(pRelative->dwKind==VAR_GLOBAL){
360 if(pRelative->bOffsetOffset){
361 //mov ptr[r11+offset],rax/eax/ax/al
362 op_mov_MR(var_size,REG_RAX,REG_R11,(int)pRelative->offset,MOD_BASE_DISP32);
363 obp-=sizeof(long);
364 pobj_GlobalVarSchedule->add();
365 obp+=sizeof(long);
366 }
367 else{
368 //mov ptr[offset],rax/eax/ax/al
369 op_mov_MR(var_size,REG_RAX,0,(int)pRelative->offset,MOD_DISP32);
370 obp-=sizeof(long);
371 pobj_GlobalVarSchedule->add();
372 obp+=sizeof(long);
373 }
374 }
375 else if( pRelative->dwKind == VAR_REFGLOBAL ){
376 if(pRelative->bOffsetOffset){
377 //add r11,qword ptr[offset]
378 op_add_RM( sizeof(_int64), REG_R11, REG_NON, (int)pRelative->offset, MOD_DISP32 );
379 obp-=sizeof(long);
380 pobj_GlobalVarSchedule->add();
381 obp+=sizeof(long);
382 }
383 else{
384 //mov r11,qword ptr[offset]
385 op_mov_RM(sizeof(_int64),REG_R11,REG_NON,(int)pRelative->offset,MOD_DISP32);
386 obp-=sizeof(long);
387 pobj_GlobalVarSchedule->add();
388 obp+=sizeof(long);
389 }
390
391 goto directmem;
392 }
393 else if(pRelative->dwKind==VAR_LOCAL){
394 if(pRelative->bOffsetOffset){
395 //mov ptr[rsp+r11+offset],rax/eax/ax/al
396 op_mov_MR_ex(var_size,REG_RAX,REG_RSP,REG_R11,(int)pRelative->offset,USE_OFFSET);
397 obp-=sizeof(long);
398 AddLocalVarAddrSchedule();
399 obp+=sizeof(long);
400 }
401 else{
402 //mov ptr[rsp+offset],rax/eax/ax/al
403 op_mov_MR(var_size,REG_RAX,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32);
404 obp-=sizeof(long);
405 AddLocalVarAddrSchedule();
406 obp+=sizeof(long);
407 }
408 }
409 else if( pRelative->dwKind == VAR_REFLOCAL ){
410 if(pRelative->bOffsetOffset){
411 //add r11,qword ptr[rsp+offset]
412 op_add_RM( sizeof(_int64), REG_R11, REG_RSP, (int)pRelative->offset, MOD_BASE_DISP32 );
413 obp-=sizeof(long);
414 AddLocalVarAddrSchedule();
415 obp+=sizeof(long);
416 }
417 else{
418 //mov r11,qword ptr[rsp+offset]
419 op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32);
420 obp-=sizeof(long);
421 AddLocalVarAddrSchedule();
422 obp+=sizeof(long);
423 }
424
425 goto directmem;
426 }
427 else if(pRelative->dwKind==VAR_DIRECTMEM){
428directmem:
429
430 //mov ptr[r11],rax/eax/ax/al
431 op_mov_MR(var_size,REG_RAX,REG_R11,0,MOD_BASE);
432 }
433}
Note: See TracBrowser for help on using the repository browser.