diff --git a/gen/gen_code.cpp b/gen/gen_code.cpp index 17d44fc..581a186 100644 --- a/gen/gen_code.cpp +++ b/gen/gen_code.cpp @@ -240,7 +240,7 @@ void putX_X_XM(bool omitOnly) void putMemOp(const char *name, const char *type, uint8_t ext, uint8_t code, int bit, int fwait = false) { - printf("void %s(const Address& addr) { %sopModM(addr, Reg%d(%d), %s, 0x%02X); }\n", name, fwait ? "db(0x9B); " : "", bit, ext, type, code); + printf("void %s(const Address& addr) { %sopMR(addr, Reg%d(%d), %s, 0x%02X); }\n", name, fwait ? "db(0x9B); " : "", bit, ext, type, code); } void putLoadSeg(const char *name, int type, uint8_t code) @@ -413,7 +413,7 @@ void put() for (size_t i = 0; i < NUM_OF_ARRAY(mmxTbl6); i++) { const MmxTbl6 *p = &mmxTbl6[i]; printf("void %s(const Xmm& xmm, const Operand& op) { opMMX(xmm, op, 0x%02X, T_0F, %s); }\n", p->name, p->code, p->pref); - printf("void %s(const Address& addr, const Xmm& xmm) { opModM(addr, xmm, T_0F|%s, 0x%02X); }\n", p->name, p->pref, p->code2); + printf("void %s(const Address& addr, const Xmm& xmm) { opMR(addr, xmm, T_0F|%s, 0x%02X); }\n", p->name, p->pref, p->code2); } } { @@ -484,7 +484,7 @@ void put() for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) { const Tbl *p = &tbl[i]; std::string type = type2String(p->type); - printf("void %s(const Xmm& reg1, const Xmm& reg2) { opModR(reg1, reg2, %s, 0x%02X); }\n", p->name, type.c_str(), p->code); + printf("void %s(const Xmm& reg1, const Xmm& reg2) { opRR(reg1, reg2, %s, 0x%02X); }\n", p->name, type.c_str(), p->code); } } { @@ -563,7 +563,7 @@ void put() }; for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) { const Tbl *p = &tbl[i]; - printf("void prefetch%s(const Address& addr) { opModM(addr, Reg32(%d), T_0F, 0x%02X); }\n", p->name, p->ext, p->code); + printf("void prefetch%s(const Address& addr) { opMR(addr, Reg32(%d), T_0F, 0x%02X); }\n", p->name, p->ext, p->code); } } { @@ -622,12 +622,12 @@ void put() const char *msg = "//-V524"; // disable warning of PVS-Studio for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) { const Tbl *p = &tbl[i]; - printf("void cmov%s(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | %d); }%s\n", p->name, p->ext, msg); + printf("void cmov%s(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | %d); }%s\n", p->name, p->ext, msg); printf("void j%s(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x%02X, 0x%02X, 0x%02X); }%s\n", p->name, p->ext | 0x70, p->ext | 0x80, 0x0F, msg); printf("void j%s(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x%02X, 0x%02X, 0x%02X); }%s\n", p->name, p->ext | 0x70, p->ext | 0x80, 0x0F, msg); printf("void j%s(const char *label, LabelType type = T_AUTO) { j%s(std::string(label), type); }%s\n", p->name, p->name, msg); printf("void j%s(const void *addr) { opJmpAbs(addr, T_NEAR, 0x%02X, 0x%02X, 0x%02X); }%s\n", p->name, p->ext | 0x70, p->ext | 0x80, 0x0F, msg); - printf("void set%s(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | %d); }%s\n", p->name, p->ext, msg); + printf("void set%s(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | %d); }%s\n", p->name, p->ext, msg); } } { @@ -805,8 +805,8 @@ void put() }; for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) { const Tbl *p = &tbl[i]; - printf("void %s(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x%02X); }\n", p->name, p->code); - printf("void %s(const Operand& op, uint32_t imm) { opRM_I(op, imm, 0x%02X, %d); }\n", p->name, p->code, p->ext); + printf("void %s(const Operand& op1, const Operand& op2) { opRO_MR(op1, op2, 0x%02X); }\n", p->name, p->code); + printf("void %s(const Operand& op, uint32_t imm) { opOI(op, imm, 0x%02X, %d); }\n", p->name, p->code, p->ext); if (!p->support3op) continue; printf("void %s(const Reg& d, const Operand& op1, const Operand& op2) { opROO(d, op1, op2, 0, 0x%02X); }\n", p->name, p->code); printf("void %s(const Reg& d, const Operand& op, uint32_t imm) { opROI(d, op, imm, 0, %d); }\n", p->name, p->ext); @@ -825,7 +825,7 @@ void put() 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("opModM(addr, reg, T_0F38%s, 0x0FC); }\n", p->prefix); + printf("opMR(addr, reg, T_0F38%s, 0x0FC); }\n", p->prefix); } } @@ -856,8 +856,8 @@ void put() }; for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) { const Tbl *p = &tbl[i]; - printf("void %s(const Operand& op, const Reg& reg) { opModRM(reg, op, op.isREG(16|32|64) && op.getBit() == reg.getBit(), op.isMEM(), T_0F, 0x%02X); }\n", p->name, p->code); - printf("void %s(const Operand& op, uint8_t imm) { opR_ModM(op, 16|32|64, %d, T_0F, 0xba, false, 1); db(imm); }\n", p->name, p->ext); + printf("void %s(const Operand& op, const Reg& reg) { opRO(reg, op, op.isREG(16|32|64) && op.getBit() == reg.getBit(), op.isMEM(), T_0F, 0x%02X); }\n", p->name, p->code); + printf("void %s(const Operand& op, uint8_t imm) { opRext(op, 16|32|64, %d, T_0F, 0xba, false, 1); db(imm); }\n", p->name, p->ext); } } { @@ -876,7 +876,7 @@ void put() for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) { const Tbl *p = &tbl[i]; const std::string name = p->name; - printf("void %s(const Operand& op) { opR_ModM(op, 0, %d, 0, 0x%02X); }\n", p->name, p->ext, p->code); + printf("void %s(const Operand& op) { opRext(op, 0, %d, 0, 0x%02X); }\n", p->name, p->ext, p->code); } } { @@ -924,7 +924,7 @@ void put() }; for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) { const Tbl *p = &tbl[i]; - printf("void %s(const Reg®, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x%02X); }\n", p->name, p->code); + printf("void %s(const Reg®, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x%02X); }\n", p->name, p->code); } } { @@ -1030,7 +1030,7 @@ void put() for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) { const Tbl *p = &tbl[i]; // cast xmm register to 16bit register to put 0x66 - printf("void %s(const Address& addr, const Xmm& reg) { opModM(addr, Reg16(reg.getIdx()), T_0F, 0x%02X); }\n", p->name, p->code); + printf("void %s(const Address& addr, const Xmm& reg) { opMR(addr, Reg16(reg.getIdx()), T_0F, 0x%02X); }\n", p->name, p->code); } } { @@ -1068,29 +1068,29 @@ void put() } // mpx { - puts("void bndcl(const BoundsReg& bnd, const Operand& op) { opR_ModM(op, i32e, bnd.getIdx(), T_F3 | T_0F, 0x1A, !op.isMEM()); }"); - puts("void bndcu(const BoundsReg& bnd, const Operand& op) { opR_ModM(op, i32e, bnd.getIdx(), T_F2 | T_0F, 0x1A, !op.isMEM()); }"); - puts("void bndcn(const BoundsReg& bnd, const Operand& op) { opR_ModM(op, i32e, bnd.getIdx(), T_F2 | T_0F, 0x1B, !op.isMEM()); }"); + puts("void bndcl(const BoundsReg& bnd, const Operand& op) { opRext(op, i32e, bnd.getIdx(), T_F3 | T_0F, 0x1A, !op.isMEM()); }"); + puts("void bndcu(const BoundsReg& bnd, const Operand& op) { opRext(op, i32e, bnd.getIdx(), T_F2 | T_0F, 0x1A, !op.isMEM()); }"); + puts("void bndcn(const BoundsReg& bnd, const Operand& op) { opRext(op, i32e, bnd.getIdx(), T_F2 | T_0F, 0x1B, !op.isMEM()); }"); puts("void bndldx(const BoundsReg& bnd, const Address& addr) { opMIB(addr, bnd, T_0F, 0x1A); }"); - puts("void bndmk(const BoundsReg& bnd, const Address& addr) { opModM(addr, bnd, T_F3 | T_0F, 0x1B); }"); - puts("void bndmov(const BoundsReg& bnd, const Operand& op) { opModRM(bnd, op, op.isBNDREG(), op.isMEM(), T_66 | T_0F, 0x1A); }"); - puts("void bndmov(const Address& addr, const BoundsReg& bnd) { opModM(addr, bnd, T_66 | T_0F, 0x1B); }"); + puts("void bndmk(const BoundsReg& bnd, const Address& addr) { opMR(addr, bnd, T_F3 | T_0F, 0x1B); }"); + puts("void bndmov(const BoundsReg& bnd, const Operand& op) { opRO(bnd, op, op.isBNDREG(), op.isMEM(), T_66 | T_0F, 0x1A); }"); + puts("void bndmov(const Address& addr, const BoundsReg& bnd) { opMR(addr, bnd, T_66 | T_0F, 0x1B); }"); puts("void bndstx(const Address& addr, const BoundsReg& bnd) { opMIB(addr, bnd, T_0F, 0x1B); }"); } // misc { - puts("void lea(const Reg& reg, const Address& addr) { if (!reg.isBit(16 | i32e)) XBYAK_THROW(ERR_BAD_SIZE_OF_REGISTER) opModM(addr, reg, 0, 0x8D); }"); - puts("void bswap(const Reg32e& reg) { opModR(Reg32(1), reg, 0, 0x0F); }"); + puts("void lea(const Reg& reg, const Address& addr) { if (!reg.isBit(16 | i32e)) XBYAK_THROW(ERR_BAD_SIZE_OF_REGISTER) opMR(addr, reg, 0, 0x8D); }"); + puts("void bswap(const Reg32e& reg) { opRR(Reg32(1), reg, 0, 0x0F); }"); puts("void ret(int imm = 0) { if (imm) { db(0xC2); dw(imm); } else { db(0xC3); } }"); puts("void retf(int imm = 0) { if (imm) { db(0xCA); dw(imm); } else { db(0xCB); } }"); - puts("void xadd(const Operand& op, const Reg& reg) { opModRM(reg, op, (op.isREG() && reg.isREG() && op.getBit() == reg.getBit()), op.isMEM(), T_0F, 0xC0 | (reg.isBit(8) ? 0 : 1)); }"); - puts("void cmpxchg(const Operand& op, const Reg& reg) { opModRM(reg, op, (op.isREG() && reg.isREG() && op.getBit() == reg.getBit()), op.isMEM(), T_0F, 0xB0 | (reg.isBit(8) ? 0 : 1)); }"); - puts("void movbe(const Reg& reg, const Address& addr) { opModM(addr, reg, T_0F38, 0xF0); }"); - puts("void movbe(const Address& addr, const Reg& reg) { opModM(addr, reg, T_0F38, 0xF1); }"); - puts("void movdiri(const Address& addr, const Reg32e& reg) { opModM(addr, reg, T_0F38, 0xF9); }"); - puts("void movdir64b(const Reg& reg, const Address& addr) { opModM(addr, reg.cvt32(), T_66 | T_0F38, 0xF8); }"); - puts("void cmpxchg8b(const Address& addr) { opModM(addr, Reg32(1), T_0F, 0xC7); }"); + puts("void xadd(const Operand& op, const Reg& reg) { opRO(reg, op, (op.isREG() && reg.isREG() && op.getBit() == reg.getBit()), op.isMEM(), T_0F, 0xC0 | (reg.isBit(8) ? 0 : 1)); }"); + puts("void cmpxchg(const Operand& op, const Reg& reg) { opRO(reg, op, (op.isREG() && reg.isREG() && op.getBit() == reg.getBit()), op.isMEM(), T_0F, 0xB0 | (reg.isBit(8) ? 0 : 1)); }"); + puts("void movbe(const Reg& reg, const Address& addr) { opMR(addr, reg, T_0F38, 0xF0); }"); + puts("void movbe(const Address& addr, const Reg& reg) { opMR(addr, reg, T_0F38, 0xF1); }"); + puts("void movdiri(const Address& addr, const Reg32e& reg) { opMR(addr, reg, T_0F38, 0xF9); }"); + puts("void movdir64b(const Reg& reg, const Address& addr) { opMR(addr, reg.cvt32(), T_66 | T_0F38, 0xF8); }"); + puts("void cmpxchg8b(const Address& addr) { opMR(addr, Reg32(1), T_0F, 0xC7); }"); puts("void pextrw(const Operand& op, const Mmx& xmm, uint8_t imm) { opExt(op, xmm, 0x15, imm, true); }"); puts("void pextrb(const Operand& op, const Xmm& xmm, uint8_t imm) { opExt(op, xmm, 0x14, imm); }"); @@ -1101,32 +1101,32 @@ void put() puts("void pinsrb(const Xmm& xmm, const Operand& op, uint8_t imm) { opGen(xmm, op, T_66 | T_0F3A, 0x20, isXMM_REG32orMEM, imm); }"); puts("void pinsrd(const Xmm& xmm, const Operand& op, uint8_t imm) { opGen(xmm, op, T_66 | T_0F3A, 0x22, isXMM_REG32orMEM, imm); }"); - puts("void pmovmskb(const Reg32e& reg, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opModR(reg, mmx, T_0F, 0xD7); }"); - puts("void maskmovq(const Mmx& reg1, const Mmx& reg2) { if (!reg1.isMMX() || !reg2.isMMX()) XBYAK_THROW(ERR_BAD_COMBINATION) opModR(reg1, reg2, T_0F, 0xF7); }"); - puts("void movmskps(const Reg32e& reg, const Xmm& xmm) { opModR(reg, xmm, T_0F, 0x50); }"); + puts("void pmovmskb(const Reg32e& reg, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opRR(reg, mmx, T_0F, 0xD7); }"); + puts("void maskmovq(const Mmx& reg1, const Mmx& reg2) { if (!reg1.isMMX() || !reg2.isMMX()) XBYAK_THROW(ERR_BAD_COMBINATION) opRR(reg1, reg2, T_0F, 0xF7); }"); + puts("void movmskps(const Reg32e& reg, const Xmm& xmm) { opRR(reg, xmm, T_0F, 0x50); }"); puts("void movmskpd(const Reg32e& reg, const Xmm& xmm) { db(0x66); movmskps(reg, xmm); }"); - puts("void movntps(const Address& addr, const Xmm& xmm) { opModM(addr, Mmx(xmm.getIdx()), T_0F, 0x2B); }"); - puts("void movntdqa(const Xmm& xmm, const Address& addr) { opModM(addr, xmm, T_66 | T_0F38, 0x2A); }"); - puts("void lddqu(const Xmm& xmm, const Address& addr) { opModM(addr, xmm, T_F2 | T_0F, 0xF0); }"); - puts("void movnti(const Address& addr, const Reg32e& reg) { opModM(addr, reg, T_0F, 0xC3); }"); - puts("void movntq(const Address& addr, const Mmx& mmx) { if (!mmx.isMMX()) XBYAK_THROW(ERR_BAD_COMBINATION) opModM(addr, mmx, T_0F, 0xE7); }"); + puts("void movntps(const Address& addr, const Xmm& xmm) { opMR(addr, Mmx(xmm.getIdx()), T_0F, 0x2B); }"); + puts("void movntdqa(const Xmm& xmm, const Address& addr) { opMR(addr, xmm, T_66 | T_0F38, 0x2A); }"); + puts("void lddqu(const Xmm& xmm, const Address& addr) { opMR(addr, xmm, T_F2 | T_0F, 0xF0); }"); + puts("void movnti(const Address& addr, const Reg32e& reg) { opMR(addr, reg, T_0F, 0xC3); }"); + puts("void movntq(const Address& addr, const Mmx& mmx) { if (!mmx.isMMX()) XBYAK_THROW(ERR_BAD_COMBINATION) opMR(addr, mmx, T_0F, 0xE7); }"); - puts("void movd(const Address& addr, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opModM(addr, mmx, T_0F, 0x7E); }"); - puts("void movd(const Reg32& reg, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opModR(mmx, reg, T_0F, 0x7E); }"); - puts("void movd(const Mmx& mmx, const Address& addr) { if (mmx.isXMM()) db(0x66); opModM(addr, mmx, T_0F, 0x6E); }"); - puts("void movd(const Mmx& mmx, const Reg32& reg) { if (mmx.isXMM()) db(0x66); opModR(mmx, reg, T_0F, 0x6E); }"); - puts("void movq2dq(const Xmm& xmm, const Mmx& mmx) { opModR(xmm, mmx, T_F3 | T_0F, 0xD6); }"); - puts("void movdq2q(const Mmx& mmx, const Xmm& xmm) { opModR(mmx, xmm, T_F2 | T_0F, 0xD6); }"); - puts("void movq(const Mmx& mmx, const Operand& op) { if (mmx.isXMM()) db(0xF3); opModRM(mmx, op, (mmx.getKind() == op.getKind()), op.isMEM(), T_0F, mmx.isXMM() ? 0x7E : 0x6F); }"); - puts("void movq(const Address& addr, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opModM(addr, mmx, T_0F, mmx.isXMM() ? 0xD6 : 0x7F); }"); - puts("void rdrand(const Reg& r) { if (r.isBit(8)) XBYAK_THROW(ERR_BAD_SIZE_OF_REGISTER) opModR(Reg(6, Operand::REG, r.getBit()), r, T_0F, 0xC7); }"); - puts("void rdseed(const Reg& r) { if (r.isBit(8)) XBYAK_THROW(ERR_BAD_SIZE_OF_REGISTER) opModR(Reg(7, Operand::REG, r.getBit()), r, T_0F, 0xC7); }"); - puts("void crc32(const Reg32e& reg, const Operand& op) { if (reg.isBit(32) && op.isBit(16)) db(0x66); opModRM(reg, op, op.isREG(), op.isMEM(), T_F2 | T_0F38, 0xF0 | (op.isBit(8) ? 0 : 1)); }"); + puts("void movd(const Address& addr, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opMR(addr, mmx, T_0F, 0x7E); }"); + puts("void movd(const Reg32& reg, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opRR(mmx, reg, T_0F, 0x7E); }"); + puts("void movd(const Mmx& mmx, const Address& addr) { if (mmx.isXMM()) db(0x66); opMR(addr, mmx, T_0F, 0x6E); }"); + puts("void movd(const Mmx& mmx, const Reg32& reg) { if (mmx.isXMM()) db(0x66); opRR(mmx, reg, T_0F, 0x6E); }"); + puts("void movq2dq(const Xmm& xmm, const Mmx& mmx) { opRR(xmm, mmx, T_F3 | T_0F, 0xD6); }"); + puts("void movdq2q(const Mmx& mmx, const Xmm& xmm) { opRR(mmx, xmm, T_F2 | T_0F, 0xD6); }"); + puts("void movq(const Mmx& mmx, const Operand& op) { if (mmx.isXMM()) db(0xF3); opRO(mmx, op, (mmx.getKind() == op.getKind()), op.isMEM(), T_0F, mmx.isXMM() ? 0x7E : 0x6F); }"); + puts("void movq(const Address& addr, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opMR(addr, mmx, T_0F, mmx.isXMM() ? 0xD6 : 0x7F); }"); + puts("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); }"); + puts("void rdseed(const Reg& r) { if (r.isBit(8)) XBYAK_THROW(ERR_BAD_SIZE_OF_REGISTER) opRR(Reg(7, Operand::REG, r.getBit()), r, T_0F, 0xC7); }"); + puts("void crc32(const Reg32e& reg, const Operand& op) { if (reg.isBit(32) && op.isBit(16)) db(0x66); opRO(reg, op, op.isREG(), op.isMEM(), T_F2 | T_0F38, 0xF0 | (op.isBit(8) ? 0 : 1)); }"); puts("void tpause(const Reg32& r) { int idx = r.getIdx(); if (idx > 7) XBYAK_THROW(ERR_BAD_PARAMETER) db(0x66); db(0x0F); db(0xAE); setModRM(3, 6, idx); }"); puts("void umonitor(const Reg& r) { int idx = r.getIdx(); if (idx > 7) XBYAK_THROW(ERR_BAD_PARAMETER) int bit = r.getBit(); if (BIT != bit) { if ((BIT == 32 && bit == 16) || (BIT == 64 && bit == 32)) { db(0x67); } else { XBYAK_THROW(ERR_BAD_SIZE_OF_REGISTER) } } db(0xF3); db(0x0F); db(0xAE); setModRM(3, 6, idx); }"); puts("void umwait(const Reg32& r) { int idx = r.getIdx(); if (idx > 7) XBYAK_THROW(ERR_BAD_PARAMETER) db(0xF2); db(0x0F); db(0xAE); setModRM(3, 6, idx); }"); - puts("void clwb(const Address& addr) { opModM(addr, esi, T_66 | T_0F, 0xAE); }"); - puts("void cldemote(const Address& addr) { opModM(addr, eax, T_0F, 0x1C); }"); + puts("void clwb(const Address& addr) { opMR(addr, esi, T_66 | T_0F, 0xAE); }"); + puts("void cldemote(const Address& addr) { opMR(addr, eax, T_0F, 0x1C); }"); puts("void xabort(uint8_t imm) { db(0xC6); db(0xF8); db(imm); }"); puts("void xbegin(uint32_t rel) { db(0xC7); db(0xF8); dd(rel); }"); @@ -1900,12 +1900,12 @@ void put64() putMemOp("cmpxchg16b", "T_0F", 1, 0xC7, 64); putMemOp("fxrstor64", "T_0F", 1, 0xAE, 64); - puts("void movq(const Reg64& reg, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opModR(mmx, reg, T_0F, 0x7E); }"); - puts("void movq(const Mmx& mmx, const Reg64& reg) { if (mmx.isXMM()) db(0x66); opModR(mmx, reg, T_0F, 0x6E); }"); - puts("void movsxd(const Reg64& reg, const Operand& op) { if (!op.isBit(32)) XBYAK_THROW(ERR_BAD_COMBINATION) opModRM(reg, op, op.isREG(), op.isMEM(), 0, 0x63); }"); + puts("void movq(const Reg64& reg, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opRR(mmx, reg, T_0F, 0x7E); }"); + puts("void movq(const Mmx& mmx, const Reg64& reg) { if (mmx.isXMM()) db(0x66); opRR(mmx, reg, T_0F, 0x6E); }"); + puts("void movsxd(const Reg64& reg, const Operand& op) { if (!op.isBit(32)) XBYAK_THROW(ERR_BAD_COMBINATION) opRO(reg, op, op.isREG(), op.isMEM(), 0, 0x63); }"); puts("void pextrq(const Operand& op, const Xmm& xmm, uint8_t imm) { if (!op.isREG(64) && !op.isMEM()) XBYAK_THROW(ERR_BAD_COMBINATION) opGen(Reg64(xmm.getIdx()), op, T_66 | T_0F3A, 0x16, 0, imm); }"); puts("void pinsrq(const Xmm& xmm, const Operand& op, uint8_t imm) { if (!op.isREG(64) && !op.isMEM()) XBYAK_THROW(ERR_BAD_COMBINATION) opGen(Reg64(xmm.getIdx()), op, T_66 | T_0F3A, 0x22, 0, imm); }"); - puts("void senduipi(const Reg64& r) { opModR(Reg32(6), r.cvt32(), T_F3 | T_0F, 0xC7); }"); + puts("void senduipi(const Reg64& r) { opRR(Reg32(6), r.cvt32(), T_F3 | T_0F, 0xC7); }"); puts("void vcvtss2si(const Reg64& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, T_0F | T_F3 | T_W1 | T_EVEX | T_EW1 | T_ER_X | T_N8, 0x2D); }"); puts("void vcvttss2si(const Reg64& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, T_0F | T_F3 | T_W1 | T_EVEX | T_EW1 | T_SAE_X | T_N8, 0x2C); }"); diff --git a/xbyak/xbyak.h b/xbyak/xbyak.h index dead484..64ea487 100644 --- a/xbyak/xbyak.h +++ b/xbyak/xbyak.h @@ -1983,7 +1983,7 @@ private: } LabelManager labelMgr_; bool isInDisp16(uint32_t x) const { return 0xFFFF8000 <= x || x <= 0x7FFF; } - void writeCode2(int type, const Reg& r, int code) + void writeCode(int type, const Reg& r, int code) { if (type & T_0F) { db(0x0F); @@ -1994,25 +1994,25 @@ private: } db(code | (type == 0 && !r.isBit(8))); } - void opModR(const Reg& reg1, const Reg& reg2, int type, int code) + void opRR(const Reg& reg1, const Reg& reg2, int type, int code) { rex(reg2, reg1, type); - writeCode2(type, reg1, code); + writeCode(type, reg1, code); setModRM(3, reg1.getIdx(), reg2.getIdx()); } - void opModM(const Address& addr, const Reg& reg, int type, int code, int immSize = 0) + void opMR(const Address& addr, const Reg& reg, int type, int code, int immSize = 0) { if (addr.is64bitDisp()) XBYAK_THROW(ERR_CANT_USE_64BIT_DISP) rex(addr, reg, type); - writeCode2(type, reg, code); + writeCode(type, reg, code); opAddr(addr, reg.getIdx(), immSize); } void opLoadSeg(const Address& addr, const Reg& reg, int type, int code) { if (reg.isBit(8)) XBYAK_THROW(ERR_BAD_SIZE_OF_REGISTER) if (addr.is64bitDisp()) XBYAK_THROW(ERR_CANT_USE_64BIT_DISP) - // can't use opModM - rex(addr, reg); + // can't use opMR + rex(addr, reg, type); if (type & T_0F) db(0x0F); db(code); opAddr(addr, reg.getIdx()); @@ -2021,7 +2021,7 @@ private: void opMIB(const Address& addr, const Reg& reg, int type, int code) { if (addr.getMode() != Address::M_ModRM) XBYAK_THROW(ERR_INVALID_MIB_ADDRESS) - opModM(addr.cloneNoOptimize(), reg, type, code); + opMR(addr.cloneNoOptimize(), reg, type, code); } void makeJmp(uint32_t disp, LabelType type, uint8_t shortCode, uint8_t longCode, uint8_t longPref) { @@ -2079,9 +2079,9 @@ private: const int bit = 16|i32e; if (type == T_FAR) { if (!op.isMEM(bit)) XBYAK_THROW(ERR_NOT_SUPPORTED) - opR_ModM(op, bit, ext + 1, 0, 0xFF, false); + opRext(op, bit, ext + 1, 0, 0xFF, false); } else { - opR_ModM(op, bit, ext, 0, 0xFF, true); + opRext(op, bit, ext, 0, 0xFF, true); } } // reg is reg field of ModRM @@ -2111,9 +2111,9 @@ private: if (isValid && !isValid(reg, op)) XBYAK_THROW(ERR_BAD_COMBINATION) if (!isValidSSE(reg) || !isValidSSE(op)) XBYAK_THROW(ERR_NOT_SUPPORTED) if (op.isMEM()) { - opModM(op.getAddress(), reg.getReg(), type, code, (imm8 != NONE) ? 1 : 0); + opMR(op.getAddress(), reg.getReg(), type, code, (imm8 != NONE) ? 1 : 0); } else { - opModR(reg.getReg(), op.getReg(), type, code); + opRR(reg.getReg(), op.getReg(), type, code); } if (imm8 != NONE) db(imm8); } @@ -2122,7 +2122,7 @@ private: if (!isValidSSE(mmx)) XBYAK_THROW(ERR_NOT_SUPPORTED) int type = T_0F; if (mmx.isXMM()) type |= T_66; - opModR(Reg32(ext), mmx, type, code); + opRR(Reg32(ext), mmx, type, code); db(imm8); } void opMMX(const Mmx& mmx, const Operand& op, int code, int type = T_0F, int pref = T_66, int imm8 = NONE) @@ -2134,31 +2134,32 @@ private: { if (!isValidSSE(op1) || !isValidSSE(op2)) XBYAK_THROW(ERR_NOT_SUPPORTED) if (op1.isXMM() && op2.isMEM()) { - opModM(op2.getAddress(), op1.getReg(), type, code); + opMR(op2.getAddress(), op1.getReg(), type, code); } else if (op1.isMEM() && op2.isXMM()) { - opModM(op1.getAddress(), op2.getReg(), type, code | 1); + opMR(op1.getAddress(), op2.getReg(), type, code | 1); } else { XBYAK_THROW(ERR_BAD_COMBINATION) } } + // pextr{w,b,d}, extractps void opExt(const Operand& op, const Mmx& mmx, int code, int imm, bool hasMMX2 = false) { if (!isValidSSE(op) || !isValidSSE(mmx)) XBYAK_THROW(ERR_NOT_SUPPORTED) if (hasMMX2 && op.isREG(i32e)) { /* pextrw is special */ if (mmx.isXMM()) db(0x66); - opModR(op.getReg(), mmx, T_0F, 0xC5); db(imm); + opRR(op.getReg(), mmx, T_0F, 0xC5); db(imm); } else { opGen(mmx, op, T_66 | T_0F3A, code, isXMM_REG32orMEM, imm); } } - void opR_ModM(const Operand& op, int bit, int ext, int type, int code, bool disableRex = false, int immSize = 0) + void opRext(const Operand& op, int bit, int ext, int type, int code, bool disableRex = false, int immSize = 0) { int opBit = op.getBit(); if (disableRex && opBit == 64) opBit = 32; if (op.isREG(bit)) { - opModR(Reg(ext, Operand::REG, opBit), op.getReg().changeBit(opBit), type, code); + opRR(Reg(ext, Operand::REG, opBit), op.getReg().changeBit(opBit), type, code); } else if (op.isMEM()) { - opModM(op.getAddress(), Reg(ext, Operand::REG, opBit), type, code, immSize); + opMR(op.getAddress(), Reg(ext, Operand::REG, opBit), type, code, immSize); } else { XBYAK_THROW(ERR_BAD_COMBINATION) } @@ -2166,20 +2167,20 @@ private: void opShift(const Operand& op, int imm, int ext) { verifyMemHasSize(op); - opR_ModM(op, 0, ext, 0, (0xC0 | ((imm == 1 ? 1 : 0) << 4)), false, (imm != 1) ? 1 : 0); + opRext(op, 0, ext, 0, (0xC0 | ((imm == 1 ? 1 : 0) << 4)), false, (imm != 1) ? 1 : 0); if (imm != 1) db(imm); } void opShift(const Operand& op, const Reg8& _cl, int ext) { if (_cl.getIdx() != Operand::CL) XBYAK_THROW(ERR_BAD_COMBINATION) - opR_ModM(op, 0, ext, 0, 0xD2); + opRext(op, 0, ext, 0, 0xD2); } - void opModRM(const Operand& op1, const Operand& op2, bool condR, bool condM, int type, int code, int immSize = 0) + void opRO(const Reg& r, const Operand& op, bool condR, bool condM, int type, int code, int immSize = 0) { if (condR) { - opModR(op1.getReg(), op2.getReg(), type, code); + opRR(r, op.getReg(), type, code); } else if (condM) { - opModM(op2.getAddress(), op1.getReg(), type, code, immSize); + opMR(op.getAddress(), r, type, code, immSize); } else { XBYAK_THROW(ERR_BAD_COMBINATION) } @@ -2187,16 +2188,18 @@ private: void opShxd(const Operand& op, const Reg& reg, uint8_t imm, int code, const Reg8 *_cl = 0) { if (_cl && _cl->getIdx() != Operand::CL) XBYAK_THROW(ERR_BAD_COMBINATION) - opModRM(reg, op, (op.isREG(16 | i32e) && op.getBit() == reg.getBit()), op.isMEM() && (reg.isREG(16 | i32e)), T_0F, code | (_cl ? 1 : 0), _cl ? 0 : 1); + opRO(reg, op, (op.isREG(16 | i32e) && op.getBit() == reg.getBit()), op.isMEM() && (reg.isREG(16 | i32e)), T_0F, code | (_cl ? 1 : 0), _cl ? 0 : 1); if (!_cl) db(imm); } // (REG, REG|MEM), (MEM, REG) - void opRM_RM(const Operand& op1, const Operand& op2, int code) + void opRO_MR(const Operand& op1, const Operand& op2, int code) { if (op1.isREG() && op2.isMEM()) { - opModM(op2.getAddress(), op1.getReg(), 0, code | 2); + opMR(op2.getAddress(), op1.getReg(), 0, code | 2); + } else if (op2.isREG()) { + opRO(static_cast(op2), op1, op1.isREG() && op1.getKind() == op2.getKind(), op1.isMEM() && op2.isREG(), 0, code); } else { - opModRM(op2, op1, op1.isREG() && op1.getKind() == op2.getKind(), op1.isMEM() && op2.isREG(), 0, code); + XBYAK_THROW(ERR_BAD_COMBINATION) } } uint32_t getImmBit(const Operand& op, uint32_t imm) @@ -2209,7 +2212,7 @@ private: return immBit; } // (REG|MEM, IMM) - void opRM_I(const Operand& op, uint32_t imm, int code, int ext) + void opOI(const Operand& op, uint32_t imm, int code, int ext) { uint32_t immBit = getImmBit(op, imm); if (op.isREG() && op.getIdx() == 0 && (op.getBit() == immBit || (op.isBit(64) && immBit == 32))) { // rax, eax, ax, al @@ -2217,7 +2220,7 @@ private: db(code | 4 | (immBit == 8 ? 0 : 1)); } else { int tmp = immBit < (std::min)(op.getBit(), 32U) ? 2 : 0; - opR_ModM(op, 0, ext, 0, 0x80 | tmp, false, immBit / 8); + opRext(op, 0, ext, 0, 0x80 | tmp, false, immBit / 8); } db(imm, immBit / 8); } @@ -2240,9 +2243,9 @@ private: #endif code = 0xFE; if (op.isREG()) { - opModR(Reg(ext, Operand::REG, op.getBit()), op.getReg(), 0, code); + opRR(Reg(ext, Operand::REG, op.getBit()), op.getReg(), 0, code); } else { - opModM(op.getAddress(), Reg(ext, Operand::REG, op.getBit()), 0, code); + opMR(op.getAddress(), Reg(ext, Operand::REG, op.getBit()), 0, code); } } void opPushPop(const Operand& op, int code, int ext, int alt) @@ -2256,7 +2259,7 @@ private: return; } if (op.isMEM()) { - opModM(op.getAddress(), Reg(ext, Operand::REG, 32), 0, code); + opMR(op.getAddress(), Reg(ext, Operand::REG, 32), 0, code); return; } } @@ -2314,7 +2317,7 @@ private: if (op.isBit(32)) XBYAK_THROW(ERR_BAD_COMBINATION) int w = op.isBit(16); bool cond = reg.isREG() && (reg.getBit() > op.getBit()); - opModRM(reg, op, cond && op.isREG(), cond && op.isMEM(), T_0F, code | w); + opRO(reg, op, cond && op.isREG(), cond && op.isMEM(), T_0F, code | w); } void opFpuMem(const Address& addr, uint8_t m16, uint8_t m32, uint8_t m64, uint8_t ext, uint8_t m64ext) { @@ -2322,7 +2325,6 @@ private: uint8_t code = addr.isBit(16) ? m16 : addr.isBit(32) ? m32 : addr.isBit(64) ? m64 : 0; if (!code) XBYAK_THROW(ERR_BAD_MEM_SIZE) if (m64ext && addr.isBit(64)) ext = m64ext; - rex(addr, st0); db(code); opAddr(addr, ext); @@ -2463,7 +2465,7 @@ private: bool is16bit = reg.isREG(16) && (op.isREG(16) || op.isMEM()); if (!is16bit && !(reg.isREG(i32e) && (op.isREG(reg.getBit()) || op.isMEM()))) XBYAK_THROW(ERR_BAD_COMBINATION) if (is16bit) db(0x66); - opModRM(reg.changeBit(i32e == 32 ? 32 : reg.getBit()), op, op.isREG(), true, T_F3 | T_0F, code); + opRO(reg.changeBit(i32e == 32 ? 32 : reg.getBit()), op, op.isREG(), true, T_F3 | T_0F, code); } void opGather(const Xmm& x1, const Address& addr, const Xmm& x2, int type, uint8_t code, int mode) { @@ -2686,7 +2688,7 @@ public: void test(const Operand& op, const Reg& reg) { - opModRM(reg, op, op.isREG() && (op.getKind() == reg.getKind()), op.isMEM(), 0, 0x84); + opRO(reg, op, op.isREG() && (op.getKind() == reg.getKind()), op.isMEM(), 0, 0x84); } void test(const Operand& op, uint32_t imm) { @@ -2696,19 +2698,19 @@ public: rex(op); db(0xA8 | (op.isBit(8) ? 0 : 1)); } else { - opR_ModM(op, 0, 0, 0, 0xF6, false, immSize); + opRext(op, 0, 0, 0, 0xF6, false, immSize); } db(imm, immSize); } void imul(const Reg& reg, const Operand& op) { - opModRM(reg, op, op.isREG() && (reg.getKind() == op.getKind()), op.isMEM(), T_0F, 0xAF); + opRO(reg, op, op.isREG() && (reg.getKind() == op.getKind()), op.isMEM(), T_0F, 0xAF); } void imul(const Reg& reg, const Operand& op, int imm) { int s = inner::IsInDisp8(imm) ? 1 : 0; int immSize = s ? 1 : reg.isREG(16) ? 2 : 4; - opModRM(reg, op, op.isREG() && (reg.getKind() == op.getKind()), op.isMEM(), 0, 0x69 | (s << 1), immSize); + opRO(reg, op, op.isREG() && (reg.getKind() == op.getKind()), op.isMEM(), 0, 0x69 | (s << 1), immSize); db(imm, immSize); } void push(const Operand& op) { opPushPop(op, 0xFF, 6, 0x50); } @@ -2765,7 +2767,7 @@ public: } else #endif { - opRM_RM(reg1, reg2, 0x88); + opRO_MR(reg1, reg2, 0x88); } } void mov(const Operand& op, uint64_t imm) @@ -2783,7 +2785,7 @@ public: if (!inner::IsInInt32(imm)) XBYAK_THROW(ERR_IMM_IS_TOO_BIG) immSize = 4; } - opModM(op.getAddress(), Reg(0, Operand::REG, op.getBit()), 0, 0xC6, immSize); + opMR(op.getAddress(), Reg(0, Operand::REG, op.getBit()), 0, 0xC6, immSize); db(static_cast(imm), immSize); } else { XBYAK_THROW(ERR_BAD_COMBINATION) @@ -2815,7 +2817,7 @@ public: rex(*p2, *p1); db(0x90 | (p2->getIdx() & 7)); return; } - opModRM(*p1, *p2, (p1->isREG() && p2->isREG() && (p1->getBit() == p2->getBit())), p2->isMEM(), 0, 0x86 | (p1->isBit(8) ? 0 : 1)); + opRO(static_cast(*p1), *p2, (p1->isREG() && p2->isREG() && (p1->getBit() == p2->getBit())), p2->isMEM(), 0, 0x86 | (p1->isBit(8) ? 0 : 1)); } #ifndef XBYAK_DISABLE_SEGMENT @@ -2860,11 +2862,11 @@ public: } void mov(const Operand& op, const Segment& seg) { - opModRM(Reg8(seg.getIdx()), op, op.isREG(16|i32e), op.isMEM(), 0, 0x8C); + opRO(Reg8(seg.getIdx()), op, op.isREG(16|i32e), op.isMEM(), 0, 0x8C); } void mov(const Segment& seg, const Operand& op) { - opModRM(Reg8(seg.getIdx()), op.isREG(16|i32e) ? static_cast(op.getReg().cvt32()) : op, op.isREG(16|i32e), op.isMEM(), 0, 0x8E); + opRO(Reg8(seg.getIdx()), op.isREG(16|i32e) ? static_cast(op.getReg().cvt32()) : op, op.isREG(16|i32e), op.isMEM(), 0, 0x8E); } // (r, r, m) or (r, m, r) @@ -2879,11 +2881,11 @@ public: const Address& addr = p2->getAddress(); const RegExp e = addr.getRegExp(); evexLeg(r, e.getBase(), e.getIndex(), d, type); - writeCode2(type, d, code); + writeCode(type, d, code); opAddr(addr, r.getIdx(), immSize); } else { evexLeg(static_cast(op2), static_cast(op1), Reg(), d, type); - writeCode2(type, d, code); + writeCode(type, d, code); setModRM(3, op2.getIdx(), op1.getIdx()); } return true; diff --git a/xbyak/xbyak_mnemonic.h b/xbyak/xbyak_mnemonic.h index 337f4c3..24cbb78 100644 --- a/xbyak/xbyak_mnemonic.h +++ b/xbyak/xbyak_mnemonic.h @@ -1,14 +1,14 @@ const char *getVersionString() const { return "6.73"; } -void aadd(const Address& addr, const Reg32e ®) { opModM(addr, reg, T_0F38, 0x0FC); } -void aand(const Address& addr, const Reg32e ®) { opModM(addr, reg, T_0F38 | T_66, 0x0FC); } -void adc(const Operand& op, uint32_t imm) { opRM_I(op, imm, 0x10, 2); } -void adc(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x10); } +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 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, 0, 2); } void adc(const Reg& d, const Operand& op1, const Operand& op2) { opROO(d, op1, op2, 0, 0x10); } void adcx(const Reg32e& d, const Reg32e& reg, const Operand& op) { opROO(d, op, reg, T_66, 0x66); } void adcx(const Reg32e& reg, const Operand& op) { if (opROO(Reg(), op, reg, T_66, 0x66)) return; opGen(reg, op, T_66 | T_0F38, 0xF6, isREG32_REG32orMEM); } -void add(const Operand& op, uint32_t imm) { opRM_I(op, imm, 0x00, 0); } -void add(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x00); } +void add(const Operand& op, uint32_t imm) { opOI(op, imm, 0x00, 0); } +void add(const Operand& op1, const Operand& op2) { opRO_MR(op1, op2, 0x00); } void add(const Reg& d, const Operand& op, uint32_t imm) { opROI(d, op, imm, 0, 0); } void add(const Reg& d, const Operand& op1, const Operand& op2) { opROO(d, op1, op2, 0, 0x00); } void addpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F | T_66, 0x58, isXMM_XMMorMEM); } @@ -25,8 +25,8 @@ void aesenc(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_66 | T_0F38 | void aesenclast(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_66 | T_0F38 | T_YMM | T_EVEX, 0xDD, isXMM_XMMorMEM); } void aesimc(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_66 | T_0F38 | T_W0, 0xDB, isXMM_XMMorMEM, NONE); } void aeskeygenassist(const Xmm& xmm, const Operand& op, uint8_t imm) { opGen(xmm, op, T_66 | T_0F3A, 0xDF, isXMM_XMMorMEM, imm); } -void and_(const Operand& op, uint32_t imm) { opRM_I(op, imm, 0x20, 4); } -void and_(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x20); } +void and_(const Operand& op, uint32_t imm) { opOI(op, imm, 0x20, 4); } +void and_(const Operand& op1, const Operand& op2) { opRO_MR(op1, op2, 0x20); } void and_(const Reg& d, const Operand& op, uint32_t imm) { opROI(d, op, imm, 0, 4); } void and_(const Reg& d, const Operand& op1, const Operand& op2) { opROO(d, op1, op2, 0, 0x20); } void andn(const Reg32e& r1, const Reg32e& r2, const Operand& op) { opGpr(r1, r2, op, T_0F38, 0xf2, true); } @@ -34,8 +34,8 @@ void andnpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F | T_66, 0x5 void andnps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F, 0x55, isXMM_XMMorMEM); } void andpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F | T_66, 0x54, isXMM_XMMorMEM); } void andps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F, 0x54, isXMM_XMMorMEM); } -void aor(const Address& addr, const Reg32e ®) { opModM(addr, reg, T_0F38 | T_F2, 0x0FC); } -void axor(const Address& addr, const Reg32e ®) { opModM(addr, reg, T_0F38 | T_F3, 0x0FC); } +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 bextr(const Reg32e& r1, const Operand& op, const Reg32e& r2) { opGpr(r1, op, r2, T_0F38, 0xf7, false); } void blendpd(const Xmm& xmm, const Operand& op, int imm) { opGen(xmm, op, T_66 | T_0F3A, 0x0D, isXMM_XMMorMEM, static_cast(imm)); } void blendps(const Xmm& xmm, const Operand& op, int imm) { opGen(xmm, op, T_66 | T_0F3A, 0x0C, isXMM_XMMorMEM, static_cast(imm)); } @@ -45,69 +45,69 @@ void blsi(const Reg32e& r, const Operand& op) { opGpr(Reg32e(3, r.getBit()), op, void blsmsk(const Reg32e& r, const Operand& op) { opGpr(Reg32e(2, r.getBit()), op, r, T_0F38, 0xf3, false); } void blsr(const Reg32e& r, const Operand& op) { opGpr(Reg32e(1, r.getBit()), op, r, T_0F38, 0xf3, false); } void bnd() { db(0xF2); } -void bndcl(const BoundsReg& bnd, const Operand& op) { opR_ModM(op, i32e, bnd.getIdx(), T_F3 | T_0F, 0x1A, !op.isMEM()); } -void bndcn(const BoundsReg& bnd, const Operand& op) { opR_ModM(op, i32e, bnd.getIdx(), T_F2 | T_0F, 0x1B, !op.isMEM()); } -void bndcu(const BoundsReg& bnd, const Operand& op) { opR_ModM(op, i32e, bnd.getIdx(), T_F2 | T_0F, 0x1A, !op.isMEM()); } +void bndcl(const BoundsReg& bnd, const Operand& op) { opRext(op, i32e, bnd.getIdx(), T_F3 | T_0F, 0x1A, !op.isMEM()); } +void bndcn(const BoundsReg& bnd, const Operand& op) { opRext(op, i32e, bnd.getIdx(), T_F2 | T_0F, 0x1B, !op.isMEM()); } +void bndcu(const BoundsReg& bnd, const Operand& op) { opRext(op, i32e, bnd.getIdx(), T_F2 | T_0F, 0x1A, !op.isMEM()); } void bndldx(const BoundsReg& bnd, const Address& addr) { opMIB(addr, bnd, T_0F, 0x1A); } -void bndmk(const BoundsReg& bnd, const Address& addr) { opModM(addr, bnd, T_F3 | T_0F, 0x1B); } -void bndmov(const Address& addr, const BoundsReg& bnd) { opModM(addr, bnd, T_66 | T_0F, 0x1B); } -void bndmov(const BoundsReg& bnd, const Operand& op) { opModRM(bnd, op, op.isBNDREG(), op.isMEM(), T_66 | T_0F, 0x1A); } +void bndmk(const BoundsReg& bnd, const Address& addr) { opMR(addr, bnd, T_F3 | T_0F, 0x1B); } +void bndmov(const Address& addr, const BoundsReg& bnd) { opMR(addr, bnd, T_66 | T_0F, 0x1B); } +void bndmov(const BoundsReg& bnd, const Operand& op) { opRO(bnd, op, op.isBNDREG(), op.isMEM(), T_66 | T_0F, 0x1A); } void bndstx(const Address& addr, const BoundsReg& bnd) { opMIB(addr, bnd, T_0F, 0x1B); } -void bsf(const Reg®, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0xBC); } -void bsr(const Reg®, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0xBD); } -void bswap(const Reg32e& reg) { opModR(Reg32(1), reg, 0, 0x0F); } -void bt(const Operand& op, const Reg& reg) { opModRM(reg, op, op.isREG(16|32|64) && op.getBit() == reg.getBit(), op.isMEM(), T_0F, 0xA3); } -void bt(const Operand& op, uint8_t imm) { opR_ModM(op, 16|32|64, 4, T_0F, 0xba, false, 1); db(imm); } -void btc(const Operand& op, const Reg& reg) { opModRM(reg, op, op.isREG(16|32|64) && op.getBit() == reg.getBit(), op.isMEM(), T_0F, 0xBB); } -void btc(const Operand& op, uint8_t imm) { opR_ModM(op, 16|32|64, 7, T_0F, 0xba, false, 1); db(imm); } -void btr(const Operand& op, const Reg& reg) { opModRM(reg, op, op.isREG(16|32|64) && op.getBit() == reg.getBit(), op.isMEM(), T_0F, 0xB3); } -void btr(const Operand& op, uint8_t imm) { opR_ModM(op, 16|32|64, 6, T_0F, 0xba, false, 1); db(imm); } -void bts(const Operand& op, const Reg& reg) { opModRM(reg, op, op.isREG(16|32|64) && op.getBit() == reg.getBit(), op.isMEM(), T_0F, 0xAB); } -void bts(const Operand& op, uint8_t imm) { opR_ModM(op, 16|32|64, 5, T_0F, 0xba, false, 1); db(imm); } +void bsf(const Reg®, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0xBC); } +void bsr(const Reg®, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0xBD); } +void bswap(const Reg32e& reg) { opRR(Reg32(1), reg, 0, 0x0F); } +void bt(const Operand& op, const Reg& reg) { opRO(reg, op, op.isREG(16|32|64) && op.getBit() == reg.getBit(), op.isMEM(), T_0F, 0xA3); } +void bt(const Operand& op, uint8_t imm) { opRext(op, 16|32|64, 4, T_0F, 0xba, false, 1); db(imm); } +void btc(const Operand& op, const Reg& reg) { opRO(reg, op, op.isREG(16|32|64) && op.getBit() == reg.getBit(), op.isMEM(), T_0F, 0xBB); } +void btc(const Operand& op, uint8_t imm) { opRext(op, 16|32|64, 7, T_0F, 0xba, false, 1); db(imm); } +void btr(const Operand& op, const Reg& reg) { opRO(reg, op, op.isREG(16|32|64) && op.getBit() == reg.getBit(), op.isMEM(), T_0F, 0xB3); } +void btr(const Operand& op, uint8_t imm) { opRext(op, 16|32|64, 6, T_0F, 0xba, false, 1); db(imm); } +void bts(const Operand& op, const Reg& reg) { opRO(reg, op, op.isREG(16|32|64) && op.getBit() == reg.getBit(), op.isMEM(), T_0F, 0xAB); } +void bts(const Operand& op, uint8_t imm) { opRext(op, 16|32|64, 5, T_0F, 0xba, false, 1); db(imm); } void bzhi(const Reg32e& r1, const Operand& op, const Reg32e& r2) { opGpr(r1, op, r2, T_0F38, 0xf5, false); } void cbw() { db(0x66); db(0x98); } void cdq() { db(0x99); } void clc() { db(0xF8); } void cld() { db(0xFC); } -void cldemote(const Address& addr) { opModM(addr, eax, T_0F, 0x1C); } -void clflush(const Address& addr) { opModM(addr, Reg32(7), T_0F, 0xAE); } -void clflushopt(const Address& addr) { opModM(addr, Reg32(7), T_66 | T_0F, 0xAE); } +void cldemote(const Address& addr) { opMR(addr, eax, T_0F, 0x1C); } +void clflush(const Address& addr) { opMR(addr, Reg32(7), T_0F, 0xAE); } +void clflushopt(const Address& addr) { opMR(addr, Reg32(7), T_66 | T_0F, 0xAE); } void cli() { db(0xFA); } -void clwb(const Address& addr) { opModM(addr, esi, T_66 | T_0F, 0xAE); } +void clwb(const Address& addr) { opMR(addr, esi, T_66 | T_0F, 0xAE); } void clzero() { db(0x0F); db(0x01); db(0xFC); } void cmc() { db(0xF5); } -void cmova(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 7); }//-V524 -void cmovae(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 3); }//-V524 -void cmovb(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 2); }//-V524 -void cmovbe(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 6); }//-V524 -void cmovc(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 2); }//-V524 -void cmove(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 4); }//-V524 -void cmovg(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 15); }//-V524 -void cmovge(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 13); }//-V524 -void cmovl(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 12); }//-V524 -void cmovle(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 14); }//-V524 -void cmovna(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 6); }//-V524 -void cmovnae(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 2); }//-V524 -void cmovnb(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 3); }//-V524 -void cmovnbe(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 7); }//-V524 -void cmovnc(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 3); }//-V524 -void cmovne(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 5); }//-V524 -void cmovng(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 14); }//-V524 -void cmovnge(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 12); }//-V524 -void cmovnl(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 13); }//-V524 -void cmovnle(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 15); }//-V524 -void cmovno(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 1); }//-V524 -void cmovnp(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 11); }//-V524 -void cmovns(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 9); }//-V524 -void cmovnz(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 5); }//-V524 -void cmovo(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 0); }//-V524 -void cmovp(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 10); }//-V524 -void cmovpe(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 10); }//-V524 -void cmovpo(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 11); }//-V524 -void cmovs(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 8); }//-V524 -void cmovz(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 4); }//-V524 -void cmp(const Operand& op, uint32_t imm) { opRM_I(op, imm, 0x38, 7); } -void cmp(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x38); } +void cmova(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 7); }//-V524 +void cmovae(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 3); }//-V524 +void cmovb(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 2); }//-V524 +void cmovbe(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 6); }//-V524 +void cmovc(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 2); }//-V524 +void cmove(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 4); }//-V524 +void cmovg(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 15); }//-V524 +void cmovge(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 13); }//-V524 +void cmovl(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 12); }//-V524 +void cmovle(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 14); }//-V524 +void cmovna(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 6); }//-V524 +void cmovnae(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 2); }//-V524 +void cmovnb(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 3); }//-V524 +void cmovnbe(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 7); }//-V524 +void cmovnc(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 3); }//-V524 +void cmovne(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 5); }//-V524 +void cmovng(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 14); }//-V524 +void cmovnge(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 12); }//-V524 +void cmovnl(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 13); }//-V524 +void cmovnle(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 15); }//-V524 +void cmovno(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 1); }//-V524 +void cmovnp(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 11); }//-V524 +void cmovns(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 9); }//-V524 +void cmovnz(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 5); }//-V524 +void cmovo(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 0); }//-V524 +void cmovp(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 10); }//-V524 +void cmovpe(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 10); }//-V524 +void cmovpo(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 11); }//-V524 +void cmovs(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 8); }//-V524 +void cmovz(const Reg& reg, const Operand& op) { opRO(reg, op, op.isREG(16 | i32e), op.isMEM(), T_0F, 0x40 | 4); }//-V524 +void cmp(const Operand& op, uint32_t imm) { opOI(op, imm, 0x38, 7); } +void cmp(const Operand& op1, const Operand& op2) { opRO_MR(op1, op2, 0x38); } void cmpeqpd(const Xmm& x, const Operand& op) { cmppd(x, op, 0); } void cmpeqps(const Xmm& x, const Operand& op) { cmpps(x, op, 0); } void cmpeqsd(const Xmm& x, const Operand& op) { cmpsd(x, op, 0); } @@ -147,12 +147,12 @@ void cmpunordpd(const Xmm& x, const Operand& op) { cmppd(x, op, 3); } void cmpunordps(const Xmm& x, const Operand& op) { cmpps(x, op, 3); } void cmpunordsd(const Xmm& x, const Operand& op) { cmpsd(x, op, 3); } void cmpunordss(const Xmm& x, const Operand& op) { cmpss(x, op, 3); } -void cmpxchg(const Operand& op, const Reg& reg) { opModRM(reg, op, (op.isREG() && reg.isREG() && op.getBit() == reg.getBit()), op.isMEM(), T_0F, 0xB0 | (reg.isBit(8) ? 0 : 1)); } -void cmpxchg8b(const Address& addr) { opModM(addr, Reg32(1), T_0F, 0xC7); } +void cmpxchg(const Operand& op, const Reg& reg) { opRO(reg, op, (op.isREG() && reg.isREG() && op.getBit() == reg.getBit()), op.isMEM(), T_0F, 0xB0 | (reg.isBit(8) ? 0 : 1)); } +void cmpxchg8b(const Address& addr) { opMR(addr, Reg32(1), T_0F, 0xC7); } void comisd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F | T_66, 0x2F, isXMM_XMMorMEM); } void comiss(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F | 0, 0x2F, isXMM_XMMorMEM); } void cpuid() { db(0x0F); db(0xA2); } -void crc32(const Reg32e& reg, const Operand& op) { if (reg.isBit(32) && op.isBit(16)) db(0x66); opModRM(reg, op, op.isREG(), op.isMEM(), T_F2 | T_0F38, 0xF0 | (op.isBit(8) ? 0 : 1)); } +void crc32(const Reg32e& reg, const Operand& op) { if (reg.isBit(32) && op.isBit(16)) db(0x66); opRO(reg, op, op.isREG(), op.isMEM(), T_F2 | T_0F38, 0xF0 | (op.isBit(8) ? 0 : 1)); } void cvtdq2pd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F | T_F3, 0xE6, isXMM_XMMorMEM); } void cvtdq2ps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F | 0, 0x5B, isXMM_XMMorMEM); } void cvtpd2dq(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F | T_F2, 0xE6, isXMM_XMMorMEM); } @@ -178,7 +178,7 @@ void cvttss2si(const Operand& reg, const Operand& op) { opGen(reg, op, T_0F | T_ void cwd() { db(0x66); db(0x99); } void cwde() { db(0x98); } void dec(const Operand& op) { opIncDec(op, 0x48, 1); } -void div(const Operand& op) { opR_ModM(op, 0, 6, 0, 0xF6); } +void div(const Operand& op) { opRext(op, 0, 6, 0, 0xF6); } void divpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F | T_66, 0x5E, isXMM_XMMorMEM); } void divps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F, 0x5E, isXMM_XMMorMEM); } void divsd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F | T_F2, 0x5E, isXMM_XMMorMEM); } @@ -198,8 +198,8 @@ void fadd(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0xD8C0, 0xDCC void faddp() { db(0xDE); db(0xC1); } void faddp(const Fpu& reg1) { opFpuFpu(reg1, st0, 0x0000, 0xDEC0); } void faddp(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0x0000, 0xDEC0); } -void fbld(const Address& addr) { opModM(addr, Reg32(4), 0, 0xDF); } -void fbstp(const Address& addr) { opModM(addr, Reg32(6), 0, 0xDF); } +void fbld(const Address& addr) { opMR(addr, Reg32(4), 0, 0xDF); } +void fbstp(const Address& addr) { opMR(addr, Reg32(6), 0, 0xDF); } void fchs() { db(0xD9); db(0xE0); } void fclex() { db(0x9B); db(0xDB); db(0xE2); } void fcmovb(const Fpu& reg1) { opFpuFpu(st0, reg1, 0xDAC0, 0x00C0); } @@ -261,8 +261,8 @@ void fisubr(const Address& addr) { opFpuMem(addr, 0xDE, 0xDA, 0x00, 5, 0); } void fld(const Address& addr) { opFpuMem(addr, 0x00, 0xD9, 0xDD, 0, 0); } void fld(const Fpu& reg) { opFpu(reg, 0xD9, 0xC0); } void fld1() { db(0xD9); db(0xE8); } -void fldcw(const Address& addr) { opModM(addr, Reg32(5), 0, 0xD9); } -void fldenv(const Address& addr) { opModM(addr, Reg32(4), 0, 0xD9); } +void fldcw(const Address& addr) { opMR(addr, Reg32(5), 0, 0xD9); } +void fldenv(const Address& addr) { opMR(addr, Reg32(4), 0, 0xD9); } void fldl2e() { db(0xD9); db(0xEA); } void fldl2t() { db(0xD9); db(0xE9); } void fldlg2() { db(0xD9); db(0xEC); } @@ -278,29 +278,29 @@ void fmulp(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0x0000, 0xDE void fnclex() { db(0xDB); db(0xE2); } void fninit() { db(0xDB); db(0xE3); } void fnop() { db(0xD9); db(0xD0); } -void fnsave(const Address& addr) { opModM(addr, Reg32(6), 0, 0xDD); } -void fnstcw(const Address& addr) { opModM(addr, Reg32(7), 0, 0xD9); } -void fnstenv(const Address& addr) { opModM(addr, Reg32(6), 0, 0xD9); } -void fnstsw(const Address& addr) { opModM(addr, Reg32(7), 0, 0xDD); } +void fnsave(const Address& addr) { opMR(addr, Reg32(6), 0, 0xDD); } +void fnstcw(const Address& addr) { opMR(addr, Reg32(7), 0, 0xD9); } +void fnstenv(const Address& addr) { opMR(addr, Reg32(6), 0, 0xD9); } +void fnstsw(const Address& addr) { opMR(addr, Reg32(7), 0, 0xDD); } void fnstsw(const Reg16& r) { if (r.getIdx() != Operand::AX) XBYAK_THROW(ERR_BAD_PARAMETER) db(0xDF); db(0xE0); } void fpatan() { db(0xD9); db(0xF3); } void fprem() { db(0xD9); db(0xF8); } void fprem1() { db(0xD9); db(0xF5); } void fptan() { db(0xD9); db(0xF2); } void frndint() { db(0xD9); db(0xFC); } -void frstor(const Address& addr) { opModM(addr, Reg32(4), 0, 0xDD); } -void fsave(const Address& addr) { db(0x9B); opModM(addr, Reg32(6), 0, 0xDD); } +void frstor(const Address& addr) { opMR(addr, Reg32(4), 0, 0xDD); } +void fsave(const Address& addr) { db(0x9B); opMR(addr, Reg32(6), 0, 0xDD); } void fscale() { db(0xD9); db(0xFD); } void fsin() { db(0xD9); db(0xFE); } void fsincos() { db(0xD9); db(0xFB); } void fsqrt() { db(0xD9); db(0xFA); } void fst(const Address& addr) { opFpuMem(addr, 0x00, 0xD9, 0xDD, 2, 0); } void fst(const Fpu& reg) { opFpu(reg, 0xDD, 0xD0); } -void fstcw(const Address& addr) { db(0x9B); opModM(addr, Reg32(7), 0, 0xD9); } -void fstenv(const Address& addr) { db(0x9B); opModM(addr, Reg32(6), 0, 0xD9); } +void fstcw(const Address& addr) { db(0x9B); opMR(addr, Reg32(7), 0, 0xD9); } +void fstenv(const Address& addr) { db(0x9B); opMR(addr, Reg32(6), 0, 0xD9); } void fstp(const Address& addr) { opFpuMem(addr, 0x00, 0xD9, 0xDD, 3, 0); } void fstp(const Fpu& reg) { opFpu(reg, 0xDD, 0xD8); } -void fstsw(const Address& addr) { db(0x9B); opModM(addr, Reg32(7), 0, 0xDD); } +void fstsw(const Address& addr) { db(0x9B); opMR(addr, Reg32(7), 0, 0xDD); } void fstsw(const Reg16& r) { if (r.getIdx() != Operand::AX) XBYAK_THROW(ERR_BAD_PARAMETER) db(0x9B); db(0xDF); db(0xE0); } void fsub(const Address& addr) { opFpuMem(addr, 0x00, 0xD8, 0xDC, 4, 0); } void fsub(const Fpu& reg1) { opFpuFpu(st0, reg1, 0xD8E0, 0xDCE8); } @@ -328,7 +328,7 @@ void fwait() { db(0x9B); } void fxam() { db(0xD9); db(0xE5); } void fxch() { db(0xD9); db(0xC9); } void fxch(const Fpu& reg) { opFpu(reg, 0xD9, 0xC8); } -void fxrstor(const Address& addr) { opModM(addr, Reg32(1), T_0F, 0xAE); } +void fxrstor(const Address& addr) { opMR(addr, Reg32(1), T_0F, 0xAE); } void fxtract() { db(0xD9); db(0xF4); } void fyl2x() { db(0xD9); db(0xF1); } void fyl2xp1() { db(0xD9); db(0xF9); } @@ -340,8 +340,8 @@ void haddps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_F2 | T_0F | T_ void hlt() { db(0xF4); } void hsubpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_66 | T_0F | T_YMM, 0x7D, isXMM_XMMorMEM); } void hsubps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_F2 | T_0F | T_YMM, 0x7D, isXMM_XMMorMEM); } -void idiv(const Operand& op) { opR_ModM(op, 0, 7, 0, 0xF6); } -void imul(const Operand& op) { opR_ModM(op, 0, 5, 0, 0xF6); } +void idiv(const Operand& op) { opRext(op, 0, 7, 0, 0xF6); } +void imul(const Operand& op) { opRext(op, 0, 5, 0, 0xF6); } void in_(const Reg& a, const Reg& d) { opInOut(a, d, 0xEC); } void in_(const Reg& a, uint8_t v) { opInOut(a, 0xE4, v); } void inc(const Operand& op) { opIncDec(op, 0x40, 0); } @@ -469,9 +469,9 @@ void jz(const char *label, LabelType type = T_AUTO) { jz(std::string(label), typ void jz(const void *addr) { opJmpAbs(addr, T_NEAR, 0x74, 0x84, 0x0F); }//-V524 void jz(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x74, 0x84, 0x0F); }//-V524 void lahf() { db(0x9F); } -void lddqu(const Xmm& xmm, const Address& addr) { opModM(addr, xmm, T_F2 | T_0F, 0xF0); } -void ldmxcsr(const Address& addr) { opModM(addr, Reg32(2), T_0F, 0xAE); } -void lea(const Reg& reg, const Address& addr) { if (!reg.isBit(16 | i32e)) XBYAK_THROW(ERR_BAD_SIZE_OF_REGISTER) opModM(addr, reg, 0, 0x8D); } +void lddqu(const Xmm& xmm, const Address& addr) { opMR(addr, xmm, T_F2 | T_0F, 0xF0); } +void ldmxcsr(const Address& addr) { opMR(addr, Reg32(2), T_0F, 0xAE); } +void lea(const Reg& reg, const Address& addr) { if (!reg.isBit(16 | i32e)) XBYAK_THROW(ERR_BAD_SIZE_OF_REGISTER) opMR(addr, reg, 0, 0x8D); } void leave() { db(0xC9); } void lfence() { db(0x0F); db(0xAE); db(0xE8); } void lfs(const Reg& reg, const Address& addr) { opLoadSeg(addr, reg, T_0F, 0xB4); } @@ -491,8 +491,8 @@ void loopne(const char *label) { loopne(std::string(label)); } void loopne(std::string label) { opJmp(label, T_SHORT, 0xE0, 0, 0); } void lss(const Reg& reg, const Address& addr) { opLoadSeg(addr, reg, T_0F, 0xB2); } void lzcnt(const Reg®, const Operand& op) { opCnt(reg, op, 0xBD); } -void maskmovdqu(const Xmm& reg1, const Xmm& reg2) { opModR(reg1, reg2, T_66 | T_0F, 0xF7); } -void maskmovq(const Mmx& reg1, const Mmx& reg2) { if (!reg1.isMMX() || !reg2.isMMX()) XBYAK_THROW(ERR_BAD_COMBINATION) opModR(reg1, reg2, T_0F, 0xF7); } +void maskmovdqu(const Xmm& reg1, const Xmm& reg2) { opRR(reg1, reg2, T_66 | T_0F, 0xF7); } +void maskmovq(const Mmx& reg1, const Mmx& reg2) { if (!reg1.isMMX() || !reg2.isMMX()) XBYAK_THROW(ERR_BAD_COMBINATION) opRR(reg1, reg2, T_0F, 0xF7); } void maxpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F | T_66, 0x5F, isXMM_XMMorMEM); } void maxps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F, 0x5F, isXMM_XMMorMEM); } void maxsd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F | T_F2, 0x5F, isXMM_XMMorMEM); } @@ -504,58 +504,58 @@ void minsd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F | T_F2, 0x5D void minss(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F | T_F3, 0x5D, isXMM_XMMorMEM); } void monitor() { db(0x0F); db(0x01); db(0xC8); } void monitorx() { db(0x0F); db(0x01); db(0xFA); } -void movapd(const Address& addr, const Xmm& xmm) { opModM(addr, xmm, T_0F|T_66, 0x29); } +void movapd(const Address& addr, const Xmm& xmm) { opMR(addr, xmm, T_0F|T_66, 0x29); } void movapd(const Xmm& xmm, const Operand& op) { opMMX(xmm, op, 0x28, T_0F, T_66); } -void movaps(const Address& addr, const Xmm& xmm) { opModM(addr, xmm, T_0F|0, 0x29); } +void movaps(const Address& addr, const Xmm& xmm) { opMR(addr, xmm, T_0F|0, 0x29); } void movaps(const Xmm& xmm, const Operand& op) { opMMX(xmm, op, 0x28, T_0F, 0); } -void movbe(const Address& addr, const Reg& reg) { opModM(addr, reg, T_0F38, 0xF1); } -void movbe(const Reg& reg, const Address& addr) { opModM(addr, reg, T_0F38, 0xF0); } -void movd(const Address& addr, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opModM(addr, mmx, T_0F, 0x7E); } -void movd(const Mmx& mmx, const Address& addr) { if (mmx.isXMM()) db(0x66); opModM(addr, mmx, T_0F, 0x6E); } -void movd(const Mmx& mmx, const Reg32& reg) { if (mmx.isXMM()) db(0x66); opModR(mmx, reg, T_0F, 0x6E); } -void movd(const Reg32& reg, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opModR(mmx, reg, T_0F, 0x7E); } +void movbe(const Address& addr, const Reg& reg) { opMR(addr, reg, T_0F38, 0xF1); } +void movbe(const Reg& reg, const Address& addr) { opMR(addr, reg, T_0F38, 0xF0); } +void movd(const Address& addr, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opMR(addr, mmx, T_0F, 0x7E); } +void movd(const Mmx& mmx, const Address& addr) { if (mmx.isXMM()) db(0x66); opMR(addr, mmx, T_0F, 0x6E); } +void movd(const Mmx& mmx, const Reg32& reg) { if (mmx.isXMM()) db(0x66); opRR(mmx, reg, T_0F, 0x6E); } +void movd(const Reg32& reg, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opRR(mmx, reg, T_0F, 0x7E); } void movddup(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_DUP | T_F2 | T_0F | T_EW1 | T_YMM | T_EVEX | T_ER_X | T_ER_Y | T_ER_Z, 0x12, isXMM_XMMorMEM, NONE); } -void movdir64b(const Reg& reg, const Address& addr) { opModM(addr, reg.cvt32(), T_66 | T_0F38, 0xF8); } -void movdiri(const Address& addr, const Reg32e& reg) { opModM(addr, reg, T_0F38, 0xF9); } -void movdq2q(const Mmx& mmx, const Xmm& xmm) { opModR(mmx, xmm, T_F2 | T_0F, 0xD6); } -void movdqa(const Address& addr, const Xmm& xmm) { opModM(addr, xmm, T_0F|T_66, 0x7F); } +void movdir64b(const Reg& reg, const Address& addr) { opMR(addr, reg.cvt32(), T_66 | T_0F38, 0xF8); } +void movdiri(const Address& addr, const Reg32e& reg) { opMR(addr, reg, T_0F38, 0xF9); } +void movdq2q(const Mmx& mmx, const Xmm& xmm) { opRR(mmx, xmm, T_F2 | T_0F, 0xD6); } +void movdqa(const Address& addr, const Xmm& xmm) { opMR(addr, xmm, T_0F|T_66, 0x7F); } void movdqa(const Xmm& xmm, const Operand& op) { opMMX(xmm, op, 0x6F, T_0F, T_66); } -void movdqu(const Address& addr, const Xmm& xmm) { opModM(addr, xmm, T_0F|T_F3, 0x7F); } +void movdqu(const Address& addr, const Xmm& xmm) { opMR(addr, xmm, T_0F|T_F3, 0x7F); } void movdqu(const Xmm& xmm, const Operand& op) { opMMX(xmm, op, 0x6F, T_0F, T_F3); } -void movhlps(const Xmm& reg1, const Xmm& reg2) { opModR(reg1, reg2, T_0F, 0x12); } +void movhlps(const Xmm& reg1, const Xmm& reg2) { opRR(reg1, reg2, T_0F, 0x12); } void movhpd(const Operand& op1, const Operand& op2) { opMovXMM(op1, op2, 0x120, 0x16); } void movhps(const Operand& op1, const Operand& op2) { opMovXMM(op1, op2, 0x100, 0x16); } -void movlhps(const Xmm& reg1, const Xmm& reg2) { opModR(reg1, reg2, T_0F, 0x16); } +void movlhps(const Xmm& reg1, const Xmm& reg2) { opRR(reg1, reg2, T_0F, 0x16); } void movlpd(const Operand& op1, const Operand& op2) { opMovXMM(op1, op2, 0x120, 0x12); } void movlps(const Operand& op1, const Operand& op2) { opMovXMM(op1, op2, 0x100, 0x12); } void movmskpd(const Reg32e& reg, const Xmm& xmm) { db(0x66); movmskps(reg, xmm); } -void movmskps(const Reg32e& reg, const Xmm& xmm) { opModR(reg, xmm, T_0F, 0x50); } -void movntdq(const Address& addr, const Xmm& reg) { opModM(addr, Reg16(reg.getIdx()), T_0F, 0xE7); } -void movntdqa(const Xmm& xmm, const Address& addr) { opModM(addr, xmm, T_66 | T_0F38, 0x2A); } -void movnti(const Address& addr, const Reg32e& reg) { opModM(addr, reg, T_0F, 0xC3); } -void movntpd(const Address& addr, const Xmm& reg) { opModM(addr, Reg16(reg.getIdx()), T_0F, 0x2B); } -void movntps(const Address& addr, const Xmm& xmm) { opModM(addr, Mmx(xmm.getIdx()), T_0F, 0x2B); } -void movntq(const Address& addr, const Mmx& mmx) { if (!mmx.isMMX()) XBYAK_THROW(ERR_BAD_COMBINATION) opModM(addr, mmx, T_0F, 0xE7); } -void movq(const Address& addr, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opModM(addr, mmx, T_0F, mmx.isXMM() ? 0xD6 : 0x7F); } -void movq(const Mmx& mmx, const Operand& op) { if (mmx.isXMM()) db(0xF3); opModRM(mmx, op, (mmx.getKind() == op.getKind()), op.isMEM(), T_0F, mmx.isXMM() ? 0x7E : 0x6F); } -void movq2dq(const Xmm& xmm, const Mmx& mmx) { opModR(xmm, mmx, T_F3 | T_0F, 0xD6); } +void movmskps(const Reg32e& reg, const Xmm& xmm) { opRR(reg, xmm, T_0F, 0x50); } +void movntdq(const Address& addr, const Xmm& reg) { opMR(addr, Reg16(reg.getIdx()), T_0F, 0xE7); } +void movntdqa(const Xmm& xmm, const Address& addr) { opMR(addr, xmm, T_66 | T_0F38, 0x2A); } +void movnti(const Address& addr, const Reg32e& reg) { opMR(addr, reg, T_0F, 0xC3); } +void movntpd(const Address& addr, const Xmm& reg) { opMR(addr, Reg16(reg.getIdx()), T_0F, 0x2B); } +void movntps(const Address& addr, const Xmm& xmm) { opMR(addr, Mmx(xmm.getIdx()), T_0F, 0x2B); } +void movntq(const Address& addr, const Mmx& mmx) { if (!mmx.isMMX()) XBYAK_THROW(ERR_BAD_COMBINATION) opMR(addr, mmx, T_0F, 0xE7); } +void movq(const Address& addr, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opMR(addr, mmx, T_0F, mmx.isXMM() ? 0xD6 : 0x7F); } +void movq(const Mmx& mmx, const Operand& op) { if (mmx.isXMM()) db(0xF3); opRO(mmx, op, (mmx.getKind() == op.getKind()), op.isMEM(), T_0F, mmx.isXMM() ? 0x7E : 0x6F); } +void movq2dq(const Xmm& xmm, const Mmx& mmx) { opRR(xmm, mmx, T_F3 | T_0F, 0xD6); } void movsb() { db(0xA4); } void movsd() { db(0xA5); } -void movsd(const Address& addr, const Xmm& xmm) { opModM(addr, xmm, T_0F|T_F2, 0x11); } +void movsd(const Address& addr, const Xmm& xmm) { opMR(addr, xmm, T_0F|T_F2, 0x11); } void movsd(const Xmm& xmm, const Operand& op) { opMMX(xmm, op, 0x10, T_0F, T_F2); } void movshdup(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_F3 | T_0F | T_EW0 | T_YMM | T_EVEX, 0x16, isXMM_XMMorMEM, NONE); } void movsldup(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_F3 | T_0F | T_EW0 | T_YMM | T_EVEX, 0x12, isXMM_XMMorMEM, NONE); } -void movss(const Address& addr, const Xmm& xmm) { opModM(addr, xmm, T_0F|T_F3, 0x11); } +void movss(const Address& addr, const Xmm& xmm) { opMR(addr, xmm, T_0F|T_F3, 0x11); } void movss(const Xmm& xmm, const Operand& op) { opMMX(xmm, op, 0x10, T_0F, T_F3); } void movsw() { db(0x66); db(0xA5); } void movsx(const Reg& reg, const Operand& op) { opMovxx(reg, op, 0xBE); } -void movupd(const Address& addr, const Xmm& xmm) { opModM(addr, xmm, T_0F|T_66, 0x11); } +void movupd(const Address& addr, const Xmm& xmm) { opMR(addr, xmm, T_0F|T_66, 0x11); } void movupd(const Xmm& xmm, const Operand& op) { opMMX(xmm, op, 0x10, T_0F, T_66); } -void movups(const Address& addr, const Xmm& xmm) { opModM(addr, xmm, T_0F|0, 0x11); } +void movups(const Address& addr, const Xmm& xmm) { opMR(addr, xmm, T_0F|0, 0x11); } void movups(const Xmm& xmm, const Operand& op) { opMMX(xmm, op, 0x10, T_0F, 0); } void movzx(const Reg& reg, const Operand& op) { opMovxx(reg, op, 0xB6); } void mpsadbw(const Xmm& xmm, const Operand& op, int imm) { opGen(xmm, op, T_66 | T_0F3A, 0x42, isXMM_XMMorMEM, static_cast(imm)); } -void mul(const Operand& op) { opR_ModM(op, 0, 4, 0, 0xF6); } +void mul(const Operand& op) { opRext(op, 0, 4, 0, 0xF6); } void mulpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F | T_66, 0x59, isXMM_XMMorMEM); } void mulps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F, 0x59, isXMM_XMMorMEM); } void mulsd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F | T_F2, 0x59, isXMM_XMMorMEM); } @@ -563,10 +563,10 @@ void mulss(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F | T_F3, 0x59 void mulx(const Reg32e& r1, const Reg32e& r2, const Operand& op) { opGpr(r1, r2, op, T_F2 | T_0F38, 0xf6, true); } void mwait() { db(0x0F); db(0x01); db(0xC9); } void mwaitx() { db(0x0F); db(0x01); db(0xFB); } -void neg(const Operand& op) { opR_ModM(op, 0, 3, 0, 0xF6); } -void not_(const Operand& op) { opR_ModM(op, 0, 2, 0, 0xF6); } -void or_(const Operand& op, uint32_t imm) { opRM_I(op, imm, 0x08, 1); } -void or_(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x08); } +void neg(const Operand& op) { opRext(op, 0, 3, 0, 0xF6); } +void not_(const Operand& op) { opRext(op, 0, 2, 0, 0xF6); } +void or_(const Operand& op, uint32_t imm) { opOI(op, imm, 0x08, 1); } +void or_(const Operand& op1, const Operand& op2) { opRO_MR(op1, op2, 0x08); } void or_(const Reg& d, const Operand& op, uint32_t imm) { opROI(d, op, imm, 0, 1); } void or_(const Reg& d, const Operand& op1, const Operand& op2) { opROO(d, op1, op2, 0, 0x08); } void orpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F | T_66, 0x56, isXMM_XMMorMEM); } @@ -645,7 +645,7 @@ void pminsw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xEA); } void pminub(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xDA); } void pminud(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_66 | T_0F38, 0x3B, isXMM_XMMorMEM); } void pminuw(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_66 | T_0F38, 0x3A, isXMM_XMMorMEM); } -void pmovmskb(const Reg32e& reg, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opModR(reg, mmx, T_0F, 0xD7); } +void pmovmskb(const Reg32e& reg, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opRR(reg, mmx, T_0F, 0xD7); } void pmovsxbd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_N4 | T_N_VL | T_66 | T_0F38 | T_YMM | T_EVEX, 0x21, isXMM_XMMorMEM, NONE); } void pmovsxbq(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_N2 | T_N_VL | T_66 | T_0F38 | T_YMM | T_EVEX, 0x22, isXMM_XMMorMEM, NONE); } void pmovsxbw(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_N8 | T_N_VL | T_66 | T_0F38 | T_YMM | T_EVEX, 0x20, isXMM_XMMorMEM, NONE); } @@ -668,14 +668,14 @@ void pmuludq(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xF4); } void popcnt(const Reg®, const Operand& op) { opCnt(reg, op, 0xB8); } void popf() { db(0x9D); } void por(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xEB); } -void prefetchit0(const Address& addr) { opModM(addr, Reg32(7), T_0F, 0x18); } -void prefetchit1(const Address& addr) { opModM(addr, Reg32(6), T_0F, 0x18); } -void prefetchnta(const Address& addr) { opModM(addr, Reg32(0), T_0F, 0x18); } -void prefetcht0(const Address& addr) { opModM(addr, Reg32(1), T_0F, 0x18); } -void prefetcht1(const Address& addr) { opModM(addr, Reg32(2), T_0F, 0x18); } -void prefetcht2(const Address& addr) { opModM(addr, Reg32(3), T_0F, 0x18); } -void prefetchw(const Address& addr) { opModM(addr, Reg32(1), T_0F, 0x0D); } -void prefetchwt1(const Address& addr) { opModM(addr, Reg32(2), T_0F, 0x0D); } +void prefetchit0(const Address& addr) { opMR(addr, Reg32(7), T_0F, 0x18); } +void prefetchit1(const Address& addr) { opMR(addr, Reg32(6), T_0F, 0x18); } +void prefetchnta(const Address& addr) { opMR(addr, Reg32(0), T_0F, 0x18); } +void prefetcht0(const Address& addr) { opMR(addr, Reg32(1), T_0F, 0x18); } +void prefetcht1(const Address& addr) { opMR(addr, Reg32(2), T_0F, 0x18); } +void prefetcht2(const Address& addr) { opMR(addr, Reg32(3), T_0F, 0x18); } +void prefetchw(const Address& addr) { opMR(addr, Reg32(1), T_0F, 0x0D); } +void prefetchwt1(const Address& addr) { opMR(addr, Reg32(2), T_0F, 0x0D); } void psadbw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xF6); } void pshufb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x00, T_0F38, T_66); } void pshufd(const Mmx& mmx, const Operand& op, uint8_t imm8) { opMMX(mmx, op, 0x70, T_0F, T_66, imm8); } @@ -730,8 +730,8 @@ void rcr(const Operand& op, const Reg8& _cl) { opShift(op, _cl, 3); } void rcr(const Operand& op, int imm) { opShift(op, imm, 3); } 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) opModR(Reg(6, Operand::REG, r.getBit()), r, T_0F, 0xC7); } -void rdseed(const Reg& r) { if (r.isBit(8)) XBYAK_THROW(ERR_BAD_SIZE_OF_REGISTER) opModR(Reg(7, Operand::REG, r.getBit()), r, T_0F, 0xC7); } +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); } +void rdseed(const Reg& r) { if (r.isBit(8)) XBYAK_THROW(ERR_BAD_SIZE_OF_REGISTER) opRR(Reg(7, Operand::REG, r.getBit()), r, T_0F, 0xC7); } void rdtsc() { db(0x0F); db(0x31); } void rdtscp() { db(0x0F); db(0x01); db(0xF9); } void rep() { db(0xF3); } @@ -758,44 +758,44 @@ void sal(const Operand& op, int imm) { opShift(op, imm, 4); } void sar(const Operand& op, const Reg8& _cl) { opShift(op, _cl, 7); } void sar(const Operand& op, int imm) { opShift(op, imm, 7); } void sarx(const Reg32e& r1, const Operand& op, const Reg32e& r2) { opGpr(r1, op, r2, T_F3 | T_0F38, 0xf7, false); } -void sbb(const Operand& op, uint32_t imm) { opRM_I(op, imm, 0x18, 3); } -void sbb(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x18); } +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); } void sbb(const Reg& d, const Operand& op, uint32_t imm) { opROI(d, op, imm, 0, 3); } void sbb(const Reg& d, const Operand& op1, const Operand& op2) { opROO(d, op1, op2, 0, 0x18); } void scasb() { db(0xAE); } void scasd() { db(0xAF); } void scasw() { db(0x66); db(0xAF); } void serialize() { db(0x0F); db(0x01); db(0xE8); } -void seta(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 7); }//-V524 -void setae(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 3); }//-V524 -void setb(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 2); }//-V524 -void setbe(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 6); }//-V524 -void setc(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 2); }//-V524 -void sete(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 4); }//-V524 -void setg(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 15); }//-V524 -void setge(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 13); }//-V524 -void setl(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 12); }//-V524 -void setle(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 14); }//-V524 -void setna(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 6); }//-V524 -void setnae(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 2); }//-V524 -void setnb(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 3); }//-V524 -void setnbe(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 7); }//-V524 -void setnc(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 3); }//-V524 -void setne(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 5); }//-V524 -void setng(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 14); }//-V524 -void setnge(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 12); }//-V524 -void setnl(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 13); }//-V524 -void setnle(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 15); }//-V524 -void setno(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 1); }//-V524 -void setnp(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 11); }//-V524 -void setns(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 9); }//-V524 -void setnz(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 5); }//-V524 -void seto(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 0); }//-V524 -void setp(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 10); }//-V524 -void setpe(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 10); }//-V524 -void setpo(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 11); }//-V524 -void sets(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 8); }//-V524 -void setz(const Operand& op) { opR_ModM(op, 8, 0, T_0F, 0x90 | 4); }//-V524 +void seta(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 7); }//-V524 +void setae(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 3); }//-V524 +void setb(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 2); }//-V524 +void setbe(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 6); }//-V524 +void setc(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 2); }//-V524 +void sete(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 4); }//-V524 +void setg(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 15); }//-V524 +void setge(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 13); }//-V524 +void setl(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 12); }//-V524 +void setle(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 14); }//-V524 +void setna(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 6); }//-V524 +void setnae(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 2); }//-V524 +void setnb(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 3); }//-V524 +void setnbe(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 7); }//-V524 +void setnc(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 3); }//-V524 +void setne(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 5); }//-V524 +void setng(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 14); }//-V524 +void setnge(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 12); }//-V524 +void setnl(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 13); }//-V524 +void setnle(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 15); }//-V524 +void setno(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 1); }//-V524 +void setnp(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 11); }//-V524 +void setns(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 9); }//-V524 +void setnz(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 5); }//-V524 +void seto(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 0); }//-V524 +void setp(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 10); }//-V524 +void setpe(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 10); }//-V524 +void setpo(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 11); }//-V524 +void sets(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 8); }//-V524 +void setz(const Operand& op) { opRext(op, 8, 0, T_0F, 0x90 | 4); }//-V524 void sfence() { db(0x0F); db(0xAE); db(0xF8); } void sha1msg1(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F38, 0xC9, isXMM_XMMorMEM, NONE); } void sha1msg2(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F38, 0xCA, isXMM_XMMorMEM, NONE); } @@ -824,12 +824,12 @@ void stac() { db(0x0F); db(0x01); db(0xCB); } void stc() { db(0xF9); } void std() { db(0xFD); } void sti() { db(0xFB); } -void stmxcsr(const Address& addr) { opModM(addr, Reg32(3), T_0F, 0xAE); } +void stmxcsr(const Address& addr) { opMR(addr, Reg32(3), T_0F, 0xAE); } void stosb() { db(0xAA); } void stosd() { db(0xAB); } void stosw() { db(0x66); db(0xAB); } -void sub(const Operand& op, uint32_t imm) { opRM_I(op, imm, 0x28, 5); } -void sub(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x28); } +void sub(const Operand& op, uint32_t imm) { opOI(op, imm, 0x28, 5); } +void sub(const Operand& op1, const Operand& op2) { opRO_MR(op1, op2, 0x28); } void sub(const Reg& d, const Operand& op, uint32_t imm) { opROI(d, op, imm, 0, 5); } void sub(const Reg& d, const Operand& op1, const Operand& op2) { opROO(d, op1, op2, 0, 0x28); } void subpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F | T_66, 0x5C, isXMM_XMMorMEM); } @@ -1403,13 +1403,13 @@ void wait() { db(0x9B); } void wbinvd() { db(0x0F); db(0x09); } void wrmsr() { db(0x0F); db(0x30); } void xabort(uint8_t imm) { db(0xC6); db(0xF8); db(imm); } -void xadd(const Operand& op, const Reg& reg) { opModRM(reg, op, (op.isREG() && reg.isREG() && op.getBit() == reg.getBit()), op.isMEM(), T_0F, 0xC0 | (reg.isBit(8) ? 0 : 1)); } +void xadd(const Operand& op, const Reg& reg) { opRO(reg, op, (op.isREG() && reg.isREG() && op.getBit() == reg.getBit()), op.isMEM(), T_0F, 0xC0 | (reg.isBit(8) ? 0 : 1)); } void xbegin(uint32_t rel) { db(0xC7); db(0xF8); dd(rel); } void xend() { db(0x0F); db(0x01); db(0xD5); } void xgetbv() { db(0x0F); db(0x01); db(0xD0); } void xlatb() { db(0xD7); } -void xor_(const Operand& op, uint32_t imm) { opRM_I(op, imm, 0x30, 6); } -void xor_(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x30); } +void xor_(const Operand& op, uint32_t imm) { opOI(op, imm, 0x30, 6); } +void xor_(const Operand& op1, const Operand& op2) { opRO_MR(op1, op2, 0x30); } void xor_(const Reg& d, const Operand& op, uint32_t imm) { opROI(d, op, imm, 0, 6); } void xor_(const Reg& d, const Operand& op1, const Operand& op2) { opROO(d, op1, op2, 0, 0x30); } void xorpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, T_0F | T_66, 0x57, isXMM_XMMorMEM); } @@ -1692,14 +1692,14 @@ void clui() { db(0xF3); db(0x0F); db(0x01); db(0xEE); } void stui() { db(0xF3); db(0x0F); db(0x01); db(0xEF); } void testui() { db(0xF3); db(0x0F); db(0x01); db(0xED); } void uiret() { db(0xF3); db(0x0F); db(0x01); db(0xEC); } -void cmpxchg16b(const Address& addr) { opModM(addr, Reg64(1), T_0F, 0xC7); } -void fxrstor64(const Address& addr) { opModM(addr, Reg64(1), T_0F, 0xAE); } -void movq(const Reg64& reg, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opModR(mmx, reg, T_0F, 0x7E); } -void movq(const Mmx& mmx, const Reg64& reg) { if (mmx.isXMM()) db(0x66); opModR(mmx, reg, T_0F, 0x6E); } -void movsxd(const Reg64& reg, const Operand& op) { if (!op.isBit(32)) XBYAK_THROW(ERR_BAD_COMBINATION) opModRM(reg, op, op.isREG(), op.isMEM(), 0, 0x63); } +void cmpxchg16b(const Address& addr) { opMR(addr, Reg64(1), T_0F, 0xC7); } +void fxrstor64(const Address& addr) { opMR(addr, Reg64(1), T_0F, 0xAE); } +void movq(const Reg64& reg, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opRR(mmx, reg, T_0F, 0x7E); } +void movq(const Mmx& mmx, const Reg64& reg) { if (mmx.isXMM()) db(0x66); opRR(mmx, reg, T_0F, 0x6E); } +void movsxd(const Reg64& reg, const Operand& op) { if (!op.isBit(32)) XBYAK_THROW(ERR_BAD_COMBINATION) opRO(reg, op, op.isREG(), op.isMEM(), 0, 0x63); } void pextrq(const Operand& op, const Xmm& xmm, uint8_t imm) { if (!op.isREG(64) && !op.isMEM()) XBYAK_THROW(ERR_BAD_COMBINATION) opGen(Reg64(xmm.getIdx()), op, T_66 | T_0F3A, 0x16, 0, imm); } void pinsrq(const Xmm& xmm, const Operand& op, uint8_t imm) { if (!op.isREG(64) && !op.isMEM()) XBYAK_THROW(ERR_BAD_COMBINATION) opGen(Reg64(xmm.getIdx()), op, T_66 | T_0F3A, 0x22, 0, imm); } -void senduipi(const Reg64& r) { opModR(Reg32(6), r.cvt32(), T_F3 | T_0F, 0xC7); } +void senduipi(const Reg64& r) { opRR(Reg32(6), r.cvt32(), T_F3 | T_0F, 0xC7); } void vcvtss2si(const Reg64& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, T_0F | T_F3 | T_W1 | T_EVEX | T_EW1 | T_ER_X | T_N8, 0x2D); } void vcvttss2si(const Reg64& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, T_0F | T_F3 | T_W1 | T_EVEX | T_EW1 | T_SAE_X | T_N8, 0x2C); } void vcvtsd2si(const Reg64& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, T_0F | T_F2 | T_W1 | T_EVEX | T_EW1 | T_N4 | T_ER_X, 0x2D); }