source: dev/BasicCompiler64/NumOpe.cpp@ 89

Last change on this file since 89 was 79, checked in by dai_9181, 18 years ago

バージョンをβ17にした。
#strictをデフォルトの状態で適用するようにした(#90)。
Dimステートメントにおいて、初期値式とAsが同時に指定されていたとき、As以降も初期値式の一部として捉えるよう、変更(#91)。
GetTypeDef関数を完全廃止。

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