source: dev/BasicCompiler64/NumOpe.cpp@ 94

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

New[]を禁止した。
一部の動的型情報が生成されないバグを修正。
As演算子によるダウンキャストを許可(プログラム的なチェックはまだ走っていない)

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