1/**
2 * \file libyasm/insn.h
3 * \brief YASM mnenomic instruction.
4 *
5 * \license
6 *  Copyright (C) 2002-2007  Peter Johnson
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *  - Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 *  - Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 * \endlicense
29 */
30#ifndef YASM_INSN_H
31#define YASM_INSN_H
32
33#ifndef YASM_LIB_DECL
34#define YASM_LIB_DECL
35#endif
36
37/** Base structure for an effective address.  As with all base
38 * structures, must be present as the first element in any
39 * #yasm_arch implementation of an effective address.
40 */
41struct yasm_effaddr {
42    yasm_value disp;            /**< address displacement */
43
44    /** Segment register override (0 if none). */
45    uintptr_t segreg;
46
47    /** 1 if length of disp must be >0. */
48    unsigned int need_nonzero_len:1;
49
50    /** 1 if a displacement should be present in the output. */
51    unsigned int need_disp:1;
52
53    /** 1 if reg*2 should not be split into reg+reg. (0 if not).
54     * This flag indicates (for architectures that support complex effective
55     * addresses such as x86) if various types of complex effective addresses
56     * can be split into different forms in order to minimize instruction
57     * length.
58     */
59    unsigned int nosplit:1;
60
61    /** 1 if effective address is /definitely/ an effective address.
62     * This is used in e.g. the GAS parser to differentiate
63     * between "expr" (which might or might not be an effective address) and
64     * "expr(,1)" (which is definitely an effective address).
65     */
66    unsigned int strong:1;
67
68    /** 1 if effective address is forced PC-relative. */
69    unsigned int pc_rel:1;
70
71    /** 1 if effective address is forced non-PC-relative. */
72    unsigned int not_pc_rel:1;
73
74    /** length of pointed data (in bytes), 0 if unknown. */
75    unsigned int data_len;
76};
77
78/** An instruction operand (opaque type). */
79typedef struct yasm_insn_operand yasm_insn_operand;
80
81/** The type of an instruction operand. */
82typedef enum yasm_insn_operand_type {
83    YASM_INSN__OPERAND_REG = 1,     /**< A register. */
84    YASM_INSN__OPERAND_SEGREG,      /**< A segment register. */
85    YASM_INSN__OPERAND_MEMORY,      /**< An effective address
86                                     *   (memory reference). */
87    YASM_INSN__OPERAND_IMM          /**< An immediate or jump target. */
88} yasm_insn_operand_type;
89
90/** An instruction operand. */
91struct yasm_insn_operand {
92    /** Link for building linked list of operands.  \internal */
93    /*@reldef@*/ STAILQ_ENTRY(yasm_insn_operand) link;
94
95    /** Operand data. */
96    union {
97        uintptr_t reg;      /**< Arch data for reg/segreg. */
98        yasm_effaddr *ea;   /**< Effective address for memory references. */
99        yasm_expr *val;     /**< Value of immediate or jump target. */
100    } data;
101
102    yasm_expr *seg;         /**< Segment expression */
103
104    uintptr_t targetmod;        /**< Arch target modifier, 0 if none. */
105
106    /** Specified size of the operand, in bits.  0 if not user-specified. */
107    unsigned int size:16;
108
109    /** Nonzero if dereference.  Used for "*foo" in GAS.
110     * The reason for this is that by default in GAS, an unprefixed value
111     * is a memory address, except for jumps/calls, in which case it needs a
112     * "*" prefix to become a memory address (otherwise it's an immediate).
113     * This isn't knowable in the parser stage, so the parser sets this flag
114     * to indicate the "*" prefix has been used, and the arch needs to adjust
115     * the operand type appropriately depending on the instruction type.
116     */
117    unsigned int deref:1;
118
119    /** Nonzero if strict.  Used for "strict foo" in NASM.
120     * This is used to inhibit optimization on otherwise "sized" values.
121     * For example, the user may just want to be explicit with the size on
122     * "push dword 4", but not actually want to force the immediate size to
123     * 4 bytes (rather wanting the optimizer to optimize it down to 1 byte as
124     * though "dword" was not specified).  To indicate the immediate should
125     * actually be forced to 4 bytes, the user needs to write
126     * "push strict dword 4", which sets this flag.
127     */
128    unsigned int strict:1;
129
130    /** Operand type. */
131    unsigned int type:4;
132};
133
134/** Base structure for "instruction" bytecodes.  These are the mnenomic
135 * (rather than raw) representation of instructions.  As with all base
136 * structures, must be present as the first element in any
137 * #yasm_arch implementation of mnenomic instruction bytecodes.
138 */
139struct yasm_insn {
140    /** Linked list of operands. */
141    /*@reldef@*/ STAILQ_HEAD(yasm_insn_operands, yasm_insn_operand) operands;
142
143    /** Array of prefixes. */
144    /*@null@*/ uintptr_t *prefixes;
145
146    /** Array of segment prefixes. */
147    /*@null@*/ uintptr_t *segregs;
148
149    unsigned int num_operands;       /**< Number of operands. */
150    unsigned int num_prefixes;       /**< Number of prefixes. */
151    unsigned int num_segregs;        /**< Number of segment prefixes. */
152};
153
154/** Set segment override for an effective address.
155 * Some architectures (such as x86) support segment overrides on effective
156 * addresses.  A override of an override will result in a warning.
157 * \param ea            effective address
158 * \param segreg        segment register (0 if none)
159 */
160YASM_LIB_DECL
161void yasm_ea_set_segreg(yasm_effaddr *ea, uintptr_t segreg);
162
163/** Create an instruction operand from a register.
164 * \param reg   register
165 * \return Newly allocated operand.
166 */
167YASM_LIB_DECL
168yasm_insn_operand *yasm_operand_create_reg(uintptr_t reg);
169
170/** Create an instruction operand from a segment register.
171 * \param segreg        segment register
172 * \return Newly allocated operand.
173 */
174YASM_LIB_DECL
175yasm_insn_operand *yasm_operand_create_segreg(uintptr_t segreg);
176
177/** Create an instruction operand from an effective address.
178 * \param ea    effective address
179 * \return Newly allocated operand.
180 */
181YASM_LIB_DECL
182yasm_insn_operand *yasm_operand_create_mem(/*@only@*/ yasm_effaddr *ea);
183
184/** Create an instruction operand from an immediate expression.
185 * Looks for cases of a single register and creates a register variant of
186 * #yasm_insn_operand.
187 * \param val   immediate expression
188 * \return Newly allocated operand.
189 */
190YASM_LIB_DECL
191yasm_insn_operand *yasm_operand_create_imm(/*@only@*/ yasm_expr *val);
192
193/** Get the first operand in an instruction.
194 * \param insn          instruction
195 * \return First operand (NULL if no operands).
196 */
197yasm_insn_operand *yasm_insn_ops_first(yasm_insn *insn);
198#define yasm_insn_ops_first(insn)   STAILQ_FIRST(&((insn)->operands))
199
200/** Get the next operand in an instruction.
201 * \param op            previous operand
202 * \return Next operand (NULL if op was the last operand).
203 */
204yasm_insn_operand *yasm_insn_op_next(yasm_insn_operand *op);
205#define yasm_insn_op_next(cur)      STAILQ_NEXT(cur, link)
206
207/** Add operand to the end of an instruction.
208 * \note Does not make a copy of the operand; so don't pass this function
209 *       static or local variables, and discard the op pointer after calling
210 *       this function.
211 * \param insn          instruction
212 * \param op            operand (may be NULL)
213 * \return If operand was actually appended (it wasn't NULL), the operand;
214 *         otherwise NULL.
215 */
216YASM_LIB_DECL
217/*@null@*/ yasm_insn_operand *yasm_insn_ops_append
218    (yasm_insn *insn,
219     /*@returned@*/ /*@null@*/ yasm_insn_operand *op);
220
221/** Associate a prefix with an instruction.
222 * \param insn          instruction
223 * \param prefix        data that identifies the prefix
224 */
225YASM_LIB_DECL
226void yasm_insn_add_prefix(yasm_insn *insn, uintptr_t prefix);
227
228/** Associate a segment prefix with an instruction.
229 * \param insn          instruction
230 * \param segreg        data that identifies the segment register
231 */
232YASM_LIB_DECL
233void yasm_insn_add_seg_prefix(yasm_insn *insn, uintptr_t segreg);
234
235/** Initialize the common parts of an instruction.
236 * \internal For use by yasm_arch implementations only.
237 * \param insn          instruction
238 */
239YASM_LIB_DECL
240void yasm_insn_initialize(/*@out@*/ yasm_insn *insn);
241
242/** Delete the common parts of an instruction.
243 * \internal For use by yasm_arch implementations only.
244 * \param insn          instruction
245 * \param content       if nonzero, deletes content of each operand
246 * \param arch          architecture
247 */
248YASM_LIB_DECL
249void yasm_insn_delete(yasm_insn *insn,
250                      void (*ea_destroy) (/*@only@*/ yasm_effaddr *));
251
252/** Print a list of instruction operands.  For debugging purposes.
253 * \internal For use by yasm_arch implementations only.
254 * \param insn          instruction
255 * \param f             file
256 * \param indent_level  indentation level
257 * \param arch          architecture
258 */
259YASM_LIB_DECL
260void yasm_insn_print(const yasm_insn *insn, FILE *f, int indent_level);
261
262/** Finalize the common parts of an instruction.
263 * \internal For use by yasm_arch implementations only.
264 * \param insn          instruction
265 */
266YASM_LIB_DECL
267void yasm_insn_finalize(yasm_insn *insn);
268
269#endif
270