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

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