diff options
| author | 2026-03-19 11:51:13 +0100 | |
|---|---|---|
| committer | 2026-03-19 11:51:13 +0100 | |
| commit | 46fc55e27390ea85eb34ec0367f40426197c9b9f (patch) | |
| tree | e7fab125f4f5a0da5d1f8e47d3a5301f501e5a35 | |
| parent | 85afa319cae05bcd39de0f4f63d22a49bbd0e665 (diff) | |
regalloc & emit: explicit comparisons over memcmp of small structures
The one in x86-64_emit was not portable due to relying on zero
initialization of inactive union fields/padding.
| -rw-r--r-- | src/ir_regalloc.c | 2 | ||||
| -rw-r--r-- | src/t_x86-64_emit.c | 20 |
2 files changed, 19 insertions, 3 deletions
diff --git a/src/ir_regalloc.c b/src/ir_regalloc.c index ddb05e2..54f5d59 100644 --- a/src/ir_regalloc.c +++ b/src/ir_regalloc.c @@ -210,7 +210,7 @@ typedef struct { static void pmadd(PMState *pms, enum irclass k, Alloc dst, Alloc src) { - if (!memcmp(&dst, &src, sizeof dst)) return; + if (dst.bits == src.bits) return; assert(pms->npmove < MAXREGS); pms->pmove[pms->npmove++] = (struct PMove) { k, PMTOMOVE, dst, src }; } diff --git a/src/t_x86-64_emit.c b/src/t_x86-64_emit.c index e1df982..507955a 100644 --- a/src/t_x86-64_emit.c +++ b/src/t_x86-64_emit.c @@ -160,6 +160,22 @@ mkmemoper(Ref r) } } +static bool +opereql(Oper a, Oper b) +{ + if (a.t != b.t) return 0; + switch (a.t) { + case OREG: return a.reg == b.reg; + case OIMM: return a.imm == b.imm; + case OMEM: + return a.base == b.base && a.index == b.index && a.shift == b.shift && a.disp == b.disp; + case OSYM: + case OSYMGOT: + return a.cindex == b.cindex && a.cshift == b.cshift && a.con == b.con && a.disp == b.disp; + default: assert(0); + } +} + /** Instruction description tables ** * * Each instruction is a list of descs, and the first one that matches @@ -703,7 +719,7 @@ static const EncDesc imul3_imm8tab[] = { static void Ximul(uchar **pcode, enum irclass k, Oper dst, Oper s1, Oper s2) { - if (!memcmp(&dst, &s1, sizeof dst) && s2.t != OIMM) { + if (opereql(dst, s1) && s2.t != OIMM) { Ximul2(pcode, k, dst, s2); return; } @@ -908,7 +924,7 @@ gencopy(uchar **pcode, enum irclass cls, Block *blk, int curi, Oper dst, Ref val *pcode += 8; } else { Oper src = mkimmdatregoper(val); - if (memcmp(&dst, &src, sizeof dst) != 0) + if (!opereql(dst, src)) Xmov(pcode, cls == KF64 && src.t == OREG && src.reg < XMM0 ? KI64 : cls, dst, src); } } |