source: dev/trunk/abdev/BasicCompiler64/NumOpe.cpp@ 318

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

64bit版でコンパイルできるようにした。

File size: 30.1 KB
Line 
1#include "stdafx.h"
2
3#include <jenga/include/smoothie/Smoothie.h>
4#include <jenga/include/smoothie/LexicalAnalysis.h>
5
6#include <Compiler.h>
7
8#include "../BasicCompiler_Common/common.h"
9#include "Opcode.h"
10
11void NewStringObject(int reg, const char *str){
12 ///////////////////////////////////////////////////////
13 // lpszTextを元にStringオブジェクトを生成し、
14 // オブジェクトポインタをregに格納する
15 ///////////////////////////////////////////////////////
16
17
18 //////////////////////////////////////////////////////
19 ///// レジスタ資源のバックアップ
20 { BACKUP_REGISTER_RESOURCE
21 //////////////////////////////////////////////////////
22
23 char *parameter = (char *)malloc( lstrlen( str ) + 32 );
24 sprintf( parameter, "\"%s\"%c%c*Char", str, 1, ESC_AS );
25 SetStringQuotes( parameter );
26
27 Operator_New( *compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr(), "", parameter, Type( DEF_OBJECT, *compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr() ) );
28
29 free( parameter );
30
31 //mov reg,rax
32 compiler.codeGenerator.op_mov_RR( reg, REG_RAX );
33
34 /////////////////////////////////////////////
35 ////// レジスタ資源を復元
36 RESTORE_REGISTER_RESOURCE
37 }////////////////////////////////////////////
38}
39
40void SetUseRegFromRax(int type,int UseReg,int XmmReg){
41 if(IsRealNumberType(type)){
42 //実数型
43 if(XmmReg==REG_XMM4){
44 if(type==DEF_DOUBLE){
45 //movsd qword ptr[rsp+offset],xmm0 ※スタックフレームを利用
46 pobj_sf->push(REG_XMM0,sizeof(double));
47 }
48 if(type==DEF_SINGLE){
49 //movss dword ptr[rsp+offset],xmm0 ※スタックフレームを利用
50 pobj_sf->push(REG_XMM0,sizeof(float));
51 }
52 }
53 else{
54 if(type==DEF_DOUBLE){
55 //movsd xmm_reg,xmm0
56 compiler.codeGenerator.op_movsd_RR(XmmReg,REG_XMM0);
57 }
58 else if(type==DEF_SINGLE){
59 //movss xmm_reg,xmm0
60 compiler.codeGenerator.op_movss_RR(XmmReg,REG_XMM0);
61 }
62 }
63 }
64 else{
65 //整数型
66 if(UseReg==REG_R14){
67 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
68 pobj_sf->push(REG_RAX);
69 }
70 else{
71 //mov reg,rax
72 compiler.codeGenerator.op_mov_RR(UseReg,REG_RAX);
73 }
74 }
75}
76
77void ExtendRegToBigType( int reg, int bigBasicType, int baseBasicType ){
78 switch( Type::GetBasicSize( bigBasicType ) ){
79 case sizeof(_int64):
80 ExtendTypeTo64(baseBasicType,reg);
81 break;
82 case sizeof(long):
83 ExtendTypeTo32(baseBasicType,reg);
84 break;
85 case sizeof(short):
86 ExtendTypeTo16(baseBasicType,reg);
87 break;
88 }
89}
90
91
92bool VarToReg( RELATIVE_VAR &relativeVar, const Type &baseType, Type &resultType ){
93 int UseReg=pobj_reg->GetNextReg();
94 int XmmReg=pobj_reg->GetNextXmmReg();
95
96 //大きな型への暗黙の変換
97 int bigType = AutoBigCast(baseType.GetBasicType(),resultType.GetBasicType());
98
99 if(resultType.GetBasicType()&FLAG_PTR){
100 //配列ポインタ
101 resultType.SetBasicType( GetPtrType(resultType.GetBasicType()^FLAG_PTR) );
102
103 SetVarPtrToReg(UseReg,&relativeVar);
104 }
105 else if(resultType.IsReal()){
106 //実数型
107 if( resultType.IsDouble() )
108 SetXmmReg_DoubleVariable(&relativeVar,XmmReg);
109 if( resultType.IsSingle() )
110 SetXmmReg_SingleVariable(&relativeVar,XmmReg);
111 }
112 else if( resultType.IsWhole() || resultType.IsObject()){
113 //整数型
114 SetReg_WholeVariable(resultType,&relativeVar,UseReg);
115 }
116 else if( resultType.IsStruct() ){
117 //構造体ポインタをUseRegへ格納(構造体は値型)
118 SetVarPtrToReg(UseReg,&relativeVar);
119 }
120 else{
121 return false;
122 }
123
124 if( resultType.GetBasicType() != bigType ){
125 // 大きな型へ変換された場合
126 // ※レジスタの値をキャストする
127 ExtendRegToBigType( UseReg, bigType, resultType.GetBasicType() );
128
129 resultType.SetBasicType( bigType );
130 }
131
132 return true;
133}
134bool TermMemberOpe( const Type &leftType, const Type &baseType, Type &resultType, const char *termFull, const char *termLeft, const char *member )
135{
136 const CClass &objClass = leftType.GetClass();
137
138 int UseReg=pobj_reg->GetNextReg();
139 int XmmReg=pobj_reg->GetNextXmmReg();
140
141
142 if( GetMemberType( leftType, member, resultType, 0, false ) ){
143 // メンバが見つかったとき
144
145 //オブジェクトポインタをr11にコピー
146 compiler.codeGenerator.op_mov_RR( REG_R11, UseReg );
147
148 RELATIVE_VAR relativeVar;
149 relativeVar.dwKind=VAR_DIRECTMEM;
150
151 if( !_member_offset(
152 true, //エラー表示あり
153 false, //読み込み専用
154 leftType,
155 member,&relativeVar,resultType,0)){
156 return false;
157 }
158
159 if( !VarToReg( relativeVar, baseType, resultType ) ){
160 SetError(11,termFull,cp);
161 }
162
163 return true;
164 }
165
166
167 ///////////////////////////////////////////////////////////////////
168 // 動的メソッドを検索
169 ///////////////////////////////////////////////////////////////////
170 vector<const UserProc *> userProcs;
171
172 char methodName[VN_SIZE], lpPtrOffset[VN_SIZE], parameter[VN_SIZE], dummy[1];
173 ReferenceKind refType;
174 lstrcpy( methodName, member );
175 GetVarFormatString(methodName,parameter,lpPtrOffset,dummy,refType);
176
177 objClass.GetMethods().Enum( methodName, userProcs );
178 if(userProcs.size()){
179 //オーバーロードを解決
180 const UserProc *pUserProc = OverloadSolutionWithStrParam(termFull,userProcs,parameter,termLeft);
181
182 if( pUserProc ){
183
184 resultType = pUserProc->ReturnType();
185
186
187 //////////////////////////////////////////////////////
188 ///// レジスタ資源のバックアップ
189 { BACKUP_REGISTER_RESOURCE
190 //////////////////////////////////////////////////////
191
192 //オブジェクトポインタをスタックに入れておく
193 //mov qword ptr[rsp+offset],reg ※スタックフレームを利用
194 pobj_sf->push( UseReg );
195
196 if( !Opcode_CallProc(parameter,pUserProc,PROCFLAG_NEW,termLeft ) ){
197 //レジスタ資源を復元
198 RESTORE_REGISTER_RESOURCE
199
200 return false;
201 }
202
203 pobj_sf->pop();
204
205 /////////////////////
206 // 戻り値の処理
207 /////////////////////
208
209 //大きな型への暗黙の変換
210 int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() );
211
212 if( resultType.GetBasicType() != bigType ){
213 // 大きな型へ変換された場合
214 // ※レジスタの値をキャストする
215 ExtendRegToBigType( REG_RAX, bigType, resultType.GetBasicType() );
216
217 resultType.SetBasicType( bigType );
218 }
219
220 SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
221
222 // 型パラメータを解決
223 ResolveFormalGenericTypeParameter( resultType, leftType, pUserProc );
224
225
226 /////////////////////////////////////////////
227 ////// レジスタ資源を復元
228 RESTORE_REGISTER_RESOURCE
229 }////////////////////////////////////////////
230
231 return true;
232 }
233 }
234
235 return false;
236}
237bool TermOpe( const char *term, const Type &baseType, Type &resultType, bool &isLiteral, BOOL *pbUseHeap, bool isWantObject, bool *pIsClassName, bool isProcedureCallOnly ){
238 char parameter[VN_SIZE];
239
240 // Withを解決
241 char termFull[VN_SIZE];
242 if(term[0]=='.'){
243 GetWithName(termFull);
244 lstrcat(termFull,term);
245 }
246 else lstrcpy(termFull,term);
247
248 char termLeft[VN_SIZE];
249 lstrcpy(termLeft,termFull);
250
251 // パース
252 char member[VN_SIZE];
253 ReferenceKind refType;
254 if( SplitMemberName( termFull, termLeft, member, refType ) ){
255 ///////////////////////////////////////////////////////////////////
256 // オブジェクトとメンバに分解できるとき
257 // termLeft.member
258 ///////////////////////////////////////////////////////////////////
259
260 isLiteral = false;
261
262 // オブジェクト側の型を取得
263 bool isClassName = false;
264 Type leftType;
265 if( GetTermType( termLeft, leftType, isLiteral, &isClassName ) ){
266 if( isClassName == false && compiler.GetObjectModule().meta.GetBlittableTypes().IsExist( leftType ) ){
267 // 左側のオブジェクト部分がBlittable型のとき
268
269 char temporary[VN_SIZE];
270 lstrcpy( temporary, termLeft );
271 sprintf( termLeft, "%s(%s)",
272 compiler.GetObjectModule().meta.GetBlittableTypes().Find( leftType ).GetCreateStaticMethodFullName().c_str(),
273 temporary );
274 }
275 }
276
277 if( !TermOpe( termLeft, baseType, leftType, isLiteral, pbUseHeap, true, &isClassName ) ){
278 goto globalArea;
279 }
280
281 if( isClassName ){
282 // 静的メンバ/メソッドの場合
283 goto globalArea;
284 }
285
286 if( !leftType.HasMember() ){
287 // メンバを持たない型の場合
288 return false;
289 }
290
291 return TermMemberOpe( leftType, baseType, resultType, termFull, termLeft, member );
292 }
293globalArea:
294
295 //////////////////////////////////////////////
296 // クラス名かどうかをチェック(静的メンバ用)
297 //////////////////////////////////////////////
298
299 if( pIsClassName ){
300 if( compiler.GetObjectModule().meta.GetClasses().Find( termFull ) ){
301 *pIsClassName = true;
302 return true;
303 }
304 }
305
306
307 /////////////////////////////////////////////////////////////////
308 // グローバル属性エリア
309 /////////////////////////////////////////////////////////////////
310
311 int UseReg=pobj_reg->GetNextReg();
312 int XmmReg=pobj_reg->GetNextXmmReg();
313
314
315 if(lstrcmpi(termFull,"This")==0 && isProcedureCallOnly == false ){
316 //Thisオブジェクト
317 resultType.SetType( DEF_OBJECT, compiler.pCompilingClass );
318
319 SetThisPtrToReg( UseReg );
320
321 isLiteral = false;
322
323 return true;
324 }
325
326
327 //////////////////////////////////////
328 // 関数(DLL、ユーザー定義、組み込み)
329 //////////////////////////////////////
330 char procName[VN_SIZE];
331 char temporary[8192];
332
333 int i2=GetCallProcName(termFull,procName);
334 if(termFull[i2]=='('){
335 int i4=GetStringInPare_RemovePare(parameter,termFull+i2+1);
336
337 void *pInfo;
338 int idProc=GetProc(procName,(void **)&pInfo);
339
340 if(idProc){
341 //閉じカッコ")"に続く文字がNULLでないとき
342 if(termFull[i2+1+i4+1]!='\0'){
343 SetError(42,NULL,cp);
344 }
345
346
347 //////////////////////////////////////////////////////
348 ///// レジスタ資源のバックアップ
349 { BACKUP_REGISTER_RESOURCE
350 //////////////////////////////////////////////////////
351
352
353 ////////////////
354 // 呼び出し
355 ////////////////
356
357 CallProc(idProc,pInfo,procName,parameter,resultType);
358
359
360 /////////////////////
361 // 戻り値の処理
362 /////////////////////
363
364 //大きな型への暗黙の変換
365 int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() );
366
367 if( resultType.GetBasicType() != bigType ){
368 // 大きな型へ変換された場合
369 // ※レジスタの値をキャストする
370 ExtendRegToBigType( REG_RAX, bigType, resultType.GetBasicType() );
371
372 resultType.SetBasicType( bigType );
373 }
374
375 SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
376
377 /////////////////////////////////////////////
378 ////// レジスタ資源を復元
379 RESTORE_REGISTER_RESOURCE
380 }////////////////////////////////////////////
381
382 if(resultType.IsStruct()){
383 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
384 //※後にfreeする必要あり
385 // TODO: 解放はGCに任せる
386 *pbUseHeap = 1;
387 }
388
389 isLiteral = false;
390
391 return true;
392 }
393
394 ConstMacro *pConstMacro = compiler.GetObjectModule().meta.GetGlobalConstMacros().Find( procName );
395 if( pConstMacro )
396 {
397 if( pConstMacro->GetCalcBuffer( parameter, temporary ) )
398 {
399 /////////////////////////
400 // マクロ関数
401 /////////////////////////
402
403 //閉じカッコ")"に続く文字がNULLでないときはエラーにする
404 if(termFull[i2+1+i4+1]!='\0') SetError(42,NULL,cp);
405
406 //マクロ関数の場合
407 NumOpe(&UseReg, temporary,Type(),resultType);
408
409 if(!IS_LITERAL(resultType.GetIndex())){
410 //リテラル値ではなかったとき
411 isLiteral = false;
412 }
413
414 return true;
415 }
416 }
417 }
418 else if( isProcedureCallOnly ){
419 // 関数呼び出し以外は受け付けない
420 return false;
421 }
422
423
424 ////////////////////////////////
425 // インデクサ(getアクセサ)
426 ////////////////////////////////
427
428 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
429 GetArrayElement(termFull,VarName,ArrayElements);
430 if(ArrayElements[0]){
431 GetVarType(VarName,resultType,false);
432 if( resultType.IsObject() ){
433 CallIndexerGetterProc(UseReg,resultType,VarName,ArrayElements,resultType);
434
435 isLiteral = false;
436
437 return true;
438 }
439 }
440
441
442 ////////////////////////////////
443 // 変数
444 ////////////////////////////////
445
446 RELATIVE_VAR relativeVar;
447 if(GetVarOffset(
448 false, //エラー表示なし
449 false, //読み込み専用
450 termFull,
451 &relativeVar,resultType)){
452 //////////
453 // 変数
454 //////////
455
456 if( !VarToReg( relativeVar, baseType, resultType ) ){
457 SetError(11,termFull,cp);
458 }
459
460 isLiteral = false;
461
462 return true;
463 }
464
465/*
466 ////////////////////////////////
467 // 型名
468 ////////////////////////////////
469
470 if( compiler.StringToType( termFull, resultType ) ){
471 resultType.SetBasicType( resultType.GetBasicType() | FLAG_CAST );
472 return true;
473 }*/
474
475
476 /////////////////////////////////
477 // プロパティ用のメソッド
478 /////////////////////////////////
479
480 //配列要素を排除
481 GetArrayElement(termFull,VarName,ArrayElements);
482
483 if(GetSubHash(VarName,0)){
484
485 //////////////////////////////////////////////////////
486 ///// レジスタ資源のバックアップ
487 { BACKUP_REGISTER_RESOURCE
488 //////////////////////////////////////////////////////
489
490 CallPropertyMethod(termFull,NULL,resultType);
491
492 //大きな型への暗黙の変換
493 int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() );
494
495 if( resultType.GetBasicType() != bigType ){
496 // 大きな型へ変換された場合
497 // ※レジスタの値をキャストする
498 ExtendRegToBigType( REG_RAX, bigType, resultType.GetBasicType() );
499
500 resultType.SetBasicType( bigType );
501 }
502
503 SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg);
504
505 /////////////////////////////////////////////
506 ////// レジスタ資源を復元
507 RESTORE_REGISTER_RESOURCE
508 }////////////////////////////////////////////
509
510 if(resultType.IsStruct()){
511 //構造体が戻ったときはヒープ領域にインスタンスが格納されている
512 //※後にfreeする必要あり
513 // TODO: 解放はGCに任せる
514 *pbUseHeap = 1;
515 }
516
517 isLiteral = false;
518
519 return true;
520 }
521
522
523 return false;
524}
525
526bool _numope( int *pReg,
527 const char *expression,
528 const Type &baseType,
529 Type &resultType,
530 BOOL *pbUseHeap )
531{
532
533 int i,i2,i3;
534 char temporary[1024],temp2[1024];
535
536 if(expression[0]=='\0'){
537 SetError(1,NULL,cp);
538 return false;
539 }
540
541 if( !baseType.IsNull() && expression[0] == '[' ){
542 // リテラル配列の場合
543
544 if( !baseType.IsPointer() ){
545 SetError(1,NULL,cp);
546 return false;
547 }
548 Type tempBaseType( baseType );
549 tempBaseType.PtrLevelDown();
550
551 char *buffer = (char *)malloc( lstrlen( expression ) + 1 );
552 lstrcpy( buffer, expression );
553 RemoveStringBracket( buffer );
554
555 void *binary = malloc( 1 );
556 int num = 0;
557
558 i = 0;
559 while( buffer[i] ){
560 i = GetOneParameter( buffer, i, temporary );
561 if( buffer[i] == ',' ){
562 i++;
563 }
564
565 Type resultType;
566 _int64 i64data;
567 if( !StaticCalculation( true, temporary, tempBaseType.GetBasicType(), &i64data, resultType ) ){
568 return false;
569 }
570 if( !resultType.IsWhole() ){
571 // TODO: 実数に未対応
572 SetError();
573 return false;
574 }
575
576 binary = realloc( binary, ( num + 1 ) * tempBaseType.GetSize() );
577 memcpy( (char *)binary + (num * tempBaseType.GetSize()), &i64data, tempBaseType.GetSize() );
578 num++;
579 }
580
581 i2 = compiler.GetObjectModule().dataTable.AddBinary( binary, num * tempBaseType.GetSize() );
582
583 //mov reg,i2
584 compiler.codeGenerator.op_mov_RV(sizeof(_int64),*pReg,i2, Schedule::DataTable );
585
586 free( buffer );
587
588 resultType = baseType;
589
590 return true;
591 }
592
593 bool isLiteralCalculation;
594 if( !NumOpe_GetType( expression, baseType, resultType, &isLiteralCalculation ) )
595 {
596 return false;
597 }
598 if( isLiteralCalculation )
599 {
600 //右辺値が数値の定数式の場合
601 _int64 i64data;
602 StaticCalculation(true, expression,baseType.GetBasicType(),&i64data,resultType);
603
604 if(resultType.IsReal()){
605 if(baseType.IsReal()) resultType=baseType;
606
607 int xmmReg = pobj_reg->GetNextXmmReg();
608 *pReg = xmmReg;
609
610 if(resultType.IsDouble()){
611 i3 = compiler.GetObjectModule().dataTable.Add( i64data );
612
613 //movlpd xmm_reg,qword ptr[data table offset]
614 compiler.codeGenerator.op_movlpd_RM( xmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
615 }
616 if(resultType.IsSingle()){
617 double dbl;
618 memcpy(&dbl,&i64data,sizeof(_int64));
619
620 float flt;
621 int i32data;
622 flt=(float)dbl;
623 memcpy(&i32data,&flt,sizeof(long));
624
625 i3 = compiler.GetObjectModule().dataTable.Add( i32data );
626
627 //movss xmm_reg,dword ptr[data table offset]
628 compiler.codeGenerator.op_movss_RM( xmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
629 }
630 }
631 else{
632 if(!resultType.Is64()){
633 //整数(符号有り/無し)
634
635 i3=(long)i64data;
636
637 if(resultType.GetBasicSize()==sizeof(char)) i3=i3&0x000000FF;
638 if(resultType.GetBasicSize()==sizeof(short)) i3=i3&0x0000FFFF;
639
640 i64data=(_int64)i3;
641 }
642
643 //mov reg,i64data
644 compiler.codeGenerator.op_mov_RV64(*pReg,i64data);
645 }
646 return true;
647 }
648
649 if(expression[0]==1&& expression[1]==ESC_NEW ){
650 //New演算子(オブジェクト生成)
651
652 if( pobj_BlockReg->check(REG_RAX) ){
653 SetError();
654 }
655
656 //////////////////////////////////////////////////////
657 ///// レジスタ資源のバックアップ
658 { BACKUP_REGISTER_RESOURCE
659 //////////////////////////////////////////////////////
660
661 if( !Operator_New( expression+2, baseType, resultType ) ){
662 return false;
663 }
664
665 /////////////////////////////////////////////
666 ////// レジスタ資源を復元
667 RESTORE_REGISTER_RESOURCE
668 }////////////////////////////////////////////
669
670 //mov reg,rax
671 compiler.codeGenerator.op_mov_RR( *pReg, REG_RAX );
672
673 return true;
674 }
675
676
677 /////////////////////////////////
678 // 式要素を逆ポーランド式で取得
679 /////////////////////////////////
680
681 char *values[255];
682 long calc[255];
683 long stack[255];
684 int pnum;
685 if(!GetNumOpeElements(expression,&pnum,values,calc,stack)){
686 for(i=0;i<pnum;i++){
687 if(values[i]) HeapDefaultFree(values[i]);
688 }
689 return 0;
690 }
691
692
693
694 ////////////////////////////////
695 // 演算部分のコード生成を開始
696 ////////////////////////////////
697
698 BOOL bError;
699 bError=0;
700
701 //リテラル値のみの計算かどうかを判別するためのフラグ
702 BOOL bLiteralCalculation=1;
703
704 double dbl;
705 int sp;
706 int type_stack[255];
707 LONG_PTR index_stack[255];
708 bool isNothing_stack[255];
709 BOOL bUseHeap[255];
710 _int64 i64data;
711 int UseReg,XmmReg;
712 BOOL bXmm;
713 for(i=0,sp=0;i<pnum;i++){
714 int idCalc;
715 idCalc=calc[i]%100;
716
717 if(idCalc){
718 if(type_stack[sp-2]==DEF_OBJECT){
719 if( idCalc == CALC_AS
720 && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
721 && index_stack[sp-1] == index_stack[sp-2]
722 || isNothing_stack[sp-2] ){
723 // 同一の型、またはNothingに対するAsはAs演算子を呼び出さない
724 }
725 else if( idCalc == CALC_AS
726 && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST )
727 && ( ((CClass *)index_stack[sp-1])->IsEqualsOrSubClass( (CClass *)index_stack[sp-2] ) || ((CClass *)index_stack[sp-2])->IsEqualsOrSubClass( (CClass *)index_stack[sp-1] )
728 )){
729 // ダウンキャストを許可する
730 }
731 else if( idCalc == CALC_AS
732 && type_stack[sp-1] == ( DEF_OBJECT | FLAG_CAST ) && ((CClass *)index_stack[sp-1])->IsInterface()
733 ){
734 // インターフェイスへのキャスト
735 // TODO: 実装
736 CastToInterface( pobj_reg->GetLockingReg(), REG_R15, *(CClass *)index_stack[sp-2], *(CClass *)index_stack[sp-1] );
737 }
738 else{
739 //オーバーロードされたオペレータを呼び出す
740 i2=CallOperatorProc(idCalc,baseType,type_stack,index_stack,bUseHeap,sp);
741 if(i2==0){
742 if(idCalc==CALC_EQUAL) lstrcpy(temp2,"==");
743 else GetCalcName(idCalc,temp2);
744 sprintf(temporary,"Operator %s",temp2);
745 SetError(27,temporary,cp);
746 goto error;
747 }
748 else if(i2==-1) goto error;
749
750 continue;
751 }
752 }
753
754 if(!CheckCalcType(idCalc,type_stack,sp)) goto error;
755 }
756
757 switch(idCalc){
758 //数値
759 case 0:
760 index_stack[sp]=-1;
761 isNothing_stack[sp] = false;
762 bUseHeap[sp]=0;
763
764 UseReg=pobj_reg->GetNextReg();
765 XmmReg=pobj_reg->GetNextXmmReg();
766
767 bXmm=0;
768
769 char *term;
770 term=values[i];
771
772 if( calc[i+1]%100 == CALC_AS ){
773 // As演算子の右辺値
774 //型名
775 if( compiler.StringToType( term, resultType ) ){
776 resultType.SetBasicType( resultType.GetBasicType() | FLAG_CAST );
777 }
778 else{
779 SetError(3, term, cp );
780 goto error;
781 }
782
783 type_stack[sp] = resultType.GetBasicType();
784 index_stack[sp] = resultType.GetIndex();
785 sp++;
786
787 break;
788 }
789
790 if(term[0]=='\"'){
791 //リテラル文字列
792 if(!RemoveStringQuotes(term)){
793 SetError(43,NULL,cp);
794 goto error;
795 }
796 i3=lstrlen(term);
797StrLiteral:
798
799 if( baseType.IsObject() || baseType.IsNull() ){
800 //要求タイプがオブジェクト、または未定のとき
801
802 //String型オブジェクトを生成
803 NewStringObject(UseReg,term);
804
805 type_stack[sp]=DEF_OBJECT;
806 index_stack[sp]=(LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr();
807 bLiteralCalculation=0;
808
809 if(bXmm) pobj_reg->LockXmmReg();
810 else pobj_reg->LockReg();
811
812 sp++;
813 break;
814 }
815
816 type_stack[sp]=typeOfPtrChar;
817 bLiteralCalculation=0;
818
819 i2 = compiler.GetObjectModule().dataTable.AddString( term, i3 );
820
821 //mov reg,i2
822 compiler.codeGenerator.op_mov_RV(sizeof(_int64),UseReg,i2, Schedule::DataTable);
823
824 if(UseReg==REG_R14){
825 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
826 pobj_sf->push(REG_R14);
827 }
828 }
829 else if((term[0]=='e'||term[0]=='E')&&
830 (term[1]=='x'||term[1]=='X')&&
831 term[2]=='\"'){
832 //拡張版リテラル文字列(エスケープシーケンス可能)
833 if(!RemoveStringQuotes(term+2)){
834 SetError(43,NULL,cp);
835 goto error;
836 }
837 i3=FormatString_EscapeSequence(term+2);
838 term+=2;
839
840 goto StrLiteral;
841 }
842 else if(IsVariableTopChar(term[0])||
843 term[0]=='*'||
844 (term[0]=='.'&&IsVariableTopChar(term[1]))){
845 //////////////////
846 // 何らかの識別子
847
848 bool isLiteral;
849 if( TermOpe( term, baseType, resultType, isLiteral, &bUseHeap[sp] ) ){
850 if(resultType.IsNull()){
851 //戻り値が存在しないとき
852 for(i2=0;;i2++){
853 if(term[i2]=='('||term[i2]=='\0'){
854 term[i2]=0;
855 break;
856 }
857 }
858 SetError(38,term,cp);
859
860 goto error;
861 }
862
863 type_stack[sp] = resultType.GetBasicType();
864 index_stack[sp] = resultType.GetIndex();
865
866 if( !isLiteral ){
867 bLiteralCalculation=0;
868 }
869
870 if( resultType.GetBasicType() & FLAG_CAST ){
871 // 型名のみ
872 SetError();
873 }
874 else{
875 if( resultType.IsReal() == false && UseReg==REG_R14 ){
876 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
877 pobj_sf->push(REG_R14);
878 }
879 if( resultType.IsReal() && XmmReg==REG_XMM4 ){
880 if(resultType.IsDouble()){
881 //movsd qword ptr[rsp+offset],xmm4 ※スタックフレームを利用
882 pobj_sf->push(REG_XMM4,sizeof(double));
883 }
884 if(resultType.IsSingle()){
885 //movss dword ptr[rsp+offset],xmm4 ※スタックフレームを利用
886 pobj_sf->push(REG_XMM4,sizeof(float));
887 }
888 }
889
890 if( resultType.IsReal() ){
891 pobj_reg->LockXmmReg();
892 }
893 else{
894 pobj_reg->LockReg();
895 }
896 }
897
898 sp++;
899 break;
900 }
901
902
903 // Nothing
904 if( lstrcmp( term, "Nothing" ) == 0 ){
905 isNothing_stack[sp] = true;
906
907 type_stack[sp] = DEF_OBJECT;
908 if( baseType.IsObject() ){
909 index_stack[sp] = baseType.GetIndex();
910 }
911 else{
912 index_stack[sp] = (LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetObjectClassPtr();
913 }
914
915 bLiteralCalculation = 0;
916
917 //xor reg,reg
918 compiler.codeGenerator.op_zero_reg( UseReg );
919
920 if(UseReg==REG_R14){
921 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
922 pobj_sf->push(REG_R14);
923 }
924
925 pobj_reg->LockReg();
926 sp++;
927 break;
928 }
929
930
931 //////////////
932 // 定数の場合
933 //////////////
934
935 i3 = compiler.GetObjectModule().meta.GetGlobalConsts().GetBasicType(term);
936 if(i3){
937 if( compiler.GetObjectModule().meta.GetGlobalConsts().IsStringPtr( term ) ){
938 //リテラル文字列
939
940 double dbl = compiler.GetObjectModule().meta.GetGlobalConsts().GetDoubleData(term);
941 memcpy(&i64data,&dbl,sizeof(double));
942
943 //バイト数
944 i3=lstrlen((char *)i64data);
945
946 memcpy(term,(char *)i64data,i3);
947 term[i3]=0;
948 goto StrLiteral;
949 }
950
951 type_stack[sp] = i3;
952 if(IsRealNumberType(i3)){
953 //実数
954 double dbl = compiler.GetObjectModule().meta.GetGlobalConsts().GetDoubleData(term);
955 memcpy(&i64data,&dbl,sizeof(double));
956 goto Literal;
957 }
958 else if(IsWholeNumberType(i3)){
959 //整数
960 i64data = compiler.GetObjectModule().meta.GetGlobalConsts().GetWholeData(term);
961 goto Literal;
962 }
963 /*else if(i3==DEF_STRING){
964 //リテラル文字列
965
966 //バイト数
967 i3=(int)dbl;
968
969 memcpy(term,temporary,i3);
970 goto StrLiteral;
971 }*/
972 else{
973 SetError(1,NULL,0);
974 goto error;
975 }
976 }
977
978
979 //該当する識別子が見当たらないときはエラー扱いにする
980 bError=1;
981 SetError(3,term,cp);
982 type_stack[sp]=DEF_DOUBLE;
983 }
984 else{
985 //リテラル値
986 type_stack[sp]=GetLiteralValue(term,&i64data,baseType.GetBasicType());
987Literal:
988 if(type_stack[sp]==DEF_DOUBLE){
989 //64ビット浮動小数型
990 bXmm=1;
991
992 if(XmmReg==REG_XMM4){
993 //mov r14,i64data
994 compiler.codeGenerator.op_mov_RV64(REG_R14,i64data);
995
996
997 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
998 pobj_sf->push(REG_R14);
999 }
1000 else{
1001 i3 = compiler.GetObjectModule().dataTable.Add( i64data );
1002
1003 //movlpd xmm_reg,qword ptr[data table offset]
1004 compiler.codeGenerator.op_movlpd_RM( XmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
1005 }
1006 }
1007 else if(type_stack[sp]==DEF_SINGLE){
1008 //32ビット浮動小数型
1009 bXmm=1;
1010
1011 float flt;
1012 int i32data;
1013 memcpy(&dbl,&i64data,sizeof(double));
1014 flt=(float)dbl;
1015 memcpy(&i32data,&flt,sizeof(long));
1016
1017 if(XmmReg==REG_XMM4){
1018 SetError(); // TODO: 未実装
1019 //push term
1020 //compiler.codeGenerator.op_push_value(i32data);
1021 }
1022 else{
1023 i3=compiler.GetObjectModule().dataTable.Add( i32data );
1024
1025 //movss xmm_reg,dword ptr[data table offset]
1026 compiler.codeGenerator.op_movss_RM( XmmReg, 0, i3, MOD_DISP32, Schedule::DataTable );
1027 }
1028 }
1029 else{
1030 //整数
1031
1032 index_stack[sp]=GetLiteralIndex(i64data);
1033
1034 //mov reg,i64data
1035 compiler.codeGenerator.op_mov_RV64(UseReg,i64data);
1036
1037 if(UseReg==REG_R14){
1038 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
1039 pobj_sf->push(REG_R14);
1040 }
1041 }
1042 }
1043
1044 if(bXmm) pobj_reg->LockXmmReg();
1045 else pobj_reg->LockReg();
1046
1047 sp++;
1048 break;
1049
1050 //論理演算子
1051 case CALC_XOR:
1052 case CALC_OR:
1053 case CALC_AND:
1054 if(!CalcTwoTerm_Logical(idCalc,type_stack,index_stack,&sp)) goto error;
1055 break;
1056 case CALC_NOT:
1057 //value[sp-1]=Not value[sp-1]
1058 //NOT演算子
1059 if(!Calc_Not(type_stack,sp)) goto error;
1060 break;
1061
1062 //比較演算子
1063 case CALC_PE: //value[sp-2] <= value[sp-1]
1064 case CALC_QE: //value[sp-2] >= value[sp-1]
1065 case CALC_P: //value[sp-2] < value[sp-1]
1066 case CALC_Q: //value[sp-2] > value[sp-1]
1067 case CALC_NOTEQUAL: //value[sp-2] <> value[sp-1]
1068 case CALC_EQUAL: //value[sp-2] = value[sp-1]
1069 if(!CalcTwoTerm_Relational(idCalc,type_stack,index_stack,&sp)) goto error;
1070 break;
1071
1072 //ビットシフト
1073 case CALC_SHL: //value[sp-2] << value[sp-1]
1074 case CALC_SHR: //value[sp-2] >> value[sp-1]
1075 if(!Calc_Shift(idCalc,type_stack,&sp)) goto error;
1076 break;
1077
1078 //算術演算
1079 case CALC_ADDITION:
1080 case CALC_SUBTRACTION:
1081 case CALC_PRODUCT:
1082 if(!CalcTwoTerm_Arithmetic(idCalc,type_stack,index_stack,&sp)) goto error;
1083 break;
1084 case CALC_MOD:
1085 //value[sp-2]%=value[sp-1]
1086 //剰余演算
1087 if(!Calc_Mod(type_stack,index_stack,&sp)) goto error;
1088 break;
1089 case CALC_QUOTIENT:
1090 //value[sp-2]/=value[sp-1];
1091 //除算
1092 if(!Calc_Divide(type_stack,&sp,baseType.GetBasicType())) goto error;
1093 break;
1094 case CALC_INTQUOTIENT:
1095 //value[sp-2]/=value[sp-1]
1096 //整数除算
1097 if(!Calc_IntDivide(type_stack,index_stack,&sp)) goto error;
1098 break;
1099 case CALC_MINUSMARK:
1100 //value[sp-1]=-value[sp-1]
1101 //符号反転
1102 if(!Calc_MinusMark(type_stack,sp)) goto error;
1103 break;
1104 case CALC_POWER:
1105 //べき乗演算(浮動小数点演算のみ)
1106 if(!Calc_Power(type_stack,&sp)) goto error;
1107 break;
1108 case CALC_AS:
1109 //キャスト
1110 if(!Calc_Cast(type_stack,index_stack,&sp)) goto error;
1111 break;
1112 case CALC_BYVAL:
1113 //ポインタ型→参照型
1114 if( PTR_LEVEL( type_stack[sp-1] ) <= 0 ){
1115 //ポインタ型ではないとき
1116 SetError( 3, NULL, cp );
1117 goto error;
1118 }
1119
1120 type_stack[sp-1] = PTR_LEVEL_DOWN( type_stack[sp-1] );
1121
1122 break;
1123
1124 default:
1125 SetError(300,NULL,cp);
1126 goto error;
1127 }
1128 }
1129
1130 if(bError) goto error;
1131
1132 if(sp!=1){
1133 SetError(1,NULL,cp);
1134 goto error;
1135 }
1136
1137 if(bLiteralCalculation){
1138 SetError();
1139 }
1140 else{
1141 //右辺値が数値の定数式ではないとき
1142 if(IS_LITERAL(index_stack[0])) index_stack[0]=-1;
1143 }
1144
1145 if(pbUseHeap) *pbUseHeap=bUseHeap[0];
1146
1147 if(IsRealNumberType(type_stack[0]))
1148 *pReg=pobj_reg->UnlockXmmReg();
1149 else
1150 *pReg=pobj_reg->UnlockReg();
1151
1152
1153 resultType.SetType( type_stack[0], index_stack[0] );
1154
1155 bool isSuccessful = true;
1156 goto finish;
1157
1158
1159
1160 //////////////////
1161 // エラー処理
1162 //////////////////
1163
1164error:
1165
1166 isSuccessful = false;
1167 goto finish;
1168
1169
1170
1171
1172finish:
1173
1174 for(i=0;i<pnum;i++){
1175 if(values[i]) HeapDefaultFree(values[i]);
1176 }
1177
1178 return isSuccessful;
1179}
1180
1181bool NumOpe( int *pReg,
1182 const char *expression,
1183 const Type &baseType,
1184 Type &resultType,
1185 BOOL *pbUseHeap )
1186{
1187 BOOL bInitRegSwitch=0;
1188 if(!pobj_reg){
1189 bInitRegSwitch=1;
1190
1191 //作業用レジスタを取得
1192 pobj_reg=new CRegister(*pReg);
1193 }
1194
1195 //エラー時の復旧用
1196 CRegister objReg_Backup;
1197 objReg_Backup=*pobj_reg;
1198
1199 *pReg = pobj_reg->GetNextReg();
1200
1201
1202 bool result = _numope( pReg, expression, baseType, resultType, pbUseHeap );
1203
1204
1205 if( !result )
1206 {
1207 *pobj_reg=objReg_Backup;
1208 }
1209
1210 if(bInitRegSwitch){
1211 //整合性をチェック(バグ回避)
1212 if( result )
1213 {
1214 pobj_reg->bug_check();
1215 }
1216
1217 //作業レジスタを解放
1218 delete pobj_reg;
1219 pobj_reg=0;
1220 }
1221
1222 return result;
1223}
Note: See TracBrowser for help on using the repository browser.