source: dev/BasicCompiler64/Register.cpp@ 3

Last change on this file since 3 was 3, checked in by dai_9181, 17 years ago
File size: 5.7 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "Opcode.h"
3
4
5//エラー用
6extern int cp;
7
8
9////////////////////////////
10// レジスタのブロッキング
11////////////////////////////
12
13CBlockReg *pobj_BlockReg;
14
15CBlockReg::CBlockReg(){
16 num=0;
17}
18void CBlockReg::lock(int reg){
19 if(check(reg)){
20 SetError(300,NULL,cp);
21 }
22 array_BlockReg[num++]=reg;
23}
24void CBlockReg::unlock(int reg){
25 int i;
26 for(i=0;i<num;i++){
27 if(array_BlockReg[i]==reg) break;
28 }
29 if(i==num) return;
30
31 num--;
32 for(;i<num;i++){
33 array_BlockReg[i]=array_BlockReg[i+1];
34 }
35}
36BOOL CBlockReg::check(int reg){
37 int i;
38 for(i=0;i<num;i++){
39 if(array_BlockReg[i]==reg) return 1;
40 }
41 return 0;
42}
43void CBlockReg::clear(void){
44 num=0;
45}
46void CBlockReg::backup(){
47 int i;
48
49 for(i=num-1;i>=0;i--){
50 if(IS_XMM_REG(array_BlockReg[i])){
51 //movlpd qword ptr[rsp+offset],xmm_reg ※スタックフレームを利用
52 pobj_sf->push(array_BlockReg[i],sizeof(double));
53 }
54 else{
55 //mov qword ptr[rsp+offset],reg ※スタックフレームを利用
56 pobj_sf->push(array_BlockReg[i]);
57 }
58 }
59}
60void CBlockReg::restore(){
61 int i;
62
63 for(i=0;i<num;i++){
64 if(IS_XMM_REG(array_BlockReg[i])){
65 //movlpd xmm_reg,qword ptr[rsp+offset] ※スタックフレームを利用
66 pobj_sf->pop(array_BlockReg[i],sizeof(double));
67 }
68 else{
69 //mov reg,qword ptr[rsp+offset] ※スタックフレームを利用
70 pobj_sf->pop(array_BlockReg[i]);
71 }
72 }
73}
74
75
76///////////////////
77// レジスタ管理
78///////////////////
79
80const int CalculationRegister[]={
81 REG_RAX,
82 REG_RCX,
83 REG_RDX,
84 REG_RBX,
85 REG_RSI,
86 REG_RDI,
87 REG_R8,
88 REG_R9,
89 REG_R10
90};
91
92const int CalculationXmmRegister[]={
93 REG_XMM0,
94 REG_XMM1,
95 REG_XMM2,
96 REG_XMM3,
97 /*XMM4、XMM5は演算時に一時的に利用*/
98/* REG_XMM6,
99 REG_XMM7,
100 REG_XMM8,
101 REG_XMM9,
102 REG_XMM10,
103 REG_XMM11,
104 REG_XMM12,
105 REG_XMM13,
106 REG_XMM14,
107 REG_XMM15 関数呼び出し時のレジスタ保持を未搭載のため、保留*/
108};
109
110CRegister *pobj_reg;
111
112void CRegister::EnumRegister(int *pRegList,int nMaxList,int *array_reg,int *sp,int AnswerReg){
113 int i,i2,sw=0;
114
115 i2=nMaxList-1;
116 for(i=0;i2>=0;i++,i2--){
117 if(AnswerReg==pRegList[i2]){
118 sw=1;
119 i--;
120 continue;
121 }
122
123 if(pobj_BlockReg->check(pRegList[i2])){
124 //レジスタがブロッキングされているとき
125 i--;
126 continue;
127 }
128
129 array_reg[i]=pRegList[i2];
130 }
131
132 if(sw){
133 array_reg[i++]=AnswerReg;
134
135 //エラーチェック
136 if(pobj_BlockReg->check(AnswerReg)) SetError(300,NULL,cp);
137 }
138
139 *sp=i-1;
140}
141
142CRegister::CRegister(int AnswerReg){
143 /* 例: AnswerReg=REG_RCX ※REG_RCXをスタックの最後尾へセット
144 ※r15、r14は一時保存用として利用する
145 ※r13は同一関数内の単発処理用の一時保存レジスタとして利用する
146 ※r12、r11は配列計算用として利用する
147 array_UseReg[0]=REG_R10
148 array_UseReg[1]=REG_R9
149 array_UseReg[2]=REG_R8
150 array_UseReg[3]=REG_RBX
151 array_UseReg[4]=REG_RDX
152 array_UseReg[5]=REG_RAX
153 array_UseReg[6]=REG_RCX */
154
155
156 ///////////////////////////////////////////////////////////
157 //array_UseRegに、計算に利用するレジスタリストを作成
158 ///////////////////////////////////////////////////////////
159
160 EnumRegister(
161 (int *)CalculationRegister,
162 sizeof(CalculationRegister)/sizeof(int),
163 array_UseReg,
164 &sp_UseReg,
165 AnswerReg);
166
167
168
169 ///////////////////////////////////////////////////////////
170 //array_XmmRegに、計算に利用するレジスタリストを作成
171 ///////////////////////////////////////////////////////////
172
173 EnumRegister(
174 (int *)CalculationXmmRegister,
175 sizeof(CalculationXmmRegister)/sizeof(int),
176 array_XmmReg,
177 &sp_XmmReg,
178 AnswerReg);
179
180
181 init_sp_reg=sp_UseReg;
182 init_sp_xmm_reg=sp_XmmReg;
183}
184void CRegister::bug_check(){
185 if(init_sp_reg!=sp_UseReg||
186 init_sp_xmm_reg!=sp_XmmReg) SetError(300,NULL,cp);
187}
188int CRegister::GetNextReg(){
189 if(sp_UseReg<0) return REG_R14;
190 return array_UseReg[sp_UseReg];
191}
192int CRegister::GetLockingReg(){
193 UnlockReg();
194 return LockReg();
195}
196int CRegister::LockReg(){
197 int reg;
198 reg=GetNextReg();
199
200 sp_UseReg--;
201
202 return reg;
203}
204int CRegister::UnlockReg(){
205 sp_UseReg++;
206 return GetNextReg();
207}
208int CRegister::GetNextXmmReg(){
209 if(sp_XmmReg<0) return REG_XMM4;
210 return array_XmmReg[sp_XmmReg];
211}
212int CRegister::GetLockingXmmReg(){
213 UnlockXmmReg();
214 return LockXmmReg();
215}
216int CRegister::LockXmmReg(){
217 int xmm_reg;
218 xmm_reg=GetNextXmmReg();
219
220 sp_XmmReg--;
221
222 return xmm_reg;
223}
224int CRegister::UnlockXmmReg(){
225 sp_XmmReg++;
226 return GetNextXmmReg();
227}
228void CRegister::backup(){
229 int i;
230
231 //汎用レジスタを退避
232 for(i=init_sp_reg;i>sp_UseReg;i--){
233 //mov qword ptr[rsp+offset],reg ※スタックフレームを利用
234 pobj_sf->push(array_UseReg[i]);
235 }
236
237 //XMMレジスタを退避
238 for(i=init_sp_xmm_reg;i>sp_XmmReg;i--){
239 //mov qword ptr[rsp+offset],reg ※スタックフレームを利用
240 pobj_sf->push(array_XmmReg[i],sizeof(_int64));
241 }
242}
243void CRegister::restore(){
244 int i;
245
246 //XMMレジスタを復元
247 if(sp_XmmReg<0) i=0;
248 else i=sp_XmmReg+1;
249 for(;i<=init_sp_xmm_reg;i++){
250 //mov reg,qword ptr[rsp+offset] ※スタックフレームを利用
251 pobj_sf->pop(array_XmmReg[i],sizeof(_int64));
252 }
253
254 //汎用レジスタを復元
255 if(sp_UseReg<0) i=0;
256 else i=sp_UseReg+1;
257 for(;i<=init_sp_reg;i++){
258 //mov reg,qword ptr[rsp+offset] ※スタックフレームを利用
259 pobj_sf->pop(array_UseReg[i]);
260 }
261}
262
263
264
265////////////////////////
266// その他
267////////////////////////
268
269BOOL IsGeneralReg(int reg){
270 if(REG_RAX<=reg&&reg<=REG_R15) return 1;
271 return 0;
272}
273BOOL IsXmmReg(int reg){
274 if(REG_XMM0<=reg&&reg<=REG_XMM15) return 1;
275 return 0;
276}
277BOOL IsVolatileReg(int reg){
278 if(reg==REG_RAX||
279 reg==REG_RCX||
280 reg==REG_RDX||
281 REG_R8<=reg&&reg<=REG_R11||
282 REG_XMM0<=reg&&reg<=REG_XMM5){
283 //値を保持する必要なし
284 return 1;
285 }
286 else{
287 //値を保持する必要あり
288 return 0;
289 }
290}
Note: See TracBrowser for help on using the repository browser.