11a59d1b8SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 2eb13296cSMasami Hiramatsu #ifndef _ASM_X86_INAT_H 3eb13296cSMasami Hiramatsu #define _ASM_X86_INAT_H 4eb13296cSMasami Hiramatsu /* 5eb13296cSMasami Hiramatsu * x86 instruction attributes 6eb13296cSMasami Hiramatsu * 7eb13296cSMasami Hiramatsu * Written by Masami Hiramatsu <mhiramat@redhat.com> 8eb13296cSMasami Hiramatsu */ 9*d30c7b82SBorislav Petkov #include <asm/inat_types.h> /* __ignore_sync_check__ */ 10eb13296cSMasami Hiramatsu 11eb13296cSMasami Hiramatsu /* 12eb13296cSMasami Hiramatsu * Internal bits. Don't use bitmasks directly, because these bits are 13eb13296cSMasami Hiramatsu * unstable. You should use checking functions. 14eb13296cSMasami Hiramatsu */ 15eb13296cSMasami Hiramatsu 16eb13296cSMasami Hiramatsu #define INAT_OPCODE_TABLE_SIZE 256 17eb13296cSMasami Hiramatsu #define INAT_GROUP_TABLE_SIZE 8 18eb13296cSMasami Hiramatsu 1904d46c1bSMasami Hiramatsu /* Legacy last prefixes */ 20eb13296cSMasami Hiramatsu #define INAT_PFX_OPNDSZ 1 /* 0x66 */ /* LPFX1 */ 21e0e492e9SMasami Hiramatsu #define INAT_PFX_REPE 2 /* 0xF3 */ /* LPFX2 */ 22e0e492e9SMasami Hiramatsu #define INAT_PFX_REPNE 3 /* 0xF2 */ /* LPFX3 */ 2304d46c1bSMasami Hiramatsu /* Other Legacy prefixes */ 24eb13296cSMasami Hiramatsu #define INAT_PFX_LOCK 4 /* 0xF0 */ 25eb13296cSMasami Hiramatsu #define INAT_PFX_CS 5 /* 0x2E */ 26eb13296cSMasami Hiramatsu #define INAT_PFX_DS 6 /* 0x3E */ 27eb13296cSMasami Hiramatsu #define INAT_PFX_ES 7 /* 0x26 */ 28eb13296cSMasami Hiramatsu #define INAT_PFX_FS 8 /* 0x64 */ 29eb13296cSMasami Hiramatsu #define INAT_PFX_GS 9 /* 0x65 */ 30eb13296cSMasami Hiramatsu #define INAT_PFX_SS 10 /* 0x36 */ 31eb13296cSMasami Hiramatsu #define INAT_PFX_ADDRSZ 11 /* 0x67 */ 3204d46c1bSMasami Hiramatsu /* x86-64 REX prefix */ 3304d46c1bSMasami Hiramatsu #define INAT_PFX_REX 12 /* 0x4X */ 34e0e492e9SMasami Hiramatsu /* AVX VEX prefixes */ 35e0e492e9SMasami Hiramatsu #define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */ 36e0e492e9SMasami Hiramatsu #define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */ 3725af37f4SAdrian Hunter #define INAT_PFX_EVEX 15 /* EVEX prefix */ 38eb13296cSMasami Hiramatsu 3904d46c1bSMasami Hiramatsu #define INAT_LSTPFX_MAX 3 4004d46c1bSMasami Hiramatsu #define INAT_LGCPFX_MAX 11 41eb13296cSMasami Hiramatsu 42eb13296cSMasami Hiramatsu /* Immediate size */ 43eb13296cSMasami Hiramatsu #define INAT_IMM_BYTE 1 44eb13296cSMasami Hiramatsu #define INAT_IMM_WORD 2 45eb13296cSMasami Hiramatsu #define INAT_IMM_DWORD 3 46eb13296cSMasami Hiramatsu #define INAT_IMM_QWORD 4 47eb13296cSMasami Hiramatsu #define INAT_IMM_PTR 5 48eb13296cSMasami Hiramatsu #define INAT_IMM_VWORD32 6 49eb13296cSMasami Hiramatsu #define INAT_IMM_VWORD 7 50eb13296cSMasami Hiramatsu 51eb13296cSMasami Hiramatsu /* Legacy prefix */ 52eb13296cSMasami Hiramatsu #define INAT_PFX_OFFS 0 53eb13296cSMasami Hiramatsu #define INAT_PFX_BITS 4 54eb13296cSMasami Hiramatsu #define INAT_PFX_MAX ((1 << INAT_PFX_BITS) - 1) 55eb13296cSMasami Hiramatsu #define INAT_PFX_MASK (INAT_PFX_MAX << INAT_PFX_OFFS) 56eb13296cSMasami Hiramatsu /* Escape opcodes */ 57eb13296cSMasami Hiramatsu #define INAT_ESC_OFFS (INAT_PFX_OFFS + INAT_PFX_BITS) 58eb13296cSMasami Hiramatsu #define INAT_ESC_BITS 2 59eb13296cSMasami Hiramatsu #define INAT_ESC_MAX ((1 << INAT_ESC_BITS) - 1) 60eb13296cSMasami Hiramatsu #define INAT_ESC_MASK (INAT_ESC_MAX << INAT_ESC_OFFS) 61eb13296cSMasami Hiramatsu /* Group opcodes (1-16) */ 62eb13296cSMasami Hiramatsu #define INAT_GRP_OFFS (INAT_ESC_OFFS + INAT_ESC_BITS) 63eb13296cSMasami Hiramatsu #define INAT_GRP_BITS 5 64eb13296cSMasami Hiramatsu #define INAT_GRP_MAX ((1 << INAT_GRP_BITS) - 1) 65eb13296cSMasami Hiramatsu #define INAT_GRP_MASK (INAT_GRP_MAX << INAT_GRP_OFFS) 66eb13296cSMasami Hiramatsu /* Immediates */ 67eb13296cSMasami Hiramatsu #define INAT_IMM_OFFS (INAT_GRP_OFFS + INAT_GRP_BITS) 68eb13296cSMasami Hiramatsu #define INAT_IMM_BITS 3 69eb13296cSMasami Hiramatsu #define INAT_IMM_MASK (((1 << INAT_IMM_BITS) - 1) << INAT_IMM_OFFS) 70eb13296cSMasami Hiramatsu /* Flags */ 71eb13296cSMasami Hiramatsu #define INAT_FLAG_OFFS (INAT_IMM_OFFS + INAT_IMM_BITS) 7204d46c1bSMasami Hiramatsu #define INAT_MODRM (1 << (INAT_FLAG_OFFS)) 7304d46c1bSMasami Hiramatsu #define INAT_FORCE64 (1 << (INAT_FLAG_OFFS + 1)) 7404d46c1bSMasami Hiramatsu #define INAT_SCNDIMM (1 << (INAT_FLAG_OFFS + 2)) 7504d46c1bSMasami Hiramatsu #define INAT_MOFFSET (1 << (INAT_FLAG_OFFS + 3)) 7604d46c1bSMasami Hiramatsu #define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4)) 77e0e492e9SMasami Hiramatsu #define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5)) 78e0e492e9SMasami Hiramatsu #define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6)) 7925af37f4SAdrian Hunter #define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7)) 80eb13296cSMasami Hiramatsu /* Attribute making macros for attribute tables */ 81eb13296cSMasami Hiramatsu #define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS) 82eb13296cSMasami Hiramatsu #define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS) 83eb13296cSMasami Hiramatsu #define INAT_MAKE_GROUP(grp) ((grp << INAT_GRP_OFFS) | INAT_MODRM) 84eb13296cSMasami Hiramatsu #define INAT_MAKE_IMM(imm) (imm << INAT_IMM_OFFS) 85eb13296cSMasami Hiramatsu 8632d0b953SRicardo Neri /* Identifiers for segment registers */ 8732d0b953SRicardo Neri #define INAT_SEG_REG_IGNORE 0 8832d0b953SRicardo Neri #define INAT_SEG_REG_DEFAULT 1 8932d0b953SRicardo Neri #define INAT_SEG_REG_CS 2 9032d0b953SRicardo Neri #define INAT_SEG_REG_SS 3 9132d0b953SRicardo Neri #define INAT_SEG_REG_DS 4 9232d0b953SRicardo Neri #define INAT_SEG_REG_ES 5 9332d0b953SRicardo Neri #define INAT_SEG_REG_FS 6 9432d0b953SRicardo Neri #define INAT_SEG_REG_GS 7 9532d0b953SRicardo Neri 96eb13296cSMasami Hiramatsu /* Attribute search APIs */ 97eb13296cSMasami Hiramatsu extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode); 98f8d98f10SMasami Hiramatsu extern int inat_get_last_prefix_id(insn_byte_t last_pfx); 99eb13296cSMasami Hiramatsu extern insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, 100f8d98f10SMasami Hiramatsu int lpfx_id, 101eb13296cSMasami Hiramatsu insn_attr_t esc_attr); 102eb13296cSMasami Hiramatsu extern insn_attr_t inat_get_group_attribute(insn_byte_t modrm, 103f8d98f10SMasami Hiramatsu int lpfx_id, 104eb13296cSMasami Hiramatsu insn_attr_t esc_attr); 105e0e492e9SMasami Hiramatsu extern insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, 106e0e492e9SMasami Hiramatsu insn_byte_t vex_m, 107e0e492e9SMasami Hiramatsu insn_byte_t vex_pp); 108eb13296cSMasami Hiramatsu 109eb13296cSMasami Hiramatsu /* Attribute checking functions */ inat_is_legacy_prefix(insn_attr_t attr)11004d46c1bSMasami Hiramatsustatic inline int inat_is_legacy_prefix(insn_attr_t attr) 111eb13296cSMasami Hiramatsu { 11204d46c1bSMasami Hiramatsu attr &= INAT_PFX_MASK; 11304d46c1bSMasami Hiramatsu return attr && attr <= INAT_LGCPFX_MAX; 114eb13296cSMasami Hiramatsu } 115eb13296cSMasami Hiramatsu inat_is_address_size_prefix(insn_attr_t attr)116eb13296cSMasami Hiramatsustatic inline int inat_is_address_size_prefix(insn_attr_t attr) 117eb13296cSMasami Hiramatsu { 118eb13296cSMasami Hiramatsu return (attr & INAT_PFX_MASK) == INAT_PFX_ADDRSZ; 119eb13296cSMasami Hiramatsu } 120eb13296cSMasami Hiramatsu inat_is_operand_size_prefix(insn_attr_t attr)121eb13296cSMasami Hiramatsustatic inline int inat_is_operand_size_prefix(insn_attr_t attr) 122eb13296cSMasami Hiramatsu { 123eb13296cSMasami Hiramatsu return (attr & INAT_PFX_MASK) == INAT_PFX_OPNDSZ; 124eb13296cSMasami Hiramatsu } 125eb13296cSMasami Hiramatsu inat_is_rex_prefix(insn_attr_t attr)12604d46c1bSMasami Hiramatsustatic inline int inat_is_rex_prefix(insn_attr_t attr) 12704d46c1bSMasami Hiramatsu { 12804d46c1bSMasami Hiramatsu return (attr & INAT_PFX_MASK) == INAT_PFX_REX; 12904d46c1bSMasami Hiramatsu } 13004d46c1bSMasami Hiramatsu inat_last_prefix_id(insn_attr_t attr)131eb13296cSMasami Hiramatsustatic inline int inat_last_prefix_id(insn_attr_t attr) 132eb13296cSMasami Hiramatsu { 13304d46c1bSMasami Hiramatsu if ((attr & INAT_PFX_MASK) > INAT_LSTPFX_MAX) 134eb13296cSMasami Hiramatsu return 0; 135eb13296cSMasami Hiramatsu else 136eb13296cSMasami Hiramatsu return attr & INAT_PFX_MASK; 137eb13296cSMasami Hiramatsu } 138eb13296cSMasami Hiramatsu inat_is_vex_prefix(insn_attr_t attr)139e0e492e9SMasami Hiramatsustatic inline int inat_is_vex_prefix(insn_attr_t attr) 140e0e492e9SMasami Hiramatsu { 141e0e492e9SMasami Hiramatsu attr &= INAT_PFX_MASK; 14225af37f4SAdrian Hunter return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3 || 14325af37f4SAdrian Hunter attr == INAT_PFX_EVEX; 14425af37f4SAdrian Hunter } 14525af37f4SAdrian Hunter inat_is_evex_prefix(insn_attr_t attr)14625af37f4SAdrian Hunterstatic inline int inat_is_evex_prefix(insn_attr_t attr) 14725af37f4SAdrian Hunter { 14825af37f4SAdrian Hunter return (attr & INAT_PFX_MASK) == INAT_PFX_EVEX; 149e0e492e9SMasami Hiramatsu } 150e0e492e9SMasami Hiramatsu inat_is_vex3_prefix(insn_attr_t attr)151e0e492e9SMasami Hiramatsustatic inline int inat_is_vex3_prefix(insn_attr_t attr) 152e0e492e9SMasami Hiramatsu { 153e0e492e9SMasami Hiramatsu return (attr & INAT_PFX_MASK) == INAT_PFX_VEX3; 154e0e492e9SMasami Hiramatsu } 155e0e492e9SMasami Hiramatsu inat_is_escape(insn_attr_t attr)156eb13296cSMasami Hiramatsustatic inline int inat_is_escape(insn_attr_t attr) 157eb13296cSMasami Hiramatsu { 158eb13296cSMasami Hiramatsu return attr & INAT_ESC_MASK; 159eb13296cSMasami Hiramatsu } 160eb13296cSMasami Hiramatsu inat_escape_id(insn_attr_t attr)161eb13296cSMasami Hiramatsustatic inline int inat_escape_id(insn_attr_t attr) 162eb13296cSMasami Hiramatsu { 163eb13296cSMasami Hiramatsu return (attr & INAT_ESC_MASK) >> INAT_ESC_OFFS; 164eb13296cSMasami Hiramatsu } 165eb13296cSMasami Hiramatsu inat_is_group(insn_attr_t attr)166eb13296cSMasami Hiramatsustatic inline int inat_is_group(insn_attr_t attr) 167eb13296cSMasami Hiramatsu { 168eb13296cSMasami Hiramatsu return attr & INAT_GRP_MASK; 169eb13296cSMasami Hiramatsu } 170eb13296cSMasami Hiramatsu inat_group_id(insn_attr_t attr)171eb13296cSMasami Hiramatsustatic inline int inat_group_id(insn_attr_t attr) 172eb13296cSMasami Hiramatsu { 173eb13296cSMasami Hiramatsu return (attr & INAT_GRP_MASK) >> INAT_GRP_OFFS; 174eb13296cSMasami Hiramatsu } 175eb13296cSMasami Hiramatsu inat_group_common_attribute(insn_attr_t attr)176eb13296cSMasami Hiramatsustatic inline int inat_group_common_attribute(insn_attr_t attr) 177eb13296cSMasami Hiramatsu { 178eb13296cSMasami Hiramatsu return attr & ~INAT_GRP_MASK; 179eb13296cSMasami Hiramatsu } 180eb13296cSMasami Hiramatsu inat_has_immediate(insn_attr_t attr)181eb13296cSMasami Hiramatsustatic inline int inat_has_immediate(insn_attr_t attr) 182eb13296cSMasami Hiramatsu { 183eb13296cSMasami Hiramatsu return attr & INAT_IMM_MASK; 184eb13296cSMasami Hiramatsu } 185eb13296cSMasami Hiramatsu inat_immediate_size(insn_attr_t attr)186eb13296cSMasami Hiramatsustatic inline int inat_immediate_size(insn_attr_t attr) 187eb13296cSMasami Hiramatsu { 188eb13296cSMasami Hiramatsu return (attr & INAT_IMM_MASK) >> INAT_IMM_OFFS; 189eb13296cSMasami Hiramatsu } 190eb13296cSMasami Hiramatsu inat_has_modrm(insn_attr_t attr)191eb13296cSMasami Hiramatsustatic inline int inat_has_modrm(insn_attr_t attr) 192eb13296cSMasami Hiramatsu { 193eb13296cSMasami Hiramatsu return attr & INAT_MODRM; 194eb13296cSMasami Hiramatsu } 195eb13296cSMasami Hiramatsu inat_is_force64(insn_attr_t attr)196eb13296cSMasami Hiramatsustatic inline int inat_is_force64(insn_attr_t attr) 197eb13296cSMasami Hiramatsu { 198eb13296cSMasami Hiramatsu return attr & INAT_FORCE64; 199eb13296cSMasami Hiramatsu } 200eb13296cSMasami Hiramatsu inat_has_second_immediate(insn_attr_t attr)201eb13296cSMasami Hiramatsustatic inline int inat_has_second_immediate(insn_attr_t attr) 202eb13296cSMasami Hiramatsu { 203eb13296cSMasami Hiramatsu return attr & INAT_SCNDIMM; 204eb13296cSMasami Hiramatsu } 205eb13296cSMasami Hiramatsu inat_has_moffset(insn_attr_t attr)206eb13296cSMasami Hiramatsustatic inline int inat_has_moffset(insn_attr_t attr) 207eb13296cSMasami Hiramatsu { 208eb13296cSMasami Hiramatsu return attr & INAT_MOFFSET; 209eb13296cSMasami Hiramatsu } 210eb13296cSMasami Hiramatsu inat_has_variant(insn_attr_t attr)211eb13296cSMasami Hiramatsustatic inline int inat_has_variant(insn_attr_t attr) 212eb13296cSMasami Hiramatsu { 213eb13296cSMasami Hiramatsu return attr & INAT_VARIANT; 214eb13296cSMasami Hiramatsu } 215eb13296cSMasami Hiramatsu inat_accept_vex(insn_attr_t attr)216e0e492e9SMasami Hiramatsustatic inline int inat_accept_vex(insn_attr_t attr) 217e0e492e9SMasami Hiramatsu { 218e0e492e9SMasami Hiramatsu return attr & INAT_VEXOK; 219e0e492e9SMasami Hiramatsu } 220e0e492e9SMasami Hiramatsu inat_must_vex(insn_attr_t attr)221e0e492e9SMasami Hiramatsustatic inline int inat_must_vex(insn_attr_t attr) 222e0e492e9SMasami Hiramatsu { 22325af37f4SAdrian Hunter return attr & (INAT_VEXONLY | INAT_EVEXONLY); 22425af37f4SAdrian Hunter } 22525af37f4SAdrian Hunter inat_must_evex(insn_attr_t attr)22625af37f4SAdrian Hunterstatic inline int inat_must_evex(insn_attr_t attr) 22725af37f4SAdrian Hunter { 22825af37f4SAdrian Hunter return attr & INAT_EVEXONLY; 229e0e492e9SMasami Hiramatsu } 230eb13296cSMasami Hiramatsu #endif 231