OpenCores
URL https://opencores.org/ocsvn/thor/thor/trunk

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v5/] [software/] [CC64/] [source/] [FPRegister.cpp] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2012-2016  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch<remove>@finitron.ca
6
//       ||
7
//
8
// C32 - 'C' derived language compiler
9
//  - 32 bit CPU
10
//
11
// This source file is free software: you can redistribute it and/or modify 
12
// it under the terms of the GNU Lesser General Public License as published 
13
// by the Free Software Foundation, either version 3 of the License, or     
14
// (at your option) any later version.                                      
15
//                                                                          
16
// This source file is distributed in the hope that it will be useful,      
17
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
18
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
19
// GNU General Public License for more details.                             
20
//                                                                          
21
// You should have received a copy of the GNU General Public License        
22
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
23
//                                                                          
24
// ============================================================================
25
//
26
#include "stdafx.h"
27
/*
28
int tmpregs[] = {3,4,5,6,7,8,9,10};
29
int regstack[8];
30
int rsp=7;
31
int regmask=0;
32
 
33
int tmpbregs[] = {3,4,5,6,7,8};
34
int bregstack[6];
35
int brsp=5;
36
int bregmask = 0;
37
*/
38
static short int next_fpreg;
39
#define MAX_REG 4                       /* max. scratch data    register (D2) */
40
#define MAX_REG_STACK   30
41
 
42
// Only registers 5,6,7 and 8 are used for temporaries
43
static short int fpreg_in_use[256];     // 0 to 15
44
static short int save_fpreg_in_use[256];
45
 
46
static struct {
47
    enum e_am mode;
48
    short int reg;
49
        union {
50
                char isPushed;  /* flags if pushed or corresponding reg_alloc * number */
51
                char allocnum;
52
        } f;
53
}
54
        fpreg_stack[MAX_REG_STACK + 1],
55
        fpreg_alloc[MAX_REG_STACK + 1],
56
        save_fpreg_alloc[MAX_REG_STACK + 1],
57
        stacked_fpregs[MAX_REG_STACK + 1];
58
 
59
static short int fpreg_stack_ptr;
60
static short int fpreg_alloc_ptr;
61
static short int save_fpreg_alloc_ptr;
62
 
63
char tmpfpregs[] = {3,4,5,6,7,8,9,10};
64
char regfpstack[18];
65
int fprsp=17;
66
int fpregmask=0;
67
 
68
void initFPRegStack()
69
{
70
        int i;
71
 
72
    next_fpreg = 3;
73
        //for (rsp=0; rsp < 3; rsp=rsp+1)
74
        //      regstack[rsp] = tmpregs[rsp];
75
        //rsp = 0;
76
        for (i = 0; i <= 255; i++) {
77
                fpreg_in_use[i] = -1;
78
        }
79
    fpreg_stack_ptr = 0;
80
    fpreg_alloc_ptr = 0;
81
//    act_scratch = 0;
82
    memset(fpreg_stack,0,sizeof(fpreg_stack));
83
    memset(fpreg_alloc,0,sizeof(fpreg_alloc));
84
    memset(stacked_fpregs,0,sizeof(stacked_fpregs));
85
    memset(save_fpreg_alloc,0,sizeof(save_fpreg_alloc));
86
}
87
 
88
void GenerateTempFPRegPush(int reg, int rmode, int number)
89
{
90
        AMODE *ap1;
91
    ap1 = allocAmode();
92
    ap1->preg = reg;
93
    ap1->mode = rmode;
94
    ap1->isFloat = TRUE;
95
 
96
        GenerateMonadic(op_push,'t',ap1);
97
        TRACE(printf("pushing r%d\r\n", reg);)
98
    fpreg_stack[fpreg_stack_ptr].mode = (enum e_am)rmode;
99
    fpreg_stack[fpreg_stack_ptr].reg = reg;
100
    fpreg_stack[fpreg_stack_ptr].f.allocnum = number;
101
    if (fpreg_alloc[number].f.isPushed=='T')
102
                fatal("GenerateTempRegPush(): register already pushed");
103
    fpreg_alloc[number].f.isPushed = 'T';
104
        if (++fpreg_stack_ptr > MAX_REG_STACK)
105
                fatal("GenerateTempRegPush(): register stack overflow");
106
}
107
 
