diff options
| author | 2025-09-09 12:57:08 +0200 | |
|---|---|---|
| committer | 2025-09-09 12:57:08 +0200 | |
| commit | 1cc69f922b79127d4cbaa61716397f0bfb85ede7 (patch) | |
| tree | 43953b8986ec363c9426608aa8574beaea9f0e34 /amd64 | |
| parent | 3bac8a6bc4f04ed9d302896264809b191477e11b (diff) | |
ioper
Diffstat (limited to 'amd64')
| -rw-r--r-- | amd64/emit.c | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/amd64/emit.c b/amd64/emit.c index 5c9fb2a..8a2ca64 100644 --- a/amd64/emit.c +++ b/amd64/emit.c @@ -10,7 +10,7 @@ */ enum operkind { ONONE, OREG, OIMM, OMEM, OSYM }; enum { NOBASE = 63, NOINDEX = 63 }; -static struct oper { +struct oper { uchar t; union { struct { uchar base; }; /* OMEM */ @@ -25,17 +25,24 @@ static struct oper { int disp; /* OMEM, OSYM */ int imm; /* OIMM */ }; -} ioper[MAXINSTR]; +}; #define mkoper(t, ...) ((struct oper){(t), __VA_ARGS__}) #define reg2oper(R) (assert((uint)(R) <= XMM15), mkoper(OREG, .reg = (R))) static struct oper mkmemoper(union ref); static struct oper +ioper(int i) +{ + int reg = instrtab[i].reg - 1; + return reg < 0 ? mkoper(ONONE,) : reg2oper(reg); +} + +static struct oper ref2oper(union ref r) { switch (r.t) { - case RTMP: return ioper[r.i]; + case RTMP: return ioper(r.i); case RREG: return reg2oper(r.i); case RICON: return mkoper(OIMM, .imm = r.i); case RXCON: @@ -71,8 +78,8 @@ addmemoper(struct oper *mem, struct oper add) static inline struct oper mkregoper(union ref r) { - assert(r.t == RREG || (r.t == RTMP && ioper[r.i].t == OREG)); - return r.t == RREG ? reg2oper(r.i) : ioper[r.i]; + assert(r.t == RREG || (r.t == RTMP && ioper(r.i).t == OREG)); + return r.t == RREG ? reg2oper(r.i) : ioper(r.i); } static inline struct oper @@ -82,8 +89,8 @@ mkimmoper(union ref r) return mkoper(OIMM, .imm = intconval(r)); } -#define ismemref(ref) ((ref).t == RTMP && ioper[(ref).i].t == OMEM) -#define isregref(ref) ((ref).t == RREG || ((ref).t == RTMP && ioper[(ref).i].t == OREG)) +#define ismemref(ref) ((ref).t == RTMP && ioper((ref).i).t == OMEM) +#define isregref(ref) ((ref).t == RREG || ((ref).t == RTMP && ioper((ref).i).t == OREG)) static inline struct oper mkimmregoper(union ref r) @@ -110,15 +117,15 @@ static struct oper mkmemoper(union ref r) { if (r.t == RTMP) { - struct oper wop = ioper[r.i]; + struct oper wop = ioper(r.i); if (wop.t == OMEM) return wop; assert(wop.t == OREG); return mkoper(OMEM, .base = wop.reg, .index = NOINDEX); } else if (r.t == RADDR) { const struct addr *addr = &addrht[r.i]; struct oper mem; - if (addr->base.t == RTMP && ioper[addr->base.i].t == OMEM) { - mem = ioper[addr->base.i]; + if (addr->base.t == RTMP && ioper(addr->base.i).t == OMEM) { + mem = ioper(addr->base.i); if (addr->index.bits) addmemoper(&mem, mkregoper(addr->index)); assert(!mem.shift); mem.shift = addr->shift; @@ -330,8 +337,10 @@ encode(uchar **pcode, const struct desc *tab, int ntab, enum irclass k, struct o if (mem.base == RSP || mem.base == R12) sib = 1; D(opc, nopc); B(mod << 6 | (reg & 7) << 3 | (sib ? 4 : (mem.base & 7))); - if (sib) + if (sib) { + if (mem.index == NOINDEX) mem.index = RSP; B(mem.shift << 6 | (mem.index & 7) << 3 | (mem.base & 7)); + } if (mod == 1) B(mem.disp); else if (mod == 2 || (mod == 0 && mem.base == RBP/*RIP-rel*/)) { I32(mem.disp); @@ -945,7 +954,7 @@ emitinstr(uchar **pcode, struct function *fn, struct block *blk, int curi, struc Xcall(pcode, KPTR, ref2oper(ins->l)); break; } - if (ins->reg) ioper[ins - instrtab] = reg2oper(ins->reg-1); + // if (ins->reg) ioper(ins - instrtab) = reg2oper(ins->reg-1); } static void |