source: dev/BasicCompiler64/Compile_Set_Var.cpp@ 79

Last change on this file since 79 was 75, checked in by dai_9181, 18 years ago

TYPEINFO→Typeへのリファクタリングを実施。64bitはほぼ完了。32bitが全般的に未完成。

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