1/* Copyright (c) 2007, Google Inc.
2 * All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 *     * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *     * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 *     * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * ---
31 * Author: Joi Sigurdsson
32 *
33 * Several simple types used by the disassembler and some of the patching
34 * mechanisms.
35 */
36
37#ifndef GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_TYPES_H_
38#define GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_TYPES_H_
39
40namespace sidestep {
41
42// Categories of instructions that we care about
43enum InstructionType {
44  // This opcode is not used
45  IT_UNUSED,
46  // This disassembler does not recognize this opcode (error)
47  IT_UNKNOWN,
48  // This is not an instruction but a reference to another table
49  IT_REFERENCE,
50  // This byte is a prefix byte that we can ignore
51  IT_PREFIX,
52  // This is a prefix byte that switches to the nondefault address size
53  IT_PREFIX_ADDRESS,
54  // This is a prefix byte that switches to the nondefault operand size
55  IT_PREFIX_OPERAND,
56  // A jump or call instruction
57  IT_JUMP,
58  // A return instruction
59  IT_RETURN,
60  // Any other type of instruction (in this case we don't care what it is)
61  IT_GENERIC,
62};
63
64// Lists IA-32 operand sizes in multiples of 8 bits
65enum OperandSize {
66  OS_ZERO = 0,
67  OS_BYTE = 1,
68  OS_WORD = 2,
69  OS_DOUBLE_WORD = 4,
70  OS_QUAD_WORD = 8,
71  OS_DOUBLE_QUAD_WORD = 16,
72  OS_32_BIT_POINTER = 32/8,
73  OS_48_BIT_POINTER = 48/8,
74  OS_SINGLE_PRECISION_FLOATING = 32/8,
75  OS_DOUBLE_PRECISION_FLOATING = 64/8,
76  OS_DOUBLE_EXTENDED_PRECISION_FLOATING = 80/8,
77  OS_128_BIT_PACKED_SINGLE_PRECISION_FLOATING = 128/8,
78  OS_PSEUDO_DESCRIPTOR = 6
79};
80
81// Operand addressing methods from the IA-32 manual.  The enAmMask value
82// is a mask for the rest.  The other enumeration values are named for the
83// names given to the addressing methods in the manual, e.g. enAm_D is for
84// the D addressing method.
85//
86// The reason we use a full 4 bytes and a mask, is that we need to combine
87// these flags with the enOperandType to store the details
88// on the operand in a single integer.
89enum AddressingMethod {
90  AM_NOT_USED = 0,        // This operand is not used for this instruction
91  AM_MASK = 0x00FF0000,  // Mask for the rest of the values in this enumeration
92  AM_A = 0x00010000,    // A addressing type
93  AM_C = 0x00020000,    // C addressing type
94  AM_D = 0x00030000,    // D addressing type
95  AM_E = 0x00040000,    // E addressing type
96  AM_F = 0x00050000,    // F addressing type
97  AM_G = 0x00060000,    // G addressing type
98  AM_I = 0x00070000,    // I addressing type
99  AM_J = 0x00080000,    // J addressing type
100  AM_M = 0x00090000,    // M addressing type
101  AM_O = 0x000A0000,    // O addressing type
102  AM_P = 0x000B0000,    // P addressing type
103  AM_Q = 0x000C0000,    // Q addressing type
104  AM_R = 0x000D0000,    // R addressing type
105  AM_S = 0x000E0000,    // S addressing type
106  AM_T = 0x000F0000,    // T addressing type
107  AM_V = 0x00100000,    // V addressing type
108  AM_W = 0x00110000,    // W addressing type
109  AM_X = 0x00120000,    // X addressing type
110  AM_Y = 0x00130000,    // Y addressing type
111  AM_REGISTER = 0x00140000,  // Specific register is always used as this op
112  AM_IMPLICIT = 0x00150000,  // An implicit, fixed value is used
113};
114
115// Operand types from the IA-32 manual. The enOtMask value is
116// a mask for the rest. The rest of the values are named for the
117// names given to these operand types in the manual, e.g. enOt_ps
118// is for the ps operand type in the manual.
119//
120// The reason we use a full 4 bytes and a mask, is that we need
121// to combine these flags with the enAddressingMethod to store the details
122// on the operand in a single integer.
123enum OperandType {
124  OT_MASK = 0xFF000000,
125  OT_A = 0x01000000,
126  OT_B = 0x02000000,
127  OT_C = 0x03000000,
128  OT_D = 0x04000000,
129  OT_DQ = 0x05000000,
130  OT_P = 0x06000000,
131  OT_PI = 0x07000000,
132  OT_PS = 0x08000000,  // actually unsupported for (we don't know its size)
133  OT_Q = 0x09000000,
134  OT_S = 0x0A000000,
135  OT_SS = 0x0B000000,
136  OT_SI = 0x0C000000,
137  OT_V = 0x0D000000,
138  OT_W = 0x0E000000,
139  OT_SD = 0x0F000000,  // scalar double-precision floating-point value
140  OT_PD = 0x10000000,  // double-precision floating point
141  // dummy "operand type" for address mode M - which doesn't specify
142  // operand type
143  OT_ADDRESS_MODE_M = 0x80000000
144};
145
146// Flag that indicates if an immediate operand is 64-bits.
147//
148// The Intel 64 and IA-32 Architecture Software Developer's Manual currently
149// defines MOV as the only instruction supporting a 64-bit immediate operand.
150enum ImmediateOperandSize {
151  IOS_MASK = 0x0000F000,
152  IOS_DEFAULT = 0x0,
153  IOS_64 = 0x00001000
154};
155
156// Everything that's in an Opcode (see below) except the three
157// alternative opcode structs for different prefixes.
158struct SpecificOpcode {
159  // Index to continuation table, or 0 if this is the last
160  // byte in the opcode.
161  int table_index_;
162
163  // The opcode type
164  InstructionType type_;
165
166  // Description of the type of the dest, src and aux operands,
167  // put together from enOperandType, enAddressingMethod and
168  // enImmediateOperandSize flags.
169  int flag_dest_;
170  int flag_source_;
171  int flag_aux_;
172
173  // We indicate the mnemonic for debugging purposes
174  const char* mnemonic_;
175};
176
177// The information we keep in our tables about each of the different
178// valid instructions recognized by the IA-32 architecture.
179struct Opcode {
180  // Index to continuation table, or 0 if this is the last
181  // byte in the opcode.
182  int table_index_;
183
184  // The opcode type
185  InstructionType type_;
186
187  // Description of the type of the dest, src and aux operands,
188  // put together from an enOperandType flag and an enAddressingMethod
189  // flag.
190  int flag_dest_;
191  int flag_source_;
192  int flag_aux_;
193
194  // We indicate the mnemonic for debugging purposes
195  const char* mnemonic_;
196
197  // Alternative opcode info if certain prefixes are specified.
198  // In most cases, all of these are zeroed-out.  Only used if
199  // bPrefixDependent is true.
200  bool is_prefix_dependent_;
201  SpecificOpcode opcode_if_f2_prefix_;
202  SpecificOpcode opcode_if_f3_prefix_;
203  SpecificOpcode opcode_if_66_prefix_;
204};
205
206// Information about each table entry.
207struct OpcodeTable {
208  // Table of instruction entries
209  const Opcode* table_;
210  // How many bytes left to shift ModR/M byte <b>before</b> applying mask
211  unsigned char shift_;
212  // Mask to apply to byte being looked at before comparing to table
213  unsigned char mask_;
214  // Minimum/maximum indexes in table.
215  unsigned char min_lim_;
216  unsigned char max_lim_;
217};
218
219// Information about each entry in table used to decode ModR/M byte.
220struct ModrmEntry {
221  // Is the operand encoded as bytes in the instruction (rather than
222  // if it's e.g. a register in which case it's just encoded in the
223  // ModR/M byte)
224  bool is_encoded_in_instruction_;
225
226  // Is there a SIB byte?  In this case we always need to decode it.
227  bool use_sib_byte_;
228
229  // What is the size of the operand (only important if it's encoded
230  // in the instruction)?
231  OperandSize operand_size_;
232};
233
234};  // namespace sidestep
235
236#endif  // GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_TYPES_H_
237