add vmovsd, vmovss
This commit is contained in:
parent
b6fe81bf84
commit
ac26e3a19c
5 changed files with 41 additions and 17 deletions
|
@ -24,6 +24,7 @@ enum {
|
||||||
T_MUST_EVEX = 1 << 23,
|
T_MUST_EVEX = 1 << 23,
|
||||||
T_B32 = 1 << 24, // m32bcst
|
T_B32 = 1 << 24, // m32bcst
|
||||||
T_B64 = 1 << 25, // m64bcst
|
T_B64 = 1 << 25, // m64bcst
|
||||||
|
T_M_K = 1 << 26, // mem{k}
|
||||||
T_XXX
|
T_XXX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -124,5 +125,9 @@ std::string type2String(int type)
|
||||||
if (!str.empty()) str += " | ";
|
if (!str.empty()) str += " | ";
|
||||||
str += "T_B64";
|
str += "T_B64";
|
||||||
}
|
}
|
||||||
|
if (type & T_M_K) {
|
||||||
|
if (!str.empty()) str += " | ";
|
||||||
|
str += "T_M_K";
|
||||||
|
}
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
|
@ -1541,10 +1541,12 @@ void put()
|
||||||
// vmovsd, vmovss
|
// vmovsd, vmovss
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
char c1 = i == 0 ? 'd' : 's';
|
char c1 = i == 0 ? 'd' : 's';
|
||||||
char c2 = i == 0 ? '2' : '3';
|
int type = T_0F | T_EVEX;
|
||||||
printf("void vmovs%c(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x1, x2, op, T_0F | T_F%c, 0x10); }\n", c1, c2);
|
type |= i == 0 ? T_F2 | T_EW1 : T_F3 | T_EW0;
|
||||||
printf("void vmovs%c(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, xm0, addr, T_0F | T_F%c, 0x10); }\n", c1, c2);
|
std::string s = type2String(type);
|
||||||
printf("void vmovs%c(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, T_0F | T_F%c, 0x11); }\n", c1, c2);
|
printf("void vmovs%c(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x1, x2, op, %s, 0x10); }\n", c1, s.c_str());
|
||||||
|
printf("void vmovs%c(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, xm0, addr, %s, 0x10); }\n", c1, s.c_str());
|
||||||
|
printf("void vmovs%c(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, %s | T_M_K, 0x11); }\n", c1, s.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// cvt
|
// cvt
|
||||||
|
|
|
@ -97,12 +97,13 @@ const uint64 XMM_SAE = 1ULL << 51;
|
||||||
#ifdef XBYAK64
|
#ifdef XBYAK64
|
||||||
const uint64 XMM_KZ = 1ULL << 52;
|
const uint64 XMM_KZ = 1ULL << 52;
|
||||||
const uint64 YMM_KZ = 1ULL << 53;
|
const uint64 YMM_KZ = 1ULL << 53;
|
||||||
const uint64 ZMM_KZ = 1ULL << 54; // max value
|
const uint64 ZMM_KZ = 1ULL << 54;
|
||||||
#else
|
#else
|
||||||
const uint64 XMM_KZ = 0;
|
const uint64 XMM_KZ = 0;
|
||||||
const uint64 YMM_KZ = 0;
|
const uint64 YMM_KZ = 0;
|
||||||
const uint64 ZMM_KZ = 0;
|
const uint64 ZMM_KZ = 0;
|
||||||
#endif
|
#endif
|
||||||
|
const uint64 MEM_K = 1ULL << 55; // max value
|
||||||
|
|
||||||
const uint64 NOPARA = 1ULL << (bitEnd - 1);
|
const uint64 NOPARA = 1ULL << (bitEnd - 1);
|
||||||
|
|
||||||
|
@ -388,6 +389,8 @@ class Test {
|
||||||
return isXbyak_ ? "ymm2 |k3|T_z" : "ymm2{k3}{z}";
|
return isXbyak_ ? "ymm2 |k3|T_z" : "ymm2{k3}{z}";
|
||||||
case ZMM_KZ:
|
case ZMM_KZ:
|
||||||
return isXbyak_ ? "zmm7|k1" : "zmm7{k1}";
|
return isXbyak_ ? "zmm7|k1" : "zmm7{k1}";
|
||||||
|
case MEM_K:
|
||||||
|
return isXbyak_ ? "ptr [rax] | k1" : "[rax]{k1}";
|
||||||
#else
|
#else
|
||||||
case XMM_SAE:
|
case XMM_SAE:
|
||||||
return isXbyak_ ? "xmm5 | T_sae" : "xmm5, {sae}";
|
return isXbyak_ ? "xmm5 | T_sae" : "xmm5, {sae}";
|
||||||
|
@ -395,6 +398,8 @@ class Test {
|
||||||
return isXbyak_ ? "zmm5 | T_sae" : "zmm5, {sae}";
|
return isXbyak_ ? "zmm5 | T_sae" : "zmm5, {sae}";
|
||||||
case ZMM_ER:
|
case ZMM_ER:
|
||||||
return isXbyak_ ? "zmm2 | T_rd_sae" : "zmm2, {rd-sae}";
|
return isXbyak_ ? "zmm2 | T_rd_sae" : "zmm2, {rd-sae}";
|
||||||
|
case MEM_K:
|
||||||
|
return isXbyak_ ? "ptr [eax] | k1" : "[eax]{k1}";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2616,6 +2621,13 @@ public:
|
||||||
put("vmovntdq", MEM, _XMM3 | _YMM3 | ZMM);
|
put("vmovntdq", MEM, _XMM3 | _YMM3 | ZMM);
|
||||||
put("vmovntpd", MEM, _XMM3 | _YMM3 | ZMM);
|
put("vmovntpd", MEM, _XMM3 | _YMM3 | ZMM);
|
||||||
put("vmovntps", MEM, _XMM3 | _YMM3 | ZMM);
|
put("vmovntps", MEM, _XMM3 | _YMM3 | ZMM);
|
||||||
|
|
||||||
|
put("vmovsd", XMM_KZ, _XMM3, _XMM3);
|
||||||
|
put("vmovsd", XMM_KZ, MEM);
|
||||||
|
put("vmovsd", MEM_K, XMM);
|
||||||
|
put("vmovss", XMM_KZ, _XMM3, _XMM3);
|
||||||
|
put("vmovss", XMM_KZ, MEM);
|
||||||
|
put("vmovss", MEM_K, XMM);
|
||||||
{
|
{
|
||||||
const char tbl[][16] = {
|
const char tbl[][16] = {
|
||||||
"vmovhpd",
|
"vmovhpd",
|
||||||
|
|
|
@ -172,6 +172,7 @@ enum {
|
||||||
ERR_SAE_IS_INVALID,
|
ERR_SAE_IS_INVALID,
|
||||||
ERR_ER_IS_INVALID,
|
ERR_ER_IS_INVALID,
|
||||||
ERR_INVALID_BROADCAST,
|
ERR_INVALID_BROADCAST,
|
||||||
|
ERR_INVALID_OPMASK_WITH_MEMORY,
|
||||||
ERR_INTERNAL
|
ERR_INTERNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -229,6 +230,7 @@ public:
|
||||||
"sae(suppress all exceptions) is invalid",
|
"sae(suppress all exceptions) is invalid",
|
||||||
"er(embedded rounding) is invalid",
|
"er(embedded rounding) is invalid",
|
||||||
"invalid broadcast",
|
"invalid broadcast",
|
||||||
|
"invalid opmask with memory",
|
||||||
"internal error",
|
"internal error",
|
||||||
};
|
};
|
||||||
assert((size_t)err_ < sizeof(errTbl) / sizeof(*errTbl));
|
assert((size_t)err_ < sizeof(errTbl) / sizeof(*errTbl));
|
||||||
|
@ -546,7 +548,7 @@ struct Opmask : public Reg {
|
||||||
template<class T>
|
template<class T>
|
||||||
T operator|(const T& x, const Opmask& k)
|
T operator|(const T& x, const Opmask& k)
|
||||||
{
|
{
|
||||||
if (!x.is(Operand::XMM | Operand::YMM | Operand::ZMM | Operand::OPMASK)) throw Error(ERR_BAD_COMBINATION);
|
if (!x.is(Operand::XMM | Operand::YMM | Operand::ZMM | Operand::OPMASK | Operand::MEM)) throw Error(ERR_BAD_COMBINATION);
|
||||||
T r(x);
|
T r(x);
|
||||||
r.setOpmaskIdx(k.getIdx());
|
r.setOpmaskIdx(k.getIdx());
|
||||||
return r;
|
return r;
|
||||||
|
@ -955,7 +957,7 @@ public:
|
||||||
}
|
}
|
||||||
#ifdef XBYAK64
|
#ifdef XBYAK64
|
||||||
explicit Address(size_t disp)
|
explicit Address(size_t disp)
|
||||||
: Operand(0, MEM, 64), e_(disp), label_(0), mode_(M_64bitDisp), permitVsib_(false), broadcast_(false) { }
|
: Operand(0, MEM, 64), e_(disp), label_(0), mode_(M_64bitDisp), permitVsib_(false), broadcast_(false){ }
|
||||||
Address(uint32 sizeBit, bool broadcast, const RegRip& addr)
|
Address(uint32 sizeBit, bool broadcast, const RegRip& addr)
|
||||||
: Operand(0, MEM, sizeBit), e_(addr.disp_), label_(addr.label_), mode_(M_rip), permitVsib_(false), broadcast_(broadcast) { }
|
: Operand(0, MEM, sizeBit), e_(addr.disp_), label_(addr.label_), mode_(M_rip), permitVsib_(false), broadcast_(broadcast) { }
|
||||||
#endif
|
#endif
|
||||||
|
@ -1364,6 +1366,7 @@ private:
|
||||||
T_MUST_EVEX = 1 << 23,
|
T_MUST_EVEX = 1 << 23,
|
||||||
T_B32 = 1 << 24, // m32bcst
|
T_B32 = 1 << 24, // m32bcst
|
||||||
T_B64 = 1 << 25, // m64bcst
|
T_B64 = 1 << 25, // m64bcst
|
||||||
|
T_M_K = 1 << 26, // mem{k}
|
||||||
T_XXX
|
T_XXX
|
||||||
};
|
};
|
||||||
void vex(const Reg& reg, const Reg& base, const Operand *v, int type, int code, bool x = false)
|
void vex(const Reg& reg, const Reg& base, const Operand *v, int type, int code, bool x = false)
|
||||||
|
@ -1401,7 +1404,7 @@ private:
|
||||||
T_RZ_SAE = 4,
|
T_RZ_SAE = 4,
|
||||||
T_SAE = 5,
|
T_SAE = 5,
|
||||||
};
|
};
|
||||||
void evex(const Reg& reg, const Reg& base, const Operand *v, int type, int code, bool x = false, bool b = false)
|
void evex(const Reg& reg, const Reg& base, const Operand *v, int type, int code, bool x = false, bool b = false, int aaa = 0)
|
||||||
{
|
{
|
||||||
if (!(type & T_EVEX)) throw Error(ERR_EVEX_IS_INVALID);
|
if (!(type & T_EVEX)) throw Error(ERR_EVEX_IS_INVALID);
|
||||||
int w = (type & T_EW1) ? 1 : 0;
|
int w = (type & T_EW1) ? 1 : 0;
|
||||||
|
@ -1431,7 +1434,7 @@ private:
|
||||||
}
|
}
|
||||||
bool Vp = !(v ? v->isExtIdx2() : 0);
|
bool Vp = !(v ? v->isExtIdx2() : 0);
|
||||||
bool z = reg.hasZero();
|
bool z = reg.hasZero();
|
||||||
int aaa = reg.getOpmaskIdx();
|
if (aaa == 0) aaa = reg.getOpmaskIdx();
|
||||||
db(0x62);
|
db(0x62);
|
||||||
db((R ? 0x80 : 0) | (X ? 0x40 : 0) | (B ? 0x20 : 0) | (Rp ? 0x10 : 0) | (mm & 3));
|
db((R ? 0x80 : 0) | (X ? 0x40 : 0) | (B ? 0x20 : 0) | (Rp ? 0x10 : 0) | (mm & 3));
|
||||||
db((w == 1 ? 0x80 : 0) | ((vvvv & 15) << 3) | 4 | (pp & 3));
|
db((w == 1 ? 0x80 : 0) | ((vvvv & 15) << 3) | 4 | (pp & 3));
|
||||||
|
@ -1756,7 +1759,9 @@ private:
|
||||||
if (BIT == 64 && addr.is32bit()) db(0x67);
|
if (BIT == 64 && addr.is32bit()) db(0x67);
|
||||||
int disp8N = 0;
|
int disp8N = 0;
|
||||||
bool x = addr.getRegExp().getIndex().isExtIdx();
|
bool x = addr.getRegExp().getIndex().isExtIdx();
|
||||||
if ((type & T_MUST_EVEX) || r.hasEvex() || (p1 && p1->hasEvex()) || addr.isBroadcast()) {
|
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);
|
||||||
bool b = false;
|
bool b = false;
|
||||||
if (addr.isBroadcast()) {
|
if (addr.isBroadcast()) {
|
||||||
if (!(type & (T_B32 | T_B64))) throw Error(ERR_INVALID_BROADCAST);
|
if (!(type & (T_B32 | T_B64))) throw Error(ERR_INVALID_BROADCAST);
|
||||||
|
@ -1765,7 +1770,7 @@ private:
|
||||||
} else {
|
} else {
|
||||||
disp8N = 1;
|
disp8N = 1;
|
||||||
}
|
}
|
||||||
evex(r, base, p1, type, code, x, b);
|
evex(r, base, p1, type, code, x, b, aaa);
|
||||||
} else {
|
} else {
|
||||||
vex(r, base, p1, type, code, x);
|
vex(r, base, p1, type, code, x);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1467,12 +1467,12 @@ void vmovntdq(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, cvtIdx0(x), a
|
||||||
void vmovntpd(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, cvtIdx0(x), addr, T_0F | T_66 | T_YMM | T_EVEX | T_EW1, 0x2B); }
|
void vmovntpd(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, cvtIdx0(x), addr, T_0F | T_66 | T_YMM | T_EVEX | T_EW1, 0x2B); }
|
||||||
void vmovntps(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, cvtIdx0(x), addr, T_0F | T_YMM | T_EVEX | T_EW0, 0x2B); }
|
void vmovntps(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, cvtIdx0(x), addr, T_0F | T_YMM | T_EVEX | T_EW0, 0x2B); }
|
||||||
void vmovntdqa(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, cvtIdx0(x), addr, T_0F38 | T_66 | T_YMM | T_EVEX | T_EW0, 0x2A); }
|
void vmovntdqa(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, cvtIdx0(x), addr, T_0F38 | T_66 | T_YMM | T_EVEX | T_EW0, 0x2A); }
|
||||||
void vmovsd(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x1, x2, op, T_0F | T_F2, 0x10); }
|
void vmovsd(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x1, x2, op, T_0F | T_F2 | T_EW1 | T_EVEX, 0x10); }
|
||||||
void vmovsd(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, xm0, addr, T_0F | T_F2, 0x10); }
|
void vmovsd(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, xm0, addr, T_0F | T_F2 | T_EW1 | T_EVEX, 0x10); }
|
||||||
void vmovsd(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, T_0F | T_F2, 0x11); }
|
void vmovsd(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, T_0F | T_F2 | T_EW1 | T_EVEX | T_M_K, 0x11); }
|
||||||
void vmovss(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x1, x2, op, T_0F | T_F3, 0x10); }
|
void vmovss(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x1, x2, op, T_0F | T_F3 | T_EW0 | T_EVEX, 0x10); }
|
||||||
void vmovss(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, xm0, addr, T_0F | T_F3, 0x10); }
|
void vmovss(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, xm0, addr, T_0F | T_F3 | T_EW0 | T_EVEX, 0x10); }
|
||||||
void vmovss(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, T_0F | T_F3, 0x11); }
|
void vmovss(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, T_0F | T_F3 | T_EW0 | T_EVEX | T_M_K, 0x11); }
|
||||||
void vcvtss2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, T_0F | T_F3 | T_W0, 0x2D); }
|
void vcvtss2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, T_0F | T_F3 | T_W0, 0x2D); }
|
||||||
void vcvttss2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, T_0F | T_F3 | T_W0, 0x2C); }
|
void vcvttss2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, T_0F | T_F3 | T_W0, 0x2C); }
|
||||||
void vcvtsd2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, T_0F | T_F2 | T_W0, 0x2D); }
|
void vcvtsd2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, T_0F | T_F2 | T_W0, 0x2D); }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue