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 * \340 - reserve <operand 0> bytes of uninitialized storage.
97 * Operand 0 had better be a segmentless constant.
98 * \360 - no SSE prefix (== \364\331)
99 * \361 - 66 SSE prefix (== \366\331)
100 * \362 - F2 SSE prefix (== \364\332)
101 * \363 - F3 SSE prefix (== \364\333)
102 * \364 - operand-size prefix (0x66) not permitted
103 * \365 - address-size prefix (0x67) not permitted
104 * \366 - operand-size prefix (0x66) used as opcode extension
105 * \367 - address-size prefix (0x67) used as opcode extension
106 * \370,\371,\372 - match only if operand 0 meets byte jump criteria.
107 * 370 is used for Jcc, 371 is used for JMP.
108 * \373 - assemble 0x03 if bits==16, 0x05 if bits==32;
109 * used for conditional jump over longer jump
112 #include "compiler.h"
116 #include <inttypes.h>
120 #include "assemble.h"
124 /* Initialized to zero by the C standard */
125 static const uint8_t const_zero_buf[256];
128 int sib_present; /* is a SIB byte necessary? */
129 int bytes; /* # of bytes of offset needed */
130 int size; /* lazy - this is sib+bytes+1 */
131 uint8_t modrm, sib, rex, rip; /* the bytes themselves */
134 static uint32_t cpu; /* cpu level received from nasm.c */
135 static efunc errfunc;
136 static struct ofmt *outfmt;
137 static ListGen *list;
139 static int64_t calcsize(int32_t, int64_t, int, insn *, const uint8_t *);
140 static void gencode(int32_t, int64_t, int, insn *, const uint8_t *, int64_t);
141 static int matches(const struct itemplate *, insn *, int bits);
142 static int32_t regflag(const operand *);
143 static int32_t regval(const operand *);
144 static int rexflags(int, int32_t, int);
145 static int op_rexflags(const operand *, int);
146 static ea *process_ea(operand *, ea *, int, int, int, int32_t, int);
147 static void add_asp(insn *, int);
149 static int has_prefix(insn * ins, enum prefix_pos pos, enum prefixes prefix)
151 return ins->prefixes[pos] == prefix;
154 static void assert_no_prefix(insn * ins, enum prefix_pos pos)
156 if (ins->prefixes[pos])
157 errfunc(ERR_NONFATAL, "invalid %s prefix",
158 prefix_name(ins->prefixes[pos]));
161 static const char *size_name(int size)
183 static void warn_overflow(int size, int64_t data)
186 int64_t lim = ((int64_t)1 << (size*8))-1;
188 if (data < ~lim || data > lim)
189 errfunc(ERR_WARNING | ERR_WARN_NOV,
190 "%s data exceeds bounds", size_name(size));
194 * This routine wrappers the real output format's output routine,
195 * in order to pass a copy of the data off to the listing file
196 * generator at the same time.
198 static void out(int64_t offset, int32_t segto, const void *data,
199 enum out_type type, uint64_t size,
200 int32_t segment, int32_t wrt)
202 static int32_t lineno = 0; /* static!!! */
203 static char *lnfname = NULL;
206 if (type == OUT_ADDRESS && segment == NO_SEG && wrt == NO_SEG) {
208 * This is a non-relocated address, and we're going to
209 * convert it into RAWDATA format.
214 errfunc(ERR_PANIC, "OUT_ADDRESS with size > 8");
218 WRITEADDR(q, *(int64_t *)data, size);
223 list->output(offset, data, type, size);
226 * this call to src_get determines when we call the
227 * debug-format-specific "linenum" function
228 * it updates lineno and lnfname to the current values
229 * returning 0 if "same as last time", -2 if lnfname
230 * changed, and the amount by which lineno changed,
231 * if it did. thus, these variables must be static
234 if (src_get(&lineno, &lnfname)) {
235 outfmt->current_dfmt->linenum(lnfname, lineno, segto);
238 outfmt->output(segto, data, type, size, segment, wrt);
241 static int jmp_match(int32_t segment, int64_t offset, int bits,
242 insn * ins, const uint8_t *code)
247 if (c != 0370 && c != 0371)
249 if (ins->oprs[0].opflags & OPFLAG_FORWARD) {
250 if ((optimizing < 0 || (ins->oprs[0].type & STRICT))
254 return (pass0 == 0); /* match a forward reference */
256 isize = calcsize(segment, offset, bits, ins, code);
257 if (ins->oprs[0].segment != segment)
259 isize = ins->oprs[0].offset - offset - isize; /* isize is now the delta */
260 if (isize >= -128L && isize <= 127L)
261 return 1; /* it is byte size */
266 int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp,
267 insn * instruction, struct ofmt *output, efunc error,
270 const struct itemplate *temp;
275 int64_t start = offset;
276 int64_t wsize = 0; /* size for DB etc. */
278 errfunc = error; /* to pass to other functions */
280 outfmt = output; /* likewise */
281 list = listgen; /* and again */
283 switch (instruction->opcode) {
313 int32_t t = instruction->times;
316 "instruction->times < 0 (%ld) in assemble()", t);
318 while (t--) { /* repeat TIMES times */
319 for (e = instruction->eops; e; e = e->next) {
320 if (e->type == EOT_DB_NUMBER) {
322 if (e->segment != NO_SEG)
323 errfunc(ERR_NONFATAL,
324 "one-byte relocation attempted");
326 uint8_t out_byte = e->offset;
327 out(offset, segment, &out_byte,
328 OUT_RAWDATA, 1, NO_SEG, NO_SEG);
330 } else if (wsize > 8) {
331 errfunc(ERR_NONFATAL,
332 "integer supplied to a DT, DO or DY"
335 out(offset, segment, &e->offset,
336 OUT_ADDRESS, wsize, e->segment, e->wrt);
338 } else if (e->type == EOT_DB_STRING ||
339 e->type == EOT_DB_STRING_FREE) {
342 out(offset, segment, e->stringval,
343 OUT_RAWDATA, e->stringlen, NO_SEG, NO_SEG);
344 align = e->stringlen % wsize;
347 align = wsize - align;
348 out(offset, segment, const_zero_buf,
349 OUT_RAWDATA, align, NO_SEG, NO_SEG);
351 offset += e->stringlen + align;
354 if (t > 0 && t == instruction->times - 1) {
356 * Dummy call to list->output to give the offset to the
359 list->output(offset, NULL, OUT_RAWDATA, 0);
360 list->uplevel(LIST_TIMES);
363 if (instruction->times > 1)
364 list->downlevel(LIST_TIMES);
365 return offset - start;
368 if (instruction->opcode == I_INCBIN) {
369 const char *fname = instruction->eops->stringval;
372 fp = fopen(fname, "rb");
374 error(ERR_NONFATAL, "`incbin': unable to open file `%s'",
376 } else if (fseek(fp, 0L, SEEK_END) < 0) {
377 error(ERR_NONFATAL, "`incbin': unable to seek on file `%s'",
380 static char buf[4096];
381 size_t t = instruction->times;
386 if (instruction->eops->next) {
387 base = instruction->eops->next->offset;
389 if (instruction->eops->next->next &&
390 len > (size_t)instruction->eops->next->next->offset)
391 len = (size_t)instruction->eops->next->next->offset;
394 * Dummy call to list->output to give the offset to the
397 list->output(offset, NULL, OUT_RAWDATA, 0);
398 list->uplevel(LIST_INCBIN);
402 fseek(fp, base, SEEK_SET);
406 fread(buf, 1, (l > (int32_t) sizeof(buf) ? (int32_t) sizeof(buf) : l),
410 * This shouldn't happen unless the file
411 * actually changes while we are reading
415 "`incbin': unexpected EOF while"
416 " reading file `%s'", fname);
417 t = 0; /* Try to exit cleanly */
420 out(offset, segment, buf, OUT_RAWDATA, m,
425 list->downlevel(LIST_INCBIN);
426 if (instruction->times > 1) {
428 * Dummy call to list->output to give the offset to the
431 list->output(offset, NULL, OUT_RAWDATA, 0);
432 list->uplevel(LIST_TIMES);
433 list->downlevel(LIST_TIMES);
436 return instruction->times * len;
438 return 0; /* if we're here, there's an error */
441 /* Check to see if we need an address-size prefix */
442 add_asp(instruction, bits);
446 for (temp = nasm_instructions[instruction->opcode]; temp->opcode != -1; temp++){
447 int m = matches(temp, instruction, bits);
450 m += jmp_match(segment, offset, bits, instruction, temp->code);
452 if (m == 100) { /* matches! */
453 const uint8_t *codes = temp->code;
454 int64_t insn_size = calcsize(segment, offset, bits,
456 itimes = instruction->times;
457 if (insn_size < 0) /* shouldn't be, on pass two */
458 error(ERR_PANIC, "errors made it through from pass one");
461 for (j = 0; j < MAXPREFIX; j++) {
463 switch (instruction->prefixes[j]) {
479 "cs segment base generated, but will be ignored in 64-bit mode");
486 "ds segment base generated, but will be ignored in 64-bit mode");
493 "es segment base generated, but will be ignored in 64-bit mode");
506 "ss segment base generated, but will be ignored in 64-bit mode");
513 "segr6 and segr7 cannot be used as prefixes");
518 "16-bit addressing is not supported "
520 } else if (bits != 16)
530 "64-bit addressing is only supported "
554 error(ERR_PANIC, "invalid instruction prefix");
557 out(offset, segment, &c, OUT_RAWDATA, 1,
562 insn_end = offset + insn_size;
563 gencode(segment, offset, bits, instruction, codes,
566 if (itimes > 0 && itimes == instruction->times - 1) {
568 * Dummy call to list->output to give the offset to the
571 list->output(offset, NULL, OUT_RAWDATA, 0);
572 list->uplevel(LIST_TIMES);
575 if (instruction->times > 1)
576 list->downlevel(LIST_TIMES);
577 return offset - start;
578 } else if (m > 0 && m > size_prob) {
584 if (temp->opcode == -1) { /* didn't match any instruction */
587 error(ERR_NONFATAL, "operation size not specified");
590 error(ERR_NONFATAL, "mismatch in operand sizes");
593 error(ERR_NONFATAL, "no instruction for this cpu level");
596 error(ERR_NONFATAL, "instruction not supported in 64-bit mode");
600 "invalid combination of opcode and operands");
607 int64_t insn_size(int32_t segment, int64_t offset, int bits, uint32_t cp,
608 insn * instruction, efunc error)
610 const struct itemplate *temp;
612 errfunc = error; /* to pass to other functions */
615 if (instruction->opcode == -1)
618 if (instruction->opcode == I_DB || instruction->opcode == I_DW ||
619 instruction->opcode == I_DD || instruction->opcode == I_DQ ||
620 instruction->opcode == I_DT || instruction->opcode == I_DO ||
621 instruction->opcode == I_DY) {
623 int32_t isize, osize, wsize = 0; /* placate gcc */
626 switch (instruction->opcode) {
652 for (e = instruction->eops; e; e = e->next) {
656 if (e->type == EOT_DB_NUMBER)
658 else if (e->type == EOT_DB_STRING ||
659 e->type == EOT_DB_STRING_FREE)
660 osize = e->stringlen;
662 align = (-osize) % wsize;
665 isize += osize + align;
667 return isize * instruction->times;
670 if (instruction->opcode == I_INCBIN) {
671 const char *fname = instruction->eops->stringval;
675 fp = fopen(fname, "rb");
677 error(ERR_NONFATAL, "`incbin': unable to open file `%s'",
679 else if (fseek(fp, 0L, SEEK_END) < 0)
680 error(ERR_NONFATAL, "`incbin': unable to seek on file `%s'",
685 if (instruction->eops->next) {
686 len -= instruction->eops->next->offset;
687 if (instruction->eops->next->next &&
688 len > (size_t)instruction->eops->next->next->offset) {
689 len = (size_t)instruction->eops->next->next->offset;
692 return instruction->times * len;
694 return 0; /* if we're here, there's an error */
697 /* Check to see if we need an address-size prefix */
698 add_asp(instruction, bits);
700 for (temp = nasm_instructions[instruction->opcode]; temp->opcode != -1; temp++) {
701 int m = matches(temp, instruction, bits);
703 m += jmp_match(segment, offset, bits, instruction, temp->code);
706 /* we've matched an instruction. */
708 const uint8_t *codes = temp->code;
711 isize = calcsize(segment, offset, bits, instruction, codes);
714 for (j = 0; j < MAXPREFIX; j++) {
715 switch (instruction->prefixes[j]) {
741 return isize * instruction->times;
744 return -1; /* didn't match any instruction */
747 static bool possible_sbyte(insn * ins, int op)
749 return !(ins->forw_ref && ins->oprs[op].opflags) &&
751 !(ins->oprs[op].type & STRICT) &&
752 ins->oprs[op].wrt == NO_SEG && ins->oprs[op].segment == NO_SEG;
755 /* check that opn[op] is a signed byte of size 16 or 32 */
756 static bool is_sbyte16(insn * ins, int op)
760 if (!possible_sbyte(ins, op))
763 v = ins->oprs[op].offset;
764 return v >= -128 && v <= 127;
767 static bool is_sbyte32(insn * ins, int op)
771 if (!possible_sbyte(ins, op))
774 v = ins->oprs[op].offset;
775 return v >= -128 && v <= 127;
778 /* check that opn[op] is a signed byte of size 32; warn if this is not
779 the original value when extended to 64 bits */
780 static bool is_sbyte64(insn * ins, int op)
785 /* dead in the water on forward reference or External */
786 if (!possible_sbyte(ins, op))
789 v64 = ins->oprs[op].offset;
792 warn_overflow(32, v64);
794 return v32 >= -128 && v32 <= 127;
796 static int64_t calcsize(int32_t segment, int64_t offset, int bits,
797 insn * ins, const uint8_t *codes)
804 ins->rex = 0; /* Ensure REX is reset */
806 if (ins->prefixes[PPS_OSIZE] == P_O64)
809 (void)segment; /* Don't warn that this parameter is unused */
810 (void)offset; /* Don't warn that this parameter is unused */
814 opx = &ins->oprs[c & 3];
819 codes += c, length += c;
832 op_rexflags(opx, REX_B|REX_H|REX_P|REX_W);
863 if (opx->type & (BITS16 | BITS32 | BITS64))
864 length += (opx->type & BITS16) ? 2 : 4;
866 length += (bits == 16) ? 2 : 4;
878 length += ins->addr_size >> 3;
890 length += 8; /* MOV reg64/imm */
902 if (opx->type & (BITS16 | BITS32 | BITS64))
903 length += (opx->type & BITS16) ? 2 : 4;
905 length += (bits == 16) ? 2 : 4;
923 length += is_sbyte16(ins, c & 3) ? 1 : 2;
936 length += is_sbyte32(ins, c & 3) ? 1 : 4;
951 ins->drexdst = regval(opx);
958 ins->rex |= REX_D|REX_OC;
959 ins->drexdst = regval(opx);
973 length += is_sbyte64(ins, c & 3) ? 1 : 4;
981 ins->drexdst = regval(opx);
982 ins->vex_m = *codes++;
983 ins->vex_wlp = *codes++;
989 ins->vex_m = *codes++;
990 ins->vex_wlp = *codes++;
1000 length += (bits != 16) && !has_prefix(ins, PPS_ASIZE, P_A16);
1003 length += (bits != 32) && !has_prefix(ins, PPS_ASIZE, P_A32);
1008 if (bits != 64 || has_prefix(ins, PPS_ASIZE, P_A16) ||
1009 has_prefix(ins, PPS_ASIZE, P_A32))
1018 length += (bits != 16);
1021 length += (bits == 16);
1046 if (ins->oprs[0].segment != NO_SEG)
1047 errfunc(ERR_NONFATAL, "attempt to reserve non-constant"
1048 " quantity of BSS space");
1050 length += ins->oprs[0].offset;
1073 default: /* can't do it by 'case' statements */
1074 if (c >= 0100 && c <= 0277) { /* it's an EA */
1078 ea_data.rex = 0; /* Ensure ea.REX is initially 0 */
1081 /* pick rfield from operand b */
1082 rflags = regflag(&ins->oprs[c & 7]);
1083 rfield = nasm_regvals[ins->oprs[c & 7].basereg];
1090 (&ins->oprs[(c >> 3) & 7], &ea_data, bits,
1091 ins->addr_size, rfield, rflags, ins->forw_ref)) {
1092 errfunc(ERR_NONFATAL, "invalid effective address");
1095 ins->rex |= ea_data.rex;
1096 length += ea_data.size;
1099 errfunc(ERR_PANIC, "internal instruction table corrupt"
1100 ": instruction code 0x%02X given", c);
1105 ins->rex &= rex_mask;
1107 if (ins->rex & REX_V) {
1108 int bad32 = REX_R|REX_W|REX_X|REX_B;
1110 if (ins->rex & REX_H) {
1111 errfunc(ERR_NONFATAL, "cannot use high register in vex instruction");
1114 switch (ins->vex_wlp & 030) {
1128 if (bits != 64 && ((ins->rex & bad32) || ins->drexdst > 7)) {
1129 errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode");
1132 if (ins->vex_m != 1 || (ins->rex & (REX_W|REX_R|REX_B)))
1136 } else if (ins->rex & REX_D) {
1137 if (ins->rex & REX_H) {
1138 errfunc(ERR_NONFATAL, "cannot use high register in drex instruction");
1141 if (bits != 64 && ((ins->rex & (REX_R|REX_W|REX_X|REX_B)) ||
1142 ins->drexdst > 7)) {
1143 errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode");
1147 } else if (ins->rex & REX_REAL) {
1148 if (ins->rex & REX_H) {
1149 errfunc(ERR_NONFATAL, "cannot use high register in rex instruction");
1151 } else if (bits == 64) {
1153 } else if ((ins->rex & REX_L) &&
1154 !(ins->rex & (REX_P|REX_W|REX_X|REX_B)) &&
1157 assert_no_prefix(ins, PPS_LREP);
1160 errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode");
1168 #define EMIT_REX() \
1169 if (!(ins->rex & (REX_D|REX_V)) && (ins->rex & REX_REAL) && (bits == 64)) { \
1170 ins->rex = (ins->rex & REX_REAL)|REX_P; \
1171 out(offset, segment, &ins->rex, OUT_RAWDATA, 1, NO_SEG, NO_SEG); \
1176 static void gencode(int32_t segment, int64_t offset, int bits,
1177 insn * ins, const uint8_t *codes, int64_t insn_end)
1179 static char condval[] = { /* conditional opcodes */
1180 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
1181 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
1182 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
1188 struct operand *opx;
1192 opx = &ins->oprs[c & 3];
1198 out(offset, segment, codes, OUT_RAWDATA, c, NO_SEG, NO_SEG);
1205 switch (ins->oprs[0].basereg) {
1207 bytes[0] = 0x0E + (c == 0x04 ? 1 : 0);
1210 bytes[0] = 0x1E + (c == 0x04 ? 1 : 0);
1213 bytes[0] = 0x06 + (c == 0x04 ? 1 : 0);
1216 bytes[0] = 0x16 + (c == 0x04 ? 1 : 0);
1220 "bizarre 8086 segment register received");
1222 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1228 switch (ins->oprs[0].basereg) {
1230 bytes[0] = 0xA0 + (c == 0x05 ? 1 : 0);
1233 bytes[0] = 0xA8 + (c == 0x05 ? 1 : 0);
1237 "bizarre 386 segment register received");
1239 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1248 bytes[0] = *codes++ + ((regval(opx)) & 7);
1249 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1257 /* XXX: warns for legitimate optimizer actions */
1258 if (opx->offset < -128 || opx->offset > 127) {
1259 errfunc(ERR_WARNING | ERR_WARN_NOV,
1260 "signed byte value exceeds bounds");
1263 if (opx->segment != NO_SEG) {
1265 out(offset, segment, &data, OUT_ADDRESS, 1,
1266 opx->segment, opx->wrt);
1268 bytes[0] = opx->offset;
1269 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1279 if (opx->offset < -256 || opx->offset > 255) {
1280 errfunc(ERR_WARNING | ERR_WARN_NOV,
1281 "byte value exceeds bounds");
1283 if (opx->segment != NO_SEG) {
1285 out(offset, segment, &data, OUT_ADDRESS, 1,
1286 opx->segment, opx->wrt);
1288 bytes[0] = opx->offset;
1289 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1299 if (opx->offset < 0 || opx->offset > 255)
1300 errfunc(ERR_WARNING | ERR_WARN_NOV,
1301 "unsigned byte value exceeds bounds");
1302 if (opx->segment != NO_SEG) {
1304 out(offset, segment, &data, OUT_ADDRESS, 1,
1305 opx->segment, opx->wrt);
1307 bytes[0] = opx->offset;
1308 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1319 if (opx->segment == NO_SEG && opx->wrt == NO_SEG)
1320 warn_overflow(2, data);
1321 out(offset, segment, &data, OUT_ADDRESS, 2,
1322 opx->segment, opx->wrt);
1330 if (opx->type & (BITS16 | BITS32))
1331 size = (opx->type & BITS16) ? 2 : 4;
1333 size = (bits == 16) ? 2 : 4;
1335 if (opx->segment == NO_SEG && opx->wrt == NO_SEG)
1336 warn_overflow(size, data);
1337 out(offset, segment, &data, OUT_ADDRESS, size,
1338 opx->segment, opx->wrt);
1347 if (opx->segment == NO_SEG && opx->wrt == NO_SEG)
1348 warn_overflow(4, data);
1349 out(offset, segment, &data, OUT_ADDRESS, 4,
1350 opx->segment, opx->wrt);
1359 size = ins->addr_size >> 3;
1360 if (opx->segment == NO_SEG &&
1362 warn_overflow(size, data);
1363 out(offset, segment, &data, OUT_ADDRESS, size,
1364 opx->segment, opx->wrt);
1372 if (opx->segment != segment)
1373 errfunc(ERR_NONFATAL,
1374 "short relative jump outside segment");
1375 data = opx->offset - insn_end;
1376 if (data > 127 || data < -128)
1377 errfunc(ERR_NONFATAL, "short jump is out of range");
1379 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1387 data = (int64_t)opx->offset;
1388 out(offset, segment, &data, OUT_ADDRESS, 8,
1389 opx->segment, opx->wrt);
1397 if (opx->segment != segment) {
1399 out(offset, segment, &data,
1400 OUT_REL2ADR, insn_end - offset,
1401 opx->segment, opx->wrt);
1403 data = opx->offset - insn_end;
1404 out(offset, segment, &data,
1405 OUT_ADDRESS, 2, NO_SEG, NO_SEG);
1414 if (opx->type & (BITS16 | BITS32 | BITS64))
1415 size = (opx->type & BITS16) ? 2 : 4;
1417 size = (bits == 16) ? 2 : 4;
1418 if (opx->segment != segment) {
1420 out(offset, segment, &data,
1421 size == 2 ? OUT_REL2ADR : OUT_REL4ADR,
1422 insn_end - offset, opx->segment, opx->wrt);
1424 data = opx->offset - insn_end;
1425 out(offset, segment, &data,
1426 OUT_ADDRESS, size, NO_SEG, NO_SEG);
1435 if (opx->segment != segment) {
1437 out(offset, segment, &data,
1438 OUT_REL4ADR, insn_end - offset,
1439 opx->segment, opx->wrt);
1441 data = opx->offset - insn_end;
1442 out(offset, segment, &data,
1443 OUT_ADDRESS, 4, NO_SEG, NO_SEG);
1452 if (opx->segment == NO_SEG)
1453 errfunc(ERR_NONFATAL, "value referenced by FAR is not"
1456 out(offset, segment, &data, OUT_ADDRESS, 2,
1457 outfmt->segbase(1 + opx->segment),
1467 if (is_sbyte16(ins, c & 3)) {
1469 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1473 if (opx->segment == NO_SEG &&
1475 warn_overflow(2, data);
1476 out(offset, segment, &data, OUT_ADDRESS, 2,
1477 opx->segment, opx->wrt);
1487 bytes[0] = *codes++;
1488 if (is_sbyte16(ins, c & 3))
1489 bytes[0] |= 2; /* s-bit */
1490 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1499 if (is_sbyte32(ins, c & 3)) {
1501 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1505 out(offset, segment, &data, OUT_ADDRESS, 4,
1506 opx->segment, opx->wrt);
1516 bytes[0] = *codes++;
1517 if (is_sbyte32(ins, c & 3))
1518 bytes[0] |= 2; /* s-bit */
1519 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1535 (ins->drexdst << 4) |
1536 (ins->rex & REX_OC ? 0x08 : 0) |
1537 (ins->rex & (REX_R|REX_X|REX_B));
1539 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1545 opx = &ins->oprs[c >> 3];
1546 bytes[0] = nasm_regvals[opx->basereg] << 4;
1547 opx = &ins->oprs[c & 7];
1548 if (opx->segment != NO_SEG || opx->wrt != NO_SEG) {
1549 errfunc(ERR_NONFATAL,
1550 "non-absolute expression not permitted as argument %d",
1553 if (opx->offset & ~15) {
1554 errfunc(ERR_WARNING | ERR_WARN_NOV,
1555 "four-bit argument exceeds bounds");
1557 bytes[0] |= opx->offset & 15;
1559 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1565 opx = &ins->oprs[c >> 4];
1566 bytes[0] = nasm_regvals[opx->basereg] << 4;
1568 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1574 opx = &ins->oprs[c];
1575 bytes[0] = nasm_regvals[opx->basereg] << 4;
1576 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1585 /* is_sbyte32() is right here, we have already warned */
1586 if (is_sbyte32(ins, c & 3)) {
1588 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1592 out(offset, segment, &data, OUT_ADDRESS, 4,
1593 opx->segment, opx->wrt);
1604 if (ins->vex_m != 1 || (ins->rex & (REX_W|REX_X|REX_B))) {
1606 bytes[1] = ins->vex_m | ((~ins->rex & 7) << 5);
1607 bytes[2] = ((ins->rex & REX_W) << (7-3)) |
1608 ((~ins->drexdst & 15)<< 3) | (ins->vex_wlp & 07);
1609 out(offset, segment, &bytes, OUT_RAWDATA, 3, NO_SEG, NO_SEG);
1613 bytes[1] = ((~ins->rex & REX_R) << (7-2)) |
1614 ((~ins->drexdst & 15) << 3) | (ins->vex_wlp & 07);
1615 out(offset, segment, &bytes, OUT_RAWDATA, 2, NO_SEG, NO_SEG);
1627 if (bits == 32 && !has_prefix(ins, PPS_ASIZE, P_A16)) {
1629 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1636 if (bits != 32 && !has_prefix(ins, PPS_ASIZE, P_A32)) {
1638 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1660 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1669 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1684 *bytes = *codes++ ^ condval[ins->condition];
1685 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1694 *bytes = c - 0332 + 0xF2;
1695 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1700 if (ins->rex & REX_R) {
1702 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1705 ins->rex &= ~(REX_L|REX_R);
1712 if (ins->oprs[0].segment != NO_SEG)
1713 errfunc(ERR_PANIC, "non-constant BSS size in pass two");
1715 int64_t size = ins->oprs[0].offset;
1717 out(offset, segment, NULL,
1718 OUT_RESERVE, size, NO_SEG, NO_SEG);
1728 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1734 bytes[0] = c - 0362 + 0xf2;
1735 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1745 *bytes = c - 0366 + 0x66;
1746 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1756 *bytes = bits == 16 ? 3 : 5;
1757 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1761 default: /* can't do it by 'case' statements */
1762 if (c >= 0100 && c <= 0277) { /* it's an EA */
1770 /* pick rfield from operand b */
1771 rflags = regflag(&ins->oprs[c & 7]);
1772 rfield = nasm_regvals[ins->oprs[c & 7].basereg];
1774 /* rfield is constant */
1780 (&ins->oprs[(c >> 3) & 7], &ea_data, bits,
1781 ins->addr_size, rfield, rflags, ins->forw_ref)) {
1782 errfunc(ERR_NONFATAL, "invalid effective address");
1787 *p++ = ea_data.modrm;
1788 if (ea_data.sib_present)
1791 /* DREX suffixes come between the SIB and the displacement */
1792 if (ins->rex & REX_D) {
1794 (ins->drexdst << 4) |
1795 (ins->rex & REX_OC ? 0x08 : 0) |
1796 (ins->rex & (REX_R|REX_X|REX_B));
1801 out(offset, segment, bytes, OUT_RAWDATA, s, NO_SEG, NO_SEG);
1803 switch (ea_data.bytes) {
1807 if (ins->oprs[(c >> 3) & 7].segment != NO_SEG) {
1808 data = ins->oprs[(c >> 3) & 7].offset;
1809 out(offset, segment, &data, OUT_ADDRESS, 1,
1810 ins->oprs[(c >> 3) & 7].segment,
1811 ins->oprs[(c >> 3) & 7].wrt);
1813 *bytes = ins->oprs[(c >> 3) & 7].offset;
1814 out(offset, segment, bytes, OUT_RAWDATA, 1,
1822 data = ins->oprs[(c >> 3) & 7].offset;
1823 warn_overflow(ea_data.bytes, data);
1824 out(offset, segment, &data,
1825 ea_data.rip ? OUT_REL4ADR : OUT_ADDRESS,
1827 ins->oprs[(c >> 3) & 7].segment,
1828 ins->oprs[(c >> 3) & 7].wrt);
1834 errfunc(ERR_PANIC, "internal instruction table corrupt"
1835 ": instruction code 0x%02X given", c);
1841 static int32_t regflag(const operand * o)
1843 if (o->basereg < EXPR_REG_START || o->basereg >= REG_ENUM_LIMIT) {
1844 errfunc(ERR_PANIC, "invalid operand passed to regflag()");
1846 return nasm_reg_flags[o->basereg];
1849 static int32_t regval(const operand * o)
1851 if (o->basereg < EXPR_REG_START || o->basereg >= REG_ENUM_LIMIT) {
1852 errfunc(ERR_PANIC, "invalid operand passed to regval()");
1854 return nasm_regvals[o->basereg];
1857 static int op_rexflags(const operand * o, int mask)
1862 if (o->basereg < EXPR_REG_START || o->basereg >= REG_ENUM_LIMIT) {
1863 errfunc(ERR_PANIC, "invalid operand passed to op_rexflags()");
1866 flags = nasm_reg_flags[o->basereg];
1867 val = nasm_regvals[o->basereg];
1869 return rexflags(val, flags, mask);
1872 static int rexflags(int val, int32_t flags, int mask)
1877 rex |= REX_B|REX_X|REX_R;
1880 if (!(REG_HIGH & ~flags)) /* AH, CH, DH, BH */
1882 else if (!(REG8 & ~flags) && val >= 4) /* SPL, BPL, SIL, DIL */
1888 static int matches(const struct itemplate *itemp, insn * instruction, int bits)
1890 int i, size[MAX_OPERANDS], asize, oprs, ret;
1897 if (itemp->opcode != instruction->opcode)
1901 * Count the operands
1903 if (itemp->operands != instruction->operands)
1907 * Check that no spurious colons or TOs are present
1909 for (i = 0; i < itemp->operands; i++)
1910 if (instruction->oprs[i].type & ~itemp->opd[i] & (COLON | TO))
1914 * Process size flags
1916 if (itemp->flags & IF_ARMASK) {
1917 memset(size, 0, sizeof size);
1919 i = ((itemp->flags & IF_ARMASK) >> IF_ARSHFT) - 1;
1921 switch (itemp->flags & IF_SMASK) {
1958 switch (itemp->flags & IF_SMASK) {
1993 for (i = 0; i < MAX_OPERANDS; i++)
1998 * Check that the operand flags all match up
2000 for (i = 0; i < itemp->operands; i++) {
2001 int32_t type = instruction->oprs[i].type;
2002 if (!(type & SIZE_MASK))
2005 if (itemp->opd[i] & SAME_AS) {
2006 int j = itemp->opd[i] & ~SAME_AS;
2007 if (type != instruction->oprs[j].type ||
2008 instruction->oprs[i].basereg != instruction->oprs[j].basereg)
2010 } else if (itemp->opd[i] & ~type ||
2011 ((itemp->opd[i] & SIZE_MASK) &&
2012 ((itemp->opd[i] ^ type) & SIZE_MASK))) {
2013 if ((itemp->opd[i] & ~type & ~SIZE_MASK) ||
2022 * Check operand sizes
2024 if (itemp->flags & (IF_SM | IF_SM2)) {
2025 oprs = (itemp->flags & IF_SM2 ? 2 : itemp->operands);
2027 for (i = 0; i < oprs; i++) {
2028 if ((asize = itemp->opd[i] & SIZE_MASK) != 0) {
2030 for (j = 0; j < oprs; j++)
2036 oprs = itemp->operands;
2039 for (i = 0; i < itemp->operands; i++) {
2040 if (!(itemp->opd[i] & SIZE_MASK) &&
2041 (instruction->oprs[i].type & SIZE_MASK & ~size[i]))
2046 * Check template is okay at the set cpu level
2048 if (((itemp->flags & IF_PLEVEL) > cpu))
2052 * Check if instruction is available in long mode
2054 if ((itemp->flags & IF_NOLONG) && (bits == 64))
2058 * Check if special handling needed for Jumps
2060 if ((uint8_t)(itemp->code[0]) >= 0370)
2066 static ea *process_ea(operand * input, ea * output, int bits,
2067 int addrbits, int rfield, int32_t rflags, int forw_ref)
2069 output->rip = false;
2071 /* REX flags for the rfield operand */
2072 output->rex |= rexflags(rfield, rflags, REX_R|REX_P|REX_W|REX_H);
2074 if (!(REGISTER & ~input->type)) { /* register direct */
2078 if (input->basereg < EXPR_REG_START /* Verify as Register */
2079 || input->basereg >= REG_ENUM_LIMIT)
2082 i = nasm_regvals[input->basereg];
2085 return NULL; /* Invalid EA register */
2087 output->rex |= op_rexflags(input, REX_B|REX_P|REX_W|REX_H);
2089 output->sib_present = false; /* no SIB necessary */
2090 output->bytes = 0; /* no offset necessary either */
2091 output->modrm = 0xC0 | ((rfield & 7) << 3) | (i & 7);
2092 } else { /* it's a memory reference */
2093 if (input->basereg == -1
2094 && (input->indexreg == -1 || input->scale == 0)) {
2095 /* it's a pure offset */
2096 if (bits == 64 && (~input->type & IP_REL)) {
2097 int scale, index, base;
2098 output->sib_present = true;
2102 output->sib = (scale << 6) | (index << 3) | base;
2104 output->modrm = 4 | ((rfield & 7) << 3);
2105 output->rip = false;
2107 output->sib_present = false;
2108 output->bytes = (addrbits != 16 ? 4 : 2);
2109 output->modrm = (addrbits != 16 ? 5 : 6) | ((rfield & 7) << 3);
2110 output->rip = bits == 64;
2112 } else { /* it's an indirection */
2113 int i = input->indexreg, b = input->basereg, s = input->scale;
2114 int32_t o = input->offset, seg = input->segment;
2115 int hb = input->hintbase, ht = input->hinttype;
2118 int32_t ix, bx; /* register flags */
2121 i = -1; /* make this easy, at least */
2123 if (i >= EXPR_REG_START && i < REG_ENUM_LIMIT) {
2124 it = nasm_regvals[i];
2125 ix = nasm_reg_flags[i];
2131 if (b >= EXPR_REG_START && b < REG_ENUM_LIMIT) {
2132 bt = nasm_regvals[b];
2133 bx = nasm_reg_flags[b];
2139 /* check for a 32/64-bit memory reference... */
2140 if ((ix|bx) & (BITS32|BITS64)) {
2141 /* it must be a 32/64-bit memory reference. Firstly we have
2142 * to check that all registers involved are type E/Rxx. */
2143 int32_t sok = BITS32|BITS64;
2146 if (!(REG64 & ~ix) || !(REG32 & ~ix))
2154 return NULL; /* Invalid register */
2155 if (~sok & bx & SIZE_MASK)
2156 return NULL; /* Invalid size */
2160 /* While we're here, ensure the user didn't specify
2162 if (input->disp_size == 16 || input->disp_size == 64)
2165 if (addrbits == 16 ||
2166 (addrbits == 32 && !(sok & BITS32)) ||
2167 (addrbits == 64 && !(sok & BITS64)))
2170 /* now reorganize base/index */
2171 if (s == 1 && bt != it && bt != -1 && it != -1 &&
2172 ((hb == b && ht == EAH_NOTBASE)
2173 || (hb == i && ht == EAH_MAKEBASE))) {
2174 /* swap if hints say so */
2175 t = bt, bt = it, it = t;
2176 t = bx, bx = ix, ix = t;
2178 if (bt == it) /* convert EAX+2*EAX to 3*EAX */
2179 bt = -1, bx = 0, s++;
2180 if (bt == -1 && s == 1 && !(hb == it && ht == EAH_NOTBASE)) {
2181 /* make single reg base, unless hint */
2182 bt = it, bx = ix, it = -1, ix = 0;
2184 if (((s == 2 && it != REG_NUM_ESP
2185 && !(input->eaflags & EAF_TIMESTWO)) || s == 3
2186 || s == 5 || s == 9) && bt == -1)
2187 bt = it, bx = ix, s--; /* convert 3*EAX to EAX+2*EAX */
2188 if (it == -1 && (bt & 7) != REG_NUM_ESP
2189 && (input->eaflags & EAF_TIMESTWO))
2190 it = bt, ix = bx, bt = -1, bx = 0, s = 1;
2191 /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */
2192 if (s == 1 && it == REG_NUM_ESP) {
2193 /* swap ESP into base if scale is 1 */
2194 t = it, it = bt, bt = t;
2195 t = ix, ix = bx, bx = t;
2197 if (it == REG_NUM_ESP
2198 || (s != 1 && s != 2 && s != 4 && s != 8 && it != -1))
2199 return NULL; /* wrong, for various reasons */
2201 output->rex |= rexflags(it, ix, REX_X);
2202 output->rex |= rexflags(bt, bx, REX_B);
2204 if (it == -1 && (bt & 7) != REG_NUM_ESP) {
2213 if (rm != REG_NUM_EBP && o == 0 &&
2214 seg == NO_SEG && !forw_ref &&
2216 (EAF_BYTEOFFS | EAF_WORDOFFS)))
2218 else if (input->eaflags & EAF_BYTEOFFS ||
2219 (o >= -128 && o <= 127 && seg == NO_SEG
2221 && !(input->eaflags & EAF_WORDOFFS)))
2227 output->sib_present = false;
2228 output->bytes = (bt == -1 || mod == 2 ? 4 : mod);
2229 output->modrm = (mod << 6) | ((rfield & 7) << 3) | rm;
2232 int mod, scale, index, base;
2252 default: /* then what the smeg is it? */
2253 return NULL; /* panic */
2261 if (base != REG_NUM_EBP && o == 0 &&
2262 seg == NO_SEG && !forw_ref &&
2264 (EAF_BYTEOFFS | EAF_WORDOFFS)))
2266 else if (input->eaflags & EAF_BYTEOFFS ||
2267 (o >= -128 && o <= 127 && seg == NO_SEG
2269 && !(input->eaflags & EAF_WORDOFFS)))
2275 output->sib_present = true;
2276 output->bytes = (bt == -1 || mod == 2 ? 4 : mod);
2277 output->modrm = (mod << 6) | ((rfield & 7) << 3) | 4;
2278 output->sib = (scale << 6) | (index << 3) | base;
2280 } else { /* it's 16-bit */
2283 /* check for 64-bit long mode */
2287 /* check all registers are BX, BP, SI or DI */
2288 if ((b != -1 && b != R_BP && b != R_BX && b != R_SI
2289 && b != R_DI) || (i != -1 && i != R_BP && i != R_BX
2290 && i != R_SI && i != R_DI))
2293 /* ensure the user didn't specify DWORD/QWORD */
2294 if (input->disp_size == 32 || input->disp_size == 64)
2297 if (s != 1 && i != -1)
2298 return NULL; /* no can do, in 16-bit EA */
2299 if (b == -1 && i != -1) {
2304 if ((b == R_SI || b == R_DI) && i != -1) {
2309 /* have BX/BP as base, SI/DI index */
2311 return NULL; /* shouldn't ever happen, in theory */
2312 if (i != -1 && b != -1 &&
2313 (i == R_BP || i == R_BX || b == R_SI || b == R_DI))
2314 return NULL; /* invalid combinations */
2315 if (b == -1) /* pure offset: handled above */
2316 return NULL; /* so if it gets to here, panic! */
2320 switch (i * 256 + b) {
2321 case R_SI * 256 + R_BX:
2324 case R_DI * 256 + R_BX:
2327 case R_SI * 256 + R_BP:
2330 case R_DI * 256 + R_BP:
2348 if (rm == -1) /* can't happen, in theory */
2349 return NULL; /* so panic if it does */
2351 if (o == 0 && seg == NO_SEG && !forw_ref && rm != 6 &&
2352 !(input->eaflags & (EAF_BYTEOFFS | EAF_WORDOFFS)))
2354 else if (input->eaflags & EAF_BYTEOFFS ||
2355 (o >= -128 && o <= 127 && seg == NO_SEG
2357 && !(input->eaflags & EAF_WORDOFFS)))
2362 output->sib_present = false; /* no SIB - it's 16-bit */
2363 output->bytes = mod; /* bytes of offset needed */
2364 output->modrm = (mod << 6) | ((rfield & 7) << 3) | rm;
2369 output->size = 1 + output->sib_present + output->bytes;
2373 static void add_asp(insn *ins, int addrbits)
2378 valid = (addrbits == 64) ? 64|32 : 32|16;
2380 switch (ins->prefixes[PPS_ASIZE]) {
2391 valid &= (addrbits == 32) ? 16 : 32;
2397 for (j = 0; j < ins->operands; j++) {
2398 if (!(MEMORY & ~ins->oprs[j].type)) {
2401 /* Verify as Register */
2402 if (ins->oprs[j].indexreg < EXPR_REG_START
2403 || ins->oprs[j].indexreg >= REG_ENUM_LIMIT)
2406 i = nasm_reg_flags[ins->oprs[j].indexreg];
2408 /* Verify as Register */
2409 if (ins->oprs[j].basereg < EXPR_REG_START
2410 || ins->oprs[j].basereg >= REG_ENUM_LIMIT)
2413 b = nasm_reg_flags[ins->oprs[j].basereg];
2415 if (ins->oprs[j].scale == 0)
2419 int ds = ins->oprs[j].disp_size;
2420 if ((addrbits != 64 && ds > 8) ||
2421 (addrbits == 64 && ds == 16))
2441 if (valid & addrbits) {
2442 ins->addr_size = addrbits;
2443 } else if (valid & ((addrbits == 32) ? 16 : 32)) {
2444 /* Add an address size prefix */
2445 enum prefixes pref = (addrbits == 32) ? P_A16 : P_A32;
2446 ins->prefixes[PPS_ASIZE] = pref;
2447 ins->addr_size = (addrbits == 32) ? 16 : 32;
2450 errfunc(ERR_NONFATAL, "impossible combination of address sizes");
2451 ins->addr_size = addrbits; /* Error recovery */
2454 defdisp = ins->addr_size == 16 ? 16 : 32;
2456 for (j = 0; j < ins->operands; j++) {
2457 if (!(MEM_OFFS & ~ins->oprs[j].type) &&
2458 (ins->oprs[j].disp_size ? ins->oprs[j].disp_size : defdisp)
2459 != ins->addr_size) {
2460 /* mem_offs sizes must match the address size; if not,
2461 strip the MEM_OFFS bit and match only EA instructions */
2462 ins->oprs[j].type &= ~(MEM_OFFS & ~MEMORY);