summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2012-09-18 18:18:43 +0200
committercinap_lenrek <cinap_lenrek@gmx.de>2012-09-18 18:18:43 +0200
commit3ba213a9d79bfe52f9a8aa6834c67eac665de136 (patch)
tree6aa9f02d86e384b6296b508c1444dea37534ca8c
parent36f4f9fcd381d0423a48edee91d13e596c740c54 (diff)
downloadplan9front-3ba213a9d79bfe52f9a8aa6834c67eac665de136.tar.xz
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.
-rw-r--r--amd64/include/u.h2
-rw-r--r--sys/src/cmd/6c/reg.c2
-rw-r--r--sys/src/cmd/6c/txt.c17
-rw-r--r--sys/src/cmd/6l/span.c3
4 files changed, 18 insertions, 6 deletions
diff --git a/amd64/include/u.h b/amd64/include/u.h
index feb121703..8dce5066f 100644
--- a/amd64/include/u.h
+++ b/amd64/include/u.h
@@ -10,7 +10,7 @@ typedef unsigned long long uintptr;
typedef unsigned long usize;
typedef ushort Rune;
typedef union FPdbleword FPdbleword;
-typedef uvlong jmp_buf[2];
+typedef uintptr jmp_buf[2];
#define JMPBUFSP 0
#define JMPBUFPC 1
#define JMPBUFDPC 0
diff --git a/sys/src/cmd/6c/reg.c b/sys/src/cmd/6c/reg.c
index 32b9abf5d..43e21a4f3 100644
--- a/sys/src/cmd/6c/reg.c
+++ b/sys/src/cmd/6c/reg.c
@@ -50,6 +50,8 @@ regopt(Prog *p)
lastr = R;
nvar = 0;
regbits = RtoB(D_SP) | RtoB(D_AX) | RtoB(D_X0);
+ if(REGEXT)
+ regbits |= RtoB(REGEXT) | RtoB(REGEXT-1);
for(z=0; z<BITS; z++) {
externs.b[z] = 0;
params.b[z] = 0;
diff --git a/sys/src/cmd/6c/txt.c b/sys/src/cmd/6c/txt.c
index 24ac1db46..e3b9a9ee5 100644
--- a/sys/src/cmd/6c/txt.c
+++ b/sys/src/cmd/6c/txt.c
@@ -1,5 +1,7 @@
#include "gc.h"
+static int resvreg[nelem(reg)];
+
void
ginit(void)
{
@@ -94,6 +96,7 @@ ginit(void)
if(0)
com64init();
+ memset(reg, 0, sizeof(reg));
for(i=0; i<nelem(reg); i++) {
reg[i] = 1;
if(i >= D_AX && i <= D_R15 && i != D_SP)
@@ -101,6 +104,10 @@ ginit(void)
if(i >= D_X0 && i <= D_X7)
reg[i] = 0;
}
+ /* keep two external registers */
+ reg[REGEXT] = 1;
+ reg[REGEXT-1] = 1;
+ memmove(resvreg, reg, sizeof(resvreg));
}
void
@@ -111,10 +118,10 @@ gclean(void)
reg[D_SP]--;
for(i=D_AX; i<=D_R15; i++)
- if(reg[i])
+ if(reg[i] && !resvreg[i])
diag(Z, "reg %R left allocated", i);
for(i=D_X0; i<=D_X7; i++)
- if(reg[i])
+ if(reg[i] && !resvreg[i])
diag(Z, "reg %R left allocated", i);
while(mnstring)
outstring("", 1L);
@@ -179,7 +186,7 @@ nareg(void)
n = 0;
for(i=D_AX; i<=D_R15; i++)
- if(reg[i] == 0)
+ if(reg[i] == 0 && !resvreg[i])
n++;
return n;
}
@@ -337,7 +344,7 @@ regalloc(Node *n, Node *tn, Node *o)
goto out;
}
for(i=D_AX; i<=D_R15; i++)
- if(reg[i] == 0)
+ if(reg[i] == 0 && !resvreg[i])
goto out;
diag(tn, "out of fixed registers");
goto err;
@@ -350,7 +357,7 @@ regalloc(Node *n, Node *tn, Node *o)
goto out;
}
for(i=D_X0; i<=D_X7; i++)
- if(reg[i] == 0)
+ if(reg[i] == 0 && !resvreg[i])
goto out;
diag(tn, "out of float registers");
goto out;
diff --git a/sys/src/cmd/6l/span.c b/sys/src/cmd/6l/span.c
index 78399a2b3..ec36e1490 100644
--- a/sys/src/cmd/6l/span.c
+++ b/sys/src/cmd/6l/span.c
@@ -668,6 +668,9 @@ asmandsz(Adr *a, int r, int rex, int m64)
rex &= (0x40 | Rxr);
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;
if(a->index != D_NONE) {
if(t >= D_INDIR) {