2115 lines
106 KiB
Go
2115 lines
106 KiB
Go
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package arch
|
|
|
|
import (
|
|
"encoding/hex"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// The BF16, VP2INTERSECT and FP16 encodings have no toolchain oracle: go
|
|
// tool asm knows none of these families. The golden words below are
|
|
// transcribed from the Intel SDM instruction entries and cross-checked
|
|
// against binutils-gdb's own assembler testsuite: every row marked "GNU"
|
|
// matches a vector in gas/testsuite/gas/i386/avx512_bf16.d,
|
|
// avx512_bf16_vl.d, x86-64-vp2intersect.d, x86-64-avx512_fp16.d or
|
|
// avx512_fp16_vl.d byte for byte, so no entry rests on transcription alone. The two VMOVW rows are
|
|
// class vectors: the GNU file proves the 66.MAP5 opcode row on the m16
|
|
// memory forms, and the register form follows the manual's ModR/M reg row.
|
|
// The GNU dumps print AT&T order (sources first, destination last), which is
|
|
// the order the operands are built in here too.
|
|
type amd64GoldenRow struct {
|
|
name string
|
|
mnem string
|
|
ops []ExtOperand
|
|
want string // hex, little-endian bytes in memory order
|
|
GNU string // the matching binutils-gdb line, empty for a derived register form
|
|
}
|
|
|
|
var amd64GoldenRows = []amd64GoldenRow{
|
|
// AVX512-BF16, EVEX.NDS.F2.0F38.W0 for the three-register convert,
|
|
// EVEX.F3.0F38.W0 for the narrow convert and the dot product.
|
|
{"vcvtne2ps2bf16 zmm", "VCVTNE2PS2BF16",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(4), ExtZmm(6)},
|
|
"62f2574872f4", "62 f2 57 48 72 f4 vcvtne2ps2bf16 %zmm4,%zmm5,%zmm6"},
|
|
{"vcvtne2ps2bf16 ymm", "VCVTNE2PS2BF16",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f2572872f4", "62 f2 57 28 72 f4 vcvtne2ps2bf16 %ymm4,%ymm5,%ymm6"},
|
|
{"vcvtne2ps2bf16 xmm", "VCVTNE2PS2BF16",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f2570872f4", "62 f2 57 08 72 f4 vcvtne2ps2bf16 %xmm4,%xmm5,%xmm6"},
|
|
{"vcvtneps2bf16 zmm to ymm", "VCVTNEPS2BF16",
|
|
[]ExtOperand{ExtZmm(5), ExtYmm(6)},
|
|
"62f27e4872f5", "62 f2 7e 48 72 f5 vcvtneps2bf16 %zmm5,%ymm6"},
|
|
{"vcvtneps2bf16 ymm to xmm", "VCVTNEPS2BF16",
|
|
[]ExtOperand{ExtYmm(5), ExtXmm(6)},
|
|
"62f27e2872f5", "62 f2 7e 28 72 f5 vcvtneps2bf16 %ymm5,%xmm6"},
|
|
{"vcvtneps2bf16 xmm to xmm", "VCVTNEPS2BF16",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(6)},
|
|
"62f27e0872f5", "62 f2 7e 08 72 f5 vcvtneps2bf16 %xmm5,%xmm6"},
|
|
{"vdpbf16ps zmm", "VDPBF16PS",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(4), ExtZmm(6)},
|
|
"62f2564852f4", "62 f2 56 48 52 f4 vdpbf16ps %zmm4,%zmm5,%zmm6"},
|
|
{"vdpbf16ps ymm", "VDPBF16PS",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f2562852f4", "62 f2 56 28 52 f4 vdpbf16ps %ymm4,%ymm5,%ymm6"},
|
|
{"vdpbf16ps xmm", "VDPBF16PS",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f2560852f4", "62 f2 56 08 52 f4 vdpbf16ps %xmm4,%xmm5,%xmm6"},
|
|
|
|
// AVX512-VP2INTERSECT, EVEX.NDS.F2.0F38. The mask destination is the
|
|
// ModR/M reg field, so a k register above k7 must refuse.
|
|
{"vp2intersectd zmm k0", "VP2INTERSECTD",
|
|
[]ExtOperand{ExtZmm(2), ExtZmm(1), ExtMask(0)},
|
|
"62f26f4868c1", "62 f2 6f 48 68 c1 vp2intersectd %zmm1,%zmm2,%k0"},
|
|
{"vp2intersectd ymm k2", "VP2INTERSECTD",
|
|
[]ExtOperand{ExtYmm(2), ExtYmm(1), ExtMask(2)},
|
|
"62f26f2868d1", "62 f2 6f 28 68 d1 vp2intersectd %ymm1,%ymm2,%k2"},
|
|
{"vp2intersectd xmm k4", "VP2INTERSECTD",
|
|
[]ExtOperand{ExtXmm(2), ExtXmm(1), ExtMask(4)},
|
|
"62f26f0868e1", "62 f2 6f 08 68 e1 vp2intersectd %xmm1,%xmm2,%k4"},
|
|
{"vp2intersectq zmm k0", "VP2INTERSECTQ",
|
|
[]ExtOperand{ExtZmm(2), ExtZmm(1), ExtMask(0)},
|
|
"62f2ef4868c1", "62 f2 ef 48 68 c1 vp2intersectq %zmm1,%zmm2,%k0"},
|
|
{"vp2intersectq ymm k2", "VP2INTERSECTQ",
|
|
[]ExtOperand{ExtYmm(2), ExtYmm(1), ExtMask(2)},
|
|
"62f2ef2868d1", "62 f2 ef 28 68 d1 vp2intersectq %ymm1,%ymm2,%k2"},
|
|
{"vp2intersectq xmm k4", "VP2INTERSECTQ",
|
|
[]ExtOperand{ExtXmm(2), ExtXmm(1), ExtMask(4)},
|
|
"62f2ef0868e1", "62 f2 ef 08 68 e1 vp2intersectq %xmm1,%xmm2,%k4"},
|
|
|
|
// AVX512-FP16 scalar arithmetic, EVEX.NDS.LIG.F3.MAP5.W0. Every
|
|
// register in the GNU vector sits above 15, so the row exercises all
|
|
// four EVEX extension bits at once.
|
|
{"vmovsh", "VMOVSH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"6205160010f4", "62 05 16 00 10 f4 vmovsh %xmm28,%xmm29,%xmm30"},
|
|
{"vaddsh", "VADDSH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"6205160058f4", "62 05 16 00 58 f4 vaddsh %xmm28,%xmm29,%xmm30"},
|
|
{"vsubsh", "VSUBSH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"620516005cf4", "62 05 16 00 5c f4 vsubsh %xmm28,%xmm29,%xmm30"},
|
|
{"vmulsh", "VMULSH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"6205160059f4", "62 05 16 00 59 f4 vmulsh %xmm28,%xmm29,%xmm30"},
|
|
{"vdivsh", "VDIVSH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"620516005ef4", "62 05 16 00 5e f4 vdivsh %xmm28,%xmm29,%xmm30"},
|
|
{"vminsh", "VMINSH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"620516005df4", "62 05 16 00 5d f4 vminsh %xmm28,%xmm29,%xmm30"},
|
|
{"vmaxsh", "VMAXSH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"620516005ff4", "62 05 16 00 5f f4 vmaxsh %xmm28,%xmm29,%xmm30"},
|
|
{"vsqrtsh", "VSQRTSH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"6205160051f4", "62 05 16 00 51 f4 vsqrtsh %xmm28,%xmm29,%xmm30"},
|
|
|
|
// The scalar scale and exponent extracts, EVEX.NDS.LIG.66.MAP6.W0.
|
|
{"vscalefsh", "VSCALEFSH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"620615002df4", "62 06 15 00 2d f4 vscalefsh %xmm28,%xmm29,%xmm30"},
|
|
{"vgetexpsh", "VGETEXPSH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"6206150043f4", "62 06 15 00 43 f4 vgetexpsh %xmm28,%xmm29,%xmm30"},
|
|
|
|
// The scalar compares take two operands, EVEX.LIG.MAP5.W0.
|
|
{"vcomish", "VCOMISH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(30)},
|
|
"62057c082ff5", "62 05 7c 08 2f f5 vcomish %xmm29,%xmm30"},
|
|
{"vucomish", "VUCOMISH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(30)},
|
|
"62057c082ef5", "62 05 7c 08 2e f5 vucomish %xmm29,%xmm30"},
|
|
|
|
// The floating-point conversions between the three scalar widths. The
|
|
// single-precision convert carries no prefix, the half-to-double convert
|
|
// carries F3, the double-to-half convert F2 and W1.
|
|
{"vcvtss2sh", "VCVTSS2SH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"620514001df4", "62 05 14 00 1d f4 vcvtss2sh %xmm28,%xmm29,%xmm30"},
|
|
{"vcvtsh2ss", "VCVTSH2SS",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"6206140013f4", "62 06 14 00 13 f4 vcvtsh2ss %xmm28,%xmm29,%xmm30"},
|
|
{"vcvtsh2sd", "VCVTSH2SD",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"620516005af4", "62 05 16 00 5a f4 vcvtsh2sd %xmm28,%xmm29,%xmm30"},
|
|
{"vcvtsd2sh", "VCVTSD2SH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"620597005af4", "62 05 97 00 5a f4 vcvtsd2sh %xmm28,%xmm29,%xmm30"},
|
|
|
|
// The integer conversions, one entry per W bit: the W bit picks the
|
|
// 32-bit or the 64-bit general register.
|
|
{"vcvtsi2sh edx", "VCVTSI2SH",
|
|
[]ExtOperand{ExtXmm(29), ExtGpr32(2), ExtXmm(30)},
|
|
"626516002af2", "62 65 16 00 2a f2 vcvtsi2sh %edx,%xmm29,%xmm30"},
|
|
{"vcvtsi2sh r12", "VCVTSI2SH",
|
|
[]ExtOperand{ExtXmm(29), ExtGpr64(12), ExtXmm(30)},
|
|
"624596002af4", "62 45 96 00 2a f4 vcvtsi2sh %r12,%xmm29,%xmm30"},
|
|
{"vcvtusi2sh edx", "VCVTUSI2SH",
|
|
[]ExtOperand{ExtXmm(29), ExtGpr32(2), ExtXmm(30)},
|
|
"626516007bf2", "62 65 16 00 7b f2 vcvtusi2sh %edx,%xmm29,%xmm30"},
|
|
{"vcvtusi2sh r12", "VCVTUSI2SH",
|
|
[]ExtOperand{ExtXmm(29), ExtGpr64(12), ExtXmm(30)},
|
|
"624596007bf4", "62 45 96 00 7b f4 vcvtusi2sh %r12,%xmm29,%xmm30"},
|
|
{"vcvtsh2si edx", "VCVTSH2SI",
|
|
[]ExtOperand{ExtXmm(30), ExtGpr32(2)},
|
|
"62957e082dd6", "62 95 7e 08 2d d6 vcvtsh2si %xmm30,%edx"},
|
|
{"vcvtsh2si r12", "VCVTSH2SI",
|
|
[]ExtOperand{ExtXmm(30), ExtGpr64(12)},
|
|
"6215fe082de6", "62 15 fe 08 2d e6 vcvtsh2si %xmm30,%r12"},
|
|
{"vcvtsh2usi edx", "VCVTSH2USI",
|
|
[]ExtOperand{ExtXmm(30), ExtGpr32(2)},
|
|
"62957e0879d6", "62 95 7e 08 79 d6 vcvtsh2usi %xmm30,%edx"},
|
|
{"vcvtsh2usi r12", "VCVTSH2USI",
|
|
[]ExtOperand{ExtXmm(30), ExtGpr64(12)},
|
|
"6215fe0879e6", "62 15 fe 08 79 e6 vcvtsh2usi %xmm30,%r12"},
|
|
|
|
// VMOVW in both directions: the register forms are class vectors, the
|
|
// GNU file proves the opcode rows on the m16 memory forms.
|
|
{"vmovw into xmm", "VMOVW",
|
|
[]ExtOperand{ExtGpr32(12), ExtXmm(30)},
|
|
"62457d086ef4", ""},
|
|
{"vmovw out of xmm", "VMOVW",
|
|
[]ExtOperand{ExtXmm(30), ExtGpr32(12)},
|
|
"62157d087ee6", ""},
|
|
|
|
// AVX512-FP16 packed arithmetic, EVEX.NDS.MAP5.W0 with no mandatory
|
|
// prefix. The 512-bit GNU rows sit on high registers, the VL rows
|
|
// quote avx512_fp16_vl.d on the suite's low registers.
|
|
{"vaddph", "VADDPH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtZmm(30)},
|
|
"6205144058f4", "62 05 14 40 58 f4 vaddph %zmm28,%zmm29,%zmm30"},
|
|
{"vaddph ymm", "VADDPH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f5542858f4", "62 f5 54 28 58 f4 vaddph %ymm4,%ymm5,%ymm6"},
|
|
{"vaddph xmm", "VADDPH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f5540858f4", "62 f5 54 08 58 f4 vaddph %xmm4,%xmm5,%xmm6"},
|
|
{"vsubph", "VSUBPH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtZmm(30)},
|
|
"620514405cf4", "62 05 14 40 5c f4 vsubph %zmm28,%zmm29,%zmm30"},
|
|
{"vsubph ymm", "VSUBPH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f554285cf4", "62 f5 54 28 5c f4 vsubph %ymm4,%ymm5,%ymm6"},
|
|
{"vsubph xmm", "VSUBPH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f554085cf4", "62 f5 54 08 5c f4 vsubph %xmm4,%xmm5,%xmm6"},
|
|
{"vmulph", "VMULPH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtZmm(30)},
|
|
"6205144059f4", "62 05 14 40 59 f4 vmulph %zmm28,%zmm29,%zmm30"},
|
|
{"vmulph ymm", "VMULPH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f5542859f4", "62 f5 54 28 59 f4 vmulph %ymm4,%ymm5,%ymm6"},
|
|
{"vmulph xmm", "VMULPH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f5540859f4", "62 f5 54 08 59 f4 vmulph %xmm4,%xmm5,%xmm6"},
|
|
{"vdivph", "VDIVPH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtZmm(30)},
|
|
"620514405ef4", "62 05 14 40 5e f4 vdivph %zmm28,%zmm29,%zmm30"},
|
|
{"vdivph ymm", "VDIVPH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f554285ef4", "62 f5 54 28 5e f4 vdivph %ymm4,%ymm5,%ymm6"},
|
|
{"vdivph xmm", "VDIVPH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f554085ef4", "62 f5 54 08 5e f4 vdivph %xmm4,%xmm5,%xmm6"},
|
|
{"vminph", "VMINPH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtZmm(30)},
|
|
"620514405df4", "62 05 14 40 5d f4 vminph %zmm28,%zmm29,%zmm30"},
|
|
{"vminph ymm", "VMINPH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f554285df4", "62 f5 54 28 5d f4 vminph %ymm4,%ymm5,%ymm6"},
|
|
{"vminph xmm", "VMINPH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f554085df4", "62 f5 54 08 5d f4 vminph %xmm4,%xmm5,%xmm6"},
|
|
{"vmaxph", "VMAXPH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtZmm(30)},
|
|
"620514405ff4", "62 05 14 40 5f f4 vmaxph %zmm28,%zmm29,%zmm30"},
|
|
{"vmaxph ymm", "VMAXPH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f554285ff4", "62 f5 54 28 5f f4 vmaxph %ymm4,%ymm5,%ymm6"},
|
|
{"vmaxph xmm", "VMAXPH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f554085ff4", "62 f5 54 08 5f f4 vmaxph %xmm4,%xmm5,%xmm6"},
|
|
{"vsqrtph", "VSQRTPH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(30)},
|
|
"62057c4851f5", "62 05 7c 48 51 f5 vsqrtph %zmm29,%zmm30"},
|
|
{"vsqrtph ymm", "VSQRTPH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(6)},
|
|
"62f57c2851f5", "62 f5 7c 28 51 f5 vsqrtph %ymm5,%ymm6"},
|
|
{"vsqrtph xmm", "VSQRTPH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(6)},
|
|
"62f57c0851f5", "62 f5 7c 08 51 f5 vsqrtph %xmm5,%xmm6"},
|
|
|
|
// The imm8-control group of the scalar core. The rows take the
|
|
// immediate first and the sources after it as src1, src2, the reverse
|
|
// of the listing's AT&T register order; every control byte is the $0x7b
|
|
// the suite drives through each imm8 form, save VGETMANTSH: the upper
|
|
// nibble of its control is reserved, so the layer enforces the SDM and
|
|
// encodes $0x0b where the suite's $0x7b would fault. The GNU line
|
|
// still proves the six opcode bytes, the immediate rides last as the
|
|
// operand it is.
|
|
{"vcmpsh", "VCMPSH",
|
|
[]ExtOperand{ExtImmediate(0x7b), ExtXmm(29), ExtXmm(28), ExtMask(5)},
|
|
"62931600c2ec7b", "62 93 16 00 c2 ec 7b vcmpsh $0x7b,%xmm28,%xmm29,%k5"},
|
|
{"vgetmantsh", "VGETMANTSH",
|
|
[]ExtOperand{ExtImmediate(0x0b), ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"6203140027f40b", "62 03 14 00 27 f4 7b vgetmantsh $0x7b,%xmm28,%xmm29,%xmm30 (opcode row only)"},
|
|
{"vreducesh", "VREDUCESH",
|
|
[]ExtOperand{ExtImmediate(0x7b), ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"6203140057f47b", "62 03 14 00 57 f4 7b vreducesh $0x7b,%xmm28,%xmm29,%xmm30"},
|
|
{"vrndscalesh", "VRNDSCALESH",
|
|
[]ExtOperand{ExtImmediate(0x7b), ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"620314000af47b", "62 03 14 00 0a f4 7b vrndscalesh $0x7b,%xmm28,%xmm29,%xmm30"},
|
|
|
|
// The memory forms of the scalar moves and arithmetic, against the same
|
|
// listings' memory rows. The zero-displacement rows match the GNU
|
|
// source spellings outright and every base R8+ row exercises the EVEX.B
|
|
// high-base bit. The disp8 rows pin the bytes the listing lays down;
|
|
// binutils mainline encodes EVEX displacements with the APX disp8*N
|
|
// scaling, so its source spellings (0xfe for the m16 rows, 0x1fc0 for
|
|
// the m512 ones) are N times the plain SDM displacement those bytes
|
|
// carry, and the operand lists here hold the plain displacement. The
|
|
// rows with no GNU line are derived: the disp32 form the SDM ModR/M
|
|
// table defines and the source listings never emit plain, and the SIB
|
|
// byte the R12 base demands.
|
|
{"vmovsh load from r9", "VMOVSH",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtXmm(30)},
|
|
"62457e081031", "62 45 7e 08 10 31 vmovsh (%r9),%xmm30"},
|
|
{"vmovsh load disp8", "VMOVSH",
|
|
[]ExtOperand{ExtMemory(1, 127), ExtXmm(30)},
|
|
"62657e0810717f", "62 65 7e 08 10 71 7f vmovsh 0xfe(%rcx),%xmm30 (Disp8(7f))"},
|
|
{"vmovsh store to r9", "VMOVSH",
|
|
[]ExtOperand{ExtXmm(30), ExtMemory(9, 0)},
|
|
"62457e081131", "62 45 7e 08 11 31 vmovsh %xmm30,(%r9)"},
|
|
{"vmovsh store disp8", "VMOVSH",
|
|
[]ExtOperand{ExtXmm(30), ExtMemory(1, 127)},
|
|
"62657e0811717f", "62 65 7e 08 11 71 7f vmovsh %xmm30,0xfe(%rcx) (Disp8(7f))"},
|
|
{"vmovsh store negative disp32", "VMOVSH",
|
|
[]ExtOperand{ExtXmm(30), ExtMemory(13, -200)},
|
|
"62457e0811b538ffffff", ""},
|
|
{"vmovw load from r9", "VMOVW",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtXmm(30)},
|
|
"62457d086e31", "62 45 7d 08 6e 31 vmovw (%r9),%xmm30"},
|
|
{"vmovw load disp8", "VMOVW",
|
|
[]ExtOperand{ExtMemory(1, 127), ExtXmm(30)},
|
|
"62657d086e717f", "62 65 7d 08 6e 71 7f vmovw 0xfe(%rcx),%xmm30 (Disp8(7f))"},
|
|
{"vmovw store to r9", "VMOVW",
|
|
[]ExtOperand{ExtXmm(30), ExtMemory(9, 0)},
|
|
"62457d087e31", "62 45 7d 08 7e 31 vmovw %xmm30,(%r9)"},
|
|
{"vmovw store disp8", "VMOVW",
|
|
[]ExtOperand{ExtXmm(30), ExtMemory(1, 127)},
|
|
"62657d087e717f", "62 65 7d 08 7e 71 7f vmovw %xmm30,0xfe(%rcx) (Disp8(7f))"},
|
|
{"vaddsh memory source", "VADDSH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(9, 0), ExtXmm(30)},
|
|
"624516005831", "62 45 16 00 58 31 vaddsh (%r9),%xmm29,%xmm30"},
|
|
{"vaddsh memory source disp8", "VADDSH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(1, 127), ExtXmm(30)},
|
|
"6265160058717f", "62 65 16 00 58 71 7f vaddsh 0xfe(%rcx),%xmm29,%xmm30 (Disp8(7f))"},
|
|
{"vaddsh memory source disp32", "VADDSH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(2, 8128), ExtXmm(30)},
|
|
"6265160058b2c01f0000", ""},
|
|
{"vsubsh memory source", "VSUBSH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(9, 0), ExtXmm(30)},
|
|
"624516005c31", "62 45 16 00 5c 31 vsubsh (%r9),%xmm29,%xmm30"},
|
|
{"vmulsh memory source disp8", "VMULSH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(1, 127), ExtXmm(30)},
|
|
"6265160059717f", "62 65 16 00 59 71 7f vmulsh 0xfe(%rcx),%xmm29,%xmm30 (Disp8(7f))"},
|
|
{"vdivsh memory source", "VDIVSH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(9, 0), ExtXmm(30)},
|
|
"624516005e31", "62 45 16 00 5e 31 vdivsh (%r9),%xmm29,%xmm30"},
|
|
{"vminsh memory source disp8", "VMINSH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(1, 127), ExtXmm(30)},
|
|
"626516005d717f", "62 65 16 00 5d 71 7f vminsh 0xfe(%rcx),%xmm29,%xmm30 (Disp8(7f))"},
|
|
{"vmaxsh memory source", "VMAXSH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(9, 0), ExtXmm(30)},
|
|
"624516005f31", "62 45 16 00 5f 31 vmaxsh (%r9),%xmm29,%xmm30"},
|
|
{"vsqrtsh memory source", "VSQRTSH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(9, 0), ExtXmm(30)},
|
|
"624516005131", "62 45 16 00 51 31 vsqrtsh (%r9),%xmm29,%xmm30"},
|
|
{"vsqrtsh memory source negative disp8", "VSQRTSH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(2, -128), ExtXmm(30)},
|
|
"62651600517280", "62 65 16 87 51 72 80 vsqrtsh -0x100(%rdx),%xmm29,%xmm30 (Disp8(80); the GNU row adds {k7}{z})"},
|
|
|
|
// The packed memory forms: the arithmetic reads its second source, the
|
|
// square root its source and the compares their operand from memory.
|
|
// The disp8 rows quote the listing's plain-base rows, with the plain
|
|
// displacement the bytes encode; the R12 rows are derived and exercise
|
|
// the SIB byte.
|
|
{"vaddph memory source", "VADDPH",
|
|
[]ExtOperand{ExtZmm(29), ExtMemory(1, 127), ExtZmm(30)},
|
|
"6265144058717f", "62 65 14 40 58 71 7f vaddph 0x1fc0(%rcx),%zmm29,%zmm30 (Disp8(7f))"},
|
|
{"vaddph ymm memory source", "VADDPH",
|
|
[]ExtOperand{ExtYmm(5), ExtMemory(1, 127), ExtYmm(6)},
|
|
"62f5542858717f", "62 f5 54 28 58 71 7f vaddph 0xfe0(%ecx),%ymm5,%ymm6 (Disp8(7f))"},
|
|
{"vaddph xmm memory source", "VADDPH",
|
|
[]ExtOperand{ExtXmm(5), ExtMemory(1, 127), ExtXmm(6)},
|
|
"62f5540858717f", "62 f5 54 08 58 71 7f vaddph 0x7f0(%ecx),%xmm5,%xmm6 (Disp8(7f))"},
|
|
{"vaddph memory source over an R12 base", "VADDPH",
|
|
[]ExtOperand{ExtZmm(29), ExtMemory(12, 0), ExtZmm(30)},
|
|
"62451440583424", ""},
|
|
{"vsubph memory source", "VSUBPH",
|
|
[]ExtOperand{ExtZmm(29), ExtMemory(1, 127), ExtZmm(30)},
|
|
"626514405c717f", "62 65 14 40 5c 71 7f vsubph 0x1fc0(%rcx),%zmm29,%zmm30 (Disp8(7f))"},
|
|
{"vmulph memory source", "VMULPH",
|
|
[]ExtOperand{ExtZmm(29), ExtMemory(1, 127), ExtZmm(30)},
|
|
"6265144059717f", "62 65 14 40 59 71 7f vmulph 0x1fc0(%rcx),%zmm29,%zmm30 (Disp8(7f))"},
|
|
{"vdivph memory source", "VDIVPH",
|
|
[]ExtOperand{ExtZmm(29), ExtMemory(1, 127), ExtZmm(30)},
|
|
"626514405e717f", "62 65 14 40 5e 71 7f vdivph 0x1fc0(%rcx),%zmm29,%zmm30 (Disp8(7f))"},
|
|
{"vminph memory source", "VMINPH",
|
|
[]ExtOperand{ExtZmm(29), ExtMemory(1, 127), ExtZmm(30)},
|
|
"626514405d717f", "62 65 14 40 5d 71 7f vminph 0x1fc0(%rcx),%zmm29,%zmm30 (Disp8(7f))"},
|
|
{"vmaxph memory source", "VMAXPH",
|
|
[]ExtOperand{ExtZmm(29), ExtMemory(1, 127), ExtZmm(30)},
|
|
"626514405f717f", "62 65 14 40 5f 71 7f vmaxph 0x1fc0(%rcx),%zmm29,%zmm30 (Disp8(7f))"},
|
|
{"vsqrtph memory source", "VSQRTPH",
|
|
[]ExtOperand{ExtMemory(1, 127), ExtZmm(30)},
|
|
"62657c4851717f", "62 65 7c 48 51 71 7f vsqrtph 0x1fc0(%rcx),%zmm30 (Disp8(7f))"},
|
|
{"vsqrtph ymm memory source over an R12 base", "VSQRTPH",
|
|
[]ExtOperand{ExtMemory(12, 0), ExtYmm(6)},
|
|
"62d57c28513424", ""},
|
|
{"vcomish memory source", "VCOMISH",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtXmm(30)},
|
|
"62457c082f31", "62 45 7c 08 2f 31 vcomish (%r9),%xmm30"},
|
|
{"vcomish memory source disp8", "VCOMISH",
|
|
[]ExtOperand{ExtMemory(1, 127), ExtXmm(30)},
|
|
"62657c082f717f", "62 65 7c 08 2f 71 7f vcomish 0xfe(%rcx),%xmm30 (Disp8(7f))"},
|
|
{"vcomish memory source negative disp8", "VCOMISH",
|
|
[]ExtOperand{ExtMemory(2, -128), ExtXmm(30)},
|
|
"62657c082f7280", "62 65 7c 08 2f 72 80 vcomish -0x100(%rdx),%xmm30 (Disp8(80))"},
|
|
{"vucomish memory source", "VUCOMISH",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtXmm(30)},
|
|
"62457c082e31", "62 45 7c 08 2e 31 vucomish (%r9),%xmm30"},
|
|
{"vucomish memory source negative disp8", "VUCOMISH",
|
|
[]ExtOperand{ExtMemory(2, -128), ExtXmm(30)},
|
|
"62657c082e7280", "62 65 7c 08 2e 72 80 vucomish -0x100(%rdx),%xmm30 (Disp8(80))"},
|
|
|
|
// The {1toN} broadcast forms of the packed arithmetic: the same memory
|
|
// encoding with EVEX.b set, one element the hardware splats across the
|
|
// lanes. The zero-displacement rows quote the listings' broadcast rows
|
|
// outright, the {1to32} spellings from x86-64-avx512_fp16.d and the
|
|
// {1to16}/{1to8} ones from avx512_fp16_vl.d. The negative disp8 row
|
|
// pins the bytes of a masked GNU row: its {k7}{z} rides the z and aaa
|
|
// bits the layer leaves clear, and the spelling is N times the plain
|
|
// displacement under the disp8*N scaling.
|
|
{"vaddph broadcast source", "VADDPH",
|
|
[]ExtOperand{ExtZmm(29), ExtBroadcast(9, 0), ExtZmm(30)},
|
|
"624514505831", "62 45 14 50 58 31 vaddph (%r9){1to32},%zmm29,%zmm30"},
|
|
{"vsubph broadcast source", "VSUBPH",
|
|
[]ExtOperand{ExtZmm(29), ExtBroadcast(9, 0), ExtZmm(30)},
|
|
"624514505c31", "62 45 14 50 5c 31 vsubph (%r9){1to32},%zmm29,%zmm30"},
|
|
{"vmulph broadcast source", "VMULPH",
|
|
[]ExtOperand{ExtZmm(29), ExtBroadcast(9, 0), ExtZmm(30)},
|
|
"624514505931", "62 45 14 50 59 31 vmulph (%r9){1to32},%zmm29,%zmm30"},
|
|
{"vdivph broadcast source", "VDIVPH",
|
|
[]ExtOperand{ExtZmm(29), ExtBroadcast(9, 0), ExtZmm(30)},
|
|
"624514505e31", "62 45 14 50 5e 31 vdivph (%r9){1to32},%zmm29,%zmm30"},
|
|
{"vminph broadcast source", "VMINPH",
|
|
[]ExtOperand{ExtZmm(29), ExtBroadcast(9, 0), ExtZmm(30)},
|
|
"624514505d31", "62 45 14 50 5d 31 vminph (%r9){1to32},%zmm29,%zmm30"},
|
|
{"vmaxph broadcast source", "VMAXPH",
|
|
[]ExtOperand{ExtZmm(29), ExtBroadcast(9, 0), ExtZmm(30)},
|
|
"624514505f31", "62 45 14 50 5f 31 vmaxph (%r9){1to32},%zmm29,%zmm30"},
|
|
{"vsqrtph broadcast source", "VSQRTPH",
|
|
[]ExtOperand{ExtBroadcast(9, 0), ExtZmm(30)},
|
|
"62457c585131", "62 45 7c 58 51 31 vsqrtph (%r9){1to32},%zmm30"},
|
|
{"vaddph broadcast source negative disp8", "VADDPH",
|
|
[]ExtOperand{ExtZmm(29), ExtBroadcast(2, -128), ExtZmm(30)},
|
|
"62651450587280", "62 65 14 d7 58 72 80 vaddph -0x100(%rdx){1to32},%zmm29,%zmm30{%k7}{z} (Disp8(80); the GNU row adds {k7}{z})"},
|
|
{"vaddph ymm broadcast source", "VADDPH",
|
|
[]ExtOperand{ExtYmm(5), ExtBroadcast(1, 0), ExtYmm(6)},
|
|
"62f554385831", "62 f5 54 38 58 31 vaddph (%ecx){1to16},%ymm5,%ymm6"},
|
|
{"vaddph xmm broadcast source", "VADDPH",
|
|
[]ExtOperand{ExtXmm(5), ExtBroadcast(1, 0), ExtXmm(6)},
|
|
"62f554185831", "62 f5 54 18 58 31 vaddph (%ecx){1to8},%xmm5,%xmm6"},
|
|
{"vsqrtph ymm broadcast source", "VSQRTPH",
|
|
[]ExtOperand{ExtBroadcast(1, 0), ExtYmm(6)},
|
|
"62f57c385131", "62 f5 7c 38 51 31 vsqrtph (%ecx){1to16},%ymm6"},
|
|
|
|
// The scaled index: the SIB byte over the same displacement semantics,
|
|
// where EVEX.X carries the index's bit three. The compare row quotes
|
|
// the listing's indexed row outright; the arithmetic rows pin the bytes
|
|
// of {k7}-masked GNU rows, their mask bits riding the bits the layer
|
|
// leaves clear.
|
|
{"vcomish memory source over a scaled index", "VCOMISH",
|
|
[]ExtOperand{ExtScaledMemory(5, 14, 8, 0x10000000), ExtXmm(30)},
|
|
"62257c082fb4f500000010", "62 25 7c 08 2f b4 f5 00 00 00 10 vcomish 0x10000000(%rbp,%r14,8),%xmm30"},
|
|
{"vaddph memory source over a scaled index", "VADDPH",
|
|
[]ExtOperand{ExtZmm(29), ExtScaledMemory(5, 14, 8, 0x10000000), ExtZmm(30)},
|
|
"6225144058b4f500000010", "62 25 14 47 58 b4 f5 00 00 00 10 vaddph 0x10000000(%rbp,%r14,8),%zmm29,%zmm30{%k7} (the GNU row adds {k7})"},
|
|
{"vsqrtph memory source over a scaled index", "VSQRTPH",
|
|
[]ExtOperand{ExtScaledMemory(5, 14, 8, 0x10000000), ExtZmm(30)},
|
|
"62257c4851b4f500000010", "62 25 7c 4f 51 b4 f5 00 00 00 10 vsqrtph 0x10000000(%rbp,%r14,8),%zmm30{%k7} (the GNU row adds {k7})"},
|
|
|
|
// The BF16 memory forms: the dot product reads its second source and
|
|
// the narrow convert its full-width source from memory.
|
|
{"vdpbf16ps memory source", "VDPBF16PS",
|
|
[]ExtOperand{ExtZmm(5), ExtMemory(1, 127), ExtZmm(6)},
|
|
"62f2564852717f", "62 f2 56 48 52 71 7f vdpbf16ps 0x1fc0(%ecx),%zmm5,%zmm6 (Disp8(7f))"},
|
|
{"vdpbf16ps ymm memory source", "VDPBF16PS",
|
|
[]ExtOperand{ExtYmm(5), ExtMemory(1, 127), ExtYmm(6)},
|
|
"62f2562852717f", "62 f2 56 28 52 71 7f vdpbf16ps 0xfe0(%ecx),%ymm5,%ymm6 (Disp8(7f))"},
|
|
{"vdpbf16ps xmm memory source", "VDPBF16PS",
|
|
[]ExtOperand{ExtXmm(5), ExtMemory(1, 127), ExtXmm(6)},
|
|
"62f2560852717f", "62 f2 56 08 52 71 7f vdpbf16ps 0x7f0(%ecx),%xmm5,%xmm6 (Disp8(7f))"},
|
|
{"vcvtneps2bf16 memory source", "VCVTNEPS2BF16",
|
|
[]ExtOperand{ExtMemory(1, 127), ExtYmm(6)},
|
|
"62f27e4872717f", "62 f2 7e 48 72 71 7f vcvtneps2bf16 0x1fc0(%ecx),%ymm6 (Disp8(7f))"},
|
|
{"vcvtneps2bf16 ymm memory source", "VCVTNEPS2BF16",
|
|
[]ExtOperand{ExtMemory(1, 127), ExtXmm(6)},
|
|
"62f27e2872717f", "62 f2 7e 28 72 71 7f vcvtneps2bf16y 0xfe0(%ecx),%xmm6 (Disp8(7f))"},
|
|
// The 128-bit convert's memory row shares the 256-bit row's operand
|
|
// list, both destinations being XMM, so the resolver cannot tell them
|
|
// apart and the register row above pins the 128-bit template alone.
|
|
|
|
// The BF16 dot product's broadcast forms, the m16bcst spelling the
|
|
// manual gives beside the plain vector source: {1to16} on the 512-bit
|
|
// row of avx512_bf16.d, the VL rows from avx512_bf16_vl.d. The narrow
|
|
// convert takes no broadcast: its source is a full-width vector.
|
|
{"vdpbf16ps broadcast source", "VDPBF16PS",
|
|
[]ExtOperand{ExtZmm(5), ExtBroadcast(1, 0), ExtZmm(6)},
|
|
"62f256585231", "62 f2 56 58 52 31 vdpbf16ps (%ecx){1to16},%zmm5,%zmm6"},
|
|
{"vdpbf16ps ymm broadcast source", "VDPBF16PS",
|
|
[]ExtOperand{ExtYmm(5), ExtBroadcast(1, 0), ExtYmm(6)},
|
|
"62f256385231", "62 f2 56 38 52 31 vdpbf16ps (%ecx){1to8},%ymm5,%ymm6"},
|
|
{"vdpbf16ps xmm broadcast source", "VDPBF16PS",
|
|
[]ExtOperand{ExtXmm(5), ExtBroadcast(1, 0), ExtXmm(6)},
|
|
"62f256185231", "62 f2 56 18 52 31 vdpbf16ps (%ecx){1to4},%xmm5,%xmm6"},
|
|
|
|
// The remaining scalar memory forms: the scale and exponent extracts,
|
|
// the imm8-control group, and the integer converts, whose second
|
|
// source the manual spells r/m32. The W1 integer converts take the
|
|
// same operand list as the W0 ones, memory carrying no width to pick
|
|
// between them, so the memory rows pin the W0 templates and the W1
|
|
// entries rest on their register rows.
|
|
{"vscalefsh memory source", "VSCALEFSH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(9, 0), ExtXmm(30)},
|
|
"624615002d31", "62 46 15 00 2d 31 vscalefsh (%r9),%xmm29,%xmm30"},
|
|
{"vgetexpsh memory source", "VGETEXPSH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(9, 0), ExtXmm(30)},
|
|
"624615004331", "62 46 15 00 43 31 vgetexpsh (%r9),%xmm29,%xmm30"},
|
|
{"vgetexpsh memory source disp8", "VGETEXPSH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(1, 127), ExtXmm(30)},
|
|
"6266150043717f", "62 66 15 00 43 71 7f vgetexpsh 0xfe(%rcx),%xmm29,%xmm30 (Disp8(7f))"},
|
|
{"vcmpsh memory source", "VCMPSH",
|
|
[]ExtOperand{ExtImmediate(0x7b), ExtXmm(29), ExtMemory(9, 0), ExtMask(5)},
|
|
"62d31600c2297b", "62 d3 16 00 c2 29 7b vcmpsh $0x7b,(%r9),%xmm29,%k5"},
|
|
{"vcmpsh memory source disp8", "VCMPSH",
|
|
[]ExtOperand{ExtImmediate(0x7b), ExtXmm(29), ExtMemory(1, 127), ExtMask(5)},
|
|
"62f31600c2697f7b", "62 f3 16 00 c2 69 7f 7b vcmpsh $0x7b,0xfe(%rcx),%xmm29,%k5 (Disp8(7f))"},
|
|
{"vgetmantsh memory source", "VGETMANTSH",
|
|
[]ExtOperand{ExtImmediate(0x0b), ExtXmm(29), ExtMemory(9, 0), ExtXmm(30)},
|
|
"6243140027310b", "62 43 14 00 27 31 7b vgetmantsh $0x7b,(%r9),%xmm29,%xmm30 (opcode row only)"},
|
|
{"vreducesh memory source", "VREDUCESH",
|
|
[]ExtOperand{ExtImmediate(0x7b), ExtXmm(29), ExtMemory(9, 0), ExtXmm(30)},
|
|
"6243140057317b", "62 43 14 00 57 31 7b vreducesh $0x7b,(%r9),%xmm29,%xmm30"},
|
|
{"vrndscalesh memory source", "VRNDSCALESH",
|
|
[]ExtOperand{ExtImmediate(0x7b), ExtXmm(29), ExtMemory(9, 0), ExtXmm(30)},
|
|
"624314000a317b", "62 43 14 00 0a 31 7b vrndscalesh $0x7b,(%r9),%xmm29,%xmm30"},
|
|
{"vcvtsi2sh memory source", "VCVTSI2SH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(9, 0), ExtXmm(30)},
|
|
"624516002a31", "62 45 16 00 2a 31 vcvtsi2shl (%r9),%xmm29,%xmm30"},
|
|
{"vcvtusi2sh memory source", "VCVTUSI2SH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(9, 0), ExtXmm(30)},
|
|
"624516007b31", "62 45 16 00 7b 31 vcvtusi2shl (%r9),%xmm29,%xmm30"},
|
|
|
|
// High registers in a 512-bit form exercise the EVEX extension bits:
|
|
// with both sources above 15 the B bar and X bar bits clear, while the
|
|
// destination zmm23 keeps R bar set in byte one (derived from the
|
|
// proven class above).
|
|
{"vcvtne2ps2bf16 high registers", "VCVTNE2PS2BF16",
|
|
[]ExtOperand{ExtZmm(21), ExtZmm(20), ExtZmm(23)},
|
|
"62a2574072fc", ""},
|
|
|
|
// The write mask, the SDM's {k1}{z} decorations on the packed
|
|
// destinations: EVEX.aaa carries the masking register, EVEX.z the
|
|
// zeroing bit, laid over the words the unmasked rows above prove byte
|
|
// for byte (the x86-64-avx512_fp16.d and avx512_bf16.d listings carry
|
|
// the same {k7}{z} rows). Zeroing keeps the destination's inactive
|
|
// lanes no longer: they become zeros.
|
|
{"vaddph k7 zeroing", "VADDPH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtWriteMasked(ExtZmm(30), 7, true)},
|
|
"620514c758f4", ""},
|
|
{"vaddph k1 merging", "VADDPH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtWriteMasked(ExtZmm(30), 1, false)},
|
|
"6205144158f4", ""},
|
|
{"vaddph k7 zeroing, memory source", "VADDPH",
|
|
[]ExtOperand{ExtZmm(28), ExtMemory(9, 0), ExtWriteMasked(ExtZmm(30), 7, true)},
|
|
"62451cc75831", ""},
|
|
{"vcvtne2ps2bf16 k7 zeroing", "VCVTNE2PS2BF16",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(4), ExtWriteMasked(ExtZmm(6), 7, true)},
|
|
"62f257cf72f4", ""},
|
|
{"vdpbf16ps k5 merging", "VDPBF16PS",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(4), ExtWriteMasked(ExtZmm(6), 5, false)},
|
|
"62f2564d52f4", ""},
|
|
{"vcvtneps2bf16 k6 merging", "VCVTNEPS2BF16",
|
|
[]ExtOperand{ExtYmm(5), ExtWriteMasked(ExtXmm(6), 6, false)},
|
|
"62f27e2e72f5", ""},
|
|
{"vsqrtph k3 zeroing", "VSQRTPH",
|
|
[]ExtOperand{ExtZmm(29), ExtWriteMasked(ExtZmm(30), 3, true)},
|
|
"62057ccb51f5", ""},
|
|
|
|
// The embedded rounding and the exception suppression, the EVEX.RC
|
|
// decorations the FP destinations of the 512-bit and the scalar register
|
|
// forms carry: EVEX.b selects the rounding context and EVEX.RC replaces
|
|
// L'L, naming the mode 00 nearest even through 11 toward zero in the very
|
|
// encoding the imm8 round control shares. Every row is quoted from the
|
|
// local GNU assembler's own output, whose FP16 table matches the SDM
|
|
// entry for entry; the AT&T listings spell the decoration ahead of the
|
|
// operands. The write mask composes under the decoration, its EVEX.aaa
|
|
// and EVEX.z bits untouched by EVEX.RC.
|
|
{"vaddph rn-sae", "VADDPH",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(4), ExtRounded(ExtZmm(6), ExtRoundNearest)},
|
|
"62f5541858f4", "62 f5 54 18 58 f4 vaddph {rn-sae},%zmm4,%zmm5,%zmm6"},
|
|
{"vaddph rd-sae", "VADDPH",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(4), ExtRounded(ExtZmm(6), ExtRoundDown)},
|
|
"62f5543858f4", "62 f5 54 38 58 f4 vaddph {rd-sae},%zmm4,%zmm5,%zmm6"},
|
|
{"vaddph ru-sae", "VADDPH",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(4), ExtRounded(ExtZmm(6), ExtRoundUp)},
|
|
"62f5545858f4", "62 f5 54 58 58 f4 vaddph {ru-sae},%zmm4,%zmm5,%zmm6"},
|
|
{"vaddph rz-sae", "VADDPH",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(4), ExtRounded(ExtZmm(6), ExtRoundTruncate)},
|
|
"62f5547858f4", "62 f5 54 78 58 f4 vaddph {rz-sae},%zmm4,%zmm5,%zmm6"},
|
|
{"vaddph rz-sae under k7", "VADDPH",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(4), ExtRounded(ExtWriteMasked(ExtZmm(6), 7, false), ExtRoundTruncate)},
|
|
"62f5547f58f4", "62 f5 54 7f 58 f4 vaddph {rz-sae},%zmm4,%zmm5,%zmm6{%k7}"},
|
|
{"vaddph rz-sae under k7, zeroing", "VADDPH",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(4), ExtRounded(ExtWriteMasked(ExtZmm(6), 7, true), ExtRoundTruncate)},
|
|
"62f554ff58f4", "62 f5 54 ff 58 f4 vaddph {rz-sae},%zmm4,%zmm5,%zmm6{%k7}{z}"},
|
|
{"vaddph rz-sae, high registers", "VADDPH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtRounded(ExtZmm(30), ExtRoundTruncate)},
|
|
"6205147058f4", "62 05 14 70 58 f4 vaddph {rz-sae},%zmm28,%zmm29,%zmm30"},
|
|
{"vsubph rz-sae", "VSUBPH",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(4), ExtRounded(ExtZmm(6), ExtRoundTruncate)},
|
|
"62f554785cf4", "62 f5 54 78 5c f4 vsubph {rz-sae},%zmm4,%zmm5,%zmm6"},
|
|
{"vmulph rn-sae", "VMULPH",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(4), ExtRounded(ExtZmm(6), ExtRoundNearest)},
|
|
"62f5541859f4", "62 f5 54 18 59 f4 vmulph {rn-sae},%zmm4,%zmm5,%zmm6"},
|
|
{"vdivph rn-sae", "VDIVPH",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(4), ExtRounded(ExtZmm(6), ExtRoundNearest)},
|
|
"62f554185ef4", "62 f5 54 18 5e f4 vdivph {rn-sae},%zmm4,%zmm5,%zmm6"},
|
|
{"vminph sae", "VMINPH",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(4), ExtRounded(ExtZmm(6), ExtRoundSAE)},
|
|
"62f554185df4", "62 f5 54 18 5d f4 vminph {sae},%zmm4,%zmm5,%zmm6"},
|
|
{"vminph sae, high registers", "VMINPH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtRounded(ExtZmm(30), ExtRoundSAE)},
|
|
"620514105df4", "62 05 14 10 5d f4 vminph {sae},%zmm28,%zmm29,%zmm30"},
|
|
{"vmaxph sae", "VMAXPH",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(4), ExtRounded(ExtZmm(6), ExtRoundSAE)},
|
|
"62f554185ff4", "62 f5 54 18 5f f4 vmaxph {sae},%zmm4,%zmm5,%zmm6"},
|
|
{"vsqrtph rz-sae", "VSQRTPH",
|
|
[]ExtOperand{ExtZmm(4), ExtRounded(ExtZmm(5), ExtRoundTruncate)},
|
|
"62f57c7851ec", "62 f5 7c 78 51 ec vsqrtph {rz-sae},%zmm4,%zmm5"},
|
|
{"vaddsh rn-sae", "VADDSH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtRounded(ExtXmm(6), ExtRoundNearest)},
|
|
"62f5561858f4", "62 f5 56 18 58 f4 vaddsh {rn-sae},%xmm4,%xmm5,%xmm6"},
|
|
{"vaddsh rz-sae, high registers", "VADDSH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtRounded(ExtXmm(30), ExtRoundTruncate)},
|
|
"6205167058f4", "62 05 16 70 58 f4 vaddsh {rz-sae},%xmm28,%xmm29,%xmm30"},
|
|
{"vsubsh rd-sae", "VSUBSH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtRounded(ExtXmm(6), ExtRoundDown)},
|
|
"62f556385cf4", "62 f5 56 38 5c f4 vsubsh {rd-sae},%xmm4,%xmm5,%xmm6"},
|
|
{"vmulsh ru-sae", "VMULSH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtRounded(ExtXmm(6), ExtRoundUp)},
|
|
"62f5565859f4", "62 f5 56 58 59 f4 vmulsh {ru-sae},%xmm4,%xmm5,%xmm6"},
|
|
{"vdivsh rz-sae", "VDIVSH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtRounded(ExtXmm(6), ExtRoundTruncate)},
|
|
"62f556785ef4", "62 f5 56 78 5e f4 vdivsh {rz-sae},%xmm4,%xmm5,%xmm6"},
|
|
{"vminsh sae", "VMINSH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtRounded(ExtXmm(6), ExtRoundSAE)},
|
|
"62f556185df4", "62 f5 56 18 5d f4 vminsh {sae},%xmm4,%xmm5,%xmm6"},
|
|
{"vmaxsh sae", "VMAXSH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtRounded(ExtXmm(6), ExtRoundSAE)},
|
|
"62f556185ff4", "62 f5 56 18 5f f4 vmaxsh {sae},%xmm4,%xmm5,%xmm6"},
|
|
{"vsqrtsh rz-sae", "VSQRTSH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtRounded(ExtXmm(6), ExtRoundTruncate)},
|
|
"62f5567851f4", "62 f5 56 78 51 f4 vsqrtsh {rz-sae},%xmm4,%xmm5,%xmm6"},
|
|
{"vsqrtsh ru-sae, high registers", "VSQRTSH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtRounded(ExtXmm(30), ExtRoundUp)},
|
|
"6205165051f4", "62 05 16 50 51 f4 vsqrtsh {ru-sae},%xmm28,%xmm29,%xmm30"},
|
|
{"vscalefsh rn-sae", "VSCALEFSH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtRounded(ExtXmm(6), ExtRoundNearest)},
|
|
"62f655182df4", "62 f6 55 18 2d f4 vscalefsh {rn-sae},%xmm4,%xmm5,%xmm6"},
|
|
{"vgetexpsh sae", "VGETEXPSH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtRounded(ExtXmm(6), ExtRoundSAE)},
|
|
"62f6551843f4", "62 f6 55 18 43 f4 vgetexpsh {sae},%xmm4,%xmm5,%xmm6"},
|
|
{"vcomish sae", "VCOMISH",
|
|
[]ExtOperand{ExtXmm(29), ExtRounded(ExtXmm(30), ExtRoundSAE)},
|
|
"62057c182ff5", "62 05 7c 18 2f f5 vcomish {sae},%xmm29,%xmm30"},
|
|
{"vucomish sae", "VUCOMISH",
|
|
[]ExtOperand{ExtXmm(29), ExtRounded(ExtXmm(30), ExtRoundSAE)},
|
|
"62057c182ef5", "62 05 7c 18 2e f5 vucomish {sae},%xmm29,%xmm30"},
|
|
{"vcvtss2sh rn-sae", "VCVTSS2SH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtRounded(ExtXmm(6), ExtRoundNearest)},
|
|
"62f554181df4", "62 f5 54 18 1d f4 vcvtss2sh {rn-sae},%xmm4,%xmm5,%xmm6"},
|
|
{"vcvtsd2sh rd-sae, high registers", "VCVTSD2SH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtRounded(ExtXmm(30), ExtRoundDown)},
|
|
"620597305af4", "62 05 97 30 5a f4 vcvtsd2sh {rd-sae},%xmm28,%xmm29,%xmm30"},
|
|
{"vcvtsi2sh rn-sae, 32-bit", "VCVTSI2SH",
|
|
[]ExtOperand{ExtXmm(5), ExtGpr32(0), ExtRounded(ExtXmm(6), ExtRoundNearest)},
|
|
"62f556182af0", "62 f5 56 18 2a f0 vcvtsi2sh %eax,{rn-sae},%xmm5,%xmm6"},
|
|
{"vcvtsi2sh rz-sae, 64-bit, high registers", "VCVTSI2SH",
|
|
[]ExtOperand{ExtXmm(29), ExtGpr64(12), ExtRounded(ExtXmm(30), ExtRoundTruncate)},
|
|
"624596702af4", "62 45 96 70 2a f4 vcvtsi2sh %r12,{rz-sae},%xmm29,%xmm30"},
|
|
{"vcvtusi2sh ru-sae, 32-bit", "VCVTUSI2SH",
|
|
[]ExtOperand{ExtXmm(5), ExtGpr32(2), ExtRounded(ExtXmm(6), ExtRoundUp)},
|
|
"62f556587bf2", "62 f5 56 58 7b f2 vcvtusi2sh %edx,{ru-sae},%xmm5,%xmm6"},
|
|
{"vcvtusi2sh rd-sae, 64-bit, high registers", "VCVTUSI2SH",
|
|
[]ExtOperand{ExtXmm(29), ExtGpr64(12), ExtRounded(ExtXmm(30), ExtRoundDown)},
|
|
"624596307bf4", "62 45 96 30 7b f4 vcvtusi2sh %r12,{rd-sae},%xmm29,%xmm30"},
|
|
|
|
// The FP16 packed conversions, the fourteen directions between the FP16
|
|
// lanes and the integer and double-precision companions. The register
|
|
// rows and the rounding rows are quoted from the local GNU assembler's
|
|
// output; the memory rows follow the listing's full-width and broadcast
|
|
// spellings, whose source displacements are N times the plain SDM
|
|
// displacement the disp8 bytes carry under the assembler's compressed
|
|
// displacement scaling, and the rows with no GNU line are derived: the
|
|
// plain full-width load of a narrowing convert the AT&T syntax cannot
|
|
// spell without a size hint, laid out by the broadcast row minus EVEX.b.
|
|
{"vcvtph2w zmm", "VCVTPH2W",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(6)},
|
|
"62f57d487df5", "62 f5 7d 48 7d f5 vcvtph2w %zmm5,%zmm6"},
|
|
{"vcvtph2w ymm", "VCVTPH2W",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(6)},
|
|
"62f57d287df5", "62 f5 7d 28 7d f5 vcvtph2w %ymm5,%ymm6"},
|
|
{"vcvtph2w xmm", "VCVTPH2W",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(6)},
|
|
"62f57d087df5", "62 f5 7d 08 7d f5 vcvtph2w %xmm5,%xmm6"},
|
|
{"vcvtph2uw zmm", "VCVTPH2UW",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(6)},
|
|
"62f57c487df5", "62 f5 7c 48 7d f5 vcvtph2uw %zmm5,%zmm6"},
|
|
{"vcvtph2uw ymm", "VCVTPH2UW",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(6)},
|
|
"62f57c287df5", "62 f5 7c 28 7d f5 vcvtph2uw %ymm5,%ymm6"},
|
|
{"vcvtph2uw xmm", "VCVTPH2UW",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(6)},
|
|
"62f57c087df5", "62 f5 7c 08 7d f5 vcvtph2uw %xmm5,%xmm6"},
|
|
{"vcvtw2ph zmm", "VCVTW2PH",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(6)},
|
|
"62f57e487df5", "62 f5 7e 48 7d f5 vcvtw2ph %zmm5,%zmm6"},
|
|
{"vcvtw2ph ymm", "VCVTW2PH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(6)},
|
|
"62f57e287df5", "62 f5 7e 28 7d f5 vcvtw2ph %ymm5,%ymm6"},
|
|
{"vcvtw2ph xmm", "VCVTW2PH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(6)},
|
|
"62f57e087df5", "62 f5 7e 08 7d f5 vcvtw2ph %xmm5,%xmm6"},
|
|
{"vcvtuw2ph zmm", "VCVTUW2PH",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(6)},
|
|
"62f57f487df5", "62 f5 7f 48 7d f5 vcvtuw2ph %zmm5,%zmm6"},
|
|
{"vcvtuw2ph ymm", "VCVTUW2PH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(6)},
|
|
"62f57f287df5", "62 f5 7f 28 7d f5 vcvtuw2ph %ymm5,%ymm6"},
|
|
{"vcvtuw2ph xmm", "VCVTUW2PH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(6)},
|
|
"62f57f087df5", "62 f5 7f 08 7d f5 vcvtuw2ph %xmm5,%xmm6"},
|
|
{"vcvtph2dq zmm", "VCVTPH2DQ",
|
|
[]ExtOperand{ExtYmm(5), ExtZmm(6)},
|
|
"62f57d485bf5", "62 f5 7d 48 5b f5 vcvtph2dq %ymm5,%zmm6"},
|
|
{"vcvtph2dq ymm", "VCVTPH2DQ",
|
|
[]ExtOperand{ExtXmm(5), ExtYmm(6)},
|
|
"62f57d285bf5", "62 f5 7d 28 5b f5 vcvtph2dq %xmm5,%ymm6"},
|
|
{"vcvtph2dq xmm", "VCVTPH2DQ",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(6)},
|
|
"62f57d085bf5", "62 f5 7d 08 5b f5 vcvtph2dq %xmm5,%xmm6"},
|
|
{"vcvtph2udq zmm", "VCVTPH2UDQ",
|
|
[]ExtOperand{ExtYmm(5), ExtZmm(6)},
|
|
"62f57c4879f5", "62 f5 7c 48 79 f5 vcvtph2udq %ymm5,%zmm6"},
|
|
{"vcvtph2udq ymm", "VCVTPH2UDQ",
|
|
[]ExtOperand{ExtXmm(5), ExtYmm(6)},
|
|
"62f57c2879f5", "62 f5 7c 28 79 f5 vcvtph2udq %xmm5,%ymm6"},
|
|
{"vcvtph2udq xmm", "VCVTPH2UDQ",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(6)},
|
|
"62f57c0879f5", "62 f5 7c 08 79 f5 vcvtph2udq %xmm5,%xmm6"},
|
|
{"vcvtdq2ph zmm to ymm", "VCVTDQ2PH",
|
|
[]ExtOperand{ExtZmm(5), ExtYmm(6)},
|
|
"62f57c485bf5", "62 f5 7c 48 5b f5 vcvtdq2ph %zmm5,%ymm6"},
|
|
{"vcvtdq2ph ymm to xmm", "VCVTDQ2PH",
|
|
[]ExtOperand{ExtYmm(5), ExtXmm(6)},
|
|
"62f57c285bf5", "62 f5 7c 28 5b f5 vcvtdq2ph %ymm5,%xmm6"},
|
|
{"vcvtdq2ph xmm to xmm", "VCVTDQ2PH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(6)},
|
|
"62f57c085bf5", "62 f5 7c 08 5b f5 vcvtdq2ph %xmm5,%xmm6"},
|
|
{"vcvtudq2ph zmm to ymm", "VCVTUDQ2PH",
|
|
[]ExtOperand{ExtZmm(5), ExtYmm(6)},
|
|
"62f57f487af5", "62 f5 7f 48 7a f5 vcvtudq2ph %zmm5,%ymm6"},
|
|
{"vcvtudq2ph ymm to xmm", "VCVTUDQ2PH",
|
|
[]ExtOperand{ExtYmm(5), ExtXmm(6)},
|
|
"62f57f287af5", "62 f5 7f 28 7a f5 vcvtudq2ph %ymm5,%xmm6"},
|
|
{"vcvtudq2ph xmm to xmm", "VCVTUDQ2PH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(6)},
|
|
"62f57f087af5", "62 f5 7f 08 7a f5 vcvtudq2ph %xmm5,%xmm6"},
|
|
{"vcvtph2qq zmm", "VCVTPH2QQ",
|
|
[]ExtOperand{ExtXmm(5), ExtZmm(6)},
|
|
"62f57d487bf5", "62 f5 7d 48 7b f5 vcvtph2qq %xmm5,%zmm6"},
|
|
{"vcvtph2qq ymm", "VCVTPH2QQ",
|
|
[]ExtOperand{ExtXmm(5), ExtYmm(6)},
|
|
"62f57d287bf5", "62 f5 7d 28 7b f5 vcvtph2qq %xmm5,%ymm6"},
|
|
{"vcvtph2qq xmm", "VCVTPH2QQ",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(6)},
|
|
"62f57d087bf5", "62 f5 7d 08 7b f5 vcvtph2qq %xmm5,%xmm6"},
|
|
{"vcvtph2uqq zmm", "VCVTPH2UQQ",
|
|
[]ExtOperand{ExtXmm(5), ExtZmm(6)},
|
|
"62f57d4879f5", "62 f5 7d 48 79 f5 vcvtph2uqq %xmm5,%zmm6"},
|
|
{"vcvtph2uqq ymm", "VCVTPH2UQQ",
|
|
[]ExtOperand{ExtXmm(5), ExtYmm(6)},
|
|
"62f57d2879f5", "62 f5 7d 28 79 f5 vcvtph2uqq %xmm5,%ymm6"},
|
|
{"vcvtph2uqq xmm", "VCVTPH2UQQ",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(6)},
|
|
"62f57d0879f5", "62 f5 7d 08 79 f5 vcvtph2uqq %xmm5,%xmm6"},
|
|
{"vcvtqq2ph zmm to xmm", "VCVTQQ2PH",
|
|
[]ExtOperand{ExtZmm(5), ExtXmm(6)},
|
|
"62f5fc485bf5", "62 f5 fc 48 5b f5 vcvtqq2ph %zmm5,%xmm6"},
|
|
{"vcvtqq2ph ymm to xmm", "VCVTQQ2PH",
|
|
[]ExtOperand{ExtYmm(5), ExtXmm(6)},
|
|
"62f5fc285bf5", "62 f5 fc 28 5b f5 vcvtqq2ph %ymm5,%xmm6"},
|
|
{"vcvtqq2ph xmm to xmm", "VCVTQQ2PH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(6)},
|
|
"62f5fc085bf5", "62 f5 fc 08 5b f5 vcvtqq2ph %xmm5,%xmm6"},
|
|
{"vcvtuqq2ph zmm to xmm", "VCVTUQQ2PH",
|
|
[]ExtOperand{ExtZmm(5), ExtXmm(6)},
|
|
"62f5ff487af5", "62 f5 ff 48 7a f5 vcvtuqq2ph %zmm5,%xmm6"},
|
|
{"vcvtuqq2ph ymm to xmm", "VCVTUQQ2PH",
|
|
[]ExtOperand{ExtYmm(5), ExtXmm(6)},
|
|
"62f5ff287af5", "62 f5 ff 28 7a f5 vcvtuqq2ph %ymm5,%xmm6"},
|
|
{"vcvtuqq2ph xmm to xmm", "VCVTUQQ2PH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(6)},
|
|
"62f5ff087af5", "62 f5 ff 08 7a f5 vcvtuqq2ph %xmm5,%xmm6"},
|
|
{"vcvtph2pd zmm", "VCVTPH2PD",
|
|
[]ExtOperand{ExtXmm(5), ExtZmm(6)},
|
|
"62f57c485af5", "62 f5 7c 48 5a f5 vcvtph2pd %xmm5,%zmm6"},
|
|
{"vcvtph2pd ymm", "VCVTPH2PD",
|
|
[]ExtOperand{ExtXmm(5), ExtYmm(6)},
|
|
"62f57c285af5", "62 f5 7c 28 5a f5 vcvtph2pd %xmm5,%ymm6"},
|
|
{"vcvtph2pd xmm", "VCVTPH2PD",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(6)},
|
|
"62f57c085af5", "62 f5 7c 08 5a f5 vcvtph2pd %xmm5,%xmm6"},
|
|
{"vcvtpd2ph zmm to xmm", "VCVTPD2PH",
|
|
[]ExtOperand{ExtZmm(5), ExtXmm(6)},
|
|
"62f5fd485af5", "62 f5 fd 48 5a f5 vcvtpd2ph %zmm5,%xmm6"},
|
|
{"vcvtpd2ph ymm to xmm", "VCVTPD2PH",
|
|
[]ExtOperand{ExtYmm(5), ExtXmm(6)},
|
|
"62f5fd285af5", "62 f5 fd 28 5a f5 vcvtpd2ph %ymm5,%xmm6"},
|
|
{"vcvtpd2ph xmm to xmm", "VCVTPD2PH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(6)},
|
|
"62f5fd085af5", "62 f5 fd 08 5a f5 vcvtpd2ph %xmm5,%xmm6"},
|
|
|
|
// The rounding rows of the converting directions: the FP16-to-integer
|
|
// and the integer-to-FP16 conversions round and take EVEX.RC on their
|
|
// 512-bit register forms, exactly as the arithmetic does, and VCVTPH2PD,
|
|
// which widens exactly, takes none.
|
|
{"vcvtph2w rn-sae", "VCVTPH2W",
|
|
[]ExtOperand{ExtZmm(5), ExtRounded(ExtZmm(6), ExtRoundNearest)},
|
|
"62f57d187df5", "62 f5 7d 18 7d f5 vcvtph2w {rn-sae},%zmm5,%zmm6"},
|
|
{"vcvtph2uw rz-sae", "VCVTPH2UW",
|
|
[]ExtOperand{ExtZmm(5), ExtRounded(ExtZmm(6), ExtRoundTruncate)},
|
|
"62f57c787df5", "62 f5 7c 78 7d f5 vcvtph2uw {rz-sae},%zmm5,%zmm6"},
|
|
{"vcvtph2dq rn-sae", "VCVTPH2DQ",
|
|
[]ExtOperand{ExtYmm(5), ExtRounded(ExtZmm(6), ExtRoundNearest)},
|
|
"62f57d185bf5", "62 f5 7d 18 5b f5 vcvtph2dq {rn-sae},%ymm5,%zmm6"},
|
|
{"vcvtph2udq rn-sae", "VCVTPH2UDQ",
|
|
[]ExtOperand{ExtYmm(5), ExtRounded(ExtZmm(6), ExtRoundNearest)},
|
|
"62f57c1879f5", "62 f5 7c 18 79 f5 vcvtph2udq {rn-sae},%ymm5,%zmm6"},
|
|
{"vcvtph2qq rz-sae", "VCVTPH2QQ",
|
|
[]ExtOperand{ExtXmm(5), ExtRounded(ExtZmm(6), ExtRoundTruncate)},
|
|
"62f57d787bf5", "62 f5 7d 78 7b f5 vcvtph2qq {rz-sae},%xmm5,%zmm6"},
|
|
{"vcvtph2uqq rz-sae", "VCVTPH2UQQ",
|
|
[]ExtOperand{ExtXmm(5), ExtRounded(ExtZmm(6), ExtRoundTruncate)},
|
|
"62f57d7879f5", "62 f5 7d 78 79 f5 vcvtph2uqq {rz-sae},%xmm5,%zmm6"},
|
|
{"vcvtw2ph rz-sae", "VCVTW2PH",
|
|
[]ExtOperand{ExtZmm(5), ExtRounded(ExtZmm(6), ExtRoundTruncate)},
|
|
"62f57e787df5", "62 f5 7e 78 7d f5 vcvtw2ph {rz-sae},%zmm5,%zmm6"},
|
|
{"vcvtuw2ph rn-sae", "VCVTUW2PH",
|
|
[]ExtOperand{ExtZmm(5), ExtRounded(ExtZmm(6), ExtRoundNearest)},
|
|
"62f57f187df5", "62 f5 7f 18 7d f5 vcvtuw2ph {rn-sae},%zmm5,%zmm6"},
|
|
{"vcvtdq2ph rn-sae", "VCVTDQ2PH",
|
|
[]ExtOperand{ExtZmm(5), ExtRounded(ExtYmm(6), ExtRoundNearest)},
|
|
"62f57c185bf5", "62 f5 7c 18 5b f5 vcvtdq2ph {rn-sae},%zmm5,%ymm6"},
|
|
{"vcvtudq2ph ru-sae", "VCVTUDQ2PH",
|
|
[]ExtOperand{ExtZmm(5), ExtRounded(ExtYmm(6), ExtRoundUp)},
|
|
"62f57f587af5", "62 f5 7f 58 7a f5 vcvtudq2ph {ru-sae},%zmm5,%ymm6"},
|
|
{"vcvtqq2ph rz-sae", "VCVTQQ2PH",
|
|
[]ExtOperand{ExtZmm(5), ExtRounded(ExtXmm(6), ExtRoundTruncate)},
|
|
"62f5fc785bf5", "62 f5 fc 78 5b f5 vcvtqq2ph {rz-sae},%zmm5,%xmm6"},
|
|
{"vcvtuqq2ph rd-sae", "VCVTUQQ2PH",
|
|
[]ExtOperand{ExtZmm(5), ExtRounded(ExtXmm(6), ExtRoundDown)},
|
|
"62f5ff387af5", "62 f5 ff 38 7a f5 vcvtuqq2ph {rd-sae},%zmm5,%xmm6"},
|
|
{"vcvtpd2ph rz-sae", "VCVTPD2PH",
|
|
[]ExtOperand{ExtZmm(5), ExtRounded(ExtXmm(6), ExtRoundTruncate)},
|
|
"62f5fd785af5", "62 f5 fd 78 5a f5 vcvtpd2ph {rz-sae},%zmm5,%xmm6"},
|
|
|
|
// High registers across the conversion shapes, exercising every EVEX
|
|
// extension bit: the source above 15 clears B bar and X bar, the
|
|
// destination above 15 R bar.
|
|
{"vcvtph2w, high registers", "VCVTPH2W",
|
|
[]ExtOperand{ExtZmm(28), ExtZmm(29)},
|
|
"62057d487dec", "62 05 7d 48 7d ec vcvtph2w %zmm28,%zmm29"},
|
|
{"vcvtph2dq, high registers", "VCVTPH2DQ",
|
|
[]ExtOperand{ExtYmm(28), ExtZmm(29)},
|
|
"62057d485bec", "62 05 7d 48 5b ec vcvtph2dq %ymm28,%zmm29"},
|
|
{"vcvtdq2ph, high registers", "VCVTDQ2PH",
|
|
[]ExtOperand{ExtZmm(29), ExtYmm(30)},
|
|
"62057c485bf5", "62 05 7c 48 5b f5 vcvtdq2ph %zmm29,%ymm30"},
|
|
{"vcvtph2qq, high registers", "VCVTPH2QQ",
|
|
[]ExtOperand{ExtXmm(28), ExtZmm(29)},
|
|
"62057d487bec", "62 05 7d 48 7b ec vcvtph2qq %xmm28,%zmm29"},
|
|
{"vcvtpd2ph, high registers", "VCVTPD2PH",
|
|
[]ExtOperand{ExtZmm(28), ExtXmm(29)},
|
|
"6205fd485aec", "62 05 fd 48 5a ec vcvtpd2ph %zmm28,%xmm29"},
|
|
|
|
// The memory forms of the conversions: the FP16 sources read full-width
|
|
// vectors, the integer sources their elements under the broadcast. The
|
|
// disp8 rows quote the listing's compressed spellings, whose source is N
|
|
// times the plain displacement the bytes carry.
|
|
{"vcvtph2w memory source", "VCVTPH2W",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtZmm(30)},
|
|
"62457d487d31", "62 45 7d 48 7d 31 vcvtph2w (%r9),%zmm30"},
|
|
{"vcvtph2w memory source disp8", "VCVTPH2W",
|
|
[]ExtOperand{ExtMemory(1, 127), ExtZmm(30)},
|
|
"62657d487d717f", "62 65 7d 48 7d 71 7f vcvtph2w 0x1fc0(%rcx),%zmm30 (Disp8(7f))"},
|
|
{"vcvtph2w ymm memory source", "VCVTPH2W",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtYmm(30)},
|
|
"62457d287d31", "62 45 7d 28 7d 31 vcvtph2w (%r9),%ymm30"},
|
|
{"vcvtph2w xmm memory source", "VCVTPH2W",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtXmm(30)},
|
|
"62457d087d31", "62 45 7d 08 7d 31 vcvtph2w (%r9),%xmm30"},
|
|
{"vcvtph2uw memory source", "VCVTPH2UW",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtZmm(30)},
|
|
"62457c487d31", "62 45 7c 48 7d 31 vcvtph2uw (%r9),%zmm30"},
|
|
{"vcvtw2ph memory source", "VCVTW2PH",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtZmm(30)},
|
|
"62457e487d31", "62 45 7e 48 7d 31 vcvtw2ph (%r9),%zmm30"},
|
|
{"vcvtw2ph ymm memory source", "VCVTW2PH",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtYmm(30)},
|
|
"62457e287d31", "62 45 7e 28 7d 31 vcvtw2ph (%r9),%ymm30"},
|
|
{"vcvtph2dq memory source", "VCVTPH2DQ",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtZmm(30)},
|
|
"62457d485b31", "62 45 7d 48 5b 31 vcvtph2dq (%r9),%zmm30"},
|
|
{"vcvtph2dq memory source disp8", "VCVTPH2DQ",
|
|
[]ExtOperand{ExtMemory(1, 127), ExtZmm(30)},
|
|
"62657d485b717f", "62 65 7d 48 5b 71 7f vcvtph2dq 0xfe0(%rcx),%zmm30 (Disp8(7f))"},
|
|
{"vcvtph2dq ymm memory source", "VCVTPH2DQ",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtYmm(30)},
|
|
"62457d285b31", "62 45 7d 28 5b 31 vcvtph2dq (%r9),%ymm30"},
|
|
{"vcvtph2udq memory source", "VCVTPH2UDQ",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtZmm(30)},
|
|
"62457c487931", "62 45 7c 48 79 31 vcvtph2udq (%r9),%zmm30"},
|
|
{"vcvtdq2ph memory source", "VCVTDQ2PH",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtYmm(30)},
|
|
"62457c485b31", "62 45 7c 48 5b 31 vcvtdq2ph (%r9),%ymm30"},
|
|
{"vcvtph2qq memory source", "VCVTPH2QQ",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtZmm(30)},
|
|
"62457d487b31", "62 45 7d 48 7b 31 vcvtph2qq (%r9),%zmm30"},
|
|
{"vcvtph2qq memory source disp8", "VCVTPH2QQ",
|
|
[]ExtOperand{ExtMemory(1, 127), ExtZmm(30)},
|
|
"62657d487b717f", "62 65 7d 48 7b 71 7f vcvtph2qq 0x7f0(%rcx),%zmm30 (Disp8(7f))"},
|
|
{"vcvtph2qq ymm memory source", "VCVTPH2QQ",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtYmm(30)},
|
|
"62457d287b31", "62 45 7d 28 7b 31 vcvtph2qq (%r9),%ymm30"},
|
|
{"vcvtph2uqq memory source", "VCVTPH2UQQ",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtZmm(30)},
|
|
"62457d487931", "62 45 7d 48 79 31 vcvtph2uqq (%r9),%zmm30"},
|
|
{"vcvtph2pd memory source", "VCVTPH2PD",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtZmm(30)},
|
|
"62457c485a31", "62 45 7c 48 5a 31 vcvtph2pd (%r9),%zmm30"},
|
|
{"vcvtph2pd memory source disp8", "VCVTPH2PD",
|
|
[]ExtOperand{ExtMemory(1, 127), ExtZmm(30)},
|
|
"62657c485a717f", "62 65 7c 48 5a 71 7f vcvtph2pd 0x7f0(%rcx),%zmm30 (Disp8(7f))"},
|
|
{"vcvtph2pd ymm memory source", "VCVTPH2PD",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtYmm(30)},
|
|
"62457c285a31", "62 45 7c 28 5a 31 vcvtph2pd (%r9),%ymm30"},
|
|
{"vcvtqq2ph plain memory source", "VCVTQQ2PH",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtXmm(30)},
|
|
"6245fc485b31", ""},
|
|
{"vcvtuqq2ph plain memory source", "VCVTUQQ2PH",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtXmm(30)},
|
|
"6245ff487a31", ""},
|
|
{"vcvtpd2ph plain memory source", "VCVTPD2PH",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtXmm(30)},
|
|
"6245fd485a31", ""},
|
|
|
|
// The broadcast forms of the converting sources: a single element the
|
|
// hardware splats across the lanes, one word, dword or qword as the
|
|
// direction's input element spells it.
|
|
{"vcvtw2ph broadcast source", "VCVTW2PH",
|
|
[]ExtOperand{ExtBroadcast(9, 0), ExtZmm(30)},
|
|
"62457e587d31", "62 45 7e 58 7d 31 vcvtw2ph (%r9){1to32},%zmm30"},
|
|
{"vcvtw2ph broadcast source disp8", "VCVTW2PH",
|
|
[]ExtOperand{ExtBroadcast(1, 127), ExtZmm(30)},
|
|
"62657e587d717f", "62 65 7e 58 7d 71 7f vcvtw2ph 0xfe(%rcx){1to32},%zmm30 (Disp8(7f))"},
|
|
{"vcvtuw2ph broadcast source", "VCVTUW2PH",
|
|
[]ExtOperand{ExtBroadcast(9, 0), ExtZmm(30)},
|
|
"62457f587d31", "62 45 7f 58 7d 31 vcvtuw2ph (%r9){1to32},%zmm30"},
|
|
{"vcvtuw2ph broadcast source disp8", "VCVTUW2PH",
|
|
[]ExtOperand{ExtBroadcast(1, 127), ExtZmm(30)},
|
|
"62657f587d717f", "62 65 7f 58 7d 71 7f vcvtuw2ph 0xfe(%rcx){1to32},%zmm30 (Disp8(7f))"},
|
|
{"vcvtdq2ph broadcast source", "VCVTDQ2PH",
|
|
[]ExtOperand{ExtBroadcast(9, 0), ExtYmm(30)},
|
|
"62457c585b31", "62 45 7c 58 5b 31 vcvtdq2ph (%r9){1to16},%ymm30"},
|
|
{"vcvtdq2ph broadcast source disp8", "VCVTDQ2PH",
|
|
[]ExtOperand{ExtBroadcast(1, 127), ExtYmm(30)},
|
|
"62657c585b717f", "62 65 7c 58 5b 71 7f vcvtdq2ph 0x1fc(%rcx){1to16},%ymm30 (Disp8(7f))"},
|
|
{"vcvtudq2ph broadcast source", "VCVTUDQ2PH",
|
|
[]ExtOperand{ExtBroadcast(9, 0), ExtYmm(30)},
|
|
"62457f587a31", "62 45 7f 58 7a 31 vcvtudq2ph (%r9){1to16},%ymm30"},
|
|
{"vcvtudq2ph broadcast source disp8", "VCVTUDQ2PH",
|
|
[]ExtOperand{ExtBroadcast(1, 127), ExtYmm(30)},
|
|
"62657f587a717f", "62 65 7f 58 7a 71 7f vcvtudq2ph 0x1fc(%rcx){1to16},%ymm30 (Disp8(7f))"},
|
|
{"vcvtqq2ph broadcast source", "VCVTQQ2PH",
|
|
[]ExtOperand{ExtBroadcast(9, 0), ExtXmm(30)},
|
|
"6245fc585b31", "62 45 fc 58 5b 31 vcvtqq2ph (%r9){1to8},%xmm30"},
|
|
{"vcvtqq2ph broadcast source disp8", "VCVTQQ2PH",
|
|
[]ExtOperand{ExtBroadcast(1, 127), ExtXmm(30)},
|
|
"6265fc585b717f", "62 65 fc 58 5b 71 7f vcvtqq2ph 0x3f8(%rcx){1to8},%xmm30 (Disp8(7f))"},
|
|
// The 256-bit broadcast row shares the 512-bit row's operand list, both
|
|
// destinations being XMM, so the resolver cannot tell them apart; the
|
|
// register row above pins the 256-bit template alone.
|
|
{"vcvtuqq2ph broadcast source", "VCVTUQQ2PH",
|
|
[]ExtOperand{ExtBroadcast(9, 0), ExtXmm(30)},
|
|
"6245ff587a31", "62 45 ff 58 7a 31 vcvtuqq2ph (%r9){1to8},%xmm30"},
|
|
{"vcvtuqq2ph broadcast source disp8", "VCVTUQQ2PH",
|
|
[]ExtOperand{ExtBroadcast(1, 127), ExtXmm(30)},
|
|
"6265ff587a717f", "62 65 ff 58 7a 71 7f vcvtuqq2ph 0x3f8(%rcx){1to8},%xmm30 (Disp8(7f))"},
|
|
{"vcvtpd2ph broadcast source", "VCVTPD2PH",
|
|
[]ExtOperand{ExtBroadcast(9, 0), ExtXmm(30)},
|
|
"6245fd585a31", "62 45 fd 58 5a 31 vcvtpd2ph (%r9){1to8},%xmm30"},
|
|
{"vcvtpd2ph broadcast source disp8", "VCVTPD2PH",
|
|
[]ExtOperand{ExtBroadcast(1, 127), ExtXmm(30)},
|
|
"6265fd585a717f", "62 65 fd 58 5a 71 7f vcvtpd2ph 0x3f8(%rcx){1to8},%xmm30 (Disp8(7f))"},
|
|
// The 256-bit broadcast row shares the 512-bit row's operand list, both
|
|
// destinations being XMM, so the resolver cannot tell them apart; the
|
|
// register row above pins the 256-bit template alone.
|
|
|
|
// The write mask over the converting destinations, and one composed
|
|
// row: the broadcast, the mask and the zeroing on the one word.
|
|
{"vcvtph2w k7 zeroing", "VCVTPH2W",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtWriteMasked(ExtZmm(30), 7, true)},
|
|
"62457dcf7d31", "62 45 7d cf 7d 31 vcvtph2w (%r9),%zmm30{%k7}{z}"},
|
|
{"vcvtph2dq k7 zeroing, memory source", "VCVTPH2DQ",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtWriteMasked(ExtZmm(30), 7, true)},
|
|
"62457dcf5b31", "62 45 7d cf 5b 31 vcvtph2dq (%r9),%zmm30{%k7}{z}"},
|
|
{"vcvtph2qq k7, memory source", "VCVTPH2QQ",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtWriteMasked(ExtZmm(30), 7, false)},
|
|
"62457d4f7b31", "62 45 7d 4f 7b 31 vcvtph2qq (%r9),%zmm30{%k7}"},
|
|
{"vcvtph2pd k7, memory source", "VCVTPH2PD",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtWriteMasked(ExtZmm(30), 7, false)},
|
|
"62457c4f5a31", "62 45 7c 4f 5a 31 vcvtph2pd (%r9),%zmm30{%k7}"},
|
|
{"vcvtw2ph k7 zeroing", "VCVTW2PH",
|
|
[]ExtOperand{ExtZmm(5), ExtWriteMasked(ExtZmm(6), 7, true)},
|
|
"62f57ecf7df5", "62 f5 7e cf 7d f5 vcvtw2ph %zmm5,%zmm6{%k7}{z}"},
|
|
{"vcvtdq2ph k7 zeroing", "VCVTDQ2PH",
|
|
[]ExtOperand{ExtZmm(5), ExtWriteMasked(ExtYmm(6), 7, true)},
|
|
"62f57ccf5bf5", "62 f5 7c cf 5b f5 vcvtdq2ph %zmm5,%ymm6{%k7}{z}"},
|
|
{"vcvtw2ph broadcast under k7 zeroing", "VCVTW2PH",
|
|
[]ExtOperand{ExtBroadcast(9, 0), ExtWriteMasked(ExtZmm(30), 7, true)},
|
|
"62457edf7d31", "62 45 7e df 7d 31 vcvtw2ph (%r9){1to32},%zmm30{%k7}{z}"},
|
|
|
|
// The memory forms of the scalar conversions, the m16, m32 and m64
|
|
// sources the manual spells beside each register form. The disp8 rows
|
|
// quote the listing's compressed spellings, whose source is N times the
|
|
// plain displacement, N the element size.
|
|
{"vcvtsh2ss memory source", "VCVTSH2SS",
|
|
[]ExtOperand{ExtXmm(5), ExtMemory(9, 0), ExtXmm(6)},
|
|
"62d654081331", "62 d6 54 08 13 31 vcvtsh2ss (%r9),%xmm5,%xmm6"},
|
|
{"vcvtsh2ss memory source disp8", "VCVTSH2SS",
|
|
[]ExtOperand{ExtXmm(5), ExtMemory(1, 1), ExtXmm(6)},
|
|
"62f65408137101", "62 f6 54 08 13 71 01 vcvtsh2ss 0x2(%rcx),%xmm5,%xmm6 (Disp8(01))"},
|
|
{"vcvtsh2sd memory source", "VCVTSH2SD",
|
|
[]ExtOperand{ExtXmm(5), ExtMemory(9, 0), ExtXmm(6)},
|
|
"62d556085a31", "62 d5 56 08 5a 31 vcvtsh2sd (%r9),%xmm5,%xmm6"},
|
|
{"vcvtsh2sd memory source disp8", "VCVTSH2SD",
|
|
[]ExtOperand{ExtXmm(5), ExtMemory(1, 1), ExtXmm(6)},
|
|
"62f556085a7101", "62 f5 56 08 5a 71 01 vcvtsh2sd 0x2(%rcx),%xmm5,%xmm6 (Disp8(01))"},
|
|
{"vcvtss2sh memory source", "VCVTSS2SH",
|
|
[]ExtOperand{ExtXmm(5), ExtMemory(9, 0), ExtXmm(6)},
|
|
"62d554081d31", "62 d5 54 08 1d 31 vcvtss2sh (%r9),%xmm5,%xmm6"},
|
|
{"vcvtss2sh memory source disp8", "VCVTSS2SH",
|
|
[]ExtOperand{ExtXmm(5), ExtMemory(1, 1), ExtXmm(6)},
|
|
"62f554081d7101", "62 f5 54 08 1d 71 01 vcvtss2sh 0x4(%rcx),%xmm5,%xmm6 (Disp8(01))"},
|
|
{"vcvtsd2sh memory source", "VCVTSD2SH",
|
|
[]ExtOperand{ExtXmm(5), ExtMemory(9, 0), ExtXmm(6)},
|
|
"62d5d7085a31", "62 d5 d7 08 5a 31 vcvtsd2sh (%r9),%xmm5,%xmm6"},
|
|
{"vcvtsd2sh memory source disp8", "VCVTSD2SH",
|
|
[]ExtOperand{ExtXmm(5), ExtMemory(1, 1), ExtXmm(6)},
|
|
"62f5d7085a7101", "62 f5 d7 08 5a 71 01 vcvtsd2sh 0x8(%rcx),%xmm5,%xmm6 (Disp8(01))"},
|
|
{"vcvtsh2si memory source", "VCVTSH2SI",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtGpr32(0)},
|
|
"62d57e082d01", "62 d5 7e 08 2d 01 vcvtsh2si (%r9),%eax"},
|
|
{"vcvtsh2si 64-bit memory source", "VCVTSH2SI",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtGpr64(12)},
|
|
"6255fe082d21", "62 55 fe 08 2d 21 vcvtsh2si (%r9),%r12"},
|
|
{"vcvtsh2si memory source disp8", "VCVTSH2SI",
|
|
[]ExtOperand{ExtMemory(1, 1), ExtGpr32(0)},
|
|
"62f57e082d4101", "62 f5 7e 08 2d 41 01 vcvtsh2si 0x2(%rcx),%eax (Disp8(01))"},
|
|
{"vcvtsh2usi memory source", "VCVTSH2USI",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtGpr32(0)},
|
|
"62d57e087901", "62 d5 7e 08 79 01 vcvtsh2usi (%r9),%eax"},
|
|
{"vcvtsh2usi 64-bit memory source disp8", "VCVTSH2USI",
|
|
[]ExtOperand{ExtMemory(1, 1), ExtGpr64(12)},
|
|
"6275fe08796101", "62 75 fe 08 79 61 01 vcvtsh2usi 0x2(%rcx),%r12 (Disp8(01))"},
|
|
|
|
// The packed imm8-control group, the packed mirror of the scalar core's
|
|
// mantissa extraction, reduction and rounding. The control byte leads,
|
|
// the sources read from memory full-width, and the immediate layouts are
|
|
// the ones the scalar rows share: every row takes the $0x7b the suite
|
|
// drives through the fraction-bit forms, save VGETMANTPH, whose reserved
|
|
// upper nibble the layer refuses and whose $0x0b encodes the same opcode
|
|
// row the suite's $0x7b spells.
|
|
{"vrndscaleph zmm", "VRNDSCALEPH",
|
|
[]ExtOperand{ExtImmediate(0x7b), ExtZmm(5), ExtZmm(6)},
|
|
"62f37c4808f57b", "62 f3 7c 48 08 f5 7b vrndscaleph $0x7b,%zmm5,%zmm6"},
|
|
{"vrndscaleph ymm", "VRNDSCALEPH",
|
|
[]ExtOperand{ExtImmediate(0x7b), ExtYmm(5), ExtYmm(6)},
|
|
"62f37c2808f57b", "62 f3 7c 28 08 f5 7b vrndscaleph $0x7b,%ymm5,%ymm6"},
|
|
{"vrndscaleph xmm", "VRNDSCALEPH",
|
|
[]ExtOperand{ExtImmediate(0x7b), ExtXmm(5), ExtXmm(6)},
|
|
"62f37c0808f57b", "62 f3 7c 08 08 f5 7b vrndscaleph $0x7b,%xmm5,%xmm6"},
|
|
{"vreduceph zmm", "VREDUCEPH",
|
|
[]ExtOperand{ExtImmediate(0x7b), ExtZmm(5), ExtZmm(6)},
|
|
"62f37c4856f57b", "62 f3 7c 48 56 f5 7b vreduceph $0x7b,%zmm5,%zmm6"},
|
|
{"vreduceph ymm", "VREDUCEPH",
|
|
[]ExtOperand{ExtImmediate(0x7b), ExtYmm(5), ExtYmm(6)},
|
|
"62f37c2856f57b", "62 f3 7c 28 56 f5 7b vreduceph $0x7b,%ymm5,%ymm6"},
|
|
{"vreduceph xmm", "VREDUCEPH",
|
|
[]ExtOperand{ExtImmediate(0x7b), ExtXmm(5), ExtXmm(6)},
|
|
"62f37c0856f57b", "62 f3 7c 08 56 f5 7b vreduceph $0x7b,%xmm5,%xmm6"},
|
|
{"vgetmantph zmm", "VGETMANTPH",
|
|
[]ExtOperand{ExtImmediate(0x0b), ExtZmm(5), ExtZmm(6)},
|
|
"62f37c4826f50b", "62 f3 7c 48 26 f5 0b vgetmantph $0xb,%zmm5,%zmm6"},
|
|
{"vgetmantph ymm", "VGETMANTPH",
|
|
[]ExtOperand{ExtImmediate(0x0b), ExtYmm(5), ExtYmm(6)},
|
|
"62f37c2826f50b", "62 f3 7c 28 26 f5 0b vgetmantph $0xb,%ymm5,%ymm6"},
|
|
{"vgetmantph xmm", "VGETMANTPH",
|
|
[]ExtOperand{ExtImmediate(0x0b), ExtXmm(5), ExtXmm(6)},
|
|
"62f37c0826f50b", "62 f3 7c 08 26 f5 0b vgetmantph $0xb,%xmm5,%xmm6"},
|
|
{"vrndscaleph memory source", "VRNDSCALEPH",
|
|
[]ExtOperand{ExtImmediate(0x7b), ExtMemory(9, 0), ExtZmm(30)},
|
|
"62437c4808317b", "62 43 7c 48 08 31 7b vrndscaleph $0x7b,(%r9),%zmm30"},
|
|
{"vrndscaleph memory source disp8", "VRNDSCALEPH",
|
|
[]ExtOperand{ExtImmediate(0x7b), ExtMemory(1, 127), ExtZmm(6)},
|
|
"62f37c4808717f7b", "62 f3 7c 48 08 71 7f 7b vrndscaleph $0x7b,0x1fc0(%rcx),%zmm6 (Disp8(7f))"},
|
|
{"vreduceph memory source", "VREDUCEPH",
|
|
[]ExtOperand{ExtImmediate(0x7b), ExtMemory(9, 0), ExtZmm(30)},
|
|
"62437c4856317b", "62 43 7c 48 56 31 7b vreduceph $0x7b,(%r9),%zmm30"},
|
|
{"vgetmantph memory source", "VGETMANTPH",
|
|
[]ExtOperand{ExtImmediate(0x0b), ExtMemory(9, 0), ExtZmm(30)},
|
|
"62437c4826310b", "62 43 7c 48 26 31 0b vgetmantph $0xb,(%r9),%zmm30"},
|
|
{"vrndscaleph k7 zeroing", "VRNDSCALEPH",
|
|
[]ExtOperand{ExtImmediate(0x7b), ExtZmm(5), ExtWriteMasked(ExtZmm(6), 7, true)},
|
|
"62f37ccf08f57b", "62 f3 7c cf 08 f5 7b vrndscaleph $0x7b,%zmm5,%zmm6{%k7}{z}"},
|
|
|
|
// The AVX512-FP16 packed fused multiply-add, twelve mnemonics by three
|
|
// lengths: the 512-bit rows on the suite's high registers, the VL rows
|
|
// on the low ones, every register form quoted from the local GNU
|
|
// assembler's output (EVEX.NDS.66.MAP6.W0 throughout).
|
|
{"vfmadd132ph", "VFMADD132PH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtZmm(30)},
|
|
"6206154098f4", "62 06 15 40 98 f4 vfmadd132ph %zmm28,%zmm29,%zmm30"},
|
|
{"vfmadd213ph", "VFMADD213PH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtZmm(30)},
|
|
"62061540a8f4", "62 06 15 40 a8 f4 vfmadd213ph %zmm28,%zmm29,%zmm30"},
|
|
{"vfmadd231ph", "VFMADD231PH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtZmm(30)},
|
|
"62061540b8f4", "62 06 15 40 b8 f4 vfmadd231ph %zmm28,%zmm29,%zmm30"},
|
|
{"vfmsub132ph", "VFMSUB132PH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtZmm(30)},
|
|
"620615409af4", "62 06 15 40 9a f4 vfmsub132ph %zmm28,%zmm29,%zmm30"},
|
|
{"vfmsub213ph", "VFMSUB213PH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtZmm(30)},
|
|
"62061540aaf4", "62 06 15 40 aa f4 vfmsub213ph %zmm28,%zmm29,%zmm30"},
|
|
{"vfmsub231ph", "VFMSUB231PH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtZmm(30)},
|
|
"62061540baf4", "62 06 15 40 ba f4 vfmsub231ph %zmm28,%zmm29,%zmm30"},
|
|
{"vfmaddsub132ph", "VFMADDSUB132PH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtZmm(30)},
|
|
"6206154096f4", "62 06 15 40 96 f4 vfmaddsub132ph %zmm28,%zmm29,%zmm30"},
|
|
{"vfmaddsub213ph", "VFMADDSUB213PH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtZmm(30)},
|
|
"62061540a6f4", "62 06 15 40 a6 f4 vfmaddsub213ph %zmm28,%zmm29,%zmm30"},
|
|
{"vfmaddsub231ph", "VFMADDSUB231PH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtZmm(30)},
|
|
"62061540b6f4", "62 06 15 40 b6 f4 vfmaddsub231ph %zmm28,%zmm29,%zmm30"},
|
|
{"vfmsubadd132ph", "VFMSUBADD132PH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtZmm(30)},
|
|
"6206154097f4", "62 06 15 40 97 f4 vfmsubadd132ph %zmm28,%zmm29,%zmm30"},
|
|
{"vfmsubadd213ph", "VFMSUBADD213PH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtZmm(30)},
|
|
"62061540a7f4", "62 06 15 40 a7 f4 vfmsubadd213ph %zmm28,%zmm29,%zmm30"},
|
|
{"vfmsubadd231ph", "VFMSUBADD231PH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtZmm(30)},
|
|
"62061540b7f4", "62 06 15 40 b7 f4 vfmsubadd231ph %zmm28,%zmm29,%zmm30"},
|
|
{"vfmadd132ph ymm", "VFMADD132PH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f6552898f4", "62 f6 55 28 98 f4 vfmadd132ph %ymm4,%ymm5,%ymm6"},
|
|
{"vfmadd132ph xmm", "VFMADD132PH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f6550898f4", "62 f6 55 08 98 f4 vfmadd132ph %xmm4,%xmm5,%xmm6"},
|
|
{"vfmadd213ph ymm", "VFMADD213PH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f65528a8f4", "62 f6 55 28 a8 f4 vfmadd213ph %ymm4,%ymm5,%ymm6"},
|
|
{"vfmadd213ph xmm", "VFMADD213PH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f65508a8f4", "62 f6 55 08 a8 f4 vfmadd213ph %xmm4,%xmm5,%xmm6"},
|
|
{"vfmadd231ph ymm", "VFMADD231PH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f65528b8f4", "62 f6 55 28 b8 f4 vfmadd231ph %ymm4,%ymm5,%ymm6"},
|
|
{"vfmadd231ph xmm", "VFMADD231PH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f65508b8f4", "62 f6 55 08 b8 f4 vfmadd231ph %xmm4,%xmm5,%xmm6"},
|
|
{"vfmsub132ph ymm", "VFMSUB132PH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f655289af4", "62 f6 55 28 9a f4 vfmsub132ph %ymm4,%ymm5,%ymm6"},
|
|
{"vfmsub132ph xmm", "VFMSUB132PH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f655089af4", "62 f6 55 08 9a f4 vfmsub132ph %xmm4,%xmm5,%xmm6"},
|
|
{"vfmsub213ph ymm", "VFMSUB213PH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f65528aaf4", "62 f6 55 28 aa f4 vfmsub213ph %ymm4,%ymm5,%ymm6"},
|
|
{"vfmsub213ph xmm", "VFMSUB213PH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f65508aaf4", "62 f6 55 08 aa f4 vfmsub213ph %xmm4,%xmm5,%xmm6"},
|
|
{"vfmsub231ph ymm", "VFMSUB231PH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f65528baf4", "62 f6 55 28 ba f4 vfmsub231ph %ymm4,%ymm5,%ymm6"},
|
|
{"vfmsub231ph xmm", "VFMSUB231PH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f65508baf4", "62 f6 55 08 ba f4 vfmsub231ph %xmm4,%xmm5,%xmm6"},
|
|
{"vfmaddsub132ph ymm", "VFMADDSUB132PH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f6552896f4", "62 f6 55 28 96 f4 vfmaddsub132ph %ymm4,%ymm5,%ymm6"},
|
|
{"vfmaddsub132ph xmm", "VFMADDSUB132PH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f6550896f4", "62 f6 55 08 96 f4 vfmaddsub132ph %xmm4,%xmm5,%xmm6"},
|
|
{"vfmaddsub213ph ymm", "VFMADDSUB213PH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f65528a6f4", "62 f6 55 28 a6 f4 vfmaddsub213ph %ymm4,%ymm5,%ymm6"},
|
|
{"vfmaddsub213ph xmm", "VFMADDSUB213PH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f65508a6f4", "62 f6 55 08 a6 f4 vfmaddsub213ph %xmm4,%xmm5,%xmm6"},
|
|
{"vfmaddsub231ph ymm", "VFMADDSUB231PH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f65528b6f4", "62 f6 55 28 b6 f4 vfmaddsub231ph %ymm4,%ymm5,%ymm6"},
|
|
{"vfmaddsub231ph xmm", "VFMADDSUB231PH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f65508b6f4", "62 f6 55 08 b6 f4 vfmaddsub231ph %xmm4,%xmm5,%xmm6"},
|
|
{"vfmsubadd132ph ymm", "VFMSUBADD132PH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f6552897f4", "62 f6 55 28 97 f4 vfmsubadd132ph %ymm4,%ymm5,%ymm6"},
|
|
{"vfmsubadd132ph xmm", "VFMSUBADD132PH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f6550897f4", "62 f6 55 08 97 f4 vfmsubadd132ph %xmm4,%xmm5,%xmm6"},
|
|
{"vfmsubadd213ph ymm", "VFMSUBADD213PH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f65528a7f4", "62 f6 55 28 a7 f4 vfmsubadd213ph %ymm4,%ymm5,%ymm6"},
|
|
{"vfmsubadd213ph xmm", "VFMSUBADD213PH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f65508a7f4", "62 f6 55 08 a7 f4 vfmsubadd213ph %xmm4,%xmm5,%xmm6"},
|
|
{"vfmsubadd231ph ymm", "VFMSUBADD231PH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f65528b7f4", "62 f6 55 28 b7 f4 vfmsubadd231ph %ymm4,%ymm5,%ymm6"},
|
|
{"vfmsubadd231ph xmm", "VFMSUBADD231PH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f65508b7f4", "62 f6 55 08 b7 f4 vfmsubadd231ph %xmm4,%xmm5,%xmm6"},
|
|
|
|
// The scalar fused multiply-add, EVEX.NDS.LIG.66.MAP6.W0: the add
|
|
// opcodes one above the packed ones, the subtract two above them.
|
|
{"vfmadd132sh", "VFMADD132SH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"6206150099f4", "62 06 15 00 99 f4 vfmadd132sh %xmm28,%xmm29,%xmm30"},
|
|
{"vfmadd213sh", "VFMADD213SH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"62061500a9f4", "62 06 15 00 a9 f4 vfmadd213sh %xmm28,%xmm29,%xmm30"},
|
|
{"vfmadd231sh", "VFMADD231SH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"62061500b9f4", "62 06 15 00 b9 f4 vfmadd231sh %xmm28,%xmm29,%xmm30"},
|
|
{"vfmsub132sh", "VFMSUB132SH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"620615009bf4", "62 06 15 00 9b f4 vfmsub132sh %xmm28,%xmm29,%xmm30"},
|
|
{"vfmsub213sh", "VFMSUB213SH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"62061500abf4", "62 06 15 00 ab f4 vfmsub213sh %xmm28,%xmm29,%xmm30"},
|
|
{"vfmsub231sh", "VFMSUB231SH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"62061500bbf4", "62 06 15 00 bb f4 vfmsub231sh %xmm28,%xmm29,%xmm30"},
|
|
|
|
// The FMA memory forms: the second source reads m512, m256, m128 or the
|
|
// scalar m16 from memory. The disp8 rows quote the listing's compressed
|
|
// spellings, whose source is N times the plain displacement the bytes
|
|
// carry; the R12 row exercises the SIB byte.
|
|
{"vfmadd132ph memory source", "VFMADD132PH",
|
|
[]ExtOperand{ExtZmm(29), ExtMemory(1, 127), ExtZmm(30)},
|
|
"6266154098717f", "62 66 15 40 98 71 7f vfmadd132ph 0x1fc0(%rcx),%zmm29,%zmm30 (Disp8(7f))"},
|
|
{"vfmadd132ph ymm memory source", "VFMADD132PH",
|
|
[]ExtOperand{ExtYmm(5), ExtMemory(1, 127), ExtYmm(6)},
|
|
"62f6552898717f", "62 f6 55 28 98 71 7f vfmadd132ph 0xfe0(%ecx),%ymm5,%ymm6 (Disp8(7f))"},
|
|
{"vfmadd132ph xmm memory source", "VFMADD132PH",
|
|
[]ExtOperand{ExtXmm(5), ExtMemory(1, 127), ExtXmm(6)},
|
|
"62f6550898717f", "62 f6 55 08 98 71 7f vfmadd132ph 0x7f0(%ecx),%xmm5,%xmm6 (Disp8(7f))"},
|
|
{"vfmadd132ph memory source", "VFMADD132PH",
|
|
[]ExtOperand{ExtZmm(29), ExtMemory(9, 0), ExtZmm(30)},
|
|
"624615409831", "62 46 15 40 98 31 vfmadd132ph (%r9),%zmm29,%zmm30"},
|
|
{"vfmsub231ph memory source", "VFMSUB231PH",
|
|
[]ExtOperand{ExtZmm(29), ExtMemory(9, 0), ExtZmm(30)},
|
|
"62461540ba31", "62 46 15 40 ba 31 vfmsub231ph (%r9),%zmm29,%zmm30"},
|
|
{"vfmaddsub132ph memory source over an R12 base", "VFMADDSUB132PH",
|
|
[]ExtOperand{ExtZmm(29), ExtMemory(12, 0), ExtZmm(30)},
|
|
"62461540963424", ""},
|
|
{"vfmadd132sh memory source", "VFMADD132SH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(9, 0), ExtXmm(30)},
|
|
"624615009931", "62 46 15 00 99 31 vfmadd132sh (%r9),%xmm29,%xmm30"},
|
|
{"vfmadd132sh memory source disp8", "VFMADD132SH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(1, 1), ExtXmm(30)},
|
|
"62661500997101", "62 66 15 00 99 71 01 vfmadd132sh 0x2(%rcx),%xmm29,%xmm30 (Disp8(01))"},
|
|
{"vfmsub132sh memory source", "VFMSUB132SH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(9, 0), ExtXmm(30)},
|
|
"624615009b31", "62 46 15 00 9b 31 vfmsub132sh (%r9),%xmm29,%xmm30"},
|
|
|
|
// The FMA broadcast forms: one half-precision element the hardware
|
|
// splats across the lanes, {1to32}, {1to16} and {1to8}.
|
|
{"vfmadd132ph broadcast source", "VFMADD132PH",
|
|
[]ExtOperand{ExtZmm(29), ExtBroadcast(9, 0), ExtZmm(30)},
|
|
"624615509831", "62 46 15 50 98 31 vfmadd132ph (%r9){1to32},%zmm29,%zmm30"},
|
|
{"vfmadd132ph ymm broadcast source", "VFMADD132PH",
|
|
[]ExtOperand{ExtYmm(5), ExtBroadcast(1, 0), ExtYmm(6)},
|
|
"62f655389831", "62 f6 55 38 98 31 vfmadd132ph (%ecx){1to16},%ymm5,%ymm6"},
|
|
{"vfmadd132ph xmm broadcast source", "VFMADD132PH",
|
|
[]ExtOperand{ExtXmm(5), ExtBroadcast(1, 0), ExtXmm(6)},
|
|
"62f655189831", "62 f6 55 18 98 31 vfmadd132ph (%ecx){1to8},%xmm5,%xmm6"},
|
|
{"vfmaddsub132ph broadcast source", "VFMADDSUB132PH",
|
|
[]ExtOperand{ExtZmm(29), ExtBroadcast(9, 0), ExtZmm(30)},
|
|
"624615509631", "62 46 15 50 96 31 vfmaddsub132ph (%r9){1to32},%zmm29,%zmm30"},
|
|
{"vfmsubadd231ph broadcast source", "VFMSUBADD231PH",
|
|
[]ExtOperand{ExtZmm(29), ExtBroadcast(9, 0), ExtZmm(30)},
|
|
"62461550b731", "62 46 15 50 b7 31 vfmsubadd231ph (%r9){1to32},%zmm29,%zmm30"},
|
|
|
|
// The FMA rounding rows: the 512-bit register forms take EVEX.RC, the
|
|
// scalar register forms beside them.
|
|
{"vfmadd132ph rz-sae", "VFMADD132PH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtRounded(ExtZmm(30), ExtRoundTruncate)},
|
|
"6206157098f4", "62 06 15 70 98 f4 vfmadd132ph {rz-sae},%zmm28,%zmm29,%zmm30"},
|
|
{"vfmadd213ph rn-sae", "VFMADD213PH",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(4), ExtRounded(ExtZmm(6), ExtRoundNearest)},
|
|
"62f65518a8f4", "62 f6 55 18 a8 f4 vfmadd213ph {rn-sae},%zmm4,%zmm5,%zmm6"},
|
|
{"vfmsub132ph ru-sae", "VFMSUB132PH",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(4), ExtRounded(ExtZmm(6), ExtRoundUp)},
|
|
"62f655589af4", "62 f6 55 58 9a f4 vfmsub132ph {ru-sae},%zmm4,%zmm5,%zmm6"},
|
|
{"vfmaddsub231ph rd-sae", "VFMADDSUB231PH",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(4), ExtRounded(ExtZmm(6), ExtRoundDown)},
|
|
"62f65538b6f4", "62 f6 55 38 b6 f4 vfmaddsub231ph {rd-sae},%zmm4,%zmm5,%zmm6"},
|
|
{"vfmadd132sh rn-sae", "VFMADD132SH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtRounded(ExtXmm(6), ExtRoundNearest)},
|
|
"62f6551899f4", "62 f6 55 18 99 f4 vfmadd132sh {rn-sae},%xmm4,%xmm5,%xmm6"},
|
|
{"vfmadd231sh rz-sae, high registers", "VFMADD231SH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtRounded(ExtXmm(30), ExtRoundTruncate)},
|
|
"62061570b9f4", "62 06 15 70 b9 f4 vfmadd231sh {rz-sae},%xmm28,%xmm29,%xmm30"},
|
|
|
|
// The FMA write masks over the packed destinations.
|
|
{"vfmadd132ph k7 zeroing", "VFMADD132PH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtWriteMasked(ExtZmm(30), 7, true)},
|
|
"620615c798f4", "62 06 15 c7 98 f4 vfmadd132ph %zmm28,%zmm29,%zmm30{%k7}{z}"},
|
|
{"vfmaddsub132ph k5 merging, memory source", "VFMADDSUB132PH",
|
|
[]ExtOperand{ExtZmm(29), ExtMemory(9, 0), ExtWriteMasked(ExtZmm(30), 5, false)},
|
|
"624615459631", "62 46 15 45 96 31 vfmaddsub132ph (%r9),%zmm29,%zmm30{%k5}"},
|
|
|
|
// The complex multiply, EVEX.NDS.F3.MAP6.W0 D6 and EVEX.NDS.F2.MAP6.W0
|
|
// D6, the scalar pair at D7. No broadcast: a complex value needs both
|
|
// of its halves beside one another, so the memory shape reads its
|
|
// full-width vector plain.
|
|
{"vfmulcph", "VFMULCPH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtZmm(30)},
|
|
"62061640d6f4", "62 06 16 40 d6 f4 vfmulcph %zmm28,%zmm29,%zmm30"},
|
|
{"vfmulcph ymm", "VFMULCPH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f65628d6f4", "62 f6 56 28 d6 f4 vfmulcph %ymm4,%ymm5,%ymm6"},
|
|
{"vfmulcph xmm", "VFMULCPH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f65608d6f4", "62 f6 56 08 d6 f4 vfmulcph %xmm4,%xmm5,%xmm6"},
|
|
{"vfcmulcph", "VFCMULCPH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtZmm(30)},
|
|
"62061740d6f4", "62 06 17 40 d6 f4 vfcmulcph %zmm28,%zmm29,%zmm30"},
|
|
{"vfcmulcph ymm", "VFCMULCPH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f65728d6f4", "62 f6 57 28 d6 f4 vfcmulcph %ymm4,%ymm5,%ymm6"},
|
|
{"vfcmulcph xmm", "VFCMULCPH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f65708d6f4", "62 f6 57 08 d6 f4 vfcmulcph %xmm4,%xmm5,%xmm6"},
|
|
{"vfmulcsh", "VFMULCSH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"62061600d7f4", "62 06 16 00 d7 f4 vfmulcsh %xmm28,%xmm29,%xmm30"},
|
|
{"vfcmulcsh", "VFCMULCSH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"62061700d7f4", "62 06 17 00 d7 f4 vfcmulcsh %xmm28,%xmm29,%xmm30"},
|
|
{"vfmulcph memory source", "VFMULCPH",
|
|
[]ExtOperand{ExtZmm(29), ExtMemory(1, 127), ExtZmm(30)},
|
|
"62661640d6717f", "62 66 16 40 d6 71 7f vfmulcph 0x1fc0(%rcx),%zmm29,%zmm30 (Disp8(7f))"},
|
|
{"vfcmulcph memory source", "VFCMULCPH",
|
|
[]ExtOperand{ExtZmm(29), ExtMemory(9, 0), ExtZmm(30)},
|
|
"62461740d631", "62 46 17 40 d6 31 vfcmulcph (%r9),%zmm29,%zmm30"},
|
|
{"vfmulcsh memory source", "VFMULCSH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(9, 0), ExtXmm(30)},
|
|
"62461600d731", "62 46 16 00 d7 31 vfmulcsh (%r9),%xmm29,%xmm30"},
|
|
{"vfmulcph rz-sae", "VFMULCPH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtRounded(ExtZmm(30), ExtRoundTruncate)},
|
|
"62061670d6f4", "62 06 16 70 d6 f4 vfmulcph {rz-sae},%zmm28,%zmm29,%zmm30"},
|
|
{"vfcmulcph rn-sae", "VFCMULCPH",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(4), ExtRounded(ExtZmm(6), ExtRoundNearest)},
|
|
"62f65718d6f4", "62 f6 57 18 d6 f4 vfcmulcph {rn-sae},%zmm4,%zmm5,%zmm6"},
|
|
{"vfmulcsh rn-sae", "VFMULCSH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtRounded(ExtXmm(6), ExtRoundNearest)},
|
|
"62f65618d7f4", "62 f6 56 18 d7 f4 vfmulcsh {rn-sae},%xmm4,%xmm5,%xmm6"},
|
|
{"vfcmulcsh ru-sae, high registers", "VFCMULCSH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtRounded(ExtXmm(30), ExtRoundUp)},
|
|
"62061750d7f4", "62 06 17 50 d7 f4 vfcmulcsh {ru-sae},%xmm28,%xmm29,%xmm30"},
|
|
{"vfmulcph k7 zeroing", "VFMULCPH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtWriteMasked(ExtZmm(30), 7, true)},
|
|
"620616c7d6f4", "62 06 16 c7 d6 f4 vfmulcph %zmm28,%zmm29,%zmm30{%k7}{z}"},
|
|
{"vfcmulcph k5 merging, memory source", "VFCMULCPH",
|
|
[]ExtOperand{ExtZmm(29), ExtMemory(9, 0), ExtWriteMasked(ExtZmm(30), 5, false)},
|
|
"62461745d631", "62 46 17 45 d6 31 vfcmulcph (%r9),%zmm29,%zmm30{%k5}"},
|
|
|
|
// The complex fused multiply-add, EVEX.NDS.MAP6.W0 56 and 57: F3
|
|
// conjugating the second source and F2 the first, the scalar mirrors
|
|
// sharing the opcode one step up. The memory shape reads its
|
|
// full-width vector plain, a complex value needing both of its halves
|
|
// beside one another, so no broadcast spelling exists to encode.
|
|
{"vfmaddcph", "VFMADDCPH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtZmm(30)},
|
|
"6206164056f4", "62 06 16 40 56 f4 vfmaddcph %zmm28,%zmm29,%zmm30"},
|
|
{"vfmaddcph ymm", "VFMADDCPH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f6562856f4", "62 f6 56 28 56 f4 vfmaddcph %ymm4,%ymm5,%ymm6"},
|
|
{"vfmaddcph xmm", "VFMADDCPH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f6560856f4", "62 f6 56 08 56 f4 vfmaddcph %xmm4,%xmm5,%xmm6"},
|
|
{"vfcmaddcph", "VFCMADDCPH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtZmm(30)},
|
|
"6206174056f4", "62 06 17 40 56 f4 vfcmaddcph %zmm28,%zmm29,%zmm30"},
|
|
{"vfcmaddcph ymm", "VFCMADDCPH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f6572856f4", "62 f6 57 28 56 f4 vfcmaddcph %ymm4,%ymm5,%ymm6"},
|
|
{"vfcmaddcph xmm", "VFCMADDCPH",
|
|
[]ExtOperand{ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f6570856f4", "62 f6 57 08 56 f4 vfcmaddcph %xmm4,%xmm5,%xmm6"},
|
|
{"vfmaddcsh", "VFMADDCSH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"6206160057f4", "62 06 16 00 57 f4 vfmaddcsh %xmm28,%xmm29,%xmm30"},
|
|
{"vfcmaddcsh", "VFCMADDCSH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"6206170057f4", "62 06 17 00 57 f4 vfcmaddcsh %xmm28,%xmm29,%xmm30"},
|
|
{"vfmaddcph memory source", "VFMADDCPH",
|
|
[]ExtOperand{ExtZmm(29), ExtMemory(1, 127), ExtZmm(30)},
|
|
"6266164056717f", "62 66 16 40 56 71 7f vfmaddcph 0x1fc0(%rcx),%zmm29,%zmm30 (Disp8(7f))"},
|
|
{"vfcmaddcph memory source", "VFCMADDCPH",
|
|
[]ExtOperand{ExtZmm(29), ExtMemory(9, 0), ExtZmm(30)},
|
|
"624617405631", "62 46 17 40 56 31 vfcmaddcph (%r9),%zmm29,%zmm30"},
|
|
{"vfmaddcsh memory source", "VFMADDCSH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(9, 0), ExtXmm(30)},
|
|
"624616005731", "62 46 16 00 57 31 vfmaddcsh (%r9),%xmm29,%xmm30"},
|
|
{"vfcmaddcsh memory source", "VFCMADDCSH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(9, 0), ExtXmm(30)},
|
|
"624617005731", "62 46 17 00 57 31 vfcmaddcsh (%r9),%xmm29,%xmm30"},
|
|
{"vfmaddcsh memory source disp32", "VFMADDCSH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(1, 8128), ExtXmm(30)},
|
|
"6266160057b1c01f0000", "62 66 16 00 57 b1 c0 1f 00 00 vfmaddcsh 0x1fc0(%rcx),%xmm29,%xmm30"},
|
|
// The scalar complex shapes leave the small displacements alone: the
|
|
// local assembler never compresses them to disp8, so the disp8 row is
|
|
// derived from the proven zero-displacement row above.
|
|
{"vfmaddcsh memory source disp8", "VFMADDCSH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(1, 127), ExtXmm(30)},
|
|
"6266160057717f", ""},
|
|
{"vfmaddcph rz-sae", "VFMADDCPH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtRounded(ExtZmm(30), ExtRoundTruncate)},
|
|
"6206167056f4", "62 06 16 70 56 f4 vfmaddcph {rz-sae},%zmm28,%zmm29,%zmm30"},
|
|
{"vfcmaddcph rn-sae", "VFCMADDCPH",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(4), ExtRounded(ExtZmm(6), ExtRoundNearest)},
|
|
"62f6571856f4", "62 f6 57 18 56 f4 vfcmaddcph {rn-sae},%zmm4,%zmm5,%zmm6"},
|
|
{"vfmaddcsh rz-sae", "VFMADDCSH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtRounded(ExtXmm(30), ExtRoundTruncate)},
|
|
"6206167057f4", "62 06 16 70 57 f4 vfmaddcsh {rz-sae},%xmm28,%xmm29,%xmm30"},
|
|
{"vfcmaddcsh rn-sae, high registers", "VFCMADDCSH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtRounded(ExtXmm(30), ExtRoundNearest)},
|
|
"6206171057f4", "62 06 17 10 57 f4 vfcmaddcsh {rn-sae},%xmm28,%xmm29,%xmm30"},
|
|
{"vfmaddcph k7 zeroing", "VFMADDCPH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtWriteMasked(ExtZmm(30), 7, true)},
|
|
"620616c756f4", "62 06 16 c7 56 f4 vfmaddcph %zmm28,%zmm29,%zmm30{%k7}{z}"},
|
|
{"vfcmaddcph k5 merging, memory source", "VFCMADDCPH",
|
|
[]ExtOperand{ExtZmm(29), ExtMemory(9, 0), ExtWriteMasked(ExtZmm(30), 5, false)},
|
|
"624617455631", ""},
|
|
|
|
// VMINMAXPH, EVEX.NDS.0F3A.W0 52 /r /ib: the control byte leads the
|
|
// operand list and rides last in the word, the order the reference
|
|
// listings write both in.
|
|
{"vminmaxph", "VMINMAXPH",
|
|
[]ExtOperand{ExtImmediate(0x88), ExtZmm(29), ExtZmm(28), ExtZmm(30)},
|
|
"6203144052f488", "62 03 14 40 52 f4 88 vminmaxph $0x88,%zmm28,%zmm29,%zmm30"},
|
|
{"vminmaxph ymm", "VMINMAXPH",
|
|
[]ExtOperand{ExtImmediate(0x88), ExtYmm(5), ExtYmm(4), ExtYmm(6)},
|
|
"62f3542852f488", "62 f3 54 28 52 f4 88 vminmaxph $0x88,%ymm4,%ymm5,%ymm6"},
|
|
{"vminmaxph xmm", "VMINMAXPH",
|
|
[]ExtOperand{ExtImmediate(0x88), ExtXmm(5), ExtXmm(4), ExtXmm(6)},
|
|
"62f3540852f488", "62 f3 54 08 52 f4 88 vminmaxph $0x88,%xmm4,%xmm5,%xmm6"},
|
|
{"vminmaxph memory source", "VMINMAXPH",
|
|
[]ExtOperand{ExtImmediate(0x88), ExtZmm(29), ExtMemory(1, 127), ExtZmm(30)},
|
|
"6263144052717f88", "62 63 14 40 52 71 7f 88 vminmaxph $0x88,0x1fc0(%rcx),%zmm29,%zmm30 (Disp8(7f))"},
|
|
{"vminmaxph memory source plain", "VMINMAXPH",
|
|
[]ExtOperand{ExtImmediate(0x88), ExtZmm(29), ExtMemory(9, 0), ExtZmm(30)},
|
|
"62431440523188", "62 43 14 40 52 31 88 vminmaxph $0x88,(%r9),%zmm29,%zmm30"},
|
|
{"vminmaxph k7 zeroing", "VMINMAXPH",
|
|
[]ExtOperand{ExtImmediate(0x88), ExtZmm(29), ExtZmm(28), ExtWriteMasked(ExtZmm(30), 7, true)},
|
|
"620314c752f488", "62 03 14 c7 52 f4 88 vminmaxph $0x88,%zmm28,%zmm29,%zmm30{%k7}{z}"},
|
|
|
|
// The scalar mirror, EVEX.NDS.LIG.0F3A.W0 53 /r /ib: one control byte,
|
|
// one pair of half-precision values, the m16 memory source plain.
|
|
{"vminmaxsh", "VMINMAXSH",
|
|
[]ExtOperand{ExtImmediate(0x88), ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"6203140053f488", "62 03 14 00 53 f4 88 vminmaxsh $0x88,%xmm28,%xmm29,%xmm30"},
|
|
{"vminmaxsh memory source", "VMINMAXSH",
|
|
[]ExtOperand{ExtImmediate(0x88), ExtXmm(28), ExtMemory(9, 0), ExtXmm(29)},
|
|
"62431c00532988", "62 43 1c 00 53 29 88 vminmaxsh $0x88,(%r9),%xmm28,%xmm29"},
|
|
{"vminmaxsh memory source disp8", "VMINMAXSH",
|
|
[]ExtOperand{ExtImmediate(0x88), ExtXmm(28), ExtMemory(1, 127), ExtXmm(29)},
|
|
"62631c0053697f88", "62 63 1c 00 53 69 7f 88 vminmaxsh $0x88,0xfe(%rcx),%xmm28,%xmm29 (Disp8(7f))"},
|
|
|
|
// The AVX-VNNI-INT16 dot products, VEX.NDS.F3 and 66.0F38.W0 D2 and D3:
|
|
// the words the VEX mechanism encodes, five bytes over the C4 escape.
|
|
// The registers run 0..15, and the word is the three-operand shape the
|
|
// AVX dot products carry: dest, src1 and the second source the memory
|
|
// form reads plain.
|
|
{"vpdpwsud", "VPDPWSUD",
|
|
[]ExtOperand{ExtXmm(2), ExtXmm(1), ExtXmm(3)},
|
|
"c4e26ad2d9", "c4 e2 6a d2 d9 vpdpwsud %xmm1,%xmm2,%xmm3"},
|
|
{"vpdpwsuds", "VPDPWSUDS",
|
|
[]ExtOperand{ExtXmm(2), ExtXmm(1), ExtXmm(3)},
|
|
"c4e26ad3d9", "c4 e2 6a d3 d9 vpdpwsuds %xmm1,%xmm2,%xmm3"},
|
|
{"vpdpwusd", "VPDPWUSD",
|
|
[]ExtOperand{ExtXmm(2), ExtXmm(1), ExtXmm(3)},
|
|
"c4e269d2d9", "c4 e2 69 d2 d9 vpdpwusd %xmm1,%xmm2,%xmm3"},
|
|
{"vpdpwusds", "VPDPWUSDS",
|
|
[]ExtOperand{ExtXmm(2), ExtXmm(1), ExtXmm(3)},
|
|
"c4e269d3d9", "c4 e2 69 d3 d9 vpdpwusds %xmm1,%xmm2,%xmm3"},
|
|
{"vpdpwsud ymm", "VPDPWSUD",
|
|
[]ExtOperand{ExtYmm(2), ExtYmm(1), ExtYmm(3)},
|
|
"c4e26ed2d9", "c4 e2 6e d2 d9 vpdpwsud %ymm1,%ymm2,%ymm3"},
|
|
{"vpdpwsuds ymm", "VPDPWSUDS",
|
|
[]ExtOperand{ExtYmm(2), ExtYmm(1), ExtYmm(3)},
|
|
"c4e26ed3d9", "c4 e2 6e d3 d9 vpdpwsuds %ymm1,%ymm2,%ymm3"},
|
|
{"vpdpwusd ymm", "VPDPWUSD",
|
|
[]ExtOperand{ExtYmm(2), ExtYmm(1), ExtYmm(3)},
|
|
"c4e26dd2d9", "c4 e2 6d d2 d9 vpdpwusd %ymm1,%ymm2,%ymm3"},
|
|
{"vpdpwusds ymm", "VPDPWUSDS",
|
|
[]ExtOperand{ExtYmm(2), ExtYmm(1), ExtYmm(3)},
|
|
"c4e26dd3d9", "c4 e2 6d d3 d9 vpdpwusds %ymm1,%ymm2,%ymm3"},
|
|
{"vpdpwsud high registers", "VPDPWSUD",
|
|
[]ExtOperand{ExtXmm(11), ExtXmm(12), ExtXmm(9)},
|
|
"c44222d2cc", "c4 42 22 d2 cc vpdpwsud %xmm12,%xmm11,%xmm9"},
|
|
{"vpdpwusds ymm high registers", "VPDPWUSDS",
|
|
[]ExtOperand{ExtYmm(10), ExtYmm(15), ExtYmm(8)},
|
|
"c4422dd3c7", "c4 42 2d d3 c7 vpdpwusds %ymm15,%ymm10,%ymm8"},
|
|
{"vpdpwusds ymm, the destination above 7", "VPDPWUSDS",
|
|
[]ExtOperand{ExtYmm(10), ExtYmm(8), ExtYmm(15)},
|
|
"c4422dd3f8", "c4 42 2d d3 f8 vpdpwusds %ymm8,%ymm10,%ymm15"},
|
|
{"vpdpwsud memory source", "VPDPWSUD",
|
|
[]ExtOperand{ExtXmm(2), ExtMemory(1, 127), ExtXmm(1)},
|
|
"c4e26ad2497f", "c4 e2 6a d2 49 7f vpdpwsud 0x7f(%rcx),%xmm2,%xmm1"},
|
|
{"vpdpwsud memory source negative disp8", "VPDPWSUD",
|
|
[]ExtOperand{ExtXmm(2), ExtMemory(2, -128), ExtXmm(1)},
|
|
"c4e26ad24a80", "c4 e2 6a d2 4a 80 vpdpwsud -0x80(%rdx),%xmm2,%xmm1"},
|
|
{"vpdpwsud memory source disp32", "VPDPWSUD",
|
|
[]ExtOperand{ExtXmm(2), ExtMemory(1, 8128), ExtXmm(1)},
|
|
"c4e26ad289c01f0000", "c4 e2 6a d2 89 c0 1f 00 00 vpdpwsud 0x1fc0(%rcx),%xmm2,%xmm1"},
|
|
{"vpdpwsud memory source over an r9 base", "VPDPWSUD",
|
|
[]ExtOperand{ExtXmm(2), ExtMemory(9, 0), ExtXmm(12)},
|
|
"c4426ad221", "c4 42 6a d2 21 vpdpwsud (%r9),%xmm2,%xmm12"},
|
|
{"vpdpwsud memory source over an rsp base", "VPDPWSUD",
|
|
[]ExtOperand{ExtXmm(2), ExtMemory(4, 0), ExtXmm(1)},
|
|
"c4e26ad20c24", "c4 e2 6a d2 0c 24 vpdpwsud (%rsp),%xmm2,%xmm1"},
|
|
{"vpdpwusd memory source over a scaled index", "VPDPWUSD",
|
|
[]ExtOperand{ExtXmm(2), ExtScaledMemory(5, 14, 8, 127), ExtXmm(1)},
|
|
"c4a269d24cf57f", "c4 a2 69 d2 4c f5 7f vpdpwusd 0x7f(%rbp,%r14,8),%xmm2,%xmm1"},
|
|
}
|
|
|
|
// amd64ResolveEntry finds the table entry a golden row exercises: the entry
|
|
// is the one that accepts the row's operands, which is what pins the bytes to
|
|
// a single template when a mnemonic registers one entry per W bit.
|
|
func amd64ResolveEntry(mnem string, ops []ExtOperand) (ExtInstr, bool) {
|
|
var first ExtInstr
|
|
for _, in := range Extensions(AMD64) {
|
|
if in.Name != mnem {
|
|
continue
|
|
}
|
|
if _, err := in.Encode(ops); err == nil {
|
|
return in, true
|
|
}
|
|
if first.Name == "" {
|
|
first = in
|
|
}
|
|
}
|
|
if first.Name != "" {
|
|
return first, true
|
|
}
|
|
return ExtInstr{}, false
|
|
}
|
|
|
|
func amd64ExtInstr(t *testing.T, mnem string, class ExtOperandKind, preds ...func(ExtInstr) bool) ExtInstr {
|
|
t.Helper()
|
|
for _, in := range Extensions(AMD64) {
|
|
length := amd64LengthClass(in.Bytes)
|
|
if in.Vex {
|
|
length = amd64VexLengthClass(in.Bytes)
|
|
}
|
|
if in.Name != mnem || length != class {
|
|
continue
|
|
}
|
|
match := true
|
|
for _, p := range preds {
|
|
if !p(in) {
|
|
match = false
|
|
}
|
|
}
|
|
if match {
|
|
return in
|
|
}
|
|
}
|
|
t.Fatalf("no extended %s encoding at the %s vector length", mnem, class)
|
|
return ExtInstr{}
|
|
}
|
|
|
|
// amd64W1 names the W1 encoding of a mnemonic registered once per W bit.
|
|
func amd64W1(in ExtInstr) bool { return in.Bytes[2]&0x80 != 0 }
|
|
|
|
// withPred adapts an optional row predicate for the variadic lookup.
|
|
func withPred(p func(ExtInstr) bool) []func(ExtInstr) bool {
|
|
if p == nil {
|
|
return nil
|
|
}
|
|
return []func(ExtInstr) bool{p}
|
|
}
|
|
|
|
func TestAmd64ExtGoldenBytes(t *testing.T) {
|
|
for _, tt := range amd64GoldenRows {
|
|
in, ok := amd64ResolveEntry(tt.mnem, tt.ops)
|
|
if !ok {
|
|
t.Errorf("%s: no table entry for %s at the row's vector length", tt.name, tt.mnem)
|
|
continue
|
|
}
|
|
got, err := in.Encode(tt.ops)
|
|
if err != nil {
|
|
t.Errorf("%s: encode: %v", tt.name, err)
|
|
continue
|
|
}
|
|
if hex.EncodeToString(got) != tt.want {
|
|
t.Errorf("%s:\n got %x\n want %s", tt.name, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestAmd64ExtTemplateIntegrity checks the metadata contract: every entry
|
|
// names its manual reference, summary and feature, and every template carries
|
|
// the fixed shape of an EVEX register form with the register-derived bits
|
|
// zero, so a slip in the table is an error and not a stray byte. A VEX row
|
|
// is held to the C4 layout instead: five bytes, the map beside three zero
|
|
// register bits in byte one, W and vvvv zero in byte two and mod 11 in the
|
|
// ModR/M.
|
|
func TestAmd64ExtTemplateIntegrity(t *testing.T) {
|
|
features := map[ExtFeature]bool{
|
|
ExtFeatureBF16: true,
|
|
ExtFeatureVP2INTERSECT: true,
|
|
ExtFeatureFP16: true,
|
|
ExtFeatureVnniInt16: true,
|
|
}
|
|
for _, in := range Extensions(AMD64) {
|
|
if in.Name == "" || in.Summary == "" || in.Ref == "" {
|
|
t.Errorf("%+v: name, summary and reference are mandatory", in)
|
|
}
|
|
if !features[in.Feature] {
|
|
t.Errorf("%s: feature %q is not an amd64 extension feature", in.Name, in.Feature)
|
|
}
|
|
if in.Form.Arity() < 2 || in.Form.Arity() > 4 {
|
|
t.Errorf("%s: form %s carries an unusable arity %d", in.Name, in.Form, in.Form.Arity())
|
|
}
|
|
if in.Mem > in.Form.Arity() {
|
|
t.Errorf("%s: Mem names operand %d, outside the form's %d positions", in.Name, in.Mem, in.Form.Arity())
|
|
}
|
|
if in.Vex {
|
|
if len(in.Bytes) != 5 {
|
|
t.Errorf("%s: the template is %d bytes, want the 5-byte VEX register form", in.Name, len(in.Bytes))
|
|
continue
|
|
}
|
|
if in.Bytes[0] != 0xC4 {
|
|
t.Errorf("%s: the template opens with %02x, want the VEX escape c4", in.Name, in.Bytes[0])
|
|
}
|
|
if in.Bytes[1]&0xe0 != 0 {
|
|
t.Errorf("%s: byte one carries register bits %03b, want them zero", in.Name, in.Bytes[1]>>5)
|
|
}
|
|
if in.Bytes[1]&0x1f != 0x02 {
|
|
t.Errorf("%s: byte one carries the map %05b, want the 0f38 escape 00010", in.Name, in.Bytes[1]&0x1f)
|
|
}
|
|
if in.Bytes[2]&0xf8 != 0 {
|
|
t.Errorf("%s: byte two carries W or vvvv bits, want them zero: %08b", in.Name, in.Bytes[2])
|
|
}
|
|
if in.Bytes[4]&0x3f != 0 || in.Bytes[4]&0xc0 != 0xc0 {
|
|
t.Errorf("%s: byte four is %08b, want mod 11 with the reg and rm fields zero", in.Name, in.Bytes[4])
|
|
}
|
|
continue
|
|
}
|
|
if len(in.Bytes) != 6 {
|
|
t.Errorf("%s: the template is %d bytes, want the 6-byte EVEX register form", in.Name, len(in.Bytes))
|
|
continue
|
|
}
|
|
if in.Bytes[0] != 0x62 {
|
|
t.Errorf("%s: the template opens with %02x, want the EVEX escape 62", in.Name, in.Bytes[0])
|
|
}
|
|
if in.Bytes[1]&0xf0 != 0 {
|
|
t.Errorf("%s: byte one carries register bits %04b, want them zero", in.Name, in.Bytes[1]>>4)
|
|
}
|
|
if in.Bytes[2]&0x78 != 0 {
|
|
t.Errorf("%s: byte two carries vvvv bits %04b, want them zero", in.Name, in.Bytes[2]>>3&0xf)
|
|
}
|
|
if in.Bytes[2]&0x04 == 0 {
|
|
t.Errorf("%s: byte two lacks the reserved one-bit", in.Name)
|
|
}
|
|
if in.Bytes[3]&0x9f != 0 {
|
|
t.Errorf("%s: byte three carries z, b, V prime or aaa bits, want them zero: %08b", in.Name, in.Bytes[3])
|
|
}
|
|
if in.Bytes[5]&0x3f != 0 || in.Bytes[5]&0xc0 != 0xc0 {
|
|
t.Errorf("%s: byte five is %08b, want mod 11 with the reg and rm fields zero", in.Name, in.Bytes[5])
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestAmd64VexEncoder pins the VEX plumbing over a hand-built template: the
|
|
// register complements of R, X and B in byte one, vvvv's complement in byte
|
|
// two, the vector length bit two of byte two names and the memory shape's
|
|
// mod, SIB and displacement bytes, over the words the AVX-VNNI-INT16 dot
|
|
// product the mechanism serves quotes from GNU as.
|
|
func TestAmd64VexEncoder(t *testing.T) {
|
|
template := []byte{0xC4, 0x02, 0x02, 0xD2, 0xC0}
|
|
if got := amd64VexLengthClass(template); got != ExtXMM {
|
|
t.Errorf("the template reads as %s, want XMM", got)
|
|
}
|
|
if got := amd64VexLengthClass([]byte{0xC4, 0x02, 0x06, 0xD2, 0xC0}); got != ExtYMM {
|
|
t.Errorf("the wide template reads as %s, want YMM", got)
|
|
}
|
|
if got := hex.EncodeToString(amd64EncodeVex(template, 3, 2, 1)); got != "c4e26ad2d9" {
|
|
t.Errorf("amd64EncodeVex: got %s, want c4e26ad2d9", got)
|
|
}
|
|
// The registers above 7 clear R bar and B bar; vvvv keeps its complement.
|
|
if got := hex.EncodeToString(amd64EncodeVex(template, 9, 11, 12)); got != "c44222d2cc" {
|
|
t.Errorf("amd64EncodeVex, high registers: got %s, want c44222d2cc", got)
|
|
}
|
|
if got := hex.EncodeToString(amd64EncodeVexMemory(template, 1, 2, 1, 127)); got != "c4e26ad2497f" {
|
|
t.Errorf("amd64EncodeVexMemory: got %s, want c4e26ad2497f", got)
|
|
}
|
|
// The RSP base demands the SIB byte, the RBP base a scaled index form
|
|
// whose X bar clears under the index above 7.
|
|
if got := hex.EncodeToString(amd64EncodeVexMemory(template, 1, 2, 4, 0)); got != "c4e26ad20c24" {
|
|
t.Errorf("amd64EncodeVexMemory over RSP: got %s, want c4e26ad20c24", got)
|
|
}
|
|
if got := hex.EncodeToString(amd64EncodeVexScaledMemory(template, 1, 2, 5, 14, 8, 127)); got != "c4a26ad24cf57f" {
|
|
t.Errorf("amd64EncodeVexScaledMemory: got %s, want c4a26ad24cf57f", got)
|
|
}
|
|
}
|
|
|
|
// TestAmd64ExtEveryEntryCarriesGoldenVector pins the measure the layer is
|
|
// judged by: every registered entry is covered by at least one golden vector
|
|
// whose resolved entry has the very template, so an entry without provenance
|
|
// cannot hide.
|
|
func TestAmd64ExtEveryEntryCarriesGoldenVector(t *testing.T) {
|
|
for _, in := range Extensions(AMD64) {
|
|
found := false
|
|
for _, tt := range amd64GoldenRows {
|
|
cand, ok := amd64ResolveEntry(tt.mnem, tt.ops)
|
|
if ok && cand.Name == in.Name && string(cand.Bytes) == string(in.Bytes) {
|
|
found = true
|
|
}
|
|
}
|
|
if !found {
|
|
t.Errorf("%s (% x) has no golden vector", in.Name, in.Bytes)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAmd64ExtRejects(t *testing.T) {
|
|
for _, tt := range []struct {
|
|
name string
|
|
mnem string
|
|
ops []ExtOperand
|
|
quote string // a fragment the error carries
|
|
}{
|
|
{"wrong vector class", "VCVTNE2PS2BF16",
|
|
[]ExtOperand{ExtZmm(1), ExtZmm(2), ExtYmm(3)},
|
|
"wants a ZMM register"},
|
|
{"destination class is the source's on the narrow convert", "VCVTNEPS2BF16",
|
|
[]ExtOperand{ExtZmm(1), ExtZmm(2)},
|
|
"wants a YMM register"},
|
|
{"vector in the mask position", "VP2INTERSECTD",
|
|
[]ExtOperand{ExtZmm(1), ExtZmm(2), ExtZmm(3)},
|
|
"wants an opmask register"},
|
|
{"mask register beyond k7", "VP2INTERSECTD",
|
|
[]ExtOperand{ExtZmm(2), ExtZmm(1), ExtMask(8)},
|
|
"outside 0-7"},
|
|
{"vector where the general register belongs", "VCVTSH2SI",
|
|
[]ExtOperand{ExtXmm(1), ExtXmm(2)},
|
|
"wants a 32-bit general register"},
|
|
{"64-bit register on the W0 convert", "VCVTSI2SH",
|
|
[]ExtOperand{ExtXmm(29), ExtGpr64(12), ExtXmm(30)},
|
|
"wants a 32-bit general register"},
|
|
{"general register beyond r15", "VMOVW",
|
|
[]ExtOperand{ExtGpr32(16), ExtXmm(30)},
|
|
"outside 0-15"},
|
|
{"wrong arity", "VP2INTERSECTD",
|
|
[]ExtOperand{ExtZmm(2), ExtZmm(1)},
|
|
"takes 3 operands"},
|
|
{"arm64 arrangement suffix", "VCVTNE2PS2BF16",
|
|
[]ExtOperand{{Kind: ExtZMM, Reg: 1, Arr: ExtArrS}, ExtZmm(2), ExtZmm(3)},
|
|
"arrangement"},
|
|
{"predicate qualifier", "VCVTNEPS2BF16",
|
|
[]ExtOperand{{Kind: ExtZMM, Reg: 1, Qual: ExtQualZeroing}, ExtZmm(2)},
|
|
"predicate qualifier"},
|
|
{"vector where the control byte belongs", "VGETMANTSH",
|
|
[]ExtOperand{ExtXmm(28), ExtXmm(29), ExtXmm(30), ExtXmm(31)},
|
|
"wants an immediate control byte"},
|
|
{"reserved upper nibble on the mantissa control", "VGETMANTSH",
|
|
[]ExtOperand{ExtImmediate(0x7b), ExtXmm(28), ExtXmm(29), ExtXmm(30)},
|
|
"reserved and must be zero"},
|
|
{"control byte under the floor", "VREDUCESH",
|
|
[]ExtOperand{ExtImmediate(-1), ExtXmm(28), ExtXmm(29), ExtXmm(30)},
|
|
"outside the unsigned byte range"},
|
|
{"control byte over the top", "VRNDSCALESH",
|
|
[]ExtOperand{ExtImmediate(256), ExtXmm(28), ExtXmm(29), ExtXmm(30)},
|
|
"outside the unsigned byte range"},
|
|
{"shift on the control byte", "VRNDSCALESH",
|
|
[]ExtOperand{ExtShiftedImmediate(0x0b, 8), ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"take none"},
|
|
{"vector in the mask position of the compare", "VCMPSH",
|
|
[]ExtOperand{ExtImmediate(7), ExtXmm(28), ExtXmm(29), ExtXmm(30)},
|
|
"wants an opmask register"},
|
|
{"mask beyond k7 on the compare", "VCMPSH",
|
|
[]ExtOperand{ExtImmediate(7), ExtXmm(28), ExtXmm(29), ExtMask(8)},
|
|
"outside 0-7"},
|
|
{"memory in the arithmetic's first source", "VADDSH",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtXmm(28), ExtXmm(30)},
|
|
"wants an XMM register"},
|
|
{"memory in the arithmetic's destination", "VADDSH",
|
|
[]ExtOperand{ExtXmm(28), ExtXmm(29), ExtMemory(9, 0)},
|
|
"wants an XMM register"},
|
|
{"memory as the compare's mask destination", "VCMPSH",
|
|
[]ExtOperand{ExtImmediate(7), ExtXmm(28), ExtXmm(29), ExtMemory(9, 0)},
|
|
"wants an opmask register"},
|
|
{"memory as the convert's first source", "VCVTSI2SH",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtGpr32(2), ExtXmm(30)},
|
|
"wants an XMM register"},
|
|
{"memory as the mantissa control's first source", "VGETMANTSH",
|
|
[]ExtOperand{ExtImmediate(0x0b), ExtMemory(9, 0), ExtXmm(29), ExtXmm(30)},
|
|
"wants an XMM register"},
|
|
{"memory as the intersect source", "VP2INTERSECTD",
|
|
[]ExtOperand{ExtZmm(2), ExtMemory(9, 0), ExtMask(0)},
|
|
"wants a ZMM register"},
|
|
{"memory as the convert's first source", "VCVTSS2SH",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtXmm(28), ExtXmm(30)},
|
|
"wants an XMM register"},
|
|
{"memory as the control byte", "VGETMANTSH",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtXmm(28), ExtXmm(29), ExtXmm(30)},
|
|
"wants an immediate control byte"},
|
|
{"memory in the compare's destination", "VCOMISH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(9, 0)},
|
|
"wants an XMM register"},
|
|
{"memory as the packed square root's destination", "VSQRTPH",
|
|
[]ExtOperand{ExtZmm(29), ExtMemory(9, 0)},
|
|
"wants a ZMM register"},
|
|
{"memory as the narrow convert's destination", "VCVTNEPS2BF16",
|
|
[]ExtOperand{ExtZmm(5), ExtMemory(9, 0)},
|
|
"wants a YMM register"},
|
|
{"broadcast in a register position", "VCVTNE2PS2BF16",
|
|
[]ExtOperand{ExtZmm(5), ExtBroadcast(1, 0), ExtZmm(6)},
|
|
"carries a broadcast, the position takes a register"},
|
|
{"broadcast as the packed arithmetic's destination", "VADDPH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtBroadcast(9, 0)},
|
|
"carries a broadcast, the position takes a register"},
|
|
{"broadcast on the scalar arithmetic's memory source", "VADDSH",
|
|
[]ExtOperand{ExtXmm(29), ExtBroadcast(9, 0), ExtXmm(30)},
|
|
"carries a broadcast, the entry's memory operand takes none"},
|
|
{"broadcast on the scalar compare's memory operand", "VCOMISH",
|
|
[]ExtOperand{ExtBroadcast(9, 0), ExtXmm(30)},
|
|
"carries a broadcast, the entry's memory operand takes none"},
|
|
{"broadcast on the narrow convert's full-width source", "VCVTNEPS2BF16",
|
|
[]ExtOperand{ExtBroadcast(1, 0), ExtYmm(6)},
|
|
"carries a broadcast, the entry's memory operand takes none"},
|
|
{"scaled index beyond r15", "VCOMISH",
|
|
[]ExtOperand{ExtScaledMemory(5, 16, 8, 0x10000000), ExtXmm(30)},
|
|
"index register 16, outside 0-15"},
|
|
{"RSP as the scaled index", "VCOMISH",
|
|
[]ExtOperand{ExtScaledMemory(5, 4, 8, 0x10000000), ExtXmm(30)},
|
|
"cannot encode"},
|
|
{"a scale the multipliers do not carry", "VADDPH",
|
|
[]ExtOperand{ExtZmm(29), ExtScaledMemory(1, 14, 3, 0), ExtZmm(30)},
|
|
"outside the byte multipliers"},
|
|
{"K0 as the write mask", "VADDPH",
|
|
[]ExtOperand{ExtZmm(28), ExtZmm(30), ExtWriteMasked(ExtZmm(29), 0, true)},
|
|
"outside the masking registers k1-k7"},
|
|
{"zeroing without a write mask", "VADDPH",
|
|
[]ExtOperand{ExtZmm(28), ExtZmm(30), ExtOperand{Kind: ExtZMM, Reg: 29, Zeroing: true}},
|
|
"carries zeroing without a write mask"},
|
|
{"write mask on the scalar arithmetic", "VADDSH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtWriteMasked(ExtXmm(30), 3, true)},
|
|
"the entry's destination takes none"},
|
|
{"write mask on the compare without a vector destination", "VCOMISH",
|
|
[]ExtOperand{ExtXmm(29), ExtWriteMasked(ExtXmm(30), 2, false)},
|
|
"the entry's destination takes none"},
|
|
{"write mask on the intersection's vector source", "VP2INTERSECTD",
|
|
[]ExtOperand{ExtWriteMasked(ExtZmm(2), 3, false), ExtZmm(1), ExtMask(0)},
|
|
"the position takes none"},
|
|
{"write mask on a source position", "VADDPH",
|
|
[]ExtOperand{ExtZmm(29), ExtWriteMasked(ExtZmm(28), 3, false), ExtZmm(30)},
|
|
"the position takes none"},
|
|
{"write mask on the control form's destination", "VGETMANTSH",
|
|
[]ExtOperand{ExtImmediate(0x0b), ExtXmm(29), ExtXmm(28), ExtWriteMasked(ExtXmm(30), 7, true)},
|
|
"the entry's destination takes none"},
|
|
{"write mask where the destination is memory", "VCOMISH",
|
|
[]ExtOperand{ExtXmm(30), ExtOperand{Kind: ExtMem, Reg: 9, HasMask: true, Mask: 2}},
|
|
"the entry's destination takes none"},
|
|
{"rounding on the 256-bit arithmetic", "VADDPH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtRounded(ExtYmm(6), ExtRoundNearest)},
|
|
"the entry's destination takes none"},
|
|
{"bare {sae} on the embedded-rounding arithmetic", "VADDPH",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(4), ExtRounded(ExtZmm(6), ExtRoundSAE)},
|
|
"spells {sae} without a mode"},
|
|
{"a named mode on the exception-suppressing minimum", "VMINPH",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(4), ExtRounded(ExtZmm(6), ExtRoundDown)},
|
|
"suppresses exceptions alone"},
|
|
{"rounding over a memory source", "VADDSH",
|
|
[]ExtOperand{ExtXmm(29), ExtMemory(9, 0), ExtRounded(ExtXmm(30), ExtRoundNearest)},
|
|
"the memory form takes no rounding control"},
|
|
{"rounding over the scalar convert's memory source", "VCVTSS2SH",
|
|
[]ExtOperand{ExtXmm(5), ExtMemory(9, 0), ExtRounded(ExtXmm(6), ExtRoundNearest)},
|
|
"the memory form takes no rounding control"},
|
|
{"rounding beside the converting memory source", "VCVTW2PH",
|
|
[]ExtOperand{ExtMemory(9, 0), ExtRounded(ExtZmm(30), ExtRoundNearest)},
|
|
"the memory form takes no rounding control"},
|
|
{"rounding on a source position", "VADDPH",
|
|
[]ExtOperand{ExtZmm(5), ExtRounded(ExtZmm(4), ExtRoundUp), ExtZmm(6)},
|
|
"the position takes none"},
|
|
{"rounding on the control byte", "VRNDSCALESH",
|
|
[]ExtOperand{{Kind: ExtImm, Imm: 0x0b, Round: ExtRoundSAE}, ExtXmm(29), ExtXmm(28), ExtXmm(30)},
|
|
"the immediate takes none"},
|
|
{"rounding on the compare's memory operand", "VCOMISH",
|
|
[]ExtOperand{ExtOperand{Kind: ExtMem, Reg: 9, Round: ExtRoundSAE}, ExtXmm(30)},
|
|
"the memory operand takes none"},
|
|
{"rounding on an entry without the capability", "VMOVSH",
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(28), ExtRounded(ExtXmm(30), ExtRoundNearest)},
|
|
"the entry's destination takes none"},
|
|
{"rounding on the exactly-widening convert", "VCVTPH2PD",
|
|
[]ExtOperand{ExtXmm(5), ExtRounded(ExtZmm(6), ExtRoundNearest)},
|
|
"the entry's destination takes none"},
|
|
{"wrong source class on the widening convert", "VCVTPH2DQ",
|
|
[]ExtOperand{ExtZmm(5), ExtZmm(6)},
|
|
"wants a YMM register"},
|
|
{"wrong source class on the quarter convert", "VCVTPH2QQ",
|
|
[]ExtOperand{ExtYmm(5), ExtZmm(6)},
|
|
"wants an XMM register"},
|
|
{"wrong destination on the quarter-destination convert", "VCVTQQ2PH",
|
|
[]ExtOperand{ExtZmm(5), ExtYmm(6)},
|
|
"wants an XMM register"},
|
|
{"broadcast on the full-width FP16 source", "VCVTPH2W",
|
|
[]ExtOperand{ExtBroadcast(9, 0), ExtZmm(30)},
|
|
"the entry's memory operand takes none"},
|
|
{"broadcast on the packed control form's source", "VRNDSCALEPH",
|
|
[]ExtOperand{ExtImmediate(0x7b), ExtBroadcast(9, 0), ExtZmm(30)},
|
|
"the entry's memory operand takes none"},
|
|
{"reserved upper nibble on the packed mantissa control", "VGETMANTPH",
|
|
[]ExtOperand{ExtImmediate(0x7b), ExtZmm(5), ExtZmm(6)},
|
|
"reserved and must be zero"},
|
|
{"broadcast on the scalar multiply-add", "VFMADD132SH",
|
|
[]ExtOperand{ExtXmm(29), ExtBroadcast(9, 0), ExtXmm(30)},
|
|
"the entry's memory operand takes none"},
|
|
{"broadcast on the complex multiply", "VFMULCPH",
|
|
[]ExtOperand{ExtZmm(29), ExtBroadcast(9, 0), ExtZmm(30)},
|
|
"the entry's memory operand takes none"},
|
|
{"broadcast on the complex multiply-add", "VFMADDCPH",
|
|
[]ExtOperand{ExtZmm(29), ExtBroadcast(9, 0), ExtZmm(30)},
|
|
"the entry's memory operand takes none"},
|
|
{"rounding on the 256-bit complex multiply-add", "VFMADDCPH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtRounded(ExtYmm(6), ExtRoundNearest)},
|
|
"the entry's destination takes none"},
|
|
{"rounding over the complex multiply-add's memory source", "VFMADDCPH",
|
|
[]ExtOperand{ExtZmm(29), ExtMemory(9, 0), ExtRounded(ExtZmm(30), ExtRoundNearest)},
|
|
"the memory form takes no rounding control"},
|
|
{"rounding on the 256-bit multiply-add", "VFMADD132PH",
|
|
[]ExtOperand{ExtYmm(5), ExtYmm(4), ExtRounded(ExtYmm(6), ExtRoundNearest)},
|
|
"the entry's destination takes none"},
|
|
{"rounding on the minimum-maximum", "VMINMAXPH",
|
|
[]ExtOperand{ExtImmediate(0x88), ExtZmm(5), ExtZmm(4), ExtRounded(ExtZmm(6), ExtRoundNearest)},
|
|
"the entry's destination takes none"},
|
|
{"write mask on the scalar minimum-maximum", "VMINMAXSH",
|
|
[]ExtOperand{ExtImmediate(0x88), ExtXmm(29), ExtXmm(28), ExtWriteMasked(ExtXmm(30), 7, true)},
|
|
"the entry's destination takes none"},
|
|
{"broadcast on the scalar minimum-maximum's memory source", "VMINMAXSH",
|
|
[]ExtOperand{ExtImmediate(0x88), ExtXmm(29), ExtBroadcast(9, 0), ExtXmm(30)},
|
|
"the entry's memory operand takes none"},
|
|
{"register beyond r15 on the dot product", "VPDPWSUD",
|
|
[]ExtOperand{ExtXmm(16), ExtXmm(1), ExtXmm(2)},
|
|
"outside 0-15"},
|
|
{"write mask on the dot product", "VPDPWSUD",
|
|
[]ExtOperand{ExtXmm(2), ExtXmm(1), ExtWriteMasked(ExtXmm(3), 3, true)},
|
|
"the entry's destination takes none"},
|
|
{"broadcast on the dot product's memory source", "VPDPWSUD",
|
|
[]ExtOperand{ExtXmm(2), ExtBroadcast(9, 0), ExtXmm(1)},
|
|
"the entry's memory operand takes none"},
|
|
{"a register where the multiply-add reads memory", "VFMSUB231PH",
|
|
[]ExtOperand{ExtZmm(29), ExtYmm(4), ExtZmm(30)},
|
|
"wants a ZMM register"},
|
|
{"the complex multiply's scalar destination", "VFMULCPH",
|
|
[]ExtOperand{ExtZmm(29), ExtZmm(28), ExtXmm(30)},
|
|
"wants a ZMM register"},
|
|
} {
|
|
in := amd64ExtInstr(t, tt.mnem, operandClass(t, tt.ops))
|
|
_, err := in.Encode(tt.ops)
|
|
if err == nil {
|
|
t.Errorf("%s: encode succeeded, want an error", tt.name)
|
|
continue
|
|
}
|
|
if !strings.Contains(err.Error(), tt.quote) {
|
|
t.Errorf("%s: error %q lacks %q", tt.name, err, tt.quote)
|
|
}
|
|
}
|
|
// The W1 convert refuses the 32-bit register the W0 entry takes.
|
|
in := amd64ExtInstr(t, "VCVTSH2SI", ExtXMM, amd64W1)
|
|
if _, err := in.Encode([]ExtOperand{ExtXmm(30), ExtGpr32(2)}); err == nil {
|
|
t.Error("a 32-bit register encoded on the W1 convert, want an error")
|
|
} else if !strings.Contains(err.Error(), "wants a 64-bit general register") {
|
|
t.Errorf("the W1 error %q does not name the 64-bit class", err)
|
|
}
|
|
}
|
|
|
|
// TestAmd64ExtMemoryFormRejects covers the shapes the memory forms refuse:
|
|
// a register in the load's memory position, a memory operand in the store's
|
|
// register position, and the out-of-range bases and displacements. The
|
|
// rows resolve against the load and store entries themselves, which the
|
|
// name-and-class lookup cannot pick alone: the register forms of the same
|
|
// mnemonics share the class.
|
|
func TestAmd64ExtMemoryFormRejects(t *testing.T) {
|
|
load := func(in ExtInstr) bool { return in.Form == ExtFormAmdMemVec }
|
|
store := func(in ExtInstr) bool { return in.Form == ExtFormAmdVecMem }
|
|
for _, tt := range []struct {
|
|
name string
|
|
mnem string
|
|
pick func(ExtInstr) bool
|
|
ops []ExtOperand
|
|
quote string
|
|
}{
|
|
{"vector in the load's memory position", "VMOVSH", load,
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(30)},
|
|
"wants a memory operand"},
|
|
{"memory in the store's register position", "VMOVSH", store,
|
|
[]ExtOperand{ExtMemory(9, 0), ExtMemory(1, 0)},
|
|
"wants an XMM register"},
|
|
{"vector in the store's memory position", "VMOVSH", store,
|
|
[]ExtOperand{ExtXmm(29), ExtXmm(30)},
|
|
"wants a memory operand"},
|
|
{"base beyond r15 on the load", "VMOVW", load,
|
|
[]ExtOperand{ExtMemory(16, 0), ExtXmm(30)},
|
|
"outside 0-15"},
|
|
{"displacement past the signed 32-bit range on the store", "VMOVW", store,
|
|
[]ExtOperand{ExtXmm(30), ExtMemory(8, 1<<32)},
|
|
"outside the signed 32-bit range"},
|
|
{"broadcast on the load's memory position", "VMOVSH", load,
|
|
[]ExtOperand{ExtBroadcast(9, 0), ExtXmm(30)},
|
|
"carries a broadcast, the entry's memory operand takes none"},
|
|
{"broadcast destination on the store", "VMOVSH", store,
|
|
[]ExtOperand{ExtXmm(30), ExtBroadcast(9, 0)},
|
|
"carries a broadcast, the entry's memory operand takes none"},
|
|
{"write mask on the store's memory destination", "VMOVSH", store,
|
|
[]ExtOperand{ExtXmm(30), ExtOperand{Kind: ExtMem, Reg: 9, HasMask: true, Mask: 2}},
|
|
"the memory operand takes none"},
|
|
{"zeroing on the store's memory destination", "VMOVSH", store,
|
|
[]ExtOperand{ExtXmm(30), ExtOperand{Kind: ExtMem, Reg: 9, Zeroing: true}},
|
|
"the memory operand takes none"},
|
|
} {
|
|
in := amd64ExtInstr(t, tt.mnem, ExtXMM, tt.pick)
|
|
_, err := in.Encode(tt.ops)
|
|
if err == nil {
|
|
t.Errorf("%s: encode succeeded, want an error", tt.name)
|
|
continue
|
|
}
|
|
if !strings.Contains(err.Error(), tt.quote) {
|
|
t.Errorf("%s: error %q lacks %q", tt.name, err, tt.quote)
|
|
}
|
|
}
|
|
}
|
|
|
|
// operandClass names the vector class a row exercises, the key the entry
|
|
// lookup resolves with.
|
|
func operandClass(t *testing.T, ops []ExtOperand) ExtOperandKind {
|
|
t.Helper()
|
|
for _, op := range ops {
|
|
switch op.Kind {
|
|
case ExtXMM, ExtYMM, ExtZMM:
|
|
return op.Kind
|
|
}
|
|
}
|
|
t.Fatal("the row carries no vector operand to pick the entry with")
|
|
return ExtXMM
|
|
}
|
|
|
|
// TestAmd64ExtImm8Tables pins the imm8 semantics the layer carries as data
|
|
// against the SDM tables they are transcribed from: the rounding modes of
|
|
// the round control, the sign control of the mantissa extraction and the 32
|
|
// comparison predicates, in encoding order.
|
|
func TestAmd64ExtImm8Tables(t *testing.T) {
|
|
roundModes := [4]string{
|
|
"round to nearest (even)",
|
|
"round down (toward -infinity)",
|
|
"round up (toward +infinity)",
|
|
"round toward zero (truncate)",
|
|
}
|
|
if ExtFP16RoundingModes != roundModes {
|
|
t.Errorf("rounding modes %q, want the SDM RC field order", ExtFP16RoundingModes)
|
|
}
|
|
for i, sign := range ExtFP16GetMantSigns {
|
|
switch i {
|
|
case 0:
|
|
if sign != "the sign of the source" {
|
|
t.Errorf("sign control 0b00 = %q, want the source's own sign", sign)
|
|
}
|
|
case 1:
|
|
if sign != "positive" {
|
|
t.Errorf("sign control 0b01 = %q, want a forced positive", sign)
|
|
}
|
|
default:
|
|
if sign != "the indefinite NaN when the source is negative" {
|
|
t.Errorf("sign control 0b1x = %q, want the indefinite NaN branch", sign)
|
|
}
|
|
}
|
|
}
|
|
predicates := map[int]string{
|
|
0: "EQ_OQ", 1: "LT_OS", 2: "LE_OS", 3: "UNORD_Q", 4: "NEQ_UQ",
|
|
5: "NLT_US", 6: "NLE_US", 7: "ORD_Q", 8: "EQ_UQ", 15: "TRUE_UQ",
|
|
16: "EQ_OS", 23: "ORD_S", 24: "EQ_US", 27: "FALSE_OS", 31: "TRUE_US",
|
|
}
|
|
for i, want := range predicates {
|
|
if got := ExtFP16CmpPredicates[i]; got != want {
|
|
t.Errorf("predicate 0x%02x = %q, want %q", i, got, want)
|
|
}
|
|
}
|
|
if ExtFP16CmpPredicates[31] != "TRUE_US" {
|
|
t.Errorf("the predicate table ends at %q, want TRUE_US", ExtFP16CmpPredicates[31])
|
|
}
|
|
}
|
|
|
|
// TestAmd64ExtArchBinding pins the layer's architecture binding: only riscv
|
|
// and loong64 have no extended layer, arm64's lives in arm64_ext.go and the
|
|
// amd64 one here.
|
|
func TestAmd64ExtArchBinding(t *testing.T) {
|
|
for _, a := range []Arch{RISCV, LOONG64, Unknown} {
|
|
if got := Extensions(a); len(got) != 0 {
|
|
t.Errorf("Extensions(%s) carries %d instructions, want none", a, len(got))
|
|
}
|
|
}
|
|
if got := Extensions(AMD64); len(got) != 191 {
|
|
t.Errorf("the amd64 layer registers %d instructions, want 191", len(got))
|
|
}
|
|
}
|