From a7b02ac80dcaf7f0812d3173cb30ef4f6dc1485c Mon Sep 17 00:00:00 2001 From: MITSUNARI Shigeo Date: Wed, 3 Jan 2024 17:10:32 +0900 Subject: [PATCH] RAO_INT supports APX --- gen/gen_code.cpp | 8 ++++---- test/apx.cpp | 26 ++++++++++++++++++++++++++ xbyak/xbyak.h | 19 +++++++++++++------ xbyak/xbyak_mnemonic.h | 8 ++++---- 4 files changed, 47 insertions(+), 14 deletions(-) diff --git a/gen/gen_code.cpp b/gen/gen_code.cpp index a174e6a..5194198 100644 --- a/gen/gen_code.cpp +++ b/gen/gen_code.cpp @@ -860,14 +860,14 @@ void put() const char *prefix; } tbl[] = { { "aadd", "" }, - { "aand", " | T_66" }, - { "aor", " | T_F2" }, - { "axor", " | T_F3" }, + { "aand", "|T_66" }, + { "aor", "|T_F2" }, + { "axor", "|T_F3" }, }; for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) { const Tbl *p = &tbl[i]; printf("void %s(const Address& addr, const Reg32e ®) { ", p->name); - printf("opMR(addr, reg, T_0F38%s, 0x0FC); }\n", p->prefix); + printf("opMR(addr, reg, T_0F38%s, 0x0FC, T_APX%s); }\n", p->prefix, p->prefix); } } diff --git a/test/apx.cpp b/test/apx.cpp index 70b7d02..45fe5ee 100644 --- a/test/apx.cpp +++ b/test/apx.cpp @@ -1936,3 +1936,29 @@ CYBOZU_TEST_AUTO(0x0f_rex2) CYBOZU_TEST_EQUAL_ARRAY(c.getCode(), tbl, n); } +CYBOZU_TEST_AUTO(rao_int) +{ + struct Code : Xbyak::CodeGenerator { + Code() + { + aadd(ptr [r16+r31*1], r17d); + aadd(ptr [r16+r31*1], r17); + aand(ptr [r16+r31*1], r17d); + aand(ptr [r16+r31*1], r17); + aor(ptr [r16+r31*1], r17d); + aor(ptr [r16+r31*1], r17); + axor(ptr [r16+r31*1], r17d); + axor(ptr [r16+r31*1], r17); + } + } c; + const uint8_t tbl[] = { + 0x62, 0xac, 0x78, 0x08, 0xfc, 0x0c, 0x38, 0x62, 0xac, 0xf8, 0x08, 0xfc, 0x0c, 0x38, 0x62, 0xac, + 0x79, 0x08, 0xfc, 0x0c, 0x38, 0x62, 0xac, 0xf9, 0x08, 0xfc, 0x0c, 0x38, 0x62, 0xac, 0x7b, 0x08, + 0xfc, 0x0c, 0x38, 0x62, 0xac, 0xfb, 0x08, 0xfc, 0x0c, 0x38, 0x62, 0xac, 0x7a, 0x08, 0xfc, 0x0c, + 0x38, 0x62, 0xac, 0xfa, 0x08, 0xfc, 0x0c, 0x38, + }; + const size_t n = sizeof(tbl); + CYBOZU_TEST_EQUAL(c.getSize(), n); + CYBOZU_TEST_EQUAL_ARRAY(c.getCode(), tbl, n); +} + diff --git a/xbyak/xbyak.h b/xbyak/xbyak.h index c6e169a..9689d7d 100644 --- a/xbyak/xbyak.h +++ b/xbyak/xbyak.h @@ -727,6 +727,7 @@ public: bool operator==(const Operand& rhs) const; bool operator!=(const Operand& rhs) const { return !operator==(rhs); } const Address& getAddress() const; + Address getAddress(int immSize) const; const Reg& getReg() const; }; @@ -1345,6 +1346,12 @@ inline const Address& Operand::getAddress() const assert(isMEM()); return static_cast(*this); } +inline Address Operand::getAddress(int immSize) const +{ + Address addr = getAddress(); + addr.immSize = immSize; + return addr; +} inline bool Operand::operator==(const Operand& rhs) const { @@ -2049,13 +2056,13 @@ private: writeCode(type, reg1, code, rex2); setModRM(3, reg1.getIdx(), reg2.getIdx()); } - void opMR(Address addr, const Reg& r, uint64_t type, int code, int immSize = 0, uint64_t type2 = 0, uint8_t code2 = 0) + void opMR(const Address& addr, const Reg& r, uint64_t type, int code, uint64_t type2 = 0, int code2 = NONE) { - if (type2 && opROO(Reg(), r, addr, type2, code2)) return; + if (code2 == NONE) code2 = code; + if (type2 && opROO(Reg(), addr, r, type2, code2)) return; if (addr.is64bitDisp()) XBYAK_THROW(ERR_CANT_USE_64BIT_DISP) bool rex2 = rex(addr, r, type); writeCode(type, r, code, rex2); - addr.immSize = immSize; opAddr(addr, r.getIdx()); } void opLoadSeg(const Address& addr, const Reg& reg, uint64_t type, int code) @@ -2227,7 +2234,7 @@ private: const Reg r(ext, Operand::REG, opBit); if ((type & T_APX) && op.hasRex2NFZU() && opROO(d ? *d : Reg(0, Operand::REG, opBit), op, r, type, code)) return; if (op.isMEM()) { - opMR(op.getAddress(), r, type, code, immSize); + opMR(op.getAddress(immSize), r, type, code); } else if (op.isREG(bit)) { opRR(r, op.getReg().changeBit(opBit), type, code); } else { @@ -2253,7 +2260,7 @@ private: void opRO(const Reg& r, const Operand& op, uint64_t type, int code, bool condR = true, int immSize = 0) { if (op.isMEM()) { - opMR(op.getAddress(), r, type, code, immSize); + opMR(op.getAddress(immSize), r, type, code); } else if (condR) { opRR(r, op.getReg(), type, code); } else { @@ -2955,7 +2962,7 @@ public: if (!inner::IsInInt32(imm)) XBYAK_THROW(ERR_IMM_IS_TOO_BIG) immSize = 4; } - opMR(op.getAddress(), Reg(0, Operand::REG, op.getBit()), 0, 0xC6, immSize); + opMR(op.getAddress(immSize), Reg(0, Operand::REG, op.getBit()), 0, 0xC6); db(static_cast(imm), immSize); } else { XBYAK_THROW(ERR_BAD_COMBINATION) diff --git a/xbyak/xbyak_mnemonic.h b/xbyak/xbyak_mnemonic.h index 7771417..966d7d5 100644 --- a/xbyak/xbyak_mnemonic.h +++ b/xbyak/xbyak_mnemonic.h @@ -1,6 +1,6 @@ const char *getVersionString() const { return "7.04"; } -void aadd(const Address& addr, const Reg32e ®) { opMR(addr, reg, T_0F38, 0x0FC); } -void aand(const Address& addr, const Reg32e ®) { opMR(addr, reg, T_0F38 | T_66, 0x0FC); } +void aadd(const Address& addr, const Reg32e ®) { opMR(addr, reg, T_0F38, 0x0FC, T_APX); } +void aand(const Address& addr, const Reg32e ®) { opMR(addr, reg, T_0F38|T_66, 0x0FC, T_APX|T_66); } void adc(const Operand& op, uint32_t imm) { opOI(op, imm, 0x10, 2); } void adc(const Operand& op1, const Operand& op2) { opRO_MR(op1, op2, 0x10); } void adc(const Reg& d, const Operand& op, uint32_t imm) { opROI(d, op, imm, T_NONE, 2); } @@ -34,8 +34,8 @@ void andnpd(const Xmm& xmm, const Operand& op) { opSSE(xmm, op, T_0F | T_66, 0x5 void andnps(const Xmm& xmm, const Operand& op) { opSSE(xmm, op, T_0F, 0x55, isXMM_XMMorMEM); } void andpd(const Xmm& xmm, const Operand& op) { opSSE(xmm, op, T_0F | T_66, 0x54, isXMM_XMMorMEM); } void andps(const Xmm& xmm, const Operand& op) { opSSE(xmm, op, T_0F, 0x54, isXMM_XMMorMEM); } -void aor(const Address& addr, const Reg32e ®) { opMR(addr, reg, T_0F38 | T_F2, 0x0FC); } -void axor(const Address& addr, const Reg32e ®) { opMR(addr, reg, T_0F38 | T_F3, 0x0FC); } +void aor(const Address& addr, const Reg32e ®) { opMR(addr, reg, T_0F38|T_F2, 0x0FC, T_APX|T_F2); } +void axor(const Address& addr, const Reg32e ®) { opMR(addr, reg, T_0F38|T_F3, 0x0FC, T_APX|T_F3); } void bextr(const Reg32e& r1, const Operand& op, const Reg32e& r2) { opRRO(r1, r2, op, T_APX|T_0F38|T_NF, 0xf7); } void blendpd(const Xmm& xmm, const Operand& op, int imm) { opSSE(xmm, op, T_66 | T_0F3A, 0x0D, isXMM_XMMorMEM, static_cast(imm)); } void blendps(const Xmm& xmm, const Operand& op, int imm) { opSSE(xmm, op, T_66 | T_0F3A, 0x0C, isXMM_XMMorMEM, static_cast(imm)); }