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

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

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

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