diff options
| author | 2023-07-07 19:00:13 +0200 | |
|---|---|---|
| committer | 2023-07-07 19:00:13 +0200 | |
| commit | 2b78832d3e433e08d742011aa5b7f87396b24c7d (patch) | |
| tree | 8f5e25f203b54872cde9492245d42a2af60da02b /amd64/emit.c | |
| parent | 3a7675d100c8559bf53ef8043d446661b72f2e4e (diff) | |
amd64 codegen fixes
Diffstat (limited to 'amd64/emit.c')
| -rw-r--r-- | amd64/emit.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/amd64/emit.c b/amd64/emit.c index 088809d..6d6d70b 100644 --- a/amd64/emit.c +++ b/amd64/emit.c @@ -127,14 +127,14 @@ mkmemoper(union ref r) } if (isaddrcon(addr->base)) { return mkoper(OSYM, .con = addr->base.i, - .cindex = addr->index.bits ? mkregoper(addr->index).reg : NOINDEX, - .cshift = addr->shift, - .disp = addr->disp); + .cindex = addr->index.bits ? mkregoper(addr->index).reg : NOINDEX, + .cshift = addr->shift, + .disp = addr->disp); } else if (isaddrcon(addr->index)) { assert(!addr->shift); return mkoper(OSYM, .con = addr->index.i, - .cindex = addr->base.bits ? mkregoper(addr->base).reg : NOINDEX, - .disp = addr->disp); + .cindex = addr->base.bits ? mkregoper(addr->base).reg : NOINDEX, + .disp = addr->disp); } return mkoper(OMEM, .base = addr->base.bits ? mkregoper(addr->base).reg : NOBASE, .index = addr->index.bits ? mkregoper(addr->index).reg : NOINDEX, @@ -192,6 +192,7 @@ enum operenc { EN_I8, /* imm8 */ EN_I32, /* imm32 */ EN_R32, /* rel32 */ + NOPERENC, }; struct desc { uchar psiz; /* subset of {1,2,4,8} */ @@ -307,8 +308,10 @@ encode(uchar **pcode, const struct desc *tab, int ntab, enum irclass k, struct o D(opc, nopc); if (mem.cindex == NOINDEX) { /* %rip(var) */ + static uchar offs[NOPERENC] = { [EN_MI8] = 1, [EN_MI16] = 2, [EN_MI32] = 4 }; + int off = -4 - offs[en->operenc]; B(/*mod 0*/ (reg & 7) << 3 | RBP); - objreloc(xcon2sym(mem.con), REL_PCREL32, Stext, *pcode - objout.textbegin, -4 + mem.disp); + objreloc(xcon2sym(mem.con), REL_PCREL32, Stext, *pcode - objout.textbegin, mem.disp + off); } else { /* var(,%reg,shift) */ B(/*mod 0*/ (reg & 7) << 3 | RSP); @@ -917,14 +920,18 @@ emitbranch(uchar **pcode, struct block *blk) struct instr *ins; assert(arg.t == RTMP); ins = &instrtab[arg.i]; - assert(oiscmp(ins->op) || ins->op == Oand || ins->op == Osub); /* TODO handle float cmps */ - if (ins->r.bits != ZEROREF.bits) { - /* for CMP instr */ - cc = icmpop2cc[ins->op]; + if ((oiscmp(ins->op) || ins->op == Oand || ins->op == Osub)) { + if (ins->r.bits != ZEROREF.bits) { + /* for CMP instr */ + cc = icmpop2cc[ins->op]; + } else { + /* for TEST instr, which modifies ZF and SF and sets CF = OF = 0 */ + cc = icmpzero2cc[ins->op]; + } } else { - /* for TEST instr, which modifies ZF and SF and sets CF = OF = 0 */ - cc = icmpzero2cc[ins->op]; + /* implicit by ZF */ + cc = CCNZ; } if (blk->s1 == blk->lnext) { /* if s1 is next adjacent block, swap s1,s2 and flip condition to emit a |