feat(asm): add vpcmp compare, full opmask set, legacy sse integers and bswap
Assisted-by: GLM 5.3
This commit is contained in:
+52
-3
@@ -166,6 +166,19 @@ var evexTable = map[string]evexSpec{
|
||||
"VCMPSD": {1, 0xC2, 1, 3, -1, vexNDS3Imm, [3]int{8, 8, 8}},
|
||||
"VCMPSS": {1, 0xC2, 0, 2, -1, vexNDS3Imm, [3]int{4, 4, 4}},
|
||||
|
||||
// EVEX.66.0F3A — integer compares with an opmask destination, the same
|
||||
// NDS3Imm-with-k-reg shape as the floating-point compares; W selects the
|
||||
// operand width (byte/word vs dword/qword), the opcode the signedness.
|
||||
// The memory form takes a full vector, so disp8×N is 16/32/64.
|
||||
"VPCMPB": {3, 0x3F, 0, 1, -1, vexNDS3Imm, [3]int{16, 32, 64}},
|
||||
"VPCMPUB": {3, 0x3E, 0, 1, -1, vexNDS3Imm, [3]int{16, 32, 64}},
|
||||
"VPCMPW": {3, 0x3F, 1, 1, -1, vexNDS3Imm, [3]int{16, 32, 64}},
|
||||
"VPCMPUW": {3, 0x3E, 1, 1, -1, vexNDS3Imm, [3]int{16, 32, 64}},
|
||||
"VPCMPD": {3, 0x1F, 0, 1, -1, vexNDS3Imm, [3]int{16, 32, 64}},
|
||||
"VPCMPUD": {3, 0x1E, 0, 1, -1, vexNDS3Imm, [3]int{16, 32, 64}},
|
||||
"VPCMPQ": {3, 0x1F, 1, 1, -1, vexNDS3Imm, [3]int{16, 32, 64}},
|
||||
"VPCMPUQ": {3, 0x1E, 1, 1, -1, vexNDS3Imm, [3]int{16, 32, 64}},
|
||||
|
||||
// EVEX.66.0F38 — permutes (NDS form).
|
||||
"VPERMB": {2, 0x8D, 0, 1, -1, vexNDS3, [3]int{16, 32, 64}},
|
||||
"VPERMW": {2, 0x8D, 1, 1, -1, vexNDS3, [3]int{16, 32, 64}},
|
||||
@@ -1471,24 +1484,60 @@ type kOpSpec struct {
|
||||
|
||||
var kOpsTable = map[string]kOpSpec{
|
||||
// k ← k OP k: reg = dst, vvvv = src1, rm = src2 (three opmask
|
||||
// registers).
|
||||
// registers). Byte/word widths share W0 and differ by the 66 prefix;
|
||||
// dword/qword share the W bit selection the Go assembler emits.
|
||||
"KANDB": {1, 0x41, 0, 1, 1, vexNDS3},
|
||||
"KANDW": {1, 0x41, 0, 0, 1, vexNDS3},
|
||||
"KANDD": {1, 0x41, 1, 1, 1, vexNDS3},
|
||||
"KANDQ": {1, 0x41, 1, 0, 1, vexNDS3},
|
||||
"KANDNB": {1, 0x42, 0, 1, 1, vexNDS3},
|
||||
"KANDNW": {1, 0x42, 0, 0, 1, vexNDS3},
|
||||
"KANDND": {1, 0x42, 1, 1, 1, vexNDS3},
|
||||
"KANDNQ": {1, 0x42, 1, 0, 1, vexNDS3},
|
||||
"KORB": {1, 0x45, 0, 1, 1, vexNDS3},
|
||||
"KORW": {1, 0x45, 0, 0, 1, vexNDS3},
|
||||
"KORD": {1, 0x45, 1, 1, 1, vexNDS3},
|
||||
"KORQ": {1, 0x45, 1, 0, 1, vexNDS3},
|
||||
"KXNORB": {1, 0x46, 0, 1, 1, vexNDS3},
|
||||
"KXNORW": {1, 0x46, 0, 0, 1, vexNDS3},
|
||||
"KXNORD": {1, 0x46, 1, 1, 1, vexNDS3},
|
||||
"KXNORQ": {1, 0x46, 1, 0, 1, vexNDS3},
|
||||
"KXORB": {1, 0x47, 0, 1, 1, vexNDS3},
|
||||
"KXORW": {1, 0x47, 0, 0, 1, vexNDS3},
|
||||
"KXORD": {1, 0x47, 1, 1, 1, vexNDS3},
|
||||
"KXORQ": {1, 0x47, 1, 0, 1, vexNDS3},
|
||||
"KUNPCKBW": {1, 0x4B, 0, 1, 1, vexNDS3},
|
||||
"KUNPCKDQ": {1, 0x4B, 1, 0, 1, vexNDS3},
|
||||
"KADDB": {1, 0x4A, 0, 1, 1, vexNDS3},
|
||||
"KADDW": {1, 0x4A, 0, 0, 1, vexNDS3},
|
||||
"KADDD": {1, 0x4A, 1, 1, 1, vexNDS3},
|
||||
"KADDQ": {1, 0x4A, 1, 0, 1, vexNDS3},
|
||||
// k ← OP k (KNOT) and flags ← k OP k (KORTEST): reg = dst, rm = src.
|
||||
// k ← OP k (KNOT), k ← k AND~ k (KTEST-style RM) and flags ← k OP k
|
||||
// (KORTEST): reg = dst, rm = src.
|
||||
"KNOTB": {1, 0x44, 0, 1, 0, vexRM},
|
||||
"KNOTW": {1, 0x44, 0, 0, 0, vexRM},
|
||||
"KNOTD": {1, 0x44, 1, 1, 0, vexRM},
|
||||
"KNOTQ": {1, 0x44, 1, 0, 0, vexRM},
|
||||
"KORTESTB": {1, 0x98, 0, 1, 0, vexRM},
|
||||
"KORTESTW": {1, 0x98, 0, 0, 0, vexRM},
|
||||
"KORTESTD": {1, 0x98, 1, 1, 0, vexRM},
|
||||
// OP $imm, src, dst: reg = dst, rm = src, imm8.
|
||||
"KORTESTQ": {1, 0x98, 1, 0, 0, vexRM},
|
||||
"KTESTB": {1, 0x99, 0, 1, 0, vexRM},
|
||||
"KTESTW": {1, 0x99, 0, 0, 0, vexRM},
|
||||
"KTESTD": {1, 0x99, 1, 1, 0, vexRM},
|
||||
"KTESTQ": {1, 0x99, 1, 0, 0, vexRM},
|
||||
// OP $imm, src, dst: reg = dst, rm = src, imm8. The opcodes split by
|
||||
// direction (0x32/0x33 left, 0x30/0x31 right) and within each by
|
||||
// element half (0x32 byte/word, 0x33 dword/qword); W picks byte/dword
|
||||
// (W0) against word/qword (W1).
|
||||
"KSHIFTLB": {3, 0x32, 0, 1, 0, vexImmRM},
|
||||
"KSHIFTLW": {3, 0x32, 1, 1, 0, vexImmRM},
|
||||
"KSHIFTLD": {3, 0x33, 0, 1, 0, vexImmRM},
|
||||
"KSHIFTLQ": {3, 0x33, 1, 1, 0, vexImmRM},
|
||||
"KSHIFTRB": {3, 0x30, 0, 1, 0, vexImmRM},
|
||||
"KSHIFTRW": {3, 0x30, 1, 1, 0, vexImmRM},
|
||||
"KSHIFTRD": {3, 0x31, 0, 1, 0, vexImmRM},
|
||||
"KSHIFTRQ": {3, 0x31, 1, 1, 0, vexImmRM},
|
||||
}
|
||||
|
||||
// isKOp reports whether the mnemonic is an opmask-register instruction.
|
||||
|
||||
Reference in New Issue
Block a user