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

Last change on this file since 243 was 243, 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 CodeGenerator::PertialSchedule *pTempPertialSchedule = compiler.codeGenerator.op_jmp( 0, sizeof(long), true );
525
526 //レキシカルスコープをレベルダウン
527 GetLexicalScopes().End();
528
529 //jmpジャンプ先のオフセット値
530 compiler.codeGenerator.opfix_JmpPertialSchedule( pTempPertialSchedule );
531
532 //Continueアドレスを復元
533 compiler.codeGenerator.ContinueAreaEnd();
534}
535void OpcodeContinue(void){
536 //jmp ...(Continue addr)
537 compiler.codeGenerator.op_jmp_continue();
538}
539
540void OpcodeExitSub(void){
541 extern DWORD *pExitSubSchedule;
542 extern int ExitSubScheduleNum;
543 extern HANDLE hHeap;
544
545 if( UserProc::IsGlobalAreaCompiling() ){
546 SetError(12,"Exit Sub/Function",cp);
547 return;
548 }
549
550 //未解放のローカルオブジェクトのデストラクタを呼び出す
551 GetLexicalScopes().CallDestructorsOfReturn();
552
553 //jmp ...(End Sub/Function)
554 OpBuffer[obp++]=(char)0xE9;
555
556 pExitSubSchedule=(DWORD *)HeapReAlloc(hHeap,0,pExitSubSchedule,(ExitSubScheduleNum+1)*sizeof(DWORD));
557 pExitSubSchedule[ExitSubScheduleNum]=obp;
558 ExitSubScheduleNum++;
559
560 obp+=sizeof(long);
561}
562
563void AddCaseSchedule(void){
564 extern DWORD *pCaseSchedule;
565 extern int CaseScheduleNum;
566 extern HANDLE hHeap;
567
568 pCaseSchedule=(DWORD *)HeapReAlloc(hHeap,0,pCaseSchedule,(CaseScheduleNum+1)*sizeof(DWORD));
569 pCaseSchedule[CaseScheduleNum]=obp;
570 CaseScheduleNum++;
571}
572void OpcodeSelect( const char *lpszParms ){
573 extern DWORD *pCaseSchedule;
574 extern int CaseScheduleNum;
575 extern int NowCaseSchedule;
576 extern HANDLE hHeap;
577 extern char *basbuf;
578 int i,i2,i3,NowCaseCp;
579 char temporary[VN_SIZE];
580
581 DWORD *temp_pCaseSchedule;
582 int temp_CaseScheduleNum;
583 int temp_NowCaseSchedule;
584
585 temp_pCaseSchedule=pCaseSchedule;
586 temp_CaseScheduleNum=CaseScheduleNum;
587 temp_NowCaseSchedule=NowCaseSchedule;
588 pCaseSchedule=(DWORD *)HeapAlloc(hHeap,0,1);
589 CaseScheduleNum=0;
590 NowCaseSchedule=0;
591
592 int reg1=REG_RAX;
593 Type type1;
594 if( !NumOpe(&reg1,lpszParms,Type(), type1 ) ){
595 return;
596 }
597
598 if(type1.IsDouble()){
599 //movsd qword ptr[rsp+offset],xmm_reg ※スタックフレームを利用
600 pobj_sf->push(reg1,sizeof(double));
601 }
602 else if(type1.IsSingle()){
603 //movss dword ptr[rsp+offset],xmm_reg ※スタックフレームを利用
604 pobj_sf->push(reg1,sizeof(float));
605 }
606 else{
607 ExtendTypeTo64(type1.GetBasicType(),reg1);
608
609 //mov qword ptr[rsp+offset],reg ※スタックフレームを利用
610 pobj_sf->push(reg1);
611 }
612
613 for(i=cp;;i++){
614 if(basbuf[i]=='\0'){
615 HeapDefaultFree(pCaseSchedule);
616 pCaseSchedule=temp_pCaseSchedule;
617 CaseScheduleNum=temp_CaseScheduleNum;
618 NowCaseSchedule=temp_NowCaseSchedule;
619 SetError(22,"Select",cp);
620 return;
621 }
622 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE){
623 for(i2=0;;i++){
624 if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE) i2++;
625 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){
626 i2--;
627 if(i2==0) break;
628 }
629 }
630 continue;
631 }
632 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT) break;
633
634 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASE){
635 NowCaseCp=i;
636
637 i++;
638 while(1){
639 for(i++,i2=0;;i++,i2++){
640 if(basbuf[i]=='\"'){
641 i3=GetStringInQuotation(temporary+i2,basbuf+i);
642 i+=i3-1;
643 i2+=i3-1;
644 continue;
645 }
646 if(basbuf[i]=='('){
647 i3=GetStringInPare(temporary+i2,basbuf+i);
648 i+=i3-1;
649 i2+=i3-1;
650 continue;
651 }
652 if(basbuf[i]=='['){
653 i3=GetStringInBracket(temporary+i2,basbuf+i);
654 i+=i3-1;
655 i2+=i3-1;
656 continue;
657 }
658
659 if(IsCommandDelimitation(basbuf[i])){
660 temporary[i2]=0;
661 break;
662 }
663 if(basbuf[i]==','){
664 temporary[i2]=0;
665 break;
666 }
667
668 temporary[i2]=basbuf[i];
669 }
670
671 //エラー用
672 i2=cp;
673 cp=NowCaseCp;
674
675 int reg2=REG_RDX;
676 Type type2;
677 if( !NumOpe(&reg2,temporary,type1,type2) ){
678 return;
679 }
680
681 cp=i2;
682
683 if(type1.IsObject()){
684 std::vector<const UserProc *> subs;
685 type1.GetClass().GetMethods().Enum( CALC_EQUAL, subs );
686 if( subs.size() == 0 ){
687 return;
688 }
689
690 Parameters params;
691 params.push_back( new Parameter( "", Type( type2 ) ) );
692
693 //オーバーロードを解決
694 const UserProc *pUserProc = OverloadSolution("==",subs, params, NULL);
695
696 delete params[0];
697
698 if(!pUserProc){
699 //エラー
700 return;
701 }
702
703
704 //実体オブジェクト
705 if(reg2!=REG_RDX){
706 //mov rdx,reg2
707 compiler.codeGenerator.op_mov_RR(REG_RDX,reg2);
708 }
709
710 //mov rcx,qword ptr[rsp+offset] ※スタックフレームから参照
711 pobj_sf->ref(REG_RCX);
712
713 //call operator_proc ※ ==演算子
714 compiler.codeGenerator.op_call(pUserProc);
715
716 //test rax,rax
717 compiler.codeGenerator.op_test(REG_RAX,REG_RAX);
718
719 //jne ...
720 OpBuffer[obp++]=(char)0x0F;
721 OpBuffer[obp++]=(char)0x85;
722 }
723 else{
724 if(type1.IsDouble()){
725 int xmm_reg;
726 if(IsXmmReg(reg2)) xmm_reg=reg2;
727 else xmm_reg=REG_XMM5;
728 ChangeTypeToXmm_Double(type2.GetBasicType(),xmm_reg,reg2);
729
730 //movsd xmm4,qword ptr[rsp+offset] ※スタックフレームから参照
731 pobj_sf->ref(REG_XMM4,sizeof(double));
732
733 //comiss xmm_reg1,xmm_reg2
734 compiler.codeGenerator.op_comisd(xmm_reg,REG_XMM4);
735 }
736 else if(type1.IsSingle()){
737 int xmm_reg;
738 if(IsXmmReg(reg2)) xmm_reg=reg2;
739 else xmm_reg=REG_XMM5;
740 ChangeTypeToXmm_Single(type2.GetBasicType(),xmm_reg,reg2);
741
742 //movss xmm4,dword ptr[rsp+offset] ※スタックフレームから参照
743 pobj_sf->ref(REG_XMM4,sizeof(float));
744
745 //comiss xmm_reg1,xmm_reg2
746 compiler.codeGenerator.op_comiss(xmm_reg,REG_XMM4);
747 }
748 else{
749 //その他整数型
750
751 i2=NeutralizationType(type1.GetBasicType(),-1,type2.GetBasicType(),-1);
752
753 //mov r14,qword ptr[rsp+offset] ※スタックフレームから参照
754 pobj_sf->ref(REG_R14);
755
756 //cmp reg2,r14
757 compiler.codeGenerator.op_cmp_reg(GetTypeSize(i2,-1),reg2,REG_R14);
758 }
759
760 //je ...
761 OpBuffer[obp++]=(char)0x0F;
762 OpBuffer[obp++]=(char)0x84;
763 }
764 AddCaseSchedule();
765 obp+=sizeof(long);
766
767 if(basbuf[i]!=',') break;
768 }
769 }
770 if(basbuf[i]==1&&basbuf[i+1]==ESC_CASEELSE){
771 //jmp ...
772 OpBuffer[obp++]=(char)0xE9;
773 AddCaseSchedule();
774 obp+=sizeof(long);
775 }
776 }
777
778 //スタックフレームを1スペースだけ解除
779 pobj_sf->pop(REG_NON);
780
781 //レキシカルスコープをレベルアップ
782 GetLexicalScopes().Start( obp, SCOPE_TYPE_SELECT );
783
784 //Select Case内をコンパイル
785 CompileBuffer(ESC_ENDSELECT,0);
786
787 //jmp EndSelect
788 OpBuffer[obp++]=(char)0xE9;
789 AddCaseSchedule();
790 obp+=sizeof(long);
791
792 //最終スケジュール
793 for(i=NowCaseSchedule;i<CaseScheduleNum;i++){
794 *(long *)(OpBuffer+pCaseSchedule[i])=obp-(pCaseSchedule[i]+sizeof(long));
795 }
796 HeapDefaultFree(pCaseSchedule);
797
798 //レキシカルスコープをレベルダウン
799 GetLexicalScopes().End();
800
801 pCaseSchedule=temp_pCaseSchedule;
802 CaseScheduleNum=temp_CaseScheduleNum;
803 NowCaseSchedule=temp_NowCaseSchedule;
804}
805void OpcodeCase(char *Parameter){
806 extern DWORD *pCaseSchedule;
807 extern int NowCaseSchedule;
808 int i;
809
810 if(!pCaseSchedule){
811 SetError(30,"Case",cp);
812 return;
813 }
814
815 //jmp EndSelect
816 OpBuffer[obp++]=(char)0xE9;
817 AddCaseSchedule();
818 obp+=sizeof(long);
819
820 i=0;
821 while(1){
822 //Caseスケジュール
823 *(long *)(OpBuffer+pCaseSchedule[NowCaseSchedule])=obp-(pCaseSchedule[NowCaseSchedule]+sizeof(long));
824 NowCaseSchedule++;
825
826 i=JumpOneParameter(Parameter,i);
827 if(Parameter[i]=='\0') break;
828 }
829}
830
831void OpcodeGosub(char *Parameter){
832 extern HANDLE hHeap;
833 extern GOTOLABELSCHEDULE *pGotoLabelSchedule;
834 extern int GotoLabelScheduleNum;
835 int i,LineNum;
836
837 //call _System_GetEip
838 extern const UserProc *pSub_System_GetEip;
839 compiler.codeGenerator.op_call(pSub_System_GetEip);
840
841 //add rax,offset(Gosubステートメントの最終ポイント)
842 int schedule=obp,schedule2;
843 compiler.codeGenerator.op_add_RV(REG_RAX,0);
844 schedule2=obp-sizeof(long);
845
846 //※戻り先用のrip
847 //mov qword ptr[rsp+offset],rax ※スタックフレームを利用
848 pobj_sf->push(REG_RAX);
849
850
851 if(Parameter[0]=='*'){
852 i=GetLabelAddress(Parameter+1,0);
853
854 //jmp ...
855 OpBuffer[obp++]=(char)0xE9;
856 if(i==-1){
857 pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
858 pGotoLabelSchedule[GotoLabelScheduleNum].pName=(char *)HeapAlloc(hHeap,0,lstrlen(Parameter+1)+1);
859 lstrcpy(pGotoLabelSchedule[GotoLabelScheduleNum].pName,Parameter+1);
860 pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
861 pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
862 GotoLabelScheduleNum++;
863 }
864 *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
865 obp+=sizeof(long);
866 }
867 else{
868 LineNum=atoi(Parameter);
869 i=GetLabelAddress(0,LineNum);
870
871 //jmp ...
872 OpBuffer[obp++]=(char)0xE9;
873 if(i==-1){
874 pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE));
875 pGotoLabelSchedule[GotoLabelScheduleNum].pName=0;
876 pGotoLabelSchedule[GotoLabelScheduleNum].line=LineNum;
877 pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp;
878 pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp;
879 GotoLabelScheduleNum++;
880 }
881 *((long *)(OpBuffer+obp))=i-(obp+sizeof(long));
882 obp+=sizeof(long);
883 }
884
885 *((long *)(OpBuffer+schedule2))=obp-schedule;
886
887 //※スタックフレームを元に戻す
888 pobj_sf->pop(REG_NON);
889
890 SetError(-1,"Gosub ~ Returnステートメントは64ビットコンパイラで利用することはできません。",cp);
891}
892void OpcodeReturn(char *Parameter){
893 if( UserProc::IsGlobalAreaCompiling() ){
894 SetError(62,NULL,cp);
895 }
896 else{
897 //戻り値をセット
898 if(Parameter[0]){
899 const UserProc &proc = UserProc::CompilingUserProc();
900
901 const char *temp = "_System_ReturnValue";
902 if(proc.GetName()[0]==1&&proc.GetName()[1]==ESC_OPERATOR)
903 {
904 }
905 else{
906 temp=proc.GetName().c_str();
907 }
908
909 char temporary[VN_SIZE];
910 sprintf(temporary,"%s=%s",temp,Parameter);
911 OpcodeCalc(temporary);
912 }
913
914 //プロシージャを抜け出す(C言語のreturnと同様の処理を行う)
915 OpcodeExitSub();
916 }
917}
918
919
920////////////
921// ポインタ
922////////////
923
924void OpcodeSetPtrData(char *Parameter,int type){
925 int i;
926 char temporary[VN_SIZE];
927
928 if(Parameter[0]=='('){
929 i=JumpStringInPare(Parameter,1);
930 if(Parameter[i+1]=='\0'){
931 for(i=0;;i++){
932 Parameter[i]=Parameter[i+1];
933 if(Parameter[i]=='\0') break;
934 }
935 Parameter[i-1]=0;
936 }
937 }
938
939 //第1パラメータを取得
940 i=GetOneParameter(Parameter,0,temporary);
941 if(!Parameter[i]){
942 SetError(1,NULL,cp);
943 return;
944 }
945
946 int reg_ptr=REG_RAX;
947 Type resultType;
948 if( !NumOpe(&reg_ptr,temporary,Type(),resultType) ){
949 return;
950 }
951 if(!resultType.IsWhole()){
952 SetError(11,Parameter,cp);
953 return;
954 }
955
956 //結果を格納しているレジスタをブロッキング
957 pobj_BlockReg->lock(reg_ptr);
958
959 //第2パラメータを取得
960 i=GetOneParameter(Parameter,i,temporary);
961 if(Parameter[i]){
962 SetError(1,NULL,cp);
963 return;
964 }
965
966 int temp_reg=REG_NON;
967 if( !NumOpe(&temp_reg,temporary,Type(),resultType) ){
968 return;
969 }
970
971 //レジスタのブロッキングを解除
972 pobj_BlockReg->clear();
973
974 if(type==DEF_DOUBLE){
975 ChangeTypeToXmm_Double(resultType.GetBasicType(),REG_XMM0,temp_reg);
976
977 //movsd qword ptr[reg_ptr],xmm0
978 compiler.codeGenerator.op_movsd_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
979 }
980 else if(type==DEF_SINGLE){
981 ChangeTypeToXmm_Single(resultType.GetBasicType(),REG_XMM0,temp_reg);
982
983 //movss dword ptr[reg_ptr],xmm0
984 compiler.codeGenerator.op_movss_MR(REG_XMM0,reg_ptr,0,MOD_BASE);
985 }
986 else{
987 ChangeTypeToWhole(resultType.GetBasicType(),type,REG_RCX,temp_reg);
988
989 //mov ptr[reg_ptr],rcx
990 compiler.codeGenerator.op_mov_MR(GetTypeSize(type,-1),REG_RCX,reg_ptr,0,MOD_BASE);
991 }
992}
Note: See TracBrowser for help on using the repository browser.