source: dev/trunk/abdev/BasicCompiler64/Register.cpp@ 339

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

コード全体のリファクタリングを実施

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