Make sure autoheader has actually been run by conditionalizing
[nasm/avx512.git] / assemble.c
blob5cfc9457316f1d52b3c502abf360b87bf3d360a2
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] and \4[012] depending on 16/32 bit
29 * assembly mode or the address-size override on the operand
30 * \50, \51, \52 - a byte relative operand, from operand 0, 1 or 2
31 * \60, \61, \62 - a word relative operand, from operand 0, 1 or 2
32 * \64, \65, \66 - select between \6[012] and \7[012] depending on 16/32 bit
33 * assembly mode or the operand-size override on the operand
34 * \70, \71, \72 - a long relative operand, from operand 0, 1 or 2
35 * \1ab - a ModRM, calculated on EA in operand a, with the spare
36 * field the register value of operand b.
37 * \130,\131,\132 - an immediate word or signed byte for operand 0, 1, or 2
38 * \133,\134,\135 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
39 * is a signed byte rather than a word.
40 * \140,\141,\142 - an immediate dword or signed byte for operand 0, 1, or 2
41 * \143,\144,\145 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
42 * is a signed byte rather than a dword.
43 * \2ab - a ModRM, calculated on EA in operand a, with the spare
44 * field equal to digit b.
45 * \30x - might be an 0x67 byte, depending on the address size of
46 * the memory reference in operand x.
47 * \310 - indicates fixed 16-bit address size, i.e. optional 0x67.
48 * \311 - indicates fixed 32-bit address size, i.e. optional 0x67.
49 * \312 - (disassembler only) marker on LOOP, LOOPxx instructions.
50 * \320 - indicates fixed 16-bit operand size, i.e. optional 0x66.
51 * \321 - indicates fixed 32-bit operand size, i.e. optional 0x66.
52 * \322 - indicates that this instruction is only valid when the
53 * operand size is the default (instruction to disassembler,
54 * generates no code in the assembler)
55 * \330 - a literal byte follows in the code stream, to be added
56 * to the condition code value of the instruction.
57 * \331 - instruction not valid with REP prefix. Hint for
58 * disassembler only; for SSE instructions.
59 * \332 - disassemble a rep (0xF3 byte) prefix as repe not rep.
60 * \333 - REP prefix (0xF3 byte); for SSE instructions. Not encoded
61 * as a literal byte in order to aid the disassembler.
62 * \340 - reserve <operand 0> bytes of uninitialised storage.
63 * Operand 0 had better be a segmentless constant.
64 * \370,\371,\372 - match only if operand 0 meets byte jump criteria.
65 * 370 is used for Jcc, 371 is used for JMP.
66 * \373 - assemble 0x03 if bits==16, 0x05 if bits==32;
67 * used for conditional jump over longer jump
70 #include <stdio.h>
71 #include <string.h>
73 #include "nasm.h"
74 #include "nasmlib.h"
75 #include "assemble.h"
76 #include "insns.h"
77 #include "preproc.h"
79 extern struct itemplate *nasm_instructions[];
81 typedef struct {
82 int sib_present; /* is a SIB byte necessary? */
83 int bytes; /* # of bytes of offset needed */
84 int size; /* lazy - this is sib+bytes+1 */
85 unsigned char modrm, sib; /* the bytes themselves */
86 } ea;
88 static unsigned long cpu; /* cpu level received from nasm.c */
89 static efunc errfunc;
90 static struct ofmt *outfmt;
91 static ListGen *list;
93 static long calcsize (long, long, int, insn *, const char *);
94 static void gencode (long, long, int, insn *, const char *, long);
95 static int regval (operand *o);
96 static int matches (struct itemplate *, insn *);
97 static ea * process_ea (operand *, ea *, int, int, int);
98 static int chsize (operand *, int);
101 * This routine wrappers the real output format's output routine,
102 * in order to pass a copy of the data off to the listing file
103 * generator at the same time.
105 static void out (long offset, long segto, const void *data, unsigned long type,
106 long segment, long wrt)
108 static long lineno = 0; /* static!!! */
109 static char *lnfname = NULL;
111 if ((type & OUT_TYPMASK) == OUT_ADDRESS) {
112 if (segment != NO_SEG || wrt != NO_SEG) {
114 * This address is relocated. We must write it as
115 * OUT_ADDRESS, so there's no work to be done here.
117 list->output (offset, data, type);
119 else {
120 unsigned char p[4], *q = p;
122 * This is a non-relocated address, and we're going to
123 * convert it into RAWDATA format.
125 if ((type & OUT_SIZMASK) == 4) {
126 WRITELONG (q, * (long *) data);
127 list->output (offset, p, OUT_RAWDATA+4);
129 else {
130 WRITESHORT (q, * (long *) data);
131 list->output (offset, p, OUT_RAWDATA+2);
135 else if ((type & OUT_TYPMASK) == OUT_RAWDATA) {
136 list->output (offset, data, type);
138 else if ((type & OUT_TYPMASK) == OUT_RESERVE) {
139 list->output (offset, NULL, type);
141 else if ((type & OUT_TYPMASK) == OUT_REL2ADR ||
142 (type & OUT_TYPMASK) == OUT_REL4ADR) {
143 list->output (offset, data, type);
147 * this call to src_get determines when we call the
148 * debug-format-specific "linenum" function
149 * it updates lineno and lnfname to the current values
150 * returning 0 if "same as last time", -2 if lnfname
151 * changed, and the amount by which lineno changed,
152 * if it did. thus, these variables must be static
155 if (src_get(&lineno,&lnfname))
157 outfmt->current_dfmt->linenum(lnfname,lineno,segto);
158 if (lnfname) nasm_free(lnfname);
161 outfmt->output (segto, data, type, segment, wrt);
164 static int jmp_match (long segment, long offset, int bits,
165 insn *ins, const char *code)
166 { long isize;
167 unsigned char c = code[0];
170 if (c != 0370 && c != 0371) return 0;
171 if (ins->oprs[0].opflags & OPFLAG_FORWARD) {
172 if ((optimizing<0 || (ins->oprs[0].type & STRICT))
173 && c==0370) return 1;
174 else return (pass0==0); /* match a forward reference */
176 isize = calcsize (segment, offset, bits, ins, code);
177 if (ins->oprs[0].segment != segment) return 0;
178 isize = ins->oprs[0].offset - offset - isize; /* isize is now the delta */
179 if (isize >= -128L && isize <= 127L) return 1; /* it is byte size */
181 return 0;
185 long assemble (long segment, long offset, int bits, unsigned long cp,
186 insn *instruction, struct ofmt *output, efunc error,
187 ListGen *listgen)
189 struct itemplate *temp;
190 int j;
191 int size_prob;
192 long insn_end;
193 long itimes;
194 long start = offset;
195 long wsize = 0; /* size for DB etc. */
197 errfunc = error; /* to pass to other functions */
198 cpu = cp;
199 outfmt = output; /* likewise */
200 list = listgen; /* and again */
202 switch (instruction->opcode)
204 case -1: return 0;
205 case I_DB: wsize = 1; break;
206 case I_DW: wsize = 2; break;
207 case I_DD: wsize = 4; break;
208 case I_DQ: wsize = 8; break;
209 case I_DT: wsize = 10; break;
212 if (wsize) {
213 extop * e;
214 long t = instruction->times;
215 if (t < 0)
216 errfunc(ERR_PANIC, "instruction->times < 0 (%ld) in assemble()",t);
218 while (t--) /* repeat TIMES times */
220 for (e = instruction->eops; e; e = e->next)
222 if (e->type == EOT_DB_NUMBER)
224 if (wsize == 1) {
225 if (e->segment != NO_SEG)
226 errfunc (ERR_NONFATAL,
227 "one-byte relocation attempted");
228 else {
229 unsigned char out_byte = e->offset;
230 out (offset, segment, &out_byte, OUT_RAWDATA+1,
231 NO_SEG, NO_SEG);
234 else if (wsize > 5) {
235 errfunc (ERR_NONFATAL, "integer supplied to a D%c"
236 " instruction", wsize==8 ? 'Q' : 'T');
238 else
239 out (offset, segment, &e->offset,
240 OUT_ADDRESS+wsize, e->segment,
241 e->wrt);
242 offset += wsize;
244 else if (e->type == EOT_DB_STRING)
246 int align;
248 out (offset, segment, e->stringval,
249 OUT_RAWDATA+e->stringlen, NO_SEG, NO_SEG);
250 align = e->stringlen % wsize;
252 if (align) {
253 align = wsize - align;
254 out (offset, segment, "\0\0\0\0\0\0\0\0",
255 OUT_RAWDATA+align, NO_SEG, NO_SEG);
257 offset += e->stringlen + align;
260 if (t > 0 && t == instruction->times-1)
263 * Dummy call to list->output to give the offset to the
264 * listing module.
266 list->output (offset, NULL, OUT_RAWDATA);
267 list->uplevel (LIST_TIMES);
270 if (instruction->times > 1)
271 list->downlevel (LIST_TIMES);
272 return offset - start;
275 if (instruction->opcode == I_INCBIN)
277 static char fname[FILENAME_MAX];
278 FILE * fp;
279 long len;
280 char *prefix = "", *combine;
281 char** pPrevPath = NULL;
283 len = FILENAME_MAX-1;
284 if (len > instruction->eops->stringlen)
285 len = instruction->eops->stringlen;
286 strncpy (fname, instruction->eops->stringval, len);
287 fname[len] = '\0';
289 while (1) /* added by alexfru: 'incbin' uses include paths */
291 combine = nasm_malloc(strlen(prefix) + len + 1);
292 strcpy(combine, prefix);
293 strcat(combine, fname);
295 if ( (fp = fopen(combine, "rb")) != NULL)
297 nasm_free(combine);
298 break;
301 nasm_free(combine);
302 pPrevPath = pp_get_include_path_ptr (pPrevPath);
303 if (pPrevPath == NULL)
304 break;
305 prefix = *pPrevPath;
308 if (fp == NULL)
309 error (ERR_NONFATAL, "`incbin': unable to open file `%s'", fname);
310 else if (fseek(fp, 0L, SEEK_END) < 0)
311 error (ERR_NONFATAL, "`incbin': unable to seek on file `%s'",
312 fname);
313 else
315 static char buf[2048];
316 long t = instruction->times;
317 long base = 0;
319 len = ftell (fp);
320 if (instruction->eops->next) {
321 base = instruction->eops->next->offset;
322 len -= base;
323 if (instruction->eops->next->next &&
324 len > instruction->eops->next->next->offset)
325 len = instruction->eops->next->next->offset;
328 * Dummy call to list->output to give the offset to the
329 * listing module.
331 list->output (offset, NULL, OUT_RAWDATA);
332 list->uplevel(LIST_INCBIN);
333 while (t--)
335 long l;
337 fseek (fp, base, SEEK_SET);
338 l = len;
339 while (l > 0) {
340 long m = fread (buf, 1, (l>sizeof(buf)?sizeof(buf):l),
341 fp);
342 if (!m) {
344 * This shouldn't happen unless the file
345 * actually changes while we are reading
346 * it.
348 error (ERR_NONFATAL, "`incbin': unexpected EOF while"
349 " reading file `%s'", fname);
350 t=0; /* Try to exit cleanly */
351 break;
353 out (offset, segment, buf, OUT_RAWDATA+m,
354 NO_SEG, NO_SEG);
355 l -= m;
358 list->downlevel(LIST_INCBIN);
359 if (instruction->times > 1) {
361 * Dummy call to list->output to give the offset to the
362 * listing module.
364 list->output (offset, NULL, OUT_RAWDATA);
365 list->uplevel(LIST_TIMES);
366 list->downlevel(LIST_TIMES);
368 fclose (fp);
369 return instruction->times * len;
371 return 0; /* if we're here, there's an error */
374 size_prob = FALSE;
375 temp = nasm_instructions[instruction->opcode];
376 while (temp->opcode != -1) {
377 int m = matches (temp, instruction);
378 if (m == 99)
379 m += jmp_match(segment, offset, bits, instruction, temp->code);
381 if (m == 100) /* matches! */
383 const char *codes = temp->code;
384 long insn_size = calcsize(segment, offset, bits,
385 instruction, codes);
386 itimes = instruction->times;
387 if (insn_size < 0) /* shouldn't be, on pass two */
388 error (ERR_PANIC, "errors made it through from pass one");
389 else while (itimes--) {
390 for (j=0; j<instruction->nprefix; j++) {
391 unsigned char c=0;
392 switch (instruction->prefixes[j]) {
393 case P_LOCK:
394 c = 0xF0; break;
395 case P_REPNE: case P_REPNZ:
396 c = 0xF2; break;
397 case P_REPE: case P_REPZ: case P_REP:
398 c = 0xF3; break;
399 case R_CS: c = 0x2E; break;
400 case R_DS: c = 0x3E; break;
401 case R_ES: c = 0x26; break;
402 case R_FS: c = 0x64; break;
403 case R_GS: c = 0x65; break;
404 case R_SS: c = 0x36; break;
405 case R_SEGR6:
406 case R_SEGR7:
407 error (ERR_NONFATAL, "segr6 and segr7 cannot be used as prefixes");
408 break;
409 case P_A16:
410 if (bits != 16)
411 c = 0x67;
412 break;
413 case P_A32:
414 if (bits != 32)
415 c = 0x67;
416 break;
417 case P_O16:
418 if (bits != 16)
419 c = 0x66;
420 break;
421 case P_O32:
422 if (bits != 32)
423 c = 0x66;
424 break;
425 default:
426 error (ERR_PANIC,
427 "invalid instruction prefix");
429 if (c != 0) {
430 out (offset, segment, &c, OUT_RAWDATA+1,
431 NO_SEG, NO_SEG);
432 offset++;
435 insn_end = offset + insn_size;
436 gencode (segment, offset, bits, instruction, codes, insn_end);
437 offset += insn_size;
438 if (itimes > 0 && itimes == instruction->times-1) {
440 * Dummy call to list->output to give the offset to the
441 * listing module.
443 list->output (offset, NULL, OUT_RAWDATA);
444 list->uplevel (LIST_TIMES);
447 if (instruction->times > 1)
448 list->downlevel (LIST_TIMES);
449 return offset - start;
450 } else if (m > 0 && m > size_prob) {
451 size_prob = m;
453 temp++;
456 if (temp->opcode == -1) { /* didn't match any instruction */
457 if (size_prob == 1) /* would have matched, but for size */
458 error (ERR_NONFATAL, "operation size not specified");
459 else if (size_prob == 2)
460 error (ERR_NONFATAL, "mismatch in operand sizes");
461 else if (size_prob == 3)
462 error (ERR_NONFATAL, "no instruction for this cpu level");
463 else
464 error (ERR_NONFATAL,
465 "invalid combination of opcode and operands");
467 return 0;
470 long insn_size (long segment, long offset, int bits, unsigned long cp,
471 insn *instruction, efunc error)
473 struct itemplate *temp;
475 errfunc = error; /* to pass to other functions */
476 cpu = cp;
478 if (instruction->opcode == -1)
479 return 0;
481 if (instruction->opcode == I_DB ||
482 instruction->opcode == I_DW ||
483 instruction->opcode == I_DD ||
484 instruction->opcode == I_DQ ||
485 instruction->opcode == I_DT)
487 extop *e;
488 long isize, osize, wsize = 0; /* placate gcc */
490 isize = 0;
491 switch (instruction->opcode)
493 case I_DB: wsize = 1; break;
494 case I_DW: wsize = 2; break;
495 case I_DD: wsize = 4; break;
496 case I_DQ: wsize = 8; break;
497 case I_DT: wsize = 10; break;
500 for (e = instruction->eops; e; e = e->next)
502 long align;
504 osize = 0;
505 if (e->type == EOT_DB_NUMBER)
506 osize = 1;
507 else if (e->type == EOT_DB_STRING)
508 osize = e->stringlen;
510 align = (-osize) % wsize;
511 if (align < 0)
512 align += wsize;
513 isize += osize + align;
515 return isize * instruction->times;
518 if (instruction->opcode == I_INCBIN)
520 char fname[FILENAME_MAX];
521 FILE * fp;
522 long len;
523 char *prefix = "", *combine;
524 char** pPrevPath = NULL;
526 len = FILENAME_MAX-1;
527 if (len > instruction->eops->stringlen)
528 len = instruction->eops->stringlen;
529 strncpy (fname, instruction->eops->stringval, len);
530 fname[len] = '\0';
532 while (1) /* added by alexfru: 'incbin' uses include paths */
534 combine = nasm_malloc(strlen(prefix) + len + 1);
535 strcpy(combine, prefix);
536 strcat(combine, fname);
538 if ( (fp = fopen(combine, "rb")) != NULL)
540 nasm_free(combine);
541 break;
544 nasm_free(combine);
545 pPrevPath = pp_get_include_path_ptr (pPrevPath);
546 if (pPrevPath == NULL)
547 break;
548 prefix = *pPrevPath;
551 if (fp == NULL)
552 error (ERR_NONFATAL, "`incbin': unable to open file `%s'", fname);
553 else if (fseek(fp, 0L, SEEK_END) < 0)
554 error (ERR_NONFATAL, "`incbin': unable to seek on file `%s'",
555 fname);
556 else
558 len = ftell (fp);
559 fclose (fp);
560 if (instruction->eops->next)
562 len -= instruction->eops->next->offset;
563 if (instruction->eops->next->next &&
564 len > instruction->eops->next->next->offset)
566 len = instruction->eops->next->next->offset;
569 return instruction->times * len;
571 return 0; /* if we're here, there's an error */
574 temp = nasm_instructions[instruction->opcode];
575 while (temp->opcode != -1) {
576 int m = matches(temp, instruction);
577 if (m == 99)
578 m += jmp_match(segment, offset, bits, instruction, temp->code);
580 if (m == 100) {
581 /* we've matched an instruction. */
582 long isize;
583 const char * codes = temp->code;
584 int j;
586 isize = calcsize(segment, offset, bits, instruction, codes);
587 if (isize < 0)
588 return -1;
589 for (j = 0; j < instruction->nprefix; j++)
591 if ((instruction->prefixes[j] != P_A16 &&
592 instruction->prefixes[j] != P_O16 && bits==16) ||
593 (instruction->prefixes[j] != P_A32 &&
594 instruction->prefixes[j] != P_O32 && bits==32))
596 isize++;
599 return isize * instruction->times;
601 temp++;
603 return -1; /* didn't match any instruction */
607 /* check that opn[op] is a signed byte of size 16 or 32,
608 and return the signed value*/
609 static int is_sbyte (insn *ins, int op, int size)
611 signed long v;
612 int ret;
614 ret = !(ins->forw_ref && ins->oprs[op].opflags ) && /* dead in the water on forward reference or External */
615 optimizing>=0 &&
616 !(ins->oprs[op].type & STRICT) &&
617 ins->oprs[op].wrt==NO_SEG && ins->oprs[op].segment==NO_SEG;
619 v = ins->oprs[op].offset;
620 if (size==16) v = (signed short)v; /* sign extend if 16 bits */
622 return ret && v>=-128L && v<=127L;
625 static long calcsize (long segment, long offset, int bits,
626 insn *ins, const char *codes)
628 long length = 0;
629 unsigned char c;
631 (void) segment; /* Don't warn that this parameter is unused */
632 (void) offset; /* Don't warn that this parameter is unused */
634 while (*codes) switch (c = *codes++) {
635 case 01: case 02: case 03:
636 codes += c, length += c; break;
637 case 04: case 05: case 06: case 07:
638 length++; break;
639 case 010: case 011: case 012:
640 codes++, length++; break;
641 case 017:
642 length++; break;
643 case 014: case 015: case 016:
644 length++; break;
645 case 020: case 021: case 022:
646 length++; break;
647 case 024: case 025: case 026:
648 length++; break;
649 case 030: case 031: case 032:
650 length += 2; break;
651 case 034: case 035: case 036:
652 if ( ins->oprs[c-034].type & (BITS16|BITS32) )
653 length += (ins->oprs[c-034].type & BITS16) ? 2 : 4;
654 else
655 length += (bits == 16) ? 2 : 4;
656 break;
657 case 037:
658 length += 2; break;
659 case 040: case 041: case 042:
660 length += 4; break;
661 case 044: case 045: case 046:
662 length += ((ins->oprs[c-044].addr_size ?
663 ins->oprs[c-044].addr_size : bits) == 16 ? 2 : 4); break;
664 case 050: case 051: case 052:
665 length++; break;
666 case 060: case 061: case 062:
667 length += 2; break;
668 case 064: case 065: case 066:
669 if ( ins->oprs[c-064].type & (BITS16|BITS32) )
670 length += (ins->oprs[c-064].type & BITS16) ? 2 : 4;
671 else
672 length += (bits == 16) ? 2 : 4;
673 break;
674 case 070: case 071: case 072:
675 length += 4; break;
676 case 0130: case 0131: case 0132:
677 length += is_sbyte(ins, c-0130, 16) ? 1 : 2; break;
678 case 0133: case 0134: case 0135:
679 codes+=2; length++; break;
680 case 0140: case 0141: case 0142:
681 length += is_sbyte(ins, c-0140, 32) ? 1 : 4; break;
682 case 0143: case 0144: case 0145:
683 codes+=2; length++; break;
684 case 0300: case 0301: case 0302:
685 length += chsize (&ins->oprs[c-0300], bits);
686 break;
687 case 0310:
688 length += (bits==32);
689 break;
690 case 0311:
691 length += (bits==16);
692 break;
693 case 0312:
694 break;
695 case 0320:
696 length += (bits==32);
697 break;
698 case 0321:
699 length += (bits==16);
700 break;
701 case 0322:
702 break;
703 case 0330:
704 codes++, length++; break;
705 case 0331:
706 case 0332:
707 break;
708 case 0333:
709 length++; break;
710 case 0340: case 0341: case 0342:
711 if (ins->oprs[0].segment != NO_SEG)
712 errfunc (ERR_NONFATAL, "attempt to reserve non-constant"
713 " quantity of BSS space");
714 else
715 length += ins->oprs[0].offset << (c-0340);
716 break;
717 case 0370: case 0371: case 0372:
718 break;
719 case 0373:
720 length++; break;
721 default: /* can't do it by 'case' statements */
722 if (c>=0100 && c<=0277) { /* it's an EA */
723 ea ea_data;
724 if (!process_ea (&ins->oprs[(c>>3)&7], &ea_data, bits, 0,
725 ins->forw_ref)) {
726 errfunc (ERR_NONFATAL, "invalid effective address");
727 return -1;
728 } else
729 length += ea_data.size;
730 } else
731 errfunc (ERR_PANIC, "internal instruction table corrupt"
732 ": instruction code 0x%02X given", c);
734 return length;
737 static void gencode (long segment, long offset, int bits,
738 insn *ins, const char *codes, long insn_end)
740 static char condval[] = { /* conditional opcodes */
741 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
742 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
743 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
745 unsigned char c;
746 unsigned char bytes[4];
747 long data, size;
749 while (*codes)
750 switch (c = *codes++)
752 case 01: case 02: case 03:
753 out (offset, segment, codes, OUT_RAWDATA+c, NO_SEG, NO_SEG);
754 codes += c;
755 offset += c;
756 break;
758 case 04: case 06:
759 switch (ins->oprs[0].basereg)
761 case R_CS:
762 bytes[0] = 0x0E + (c == 0x04 ? 1 : 0); break;
763 case R_DS:
764 bytes[0] = 0x1E + (c == 0x04 ? 1 : 0); break;
765 case R_ES:
766 bytes[0] = 0x06 + (c == 0x04 ? 1 : 0); break;
767 case R_SS:
768 bytes[0] = 0x16 + (c == 0x04 ? 1 : 0); break;
769 default:
770 errfunc (ERR_PANIC, "bizarre 8086 segment register received");
772 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
773 offset++;
774 break;
776 case 05: case 07:
777 switch (ins->oprs[0].basereg) {
778 case R_FS: bytes[0] = 0xA0 + (c == 0x05 ? 1 : 0); break;
779 case R_GS: bytes[0] = 0xA8 + (c == 0x05 ? 1 : 0); break;
780 default:
781 errfunc (ERR_PANIC, "bizarre 386 segment register received");
783 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
784 offset++;
785 break;
787 case 010: case 011: case 012:
788 bytes[0] = *codes++ + regval(&ins->oprs[c-010]);
789 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
790 offset += 1;
791 break;
793 case 017:
794 bytes[0] = 0;
795 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
796 offset += 1;
797 break;
799 case 014: case 015: case 016:
800 if (ins->oprs[c-014].offset < -128
801 || ins->oprs[c-014].offset > 127)
803 errfunc (ERR_WARNING, "signed byte value exceeds bounds");
806 if (ins->oprs[c-014].segment != NO_SEG)
808 data = ins->oprs[c-014].offset;
809 out (offset, segment, &data, OUT_ADDRESS+1,
810 ins->oprs[c-014].segment, ins->oprs[c-014].wrt);
812 else {
813 bytes[0] = ins->oprs[c-014].offset;
814 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
816 offset += 1;
817 break;
819 case 020: case 021: case 022:
820 if (ins->oprs[c-020].offset < -256
821 || ins->oprs[c-020].offset > 255)
823 errfunc (ERR_WARNING, "byte value exceeds bounds");
825 if (ins->oprs[c-020].segment != NO_SEG) {
826 data = ins->oprs[c-020].offset;
827 out (offset, segment, &data, OUT_ADDRESS+1,
828 ins->oprs[c-020].segment, ins->oprs[c-020].wrt);
830 else {
831 bytes[0] = ins->oprs[c-020].offset;
832 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
834 offset += 1;
835 break;
837 case 024: case 025: case 026:
838 if (ins->oprs[c-024].offset < 0 || ins->oprs[c-024].offset > 255)
839 errfunc (ERR_WARNING, "unsigned byte value exceeds bounds");
840 if (ins->oprs[c-024].segment != NO_SEG) {
841 data = ins->oprs[c-024].offset;
842 out (offset, segment, &data, OUT_ADDRESS+1,
843 ins->oprs[c-024].segment, ins->oprs[c-024].wrt);
845 else {
846 bytes[0] = ins->oprs[c-024].offset;
847 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
849 offset += 1;
850 break;
852 case 030: case 031: case 032:
853 if (ins->oprs[c-030].segment == NO_SEG &&
854 ins->oprs[c-030].wrt == NO_SEG &&
855 (ins->oprs[c-030].offset < -65536L ||
856 ins->oprs[c-030].offset > 65535L))
858 errfunc (ERR_WARNING, "word value exceeds bounds");
860 data = ins->oprs[c-030].offset;
861 out (offset, segment, &data, OUT_ADDRESS+2,
862 ins->oprs[c-030].segment, ins->oprs[c-030].wrt);
863 offset += 2;
864 break;
866 case 034: case 035: case 036:
867 if ( ins->oprs[c-034].type & (BITS16|BITS32) )
868 size = (ins->oprs[c-034].type & BITS16) ? 2 : 4;
869 else
870 size = (bits == 16) ? 2 : 4;
871 data = ins->oprs[c-034].offset;
872 if (size==2 && (data < -65536L || data > 65535L))
873 errfunc (ERR_WARNING, "word value exceeds bounds");
874 out (offset, segment, &data, OUT_ADDRESS+size,
875 ins->oprs[c-034].segment, ins->oprs[c-034].wrt);
876 offset += size;
877 break;
879 case 037:
880 if (ins->oprs[0].segment == NO_SEG)
881 errfunc (ERR_NONFATAL, "value referenced by FAR is not"
882 " relocatable");
883 data = 0L;
884 out (offset, segment, &data, OUT_ADDRESS+2,
885 outfmt->segbase(1+ins->oprs[0].segment),
886 ins->oprs[0].wrt);
887 offset += 2;
888 break;
890 case 040: case 041: case 042:
891 data = ins->oprs[c-040].offset;
892 out (offset, segment, &data, OUT_ADDRESS+4,
893 ins->oprs[c-040].segment, ins->oprs[c-040].wrt);
894 offset += 4;
895 break;
897 case 044: case 045: case 046:
898 data = ins->oprs[c-044].offset;
899 size = ((ins->oprs[c-044].addr_size ?
900 ins->oprs[c-044].addr_size : bits) == 16 ? 2 : 4);
901 if (size==2 && (data < -65536L || data > 65535L))
902 errfunc (ERR_WARNING, "word value exceeds bounds");
903 out (offset, segment, &data, OUT_ADDRESS+size,
904 ins->oprs[c-044].segment, ins->oprs[c-044].wrt);
905 offset += size;
906 break;
908 case 050: case 051: case 052:
909 if (ins->oprs[c-050].segment != segment)
910 errfunc (ERR_NONFATAL, "short relative jump outside segment");
911 data = ins->oprs[c-050].offset - insn_end;
912 if (data > 127 || data < -128)
913 errfunc (ERR_NONFATAL, "short jump is out of range");
914 bytes[0] = data;
915 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
916 offset += 1;
917 break;
919 case 060: case 061: case 062:
920 if (ins->oprs[c-060].segment != segment) {
921 data = ins->oprs[c-060].offset;
922 out (offset, segment, &data, OUT_REL2ADR+insn_end-offset,
923 ins->oprs[c-060].segment, ins->oprs[c-060].wrt);
924 } else {
925 data = ins->oprs[c-060].offset - insn_end;
926 out (offset, segment, &data,
927 OUT_ADDRESS+2, NO_SEG, NO_SEG);
929 offset += 2;
930 break;
932 case 064: case 065: case 066:
933 if ( ins->oprs[c-064].type & (BITS16|BITS32) )
934 size = (ins->oprs[c-064].type & BITS16) ? 2 : 4;
935 else
936 size = (bits == 16) ? 2 : 4;
937 if (ins->oprs[c-064].segment != segment) {
938 long reltype = (size == 2 ? OUT_REL2ADR : OUT_REL4ADR);
939 data = ins->oprs[c-064].offset;
940 out (offset, segment, &data, reltype+insn_end-offset,
941 ins->oprs[c-064].segment, ins->oprs[c-064].wrt);
942 } else {
943 data = ins->oprs[c-064].offset - insn_end;
944 out (offset, segment, &data,
945 OUT_ADDRESS+size, NO_SEG, NO_SEG);
947 offset += size;
948 break;
950 case 070: case 071: case 072:
951 if (ins->oprs[c-070].segment != segment) {
952 data = ins->oprs[c-070].offset;
953 out (offset, segment, &data, OUT_REL4ADR+insn_end-offset,
954 ins->oprs[c-070].segment, ins->oprs[c-070].wrt);
955 } else {
956 data = ins->oprs[c-070].offset - insn_end;
957 out (offset, segment, &data,
958 OUT_ADDRESS+4, NO_SEG, NO_SEG);
960 offset += 4;
961 break;
963 case 0130: case 0131: case 0132:
964 data = ins->oprs[c-0130].offset;
965 if (is_sbyte(ins, c-0130, 16)) {
966 bytes[0] = data;
967 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
968 offset++;
969 } else {
970 if (ins->oprs[c-0130].segment == NO_SEG &&
971 ins->oprs[c-0130].wrt == NO_SEG &&
972 (data < -65536L || data > 65535L)) {
973 errfunc (ERR_WARNING, "word value exceeds bounds");
975 out (offset, segment, &data, OUT_ADDRESS+2,
976 ins->oprs[c-0130].segment, ins->oprs[c-0130].wrt);
977 offset += 2;
979 break;
981 case 0133: case 0134: case 0135:
982 codes++;
983 bytes[0] = *codes++;
984 if (is_sbyte(ins, c-0133, 16)) bytes[0] |= 2; /* s-bit */
985 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
986 offset++;
987 break;
989 case 0140: case 0141: case 0142:
990 data = ins->oprs[c-0140].offset;
991 if (is_sbyte(ins, c-0140, 32)) {
992 bytes[0] = data;
993 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
994 offset++;
995 } else {
996 out (offset, segment, &data, OUT_ADDRESS+4,
997 ins->oprs[c-0140].segment, ins->oprs[c-0140].wrt);
998 offset += 4;
1000 break;
1002 case 0143: case 0144: case 0145:
1003 codes++;
1004 bytes[0] = *codes++;
1005 if (is_sbyte(ins, c-0143, 32)) bytes[0] |= 2; /* s-bit */
1006 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
1007 offset++;
1008 break;
1010 case 0300: case 0301: case 0302:
1011 if (chsize (&ins->oprs[c-0300], bits)) {
1012 *bytes = 0x67;
1013 out (offset, segment, bytes,
1014 OUT_RAWDATA+1, NO_SEG, NO_SEG);
1015 offset += 1;
1016 } else
1017 offset += 0;
1018 break;
1020 case 0310:
1021 if (bits==32) {
1022 *bytes = 0x67;
1023 out (offset, segment, bytes,
1024 OUT_RAWDATA+1, NO_SEG, NO_SEG);
1025 offset += 1;
1026 } else
1027 offset += 0;
1028 break;
1030 case 0311:
1031 if (bits==16) {
1032 *bytes = 0x67;
1033 out (offset, segment, bytes,
1034 OUT_RAWDATA+1, NO_SEG, NO_SEG);
1035 offset += 1;
1036 } else
1037 offset += 0;
1038 break;
1040 case 0312:
1041 break;
1043 case 0320:
1044 if (bits==32) {
1045 *bytes = 0x66;
1046 out (offset, segment, bytes,
1047 OUT_RAWDATA+1, NO_SEG, NO_SEG);
1048 offset += 1;
1049 } else
1050 offset += 0;
1051 break;
1053 case 0321:
1054 if (bits==16) {
1055 *bytes = 0x66;
1056 out (offset, segment, bytes,
1057 OUT_RAWDATA+1, NO_SEG, NO_SEG);
1058 offset += 1;
1059 } else
1060 offset += 0;
1061 break;
1063 case 0322:
1064 break;
1066 case 0330:
1067 *bytes = *codes++ ^ condval[ins->condition];
1068 out (offset, segment, bytes,
1069 OUT_RAWDATA+1, NO_SEG, NO_SEG);
1070 offset += 1;
1071 break;
1073 case 0331:
1074 case 0332:
1075 break;
1077 case 0333:
1078 *bytes = 0xF3;
1079 out (offset, segment, bytes,
1080 OUT_RAWDATA+1, NO_SEG, NO_SEG);
1081 offset += 1;
1082 break;
1084 case 0340: case 0341: case 0342:
1085 if (ins->oprs[0].segment != NO_SEG)
1086 errfunc (ERR_PANIC, "non-constant BSS size in pass two");
1087 else {
1088 long size = ins->oprs[0].offset << (c-0340);
1089 if (size > 0)
1090 out (offset, segment, NULL,
1091 OUT_RESERVE+size, NO_SEG, NO_SEG);
1092 offset += size;
1094 break;
1096 case 0370: case 0371: case 0372:
1097 break;
1099 case 0373:
1100 *bytes = bits==16 ? 3 : 5;
1101 out (offset, segment, bytes,
1102 OUT_RAWDATA+1, NO_SEG, NO_SEG);
1103 offset += 1;
1104 break;
1106 default: /* can't do it by 'case' statements */
1107 if (c>=0100 && c<=0277) { /* it's an EA */
1108 ea ea_data;
1109 int rfield;
1110 unsigned char *p;
1111 long s;
1113 if (c<=0177) /* pick rfield from operand b */
1114 rfield = regval (&ins->oprs[c&7]);
1115 else /* rfield is constant */
1116 rfield = c & 7;
1118 if (!process_ea (&ins->oprs[(c>>3)&7], &ea_data, bits, rfield,
1119 ins->forw_ref))
1121 errfunc (ERR_NONFATAL, "invalid effective address");
1124 p = bytes;
1125 *p++ = ea_data.modrm;
1126 if (ea_data.sib_present)
1127 *p++ = ea_data.sib;
1129 s = p-bytes;
1130 out (offset, segment, bytes, OUT_RAWDATA + s,
1131 NO_SEG, NO_SEG);
1133 switch (ea_data.bytes) {
1134 case 0:
1135 break;
1136 case 1:
1137 if (ins->oprs[(c>>3)&7].segment != NO_SEG) {
1138 data = ins->oprs[(c>>3)&7].offset;
1139 out (offset, segment, &data, OUT_ADDRESS+1,
1140 ins->oprs[(c>>3)&7].segment,
1141 ins->oprs[(c>>3)&7].wrt);
1142 } else {
1143 *bytes = ins->oprs[(c>>3)&7].offset;
1144 out (offset, segment, bytes, OUT_RAWDATA+1,
1145 NO_SEG, NO_SEG);
1147 s++;
1148 break;
1149 case 2:
1150 case 4:
1151 data = ins->oprs[(c>>3)&7].offset;
1152 out (offset, segment, &data,
1153 OUT_ADDRESS+ea_data.bytes,
1154 ins->oprs[(c>>3)&7].segment, ins->oprs[(c>>3)&7].wrt);
1155 s += ea_data.bytes;
1156 break;
1158 offset += s;
1159 } else
1160 errfunc (ERR_PANIC, "internal instruction table corrupt"
1161 ": instruction code 0x%02X given", c);
1165 #include "regvals.c"
1167 static int regval (operand *o)
1169 if ( o->basereg < EXPR_REG_START || o->basereg >= REG_ENUM_LIMIT ) {
1170 errfunc (ERR_PANIC, "invalid operand passed to regval()");
1172 return regvals[o->basereg];
1175 static int matches (struct itemplate *itemp, insn *instruction)
1177 int i, size[3], asize, oprs, ret;
1179 ret = 100;
1182 * Check the opcode
1184 if (itemp->opcode != instruction->opcode) return 0;
1187 * Count the operands
1189 if (itemp->operands != instruction->operands) return 0;
1192 * Check that no spurious colons or TOs are present
1194 for (i=0; i<itemp->operands; i++)
1195 if (instruction->oprs[i].type & ~itemp->opd[i] & (COLON|TO))
1196 return 0;
1199 * Check that the operand flags all match up
1201 for (i=0; i<itemp->operands; i++)
1202 if (itemp->opd[i] & ~instruction->oprs[i].type ||
1203 ((itemp->opd[i] & SIZE_MASK) &&
1204 ((itemp->opd[i] ^ instruction->oprs[i].type) & SIZE_MASK)))
1206 if ((itemp->opd[i] & ~instruction->oprs[i].type & NON_SIZE) ||
1207 (instruction->oprs[i].type & SIZE_MASK))
1208 return 0;
1209 else
1210 /* ret = 1; */
1211 return 1;
1215 * Check operand sizes
1217 if (itemp->flags & IF_ARMASK) {
1218 size[0] = size[1] = size[2] = 0;
1220 switch (itemp->flags & IF_ARMASK) {
1221 case IF_AR0: i = 0; break;
1222 case IF_AR1: i = 1; break;
1223 case IF_AR2: i = 2; break;
1224 default: break; /* Shouldn't happen */
1226 if (itemp->flags & IF_SB) {
1227 size[i] = BITS8;
1228 } else if (itemp->flags & IF_SW) {
1229 size[i] = BITS16;
1230 } else if (itemp->flags & IF_SD) {
1231 size[i] = BITS32;
1233 } else {
1234 asize = 0;
1235 if (itemp->flags & IF_SB) {
1236 asize = BITS8;
1237 oprs = itemp->operands;
1238 } else if (itemp->flags & IF_SW) {
1239 asize = BITS16;
1240 oprs = itemp->operands;
1241 } else if (itemp->flags & IF_SD) {
1242 asize = BITS32;
1243 oprs = itemp->operands;
1245 size[0] = size[1] = size[2] = asize;
1248 if (itemp->flags & (IF_SM | IF_SM2)) {
1249 oprs = (itemp->flags & IF_SM2 ? 2 : itemp->operands);
1250 asize = 0;
1251 for (i=0; i<oprs; i++) {
1252 if ( (asize = itemp->opd[i] & SIZE_MASK) != 0) {
1253 int j;
1254 for (j=0; j<oprs; j++)
1255 size[j] = asize;
1256 break;
1259 } else {
1260 oprs = itemp->operands;
1263 for (i=0; i<itemp->operands; i++)
1264 if (!(itemp->opd[i] & SIZE_MASK) &&
1265 (instruction->oprs[i].type & SIZE_MASK & ~size[i]))
1266 /* ret = 2; */
1267 return 2;
1270 * Check template is okay at the set cpu level
1272 if ((itemp->flags & IF_PLEVEL) > cpu) return 3;
1275 * Check if special handling needed for Jumps
1277 if ((unsigned char)(itemp->code[0]) >= 0370) return 99;
1279 return ret;
1282 static ea *process_ea (operand *input, ea *output, int addrbits, int rfield,
1283 int forw_ref)
1285 if (!(REGISTER & ~input->type)) { /* it's a single register */
1286 static int regs[] = {
1287 R_AL, R_CL, R_DL, R_BL, R_AH, R_CH, R_DH, R_BH,
1288 R_AX, R_CX, R_DX, R_BX, R_SP, R_BP, R_SI, R_DI,
1289 R_EAX, R_ECX, R_EDX, R_EBX, R_ESP, R_EBP, R_ESI, R_EDI,
1290 R_MM0, R_MM1, R_MM2, R_MM3, R_MM4, R_MM5, R_MM6, R_MM7,
1291 R_XMM0, R_XMM1, R_XMM2, R_XMM3, R_XMM4, R_XMM5, R_XMM6, R_XMM7
1293 int i;
1295 for (i=0; i<elements(regs); i++)
1296 if (input->basereg == regs[i]) break;
1297 if (i<elements(regs)) {
1298 output->sib_present = FALSE;/* no SIB necessary */
1299 output->bytes = 0; /* no offset necessary either */
1300 output->modrm = 0xC0 | (rfield << 3) | (i & 7);
1302 else
1303 return NULL;
1304 } else { /* it's a memory reference */
1305 if (input->basereg==-1 && (input->indexreg==-1 || input->scale==0)) {
1306 /* it's a pure offset */
1307 if (input->addr_size)
1308 addrbits = input->addr_size;
1309 output->sib_present = FALSE;
1310 output->bytes = (addrbits==32 ? 4 : 2);
1311 output->modrm = (addrbits==32 ? 5 : 6) | (rfield << 3);
1313 else { /* it's an indirection */
1314 int i=input->indexreg, b=input->basereg, s=input->scale;
1315 long o=input->offset, seg=input->segment;
1316 int hb=input->hintbase, ht=input->hinttype;
1317 int t;
1319 if (s==0) i = -1; /* make this easy, at least */
1321 if (i==R_EAX || i==R_EBX || i==R_ECX || i==R_EDX
1322 || i==R_EBP || i==R_ESP || i==R_ESI || i==R_EDI
1323 || b==R_EAX || b==R_EBX || b==R_ECX || b==R_EDX
1324 || b==R_EBP || b==R_ESP || b==R_ESI || b==R_EDI) {
1325 /* it must be a 32-bit memory reference. Firstly we have
1326 * to check that all registers involved are type Exx. */
1327 if (i!=-1 && i!=R_EAX && i!=R_EBX && i!=R_ECX && i!=R_EDX
1328 && i!=R_EBP && i!=R_ESP && i!=R_ESI && i!=R_EDI)
1329 return NULL;
1330 if (b!=-1 && b!=R_EAX && b!=R_EBX && b!=R_ECX && b!=R_EDX
1331 && b!=R_EBP && b!=R_ESP && b!=R_ESI && b!=R_EDI)
1332 return NULL;
1334 /* While we're here, ensure the user didn't specify WORD. */
1335 if (input->addr_size == 16)
1336 return NULL;
1338 /* now reorganise base/index */
1339 if (s == 1 && b != i && b != -1 && i != -1 &&
1340 ((hb==b&&ht==EAH_NOTBASE) || (hb==i&&ht==EAH_MAKEBASE)))
1341 t = b, b = i, i = t; /* swap if hints say so */
1342 if (b==i) /* convert EAX+2*EAX to 3*EAX */
1343 b = -1, s++;
1344 if (b==-1 && s==1 && !(hb == i && ht == EAH_NOTBASE))
1345 b = i, i = -1; /* make single reg base, unless hint */
1346 if (((s==2 && i!=R_ESP && !(input->eaflags & EAF_TIMESTWO)) ||
1347 s==3 || s==5 || s==9) && b==-1)
1348 b = i, s--; /* convert 3*EAX to EAX+2*EAX */
1349 if (i==-1 && b!=R_ESP && (input->eaflags & EAF_TIMESTWO))
1350 i = b, b = -1, s = 1;
1351 /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */
1352 if (s==1 && i==R_ESP) /* swap ESP into base if scale is 1 */
1353 i = b, b = R_ESP;
1354 if (i==R_ESP || (s!=1 && s!=2 && s!=4 && s!=8 && i!=-1))
1355 return NULL; /* wrong, for various reasons */
1357 if (i==-1 && b!=R_ESP) {/* no SIB needed */
1358 int mod, rm;
1359 switch(b) {
1360 case R_EAX: rm = 0; break;
1361 case R_ECX: rm = 1; break;
1362 case R_EDX: rm = 2; break;
1363 case R_EBX: rm = 3; break;
1364 case R_EBP: rm = 5; break;
1365 case R_ESI: rm = 6; break;
1366 case R_EDI: rm = 7; break;
1367 case -1: rm = 5; break;
1368 default: /* should never happen */
1369 return NULL;
1371 if (b==-1 || (b!=R_EBP && o==0 &&
1372 seg==NO_SEG && !forw_ref &&
1373 !(input->eaflags &
1374 (EAF_BYTEOFFS|EAF_WORDOFFS))))
1375 mod = 0;
1376 else if (input->eaflags & EAF_BYTEOFFS ||
1377 (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
1378 !(input->eaflags & EAF_WORDOFFS))) {
1379 mod = 1;
1381 else
1382 mod = 2;
1384 output->sib_present = FALSE;
1385 output->bytes = (b==-1 || mod==2 ? 4 : mod);
1386 output->modrm = (mod<<6) | (rfield<<3) | rm;
1388 else { /* we need a SIB */
1389 int mod, scale, index, base;
1391 switch (b) {
1392 case R_EAX: base = 0; break;
1393 case R_ECX: base = 1; break;
1394 case R_EDX: base = 2; break;
1395 case R_EBX: base = 3; break;
1396 case R_ESP: base = 4; break;
1397 case R_EBP: case -1: base = 5; break;
1398 case R_ESI: base = 6; break;
1399 case R_EDI: base = 7; break;
1400 default: /* then what the smeg is it? */
1401 return NULL; /* panic */
1404 switch (i) {
1405 case R_EAX: index = 0; break;
1406 case R_ECX: index = 1; break;
1407 case R_EDX: index = 2; break;
1408 case R_EBX: index = 3; break;
1409 case -1: index = 4; break;
1410 case R_EBP: index = 5; break;
1411 case R_ESI: index = 6; break;
1412 case R_EDI: index = 7; break;
1413 default: /* then what the smeg is it? */
1414 return NULL; /* panic */
1417 if (i==-1) s = 1;
1418 switch (s) {
1419 case 1: scale = 0; break;
1420 case 2: scale = 1; break;
1421 case 4: scale = 2; break;
1422 case 8: scale = 3; break;
1423 default: /* then what the smeg is it? */
1424 return NULL; /* panic */
1427 if (b==-1 || (b!=R_EBP && o==0 &&
1428 seg==NO_SEG && !forw_ref &&
1429 !(input->eaflags &
1430 (EAF_BYTEOFFS|EAF_WORDOFFS))))
1431 mod = 0;
1432 else if (input->eaflags & EAF_BYTEOFFS ||
1433 (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
1434 !(input->eaflags & EAF_WORDOFFS)))
1435 mod = 1;
1436 else
1437 mod = 2;
1439 output->sib_present = TRUE;
1440 output->bytes = (b==-1 || mod==2 ? 4 : mod);
1441 output->modrm = (mod<<6) | (rfield<<3) | 4;
1442 output->sib = (scale<<6) | (index<<3) | base;
1445 else { /* it's 16-bit */
1446 int mod, rm;
1448 /* check all registers are BX, BP, SI or DI */
1449 if ((b!=-1 && b!=R_BP && b!=R_BX && b!=R_SI && b!=R_DI) ||
1450 (i!=-1 && i!=R_BP && i!=R_BX && i!=R_SI && i!=R_DI))
1451 return NULL;
1453 /* ensure the user didn't specify DWORD */
1454 if (input->addr_size == 32)
1455 return NULL;
1457 if (s!=1 && i!=-1) return NULL;/* no can do, in 16-bit EA */
1458 if (b==-1 && i!=-1) { int tmp = b; b = i; i = tmp; } /* swap */
1459 if ((b==R_SI || b==R_DI) && i!=-1)
1460 { int tmp = b; b = i; i = tmp; }
1461 /* have BX/BP as base, SI/DI index */
1462 if (b==i) return NULL;/* shouldn't ever happen, in theory */
1463 if (i!=-1 && b!=-1 &&
1464 (i==R_BP || i==R_BX || b==R_SI || b==R_DI))
1465 return NULL; /* invalid combinations */
1466 if (b==-1) /* pure offset: handled above */
1467 return NULL; /* so if it gets to here, panic! */
1469 rm = -1;
1470 if (i!=-1)
1471 switch (i*256 + b) {
1472 case R_SI*256+R_BX: rm=0; break;
1473 case R_DI*256+R_BX: rm=1; break;
1474 case R_SI*256+R_BP: rm=2; break;
1475 case R_DI*256+R_BP: rm=3; break;
1477 else
1478 switch (b) {
1479 case R_SI: rm=4; break;
1480 case R_DI: rm=5; break;
1481 case R_BP: rm=6; break;
1482 case R_BX: rm=7; break;
1484 if (rm==-1) /* can't happen, in theory */
1485 return NULL; /* so panic if it does */
1487 if (o==0 && seg==NO_SEG && !forw_ref && rm!=6 &&
1488 !(input->eaflags & (EAF_BYTEOFFS|EAF_WORDOFFS)))
1489 mod = 0;
1490 else if (input->eaflags & EAF_BYTEOFFS ||
1491 (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
1492 !(input->eaflags & EAF_WORDOFFS)))
1493 mod = 1;
1494 else
1495 mod = 2;
1497 output->sib_present = FALSE; /* no SIB - it's 16-bit */
1498 output->bytes = mod; /* bytes of offset needed */
1499 output->modrm = (mod<<6) | (rfield<<3) | rm;
1503 output->size = 1 + output->sib_present + output->bytes;
1504 return output;
1507 static int chsize (operand *input, int addrbits)
1509 if (!(MEMORY & ~input->type)) {
1510 int i=input->indexreg, b=input->basereg;
1512 if (input->scale==0) i = -1;
1514 if (i == -1 && b == -1) /* pure offset */
1515 return (input->addr_size != 0 && input->addr_size != addrbits);
1517 if (i==R_EAX || i==R_EBX || i==R_ECX || i==R_EDX
1518 || i==R_EBP || i==R_ESP || i==R_ESI || i==R_EDI
1519 || b==R_EAX || b==R_EBX || b==R_ECX || b==R_EDX
1520 || b==R_EBP || b==R_ESP || b==R_ESI || b==R_EDI)
1521 return (addrbits==16);
1522 else
1523 return (addrbits==32);
1525 else
1526 return 0;