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

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v5/] [software/] [CC64/] [source/] [Register.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-2018  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch<remove>@finitron.ca
6
//       ||
7
//
8
// CC64 - 'C' derived language compiler
9
//  - 64 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
extern void initFPRegStack();
29
extern void ReleaseTempFPRegister(Operand *);
30
/*
31
int tmpregs[] = {3,4,5,6,7,8,9,10};
32
int regstack[8];
33
int rsp=7;
34
int regmask=0;
35
 
36
int tmpbregs[] = {3,4,5,6,7,8};
37
int bregstack[6];
38
int brsp=5;
39
int bregmask = 0;
40
*/
41
static unsigned short int next_reg;
42
static unsigned short int next_fpreg;
43
static unsigned short int next_vreg;
44
static unsigned short int next_vmreg;
45
static short int next_breg;
46
#define MAX_REG 4                       /* max. scratch data    register (D2) */
47
#define MAX_REG_STACK   30
48
 
49
// Only registers 5,6,7 and 8 are used for temporaries
50
static short int reg_in_use[256];       // 0 to 15
51
static short int fpreg_in_use[256];     // 0 to 15
52
static short int breg_in_use[16];       // 0 to 15
53
static short int save_reg_in_use[256];
54
static short int save_fpreg_in_use[256];
55
static short int vreg_in_use[256];      // 0 to 15
56
static short int save_vreg_in_use[256];
57
static short int vmreg_in_use[256];     // 0 to 15
58
 
59
static int wrapno, save_wrapno;
60
 
61
static struct {
62
        Operand *Operand;
63
    short int reg;
64
        struct {
65
        char isPushed;  /* flags if pushed or corresponding reg_alloc * number */
66
        char allocnum;
67
        } f;
68
}
69
        reg_stack[MAX_REG_STACK + 1],
70
        reg_alloc[MAX_REG_STACK + 1],
71
        save_reg_alloc[MAX_REG_STACK + 1],
72
        fpreg_stack[MAX_REG_STACK + 1],
73
        fpreg_alloc[MAX_REG_STACK + 1],
74
        save_fpreg_alloc[MAX_REG_STACK + 1],
75
        stacked_regs[MAX_REG_STACK + 1],
76
        stacked_fpregs[MAX_REG_STACK + 1],
77
        breg_stack[MAX_REG_STACK + 1],
78
        breg_alloc[MAX_REG_STACK + 1],
79
        vreg_stack[MAX_REG_STACK + 1],
80
        vreg_alloc[MAX_REG_STACK + 1],
81
        vmreg_stack[MAX_REG_STACK + 1],
82
        vmreg_alloc[MAX_REG_STACK + 1],
83
        save_vreg_alloc[MAX_REG_STACK + 1],
84
        save_vmreg_alloc[MAX_REG_STACK + 1],
85
        stacked_vregs[MAX_REG_STACK + 1],
86
        stacked_vmregs[MAX_REG_STACK + 1]
87
;
88
 
89
static short int reg_stack_ptr;
90
static short int reg_alloc_ptr;
91
static short int save_reg_alloc_ptr;
92
static short int fpreg_stack_ptr;
93
static short int fpreg_alloc_ptr;
94
static short int save_fpreg_alloc_ptr;
95
static short int vreg_stack_ptr;
96
static short int vreg_alloc_ptr;
97
static short int save_vreg_alloc_ptr;
98
static short int vmreg_stack_ptr;
99
static short int vmreg_alloc_ptr;
100
static short int save_vmreg_alloc_ptr;
101
static short int breg_stack_ptr;
102
static short int breg_alloc_ptr;
103
 
104
char tmpregs[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
105
char tmpfpregs[] = {1,2,3,4,5,6,7,8,9,10};
106
char tmpvregs[] = {1,2,3,4,5,6,7,8,9,10};
107
char tmpvmregs[] = {1,2,3};
108
char tmpbregs[] = {5,6,7};
109
char regstack[18];
110
char fpregstack[18];
111
char bregstack[18];
112
int rsp=17;
113
int regmask=0;
114
int brsp=17;
115
int bregmask=0;
116
int rap[20];
117
int save_rap[20];
118
 
119
int NumTempRegs()
120
{
121
        if (currentFn->IsLeaf)
122
                return (regLastTemp - 1 + 1);
123
        else
124
                return (regLastTemp - regFirstTemp + 1);
125
}
126
 
127
void initRegStack()
128
{
129
        int i;
130
        Function *sym = currentFn;
131
 
132
        next_reg = sym->IsLeaf ? 1 : regFirstTemp;
133
        next_fpreg = sym->IsLeaf ? 1 : regFirstTemp;
134
        next_vreg = sym->IsLeaf ? 1 : regFirstTemp;
135
        next_vmreg = 1;
136
    next_breg = 5;
137
        //for (rsp=0; rsp < 3; rsp=rsp+1)
138
        //      regstack[rsp] = tmpregs[rsp];
139
        //rsp = 0;
140
        for (i = 0; i <= 255; i++) {
141
                reg_in_use[i] = -1;
142
                fpreg_in_use[i] = -1;
143
                vreg_in_use[i] = -1;
144
                vmreg_in_use[i] = -1;
145
                breg_in_use[i&15] = -1;
146
        }
147
    reg_stack_ptr = 0;
148
    reg_alloc_ptr = 0;
149
    fpreg_stack_ptr = 0;
150
    fpreg_alloc_ptr = 0;
151
    vreg_stack_ptr = 0;
152
    vreg_alloc_ptr = 0;
153
    vmreg_stack_ptr = 0;
154
    vmreg_alloc_ptr = 0;
155
    breg_stack_ptr = 0;
156
    breg_alloc_ptr = 0;
157
//    act_scratch = 0;
158
    memset(reg_stack,0,sizeof(reg_stack));
159
    memset(reg_alloc,0,sizeof(reg_alloc));
160
    memset(fpreg_stack,0,sizeof(fpreg_stack));
161
    memset(fpreg_alloc,0,sizeof(fpreg_alloc));
162
    memset(vreg_stack,0,sizeof(vreg_stack));
163
    memset(vreg_alloc,0,sizeof(vreg_alloc));
164
    memset(vmreg_stack,0,sizeof(vmreg_stack));
165
    memset(vmreg_alloc,0,sizeof(vmreg_alloc));
166
    memset(breg_stack,0,sizeof(breg_stack));
167
    memset(breg_alloc,0,sizeof(breg_alloc));
168
    memset(stacked_regs,0,sizeof(stacked_regs));
169
    memset(stacked_fpregs,0,sizeof(stacked_fpregs));
170
    memset(save_reg_alloc,0,sizeof(save_reg_alloc));
171
    memset(save_fpreg_alloc,0,sizeof(save_fpreg_alloc));
172
    memset(stacked_vregs,0,sizeof(stacked_vregs));
173
    memset(save_vreg_alloc,0,sizeof(save_vreg_alloc));
174
    memset(save_vmreg_alloc,0,sizeof(save_vmreg_alloc));
175
        wrapno = 0;
176
        ZeroMemory(rap, sizeof(rap));
177
}
178
 
179
// Spill a register to memory.
180
 
181
void SpillRegister(Operand *ap, int number)
182
{
183
        GenerateDiadic(op_sw,0,ap,make_indexed(currentFn->GetTempBot()-ap->deep*sizeOfWord,regFP));
184
    //reg_stack[reg_stack_ptr].Operand = ap;
185
    //reg_stack[reg_stack_ptr].f.allocnum = number;
186
    if (reg_alloc[number].f.isPushed=='T')
187
                fatal("SpillRegister(): register already spilled");
188
    reg_alloc[number].f.isPushed = 'T';
189
}
190
 
191
void SpillFPRegister(Operand *ap, int number)
192
{
193
        GenerateDiadic(op_sf,'d',ap,make_indexed(currentFn->GetTempBot()-ap->deep*sizeOfWord,regFP));
194
    fpreg_stack[fpreg_stack_ptr].Operand = ap;
195
    fpreg_stack[fpreg_stack_ptr].f.allocnum = number;
196
    if (fpreg_alloc[number].f.isPushed=='T')
197
                fatal("SpillRegister(): register already spilled");
198
    reg_alloc[number].f.isPushed = 'T';
199
}
200
 
201
// Load register from memory.
202
 
203
void LoadRegister(int regno, int number)
204
{
205
        if (reg_in_use[regno] >= 0)
206
                fatal("LoadRegister():register still in use");
207
        reg_in_use[regno] = number;
208
        GenerateDiadic(op_lw,0,makereg(regno),make_indexed(currentFn->GetTempBot()-number*sizeOfWord,regFP));
209
    reg_alloc[number].f.isPushed = 'F';
210
}
211
 
212
void LoadFPRegister(int regno, int number)
213
{
214
        if (fpreg_in_use[regno] >= 0)
215
                fatal("LoadRegister():register still in use");
216
        fpreg_in_use[regno] = number;
217
        GenerateDiadic(op_lf,'d',makefpreg(regno),make_indexed(currentFn->GetTempBot()-number*sizeOfWord,regFP));
218
    fpreg_alloc[number].f.isPushed = 'F';
219
}
220
 
221
void GenerateTempRegPush(int reg, int rmode, int number, int stkpos)
222
{
223
        Operand *ap1;
224
    ap1 = allocOperand();
225
    ap1->preg = reg;
226
    ap1->mode = rmode;
227
 
228
        GenerateMonadic(op_push,0,ap1);
229
        TRACE(printf("pushing r%d\r\n", reg);)
230
    reg_stack[reg_stack_ptr].Operand = ap1;
231
    reg_stack[reg_stack_ptr].reg = reg;
232
    reg_stack[reg_stack_ptr].f.allocnum = number;
233
    if (reg_alloc[number].f.isPushed=='T')
234
                fatal("GenerateTempRegPush(): register already pushed");
235
    reg_alloc[number].f.isPushed = 'T';
236
        if (++reg_stack_ptr > MAX_REG_STACK)
237
                fatal("GenerateTempRegPush(): register stack overflow");
238
}
239
 
240
void GenerateTempVectorRegPush(int reg, int rmode, int number, int stkpos)
241
{
242
        Operand *ap1;
243
    ap1 = allocOperand();
244
    ap1->preg = reg;
245
    ap1->mode = rmode;
246
 
247
        GenerateMonadic(op_push,0,ap1);
248
        TRACE(printf("pushing r%d\r\n", reg);)
249
    vreg_stack[vreg_stack_ptr].Operand = ap1;
250
    vreg_stack[vreg_stack_ptr].reg = reg;
251
    vreg_stack[vreg_stack_ptr].f.allocnum = number;
252
    if (vreg_alloc[number].f.isPushed=='T')
253
                fatal("GenerateTempRegPush(): register already pushed");
254
    vreg_alloc[number].f.isPushed = 'T';
255
        if (++vreg_stack_ptr > MAX_REG_STACK)
256
                fatal("GenerateTempRegPush(): register stack overflow");
257
}
258
 
259
void GenerateTempRegPop(int reg, int rmode, int number, int stkpos)
260
{
261
        Operand *ap1;
262
 
263
    if (reg_stack_ptr-- == -1)
264
                fatal("GenerateTempRegPop(): register stack underflow");
265
    /* check if the desired register really is on stack */
266
    if (reg_stack[reg_stack_ptr].f.allocnum != number)
267
                fatal("GenerateTempRegPop()/2");
268
        if (reg_in_use[reg] >= 0)
269
                fatal("GenerateTempRegPop():register still in use");
270
        TRACE(printf("popped r%d\r\n", reg);)
271
        reg_in_use[reg] = number;
272
        ap1 = allocOperand();
273
        ap1->preg = reg;
274
        ap1->mode = rmode;
275
        GenerateMonadic(op_pop,0,ap1);
276
    reg_alloc[number].f.isPushed = 'F';
277
}
278
 
279
void initstack()
280
{
281
        initRegStack();
282
        //initFPRegStack();
283
}
284
 
285
Operand *GetTempRegister()
286
{
287
        Operand *ap;
288
    Function *sym = currentFn;
289
        int number;
290
 
291
        number = reg_in_use[next_reg];
292
        if (number >= 0) {// && number < rap[wrapno]) {
293
                SpillRegister(makereg(next_reg),number);
294
        }
295
        TRACE(printf("GetTempRegister:r%d\r\n", next_reg);)
296
    reg_in_use[next_reg] = reg_alloc_ptr;
297
    ap = allocOperand();
298
    ap->mode = am_reg;
299
    ap->preg = next_reg;
300
        ap->pdeep = ap->deep;
301
    ap->deep = reg_alloc_ptr;
302
    reg_alloc[reg_alloc_ptr].reg = next_reg;
303
    reg_alloc[reg_alloc_ptr].Operand = ap;
304
    reg_alloc[reg_alloc_ptr].f.isPushed = 'F';
305
        if (next_reg++ >= regLastTemp) {
306
                wrapno++;
307
                rap[wrapno] = reg_alloc_ptr;
308
                next_reg = sym->IsLeaf ? 1 : regFirstTemp;              /* wrap around */
309
        }
310
    if (reg_alloc_ptr++ == MAX_REG_STACK)
311
                fatal("GetTempRegister(): register stack overflow");
312
        return (ap);
313
}
314
 
315
Operand *GetTempVectorRegister()
316
{
317
        Operand *ap;
318
    Function *sym = currentFn;
319
 
320
        if (vreg_in_use[next_vreg] >= 0) {
321
//              if (isThor)     
322
//                      GenerateTriadic(op_addui,0,makereg(regSP),makereg(regSP),make_immed(-8));
323
                GenerateTempVectorRegPush(next_vreg, am_reg, vreg_in_use[next_vreg],0);
324
        }
325
        TRACE(printf("GetTempRegister:r%d\r\n", next_vreg);)
326
    vreg_in_use[next_vreg] = vreg_alloc_ptr;
327
    ap = allocOperand();
328
    ap->mode = am_reg;
329
    ap->preg = next_vreg;
330
    ap->deep = vreg_alloc_ptr;
331
        ap->type = stdvector.GetIndex();
332
    vreg_alloc[vreg_alloc_ptr].reg = next_vreg;
333
    vreg_alloc[vreg_alloc_ptr].Operand = ap;
334
    vreg_alloc[vreg_alloc_ptr].f.isPushed = 'F';
335
    if (next_vreg++ >= 10)
336
                next_vreg = sym->IsLeaf ? 1 : 3;                /* wrap around */
337
    if (vreg_alloc_ptr++ == MAX_REG_STACK)
338
                fatal("GetTempVectorRegister(): register stack overflow");
339
        return ap;
340
}
341
 
342
Operand *GetTempVectorMaskRegister()
343
{
344
        Operand *ap;
345
    SYM *sym = currentFn->sym;
346
 
347
        if (vmreg_in_use[next_vmreg] >= 0) {
348
//              GenerateTempVectorMaskRegPush(next_vreg, am_reg, vreg_in_use[next_vreg],0);
349
        }
350
        TRACE(printf("GetTempRegister:r%d\r\n", next_vmreg);)
351
    vmreg_in_use[next_vreg] = vmreg_alloc_ptr;
352
    ap = allocOperand();
353
    ap->mode = am_vmreg;
354
    ap->preg = next_vmreg;
355
    ap->deep = vmreg_alloc_ptr;
356
        ap->type = stdvectormask->GetIndex();
357
    vmreg_alloc[vmreg_alloc_ptr].reg = next_vmreg;
358
    vmreg_alloc[vmreg_alloc_ptr].Operand = ap;
359
    vmreg_alloc[vmreg_alloc_ptr].f.isPushed = 'F';
360
    if (next_vmreg++ >= 3)
361
                next_vmreg = 1;         /* wrap around */
362
    if (vmreg_alloc_ptr++ == MAX_REG_STACK)
363
                fatal("GetTempVectorRegister(): register stack overflow");
364
        return (ap);
365
}
366
 
367
Operand *GetTempFPRegister()
368
{
369
        Operand *ap;
370
    Function *sym = currentFn;
371
        int number;
372
 
373
        number = fpreg_in_use[next_fpreg];
374
        if (number >= 0) {
375
                SpillFPRegister(fpreg_alloc[number].Operand,number);
376
        }
377
//      if (reg_in_use[next_reg] >= 0) {
378
//              GenerateTempRegPush(next_reg, am_reg, reg_in_use[next_reg],0);
379
//      }
380
        TRACE(printf("GetTempFPRegister:r%d\r\n", next_fpreg);)
381
    fpreg_in_use[next_fpreg] = fpreg_alloc_ptr;
382
    ap = allocOperand();
383
    ap->mode = am_fpreg;
384
    ap->preg = next_fpreg;
385
    ap->deep = fpreg_alloc_ptr;
386
        ap->type = stddouble.GetIndex();
387
    fpreg_alloc[fpreg_alloc_ptr].reg = next_fpreg;
388
    fpreg_alloc[fpreg_alloc_ptr].Operand = ap;
389
    fpreg_alloc[fpreg_alloc_ptr].f.isPushed = 'F';
390
    if (next_fpreg++ >= regLastTemp)
391
        next_fpreg = sym->IsLeaf ? 1 : regFirstTemp;            /* wrap around */
392
    if (fpreg_alloc_ptr++ == MAX_REG_STACK)
393
                fatal("GetTempFPRegister(): register stack overflow");
394
        return (ap);
395
}
396
//void RestoreTempRegs(int rgmask)
397
//{
398
//      int nn;
399
//      int rm;
400
//      int i;
401
//
402
//      nn = 0;
403
// 
404
//      for(nn = rgmask; nn > 0; nn--)
405
//              GenerateTempRegPop(0,0,0);
406
//      //if (rgmask != 0) {
407
//      //      for (nn = 1, rm = rgmask; nn <= 15; nn = nn + 1)
408
//      //              if ((rm>>nn) & 1) {
409
//      //                      GenerateMonadic(op_pop,0,makereg(nn));
410
//      //                      reg_in_use[nn] = 0;
411
//      //              }
412
//      //}
413
//}
414
 
415
//void RestoreTempBrRegs(int brgmask)
416
//{
417
//      int nn;
418
//      int rm;
419
//      int i;
420
//
421
//      nn = 0;
422
// 
423
//      for(nn = brgmask; nn > 0; nn--)
424
//              GenerateTempBrRegPop(0,0,0);
425
//}
426
 
427
/*
428
 * this routines checks if all allocated registers were freed
429
 */
430
void checkstack()
431
{
432
    int i;
433
    Function *sym = currentFn;
434
 
435
    for (i=1; i<= regLastTemp; i++)
436
        if (reg_in_use[i] != -1)
437
            fatal("checkstack()/1");
438
        if (next_reg != sym->IsLeaf ? 1 : regFirstTemp) {
439
                //printf("Nextreg: %d\r\n", next_reg);
440
        fatal("checkstack()/3");
441
        }
442
    if (reg_stack_ptr != 0)
443
        fatal("checkstack()/5");
444
    if (reg_alloc_ptr != 0)
445
        fatal("checkstack()/6");
446
}
447
 
448
void checkbrstack()
449
{
450
    int i;
451
    for (i=5; i<= 8; i++)
452
        if (breg_in_use[i] != -1)
453
            fatal("checkbstack()/1");
454
        if (next_breg != 5) {
455
                //printf("Nextreg: %d\r\n", next_breg);
456
        fatal("checkbstack()/3");
457
        }
458
    if (breg_stack_ptr != 0)
459
        fatal("checkbstack()/5");
460
    if (breg_alloc_ptr != 0)
461
        fatal("checkbstack()/6");
462
}
463
 
464
/*
465
 * validate will make sure that if a register within an address mode has been
466
 * pushed onto the stack that it is popped back at this time.
467
 */
468
void validate(Operand *ap)
469
{
470
    Function *sym = currentFn;
471
        unsigned int frg = sym->IsLeaf ? 1 : (unsigned)regFirstTemp;
472
 
473
        if (ap->type!=stdvector.GetIndex())
474
    switch (ap->mode) {
475
        case am_reg:
476
                if ((ap->preg >= frg && ap->preg <= (unsigned)regLastTemp) && reg_alloc[ap->pdeep].f.isPushed == 'T' ) {
477
                        LoadRegister(ap->preg, (int) ap->pdeep);
478
                }
479
                break;
480
        case am_fpreg:
481
                if ((ap->preg >= frg && ap->preg <= (unsigned)regLastTemp) && fpreg_alloc[ap->deep].f.isPushed == 'T' ) {
482
                        LoadFPRegister(ap->preg, (int) ap->deep);
483
                }
484
                break;
485
    case am_indx2:
486
                if ((ap->preg >= frg && ap->preg <= (unsigned)regLastTemp) && reg_alloc[ap->deep].f.isPushed == 'T') {
487
                        LoadRegister(ap->preg, (int) ap->deep);
488
                }
489
                if ((ap->sreg >= frg && ap->sreg <= (unsigned)regLastTemp) && reg_alloc[ap->deep2].f.isPushed  == 'T') {
490
                        LoadRegister(ap->sreg, (int) ap->deep2);
491
                }
492
                break;
493
    case am_ind:
494
    case am_indx:
495
    case am_ainc:
496
    case am_adec:
497
                if ((ap->preg >= frg && ap->preg <= (unsigned)regLastTemp) && reg_alloc[ap->deep].f.isPushed == 'T') {
498
                        LoadRegister(ap->preg, (int) ap->deep);
499
                }
500
                break;
501
    }
502
}
503
 
504
 
505
/*
506
 * release any temporary registers used in an addressing mode.
507
 */
508
void ReleaseTempRegister(Operand *ap)
509
{
510
        int nn;
511
    int number;
512
    Function *sym = currentFn;
513
        unsigned int frg = sym->IsLeaf ? 1 : regFirstTemp;
514
 
515
        TRACE(printf("ReleaseTempRegister:r%d r%d\r\n", ap->preg, ap->sreg);)
516
 
517
        if (ap==NULL) {
518
                printf("DIAG - NULL pointer in ReleaseTempRegister\r\n");
519
                return;
520
        }
521
 
522
        // Kludgy here. The register is being release so at the moment it
523
        // is in use until it's released. The in_use flag will cause
524
        // validate not to work. Need to keep the value of in_use for later.
525
        nn = reg_in_use[ap->preg];
526
        if (ap->type != stdvector.GetIndex() && ap->mode != am_fpreg)
527
                reg_in_use[ap->preg] = -1;
528
        validate(ap);
529
        reg_in_use[ap->preg] = nn;
530
 
531
        if (ap->type==stdvector.GetIndex()) {
532
                switch (ap->mode) {
533
                case am_vmreg:
534
                        if (ap->preg >= 1 && ap->preg <= 3) {
535
                                if (vmreg_in_use[ap->preg]==-1)
536
                                        return;
537
                                if (next_vmreg-- <= 1)
538
                                        next_vmreg = 3;
539
                                number = vmreg_in_use[ap->preg];
540
                                vmreg_in_use[ap->preg] = -1;
541
                                break;
542
                        }
543
                        return;
544
                case am_ind:
545
                case am_indx:
546
                case am_ainc:
547
                case am_adec:
548
                case am_reg:
549
        commonv:
550
                        if (ap->preg >= frg && ap->preg <= 10) {
551
                                if (vreg_in_use[ap->preg]==-1)
552
                                        return;
553
                                if (next_vreg-- <= frg)
554
                                        next_vreg = 10;
555
                                number = vreg_in_use[ap->preg];
556
                                vreg_in_use[ap->preg] = -1;
557
                                break;
558
                        }
559
                        return;
560
                case am_indx2:
561
                        if (ap->sreg >= frg && ap->sreg <= 10) {
562
                                if (vreg_in_use[ap->sreg]==-1)
563
                                        return;
564
                                if (next_vreg-- <= frg)
565
                                        next_vreg = 10;
566
                                number = vreg_in_use[ap->sreg];
567
                                vreg_in_use[ap->sreg] = -1;
568
                                //break;
569
                        }
570
                        goto commonv;
571
                default:
572
                        return;
573
                }
574
                if (vreg_alloc_ptr-- == 0)
575
                        fatal("ReleaseTempRegister(): no registers are allocated");
576
          //  if (reg_alloc_ptr != number)
577
                        //fatal("ReleaseTempRegister()/3");
578
                if (vreg_alloc[number].f.isPushed=='T')
579
                        fatal("ReleaseTempRegister(): register on stack");
580
                return;
581
        }
582
        else
583
    switch (ap->mode) {
584
        case am_fpreg:
585
                if (ap->preg >= frg && ap->preg <= (unsigned)regLastTemp) {
586
                        if (fpreg_in_use[ap->preg]==-1)
587
                                return;
588
                        if (next_fpreg-- <= frg)
589
                                next_fpreg = regLastTemp;
590
                        number = fpreg_in_use[ap->preg];
591
                        fpreg_in_use[ap->preg] = -1;
592
                        if (fpreg_alloc_ptr-- == 0)
593
                                fatal("ReleaseTempRegister(): no registers are allocated");
594
                  //  if (reg_alloc_ptr != number)
595
                                //fatal("ReleaseTempRegister()/3");
596
                        if (fpreg_alloc[number].f.isPushed=='T')
597
                                fatal("ReleaseTempRegister(): register on stack");
598
                        return;
599
                }
600
                return;
601
        case am_ind:
602
        case am_indx:
603
        case am_ainc:
604
        case am_adec:
605
        case am_reg:
606
common:
607
                if (ap->preg >= frg && ap->preg <= (unsigned)regLastTemp) {
608
                        if (reg_in_use[ap->preg]==-1)
609
                                return;
610
                        if (next_reg-- <= frg) {
611
                                next_reg = regLastTemp;
612
                                wrapno--;
613
                        }
614
                        number = reg_in_use[ap->preg];
615
                        reg_in_use[ap->preg] = -1;
616
                        break;
617
                }
618
                return;
619
    case am_indx2:
620
                if (ap->sreg >= frg && ap->sreg <= (unsigned)regLastTemp) {
621
                        if (reg_in_use[ap->sreg]==-1)
622
                                return;
623
                        if (next_reg-- <= frg) {
624
                                next_reg = regLastTemp;
625
                                wrapno--;
626
                        }
627
                        number = reg_in_use[ap->sreg];
628
                        reg_in_use[ap->sreg] = -1;
629
                        //break;
630
                }
631
                goto common;
632
    default:
633
                return;
634
    }
635
 //   /* some consistency checks */
636
        //if (number != ap->deep) {
637
        //      printf("number %d ap->deep %d\r\n", number, ap->deep);
638
        //      //fatal("ReleaseTempRegister()/1");
639
        //}
640
        if (reg_alloc_ptr-- == 0)
641
                fatal("ReleaseTempRegister(): no registers are allocated");
642
  //  if (reg_alloc_ptr != number)
643
                //fatal("ReleaseTempRegister()/3");
644
    if (reg_alloc[number].f.isPushed=='T')
645
                fatal("ReleaseTempRegister(): register on stack");
646
}
647
 
648
void ReleaseTempVectorMaskRegister()
649
{
650
}
651
 
652
void ReleaseTempVectorRegister()
653
{
654
}
655
 
656
// The following is used to save temporary registers across function calls.
657
// Save the list of allocated registers and registers in use.
658
// Go through the allocated register list and generate a push instruction to
659
// put the register on the stack if it isn't already on the stack.
660
 
661
int TempInvalidate(int *fsp)
662
{
663
    int i;
664
        int sp;
665
 
666
        sp = 0;
667
        TRACE(printf("TempInvalidate()\r\n");)
668
        save_wrapno = wrapno;
669
        save_reg_alloc_ptr = reg_alloc_ptr;
670
        memcpy(save_reg_alloc, reg_alloc, sizeof(save_reg_alloc));
671
        memcpy(save_reg_in_use, reg_in_use, sizeof(save_reg_in_use));
672
        memcpy(save_rap, rap, sizeof(rap));
673
        for (sp = i = 0; i < reg_alloc_ptr; i++) {
674
        if (reg_alloc[i].f.isPushed == 'F') {
675
                        // ToDo: fix this line
676
                        reg_alloc[i].Operand->mode = am_reg;
677
                        SpillRegister(reg_alloc[i].Operand, i);
678
                //GenerateTempRegPush(reg_alloc[i].reg, /*reg_alloc[i].Operand->mode*/am_reg, i, sp);
679
                stacked_regs[sp].reg = reg_alloc[i].reg;
680
                stacked_regs[sp].Operand = reg_alloc[i].Operand;
681
                stacked_regs[sp].f.allocnum = i;
682
                sp++;
683
                // mark the register void
684
                reg_in_use[reg_alloc[i].reg] = -1;
685
        }
686
        }
687
 
688
        save_fpreg_alloc_ptr = fpreg_alloc_ptr;
689
        memcpy(save_fpreg_alloc, fpreg_alloc, sizeof(save_fpreg_alloc));
690
        memcpy(save_fpreg_in_use, fpreg_in_use, sizeof(save_fpreg_in_use));
691
        for (*fsp = i = 0; i < fpreg_alloc_ptr; i++) {
692
        if (fpreg_in_use[fpreg_alloc[i].reg] != -1) {
693
                if (fpreg_alloc[i].f.isPushed == 'F') {
694
                                // ToDo: fix this line
695
                                fpreg_alloc[i].Operand->mode = am_fpreg;
696
                                SpillFPRegister(fpreg_alloc[i].Operand, i);
697
                        //GenerateTempRegPush(reg_alloc[i].reg, /*reg_alloc[i].Operand->mode*/am_reg, i, sp);
698
                        stacked_fpregs[sp].reg = fpreg_alloc[i].reg;
699
                        stacked_fpregs[sp].Operand = fpreg_alloc[i].Operand;
700
                        stacked_fpregs[sp].f.allocnum = i;
701
                        (*fsp)++;
702
                        // mark the register void
703
                        fpreg_in_use[fpreg_alloc[i].reg] = -1;
704
                }
705
        }
706
        }
707
        wrapno = 0;
708
        reg_alloc_ptr = 0;
709
        memset(reg_in_use, -1, sizeof(reg_in_use));
710
        ZeroMemory(reg_alloc, sizeof(reg_alloc));
711
        ZeroMemory(rap, sizeof(rap));
712
        return (sp);
713
}
714
 
715
// Pop back any temporary registers that were pushed before the function call.
716
// Restore the allocated and in use register lists.
717
 
718
void TempRevalidate(int sp, int fsp)
719
{
720
        int nn;
721
 
722
        for (nn = fsp-1; nn >= 0; nn--) {
723
                if (stacked_fpregs[nn].Operand)
724
                        LoadFPRegister(stacked_fpregs[nn].Operand->preg, stacked_fpregs[nn].f.allocnum);
725
                //GenerateTempRegPop(stacked_regs[nn].reg, /*stacked_regs[nn].Operand->mode*/am_reg, stacked_regs[nn].f.allocnum,sp-nn-1);
726
        }
727
        fpreg_alloc_ptr = save_fpreg_alloc_ptr;
728
        memcpy(fpreg_alloc, save_fpreg_alloc, sizeof(fpreg_alloc));
729
        memcpy(fpreg_in_use, save_fpreg_in_use, sizeof(fpreg_in_use));
730
 
731
        for (nn = sp-1; nn >= 0; nn--) {
732
                LoadRegister(stacked_regs[nn].Operand->preg, stacked_regs[nn].f.allocnum);
733
                //GenerateTempRegPop(stacked_regs[nn].reg, /*stacked_regs[nn].Operand->mode*/am_reg, stacked_regs[nn].f.allocnum,sp-nn-1);
734
        }
735
        wrapno = save_wrapno;
736
        reg_alloc_ptr = save_reg_alloc_ptr;
737
        memcpy(reg_alloc, save_reg_alloc, sizeof(reg_alloc));
738
        memcpy(reg_in_use, save_reg_in_use, sizeof(reg_in_use));
739
        memcpy(rap, save_rap, sizeof(rap));
740
}
741
 
742
/*
743
void initRegStack()
744
{
745
        for (rsp=0; rsp < 8; rsp=rsp+1)
746
                regstack[rsp] = tmpregs[rsp];
747
        for (brsp = 0; brsp < 6; brsp++)
748
                bregstack[brsp] = tmpbregs[brsp];
749
        rsp = 0;
750
        brsp = 0;
751
}
752
 
753
void ReleaseTempRegister(Operand *ap)
754
{
755
        if (ap==NULL) {
756
                printf("DIAG - NULL pointer in ReleaseTempRegister\r\n");
757
                return;
758
        }
759
        if( ap->mode == am_imm || ap->mode == am_direct )
760
        return;         // no registers used
761
        if (ap->mode == am_breg || ap->mode==am_brind) {
762
                if (ap->preg < 9 && ap->preg >= 3)
763
                        PushOnBrstk(ap->preg);
764
                return;
765
        }
766
        if(ap->preg < 11 && ap->preg >= 3)
767
                PushOnRstk(ap->preg);
768
}
769
*/
770
Operand *GetTempReg(int type)
771
{
772
        if (type==stdvectormask->GetIndex())
773
                return (GetTempVectorMaskRegister());
774
        else if (type==stdvector.GetIndex())
775
                return (GetTempVectorRegister());
776
        else if (type==stddouble.GetIndex())
777
                return (GetTempFPRegister());
778
        else
779
                return (GetTempRegister());
780
}
781
 
782
void ReleaseTempFPRegister(Operand *ap)
783
{
784
     ReleaseTempRegister(ap);
785
}
786
 
787
void ReleaseTempReg(Operand *ap)
788
{
789
        if (ap==nullptr)
790
                return;
791
        if (ap->type==stdvectormask->GetIndex())
792
                ReleaseTempVectorMaskRegister();
793
        else if (ap->type==stdvector.GetIndex())
794
                ReleaseTempVectorRegister();
795
        else if (ap->type==stddouble.GetIndex())
796
                ReleaseTempFPRegister(ap);
797
        else
798
                ReleaseTempRegister(ap);
799
}
800
 
801
int GetTempMemSpace()
802
{
803
        return (reg_alloc_ptr * sizeOfWord);
804
}
805
 
806
bool IsArgumentReg(int regno)
807
{
808
        return (regno >= regFirstArg && regno <= regLastArg);
809
}
810
 
811
bool IsCalleeSave(int regno)
812
{
813
        if (regno >= regFirstTemp && regno <= regLastTemp)
814
                return (true);
815
        if (regno==regSP || regno==regFP)
816
                return (true);
817
        if (regno==regTP)
818
                return (true);
819
        return(false);
820
}
821
 

powered by: WebSVN 2.1.0

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