source: dev/BasicCompiler64/Compile_Set_Var.cpp@ 48

Last change on this file since 48 was 40, checked in by dai_9181, 18 years ago

ByRef修飾子を関数戻り値とDimステートメントで指定可能にした。

File size: 10.5 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_LOCAL){
157 if(pRelative->bOffsetOffset){
158 //movsd qword ptr[rsp+r11+offset],xmm0
159 OpBuffer[obp++]=(char)0xF2;
160 OpBuffer[obp++]=(char)0x42;
161 OpBuffer[obp++]=(char)0x0F;
162 OpBuffer[obp++]=(char)0x11;
163 OpBuffer[obp++]=(char)0x84;
164 OpBuffer[obp++]=(char)0x1C;
165 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
166 AddLocalVarAddrSchedule();
167 obp+=sizeof(long);
168 }
169 else{
170 //movsd qword ptr[rsp+offset],xmm0
171 OpBuffer[obp++]=(char)0xF2;
172 OpBuffer[obp++]=(char)0x0F;
173 OpBuffer[obp++]=(char)0x11;
174 OpBuffer[obp++]=(char)0x84;
175 OpBuffer[obp++]=(char)0x24;
176 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
177 AddLocalVarAddrSchedule();
178 obp+=sizeof(long);
179 }
180 }
181 else if( pRelative->dwKind == VAR_REFLOCAL ){
182 if(pRelative->bOffsetOffset){
183 //add r11,qword ptr[rsp+offset]
184 OpBuffer[obp++]=(char)0x4C;
185 OpBuffer[obp++]=(char)0x03;
186 OpBuffer[obp++]=(char)0x9C;
187 OpBuffer[obp++]=(char)0x24;
188 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
189 AddLocalVarAddrSchedule();
190 obp+=sizeof(long);
191 }
192 else{
193 //mov r11,qword ptr[rsp+offset]
194 op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32);
195 obp-=sizeof(long);
196 AddLocalVarAddrSchedule();
197 obp+=sizeof(long);
198 }
199
200 goto directmem;
201 }
202 else if(pRelative->dwKind==VAR_DIRECTMEM){
203directmem:
204 //movsd qword ptr[r11],xmm0
205 OpBuffer[obp++]=(char)0xF2;
206 OpBuffer[obp++]=(char)0x41;
207 OpBuffer[obp++]=(char)0x0F;
208 OpBuffer[obp++]=(char)0x11;
209 OpBuffer[obp++]=(char)0x03;
210 }
211}
212void SetSingleVariable(int type,RELATIVE_VAR *pRelative){
213 //////////////////////////
214 // Single型変数に書き込む
215 //////////////////////////
216
217 //xmm0に型変換
218 ChangeTypeToXmm_Single(type,REG_XMM0,REG_RAX);
219
220 if(pRelative->dwKind==VAR_GLOBAL){
221 if(pRelative->bOffsetOffset){
222 //movss dword ptr[r11+offset],xmm0
223 OpBuffer[obp++]=(char)0xF3;
224 OpBuffer[obp++]=(char)0x41;
225 OpBuffer[obp++]=(char)0x0F;
226 OpBuffer[obp++]=(char)0x11;
227 OpBuffer[obp++]=(char)0x83;
228 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
229 pobj_GlobalVarSchedule->add();
230 obp+=sizeof(long);
231 }
232 else{
233 //movss dword ptr[offset],xmm0
234 OpBuffer[obp++]=(char)0xF3;
235 OpBuffer[obp++]=(char)0x0F;
236 OpBuffer[obp++]=(char)0x11;
237 OpBuffer[obp++]=(char)0x04;
238 OpBuffer[obp++]=(char)0x25;
239 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
240 pobj_GlobalVarSchedule->add();
241 obp+=sizeof(long);
242 }
243 }
244 else if(pRelative->dwKind==VAR_LOCAL){
245 if(pRelative->bOffsetOffset){
246 //movss dword ptr[rsp+r11+offset],xmm0
247 OpBuffer[obp++]=(char)0xF3;
248 OpBuffer[obp++]=(char)0x42;
249 OpBuffer[obp++]=(char)0x0F;
250 OpBuffer[obp++]=(char)0x11;
251 OpBuffer[obp++]=(char)0x84;
252 OpBuffer[obp++]=(char)0x1C;
253 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
254 AddLocalVarAddrSchedule();
255 obp+=sizeof(long);
256 }
257 else{
258 //movss dword ptr[rsp+offset],xmm0
259 OpBuffer[obp++]=(char)0xF3;
260 OpBuffer[obp++]=(char)0x0F;
261 OpBuffer[obp++]=(char)0x11;
262 OpBuffer[obp++]=(char)0x84;
263 OpBuffer[obp++]=(char)0x24;
264 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
265 AddLocalVarAddrSchedule();
266 obp+=sizeof(long);
267 }
268 }
269 else if( pRelative->dwKind == VAR_REFLOCAL ){
270 if(pRelative->bOffsetOffset){
271 //add r11,qword ptr[rsp+offset]
272 OpBuffer[obp++]=(char)0x4C;
273 OpBuffer[obp++]=(char)0x03;
274 OpBuffer[obp++]=(char)0x9C;
275 OpBuffer[obp++]=(char)0x24;
276 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
277 AddLocalVarAddrSchedule();
278 obp+=sizeof(long);
279 }
280 else{
281 //mov r11,qword ptr[rsp+offset]
282 op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32);
283 obp-=sizeof(long);
284 AddLocalVarAddrSchedule();
285 obp+=sizeof(long);
286 }
287
288 goto directmem;
289 }
290 else if(pRelative->dwKind==VAR_DIRECTMEM){
291directmem:
292 //movss dword ptr[r11],xmm0
293 OpBuffer[obp++]=(char)0xF3;
294 OpBuffer[obp++]=(char)0x41;
295 OpBuffer[obp++]=(char)0x0F;
296 OpBuffer[obp++]=(char)0x11;
297 OpBuffer[obp++]=(char)0x03;
298 }
299}
300void SetBooleanVariable(int type,RELATIVE_VAR *pRelative){
301 if(type==DEF_DOUBLE){
302 //Double型
303
304 //cvttsd2si rax,xmm0
305 op_cvttsd2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0);
306 }
307 else if(type==DEF_SINGLE){
308 //Single型
309
310 //cvttss2si rax,xmm0
311 op_cvttss2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0);
312 }
313
314 //cmp rax,0
315 op_cmp_value(GetTypeSize(type,-1),REG_RAX,0);
316
317 //setne al
318 op_setne( REG_RAX );
319
320 SetWholeVariable( sizeof(char), DEF_BYTE, pRelative);
321}
322void SetWholeVariable(int var_size,int type,RELATIVE_VAR *pRelative){
323 if(type==DEF_DOUBLE){
324 //Double型
325
326 //cvttsd2si rax,xmm0
327 op_cvttsd2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0);
328 }
329 else if(type==DEF_SINGLE){
330 //Single型
331
332 //cvttss2si rax,xmm0
333 op_cvttss2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0);
334 }
335 else{
336 //その他の整数
337
338 if(var_size==sizeof(_int64)){
339 //レジスタの値を64ビット(rax)に拡張する
340 ExtendTypeTo64(type,REG_RAX);
341 }
342 else if(var_size==sizeof(long)){
343 //レジスタの値を32ビット(eax)に拡張する
344 ExtendTypeTo32(type,REG_RAX);
345 }
346 else if(var_size==sizeof(short)){
347 //レジスタの値を16ビット(ax)に拡張する
348 ExtendTypeTo16(type,REG_RAX);
349 }
350 //8ビットは拡張なし
351 }
352
353 if(pRelative->dwKind==VAR_GLOBAL){
354 if(pRelative->bOffsetOffset){
355 //mov ptr[r11+offset],rax/eax/ax/al
356 op_mov_MR(var_size,REG_RAX,REG_R11,(int)pRelative->offset,MOD_BASE_DISP32);
357 obp-=sizeof(long);
358 pobj_GlobalVarSchedule->add();
359 obp+=sizeof(long);
360 }
361 else{
362 //mov ptr[offset],rax/eax/ax/al
363 op_mov_MR(var_size,REG_RAX,0,(int)pRelative->offset,MOD_DISP32);
364 obp-=sizeof(long);
365 pobj_GlobalVarSchedule->add();
366 obp+=sizeof(long);
367 }
368 }
369 else if(pRelative->dwKind==VAR_LOCAL){
370 if(pRelative->bOffsetOffset){
371 //mov ptr[rsp+r11+offset],rax/eax/ax/al
372 op_mov_MR_ex(var_size,REG_RAX,REG_RSP,REG_R11,(int)pRelative->offset,USE_OFFSET);
373 obp-=sizeof(long);
374 AddLocalVarAddrSchedule();
375 obp+=sizeof(long);
376 }
377 else{
378 //mov ptr[rsp+offset],rax/eax/ax/al
379 op_mov_MR(var_size,REG_RAX,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32);
380 obp-=sizeof(long);
381 AddLocalVarAddrSchedule();
382 obp+=sizeof(long);
383 }
384 }
385 else if( pRelative->dwKind == VAR_REFLOCAL ){
386 if(pRelative->bOffsetOffset){
387 //add r11,qword ptr[rsp+offset]
388 OpBuffer[obp++]=(char)0x4C;
389 OpBuffer[obp++]=(char)0x03;
390 OpBuffer[obp++]=(char)0x9C;
391 OpBuffer[obp++]=(char)0x24;
392 *((long *)(OpBuffer+obp))=(int)pRelative->offset;
393 AddLocalVarAddrSchedule();
394 obp+=sizeof(long);
395 }
396 else{
397 //mov r11,qword ptr[rsp+offset]
398 op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32);
399 obp-=sizeof(long);
400 AddLocalVarAddrSchedule();
401 obp+=sizeof(long);
402 }
403
404 goto directmem;
405 }
406 else if(pRelative->dwKind==VAR_DIRECTMEM){
407directmem:
408
409 //mov ptr[r11],rax/eax/ax/al
410 op_mov_MR(var_size,REG_RAX,REG_R11,0,MOD_BASE);
411 }
412}
Note: See TracBrowser for help on using the repository browser.