108
void GenerateTempFPRegPop(int reg, int rmode, int number)
109
{
110
        AMODE *ap1;
111
 
112
    if (fpreg_stack_ptr-- == -1)
113
                fatal("GenerateTempRegPop(): register stack underflow");
114
    /* check if the desired register really is on stack */
115
    if (fpreg_stack[fpreg_stack_ptr].f.allocnum != number)
116
                fatal("GenerateTempRegPop()/2");
117
        if (fpreg_in_use[reg] >= 0)
118
                fatal("GenerateTempRegPop():register still in use");
119
        TRACE(printf("popped r%d\r\n", reg);)
120
        fpreg_in_use[reg] = number;
121
        ap1 = allocAmode();
122
        ap1->preg = reg;
123
        ap1->mode = rmode;
124
        ap1->isFloat = TRUE;
125
        GenerateMonadic(op_pop,'t',ap1);
126
    fpreg_alloc[number].f.isPushed = 'F';
127
}
128
 
129
void initfpstack()
130
{
131
        initFPRegStack();
132
}
133
 
134
AMODE *GetTempFPRegister()
135
{
136
        AMODE *ap;
137
 
138
        if (fpreg_in_use[next_fpreg] >= 0)
139
                GenerateTempFPRegPush(next_fpreg, am_fpreg, fpreg_in_use[next_fpreg]);
140
        TRACE(printf("GetTempRegister:r%d\r\n", next_fpreg);)
141
    fpreg_in_use[next_fpreg] = fpreg_alloc_ptr;
142
    ap = allocAmode();
143
    ap->mode = am_fpreg;
144
    ap->preg = next_fpreg;
145
    ap->deep = fpreg_alloc_ptr;
146
    ap->isFloat = TRUE;
147
    fpreg_alloc[fpreg_alloc_ptr].reg = next_fpreg;
148
    fpreg_alloc[fpreg_alloc_ptr].mode = am_fpreg;
149
    fpreg_alloc[fpreg_alloc_ptr].f.isPushed = 'F';
150
    if (next_fpreg++ >= 10)
151
                next_fpreg = 3;         /* wrap around */
152
    if (fpreg_alloc_ptr++ == MAX_REG_STACK)
153
                fatal("GetTempRegister(): register stack overflow");
154
        return ap;
155
}
156
 
157
/*
158
 * this routines checks if all allocated registers were freed
159
 */
160
void checkfpstack()
161
{
162
    int i;
163
    for (i=3; i<= 10; i++)
164
        if (fpreg_in_use[i] != -1)
165
            fatal("checkstack()/1");
166
        if (next_fpreg != 3) {
167
                //printf("Nextreg: %d\r\n", next_reg);
168
        fatal("checkstack()/3");
169
        }
170
    if (fpreg_stack_ptr != 0)
171
        fatal("checkstack()/5");
172
    if (fpreg_alloc_ptr != 0)
173
        fatal("checkstack()/6");
174
}
175
 
176
/*
177
 * validate will make sure that if a register within an address mode has been
178
 * pushed onto the stack that it is popped back at this time.
179
 */
180
void validateFP(AMODE *ap)
181
{
182
    switch (ap->mode) {
183
        case am_fpreg:
184
                if ((ap->preg >= 3 && ap->preg <= 10) && fpreg_alloc[ap->deep].f.isPushed == 'T' ) {
185
                        GenerateTempFPRegPop(ap->preg, am_fpreg, (int) ap->deep);
186
                }
187
                break;
188
    }
189
}
190
 
191
 
