add 3-op shift

This commit is contained in:
MITSUNARI Shigeo 2023-11-22 08:52:14 +09:00
parent 426814c506
commit 5e54ffdfaf
3 changed files with 29 additions and 9 deletions

View file

@ -914,6 +914,8 @@ void put()
const Tbl *p = &tbl[i]; 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, 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 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);
} }
} }
{ {

View file

@ -2198,12 +2198,12 @@ private:
} }
return true; 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(); int opBit = op.getBit();
if (disableRex && opBit == 64) opBit = 32; if (disableRex && opBit == 64) opBit = 32;
const Reg r(ext, Operand::REG, opBit); 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()) { if (op.isMEM()) {
opMR(op.getAddress(), r, type, code, immSize); opMR(op.getAddress(), r, type, code, immSize);
} else if (op.isREG(bit)) { } else if (op.isREG(bit)) {
@ -2212,18 +2212,20 @@ private:
XBYAK_THROW(ERR_BAD_COMBINATION) 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); if (d == 0) verifyMemHasSize(op);
uint64_t type = T_VEX|T_CODE1_IF1; if (ext & 8) type |= T_NF; if (d && op.getBit() != 0 && d->getBit() != op.getBit()) XBYAK_THROW(ERR_BAD_SIZE_OF_REGISTER)
opRext(op, 0, ext&7, type, (0xC0 | ((imm == 1 ? 1 : 0) << 4)), false, (imm != 1) ? 1 : 0); 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); 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) if (_cl.getIdx() != Operand::CL) XBYAK_THROW(ERR_BAD_COMBINATION)
uint64_t type = T_VEX|T_CODE1_IF1; if (ext & 8) type |= T_NF; if (d && op.getBit() != 0 && d->getBit() != op.getBit()) XBYAK_THROW(ERR_BAD_SIZE_OF_REGISTER)
opRext(op, 0, ext&7, type, 0xD2); 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 // 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) void opRO(const Reg& r, const Operand& op, uint64_t type, int code, bool condR = true, int immSize = 0)

View file

@ -729,10 +729,14 @@ void pushf() { db(0x9C); }
void pxor(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xEF); } 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, const Reg8& _cl) { opShift(op, _cl, 2); }
void rcl(const Operand& op, int imm) { opShift(op, imm, 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 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 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, const Reg8& _cl) { opShift(op, _cl, 3); }
void rcr(const Operand& op, int imm) { opShift(op, imm, 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 rdmsr() { db(0x0F); db(0x32); }
void rdpmc() { db(0x0F); db(0x33); } 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); } 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 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, const Reg8& _cl) { opShift(op, _cl, 8); }
void rol(const Operand& op, int imm) { opShift(op, imm, 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, const Reg8& _cl) { opShift(op, _cl, 9); }
void ror(const Operand& op, int imm) { opShift(op, imm, 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 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 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); } 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 sahf() { db(0x9E); }
void sal(const Operand& op, const Reg8& _cl) { opShift(op, _cl, 12); } 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 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, const Reg8& _cl) { opShift(op, _cl, 15); }
void sar(const Operand& op, int imm) { opShift(op, imm, 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 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& 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 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 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, const Reg8& _cl) { opShift(op, _cl, 12); }
void shl(const Operand& op, int imm) { opShift(op, imm, 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, 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 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); } 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 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, const Reg8& _cl) { opShift(op, _cl, 13); }
void shr(const Operand& op, int imm) { opShift(op, imm, 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, 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 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); } void shrd(const Reg& d, const Operand& op, const Reg& reg, const Reg8& _cl) { opShxd(d, op, reg, 0, 0xAC, 0x2C, &_cl); }