source: dev/trunk/abdev/BasicCompiler64/Compile_Statement.cpp@ 338

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

メソッドの重複チェックで戻り値も判定するよにうにした

File size: 21.0 KB
RevLine 
[206]1#include "stdafx.h"
2
[183]3#include <jenga/include/smoothie/LexicalAnalysis.h>
4
5#include <Compiler.h>
6
[3]7#include "../BasicCompiler_Common/common.h"
8#include "Opcode.h"
9
[129]10void OpcodeOthers(const char *Command){
[3]11 int i,i2;
12
[122]13 char leftTerm[8192];
14 int lastParePos = 0;
[3]15 for(i=0;;i++){
[122]16 if(Command[i]=='\"'){
17 //ダブルクォートは不正なのでエラー扱い
18 leftTerm[i]=0;
19 SetError(3,leftTerm,cp);
20 return;
21 }
22
23 if(Command[i]=='('){
24 lastParePos = i;
25 i2=GetStringInPare(leftTerm+i,Command+i);
[3]26 i+=i2-1;
27 continue;
28 }
[122]29 if(Command[i]=='['){
30 i2=GetStringInBracket(leftTerm+i,Command+i);
31 i+=i2-1;
[3]32 continue;
33 }
[122]34 if(Command[i]=='\0'){
35 leftTerm[i] = 0;
[3]36 break;
37 }
[122]38
39 if( IsNumCalcMark( Command, i ) ){
40 leftTerm[i] = 0;
41 break;
42 }
43
44 leftTerm[i]=Command[i];
[3]45 }
46 if(!(
[122]47 IsVariableTopChar(leftTerm[0])||
48 leftTerm[0]=='.'||
49 (leftTerm[0]==1&&leftTerm[1]==ESC_PSMEM)
[3]50 )){
51 SetError(1,NULL,cp);
52 return;
53 }
54
55
[122]56 if(Command[i]=='\0' && lastParePos == 0){
[3]57 //////////////////////////////
58 // パラメータ無しのマクロ検索
59 //////////////////////////////
60
[206]61 const UserProc *pUserProc=GetSubHash(Command);
[3]62
63 //GetSubHash内でエラー提示が行われた場合
[75]64 if(pUserProc==(UserProc *)-1) return;
[3]65
[75]66 if(pUserProc==0){
[3]67 char temporary[VN_SIZE];
68 lstrcpy(temporary,Command);
69
70 CharUpper(temporary);
[75]71 pUserProc=GetSubHash(temporary);
[3]72
73 //GetSubHash内でエラー提示が行われた場合
[75]74 if(pUserProc==(UserProc *)-1) return;
[3]75 }
76
[75]77 if(pUserProc){
[97]78 if( !pUserProc->IsMacro() ){
79 SetError(10,Command,cp);
80 }
[3]81
[308]82 Opcode_CallProc("",pUserProc,0,"");
[3]83
84 return;
85 }
86 }
87 else if(IsNumCalcMark(Command,i)){
88 //代入演算
89 OpcodeCalc(Command);
90 return;
91 }
92
[122]93 if( pobj_reg ){
94 SetError();
95 }
96 pobj_reg=new CRegister(REG_RAX);
[3]97
[122]98 Type resultType;
99 bool isLiteral;
100 BOOL bUseHeap;
[128]101 bool result = TermOpe( leftTerm, Type(), resultType, isLiteral, &bUseHeap, false, NULL, true );
[3]102
[122]103 delete pobj_reg;
104 pobj_reg = NULL;
[3]105
[122]106 if( result ){
[3]107
108 /////////////////////
109 // 戻り値の処理
110 /////////////////////
111
[75]112 if( resultType.IsStruct() ){
[3]113 //mov r14,rax
[226]114 compiler.codeGenerator.op_mov_RR(REG_R14,REG_RAX);
[3]115
[75]116 FreeTempObject(REG_R14,&resultType.GetClass());
[3]117 }
[122]118
119 //成功
[3]120 return;
121 }
122
[122]123 // 失敗
124 SetError(1, NULL,cp);
[3]125}
126
127void Judgment(char *buffer){
[75]128 int reg=REG_RAX;
129 Type resultType;
[326]130 if( !NumOpe(&reg,buffer,Type(DEF_BOOLEAN),resultType) ){
[75]131 return;
132 }
[3]133
134 int offset;
135
[75]136 if(resultType.IsDouble()){
[3]137 double dbl=0;
[266]138 offset=compiler.GetObjectModule().dataTable.Add( dbl );
[3]139
140 //comisd xmm0,qword ptr[data table offset]
[242]141 compiler.codeGenerator.PutOld(
142 (char)0x66,
143 (char)0x0F,
144 (char)0x2F,
145 (char)0x04,
146 (char)0x25
147 );
148 compiler.codeGenerator.PutOld(
149 (long)offset,
150 Schedule::DataTable
151 );
[3]152 }
[75]153 else if(resultType.IsSingle()){
[3]154 float flt=0;
[266]155 offset=compiler.GetObjectModule().dataTable.Add( flt );
[3]156
157 //comiss xmm0,dword ptr[data table offset]
[242]158 compiler.codeGenerator.PutOld(
159 (char)0x0F,
160 (char)0x2F,
161 (char)0x04,
162 (char)0x25
163 );
164 compiler.codeGenerator.PutOld(
165 (long)offset,
166 Schedule::DataTable
167 );
[3]168 }
169 else{
170 //整数型
171
172 //cmp rax,0
[226]173 compiler.codeGenerator.op_cmp_value(resultType.GetSize(),REG_RAX,0);
[3]174 }
175}
176
177void OpcodeIf(char *Parameter){
[242]178 for(int i=0;;i++){
[3]179 if(Parameter[i]=='\0'){
180 SetError(21,NULL,cp);
181 return;
182 }
183 if(Parameter[i]==1&&Parameter[i+1]==ESC_THEN){
184 Parameter[i]=0;
185 break;
186 }
187 }
188
189 //条件式を実行してフラグをセット
190 Judgment(Parameter);
191
192 //je (endif、または else まで条件ジャンプ)
[254]193 const PertialSchedule *pIfPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
[3]194
195
196 /////////////////////////
197 // If内をコード化
198 /////////////////////////
199
200 //レキシカルスコープをレベルアップ
[308]201 compiler.codeGenerator.lexicalScopes.Start(
202 compiler.codeGenerator.GetNativeCodeSize(),
203 LexicalScope::SCOPE_TYPE_IF
204 );
[3]205
[242]206 int i2=CompileBuffer(ESC_ENDIF,0);
[3]207
208 //レキシカルスコープをレベルダウン
[254]209 compiler.codeGenerator.lexicalScopes.End();
[3]210
211
212 if(i2==ESC_ELSE){
213 //jmp (endifまで)
[254]214 const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
[3]215
[242]216 compiler.codeGenerator.opfix_JmpPertialSchedule( pIfPertialSchedule );
[3]217
218
219
220 /////////////////////////
221 // Else内をコード化
222 /////////////////////////
223
224 //レキシカルスコープをレベルアップ
[308]225 compiler.codeGenerator.lexicalScopes.Start(
226 compiler.codeGenerator.GetNativeCodeSize(),
227 LexicalScope::SCOPE_TYPE_IF
228 );
[3]229
230 CompileBuffer(ESC_ENDIF,0);
231
232 //レキシカルスコープをレベルダウン
[254]233 compiler.codeGenerator.lexicalScopes.End();
[3]234
235
[242]236 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
[3]237 }
238 else{
[242]239 compiler.codeGenerator.opfix_JmpPertialSchedule( pIfPertialSchedule );
[3]240 }
241}
242
243int GetLabelAddress(char *LabelName,int LineNum){
244 if(LabelName){
[262]245 BOOST_FOREACH( const GotoLabel &label, compiler.codeGenerator.gotoLabels )
246 {
247 if( label.name.size() > 0 )
248 {
249 if( label.name == LabelName )
250 {
251 return label.address;
252 }
[3]253 }
254 }
255 }
256 else{
[262]257 BOOST_FOREACH( const GotoLabel &label, compiler.codeGenerator.gotoLabels )
258 {
259 if( label.name.size() == 0 )
260 {
261 if( label.line == LineNum )
262 {
263 return label.address;
264 }
[3]265 }
266 }
267 }
268 return -1;
269}
270void OpcodeGoto(char *Parameter){
271 extern HANDLE hHeap;
272 int i,LineNum;
273
274 if(Parameter[0]=='*'){
275 i=GetLabelAddress(Parameter+1,0);
276
[254]277 if( i == -1 )
278 {
279 //jmp ...(schedule)
280 compiler.codeGenerator.op_jmp_goto_schedule( (const std::string)(Parameter + 1), 0, cp );
[3]281 }
[254]282 else
283 {
284 //jmp ...
[308]285 compiler.codeGenerator.op_jmp(
286 i-compiler.codeGenerator.GetNativeCodeSize(),
287 sizeof(long),
288 false,
289 true
290 );
[254]291 }
[3]292 }
293 else{
294 LineNum=atoi(Parameter);
295 i=GetLabelAddress(0,LineNum);
296
[254]297 if( i == -1 )
298 {
299 //jmp ...(schedule)
300 compiler.codeGenerator.op_jmp_goto_schedule( "", LineNum, cp );
[3]301 }
[254]302 else
303 {
304 //jmp ...
[308]305 compiler.codeGenerator.op_jmp(
306 i-compiler.codeGenerator.GetNativeCodeSize(),
307 sizeof(long),
308 false,
309 true
310 );
[254]311 }
[3]312 }
313}
314void OpcodeWhile(char *Parameter){
315 extern HANDLE hHeap;
316
317 //Continueアドレスのバックアップとセット
[242]318 compiler.codeGenerator.ContinueAreaBegin();
[3]319
320 if(!Parameter[0]) SetError(10,"While",cp);
321
322 //条件式を実行してフラグをセット
323 Judgment(Parameter);
324
325 //je (Wend まで)
[254]326 const PertialSchedule *pWhilePertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
[3]327
328 //レキシカルスコープをレベルアップ
[308]329 compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_WHILE );
[3]330
331 //While内をコンパイル
332 CompileBuffer(0,COM_WEND);
333
[254]334 compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
[3]335
336 //jmp ...
[242]337 compiler.codeGenerator.op_jmp_continue();
[3]338
339 //レキシカルスコープをレベルダウン
[254]340 compiler.codeGenerator.lexicalScopes.End();
[3]341
[242]342 compiler.codeGenerator.opfix_JmpPertialSchedule( pWhilePertialSchedule );
[3]343
344 //Continueアドレスを復元
[242]345 compiler.codeGenerator.ContinueAreaEnd();
[3]346}
347
348char szNextVariable[VN_SIZE];
349void OpcodeFor(char *Parameter){
350 extern HANDLE hHeap;
[75]351 Type resultType;
[242]352 int i,i2;
[3]353 char temporary[VN_SIZE],variable[VN_SIZE],JudgeNum[VN_SIZE],StepNum[VN_SIZE];
[34]354 bool isError = false;
[3]355
356 //第1パラメータを取得
357 i=GetOneParameter(Parameter,0,temporary);
358 if(!Parameter[i]){
359 SetError(12,"For",cp);
[34]360 isError = true;
[3]361 goto ErrorStep;
362 }
363
364 for(i2=0;;i2++){
365 if(temporary[i2]=='='){
366 variable[i2]=0;
367
368 //カウンタ初期化
369 OpcodeCalc(temporary);
370 break;
371 }
372 if(temporary[i2]=='\0'){
373 SetError(12,"For",cp);
[34]374 isError = true;
[3]375 goto ErrorStep;
376 }
377 variable[i2]=temporary[i2];
378 }
379
380 //jmp ...
[254]381 const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
[3]382
383 //Continueアドレスのバックアップとセット
[242]384 compiler.codeGenerator.ContinueAreaBegin();
[3]385
386 //第2パラメータを取得(to~)
387 i=GetOneParameter(Parameter,i,JudgeNum);
388
389 //第3パラメータを取得(step~)
390 if(Parameter[i]){
391 i=GetOneParameter(Parameter,i,StepNum);
392 if(Parameter[i]) SetError(12,"For",cp);
393 }
394 else lstrcpy(StepNum,"1");
395
396 //カウンタを増加させる
397 sprintf(temporary,"%s=(%s)+(%s)",variable,variable,StepNum);
398 OpcodeCalc(temporary);
399
[242]400 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
[3]401
402 //増加か減少かを区別する
403 sprintf(temporary,"(%s)>=0",StepNum);
404
[75]405 int reg;
[3]406 reg=REG_RAX;
[75]407 if( !NumOpe(&reg,temporary,Type(),resultType) ){
408 return;
409 }
[3]410
411 //cmp rax,0
[226]412 compiler.codeGenerator.op_cmp_value(resultType.GetSize(),REG_RAX,0);
[3]413
414 //je [カウンタ減少の場合の判定]
[242]415 pTempPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
[3]416
417 //判定(カウンタ増加の場合)
418 sprintf(temporary,"%s<=(%s)",variable,JudgeNum);
419
420 reg=REG_RAX;
[75]421 NumOpe(&reg,temporary,Type(),Type());
[3]422
423 //jmp [カウンタ減少の場合の判定を飛び越す]
[254]424 const PertialSchedule *pTempPertialSchedule2 = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
[3]425
[242]426 //jeジャンプ先のオフセット値
427 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
[3]428
429 //判定(カウンタ減少の場合)
430 sprintf(temporary,"%s>=(%s)",variable,JudgeNum);
431
432 reg=REG_RAX;
[75]433 NumOpe(&reg,temporary,Type(),resultType);
[3]434
[242]435 //jmpジャンプ先のオフセット値
436 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule2 );
[3]437
438 //cmp rax,0
[226]439 compiler.codeGenerator.op_cmp_value(resultType.GetSize(),REG_RAX,0);
[3]440
441ErrorStep:
442
443 //je ...
[242]444 pTempPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(long), true );
[3]445
446 //レキシカルスコープをレベルアップ
[308]447 compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_FOR );
[3]448
449 //For内をコンパイル
450 CompileBuffer(0,COM_NEXT);
451
[254]452 compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
[3]453
454 if(szNextVariable[0]){
455 if(lstrcmp(szNextVariable,variable)!=0){
456 SetError(55,szNextVariable,cp);
457 }
458 }
459
460 //jmp ...
[242]461 compiler.codeGenerator.op_jmp_continue();
[3]462
463 //レキシカルスコープをレベルダウン
[254]464 compiler.codeGenerator.lexicalScopes.End();
[3]465
[242]466 //jeジャンプ先のオフセット値
467 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
[3]468
469 //Continueアドレスを復元
[242]470 compiler.codeGenerator.ContinueAreaEnd();
[3]471}
472
473void OpcodeDo(char *Parameter){
474 extern HANDLE hHeap;
475 int i,i2,i3;
476
477 if(Parameter[0]) SetError(10,"Do",cp);
478
479 //Continueアドレスのバックアップとセット
[242]480 compiler.codeGenerator.ContinueAreaBegin();
[3]481
482 //レキシカルスコープをレベルアップ
[308]483 compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_DO );
[3]484
485 //Do内をコンパイル
486 CompileBuffer(0,COM_LOOP);
487
[254]488 compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
[3]489
[254]490 const PertialSchedule *pDoPertialSchedule = NULL;
[242]491
[3]492 extern char *basbuf;
493 char temporary[VN_SIZE];
494 for(i=cp-1;;i--){
495 if(IsCommandDelimitation(basbuf[i])){
496 i+=3;
497 if(!(basbuf[i]=='0'||basbuf[i]=='1')){
498 //無条件ループ
499 break;
500 }
501 i3=i;
502
503 for(i+=2,i2=0;;i++,i2++){
504 if(IsCommandDelimitation(basbuf[i])){
505 temporary[i2]=0;
506 break;
507 }
508 temporary[i2]=basbuf[i];
509 }
510
511 //条件式を実行してフラグをセット
512 Judgment(temporary);
513
514 if(basbuf[i3]=='0'){
515 //While
516
517 //je 5(ループ終了)
[242]518 pDoPertialSchedule = compiler.codeGenerator.op_je( 0, sizeof(char), true );
[3]519 }
520 else if(basbuf[i3]=='1'){
521 //Until
522
523 //jne 5(ループ終了)
[242]524 pDoPertialSchedule = compiler.codeGenerator.op_jne( 0, sizeof(char), true );
[3]525 }
526 break;
527 }
528 }
529
530 //jmp ...
[242]531 compiler.codeGenerator.op_jmp_continue();
[3]532
[242]533 if( pDoPertialSchedule )
534 {
535 compiler.codeGenerator.opfix_JmpPertialSchedule( pDoPertialSchedule );
536 }
537
[3]538 //jmp ...
[254]539 const PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
[3]540
541 //レキシカルスコープをレベルダウン
[254]542 compiler.codeGenerator.lexicalScopes.End();
[3]543
[243]544 //jmpジャンプ先のオフセット値
545 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
[3]546
547 //Continueアドレスを復元
[242]548 compiler.codeGenerator.ContinueAreaEnd();
[3]549}
550void OpcodeContinue(void){
551 //jmp ...(Continue addr)
[242]552 compiler.codeGenerator.op_jmp_continue();
[3]553}
554
555void OpcodeExitSub(void){
[75]556 if( UserProc::IsGlobalAreaCompiling() ){
[3]557 SetError(12,"Exit Sub/Function",cp);
558 return;
559 }
560
[34]561 //未解放のローカルオブジェクトのデストラクタを呼び出す
[254]562 compiler.codeGenerator.lexicalScopes.CallDestructorsOfReturn();
[34]563
[3]564 //jmp ...(End Sub/Function)
[254]565 compiler.codeGenerator.op_jmp_exitsub();
566}
[3]567
[254]568//Caseスケジュール
569class SelectSchedule
570{
571public:
572 SelectSchedule( int typeSize )
573 : typeSize( typeSize )
574 , nowCaseSchedule( 0 )
575 {
576 }
[3]577
[254]578 PertialSchedules casePertialSchedules;
579 int typeSize;
580 int nowCaseSchedule;
581};
582std::vector<SelectSchedule> selectSchedules;
[3]583
[75]584void OpcodeSelect( const char *lpszParms ){
[3]585 extern HANDLE hHeap;
586 extern char *basbuf;
587 int i,i2,i3,NowCaseCp;
588 char temporary[VN_SIZE];
[254]589
[75]590 int reg1=REG_RAX;
591 Type type1;
592 if( !NumOpe(&reg1,lpszParms,Type(), type1 ) ){
593 return;
594 }
[3]595
[254]596 selectSchedules.push_back( SelectSchedule( type1.GetSize() ) );
597
598 if( selectSchedules.back().typeSize < sizeof(long) ){
599 selectSchedules.back().typeSize = sizeof(long);
600 }
601
[75]602 if(type1.IsDouble()){
[3]603 //movsd qword ptr[rsp+offset],xmm_reg ※スタックフレームを利用
604 pobj_sf->push(reg1,sizeof(double));
605 }
[75]606 else if(type1.IsSingle()){
[3]607 //movss dword ptr[rsp+offset],xmm_reg ※スタックフレームを利用
608 pobj_sf->push(reg1,sizeof(float));
609 }
610 else{
[75]611 ExtendTypeTo64(type1.GetBasicType(),reg1);
[3]612
613 //mov qword ptr[rsp+offset],reg ※スタックフレームを利用
614 pobj_sf->push(reg1);
615 }
616
617 for(i=cp;;i++){
618 if(basbuf[i]=='\0'){
[254]619 selectSchedules.pop_back();
[3]620 SetError(22,"Select",cp);
621 return;
622 }
623 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE){
624 for(i2=0;;i++){
625 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE) i2++;
626 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){
627 i2--;
628 if(i2==0) break;
629 }
630 }
631 continue;
632 }
633 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT) break;
634
635 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASE){
636 NowCaseCp=i;
637
638 i++;
639 while(1){
640 for(i++,i2=0;;i++,i2++){
641 if(basbuf[i]=='\"'){
642 i3=GetStringInQuotation(temporary+i2,basbuf+i);
643 i+=i3-1;
644 i2+=i3-1;
645 continue;
646 }
647 if(basbuf[i]=='('){
648 i3=GetStringInPare(temporary+i2,basbuf+i);
649 i+=i3-1;
650 i2+=i3-1;
651 continue;
652 }
653 if(basbuf[i]=='['){
654 i3=GetStringInBracket(temporary+i2,basbuf+i);
655 i+=i3-1;
656 i2+=i3-1;
657 continue;
658 }
659
660 if(IsCommandDelimitation(basbuf[i])){
661 temporary[i2]=0;
662 break;
663 }
664 if(basbuf[i]==','){
665 temporary[i2]=0;
666 break;
667 }
668
669 temporary[i2]=basbuf[i];
670 }
671
672 //エラー用
673 i2=cp;
674 cp=NowCaseCp;
675
[75]676 int reg2=REG_RDX;
677 Type type2;
678 if( !NumOpe(&reg2,temporary,type1,type2) ){
679 return;
680 }
[3]681
682 cp=i2;
683
[75]684 if(type1.IsObject()){
[206]685 std::vector<const UserProc *> subs;
[135]686 type1.GetClass().GetMethods().Enum( CALC_EQUAL, subs );
[50]687 if( subs.size() == 0 ){
[3]688 return;
689 }
690
[75]691 Parameters params;
692 params.push_back( new Parameter( "", Type( type2 ) ) );
[3]693
694 //オーバーロードを解決
[206]695 const UserProc *pUserProc = OverloadSolution("==",subs, params, NULL);
[3]696
[75]697 delete params[0];
698
699 if(!pUserProc){
[3]700 //エラー
701 return;
702 }
703
704
705 //実体オブジェクト
706 if(reg2!=REG_RDX){
707 //mov rdx,reg2
[226]708 compiler.codeGenerator.op_mov_RR(REG_RDX,reg2);
[3]709 }
710
711 //mov rcx,qword ptr[rsp+offset] ※スタックフレームから参照
712 pobj_sf->ref(REG_RCX);
713
714 //call operator_proc ※ ==演算子
[226]715 compiler.codeGenerator.op_call(pUserProc);
[3]716
717 //test rax,rax
[226]718 compiler.codeGenerator.op_test(REG_RAX,REG_RAX);
[3]719
720 //jne ...
[254]721 selectSchedules.back().casePertialSchedules.push_back(
722 compiler.codeGenerator.op_jne( 0, sizeof(long), true )
723 );
[3]724 }
725 else{
[75]726 if(type1.IsDouble()){
[3]727 int xmm_reg;
728 if(IsXmmReg(reg2)) xmm_reg=reg2;
729 else xmm_reg=REG_XMM5;
[75]730 ChangeTypeToXmm_Double(type2.GetBasicType(),xmm_reg,reg2);
[3]731
732 //movsd xmm4,qword ptr[rsp+offset] ※スタックフレームから参照
733 pobj_sf->ref(REG_XMM4,sizeof(double));
734
735 //comiss xmm_reg1,xmm_reg2
[226]736 compiler.codeGenerator.op_comisd(xmm_reg,REG_XMM4);
[3]737 }
[75]738 else if(type1.IsSingle()){
[3]739 int xmm_reg;
740 if(IsXmmReg(reg2)) xmm_reg=reg2;
741 else xmm_reg=REG_XMM5;
[75]742 ChangeTypeToXmm_Single(type2.GetBasicType(),xmm_reg,reg2);
[3]743
744 //movss xmm4,dword ptr[rsp+offset] ※スタックフレームから参照
745 pobj_sf->ref(REG_XMM4,sizeof(float));
746
747 //comiss xmm_reg1,xmm_reg2
[226]748 compiler.codeGenerator.op_comiss(xmm_reg,REG_XMM4);
[3]749 }
750 else{
751 //その他整数型
752
[75]753 i2=NeutralizationType(type1.GetBasicType(),-1,type2.GetBasicType(),-1);
[3]754
755 //mov r14,qword ptr[rsp+offset] ※スタックフレームから参照
756 pobj_sf->ref(REG_R14);
757
758 //cmp reg2,r14
[308]759 compiler.codeGenerator.op_cmp_reg(Type(i2).GetSize(),reg2,REG_R14);
[3]760 }
761
762 //je ...
[254]763 selectSchedules.back().casePertialSchedules.push_back(
764 compiler.codeGenerator.op_je( 0, sizeof(long), true )
765 );
[3]766 }
767
768 if(basbuf[i]!=',') break;
769 }
770 }
771 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASEELSE){
772 //jmp ...
[254]773 selectSchedules.back().casePertialSchedules.push_back(
774 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
775 );
[3]776 }
777 }
778
779 //スタックフレームを1スペースだけ解除
780 pobj_sf->pop(REG_NON);
781
782 //レキシカルスコープをレベルアップ
[308]783 compiler.codeGenerator.lexicalScopes.Start( compiler.codeGenerator.GetNativeCodeSize(), LexicalScope::SCOPE_TYPE_SELECT );
[3]784
785 //Select Case内をコンパイル
786 CompileBuffer(ESC_ENDSELECT,0);
787
788 //jmp EndSelect
[254]789 selectSchedules.back().casePertialSchedules.push_back(
790 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
791 );
[3]792
793 //最終スケジュール
[254]794 for(i=selectSchedules.back().nowCaseSchedule;i<(int)selectSchedules.back().casePertialSchedules.size();i++){
795 compiler.codeGenerator.opfix_JmpPertialSchedule( selectSchedules.back().casePertialSchedules[i] );
[3]796 }
797
798 //レキシカルスコープをレベルダウン
[254]799 compiler.codeGenerator.lexicalScopes.End();
[3]800
[254]801 selectSchedules.pop_back();
[3]802}
803void OpcodeCase(char *Parameter){
804 int i;
805
[254]806 if(selectSchedules.back().typeSize==-1){
[3]807 SetError(30,"Case",cp);
808 return;
809 }
810
811 //jmp EndSelect
[254]812 selectSchedules.back().casePertialSchedules.push_back(
813 compiler.codeGenerator.op_jmp( 0, sizeof(long), true )
814 );
[3]815
816 i=0;
817 while(1){
818 //Caseスケジュール
[254]819 compiler.codeGenerator.opfix_JmpPertialSchedule( selectSchedules.back().casePertialSchedules[selectSchedules.back().nowCaseSchedule] );
820 selectSchedules.back().nowCaseSchedule++;
[3]821
822 i=JumpOneParameter(Parameter,i);
823 if(Parameter[i]=='\0') break;
824 }
825}
826
827void OpcodeGosub(char *Parameter){
828 SetError(-1,"Gosub ~ Returnステートメントは64ビットコンパイラで利用することはできません。",cp);
829}
830void OpcodeReturn(char *Parameter){
[75]831 if( UserProc::IsGlobalAreaCompiling() ){
[34]832 SetError(62,NULL,cp);
[3]833 }
834 else{
835 //戻り値をセット
836 if(Parameter[0]){
[206]837 const UserProc &proc = UserProc::CompilingUserProc();
[3]838
[75]839 const char *temp = "_System_ReturnValue";
840 if(proc.GetName()[0]==1&&proc.GetName()[1]==ESC_OPERATOR)
841 {
[40]842 }
843 else{
[75]844 temp=proc.GetName().c_str();
845 }
846
847 char temporary[VN_SIZE];
848 sprintf(temporary,"%s=%s",temp,Parameter);
849 OpcodeCalc(temporary);
[3]850 }
851
852 //プロシージャを抜け出す(C言語のreturnと同様の処理を行う)
853 OpcodeExitSub();
854 }
855}
856
857
858////////////
859// ポインタ
860////////////
861
862void OpcodeSetPtrData(char *Parameter,int type){
[75]863 int i;
[3]864 char temporary[VN_SIZE];
865
866 if(Parameter[0]=='('){
867 i=JumpStringInPare(Parameter,1);
868 if(Parameter[i+1]=='\0'){
869 for(i=0;;i++){
870 Parameter[i]=Parameter[i+1];
871 if(Parameter[i]=='\0') break;
872 }
873 Parameter[i-1]=0;
874 }
875 }
876
877 //第1パラメータを取得
878 i=GetOneParameter(Parameter,0,temporary);
879 if(!Parameter[i]){
880 SetError(1,NULL,cp);
881 return;
882 }
883
884 int reg_ptr=REG_RAX;
[75]885 Type resultType;
886 if( !NumOpe(&reg_ptr,temporary,Type(),resultType) ){
887 return;
888 }
889 if(!resultType.IsWhole()){
[3]890 SetError(11,Parameter,cp);
891 return;
892 }
893
894 //結果を格納しているレジスタをブロッキング
895 pobj_BlockReg->lock(reg_ptr);
896
897 //第2パラメータを取得
898 i=GetOneParameter(Parameter,i,temporary);
899 if(Parameter[i]){
900 SetError(1,NULL,cp);
901 return;
902 }
903
904 int temp_reg=REG_NON;
[75]905 if( !NumOpe(&temp_reg,temporary,Type(),resultType) ){
906 return;
907 }
[3]908
909 //レジスタのブロッキングを解除
910 pobj_BlockReg->clear();
911
912 if(type==DEF_DOUBLE){
[75]913 ChangeTypeToXmm_Double(resultType.GetBasicType(),REG_XMM0,temp_reg);
[3]914
915 //movsd qword ptr[reg_ptr],xmm0
[226]916 compiler.codeGenerator.op_movsd_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
[3]917 }
918 else if(type==DEF_SINGLE){
[75]919 ChangeTypeToXmm_Single(resultType.GetBasicType(),REG_XMM0,temp_reg);
[3]920
921 //movss dword ptr[reg_ptr],xmm0
[226]922 compiler.codeGenerator.op_movss_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
[3]923 }
924 else{
[308]925 ChangeTypeToWhole(resultType,Type(type),REG_RCX,temp_reg);
[3]926
927 //mov ptr[reg_ptr],rcx
[308]928 compiler.codeGenerator.op_mov_MR(Type(type).GetSize(),REG_RCX,reg_ptr,0,MOD_BASE);
[3]929 }
930}
Note: See TracBrowser for help on using the repository browser.