source: dev/trunk/abdev/BasicCompiler64/Compile_Set_Var.cpp@ 225

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

コード全体のリファクタリングを実施

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