source: dev/BasicCompiler64/NumOpe.cpp@ 76

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

TYPEINFO→Typeへのリファクタリングを実施。32bitが未完成。

File size: 22.7 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "Opcode.h"
3
4void NewStringObject(int reg, const char *str){
5 ///////////////////////////////////////////////////////
6 // lpszTextを元にStringオブジェクトを生成し、
7 // オブジェクトポインタをregに格納する
8 ///////////////////////////////////////////////////////
9
10
11 //////////////////////////////////////////////////////
12 ///// レジスタ資源のバックアップ
13 { BACKUP_REGISTER_RESOURCE
14 //////////////////////////////////////////////////////
15
16 char *parameter = (char *)malloc( lstrlen( str ) + 32 );
17 sprintf( parameter, "\"%s\"%c%c*Char", str, 1, ESC_AS );
18 SetStringQuotes( parameter );
19
20 extern CClass *pobj_StringClass;
21 Operator_New( *pobj_StringClass, "", parameter, Type( DEF_OBJECT, *pobj_StringClass ) );
22
23 free( parameter );
24
25 //mov reg,rax
26 op_mov_RR( reg, REG_RAX );
27
28 /////////////////////////////////////////////
29 ////// レジスタ資源を復元
30 RESTORE_REGISTER_RESOURCE
31 }////////////////////////////////////////////
32}
33
34void SetUseRegFromRax(int type,int UseReg,int XmmReg){
35 if(IsRealNumberType(type)){
36 //実数型
37 if(XmmReg==REG_XMM4){
38 if(type==DEF_DOUBLE){
39 //movsd qword ptr[rsp+offset],xmm0 ※スタックフレームを利用
40 pobj_sf->push(REG_XMM0,sizeof(double));
41 }
42 if(type==DEF_SINGLE){
43 //movss dword ptr[rsp+offset],xmm0 ※スタックフレームを利用
44 pobj_sf->push(REG_XMM0,sizeof(float));
45 }
46 }
47 else{
48 if(type==DEF_DOUBLE){
49 //movsd xmm_reg,xmm0
50 op_movsd_RR(XmmReg,REG_XMM0);
51 }
52 else if(type==DEF_SINGLE){
53 //movss xmm_reg,xmm0
54 op_movss_RR(XmmReg,REG_XMM0);
55 }
56 }
57 }
58 else{
59 //整数型
60 if(UseReg==REG_R14){
61 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
62 pobj_sf->push(REG_RAX);
63 }
64 else{
65 //mov reg,rax
66 op_mov_RR(UseReg,REG_RAX);
67 }
68 }
69}
70
71void ExtendRegToBigType( int reg, int bigBasicType, int baseBasicType ){
72 switch( Type::GetBasicSize( bigBasicType ) ){
73 case sizeof(_int64):
74 ExtendTypeTo64(baseBasicType,reg);
75 break;
76 case sizeof(long):
77 ExtendTypeTo32(baseBasicType,reg);
78 break;
79 case sizeof(short):
80 ExtendTypeTo16(baseBasicType,reg);
81 break;
82 }
83}
84
85bool NumOpe( int *pReg,
86 const char *expression,
87 const Type &baseType,
88 Type &resultType,
89 BOOL *pbUseHeap ){
90
91 int i,i2,i3,i4;
92 char temporary[1024],temp2[1024],temp3[1024];
93
94 if(expression[0]=='\0'){
95 SetError(1,NULL,cp);
96 return false;
97 }
98
99 if(expression[0]==1&& expression[1]==ESC_NEW ){
100 //New演算子(オブジェクト生成)
101
102 if( !Operator_New( expression+2, baseType, resultType ) ){
103 return false;
104 }
105
106 //mov reg,rax
107 op_mov_RR( *pReg, REG_RAX );
108
109 return true;
110 }
111
112
113 /////////////////////////////////
114 // 式要素を逆ポーランド式で取得
115 /////////////////////////////////
116
117 char *values[255];
118 long calc[255];
119 long stack[255];
120 int pnum;
121 if(!GetNumOpeElements(expression,&pnum,values,calc,stack)){
122 for(i=0;i<pnum;i++){
123 if(values[i]) HeapDefaultFree(values[i]);
124 }
125 return 0;
126 }
127
128
129 BOOL bInitRegSwitch=0;
130 if(!pobj_reg){
131 bInitRegSwitch=1;
132
133 //作業用レジスタを取得
134 pobj_reg=new CRegister(*pReg);
135 }
136
137 //エラー時の復旧用
138 CRegister objReg_Backup;
139 objReg_Backup=*pobj_reg;
140
141
142
143 ////////////////////////////////
144 // 演算部分のコード生成を開始
145 ////////////////////////////////
146
147 BOOL bError;
148 bError=0;
149
150 //リテラル値のみの計算かどうかを判別するためのフラグ
151 BOOL bLiteralCalculation=1;
152
153 //リテラル演算の場合を考慮した演算前のバッファ位置
154 int BeforeObp;
155 BeforeObp=obp;
156
157 //リテラル演算の場合を考慮した演算前のプロシージャスケジュール位置
158 //※64ビットの掛け算、除算などで特殊関数が呼ばれるため
159 int Before_ProcAddrScheduleNum;
160 Before_ProcAddrScheduleNum=pobj_SubAddrSchedule->num;
161
162 //リテラル演算の場合を考慮した演算前のデータテーブルスケジュール位置
163 int Before_DataTableScheduleNum;
164 Before_DataTableScheduleNum=pobj_DataTableSchedule->num;
165
166 //リテラル演算の場合を考慮した演算前の再配置スケジュール
167 CReloc *pobj_BackReloc;
168 pobj_BackReloc=new CReloc();
169 pobj_BackReloc->copy(pobj_Reloc);
170
171 //リテラル演算の場合を考慮した演算前のスタックフレームスケジュール位置
172 int Before_StackFrameScheduleNum;
173 Before_StackFrameScheduleNum=pobj_sf->num;
174
175 double dbl;
176 int sp;
177 int type_stack[255];
178 LONG_PTR index_stack[255];
179 BOOL bUseHeap[255];
180 _int64 i64data;
181 int UseReg,XmmReg;
182 BOOL bXmm;
183 for(i=0,sp=0;i<pnum;i++){
184 int idCalc;
185 idCalc=calc[i]%100;
186
187 if(idCalc){
188 if(type_stack[sp-2]==DEF_OBJECT){
189 //オーバーロードされたオペレータを呼び出す
190 i2=CallOperatorProc(idCalc,baseType,type_stack,index_stack,bUseHeap,sp);
191 if(i2==0){
192 if(idCalc==CALC_EQUAL) lstrcpy(temp2,"==");
193 else GetCalcName(idCalc,temp2);
194 sprintf(temporary,"Operator %s",temp2);
195 SetError(27,temporary,cp);
196 goto error;
197 }
198 else if(i2==-1) goto error;
199
200 continue;
201 }
202
203 if(!CheckCalcType(idCalc,type_stack,sp)) goto error;
204 }
205
206 switch(idCalc){
207 //数値
208 case 0:
209 index_stack[sp]=-1;
210 bUseHeap[sp]=0;
211
212 UseReg=pobj_reg->GetNextReg();
213 XmmReg=pobj_reg->GetNextXmmReg();
214
215 bXmm=0;
216
217 char *term;
218 term=values[i];
219
220 if(term[0]=='\"'){
221 //リテラル文字列
222 if(!RemoveStringQuotes(term)){
223 SetError(43,NULL,cp);
224 goto error;
225 }
226 i3=lstrlen(term);
227StrLiteral:
228
229 if( baseType.IsObject() ){
230 if( baseType.IsStringObject() ){
231 //要求タイプがStringのとき
232
233 //String型オブジェクトを生成
234 NewStringObject(UseReg,term);
235
236 extern CClass *pobj_StringClass;
237 type_stack[sp]=DEF_OBJECT;
238 index_stack[sp]=(LONG_PTR)pobj_StringClass;
239 bLiteralCalculation=0;
240
241 if(bXmm) pobj_reg->LockXmmReg();
242 else pobj_reg->LockReg();
243
244 sp++;
245 break;
246 }
247 }
248
249 type_stack[sp]=typeOfPtrChar;
250 bLiteralCalculation=0;
251
252 i2 = dataTable.AddString( term, i3 );
253
254 //mov reg,i2
255 op_mov_RV(sizeof(_int64),UseReg,i2);
256 obp-=sizeof(long);
257 pobj_DataTableSchedule->add();
258 obp+=sizeof(long);
259
260 if(UseReg==REG_R14){
261 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
262 pobj_sf->push(REG_R14);
263 }
264 }
265 else if((term[0]=='e'||term[0]=='E')&&
266 (term[1]=='x'||term[1]=='X')&&
267 term[2]=='\"'){
268 //拡張版リテラル文字列(エスケープシーケンス可能)
269 if(!RemoveStringQuotes(term+2)){
270 SetError(43,NULL,cp);
271 goto error;
272 }
273 i3=FormatString_EscapeSequence(term+2);
274 term+=2;
275
276 goto StrLiteral;
277 }
278 else if(IsVariableTopChar(term[0])||
279 term[0]=='*'||
280 (term[0]=='.'&&IsVariableTopChar(term[1]))){
281 //////////////////
282 // 何らかの識別子
283
284 //////////////////////////////////////
285 // 関数(DLL、ユーザー定義、組み込み)
286 //////////////////////////////////////
287
288 i2=GetCallProcName(term,temporary);
289 if(term[i2]=='('){
290 i4=GetStringInPare_RemovePare(temp2,term+i2+1);
291
292 void *pInfo;
293 int idProc=GetProc(temporary,(void **)&pInfo);
294
295 Type resultType;
296 if(idProc){
297 //閉じカッコ")"に続く文字がNULLでないとき
298 if(term[i2+1+i4+1]!='\0'){
299 if( term[i2+1+i4+1] == '.'
300 || term[i2+1+i4+1] == 1 && term[i2+1+i4+2] == ESC_PSMEM ){
301 goto NonProc;
302 }
303 else{
304 SetError(42,NULL,cp);
305 }
306 }
307
308
309 //////////////////////////////////////////////////////
310 ///// レジスタ資源のバックアップ
311 { BACKUP_REGISTER_RESOURCE
312 //////////////////////////////////////////////////////
313
314
315 ////////////////
316 // 呼び出し
317 ////////////////
318
319 CallProc(idProc,pInfo,temporary,temp2,resultType);
320 if(resultType.IsNull()){
321 //戻り値が存在しないとき
322 for(i2=2;;i2++){
323 if(term[i2]=='('||term[i2]=='\0'){
324 term[i2]=0;
325 break;
326 }
327 }
328 SetError(38,term,cp);
329
330 //レジスタ資源を復元
331 RESTORE_REGISTER_RESOURCE
332
333 goto error;
334 }
335
336
337 /////////////////////
338 // 戻り値の処理
339 /////////////////////
340
341 //大きな型への暗黙の変換
342 type_stack[sp]=AutoBigCast(baseType.GetBasicType(),resultType.GetBasicType());
343 index_stack[sp] = resultType.GetIndex();
344 bLiteralCalculation=0;
345
346 if( type_stack[sp] != resultType.GetBasicType() ){
347 // 大きな型へ変換された場合
348 // ※レジスタの値をキャストする
349 ExtendRegToBigType( REG_RAX, type_stack[sp], resultType.GetBasicType() );
350 }
351
352 SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
353
354 if(resultType.IsReal()) bXmm=1;
355 else bXmm=0;
356
357 /////////////////////////////////////////////
358 ////// レジスタ資源を復元
359 RESTORE_REGISTER_RESOURCE
360 }////////////////////////////////////////////
361
362
363 if(bXmm) pobj_reg->LockXmmReg();
364 else pobj_reg->LockReg();
365
366 if(resultType.IsStruct()){
367 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
368 //※後にfreeする必要あり
369 bUseHeap[sp]=1;
370 }
371
372 sp++;
373 break;
374 }
375 else if(GetConstCalcBuffer(temporary,temp2,temp3)){
376 /////////////////////////
377 // マクロ関数
378 /////////////////////////
379
380 //閉じカッコ")"に続く文字がNULLでないときはエラーにする
381 if(term[i2+1+i4+1]!='\0') SetError(42,NULL,cp);
382
383 //マクロ関数の場合
384 NumOpe(&UseReg,temp3,Type(),resultType);
385
386 if(!IS_LITERAL(resultType.GetIndex())){
387 //リテラル値ではなかったとき
388 bLiteralCalculation=0;
389 }
390
391 type_stack[sp] = resultType.GetBasicType();
392 index_stack[sp] = resultType.GetIndex();
393
394 if(resultType.IsReal()) pobj_reg->LockXmmReg();
395 else pobj_reg->LockReg();
396
397 sp++;
398 break;
399 }
400 }
401NonProc:
402
403
404 //インデクサ(getアクセサ)
405 char variable[VN_SIZE],array_element[VN_SIZE];
406 GetArrayElement(term,variable,array_element);
407 if(array_element[0]){
408 Type resultType;
409 GetVarType(variable,resultType,0);
410 if( resultType.IsObject() ){
411 CallIndexerGetterProc(UseReg,&resultType.GetClass(),variable,array_element,resultType);
412 type_stack[sp]=resultType.GetBasicType();
413 index_stack[sp]=resultType.GetIndex();
414 bLiteralCalculation=0;
415
416 if(resultType.IsReal()) pobj_reg->LockXmmReg();
417 else pobj_reg->LockReg();
418 sp++;
419 break;
420 }
421 }
422
423
424 // Nothing
425 if( lstrcmp( term, "Nothing" ) == 0 ){
426 type_stack[sp] = DEF_OBJECT;
427 if( baseType.IsObject() ){
428 index_stack[sp] = baseType.GetIndex();
429 }
430 else{
431 index_stack[sp] = (LONG_PTR)pobj_DBClass->GetObjectClass();
432 }
433
434 bLiteralCalculation = 0;
435
436 //xor reg,reg
437 op_zero_reg( UseReg );
438
439 if(UseReg==REG_R14){
440 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
441 pobj_sf->push(REG_R14);
442 }
443
444 pobj_reg->LockReg();
445 sp++;
446 break;
447 }
448
449
450 RELATIVE_VAR RelativeVar;
451 Type varType;
452 if(GetVarOffset(
453 false, //エラー表示あり
454 false, //読み込み専用
455 term,
456 &RelativeVar,varType)){
457 //////////
458 // 変数
459 //////////
460
461 //大きな型への暗黙の変換
462 type_stack[sp]=AutoBigCast(baseType.GetBasicType(),varType.GetBasicType());
463 index_stack[sp] = varType.GetIndex();
464 bLiteralCalculation=0;
465
466 if(varType.GetBasicType()&FLAG_PTR){
467 //配列ポインタ
468 type_stack[sp]=GetPtrType(varType.GetBasicType()^FLAG_PTR);
469
470 SetVarPtrToReg(UseReg,&RelativeVar);
471 }
472 else if(varType.IsReal()){
473 //実数型
474 bXmm=1;
475
476 if( varType.IsDouble() )
477 SetXmmReg_DoubleVariable(&RelativeVar,XmmReg);
478 if( varType.IsSingle() )
479 SetXmmReg_SingleVariable(&RelativeVar,XmmReg);
480 }
481 else if( varType.IsWhole() || varType.IsObject()){
482 //整数型
483 SetReg_WholeVariable(varType.GetBasicType(),&RelativeVar,UseReg);
484 }
485 else if( varType.IsStruct() ){
486 //構造体ポインタをUseRegへ格納(構造体は値型)
487 SetVarPtrToReg(UseReg,&RelativeVar);
488 }
489 else SetError(11,term,cp);
490
491 if( type_stack[sp] != varType.GetBasicType() ){
492 // 大きな型へ変換された場合
493 // ※レジスタの値をキャストする
494 ExtendRegToBigType( UseReg, type_stack[sp], varType.GetBasicType() );
495 }
496
497 if(bXmm==0&&UseReg==REG_R14){
498 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
499 pobj_sf->push(REG_R14);
500 }
501 if(bXmm&&XmmReg==REG_XMM4){
502 if(varType.IsDouble()){
503 //movsd qword ptr[rsp+offset],xmm4 ※スタックフレームを利用
504 pobj_sf->push(REG_XMM4,sizeof(double));
505 }
506 if(varType.IsSingle()){
507 //movss dword ptr[rsp+offset],xmm4 ※スタックフレームを利用
508 pobj_sf->push(REG_XMM4,sizeof(float));
509 }
510 }
511
512 if(bXmm) pobj_reg->LockXmmReg();
513 else pobj_reg->LockReg();
514 sp++;
515 break;
516 }
517
518
519 //////////////
520 // 定数の場合
521 //////////////
522
523 i3 = CDBConst::obj.GetType(term);
524 if(i3){
525 type_stack[sp] = i3;
526 if(IsRealNumberType(i3)){
527 //実数
528 double dbl = CDBConst::obj.GetDoubleData(term);
529 memcpy(&i64data,&dbl,sizeof(double));
530 goto Literal;
531 }
532 else if(IsWholeNumberType(i3)){
533 //整数
534 i64data = CDBConst::obj.GetWholeData(term);
535 goto Literal;
536 }
537 /*else if(i3==DEF_STRING){
538 //リテラル文字列
539
540 //バイト数
541 i3=(int)dbl;
542
543 memcpy(term,temporary,i3);
544 goto StrLiteral;
545 }*/
546 else{
547 SetError(1,NULL,0);
548 goto error;
549 }
550 }
551
552
553 //////////////
554 // 型名の場合
555 //////////////
556
557 LONG_PTR lp;
558 i3=GetTypeFixed(term,&lp);
559 if(i3!=-1){
560 type_stack[sp]=i3|FLAG_CAST;
561 index_stack[sp]=lp;
562 sp++;
563 break;
564 }
565
566
567
568 /////////////////////////////////
569 // プロパティ用のメソッド
570 /////////////////////////////////
571
572 //配列要素を排除
573 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
574 GetArrayElement(term,VarName,ArrayElements);
575
576 if(GetSubHash(VarName,0)){
577
578 //////////////////////////////////////////////////////
579 ///// レジスタ資源のバックアップ
580 { BACKUP_REGISTER_RESOURCE
581 //////////////////////////////////////////////////////
582
583 Type resultType;
584 CallPropertyMethod(term,NULL,resultType);
585
586 //大きな型への暗黙の変換
587 type_stack[sp]=AutoBigCast(baseType.GetBasicType(),resultType.GetBasicType());
588 index_stack[sp]=resultType.GetIndex();
589 bLiteralCalculation=0;
590
591 if( type_stack[sp] != resultType.GetBasicType() ){
592 // 大きな型へ変換された場合
593 // ※レジスタの値をキャストする
594 ExtendRegToBigType( REG_RAX, type_stack[sp], resultType.GetBasicType() );
595 }
596
597 SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
598
599 if(IsRealNumberType(type_stack[sp])) bXmm=1;
600 else bXmm=0;
601
602 /////////////////////////////////////////////
603 ////// レジスタ資源を復元
604 RESTORE_REGISTER_RESOURCE
605 }////////////////////////////////////////////
606
607 if(type_stack[sp]==DEF_STRUCT){
608 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
609 //※後にfreeする必要あり
610 bUseHeap[sp]=1;
611 }
612
613 if(bXmm) pobj_reg->LockXmmReg();
614 else pobj_reg->LockReg();
615 sp++;
616 break;
617 }
618
619
620
621 //該当する識別子が見当たらないときはエラー扱いにする
622 bError=1;
623 SetError(3,term,cp);
624 type_stack[sp]=DEF_DOUBLE;
625 }
626 else{
627 //リテラル値
628 type_stack[sp]=GetLiteralValue(term,&i64data,baseType.GetBasicType());
629Literal:
630 if(type_stack[sp]==DEF_DOUBLE){
631 //64ビット浮動小数型
632 bXmm=1;
633
634 if(XmmReg==REG_XMM4){
635 //mov r14,i64data
636 op_mov64_ToReg(REG_R14,i64data);
637
638
639 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
640 pobj_sf->push(REG_R14);
641 }
642 else{
643 i3 = dataTable.Add( i64data );
644
645 //movlpd xmm_reg,qword ptr[data table offset]
646 OpBuffer[obp++]=(char)0x66;
647 OpBuffer[obp++]=(char)0x0F;
648 OpBuffer[obp++]=(char)0x12;
649 OpBuffer[obp++]=(char)(0x04 | REGISTER_OPERAND(XmmReg)<<3);
650 OpBuffer[obp++]=(char)0x25;
651 *((long *)(OpBuffer+obp))=i3;
652 pobj_DataTableSchedule->add();
653 obp+=sizeof(long);
654 }
655 }
656 else if(type_stack[sp]==DEF_SINGLE){
657 //32ビット浮動小数型
658 bXmm=1;
659
660 float flt;
661 int i32data;
662 memcpy(&dbl,&i64data,sizeof(double));
663 flt=(float)dbl;
664 memcpy(&i32data,&flt,sizeof(long));
665
666 if(XmmReg==REG_XMM4){
667 //push term
668 op_push_value(i32data);
669 }
670 else{
671 i3=dataTable.Add( i32data );
672
673 //movss xmm_reg,dword ptr[data table offset]
674 OpBuffer[obp++]=(char)0xF3;
675 OpBuffer[obp++]=(char)0x0F;
676 OpBuffer[obp++]=(char)0x10;
677 OpBuffer[obp++]=(char)(0x04 | REGISTER_OPERAND(XmmReg)<<3);
678 OpBuffer[obp++]=(char)0x25;
679 *((long *)(OpBuffer+obp))=i3;
680 pobj_DataTableSchedule->add();
681 obp+=sizeof(long);
682 }
683 }
684 else{
685 //整数
686
687 index_stack[sp]=GetLiteralIndex(i64data);
688
689 //mov reg,i64data
690 op_mov64_ToReg(UseReg,i64data);
691
692 if(UseReg==REG_R14){
693 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
694 pobj_sf->push(REG_R14);
695 }
696 }
697 }
698
699 if(bXmm) pobj_reg->LockXmmReg();
700 else pobj_reg->LockReg();
701
702 sp++;
703 break;
704
705 //論理演算子
706 case CALC_XOR:
707 case CALC_OR:
708 case CALC_AND:
709 if(!CalcTwoTerm_Logical(idCalc,type_stack,index_stack,&sp)) goto error;
710 break;
711 case CALC_NOT:
712 //value[sp-1]=Not value[sp-1]
713 //NOT演算子
714 if(!Calc_Not(type_stack,sp)) goto error;
715 break;
716
717 //比較演算子
718 case CALC_PE: //value[sp-2] <= value[sp-1]
719 case CALC_QE: //value[sp-2] >= value[sp-1]
720 case CALC_P: //value[sp-2] < value[sp-1]
721 case CALC_Q: //value[sp-2] > value[sp-1]
722 case CALC_NOTEQUAL: //value[sp-2] <> value[sp-1]
723 case CALC_EQUAL: //value[sp-2] = value[sp-1]
724 if(!CalcTwoTerm_Relational(idCalc,type_stack,index_stack,&sp)) goto error;
725 break;
726
727 //ビットシフト
728 case CALC_SHL: //value[sp-2] << value[sp-1]
729 case CALC_SHR: //value[sp-2] >> value[sp-1]
730 if(!Calc_Shift(idCalc,type_stack,&sp)) goto error;
731 break;
732
733 //算術演算
734 case CALC_ADDITION:
735 case CALC_SUBTRACTION:
736 case CALC_PRODUCT:
737 if(!CalcTwoTerm_Arithmetic(idCalc,type_stack,index_stack,&sp)) goto error;
738 break;
739 case CALC_MOD:
740 //value[sp-2]%=value[sp-1]
741 //剰余演算
742 if(!Calc_Mod(type_stack,index_stack,&sp)) goto error;
743 break;
744 case CALC_QUOTIENT:
745 //value[sp-2]/=value[sp-1];
746 //除算
747 if(!Calc_Divide(type_stack,&sp,baseType.GetBasicType())) goto error;
748 break;
749 case CALC_INTQUOTIENT:
750 //value[sp-2]/=value[sp-1]
751 //整数除算
752 if(!Calc_IntDivide(type_stack,index_stack,&sp)) goto error;
753 break;
754 case CALC_MINUSMARK:
755 //value[sp-1]=-value[sp-1]
756 //符号反転
757 if(!Calc_MinusMark(type_stack,sp)) goto error;
758 break;
759 case CALC_POWER:
760 //べき乗演算(浮動小数点演算のみ)
761 if(!Calc_Power(type_stack,&sp)) goto error;
762 break;
763 case CALC_AS:
764 //キャスト
765 if(!Calc_Cast(type_stack,index_stack,&sp)) goto error;
766 break;
767 case CALC_BYVAL:
768 //ポインタ型→参照型
769 if( PTR_LEVEL( type_stack[sp-1] ) <= 0 ){
770 //ポインタ型ではないとき
771 SetError( 3, NULL, cp );
772 goto error;
773 }
774
775 type_stack[sp-1] = PTR_LEVEL_DOWN( type_stack[sp-1] );
776
777 break;
778
779 default:
780 SetError(300,NULL,cp);
781 goto error;
782 }
783 }
784
785 if(bError) goto error;
786
787 if(sp!=1){
788 SetError(1,NULL,cp);
789 goto error;
790 }
791
792 if(bLiteralCalculation){
793 //右辺値が数値の定数式の場合
794 Type resultType;
795 StaticCalculation(true, expression,baseType.GetBasicType(),&i64data,resultType);
796
797 obp=BeforeObp;
798 pobj_SubAddrSchedule->num=Before_ProcAddrScheduleNum;
799 pobj_DataTableSchedule->num=Before_DataTableScheduleNum;
800 pobj_Reloc->copy(pobj_BackReloc);
801 pobj_sf->num=Before_StackFrameScheduleNum;
802 *pobj_reg=objReg_Backup;
803
804 if(resultType.IsReal()){
805 if(baseType.IsReal()) resultType=baseType;
806
807 XmmReg=pobj_reg->LockXmmReg();
808
809 if(resultType.IsDouble()){
810 i3 = dataTable.Add( i64data );
811
812 //movlpd xmm_reg,qword ptr[data table offset]
813 OpBuffer[obp++]=(char)0x66;
814 OpBuffer[obp++]=(char)0x0F;
815 OpBuffer[obp++]=(char)0x12;
816 OpBuffer[obp++]=(char)(0x04 | REGISTER_OPERAND(XmmReg)<<3);
817 OpBuffer[obp++]=(char)0x25;
818 *((long *)(OpBuffer+obp))=i3;
819 pobj_DataTableSchedule->add();
820 obp+=sizeof(long);
821 }
822 if(resultType.IsSingle()){
823 memcpy(&dbl,&i64data,sizeof(_int64));
824
825 float flt;
826 int i32data;
827 flt=(float)dbl;
828 memcpy(&i32data,&flt,sizeof(long));
829
830 i3 = dataTable.Add( i32data );
831
832 //movss xmm_reg,dword ptr[data table offset]
833 OpBuffer[obp++]=(char)0xF3;
834 OpBuffer[obp++]=(char)0x0F;
835 OpBuffer[obp++]=(char)0x10;
836 OpBuffer[obp++]=(char)(0x04 | REGISTER_OPERAND(XmmReg)<<3);
837 OpBuffer[obp++]=(char)0x25;
838 *((long *)(OpBuffer+obp))=i3;
839 pobj_DataTableSchedule->add();
840 obp+=sizeof(long);
841 }
842 }
843 else{
844 if(!resultType.Is64()){
845 //整数(符号有り/無し)
846
847 i3=(long)i64data;
848
849 if(resultType.GetBasicSize()==sizeof(char)) i3=i3&0x000000FF;
850 if(resultType.GetBasicSize()==sizeof(short)) i3=i3&0x0000FFFF;
851
852 i64data=(_int64)i3;
853 }
854
855 UseReg=pobj_reg->LockReg();
856
857 //mov reg,i64data
858 op_mov64_ToReg(UseReg,i64data);
859 }
860
861 type_stack[0]=resultType.GetBasicType();
862 index_stack[0]=resultType.GetIndex();
863 }
864 else{
865 //右辺値が数値の定数式ではないとき
866 if(IS_LITERAL(index_stack[0])) index_stack[0]=-1;
867 }
868
869 if(pbUseHeap) *pbUseHeap=bUseHeap[0];
870
871 if(IsRealNumberType(type_stack[0]))
872 *pReg=pobj_reg->UnlockXmmReg();
873 else
874 *pReg=pobj_reg->UnlockReg();
875
876
877 if(bInitRegSwitch){
878 //整合性をチェック(バグ回避)
879 pobj_reg->bug_check();
880
881 //作業レジスタを解放
882 delete pobj_reg;
883 pobj_reg=0;
884 }
885
886 resultType.SetType( type_stack[0], index_stack[0] );
887
888 bool isSuccessful = true;
889 goto finish;
890
891
892
893 //////////////////
894 // エラー処理
895 //////////////////
896
897error:
898
899 *pobj_reg=objReg_Backup;
900
901 if(bInitRegSwitch){
902 //作業レジスタを解放
903 delete pobj_reg;
904 pobj_reg=0;
905 }
906
907 isSuccessful = false;
908 goto finish;
909
910
911
912
913finish:
914
915 for(i=0;i<pnum;i++){
916 if(values[i]) HeapDefaultFree(values[i]);
917 }
918
919 //再配置スケジュールバックアップ情報を解放
920 delete pobj_BackReloc;
921
922 return isSuccessful;
923}
Note: See TracBrowser for help on using the repository browser.