1 /*BEGIN_LEGAL
2
3 Copyright (c) 2018 Intel Corporation
4
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16
17 END_LEGAL */
18
19 /// @file xed-ild-private.h
20 /// instruction length decoder private header
21
22 #if !defined(XED_ILD_PRIVATE_H)
23 # define XED_ILD_PRIVATE_H
24
25
26
27
28 #include "xed-ild.h"
29 #include "xed-machine-mode-enum.h"
xed_modrm_mod(xed_uint8_t m)30 static XED_INLINE xed_uint_t xed_modrm_mod(xed_uint8_t m) { return m>>6; }
xed_modrm_reg(xed_uint8_t m)31 static XED_INLINE xed_uint_t xed_modrm_reg(xed_uint8_t m) { return (m>>3)&7; }
xed_modrm_rm(xed_uint8_t m)32 static XED_INLINE xed_uint_t xed_modrm_rm(xed_uint8_t m) { return m&7; }
xed_sib_scale(xed_uint8_t m)33 static XED_INLINE xed_uint_t xed_sib_scale(xed_uint8_t m) { return m>>6; }
xed_sib_index(xed_uint8_t m)34 static XED_INLINE xed_uint_t xed_sib_index(xed_uint8_t m) { return (m>>3)&7; }
xed_sib_base(xed_uint8_t m)35 static XED_INLINE xed_uint_t xed_sib_base(xed_uint8_t m) { return m&7; }
bits2bytes(xed_uint_t bits)36 static XED_INLINE xed_uint_t bits2bytes(xed_uint_t bits) { return bits>>3; }
bytes2bits(xed_uint_t bytes)37 static XED_INLINE xed_uint_t bytes2bits(xed_uint_t bytes) { return bytes<<3; }
38
39
40 typedef void(*xed_ild_l1_func_t)(xed_decoded_inst_t*);
41 typedef xed_uint32_t(*xed3_find_func_t)(const xed_decoded_inst_t*);
42
43 typedef struct {xed_uint32_t key; xed_uint32_t value;} lu1_entry_t;
44 typedef struct {xed_uint32_t key; xed3_find_func_t l2_func;} lu2_entry_t;
45
46
47 typedef enum {
48 XED_ILD_MAP0,
49 XED_ILD_MAP1, /* 0F */
50 XED_ILD_MAP2, /* 0F38 */
51 XED_ILD_MAP3, /* 0F3A */
52 XED_ILD_MAP4, /* required placeholders */
53 XED_ILD_MAP5,
54 XED_ILD_MAP6,
55 XED_ILD_MAPAMD, /* fake map 7 - amd 3dnow */
56 XED_ILD_MAP_XOP8, /* amd xop */
57 XED_ILD_MAP_XOP9, /* amd xop */
58 XED_ILD_MAP_XOPA, /* amd xop */
59 XED_ILD_MAP_LAST, /* for array sizing */
60 XED_ILD_MAP_INVALID /* for error handling */
61 } xed_ild_map_enum_t;
62
63
64 #define XED_GRAMMAR_MODE_64 2
65 #define XED_GRAMMAR_MODE_32 1
66 #define XED_GRAMMAR_MODE_16 0
67
68 /*
69 Double immediate instructions are special. There are only 3 of them
70 and anyway they require a special care. It seems that the simplest way
71 is just to define L1 functions for both such map-opcode pairs:
72 (0x0F,0x78) and (0x0, 0xC8)
73 */
74
75 /* (0x0f,0x78) map-opcode pair is even more special, because it has a conflict
76 on imm_bytes between AMD's INSERTQ,EXTRQ and Intel's VMREAD.
77 We already hardcode L1 functions for double immediate instructions, so we will
78 hardcode a conflict resolution here too. */
xed_ild_hasimm_map0x0F_op0x78_l1(xed_decoded_inst_t * x)79 static XED_INLINE void xed_ild_hasimm_map0x0F_op0x78_l1(xed_decoded_inst_t* x) {
80 /*FIXME: f3 prefix is not mentioned in INSERTQ or EXTRQ grammar
81 definitions, however is forbidden for VMREAD. It seems that it can
82 go with INSERTQ and EXTRQ. Right? */
83 if (xed3_operand_get_osz(x) ||
84 xed3_operand_get_ild_f2(x)
85 // || xed3_operand_get_ild_f3(x)
86 )
87 {
88 /*for INSERTQ and EXTRQ*/
89 /*straight in bytes*/
90 xed3_operand_set_imm_width(x, bytes2bits(1));
91 xed3_operand_set_imm1_bytes(x, 1);
92 return;
93 }
94 /* for VMREAD imm_bytes is 0*/
95 }
96
97 /*ENTER instruction has UIMM16 and UIMM8_1 NTs*/
xed_ild_hasimm_map0x0_op0xc8_l1(xed_decoded_inst_t * x)98 static XED_INLINE void xed_ild_hasimm_map0x0_op0xc8_l1(xed_decoded_inst_t* x) {
99 /* for ENTER */
100 /*straight in bytes*/
101 xed3_operand_set_imm_width(x, bytes2bits(2));
102 xed3_operand_set_imm1_bytes(x, 1);
103 }
104
105 /*FIXME: need to put getters in scanners headers to keep layering working*/
106
107 /// Convert xed_machine_mode_enum_t to a corresponding xed_bits_t value
108 /// for MODE operand
109 /// @param mmode - machine mode in xed_machine_mode_enum_t type
110 /// @return mode value for MODE operand in xed_bits_t type
111 ///
112 /// @ingroup ILD
113 xed_bits_t xed_ild_cvt_mode(xed_machine_mode_enum_t mmode);
114
115 /// Initialize internal data structures of the ILD.
116 void xed_ild_init_decoder(void);
117
118
119
120 /* Special getter for RM */
121 static XED_INLINE xed_uint_t
xed_ild_get_rm(const xed_decoded_inst_t * ild)122 xed_ild_get_rm(const xed_decoded_inst_t* ild) {
123 /* Sometimes we don't have modrm, but grammar still
124 * likes to use RM operand - in this case it is first
125 * 3 bits of the opcode.
126 */
127 xed_uint8_t modrm;
128 if (xed3_operand_get_has_modrm(ild))
129 return xed3_operand_get_rm(ild);
130 modrm = xed3_operand_get_nominal_opcode(ild);
131 return xed_modrm_rm(modrm);
132 }
133
134 /* compressed operand getters */
135 static XED_INLINE xed_uint_t
xed3_operand_get_mod3(const xed_decoded_inst_t * ild)136 xed3_operand_get_mod3(const xed_decoded_inst_t* ild) {
137 return xed3_operand_get_mod(ild) == 3;
138 }
139
140 static XED_INLINE xed_uint_t
xed3_operand_get_rm4(const xed_decoded_inst_t * ild)141 xed3_operand_get_rm4(const xed_decoded_inst_t* ild) {
142 return xed3_operand_get_rm(ild) == 4;
143 }
144
145 static XED_INLINE xed_uint_t
xed3_operand_get_uimm0_1(const xed_decoded_inst_t * ild)146 xed3_operand_get_uimm0_1(const xed_decoded_inst_t* ild) {
147 return xed3_operand_get_uimm0(ild) == 1;
148 }
149
150
151 #if defined(XED_AVX)
152 static XED_INLINE xed_uint_t
xed3_operand_get_vexdest210_7(const xed_decoded_inst_t * ild)153 xed3_operand_get_vexdest210_7(const xed_decoded_inst_t* ild) {
154 return xed3_operand_get_vexdest210(ild) == 7;
155 }
156 #endif
157
158 #if defined(XED_SUPPORTS_AVX512)
159 static XED_INLINE
xed3_operand_get_mask_not0(const xed_decoded_inst_t * d)160 xed_uint32_t xed3_operand_get_mask_not0(const xed_decoded_inst_t *d) {
161 /* aaa != 0 */
162 return xed3_operand_get_mask(d) != 0;
163 }
164 static XED_INLINE
xed3_operand_get_mask_zero(const xed_decoded_inst_t * d)165 xed_uint32_t xed3_operand_get_mask_zero(const xed_decoded_inst_t *d) {
166 /* aaa == 0 */
167 return xed3_operand_get_mask(d) == 0;
168 }
169 #endif
170
171 void
172 xed_instruction_length_decode(xed_decoded_inst_t* d);
173
174
175 #endif
176
177