source: dev/BasicCompiler64/stack_frame.cpp@ 20

Last change on this file since 20 was 20, checked in by dai_9181, 17 years ago

参照型パラメータに関数の戻り値オブジェクトを指定した場合などの、一時オブジェクトの扱いを可能にした。
Dimで指定される初期値を見分けることで、As指定を省略できるようにした。

File size: 3.3 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "Opcode.h"
3
4
5/////////////////////////
6// スタックフレーム管理
7/////////////////////////
8
9CStackFrame::CStackFrame(){
10 lowest_sp=0;
11 now_sp=0;
12 local_parm_size=0;
13 max_parm_size=0;
14}
15CStackFrame::~CStackFrame(){
16 //オブジェクト破棄時に不整合がないかをチェック(バグ回避)
17 error_check();
18}
19void CStackFrame::SetLocalParmSize(int size){
20 local_parm_size=size;
21}
22int CStackFrame::GetFrameSize(){
23 int answer_sp;
24
25 answer_sp=lowest_sp-max_parm_size;
26
27 if((local_parm_size%0x10)==0){
28 if((answer_sp%0x10)==0){
29 //関数のエントリポイントで128ビット境界ラインに合わせるため
30 return -(answer_sp-0x08);
31 }
32 return -(answer_sp-0x10);
33 }
34
35 if((answer_sp%0x10)==0){
36 //関数のエントリポイントで128ビット境界ラインに合わせるため
37 return -(answer_sp-0x10);
38 }
39 return -(answer_sp-0x08);
40}
41int CStackFrame::push(int reg){
42 now_sp-=sizeof(_int64);
43 if(lowest_sp>now_sp) lowest_sp=now_sp;
44
45 if(reg==REG_NON) return now_sp;
46
47 //mov qword ptr[rsp+offset],reg
48 op_mov_MR(sizeof(_int64),reg,REG_RSP,now_sp,MOD_BASE_DISP32);
49
50 //スケジュールをセット
51 obp-=sizeof(long);
52 add();
53 obp+=sizeof(long);
54
55 return now_sp;
56}
57void CStackFrame::push(int xmm_reg,int var_size){
58 now_sp-=sizeof(_int64);
59 if(lowest_sp>now_sp) lowest_sp=now_sp;
60
61 if(var_size==sizeof(double)){
62 //movlpd qword ptr[rsp+offset],xmm_reg
63 op_movlpd_MR(xmm_reg,REG_RSP,now_sp,MOD_BASE_DISP32);
64 }
65 if(var_size==sizeof(float)){
66 //movss dword ptr[rsp+offset],xmm_reg
67 OpBuffer[obp++]=(char)0xF3;
68 OpBuffer[obp++]=(char)0x0F;
69 OpBuffer[obp++]=(char)0x11;
70 OpBuffer[obp++]=(char)(0x84| REGISTER_OPERAND(xmm_reg)<<3 );
71 OpBuffer[obp++]=(char)0x24;
72 *((long *)(OpBuffer+obp))=now_sp;
73 obp+=sizeof(long);
74 }
75
76 //スケジュールをセット
77 obp-=sizeof(long);
78 add();
79 obp+=sizeof(long);
80}
81void CStackFrame::ref_offset_data( int reg, int sp_offset ){
82 //mov reg,qword ptr[rsp+offset] ※スタックフレームを利用
83 op_mov_RM(sizeof(_int64),reg,REG_RSP,sp_offset,MOD_BASE_DISP32);
84
85 //スケジュールをセット
86 obp-=sizeof(long);
87 add();
88 obp+=sizeof(long);
89}
90void CStackFrame::ref(int reg){
91 ref_offset_data( reg, now_sp );
92}
93void CStackFrame::ref(int xmm_reg,int var_size){
94 if(var_size==sizeof(double)){
95 //movlpd xmm_reg,qword ptr[rsp+offset]
96 op_movlpd_RM(xmm_reg,REG_RSP,now_sp,MOD_BASE_DISP32);
97 }
98 if(var_size==sizeof(float)){
99 //movss xmm_reg,dword ptr[rsp+offset]
100 OpBuffer[obp++]=(char)0xF3;
101 OpBuffer[obp++]=(char)0x0F;
102 OpBuffer[obp++]=(char)0x10;
103 OpBuffer[obp++]=(char)(0x84| REGISTER_OPERAND(xmm_reg)<<3 );
104 OpBuffer[obp++]=(char)0x24;
105 *((long *)(OpBuffer+obp))=now_sp;
106 obp+=sizeof(long);
107 }
108
109 //スケジュールをセット
110 obp-=sizeof(long);
111 add();
112 obp+=sizeof(long);
113}
114void CStackFrame::pop(int reg){
115 if(reg!=REG_NON) ref(reg);
116
117 now_sp+=sizeof(_int64);
118}
119void CStackFrame::pop(int xmm_reg,int var_size){
120 ref(xmm_reg,var_size);
121
122 now_sp+=sizeof(_int64);
123}
124void CStackFrame::parameter_allocate(int size){
125 if(max_parm_size<size) max_parm_size=size;
126}
127void CStackFrame::RunningSchedule(void){
128 int i;
129 int all_size;
130 all_size=GetFrameSize();
131 for(i=0;i<num;i++){
132 *((long *)(OpBuffer+pObpValues[i]))+=all_size;
133 }
134}
135
136void CStackFrame::error_check(){
137 if(now_sp){
138 SetError(300,NULL,cp);
139 }
140}
141
142//スタックフレーム管理用オブジェクトポインタ
143CStackFrame *pobj_sf;
Note: See TracBrowser for help on using the repository browser.