source: dev/BasicCompiler64/NumOpe.cpp@ 93

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

"a=[10,20,30]" などのように、リテラルバイナリデータを指定できるようにした。

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