source: dev/trunk/ab5.0/abdev/compiler_x64/NumOpe_TypeOperation.cpp@ 829

Last change on this file since 829 was 829, checked in by イグトランス (egtra), 12 years ago

svn:eol-styleとsvn:mime-type(文字コード指定含む)の設定

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