aboutsummaryrefslogtreecommitdiffhomepage
path: root/x86_64
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2026-02-28 09:15:15 +0100
committerlemon <lsof@mailbox.org>2026-02-28 09:27:07 +0100
commitc739270317a409ac4c4782dabd5f9ff82d200045 (patch)
treea99e656bd26dd2ae7faae56b0f931bec9972cb45 /x86_64
parentc0db7d92c14b242daf008f7e3731a5d080e23fa1 (diff)
backend: fix edgecases where imm32 immediate overflows
Diffstat (limited to 'x86_64')
-rw-r--r--x86_64/isel.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/x86_64/isel.c b/x86_64/isel.c
index c4c78b8..637df7e 100644
--- a/x86_64/isel.c
+++ b/x86_64/isel.c
@@ -52,13 +52,19 @@ fixarg(union ref *r, struct instr *ins, struct block *blk, int *curi)
{
int sh;
enum op op = ins ? ins->op : 0;
+ enum irclass cls = ins ? ins->cls : 0;
+Begin:
if (r->t == RXCON) {
struct xcon *con = &contab.p[r->i];
if (in_range(op, Oshl, Oslr) && r == &ins->r) {
sh = con->i;
goto ShiftImm;
- } else if (in_range(op, Oadd, Osub) && con->i == 2147483648 && r == &ins->r) {
+ } else if (cls == KI32 && in_range(con->cls, KI64, KPTR)) {
+ *r = mkintcon(KI32, (int)con->i);
+ goto Begin;
+ }
+ if (in_range(op, Oadd, Osub) && con->i == 2147483648 && r == &ins->r) {
/* add X, INT32MAX+1 -> sub X, INT32MIN */
ins->op = Oadd + (op == Oadd);
*r = mkintcon(KI32, -2147483648);
@@ -74,8 +80,8 @@ fixarg(union ref *r, struct instr *ins, struct block *blk, int *curi)
uint ksiz = cls2siz[con->cls];
union type ctype;
/* can't use memory arg in rhs if lhs is memory */
- bool docopy = &ins->l != r && (oisstore(ins->op) || ins->l.t == RADDR);
- if (con->cls <= KPTR && in_range(ins->op, Ocopy, Omove)) /* in this case we can use movabs */
+ bool docopy = ins && &ins->l != r && (oisstore(ins->op) || ins->l.t == RADDR);
+ if (con->cls <= KPTR && in_range(op, Ocopy, Omove)) /* in this case we can use movabs */
return;
else if (!docopy || con->cls >= KF32) {
if (con->cls != KF32) {