mirror of
https://github.com/herumi/xbyak
synced 2024-11-21 16:09:11 -07:00
fix mpx encoding
This commit is contained in:
parent
d0b2fb623e
commit
e4fc9d8a92
8 changed files with 108 additions and 50 deletions
|
@ -942,11 +942,11 @@ void put()
|
|||
puts("void bndcl(const BoundsReg& bnd, const Operand& op) { db(0xF3); opR_ModM(op, i32e, bnd.getIdx(), 0x0F, 0x1A, NONE, !op.isMEM()); }");
|
||||
puts("void bndcu(const BoundsReg& bnd, const Operand& op) { db(0xF2); opR_ModM(op, i32e, bnd.getIdx(), 0x0F, 0x1A, NONE, !op.isMEM()); }");
|
||||
puts("void bndcn(const BoundsReg& bnd, const Operand& op) { db(0xF2); opR_ModM(op, i32e, bnd.getIdx(), 0x0F, 0x1B, NONE, !op.isMEM()); }");
|
||||
puts("void bndldx(const BoundsReg& bnd, const Address& addr) { opModM(addr, bnd, 0x0F, 0x1A); }");
|
||||
puts("void bndldx(const BoundsReg& bnd, const Address& addr) { opMIB(addr, bnd, 0x0F, 0x1A); }");
|
||||
puts("void bndmk(const BoundsReg& bnd, const Address& addr) { db(0xF3); opModM(addr, bnd, 0x0F, 0x1B); }");
|
||||
puts("void bndmov(const BoundsReg& bnd, const Operand& op) { db(0x66); opModRM(bnd, op, op.isBNDREG(), op.isMEM(), 0x0F, 0x1A); }");
|
||||
puts("void bndmov(const Address& addr, const BoundsReg& bnd) { db(0x66); opModM(addr, bnd, 0x0F, 0x1B); }");
|
||||
puts("void bndstx(const Address& addr, const BoundsReg& bnd) { opModM(addr, bnd, 0x0F, 0x1B); }");
|
||||
puts("void bndstx(const Address& addr, const BoundsReg& bnd) { opMIB(addr, bnd, 0x0F, 0x1B); }");
|
||||
}
|
||||
// misc
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
Xbyak 5.52 ; JIT assembler for x86(IA32), x64(AMD64, x86-64) by C++
|
||||
Xbyak 5.53 ; JIT assembler for x86(IA32), x64(AMD64, x86-64) by C++
|
||||
=============
|
||||
|
||||
Abstract
|
||||
|
@ -333,6 +333,7 @@ The header files under xbyak/ are independent of cybozulib.
|
|||
|
||||
History
|
||||
-------------
|
||||
* 2017/Aug/22 ver 5.53 fix mpx encoding, add bnd() prefix
|
||||
* 2017/Aug/18 ver 5.52 fix align (thanks to MerryMage)
|
||||
* 2017/Aug/17 ver 5.51 add multi-byte nop and align() uses it(thanks to inolen)
|
||||
* 2017/Aug/08 ver 5.50 add mpx(thanks to magurosan)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak 5.52
|
||||
C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak 5.53
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
◎概要
|
||||
|
@ -343,6 +343,7 @@ cybozulibは単体テストでのみ利用されていて、xbyak/ディレク
|
|||
-----------------------------------------------------------------------------
|
||||
◎履歴
|
||||
|
||||
2017/08/22 ver 5.53 mpxエンコーディングバグ修正, bnd()プレフィクス追加
|
||||
2017/08/18 ver 5.52 align修正(thanks to MerryMage)
|
||||
2017/08/17 ver 5.51 multi-byte nop追加 align()はそれを使用する(thanks to inolen)
|
||||
2017/08/08 ver 5.50 mpx追加(thanks to magurosan)
|
||||
|
|
|
@ -1363,6 +1363,22 @@ class Test {
|
|||
put("bndmk", BNDREG, MEM);
|
||||
put("bndmov", BNDREG, BNDREG|MEM);
|
||||
put("bndstx", MEM, BNDREG);
|
||||
put("bndstx", "ptr [eax]", "[eax]", BNDREG);
|
||||
put("bndstx", "ptr [eax+5]", "[eax+5]", BNDREG);
|
||||
put("bndstx", "ptr [eax+500]", "[eax+500]", BNDREG);
|
||||
put("bndstx", "ptr [eax+ecx]", "[eax+ecx]", BNDREG);
|
||||
put("bndstx", "ptr [ecx+eax]", "[ecx+eax]", BNDREG);
|
||||
put("bndstx", "ptr [eax+esp]", "[eax+esp]", BNDREG);
|
||||
put("bndstx", "ptr [esp+eax]", "[esp+eax]", BNDREG);
|
||||
put("bndstx", "ptr [eax+ecx*2]", "[eax+ecx*2]", BNDREG);
|
||||
put("bndstx", "ptr [ecx+ecx]", "[ecx+ecx]", BNDREG);
|
||||
put("bndstx", "ptr [ecx*2]", "[ecx*2]", BNDREG);
|
||||
put("bndstx", "ptr [eax+ecx*2+500]", "[eax+ecx*2+500]", BNDREG);
|
||||
#ifdef XBYAK64
|
||||
put("bndstx", "ptr [rax+rcx*2]", "[rax+rcx*2]", BNDREG);
|
||||
put("bndstx", "ptr [r9*2]", "[r9*2]", BNDREG);
|
||||
put("bndstx", "ptr [r9*2+r15]", "[r9*2+r15]", BNDREG);
|
||||
#endif
|
||||
}
|
||||
void putFpuMem16_32() const
|
||||
{
|
||||
|
|
|
@ -6,6 +6,7 @@ using namespace Xbyak;
|
|||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4245)
|
||||
#pragma warning(disable : 4312)
|
||||
#endif
|
||||
class Sample : public CodeGenerator {
|
||||
void operator=(const Sample&);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
@echo off
|
||||
set FILTER=cat
|
||||
set FILTER=grep -v warning
|
||||
if /i "%1"=="64" (
|
||||
set OPT2=-DXBYAK64
|
||||
set OPT3=win64
|
||||
|
|
123
xbyak/xbyak.h
123
xbyak/xbyak.h
|
@ -105,7 +105,7 @@ namespace Xbyak {
|
|||
|
||||
enum {
|
||||
DEFAULT_MAX_CODE_SIZE = 4096,
|
||||
VERSION = 0x5520 /* 0xABCD = A.BC(D) */
|
||||
VERSION = 0x5530 /* 0xABCD = A.BC(D) */
|
||||
};
|
||||
|
||||
#ifndef MIE_INTEGER_TYPE_DEFINED
|
||||
|
@ -177,6 +177,7 @@ enum {
|
|||
ERR_INVALID_OPMASK_WITH_MEMORY,
|
||||
ERR_INVALID_ZERO,
|
||||
ERR_INVALID_RIP_IN_AUTO_GROW,
|
||||
ERR_INVALID_MIB_ADDRESS,
|
||||
ERR_INTERNAL
|
||||
};
|
||||
|
||||
|
@ -237,6 +238,7 @@ public:
|
|||
"invalid opmask with memory",
|
||||
"invalid zero",
|
||||
"invalid rip in AutoGrow",
|
||||
"invalid mib address",
|
||||
"internal error",
|
||||
};
|
||||
assert((size_t)err_ < sizeof(errTbl) / sizeof(*errTbl));
|
||||
|
@ -345,6 +347,9 @@ public:
|
|||
};
|
||||
#endif
|
||||
|
||||
class Address;
|
||||
class Reg;
|
||||
|
||||
class Operand {
|
||||
static const uint8 EXT8BIT = 0x20;
|
||||
unsigned int idx_:6; // 0..31 + EXT8BIT = 1 if spl/bpl/sil/dil
|
||||
|
@ -497,6 +502,8 @@ public:
|
|||
bool isEqualIfNotInherited(const Operand& rhs) const { return idx_ == rhs.idx_ && kind_ == rhs.kind_ && bit_ == rhs.bit_ && zero_ == rhs.zero_ && mask_ == rhs.mask_ && rounding_ == rhs.rounding_; }
|
||||
bool operator==(const Operand& rhs) const;
|
||||
bool operator!=(const Operand& rhs) const { return !operator==(rhs); }
|
||||
const Address& getAddress() const;
|
||||
const Reg& getReg() const;
|
||||
};
|
||||
|
||||
class Label;
|
||||
|
@ -530,6 +537,12 @@ public:
|
|||
#endif
|
||||
};
|
||||
|
||||
inline const Reg& Operand::getReg() const
|
||||
{
|
||||
assert(!isMEM());
|
||||
return static_cast<const Reg&>(*this);
|
||||
}
|
||||
|
||||
struct Reg8 : public Reg {
|
||||
explicit Reg8(int idx = 0, bool ext8bit = false) : Reg(idx, Operand::REG, 8, ext8bit) { }
|
||||
};
|
||||
|
@ -689,13 +702,15 @@ public:
|
|||
}
|
||||
}
|
||||
bool isVsib(int bit = 128 | 256 | 512) const { return index_.isBit(bit); }
|
||||
void optimize()
|
||||
RegExp optimize() const
|
||||
{
|
||||
RegExp exp = *this;
|
||||
// [reg * 2] => [reg + reg]
|
||||
if (index_.isBit(i32e) && !base_.getBit() && index_.getBit() && scale_ == 2) {
|
||||
base_ = index_;
|
||||
scale_ = 1;
|
||||
if (index_.isBit(i32e) && !base_.getBit() && scale_ == 2) {
|
||||
exp.base_ = index_;
|
||||
exp.scale_ = 1;
|
||||
}
|
||||
return exp;
|
||||
}
|
||||
bool operator==(const RegExp& rhs) const
|
||||
{
|
||||
|
@ -715,6 +730,11 @@ public:
|
|||
}
|
||||
friend RegExp operator+(const RegExp& a, const RegExp& b);
|
||||
friend RegExp operator-(const RegExp& e, size_t disp);
|
||||
uint8 getRex() const
|
||||
{
|
||||
uint8 rex = index_.getRexX() | base_.getRexB();
|
||||
return rex ? uint8(rex | 0x40) : 0;
|
||||
}
|
||||
private:
|
||||
/*
|
||||
[base_ + index_ * scale_ + disp_]
|
||||
|
@ -975,7 +995,6 @@ public:
|
|||
: Operand(0, MEM, sizeBit), e_(e), label_(0), mode_(M_ModRM), permitVsib_(false), broadcast_(broadcast)
|
||||
{
|
||||
e_.verify();
|
||||
e_.optimize();
|
||||
}
|
||||
#ifdef XBYAK64
|
||||
explicit Address(size_t disp)
|
||||
|
@ -984,7 +1003,10 @@ public:
|
|||
: Operand(0, MEM, sizeBit), e_(addr.disp_), label_(addr.label_), mode_(addr.isAddr_ ? M_ripAddr : M_rip), permitVsib_(false), broadcast_(broadcast) { }
|
||||
#endif
|
||||
void permitVsib() const { permitVsib_ = true; }
|
||||
const RegExp& getRegExp() const { return e_; }
|
||||
RegExp getRegExp(bool optimize = true) const
|
||||
{
|
||||
return optimize ? e_.optimize() : e_;
|
||||
}
|
||||
Mode getMode() const { return mode_; }
|
||||
bool is32bit() const { verify(); return e_.getBase().getBit() == 32 || e_.getIndex().getBit() == 32; }
|
||||
bool isOnlyDisp() const { verify(); return !e_.getBase().getBit() && !e_.getIndex().getBit(); } // for mov eax
|
||||
|
@ -993,9 +1015,7 @@ public:
|
|||
{
|
||||
verify();
|
||||
if (mode_ != M_ModRM) return 0;
|
||||
uint8 rex = e_.getIndex().getRexX() | e_.getBase().getRexB();
|
||||
if (rex) rex |= 0x40;
|
||||
return rex;
|
||||
return getRegExp().getRex();
|
||||
}
|
||||
bool is64bitDisp() const { verify(); return mode_ == M_64bitDisp; } // for moffset
|
||||
bool isBroadcast() const { return broadcast_; }
|
||||
|
@ -1014,9 +1034,15 @@ private:
|
|||
void verify() const { if (e_.isVsib() && !permitVsib_) throw Error(ERR_BAD_VSIB_ADDRESSING); }
|
||||
};
|
||||
|
||||
inline const Address& Operand::getAddress() const
|
||||
{
|
||||
assert(isMEM());
|
||||
return static_cast<const Address&>(*this);
|
||||
}
|
||||
|
||||
inline bool Operand::operator==(const Operand& rhs) const
|
||||
{
|
||||
if (isMEM() && rhs.isMEM()) return static_cast<const Address&>(*this) == static_cast<const Address&>(rhs);
|
||||
if (isMEM() && rhs.isMEM()) return this->getAddress() == rhs.getAddress();
|
||||
return isEqualIfNotInherited(rhs);
|
||||
}
|
||||
|
||||
|
@ -1363,12 +1389,12 @@ private:
|
|||
if (p1->isMEM()) std::swap(p1, p2);
|
||||
if (p1->isMEM()) throw Error(ERR_BAD_COMBINATION);
|
||||
if (p2->isMEM()) {
|
||||
const Address& addr = static_cast<const Address&>(*p2);
|
||||
const Address& addr = p2->getAddress();
|
||||
if (BIT == 64 && addr.is32bit()) db(0x67);
|
||||
rex = addr.getRex() | static_cast<const Reg&>(*p1).getRex();
|
||||
rex = addr.getRex() | p1->getReg().getRex();
|
||||
} else {
|
||||
// ModRM(reg, base);
|
||||
rex = static_cast<const Reg&>(op2).getRex(static_cast<const Reg&>(op1));
|
||||
rex = op2.getReg().getRex(op1.getReg());
|
||||
}
|
||||
// except movsx(16bit, 32/64bit)
|
||||
if ((op1.isBit(16) && !op2.isBit(i32e)) || (op2.isBit(16) && !op1.isBit(i32e))) db(0x66);
|
||||
|
@ -1581,6 +1607,17 @@ private:
|
|||
db(code0 | (reg.isBit(8) ? 0 : 1)); if (code1 != NONE) db(code1); if (code2 != NONE) db(code2);
|
||||
opAddr(addr, reg.getIdx(), immSize);
|
||||
}
|
||||
void opMIB(const Address& addr, const Reg& reg, int code0, int code1)
|
||||
{
|
||||
if (addr.is64bitDisp()) throw Error(ERR_CANT_USE_64BIT_DISP);
|
||||
if (addr.getMode() != Address::M_ModRM) throw Error(ERR_INVALID_MIB_ADDRESS);
|
||||
if (BIT == 64 && addr.is32bit()) db(0x67);
|
||||
const RegExp& regExp = addr.getRegExp(false);
|
||||
uint8 rex = regExp.getRex();
|
||||
if (rex) db(rex);
|
||||
db(code0); db(code1);
|
||||
setSIB(regExp, reg.getIdx());
|
||||
}
|
||||
void makeJmp(uint32 disp, LabelType type, uint8 shortCode, uint8 longCode, uint8 longPref)
|
||||
{
|
||||
const int shortJmpSize = 2;
|
||||
|
@ -1656,9 +1693,9 @@ 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, (imm8 != NONE) ? 1 : 0);
|
||||
opModM(op.getAddress(), reg.getReg(), 0x0F, preCode, code, (imm8 != NONE) ? 1 : 0);
|
||||
} else {
|
||||
opModR(static_cast<const Reg&>(reg), static_cast<const Reg&>(op), 0x0F, preCode, code);
|
||||
opModR(reg.getReg(), op.getReg(), 0x0F, preCode, code);
|
||||
}
|
||||
if (imm8 != NONE) db(imm8);
|
||||
}
|
||||
|
@ -1676,9 +1713,9 @@ private:
|
|||
{
|
||||
if (pref != NONE) db(pref);
|
||||
if (op1.isXMM() && op2.isMEM()) {
|
||||
opModM(static_cast<const Address&>(op2), static_cast<const Reg&>(op1), 0x0F, code);
|
||||
opModM(op2.getAddress(), op1.getReg(), 0x0F, code);
|
||||
} else if (op1.isMEM() && op2.isXMM()) {
|
||||
opModM(static_cast<const Address&>(op1), static_cast<const Reg&>(op2), 0x0F, code | 1);
|
||||
opModM(op1.getAddress(), op2.getReg(), 0x0F, code | 1);
|
||||
} else {
|
||||
throw Error(ERR_BAD_COMBINATION);
|
||||
}
|
||||
|
@ -1687,7 +1724,7 @@ private:
|
|||
{
|
||||
if (hasMMX2 && op.isREG(i32e)) { /* pextrw is special */
|
||||
if (mmx.isXMM()) db(0x66);
|
||||
opModR(static_cast<const Reg&>(op), mmx, 0x0F, 0xC5); db(imm);
|
||||
opModR(op.getReg(), mmx, 0x0F, 0xC5); db(imm);
|
||||
} else {
|
||||
opGen(mmx, op, code, 0x66, isXMM_REG32orMEM, imm, 0x3A);
|
||||
}
|
||||
|
@ -1697,9 +1734,9 @@ private:
|
|||
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);
|
||||
opModR(Reg(ext, Operand::REG, opBit), op.getReg().changeBit(opBit), code0, code1, code2);
|
||||
} else if (op.isMEM()) {
|
||||
opModM(static_cast<const Address&>(op), Reg(ext, Operand::REG, opBit), code0, code1, code2, immSize);
|
||||
opModM(op.getAddress(), Reg(ext, Operand::REG, opBit), code0, code1, code2, immSize);
|
||||
} else {
|
||||
throw Error(ERR_BAD_COMBINATION);
|
||||
}
|
||||
|
@ -1718,9 +1755,9 @@ private:
|
|||
void opModRM(const Operand& op1, const Operand& op2, bool condR, bool condM, int code0, int code1 = NONE, int code2 = NONE, int immSize = 0)
|
||||
{
|
||||
if (condR) {
|
||||
opModR(static_cast<const Reg&>(op1), static_cast<const Reg&>(op2), code0, code1, code2);
|
||||
opModR(op1.getReg(), op2.getReg(), code0, code1, code2);
|
||||
} else if (condM) {
|
||||
opModM(static_cast<const Address&>(op2), static_cast<const Reg&>(op1), code0, code1, code2, immSize);
|
||||
opModM(op2.getAddress(), op1.getReg(), code0, code1, code2, immSize);
|
||||
} else {
|
||||
throw Error(ERR_BAD_COMBINATION);
|
||||
}
|
||||
|
@ -1735,7 +1772,7 @@ private:
|
|||
void opRM_RM(const Operand& op1, const Operand& op2, int code)
|
||||
{
|
||||
if (op1.isREG() && op2.isMEM()) {
|
||||
opModM(static_cast<const Address&>(op2), static_cast<const Reg&>(op1), code | 2);
|
||||
opModM(op2.getAddress(), op1.getReg(), code | 2);
|
||||
} else {
|
||||
opModRM(op2, op1, op1.isREG() && op1.getKind() == op2.getKind(), op1.isMEM() && op2.isREG(), code);
|
||||
}
|
||||
|
@ -1768,19 +1805,19 @@ private:
|
|||
#endif
|
||||
code = 0xFE;
|
||||
if (op.isREG()) {
|
||||
opModR(Reg(ext, Operand::REG, op.getBit()), static_cast<const Reg&>(op), code);
|
||||
opModR(Reg(ext, Operand::REG, op.getBit()), op.getReg(), code);
|
||||
} else {
|
||||
opModM(static_cast<const Address&>(op), Reg(ext, Operand::REG, op.getBit()), code);
|
||||
opModM(op.getAddress(), Reg(ext, Operand::REG, op.getBit()), code);
|
||||
}
|
||||
}
|
||||
void opPushPop(const Operand& op, int code, int ext, int alt)
|
||||
{
|
||||
if (op.isREG()) {
|
||||
if (op.isBit(16)) db(0x66);
|
||||
if (static_cast<const Reg&>(op).getIdx() >= 8) db(0x41);
|
||||
if (op.getReg().getIdx() >= 8) db(0x41);
|
||||
db(alt | (op.getIdx() & 7));
|
||||
} else if (op.isMEM()) {
|
||||
opModM(static_cast<const Address&>(op), Reg(ext, Operand::REG, op.getBit()), code);
|
||||
opModM(op.getAddress(), Reg(ext, Operand::REG, op.getBit()), code);
|
||||
} else {
|
||||
throw Error(ERR_BAD_COMBINATION);
|
||||
}
|
||||
|
@ -1869,11 +1906,12 @@ private:
|
|||
void opVex(const Reg& r, const Operand *p1, const Operand& op2, int type, int code, int imm8 = NONE)
|
||||
{
|
||||
if (op2.isMEM()) {
|
||||
const Address& addr = static_cast<const Address&>(op2);
|
||||
const Reg& base = addr.getRegExp().getBase();
|
||||
const Address& addr = op2.getAddress();
|
||||
const RegExp& regExp = addr.getRegExp();
|
||||
const Reg& base = regExp.getBase();
|
||||
if (BIT == 64 && addr.is32bit()) db(0x67);
|
||||
int disp8N = 0;
|
||||
bool x = addr.getRegExp().getIndex().isExtIdx();
|
||||
bool x = regExp.getIndex().isExtIdx();
|
||||
if ((type & T_MUST_EVEX) || r.hasEvex() || (p1 && p1->hasEvex()) || addr.isBroadcast() || addr.getOpmaskIdx()) {
|
||||
int aaa = addr.getOpmaskIdx();
|
||||
if (aaa && !(type & T_M_K)) throw Error(ERR_INVALID_OPMASK_WITH_MEMORY);
|
||||
|
@ -1882,14 +1920,14 @@ private:
|
|||
if (!(type & (T_B32 | T_B64))) throw Error(ERR_INVALID_BROADCAST);
|
||||
b = true;
|
||||
}
|
||||
int VL = addr.getRegExp().isVsib() ? addr.getRegExp().getIndex().getBit() : 0;
|
||||
int VL = regExp.isVsib() ? regExp.getIndex().getBit() : 0;
|
||||
disp8N = evex(r, base, p1, type, code, x, b, aaa, VL);
|
||||
} else {
|
||||
vex(r, base, p1, type, code, x);
|
||||
}
|
||||
opAddr(addr, r.getIdx(), (imm8 != NONE) ? 1 : 0, disp8N);
|
||||
} else {
|
||||
const Reg& base = static_cast<const Reg&>(op2);
|
||||
const Reg& base = op2.getReg();
|
||||
if ((type & T_MUST_EVEX) || r.hasEvex() || (p1 && p1->hasEvex()) || base.hasEvex()) {
|
||||
evex(r, base, p1, type, code);
|
||||
} else {
|
||||
|
@ -1971,11 +2009,12 @@ private:
|
|||
}
|
||||
void opGather(const Xmm& x1, const Address& addr, const Xmm& x2, int type, uint8 code, int mode)
|
||||
{
|
||||
if (!addr.getRegExp().isVsib(128 | 256)) throw Error(ERR_BAD_VSIB_ADDRESSING);
|
||||
const RegExp& regExp = addr.getRegExp();
|
||||
if (!regExp.isVsib(128 | 256)) throw Error(ERR_BAD_VSIB_ADDRESSING);
|
||||
const int y_vx_y = 0;
|
||||
const int y_vy_y = 1;
|
||||
// const int x_vy_x = 2;
|
||||
const bool isAddrYMM = addr.getRegExp().getIndex().getBit() == 256;
|
||||
const bool isAddrYMM = regExp.getIndex().getBit() == 256;
|
||||
if (!x1.isXMM() || isAddrYMM || !x2.isXMM()) {
|
||||
bool isOK = false;
|
||||
if (mode == y_vx_y) {
|
||||
|
@ -2174,13 +2213,13 @@ public:
|
|||
const Address *addr = 0;
|
||||
uint8 code = 0;
|
||||
if (reg1.isREG() && reg1.getIdx() == 0 && reg2.isMEM()) { // mov eax|ax|al, [disp]
|
||||
reg = &static_cast<const Reg&>(reg1);
|
||||
addr= &static_cast<const Address&>(reg2);
|
||||
reg = ®1.getReg();
|
||||
addr= ®2.getAddress();
|
||||
code = 0xA0;
|
||||
} else
|
||||
if (reg1.isMEM() && reg2.isREG() && reg2.getIdx() == 0) { // mov [disp], eax|ax|al
|
||||
reg = &static_cast<const Reg&>(reg2);
|
||||
addr= &static_cast<const Address&>(reg1);
|
||||
reg = ®2.getReg();
|
||||
addr= ®1.getAddress();
|
||||
code = 0xA2;
|
||||
}
|
||||
#ifdef XBYAK64
|
||||
|
@ -2207,7 +2246,7 @@ public:
|
|||
void mov(const Operand& op, size_t imm)
|
||||
{
|
||||
if (op.isREG()) {
|
||||
const int size = mov_imm(static_cast<const Reg&>(op), imm);
|
||||
const int size = mov_imm(op.getReg(), imm);
|
||||
db(imm, size);
|
||||
} else if (op.isMEM()) {
|
||||
verifyMemHasSize(op);
|
||||
|
@ -2219,7 +2258,7 @@ public:
|
|||
if (!inner::IsInInt32(imm)) throw Error(ERR_IMM_IS_TOO_BIG);
|
||||
immSize = 4;
|
||||
}
|
||||
opModM(static_cast<const Address&>(op), Reg(0, Operand::REG, op.getBit()), 0xC6, NONE, NONE, immSize);
|
||||
opModM(op.getAddress(), Reg(0, Operand::REG, op.getBit()), 0xC6, NONE, NONE, immSize);
|
||||
db(static_cast<uint32>(imm), immSize);
|
||||
} else {
|
||||
throw Error(ERR_BAD_COMBINATION);
|
||||
|
@ -2303,7 +2342,7 @@ public:
|
|||
}
|
||||
void mov(const Segment& seg, const Operand& op)
|
||||
{
|
||||
opModRM(Reg8(seg.getIdx()), op.isREG(16|i32e) ? static_cast<const Operand&>(static_cast<const Reg&>(op).cvt32()) : op, op.isREG(16|i32e), op.isMEM(), 0x8E);
|
||||
opModRM(Reg8(seg.getIdx()), op.isREG(16|i32e) ? static_cast<const Operand&>(op.getReg().cvt32()) : op, op.isREG(16|i32e), op.isMEM(), 0x8E);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const char *getVersionString() const { return "5.52"; }
|
||||
const char *getVersionString() const { return "5.53"; }
|
||||
void adc(const Operand& op, uint32 imm) { opRM_I(op, imm, 0x10, 2); }
|
||||
void adc(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x10); }
|
||||
void adcx(const Reg32e& reg, const Operand& op) { opGen(reg, op, 0xF6, 0x66, isREG32_REG32orMEM, NONE, 0x38); }
|
||||
|
@ -36,11 +36,11 @@ void bnd() { db(0xF2); }
|
|||
void bndcl(const BoundsReg& bnd, const Operand& op) { db(0xF3); opR_ModM(op, i32e, bnd.getIdx(), 0x0F, 0x1A, NONE, !op.isMEM()); }
|
||||
void bndcn(const BoundsReg& bnd, const Operand& op) { db(0xF2); opR_ModM(op, i32e, bnd.getIdx(), 0x0F, 0x1B, NONE, !op.isMEM()); }
|
||||
void bndcu(const BoundsReg& bnd, const Operand& op) { db(0xF2); opR_ModM(op, i32e, bnd.getIdx(), 0x0F, 0x1A, NONE, !op.isMEM()); }
|
||||
void bndldx(const BoundsReg& bnd, const Address& addr) { opModM(addr, bnd, 0x0F, 0x1A); }
|
||||
void bndldx(const BoundsReg& bnd, const Address& addr) { opMIB(addr, bnd, 0x0F, 0x1A); }
|
||||
void bndmk(const BoundsReg& bnd, const Address& addr) { db(0xF3); opModM(addr, bnd, 0x0F, 0x1B); }
|
||||
void bndmov(const Address& addr, const BoundsReg& bnd) { db(0x66); opModM(addr, bnd, 0x0F, 0x1B); }
|
||||
void bndmov(const BoundsReg& bnd, const Operand& op) { db(0x66); opModRM(bnd, op, op.isBNDREG(), op.isMEM(), 0x0F, 0x1A); }
|
||||
void bndstx(const Address& addr, const BoundsReg& bnd) { opModM(addr, bnd, 0x0F, 0x1B); }
|
||||
void bndstx(const Address& addr, const BoundsReg& bnd) { opMIB(addr, bnd, 0x0F, 0x1B); }
|
||||
void bsf(const Reg®, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0xBC); }
|
||||
void bsr(const Reg®, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0xBD); }
|
||||
void bswap(const Reg32e& reg) { opModR(Reg32(1), reg, 0x0F); }
|
||||
|
|
Loading…
Reference in a new issue