| /* $IdPath$ |
| * x86 Architecture header file |
| * |
| * Copyright (C) 2001 Peter Johnson |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| */ |
| #ifndef YASM_X86ARCH_H |
| #define YASM_X86ARCH_H |
| |
| typedef enum { |
| X86_BC_INSN = YASM_BYTECODE_TYPE_BASE, |
| X86_BC_JMP |
| } x86_bytecode_type; |
| #define X86_BYTECODE_TYPE_MAX X86_BC_JMP+1 |
| |
| /* 0-15 (low 4 bits) used for register number, stored in same data area. |
| * Note 8-15 are only valid for some registers, and only in 64-bit mode. |
| */ |
| typedef enum { |
| X86_REG8 = 0x1<<4, |
| X86_REG8X = 0x2<<4, /* 64-bit mode only, REX prefix version of REG8 */ |
| X86_REG16 = 0x3<<4, |
| X86_REG32 = 0x4<<4, |
| X86_REG64 = 0x5<<4, /* 64-bit mode only */ |
| X86_FPUREG = 0x6<<4, |
| X86_MMXREG = 0x7<<4, |
| X86_XMMREG = 0x8<<4, |
| X86_CRREG = 0x9<<4, |
| X86_DRREG = 0xA<<4, |
| X86_TRREG = 0xB<<4, |
| X86_RIP = 0xC<<4 /* 64-bit mode only, always RIP (regnum ignored) */ |
| } x86_expritem_reg_size; |
| |
| typedef enum { |
| X86_LOCKREP = 1, |
| X86_ADDRSIZE, |
| X86_OPERSIZE |
| } x86_parse_insn_prefix; |
| |
| typedef enum { |
| X86_NEAR = 1, |
| X86_SHORT, |
| X86_FAR, |
| X86_TO |
| } x86_parse_targetmod; |
| |
| typedef enum { |
| JMP_NONE, |
| JMP_SHORT, |
| JMP_NEAR, |
| JMP_SHORT_FORCED, |
| JMP_NEAR_FORCED, |
| JMP_FAR /* not really relative, but fits here */ |
| } x86_jmp_opcode_sel; |
| |
| typedef enum { |
| X86_REX_W = 3, |
| X86_REX_R = 2, |
| X86_REX_X = 1, |
| X86_REX_B = 0 |
| } x86_rex_bit_pos; |
| |
| /* Sets REX (4th bit) and 3 LS bits from register size/number. Returns 1 if |
| * impossible to fit reg into REX, otherwise returns 0. Input parameter rexbit |
| * indicates bit of REX to use if REX is needed. Will not modify REX if not |
| * in 64-bit mode or if it wasn't needed to express reg. |
| */ |
| int yasm_x86__set_rex_from_reg(unsigned char *rex, unsigned char *low3, |
| unsigned long reg, unsigned int bits, |
| x86_rex_bit_pos rexbit); |
| |
| void yasm_x86__ea_set_segment(/*@null@*/ yasm_effaddr *ea, |
| unsigned int segment, unsigned long lindex); |
| void yasm_x86__ea_set_disponly(yasm_effaddr *ea); |
| yasm_effaddr *yasm_x86__ea_new_reg(unsigned long reg, unsigned char *rex, |
| unsigned int bits); |
| yasm_effaddr *yasm_x86__ea_new_imm(/*@keep@*/ yasm_expr *imm, |
| unsigned int im_len); |
| yasm_effaddr *yasm_x86__ea_new_expr(/*@keep@*/ yasm_expr *e); |
| |
| /*@observer@*/ /*@null@*/ yasm_effaddr *yasm_x86__bc_insn_get_ea |
| (/*@null@*/ yasm_bytecode *bc); |
| |
| void yasm_x86__bc_insn_opersize_override(yasm_bytecode *bc, |
| unsigned int opersize); |
| void yasm_x86__bc_insn_addrsize_override(yasm_bytecode *bc, |
| unsigned int addrsize); |
| void yasm_x86__bc_insn_set_lockrep_prefix(yasm_bytecode *bc, |
| unsigned int prefix, |
| unsigned long lindex); |
| |
| /* Structure with *all* inputs passed to x86_bytecode_new_insn(). |
| * IMPORTANT: ea_ptr and im_ptr cannot be reused or freed after calling the |
| * function (it doesn't make a copy). |
| */ |
| typedef struct x86_new_insn_data { |
| unsigned long lindex; |
| /*@keep@*/ /*@null@*/ yasm_effaddr *ea; |
| /*@keep@*/ /*@null@*/ yasm_expr *imm; |
| unsigned char opersize; |
| unsigned char op_len; |
| unsigned char op[3]; |
| unsigned char spare; /* bits to go in 'spare' field of ModRM */ |
| unsigned char rex; |
| unsigned char im_len; |
| unsigned char im_sign; |
| unsigned char shift_op; |
| unsigned char signext_imm8_op; |
| } x86_new_insn_data; |
| |
| yasm_bytecode *yasm_x86__bc_new_insn(x86_new_insn_data *d); |
| |
| /* Structure with *all* inputs passed to x86_bytecode_new_jmp(). |
| * Pass 0 for the opcode_len if that version of the opcode doesn't exist. |
| */ |
| typedef struct x86_new_jmp_data { |
| unsigned long lindex; |
| /*@keep@*/ yasm_expr *target; |
| /*@dependent@*/ yasm_symrec *origin; |
| x86_jmp_opcode_sel op_sel; |
| unsigned char short_op_len; |
| unsigned char short_op[3]; |
| unsigned char near_op_len; |
| unsigned char near_op[3]; |
| unsigned char far_op_len; |
| unsigned char far_op[3]; |
| unsigned char addrsize; |
| unsigned char opersize; |
| } x86_new_jmp_data; |
| |
| yasm_bytecode *yasm_x86__bc_new_jmp(x86_new_jmp_data *d); |
| |
| extern unsigned char yasm_x86_LTX_mode_bits; |
| |
| void yasm_x86__bc_delete(yasm_bytecode *bc); |
| void yasm_x86__bc_print(FILE *f, int indent_level, const yasm_bytecode *bc); |
| yasm_bc_resolve_flags yasm_x86__bc_resolve |
| (yasm_bytecode *bc, int save, const yasm_section *sect, |
| yasm_calc_bc_dist_func calc_bc_dist); |
| int yasm_x86__bc_tobytes(yasm_bytecode *bc, unsigned char **bufp, |
| const yasm_section *sect, void *d, |
| yasm_output_expr_func output_expr); |
| |
| int yasm_x86__expr_checkea |
| (yasm_expr **ep, unsigned char *addrsize, unsigned int bits, |
| unsigned int nosplit, unsigned char *displen, unsigned char *modrm, |
| unsigned char *v_modrm, unsigned char *n_modrm, unsigned char *sib, |
| unsigned char *v_sib, unsigned char *n_sib, unsigned char *rex, |
| yasm_calc_bc_dist_func calc_bc_dist); |
| |
| void yasm_x86__switch_cpu(const char *cpuid, unsigned long lindex); |
| |
| yasm_arch_check_id_retval yasm_x86__check_identifier |
| (unsigned long data[2], const char *id, unsigned long lindex); |
| |
| int yasm_x86__directive(const char *name, yasm_valparamhead *valparams, |
| /*@null@*/ yasm_valparamhead *objext_valparams, |
| yasm_sectionhead *headp, unsigned long lindex); |
| |
| /*@null@*/ yasm_bytecode *yasm_x86__new_insn |
| (const unsigned long data[2], int num_operands, |
| /*@null@*/ yasm_insn_operandhead *operands, yasm_section *cur_section, |
| /*@null@*/ yasm_bytecode *prev_bc, unsigned long lindex); |
| |
| void yasm_x86__handle_prefix(yasm_bytecode *bc, const unsigned long data[4], |
| unsigned long lindex); |
| |
| void yasm_x86__handle_seg_prefix(yasm_bytecode *bc, unsigned long segreg, |
| unsigned long lindex); |
| |
| void yasm_x86__handle_seg_override(yasm_effaddr *ea, unsigned long segreg, |
| unsigned long lindex); |
| |
| int yasm_x86__floatnum_tobytes(const yasm_floatnum *flt, unsigned char **bufp, |
| unsigned long valsize, const yasm_expr *e); |
| int yasm_x86__intnum_tobytes(const yasm_intnum *intn, unsigned char **bufp, |
| unsigned long valsize, const yasm_expr *e, |
| const yasm_bytecode *bc, int rel); |
| |
| unsigned int yasm_x86__get_reg_size(unsigned long reg); |
| |
| void yasm_x86__reg_print(FILE *f, unsigned long reg); |
| |
| void yasm_x86__segreg_print(FILE *f, unsigned long segreg); |
| |
| void yasm_x86__ea_data_print(FILE *f, int indent_level, |
| const yasm_effaddr *ea); |
| |
| #endif |