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

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

静的リンクライブラリにより、複数のグローバル領域が存在することになったのでそれぞれを関数ベースに分けた

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