mirror of
git://c9x.me/qbe.git
synced 2026-04-05 18:09:47 +00:00
arm64: prevent bogus IP1 clobbers
This commit is contained in:
parent
03da40271f
commit
73f0accb45
45
arm64/emit.c
45
arm64/emit.c
@ -109,6 +109,10 @@ static struct {
|
|||||||
{ NOp, 0, 0 }
|
{ NOp, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
V31 = 0x1fffffff, /* local name for V31 */
|
||||||
|
};
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
rname(int r, int k)
|
rname(int r, int k)
|
||||||
{
|
{
|
||||||
@ -132,6 +136,12 @@ rname(int r, int k)
|
|||||||
case Kx:
|
case Kx:
|
||||||
case Kd: sprintf(buf, "d%d", r-V0); break;
|
case Kd: sprintf(buf, "d%d", r-V0); break;
|
||||||
}
|
}
|
||||||
|
else if (r == V31)
|
||||||
|
switch (k) {
|
||||||
|
default: die("invalid class");
|
||||||
|
case Ks: sprintf(buf, "s31"); break;
|
||||||
|
case Kd: sprintf(buf, "d31"); break;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
die("invalid register");
|
die("invalid register");
|
||||||
return buf;
|
return buf;
|
||||||
@ -197,12 +207,12 @@ emitf(char *s, Ins *i, E *e)
|
|||||||
if (KBASE(k) == 0)
|
if (KBASE(k) == 0)
|
||||||
fputs(rname(IP1, k), e->f);
|
fputs(rname(IP1, k), e->f);
|
||||||
else
|
else
|
||||||
fputs(k==Ks ? "s31" : "d31", e->f);
|
fputs(rname(V31, k), e->f);
|
||||||
break;
|
break;
|
||||||
case '=':
|
case '=':
|
||||||
case '0':
|
case '0':
|
||||||
r = c == '=' ? i->to : i->arg[0];
|
r = c == '=' ? i->to : i->arg[0];
|
||||||
assert(isreg(r));
|
assert(isreg(r) || req(r, TMP(V31)));
|
||||||
fputs(rname(r.val, k), e->f);
|
fputs(rname(r.val, k), e->f);
|
||||||
break;
|
break;
|
||||||
case '1':
|
case '1':
|
||||||
@ -335,8 +345,8 @@ loadcon(Con *c, int r, int k, E *e)
|
|||||||
|
|
||||||
static void emitins(Ins *, E *);
|
static void emitins(Ins *, E *);
|
||||||
|
|
||||||
static void
|
static int
|
||||||
fixarg(Ref *pr, int sz, E *e)
|
fixarg(Ref *pr, int sz, int t, E *e)
|
||||||
{
|
{
|
||||||
Ins *i;
|
Ins *i;
|
||||||
Ref r;
|
Ref r;
|
||||||
@ -346,11 +356,14 @@ fixarg(Ref *pr, int sz, E *e)
|
|||||||
if (rtype(r) == RSlot) {
|
if (rtype(r) == RSlot) {
|
||||||
s = slot(r, e);
|
s = slot(r, e);
|
||||||
if (s > sz * 4095u) {
|
if (s > sz * 4095u) {
|
||||||
i = &(Ins){Oaddr, Kl, TMP(IP1), {r}};
|
if (t < 0)
|
||||||
|
return 1;
|
||||||
|
i = &(Ins){Oaddr, Kl, TMP(t), {r}};
|
||||||
emitins(i, e);
|
emitins(i, e);
|
||||||
*pr = TMP(IP1);
|
*pr = TMP(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -358,16 +371,28 @@ emitins(Ins *i, E *e)
|
|||||||
{
|
{
|
||||||
char *l, *p, *rn;
|
char *l, *p, *rn;
|
||||||
uint64_t s;
|
uint64_t s;
|
||||||
int o;
|
int o, t;
|
||||||
Ref r;
|
Ref r;
|
||||||
Con *c;
|
Con *c;
|
||||||
|
|
||||||
switch (i->op) {
|
switch (i->op) {
|
||||||
default:
|
default:
|
||||||
if (isload(i->op))
|
if (isload(i->op))
|
||||||
fixarg(&i->arg[0], loadsz(i), e);
|
fixarg(&i->arg[0], loadsz(i), IP1, e);
|
||||||
if (isstore(i->op))
|
if (isstore(i->op)) {
|
||||||
fixarg(&i->arg[1], storesz(i), e);
|
t = T.apple ? -1 : R18;
|
||||||
|
if (fixarg(&i->arg[1], storesz(i), t, e)) {
|
||||||
|
if (req(i->arg[0], TMP(IP1))) {
|
||||||
|
fprintf(e->f,
|
||||||
|
"\tfmov\t%c31, %c17\n",
|
||||||
|
"ds"[i->cls == Kw],
|
||||||
|
"xw"[i->cls == Kw]);
|
||||||
|
i->arg[0] = TMP(V31);
|
||||||
|
i->op = Ostores + (i->cls-Kw);
|
||||||
|
}
|
||||||
|
fixarg(&i->arg[1], storesz(i), IP1, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
Table:
|
Table:
|
||||||
/* most instructions are just pulled out of
|
/* most instructions are just pulled out of
|
||||||
* the table omap[], some special cases are
|
* the table omap[], some special cases are
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user