NASM 0.98.09
[nasm.git] / assemble.c
blob8058979ecfbd84432a67cee800268ac6df603049
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 address-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 * \50, \51, \52 - a byte relative operand, from operand 0, 1 or 2
29 * \60, \61, \62 - a word relative operand, from operand 0, 1 or 2
30 * \64, \65, \66 - select between \6[012] and \7[012] depending on 16/32 bit
31 * assembly mode or the address-size override on the operand
32 * \70, \71, \72 - a long relative operand, from operand 0, 1 or 2
33 * \1ab - a ModRM, calculated on EA in operand a, with the spare
34 * field the register value of operand b.
35 * \130,\131,\132 - an immediate word or signed byte for operand 0, 1, or 2
36 * \133,\134,\135 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
37 * is a signed byte rather than a word.
38 * \140,\141,\142 - an immediate dword or signed byte for operand 0, 1, or 2
39 * \143,\144,\145 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
40 * is a signed byte rather than a dword.
41 * \2ab - a ModRM, calculated on EA in operand a, with the spare
42 * field equal to digit b.
43 * \30x - might be an 0x67 byte, depending on the address size of
44 * the memory reference in operand x.
45 * \310 - indicates fixed 16-bit address size, i.e. optional 0x67.
46 * \311 - indicates fixed 32-bit address size, i.e. optional 0x67.
47 * \312 - (disassembler only) marker on LOOP, LOOPxx instructions.
48 * \320 - indicates fixed 16-bit operand size, i.e. optional 0x66.
49 * \321 - indicates fixed 32-bit operand size, i.e. optional 0x66.
50 * \322 - indicates that this instruction is only valid when the
51 * operand size is the default (instruction to disassembler,
52 * generates no code in the assembler)
53 * \330 - a literal byte follows in the code stream, to be added
54 * to the condition code value of the instruction.
55 * \331 - instruction not valid with REP prefix. Hint for
56 * disassembler only; for SSE instructions.
57 * \332 - disassemble a rep (0xF3 byte) prefix as repe not rep.
58 * \333 - REP prefix (0xF3 byte); for SSE instructions. Not encoded
59 * as a literal byte in order to aid the disassembler.
60 * \340 - reserve <operand 0> bytes of uninitialised storage.
61 * Operand 0 had better be a segmentless constant.
62 * \370,\371,\372 - match only if operand 0, 1, 2 meets byte jump criteria.
63 * \373 - assemble 0x03 if bits==16, 0x05 if bits==32;
64 * used for conditional jump over longer jump
67 #include <stdio.h>
68 #include <string.h>
70 #include "nasm.h"
71 #include "nasmlib.h"
72 #include "assemble.h"
73 #include "insns.h"
75 extern struct itemplate *nasm_instructions[];
77 typedef struct {
78 int sib_present; /* is a SIB byte necessary? */
79 int bytes; /* # of bytes of offset needed */
80 int size; /* lazy - this is sib+bytes+1 */
81 unsigned char modrm, sib; /* the bytes themselves */
82 } ea;
84 static unsigned long cpu; /* cpu level received from nasm.c */
85 static efunc errfunc;
86 static struct ofmt *outfmt;
87 static ListGen *list;
89 static long calcsize (long, long, int, insn *, char *);
90 static void gencode (long, long, int, insn *, char *, long);
91 static int regval (operand *o);
92 static int matches (struct itemplate *, insn *);
93 static ea * process_ea (operand *, ea *, int, int, int);
94 static int chsize (operand *, int);
97 * This routine wrappers the real output format's output routine,
98 * in order to pass a copy of the data off to the listing file
99 * generator at the same time.
101 static void out (long offset, long segto, void *data, unsigned long type,
102 long segment, long wrt)
104 static long lineno;
105 static char *lnfname;
107 if ((type & OUT_TYPMASK) == OUT_ADDRESS) {
108 if (segment != NO_SEG || wrt != NO_SEG) {
110 * This address is relocated. We must write it as
111 * OUT_ADDRESS, so there's no work to be done here.
113 list->output (offset, data, type);
115 else {
116 unsigned char p[4], *q = p;
118 * This is a non-relocated address, and we're going to
119 * convert it into RAWDATA format.
121 if ((type & OUT_SIZMASK) == 4) {
122 WRITELONG (q, * (long *) data);
123 list->output (offset, p, OUT_RAWDATA+4);
125 else {
126 WRITESHORT (q, * (long *) data);
127 list->output (offset, p, OUT_RAWDATA+2);
131 else if ((type & OUT_TYPMASK) == OUT_RAWDATA) {
132 list->output (offset, data, type);
134 else if ((type & OUT_TYPMASK) == OUT_RESERVE) {
135 list->output (offset, NULL, type);
137 else if ((type & OUT_TYPMASK) == OUT_REL2ADR ||
138 (type & OUT_TYPMASK) == OUT_REL4ADR) {
139 list->output (offset, data, type);
142 if (src_get(&lineno,&lnfname))
143 outfmt->current_dfmt->linenum(lnfname,lineno,segto);
145 outfmt->output (segto, data, type, segment, wrt);
148 static int jmp_match (long segment, long offset, int bits,
149 insn *ins, char *code)
150 { long isize;
151 unsigned char c = code[0];
154 if (c != 0370) return 0;
155 if (ins->oprs[0].opflags & OPFLAG_FORWARD) return (! pass0); /*1;*/ /* match a forward reference */
157 isize = calcsize (segment, offset, bits, ins, code);
158 if (ins->oprs[0].segment != segment) return 0;
159 isize = ins->oprs[0].offset - offset - isize; /* isize is now the delta */
160 if (isize >= -128L && isize <= 127L) return 1; /* it is byte size */
162 return 0;
166 long assemble (long segment, long offset, int bits, unsigned long cp,
167 insn *instruction, struct ofmt *output, efunc error,
168 ListGen *listgen)
170 struct itemplate *temp;
171 int j;
172 int size_prob;
173 long insn_end;
174 long itimes;
175 long start = offset;
176 long wsize = 0; /* size for DB etc. */
178 errfunc = error; /* to pass to other functions */
179 cpu = cp;
180 outfmt = output; /* likewise */
181 list = listgen; /* and again */
183 switch (instruction->opcode)
185 case -1: return 0;
186 case I_DB: wsize = 1; break;
187 case I_DW: wsize = 2; break;
188 case I_DD: wsize = 4; break;
189 case I_DQ: wsize = 8; break;
190 case I_DT: wsize = 10; break;
193 if (wsize) {
194 extop * e;
195 long t = instruction->times;
196 if (t < 0)
197 errfunc(ERR_PANIC, "instruction->times < 0 (%ld) in assemble()",t);
199 while (t--) /* repeat TIMES times */
201 for (e = instruction->eops; e; e = e->next)
203 if (e->type == EOT_DB_NUMBER)
205 if (wsize == 1) {
206 if (e->segment != NO_SEG)
207 errfunc (ERR_NONFATAL,
208 "one-byte relocation attempted");
209 else {
210 unsigned char out_byte = e->offset;
211 out (offset, segment, &out_byte, OUT_RAWDATA+1,
212 NO_SEG, NO_SEG);
215 else if (wsize > 5) {
216 errfunc (ERR_NONFATAL, "integer supplied to a D%c"
217 " instruction", wsize==8 ? 'Q' : 'T');
219 else
220 out (offset, segment, &e->offset,
221 OUT_ADDRESS+wsize, e->segment,
222 e->wrt);
223 offset += wsize;
225 else if (e->type == EOT_DB_STRING)
227 int align;
229 out (offset, segment, e->stringval,
230 OUT_RAWDATA+e->stringlen, NO_SEG, NO_SEG);
231 align = e->stringlen % wsize;
233 if (align) {
234 align = wsize - align;
235 out (offset, segment, "\0\0\0\0\0\0\0\0",
236 OUT_RAWDATA+align, NO_SEG, NO_SEG);
238 offset += e->stringlen + align;
241 if (t > 0 && t == instruction->times-1)
244 * Dummy call to list->output to give the offset to the
245 * listing module.
247 list->output (offset, NULL, OUT_RAWDATA);
248 list->uplevel (LIST_TIMES);
251 if (instruction->times > 1)
252 list->downlevel (LIST_TIMES);
253 return offset - start;
256 if (instruction->opcode == I_INCBIN)
258 static char fname[FILENAME_MAX];
259 FILE * fp;
260 long len;
262 len = FILENAME_MAX-1;
263 if (len > instruction->eops->stringlen)
264 len = instruction->eops->stringlen;
265 strncpy (fname, instruction->eops->stringval, len);
266 fname[len] = '\0';
268 if ( (fp = fopen(fname, "rb")) == NULL)
269 error (ERR_NONFATAL, "`incbin': unable to open file `%s'", fname);
270 else if (fseek(fp, 0L, SEEK_END) < 0)
271 error (ERR_NONFATAL, "`incbin': unable to seek on file `%s'",
272 fname);
273 else
275 static char buf[2048];
276 long t = instruction->times;
277 long base = 0;
279 len = ftell (fp);
280 if (instruction->eops->next) {
281 base = instruction->eops->next->offset;
282 len -= base;
283 if (instruction->eops->next->next &&
284 len > instruction->eops->next->next->offset)
285 len = instruction->eops->next->next->offset;
288 * Dummy call to list->output to give the offset to the
289 * listing module.
291 list->output (offset, NULL, OUT_RAWDATA);
292 list->uplevel(LIST_INCBIN);
293 while (t--)
295 long l;
297 fseek (fp, base, SEEK_SET);
298 l = len;
299 while (l > 0) {
300 long m = fread (buf, 1, (l>sizeof(buf)?sizeof(buf):l),
301 fp);
302 if (!m) {
304 * This shouldn't happen unless the file
305 * actually changes while we are reading
306 * it.
308 error (ERR_NONFATAL, "`incbin': unexpected EOF while"
309 " reading file `%s'", fname);
310 t=0; /* Try to exit cleanly */
311 break;
313 out (offset, segment, buf, OUT_RAWDATA+m,
314 NO_SEG, NO_SEG);
315 l -= m;
318 list->downlevel(LIST_INCBIN);
319 if (instruction->times > 1) {
321 * Dummy call to list->output to give the offset to the
322 * listing module.
324 list->output (offset, NULL, OUT_RAWDATA);
325 list->uplevel(LIST_TIMES);
326 list->downlevel(LIST_TIMES);
328 fclose (fp);
329 return instruction->times * len;
331 return 0; /* if we're here, there's an error */
334 size_prob = FALSE;
335 temp = nasm_instructions[instruction->opcode];
336 while (temp->opcode != -1) {
337 int m = matches (temp, instruction);
338 if (m == 99)
339 m += jmp_match(segment, offset, bits, instruction, temp->code);
341 if (m == 100) /* matches! */
343 char *codes = temp->code;
344 long insn_size = calcsize(segment, offset, bits,
345 instruction, codes);
346 itimes = instruction->times;
347 if (insn_size < 0) /* shouldn't be, on pass two */
348 error (ERR_PANIC, "errors made it through from pass one");
349 else while (itimes--) {
350 insn_end = offset + insn_size;
351 for (j=0; j<instruction->nprefix; j++) {
352 unsigned char c=0;
353 switch (instruction->prefixes[j]) {
354 case P_LOCK:
355 c = 0xF0; break;
356 case P_REPNE: case P_REPNZ:
357 c = 0xF2; break;
358 case P_REPE: case P_REPZ: case P_REP:
359 c = 0xF3; break;
360 case R_CS: c = 0x2E; break;
361 case R_DS: c = 0x3E; break;
362 case R_ES: c = 0x26; break;
363 case R_FS: c = 0x64; break;
364 case R_GS: c = 0x65; break;
365 case R_SS: c = 0x36; break;
366 case P_A16:
367 if (bits != 16)
368 c = 0x67;
369 break;
370 case P_A32:
371 if (bits != 32)
372 c = 0x67;
373 break;
374 case P_O16:
375 if (bits != 16)
376 c = 0x66;
377 break;
378 case P_O32:
379 if (bits != 32)
380 c = 0x66;
381 break;
382 default:
383 error (ERR_PANIC,
384 "invalid instruction prefix");
386 if (c != 0) {
387 out (offset, segment, &c, OUT_RAWDATA+1,
388 NO_SEG, NO_SEG);
389 offset++;
392 gencode (segment, offset, bits, instruction, codes, insn_end);
393 offset += insn_size;
394 if (itimes > 0 && itimes == instruction->times-1) {
396 * Dummy call to list->output to give the offset to the
397 * listing module.
399 list->output (offset, NULL, OUT_RAWDATA);
400 list->uplevel (LIST_TIMES);
403 if (instruction->times > 1)
404 list->downlevel (LIST_TIMES);
405 return offset - start;
406 } else if (m > 0 && m > size_prob) {
407 size_prob = m;
409 temp++;
412 if (temp->opcode == -1) { /* didn't match any instruction */
413 if (size_prob == 1) /* would have matched, but for size */
414 error (ERR_NONFATAL, "operation size not specified");
415 else if (size_prob == 2)
416 error (ERR_NONFATAL, "mismatch in operand sizes");
417 else if (size_prob == 3)
418 error (ERR_NONFATAL, "no instruction for this cpu level");
419 else
420 error (ERR_NONFATAL,
421 "invalid combination of opcode and operands");
423 return 0;
426 long insn_size (long segment, long offset, int bits, unsigned long cp,
427 insn *instruction, efunc error)
429 struct itemplate *temp;
431 errfunc = error; /* to pass to other functions */
432 cpu = cp;
434 if (instruction->opcode == -1)
435 return 0;
437 if (instruction->opcode == I_DB ||
438 instruction->opcode == I_DW ||
439 instruction->opcode == I_DD ||
440 instruction->opcode == I_DQ ||
441 instruction->opcode == I_DT)
443 extop *e;
444 long isize, osize, wsize = 0; /* placate gcc */
446 isize = 0;
447 switch (instruction->opcode)
449 case I_DB: wsize = 1; break;
450 case I_DW: wsize = 2; break;
451 case I_DD: wsize = 4; break;
452 case I_DQ: wsize = 8; break;
453 case I_DT: wsize = 10; break;
456 for (e = instruction->eops; e; e = e->next)
458 long align;
460 osize = 0;
461 if (e->type == EOT_DB_NUMBER)
462 osize = 1;
463 else if (e->type == EOT_DB_STRING)
464 osize = e->stringlen;
466 align = (-osize) % wsize;
467 if (align < 0)
468 align += wsize;
469 isize += osize + align;
471 return isize * instruction->times;
474 if (instruction->opcode == I_INCBIN)
476 char fname[FILENAME_MAX];
477 FILE * fp;
478 long len;
480 len = FILENAME_MAX-1;
481 if (len > instruction->eops->stringlen)
482 len = instruction->eops->stringlen;
483 strncpy (fname, instruction->eops->stringval, len);
484 fname[len] = '\0';
485 if ( (fp = fopen(fname, "rb")) == NULL )
486 error (ERR_NONFATAL, "`incbin': unable to open file `%s'", fname);
487 else if (fseek(fp, 0L, SEEK_END) < 0)
488 error (ERR_NONFATAL, "`incbin': unable to seek on file `%s'",
489 fname);
490 else
492 len = ftell (fp);
493 fclose (fp);
494 if (instruction->eops->next)
496 len -= instruction->eops->next->offset;
497 if (instruction->eops->next->next &&
498 len > instruction->eops->next->next->offset)
500 len = instruction->eops->next->next->offset;
503 return instruction->times * len;
505 return 0; /* if we're here, there's an error */
508 temp = nasm_instructions[instruction->opcode];
509 while (temp->opcode != -1) {
510 int m = matches(temp, instruction);
511 if (m == 99)
512 m += jmp_match(segment, offset, bits, instruction, temp->code);
514 if (m == 100) {
515 /* we've matched an instruction. */
516 long isize;
517 char * codes = temp->code;
518 int j;
520 isize = calcsize(segment, offset, bits, instruction, codes);
521 if (isize < 0)
522 return -1;
523 for (j = 0; j < instruction->nprefix; j++)
525 if ((instruction->prefixes[j] != P_A16 &&
526 instruction->prefixes[j] != P_O16 && bits==16) ||
527 (instruction->prefixes[j] != P_A32 &&
528 instruction->prefixes[j] != P_O32 && bits==32))
530 isize++;
533 return isize * instruction->times;
535 temp++;
537 return -1; /* didn't match any instruction */
541 /* check that opn[op] is a signed byte of size 16 or 32,
542 and return the signed value*/
543 static int is_sbyte (insn *ins, int op, int size)
545 signed long v;
546 int ret;
548 ret = !(ins->forw_ref && ins->oprs[op].opflags ) && /* dead in the water on forward reference or External */
549 !(ins->oprs[op].type & (BITS16|BITS32)) && /* John Coffman's 3/24/01 patch - fbk - 10/16/01 */
550 ins->oprs[op].wrt==NO_SEG && ins->oprs[op].segment==NO_SEG;
552 v = ins->oprs[op].offset;
553 if (size==16) v = (signed short)v; /* sign extend if 16 bits */
555 return ret && v>=-128L && v<=127L;
558 static long calcsize (long segment, long offset, int bits,
559 insn *ins, char *codes)
561 long length = 0;
562 unsigned char c;
564 (void) segment; /* Don't warn that this parameter is unused */
565 (void) offset; /* Don't warn that this parameter is unused */
567 while (*codes) switch (c = *codes++) {
568 case 01: case 02: case 03:
569 codes += c, length += c; break;
570 case 04: case 05: case 06: case 07:
571 length++; break;
572 case 010: case 011: case 012:
573 codes++, length++; break;
574 case 017:
575 length++; break;
576 case 014: case 015: case 016:
577 length++; break;
578 case 020: case 021: case 022:
579 length++; break;
580 case 024: case 025: case 026:
581 length++; break;
582 case 030: case 031: case 032:
583 length += 2; break;
584 case 034: case 035: case 036:
585 length += ((ins->oprs[c-034].addr_size ?
586 ins->oprs[c-034].addr_size : bits) == 16 ? 2 : 4); break;
587 case 037:
588 length += 2; break;
589 case 040: case 041: case 042:
590 length += 4; break;
591 case 050: case 051: case 052:
592 length++; break;
593 case 060: case 061: case 062:
594 length += 2; break;
595 case 064: case 065: case 066:
596 length += ((ins->oprs[c-064].addr_size ?
597 ins->oprs[c-064].addr_size : bits) == 16 ? 2 : 4); break;
598 case 070: case 071: case 072:
599 length += 4; break;
600 case 0130: case 0131: case 0132:
601 length += is_sbyte(ins, c-0130, 16) ? 1 : 2; break;
602 case 0133: case 0134: case 0135:
603 codes+=2; length++; break;
604 case 0140: case 0141: case 0142:
605 length += is_sbyte(ins, c-0140, 32) ? 1 : 4; break;
606 case 0143: case 0144: case 0145:
607 codes+=2; length++; break;
608 case 0300: case 0301: case 0302:
609 length += chsize (&ins->oprs[c-0300], bits);
610 break;
611 case 0310:
612 length += (bits==32);
613 break;
614 case 0311:
615 length += (bits==16);
616 break;
617 case 0312:
618 break;
619 case 0320:
620 length += (bits==32);
621 break;
622 case 0321:
623 length += (bits==16);
624 break;
625 case 0322:
626 break;
627 case 0330:
628 codes++, length++; break;
629 case 0331:
630 case 0332:
631 break;
632 case 0333:
633 length++; break;
634 case 0340: case 0341: case 0342:
635 if (ins->oprs[0].segment != NO_SEG)
636 errfunc (ERR_NONFATAL, "attempt to reserve non-constant"
637 " quantity of BSS space");
638 else
639 length += ins->oprs[0].offset << (c-0340);
640 break;
641 case 0370: case 0371: case 0372:
642 break;
643 case 0373:
644 length++; break;
645 default: /* can't do it by 'case' statements */
646 if (c>=0100 && c<=0277) { /* it's an EA */
647 ea ea_data;
648 if (!process_ea (&ins->oprs[(c>>3)&7], &ea_data, bits, 0,
649 ins->forw_ref)) {
650 errfunc (ERR_NONFATAL, "invalid effective address");
651 return -1;
652 } else
653 length += ea_data.size;
654 } else
655 errfunc (ERR_PANIC, "internal instruction table corrupt"
656 ": instruction code 0x%02X given", c);
658 return length;
661 static void gencode (long segment, long offset, int bits,
662 insn *ins, char *codes, long insn_end)
664 static char condval[] = { /* conditional opcodes */
665 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
666 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
667 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
669 unsigned char c;
670 unsigned char bytes[4];
671 long data, size;
673 while (*codes)
674 switch (c = *codes++)
676 case 01: case 02: case 03:
677 out (offset, segment, codes, OUT_RAWDATA+c, NO_SEG, NO_SEG);
678 codes += c;
679 offset += c;
680 break;
682 case 04: case 06:
683 switch (ins->oprs[0].basereg)
685 case R_CS:
686 bytes[0] = 0x0E + (c == 0x04 ? 1 : 0); break;
687 case R_DS:
688 bytes[0] = 0x1E + (c == 0x04 ? 1 : 0); break;
689 case R_ES:
690 bytes[0] = 0x06 + (c == 0x04 ? 1 : 0); break;
691 case R_SS:
692 bytes[0] = 0x16 + (c == 0x04 ? 1 : 0); break;
693 default:
694 errfunc (ERR_PANIC, "bizarre 8086 segment register received");
696 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
697 offset++;
698 break;
700 case 05: case 07:
701 switch (ins->oprs[0].basereg) {
702 case R_FS: bytes[0] = 0xA0 + (c == 0x05 ? 1 : 0); break;
703 case R_GS: bytes[0] = 0xA8 + (c == 0x05 ? 1 : 0); break;
704 default:
705 errfunc (ERR_PANIC, "bizarre 386 segment register received");
707 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
708 offset++;
709 break;
711 case 010: case 011: case 012:
712 bytes[0] = *codes++ + regval(&ins->oprs[c-010]);
713 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
714 offset += 1;
715 break;
717 case 017:
718 bytes[0] = 0;
719 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
720 offset += 1;
721 break;
723 case 014: case 015: case 016:
724 if (ins->oprs[c-014].offset < -128
725 || ins->oprs[c-014].offset > 127)
727 errfunc (ERR_WARNING, "signed byte value exceeds bounds");
730 if (ins->oprs[c-014].segment != NO_SEG)
732 data = ins->oprs[c-014].offset;
733 out (offset, segment, &data, OUT_ADDRESS+1,
734 ins->oprs[c-014].segment, ins->oprs[c-014].wrt);
736 else {
737 bytes[0] = ins->oprs[c-014].offset;
738 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
740 offset += 1;
741 break;
743 case 020: case 021: case 022:
744 if (ins->oprs[c-020].offset < -256
745 || ins->oprs[c-020].offset > 255)
747 errfunc (ERR_WARNING, "byte value exceeds bounds");
749 if (ins->oprs[c-020].segment != NO_SEG) {
750 data = ins->oprs[c-020].offset;
751 out (offset, segment, &data, OUT_ADDRESS+1,
752 ins->oprs[c-020].segment, ins->oprs[c-020].wrt);
754 else {
755 bytes[0] = ins->oprs[c-020].offset;
756 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
758 offset += 1;
759 break;
761 case 024: case 025: case 026:
762 if (ins->oprs[c-024].offset < 0 || ins->oprs[c-024].offset > 255)
763 errfunc (ERR_WARNING, "unsigned byte value exceeds bounds");
764 if (ins->oprs[c-024].segment != NO_SEG) {
765 data = ins->oprs[c-024].offset;
766 out (offset, segment, &data, OUT_ADDRESS+1,
767 ins->oprs[c-024].segment, ins->oprs[c-024].wrt);
769 else {
770 bytes[0] = ins->oprs[c-024].offset;
771 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
773 offset += 1;
774 break;
776 case 030: case 031: case 032:
777 if (ins->oprs[c-030].segment == NO_SEG &&
778 ins->oprs[c-030].wrt == NO_SEG &&
779 (ins->oprs[c-030].offset < -65536L ||
780 ins->oprs[c-030].offset > 65535L))
782 errfunc (ERR_WARNING, "word value exceeds bounds");
784 data = ins->oprs[c-030].offset;
785 out (offset, segment, &data, OUT_ADDRESS+2,
786 ins->oprs[c-030].segment, ins->oprs[c-030].wrt);
787 offset += 2;
788 break;
790 case 034: case 035: case 036:
791 data = ins->oprs[c-034].offset;
792 size = ((ins->oprs[c-034].addr_size ?
793 ins->oprs[c-034].addr_size : bits) == 16 ? 2 : 4);
794 if (size==16 && (data < -65536L || data > 65535L))
795 errfunc (ERR_WARNING, "word value exceeds bounds");
796 out (offset, segment, &data, OUT_ADDRESS+size,
797 ins->oprs[c-034].segment, ins->oprs[c-034].wrt);
798 offset += size;
799 break;
801 case 037:
802 if (ins->oprs[0].segment == NO_SEG)
803 errfunc (ERR_NONFATAL, "value referenced by FAR is not"
804 " relocatable");
805 data = 0L;
806 out (offset, segment, &data, OUT_ADDRESS+2,
807 outfmt->segbase(1+ins->oprs[0].segment),
808 ins->oprs[0].wrt);
809 offset += 2;
810 break;
812 case 040: case 041: case 042:
813 data = ins->oprs[c-040].offset;
814 out (offset, segment, &data, OUT_ADDRESS+4,
815 ins->oprs[c-040].segment, ins->oprs[c-040].wrt);
816 offset += 4;
817 break;
819 case 050: case 051: case 052:
820 if (ins->oprs[c-050].segment != segment)
821 errfunc (ERR_NONFATAL, "short relative jump outside segment");
822 data = ins->oprs[c-050].offset - insn_end;
823 if (data > 127 || data < -128)
824 errfunc (ERR_NONFATAL, "short jump is out of range");
825 bytes[0] = data;
826 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
827 offset += 1;
828 break;
830 case 060: case 061: case 062:
831 if (ins->oprs[c-060].segment != segment) {
832 data = ins->oprs[c-060].offset;
833 out (offset, segment, &data, OUT_REL2ADR+insn_end-offset,
834 ins->oprs[c-060].segment, ins->oprs[c-060].wrt);
835 } else {
836 data = ins->oprs[c-060].offset - insn_end;
837 out (offset, segment, &data,
838 OUT_ADDRESS+2, NO_SEG, NO_SEG);
840 offset += 2;
841 break;
843 case 064: case 065: case 066:
844 size = ((ins->oprs[c-064].addr_size ?
845 ins->oprs[c-064].addr_size : bits) == 16 ? 2 : 4);
846 if (ins->oprs[c-064].segment != segment) {
847 data = ins->oprs[c-064].offset;
848 size = (bits == 16 ? OUT_REL2ADR : OUT_REL4ADR);
849 out (offset, segment, &data, size+insn_end-offset,
850 ins->oprs[c-064].segment, ins->oprs[c-064].wrt);
851 size = (bits == 16 ? 2 : 4);
852 } else {
853 data = ins->oprs[c-064].offset - insn_end;
854 out (offset, segment, &data,
855 OUT_ADDRESS+size, NO_SEG, NO_SEG);
857 offset += size;
858 break;
860 case 070: case 071: case 072:
861 if (ins->oprs[c-070].segment != segment) {
862 data = ins->oprs[c-070].offset;
863 out (offset, segment, &data, OUT_REL4ADR+insn_end-offset,
864 ins->oprs[c-070].segment, ins->oprs[c-070].wrt);
865 } else {
866 data = ins->oprs[c-070].offset - insn_end;
867 out (offset, segment, &data,
868 OUT_ADDRESS+4, NO_SEG, NO_SEG);
870 offset += 4;
871 break;
873 case 0130: case 0131: case 0132:
874 data = ins->oprs[c-0130].offset;
875 if (is_sbyte(ins, c-0130, 16)) {
876 out (offset, segment, &data, OUT_RAWDATA+1, NO_SEG, NO_SEG);
877 offset++;
878 } else {
879 if (ins->oprs[c-0130].segment == NO_SEG &&
880 ins->oprs[c-0130].wrt == NO_SEG &&
881 (data < -65536L || data > 65535L)) {
882 errfunc (ERR_WARNING, "word value exceeds bounds");
884 out (offset, segment, &data, OUT_ADDRESS+2,
885 ins->oprs[c-0130].segment, ins->oprs[c-0130].wrt);
886 offset += 2;
888 break;
890 case 0133: case 0134: case 0135:
891 codes++;
892 bytes[0] = *codes++;
893 if (is_sbyte(ins, c-0133, 16)) bytes[0] |= 2; /* s-bit */
894 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
895 offset++;
896 break;
898 case 0140: case 0141: case 0142:
899 data = ins->oprs[c-0140].offset;
900 if (is_sbyte(ins, c-0140, 32)) {
901 out (offset, segment, &data, OUT_RAWDATA+1, NO_SEG, NO_SEG);
902 offset++;
903 } else {
904 out (offset, segment, &data, OUT_ADDRESS+4,
905 ins->oprs[c-0140].segment, ins->oprs[c-0140].wrt);
906 offset += 4;
908 break;
910 case 0143: case 0144: case 0145:
911 codes++;
912 bytes[0] = *codes++;
913 if (is_sbyte(ins, c-0143, 32)) bytes[0] |= 2; /* s-bit */
914 out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
915 offset++;
916 break;
918 case 0300: case 0301: case 0302:
919 if (chsize (&ins->oprs[c-0300], bits)) {
920 *bytes = 0x67;
921 out (offset, segment, bytes,
922 OUT_RAWDATA+1, NO_SEG, NO_SEG);
923 offset += 1;
924 } else
925 offset += 0;
926 break;
928 case 0310:
929 if (bits==32) {
930 *bytes = 0x67;
931 out (offset, segment, bytes,
932 OUT_RAWDATA+1, NO_SEG, NO_SEG);
933 offset += 1;
934 } else
935 offset += 0;
936 break;
938 case 0311:
939 if (bits==16) {
940 *bytes = 0x67;
941 out (offset, segment, bytes,
942 OUT_RAWDATA+1, NO_SEG, NO_SEG);
943 offset += 1;
944 } else
945 offset += 0;
946 break;
948 case 0312:
949 break;
951 case 0320:
952 if (bits==32) {
953 *bytes = 0x66;
954 out (offset, segment, bytes,
955 OUT_RAWDATA+1, NO_SEG, NO_SEG);
956 offset += 1;
957 } else
958 offset += 0;
959 break;
961 case 0321:
962 if (bits==16) {
963 *bytes = 0x66;
964 out (offset, segment, bytes,
965 OUT_RAWDATA+1, NO_SEG, NO_SEG);
966 offset += 1;
967 } else
968 offset += 0;
969 break;
971 case 0322:
972 break;
974 case 0330:
975 *bytes = *codes++ ^ condval[ins->condition];
976 out (offset, segment, bytes,
977 OUT_RAWDATA+1, NO_SEG, NO_SEG);
978 offset += 1;
979 break;
981 case 0331:
982 case 0332:
983 break;
985 case 0333:
986 *bytes = 0xF3;
987 out (offset, segment, bytes,
988 OUT_RAWDATA+1, NO_SEG, NO_SEG);
989 offset += 1;
990 break;
992 case 0340: case 0341: case 0342:
993 if (ins->oprs[0].segment != NO_SEG)
994 errfunc (ERR_PANIC, "non-constant BSS size in pass two");
995 else {
996 long size = ins->oprs[0].offset << (c-0340);
997 if (size > 0)
998 out (offset, segment, NULL,
999 OUT_RESERVE+size, NO_SEG, NO_SEG);
1000 offset += size;
1002 break;
1004 case 0370: case 0371: case 0372:
1005 break;
1007 case 0373:
1008 *bytes = bits==16 ? 3 : 5;
1009 out (offset, segment, bytes,
1010 OUT_RAWDATA+1, NO_SEG, NO_SEG);
1011 offset += 1;
1012 break;
1014 default: /* can't do it by 'case' statements */
1015 if (c>=0100 && c<=0277) { /* it's an EA */
1016 ea ea_data;
1017 int rfield;
1018 unsigned char *p;
1019 long s;
1021 if (c<=0177) /* pick rfield from operand b */
1022 rfield = regval (&ins->oprs[c&7]);
1023 else /* rfield is constant */
1024 rfield = c & 7;
1026 if (!process_ea (&ins->oprs[(c>>3)&7], &ea_data, bits, rfield,
1027 ins->forw_ref))
1029 errfunc (ERR_NONFATAL, "invalid effective address");
1032 p = bytes;
1033 *p++ = ea_data.modrm;
1034 if (ea_data.sib_present)
1035 *p++ = ea_data.sib;
1037 s = p-bytes;
1038 out (offset, segment, bytes, OUT_RAWDATA + s,
1039 NO_SEG, NO_SEG);
1041 switch (ea_data.bytes) {
1042 case 0:
1043 break;
1044 case 1:
1045 if (ins->oprs[(c>>3)&7].segment != NO_SEG) {
1046 data = ins->oprs[(c>>3)&7].offset;
1047 out (offset, segment, &data, OUT_ADDRESS+1,
1048 ins->oprs[(c>>3)&7].segment,
1049 ins->oprs[(c>>3)&7].wrt);
1050 } else {
1051 *bytes = ins->oprs[(c>>3)&7].offset;
1052 out (offset, segment, bytes, OUT_RAWDATA+1,
1053 NO_SEG, NO_SEG);
1055 s++;
1056 break;
1057 case 2:
1058 case 4:
1059 data = ins->oprs[(c>>3)&7].offset;
1060 out (offset, segment, &data,
1061 OUT_ADDRESS+ea_data.bytes,
1062 ins->oprs[(c>>3)&7].segment, ins->oprs[(c>>3)&7].wrt);
1063 s += ea_data.bytes;
1064 break;
1066 offset += s;
1067 } else
1068 errfunc (ERR_PANIC, "internal instruction table corrupt"
1069 ": instruction code 0x%02X given", c);
1073 static int regval (operand *o)
1075 switch (o->basereg) {
1076 case R_EAX: case R_AX: case R_AL: case R_ES: case R_CR0: case R_DR0:
1077 case R_ST0: case R_MM0: case R_XMM0:
1078 return 0;
1079 case R_ECX: case R_CX: case R_CL: case R_CS: case R_DR1: case R_ST1:
1080 case R_MM1: case R_XMM1:
1081 return 1;
1082 case R_EDX: case R_DX: case R_DL: case R_SS: case R_CR2: case R_DR2:
1083 case R_ST2: case R_MM2: case R_XMM2:
1084 return 2;
1085 case R_EBX: case R_BX: case R_BL: case R_DS: case R_CR3: case R_DR3:
1086 case R_TR3: case R_ST3: case R_MM3: case R_XMM3:
1087 return 3;
1088 case R_ESP: case R_SP: case R_AH: case R_FS: case R_CR4: case R_TR4:
1089 case R_ST4: case R_MM4: case R_XMM4:
1090 return 4;
1091 case R_EBP: case R_BP: case R_CH: case R_GS: case R_TR5: case R_ST5:
1092 case R_MM5: case R_XMM5:
1093 return 5;
1094 case R_ESI: case R_SI: case R_DH: case R_DR6: case R_TR6: case R_ST6:
1095 case R_MM6: case R_XMM6:
1096 return 6;
1097 case R_EDI: case R_DI: case R_BH: case R_DR7: case R_TR7: case R_ST7:
1098 case R_MM7: case R_XMM7:
1099 return 7;
1100 default: /* panic */
1101 errfunc (ERR_PANIC, "invalid register operand given to regval()");
1102 return 0;
1106 static int matches (struct itemplate *itemp, insn *instruction)
1108 int i, size[3], asize, oprs, ret;
1110 ret = 100;
1113 * Check the opcode
1115 if (itemp->opcode != instruction->opcode) return 0;
1118 * Count the operands
1120 if (itemp->operands != instruction->operands) return 0;
1123 * Check that no spurious colons or TOs are present
1125 for (i=0; i<itemp->operands; i++)
1126 if (instruction->oprs[i].type & ~itemp->opd[i] & (COLON|TO))
1127 return 0;
1130 * Check that the operand flags all match up
1132 for (i=0; i<itemp->operands; i++)
1133 if (itemp->opd[i] & ~instruction->oprs[i].type ||
1134 ((itemp->opd[i] & SIZE_MASK) &&
1135 ((itemp->opd[i] ^ instruction->oprs[i].type) & SIZE_MASK)))
1137 if ((itemp->opd[i] & ~instruction->oprs[i].type & NON_SIZE) ||
1138 (instruction->oprs[i].type & SIZE_MASK))
1139 return 0;
1140 else
1141 /* ret = 1; */
1142 return 1;
1146 * Check operand sizes
1148 if (itemp->flags & IF_ARMASK) {
1149 size[0] = size[1] = size[2] = 0;
1151 switch (itemp->flags & IF_ARMASK) {
1152 case IF_AR0: i = 0; break;
1153 case IF_AR1: i = 1; break;
1154 case IF_AR2: i = 2; break;
1155 default: break; /* Shouldn't happen */
1157 if (itemp->flags & IF_SB) {
1158 size[i] = BITS8;
1159 } else if (itemp->flags & IF_SW) {
1160 size[i] = BITS16;
1161 } else if (itemp->flags & IF_SD) {
1162 size[i] = BITS32;
1164 } else {
1165 asize = 0;
1166 if (itemp->flags & IF_SB) {
1167 asize = BITS8;
1168 oprs = itemp->operands;
1169 } else if (itemp->flags & IF_SW) {
1170 asize = BITS16;
1171 oprs = itemp->operands;
1172 } else if (itemp->flags & IF_SD) {
1173 asize = BITS32;
1174 oprs = itemp->operands;
1176 size[0] = size[1] = size[2] = asize;
1179 if (itemp->flags & (IF_SM | IF_SM2)) {
1180 oprs = (itemp->flags & IF_SM2 ? 2 : itemp->operands);
1181 asize = 0;
1182 for (i=0; i<oprs; i++) {
1183 if ( (asize = itemp->opd[i] & SIZE_MASK) != 0) {
1184 int j;
1185 for (j=0; j<oprs; j++)
1186 size[j] = asize;
1187 break;
1190 } else {
1191 oprs = itemp->operands;
1194 for (i=0; i<itemp->operands; i++)
1195 if (!(itemp->opd[i] & SIZE_MASK) &&
1196 (instruction->oprs[i].type & SIZE_MASK & ~size[i]))
1197 /* ret = 2; */
1198 return 2;
1201 * Check template is okay at the set cpu level
1203 if ((itemp->flags & IF_PLEVEL) > cpu) return 3;
1206 * Check if special handling needed for Jumps
1208 if ((unsigned char)(itemp->code[0]) >= 0370) return 99;
1210 return ret;
1213 static ea *process_ea (operand *input, ea *output, int addrbits, int rfield,
1214 int forw_ref)
1216 if (!(REGISTER & ~input->type)) { /* it's a single register */
1217 static int regs[] = {
1218 R_AL, R_CL, R_DL, R_BL, R_AH, R_CH, R_DH, R_BH,
1219 R_AX, R_CX, R_DX, R_BX, R_SP, R_BP, R_SI, R_DI,
1220 R_EAX, R_ECX, R_EDX, R_EBX, R_ESP, R_EBP, R_ESI, R_EDI,
1221 R_MM0, R_MM1, R_MM2, R_MM3, R_MM4, R_MM5, R_MM6, R_MM7,
1222 R_XMM0, R_XMM1, R_XMM2, R_XMM3, R_XMM4, R_XMM5, R_XMM6, R_XMM7
1224 int i;
1226 for (i=0; i<elements(regs); i++)
1227 if (input->basereg == regs[i]) break;
1228 if (i<elements(regs)) {
1229 output->sib_present = FALSE;/* no SIB necessary */
1230 output->bytes = 0; /* no offset necessary either */
1231 output->modrm = 0xC0 | (rfield << 3) | (i & 7);
1233 else
1234 return NULL;
1235 } else { /* it's a memory reference */
1236 if (input->basereg==-1 && (input->indexreg==-1 || input->scale==0)) {
1237 /* it's a pure offset */
1238 if (input->addr_size)
1239 addrbits = input->addr_size;
1240 output->sib_present = FALSE;
1241 output->bytes = (addrbits==32 ? 4 : 2);
1242 output->modrm = (addrbits==32 ? 5 : 6) | (rfield << 3);
1244 else { /* it's an indirection */
1245 int i=input->indexreg, b=input->basereg, s=input->scale;
1246 long o=input->offset, seg=input->segment;
1247 int hb=input->hintbase, ht=input->hinttype;
1248 int t;
1250 if (s==0) i = -1; /* make this easy, at least */
1252 if (i==R_EAX || i==R_EBX || i==R_ECX || i==R_EDX
1253 || i==R_EBP || i==R_ESP || i==R_ESI || i==R_EDI
1254 || b==R_EAX || b==R_EBX || b==R_ECX || b==R_EDX
1255 || b==R_EBP || b==R_ESP || b==R_ESI || b==R_EDI) {
1256 /* it must be a 32-bit memory reference. Firstly we have
1257 * to check that all registers involved are type Exx. */
1258 if (i!=-1 && i!=R_EAX && i!=R_EBX && i!=R_ECX && i!=R_EDX
1259 && i!=R_EBP && i!=R_ESP && i!=R_ESI && i!=R_EDI)
1260 return NULL;
1261 if (b!=-1 && b!=R_EAX && b!=R_EBX && b!=R_ECX && b!=R_EDX
1262 && b!=R_EBP && b!=R_ESP && b!=R_ESI && b!=R_EDI)
1263 return NULL;
1265 /* While we're here, ensure the user didn't specify WORD. */
1266 if (input->addr_size == 16)
1267 return NULL;
1269 /* now reorganise base/index */
1270 if (s == 1 && b != i && b != -1 && i != -1 &&
1271 ((hb==b&&ht==EAH_NOTBASE) || (hb==i&&ht==EAH_MAKEBASE)))
1272 t = b, b = i, i = t; /* swap if hints say so */
1273 if (b==i) /* convert EAX+2*EAX to 3*EAX */
1274 b = -1, s++;
1275 if (b==-1 && s==1 && !(hb == i && ht == EAH_NOTBASE))
1276 b = i, i = -1; /* make single reg base, unless hint */
1277 if (((s==2 && i!=R_ESP && !(input->eaflags & EAF_TIMESTWO)) ||
1278 s==3 || s==5 || s==9) && b==-1)
1279 b = i, s--; /* convert 3*EAX to EAX+2*EAX */
1280 if (s==1 && i==R_ESP) /* swap ESP into base if scale is 1 */
1281 i = b, b = R_ESP;
1282 if (i==R_ESP || (s!=1 && s!=2 && s!=4 && s!=8 && i!=-1))
1283 return NULL; /* wrong, for various reasons */
1285 if (i==-1 && b!=R_ESP) {/* no SIB needed */
1286 int mod, rm;
1287 switch(b) {
1288 case R_EAX: rm = 0; break;
1289 case R_ECX: rm = 1; break;
1290 case R_EDX: rm = 2; break;
1291 case R_EBX: rm = 3; break;
1292 case R_EBP: rm = 5; break;
1293 case R_ESI: rm = 6; break;
1294 case R_EDI: rm = 7; break;
1295 case -1: rm = 5; break;
1296 default: /* should never happen */
1297 return NULL;
1299 if (b==-1 || (b!=R_EBP && o==0 &&
1300 seg==NO_SEG && !forw_ref &&
1301 !(input->eaflags &
1302 (EAF_BYTEOFFS|EAF_WORDOFFS))))
1303 mod = 0;
1304 else if (input->eaflags & EAF_BYTEOFFS ||
1305 (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
1306 !(input->eaflags & EAF_WORDOFFS))) {
1307 mod = 1;
1309 else
1310 mod = 2;
1312 output->sib_present = FALSE;
1313 output->bytes = (b==-1 || mod==2 ? 4 : mod);
1314 output->modrm = (mod<<6) | (rfield<<3) | rm;
1316 else { /* we need a SIB */
1317 int mod, scale, index, base;
1319 switch (b) {
1320 case R_EAX: base = 0; break;
1321 case R_ECX: base = 1; break;
1322 case R_EDX: base = 2; break;
1323 case R_EBX: base = 3; break;
1324 case R_ESP: base = 4; break;
1325 case R_EBP: case -1: base = 5; break;
1326 case R_ESI: base = 6; break;
1327 case R_EDI: base = 7; break;
1328 default: /* then what the smeg is it? */
1329 return NULL; /* panic */
1332 switch (i) {
1333 case R_EAX: index = 0; break;
1334 case R_ECX: index = 1; break;
1335 case R_EDX: index = 2; break;
1336 case R_EBX: index = 3; break;
1337 case -1: index = 4; break;
1338 case R_EBP: index = 5; break;
1339 case R_ESI: index = 6; break;
1340 case R_EDI: index = 7; break;
1341 default: /* then what the smeg is it? */
1342 return NULL; /* panic */
1345 if (i==-1) s = 1;
1346 switch (s) {
1347 case 1: scale = 0; break;
1348 case 2: scale = 1; break;
1349 case 4: scale = 2; break;
1350 case 8: scale = 3; break;
1351 default: /* then what the smeg is it? */
1352 return NULL; /* panic */
1355 if (b==-1 || (b!=R_EBP && o==0 &&
1356 seg==NO_SEG && !forw_ref &&
1357 !(input->eaflags &
1358 (EAF_BYTEOFFS|EAF_WORDOFFS))))
1359 mod = 0;
1360 else if (input->eaflags & EAF_BYTEOFFS ||
1361 (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
1362 !(input->eaflags & EAF_WORDOFFS)))
1363 mod = 1;
1364 else
1365 mod = 2;
1367 output->sib_present = TRUE;
1368 output->bytes = (b==-1 || mod==2 ? 4 : mod);
1369 output->modrm = (mod<<6) | (rfield<<3) | 4;
1370 output->sib = (scale<<6) | (index<<3) | base;
1373 else { /* it's 16-bit */
1374 int mod, rm;
1376 /* check all registers are BX, BP, SI or DI */
1377 if ((b!=-1 && b!=R_BP && b!=R_BX && b!=R_SI && b!=R_DI) ||
1378 (i!=-1 && i!=R_BP && i!=R_BX && i!=R_SI && i!=R_DI))
1379 return NULL;
1381 /* ensure the user didn't specify DWORD */
1382 if (input->addr_size == 32)
1383 return NULL;
1385 if (s!=1 && i!=-1) return NULL;/* no can do, in 16-bit EA */
1386 if (b==-1 && i!=-1) b ^= i ^= b ^= i; /* swap them round */
1387 if ((b==R_SI || b==R_DI) && i!=-1)
1388 b ^= i ^= b ^= i; /* have BX/BP as base, SI/DI index */
1389 if (b==i) return NULL;/* shouldn't ever happen, in theory */
1390 if (i!=-1 && b!=-1 &&
1391 (i==R_BP || i==R_BX || b==R_SI || b==R_DI))
1392 return NULL; /* invalid combinations */
1393 if (b==-1) /* pure offset: handled above */
1394 return NULL; /* so if it gets to here, panic! */
1396 rm = -1;
1397 if (i!=-1)
1398 switch (i*256 + b) {
1399 case R_SI*256+R_BX: rm=0; break;
1400 case R_DI*256+R_BX: rm=1; break;
1401 case R_SI*256+R_BP: rm=2; break;
1402 case R_DI*256+R_BP: rm=3; break;
1404 else
1405 switch (b) {
1406 case R_SI: rm=4; break;
1407 case R_DI: rm=5; break;
1408 case R_BP: rm=6; break;
1409 case R_BX: rm=7; break;
1411 if (rm==-1) /* can't happen, in theory */
1412 return NULL; /* so panic if it does */
1414 if (o==0 && seg==NO_SEG && !forw_ref && rm!=6 &&
1415 !(input->eaflags & (EAF_BYTEOFFS|EAF_WORDOFFS)))
1416 mod = 0;
1417 else if (input->eaflags & EAF_BYTEOFFS ||
1418 (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
1419 !(input->eaflags & EAF_WORDOFFS)))
1420 mod = 1;
1421 else
1422 mod = 2;
1424 output->sib_present = FALSE; /* no SIB - it's 16-bit */
1425 output->bytes = mod; /* bytes of offset needed */
1426 output->modrm = (mod<<6) | (rfield<<3) | rm;
1430 output->size = 1 + output->sib_present + output->bytes;
1431 return output;
1434 static int chsize (operand *input, int addrbits)
1436 if (!(MEMORY & ~input->type)) {
1437 int i=input->indexreg, b=input->basereg;
1439 if (input->scale==0) i = -1;
1441 if (i == -1 && b == -1) /* pure offset */
1442 return (input->addr_size != 0 && input->addr_size != addrbits);
1444 if (i==R_EAX || i==R_EBX || i==R_ECX || i==R_EDX
1445 || i==R_EBP || i==R_ESP || i==R_ESI || i==R_EDI
1446 || b==R_EAX || b==R_EBX || b==R_ECX || b==R_EDX
1447 || b==R_EBP || b==R_ESP || b==R_ESI || b==R_EDI)
1448 return (addrbits==16);
1449 else
1450 return (addrbits==32);
1452 else
1453 return 0;