/* ----------------------------------------------------------------------- * * * Copyright 1996-2020 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following * conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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 COPYRIGHT HOLDERS AND * 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 COPYRIGHT OWNER OR * 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. * * ----------------------------------------------------------------------- */ /* * assemble.c code generation for the Netwide Assembler * * Bytecode specification * ---------------------- * * * Codes Mnemonic Explanation * * \0 terminates the code. (Unless it's a literal of course.) * \1..\4 that many literal bytes follow in the code stream * \5 add 4 to the primary operand number (b, low octdigit) * \6 add 4 to the secondary operand number (a, middle octdigit) * \7 add 4 to both the primary and the secondary operand number * \10..\13 a literal byte follows in the code stream, to be added * to the register value of operand 0..3 * \14..\17 the position of index register operand in MIB (BND insns) * \20..\23 ib a byte immediate operand, from operand 0..3 * \24..\27 ib,u a zero-extended byte immediate operand, from operand 0..3 * \30..\33 iw a word immediate operand, from operand 0..3 * \34..\37 iwd select between \3[0-3] and \4[0-3] depending on 16/32 bit * assembly mode or the operand-size override on the operand * \40..\43 id a long immediate operand, from operand 0..3 * \44..\47 iwdq select between \3[0-3], \4[0-3] and \5[4-7] * depending on the address size of the instruction. * \50..\53 rel8 a byte relative operand, from operand 0..3 * \54..\57 iq a qword immediate operand, from operand 0..3 * \60..\63 rel16 a word relative operand, from operand 0..3 * \64..\67 rel select between \6[0-3] and \7[0-3] depending on 16/32 bit * assembly mode or the operand-size override on the operand * \70..\73 rel32 a long relative operand, from operand 0..3 * \74..\77 seg a word constant, from the _segment_ part of operand 0..3 * \1ab a ModRM, calculated on EA in operand a, with the spare * field the register value of operand b. * \172\ab the register number from operand a in bits 7..4, with * the 4-bit immediate from operand b in bits 3..0. * \173\xab the register number from operand a in bits 7..4, with * the value b in bits 3..0. * \174..\177 the register number from operand 0..3 in bits 7..4, and * an arbitrary value in bits 3..0 (assembled as zero.) * \2ab a ModRM, calculated on EA in operand a, with the spare * field equal to digit b. * * \240..\243 this instruction uses EVEX rather than REX or VEX/XOP, with the * V field taken from operand 0..3. * \250 this instruction uses EVEX rather than REX or VEX/XOP, with the * V field set to 1111b. * * EVEX prefixes are followed by the sequence: * \cm\wlp\tup where cm is: * cc 00m mmm * c = 2 for EVEX and mmmm is the M field (EVEX.P0[3:0]) * and wlp is: * 00 wwl lpp * [l0] ll = 0 (.128, .lz) * [l1] ll = 1 (.256) * [l2] ll = 2 (.512) * [lig] ll = 3 for EVEX.L'L don't care (always assembled as 0) * * [w0] ww = 0 for W = 0 * [w1] ww = 1 for W = 1 * [wig] ww = 2 for W don't care (always assembled as 0) * [ww] ww = 3 for W used as REX.W * * [p0] pp = 0 for no prefix * [60] pp = 1 for legacy prefix 60 * [f3] pp = 2 * [f2] pp = 3 * * tup is tuple type for Disp8*N from %tuple_codes in insns.pl * (compressed displacement encoding) * * \254..\257 id,s a signed 32-bit operand to be extended to 64 bits. * \260..\263 this instruction uses VEX/XOP rather than REX, with the * V field taken from operand 0..3. * \270 this instruction uses VEX/XOP rather than REX, with the * V field set to 1111b. * * VEX/XOP prefixes are followed by the sequence: * \tmm\wlp where mm is the M field; and wlp is: * 00 wwl lpp * [l0] ll = 0 for L = 0 (.128, .lz) * [l1] ll = 1 for L = 1 (.256) * [lig] ll = 2 for L don't care (always assembled as 0) * * [w0] ww = 0 for W = 0 * [w1 ] ww = 1 for W = 1 * [wig] ww = 2 for W don't care (always assembled as 0) * [ww] ww = 3 for W used as REX.W * * t = 0 for VEX (C4/C5), t = 1 for XOP (8F). * * \271 hlexr instruction takes XRELEASE (F3) with or without lock * \272 hlenl instruction takes XACQUIRE/XRELEASE with or without lock * \273 hle instruction takes XACQUIRE/XRELEASE with lock only * \274..\277 ib,s a byte immediate operand, from operand 0..3, sign-extended * to the operand size (if o16/o32/o64 present) or the bit size * \310 a16 indicates fixed 16-bit address size, i.e. optional 0x67. * \311 a32 indicates fixed 32-bit address size, i.e. optional 0x67. * \312 adf (disassembler only) invalid with non-default address size. * \313 a64 indicates fixed 64-bit address size, 0x67 invalid. * \314 norexb (disassembler only) invalid with REX.B * \315 norexx (disassembler only) invalid with REX.X * \316 norexr (disassembler only) invalid with REX.R * \317 norexw (disassembler only) invalid with REX.W * \320 o16 indicates fixed 16-bit operand size, i.e. optional 0x66. * \321 o32 indicates fixed 32-bit operand size, i.e. optional 0x66. * \322 odf indicates that this instruction is only valid when the * operand size is the default (instruction to disassembler, * generates no code in the assembler) * \323 o64nw indicates fixed 64-bit operand size, REX on extensions only. * \324 o64 indicates 64-bit operand size requiring REX prefix. * \325 nohi instruction which always uses spl/bpl/sil/dil * \326 nof3 instruction not valid with 0xF3 REP prefix. Hint for disassembler only; for SSE instructions. * \330 a literal byte follows in the code stream, to be added * to the condition code value of the instruction. * \331 norep instruction not valid with REP prefix. Hint for * disassembler only; for SSE instructions. * \332 f2i REP prefix (0xF2 byte) used as opcode extension. * \333 f3i REP prefix (0xF3 byte) used as opcode extension. * \334 rex.l LOCK prefix used as REX.R (used in non-64-bit mode) * \335 repe disassemble a rep (0xF3 byte) prefix as repe not rep. * \336 mustrep force a REP(E) prefix (0xF3) even if not specified. * \337 mustrepne force a REPNE prefix (0xF2) even if not specified. * \336-\337 are still listed as prefixes in the disassembler. * \340 resb reserve <operand 0> bytes of uninitialized storage. * Operand 0 had better be a segmentless constant. * \341 wait this instruction needs a WAIT "prefix" * \360 np no SSE prefix (== \364\331) * \361 66 SSE prefix (== \366\331) * \364 !osp operand-size prefix (0x66) not permitted * \365 !asp address-size prefix (0x67) not permitted * \366 operand-size prefix (0x66) used as opcode extension * \367 address-size prefix (0x67) used as opcode extension * \370,\371 jcc8 match only if operand 0 meets byte jump criteria. * jmp8 370 is used for Jcc, 371 is used for JMP. * \373 jlen assemble 0x03 if bits==16, 0x05 if bits==32; * used for conditional jump over longer jump * \374 vsibx|vm32x|vm64x this instruction takes an XMM VSIB memory EA * \375 vsiby|vm32y|vm64y this instruction takes an YMM VSIB memory EA * \376 vsibz|vm32z|vm64z this instruction takes an ZMM VSIB memory EA */ #include "compiler.h" #include "nasm.h" #include "nasmlib.h" #include "error.h" #include "assemble.h" #include "insns.h" #include "tables.h" #include "disp8.h" #include "listing.h" enum match_result { … }; ea; #define GEN_SIB(scale, index, base) … #define GEN_MODRM(mod, reg, rm) … static int64_t calcsize(int32_t, int64_t, int, insn *, const struct itemplate *); static int emit_prefix(struct out_data *data, const int bits, insn *ins); static void gencode(struct out_data *data, insn *ins); static enum match_result find_match(const struct itemplate **tempp, insn *instruction, int32_t segment, int64_t offset, int bits); static enum match_result matches(const struct itemplate *, insn *, int bits); static opflags_t regflag(const operand *); static int32_t regval(const operand *); static int rexflags(int, opflags_t, int); static int op_rexflags(const operand *, int); static int op_evexflags(const operand *, int, uint8_t); static void add_asp(insn *, int); static enum ea_type process_ea(operand *, ea *, int, int, opflags_t, insn *, const char **); static inline bool absolute_op(const struct operand *o) { … } static int has_prefix(insn * ins, enum prefix_pos pos, int prefix) { … } static void assert_no_prefix(insn * ins, enum prefix_pos pos) { … } static const char *size_name(int size) { … } static void warn_overflow(int size) { … } static void warn_overflow_const(int64_t data, int size) { … } static void warn_overflow_out(int64_t data, int size, enum out_sign sign) { … } /* * This routine wrappers the real output format's output routine, * in order to pass a copy of the data off to the listing file * generator at the same time, flatten unnecessary relocations, * and verify backend compatibility. */ /* * This warning is currently issued by backends, but in the future * this code should be centralized. * *!zeroing [on] RESx in initialized section becomes zero *! a \c{RESx} directive was used in a section which contains *! initialized data, and the output format does not support *! this. Instead, this will be replaced with explicit zero *! content, which may produce a large output file. */ static void out(struct out_data *data) { … } static inline void out_rawdata(struct out_data *data, const void *rawdata, size_t size) { … } static void out_rawbyte(struct out_data *data, uint8_t byte) { … } static inline void out_reserve(struct out_data *data, uint64_t size) { … } static void out_segment(struct out_data *data, const struct operand *opx) { … } static void out_imm(struct out_data *data, const struct operand *opx, int size, enum out_sign sign) { … } static void out_reladdr(struct out_data *data, const struct operand *opx, int size) { … } static bool jmp_match(int32_t segment, int64_t offset, int bits, insn * ins, const struct itemplate *temp) { … } static inline int64_t merge_resb(insn *ins, int64_t isize) { … } /* This must be handle non-power-of-2 alignment values */ static inline size_t pad_bytes(size_t len, size_t align) { … } static void out_eops(struct out_data *data, const extop *e) { … } /* This is totally just a wild guess what is reasonable... */ #define INCBIN_MAX_BUF … int64_t assemble(int32_t segment, int64_t start, int bits, insn *instruction) { … } static int32_t eops_typeinfo(const extop *e) { … } static inline void debug_set_db_type(insn *instruction) { … } static void debug_set_type(insn *instruction) { … } /* Proecess an EQU directive */ static void define_equ(insn * instruction) { … } static int64_t len_extops(const extop *e) { … } int64_t insn_size(int32_t segment, int64_t offset, int bits, insn *instruction) { … } static void bad_hle_warn(const insn * ins, uint8_t hleok) { … } /* Common construct */ #define case3(x) … #define case4(x) … static int64_t calcsize(int32_t segment, int64_t offset, int bits, insn * ins, const struct itemplate *temp) { … } static inline void emit_rex(struct out_data *data, insn *ins) { … } static int emit_prefix(struct out_data *data, const int bits, insn *ins) { … } static void gencode(struct out_data *data, insn *ins) { … } static opflags_t regflag(const operand * o) { … } static int32_t regval(const operand * o) { … } static int op_rexflags(const operand * o, int mask) { … } static int rexflags(int val, opflags_t flags, int mask) { … } static int evexflags(int val, decoflags_t deco, int mask, uint8_t byte) { … } static int op_evexflags(const operand * o, int mask, uint8_t byte) { … } static enum match_result find_match(const struct itemplate **tempp, insn *instruction, int32_t segment, int64_t offset, int bits) { … } static uint8_t get_broadcast_num(opflags_t opflags, opflags_t brsize) { … } static enum match_result matches(const struct itemplate *itemp, insn *instruction, int bits) { … } /* * Check if ModR/M.mod should/can be 01. * - EAF_BYTEOFFS is set * - offset can fit in a byte when EVEX is not used * - offset can be compressed when EVEX is used */ #define IS_MOD_01() … static enum ea_type process_ea(operand *input, ea *output, int bits, int rfield, opflags_t rflags, insn *ins, const char **errmsg) { … } static void add_asp(insn *ins, int addrbits) { … }