diff options
Diffstat (limited to 'amd64')
| -rw-r--r-- | amd64/emit.c | 1 | ||||
| -rw-r--r-- | amd64/isel.c | 9 |
2 files changed, 7 insertions, 3 deletions
diff --git a/amd64/emit.c b/amd64/emit.c index f4c95bd..95055da 100644 --- a/amd64/emit.c +++ b/amd64/emit.c @@ -599,6 +599,7 @@ DEFINSTR2(Xxor, {4|8, PGPR, PI32, "\x81", EN_RI32, .ext=6}, /* XOR r32/64, imm */ { 8, PGPR, PMEM, "\x33", EN_RM}, /* XOR r64, m64 */ {4|8, PFPR, PFPR, "\x0F\x57", EN_RR}, /* XORPS xmm, xmm */ + {4|8, PFPR, PMEM, "\x0F\x57", EN_RM}, /* XORPS xmm, m128 */ ) DEFINSTR2(Xshl, {4|8, PGPR, P1, "\xD1", EN_R, .ext=4}, /* SHL r32/64, 1 */ diff --git a/amd64/isel.c b/amd64/isel.c index 64cda27..be2f769 100644 --- a/amd64/isel.c +++ b/amd64/isel.c @@ -494,9 +494,12 @@ sel(struct function *fn, struct instr *ins, struct block *blk, int *curi) goto ALU; case Oneg: if (kisflt(ins->cls)) { - ins->op = Osub; - ins->r = ins->l; - ins->l = ZEROREF; + /* flip sign bit with XORPS/D */ + static const uvlong sd[2] = {0x8000000000000000,0x8000000000000000}; + static const uint sf[4] = {0x80000000,80000000,0x80000000,80000000}; + ins->op = Oxor; + ins->r = mkdatref(NULL, mktype(ins->cls == KF32 ? TYFLOAT : TYDOUBLE), /*siz*/16, + /*align*/16, ins->cls == KF32 ? (void *)sf : sd, /*siz*/16, /*deref*/1); } /* fallthru */ case Onot: |