fix encoding of vpsrlvq, vsqrtpd

This commit is contained in:
MITSUNARI Shigeo 2016-07-17 11:30:10 +09:00
parent e5ad6ad61e
commit f79df1f515
8 changed files with 100 additions and 39 deletions

View file

@ -1036,7 +1036,7 @@ void put()
{ 0x47, "psllvq", T_0F38 | T_66 | T_W1 | T_YMM | T_EVEX | T_EW1 | T_B64, false, false },
{ 0x46, "psravd", T_0F38 | T_66 | T_W0 | T_YMM | T_EVEX | T_EW0 | T_B32, false, false },
{ 0x45, "psrlvd", T_0F38 | T_66 | T_W0 | T_YMM | T_EVEX | T_EW0 | T_B32, false, false },
{ 0x45, "psrlvq", T_0F38 | T_66 | T_W1 | T_YMM | T_EVEX | T_EW1 | T_B32, false, false },
{ 0x45, "psrlvq", T_0F38 | T_66 | T_W1 | T_YMM | T_EVEX | T_EW1 | T_B64, false, false },
{ 0xC2, "cmppd", T_0F | T_66 | T_YMM, true, true },
{ 0xC2, "cmpps", T_0F | T_YMM, true, true },
@ -1241,7 +1241,7 @@ void put()
{ 0x53, "rcpps", T_0F | T_YMM, false },
{ 0x52, "rsqrtps", T_0F | T_YMM, false },
{ 0x51, "sqrtpd", T_0F | T_66 | T_YMM | T_EVEX | T_EW1 | T_ER_Z | T_B32 | T_B64, false },
{ 0x51, "sqrtpd", T_0F | T_66 | T_YMM | T_EVEX | T_EW1 | T_ER_Z | T_B64, false },
{ 0x51, "sqrtps", T_0F | T_YMM | T_EVEX | T_EW0 | T_ER_Z | T_B32, false },
{ 0x2E, "ucomisd", T_0F | T_66 | T_EVEX | T_EW1 | T_SAE_X, false },
@ -1585,8 +1585,9 @@ void put()
"opAVX_X_X_XMcvt(x, false, cvtIdx0(x), op, !op.isMEM(), x.isXMM() ? Operand::XMM : Operand::YMM, T_0F | T_F3 | T_YMM | T_EVEX | T_EW0 | T_B32, 0xE6); }\n");
printf("void vcvtpd2ps(const Xmm& x, const Operand& op) { if (x.isYMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(op.isYMM() ? Ymm(x.getIdx()) : x, cvtIdx0(op), op, T_0F | T_66 | T_YMM, 0x5A); }\n");
printf("void vcvtpd2dq(const Xmm& x, const Operand& op) { if (!(op.isMEM() || (x.isXMM() && op.is(Operand::XMM | Operand::YMM)) || (x.isYMM() && op.isZMM()))) throw Error(ERR_BAD_COMBINATION); "
"opAVX_X_X_XM(x.copyAndSetKind(op.getKind()), cvtIdx0(op.isMEM() ? x : op), op, T_0F | T_F2 | T_YMM | T_EVEX | T_EW1 | T_B64 | T_ER_Z, 0xE6); }\n");
// printf("void vcvtpd2dq(const Xmm& x, const Operand& op) { if (!(op.isMEM() || (x.isXMM() && op.is(Operand::XMM | Operand::YMM)) || (x.isYMM() && op.isZMM()))) throw Error(ERR_BAD_COMBINATION); "
// "Operand::Kind kind = x.isXMM() ? (op.isBit(256) ? Operand::YMM : Operand::XMM) : Operand::ZMM;"
// "opAVX_X_X_XM(x.copyAndSetKind(kind), xm0.copyAndSetKind(kind), op, T_0F | T_F2 | T_YMM | T_EVEX | T_EW1 | T_B64 | T_ER_Z, 0xE6); }\n");
printf("void vcvttpd2dq(const Xmm& x, const Operand& op) { if (x.isYMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(op.isYMM() ? Ymm(x.getIdx()) : x, cvtIdx0(op), op, T_0F | T_66 | T_YMM, 0xE6); }\n");
printf("void vcvtph2ps(const Xmm& x, const Operand& op) { if (!op.isMEM() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opVex(x, 0, op, T_0F38 | T_66 | T_W0, 0x13); }\n");

