Add dummy test for version tracking
[nasm/autotest.git] / assemble.c
blob31955e5d7346331a41dbf67ec9cf91096f66ba7a
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
14 * on operand 0
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
43 * operand 0..3.
44 * \164..\167 - this instruction uses DREX rather than REX, with the
45 * OC0 field set to 1, and the dest field taken from
46 * operand 0..3.
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:
66 * 00 0ww lpp
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"
114 #include <stdio.h>
115 #include <string.h>
116 #include <inttypes.h>
118 #include "nasm.h"
119 #include "nasmlib.h"
120 #include "assemble.h"
121 #include "insns.h"
122 #include "tables.h"
124 /* Initialized to zero by the C standard */
125 static const uint8_t const_zero_buf[256];
127 typedef struct {
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 */
132 } ea;
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)
163 switch (size) {
164 case 1:
165 return "byte";
166 case 2:
167 return "word";
168 case 4:
169 return "dword";
170 case 8:
171 return "qword";
172 case 10:
173 return "tword";
174 case 16:
175 return "oword";
176 case 32:
177 return "yword";
178 default:
179 return "???";
183 static void warn_overflow(int size, int64_t data)
185 if (size < 8) {
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;
204 uint8_t p[8];
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.
211 uint8_t *q = p;
213 if (size > 8) {
214 errfunc(ERR_PANIC, "OUT_ADDRESS with size > 8");
215 return;
218 WRITEADDR(q, *(int64_t *)data, size);
219 data = p;
220 type = OUT_RAWDATA;
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)
244 int64_t isize;
245 uint8_t c = code[0];
247 if (c != 0370 && c != 0371)
248 return 0;
249 if (ins->oprs[0].opflags & OPFLAG_FORWARD) {
250 if ((optimizing < 0 || (ins->oprs[0].type & STRICT))
251 && c == 0370)
252 return 1;
253 else
254 return (pass0 == 0); /* match a forward reference */
256 isize = calcsize(segment, offset, bits, ins, code);
257 if (ins->oprs[0].segment != segment)
258 return 0;
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 */
263 return 0;
266 int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp,
267 insn * instruction, struct ofmt *output, efunc error,
268 ListGen * listgen)
270 const struct itemplate *temp;
271 int j;
272 int size_prob;
273 int64_t insn_end;
274 int32_t itimes;
275 int64_t start = offset;
276 int64_t wsize = 0; /* size for DB etc. */
278 errfunc = error; /* to pass to other functions */
279 cpu = cp;
280 outfmt = output; /* likewise */
281 list = listgen; /* and again */
283 switch (instruction->opcode) {
284 case -1:
285 return 0;
286 case I_DB:
287 wsize = 1;
288 break;
289 case I_DW:
290 wsize = 2;
291 break;
292 case I_DD:
293 wsize = 4;
294 break;
295 case I_DQ:
296 wsize = 8;
297 break;
298 case I_DT:
299 wsize = 10;
300 break;
301 case I_DO:
302 wsize = 16;
303 break;
304 case I_DY:
305 wsize = 32;
306 break;
307 default:
308 break;
311 if (wsize) {
312 extop *e;
313 int32_t t = instruction->times;
314 if (t < 0)
315 errfunc(ERR_PANIC,
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) {
321 if (wsize == 1) {
322 if (e->segment != NO_SEG)
323 errfunc(ERR_NONFATAL,
324 "one-byte relocation attempted");
325 else {
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"
333 " instruction");
334 } else
335 out(offset, segment, &e->offset,
336 OUT_ADDRESS, wsize, e->segment, e->wrt);
337 offset += wsize;
338 } else if (e->type == EOT_DB_STRING ||
339 e->type == EOT_DB_STRING_FREE) {
340 int align;
342 out(offset, segment, e->stringval,
343 OUT_RAWDATA, e->stringlen, NO_SEG, NO_SEG);
344 align = e->stringlen % wsize;
346 if (align) {
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
357 * listing module.
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;
370 FILE *fp;
372 fp = fopen(fname, "rb");
373 if (!fp) {
374 error(ERR_NONFATAL, "`incbin': unable to open file `%s'",
375 fname);
376 } else if (fseek(fp, 0L, SEEK_END) < 0) {
377 error(ERR_NONFATAL, "`incbin': unable to seek on file `%s'",
378 fname);
379 } else {
380 static char buf[4096];
381 size_t t = instruction->times;
382 size_t base = 0;
383 size_t len;
385 len = ftell(fp);
386 if (instruction->eops->next) {
387 base = instruction->eops->next->offset;
388 len -= base;
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
395 * listing module.
397 list->output(offset, NULL, OUT_RAWDATA, 0);
398 list->uplevel(LIST_INCBIN);
399 while (t--) {
400 size_t l;
402 fseek(fp, base, SEEK_SET);
403 l = len;
404 while (l > 0) {
405 int32_t m =
406 fread(buf, 1, (l > (int32_t) sizeof(buf) ? (int32_t) sizeof(buf) : l),
407 fp);
408 if (!m) {
410 * This shouldn't happen unless the file
411 * actually changes while we are reading
412 * it.
414 error(ERR_NONFATAL,
415 "`incbin': unexpected EOF while"
416 " reading file `%s'", fname);
417 t = 0; /* Try to exit cleanly */
418 break;
420 out(offset, segment, buf, OUT_RAWDATA, m,
421 NO_SEG, NO_SEG);
422 l -= m;
425 list->downlevel(LIST_INCBIN);
426 if (instruction->times > 1) {
428 * Dummy call to list->output to give the offset to the
429 * listing module.
431 list->output(offset, NULL, OUT_RAWDATA, 0);
432 list->uplevel(LIST_TIMES);
433 list->downlevel(LIST_TIMES);
435 fclose(fp);
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);
444 size_prob = false;
446 for (temp = nasm_instructions[instruction->opcode]; temp->opcode != -1; temp++){
447 int m = matches(temp, instruction, bits);
449 if (m == 99)
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,
455 instruction, codes);
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");
459 else
460 while (itimes--) {
461 for (j = 0; j < MAXPREFIX; j++) {
462 uint8_t c = 0;
463 switch (instruction->prefixes[j]) {
464 case P_LOCK:
465 c = 0xF0;
466 break;
467 case P_REPNE:
468 case P_REPNZ:
469 c = 0xF2;
470 break;
471 case P_REPE:
472 case P_REPZ:
473 case P_REP:
474 c = 0xF3;
475 break;
476 case R_CS:
477 if (bits == 64) {
478 error(ERR_WARNING,
479 "cs segment base generated, but will be ignored in 64-bit mode");
481 c = 0x2E;
482 break;
483 case R_DS:
484 if (bits == 64) {
485 error(ERR_WARNING,
486 "ds segment base generated, but will be ignored in 64-bit mode");
488 c = 0x3E;
489 break;
490 case R_ES:
491 if (bits == 64) {
492 error(ERR_WARNING,
493 "es segment base generated, but will be ignored in 64-bit mode");
495 c = 0x26;
496 break;
497 case R_FS:
498 c = 0x64;
499 break;
500 case R_GS:
501 c = 0x65;
502 break;
503 case R_SS:
504 if (bits == 64) {
505 error(ERR_WARNING,
506 "ss segment base generated, but will be ignored in 64-bit mode");
508 c = 0x36;
509 break;
510 case R_SEGR6:
511 case R_SEGR7:
512 error(ERR_NONFATAL,
513 "segr6 and segr7 cannot be used as prefixes");
514 break;
515 case P_A16:
516 if (bits == 64) {
517 error(ERR_NONFATAL,
518 "16-bit addressing is not supported "
519 "in 64-bit mode");
520 } else if (bits != 16)
521 c = 0x67;
522 break;
523 case P_A32:
524 if (bits != 32)
525 c = 0x67;
526 break;
527 case P_A64:
528 if (bits != 64) {
529 error(ERR_NONFATAL,
530 "64-bit addressing is only supported "
531 "in 64-bit mode");
533 break;
534 case P_ASP:
535 c = 0x67;
536 break;
537 case P_O16:
538 if (bits != 16)
539 c = 0x66;
540 break;
541 case P_O32:
542 if (bits == 16)
543 c = 0x66;
544 break;
545 case P_O64:
546 /* REX.W */
547 break;
548 case P_OSP:
549 c = 0x66;
550 break;
551 case P_none:
552 break;
553 default:
554 error(ERR_PANIC, "invalid instruction prefix");
556 if (c != 0) {
557 out(offset, segment, &c, OUT_RAWDATA, 1,
558 NO_SEG, NO_SEG);
559 offset++;
562 insn_end = offset + insn_size;
563 gencode(segment, offset, bits, instruction, codes,
564 insn_end);
565 offset += insn_size;
566 if (itimes > 0 && itimes == instruction->times - 1) {
568 * Dummy call to list->output to give the offset to the
569 * listing module.
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) {
579 size_prob = m;
581 // temp++;
584 if (temp->opcode == -1) { /* didn't match any instruction */
585 switch (size_prob) {
586 case 1:
587 error(ERR_NONFATAL, "operation size not specified");
588 break;
589 case 2:
590 error(ERR_NONFATAL, "mismatch in operand sizes");
591 break;
592 case 3:
593 error(ERR_NONFATAL, "no instruction for this cpu level");
594 break;
595 case 4:
596 error(ERR_NONFATAL, "instruction not supported in 64-bit mode");
597 break;
598 default:
599 error(ERR_NONFATAL,
600 "invalid combination of opcode and operands");
601 break;
604 return 0;
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 */
613 cpu = cp;
615 if (instruction->opcode == -1)
616 return 0;
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) {
622 extop *e;
623 int32_t isize, osize, wsize = 0; /* placate gcc */
625 isize = 0;
626 switch (instruction->opcode) {
627 case I_DB:
628 wsize = 1;
629 break;
630 case I_DW:
631 wsize = 2;
632 break;
633 case I_DD:
634 wsize = 4;
635 break;
636 case I_DQ:
637 wsize = 8;
638 break;
639 case I_DT:
640 wsize = 10;
641 break;
642 case I_DO:
643 wsize = 16;
644 break;
645 case I_DY:
646 wsize = 32;
647 break;
648 default:
649 break;
652 for (e = instruction->eops; e; e = e->next) {
653 int32_t align;
655 osize = 0;
656 if (e->type == EOT_DB_NUMBER)
657 osize = 1;
658 else if (e->type == EOT_DB_STRING ||
659 e->type == EOT_DB_STRING_FREE)
660 osize = e->stringlen;
662 align = (-osize) % wsize;
663 if (align < 0)
664 align += wsize;
665 isize += osize + align;
667 return isize * instruction->times;
670 if (instruction->opcode == I_INCBIN) {
671 const char *fname = instruction->eops->stringval;
672 FILE *fp;
673 size_t len;
675 fp = fopen(fname, "rb");
676 if (!fp)
677 error(ERR_NONFATAL, "`incbin': unable to open file `%s'",
678 fname);
679 else if (fseek(fp, 0L, SEEK_END) < 0)
680 error(ERR_NONFATAL, "`incbin': unable to seek on file `%s'",
681 fname);
682 else {
683 len = ftell(fp);
684 fclose(fp);
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);
702 if (m == 99)
703 m += jmp_match(segment, offset, bits, instruction, temp->code);
705 if (m == 100) {
706 /* we've matched an instruction. */
707 int64_t isize;
708 const uint8_t *codes = temp->code;
709 int j;
711 isize = calcsize(segment, offset, bits, instruction, codes);
712 if (isize < 0)
713 return -1;
714 for (j = 0; j < MAXPREFIX; j++) {
715 switch (instruction->prefixes[j]) {
716 case P_A16:
717 if (bits != 16)
718 isize++;
719 break;
720 case P_A32:
721 if (bits != 32)
722 isize++;
723 break;
724 case P_O16:
725 if (bits != 16)
726 isize++;
727 break;
728 case P_O32:
729 if (bits == 16)
730 isize++;
731 break;
732 case P_A64:
733 case P_O64:
734 case P_none:
735 break;
736 default:
737 isize++;
738 break;
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) &&
750 optimizing >= 0 &&
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)
758 int16_t v;
760 if (!possible_sbyte(ins, op))
761 return false;
763 v = ins->oprs[op].offset;
764 return v >= -128 && v <= 127;
767 static bool is_sbyte32(insn * ins, int op)
769 int32_t v;
771 if (!possible_sbyte(ins, op))
772 return false;
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)
782 int64_t v64;
783 int32_t v32;
785 /* dead in the water on forward reference or External */
786 if (!possible_sbyte(ins, op))
787 return false;
789 v64 = ins->oprs[op].offset;
790 v32 = (int32_t)v64;
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)
799 int64_t length = 0;
800 uint8_t c;
801 int rex_mask = ~0;
802 struct operand *opx;
804 ins->rex = 0; /* Ensure REX is reset */
806 if (ins->prefixes[PPS_OSIZE] == P_O64)
807 ins->rex |= REX_W;
809 (void)segment; /* Don't warn that this parameter is unused */
810 (void)offset; /* Don't warn that this parameter is unused */
812 while (*codes) {
813 c = *codes++;
814 opx = &ins->oprs[c & 3];
815 switch (c) {
816 case 01:
817 case 02:
818 case 03:
819 codes += c, length += c;
820 break;
821 case 04:
822 case 05:
823 case 06:
824 case 07:
825 length++;
826 break;
827 case 010:
828 case 011:
829 case 012:
830 case 013:
831 ins->rex |=
832 op_rexflags(opx, REX_B|REX_H|REX_P|REX_W);
833 codes++, length++;
834 break;
835 case 014:
836 case 015:
837 case 016:
838 case 017:
839 length++;
840 break;
841 case 020:
842 case 021:
843 case 022:
844 case 023:
845 length++;
846 break;
847 case 024:
848 case 025:
849 case 026:
850 case 027:
851 length++;
852 break;
853 case 030:
854 case 031:
855 case 032:
856 case 033:
857 length += 2;
858 break;
859 case 034:
860 case 035:
861 case 036:
862 case 037:
863 if (opx->type & (BITS16 | BITS32 | BITS64))
864 length += (opx->type & BITS16) ? 2 : 4;
865 else
866 length += (bits == 16) ? 2 : 4;
867 break;
868 case 040:
869 case 041:
870 case 042:
871 case 043:
872 length += 4;
873 break;
874 case 044:
875 case 045:
876 case 046:
877 case 047:
878 length += ins->addr_size >> 3;
879 break;
880 case 050:
881 case 051:
882 case 052:
883 case 053:
884 length++;
885 break;
886 case 054:
887 case 055:
888 case 056:
889 case 057:
890 length += 8; /* MOV reg64/imm */
891 break;
892 case 060:
893 case 061:
894 case 062:
895 case 063:
896 length += 2;
897 break;
898 case 064:
899 case 065:
900 case 066:
901 case 067:
902 if (opx->type & (BITS16 | BITS32 | BITS64))
903 length += (opx->type & BITS16) ? 2 : 4;
904 else
905 length += (bits == 16) ? 2 : 4;
906 break;
907 case 070:
908 case 071:
909 case 072:
910 case 073:
911 length += 4;
912 break;
913 case 074:
914 case 075:
915 case 076:
916 case 077:
917 length += 2;
918 break;
919 case 0140:
920 case 0141:
921 case 0142:
922 case 0143:
923 length += is_sbyte16(ins, c & 3) ? 1 : 2;
924 break;
925 case 0144:
926 case 0145:
927 case 0146:
928 case 0147:
929 codes++;
930 length++;
931 break;
932 case 0150:
933 case 0151:
934 case 0152:
935 case 0153:
936 length += is_sbyte32(ins, c & 3) ? 1 : 4;
937 break;
938 case 0154:
939 case 0155:
940 case 0156:
941 case 0157:
942 codes++;
943 length++;
944 break;
945 case 0160:
946 case 0161:
947 case 0162:
948 case 0163:
949 length++;
950 ins->rex |= REX_D;
951 ins->drexdst = regval(opx);
952 break;
953 case 0164:
954 case 0165:
955 case 0166:
956 case 0167:
957 length++;
958 ins->rex |= REX_D|REX_OC;
959 ins->drexdst = regval(opx);
960 break;
961 case 0171:
962 break;
963 case 0172:
964 case 0173:
965 case 0174:
966 codes++;
967 length++;
968 break;
969 case 0250:
970 case 0251:
971 case 0252:
972 case 0253:
973 length += is_sbyte64(ins, c & 3) ? 1 : 4;
974 break;
975 case 0260:
976 case 0261:
977 case 0262:
978 case 0263:
979 length += 2;
980 ins->rex |= REX_V;
981 ins->drexdst = regval(opx);
982 ins->vex_m = *codes++;
983 ins->vex_wlp = *codes++;
984 break;
985 case 0270:
986 length += 2;
987 ins->rex |= REX_V;
988 ins->drexdst = 0;
989 ins->vex_m = *codes++;
990 ins->vex_wlp = *codes++;
991 break;
992 case 0300:
993 case 0301:
994 case 0302:
995 case 0303:
996 break;
997 case 0310:
998 if (bits == 64)
999 return -1;
1000 length += (bits != 16) && !has_prefix(ins, PPS_ASIZE, P_A16);
1001 break;
1002 case 0311:
1003 length += (bits != 32) && !has_prefix(ins, PPS_ASIZE, P_A32);
1004 break;
1005 case 0312:
1006 break;
1007 case 0313:
1008 if (bits != 64 || has_prefix(ins, PPS_ASIZE, P_A16) ||
1009 has_prefix(ins, PPS_ASIZE, P_A32))
1010 return -1;
1011 break;
1012 case 0314:
1013 case 0315:
1014 case 0316:
1015 case 0317:
1016 break;
1017 case 0320:
1018 length += (bits != 16);
1019 break;
1020 case 0321:
1021 length += (bits == 16);
1022 break;
1023 case 0322:
1024 break;
1025 case 0323:
1026 rex_mask &= ~REX_W;
1027 break;
1028 case 0324:
1029 ins->rex |= REX_W;
1030 break;
1031 case 0330:
1032 codes++, length++;
1033 break;
1034 case 0331:
1035 break;
1036 case 0332:
1037 case 0333:
1038 length++;
1039 break;
1040 case 0334:
1041 ins->rex |= REX_L;
1042 break;
1043 case 0335:
1044 break;
1045 case 0340:
1046 if (ins->oprs[0].segment != NO_SEG)
1047 errfunc(ERR_NONFATAL, "attempt to reserve non-constant"
1048 " quantity of BSS space");
1049 else
1050 length += ins->oprs[0].offset;
1051 break;
1052 case 0360:
1053 break;
1054 case 0361:
1055 case 0362:
1056 case 0363:
1057 length++;
1058 break;
1059 case 0364:
1060 case 0365:
1061 break;
1062 case 0366:
1063 case 0367:
1064 length++;
1065 break;
1066 case 0370:
1067 case 0371:
1068 case 0372:
1069 break;
1070 case 0373:
1071 length++;
1072 break;
1073 default: /* can't do it by 'case' statements */
1074 if (c >= 0100 && c <= 0277) { /* it's an EA */
1075 ea ea_data;
1076 int rfield;
1077 int32_t rflags;
1078 ea_data.rex = 0; /* Ensure ea.REX is initially 0 */
1080 if (c <= 0177) {
1081 /* pick rfield from operand b */
1082 rflags = regflag(&ins->oprs[c & 7]);
1083 rfield = nasm_regvals[ins->oprs[c & 7].basereg];
1084 } else {
1085 rflags = 0;
1086 rfield = c & 7;
1089 if (!process_ea
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");
1093 return -1;
1094 } else {
1095 ins->rex |= ea_data.rex;
1096 length += ea_data.size;
1098 } else {
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");
1112 return -1;
1114 switch (ins->vex_wlp & 030) {
1115 case 000:
1116 case 020:
1117 ins->rex &= ~REX_W;
1118 break;
1119 case 010:
1120 ins->rex |= REX_W;
1121 bad32 &= ~REX_W;
1122 break;
1123 case 030:
1124 /* Follow REX_W */
1125 break;
1128 if (bits != 64 && ((ins->rex & bad32) || ins->drexdst > 7)) {
1129 errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode");
1130 return -1;
1132 if (ins->vex_m != 1 || (ins->rex & (REX_W|REX_R|REX_B)))
1133 length += 3;
1134 else
1135 length += 2;
1136 } else if (ins->rex & REX_D) {
1137 if (ins->rex & REX_H) {
1138 errfunc(ERR_NONFATAL, "cannot use high register in drex instruction");
1139 return -1;
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");
1144 return -1;
1146 length++;
1147 } else if (ins->rex & REX_REAL) {
1148 if (ins->rex & REX_H) {
1149 errfunc(ERR_NONFATAL, "cannot use high register in rex instruction");
1150 return -1;
1151 } else if (bits == 64) {
1152 length++;
1153 } else if ((ins->rex & REX_L) &&
1154 !(ins->rex & (REX_P|REX_W|REX_X|REX_B)) &&
1155 cpu >= IF_X86_64) {
1156 /* LOCK-as-REX.R */
1157 assert_no_prefix(ins, PPS_LREP);
1158 length++;
1159 } else {
1160 errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode");
1161 return -1;
1165 return length;
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); \
1172 ins->rex = 0; \
1173 offset += 1; \
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
1184 uint8_t c;
1185 uint8_t bytes[4];
1186 int64_t size;
1187 int64_t data;
1188 struct operand *opx;
1190 while (*codes) {
1191 c = *codes++;
1192 opx = &ins->oprs[c & 3];
1193 switch (c) {
1194 case 01:
1195 case 02:
1196 case 03:
1197 EMIT_REX();
1198 out(offset, segment, codes, OUT_RAWDATA, c, NO_SEG, NO_SEG);
1199 codes += c;
1200 offset += c;
1201 break;
1203 case 04:
1204 case 06:
1205 switch (ins->oprs[0].basereg) {
1206 case R_CS:
1207 bytes[0] = 0x0E + (c == 0x04 ? 1 : 0);
1208 break;
1209 case R_DS:
1210 bytes[0] = 0x1E + (c == 0x04 ? 1 : 0);
1211 break;
1212 case R_ES:
1213 bytes[0] = 0x06 + (c == 0x04 ? 1 : 0);
1214 break;
1215 case R_SS:
1216 bytes[0] = 0x16 + (c == 0x04 ? 1 : 0);
1217 break;
1218 default:
1219 errfunc(ERR_PANIC,
1220 "bizarre 8086 segment register received");
1222 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1223 offset++;
1224 break;
1226 case 05:
1227 case 07:
1228 switch (ins->oprs[0].basereg) {
1229 case R_FS:
1230 bytes[0] = 0xA0 + (c == 0x05 ? 1 : 0);
1231 break;
1232 case R_GS:
1233 bytes[0] = 0xA8 + (c == 0x05 ? 1 : 0);
1234 break;
1235 default:
1236 errfunc(ERR_PANIC,
1237 "bizarre 386 segment register received");
1239 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1240 offset++;
1241 break;
1243 case 010:
1244 case 011:
1245 case 012:
1246 case 013:
1247 EMIT_REX();
1248 bytes[0] = *codes++ + ((regval(opx)) & 7);
1249 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1250 offset += 1;
1251 break;
1253 case 014:
1254 case 015:
1255 case 016:
1256 case 017:
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) {
1264 data = opx->offset;
1265 out(offset, segment, &data, OUT_ADDRESS, 1,
1266 opx->segment, opx->wrt);
1267 } else {
1268 bytes[0] = opx->offset;
1269 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1270 NO_SEG);
1272 offset += 1;
1273 break;
1275 case 020:
1276 case 021:
1277 case 022:
1278 case 023:
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) {
1284 data = opx->offset;
1285 out(offset, segment, &data, OUT_ADDRESS, 1,
1286 opx->segment, opx->wrt);
1287 } else {
1288 bytes[0] = opx->offset;
1289 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1290 NO_SEG);
1292 offset += 1;
1293 break;
1295 case 024:
1296 case 025:
1297 case 026:
1298 case 027:
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) {
1303 data = opx->offset;
1304 out(offset, segment, &data, OUT_ADDRESS, 1,
1305 opx->segment, opx->wrt);
1306 } else {
1307 bytes[0] = opx->offset;
1308 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1309 NO_SEG);
1311 offset += 1;
1312 break;
1314 case 030:
1315 case 031:
1316 case 032:
1317 case 033:
1318 data = opx->offset;
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);
1323 offset += 2;
1324 break;
1326 case 034:
1327 case 035:
1328 case 036:
1329 case 037:
1330 if (opx->type & (BITS16 | BITS32))
1331 size = (opx->type & BITS16) ? 2 : 4;
1332 else
1333 size = (bits == 16) ? 2 : 4;
1334 data = opx->offset;
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);
1339 offset += size;
1340 break;
1342 case 040:
1343 case 041:
1344 case 042:
1345 case 043:
1346 data = opx->offset;
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);
1351 offset += 4;
1352 break;
1354 case 044:
1355 case 045:
1356 case 046:
1357 case 047:
1358 data = opx->offset;
1359 size = ins->addr_size >> 3;
1360 if (opx->segment == NO_SEG &&
1361 opx->wrt == NO_SEG)
1362 warn_overflow(size, data);
1363 out(offset, segment, &data, OUT_ADDRESS, size,
1364 opx->segment, opx->wrt);
1365 offset += size;
1366 break;
1368 case 050:
1369 case 051:
1370 case 052:
1371 case 053:
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");
1378 bytes[0] = data;
1379 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1380 offset += 1;
1381 break;
1383 case 054:
1384 case 055:
1385 case 056:
1386 case 057:
1387 data = (int64_t)opx->offset;
1388 out(offset, segment, &data, OUT_ADDRESS, 8,
1389 opx->segment, opx->wrt);
1390 offset += 8;
1391 break;
1393 case 060:
1394 case 061:
1395 case 062:
1396 case 063:
1397 if (opx->segment != segment) {
1398 data = opx->offset;
1399 out(offset, segment, &data,
1400 OUT_REL2ADR, insn_end - offset,
1401 opx->segment, opx->wrt);
1402 } else {
1403 data = opx->offset - insn_end;
1404 out(offset, segment, &data,
1405 OUT_ADDRESS, 2, NO_SEG, NO_SEG);
1407 offset += 2;
1408 break;
1410 case 064:
1411 case 065:
1412 case 066:
1413 case 067:
1414 if (opx->type & (BITS16 | BITS32 | BITS64))
1415 size = (opx->type & BITS16) ? 2 : 4;
1416 else
1417 size = (bits == 16) ? 2 : 4;
1418 if (opx->segment != segment) {
1419 data = opx->offset;
1420 out(offset, segment, &data,
1421 size == 2 ? OUT_REL2ADR : OUT_REL4ADR,
1422 insn_end - offset, opx->segment, opx->wrt);
1423 } else {
1424 data = opx->offset - insn_end;
1425 out(offset, segment, &data,
1426 OUT_ADDRESS, size, NO_SEG, NO_SEG);
1428 offset += size;
1429 break;
1431 case 070:
1432 case 071:
1433 case 072:
1434 case 073:
1435 if (opx->segment != segment) {
1436 data = opx->offset;
1437 out(offset, segment, &data,
1438 OUT_REL4ADR, insn_end - offset,
1439 opx->segment, opx->wrt);
1440 } else {
1441 data = opx->offset - insn_end;
1442 out(offset, segment, &data,
1443 OUT_ADDRESS, 4, NO_SEG, NO_SEG);
1445 offset += 4;
1446 break;
1448 case 074:
1449 case 075:
1450 case 076:
1451 case 077:
1452 if (opx->segment == NO_SEG)
1453 errfunc(ERR_NONFATAL, "value referenced by FAR is not"
1454 " relocatable");
1455 data = 0;
1456 out(offset, segment, &data, OUT_ADDRESS, 2,
1457 outfmt->segbase(1 + opx->segment),
1458 opx->wrt);
1459 offset += 2;
1460 break;
1462 case 0140:
1463 case 0141:
1464 case 0142:
1465 case 0143:
1466 data = opx->offset;
1467 if (is_sbyte16(ins, c & 3)) {
1468 bytes[0] = data;
1469 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1470 NO_SEG);
1471 offset++;
1472 } else {
1473 if (opx->segment == NO_SEG &&
1474 opx->wrt == NO_SEG)
1475 warn_overflow(2, data);
1476 out(offset, segment, &data, OUT_ADDRESS, 2,
1477 opx->segment, opx->wrt);
1478 offset += 2;
1480 break;
1482 case 0144:
1483 case 0145:
1484 case 0146:
1485 case 0147:
1486 EMIT_REX();
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);
1491 offset++;
1492 break;
1494 case 0150:
1495 case 0151:
1496 case 0152:
1497 case 0153:
1498 data = opx->offset;
1499 if (is_sbyte32(ins, c & 3)) {
1500 bytes[0] = data;
1501 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1502 NO_SEG);
1503 offset++;
1504 } else {
1505 out(offset, segment, &data, OUT_ADDRESS, 4,
1506 opx->segment, opx->wrt);
1507 offset += 4;
1509 break;
1511 case 0154:
1512 case 0155:
1513 case 0156:
1514 case 0157:
1515 EMIT_REX();
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);
1520 offset++;
1521 break;
1523 case 0160:
1524 case 0161:
1525 case 0162:
1526 case 0163:
1527 case 0164:
1528 case 0165:
1529 case 0166:
1530 case 0167:
1531 break;
1533 case 0171:
1534 bytes[0] =
1535 (ins->drexdst << 4) |
1536 (ins->rex & REX_OC ? 0x08 : 0) |
1537 (ins->rex & (REX_R|REX_X|REX_B));
1538 ins->rex = 0;
1539 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1540 offset++;
1541 break;
1543 case 0172:
1544 c = *codes++;
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",
1551 c & 7);
1552 } else {
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);
1560 offset++;
1561 break;
1563 case 0173:
1564 c = *codes++;
1565 opx = &ins->oprs[c >> 4];
1566 bytes[0] = nasm_regvals[opx->basereg] << 4;
1567 bytes[0] |= c & 15;
1568 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1569 offset++;
1570 break;
1572 case 0174:
1573 c = *codes++;
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);
1577 offset++;
1578 break;
1580 case 0250:
1581 case 0251:
1582 case 0252:
1583 case 0253:
1584 data = opx->offset;
1585 /* is_sbyte32() is right here, we have already warned */
1586 if (is_sbyte32(ins, c & 3)) {
1587 bytes[0] = data;
1588 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1589 NO_SEG);
1590 offset++;
1591 } else {
1592 out(offset, segment, &data, OUT_ADDRESS, 4,
1593 opx->segment, opx->wrt);
1594 offset += 4;
1596 break;
1598 case 0260:
1599 case 0261:
1600 case 0262:
1601 case 0263:
1602 case 0270:
1603 codes += 2;
1604 if (ins->vex_m != 1 || (ins->rex & (REX_W|REX_X|REX_B))) {
1605 bytes[0] = 0xc4;
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);
1610 offset += 3;
1611 } else {
1612 bytes[0] = 0xc5;
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);
1616 offset += 2;
1618 break;
1620 case 0300:
1621 case 0301:
1622 case 0302:
1623 case 0303:
1624 break;
1626 case 0310:
1627 if (bits == 32 && !has_prefix(ins, PPS_ASIZE, P_A16)) {
1628 *bytes = 0x67;
1629 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1630 offset += 1;
1631 } else
1632 offset += 0;
1633 break;
1635 case 0311:
1636 if (bits != 32 && !has_prefix(ins, PPS_ASIZE, P_A32)) {
1637 *bytes = 0x67;
1638 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1639 offset += 1;
1640 } else
1641 offset += 0;
1642 break;
1644 case 0312:
1645 break;
1647 case 0313:
1648 ins->rex = 0;
1649 break;
1651 case 0314:
1652 case 0315:
1653 case 0316:
1654 case 0317:
1655 break;
1657 case 0320:
1658 if (bits != 16) {
1659 *bytes = 0x66;
1660 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1661 offset += 1;
1662 } else
1663 offset += 0;
1664 break;
1666 case 0321:
1667 if (bits == 16) {
1668 *bytes = 0x66;
1669 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1670 offset += 1;
1671 } else
1672 offset += 0;
1673 break;
1675 case 0322:
1676 case 0323:
1677 break;
1679 case 0324:
1680 ins->rex |= REX_W;
1681 break;
1683 case 0330:
1684 *bytes = *codes++ ^ condval[ins->condition];
1685 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1686 offset += 1;
1687 break;
1689 case 0331:
1690 break;
1692 case 0332:
1693 case 0333:
1694 *bytes = c - 0332 + 0xF2;
1695 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1696 offset += 1;
1697 break;
1699 case 0334:
1700 if (ins->rex & REX_R) {
1701 *bytes = 0xF0;
1702 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1703 offset += 1;
1705 ins->rex &= ~(REX_L|REX_R);
1706 break;
1708 case 0335:
1709 break;
1711 case 0340:
1712 if (ins->oprs[0].segment != NO_SEG)
1713 errfunc(ERR_PANIC, "non-constant BSS size in pass two");
1714 else {
1715 int64_t size = ins->oprs[0].offset;
1716 if (size > 0)
1717 out(offset, segment, NULL,
1718 OUT_RESERVE, size, NO_SEG, NO_SEG);
1719 offset += size;
1721 break;
1723 case 0360:
1724 break;
1726 case 0361:
1727 bytes[0] = 0x66;
1728 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1729 offset += 1;
1730 break;
1732 case 0362:
1733 case 0363:
1734 bytes[0] = c - 0362 + 0xf2;
1735 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1736 offset += 1;
1737 break;
1739 case 0364:
1740 case 0365:
1741 break;
1743 case 0366:
1744 case 0367:
1745 *bytes = c - 0366 + 0x66;
1746 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1747 offset += 1;
1748 break;
1750 case 0370:
1751 case 0371:
1752 case 0372:
1753 break;
1755 case 0373:
1756 *bytes = bits == 16 ? 3 : 5;
1757 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1758 offset += 1;
1759 break;
1761 default: /* can't do it by 'case' statements */
1762 if (c >= 0100 && c <= 0277) { /* it's an EA */
1763 ea ea_data;
1764 int rfield;
1765 int32_t rflags;
1766 uint8_t *p;
1767 int32_t s;
1769 if (c <= 0177) {
1770 /* pick rfield from operand b */
1771 rflags = regflag(&ins->oprs[c & 7]);
1772 rfield = nasm_regvals[ins->oprs[c & 7].basereg];
1773 } else {
1774 /* rfield is constant */
1775 rflags = 0;
1776 rfield = c & 7;
1779 if (!process_ea
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");
1786 p = bytes;
1787 *p++ = ea_data.modrm;
1788 if (ea_data.sib_present)
1789 *p++ = ea_data.sib;
1791 /* DREX suffixes come between the SIB and the displacement */
1792 if (ins->rex & REX_D) {
1793 *p++ =
1794 (ins->drexdst << 4) |
1795 (ins->rex & REX_OC ? 0x08 : 0) |
1796 (ins->rex & (REX_R|REX_X|REX_B));
1797 ins->rex = 0;
1800 s = p - bytes;
1801 out(offset, segment, bytes, OUT_RAWDATA, s, NO_SEG, NO_SEG);
1803 switch (ea_data.bytes) {
1804 case 0:
1805 break;
1806 case 1:
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);
1812 } else {
1813 *bytes = ins->oprs[(c >> 3) & 7].offset;
1814 out(offset, segment, bytes, OUT_RAWDATA, 1,
1815 NO_SEG, NO_SEG);
1817 s++;
1818 break;
1819 case 8:
1820 case 2:
1821 case 4:
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,
1826 ea_data.bytes,
1827 ins->oprs[(c >> 3) & 7].segment,
1828 ins->oprs[(c >> 3) & 7].wrt);
1829 s += ea_data.bytes;
1830 break;
1832 offset += s;
1833 } else {
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)
1859 int32_t flags;
1860 int val;
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)
1874 int rex = 0;
1876 if (val >= 8)
1877 rex |= REX_B|REX_X|REX_R;
1878 if (flags & BITS64)
1879 rex |= REX_W;
1880 if (!(REG_HIGH & ~flags)) /* AH, CH, DH, BH */
1881 rex |= REX_H;
1882 else if (!(REG8 & ~flags) && val >= 4) /* SPL, BPL, SIL, DIL */
1883 rex |= REX_P;
1885 return rex & mask;
1888 static int matches(const struct itemplate *itemp, insn * instruction, int bits)
1890 int i, size[MAX_OPERANDS], asize, oprs, ret;
1892 ret = 100;
1895 * Check the opcode
1897 if (itemp->opcode != instruction->opcode)
1898 return 0;
1901 * Count the operands
1903 if (itemp->operands != instruction->operands)
1904 return 0;
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))
1911 return 0;
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) {
1922 case IF_SB:
1923 size[i] = BITS8;
1924 break;
1925 case IF_SW:
1926 size[i] = BITS16;
1927 break;
1928 case IF_SD:
1929 size[i] = BITS32;
1930 break;
1931 case IF_SQ:
1932 size[i] = BITS64;
1933 break;
1934 case IF_SO:
1935 size[i] = BITS128;
1936 break;
1937 case IF_SY:
1938 size[i] = BITS256;
1939 break;
1940 case IF_SZ:
1941 switch (bits) {
1942 case 16:
1943 size[i] = BITS16;
1944 break;
1945 case 32:
1946 size[i] = BITS32;
1947 break;
1948 case 64:
1949 size[i] = BITS64;
1950 break;
1952 break;
1953 default:
1954 break;
1956 } else {
1957 asize = 0;
1958 switch (itemp->flags & IF_SMASK) {
1959 case IF_SB:
1960 asize = BITS8;
1961 break;
1962 case IF_SW:
1963 asize = BITS16;
1964 break;
1965 case IF_SD:
1966 asize = BITS32;
1967 break;
1968 case IF_SQ:
1969 asize = BITS64;
1970 break;
1971 case IF_SO:
1972 asize = BITS128;
1973 break;
1974 case IF_SY:
1975 asize = BITS256;
1976 break;
1977 case IF_SZ:
1978 switch (bits) {
1979 case 16:
1980 asize = BITS16;
1981 break;
1982 case 32:
1983 asize = BITS32;
1984 break;
1985 case 64:
1986 asize = BITS64;
1987 break;
1989 break;
1990 default:
1991 break;
1993 for (i = 0; i < MAX_OPERANDS; i++)
1994 size[i] = asize;
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))
2003 type |= size[i];
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)
2009 return 0;
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) ||
2014 (type & SIZE_MASK))
2015 return 0;
2016 else
2017 return 1;
2022 * Check operand sizes
2024 if (itemp->flags & (IF_SM | IF_SM2)) {
2025 oprs = (itemp->flags & IF_SM2 ? 2 : itemp->operands);
2026 asize = 0;
2027 for (i = 0; i < oprs; i++) {
2028 if ((asize = itemp->opd[i] & SIZE_MASK) != 0) {
2029 int j;
2030 for (j = 0; j < oprs; j++)
2031 size[j] = asize;
2032 break;
2035 } else {
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]))
2042 return 2;
2046 * Check template is okay at the set cpu level
2048 if (((itemp->flags & IF_PLEVEL) > cpu))
2049 return 3;
2052 * Check if instruction is available in long mode
2054 if ((itemp->flags & IF_NOLONG) && (bits == 64))
2055 return 4;
2058 * Check if special handling needed for Jumps
2060 if ((uint8_t)(itemp->code[0]) >= 0370)
2061 return 99;
2063 return ret;
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 */
2075 int i;
2076 int32_t f;
2078 if (input->basereg < EXPR_REG_START /* Verify as Register */
2079 || input->basereg >= REG_ENUM_LIMIT)
2080 return NULL;
2081 f = regflag(input);
2082 i = nasm_regvals[input->basereg];
2084 if (REG_EA & ~f)
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;
2099 scale = 0;
2100 index = 4;
2101 base = 5;
2102 output->sib = (scale << 6) | (index << 3) | base;
2103 output->bytes = 4;
2104 output->modrm = 4 | ((rfield & 7) << 3);
2105 output->rip = false;
2106 } else {
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;
2116 int t;
2117 int it, bt;
2118 int32_t ix, bx; /* register flags */
2120 if (s == 0)
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];
2126 } else {
2127 it = -1;
2128 ix = 0;
2131 if (b >= EXPR_REG_START && b < REG_ENUM_LIMIT) {
2132 bt = nasm_regvals[b];
2133 bx = nasm_reg_flags[b];
2134 } else {
2135 bt = -1;
2136 bx = 0;
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;
2145 if (it != -1) {
2146 if (!(REG64 & ~ix) || !(REG32 & ~ix))
2147 sok &= ix;
2148 else
2149 return NULL;
2152 if (bt != -1) {
2153 if (REG_GPR & ~bx)
2154 return NULL; /* Invalid register */
2155 if (~sok & bx & SIZE_MASK)
2156 return NULL; /* Invalid size */
2157 sok &= bx;
2160 /* While we're here, ensure the user didn't specify
2161 WORD or QWORD. */
2162 if (input->disp_size == 16 || input->disp_size == 64)
2163 return NULL;
2165 if (addrbits == 16 ||
2166 (addrbits == 32 && !(sok & BITS32)) ||
2167 (addrbits == 64 && !(sok & BITS64)))
2168 return NULL;
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) {
2205 /* no SIB needed */
2206 int mod, rm;
2208 if (bt == -1) {
2209 rm = 5;
2210 mod = 0;
2211 } else {
2212 rm = (bt & 7);
2213 if (rm != REG_NUM_EBP && o == 0 &&
2214 seg == NO_SEG && !forw_ref &&
2215 !(input->eaflags &
2216 (EAF_BYTEOFFS | EAF_WORDOFFS)))
2217 mod = 0;
2218 else if (input->eaflags & EAF_BYTEOFFS ||
2219 (o >= -128 && o <= 127 && seg == NO_SEG
2220 && !forw_ref
2221 && !(input->eaflags & EAF_WORDOFFS)))
2222 mod = 1;
2223 else
2224 mod = 2;
2227 output->sib_present = false;
2228 output->bytes = (bt == -1 || mod == 2 ? 4 : mod);
2229 output->modrm = (mod << 6) | ((rfield & 7) << 3) | rm;
2230 } else {
2231 /* we need a SIB */
2232 int mod, scale, index, base;
2234 if (it == -1)
2235 index = 4, s = 1;
2236 else
2237 index = (it & 7);
2239 switch (s) {
2240 case 1:
2241 scale = 0;
2242 break;
2243 case 2:
2244 scale = 1;
2245 break;
2246 case 4:
2247 scale = 2;
2248 break;
2249 case 8:
2250 scale = 3;
2251 break;
2252 default: /* then what the smeg is it? */
2253 return NULL; /* panic */
2256 if (bt == -1) {
2257 base = 5;
2258 mod = 0;
2259 } else {
2260 base = (bt & 7);
2261 if (base != REG_NUM_EBP && o == 0 &&
2262 seg == NO_SEG && !forw_ref &&
2263 !(input->eaflags &
2264 (EAF_BYTEOFFS | EAF_WORDOFFS)))
2265 mod = 0;
2266 else if (input->eaflags & EAF_BYTEOFFS ||
2267 (o >= -128 && o <= 127 && seg == NO_SEG
2268 && !forw_ref
2269 && !(input->eaflags & EAF_WORDOFFS)))
2270 mod = 1;
2271 else
2272 mod = 2;
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 */
2281 int mod, rm;
2283 /* check for 64-bit long mode */
2284 if (addrbits == 64)
2285 return NULL;
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))
2291 return NULL;
2293 /* ensure the user didn't specify DWORD/QWORD */
2294 if (input->disp_size == 32 || input->disp_size == 64)
2295 return NULL;
2297 if (s != 1 && i != -1)
2298 return NULL; /* no can do, in 16-bit EA */
2299 if (b == -1 && i != -1) {
2300 int tmp = b;
2301 b = i;
2302 i = tmp;
2303 } /* swap */
2304 if ((b == R_SI || b == R_DI) && i != -1) {
2305 int tmp = b;
2306 b = i;
2307 i = tmp;
2309 /* have BX/BP as base, SI/DI index */
2310 if (b == i)
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! */
2318 rm = -1;
2319 if (i != -1)
2320 switch (i * 256 + b) {
2321 case R_SI * 256 + R_BX:
2322 rm = 0;
2323 break;
2324 case R_DI * 256 + R_BX:
2325 rm = 1;
2326 break;
2327 case R_SI * 256 + R_BP:
2328 rm = 2;
2329 break;
2330 case R_DI * 256 + R_BP:
2331 rm = 3;
2332 break;
2333 } else
2334 switch (b) {
2335 case R_SI:
2336 rm = 4;
2337 break;
2338 case R_DI:
2339 rm = 5;
2340 break;
2341 case R_BP:
2342 rm = 6;
2343 break;
2344 case R_BX:
2345 rm = 7;
2346 break;
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)))
2353 mod = 0;
2354 else if (input->eaflags & EAF_BYTEOFFS ||
2355 (o >= -128 && o <= 127 && seg == NO_SEG
2356 && !forw_ref
2357 && !(input->eaflags & EAF_WORDOFFS)))
2358 mod = 1;
2359 else
2360 mod = 2;
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;
2370 return output;
2373 static void add_asp(insn *ins, int addrbits)
2375 int j, valid;
2376 int defdisp;
2378 valid = (addrbits == 64) ? 64|32 : 32|16;
2380 switch (ins->prefixes[PPS_ASIZE]) {
2381 case P_A16:
2382 valid &= 16;
2383 break;
2384 case P_A32:
2385 valid &= 32;
2386 break;
2387 case P_A64:
2388 valid &= 64;
2389 break;
2390 case P_ASP:
2391 valid &= (addrbits == 32) ? 16 : 32;
2392 break;
2393 default:
2394 break;
2397 for (j = 0; j < ins->operands; j++) {
2398 if (!(MEMORY & ~ins->oprs[j].type)) {
2399 int32_t i, b;
2401 /* Verify as Register */
2402 if (ins->oprs[j].indexreg < EXPR_REG_START
2403 || ins->oprs[j].indexreg >= REG_ENUM_LIMIT)
2404 i = 0;
2405 else
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)
2411 b = 0;
2412 else
2413 b = nasm_reg_flags[ins->oprs[j].basereg];
2415 if (ins->oprs[j].scale == 0)
2416 i = 0;
2418 if (!i && !b) {
2419 int ds = ins->oprs[j].disp_size;
2420 if ((addrbits != 64 && ds > 8) ||
2421 (addrbits == 64 && ds == 16))
2422 valid &= ds;
2423 } else {
2424 if (!(REG16 & ~b))
2425 valid &= 16;
2426 if (!(REG32 & ~b))
2427 valid &= 32;
2428 if (!(REG64 & ~b))
2429 valid &= 64;
2431 if (!(REG16 & ~i))
2432 valid &= 16;
2433 if (!(REG32 & ~i))
2434 valid &= 32;
2435 if (!(REG64 & ~i))
2436 valid &= 64;
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;
2448 } else {
2449 /* Impossible... */
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);