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

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