Home | History | Annotate | Download | only in libyasm
      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  */
     41 struct 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). */
     79 typedef struct yasm_insn_operand yasm_insn_operand;
     80 
     81 /** The type of an instruction operand. */
     82 typedef 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. */
     91 struct 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  */
    139 struct 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  */
    160 YASM_LIB_DECL
    161 void 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  */
    167 YASM_LIB_DECL
    168 yasm_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  */
    174 YASM_LIB_DECL
    175 yasm_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  */
    181 YASM_LIB_DECL
    182 yasm_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  */
    190 YASM_LIB_DECL
    191 yasm_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  */
    197 yasm_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  */
    204 yasm_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  */
    216 YASM_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  */
    225 YASM_LIB_DECL
    226 void 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  */
    232 YASM_LIB_DECL
    233 void 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  */
    239 YASM_LIB_DECL
    240 void 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  */
    248 YASM_LIB_DECL
    249 void 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  */
    259 YASM_LIB_DECL
    260 void 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  */
    266 YASM_LIB_DECL
    267 void yasm_insn_finalize(yasm_insn *insn);
    268 
    269 #endif
    270