From a5bb980335f5234f4901ae062e183e5bb72f845f Mon Sep 17 00:00:00 2001 From: lemon Date: Mon, 12 Jun 2023 22:14:45 +0200 Subject: xor reg,reg --- amd64/emit.c | 16 +++++++++++++--- amd64/isel.c | 13 ++++++++++++- test/test3.c | 5 ++++- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/amd64/emit.c b/amd64/emit.c index c1f01a3..f872b49 100644 --- a/amd64/emit.c +++ b/amd64/emit.c @@ -238,10 +238,10 @@ DEFINSTR2(Xmov, {4|8, PGPR, PMEM, "\x8B", EN_RM}, /* MOV r32/64, m32/64 */ {4|8, PGPR, PI32, "\xB8", EN_OI}, /* MOV r32/64, imm */ {4, PFPR, PFPR, "\xF3\x0F\x10", EN_RR}, /* MOVSS xmm, xmm */ - {4, PFPR, PMEM, "\xF3\x0F\x10", EN_RM}, /* MOVSS xmm, m32 */ - {4, PMEM, PFPR, "\xF3\x0F\x10", EN_MR}, /* MOVSS m32, xmm */ {8, PFPR, PFPR, "\xF2\x0F\x10", EN_RR}, /* MOVSD xmm, xmm */ + {4, PFPR, PMEM, "\xF3\x0F\x10", EN_RM}, /* MOVSS xmm, m32 */ {8, PFPR, PMEM, "\xF2\x0F\x10", EN_RM}, /* MOVSD xmm, m64 */ + {4, PMEM, PFPR, "\xF3\x0F\x10", EN_MR}, /* MOVSS m32, xmm */ {8, PMEM, PFPR, "\xF2\x0F\x11", EN_MR}, /* MOVSS m64, xmm */ ) DEFINSTR2(Xmovsx4, @@ -291,6 +291,14 @@ DEFINSTR2(Xsub, {4, PFPR, PMEM, "\xF3\x0F\x5C", EN_RM}, /* SUBSS xmm, m32 */ {8, PFPR, PMEM, "\xF2\x0F\x5C", EN_RM}, /* SUBSD xmm, m64 */ ) +DEFINSTR2(Xxor, + {4|8, PGPR, PGPR, "\x33", EN_RR}, /* XOR r32/64, r32/64 */ + {4|8, PGPR, PI8, "\x83", EN_RI8, .ext=6}, /* XOR r32/64, imm8 */ + {4|8, PRAX, PI32, "\x35", EN_I32}, /* XOR eax/rax, imm */ + {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 */ +) DEFINSTR2(Xshl, {4|8, PGPR, P1, "\xD1", EN_R, .ext=4}, /* SHL r32/64, 1 */ {4|8, PGPR, PI32, "\xC1", EN_RI8, .ext=4}, /* SHL r32/64, imm */ @@ -431,10 +439,12 @@ gencopy(uchar **pcode, enum irclass cls, struct oper dst, union ref val) /* normal (not 2-address) case */ Lea: Xlea(pcode, cls2siz[cls], dst, ref2oper(val)); + } else if (val.t == RICON && val.i == 0 && dst.t == OREG) { + Xxor(pcode, cls2siz[cls], dst, dst); } else if (val.t == RXCON && conht[val.i].isdat && !conht[val.i].deref) { Xlea(pcode, cls2siz[cls], dst, mkoper(OCONR, .con = val.i)); } else { - struct oper src = mkimmregoper(val); + struct oper src = mkimmdatregoper(val); if (memcmp(&dst, &src, sizeof dst) != 0) Xmov(pcode, cls2siz[cls], dst, src); } diff --git a/amd64/isel.c b/amd64/isel.c index 30ad222..858dfbc 100644 --- a/amd64/isel.c +++ b/amd64/isel.c @@ -17,7 +17,12 @@ fixarg(struct function *fn, union ref *r, struct instr *ins, struct block *blk, /* add X, INT32MAX+1 -> sub X, INT32MIN */ ins->op = Oadd + (op == Oadd); *r = mkintcon(fn, KI4, -2147483648); - } else if (con->cls && (kisflt(con->cls) || con->cls == KI8)) { + } else if (in_range(op, Ocopy, Omove) && kisflt(con->cls) + && (con->cls == KF4 ? con->fs == 0.0f : con->fd == 0.0)) + { + /* copy of float zero -> regular zero, that emit() will turn into xor x,x */ + *r = mkref(RICON, 0); + } else if (kisflt(con->cls) || con->cls == KI8) { /* float immediates & >32b immediates are loaded from memory */ uchar data[8]; uint siz = cls2siz[con->cls]; @@ -140,6 +145,11 @@ sel(struct function *fn, struct instr *ins, struct block *blk, int *curi) enum op op = ins->op; switch (op) { + default: assert(0); + case Onop: break; + case Oalloca1: case Oalloca2: case Oalloca4: case Oalloca8: case Oalloca16: + case Ocall: case Ointrin: + break; case Oshl: case Osar: case Oslr: if (!iscon(ins->r)) { /* shift amount register is always CL */ @@ -222,6 +232,7 @@ sel(struct function *fn, struct instr *ins, struct block *blk, int *curi) if (ins->l.t != RTMP && ins->l.t != RREG) ins->l = insertinstr(blk, (*curi)++, mkinstr(Ocopy, ins->cls, ins->l)); if (ins->r.t) + case Omove: fixarg(fn, &ins->r, ins, blk, curi); break; case Oloads1: case Oloadu1: case Oloads2: case Oloadu2: diff --git a/test/test3.c b/test/test3.c index 8bd9020..74f4c00 100644 --- a/test/test3.c +++ b/test/test3.c @@ -12,10 +12,13 @@ int shcl(int a, int b) { return a << (b+1); } +int zero() { return 0; } +float fzero() { return 0.0f; } + struct p { long x,y; }; struct p divsh(int a) { struct p p; - p.x = a << (a / 5); + p.x = a << (a % 5); p.y = a; return p; } -- cgit v1.2.3