source: dev/BasicCompiler64/Register.cpp @ 131

Last change on this file since 131 was 131, checked in by dai_9181, 16 years ago

Prototypeクラスを用意した。

File size: 6.2 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}
228bool CRegister::IsUsing( int reg ){
229    int i;
230
231    //汎用レジスタを調べる
232    for(i=init_sp_reg;i>sp_UseReg;i--){
233        if( array_UseReg[i] == reg ) return true;
234    }
235
236    //XMMレジスタを調べる
237    for(i=init_sp_xmm_reg;i>sp_XmmReg;i--){
238        if( array_XmmReg[i] == reg ) return true;
239    }
240
241    //ブロックされている場合を考慮
242    if( pobj_BlockReg->check( reg ) ) return true;
243
244    //使用中でないとき
245    return false;
246}
247void CRegister::backup(){
248    int i;
249
250    //汎用レジスタを退避
251    for(i=init_sp_reg;i>sp_UseReg;i--){
252        //mov qword ptr[rsp+offset],reg     ※スタックフレームを利用
253        pobj_sf->push(array_UseReg[i]);
254    }
255
256    //XMMレジスタを退避
257    for(i=init_sp_xmm_reg;i>sp_XmmReg;i--){
258        //mov qword ptr[rsp+offset],reg     ※スタックフレームを利用
259        pobj_sf->push(array_XmmReg[i],sizeof(_int64));
260    }
261}
262void CRegister::restore(){
263    int i;
264
265    //XMMレジスタを復元
266    if(sp_XmmReg<0) i=0;
267    else i=sp_XmmReg+1;
268    for(;i<=init_sp_xmm_reg;i++){
269        //mov reg,qword ptr[rsp+offset]     ※スタックフレームを利用
270        pobj_sf->pop(array_XmmReg[i],sizeof(_int64));
271    }
272
273    //汎用レジスタを復元
274    if(sp_UseReg<0) i=0;
275    else i=sp_UseReg+1;
276    for(;i<=init_sp_reg;i++){
277        //mov reg,qword ptr[rsp+offset]     ※スタックフレームを利用
278        pobj_sf->pop(array_UseReg[i]);
279    }
280}
281
282
283
284////////////////////////
285// その他
286////////////////////////
287
288BOOL IsGeneralReg(int reg){
289    if(REG_RAX<=reg&&reg<=REG_R15) return 1;
290    return 0;
291}
292BOOL IsXmmReg(int reg){
293    if(REG_XMM0<=reg&&reg<=REG_XMM15) return 1;
294    return 0;
295}
296BOOL IsVolatileReg(int reg){
297    if(reg==REG_RAX||
298        reg==REG_RCX||
299        reg==REG_RDX||
300        REG_R8<=reg&&reg<=REG_R11||
301        REG_XMM0<=reg&&reg<=REG_XMM5){
302        //値を保持する必要なし
303        return 1;
304    }
305    else{
306        //値を保持する必要あり
307        return 0;
308    }
309}
310
311void IfR14Push( int reg ){
312    if( reg == REG_R14 ){
313        //mov qword ptr[rsp+offset],r14     ※スタックフレームを利用
314        pobj_sf->push( REG_R14 );
315    }
316}
Note: See TracBrowser for help on using the repository browser.