mirror of
https://github.com/herumi/xbyak
synced 2024-11-20 16:06:14 -07:00
RAO_INT supports APX
This commit is contained in:
parent
26840492c3
commit
a7b02ac80d
4 changed files with 47 additions and 14 deletions
|
@ -860,14 +860,14 @@ void put()
|
||||||
const char *prefix;
|
const char *prefix;
|
||||||
} tbl[] = {
|
} tbl[] = {
|
||||||
{ "aadd", "" },
|
{ "aadd", "" },
|
||||||
{ "aand", " | T_66" },
|
{ "aand", "|T_66" },
|
||||||
{ "aor", " | T_F2" },
|
{ "aor", "|T_F2" },
|
||||||
{ "axor", " | T_F3" },
|
{ "axor", "|T_F3" },
|
||||||
};
|
};
|
||||||
for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) {
|
for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) {
|
||||||
const Tbl *p = &tbl[i];
|
const Tbl *p = &tbl[i];
|
||||||
printf("void %s(const Address& addr, const Reg32e ®) { ", p->name);
|
printf("void %s(const Address& addr, const Reg32e ®) { ", p->name);
|
||||||
printf("opMR(addr, reg, T_0F38%s, 0x0FC); }\n", p->prefix);
|
printf("opMR(addr, reg, T_0F38%s, 0x0FC, T_APX%s); }\n", p->prefix, p->prefix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
26
test/apx.cpp
26
test/apx.cpp
|
@ -1936,3 +1936,29 @@ CYBOZU_TEST_AUTO(0x0f_rex2)
|
||||||
CYBOZU_TEST_EQUAL_ARRAY(c.getCode(), tbl, n);
|
CYBOZU_TEST_EQUAL_ARRAY(c.getCode(), tbl, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CYBOZU_TEST_AUTO(rao_int)
|
||||||
|
{
|
||||||
|
struct Code : Xbyak::CodeGenerator {
|
||||||
|
Code()
|
||||||
|
{
|
||||||
|
aadd(ptr [r16+r31*1], r17d);
|
||||||
|
aadd(ptr [r16+r31*1], r17);
|
||||||
|
aand(ptr [r16+r31*1], r17d);
|
||||||
|
aand(ptr [r16+r31*1], r17);
|
||||||
|
aor(ptr [r16+r31*1], r17d);
|
||||||
|
aor(ptr [r16+r31*1], r17);
|
||||||
|
axor(ptr [r16+r31*1], r17d);
|
||||||
|
axor(ptr [r16+r31*1], r17);
|
||||||
|
}
|
||||||
|
} c;
|
||||||
|
const uint8_t tbl[] = {
|
||||||
|
0x62, 0xac, 0x78, 0x08, 0xfc, 0x0c, 0x38, 0x62, 0xac, 0xf8, 0x08, 0xfc, 0x0c, 0x38, 0x62, 0xac,
|
||||||
|
0x79, 0x08, 0xfc, 0x0c, 0x38, 0x62, 0xac, 0xf9, 0x08, 0xfc, 0x0c, 0x38, 0x62, 0xac, 0x7b, 0x08,
|
||||||
|
0xfc, 0x0c, 0x38, 0x62, 0xac, 0xfb, 0x08, 0xfc, 0x0c, 0x38, 0x62, 0xac, 0x7a, 0x08, 0xfc, 0x0c,
|
||||||
|
0x38, 0x62, 0xac, 0xfa, 0x08, 0xfc, 0x0c, 0x38,
|
||||||
|
};
|
||||||
|
const size_t n = sizeof(tbl);
|
||||||
|
CYBOZU_TEST_EQUAL(c.getSize(), n);
|
||||||
|
CYBOZU_TEST_EQUAL_ARRAY(c.getCode(), tbl, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -727,6 +727,7 @@ public:
|
||||||
bool operator==(const Operand& rhs) const;
|
bool operator==(const Operand& rhs) const;
|
||||||
bool operator!=(const Operand& rhs) const { return !operator==(rhs); }
|
bool operator!=(const Operand& rhs) const { return !operator==(rhs); }
|
||||||
const Address& getAddress() const;
|
const Address& getAddress() const;
|
||||||
|
Address getAddress(int immSize) const;
|
||||||
const Reg& getReg() const;
|
const Reg& getReg() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1345,6 +1346,12 @@ inline const Address& Operand::getAddress() const
|
||||||
assert(isMEM());
|
assert(isMEM());
|
||||||
return static_cast<const Address&>(*this);
|
return static_cast<const Address&>(*this);
|
||||||
}
|
}
|
||||||
|
inline Address Operand::getAddress(int immSize) const
|
||||||
|
{
|
||||||
|
Address addr = getAddress();
|
||||||
|
addr.immSize = immSize;
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool Operand::operator==(const Operand& rhs) const
|
inline bool Operand::operator==(const Operand& rhs) const
|
||||||
{
|
{
|
||||||
|
@ -2049,13 +2056,13 @@ private:
|
||||||
writeCode(type, reg1, code, rex2);
|
writeCode(type, reg1, code, rex2);
|
||||||
setModRM(3, reg1.getIdx(), reg2.getIdx());
|
setModRM(3, reg1.getIdx(), reg2.getIdx());
|
||||||
}
|
}
|
||||||
void opMR(Address addr, const Reg& r, uint64_t type, int code, int immSize = 0, uint64_t type2 = 0, uint8_t code2 = 0)
|
void opMR(const Address& addr, const Reg& r, uint64_t type, int code, uint64_t type2 = 0, int code2 = NONE)
|
||||||
{
|
{
|
||||||
if (type2 && opROO(Reg(), r, addr, type2, code2)) return;
|
if (code2 == NONE) code2 = code;
|
||||||
|
if (type2 && opROO(Reg(), addr, r, type2, code2)) return;
|
||||||
if (addr.is64bitDisp()) XBYAK_THROW(ERR_CANT_USE_64BIT_DISP)
|
if (addr.is64bitDisp()) XBYAK_THROW(ERR_CANT_USE_64BIT_DISP)
|
||||||
bool rex2 = rex(addr, r, type);
|
bool rex2 = rex(addr, r, type);
|
||||||
writeCode(type, r, code, rex2);
|
writeCode(type, r, code, rex2);
|
||||||
addr.immSize = immSize;
|
|
||||||
opAddr(addr, r.getIdx());
|
opAddr(addr, r.getIdx());
|
||||||
}
|
}
|
||||||
void opLoadSeg(const Address& addr, const Reg& reg, uint64_t type, int code)
|
void opLoadSeg(const Address& addr, const Reg& reg, uint64_t type, int code)
|
||||||
|
@ -2227,7 +2234,7 @@ private:
|
||||||
const Reg r(ext, Operand::REG, opBit);
|
const Reg r(ext, Operand::REG, opBit);
|
||||||
if ((type & T_APX) && op.hasRex2NFZU() && opROO(d ? *d : Reg(0, Operand::REG, opBit), op, r, type, code)) return;
|
if ((type & T_APX) && op.hasRex2NFZU() && 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(immSize), r, type, code);
|
||||||
} else if (op.isREG(bit)) {
|
} else if (op.isREG(bit)) {
|
||||||
opRR(r, op.getReg().changeBit(opBit), type, code);
|
opRR(r, op.getReg().changeBit(opBit), type, code);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2253,7 +2260,7 @@ private:
|
||||||
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)
|
||||||
{
|
{
|
||||||
if (op.isMEM()) {
|
if (op.isMEM()) {
|
||||||
opMR(op.getAddress(), r, type, code, immSize);
|
opMR(op.getAddress(immSize), r, type, code);
|
||||||
} else if (condR) {
|
} else if (condR) {
|
||||||
opRR(r, op.getReg(), type, code);
|
opRR(r, op.getReg(), type, code);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2955,7 +2962,7 @@ public:
|
||||||
if (!inner::IsInInt32(imm)) XBYAK_THROW(ERR_IMM_IS_TOO_BIG)
|
if (!inner::IsInInt32(imm)) XBYAK_THROW(ERR_IMM_IS_TOO_BIG)
|
||||||
immSize = 4;
|
immSize = 4;
|
||||||
}
|
}
|
||||||
opMR(op.getAddress(), Reg(0, Operand::REG, op.getBit()), 0, 0xC6, immSize);
|
opMR(op.getAddress(immSize), Reg(0, Operand::REG, op.getBit()), 0, 0xC6);
|
||||||
db(static_cast<uint32_t>(imm), immSize);
|
db(static_cast<uint32_t>(imm), immSize);
|
||||||
} else {
|
} else {
|
||||||
XBYAK_THROW(ERR_BAD_COMBINATION)
|
XBYAK_THROW(ERR_BAD_COMBINATION)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const char *getVersionString() const { return "7.04"; }
|
const char *getVersionString() const { return "7.04"; }
|
||||||
void aadd(const Address& addr, const Reg32e ®) { opMR(addr, reg, T_0F38, 0x0FC); }
|
void aadd(const Address& addr, const Reg32e ®) { opMR(addr, reg, T_0F38, 0x0FC, T_APX); }
|
||||||
void aand(const Address& addr, const Reg32e ®) { opMR(addr, reg, T_0F38 | T_66, 0x0FC); }
|
void aand(const Address& addr, const Reg32e ®) { opMR(addr, reg, T_0F38|T_66, 0x0FC, T_APX|T_66); }
|
||||||
void adc(const Operand& op, uint32_t imm) { opOI(op, imm, 0x10, 2); }
|
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 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, T_NONE, 2); }
|
void adc(const Reg& d, const Operand& op, uint32_t imm) { opROI(d, op, imm, T_NONE, 2); }
|
||||||
|
@ -34,8 +34,8 @@ void andnpd(const Xmm& xmm, const Operand& op) { opSSE(xmm, op, T_0F | T_66, 0x5
|
||||||
void andnps(const Xmm& xmm, const Operand& op) { opSSE(xmm, op, T_0F, 0x55, isXMM_XMMorMEM); }
|
void andnps(const Xmm& xmm, const Operand& op) { opSSE(xmm, op, T_0F, 0x55, isXMM_XMMorMEM); }
|
||||||
void andpd(const Xmm& xmm, const Operand& op) { opSSE(xmm, op, T_0F | T_66, 0x54, isXMM_XMMorMEM); }
|
void andpd(const Xmm& xmm, const Operand& op) { opSSE(xmm, op, T_0F | T_66, 0x54, isXMM_XMMorMEM); }
|
||||||
void andps(const Xmm& xmm, const Operand& op) { opSSE(xmm, op, T_0F, 0x54, isXMM_XMMorMEM); }
|
void andps(const Xmm& xmm, const Operand& op) { opSSE(xmm, op, T_0F, 0x54, isXMM_XMMorMEM); }
|
||||||
void aor(const Address& addr, const Reg32e ®) { opMR(addr, reg, T_0F38 | T_F2, 0x0FC); }
|
void aor(const Address& addr, const Reg32e ®) { opMR(addr, reg, T_0F38|T_F2, 0x0FC, T_APX|T_F2); }
|
||||||
void axor(const Address& addr, const Reg32e ®) { opMR(addr, reg, T_0F38 | T_F3, 0x0FC); }
|
void axor(const Address& addr, const Reg32e ®) { opMR(addr, reg, T_0F38|T_F3, 0x0FC, T_APX|T_F3); }
|
||||||
void bextr(const Reg32e& r1, const Operand& op, const Reg32e& r2) { opRRO(r1, r2, op, T_APX|T_0F38|T_NF, 0xf7); }
|
void bextr(const Reg32e& r1, const Operand& op, const Reg32e& r2) { opRRO(r1, r2, op, T_APX|T_0F38|T_NF, 0xf7); }
|
||||||
void blendpd(const Xmm& xmm, const Operand& op, int imm) { opSSE(xmm, op, T_66 | T_0F3A, 0x0D, isXMM_XMMorMEM, static_cast<uint8_t>(imm)); }
|
void blendpd(const Xmm& xmm, const Operand& op, int imm) { opSSE(xmm, op, T_66 | T_0F3A, 0x0D, isXMM_XMMorMEM, static_cast<uint8_t>(imm)); }
|
||||||
void blendps(const Xmm& xmm, const Operand& op, int imm) { opSSE(xmm, op, T_66 | T_0F3A, 0x0C, isXMM_XMMorMEM, static_cast<uint8_t>(imm)); }
|
void blendps(const Xmm& xmm, const Operand& op, int imm) { opSSE(xmm, op, T_66 | T_0F3A, 0x0C, isXMM_XMMorMEM, static_cast<uint8_t>(imm)); }
|
||||||
|
|
Loading…
Reference in a new issue