source: dev/trunk/ab5.0/abdev/compiler_x64/Compile_Set_Var.cpp@ 797

Last change on this file since 797 was 468, checked in by dai_9181, 17 years ago

64bit版を最新の状態にした

File size: 10.2 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 compiler.errorMessenger.Output(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 compiler.codeGenerator.op_movsd_MR( REG_XMM0, REG_R11, (long)pRelative->offset, MOD_BASE_DISP32, Schedule::GlobalVar );
108 }
109 else{
110 //movsd qword ptr[offset],xmm0
111 compiler.codeGenerator.op_movsd_MR( REG_XMM0, 0, (long)pRelative->offset, MOD_DISP32, Schedule::GlobalVar );
112 }
113 }
114 else if(pRelative->dwKind==VAR_REFGLOBAL){
115 compiler.errorMessenger.Output(300,NULL,cp);
116 }
117 else if(pRelative->dwKind==VAR_LOCAL){
118 if(pRelative->bOffsetOffset){
119 //movsd qword ptr[rsp+r11+offset],xmm0
120 compiler.codeGenerator.PutOld(
121 (char)0xF2,
122 (char)0x42,
123 (char)0x0F,
124 (char)0x11,
125 (char)0x84,
126 (char)0x1C
127 );
128 compiler.codeGenerator.localVarPertialSchedules.push_back(
129 compiler.codeGenerator.PutOld( (long)pRelative->offset, true )
130 );
131 }
132 else{
133 //movsd qword ptr[rsp+offset],xmm0
134 compiler.codeGenerator.localVarPertialSchedules.push_back(
135 compiler.codeGenerator.op_movsd_MR( REG_XMM0, REG_RSP, (long)pRelative->offset, MOD_BASE_DISP32, Schedule::None, true )
136 );
137 }
138 }
139 else if( pRelative->dwKind == VAR_REFLOCAL ){
140 if(pRelative->bOffsetOffset){
141 //add r11,qword ptr[rsp+offset]
142 compiler.codeGenerator.localVarPertialSchedules.push_back(
143 compiler.codeGenerator.op_add_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32, Schedule::None, true )
144 );
145 }
146 else{
147 //mov r11,qword ptr[rsp+offset]
148 compiler.codeGenerator.localVarPertialSchedules.push_back(
149 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32, Schedule::None, true )
150 );
151 }
152
153 goto directmem;
154 }
155 else if(pRelative->dwKind==VAR_DIRECTMEM){
156directmem:
157 //movsd qword ptr[r11],xmm0
158 compiler.codeGenerator.op_movsd_MR( REG_XMM0, REG_R11, 0, MOD_BASE );
159 }
160}
161void SetSingleVariable(int type,RELATIVE_VAR *pRelative){
162 //////////////////////////
163 // Single型変数に書き込む
164 //////////////////////////
165
166 //xmm0に型変換
167 ChangeTypeToXmm_Single(type,REG_XMM0,REG_RAX);
168
169 if(pRelative->dwKind==VAR_GLOBAL){
170 if(pRelative->bOffsetOffset){
171 //movss dword ptr[r11+offset],xmm0
172 compiler.codeGenerator.op_movss_MR( REG_XMM0, REG_R11, (long)pRelative->offset, MOD_BASE_DISP32, Schedule::GlobalVar );
173 }
174 else{
175 //movss dword ptr[offset],xmm0
176 compiler.codeGenerator.op_movss_MR( REG_XMM0, 0, (long)pRelative->offset, MOD_DISP32, Schedule::GlobalVar );
177 }
178 }
179 else if(pRelative->dwKind==VAR_REFGLOBAL){
180 compiler.errorMessenger.Output(300,NULL,cp);
181 }
182 else if(pRelative->dwKind==VAR_LOCAL){
183 if(pRelative->bOffsetOffset){
184 //movss dword ptr[rsp+r11+offset],xmm0
185 compiler.codeGenerator.PutOld(
186 (char)0xF3,
187 (char)0x42,
188 (char)0x0F,
189 (char)0x11,
190 (char)0x84,
191 (char)0x1C
192 );
193 compiler.codeGenerator.localVarPertialSchedules.push_back(
194 compiler.codeGenerator.PutOld( (long)pRelative->offset, true )
195 );
196 }
197 else{
198 //movss dword ptr[rsp+offset],xmm0
199 compiler.codeGenerator.localVarPertialSchedules.push_back(
200 compiler.codeGenerator.op_movss_MR( REG_XMM0, REG_RSP, (long)pRelative->offset, MOD_BASE_DISP32, Schedule::None, true )
201 );
202 }
203 }
204 else if( pRelative->dwKind == VAR_REFLOCAL ){
205 if(pRelative->bOffsetOffset){
206 //add r11,qword ptr[rsp+offset]
207 compiler.codeGenerator.localVarPertialSchedules.push_back(
208 compiler.codeGenerator.op_add_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32, Schedule::None, true )
209 );
210 }
211 else{
212 //mov r11,qword ptr[rsp+offset]
213 compiler.codeGenerator.localVarPertialSchedules.push_back(
214 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32, Schedule::None, true )
215 );
216 }
217
218 goto directmem;
219 }
220 else if(pRelative->dwKind==VAR_DIRECTMEM){
221directmem:
222 //movss dword ptr[r11],xmm0
223 compiler.codeGenerator.op_movss_MR( REG_XMM0, REG_R11, 0, MOD_BASE );
224 }
225}
226void SetRealVariable(int VarType, int CalcType, RELATIVE_VAR *pRelativeVar){
227 if(VarType==DEF_DOUBLE){
228 //Double型変数へスタックの内容を格納する
229 SetDoubleVariable(CalcType,pRelativeVar);
230 }
231 else if(VarType==DEF_SINGLE){
232 //Single型変数へスタックの内容を格納する
233 SetSingleVariable(CalcType,pRelativeVar);
234 }
235}
236void SetBooleanVariable(int type,RELATIVE_VAR *pRelative){
237 if(type==DEF_DOUBLE){
238 //Double型
239
240 //cvttsd2si rax,xmm0
241 compiler.codeGenerator.op_cvttsd2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0);
242 }
243 else if(type==DEF_SINGLE){
244 //Single型
245
246 //cvttss2si rax,xmm0
247 compiler.codeGenerator.op_cvttss2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0);
248 }
249
250 //cmp rax,0
251 compiler.codeGenerator.op_cmp_value(Type(type).GetSize(),REG_RAX,0);
252
253 //setne al
254 compiler.codeGenerator.op_setne( REG_RAX );
255
256 SetWholeVariable( sizeof(char), DEF_BYTE, pRelative);
257}
258void SetWholeVariable(int varSize,int type,RELATIVE_VAR *pRelative){
259 if(type==DEF_DOUBLE){
260 //Double型
261
262 //cvttsd2si rax,xmm0
263 compiler.codeGenerator.op_cvttsd2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0);
264 }
265 else if(type==DEF_SINGLE){
266 //Single型
267
268 //cvttss2si rax,xmm0
269 compiler.codeGenerator.op_cvttss2si_xmm(sizeof(_int64),REG_RAX,REG_XMM0);
270 }
271 else{
272 //その他の整数
273
274 if(varSize==sizeof(_int64)){
275 //レジスタの値を64ビット(rax)に拡張する
276 ExtendTypeTo64(type,REG_RAX);
277 }
278 else if(varSize==sizeof(long)){
279 //レジスタの値を32ビット(eax)に拡張する
280 ExtendTypeTo32(type,REG_RAX);
281 }
282 else if(varSize==sizeof(short)){
283 //レジスタの値を16ビット(ax)に拡張する
284 ExtendTypeTo16(type,REG_RAX);
285 }
286 //8ビットは拡張なし
287 }
288
289 if(pRelative->dwKind==VAR_GLOBAL){
290 if(pRelative->bOffsetOffset){
291 //mov ptr[r11+offset],rax/eax/ax/al
292 compiler.codeGenerator.op_mov_MR(varSize,REG_RAX,REG_R11,(int)pRelative->offset,MOD_BASE_DISP32, Schedule::GlobalVar );
293 }
294 else{
295 //mov ptr[offset],rax/eax/ax/al
296 compiler.codeGenerator.op_mov_MR(varSize,REG_RAX,0,(int)pRelative->offset,MOD_DISP32, Schedule::GlobalVar );
297 }
298 }
299 else if( pRelative->dwKind == VAR_REFGLOBAL ){
300 if(pRelative->bOffsetOffset){
301 //add r11,qword ptr[offset]
302 compiler.codeGenerator.op_add_RM( sizeof(_int64), REG_R11, REG_NON, (int)pRelative->offset, MOD_DISP32, Schedule::GlobalVar );
303 }
304 else{
305 //mov r11,qword ptr[offset]
306 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_R11,REG_NON,(int)pRelative->offset,MOD_DISP32, Schedule::GlobalVar );
307 }
308
309 goto directmem;
310 }
311 else if(pRelative->dwKind==VAR_LOCAL){
312 if(pRelative->bOffsetOffset){
313 //mov ptr[rsp+r11+offset],rax/eax/ax/al
314 compiler.codeGenerator.localVarPertialSchedules.push_back(
315 compiler.codeGenerator.op_mov_MR_ex(varSize,REG_RAX,REG_RSP,REG_R11,(int)pRelative->offset,USE_OFFSET, Schedule::None, true )
316 );
317 }
318 else{
319 //mov ptr[rsp+offset],rax/eax/ax/al
320 compiler.codeGenerator.localVarPertialSchedules.push_back(
321 compiler.codeGenerator.op_mov_MR(varSize,REG_RAX,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32, Schedule::None, true )
322 );
323 }
324 }
325 else if( pRelative->dwKind == VAR_REFLOCAL ){
326 if(pRelative->bOffsetOffset){
327 //add r11,qword ptr[rsp+offset]
328 compiler.codeGenerator.localVarPertialSchedules.push_back(
329 compiler.codeGenerator.op_add_RM( sizeof(_int64), REG_R11, REG_RSP, (int)pRelative->offset, MOD_BASE_DISP32, Schedule::None, true )
330 );
331 }
332 else{
333 //mov r11,qword ptr[rsp+offset]
334 compiler.codeGenerator.localVarPertialSchedules.push_back(
335 compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_R11,REG_RSP,(int)pRelative->offset,MOD_BASE_DISP32, Schedule::None, true )
336 );
337 }
338
339 goto directmem;
340 }
341 else if(pRelative->dwKind==VAR_DIRECTMEM){
342directmem:
343
344 //mov ptr[r11],rax/eax/ax/al
345 compiler.codeGenerator.op_mov_MR(varSize,REG_RAX,REG_R11,0,MOD_BASE);
346 }
347}
Note: See TracBrowser for help on using the repository browser.