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

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

BasicSourceのシリアライズがうまくいっていない

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