6c: extern register fix (import from patch/6c-extreg)

to make it easy to use normal libraries (such as libdraw, libsec, and libmp)
with the kernel, which uses extern register, don't stray into the external
register set when allocating values to registers.
This commit is contained in:
cinap_lenrek 2012-09-18 18:18:43 +02:00
parent 36f4f9fcd3
commit 3ba213a9d7
4 changed files with 18 additions and 6 deletions

View file

@ -10,7 +10,7 @@ typedef unsigned long long uintptr;
typedef unsigned long usize; typedef unsigned long usize;
typedef ushort Rune; typedef ushort Rune;
typedef union FPdbleword FPdbleword; typedef union FPdbleword FPdbleword;
typedef uvlong jmp_buf[2]; typedef uintptr jmp_buf[2];
#define JMPBUFSP 0 #define JMPBUFSP 0
#define JMPBUFPC 1 #define JMPBUFPC 1
#define JMPBUFDPC 0 #define JMPBUFDPC 0

View file

@ -50,6 +50,8 @@ regopt(Prog *p)
lastr = R; lastr = R;
nvar = 0; nvar = 0;
regbits = RtoB(D_SP) | RtoB(D_AX) | RtoB(D_X0); regbits = RtoB(D_SP) | RtoB(D_AX) | RtoB(D_X0);
if(REGEXT)
regbits |= RtoB(REGEXT) | RtoB(REGEXT-1);
for(z=0; z<BITS; z++) { for(z=0; z<BITS; z++) {
externs.b[z] = 0; externs.b[z] = 0;
params.b[z] = 0; params.b[z] = 0;

View file

@ -1,5 +1,7 @@
#include "gc.h" #include "gc.h"
static int resvreg[nelem(reg)];
void void
ginit(void) ginit(void)
{ {
@ -94,6 +96,7 @@ ginit(void)
if(0) if(0)
com64init(); com64init();
memset(reg, 0, sizeof(reg));
for(i=0; i<nelem(reg); i++) { for(i=0; i<nelem(reg); i++) {
reg[i] = 1; reg[i] = 1;
if(i >= D_AX && i <= D_R15 && i != D_SP) if(i >= D_AX && i <= D_R15 && i != D_SP)
@ -101,6 +104,10 @@ ginit(void)
if(i >= D_X0 && i <= D_X7) if(i >= D_X0 && i <= D_X7)
reg[i] = 0; reg[i] = 0;
} }
/* keep two external registers */
reg[REGEXT] = 1;
reg[REGEXT-1] = 1;
memmove(resvreg, reg, sizeof(resvreg));
} }
void void
@ -111,10 +118,10 @@ gclean(void)
reg[D_SP]--; reg[D_SP]--;
for(i=D_AX; i<=D_R15; i++) for(i=D_AX; i<=D_R15; i++)
if(reg[i]) if(reg[i] && !resvreg[i])
diag(Z, "reg %R left allocated", i); diag(Z, "reg %R left allocated", i);
for(i=D_X0; i<=D_X7; i++) for(i=D_X0; i<=D_X7; i++)
if(reg[i]) if(reg[i] && !resvreg[i])
diag(Z, "reg %R left allocated", i); diag(Z, "reg %R left allocated", i);
while(mnstring) while(mnstring)
outstring("", 1L); outstring("", 1L);
@ -179,7 +186,7 @@ nareg(void)
n = 0; n = 0;
for(i=D_AX; i<=D_R15; i++) for(i=D_AX; i<=D_R15; i++)
if(reg[i] == 0) if(reg[i] == 0 && !resvreg[i])
n++; n++;
return n; return n;
} }
@ -337,7 +344,7 @@ regalloc(Node *n, Node *tn, Node *o)
goto out; goto out;
} }
for(i=D_AX; i<=D_R15; i++) for(i=D_AX; i<=D_R15; i++)
if(reg[i] == 0) if(reg[i] == 0 && !resvreg[i])
goto out; goto out;
diag(tn, "out of fixed registers"); diag(tn, "out of fixed registers");
goto err; goto err;
@ -350,7 +357,7 @@ regalloc(Node *n, Node *tn, Node *o)
goto out; goto out;
} }
for(i=D_X0; i<=D_X7; i++) for(i=D_X0; i<=D_X7; i++)
if(reg[i] == 0) if(reg[i] == 0 && !resvreg[i])
goto out; goto out;
diag(tn, "out of float registers"); diag(tn, "out of float registers");
goto out; goto out;

View file

@ -668,6 +668,9 @@ asmandsz(Adr *a, int r, int rex, int m64)
rex &= (0x40 | Rxr); rex &= (0x40 | Rxr);
v = a->offset; v = a->offset;
if ((vlong)v != a->offset)
print("asmandsz: Trying to emit %#ullx and 32 bits is not sufficient\n",
a->offset);
t = a->type; t = a->type;
if(a->index != D_NONE) { if(a->index != D_NONE) {
if(t >= D_INDIR) { if(t >= D_INDIR) {