source: dev/trunk/abdev/BasicCompiler64/NumOpe_TypeOperation.cpp@ 198

Last change on this file since 198 was 198, checked in by dai_9181, 17 years ago
File size: 12.7 KB
Line 
1#include <jenga/include/smoothie/Smoothie.h>
2
3#include <Compiler.h>
4
5#include "../BasicCompiler_Common/common.h"
6#include "Opcode.h"
7
8void ExtendTypeTo64(int type,int reg){
9 if(type==DEF_LONG){
10 //movsxd reg64,reg32
11 op_movsxd(reg,reg);
12 }
13 else if(type==DEF_DWORD){
14 //and reg,00000000FFFFFFFFh
15 }
16 else if(type==DEF_INTEGER || (Smoothie::IsUnicode()&&type==DEF_CHAR)){
17 //movsx reg64,reg16
18 op_movsx64_FromReg16(reg,reg);
19 }
20 else if(type==DEF_WORD){
21 //and reg,000000000000FFFFh
22 op_and64_value(reg,(int)0xFFFF);
23 }
24 else if(type==DEF_SBYTE || (Smoothie::IsUnicode()==false&&type==DEF_CHAR)){
25 //movsx reg64,reg8
26 op_movsx64_FromReg8(reg,reg);
27 }
28 else if(type==DEF_BYTE || type==DEF_BOOLEAN){
29 //and reg,00000000000000FFh
30 op_and64_value(reg,(int)0x00FF);
31 }
32}
33void ExtendTypeTo32(int type,int reg){
34 if(type==DEF_INTEGER || (Smoothie::IsUnicode()&&type==DEF_CHAR)){
35 //movsx reg32,reg16
36 op_movsx32_FromReg16(reg,reg);
37 }
38 else if(type==DEF_WORD){
39 //and reg,0000FFFFh
40 op_and32_value(reg,(int)0xFFFF);
41 }
42 else if(type==DEF_SBYTE || (Smoothie::IsUnicode()==false&&type==DEF_CHAR)){
43 //movsx reg32,reg8
44 op_movsx32_FromReg8(reg,reg);
45 }
46 else if(type==DEF_BYTE || type==DEF_BOOLEAN){
47 //and reg,000000FFh
48 op_and32_value(reg,(int)0xFF);
49 }
50}
51void ExtendTypeTo16(int type,int reg){
52 if(type==DEF_SBYTE || (Smoothie::IsUnicode()==false&&type==DEF_CHAR)){
53 //movsx reg16,reg8
54 op_movsx16_FromReg8(reg,reg);
55 }
56 else if(type==DEF_BYTE){
57 //and reg,000000FFh
58 op_and32_value(reg,(int)0xFF);
59 }
60}
61
62void ChangeTypeToXmm_Double(int type,int xmm_reg,int general_reg){
63 if(type==DEF_DOUBLE){
64 //なにもしない
65 }
66 else if(type==DEF_SINGLE){
67 //Single型
68
69 //cvtss2sd
70 op_cvtss2sd(xmm_reg,xmm_reg);
71 }
72 else if(Is64Type(type)){
73 //64ビット整数型
74
75 //cvtsi2sd xmm_reg,reg
76 op_cvtsi2sd_reg(sizeof(_int64),xmm_reg,general_reg);
77
78 if(type==DEF_QWORD){
79 //符号なし
80
81 //test reg,reg
82 op_test(general_reg,general_reg);
83
84 //jge 9
85 OpBuffer[obp++]=(char)0x7D;
86 OpBuffer[obp++]=(char)0x09;
87
88 //addsd xmm_reg,qword ptr[offset] ※offset value:43f0000000000000
89 int temp;
90 _int64 i64data=0x43f0000000000000;
91 temp=compiler.GetNativeCode().GetDataTable().Add( i64data );
92 OpBuffer[obp++]=(char)0xF2;
93 OpBuffer[obp++]=(char)0x0F;
94 OpBuffer[obp++]=(char)0x58;
95 OpBuffer[obp++]=(char)(0x04 | REGISTER_OPERAND(xmm_reg)<<3);
96 OpBuffer[obp++]=(char)0x25;
97 *((long *)(OpBuffer+obp))=temp;
98 pobj_DataTableSchedule->add();
99 obp+=sizeof(long);
100 }
101 }
102 else if(type==DEF_DWORD){
103 //符号なし32ビット値
104
105 //64ビットにレジスタ値を拡張
106 ExtendTypeTo64(type,general_reg);
107
108 //cvtsi2sd xmm_reg,reg
109 op_cvtsi2sd_reg(sizeof(_int64),xmm_reg,general_reg);
110 }
111 else{
112 //その他整数
113
114 //32ビットにレジスタ値を拡張
115 ExtendTypeTo32(type,general_reg);
116
117 //cvtsi2sd xmm_reg,reg
118 op_cvtsi2sd_reg(sizeof(long),xmm_reg,general_reg);
119 }
120}
121void ChangeTypeToXmm_Single(int type,int xmm_reg,int general_reg){
122 if(type==DEF_DOUBLE){
123 //Double型
124
125 //cvtsd2ss
126 op_cvtsd2ss(xmm_reg,xmm_reg);
127 }
128 else if(type==DEF_SINGLE){
129 //なにもしない
130 }
131 else if(Is64Type(type)){
132 //64ビット整数型
133
134 //cvtsi2ss xmm_reg,reg
135 op_cvtsi2ss_reg(sizeof(_int64),xmm_reg,general_reg);
136
137 if(type==DEF_QWORD){
138 //符号なし
139
140 //test reg,reg
141 op_test(general_reg,general_reg);
142
143 //jge 9
144 OpBuffer[obp++]=(char)0x7D;
145 OpBuffer[obp++]=(char)0x09;
146
147 //addss xmm_reg,dword ptr[offset] ※offset value:5f800000
148 int temp;
149 long i32data=0x5f800000;
150 temp=compiler.GetNativeCode().GetDataTable().Add( i32data );
151 OpBuffer[obp++]=(char)0xF3;
152 OpBuffer[obp++]=(char)0x0F;
153 OpBuffer[obp++]=(char)0x58;
154 OpBuffer[obp++]=(char)(0x04 | REGISTER_OPERAND(xmm_reg)<<3);
155 OpBuffer[obp++]=(char)0x25;
156 *((long *)(OpBuffer+obp))=temp;
157 pobj_DataTableSchedule->add();
158 obp+=sizeof(long);
159 }
160 }
161 else if(type==DEF_DWORD){
162 //符号なし32ビット値
163
164 //64ビットにレジスタ値を拡張
165 ExtendTypeTo64(type,general_reg);
166
167 //cvtsi2ss xmm_reg,reg
168 op_cvtsi2ss_reg(sizeof(_int64),xmm_reg,general_reg);
169 }
170 else{
171 //その他整数
172
173 //32ビットにレジスタ値を拡張
174 ExtendTypeTo32(type,general_reg);
175
176 //cvtsi2ss xmm_reg,reg
177 op_cvtsi2ss_reg(sizeof(long),xmm_reg,general_reg);
178 }
179}
180
181void ChangeTypeToWhole(int OldType,int NewType,int reg,int xmm_reg){
182 if(OldType==DEF_DOUBLE){
183 if(Is64Type(NewType)){
184 //cvttsd2si reg,xmm_reg
185 op_cvttsd2si_xmm(sizeof(_int64),reg,xmm_reg);
186 }
187 else{
188 //cvttsd2si reg,xmm_reg
189 op_cvttsd2si_xmm(sizeof(long),reg,xmm_reg);
190 }
191 }
192 else if(OldType==DEF_SINGLE){
193 if(Is64Type(NewType)){
194 //cvttss2si reg,xmm_reg
195 op_cvttss2si_xmm(sizeof(_int64),reg,xmm_reg);
196 }
197 else{
198 //cvttss2si reg,xmm_reg
199 op_cvttss2si_xmm(sizeof(long),reg,xmm_reg);
200 }
201 }
202 else{
203 //整数から整数へ変換
204
205 if(Is64Type(NewType)){
206 ExtendTypeTo64(OldType,reg);
207 }
208 else if(GetTypeSize(NewType,-1)==sizeof(long)){
209 ExtendTypeTo32(OldType,reg);
210 }
211 else if(GetTypeSize(NewType,-1)==sizeof(short)){
212 ExtendTypeTo16(OldType,reg);
213 }
214 }
215}
216
217
218
219/////////////////////////////////////////
220// 1つの項を適切なレジスタへセット
221/////////////////////////////////////////
222
223void SetOneTermToReg_RealCalc(int TermType,int *pXmmReg){
224 int xmm_reg;
225
226 if(IsRealNumberType(TermType)){
227 //実数型
228 xmm_reg=pobj_reg->GetLockingXmmReg();
229
230 if(xmm_reg==REG_XMM4){
231 if(TermType==DEF_DOUBLE){
232 //movlpd xmm4,qword ptr[rsp+offset] ※スタックフレームを利用
233 pobj_sf->pop(xmm_reg,sizeof(double));
234 }
235 if(TermType==DEF_SINGLE){
236 //movss xmm4,dword ptr[rsp+offset] ※スタックフレームを利用
237 pobj_sf->pop(xmm_reg,sizeof(float));
238 }
239 }
240 }
241 else{
242 SetError(300,NULL,cp);
243 }
244
245 *pXmmReg=xmm_reg;
246}
247void SetOneTermToReg_Whole64Calc(int TermType,int *pReg){
248 //1つの項を適切なレジスタへセット(64ビット整数演算用)
249 int reg;
250
251 reg=pobj_reg->GetLockingReg();
252
253 if(reg==REG_R14){
254 //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用
255 pobj_sf->pop(REG_R14);
256 }
257
258 //レジスタ値を64ビットに拡張
259 ExtendTypeTo64(TermType,reg);
260
261 *pReg=reg;
262}
263void SetOneTermToReg_Whole32Calc(int TermType,int *pReg){
264 //1つの項を適切なレジスタへセット(32ビット整数演算用)
265 int reg;
266
267 reg=pobj_reg->GetLockingReg();
268
269 if(reg==REG_R14){
270 //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用
271 pobj_sf->pop(REG_R14);
272 }
273
274 //レジスタ値を32ビットに拡張
275 ExtendTypeTo32(TermType,reg);
276
277 *pReg=reg;
278}
279
280
281
282/////////////////////////////////////////
283// 2つの項を適切なレジスタへセット
284/////////////////////////////////////////
285
286void SetTowTermToReg_RealCalc(int AnswerType,int *type,int sp,int *pXmmReg1,int *pXmmReg2){
287 //2つの項を適切なレジスタへセット(Double演算用)
288 int xmm_reg1,xmm_reg2,temp_reg;
289
290
291 ///////////////////
292 // 第2項
293 ///////////////////
294
295 if(IsRealNumberType(type[sp-1])){
296 //実数型
297 xmm_reg2=pobj_reg->UnlockXmmReg();
298
299 if(xmm_reg2==REG_XMM4){
300 xmm_reg2=REG_XMM5;
301
302 if(type[sp-1]==DEF_DOUBLE){
303 //movlpd xmm5,qword ptr[rsp+offset] ※スタックフレームを利用
304 pobj_sf->pop(xmm_reg2,sizeof(double));
305 }
306 if(type[sp-1]==DEF_SINGLE){
307 //movss xmm5,dword ptr[rsp+offset] ※スタックフレームを利用
308 pobj_sf->pop(xmm_reg2,sizeof(float));
309 }
310 }
311 else{
312 if(!IsRealNumberType(type[sp-2])){
313 if(type[sp-1]==DEF_DOUBLE){
314 //movsd xmm5,xmm_reg
315 OpBuffer[obp++]=(char)0xF2;
316 OpBuffer[obp++]=(char)0x0F;
317 OpBuffer[obp++]=(char)0x10;
318 OpBuffer[obp++]=(char)(0xE8 | REGISTER_OPERAND(xmm_reg2));
319 }
320 if(type[sp-1]==DEF_SINGLE){
321 //movss xmm5,xmm_reg
322 OpBuffer[obp++]=(char)0xF3;
323 OpBuffer[obp++]=(char)0x0F;
324 OpBuffer[obp++]=(char)0x10;
325 OpBuffer[obp++]=(char)(0xE8 | REGISTER_OPERAND(xmm_reg2));
326 }
327
328 xmm_reg2=REG_XMM5;
329 }
330 }
331 }
332 else{
333 //整数値
334
335 temp_reg=pobj_reg->UnlockReg();
336
337 if(temp_reg==REG_R14){
338 //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用
339 pobj_sf->pop(REG_R14);
340 }
341
342 xmm_reg2=REG_XMM5;
343 }
344
345 //汎用レジスタ(temp_reg)をXMMレジスタ(xmm_reg2)にコピー
346 if(AnswerType==DEF_DOUBLE)
347 ChangeTypeToXmm_Double(type[sp-1],xmm_reg2,temp_reg);
348 if(AnswerType==DEF_SINGLE)
349 ChangeTypeToXmm_Single(type[sp-1],xmm_reg2,temp_reg);
350
351
352 ///////////////////
353 // 第1項
354 ///////////////////
355
356 if(IsRealNumberType(type[sp-2])){
357 //実数
358 xmm_reg1=pobj_reg->GetLockingXmmReg();
359
360 if(xmm_reg1==REG_XMM4){
361 if(type[sp-2]==DEF_DOUBLE){
362 //movlpd xmm4,qword ptr[rsp+offset] ※スタックフレームを利用
363 pobj_sf->pop(xmm_reg1,sizeof(double));
364 }
365 if(type[sp-2]==DEF_SINGLE){
366 //movss xmm4,dword ptr[rsp+offset] ※スタックフレームを利用
367 pobj_sf->pop(xmm_reg1,sizeof(float));
368 }
369 }
370 }
371 else{
372 //整数
373
374 temp_reg=pobj_reg->UnlockReg();
375
376 if(temp_reg==REG_R14){
377 //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用
378 pobj_sf->pop(REG_R14);
379 }
380
381 xmm_reg1=pobj_reg->LockXmmReg();
382 }
383
384 //汎用レジスタ(temp_reg)をXMMレジスタ(xmm_reg1)にコピー
385 if(AnswerType==DEF_DOUBLE)
386 ChangeTypeToXmm_Double(type[sp-2],xmm_reg1,temp_reg);
387 if(AnswerType==DEF_SINGLE)
388 ChangeTypeToXmm_Single(type[sp-2],xmm_reg1,temp_reg);
389
390
391 *pXmmReg1=xmm_reg1;
392 *pXmmReg2=xmm_reg2;
393}
394void SetTowTermToReg_Whole64Calc(int *type,int sp,int *pReg1,int *pReg2){
395 //2つの項を適切なレジスタへセット(64ビット整数演算用)
396 int reg1,reg2;
397
398 //////////////////
399 // 第2項
400 //////////////////
401 reg2=pobj_reg->UnlockReg();
402
403 if(reg2==REG_R14){
404 //mov r15,qword ptr[rsp+offset] ※スタックフレームを利用
405 pobj_sf->pop(REG_R15);
406
407 reg2=REG_R15;
408 }
409
410 //レジスタ値を64ビットに拡張
411 ExtendTypeTo64(type[sp-1],reg2);
412
413
414 //////////////////
415 // 第1項
416 //////////////////
417 reg1=pobj_reg->GetLockingReg();
418
419 if(reg1==REG_R14){
420 //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用
421 pobj_sf->pop(REG_R14);
422 }
423
424 //レジスタ値を64ビットに拡張
425 ExtendTypeTo64(type[sp-2],reg1);
426
427
428 *pReg1=reg1;
429 *pReg2=reg2;
430}
431void SetTowTermToReg_Whole32Calc(int *type,int sp,int *pReg1,int *pReg2){
432 //2つの項を適切なレジスタへセット(32ビット整数演算用)
433 int reg1,reg2;
434
435 //////////////////
436 // 第2項
437 //////////////////
438 reg2=pobj_reg->UnlockReg();
439
440 if(reg2==REG_R14){
441 //mov r15,qword ptr[rsp+offset] ※スタックフレームを利用
442 pobj_sf->pop(REG_R15);
443
444 reg2=REG_R15;
445 }
446
447 //レジスタ値を32ビットに拡張
448 ExtendTypeTo32(type[sp-1],reg2);
449
450
451 //////////////////
452 // 第1項
453 //////////////////
454 reg1=pobj_reg->GetLockingReg();
455
456 if(reg1==REG_R14){
457 //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用
458 pobj_sf->pop(REG_R14);
459 }
460
461 //レジスタ値を32ビットに拡張
462 ExtendTypeTo32(type[sp-2],reg1);
463
464
465 *pReg1=reg1;
466 *pReg2=reg2;
467}
468
469
470
471////////////////////////////
472// As 演算子によるキャスト
473////////////////////////////
474
475BOOL Calc_Cast(int *type,LONG_PTR *index_stack,int *pStackPointer){
476 //キャスト
477
478 int sp;
479 sp=*pStackPointer;
480
481 int CastType;
482 CastType=type[sp-1];
483 if((CastType&FLAG_CAST)==0){
484 SetError(47,NULL,cp);
485 return 0;
486 }
487 CastType=CastType&(~FLAG_CAST);
488
489 int xmm_reg,reg;
490
491 if(IsRealNumberType(CastType)){
492 //実数型へキャスト
493
494 if(IsRealNumberType(type[sp-2])){
495 SetOneTermToReg_RealCalc(type[sp-2],&xmm_reg);
496 }
497 else{
498 if(Is64Type(type[sp-2]))
499 SetOneTermToReg_Whole64Calc(type[sp-2],&reg);
500 else if(IsWholeNumberType(type[sp-2]))
501 SetOneTermToReg_Whole32Calc(type[sp-2],&reg);
502
503 pobj_reg->UnlockReg();
504
505 xmm_reg=pobj_reg->LockXmmReg();
506 }
507
508 if(CastType==DEF_DOUBLE){
509 //Double型にデータ変換
510 ChangeTypeToXmm_Double(type[sp-2],xmm_reg,reg);
511 }
512 else if(CastType==DEF_SINGLE){
513 //Single型にデータ変換
514 ChangeTypeToXmm_Single(type[sp-2],xmm_reg,reg);
515 }
516
517 if(xmm_reg==REG_XMM4){
518 //movsd qword ptr[rsp+offset],xmm4 ※スタックフレームを利用
519 pobj_sf->push(REG_XMM4,sizeof(double));
520 }
521 }
522 else{
523 //その他整数型へ変換
524
525 if(IsRealNumberType(type[sp-2])){
526 SetOneTermToReg_RealCalc(type[sp-2],&xmm_reg);
527
528 pobj_reg->UnlockXmmReg();
529
530 reg=pobj_reg->LockReg();
531
532 //整数型へデータ変換
533 ChangeTypeToWhole(type[sp-2],CastType,reg,xmm_reg);
534
535 if(reg==REG_R14){
536 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
537 pobj_sf->push(REG_R14);
538 }
539 }
540 else{
541 reg=pobj_reg->GetLockingReg();
542
543 if(reg==REG_R14){
544 //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用
545 pobj_sf->pop(REG_R14);
546 }
547
548 //整数型へデータ変換
549 ChangeTypeToWhole(type[sp-2],CastType,reg,0);
550
551 if(reg==REG_R14){
552 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
553 pobj_sf->push(REG_R14);
554 }
555 }
556 }
557
558 type[sp-2]=CastType;
559 index_stack[sp-2]=index_stack[sp-1];
560
561 sp--;
562
563 *pStackPointer=sp;
564 return 1;
565}
Note: See TracBrowser for help on using the repository browser.