1 /* assemble.c code generation for the Netwide Assembler
3 * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
4 * Julian Hall. All rights reserved. The software is
5 * redistributable under the license given in the file "LICENSE"
6 * distributed in the NASM archive.
8 * the actual codes (C syntax, i.e. octal):
9 * \0 - terminates the code. (Unless it's a literal of course.)
10 * \1, \2, \3 - that many literal bytes follow in the code stream
11 * \4, \6 - the POP/PUSH (respectively) codes for CS, DS, ES, SS
12 * (POP is never used for CS) depending on operand 0
13 * \5, \7 - the second byte of POP/PUSH codes for FS, GS, depending
15 * \10..\13 - a literal byte follows in the code stream, to be added
16 * to the register value of operand 0..3
17 * \14..\17 - a signed byte immediate operand, from operand 0..3
18 * \20..\23 - a byte immediate operand, from operand 0..3
19 * \24..\27 - an unsigned byte immediate operand, from operand 0..3
20 * \30..\33 - a word immediate operand, from operand 0..3
21 * \34..\37 - select between \3[0-3] and \4[0-3] depending on 16/32 bit
22 * assembly mode or the operand-size override on the operand
23 * \40..\43 - a long immediate operand, from operand 0..3
24 * \44..\47 - select between \3[0-3], \4[0-3] and \5[4-7]
25 * depending on the address size of the instruction.
26 * \50..\53 - a byte relative operand, from operand 0..3
27 * \54..\57 - a qword immediate operand, from operand 0..3
28 * \60..\63 - a word relative operand, from operand 0..3
29 * \64..\67 - select between \6[0-3] and \7[0-3] depending on 16/32 bit
30 * assembly mode or the operand-size override on the operand
31 * \70..\73 - a long relative operand, from operand 0..3
32 * \74..\77 - a word constant, from the _segment_ part of operand 0..3
33 * \1ab - a ModRM, calculated on EA in operand a, with the spare
34 * field the register value of operand b.
35 * \140..\143 - an immediate word or signed byte for operand 0..3
36 * \144..\147 - or 2 (s-field) into opcode byte if operand 0..3
37 * is a signed byte rather than a word. Opcode byte follows.
38 * \150..\153 - an immediate dword or signed byte for operand 0..3
39 * \154..\157 - or 2 (s-field) into opcode byte if operand 0..3
40 * is a signed byte rather than a dword. Opcode byte follows.
41 * \160..\163 - this instruction uses DREX rather than REX, with the
42 * OC0 field set to 0, and the dest field taken from
44 * \164..\167 - this instruction uses DREX rather than REX, with the
45 * OC0 field set to 1, and the dest field taken from
47 * \171 - placement of DREX suffix in the absence of an EA
48 * \172\ab - the register number from operand a in bits 7..4, with
49 * the 4-bit immediate from operand b in bits 3..0.
50 * \173\xab - the register number from operand a in bits 7..4, with
51 * the value b in bits 3..0.
52 * \174\a - the register number from operand a in bits 7..4, and
53 * an arbitrary value in bits 3..0 (assembled as zero.)
54 * \2ab - a ModRM, calculated on EA in operand a, with the spare
55 * field equal to digit b.
56 * \250..\253 - same as \150..\153, except warn if the 64-bit operand
57 * is not equal to the truncated and sign-extended 32-bit
58 * operand; used for 32-bit immediates in 64-bit mode.
59 * \260..\263 - this instruction uses VEX rather than REX, with the
60 * V field taken from operand 0..3.
61 * \270 - this instruction uses VEX rather than REX, with the
62 * V field set to 1111b.
64 * VEX prefixes are followed by the sequence:
65 * \mm\wlp where mm is the M field; and wlp is:
67 * [w0] ww = 0 for W = 0
68 * [w1] ww = 1 for W = 1
69 * [wx] ww = 2 for W don't care (always assembled as 0)
70 * [ww] ww = 3 for W used as REX.W
73 * \310 - indicates fixed 16-bit address size, i.e. optional 0x67.
74 * \311 - indicates fixed 32-bit address size, i.e. optional 0x67.
75 * \312 - (disassembler only) marker on LOOP, LOOPxx instructions.
76 * \313 - indicates fixed 64-bit address size, 0x67 invalid.
77 * \314 - (disassembler only) invalid with REX.B
78 * \315 - (disassembler only) invalid with REX.X
79 * \316 - (disassembler only) invalid with REX.R
80 * \317 - (disassembler only) invalid with REX.W
81 * \320 - indicates fixed 16-bit operand size, i.e. optional 0x66.
82 * \321 - indicates fixed 32-bit operand size, i.e. optional 0x66.
83 * \322 - indicates that this instruction is only valid when the
84 * operand size is the default (instruction to disassembler,
85 * generates no code in the assembler)
86 * \323 - indicates fixed 64-bit operand size, REX on extensions only.
87 * \324 - indicates 64-bit operand size requiring REX prefix.
88 * \330 - a literal byte follows in the code stream, to be added
89 * to the condition code value of the instruction.
90 * \331 - instruction not valid with REP prefix. Hint for
91 * disassembler only; for SSE instructions.
92 * \332 - REP prefix (0xF2 byte) used as opcode extension.
93 * \333 - REP prefix (0xF3 byte) used as opcode extension.
94 * \334 - LOCK prefix used instead of REX.R
95 * \335 - disassemble a rep (0xF3 byte) prefix as repe not rep.
96 * \336 - force a REP(E) prefix (0xF2) even if not specified.
97 * \337 - force a REPNE prefix (0xF3) even if not specified.
98 * \336-\337 are still listed as prefixes in the disassembler.
99 * \340 - reserve <operand 0> bytes of uninitialized storage.
100 * Operand 0 had better be a segmentless constant.
101 * \360 - no SSE prefix (== \364\331)
102 * \361 - 66 SSE prefix (== \366\331)
103 * \362 - F2 SSE prefix (== \364\332)
104 * \363 - F3 SSE prefix (== \364\333)
105 * \364 - operand-size prefix (0x66) not permitted
106 * \365 - address-size prefix (0x67) not permitted
107 * \366 - operand-size prefix (0x66) used as opcode extension
108 * \367 - address-size prefix (0x67) used as opcode extension
109 * \370,\371,\372 - match only if operand 0 meets byte jump criteria.
110 * 370 is used for Jcc, 371 is used for JMP.
111 * \373 - assemble 0x03 if bits==16, 0x05 if bits==32;
112 * used for conditional jump over longer jump
115 #include "compiler.h"
119 #include <inttypes.h>
123 #include "assemble.h"
127 /* Initialized to zero by the C standard */
128 static const uint8_t const_zero_buf[256];
131 int sib_present; /* is a SIB byte necessary? */
132 int bytes; /* # of bytes of offset needed */
133 int size; /* lazy - this is sib+bytes+1 */
134 uint8_t modrm, sib, rex, rip; /* the bytes themselves */
137 static uint32_t cpu; /* cpu level received from nasm.c */
138 static efunc errfunc;
139 static struct ofmt *outfmt;
140 static ListGen *list;
142 static int64_t calcsize(int32_t, int64_t, int, insn *, const uint8_t *);
143 static void gencode(int32_t segment, int64_t offset, int bits,
144 insn * ins, const struct itemplate *temp,
146 static int matches(const struct itemplate *, insn *, int bits);
147 static int32_t regflag(const operand *);
148 static int32_t regval(const operand *);
149 static int rexflags(int, int32_t, int);
150 static int op_rexflags(const operand *, int);
151 static ea *process_ea(operand *, ea *, int, int, int, int32_t);
152 static void add_asp(insn *, int);
154 static int has_prefix(insn * ins, enum prefix_pos pos, enum prefixes prefix)
156 return ins->prefixes[pos] == prefix;
159 static void assert_no_prefix(insn * ins, enum prefix_pos pos)
161 if (ins->prefixes[pos])
162 errfunc(ERR_NONFATAL, "invalid %s prefix",
163 prefix_name(ins->prefixes[pos]));
166 static const char *size_name(int size)
188 static void warn_overflow(int size, int64_t data)
191 int64_t lim = ((int64_t)1 << (size*8))-1;
193 if (data < ~lim || data > lim)
194 errfunc(ERR_WARNING | ERR_WARN_NOV,
195 "%s data exceeds bounds", size_name(size));
199 * This routine wrappers the real output format's output routine,
200 * in order to pass a copy of the data off to the listing file
201 * generator at the same time.
203 static void out(int64_t offset, int32_t segto, const void *data,
204 enum out_type type, uint64_t size,
205 int32_t segment, int32_t wrt)
207 static int32_t lineno = 0; /* static!!! */
208 static char *lnfname = NULL;
211 if (type == OUT_ADDRESS && segment == NO_SEG && wrt == NO_SEG) {
213 * This is a non-relocated address, and we're going to
214 * convert it into RAWDATA format.
219 errfunc(ERR_PANIC, "OUT_ADDRESS with size > 8");
223 WRITEADDR(q, *(int64_t *)data, size);
228 list->output(offset, data, type, size);
231 * this call to src_get determines when we call the
232 * debug-format-specific "linenum" function
233 * it updates lineno and lnfname to the current values
234 * returning 0 if "same as last time", -2 if lnfname
235 * changed, and the amount by which lineno changed,
236 * if it did. thus, these variables must be static
239 if (src_get(&lineno, &lnfname)) {
240 outfmt->current_dfmt->linenum(lnfname, lineno, segto);
243 outfmt->output(segto, data, type, size, segment, wrt);
246 static bool jmp_match(int32_t segment, int64_t offset, int bits,
247 insn * ins, const uint8_t *code)
252 if ((c != 0370 && c != 0371) || (ins->oprs[0].type & STRICT))
256 if (optimizing < 0 && c == 0371)
259 isize = calcsize(segment, offset, bits, ins, code);
260 if (ins->oprs[0].segment != segment)
263 isize = ins->oprs[0].offset - offset - isize; /* isize is delta */
264 return (isize >= -128 && isize <= 127); /* is it byte size? */
267 int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp,
268 insn * instruction, struct ofmt *output, efunc error,
271 const struct itemplate *temp;
276 int64_t start = offset;
277 int64_t wsize = 0; /* size for DB etc. */
279 errfunc = error; /* to pass to other functions */
281 outfmt = output; /* likewise */
282 list = listgen; /* and again */
284 switch (instruction->opcode) {
314 int32_t t = instruction->times;
317 "instruction->times < 0 (%ld) in assemble()", t);
319 while (t--) { /* repeat TIMES times */
320 for (e = instruction->eops; e; e = e->next) {
321 if (e->type == EOT_DB_NUMBER) {
323 if (e->segment != NO_SEG)
324 errfunc(ERR_NONFATAL,
325 "one-byte relocation attempted");
327 uint8_t out_byte = e->offset;
328 out(offset, segment, &out_byte,
329 OUT_RAWDATA, 1, NO_SEG, NO_SEG);
331 } else if (wsize > 8) {
332 errfunc(ERR_NONFATAL,
333 "integer supplied to a DT, DO or DY"
336 out(offset, segment, &e->offset,
337 OUT_ADDRESS, wsize, e->segment, e->wrt);
339 } else if (e->type == EOT_DB_STRING ||
340 e->type == EOT_DB_STRING_FREE) {
343 out(offset, segment, e->stringval,
344 OUT_RAWDATA, e->stringlen, NO_SEG, NO_SEG);
345 align = e->stringlen % wsize;
348 align = wsize - align;
349 out(offset, segment, const_zero_buf,
350 OUT_RAWDATA, align, NO_SEG, NO_SEG);
352 offset += e->stringlen + align;
355 if (t > 0 && t == instruction->times - 1) {
357 * Dummy call to list->output to give the offset to the
360 list->output(offset, NULL, OUT_RAWDATA, 0);
361 list->uplevel(LIST_TIMES);
364 if (instruction->times > 1)
365 list->downlevel(LIST_TIMES);
366 return offset - start;
369 if (instruction->opcode == I_INCBIN) {
370 const char *fname = instruction->eops->stringval;
373 fp = fopen(fname, "rb");
375 error(ERR_NONFATAL, "`incbin': unable to open file `%s'",
377 } else if (fseek(fp, 0L, SEEK_END) < 0) {
378 error(ERR_NONFATAL, "`incbin': unable to seek on file `%s'",
381 static char buf[4096];
382 size_t t = instruction->times;
387 if (instruction->eops->next) {
388 base = instruction->eops->next->offset;
390 if (instruction->eops->next->next &&
391 len > (size_t)instruction->eops->next->next->offset)
392 len = (size_t)instruction->eops->next->next->offset;
395 * Dummy call to list->output to give the offset to the
398 list->output(offset, NULL, OUT_RAWDATA, 0);
399 list->uplevel(LIST_INCBIN);
403 fseek(fp, base, SEEK_SET);
407 fread(buf, 1, (l > (int32_t) sizeof(buf) ? (int32_t) sizeof(buf) : l),
411 * This shouldn't happen unless the file
412 * actually changes while we are reading
416 "`incbin': unexpected EOF while"
417 " reading file `%s'", fname);
418 t = 0; /* Try to exit cleanly */
421 out(offset, segment, buf, OUT_RAWDATA, m,
426 list->downlevel(LIST_INCBIN);
427 if (instruction->times > 1) {
429 * Dummy call to list->output to give the offset to the
432 list->output(offset, NULL, OUT_RAWDATA, 0);
433 list->uplevel(LIST_TIMES);
434 list->downlevel(LIST_TIMES);
437 return instruction->times * len;
439 return 0; /* if we're here, there's an error */
442 /* Check to see if we need an address-size prefix */
443 add_asp(instruction, bits);
447 for (temp = nasm_instructions[instruction->opcode]; temp->opcode != -1; temp++){
448 int m = matches(temp, instruction, bits);
450 (m == 99 && jmp_match(segment, offset, bits,
451 instruction, temp->code))) {
453 int64_t insn_size = calcsize(segment, offset, bits,
454 instruction, temp->code);
455 itimes = instruction->times;
456 if (insn_size < 0) /* shouldn't be, on pass two */
457 error(ERR_PANIC, "errors made it through from pass one");
460 for (j = 0; j < MAXPREFIX; j++) {
462 switch (instruction->prefixes[j]) {
478 "cs segment base generated, but will be ignored in 64-bit mode");
485 "ds segment base generated, but will be ignored in 64-bit mode");
492 "es segment base generated, but will be ignored in 64-bit mode");
505 "ss segment base generated, but will be ignored in 64-bit mode");
512 "segr6 and segr7 cannot be used as prefixes");
517 "16-bit addressing is not supported "
519 } else if (bits != 16)
529 "64-bit addressing is only supported "
553 error(ERR_PANIC, "invalid instruction prefix");
556 out(offset, segment, &c, OUT_RAWDATA, 1,
561 insn_end = offset + insn_size;
562 gencode(segment, offset, bits, instruction,
565 if (itimes > 0 && itimes == instruction->times - 1) {
567 * Dummy call to list->output to give the offset to the
570 list->output(offset, NULL, OUT_RAWDATA, 0);
571 list->uplevel(LIST_TIMES);
574 if (instruction->times > 1)
575 list->downlevel(LIST_TIMES);
576 return offset - start;
577 } else if (m > 0 && m > size_prob) {
582 if (temp->opcode == -1) { /* didn't match any instruction */
585 error(ERR_NONFATAL, "operation size not specified");
588 error(ERR_NONFATAL, "mismatch in operand sizes");
591 error(ERR_NONFATAL, "no instruction for this cpu level");
594 error(ERR_NONFATAL, "instruction not supported in 64-bit mode");
598 "invalid combination of opcode and operands");
605 int64_t insn_size(int32_t segment, int64_t offset, int bits, uint32_t cp,
606 insn * instruction, efunc error)
608 const struct itemplate *temp;
610 errfunc = error; /* to pass to other functions */
613 if (instruction->opcode == -1)
616 if (instruction->opcode == I_DB || instruction->opcode == I_DW ||
617 instruction->opcode == I_DD || instruction->opcode == I_DQ ||
618 instruction->opcode == I_DT || instruction->opcode == I_DO ||
619 instruction->opcode == I_DY) {
621 int32_t isize, osize, wsize = 0; /* placate gcc */
624 switch (instruction->opcode) {
650 for (e = instruction->eops; e; e = e->next) {
654 if (e->type == EOT_DB_NUMBER)
656 else if (e->type == EOT_DB_STRING ||
657 e->type == EOT_DB_STRING_FREE)
658 osize = e->stringlen;
660 align = (-osize) % wsize;
663 isize += osize + align;
665 return isize * instruction->times;
668 if (instruction->opcode == I_INCBIN) {
669 const char *fname = instruction->eops->stringval;
673 fp = fopen(fname, "rb");
675 error(ERR_NONFATAL, "`incbin': unable to open file `%s'",
677 else if (fseek(fp, 0L, SEEK_END) < 0)
678 error(ERR_NONFATAL, "`incbin': unable to seek on file `%s'",
683 if (instruction->eops->next) {
684 len -= instruction->eops->next->offset;
685 if (instruction->eops->next->next &&
686 len > (size_t)instruction->eops->next->next->offset) {
687 len = (size_t)instruction->eops->next->next->offset;
690 return instruction->times * len;
692 return 0; /* if we're here, there's an error */
695 /* Check to see if we need an address-size prefix */
696 add_asp(instruction, bits);
698 for (temp = nasm_instructions[instruction->opcode]; temp->opcode != -1; temp++) {
699 int m = matches(temp, instruction, bits);
701 (m == 99 && jmp_match(segment, offset, bits,
702 instruction, temp->code))) {
703 /* we've matched an instruction. */
705 const uint8_t *codes = temp->code;
708 isize = calcsize(segment, offset, bits, instruction, codes);
711 for (j = 0; j < MAXPREFIX; j++) {
712 switch (instruction->prefixes[j]) {
738 return isize * instruction->times;
741 return -1; /* didn't match any instruction */
744 static bool possible_sbyte(operand *o)
746 return !(o->opflags & OPFLAG_FORWARD) &&
747 optimizing >= 0 && !(o->type & STRICT) &&
748 o->wrt == NO_SEG && o->segment == NO_SEG;
751 /* check that opn[op] is a signed byte of size 16 or 32 */
752 static bool is_sbyte16(operand *o)
756 if (!possible_sbyte(o))
760 return v >= -128 && v <= 127;
763 static bool is_sbyte32(operand *o)
767 if (!possible_sbyte(o))
771 return v >= -128 && v <= 127;
774 /* check that opn[op] is a signed byte of size 32; warn if this is not
775 the original value when extended to 64 bits */
776 static bool is_sbyte64(operand *o)
781 /* dead in the water on forward reference or External */
782 if (!possible_sbyte(o))
788 warn_overflow(32, v64);
790 return v32 >= -128 && v32 <= 127;
792 static int64_t calcsize(int32_t segment, int64_t offset, int bits,
793 insn * ins, const uint8_t *codes)
800 ins->rex = 0; /* Ensure REX is reset */
802 if (ins->prefixes[PPS_OSIZE] == P_O64)
805 (void)segment; /* Don't warn that this parameter is unused */
806 (void)offset; /* Don't warn that this parameter is unused */
810 opx = &ins->oprs[c & 3];
815 codes += c, length += c;
828 op_rexflags(opx, REX_B|REX_H|REX_P|REX_W);
859 if (opx->type & (BITS16 | BITS32 | BITS64))
860 length += (opx->type & BITS16) ? 2 : 4;
862 length += (bits == 16) ? 2 : 4;
874 length += ins->addr_size >> 3;
886 length += 8; /* MOV reg64/imm */
898 if (opx->type & (BITS16 | BITS32 | BITS64))
899 length += (opx->type & BITS16) ? 2 : 4;
901 length += (bits == 16) ? 2 : 4;
919 length += is_sbyte16(opx) ? 1 : 2;
932 length += is_sbyte32(opx) ? 1 : 4;
947 ins->drexdst = regval(opx);
954 ins->rex |= REX_D|REX_OC;
955 ins->drexdst = regval(opx);
969 length += is_sbyte64(opx) ? 1 : 4;
976 ins->drexdst = regval(opx);
977 ins->vex_m = *codes++;
978 ins->vex_wlp = *codes++;
983 ins->vex_m = *codes++;
984 ins->vex_wlp = *codes++;
994 length += (bits != 16) && !has_prefix(ins, PPS_ASIZE, P_A16);
997 length += (bits != 32) && !has_prefix(ins, PPS_ASIZE, P_A32);
1002 if (bits != 64 || has_prefix(ins, PPS_ASIZE, P_A16) ||
1003 has_prefix(ins, PPS_ASIZE, P_A32))
1012 length += (bits != 16);
1015 length += (bits == 16);
1040 if (!ins->prefixes[PPS_LREP])
1041 ins->prefixes[PPS_LREP] = P_REP;
1044 if (!ins->prefixes[PPS_LREP])
1045 ins->prefixes[PPS_LREP] = P_REPNE;
1048 if (ins->oprs[0].segment != NO_SEG)
1049 errfunc(ERR_NONFATAL, "attempt to reserve non-constant"
1050 " quantity of BSS space");
1052 length += ins->oprs[0].offset;
1075 default: /* can't do it by 'case' statements */
1076 if (c >= 0100 && c <= 0277) { /* it's an EA */
1080 ea_data.rex = 0; /* Ensure ea.REX is initially 0 */
1083 /* pick rfield from operand b */
1084 rflags = regflag(&ins->oprs[c & 7]);
1085 rfield = nasm_regvals[ins->oprs[c & 7].basereg];
1092 (&ins->oprs[(c >> 3) & 7], &ea_data, bits,
1093 ins->addr_size, rfield, rflags)) {
1094 errfunc(ERR_NONFATAL, "invalid effective address");
1097 ins->rex |= ea_data.rex;
1098 length += ea_data.size;
1101 errfunc(ERR_PANIC, "internal instruction table corrupt"
1102 ": instruction code 0x%02X given", c);
1107 ins->rex &= rex_mask;
1109 if (ins->rex & REX_V) {
1110 int bad32 = REX_R|REX_W|REX_X|REX_B;
1112 if (ins->rex & REX_H) {
1113 errfunc(ERR_NONFATAL, "cannot use high register in vex instruction");
1116 switch (ins->vex_wlp & 030) {
1130 if (bits != 64 && ((ins->rex & bad32) || ins->drexdst > 7)) {
1131 errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode");
1134 if (ins->vex_m != 1 || (ins->rex & (REX_W|REX_R|REX_B)))
1138 } else if (ins->rex & REX_D) {
1139 if (ins->rex & REX_H) {
1140 errfunc(ERR_NONFATAL, "cannot use high register in drex instruction");
1143 if (bits != 64 && ((ins->rex & (REX_R|REX_W|REX_X|REX_B)) ||
1144 ins->drexdst > 7)) {
1145 errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode");
1149 } else if (ins->rex & REX_REAL) {
1150 if (ins->rex & REX_H) {
1151 errfunc(ERR_NONFATAL, "cannot use high register in rex instruction");
1153 } else if (bits == 64) {
1155 } else if ((ins->rex & REX_L) &&
1156 !(ins->rex & (REX_P|REX_W|REX_X|REX_B)) &&
1159 assert_no_prefix(ins, PPS_LREP);
1162 errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode");
1170 #define EMIT_REX() \
1171 if (!(ins->rex & (REX_D|REX_V)) && (ins->rex & REX_REAL) && (bits == 64)) { \
1172 ins->rex = (ins->rex & REX_REAL)|REX_P; \
1173 out(offset, segment, &ins->rex, OUT_RAWDATA, 1, NO_SEG, NO_SEG); \
1178 static void gencode(int32_t segment, int64_t offset, int bits,
1179 insn * ins, const struct itemplate *temp,
1182 static char condval[] = { /* conditional opcodes */
1183 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
1184 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
1185 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
1191 struct operand *opx;
1192 const uint8_t *codes = temp->code;
1196 opx = &ins->oprs[c & 3];
1202 out(offset, segment, codes, OUT_RAWDATA, c, NO_SEG, NO_SEG);
1209 switch (ins->oprs[0].basereg) {
1211 bytes[0] = 0x0E + (c == 0x04 ? 1 : 0);
1214 bytes[0] = 0x1E + (c == 0x04 ? 1 : 0);
1217 bytes[0] = 0x06 + (c == 0x04 ? 1 : 0);
1220 bytes[0] = 0x16 + (c == 0x04 ? 1 : 0);
1224 "bizarre 8086 segment register received");
1226 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1232 switch (ins->oprs[0].basereg) {
1234 bytes[0] = 0xA0 + (c == 0x05 ? 1 : 0);
1237 bytes[0] = 0xA8 + (c == 0x05 ? 1 : 0);
1241 "bizarre 386 segment register received");
1243 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1252 bytes[0] = *codes++ + ((regval(opx)) & 7);
1253 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1261 /* The test for BITS8 and SBYTE here is intended to avoid
1262 warning on optimizer actions due to SBYTE, while still
1263 warn on explicit BYTE directives. Also warn, obviously,
1264 if the optimizer isn't enabled. */
1265 if (((opx->type & BITS8) ||
1266 !(opx->type & temp->opd[c & 3] & BYTENESS)) &&
1267 (opx->offset < -128 || opx->offset > 127)) {
1268 errfunc(ERR_WARNING | ERR_WARN_NOV,
1269 "signed byte value exceeds bounds");
1271 if (opx->segment != NO_SEG) {
1273 out(offset, segment, &data, OUT_ADDRESS, 1,
1274 opx->segment, opx->wrt);
1276 bytes[0] = opx->offset;
1277 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1287 if (opx->offset < -256 || opx->offset > 255) {
1288 errfunc(ERR_WARNING | ERR_WARN_NOV,
1289 "byte value exceeds bounds");
1291 if (opx->segment != NO_SEG) {
1293 out(offset, segment, &data, OUT_ADDRESS, 1,
1294 opx->segment, opx->wrt);
1296 bytes[0] = opx->offset;
1297 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1307 if (opx->offset < 0 || opx->offset > 255)
1308 errfunc(ERR_WARNING | ERR_WARN_NOV,
1309 "unsigned byte value exceeds bounds");
1310 if (opx->segment != NO_SEG) {
1312 out(offset, segment, &data, OUT_ADDRESS, 1,
1313 opx->segment, opx->wrt);
1315 bytes[0] = opx->offset;
1316 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1327 if (opx->segment == NO_SEG && opx->wrt == NO_SEG)
1328 warn_overflow(2, data);
1329 out(offset, segment, &data, OUT_ADDRESS, 2,
1330 opx->segment, opx->wrt);
1338 if (opx->type & (BITS16 | BITS32))
1339 size = (opx->type & BITS16) ? 2 : 4;
1341 size = (bits == 16) ? 2 : 4;
1343 if (opx->segment == NO_SEG && opx->wrt == NO_SEG)
1344 warn_overflow(size, data);
1345 out(offset, segment, &data, OUT_ADDRESS, size,
1346 opx->segment, opx->wrt);
1355 if (opx->segment == NO_SEG && opx->wrt == NO_SEG)
1356 warn_overflow(4, data);
1357 out(offset, segment, &data, OUT_ADDRESS, 4,
1358 opx->segment, opx->wrt);
1367 size = ins->addr_size >> 3;
1368 if (opx->segment == NO_SEG &&
1370 warn_overflow(size, data);
1371 out(offset, segment, &data, OUT_ADDRESS, size,
1372 opx->segment, opx->wrt);
1380 if (opx->segment != segment)
1381 errfunc(ERR_NONFATAL,
1382 "short relative jump outside segment");
1383 data = opx->offset - insn_end;
1384 if (data > 127 || data < -128)
1385 errfunc(ERR_NONFATAL, "short jump is out of range");
1387 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1395 data = (int64_t)opx->offset;
1396 out(offset, segment, &data, OUT_ADDRESS, 8,
1397 opx->segment, opx->wrt);
1405 if (opx->segment != segment) {
1407 out(offset, segment, &data,
1408 OUT_REL2ADR, insn_end - offset,
1409 opx->segment, opx->wrt);
1411 data = opx->offset - insn_end;
1412 out(offset, segment, &data,
1413 OUT_ADDRESS, 2, NO_SEG, NO_SEG);
1422 if (opx->type & (BITS16 | BITS32 | BITS64))
1423 size = (opx->type & BITS16) ? 2 : 4;
1425 size = (bits == 16) ? 2 : 4;
1426 if (opx->segment != segment) {
1428 out(offset, segment, &data,
1429 size == 2 ? OUT_REL2ADR : OUT_REL4ADR,
1430 insn_end - offset, opx->segment, opx->wrt);
1432 data = opx->offset - insn_end;
1433 out(offset, segment, &data,
1434 OUT_ADDRESS, size, NO_SEG, NO_SEG);
1443 if (opx->segment != segment) {
1445 out(offset, segment, &data,
1446 OUT_REL4ADR, insn_end - offset,
1447 opx->segment, opx->wrt);
1449 data = opx->offset - insn_end;
1450 out(offset, segment, &data,
1451 OUT_ADDRESS, 4, NO_SEG, NO_SEG);
1460 if (opx->segment == NO_SEG)
1461 errfunc(ERR_NONFATAL, "value referenced by FAR is not"
1464 out(offset, segment, &data, OUT_ADDRESS, 2,
1465 outfmt->segbase(1 + opx->segment),
1475 if (is_sbyte16(opx)) {
1477 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1481 if (opx->segment == NO_SEG &&
1483 warn_overflow(2, data);
1484 out(offset, segment, &data, OUT_ADDRESS, 2,
1485 opx->segment, opx->wrt);
1495 bytes[0] = *codes++;
1496 if (is_sbyte16(opx))
1497 bytes[0] |= 2; /* s-bit */
1498 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1507 if (is_sbyte32(opx)) {
1509 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1513 out(offset, segment, &data, OUT_ADDRESS, 4,
1514 opx->segment, opx->wrt);
1524 bytes[0] = *codes++;
1525 if (is_sbyte32(opx))
1526 bytes[0] |= 2; /* s-bit */
1527 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1543 (ins->drexdst << 4) |
1544 (ins->rex & REX_OC ? 0x08 : 0) |
1545 (ins->rex & (REX_R|REX_X|REX_B));
1547 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1553 opx = &ins->oprs[c >> 3];
1554 bytes[0] = nasm_regvals[opx->basereg] << 4;
1555 opx = &ins->oprs[c & 7];
1556 if (opx->segment != NO_SEG || opx->wrt != NO_SEG) {
1557 errfunc(ERR_NONFATAL,
1558 "non-absolute expression not permitted as argument %d",
1561 if (opx->offset & ~15) {
1562 errfunc(ERR_WARNING | ERR_WARN_NOV,
1563 "four-bit argument exceeds bounds");
1565 bytes[0] |= opx->offset & 15;
1567 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1573 opx = &ins->oprs[c >> 4];
1574 bytes[0] = nasm_regvals[opx->basereg] << 4;
1576 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1582 opx = &ins->oprs[c];
1583 bytes[0] = nasm_regvals[opx->basereg] << 4;
1584 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1593 /* is_sbyte32() is right here, we have already warned */
1594 if (is_sbyte32(opx)) {
1596 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1600 out(offset, segment, &data, OUT_ADDRESS, 4,
1601 opx->segment, opx->wrt);
1612 if (ins->vex_m != 1 || (ins->rex & (REX_W|REX_X|REX_B))) {
1614 bytes[1] = ins->vex_m | ((~ins->rex & 7) << 5);
1615 bytes[2] = ((ins->rex & REX_W) << (7-3)) |
1616 ((~ins->drexdst & 15)<< 3) | (ins->vex_wlp & 07);
1617 out(offset, segment, &bytes, OUT_RAWDATA, 3, NO_SEG, NO_SEG);
1621 bytes[1] = ((~ins->rex & REX_R) << (7-2)) |
1622 ((~ins->drexdst & 15) << 3) | (ins->vex_wlp & 07);
1623 out(offset, segment, &bytes, OUT_RAWDATA, 2, NO_SEG, NO_SEG);
1635 if (bits == 32 && !has_prefix(ins, PPS_ASIZE, P_A16)) {
1637 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1644 if (bits != 32 && !has_prefix(ins, PPS_ASIZE, P_A32)) {
1646 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1668 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1677 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1692 *bytes = *codes++ ^ condval[ins->condition];
1693 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1702 *bytes = c - 0332 + 0xF2;
1703 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1708 if (ins->rex & REX_R) {
1710 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1713 ins->rex &= ~(REX_L|REX_R);
1724 if (ins->oprs[0].segment != NO_SEG)
1725 errfunc(ERR_PANIC, "non-constant BSS size in pass two");
1727 int64_t size = ins->oprs[0].offset;
1729 out(offset, segment, NULL,
1730 OUT_RESERVE, size, NO_SEG, NO_SEG);
1740 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1746 bytes[0] = c - 0362 + 0xf2;
1747 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1757 *bytes = c - 0366 + 0x66;
1758 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1768 *bytes = bits == 16 ? 3 : 5;
1769 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1773 default: /* can't do it by 'case' statements */
1774 if (c >= 0100 && c <= 0277) { /* it's an EA */
1782 /* pick rfield from operand b */
1783 rflags = regflag(&ins->oprs[c & 7]);
1784 rfield = nasm_regvals[ins->oprs[c & 7].basereg];
1786 /* rfield is constant */
1792 (&ins->oprs[(c >> 3) & 7], &ea_data, bits,
1793 ins->addr_size, rfield, rflags)) {
1794 errfunc(ERR_NONFATAL, "invalid effective address");
1799 *p++ = ea_data.modrm;
1800 if (ea_data.sib_present)
1803 /* DREX suffixes come between the SIB and the displacement */
1804 if (ins->rex & REX_D) {
1806 (ins->drexdst << 4) |
1807 (ins->rex & REX_OC ? 0x08 : 0) |
1808 (ins->rex & (REX_R|REX_X|REX_B));
1813 out(offset, segment, bytes, OUT_RAWDATA, s, NO_SEG, NO_SEG);
1816 * Make sure the address gets the right offset in case
1817 * the line breaks in the .lst file (BR 1197827)
1822 switch (ea_data.bytes) {
1826 if (ins->oprs[(c >> 3) & 7].segment != NO_SEG) {
1827 data = ins->oprs[(c >> 3) & 7].offset;
1828 out(offset, segment, &data, OUT_ADDRESS, 1,
1829 ins->oprs[(c >> 3) & 7].segment,
1830 ins->oprs[(c >> 3) & 7].wrt);
1832 *bytes = ins->oprs[(c >> 3) & 7].offset;
1833 out(offset, segment, bytes, OUT_RAWDATA, 1,
1841 data = ins->oprs[(c >> 3) & 7].offset;
1842 warn_overflow(ea_data.bytes, data);
1843 out(offset, segment, &data,
1844 ea_data.rip ? OUT_REL4ADR : OUT_ADDRESS,
1846 ins->oprs[(c >> 3) & 7].segment,
1847 ins->oprs[(c >> 3) & 7].wrt);
1853 errfunc(ERR_PANIC, "internal instruction table corrupt"
1854 ": instruction code 0x%02X given", c);
1860 static int32_t regflag(const operand * o)
1862 if (o->basereg < EXPR_REG_START || o->basereg >= REG_ENUM_LIMIT) {
1863 errfunc(ERR_PANIC, "invalid operand passed to regflag()");
1865 return nasm_reg_flags[o->basereg];
1868 static int32_t regval(const operand * o)
1870 if (o->basereg < EXPR_REG_START || o->basereg >= REG_ENUM_LIMIT) {
1871 errfunc(ERR_PANIC, "invalid operand passed to regval()");
1873 return nasm_regvals[o->basereg];
1876 static int op_rexflags(const operand * o, int mask)
1881 if (o->basereg < EXPR_REG_START || o->basereg >= REG_ENUM_LIMIT) {
1882 errfunc(ERR_PANIC, "invalid operand passed to op_rexflags()");
1885 flags = nasm_reg_flags[o->basereg];
1886 val = nasm_regvals[o->basereg];
1888 return rexflags(val, flags, mask);
1891 static int rexflags(int val, int32_t flags, int mask)
1896 rex |= REX_B|REX_X|REX_R;
1899 if (!(REG_HIGH & ~flags)) /* AH, CH, DH, BH */
1901 else if (!(REG8 & ~flags) && val >= 4) /* SPL, BPL, SIL, DIL */
1907 static int matches(const struct itemplate *itemp, insn * instruction, int bits)
1909 int i, size[MAX_OPERANDS], asize, oprs, ret;
1916 if (itemp->opcode != instruction->opcode)
1920 * Count the operands
1922 if (itemp->operands != instruction->operands)
1926 * Check that no spurious colons or TOs are present
1928 for (i = 0; i < itemp->operands; i++)
1929 if (instruction->oprs[i].type & ~itemp->opd[i] & (COLON | TO))
1933 * Process size flags
1935 if (itemp->flags & IF_ARMASK) {
1936 memset(size, 0, sizeof size);
1938 i = ((itemp->flags & IF_ARMASK) >> IF_ARSHFT) - 1;
1940 switch (itemp->flags & IF_SMASK) {
1977 switch (itemp->flags & IF_SMASK) {
2012 for (i = 0; i < MAX_OPERANDS; i++)
2017 * Check that the operand flags all match up
2019 for (i = 0; i < itemp->operands; i++) {
2020 int32_t type = instruction->oprs[i].type;
2021 if (!(type & SIZE_MASK))
2024 if (itemp->opd[i] & SAME_AS) {
2025 int j = itemp->opd[i] & ~SAME_AS;
2026 if (type != instruction->oprs[j].type ||
2027 instruction->oprs[i].basereg != instruction->oprs[j].basereg)
2029 } else if (itemp->opd[i] & ~type ||
2030 ((itemp->opd[i] & SIZE_MASK) &&
2031 ((itemp->opd[i] ^ type) & SIZE_MASK))) {
2032 if ((itemp->opd[i] & ~type & ~SIZE_MASK) ||
2041 * Check operand sizes
2043 if (itemp->flags & (IF_SM | IF_SM2)) {
2044 oprs = (itemp->flags & IF_SM2 ? 2 : itemp->operands);
2046 for (i = 0; i < oprs; i++) {
2047 if ((asize = itemp->opd[i] & SIZE_MASK) != 0) {
2049 for (j = 0; j < oprs; j++)
2055 oprs = itemp->operands;
2058 for (i = 0; i < itemp->operands; i++) {
2059 if (!(itemp->opd[i] & SIZE_MASK) &&
2060 (instruction->oprs[i].type & SIZE_MASK & ~size[i]))
2065 * Check template is okay at the set cpu level
2067 if (((itemp->flags & IF_PLEVEL) > cpu))
2071 * Check if instruction is available in long mode
2073 if ((itemp->flags & IF_NOLONG) && (bits == 64))
2077 * Check if special handling needed for Jumps
2079 if ((uint8_t)(itemp->code[0]) >= 0370)
2085 static ea *process_ea(operand * input, ea * output, int bits,
2086 int addrbits, int rfield, int32_t rflags)
2088 bool forw_ref = !!(input->opflags & OPFLAG_FORWARD);
2090 output->rip = false;
2092 /* REX flags for the rfield operand */
2093 output->rex |= rexflags(rfield, rflags, REX_R|REX_P|REX_W|REX_H);
2095 if (!(REGISTER & ~input->type)) { /* register direct */
2099 if (input->basereg < EXPR_REG_START /* Verify as Register */
2100 || input->basereg >= REG_ENUM_LIMIT)
2103 i = nasm_regvals[input->basereg];
2106 return NULL; /* Invalid EA register */
2108 output->rex |= op_rexflags(input, REX_B|REX_P|REX_W|REX_H);
2110 output->sib_present = false; /* no SIB necessary */
2111 output->bytes = 0; /* no offset necessary either */
2112 output->modrm = 0xC0 | ((rfield & 7) << 3) | (i & 7);
2113 } else { /* it's a memory reference */
2114 if (input->basereg == -1
2115 && (input->indexreg == -1 || input->scale == 0)) {
2116 /* it's a pure offset */
2117 if (bits == 64 && (~input->type & IP_REL)) {
2118 int scale, index, base;
2119 output->sib_present = true;
2123 output->sib = (scale << 6) | (index << 3) | base;
2125 output->modrm = 4 | ((rfield & 7) << 3);
2126 output->rip = false;
2128 output->sib_present = false;
2129 output->bytes = (addrbits != 16 ? 4 : 2);
2130 output->modrm = (addrbits != 16 ? 5 : 6) | ((rfield & 7) << 3);
2131 output->rip = bits == 64;
2133 } else { /* it's an indirection */
2134 int i = input->indexreg, b = input->basereg, s = input->scale;
2135 int32_t o = input->offset, seg = input->segment;
2136 int hb = input->hintbase, ht = input->hinttype;
2139 int32_t ix, bx; /* register flags */
2142 i = -1; /* make this easy, at least */
2144 if (i >= EXPR_REG_START && i < REG_ENUM_LIMIT) {
2145 it = nasm_regvals[i];
2146 ix = nasm_reg_flags[i];
2152 if (b >= EXPR_REG_START && b < REG_ENUM_LIMIT) {
2153 bt = nasm_regvals[b];
2154 bx = nasm_reg_flags[b];
2160 /* check for a 32/64-bit memory reference... */
2161 if ((ix|bx) & (BITS32|BITS64)) {
2162 /* it must be a 32/64-bit memory reference. Firstly we have
2163 * to check that all registers involved are type E/Rxx. */
2164 int32_t sok = BITS32|BITS64;
2167 if (!(REG64 & ~ix) || !(REG32 & ~ix))
2175 return NULL; /* Invalid register */
2176 if (~sok & bx & SIZE_MASK)
2177 return NULL; /* Invalid size */
2181 /* While we're here, ensure the user didn't specify
2183 if (input->disp_size == 16 || input->disp_size == 64)
2186 if (addrbits == 16 ||
2187 (addrbits == 32 && !(sok & BITS32)) ||
2188 (addrbits == 64 && !(sok & BITS64)))
2191 /* now reorganize base/index */
2192 if (s == 1 && bt != it && bt != -1 && it != -1 &&
2193 ((hb == b && ht == EAH_NOTBASE)
2194 || (hb == i && ht == EAH_MAKEBASE))) {
2195 /* swap if hints say so */
2196 t = bt, bt = it, it = t;
2197 t = bx, bx = ix, ix = t;
2199 if (bt == it) /* convert EAX+2*EAX to 3*EAX */
2200 bt = -1, bx = 0, s++;
2201 if (bt == -1 && s == 1 && !(hb == it && ht == EAH_NOTBASE)) {
2202 /* make single reg base, unless hint */
2203 bt = it, bx = ix, it = -1, ix = 0;
2205 if (((s == 2 && it != REG_NUM_ESP
2206 && !(input->eaflags & EAF_TIMESTWO)) || s == 3
2207 || s == 5 || s == 9) && bt == -1)
2208 bt = it, bx = ix, s--; /* convert 3*EAX to EAX+2*EAX */
2209 if (it == -1 && (bt & 7) != REG_NUM_ESP
2210 && (input->eaflags & EAF_TIMESTWO))
2211 it = bt, ix = bx, bt = -1, bx = 0, s = 1;
2212 /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */
2213 if (s == 1 && it == REG_NUM_ESP) {
2214 /* swap ESP into base if scale is 1 */
2215 t = it, it = bt, bt = t;
2216 t = ix, ix = bx, bx = t;
2218 if (it == REG_NUM_ESP
2219 || (s != 1 && s != 2 && s != 4 && s != 8 && it != -1))
2220 return NULL; /* wrong, for various reasons */
2222 output->rex |= rexflags(it, ix, REX_X);
2223 output->rex |= rexflags(bt, bx, REX_B);
2225 if (it == -1 && (bt & 7) != REG_NUM_ESP) {
2234 if (rm != REG_NUM_EBP && o == 0 &&
2235 seg == NO_SEG && !forw_ref &&
2237 (EAF_BYTEOFFS | EAF_WORDOFFS)))
2239 else if (input->eaflags & EAF_BYTEOFFS ||
2240 (o >= -128 && o <= 127 && seg == NO_SEG
2242 && !(input->eaflags & EAF_WORDOFFS)))
2248 output->sib_present = false;
2249 output->bytes = (bt == -1 || mod == 2 ? 4 : mod);
2250 output->modrm = (mod << 6) | ((rfield & 7) << 3) | rm;
2253 int mod, scale, index, base;
2273 default: /* then what the smeg is it? */
2274 return NULL; /* panic */
2282 if (base != REG_NUM_EBP && o == 0 &&
2283 seg == NO_SEG && !forw_ref &&
2285 (EAF_BYTEOFFS | EAF_WORDOFFS)))
2287 else if (input->eaflags & EAF_BYTEOFFS ||
2288 (o >= -128 && o <= 127 && seg == NO_SEG
2290 && !(input->eaflags & EAF_WORDOFFS)))
2296 output->sib_present = true;
2297 output->bytes = (bt == -1 || mod == 2 ? 4 : mod);
2298 output->modrm = (mod << 6) | ((rfield & 7) << 3) | 4;
2299 output->sib = (scale << 6) | (index << 3) | base;
2301 } else { /* it's 16-bit */
2304 /* check for 64-bit long mode */
2308 /* check all registers are BX, BP, SI or DI */
2309 if ((b != -1 && b != R_BP && b != R_BX && b != R_SI
2310 && b != R_DI) || (i != -1 && i != R_BP && i != R_BX
2311 && i != R_SI && i != R_DI))
2314 /* ensure the user didn't specify DWORD/QWORD */
2315 if (input->disp_size == 32 || input->disp_size == 64)
2318 if (s != 1 && i != -1)
2319 return NULL; /* no can do, in 16-bit EA */
2320 if (b == -1 && i != -1) {
2325 if ((b == R_SI || b == R_DI) && i != -1) {
2330 /* have BX/BP as base, SI/DI index */
2332 return NULL; /* shouldn't ever happen, in theory */
2333 if (i != -1 && b != -1 &&
2334 (i == R_BP || i == R_BX || b == R_SI || b == R_DI))
2335 return NULL; /* invalid combinations */
2336 if (b == -1) /* pure offset: handled above */
2337 return NULL; /* so if it gets to here, panic! */
2341 switch (i * 256 + b) {
2342 case R_SI * 256 + R_BX:
2345 case R_DI * 256 + R_BX:
2348 case R_SI * 256 + R_BP:
2351 case R_DI * 256 + R_BP:
2369 if (rm == -1) /* can't happen, in theory */
2370 return NULL; /* so panic if it does */
2372 if (o == 0 && seg == NO_SEG && !forw_ref && rm != 6 &&
2373 !(input->eaflags & (EAF_BYTEOFFS | EAF_WORDOFFS)))
2375 else if (input->eaflags & EAF_BYTEOFFS ||
2376 (o >= -128 && o <= 127 && seg == NO_SEG
2378 && !(input->eaflags & EAF_WORDOFFS)))
2383 output->sib_present = false; /* no SIB - it's 16-bit */
2384 output->bytes = mod; /* bytes of offset needed */
2385 output->modrm = (mod << 6) | ((rfield & 7) << 3) | rm;
2390 output->size = 1 + output->sib_present + output->bytes;
2394 static void add_asp(insn *ins, int addrbits)
2399 valid = (addrbits == 64) ? 64|32 : 32|16;
2401 switch (ins->prefixes[PPS_ASIZE]) {
2412 valid &= (addrbits == 32) ? 16 : 32;
2418 for (j = 0; j < ins->operands; j++) {
2419 if (!(MEMORY & ~ins->oprs[j].type)) {
2422 /* Verify as Register */
2423 if (ins->oprs[j].indexreg < EXPR_REG_START
2424 || ins->oprs[j].indexreg >= REG_ENUM_LIMIT)
2427 i = nasm_reg_flags[ins->oprs[j].indexreg];
2429 /* Verify as Register */
2430 if (ins->oprs[j].basereg < EXPR_REG_START
2431 || ins->oprs[j].basereg >= REG_ENUM_LIMIT)
2434 b = nasm_reg_flags[ins->oprs[j].basereg];
2436 if (ins->oprs[j].scale == 0)
2440 int ds = ins->oprs[j].disp_size;
2441 if ((addrbits != 64 && ds > 8) ||
2442 (addrbits == 64 && ds == 16))
2462 if (valid & addrbits) {
2463 ins->addr_size = addrbits;
2464 } else if (valid & ((addrbits == 32) ? 16 : 32)) {
2465 /* Add an address size prefix */
2466 enum prefixes pref = (addrbits == 32) ? P_A16 : P_A32;
2467 ins->prefixes[PPS_ASIZE] = pref;
2468 ins->addr_size = (addrbits == 32) ? 16 : 32;
2471 errfunc(ERR_NONFATAL, "impossible combination of address sizes");
2472 ins->addr_size = addrbits; /* Error recovery */
2475 defdisp = ins->addr_size == 16 ? 16 : 32;
2477 for (j = 0; j < ins->operands; j++) {
2478 if (!(MEM_OFFS & ~ins->oprs[j].type) &&
2479 (ins->oprs[j].disp_size ? ins->oprs[j].disp_size : defdisp)
2480 != ins->addr_size) {
2481 /* mem_offs sizes must match the address size; if not,
2482 strip the MEM_OFFS bit and match only EA instructions */
2483 ins->oprs[j].type &= ~(MEM_OFFS & ~MEMORY);