Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf intel-pt: Use shared x86 insn decoder

Now that there's a common version of the decoder for all tools, use it
instead of the local copy.

Also use perf's check-headers.sh script to diff the decoder files to
make sure they remain in sync with the kernel version. Objtool has a
similar check.

Committer notes:

Had to keep this all pointing explicitely to x86 headers/files, i.e.
instead of asm/isnn.h we had to use ../include/asm/insn.h when the files
were in differemt dirs, or just replace "<asm/foo.h>" with "foo.h".

This way we continue to be able to process perf.data files with Intel PT
traces in distros other than x86.

Also fixed up the awk script paths to use $(srcdir)/tools/arch instead
or relative directories so that we keep detached tarballs (make help |
grep perf) working.

For now the include lines in these headers are being ignored so as not
to flag false reports of kernel/tools out of sync.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Reviewed-by: Masami Hiramatsu <mhiramat@kernel.org>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: x86@kernel.org
Link: http://lore.kernel.org/lkml/8a37e615d2880f039505d693d1e068a009358a2b.1567118001.git.jpoimboe@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Josh Poimboeuf and committed by
Arnaldo Carvalho de Melo
00a26390 f1da0a6c

+23 -2632
+1 -1
tools/arch/x86/include/asm/inat.h
··· 6 6 * 7 7 * Written by Masami Hiramatsu <mhiramat@redhat.com> 8 8 */ 9 - #include <asm/inat_types.h> 9 + #include "inat_types.h" 10 10 11 11 /* 12 12 * Internal bits. Don't use bitmasks directly, because these bits are
+1 -1
tools/arch/x86/include/asm/insn.h
··· 8 8 */ 9 9 10 10 /* insn_attr_t is defined in inat.h */ 11 - #include <asm/inat.h> 11 + #include "inat.h" 12 12 13 13 struct insn_field { 14 14 union {
+1 -1
tools/arch/x86/lib/inat.c
··· 4 4 * 5 5 * Written by Masami Hiramatsu <mhiramat@redhat.com> 6 6 */ 7 - #include <asm/insn.h> 7 + #include "../include/asm/insn.h" 8 8 9 9 /* Attribute tables are generated from opcode map */ 10 10 #include "inat-tables.c"
+2 -2
tools/arch/x86/lib/insn.c
··· 10 10 #else 11 11 #include <string.h> 12 12 #endif 13 - #include <asm/inat.h> 14 - #include <asm/insn.h> 13 + #include "../include/asm/inat.h" 14 + #include "../include/asm/insn.h" 15 15 16 16 /* Verify next sizeof(t) bytes can be on the same instruction */ 17 17 #define validate_next(t, insn, n) \
+1 -1
tools/perf/arch/x86/tests/insn-x86.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 #include <linux/types.h> 3 + #include "../../../../arch/x86/include/asm/insn.h" 3 4 #include <string.h> 4 5 5 6 #include "debug.h" 6 7 #include "tests/tests.h" 7 8 #include "arch-tests.h" 8 9 9 - #include "intel-pt-decoder/insn.h" 10 10 #include "intel-pt-decoder/intel-pt-insn-decoder.h" 11 11 12 12 struct test_data {
+1 -1
tools/perf/arch/x86/util/archinsn.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 + #include "../../../../arch/x86/include/asm/insn.h" 2 3 #include "archinsn.h" 3 - #include "util/intel-pt-decoder/insn.h" 4 4 #include "machine.h" 5 5 #include "thread.h" 6 6 #include "symbol.h"
+9 -2
tools/perf/check-headers.sh
··· 1 1 #!/bin/sh 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 4 - HEADERS=' 4 + FILES=' 5 5 include/uapi/linux/const.h 6 6 include/uapi/drm/drm.h 7 7 include/uapi/drm/i915_drm.h ··· 26 26 arch/x86/include/asm/disabled-features.h 27 27 arch/x86/include/asm/required-features.h 28 28 arch/x86/include/asm/cpufeatures.h 29 + arch/x86/include/asm/inat.h 30 + arch/x86/include/asm/inat_types.h 31 + arch/x86/include/asm/insn.h 29 32 arch/x86/include/uapi/asm/prctl.h 33 + arch/x86/lib/inat.c 34 + arch/x86/lib/insn.c 35 + arch/x86/lib/x86-opcode-map.txt 36 + arch/x86/tools/gen-insn-attr-x86.awk 30 37 arch/arm/include/uapi/asm/perf_regs.h 31 38 arch/arm64/include/uapi/asm/perf_regs.h 32 39 arch/powerpc/include/uapi/asm/perf_regs.h ··· 105 98 cd ../.. 106 99 107 100 # simple diff check 108 - for i in $HEADERS; do 101 + for i in $FILES; do 109 102 check $i -B 110 103 done 111 104
+2 -18
tools/perf/util/intel-pt-decoder/Build
··· 1 1 perf-$(CONFIG_AUXTRACE) += intel-pt-pkt-decoder.o intel-pt-insn-decoder.o intel-pt-log.o intel-pt-decoder.o 2 2 3 - inat_tables_script = util/intel-pt-decoder/gen-insn-attr-x86.awk 4 - inat_tables_maps = util/intel-pt-decoder/x86-opcode-map.txt 3 + inat_tables_script = $(srctree)/tools/arch/x86/tools/gen-insn-attr-x86.awk 4 + inat_tables_maps = $(srctree)/tools/arch/x86/lib/x86-opcode-map.txt 5 5 6 6 $(OUTPUT)util/intel-pt-decoder/inat-tables.c: $(inat_tables_script) $(inat_tables_maps) 7 7 $(call rule_mkdir) ··· 10 10 # Busybox's diff doesn't have -I, avoid warning in the case 11 11 12 12 $(OUTPUT)util/intel-pt-decoder/intel-pt-insn-decoder.o: util/intel-pt-decoder/intel-pt-insn-decoder.c $(OUTPUT)util/intel-pt-decoder/inat-tables.c 13 - @(diff -I 2>&1 | grep -q 'option requires an argument' && \ 14 - test -d ../../kernel -a -d ../../tools -a -d ../perf && ( \ 15 - ((diff -B -I'^#include' util/intel-pt-decoder/insn.c ../../arch/x86/lib/insn.c >/dev/null) || \ 16 - (echo "Warning: Intel PT: x86 instruction decoder C file at 'tools/perf/util/intel-pt-decoder/insn.c' differs from latest version at 'arch/x86/lib/insn.c'" >&2)) && \ 17 - ((diff -B -I'^#include' util/intel-pt-decoder/inat.c ../../arch/x86/lib/inat.c >/dev/null) || \ 18 - (echo "Warning: Intel PT: x86 instruction decoder C file at 'tools/perf/util/intel-pt-decoder/inat.c' differs from latest version at 'arch/x86/lib/inat.c'" >&2)) && \ 19 - ((diff -B util/intel-pt-decoder/x86-opcode-map.txt ../../arch/x86/lib/x86-opcode-map.txt >/dev/null) || \ 20 - (echo "Warning: Intel PT: x86 instruction decoder map file at 'tools/perf/util/intel-pt-decoder/x86-opcode-map.txt' differs from latest version at 'arch/x86/lib/x86-opcode-map.txt'" >&2)) && \ 21 - ((diff -B util/intel-pt-decoder/gen-insn-attr-x86.awk ../../arch/x86/tools/gen-insn-attr-x86.awk >/dev/null) || \ 22 - (echo "Warning: Intel PT: x86 instruction decoder script at 'tools/perf/util/intel-pt-decoder/gen-insn-attr-x86.awk' differs from latest version at 'arch/x86/tools/gen-insn-attr-x86.awk'" >&2)) && \ 23 - ((diff -B -I'^#include' util/intel-pt-decoder/insn.h ../../arch/x86/include/asm/insn.h >/dev/null) || \ 24 - (echo "Warning: Intel PT: x86 instruction decoder header at 'tools/perf/util/intel-pt-decoder/insn.h' differs from latest version at 'arch/x86/include/asm/insn.h'" >&2)) && \ 25 - ((diff -B -I'^#include' util/intel-pt-decoder/inat.h ../../arch/x86/include/asm/inat.h >/dev/null) || \ 26 - (echo "Warning: Intel PT: x86 instruction decoder header at 'tools/perf/util/intel-pt-decoder/inat.h' differs from latest version at 'arch/x86/include/asm/inat.h'" >&2)) && \ 27 - ((diff -B -I'^#include' util/intel-pt-decoder/inat_types.h ../../arch/x86/include/asm/inat_types.h >/dev/null) || \ 28 - (echo "Warning: Intel PT: x86 instruction decoder header at 'tools/perf/util/intel-pt-decoder/inat_types.h' differs from latest version at 'arch/x86/include/asm/inat_types.h'" >&2)))) || true 29 13 $(call rule_mkdir) 30 14 $(call if_changed_dep,cc_o_c) 31 15
-392
tools/perf/util/intel-pt-decoder/gen-insn-attr-x86.awk
··· 1 - #!/bin/awk -f 2 - # SPDX-License-Identifier: GPL-2.0 3 - # gen-insn-attr-x86.awk: Instruction attribute table generator 4 - # Written by Masami Hiramatsu <mhiramat@redhat.com> 5 - # 6 - # Usage: awk -f gen-insn-attr-x86.awk x86-opcode-map.txt > inat-tables.c 7 - 8 - # Awk implementation sanity check 9 - function check_awk_implement() { 10 - if (sprintf("%x", 0) != "0") 11 - return "Your awk has a printf-format problem." 12 - return "" 13 - } 14 - 15 - # Clear working vars 16 - function clear_vars() { 17 - delete table 18 - delete lptable2 19 - delete lptable1 20 - delete lptable3 21 - eid = -1 # escape id 22 - gid = -1 # group id 23 - aid = -1 # AVX id 24 - tname = "" 25 - } 26 - 27 - BEGIN { 28 - # Implementation error checking 29 - awkchecked = check_awk_implement() 30 - if (awkchecked != "") { 31 - print "Error: " awkchecked > "/dev/stderr" 32 - print "Please try to use gawk." > "/dev/stderr" 33 - exit 1 34 - } 35 - 36 - # Setup generating tables 37 - print "/* x86 opcode map generated from x86-opcode-map.txt */" 38 - print "/* Do not change this code. */\n" 39 - ggid = 1 40 - geid = 1 41 - gaid = 0 42 - delete etable 43 - delete gtable 44 - delete atable 45 - 46 - opnd_expr = "^[A-Za-z/]" 47 - ext_expr = "^\\(" 48 - sep_expr = "^\\|$" 49 - group_expr = "^Grp[0-9A-Za-z]+" 50 - 51 - imm_expr = "^[IJAOL][a-z]" 52 - imm_flag["Ib"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" 53 - imm_flag["Jb"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" 54 - imm_flag["Iw"] = "INAT_MAKE_IMM(INAT_IMM_WORD)" 55 - imm_flag["Id"] = "INAT_MAKE_IMM(INAT_IMM_DWORD)" 56 - imm_flag["Iq"] = "INAT_MAKE_IMM(INAT_IMM_QWORD)" 57 - imm_flag["Ap"] = "INAT_MAKE_IMM(INAT_IMM_PTR)" 58 - imm_flag["Iz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)" 59 - imm_flag["Jz"] = "INAT_MAKE_IMM(INAT_IMM_VWORD32)" 60 - imm_flag["Iv"] = "INAT_MAKE_IMM(INAT_IMM_VWORD)" 61 - imm_flag["Ob"] = "INAT_MOFFSET" 62 - imm_flag["Ov"] = "INAT_MOFFSET" 63 - imm_flag["Lx"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)" 64 - 65 - modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])" 66 - force64_expr = "\\([df]64\\)" 67 - rex_expr = "^REX(\\.[XRWB]+)*" 68 - fpu_expr = "^ESC" # TODO 69 - 70 - lprefix1_expr = "\\((66|!F3)\\)" 71 - lprefix2_expr = "\\(F3\\)" 72 - lprefix3_expr = "\\((F2|!F3|66\\&F2)\\)" 73 - lprefix_expr = "\\((66|F2|F3)\\)" 74 - max_lprefix = 4 75 - 76 - # All opcodes starting with lower-case 'v', 'k' or with (v1) superscript 77 - # accepts VEX prefix 78 - vexok_opcode_expr = "^[vk].*" 79 - vexok_expr = "\\(v1\\)" 80 - # All opcodes with (v) superscript supports *only* VEX prefix 81 - vexonly_expr = "\\(v\\)" 82 - # All opcodes with (ev) superscript supports *only* EVEX prefix 83 - evexonly_expr = "\\(ev\\)" 84 - 85 - prefix_expr = "\\(Prefix\\)" 86 - prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ" 87 - prefix_num["REPNE"] = "INAT_PFX_REPNE" 88 - prefix_num["REP/REPE"] = "INAT_PFX_REPE" 89 - prefix_num["XACQUIRE"] = "INAT_PFX_REPNE" 90 - prefix_num["XRELEASE"] = "INAT_PFX_REPE" 91 - prefix_num["LOCK"] = "INAT_PFX_LOCK" 92 - prefix_num["SEG=CS"] = "INAT_PFX_CS" 93 - prefix_num["SEG=DS"] = "INAT_PFX_DS" 94 - prefix_num["SEG=ES"] = "INAT_PFX_ES" 95 - prefix_num["SEG=FS"] = "INAT_PFX_FS" 96 - prefix_num["SEG=GS"] = "INAT_PFX_GS" 97 - prefix_num["SEG=SS"] = "INAT_PFX_SS" 98 - prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ" 99 - prefix_num["VEX+1byte"] = "INAT_PFX_VEX2" 100 - prefix_num["VEX+2byte"] = "INAT_PFX_VEX3" 101 - prefix_num["EVEX"] = "INAT_PFX_EVEX" 102 - 103 - clear_vars() 104 - } 105 - 106 - function semantic_error(msg) { 107 - print "Semantic error at " NR ": " msg > "/dev/stderr" 108 - exit 1 109 - } 110 - 111 - function debug(msg) { 112 - print "DEBUG: " msg 113 - } 114 - 115 - function array_size(arr, i,c) { 116 - c = 0 117 - for (i in arr) 118 - c++ 119 - return c 120 - } 121 - 122 - /^Table:/ { 123 - print "/* " $0 " */" 124 - if (tname != "") 125 - semantic_error("Hit Table: before EndTable:."); 126 - } 127 - 128 - /^Referrer:/ { 129 - if (NF != 1) { 130 - # escape opcode table 131 - ref = "" 132 - for (i = 2; i <= NF; i++) 133 - ref = ref $i 134 - eid = escape[ref] 135 - tname = sprintf("inat_escape_table_%d", eid) 136 - } 137 - } 138 - 139 - /^AVXcode:/ { 140 - if (NF != 1) { 141 - # AVX/escape opcode table 142 - aid = $2 143 - if (gaid <= aid) 144 - gaid = aid + 1 145 - if (tname == "") # AVX only opcode table 146 - tname = sprintf("inat_avx_table_%d", $2) 147 - } 148 - if (aid == -1 && eid == -1) # primary opcode table 149 - tname = "inat_primary_table" 150 - } 151 - 152 - /^GrpTable:/ { 153 - print "/* " $0 " */" 154 - if (!($2 in group)) 155 - semantic_error("No group: " $2 ) 156 - gid = group[$2] 157 - tname = "inat_group_table_" gid 158 - } 159 - 160 - function print_table(tbl,name,fmt,n) 161 - { 162 - print "const insn_attr_t " name " = {" 163 - for (i = 0; i < n; i++) { 164 - id = sprintf(fmt, i) 165 - if (tbl[id]) 166 - print " [" id "] = " tbl[id] "," 167 - } 168 - print "};" 169 - } 170 - 171 - /^EndTable/ { 172 - if (gid != -1) { 173 - # print group tables 174 - if (array_size(table) != 0) { 175 - print_table(table, tname "[INAT_GROUP_TABLE_SIZE]", 176 - "0x%x", 8) 177 - gtable[gid,0] = tname 178 - } 179 - if (array_size(lptable1) != 0) { 180 - print_table(lptable1, tname "_1[INAT_GROUP_TABLE_SIZE]", 181 - "0x%x", 8) 182 - gtable[gid,1] = tname "_1" 183 - } 184 - if (array_size(lptable2) != 0) { 185 - print_table(lptable2, tname "_2[INAT_GROUP_TABLE_SIZE]", 186 - "0x%x", 8) 187 - gtable[gid,2] = tname "_2" 188 - } 189 - if (array_size(lptable3) != 0) { 190 - print_table(lptable3, tname "_3[INAT_GROUP_TABLE_SIZE]", 191 - "0x%x", 8) 192 - gtable[gid,3] = tname "_3" 193 - } 194 - } else { 195 - # print primary/escaped tables 196 - if (array_size(table) != 0) { 197 - print_table(table, tname "[INAT_OPCODE_TABLE_SIZE]", 198 - "0x%02x", 256) 199 - etable[eid,0] = tname 200 - if (aid >= 0) 201 - atable[aid,0] = tname 202 - } 203 - if (array_size(lptable1) != 0) { 204 - print_table(lptable1,tname "_1[INAT_OPCODE_TABLE_SIZE]", 205 - "0x%02x", 256) 206 - etable[eid,1] = tname "_1" 207 - if (aid >= 0) 208 - atable[aid,1] = tname "_1" 209 - } 210 - if (array_size(lptable2) != 0) { 211 - print_table(lptable2,tname "_2[INAT_OPCODE_TABLE_SIZE]", 212 - "0x%02x", 256) 213 - etable[eid,2] = tname "_2" 214 - if (aid >= 0) 215 - atable[aid,2] = tname "_2" 216 - } 217 - if (array_size(lptable3) != 0) { 218 - print_table(lptable3,tname "_3[INAT_OPCODE_TABLE_SIZE]", 219 - "0x%02x", 256) 220 - etable[eid,3] = tname "_3" 221 - if (aid >= 0) 222 - atable[aid,3] = tname "_3" 223 - } 224 - } 225 - print "" 226 - clear_vars() 227 - } 228 - 229 - function add_flags(old,new) { 230 - if (old && new) 231 - return old " | " new 232 - else if (old) 233 - return old 234 - else 235 - return new 236 - } 237 - 238 - # convert operands to flags. 239 - function convert_operands(count,opnd, i,j,imm,mod) 240 - { 241 - imm = null 242 - mod = null 243 - for (j = 1; j <= count; j++) { 244 - i = opnd[j] 245 - if (match(i, imm_expr) == 1) { 246 - if (!imm_flag[i]) 247 - semantic_error("Unknown imm opnd: " i) 248 - if (imm) { 249 - if (i != "Ib") 250 - semantic_error("Second IMM error") 251 - imm = add_flags(imm, "INAT_SCNDIMM") 252 - } else 253 - imm = imm_flag[i] 254 - } else if (match(i, modrm_expr)) 255 - mod = "INAT_MODRM" 256 - } 257 - return add_flags(imm, mod) 258 - } 259 - 260 - /^[0-9a-f]+\:/ { 261 - if (NR == 1) 262 - next 263 - # get index 264 - idx = "0x" substr($1, 1, index($1,":") - 1) 265 - if (idx in table) 266 - semantic_error("Redefine " idx " in " tname) 267 - 268 - # check if escaped opcode 269 - if ("escape" == $2) { 270 - if ($3 != "#") 271 - semantic_error("No escaped name") 272 - ref = "" 273 - for (i = 4; i <= NF; i++) 274 - ref = ref $i 275 - if (ref in escape) 276 - semantic_error("Redefine escape (" ref ")") 277 - escape[ref] = geid 278 - geid++ 279 - table[idx] = "INAT_MAKE_ESCAPE(" escape[ref] ")" 280 - next 281 - } 282 - 283 - variant = null 284 - # converts 285 - i = 2 286 - while (i <= NF) { 287 - opcode = $(i++) 288 - delete opnds 289 - ext = null 290 - flags = null 291 - opnd = null 292 - # parse one opcode 293 - if (match($i, opnd_expr)) { 294 - opnd = $i 295 - count = split($(i++), opnds, ",") 296 - flags = convert_operands(count, opnds) 297 - } 298 - if (match($i, ext_expr)) 299 - ext = $(i++) 300 - if (match($i, sep_expr)) 301 - i++ 302 - else if (i < NF) 303 - semantic_error($i " is not a separator") 304 - 305 - # check if group opcode 306 - if (match(opcode, group_expr)) { 307 - if (!(opcode in group)) { 308 - group[opcode] = ggid 309 - ggid++ 310 - } 311 - flags = add_flags(flags, "INAT_MAKE_GROUP(" group[opcode] ")") 312 - } 313 - # check force(or default) 64bit 314 - if (match(ext, force64_expr)) 315 - flags = add_flags(flags, "INAT_FORCE64") 316 - 317 - # check REX prefix 318 - if (match(opcode, rex_expr)) 319 - flags = add_flags(flags, "INAT_MAKE_PREFIX(INAT_PFX_REX)") 320 - 321 - # check coprocessor escape : TODO 322 - if (match(opcode, fpu_expr)) 323 - flags = add_flags(flags, "INAT_MODRM") 324 - 325 - # check VEX codes 326 - if (match(ext, evexonly_expr)) 327 - flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY") 328 - else if (match(ext, vexonly_expr)) 329 - flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY") 330 - else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr)) 331 - flags = add_flags(flags, "INAT_VEXOK") 332 - 333 - # check prefixes 334 - if (match(ext, prefix_expr)) { 335 - if (!prefix_num[opcode]) 336 - semantic_error("Unknown prefix: " opcode) 337 - flags = add_flags(flags, "INAT_MAKE_PREFIX(" prefix_num[opcode] ")") 338 - } 339 - if (length(flags) == 0) 340 - continue 341 - # check if last prefix 342 - if (match(ext, lprefix1_expr)) { 343 - lptable1[idx] = add_flags(lptable1[idx],flags) 344 - variant = "INAT_VARIANT" 345 - } 346 - if (match(ext, lprefix2_expr)) { 347 - lptable2[idx] = add_flags(lptable2[idx],flags) 348 - variant = "INAT_VARIANT" 349 - } 350 - if (match(ext, lprefix3_expr)) { 351 - lptable3[idx] = add_flags(lptable3[idx],flags) 352 - variant = "INAT_VARIANT" 353 - } 354 - if (!match(ext, lprefix_expr)){ 355 - table[idx] = add_flags(table[idx],flags) 356 - } 357 - } 358 - if (variant) 359 - table[idx] = add_flags(table[idx],variant) 360 - } 361 - 362 - END { 363 - if (awkchecked != "") 364 - exit 1 365 - # print escape opcode map's array 366 - print "/* Escape opcode map array */" 367 - print "const insn_attr_t * const inat_escape_tables[INAT_ESC_MAX + 1]" \ 368 - "[INAT_LSTPFX_MAX + 1] = {" 369 - for (i = 0; i < geid; i++) 370 - for (j = 0; j < max_lprefix; j++) 371 - if (etable[i,j]) 372 - print " ["i"]["j"] = "etable[i,j]"," 373 - print "};\n" 374 - # print group opcode map's array 375 - print "/* Group opcode map array */" 376 - print "const insn_attr_t * const inat_group_tables[INAT_GRP_MAX + 1]"\ 377 - "[INAT_LSTPFX_MAX + 1] = {" 378 - for (i = 0; i < ggid; i++) 379 - for (j = 0; j < max_lprefix; j++) 380 - if (gtable[i,j]) 381 - print " ["i"]["j"] = "gtable[i,j]"," 382 - print "};\n" 383 - # print AVX opcode map's array 384 - print "/* AVX opcode map array */" 385 - print "const insn_attr_t * const inat_avx_tables[X86_VEX_M_MAX + 1]"\ 386 - "[INAT_LSTPFX_MAX + 1] = {" 387 - for (i = 0; i < gaid; i++) 388 - for (j = 0; j < max_lprefix; j++) 389 - if (atable[i,j]) 390 - print " ["i"]["j"] = "atable[i,j]"," 391 - print "};" 392 - }
-82
tools/perf/util/intel-pt-decoder/inat.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-or-later 2 - /* 3 - * x86 instruction attribute tables 4 - * 5 - * Written by Masami Hiramatsu <mhiramat@redhat.com> 6 - */ 7 - #include "insn.h" 8 - 9 - /* Attribute tables are generated from opcode map */ 10 - #include "inat-tables.c" 11 - 12 - /* Attribute search APIs */ 13 - insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode) 14 - { 15 - return inat_primary_table[opcode]; 16 - } 17 - 18 - int inat_get_last_prefix_id(insn_byte_t last_pfx) 19 - { 20 - insn_attr_t lpfx_attr; 21 - 22 - lpfx_attr = inat_get_opcode_attribute(last_pfx); 23 - return inat_last_prefix_id(lpfx_attr); 24 - } 25 - 26 - insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, int lpfx_id, 27 - insn_attr_t esc_attr) 28 - { 29 - const insn_attr_t *table; 30 - int n; 31 - 32 - n = inat_escape_id(esc_attr); 33 - 34 - table = inat_escape_tables[n][0]; 35 - if (!table) 36 - return 0; 37 - if (inat_has_variant(table[opcode]) && lpfx_id) { 38 - table = inat_escape_tables[n][lpfx_id]; 39 - if (!table) 40 - return 0; 41 - } 42 - return table[opcode]; 43 - } 44 - 45 - insn_attr_t inat_get_group_attribute(insn_byte_t modrm, int lpfx_id, 46 - insn_attr_t grp_attr) 47 - { 48 - const insn_attr_t *table; 49 - int n; 50 - 51 - n = inat_group_id(grp_attr); 52 - 53 - table = inat_group_tables[n][0]; 54 - if (!table) 55 - return inat_group_common_attribute(grp_attr); 56 - if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && lpfx_id) { 57 - table = inat_group_tables[n][lpfx_id]; 58 - if (!table) 59 - return inat_group_common_attribute(grp_attr); 60 - } 61 - return table[X86_MODRM_REG(modrm)] | 62 - inat_group_common_attribute(grp_attr); 63 - } 64 - 65 - insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, insn_byte_t vex_m, 66 - insn_byte_t vex_p) 67 - { 68 - const insn_attr_t *table; 69 - if (vex_m > X86_VEX_M_MAX || vex_p > INAT_LSTPFX_MAX) 70 - return 0; 71 - /* At first, this checks the master table */ 72 - table = inat_avx_tables[vex_m][0]; 73 - if (!table) 74 - return 0; 75 - if (!inat_is_group(table[opcode]) && vex_p) { 76 - /* If this is not a group, get attribute directly */ 77 - table = inat_avx_tables[vex_m][vex_p]; 78 - if (!table) 79 - return 0; 80 - } 81 - return table[opcode]; 82 - }
-230
tools/perf/util/intel-pt-decoder/inat.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 - #ifndef _ASM_X86_INAT_H 3 - #define _ASM_X86_INAT_H 4 - /* 5 - * x86 instruction attributes 6 - * 7 - * Written by Masami Hiramatsu <mhiramat@redhat.com> 8 - */ 9 - #include "inat_types.h" 10 - 11 - /* 12 - * Internal bits. Don't use bitmasks directly, because these bits are 13 - * unstable. You should use checking functions. 14 - */ 15 - 16 - #define INAT_OPCODE_TABLE_SIZE 256 17 - #define INAT_GROUP_TABLE_SIZE 8 18 - 19 - /* Legacy last prefixes */ 20 - #define INAT_PFX_OPNDSZ 1 /* 0x66 */ /* LPFX1 */ 21 - #define INAT_PFX_REPE 2 /* 0xF3 */ /* LPFX2 */ 22 - #define INAT_PFX_REPNE 3 /* 0xF2 */ /* LPFX3 */ 23 - /* Other Legacy prefixes */ 24 - #define INAT_PFX_LOCK 4 /* 0xF0 */ 25 - #define INAT_PFX_CS 5 /* 0x2E */ 26 - #define INAT_PFX_DS 6 /* 0x3E */ 27 - #define INAT_PFX_ES 7 /* 0x26 */ 28 - #define INAT_PFX_FS 8 /* 0x64 */ 29 - #define INAT_PFX_GS 9 /* 0x65 */ 30 - #define INAT_PFX_SS 10 /* 0x36 */ 31 - #define INAT_PFX_ADDRSZ 11 /* 0x67 */ 32 - /* x86-64 REX prefix */ 33 - #define INAT_PFX_REX 12 /* 0x4X */ 34 - /* AVX VEX prefixes */ 35 - #define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */ 36 - #define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */ 37 - #define INAT_PFX_EVEX 15 /* EVEX prefix */ 38 - 39 - #define INAT_LSTPFX_MAX 3 40 - #define INAT_LGCPFX_MAX 11 41 - 42 - /* Immediate size */ 43 - #define INAT_IMM_BYTE 1 44 - #define INAT_IMM_WORD 2 45 - #define INAT_IMM_DWORD 3 46 - #define INAT_IMM_QWORD 4 47 - #define INAT_IMM_PTR 5 48 - #define INAT_IMM_VWORD32 6 49 - #define INAT_IMM_VWORD 7 50 - 51 - /* Legacy prefix */ 52 - #define INAT_PFX_OFFS 0 53 - #define INAT_PFX_BITS 4 54 - #define INAT_PFX_MAX ((1 << INAT_PFX_BITS) - 1) 55 - #define INAT_PFX_MASK (INAT_PFX_MAX << INAT_PFX_OFFS) 56 - /* Escape opcodes */ 57 - #define INAT_ESC_OFFS (INAT_PFX_OFFS + INAT_PFX_BITS) 58 - #define INAT_ESC_BITS 2 59 - #define INAT_ESC_MAX ((1 << INAT_ESC_BITS) - 1) 60 - #define INAT_ESC_MASK (INAT_ESC_MAX << INAT_ESC_OFFS) 61 - /* Group opcodes (1-16) */ 62 - #define INAT_GRP_OFFS (INAT_ESC_OFFS + INAT_ESC_BITS) 63 - #define INAT_GRP_BITS 5 64 - #define INAT_GRP_MAX ((1 << INAT_GRP_BITS) - 1) 65 - #define INAT_GRP_MASK (INAT_GRP_MAX << INAT_GRP_OFFS) 66 - /* Immediates */ 67 - #define INAT_IMM_OFFS (INAT_GRP_OFFS + INAT_GRP_BITS) 68 - #define INAT_IMM_BITS 3 69 - #define INAT_IMM_MASK (((1 << INAT_IMM_BITS) - 1) << INAT_IMM_OFFS) 70 - /* Flags */ 71 - #define INAT_FLAG_OFFS (INAT_IMM_OFFS + INAT_IMM_BITS) 72 - #define INAT_MODRM (1 << (INAT_FLAG_OFFS)) 73 - #define INAT_FORCE64 (1 << (INAT_FLAG_OFFS + 1)) 74 - #define INAT_SCNDIMM (1 << (INAT_FLAG_OFFS + 2)) 75 - #define INAT_MOFFSET (1 << (INAT_FLAG_OFFS + 3)) 76 - #define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4)) 77 - #define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5)) 78 - #define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6)) 79 - #define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7)) 80 - /* Attribute making macros for attribute tables */ 81 - #define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS) 82 - #define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS) 83 - #define INAT_MAKE_GROUP(grp) ((grp << INAT_GRP_OFFS) | INAT_MODRM) 84 - #define INAT_MAKE_IMM(imm) (imm << INAT_IMM_OFFS) 85 - 86 - /* Identifiers for segment registers */ 87 - #define INAT_SEG_REG_IGNORE 0 88 - #define INAT_SEG_REG_DEFAULT 1 89 - #define INAT_SEG_REG_CS 2 90 - #define INAT_SEG_REG_SS 3 91 - #define INAT_SEG_REG_DS 4 92 - #define INAT_SEG_REG_ES 5 93 - #define INAT_SEG_REG_FS 6 94 - #define INAT_SEG_REG_GS 7 95 - 96 - /* Attribute search APIs */ 97 - extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode); 98 - extern int inat_get_last_prefix_id(insn_byte_t last_pfx); 99 - extern insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, 100 - int lpfx_id, 101 - insn_attr_t esc_attr); 102 - extern insn_attr_t inat_get_group_attribute(insn_byte_t modrm, 103 - int lpfx_id, 104 - insn_attr_t esc_attr); 105 - extern insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, 106 - insn_byte_t vex_m, 107 - insn_byte_t vex_pp); 108 - 109 - /* Attribute checking functions */ 110 - static inline int inat_is_legacy_prefix(insn_attr_t attr) 111 - { 112 - attr &= INAT_PFX_MASK; 113 - return attr && attr <= INAT_LGCPFX_MAX; 114 - } 115 - 116 - static inline int inat_is_address_size_prefix(insn_attr_t attr) 117 - { 118 - return (attr & INAT_PFX_MASK) == INAT_PFX_ADDRSZ; 119 - } 120 - 121 - static inline int inat_is_operand_size_prefix(insn_attr_t attr) 122 - { 123 - return (attr & INAT_PFX_MASK) == INAT_PFX_OPNDSZ; 124 - } 125 - 126 - static inline int inat_is_rex_prefix(insn_attr_t attr) 127 - { 128 - return (attr & INAT_PFX_MASK) == INAT_PFX_REX; 129 - } 130 - 131 - static inline int inat_last_prefix_id(insn_attr_t attr) 132 - { 133 - if ((attr & INAT_PFX_MASK) > INAT_LSTPFX_MAX) 134 - return 0; 135 - else 136 - return attr & INAT_PFX_MASK; 137 - } 138 - 139 - static inline int inat_is_vex_prefix(insn_attr_t attr) 140 - { 141 - attr &= INAT_PFX_MASK; 142 - return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3 || 143 - attr == INAT_PFX_EVEX; 144 - } 145 - 146 - static inline int inat_is_evex_prefix(insn_attr_t attr) 147 - { 148 - return (attr & INAT_PFX_MASK) == INAT_PFX_EVEX; 149 - } 150 - 151 - static inline int inat_is_vex3_prefix(insn_attr_t attr) 152 - { 153 - return (attr & INAT_PFX_MASK) == INAT_PFX_VEX3; 154 - } 155 - 156 - static inline int inat_is_escape(insn_attr_t attr) 157 - { 158 - return attr & INAT_ESC_MASK; 159 - } 160 - 161 - static inline int inat_escape_id(insn_attr_t attr) 162 - { 163 - return (attr & INAT_ESC_MASK) >> INAT_ESC_OFFS; 164 - } 165 - 166 - static inline int inat_is_group(insn_attr_t attr) 167 - { 168 - return attr & INAT_GRP_MASK; 169 - } 170 - 171 - static inline int inat_group_id(insn_attr_t attr) 172 - { 173 - return (attr & INAT_GRP_MASK) >> INAT_GRP_OFFS; 174 - } 175 - 176 - static inline int inat_group_common_attribute(insn_attr_t attr) 177 - { 178 - return attr & ~INAT_GRP_MASK; 179 - } 180 - 181 - static inline int inat_has_immediate(insn_attr_t attr) 182 - { 183 - return attr & INAT_IMM_MASK; 184 - } 185 - 186 - static inline int inat_immediate_size(insn_attr_t attr) 187 - { 188 - return (attr & INAT_IMM_MASK) >> INAT_IMM_OFFS; 189 - } 190 - 191 - static inline int inat_has_modrm(insn_attr_t attr) 192 - { 193 - return attr & INAT_MODRM; 194 - } 195 - 196 - static inline int inat_is_force64(insn_attr_t attr) 197 - { 198 - return attr & INAT_FORCE64; 199 - } 200 - 201 - static inline int inat_has_second_immediate(insn_attr_t attr) 202 - { 203 - return attr & INAT_SCNDIMM; 204 - } 205 - 206 - static inline int inat_has_moffset(insn_attr_t attr) 207 - { 208 - return attr & INAT_MOFFSET; 209 - } 210 - 211 - static inline int inat_has_variant(insn_attr_t attr) 212 - { 213 - return attr & INAT_VARIANT; 214 - } 215 - 216 - static inline int inat_accept_vex(insn_attr_t attr) 217 - { 218 - return attr & INAT_VEXOK; 219 - } 220 - 221 - static inline int inat_must_vex(insn_attr_t attr) 222 - { 223 - return attr & (INAT_VEXONLY | INAT_EVEXONLY); 224 - } 225 - 226 - static inline int inat_must_evex(insn_attr_t attr) 227 - { 228 - return attr & INAT_EVEXONLY; 229 - } 230 - #endif
-15
tools/perf/util/intel-pt-decoder/inat_types.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 - #ifndef _ASM_X86_INAT_TYPES_H 3 - #define _ASM_X86_INAT_TYPES_H 4 - /* 5 - * x86 instruction attributes 6 - * 7 - * Written by Masami Hiramatsu <mhiramat@redhat.com> 8 - */ 9 - 10 - /* Instruction attributes */ 11 - typedef unsigned int insn_attr_t; 12 - typedef unsigned char insn_byte_t; 13 - typedef signed int insn_value_t; 14 - 15 - #endif
-593
tools/perf/util/intel-pt-decoder/insn.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-or-later 2 - /* 3 - * x86 instruction analysis 4 - * 5 - * Copyright (C) IBM Corporation, 2002, 2004, 2009 6 - */ 7 - 8 - #ifdef __KERNEL__ 9 - #include <linux/string.h> 10 - #else 11 - #include <string.h> 12 - #endif 13 - #include "inat.h" 14 - #include "insn.h" 15 - 16 - /* Verify next sizeof(t) bytes can be on the same instruction */ 17 - #define validate_next(t, insn, n) \ 18 - ((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr) 19 - 20 - #define __get_next(t, insn) \ 21 - ({ t r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; }) 22 - 23 - #define __peek_nbyte_next(t, insn, n) \ 24 - ({ t r = *(t*)((insn)->next_byte + n); r; }) 25 - 26 - #define get_next(t, insn) \ 27 - ({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); }) 28 - 29 - #define peek_nbyte_next(t, insn, n) \ 30 - ({ if (unlikely(!validate_next(t, insn, n))) goto err_out; __peek_nbyte_next(t, insn, n); }) 31 - 32 - #define peek_next(t, insn) peek_nbyte_next(t, insn, 0) 33 - 34 - /** 35 - * insn_init() - initialize struct insn 36 - * @insn: &struct insn to be initialized 37 - * @kaddr: address (in kernel memory) of instruction (or copy thereof) 38 - * @x86_64: !0 for 64-bit kernel or 64-bit app 39 - */ 40 - void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64) 41 - { 42 - /* 43 - * Instructions longer than MAX_INSN_SIZE (15 bytes) are invalid 44 - * even if the input buffer is long enough to hold them. 45 - */ 46 - if (buf_len > MAX_INSN_SIZE) 47 - buf_len = MAX_INSN_SIZE; 48 - 49 - memset(insn, 0, sizeof(*insn)); 50 - insn->kaddr = kaddr; 51 - insn->end_kaddr = kaddr + buf_len; 52 - insn->next_byte = kaddr; 53 - insn->x86_64 = x86_64 ? 1 : 0; 54 - insn->opnd_bytes = 4; 55 - if (x86_64) 56 - insn->addr_bytes = 8; 57 - else 58 - insn->addr_bytes = 4; 59 - } 60 - 61 - /** 62 - * insn_get_prefixes - scan x86 instruction prefix bytes 63 - * @insn: &struct insn containing instruction 64 - * 65 - * Populates the @insn->prefixes bitmap, and updates @insn->next_byte 66 - * to point to the (first) opcode. No effect if @insn->prefixes.got 67 - * is already set. 68 - */ 69 - void insn_get_prefixes(struct insn *insn) 70 - { 71 - struct insn_field *prefixes = &insn->prefixes; 72 - insn_attr_t attr; 73 - insn_byte_t b, lb; 74 - int i, nb; 75 - 76 - if (prefixes->got) 77 - return; 78 - 79 - nb = 0; 80 - lb = 0; 81 - b = peek_next(insn_byte_t, insn); 82 - attr = inat_get_opcode_attribute(b); 83 - while (inat_is_legacy_prefix(attr)) { 84 - /* Skip if same prefix */ 85 - for (i = 0; i < nb; i++) 86 - if (prefixes->bytes[i] == b) 87 - goto found; 88 - if (nb == 4) 89 - /* Invalid instruction */ 90 - break; 91 - prefixes->bytes[nb++] = b; 92 - if (inat_is_address_size_prefix(attr)) { 93 - /* address size switches 2/4 or 4/8 */ 94 - if (insn->x86_64) 95 - insn->addr_bytes ^= 12; 96 - else 97 - insn->addr_bytes ^= 6; 98 - } else if (inat_is_operand_size_prefix(attr)) { 99 - /* oprand size switches 2/4 */ 100 - insn->opnd_bytes ^= 6; 101 - } 102 - found: 103 - prefixes->nbytes++; 104 - insn->next_byte++; 105 - lb = b; 106 - b = peek_next(insn_byte_t, insn); 107 - attr = inat_get_opcode_attribute(b); 108 - } 109 - /* Set the last prefix */ 110 - if (lb && lb != insn->prefixes.bytes[3]) { 111 - if (unlikely(insn->prefixes.bytes[3])) { 112 - /* Swap the last prefix */ 113 - b = insn->prefixes.bytes[3]; 114 - for (i = 0; i < nb; i++) 115 - if (prefixes->bytes[i] == lb) 116 - prefixes->bytes[i] = b; 117 - } 118 - insn->prefixes.bytes[3] = lb; 119 - } 120 - 121 - /* Decode REX prefix */ 122 - if (insn->x86_64) { 123 - b = peek_next(insn_byte_t, insn); 124 - attr = inat_get_opcode_attribute(b); 125 - if (inat_is_rex_prefix(attr)) { 126 - insn->rex_prefix.value = b; 127 - insn->rex_prefix.nbytes = 1; 128 - insn->next_byte++; 129 - if (X86_REX_W(b)) 130 - /* REX.W overrides opnd_size */ 131 - insn->opnd_bytes = 8; 132 - } 133 - } 134 - insn->rex_prefix.got = 1; 135 - 136 - /* Decode VEX prefix */ 137 - b = peek_next(insn_byte_t, insn); 138 - attr = inat_get_opcode_attribute(b); 139 - if (inat_is_vex_prefix(attr)) { 140 - insn_byte_t b2 = peek_nbyte_next(insn_byte_t, insn, 1); 141 - if (!insn->x86_64) { 142 - /* 143 - * In 32-bits mode, if the [7:6] bits (mod bits of 144 - * ModRM) on the second byte are not 11b, it is 145 - * LDS or LES or BOUND. 146 - */ 147 - if (X86_MODRM_MOD(b2) != 3) 148 - goto vex_end; 149 - } 150 - insn->vex_prefix.bytes[0] = b; 151 - insn->vex_prefix.bytes[1] = b2; 152 - if (inat_is_evex_prefix(attr)) { 153 - b2 = peek_nbyte_next(insn_byte_t, insn, 2); 154 - insn->vex_prefix.bytes[2] = b2; 155 - b2 = peek_nbyte_next(insn_byte_t, insn, 3); 156 - insn->vex_prefix.bytes[3] = b2; 157 - insn->vex_prefix.nbytes = 4; 158 - insn->next_byte += 4; 159 - if (insn->x86_64 && X86_VEX_W(b2)) 160 - /* VEX.W overrides opnd_size */ 161 - insn->opnd_bytes = 8; 162 - } else if (inat_is_vex3_prefix(attr)) { 163 - b2 = peek_nbyte_next(insn_byte_t, insn, 2); 164 - insn->vex_prefix.bytes[2] = b2; 165 - insn->vex_prefix.nbytes = 3; 166 - insn->next_byte += 3; 167 - if (insn->x86_64 && X86_VEX_W(b2)) 168 - /* VEX.W overrides opnd_size */ 169 - insn->opnd_bytes = 8; 170 - } else { 171 - /* 172 - * For VEX2, fake VEX3-like byte#2. 173 - * Makes it easier to decode vex.W, vex.vvvv, 174 - * vex.L and vex.pp. Masking with 0x7f sets vex.W == 0. 175 - */ 176 - insn->vex_prefix.bytes[2] = b2 & 0x7f; 177 - insn->vex_prefix.nbytes = 2; 178 - insn->next_byte += 2; 179 - } 180 - } 181 - vex_end: 182 - insn->vex_prefix.got = 1; 183 - 184 - prefixes->got = 1; 185 - 186 - err_out: 187 - return; 188 - } 189 - 190 - /** 191 - * insn_get_opcode - collect opcode(s) 192 - * @insn: &struct insn containing instruction 193 - * 194 - * Populates @insn->opcode, updates @insn->next_byte to point past the 195 - * opcode byte(s), and set @insn->attr (except for groups). 196 - * If necessary, first collects any preceding (prefix) bytes. 197 - * Sets @insn->opcode.value = opcode1. No effect if @insn->opcode.got 198 - * is already 1. 199 - */ 200 - void insn_get_opcode(struct insn *insn) 201 - { 202 - struct insn_field *opcode = &insn->opcode; 203 - insn_byte_t op; 204 - int pfx_id; 205 - if (opcode->got) 206 - return; 207 - if (!insn->prefixes.got) 208 - insn_get_prefixes(insn); 209 - 210 - /* Get first opcode */ 211 - op = get_next(insn_byte_t, insn); 212 - opcode->bytes[0] = op; 213 - opcode->nbytes = 1; 214 - 215 - /* Check if there is VEX prefix or not */ 216 - if (insn_is_avx(insn)) { 217 - insn_byte_t m, p; 218 - m = insn_vex_m_bits(insn); 219 - p = insn_vex_p_bits(insn); 220 - insn->attr = inat_get_avx_attribute(op, m, p); 221 - if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) || 222 - (!inat_accept_vex(insn->attr) && 223 - !inat_is_group(insn->attr))) 224 - insn->attr = 0; /* This instruction is bad */ 225 - goto end; /* VEX has only 1 byte for opcode */ 226 - } 227 - 228 - insn->attr = inat_get_opcode_attribute(op); 229 - while (inat_is_escape(insn->attr)) { 230 - /* Get escaped opcode */ 231 - op = get_next(insn_byte_t, insn); 232 - opcode->bytes[opcode->nbytes++] = op; 233 - pfx_id = insn_last_prefix_id(insn); 234 - insn->attr = inat_get_escape_attribute(op, pfx_id, insn->attr); 235 - } 236 - if (inat_must_vex(insn->attr)) 237 - insn->attr = 0; /* This instruction is bad */ 238 - end: 239 - opcode->got = 1; 240 - 241 - err_out: 242 - return; 243 - } 244 - 245 - /** 246 - * insn_get_modrm - collect ModRM byte, if any 247 - * @insn: &struct insn containing instruction 248 - * 249 - * Populates @insn->modrm and updates @insn->next_byte to point past the 250 - * ModRM byte, if any. If necessary, first collects the preceding bytes 251 - * (prefixes and opcode(s)). No effect if @insn->modrm.got is already 1. 252 - */ 253 - void insn_get_modrm(struct insn *insn) 254 - { 255 - struct insn_field *modrm = &insn->modrm; 256 - insn_byte_t pfx_id, mod; 257 - if (modrm->got) 258 - return; 259 - if (!insn->opcode.got) 260 - insn_get_opcode(insn); 261 - 262 - if (inat_has_modrm(insn->attr)) { 263 - mod = get_next(insn_byte_t, insn); 264 - modrm->value = mod; 265 - modrm->nbytes = 1; 266 - if (inat_is_group(insn->attr)) { 267 - pfx_id = insn_last_prefix_id(insn); 268 - insn->attr = inat_get_group_attribute(mod, pfx_id, 269 - insn->attr); 270 - if (insn_is_avx(insn) && !inat_accept_vex(insn->attr)) 271 - insn->attr = 0; /* This is bad */ 272 - } 273 - } 274 - 275 - if (insn->x86_64 && inat_is_force64(insn->attr)) 276 - insn->opnd_bytes = 8; 277 - modrm->got = 1; 278 - 279 - err_out: 280 - return; 281 - } 282 - 283 - 284 - /** 285 - * insn_rip_relative() - Does instruction use RIP-relative addressing mode? 286 - * @insn: &struct insn containing instruction 287 - * 288 - * If necessary, first collects the instruction up to and including the 289 - * ModRM byte. No effect if @insn->x86_64 is 0. 290 - */ 291 - int insn_rip_relative(struct insn *insn) 292 - { 293 - struct insn_field *modrm = &insn->modrm; 294 - 295 - if (!insn->x86_64) 296 - return 0; 297 - if (!modrm->got) 298 - insn_get_modrm(insn); 299 - /* 300 - * For rip-relative instructions, the mod field (top 2 bits) 301 - * is zero and the r/m field (bottom 3 bits) is 0x5. 302 - */ 303 - return (modrm->nbytes && (modrm->value & 0xc7) == 0x5); 304 - } 305 - 306 - /** 307 - * insn_get_sib() - Get the SIB byte of instruction 308 - * @insn: &struct insn containing instruction 309 - * 310 - * If necessary, first collects the instruction up to and including the 311 - * ModRM byte. 312 - */ 313 - void insn_get_sib(struct insn *insn) 314 - { 315 - insn_byte_t modrm; 316 - 317 - if (insn->sib.got) 318 - return; 319 - if (!insn->modrm.got) 320 - insn_get_modrm(insn); 321 - if (insn->modrm.nbytes) { 322 - modrm = (insn_byte_t)insn->modrm.value; 323 - if (insn->addr_bytes != 2 && 324 - X86_MODRM_MOD(modrm) != 3 && X86_MODRM_RM(modrm) == 4) { 325 - insn->sib.value = get_next(insn_byte_t, insn); 326 - insn->sib.nbytes = 1; 327 - } 328 - } 329 - insn->sib.got = 1; 330 - 331 - err_out: 332 - return; 333 - } 334 - 335 - 336 - /** 337 - * insn_get_displacement() - Get the displacement of instruction 338 - * @insn: &struct insn containing instruction 339 - * 340 - * If necessary, first collects the instruction up to and including the 341 - * SIB byte. 342 - * Displacement value is sign-expanded. 343 - */ 344 - void insn_get_displacement(struct insn *insn) 345 - { 346 - insn_byte_t mod, rm, base; 347 - 348 - if (insn->displacement.got) 349 - return; 350 - if (!insn->sib.got) 351 - insn_get_sib(insn); 352 - if (insn->modrm.nbytes) { 353 - /* 354 - * Interpreting the modrm byte: 355 - * mod = 00 - no displacement fields (exceptions below) 356 - * mod = 01 - 1-byte displacement field 357 - * mod = 10 - displacement field is 4 bytes, or 2 bytes if 358 - * address size = 2 (0x67 prefix in 32-bit mode) 359 - * mod = 11 - no memory operand 360 - * 361 - * If address size = 2... 362 - * mod = 00, r/m = 110 - displacement field is 2 bytes 363 - * 364 - * If address size != 2... 365 - * mod != 11, r/m = 100 - SIB byte exists 366 - * mod = 00, SIB base = 101 - displacement field is 4 bytes 367 - * mod = 00, r/m = 101 - rip-relative addressing, displacement 368 - * field is 4 bytes 369 - */ 370 - mod = X86_MODRM_MOD(insn->modrm.value); 371 - rm = X86_MODRM_RM(insn->modrm.value); 372 - base = X86_SIB_BASE(insn->sib.value); 373 - if (mod == 3) 374 - goto out; 375 - if (mod == 1) { 376 - insn->displacement.value = get_next(signed char, insn); 377 - insn->displacement.nbytes = 1; 378 - } else if (insn->addr_bytes == 2) { 379 - if ((mod == 0 && rm == 6) || mod == 2) { 380 - insn->displacement.value = 381 - get_next(short, insn); 382 - insn->displacement.nbytes = 2; 383 - } 384 - } else { 385 - if ((mod == 0 && rm == 5) || mod == 2 || 386 - (mod == 0 && base == 5)) { 387 - insn->displacement.value = get_next(int, insn); 388 - insn->displacement.nbytes = 4; 389 - } 390 - } 391 - } 392 - out: 393 - insn->displacement.got = 1; 394 - 395 - err_out: 396 - return; 397 - } 398 - 399 - /* Decode moffset16/32/64. Return 0 if failed */ 400 - static int __get_moffset(struct insn *insn) 401 - { 402 - switch (insn->addr_bytes) { 403 - case 2: 404 - insn->moffset1.value = get_next(short, insn); 405 - insn->moffset1.nbytes = 2; 406 - break; 407 - case 4: 408 - insn->moffset1.value = get_next(int, insn); 409 - insn->moffset1.nbytes = 4; 410 - break; 411 - case 8: 412 - insn->moffset1.value = get_next(int, insn); 413 - insn->moffset1.nbytes = 4; 414 - insn->moffset2.value = get_next(int, insn); 415 - insn->moffset2.nbytes = 4; 416 - break; 417 - default: /* opnd_bytes must be modified manually */ 418 - goto err_out; 419 - } 420 - insn->moffset1.got = insn->moffset2.got = 1; 421 - 422 - return 1; 423 - 424 - err_out: 425 - return 0; 426 - } 427 - 428 - /* Decode imm v32(Iz). Return 0 if failed */ 429 - static int __get_immv32(struct insn *insn) 430 - { 431 - switch (insn->opnd_bytes) { 432 - case 2: 433 - insn->immediate.value = get_next(short, insn); 434 - insn->immediate.nbytes = 2; 435 - break; 436 - case 4: 437 - case 8: 438 - insn->immediate.value = get_next(int, insn); 439 - insn->immediate.nbytes = 4; 440 - break; 441 - default: /* opnd_bytes must be modified manually */ 442 - goto err_out; 443 - } 444 - 445 - return 1; 446 - 447 - err_out: 448 - return 0; 449 - } 450 - 451 - /* Decode imm v64(Iv/Ov), Return 0 if failed */ 452 - static int __get_immv(struct insn *insn) 453 - { 454 - switch (insn->opnd_bytes) { 455 - case 2: 456 - insn->immediate1.value = get_next(short, insn); 457 - insn->immediate1.nbytes = 2; 458 - break; 459 - case 4: 460 - insn->immediate1.value = get_next(int, insn); 461 - insn->immediate1.nbytes = 4; 462 - break; 463 - case 8: 464 - insn->immediate1.value = get_next(int, insn); 465 - insn->immediate1.nbytes = 4; 466 - insn->immediate2.value = get_next(int, insn); 467 - insn->immediate2.nbytes = 4; 468 - break; 469 - default: /* opnd_bytes must be modified manually */ 470 - goto err_out; 471 - } 472 - insn->immediate1.got = insn->immediate2.got = 1; 473 - 474 - return 1; 475 - err_out: 476 - return 0; 477 - } 478 - 479 - /* Decode ptr16:16/32(Ap) */ 480 - static int __get_immptr(struct insn *insn) 481 - { 482 - switch (insn->opnd_bytes) { 483 - case 2: 484 - insn->immediate1.value = get_next(short, insn); 485 - insn->immediate1.nbytes = 2; 486 - break; 487 - case 4: 488 - insn->immediate1.value = get_next(int, insn); 489 - insn->immediate1.nbytes = 4; 490 - break; 491 - case 8: 492 - /* ptr16:64 is not exist (no segment) */ 493 - return 0; 494 - default: /* opnd_bytes must be modified manually */ 495 - goto err_out; 496 - } 497 - insn->immediate2.value = get_next(unsigned short, insn); 498 - insn->immediate2.nbytes = 2; 499 - insn->immediate1.got = insn->immediate2.got = 1; 500 - 501 - return 1; 502 - err_out: 503 - return 0; 504 - } 505 - 506 - /** 507 - * insn_get_immediate() - Get the immediates of instruction 508 - * @insn: &struct insn containing instruction 509 - * 510 - * If necessary, first collects the instruction up to and including the 511 - * displacement bytes. 512 - * Basically, most of immediates are sign-expanded. Unsigned-value can be 513 - * get by bit masking with ((1 << (nbytes * 8)) - 1) 514 - */ 515 - void insn_get_immediate(struct insn *insn) 516 - { 517 - if (insn->immediate.got) 518 - return; 519 - if (!insn->displacement.got) 520 - insn_get_displacement(insn); 521 - 522 - if (inat_has_moffset(insn->attr)) { 523 - if (!__get_moffset(insn)) 524 - goto err_out; 525 - goto done; 526 - } 527 - 528 - if (!inat_has_immediate(insn->attr)) 529 - /* no immediates */ 530 - goto done; 531 - 532 - switch (inat_immediate_size(insn->attr)) { 533 - case INAT_IMM_BYTE: 534 - insn->immediate.value = get_next(signed char, insn); 535 - insn->immediate.nbytes = 1; 536 - break; 537 - case INAT_IMM_WORD: 538 - insn->immediate.value = get_next(short, insn); 539 - insn->immediate.nbytes = 2; 540 - break; 541 - case INAT_IMM_DWORD: 542 - insn->immediate.value = get_next(int, insn); 543 - insn->immediate.nbytes = 4; 544 - break; 545 - case INAT_IMM_QWORD: 546 - insn->immediate1.value = get_next(int, insn); 547 - insn->immediate1.nbytes = 4; 548 - insn->immediate2.value = get_next(int, insn); 549 - insn->immediate2.nbytes = 4; 550 - break; 551 - case INAT_IMM_PTR: 552 - if (!__get_immptr(insn)) 553 - goto err_out; 554 - break; 555 - case INAT_IMM_VWORD32: 556 - if (!__get_immv32(insn)) 557 - goto err_out; 558 - break; 559 - case INAT_IMM_VWORD: 560 - if (!__get_immv(insn)) 561 - goto err_out; 562 - break; 563 - default: 564 - /* Here, insn must have an immediate, but failed */ 565 - goto err_out; 566 - } 567 - if (inat_has_second_immediate(insn->attr)) { 568 - insn->immediate2.value = get_next(signed char, insn); 569 - insn->immediate2.nbytes = 1; 570 - } 571 - done: 572 - insn->immediate.got = 1; 573 - 574 - err_out: 575 - return; 576 - } 577 - 578 - /** 579 - * insn_get_length() - Get the length of instruction 580 - * @insn: &struct insn containing instruction 581 - * 582 - * If necessary, first collects the instruction up to and including the 583 - * immediates bytes. 584 - */ 585 - void insn_get_length(struct insn *insn) 586 - { 587 - if (insn->length) 588 - return; 589 - if (!insn->immediate.got) 590 - insn_get_immediate(insn); 591 - insn->length = (unsigned char)((unsigned long)insn->next_byte 592 - - (unsigned long)insn->kaddr); 593 - }
-216
tools/perf/util/intel-pt-decoder/insn.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 - #ifndef _ASM_X86_INSN_H 3 - #define _ASM_X86_INSN_H 4 - /* 5 - * x86 instruction analysis 6 - * 7 - * Copyright (C) IBM Corporation, 2009 8 - */ 9 - 10 - /* insn_attr_t is defined in inat.h */ 11 - #include "inat.h" 12 - 13 - struct insn_field { 14 - union { 15 - insn_value_t value; 16 - insn_byte_t bytes[4]; 17 - }; 18 - /* !0 if we've run insn_get_xxx() for this field */ 19 - unsigned char got; 20 - unsigned char nbytes; 21 - }; 22 - 23 - struct insn { 24 - struct insn_field prefixes; /* 25 - * Prefixes 26 - * prefixes.bytes[3]: last prefix 27 - */ 28 - struct insn_field rex_prefix; /* REX prefix */ 29 - struct insn_field vex_prefix; /* VEX prefix */ 30 - struct insn_field opcode; /* 31 - * opcode.bytes[0]: opcode1 32 - * opcode.bytes[1]: opcode2 33 - * opcode.bytes[2]: opcode3 34 - */ 35 - struct insn_field modrm; 36 - struct insn_field sib; 37 - struct insn_field displacement; 38 - union { 39 - struct insn_field immediate; 40 - struct insn_field moffset1; /* for 64bit MOV */ 41 - struct insn_field immediate1; /* for 64bit imm or off16/32 */ 42 - }; 43 - union { 44 - struct insn_field moffset2; /* for 64bit MOV */ 45 - struct insn_field immediate2; /* for 64bit imm or seg16 */ 46 - }; 47 - 48 - insn_attr_t attr; 49 - unsigned char opnd_bytes; 50 - unsigned char addr_bytes; 51 - unsigned char length; 52 - unsigned char x86_64; 53 - 54 - const insn_byte_t *kaddr; /* kernel address of insn to analyze */ 55 - const insn_byte_t *end_kaddr; /* kernel address of last insn in buffer */ 56 - const insn_byte_t *next_byte; 57 - }; 58 - 59 - #define MAX_INSN_SIZE 15 60 - 61 - #define X86_MODRM_MOD(modrm) (((modrm) & 0xc0) >> 6) 62 - #define X86_MODRM_REG(modrm) (((modrm) & 0x38) >> 3) 63 - #define X86_MODRM_RM(modrm) ((modrm) & 0x07) 64 - 65 - #define X86_SIB_SCALE(sib) (((sib) & 0xc0) >> 6) 66 - #define X86_SIB_INDEX(sib) (((sib) & 0x38) >> 3) 67 - #define X86_SIB_BASE(sib) ((sib) & 0x07) 68 - 69 - #define X86_REX_W(rex) ((rex) & 8) 70 - #define X86_REX_R(rex) ((rex) & 4) 71 - #define X86_REX_X(rex) ((rex) & 2) 72 - #define X86_REX_B(rex) ((rex) & 1) 73 - 74 - /* VEX bit flags */ 75 - #define X86_VEX_W(vex) ((vex) & 0x80) /* VEX3 Byte2 */ 76 - #define X86_VEX_R(vex) ((vex) & 0x80) /* VEX2/3 Byte1 */ 77 - #define X86_VEX_X(vex) ((vex) & 0x40) /* VEX3 Byte1 */ 78 - #define X86_VEX_B(vex) ((vex) & 0x20) /* VEX3 Byte1 */ 79 - #define X86_VEX_L(vex) ((vex) & 0x04) /* VEX3 Byte2, VEX2 Byte1 */ 80 - /* VEX bit fields */ 81 - #define X86_EVEX_M(vex) ((vex) & 0x03) /* EVEX Byte1 */ 82 - #define X86_VEX3_M(vex) ((vex) & 0x1f) /* VEX3 Byte1 */ 83 - #define X86_VEX2_M 1 /* VEX2.M always 1 */ 84 - #define X86_VEX_V(vex) (((vex) & 0x78) >> 3) /* VEX3 Byte2, VEX2 Byte1 */ 85 - #define X86_VEX_P(vex) ((vex) & 0x03) /* VEX3 Byte2, VEX2 Byte1 */ 86 - #define X86_VEX_M_MAX 0x1f /* VEX3.M Maximum value */ 87 - 88 - extern void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64); 89 - extern void insn_get_prefixes(struct insn *insn); 90 - extern void insn_get_opcode(struct insn *insn); 91 - extern void insn_get_modrm(struct insn *insn); 92 - extern void insn_get_sib(struct insn *insn); 93 - extern void insn_get_displacement(struct insn *insn); 94 - extern void insn_get_immediate(struct insn *insn); 95 - extern void insn_get_length(struct insn *insn); 96 - 97 - /* Attribute will be determined after getting ModRM (for opcode groups) */ 98 - static inline void insn_get_attribute(struct insn *insn) 99 - { 100 - insn_get_modrm(insn); 101 - } 102 - 103 - /* Instruction uses RIP-relative addressing */ 104 - extern int insn_rip_relative(struct insn *insn); 105 - 106 - /* Init insn for kernel text */ 107 - static inline void kernel_insn_init(struct insn *insn, 108 - const void *kaddr, int buf_len) 109 - { 110 - #ifdef CONFIG_X86_64 111 - insn_init(insn, kaddr, buf_len, 1); 112 - #else /* CONFIG_X86_32 */ 113 - insn_init(insn, kaddr, buf_len, 0); 114 - #endif 115 - } 116 - 117 - static inline int insn_is_avx(struct insn *insn) 118 - { 119 - if (!insn->prefixes.got) 120 - insn_get_prefixes(insn); 121 - return (insn->vex_prefix.value != 0); 122 - } 123 - 124 - static inline int insn_is_evex(struct insn *insn) 125 - { 126 - if (!insn->prefixes.got) 127 - insn_get_prefixes(insn); 128 - return (insn->vex_prefix.nbytes == 4); 129 - } 130 - 131 - /* Ensure this instruction is decoded completely */ 132 - static inline int insn_complete(struct insn *insn) 133 - { 134 - return insn->opcode.got && insn->modrm.got && insn->sib.got && 135 - insn->displacement.got && insn->immediate.got; 136 - } 137 - 138 - static inline insn_byte_t insn_vex_m_bits(struct insn *insn) 139 - { 140 - if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */ 141 - return X86_VEX2_M; 142 - else if (insn->vex_prefix.nbytes == 3) /* 3 bytes VEX */ 143 - return X86_VEX3_M(insn->vex_prefix.bytes[1]); 144 - else /* EVEX */ 145 - return X86_EVEX_M(insn->vex_prefix.bytes[1]); 146 - } 147 - 148 - static inline insn_byte_t insn_vex_p_bits(struct insn *insn) 149 - { 150 - if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */ 151 - return X86_VEX_P(insn->vex_prefix.bytes[1]); 152 - else 153 - return X86_VEX_P(insn->vex_prefix.bytes[2]); 154 - } 155 - 156 - /* Get the last prefix id from last prefix or VEX prefix */ 157 - static inline int insn_last_prefix_id(struct insn *insn) 158 - { 159 - if (insn_is_avx(insn)) 160 - return insn_vex_p_bits(insn); /* VEX_p is a SIMD prefix id */ 161 - 162 - if (insn->prefixes.bytes[3]) 163 - return inat_get_last_prefix_id(insn->prefixes.bytes[3]); 164 - 165 - return 0; 166 - } 167 - 168 - /* Offset of each field from kaddr */ 169 - static inline int insn_offset_rex_prefix(struct insn *insn) 170 - { 171 - return insn->prefixes.nbytes; 172 - } 173 - static inline int insn_offset_vex_prefix(struct insn *insn) 174 - { 175 - return insn_offset_rex_prefix(insn) + insn->rex_prefix.nbytes; 176 - } 177 - static inline int insn_offset_opcode(struct insn *insn) 178 - { 179 - return insn_offset_vex_prefix(insn) + insn->vex_prefix.nbytes; 180 - } 181 - static inline int insn_offset_modrm(struct insn *insn) 182 - { 183 - return insn_offset_opcode(insn) + insn->opcode.nbytes; 184 - } 185 - static inline int insn_offset_sib(struct insn *insn) 186 - { 187 - return insn_offset_modrm(insn) + insn->modrm.nbytes; 188 - } 189 - static inline int insn_offset_displacement(struct insn *insn) 190 - { 191 - return insn_offset_sib(insn) + insn->sib.nbytes; 192 - } 193 - static inline int insn_offset_immediate(struct insn *insn) 194 - { 195 - return insn_offset_displacement(insn) + insn->displacement.nbytes; 196 - } 197 - 198 - #define POP_SS_OPCODE 0x1f 199 - #define MOV_SREG_OPCODE 0x8e 200 - 201 - /* 202 - * Intel SDM Vol.3A 6.8.3 states; 203 - * "Any single-step trap that would be delivered following the MOV to SS 204 - * instruction or POP to SS instruction (because EFLAGS.TF is 1) is 205 - * suppressed." 206 - * This function returns true if @insn is MOV SS or POP SS. On these 207 - * instructions, single stepping is suppressed. 208 - */ 209 - static inline int insn_masking_exception(struct insn *insn) 210 - { 211 - return insn->opcode.bytes[0] == POP_SS_OPCODE || 212 - (insn->opcode.bytes[0] == MOV_SREG_OPCODE && 213 - X86_MODRM_REG(insn->modrm.bytes[0]) == 2); 214 - } 215 - 216 - #endif /* _ASM_X86_INSN_H */
+5 -5
tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c
··· 4 4 * Copyright (c) 2013-2014, Intel Corporation. 5 5 */ 6 6 7 + #include <linux/kernel.h> 7 8 #include <stdio.h> 8 9 #include <string.h> 9 10 #include <endian.h> 10 11 #include <byteswap.h> 12 + #include "../../../arch/x86/include/asm/insn.h" 13 + 14 + #include "../../../arch/x86/lib/inat.c" 15 + #include "../../../arch/x86/lib/insn.c" 11 16 12 17 #include "event.h" 13 - 14 - #include "insn.h" 15 - 16 - #include "inat.c" 17 - #include "insn.c" 18 18 19 19 #include "intel-pt-insn-decoder.h" 20 20 #include "dump-insn.h"
-1072
tools/perf/util/intel-pt-decoder/x86-opcode-map.txt
··· 1 - # x86 Opcode Maps 2 - # 3 - # This is (mostly) based on following documentations. 4 - # - Intel(R) 64 and IA-32 Architectures Software Developer's Manual Vol.2C 5 - # (#326018-047US, June 2013) 6 - # 7 - #<Opcode maps> 8 - # Table: table-name 9 - # Referrer: escaped-name 10 - # AVXcode: avx-code 11 - # opcode: mnemonic|GrpXXX [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...] 12 - # (or) 13 - # opcode: escape # escaped-name 14 - # EndTable 15 - # 16 - # mnemonics that begin with lowercase 'v' accept a VEX or EVEX prefix 17 - # mnemonics that begin with lowercase 'k' accept a VEX prefix 18 - # 19 - #<group maps> 20 - # GrpTable: GrpXXX 21 - # reg: mnemonic [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...] 22 - # EndTable 23 - # 24 - # AVX Superscripts 25 - # (ev): this opcode requires EVEX prefix. 26 - # (evo): this opcode is changed by EVEX prefix (EVEX opcode) 27 - # (v): this opcode requires VEX prefix. 28 - # (v1): this opcode only supports 128bit VEX. 29 - # 30 - # Last Prefix Superscripts 31 - # - (66): the last prefix is 0x66 32 - # - (F3): the last prefix is 0xF3 33 - # - (F2): the last prefix is 0xF2 34 - # - (!F3) : the last prefix is not 0xF3 (including non-last prefix case) 35 - # - (66&F2): Both 0x66 and 0xF2 prefixes are specified. 36 - 37 - Table: one byte opcode 38 - Referrer: 39 - AVXcode: 40 - # 0x00 - 0x0f 41 - 00: ADD Eb,Gb 42 - 01: ADD Ev,Gv 43 - 02: ADD Gb,Eb 44 - 03: ADD Gv,Ev 45 - 04: ADD AL,Ib 46 - 05: ADD rAX,Iz 47 - 06: PUSH ES (i64) 48 - 07: POP ES (i64) 49 - 08: OR Eb,Gb 50 - 09: OR Ev,Gv 51 - 0a: OR Gb,Eb 52 - 0b: OR Gv,Ev 53 - 0c: OR AL,Ib 54 - 0d: OR rAX,Iz 55 - 0e: PUSH CS (i64) 56 - 0f: escape # 2-byte escape 57 - # 0x10 - 0x1f 58 - 10: ADC Eb,Gb 59 - 11: ADC Ev,Gv 60 - 12: ADC Gb,Eb 61 - 13: ADC Gv,Ev 62 - 14: ADC AL,Ib 63 - 15: ADC rAX,Iz 64 - 16: PUSH SS (i64) 65 - 17: POP SS (i64) 66 - 18: SBB Eb,Gb 67 - 19: SBB Ev,Gv 68 - 1a: SBB Gb,Eb 69 - 1b: SBB Gv,Ev 70 - 1c: SBB AL,Ib 71 - 1d: SBB rAX,Iz 72 - 1e: PUSH DS (i64) 73 - 1f: POP DS (i64) 74 - # 0x20 - 0x2f 75 - 20: AND Eb,Gb 76 - 21: AND Ev,Gv 77 - 22: AND Gb,Eb 78 - 23: AND Gv,Ev 79 - 24: AND AL,Ib 80 - 25: AND rAx,Iz 81 - 26: SEG=ES (Prefix) 82 - 27: DAA (i64) 83 - 28: SUB Eb,Gb 84 - 29: SUB Ev,Gv 85 - 2a: SUB Gb,Eb 86 - 2b: SUB Gv,Ev 87 - 2c: SUB AL,Ib 88 - 2d: SUB rAX,Iz 89 - 2e: SEG=CS (Prefix) 90 - 2f: DAS (i64) 91 - # 0x30 - 0x3f 92 - 30: XOR Eb,Gb 93 - 31: XOR Ev,Gv 94 - 32: XOR Gb,Eb 95 - 33: XOR Gv,Ev 96 - 34: XOR AL,Ib 97 - 35: XOR rAX,Iz 98 - 36: SEG=SS (Prefix) 99 - 37: AAA (i64) 100 - 38: CMP Eb,Gb 101 - 39: CMP Ev,Gv 102 - 3a: CMP Gb,Eb 103 - 3b: CMP Gv,Ev 104 - 3c: CMP AL,Ib 105 - 3d: CMP rAX,Iz 106 - 3e: SEG=DS (Prefix) 107 - 3f: AAS (i64) 108 - # 0x40 - 0x4f 109 - 40: INC eAX (i64) | REX (o64) 110 - 41: INC eCX (i64) | REX.B (o64) 111 - 42: INC eDX (i64) | REX.X (o64) 112 - 43: INC eBX (i64) | REX.XB (o64) 113 - 44: INC eSP (i64) | REX.R (o64) 114 - 45: INC eBP (i64) | REX.RB (o64) 115 - 46: INC eSI (i64) | REX.RX (o64) 116 - 47: INC eDI (i64) | REX.RXB (o64) 117 - 48: DEC eAX (i64) | REX.W (o64) 118 - 49: DEC eCX (i64) | REX.WB (o64) 119 - 4a: DEC eDX (i64) | REX.WX (o64) 120 - 4b: DEC eBX (i64) | REX.WXB (o64) 121 - 4c: DEC eSP (i64) | REX.WR (o64) 122 - 4d: DEC eBP (i64) | REX.WRB (o64) 123 - 4e: DEC eSI (i64) | REX.WRX (o64) 124 - 4f: DEC eDI (i64) | REX.WRXB (o64) 125 - # 0x50 - 0x5f 126 - 50: PUSH rAX/r8 (d64) 127 - 51: PUSH rCX/r9 (d64) 128 - 52: PUSH rDX/r10 (d64) 129 - 53: PUSH rBX/r11 (d64) 130 - 54: PUSH rSP/r12 (d64) 131 - 55: PUSH rBP/r13 (d64) 132 - 56: PUSH rSI/r14 (d64) 133 - 57: PUSH rDI/r15 (d64) 134 - 58: POP rAX/r8 (d64) 135 - 59: POP rCX/r9 (d64) 136 - 5a: POP rDX/r10 (d64) 137 - 5b: POP rBX/r11 (d64) 138 - 5c: POP rSP/r12 (d64) 139 - 5d: POP rBP/r13 (d64) 140 - 5e: POP rSI/r14 (d64) 141 - 5f: POP rDI/r15 (d64) 142 - # 0x60 - 0x6f 143 - 60: PUSHA/PUSHAD (i64) 144 - 61: POPA/POPAD (i64) 145 - 62: BOUND Gv,Ma (i64) | EVEX (Prefix) 146 - 63: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64) 147 - 64: SEG=FS (Prefix) 148 - 65: SEG=GS (Prefix) 149 - 66: Operand-Size (Prefix) 150 - 67: Address-Size (Prefix) 151 - 68: PUSH Iz (d64) 152 - 69: IMUL Gv,Ev,Iz 153 - 6a: PUSH Ib (d64) 154 - 6b: IMUL Gv,Ev,Ib 155 - 6c: INS/INSB Yb,DX 156 - 6d: INS/INSW/INSD Yz,DX 157 - 6e: OUTS/OUTSB DX,Xb 158 - 6f: OUTS/OUTSW/OUTSD DX,Xz 159 - # 0x70 - 0x7f 160 - 70: JO Jb 161 - 71: JNO Jb 162 - 72: JB/JNAE/JC Jb 163 - 73: JNB/JAE/JNC Jb 164 - 74: JZ/JE Jb 165 - 75: JNZ/JNE Jb 166 - 76: JBE/JNA Jb 167 - 77: JNBE/JA Jb 168 - 78: JS Jb 169 - 79: JNS Jb 170 - 7a: JP/JPE Jb 171 - 7b: JNP/JPO Jb 172 - 7c: JL/JNGE Jb 173 - 7d: JNL/JGE Jb 174 - 7e: JLE/JNG Jb 175 - 7f: JNLE/JG Jb 176 - # 0x80 - 0x8f 177 - 80: Grp1 Eb,Ib (1A) 178 - 81: Grp1 Ev,Iz (1A) 179 - 82: Grp1 Eb,Ib (1A),(i64) 180 - 83: Grp1 Ev,Ib (1A) 181 - 84: TEST Eb,Gb 182 - 85: TEST Ev,Gv 183 - 86: XCHG Eb,Gb 184 - 87: XCHG Ev,Gv 185 - 88: MOV Eb,Gb 186 - 89: MOV Ev,Gv 187 - 8a: MOV Gb,Eb 188 - 8b: MOV Gv,Ev 189 - 8c: MOV Ev,Sw 190 - 8d: LEA Gv,M 191 - 8e: MOV Sw,Ew 192 - 8f: Grp1A (1A) | POP Ev (d64) 193 - # 0x90 - 0x9f 194 - 90: NOP | PAUSE (F3) | XCHG r8,rAX 195 - 91: XCHG rCX/r9,rAX 196 - 92: XCHG rDX/r10,rAX 197 - 93: XCHG rBX/r11,rAX 198 - 94: XCHG rSP/r12,rAX 199 - 95: XCHG rBP/r13,rAX 200 - 96: XCHG rSI/r14,rAX 201 - 97: XCHG rDI/r15,rAX 202 - 98: CBW/CWDE/CDQE 203 - 99: CWD/CDQ/CQO 204 - 9a: CALLF Ap (i64) 205 - 9b: FWAIT/WAIT 206 - 9c: PUSHF/D/Q Fv (d64) 207 - 9d: POPF/D/Q Fv (d64) 208 - 9e: SAHF 209 - 9f: LAHF 210 - # 0xa0 - 0xaf 211 - a0: MOV AL,Ob 212 - a1: MOV rAX,Ov 213 - a2: MOV Ob,AL 214 - a3: MOV Ov,rAX 215 - a4: MOVS/B Yb,Xb 216 - a5: MOVS/W/D/Q Yv,Xv 217 - a6: CMPS/B Xb,Yb 218 - a7: CMPS/W/D Xv,Yv 219 - a8: TEST AL,Ib 220 - a9: TEST rAX,Iz 221 - aa: STOS/B Yb,AL 222 - ab: STOS/W/D/Q Yv,rAX 223 - ac: LODS/B AL,Xb 224 - ad: LODS/W/D/Q rAX,Xv 225 - ae: SCAS/B AL,Yb 226 - # Note: The May 2011 Intel manual shows Xv for the second parameter of the 227 - # next instruction but Yv is correct 228 - af: SCAS/W/D/Q rAX,Yv 229 - # 0xb0 - 0xbf 230 - b0: MOV AL/R8L,Ib 231 - b1: MOV CL/R9L,Ib 232 - b2: MOV DL/R10L,Ib 233 - b3: MOV BL/R11L,Ib 234 - b4: MOV AH/R12L,Ib 235 - b5: MOV CH/R13L,Ib 236 - b6: MOV DH/R14L,Ib 237 - b7: MOV BH/R15L,Ib 238 - b8: MOV rAX/r8,Iv 239 - b9: MOV rCX/r9,Iv 240 - ba: MOV rDX/r10,Iv 241 - bb: MOV rBX/r11,Iv 242 - bc: MOV rSP/r12,Iv 243 - bd: MOV rBP/r13,Iv 244 - be: MOV rSI/r14,Iv 245 - bf: MOV rDI/r15,Iv 246 - # 0xc0 - 0xcf 247 - c0: Grp2 Eb,Ib (1A) 248 - c1: Grp2 Ev,Ib (1A) 249 - c2: RETN Iw (f64) 250 - c3: RETN 251 - c4: LES Gz,Mp (i64) | VEX+2byte (Prefix) 252 - c5: LDS Gz,Mp (i64) | VEX+1byte (Prefix) 253 - c6: Grp11A Eb,Ib (1A) 254 - c7: Grp11B Ev,Iz (1A) 255 - c8: ENTER Iw,Ib 256 - c9: LEAVE (d64) 257 - ca: RETF Iw 258 - cb: RETF 259 - cc: INT3 260 - cd: INT Ib 261 - ce: INTO (i64) 262 - cf: IRET/D/Q 263 - # 0xd0 - 0xdf 264 - d0: Grp2 Eb,1 (1A) 265 - d1: Grp2 Ev,1 (1A) 266 - d2: Grp2 Eb,CL (1A) 267 - d3: Grp2 Ev,CL (1A) 268 - d4: AAM Ib (i64) 269 - d5: AAD Ib (i64) 270 - d6: 271 - d7: XLAT/XLATB 272 - d8: ESC 273 - d9: ESC 274 - da: ESC 275 - db: ESC 276 - dc: ESC 277 - dd: ESC 278 - de: ESC 279 - df: ESC 280 - # 0xe0 - 0xef 281 - # Note: "forced64" is Intel CPU behavior: they ignore 0x66 prefix 282 - # in 64-bit mode. AMD CPUs accept 0x66 prefix, it causes RIP truncation 283 - # to 16 bits. In 32-bit mode, 0x66 is accepted by both Intel and AMD. 284 - e0: LOOPNE/LOOPNZ Jb (f64) 285 - e1: LOOPE/LOOPZ Jb (f64) 286 - e2: LOOP Jb (f64) 287 - e3: JrCXZ Jb (f64) 288 - e4: IN AL,Ib 289 - e5: IN eAX,Ib 290 - e6: OUT Ib,AL 291 - e7: OUT Ib,eAX 292 - # With 0x66 prefix in 64-bit mode, for AMD CPUs immediate offset 293 - # in "near" jumps and calls is 16-bit. For CALL, 294 - # push of return address is 16-bit wide, RSP is decremented by 2 295 - # but is not truncated to 16 bits, unlike RIP. 296 - e8: CALL Jz (f64) 297 - e9: JMP-near Jz (f64) 298 - ea: JMP-far Ap (i64) 299 - eb: JMP-short Jb (f64) 300 - ec: IN AL,DX 301 - ed: IN eAX,DX 302 - ee: OUT DX,AL 303 - ef: OUT DX,eAX 304 - # 0xf0 - 0xff 305 - f0: LOCK (Prefix) 306 - f1: 307 - f2: REPNE (Prefix) | XACQUIRE (Prefix) 308 - f3: REP/REPE (Prefix) | XRELEASE (Prefix) 309 - f4: HLT 310 - f5: CMC 311 - f6: Grp3_1 Eb (1A) 312 - f7: Grp3_2 Ev (1A) 313 - f8: CLC 314 - f9: STC 315 - fa: CLI 316 - fb: STI 317 - fc: CLD 318 - fd: STD 319 - fe: Grp4 (1A) 320 - ff: Grp5 (1A) 321 - EndTable 322 - 323 - Table: 2-byte opcode (0x0f) 324 - Referrer: 2-byte escape 325 - AVXcode: 1 326 - # 0x0f 0x00-0x0f 327 - 00: Grp6 (1A) 328 - 01: Grp7 (1A) 329 - 02: LAR Gv,Ew 330 - 03: LSL Gv,Ew 331 - 04: 332 - 05: SYSCALL (o64) 333 - 06: CLTS 334 - 07: SYSRET (o64) 335 - 08: INVD 336 - 09: WBINVD 337 - 0a: 338 - 0b: UD2 (1B) 339 - 0c: 340 - # AMD's prefetch group. Intel supports prefetchw(/1) only. 341 - 0d: GrpP 342 - 0e: FEMMS 343 - # 3DNow! uses the last imm byte as opcode extension. 344 - 0f: 3DNow! Pq,Qq,Ib 345 - # 0x0f 0x10-0x1f 346 - # NOTE: According to Intel SDM opcode map, vmovups and vmovupd has no operands 347 - # but it actually has operands. And also, vmovss and vmovsd only accept 128bit. 348 - # MOVSS/MOVSD has too many forms(3) on SDM. This map just shows a typical form. 349 - # Many AVX instructions lack v1 superscript, according to Intel AVX-Prgramming 350 - # Reference A.1 351 - 10: vmovups Vps,Wps | vmovupd Vpd,Wpd (66) | vmovss Vx,Hx,Wss (F3),(v1) | vmovsd Vx,Hx,Wsd (F2),(v1) 352 - 11: vmovups Wps,Vps | vmovupd Wpd,Vpd (66) | vmovss Wss,Hx,Vss (F3),(v1) | vmovsd Wsd,Hx,Vsd (F2),(v1) 353 - 12: vmovlps Vq,Hq,Mq (v1) | vmovhlps Vq,Hq,Uq (v1) | vmovlpd Vq,Hq,Mq (66),(v1) | vmovsldup Vx,Wx (F3) | vmovddup Vx,Wx (F2) 354 - 13: vmovlps Mq,Vq (v1) | vmovlpd Mq,Vq (66),(v1) 355 - 14: vunpcklps Vx,Hx,Wx | vunpcklpd Vx,Hx,Wx (66) 356 - 15: vunpckhps Vx,Hx,Wx | vunpckhpd Vx,Hx,Wx (66) 357 - 16: vmovhps Vdq,Hq,Mq (v1) | vmovlhps Vdq,Hq,Uq (v1) | vmovhpd Vdq,Hq,Mq (66),(v1) | vmovshdup Vx,Wx (F3) 358 - 17: vmovhps Mq,Vq (v1) | vmovhpd Mq,Vq (66),(v1) 359 - 18: Grp16 (1A) 360 - 19: 361 - # Intel SDM opcode map does not list MPX instructions. For now using Gv for 362 - # bnd registers and Ev for everything else is OK because the instruction 363 - # decoder does not use the information except as an indication that there is 364 - # a ModR/M byte. 365 - 1a: BNDCL Gv,Ev (F3) | BNDCU Gv,Ev (F2) | BNDMOV Gv,Ev (66) | BNDLDX Gv,Ev 366 - 1b: BNDCN Gv,Ev (F2) | BNDMOV Ev,Gv (66) | BNDMK Gv,Ev (F3) | BNDSTX Ev,Gv 367 - 1c: 368 - 1d: 369 - 1e: 370 - 1f: NOP Ev 371 - # 0x0f 0x20-0x2f 372 - 20: MOV Rd,Cd 373 - 21: MOV Rd,Dd 374 - 22: MOV Cd,Rd 375 - 23: MOV Dd,Rd 376 - 24: 377 - 25: 378 - 26: 379 - 27: 380 - 28: vmovaps Vps,Wps | vmovapd Vpd,Wpd (66) 381 - 29: vmovaps Wps,Vps | vmovapd Wpd,Vpd (66) 382 - 2a: cvtpi2ps Vps,Qpi | cvtpi2pd Vpd,Qpi (66) | vcvtsi2ss Vss,Hss,Ey (F3),(v1) | vcvtsi2sd Vsd,Hsd,Ey (F2),(v1) 383 - 2b: vmovntps Mps,Vps | vmovntpd Mpd,Vpd (66) 384 - 2c: cvttps2pi Ppi,Wps | cvttpd2pi Ppi,Wpd (66) | vcvttss2si Gy,Wss (F3),(v1) | vcvttsd2si Gy,Wsd (F2),(v1) 385 - 2d: cvtps2pi Ppi,Wps | cvtpd2pi Qpi,Wpd (66) | vcvtss2si Gy,Wss (F3),(v1) | vcvtsd2si Gy,Wsd (F2),(v1) 386 - 2e: vucomiss Vss,Wss (v1) | vucomisd Vsd,Wsd (66),(v1) 387 - 2f: vcomiss Vss,Wss (v1) | vcomisd Vsd,Wsd (66),(v1) 388 - # 0x0f 0x30-0x3f 389 - 30: WRMSR 390 - 31: RDTSC 391 - 32: RDMSR 392 - 33: RDPMC 393 - 34: SYSENTER 394 - 35: SYSEXIT 395 - 36: 396 - 37: GETSEC 397 - 38: escape # 3-byte escape 1 398 - 39: 399 - 3a: escape # 3-byte escape 2 400 - 3b: 401 - 3c: 402 - 3d: 403 - 3e: 404 - 3f: 405 - # 0x0f 0x40-0x4f 406 - 40: CMOVO Gv,Ev 407 - 41: CMOVNO Gv,Ev | kandw/q Vk,Hk,Uk | kandb/d Vk,Hk,Uk (66) 408 - 42: CMOVB/C/NAE Gv,Ev | kandnw/q Vk,Hk,Uk | kandnb/d Vk,Hk,Uk (66) 409 - 43: CMOVAE/NB/NC Gv,Ev 410 - 44: CMOVE/Z Gv,Ev | knotw/q Vk,Uk | knotb/d Vk,Uk (66) 411 - 45: CMOVNE/NZ Gv,Ev | korw/q Vk,Hk,Uk | korb/d Vk,Hk,Uk (66) 412 - 46: CMOVBE/NA Gv,Ev | kxnorw/q Vk,Hk,Uk | kxnorb/d Vk,Hk,Uk (66) 413 - 47: CMOVA/NBE Gv,Ev | kxorw/q Vk,Hk,Uk | kxorb/d Vk,Hk,Uk (66) 414 - 48: CMOVS Gv,Ev 415 - 49: CMOVNS Gv,Ev 416 - 4a: CMOVP/PE Gv,Ev | kaddw/q Vk,Hk,Uk | kaddb/d Vk,Hk,Uk (66) 417 - 4b: CMOVNP/PO Gv,Ev | kunpckbw Vk,Hk,Uk (66) | kunpckwd/dq Vk,Hk,Uk 418 - 4c: CMOVL/NGE Gv,Ev 419 - 4d: CMOVNL/GE Gv,Ev 420 - 4e: CMOVLE/NG Gv,Ev 421 - 4f: CMOVNLE/G Gv,Ev 422 - # 0x0f 0x50-0x5f 423 - 50: vmovmskps Gy,Ups | vmovmskpd Gy,Upd (66) 424 - 51: vsqrtps Vps,Wps | vsqrtpd Vpd,Wpd (66) | vsqrtss Vss,Hss,Wss (F3),(v1) | vsqrtsd Vsd,Hsd,Wsd (F2),(v1) 425 - 52: vrsqrtps Vps,Wps | vrsqrtss Vss,Hss,Wss (F3),(v1) 426 - 53: vrcpps Vps,Wps | vrcpss Vss,Hss,Wss (F3),(v1) 427 - 54: vandps Vps,Hps,Wps | vandpd Vpd,Hpd,Wpd (66) 428 - 55: vandnps Vps,Hps,Wps | vandnpd Vpd,Hpd,Wpd (66) 429 - 56: vorps Vps,Hps,Wps | vorpd Vpd,Hpd,Wpd (66) 430 - 57: vxorps Vps,Hps,Wps | vxorpd Vpd,Hpd,Wpd (66) 431 - 58: vaddps Vps,Hps,Wps | vaddpd Vpd,Hpd,Wpd (66) | vaddss Vss,Hss,Wss (F3),(v1) | vaddsd Vsd,Hsd,Wsd (F2),(v1) 432 - 59: vmulps Vps,Hps,Wps | vmulpd Vpd,Hpd,Wpd (66) | vmulss Vss,Hss,Wss (F3),(v1) | vmulsd Vsd,Hsd,Wsd (F2),(v1) 433 - 5a: vcvtps2pd Vpd,Wps | vcvtpd2ps Vps,Wpd (66) | vcvtss2sd Vsd,Hx,Wss (F3),(v1) | vcvtsd2ss Vss,Hx,Wsd (F2),(v1) 434 - 5b: vcvtdq2ps Vps,Wdq | vcvtqq2ps Vps,Wqq (evo) | vcvtps2dq Vdq,Wps (66) | vcvttps2dq Vdq,Wps (F3) 435 - 5c: vsubps Vps,Hps,Wps | vsubpd Vpd,Hpd,Wpd (66) | vsubss Vss,Hss,Wss (F3),(v1) | vsubsd Vsd,Hsd,Wsd (F2),(v1) 436 - 5d: vminps Vps,Hps,Wps | vminpd Vpd,Hpd,Wpd (66) | vminss Vss,Hss,Wss (F3),(v1) | vminsd Vsd,Hsd,Wsd (F2),(v1) 437 - 5e: vdivps Vps,Hps,Wps | vdivpd Vpd,Hpd,Wpd (66) | vdivss Vss,Hss,Wss (F3),(v1) | vdivsd Vsd,Hsd,Wsd (F2),(v1) 438 - 5f: vmaxps Vps,Hps,Wps | vmaxpd Vpd,Hpd,Wpd (66) | vmaxss Vss,Hss,Wss (F3),(v1) | vmaxsd Vsd,Hsd,Wsd (F2),(v1) 439 - # 0x0f 0x60-0x6f 440 - 60: punpcklbw Pq,Qd | vpunpcklbw Vx,Hx,Wx (66),(v1) 441 - 61: punpcklwd Pq,Qd | vpunpcklwd Vx,Hx,Wx (66),(v1) 442 - 62: punpckldq Pq,Qd | vpunpckldq Vx,Hx,Wx (66),(v1) 443 - 63: packsswb Pq,Qq | vpacksswb Vx,Hx,Wx (66),(v1) 444 - 64: pcmpgtb Pq,Qq | vpcmpgtb Vx,Hx,Wx (66),(v1) 445 - 65: pcmpgtw Pq,Qq | vpcmpgtw Vx,Hx,Wx (66),(v1) 446 - 66: pcmpgtd Pq,Qq | vpcmpgtd Vx,Hx,Wx (66),(v1) 447 - 67: packuswb Pq,Qq | vpackuswb Vx,Hx,Wx (66),(v1) 448 - 68: punpckhbw Pq,Qd | vpunpckhbw Vx,Hx,Wx (66),(v1) 449 - 69: punpckhwd Pq,Qd | vpunpckhwd Vx,Hx,Wx (66),(v1) 450 - 6a: punpckhdq Pq,Qd | vpunpckhdq Vx,Hx,Wx (66),(v1) 451 - 6b: packssdw Pq,Qd | vpackssdw Vx,Hx,Wx (66),(v1) 452 - 6c: vpunpcklqdq Vx,Hx,Wx (66),(v1) 453 - 6d: vpunpckhqdq Vx,Hx,Wx (66),(v1) 454 - 6e: movd/q Pd,Ey | vmovd/q Vy,Ey (66),(v1) 455 - 6f: movq Pq,Qq | vmovdqa Vx,Wx (66) | vmovdqa32/64 Vx,Wx (66),(evo) | vmovdqu Vx,Wx (F3) | vmovdqu32/64 Vx,Wx (F3),(evo) | vmovdqu8/16 Vx,Wx (F2),(ev) 456 - # 0x0f 0x70-0x7f 457 - 70: pshufw Pq,Qq,Ib | vpshufd Vx,Wx,Ib (66),(v1) | vpshufhw Vx,Wx,Ib (F3),(v1) | vpshuflw Vx,Wx,Ib (F2),(v1) 458 - 71: Grp12 (1A) 459 - 72: Grp13 (1A) 460 - 73: Grp14 (1A) 461 - 74: pcmpeqb Pq,Qq | vpcmpeqb Vx,Hx,Wx (66),(v1) 462 - 75: pcmpeqw Pq,Qq | vpcmpeqw Vx,Hx,Wx (66),(v1) 463 - 76: pcmpeqd Pq,Qq | vpcmpeqd Vx,Hx,Wx (66),(v1) 464 - # Note: Remove (v), because vzeroall and vzeroupper becomes emms without VEX. 465 - 77: emms | vzeroupper | vzeroall 466 - 78: VMREAD Ey,Gy | vcvttps2udq/pd2udq Vx,Wpd (evo) | vcvttsd2usi Gv,Wx (F2),(ev) | vcvttss2usi Gv,Wx (F3),(ev) | vcvttps2uqq/pd2uqq Vx,Wx (66),(ev) 467 - 79: VMWRITE Gy,Ey | vcvtps2udq/pd2udq Vx,Wpd (evo) | vcvtsd2usi Gv,Wx (F2),(ev) | vcvtss2usi Gv,Wx (F3),(ev) | vcvtps2uqq/pd2uqq Vx,Wx (66),(ev) 468 - 7a: vcvtudq2pd/uqq2pd Vpd,Wx (F3),(ev) | vcvtudq2ps/uqq2ps Vpd,Wx (F2),(ev) | vcvttps2qq/pd2qq Vx,Wx (66),(ev) 469 - 7b: vcvtusi2sd Vpd,Hpd,Ev (F2),(ev) | vcvtusi2ss Vps,Hps,Ev (F3),(ev) | vcvtps2qq/pd2qq Vx,Wx (66),(ev) 470 - 7c: vhaddpd Vpd,Hpd,Wpd (66) | vhaddps Vps,Hps,Wps (F2) 471 - 7d: vhsubpd Vpd,Hpd,Wpd (66) | vhsubps Vps,Hps,Wps (F2) 472 - 7e: movd/q Ey,Pd | vmovd/q Ey,Vy (66),(v1) | vmovq Vq,Wq (F3),(v1) 473 - 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) 474 - # 0x0f 0x80-0x8f 475 - # Note: "forced64" is Intel CPU behavior (see comment about CALL insn). 476 - 80: JO Jz (f64) 477 - 81: JNO Jz (f64) 478 - 82: JB/JC/JNAE Jz (f64) 479 - 83: JAE/JNB/JNC Jz (f64) 480 - 84: JE/JZ Jz (f64) 481 - 85: JNE/JNZ Jz (f64) 482 - 86: JBE/JNA Jz (f64) 483 - 87: JA/JNBE Jz (f64) 484 - 88: JS Jz (f64) 485 - 89: JNS Jz (f64) 486 - 8a: JP/JPE Jz (f64) 487 - 8b: JNP/JPO Jz (f64) 488 - 8c: JL/JNGE Jz (f64) 489 - 8d: JNL/JGE Jz (f64) 490 - 8e: JLE/JNG Jz (f64) 491 - 8f: JNLE/JG Jz (f64) 492 - # 0x0f 0x90-0x9f 493 - 90: SETO Eb | kmovw/q Vk,Wk | kmovb/d Vk,Wk (66) 494 - 91: SETNO Eb | kmovw/q Mv,Vk | kmovb/d Mv,Vk (66) 495 - 92: SETB/C/NAE Eb | kmovw Vk,Rv | kmovb Vk,Rv (66) | kmovq/d Vk,Rv (F2) 496 - 93: SETAE/NB/NC Eb | kmovw Gv,Uk | kmovb Gv,Uk (66) | kmovq/d Gv,Uk (F2) 497 - 94: SETE/Z Eb 498 - 95: SETNE/NZ Eb 499 - 96: SETBE/NA Eb 500 - 97: SETA/NBE Eb 501 - 98: SETS Eb | kortestw/q Vk,Uk | kortestb/d Vk,Uk (66) 502 - 99: SETNS Eb | ktestw/q Vk,Uk | ktestb/d Vk,Uk (66) 503 - 9a: SETP/PE Eb 504 - 9b: SETNP/PO Eb 505 - 9c: SETL/NGE Eb 506 - 9d: SETNL/GE Eb 507 - 9e: SETLE/NG Eb 508 - 9f: SETNLE/G Eb 509 - # 0x0f 0xa0-0xaf 510 - a0: PUSH FS (d64) 511 - a1: POP FS (d64) 512 - a2: CPUID 513 - a3: BT Ev,Gv 514 - a4: SHLD Ev,Gv,Ib 515 - a5: SHLD Ev,Gv,CL 516 - a6: GrpPDLK 517 - a7: GrpRNG 518 - a8: PUSH GS (d64) 519 - a9: POP GS (d64) 520 - aa: RSM 521 - ab: BTS Ev,Gv 522 - ac: SHRD Ev,Gv,Ib 523 - ad: SHRD Ev,Gv,CL 524 - ae: Grp15 (1A),(1C) 525 - af: IMUL Gv,Ev 526 - # 0x0f 0xb0-0xbf 527 - b0: CMPXCHG Eb,Gb 528 - b1: CMPXCHG Ev,Gv 529 - b2: LSS Gv,Mp 530 - b3: BTR Ev,Gv 531 - b4: LFS Gv,Mp 532 - b5: LGS Gv,Mp 533 - b6: MOVZX Gv,Eb 534 - b7: MOVZX Gv,Ew 535 - b8: JMPE (!F3) | POPCNT Gv,Ev (F3) 536 - b9: Grp10 (1A) 537 - ba: Grp8 Ev,Ib (1A) 538 - bb: BTC Ev,Gv 539 - bc: BSF Gv,Ev (!F3) | TZCNT Gv,Ev (F3) 540 - bd: BSR Gv,Ev (!F3) | LZCNT Gv,Ev (F3) 541 - be: MOVSX Gv,Eb 542 - bf: MOVSX Gv,Ew 543 - # 0x0f 0xc0-0xcf 544 - c0: XADD Eb,Gb 545 - c1: XADD Ev,Gv 546 - c2: vcmpps Vps,Hps,Wps,Ib | vcmppd Vpd,Hpd,Wpd,Ib (66) | vcmpss Vss,Hss,Wss,Ib (F3),(v1) | vcmpsd Vsd,Hsd,Wsd,Ib (F2),(v1) 547 - c3: movnti My,Gy 548 - c4: pinsrw Pq,Ry/Mw,Ib | vpinsrw Vdq,Hdq,Ry/Mw,Ib (66),(v1) 549 - c5: pextrw Gd,Nq,Ib | vpextrw Gd,Udq,Ib (66),(v1) 550 - c6: vshufps Vps,Hps,Wps,Ib | vshufpd Vpd,Hpd,Wpd,Ib (66) 551 - c7: Grp9 (1A) 552 - c8: BSWAP RAX/EAX/R8/R8D 553 - c9: BSWAP RCX/ECX/R9/R9D 554 - ca: BSWAP RDX/EDX/R10/R10D 555 - cb: BSWAP RBX/EBX/R11/R11D 556 - cc: BSWAP RSP/ESP/R12/R12D 557 - cd: BSWAP RBP/EBP/R13/R13D 558 - ce: BSWAP RSI/ESI/R14/R14D 559 - cf: BSWAP RDI/EDI/R15/R15D 560 - # 0x0f 0xd0-0xdf 561 - d0: vaddsubpd Vpd,Hpd,Wpd (66) | vaddsubps Vps,Hps,Wps (F2) 562 - d1: psrlw Pq,Qq | vpsrlw Vx,Hx,Wx (66),(v1) 563 - d2: psrld Pq,Qq | vpsrld Vx,Hx,Wx (66),(v1) 564 - d3: psrlq Pq,Qq | vpsrlq Vx,Hx,Wx (66),(v1) 565 - d4: paddq Pq,Qq | vpaddq Vx,Hx,Wx (66),(v1) 566 - d5: pmullw Pq,Qq | vpmullw Vx,Hx,Wx (66),(v1) 567 - d6: vmovq Wq,Vq (66),(v1) | movq2dq Vdq,Nq (F3) | movdq2q Pq,Uq (F2) 568 - d7: pmovmskb Gd,Nq | vpmovmskb Gd,Ux (66),(v1) 569 - d8: psubusb Pq,Qq | vpsubusb Vx,Hx,Wx (66),(v1) 570 - d9: psubusw Pq,Qq | vpsubusw Vx,Hx,Wx (66),(v1) 571 - da: pminub Pq,Qq | vpminub Vx,Hx,Wx (66),(v1) 572 - db: pand Pq,Qq | vpand Vx,Hx,Wx (66),(v1) | vpandd/q Vx,Hx,Wx (66),(evo) 573 - dc: paddusb Pq,Qq | vpaddusb Vx,Hx,Wx (66),(v1) 574 - dd: paddusw Pq,Qq | vpaddusw Vx,Hx,Wx (66),(v1) 575 - de: pmaxub Pq,Qq | vpmaxub Vx,Hx,Wx (66),(v1) 576 - df: pandn Pq,Qq | vpandn Vx,Hx,Wx (66),(v1) | vpandnd/q Vx,Hx,Wx (66),(evo) 577 - # 0x0f 0xe0-0xef 578 - e0: pavgb Pq,Qq | vpavgb Vx,Hx,Wx (66),(v1) 579 - e1: psraw Pq,Qq | vpsraw Vx,Hx,Wx (66),(v1) 580 - e2: psrad Pq,Qq | vpsrad Vx,Hx,Wx (66),(v1) 581 - e3: pavgw Pq,Qq | vpavgw Vx,Hx,Wx (66),(v1) 582 - e4: pmulhuw Pq,Qq | vpmulhuw Vx,Hx,Wx (66),(v1) 583 - e5: pmulhw Pq,Qq | vpmulhw Vx,Hx,Wx (66),(v1) 584 - e6: vcvttpd2dq Vx,Wpd (66) | vcvtdq2pd Vx,Wdq (F3) | vcvtdq2pd/qq2pd Vx,Wdq (F3),(evo) | vcvtpd2dq Vx,Wpd (F2) 585 - e7: movntq Mq,Pq | vmovntdq Mx,Vx (66) 586 - e8: psubsb Pq,Qq | vpsubsb Vx,Hx,Wx (66),(v1) 587 - e9: psubsw Pq,Qq | vpsubsw Vx,Hx,Wx (66),(v1) 588 - ea: pminsw Pq,Qq | vpminsw Vx,Hx,Wx (66),(v1) 589 - eb: por Pq,Qq | vpor Vx,Hx,Wx (66),(v1) | vpord/q Vx,Hx,Wx (66),(evo) 590 - ec: paddsb Pq,Qq | vpaddsb Vx,Hx,Wx (66),(v1) 591 - ed: paddsw Pq,Qq | vpaddsw Vx,Hx,Wx (66),(v1) 592 - ee: pmaxsw Pq,Qq | vpmaxsw Vx,Hx,Wx (66),(v1) 593 - ef: pxor Pq,Qq | vpxor Vx,Hx,Wx (66),(v1) | vpxord/q Vx,Hx,Wx (66),(evo) 594 - # 0x0f 0xf0-0xff 595 - f0: vlddqu Vx,Mx (F2) 596 - f1: psllw Pq,Qq | vpsllw Vx,Hx,Wx (66),(v1) 597 - f2: pslld Pq,Qq | vpslld Vx,Hx,Wx (66),(v1) 598 - f3: psllq Pq,Qq | vpsllq Vx,Hx,Wx (66),(v1) 599 - f4: pmuludq Pq,Qq | vpmuludq Vx,Hx,Wx (66),(v1) 600 - f5: pmaddwd Pq,Qq | vpmaddwd Vx,Hx,Wx (66),(v1) 601 - f6: psadbw Pq,Qq | vpsadbw Vx,Hx,Wx (66),(v1) 602 - f7: maskmovq Pq,Nq | vmaskmovdqu Vx,Ux (66),(v1) 603 - f8: psubb Pq,Qq | vpsubb Vx,Hx,Wx (66),(v1) 604 - f9: psubw Pq,Qq | vpsubw Vx,Hx,Wx (66),(v1) 605 - fa: psubd Pq,Qq | vpsubd Vx,Hx,Wx (66),(v1) 606 - fb: psubq Pq,Qq | vpsubq Vx,Hx,Wx (66),(v1) 607 - fc: paddb Pq,Qq | vpaddb Vx,Hx,Wx (66),(v1) 608 - fd: paddw Pq,Qq | vpaddw Vx,Hx,Wx (66),(v1) 609 - fe: paddd Pq,Qq | vpaddd Vx,Hx,Wx (66),(v1) 610 - ff: UD0 611 - EndTable 612 - 613 - Table: 3-byte opcode 1 (0x0f 0x38) 614 - Referrer: 3-byte escape 1 615 - AVXcode: 2 616 - # 0x0f 0x38 0x00-0x0f 617 - 00: pshufb Pq,Qq | vpshufb Vx,Hx,Wx (66),(v1) 618 - 01: phaddw Pq,Qq | vphaddw Vx,Hx,Wx (66),(v1) 619 - 02: phaddd Pq,Qq | vphaddd Vx,Hx,Wx (66),(v1) 620 - 03: phaddsw Pq,Qq | vphaddsw Vx,Hx,Wx (66),(v1) 621 - 04: pmaddubsw Pq,Qq | vpmaddubsw Vx,Hx,Wx (66),(v1) 622 - 05: phsubw Pq,Qq | vphsubw Vx,Hx,Wx (66),(v1) 623 - 06: phsubd Pq,Qq | vphsubd Vx,Hx,Wx (66),(v1) 624 - 07: phsubsw Pq,Qq | vphsubsw Vx,Hx,Wx (66),(v1) 625 - 08: psignb Pq,Qq | vpsignb Vx,Hx,Wx (66),(v1) 626 - 09: psignw Pq,Qq | vpsignw Vx,Hx,Wx (66),(v1) 627 - 0a: psignd Pq,Qq | vpsignd Vx,Hx,Wx (66),(v1) 628 - 0b: pmulhrsw Pq,Qq | vpmulhrsw Vx,Hx,Wx (66),(v1) 629 - 0c: vpermilps Vx,Hx,Wx (66),(v) 630 - 0d: vpermilpd Vx,Hx,Wx (66),(v) 631 - 0e: vtestps Vx,Wx (66),(v) 632 - 0f: vtestpd Vx,Wx (66),(v) 633 - # 0x0f 0x38 0x10-0x1f 634 - 10: pblendvb Vdq,Wdq (66) | vpsrlvw Vx,Hx,Wx (66),(evo) | vpmovuswb Wx,Vx (F3),(ev) 635 - 11: vpmovusdb Wx,Vd (F3),(ev) | vpsravw Vx,Hx,Wx (66),(ev) 636 - 12: vpmovusqb Wx,Vq (F3),(ev) | vpsllvw Vx,Hx,Wx (66),(ev) 637 - 13: vcvtph2ps Vx,Wx (66),(v) | vpmovusdw Wx,Vd (F3),(ev) 638 - 14: blendvps Vdq,Wdq (66) | vpmovusqw Wx,Vq (F3),(ev) | vprorvd/q Vx,Hx,Wx (66),(evo) 639 - 15: blendvpd Vdq,Wdq (66) | vpmovusqd Wx,Vq (F3),(ev) | vprolvd/q Vx,Hx,Wx (66),(evo) 640 - 16: vpermps Vqq,Hqq,Wqq (66),(v) | vpermps/d Vqq,Hqq,Wqq (66),(evo) 641 - 17: vptest Vx,Wx (66) 642 - 18: vbroadcastss Vx,Wd (66),(v) 643 - 19: vbroadcastsd Vqq,Wq (66),(v) | vbroadcastf32x2 Vqq,Wq (66),(evo) 644 - 1a: vbroadcastf128 Vqq,Mdq (66),(v) | vbroadcastf32x4/64x2 Vqq,Wq (66),(evo) 645 - 1b: vbroadcastf32x8/64x4 Vqq,Mdq (66),(ev) 646 - 1c: pabsb Pq,Qq | vpabsb Vx,Wx (66),(v1) 647 - 1d: pabsw Pq,Qq | vpabsw Vx,Wx (66),(v1) 648 - 1e: pabsd Pq,Qq | vpabsd Vx,Wx (66),(v1) 649 - 1f: vpabsq Vx,Wx (66),(ev) 650 - # 0x0f 0x38 0x20-0x2f 651 - 20: vpmovsxbw Vx,Ux/Mq (66),(v1) | vpmovswb Wx,Vx (F3),(ev) 652 - 21: vpmovsxbd Vx,Ux/Md (66),(v1) | vpmovsdb Wx,Vd (F3),(ev) 653 - 22: vpmovsxbq Vx,Ux/Mw (66),(v1) | vpmovsqb Wx,Vq (F3),(ev) 654 - 23: vpmovsxwd Vx,Ux/Mq (66),(v1) | vpmovsdw Wx,Vd (F3),(ev) 655 - 24: vpmovsxwq Vx,Ux/Md (66),(v1) | vpmovsqw Wx,Vq (F3),(ev) 656 - 25: vpmovsxdq Vx,Ux/Mq (66),(v1) | vpmovsqd Wx,Vq (F3),(ev) 657 - 26: vptestmb/w Vk,Hx,Wx (66),(ev) | vptestnmb/w Vk,Hx,Wx (F3),(ev) 658 - 27: vptestmd/q Vk,Hx,Wx (66),(ev) | vptestnmd/q Vk,Hx,Wx (F3),(ev) 659 - 28: vpmuldq Vx,Hx,Wx (66),(v1) | vpmovm2b/w Vx,Uk (F3),(ev) 660 - 29: vpcmpeqq Vx,Hx,Wx (66),(v1) | vpmovb2m/w2m Vk,Ux (F3),(ev) 661 - 2a: vmovntdqa Vx,Mx (66),(v1) | vpbroadcastmb2q Vx,Uk (F3),(ev) 662 - 2b: vpackusdw Vx,Hx,Wx (66),(v1) 663 - 2c: vmaskmovps Vx,Hx,Mx (66),(v) | vscalefps/d Vx,Hx,Wx (66),(evo) 664 - 2d: vmaskmovpd Vx,Hx,Mx (66),(v) | vscalefss/d Vx,Hx,Wx (66),(evo) 665 - 2e: vmaskmovps Mx,Hx,Vx (66),(v) 666 - 2f: vmaskmovpd Mx,Hx,Vx (66),(v) 667 - # 0x0f 0x38 0x30-0x3f 668 - 30: vpmovzxbw Vx,Ux/Mq (66),(v1) | vpmovwb Wx,Vx (F3),(ev) 669 - 31: vpmovzxbd Vx,Ux/Md (66),(v1) | vpmovdb Wx,Vd (F3),(ev) 670 - 32: vpmovzxbq Vx,Ux/Mw (66),(v1) | vpmovqb Wx,Vq (F3),(ev) 671 - 33: vpmovzxwd Vx,Ux/Mq (66),(v1) | vpmovdw Wx,Vd (F3),(ev) 672 - 34: vpmovzxwq Vx,Ux/Md (66),(v1) | vpmovqw Wx,Vq (F3),(ev) 673 - 35: vpmovzxdq Vx,Ux/Mq (66),(v1) | vpmovqd Wx,Vq (F3),(ev) 674 - 36: vpermd Vqq,Hqq,Wqq (66),(v) | vpermd/q Vqq,Hqq,Wqq (66),(evo) 675 - 37: vpcmpgtq Vx,Hx,Wx (66),(v1) 676 - 38: vpminsb Vx,Hx,Wx (66),(v1) | vpmovm2d/q Vx,Uk (F3),(ev) 677 - 39: vpminsd Vx,Hx,Wx (66),(v1) | vpminsd/q Vx,Hx,Wx (66),(evo) | vpmovd2m/q2m Vk,Ux (F3),(ev) 678 - 3a: vpminuw Vx,Hx,Wx (66),(v1) | vpbroadcastmw2d Vx,Uk (F3),(ev) 679 - 3b: vpminud Vx,Hx,Wx (66),(v1) | vpminud/q Vx,Hx,Wx (66),(evo) 680 - 3c: vpmaxsb Vx,Hx,Wx (66),(v1) 681 - 3d: vpmaxsd Vx,Hx,Wx (66),(v1) | vpmaxsd/q Vx,Hx,Wx (66),(evo) 682 - 3e: vpmaxuw Vx,Hx,Wx (66),(v1) 683 - 3f: vpmaxud Vx,Hx,Wx (66),(v1) | vpmaxud/q Vx,Hx,Wx (66),(evo) 684 - # 0x0f 0x38 0x40-0x8f 685 - 40: vpmulld Vx,Hx,Wx (66),(v1) | vpmulld/q Vx,Hx,Wx (66),(evo) 686 - 41: vphminposuw Vdq,Wdq (66),(v1) 687 - 42: vgetexpps/d Vx,Wx (66),(ev) 688 - 43: vgetexpss/d Vx,Hx,Wx (66),(ev) 689 - 44: vplzcntd/q Vx,Wx (66),(ev) 690 - 45: vpsrlvd/q Vx,Hx,Wx (66),(v) 691 - 46: vpsravd Vx,Hx,Wx (66),(v) | vpsravd/q Vx,Hx,Wx (66),(evo) 692 - 47: vpsllvd/q Vx,Hx,Wx (66),(v) 693 - # Skip 0x48-0x4b 694 - 4c: vrcp14ps/d Vpd,Wpd (66),(ev) 695 - 4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev) 696 - 4e: vrsqrt14ps/d Vpd,Wpd (66),(ev) 697 - 4f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev) 698 - # Skip 0x50-0x57 699 - 58: vpbroadcastd Vx,Wx (66),(v) 700 - 59: vpbroadcastq Vx,Wx (66),(v) | vbroadcasti32x2 Vx,Wx (66),(evo) 701 - 5a: vbroadcasti128 Vqq,Mdq (66),(v) | vbroadcasti32x4/64x2 Vx,Wx (66),(evo) 702 - 5b: vbroadcasti32x8/64x4 Vqq,Mdq (66),(ev) 703 - # Skip 0x5c-0x63 704 - 64: vpblendmd/q Vx,Hx,Wx (66),(ev) 705 - 65: vblendmps/d Vx,Hx,Wx (66),(ev) 706 - 66: vpblendmb/w Vx,Hx,Wx (66),(ev) 707 - # Skip 0x67-0x74 708 - 75: vpermi2b/w Vx,Hx,Wx (66),(ev) 709 - 76: vpermi2d/q Vx,Hx,Wx (66),(ev) 710 - 77: vpermi2ps/d Vx,Hx,Wx (66),(ev) 711 - 78: vpbroadcastb Vx,Wx (66),(v) 712 - 79: vpbroadcastw Vx,Wx (66),(v) 713 - 7a: vpbroadcastb Vx,Rv (66),(ev) 714 - 7b: vpbroadcastw Vx,Rv (66),(ev) 715 - 7c: vpbroadcastd/q Vx,Rv (66),(ev) 716 - 7d: vpermt2b/w Vx,Hx,Wx (66),(ev) 717 - 7e: vpermt2d/q Vx,Hx,Wx (66),(ev) 718 - 7f: vpermt2ps/d Vx,Hx,Wx (66),(ev) 719 - 80: INVEPT Gy,Mdq (66) 720 - 81: INVVPID Gy,Mdq (66) 721 - 82: INVPCID Gy,Mdq (66) 722 - 83: vpmultishiftqb Vx,Hx,Wx (66),(ev) 723 - 88: vexpandps/d Vpd,Wpd (66),(ev) 724 - 89: vpexpandd/q Vx,Wx (66),(ev) 725 - 8a: vcompressps/d Wx,Vx (66),(ev) 726 - 8b: vpcompressd/q Wx,Vx (66),(ev) 727 - 8c: vpmaskmovd/q Vx,Hx,Mx (66),(v) 728 - 8d: vpermb/w Vx,Hx,Wx (66),(ev) 729 - 8e: vpmaskmovd/q Mx,Vx,Hx (66),(v) 730 - # 0x0f 0x38 0x90-0xbf (FMA) 731 - 90: vgatherdd/q Vx,Hx,Wx (66),(v) | vpgatherdd/q Vx,Wx (66),(evo) 732 - 91: vgatherqd/q Vx,Hx,Wx (66),(v) | vpgatherqd/q Vx,Wx (66),(evo) 733 - 92: vgatherdps/d Vx,Hx,Wx (66),(v) 734 - 93: vgatherqps/d Vx,Hx,Wx (66),(v) 735 - 94: 736 - 95: 737 - 96: vfmaddsub132ps/d Vx,Hx,Wx (66),(v) 738 - 97: vfmsubadd132ps/d Vx,Hx,Wx (66),(v) 739 - 98: vfmadd132ps/d Vx,Hx,Wx (66),(v) 740 - 99: vfmadd132ss/d Vx,Hx,Wx (66),(v),(v1) 741 - 9a: vfmsub132ps/d Vx,Hx,Wx (66),(v) 742 - 9b: vfmsub132ss/d Vx,Hx,Wx (66),(v),(v1) 743 - 9c: vfnmadd132ps/d Vx,Hx,Wx (66),(v) 744 - 9d: vfnmadd132ss/d Vx,Hx,Wx (66),(v),(v1) 745 - 9e: vfnmsub132ps/d Vx,Hx,Wx (66),(v) 746 - 9f: vfnmsub132ss/d Vx,Hx,Wx (66),(v),(v1) 747 - a0: vpscatterdd/q Wx,Vx (66),(ev) 748 - a1: vpscatterqd/q Wx,Vx (66),(ev) 749 - a2: vscatterdps/d Wx,Vx (66),(ev) 750 - a3: vscatterqps/d Wx,Vx (66),(ev) 751 - a6: vfmaddsub213ps/d Vx,Hx,Wx (66),(v) 752 - a7: vfmsubadd213ps/d Vx,Hx,Wx (66),(v) 753 - a8: vfmadd213ps/d Vx,Hx,Wx (66),(v) 754 - a9: vfmadd213ss/d Vx,Hx,Wx (66),(v),(v1) 755 - aa: vfmsub213ps/d Vx,Hx,Wx (66),(v) 756 - ab: vfmsub213ss/d Vx,Hx,Wx (66),(v),(v1) 757 - ac: vfnmadd213ps/d Vx,Hx,Wx (66),(v) 758 - ad: vfnmadd213ss/d Vx,Hx,Wx (66),(v),(v1) 759 - ae: vfnmsub213ps/d Vx,Hx,Wx (66),(v) 760 - af: vfnmsub213ss/d Vx,Hx,Wx (66),(v),(v1) 761 - b4: vpmadd52luq Vx,Hx,Wx (66),(ev) 762 - b5: vpmadd52huq Vx,Hx,Wx (66),(ev) 763 - b6: vfmaddsub231ps/d Vx,Hx,Wx (66),(v) 764 - b7: vfmsubadd231ps/d Vx,Hx,Wx (66),(v) 765 - b8: vfmadd231ps/d Vx,Hx,Wx (66),(v) 766 - b9: vfmadd231ss/d Vx,Hx,Wx (66),(v),(v1) 767 - ba: vfmsub231ps/d Vx,Hx,Wx (66),(v) 768 - bb: vfmsub231ss/d Vx,Hx,Wx (66),(v),(v1) 769 - bc: vfnmadd231ps/d Vx,Hx,Wx (66),(v) 770 - bd: vfnmadd231ss/d Vx,Hx,Wx (66),(v),(v1) 771 - be: vfnmsub231ps/d Vx,Hx,Wx (66),(v) 772 - bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1) 773 - # 0x0f 0x38 0xc0-0xff 774 - c4: vpconflictd/q Vx,Wx (66),(ev) 775 - c6: Grp18 (1A) 776 - c7: Grp19 (1A) 777 - c8: sha1nexte Vdq,Wdq | vexp2ps/d Vx,Wx (66),(ev) 778 - c9: sha1msg1 Vdq,Wdq 779 - ca: sha1msg2 Vdq,Wdq | vrcp28ps/d Vx,Wx (66),(ev) 780 - cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev) 781 - cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev) 782 - cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev) 783 - db: VAESIMC Vdq,Wdq (66),(v1) 784 - dc: VAESENC Vdq,Hdq,Wdq (66),(v1) 785 - dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1) 786 - de: VAESDEC Vdq,Hdq,Wdq (66),(v1) 787 - df: VAESDECLAST Vdq,Hdq,Wdq (66),(v1) 788 - f0: MOVBE Gy,My | MOVBE Gw,Mw (66) | CRC32 Gd,Eb (F2) | CRC32 Gd,Eb (66&F2) 789 - f1: MOVBE My,Gy | MOVBE Mw,Gw (66) | CRC32 Gd,Ey (F2) | CRC32 Gd,Ew (66&F2) 790 - f2: ANDN Gy,By,Ey (v) 791 - f3: Grp17 (1A) 792 - f5: BZHI Gy,Ey,By (v) | PEXT Gy,By,Ey (F3),(v) | PDEP Gy,By,Ey (F2),(v) 793 - f6: ADCX Gy,Ey (66) | ADOX Gy,Ey (F3) | MULX By,Gy,rDX,Ey (F2),(v) 794 - f7: BEXTR Gy,Ey,By (v) | SHLX Gy,Ey,By (66),(v) | SARX Gy,Ey,By (F3),(v) | SHRX Gy,Ey,By (F2),(v) 795 - EndTable 796 - 797 - Table: 3-byte opcode 2 (0x0f 0x3a) 798 - Referrer: 3-byte escape 2 799 - AVXcode: 3 800 - # 0x0f 0x3a 0x00-0xff 801 - 00: vpermq Vqq,Wqq,Ib (66),(v) 802 - 01: vpermpd Vqq,Wqq,Ib (66),(v) 803 - 02: vpblendd Vx,Hx,Wx,Ib (66),(v) 804 - 03: valignd/q Vx,Hx,Wx,Ib (66),(ev) 805 - 04: vpermilps Vx,Wx,Ib (66),(v) 806 - 05: vpermilpd Vx,Wx,Ib (66),(v) 807 - 06: vperm2f128 Vqq,Hqq,Wqq,Ib (66),(v) 808 - 07: 809 - 08: vroundps Vx,Wx,Ib (66) | vrndscaleps Vx,Wx,Ib (66),(evo) 810 - 09: vroundpd Vx,Wx,Ib (66) | vrndscalepd Vx,Wx,Ib (66),(evo) 811 - 0a: vroundss Vss,Wss,Ib (66),(v1) | vrndscaless Vx,Hx,Wx,Ib (66),(evo) 812 - 0b: vroundsd Vsd,Wsd,Ib (66),(v1) | vrndscalesd Vx,Hx,Wx,Ib (66),(evo) 813 - 0c: vblendps Vx,Hx,Wx,Ib (66) 814 - 0d: vblendpd Vx,Hx,Wx,Ib (66) 815 - 0e: vpblendw Vx,Hx,Wx,Ib (66),(v1) 816 - 0f: palignr Pq,Qq,Ib | vpalignr Vx,Hx,Wx,Ib (66),(v1) 817 - 14: vpextrb Rd/Mb,Vdq,Ib (66),(v1) 818 - 15: vpextrw Rd/Mw,Vdq,Ib (66),(v1) 819 - 16: vpextrd/q Ey,Vdq,Ib (66),(v1) 820 - 17: vextractps Ed,Vdq,Ib (66),(v1) 821 - 18: vinsertf128 Vqq,Hqq,Wqq,Ib (66),(v) | vinsertf32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo) 822 - 19: vextractf128 Wdq,Vqq,Ib (66),(v) | vextractf32x4/64x2 Wdq,Vqq,Ib (66),(evo) 823 - 1a: vinsertf32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev) 824 - 1b: vextractf32x8/64x4 Wdq,Vqq,Ib (66),(ev) 825 - 1d: vcvtps2ph Wx,Vx,Ib (66),(v) 826 - 1e: vpcmpud/q Vk,Hd,Wd,Ib (66),(ev) 827 - 1f: vpcmpd/q Vk,Hd,Wd,Ib (66),(ev) 828 - 20: vpinsrb Vdq,Hdq,Ry/Mb,Ib (66),(v1) 829 - 21: vinsertps Vdq,Hdq,Udq/Md,Ib (66),(v1) 830 - 22: vpinsrd/q Vdq,Hdq,Ey,Ib (66),(v1) 831 - 23: vshuff32x4/64x2 Vx,Hx,Wx,Ib (66),(ev) 832 - 25: vpternlogd/q Vx,Hx,Wx,Ib (66),(ev) 833 - 26: vgetmantps/d Vx,Wx,Ib (66),(ev) 834 - 27: vgetmantss/d Vx,Hx,Wx,Ib (66),(ev) 835 - 30: kshiftrb/w Vk,Uk,Ib (66),(v) 836 - 31: kshiftrd/q Vk,Uk,Ib (66),(v) 837 - 32: kshiftlb/w Vk,Uk,Ib (66),(v) 838 - 33: kshiftld/q Vk,Uk,Ib (66),(v) 839 - 38: vinserti128 Vqq,Hqq,Wqq,Ib (66),(v) | vinserti32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo) 840 - 39: vextracti128 Wdq,Vqq,Ib (66),(v) | vextracti32x4/64x2 Wdq,Vqq,Ib (66),(evo) 841 - 3a: vinserti32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev) 842 - 3b: vextracti32x8/64x4 Wdq,Vqq,Ib (66),(ev) 843 - 3e: vpcmpub/w Vk,Hk,Wx,Ib (66),(ev) 844 - 3f: vpcmpb/w Vk,Hk,Wx,Ib (66),(ev) 845 - 40: vdpps Vx,Hx,Wx,Ib (66) 846 - 41: vdppd Vdq,Hdq,Wdq,Ib (66),(v1) 847 - 42: vmpsadbw Vx,Hx,Wx,Ib (66),(v1) | vdbpsadbw Vx,Hx,Wx,Ib (66),(evo) 848 - 43: vshufi32x4/64x2 Vx,Hx,Wx,Ib (66),(ev) 849 - 44: vpclmulqdq Vdq,Hdq,Wdq,Ib (66),(v1) 850 - 46: vperm2i128 Vqq,Hqq,Wqq,Ib (66),(v) 851 - 4a: vblendvps Vx,Hx,Wx,Lx (66),(v) 852 - 4b: vblendvpd Vx,Hx,Wx,Lx (66),(v) 853 - 4c: vpblendvb Vx,Hx,Wx,Lx (66),(v1) 854 - 50: vrangeps/d Vx,Hx,Wx,Ib (66),(ev) 855 - 51: vrangess/d Vx,Hx,Wx,Ib (66),(ev) 856 - 54: vfixupimmps/d Vx,Hx,Wx,Ib (66),(ev) 857 - 55: vfixupimmss/d Vx,Hx,Wx,Ib (66),(ev) 858 - 56: vreduceps/d Vx,Wx,Ib (66),(ev) 859 - 57: vreducess/d Vx,Hx,Wx,Ib (66),(ev) 860 - 60: vpcmpestrm Vdq,Wdq,Ib (66),(v1) 861 - 61: vpcmpestri Vdq,Wdq,Ib (66),(v1) 862 - 62: vpcmpistrm Vdq,Wdq,Ib (66),(v1) 863 - 63: vpcmpistri Vdq,Wdq,Ib (66),(v1) 864 - 66: vfpclassps/d Vk,Wx,Ib (66),(ev) 865 - 67: vfpclassss/d Vk,Wx,Ib (66),(ev) 866 - cc: sha1rnds4 Vdq,Wdq,Ib 867 - df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1) 868 - f0: RORX Gy,Ey,Ib (F2),(v) 869 - EndTable 870 - 871 - GrpTable: Grp1 872 - 0: ADD 873 - 1: OR 874 - 2: ADC 875 - 3: SBB 876 - 4: AND 877 - 5: SUB 878 - 6: XOR 879 - 7: CMP 880 - EndTable 881 - 882 - GrpTable: Grp1A 883 - 0: POP 884 - EndTable 885 - 886 - GrpTable: Grp2 887 - 0: ROL 888 - 1: ROR 889 - 2: RCL 890 - 3: RCR 891 - 4: SHL/SAL 892 - 5: SHR 893 - 6: 894 - 7: SAR 895 - EndTable 896 - 897 - GrpTable: Grp3_1 898 - 0: TEST Eb,Ib 899 - 1: TEST Eb,Ib 900 - 2: NOT Eb 901 - 3: NEG Eb 902 - 4: MUL AL,Eb 903 - 5: IMUL AL,Eb 904 - 6: DIV AL,Eb 905 - 7: IDIV AL,Eb 906 - EndTable 907 - 908 - GrpTable: Grp3_2 909 - 0: TEST Ev,Iz 910 - 1: 911 - 2: NOT Ev 912 - 3: NEG Ev 913 - 4: MUL rAX,Ev 914 - 5: IMUL rAX,Ev 915 - 6: DIV rAX,Ev 916 - 7: IDIV rAX,Ev 917 - EndTable 918 - 919 - GrpTable: Grp4 920 - 0: INC Eb 921 - 1: DEC Eb 922 - EndTable 923 - 924 - GrpTable: Grp5 925 - 0: INC Ev 926 - 1: DEC Ev 927 - # Note: "forced64" is Intel CPU behavior (see comment about CALL insn). 928 - 2: CALLN Ev (f64) 929 - 3: CALLF Ep 930 - 4: JMPN Ev (f64) 931 - 5: JMPF Mp 932 - 6: PUSH Ev (d64) 933 - 7: 934 - EndTable 935 - 936 - GrpTable: Grp6 937 - 0: SLDT Rv/Mw 938 - 1: STR Rv/Mw 939 - 2: LLDT Ew 940 - 3: LTR Ew 941 - 4: VERR Ew 942 - 5: VERW Ew 943 - EndTable 944 - 945 - GrpTable: Grp7 946 - 0: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B) 947 - 1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001),(11B) | CLAC (010),(11B) | STAC (011),(11B) 948 - 2: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B) 949 - 3: LIDT Ms 950 - 4: SMSW Mw/Rv 951 - 5: rdpkru (110),(11B) | wrpkru (111),(11B) 952 - 6: LMSW Ew 953 - 7: INVLPG Mb | SWAPGS (o64),(000),(11B) | RDTSCP (001),(11B) 954 - EndTable 955 - 956 - GrpTable: Grp8 957 - 4: BT 958 - 5: BTS 959 - 6: BTR 960 - 7: BTC 961 - EndTable 962 - 963 - GrpTable: Grp9 964 - 1: CMPXCHG8B/16B Mq/Mdq 965 - 3: xrstors 966 - 4: xsavec 967 - 5: xsaves 968 - 6: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B) 969 - 7: VMPTRST Mq | VMPTRST Mq (F3) | RDSEED Rv (11B) 970 - EndTable 971 - 972 - GrpTable: Grp10 973 - # all are UD1 974 - 0: UD1 975 - 1: UD1 976 - 2: UD1 977 - 3: UD1 978 - 4: UD1 979 - 5: UD1 980 - 6: UD1 981 - 7: UD1 982 - EndTable 983 - 984 - # Grp11A and Grp11B are expressed as Grp11 in Intel SDM 985 - GrpTable: Grp11A 986 - 0: MOV Eb,Ib 987 - 7: XABORT Ib (000),(11B) 988 - EndTable 989 - 990 - GrpTable: Grp11B 991 - 0: MOV Eb,Iz 992 - 7: XBEGIN Jz (000),(11B) 993 - EndTable 994 - 995 - GrpTable: Grp12 996 - 2: psrlw Nq,Ib (11B) | vpsrlw Hx,Ux,Ib (66),(11B),(v1) 997 - 4: psraw Nq,Ib (11B) | vpsraw Hx,Ux,Ib (66),(11B),(v1) 998 - 6: psllw Nq,Ib (11B) | vpsllw Hx,Ux,Ib (66),(11B),(v1) 999 - EndTable 1000 - 1001 - GrpTable: Grp13 1002 - 0: vprord/q Hx,Wx,Ib (66),(ev) 1003 - 1: vprold/q Hx,Wx,Ib (66),(ev) 1004 - 2: psrld Nq,Ib (11B) | vpsrld Hx,Ux,Ib (66),(11B),(v1) 1005 - 4: psrad Nq,Ib (11B) | vpsrad Hx,Ux,Ib (66),(11B),(v1) | vpsrad/q Hx,Ux,Ib (66),(evo) 1006 - 6: pslld Nq,Ib (11B) | vpslld Hx,Ux,Ib (66),(11B),(v1) 1007 - EndTable 1008 - 1009 - GrpTable: Grp14 1010 - 2: psrlq Nq,Ib (11B) | vpsrlq Hx,Ux,Ib (66),(11B),(v1) 1011 - 3: vpsrldq Hx,Ux,Ib (66),(11B),(v1) 1012 - 6: psllq Nq,Ib (11B) | vpsllq Hx,Ux,Ib (66),(11B),(v1) 1013 - 7: vpslldq Hx,Ux,Ib (66),(11B),(v1) 1014 - EndTable 1015 - 1016 - GrpTable: Grp15 1017 - 0: fxsave | RDFSBASE Ry (F3),(11B) 1018 - 1: fxstor | RDGSBASE Ry (F3),(11B) 1019 - 2: vldmxcsr Md (v1) | WRFSBASE Ry (F3),(11B) 1020 - 3: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B) 1021 - 4: XSAVE | ptwrite Ey (F3),(11B) 1022 - 5: XRSTOR | lfence (11B) 1023 - 6: XSAVEOPT | clwb (66) | mfence (11B) 1024 - 7: clflush | clflushopt (66) | sfence (11B) 1025 - EndTable 1026 - 1027 - GrpTable: Grp16 1028 - 0: prefetch NTA 1029 - 1: prefetch T0 1030 - 2: prefetch T1 1031 - 3: prefetch T2 1032 - EndTable 1033 - 1034 - GrpTable: Grp17 1035 - 1: BLSR By,Ey (v) 1036 - 2: BLSMSK By,Ey (v) 1037 - 3: BLSI By,Ey (v) 1038 - EndTable 1039 - 1040 - GrpTable: Grp18 1041 - 1: vgatherpf0dps/d Wx (66),(ev) 1042 - 2: vgatherpf1dps/d Wx (66),(ev) 1043 - 5: vscatterpf0dps/d Wx (66),(ev) 1044 - 6: vscatterpf1dps/d Wx (66),(ev) 1045 - EndTable 1046 - 1047 - GrpTable: Grp19 1048 - 1: vgatherpf0qps/d Wx (66),(ev) 1049 - 2: vgatherpf1qps/d Wx (66),(ev) 1050 - 5: vscatterpf0qps/d Wx (66),(ev) 1051 - 6: vscatterpf1qps/d Wx (66),(ev) 1052 - EndTable 1053 - 1054 - # AMD's Prefetch Group 1055 - GrpTable: GrpP 1056 - 0: PREFETCH 1057 - 1: PREFETCHW 1058 - EndTable 1059 - 1060 - GrpTable: GrpPDLK 1061 - 0: MONTMUL 1062 - 1: XSHA1 1063 - 2: XSHA2 1064 - EndTable 1065 - 1066 - GrpTable: GrpRNG 1067 - 0: xstore-rng 1068 - 1: xcrypt-ecb 1069 - 2: xcrypt-cbc 1070 - 4: xcrypt-cfb 1071 - 5: xcrypt-ofb 1072 - EndTable