diff options
author | MITSUNARI Shigeo <[email protected]> | 2023-11-22 08:52:14 +0900 |
---|---|---|
committer | MITSUNARI Shigeo <[email protected]> | 2023-11-22 08:52:14 +0900 |
commit | 5e54ffdfaf8a38efcd0821c74bde63379c0e914a (patch) | |
tree | 2f2a9bc84502ed59d98a91af73c3cf66185297c1 | |
parent | 426814c50680085c7b8e694ff0bad9307d692ec6 (diff) | |
download | xbyak-5e54ffdfaf8a38efcd0821c74bde63379c0e914a.tar.gz xbyak-5e54ffdfaf8a38efcd0821c74bde63379c0e914a.zip |
add 3-op shift
-rw-r--r-- | gen/gen_code.cpp | 2 | ||||
-rw-r--r-- | xbyak/xbyak.h | 20 | ||||
-rw-r--r-- | xbyak/xbyak_mnemonic.h | 16 |
3 files changed, 29 insertions, 9 deletions
diff --git a/gen/gen_code.cpp b/gen/gen_code.cpp index a0ed29b..4f4eb68 100644 --- a/gen/gen_code.cpp +++ b/gen/gen_code.cpp @@ -914,6 +914,8 @@ void put() const Tbl *p = &tbl[i]; printf("void %s(const Operand& op, int imm) { opShift(op, imm, %d); }\n", p->name, p->ext); printf("void %s(const Operand& op, const Reg8& _cl) { opShift(op, _cl, %d); }\n", p->name, p->ext); + printf("void %s(const Reg& d, const Operand& op, int imm) { opShift(op, imm, %d, &d); }\n", p->name, p->ext); + printf("void %s(const Reg& d, const Operand& op, const Reg8& _cl) { opShift(op, _cl, %d, &d); }\n", p->name, p->ext); } } { diff --git a/xbyak/xbyak.h b/xbyak/xbyak.h index 35bb18e..d4c5b14 100644 --- a/xbyak/xbyak.h +++ b/xbyak/xbyak.h @@ -2198,12 +2198,12 @@ private: } return true; } - void opRext(const Operand& op, int bit, int ext, uint64_t type, int code, bool disableRex = false, int immSize = 0) + void opRext(const Operand& op, int bit, int ext, uint64_t type, int code, bool disableRex = false, int immSize = 0, const Reg *d = 0) { int opBit = op.getBit(); if (disableRex && opBit == 64) opBit = 32; const Reg r(ext, Operand::REG, opBit); - if ((type & T_VEX) && op.hasRex2NF() && opROO(Reg(0, Operand::REG, opBit), op, r, type, code)) return; + if ((type & T_VEX) && op.hasRex2NF() && opROO(d ? *d : Reg(0, Operand::REG, opBit), op, r, type, code)) return; if (op.isMEM()) { opMR(op.getAddress(), r, type, code, immSize); } else if (op.isREG(bit)) { @@ -2212,18 +2212,20 @@ private: XBYAK_THROW(ERR_BAD_COMBINATION) } } - void opShift(const Operand& op, int imm, int ext) + void opShift(const Operand& op, int imm, int ext, const Reg *d = 0) { - verifyMemHasSize(op); - uint64_t type = T_VEX|T_CODE1_IF1; if (ext & 8) type |= T_NF; - opRext(op, 0, ext&7, type, (0xC0 | ((imm == 1 ? 1 : 0) << 4)), false, (imm != 1) ? 1 : 0); + if (d == 0) verifyMemHasSize(op); + if (d && op.getBit() != 0 && d->getBit() != op.getBit()) XBYAK_THROW(ERR_BAD_SIZE_OF_REGISTER) + uint64_t type = T_VEX|T_CODE1_IF1; if (ext & 8) type |= T_NF; if (d) type |= T_ND1; + opRext(op, 0, ext&7, type, (0xC0 | ((imm == 1 ? 1 : 0) << 4)), false, (imm != 1) ? 1 : 0, d); if (imm != 1) db(imm); } - void opShift(const Operand& op, const Reg8& _cl, int ext) + void opShift(const Operand& op, const Reg8& _cl, int ext, const Reg *d = 0) { if (_cl.getIdx() != Operand::CL) XBYAK_THROW(ERR_BAD_COMBINATION) - uint64_t type = T_VEX|T_CODE1_IF1; if (ext & 8) type |= T_NF; - opRext(op, 0, ext&7, type, 0xD2); + if (d && op.getBit() != 0 && d->getBit() != op.getBit()) XBYAK_THROW(ERR_BAD_SIZE_OF_REGISTER) + uint64_t type = T_VEX|T_CODE1_IF1; if (ext & 8) type |= T_NF; if (d) type |= T_ND1; + opRext(op, 0, ext&7, type, 0xD2, false, 0, d); } // condR assumes that op.isREG() is true void opRO(const Reg& r, const Operand& op, uint64_t type, int code, bool condR = true, int immSize = 0) diff --git a/xbyak/xbyak_mnemonic.h b/xbyak/xbyak_mnemonic.h index 9b3d487..847688c 100644 --- a/xbyak/xbyak_mnemonic.h +++ b/xbyak/xbyak_mnemonic.h @@ -729,10 +729,14 @@ void pushf() { db(0x9C); } void pxor(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xEF); } void rcl(const Operand& op, const Reg8& _cl) { opShift(op, _cl, 2); } void rcl(const Operand& op, int imm) { opShift(op, imm, 2); } +void rcl(const Reg& d, const Operand& op, const Reg8& _cl) { opShift(op, _cl, 2, &d); } +void rcl(const Reg& d, const Operand& op, int imm) { opShift(op, imm, 2, &d); } void rcpps(const Xmm& xmm, const Operand& op) { opSSE(xmm, op, T_0F, 0x53, isXMM_XMMorMEM); } void rcpss(const Xmm& xmm, const Operand& op) { opSSE(xmm, op, T_0F | T_F3, 0x53, isXMM_XMMorMEM); } void rcr(const Operand& op, const Reg8& _cl) { opShift(op, _cl, 3); } void rcr(const Operand& op, int imm) { opShift(op, imm, 3); } +void rcr(const Reg& d, const Operand& op, const Reg8& _cl) { opShift(op, _cl, 3, &d); } +void rcr(const Reg& d, const Operand& op, int imm) { opShift(op, imm, 3, &d); } void rdmsr() { db(0x0F); db(0x32); } void rdpmc() { db(0x0F); db(0x33); } void rdrand(const Reg& r) { if (r.isBit(8)) XBYAK_THROW(ERR_BAD_SIZE_OF_REGISTER) opRR(Reg(6, Operand::REG, r.getBit()), r, T_0F, 0xC7); } @@ -748,8 +752,12 @@ void ret(int imm = 0) { if (imm) { db(0xC2); dw(imm); } else { db(0xC3); } } void retf(int imm = 0) { if (imm) { db(0xCA); dw(imm); } else { db(0xCB); } } void rol(const Operand& op, const Reg8& _cl) { opShift(op, _cl, 8); } void rol(const Operand& op, int imm) { opShift(op, imm, 8); } +void rol(const Reg& d, const Operand& op, const Reg8& _cl) { opShift(op, _cl, 8, &d); } +void rol(const Reg& d, const Operand& op, int imm) { opShift(op, imm, 8, &d); } void ror(const Operand& op, const Reg8& _cl) { opShift(op, _cl, 9); } void ror(const Operand& op, int imm) { opShift(op, imm, 9); } +void ror(const Reg& d, const Operand& op, const Reg8& _cl) { opShift(op, _cl, 9, &d); } +void ror(const Reg& d, const Operand& op, int imm) { opShift(op, imm, 9, &d); } void rorx(const Reg32e& r, const Operand& op, uint8_t imm) { opRRO(r, Reg32e(0, r.getBit()), op, T_0F3A|T_F2|T_VEX|T_MAP3, 0xF0, imm); } void roundpd(const Xmm& xmm, const Operand& op, uint8_t imm) { opSSE(xmm, op, T_66|T_0F3A|T_YMM, 0x09, isXMM_XMMorMEM, imm); } void roundps(const Xmm& xmm, const Operand& op, uint8_t imm) { opSSE(xmm, op, T_66|T_0F3A|T_YMM, 0x08, isXMM_XMMorMEM, imm); } @@ -760,8 +768,12 @@ void rsqrtss(const Xmm& xmm, const Operand& op) { opSSE(xmm, op, T_0F | T_F3, 0x void sahf() { db(0x9E); } void sal(const Operand& op, const Reg8& _cl) { opShift(op, _cl, 12); } void sal(const Operand& op, int imm) { opShift(op, imm, 12); } +void sal(const Reg& d, const Operand& op, const Reg8& _cl) { opShift(op, _cl, 12, &d); } +void sal(const Reg& d, const Operand& op, int imm) { opShift(op, imm, 12, &d); } void sar(const Operand& op, const Reg8& _cl) { opShift(op, _cl, 15); } void sar(const Operand& op, int imm) { opShift(op, imm, 15); } +void sar(const Reg& d, const Operand& op, const Reg8& _cl) { opShift(op, _cl, 15, &d); } +void sar(const Reg& d, const Operand& op, int imm) { opShift(op, imm, 15, &d); } void sarx(const Reg32e& r1, const Operand& op, const Reg32e& r2) { opRRO(r1, r2, op, T_VEX|T_F3|T_0F38, 0xf7); } void sbb(const Operand& op, uint32_t imm) { opOI(op, imm, 0x18, 3); } void sbb(const Operand& op1, const Operand& op2) { opRO_MR(op1, op2, 0x18); } @@ -811,6 +823,8 @@ void sha256msg2(const Xmm& xmm, const Operand& op) { opSSE(xmm, op, T_0F38, 0xCD void sha256rnds2(const Xmm& xmm, const Operand& op) { opSSE(xmm, op, T_0F38, 0xCB, isXMM_XMMorMEM, NONE); } void shl(const Operand& op, const Reg8& _cl) { opShift(op, _cl, 12); } void shl(const Operand& op, int imm) { opShift(op, imm, 12); } +void shl(const Reg& d, const Operand& op, const Reg8& _cl) { opShift(op, _cl, 12, &d); } +void shl(const Reg& d, const Operand& op, int imm) { opShift(op, imm, 12, &d); } void shld(const Operand& op, const Reg& reg, const Reg8& _cl) { opShxd(Reg(), op, reg, 0, 0xA4, 0x24, &_cl); } void shld(const Operand& op, const Reg& reg, uint8_t imm) { opShxd(Reg(), op, reg, imm, 0xA4, 0x24); } void shld(const Reg& d, const Operand& op, const Reg& reg, const Reg8& _cl) { opShxd(d, op, reg, 0, 0xA4, 0x24, &_cl); } @@ -818,6 +832,8 @@ void shld(const Reg& d, const Operand& op, const Reg& reg, uint8_t imm) { opShxd void shlx(const Reg32e& r1, const Operand& op, const Reg32e& r2) { opRRO(r1, r2, op, T_VEX|T_66|T_0F38, 0xf7); } void shr(const Operand& op, const Reg8& _cl) { opShift(op, _cl, 13); } void shr(const Operand& op, int imm) { opShift(op, imm, 13); } +void shr(const Reg& d, const Operand& op, const Reg8& _cl) { opShift(op, _cl, 13, &d); } +void shr(const Reg& d, const Operand& op, int imm) { opShift(op, imm, 13, &d); } void shrd(const Operand& op, const Reg& reg, const Reg8& _cl) { opShxd(Reg(), op, reg, 0, 0xAC, 0x2C, &_cl); } void shrd(const Operand& op, const Reg& reg, uint8_t imm) { opShxd(Reg(), op, reg, imm, 0xAC, 0x2C); } void shrd(const Reg& d, const Operand& op, const Reg& reg, const Reg8& _cl) { opShxd(d, op, reg, 0, 0xAC, 0x2C, &_cl); } |