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
RevLine 
[3]1#include "../BasicCompiler_Common/common.h"
2#include "Opcode.h"
3
[76]4void NewStringObject(int reg, const char *str){
[3]5 ///////////////////////////////////////////////////////
6 // lpszTextを元にStringオブジェクトを生成し、
7 // オブジェクトポインタをregに格納する
8 ///////////////////////////////////////////////////////
9
10
11 //////////////////////////////////////////////////////
12 ///// レジスタ資源のバックアップ
13 { BACKUP_REGISTER_RESOURCE
14 //////////////////////////////////////////////////////
15
[76]16 char *parameter = (char *)malloc( lstrlen( str ) + 32 );
17 sprintf( parameter, "\"%s\"%c%c*Char", str, 1, ESC_AS );
[64]18 SetStringQuotes( parameter );
19
[3]20 extern CClass *pobj_StringClass;
[75]21 Operator_New( *pobj_StringClass, "", parameter, Type( DEF_OBJECT, *pobj_StringClass ) );
[3]22
[64]23 free( parameter );
[3]24
[64]25 //mov reg,rax
26 op_mov_RR( reg, REG_RAX );
[3]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
[64]66 op_mov_RR(UseReg,REG_RAX);
[3]67 }
68 }
69}
70
[75]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
[3]91 int i,i2,i3,i4;
92 char temporary[1024],temp2[1024],temp3[1024];
93
[75]94 if(expression[0]=='\0'){
[3]95 SetError(1,NULL,cp);
[75]96 return false;
[3]97 }
98
[75]99 if(expression[0]==1&& expression[1]==ESC_NEW ){
[3]100 //New演算子(オブジェクト生成)
[64]101
[75]102 if( !Operator_New( expression+2, baseType, resultType ) ){
103 return false;
104 }
105
[64]106 //mov reg,rax
107 op_mov_RR( *pReg, REG_RAX );
108
[75]109 return true;
[3]110 }
111
[93]112 if( !baseType.IsNull() && expression[0] == '[' ){
113 // リテラル配列の場合
[3]114
[93]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
[3]168 /////////////////////////////////
169 // 式要素を逆ポーランド式で取得
170 /////////////////////////////////
171
172 char *values[255];
173 long calc[255];
174 long stack[255];
175 int pnum;
[75]176 if(!GetNumOpeElements(expression,&pnum,values,calc,stack)){
[3]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;
[75]232 int type_stack[255];
[3]233 LONG_PTR index_stack[255];
[79]234 bool isNothing_stack[255];
[3]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){
[75]244 if(type_stack[sp-2]==DEF_OBJECT){
[79]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演算子を呼び出さない
[3]250 }
[79]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;
[3]262
[79]263 continue;
264 }
[3]265 }
266
[75]267 if(!CheckCalcType(idCalc,type_stack,sp)) goto error;
[3]268 }
269
270 switch(idCalc){
271 //数値
272 case 0:
273 index_stack[sp]=-1;
[79]274 isNothing_stack[sp] = false;
[3]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:
[76]293
[75]294 if( baseType.IsObject() ){
295 if( baseType.IsStringObject() ){
[68]296 //要求タイプがStringのとき
[3]297
298 //String型オブジェクトを生成
299 NewStringObject(UseReg,term);
300
301 extern CClass *pobj_StringClass;
[75]302 type_stack[sp]=DEF_OBJECT;
[3]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
[75]314 type_stack[sp]=typeOfPtrChar;
[3]315 bLiteralCalculation=0;
316
[56]317 i2 = dataTable.AddString( term, i3 );
[3]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;
[76]358 int idProc=GetProc(temporary,(void **)&pInfo);
[3]359
[75]360 Type resultType;
[3]361 if(idProc){
[49]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 }
[3]372
373
374 //////////////////////////////////////////////////////
375 ///// レジスタ資源のバックアップ
376 { BACKUP_REGISTER_RESOURCE
377 //////////////////////////////////////////////////////
378
379
380 ////////////////
381 // 呼び出し
382 ////////////////
383
[75]384 CallProc(idProc,pInfo,temporary,temp2,resultType);
385 if(resultType.IsNull()){
[3]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 //大きな型への暗黙の変換
[75]407 type_stack[sp]=AutoBigCast(baseType.GetBasicType(),resultType.GetBasicType());
408 index_stack[sp] = resultType.GetIndex();
[3]409 bLiteralCalculation=0;
410
[75]411 if( type_stack[sp] != resultType.GetBasicType() ){
412 // 大きな型へ変換された場合
413 // ※レジスタの値をキャストする
414 ExtendRegToBigType( REG_RAX, type_stack[sp], resultType.GetBasicType() );
415 }
[3]416
[75]417 SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
418
419 if(resultType.IsReal()) bXmm=1;
[3]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
[75]431 if(resultType.IsStruct()){
[64]432 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
[3]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 //マクロ関数の場合
[75]449 NumOpe(&UseReg,temp3,Type(),resultType);
[3]450
[75]451 if(!IS_LITERAL(resultType.GetIndex())){
[3]452 //リテラル値ではなかったとき
453 bLiteralCalculation=0;
454 }
455
[75]456 type_stack[sp] = resultType.GetBasicType();
457 index_stack[sp] = resultType.GetIndex();
[3]458
[75]459 if(resultType.IsReal()) pobj_reg->LockXmmReg();
[3]460 else pobj_reg->LockReg();
461
462 sp++;
463 break;
464 }
465 }
[49]466NonProc:
[3]467
468
[38]469 //インデクサ(getアクセサ)
[3]470 char variable[VN_SIZE],array_element[VN_SIZE];
471 GetArrayElement(term,variable,array_element);
472 if(array_element[0]){
[75]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();
[3]479 bLiteralCalculation=0;
480
[75]481 if(resultType.IsReal()) pobj_reg->LockXmmReg();
[3]482 else pobj_reg->LockReg();
483 sp++;
484 break;
485 }
486 }
487
488
[67]489 // Nothing
490 if( lstrcmp( term, "Nothing" ) == 0 ){
[79]491 isNothing_stack[sp] = true;
492
[75]493 type_stack[sp] = DEF_OBJECT;
494 if( baseType.IsObject() ){
495 index_stack[sp] = baseType.GetIndex();
[67]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
[3]517 RELATIVE_VAR RelativeVar;
[75]518 Type varType;
[11]519 if(GetVarOffset(
520 false, //エラー表示あり
521 false, //読み込み専用
522 term,
[75]523 &RelativeVar,varType)){
[3]524 //////////
525 // 変数
526 //////////
527
528 //大きな型への暗黙の変換
[75]529 type_stack[sp]=AutoBigCast(baseType.GetBasicType(),varType.GetBasicType());
530 index_stack[sp] = varType.GetIndex();
[3]531 bLiteralCalculation=0;
532
[75]533 if(varType.GetBasicType()&FLAG_PTR){
[3]534 //配列ポインタ
[75]535 type_stack[sp]=GetPtrType(varType.GetBasicType()^FLAG_PTR);
[3]536
537 SetVarPtrToReg(UseReg,&RelativeVar);
538 }
[75]539 else if(varType.IsReal()){
[3]540 //実数型
541 bXmm=1;
542
[75]543 if( varType.IsDouble() )
[3]544 SetXmmReg_DoubleVariable(&RelativeVar,XmmReg);
[75]545 if( varType.IsSingle() )
[3]546 SetXmmReg_SingleVariable(&RelativeVar,XmmReg);
547 }
[75]548 else if( varType.IsWhole() || varType.IsObject()){
[3]549 //整数型
[75]550 SetReg_WholeVariable(varType.GetBasicType(),&RelativeVar,UseReg);
[3]551 }
[75]552 else if( varType.IsStruct() ){
[64]553 //構造体ポインタをUseRegへ格納(構造体は値型)
[3]554 SetVarPtrToReg(UseReg,&RelativeVar);
555 }
556 else SetError(11,term,cp);
557
[75]558 if( type_stack[sp] != varType.GetBasicType() ){
559 // 大きな型へ変換された場合
560 // ※レジスタの値をキャストする
561 ExtendRegToBigType( UseReg, type_stack[sp], varType.GetBasicType() );
562 }
563
[3]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){
[75]569 if(varType.IsDouble()){
[3]570 //movsd qword ptr[rsp+offset],xmm4 ※スタックフレームを利用
571 pobj_sf->push(REG_XMM4,sizeof(double));
572 }
[75]573 if(varType.IsSingle()){
[3]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
[9]590 i3 = CDBConst::obj.GetType(term);
591 if(i3){
[75]592 type_stack[sp] = i3;
[3]593 if(IsRealNumberType(i3)){
594 //実数
[9]595 double dbl = CDBConst::obj.GetDoubleData(term);
[3]596 memcpy(&i64data,&dbl,sizeof(double));
597 goto Literal;
598 }
599 else if(IsWholeNumberType(i3)){
600 //整数
[9]601 i64data = CDBConst::obj.GetWholeData(term);
[3]602 goto Literal;
603 }
[9]604 /*else if(i3==DEF_STRING){
[3]605 //リテラル文字列
606
607 //バイト数
608 i3=(int)dbl;
609
610 memcpy(term,temporary,i3);
611 goto StrLiteral;
[9]612 }*/
[3]613 else{
614 SetError(1,NULL,0);
615 goto error;
616 }
617 }
618
619
620 //////////////
621 // 型名の場合
622 //////////////
[79]623 Type tempType;
624 if( Type::StringToType( term, tempType ) ){
625 type_stack[sp] = tempType.GetBasicType() | FLAG_CAST;
626 index_stack[sp] = tempType.GetIndex();
[3]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
[75]647 Type resultType;
648 CallPropertyMethod(term,NULL,resultType);
[3]649
650 //大きな型への暗黙の変換
[75]651 type_stack[sp]=AutoBigCast(baseType.GetBasicType(),resultType.GetBasicType());
652 index_stack[sp]=resultType.GetIndex();
[3]653 bLiteralCalculation=0;
654
[75]655 if( type_stack[sp] != resultType.GetBasicType() ){
656 // 大きな型へ変換された場合
657 // ※レジスタの値をキャストする
658 ExtendRegToBigType( REG_RAX, type_stack[sp], resultType.GetBasicType() );
659 }
[3]660
[75]661 SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
662
663 if(IsRealNumberType(type_stack[sp])) bXmm=1;
[3]664 else bXmm=0;
665
666 /////////////////////////////////////////////
667 ////// レジスタ資源を復元
668 RESTORE_REGISTER_RESOURCE
669 }////////////////////////////////////////////
670
[75]671 if(type_stack[sp]==DEF_STRUCT){
[64]672 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
[3]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);
[75]688 type_stack[sp]=DEF_DOUBLE;
[3]689 }
690 else{
691 //リテラル値
[75]692 type_stack[sp]=GetLiteralValue(term,&i64data,baseType.GetBasicType());
[3]693Literal:
[75]694 if(type_stack[sp]==DEF_DOUBLE){
[3]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{
[56]707 i3 = dataTable.Add( i64data );
[3]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 }
[75]720 else if(type_stack[sp]==DEF_SINGLE){
[3]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{
[56]735 i3=dataTable.Add( i32data );
[3]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:
[75]773 if(!CalcTwoTerm_Logical(idCalc,type_stack,index_stack,&sp)) goto error;
[3]774 break;
775 case CALC_NOT:
776 //value[sp-1]=Not value[sp-1]
777 //NOT演算子
[75]778 if(!Calc_Not(type_stack,sp)) goto error;
[3]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]
[75]788 if(!CalcTwoTerm_Relational(idCalc,type_stack,index_stack,&sp)) goto error;
[3]789 break;
790
791 //ビットシフト
792 case CALC_SHL: //value[sp-2] << value[sp-1]
793 case CALC_SHR: //value[sp-2] >> value[sp-1]
[75]794 if(!Calc_Shift(idCalc,type_stack,&sp)) goto error;
[3]795 break;
796
797 //算術演算
798 case CALC_ADDITION:
799 case CALC_SUBTRACTION:
800 case CALC_PRODUCT:
[75]801 if(!CalcTwoTerm_Arithmetic(idCalc,type_stack,index_stack,&sp)) goto error;
[3]802 break;
803 case CALC_MOD:
804 //value[sp-2]%=value[sp-1]
805 //剰余演算
[75]806 if(!Calc_Mod(type_stack,index_stack,&sp)) goto error;
[3]807 break;
808 case CALC_QUOTIENT:
809 //value[sp-2]/=value[sp-1];
810 //除算
[75]811 if(!Calc_Divide(type_stack,&sp,baseType.GetBasicType())) goto error;
[3]812 break;
813 case CALC_INTQUOTIENT:
814 //value[sp-2]/=value[sp-1]
815 //整数除算
[75]816 if(!Calc_IntDivide(type_stack,index_stack,&sp)) goto error;
[3]817 break;
818 case CALC_MINUSMARK:
819 //value[sp-1]=-value[sp-1]
820 //符号反転
[75]821 if(!Calc_MinusMark(type_stack,sp)) goto error;
[3]822 break;
823 case CALC_POWER:
824 //べき乗演算(浮動小数点演算のみ)
[75]825 if(!Calc_Power(type_stack,&sp)) goto error;
[3]826 break;
827 case CALC_AS:
828 //キャスト
[75]829 if(!Calc_Cast(type_stack,index_stack,&sp)) goto error;
[3]830 break;
[41]831 case CALC_BYVAL:
832 //ポインタ型→参照型
[75]833 if( PTR_LEVEL( type_stack[sp-1] ) <= 0 ){
[41]834 //ポインタ型ではないとき
835 SetError( 3, NULL, cp );
836 goto error;
837 }
[3]838
[75]839 type_stack[sp-1] = PTR_LEVEL_DOWN( type_stack[sp-1] );
[41]840
841 break;
842
[3]843 default:
844 SetError(300,NULL,cp);
[41]845 goto error;
[3]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 //右辺値が数値の定数式の場合
[75]858 Type resultType;
859 StaticCalculation(true, expression,baseType.GetBasicType(),&i64data,resultType);
[3]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
[75]868 if(resultType.IsReal()){
869 if(baseType.IsReal()) resultType=baseType;
[3]870
871 XmmReg=pobj_reg->LockXmmReg();
872
[75]873 if(resultType.IsDouble()){
[56]874 i3 = dataTable.Add( i64data );
[3]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 }
[75]886 if(resultType.IsSingle()){
[3]887 memcpy(&dbl,&i64data,sizeof(_int64));
888
889 float flt;
890 int i32data;
891 flt=(float)dbl;
892 memcpy(&i32data,&flt,sizeof(long));
893
[56]894 i3 = dataTable.Add( i32data );
[3]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{
[75]908 if(!resultType.Is64()){
[3]909 //整数(符号有り/無し)
910
911 i3=(long)i64data;
912
[75]913 if(resultType.GetBasicSize()==sizeof(char)) i3=i3&0x000000FF;
914 if(resultType.GetBasicSize()==sizeof(short)) i3=i3&0x0000FFFF;
[3]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
[75]925 type_stack[0]=resultType.GetBasicType();
926 index_stack[0]=resultType.GetIndex();
[3]927 }
928 else{
929 //右辺値が数値の定数式ではないとき
930 if(IS_LITERAL(index_stack[0])) index_stack[0]=-1;
931 }
932
933 if(pbUseHeap) *pbUseHeap=bUseHeap[0];
934
[75]935 if(IsRealNumberType(type_stack[0]))
[3]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
[75]950 resultType.SetType( type_stack[0], index_stack[0] );
951
952 bool isSuccessful = true;
[3]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
[75]971 isSuccessful = false;
[3]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
[75]986 return isSuccessful;
[3]987}
Note: See TracBrowser for help on using the repository browser.