mirror of
https://github.com/RPCSX/xbyak.git
synced 2024-12-03 08:40:58 +00:00
patch by whyisthisfieldhere
This commit is contained in:
parent
b2cc628b44
commit
28f2a1fa97
@ -1322,13 +1322,13 @@ private:
|
||||
db(code0 | (reg1.isBit(8) ? 0 : 1)); if (code1 != NONE) db(code1); if (code2 != NONE) db(code2);
|
||||
db(getModRM(3, reg1.getIdx(), reg2.getIdx()));
|
||||
}
|
||||
void opModM(const Address& addr, const Reg& reg, int code0, int code1 = NONE, int code2 = NONE)
|
||||
void opModM(const Address& addr, const Reg& reg, int code0, int code1 = NONE, int code2 = NONE, int endOffset = 0)
|
||||
{
|
||||
if (addr.is64bitDisp()) throw Error(ERR_CANT_USE_64BIT_DISP);
|
||||
rex(addr, reg);
|
||||
db(code0 | (reg.isBit(8) ? 0 : 1)); if (code1 != NONE) db(code1); if (code2 != NONE) db(code2);
|
||||
addr.updateRegField(static_cast<uint8>(reg.getIdx()));
|
||||
opAddr(addr);
|
||||
opAddr(addr, endOffset);
|
||||
}
|
||||
void makeJmp(uint32 disp, LabelType type, uint8 shortCode, uint8 longCode, uint8 longPref)
|
||||
{
|
||||
@ -1377,11 +1377,11 @@ private:
|
||||
}
|
||||
|
||||
}
|
||||
void opAddr(const Address &addr)
|
||||
void opAddr(const Address &addr, int endOffset = 0)
|
||||
{
|
||||
db(addr.getCode(), static_cast<int>(addr.getSize()));
|
||||
if (addr.getLabel()) { // [rip + Label]
|
||||
putL_inner(*addr.getLabel(), true, addr.getDisp());
|
||||
putL_inner(*addr.getLabel(), true, addr.getDisp() - endOffset);
|
||||
}
|
||||
}
|
||||
/* preCode is for SSSE3/SSE4 */
|
||||
@ -1390,7 +1390,7 @@ private:
|
||||
if (isValid && !isValid(reg, op)) throw Error(ERR_BAD_COMBINATION);
|
||||
if (pref != NONE) db(pref);
|
||||
if (op.isMEM()) {
|
||||
opModM(static_cast<const Address&>(op), static_cast<const Reg&>(reg), 0x0F, preCode, code);
|
||||
opModM(static_cast<const Address&>(op), static_cast<const Reg&>(reg), 0x0F, preCode, code, (imm8 != NONE) ? 1 : 0);
|
||||
} else {
|
||||
opModR(static_cast<const Reg&>(reg), static_cast<const Reg&>(op), 0x0F, preCode, code);
|
||||
}
|
||||
@ -1426,14 +1426,14 @@ private:
|
||||
opGen(mmx, op, code, 0x66, isXMM_REG32orMEM, imm, B00111010);
|
||||
}
|
||||
}
|
||||
void opR_ModM(const Operand& op, int bit, int ext, int code0, int code1 = NONE, int code2 = NONE, bool disableRex = false)
|
||||
void opR_ModM(const Operand& op, int bit, int ext, int code0, int code1 = NONE, int code2 = NONE, bool disableRex = false, int endOffset = 0)
|
||||
{
|
||||
int opBit = op.getBit();
|
||||
if (disableRex && opBit == 64) opBit = 32;
|
||||
if (op.isREG(bit)) {
|
||||
opModR(Reg(ext, Operand::REG, opBit), static_cast<const Reg&>(op).changeBit(opBit), code0, code1, code2);
|
||||
} else if (op.isMEM()) {
|
||||
opModM(static_cast<const Address&>(op), Reg(ext, Operand::REG, opBit), code0, code1, code2);
|
||||
opModM(static_cast<const Address&>(op), Reg(ext, Operand::REG, opBit), code0, code1, code2, endOffset);
|
||||
} else {
|
||||
throw Error(ERR_BAD_COMBINATION);
|
||||
}
|
||||
@ -1441,7 +1441,7 @@ private:
|
||||
void opShift(const Operand& op, int imm, int ext)
|
||||
{
|
||||
verifyMemHasSize(op);
|
||||
opR_ModM(op, 0, ext, (B11000000 | ((imm == 1 ? 1 : 0) << 4)));
|
||||
opR_ModM(op, 0, ext, (B11000000 | ((imm == 1 ? 1 : 0) << 4)), NONE, NONE, false, (imm != 1) ? 1 : 0);
|
||||
if (imm != 1) db(imm);
|
||||
}
|
||||
void opShift(const Operand& op, const Reg8& cl, int ext)
|
||||
@ -1449,12 +1449,12 @@ private:
|
||||
if (cl.getIdx() != Operand::CL) throw Error(ERR_BAD_COMBINATION);
|
||||
opR_ModM(op, 0, ext, B11010010);
|
||||
}
|
||||
void opModRM(const Operand& op1, const Operand& op2, bool condR, bool condM, int code0, int code1 = NONE, int code2 = NONE)
|
||||
void opModRM(const Operand& op1, const Operand& op2, bool condR, bool condM, int code0, int code1 = NONE, int code2 = NONE, int endOffset = 0)
|
||||
{
|
||||
if (condR) {
|
||||
opModR(static_cast<const Reg&>(op1), static_cast<const Reg&>(op2), code0, code1, code2);
|
||||
} else if (condM) {
|
||||
opModM(static_cast<const Address&>(op2), static_cast<const Reg&>(op1), code0, code1, code2);
|
||||
opModM(static_cast<const Address&>(op2), static_cast<const Reg&>(op1), code0, code1, code2, endOffset);
|
||||
} else {
|
||||
throw Error(ERR_BAD_COMBINATION);
|
||||
}
|
||||
@ -1462,7 +1462,7 @@ private:
|
||||
void opShxd(const Operand& op, const Reg& reg, uint8 imm, int code, const Reg8 *cl = 0)
|
||||
{
|
||||
if (cl && cl->getIdx() != Operand::CL) throw Error(ERR_BAD_COMBINATION);
|
||||
opModRM(reg, op, (op.isREG(16 | i32e) && op.getBit() == reg.getBit()), op.isMEM() && (reg.isREG(16 | i32e)), 0x0F, code | (cl ? 1 : 0));
|
||||
opModRM(reg, op, (op.isREG(16 | i32e) && op.getBit() == reg.getBit()), op.isMEM() && (reg.isREG(16 | i32e)), 0x0F, code | (cl ? 1 : 0), NONE, cl ? 0 : 1);
|
||||
if (!cl) db(imm);
|
||||
}
|
||||
// (REG, REG|MEM), (MEM, REG)
|
||||
@ -1487,7 +1487,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, B10000000 | tmp);
|
||||
opR_ModM(op, 0, ext, B10000000 | tmp, NONE, NONE, false, immBit / 8);
|
||||
}
|
||||
db(imm, immBit / 8);
|
||||
}
|
||||
@ -1558,7 +1558,7 @@ private:
|
||||
{
|
||||
db(code1); db(code2 | reg.getIdx());
|
||||
}
|
||||
void opVex(const Reg& r, const Operand *p1, const Operand *p2, int type, int code, int w)
|
||||
void opVex(const Reg& r, const Operand *p1, const Operand *p2, int type, int code, int w, int imm8 = NONE)
|
||||
{
|
||||
bool x, b;
|
||||
if (p2->isMEM()) {
|
||||
@ -1578,14 +1578,15 @@ private:
|
||||
if (p2->isMEM()) {
|
||||
const Address& addr = static_cast<const Address&>(*p2);
|
||||
addr.updateRegField(static_cast<uint8>(r.getIdx()));
|
||||
opAddr(addr);
|
||||
opAddr(addr, (imm8 != NONE) ? 1 : 0);
|
||||
} else {
|
||||
db(getModRM(3, r.getIdx(), p2->getIdx()));
|
||||
}
|
||||
if (imm8 != NONE) db(imm8);
|
||||
}
|
||||
// (r, r, r/m) if isR_R_RM
|
||||
// (r, r/m, r)
|
||||
void opGpr(const Reg32e& r, const Operand& op1, const Operand& op2, int type, uint8 code, bool isR_R_RM)
|
||||
void opGpr(const Reg32e& r, const Operand& op1, const Operand& op2, int type, uint8 code, bool isR_R_RM, int imm8 = NONE)
|
||||
{
|
||||
const Operand *p1 = &op1;
|
||||
const Operand *p2 = &op2;
|
||||
@ -1593,9 +1594,9 @@ private:
|
||||
const unsigned int bit = r.getBit();
|
||||
if (p1->getBit() != bit || (p2->isREG() && p2->getBit() != bit)) throw Error(ERR_BAD_COMBINATION);
|
||||
int w = bit == 64;
|
||||
opVex(r, p1, p2, type, code, w);
|
||||
opVex(r, p1, p2, type, code, w, imm8);
|
||||
}
|
||||
void opAVX_X_X_XM(const Xmm& x1, const Operand& op1, const Operand& op2, int type, int code0, bool supportYMM, int w = -1)
|
||||
void opAVX_X_X_XM(const Xmm& x1, const Operand& op1, const Operand& op2, int type, int code0, bool supportYMM, int w = -1, int imm8 = NONE)
|
||||
{
|
||||
const Xmm *x2;
|
||||
const Operand *op;
|
||||
@ -1609,18 +1610,18 @@ private:
|
||||
}
|
||||
// (x1, x2, op)
|
||||
if (!((x1.isXMM() && x2->isXMM()) || (supportYMM && x1.isYMM() && x2->isYMM()))) throw Error(ERR_BAD_COMBINATION);
|
||||
opVex(x1, x2, op, type, code0, w);
|
||||
opVex(x1, x2, op, type, code0, w, imm8);
|
||||
}
|
||||
// if cvt then return pointer to Xmm(idx) (or Ymm(idx)), otherwise return op
|
||||
void opAVX_X_X_XMcvt(const Xmm& x1, const Operand& op1, const Operand& op2, bool cvt, Operand::Kind kind, int type, int code0, bool supportYMM, int w = -1)
|
||||
void opAVX_X_X_XMcvt(const Xmm& x1, const Operand& op1, const Operand& op2, bool cvt, Operand::Kind kind, int type, int code0, bool supportYMM, int w = -1, int imm8 = NONE)
|
||||
{
|
||||
// use static_cast to avoid calling unintentional copy constructor on gcc
|
||||
opAVX_X_X_XM(x1, op1, cvt ? kind == Operand::XMM ? static_cast<const Operand&>(Xmm(op2.getIdx())) : static_cast<const Operand&>(Ymm(op2.getIdx())) : op2, type, code0, supportYMM, w);
|
||||
opAVX_X_X_XM(x1, op1, cvt ? kind == Operand::XMM ? static_cast<const Operand&>(Xmm(op2.getIdx())) : static_cast<const Operand&>(Ymm(op2.getIdx())) : op2, type, code0, supportYMM, w, imm8);
|
||||
}
|
||||
// support (x, x/m, imm), (y, y/m, imm)
|
||||
void opAVX_X_XM_IMM(const Xmm& x, const Operand& op, int type, int code, bool supportYMM, int w = -1, int imm = NONE)
|
||||
void opAVX_X_XM_IMM (const Xmm& x, const Operand& op, int type, int code, bool supportYMM, int w = -1, int imm8 = NONE)
|
||||
{
|
||||
opAVX_X_X_XM(x, x.isXMM() ? xm0 : ym0, op, type, code, supportYMM, w); if (imm != NONE) db((uint8)imm);
|
||||
opAVX_X_X_XM(x, x.isXMM() ? xm0 : ym0, op, type, code, supportYMM, w, imm8);
|
||||
}
|
||||
// QQQ:need to refactor
|
||||
void opSp1(const Reg& reg, const Operand& op, uint8 pref, uint8 code0, uint8 code1)
|
||||
@ -1719,13 +1720,14 @@ public:
|
||||
void test(const Operand& op, uint32 imm)
|
||||
{
|
||||
verifyMemHasSize(op);
|
||||
int immSize = (std::min)(op.getBit() / 8, 4U);
|
||||
if (op.isREG() && op.getIdx() == 0) { // al, ax, eax
|
||||
rex(op);
|
||||
db(B10101000 | (op.isBit(8) ? 0 : 1));
|
||||
} else {
|
||||
opR_ModM(op, 0, 0, B11110110);
|
||||
opR_ModM(op, 0, 0, B11110110, NONE, NONE, false, immSize);
|
||||
}
|
||||
db(imm, (std::min)(op.getBit() / 8, 4U));
|
||||
db(imm, immSize);
|
||||
}
|
||||
void ret(int imm = 0)
|
||||
{
|
||||
@ -1743,8 +1745,8 @@ public:
|
||||
void imul(const Reg& reg, const Operand& op, int imm)
|
||||
{
|
||||
int s = inner::IsInDisp8(imm) ? 1 : 0;
|
||||
opModRM(reg, op, op.isREG() && (reg.getKind() == op.getKind()), op.isMEM(), B01101001 | (s << 1));
|
||||
int size = s ? 1 : reg.isREG(16) ? 2 : 4;
|
||||
int size = s ? 1 : reg.isREG(16) ? 2 : 4;
|
||||
opModRM(reg, op, op.isREG() && (reg.getKind() == op.getKind()), op.isMEM(), B01101001 | (s << 1), NONE, NONE, size);
|
||||
db(imm, size);
|
||||
}
|
||||
void pop(const Operand& op)
|
||||
@ -2055,7 +2057,7 @@ public:
|
||||
}
|
||||
void rdrand(const Reg& r) { if (r.isBit(8)) throw Error(ERR_BAD_SIZE_OF_REGISTER); opModR(Reg(6, Operand::REG, r.getBit()), r, 0x0f, 0xc7); }
|
||||
void rdseed(const Reg& r) { if (r.isBit(8)) throw Error(ERR_BAD_SIZE_OF_REGISTER); opModR(Reg(7, Operand::REG, r.getBit()), r, 0x0f, 0xc7); }
|
||||
void rorx(const Reg32e& r, const Operand& op, uint8 imm) { opGpr(r, op, Reg32e(0, r.getBit()), MM_0F3A | PP_F2, 0xF0, false); db(imm); }
|
||||
void rorx(const Reg32e& r, const Operand& op, uint8 imm) { opGpr(r, op, Reg32e(0, r.getBit()), MM_0F3A | PP_F2, 0xF0, false, imm); }
|
||||
enum { NONE = 256 };
|
||||
CodeGenerator(size_t maxSize = DEFAULT_MAX_CODE_SIZE, void *userPtr = 0, Allocator *allocator = 0)
|
||||
: CodeArray(maxSize, userPtr, allocator)
|
||||
|
Loading…
Reference in New Issue
Block a user