rdx: Add cast avoid warning from gcc
[nasm/perl-rewrite.git] / assemble.c
blob0397f5df72d6993d8370c7c127a5f11906241d4a
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 0..3.
50 * \173\xab - the register number from operand a in bits 7..4, with
51 * the value b in bits 0..3.
52 * \2ab - a ModRM, calculated on EA in operand a, with the spare
53 * field equal to digit b.
54 * \250..\253 - same as \150..\153, except warn if the 64-bit operand
55 * is not equal to the truncated and sign-extended 32-bit
56 * operand; used for 32-bit immediates in 64-bit mode.
57 * \260..\263 - this instruction uses VEX rather than REX, with the
58 * V field taken from operand 0..3.
59 * \270 - this instruction uses VEX rather than REX, with the
60 * V field set to 1111b.
62 * VEX prefixes are followed by the sequence:
63 * \mm\wlp where mm is the M field; and wlp is:
64 * 00 0ww lpp
65 * ww = 0 for W = 0
66 * ww = 1 for W = 1
67 * ww = 2 for W used as REX.W
69 * \310 - indicates fixed 16-bit address size, i.e. optional 0x67.
70 * \311 - indicates fixed 32-bit address size, i.e. optional 0x67.
71 * \312 - (disassembler only) marker on LOOP, LOOPxx instructions.
72 * \313 - indicates fixed 64-bit address size, 0x67 invalid.
73 * \314 - (disassembler only) invalid with REX.B
74 * \315 - (disassembler only) invalid with REX.X
75 * \316 - (disassembler only) invalid with REX.R
76 * \317 - (disassembler only) invalid with REX.W
77 * \320 - indicates fixed 16-bit operand size, i.e. optional 0x66.
78 * \321 - indicates fixed 32-bit operand size, i.e. optional 0x66.
79 * \322 - indicates that this instruction is only valid when the
80 * operand size is the default (instruction to disassembler,
81 * generates no code in the assembler)
82 * \323 - indicates fixed 64-bit operand size, REX on extensions only.
83 * \324 - indicates 64-bit operand size requiring REX prefix.
84 * \330 - a literal byte follows in the code stream, to be added
85 * to the condition code value of the instruction.
86 * \331 - instruction not valid with REP prefix. Hint for
87 * disassembler only; for SSE instructions.
88 * \332 - REP prefix (0xF2 byte) used as opcode extension.
89 * \333 - REP prefix (0xF3 byte) used as opcode extension.
90 * \334 - LOCK prefix used instead of REX.R
91 * \335 - disassemble a rep (0xF3 byte) prefix as repe not rep.
92 * \340 - reserve <operand 0> bytes of uninitialized storage.
93 * Operand 0 had better be a segmentless constant.
94 * \360 - no SSE prefix (== \364\331)
95 * \361 - 66 SSE prefix (== \366\331)
96 * \362 - F2 SSE prefix (== \364\332)
97 * \363 - F3 SSE prefix (== \364\333)
98 * \364 - operand-size prefix (0x66) not permitted
99 * \365 - address-size prefix (0x67) not permitted
100 * \366 - operand-size prefix (0x66) used as opcode extension
101 * \367 - address-size prefix (0x67) used as opcode extension
102 * \370,\371,\372 - match only if operand 0 meets byte jump criteria.
103 * 370 is used for Jcc, 371 is used for JMP.
104 * \373 - assemble 0x03 if bits==16, 0x05 if bits==32;
105 * used for conditional jump over longer jump
108 #include "compiler.h"
110 #include <stdio.h>
111 #include <string.h>
112 #include <inttypes.h>
114 #include "nasm.h"
115 #include "nasmlib.h"
116 #include "assemble.h"
117 #include "insns.h"
118 #include "preproc.h"
119 #include "tables.h"
121 /* Initialized to zero by the C standard */
122 static const uint8_t const_zero_buf[256];
124 typedef struct {
125 int sib_present; /* is a SIB byte necessary? */
126 int bytes; /* # of bytes of offset needed */
127 int size; /* lazy - this is sib+bytes+1 */
128 uint8_t modrm, sib, rex, rip; /* the bytes themselves */
129 } ea;
131 static uint32_t cpu; /* cpu level received from nasm.c */
132 static efunc errfunc;
133 static struct ofmt *outfmt;
134 static ListGen *list;
136 static int64_t calcsize(int32_t, int64_t, int, insn *, const uint8_t *);
137 static void gencode(int32_t, int64_t, int, insn *, const uint8_t *, int64_t);
138 static int matches(const struct itemplate *, insn *, int bits);
139 static int32_t regflag(const operand *);
140 static int32_t regval(const operand *);
141 static int rexflags(int, int32_t, int);
142 static int op_rexflags(const operand *, int);
143 static ea *process_ea(operand *, ea *, int, int, int, int32_t, int);
144 static void add_asp(insn *, int);
146 static int has_prefix(insn * ins, enum prefix_pos pos, enum prefixes prefix)
148 return ins->prefixes[pos] == prefix;
151 static void assert_no_prefix(insn * ins, enum prefix_pos pos)
153 if (ins->prefixes[pos])
154 errfunc(ERR_NONFATAL, "invalid %s prefix",
155 prefix_name(ins->prefixes[pos]));
158 static const char *size_name(int size)
160 switch (size) {
161 case 1:
162 return "byte";
163 case 2:
164 return "word";
165 case 4:
166 return "dword";
167 case 8:
168 return "qword";
169 case 10:
170 return "tword";
171 case 16:
172 return "oword";
173 case 32:
174 return "yword";
175 default:
176 return "???";
180 static void warn_overflow(int size, int64_t data)
182 if (size < 8) {
183 int64_t lim = ((int64_t)1 << (size*8))-1;
185 if (data < ~lim || data > lim)
186 errfunc(ERR_WARNING | ERR_WARN_NOV,
187 "%s data exceeds bounds", size_name(size));
191 * This routine wrappers the real output format's output routine,
192 * in order to pass a copy of the data off to the listing file
193 * generator at the same time.
195 static void out(int64_t offset, int32_t segto, const void *data,
196 enum out_type type, uint64_t size,
197 int32_t segment, int32_t wrt)
199 static int32_t lineno = 0; /* static!!! */
200 static char *lnfname = NULL;
201 uint8_t p[8];
203 if (type == OUT_ADDRESS && segment == NO_SEG && wrt == NO_SEG) {
205 * This is a non-relocated address, and we're going to
206 * convert it into RAWDATA format.
208 uint8_t *q = p;
210 if (size > 8) {
211 errfunc(ERR_PANIC, "OUT_ADDRESS with size > 8");
212 return;
215 WRITEADDR(q, *(int64_t *)data, size);
216 data = p;
217 type = OUT_RAWDATA;
220 list->output(offset, data, type, size);
223 * this call to src_get determines when we call the
224 * debug-format-specific "linenum" function
225 * it updates lineno and lnfname to the current values
226 * returning 0 if "same as last time", -2 if lnfname
227 * changed, and the amount by which lineno changed,
228 * if it did. thus, these variables must be static
231 if (src_get(&lineno, &lnfname)) {
232 outfmt->current_dfmt->linenum(lnfname, lineno, segto);
235 outfmt->output(segto, data, type, size, segment, wrt);
238 static int jmp_match(int32_t segment, int64_t offset, int bits,
239 insn * ins, const uint8_t *code)
241 int64_t isize;
242 uint8_t c = code[0];
244 if (c != 0370 && c != 0371)
245 return 0;
246 if (ins->oprs[0].opflags & OPFLAG_FORWARD) {
247 if ((optimizing < 0 || (ins->oprs[0].type & STRICT))
248 && c == 0370)
249 return 1;
250 else
251 return (pass0 == 0); /* match a forward reference */
253 isize = calcsize(segment, offset, bits, ins, code);
254 if (ins->oprs[0].segment != segment)
255 return 0;
256 isize = ins->oprs[0].offset - offset - isize; /* isize is now the delta */
257 if (isize >= -128L && isize <= 127L)
258 return 1; /* it is byte size */
260 return 0;
263 int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp,
264 insn * instruction, struct ofmt *output, efunc error,
265 ListGen * listgen)
267 const struct itemplate *temp;
268 int j;
269 int size_prob;
270 int64_t insn_end;
271 int32_t itimes;
272 int64_t start = offset;
273 int64_t wsize = 0; /* size for DB etc. */
275 errfunc = error; /* to pass to other functions */
276 cpu = cp;
277 outfmt = output; /* likewise */
278 list = listgen; /* and again */
280 switch (instruction->opcode) {
281 case -1:
282 return 0;
283 case I_DB:
284 wsize = 1;
285 break;
286 case I_DW:
287 wsize = 2;
288 break;
289 case I_DD:
290 wsize = 4;
291 break;
292 case I_DQ:
293 wsize = 8;
294 break;
295 case I_DT:
296 wsize = 10;
297 break;
298 case I_DO:
299 wsize = 16;
300 break;
301 case I_DY:
302 wsize = 32;
303 break;
304 default:
305 break;
308 if (wsize) {
309 extop *e;
310 int32_t t = instruction->times;
311 if (t < 0)
312 errfunc(ERR_PANIC,
313 "instruction->times < 0 (%ld) in assemble()", t);
315 while (t--) { /* repeat TIMES times */
316 for (e = instruction->eops; e; e = e->next) {
317 if (e->type == EOT_DB_NUMBER) {
318 if (wsize == 1) {
319 if (e->segment != NO_SEG)
320 errfunc(ERR_NONFATAL,
321 "one-byte relocation attempted");
322 else {
323 uint8_t out_byte = e->offset;
324 out(offset, segment, &out_byte,
325 OUT_RAWDATA, 1, NO_SEG, NO_SEG);
327 } else if (wsize > 8) {
328 errfunc(ERR_NONFATAL, "integer supplied to a DT, DO or DY"
329 " instruction");
330 } else
331 out(offset, segment, &e->offset,
332 OUT_ADDRESS, wsize, e->segment, e->wrt);
333 offset += wsize;
334 } else if (e->type == EOT_DB_STRING) {
335 int align;
337 out(offset, segment, e->stringval,
338 OUT_RAWDATA, e->stringlen, NO_SEG, NO_SEG);
339 align = e->stringlen % wsize;
341 if (align) {
342 align = wsize - align;
343 out(offset, segment, const_zero_buf,
344 OUT_RAWDATA, align, NO_SEG, NO_SEG);
346 offset += e->stringlen + align;
349 if (t > 0 && t == instruction->times - 1) {
351 * Dummy call to list->output to give the offset to the
352 * listing module.
354 list->output(offset, NULL, OUT_RAWDATA, 0);
355 list->uplevel(LIST_TIMES);
358 if (instruction->times > 1)
359 list->downlevel(LIST_TIMES);
360 return offset - start;
363 if (instruction->opcode == I_INCBIN) {
364 static char fname[FILENAME_MAX];
365 FILE *fp;
366 int32_t len;
367 char *prefix = "", *combine;
368 char **pPrevPath = NULL;
370 len = FILENAME_MAX - 1;
371 if (len > instruction->eops->stringlen)
372 len = instruction->eops->stringlen;
373 strncpy(fname, instruction->eops->stringval, len);
374 fname[len] = '\0';
376 while (1) { /* added by alexfru: 'incbin' uses include paths */
377 combine = nasm_malloc(strlen(prefix) + len + 1);
378 strcpy(combine, prefix);
379 strcat(combine, fname);
381 if ((fp = fopen(combine, "rb")) != NULL) {
382 nasm_free(combine);
383 break;
386 nasm_free(combine);
387 pPrevPath = pp_get_include_path_ptr(pPrevPath);
388 if (pPrevPath == NULL)
389 break;
390 prefix = *pPrevPath;
393 if (fp == NULL)
394 error(ERR_NONFATAL, "`incbin': unable to open file `%s'",
395 fname);
396 else if (fseek(fp, 0L, SEEK_END) < 0)
397 error(ERR_NONFATAL, "`incbin': unable to seek on file `%s'",
398 fname);
399 else {
400 static char buf[2048];
401 int32_t t = instruction->times;
402 int32_t base = 0;
404 len = ftell(fp);
405 if (instruction->eops->next) {
406 base = instruction->eops->next->offset;
407 len -= base;
408 if (instruction->eops->next->next &&
409 len > instruction->eops->next->next->offset)
410 len = instruction->eops->next->next->offset;
413 * Dummy call to list->output to give the offset to the
414 * listing module.
416 list->output(offset, NULL, OUT_RAWDATA, 0);
417 list->uplevel(LIST_INCBIN);
418 while (t--) {
419 int32_t l;
421 fseek(fp, base, SEEK_SET);
422 l = len;
423 while (l > 0) {
424 int32_t m =
425 fread(buf, 1, (l > (int32_t) sizeof(buf) ? (int32_t) sizeof(buf) : l),
426 fp);
427 if (!m) {
429 * This shouldn't happen unless the file
430 * actually changes while we are reading
431 * it.
433 error(ERR_NONFATAL,
434 "`incbin': unexpected EOF while"
435 " reading file `%s'", fname);
436 t = 0; /* Try to exit cleanly */
437 break;
439 out(offset, segment, buf, OUT_RAWDATA, m,
440 NO_SEG, NO_SEG);
441 l -= m;
444 list->downlevel(LIST_INCBIN);
445 if (instruction->times > 1) {
447 * Dummy call to list->output to give the offset to the
448 * listing module.
450 list->output(offset, NULL, OUT_RAWDATA, 0);
451 list->uplevel(LIST_TIMES);
452 list->downlevel(LIST_TIMES);
454 fclose(fp);
455 return instruction->times * len;
457 return 0; /* if we're here, there's an error */
460 /* Check to see if we need an address-size prefix */
461 add_asp(instruction, bits);
463 size_prob = false;
465 for (temp = nasm_instructions[instruction->opcode]; temp->opcode != -1; temp++){
466 int m = matches(temp, instruction, bits);
468 if (m == 99)
469 m += jmp_match(segment, offset, bits, instruction, temp->code);
471 if (m == 100) { /* matches! */
472 const uint8_t *codes = temp->code;
473 int64_t insn_size = calcsize(segment, offset, bits,
474 instruction, codes);
475 itimes = instruction->times;
476 if (insn_size < 0) /* shouldn't be, on pass two */
477 error(ERR_PANIC, "errors made it through from pass one");
478 else
479 while (itimes--) {
480 for (j = 0; j < MAXPREFIX; j++) {
481 uint8_t c = 0;
482 switch (instruction->prefixes[j]) {
483 case P_LOCK:
484 c = 0xF0;
485 break;
486 case P_REPNE:
487 case P_REPNZ:
488 c = 0xF2;
489 break;
490 case P_REPE:
491 case P_REPZ:
492 case P_REP:
493 c = 0xF3;
494 break;
495 case R_CS:
496 if (bits == 64) {
497 error(ERR_WARNING,
498 "cs segment base generated, but will be ignored in 64-bit mode");
500 c = 0x2E;
501 break;
502 case R_DS:
503 if (bits == 64) {
504 error(ERR_WARNING,
505 "ds segment base generated, but will be ignored in 64-bit mode");
507 c = 0x3E;
508 break;
509 case R_ES:
510 if (bits == 64) {
511 error(ERR_WARNING,
512 "es segment base generated, but will be ignored in 64-bit mode");
514 c = 0x26;
515 break;
516 case R_FS:
517 c = 0x64;
518 break;
519 case R_GS:
520 c = 0x65;
521 break;
522 case R_SS:
523 if (bits == 64) {
524 error(ERR_WARNING,
525 "ss segment base generated, but will be ignored in 64-bit mode");
527 c = 0x36;
528 break;
529 case R_SEGR6:
530 case R_SEGR7:
531 error(ERR_NONFATAL,
532 "segr6 and segr7 cannot be used as prefixes");
533 break;
534 case P_A16:
535 if (bits == 64) {
536 error(ERR_NONFATAL,
537 "16-bit addressing is not supported "
538 "in 64-bit mode");
539 } else if (bits != 16)
540 c = 0x67;
541 break;
542 case P_A32:
543 if (bits != 32)
544 c = 0x67;
545 break;
546 case P_A64:
547 if (bits != 64) {
548 error(ERR_NONFATAL,
549 "64-bit addressing is only supported "
550 "in 64-bit mode");
552 break;
553 case P_ASP:
554 c = 0x67;
555 break;
556 case P_O16:
557 if (bits != 16)
558 c = 0x66;
559 break;
560 case P_O32:
561 if (bits == 16)
562 c = 0x66;
563 break;
564 case P_O64:
565 /* REX.W */
566 break;
567 case P_OSP:
568 c = 0x66;
569 break;
570 case P_none:
571 break;
572 default:
573 error(ERR_PANIC, "invalid instruction prefix");
575 if (c != 0) {
576 out(offset, segment, &c, OUT_RAWDATA, 1,
577 NO_SEG, NO_SEG);
578 offset++;
581 insn_end = offset + insn_size;
582 gencode(segment, offset, bits, instruction, codes,
583 insn_end);
584 offset += insn_size;
585 if (itimes > 0 && itimes == instruction->times - 1) {
587 * Dummy call to list->output to give the offset to the
588 * listing module.
590 list->output(offset, NULL, OUT_RAWDATA, 0);
591 list->uplevel(LIST_TIMES);
594 if (instruction->times > 1)
595 list->downlevel(LIST_TIMES);
596 return offset - start;
597 } else if (m > 0 && m > size_prob) {
598 size_prob = m;
600 // temp++;
603 if (temp->opcode == -1) { /* didn't match any instruction */
604 switch (size_prob) {
605 case 1:
606 error(ERR_NONFATAL, "operation size not specified");
607 break;
608 case 2:
609 error(ERR_NONFATAL, "mismatch in operand sizes");
610 break;
611 case 3:
612 error(ERR_NONFATAL, "no instruction for this cpu level");
613 break;
614 case 4:
615 error(ERR_NONFATAL, "instruction not supported in 64-bit mode");
616 break;
617 default:
618 error(ERR_NONFATAL,
619 "invalid combination of opcode and operands");
620 break;
623 return 0;
626 int64_t insn_size(int32_t segment, int64_t offset, int bits, uint32_t cp,
627 insn * instruction, efunc error)
629 const struct itemplate *temp;
631 errfunc = error; /* to pass to other functions */
632 cpu = cp;
634 if (instruction->opcode == -1)
635 return 0;
637 if (instruction->opcode == I_DB || instruction->opcode == I_DW ||
638 instruction->opcode == I_DD || instruction->opcode == I_DQ ||
639 instruction->opcode == I_DT || instruction->opcode == I_DO ||
640 instruction->opcode == I_DY) {
641 extop *e;
642 int32_t isize, osize, wsize = 0; /* placate gcc */
644 isize = 0;
645 switch (instruction->opcode) {
646 case I_DB:
647 wsize = 1;
648 break;
649 case I_DW:
650 wsize = 2;
651 break;
652 case I_DD:
653 wsize = 4;
654 break;
655 case I_DQ:
656 wsize = 8;
657 break;
658 case I_DT:
659 wsize = 10;
660 break;
661 case I_DO:
662 wsize = 16;
663 break;
664 case I_DY:
665 wsize = 32;
666 break;
667 default:
668 break;
671 for (e = instruction->eops; e; e = e->next) {
672 int32_t align;
674 osize = 0;
675 if (e->type == EOT_DB_NUMBER)
676 osize = 1;
677 else if (e->type == EOT_DB_STRING)
678 osize = e->stringlen;
680 align = (-osize) % wsize;
681 if (align < 0)
682 align += wsize;
683 isize += osize + align;
685 return isize * instruction->times;
688 if (instruction->opcode == I_INCBIN) {
689 char fname[FILENAME_MAX];
690 FILE *fp;
691 int32_t len;
692 char *prefix = "", *combine;
693 char **pPrevPath = NULL;
695 len = FILENAME_MAX - 1;
696 if (len > instruction->eops->stringlen)
697 len = instruction->eops->stringlen;
698 strncpy(fname, instruction->eops->stringval, len);
699 fname[len] = '\0';
701 /* added by alexfru: 'incbin' uses include paths */
702 while (1) {
703 combine = nasm_malloc(strlen(prefix) + len + 1);
704 strcpy(combine, prefix);
705 strcat(combine, fname);
707 if ((fp = fopen(combine, "rb")) != NULL) {
708 nasm_free(combine);
709 break;
712 nasm_free(combine);
713 pPrevPath = pp_get_include_path_ptr(pPrevPath);
714 if (pPrevPath == NULL)
715 break;
716 prefix = *pPrevPath;
719 if (fp == NULL)
720 error(ERR_NONFATAL, "`incbin': unable to open file `%s'",
721 fname);
722 else if (fseek(fp, 0L, SEEK_END) < 0)
723 error(ERR_NONFATAL, "`incbin': unable to seek on file `%s'",
724 fname);
725 else {
726 len = ftell(fp);
727 fclose(fp);
728 if (instruction->eops->next) {
729 len -= instruction->eops->next->offset;
730 if (instruction->eops->next->next &&
731 len > instruction->eops->next->next->offset) {
732 len = instruction->eops->next->next->offset;
735 return instruction->times * len;
737 return 0; /* if we're here, there's an error */
740 /* Check to see if we need an address-size prefix */
741 add_asp(instruction, bits);
743 for (temp = nasm_instructions[instruction->opcode]; temp->opcode != -1; temp++) {
744 int m = matches(temp, instruction, bits);
745 if (m == 99)
746 m += jmp_match(segment, offset, bits, instruction, temp->code);
748 if (m == 100) {
749 /* we've matched an instruction. */
750 int64_t isize;
751 const uint8_t *codes = temp->code;
752 int j;
754 isize = calcsize(segment, offset, bits, instruction, codes);
755 if (isize < 0)
756 return -1;
757 for (j = 0; j < MAXPREFIX; j++) {
758 switch (instruction->prefixes[j]) {
759 case P_A16:
760 if (bits != 16)
761 isize++;
762 break;
763 case P_A32:
764 if (bits != 32)
765 isize++;
766 break;
767 case P_O16:
768 if (bits != 16)
769 isize++;
770 break;
771 case P_O32:
772 if (bits == 16)
773 isize++;
774 break;
775 case P_A64:
776 case P_O64:
777 case P_none:
778 break;
779 default:
780 isize++;
781 break;
784 return isize * instruction->times;
787 return -1; /* didn't match any instruction */
790 static bool possible_sbyte(insn * ins, int op)
792 return !(ins->forw_ref && ins->oprs[op].opflags) &&
793 optimizing >= 0 &&
794 !(ins->oprs[op].type & STRICT) &&
795 ins->oprs[op].wrt == NO_SEG && ins->oprs[op].segment == NO_SEG;
798 /* check that opn[op] is a signed byte of size 16 or 32 */
799 static bool is_sbyte16(insn * ins, int op)
801 int16_t v;
803 if (!possible_sbyte(ins, op))
804 return false;
806 v = ins->oprs[op].offset;
807 return v >= -128 && v <= 127;
810 static bool is_sbyte32(insn * ins, int op)
812 int32_t v;
814 if (!possible_sbyte(ins, op))
815 return false;
817 v = ins->oprs[op].offset;
818 return v >= -128 && v <= 127;
821 /* check that opn[op] is a signed byte of size 32; warn if this is not
822 the original value when extended to 64 bits */
823 static bool is_sbyte64(insn * ins, int op)
825 int64_t v64;
826 int32_t v32;
828 /* dead in the water on forward reference or External */
829 if (!possible_sbyte(ins, op))
830 return false;
832 v64 = ins->oprs[op].offset;
833 v32 = (int32_t)v64;
835 warn_overflow(32, v64);
837 return v32 >= -128 && v32 <= 127;
839 static int64_t calcsize(int32_t segment, int64_t offset, int bits,
840 insn * ins, const uint8_t *codes)
842 int64_t length = 0;
843 uint8_t c;
844 int rex_mask = ~0;
845 struct operand *opx;
847 ins->rex = 0; /* Ensure REX is reset */
849 if (ins->prefixes[PPS_OSIZE] == P_O64)
850 ins->rex |= REX_W;
852 (void)segment; /* Don't warn that this parameter is unused */
853 (void)offset; /* Don't warn that this parameter is unused */
855 while (*codes) {
856 c = *codes++;
857 opx = &ins->oprs[c & 3];
858 switch (c) {
859 case 01:
860 case 02:
861 case 03:
862 codes += c, length += c;
863 break;
864 case 04:
865 case 05:
866 case 06:
867 case 07:
868 length++;
869 break;
870 case 010:
871 case 011:
872 case 012:
873 case 013:
874 ins->rex |=
875 op_rexflags(opx, REX_B|REX_H|REX_P|REX_W);
876 codes++, length++;
877 break;
878 case 014:
879 case 015:
880 case 016:
881 case 017:
882 length++;
883 break;
884 case 020:
885 case 021:
886 case 022:
887 case 023:
888 length++;
889 break;
890 case 024:
891 case 025:
892 case 026:
893 case 027:
894 length++;
895 break;
896 case 030:
897 case 031:
898 case 032:
899 case 033:
900 length += 2;
901 break;
902 case 034:
903 case 035:
904 case 036:
905 case 037:
906 if (opx->type & (BITS16 | BITS32 | BITS64))
907 length += (opx->type & BITS16) ? 2 : 4;
908 else
909 length += (bits == 16) ? 2 : 4;
910 break;
911 case 040:
912 case 041:
913 case 042:
914 case 043:
915 length += 4;
916 break;
917 case 044:
918 case 045:
919 case 046:
920 case 047:
921 length += ins->addr_size >> 3;
922 break;
923 case 050:
924 case 051:
925 case 052:
926 case 053:
927 length++;
928 break;
929 case 054:
930 case 055:
931 case 056:
932 case 057:
933 length += 8; /* MOV reg64/imm */
934 break;
935 case 060:
936 case 061:
937 case 062:
938 case 063:
939 length += 2;
940 break;
941 case 064:
942 case 065:
943 case 066:
944 case 067:
945 if (opx->type & (BITS16 | BITS32 | BITS64))
946 length += (opx->type & BITS16) ? 2 : 4;
947 else
948 length += (bits == 16) ? 2 : 4;
949 break;
950 case 070:
951 case 071:
952 case 072:
953 case 073:
954 length += 4;
955 break;
956 case 074:
957 case 075:
958 case 076:
959 case 077:
960 length += 2;
961 break;
962 case 0140:
963 case 0141:
964 case 0142:
965 case 0143:
966 length += is_sbyte16(ins, c & 3) ? 1 : 2;
967 break;
968 case 0144:
969 case 0145:
970 case 0146:
971 case 0147:
972 codes++;
973 length++;
974 break;
975 case 0150:
976 case 0151:
977 case 0152:
978 case 0153:
979 length += is_sbyte32(ins, c & 3) ? 1 : 4;
980 break;
981 case 0154:
982 case 0155:
983 case 0156:
984 case 0157:
985 codes++;
986 length++;
987 break;
988 case 0160:
989 case 0161:
990 case 0162:
991 case 0163:
992 length++;
993 ins->rex |= REX_D;
994 ins->drexdst = regval(opx);
995 break;
996 case 0164:
997 case 0165:
998 case 0166:
999 case 0167:
1000 length++;
1001 ins->rex |= REX_D|REX_OC;
1002 ins->drexdst = regval(opx);
1003 break;
1004 case 0171:
1005 break;
1006 case 0172:
1007 case 0173:
1008 codes++;
1009 length++;
1010 break;
1011 case 0250:
1012 case 0251:
1013 case 0252:
1014 case 0253:
1015 length += is_sbyte64(ins, c & 3) ? 1 : 4;
1016 break;
1017 case 0260:
1018 case 0261:
1019 case 0262:
1020 case 0263:
1021 length += 2;
1022 ins->rex |= REX_V;
1023 ins->drexdst = regval(opx);
1024 ins->vex_m = *codes++;
1025 ins->vex_wlp = *codes++;
1026 break;
1027 case 0270:
1028 length += 2;
1029 ins->rex |= REX_V;
1030 ins->drexdst = 0;
1031 ins->vex_m = *codes++;
1032 ins->vex_wlp = *codes++;
1033 break;
1034 case 0300:
1035 case 0301:
1036 case 0302:
1037 case 0303:
1038 break;
1039 case 0310:
1040 if (bits == 64)
1041 return -1;
1042 length += (bits != 16) && !has_prefix(ins, PPS_ASIZE, P_A16);
1043 break;
1044 case 0311:
1045 length += (bits != 32) && !has_prefix(ins, PPS_ASIZE, P_A32);
1046 break;
1047 case 0312:
1048 break;
1049 case 0313:
1050 if (bits != 64 || has_prefix(ins, PPS_ASIZE, P_A16) ||
1051 has_prefix(ins, PPS_ASIZE, P_A32))
1052 return -1;
1053 break;
1054 case 0314:
1055 case 0315:
1056 case 0316:
1057 case 0317:
1058 break;
1059 case 0320:
1060 length += (bits != 16);
1061 break;
1062 case 0321:
1063 length += (bits == 16);
1064 break;
1065 case 0322:
1066 break;
1067 case 0323:
1068 rex_mask &= ~REX_W;
1069 break;
1070 case 0324:
1071 ins->rex |= REX_W;
1072 break;
1073 case 0330:
1074 codes++, length++;
1075 break;
1076 case 0331:
1077 break;
1078 case 0332:
1079 case 0333:
1080 length++;
1081 break;
1082 case 0334:
1083 ins->rex |= REX_L;
1084 break;
1085 case 0335:
1086 break;
1087 case 0340:
1088 if (ins->oprs[0].segment != NO_SEG)
1089 errfunc(ERR_NONFATAL, "attempt to reserve non-constant"
1090 " quantity of BSS space");
1091 else
1092 length += ins->oprs[0].offset;
1093 break;
1094 case 0360:
1095 break;
1096 case 0361:
1097 case 0362:
1098 case 0363:
1099 length++;
1100 break;
1101 case 0364:
1102 case 0365:
1103 break;
1104 case 0366:
1105 case 0367:
1106 length++;
1107 break;
1108 case 0370:
1109 case 0371:
1110 case 0372:
1111 break;
1112 case 0373:
1113 length++;
1114 break;
1115 default: /* can't do it by 'case' statements */
1116 if (c >= 0100 && c <= 0277) { /* it's an EA */
1117 ea ea_data;
1118 int rfield;
1119 int32_t rflags;
1120 ea_data.rex = 0; /* Ensure ea.REX is initially 0 */
1122 if (c <= 0177) {
1123 /* pick rfield from operand b */
1124 rflags = regflag(&ins->oprs[c & 7]);
1125 rfield = nasm_regvals[ins->oprs[c & 7].basereg];
1126 } else {
1127 rflags = 0;
1128 rfield = c & 7;
1131 if (!process_ea
1132 (&ins->oprs[(c >> 3) & 7], &ea_data, bits,
1133 ins->addr_size, rfield, rflags, ins->forw_ref)) {
1134 errfunc(ERR_NONFATAL, "invalid effective address");
1135 return -1;
1136 } else {
1137 ins->rex |= ea_data.rex;
1138 length += ea_data.size;
1140 } else {
1141 errfunc(ERR_PANIC, "internal instruction table corrupt"
1142 ": instruction code 0x%02X given", c);
1147 ins->rex &= rex_mask;
1149 if (ins->rex & REX_V) {
1150 int bad32 = REX_R|REX_W|REX_X|REX_B;
1152 if (ins->rex & REX_H) {
1153 errfunc(ERR_NONFATAL, "cannot use high register in vex instruction");
1154 return -1;
1156 switch (ins->vex_wlp & 030) {
1157 case 000:
1158 ins->rex &= ~REX_W;
1159 break;
1160 case 010:
1161 ins->rex |= REX_W;
1162 bad32 &= ~REX_W;
1163 break;
1164 default:
1165 /* Follow REX_W */
1166 break;
1169 if (bits != 64 && ((ins->rex & bad32) || ins->drexdst > 7)) {
1170 errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode");
1171 return -1;
1173 if (ins->vex_m != 1 || (ins->rex & (REX_W|REX_R|REX_B)))
1174 length += 3;
1175 else
1176 length += 2;
1177 } else if (ins->rex & REX_D) {
1178 if (ins->rex & REX_H) {
1179 errfunc(ERR_NONFATAL, "cannot use high register in drex instruction");
1180 return -1;
1182 if (bits != 64 && ((ins->rex & (REX_R|REX_W|REX_X|REX_B)) ||
1183 ins->drexdst > 7)) {
1184 errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode");
1185 return -1;
1187 length++;
1188 } else if (ins->rex & REX_REAL) {
1189 if (ins->rex & REX_H) {
1190 errfunc(ERR_NONFATAL, "cannot use high register in rex instruction");
1191 return -1;
1192 } else if (bits == 64) {
1193 length++;
1194 } else if ((ins->rex & REX_L) &&
1195 !(ins->rex & (REX_P|REX_W|REX_X|REX_B)) &&
1196 cpu >= IF_X86_64) {
1197 /* LOCK-as-REX.R */
1198 assert_no_prefix(ins, PPS_LREP);
1199 length++;
1200 } else {
1201 errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode");
1202 return -1;
1206 return length;
1209 #define EMIT_REX() \
1210 if (!(ins->rex & (REX_D|REX_V)) && (ins->rex & REX_REAL) && (bits == 64)) { \
1211 ins->rex = (ins->rex & REX_REAL)|REX_P; \
1212 out(offset, segment, &ins->rex, OUT_RAWDATA, 1, NO_SEG, NO_SEG); \
1213 ins->rex = 0; \
1214 offset += 1; \
1217 static void gencode(int32_t segment, int64_t offset, int bits,
1218 insn * ins, const uint8_t *codes, int64_t insn_end)
1220 static char condval[] = { /* conditional opcodes */
1221 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
1222 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
1223 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
1225 uint8_t c;
1226 uint8_t bytes[4];
1227 int64_t size;
1228 int64_t data;
1229 struct operand *opx;
1231 while (*codes) {
1232 c = *codes++;
1233 opx = &ins->oprs[c & 3];
1234 switch (c) {
1235 case 01:
1236 case 02:
1237 case 03:
1238 EMIT_REX();
1239 out(offset, segment, codes, OUT_RAWDATA, c, NO_SEG, NO_SEG);
1240 codes += c;
1241 offset += c;
1242 break;
1244 case 04:
1245 case 06:
1246 switch (ins->oprs[0].basereg) {
1247 case R_CS:
1248 bytes[0] = 0x0E + (c == 0x04 ? 1 : 0);
1249 break;
1250 case R_DS:
1251 bytes[0] = 0x1E + (c == 0x04 ? 1 : 0);
1252 break;
1253 case R_ES:
1254 bytes[0] = 0x06 + (c == 0x04 ? 1 : 0);
1255 break;
1256 case R_SS:
1257 bytes[0] = 0x16 + (c == 0x04 ? 1 : 0);
1258 break;
1259 default:
1260 errfunc(ERR_PANIC,
1261 "bizarre 8086 segment register received");
1263 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1264 offset++;
1265 break;
1267 case 05:
1268 case 07:
1269 switch (ins->oprs[0].basereg) {
1270 case R_FS:
1271 bytes[0] = 0xA0 + (c == 0x05 ? 1 : 0);
1272 break;
1273 case R_GS:
1274 bytes[0] = 0xA8 + (c == 0x05 ? 1 : 0);
1275 break;
1276 default:
1277 errfunc(ERR_PANIC,
1278 "bizarre 386 segment register received");
1280 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1281 offset++;
1282 break;
1284 case 010:
1285 case 011:
1286 case 012:
1287 case 013:
1288 EMIT_REX();
1289 bytes[0] = *codes++ + ((regval(opx)) & 7);
1290 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1291 offset += 1;
1292 break;
1294 case 014:
1295 case 015:
1296 case 016:
1297 case 017:
1298 /* XXX: warns for legitimate optimizer actions */
1299 if (opx->offset < -128 || opx->offset > 127) {
1300 errfunc(ERR_WARNING | ERR_WARN_NOV,
1301 "signed byte value exceeds bounds");
1304 if (opx->segment != NO_SEG) {
1305 data = opx->offset;
1306 out(offset, segment, &data, OUT_ADDRESS, 1,
1307 opx->segment, opx->wrt);
1308 } else {
1309 bytes[0] = opx->offset;
1310 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1311 NO_SEG);
1313 offset += 1;
1314 break;
1316 case 020:
1317 case 021:
1318 case 022:
1319 case 023:
1320 if (opx->offset < -256 || opx->offset > 255) {
1321 errfunc(ERR_WARNING | ERR_WARN_NOV,
1322 "byte value exceeds bounds");
1324 if (opx->segment != NO_SEG) {
1325 data = opx->offset;
1326 out(offset, segment, &data, OUT_ADDRESS, 1,
1327 opx->segment, opx->wrt);
1328 } else {
1329 bytes[0] = opx->offset;
1330 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1331 NO_SEG);
1333 offset += 1;
1334 break;
1336 case 024:
1337 case 025:
1338 case 026:
1339 case 027:
1340 if (opx->offset < 0 || opx->offset > 255)
1341 errfunc(ERR_WARNING | ERR_WARN_NOV,
1342 "unsigned byte value exceeds bounds");
1343 if (opx->segment != NO_SEG) {
1344 data = opx->offset;
1345 out(offset, segment, &data, OUT_ADDRESS, 1,
1346 opx->segment, opx->wrt);
1347 } else {
1348 bytes[0] = opx->offset;
1349 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1350 NO_SEG);
1352 offset += 1;
1353 break;
1355 case 030:
1356 case 031:
1357 case 032:
1358 case 033:
1359 data = opx->offset;
1360 if (opx->segment == NO_SEG && opx->wrt == NO_SEG)
1361 warn_overflow(2, data);
1362 out(offset, segment, &data, OUT_ADDRESS, 2,
1363 opx->segment, opx->wrt);
1364 offset += 2;
1365 break;
1367 case 034:
1368 case 035:
1369 case 036:
1370 case 037:
1371 if (opx->type & (BITS16 | BITS32))
1372 size = (opx->type & BITS16) ? 2 : 4;
1373 else
1374 size = (bits == 16) ? 2 : 4;
1375 data = opx->offset;
1376 if (opx->segment == NO_SEG && opx->wrt == NO_SEG)
1377 warn_overflow(size, data);
1378 out(offset, segment, &data, OUT_ADDRESS, size,
1379 opx->segment, opx->wrt);
1380 offset += size;
1381 break;
1383 case 040:
1384 case 041:
1385 case 042:
1386 case 043:
1387 data = opx->offset;
1388 if (opx->segment == NO_SEG && opx->wrt == NO_SEG)
1389 warn_overflow(4, data);
1390 out(offset, segment, &data, OUT_ADDRESS, 4,
1391 opx->segment, opx->wrt);
1392 offset += 4;
1393 break;
1395 case 044:
1396 case 045:
1397 case 046:
1398 case 047:
1399 data = opx->offset;
1400 size = ins->addr_size >> 3;
1401 if (opx->segment == NO_SEG &&
1402 opx->wrt == NO_SEG)
1403 warn_overflow(size, data);
1404 out(offset, segment, &data, OUT_ADDRESS, size,
1405 opx->segment, opx->wrt);
1406 offset += size;
1407 break;
1409 case 050:
1410 case 051:
1411 case 052:
1412 case 053:
1413 if (opx->segment != segment)
1414 errfunc(ERR_NONFATAL,
1415 "short relative jump outside segment");
1416 data = opx->offset - insn_end;
1417 if (data > 127 || data < -128)
1418 errfunc(ERR_NONFATAL, "short jump is out of range");
1419 bytes[0] = data;
1420 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1421 offset += 1;
1422 break;
1424 case 054:
1425 case 055:
1426 case 056:
1427 case 057:
1428 data = (int64_t)opx->offset;
1429 out(offset, segment, &data, OUT_ADDRESS, 8,
1430 opx->segment, opx->wrt);
1431 offset += 8;
1432 break;
1434 case 060:
1435 case 061:
1436 case 062:
1437 case 063:
1438 if (opx->segment != segment) {
1439 data = opx->offset;
1440 out(offset, segment, &data,
1441 OUT_REL2ADR, insn_end - offset,
1442 opx->segment, opx->wrt);
1443 } else {
1444 data = opx->offset - insn_end;
1445 out(offset, segment, &data,
1446 OUT_ADDRESS, 2, NO_SEG, NO_SEG);
1448 offset += 2;
1449 break;
1451 case 064:
1452 case 065:
1453 case 066:
1454 case 067:
1455 if (opx->type & (BITS16 | BITS32 | BITS64))
1456 size = (opx->type & BITS16) ? 2 : 4;
1457 else
1458 size = (bits == 16) ? 2 : 4;
1459 if (opx->segment != segment) {
1460 data = opx->offset;
1461 out(offset, segment, &data,
1462 size == 2 ? OUT_REL2ADR : OUT_REL4ADR,
1463 insn_end - offset, opx->segment, opx->wrt);
1464 } else {
1465 data = opx->offset - insn_end;
1466 out(offset, segment, &data,
1467 OUT_ADDRESS, size, NO_SEG, NO_SEG);
1469 offset += size;
1470 break;
1472 case 070:
1473 case 071:
1474 case 072:
1475 case 073:
1476 if (opx->segment != segment) {
1477 data = opx->offset;
1478 out(offset, segment, &data,
1479 OUT_REL4ADR, insn_end - offset,
1480 opx->segment, opx->wrt);
1481 } else {
1482 data = opx->offset - insn_end;
1483 out(offset, segment, &data,
1484 OUT_ADDRESS, 4, NO_SEG, NO_SEG);
1486 offset += 4;
1487 break;
1489 case 074:
1490 case 075:
1491 case 076:
1492 case 077:
1493 if (opx->segment == NO_SEG)
1494 errfunc(ERR_NONFATAL, "value referenced by FAR is not"
1495 " relocatable");
1496 data = 0;
1497 out(offset, segment, &data, OUT_ADDRESS, 2,
1498 outfmt->segbase(1 + opx->segment),
1499 opx->wrt);
1500 offset += 2;
1501 break;
1503 case 0140:
1504 case 0141:
1505 case 0142:
1506 case 0143:
1507 data = opx->offset;
1508 if (is_sbyte16(ins, c & 3)) {
1509 bytes[0] = data;
1510 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1511 NO_SEG);
1512 offset++;
1513 } else {
1514 if (opx->segment == NO_SEG &&
1515 opx->wrt == NO_SEG)
1516 warn_overflow(2, data);
1517 out(offset, segment, &data, OUT_ADDRESS, 2,
1518 opx->segment, opx->wrt);
1519 offset += 2;
1521 break;
1523 case 0144:
1524 case 0145:
1525 case 0146:
1526 case 0147:
1527 EMIT_REX();
1528 bytes[0] = *codes++;
1529 if (is_sbyte16(ins, c & 3))
1530 bytes[0] |= 2; /* s-bit */
1531 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1532 offset++;
1533 break;
1535 case 0150:
1536 case 0151:
1537 case 0152:
1538 case 0153:
1539 data = opx->offset;
1540 if (is_sbyte32(ins, c & 3)) {
1541 bytes[0] = data;
1542 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1543 NO_SEG);
1544 offset++;
1545 } else {
1546 out(offset, segment, &data, OUT_ADDRESS, 4,
1547 opx->segment, opx->wrt);
1548 offset += 4;
1550 break;
1552 case 0154:
1553 case 0155:
1554 case 0156:
1555 case 0157:
1556 EMIT_REX();
1557 bytes[0] = *codes++;
1558 if (is_sbyte32(ins, c & 3))
1559 bytes[0] |= 2; /* s-bit */
1560 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1561 offset++;
1562 break;
1564 case 0160:
1565 case 0161:
1566 case 0162:
1567 case 0163:
1568 case 0164:
1569 case 0165:
1570 case 0166:
1571 case 0167:
1572 break;
1574 case 0171:
1575 bytes[0] =
1576 (ins->drexdst << 4) |
1577 (ins->rex & REX_OC ? 0x08 : 0) |
1578 (ins->rex & (REX_R|REX_X|REX_B));
1579 ins->rex = 0;
1580 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1581 offset++;
1582 break;
1584 case 0172:
1585 c = *codes++;
1586 opx = &ins->oprs[c >> 3];
1587 bytes[0] = nasm_regvals[opx->basereg] << 4;
1588 opx = &ins->oprs[c & 7];
1589 if (opx->segment != NO_SEG || opx->wrt != NO_SEG) {
1590 errfunc(ERR_NONFATAL,
1591 "non-absolute expression not permitted as argument %d",
1592 c & 7);
1593 } else {
1594 if (opx->offset & ~15) {
1595 errfunc(ERR_WARNING | ERR_WARN_NOV,
1596 "four-bit argument exceeds bounds");
1598 bytes[0] |= opx->offset & 15;
1600 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1601 offset++;
1602 break;
1604 case 0173:
1605 c = *codes++;
1606 opx = &ins->oprs[c >> 4];
1607 bytes[0] = nasm_regvals[opx->basereg] << 4;
1608 bytes[0] |= c & 15;
1609 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1610 offset++;
1611 break;
1613 case 0250:
1614 case 0251:
1615 case 0252:
1616 case 0253:
1617 data = opx->offset;
1618 /* is_sbyte32() is right here, we have already warned */
1619 if (is_sbyte32(ins, c & 3)) {
1620 bytes[0] = data;
1621 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
1622 NO_SEG);
1623 offset++;
1624 } else {
1625 out(offset, segment, &data, OUT_ADDRESS, 4,
1626 opx->segment, opx->wrt);
1627 offset += 4;
1629 break;
1631 case 0260:
1632 case 0261:
1633 case 0262:
1634 case 0263:
1635 case 0270:
1636 codes += 2;
1637 if (ins->vex_m != 1 || (ins->rex & (REX_W|REX_X|REX_B))) {
1638 bytes[0] = 0xc4;
1639 bytes[1] = ins->vex_m | ((~ins->rex & 7) << 5);
1640 bytes[2] = ((ins->rex & REX_W) << (7-3)) |
1641 ((~ins->drexdst & 15)<< 3) | (ins->vex_wlp & 07);
1642 out(offset, segment, &bytes, OUT_RAWDATA, 3, NO_SEG, NO_SEG);
1643 offset += 3;
1644 } else {
1645 bytes[0] = 0xc5;
1646 bytes[1] = ((~ins->rex & REX_R) << (7-2)) |
1647 ((~ins->drexdst & 15) << 3) | (ins->vex_wlp & 07);
1648 out(offset, segment, &bytes, OUT_RAWDATA, 2, NO_SEG, NO_SEG);
1649 offset += 2;
1651 break;
1653 case 0300:
1654 case 0301:
1655 case 0302:
1656 case 0303:
1657 break;
1659 case 0310:
1660 if (bits == 32 && !has_prefix(ins, PPS_ASIZE, P_A16)) {
1661 *bytes = 0x67;
1662 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1663 offset += 1;
1664 } else
1665 offset += 0;
1666 break;
1668 case 0311:
1669 if (bits != 32 && !has_prefix(ins, PPS_ASIZE, P_A32)) {
1670 *bytes = 0x67;
1671 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1672 offset += 1;
1673 } else
1674 offset += 0;
1675 break;
1677 case 0312:
1678 break;
1680 case 0313:
1681 ins->rex = 0;
1682 break;
1684 case 0314:
1685 case 0315:
1686 case 0316:
1687 case 0317:
1688 break;
1690 case 0320:
1691 if (bits != 16) {
1692 *bytes = 0x66;
1693 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1694 offset += 1;
1695 } else
1696 offset += 0;
1697 break;
1699 case 0321:
1700 if (bits == 16) {
1701 *bytes = 0x66;
1702 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1703 offset += 1;
1704 } else
1705 offset += 0;
1706 break;
1708 case 0322:
1709 case 0323:
1710 break;
1712 case 0324:
1713 ins->rex |= REX_W;
1714 break;
1716 case 0330:
1717 *bytes = *codes++ ^ condval[ins->condition];
1718 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1719 offset += 1;
1720 break;
1722 case 0331:
1723 break;
1725 case 0332:
1726 case 0333:
1727 *bytes = c - 0332 + 0xF2;
1728 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1729 offset += 1;
1730 break;
1732 case 0334:
1733 if (ins->rex & REX_R) {
1734 *bytes = 0xF0;
1735 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1736 offset += 1;
1738 ins->rex &= ~(REX_L|REX_R);
1739 break;
1741 case 0335:
1742 break;
1744 case 0340:
1745 if (ins->oprs[0].segment != NO_SEG)
1746 errfunc(ERR_PANIC, "non-constant BSS size in pass two");
1747 else {
1748 int64_t size = ins->oprs[0].offset;
1749 if (size > 0)
1750 out(offset, segment, NULL,
1751 OUT_RESERVE, size, NO_SEG, NO_SEG);
1752 offset += size;
1754 break;
1756 case 0360:
1757 break;
1759 case 0361:
1760 bytes[0] = 0x66;
1761 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1762 offset += 1;
1763 break;
1765 case 0362:
1766 case 0363:
1767 bytes[0] = c - 0362 + 0xf2;
1768 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1769 offset += 1;
1770 break;
1772 case 0364:
1773 case 0365:
1774 break;
1776 case 0366:
1777 case 0367:
1778 *bytes = c - 0366 + 0x66;
1779 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1780 offset += 1;
1781 break;
1783 case 0370:
1784 case 0371:
1785 case 0372:
1786 break;
1788 case 0373:
1789 *bytes = bits == 16 ? 3 : 5;
1790 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
1791 offset += 1;
1792 break;
1794 default: /* can't do it by 'case' statements */
1795 if (c >= 0100 && c <= 0277) { /* it's an EA */
1796 ea ea_data;
1797 int rfield;
1798 int32_t rflags;
1799 uint8_t *p;
1800 int32_t s;
1802 if (c <= 0177) {
1803 /* pick rfield from operand b */
1804 rflags = regflag(&ins->oprs[c & 7]);
1805 rfield = nasm_regvals[ins->oprs[c & 7].basereg];
1806 } else {
1807 /* rfield is constant */
1808 rflags = 0;
1809 rfield = c & 7;
1812 if (!process_ea
1813 (&ins->oprs[(c >> 3) & 7], &ea_data, bits,
1814 ins->addr_size, rfield, rflags, ins->forw_ref)) {
1815 errfunc(ERR_NONFATAL, "invalid effective address");
1819 p = bytes;
1820 *p++ = ea_data.modrm;
1821 if (ea_data.sib_present)
1822 *p++ = ea_data.sib;
1824 /* DREX suffixes come between the SIB and the displacement */
1825 if (ins->rex & REX_D) {
1826 *p++ =
1827 (ins->drexdst << 4) |
1828 (ins->rex & REX_OC ? 0x08 : 0) |
1829 (ins->rex & (REX_R|REX_X|REX_B));
1830 ins->rex = 0;
1833 s = p - bytes;
1834 out(offset, segment, bytes, OUT_RAWDATA, s, NO_SEG, NO_SEG);
1836 switch (ea_data.bytes) {
1837 case 0:
1838 break;
1839 case 1:
1840 if (ins->oprs[(c >> 3) & 7].segment != NO_SEG) {
1841 data = ins->oprs[(c >> 3) & 7].offset;
1842 out(offset, segment, &data, OUT_ADDRESS, 1,
1843 ins->oprs[(c >> 3) & 7].segment,
1844 ins->oprs[(c >> 3) & 7].wrt);
1845 } else {
1846 *bytes = ins->oprs[(c >> 3) & 7].offset;
1847 out(offset, segment, bytes, OUT_RAWDATA, 1,
1848 NO_SEG, NO_SEG);
1850 s++;
1851 break;
1852 case 8:
1853 case 2:
1854 case 4:
1855 data = ins->oprs[(c >> 3) & 7].offset;
1856 warn_overflow(ea_data.bytes, data);
1857 out(offset, segment, &data,
1858 ea_data.rip ? OUT_REL4ADR : OUT_ADDRESS,
1859 ea_data.bytes,
1860 ins->oprs[(c >> 3) & 7].segment,
1861 ins->oprs[(c >> 3) & 7].wrt);
1862 s += ea_data.bytes;
1863 break;
1865 offset += s;
1866 } else {
1867 errfunc(ERR_PANIC, "internal instruction table corrupt"
1868 ": instruction code 0x%02X given", c);
1874 static int32_t regflag(const operand * o)
1876 if (o->basereg < EXPR_REG_START || o->basereg >= REG_ENUM_LIMIT) {
1877 errfunc(ERR_PANIC, "invalid operand passed to regflag()");
1879 return nasm_reg_flags[o->basereg];
1882 static int32_t regval(const operand * o)
1884 if (o->basereg < EXPR_REG_START || o->basereg >= REG_ENUM_LIMIT) {
1885 errfunc(ERR_PANIC, "invalid operand passed to regval()");
1887 return nasm_regvals[o->basereg];
1890 static int op_rexflags(const operand * o, int mask)
1892 int32_t flags;
1893 int val;
1895 if (o->basereg < EXPR_REG_START || o->basereg >= REG_ENUM_LIMIT) {
1896 errfunc(ERR_PANIC, "invalid operand passed to op_rexflags()");
1899 flags = nasm_reg_flags[o->basereg];
1900 val = nasm_regvals[o->basereg];
1902 return rexflags(val, flags, mask);
1905 static int rexflags(int val, int32_t flags, int mask)
1907 int rex = 0;
1909 if (val >= 8)
1910 rex |= REX_B|REX_X|REX_R;
1911 if (flags & BITS64)
1912 rex |= REX_W;
1913 if (!(REG_HIGH & ~flags)) /* AH, CH, DH, BH */
1914 rex |= REX_H;
1915 else if (!(REG8 & ~flags) && val >= 4) /* SPL, BPL, SIL, DIL */
1916 rex |= REX_P;
1918 return rex & mask;
1921 static int matches(const struct itemplate *itemp, insn * instruction, int bits)
1923 int i, size[MAX_OPERANDS], asize, oprs, ret;
1925 ret = 100;
1928 * Check the opcode
1930 if (itemp->opcode != instruction->opcode)
1931 return 0;
1934 * Count the operands
1936 if (itemp->operands != instruction->operands)
1937 return 0;
1940 * Check that no spurious colons or TOs are present
1942 for (i = 0; i < itemp->operands; i++)
1943 if (instruction->oprs[i].type & ~itemp->opd[i] & (COLON | TO))
1944 return 0;
1947 * Process size flags
1949 if (itemp->flags & IF_ARMASK) {
1950 memset(size, 0, sizeof size);
1952 i = ((itemp->flags & IF_ARMASK) >> IF_ARSHFT) - 1;
1954 switch (itemp->flags & IF_SMASK) {
1955 case IF_SB:
1956 size[i] = BITS8;
1957 break;
1958 case IF_SW:
1959 size[i] = BITS16;
1960 break;
1961 case IF_SD:
1962 size[i] = BITS32;
1963 break;
1964 case IF_SQ:
1965 size[i] = BITS64;
1966 break;
1967 case IF_SO:
1968 size[i] = BITS128;
1969 break;
1970 case IF_SY:
1971 size[i] = BITS256;
1972 break;
1973 case IF_SZ:
1974 switch (bits) {
1975 case 16:
1976 size[i] = BITS16;
1977 break;
1978 case 32:
1979 size[i] = BITS32;
1980 break;
1981 case 64:
1982 size[i] = BITS64;
1983 break;
1985 break;
1986 default:
1987 break;
1989 } else {
1990 asize = 0;
1991 switch (itemp->flags & IF_SMASK) {
1992 case IF_SB:
1993 asize = BITS8;
1994 break;
1995 case IF_SW:
1996 asize = BITS16;
1997 break;
1998 case IF_SD:
1999 asize = BITS32;
2000 break;
2001 case IF_SQ:
2002 asize = BITS64;
2003 break;
2004 case IF_SO:
2005 asize = BITS128;
2006 break;
2007 case IF_SY:
2008 asize = BITS256;
2009 break;
2010 case IF_SZ:
2011 switch (bits) {
2012 case 16:
2013 asize = BITS16;
2014 break;
2015 case 32:
2016 asize = BITS32;
2017 break;
2018 case 64:
2019 asize = BITS64;
2020 break;
2022 break;
2023 default:
2024 break;
2026 for (i = 0; i < MAX_OPERANDS; i++)
2027 size[i] = asize;
2031 * Check that the operand flags all match up
2033 for (i = 0; i < itemp->operands; i++) {
2034 int32_t type = instruction->oprs[i].type;
2035 if (!(type & SIZE_MASK))
2036 type |= size[i];
2038 if (itemp->opd[i] & SAME_AS) {
2039 int j = itemp->opd[i] & ~SAME_AS;
2040 if (type != instruction->oprs[j].type ||
2041 instruction->oprs[i].basereg != instruction->oprs[j].basereg)
2042 return 0;
2043 } else if (itemp->opd[i] & ~type ||
2044 ((itemp->opd[i] & SIZE_MASK) &&
2045 ((itemp->opd[i] ^ type) & SIZE_MASK))) {
2046 if ((itemp->opd[i] & ~type & ~SIZE_MASK) ||
2047 (type & SIZE_MASK))
2048 return 0;
2049 else
2050 return 1;
2055 * Check operand sizes
2057 if (itemp->flags & (IF_SM | IF_SM2)) {
2058 oprs = (itemp->flags & IF_SM2 ? 2 : itemp->operands);
2059 asize = 0;
2060 for (i = 0; i < oprs; i++) {
2061 if ((asize = itemp->opd[i] & SIZE_MASK) != 0) {
2062 int j;
2063 for (j = 0; j < oprs; j++)
2064 size[j] = asize;
2065 break;
2068 } else {
2069 oprs = itemp->operands;
2072 for (i = 0; i < itemp->operands; i++) {
2073 if (!(itemp->opd[i] & SIZE_MASK) &&
2074 (instruction->oprs[i].type & SIZE_MASK & ~size[i]))
2075 return 2;
2079 * Check template is okay at the set cpu level
2081 if (((itemp->flags & IF_PLEVEL) > cpu))
2082 return 3;
2085 * Check if instruction is available in long mode
2087 if ((itemp->flags & IF_NOLONG) && (bits == 64))
2088 return 4;
2091 * Check if special handling needed for Jumps
2093 if ((uint8_t)(itemp->code[0]) >= 0370)
2094 return 99;
2096 return ret;
2099 static ea *process_ea(operand * input, ea * output, int bits,
2100 int addrbits, int rfield, int32_t rflags, int forw_ref)
2102 output->rip = false;
2104 /* REX flags for the rfield operand */
2105 output->rex |= rexflags(rfield, rflags, REX_R|REX_P|REX_W|REX_H);
2107 if (!(REGISTER & ~input->type)) { /* register direct */
2108 int i;
2109 int32_t f;
2111 if (input->basereg < EXPR_REG_START /* Verify as Register */
2112 || input->basereg >= REG_ENUM_LIMIT)
2113 return NULL;
2114 f = regflag(input);
2115 i = nasm_regvals[input->basereg];
2117 if (REG_EA & ~f)
2118 return NULL; /* Invalid EA register */
2120 output->rex |= op_rexflags(input, REX_B|REX_P|REX_W|REX_H);
2122 output->sib_present = false; /* no SIB necessary */
2123 output->bytes = 0; /* no offset necessary either */
2124 output->modrm = 0xC0 | ((rfield & 7) << 3) | (i & 7);
2125 } else { /* it's a memory reference */
2126 if (input->basereg == -1
2127 && (input->indexreg == -1 || input->scale == 0)) {
2128 /* it's a pure offset */
2129 if (bits == 64 && (~input->type & IP_REL)) {
2130 int scale, index, base;
2131 output->sib_present = true;
2132 scale = 0;
2133 index = 4;
2134 base = 5;
2135 output->sib = (scale << 6) | (index << 3) | base;
2136 output->bytes = 4;
2137 output->modrm = 4 | ((rfield & 7) << 3);
2138 output->rip = false;
2139 } else {
2140 output->sib_present = false;
2141 output->bytes = (addrbits != 16 ? 4 : 2);
2142 output->modrm = (addrbits != 16 ? 5 : 6) | ((rfield & 7) << 3);
2143 output->rip = bits == 64;
2145 } else { /* it's an indirection */
2146 int i = input->indexreg, b = input->basereg, s = input->scale;
2147 int32_t o = input->offset, seg = input->segment;
2148 int hb = input->hintbase, ht = input->hinttype;
2149 int t;
2150 int it, bt;
2151 int32_t ix, bx; /* register flags */
2153 if (s == 0)
2154 i = -1; /* make this easy, at least */
2156 if (i >= EXPR_REG_START && i < REG_ENUM_LIMIT) {
2157 it = nasm_regvals[i];
2158 ix = nasm_reg_flags[i];
2159 } else {
2160 it = -1;
2161 ix = 0;
2164 if (b >= EXPR_REG_START && b < REG_ENUM_LIMIT) {
2165 bt = nasm_regvals[b];
2166 bx = nasm_reg_flags[b];
2167 } else {
2168 bt = -1;
2169 bx = 0;
2172 /* check for a 32/64-bit memory reference... */
2173 if ((ix|bx) & (BITS32|BITS64)) {
2174 /* it must be a 32/64-bit memory reference. Firstly we have
2175 * to check that all registers involved are type E/Rxx. */
2176 int32_t sok = BITS32|BITS64;
2178 if (it != -1) {
2179 if (!(REG64 & ~ix) || !(REG32 & ~ix))
2180 sok &= ix;
2181 else
2182 return NULL;
2185 if (bt != -1) {
2186 if (REG_GPR & ~bx)
2187 return NULL; /* Invalid register */
2188 if (~sok & bx & SIZE_MASK)
2189 return NULL; /* Invalid size */
2190 sok &= bx;
2193 /* While we're here, ensure the user didn't specify
2194 WORD or QWORD. */
2195 if (input->disp_size == 16 || input->disp_size == 64)
2196 return NULL;
2198 if (addrbits == 16 ||
2199 (addrbits == 32 && !(sok & BITS32)) ||
2200 (addrbits == 64 && !(sok & BITS64)))
2201 return NULL;
2203 /* now reorganize base/index */
2204 if (s == 1 && bt != it && bt != -1 && it != -1 &&
2205 ((hb == b && ht == EAH_NOTBASE)
2206 || (hb == i && ht == EAH_MAKEBASE))) {
2207 /* swap if hints say so */
2208 t = bt, bt = it, it = t;
2209 t = bx, bx = ix, ix = t;
2211 if (bt == it) /* convert EAX+2*EAX to 3*EAX */
2212 bt = -1, bx = 0, s++;
2213 if (bt == -1 && s == 1 && !(hb == it && ht == EAH_NOTBASE)) {
2214 /* make single reg base, unless hint */
2215 bt = it, bx = ix, it = -1, ix = 0;
2217 if (((s == 2 && it != REG_NUM_ESP
2218 && !(input->eaflags & EAF_TIMESTWO)) || s == 3
2219 || s == 5 || s == 9) && bt == -1)
2220 bt = it, bx = ix, s--; /* convert 3*EAX to EAX+2*EAX */
2221 if (it == -1 && (bt & 7) != REG_NUM_ESP
2222 && (input->eaflags & EAF_TIMESTWO))
2223 it = bt, ix = bx, bt = -1, bx = 0, s = 1;
2224 /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */
2225 if (s == 1 && it == REG_NUM_ESP) {
2226 /* swap ESP into base if scale is 1 */
2227 t = it, it = bt, bt = t;
2228 t = ix, ix = bx, bx = t;
2230 if (it == REG_NUM_ESP
2231 || (s != 1 && s != 2 && s != 4 && s != 8 && it != -1))
2232 return NULL; /* wrong, for various reasons */
2234 output->rex |= rexflags(it, ix, REX_X);
2235 output->rex |= rexflags(bt, bx, REX_B);
2237 if (it == -1 && (bt & 7) != REG_NUM_ESP) {
2238 /* no SIB needed */
2239 int mod, rm;
2241 if (bt == -1) {
2242 rm = 5;
2243 mod = 0;
2244 } else {
2245 rm = (bt & 7);
2246 if (rm != REG_NUM_EBP && o == 0 &&
2247 seg == NO_SEG && !forw_ref &&
2248 !(input->eaflags &
2249 (EAF_BYTEOFFS | EAF_WORDOFFS)))
2250 mod = 0;
2251 else if (input->eaflags & EAF_BYTEOFFS ||
2252 (o >= -128 && o <= 127 && seg == NO_SEG
2253 && !forw_ref
2254 && !(input->eaflags & EAF_WORDOFFS)))
2255 mod = 1;
2256 else
2257 mod = 2;
2260 output->sib_present = false;
2261 output->bytes = (bt == -1 || mod == 2 ? 4 : mod);
2262 output->modrm = (mod << 6) | ((rfield & 7) << 3) | rm;
2263 } else {
2264 /* we need a SIB */
2265 int mod, scale, index, base;
2267 if (it == -1)
2268 index = 4, s = 1;
2269 else
2270 index = (it & 7);
2272 switch (s) {
2273 case 1:
2274 scale = 0;
2275 break;
2276 case 2:
2277 scale = 1;
2278 break;
2279 case 4:
2280 scale = 2;
2281 break;
2282 case 8:
2283 scale = 3;
2284 break;
2285 default: /* then what the smeg is it? */
2286 return NULL; /* panic */
2289 if (bt == -1) {
2290 base = 5;
2291 mod = 0;
2292 } else {
2293 base = (bt & 7);
2294 if (base != REG_NUM_EBP && o == 0 &&
2295 seg == NO_SEG && !forw_ref &&
2296 !(input->eaflags &
2297 (EAF_BYTEOFFS | EAF_WORDOFFS)))
2298 mod = 0;
2299 else if (input->eaflags & EAF_BYTEOFFS ||
2300 (o >= -128 && o <= 127 && seg == NO_SEG
2301 && !forw_ref
2302 && !(input->eaflags & EAF_WORDOFFS)))
2303 mod = 1;
2304 else
2305 mod = 2;
2308 output->sib_present = true;
2309 output->bytes = (bt == -1 || mod == 2 ? 4 : mod);
2310 output->modrm = (mod << 6) | ((rfield & 7) << 3) | 4;
2311 output->sib = (scale << 6) | (index << 3) | base;
2313 } else { /* it's 16-bit */
2314 int mod, rm;
2316 /* check for 64-bit long mode */
2317 if (addrbits == 64)
2318 return NULL;
2320 /* check all registers are BX, BP, SI or DI */
2321 if ((b != -1 && b != R_BP && b != R_BX && b != R_SI
2322 && b != R_DI) || (i != -1 && i != R_BP && i != R_BX
2323 && i != R_SI && i != R_DI))
2324 return NULL;
2326 /* ensure the user didn't specify DWORD/QWORD */
2327 if (input->disp_size == 32 || input->disp_size == 64)
2328 return NULL;
2330 if (s != 1 && i != -1)
2331 return NULL; /* no can do, in 16-bit EA */
2332 if (b == -1 && i != -1) {
2333 int tmp = b;
2334 b = i;
2335 i = tmp;
2336 } /* swap */
2337 if ((b == R_SI || b == R_DI) && i != -1) {
2338 int tmp = b;
2339 b = i;
2340 i = tmp;
2342 /* have BX/BP as base, SI/DI index */
2343 if (b == i)
2344 return NULL; /* shouldn't ever happen, in theory */
2345 if (i != -1 && b != -1 &&
2346 (i == R_BP || i == R_BX || b == R_SI || b == R_DI))
2347 return NULL; /* invalid combinations */
2348 if (b == -1) /* pure offset: handled above */
2349 return NULL; /* so if it gets to here, panic! */
2351 rm = -1;
2352 if (i != -1)
2353 switch (i * 256 + b) {
2354 case R_SI * 256 + R_BX:
2355 rm = 0;
2356 break;
2357 case R_DI * 256 + R_BX:
2358 rm = 1;
2359 break;
2360 case R_SI * 256 + R_BP:
2361 rm = 2;
2362 break;
2363 case R_DI * 256 + R_BP:
2364 rm = 3;
2365 break;
2366 } else
2367 switch (b) {
2368 case R_SI:
2369 rm = 4;
2370 break;
2371 case R_DI:
2372 rm = 5;
2373 break;
2374 case R_BP:
2375 rm = 6;
2376 break;
2377 case R_BX:
2378 rm = 7;
2379 break;
2381 if (rm == -1) /* can't happen, in theory */
2382 return NULL; /* so panic if it does */
2384 if (o == 0 && seg == NO_SEG && !forw_ref && rm != 6 &&
2385 !(input->eaflags & (EAF_BYTEOFFS | EAF_WORDOFFS)))
2386 mod = 0;
2387 else if (input->eaflags & EAF_BYTEOFFS ||
2388 (o >= -128 && o <= 127 && seg == NO_SEG
2389 && !forw_ref
2390 && !(input->eaflags & EAF_WORDOFFS)))
2391 mod = 1;
2392 else
2393 mod = 2;
2395 output->sib_present = false; /* no SIB - it's 16-bit */
2396 output->bytes = mod; /* bytes of offset needed */
2397 output->modrm = (mod << 6) | ((rfield & 7) << 3) | rm;
2402 output->size = 1 + output->sib_present + output->bytes;
2403 return output;
2406 static void add_asp(insn *ins, int addrbits)
2408 int j, valid;
2409 int defdisp;
2411 valid = (addrbits == 64) ? 64|32 : 32|16;
2413 switch (ins->prefixes[PPS_ASIZE]) {
2414 case P_A16:
2415 valid &= 16;
2416 break;
2417 case P_A32:
2418 valid &= 32;
2419 break;
2420 case P_A64:
2421 valid &= 64;
2422 break;
2423 case P_ASP:
2424 valid &= (addrbits == 32) ? 16 : 32;
2425 break;
2426 default:
2427 break;
2430 for (j = 0; j < ins->operands; j++) {
2431 if (!(MEMORY & ~ins->oprs[j].type)) {
2432 int32_t i, b;
2434 /* Verify as Register */
2435 if (ins->oprs[j].indexreg < EXPR_REG_START
2436 || ins->oprs[j].indexreg >= REG_ENUM_LIMIT)
2437 i = 0;
2438 else
2439 i = nasm_reg_flags[ins->oprs[j].indexreg];
2441 /* Verify as Register */
2442 if (ins->oprs[j].basereg < EXPR_REG_START
2443 || ins->oprs[j].basereg >= REG_ENUM_LIMIT)
2444 b = 0;
2445 else
2446 b = nasm_reg_flags[ins->oprs[j].basereg];
2448 if (ins->oprs[j].scale == 0)
2449 i = 0;
2451 if (!i && !b) {
2452 int ds = ins->oprs[j].disp_size;
2453 if ((addrbits != 64 && ds > 8) ||
2454 (addrbits == 64 && ds == 16))
2455 valid &= ds;
2456 } else {
2457 if (!(REG16 & ~b))
2458 valid &= 16;
2459 if (!(REG32 & ~b))
2460 valid &= 32;
2461 if (!(REG64 & ~b))
2462 valid &= 64;
2464 if (!(REG16 & ~i))
2465 valid &= 16;
2466 if (!(REG32 & ~i))
2467 valid &= 32;
2468 if (!(REG64 & ~i))
2469 valid &= 64;
2474 if (valid & addrbits) {
2475 ins->addr_size = addrbits;
2476 } else if (valid & ((addrbits == 32) ? 16 : 32)) {
2477 /* Add an address size prefix */
2478 enum prefixes pref = (addrbits == 32) ? P_A16 : P_A32;
2479 ins->prefixes[PPS_ASIZE] = pref;
2480 ins->addr_size = (addrbits == 32) ? 16 : 32;
2481 } else {
2482 /* Impossible... */
2483 errfunc(ERR_NONFATAL, "impossible combination of address sizes");
2484 ins->addr_size = addrbits; /* Error recovery */
2487 defdisp = ins->addr_size == 16 ? 16 : 32;
2489 for (j = 0; j < ins->operands; j++) {
2490 if (!(MEM_OFFS & ~ins->oprs[j].type) &&
2491 (ins->oprs[j].disp_size ? ins->oprs[j].disp_size : defdisp)
2492 != ins->addr_size) {
2493 /* mem_offs sizes must match the address size; if not,
2494 strip the MEM_OFFS bit and match only EA instructions */
2495 ins->oprs[j].type &= ~(MEM_OFFS & ~MEMORY);