Fix some MMX/SSE irregularities which interact with the 64-bit support
[nasm/avx512.git] / assemble.c
blob575103abfefcba7f95a62c1623b61a3db33e65cc
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 licence given in the file "Licence"
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, \11, \12 - a literal byte follows in the code stream, to be added
16 * to the register value of operand 0, 1 or 2
17 * \17 - encodes the literal byte 0. (Some compilers don't take
18 * kindly to a zero byte in the _middle_ of a compile time
19 * string constant, so I had to put this hack in.)
20 * \14, \15, \16 - a signed byte immediate operand, from operand 0, 1 or 2
21 * \20, \21, \22 - a byte immediate operand, from operand 0, 1 or 2
22 * \24, \25, \26 - an unsigned byte immediate operand, from operand 0, 1 or 2
23 * \30, \31, \32 - a word immediate operand, from operand 0, 1 or 2
24 * \34, \35, \36 - select between \3[012] and \4[012] depending on 16/32 bit
25 * assembly mode or the operand-size override on the operand
26 * \37 - a word constant, from the _segment_ part of operand 0
27 * \40, \41, \42 - a long immediate operand, from operand 0, 1 or 2
28 * \44, \45, \46 - select between \3[012], \4[012] and \5[456]
29 * depending on assembly mode or the address-size override
30 * on the operand.
31 * \50, \51, \52 - a byte relative operand, from operand 0, 1 or 2
32 * \54, \55, \56 - a qword immediate operand, from operand 0, 1 or 2
33 * \60, \61, \62 - a word relative operand, from operand 0, 1 or 2
34 * \64, \65, \66 - select between \6[012] and \7[012] depending on 16/32 bit
35 * assembly mode or the operand-size override on the operand
36 * \70, \71, \72 - a long relative operand, from operand 0, 1 or 2
37 * \1ab - a ModRM, calculated on EA in operand a, with the spare
38 * field the register value of operand b.
39 * \130,\131,\132 - an immediate word or signed byte for operand 0, 1, or 2
40 * \133,\134,\135 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
41 * is a signed byte rather than a word.
42 * \140,\141,\142 - an immediate dword or signed byte for operand 0, 1, or 2
43 * \143,\144,\145 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
44 * is a signed byte rather than a dword.
45 * \150,\151,\152 - an immediate qword or signed byte for operand 0, 1, or 2
46 * \153,\154,\155 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
47 * is a signed byte rather than a qword.
48 * \2ab - a ModRM, calculated on EA in operand a, with the spare
49 * field equal to digit b.
50 * \30x - might be an 0x67 byte, depending on the address size of
51 * the memory reference in operand x.
52 * \310 - indicates fixed 16-bit address size, i.e. optional 0x67.
53 * \311 - indicates fixed 32-bit address size, i.e. optional 0x67.
54 * \312 - (disassembler only) marker on LOOP, LOOPxx instructions.
55 * \313 - indicates fixed 64-bit address size, 0x67 invalid.
56 * \320 - indicates fixed 16-bit operand size, i.e. optional 0x66.
57 * \321 - indicates fixed 32-bit operand size, i.e. optional 0x66.
58 * \322 - indicates that this instruction is only valid when the
59 * operand size is the default (instruction to disassembler,
60 * generates no code in the assembler)
61 * \323 - indicates fixed 64-bit operand size, REX on extensions only.
62 * \324 - indicates 64-bit operand size requiring REX prefix.
63 * \330 - a literal byte follows in the code stream, to be added
64 * to the condition code value of the instruction.
65 * \331 - instruction not valid with REP prefix. Hint for
66 * disassembler only; for SSE instructions.
67 * \332 - disassemble a rep (0xF3 byte) prefix as repe not rep.
68 * \333 - REP prefix (0xF3 byte); for SSE instructions. Not encoded
69 * as a literal byte in order to aid the disassembler.
70 * \334 - LOCK prefix used instead of REX.R
71 * \340 - reserve <operand 0> bytes of uninitialized storage.
72 * Operand 0 had better be a segmentless constant.
73 * \366 - operand-size override prefix (0x66); to ensure proper
74 REX prefix placement.
75 * \370,\371,\372 - match only if operand 0 meets byte jump criteria.
76 * 370 is used for Jcc, 371 is used for JMP.
77 * \373 - assemble 0x03 if bits==16, 0x05 if bits==32;
78 * used for conditional jump over longer jump
81 #include <stdio.h>
82 #include <string.h>
83 #include <inttypes.h>
85 #include "nasm.h"
86 #include "nasmlib.h"
87 #include "assemble.h"
88 #include "insns.h"
89 #include "preproc.h"
90 #include "regflags.c"
91 #include "regvals.c"
93 extern struct itemplate *nasm_instructions[];
95 typedef struct {
96 int sib_present; /* is a SIB byte necessary? */
97 int bytes; /* # of bytes of offset needed */
98 int size; /* lazy - this is sib+bytes+1 */
99 uint8_t modrm, sib, rex, rip; /* the bytes themselves */
100 } ea;
102 static uint32_t cpu; /* cpu level received from nasm.c */
103 static efunc errfunc;
104 static struct ofmt *outfmt;
105 static ListGen *list;
107 static int32_t calcsize(int32_t, int32_t, int, insn *, const char *);
108 static void gencode(int32_t, int32_t, int, insn *, const char *, int32_t);
109 static int matches(struct itemplate *, insn *, int bits);
110 static int32_t regflag(const operand *);
111 static int32_t regval(const operand *);
112 static int rexflags(int, int32_t, int);
113 static int op_rexflags(const operand *, int);
114 static ea *process_ea(operand *, ea *, int, int, int32_t, int);
115 static int chsize(operand *, int);
117 static void assert_no_prefix(insn * ins, int prefix)
119 int j;
121 for (j = 0; j < ins->nprefix; j++) {
122 if (ins->prefixes[j] == prefix) {
123 errfunc(ERR_NONFATAL, "invalid %s prefix", prefix_name(prefix));
124 break;
130 * This routine wrappers the real output format's output routine,
131 * in order to pass a copy of the data off to the listing file
132 * generator at the same time.
134 static void out(int32_t offset, int32_t segto, const void *data,
135 uint32_t type, int32_t segment, int32_t wrt)
137 static int32_t lineno = 0; /* static!!! */
138 static char *lnfname = NULL;
140 if ((type & OUT_TYPMASK) == OUT_ADDRESS) {
141 if (segment != NO_SEG || wrt != NO_SEG) {
143 * This address is relocated. We must write it as
144 * OUT_ADDRESS, so there's no work to be done here.
146 list->output(offset, data, type);
147 } else {
148 uint8_t p[8], *q = p;
150 * This is a non-relocated address, and we're going to
151 * convert it into RAWDATA format.
153 if ((type & OUT_SIZMASK) == 4) {
154 WRITELONG(q, *(int32_t *)data);
155 list->output(offset, p, OUT_RAWDATA + 4);
156 } else if ((type & OUT_SIZMASK) == 8) {
157 WRITEDLONG(q, *(int64_t *)data);
158 list->output(offset, p, OUT_RAWDATA + 8);
159 } else {
160 WRITESHORT(q, *(int32_t *)data);
161 list->output(offset, p, OUT_RAWDATA + 2);
164 } else if ((type & OUT_TYPMASK) == OUT_RAWDATA) {
165 list->output(offset, data, type);
166 } else if ((type & OUT_TYPMASK) == OUT_RESERVE) {
167 list->output(offset, NULL, type);
168 } else if ((type & OUT_TYPMASK) == OUT_REL2ADR ||
169 (type & OUT_TYPMASK) == OUT_REL4ADR) {
170 list->output(offset, data, type);
174 * this call to src_get determines when we call the
175 * debug-format-specific "linenum" function
176 * it updates lineno and lnfname to the current values
177 * returning 0 if "same as last time", -2 if lnfname
178 * changed, and the amount by which lineno changed,
179 * if it did. thus, these variables must be static
182 if (src_get(&lineno, &lnfname)) {
183 outfmt->current_dfmt->linenum(lnfname, lineno, segto);
186 outfmt->output(segto, data, type, segment, wrt);
189 static int jmp_match(int32_t segment, int32_t offset, int bits,
190 insn * ins, const char *code)
192 int32_t isize;
193 uint8_t c = code[0];
195 if (c != 0370 && c != 0371)
196 return 0;
197 if (ins->oprs[0].opflags & OPFLAG_FORWARD) {
198 if ((optimizing < 0 || (ins->oprs[0].type & STRICT))
199 && c == 0370)
200 return 1;
201 else
202 return (pass0 == 0); /* match a forward reference */
204 isize = calcsize(segment, offset, bits, ins, code);
205 if (ins->oprs[0].segment != segment)
206 return 0;
207 isize = ins->oprs[0].offset - offset - isize; /* isize is now the delta */
208 if (isize >= -128L && isize <= 127L)
209 return 1; /* it is byte size */
211 return 0;
214 int32_t assemble(int32_t segment, int32_t offset, int bits, uint32_t cp,
215 insn * instruction, struct ofmt *output, efunc error,
216 ListGen * listgen)
218 struct itemplate *temp;
219 int j;
220 int size_prob;
221 int32_t insn_end;
222 int32_t itimes;
223 int32_t start = offset;
224 int32_t wsize = 0; /* size for DB etc. */
226 errfunc = error; /* to pass to other functions */
227 cpu = cp;
228 outfmt = output; /* likewise */
229 list = listgen; /* and again */
231 switch (instruction->opcode) {
232 case -1:
233 return 0;
234 case I_DB:
235 wsize = 1;
236 break;
237 case I_DW:
238 wsize = 2;
239 break;
240 case I_DD:
241 wsize = 4;
242 break;
243 case I_DQ:
244 wsize = 8;
245 break;
246 case I_DT:
247 wsize = 10;
248 break;
251 if (wsize) {
252 extop *e;
253 int32_t t = instruction->times;
254 if (t < 0)
255 errfunc(ERR_PANIC,
256 "instruction->times < 0 (%ld) in assemble()", t);
258 while (t--) { /* repeat TIMES times */
259 for (e = instruction->eops; e; e = e->next) {
260 if (e->type == EOT_DB_NUMBER) {
261 if (wsize == 1) {
262 if (e->segment != NO_SEG)
263 errfunc(ERR_NONFATAL,
264 "one-byte relocation attempted");
265 else {
266 uint8_t out_byte = e->offset;
267 out(offset, segment, &out_byte,
268 OUT_RAWDATA + 1, NO_SEG, NO_SEG);
270 } else if (wsize > 8) {
271 errfunc(ERR_NONFATAL, "integer supplied to a DT"
272 " instruction");
273 } else
274 out(offset, segment, &e->offset,
275 OUT_ADDRESS + wsize, e->segment, e->wrt);
276 offset += wsize;
277 } else if (e->type == EOT_DB_STRING) {
278 int align;
280 out(offset, segment, e->stringval,
281 OUT_RAWDATA + e->stringlen, NO_SEG, NO_SEG);
282 align = e->stringlen % wsize;
284 if (align) {
285 align = wsize - align;
286 out(offset, segment, "\0\0\0\0\0\0\0\0",
287 OUT_RAWDATA + align, NO_SEG, NO_SEG);
289 offset += e->stringlen + align;
292 if (t > 0 && t == instruction->times - 1) {
294 * Dummy call to list->output to give the offset to the
295 * listing module.
297 list->output(offset, NULL, OUT_RAWDATA);
298 list->uplevel(LIST_TIMES);
301 if (instruction->times > 1)
302 list->downlevel(LIST_TIMES);
303 return offset - start;
306 if (instruction->opcode == I_INCBIN) {
307 static char fname[FILENAME_MAX];
308 FILE *fp;
309 int32_t len;
310 char *prefix = "", *combine;
311 char **pPrevPath = NULL;
313 len = FILENAME_MAX - 1;
314 if (len > instruction->eops->stringlen)
315 len = instruction->eops->stringlen;
316 strncpy(fname, instruction->eops->stringval, len);
317 fname[len] = '\0';
319 while (1) { /* added by alexfru: 'incbin' uses include paths */
320 combine = nasm_malloc(strlen(prefix) + len + 1);
321 strcpy(combine, prefix);
322 strcat(combine, fname);
324 if ((fp = fopen(combine, "rb")) != NULL) {
325 nasm_free(combine);
326 break;
329 nasm_free(combine);
330 pPrevPath = pp_get_include_path_ptr(pPrevPath);
331 if (pPrevPath == NULL)
332 break;
333 prefix = *pPrevPath;
336 if (fp == NULL)
337 error(ERR_NONFATAL, "`incbin': unable to open file `%s'",
338 fname);
339 else if (fseek(fp, 0L, SEEK_END) < 0)
340 error(ERR_NONFATAL, "`incbin': unable to seek on file `%s'",
341 fname);
342 else {
343 static char buf[2048];
344 int32_t t = instruction->times;
345 int32_t base = 0;
347 len = ftell(fp);
348 if (instruction->eops->next) {
349 base = instruction->eops->next->offset;
350 len -= base;
351 if (instruction->eops->next->next &&
352 len > instruction->eops->next->next->offset)
353 len = instruction->eops->next->next->offset;
356 * Dummy call to list->output to give the offset to the
357 * listing module.
359 list->output(offset, NULL, OUT_RAWDATA);
360 list->uplevel(LIST_INCBIN);
361 while (t--) {
362 int32_t l;
364 fseek(fp, base, SEEK_SET);
365 l = len;
366 while (l > 0) {
367 int32_t m =
368 fread(buf, 1, (l > sizeof(buf) ? sizeof(buf) : l),
369 fp);
370 if (!m) {
372 * This shouldn't happen unless the file
373 * actually changes while we are reading
374 * it.
376 error(ERR_NONFATAL,
377 "`incbin': unexpected EOF while"
378 " reading file `%s'", fname);
379 t = 0; /* Try to exit cleanly */
380 break;
382 out(offset, segment, buf, OUT_RAWDATA + m,
383 NO_SEG, NO_SEG);
384 l -= m;
387 list->downlevel(LIST_INCBIN);
388 if (instruction->times > 1) {
390 * Dummy call to list->output to give the offset to the
391 * listing module.
393 list->output(offset, NULL, OUT_RAWDATA);
394 list->uplevel(LIST_TIMES);
395 list->downlevel(LIST_TIMES);
397 fclose(fp);
398 return instruction->times * len;
400 return 0; /* if we're here, there's an error */
403 size_prob = FALSE;
405 for (temp = nasm_instructions[instruction->opcode]; temp->opcode != -1; temp++){
406 int m = matches(temp, instruction, bits);
408 if (m == 99)
409 m += jmp_match(segment, offset, bits, instruction, temp->code);
411 if (m == 100) { /* matches! */
412 const char *codes = temp->code;
413 int32_t insn_size = calcsize(segment, offset, bits,
414 instruction, codes);
415 itimes = instruction->times;
416 if (insn_size < 0) /* shouldn't be, on pass two */
417 error(ERR_PANIC, "errors made it through from pass one");
418 else
419 while (itimes--) {
420 for (j = 0; j < instruction->nprefix; j++) {
421 uint8_t c = 0;
422 switch (instruction->prefixes[j]) {
423 case P_LOCK:
424 c = 0xF0;
425 break;
426 case P_REPNE:
427 case P_REPNZ:
428 c = 0xF2;
429 break;
430 case P_REPE:
431 case P_REPZ:
432 case P_REP:
433 c = 0xF3;
434 break;
435 case R_CS:
436 if (bits == 64) {
437 error(ERR_WARNING,
438 "cs segment base ignored in 64-bit mode");
440 c = 0x2E;
441 break;
442 case R_DS:
443 if (bits == 64) {
444 error(ERR_WARNING,
445 "ds segment base ignored in 64-bit mode");
447 c = 0x3E;
448 break;
449 case R_ES:
450 if (bits == 64) {
451 error(ERR_WARNING,
452 "es segment base ignored in 64-bit mode");
454 c = 0x26;
455 break;
456 case R_FS:
457 c = 0x64;
458 break;
459 case R_GS:
460 c = 0x65;
461 break;
462 case R_SS:
463 if (bits == 64) {
464 error(ERR_WARNING,
465 "ss segment base ignored in 64-bit mode");
467 c = 0x36;
468 break;
469 case R_SEGR6:
470 case R_SEGR7:
471 error(ERR_NONFATAL,
472 "segr6 and segr7 cannot be used as prefixes");
473 break;
474 case P_A16:
475 if (bits == 64) {
476 error(ERR_NONFATAL,
477 "16-bit addressing is not supported "
478 "in 64-bit mode");
479 break;
481 if (bits != 16)
482 c = 0x67;
483 break;
484 case P_A32:
485 if (bits != 32)
486 c = 0x67;
487 break;
488 case P_O16:
489 if (bits != 16)
490 c = 0x66;
491 break;
492 case P_O32:
493 if (bits == 16)
494 c = 0x66;
495 break;
496 default:
497 error(ERR_PANIC, "invalid instruction prefix");
499 if (c != 0) {
500 out(offset, segment, &c, OUT_RAWDATA + 1,
501 NO_SEG, NO_SEG);
502 offset++;
505 insn_end = offset + insn_size;
506 gencode(segment, offset, bits, instruction, codes,
507 insn_end);
508 offset += insn_size;
509 if (itimes > 0 && itimes == instruction->times - 1) {
511 * Dummy call to list->output to give the offset to the
512 * listing module.
514 list->output(offset, NULL, OUT_RAWDATA);
515 list->uplevel(LIST_TIMES);
518 if (instruction->times > 1)
519 list->downlevel(LIST_TIMES);
520 return offset - start;
521 } else if (m > 0 && m > size_prob) {
522 size_prob = m;
524 // temp++;
527 if (temp->opcode == -1) { /* didn't match any instruction */
528 switch (size_prob) {
529 case 1:
530 error(ERR_NONFATAL, "operation size not specified");
531 break;
532 case 2:
533 error(ERR_NONFATAL, "mismatch in operand sizes");
534 break;
535 case 3:
536 error(ERR_NONFATAL, "no instruction for this cpu level");
537 break;
538 case 4:
539 error(ERR_NONFATAL, "instruction not supported in 64-bit mode");
540 break;
541 default:
542 error(ERR_NONFATAL,
543 "invalid combination of opcode and operands");
544 break;
547 return 0;
550 int32_t insn_size(int32_t segment, int32_t offset, int bits, uint32_t cp,
551 insn * instruction, efunc error)
553 struct itemplate *temp;
555 errfunc = error; /* to pass to other functions */
556 cpu = cp;
558 if (instruction->opcode == -1)
559 return 0;
561 if (instruction->opcode == I_DB ||
562 instruction->opcode == I_DW ||
563 instruction->opcode == I_DD ||
564 instruction->opcode == I_DQ || instruction->opcode == I_DT) {
565 extop *e;
566 int32_t isize, osize, wsize = 0; /* placate gcc */
568 isize = 0;
569 switch (instruction->opcode) {
570 case I_DB:
571 wsize = 1;
572 break;
573 case I_DW:
574 wsize = 2;
575 break;
576 case I_DD:
577 wsize = 4;
578 break;
579 case I_DQ:
580 wsize = 8;
581 break;
582 case I_DT:
583 wsize = 10;
584 break;
587 for (e = instruction->eops; e; e = e->next) {
588 int32_t align;
590 osize = 0;
591 if (e->type == EOT_DB_NUMBER)
592 osize = 1;
593 else if (e->type == EOT_DB_STRING)
594 osize = e->stringlen;
596 align = (-osize) % wsize;
597 if (align < 0)
598 align += wsize;
599 isize += osize + align;
601 return isize * instruction->times;
604 if (instruction->opcode == I_INCBIN) {
605 char fname[FILENAME_MAX];
606 FILE *fp;
607 int32_t len;
608 char *prefix = "", *combine;
609 char **pPrevPath = NULL;
611 len = FILENAME_MAX - 1;
612 if (len > instruction->eops->stringlen)
613 len = instruction->eops->stringlen;
614 strncpy(fname, instruction->eops->stringval, len);
615 fname[len] = '\0';
617 while (1) { /* added by alexfru: 'incbin' uses include paths */
618 combine = nasm_malloc(strlen(prefix) + len + 1);
619 strcpy(combine, prefix);
620 strcat(combine, fname);
622 if ((fp = fopen(combine, "rb")) != NULL) {
623 nasm_free(combine);
624 break;
627 nasm_free(combine);
628 pPrevPath = pp_get_include_path_ptr(pPrevPath);
629 if (pPrevPath == NULL)
630 break;
631 prefix = *pPrevPath;
634 if (fp == NULL)
635 error(ERR_NONFATAL, "`incbin': unable to open file `%s'",
636 fname);
637 else if (fseek(fp, 0L, SEEK_END) < 0)
638 error(ERR_NONFATAL, "`incbin': unable to seek on file `%s'",
639 fname);
640 else {
641 len = ftell(fp);
642 fclose(fp);
643 if (instruction->eops->next) {
644 len -= instruction->eops->next->offset;
645 if (instruction->eops->next->next &&
646 len > instruction->eops->next->next->offset) {
647 len = instruction->eops->next->next->offset;
650 return instruction->times * len;
652 return 0; /* if we're here, there's an error */
655 for (temp = nasm_instructions[instruction->opcode]; temp->opcode != -1; temp++) {
656 int m = matches(temp, instruction, bits);
657 if (m == 99)
658 m += jmp_match(segment, offset, bits, instruction, temp->code);
660 if (m == 100) {
661 /* we've matched an instruction. */
662 int32_t isize;
663 const char *codes = temp->code;
664 int j;
666 isize = calcsize(segment, offset, bits, instruction, codes);
667 if (isize < 0)
668 return -1;
669 for (j = 0; j < instruction->nprefix; j++) {
670 if ((instruction->prefixes[j] != P_A16 &&
671 instruction->prefixes[j] != P_O16 && bits == 16) ||
672 (instruction->prefixes[j] != P_A32 &&
673 instruction->prefixes[j] != P_O32 && bits >= 32)) {
674 isize++;
677 return isize * instruction->times;
680 return -1; /* didn't match any instruction */
683 /* check that opn[op] is a signed byte of size 16 or 32,
684 and return the signed value*/
685 static int is_sbyte(insn * ins, int op, int size)
687 int32_t v;
688 int ret;
690 ret = !(ins->forw_ref && ins->oprs[op].opflags) && /* dead in the water on forward reference or External */
691 optimizing >= 0 &&
692 !(ins->oprs[op].type & STRICT) &&
693 ins->oprs[op].wrt == NO_SEG && ins->oprs[op].segment == NO_SEG;
695 v = ins->oprs[op].offset;
696 if (size == 16)
697 v = (int16_t)v; /* sign extend if 16 bits */
699 return ret && v >= -128L && v <= 127L;
702 static int32_t calcsize(int32_t segment, int32_t offset, int bits,
703 insn * ins, const char *codes)
705 int32_t length = 0;
706 uint8_t c;
707 int rex_mask = ~0;
708 ins->rex = 0; /* Ensure REX is reset */
710 (void)segment; /* Don't warn that this parameter is unused */
711 (void)offset; /* Don't warn that this parameter is unused */
713 while (*codes)
714 switch (c = *codes++) {
715 case 01:
716 case 02:
717 case 03:
718 codes += c, length += c;
719 break;
720 case 04:
721 case 05:
722 case 06:
723 case 07:
724 length++;
725 break;
726 case 010:
727 case 011:
728 case 012:
729 ins->rex |=
730 op_rexflags(&ins->oprs[c - 010], REX_B|REX_H|REX_P|REX_W);
731 codes++, length++;
732 break;
733 case 017:
734 length++;
735 break;
736 case 014:
737 case 015:
738 case 016:
739 length++;
740 break;
741 case 020:
742 case 021:
743 case 022:
744 length++;
745 break;
746 case 024:
747 case 025:
748 case 026:
749 length++;
750 break;
751 case 030:
752 case 031:
753 case 032:
754 length += 2;
755 break;
756 case 034:
757 case 035:
758 case 036:
759 if (ins->oprs[c - 034].type & (BITS16 | BITS32 | BITS64))
760 length += (ins->oprs[c - 034].type & BITS16) ? 2 : 4;
761 else
762 length += (bits == 16) ? 2 : 4;
763 break;
764 case 037:
765 length += 2;
766 break;
767 case 040:
768 case 041:
769 case 042:
770 length += 4;
771 break;
772 case 044:
773 case 045:
774 case 046:
775 length += ((ins->oprs[c - 044].addr_size ?
776 ins->oprs[c - 044].addr_size : bits) >> 3);
777 break;
778 case 050:
779 case 051:
780 case 052:
781 length++;
782 break;
783 case 054:
784 case 055:
785 case 056:
786 length += 8; /* MOV reg64/imm */
787 break;
788 case 060:
789 case 061:
790 case 062:
791 length += 2;
792 break;
793 case 064:
794 case 065:
795 case 066:
796 if (ins->oprs[c - 064].type & (BITS16 | BITS32 | BITS64))
797 length += (ins->oprs[c - 064].type & BITS16) ? 2 : 4;
798 else
799 length += (bits == 16) ? 2 : 4;
800 break;
801 case 070:
802 case 071:
803 case 072:
804 length += 4;
805 break;
806 case 0130:
807 case 0131:
808 case 0132:
809 length += is_sbyte(ins, c - 0130, 16) ? 1 : 2;
810 break;
811 case 0133:
812 case 0134:
813 case 0135:
814 codes += 2;
815 length++;
816 break;
817 case 0140:
818 case 0141:
819 case 0142:
820 length += is_sbyte(ins, c - 0140, 32) ? 1 : 4;
821 break;
822 case 0143:
823 case 0144:
824 case 0145:
825 codes += 2;
826 length++;
827 break;
828 case 0300:
829 case 0301:
830 case 0302:
831 length += chsize(&ins->oprs[c - 0300], bits);
832 break;
833 case 0310:
834 length += (bits != 16);
835 break;
836 case 0311:
837 length += (bits != 32);
838 break;
839 case 0312:
840 break;
841 case 0313:
842 break;
843 case 0320:
844 length += (bits != 16);
845 break;
846 case 0321:
847 length += (bits == 16);
848 break;
849 case 0322:
850 break;
851 case 0323:
852 rex_mask &= ~REX_W;
853 break;
854 case 0324:
855 ins->rex |= REX_W;
856 break;
857 case 0330:
858 codes++, length++;
859 break;
860 case 0331:
861 case 0332:
862 break;
863 case 0333:
864 length++;
865 break;
866 case 0334:
867 assert_no_prefix(ins, P_LOCK);
868 ins->rex |= REX_L;
869 break;
870 case 0340:
871 case 0341:
872 case 0342:
873 if (ins->oprs[0].segment != NO_SEG)
874 errfunc(ERR_NONFATAL, "attempt to reserve non-constant"
875 " quantity of BSS space");
876 else
877 length += ins->oprs[0].offset << (c - 0340);
878 break;
879 case 0366:
880 length++;
881 break;
882 case 0370:
883 case 0371:
884 case 0372:
885 break;
886 case 0373:
887 length++;
888 break;
889 default: /* can't do it by 'case' statements */
890 if (c >= 0100 && c <= 0277) { /* it's an EA */
891 ea ea_data;
892 int rfield;
893 int32_t rflags;
894 ea_data.rex = 0; /* Ensure ea.REX is initially 0 */
896 if (c <= 0177) {
897 /* pick rfield from operand b */
898 rflags = regflag(&ins->oprs[c & 7]);
899 rfield = regvals[ins->oprs[c & 7].basereg];
900 } else {
901 rflags = 0;
902 rfield = c & 7;
905 if (!process_ea
906 (&ins->oprs[(c >> 3) & 7], &ea_data, bits,
907 rfield, rflags, ins->forw_ref)) {
908 errfunc(ERR_NONFATAL, "invalid effective address");
909 return -1;
910 } else {
911 ins->rex |= ea_data.rex;
912 length += ea_data.size;
914 } else
915 errfunc(ERR_PANIC, "internal instruction table corrupt"
916 ": instruction code 0x%02X given", c);
919 ins->rex &= rex_mask;
920 if (ins->rex & REX_REAL) {
921 if (ins->rex & REX_H) {
922 errfunc(ERR_NONFATAL, "cannot use high register in rex instruction");
923 return -1;
924 } else if (bits == 64 ||
925 ((ins->rex & REX_L) &&
926 !(ins->rex & (REX_P|REX_W|REX_X|REX_B)) &&
927 cpu >= IF_X86_64)) {
928 length++;
929 } else {
930 errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode");
931 return -1;
935 return length;
938 #define EMIT_REX() \
939 if((ins->rex & REX_REAL) && (bits == 64)) { \
940 ins->rex = (ins->rex & REX_REAL)|REX_P; \
941 out(offset, segment, &ins->rex, OUT_RAWDATA+1, NO_SEG, NO_SEG); \
942 ins->rex = 0; \
943 offset += 1; \
946 static void gencode(int32_t segment, int32_t offset, int bits,
947 insn * ins, const char *codes, int32_t insn_end)
949 static char condval[] = { /* conditional opcodes */
950 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
951 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
952 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
954 uint8_t c;
955 uint8_t bytes[4];
956 int32_t size;
957 int64_t data;
959 while (*codes)
960 switch (c = *codes++) {
961 case 01:
962 case 02:
963 case 03:
964 EMIT_REX();
965 out(offset, segment, codes, OUT_RAWDATA + c, NO_SEG, NO_SEG);
966 codes += c;
967 offset += c;
968 break;
970 case 04:
971 case 06:
972 switch (ins->oprs[0].basereg) {
973 case R_CS:
974 bytes[0] = 0x0E + (c == 0x04 ? 1 : 0);
975 break;
976 case R_DS:
977 bytes[0] = 0x1E + (c == 0x04 ? 1 : 0);
978 break;
979 case R_ES:
980 bytes[0] = 0x06 + (c == 0x04 ? 1 : 0);
981 break;
982 case R_SS:
983 bytes[0] = 0x16 + (c == 0x04 ? 1 : 0);
984 break;
985 default:
986 errfunc(ERR_PANIC,
987 "bizarre 8086 segment register received");
989 out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
990 offset++;
991 break;
993 case 05:
994 case 07:
995 switch (ins->oprs[0].basereg) {
996 case R_FS:
997 bytes[0] = 0xA0 + (c == 0x05 ? 1 : 0);
998 break;
999 case R_GS:
1000 bytes[0] = 0xA8 + (c == 0x05 ? 1 : 0);
1001 break;
1002 default:
1003 errfunc(ERR_PANIC,
1004 "bizarre 386 segment register received");
1006 out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
1007 offset++;
1008 break;
1010 case 010:
1011 case 011:
1012 case 012:
1013 EMIT_REX();
1014 bytes[0] = *codes++ + ((regval(&ins->oprs[c - 010])) & 7);
1015 out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
1016 offset += 1;
1017 break;
1019 case 017:
1020 bytes[0] = 0;
1021 out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
1022 offset += 1;
1023 break;
1025 case 014:
1026 case 015:
1027 case 016:
1028 if (ins->oprs[c - 014].offset < -128
1029 || ins->oprs[c - 014].offset > 127) {
1030 errfunc(ERR_WARNING, "signed byte value exceeds bounds");
1033 if (ins->oprs[c - 014].segment != NO_SEG) {
1034 data = ins->oprs[c - 014].offset;
1035 out(offset, segment, &data, OUT_ADDRESS + 1,
1036 ins->oprs[c - 014].segment, ins->oprs[c - 014].wrt);
1037 } else {
1038 bytes[0] = ins->oprs[c - 014].offset;
1039 out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
1040 NO_SEG);
1042 offset += 1;
1043 break;
1045 case 020:
1046 case 021:
1047 case 022:
1048 if (ins->oprs[c - 020].offset < -256
1049 || ins->oprs[c - 020].offset > 255) {
1050 errfunc(ERR_WARNING, "byte value exceeds bounds");
1052 if (ins->oprs[c - 020].segment != NO_SEG) {
1053 data = ins->oprs[c - 020].offset;
1054 out(offset, segment, &data, OUT_ADDRESS + 1,
1055 ins->oprs[c - 020].segment, ins->oprs[c - 020].wrt);
1056 } else {
1057 bytes[0] = ins->oprs[c - 020].offset;
1058 out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
1059 NO_SEG);
1061 offset += 1;
1062 break;
1064 case 024:
1065 case 025:
1066 case 026:
1067 if (ins->oprs[c - 024].offset < 0
1068 || ins->oprs[c - 024].offset > 255)
1069 errfunc(ERR_WARNING, "unsigned byte value exceeds bounds");
1070 if (ins->oprs[c - 024].segment != NO_SEG) {
1071 data = ins->oprs[c - 024].offset;
1072 out(offset, segment, &data, OUT_ADDRESS + 1,
1073 ins->oprs[c - 024].segment, ins->oprs[c - 024].wrt);
1074 } else {
1075 bytes[0] = ins->oprs[c - 024].offset;
1076 out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
1077 NO_SEG);
1079 offset += 1;
1080 break;
1082 case 030:
1083 case 031:
1084 case 032:
1085 if (ins->oprs[c - 030].segment == NO_SEG &&
1086 ins->oprs[c - 030].wrt == NO_SEG &&
1087 (ins->oprs[c - 030].offset < -65536L ||
1088 ins->oprs[c - 030].offset > 65535L)) {
1089 errfunc(ERR_WARNING, "word value exceeds bounds");
1091 data = ins->oprs[c - 030].offset;
1092 out(offset, segment, &data, OUT_ADDRESS + 2,
1093 ins->oprs[c - 030].segment, ins->oprs[c - 030].wrt);
1094 offset += 2;
1095 break;
1097 case 034:
1098 case 035:
1099 case 036:
1100 if (ins->oprs[c - 034].type & (BITS16 | BITS32))
1101 size = (ins->oprs[c - 034].type & BITS16) ? 2 : 4;
1102 else
1103 size = (bits == 16) ? 2 : 4;
1104 data = ins->oprs[c - 034].offset;
1105 if (size == 2 && (data < -65536L || data > 65535L))
1106 errfunc(ERR_WARNING, "word value exceeds bounds");
1107 out(offset, segment, &data, OUT_ADDRESS + size,
1108 ins->oprs[c - 034].segment, ins->oprs[c - 034].wrt);
1109 offset += size;
1110 break;
1112 case 037:
1113 if (ins->oprs[0].segment == NO_SEG)
1114 errfunc(ERR_NONFATAL, "value referenced by FAR is not"
1115 " relocatable");
1116 data = 0L;
1117 out(offset, segment, &data, OUT_ADDRESS + 2,
1118 outfmt->segbase(1 + ins->oprs[0].segment),
1119 ins->oprs[0].wrt);
1120 offset += 2;
1121 break;
1123 case 040:
1124 case 041:
1125 case 042:
1126 data = ins->oprs[c - 040].offset;
1127 out(offset, segment, &data, OUT_ADDRESS + 4,
1128 ins->oprs[c - 040].segment, ins->oprs[c - 040].wrt);
1129 offset += 4;
1130 break;
1132 case 044:
1133 case 045:
1134 case 046:
1135 data = ins->oprs[c - 044].offset;
1136 size = ((ins->oprs[c - 044].addr_size ?
1137 ins->oprs[c - 044].addr_size : bits) >> 3);
1138 if (size == 2 && (data < -65536L || data > 65535L))
1139 errfunc(ERR_WARNING, "word value exceeds bounds");
1140 out(offset, segment, &data, OUT_ADDRESS + size,
1141 ins->oprs[c - 044].segment, ins->oprs[c - 044].wrt);
1142 offset += size;
1143 break;
1145 case 050:
1146 case 051:
1147 case 052:
1148 if (ins->oprs[c - 050].segment != segment)
1149 errfunc(ERR_NONFATAL,
1150 "short relative jump outside segment");
1151 data = ins->oprs[c - 050].offset - insn_end;
1152 if (data > 127 || data < -128)
1153 errfunc(ERR_NONFATAL, "short jump is out of range");
1154 bytes[0] = data;
1155 out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
1156 offset += 1;
1157 break;
1159 case 054:
1160 case 055:
1161 case 056:
1162 data = (int64_t)ins->oprs[c - 054].offset;
1163 out(offset, segment, &data, OUT_ADDRESS + 8,
1164 ins->oprs[c - 054].segment, ins->oprs[c - 054].wrt);
1165 offset += 8;
1166 break;
1168 case 060:
1169 case 061:
1170 case 062:
1171 if (ins->oprs[c - 060].segment != segment) {
1172 data = ins->oprs[c - 060].offset;
1173 out(offset, segment, &data,
1174 OUT_REL2ADR + insn_end - offset,
1175 ins->oprs[c - 060].segment, ins->oprs[c - 060].wrt);
1176 } else {
1177 data = ins->oprs[c - 060].offset - insn_end;
1178 out(offset, segment, &data,
1179 OUT_ADDRESS + 2, NO_SEG, NO_SEG);
1181 offset += 2;
1182 break;
1184 case 064:
1185 case 065:
1186 case 066:
1187 if (ins->oprs[c - 064].type & (BITS16 | BITS32 | BITS64))
1188 size = (ins->oprs[c - 064].type & BITS16) ? 2 : 4;
1189 else
1190 size = (bits == 16) ? 2 : 4;
1191 if (ins->oprs[c - 064].segment != segment) {
1192 int32_t reltype = (size == 2 ? OUT_REL2ADR : OUT_REL4ADR);
1193 data = ins->oprs[c - 064].offset;
1194 out(offset, segment, &data, reltype + insn_end - offset,
1195 ins->oprs[c - 064].segment, ins->oprs[c - 064].wrt);
1196 } else {
1197 data = ins->oprs[c - 064].offset - insn_end;
1198 out(offset, segment, &data,
1199 OUT_ADDRESS + size, NO_SEG, NO_SEG);
1201 offset += size;
1202 break;
1204 case 070:
1205 case 071:
1206 case 072:
1207 if (ins->oprs[c - 070].segment != segment) {
1208 data = ins->oprs[c - 070].offset;
1209 out(offset, segment, &data,
1210 OUT_REL4ADR + insn_end - offset,
1211 ins->oprs[c - 070].segment, ins->oprs[c - 070].wrt);
1212 } else {
1213 data = ins->oprs[c - 070].offset - insn_end;
1214 out(offset, segment, &data,
1215 OUT_ADDRESS + 4, NO_SEG, NO_SEG);
1217 offset += 4;
1218 break;
1220 case 0130:
1221 case 0131:
1222 case 0132:
1223 data = ins->oprs[c - 0130].offset;
1224 if (is_sbyte(ins, c - 0130, 16)) {
1225 bytes[0] = data;
1226 out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
1227 NO_SEG);
1228 offset++;
1229 } else {
1230 if (ins->oprs[c - 0130].segment == NO_SEG &&
1231 ins->oprs[c - 0130].wrt == NO_SEG &&
1232 (data < -65536L || data > 65535L)) {
1233 errfunc(ERR_WARNING, "word value exceeds bounds");
1235 out(offset, segment, &data, OUT_ADDRESS + 2,
1236 ins->oprs[c - 0130].segment, ins->oprs[c - 0130].wrt);
1237 offset += 2;
1239 break;
1241 case 0133:
1242 case 0134:
1243 case 0135:
1244 EMIT_REX();
1245 codes++;
1246 bytes[0] = *codes++;
1247 if (is_sbyte(ins, c - 0133, 16))
1248 bytes[0] |= 2; /* s-bit */
1249 out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
1250 offset++;
1251 break;
1253 case 0140:
1254 case 0141:
1255 case 0142:
1256 data = ins->oprs[c - 0140].offset;
1257 if (is_sbyte(ins, c - 0140, 32)) {
1258 bytes[0] = data;
1259 out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
1260 NO_SEG);
1261 offset++;
1262 } else {
1263 out(offset, segment, &data, OUT_ADDRESS + 4,
1264 ins->oprs[c - 0140].segment, ins->oprs[c - 0140].wrt);
1265 offset += 4;
1267 break;
1269 case 0143:
1270 case 0144:
1271 case 0145:
1272 EMIT_REX();
1273 codes++;
1274 bytes[0] = *codes++;
1275 if (is_sbyte(ins, c - 0143, 32))
1276 bytes[0] |= 2; /* s-bit */
1277 out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
1278 offset++;
1279 break;
1281 case 0300:
1282 case 0301:
1283 case 0302:
1284 if (chsize(&ins->oprs[c - 0300], bits)) {
1285 *bytes = 0x67;
1286 out(offset, segment, bytes,
1287 OUT_RAWDATA + 1, NO_SEG, NO_SEG);
1288 offset += 1;
1289 } else
1290 offset += 0;
1291 break;
1293 case 0310:
1294 if (bits != 16) {
1295 *bytes = 0x67;
1296 out(offset, segment, bytes,
1297 OUT_RAWDATA + 1, NO_SEG, NO_SEG);
1298 offset += 1;
1299 } else
1300 offset += 0;
1301 break;
1303 case 0311:
1304 if (bits != 32) {
1305 *bytes = 0x67;
1306 out(offset, segment, bytes,
1307 OUT_RAWDATA + 1, NO_SEG, NO_SEG);
1308 offset += 1;
1309 } else
1310 offset += 0;
1311 break;
1313 case 0312:
1314 break;
1316 case 0313:
1317 ins->rex = 0;
1318 break;
1320 case 0320:
1321 if (bits != 16) {
1322 *bytes = 0x66;
1323 out(offset, segment, bytes,
1324 OUT_RAWDATA + 1, NO_SEG, NO_SEG);
1325 offset += 1;
1326 } else
1327 offset += 0;
1328 break;
1330 case 0321:
1331 if (bits == 16) {
1332 *bytes = 0x66;
1333 out(offset, segment, bytes,
1334 OUT_RAWDATA + 1, NO_SEG, NO_SEG);
1335 offset += 1;
1336 } else
1337 offset += 0;
1338 break;
1340 case 0322:
1341 case 0323:
1342 break;
1344 case 0324:
1345 ins->rex |= REX_W;
1346 break;
1348 case 0330:
1349 *bytes = *codes++ ^ condval[ins->condition];
1350 out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
1351 offset += 1;
1352 break;
1354 case 0331:
1355 case 0332:
1356 break;
1358 case 0333:
1359 *bytes = 0xF3;
1360 out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
1361 offset += 1;
1362 break;
1364 case 0334:
1365 if (ins->rex & REX_R) {
1366 *bytes = 0xF0;
1367 out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
1368 offset += 1;
1370 ins->rex &= ~(REX_L|REX_R);
1371 break;
1373 case 0340:
1374 case 0341:
1375 case 0342:
1376 if (ins->oprs[0].segment != NO_SEG)
1377 errfunc(ERR_PANIC, "non-constant BSS size in pass two");
1378 else {
1379 int32_t size = ins->oprs[0].offset << (c - 0340);
1380 if (size > 0)
1381 out(offset, segment, NULL,
1382 OUT_RESERVE + size, NO_SEG, NO_SEG);
1383 offset += size;
1385 break;
1387 case 0366:
1388 *bytes = 0x66;
1389 out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
1390 offset += 1;
1391 break;
1392 case 0370:
1393 case 0371:
1394 case 0372:
1395 break;
1397 case 0373:
1398 *bytes = bits == 16 ? 3 : 5;
1399 out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
1400 offset += 1;
1401 break;
1403 default: /* can't do it by 'case' statements */
1404 if (c >= 0100 && c <= 0277) { /* it's an EA */
1405 ea ea_data;
1406 int rfield;
1407 int32_t rflags;
1408 uint8_t *p;
1409 int32_t s;
1411 if (c <= 0177) {
1412 /* pick rfield from operand b */
1413 rflags = regflag(&ins->oprs[c & 7]);
1414 rfield = regvals[ins->oprs[c & 7].basereg];
1415 } else {
1416 /* rfield is constant */
1417 rflags = 0;
1418 rfield = c & 7;
1421 if (!process_ea
1422 (&ins->oprs[(c >> 3) & 7], &ea_data, bits,
1423 rfield, rflags, ins->forw_ref)) {
1424 errfunc(ERR_NONFATAL, "invalid effective address");
1427 p = bytes;
1428 *p++ = ea_data.modrm;
1429 if (ea_data.sib_present)
1430 *p++ = ea_data.sib;
1432 s = p - bytes;
1433 out(offset, segment, bytes, OUT_RAWDATA + s,
1434 NO_SEG, NO_SEG);
1436 switch (ea_data.bytes) {
1437 case 0:
1438 break;
1439 case 1:
1440 if (ins->oprs[(c >> 3) & 7].segment != NO_SEG) {
1441 data = ins->oprs[(c >> 3) & 7].offset;
1442 out(offset, segment, &data, OUT_ADDRESS + 1,
1443 ins->oprs[(c >> 3) & 7].segment,
1444 ins->oprs[(c >> 3) & 7].wrt);
1445 } else {
1446 *bytes = ins->oprs[(c >> 3) & 7].offset;
1447 out(offset, segment, bytes, OUT_RAWDATA + 1,
1448 NO_SEG, NO_SEG);
1450 s++;
1451 break;
1452 case 8:
1453 case 2:
1454 case 4:
1455 data = ins->oprs[(c >> 3) & 7].offset;
1456 if (ea_data.rip && (ins->oprs[(c >> 3) & 7].segment == 0xFFFFFFFF))
1457 ea_data.rip = 0; /* Make distinction between Symbols and Immediates */
1458 out(offset, segment, &data, /* RIP = Relative, not Absolute */
1459 (ea_data.rip ? OUT_REL4ADR : OUT_ADDRESS) + ea_data.bytes,
1460 ins->oprs[(c >> 3) & 7].segment,
1461 ins->oprs[(c >> 3) & 7].wrt);
1462 s += ea_data.bytes;
1463 break;
1465 offset += s;
1466 } else
1467 errfunc(ERR_PANIC, "internal instruction table corrupt"
1468 ": instruction code 0x%02X given", c);
1472 static int32_t regflag(const operand * o)
1474 if (o->basereg < EXPR_REG_START || o->basereg >= REG_ENUM_LIMIT) {
1475 errfunc(ERR_PANIC, "invalid operand passed to regflag()");
1477 return reg_flags[o->basereg];
1480 static int32_t regval(const operand * o)
1482 if (o->basereg < EXPR_REG_START || o->basereg >= REG_ENUM_LIMIT) {
1483 errfunc(ERR_PANIC, "invalid operand passed to regval()");
1485 return regvals[o->basereg];
1488 static int op_rexflags(const operand * o, int mask)
1490 int32_t flags;
1491 int val;
1493 if (o->basereg < EXPR_REG_START || o->basereg >= REG_ENUM_LIMIT) {
1494 errfunc(ERR_PANIC, "invalid operand passed to op_rexflags()");
1497 flags = reg_flags[o->basereg];
1498 val = regvals[o->basereg];
1500 return rexflags(val, flags, mask);
1503 static int rexflags(int val, int32_t flags, int mask)
1505 int rex = 0;
1507 if (val >= 8)
1508 rex |= REX_B|REX_X|REX_R;
1509 if (flags & BITS64)
1510 rex |= REX_W;
1511 if (!(REG_HIGH & ~flags)) /* AH, CH, DH, BH */
1512 rex |= REX_H;
1513 else if (!(REG8 & ~flags) && val >= 4) /* SPL, BPL, SIL, DIL */
1514 rex |= REX_P;
1516 return rex & mask;
1519 static int matches(struct itemplate *itemp, insn * instruction, int bits)
1521 int i, size[3], asize, oprs, ret;
1523 ret = 100;
1526 * Check the opcode
1528 if (itemp->opcode != instruction->opcode)
1529 return 0;
1532 * Count the operands
1534 if (itemp->operands != instruction->operands)
1535 return 0;
1538 * Check that no spurious colons or TOs are present
1540 for (i = 0; i < itemp->operands; i++)
1541 if (instruction->oprs[i].type & ~itemp->opd[i] & (COLON | TO))
1542 return 0;
1545 * Check that the operand flags all match up
1547 for (i = 0; i < itemp->operands; i++)
1548 if (itemp->opd[i] & ~instruction->oprs[i].type ||
1549 ((itemp->opd[i] & SIZE_MASK) &&
1550 ((itemp->opd[i] ^ instruction->oprs[i].type) & SIZE_MASK))) {
1551 if ((itemp->opd[i] & ~instruction->oprs[i].type & ~SIZE_MASK) ||
1552 (instruction->oprs[i].type & SIZE_MASK))
1553 return 0;
1554 else
1555 return 1;
1559 * Check operand sizes
1561 if (itemp->flags & IF_ARMASK) {
1562 size[0] = size[1] = size[2] = 0;
1564 switch (itemp->flags & IF_ARMASK) {
1565 case IF_AR0:
1566 i = 0;
1567 break;
1568 case IF_AR1:
1569 i = 1;
1570 break;
1571 case IF_AR2:
1572 i = 2;
1573 break;
1574 default:
1575 break; /* Shouldn't happen */
1577 if (itemp->flags & IF_SB) {
1578 size[i] = BITS8;
1579 } else if (itemp->flags & IF_SW) {
1580 size[i] = BITS16;
1581 } else if (itemp->flags & IF_SD) {
1582 size[i] = BITS32;
1583 } else if (itemp->flags & IF_SQ) {
1584 size[i] = BITS64;
1586 } else {
1587 asize = 0;
1588 if (itemp->flags & IF_SB) {
1589 asize = BITS8;
1590 oprs = itemp->operands;
1591 } else if (itemp->flags & IF_SW) {
1592 asize = BITS16;
1593 oprs = itemp->operands;
1594 } else if (itemp->flags & IF_SD) {
1595 asize = BITS32;
1596 oprs = itemp->operands;
1597 } else if (itemp->flags & IF_SQ) {
1598 asize = BITS64;
1599 oprs = itemp->operands;
1601 size[0] = size[1] = size[2] = asize;
1604 if (itemp->flags & (IF_SM | IF_SM2)) {
1605 oprs = (itemp->flags & IF_SM2 ? 2 : itemp->operands);
1606 asize = 0;
1607 for (i = 0; i < oprs; i++) {
1608 if ((asize = itemp->opd[i] & SIZE_MASK) != 0) {
1609 int j;
1610 for (j = 0; j < oprs; j++)
1611 size[j] = asize;
1612 break;
1615 } else {
1616 oprs = itemp->operands;
1619 for (i = 0; i < itemp->operands; i++) {
1620 if (!(itemp->opd[i] & SIZE_MASK) &&
1621 (instruction->oprs[i].type & SIZE_MASK & ~size[i]))
1622 return 2;
1626 * Check template is okay at the set cpu level
1628 if (((itemp->flags & IF_PLEVEL) > cpu))
1629 return 3;
1632 * Check if instruction is available in long mode
1634 if ((itemp->flags & IF_NOLONG) && (bits == 64))
1635 return 4;
1638 * Check if special handling needed for Jumps
1640 if ((uint8_t)(itemp->code[0]) >= 0370)
1641 return 99;
1643 return ret;
1646 static ea *process_ea(operand * input, ea * output, int addrbits,
1647 int rfield, int32_t rflags, int forw_ref)
1649 output->rip = FALSE;
1651 /* REX flags for the rfield operand */
1652 output->rex |= rexflags(rfield, rflags, REX_R|REX_P|REX_W|REX_H);
1654 if (!(REGISTER & ~input->type)) { /* register direct */
1655 int i;
1656 int32_t f;
1658 if (input->basereg < EXPR_REG_START /* Verify as Register */
1659 || input->basereg >= REG_ENUM_LIMIT)
1660 return NULL;
1661 f = regflag(input);
1662 i = regvals[input->basereg];
1664 if (REG_EA & ~f)
1665 return NULL; /* Invalid EA register */
1667 output->rex |= op_rexflags(input, REX_B|REX_P|REX_W|REX_H);
1669 output->sib_present = FALSE; /* no SIB necessary */
1670 output->bytes = 0; /* no offset necessary either */
1671 output->modrm = 0xC0 | ((rfield & 7) << 3) | (i & 7);
1672 } else { /* it's a memory reference */
1673 if (input->basereg == -1
1674 && (input->indexreg == -1 || input->scale == 0)) {
1675 /* it's a pure offset */
1676 if (input->addr_size)
1677 addrbits = input->addr_size;
1679 if (globalbits == 64 && (~input->type & IP_REL)) {
1680 int scale, index, base;
1681 output->sib_present = TRUE;
1682 scale = 0;
1683 index = 4;
1684 base = 5;
1685 output->sib = (scale << 6) | (index << 3) | base;
1686 output->bytes = 4;
1687 output->modrm = 4 | ((rfield & 7) << 3);
1688 output->rip = FALSE;
1689 } else {
1690 output->sib_present = FALSE;
1691 output->bytes = (addrbits != 16 ? 4 : 2);
1692 output->modrm = (addrbits != 16 ? 5 : 6) | ((rfield & 7) << 3);
1693 output->rip = globalbits == 64;
1695 } else { /* it's an indirection */
1696 int i = input->indexreg, b = input->basereg, s = input->scale;
1697 int32_t o = input->offset, seg = input->segment;
1698 int hb = input->hintbase, ht = input->hinttype;
1699 int t;
1700 int it, bt;
1701 int32_t ix, bx; /* register flags */
1703 if (s == 0)
1704 i = -1; /* make this easy, at least */
1706 if (i >= EXPR_REG_START && i < REG_ENUM_LIMIT) {
1707 it = regvals[i];
1708 ix = reg_flags[i];
1709 } else {
1710 it = -1;
1711 ix = 0;
1714 if (b != -1 && b >= EXPR_REG_START && b < REG_ENUM_LIMIT) {
1715 bt = regvals[b];
1716 bx = reg_flags[b];
1717 } else {
1718 bt = -1;
1719 bx = 0;
1722 /* check for a 32/64-bit memory reference... */
1723 if ((ix|bx) & (BITS32|BITS64)) {
1724 /* it must be a 32/64-bit memory reference. Firstly we have
1725 * to check that all registers involved are type E/Rxx. */
1726 int32_t sok = BITS32|BITS64;
1728 if (it != -1) {
1729 if (!(REG64 & ~ix) || !(REG32 & ~ix))
1730 sok &= ix;
1731 else
1732 return NULL;
1735 if (bt != -1) {
1736 if (REG_GPR & ~bx)
1737 return NULL; /* Invalid register */
1738 if (~sok & bx & SIZE_MASK)
1739 return NULL; /* Invalid size */
1740 sok &= ~bx;
1743 /* While we're here, ensure the user didn't specify WORD. */
1744 if (input->addr_size == 16 ||
1745 (input->addr_size == 32 && !(sok & BITS32)) ||
1746 (input->addr_size == 64 && !(sok & BITS64)))
1747 return NULL;
1749 /* now reorganize base/index */
1750 if (s == 1 && bt != it && bt != -1 && it != -1 &&
1751 ((hb == b && ht == EAH_NOTBASE)
1752 || (hb == i && ht == EAH_MAKEBASE))) {
1753 /* swap if hints say so */
1754 t = bt, bt = it, it = t;
1755 t = bx, bx = ix, ix = t;
1757 if (bt == it) /* convert EAX+2*EAX to 3*EAX */
1758 bt = -1, bx = 0, s++;
1759 if (bt == -1 && s == 1 && !(hb == it && ht == EAH_NOTBASE)) {
1760 /* make single reg base, unless hint */
1761 bt = it, bx = ix, it = -1, ix = 0;
1763 if (((s == 2 && t != REG_NUM_ESP
1764 && !(input->eaflags & EAF_TIMESTWO)) || s == 3
1765 || s == 5 || s == 9) && bt == -1)
1766 bt = it, bx = ix, s--; /* convert 3*EAX to EAX+2*EAX */
1767 if (it == -1 && (bt & 7) != REG_NUM_ESP
1768 && (input->eaflags & EAF_TIMESTWO))
1769 it = bt, ix = bx, bt = -1, bx = 0, s = 1;
1770 /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */
1771 if (s == 1 && it == REG_NUM_ESP) {
1772 /* swap ESP into base if scale is 1 */
1773 t = it, it = bt, bt = t;
1774 t = ix, ix = bx, bx = t;
1776 if (it == REG_NUM_ESP
1777 || (s != 1 && s != 2 && s != 4 && s != 8 && it != -1))
1778 return NULL; /* wrong, for various reasons */
1780 output->rex |= rexflags(it, ix, REX_X);
1781 output->rex |= rexflags(bt, bx, REX_B);
1783 if (it == -1 && (bt & 7) != REG_NUM_ESP) {
1784 /* no SIB needed */
1785 int mod, rm;
1787 if (bt == -1) {
1788 rm = 5;
1789 mod = 0;
1790 } else {
1791 rm = (bt & 7);
1792 if (rm != REG_NUM_EBP && o == 0 &&
1793 seg == NO_SEG && !forw_ref &&
1794 !(input->eaflags &
1795 (EAF_BYTEOFFS | EAF_WORDOFFS)))
1796 mod = 0;
1797 else if (input->eaflags & EAF_BYTEOFFS ||
1798 (o >= -128 && o <= 127 && seg == NO_SEG
1799 && !forw_ref
1800 && !(input->eaflags & EAF_WORDOFFS)))
1801 mod = 1;
1802 else
1803 mod = 2;
1806 output->sib_present = FALSE;
1807 output->bytes = (bt == -1 || mod == 2 ? 4 : mod);
1808 output->modrm = (mod << 6) | ((rfield & 7) << 3) | rm;
1809 } else {
1810 /* we need a SIB */
1811 int mod, scale, index, base;
1813 if (it == -1)
1814 index = 4, s = 1;
1815 else
1816 index = (it & 7);
1818 switch (s) {
1819 case 1:
1820 scale = 0;
1821 break;
1822 case 2:
1823 scale = 1;
1824 break;
1825 case 4:
1826 scale = 2;
1827 break;
1828 case 8:
1829 scale = 3;
1830 break;
1831 default: /* then what the smeg is it? */
1832 return NULL; /* panic */
1835 if (bt == -1) {
1836 base = 5;
1837 mod = 0;
1838 } else {
1839 base = (bt & 7);
1840 if (base != REG_NUM_EBP && o == 0 &&
1841 seg == NO_SEG && !forw_ref &&
1842 !(input->eaflags &
1843 (EAF_BYTEOFFS | EAF_WORDOFFS)))
1844 mod = 0;
1845 else if (input->eaflags & EAF_BYTEOFFS ||
1846 (o >= -128 && o <= 127 && seg == NO_SEG
1847 && !forw_ref
1848 && !(input->eaflags & EAF_WORDOFFS)))
1849 mod = 1;
1850 else
1851 mod = 2;
1854 output->sib_present = TRUE;
1855 output->bytes = (bt == -1 || mod == 2 ? 4 : mod);
1856 output->modrm = (mod << 6) | ((rfield & 7) << 3) | 4;
1857 output->sib = (scale << 6) | (index << 3) | base;
1859 } else { /* it's 16-bit */
1860 int mod, rm;
1862 /* check for 64-bit long mode */
1863 if (addrbits == 64)
1864 return NULL;
1866 /* check all registers are BX, BP, SI or DI */
1867 if ((b != -1 && b != R_BP && b != R_BX && b != R_SI
1868 && b != R_DI) || (i != -1 && i != R_BP && i != R_BX
1869 && i != R_SI && i != R_DI))
1870 return NULL;
1872 /* ensure the user didn't specify DWORD/QWORD */
1873 if (input->addr_size == 32 || input->addr_size == 64)
1874 return NULL;
1876 if (s != 1 && i != -1)
1877 return NULL; /* no can do, in 16-bit EA */
1878 if (b == -1 && i != -1) {
1879 int tmp = b;
1880 b = i;
1881 i = tmp;
1882 } /* swap */
1883 if ((b == R_SI || b == R_DI) && i != -1) {
1884 int tmp = b;
1885 b = i;
1886 i = tmp;
1888 /* have BX/BP as base, SI/DI index */
1889 if (b == i)
1890 return NULL; /* shouldn't ever happen, in theory */
1891 if (i != -1 && b != -1 &&
1892 (i == R_BP || i == R_BX || b == R_SI || b == R_DI))
1893 return NULL; /* invalid combinations */
1894 if (b == -1) /* pure offset: handled above */
1895 return NULL; /* so if it gets to here, panic! */
1897 rm = -1;
1898 if (i != -1)
1899 switch (i * 256 + b) {
1900 case R_SI * 256 + R_BX:
1901 rm = 0;
1902 break;
1903 case R_DI * 256 + R_BX:
1904 rm = 1;
1905 break;
1906 case R_SI * 256 + R_BP:
1907 rm = 2;
1908 break;
1909 case R_DI * 256 + R_BP:
1910 rm = 3;
1911 break;
1912 } else
1913 switch (b) {
1914 case R_SI:
1915 rm = 4;
1916 break;
1917 case R_DI:
1918 rm = 5;
1919 break;
1920 case R_BP:
1921 rm = 6;
1922 break;
1923 case R_BX:
1924 rm = 7;
1925 break;
1927 if (rm == -1) /* can't happen, in theory */
1928 return NULL; /* so panic if it does */
1930 if (o == 0 && seg == NO_SEG && !forw_ref && rm != 6 &&
1931 !(input->eaflags & (EAF_BYTEOFFS | EAF_WORDOFFS)))
1932 mod = 0;
1933 else if (input->eaflags & EAF_BYTEOFFS ||
1934 (o >= -128 && o <= 127 && seg == NO_SEG
1935 && !forw_ref
1936 && !(input->eaflags & EAF_WORDOFFS)))
1937 mod = 1;
1938 else
1939 mod = 2;
1941 output->sib_present = FALSE; /* no SIB - it's 16-bit */
1942 output->bytes = mod; /* bytes of offset needed */
1943 output->modrm = (mod << 6) | ((rfield & 7) << 3) | rm;
1948 output->size = 1 + output->sib_present + output->bytes;
1949 return output;
1952 static int chsize(operand * input, int addrbits)
1954 if (!(MEMORY & ~input->type)) {
1955 int32_t i, b;
1957 if (input->indexreg < EXPR_REG_START /* Verify as Register */
1958 || input->indexreg >= REG_ENUM_LIMIT)
1959 i = 0;
1960 else
1961 i = reg_flags[input->indexreg];
1963 if (input->basereg < EXPR_REG_START /* Verify as Register */
1964 || input->basereg >= REG_ENUM_LIMIT)
1965 b = 0;
1966 else
1967 b = reg_flags[input->basereg];
1969 if (input->scale == 0)
1970 i = 0;
1972 if (!i && !b) /* pure offset */
1973 return (input->addr_size != 0 && input->addr_size != addrbits);
1975 if (!(REG32 & ~i) || !(REG32 & ~b))
1976 return (addrbits != 32);
1977 else
1978 return (addrbits == 32);
1979 } else {
1980 return 0;