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

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