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

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