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

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