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

Last change on this file since 228 was 228, 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(int type,int reg){
11 if(type==DEF_LONG){
12 //movsxd reg64,reg32
13 compiler.codeGenerator.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 compiler.codeGenerator.op_movsx64_FromReg16(reg,reg);
21 }
22 else if(type==DEF_WORD){
23 //and reg,000000000000FFFFh
24 compiler.codeGenerator.op_and64_value(reg,(int)0xFFFF);
25 }
26 else if(type==DEF_SBYTE || (Smoothie::IsUnicode()==false&&type==DEF_CHAR)){
27 //movsx reg64,reg8
28 compiler.codeGenerator.op_movsx64_FromReg8(reg,reg);
29 }
30 else if(type==DEF_BYTE || type==DEF_BOOLEAN){
31 //and reg,00000000000000FFh
32 compiler.codeGenerator.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 compiler.codeGenerator.op_movsx32_FromReg16(reg,reg);
39 }
40 else if(type==DEF_WORD){
41 //and reg,0000FFFFh
42 compiler.codeGenerator.op_and32_value(reg,(int)0xFFFF);
43 }
44 else if(type==DEF_SBYTE || (Smoothie::IsUnicode()==false&&type==DEF_CHAR)){
45 //movsx reg32,reg8
46 compiler.codeGenerator.op_movsx32_FromReg8(reg,reg);
47 }
48 else if(type==DEF_BYTE || type==DEF_BOOLEAN){
49 //and reg,000000FFh
50 compiler.codeGenerator.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 compiler.codeGenerator.op_movsx16_FromReg8(reg,reg);
57 }
58 else if(type==DEF_BYTE){
59 //and reg,000000FFh
60 compiler.codeGenerator.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 compiler.codeGenerator.op_cvtss2sd(xmm_reg,xmm_reg);
73 }
74 else if(Is64Type(type)){
75 //64ビット整数型
76
77 //cvtsi2sd xmm_reg,reg
78 compiler.codeGenerator.op_cvtsi2sd_reg(sizeof(_int64),xmm_reg,general_reg);
79
80 if(type==DEF_QWORD){
81 //符号なし
82
83 //test reg,reg
84 compiler.codeGenerator.op_test(general_reg,general_reg);
85
86 //jge 9
87 compiler.codeGenerator.op_jge( 9 );
88
89 //addsd xmm_reg,qword ptr[offset] ※offset value:43f0000000000000
90 int temp;
91 _int64 i64data=0x43f0000000000000;
92 temp=compiler.GetDataTable().Add( i64data );
93 OpBuffer[obp++]=(char)0xF2;
94 OpBuffer[obp++]=(char)0x0F;
95 OpBuffer[obp++]=(char)0x58;
96 OpBuffer[obp++]=(char)(0x04 | REGISTER_OPERAND(xmm_reg)<<3);
97 OpBuffer[obp++]=(char)0x25;
98 *((long *)(OpBuffer+obp))=temp;
99 pobj_DataTableSchedule->add();
100 obp+=sizeof(long);
101 }
102 }
103 else if(type==DEF_DWORD){
104 //符号なし32ビット値
105
106 //64ビットにレジスタ値を拡張
107 ExtendTypeTo64(type,general_reg);
108
109 //cvtsi2sd xmm_reg,reg
110 compiler.codeGenerator.op_cvtsi2sd_reg(sizeof(_int64),xmm_reg,general_reg);
111 }
112 else{
113 //その他整数
114
115 //32ビットにレジスタ値を拡張
116 ExtendTypeTo32(type,general_reg);
117
118 //cvtsi2sd xmm_reg,reg
119 compiler.codeGenerator.op_cvtsi2sd_reg(sizeof(long),xmm_reg,general_reg);
120 }
121}
122void ChangeTypeToXmm_Single(int type,int xmm_reg,int general_reg){
123 if(type==DEF_DOUBLE){
124 //Double型
125
126 //cvtsd2ss
127 compiler.codeGenerator.op_cvtsd2ss(xmm_reg,xmm_reg);
128 }
129 else if(type==DEF_SINGLE){
130 //なにもしない
131 }
132 else if(Is64Type(type)){
133 //64ビット整数型
134
135 //cvtsi2ss xmm_reg,reg
136 compiler.codeGenerator.op_cvtsi2ss_reg(sizeof(_int64),xmm_reg,general_reg);
137
138 if(type==DEF_QWORD){
139 //符号なし
140
141 //test reg,reg
142 compiler.codeGenerator.op_test(general_reg,general_reg);
143
144 //jge 9
145 compiler.codeGenerator.op_jge( 9 );
146
147 //addss xmm_reg,dword ptr[offset] ※offset value:5f800000
148 int temp;
149 long i32data=0x5f800000;
150 temp=compiler.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 compiler.codeGenerator.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 compiler.codeGenerator.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 compiler.codeGenerator.op_cvttsd2si_xmm(sizeof(_int64),reg,xmm_reg);
186 }
187 else{
188 //cvttsd2si reg,xmm_reg
189 compiler.codeGenerator.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 compiler.codeGenerator.op_cvttss2si_xmm(sizeof(_int64),reg,xmm_reg);
196 }
197 else{
198 //cvttss2si reg,xmm_reg
199 compiler.codeGenerator.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 compiler.codeGenerator.op_movsd_RR( REG_XMM5, xmm_reg2 );
316 }
317 if(type[sp-1]==DEF_SINGLE){
318 //movss xmm5,xmm_reg
319 compiler.codeGenerator.op_movss_RR( REG_XMM5, xmm_reg2 );
320 }
321
322 xmm_reg2=REG_XMM5;
323 }
324 }
325 }
326 else{
327 //整数値
328
329 temp_reg=pobj_reg->UnlockReg();
330
331 if(temp_reg==REG_R14){
332 //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用
333 pobj_sf->pop(REG_R14);
334 }
335
336 xmm_reg2=REG_XMM5;
337 }
338
339 //汎用レジスタ(temp_reg)をXMMレジスタ(xmm_reg2)にコピー
340 if(AnswerType==DEF_DOUBLE)
341 ChangeTypeToXmm_Double(type[sp-1],xmm_reg2,temp_reg);
342 if(AnswerType==DEF_SINGLE)
343 ChangeTypeToXmm_Single(type[sp-1],xmm_reg2,temp_reg);
344
345
346 ///////////////////
347 // 第1項
348 ///////////////////
349
350 if(IsRealNumberType(type[sp-2])){
351 //実数
352 xmm_reg1=pobj_reg->GetLockingXmmReg();
353
354 if(xmm_reg1==REG_XMM4){
355 if(type[sp-2]==DEF_DOUBLE){
356 //movlpd xmm4,qword ptr[rsp+offset] ※スタックフレームを利用
357 pobj_sf->pop(xmm_reg1,sizeof(double));
358 }
359 if(type[sp-2]==DEF_SINGLE){
360 //movss xmm4,dword ptr[rsp+offset] ※スタックフレームを利用
361 pobj_sf->pop(xmm_reg1,sizeof(float));
362 }
363 }
364 }
365 else{
366 //整数
367
368 temp_reg=pobj_reg->UnlockReg();
369
370 if(temp_reg==REG_R14){
371 //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用
372 pobj_sf->pop(REG_R14);
373 }
374
375 xmm_reg1=pobj_reg->LockXmmReg();
376 }
377
378 //汎用レジスタ(temp_reg)をXMMレジスタ(xmm_reg1)にコピー
379 if(AnswerType==DEF_DOUBLE)
380 ChangeTypeToXmm_Double(type[sp-2],xmm_reg1,temp_reg);
381 if(AnswerType==DEF_SINGLE)
382 ChangeTypeToXmm_Single(type[sp-2],xmm_reg1,temp_reg);
383
384
385 *pXmmReg1=xmm_reg1;
386 *pXmmReg2=xmm_reg2;
387}
388void SetTowTermToReg_Whole64Calc(int *type,int sp,int *pReg1,int *pReg2){
389 //2つの項を適切なレジスタへセット(64ビット整数演算用)
390 int reg1,reg2;
391
392 //////////////////
393 // 第2項
394 //////////////////
395 reg2=pobj_reg->UnlockReg();
396
397 if(reg2==REG_R14){
398 //mov r15,qword ptr[rsp+offset] ※スタックフレームを利用
399 pobj_sf->pop(REG_R15);
400
401 reg2=REG_R15;
402 }
403
404 //レジスタ値を64ビットに拡張
405 ExtendTypeTo64(type[sp-1],reg2);
406
407
408 //////////////////
409 // 第1項
410 //////////////////
411 reg1=pobj_reg->GetLockingReg();
412
413 if(reg1==REG_R14){
414 //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用
415 pobj_sf->pop(REG_R14);
416 }
417
418 //レジスタ値を64ビットに拡張
419 ExtendTypeTo64(type[sp-2],reg1);
420
421
422 *pReg1=reg1;
423 *pReg2=reg2;
424}
425void SetTowTermToReg_Whole32Calc(int *type,int sp,int *pReg1,int *pReg2){
426 //2つの項を適切なレジスタへセット(32ビット整数演算用)
427 int reg1,reg2;
428
429 //////////////////
430 // 第2項
431 //////////////////
432 reg2=pobj_reg->UnlockReg();
433
434 if(reg2==REG_R14){
435 //mov r15,qword ptr[rsp+offset] ※スタックフレームを利用
436 pobj_sf->pop(REG_R15);
437
438 reg2=REG_R15;
439 }
440
441 //レジスタ値を32ビットに拡張
442 ExtendTypeTo32(type[sp-1],reg2);
443
444
445 //////////////////
446 // 第1項
447 //////////////////
448 reg1=pobj_reg->GetLockingReg();
449
450 if(reg1==REG_R14){
451 //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用
452 pobj_sf->pop(REG_R14);
453 }
454
455 //レジスタ値を32ビットに拡張
456 ExtendTypeTo32(type[sp-2],reg1);
457
458
459 *pReg1=reg1;
460 *pReg2=reg2;
461}
462
463
464
465////////////////////////////
466// As 演算子によるキャスト
467////////////////////////////
468
469BOOL Calc_Cast(int *type,LONG_PTR *index_stack,int *pStackPointer){
470 //キャスト
471
472 int sp;
473 sp=*pStackPointer;
474
475 int CastType;
476 CastType=type[sp-1];
477 if((CastType&FLAG_CAST)==0){
478 SetError(47,NULL,cp);
479 return 0;
480 }
481 CastType=CastType&(~FLAG_CAST);
482
483 int xmm_reg,reg;
484
485 if(IsRealNumberType(CastType)){
486 //実数型へキャスト
487
488 if(IsRealNumberType(type[sp-2])){
489 SetOneTermToReg_RealCalc(type[sp-2],&xmm_reg);
490 }
491 else{
492 if(Is64Type(type[sp-2]))
493 SetOneTermToReg_Whole64Calc(type[sp-2],&reg);
494 else if(IsWholeNumberType(type[sp-2]))
495 SetOneTermToReg_Whole32Calc(type[sp-2],&reg);
496
497 pobj_reg->UnlockReg();
498
499 xmm_reg=pobj_reg->LockXmmReg();
500 }
501
502 if(CastType==DEF_DOUBLE){
503 //Double型にデータ変換
504 ChangeTypeToXmm_Double(type[sp-2],xmm_reg,reg);
505 }
506 else if(CastType==DEF_SINGLE){
507 //Single型にデータ変換
508 ChangeTypeToXmm_Single(type[sp-2],xmm_reg,reg);
509 }
510
511 if(xmm_reg==REG_XMM4){
512 //movsd qword ptr[rsp+offset],xmm4 ※スタックフレームを利用
513 pobj_sf->push(REG_XMM4,sizeof(double));
514 }
515 }
516 else{
517 //その他整数型へ変換
518
519 if(IsRealNumberType(type[sp-2])){
520 SetOneTermToReg_RealCalc(type[sp-2],&xmm_reg);
521
522 pobj_reg->UnlockXmmReg();
523
524 reg=pobj_reg->LockReg();
525
526 //整数型へデータ変換
527 ChangeTypeToWhole(type[sp-2],CastType,reg,xmm_reg);
528
529 if(reg==REG_R14){
530 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
531 pobj_sf->push(REG_R14);
532 }
533 }
534 else{
535 reg=pobj_reg->GetLockingReg();
536
537 if(reg==REG_R14){
538 //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用
539 pobj_sf->pop(REG_R14);
540 }
541
542 //整数型へデータ変換
543 ChangeTypeToWhole(type[sp-2],CastType,reg,0);
544
545 if(reg==REG_R14){
546 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
547 pobj_sf->push(REG_R14);
548 }
549 }
550 }
551
552 type[sp-2]=CastType;
553 index_stack[sp-2]=index_stack[sp-1];
554
555 sp--;
556
557 *pStackPointer=sp;
558 return 1;
559}
Note: See TracBrowser for help on using the repository browser.