source: dev/trunk/ab5.0/abdev/compiler_x64/Compile_ProcOp.cpp @ 584

Last change on this file since 584 was 584, checked in by dai_9181, 15 years ago

[530][583]を64bit版にマージ。

File size: 20.1 KB
Line 
1#include "stdafx.h"
2
3#include <Program.h>
4#include <Compiler.h>
5#include <Class.h>
6
7#include "../BasicCompiler_Common/common.h"
8#include "Opcode.h"
9
10void SystemProc( const UserProc &userProc ){
11    if( userProc.GetName() == "_System_GetEip" ){
12        //mov rax,qword ptr[rsp]
13        compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RAX,REG_RSP,0,MOD_BASE);
14
15        //ret
16        compiler.codeGenerator.op_ret();
17    }
18    else if( userProc.GetName() == "_System_InitDllGlobalVariables" ){
19        ////////////////////////////////////////
20        // DLLのグローバル領域をコンパイル
21        ////////////////////////////////////////
22        if(!compiler.IsDll()){
23            //ret
24            compiler.codeGenerator.op_ret();
25
26            return;
27        }
28
29        const UserProc *pBackUserProc;
30        pBackUserProc = &compiler.GetCompilingUserProc();
31        compiler.StartGlobalAreaCompile();
32
33        int BackCp;
34        BackCp=cp;
35        cp=-1;
36
37        //sub rsp,スタックフレームサイズ
38        const PertialSchedule *pStackFramePertialSchedule = compiler.codeGenerator.op_sub_rsp( 0, true );
39
40        if( compiler.IsDebug() )
41        {
42            //デバッグ用の変数を定義
43            DebugVariable();
44        }
45
46        //GC用の変数を定義
47        InitGCVariables();
48
49        //_System_StartupProgramの呼び出し
50        extern const UserProc *pSub_System_StartupProgram;
51        compiler.codeGenerator.op_call(pSub_System_StartupProgram);
52
53        //クラスに属する静的メンバを定義
54        ActiveBasic::Compiler::ProcedureGenerator::Generate_InitStaticMember(
55            compiler.GetObjectModule().meta.GetClasses()
56        );
57
58        GetGlobalDataForDll();
59
60        //add rsp,スタックフレームサイズ
61        compiler.codeGenerator.op_add_RV(REG_RSP,pobj_sf->GetFrameSize(0));
62
63        //スタックフレームスケジュール(subコマンドに渡す値)
64        compiler.codeGenerator.opfix( pStackFramePertialSchedule, pobj_sf->GetFrameSize(0) );
65
66        compiler.SetCompilingUserProc( pBackUserProc );
67        cp=BackCp;
68
69        //ret
70        compiler.codeGenerator.op_ret();
71    }
72    else if( userProc.GetName() == "_System_InitStaticLocalVariables" ){
73        //静的ローカルオブジェクトのコンストラクタ呼び出し
74
75        //sub rsp,スタックフレームサイズ
76        const PertialSchedule *pStackFramePertialSchedule = compiler.codeGenerator.op_sub_rsp( 0, true );
77
78        BOOST_FOREACH( Variable *pVar, compiler.GetObjectModule().meta.GetGlobalVars() ){
79            if(memicmp(pVar->GetName().c_str(),"Static%",7)==0){
80                //コンストラクタ呼び出し
81                if( pVar->GetType().IsObject() ){
82
83                    //エラー用
84                    cp=pVar->source_code_address;
85
86                    CallConstructor(
87                        pVar->GetName().c_str(),
88                        pVar->GetSubscripts(),
89                        pVar->GetType(),
90                        pVar->GetParamStrForConstructor().c_str());
91                }
92            }
93        }
94
95        //add rsp,スタックフレームサイズ
96        compiler.codeGenerator.op_add_RV(REG_RSP,pobj_sf->GetFrameSize(0));
97
98        //スタックフレームスケジュール(subコマンドに渡す値)
99        compiler.codeGenerator.opfix( pStackFramePertialSchedule, pobj_sf->GetFrameSize(0) );
100
101        //ret
102        compiler.codeGenerator.op_ret();
103    }
104    else if( userProc.GetName() == "_System_Call_Destructor_of_GlobalObject" ){
105        //sub rsp,8(※RSPを16バイト境界にあわせるため)
106        compiler.codeGenerator.op_sub_rsp(0x8);
107
108        const UserProc *pBackUserProc;
109        pBackUserProc = &compiler.GetCompilingUserProc();
110        compiler.StartGlobalAreaCompile();
111
112        compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
113
114        compiler.SetCompilingUserProc( pBackUserProc );
115
116
117        //add rsp,8
118        compiler.codeGenerator.op_add_RV(REG_RSP,0x8);
119
120        //ret
121        compiler.codeGenerator.op_ret();
122    }
123    else{
124        compiler.errorMessenger.OutputFatalError();
125    }
126}
127void AutoGeneration(const UserProc &userProc){
128    if( userProc.GetName() == "InitializeUserTypes"
129        && userProc.HasParentClass()
130        && userProc.GetParentClass().GetName() == "_System_TypeBase" )
131    {
132        ActiveBasic::Compiler::ProcedureGenerator::Generate_System_InitializeUserTypes(
133            compiler.GetObjectModule().meta.GetClasses()
134        );
135    }
136    else if( userProc.GetName() == "InitializeUserTypesForBaseType"
137        && userProc.HasParentClass()
138        && userProc.GetParentClass().GetName() == "_System_TypeBase" )
139    {
140        ActiveBasic::Compiler::ProcedureGenerator::Generate_System_InitializeUserTypesForBaseType(
141            compiler.GetObjectModule().meta.GetClasses()
142        );
143    }
144    else if( userProc.GetName() == "RegisterGlobalRoots"
145        && userProc.HasParentClass()
146        && userProc.GetParentClass().GetName() == "_System_CGarbageCollection" )
147    {
148        Compile_AddGlobalRootsForGc();
149    }
150    else if( userProc.GetName() == compiler.globalAreaProcName ){
151        ////////////////////////////////////////
152        // グローバル領域をコンパイル
153        ////////////////////////////////////////
154
155        UserProc::pGlobalProc = &userProc;
156
157        const UserProc *pBackUserProc = &compiler.GetCompilingUserProc();
158        compiler.StartGlobalAreaCompile();
159
160        int BackCp = cp;
161        cp=-1;
162
163        //クラスに属する静的メンバを定義
164        ActiveBasic::Compiler::ProcedureGenerator::Generate_InitStaticMember(
165            compiler.GetObjectModule().meta.GetClasses()
166        );
167
168        //グローバル実行領域をコンパイル開始
169        CompileBuffer(0,0);
170
171        //Goto未知ラベルスケジュールが存在したらエラーにする
172        BOOST_FOREACH( const GotoLabelSchedule *pGotoLabelSchedule, compiler.codeGenerator.gotoLabelSchedules )
173        {
174            if(pGotoLabelSchedule->GetName().size()>0){
175                compiler.errorMessenger.Output(6,pGotoLabelSchedule->GetName(),pGotoLabelSchedule->GetSourceCodePos());
176            }
177            else{
178                char temporary[255];
179                sprintf(temporary,"%d",pGotoLabelSchedule->GetLineNum());
180                compiler.errorMessenger.Output(6,temporary,pGotoLabelSchedule->GetSourceCodePos());
181            }
182        }
183
184        compiler.SetCompilingUserProc( pBackUserProc );
185        cp=BackCp;
186    }
187    else if( userProc.HasParentClass()
188        && userProc.IsCastOperator()
189        && userProc.ReturnType().IsInterface() )
190    {
191        // インターフェイス型にキャストするためのメソッド
192
193        int vtblMasterListIndex = userProc.GetParentClass().GetVtblMasterListIndex( &userProc.ReturnType().GetClass() );
194
195        char temporary[1024];
196        sprintf( temporary,
197            "Return New %s(ObjPtr( This ),Get_LONG_PTR( (Get_LONG_PTR( ObjPtr(This)+SizeOf(VoidPtr) ) + SizeOf(LONG_PTR)*%d) As VoidPtr ) As VoidPtr )",
198            userProc.ReturnType().GetClass().GetName().c_str(),
199            vtblMasterListIndex
200        );
201        MakeMiddleCode( temporary );
202
203        ChangeOpcode( temporary );
204    }
205    else{
206        compiler.errorMessenger.OutputFatalError();
207    }
208}
209void _compile_proc(const UserProc *pUserProc){
210    extern char *basbuf;
211    extern HANDLE hHeap;
212    int i3,i4;
213    char temporary[VN_SIZE];
214
215    if( pUserProc->GetLocalVars().size() ){
216        compiler.errorMessenger.OutputFatalError();
217        return;
218    }
219
220    trace_for_sourcecodestep( "★★★ " << pUserProc->GetFullName() << "のコンパイルを開始" );
221
222    pUserProc->CompleteCompile();
223
224    extern BOOL bSystemProc;
225    if(memcmp(pUserProc->GetName().c_str(),"_System_",8)==0) bSystemProc=1;
226    else bSystemProc=0;
227
228    extern BOOL bDebugSupportProc;
229    if(memcmp(pUserProc->GetName().c_str(),"_DebugSys_",10)==0){
230        if( !compiler.IsDebug() )
231        {
232            return;
233        }
234        bDebugSupportProc=1;
235    }
236    else bDebugSupportProc=0;
237
238    compiler.StartProcedureCompile( pUserProc );
239
240    if(pUserProc->IsSystem()){
241        ////////////////////
242        // 特殊関数
243        ////////////////////
244
245        extern int AllLocalVarSize;
246        AllLocalVarSize=0;
247
248        //スタックフレーム管理用オブジェクトを初期化
249        extern StackFrame *pobj_sf;
250        pobj_sf=new StackFrame();
251
252        SystemProc(*pUserProc);
253
254        //スタックフレーム管理用オブジェクトを破棄
255        delete pobj_sf;
256        pobj_sf=0;
257
258        return;
259    }
260
261    if( !pUserProc->IsAutoGeneration() )
262    {
263        cp=pUserProc->GetCodePos();
264        for(;;cp++){
265            if(IsCommandDelimitation(basbuf[cp])) break;
266        }
267        cp--;
268    }
269
270    //プロシージャ抜け出しスケジュール(Exit Sub/Function)
271    compiler.codeGenerator.exitSubCodePositions.clear();
272
273    //ラベル用のメモリを確保
274    compiler.codeGenerator.gotoLabels.clear();
275
276    //Gotoラベルスケジュール
277    compiler.codeGenerator.gotoLabelSchedules.clear();
278
279    //With情報のメモリを確保
280    extern WITHINFO WithInfo;
281    WithInfo.ppName=(char **)HeapAlloc(hHeap,0,1);
282    WithInfo.pWithCp=(int *)HeapAlloc(hHeap,0,1);
283    WithInfo.num=0;
284
285    //Continueアドレスを初期化
286    compiler.codeGenerator.ClearContinueArea();
287
288    //ローカル変数に関する情報
289    extern int AllLocalVarSize;
290    AllLocalVarSize=0;
291
292    //レキシカルスコープ情報を初期化
293    compiler.codeGenerator.lexicalScopes.Init( compiler.codeGenerator.GetNativeCodeSize() );
294
295
296    /////////////////////////////////////
297    // パラメータ用の変数データを考慮
298    /////////////////////////////////////
299
300    //パラメータ用の変数データを考慮
301    for(i3=(int)pUserProc->RealParams().size()-1;i3>=0;i3--){
302        Parameter &param = *pUserProc->RealParams()[i3];
303
304        Variable *pVar = new Variable(
305            ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( param.GetVarName().c_str() ),
306            param,
307            false,
308            param.IsRef(),
309            "",
310            false
311        );
312
313        if( param.IsArray() ){
314            pVar->SetArray( param.GetSubscripts() );
315        }
316
317        int varSize;
318        if( param.IsRef() == false && param.IsStruct() ){
319            //構造体のByValパラメータ
320            pVar->ThisIsParameter();
321            varSize=PTR_SIZE;
322        }
323        else{
324            if( param.IsArray() == false ){
325                varSize = pVar->GetMemorySize();
326            }
327            else{
328                varSize=PTR_SIZE;
329            }
330        }
331        AllLocalVarSize+=varSize;
332        pVar->SetOffsetAddress( AllLocalVarSize );
333
334        //レキシカルスコープ情報
335        pVar->SetScopeLevel( compiler.codeGenerator.lexicalScopes.GetNowLevel() );
336        pVar->SetScopeStartAddress( compiler.codeGenerator.lexicalScopes.GetStartAddress() );
337        pVar->isLiving = true;
338
339        pUserProc->GetLocalVars().push_back( pVar );
340    }
341
342    //Thisポインタを示すローカルオフセット値をセット
343    extern int LocalVar_ThisPtrOffset;
344    LocalVar_ThisPtrOffset=AllLocalVarSize;
345
346    //スタックフレーム管理用クラスを初期化
347    extern StackFrame *pobj_sf;
348    pobj_sf=new StackFrame();
349
350
351    ///////////////////////
352    // ここからコード生成
353
354    for(i3=(int)pUserProc->RealParams().size()-1;i3>=0;i3--){
355        Parameter &param = *pUserProc->RealParams()[i3];
356        if(i3==3){
357            if(param.IsReal()&&param.IsRef() == false){
358                //movsd qword ptr[rsp+0x20],xmm3
359                compiler.codeGenerator.op_movsd_MR(REG_XMM3,REG_RSP,0x20,MOD_BASE_DISP32);
360            }
361            else{
362                //mov qword ptr[rsp+0x20],r9
363                compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_R9,REG_RSP,0x20,MOD_BASE_DISP32);
364            }
365        }
366        if(i3==2){
367            if(param.IsReal()&&param.IsRef() == false){
368                //movsd qword ptr[rsp+0x18],xmm2
369                compiler.codeGenerator.op_movsd_MR(REG_XMM2,REG_RSP,0x18,MOD_BASE_DISP32);
370            }
371            else{
372                //mov qword ptr[rsp+0x18],r8
373                compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_R8,REG_RSP,0x18,MOD_BASE_DISP32);
374            }
375        }
376        if(i3==1){
377            if(param.IsReal()&&param.IsRef() == false){
378                //movsd qword ptr[rsp+0x10],xmm1
379                compiler.codeGenerator.op_movsd_MR(REG_XMM1,REG_RSP,0x10,MOD_BASE_DISP32);
380            }
381            else{
382                //mov qword ptr[rsp+0x10],rdx
383                compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RDX,REG_RSP,0x10,MOD_BASE_DISP32);
384            }
385        }
386        if(i3==0){
387            if(param.IsReal()&&param.IsRef() == false){
388                //movsd qword ptr[rsp+0x8],xmm0
389                compiler.codeGenerator.op_movsd_MR(REG_XMM0,REG_RSP,0x8,MOD_BASE_DISP32);
390            }
391            else{
392                //mov qword ptr[rsp+0x8],rcx
393                compiler.codeGenerator.op_mov_MR(sizeof(_int64),REG_RCX,REG_RSP,0x8,MOD_BASE_DISP32);
394            }
395        }
396    }
397
398    //ret用のアドレスを考慮
399    AllLocalVarSize+=sizeof(_int64);
400
401    //sub rsp,スタックフレームサイズ
402    const PertialSchedule *pStackFramePertialSchedule = compiler.codeGenerator.op_sub_rsp( 0, true );
403
404    //mov qword ptr[rsp+offset],reg     ※スタックフレームを利用
405    pobj_sf->push(REG_RBX);
406    pobj_sf->push(REG_RSI);
407    pobj_sf->push(REG_RDI);
408    pobj_sf->push(REG_R12);
409    pobj_sf->push(REG_R13);
410    pobj_sf->push(REG_R14);
411    pobj_sf->push(REG_R15);
412
413    //ローカル変数のベース値
414    int BaseLocalVar;
415    BaseLocalVar=AllLocalVarSize;
416
417    if( !pUserProc->ReturnType().IsNull() ){
418        //戻り値が存在するとき
419
420        const char *temp = pUserProc->GetName().c_str();
421        if( temp[0]==1&&temp[1]==ESC_OPERATOR ){
422            temp = "_System_ReturnValue";
423        }
424
425        if( pUserProc->ReturnType().IsStruct() ){
426            //戻り値用の構造体(値型)はパラメータで引き渡される
427        }
428        else{
429            if( pUserProc->ReturnType().IsObject() ){
430                sprintf(temporary,"%s=Nothing%c%c%s",temp,1,ESC_AS, compiler.TypeToString( pUserProc->ReturnType() ).c_str() );
431            }
432            else{
433                //戻り値用の変数の定義
434                sprintf(temporary,"%s%c%c%s",temp,1,ESC_AS, compiler.TypeToString( pUserProc->ReturnType() ).c_str() );
435            }
436
437            OpcodeDim(temporary,0);
438        }
439    }
440
441    const PertialSchedule *pRspOffsetPertialSchedule1 = NULL;
442    const PertialSchedule *pRspOffsetPertialSchedule2 = NULL;
443    if( compiler.IsDebug() && bDebugSupportProc == 0 )
444    {
445        //mov rdx, qword ptr[rsp+スタックフレームサイズ]
446        pRspOffsetPertialSchedule1 = compiler.codeGenerator.op_mov_RM(sizeof(_int64),REG_RDX,REG_RSP,0,MOD_BASE_DISP32, Schedule::None, true );
447
448        //mov rcx,rsp
449        compiler.codeGenerator.op_mov_RR(REG_RCX,REG_RSP);
450
451        //add rcx,スタックフレームサイズ+sizeof(_int64) ※ret用のサイズを考慮
452        pRspOffsetPertialSchedule2 = compiler.codeGenerator.op_add_RV(REG_RCX,0, Schedule::None, true );
453
454        //call _DebugSys_StartProc
455        extern const UserProc *pSub_DebugSys_StartProc;
456        compiler.codeGenerator.op_call(pSub_DebugSys_StartProc);
457    }
458
459    if( compiler.IsCompilingClass() ){
460        if( pUserProc->GetName() == compiler.GetCompilingClass().GetName() ){
461            ////////////////////////////////////
462            // コンストラクタをコンパイルするとき
463            ////////////////////////////////////
464
465            //コンストラクタのコンパイル開始を通知
466            compiler.GetCompilingClass().NotifyStartConstructorCompile();
467
468            //基底クラスかどうかの識別
469            //(継承元がインターフェイスの場合も基底クラスと見なす)
470            BOOL bThisIsSuperClass;
471            if( !compiler.GetCompilingClass().HasSuperClass() ) bThisIsSuperClass=1;
472            else if( compiler.GetCompilingClass().GetSuperClass().GetConstructorMethod() == NULL ){
473                //インターフェイスを継承したときはコンストラクタを持たない
474                bThisIsSuperClass=1;
475            }
476            else bThisIsSuperClass=0;
477
478            if(!bThisIsSuperClass){
479                /* サブクラスコンストラクタをコンパイルしているときは、
480                    基底クラスのコンストラクタを呼び出す */
481
482                i3=cp+1;
483                while(IsCommandDelimitation(basbuf[i3])) i3++;
484                for(i4=0;;i3++,i4++){
485                    if(!IsVariableChar(basbuf[i3])){
486                        temporary[i4]=0;
487                        break;
488                    }
489                    temporary[i4]=basbuf[i3];
490                }
491                if( compiler.GetCompilingClass().GetSuperClass().GetName() == temporary ){
492                    //基底クラスのコンストラクタを呼び出す
493                    cp=i3;
494                    for(i4=0;;cp++,i4++){
495                        if(IsCommandDelimitation(basbuf[cp])){
496                            temporary[i4]=0;
497                            break;
498                        }
499                        temporary[i4]=basbuf[cp];
500                    }
501                    if(!(temporary[0]=='('&&temporary[lstrlen(temporary)-1]==')')){
502                        compiler.errorMessenger.Output(1,NULL,cp);
503                    }
504                    RemoveStringPare(temporary);
505
506                    Type dummyType;
507                    CallProc( PROC_DEFAULT
508                        , &compiler.GetCompilingClass().GetSuperClass().GetConstructorMethod()->GetUserProc()
509                        , compiler.GetCompilingClass().GetSuperClass().GetConstructorMethod()->GetUserProc().GetName().c_str()
510                        , temporary
511                        , Type()        // baseTypeはなし
512                        , dummyType
513                    );
514                }
515                else{
516                    //基底クラスのコンストラクタを暗黙的に呼び出す
517                    Opcode_CallProc("",
518                        &compiler.GetCompilingClass().GetSuperClass().GetConstructorMethod()->GetUserProc(),
519                        0,
520                        "");
521                }
522            }
523        }
524        else if( pUserProc->IsDestructor() ){
525            //デストラクタをコンパイルしたとき
526
527            //デストラクタのコンパイル開始を通知
528            compiler.GetCompilingClass().NotifyStartDestructorCompile();
529        }
530    }
531
532    //////////////////////////////////////////
533    //////////////////////////////////////////
534    ////// プロシージャ内をコンパイル ////////
535    if( pUserProc->IsAutoGeneration() ){
536        AutoGeneration( *pUserProc );
537    }
538    else{
539        if(pUserProc->IsMacro()){
540            CompileBuffer(ESC_ENDMACRO,0);
541        }
542        else{
543            if(pUserProc->IsSub()){
544                CompileBuffer(ESC_ENDSUB,0);
545            }
546            else if(pUserProc->IsFunction()){
547                CompileBuffer(ESC_ENDFUNCTION,0);
548            }
549        }
550    }
551    //////////////////////////////////////////
552    //////////////////////////////////////////
553
554    if( compiler.IsCompilingClass() ){
555
556        if( compiler.GetCompilingClass().IsCompilingConstructor() ){
557            // コンストラクタをコンパイルしていたとき
558
559            // コンストラクタのコンパイルが完了したことを通知
560            compiler.GetCompilingClass().NotifyFinishConstructorCompile();
561        }
562        else if( pUserProc->IsDestructor() ){
563            ////////////////////////////////////
564            //デストラクタをコンパイルしたとき
565            ////////////////////////////////////
566
567            // デストラクタのコンパイルが完了したことを通知
568            compiler.GetCompilingClass().NotifyFinishDestructorCompile();
569
570            if( compiler.GetCompilingClass().HasSuperClass() ){
571                /* サブクラスのデストラクタをコンパイルしているときは、
572                    基底クラスのデストラクタを呼び出す */
573
574                const CMethod *method = compiler.GetCompilingClass().GetSuperClass().GetDestructorMethod();
575                if( method ){
576                    Opcode_CallProc("",
577                        &method->GetUserProc(),
578                        0,
579                        "");
580                }
581            }
582        }
583    }
584
585    // Tryスコープの検証
586    Exception::InspectTryScope();
587
588    //With情報のメモリを解放
589    for(i3=0;i3<WithInfo.num;i3++){
590        compiler.errorMessenger.Output(22,"With",WithInfo.pWithCp[i3]);
591        HeapDefaultFree(WithInfo.ppName[i3]);
592    }
593    HeapDefaultFree(WithInfo.ppName);
594    HeapDefaultFree(WithInfo.pWithCp);
595
596    //ローカルオブジェクト(レキシカルスコープレベル=0)の解放処理
597    compiler.codeGenerator.lexicalScopes.CallDestructorsOfScopeEnd();
598
599    //プロシージャ抜け出しスケジュール(Exit Sub/Function)
600    compiler.codeGenerator.ResolveExitSubSchedule();
601
602    if( compiler.IsDebug() && bDebugSupportProc == 0 )
603    {
604        //call _DebugSys_EndProc
605        extern const UserProc *pSub_DebugSys_EndProc;
606        compiler.codeGenerator.op_call(pSub_DebugSys_EndProc);
607    }
608
609    if( !pUserProc->ReturnType().IsNull() ){
610        //////////////////////////////////
611        // 戻り値をraxまたはxmm0に設定
612        //////////////////////////////////
613
614        RELATIVE_VAR RelativeVar;
615
616        const char *temp = pUserProc->GetName().c_str();
617        if( temp[0]==1 && temp[1]==ESC_OPERATOR ){
618            temp="_System_ReturnValue";
619        }
620        GetVarOffsetReadWrite(temp,&RelativeVar,Type());
621
622        const Type &returnType = pUserProc->ReturnType();
623        if( returnType.IsObject() || returnType.IsStruct() )
624        {
625            SetVarPtrToReg(REG_RAX,&RelativeVar);
626            if( returnType.IsObject() )
627            {
628                //mov rax,qword ptr[rax]
629                compiler.codeGenerator.op_mov_RM( sizeof(_int64), REG_RAX, REG_RAX, 0, MOD_BASE );
630            }
631        }
632        else if( returnType.IsDouble() )
633        {
634            //64ビット実数型
635            SetXmmReg_DoubleVariable(&RelativeVar,REG_XMM0);
636        }
637        else if( returnType.IsSingle() )
638        {
639            //32ビット実数型
640            SetXmmReg_SingleVariable(&RelativeVar,REG_XMM0);
641        }
642        else if( returnType.IsWhole() )
643        {
644            //整数型
645            SetReg_WholeVariable(returnType,&RelativeVar,REG_RAX);
646        }
647        else compiler.errorMessenger.Output(300,NULL,cp);
648    }
649
650    //ローカル変数領域のサイズをスタックフレームに通知
651    int localParmSize = AllLocalVarSize - BaseLocalVar;
652    int stackFrameSize = pobj_sf->GetFrameSize( localParmSize );
653
654    //ローカル変数アドレススケジュール
655    BOOST_FOREACH( const PertialSchedule *pPertialSchedule, compiler.codeGenerator.localVarPertialSchedules )
656    {
657        compiler.codeGenerator.opfix_offset( pPertialSchedule, AllLocalVarSize + stackFrameSize );
658    }
659    compiler.codeGenerator.localVarPertialSchedules.clear();
660    BOOST_FOREACH( Variable *pVar, pUserProc->GetLocalVars() ){
661        //後にデバッグで利用する
662        pVar->SetOffsetAddress(
663            AllLocalVarSize + stackFrameSize - pVar->GetOffsetAddress()
664        );
665    }
666
667    //mov reg,qword ptr[rsp+offset]     ※スタックフレームを利用
668    pobj_sf->pop(REG_R15);
669    pobj_sf->pop(REG_R14);
670    pobj_sf->pop(REG_R13);
671    pobj_sf->pop(REG_R12);
672    pobj_sf->pop(REG_RDI);
673    pobj_sf->pop(REG_RSI);
674    pobj_sf->pop(REG_RBX);
675
676    int stackFrameAndLocalParamSize = localParmSize + stackFrameSize;
677
678    //add rsp,スタックフレームサイズ
679    compiler.codeGenerator.op_add_rsp(stackFrameAndLocalParamSize);
680
681    //ret
682    compiler.codeGenerator.op_ret();
683
684
685    //デバッグ用
686    if( pRspOffsetPertialSchedule1 ){
687        compiler.codeGenerator.opfix( pRspOffsetPertialSchedule1, stackFrameAndLocalParamSize );
688        compiler.codeGenerator.opfix( pRspOffsetPertialSchedule2, stackFrameAndLocalParamSize + sizeof(_int64) );
689    }
690
691
692    //スタックフレームスケジュール(subコマンド)
693    compiler.codeGenerator.opfix( pStackFramePertialSchedule, stackFrameAndLocalParamSize );
694
695    //スタックフレームスケジュールを実行
696    pobj_sf->RunningSchedule( stackFrameSize );
697    delete pobj_sf;
698    pobj_sf=0;
699
700
701    compiler.FinishProcedureCompile();
702
703
704    //ローカル変数のネーム情報は後に解放する
705}
Note: See TracBrowser for help on using the repository browser.