aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
author lemon<lsof@mailbox.org>2025-10-22 09:56:49 +0200
committer lemon<lsof@mailbox.org>2025-10-22 09:56:49 +0200
commit031f539c86f168ee8d0d1b0dd34572863cc17282 (patch)
tree6362701adf77be17b1639fc5085fde4dd82a8ae9
parentf5714c5c553e9816eef4cfddef128ba2706fb118 (diff)
always keep volatile loads
-rw-r--r--c/c.c27
-rw-r--r--ir/regalloc.c4
2 files changed, 18 insertions, 13 deletions
diff --git a/c/c.c b/c/c.c
index 9aa4217..bde0ef1 100644
--- a/c/c.c
+++ b/c/c.c
@@ -785,7 +785,7 @@ Unary:
break;
case TKSTRLIT:
ty = mktype(((const char []){TYCHAR, TYSHORT, TYINT})[tk.wide]);
- ex = mkexpr(ESTRLIT, tk.span, mkarrtype(ty, 0, tk.len+1), .s = { (void *)tk.s, tk.len });
+ ex = mkexpr(ESTRLIT, tk.span, mkarrtype(ty, 0, tk.len+1), { .s.p = (void *)tk.s, .s.n = tk.len });
break;
case TKIDENT:
Ident:
@@ -2599,7 +2599,7 @@ expraddr(struct function *fn, const struct expr *ex)
}
static union ref
-genload(struct function *fn, union type t, union ref ref)
+genload(struct function *fn, union type t, union ref ref, bool volatyl)
{
struct instr ins = {0};
@@ -2614,6 +2614,7 @@ genload(struct function *fn, union type t, union ref ref)
default: assert(0);
}
ins.l = ref;
+ ins.keep = volatyl;
return addinstr(fn, ins);
}
@@ -2963,7 +2964,7 @@ compilecall(struct function *fn, const struct expr *ex)
}
static union ref
-genbitfload(struct function *fn, const union type ty, union ref *addr, const struct exgetfld *fld)
+genbitfload(struct function *fn, const union type ty, union ref *addr, const struct exgetfld *fld, bool volatyl)
{
enum irclass k = type2cls[scalartypet(ty)];
uint off = fld->off, bitsiz = fld->bitsiz, bitoff = fld->bitoff;
@@ -2973,7 +2974,7 @@ genbitfload(struct function *fn, const union type ty, union ref *addr, const str
assert(k);
if (off > 0)
*addr = addinstr(fn, mkinstr(Oadd, KPTR, .l = *addr, .r = mkintcon(KI4, off)));
- tmp = genload(fn, ty, *addr);
+ tmp = genload(fn, ty, *addr, volatyl);
if (!issigned(ty)) {
/* shift right and mask */
if (bitoff > 0)
@@ -3007,7 +3008,7 @@ genbitfstore(struct function *fn, const union type ty, union ref addr,
if (!tmp.bits) {
if (off > 0)
addr = addinstr(fn, mkinstr(Oadd, KPTR, .l = addr, .r = mkintcon(KI4, off)));
- tmp = genload(fn, ty, addr);
+ tmp = genload(fn, ty, addr, 0);
}
mask = (bitsiz == 64 ? -1ull : (1ull << bitsiz) - 1) << bitoff;
@@ -3055,15 +3056,15 @@ compileexpr(struct function *fn, const struct expr *ex, bool discard)
return mkintcon(cls, ex->i);
case ESYM:
if (discard && !(ex->qual & QVOLATILE)) return NOREF;
- return genload(fn, ex->ty, expraddr(fn, ex));
+ return genload(fn, ex->ty, expraddr(fn, ex), ex->qual & QVOLATILE);
case EGETF:
if (discard && !(ex->qual & QVOLATILE)) return NOREF;
if (ex->fld.bitsiz) {
/* bit-field */
r = expraddr(fn, ex->sub);
- return genbitfload(fn, ex->ty, &r, &ex->fld);
+ return genbitfload(fn, ex->ty, &r, &ex->fld, ex->qual & QVOLATILE);
}
- return genload(fn, ex->ty, expraddr(fn, ex));
+ return genload(fn, ex->ty, expraddr(fn, ex), ex->qual & QVOLATILE);
case ECAST:
if (ex->ty.t == TYVOID) {
expreffects(fn, sub);
@@ -3099,7 +3100,7 @@ compileexpr(struct function *fn, const struct expr *ex, bool discard)
discard &= (ex->qual & QVOLATILE) == 0;
r = compileexpr(fn, sub, discard);
if (discard) return NOREF;
- return genload(fn, ex->ty, r);
+ return genload(fn, ex->ty, r, ex->qual & QVOLATILE);
case EADDROF:
return expraddr(fn, sub);
case EMUL:
@@ -3154,7 +3155,7 @@ compileexpr(struct function *fn, const struct expr *ex, bool discard)
ins.op = ex->t == EPOSTINC ? Oadd : Osub;
ins.cls = cls;
r = expraddr(fn, sub);
- ins.l = genload(fn, sub->ty, r);
+ ins.l = genload(fn, sub->ty, r, sub->qual & QVOLATILE);
if (ex->ty.t == TYPTR)
ins.r = mkintcon(KI4, typesize(typechild(ex->ty)));
else
@@ -3166,7 +3167,7 @@ compileexpr(struct function *fn, const struct expr *ex, bool discard)
ins.op = ex->t == EPREINC ? Oadd : Osub;
ins.cls = cls;
r = expraddr(fn, sub);
- ins.l = genload(fn, sub->ty, r);
+ ins.l = genload(fn, sub->ty, r, sub->qual & QVOLATILE);
if (ex->ty.t == TYPTR)
ins.r = mkintcon(KI4, typesize(typechild(ex->ty)));
else
@@ -3255,13 +3256,13 @@ compileexpr(struct function *fn, const struct expr *ex, bool discard)
if (sub[0].t == EGETF && (bitsiz = sub[0].fld.bitsiz)) {
/* bit-field */
r = expraddr(fn, &sub[0].sub[0]);
- ins.l = genbitfload(fn, sub[0].ty, &r, &sub[0].fld);
+ ins.l = genbitfload(fn, sub[0].ty, &r, &sub[0].fld, sub[0].qual & QVOLATILE);
q = addinstr(fn, ins);
genbitfstore(fn, sub[0].ty, r, &sub[0].fld, ins.l, q);
} else {
bitsiz = 0;
r = expraddr(fn, &sub[0]);
- ins.l = genload(fn, ex->ty, r);
+ ins.l = genload(fn, ex->ty, r, ex->qual & QVOLATILE);
if ((ins.op != Oadd && ins.op != Osub) || cls != KPTR) {
ins.l = cvt(fn, ty, sub[0].ty, ins.l);
ins.r = cvt(fn, ex->ty, sub[1].ty, ins.r);
diff --git a/ir/regalloc.c b/ir/regalloc.c
index b9f5517..0dcb11c 100644
--- a/ir/regalloc.c
+++ b/ir/regalloc.c
@@ -1048,6 +1048,10 @@ devirt(struct rega *ra, struct block *blk)
insertinstr(blk, curi++, mkmove(ins->cls, ins->reg-1, ins->l.i));
ins->l.i = ins->reg-1;
}
+ if (!ins->reg && in_range(ins->op, Oloads1, Oloadf8)) {
+ assert(ins->keep);
+ ins->reg = kisint(ins->cls) ? mctarg->gprscratch+1 : mctarg->fprscratch+1;
+ }
}
return allnops;