View file

@ -143,6 +143,11 @@ vaddpd ymm1, ymm2, [rax+256]{1to4} --> vaddpd(ymm1, ymm2, ptr_b [rax+256]);
vaddpd zmm1, zmm2, [rax+256]{1to8} --> vaddpd(zmm1, zmm2, ptr_b [rax+256]);
vaddps zmm1, zmm2, [rax+rcx*8+8]{1to16} --> vaddps(zmm1, zmm2, ptr_b [rax+rcx*8+8]);
vmovsd [rax]{k1}, xmm4 --> vmovsd (ptr [rax] | k1, xmm4);
vcvtpd2dq xmm16, oword [eax+33] --> vcvtpd2dq(xmm16, ptr [eax+33]); // default oword(m128)
vcvtpd2dq xmm21, [eax+32]{1to2} --> vcvtpd2dq(xmm21, ptr_b [eax+32]);
vcvtpd2dq xmm0, yword [eax+33] --> vcvtpd2dq(xmm0, yword [eax+33]); // use yword for m256
vcvtpd2dq xmm19, [eax+32]{1to4} --> vcvtpd2dq(xmm19, yword_b [eax+32]); // use yword_b to broadcast
```
Remark
* k1, ..., k7 are new opmask registers.

View file

@ -139,6 +139,11 @@ vaddpd zmm1, zmm2, [rax+256]{1to8} --> vaddpd(zmm1, zmm2, ptr_b [rax+256]);
vaddps zmm1, zmm2, [rax+rcx*8+8]{1to16} --> vaddps(zmm1, zmm2, ptr_b [rax+rcx*8+8]);
vmovsd [rax]{k1}, xmm4 --> vmovsd (ptr [rax] | k1, xmm4);
vcvtpd2dq xmm16, oword [eax+33] --> vcvtpd2dq(xmm16, ptr [eax+33]); // default oword(m128)
vcvtpd2dq xmm21, [eax+32]{1to2} --> vcvtpd2dq(xmm21, ptr_b [eax+32]);
vcvtpd2dq xmm0, yword [eax+33] --> vcvtpd2dq(xmm0, yword [eax+33]); // use yword for m256
vcvtpd2dq xmm19, [eax+32]{1to4} --> vcvtpd2dq(xmm19, yword_b [eax+32]); // use yword_b to broadcast
注意
* k1, ..., k7 は新しいopmaskレジスタです。

View file

@ -27,7 +27,6 @@ const uint64 IMM_1 = 1ULL << 14;
const uint64 MEM8 = 1ULL << 15;
const uint64 MEM16 = 1ULL << 16;
const uint64 MEM32 = 1ULL << 17;
const uint64 NEG = 1ULL << 18;
const uint64 ONE = 1ULL << 19;
const uint64 CL = 1ULL << 20;
const uint64 MEM_ONLY_DISP = 1ULL << 21;
@ -109,6 +108,9 @@ const uint64 M_1to4 = 1ULL << 57;
const uint64 M_1to8 = 1ULL << 58;
const uint64 M_1to16 = 1ULL << 59;
const uint64 XMM_ER = 1ULL << 60;
const uint64 M_xword = 1ULL << 61;
const uint64 M_yword = 1ULL << 62;
const uint64 MY_1to4 = 1ULL << 18;
const uint64 NOPARA = 1ULL << (bitEnd - 1);
@ -242,7 +244,19 @@ class Test {
}
#endif
case _MEM:
return isXbyak_ ? "ptr[eax+ecx+3]" : "[eax+ecx+3]";
{
return isXbyak_ ? "ptr[eax+ecx+3]" : "[eax+ecx+3]"; // QQQ : disp8N
/*
idx %= 5;
switch (idx) {
case 0: return isXbyak_ ? "ptr[eax+ecx]" : "[eax+ecx]";
case 1: return isXbyak_ ? "ptr[eax+ecx+1]" : "[eax+ecx+1]";
case 2: return isXbyak_ ? "ptr[eax+ecx+16]" : "[eax+ecx+16]";
case 3: return isXbyak_ ? "ptr[eax+ecx+32]" : "[eax+ecx+32]";
case 4: return isXbyak_ ? "ptr[eax+ecx+48]" : "[eax+ecx+48]";
}
*/
}
case _MEMe:
{
static int ccc = 1;
@ -362,8 +376,6 @@ class Test {
return "4";
case IMM_2:
return isXbyak_ ? "0xda" : "0xda";
case NEG:
return "-5";
case VM32X_32:
return isXbyak_ ? "ptr [ebp+4+xmm1*8]" : "[ebp+4+xmm1*8]";
case VM32X_64:
@ -372,10 +384,14 @@ class Test {
return isXbyak_ ? "ptr [ymm4]" : "[ymm4]";
case VM32Y_64:
return isXbyak_ ? "ptr [12345+ymm13*2+r13]" : "[12345+ymm13*2+r13]";
case M_1to2: return isXbyak_ ? "ptr_b [eax]" : "[eax]{1to2}";
case M_1to4: return isXbyak_ ? "ptr_b [eax]" : "[eax]{1to4}";
case M_1to8: return isXbyak_ ? "ptr_b [eax]" : "[eax]{1to8}";
case M_1to16: return isXbyak_ ? "ptr_b [eax]" : "[eax]{1to16}";
case M_1to2: return isXbyak_ ? "ptr_b [eax+32]" : "[eax+32]{1to2}";
case M_1to4: return isXbyak_ ? "ptr_b [eax+32]" : "[eax+32]{1to4}";
case M_1to8: return isXbyak_ ? "ptr_b [eax+32]" : "[eax+32]{1to8}";
case M_1to16: return isXbyak_ ? "ptr_b [eax+32]" : "[eax+32]{1to16}";
case M_xword: return isXbyak_ ? "ptr [eax+33]" : "oword [eax+33]";
case M_yword: return isXbyak_ ? "yword [eax+33]" : "yword [eax+33]";
case MY_1to4: return isXbyak_ ? "yword_b [eax+32]" : "[eax+32]{1to4}";
case K:
{
static const char kTbl[][5] = {
@ -2318,8 +2334,8 @@ public:
{
#ifdef USE_AVX512
putAVX512();
return;
#endif
#else
#ifdef USE_AVX
separateFunc();
@ -2416,6 +2432,8 @@ public:
#endif // XBYAK64
#endif // USE_AVX
#endif // USE_AVX512
}
#ifdef USE_AVX512
void putOpmask()
@ -2549,6 +2567,9 @@ public:
}
}
}
put("vaddpd", XMM, XMM, _MEM);
put("vaddpd", YMM, YMM, _MEM);
put("vaddpd", ZMM, ZMM, _MEM);
}
void putCmpK()
{
@ -2590,7 +2611,7 @@ public:
put("vcomiss", XMM, XMM_SAE);
#endif
}
void putBroadcastSub(int disp)
void putBroadcastSub(int idx, int disp)
{
#ifdef XBYAK64
const char *a = "rax";
@ -2598,19 +2619,23 @@ public:
const char *a = "eax";
#endif
if (isXbyak_) {
printf("vaddpd(zmm0, zmm1, ptr_b[%s+%d]);dump();\n", a, disp);
printf("vaddpd(ymm0, ymm1, ptr_b[%s+%d]);dump();\n", a, disp);
printf("vaddpd(xmm0, xmm1, ptr_b[%s+%d]);dump();\n", a, disp);
printf("vaddpd(zmm%d, zmm1, ptr_b[%s+%d]);dump();\n", idx, a, disp);
printf("vaddpd(ymm%d, ymm1, ptr_b[%s+%d]);dump();\n", idx, a, disp);
printf("vaddpd(xmm%d, xmm1, ptr_b[%s+%d]);dump();\n", idx, a, disp);
} else {
printf("vaddpd zmm0, zmm1, [%s+%d]{1to8}\n", a, disp);
printf("vaddpd ymm0, ymm1, [%s+%d]{1to4}\n", a, disp);
printf("vaddpd xmm0, xmm1, [%s+%d]{1to2}\n", a, disp);
printf("vaddpd zmm%d, zmm1, [%s+%d]{1to8}\n", idx, a, disp);
printf("vaddpd ymm%d, ymm1, [%s+%d]{1to4}\n", idx, a, disp);
printf("vaddpd xmm%d, xmm1, [%s+%d]{1to2}\n", idx, a, disp);
}
}
void putBroadcast()
{
for (int i = 0; i < 9; i++) {
putBroadcastSub(i);
putBroadcastSub(0, i);
#ifdef XBYAK64
putBroadcastSub(10, i);
putBroadcastSub(20, i);
#endif
}
put("vpbroadcastb", XMM_KZ | ZMM_KZ, REG8);
put("vpbroadcastw", XMM_KZ | ZMM_KZ, REG16);
@ -3243,12 +3268,22 @@ public:
put("vcvtdq2ps", YMM_KZ, _YMM | M_1to8);
put("vcvtdq2ps", ZMM_KZ, _ZMM | M_1to16);
put("vcvtpd2dq", XMM_KZ, _XMM | _YMM | M_1to4);
put("vcvtpd2dq", XMM_KZ, _XMM | _YMM | M_1to2);
put("vcvtpd2dq", YMM_KZ, _ZMM | ZMM_ER | M_1to8);
#endif
}
void putMin()
{
#ifdef XBYAK64
put("vcvtpd2dq", _XMM | _XMM3, _XMM | M_xword | M_1to2);
put("vcvtpd2dq", _XMM | _XMM3, _YMM | M_yword | MY_1to4);
#endif
}
void putAVX512()
{
#ifdef MIN_TEST
putMin();
#else
putOpmask();
separateFunc();
putCombi();
@ -3276,6 +3311,7 @@ public:
put512_AVX1();
separateFunc();
put512_cvt();
#endif
}
#endif
};

View file

@ -1,7 +1,12 @@
@echo off
set FILTER=cat
set Y=0
if /i "%1"=="64" (
if /i "%1"=="min" (
set EXE=nasm.exe
set OPT2=-DXBYAK64 -DMIN_TEST
set OPT3=win64
set FILTER=normalize_prefix
) else if /i "%1"=="64" (
set EXE=nasm.exe
set OPT2=-DXBYAK64
set OPT3=win64
@ -13,13 +18,13 @@ if /i "%1"=="64" (
)
call set_opt
bmake -f Makefile.win all
echo cl -I../ make_nm.cpp %OPT% %OPT2% /EHs /DUSE_AVX512
cl -I../ make_nm.cpp %OPT% %OPT2% /EHs /DUSE_AVX512
make_nm > a.asm
echo cl -I../ make_512.cpp %OPT% %OPT2% /EHs /DUSE_AVX512
cl -I../ make_512.cpp %OPT% %OPT2% /EHs /DUSE_AVX512
make_512 > a.asm
%EXE% -f %OPT3% -l a.lst a.asm
rem connect "?????-" and "??"
awk "{if (index($3, ""-"")) { conti=substr($3, 0, length($3) - 1) } else { conti = conti $3; print conti; conti = """" }} " < a.lst |%FILTER% > ok.lst
make_nm jit > nm.cpp
make_512 jit > nm.cpp
cl -I../ -DXBYAK_TEST nm_frame.cpp %OPT% %OPT2% /DXBYAK_AVX512
nm_frame |%FILTER% > x.lst
diff x.lst ok.lst

View file

@ -16,16 +16,16 @@ else
endif
set CFLAGS="-Wall -fno-operator-names -I../ $OPT2 -DUSE_AVX512"
echo "compile make_nm.cpp"
g++ $CFLAGS make_nm.cpp -o make_nm
echo "compile make_512.cpp"
g++ $CFLAGS make_512.cpp -o make_512
./make_nm > a.asm
./make_512 > a.asm
echo "asm"
$EXE -f$OPT3 a.asm -l a.lst
awk '{if (index($3, "-")) { conti=substr($3, 0, length($3) - 1) } else { conti = conti $3; print conti; conti = "" }} ' < a.lst | $FILTER > ok.lst
echo "xbyak"
./make_nm jit > nm.cpp
./make_512 jit > nm.cpp
echo "compile nm_frame.cpp"
g++ $CFLAGS -DXBYAK_TEST nm_frame.cpp -o nm_frame -DXBYAK_AVX512
./nm_frame | $FILTER > x.lst

View file

@ -1777,7 +1777,8 @@ private:
disp8N = (type & T_B32) ? 4 : 8;
b = true;
} else {
disp8N = 1;
// int bit = Max(r.getBit(), p1 ? p1->getBit() : 0);
disp8N = 1;//bit == 512 ? 64 : bit == 256 ? 32 : bit == 128 ? 16 : 1;
}
evex(r, base, p1, type, code, x, b, aaa);
} else {
@ -1823,6 +1824,14 @@ private:
if (!((x1.isXMM() && x2->isXMM()) || ((type & T_YMM) && ((x1.isYMM() && x2->isYMM()) || (x1.isZMM() && x2->isZMM()))))) throw Error(ERR_BAD_COMBINATION);
opVex(x1, x2, *op, type, code0, imm8);
}
public:
void vcvtpd2dq(const Xmm& x, const Operand& op)
{
if (!(op.isMEM() || (x.isXMM() && op.is(Operand::XMM | Operand::YMM)) || (x.isYMM() && op.isZMM()))) throw Error(ERR_BAD_COMBINATION);
Operand::Kind kind = x.isXMM() ? (op.isBit(256) ? Operand::YMM : Operand::XMM) : Operand::ZMM;
opVex(x.copyAndSetKind(kind), &xm0, op, T_0F | T_F2 | T_YMM | T_EVEX | T_EW1 | T_B64 | T_ER_Z, 0xE6);
}
void opAVX_K_X_XM(const Opmask& k, const Xmm& x2, const Operand& op3, int type, int code0, int imm8 = NONE)
{
if (!op3.isMEM() && (x2.getKind() != op3.getKind())) throw Error(ERR_BAD_COMBINATION);
@ -1889,8 +1898,8 @@ public:
const Reg32 eax, ecx, edx, ebx, esp, ebp, esi, edi;
const Reg16 ax, cx, dx, bx, sp, bp, si, di;
const Reg8 al, cl, dl, bl, ah, ch, dh, bh;
const AddressFrame ptr, byte, word, dword, qword;
const AddressFrame ptr_b; // broadcast such as {1to2}, {1to4}, {1to8}, {1to16}, {b}
const AddressFrame ptr, byte, word, dword, qword, yword;
const AddressFrame ptr_b, yword_b; // broadcast such as {1to2}, {1to4}, {1to8}, {1to16}, {b}
const Fpu st0, st1, st2, st3, st4, st5, st6, st7;
const Opmask k0, k1, k2, k3, k4, k5, k6, k7;
const EvexModifierRounding T_sae, T_rn_sae, T_rd_sae, T_ru_sae, T_rz_sae; // {sae}, {rn-sae}, {rd-sae}, {ru-sae}, {rz-sae}
@ -2371,7 +2380,8 @@ public:
, eax(Operand::EAX), ecx(Operand::ECX), edx(Operand::EDX), ebx(Operand::EBX), esp(Operand::ESP), ebp(Operand::EBP), esi(Operand::ESI), edi(Operand::EDI)
, ax(Operand::AX), cx(Operand::CX), dx(Operand::DX), bx(Operand::BX), sp(Operand::SP), bp(Operand::BP), si(Operand::SI), di(Operand::DI)
, al(Operand::AL), cl(Operand::CL), dl(Operand::DL), bl(Operand::BL), ah(Operand::AH), ch(Operand::CH), dh(Operand::DH), bh(Operand::BH)
, ptr(0), byte(8), word(16), dword(32), qword(64), ptr_b(0, true)
, ptr(0), byte(8), word(16), dword(32), qword(64), yword(256)
, ptr_b(0, true), yword_b(256, true)
, st0(0), st1(1), st2(2), st3(3), st4(4), st5(5), st6(6), st7(7)
, k0(0), k1(1), k2(2), k3(3), k4(4), k5(5), k6(6), k7(7)
, T_sae(T_SAE), T_rn_sae(T_RN_SAE), T_rd_sae(T_RD_SAE), T_ru_sae(T_RU_SAE), T_rz_sae(T_RZ_SAE)

View file

@ -762,7 +762,7 @@ void vpsllvd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1,
void vpsllvq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_0F38 | T_66 | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0x47); }
void vpsravd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_0F38 | T_66 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0x46); }
void vpsrlvd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_0F38 | T_66 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0x45); }
void vpsrlvq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_0F38 | T_66 | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B32, 0x45); }
void vpsrlvq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_0F38 | T_66 | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0x45); }
void vcmppd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_0F | T_66 | T_YMM, 0xC2, imm); }
void vcmppd(const Xmm& x, const Operand& op, uint8 imm) { vcmppd(x, x, op, imm); }
void vcmpps(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_0F | T_YMM, 0xC2, imm); }
@ -1009,7 +1009,7 @@ void vpshuflw(const Xmm& xm, const Operand& op, uint8 imm) { opAVX_X_XM_IMM(xm,
void vptest(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_0F38 | T_66, 0x17); }
void vrcpps(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_0F | T_YMM, 0x53); }
void vrsqrtps(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_0F | T_YMM, 0x52); }
void vsqrtpd(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_0F | T_66 | T_EW1 | T_YMM | T_EVEX | T_ER_Z | T_B32 | T_B64, 0x51); }
void vsqrtpd(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_0F | T_66 | T_EW1 | T_YMM | T_EVEX | T_ER_Z | T_B64, 0x51); }
void vsqrtps(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_0F | T_EW0 | T_YMM | T_EVEX | T_ER_Z | T_B32, 0x51); }
void vucomisd(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_0F | T_66 | T_EW1 | T_EVEX | T_SAE_X, 0x2E); }
void vucomiss(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_0F | T_EW0 | T_EVEX | T_SAE_X, 0x2E); }
@ -1483,7 +1483,6 @@ void vcvtsi2sd(const Xmm& x, const Operand& op1, const Operand& op2 = Operand())
void vcvtps2pd(const Xmm& x, const Operand& op) { if (!op.isMEM() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XMcvt(x, false, cvtIdx0(x), op, !op.isMEM(), x.isXMM() ? Operand::XMM : Operand::YMM, T_0F | T_YMM, 0x5A); }
void vcvtdq2pd(const Xmm& x, const Operand& op) { if (!(op.isMEM() || (x.is(Operand::XMM | Operand::YMM) && op.isXMM()) || (x.isZMM() && op.isYMM()))) throw Error(ERR_BAD_COMBINATION);opAVX_X_X_XMcvt(x, false, cvtIdx0(x), op, !op.isMEM(), x.isXMM() ? Operand::XMM : Operand::YMM, T_0F | T_F3 | T_YMM | T_EVEX | T_EW0 | T_B32, 0xE6); }
void vcvtpd2ps(const Xmm& x, const Operand& op) { if (x.isYMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(op.isYMM() ? Ymm(x.getIdx()) : x, cvtIdx0(op), op, T_0F | T_66 | T_YMM, 0x5A); }
void vcvtpd2dq(const Xmm& x, const Operand& op) { if (!(op.isMEM() || (x.isXMM() && op.is(Operand::XMM | Operand::YMM)) || (x.isYMM() && op.isZMM()))) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x.copyAndSetKind(op.getKind()), cvtIdx0(op.isMEM() ? x : op), op, T_0F | T_F2 | T_YMM | T_EVEX | T_EW1 | T_B64 | T_ER_Z, 0xE6); }
void vcvttpd2dq(const Xmm& x, const Operand& op) { if (x.isYMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(op.isYMM() ? Ymm(x.getIdx()) : x, cvtIdx0(op), op, T_0F | T_66 | T_YMM, 0xE6); }
void vcvtph2ps(const Xmm& x, const Operand& op) { if (!op.isMEM() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opVex(x, 0, op, T_0F38 | T_66 | T_W0, 0x13); }
void vcvtps2ph(const Operand& op, const Xmm& x, uint8 imm) { if (!op.isMEM() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opVex(x, 0, op, T_0F3A | T_66 | T_W0, 0x1d, imm); }