source: dev/trunk/ab5.0/abdev/compiler_x64/Compile_Statement.cpp@ 648

Last change on this file since 648 was 587, checked in by dai_9181, 16 years ago

[585][586]をリバース。NativeCodeクラスとMetaクラスは依存関係があるので分離しない方針とする。

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