perf intel pt: Update instruction decoder for APX and other new instructions
Subsystems (2)
Adrian Hunter
reviewercover perf intel pt: Update instruction decoder for APX and other new instructions
Hi
The x86 instruction decoder is used not only for decoding kernel instructions. It is also used by perf uprobes (user space probes) and by perf tools Intel Processor Trace decoding. Consequently, it needs to support instructions executed by user space also.
It should be noted that there are 2 copies of the instruction decoder. One for the kernel and one for tools, which is a policy to prevent changes from breaking builds.
Changes are based upon documents:
Intel® Advanced Performance Extensions (Intel® APX) Architecture Specification
April, 2024 Revision 4.0 355828-004
Intel® Architecture Instruction Set Extensions and Future Features Programming Reference March 2024 319433-052
The patches depend on a patch by Chang S. Bae that they have already submitted in their Key Locker patch set. Nevertheless, the patch is included in this patch set as well.
The final patch is an update to the perf tools' "x86 instruction decoder test - new instructions" test, which provides testing.
Adrian Hunter (9):
x86/insn: Fix PUSH instruction in x86 instruction decoder opcode map x86/insn: Add VEX versions of VPDPBUSD, VPDPBUSDS, VPDPWSSD and VPDPWSSDS x86/insn: Add misc new Intel instructions
x86/insn: Add support for REX2 prefix to the instruction decoder logic x86/insn: x86/insn: Add support for REX2 prefix to the instruction decoder opcode map x86/insn: Add support for APX EVEX to the instruction decoder logic x86/insn: Add support for APX EVEX instructions to the opcode map
perf intel pt: Add new JMPABS instruction to the Intel PT instruction decoder perf tests: Add APX and other new instructions to x86 instruction decoder test
Chang S. Bae (1):
x86/insn: Add Key Locker instructions to the opcode map
arch/x86/include/asm/inat.h | 17 +- arch/x86/include/asm/insn.h | 32 +- arch/x86/lib/insn.c | 29 + arch/x86/lib/x86-opcode-map.txt | 315 ++++-- arch/x86/tools/gen-insn-attr-x86.awk | 15 +- tools/arch/x86/include/asm/inat.h | 17 +- tools/arch/x86/include/asm/insn.h | 32 +- tools/arch/x86/lib/insn.c | 29 + tools/arch/x86/lib/x86-opcode-map.txt | 315 ++++-- tools/arch/x86/tools/gen-insn-attr-x86.awk | 15 +- tools/perf/arch/x86/tests/insn-x86-dat-32.c | 116 +++ tools/perf/arch/x86/tests/insn-x86-dat-64.c | 1026 ++++++++++++++++++++ tools/perf/arch/x86/tests/insn-x86-dat-src.c | 597 ++++++++++++ .../util/intel-pt-decoder/intel-pt-insn-decoder.c | 9 + 14 files changed, 2370 insertions(+), 194 deletions(-)
Regards
Adrian
Adrian Hunter
reviewerPATCH 1/10 x86/insn: Add Key Locker instructions to the opcode map
From: "Chang S. Bae" <[email protected]>
The x86 instruction decoder needs to know these new instructions that are going to be used in the crypto library as well as the x86 core code. Add the following:
LOADIWKEY:
Load a CPU-internal wrapping key.
ENCODEKEY128:
Wrap a 128-bit AES key to a key handle.
ENCODEKEY256:
Wrap a 256-bit AES key to a key handle.
AESENC128KL:
Encrypt a 128-bit block of data using a 128-bit AES key indicated by a key handle.
AESENC256KL:
Encrypt a 128-bit block of data using a 256-bit AES key indicated by a key handle.
AESDEC128KL:
Decrypt a 128-bit block of data using a 128-bit AES key indicated by a key handle.
AESDEC256KL:
Decrypt a 128-bit block of data using a 256-bit AES key indicated by a key handle.
AESENCWIDE128KL:
Encrypt 8 128-bit blocks of data using a 128-bit AES key indicated by a key handle.
AESENCWIDE256KL:
Encrypt 8 128-bit blocks of data using a 256-bit AES key indicated by a key handle.
AESDECWIDE128KL:
Decrypt 8 128-bit blocks of data using a 128-bit AES key indicated by a key handle.
AESDECWIDE256KL:
Decrypt 8 128-bit blocks of data using a 256-bit AES key indicated by a key handle.
The detail can be found in Intel Software Developer Manual.
--- arch/x86/lib/x86-opcode-map.txt | 11 +++++++---- tools/arch/x86/lib/x86-opcode-map.txt | 11 +++++++---- 2 files changed, 14 insertions(+), 8 deletions(-)
arch/x86/lib/x86-opcode-map.txt +7 -4
@@ -800,11 +800,12 @@ cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev) cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev) cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev) cf: vgf2p8mulb Vx,Wx (66) +d8: AESENCWIDE128KL Qpi (F3),(000),(00B) | AESENCWIDE256KL Qpi (F3),(000),(10B) | AESDECWIDE128KL Qpi (F3),(000),(01B) | AESDECWIDE256KL Qpi (F3),(000),(11B) db: VAESIMC Vdq,Wdq (66),(v1) -dc: vaesenc Vx,Hx,Wx (66) -dd: vaesenclast Vx,Hx,Wx (66) -de: vaesdec Vx,Hx,Wx (66) -df: vaesdeclast Vx,Hx,Wx (66) +dc: vaesenc Vx,Hx,Wx (66) | LOADIWKEY Vx,Hx (F3) | AESENC128KL Vpd,Qpi (F3) +dd: vaesenclast Vx,Hx,Wx (66) | AESDEC128KL Vpd,Qpi (F3) +de: vaesdec Vx,Hx,Wx (66) | AESENC256KL Vpd,Qpi (F3) +df: vaesdeclast Vx,Hx,Wx (66) | AESDEC256KL Vpd,Qpi (F3) f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2) | CRC32 Gd,Eb (66&F2) f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2) | CRC32 Gd,Ew (66&F2) f2: ANDN Gy,By,Ey (v)
@@ -814,6 +815,8 @@ f6: ADCX Gy,Ey (66) | ADOX Gy,Ey (F3) | MULX By,Gy,rDX,Ey (F2),(v) | WRSSD/Q My, f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v) f8: MOVDIR64B Gv,Mdqq (66) | ENQCMD Gv,Mdqq (F2) | ENQCMDS Gv,Mdqq (F3) f9: MOVDIRI My,Gy +fa: ENCODEKEY128 Ew,Ew (F3) +fb: ENCODEKEY256 Ew,Ew (F3) EndTable Table: 3-byte opcode 2 (0x0f 0x3a)
tools/arch/x86/lib/x86-opcode-map.txt +7 -4
@@ -800,11 +800,12 @@ cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev) cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev) cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev) cf: vgf2p8mulb Vx,Wx (66) +d8: AESENCWIDE128KL Qpi (F3),(000),(00B) | AESENCWIDE256KL Qpi (F3),(000),(10B) | AESDECWIDE128KL Qpi (F3),(000),(01B) | AESDECWIDE256KL Qpi (F3),(000),(11B) db: VAESIMC Vdq,Wdq (66),(v1) -dc: vaesenc Vx,Hx,Wx (66) -dd: vaesenclast Vx,Hx,Wx (66) -de: vaesdec Vx,Hx,Wx (66) -df: vaesdeclast Vx,Hx,Wx (66) +dc: vaesenc Vx,Hx,Wx (66) | LOADIWKEY Vx,Hx (F3) | AESENC128KL Vpd,Qpi (F3) +dd: vaesenclast Vx,Hx,Wx (66) | AESDEC128KL Vpd,Qpi (F3) +de: vaesdec Vx,Hx,Wx (66) | AESENC256KL Vpd,Qpi (F3) +df: vaesdeclast Vx,Hx,Wx (66) | AESDEC256KL Vpd,Qpi (F3) f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2) | CRC32 Gd,Eb (66&F2) f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2) | CRC32 Gd,Ew (66&F2) f2: ANDN Gy,By,Ey (v)
@@ -814,6 +815,8 @@ f6: ADCX Gy,Ey (66) | ADOX Gy,Ey (F3) | MULX By,Gy,rDX,Ey (F2),(v) | WRSSD/Q My, f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v) f8: MOVDIR64B Gv,Mdqq (66) | ENQCMD Gv,Mdqq (F2) | ENQCMDS Gv,Mdqq (F3) f9: MOVDIRI My,Gy +fa: ENCODEKEY128 Ew,Ew (F3) +fb: ENCODEKEY256 Ew,Ew (F3) EndTable Table: 3-byte opcode 2 (0x0f 0x3a)
Signature · 1 line
2.34.1
[tip: perf/core] x86/insn: Add Key Locker instructions to the opcode map
The following commit has been merged into the perf/core branch of tip:
The following commit has been merged into the perf/core branch of tip:
Commit-ID: a5dd673ab7d269e4a5b6565fc2b5c6295a079605 Gitweb: https://git.kernel.org/tip/a5dd673ab7d269e4a5b6565fc2b5c6295a079605 Author: Chang S. Bae <[email protected]> AuthorDate: Thu, 02 May 2024 13:58:44 +03:00 Committer: Ingo Molnar <[email protected]> CommitterDate: Thu, 02 May 2024 13:13:41 +02:00
x86/insn: Add Key Locker instructions to the opcode map
The x86 instruction decoder needs to know these new instructions that are going to be used in the crypto library as well as the x86 core code. Add the following:
LOADIWKEY:
Load a CPU-internal wrapping key.
ENCODEKEY128:
Wrap a 128-bit AES key to a key handle.
ENCODEKEY256:
Wrap a 256-bit AES key to a key handle.
AESENC128KL:
Encrypt a 128-bit block of data using a 128-bit AES key indicated by a key handle.
AESENC256KL:
Encrypt a 128-bit block of data using a 256-bit AES key indicated by a key handle.
AESDEC128KL:
Decrypt a 128-bit block of data using a 128-bit AES key indicated by a key handle.
AESDEC256KL:
Decrypt a 128-bit block of data using a 256-bit AES key indicated by a key handle.
AESENCWIDE128KL:
Encrypt 8 128-bit blocks of data using a 128-bit AES key indicated by a key handle.
AESENCWIDE256KL:
Encrypt 8 128-bit blocks of data using a 256-bit AES key indicated by a key handle.
AESDECWIDE128KL:
Decrypt 8 128-bit blocks of data using a 128-bit AES key indicated by a key handle.
AESDECWIDE256KL:
Decrypt 8 128-bit blocks of data using a 256-bit AES key indicated by a key handle.
The detail can be found in Intel Software Developer Manual.
--- arch/x86/lib/x86-opcode-map.txt | 11 +++++++---- tools/arch/x86/lib/x86-opcode-map.txt | 11 +++++++---- 2 files changed, 14 insertions(+), 8 deletions(-)
arch/x86/lib/x86-opcode-map.txt +7 -4
@@ -800,11 +800,12 @@ cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev) cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev) cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev) cf: vgf2p8mulb Vx,Wx (66) +d8: AESENCWIDE128KL Qpi (F3),(000),(00B) | AESENCWIDE256KL Qpi (F3),(000),(10B) | AESDECWIDE128KL Qpi (F3),(000),(01B) | AESDECWIDE256KL Qpi (F3),(000),(11B) db: VAESIMC Vdq,Wdq (66),(v1) -dc: vaesenc Vx,Hx,Wx (66) -dd: vaesenclast Vx,Hx,Wx (66) -de: vaesdec Vx,Hx,Wx (66) -df: vaesdeclast Vx,Hx,Wx (66) +dc: vaesenc Vx,Hx,Wx (66) | LOADIWKEY Vx,Hx (F3) | AESENC128KL Vpd,Qpi (F3) +dd: vaesenclast Vx,Hx,Wx (66) | AESDEC128KL Vpd,Qpi (F3) +de: vaesdec Vx,Hx,Wx (66) | AESENC256KL Vpd,Qpi (F3) +df: vaesdeclast Vx,Hx,Wx (66) | AESDEC256KL Vpd,Qpi (F3) f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2) | CRC32 Gd,Eb (66&F2) f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2) | CRC32 Gd,Ew (66&F2) f2: ANDN Gy,By,Ey (v)
@@ -814,6 +815,8 @@ f6: ADCX Gy,Ey (66) | ADOX Gy,Ey (F3) | MULX By,Gy,rDX,Ey (F2),(v) | WRSSD/Q My, f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v) f8: MOVDIR64B Gv,Mdqq (66) | ENQCMD Gv,Mdqq (F2) | ENQCMDS Gv,Mdqq (F3) f9: MOVDIRI My,Gy +fa: ENCODEKEY128 Ew,Ew (F3) +fb: ENCODEKEY256 Ew,Ew (F3) EndTable Table: 3-byte opcode 2 (0x0f 0x3a)
tools/arch/x86/lib/x86-opcode-map.txt +7 -4
@@ -800,11 +800,12 @@ cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev) cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev) cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev) cf: vgf2p8mulb Vx,Wx (66) +d8: AESENCWIDE128KL Qpi (F3),(000),(00B) | AESENCWIDE256KL Qpi (F3),(000),(10B) | AESDECWIDE128KL Qpi (F3),(000),(01B) | AESDECWIDE256KL Qpi (F3),(000),(11B) db: VAESIMC Vdq,Wdq (66),(v1) -dc: vaesenc Vx,Hx,Wx (66) -dd: vaesenclast Vx,Hx,Wx (66) -de: vaesdec Vx,Hx,Wx (66) -df: vaesdeclast Vx,Hx,Wx (66) +dc: vaesenc Vx,Hx,Wx (66) | LOADIWKEY Vx,Hx (F3) | AESENC128KL Vpd,Qpi (F3) +dd: vaesenclast Vx,Hx,Wx (66) | AESDEC128KL Vpd,Qpi (F3) +de: vaesdec Vx,Hx,Wx (66) | AESENC256KL Vpd,Qpi (F3) +df: vaesdeclast Vx,Hx,Wx (66) | AESDEC256KL Vpd,Qpi (F3) f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2) | CRC32 Gd,Eb (66&F2) f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2) | CRC32 Gd,Ew (66&F2) f2: ANDN Gy,By,Ey (v)
@@ -814,6 +815,8 @@ f6: ADCX Gy,Ey (66) | ADOX Gy,Ey (F3) | MULX By,Gy,rDX,Ey (F2),(v) | WRSSD/Q My, f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v) f8: MOVDIR64B Gv,Mdqq (66) | ENQCMD Gv,Mdqq (F2) | ENQCMDS Gv,Mdqq (F3) f9: MOVDIRI My,Gy +fa: ENCODEKEY128 Ew,Ew (F3) +fb: ENCODEKEY256 Ew,Ew (F3) EndTable Table: 3-byte opcode 2 (0x0f 0x3a)
Adrian Hunter
reviewerPATCH 2/10 x86/insn: Fix PUSH instruction in x86 instruction decoder opcode map
In reply to Adrian HunterThe x86 instruction decoder is used not only for decoding kernel instructions. It is also used by perf uprobes (user space probes) and by perf tools Intel Processor Trace decoding. Consequently, it needs to support instructions executed by user space also.
Opcode 0x68 PUSH instruction is currently defined as 64-bit operand size only i.e. (d64). That was based on Intel SDM Opcode Map. However that is contradicted by the Instruction Set Reference section for PUSH in the same manual.
Remove 64-bit operand size only annotation from opcode 0x68 PUSH instruction.
Example:
$ cat pushw.s
.global _start
.text
_start:
pushw $0x1234
mov $0x1,%eax # system call number (sys_exit)
int $0x80
$ as -o pushw.o pushw.s
$ ld -s -o pushw pushw.o
$ objdump -d pushw | tail -4
0000000000401000 <.text>:
401000: 66 68 34 12 pushw $0x1234
401004: b8 01 00 00 00 mov $0x1,%eax
401009: cd 80 int $0x80
$ perf record -e intel_pt//u ./pushw
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.014 MB perf.data ]Before:
$ perf script --insn-trace=disasm
Warning:
1 instruction trace errors
pushw 10349 [000] 10586.869237014: 401000 [unknown] (/home/ahunter/git/misc/rtit-tests/pushw) pushw $0x1234
pushw 10349 [000] 10586.869237014: 401006 [unknown] (/home/ahunter/git/misc/rtit-tests/pushw) addb %al, (%rax)
pushw 10349 [000] 10586.869237014: 401008 [unknown] (/home/ahunter/git/misc/rtit-tests/pushw) addb %cl, %ch
pushw 10349 [000] 10586.869237014: 40100a [unknown] (/home/ahunter/git/misc/rtit-tests/pushw) addb $0x2e, (%rax)
instruction trace error type 1 time 10586.869237224 cpu 0 pid 10349 tid 10349 ip 0x40100d code 6: Trace doesn't match instructionAfter:
$ perf script --insn-trace=disasm
pushw 10349 [000] 10586.869237014: 401000 [unknown] (./pushw) pushw $0x1234
pushw 10349 [000] 10586.869237014: 401004 [unknown] (./pushw) movl $1, %eax--- arch/x86/lib/x86-opcode-map.txt | 2 +- tools/arch/x86/lib/x86-opcode-map.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
arch/x86/lib/x86-opcode-map.txt +1 -1
@@ -148,7 +148,7 @@ AVXcode: 65: SEG=GS (Prefix) 66: Operand-Size (Prefix) 67: Address-Size (Prefix) -68: PUSH Iz (d64) +68: PUSH Iz 69: IMUL Gv,Ev,Iz 6a: PUSH Ib (d64) 6b: IMUL Gv,Ev,Ib
tools/arch/x86/lib/x86-opcode-map.txt +1 -1
@@ -148,7 +148,7 @@ AVXcode: 65: SEG=GS (Prefix) 66: Operand-Size (Prefix) 67: Address-Size (Prefix) -68: PUSH Iz (d64) +68: PUSH Iz 69: IMUL Gv,Ev,Iz 6a: PUSH Ib (d64) 6b: IMUL Gv,Ev,Ib
Signature · 1 line
2.34.1
[tip: perf/core] x86/insn: Fix PUSH instruction in x86 instruction decoder opcode map
The following commit has been merged into the perf/core branch of tip:
The following commit has been merged into the perf/core branch of tip:
Commit-ID: 59162e0c11d7257cde15f907d19fefe26da66692 Gitweb: https://git.kernel.org/tip/59162e0c11d7257cde15f907d19fefe26da66692 Author: Adrian Hunter <[email protected]> AuthorDate: Thu, 02 May 2024 13:58:45 +03:00 Committer: Ingo Molnar <[email protected]> CommitterDate: Thu, 02 May 2024 13:13:41 +02:00
x86/insn: Fix PUSH instruction in x86 instruction decoder opcode map
The x86 instruction decoder is used not only for decoding kernel instructions. It is also used by perf uprobes (user space probes) and by perf tools Intel Processor Trace decoding. Consequently, it needs to support instructions executed by user space also.
Opcode 0x68 PUSH instruction is currently defined as 64-bit operand size only i.e. (d64). That was based on Intel SDM Opcode Map. However that is contradicted by the Instruction Set Reference section for PUSH in the same manual.
Remove 64-bit operand size only annotation from opcode 0x68 PUSH instruction.
Example:
$ cat pushw.s
.global _start
.text
_start:
pushw $0x1234
mov $0x1,%eax # system call number (sys_exit)
int $0x80
$ as -o pushw.o pushw.s
$ ld -s -o pushw pushw.o
$ objdump -d pushw | tail -4
0000000000401000 <.text>:
401000: 66 68 34 12 pushw $0x1234
401004: b8 01 00 00 00 mov $0x1,%eax
401009: cd 80 int $0x80
$ perf record -e intel_pt//u ./pushw
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.014 MB perf.data ]Before:
$ perf script --insn-trace=disasm
Warning:
1 instruction trace errors
pushw 10349 [000] 10586.869237014: 401000 [unknown] (/home/ahunter/git/misc/rtit-tests/pushw) pushw $0x1234
pushw 10349 [000] 10586.869237014: 401006 [unknown] (/home/ahunter/git/misc/rtit-tests/pushw) addb %al, (%rax)
pushw 10349 [000] 10586.869237014: 401008 [unknown] (/home/ahunter/git/misc/rtit-tests/pushw) addb %cl, %ch
pushw 10349 [000] 10586.869237014: 40100a [unknown] (/home/ahunter/git/misc/rtit-tests/pushw) addb $0x2e, (%rax)
instruction trace error type 1 time 10586.869237224 cpu 0 pid 10349 tid 10349 ip 0x40100d code 6: Trace doesn't match instructionAfter:
$ perf script --insn-trace=disasm
pushw 10349 [000] 10586.869237014: 401000 [unknown] (./pushw) pushw $0x1234
pushw 10349 [000] 10586.869237014: 401004 [unknown] (./pushw) movl $1, %eax--- arch/x86/lib/x86-opcode-map.txt | 2 +- tools/arch/x86/lib/x86-opcode-map.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
arch/x86/lib/x86-opcode-map.txt +1 -1
@@ -148,7 +148,7 @@ AVXcode: 65: SEG=GS (Prefix) 66: Operand-Size (Prefix) 67: Address-Size (Prefix) -68: PUSH Iz (d64) +68: PUSH Iz 69: IMUL Gv,Ev,Iz 6a: PUSH Ib (d64) 6b: IMUL Gv,Ev,Ib
tools/arch/x86/lib/x86-opcode-map.txt +1 -1
@@ -148,7 +148,7 @@ AVXcode: 65: SEG=GS (Prefix) 66: Operand-Size (Prefix) 67: Address-Size (Prefix) -68: PUSH Iz (d64) +68: PUSH Iz 69: IMUL Gv,Ev,Iz 6a: PUSH Ib (d64) 6b: IMUL Gv,Ev,Ib
Arnaldo Carvalho de Melo
maintainerRe: [PATCH 02/10] x86/insn: Fix PUSH instruction in x86 instruction decoder opcode map
In reply to Adrian HunterQuoted 4 lines · Adrian Hunter
The x86 instruction decoder is used not only for decoding kernel instructions. It is also used by perf uprobes (user space probes) and by perf tools Intel Processor Trace decoding. Consequently, it needs to support instructions executed by user space also.
I wonder if we should do it this way, i.e. updating both tools/ and kernel source code in the same patch.
I think the best is to update the kernel bits, then, after that is merged, do the tooling part.
To avoid possible, yet unlikely, clashes in linux-next, for instance.
- Arnaldo
Quoted 80 lines
Opcode
0x68PUSH instruction is currently defined as 64-bit operand size only i.e. (d64). That was based on Intel SDM Opcode Map. However that is contradicted by the Instruction Set Reference section for PUSH in the same manual.Remove 64-bit operand size only annotation from opcode
0x68PUSH instruction.Example:
$ cat pushw.s .global _start .text _start: pushw $0x1234 mov $0x1,%eax # system call number (sys_exit) int $0x80 $ as -o pushw.o pushw.s $ ld -s -o pushw pushw.o $ objdump -d pushw | tail -4 0000000000401000 <.text>: 401000: 66 68 34 12 pushw $0x1234 401004: b8 01 00 00 00 mov $0x1,%eax 401009: cd 80 int $0x80 $ perf record -e intel_pt//u ./pushw [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.014 MB perf.data ]Before:
$ perf script --insn-trace=disasm Warning: 1 instruction trace errors pushw 10349 [000] 10586.869237014: 401000 [unknown] (/home/ahunter/git/misc/rtit-tests/pushw) pushw $0x1234 pushw 10349 [000] 10586.869237014: 401006 [unknown] (/home/ahunter/git/misc/rtit-tests/pushw) addb %al, (%rax) pushw 10349 [000] 10586.869237014: 401008 [unknown] (/home/ahunter/git/misc/rtit-tests/pushw) addb %cl, %ch pushw 10349 [000] 10586.869237014: 40100a [unknown] (/home/ahunter/git/misc/rtit-tests/pushw) addb $0x2e, (%rax) instruction trace error type 1 time 10586.869237224 cpu 0 pid 10349 tid 10349 ip 0x40100d code 6: Trace doesn't match instructionAfter:
$ perf script --insn-trace=disasm pushw 10349 [000] 10586.869237014: 401000 [unknown] (./pushw) pushw $0x1234 pushw 10349 [000] 10586.869237014: 401004 [unknown] (./pushw) movl $1, %eaxFixes eb13296cfaf6 ("x86: Instruction decoder API")Signed-off-by Adrian Hunter <[email protected]>--- arch/x86/lib/x86-opcode-map.txt | 2 +- tools/arch/x86/lib/x86-opcode-map.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)arch/x86/lib/x86-opcode-map.txt +1
-1@@ -148,7 +148,7 @@ AVXcode: 65: SEG=GS (Prefix) 66: Operand-Size (Prefix) 67: Address-Size (Prefix) -68: PUSH Iz (d64) +68: PUSH Iz 69: IMUL Gv,Ev,Iz 6a: PUSH Ib (d64) 6b: IMUL Gv,Ev,Ibtools/arch/x86/lib/x86-opcode-map.txt +1
-1@@ -148,7 +148,7 @@ AVXcode: 65: SEG=GS (Prefix) 66: Operand-Size (Prefix) 67: Address-Size (Prefix) -68: PUSH Iz (d64) +68: PUSH Iz 69: IMUL Gv,Ev,Iz 6a: PUSH Ib (d64) 6b: IMUL Gv,Ev,IbSignature · 1 line
2.34.1
Adrian Hunter
reviewerRe: [PATCH 02/10] x86/insn: Fix PUSH instruction in x86 instruction decoder opcode map
Quoted 11 lines · Arnaldo Carvalho de Melo
Quoted 4 lines · Adrian Hunter
The x86 instruction decoder is used not only for decoding kernel instructions. It is also used by perf uprobes (user space probes) and by perf tools Intel Processor Trace decoding. Consequently, it needs to support instructions executed by user space also.
I wonder if we should do it this way, i.e. updating both
tools/and kernel source code in the same patch.I think the best is to update the kernel bits, then, after that is merged, do the tooling part.
For objtool purposes, it might be better to do both at the same time.
Quoted 2 lines
To avoid possible, yet unlikely, clashes in linux-next, for instance.
Always gonna find out about clashes at some point.
Adrian Hunter
reviewerPATCH 3/10 x86/insn: Add VEX versions of VPDPBUSD, VPDPBUSDS, VPDPWSSD and VPDPWSSDS
In reply to Adrian HunterThe x86 instruction decoder is used not only for decoding kernel instructions. It is also used by perf uprobes (user space probes) and by perf tools Intel Processor Trace decoding. Consequently, it needs to support instructions executed by user space also.
Intel Architecture Instruction Set Extensions and Future Features manual number 319433-044 of May 2021, documented VEX versions of instructions VPDPBUSD, VPDPBUSDS, VPDPWSSD and VPDPWSSDS, but the opcode map has them listed as EVEX only.
Remove EVEX-only (ev) annotation from instructions VPDPBUSD, VPDPBUSDS, VPDPWSSD and VPDPWSSDS, which allows them to be decoded with either a VEX or EVEX prefix.
--- arch/x86/lib/x86-opcode-map.txt | 8 ++++---- tools/arch/x86/lib/x86-opcode-map.txt | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-)
arch/x86/lib/x86-opcode-map.txt +4 -4
@@ -698,10 +698,10 @@ AVXcode: 2 4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev) 4e: vrsqrt14ps/d Vpd,Wpd (66),(ev) 4f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev) -50: vpdpbusd Vx,Hx,Wx (66),(ev) -51: vpdpbusds Vx,Hx,Wx (66),(ev) -52: vdpbf16ps Vx,Hx,Wx (F3),(ev) | vpdpwssd Vx,Hx,Wx (66),(ev) | vp4dpwssd Vdqq,Hdqq,Wdq (F2),(ev) -53: vpdpwssds Vx,Hx,Wx (66),(ev) | vp4dpwssds Vdqq,Hdqq,Wdq (F2),(ev) +50: vpdpbusd Vx,Hx,Wx (66) +51: vpdpbusds Vx,Hx,Wx (66) +52: vdpbf16ps Vx,Hx,Wx (F3),(ev) | vpdpwssd Vx,Hx,Wx (66) | vp4dpwssd Vdqq,Hdqq,Wdq (F2),(ev) +53: vpdpwssds Vx,Hx,Wx (66) | vp4dpwssds Vdqq,Hdqq,Wdq (F2),(ev) 54: vpopcntb/w Vx,Wx (66),(ev) 55: vpopcntd/q Vx,Wx (66),(ev) 58: vpbroadcastd Vx,Wx (66),(v)
tools/arch/x86/lib/x86-opcode-map.txt +4 -4
@@ -698,10 +698,10 @@ AVXcode: 2 4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev) 4e: vrsqrt14ps/d Vpd,Wpd (66),(ev) 4f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev) -50: vpdpbusd Vx,Hx,Wx (66),(ev) -51: vpdpbusds Vx,Hx,Wx (66),(ev) -52: vdpbf16ps Vx,Hx,Wx (F3),(ev) | vpdpwssd Vx,Hx,Wx (66),(ev) | vp4dpwssd Vdqq,Hdqq,Wdq (F2),(ev) -53: vpdpwssds Vx,Hx,Wx (66),(ev) | vp4dpwssds Vdqq,Hdqq,Wdq (F2),(ev) +50: vpdpbusd Vx,Hx,Wx (66) +51: vpdpbusds Vx,Hx,Wx (66) +52: vdpbf16ps Vx,Hx,Wx (F3),(ev) | vpdpwssd Vx,Hx,Wx (66) | vp4dpwssd Vdqq,Hdqq,Wdq (F2),(ev) +53: vpdpwssds Vx,Hx,Wx (66) | vp4dpwssds Vdqq,Hdqq,Wdq (F2),(ev) 54: vpopcntb/w Vx,Wx (66),(ev) 55: vpopcntd/q Vx,Wx (66),(ev) 58: vpbroadcastd Vx,Wx (66),(v)
Signature · 1 line
2.34.1
[tip: perf/core] x86/insn: Add VEX versions of VPDPBUSD, VPDPBUSDS, VPDPWSSD and VPDPWSSDS
The following commit has been merged into the perf/core branch of tip:
The following commit has been merged into the perf/core branch of tip:
Commit-ID: b8000264348979b60dbe479255570a40e1b3a097 Gitweb: https://git.kernel.org/tip/b8000264348979b60dbe479255570a40e1b3a097 Author: Adrian Hunter <[email protected]> AuthorDate: Thu, 02 May 2024 13:58:46 +03:00 Committer: Ingo Molnar <[email protected]> CommitterDate: Thu, 02 May 2024 13:13:42 +02:00
x86/insn: Add VEX versions of VPDPBUSD, VPDPBUSDS, VPDPWSSD and VPDPWSSDS
The x86 instruction decoder is used not only for decoding kernel instructions. It is also used by perf uprobes (user space probes) and by perf tools Intel Processor Trace decoding. Consequently, it needs to support instructions executed by user space also.
Intel Architecture Instruction Set Extensions and Future Features manual number 319433-044 of May 2021, documented VEX versions of instructions VPDPBUSD, VPDPBUSDS, VPDPWSSD and VPDPWSSDS, but the opcode map has them listed as EVEX only.
Remove EVEX-only (ev) annotation from instructions VPDPBUSD, VPDPBUSDS, VPDPWSSD and VPDPWSSDS, which allows them to be decoded with either a VEX or EVEX prefix.
--- arch/x86/lib/x86-opcode-map.txt | 8 ++++---- tools/arch/x86/lib/x86-opcode-map.txt | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-)
arch/x86/lib/x86-opcode-map.txt +4 -4
@@ -698,10 +698,10 @@ AVXcode: 2 4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev) 4e: vrsqrt14ps/d Vpd,Wpd (66),(ev) 4f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev) -50: vpdpbusd Vx,Hx,Wx (66),(ev) -51: vpdpbusds Vx,Hx,Wx (66),(ev) -52: vdpbf16ps Vx,Hx,Wx (F3),(ev) | vpdpwssd Vx,Hx,Wx (66),(ev) | vp4dpwssd Vdqq,Hdqq,Wdq (F2),(ev) -53: vpdpwssds Vx,Hx,Wx (66),(ev) | vp4dpwssds Vdqq,Hdqq,Wdq (F2),(ev) +50: vpdpbusd Vx,Hx,Wx (66) +51: vpdpbusds Vx,Hx,Wx (66) +52: vdpbf16ps Vx,Hx,Wx (F3),(ev) | vpdpwssd Vx,Hx,Wx (66) | vp4dpwssd Vdqq,Hdqq,Wdq (F2),(ev) +53: vpdpwssds Vx,Hx,Wx (66) | vp4dpwssds Vdqq,Hdqq,Wdq (F2),(ev) 54: vpopcntb/w Vx,Wx (66),(ev) 55: vpopcntd/q Vx,Wx (66),(ev) 58: vpbroadcastd Vx,Wx (66),(v)
tools/arch/x86/lib/x86-opcode-map.txt +4 -4
@@ -698,10 +698,10 @@ AVXcode: 2 4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev) 4e: vrsqrt14ps/d Vpd,Wpd (66),(ev) 4f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev) -50: vpdpbusd Vx,Hx,Wx (66),(ev) -51: vpdpbusds Vx,Hx,Wx (66),(ev) -52: vdpbf16ps Vx,Hx,Wx (F3),(ev) | vpdpwssd Vx,Hx,Wx (66),(ev) | vp4dpwssd Vdqq,Hdqq,Wdq (F2),(ev) -53: vpdpwssds Vx,Hx,Wx (66),(ev) | vp4dpwssds Vdqq,Hdqq,Wdq (F2),(ev) +50: vpdpbusd Vx,Hx,Wx (66) +51: vpdpbusds Vx,Hx,Wx (66) +52: vdpbf16ps Vx,Hx,Wx (F3),(ev) | vpdpwssd Vx,Hx,Wx (66) | vp4dpwssd Vdqq,Hdqq,Wdq (F2),(ev) +53: vpdpwssds Vx,Hx,Wx (66) | vp4dpwssds Vdqq,Hdqq,Wdq (F2),(ev) 54: vpopcntb/w Vx,Wx (66),(ev) 55: vpopcntd/q Vx,Wx (66),(ev) 58: vpbroadcastd Vx,Wx (66),(v)
Adrian Hunter
reviewerPATCH 4/10 x86/insn: Add misc new Intel instructions
In reply to Adrian HunterThe x86 instruction decoder is used not only for decoding kernel instructions. It is also used by perf uprobes (user space probes) and by perf tools Intel Processor Trace decoding. Consequently, it needs to support instructions executed by user space also.
Add instructions documented in Intel Architecture Instruction Set Extensions and Future Features Programming Reference March 2024 319433-052, that have not been added yet:
AADD AAND AOR AXOR CMPccXADD PBNDKB RDMSRLIST URDMSR UWRMSR VBCSTNEBF162PS VBCSTNESH2PS VCVTNEEBF162PS VCVTNEEPH2PS VCVTNEOBF162PS VCVTNEOPH2PS VCVTNEPS2BF16 VPDPB[SU,UU,SS]D[,S] VPDPW[SU,US,UU]D[,S] VPMADD52HUQ VPMADD52LUQ VSHA512MSG1 VSHA512MSG2 VSHA512RNDS2 VSM3MSG1 VSM3MSG2 VSM3RNDS2 VSM4KEY4 VSM4RNDS4 WRMSRLIST TCMMIMFP16PS TCMMRLFP16PS TDPFP16PS PREFETCHIT1 PREFETCHIT0
--- arch/x86/lib/x86-opcode-map.txt | 57 +++++++++++++++++++++------ tools/arch/x86/lib/x86-opcode-map.txt | 57 +++++++++++++++++++++------ 2 files changed, 90 insertions(+), 24 deletions(-)
arch/x86/lib/x86-opcode-map.txt +45 -12
@@ -698,8 +698,8 @@ AVXcode: 2 4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev) 4e: vrsqrt14ps/d Vpd,Wpd (66),(ev) 4f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev) -50: vpdpbusd Vx,Hx,Wx (66) -51: vpdpbusds Vx,Hx,Wx (66) +50: vpdpbusd Vx,Hx,Wx (66) | vpdpbssd Vx,Hx,Wx (F2),(v) | vpdpbsud Vx,Hx,Wx (F3),(v) | vpdpbuud Vx,Hx,Wx (v) +51: vpdpbusds Vx,Hx,Wx (66) | vpdpbssds Vx,Hx,Wx (F2),(v) | vpdpbsuds Vx,Hx,Wx (F3),(v) | vpdpbuuds Vx,Hx,Wx (v) 52: vdpbf16ps Vx,Hx,Wx (F3),(ev) | vpdpwssd Vx,Hx,Wx (66) | vp4dpwssd Vdqq,Hdqq,Wdq (F2),(ev) 53: vpdpwssds Vx,Hx,Wx (66) | vp4dpwssds Vdqq,Hdqq,Wdq (F2),(ev) 54: vpopcntb/w Vx,Wx (66),(ev)
@@ -708,7 +708,7 @@ AVXcode: 2 59: vpbroadcastq Vx,Wx (66),(v) | vbroadcasti32x2 Vx,Wx (66),(evo) 5a: vbroadcasti128 Vqq,Mdq (66),(v) | vbroadcasti32x4/64x2 Vx,Wx (66),(evo) 5b: vbroadcasti32x8/64x4 Vqq,Mdq (66),(ev) -5c: TDPBF16PS Vt,Wt,Ht (F3),(v1) +5c: TDPBF16PS Vt,Wt,Ht (F3),(v1) | TDPFP16PS Vt,Wt,Ht (F2),(v1),(o64) # Skip 0x5d 5e: TDPBSSD Vt,Wt,Ht (F2),(v1) | TDPBSUD Vt,Wt,Ht (F3),(v1) | TDPBUSD Vt,Wt,Ht (66),(v1) | TDPBUUD Vt,Wt,Ht (v1) # Skip 0x5f-0x61
@@ -718,10 +718,12 @@ AVXcode: 2 65: vblendmps/d Vx,Hx,Wx (66),(ev) 66: vpblendmb/w Vx,Hx,Wx (66),(ev) 68: vp2intersectd/q Kx,Hx,Wx (F2),(ev) -# Skip 0x69-0x6f +# Skip 0x69-0x6b +6c: TCMMIMFP16PS Vt,Wt,Ht (66),(v1),(o64) | TCMMRLFP16PS Vt,Wt,Ht (v1),(o64) +# Skip 0x6d-0x6f 70: vpshldvw Vx,Hx,Wx (66),(ev) 71: vpshldvd/q Vx,Hx,Wx (66),(ev) -72: vcvtne2ps2bf16 Vx,Hx,Wx (F2),(ev) | vcvtneps2bf16 Vx,Wx (F3),(ev) | vpshrdvw Vx,Hx,Wx (66),(ev) +72: vcvtne2ps2bf16 Vx,Hx,Wx (F2),(ev) | vcvtneps2bf16 Vx,Wx (F3) | vpshrdvw Vx,Hx,Wx (66),(ev) 73: vpshrdvd/q Vx,Hx,Wx (66),(ev) 75: vpermi2b/w Vx,Hx,Wx (66),(ev) 76: vpermi2d/q Vx,Hx,Wx (66),(ev)
@@ -777,8 +779,10 @@ ac: vfnmadd213ps/d Vx,Hx,Wx (66),(v) ad: vfnmadd213ss/d Vx,Hx,Wx (66),(v),(v1) ae: vfnmsub213ps/d Vx,Hx,Wx (66),(v) af: vfnmsub213ss/d Vx,Hx,Wx (66),(v),(v1) -b4: vpmadd52luq Vx,Hx,Wx (66),(ev) -b5: vpmadd52huq Vx,Hx,Wx (66),(ev) +b0: vcvtneebf162ps Vx,Mx (F3),(!11B),(v) | vcvtneeph2ps Vx,Mx (66),(!11B),(v) | vcvtneobf162ps Vx,Mx (F2),(!11B),(v) | vcvtneoph2ps Vx,Mx (!11B),(v) +b1: vbcstnebf162ps Vx,Mw (F3),(!11B),(v) | vbcstnesh2ps Vx,Mw (66),(!11B),(v) +b4: vpmadd52luq Vx,Hx,Wx (66) +b5: vpmadd52huq Vx,Hx,Wx (66) b6: vfmaddsub231ps/d Vx,Hx,Wx (66),(v) b7: vfmsubadd231ps/d Vx,Hx,Wx (66),(v) b8: vfmadd231ps/d Vx,Hx,Wx (66),(v)
@@ -796,16 +800,35 @@ c7: Grp19 (1A) c8: sha1nexte Vdq,Wdq | vexp2ps/d Vx,Wx (66),(ev) c9: sha1msg1 Vdq,Wdq ca: sha1msg2 Vdq,Wdq | vrcp28ps/d Vx,Wx (66),(ev) -cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev) -cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev) -cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev) +cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev) | vsha512rnds2 Vqq,Hqq,Udq (F2),(11B),(v) +cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev) | vsha512msg1 Vqq,Udq (F2),(11B),(v) +cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev) | vsha512msg2 Vqq,Uqq (F2),(11B),(v) cf: vgf2p8mulb Vx,Wx (66) +d2: vpdpwsud Vx,Hx,Wx (F3),(v) | vpdpwusd Vx,Hx,Wx (66),(v) | vpdpwuud Vx,Hx,Wx (v) +d3: vpdpwsuds Vx,Hx,Wx (F3),(v) | vpdpwusds Vx,Hx,Wx (66),(v) | vpdpwuuds Vx,Hx,Wx (v) d8: AESENCWIDE128KL Qpi (F3),(000),(00B) | AESENCWIDE256KL Qpi (F3),(000),(10B) | AESDECWIDE128KL Qpi (F3),(000),(01B) | AESDECWIDE256KL Qpi (F3),(000),(11B) +da: vsm3msg1 Vdq,Hdq,Udq (v1) | vsm3msg2 Vdq,Hdq,Udq (66),(v1) | vsm4key4 Vx,Hx,Wx (F3),(v) | vsm4rnds4 Vx,Hx,Wx (F2),(v) db: VAESIMC Vdq,Wdq (66),(v1) dc: vaesenc Vx,Hx,Wx (66) | LOADIWKEY Vx,Hx (F3) | AESENC128KL Vpd,Qpi (F3) dd: vaesenclast Vx,Hx,Wx (66) | AESDEC128KL Vpd,Qpi (F3) de: vaesdec Vx,Hx,Wx (66) | AESENC256KL Vpd,Qpi (F3) df: vaesdeclast Vx,Hx,Wx (66) | AESDEC256KL Vpd,Qpi (F3) +e0: CMPOXADD My,Gy,By (66),(v1),(o64) +e1: CMPNOXADD My,Gy,By (66),(v1),(o64) +e2: CMPBXADD My,Gy,By (66),(v1),(o64) +e3: CMPNBXADD My,Gy,By (66),(v1),(o64) +e4: CMPZXADD My,Gy,By (66),(v1),(o64) +e5: CMPNZXADD My,Gy,By (66),(v1),(o64) +e6: CMPBEXADD My,Gy,By (66),(v1),(o64) +e7: CMPNBEXADD My,Gy,By (66),(v1),(o64) +e8: CMPSXADD My,Gy,By (66),(v1),(o64) +e9: CMPNSXADD My,Gy,By (66),(v1),(o64) +ea: CMPPXADD My,Gy,By (66),(v1),(o64) +eb: CMPNPXADD My,Gy,By (66),(v1),(o64) +ec: CMPLXADD My,Gy,By (66),(v1),(o64) +ed: CMPNLXADD My,Gy,By (66),(v1),(o64) +ee: CMPLEXADD My,Gy,By (66),(v1),(o64) +ef: CMPNLEXADD My,Gy,By (66),(v1),(o64) f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2) | CRC32 Gd,Eb (66&F2) f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2) | CRC32 Gd,Ew (66&F2) f2: ANDN Gy,By,Ey (v)
@@ -813,10 +836,11 @@ f3: Grp17 (1A) f5: BZHI Gy,Ey,By (v) | PEXT Gy,By,Ey (F3),(v) | PDEP Gy,By,Ey (F2),(v) | WRUSSD/Q My,Gy (66) f6: ADCX Gy,Ey (66) | ADOX Gy,Ey (F3) | MULX By,Gy,rDX,Ey (F2),(v) | WRSSD/Q My,Gy f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v) -f8: MOVDIR64B Gv,Mdqq (66) | ENQCMD Gv,Mdqq (F2) | ENQCMDS Gv,Mdqq (F3) +f8: MOVDIR64B Gv,Mdqq (66) | ENQCMD Gv,Mdqq (F2) | ENQCMDS Gv,Mdqq (F3) | URDMSR Rq,Gq (F2),(11B) | UWRMSR Gq,Rq (F3),(11B) f9: MOVDIRI My,Gy fa: ENCODEKEY128 Ew,Ew (F3) fb: ENCODEKEY256 Ew,Ew (F3) +fc: AADD My,Gy | AAND My,Gy (66) | AOR My,Gy (F2) | AXOR My,Gy (F3) EndTable Table: 3-byte opcode 2 (0x0f 0x3a)
@@ -896,6 +920,7 @@ c2: vcmpph Vx,Hx,Wx,Ib (ev) | vcmpsh Vx,Hx,Wx,Ib (F3),(ev) cc: sha1rnds4 Vdq,Wdq,Ib ce: vgf2p8affineqb Vx,Wx,Ib (66) cf: vgf2p8affineinvqb Vx,Wx,Ib (66) +de: vsm3rnds2 Vdq,Hdq,Wdq,Ib (66),(v1) df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1) f0: RORX Gy,Ey,Ib (F2),(v) | HRESET Gv,Ib (F3),(000),(11B) EndTable
@@ -978,6 +1003,12 @@ d6: vfcmulcph Vx,Hx,Wx (F2),(ev) | vfmulcph Vx,Hx,Wx (F3),(ev) d7: vfcmulcsh Vx,Hx,Wx (F2),(ev) | vfmulcsh Vx,Hx,Wx (F3),(ev) EndTable +Table: VEX map 7 +Referrer: +AVXcode: 7 +f8: URDMSR Rq,Id (F2),(v1),(11B) | UWRMSR Id,Rq (F3),(v1),(11B) +EndTable + GrpTable: Grp1 0: ADD 1: OR
@@ -1054,7 +1085,7 @@ GrpTable: Grp6 EndTable GrpTable: Grp7 -0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B) | PCONFIG (101),(11B) | ENCLV (000),(11B) | WRMSRNS (110),(11B) +0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B) | PCONFIG (101),(11B) | ENCLV (000),(11B) | WRMSRNS (110),(11B) | RDMSRLIST (F2),(110),(11B) | WRMSRLIST (F3),(110),(11B) | PBNDKB (111),(11B) 1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001),(11B) | CLAC (010),(11B) | STAC (011),(11B) | ENCLS (111),(11B) | ERETU (F3),(010),(11B) | ERETS (F2),(010),(11B) 2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B) | ENCLU (111),(11B) 3: LIDT Ms
@@ -1140,6 +1171,8 @@ GrpTable: Grp16 1: prefetch T0 2: prefetch T1 3: prefetch T2 +6: prefetch IT1 +7: prefetch IT0 EndTable GrpTable: Grp17
tools/arch/x86/lib/x86-opcode-map.txt +45 -12
129 lines not on this page · raw message
Signature · 1 line
2.34.1
[tip: perf/core] x86/insn: Add misc new Intel instructions
The following commit has been merged into the perf/core branch of tip:
The following commit has been merged into the perf/core branch of tip:
Commit-ID: 9dd3612895de3d967ebd607423571bd6b0854ccc Gitweb: https://git.kernel.org/tip/9dd3612895de3d967ebd607423571bd6b0854ccc Author: Adrian Hunter <[email protected]> AuthorDate: Thu, 02 May 2024 13:58:47 +03:00 Committer: Ingo Molnar <[email protected]> CommitterDate: Thu, 02 May 2024 13:13:43 +02:00
x86/insn: Add misc new Intel instructions
The x86 instruction decoder is used not only for decoding kernel instructions. It is also used by perf uprobes (user space probes) and by perf tools Intel Processor Trace decoding. Consequently, it needs to support instructions executed by user space also.
Add instructions documented in Intel Architecture Instruction Set Extensions and Future Features Programming Reference March 2024 319433-052, that have not been added yet:
AADD AAND AOR AXOR CMPccXADD PBNDKB RDMSRLIST URDMSR UWRMSR VBCSTNEBF162PS VBCSTNESH2PS VCVTNEEBF162PS VCVTNEEPH2PS VCVTNEOBF162PS VCVTNEOPH2PS VCVTNEPS2BF16 VPDPB[SU,UU,SS]D[,S] VPDPW[SU,US,UU]D[,S] VPMADD52HUQ VPMADD52LUQ VSHA512MSG1 VSHA512MSG2 VSHA512RNDS2 VSM3MSG1 VSM3MSG2 VSM3RNDS2 VSM4KEY4 VSM4RNDS4 WRMSRLIST TCMMIMFP16PS TCMMRLFP16PS TDPFP16PS PREFETCHIT1 PREFETCHIT0
--- arch/x86/lib/x86-opcode-map.txt | 57 ++++++++++++++++++++------ tools/arch/x86/lib/x86-opcode-map.txt | 57 ++++++++++++++++++++------ 2 files changed, 90 insertions(+), 24 deletions(-)
arch/x86/lib/x86-opcode-map.txt +45 -12
@@ -698,8 +698,8 @@ AVXcode: 2 4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev) 4e: vrsqrt14ps/d Vpd,Wpd (66),(ev) 4f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev) -50: vpdpbusd Vx,Hx,Wx (66) -51: vpdpbusds Vx,Hx,Wx (66) +50: vpdpbusd Vx,Hx,Wx (66) | vpdpbssd Vx,Hx,Wx (F2),(v) | vpdpbsud Vx,Hx,Wx (F3),(v) | vpdpbuud Vx,Hx,Wx (v) +51: vpdpbusds Vx,Hx,Wx (66) | vpdpbssds Vx,Hx,Wx (F2),(v) | vpdpbsuds Vx,Hx,Wx (F3),(v) | vpdpbuuds Vx,Hx,Wx (v) 52: vdpbf16ps Vx,Hx,Wx (F3),(ev) | vpdpwssd Vx,Hx,Wx (66) | vp4dpwssd Vdqq,Hdqq,Wdq (F2),(ev) 53: vpdpwssds Vx,Hx,Wx (66) | vp4dpwssds Vdqq,Hdqq,Wdq (F2),(ev) 54: vpopcntb/w Vx,Wx (66),(ev)
@@ -708,7 +708,7 @@ AVXcode: 2 59: vpbroadcastq Vx,Wx (66),(v) | vbroadcasti32x2 Vx,Wx (66),(evo) 5a: vbroadcasti128 Vqq,Mdq (66),(v) | vbroadcasti32x4/64x2 Vx,Wx (66),(evo) 5b: vbroadcasti32x8/64x4 Vqq,Mdq (66),(ev) -5c: TDPBF16PS Vt,Wt,Ht (F3),(v1) +5c: TDPBF16PS Vt,Wt,Ht (F3),(v1) | TDPFP16PS Vt,Wt,Ht (F2),(v1),(o64) # Skip 0x5d 5e: TDPBSSD Vt,Wt,Ht (F2),(v1) | TDPBSUD Vt,Wt,Ht (F3),(v1) | TDPBUSD Vt,Wt,Ht (66),(v1) | TDPBUUD Vt,Wt,Ht (v1) # Skip 0x5f-0x61
@@ -718,10 +718,12 @@ AVXcode: 2 65: vblendmps/d Vx,Hx,Wx (66),(ev) 66: vpblendmb/w Vx,Hx,Wx (66),(ev) 68: vp2intersectd/q Kx,Hx,Wx (F2),(ev) -# Skip 0x69-0x6f +# Skip 0x69-0x6b +6c: TCMMIMFP16PS Vt,Wt,Ht (66),(v1),(o64) | TCMMRLFP16PS Vt,Wt,Ht (v1),(o64) +# Skip 0x6d-0x6f 70: vpshldvw Vx,Hx,Wx (66),(ev) 71: vpshldvd/q Vx,Hx,Wx (66),(ev) -72: vcvtne2ps2bf16 Vx,Hx,Wx (F2),(ev) | vcvtneps2bf16 Vx,Wx (F3),(ev) | vpshrdvw Vx,Hx,Wx (66),(ev) +72: vcvtne2ps2bf16 Vx,Hx,Wx (F2),(ev) | vcvtneps2bf16 Vx,Wx (F3) | vpshrdvw Vx,Hx,Wx (66),(ev) 73: vpshrdvd/q Vx,Hx,Wx (66),(ev) 75: vpermi2b/w Vx,Hx,Wx (66),(ev) 76: vpermi2d/q Vx,Hx,Wx (66),(ev)
@@ -777,8 +779,10 @@ ac: vfnmadd213ps/d Vx,Hx,Wx (66),(v) ad: vfnmadd213ss/d Vx,Hx,Wx (66),(v),(v1) ae: vfnmsub213ps/d Vx,Hx,Wx (66),(v) af: vfnmsub213ss/d Vx,Hx,Wx (66),(v),(v1) -b4: vpmadd52luq Vx,Hx,Wx (66),(ev) -b5: vpmadd52huq Vx,Hx,Wx (66),(ev) +b0: vcvtneebf162ps Vx,Mx (F3),(!11B),(v) | vcvtneeph2ps Vx,Mx (66),(!11B),(v) | vcvtneobf162ps Vx,Mx (F2),(!11B),(v) | vcvtneoph2ps Vx,Mx (!11B),(v) +b1: vbcstnebf162ps Vx,Mw (F3),(!11B),(v) | vbcstnesh2ps Vx,Mw (66),(!11B),(v) +b4: vpmadd52luq Vx,Hx,Wx (66) +b5: vpmadd52huq Vx,Hx,Wx (66) b6: vfmaddsub231ps/d Vx,Hx,Wx (66),(v) b7: vfmsubadd231ps/d Vx,Hx,Wx (66),(v) b8: vfmadd231ps/d Vx,Hx,Wx (66),(v)
@@ -796,16 +800,35 @@ c7: Grp19 (1A) c8: sha1nexte Vdq,Wdq | vexp2ps/d Vx,Wx (66),(ev) c9: sha1msg1 Vdq,Wdq ca: sha1msg2 Vdq,Wdq | vrcp28ps/d Vx,Wx (66),(ev) -cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev) -cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev) -cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev) +cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev) | vsha512rnds2 Vqq,Hqq,Udq (F2),(11B),(v) +cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev) | vsha512msg1 Vqq,Udq (F2),(11B),(v) +cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev) | vsha512msg2 Vqq,Uqq (F2),(11B),(v) cf: vgf2p8mulb Vx,Wx (66) +d2: vpdpwsud Vx,Hx,Wx (F3),(v) | vpdpwusd Vx,Hx,Wx (66),(v) | vpdpwuud Vx,Hx,Wx (v) +d3: vpdpwsuds Vx,Hx,Wx (F3),(v) | vpdpwusds Vx,Hx,Wx (66),(v) | vpdpwuuds Vx,Hx,Wx (v) d8: AESENCWIDE128KL Qpi (F3),(000),(00B) | AESENCWIDE256KL Qpi (F3),(000),(10B) | AESDECWIDE128KL Qpi (F3),(000),(01B) | AESDECWIDE256KL Qpi (F3),(000),(11B) +da: vsm3msg1 Vdq,Hdq,Udq (v1) | vsm3msg2 Vdq,Hdq,Udq (66),(v1) | vsm4key4 Vx,Hx,Wx (F3),(v) | vsm4rnds4 Vx,Hx,Wx (F2),(v) db: VAESIMC Vdq,Wdq (66),(v1) dc: vaesenc Vx,Hx,Wx (66) | LOADIWKEY Vx,Hx (F3) | AESENC128KL Vpd,Qpi (F3) dd: vaesenclast Vx,Hx,Wx (66) | AESDEC128KL Vpd,Qpi (F3) de: vaesdec Vx,Hx,Wx (66) | AESENC256KL Vpd,Qpi (F3) df: vaesdeclast Vx,Hx,Wx (66) | AESDEC256KL Vpd,Qpi (F3) +e0: CMPOXADD My,Gy,By (66),(v1),(o64) +e1: CMPNOXADD My,Gy,By (66),(v1),(o64) +e2: CMPBXADD My,Gy,By (66),(v1),(o64) +e3: CMPNBXADD My,Gy,By (66),(v1),(o64) +e4: CMPZXADD My,Gy,By (66),(v1),(o64) +e5: CMPNZXADD My,Gy,By (66),(v1),(o64) +e6: CMPBEXADD My,Gy,By (66),(v1),(o64) +e7: CMPNBEXADD My,Gy,By (66),(v1),(o64) +e8: CMPSXADD My,Gy,By (66),(v1),(o64) +e9: CMPNSXADD My,Gy,By (66),(v1),(o64) +ea: CMPPXADD My,Gy,By (66),(v1),(o64) +eb: CMPNPXADD My,Gy,By (66),(v1),(o64) +ec: CMPLXADD My,Gy,By (66),(v1),(o64) +ed: CMPNLXADD My,Gy,By (66),(v1),(o64) +ee: CMPLEXADD My,Gy,By (66),(v1),(o64) +ef: CMPNLEXADD My,Gy,By (66),(v1),(o64) f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2) | CRC32 Gd,Eb (66&F2) f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2) | CRC32 Gd,Ew (66&F2) f2: ANDN Gy,By,Ey (v)
@@ -813,10 +836,11 @@ f3: Grp17 (1A) f5: BZHI Gy,Ey,By (v) | PEXT Gy,By,Ey (F3),(v) | PDEP Gy,By,Ey (F2),(v) | WRUSSD/Q My,Gy (66) f6: ADCX Gy,Ey (66) | ADOX Gy,Ey (F3) | MULX By,Gy,rDX,Ey (F2),(v) | WRSSD/Q My,Gy f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v) -f8: MOVDIR64B Gv,Mdqq (66) | ENQCMD Gv,Mdqq (F2) | ENQCMDS Gv,Mdqq (F3) +f8: MOVDIR64B Gv,Mdqq (66) | ENQCMD Gv,Mdqq (F2) | ENQCMDS Gv,Mdqq (F3) | URDMSR Rq,Gq (F2),(11B) | UWRMSR Gq,Rq (F3),(11B) f9: MOVDIRI My,Gy fa: ENCODEKEY128 Ew,Ew (F3) fb: ENCODEKEY256 Ew,Ew (F3) +fc: AADD My,Gy | AAND My,Gy (66) | AOR My,Gy (F2) | AXOR My,Gy (F3) EndTable Table: 3-byte opcode 2 (0x0f 0x3a)
@@ -896,6 +920,7 @@ c2: vcmpph Vx,Hx,Wx,Ib (ev) | vcmpsh Vx,Hx,Wx,Ib (F3),(ev) cc: sha1rnds4 Vdq,Wdq,Ib ce: vgf2p8affineqb Vx,Wx,Ib (66) cf: vgf2p8affineinvqb Vx,Wx,Ib (66) +de: vsm3rnds2 Vdq,Hdq,Wdq,Ib (66),(v1) df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1) f0: RORX Gy,Ey,Ib (F2),(v) | HRESET Gv,Ib (F3),(000),(11B) EndTable
@@ -978,6 +1003,12 @@ d6: vfcmulcph Vx,Hx,Wx (F2),(ev) | vfmulcph Vx,Hx,Wx (F3),(ev) d7: vfcmulcsh Vx,Hx,Wx (F2),(ev) | vfmulcsh Vx,Hx,Wx (F3),(ev) EndTable +Table: VEX map 7 +Referrer: +AVXcode: 7 +f8: URDMSR Rq,Id (F2),(v1),(11B) | UWRMSR Id,Rq (F3),(v1),(11B) +EndTable + GrpTable: Grp1 0: ADD 1: OR
@@ -1054,7 +1085,7 @@ GrpTable: Grp6 EndTable GrpTable: Grp7 -0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B) | PCONFIG (101),(11B) | ENCLV (000),(11B) | WRMSRNS (110),(11B) +0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B) | PCONFIG (101),(11B) | ENCLV (000),(11B) | WRMSRNS (110),(11B) | RDMSRLIST (F2),(110),(11B) | WRMSRLIST (F3),(110),(11B) | PBNDKB (111),(11B) 1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001),(11B) | CLAC (010),(11B) | STAC (011),(11B) | ENCLS (111),(11B) | ERETU (F3),(010),(11B) | ERETS (F2),(010),(11B) 2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B) | ENCLU (111),(11B) 3: LIDT Ms
@@ -1140,6 +1171,8 @@ GrpTable: Grp16 1: prefetch T0 2: prefetch T1 3: prefetch T2 +6: prefetch IT1 +7: prefetch IT0 EndTable GrpTable: Grp17
tools/arch/x86/lib/x86-opcode-map.txt +45 -12
129 lines not on this page · raw message
Adrian Hunter
reviewerPATCH 5/10 x86/insn: Add support for REX2 prefix to the instruction decoder logic
In reply to Adrian HunterIntel Advanced Performance Extensions (APX) uses a new 2-byte prefix named REX2 to select extended general purpose registers (EGPRs) i.e. r16 to r31.
The REX2 prefix is effectively an extended version of the REX prefix.
REX2 and EVEX are also used with PUSH/POP instructions to provide a Push-Pop Acceleration (PPX) hint. With PPX hints, a CPU will attempt to fast-forward register data between matching PUSH and POP instructions.
REX2 is valid only with opcodes in maps 0 and 1. Similar extension for other maps is provided by the EVEX prefix, covered in a separate patch.
Some opcodes in maps 0 and 1 are reserved under REX2. One of these is used for a new 64-bit absolute direct jump instruction JMPABS.
Refer to the Intel Advanced Performance Extensions (Intel APX) Architecture Specification for details.
Define a code value for the REX2 prefix (INAT_PFX_REX2), and add attribute flags for opcodes reserved under REX2 (INAT_NO_REX2) and to identify opcodes (only JMPABS) that require a mandatory REX2 prefix (INAT_REX2_VARIANT).
Amend logic to read the REX2 prefix and get the opcode attribute for the map number (0 or 1) encoded in the REX2 prefix.
Amend the awk script that generates the attribute tables from the opcode map, to recognise "REX2" as attribute INAT_PFX_REX2, and "(!REX2)" as attribute INAT_NO_REX2, and "(REX2)" as attribute INAT_REX2_VARIANT.
--- arch/x86/include/asm/inat.h | 11 +++++++++- arch/x86/include/asm/insn.h | 25 ++++++++++++++++++---- arch/x86/lib/insn.c | 25 ++++++++++++++++++++++ arch/x86/tools/gen-insn-attr-x86.awk | 11 +++++++++- tools/arch/x86/include/asm/inat.h | 11 +++++++++- tools/arch/x86/include/asm/insn.h | 25 ++++++++++++++++++---- tools/arch/x86/lib/insn.c | 25 ++++++++++++++++++++++ tools/arch/x86/tools/gen-insn-attr-x86.awk | 11 +++++++++- 8 files changed, 132 insertions(+), 12 deletions(-)
arch/x86/include/asm/inat.h +10 -1
@@ -35,6 +35,8 @@#define INAT_PFX_VEX2 13/* 2-bytes VEX prefix */ #define INAT_PFX_VEX3 14/* 3-bytes VEX prefix */ #define INAT_PFX_EVEX 15/* EVEX prefix */ +/* x86-64 REX2 prefix */ +#define INAT_PFX_REX2 16/* 0xD5 */ #define INAT_LSTPFX_MAX 3#define INAT_LGCPFX_MAX 11
@@ -50,7 +52,7 @@/* Legacy prefix */ #define INAT_PFX_OFFS 0 -#define INAT_PFX_BITS 4 +#define INAT_PFX_BITS 5#define INAT_PFX_MAX ((1 << INAT_PFX_BITS) - 1)#define INAT_PFX_MASK (INAT_PFX_MAX << INAT_PFX_OFFS)/* Escape opcodes */
@@ -77,6 +79,8 @@#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5))#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6))#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7)) +#define INAT_NO_REX2 (1 << (INAT_FLAG_OFFS + 8)) +#define INAT_REX2_VARIANT (1 << (INAT_FLAG_OFFS + 9))/* Attribute making macros for attribute tables */ #define INAT_MAKE_PREFIX (pfx) (pfx << INAT_PFX_OFFS)#define INAT_MAKE_ESCAPE (esc) (esc << INAT_ESC_OFFS)
@@ -128,6 +132,11 @@ static inline int inat_is_rex_prefix(insn_attr_t attr)return (attr &INAT_PFX_MASK ) ==INAT_PFX_REX ; } +static inline int inat_is_rex2_prefix (insn_attr_t attr) +{ +return (attr &INAT_PFX_MASK ) ==INAT_PFX_REX2 ; +} +static inline int inat_last_prefix_id (insn_attr_t attr) {if ((attr &INAT_PFX_MASK ) >INAT_LSTPFX_MAX )
arch/x86/include/asm/insn.h +21 -4
@@ -112,10 +112,15 @@ struct insn {#define X86_SIB_INDEX (sib) (((sib) & 0x38) >> 3)#define X86_SIB_BASE (sib) ((sib) & 0x07) -#define X86_REX_W (rex) ((rex) & 8) -#define X86_REX_R (rex) ((rex) & 4) -#define X86_REX_X (rex) ((rex) & 2) -#define X86_REX_B (rex) ((rex) & 1) +#define X86_REX2_M (rex) ((rex) & 0x80)/* REX2 M0 */ +#define X86_REX2_R (rex) ((rex) & 0x40)/* REX2 R4 */ +#define X86_REX2_X (rex) ((rex) & 0x20)/* REX2 X4 */ +#define X86_REX2_B (rex) ((rex) & 0x10)/* REX2 B4 */ + +#define X86_REX_W (rex) ((rex) & 8)/* REX or REX2 W */ +#define X86_REX_R (rex) ((rex) & 4)/* REX or REX2 R3 */ +#define X86_REX_X (rex) ((rex) & 2)/* REX or REX2 X3 */ +#define X86_REX_B (rex) ((rex) & 1)/* REX or REX2 B3 */ /* VEX bit flags */ #define X86_VEX_W (vex) ((vex) & 0x80)/* VEX3 Byte2 */
@@ -161,6 +166,18 @@ static inline void insn_get_attribute(struct insn *insn)/* Instruction uses RIP-relative addressing */ extern int insn_rip_relative (struct insn *insn); +static inline int insn_is_rex2 (struct insn *insn) +{ +if (!insn->prefixes.got) +insn_get_prefixes (insn); +return insn->rex_prefix.nbytes ==2 ; +} + +static inline insn_byte_t insn_rex2_m_bit (struct insn *insn) +{ +return X86_REX2_M (insn->rex_prefix.bytes[1 ]); +} +static inline int insn_is_avx (struct insn *insn) {if (!insn->prefixes.got)
arch/x86/lib/insn.c +25 -0
@@ -185,6 +185,17 @@ int insn_get_prefixes(struct insn *insn)if (X86_REX_W (b))/* REX.W overrides opnd_size */ insn->opnd_bytes =8 ; + }else if (inat_is_rex2_prefix (attr)) { +insn_set_byte (&insn->rex_prefix,0 , b); + b =peek_nbyte_next (insn_byte_t, insn,1 ); +insn_set_byte (&insn->rex_prefix,1 , b); + insn->rex_prefix.nbytes =2 ; + insn->next_byte +=2 ; +if (X86_REX_W (b)) +/* REX.W overrides opnd_size */ + insn->opnd_bytes =8 ; + insn->rex_prefix.got =1 ; + goto vex_end; } } insn->rex_prefix.got =1 ;
@@ -294,6 +305,20 @@ int insn_get_opcode(struct insn *insn) goto end; } +/* Check if there is REX2 prefix or not */ +if (insn_is_rex2 (insn)) { +if (insn_rex2_m_bit (insn)) { +/* map 1 is escape 0x0f */ +insn_attr_t esc_attr =inat_get_opcode_attribute (0x0f ); + + pfx_id =insn_last_prefix_id (insn); + insn->attr =inat_get_escape_attribute (op, pfx_id, esc_attr); + }else { + insn->attr =inat_get_opcode_attribute (op); + } + goto end; + } + insn->attr =inat_get_opcode_attribute (op);while (inat_is_escape (insn->attr)) {/* Get escaped opcode */
arch/x86/tools/gen-insn-attr-x86.awk +10 -1
@@ -64,7 +64,9 @@ BEGIN { modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])" force64_expr = "\\([df]64\\)" - rex_expr = "^REX(\\.[XRWB]+)*" + rex_expr = "^((REX(\\.[XRWB]+)+)|(REX$))" + rex2_expr = "\\(REX2\\)" + no_rex2_expr = "\\(!REX2\\)" fpu_expr = "^ESC" # TODO lprefix1_expr = "\\((66|!F3)\\)"
@@ -99,6 +101,7 @@ BEGIN { prefix_num["VEX+1byte"] = "INAT_PFX_VEX2" prefix_num["VEX+2byte"] = "INAT_PFX_VEX3" prefix_num["EVEX"] = "INAT_PFX_EVEX" + prefix_num["REX2"] = "INAT_PFX_REX2" clear_vars() }
@@ -314,6 +317,10 @@ function convert_operands(count,opnd, i,j,imm,mod) if (match(ext, force64_expr)) flags = add_flags(flags, "INAT_FORCE64") + # check REX2 not allowed + if (match(ext, no_rex2_expr)) + flags = add_flags(flags, "INAT_NO_REX2") + # check REX prefix if (match(opcode, rex_expr)) flags = add_flags(flags, "INAT_MAKE_PREFIX(INAT_PFX_REX)")
@@ -351,6 +358,8 @@ function convert_operands(count,opnd, i,j,imm,mod) lptable3[idx] = add_flags(lptable3[idx],flags) variant = "INAT_VARIANT" } + if (match(ext, rex2_expr)) + table[idx] = add_flags(table[idx], "INAT_REX2_VARIANT") if (!match(ext, lprefix_expr)){ table[idx] = add_flags(table[idx],flags) }
tools/arch/x86/include/asm/inat.h +10 -1
@@ -35,6 +35,8 @@#define INAT_PFX_VEX2 13/* 2-bytes VEX prefix */ #define INAT_PFX_VEX3 14/* 3-bytes VEX prefix */ #define INAT_PFX_EVEX 15/* EVEX prefix */ +/* x86-64 REX2 prefix */ +#define INAT_PFX_REX2 16/* 0xD5 */ #define INAT_LSTPFX_MAX 3#define INAT_LGCPFX_MAX 11
@@ -50,7 +52,7 @@/* Legacy prefix */ #define INAT_PFX_OFFS 0 -#define INAT_PFX_BITS 4 +#define INAT_PFX_BITS 5#define INAT_PFX_MAX ((1 << INAT_PFX_BITS) - 1)#define INAT_PFX_MASK (INAT_PFX_MAX << INAT_PFX_OFFS)/* Escape opcodes */
@@ -77,6 +79,8 @@#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5))#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6))#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7)) +#define INAT_NO_REX2 (1 << (INAT_FLAG_OFFS + 8)) +#define INAT_REX2_VARIANT (1 << (INAT_FLAG_OFFS + 9))/* Attribute making macros for attribute tables */ #define INAT_MAKE_PREFIX (pfx) (pfx << INAT_PFX_OFFS)#define INAT_MAKE_ESCAPE (esc) (esc << INAT_ESC_OFFS)
@@ -128,6 +132,11 @@ static inline int inat_is_rex_prefix(insn_attr_t attr)return (attr &INAT_PFX_MASK ) ==INAT_PFX_REX ; } +static inline int inat_is_rex2_prefix (insn_attr_t attr) +{ +return (attr &INAT_PFX_MASK ) ==INAT_PFX_REX2 ; +} +static inline int inat_last_prefix_id (insn_attr_t attr) {if ((attr &INAT_PFX_MASK ) >INAT_LSTPFX_MAX )
tools/arch/x86/include/asm/insn.h +21 -4
@@ -112,10 +112,15 @@ struct insn {#define X86_SIB_INDEX (sib) (((sib) & 0x38) >> 3)#define X86_SIB_BASE (sib) ((sib) & 0x07) -#define X86_REX_W (rex) ((rex) & 8) -#define X86_REX_R (rex) ((rex) & 4) -#define X86_REX_X (rex) ((rex) & 2) -#define X86_REX_B (rex) ((rex) & 1) +#define X86_REX2_M (rex) ((rex) & 0x80)/* REX2 M0 */ +#define X86_REX2_R (rex) ((rex) & 0x40)/* REX2 R4 */ +#define X86_REX2_X (rex) ((rex) & 0x20)/* REX2 X4 */ +#define X86_REX2_B (rex) ((rex) & 0x10)/* REX2 B4 */ + +#define X86_REX_W (rex) ((rex) & 8)/* REX or REX2 W */ +#define X86_REX_R (rex) ((rex) & 4)/* REX or REX2 R3 */ +#define X86_REX_X (rex) ((rex) & 2)/* REX or REX2 X3 */ +#define X86_REX_B (rex) ((rex) & 1)/* REX or REX2 B3 */ /* VEX bit flags */ #define X86_VEX_W (vex) ((vex) & 0x80)/* VEX3 Byte2 */
@@ -161,6 +166,18 @@ static inline void insn_get_attribute(struct insn *insn)/* Instruction uses RIP-relative addressing */ extern int insn_rip_relative (struct insn *insn); +static inline int insn_is_rex2 (struct insn *insn) +{ +if (!insn->prefixes.got) +insn_get_prefixes (insn); +return insn->rex_prefix.nbytes ==2 ; +} + +static inline insn_byte_t insn_rex2_m_bit (struct insn *insn) +{ +return X86_REX2_M (insn->rex_prefix.bytes[1 ]); +} +static inline int insn_is_avx (struct insn *insn) {if (!insn->prefixes.got)
tools/arch/x86/lib/insn.c +25 -0
@@ -185,6 +185,17 @@ int insn_get_prefixes(struct insn *insn)if (X86_REX_W (b))/* REX.W overrides opnd_size */ insn->opnd_bytes =8 ; + }else if (inat_is_rex2_prefix (attr)) { +insn_set_byte (&insn->rex_prefix,0 , b); + b =peek_nbyte_next (insn_byte_t, insn,1 ); +insn_set_byte (&insn->rex_prefix,1 , b); + insn->rex_prefix.nbytes =2 ; + insn->next_byte +=2 ; +if (X86_REX_W (b)) +/* REX.W overrides opnd_size */ + insn->opnd_bytes =8 ; + insn->rex_prefix.got =1 ; + goto vex_end; } } insn->rex_prefix.got =1 ;
@@ -294,6 +305,20 @@ int insn_get_opcode(struct insn *insn) goto end; } +/* Check if there is REX2 prefix or not */ +if (insn_is_rex2 (insn)) { +if (insn_rex2_m_bit (insn)) { +/* map 1 is escape 0x0f */ +insn_attr_t esc_attr =inat_get_opcode_attribute (0x0f ); + + pfx_id =insn_last_prefix_id (insn); + insn->attr =inat_get_escape_attribute (op, pfx_id, esc_attr); + }else { + insn->attr =inat_get_opcode_attribute (op); + } + goto end; + } + insn->attr =inat_get_opcode_attribute (op);while (inat_is_escape (insn->attr)) {/* Get escaped opcode */
tools/arch/x86/tools/gen-insn-attr-x86.awk +10 -1
@@ -64,7 +64,9 @@ BEGIN { modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])" force64_expr = "\\([df]64\\)" - rex_expr = "^REX(\\.[XRWB]+)*" + rex_expr = "^((REX(\\.[XRWB]+)+)|(REX$))" + rex2_expr = "\\(REX2\\)" + no_rex2_expr = "\\(!REX2\\)" fpu_expr = "^ESC" # TODO lprefix1_expr = "\\((66|!F3)\\)"
@@ -99,6 +101,7 @@ BEGIN { prefix_num["VEX+1byte"] = "INAT_PFX_VEX2" prefix_num["VEX+2byte"] = "INAT_PFX_VEX3" prefix_num["EVEX"] = "INAT_PFX_EVEX" + prefix_num["REX2"] = "INAT_PFX_REX2" clear_vars() }
@@ -314,6 +317,10 @@ function convert_operands(count,opnd, i,j,imm,mod) if (match(ext, force64_expr)) flags = add_flags(flags, "INAT_FORCE64") + # check REX2 not allowed + if (match(ext, no_rex2_expr)) + flags = add_flags(flags, "INAT_NO_REX2") + # check REX prefix if (match(opcode, rex_expr)) flags = add_flags(flags, "INAT_MAKE_PREFIX(INAT_PFX_REX)")
@@ -351,6 +358,8 @@ function convert_operands(count,opnd, i,j,imm,mod) lptable3[idx] = add_flags(lptable3[idx],flags) variant = "INAT_VARIANT" } + if (match(ext, rex2_expr)) + table[idx] = add_flags(table[idx], "INAT_REX2_VARIANT") if (!match(ext, lprefix_expr)){ table[idx] = add_flags(table[idx],flags) }
Signature · 1 line
2.34.1
[tip: perf/core] x86/insn: Add support for REX2 prefix to the instruction decoder logic
The following commit has been merged into the perf/core branch of tip:
The following commit has been merged into the perf/core branch of tip:
Commit-ID: eada38d575a2b947b3ffefd570fea90a5a17feb3 Gitweb: https://git.kernel.org/tip/eada38d575a2b947b3ffefd570fea90a5a17feb3 Author: Adrian Hunter <[email protected]> AuthorDate: Thu, 02 May 2024 13:58:48 +03:00 Committer: Ingo Molnar <[email protected]> CommitterDate: Thu, 02 May 2024 13:13:44 +02:00
x86/insn: Add support for REX2 prefix to the instruction decoder logic
Intel Advanced Performance Extensions (APX) uses a new 2-byte prefix named REX2 to select extended general purpose registers (EGPRs) i.e. r16 to r31.
The REX2 prefix is effectively an extended version of the REX prefix.
REX2 and EVEX are also used with PUSH/POP instructions to provide a Push-Pop Acceleration (PPX) hint. With PPX hints, a CPU will attempt to fast-forward register data between matching PUSH and POP instructions.
REX2 is valid only with opcodes in maps 0 and 1. Similar extension for other maps is provided by the EVEX prefix, covered in a separate patch.
Some opcodes in maps 0 and 1 are reserved under REX2. One of these is used for a new 64-bit absolute direct jump instruction JMPABS.
Refer to the Intel Advanced Performance Extensions (Intel APX) Architecture Specification for details.
Define a code value for the REX2 prefix (INAT_PFX_REX2), and add attribute flags for opcodes reserved under REX2 (INAT_NO_REX2) and to identify opcodes (only JMPABS) that require a mandatory REX2 prefix (INAT_REX2_VARIANT).
Amend logic to read the REX2 prefix and get the opcode attribute for the map number (0 or 1) encoded in the REX2 prefix.
Amend the awk script that generates the attribute tables from the opcode map, to recognise "REX2" as attribute INAT_PFX_REX2, and "(!REX2)" as attribute INAT_NO_REX2, and "(REX2)" as attribute INAT_REX2_VARIANT.
--- arch/x86/include/asm/inat.h | 11 ++++++++- arch/x86/include/asm/insn.h | 25 +++++++++++++++++---- arch/x86/lib/insn.c | 25 +++++++++++++++++++++- arch/x86/tools/gen-insn-attr-x86.awk | 11 ++++++++- tools/arch/x86/include/asm/inat.h | 11 ++++++++- tools/arch/x86/include/asm/insn.h | 25 +++++++++++++++++---- tools/arch/x86/lib/insn.c | 25 +++++++++++++++++++++- tools/arch/x86/tools/gen-insn-attr-x86.awk | 11 ++++++++- 8 files changed, 132 insertions(+), 12 deletions(-)
arch/x86/include/asm/inat.h +10 -1
@@ -35,6 +35,8 @@#define INAT_PFX_VEX2 13/* 2-bytes VEX prefix */ #define INAT_PFX_VEX3 14/* 3-bytes VEX prefix */ #define INAT_PFX_EVEX 15/* EVEX prefix */ +/* x86-64 REX2 prefix */ +#define INAT_PFX_REX2 16/* 0xD5 */ #define INAT_LSTPFX_MAX 3#define INAT_LGCPFX_MAX 11
@@ -50,7 +52,7 @@/* Legacy prefix */ #define INAT_PFX_OFFS 0 -#define INAT_PFX_BITS 4 +#define INAT_PFX_BITS 5#define INAT_PFX_MAX ((1 << INAT_PFX_BITS) - 1)#define INAT_PFX_MASK (INAT_PFX_MAX << INAT_PFX_OFFS)/* Escape opcodes */
@@ -77,6 +79,8 @@#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5))#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6))#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7)) +#define INAT_NO_REX2 (1 << (INAT_FLAG_OFFS + 8)) +#define INAT_REX2_VARIANT (1 << (INAT_FLAG_OFFS + 9))/* Attribute making macros for attribute tables */ #define INAT_MAKE_PREFIX (pfx) (pfx << INAT_PFX_OFFS)#define INAT_MAKE_ESCAPE (esc) (esc << INAT_ESC_OFFS)
@@ -128,6 +132,11 @@ static inline int inat_is_rex_prefix(insn_attr_t attr)return (attr &INAT_PFX_MASK ) ==INAT_PFX_REX ; } +static inline int inat_is_rex2_prefix (insn_attr_t attr) +{ +return (attr &INAT_PFX_MASK ) ==INAT_PFX_REX2 ; +} +static inline int inat_last_prefix_id (insn_attr_t attr) {if ((attr &INAT_PFX_MASK ) >INAT_LSTPFX_MAX )
arch/x86/include/asm/insn.h +21 -4
@@ -112,10 +112,15 @@ struct insn {#define X86_SIB_INDEX (sib) (((sib) & 0x38) >> 3)#define X86_SIB_BASE (sib) ((sib) & 0x07) -#define X86_REX_W (rex) ((rex) & 8) -#define X86_REX_R (rex) ((rex) & 4) -#define X86_REX_X (rex) ((rex) & 2) -#define X86_REX_B (rex) ((rex) & 1) +#define X86_REX2_M (rex) ((rex) & 0x80)/* REX2 M0 */ +#define X86_REX2_R (rex) ((rex) & 0x40)/* REX2 R4 */ +#define X86_REX2_X (rex) ((rex) & 0x20)/* REX2 X4 */ +#define X86_REX2_B (rex) ((rex) & 0x10)/* REX2 B4 */ + +#define X86_REX_W (rex) ((rex) & 8)/* REX or REX2 W */ +#define X86_REX_R (rex) ((rex) & 4)/* REX or REX2 R3 */ +#define X86_REX_X (rex) ((rex) & 2)/* REX or REX2 X3 */ +#define X86_REX_B (rex) ((rex) & 1)/* REX or REX2 B3 */ /* VEX bit flags */ #define X86_VEX_W (vex) ((vex) & 0x80)/* VEX3 Byte2 */
@@ -161,6 +166,18 @@ static inline void insn_get_attribute(struct insn *insn)/* Instruction uses RIP-relative addressing */ extern int insn_rip_relative (struct insn *insn); +static inline int insn_is_rex2 (struct insn *insn) +{ +if (!insn->prefixes.got) +insn_get_prefixes (insn); +return insn->rex_prefix.nbytes ==2 ; +} + +static inline insn_byte_t insn_rex2_m_bit (struct insn *insn) +{ +return X86_REX2_M (insn->rex_prefix.bytes[1 ]); +} +static inline int insn_is_avx (struct insn *insn) {if (!insn->prefixes.got)
arch/x86/lib/insn.c +25 -0
@@ -185,6 +185,17 @@ found:if (X86_REX_W (b))/* REX.W overrides opnd_size */ insn->opnd_bytes =8 ; + }else if (inat_is_rex2_prefix (attr)) { +insn_set_byte (&insn->rex_prefix,0 , b); + b =peek_nbyte_next (insn_byte_t, insn,1 ); +insn_set_byte (&insn->rex_prefix,1 , b); + insn->rex_prefix.nbytes =2 ; + insn->next_byte +=2 ; +if (X86_REX_W (b)) +/* REX.W overrides opnd_size */ + insn->opnd_bytes =8 ; + insn->rex_prefix.got =1 ; + goto vex_end; } } insn->rex_prefix.got =1 ;
@@ -294,6 +305,20 @@ int insn_get_opcode(struct insn *insn) goto end; } +/* Check if there is REX2 prefix or not */ +if (insn_is_rex2 (insn)) { +if (insn_rex2_m_bit (insn)) { +/* map 1 is escape 0x0f */ +insn_attr_t esc_attr =inat_get_opcode_attribute (0x0f ); + + pfx_id =insn_last_prefix_id (insn); + insn->attr =inat_get_escape_attribute (op, pfx_id, esc_attr); + }else { + insn->attr =inat_get_opcode_attribute (op); + } + goto end; + } + insn->attr =inat_get_opcode_attribute (op);while (inat_is_escape (insn->attr)) {/* Get escaped opcode */
arch/x86/tools/gen-insn-attr-x86.awk +10 -1
@@ -64,7 +64,9 @@ BEGIN { modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])" force64_expr = "\\([df]64\\)" - rex_expr = "^REX(\\.[XRWB]+)*" + rex_expr = "^((REX(\\.[XRWB]+)+)|(REX$))" + rex2_expr = "\\(REX2\\)" + no_rex2_expr = "\\(!REX2\\)" fpu_expr = "^ESC" # TODO lprefix1_expr = "\\((66|!F3)\\)"
@@ -99,6 +101,7 @@ BEGIN { prefix_num["VEX+1byte"] = "INAT_PFX_VEX2" prefix_num["VEX+2byte"] = "INAT_PFX_VEX3" prefix_num["EVEX"] = "INAT_PFX_EVEX" + prefix_num["REX2"] = "INAT_PFX_REX2" clear_vars() }
@@ -314,6 +317,10 @@ function convert_operands(count,opnd, i,j,imm,mod) if (match(ext, force64_expr)) flags = add_flags(flags, "INAT_FORCE64") + # check REX2 not allowed + if (match(ext, no_rex2_expr)) + flags = add_flags(flags, "INAT_NO_REX2") + # check REX prefix if (match(opcode, rex_expr)) flags = add_flags(flags, "INAT_MAKE_PREFIX(INAT_PFX_REX)")
@@ -351,6 +358,8 @@ function convert_operands(count,opnd, i,j,imm,mod) lptable3[idx] = add_flags(lptable3[idx],flags) variant = "INAT_VARIANT" } + if (match(ext, rex2_expr)) + table[idx] = add_flags(table[idx], "INAT_REX2_VARIANT") if (!match(ext, lprefix_expr)){ table[idx] = add_flags(table[idx],flags) }
tools/arch/x86/include/asm/inat.h +10 -1
@@ -35,6 +35,8 @@#define INAT_PFX_VEX2 13/* 2-bytes VEX prefix */ #define INAT_PFX_VEX3 14/* 3-bytes VEX prefix */ #define INAT_PFX_EVEX 15/* EVEX prefix */ +/* x86-64 REX2 prefix */ +#define INAT_PFX_REX2 16/* 0xD5 */ #define INAT_LSTPFX_MAX 3#define INAT_LGCPFX_MAX 11
@@ -50,7 +52,7 @@/* Legacy prefix */ #define INAT_PFX_OFFS 0 -#define INAT_PFX_BITS 4 +#define INAT_PFX_BITS 5#define INAT_PFX_MAX ((1 << INAT_PFX_BITS) - 1)#define INAT_PFX_MASK (INAT_PFX_MAX << INAT_PFX_OFFS)/* Escape opcodes */
@@ -77,6 +79,8 @@#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5))#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6))#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7)) +#define INAT_NO_REX2 (1 << (INAT_FLAG_OFFS + 8)) +#define INAT_REX2_VARIANT (1 << (INAT_FLAG_OFFS + 9))/* Attribute making macros for attribute tables */ #define INAT_MAKE_PREFIX (pfx) (pfx << INAT_PFX_OFFS)#define INAT_MAKE_ESCAPE (esc) (esc << INAT_ESC_OFFS)
@@ -128,6 +132,11 @@ static inline int inat_is_rex_prefix(insn_attr_t attr)return (attr &INAT_PFX_MASK ) ==INAT_PFX_REX ; } +static inline int inat_is_rex2_prefix (insn_attr_t attr) +{ +return (attr &INAT_PFX_MASK ) ==INAT_PFX_REX2 ; +} +static inline int inat_last_prefix_id (insn_attr_t attr) {if ((attr &INAT_PFX_MASK ) >INAT_LSTPFX_MAX )
tools/arch/x86/include/asm/insn.h +21 -4
@@ -112,10 +112,15 @@ struct insn {#define X86_SIB_INDEX (sib) (((sib) & 0x38) >> 3)#define X86_SIB_BASE (sib) ((sib) & 0x07) -#define X86_REX_W (rex) ((rex) & 8) -#define X86_REX_R (rex) ((rex) & 4) -#define X86_REX_X (rex) ((rex) & 2) -#define X86_REX_B (rex) ((rex) & 1) +#define X86_REX2_M (rex) ((rex) & 0x80)/* REX2 M0 */ +#define X86_REX2_R (rex) ((rex) & 0x40)/* REX2 R4 */ +#define X86_REX2_X (rex) ((rex) & 0x20)/* REX2 X4 */ +#define X86_REX2_B (rex) ((rex) & 0x10)/* REX2 B4 */ + +#define X86_REX_W (rex) ((rex) & 8)/* REX or REX2 W */ +#define X86_REX_R (rex) ((rex) & 4)/* REX or REX2 R3 */ +#define X86_REX_X (rex) ((rex) & 2)/* REX or REX2 X3 */ +#define X86_REX_B (rex) ((rex) & 1)/* REX or REX2 B3 */ /* VEX bit flags */ #define X86_VEX_W (vex) ((vex) & 0x80)/* VEX3 Byte2 */
@@ -161,6 +166,18 @@ static inline void insn_get_attribute(struct insn *insn)/* Instruction uses RIP-relative addressing */ extern int insn_rip_relative (struct insn *insn); +static inline int insn_is_rex2 (struct insn *insn) +{ +if (!insn->prefixes.got) +insn_get_prefixes (insn); +return insn->rex_prefix.nbytes ==2 ; +} + +static inline insn_byte_t insn_rex2_m_bit (struct insn *insn) +{ +return X86_REX2_M (insn->rex_prefix.bytes[1 ]); +} +static inline int insn_is_avx (struct insn *insn) {if (!insn->prefixes.got)
tools/arch/x86/lib/insn.c +25 -0
@@ -185,6 +185,17 @@ found:if (X86_REX_W (b))/* REX.W overrides opnd_size */ insn->opnd_bytes =8 ; + }else if (inat_is_rex2_prefix (attr)) { +insn_set_byte (&insn->rex_prefix,0 , b); + b =peek_nbyte_next (insn_byte_t, insn,1 ); +insn_set_byte (&insn->rex_prefix,1 , b); + insn->rex_prefix.nbytes =2 ; + insn->next_byte +=2 ; +if (X86_REX_W (b)) +/* REX.W overrides opnd_size */ + insn->opnd_bytes =8 ; + insn->rex_prefix.got =1 ; + goto vex_end; } } insn->rex_prefix.got =1 ;
@@ -294,6 +305,20 @@ int insn_get_opcode(struct insn *insn) goto end; } +/* Check if there is REX2 prefix or not */ +if (insn_is_rex2 (insn)) { +if (insn_rex2_m_bit (insn)) { +/* map 1 is escape 0x0f */ +insn_attr_t esc_attr =inat_get_opcode_attribute (0x0f ); + + pfx_id =insn_last_prefix_id (insn); + insn->attr =inat_get_escape_attribute (op, pfx_id, esc_attr); + }else { + insn->attr =inat_get_opcode_attribute (op); + } + goto end; + } + insn->attr =inat_get_opcode_attribute (op);while (inat_is_escape (insn->attr)) {/* Get escaped opcode */
tools/arch/x86/tools/gen-insn-attr-x86.awk +10 -1
@@ -64,7 +64,9 @@ BEGIN { modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])" force64_expr = "\\([df]64\\)" - rex_expr = "^REX(\\.[XRWB]+)*" + rex_expr = "^((REX(\\.[XRWB]+)+)|(REX$))" + rex2_expr = "\\(REX2\\)" + no_rex2_expr = "\\(!REX2\\)" fpu_expr = "^ESC" # TODO lprefix1_expr = "\\((66|!F3)\\)"
@@ -99,6 +101,7 @@ BEGIN { prefix_num["VEX+1byte"] = "INAT_PFX_VEX2" prefix_num["VEX+2byte"] = "INAT_PFX_VEX3" prefix_num["EVEX"] = "INAT_PFX_EVEX" + prefix_num["REX2"] = "INAT_PFX_REX2" clear_vars() }
@@ -314,6 +317,10 @@ function convert_operands(count,opnd, i,j,imm,mod) if (match(ext, force64_expr)) flags = add_flags(flags, "INAT_FORCE64") + # check REX2 not allowed + if (match(ext, no_rex2_expr)) + flags = add_flags(flags, "INAT_NO_REX2") + # check REX prefix if (match(opcode, rex_expr)) flags = add_flags(flags, "INAT_MAKE_PREFIX(INAT_PFX_REX)")
@@ -351,6 +358,8 @@ function convert_operands(count,opnd, i,j,imm,mod) lptable3[idx] = add_flags(lptable3[idx],flags) variant = "INAT_VARIANT" } + if (match(ext, rex2_expr)) + table[idx] = add_flags(table[idx], "INAT_REX2_VARIANT") if (!match(ext, lprefix_expr)){ table[idx] = add_flags(table[idx],flags) }
Ian Rogers
reviewerRe: [PATCH 05/10] x86/insn: Add support for REX2 prefix to the instruction decoder logic
In reply to Adrian HunterQuoted 111 lines · Adrian Hunter
Intel Advanced Performance Extensions (APX) uses a new 2-byte prefix named REX2 to select extended general purpose registers (EGPRs) i.e. r16 to r31.
The REX2 prefix is effectively an extended version of the REX prefix.
REX2 and EVEX are also used with PUSH/POP instructions to provide a Push-Pop Acceleration (PPX) hint. With PPX hints, a CPU will attempt to fast-forward register data between matching PUSH and POP instructions.
REX2 is valid only with opcodes in maps 0 and 1. Similar extension for other maps is provided by the EVEX prefix, covered in a separate patch.
Some opcodes in maps 0 and 1 are reserved under REX2. One of these is used for a new 64-bit absolute direct jump instruction JMPABS.
Refer to the Intel Advanced Performance Extensions (Intel APX) Architecture Specification for details.
Define a code value for the REX2 prefix (
INAT_PFX_REX2), and add attribute flags for opcodes reserved under REX2 (INAT_NO_REX2) and to identify opcodes (only JMPABS) that require a mandatory REX2 prefix (INAT_REX2_VARIANT).Amend logic to read the REX2 prefix and get the opcode attribute for the map number (0 or 1) encoded in the REX2 prefix.
Amend the awk script that generates the attribute tables from the opcode map, to recognise "REX2" as attribute
INAT_PFX_REX2, and "(!REX2)" as attributeINAT_NO_REX2, and "(REX2)" as attributeINAT_REX2_VARIANT.Signed-off-by Adrian Hunter <[email protected]>--- arch/x86/include/asm/inat.h | 11 +++++++++- arch/x86/include/asm/insn.h | 25 ++++++++++++++++++---- arch/x86/lib/insn.c | 25 ++++++++++++++++++++++ arch/x86/tools/gen-insn-attr-x86.awk | 11 +++++++++- tools/arch/x86/include/asm/inat.h | 11 +++++++++- tools/arch/x86/include/asm/insn.h | 25 ++++++++++++++++++---- tools/arch/x86/lib/insn.c | 25 ++++++++++++++++++++++ tools/arch/x86/tools/gen-insn-attr-x86.awk | 11 +++++++++- 8 files changed, 132 insertions(+), 12 deletions(-)arch/x86/include/asm/inat.h +10
-1@@ -35,6 +35,8 @@#define INAT_PFX_VEX2 13/* 2-bytes VEX prefix */ #define INAT_PFX_VEX3 14/* 3-bytes VEX prefix */ #define INAT_PFX_EVEX 15/* EVEX prefix */ +/* x86-64 REX2 prefix */ +#define INAT_PFX_REX2 16/* 0xD5 */ #define INAT_LSTPFX_MAX 3#define INAT_LGCPFX_MAX 11@@ -50,7 +52,7 @@/* Legacy prefix */ #define INAT_PFX_OFFS 0 -#define INAT_PFX_BITS 4 +#define INAT_PFX_BITS 5#define INAT_PFX_MAX ((1 << INAT_PFX_BITS) - 1)#define INAT_PFX_MASK (INAT_PFX_MAX << INAT_PFX_OFFS)/* Escape opcodes */ @@ -77,6 +79,8 @@#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5))#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6))#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7)) +#define INAT_NO_REX2 (1 << (INAT_FLAG_OFFS + 8)) +#define INAT_REX2_VARIANT (1 << (INAT_FLAG_OFFS + 9))/* Attribute making macros for attribute tables */ #define INAT_MAKE_PREFIX (pfx) (pfx << INAT_PFX_OFFS)#define INAT_MAKE_ESCAPE (esc) (esc << INAT_ESC_OFFS)@@ -128,6 +132,11 @@ static inline int inat_is_rex_prefix(insn_attr_t attr)return (attr &INAT_PFX_MASK ) ==INAT_PFX_REX ; } +static inline int inat_is_rex2_prefix (insn_attr_t attr) +{ +return (attr &INAT_PFX_MASK ) ==INAT_PFX_REX2 ; +} +static inline int inat_last_prefix_id (insn_attr_t attr) {if ((attr &INAT_PFX_MASK ) >INAT_LSTPFX_MAX )arch/x86/include/asm/insn.h +9
-4@@ -112,10 +112,15 @@ struct insn {#define X86_SIB_INDEX (sib) (((sib) & 0x38) >> 3)#define X86_SIB_BASE (sib) ((sib) & 0x07) -#define X86_REX_W (rex) ((rex) & 8) -#define X86_REX_R (rex) ((rex) & 4) -#define X86_REX_X (rex) ((rex) & 2) -#define X86_REX_B (rex) ((rex) & 1) +#define X86_REX2_M (rex) ((rex) & 0x80)/* REX2 M0 */ +#define X86_REX2_R (rex) ((rex) & 0x40)/* REX2 R4 */ +#define X86_REX2_X (rex) ((rex) & 0x20)/* REX2 X4 */ +#define X86_REX2_B (rex) ((rex) & 0x10)/* REX2 B4 */ + +#define X86_REX_W (rex) ((rex) & 8)/* REX or REX2 W */ +#define X86_REX_R (rex) ((rex) & 4)/* REX or REX2 R3 */ +#define X86_REX_X (rex) ((rex) & 2)/* REX or REX2 X3 */ +#define X86_REX_B (rex) ((rex) & 1)/* REX or REX2 B3 */ /* VEX bit flags */ #define X86_VEX_W (vex) ((vex) & 0x80)/* VEX3 Byte2 */
arch/x86/include/asm/insn.h static inline void insn_get_attribute(struct insn *insn) · line 173
Quoted 8 lines
arch/x86/include/asm/insn.h +5
-0@@ -161,6 +166,18 @@ static inline void insn_get_attribute(struct insn *insn)/* Instruction uses RIP-relative addressing */ extern int insn_rip_relative (struct insn *insn); +static inline int insn_is_rex2 (struct insn *insn) +{ +if (!insn->prefixes.got) +insn_get_prefixes (insn); +return insn->rex_prefix.nbytes ==2 ;
It'd be nice to capture that a rex2 prefix is by definition 2 bytes. Playing devil's advocate, if there were a REX and a REX2 prefix, couldn't rex_prefix.nbytes be 3? I'm wondering about other prefix combinations that may confuse this logic, maybe someone dreams up doing this for say alignment reasons like "rep ret".
Thanks,
Ian
Quoted 271 lines
arch/x86/include/asm/insn.h +7
-0+} + +static inline insn_byte_t insn_rex2_m_bit (struct insn *insn) +{ +return X86_REX2_M (insn->rex_prefix.bytes[1 ]); +} +static inline int insn_is_avx (struct insn *insn) {if (!insn->prefixes.got)arch/x86/lib/insn.c +25
-0@@ -185,6 +185,17 @@ int insn_get_prefixes(struct insn *insn)if (X86_REX_W (b))/* REX.W overrides opnd_size */ insn->opnd_bytes =8 ; + }else if (inat_is_rex2_prefix (attr)) { +insn_set_byte (&insn->rex_prefix,0 , b); + b =peek_nbyte_next (insn_byte_t, insn,1 ); +insn_set_byte (&insn->rex_prefix,1 , b); + insn->rex_prefix.nbytes =2 ; + insn->next_byte +=2 ; +if (X86_REX_W (b)) +/* REX.W overrides opnd_size */ + insn->opnd_bytes =8 ; + insn->rex_prefix.got =1 ; + goto vex_end; } } insn->rex_prefix.got =1 ;@@ -294,6 +305,20 @@ int insn_get_opcode(struct insn *insn) goto end; } +/* Check if there is REX2 prefix or not */ +if (insn_is_rex2 (insn)) { +if (insn_rex2_m_bit (insn)) { +/* map 1 is escape 0x0f */ +insn_attr_t esc_attr =inat_get_opcode_attribute (0x0f ); + + pfx_id =insn_last_prefix_id (insn); + insn->attr =inat_get_escape_attribute (op, pfx_id, esc_attr); + }else { + insn->attr =inat_get_opcode_attribute (op); + } + goto end; + } + insn->attr =inat_get_opcode_attribute (op);while (inat_is_escape (insn->attr)) {/* Get escaped opcode */ arch/x86/tools/gen-insn-attr-x86.awk +10
-1@@ -64,7 +64,9 @@ BEGIN { modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])" force64_expr = "\\([df]64\\)" - rex_expr = "^REX(\\.[XRWB]+)*" + rex_expr = "^((REX(\\.[XRWB]+)+)|(REX$))" + rex2_expr = "\\(REX2\\)" + no_rex2_expr = "\\(!REX2\\)" fpu_expr = "^ESC" # TODO lprefix1_expr = "\\((66|!F3)\\)"@@ -99,6 +101,7 @@ BEGIN { prefix_num["VEX+1byte"] = "INAT_PFX_VEX2" prefix_num["VEX+2byte"] = "INAT_PFX_VEX3" prefix_num["EVEX"] = "INAT_PFX_EVEX" + prefix_num["REX2"] = "INAT_PFX_REX2" clear_vars() }@@ -314,6 +317,10 @@ function convert_operands(count,opnd, i,j,imm,mod) if (match(ext, force64_expr)) flags = add_flags(flags, "INAT_FORCE64") + # check REX2 not allowed + if (match(ext, no_rex2_expr)) + flags = add_flags(flags, "INAT_NO_REX2") + # check REX prefix if (match(opcode, rex_expr)) flags = add_flags(flags, "INAT_MAKE_PREFIX(INAT_PFX_REX)")@@ -351,6 +358,8 @@ function convert_operands(count,opnd, i,j,imm,mod) lptable3[idx] = add_flags(lptable3[idx],flags) variant = "INAT_VARIANT" } + if (match(ext, rex2_expr)) + table[idx] = add_flags(table[idx], "INAT_REX2_VARIANT") if (!match(ext, lprefix_expr)){ table[idx] = add_flags(table[idx],flags) }tools/arch/x86/include/asm/inat.h +10
-1@@ -35,6 +35,8 @@#define INAT_PFX_VEX2 13/* 2-bytes VEX prefix */ #define INAT_PFX_VEX3 14/* 3-bytes VEX prefix */ #define INAT_PFX_EVEX 15/* EVEX prefix */ +/* x86-64 REX2 prefix */ +#define INAT_PFX_REX2 16/* 0xD5 */ #define INAT_LSTPFX_MAX 3#define INAT_LGCPFX_MAX 11@@ -50,7 +52,7 @@/* Legacy prefix */ #define INAT_PFX_OFFS 0 -#define INAT_PFX_BITS 4 +#define INAT_PFX_BITS 5#define INAT_PFX_MAX ((1 << INAT_PFX_BITS) - 1)#define INAT_PFX_MASK (INAT_PFX_MAX << INAT_PFX_OFFS)/* Escape opcodes */ @@ -77,6 +79,8 @@#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5))#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6))#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7)) +#define INAT_NO_REX2 (1 << (INAT_FLAG_OFFS + 8)) +#define INAT_REX2_VARIANT (1 << (INAT_FLAG_OFFS + 9))/* Attribute making macros for attribute tables */ #define INAT_MAKE_PREFIX (pfx) (pfx << INAT_PFX_OFFS)#define INAT_MAKE_ESCAPE (esc) (esc << INAT_ESC_OFFS)@@ -128,6 +132,11 @@ static inline int inat_is_rex_prefix(insn_attr_t attr)return (attr &INAT_PFX_MASK ) ==INAT_PFX_REX ; } +static inline int inat_is_rex2_prefix (insn_attr_t attr) +{ +return (attr &INAT_PFX_MASK ) ==INAT_PFX_REX2 ; +} +static inline int inat_last_prefix_id (insn_attr_t attr) {if ((attr &INAT_PFX_MASK ) >INAT_LSTPFX_MAX )tools/arch/x86/include/asm/insn.h +21
-4@@ -112,10 +112,15 @@ struct insn {#define X86_SIB_INDEX (sib) (((sib) & 0x38) >> 3)#define X86_SIB_BASE (sib) ((sib) & 0x07) -#define X86_REX_W (rex) ((rex) & 8) -#define X86_REX_R (rex) ((rex) & 4) -#define X86_REX_X (rex) ((rex) & 2) -#define X86_REX_B (rex) ((rex) & 1) +#define X86_REX2_M (rex) ((rex) & 0x80)/* REX2 M0 */ +#define X86_REX2_R (rex) ((rex) & 0x40)/* REX2 R4 */ +#define X86_REX2_X (rex) ((rex) & 0x20)/* REX2 X4 */ +#define X86_REX2_B (rex) ((rex) & 0x10)/* REX2 B4 */ + +#define X86_REX_W (rex) ((rex) & 8)/* REX or REX2 W */ +#define X86_REX_R (rex) ((rex) & 4)/* REX or REX2 R3 */ +#define X86_REX_X (rex) ((rex) & 2)/* REX or REX2 X3 */ +#define X86_REX_B (rex) ((rex) & 1)/* REX or REX2 B3 */ /* VEX bit flags */ #define X86_VEX_W (vex) ((vex) & 0x80)/* VEX3 Byte2 */ @@ -161,6 +166,18 @@ static inline void insn_get_attribute(struct insn *insn)/* Instruction uses RIP-relative addressing */ extern int insn_rip_relative (struct insn *insn); +static inline int insn_is_rex2 (struct insn *insn) +{ +if (!insn->prefixes.got) +insn_get_prefixes (insn); +return insn->rex_prefix.nbytes ==2 ; +} + +static inline insn_byte_t insn_rex2_m_bit (struct insn *insn) +{ +return X86_REX2_M (insn->rex_prefix.bytes[1 ]); +} +static inline int insn_is_avx (struct insn *insn) {if (!insn->prefixes.got)tools/arch/x86/lib/insn.c +25
-0@@ -185,6 +185,17 @@ int insn_get_prefixes(struct insn *insn)if (X86_REX_W (b))/* REX.W overrides opnd_size */ insn->opnd_bytes =8 ; + }else if (inat_is_rex2_prefix (attr)) { +insn_set_byte (&insn->rex_prefix,0 , b); + b =peek_nbyte_next (insn_byte_t, insn,1 ); +insn_set_byte (&insn->rex_prefix,1 , b); + insn->rex_prefix.nbytes =2 ; + insn->next_byte +=2 ; +if (X86_REX_W (b)) +/* REX.W overrides opnd_size */ + insn->opnd_bytes =8 ; + insn->rex_prefix.got =1 ; + goto vex_end; } } insn->rex_prefix.got =1 ;@@ -294,6 +305,20 @@ int insn_get_opcode(struct insn *insn) goto end; } +/* Check if there is REX2 prefix or not */ +if (insn_is_rex2 (insn)) { +if (insn_rex2_m_bit (insn)) { +/* map 1 is escape 0x0f */ +insn_attr_t esc_attr =inat_get_opcode_attribute (0x0f ); + + pfx_id =insn_last_prefix_id (insn); + insn->attr =inat_get_escape_attribute (op, pfx_id, esc_attr); + }else { + insn->attr =inat_get_opcode_attribute (op); + } + goto end; + } + insn->attr =inat_get_opcode_attribute (op);while (inat_is_escape (insn->attr)) {/* Get escaped opcode */ tools/arch/x86/tools/gen-insn-attr-x86.awk +10
-2@@ -64,7 +64,9 @@ BEGIN { modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])" force64_expr = "\\([df]64\\)" - rex_expr = "^REX(\\.[XRWB]+)*" + rex_expr = "^((REX(\\.[XRWB]+)+)|(REX$))" + rex2_expr = "\\(REX2\\)" + no_rex2_expr = "\\(!REX2\\)" fpu_expr = "^ESC" # TODO lprefix1_expr = "\\((66|!F3)\\)"@@ -99,6 +101,7 @@ BEGIN { prefix_num["VEX+1byte"] = "INAT_PFX_VEX2" prefix_num["VEX+2byte"] = "INAT_PFX_VEX3" prefix_num["EVEX"] = "INAT_PFX_EVEX" + prefix_num["REX2"] = "INAT_PFX_REX2" clear_vars() }@@ -314,6 +317,10 @@ function convert_operands(count,opnd, i,j,imm,mod) if (match(ext, force64_expr)) flags = add_flags(flags, "INAT_FORCE64") + # check REX2 not allowed + if (match(ext, no_rex2_expr)) + flags = add_flags(flags, "INAT_NO_REX2") + # check REX prefix if (match(opcode, rex_expr)) flags = add_flags(flags, "INAT_MAKE_PREFIX(INAT_PFX_REX)")@@ -351,6 +358,8 @@ function convert_operands(count,opnd, i,j,imm,mod) lptable3[idx] = add_flags(lptable3[idx],flags) variant = "INAT_VARIANT" } + if (match(ext, rex2_expr)) + table[idx] = add_flags(table[idx], "INAT_REX2_VARIANT") if (!match(ext, lprefix_expr)){ table[idx] = add_flags(table[idx],flags) } --2.34.1
Adrian Hunter
reviewerRe: [PATCH 05/10] x86/insn: Add support for REX2 prefix to the instruction decoder logic
Quoted 115 lines · Ian Rogers
Quoted 114 lines · Adrian Hunter
Intel Advanced Performance Extensions (APX) uses a new 2-byte prefix named REX2 to select extended general purpose registers (EGPRs) i.e. r16 to r31.
The REX2 prefix is effectively an extended version of the REX prefix.
REX2 and EVEX are also used with PUSH/POP instructions to provide a Push-Pop Acceleration (PPX) hint. With PPX hints, a CPU will attempt to fast-forward register data between matching PUSH and POP instructions.
REX2 is valid only with opcodes in maps 0 and 1. Similar extension for other maps is provided by the EVEX prefix, covered in a separate patch.
Some opcodes in maps 0 and 1 are reserved under REX2. One of these is used for a new 64-bit absolute direct jump instruction JMPABS.
Refer to the Intel Advanced Performance Extensions (Intel APX) Architecture Specification for details.
Define a code value for the REX2 prefix (
INAT_PFX_REX2), and add attribute flags for opcodes reserved under REX2 (INAT_NO_REX2) and to identify opcodes (only JMPABS) that require a mandatory REX2 prefix (INAT_REX2_VARIANT).Amend logic to read the REX2 prefix and get the opcode attribute for the map number (0 or 1) encoded in the REX2 prefix.
Amend the awk script that generates the attribute tables from the opcode map, to recognise "REX2" as attribute
INAT_PFX_REX2, and "(!REX2)" as attributeINAT_NO_REX2, and "(REX2)" as attributeINAT_REX2_VARIANT.Signed-off-by Adrian Hunter <[email protected]>--- arch/x86/include/asm/inat.h | 11 +++++++++- arch/x86/include/asm/insn.h | 25 ++++++++++++++++++---- arch/x86/lib/insn.c | 25 ++++++++++++++++++++++ arch/x86/tools/gen-insn-attr-x86.awk | 11 +++++++++- tools/arch/x86/include/asm/inat.h | 11 +++++++++- tools/arch/x86/include/asm/insn.h | 25 ++++++++++++++++++---- tools/arch/x86/lib/insn.c | 25 ++++++++++++++++++++++ tools/arch/x86/tools/gen-insn-attr-x86.awk | 11 +++++++++- 8 files changed, 132 insertions(+), 12 deletions(-)arch/x86/include/asm/inat.h +10
-1@@ -35,6 +35,8 @@#define INAT_PFX_VEX2 13/* 2-bytes VEX prefix */ #define INAT_PFX_VEX3 14/* 3-bytes VEX prefix */ #define INAT_PFX_EVEX 15/* EVEX prefix */ +/* x86-64 REX2 prefix */ +#define INAT_PFX_REX2 16/* 0xD5 */ #define INAT_LSTPFX_MAX 3#define INAT_LGCPFX_MAX 11@@ -50,7 +52,7 @@/* Legacy prefix */ #define INAT_PFX_OFFS 0 -#define INAT_PFX_BITS 4 +#define INAT_PFX_BITS 5#define INAT_PFX_MAX ((1 << INAT_PFX_BITS) - 1)#define INAT_PFX_MASK (INAT_PFX_MAX << INAT_PFX_OFFS)/* Escape opcodes */ @@ -77,6 +79,8 @@#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5))#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6))#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7)) +#define INAT_NO_REX2 (1 << (INAT_FLAG_OFFS + 8)) +#define INAT_REX2_VARIANT (1 << (INAT_FLAG_OFFS + 9))/* Attribute making macros for attribute tables */ #define INAT_MAKE_PREFIX (pfx) (pfx << INAT_PFX_OFFS)#define INAT_MAKE_ESCAPE (esc) (esc << INAT_ESC_OFFS)@@ -128,6 +132,11 @@ static inline int inat_is_rex_prefix(insn_attr_t attr)return (attr &INAT_PFX_MASK ) ==INAT_PFX_REX ; } +static inline int inat_is_rex2_prefix (insn_attr_t attr) +{ +return (attr &INAT_PFX_MASK ) ==INAT_PFX_REX2 ; +} +static inline int inat_last_prefix_id (insn_attr_t attr) {if ((attr &INAT_PFX_MASK ) >INAT_LSTPFX_MAX )arch/x86/include/asm/insn.h +9
-4@@ -112,10 +112,15 @@ struct insn {#define X86_SIB_INDEX (sib) (((sib) & 0x38) >> 3)#define X86_SIB_BASE (sib) ((sib) & 0x07) -#define X86_REX_W (rex) ((rex) & 8) -#define X86_REX_R (rex) ((rex) & 4) -#define X86_REX_X (rex) ((rex) & 2) -#define X86_REX_B (rex) ((rex) & 1) +#define X86_REX2_M (rex) ((rex) & 0x80)/* REX2 M0 */ +#define X86_REX2_R (rex) ((rex) & 0x40)/* REX2 R4 */ +#define X86_REX2_X (rex) ((rex) & 0x20)/* REX2 X4 */ +#define X86_REX2_B (rex) ((rex) & 0x10)/* REX2 B4 */ + +#define X86_REX_W (rex) ((rex) & 8)/* REX or REX2 W */ +#define X86_REX_R (rex) ((rex) & 4)/* REX or REX2 R3 */ +#define X86_REX_X (rex) ((rex) & 2)/* REX or REX2 X3 */ +#define X86_REX_B (rex) ((rex) & 1)/* REX or REX2 B3 */ /* VEX bit flags */ #define X86_VEX_W (vex) ((vex) & 0x80)/* VEX3 Byte2 */ @@ -161,6 +166,18 @@ static inline void insn_get_attribute(struct insn *insn)/* Instruction uses RIP-relative addressing */ extern int insn_rip_relative (struct insn *insn);
Quoted 11 lines
arch/x86/include/asm/insn.h static inline void insn_get_attribute(struct insn *insn) · line 173
Quoted 5 lines
arch/x86/include/asm/insn.h +5
-0+static inline int insn_is_rex2 (struct insn *insn) +{ +if (!insn->prefixes.got) +insn_get_prefixes (insn); +return insn->rex_prefix.nbytes ==2 ;It'd be nice to capture that a rex2 prefix is by definition 2 bytes. Playing devil's advocate, if there were a REX and a REX2 prefix, couldn't rex_prefix.nbytes be 3? I'm wondering about other prefix combinations that may confuse this logic, maybe someone dreams up doing this for say alignment reasons like "rep ret".
REX with REX2 is not allowed.
Adrian Hunter
reviewerPATCH 6/10 x86/insn: x86/insn: Add support for REX2 prefix to the instruction decoder opcode map
In reply to Adrian HunterSupport for REX2 has been added to the instruction decoder logic and the awk script that generates the attribute tables from the opcode map.
Add REX2 prefix byte (0xD5) to the opcode map.
Add annotation (!REX2) for map 0/1 opcodes that are reserved under REX2.
Add JMPABS to the opcode map and add annotation (REX2) to identify that it has a mandatory REX2 prefix. A separate opcode attribute table is not needed at this time because JMPABS has the same attribute encoding as the MOV instruction that it shares an opcode with i.e. INAT_MOFFSET.
--- arch/x86/lib/x86-opcode-map.txt | 148 +++++++++++++------------- tools/arch/x86/lib/x86-opcode-map.txt | 148 +++++++++++++------------- 2 files changed, 152 insertions(+), 144 deletions(-)
arch/x86/lib/x86-opcode-map.txt +76 -72
@@ -33,6 +33,10 @@ # - (F2): the last prefix is 0xF2 # - (!F3) : the last prefix is not 0xF3 (including non-last prefix case) # - (66&F2): Both 0x66 and 0xF2 prefixes are specified. +# +# REX2 Prefix +# - (!REX2): REX2 is not allowed +# - (REX2): REX2 variant e.g. JMPABS Table: one byte opcode Referrer:
@@ -157,22 +161,22 @@ AVXcode: 6e: OUTS/OUTSB DX,Xb 6f: OUTS/OUTSW/OUTSD DX,Xz # 0x70 - 0x7f -70: JO Jb -71: JNO Jb -72: JB/JNAE/JC Jb -73: JNB/JAE/JNC Jb -74: JZ/JE Jb -75: JNZ/JNE Jb -76: JBE/JNA Jb -77: JNBE/JA Jb -78: JS Jb -79: JNS Jb -7a: JP/JPE Jb -7b: JNP/JPO Jb -7c: JL/JNGE Jb -7d: JNL/JGE Jb -7e: JLE/JNG Jb -7f: JNLE/JG Jb +70: JO Jb (!REX2) +71: JNO Jb (!REX2) +72: JB/JNAE/JC Jb (!REX2) +73: JNB/JAE/JNC Jb (!REX2) +74: JZ/JE Jb (!REX2) +75: JNZ/JNE Jb (!REX2) +76: JBE/JNA Jb (!REX2) +77: JNBE/JA Jb (!REX2) +78: JS Jb (!REX2) +79: JNS Jb (!REX2) +7a: JP/JPE Jb (!REX2) +7b: JNP/JPO Jb (!REX2) +7c: JL/JNGE Jb (!REX2) +7d: JNL/JGE Jb (!REX2) +7e: JLE/JNG Jb (!REX2) +7f: JNLE/JG Jb (!REX2) # 0x80 - 0x8f 80: Grp1 Eb,Ib (1A) 81: Grp1 Ev,Iz (1A)
@@ -208,24 +212,24 @@ AVXcode: 9e: SAHF 9f: LAHF # 0xa0 - 0xaf -a0: MOV AL,Ob -a1: MOV rAX,Ov -a2: MOV Ob,AL -a3: MOV Ov,rAX -a4: MOVS/B Yb,Xb -a5: MOVS/W/D/Q Yv,Xv -a6: CMPS/B Xb,Yb -a7: CMPS/W/D Xv,Yv -a8: TEST AL,Ib -a9: TEST rAX,Iz -aa: STOS/B Yb,AL -ab: STOS/W/D/Q Yv,rAX -ac: LODS/B AL,Xb -ad: LODS/W/D/Q rAX,Xv -ae: SCAS/B AL,Yb +a0: MOV AL,Ob (!REX2) +a1: MOV rAX,Ov (!REX2) | JMPABS O (REX2),(o64) +a2: MOV Ob,AL (!REX2) +a3: MOV Ov,rAX (!REX2) +a4: MOVS/B Yb,Xb (!REX2) +a5: MOVS/W/D/Q Yv,Xv (!REX2) +a6: CMPS/B Xb,Yb (!REX2) +a7: CMPS/W/D Xv,Yv (!REX2) +a8: TEST AL,Ib (!REX2) +a9: TEST rAX,Iz (!REX2) +aa: STOS/B Yb,AL (!REX2) +ab: STOS/W/D/Q Yv,rAX (!REX2) +ac: LODS/B AL,Xb (!REX2) +ad: LODS/W/D/Q rAX,Xv (!REX2) +ae: SCAS/B AL,Yb (!REX2) # Note: The May 2011 Intel manual shows Xv for the second parameter of the # next instruction but Yv is correct -af: SCAS/W/D/Q rAX,Yv +af: SCAS/W/D/Q rAX,Yv (!REX2) # 0xb0 - 0xbf b0: MOV AL/R8L,Ib b1: MOV CL/R9L,Ib
@@ -266,7 +270,7 @@ d1: Grp2 Ev,1 (1A) d2: Grp2 Eb,CL (1A) d3: Grp2 Ev,CL (1A) d4: AAM Ib (i64) -d5: AAD Ib (i64) +d5: AAD Ib (i64) | REX2 (Prefix),(o64) d6: d7: XLAT/XLATB d8: ESC
@@ -281,26 +285,26 @@ df: ESC # Note: "forced64" is Intel CPU behavior: they ignore 0x66 prefix # in 64-bit mode. AMD CPUs accept 0x66 prefix, it causes RIP truncation # to 16 bits. In 32-bit mode, 0x66 is accepted by both Intel and AMD. -e0: LOOPNE/LOOPNZ Jb (f64) -e1: LOOPE/LOOPZ Jb (f64) -e2: LOOP Jb (f64) -e3: JrCXZ Jb (f64) -e4: IN AL,Ib -e5: IN eAX,Ib -e6: OUT Ib,AL -e7: OUT Ib,eAX +e0: LOOPNE/LOOPNZ Jb (f64) (!REX2) +e1: LOOPE/LOOPZ Jb (f64) (!REX2) +e2: LOOP Jb (f64) (!REX2) +e3: JrCXZ Jb (f64) (!REX2) +e4: IN AL,Ib (!REX2) +e5: IN eAX,Ib (!REX2) +e6: OUT Ib,AL (!REX2) +e7: OUT Ib,eAX (!REX2) # With 0x66 prefix in 64-bit mode, for AMD CPUs immediate offset # in "near" jumps and calls is 16-bit. For CALL, # push of return address is 16-bit wide, RSP is decremented by 2 # but is not truncated to 16 bits, unlike RIP. -e8: CALL Jz (f64) -e9: JMP-near Jz (f64) -ea: JMP-far Ap (i64) -eb: JMP-short Jb (f64) -ec: IN AL,DX -ed: IN eAX,DX -ee: OUT DX,AL -ef: OUT DX,eAX +e8: CALL Jz (f64) (!REX2) +e9: JMP-near Jz (f64) (!REX2) +ea: JMP-far Ap (i64) (!REX2) +eb: JMP-short Jb (f64) (!REX2) +ec: IN AL,DX (!REX2) +ed: IN eAX,DX (!REX2) +ee: OUT DX,AL (!REX2) +ef: OUT DX,eAX (!REX2) # 0xf0 - 0xff f0: LOCK (Prefix) f1:
@@ -386,14 +390,14 @@ AVXcode: 1 2e: vucomiss Vss,Wss (v1) | vucomisd Vsd,Wsd (66),(v1) 2f: vcomiss Vss,Wss (v1) | vcomisd Vsd,Wsd (66),(v1) # 0x0f 0x30-0x3f -30: WRMSR -31: RDTSC -32: RDMSR -33: RDPMC -34: SYSENTER -35: SYSEXIT +30: WRMSR (!REX2) +31: RDTSC (!REX2) +32: RDMSR (!REX2) +33: RDPMC (!REX2) +34: SYSENTER (!REX2) +35: SYSEXIT (!REX2) 36: -37: GETSEC +37: GETSEC (!REX2) 38: escape # 3-byte escape 1 39: 3a: escape # 3-byte escape 2
@@ -473,22 +477,22 @@ AVXcode: 1 7f: movq Qq,Pq | vmovdqa Wx,Vx (66) | vmovdqa32/64 Wx,Vx (66),(evo) | vmovdqu Wx,Vx (F3) | vmovdqu32/64 Wx,Vx (F3),(evo) | vmovdqu8/16 Wx,Vx (F2),(ev) # 0x0f 0x80-0x8f # Note: "forced64" is Intel CPU behavior (see comment about CALL insn). -80: JO Jz (f64) -81: JNO Jz (f64) -82: JB/JC/JNAE Jz (f64) -83: JAE/JNB/JNC Jz (f64) -84: JE/JZ Jz (f64) -85: JNE/JNZ Jz (f64) -86: JBE/JNA Jz (f64) -87: JA/JNBE Jz (f64) -88: JS Jz (f64) -89: JNS Jz (f64) -8a: JP/JPE Jz (f64) -8b: JNP/JPO Jz (f64) -8c: JL/JNGE Jz (f64) -8d: JNL/JGE Jz (f64) -8e: JLE/JNG Jz (f64) -8f: JNLE/JG Jz (f64) +80: JO Jz (f64) (!REX2) +81: JNO Jz (f64) (!REX2) +82: JB/JC/JNAE Jz (f64) (!REX2) +83: JAE/JNB/JNC Jz (f64) (!REX2) +84: JE/JZ Jz (f64) (!REX2) +85: JNE/JNZ Jz (f64) (!REX2) +86: JBE/JNA Jz (f64) (!REX2) +87: JA/JNBE Jz (f64) (!REX2) +88: JS Jz (f64) (!REX2) +89: JNS Jz (f64) (!REX2) +8a: JP/JPE Jz (f64) (!REX2) +8b: JNP/JPO Jz (f64) (!REX2) +8c: JL/JNGE Jz (f64) (!REX2) +8d: JNL/JGE Jz (f64) (!REX2) +8e: JLE/JNG Jz (f64) (!REX2) +8f: JNLE/JG Jz (f64) (!REX2) # 0x0f 0x90-0x9f 90: SETO Eb | kmovw/q Vk,Wk | kmovb/d Vk,Wk (66) 91: SETNO Eb | kmovw/q Mv,Vk | kmovb/d Mv,Vk (66)
tools/arch/x86/lib/x86-opcode-map.txt +76 -72
197 lines not on this page · raw message
Signature · 1 line
2.34.1
[tip: perf/core] x86/insn: x86/insn: Add support for REX2 prefix to the instruction decoder opcode map
The following commit has been merged into the perf/core branch of tip:
The following commit has been merged into the perf/core branch of tip:
Commit-ID: 159039af8c074a14545fd695c38d2772b3c98b12 Gitweb: https://git.kernel.org/tip/159039af8c074a14545fd695c38d2772b3c98b12 Author: Adrian Hunter <[email protected]> AuthorDate: Thu, 02 May 2024 13:58:49 +03:00 Committer: Ingo Molnar <[email protected]> CommitterDate: Thu, 02 May 2024 13:13:44 +02:00
x86/insn: x86/insn: Add support for REX2 prefix to the instruction decoder opcode map
Support for REX2 has been added to the instruction decoder logic and the awk script that generates the attribute tables from the opcode map.
Add REX2 prefix byte (0xD5) to the opcode map.
Add annotation (!REX2) for map 0/1 opcodes that are reserved under REX2.
Add JMPABS to the opcode map and add annotation (REX2) to identify that it has a mandatory REX2 prefix. A separate opcode attribute table is not needed at this time because JMPABS has the same attribute encoding as the MOV instruction that it shares an opcode with i.e. INAT_MOFFSET.
--- arch/x86/lib/x86-opcode-map.txt | 148 ++++++++++++------------- tools/arch/x86/lib/x86-opcode-map.txt | 148 ++++++++++++------------- 2 files changed, 152 insertions(+), 144 deletions(-)
arch/x86/lib/x86-opcode-map.txt +76 -72
@@ -33,6 +33,10 @@ # - (F2): the last prefix is 0xF2 # - (!F3) : the last prefix is not 0xF3 (including non-last prefix case) # - (66&F2): Both 0x66 and 0xF2 prefixes are specified. +# +# REX2 Prefix +# - (!REX2): REX2 is not allowed +# - (REX2): REX2 variant e.g. JMPABS Table: one byte opcode Referrer:
@@ -157,22 +161,22 @@ AVXcode: 6e: OUTS/OUTSB DX,Xb 6f: OUTS/OUTSW/OUTSD DX,Xz # 0x70 - 0x7f -70: JO Jb -71: JNO Jb -72: JB/JNAE/JC Jb -73: JNB/JAE/JNC Jb -74: JZ/JE Jb -75: JNZ/JNE Jb -76: JBE/JNA Jb -77: JNBE/JA Jb -78: JS Jb -79: JNS Jb -7a: JP/JPE Jb -7b: JNP/JPO Jb -7c: JL/JNGE Jb -7d: JNL/JGE Jb -7e: JLE/JNG Jb -7f: JNLE/JG Jb +70: JO Jb (!REX2) +71: JNO Jb (!REX2) +72: JB/JNAE/JC Jb (!REX2) +73: JNB/JAE/JNC Jb (!REX2) +74: JZ/JE Jb (!REX2) +75: JNZ/JNE Jb (!REX2) +76: JBE/JNA Jb (!REX2) +77: JNBE/JA Jb (!REX2) +78: JS Jb (!REX2) +79: JNS Jb (!REX2) +7a: JP/JPE Jb (!REX2) +7b: JNP/JPO Jb (!REX2) +7c: JL/JNGE Jb (!REX2) +7d: JNL/JGE Jb (!REX2) +7e: JLE/JNG Jb (!REX2) +7f: JNLE/JG Jb (!REX2) # 0x80 - 0x8f 80: Grp1 Eb,Ib (1A) 81: Grp1 Ev,Iz (1A)
@@ -208,24 +212,24 @@ AVXcode: 9e: SAHF 9f: LAHF # 0xa0 - 0xaf -a0: MOV AL,Ob -a1: MOV rAX,Ov -a2: MOV Ob,AL -a3: MOV Ov,rAX -a4: MOVS/B Yb,Xb -a5: MOVS/W/D/Q Yv,Xv -a6: CMPS/B Xb,Yb -a7: CMPS/W/D Xv,Yv -a8: TEST AL,Ib -a9: TEST rAX,Iz -aa: STOS/B Yb,AL -ab: STOS/W/D/Q Yv,rAX -ac: LODS/B AL,Xb -ad: LODS/W/D/Q rAX,Xv -ae: SCAS/B AL,Yb +a0: MOV AL,Ob (!REX2) +a1: MOV rAX,Ov (!REX2) | JMPABS O (REX2),(o64) +a2: MOV Ob,AL (!REX2) +a3: MOV Ov,rAX (!REX2) +a4: MOVS/B Yb,Xb (!REX2) +a5: MOVS/W/D/Q Yv,Xv (!REX2) +a6: CMPS/B Xb,Yb (!REX2) +a7: CMPS/W/D Xv,Yv (!REX2) +a8: TEST AL,Ib (!REX2) +a9: TEST rAX,Iz (!REX2) +aa: STOS/B Yb,AL (!REX2) +ab: STOS/W/D/Q Yv,rAX (!REX2) +ac: LODS/B AL,Xb (!REX2) +ad: LODS/W/D/Q rAX,Xv (!REX2) +ae: SCAS/B AL,Yb (!REX2) # Note: The May 2011 Intel manual shows Xv for the second parameter of the # next instruction but Yv is correct -af: SCAS/W/D/Q rAX,Yv +af: SCAS/W/D/Q rAX,Yv (!REX2) # 0xb0 - 0xbf b0: MOV AL/R8L,Ib b1: MOV CL/R9L,Ib
@@ -266,7 +270,7 @@ d1: Grp2 Ev,1 (1A) d2: Grp2 Eb,CL (1A) d3: Grp2 Ev,CL (1A) d4: AAM Ib (i64) -d5: AAD Ib (i64) +d5: AAD Ib (i64) | REX2 (Prefix),(o64) d6: d7: XLAT/XLATB d8: ESC
@@ -281,26 +285,26 @@ df: ESC # Note: "forced64" is Intel CPU behavior: they ignore 0x66 prefix # in 64-bit mode. AMD CPUs accept 0x66 prefix, it causes RIP truncation # to 16 bits. In 32-bit mode, 0x66 is accepted by both Intel and AMD. -e0: LOOPNE/LOOPNZ Jb (f64) -e1: LOOPE/LOOPZ Jb (f64) -e2: LOOP Jb (f64) -e3: JrCXZ Jb (f64) -e4: IN AL,Ib -e5: IN eAX,Ib -e6: OUT Ib,AL -e7: OUT Ib,eAX +e0: LOOPNE/LOOPNZ Jb (f64) (!REX2) +e1: LOOPE/LOOPZ Jb (f64) (!REX2) +e2: LOOP Jb (f64) (!REX2) +e3: JrCXZ Jb (f64) (!REX2) +e4: IN AL,Ib (!REX2) +e5: IN eAX,Ib (!REX2) +e6: OUT Ib,AL (!REX2) +e7: OUT Ib,eAX (!REX2) # With 0x66 prefix in 64-bit mode, for AMD CPUs immediate offset # in "near" jumps and calls is 16-bit. For CALL, # push of return address is 16-bit wide, RSP is decremented by 2 # but is not truncated to 16 bits, unlike RIP. -e8: CALL Jz (f64) -e9: JMP-near Jz (f64) -ea: JMP-far Ap (i64) -eb: JMP-short Jb (f64) -ec: IN AL,DX -ed: IN eAX,DX -ee: OUT DX,AL -ef: OUT DX,eAX +e8: CALL Jz (f64) (!REX2) +e9: JMP-near Jz (f64) (!REX2) +ea: JMP-far Ap (i64) (!REX2) +eb: JMP-short Jb (f64) (!REX2) +ec: IN AL,DX (!REX2) +ed: IN eAX,DX (!REX2) +ee: OUT DX,AL (!REX2) +ef: OUT DX,eAX (!REX2) # 0xf0 - 0xff f0: LOCK (Prefix) f1:
@@ -386,14 +390,14 @@ AVXcode: 1 2e: vucomiss Vss,Wss (v1) | vucomisd Vsd,Wsd (66),(v1) 2f: vcomiss Vss,Wss (v1) | vcomisd Vsd,Wsd (66),(v1) # 0x0f 0x30-0x3f -30: WRMSR -31: RDTSC -32: RDMSR -33: RDPMC -34: SYSENTER -35: SYSEXIT +30: WRMSR (!REX2) +31: RDTSC (!REX2) +32: RDMSR (!REX2) +33: RDPMC (!REX2) +34: SYSENTER (!REX2) +35: SYSEXIT (!REX2) 36: -37: GETSEC +37: GETSEC (!REX2) 38: escape # 3-byte escape 1 39: 3a: escape # 3-byte escape 2
@@ -473,22 +477,22 @@ AVXcode: 1 7f: movq Qq,Pq | vmovdqa Wx,Vx (66) | vmovdqa32/64 Wx,Vx (66),(evo) | vmovdqu Wx,Vx (F3) | vmovdqu32/64 Wx,Vx (F3),(evo) | vmovdqu8/16 Wx,Vx (F2),(ev) # 0x0f 0x80-0x8f # Note: "forced64" is Intel CPU behavior (see comment about CALL insn). -80: JO Jz (f64) -81: JNO Jz (f64) -82: JB/JC/JNAE Jz (f64) -83: JAE/JNB/JNC Jz (f64) -84: JE/JZ Jz (f64) -85: JNE/JNZ Jz (f64) -86: JBE/JNA Jz (f64) -87: JA/JNBE Jz (f64) -88: JS Jz (f64) -89: JNS Jz (f64) -8a: JP/JPE Jz (f64) -8b: JNP/JPO Jz (f64) -8c: JL/JNGE Jz (f64) -8d: JNL/JGE Jz (f64) -8e: JLE/JNG Jz (f64) -8f: JNLE/JG Jz (f64) +80: JO Jz (f64) (!REX2) +81: JNO Jz (f64) (!REX2) +82: JB/JC/JNAE Jz (f64) (!REX2) +83: JAE/JNB/JNC Jz (f64) (!REX2) +84: JE/JZ Jz (f64) (!REX2) +85: JNE/JNZ Jz (f64) (!REX2) +86: JBE/JNA Jz (f64) (!REX2) +87: JA/JNBE Jz (f64) (!REX2) +88: JS Jz (f64) (!REX2) +89: JNS Jz (f64) (!REX2) +8a: JP/JPE Jz (f64) (!REX2) +8b: JNP/JPO Jz (f64) (!REX2) +8c: JL/JNGE Jz (f64) (!REX2) +8d: JNL/JGE Jz (f64) (!REX2) +8e: JLE/JNG Jz (f64) (!REX2) +8f: JNLE/JG Jz (f64) (!REX2) # 0x0f 0x90-0x9f 90: SETO Eb | kmovw/q Vk,Wk | kmovb/d Vk,Wk (66) 91: SETNO Eb | kmovw/q Mv,Vk | kmovb/d Mv,Vk (66)
tools/arch/x86/lib/x86-opcode-map.txt +76 -72
197 lines not on this page · raw message
Adrian Hunter
reviewerPATCH 7/10 x86/insn: Add support for APX EVEX to the instruction decoder logic
In reply to Adrian HunterIntel Advanced Performance Extensions (APX) extends the EVEX prefix to support:
- extended general purpose registers (EGPRs) i.e. r16 to r31
- Push-Pop Acceleration (PPX) hints
- new data destination (NDD) register
- suppress status flags writes (NF) of common instructions
- new instructions
Refer to the Intel Advanced Performance Extensions (Intel APX) Architecture Specification for details.
The extended EVEX prefix does not need amended instruction decoder logic, except in one area. Some instructions are defined as SCALABLE which means the EVEX.W bit and EVEX.pp bits are used to determine operand size. Specifically, if an instruction is SCALABLE and EVEX.W is zero, then EVEX.pp value 0 (representing no prefix NP) means default operand size, whereas EVEX.pp value 1 (representing 66 prefix) means operand size override i.e. 16 bits
Add an attribute (INAT_EVEX_SCALABLE) to identify such instructions, and amend the logic appropriately.
Amend the awk script that generates the attribute tables from the opcode map, to recognise "(es)" as attribute INAT_EVEX_SCALABLE.
--- arch/x86/include/asm/inat.h | 6 ++++++ arch/x86/include/asm/insn.h | 7 +++++++ arch/x86/lib/insn.c | 4 ++++ arch/x86/tools/gen-insn-attr-x86.awk | 4 ++++ tools/arch/x86/include/asm/inat.h | 6 ++++++ tools/arch/x86/include/asm/insn.h | 7 +++++++ tools/arch/x86/lib/insn.c | 4 ++++ tools/arch/x86/tools/gen-insn-attr-x86.awk | 4 ++++ 8 files changed, 42 insertions(+)
arch/x86/include/asm/inat.h +6 -0
@@ -81,6 +81,7 @@#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7))#define INAT_NO_REX2 (1 << (INAT_FLAG_OFFS + 8))#define INAT_REX2_VARIANT (1 << (INAT_FLAG_OFFS + 9)) +#define INAT_EVEX_SCALABLE (1 << (INAT_FLAG_OFFS + 10))/* Attribute making macros for attribute tables */ #define INAT_MAKE_PREFIX (pfx) (pfx << INAT_PFX_OFFS)#define INAT_MAKE_ESCAPE (esc) (esc << INAT_ESC_OFFS)
@@ -236,4 +237,9 @@ static inline int inat_must_evex(insn_attr_t attr) {return attr &INAT_EVEXONLY ; } + +static inline int inat_evex_scalable (insn_attr_t attr) +{ +return attr &INAT_EVEX_SCALABLE ; +}#endif
arch/x86/include/asm/insn.h +7 -0
@@ -215,6 +215,13 @@ static inline insn_byte_t insn_vex_p_bits(struct insn *insn)return X86_VEX_P (insn->vex_prefix.bytes[2 ]); } +static inline insn_byte_t insn_vex_w_bit (struct insn *insn) +{ +if (insn->vex_prefix.nbytes <3 ) +return 0 ; +return X86_VEX_W (insn->vex_prefix.bytes[2 ]); +} +/* Get the last prefix id from last prefix or VEX prefix */ static inline int insn_last_prefix_id (struct insn *insn) {
arch/x86/lib/insn.c +4 -0
@@ -294,6 +294,10 @@ int insn_get_opcode(struct insn *insn) m =insn_vex_m_bits (insn); p =insn_vex_p_bits (insn); insn->attr =inat_get_avx_attribute (op, m, p); +/* SCALABLE EVEX uses p bits to encode operand size */ +if (inat_evex_scalable (insn->attr) && !insn_vex_w_bit (insn) && + p ==INAT_PFX_OPNDSZ ) + insn->opnd_bytes =2 ;if ((inat_must_evex (insn->attr) && !insn_is_evex (insn)) || (!inat_accept_vex (insn->attr) && !inat_is_group (insn->attr))) {
arch/x86/tools/gen-insn-attr-x86.awk +4 -0
@@ -83,6 +83,8 @@ BEGIN { vexonly_expr = "\\(v\\)" # All opcodes with (ev) superscript supports *only* EVEX prefix evexonly_expr = "\\(ev\\)" + # (es) is the same as (ev) but also "SCALABLE" i.e. W and pp determine operand size + evex_scalable_expr = "\\(es\\)" prefix_expr = "\\(Prefix\\)" prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ"
@@ -332,6 +334,8 @@ function convert_operands(count,opnd, i,j,imm,mod) # check VEX codes if (match(ext, evexonly_expr)) flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY") + else if (match(ext, evex_scalable_expr)) + flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY | INAT_EVEX_SCALABLE") else if (match(ext, vexonly_expr)) flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY") else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr))
tools/arch/x86/include/asm/inat.h +6 -0
@@ -81,6 +81,7 @@#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7))#define INAT_NO_REX2 (1 << (INAT_FLAG_OFFS + 8))#define INAT_REX2_VARIANT (1 << (INAT_FLAG_OFFS + 9)) +#define INAT_EVEX_SCALABLE (1 << (INAT_FLAG_OFFS + 10))/* Attribute making macros for attribute tables */ #define INAT_MAKE_PREFIX (pfx) (pfx << INAT_PFX_OFFS)#define INAT_MAKE_ESCAPE (esc) (esc << INAT_ESC_OFFS)
@@ -236,4 +237,9 @@ static inline int inat_must_evex(insn_attr_t attr) {return attr &INAT_EVEXONLY ; } + +static inline int inat_evex_scalable (insn_attr_t attr) +{ +return attr &INAT_EVEX_SCALABLE ; +}#endif
tools/arch/x86/include/asm/insn.h +7 -0
@@ -215,6 +215,13 @@ static inline insn_byte_t insn_vex_p_bits(struct insn *insn)return X86_VEX_P (insn->vex_prefix.bytes[2 ]); } +static inline insn_byte_t insn_vex_w_bit (struct insn *insn) +{ +if (insn->vex_prefix.nbytes <3 ) +return 0 ; +return X86_VEX_W (insn->vex_prefix.bytes[2 ]); +} +/* Get the last prefix id from last prefix or VEX prefix */ static inline int insn_last_prefix_id (struct insn *insn) {
tools/arch/x86/lib/insn.c +4 -0
@@ -294,6 +294,10 @@ int insn_get_opcode(struct insn *insn) m =insn_vex_m_bits (insn); p =insn_vex_p_bits (insn); insn->attr =inat_get_avx_attribute (op, m, p); +/* SCALABLE EVEX uses p bits to encode operand size */ +if (inat_evex_scalable (insn->attr) && !insn_vex_w_bit (insn) && + p ==INAT_PFX_OPNDSZ ) + insn->opnd_bytes =2 ;if ((inat_must_evex (insn->attr) && !insn_is_evex (insn)) || (!inat_accept_vex (insn->attr) && !inat_is_group (insn->attr))) {
tools/arch/x86/tools/gen-insn-attr-x86.awk +4 -0
@@ -83,6 +83,8 @@ BEGIN { vexonly_expr = "\\(v\\)" # All opcodes with (ev) superscript supports *only* EVEX prefix evexonly_expr = "\\(ev\\)" + # (es) is the same as (ev) but also "SCALABLE" i.e. W and pp determine operand size + evex_scalable_expr = "\\(es\\)" prefix_expr = "\\(Prefix\\)" prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ"
@@ -332,6 +334,8 @@ function convert_operands(count,opnd, i,j,imm,mod) # check VEX codes if (match(ext, evexonly_expr)) flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY") + else if (match(ext, evex_scalable_expr)) + flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY | INAT_EVEX_SCALABLE") else if (match(ext, vexonly_expr)) flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY") else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr))
Signature · 1 line
2.34.1
[tip: perf/core] x86/insn: Add support for APX EVEX to the instruction decoder logic
The following commit has been merged into the perf/core branch of tip:
The following commit has been merged into the perf/core branch of tip:
Commit-ID: 87bbaf1a4be4904fcf04a024e7c1d9f9d1fa945b Gitweb: https://git.kernel.org/tip/87bbaf1a4be4904fcf04a024e7c1d9f9d1fa945b Author: Adrian Hunter <[email protected]> AuthorDate: Thu, 02 May 2024 13:58:50 +03:00 Committer: Ingo Molnar <[email protected]> CommitterDate: Thu, 02 May 2024 13:13:45 +02:00
x86/insn: Add support for APX EVEX to the instruction decoder logic
Intel Advanced Performance Extensions (APX) extends the EVEX prefix to support:
- extended general purpose registers (EGPRs) i.e. r16 to r31
- Push-Pop Acceleration (PPX) hints
- new data destination (NDD) register
- suppress status flags writes (NF) of common instructions
- new instructions
Refer to the Intel Advanced Performance Extensions (Intel APX) Architecture Specification for details.
The extended EVEX prefix does not need amended instruction decoder logic, except in one area. Some instructions are defined as SCALABLE which means the EVEX.W bit and EVEX.pp bits are used to determine operand size. Specifically, if an instruction is SCALABLE and EVEX.W is zero, then EVEX.pp value 0 (representing no prefix NP) means default operand size, whereas EVEX.pp value 1 (representing 66 prefix) means operand size override i.e. 16 bits
Add an attribute (INAT_EVEX_SCALABLE) to identify such instructions, and amend the logic appropriately.
Amend the awk script that generates the attribute tables from the opcode map, to recognise "(es)" as attribute INAT_EVEX_SCALABLE.
--- arch/x86/include/asm/inat.h | 6 ++++++ arch/x86/include/asm/insn.h | 7 +++++++ arch/x86/lib/insn.c | 4 ++++ arch/x86/tools/gen-insn-attr-x86.awk | 4 ++++ tools/arch/x86/include/asm/inat.h | 6 ++++++ tools/arch/x86/include/asm/insn.h | 7 +++++++ tools/arch/x86/lib/insn.c | 4 ++++ tools/arch/x86/tools/gen-insn-attr-x86.awk | 4 ++++ 8 files changed, 42 insertions(+)
arch/x86/include/asm/inat.h +6 -0
@@ -81,6 +81,7 @@#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7))#define INAT_NO_REX2 (1 << (INAT_FLAG_OFFS + 8))#define INAT_REX2_VARIANT (1 << (INAT_FLAG_OFFS + 9)) +#define INAT_EVEX_SCALABLE (1 << (INAT_FLAG_OFFS + 10))/* Attribute making macros for attribute tables */ #define INAT_MAKE_PREFIX (pfx) (pfx << INAT_PFX_OFFS)#define INAT_MAKE_ESCAPE (esc) (esc << INAT_ESC_OFFS)
@@ -236,4 +237,9 @@ static inline int inat_must_evex(insn_attr_t attr) {return attr &INAT_EVEXONLY ; } + +static inline int inat_evex_scalable (insn_attr_t attr) +{ +return attr &INAT_EVEX_SCALABLE ; +}#endif
arch/x86/include/asm/insn.h +7 -0
@@ -215,6 +215,13 @@ static inline insn_byte_t insn_vex_p_bits(struct insn *insn)return X86_VEX_P (insn->vex_prefix.bytes[2 ]); } +static inline insn_byte_t insn_vex_w_bit (struct insn *insn) +{ +if (insn->vex_prefix.nbytes <3 ) +return 0 ; +return X86_VEX_W (insn->vex_prefix.bytes[2 ]); +} +/* Get the last prefix id from last prefix or VEX prefix */ static inline int insn_last_prefix_id (struct insn *insn) {
arch/x86/lib/insn.c +4 -0
@@ -294,6 +294,10 @@ int insn_get_opcode(struct insn *insn) m =insn_vex_m_bits (insn); p =insn_vex_p_bits (insn); insn->attr =inat_get_avx_attribute (op, m, p); +/* SCALABLE EVEX uses p bits to encode operand size */ +if (inat_evex_scalable (insn->attr) && !insn_vex_w_bit (insn) && + p ==INAT_PFX_OPNDSZ ) + insn->opnd_bytes =2 ;if ((inat_must_evex (insn->attr) && !insn_is_evex (insn)) || (!inat_accept_vex (insn->attr) && !inat_is_group (insn->attr))) {
arch/x86/tools/gen-insn-attr-x86.awk +4 -0
@@ -83,6 +83,8 @@ BEGIN { vexonly_expr = "\\(v\\)" # All opcodes with (ev) superscript supports *only* EVEX prefix evexonly_expr = "\\(ev\\)" + # (es) is the same as (ev) but also "SCALABLE" i.e. W and pp determine operand size + evex_scalable_expr = "\\(es\\)" prefix_expr = "\\(Prefix\\)" prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ"
@@ -332,6 +334,8 @@ function convert_operands(count,opnd, i,j,imm,mod) # check VEX codes if (match(ext, evexonly_expr)) flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY") + else if (match(ext, evex_scalable_expr)) + flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY | INAT_EVEX_SCALABLE") else if (match(ext, vexonly_expr)) flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY") else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr))
tools/arch/x86/include/asm/inat.h +6 -0
@@ -81,6 +81,7 @@#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7))#define INAT_NO_REX2 (1 << (INAT_FLAG_OFFS + 8))#define INAT_REX2_VARIANT (1 << (INAT_FLAG_OFFS + 9)) +#define INAT_EVEX_SCALABLE (1 << (INAT_FLAG_OFFS + 10))/* Attribute making macros for attribute tables */ #define INAT_MAKE_PREFIX (pfx) (pfx << INAT_PFX_OFFS)#define INAT_MAKE_ESCAPE (esc) (esc << INAT_ESC_OFFS)
@@ -236,4 +237,9 @@ static inline int inat_must_evex(insn_attr_t attr) {return attr &INAT_EVEXONLY ; } + +static inline int inat_evex_scalable (insn_attr_t attr) +{ +return attr &INAT_EVEX_SCALABLE ; +}#endif
tools/arch/x86/include/asm/insn.h +7 -0
@@ -215,6 +215,13 @@ static inline insn_byte_t insn_vex_p_bits(struct insn *insn)return X86_VEX_P (insn->vex_prefix.bytes[2 ]); } +static inline insn_byte_t insn_vex_w_bit (struct insn *insn) +{ +if (insn->vex_prefix.nbytes <3 ) +return 0 ; +return X86_VEX_W (insn->vex_prefix.bytes[2 ]); +} +/* Get the last prefix id from last prefix or VEX prefix */ static inline int insn_last_prefix_id (struct insn *insn) {
tools/arch/x86/lib/insn.c +4 -0
@@ -294,6 +294,10 @@ int insn_get_opcode(struct insn *insn) m =insn_vex_m_bits (insn); p =insn_vex_p_bits (insn); insn->attr =inat_get_avx_attribute (op, m, p); +/* SCALABLE EVEX uses p bits to encode operand size */ +if (inat_evex_scalable (insn->attr) && !insn_vex_w_bit (insn) && + p ==INAT_PFX_OPNDSZ ) + insn->opnd_bytes =2 ;if ((inat_must_evex (insn->attr) && !insn_is_evex (insn)) || (!inat_accept_vex (insn->attr) && !inat_is_group (insn->attr))) {
tools/arch/x86/tools/gen-insn-attr-x86.awk +4 -0
@@ -83,6 +83,8 @@ BEGIN { vexonly_expr = "\\(v\\)" # All opcodes with (ev) superscript supports *only* EVEX prefix evexonly_expr = "\\(ev\\)" + # (es) is the same as (ev) but also "SCALABLE" i.e. W and pp determine operand size + evex_scalable_expr = "\\(es\\)" prefix_expr = "\\(Prefix\\)" prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ"
@@ -332,6 +334,8 @@ function convert_operands(count,opnd, i,j,imm,mod) # check VEX codes if (match(ext, evexonly_expr)) flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY") + else if (match(ext, evex_scalable_expr)) + flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY | INAT_EVEX_SCALABLE") else if (match(ext, vexonly_expr)) flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY") else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr))
Adrian Hunter
reviewerPATCH 8/10 x86/insn: Add support for APX EVEX instructions to the opcode map
In reply to Adrian HunterTo support APX functionality, the EVEX prefix is used to:
- promote legacy instructions
- promote VEX instructions
- add new instructions
Promoted VEX instructions require no extra annotation because the opcodes do not change and the permissive nature of the instruction decoder already allows them to have an EVEX prefix.
Promoted legacy instructions and new instructions are placed in map 4 which has not been used before.
Create a new table for map 4 and add APX instructions.
Annotate SCALABLE instructions with "(es)" - refer to patch "x86/insn: Add support for APX EVEX to the instruction decoder logic". SCALABLE instructions must be represented in both no-prefix (NP) and 66 prefix forms.
--- arch/x86/lib/x86-opcode-map.txt | 93 +++++++++++++++++++++++++++ tools/arch/x86/lib/x86-opcode-map.txt | 93 +++++++++++++++++++++++++++ 2 files changed, 186 insertions(+)
arch/x86/lib/x86-opcode-map.txt +93 -0
@@ -23,6 +23,7 @@ # # AVX Superscripts # (ev): this opcode requires EVEX prefix. +# (es): this opcode requires EVEX prefix and is SCALABALE. # (evo): this opcode is changed by EVEX prefix (EVEX opcode) # (v): this opcode requires VEX prefix. # (v1): this opcode only supports 128bit VEX.
@@ -929,6 +930,98 @@ df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1) f0: RORX Gy,Ey,Ib (F2),(v) | HRESET Gv,Ib (F3),(000),(11B) EndTable +Table: EVEX map 4 +Referrer: +AVXcode: 4 +00: ADD Eb,Gb (ev) +01: ADD Ev,Gv (es) | ADD Ev,Gv (66),(es) +02: ADD Gb,Eb (ev) +03: ADD Gv,Ev (es) | ADD Gv,Ev (66),(es) +08: OR Eb,Gb (ev) +09: OR Ev,Gv (es) | OR Ev,Gv (66),(es) +0a: OR Gb,Eb (ev) +0b: OR Gv,Ev (es) | OR Gv,Ev (66),(es) +10: ADC Eb,Gb (ev) +11: ADC Ev,Gv (es) | ADC Ev,Gv (66),(es) +12: ADC Gb,Eb (ev) +13: ADC Gv,Ev (es) | ADC Gv,Ev (66),(es) +18: SBB Eb,Gb (ev) +19: SBB Ev,Gv (es) | SBB Ev,Gv (66),(es) +1a: SBB Gb,Eb (ev) +1b: SBB Gv,Ev (es) | SBB Gv,Ev (66),(es) +20: AND Eb,Gb (ev) +21: AND Ev,Gv (es) | AND Ev,Gv (66),(es) +22: AND Gb,Eb (ev) +23: AND Gv,Ev (es) | AND Gv,Ev (66),(es) +24: SHLD Ev,Gv,Ib (es) | SHLD Ev,Gv,Ib (66),(es) +28: SUB Eb,Gb (ev) +29: SUB Ev,Gv (es) | SUB Ev,Gv (66),(es) +2a: SUB Gb,Eb (ev) +2b: SUB Gv,Ev (es) | SUB Gv,Ev (66),(es) +2c: SHRD Ev,Gv,Ib (es) | SHRD Ev,Gv,Ib (66),(es) +30: XOR Eb,Gb (ev) +31: XOR Ev,Gv (es) | XOR Ev,Gv (66),(es) +32: XOR Gb,Eb (ev) +33: XOR Gv,Ev (es) | XOR Gv,Ev (66),(es) +# CCMPSCC instructions are: CCOMB, CCOMBE, CCOMF, CCOML, CCOMLE, CCOMNB, CCOMNBE, CCOMNL, CCOMNLE, +# CCOMNO, CCOMNS, CCOMNZ, CCOMO, CCOMS, CCOMT, CCOMZ +38: CCMPSCC Eb,Gb (ev) +39: CCMPSCC Ev,Gv (es) | CCMPSCC Ev,Gv (66),(es) +3a: CCMPSCC Gv,Ev (ev) +3b: CCMPSCC Gv,Ev (es) | CCMPSCC Gv,Ev (66),(es) +40: CMOVO Gv,Ev (es) | CMOVO Gv,Ev (66),(es) | CFCMOVO Ev,Ev (es) | CFCMOVO Ev,Ev (66),(es) | SETO Eb (F2),(ev) +41: CMOVNO Gv,Ev (es) | CMOVNO Gv,Ev (66),(es) | CFCMOVNO Ev,Ev (es) | CFCMOVNO Ev,Ev (66),(es) | SETNO Eb (F2),(ev) +42: CMOVB Gv,Ev (es) | CMOVB Gv,Ev (66),(es) | CFCMOVB Ev,Ev (es) | CFCMOVB Ev,Ev (66),(es) | SETB Eb (F2),(ev) +43: CMOVNB Gv,Ev (es) | CMOVNB Gv,Ev (66),(es) | CFCMOVNB Ev,Ev (es) | CFCMOVNB Ev,Ev (66),(es) | SETNB Eb (F2),(ev) +44: CMOVZ Gv,Ev (es) | CMOVZ Gv,Ev (66),(es) | CFCMOVZ Ev,Ev (es) | CFCMOVZ Ev,Ev (66),(es) | SETZ Eb (F2),(ev) +45: CMOVNZ Gv,Ev (es) | CMOVNZ Gv,Ev (66),(es) | CFCMOVNZ Ev,Ev (es) | CFCMOVNZ Ev,Ev (66),(es) | SETNZ Eb (F2),(ev) +46: CMOVBE Gv,Ev (es) | CMOVBE Gv,Ev (66),(es) | CFCMOVBE Ev,Ev (es) | CFCMOVBE Ev,Ev (66),(es) | SETBE Eb (F2),(ev) +47: CMOVNBE Gv,Ev (es) | CMOVNBE Gv,Ev (66),(es) | CFCMOVNBE Ev,Ev (es) | CFCMOVNBE Ev,Ev (66),(es) | SETNBE Eb (F2),(ev) +48: CMOVS Gv,Ev (es) | CMOVS Gv,Ev (66),(es) | CFCMOVS Ev,Ev (es) | CFCMOVS Ev,Ev (66),(es) | SETS Eb (F2),(ev) +49: CMOVNS Gv,Ev (es) | CMOVNS Gv,Ev (66),(es) | CFCMOVNS Ev,Ev (es) | CFCMOVNS Ev,Ev (66),(es) | SETNS Eb (F2),(ev) +4a: CMOVP Gv,Ev (es) | CMOVP Gv,Ev (66),(es) | CFCMOVP Ev,Ev (es) | CFCMOVP Ev,Ev (66),(es) | SETP Eb (F2),(ev) +4b: CMOVNP Gv,Ev (es) | CMOVNP Gv,Ev (66),(es) | CFCMOVNP Ev,Ev (es) | CFCMOVNP Ev,Ev (66),(es) | SETNP Eb (F2),(ev) +4c: CMOVL Gv,Ev (es) | CMOVL Gv,Ev (66),(es) | CFCMOVL Ev,Ev (es) | CFCMOVL Ev,Ev (66),(es) | SETL Eb (F2),(ev) +4d: CMOVNL Gv,Ev (es) | CMOVNL Gv,Ev (66),(es) | CFCMOVNL Ev,Ev (es) | CFCMOVNL Ev,Ev (66),(es) | SETNL Eb (F2),(ev) +4e: CMOVLE Gv,Ev (es) | CMOVLE Gv,Ev (66),(es) | CFCMOVLE Ev,Ev (es) | CFCMOVLE Ev,Ev (66),(es) | SETLE Eb (F2),(ev) +4f: CMOVNLE Gv,Ev (es) | CMOVNLE Gv,Ev (66),(es) | CFCMOVNLE Ev,Ev (es) | CFCMOVNLE Ev,Ev (66),(es) | SETNLE Eb (F2),(ev) +60: MOVBE Gv,Ev (es) | MOVBE Gv,Ev (66),(es) +61: MOVBE Ev,Gv (es) | MOVBE Ev,Gv (66),(es) +65: WRUSSD Md,Gd (66),(ev) | WRUSSQ Mq,Gq (66),(ev) +66: ADCX Gy,Ey (66),(ev) | ADOX Gy,Ey (F3),(ev) | WRSSD Md,Gd (ev) | WRSSQ Mq,Gq (66),(ev) +69: IMUL Gv,Ev,Iz (es) | IMUL Gv,Ev,Iz (66),(es) +6b: IMUL Gv,Ev,Ib (es) | IMUL Gv,Ev,Ib (66),(es) +80: Grp1 Eb,Ib (1A),(ev) +81: Grp1 Ev,Iz (1A),(es) +83: Grp1 Ev,Ib (1A),(es) +# CTESTSCC instructions are: CTESTB, CTESTBE, CTESTF, CTESTL, CTESTLE, CTESTNB, CTESTNBE, CTESTNL, +# CTESTNLE, CTESTNO, CTESTNS, CTESTNZ, CTESTO, CTESTS, CTESTT, CTESTZ +84: CTESTSCC (ev) +85: CTESTSCC (es) | CTESTSCC (66),(es) +88: POPCNT Gv,Ev (es) | POPCNT Gv,Ev (66),(es) +8f: POP2 Bq,Rq (000),(11B),(ev) +a5: SHLD Ev,Gv,CL (es) | SHLD Ev,Gv,CL (66),(es) +ad: SHRD Ev,Gv,CL (es) | SHRD Ev,Gv,CL (66),(es) +af: IMUL Gv,Ev (es) | IMUL Gv,Ev (66),(es) +c0: Grp2 Eb,Ib (1A),(ev) +c1: Grp2 Ev,Ib (1A),(es) +d0: Grp2 Eb,1 (1A),(ev) +d1: Grp2 Ev,1 (1A),(es) +d2: Grp2 Eb,CL (1A),(ev) +d3: Grp2 Ev,CL (1A),(es) +f0: CRC32 Gy,Eb (es) | INVEPT Gq,Mdq (F3),(ev) +f1: CRC32 Gy,Ey (es) | CRC32 Gy,Ey (66),(es) | INVVPID Gy,Mdq (F3),(ev) +f2: INVPCID Gy,Mdq (F3),(ev) +f4: TZCNT Gv,Ev (es) | TZCNT Gv,Ev (66),(es) +f5: LZCNT Gv,Ev (es) | LZCNT Gv,Ev (66),(es) +f6: Grp3_1 Eb (1A),(ev) +f7: Grp3_2 Ev (1A),(es) +f8: MOVDIR64B Gv,Mdqq (66),(ev) | ENQCMD Gv,Mdqq (F2),(ev) | ENQCMDS Gv,Mdqq (F3),(ev) | URDMSR Rq,Gq (F2),(11B),(ev) | UWRMSR Gq,Rq (F3),(11B),(ev) +f9: MOVDIRI My,Gy (ev) +fe: Grp4 (1A),(ev) +ff: Grp5 (1A),(es) | PUSH2 Bq,Rq (110),(11B),(ev) +EndTable + Table: EVEX map 5 Referrer: AVXcode: 5
tools/arch/x86/lib/x86-opcode-map.txt +93 -0
105 lines not on this page · raw message
Signature · 1 line
2.34.1
[tip: perf/core] x86/insn: Add support for APX EVEX instructions to the opcode map
The following commit has been merged into the perf/core branch of tip:
The following commit has been merged into the perf/core branch of tip:
Commit-ID: 690ca3a3067f760bef92ca5db1c42490498ab5de Gitweb: https://git.kernel.org/tip/690ca3a3067f760bef92ca5db1c42490498ab5de Author: Adrian Hunter <[email protected]> AuthorDate: Thu, 02 May 2024 13:58:51 +03:00 Committer: Ingo Molnar <[email protected]> CommitterDate: Thu, 02 May 2024 13:13:46 +02:00
x86/insn: Add support for APX EVEX instructions to the opcode map
To support APX functionality, the EVEX prefix is used to:
- promote legacy instructions
- promote VEX instructions
- add new instructions
Promoted VEX instructions require no extra annotation because the opcodes do not change and the permissive nature of the instruction decoder already allows them to have an EVEX prefix.
Promoted legacy instructions and new instructions are placed in map 4 which has not been used before.
Create a new table for map 4 and add APX instructions.
Annotate SCALABLE instructions with "(es)" - refer to patch "x86/insn: Add support for APX EVEX to the instruction decoder logic". SCALABLE instructions must be represented in both no-prefix (NP) and 66 prefix forms.
--- arch/x86/lib/x86-opcode-map.txt | 93 ++++++++++++++++++++++++++- tools/arch/x86/lib/x86-opcode-map.txt | 93 ++++++++++++++++++++++++++- 2 files changed, 186 insertions(+)
arch/x86/lib/x86-opcode-map.txt +93 -0
@@ -23,6 +23,7 @@ # # AVX Superscripts # (ev): this opcode requires EVEX prefix. +# (es): this opcode requires EVEX prefix and is SCALABALE. # (evo): this opcode is changed by EVEX prefix (EVEX opcode) # (v): this opcode requires VEX prefix. # (v1): this opcode only supports 128bit VEX.
@@ -929,6 +930,98 @@ df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1) f0: RORX Gy,Ey,Ib (F2),(v) | HRESET Gv,Ib (F3),(000),(11B) EndTable +Table: EVEX map 4 +Referrer: +AVXcode: 4 +00: ADD Eb,Gb (ev) +01: ADD Ev,Gv (es) | ADD Ev,Gv (66),(es) +02: ADD Gb,Eb (ev) +03: ADD Gv,Ev (es) | ADD Gv,Ev (66),(es) +08: OR Eb,Gb (ev) +09: OR Ev,Gv (es) | OR Ev,Gv (66),(es) +0a: OR Gb,Eb (ev) +0b: OR Gv,Ev (es) | OR Gv,Ev (66),(es) +10: ADC Eb,Gb (ev) +11: ADC Ev,Gv (es) | ADC Ev,Gv (66),(es) +12: ADC Gb,Eb (ev) +13: ADC Gv,Ev (es) | ADC Gv,Ev (66),(es) +18: SBB Eb,Gb (ev) +19: SBB Ev,Gv (es) | SBB Ev,Gv (66),(es) +1a: SBB Gb,Eb (ev) +1b: SBB Gv,Ev (es) | SBB Gv,Ev (66),(es) +20: AND Eb,Gb (ev) +21: AND Ev,Gv (es) | AND Ev,Gv (66),(es) +22: AND Gb,Eb (ev) +23: AND Gv,Ev (es) | AND Gv,Ev (66),(es) +24: SHLD Ev,Gv,Ib (es) | SHLD Ev,Gv,Ib (66),(es) +28: SUB Eb,Gb (ev) +29: SUB Ev,Gv (es) | SUB Ev,Gv (66),(es) +2a: SUB Gb,Eb (ev) +2b: SUB Gv,Ev (es) | SUB Gv,Ev (66),(es) +2c: SHRD Ev,Gv,Ib (es) | SHRD Ev,Gv,Ib (66),(es) +30: XOR Eb,Gb (ev) +31: XOR Ev,Gv (es) | XOR Ev,Gv (66),(es) +32: XOR Gb,Eb (ev) +33: XOR Gv,Ev (es) | XOR Gv,Ev (66),(es) +# CCMPSCC instructions are: CCOMB, CCOMBE, CCOMF, CCOML, CCOMLE, CCOMNB, CCOMNBE, CCOMNL, CCOMNLE, +# CCOMNO, CCOMNS, CCOMNZ, CCOMO, CCOMS, CCOMT, CCOMZ +38: CCMPSCC Eb,Gb (ev) +39: CCMPSCC Ev,Gv (es) | CCMPSCC Ev,Gv (66),(es) +3a: CCMPSCC Gv,Ev (ev) +3b: CCMPSCC Gv,Ev (es) | CCMPSCC Gv,Ev (66),(es) +40: CMOVO Gv,Ev (es) | CMOVO Gv,Ev (66),(es) | CFCMOVO Ev,Ev (es) | CFCMOVO Ev,Ev (66),(es) | SETO Eb (F2),(ev) +41: CMOVNO Gv,Ev (es) | CMOVNO Gv,Ev (66),(es) | CFCMOVNO Ev,Ev (es) | CFCMOVNO Ev,Ev (66),(es) | SETNO Eb (F2),(ev) +42: CMOVB Gv,Ev (es) | CMOVB Gv,Ev (66),(es) | CFCMOVB Ev,Ev (es) | CFCMOVB Ev,Ev (66),(es) | SETB Eb (F2),(ev) +43: CMOVNB Gv,Ev (es) | CMOVNB Gv,Ev (66),(es) | CFCMOVNB Ev,Ev (es) | CFCMOVNB Ev,Ev (66),(es) | SETNB Eb (F2),(ev) +44: CMOVZ Gv,Ev (es) | CMOVZ Gv,Ev (66),(es) | CFCMOVZ Ev,Ev (es) | CFCMOVZ Ev,Ev (66),(es) | SETZ Eb (F2),(ev) +45: CMOVNZ Gv,Ev (es) | CMOVNZ Gv,Ev (66),(es) | CFCMOVNZ Ev,Ev (es) | CFCMOVNZ Ev,Ev (66),(es) | SETNZ Eb (F2),(ev) +46: CMOVBE Gv,Ev (es) | CMOVBE Gv,Ev (66),(es) | CFCMOVBE Ev,Ev (es) | CFCMOVBE Ev,Ev (66),(es) | SETBE Eb (F2),(ev) +47: CMOVNBE Gv,Ev (es) | CMOVNBE Gv,Ev (66),(es) | CFCMOVNBE Ev,Ev (es) | CFCMOVNBE Ev,Ev (66),(es) | SETNBE Eb (F2),(ev) +48: CMOVS Gv,Ev (es) | CMOVS Gv,Ev (66),(es) | CFCMOVS Ev,Ev (es) | CFCMOVS Ev,Ev (66),(es) | SETS Eb (F2),(ev) +49: CMOVNS Gv,Ev (es) | CMOVNS Gv,Ev (66),(es) | CFCMOVNS Ev,Ev (es) | CFCMOVNS Ev,Ev (66),(es) | SETNS Eb (F2),(ev) +4a: CMOVP Gv,Ev (es) | CMOVP Gv,Ev (66),(es) | CFCMOVP Ev,Ev (es) | CFCMOVP Ev,Ev (66),(es) | SETP Eb (F2),(ev) +4b: CMOVNP Gv,Ev (es) | CMOVNP Gv,Ev (66),(es) | CFCMOVNP Ev,Ev (es) | CFCMOVNP Ev,Ev (66),(es) | SETNP Eb (F2),(ev) +4c: CMOVL Gv,Ev (es) | CMOVL Gv,Ev (66),(es) | CFCMOVL Ev,Ev (es) | CFCMOVL Ev,Ev (66),(es) | SETL Eb (F2),(ev) +4d: CMOVNL Gv,Ev (es) | CMOVNL Gv,Ev (66),(es) | CFCMOVNL Ev,Ev (es) | CFCMOVNL Ev,Ev (66),(es) | SETNL Eb (F2),(ev) +4e: CMOVLE Gv,Ev (es) | CMOVLE Gv,Ev (66),(es) | CFCMOVLE Ev,Ev (es) | CFCMOVLE Ev,Ev (66),(es) | SETLE Eb (F2),(ev) +4f: CMOVNLE Gv,Ev (es) | CMOVNLE Gv,Ev (66),(es) | CFCMOVNLE Ev,Ev (es) | CFCMOVNLE Ev,Ev (66),(es) | SETNLE Eb (F2),(ev) +60: MOVBE Gv,Ev (es) | MOVBE Gv,Ev (66),(es) +61: MOVBE Ev,Gv (es) | MOVBE Ev,Gv (66),(es) +65: WRUSSD Md,Gd (66),(ev) | WRUSSQ Mq,Gq (66),(ev) +66: ADCX Gy,Ey (66),(ev) | ADOX Gy,Ey (F3),(ev) | WRSSD Md,Gd (ev) | WRSSQ Mq,Gq (66),(ev) +69: IMUL Gv,Ev,Iz (es) | IMUL Gv,Ev,Iz (66),(es) +6b: IMUL Gv,Ev,Ib (es) | IMUL Gv,Ev,Ib (66),(es) +80: Grp1 Eb,Ib (1A),(ev) +81: Grp1 Ev,Iz (1A),(es) +83: Grp1 Ev,Ib (1A),(es) +# CTESTSCC instructions are: CTESTB, CTESTBE, CTESTF, CTESTL, CTESTLE, CTESTNB, CTESTNBE, CTESTNL, +# CTESTNLE, CTESTNO, CTESTNS, CTESTNZ, CTESTO, CTESTS, CTESTT, CTESTZ +84: CTESTSCC (ev) +85: CTESTSCC (es) | CTESTSCC (66),(es) +88: POPCNT Gv,Ev (es) | POPCNT Gv,Ev (66),(es) +8f: POP2 Bq,Rq (000),(11B),(ev) +a5: SHLD Ev,Gv,CL (es) | SHLD Ev,Gv,CL (66),(es) +ad: SHRD Ev,Gv,CL (es) | SHRD Ev,Gv,CL (66),(es) +af: IMUL Gv,Ev (es) | IMUL Gv,Ev (66),(es) +c0: Grp2 Eb,Ib (1A),(ev) +c1: Grp2 Ev,Ib (1A),(es) +d0: Grp2 Eb,1 (1A),(ev) +d1: Grp2 Ev,1 (1A),(es) +d2: Grp2 Eb,CL (1A),(ev) +d3: Grp2 Ev,CL (1A),(es) +f0: CRC32 Gy,Eb (es) | INVEPT Gq,Mdq (F3),(ev) +f1: CRC32 Gy,Ey (es) | CRC32 Gy,Ey (66),(es) | INVVPID Gy,Mdq (F3),(ev) +f2: INVPCID Gy,Mdq (F3),(ev) +f4: TZCNT Gv,Ev (es) | TZCNT Gv,Ev (66),(es) +f5: LZCNT Gv,Ev (es) | LZCNT Gv,Ev (66),(es) +f6: Grp3_1 Eb (1A),(ev) +f7: Grp3_2 Ev (1A),(es) +f8: MOVDIR64B Gv,Mdqq (66),(ev) | ENQCMD Gv,Mdqq (F2),(ev) | ENQCMDS Gv,Mdqq (F3),(ev) | URDMSR Rq,Gq (F2),(11B),(ev) | UWRMSR Gq,Rq (F3),(11B),(ev) +f9: MOVDIRI My,Gy (ev) +fe: Grp4 (1A),(ev) +ff: Grp5 (1A),(es) | PUSH2 Bq,Rq (110),(11B),(ev) +EndTable + Table: EVEX map 5 Referrer: AVXcode: 5
tools/arch/x86/lib/x86-opcode-map.txt +93 -0
105 lines not on this page · raw message
Adrian Hunter
reviewerPATCH 9/10 perf intel pt: Add new JMPABS instruction to the Intel PT instruction decoder
In reply to Adrian HunterJMPABS is 64-bit absolute direct jump instruction, encoded with a mandatory REX2 prefix. JMPABS is designed to be used in the procedure linkage table (PLT) to replace indirect jumps, because it has better performance. In that case the jump target will be amended at run time. To enable Intel PT to follow the code, a TIP packet is always emitted when JMPABS is traced under Intel PT.
Refer to the Intel Advanced Performance Extensions (Intel APX) Architecture Specification for details.
Decode JMPABS as an indirect jump, because it has an associated TIP packet the same as an indirect jump and the control flow should follow the TIP packet payload, and not assume it is the same as the on-file object code JMPABS target address.
--- tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c | 9 +++++++++ 1 file changed, 9 insertions(+)
tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c +9 -0
@@ -92,6 +92,15 @@ static void intel_pt_insn_decoder(struct insn *insn, op =INTEL_PT_OP_JCC ; branch =INTEL_PT_BR_CONDITIONAL ;break ; +case 0xa1 : +if (insn_is_rex2 (insn)) {/* jmpabs */ + intel_pt_insn->op =INTEL_PT_OP_JMP ; +/* jmpabs causes a TIP packet like an indirect branch */ + intel_pt_insn->branch =INTEL_PT_BR_INDIRECT ; + intel_pt_insn->length = insn->length; +return ; + } +break ;case 0xc2 :/* near ret */ case 0xc3 :/* near ret */ case 0xca :/* far ret */
Signature · 1 line
2.34.1
Adrian Hunter
reviewerRe: [PATCH 09/10] perf intel pt: Add new JMPABS instruction to the Intel PT instruction decoder
Quoted 10 lines · Adrian Hunter
JMPABS is 64-bit absolute direct jump instruction, encoded with a mandatory REX2 prefix. JMPABS is designed to be used in the procedure linkage table (PLT) to replace indirect jumps, because it has better performance. In that case the jump target will be amended at run time. To enable Intel PT to follow the code, a TIP packet is always emitted when JMPABS is traced under Intel PT.
Refer to the Intel Advanced Performance Extensions (Intel APX) Architecture Specification for details.
Quoted 6 lines
Decode JMPABS as an indirect jump, because it has an associated TIP packet the same as an indirect jump and the control flow should follow the TIP packet payload, and not assume it is the same as the on-file object code JMPABS target address.
Signed-off-by Adrian Hunter <[email protected]>
Patches 1-8 are in perf-tools-next now, so this and patch 10 could be applied.
Quoted 24 lines
--- tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c | 9 +++++++++ 1 file changed, 9 insertions(+)tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c +9
-0@@ -92,6 +92,15 @@ static void intel_pt_insn_decoder(struct insn *insn, op =INTEL_PT_OP_JCC ; branch =INTEL_PT_BR_CONDITIONAL ;break ; +case 0xa1 : +if (insn_is_rex2 (insn)) {/* jmpabs */ + intel_pt_insn->op =INTEL_PT_OP_JMP ; +/* jmpabs causes a TIP packet like an indirect branch */ + intel_pt_insn->branch =INTEL_PT_BR_INDIRECT ; + intel_pt_insn->length = insn->length; +return ; + } +break ;case 0xc2 :/* near ret */ case 0xc3 :/* near ret */ case 0xca :/* far ret */
Adrian Hunter
reviewerRe: [PATCH 09/10] perf intel pt: Add new JMPABS instruction to the Intel PT instruction decoder
Quoted 16 lines · Adrian Hunter
Quoted 15 lines · Adrian Hunter
JMPABS is 64-bit absolute direct jump instruction, encoded with a mandatory REX2 prefix. JMPABS is designed to be used in the procedure linkage table (PLT) to replace indirect jumps, because it has better performance. In that case the jump target will be amended at run time. To enable Intel PT to follow the code, a TIP packet is always emitted when JMPABS is traced under Intel PT.
Refer to the Intel Advanced Performance Extensions (Intel APX) Architecture Specification for details.
Decode JMPABS as an indirect jump, because it has an associated TIP packet the same as an indirect jump and the control flow should follow the TIP packet payload, and not assume it is the same as the on-file object code JMPABS target address.
Quoted 4 lines
Quoted 1 line
Signed-off-by Adrian Hunter <[email protected]>Patches 1-8 are in perf-tools-next now, so this and patch 10 could be applied.
Still apply
Quoted 26 lines
Quoted 25 lines
--- tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c | 9 +++++++++ 1 file changed, 9 insertions(+)tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c +9
-0@@ -92,6 +92,15 @@ static void intel_pt_insn_decoder(struct insn *insn, op =INTEL_PT_OP_JCC ; branch =INTEL_PT_BR_CONDITIONAL ;break ; +case 0xa1 : +if (insn_is_rex2 (insn)) {/* jmpabs */ + intel_pt_insn->op =INTEL_PT_OP_JMP ; +/* jmpabs causes a TIP packet like an indirect branch */ + intel_pt_insn->branch =INTEL_PT_BR_INDIRECT ; + intel_pt_insn->length = insn->length; +return ; + } +break ;case 0xc2 :/* near ret */ case 0xc3 :/* near ret */ case 0xca :/* far ret */
Adrian Hunter
reviewerPATCH 10/10 perf tests: Add APX and other new instructions to x86 instruction decoder test
In reply to Adrian HunterAdd samples of APX and other new instructions to the 'x86 instruction decoder - new instructions' test.
Note the test is only available if the perf tool has been built with EXTRA_TESTS=1.
Example:
$ make EXTRA_TESTS=1 -C tools/perf $ tools/perf/perf test -F -v 'new ins' |& grep -i 'jmpabs\|popp\|pushp' Decoded ok: d5 00 a1 ef cd ab 90 78 56 34 12 jmpabs $0x1234567890abcdef Decoded ok: d5 08 53 pushp %rbx Decoded ok: d5 18 50 pushp %r16 Decoded ok: d5 19 57 pushp %r31 Decoded ok: d5 19 5f popp %r31 Decoded ok: d5 18 58 popp %r16 Decoded ok: d5 08 5b popp %rbx
--- tools/perf/arch/x86/tests/insn-x86-dat-32.c | 116 ++ tools/perf/arch/x86/tests/insn-x86-dat-64.c | 1026 ++++++++++++++++++ tools/perf/arch/x86/tests/insn-x86-dat-src.c | 597 ++++++++++ 3 files changed, 1739 insertions(+)
tools/perf/arch/x86/tests/insn-x86-dat-32.c +116 -0
@@ -3107,6 +3107,122 @@ "62 f5 7c 08 2e ca \tvucomish %xmm2,%xmm1",}, {{0x62, 0xf5, 0x7c, 0x08, 0x2e, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 11, 0, "", "", "62 f5 7c 08 2e 8c c8 78 56 34 12 \tvucomish 0x12345678(%eax,%ecx,8),%xmm1",}, +{{0xf3, 0x0f, 0x38, 0xdc, 0xd1, }, 5, 0, "", "", +"f3 0f 38 dc d1 \tloadiwkey %xmm1,%xmm2",}, +{{0xf3, 0x0f, 0x38, 0xfa, 0xd0, }, 5, 0, "", "", +"f3 0f 38 fa d0 \tencodekey128 %eax,%edx",}, +{{0xf3, 0x0f, 0x38, 0xfb, 0xd0, }, 5, 0, "", "", +"f3 0f 38 fb d0 \tencodekey256 %eax,%edx",}, +{{0xf3, 0x0f, 0x38, 0xdc, 0x5a, 0x77, }, 6, 0, "", "", +"f3 0f 38 dc 5a 77 \taesenc128kl 0x77(%edx),%xmm3",}, +{{0xf3, 0x0f, 0x38, 0xde, 0x5a, 0x77, }, 6, 0, "", "", +"f3 0f 38 de 5a 77 \taesenc256kl 0x77(%edx),%xmm3",}, +{{0xf3, 0x0f, 0x38, 0xdd, 0x5a, 0x77, }, 6, 0, "", "", +"f3 0f 38 dd 5a 77 \taesdec128kl 0x77(%edx),%xmm3",}, +{{0xf3, 0x0f, 0x38, 0xdf, 0x5a, 0x77, }, 6, 0, "", "", +"f3 0f 38 df 5a 77 \taesdec256kl 0x77(%edx),%xmm3",}, +{{0xf3, 0x0f, 0x38, 0xd8, 0x42, 0x77, }, 6, 0, "", "", +"f3 0f 38 d8 42 77 \taesencwide128kl 0x77(%edx)",}, +{{0xf3, 0x0f, 0x38, 0xd8, 0x52, 0x77, }, 6, 0, "", "", +"f3 0f 38 d8 52 77 \taesencwide256kl 0x77(%edx)",}, +{{0xf3, 0x0f, 0x38, 0xd8, 0x4a, 0x77, }, 6, 0, "", "", +"f3 0f 38 d8 4a 77 \taesdecwide128kl 0x77(%edx)",}, +{{0xf3, 0x0f, 0x38, 0xd8, 0x5a, 0x77, }, 6, 0, "", "", +"f3 0f 38 d8 5a 77 \taesdecwide256kl 0x77(%edx)",}, +{{0x0f, 0x38, 0xfc, 0x08, }, 4, 0, "", "", +"0f 38 fc 08 \taadd %ecx,(%eax)",}, +{{0x0f, 0x38, 0xfc, 0x15, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "", +"0f 38 fc 15 78 56 34 12 \taadd %edx,0x12345678",}, +{{0x0f, 0x38, 0xfc, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "", +"0f 38 fc 94 c8 78 56 34 12 \taadd %edx,0x12345678(%eax,%ecx,8)",}, +{{0x66, 0x0f, 0x38, 0xfc, 0x08, }, 5, 0, "", "", +"66 0f 38 fc 08 \taand %ecx,(%eax)",}, +{{0x66, 0x0f, 0x38, 0xfc, 0x15, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "", +"66 0f 38 fc 15 78 56 34 12 \taand %edx,0x12345678",}, +{{0x66, 0x0f, 0x38, 0xfc, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "", +"66 0f 38 fc 94 c8 78 56 34 12 \taand %edx,0x12345678(%eax,%ecx,8)",}, +{{0xf2, 0x0f, 0x38, 0xfc, 0x08, }, 5, 0, "", "", +"f2 0f 38 fc 08 \taor %ecx,(%eax)",}, +{{0xf2, 0x0f, 0x38, 0xfc, 0x15, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "", +"f2 0f 38 fc 15 78 56 34 12 \taor %edx,0x12345678",}, +{{0xf2, 0x0f, 0x38, 0xfc, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "", +"f2 0f 38 fc 94 c8 78 56 34 12 \taor %edx,0x12345678(%eax,%ecx,8)",}, +{{0xf3, 0x0f, 0x38, 0xfc, 0x08, }, 5, 0, "", "", +"f3 0f 38 fc 08 \taxor %ecx,(%eax)",}, +{{0xf3, 0x0f, 0x38, 0xfc, 0x15, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "", +"f3 0f 38 fc 15 78 56 34 12 \taxor %edx,0x12345678",}, +{{0xf3, 0x0f, 0x38, 0xfc, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "", +"f3 0f 38 fc 94 c8 78 56 34 12 \taxor %edx,0x12345678(%eax,%ecx,8)",}, +{{0xc4, 0xe2, 0x7a, 0xb1, 0x31, }, 5, 0, "", "", +"c4 e2 7a b1 31 \tvbcstnebf162ps (%ecx),%xmm6",}, +{{0xc4, 0xe2, 0x79, 0xb1, 0x31, }, 5, 0, "", "", +"c4 e2 79 b1 31 \tvbcstnesh2ps (%ecx),%xmm6",}, +{{0xc4, 0xe2, 0x7a, 0xb0, 0x31, }, 5, 0, "", "", +"c4 e2 7a b0 31 \tvcvtneebf162ps (%ecx),%xmm6",}, +{{0xc4, 0xe2, 0x79, 0xb0, 0x31, }, 5, 0, "", "", +"c4 e2 79 b0 31 \tvcvtneeph2ps (%ecx),%xmm6",}, +{{0xc4, 0xe2, 0x7b, 0xb0, 0x31, }, 5, 0, "", "", +"c4 e2 7b b0 31 \tvcvtneobf162ps (%ecx),%xmm6",}, +{{0xc4, 0xe2, 0x78, 0xb0, 0x31, }, 5, 0, "", "", +"c4 e2 78 b0 31 \tvcvtneoph2ps (%ecx),%xmm6",}, +{{0x62, 0xf2, 0x7e, 0x08, 0x72, 0xf1, }, 6, 0, "", "", +"62 f2 7e 08 72 f1 \tvcvtneps2bf16 %xmm1,%xmm6",}, +{{0xc4, 0xe2, 0x6b, 0x50, 0xd9, }, 5, 0, "", "", +"c4 e2 6b 50 d9 \tvpdpbssd %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x6b, 0x51, 0xd9, }, 5, 0, "", "", +"c4 e2 6b 51 d9 \tvpdpbssds %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x6a, 0x50, 0xd9, }, 5, 0, "", "", +"c4 e2 6a 50 d9 \tvpdpbsud %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x6a, 0x51, 0xd9, }, 5, 0, "", "", +"c4 e2 6a 51 d9 \tvpdpbsuds %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x68, 0x50, 0xd9, }, 5, 0, "", "", +"c4 e2 68 50 d9 \tvpdpbuud %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x68, 0x51, 0xd9, }, 5, 0, "", "", +"c4 e2 68 51 d9 \tvpdpbuuds %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x6a, 0xd2, 0xd9, }, 5, 0, "", "", +"c4 e2 6a d2 d9 \tvpdpwsud %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x6a, 0xd3, 0xd9, }, 5, 0, "", "", +"c4 e2 6a d3 d9 \tvpdpwsuds %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x69, 0xd2, 0xd9, }, 5, 0, "", "", +"c4 e2 69 d2 d9 \tvpdpwusd %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x69, 0xd3, 0xd9, }, 5, 0, "", "", +"c4 e2 69 d3 d9 \tvpdpwusds %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x68, 0xd2, 0xd9, }, 5, 0, "", "", +"c4 e2 68 d2 d9 \tvpdpwuud %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x68, 0xd3, 0xd9, }, 5, 0, "", "", +"c4 e2 68 d3 d9 \tvpdpwuuds %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0xed, 0x08, 0xb5, 0xd9, }, 6, 0, "", "", +"62 f2 ed 08 b5 d9 \tvpmadd52huq %xmm1,%xmm2,%xmm3",}, +{{0x62, 0xf2, 0xed, 0x08, 0xb4, 0xd9, }, 6, 0, "", "", +"62 f2 ed 08 b4 d9 \tvpmadd52luq %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x7f, 0xcc, 0xd1, }, 5, 0, "", "", +"c4 e2 7f cc d1 \tvsha512msg1 %xmm1,%ymm2",}, +{{0xc4, 0xe2, 0x7f, 0xcd, 0xd1, }, 5, 0, "", "", +"c4 e2 7f cd d1 \tvsha512msg2 %ymm1,%ymm2",}, +{{0xc4, 0xe2, 0x6f, 0xcb, 0xd9, }, 5, 0, "", "", +"c4 e2 6f cb d9 \tvsha512rnds2 %xmm1,%ymm2,%ymm3",}, +{{0xc4, 0xe2, 0x68, 0xda, 0xd9, }, 5, 0, "", "", +"c4 e2 68 da d9 \tvsm3msg1 %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x69, 0xda, 0xd9, }, 5, 0, "", "", +"c4 e2 69 da d9 \tvsm3msg2 %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe3, 0x69, 0xde, 0xd9, 0xa1, }, 6, 0, "", "", +"c4 e3 69 de d9 a1 \tvsm3rnds2 $0xa1,%xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x6a, 0xda, 0xd9, }, 5, 0, "", "", +"c4 e2 6a da d9 \tvsm4key4 %xmm1,%xmm2,%xmm3",}, +{{0xc4, 0xe2, 0x6b, 0xda, 0xd9, }, 5, 0, "", "", +"c4 e2 6b da d9 \tvsm4rnds4 %xmm1,%xmm2,%xmm3",}, +{{0x0f, 0x0d, 0x00, }, 3, 0, "", "", +"0f 0d 00 \tprefetch (%eax)",}, +{{0x0f, 0x18, 0x08, }, 3, 0, "", "", +"0f 18 08 \tprefetcht0 (%eax)",}, +{{0x0f, 0x18, 0x10, }, 3, 0, "", "", +"0f 18 10 \tprefetcht1 (%eax)",}, +{{0x0f, 0x18, 0x18, }, 3, 0, "", "", +"0f 18 18 \tprefetcht2 (%eax)",}, +{{0x0f, 0x18, 0x00, }, 3, 0, "", "", +"0f 18 00 \tprefetchnta (%eax)",}, +{{0x0f, 0x01, 0xc6, }, 3, 0, "", "", +"0f 01 c6 \twrmsrns",}, {{0xf3, 0x0f, 0x3a, 0xf0, 0xc0, 0x00, }, 6, 0, "", "", "f3 0f 3a f0 c0 00 \threset $0x0",}, {{0x0f, 0x01, 0xe8, }, 3, 0, "", "",
tools/perf/arch/x86/tests/insn-x86-dat-64.c +1026 -0
1,032 lines not on this page · raw message
tools/perf/arch/x86/tests/insn-x86-dat-src.c +597 -0
609 lines not on this page · raw message
Signature · 1 line
2.34.1
Re: (subset) [PATCH 00/10] perf intel pt: Update instruction decoder for APX and other new instructions
In reply to Adrian HunterQuoted 10 lines · Adrian Hunter
The x86 instruction decoder is used not only for decoding kernel instructions. It is also used by perf uprobes (user space probes) and by perf tools Intel Processor Trace decoding. Consequently, it needs to support instructions executed by user space also.
It should be noted that there are 2 copies of the instruction decoder. One for the kernel and one for tools, which is a policy to prevent changes from breaking builds.
[...]
Applied patch 9 and 10 to perf-tools-next, thanks!
Best regards,
Namhyung