192
/*
193
 * release any temporary registers used in an addressing mode.
194
 */
195
void ReleaseTempFPRegister(AMODE *ap)
196
{
197
    int number;
198
 
199
        TRACE(printf("ReleaseTempFPRegister:r%d r%d\r\n", ap->preg, ap->sreg);)
200
 
201
        if (ap==NULL) {
202
                printf("DIAG - NULL pointer in ReleaseTempRegister\r\n");
203
                return;
204
        }
205
 
206
//      validate(ap);
207
    switch (ap->mode) {
208
        case am_fpreg:
209
                if (ap->preg >= 3 && ap->preg <= 10) {
210
                        if (fpreg_in_use[ap->preg]==-1)
211
                                return;
212
                        if (next_fpreg-- <= 3)
213
                                next_fpreg = 10;
214
                        number = fpreg_in_use[ap->preg];
215
                        fpreg_in_use[ap->preg] = -1;
216
                        break;
217
                }
218
                return;
219
    default:
220
                return;
221
    }
222
 //   /* some consistency checks */
223
        //if (number != ap->deep) {
224
        //      printf("number %d ap->deep %d\r\n", number, ap->deep);
225
        //      //fatal("ReleaseTempRegister()/1");
226
        //}
227
        if (fpreg_alloc_ptr-- == 0)
228
                fatal("ReleaseTempRegister(): no registers are allocated");
229
  //  if (reg_alloc_ptr != number)
230
                //fatal("ReleaseTempRegister()/3");
231
    if (fpreg_alloc[number].f.isPushed=='T')
232
                fatal("ReleaseTempRegister(): register on stack");
233
}
234
 
235
// The following is used to save temporary registers across function calls.
236
// Save the list of allocated registers and registers in use.
237
// Go through the allocated register list and generate a push instruction to
238
// put the register on the stack if it isn't already on the stack.
239
 
240
int TempFPInvalidate()
241
{
242
    int i;
243
        int sp;
244
 
245
        sp = 0;
246
        TRACE(printf("TempFPInvalidate()\r\n");)
247
        save_fpreg_alloc_ptr = fpreg_alloc_ptr;
248
        memcpy(save_fpreg_alloc, fpreg_alloc, sizeof(save_fpreg_alloc));
249
        memcpy(save_fpreg_in_use, fpreg_in_use, sizeof(save_fpreg_in_use));
250
        for (i = 0; i < fpreg_alloc_ptr; i++) {
251
        if (fpreg_in_use[fpreg_alloc[i].reg] != -1) {
252
                if (fpreg_alloc[i].f.isPushed == 'F') {
253
                        GenerateTempFPRegPush(fpreg_alloc[i].reg, fpreg_alloc[i].mode, i);
254
                        stacked_fpregs[sp].reg = fpreg_alloc[i].reg;
255
                        stacked_fpregs[sp].mode = fpreg_alloc[i].mode;
256
                        stacked_fpregs[sp].f.allocnum = i;
257
                        sp++;
258
                        // mark the register void
259
                        fpreg_in_use[fpreg_alloc[i].reg] = -1;
260
                }
261
        }
262
        }
263
        return sp;
264
}
265
 
266
// Pop back any temporary registers that were pushed before the function call.
267
// Restore the allocated and in use register lists.
268
 
269
void TempFPRevalidate(int sp)
270
{
271
        int nn;
272
 
273
        for (nn = sp-1; nn >= 0; nn--)
274
                GenerateTempFPRegPop(stacked_fpregs[nn].reg, stacked_fpregs[nn].mode, stacked_fpregs[nn].f.allocnum);
275
        fpreg_alloc_ptr = save_fpreg_alloc_ptr;
276
        memcpy(fpreg_alloc, save_fpreg_alloc, sizeof(fpreg_alloc));
277
        memcpy(fpreg_in_use, save_fpreg_in_use, sizeof(fpreg_in_use));
278
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.