source: dev/trunk/abdev/BasicCompiler64/stack_frame.cpp@ 225

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

[64bitコンパイラ] スタックフレームが128ビット境界ラインにならないバグを修正

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