source: dev/BasicCompiler64/NumOpe.cpp@ 75

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

TYPEINFO→Typeへのリファクタリングを実施。64bitはほぼ完了。32bitが全般的に未完成。

File size: 22.7 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "Opcode.h"
3
4void NewStringObject(int reg,LPSTR lpszText){
5 ///////////////////////////////////////////////////////
6 // lpszTextを元にStringオブジェクトを生成し、
7 // オブジェクトポインタをregに格納する
8 ///////////////////////////////////////////////////////
9
10
11 //////////////////////////////////////////////////////
12 ///// レジスタ資源のバックアップ
13 { BACKUP_REGISTER_RESOURCE
14 //////////////////////////////////////////////////////
15
16 char *parameter = (char *)malloc( lstrlen( lpszText ) + 32 );
17 sprintf( parameter, "\"%s\"%c%c*Char", lpszText, 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 int idProc;
293 void *pInfo;
294 idProc=GetProc(temporary,(void **)&pInfo);
295
296 Type resultType;
297 if(idProc){
298 //閉じカッコ")"に続く文字がNULLでないとき
299 if(term[i2+1+i4+1]!='\0'){
300 if( term[i2+1+i4+1] == '.'
301 || term[i2+1+i4+1] == 1 && term[i2+1+i4+2] == ESC_PSMEM ){
302 goto NonProc;
303 }
304 else{
305 SetError(42,NULL,cp);
306 }
307 }
308
309
310 //////////////////////////////////////////////////////
311 ///// レジスタ資源のバックアップ
312 { BACKUP_REGISTER_RESOURCE
313 //////////////////////////////////////////////////////
314
315
316 ////////////////
317 // 呼び出し
318 ////////////////
319
320 CallProc(idProc,pInfo,temporary,temp2,resultType);
321 if(resultType.IsNull()){
322 //戻り値が存在しないとき
323 for(i2=2;;i2++){
324 if(term[i2]=='('||term[i2]=='\0'){
325 term[i2]=0;
326 break;
327 }
328 }
329 SetError(38,term,cp);
330
331 //レジスタ資源を復元
332 RESTORE_REGISTER_RESOURCE
333
334 goto error;
335 }
336
337
338 /////////////////////
339 // 戻り値の処理
340 /////////////////////
341
342 //大きな型への暗黙の変換
343 type_stack[sp]=AutoBigCast(baseType.GetBasicType(),resultType.GetBasicType());
344 index_stack[sp] = resultType.GetIndex();
345 bLiteralCalculation=0;
346
347 if( type_stack[sp] != resultType.GetBasicType() ){
348 // 大きな型へ変換された場合
349 // ※レジスタの値をキャストする
350 ExtendRegToBigType( REG_RAX, type_stack[sp], resultType.GetBasicType() );
351 }
352
353 SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
354
355 if(resultType.IsReal()) bXmm=1;
356 else bXmm=0;
357
358 /////////////////////////////////////////////
359 ////// レジスタ資源を復元
360 RESTORE_REGISTER_RESOURCE
361 }////////////////////////////////////////////
362
363
364 if(bXmm) pobj_reg->LockXmmReg();
365 else pobj_reg->LockReg();
366
367 if(resultType.IsStruct()){
368 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
369 //※後にfreeする必要あり
370 bUseHeap[sp]=1;
371 }
372
373 sp++;
374 break;
375 }
376 else if(GetConstCalcBuffer(temporary,temp2,temp3)){
377 /////////////////////////
378 // マクロ関数
379 /////////////////////////
380
381 //閉じカッコ")"に続く文字がNULLでないときはエラーにする
382 if(term[i2+1+i4+1]!='\0') SetError(42,NULL,cp);
383
384 //マクロ関数の場合
385 NumOpe(&UseReg,temp3,Type(),resultType);
386
387 if(!IS_LITERAL(resultType.GetIndex())){
388 //リテラル値ではなかったとき
389 bLiteralCalculation=0;
390 }
391
392 type_stack[sp] = resultType.GetBasicType();
393 index_stack[sp] = resultType.GetIndex();
394
395 if(resultType.IsReal()) pobj_reg->LockXmmReg();
396 else pobj_reg->LockReg();
397
398 sp++;
399 break;
400 }
401 }
402NonProc:
403
404
405 //インデクサ(getアクセサ)
406 char variable[VN_SIZE],array_element[VN_SIZE];
407 GetArrayElement(term,variable,array_element);
408 if(array_element[0]){
409 Type resultType;
410 GetVarType(variable,resultType,0);
411 if( resultType.IsObject() ){
412 CallIndexerGetterProc(UseReg,&resultType.GetClass(),variable,array_element,resultType);
413 type_stack[sp]=resultType.GetBasicType();
414 index_stack[sp]=resultType.GetIndex();
415 bLiteralCalculation=0;
416
417 if(resultType.IsReal()) pobj_reg->LockXmmReg();
418 else pobj_reg->LockReg();
419 sp++;
420 break;
421 }
422 }
423
424
425 // Nothing
426 if( lstrcmp( term, "Nothing" ) == 0 ){
427 type_stack[sp] = DEF_OBJECT;
428 if( baseType.IsObject() ){
429 index_stack[sp] = baseType.GetIndex();
430 }
431 else{
432 index_stack[sp] = (LONG_PTR)pobj_DBClass->GetObjectClass();
433 }
434
435 bLiteralCalculation = 0;
436
437 //xor reg,reg
438 op_zero_reg( UseReg );
439
440 if(UseReg==REG_R14){
441 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
442 pobj_sf->push(REG_R14);
443 }
444
445 pobj_reg->LockReg();
446 sp++;
447 break;
448 }
449
450
451 RELATIVE_VAR RelativeVar;
452 Type varType;
453 if(GetVarOffset(
454 false, //エラー表示あり
455 false, //読み込み専用
456 term,
457 &RelativeVar,varType)){
458 //////////
459 // 変数
460 //////////
461
462 //大きな型への暗黙の変換
463 type_stack[sp]=AutoBigCast(baseType.GetBasicType(),varType.GetBasicType());
464 index_stack[sp] = varType.GetIndex();
465 bLiteralCalculation=0;
466
467 if(varType.GetBasicType()&FLAG_PTR){
468 //配列ポインタ
469 type_stack[sp]=GetPtrType(varType.GetBasicType()^FLAG_PTR);
470
471 SetVarPtrToReg(UseReg,&RelativeVar);
472 }
473 else if(varType.IsReal()){
474 //実数型
475 bXmm=1;
476
477 if( varType.IsDouble() )
478 SetXmmReg_DoubleVariable(&RelativeVar,XmmReg);
479 if( varType.IsSingle() )
480 SetXmmReg_SingleVariable(&RelativeVar,XmmReg);
481 }
482 else if( varType.IsWhole() || varType.IsObject()){
483 //整数型
484 SetReg_WholeVariable(varType.GetBasicType(),&RelativeVar,UseReg);
485 }
486 else if( varType.IsStruct() ){
487 //構造体ポインタをUseRegへ格納(構造体は値型)
488 SetVarPtrToReg(UseReg,&RelativeVar);
489 }
490 else SetError(11,term,cp);
491
492 if( type_stack[sp] != varType.GetBasicType() ){
493 // 大きな型へ変換された場合
494 // ※レジスタの値をキャストする
495 ExtendRegToBigType( UseReg, type_stack[sp], varType.GetBasicType() );
496 }
497
498 if(bXmm==0&&UseReg==REG_R14){
499 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
500 pobj_sf->push(REG_R14);
501 }
502 if(bXmm&&XmmReg==REG_XMM4){
503 if(varType.IsDouble()){
504 //movsd qword ptr[rsp+offset],xmm4 ※スタックフレームを利用
505 pobj_sf->push(REG_XMM4,sizeof(double));
506 }
507 if(varType.IsSingle()){
508 //movss dword ptr[rsp+offset],xmm4 ※スタックフレームを利用
509 pobj_sf->push(REG_XMM4,sizeof(float));
510 }
511 }
512
513 if(bXmm) pobj_reg->LockXmmReg();
514 else pobj_reg->LockReg();
515 sp++;
516 break;
517 }
518
519
520 //////////////
521 // 定数の場合
522 //////////////
523
524 i3 = CDBConst::obj.GetType(term);
525 if(i3){
526 type_stack[sp] = i3;
527 if(IsRealNumberType(i3)){
528 //実数
529 double dbl = CDBConst::obj.GetDoubleData(term);
530 memcpy(&i64data,&dbl,sizeof(double));
531 goto Literal;
532 }
533 else if(IsWholeNumberType(i3)){
534 //整数
535 i64data = CDBConst::obj.GetWholeData(term);
536 goto Literal;
537 }
538 /*else if(i3==DEF_STRING){
539 //リテラル文字列
540
541 //バイト数
542 i3=(int)dbl;
543
544 memcpy(term,temporary,i3);
545 goto StrLiteral;
546 }*/
547 else{
548 SetError(1,NULL,0);
549 goto error;
550 }
551 }
552
553
554
555 //////////////
556 // 型名の場合
557 //////////////
558
559 LONG_PTR lp;
560 i3=GetTypeFixed(term,&lp);
561 if(i3!=-1){
562 type_stack[sp]=i3|FLAG_CAST;
563 index_stack[sp]=lp;
564 sp++;
565 break;
566 }
567
568
569
570 /////////////////////////////////
571 // プロパティ用のメソッド
572 /////////////////////////////////
573
574 //配列要素を排除
575 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
576 GetArrayElement(term,VarName,ArrayElements);
577
578 if(GetSubHash(VarName,0)){
579
580 //////////////////////////////////////////////////////
581 ///// レジスタ資源のバックアップ
582 { BACKUP_REGISTER_RESOURCE
583 //////////////////////////////////////////////////////
584
585 Type resultType;
586 CallPropertyMethod(term,NULL,resultType);
587
588 //大きな型への暗黙の変換
589 type_stack[sp]=AutoBigCast(baseType.GetBasicType(),resultType.GetBasicType());
590 index_stack[sp]=resultType.GetIndex();
591 bLiteralCalculation=0;
592
593 if( type_stack[sp] != resultType.GetBasicType() ){
594 // 大きな型へ変換された場合
595 // ※レジスタの値をキャストする
596 ExtendRegToBigType( REG_RAX, type_stack[sp], resultType.GetBasicType() );
597 }
598
599 SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
600
601 if(IsRealNumberType(type_stack[sp])) bXmm=1;
602 else bXmm=0;
603
604 /////////////////////////////////////////////
605 ////// レジスタ資源を復元
606 RESTORE_REGISTER_RESOURCE
607 }////////////////////////////////////////////
608
609 if(type_stack[sp]==DEF_STRUCT){
610 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
611 //※後にfreeする必要あり
612 bUseHeap[sp]=1;
613 }
614
615 if(bXmm) pobj_reg->LockXmmReg();
616 else pobj_reg->LockReg();
617 sp++;
618 break;
619 }
620
621
622
623 //該当する識別子が見当たらないときはエラー扱いにする
624 bError=1;
625 SetError(3,term,cp);
626 type_stack[sp]=DEF_DOUBLE;
627 }
628 else{
629 //リテラル値
630 type_stack[sp]=GetLiteralValue(term,&i64data,baseType.GetBasicType());
631Literal:
632 if(type_stack[sp]==DEF_DOUBLE){
633 //64ビット浮動小数型
634 bXmm=1;
635
636 if(XmmReg==REG_XMM4){
637 //mov r14,i64data
638 op_mov64_ToReg(REG_R14,i64data);
639
640
641 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
642 pobj_sf->push(REG_R14);
643 }
644 else{
645 i3 = dataTable.Add( i64data );
646
647 //movlpd xmm_reg,qword ptr[data table offset]
648 OpBuffer[obp++]=(char)0x66;
649 OpBuffer[obp++]=(char)0x0F;
650 OpBuffer[obp++]=(char)0x12;
651 OpBuffer[obp++]=(char)(0x04 | REGISTER_OPERAND(XmmReg)<<3);
652 OpBuffer[obp++]=(char)0x25;
653 *((long *)(OpBuffer+obp))=i3;
654 pobj_DataTableSchedule->add();
655 obp+=sizeof(long);
656 }
657 }
658 else if(type_stack[sp]==DEF_SINGLE){
659 //32ビット浮動小数型
660 bXmm=1;
661
662 float flt;
663 int i32data;
664 memcpy(&dbl,&i64data,sizeof(double));
665 flt=(float)dbl;
666 memcpy(&i32data,&flt,sizeof(long));
667
668 if(XmmReg==REG_XMM4){
669 //push term
670 op_push_value(i32data);
671 }
672 else{
673 i3=dataTable.Add( i32data );
674
675 //movss xmm_reg,dword ptr[data table offset]
676 OpBuffer[obp++]=(char)0xF3;
677 OpBuffer[obp++]=(char)0x0F;
678 OpBuffer[obp++]=(char)0x10;
679 OpBuffer[obp++]=(char)(0x04 | REGISTER_OPERAND(XmmReg)<<3);
680 OpBuffer[obp++]=(char)0x25;
681 *((long *)(OpBuffer+obp))=i3;
682 pobj_DataTableSchedule->add();
683 obp+=sizeof(long);
684 }
685 }
686 else{
687 //整数
688
689 index_stack[sp]=GetLiteralIndex(i64data);
690
691 //mov reg,i64data
692 op_mov64_ToReg(UseReg,i64data);
693
694 if(UseReg==REG_R14){
695 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
696 pobj_sf->push(REG_R14);
697 }
698 }
699 }
700
701 if(bXmm) pobj_reg->LockXmmReg();
702 else pobj_reg->LockReg();
703
704 sp++;
705 break;
706
707 //論理演算子
708 case CALC_XOR:
709 case CALC_OR:
710 case CALC_AND:
711 if(!CalcTwoTerm_Logical(idCalc,type_stack,index_stack,&sp)) goto error;
712 break;
713 case CALC_NOT:
714 //value[sp-1]=Not value[sp-1]
715 //NOT演算子
716 if(!Calc_Not(type_stack,sp)) goto error;
717 break;
718
719 //比較演算子
720 case CALC_PE: //value[sp-2] <= value[sp-1]
721 case CALC_QE: //value[sp-2] >= value[sp-1]
722 case CALC_P: //value[sp-2] < value[sp-1]
723 case CALC_Q: //value[sp-2] > value[sp-1]
724 case CALC_NOTEQUAL: //value[sp-2] <> value[sp-1]
725 case CALC_EQUAL: //value[sp-2] = value[sp-1]
726 if(!CalcTwoTerm_Relational(idCalc,type_stack,index_stack,&sp)) goto error;
727 break;
728
729 //ビットシフト
730 case CALC_SHL: //value[sp-2] << value[sp-1]
731 case CALC_SHR: //value[sp-2] >> value[sp-1]
732 if(!Calc_Shift(idCalc,type_stack,&sp)) goto error;
733 break;
734
735 //算術演算
736 case CALC_ADDITION:
737 case CALC_SUBTRACTION:
738 case CALC_PRODUCT:
739 if(!CalcTwoTerm_Arithmetic(idCalc,type_stack,index_stack,&sp)) goto error;
740 break;
741 case CALC_MOD:
742 //value[sp-2]%=value[sp-1]
743 //剰余演算
744 if(!Calc_Mod(type_stack,index_stack,&sp)) goto error;
745 break;
746 case CALC_QUOTIENT:
747 //value[sp-2]/=value[sp-1];
748 //除算
749 if(!Calc_Divide(type_stack,&sp,baseType.GetBasicType())) goto error;
750 break;
751 case CALC_INTQUOTIENT:
752 //value[sp-2]/=value[sp-1]
753 //整数除算
754 if(!Calc_IntDivide(type_stack,index_stack,&sp)) goto error;
755 break;
756 case CALC_MINUSMARK:
757 //value[sp-1]=-value[sp-1]
758 //符号反転
759 if(!Calc_MinusMark(type_stack,sp)) goto error;
760 break;
761 case CALC_POWER:
762 //べき乗演算(浮動小数点演算のみ)
763 if(!Calc_Power(type_stack,&sp)) goto error;
764 break;
765 case CALC_AS:
766 //キャスト
767 if(!Calc_Cast(type_stack,index_stack,&sp)) goto error;
768 break;
769 case CALC_BYVAL:
770 //ポインタ型→参照型
771 if( PTR_LEVEL( type_stack[sp-1] ) <= 0 ){
772 //ポインタ型ではないとき
773 SetError( 3, NULL, cp );
774 goto error;
775 }
776
777 type_stack[sp-1] = PTR_LEVEL_DOWN( type_stack[sp-1] );
778
779 break;
780
781 default:
782 SetError(300,NULL,cp);
783 goto error;
784 }
785 }
786
787 if(bError) goto error;
788
789 if(sp!=1){
790 SetError(1,NULL,cp);
791 goto error;
792 }
793
794 if(bLiteralCalculation){
795 //右辺値が数値の定数式の場合
796 Type resultType;
797 StaticCalculation(true, expression,baseType.GetBasicType(),&i64data,resultType);
798
799 obp=BeforeObp;
800 pobj_SubAddrSchedule->num=Before_ProcAddrScheduleNum;
801 pobj_DataTableSchedule->num=Before_DataTableScheduleNum;
802 pobj_Reloc->copy(pobj_BackReloc);
803 pobj_sf->num=Before_StackFrameScheduleNum;
804 *pobj_reg=objReg_Backup;
805
806 if(resultType.IsReal()){
807 if(baseType.IsReal()) resultType=baseType;
808
809 XmmReg=pobj_reg->LockXmmReg();
810
811 if(resultType.IsDouble()){
812 i3 = dataTable.Add( i64data );
813
814 //movlpd xmm_reg,qword ptr[data table offset]
815 OpBuffer[obp++]=(char)0x66;
816 OpBuffer[obp++]=(char)0x0F;
817 OpBuffer[obp++]=(char)0x12;
818 OpBuffer[obp++]=(char)(0x04 | REGISTER_OPERAND(XmmReg)<<3);
819 OpBuffer[obp++]=(char)0x25;
820 *((long *)(OpBuffer+obp))=i3;
821 pobj_DataTableSchedule->add();
822 obp+=sizeof(long);
823 }
824 if(resultType.IsSingle()){
825 memcpy(&dbl,&i64data,sizeof(_int64));
826
827 float flt;
828 int i32data;
829 flt=(float)dbl;
830 memcpy(&i32data,&flt,sizeof(long));
831
832 i3 = dataTable.Add( i32data );
833
834 //movss xmm_reg,dword ptr[data table offset]
835 OpBuffer[obp++]=(char)0xF3;
836 OpBuffer[obp++]=(char)0x0F;
837 OpBuffer[obp++]=(char)0x10;
838 OpBuffer[obp++]=(char)(0x04 | REGISTER_OPERAND(XmmReg)<<3);
839 OpBuffer[obp++]=(char)0x25;
840 *((long *)(OpBuffer+obp))=i3;
841 pobj_DataTableSchedule->add();
842 obp+=sizeof(long);
843 }
844 }
845 else{
846 if(!resultType.Is64()){
847 //整数(符号有り/無し)
848
849 i3=(long)i64data;
850
851 if(resultType.GetBasicSize()==sizeof(char)) i3=i3&0x000000FF;
852 if(resultType.GetBasicSize()==sizeof(short)) i3=i3&0x0000FFFF;
853
854 i64data=(_int64)i3;
855 }
856
857 UseReg=pobj_reg->LockReg();
858
859 //mov reg,i64data
860 op_mov64_ToReg(UseReg,i64data);
861 }
862
863 type_stack[0]=resultType.GetBasicType();
864 index_stack[0]=resultType.GetIndex();
865 }
866 else{
867 //右辺値が数値の定数式ではないとき
868 if(IS_LITERAL(index_stack[0])) index_stack[0]=-1;
869 }
870
871 if(pbUseHeap) *pbUseHeap=bUseHeap[0];
872
873 if(IsRealNumberType(type_stack[0]))
874 *pReg=pobj_reg->UnlockXmmReg();
875 else
876 *pReg=pobj_reg->UnlockReg();
877
878
879 if(bInitRegSwitch){
880 //整合性をチェック(バグ回避)
881 pobj_reg->bug_check();
882
883 //作業レジスタを解放
884 delete pobj_reg;
885 pobj_reg=0;
886 }
887
888 resultType.SetType( type_stack[0], index_stack[0] );
889
890 bool isSuccessful = true;
891 goto finish;
892
893
894
895 //////////////////
896 // エラー処理
897 //////////////////
898
899error:
900
901 *pobj_reg=objReg_Backup;
902
903 if(bInitRegSwitch){
904 //作業レジスタを解放
905 delete pobj_reg;
906 pobj_reg=0;
907 }
908
909 isSuccessful = false;
910 goto finish;
911
912
913
914
915finish:
916
917 for(i=0;i<pnum;i++){
918 if(values[i]) HeapDefaultFree(values[i]);
919 }
920
921 //再配置スケジュールバックアップ情報を解放
922 delete pobj_BackReloc;
923
924 return isSuccessful;
925}
Note: See TracBrowser for help on using the repository browser.