diff --git a/asm/amd64_vexparity_test.go b/asm/amd64_vexparity_test.go new file mode 100644 index 0000000..111972c --- /dev/null +++ b/asm/amd64_vexparity_test.go @@ -0,0 +1,835 @@ +// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org) +// SPDX-License-Identifier: BSD-3-Clause + +package asm + +import ( + "slices" + "strings" + "testing" +) + +// amd64VexParityCorpus holds every line the Go toolchain's own +// amd64enc.s carries for the mnemonics the full-file byte sweep +// flagged: the VEX forms the toolchain prefers for plain vector +// registers, the compare-with-predicate family and the byte-level +// corrections (PEXTRW's GPR fields, PUSHW and POPW widths, the double +// shift's high register field, VCOMISS's prefix, RORX's destination +// bit, the variable shifts' consolidated rows). Each entry lists the +// byte strings go tool asm emits or accepts for the line; a line +// passes when the assembled bytes match one of them. +var amd64VexParityCorpus = []struct { + line string + want string +}{ + {"PEXTRW $7, X11, (BX)", "66 44 0f 3a 15 1b 07"}, + {"PEXTRW $7, X11, (R11)", "66 45 0f 3a 15 1b 07"}, + {"PEXTRW $7, X11, DX", "66 41 0f c5 d3 07|66 44 0f 3a 15 da 07"}, + {"PEXTRW $7, X11, R11", "66 45 0f c5 db 07|66 45 0f 3a 15 db 07"}, + {"PEXTRW $7, X2, (BX)", "66 0f 3a 15 13 07"}, + {"PEXTRW $7, X2, (R11)", "66 41 0f 3a 15 13 07"}, + {"PEXTRW $7, X2, DX", "66 0f c5 d2 07|66 0f 3a 15 d2 07"}, + {"PEXTRW $7, X2, R11", "66 44 0f c5 da 07|66 41 0f 3a 15 d3 07"}, + {"POPW (BX)", "66 8f 03"}, + {"POPW (R11)", "66 41 8f 03"}, + {"POPW DX", "66 8f c2|66 5a"}, + {"POPW R11", "66 41 8f c3|66 41 5b"}, + {"PUSHW $61731", "66 68 23 f1"}, + {"PUSHW (BX)", "66 ff 33"}, + {"PUSHW (R11)", "66 41 ff 33"}, + {"PUSHW DX", "66 ff f2|66 52"}, + {"PUSHW R11", "66 41 ff f3|66 41 53"}, + {"RORXL $7, (BX), DX", "c4 e3 7b f0 13 07"}, + {"RORXL $7, (BX), R11", "c4 63 7b f0 1b 07"}, + {"RORXL $7, (R11), DX", "c4 c3 7b f0 13 07"}, + {"RORXL $7, (R11), R11", "c4 43 7b f0 1b 07"}, + {"RORXL $7, DX, DX", "c4 e3 7b f0 d2 07"}, + {"RORXL $7, DX, R11", "c4 63 7b f0 da 07"}, + {"RORXL $7, R11, DX", "c4 c3 7b f0 d3 07"}, + {"RORXL $7, R11, R11", "c4 43 7b f0 db 07"}, + {"RORXQ $7, (BX), DX", "c4 e3 fb f0 13 07"}, + {"RORXQ $7, (BX), R11", "c4 63 fb f0 1b 07"}, + {"RORXQ $7, (R11), DX", "c4 c3 fb f0 13 07"}, + {"RORXQ $7, (R11), R11", "c4 43 fb f0 1b 07"}, + {"RORXQ $7, DX, DX", "c4 e3 fb f0 d2 07"}, + {"RORXQ $7, DX, R11", "c4 63 fb f0 da 07"}, + {"RORXQ $7, R11, DX", "c4 c3 fb f0 d3 07"}, + {"RORXQ $7, R11, R11", "c4 43 fb f0 db 07"}, + {"SHLL $1, (BX)", "d1 23"}, + {"SHLL $1, (R11)", "41 d1 23"}, + {"SHLL $1, DX", "d1 e2"}, + {"SHLL $1, R11", "41 d1 e3"}, + {"SHLL $7, (BX)", "c1 23 07"}, + {"SHLL $7, (R11)", "41 c1 23 07"}, + {"SHLL $7, DX", "c1 e2 07"}, + {"SHLL $7, DX, (BX)", "0f a4 13 07"}, + {"SHLL $7, DX, (R11)", "41 0f a4 13 07"}, + {"SHLL $7, DX, DX", "0f a4 d2 07"}, + {"SHLL $7, DX, R11", "41 0f a4 d3 07"}, + {"SHLL $7, R11", "41 c1 e3 07"}, + {"SHLL $7, R11, (BX)", "44 0f a4 1b 07"}, + {"SHLL $7, R11, (R11)", "45 0f a4 1b 07"}, + {"SHLL $7, R11, DX", "44 0f a4 da 07"}, + {"SHLL $7, R11, R11", "45 0f a4 db 07"}, + {"SHLL CL, (BX)", "d3 23"}, + {"SHLL CL, (R11)", "41 d3 23"}, + {"SHLL CL, DX", "d3 e2"}, + {"SHLL CL, DX, (BX)", "0f a5 13"}, + {"SHLL CL, DX, (R11)", "41 0f a5 13"}, + {"SHLL CL, DX, DX", "0f a5 d2"}, + {"SHLL CL, DX, R11", "41 0f a5 d3"}, + {"SHLL CL, R11", "41 d3 e3"}, + {"SHLL CL, R11, (BX)", "44 0f a5 1b"}, + {"SHLL CL, R11, (R11)", "45 0f a5 1b"}, + {"SHLL CL, R11, DX", "44 0f a5 da"}, + {"SHLL CL, R11, R11", "45 0f a5 db"}, + {"SHLQ $1, (BX)", "48 d1 23"}, + {"SHLQ $1, (R11)", "49 d1 23"}, + {"SHLQ $1, DX", "48 d1 e2"}, + {"SHLQ $1, R11", "49 d1 e3"}, + {"SHLQ $7, (BX)", "48 c1 23 07"}, + {"SHLQ $7, (R11)", "49 c1 23 07"}, + {"SHLQ $7, DX", "48 c1 e2 07"}, + {"SHLQ $7, DX, (BX)", "48 0f a4 13 07"}, + {"SHLQ $7, DX, (R11)", "49 0f a4 13 07"}, + {"SHLQ $7, DX, DX", "48 0f a4 d2 07"}, + {"SHLQ $7, DX, R11", "49 0f a4 d3 07"}, + {"SHLQ $7, R11", "49 c1 e3 07"}, + {"SHLQ $7, R11, (BX)", "4c 0f a4 1b 07"}, + {"SHLQ $7, R11, (R11)", "4d 0f a4 1b 07"}, + {"SHLQ $7, R11, DX", "4c 0f a4 da 07"}, + {"SHLQ $7, R11, R11", "4d 0f a4 db 07"}, + {"SHLQ CL, (BX)", "48 d3 23"}, + {"SHLQ CL, (R11)", "49 d3 23"}, + {"SHLQ CL, DX", "48 d3 e2"}, + {"SHLQ CL, DX, (BX)", "48 0f a5 13"}, + {"SHLQ CL, DX, (R11)", "49 0f a5 13"}, + {"SHLQ CL, DX, DX", "48 0f a5 d2"}, + {"SHLQ CL, DX, R11", "49 0f a5 d3"}, + {"SHLQ CL, R11", "49 d3 e3"}, + {"SHLQ CL, R11, (BX)", "4c 0f a5 1b"}, + {"SHLQ CL, R11, (R11)", "4d 0f a5 1b"}, + {"SHLQ CL, R11, DX", "4c 0f a5 da"}, + {"SHLQ CL, R11, R11", "4d 0f a5 db"}, + {"SHLW $1, (BX)", "66 d1 23"}, + {"SHLW $1, (R11)", "66 41 d1 23"}, + {"SHLW $1, DX", "66 d1 e2"}, + {"SHLW $1, R11", "66 41 d1 e3"}, + {"SHLW $7, (BX)", "66 c1 23 07"}, + {"SHLW $7, (R11)", "66 41 c1 23 07"}, + {"SHLW $7, DX", "66 c1 e2 07"}, + {"SHLW $7, DX, (BX)", "66 0f a4 13 07"}, + {"SHLW $7, DX, (R11)", "66 41 0f a4 13 07"}, + {"SHLW $7, DX, DX", "66 0f a4 d2 07"}, + {"SHLW $7, DX, R11", "66 41 0f a4 d3 07"}, + {"SHLW $7, R11", "66 41 c1 e3 07"}, + {"SHLW $7, R11, (BX)", "66 44 0f a4 1b 07"}, + {"SHLW $7, R11, (R11)", "66 45 0f a4 1b 07"}, + {"SHLW $7, R11, DX", "66 44 0f a4 da 07"}, + {"SHLW $7, R11, R11", "66 45 0f a4 db 07"}, + {"SHLW CL, (BX)", "66 d3 23"}, + {"SHLW CL, (R11)", "66 41 d3 23"}, + {"SHLW CL, DX", "66 d3 e2"}, + {"SHLW CL, DX, (BX)", "66 0f a5 13"}, + {"SHLW CL, DX, (R11)", "66 41 0f a5 13"}, + {"SHLW CL, DX, DX", "66 0f a5 d2"}, + {"SHLW CL, DX, R11", "66 41 0f a5 d3"}, + {"SHLW CL, R11", "66 41 d3 e3"}, + {"SHLW CL, R11, (BX)", "66 44 0f a5 1b"}, + {"SHLW CL, R11, (R11)", "66 45 0f a5 1b"}, + {"SHLW CL, R11, DX", "66 44 0f a5 da"}, + {"SHLW CL, R11, R11", "66 45 0f a5 db"}, + {"VCMPPD $7, (BX), X9, X11", "c4 61 31 c2 1b 07|c5 31 c2 1b 07"}, + {"VCMPPD $7, (BX), X9, X2", "c4 e1 31 c2 13 07|c5 b1 c2 13 07"}, + {"VCMPPD $7, (BX), Y15, Y11", "c4 61 05 c2 1b 07|c5 05 c2 1b 07"}, + {"VCMPPD $7, (BX), Y15, Y2", "c4 e1 05 c2 13 07|c5 85 c2 13 07"}, + {"VCMPPD $7, (R11), X9, X11", "c4 41 31 c2 1b 07"}, + {"VCMPPD $7, (R11), X9, X2", "c4 c1 31 c2 13 07"}, + {"VCMPPD $7, (R11), Y15, Y11", "c4 41 05 c2 1b 07"}, + {"VCMPPD $7, (R11), Y15, Y2", "c4 c1 05 c2 13 07"}, + {"VCMPPD $7, X11, X9, X11", "c4 41 31 c2 db 07"}, + {"VCMPPD $7, X11, X9, X2", "c4 c1 31 c2 d3 07"}, + {"VCMPPD $7, X2, X9, X11", "c4 61 31 c2 da 07|c5 31 c2 da 07"}, + {"VCMPPD $7, X2, X9, X2", "c4 e1 31 c2 d2 07|c5 b1 c2 d2 07"}, + {"VCMPPD $7, Y11, Y15, Y11", "c4 41 05 c2 db 07"}, + {"VCMPPD $7, Y11, Y15, Y2", "c4 c1 05 c2 d3 07"}, + {"VCMPPD $7, Y2, Y15, Y11", "c4 61 05 c2 da 07|c5 05 c2 da 07"}, + {"VCMPPD $7, Y2, Y15, Y2", "c4 e1 05 c2 d2 07|c5 85 c2 d2 07"}, + {"VCMPPS $7, (BX), X9, X11", "c4 61 30 c2 1b 07|c5 30 c2 1b 07"}, + {"VCMPPS $7, (BX), X9, X2", "c4 e1 30 c2 13 07|c5 b0 c2 13 07"}, + {"VCMPPS $7, (BX), Y15, Y11", "c4 61 04 c2 1b 07|c5 04 c2 1b 07"}, + {"VCMPPS $7, (BX), Y15, Y2", "c4 e1 04 c2 13 07|c5 84 c2 13 07"}, + {"VCMPPS $7, (R11), X9, X11", "c4 41 30 c2 1b 07"}, + {"VCMPPS $7, (R11), X9, X2", "c4 c1 30 c2 13 07"}, + {"VCMPPS $7, (R11), Y15, Y11", "c4 41 04 c2 1b 07"}, + {"VCMPPS $7, (R11), Y15, Y2", "c4 c1 04 c2 13 07"}, + {"VCMPPS $7, X11, X9, X11", "c4 41 30 c2 db 07"}, + {"VCMPPS $7, X11, X9, X2", "c4 c1 30 c2 d3 07"}, + {"VCMPPS $7, X2, X9, X11", "c4 61 30 c2 da 07|c5 30 c2 da 07"}, + {"VCMPPS $7, X2, X9, X2", "c4 e1 30 c2 d2 07|c5 b0 c2 d2 07"}, + {"VCMPPS $7, Y11, Y15, Y11", "c4 41 04 c2 db 07"}, + {"VCMPPS $7, Y11, Y15, Y2", "c4 c1 04 c2 d3 07"}, + {"VCMPPS $7, Y2, Y15, Y11", "c4 61 04 c2 da 07|c5 04 c2 da 07"}, + {"VCMPPS $7, Y2, Y15, Y2", "c4 e1 04 c2 d2 07|c5 84 c2 d2 07"}, + {"VCMPSD $7, (BX), X9, X11", "c4 61 33 c2 1b 07|c5 33 c2 1b 07"}, + {"VCMPSD $7, (BX), X9, X2", "c4 e1 33 c2 13 07|c5 b3 c2 13 07"}, + {"VCMPSD $7, (R11), X9, X11", "c4 41 33 c2 1b 07"}, + {"VCMPSD $7, (R11), X9, X2", "c4 c1 33 c2 13 07"}, + {"VCMPSD $7, X11, X9, X11", "c4 41 33 c2 db 07"}, + {"VCMPSD $7, X11, X9, X2", "c4 c1 33 c2 d3 07"}, + {"VCMPSD $7, X2, X9, X11", "c4 61 33 c2 da 07|c5 33 c2 da 07"}, + {"VCMPSD $7, X2, X9, X2", "c4 e1 33 c2 d2 07|c5 b3 c2 d2 07"}, + {"VCMPSS $7, (BX), X9, X11", "c4 61 32 c2 1b 07|c5 32 c2 1b 07"}, + {"VCMPSS $7, (BX), X9, X2", "c4 e1 32 c2 13 07|c5 b2 c2 13 07"}, + {"VCMPSS $7, (R11), X9, X11", "c4 41 32 c2 1b 07"}, + {"VCMPSS $7, (R11), X9, X2", "c4 c1 32 c2 13 07"}, + {"VCMPSS $7, X11, X9, X11", "c4 41 32 c2 db 07"}, + {"VCMPSS $7, X11, X9, X2", "c4 c1 32 c2 d3 07"}, + {"VCMPSS $7, X2, X9, X11", "c4 61 32 c2 da 07|c5 32 c2 da 07"}, + {"VCMPSS $7, X2, X9, X2", "c4 e1 32 c2 d2 07|c5 b2 c2 d2 07"}, + {"VCOMISS (BX), X11", "c4 61 78 2f 1b|c5 78 2f 1b"}, + {"VCOMISS (BX), X2", "c4 e1 78 2f 13|c5 f8 2f 13"}, + {"VCOMISS (R11), X11", "c4 41 78 2f 1b"}, + {"VCOMISS (R11), X2", "c4 c1 78 2f 13"}, + {"VCOMISS X11, X11", "c4 41 78 2f db"}, + {"VCOMISS X11, X2", "c4 c1 78 2f d3"}, + {"VCOMISS X2, X11", "c4 61 78 2f da|c5 78 2f da"}, + {"VCOMISS X2, X2", "c4 e1 78 2f d2|c5 f8 2f d2"}, + {"VCVTPS2DQ (BX), X11", "c4 61 79 5b 1b|c5 79 5b 1b"}, + {"VCVTPS2DQ (BX), X2", "c4 e1 79 5b 13|c5 f9 5b 13"}, + {"VCVTPS2DQ (BX), Y11", "c4 61 7d 5b 1b|c5 7d 5b 1b"}, + {"VCVTPS2DQ (BX), Y2", "c4 e1 7d 5b 13|c5 fd 5b 13"}, + {"VCVTPS2DQ (R11), X11", "c4 41 79 5b 1b"}, + {"VCVTPS2DQ (R11), X2", "c4 c1 79 5b 13"}, + {"VCVTPS2DQ (R11), Y11", "c4 41 7d 5b 1b"}, + {"VCVTPS2DQ (R11), Y2", "c4 c1 7d 5b 13"}, + {"VCVTPS2DQ X11, X11", "c4 41 79 5b db"}, + {"VCVTPS2DQ X11, X2", "c4 c1 79 5b d3"}, + {"VCVTPS2DQ X2, X11", "c4 61 79 5b da|c5 79 5b da"}, + {"VCVTPS2DQ X2, X2", "c4 e1 79 5b d2|c5 f9 5b d2"}, + {"VCVTPS2DQ Y11, Y11", "c4 41 7d 5b db"}, + {"VCVTPS2DQ Y11, Y2", "c4 c1 7d 5b d3"}, + {"VCVTPS2DQ Y2, Y11", "c4 61 7d 5b da|c5 7d 5b da"}, + {"VCVTPS2DQ Y2, Y2", "c4 e1 7d 5b d2|c5 fd 5b d2"}, + {"VCVTTPS2DQ (BX), X11", "c4 61 7a 5b 1b|c5 7a 5b 1b"}, + {"VCVTTPS2DQ (BX), X2", "c4 e1 7a 5b 13|c5 fa 5b 13"}, + {"VCVTTPS2DQ (BX), Y11", "c4 61 7e 5b 1b|c5 7e 5b 1b"}, + {"VCVTTPS2DQ (BX), Y2", "c4 e1 7e 5b 13|c5 fe 5b 13"}, + {"VCVTTPS2DQ (R11), X11", "c4 41 7a 5b 1b"}, + {"VCVTTPS2DQ (R11), X2", "c4 c1 7a 5b 13"}, + {"VCVTTPS2DQ (R11), Y11", "c4 41 7e 5b 1b"}, + {"VCVTTPS2DQ (R11), Y2", "c4 c1 7e 5b 13"}, + {"VCVTTPS2DQ X11, X11", "c4 41 7a 5b db"}, + {"VCVTTPS2DQ X11, X2", "c4 c1 7a 5b d3"}, + {"VCVTTPS2DQ X2, X11", "c4 61 7a 5b da|c5 7a 5b da"}, + {"VCVTTPS2DQ X2, X2", "c4 e1 7a 5b d2|c5 fa 5b d2"}, + {"VCVTTPS2DQ Y11, Y11", "c4 41 7e 5b db"}, + {"VCVTTPS2DQ Y11, Y2", "c4 c1 7e 5b d3"}, + {"VCVTTPS2DQ Y2, Y11", "c4 61 7e 5b da|c5 7e 5b da"}, + {"VCVTTPS2DQ Y2, Y2", "c4 e1 7e 5b d2|c5 fe 5b d2"}, + {"VMOVLHPS X11, X9, X11", "c4 41 30 16 db"}, + {"VMOVLHPS X11, X9, X2", "c4 c1 30 16 d3"}, + {"VMOVLHPS X2, X9, X11", "c4 61 30 16 da|c5 30 16 da"}, + {"VMOVLHPS X2, X9, X2", "c4 e1 30 16 d2|c5 b0 16 d2"}, + {"VMOVUPS (BX), X11", "c4 61 78 10 1b|c5 78 10 1b"}, + {"VMOVUPS (BX), X2", "c4 e1 78 10 13|c5 f8 10 13"}, + {"VMOVUPS (BX), Y11", "c4 61 7c 10 1b|c5 7c 10 1b"}, + {"VMOVUPS (BX), Y2", "c4 e1 7c 10 13|c5 fc 10 13"}, + {"VMOVUPS (R11), X11", "c4 41 78 10 1b"}, + {"VMOVUPS (R11), X2", "c4 c1 78 10 13"}, + {"VMOVUPS (R11), Y11", "c4 41 7c 10 1b"}, + {"VMOVUPS (R11), Y2", "c4 c1 7c 10 13"}, + {"VMOVUPS X11, (BX)", "c4 61 78 11 1b|c5 78 11 1b"}, + {"VMOVUPS X11, (R11)", "c4 41 78 11 1b"}, + {"VMOVUPS X11, X11", "c4 41 78 10 db|c4 41 78 11 db"}, + {"VMOVUPS X11, X2", "c4 c1 78 10 d3|c4 61 78 11 da|c5 78 11 da"}, + {"VMOVUPS X2, (BX)", "c4 e1 78 11 13|c5 f8 11 13"}, + {"VMOVUPS X2, (R11)", "c4 c1 78 11 13"}, + {"VMOVUPS X2, X11", "c4 61 78 10 da|c5 78 10 da|c4 c1 78 11 d3"}, + {"VMOVUPS X2, X2", "c4 e1 78 10 d2|c5 f8 10 d2|c4 e1 78 11 d2|c5 f8 11 d2"}, + {"VMOVUPS Y11, (BX)", "c4 61 7c 11 1b|c5 7c 11 1b"}, + {"VMOVUPS Y11, (R11)", "c4 41 7c 11 1b"}, + {"VMOVUPS Y11, Y11", "c4 41 7c 10 db|c4 41 7c 11 db"}, + {"VMOVUPS Y11, Y2", "c4 c1 7c 10 d3|c4 61 7c 11 da|c5 7c 11 da"}, + {"VMOVUPS Y2, (BX)", "c4 e1 7c 11 13|c5 fc 11 13"}, + {"VMOVUPS Y2, (R11)", "c4 c1 7c 11 13"}, + {"VMOVUPS Y2, Y11", "c4 61 7c 10 da|c5 7c 10 da|c4 c1 7c 11 d3"}, + {"VMOVUPS Y2, Y2", "c4 e1 7c 10 d2|c5 fc 10 d2|c4 e1 7c 11 d2|c5 fc 11 d2"}, + {"VPABSB (BX), X11", "c4 62 79 1c 1b"}, + {"VPABSB (BX), X2", "c4 e2 79 1c 13"}, + {"VPABSB (BX), Y11", "c4 62 7d 1c 1b"}, + {"VPABSB (BX), Y2", "c4 e2 7d 1c 13"}, + {"VPABSB (R11), X11", "c4 42 79 1c 1b"}, + {"VPABSB (R11), X2", "c4 c2 79 1c 13"}, + {"VPABSB (R11), Y11", "c4 42 7d 1c 1b"}, + {"VPABSB (R11), Y2", "c4 c2 7d 1c 13"}, + {"VPABSB X11, X11", "c4 42 79 1c db"}, + {"VPABSB X11, X2", "c4 c2 79 1c d3"}, + {"VPABSB X2, X11", "c4 62 79 1c da"}, + {"VPABSB X2, X2", "c4 e2 79 1c d2"}, + {"VPABSB Y11, Y11", "c4 42 7d 1c db"}, + {"VPABSB Y11, Y2", "c4 c2 7d 1c d3"}, + {"VPABSB Y2, Y11", "c4 62 7d 1c da"}, + {"VPABSB Y2, Y2", "c4 e2 7d 1c d2"}, + {"VPABSD (BX), X11", "c4 62 79 1e 1b"}, + {"VPABSD (BX), X2", "c4 e2 79 1e 13"}, + {"VPABSD (BX), Y11", "c4 62 7d 1e 1b"}, + {"VPABSD (BX), Y2", "c4 e2 7d 1e 13"}, + {"VPABSD (R11), X11", "c4 42 79 1e 1b"}, + {"VPABSD (R11), X2", "c4 c2 79 1e 13"}, + {"VPABSD (R11), Y11", "c4 42 7d 1e 1b"}, + {"VPABSD (R11), Y2", "c4 c2 7d 1e 13"}, + {"VPABSD X11, X11", "c4 42 79 1e db"}, + {"VPABSD X11, X2", "c4 c2 79 1e d3"}, + {"VPABSD X2, X11", "c4 62 79 1e da"}, + {"VPABSD X2, X2", "c4 e2 79 1e d2"}, + {"VPABSD Y11, Y11", "c4 42 7d 1e db"}, + {"VPABSD Y11, Y2", "c4 c2 7d 1e d3"}, + {"VPABSD Y2, Y11", "c4 62 7d 1e da"}, + {"VPABSD Y2, Y2", "c4 e2 7d 1e d2"}, + {"VPABSW (BX), X11", "c4 62 79 1d 1b"}, + {"VPABSW (BX), X2", "c4 e2 79 1d 13"}, + {"VPABSW (BX), Y11", "c4 62 7d 1d 1b"}, + {"VPABSW (BX), Y2", "c4 e2 7d 1d 13"}, + {"VPABSW (R11), X11", "c4 42 79 1d 1b"}, + {"VPABSW (R11), X2", "c4 c2 79 1d 13"}, + {"VPABSW (R11), Y11", "c4 42 7d 1d 1b"}, + {"VPABSW (R11), Y2", "c4 c2 7d 1d 13"}, + {"VPABSW X11, X11", "c4 42 79 1d db"}, + {"VPABSW X11, X2", "c4 c2 79 1d d3"}, + {"VPABSW X2, X11", "c4 62 79 1d da"}, + {"VPABSW X2, X2", "c4 e2 79 1d d2"}, + {"VPABSW Y11, Y11", "c4 42 7d 1d db"}, + {"VPABSW Y11, Y2", "c4 c2 7d 1d d3"}, + {"VPABSW Y2, Y11", "c4 62 7d 1d da"}, + {"VPABSW Y2, Y2", "c4 e2 7d 1d d2"}, + {"VPACKSSWB (BX), X9, X11", "c4 61 31 63 1b|c5 31 63 1b"}, + {"VPACKSSWB (BX), X9, X2", "c4 e1 31 63 13|c5 b1 63 13"}, + {"VPACKSSWB (BX), Y15, Y11", "c4 61 05 63 1b|c5 05 63 1b"}, + {"VPACKSSWB (BX), Y15, Y2", "c4 e1 05 63 13|c5 85 63 13"}, + {"VPACKSSWB (R11), X9, X11", "c4 41 31 63 1b"}, + {"VPACKSSWB (R11), X9, X2", "c4 c1 31 63 13"}, + {"VPACKSSWB (R11), Y15, Y11", "c4 41 05 63 1b"}, + {"VPACKSSWB (R11), Y15, Y2", "c4 c1 05 63 13"}, + {"VPACKSSWB X11, X9, X11", "c4 41 31 63 db"}, + {"VPACKSSWB X11, X9, X2", "c4 c1 31 63 d3"}, + {"VPACKSSWB X2, X9, X11", "c4 61 31 63 da|c5 31 63 da"}, + {"VPACKSSWB X2, X9, X2", "c4 e1 31 63 d2|c5 b1 63 d2"}, + {"VPACKSSWB Y11, Y15, Y11", "c4 41 05 63 db"}, + {"VPACKSSWB Y11, Y15, Y2", "c4 c1 05 63 d3"}, + {"VPACKSSWB Y2, Y15, Y11", "c4 61 05 63 da|c5 05 63 da"}, + {"VPACKSSWB Y2, Y15, Y2", "c4 e1 05 63 d2|c5 85 63 d2"}, + {"VPACKUSDW (BX), X9, X11", "c4 62 31 2b 1b"}, + {"VPACKUSDW (BX), X9, X2", "c4 e2 31 2b 13"}, + {"VPACKUSDW (BX), Y15, Y11", "c4 62 05 2b 1b"}, + {"VPACKUSDW (BX), Y15, Y2", "c4 e2 05 2b 13"}, + {"VPACKUSDW (R11), X9, X11", "c4 42 31 2b 1b"}, + {"VPACKUSDW (R11), X9, X2", "c4 c2 31 2b 13"}, + {"VPACKUSDW (R11), Y15, Y11", "c4 42 05 2b 1b"}, + {"VPACKUSDW (R11), Y15, Y2", "c4 c2 05 2b 13"}, + {"VPACKUSDW X11, X9, X11", "c4 42 31 2b db"}, + {"VPACKUSDW X11, X9, X2", "c4 c2 31 2b d3"}, + {"VPACKUSDW X2, X9, X11", "c4 62 31 2b da"}, + {"VPACKUSDW X2, X9, X2", "c4 e2 31 2b d2"}, + {"VPACKUSDW Y11, Y15, Y11", "c4 42 05 2b db"}, + {"VPACKUSDW Y11, Y15, Y2", "c4 c2 05 2b d3"}, + {"VPACKUSDW Y2, Y15, Y11", "c4 62 05 2b da"}, + {"VPACKUSDW Y2, Y15, Y2", "c4 e2 05 2b d2"}, + {"VPACKUSWB (BX), X9, X11", "c4 61 31 67 1b|c5 31 67 1b"}, + {"VPACKUSWB (BX), X9, X2", "c4 e1 31 67 13|c5 b1 67 13"}, + {"VPACKUSWB (BX), Y15, Y11", "c4 61 05 67 1b|c5 05 67 1b"}, + {"VPACKUSWB (BX), Y15, Y2", "c4 e1 05 67 13|c5 85 67 13"}, + {"VPACKUSWB (R11), X9, X11", "c4 41 31 67 1b"}, + {"VPACKUSWB (R11), X9, X2", "c4 c1 31 67 13"}, + {"VPACKUSWB (R11), Y15, Y11", "c4 41 05 67 1b"}, + {"VPACKUSWB (R11), Y15, Y2", "c4 c1 05 67 13"}, + {"VPACKUSWB X11, X9, X11", "c4 41 31 67 db"}, + {"VPACKUSWB X11, X9, X2", "c4 c1 31 67 d3"}, + {"VPACKUSWB X2, X9, X11", "c4 61 31 67 da|c5 31 67 da"}, + {"VPACKUSWB X2, X9, X2", "c4 e1 31 67 d2|c5 b1 67 d2"}, + {"VPACKUSWB Y11, Y15, Y11", "c4 41 05 67 db"}, + {"VPACKUSWB Y11, Y15, Y2", "c4 c1 05 67 d3"}, + {"VPACKUSWB Y2, Y15, Y11", "c4 61 05 67 da|c5 05 67 da"}, + {"VPACKUSWB Y2, Y15, Y2", "c4 e1 05 67 d2|c5 85 67 d2"}, + {"VPADDB (BX), X9, X11", "c4 61 31 fc 1b|c5 31 fc 1b"}, + {"VPADDB (BX), X9, X2", "c4 e1 31 fc 13|c5 b1 fc 13"}, + {"VPADDB (BX), Y15, Y11", "c4 61 05 fc 1b|c5 05 fc 1b"}, + {"VPADDB (BX), Y15, Y2", "c4 e1 05 fc 13|c5 85 fc 13"}, + {"VPADDB (R11), X9, X11", "c4 41 31 fc 1b"}, + {"VPADDB (R11), X9, X2", "c4 c1 31 fc 13"}, + {"VPADDB (R11), Y15, Y11", "c4 41 05 fc 1b"}, + {"VPADDB (R11), Y15, Y2", "c4 c1 05 fc 13"}, + {"VPADDB X11, X9, X11", "c4 41 31 fc db"}, + {"VPADDB X11, X9, X2", "c4 c1 31 fc d3"}, + {"VPADDB X2, X9, X11", "c4 61 31 fc da|c5 31 fc da"}, + {"VPADDB X2, X9, X2", "c4 e1 31 fc d2|c5 b1 fc d2"}, + {"VPADDB Y11, Y15, Y11", "c4 41 05 fc db"}, + {"VPADDB Y11, Y15, Y2", "c4 c1 05 fc d3"}, + {"VPADDB Y2, Y15, Y11", "c4 61 05 fc da|c5 05 fc da"}, + {"VPADDB Y2, Y15, Y2", "c4 e1 05 fc d2|c5 85 fc d2"}, + {"VPADDW (BX), X9, X11", "c4 61 31 fd 1b|c5 31 fd 1b"}, + {"VPADDW (BX), X9, X2", "c4 e1 31 fd 13|c5 b1 fd 13"}, + {"VPADDW (BX), Y15, Y11", "c4 61 05 fd 1b|c5 05 fd 1b"}, + {"VPADDW (BX), Y15, Y2", "c4 e1 05 fd 13|c5 85 fd 13"}, + {"VPADDW (R11), X9, X11", "c4 41 31 fd 1b"}, + {"VPADDW (R11), X9, X2", "c4 c1 31 fd 13"}, + {"VPADDW (R11), Y15, Y11", "c4 41 05 fd 1b"}, + {"VPADDW (R11), Y15, Y2", "c4 c1 05 fd 13"}, + {"VPADDW X11, X9, X11", "c4 41 31 fd db"}, + {"VPADDW X11, X9, X2", "c4 c1 31 fd d3"}, + {"VPADDW X2, X9, X11", "c4 61 31 fd da|c5 31 fd da"}, + {"VPADDW X2, X9, X2", "c4 e1 31 fd d2|c5 b1 fd d2"}, + {"VPADDW Y11, Y15, Y11", "c4 41 05 fd db"}, + {"VPADDW Y11, Y15, Y2", "c4 c1 05 fd d3"}, + {"VPADDW Y2, Y15, Y11", "c4 61 05 fd da|c5 05 fd da"}, + {"VPADDW Y2, Y15, Y2", "c4 e1 05 fd d2|c5 85 fd d2"}, + {"VPAVGB (BX), X9, X11", "c4 61 31 e0 1b|c5 31 e0 1b"}, + {"VPAVGB (BX), X9, X2", "c4 e1 31 e0 13|c5 b1 e0 13"}, + {"VPAVGB (BX), Y15, Y11", "c4 61 05 e0 1b|c5 05 e0 1b"}, + {"VPAVGB (BX), Y15, Y2", "c4 e1 05 e0 13|c5 85 e0 13"}, + {"VPAVGB (R11), X9, X11", "c4 41 31 e0 1b"}, + {"VPAVGB (R11), X9, X2", "c4 c1 31 e0 13"}, + {"VPAVGB (R11), Y15, Y11", "c4 41 05 e0 1b"}, + {"VPAVGB (R11), Y15, Y2", "c4 c1 05 e0 13"}, + {"VPAVGB X11, X9, X11", "c4 41 31 e0 db"}, + {"VPAVGB X11, X9, X2", "c4 c1 31 e0 d3"}, + {"VPAVGB X2, X9, X11", "c4 61 31 e0 da|c5 31 e0 da"}, + {"VPAVGB X2, X9, X2", "c4 e1 31 e0 d2|c5 b1 e0 d2"}, + {"VPAVGB Y11, Y15, Y11", "c4 41 05 e0 db"}, + {"VPAVGB Y11, Y15, Y2", "c4 c1 05 e0 d3"}, + {"VPAVGB Y2, Y15, Y11", "c4 61 05 e0 da|c5 05 e0 da"}, + {"VPAVGB Y2, Y15, Y2", "c4 e1 05 e0 d2|c5 85 e0 d2"}, + {"VPAVGW (BX), X9, X11", "c4 61 31 e3 1b|c5 31 e3 1b"}, + {"VPAVGW (BX), X9, X2", "c4 e1 31 e3 13|c5 b1 e3 13"}, + {"VPAVGW (BX), Y15, Y11", "c4 61 05 e3 1b|c5 05 e3 1b"}, + {"VPAVGW (BX), Y15, Y2", "c4 e1 05 e3 13|c5 85 e3 13"}, + {"VPAVGW (R11), X9, X11", "c4 41 31 e3 1b"}, + {"VPAVGW (R11), X9, X2", "c4 c1 31 e3 13"}, + {"VPAVGW (R11), Y15, Y11", "c4 41 05 e3 1b"}, + {"VPAVGW (R11), Y15, Y2", "c4 c1 05 e3 13"}, + {"VPAVGW X11, X9, X11", "c4 41 31 e3 db"}, + {"VPAVGW X11, X9, X2", "c4 c1 31 e3 d3"}, + {"VPAVGW X2, X9, X11", "c4 61 31 e3 da|c5 31 e3 da"}, + {"VPAVGW X2, X9, X2", "c4 e1 31 e3 d2|c5 b1 e3 d2"}, + {"VPAVGW Y11, Y15, Y11", "c4 41 05 e3 db"}, + {"VPAVGW Y11, Y15, Y2", "c4 c1 05 e3 d3"}, + {"VPAVGW Y2, Y15, Y11", "c4 61 05 e3 da|c5 05 e3 da"}, + {"VPAVGW Y2, Y15, Y2", "c4 e1 05 e3 d2|c5 85 e3 d2"}, + {"VPMADDUBSW (BX), X9, X11", "c4 62 31 04 1b"}, + {"VPMADDUBSW (BX), X9, X2", "c4 e2 31 04 13"}, + {"VPMADDUBSW (BX), Y15, Y11", "c4 62 05 04 1b"}, + {"VPMADDUBSW (BX), Y15, Y2", "c4 e2 05 04 13"}, + {"VPMADDUBSW (R11), X9, X11", "c4 42 31 04 1b"}, + {"VPMADDUBSW (R11), X9, X2", "c4 c2 31 04 13"}, + {"VPMADDUBSW (R11), Y15, Y11", "c4 42 05 04 1b"}, + {"VPMADDUBSW (R11), Y15, Y2", "c4 c2 05 04 13"}, + {"VPMADDUBSW X11, X9, X11", "c4 42 31 04 db"}, + {"VPMADDUBSW X11, X9, X2", "c4 c2 31 04 d3"}, + {"VPMADDUBSW X2, X9, X11", "c4 62 31 04 da"}, + {"VPMADDUBSW X2, X9, X2", "c4 e2 31 04 d2"}, + {"VPMADDUBSW Y11, Y15, Y11", "c4 42 05 04 db"}, + {"VPMADDUBSW Y11, Y15, Y2", "c4 c2 05 04 d3"}, + {"VPMADDUBSW Y2, Y15, Y11", "c4 62 05 04 da"}, + {"VPMADDUBSW Y2, Y15, Y2", "c4 e2 05 04 d2"}, + {"VPMADDWD (BX), X9, X11", "c4 61 31 f5 1b|c5 31 f5 1b"}, + {"VPMADDWD (BX), X9, X2", "c4 e1 31 f5 13|c5 b1 f5 13"}, + {"VPMADDWD (BX), Y15, Y11", "c4 61 05 f5 1b|c5 05 f5 1b"}, + {"VPMADDWD (BX), Y15, Y2", "c4 e1 05 f5 13|c5 85 f5 13"}, + {"VPMADDWD (R11), X9, X11", "c4 41 31 f5 1b"}, + {"VPMADDWD (R11), X9, X2", "c4 c1 31 f5 13"}, + {"VPMADDWD (R11), Y15, Y11", "c4 41 05 f5 1b"}, + {"VPMADDWD (R11), Y15, Y2", "c4 c1 05 f5 13"}, + {"VPMADDWD X11, X9, X11", "c4 41 31 f5 db"}, + {"VPMADDWD X11, X9, X2", "c4 c1 31 f5 d3"}, + {"VPMADDWD X2, X9, X11", "c4 61 31 f5 da|c5 31 f5 da"}, + {"VPMADDWD X2, X9, X2", "c4 e1 31 f5 d2|c5 b1 f5 d2"}, + {"VPMADDWD Y11, Y15, Y11", "c4 41 05 f5 db"}, + {"VPMADDWD Y11, Y15, Y2", "c4 c1 05 f5 d3"}, + {"VPMADDWD Y2, Y15, Y11", "c4 61 05 f5 da|c5 05 f5 da"}, + {"VPMADDWD Y2, Y15, Y2", "c4 e1 05 f5 d2|c5 85 f5 d2"}, + {"VPMAXSB (BX), X9, X11", "c4 62 31 3c 1b"}, + {"VPMAXSB (BX), X9, X2", "c4 e2 31 3c 13"}, + {"VPMAXSB (BX), Y15, Y11", "c4 62 05 3c 1b"}, + {"VPMAXSB (BX), Y15, Y2", "c4 e2 05 3c 13"}, + {"VPMAXSB (R11), X9, X11", "c4 42 31 3c 1b"}, + {"VPMAXSB (R11), X9, X2", "c4 c2 31 3c 13"}, + {"VPMAXSB (R11), Y15, Y11", "c4 42 05 3c 1b"}, + {"VPMAXSB (R11), Y15, Y2", "c4 c2 05 3c 13"}, + {"VPMAXSB X11, X9, X11", "c4 42 31 3c db"}, + {"VPMAXSB X11, X9, X2", "c4 c2 31 3c d3"}, + {"VPMAXSB X2, X9, X11", "c4 62 31 3c da"}, + {"VPMAXSB X2, X9, X2", "c4 e2 31 3c d2"}, + {"VPMAXSB Y11, Y15, Y11", "c4 42 05 3c db"}, + {"VPMAXSB Y11, Y15, Y2", "c4 c2 05 3c d3"}, + {"VPMAXSB Y2, Y15, Y11", "c4 62 05 3c da"}, + {"VPMAXSB Y2, Y15, Y2", "c4 e2 05 3c d2"}, + {"VPMAXSD (BX), X9, X11", "c4 62 31 3d 1b"}, + {"VPMAXSD (BX), X9, X2", "c4 e2 31 3d 13"}, + {"VPMAXSD (BX), Y15, Y11", "c4 62 05 3d 1b"}, + {"VPMAXSD (BX), Y15, Y2", "c4 e2 05 3d 13"}, + {"VPMAXSD (R11), X9, X11", "c4 42 31 3d 1b"}, + {"VPMAXSD (R11), X9, X2", "c4 c2 31 3d 13"}, + {"VPMAXSD (R11), Y15, Y11", "c4 42 05 3d 1b"}, + {"VPMAXSD (R11), Y15, Y2", "c4 c2 05 3d 13"}, + {"VPMAXSD X11, X9, X11", "c4 42 31 3d db"}, + {"VPMAXSD X11, X9, X2", "c4 c2 31 3d d3"}, + {"VPMAXSD X2, X9, X11", "c4 62 31 3d da"}, + {"VPMAXSD X2, X9, X2", "c4 e2 31 3d d2"}, + {"VPMAXSD Y11, Y15, Y11", "c4 42 05 3d db"}, + {"VPMAXSD Y11, Y15, Y2", "c4 c2 05 3d d3"}, + {"VPMAXSD Y2, Y15, Y11", "c4 62 05 3d da"}, + {"VPMAXSD Y2, Y15, Y2", "c4 e2 05 3d d2"}, + {"VPMAXSW (BX), X9, X11", "c4 61 31 ee 1b|c5 31 ee 1b"}, + {"VPMAXSW (BX), X9, X2", "c4 e1 31 ee 13|c5 b1 ee 13"}, + {"VPMAXSW (BX), Y15, Y11", "c4 61 05 ee 1b|c5 05 ee 1b"}, + {"VPMAXSW (BX), Y15, Y2", "c4 e1 05 ee 13|c5 85 ee 13"}, + {"VPMAXSW (R11), X9, X11", "c4 41 31 ee 1b"}, + {"VPMAXSW (R11), X9, X2", "c4 c1 31 ee 13"}, + {"VPMAXSW (R11), Y15, Y11", "c4 41 05 ee 1b"}, + {"VPMAXSW (R11), Y15, Y2", "c4 c1 05 ee 13"}, + {"VPMAXSW X11, X9, X11", "c4 41 31 ee db"}, + {"VPMAXSW X11, X9, X2", "c4 c1 31 ee d3"}, + {"VPMAXSW X2, X9, X11", "c4 61 31 ee da|c5 31 ee da"}, + {"VPMAXSW X2, X9, X2", "c4 e1 31 ee d2|c5 b1 ee d2"}, + {"VPMAXSW Y11, Y15, Y11", "c4 41 05 ee db"}, + {"VPMAXSW Y11, Y15, Y2", "c4 c1 05 ee d3"}, + {"VPMAXSW Y2, Y15, Y11", "c4 61 05 ee da|c5 05 ee da"}, + {"VPMAXSW Y2, Y15, Y2", "c4 e1 05 ee d2|c5 85 ee d2"}, + {"VPMAXUB (BX), X9, X11", "c4 61 31 de 1b|c5 31 de 1b"}, + {"VPMAXUB (BX), X9, X2", "c4 e1 31 de 13|c5 b1 de 13"}, + {"VPMAXUB (BX), Y15, Y11", "c4 61 05 de 1b|c5 05 de 1b"}, + {"VPMAXUB (BX), Y15, Y2", "c4 e1 05 de 13|c5 85 de 13"}, + {"VPMAXUB (R11), X9, X11", "c4 41 31 de 1b"}, + {"VPMAXUB (R11), X9, X2", "c4 c1 31 de 13"}, + {"VPMAXUB (R11), Y15, Y11", "c4 41 05 de 1b"}, + {"VPMAXUB (R11), Y15, Y2", "c4 c1 05 de 13"}, + {"VPMAXUB X11, X9, X11", "c4 41 31 de db"}, + {"VPMAXUB X11, X9, X2", "c4 c1 31 de d3"}, + {"VPMAXUB X2, X9, X11", "c4 61 31 de da|c5 31 de da"}, + {"VPMAXUB X2, X9, X2", "c4 e1 31 de d2|c5 b1 de d2"}, + {"VPMAXUB Y11, Y15, Y11", "c4 41 05 de db"}, + {"VPMAXUB Y11, Y15, Y2", "c4 c1 05 de d3"}, + {"VPMAXUB Y2, Y15, Y11", "c4 61 05 de da|c5 05 de da"}, + {"VPMAXUB Y2, Y15, Y2", "c4 e1 05 de d2|c5 85 de d2"}, + {"VPMAXUD (BX), X9, X11", "c4 62 31 3f 1b"}, + {"VPMAXUD (BX), X9, X2", "c4 e2 31 3f 13"}, + {"VPMAXUD (BX), Y15, Y11", "c4 62 05 3f 1b"}, + {"VPMAXUD (BX), Y15, Y2", "c4 e2 05 3f 13"}, + {"VPMAXUD (R11), X9, X11", "c4 42 31 3f 1b"}, + {"VPMAXUD (R11), X9, X2", "c4 c2 31 3f 13"}, + {"VPMAXUD (R11), Y15, Y11", "c4 42 05 3f 1b"}, + {"VPMAXUD (R11), Y15, Y2", "c4 c2 05 3f 13"}, + {"VPMAXUD X11, X9, X11", "c4 42 31 3f db"}, + {"VPMAXUD X11, X9, X2", "c4 c2 31 3f d3"}, + {"VPMAXUD X2, X9, X11", "c4 62 31 3f da"}, + {"VPMAXUD X2, X9, X2", "c4 e2 31 3f d2"}, + {"VPMAXUD Y11, Y15, Y11", "c4 42 05 3f db"}, + {"VPMAXUD Y11, Y15, Y2", "c4 c2 05 3f d3"}, + {"VPMAXUD Y2, Y15, Y11", "c4 62 05 3f da"}, + {"VPMAXUD Y2, Y15, Y2", "c4 e2 05 3f d2"}, + {"VPMAXUW (BX), X9, X11", "c4 62 31 3e 1b"}, + {"VPMAXUW (BX), X9, X2", "c4 e2 31 3e 13"}, + {"VPMAXUW (BX), Y15, Y11", "c4 62 05 3e 1b"}, + {"VPMAXUW (BX), Y15, Y2", "c4 e2 05 3e 13"}, + {"VPMAXUW (R11), X9, X11", "c4 42 31 3e 1b"}, + {"VPMAXUW (R11), X9, X2", "c4 c2 31 3e 13"}, + {"VPMAXUW (R11), Y15, Y11", "c4 42 05 3e 1b"}, + {"VPMAXUW (R11), Y15, Y2", "c4 c2 05 3e 13"}, + {"VPMAXUW X11, X9, X11", "c4 42 31 3e db"}, + {"VPMAXUW X11, X9, X2", "c4 c2 31 3e d3"}, + {"VPMAXUW X2, X9, X11", "c4 62 31 3e da"}, + {"VPMAXUW X2, X9, X2", "c4 e2 31 3e d2"}, + {"VPMAXUW Y11, Y15, Y11", "c4 42 05 3e db"}, + {"VPMAXUW Y11, Y15, Y2", "c4 c2 05 3e d3"}, + {"VPMAXUW Y2, Y15, Y11", "c4 62 05 3e da"}, + {"VPMAXUW Y2, Y15, Y2", "c4 e2 05 3e d2"}, + {"VPMINSB (BX), X9, X11", "c4 62 31 38 1b"}, + {"VPMINSB (BX), X9, X2", "c4 e2 31 38 13"}, + {"VPMINSB (BX), Y15, Y11", "c4 62 05 38 1b"}, + {"VPMINSB (BX), Y15, Y2", "c4 e2 05 38 13"}, + {"VPMINSB (R11), X9, X11", "c4 42 31 38 1b"}, + {"VPMINSB (R11), X9, X2", "c4 c2 31 38 13"}, + {"VPMINSB (R11), Y15, Y11", "c4 42 05 38 1b"}, + {"VPMINSB (R11), Y15, Y2", "c4 c2 05 38 13"}, + {"VPMINSB X11, X9, X11", "c4 42 31 38 db"}, + {"VPMINSB X11, X9, X2", "c4 c2 31 38 d3"}, + {"VPMINSB X2, X9, X11", "c4 62 31 38 da"}, + {"VPMINSB X2, X9, X2", "c4 e2 31 38 d2"}, + {"VPMINSB Y11, Y15, Y11", "c4 42 05 38 db"}, + {"VPMINSB Y11, Y15, Y2", "c4 c2 05 38 d3"}, + {"VPMINSB Y2, Y15, Y11", "c4 62 05 38 da"}, + {"VPMINSB Y2, Y15, Y2", "c4 e2 05 38 d2"}, + {"VPMINSD (BX), X9, X11", "c4 62 31 39 1b"}, + {"VPMINSD (BX), X9, X2", "c4 e2 31 39 13"}, + {"VPMINSD (BX), Y15, Y11", "c4 62 05 39 1b"}, + {"VPMINSD (BX), Y15, Y2", "c4 e2 05 39 13"}, + {"VPMINSD (R11), X9, X11", "c4 42 31 39 1b"}, + {"VPMINSD (R11), X9, X2", "c4 c2 31 39 13"}, + {"VPMINSD (R11), Y15, Y11", "c4 42 05 39 1b"}, + {"VPMINSD (R11), Y15, Y2", "c4 c2 05 39 13"}, + {"VPMINSD X11, X9, X11", "c4 42 31 39 db"}, + {"VPMINSD X11, X9, X2", "c4 c2 31 39 d3"}, + {"VPMINSD X2, X9, X11", "c4 62 31 39 da"}, + {"VPMINSD X2, X9, X2", "c4 e2 31 39 d2"}, + {"VPMINSD Y11, Y15, Y11", "c4 42 05 39 db"}, + {"VPMINSD Y11, Y15, Y2", "c4 c2 05 39 d3"}, + {"VPMINSD Y2, Y15, Y11", "c4 62 05 39 da"}, + {"VPMINSD Y2, Y15, Y2", "c4 e2 05 39 d2"}, + {"VPMINSW (BX), X9, X11", "c4 61 31 ea 1b|c5 31 ea 1b"}, + {"VPMINSW (BX), X9, X2", "c4 e1 31 ea 13|c5 b1 ea 13"}, + {"VPMINSW (BX), Y15, Y11", "c4 61 05 ea 1b|c5 05 ea 1b"}, + {"VPMINSW (BX), Y15, Y2", "c4 e1 05 ea 13|c5 85 ea 13"}, + {"VPMINSW (R11), X9, X11", "c4 41 31 ea 1b"}, + {"VPMINSW (R11), X9, X2", "c4 c1 31 ea 13"}, + {"VPMINSW (R11), Y15, Y11", "c4 41 05 ea 1b"}, + {"VPMINSW (R11), Y15, Y2", "c4 c1 05 ea 13"}, + {"VPMINSW X11, X9, X11", "c4 41 31 ea db"}, + {"VPMINSW X11, X9, X2", "c4 c1 31 ea d3"}, + {"VPMINSW X2, X9, X11", "c4 61 31 ea da|c5 31 ea da"}, + {"VPMINSW X2, X9, X2", "c4 e1 31 ea d2|c5 b1 ea d2"}, + {"VPMINSW Y11, Y15, Y11", "c4 41 05 ea db"}, + {"VPMINSW Y11, Y15, Y2", "c4 c1 05 ea d3"}, + {"VPMINSW Y2, Y15, Y11", "c4 61 05 ea da|c5 05 ea da"}, + {"VPMINSW Y2, Y15, Y2", "c4 e1 05 ea d2|c5 85 ea d2"}, + {"VPMINUB (BX), X9, X11", "c4 61 31 da 1b|c5 31 da 1b"}, + {"VPMINUB (BX), X9, X2", "c4 e1 31 da 13|c5 b1 da 13"}, + {"VPMINUB (BX), Y15, Y11", "c4 61 05 da 1b|c5 05 da 1b"}, + {"VPMINUB (BX), Y15, Y2", "c4 e1 05 da 13|c5 85 da 13"}, + {"VPMINUB (R11), X9, X11", "c4 41 31 da 1b"}, + {"VPMINUB (R11), X9, X2", "c4 c1 31 da 13"}, + {"VPMINUB (R11), Y15, Y11", "c4 41 05 da 1b"}, + {"VPMINUB (R11), Y15, Y2", "c4 c1 05 da 13"}, + {"VPMINUB X11, X9, X11", "c4 41 31 da db"}, + {"VPMINUB X11, X9, X2", "c4 c1 31 da d3"}, + {"VPMINUB X2, X9, X11", "c4 61 31 da da|c5 31 da da"}, + {"VPMINUB X2, X9, X2", "c4 e1 31 da d2|c5 b1 da d2"}, + {"VPMINUB Y11, Y15, Y11", "c4 41 05 da db"}, + {"VPMINUB Y11, Y15, Y2", "c4 c1 05 da d3"}, + {"VPMINUB Y2, Y15, Y11", "c4 61 05 da da|c5 05 da da"}, + {"VPMINUB Y2, Y15, Y2", "c4 e1 05 da d2|c5 85 da d2"}, + {"VPMINUD (BX), X9, X11", "c4 62 31 3b 1b"}, + {"VPMINUD (BX), X9, X2", "c4 e2 31 3b 13"}, + {"VPMINUD (BX), Y15, Y11", "c4 62 05 3b 1b"}, + {"VPMINUD (BX), Y15, Y2", "c4 e2 05 3b 13"}, + {"VPMINUD (R11), X9, X11", "c4 42 31 3b 1b"}, + {"VPMINUD (R11), X9, X2", "c4 c2 31 3b 13"}, + {"VPMINUD (R11), Y15, Y11", "c4 42 05 3b 1b"}, + {"VPMINUD (R11), Y15, Y2", "c4 c2 05 3b 13"}, + {"VPMINUD X11, X9, X11", "c4 42 31 3b db"}, + {"VPMINUD X11, X9, X2", "c4 c2 31 3b d3"}, + {"VPMINUD X2, X9, X11", "c4 62 31 3b da"}, + {"VPMINUD X2, X9, X2", "c4 e2 31 3b d2"}, + {"VPMINUD Y11, Y15, Y11", "c4 42 05 3b db"}, + {"VPMINUD Y11, Y15, Y2", "c4 c2 05 3b d3"}, + {"VPMINUD Y2, Y15, Y11", "c4 62 05 3b da"}, + {"VPMINUD Y2, Y15, Y2", "c4 e2 05 3b d2"}, + {"VPMINUW (BX), X9, X11", "c4 62 31 3a 1b"}, + {"VPMINUW (BX), X9, X2", "c4 e2 31 3a 13"}, + {"VPMINUW (BX), Y15, Y11", "c4 62 05 3a 1b"}, + {"VPMINUW (BX), Y15, Y2", "c4 e2 05 3a 13"}, + {"VPMINUW (R11), X9, X11", "c4 42 31 3a 1b"}, + {"VPMINUW (R11), X9, X2", "c4 c2 31 3a 13"}, + {"VPMINUW (R11), Y15, Y11", "c4 42 05 3a 1b"}, + {"VPMINUW (R11), Y15, Y2", "c4 c2 05 3a 13"}, + {"VPMINUW X11, X9, X11", "c4 42 31 3a db"}, + {"VPMINUW X11, X9, X2", "c4 c2 31 3a d3"}, + {"VPMINUW X2, X9, X11", "c4 62 31 3a da"}, + {"VPMINUW X2, X9, X2", "c4 e2 31 3a d2"}, + {"VPMINUW Y11, Y15, Y11", "c4 42 05 3a db"}, + {"VPMINUW Y11, Y15, Y2", "c4 c2 05 3a d3"}, + {"VPMINUW Y2, Y15, Y11", "c4 62 05 3a da"}, + {"VPMINUW Y2, Y15, Y2", "c4 e2 05 3a d2"}, + {"VPMOVSXBW (BX), X11", "c4 62 79 20 1b"}, + {"VPMOVSXBW (BX), X2", "c4 e2 79 20 13"}, + {"VPMOVSXBW (BX), Y11", "c4 62 7d 20 1b"}, + {"VPMOVSXBW (BX), Y2", "c4 e2 7d 20 13"}, + {"VPMOVSXBW (R11), X11", "c4 42 79 20 1b"}, + {"VPMOVSXBW (R11), X2", "c4 c2 79 20 13"}, + {"VPMOVSXBW (R11), Y11", "c4 42 7d 20 1b"}, + {"VPMOVSXBW (R11), Y2", "c4 c2 7d 20 13"}, + {"VPMOVSXBW X11, X11", "c4 42 79 20 db"}, + {"VPMOVSXBW X11, X2", "c4 c2 79 20 d3"}, + {"VPMOVSXBW X11, Y11", "c4 42 7d 20 db"}, + {"VPMOVSXBW X11, Y2", "c4 c2 7d 20 d3"}, + {"VPMOVSXBW X2, X11", "c4 62 79 20 da"}, + {"VPMOVSXBW X2, X2", "c4 e2 79 20 d2"}, + {"VPMOVSXBW X2, Y11", "c4 62 7d 20 da"}, + {"VPMOVSXBW X2, Y2", "c4 e2 7d 20 d2"}, + {"VPMULHUW (BX), X9, X11", "c4 61 31 e4 1b|c5 31 e4 1b"}, + {"VPMULHUW (BX), X9, X2", "c4 e1 31 e4 13|c5 b1 e4 13"}, + {"VPMULHUW (BX), Y15, Y11", "c4 61 05 e4 1b|c5 05 e4 1b"}, + {"VPMULHUW (BX), Y15, Y2", "c4 e1 05 e4 13|c5 85 e4 13"}, + {"VPMULHUW (R11), X9, X11", "c4 41 31 e4 1b"}, + {"VPMULHUW (R11), X9, X2", "c4 c1 31 e4 13"}, + {"VPMULHUW (R11), Y15, Y11", "c4 41 05 e4 1b"}, + {"VPMULHUW (R11), Y15, Y2", "c4 c1 05 e4 13"}, + {"VPMULHUW X11, X9, X11", "c4 41 31 e4 db"}, + {"VPMULHUW X11, X9, X2", "c4 c1 31 e4 d3"}, + {"VPMULHUW X2, X9, X11", "c4 61 31 e4 da|c5 31 e4 da"}, + {"VPMULHUW X2, X9, X2", "c4 e1 31 e4 d2|c5 b1 e4 d2"}, + {"VPMULHUW Y11, Y15, Y11", "c4 41 05 e4 db"}, + {"VPMULHUW Y11, Y15, Y2", "c4 c1 05 e4 d3"}, + {"VPMULHUW Y2, Y15, Y11", "c4 61 05 e4 da|c5 05 e4 da"}, + {"VPMULHUW Y2, Y15, Y2", "c4 e1 05 e4 d2|c5 85 e4 d2"}, + {"VPMULLW (BX), X9, X11", "c4 61 31 d5 1b|c5 31 d5 1b"}, + {"VPMULLW (BX), X9, X2", "c4 e1 31 d5 13|c5 b1 d5 13"}, + {"VPMULLW (BX), Y15, Y11", "c4 61 05 d5 1b|c5 05 d5 1b"}, + {"VPMULLW (BX), Y15, Y2", "c4 e1 05 d5 13|c5 85 d5 13"}, + {"VPMULLW (R11), X9, X11", "c4 41 31 d5 1b"}, + {"VPMULLW (R11), X9, X2", "c4 c1 31 d5 13"}, + {"VPMULLW (R11), Y15, Y11", "c4 41 05 d5 1b"}, + {"VPMULLW (R11), Y15, Y2", "c4 c1 05 d5 13"}, + {"VPMULLW X11, X9, X11", "c4 41 31 d5 db"}, + {"VPMULLW X11, X9, X2", "c4 c1 31 d5 d3"}, + {"VPMULLW X2, X9, X11", "c4 61 31 d5 da|c5 31 d5 da"}, + {"VPMULLW X2, X9, X2", "c4 e1 31 d5 d2|c5 b1 d5 d2"}, + {"VPMULLW Y11, Y15, Y11", "c4 41 05 d5 db"}, + {"VPMULLW Y11, Y15, Y2", "c4 c1 05 d5 d3"}, + {"VPMULLW Y2, Y15, Y11", "c4 61 05 d5 da|c5 05 d5 da"}, + {"VPMULLW Y2, Y15, Y2", "c4 e1 05 d5 d2|c5 85 d5 d2"}, + {"VPSLLVD (BX), X9, X11", "c4 62 31 47 1b"}, + {"VPSLLVD (BX), X9, X2", "c4 e2 31 47 13"}, + {"VPSLLVD (BX), Y15, Y11", "c4 62 05 47 1b"}, + {"VPSLLVD (BX), Y15, Y2", "c4 e2 05 47 13"}, + {"VPSLLVD (R11), X9, X11", "c4 42 31 47 1b"}, + {"VPSLLVD (R11), X9, X2", "c4 c2 31 47 13"}, + {"VPSLLVD (R11), Y15, Y11", "c4 42 05 47 1b"}, + {"VPSLLVD (R11), Y15, Y2", "c4 c2 05 47 13"}, + {"VPSLLVD X11, X9, X11", "c4 42 31 47 db"}, + {"VPSLLVD X11, X9, X2", "c4 c2 31 47 d3"}, + {"VPSLLVD X2, X9, X11", "c4 62 31 47 da"}, + {"VPSLLVD X2, X9, X2", "c4 e2 31 47 d2"}, + {"VPSLLVD Y11, Y15, Y11", "c4 42 05 47 db"}, + {"VPSLLVD Y11, Y15, Y2", "c4 c2 05 47 d3"}, + {"VPSLLVD Y2, Y15, Y11", "c4 62 05 47 da"}, + {"VPSLLVD Y2, Y15, Y2", "c4 e2 05 47 d2"}, + {"VPSLLVQ (BX), X9, X11", "c4 62 b1 47 1b"}, + {"VPSLLVQ (BX), X9, X2", "c4 e2 b1 47 13"}, + {"VPSLLVQ (BX), Y15, Y11", "c4 62 85 47 1b"}, + {"VPSLLVQ (BX), Y15, Y2", "c4 e2 85 47 13"}, + {"VPSLLVQ (R11), X9, X11", "c4 42 b1 47 1b"}, + {"VPSLLVQ (R11), X9, X2", "c4 c2 b1 47 13"}, + {"VPSLLVQ (R11), Y15, Y11", "c4 42 85 47 1b"}, + {"VPSLLVQ (R11), Y15, Y2", "c4 c2 85 47 13"}, + {"VPSLLVQ X11, X9, X11", "c4 42 b1 47 db"}, + {"VPSLLVQ X11, X9, X2", "c4 c2 b1 47 d3"}, + {"VPSLLVQ X2, X9, X11", "c4 62 b1 47 da"}, + {"VPSLLVQ X2, X9, X2", "c4 e2 b1 47 d2"}, + {"VPSLLVQ Y11, Y15, Y11", "c4 42 85 47 db"}, + {"VPSLLVQ Y11, Y15, Y2", "c4 c2 85 47 d3"}, + {"VPSLLVQ Y2, Y15, Y11", "c4 62 85 47 da"}, + {"VPSLLVQ Y2, Y15, Y2", "c4 e2 85 47 d2"}, + {"VPSRAVD (BX), X9, X11", "c4 62 31 46 1b"}, + {"VPSRAVD (BX), X9, X2", "c4 e2 31 46 13"}, + {"VPSRAVD (BX), Y15, Y11", "c4 62 05 46 1b"}, + {"VPSRAVD (BX), Y15, Y2", "c4 e2 05 46 13"}, + {"VPSRAVD (R11), X9, X11", "c4 42 31 46 1b"}, + {"VPSRAVD (R11), X9, X2", "c4 c2 31 46 13"}, + {"VPSRAVD (R11), Y15, Y11", "c4 42 05 46 1b"}, + {"VPSRAVD (R11), Y15, Y2", "c4 c2 05 46 13"}, + {"VPSRAVD X11, X9, X11", "c4 42 31 46 db"}, + {"VPSRAVD X11, X9, X2", "c4 c2 31 46 d3"}, + {"VPSRAVD X2, X9, X11", "c4 62 31 46 da"}, + {"VPSRAVD X2, X9, X2", "c4 e2 31 46 d2"}, + {"VPSRAVD Y11, Y15, Y11", "c4 42 05 46 db"}, + {"VPSRAVD Y11, Y15, Y2", "c4 c2 05 46 d3"}, + {"VPSRAVD Y2, Y15, Y11", "c4 62 05 46 da"}, + {"VPSRAVD Y2, Y15, Y2", "c4 e2 05 46 d2"}, + {"VPSRLVD (BX), X9, X11", "c4 62 31 45 1b"}, + {"VPSRLVD (BX), X9, X2", "c4 e2 31 45 13"}, + {"VPSRLVD (BX), Y15, Y11", "c4 62 05 45 1b"}, + {"VPSRLVD (BX), Y15, Y2", "c4 e2 05 45 13"}, + {"VPSRLVD (R11), X9, X11", "c4 42 31 45 1b"}, + {"VPSRLVD (R11), X9, X2", "c4 c2 31 45 13"}, + {"VPSRLVD (R11), Y15, Y11", "c4 42 05 45 1b"}, + {"VPSRLVD (R11), Y15, Y2", "c4 c2 05 45 13"}, + {"VPSRLVD X11, X9, X11", "c4 42 31 45 db"}, + {"VPSRLVD X11, X9, X2", "c4 c2 31 45 d3"}, + {"VPSRLVD X2, X9, X11", "c4 62 31 45 da"}, + {"VPSRLVD X2, X9, X2", "c4 e2 31 45 d2"}, + {"VPSRLVD Y11, Y15, Y11", "c4 42 05 45 db"}, + {"VPSRLVD Y11, Y15, Y2", "c4 c2 05 45 d3"}, + {"VPSRLVD Y2, Y15, Y11", "c4 62 05 45 da"}, + {"VPSRLVD Y2, Y15, Y2", "c4 e2 05 45 d2"}, + {"VPSRLVQ (BX), X9, X11", "c4 62 b1 45 1b"}, + {"VPSRLVQ (BX), X9, X2", "c4 e2 b1 45 13"}, + {"VPSRLVQ (BX), Y15, Y11", "c4 62 85 45 1b"}, + {"VPSRLVQ (BX), Y15, Y2", "c4 e2 85 45 13"}, + {"VPSRLVQ (R11), X9, X11", "c4 42 b1 45 1b"}, + {"VPSRLVQ (R11), X9, X2", "c4 c2 b1 45 13"}, + {"VPSRLVQ (R11), Y15, Y11", "c4 42 85 45 1b"}, + {"VPSRLVQ (R11), Y15, Y2", "c4 c2 85 45 13"}, + {"VPSRLVQ X11, X9, X11", "c4 42 b1 45 db"}, + {"VPSRLVQ X11, X9, X2", "c4 c2 b1 45 d3"}, + {"VPSRLVQ X2, X9, X11", "c4 62 b1 45 da"}, + {"VPSRLVQ X2, X9, X2", "c4 e2 b1 45 d2"}, + {"VPSRLVQ Y11, Y15, Y11", "c4 42 85 45 db"}, + {"VPSRLVQ Y11, Y15, Y2", "c4 c2 85 45 d3"}, + {"VPSRLVQ Y2, Y15, Y11", "c4 62 85 45 da"}, + {"VPSRLVQ Y2, Y15, Y2", "c4 e2 85 45 d2"}, + {"VPSUBB (BX), X9, X11", "c4 61 31 f8 1b|c5 31 f8 1b"}, + {"VPSUBB (BX), X9, X2", "c4 e1 31 f8 13|c5 b1 f8 13"}, + {"VPSUBB (BX), Y15, Y11", "c4 61 05 f8 1b|c5 05 f8 1b"}, + {"VPSUBB (BX), Y15, Y2", "c4 e1 05 f8 13|c5 85 f8 13"}, + {"VPSUBB (R11), X9, X11", "c4 41 31 f8 1b"}, + {"VPSUBB (R11), X9, X2", "c4 c1 31 f8 13"}, + {"VPSUBB (R11), Y15, Y11", "c4 41 05 f8 1b"}, + {"VPSUBB (R11), Y15, Y2", "c4 c1 05 f8 13"}, + {"VPSUBB X11, X9, X11", "c4 41 31 f8 db"}, + {"VPSUBB X11, X9, X2", "c4 c1 31 f8 d3"}, + {"VPSUBB X2, X9, X11", "c4 61 31 f8 da|c5 31 f8 da"}, + {"VPSUBB X2, X9, X2", "c4 e1 31 f8 d2|c5 b1 f8 d2"}, + {"VPSUBB Y11, Y15, Y11", "c4 41 05 f8 db"}, + {"VPSUBB Y11, Y15, Y2", "c4 c1 05 f8 d3"}, + {"VPSUBB Y2, Y15, Y11", "c4 61 05 f8 da|c5 05 f8 da"}, + {"VPSUBB Y2, Y15, Y2", "c4 e1 05 f8 d2|c5 85 f8 d2"}, + {"VPSUBW (BX), X9, X11", "c4 61 31 f9 1b|c5 31 f9 1b"}, + {"VPSUBW (BX), X9, X2", "c4 e1 31 f9 13|c5 b1 f9 13"}, + {"VPSUBW (BX), Y15, Y11", "c4 61 05 f9 1b|c5 05 f9 1b"}, + {"VPSUBW (BX), Y15, Y2", "c4 e1 05 f9 13|c5 85 f9 13"}, + {"VPSUBW (R11), X9, X11", "c4 41 31 f9 1b"}, + {"VPSUBW (R11), X9, X2", "c4 c1 31 f9 13"}, + {"VPSUBW (R11), Y15, Y11", "c4 41 05 f9 1b"}, + {"VPSUBW (R11), Y15, Y2", "c4 c1 05 f9 13"}, + {"VPSUBW X11, X9, X11", "c4 41 31 f9 db"}, + {"VPSUBW X11, X9, X2", "c4 c1 31 f9 d3"}, + {"VPSUBW X2, X9, X11", "c4 61 31 f9 da|c5 31 f9 da"}, + {"VPSUBW X2, X9, X2", "c4 e1 31 f9 d2|c5 b1 f9 d2"}, + {"VPSUBW Y11, Y15, Y11", "c4 41 05 f9 db"}, + {"VPSUBW Y11, Y15, Y2", "c4 c1 05 f9 d3"}, + {"VPSUBW Y2, Y15, Y11", "c4 61 05 f9 da|c5 05 f9 da"}, + {"VPSUBW Y2, Y15, Y2", "c4 e1 05 f9 d2|c5 85 f9 d2"}, + {"VSHUFPS $7, (BX), X9, X11", "c4 61 30 c6 1b 07|c5 30 c6 1b 07"}, + {"VSHUFPS $7, (BX), X9, X2", "c4 e1 30 c6 13 07|c5 b0 c6 13 07"}, + {"VSHUFPS $7, (BX), Y15, Y11", "c4 61 04 c6 1b 07|c5 04 c6 1b 07"}, + {"VSHUFPS $7, (BX), Y15, Y2", "c4 e1 04 c6 13 07|c5 84 c6 13 07"}, + {"VSHUFPS $7, (R11), X9, X11", "c4 41 30 c6 1b 07"}, + {"VSHUFPS $7, (R11), X9, X2", "c4 c1 30 c6 13 07"}, + {"VSHUFPS $7, (R11), Y15, Y11", "c4 41 04 c6 1b 07"}, + {"VSHUFPS $7, (R11), Y15, Y2", "c4 c1 04 c6 13 07"}, + {"VSHUFPS $7, X11, X9, X11", "c4 41 30 c6 db 07"}, + {"VSHUFPS $7, X11, X9, X2", "c4 c1 30 c6 d3 07"}, + {"VSHUFPS $7, X2, X9, X11", "c4 61 30 c6 da 07|c5 30 c6 da 07"}, + {"VSHUFPS $7, X2, X9, X2", "c4 e1 30 c6 d2 07|c5 b0 c6 d2 07"}, + {"VSHUFPS $7, Y11, Y15, Y11", "c4 41 04 c6 db 07"}, + {"VSHUFPS $7, Y11, Y15, Y2", "c4 c1 04 c6 d3 07"}, + {"VSHUFPS $7, Y2, Y15, Y11", "c4 61 04 c6 da 07|c5 04 c6 da 07"}, + {"VSHUFPS $7, Y2, Y15, Y2", "c4 e1 04 c6 d2 07|c5 84 c6 d2 07"}, +} + +// TestAmd64VexParityCorpus assembles every corpus line and requires the +// bytes to match one of the alternatives go tool asm accepts. +func TestAmd64VexParityCorpus(t *testing.T) { + for _, tc := range amd64VexParityCorpus { + fn := firstText(t, "TEXT ·p(SB), 4, $0\n\t"+tc.line+"\n") + code, _, err := Assemble(fn) + if err != nil { + t.Errorf("%s: %v", tc.line, err) + continue + } + got := hexBytes(code) + if !slices.Contains(strings.Split(tc.want, "|"), got) { + t.Errorf("%s: got %s, want one of %s", tc.line, got, tc.want) + } + } +} diff --git a/asm/instrs.go b/asm/instrs.go index 63b7ede..82dae29 100644 --- a/asm/instrs.go +++ b/asm/instrs.go @@ -791,7 +791,7 @@ func (e *enc) encodeDoubleShift(base string, ops []Operand, size int) error { } i.imm = []byte{byte(imm)} } - if err := setRMReg(i, srcReg.idx, srcReg.idx >= 8, false, dst, size); err != nil { + if err := setRMReg(i, srcReg.idx&7, srcReg.idx >= 8, false, dst, size); err != nil { return err } return e.emit(i) @@ -943,8 +943,12 @@ func (e *enc) encodePushPop(ops []Operand, size int, push bool) error { } // PUSH imm32, sign-extended to 64 bits; go tool asm bounds the // immediate by the same signed/unsigned 32-bit span as every other - // scalar immediate. - immBytes, err := immediate(int64(op), 8, false) + // scalar immediate. The W spelling takes imm16 alone. + immWidth := 8 + if w16 { + immWidth = 2 + } + immBytes, err := immediate(int64(op), immWidth, false) if err != nil { return err } @@ -1432,13 +1436,15 @@ type sseExtract struct { op []byte opMem []byte // used when the destination is memory; nil shares op rexW bool // PEXTRQ's REX.W + rev bool // PEXTRW's GPR form swaps the fields: the register + // destination rides reg and the XMM source r/m } var sseExtractTable = map[string]sseExtract{ - "PEXTRB": {[]byte{0x0F, 0x3A, 0x14}, nil, false}, - "PEXTRD": {[]byte{0x0F, 0x3A, 0x16}, nil, false}, - "PEXTRQ": {[]byte{0x0F, 0x3A, 0x16}, nil, true}, - "PEXTRW": {[]byte{0x0F, 0xC5}, []byte{0x0F, 0x3A, 0x15}, false}, + "PEXTRB": {[]byte{0x0F, 0x3A, 0x14}, nil, false, false}, + "PEXTRD": {[]byte{0x0F, 0x3A, 0x16}, nil, false, false}, + "PEXTRQ": {[]byte{0x0F, 0x3A, 0x16}, nil, true, false}, + "PEXTRW": {[]byte{0x0F, 0xC5}, []byte{0x0F, 0x3A, 0x15}, false, true}, } // sseInsert describes a lane insert: OP $imm, src, xdst with reg = the XMM @@ -1925,8 +1931,17 @@ func (e *enc) encodeSSEExtract(m sseExtract, ops []Operand) error { if m.opMem != nil && memOperand(ops[2]) { opcode = m.opMem } + reg, rm := srcReg, ops[2] + if m.rev && opcode[1] == 0xC5 { + // the 0F C5 layout: the GPR destination rides reg, the XMM source r/m + if d, ok := ops[2].(Reg); !ok { + return fmt.Errorf("PEXTRW destination must be a register or memory") + } else { + reg, rm = d, ops[1] + } + } i := &instr{prefix: 0x66, opcode: opcode, modrm: -1, sib: -1, rexW: m.rexW} - if err := setRM(i, srcReg, ops[2], 8); err != nil { + if err := setRM(i, reg, rm, 8); err != nil { return err } i.imm = []byte{immByte} diff --git a/asm/vex.go b/asm/vex.go index 483eaac..e26cb4c 100644 --- a/asm/vex.go +++ b/asm/vex.go @@ -97,6 +97,7 @@ type vexSpec struct { pp int // 0 = none, 1 = 66, 2 = F3, 3 = F2 opdigit int // ModRM.reg /digit, or -1 when reg is a register form vexForm + vex3 bool // always the 3-byte prefix, as the toolchain emits } // vexTable maps an upper-case mnemonic to its VEX encoding. It is extended @@ -104,385 +105,447 @@ type vexSpec struct { // against the Go assembler. var vexTable = map[string]vexSpec{ // VEX.128/256.66.0F.WIG, integer arithmetic / logic / compare. - "VPADDD": {1, 0xFE, 0, 1, -1, vexNDS3}, - "VPADDQ": {1, 0xD4, 0, 1, -1, vexNDS3}, - "VPSUBD": {1, 0xFA, 0, 1, -1, vexNDS3}, - "VPSUBQ": {1, 0xFB, 0, 1, -1, vexNDS3}, - "VPXOR": {1, 0xEF, 0, 1, -1, vexNDS3}, - "VPOR": {1, 0xEB, 0, 1, -1, vexNDS3}, - "VPAND": {1, 0xDB, 0, 1, -1, vexNDS3}, - "VPANDN": {1, 0xDF, 0, 1, -1, vexNDS3}, - "VPCMPEQD": {1, 0x76, 0, 1, -1, vexNDS3}, - "VPUNPCKLDQ": {1, 0x62, 0, 1, -1, vexNDS3}, - "VPUNPCKHDQ": {1, 0x6A, 0, 1, -1, vexNDS3}, - "VPUNPCKLQDQ": {1, 0x6C, 0, 1, -1, vexNDS3}, - "VPACKSSDW": {1, 0x6B, 0, 1, -1, vexNDS3}, + "VPADDD": {1, 0xFE, 0, 1, -1, vexNDS3, false}, + "VPADDQ": {1, 0xD4, 0, 1, -1, vexNDS3, false}, + "VPSUBD": {1, 0xFA, 0, 1, -1, vexNDS3, false}, + "VPSUBQ": {1, 0xFB, 0, 1, -1, vexNDS3, false}, + "VPXOR": {1, 0xEF, 0, 1, -1, vexNDS3, false}, + "VPOR": {1, 0xEB, 0, 1, -1, vexNDS3, false}, + "VPAND": {1, 0xDB, 0, 1, -1, vexNDS3, false}, + "VPANDN": {1, 0xDF, 0, 1, -1, vexNDS3, false}, + "VPCMPEQD": {1, 0x76, 0, 1, -1, vexNDS3, false}, + "VPUNPCKLDQ": {1, 0x62, 0, 1, -1, vexNDS3, false}, + "VPUNPCKHDQ": {1, 0x6A, 0, 1, -1, vexNDS3, false}, + "VPUNPCKLQDQ": {1, 0x6C, 0, 1, -1, vexNDS3, false}, + "VPACKSSDW": {1, 0x6B, 0, 1, -1, vexNDS3, false}, // VEX.256.66.0F38.W0, dword permute (three-operand NDS form). - "VPERMD": {2, 0x36, 0, 1, -1, vexNDS3}, + "VPERMD": {2, 0x36, 0, 1, -1, vexNDS3, false}, // VEX.128/256.66.0F38.WIG. - "VPMULLD": {2, 0x40, 0, 1, -1, vexNDS3}, - "VPMULDQ": {2, 0x28, 0, 1, -1, vexNDS3}, - "VPSHUFB": {2, 0x00, 0, 1, -1, vexNDS3}, - "VPCMPGTQ": {2, 0x37, 0, 1, -1, vexNDS3}, + "VPMULLD": {2, 0x40, 0, 1, -1, vexNDS3, false}, + "VPMULDQ": {2, 0x28, 0, 1, -1, vexNDS3, false}, + "VPSHUFB": {2, 0x00, 0, 1, -1, vexNDS3, false}, + "VPCMPGTQ": {2, 0x37, 0, 1, -1, vexNDS3, false}, // VEX.128/256.66.0F.WIG, packed double-precision arithmetic / logic. - "VADDPD": {1, 0x58, 0, 1, -1, vexNDS3}, - "VMULPD": {1, 0x59, 0, 1, -1, vexNDS3}, - "VSUBPD": {1, 0x5C, 0, 1, -1, vexNDS3}, - "VDIVPD": {1, 0x5E, 0, 1, -1, vexNDS3}, - "VMINPD": {1, 0x5D, 0, 1, -1, vexNDS3}, - "VMAXPD": {1, 0x5F, 0, 1, -1, vexNDS3}, + "VADDPD": {1, 0x58, 0, 1, -1, vexNDS3, false}, + "VMULPD": {1, 0x59, 0, 1, -1, vexNDS3, false}, + "VSUBPD": {1, 0x5C, 0, 1, -1, vexNDS3, false}, + "VDIVPD": {1, 0x5E, 0, 1, -1, vexNDS3, false}, + "VMINPD": {1, 0x5D, 0, 1, -1, vexNDS3, false}, + "VMAXPD": {1, 0x5F, 0, 1, -1, vexNDS3, false}, // VEX.128/256.0F.WIG, packed single-precision arithmetic. - "VADDPS": {1, 0x58, 0, 0, -1, vexNDS3}, - "VMULPS": {1, 0x59, 0, 0, -1, vexNDS3}, - "VSUBPS": {1, 0x5C, 0, 0, -1, vexNDS3}, - "VDIVPS": {1, 0x5E, 0, 0, -1, vexNDS3}, - "VMINPS": {1, 0x5D, 0, 0, -1, vexNDS3}, - "VMAXPS": {1, 0x5F, 0, 0, -1, vexNDS3}, - "VXORPD": {1, 0x57, 0, 1, -1, vexNDS3}, - "VUNPCKHPD": {1, 0x15, 0, 1, -1, vexNDS3}, - "VUNPCKLPD": {1, 0x14, 0, 1, -1, vexNDS3}, + "VADDPS": {1, 0x58, 0, 0, -1, vexNDS3, false}, + "VMULPS": {1, 0x59, 0, 0, -1, vexNDS3, false}, + "VSUBPS": {1, 0x5C, 0, 0, -1, vexNDS3, false}, + "VDIVPS": {1, 0x5E, 0, 0, -1, vexNDS3, false}, + "VMINPS": {1, 0x5D, 0, 0, -1, vexNDS3, false}, + "VMAXPS": {1, 0x5F, 0, 0, -1, vexNDS3, false}, + "VXORPD": {1, 0x57, 0, 1, -1, vexNDS3, false}, + "VUNPCKHPD": {1, 0x15, 0, 1, -1, vexNDS3, false}, + "VUNPCKLPD": {1, 0x14, 0, 1, -1, vexNDS3, false}, // VEX.128.F2.0F.WIG, scalar double-precision arithmetic (the packed // opcodes with an F2 pp). - "VADDSD": {1, 0x58, 0, 3, -1, vexNDS3}, - "VSUBSD": {1, 0x5C, 0, 3, -1, vexNDS3}, - "VMULSD": {1, 0x59, 0, 3, -1, vexNDS3}, - "VDIVSD": {1, 0x5E, 0, 3, -1, vexNDS3}, - "VMINSD": {1, 0x5D, 0, 3, -1, vexNDS3}, - "VMAXSD": {1, 0x5F, 0, 3, -1, vexNDS3}, + "VADDSD": {1, 0x58, 0, 3, -1, vexNDS3, false}, + "VSUBSD": {1, 0x5C, 0, 3, -1, vexNDS3, false}, + "VMULSD": {1, 0x59, 0, 3, -1, vexNDS3, false}, + "VDIVSD": {1, 0x5E, 0, 3, -1, vexNDS3, false}, + "VMINSD": {1, 0x5D, 0, 3, -1, vexNDS3, false}, + "VMAXSD": {1, 0x5F, 0, 3, -1, vexNDS3, false}, // VEX.128.F3.0F.WIG, scalar single-precision arithmetic (the packed // opcodes with an F3 pp). - "VADDSS": {1, 0x58, 0, 2, -1, vexNDS3}, - "VSUBSS": {1, 0x5C, 0, 2, -1, vexNDS3}, - "VMULSS": {1, 0x59, 0, 2, -1, vexNDS3}, - "VDIVSS": {1, 0x5E, 0, 2, -1, vexNDS3}, - "VMINSS": {1, 0x5D, 0, 2, -1, vexNDS3}, - "VMAXSS": {1, 0x5F, 0, 2, -1, vexNDS3}, + "VADDSS": {1, 0x58, 0, 2, -1, vexNDS3, false}, + "VSUBSS": {1, 0x5C, 0, 2, -1, vexNDS3, false}, + "VMULSS": {1, 0x59, 0, 2, -1, vexNDS3, false}, + "VDIVSS": {1, 0x5E, 0, 2, -1, vexNDS3, false}, + "VMINSS": {1, 0x5D, 0, 2, -1, vexNDS3, false}, + "VMAXSS": {1, 0x5F, 0, 2, -1, vexNDS3, false}, // VEX.128/256.66.0F38.W1, fused multiply-add (NDS form). - "VFMADD231PD": {2, 0xB8, 1, 1, -1, vexNDS3}, + "VFMADD231PD": {2, 0xB8, 1, 1, -1, vexNDS3, false}, // Scalar fused multiply-add (NDS form). The Go assembler carries the // same 66 prefix as the packed forms on every FMA row, and W1 on the // double-precision spellings, so SD shares PD's prefix/W pair and the // scalar width rides on the W bit. - "VFMADD213SD": {2, 0xA9, 1, 1, -1, vexNDS3}, - "VFNMADD231SD": {2, 0xBD, 1, 1, -1, vexNDS3}, + "VFMADD213SD": {2, 0xA9, 1, 1, -1, vexNDS3, false}, + "VFNMADD231SD": {2, 0xBD, 1, 1, -1, vexNDS3, false}, // VEX.128/256.66.0F38.WIG, sign/zero extend and broadcast (reg=dst, rm=src, // no vvvv). - "VPMOVSXWD": {2, 0x23, 0, 1, -1, vexRM}, - "VPMOVSXDQ": {2, 0x25, 0, 1, -1, vexRM}, - "VPMOVSXBD": {2, 0x21, 0, 1, -1, vexRM}, - "VPMOVSXBQ": {2, 0x22, 0, 1, -1, vexRM}, - "VPMOVSXWQ": {2, 0x24, 0, 1, -1, vexRM}, - "VPMOVZXDQ": {2, 0x35, 0, 1, -1, vexRM}, - "VPMOVZXBW": {2, 0x30, 0, 1, -1, vexRM}, - "VPMOVZXBD": {2, 0x31, 0, 1, -1, vexRM}, - "VPMOVZXBQ": {2, 0x32, 0, 1, -1, vexRM}, - "VPMOVZXWD": {2, 0x33, 0, 1, -1, vexRM}, - "VPMOVZXWQ": {2, 0x34, 0, 1, -1, vexRM}, - "VPBROADCASTD": {2, 0x58, 0, 1, -1, vexRM}, - "VPBROADCASTQ": {2, 0x59, 0, 1, -1, vexRM}, - "VPBROADCASTB": {2, 0x78, 0, 1, -1, vexRM}, - "VPBROADCASTW": {2, 0x79, 0, 1, -1, vexRM}, + "VPMOVSXWD": {2, 0x23, 0, 1, -1, vexRM, false}, + "VPMOVSXDQ": {2, 0x25, 0, 1, -1, vexRM, false}, + "VPMOVSXBD": {2, 0x21, 0, 1, -1, vexRM, false}, + "VPMOVSXBQ": {2, 0x22, 0, 1, -1, vexRM, false}, + "VPMOVSXWQ": {2, 0x24, 0, 1, -1, vexRM, false}, + "VPMOVZXDQ": {2, 0x35, 0, 1, -1, vexRM, false}, + "VPMOVZXBW": {2, 0x30, 0, 1, -1, vexRM, false}, + "VPMOVZXBD": {2, 0x31, 0, 1, -1, vexRM, false}, + "VPMOVZXBQ": {2, 0x32, 0, 1, -1, vexRM, false}, + "VPMOVZXWD": {2, 0x33, 0, 1, -1, vexRM, false}, + "VPMOVZXWQ": {2, 0x34, 0, 1, -1, vexRM, false}, + "VPBROADCASTD": {2, 0x58, 0, 1, -1, vexRM, false}, + "VPBROADCASTQ": {2, 0x59, 0, 1, -1, vexRM, false}, + "VPBROADCASTB": {2, 0x78, 0, 1, -1, vexRM, false}, + "VPBROADCASTW": {2, 0x79, 0, 1, -1, vexRM, false}, // VEX.128/256.F3.0F.WIG, signed dword to packed double conversion // (reg=dst, rm=src, no vvvv; the length follows the destination). - "VCVTDQ2PD": {1, 0xE6, 0, 2, -1, vexRM}, + "VCVTDQ2PD": {1, 0xE6, 0, 2, -1, vexRM, false}, // VEX.128/256.0F.WIG, signed dword to packed single conversion // (reg=dst, rm=src, no vvvv, no mandatory prefix). - "VCVTDQ2PS": {1, 0x5B, 0, 0, -1, vexRM}, + "VCVTDQ2PS": {1, 0x5B, 0, 0, -1, vexRM, false}, // VEX.128/256.0F.WIG, packed single to packed double conversion // (reg=dst, rm=src; the destination is the wide operand and sets the // length). Intel's maps prescribe the F3 prefix here (VEX.pp = 10), but // the Go assembler emits the instruction with pp = 00, and gasm follows // the Go assembler's bytes, its machine code is the oracle, not the // manual. - "VCVTPS2PD": {1, 0x5A, 0, 0, -1, vexRM}, + "VCVTPS2PD": {1, 0x5A, 0, 0, -1, vexRM, false}, // VEX.128.F2.0F.WIG, duplicate the low double of each 128-bit lane // (reg=dst, rm=src, no vvvv; the length follows the destination). - "VMOVDDUP": {1, 0x12, 0, 3, -1, vexRM}, + "VMOVDDUP": {1, 0x12, 0, 3, -1, vexRM, false}, // VEX.128/256.66.0F.WIG, move mask to a GPR (reg=gpr dst, rm=vec src). - "VPMOVMSKB": {1, 0xD7, 0, 1, -1, vexRM}, - "VMOVMSKPS": {1, 0x50, 0, 0, -1, vexRM}, // no 66 prefix (that would be VMOVMSKPD) + "VPMOVMSKB": {1, 0xD7, 0, 1, -1, vexRM, false}, + "VMOVMSKPS": {1, 0x50, 0, 0, -1, vexRM, false}, // no 66 prefix (that would be VMOVMSKPD) // VEX.128/256.66.0F.WIG, immediate shifts (opdigit selects the shift). - "VPSLLD": {1, 0x72, 0, 1, 6, vexShiftImm}, - "VPSRAD": {1, 0x72, 0, 1, 4, vexShiftImm}, - "VPSRLD": {1, 0x72, 0, 1, 2, vexShiftImm}, - "VPSRLQ": {1, 0x73, 0, 1, 2, vexShiftImm}, - "VPSLLQ": {1, 0x73, 0, 1, 6, vexShiftImm}, + "VPSLLD": {1, 0x72, 0, 1, 6, vexShiftImm, false}, + "VPSRAD": {1, 0x72, 0, 1, 4, vexShiftImm, false}, + "VPSRLD": {1, 0x72, 0, 1, 2, vexShiftImm, false}, + "VPSRLQ": {1, 0x73, 0, 1, 2, vexShiftImm, false}, + "VPSLLQ": {1, 0x73, 0, 1, 6, vexShiftImm, false}, // VEX.128/256.66.0F.WIG, immediate shuffle (reg=dst, rm=src, imm8). - "VPSHUFD": {1, 0x70, 0, 1, -1, vexImmRM}, + "VPSHUFD": {1, 0x70, 0, 1, -1, vexImmRM, false}, // VEX.256.66.0F3A.W1, qword permute (reg=dst, rm=src, imm8), and its // double twin under op 01; the in-lane permutes under 04/05. - "VPERMQ": {3, 0x00, 1, 1, -1, vexImmRM}, - "VPERMPD": {3, 0x01, 1, 1, -1, vexImmRM}, - "VPERMILPS": {3, 0x04, 0, 1, -1, vexImmRM}, - "VPERMILPD": {3, 0x05, 0, 1, -1, vexImmRM}, + "VPERMQ": {3, 0x00, 1, 1, -1, vexImmRM, false}, + "VPERMPD": {3, 0x01, 1, 1, -1, vexImmRM, false}, + "VPERMILPS": {3, 0x04, 0, 1, -1, vexImmRM, false}, + "VPERMILPD": {3, 0x05, 0, 1, -1, vexImmRM, false}, // VEX.66.0F3A.W0, the immediate-controlled AVX tail: the rounding // pair, the AES key assistant and the string compares. - "VROUNDPD": {3, 0x09, 0, 1, -1, vexImmRM}, - "VROUNDPS": {3, 0x08, 0, 1, -1, vexImmRM}, - "VAESKEYGENASSIST": {3, 0xDF, 0, 1, -1, vexImmRM}, - "VPCMPESTRI": {3, 0x61, 0, 1, -1, vexImmRM}, - "VPCMPESTRM": {3, 0x60, 0, 1, -1, vexImmRM}, - "VPCMPISTRI": {3, 0x63, 0, 1, -1, vexImmRM}, - "VPCMPISTRM": {3, 0x62, 0, 1, -1, vexImmRM}, + "VROUNDPD": {3, 0x09, 0, 1, -1, vexImmRM, false}, + "VROUNDPS": {3, 0x08, 0, 1, -1, vexImmRM, false}, + "VAESKEYGENASSIST": {3, 0xDF, 0, 1, -1, vexImmRM, false}, + "VPCMPESTRI": {3, 0x61, 0, 1, -1, vexImmRM, false}, + "VPCMPESTRM": {3, 0x60, 0, 1, -1, vexImmRM, false}, + "VPCMPISTRI": {3, 0x63, 0, 1, -1, vexImmRM, false}, + "VPCMPISTRM": {3, 0x62, 0, 1, -1, vexImmRM, false}, // VEX.128.66.0F3A.W0, the scalar lane extract to a GPR or memory // (reg = the XMM source, r/m = the destination). - "VEXTRACTPS": {3, 0x17, 0, 1, -1, vexExtractGPR}, - "VPEXTRW": {3, 0x15, 0, 1, -1, vexExtractGPR}, + "VEXTRACTPS": {3, 0x17, 0, 1, -1, vexExtractGPR, false}, + "VPEXTRW": {3, 0x15, 0, 1, -1, vexExtractGPR, false}, // VEX.128.66.0F3A.W0, the four-operand variable blend with its mask // register in the /is4 byte. - "VPBLENDVB": {3, 0x4C, 0, 1, -1, vexBlend4}, + "VPBLENDVB": {3, 0x4C, 0, 1, -1, vexBlend4, false}, // VEX.128/256.66.0F.WIG, two-source shuffle (reg=dst, vvvv=src1, rm=src2, // imm8). - "VSHUFPD": {1, 0xC6, 0, 1, -1, vexNDS3Imm}, + "VSHUFPD": {1, 0xC6, 0, 1, -1, vexNDS3Imm, false}, // VEX.256.66.0F3A.W0, permute / insert (same shape; VINSERTI128's rm is // the XMM or memory source). - "VPERM2I128": {3, 0x46, 0, 1, -1, vexNDS3Imm}, - "VINSERTI128": {3, 0x38, 0, 1, -1, vexNDS3Imm}, + "VPERM2I128": {3, 0x46, 0, 1, -1, vexNDS3Imm, false}, + "VINSERTI128": {3, 0x38, 0, 1, -1, vexNDS3Imm, false}, // VEX.256.66.0F3A.W0, lane extract (reg=YMM src, rm=XMM/memory dst, imm8). - "VEXTRACTI128": {3, 0x39, 0, 1, -1, vexExtract}, - "VEXTRACTF128": {3, 0x19, 0, 1, -1, vexExtract}, + "VEXTRACTI128": {3, 0x39, 0, 1, -1, vexExtract, false}, + "VEXTRACTF128": {3, 0x19, 0, 1, -1, vexExtract, false}, // VEX.128/256.66.0F3A.W0, half-precision convert back ($imm, src, dst: // reg=src, rm=XMM/memory dst, imm8, the extract layout). - "VCVTPS2PH": {3, 0x1D, 0, 1, -1, vexExtract}, + "VCVTPS2PH": {3, 0x1D, 0, 1, -1, vexExtract, false}, // VEX.128.0F.W0, no operands. - "VZEROUPPER": {1, 0x77, 0, 0, -1, vexZero}, + "VZEROUPPER": {1, 0x77, 0, 0, -1, vexZero, false}, // VEX.256.0F.W0, zero all vector registers (the L = 1 twin). - "VZEROALL": {1, 0x77, 0, 0, -1, vexZeroAll}, + "VZEROALL": {1, 0x77, 0, 0, -1, vexZeroAll, false}, // VEX.128/256.66.0F38, byte shuffle shifts and the packed byte compare. - "VPSLLDQ": {1, 0x73, 0, 1, 7, vexShiftImm}, - "VPSRLDQ": {1, 0x73, 0, 1, 3, vexShiftImm}, - "VPCMPEQB": {1, 0x74, 0, 1, -1, vexNDS3}, + "VPSLLDQ": {1, 0x73, 0, 1, 7, vexShiftImm, false}, + "VPSRLDQ": {1, 0x73, 0, 1, 3, vexShiftImm, false}, + "VPCMPEQB": {1, 0x74, 0, 1, -1, vexNDS3, false}, // VEX.128/256.0F.WIG, packed single XOR (NDS form). - "VXORPS": {1, 0x57, 0, 0, -1, vexNDS3}, + "VXORPS": {1, 0x57, 0, 0, -1, vexNDS3, false}, // VEX.256.66.0F3A.W0, two-source permutes and blends with an imm8 control. - "VPERM2F128": {3, 0x06, 0, 1, -1, vexNDS3Imm}, - "VPBLENDD": {3, 0x02, 0, 1, -1, vexNDS3Imm}, + "VPERM2F128": {3, 0x06, 0, 1, -1, vexNDS3Imm, false}, + "VPBLENDD": {3, 0x02, 0, 1, -1, vexNDS3Imm, false}, // VEX.128/256.66.0F3A.WIG, byte align (NDS + imm8); the ZMM spelling // falls through to the EVEX table. - "VPALIGNR": {3, 0x0F, 0, 1, -1, vexNDS3Imm}, + "VPALIGNR": {3, 0x0F, 0, 1, -1, vexNDS3Imm, false}, // VEX.128/256.66.0F3A.W0, carry-less multiply ($imm, src2, src1, dst). - "VPCLMULQDQ": {3, 0x44, 0, 1, -1, vexNDS3Imm}, + "VPCLMULQDQ": {3, 0x44, 0, 1, -1, vexNDS3Imm, false}, // VEX.128/256.66.0F3A.W1, GF(2^8) affine transform (NDS + imm8). - "VGF2P8AFFINEQB": {3, 0xCE, 1, 1, -1, vexNDS3Imm}, + "VGF2P8AFFINEQB": {3, 0xCE, 1, 1, -1, vexNDS3Imm, false}, // BMI1/BMI2 general-register VEX forms (see vexNDS3GPR/vexImmRMGPR). - "ANDNL": {2, 0xF2, 0, 0, -1, vexNDS3GPR}, - "ANDNQ": {2, 0xF2, 1, 0, -1, vexNDS3GPR}, - "MULXL": {2, 0xF6, 0, 3, -1, vexNDS3GPR}, - "MULXQ": {2, 0xF6, 1, 3, -1, vexNDS3GPR}, + "ANDNL": {2, 0xF2, 0, 0, -1, vexNDS3GPR, false}, + "ANDNQ": {2, 0xF2, 1, 0, -1, vexNDS3GPR, false}, + "MULXL": {2, 0xF6, 0, 3, -1, vexNDS3GPR, false}, + "MULXQ": {2, 0xF6, 1, 3, -1, vexNDS3GPR, false}, // VEX.NDS.LZ.0F38, the BMI2 three-operand bit ops: BEXTR and BZHI // share the F7/F5 opcodes across W, the variable shifts carry their // direction in the prefix (SHLX 66, SHRX F2, SARX F3) and PDEP/PEXT // in F2/F3. - "BEXTRL": {2, 0xF7, 0, 0, -1, vexCountGPR}, - "BEXTRQ": {2, 0xF7, 1, 0, -1, vexCountGPR}, - "BZHIL": {2, 0xF5, 0, 0, -1, vexCountGPR}, - "BZHIQ": {2, 0xF5, 1, 0, -1, vexCountGPR}, - "SARXL": {2, 0xF7, 0, 2, -1, vexCountGPR}, - "SARXQ": {2, 0xF7, 1, 2, -1, vexCountGPR}, - "SHLXL": {2, 0xF7, 0, 1, -1, vexCountGPR}, - "SHLXQ": {2, 0xF7, 1, 1, -1, vexCountGPR}, - "SHRXL": {2, 0xF7, 0, 3, -1, vexCountGPR}, - "SHRXQ": {2, 0xF7, 1, 3, -1, vexCountGPR}, - "PDEPL": {2, 0xF5, 0, 3, -1, vexNDS3GPR}, - "PDEPQ": {2, 0xF5, 1, 3, -1, vexNDS3GPR}, - "PEXTL": {2, 0xF5, 0, 2, -1, vexNDS3GPR}, - "PEXTQ": {2, 0xF5, 1, 2, -1, vexNDS3GPR}, + "BEXTRL": {2, 0xF7, 0, 0, -1, vexCountGPR, false}, + "BEXTRQ": {2, 0xF7, 1, 0, -1, vexCountGPR, false}, + "BZHIL": {2, 0xF5, 0, 0, -1, vexCountGPR, false}, + "BZHIQ": {2, 0xF5, 1, 0, -1, vexCountGPR, false}, + "SARXL": {2, 0xF7, 0, 2, -1, vexCountGPR, false}, + "SARXQ": {2, 0xF7, 1, 2, -1, vexCountGPR, false}, + "SHLXL": {2, 0xF7, 0, 1, -1, vexCountGPR, false}, + "SHLXQ": {2, 0xF7, 1, 1, -1, vexCountGPR, false}, + "SHRXL": {2, 0xF7, 0, 3, -1, vexCountGPR, false}, + "SHRXQ": {2, 0xF7, 1, 3, -1, vexCountGPR, false}, + "PDEPL": {2, 0xF5, 0, 3, -1, vexNDS3GPR, false}, + "PDEPQ": {2, 0xF5, 1, 3, -1, vexNDS3GPR, false}, + "PEXTL": {2, 0xF5, 0, 2, -1, vexNDS3GPR, false}, + "PEXTQ": {2, 0xF5, 1, 2, -1, vexNDS3GPR, false}, // VEX.LZ.0F38.W, the BMI1 unary bit ops (src, dst: ModRM.reg = /digit, // rm = src, vvvv = dst). - "BLSIL": {2, 0xF3, 0, 0, 3, vexRMOpGPR}, - "BLSIQ": {2, 0xF3, 1, 0, 3, vexRMOpGPR}, - "BLSMSKL": {2, 0xF3, 0, 0, 2, vexRMOpGPR}, - "BLSMSKQ": {2, 0xF3, 1, 0, 2, vexRMOpGPR}, - "BLSRL": {2, 0xF3, 0, 0, 1, vexRMOpGPR}, - "BLSRQ": {2, 0xF3, 1, 0, 1, vexRMOpGPR}, - "RORXL": {3, 0xF0, 0, 3, -1, vexImmRMGPR}, - "RORXQ": {3, 0xF0, 1, 3, -1, vexImmRMGPR}, + "BLSIL": {2, 0xF3, 0, 0, 3, vexRMOpGPR, false}, + "BLSIQ": {2, 0xF3, 1, 0, 3, vexRMOpGPR, false}, + "BLSMSKL": {2, 0xF3, 0, 0, 2, vexRMOpGPR, false}, + "BLSMSKQ": {2, 0xF3, 1, 0, 2, vexRMOpGPR, false}, + "BLSRL": {2, 0xF3, 0, 0, 1, vexRMOpGPR, false}, + "BLSRQ": {2, 0xF3, 1, 0, 1, vexRMOpGPR, false}, + "RORXL": {3, 0xF0, 0, 3, -1, vexImmRMGPR, false}, + "RORXQ": {3, 0xF0, 1, 3, -1, vexImmRMGPR, false}, // VEX.128.0F.W0, mask-register test (KTESTW k1, k2: reg = dst, rm = src). - "KTESTW": {1, 0x99, 0, 0, -1, vexRM}, + "KTESTW": {1, 0x99, 0, 0, -1, vexRM, false}, // VEX.66.0F38.W0, broadcast a single/double to all lanes (reg=dst, // rm=scalar memory; SD is 256-bit only). - "VBROADCASTSS": {2, 0x18, 0, 1, -1, vexRM}, - "VBROADCASTSD": {2, 0x19, 0, 1, -1, vexRM}, + "VBROADCASTSS": {2, 0x18, 0, 1, -1, vexRM, false}, + "VBROADCASTSD": {2, 0x19, 0, 1, -1, vexRM, false}, // VEX.256.66.0F38.W0, broadcast a 128-bit lane into both halves of a // YMM (the encoder rejects an XMM destination, as go tool asm does). - "VBROADCASTI128": {2, 0x5A, 0, 1, -1, vexRM}, + "VBROADCASTI128": {2, 0x5A, 0, 1, -1, vexRM, false}, // VEX.128/256.66.0F.WIG, non-temporal store (vector source in reg, // memory destination in rm). - "VMOVNTDQ": {1, 0xE7, 0, 1, -1, vexRMRev}, + "VMOVNTDQ": {1, 0xE7, 0, 1, -1, vexRMRev, false}, // VEX.128/256.66.0F38.W0, test (reg=dst, rm=src, no vvvv). - "VPTEST": {2, 0x17, 0, 1, -1, vexRM}, + "VPTEST": {2, 0x17, 0, 1, -1, vexRM, false}, // VEX.66.0F38.W0, half-precision convert (reg=dst, rm=half-width // source). - "VCVTPH2PS": {2, 0x13, 0, 1, -1, vexRM}, + "VCVTPH2PS": {2, 0x13, 0, 1, -1, vexRM, false}, // VEX.F3.0F.WIG, replicate even/odd singles (reg=dst, rm=src). - "VMOVSLDUP": {1, 0x12, 0, 2, -1, vexRM}, - "VMOVSHDUP": {1, 0x16, 0, 2, -1, vexRM}, + "VMOVSLDUP": {1, 0x12, 0, 2, -1, vexRM, false}, + "VMOVSHDUP": {1, 0x16, 0, 2, -1, vexRM, false}, // VEX.66.0F.WIG, packed double to packed single conversion, the X/Y // spellings: the destination is always XMM and the spelling fixes the // source length (X = 128, Y = 256). - "VCVTPD2PSX": {1, 0x5A, 0, 1, -1, vexRMSrcLen}, - "VCVTPD2PSY": {1, 0x5A, 0, 1, -1, vexRMSrcLen}, + "VCVTPD2PSX": {1, 0x5A, 0, 1, -1, vexRMSrcLen, false}, + "VCVTPD2PSY": {1, 0x5A, 0, 1, -1, vexRMSrcLen, false}, // VEX scalar conversions between vector and general-purpose registers. // Vector to GPR (two operands: vec/mem source, GPR destination, vvvv // unused; the length follows the source). - "VCVTSD2SI": {1, 0x2D, 0, 3, -1, vexRM}, - "VCVTSD2SIQ": {1, 0x2D, 1, 3, -1, vexRM}, - "VCVTSS2SI": {1, 0x2D, 0, 2, -1, vexRM}, - "VCVTSS2SIQ": {1, 0x2D, 1, 2, -1, vexRM}, - "VCVTTSD2SI": {1, 0x2C, 0, 3, -1, vexRM}, - "VCVTTSD2SIQ": {1, 0x2C, 1, 3, -1, vexRM}, - "VCVTTSS2SI": {1, 0x2C, 0, 2, -1, vexRM}, - "VCVTTSS2SIQ": {1, 0x2C, 1, 2, -1, vexRM}, + "VCVTSD2SI": {1, 0x2D, 0, 3, -1, vexRM, false}, + "VCVTSD2SIQ": {1, 0x2D, 1, 3, -1, vexRM, false}, + "VCVTSS2SI": {1, 0x2D, 0, 2, -1, vexRM, false}, + "VCVTSS2SIQ": {1, 0x2D, 1, 2, -1, vexRM, false}, + "VCVTTSD2SI": {1, 0x2C, 0, 3, -1, vexRM, false}, + "VCVTTSD2SIQ": {1, 0x2C, 1, 3, -1, vexRM, false}, + "VCVTTSS2SI": {1, 0x2C, 0, 2, -1, vexRM, false}, + "VCVTTSS2SIQ": {1, 0x2C, 1, 2, -1, vexRM, false}, // GPR to vector (three operands: GPR/mem source in r/m, the preserved // vector source in vvvv, vector destination in reg). - "VCVTSI2SDL": {1, 0x2A, 0, 3, -1, vexNDS3}, - "VCVTSI2SDQ": {1, 0x2A, 1, 3, -1, vexNDS3}, - "VCVTSI2SSL": {1, 0x2A, 0, 2, -1, vexNDS3}, - "VCVTSI2SSQ": {1, 0x2A, 1, 2, -1, vexNDS3}, + "VCVTSI2SDL": {1, 0x2A, 0, 3, -1, vexNDS3, false}, + "VCVTSI2SDQ": {1, 0x2A, 1, 3, -1, vexNDS3, false}, + "VCVTSI2SSL": {1, 0x2A, 0, 2, -1, vexNDS3, false}, + "VCVTSI2SSQ": {1, 0x2A, 1, 2, -1, vexNDS3, false}, // VEX.128/256.66.0F.WIG, word shifts (opdigit selects the shift). - "VPSRLW": {1, 0x71, 0, 1, 2, vexShiftImm}, - "VPSRAW": {1, 0x71, 0, 1, 4, vexShiftImm}, - "VPSLLW": {1, 0x71, 0, 1, 6, vexShiftImm}, + "VPSRLW": {1, 0x71, 0, 1, 2, vexShiftImm, false}, + "VPSRAW": {1, 0x71, 0, 1, 4, vexShiftImm, false}, + "VPSLLW": {1, 0x71, 0, 1, 6, vexShiftImm, false}, // VEX.F2.0F, packed double to packed dword conversions, truncating and // non-truncating. The destination is always XMM; the X/Y spellings fix // the source length (XMM/YMM), and VEX.L follows it, see vexSrcLen. - "VCVTPD2DQX": {1, 0xE6, 0, 3, -1, vexRMSrcLen}, - "VCVTPD2DQY": {1, 0xE6, 0, 3, -1, vexRMSrcLen}, - "VCVTTPD2DQX": {1, 0xE6, 0, 1, -1, vexRMSrcLen}, - "VCVTTPD2DQY": {1, 0xE6, 0, 1, -1, vexRMSrcLen}, + "VCVTPD2DQX": {1, 0xE6, 0, 3, -1, vexRMSrcLen, false}, + "VCVTPD2DQY": {1, 0xE6, 0, 3, -1, vexRMSrcLen, false}, + "VCVTTPD2DQX": {1, 0xE6, 0, 1, -1, vexRMSrcLen, false}, + "VCVTTPD2DQY": {1, 0xE6, 0, 1, -1, vexRMSrcLen, false}, // --- the VEX forms the avx512enc corpus exercises alongside the EVEX // spellings, read off the toolchain opcode tables --- - "VAESDEC": {2, 0xDE, 0, 1, -1, vexNDS3}, - "VAESDECLAST": {2, 0xDF, 0, 1, -1, vexNDS3}, - "VAESENC": {2, 0xDC, 0, 1, -1, vexNDS3}, - "VAESENCLAST": {2, 0xDD, 0, 1, -1, vexNDS3}, - "VANDNPD": {1, 0x55, 0, 1, -1, vexNDS3}, - "VANDPD": {1, 0x54, 0, 1, -1, vexNDS3}, - "VCOMISD": {1, 0x2F, 0, 1, -1, vexRM}, - "VCVTSD2SS": {1, 0x5A, 0, 3, -1, vexNDS3}, - "VCVTSS2SD": {1, 0x5A, 0, 2, -1, vexNDS3}, - "VFMADD132PD": {2, 0x98, 1, 1, -1, vexNDS3}, - "VFMADD132PS": {2, 0x98, 0, 1, -1, vexNDS3}, - "VFMADD132SD": {2, 0x99, 1, 1, -1, vexNDS3}, - "VFMADD132SS": {2, 0x99, 0, 1, -1, vexNDS3}, - "VFMADD213PD": {2, 0xA8, 1, 1, -1, vexNDS3}, - "VFMADD213PS": {2, 0xA8, 0, 1, -1, vexNDS3}, - "VFMADD213SS": {2, 0xA9, 0, 1, -1, vexNDS3}, - "VFMADD231PS": {2, 0xB8, 0, 1, -1, vexNDS3}, - "VFMADD231SD": {2, 0xB9, 1, 1, -1, vexNDS3}, - "VFMADD231SS": {2, 0xB9, 0, 1, -1, vexNDS3}, - "VFMADDSUB132PD": {2, 0x96, 1, 1, -1, vexNDS3}, - "VFMADDSUB132PS": {2, 0x96, 0, 1, -1, vexNDS3}, - "VFMADDSUB213PD": {2, 0xA6, 1, 1, -1, vexNDS3}, - "VFMADDSUB213PS": {2, 0xA6, 0, 1, -1, vexNDS3}, - "VFMADDSUB231PD": {2, 0xB6, 1, 1, -1, vexNDS3}, - "VFMADDSUB231PS": {2, 0xB6, 0, 1, -1, vexNDS3}, - "VFMSUB132PD": {2, 0x9A, 1, 1, -1, vexNDS3}, - "VFMSUB132PS": {2, 0x9A, 0, 1, -1, vexNDS3}, - "VFMSUB132SD": {2, 0x9B, 1, 1, -1, vexNDS3}, - "VFMSUB132SS": {2, 0x9B, 0, 1, -1, vexNDS3}, - "VFMSUB213PD": {2, 0xAA, 1, 1, -1, vexNDS3}, - "VFMSUB213PS": {2, 0xAA, 0, 1, -1, vexNDS3}, - "VFMSUB213SD": {2, 0xAB, 1, 1, -1, vexNDS3}, - "VFMSUB213SS": {2, 0xAB, 0, 1, -1, vexNDS3}, - "VFMSUB231PD": {2, 0xBA, 1, 1, -1, vexNDS3}, - "VFMSUB231PS": {2, 0xBA, 0, 1, -1, vexNDS3}, - "VFMSUB231SD": {2, 0xBB, 1, 1, -1, vexNDS3}, - "VFMSUB231SS": {2, 0xBB, 0, 1, -1, vexNDS3}, - "VFMSUBADD132PD": {2, 0x97, 1, 1, -1, vexNDS3}, - "VFMSUBADD132PS": {2, 0x97, 0, 1, -1, vexNDS3}, - "VFMSUBADD213PD": {2, 0xA7, 1, 1, -1, vexNDS3}, - "VFMSUBADD213PS": {2, 0xA7, 0, 1, -1, vexNDS3}, - "VFMSUBADD231PD": {2, 0xB7, 1, 1, -1, vexNDS3}, - "VFMSUBADD231PS": {2, 0xB7, 0, 1, -1, vexNDS3}, - "VFNMADD132PD": {2, 0x9C, 1, 1, -1, vexNDS3}, - "VFNMADD132PS": {2, 0x9C, 0, 1, -1, vexNDS3}, - "VFNMADD132SD": {2, 0x9D, 1, 1, -1, vexNDS3}, - "VFNMADD132SS": {2, 0x9D, 0, 1, -1, vexNDS3}, - "VFNMADD213PD": {2, 0xAC, 1, 1, -1, vexNDS3}, - "VFNMADD213PS": {2, 0xAC, 0, 1, -1, vexNDS3}, - "VFNMADD213SD": {2, 0xAD, 1, 1, -1, vexNDS3}, - "VFNMADD213SS": {2, 0xAD, 0, 1, -1, vexNDS3}, - "VFNMADD231PD": {2, 0xBC, 1, 1, -1, vexNDS3}, - "VFNMADD231PS": {2, 0xBC, 0, 1, -1, vexNDS3}, - "VFNMADD231SS": {2, 0xBD, 0, 1, -1, vexNDS3}, - "VFNMSUB132PD": {2, 0x9E, 1, 1, -1, vexNDS3}, - "VFNMSUB132PS": {2, 0x9E, 0, 1, -1, vexNDS3}, - "VFNMSUB132SD": {2, 0x9F, 1, 1, -1, vexNDS3}, - "VFNMSUB132SS": {2, 0x9F, 0, 1, -1, vexNDS3}, - "VFNMSUB213PD": {2, 0xAE, 1, 1, -1, vexNDS3}, - "VFNMSUB213PS": {2, 0xAE, 0, 1, -1, vexNDS3}, - "VFNMSUB213SD": {2, 0xAF, 1, 1, -1, vexNDS3}, - "VFNMSUB213SS": {2, 0xAF, 0, 1, -1, vexNDS3}, - "VFNMSUB231PD": {2, 0xBE, 1, 1, -1, vexNDS3}, - "VFNMSUB231PS": {2, 0xBE, 0, 1, -1, vexNDS3}, - "VFNMSUB231SD": {2, 0xBF, 1, 1, -1, vexNDS3}, - "VFNMSUB231SS": {2, 0xBF, 0, 1, -1, vexNDS3}, - "VGF2P8AFFINEINVQB": {3, 0xCF, 1, 1, -1, vexNDS3Imm}, - "VGF2P8MULB": {2, 0xCF, 0, 1, -1, vexNDS3}, - "VMOVNTDQA": {2, 0x2A, 0, 1, -1, vexRM}, - "VMOVNTPD": {1, 0x2B, 0, 1, -1, vexRMRev}, - "VORPD": {1, 0x56, 0, 1, -1, vexNDS3}, - "VPADDSB": {1, 0xEC, 0, 1, -1, vexNDS3}, - "VPADDSW": {1, 0xED, 0, 1, -1, vexNDS3}, - "VPADDUSB": {1, 0xDC, 0, 1, -1, vexNDS3}, - "VPADDUSW": {1, 0xDD, 0, 1, -1, vexNDS3}, - "VPCMPEQQ": {2, 0x29, 0, 1, -1, vexNDS3}, - "VPCMPEQW": {1, 0x75, 0, 1, -1, vexNDS3}, - "VPCMPGTB": {1, 0x64, 0, 1, -1, vexNDS3}, - "VPCMPGTD": {1, 0x66, 0, 1, -1, vexNDS3}, - "VPCMPGTW": {1, 0x65, 0, 1, -1, vexNDS3}, - "VPERMPS": {2, 0x16, 0, 1, -1, vexNDS3}, - "VPEXTRB": {3, 0x14, 0, 1, -1, vexExtract}, - "VPEXTRD": {3, 0x16, 0, 1, -1, vexExtract}, - "VPEXTRQ": {3, 0x16, 1, 1, -1, vexExtract}, - "VPINSRD": {3, 0x22, 0, 1, -1, vexNDS3Imm}, - "VPINSRQ": {3, 0x22, 1, 1, -1, vexNDS3Imm}, - "VPMULHRSW": {2, 0x0B, 0, 1, -1, vexNDS3}, - "VPMULHW": {1, 0xE5, 0, 1, -1, vexNDS3}, - "VPMULUDQ": {1, 0xF4, 0, 1, -1, vexNDS3}, - "VPSADBW": {1, 0xF6, 0, 1, -1, vexNDS3}, - "VPSUBSB": {1, 0xE8, 0, 1, -1, vexNDS3}, - "VPSUBSW": {1, 0xE9, 0, 1, -1, vexNDS3}, - "VPSUBUSB": {1, 0xD8, 0, 1, -1, vexNDS3}, - "VPSUBUSW": {1, 0xD9, 0, 1, -1, vexNDS3}, - "VPUNPCKHBW": {1, 0x68, 0, 1, -1, vexNDS3}, - "VPUNPCKHQDQ": {1, 0x6D, 0, 1, -1, vexNDS3}, - "VPUNPCKHWD": {1, 0x69, 0, 1, -1, vexNDS3}, - "VPUNPCKLBW": {1, 0x60, 0, 1, -1, vexNDS3}, - "VPUNPCKLWD": {1, 0x61, 0, 1, -1, vexNDS3}, - "VSQRTPD": {1, 0x51, 0, 1, -1, vexRM}, - "VSQRTSD": {1, 0x51, 0, 3, -1, vexNDS3}, - "VSQRTSS": {1, 0x51, 0, 2, -1, vexNDS3}, - "VUCOMISD": {1, 0x2E, 0, 1, -1, vexRM}, + "VAESDEC": {2, 0xDE, 0, 1, -1, vexNDS3, false}, + "VAESDECLAST": {2, 0xDF, 0, 1, -1, vexNDS3, false}, + "VAESENC": {2, 0xDC, 0, 1, -1, vexNDS3, false}, + "VAESENCLAST": {2, 0xDD, 0, 1, -1, vexNDS3, false}, + "VANDNPD": {1, 0x55, 0, 1, -1, vexNDS3, false}, + "VANDPD": {1, 0x54, 0, 1, -1, vexNDS3, false}, + "VCOMISD": {1, 0x2F, 0, 1, -1, vexRM, false}, + "VCVTSD2SS": {1, 0x5A, 0, 3, -1, vexNDS3, false}, + "VCVTSS2SD": {1, 0x5A, 0, 2, -1, vexNDS3, false}, + "VFMADD132PD": {2, 0x98, 1, 1, -1, vexNDS3, false}, + "VFMADD132PS": {2, 0x98, 0, 1, -1, vexNDS3, false}, + "VFMADD132SD": {2, 0x99, 1, 1, -1, vexNDS3, false}, + "VFMADD132SS": {2, 0x99, 0, 1, -1, vexNDS3, false}, + "VFMADD213PD": {2, 0xA8, 1, 1, -1, vexNDS3, false}, + "VFMADD213PS": {2, 0xA8, 0, 1, -1, vexNDS3, false}, + "VFMADD213SS": {2, 0xA9, 0, 1, -1, vexNDS3, false}, + "VFMADD231PS": {2, 0xB8, 0, 1, -1, vexNDS3, false}, + "VFMADD231SD": {2, 0xB9, 1, 1, -1, vexNDS3, false}, + "VFMADD231SS": {2, 0xB9, 0, 1, -1, vexNDS3, false}, + "VFMADDSUB132PD": {2, 0x96, 1, 1, -1, vexNDS3, false}, + "VFMADDSUB132PS": {2, 0x96, 0, 1, -1, vexNDS3, false}, + "VFMADDSUB213PD": {2, 0xA6, 1, 1, -1, vexNDS3, false}, + "VFMADDSUB213PS": {2, 0xA6, 0, 1, -1, vexNDS3, false}, + "VFMADDSUB231PD": {2, 0xB6, 1, 1, -1, vexNDS3, false}, + "VFMADDSUB231PS": {2, 0xB6, 0, 1, -1, vexNDS3, false}, + "VFMSUB132PD": {2, 0x9A, 1, 1, -1, vexNDS3, false}, + "VFMSUB132PS": {2, 0x9A, 0, 1, -1, vexNDS3, false}, + "VFMSUB132SD": {2, 0x9B, 1, 1, -1, vexNDS3, false}, + "VFMSUB132SS": {2, 0x9B, 0, 1, -1, vexNDS3, false}, + "VFMSUB213PD": {2, 0xAA, 1, 1, -1, vexNDS3, false}, + "VFMSUB213PS": {2, 0xAA, 0, 1, -1, vexNDS3, false}, + "VFMSUB213SD": {2, 0xAB, 1, 1, -1, vexNDS3, false}, + "VFMSUB213SS": {2, 0xAB, 0, 1, -1, vexNDS3, false}, + "VFMSUB231PD": {2, 0xBA, 1, 1, -1, vexNDS3, false}, + "VFMSUB231PS": {2, 0xBA, 0, 1, -1, vexNDS3, false}, + "VFMSUB231SD": {2, 0xBB, 1, 1, -1, vexNDS3, false}, + "VFMSUB231SS": {2, 0xBB, 0, 1, -1, vexNDS3, false}, + "VFMSUBADD132PD": {2, 0x97, 1, 1, -1, vexNDS3, false}, + "VFMSUBADD132PS": {2, 0x97, 0, 1, -1, vexNDS3, false}, + "VFMSUBADD213PD": {2, 0xA7, 1, 1, -1, vexNDS3, false}, + "VFMSUBADD213PS": {2, 0xA7, 0, 1, -1, vexNDS3, false}, + "VFMSUBADD231PD": {2, 0xB7, 1, 1, -1, vexNDS3, false}, + "VFMSUBADD231PS": {2, 0xB7, 0, 1, -1, vexNDS3, false}, + "VFNMADD132PD": {2, 0x9C, 1, 1, -1, vexNDS3, false}, + "VFNMADD132PS": {2, 0x9C, 0, 1, -1, vexNDS3, false}, + "VFNMADD132SD": {2, 0x9D, 1, 1, -1, vexNDS3, false}, + "VFNMADD132SS": {2, 0x9D, 0, 1, -1, vexNDS3, false}, + "VFNMADD213PD": {2, 0xAC, 1, 1, -1, vexNDS3, false}, + "VFNMADD213PS": {2, 0xAC, 0, 1, -1, vexNDS3, false}, + "VFNMADD213SD": {2, 0xAD, 1, 1, -1, vexNDS3, false}, + "VFNMADD213SS": {2, 0xAD, 0, 1, -1, vexNDS3, false}, + "VFNMADD231PD": {2, 0xBC, 1, 1, -1, vexNDS3, false}, + "VFNMADD231PS": {2, 0xBC, 0, 1, -1, vexNDS3, false}, + "VFNMADD231SS": {2, 0xBD, 0, 1, -1, vexNDS3, false}, + "VFNMSUB132PD": {2, 0x9E, 1, 1, -1, vexNDS3, false}, + "VFNMSUB132PS": {2, 0x9E, 0, 1, -1, vexNDS3, false}, + "VFNMSUB132SD": {2, 0x9F, 1, 1, -1, vexNDS3, false}, + "VFNMSUB132SS": {2, 0x9F, 0, 1, -1, vexNDS3, false}, + "VFNMSUB213PD": {2, 0xAE, 1, 1, -1, vexNDS3, false}, + "VFNMSUB213PS": {2, 0xAE, 0, 1, -1, vexNDS3, false}, + "VFNMSUB213SD": {2, 0xAF, 1, 1, -1, vexNDS3, false}, + "VFNMSUB213SS": {2, 0xAF, 0, 1, -1, vexNDS3, false}, + "VFNMSUB231PD": {2, 0xBE, 1, 1, -1, vexNDS3, false}, + "VFNMSUB231PS": {2, 0xBE, 0, 1, -1, vexNDS3, false}, + "VFNMSUB231SD": {2, 0xBF, 1, 1, -1, vexNDS3, false}, + "VFNMSUB231SS": {2, 0xBF, 0, 1, -1, vexNDS3, false}, + "VGF2P8AFFINEINVQB": {3, 0xCF, 1, 1, -1, vexNDS3Imm, false}, + "VGF2P8MULB": {2, 0xCF, 0, 1, -1, vexNDS3, false}, + "VMOVNTDQA": {2, 0x2A, 0, 1, -1, vexRM, false}, + "VMOVNTPD": {1, 0x2B, 0, 1, -1, vexRMRev, false}, + "VORPD": {1, 0x56, 0, 1, -1, vexNDS3, false}, + "VPADDSB": {1, 0xEC, 0, 1, -1, vexNDS3, false}, + "VPADDSW": {1, 0xED, 0, 1, -1, vexNDS3, false}, + "VPADDUSB": {1, 0xDC, 0, 1, -1, vexNDS3, false}, + "VPADDUSW": {1, 0xDD, 0, 1, -1, vexNDS3, false}, + "VPCMPEQQ": {2, 0x29, 0, 1, -1, vexNDS3, false}, + "VPCMPEQW": {1, 0x75, 0, 1, -1, vexNDS3, false}, + "VPCMPGTB": {1, 0x64, 0, 1, -1, vexNDS3, false}, + "VPCMPGTD": {1, 0x66, 0, 1, -1, vexNDS3, false}, + "VPCMPGTW": {1, 0x65, 0, 1, -1, vexNDS3, false}, + "VPERMPS": {2, 0x16, 0, 1, -1, vexNDS3, false}, + "VPEXTRB": {3, 0x14, 0, 1, -1, vexExtract, false}, + "VPEXTRD": {3, 0x16, 0, 1, -1, vexExtract, false}, + "VPEXTRQ": {3, 0x16, 1, 1, -1, vexExtract, false}, + "VPINSRD": {3, 0x22, 0, 1, -1, vexNDS3Imm, false}, + "VPINSRQ": {3, 0x22, 1, 1, -1, vexNDS3Imm, false}, + "VPMULHRSW": {2, 0x0B, 0, 1, -1, vexNDS3, false}, + "VPMULHW": {1, 0xE5, 0, 1, -1, vexNDS3, false}, + "VPMULUDQ": {1, 0xF4, 0, 1, -1, vexNDS3, false}, + "VPSADBW": {1, 0xF6, 0, 1, -1, vexNDS3, false}, + "VPSUBSB": {1, 0xE8, 0, 1, -1, vexNDS3, false}, + "VPSUBSW": {1, 0xE9, 0, 1, -1, vexNDS3, false}, + "VPSUBUSB": {1, 0xD8, 0, 1, -1, vexNDS3, false}, + "VPSUBUSW": {1, 0xD9, 0, 1, -1, vexNDS3, false}, + "VPUNPCKHBW": {1, 0x68, 0, 1, -1, vexNDS3, false}, + "VPUNPCKHQDQ": {1, 0x6D, 0, 1, -1, vexNDS3, false}, + "VPUNPCKHWD": {1, 0x69, 0, 1, -1, vexNDS3, false}, + "VPUNPCKLBW": {1, 0x60, 0, 1, -1, vexNDS3, false}, + "VPUNPCKLWD": {1, 0x61, 0, 1, -1, vexNDS3, false}, + "VSQRTPD": {1, 0x51, 0, 1, -1, vexRM, false}, + "VSQRTSD": {1, 0x51, 0, 3, -1, vexNDS3, false}, + "VSQRTSS": {1, 0x51, 0, 2, -1, vexNDS3, false}, + "VUCOMISD": {1, 0x2E, 0, 1, -1, vexRM, false}, // VEX.0F.WIG, the plain-prefix single/double arithmetic and unpack // spellings (no 66 prefix; WIG, so W = 0). - "VANDNPS": {1, 0x55, 0, 0, -1, vexNDS3}, - "VANDPS": {1, 0x54, 0, 0, -1, vexNDS3}, - "VORPS": {1, 0x56, 0, 0, -1, vexNDS3}, - "VUNPCKLPS": {1, 0x14, 0, 0, -1, vexNDS3}, - "VUNPCKHPS": {1, 0x15, 0, 0, -1, vexNDS3}, - "VSQRTPS": {1, 0x51, 0, 0, -1, vexRM}, - "VMOVNTPS": {1, 0x2B, 0, 0, -1, vexRMRev}, + "VANDNPS": {1, 0x55, 0, 0, -1, vexNDS3, false}, + "VANDPS": {1, 0x54, 0, 0, -1, vexNDS3, false}, + "VORPS": {1, 0x56, 0, 0, -1, vexNDS3, false}, + "VUNPCKLPS": {1, 0x14, 0, 0, -1, vexNDS3, false}, + "VUNPCKHPS": {1, 0x15, 0, 0, -1, vexNDS3, false}, + "VSQRTPS": {1, 0x51, 0, 0, -1, vexRM, false}, + "VMOVNTPS": {1, 0x2B, 0, 0, -1, vexRMRev, false}, // VEX.128.66.0F, the scalar and packed compare forms. - "VCOMISS": {1, 0x2F, 0, 1, -1, vexRM}, - "VUCOMISS": {1, 0x2E, 0, 0, -1, vexRM}, + "VCOMISS": {1, 0x2F, 0, 0, -1, vexRM, false}, + "VUCOMISS": {1, 0x2E, 0, 0, -1, vexRM, false}, // VEX.128.0F.F3/F2.W0, the high/low word shuffles ($imm, src, dst). - "VPSHUFHW": {1, 0x70, 0, 2, -1, vexImmRM}, - "VPSHUFLW": {1, 0x70, 0, 3, -1, vexImmRM}, + "VPSHUFHW": {1, 0x70, 0, 2, -1, vexImmRM, false}, + "VPSHUFLW": {1, 0x70, 0, 3, -1, vexImmRM, false}, + + // --- the SSE2/SSSE3/SSE4.1 AVX twins the corpus exercises under plain + // vector registers, which the toolchain encodes in VEX (EVEX only for + // ZMM, opmask and index-16+ registers) --- + + // VEX.NDS.128/256, the compare-with-predicate family ($imm, src2, src1, + // dst): PD/PS carry 66/none, the scalar SD/SS spellings F2/F3. + "VCMPPD": {1, 0xC2, 0, 1, -1, vexNDS3Imm, false}, + "VCMPPS": {1, 0xC2, 0, 0, -1, vexNDS3Imm, false}, + "VCMPSD": {1, 0xC2, 0, 3, -1, vexNDS3Imm, false}, + "VCMPSS": {1, 0xC2, 0, 2, -1, vexNDS3Imm, false}, + // VEX.128/256.66.0F.WIG, the packed integer arithmetic and logic twins + // the main table's EVEX rows shadow. + "VPADDB": {1, 0xFC, 0, 1, -1, vexNDS3, false}, + "VPADDW": {1, 0xFD, 0, 1, -1, vexNDS3, false}, + "VPSUBB": {1, 0xF8, 0, 1, -1, vexNDS3, false}, + "VPSUBW": {1, 0xF9, 0, 1, -1, vexNDS3, false}, + "VPMULLW": {1, 0xD5, 0, 1, -1, vexNDS3, false}, + "VPMULHUW": {1, 0xE4, 0, 1, -1, vexNDS3, false}, + "VPMADDWD": {1, 0xF5, 0, 1, -1, vexNDS3, false}, + "VPMAXSW": {1, 0xEE, 0, 1, -1, vexNDS3, false}, + "VPMAXUB": {1, 0xDE, 0, 1, -1, vexNDS3, false}, + "VPMINSW": {1, 0xEA, 0, 1, -1, vexNDS3, false}, + "VPMINUB": {1, 0xDA, 0, 1, -1, vexNDS3, false}, + "VPAVGB": {1, 0xE0, 0, 1, -1, vexNDS3, false}, + "VPAVGW": {1, 0xE3, 0, 1, -1, vexNDS3, false}, + "VPACKSSWB": {1, 0x63, 0, 1, -1, vexNDS3, false}, + "VPACKUSWB": {1, 0x67, 0, 1, -1, vexNDS3, false}, + // VEX.128/256.66.0F38.WIG, the SSE4.1 integer twins. + "VPMAXSB": {2, 0x3C, 0, 1, -1, vexNDS3, false}, + "VPMAXSD": {2, 0x3D, 0, 1, -1, vexNDS3, false}, + "VPMAXUD": {2, 0x3F, 0, 1, -1, vexNDS3, false}, + "VPMAXUW": {2, 0x3E, 0, 1, -1, vexNDS3, false}, + "VPMINSB": {2, 0x38, 0, 1, -1, vexNDS3, false}, + "VPMINSD": {2, 0x39, 0, 1, -1, vexNDS3, false}, + "VPMINUD": {2, 0x3B, 0, 1, -1, vexNDS3, false}, + "VPMINUW": {2, 0x3A, 0, 1, -1, vexNDS3, false}, + // the absolute values are two-operand, reg = destination. + "VPABSB": {2, 0x1C, 0, 1, -1, vexRM, false}, + "VPABSW": {2, 0x1D, 0, 1, -1, vexRM, false}, + "VPABSD": {2, 0x1E, 0, 1, -1, vexRM, false}, + "VPACKUSDW": {2, 0x2B, 0, 1, -1, vexNDS3, false}, + "VPMADDUBSW": {2, 0x04, 0, 1, -1, vexNDS3, false}, + "VPMOVSXBW": {2, 0x20, 0, 1, -1, vexRM, false}, + // VEX.128/256.66.0F38.W0/W1, the variable bit shifts (the count rides + // vvvv or memory). + // The toolchain consolidates each variable shift on one opcode with + // the W bit carrying the width: 45 for the right shifts, 46 for the + // arithmetic and 47 for the left, not the manual's per-width rows. + "VPSLLVD": {2, 0x47, 0, 1, -1, vexNDS3, false}, + "VPSLLVQ": {2, 0x47, 1, 1, -1, vexNDS3, false}, + "VPSRAVD": {2, 0x46, 0, 1, -1, vexNDS3, false}, + "VPSRLVD": {2, 0x45, 0, 1, -1, vexNDS3, false}, + "VPSRLVQ": {2, 0x45, 1, 1, -1, vexNDS3, false}, + // VEX.128/256.0F and F3.0F, the packed float converts the SSE2 pair + // spells: dword to packed single and its truncating twin. + "VCVTPS2DQ": {1, 0x5B, 0, 1, -1, vexRM, false}, + "VCVTTPS2DQ": {1, 0x5B, 0, 2, -1, vexRM, false}, + // the low-half register move the corpus exercises. + "VMOVLHPS": {1, 0x16, 0, 0, -1, vexNDS3, false}, + // VEX.NDS.128/256, the two-source shuffle with its imm8 control. + "VSHUFPS": {1, 0xC6, 0, 0, -1, vexNDS3Imm, false}, // --- the corpus families from amd64enc.s: the SSE3 horizontal and // add-subtract pairs, the SSSE3 sign and horizontal integers, the AVX @@ -490,75 +553,94 @@ var vexTable = map[string]vexSpec{ // VEX.128/256, the horizontal and add-subtract float pairs: PD carries // 66, PS carries F2 (0F 7C/7D and 0F D0). - "VHADDPD": {1, 0x7C, 0, 1, -1, vexNDS3}, - "VHADDPS": {1, 0x7C, 0, 3, -1, vexNDS3}, - "VHSUBPD": {1, 0x7D, 0, 1, -1, vexNDS3}, - "VHSUBPS": {1, 0x7D, 0, 3, -1, vexNDS3}, - "VADDSUBPD": {1, 0xD0, 0, 1, -1, vexNDS3}, - "VADDSUBPS": {1, 0xD0, 0, 3, -1, vexNDS3}, + "VHADDPD": {1, 0x7C, 0, 1, -1, vexNDS3, false}, + "VHADDPS": {1, 0x7C, 0, 3, -1, vexNDS3, false}, + "VHSUBPD": {1, 0x7D, 0, 1, -1, vexNDS3, false}, + "VHSUBPS": {1, 0x7D, 0, 3, -1, vexNDS3, false}, + "VADDSUBPD": {1, 0xD0, 0, 1, -1, vexNDS3, false}, + "VADDSUBPS": {1, 0xD0, 0, 3, -1, vexNDS3, false}, // VEX.128/256.0F38.W0, the SSSE3 horizontal integer family and the sign // controls, all NDS over 66. - "VPHADDW": {2, 0x01, 0, 1, -1, vexNDS3}, - "VPHADDD": {2, 0x02, 0, 1, -1, vexNDS3}, - "VPHADDSW": {2, 0x03, 0, 1, -1, vexNDS3}, - "VPHSUBW": {2, 0x05, 0, 1, -1, vexNDS3}, - "VPHSUBD": {2, 0x06, 0, 1, -1, vexNDS3}, - "VPHSUBSW": {2, 0x07, 0, 1, -1, vexNDS3}, - "VPSIGNB": {2, 0x08, 0, 1, -1, vexNDS3}, - "VPSIGNW": {2, 0x09, 0, 1, -1, vexNDS3}, - "VPSIGND": {2, 0x0A, 0, 1, -1, vexNDS3}, + "VPHADDW": {2, 0x01, 0, 1, -1, vexNDS3, false}, + "VPHADDD": {2, 0x02, 0, 1, -1, vexNDS3, false}, + "VPHADDSW": {2, 0x03, 0, 1, -1, vexNDS3, false}, + "VPHSUBW": {2, 0x05, 0, 1, -1, vexNDS3, false}, + "VPHSUBD": {2, 0x06, 0, 1, -1, vexNDS3, false}, + "VPHSUBSW": {2, 0x07, 0, 1, -1, vexNDS3, false}, + "VPSIGNB": {2, 0x08, 0, 1, -1, vexNDS3, false}, + "VPSIGNW": {2, 0x09, 0, 1, -1, vexNDS3, false}, + "VPSIGND": {2, 0x0A, 0, 1, -1, vexNDS3, false}, // VEX.128/256.0F38.W0, the masked loads/stores whose mask source rides // vvvv, memory in r/m: the Plan 9 order puts the destination first // (dst, mask, src), its own form below. VMOVHLPS is the plain NDS // register move under 0F 12, and the test pair and the AES inverse cube // root are two-operand. - "VMOVHLPS": {1, 0x12, 0, 0, -1, vexNDS3}, - "VMASKMOVPD": {2, 0x2F, 0, 1, -1, vexNDS3Dst}, - "VMASKMOVPS": {2, 0x2E, 0, 1, -1, vexNDS3Dst}, - "VPMASKMOVD": {2, 0x8E, 0, 1, -1, vexNDS3Dst}, - "VPMASKMOVQ": {2, 0x8E, 1, 1, -1, vexNDS3Dst}, - "VTESTPD": {2, 0x0F, 0, 1, -1, vexRM}, - "VTESTPS": {2, 0x0E, 0, 1, -1, vexRM}, - "VAESIMC": {2, 0xDB, 0, 1, -1, vexRM}, - "VPHMINPOSUW": {2, 0x41, 0, 1, -1, vexRM}, + "VMOVHLPS": {1, 0x12, 0, 0, -1, vexNDS3, false}, + "VMASKMOVPD": {2, 0x2F, 0, 1, -1, vexNDS3Dst, false}, + "VMASKMOVPS": {2, 0x2E, 0, 1, -1, vexNDS3Dst, false}, + "VPMASKMOVD": {2, 0x8E, 0, 1, -1, vexNDS3Dst, false}, + "VPMASKMOVQ": {2, 0x8E, 1, 1, -1, vexNDS3Dst, false}, + "VTESTPD": {2, 0x0F, 0, 1, -1, vexRM, false}, + "VTESTPS": {2, 0x0E, 0, 1, -1, vexRM, false}, + "VAESIMC": {2, 0xDB, 0, 1, -1, vexRM, false}, + "VPHMINPOSUW": {2, 0x41, 0, 1, -1, vexRM, false}, // VEX.128/256.66.0F38.W0, broadcast a 128-bit lane into a YMM. - "VBROADCASTF128": {2, 0x1A, 0, 1, -1, vexRM}, + "VBROADCASTF128": {2, 0x1A, 0, 1, -1, vexRM, false}, // VEX.128/256, the reciprocal square root estimates: PS bare (two-op // RM), SS F3-prefixed NDS (the scalar preserved source). - "VRCPPS": {1, 0x53, 0, 0, -1, vexRM}, - "VRSQRTPS": {1, 0x52, 0, 0, -1, vexRM}, - "VRCPSS": {1, 0x53, 0, 2, -1, vexNDS3}, - "VRSQRTSS": {1, 0x52, 0, 2, -1, vexNDS3}, + "VRCPPS": {1, 0x53, 0, 0, -1, vexRM, false}, + "VRSQRTPS": {1, 0x52, 0, 0, -1, vexRM, false}, + "VRCPSS": {1, 0x53, 0, 2, -1, vexNDS3, false}, + "VRSQRTSS": {1, 0x52, 0, 2, -1, vexNDS3, false}, // VEX.128/256.F2.0F.WIG, the unaligned load with cache hints and the // duplicated low double, F3 for the singles replica. - "VLDDQU": {1, 0xF0, 0, 3, -1, vexRM}, + "VLDDQU": {1, 0xF0, 0, 3, -1, vexRM, false}, // VEX.128/256.66.0F, the move-mask twin of VMOVMSKPS and the masked // store over the integer bank. - "VMOVMSKPD": {1, 0x50, 0, 1, -1, vexRM}, - "VMASKMOVDQU": {1, 0xF7, 0, 1, -1, vexRM}, + "VMOVMSKPD": {1, 0x50, 0, 1, -1, vexRM, false}, + "VMASKMOVDQU": {1, 0xF7, 0, 1, -1, vexRM, false}, // VEX.128/256.0F3A.W0, the imm8 tail the legacy set carries and its // variable blends over the is4 byte. - "VBLENDPD": {3, 0x0D, 0, 1, -1, vexNDS3Imm}, - "VBLENDPS": {3, 0x0C, 0, 1, -1, vexNDS3Imm}, - "VPBLENDW": {3, 0x0E, 0, 1, -1, vexNDS3Imm}, - "VDPPD": {3, 0x41, 0, 1, -1, vexNDS3Imm}, - "VDPPS": {3, 0x40, 0, 1, -1, vexNDS3Imm}, - "VINSERTPS": {3, 0x21, 0, 1, -1, vexNDS3Imm}, - "VMPSADBW": {3, 0x42, 0, 1, -1, vexNDS3Imm}, - "VROUNDSD": {3, 0x0B, 0, 1, -1, vexNDS3Imm}, - "VROUNDSS": {3, 0x0A, 0, 1, -1, vexNDS3Imm}, - "VPINSRB": {3, 0x20, 0, 1, -1, vexNDS3Imm}, + "VBLENDPD": {3, 0x0D, 0, 1, -1, vexNDS3Imm, false}, + "VBLENDPS": {3, 0x0C, 0, 1, -1, vexNDS3Imm, false}, + "VPBLENDW": {3, 0x0E, 0, 1, -1, vexNDS3Imm, false}, + "VDPPD": {3, 0x41, 0, 1, -1, vexNDS3Imm, false}, + "VDPPS": {3, 0x40, 0, 1, -1, vexNDS3Imm, false}, + "VINSERTPS": {3, 0x21, 0, 1, -1, vexNDS3Imm, false}, + "VMPSADBW": {3, 0x42, 0, 1, -1, vexNDS3Imm, false}, + "VROUNDSD": {3, 0x0B, 0, 1, -1, vexNDS3Imm, false}, + "VROUNDSS": {3, 0x0A, 0, 1, -1, vexNDS3Imm, false}, + "VPINSRB": {3, 0x20, 0, 1, -1, vexNDS3Imm, false}, // VEX.128.66.0F3A.W0, the four-operand variable blends over the /is4 // byte (the mask rides is4[7:4], the raw register number times 16). - "VBLENDVPS": {3, 0x4A, 0, 1, -1, vexBlend4}, - "VBLENDVPD": {3, 0x4B, 0, 1, -1, vexBlend4}, + "VBLENDVPS": {3, 0x4A, 0, 1, -1, vexBlend4, false}, + "VBLENDVPD": {3, 0x4B, 0, 1, -1, vexBlend4, false}, // VEX.256.66.0F3A.W0, the lane insert, and the GPR insert the legacy // set spells: VPINSRW rides plain 0F C4 with 66. - "VINSERTF128": {3, 0x18, 0, 1, -1, vexNDS3Imm}, - "VPINSRW": {1, 0xC4, 0, 1, -1, vexNDS3Imm}, + "VINSERTF128": {3, 0x18, 0, 1, -1, vexNDS3Imm, false}, + "VPINSRW": {1, 0xC4, 0, 1, -1, vexNDS3Imm, false}, // VEX.128/256.0F, the MXCSR accessors, memory alone, no prefix. - "VLDMXCSR": {1, 0xAE, 0, 0, 2, vexRMOpDigit}, - "VSTMXCSR": {1, 0xAE, 0, 0, 3, vexRMOpDigit}, + "VLDMXCSR": {1, 0xAE, 0, 0, 2, vexRMOpDigit, false}, + "VSTMXCSR": {1, 0xAE, 0, 0, 3, vexRMOpDigit, false}, +} + +// vex3Only lists the mnemonics whose rows never offer the 2-byte prefix: +// the toolchain emits the 3-byte spelling at every operand shape, and the +// corpus pins it. The table entries for the register-form members carry +// the preference directly. +var vex3Only = map[string]bool{ + "VCMPPD": true, "VCMPPS": true, "VCMPSD": true, "VCMPSS": true, + "VCOMISS": true, "VCVTPS2DQ": true, "VCVTTPS2DQ": true, + "VMOVLHPS": true, "VMOVUPS": true, +} + +func init() { + for n := range vex3Only { + if s, ok := vexTable[n]; ok { + s.vex3 = true + vexTable[n] = s + } + } } // vexSrcLen maps a source-length conversion mnemonic (the X/Y spellings of @@ -592,8 +674,8 @@ var vexVarShift = map[string]byte{ // NDS opcodes: the control rides vvvv, the immediate form the main table // carries never enters this path. var vexPermilReg = map[string]vexSpec{ - "VPERMILPS": {2, 0x0C, 0, 1, -1, vexNDS3}, - "VPERMILPD": {2, 0x0D, 0, 1, -1, vexNDS3}, + "VPERMILPS": {2, 0x0C, 0, 1, -1, vexNDS3, false}, + "VPERMILPD": {2, 0x0D, 0, 1, -1, vexNDS3, false}, } // vexMoveSpec describes a VEX move, which takes different opcodes (and @@ -631,6 +713,8 @@ var vexMoveTable = map[string]vexMoveSpec{ "VMOVSD": {1, 3, 0x10, 0x11, 0, 0, 0, 0, false, false, true}, // VEX.128.F3.0F.WIG, scalar single move, the same two shapes. "VMOVSS": {1, 2, 0x10, 0x11, 0, 0, 0, 0, false, false, true}, + // VEX.128/256, the unaligned packed single move the corpus exercises. + "VMOVUPS": {1, 0, 0x10, 0x11, 0, 0, 0, 0, true, false, false}, // VEX.128/256, aligned packed moves. "VMOVAPS": {1, 0, 0x28, 0x29, 0, 0, 0, 0, true, false, false}, "VMOVAPD": {1, 1, 0x28, 0x29, 0, 0, 0, 0, true, false, false}, @@ -1102,7 +1186,11 @@ func (e *enc) encodeVexImmRMGPR(spec vexSpec, ops []Operand) error { if err != nil { return err } - if err := e.emitVexFields(spec, 0, dstReg.idx&7, 0, 15, src); err != nil { + rBit := 0 + if dstReg.idx >= 8 { + rBit = 1 + } + if err := e.emitVexFields(spec, 0, dstReg.idx&7, rBit, 15, src); err != nil { return err } e.out = append(e.out, immByte) @@ -1319,7 +1407,7 @@ func (e *enc) encodeVexMove(mnem string, ms vexMoveSpec, ops []Operand) error { if reg.idx >= 8 { rBit = 1 } - spec := vexSpec{mapSel: ms.mapSel, opcode: op, w: w, pp: ms.pp, opdigit: -1} + spec := vexSpec{mapSel: ms.mapSel, opcode: op, w: w, pp: ms.pp, opdigit: -1, vex3: vex3Only[mnem]} return e.emitVexFields(spec, reg.vecLenBit(), regField, rBit, 15, rm) } @@ -1385,7 +1473,7 @@ func (e *enc) emitVexFields(spec vexSpec, l, regField, rBit, vvvvBar int, rm Ope return fmt.Errorf("invalid VEX r/m operand") } - if spec.mapSel == 1 && xBit == 0 && bBit == 0 && spec.w == 0 { + if !spec.vex3 && spec.mapSel == 1 && xBit == 0 && bBit == 0 && spec.w == 0 { e.out = append(e.out, 0xC5, byte((1-rBit)<<7|vvvvBar<<3|l<<2|spec.pp)) } else { e.out = append(e.out, 0xC4, diff --git a/asm/vex_test.go b/asm/vex_test.go index 78fe3be..467df98 100644 --- a/asm/vex_test.go +++ b/asm/vex_test.go @@ -79,6 +79,7 @@ var x86asmUnrecognised = map[string]bool{ // The register-only half move the decoder's AVX tables lack; its // bytes are pinned against go tool asm through the corpus test. "VMOVHLPS": true, + "VMOVLHPS": true, } // TestVexNDS3 encodes `mnem Y0, Y1, Y2` for every three-operand NDS