Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 #ifndef _ASM_X86_INAT_H
0003 #define _ASM_X86_INAT_H
0004 /*
0005  * x86 instruction attributes
0006  *
0007  * Written by Masami Hiramatsu <mhiramat@redhat.com>
0008  */
0009 #include <asm/inat_types.h> /* __ignore_sync_check__ */
0010 
0011 /*
0012  * Internal bits. Don't use bitmasks directly, because these bits are
0013  * unstable. You should use checking functions.
0014  */
0015 
0016 #define INAT_OPCODE_TABLE_SIZE 256
0017 #define INAT_GROUP_TABLE_SIZE 8
0018 
0019 /* Legacy last prefixes */
0020 #define INAT_PFX_OPNDSZ 1   /* 0x66 */ /* LPFX1 */
0021 #define INAT_PFX_REPE   2   /* 0xF3 */ /* LPFX2 */
0022 #define INAT_PFX_REPNE  3   /* 0xF2 */ /* LPFX3 */
0023 /* Other Legacy prefixes */
0024 #define INAT_PFX_LOCK   4   /* 0xF0 */
0025 #define INAT_PFX_CS 5   /* 0x2E */
0026 #define INAT_PFX_DS 6   /* 0x3E */
0027 #define INAT_PFX_ES 7   /* 0x26 */
0028 #define INAT_PFX_FS 8   /* 0x64 */
0029 #define INAT_PFX_GS 9   /* 0x65 */
0030 #define INAT_PFX_SS 10  /* 0x36 */
0031 #define INAT_PFX_ADDRSZ 11  /* 0x67 */
0032 /* x86-64 REX prefix */
0033 #define INAT_PFX_REX    12  /* 0x4X */
0034 /* AVX VEX prefixes */
0035 #define INAT_PFX_VEX2   13  /* 2-bytes VEX prefix */
0036 #define INAT_PFX_VEX3   14  /* 3-bytes VEX prefix */
0037 #define INAT_PFX_EVEX   15  /* EVEX prefix */
0038 
0039 #define INAT_LSTPFX_MAX 3
0040 #define INAT_LGCPFX_MAX 11
0041 
0042 /* Immediate size */
0043 #define INAT_IMM_BYTE       1
0044 #define INAT_IMM_WORD       2
0045 #define INAT_IMM_DWORD      3
0046 #define INAT_IMM_QWORD      4
0047 #define INAT_IMM_PTR        5
0048 #define INAT_IMM_VWORD32    6
0049 #define INAT_IMM_VWORD      7
0050 
0051 /* Legacy prefix */
0052 #define INAT_PFX_OFFS   0
0053 #define INAT_PFX_BITS   4
0054 #define INAT_PFX_MAX    ((1 << INAT_PFX_BITS) - 1)
0055 #define INAT_PFX_MASK   (INAT_PFX_MAX << INAT_PFX_OFFS)
0056 /* Escape opcodes */
0057 #define INAT_ESC_OFFS   (INAT_PFX_OFFS + INAT_PFX_BITS)
0058 #define INAT_ESC_BITS   2
0059 #define INAT_ESC_MAX    ((1 << INAT_ESC_BITS) - 1)
0060 #define INAT_ESC_MASK   (INAT_ESC_MAX << INAT_ESC_OFFS)
0061 /* Group opcodes (1-16) */
0062 #define INAT_GRP_OFFS   (INAT_ESC_OFFS + INAT_ESC_BITS)
0063 #define INAT_GRP_BITS   5
0064 #define INAT_GRP_MAX    ((1 << INAT_GRP_BITS) - 1)
0065 #define INAT_GRP_MASK   (INAT_GRP_MAX << INAT_GRP_OFFS)
0066 /* Immediates */
0067 #define INAT_IMM_OFFS   (INAT_GRP_OFFS + INAT_GRP_BITS)
0068 #define INAT_IMM_BITS   3
0069 #define INAT_IMM_MASK   (((1 << INAT_IMM_BITS) - 1) << INAT_IMM_OFFS)
0070 /* Flags */
0071 #define INAT_FLAG_OFFS  (INAT_IMM_OFFS + INAT_IMM_BITS)
0072 #define INAT_MODRM  (1 << (INAT_FLAG_OFFS))
0073 #define INAT_FORCE64    (1 << (INAT_FLAG_OFFS + 1))
0074 #define INAT_SCNDIMM    (1 << (INAT_FLAG_OFFS + 2))
0075 #define INAT_MOFFSET    (1 << (INAT_FLAG_OFFS + 3))
0076 #define INAT_VARIANT    (1 << (INAT_FLAG_OFFS + 4))
0077 #define INAT_VEXOK  (1 << (INAT_FLAG_OFFS + 5))
0078 #define INAT_VEXONLY    (1 << (INAT_FLAG_OFFS + 6))
0079 #define INAT_EVEXONLY   (1 << (INAT_FLAG_OFFS + 7))
0080 /* Attribute making macros for attribute tables */
0081 #define INAT_MAKE_PREFIX(pfx)   (pfx << INAT_PFX_OFFS)
0082 #define INAT_MAKE_ESCAPE(esc)   (esc << INAT_ESC_OFFS)
0083 #define INAT_MAKE_GROUP(grp)    ((grp << INAT_GRP_OFFS) | INAT_MODRM)
0084 #define INAT_MAKE_IMM(imm)  (imm << INAT_IMM_OFFS)
0085 
0086 /* Identifiers for segment registers */
0087 #define INAT_SEG_REG_IGNORE 0
0088 #define INAT_SEG_REG_DEFAULT    1
0089 #define INAT_SEG_REG_CS     2
0090 #define INAT_SEG_REG_SS     3
0091 #define INAT_SEG_REG_DS     4
0092 #define INAT_SEG_REG_ES     5
0093 #define INAT_SEG_REG_FS     6
0094 #define INAT_SEG_REG_GS     7
0095 
0096 /* Attribute search APIs */
0097 extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode);
0098 extern int inat_get_last_prefix_id(insn_byte_t last_pfx);
0099 extern insn_attr_t inat_get_escape_attribute(insn_byte_t opcode,
0100                          int lpfx_id,
0101                          insn_attr_t esc_attr);
0102 extern insn_attr_t inat_get_group_attribute(insn_byte_t modrm,
0103                         int lpfx_id,
0104                         insn_attr_t esc_attr);
0105 extern insn_attr_t inat_get_avx_attribute(insn_byte_t opcode,
0106                       insn_byte_t vex_m,
0107                       insn_byte_t vex_pp);
0108 
0109 /* Attribute checking functions */
0110 static inline int inat_is_legacy_prefix(insn_attr_t attr)
0111 {
0112     attr &= INAT_PFX_MASK;
0113     return attr && attr <= INAT_LGCPFX_MAX;
0114 }
0115 
0116 static inline int inat_is_address_size_prefix(insn_attr_t attr)
0117 {
0118     return (attr & INAT_PFX_MASK) == INAT_PFX_ADDRSZ;
0119 }
0120 
0121 static inline int inat_is_operand_size_prefix(insn_attr_t attr)
0122 {
0123     return (attr & INAT_PFX_MASK) == INAT_PFX_OPNDSZ;
0124 }
0125 
0126 static inline int inat_is_rex_prefix(insn_attr_t attr)
0127 {
0128     return (attr & INAT_PFX_MASK) == INAT_PFX_REX;
0129 }
0130 
0131 static inline int inat_last_prefix_id(insn_attr_t attr)
0132 {
0133     if ((attr & INAT_PFX_MASK) > INAT_LSTPFX_MAX)
0134         return 0;
0135     else
0136         return attr & INAT_PFX_MASK;
0137 }
0138 
0139 static inline int inat_is_vex_prefix(insn_attr_t attr)
0140 {
0141     attr &= INAT_PFX_MASK;
0142     return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3 ||
0143            attr == INAT_PFX_EVEX;
0144 }
0145 
0146 static inline int inat_is_evex_prefix(insn_attr_t attr)
0147 {
0148     return (attr & INAT_PFX_MASK) == INAT_PFX_EVEX;
0149 }
0150 
0151 static inline int inat_is_vex3_prefix(insn_attr_t attr)
0152 {
0153     return (attr & INAT_PFX_MASK) == INAT_PFX_VEX3;
0154 }
0155 
0156 static inline int inat_is_escape(insn_attr_t attr)
0157 {
0158     return attr & INAT_ESC_MASK;
0159 }
0160 
0161 static inline int inat_escape_id(insn_attr_t attr)
0162 {
0163     return (attr & INAT_ESC_MASK) >> INAT_ESC_OFFS;
0164 }
0165 
0166 static inline int inat_is_group(insn_attr_t attr)
0167 {
0168     return attr & INAT_GRP_MASK;
0169 }
0170 
0171 static inline int inat_group_id(insn_attr_t attr)
0172 {
0173     return (attr & INAT_GRP_MASK) >> INAT_GRP_OFFS;
0174 }
0175 
0176 static inline int inat_group_common_attribute(insn_attr_t attr)
0177 {
0178     return attr & ~INAT_GRP_MASK;
0179 }
0180 
0181 static inline int inat_has_immediate(insn_attr_t attr)
0182 {
0183     return attr & INAT_IMM_MASK;
0184 }
0185 
0186 static inline int inat_immediate_size(insn_attr_t attr)
0187 {
0188     return (attr & INAT_IMM_MASK) >> INAT_IMM_OFFS;
0189 }
0190 
0191 static inline int inat_has_modrm(insn_attr_t attr)
0192 {
0193     return attr & INAT_MODRM;
0194 }
0195 
0196 static inline int inat_is_force64(insn_attr_t attr)
0197 {
0198     return attr & INAT_FORCE64;
0199 }
0200 
0201 static inline int inat_has_second_immediate(insn_attr_t attr)
0202 {
0203     return attr & INAT_SCNDIMM;
0204 }
0205 
0206 static inline int inat_has_moffset(insn_attr_t attr)
0207 {
0208     return attr & INAT_MOFFSET;
0209 }
0210 
0211 static inline int inat_has_variant(insn_attr_t attr)
0212 {
0213     return attr & INAT_VARIANT;
0214 }
0215 
0216 static inline int inat_accept_vex(insn_attr_t attr)
0217 {
0218     return attr & INAT_VEXOK;
0219 }
0220 
0221 static inline int inat_must_vex(insn_attr_t attr)
0222 {
0223     return attr & (INAT_VEXONLY | INAT_EVEXONLY);
0224 }
0225 
0226 static inline int inat_must_evex(insn_attr_t attr)
0227 {
0228     return attr & INAT_EVEXONLY;
0229 }
0230 #endif