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
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
78 extern struct itemplate
*nasm_instructions
[];
81 int sib_present
; /* is a SIB byte necessary? */
82 int bytes
; /* # of bytes of offset needed */
83 int size
; /* lazy - this is sib+bytes+1 */
84 unsigned char modrm
, sib
; /* the bytes themselves */
87 static unsigned long cpu
; /* cpu level received from nasm.c */
89 static struct ofmt
*outfmt
;
92 static long calcsize (long, long, int, insn
*, const char *);
93 static void gencode (long, long, int, insn
*, const char *, long);
94 static int regval (operand
*o
);
95 static int matches (struct itemplate
*, insn
*);
96 static ea
* process_ea (operand
*, ea
*, int, int, int);
97 static int chsize (operand
*, int);
100 * This routine wrappers the real output format's output routine,
101 * in order to pass a copy of the data off to the listing file
102 * generator at the same time.
104 static void out (long offset
, long segto
, const void *data
, unsigned long type
,
105 long segment
, long wrt
)
108 char *lnfname
= NULL
;
110 if ((type
& OUT_TYPMASK
) == OUT_ADDRESS
) {
111 if (segment
!= NO_SEG
|| wrt
!= NO_SEG
) {
113 * This address is relocated. We must write it as
114 * OUT_ADDRESS, so there's no work to be done here.
116 list
->output (offset
, data
, type
);
119 unsigned char p
[4], *q
= p
;
121 * This is a non-relocated address, and we're going to
122 * convert it into RAWDATA format.
124 if ((type
& OUT_SIZMASK
) == 4) {
125 WRITELONG (q
, * (long *) data
);
126 list
->output (offset
, p
, OUT_RAWDATA
+4);
129 WRITESHORT (q
, * (long *) data
);
130 list
->output (offset
, p
, OUT_RAWDATA
+2);
134 else if ((type
& OUT_TYPMASK
) == OUT_RAWDATA
) {
135 list
->output (offset
, data
, type
);
137 else if ((type
& OUT_TYPMASK
) == OUT_RESERVE
) {
138 list
->output (offset
, NULL
, type
);
140 else if ((type
& OUT_TYPMASK
) == OUT_REL2ADR
||
141 (type
& OUT_TYPMASK
) == OUT_REL4ADR
) {
142 list
->output (offset
, data
, type
);
145 if (src_get(&lineno
,&lnfname
))
147 outfmt
->current_dfmt
->linenum(lnfname
,lineno
,segto
);
148 if (lnfname
) nasm_free(lnfname
);
151 outfmt
->output (segto
, data
, type
, segment
, wrt
);
154 static int jmp_match (long segment
, long offset
, int bits
,
155 insn
*ins
, const char *code
)
157 unsigned char c
= code
[0];
160 if (c
!= 0370 && c
!= 0371) return 0;
161 if (ins
->oprs
[0].opflags
& OPFLAG_FORWARD
) {
162 if ((optimizing
<0 || (ins
->oprs
[0].type
& STRICT
))
163 && c
==0370) return 1;
164 else return (pass0
==0); /* match a forward reference */
166 isize
= calcsize (segment
, offset
, bits
, ins
, code
);
167 if (ins
->oprs
[0].segment
!= segment
) return 0;
168 isize
= ins
->oprs
[0].offset
- offset
- isize
; /* isize is now the delta */
169 if (isize
>= -128L && isize
<= 127L) return 1; /* it is byte size */
175 long assemble (long segment
, long offset
, int bits
, unsigned long cp
,
176 insn
*instruction
, struct ofmt
*output
, efunc error
,
179 struct itemplate
*temp
;
185 long wsize
= 0; /* size for DB etc. */
187 errfunc
= error
; /* to pass to other functions */
189 outfmt
= output
; /* likewise */
190 list
= listgen
; /* and again */
192 switch (instruction
->opcode
)
195 case I_DB
: wsize
= 1; break;
196 case I_DW
: wsize
= 2; break;
197 case I_DD
: wsize
= 4; break;
198 case I_DQ
: wsize
= 8; break;
199 case I_DT
: wsize
= 10; break;
204 long t
= instruction
->times
;
206 errfunc(ERR_PANIC
, "instruction->times < 0 (%ld) in assemble()",t
);
208 while (t
--) /* repeat TIMES times */
210 for (e
= instruction
->eops
; e
; e
= e
->next
)
212 if (e
->type
== EOT_DB_NUMBER
)
215 if (e
->segment
!= NO_SEG
)
216 errfunc (ERR_NONFATAL
,
217 "one-byte relocation attempted");
219 unsigned char out_byte
= e
->offset
;
220 out (offset
, segment
, &out_byte
, OUT_RAWDATA
+1,
224 else if (wsize
> 5) {
225 errfunc (ERR_NONFATAL
, "integer supplied to a D%c"
226 " instruction", wsize
==8 ? 'Q' : 'T');
229 out (offset
, segment
, &e
->offset
,
230 OUT_ADDRESS
+wsize
, e
->segment
,
234 else if (e
->type
== EOT_DB_STRING
)
238 out (offset
, segment
, e
->stringval
,
239 OUT_RAWDATA
+e
->stringlen
, NO_SEG
, NO_SEG
);
240 align
= e
->stringlen
% wsize
;
243 align
= wsize
- align
;
244 out (offset
, segment
, "\0\0\0\0\0\0\0\0",
245 OUT_RAWDATA
+align
, NO_SEG
, NO_SEG
);
247 offset
+= e
->stringlen
+ align
;
250 if (t
> 0 && t
== instruction
->times
-1)
253 * Dummy call to list->output to give the offset to the
256 list
->output (offset
, NULL
, OUT_RAWDATA
);
257 list
->uplevel (LIST_TIMES
);
260 if (instruction
->times
> 1)
261 list
->downlevel (LIST_TIMES
);
262 return offset
- start
;
265 if (instruction
->opcode
== I_INCBIN
)
267 static char fname
[FILENAME_MAX
];
271 len
= FILENAME_MAX
-1;
272 if (len
> instruction
->eops
->stringlen
)
273 len
= instruction
->eops
->stringlen
;
274 strncpy (fname
, instruction
->eops
->stringval
, len
);
277 if ( (fp
= fopen(fname
, "rb")) == NULL
)
278 error (ERR_NONFATAL
, "`incbin': unable to open file `%s'", fname
);
279 else if (fseek(fp
, 0L, SEEK_END
) < 0)
280 error (ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
284 static char buf
[2048];
285 long t
= instruction
->times
;
289 if (instruction
->eops
->next
) {
290 base
= instruction
->eops
->next
->offset
;
292 if (instruction
->eops
->next
->next
&&
293 len
> instruction
->eops
->next
->next
->offset
)
294 len
= instruction
->eops
->next
->next
->offset
;
297 * Dummy call to list->output to give the offset to the
300 list
->output (offset
, NULL
, OUT_RAWDATA
);
301 list
->uplevel(LIST_INCBIN
);
306 fseek (fp
, base
, SEEK_SET
);
309 long m
= fread (buf
, 1, (l
>sizeof(buf
)?sizeof(buf
):l
),
313 * This shouldn't happen unless the file
314 * actually changes while we are reading
317 error (ERR_NONFATAL
, "`incbin': unexpected EOF while"
318 " reading file `%s'", fname
);
319 t
=0; /* Try to exit cleanly */
322 out (offset
, segment
, buf
, OUT_RAWDATA
+m
,
327 list
->downlevel(LIST_INCBIN
);
328 if (instruction
->times
> 1) {
330 * Dummy call to list->output to give the offset to the
333 list
->output (offset
, NULL
, OUT_RAWDATA
);
334 list
->uplevel(LIST_TIMES
);
335 list
->downlevel(LIST_TIMES
);
338 return instruction
->times
* len
;
340 return 0; /* if we're here, there's an error */
344 temp
= nasm_instructions
[instruction
->opcode
];
345 while (temp
->opcode
!= -1) {
346 int m
= matches (temp
, instruction
);
348 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
350 if (m
== 100) /* matches! */
352 const char *codes
= temp
->code
;
353 long insn_size
= calcsize(segment
, offset
, bits
,
355 itimes
= instruction
->times
;
356 if (insn_size
< 0) /* shouldn't be, on pass two */
357 error (ERR_PANIC
, "errors made it through from pass one");
358 else while (itimes
--) {
359 insn_end
= offset
+ insn_size
;
360 for (j
=0; j
<instruction
->nprefix
; j
++) {
362 switch (instruction
->prefixes
[j
]) {
365 case P_REPNE
: case P_REPNZ
:
367 case P_REPE
: case P_REPZ
: case P_REP
:
369 case R_CS
: c
= 0x2E; break;
370 case R_DS
: c
= 0x3E; break;
371 case R_ES
: c
= 0x26; break;
372 case R_FS
: c
= 0x64; break;
373 case R_GS
: c
= 0x65; break;
374 case R_SS
: c
= 0x36; break;
377 error (ERR_NONFATAL
, "segr6 and segr7 cannot be used as prefixes");
397 "invalid instruction prefix");
400 out (offset
, segment
, &c
, OUT_RAWDATA
+1,
405 gencode (segment
, offset
, bits
, instruction
, codes
, insn_end
);
407 if (itimes
> 0 && itimes
== instruction
->times
-1) {
409 * Dummy call to list->output to give the offset to the
412 list
->output (offset
, NULL
, OUT_RAWDATA
);
413 list
->uplevel (LIST_TIMES
);
416 if (instruction
->times
> 1)
417 list
->downlevel (LIST_TIMES
);
418 return offset
- start
;
419 } else if (m
> 0 && m
> size_prob
) {
425 if (temp
->opcode
== -1) { /* didn't match any instruction */
426 if (size_prob
== 1) /* would have matched, but for size */
427 error (ERR_NONFATAL
, "operation size not specified");
428 else if (size_prob
== 2)
429 error (ERR_NONFATAL
, "mismatch in operand sizes");
430 else if (size_prob
== 3)
431 error (ERR_NONFATAL
, "no instruction for this cpu level");
434 "invalid combination of opcode and operands");
439 long insn_size (long segment
, long offset
, int bits
, unsigned long cp
,
440 insn
*instruction
, efunc error
)
442 struct itemplate
*temp
;
444 errfunc
= error
; /* to pass to other functions */
447 if (instruction
->opcode
== -1)
450 if (instruction
->opcode
== I_DB
||
451 instruction
->opcode
== I_DW
||
452 instruction
->opcode
== I_DD
||
453 instruction
->opcode
== I_DQ
||
454 instruction
->opcode
== I_DT
)
457 long isize
, osize
, wsize
= 0; /* placate gcc */
460 switch (instruction
->opcode
)
462 case I_DB
: wsize
= 1; break;
463 case I_DW
: wsize
= 2; break;
464 case I_DD
: wsize
= 4; break;
465 case I_DQ
: wsize
= 8; break;
466 case I_DT
: wsize
= 10; break;
469 for (e
= instruction
->eops
; e
; e
= e
->next
)
474 if (e
->type
== EOT_DB_NUMBER
)
476 else if (e
->type
== EOT_DB_STRING
)
477 osize
= e
->stringlen
;
479 align
= (-osize
) % wsize
;
482 isize
+= osize
+ align
;
484 return isize
* instruction
->times
;
487 if (instruction
->opcode
== I_INCBIN
)
489 char fname
[FILENAME_MAX
];
493 len
= FILENAME_MAX
-1;
494 if (len
> instruction
->eops
->stringlen
)
495 len
= instruction
->eops
->stringlen
;
496 strncpy (fname
, instruction
->eops
->stringval
, len
);
498 if ( (fp
= fopen(fname
, "rb")) == NULL
)
499 error (ERR_NONFATAL
, "`incbin': unable to open file `%s'", fname
);
500 else if (fseek(fp
, 0L, SEEK_END
) < 0)
501 error (ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
507 if (instruction
->eops
->next
)
509 len
-= instruction
->eops
->next
->offset
;
510 if (instruction
->eops
->next
->next
&&
511 len
> instruction
->eops
->next
->next
->offset
)
513 len
= instruction
->eops
->next
->next
->offset
;
516 return instruction
->times
* len
;
518 return 0; /* if we're here, there's an error */
521 temp
= nasm_instructions
[instruction
->opcode
];
522 while (temp
->opcode
!= -1) {
523 int m
= matches(temp
, instruction
);
525 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
528 /* we've matched an instruction. */
530 const char * codes
= temp
->code
;
533 isize
= calcsize(segment
, offset
, bits
, instruction
, codes
);
536 for (j
= 0; j
< instruction
->nprefix
; j
++)
538 if ((instruction
->prefixes
[j
] != P_A16
&&
539 instruction
->prefixes
[j
] != P_O16
&& bits
==16) ||
540 (instruction
->prefixes
[j
] != P_A32
&&
541 instruction
->prefixes
[j
] != P_O32
&& bits
==32))
546 return isize
* instruction
->times
;
550 return -1; /* didn't match any instruction */
554 /* check that opn[op] is a signed byte of size 16 or 32,
555 and return the signed value*/
556 static int is_sbyte (insn
*ins
, int op
, int size
)
561 ret
= !(ins
->forw_ref
&& ins
->oprs
[op
].opflags
) && /* dead in the water on forward reference or External */
563 !(ins
->oprs
[op
].type
& STRICT
) &&
564 ins
->oprs
[op
].wrt
==NO_SEG
&& ins
->oprs
[op
].segment
==NO_SEG
;
566 v
= ins
->oprs
[op
].offset
;
567 if (size
==16) v
= (signed short)v
; /* sign extend if 16 bits */
569 return ret
&& v
>=-128L && v
<=127L;
572 static long calcsize (long segment
, long offset
, int bits
,
573 insn
*ins
, const char *codes
)
578 (void) segment
; /* Don't warn that this parameter is unused */
579 (void) offset
; /* Don't warn that this parameter is unused */
581 while (*codes
) switch (c
= *codes
++) {
582 case 01: case 02: case 03:
583 codes
+= c
, length
+= c
; break;
584 case 04: case 05: case 06: case 07:
586 case 010: case 011: case 012:
587 codes
++, length
++; break;
590 case 014: case 015: case 016:
592 case 020: case 021: case 022:
594 case 024: case 025: case 026:
596 case 030: case 031: case 032:
598 case 034: case 035: case 036:
599 if ( ins
->oprs
[c
-034].type
& (BITS16
|BITS32
) )
600 length
+= (ins
->oprs
[c
-034].type
& BITS16
) ? 2 : 4;
602 length
+= (bits
== 16) ? 2 : 4;
606 case 040: case 041: case 042:
608 case 044: case 045: case 046:
609 length
+= ((ins
->oprs
[c
-044].addr_size
?
610 ins
->oprs
[c
-044].addr_size
: bits
) == 16 ? 2 : 4); break;
611 case 050: case 051: case 052:
613 case 060: case 061: case 062:
615 case 064: case 065: case 066:
616 if ( ins
->oprs
[c
-064].type
& (BITS16
|BITS32
) )
617 length
+= (ins
->oprs
[c
-064].type
& BITS16
) ? 2 : 4;
619 length
+= (bits
== 16) ? 2 : 4;
621 case 070: case 071: case 072:
623 case 0130: case 0131: case 0132:
624 length
+= is_sbyte(ins
, c
-0130, 16) ? 1 : 2; break;
625 case 0133: case 0134: case 0135:
626 codes
+=2; length
++; break;
627 case 0140: case 0141: case 0142:
628 length
+= is_sbyte(ins
, c
-0140, 32) ? 1 : 4; break;
629 case 0143: case 0144: case 0145:
630 codes
+=2; length
++; break;
631 case 0300: case 0301: case 0302:
632 length
+= chsize (&ins
->oprs
[c
-0300], bits
);
635 length
+= (bits
==32);
638 length
+= (bits
==16);
643 length
+= (bits
==32);
646 length
+= (bits
==16);
651 codes
++, length
++; break;
657 case 0340: case 0341: case 0342:
658 if (ins
->oprs
[0].segment
!= NO_SEG
)
659 errfunc (ERR_NONFATAL
, "attempt to reserve non-constant"
660 " quantity of BSS space");
662 length
+= ins
->oprs
[0].offset
<< (c
-0340);
664 case 0370: case 0371: case 0372:
668 default: /* can't do it by 'case' statements */
669 if (c
>=0100 && c
<=0277) { /* it's an EA */
671 if (!process_ea (&ins
->oprs
[(c
>>3)&7], &ea_data
, bits
, 0,
673 errfunc (ERR_NONFATAL
, "invalid effective address");
676 length
+= ea_data
.size
;
678 errfunc (ERR_PANIC
, "internal instruction table corrupt"
679 ": instruction code 0x%02X given", c
);
684 static void gencode (long segment
, long offset
, int bits
,
685 insn
*ins
, const char *codes
, long insn_end
)
687 static char condval
[] = { /* conditional opcodes */
688 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
689 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
690 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
693 unsigned char bytes
[4];
697 switch (c
= *codes
++)
699 case 01: case 02: case 03:
700 out (offset
, segment
, codes
, OUT_RAWDATA
+c
, NO_SEG
, NO_SEG
);
706 switch (ins
->oprs
[0].basereg
)
709 bytes
[0] = 0x0E + (c
== 0x04 ? 1 : 0); break;
711 bytes
[0] = 0x1E + (c
== 0x04 ? 1 : 0); break;
713 bytes
[0] = 0x06 + (c
== 0x04 ? 1 : 0); break;
715 bytes
[0] = 0x16 + (c
== 0x04 ? 1 : 0); break;
717 errfunc (ERR_PANIC
, "bizarre 8086 segment register received");
719 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
724 switch (ins
->oprs
[0].basereg
) {
725 case R_FS
: bytes
[0] = 0xA0 + (c
== 0x05 ? 1 : 0); break;
726 case R_GS
: bytes
[0] = 0xA8 + (c
== 0x05 ? 1 : 0); break;
728 errfunc (ERR_PANIC
, "bizarre 386 segment register received");
730 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
734 case 010: case 011: case 012:
735 bytes
[0] = *codes
++ + regval(&ins
->oprs
[c
-010]);
736 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
742 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
746 case 014: case 015: case 016:
747 if (ins
->oprs
[c
-014].offset
< -128
748 || ins
->oprs
[c
-014].offset
> 127)
750 errfunc (ERR_WARNING
, "signed byte value exceeds bounds");
753 if (ins
->oprs
[c
-014].segment
!= NO_SEG
)
755 data
= ins
->oprs
[c
-014].offset
;
756 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
757 ins
->oprs
[c
-014].segment
, ins
->oprs
[c
-014].wrt
);
760 bytes
[0] = ins
->oprs
[c
-014].offset
;
761 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
766 case 020: case 021: case 022:
767 if (ins
->oprs
[c
-020].offset
< -256
768 || ins
->oprs
[c
-020].offset
> 255)
770 errfunc (ERR_WARNING
, "byte value exceeds bounds");
772 if (ins
->oprs
[c
-020].segment
!= NO_SEG
) {
773 data
= ins
->oprs
[c
-020].offset
;
774 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
775 ins
->oprs
[c
-020].segment
, ins
->oprs
[c
-020].wrt
);
778 bytes
[0] = ins
->oprs
[c
-020].offset
;
779 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
784 case 024: case 025: case 026:
785 if (ins
->oprs
[c
-024].offset
< 0 || ins
->oprs
[c
-024].offset
> 255)
786 errfunc (ERR_WARNING
, "unsigned byte value exceeds bounds");
787 if (ins
->oprs
[c
-024].segment
!= NO_SEG
) {
788 data
= ins
->oprs
[c
-024].offset
;
789 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
790 ins
->oprs
[c
-024].segment
, ins
->oprs
[c
-024].wrt
);
793 bytes
[0] = ins
->oprs
[c
-024].offset
;
794 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
799 case 030: case 031: case 032:
800 if (ins
->oprs
[c
-030].segment
== NO_SEG
&&
801 ins
->oprs
[c
-030].wrt
== NO_SEG
&&
802 (ins
->oprs
[c
-030].offset
< -65536L ||
803 ins
->oprs
[c
-030].offset
> 65535L))
805 errfunc (ERR_WARNING
, "word value exceeds bounds");
807 data
= ins
->oprs
[c
-030].offset
;
808 out (offset
, segment
, &data
, OUT_ADDRESS
+2,
809 ins
->oprs
[c
-030].segment
, ins
->oprs
[c
-030].wrt
);
813 case 034: case 035: case 036:
814 if ( ins
->oprs
[c
-034].type
& (BITS16
|BITS32
) )
815 size
= (ins
->oprs
[c
-034].type
& BITS16
) ? 2 : 4;
817 size
= (bits
== 16) ? 2 : 4;
818 data
= ins
->oprs
[c
-034].offset
;
819 if (size
==2 && (data
< -65536L || data
> 65535L))
820 errfunc (ERR_WARNING
, "word value exceeds bounds");
821 out (offset
, segment
, &data
, OUT_ADDRESS
+size
,
822 ins
->oprs
[c
-034].segment
, ins
->oprs
[c
-034].wrt
);
827 if (ins
->oprs
[0].segment
== NO_SEG
)
828 errfunc (ERR_NONFATAL
, "value referenced by FAR is not"
831 out (offset
, segment
, &data
, OUT_ADDRESS
+2,
832 outfmt
->segbase(1+ins
->oprs
[0].segment
),
837 case 040: case 041: case 042:
838 data
= ins
->oprs
[c
-040].offset
;
839 out (offset
, segment
, &data
, OUT_ADDRESS
+4,
840 ins
->oprs
[c
-040].segment
, ins
->oprs
[c
-040].wrt
);
844 case 044: case 045: case 046:
845 data
= ins
->oprs
[c
-044].offset
;
846 size
= ((ins
->oprs
[c
-044].addr_size
?
847 ins
->oprs
[c
-044].addr_size
: bits
) == 16 ? 2 : 4);
848 if (size
==2 && (data
< -65536L || data
> 65535L))
849 errfunc (ERR_WARNING
, "word value exceeds bounds");
850 out (offset
, segment
, &data
, OUT_ADDRESS
+size
,
851 ins
->oprs
[c
-044].segment
, ins
->oprs
[c
-044].wrt
);
855 case 050: case 051: case 052:
856 if (ins
->oprs
[c
-050].segment
!= segment
)
857 errfunc (ERR_NONFATAL
, "short relative jump outside segment");
858 data
= ins
->oprs
[c
-050].offset
- insn_end
;
859 if (data
> 127 || data
< -128)
860 errfunc (ERR_NONFATAL
, "short jump is out of range");
862 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
866 case 060: case 061: case 062:
867 if (ins
->oprs
[c
-060].segment
!= segment
) {
868 data
= ins
->oprs
[c
-060].offset
;
869 out (offset
, segment
, &data
, OUT_REL2ADR
+insn_end
-offset
,
870 ins
->oprs
[c
-060].segment
, ins
->oprs
[c
-060].wrt
);
872 data
= ins
->oprs
[c
-060].offset
- insn_end
;
873 out (offset
, segment
, &data
,
874 OUT_ADDRESS
+2, NO_SEG
, NO_SEG
);
879 case 064: case 065: case 066:
880 if ( ins
->oprs
[c
-064].type
& (BITS16
|BITS32
) )
881 size
= (ins
->oprs
[c
-064].type
& BITS16
) ? 2 : 4;
883 size
= (bits
== 16) ? 2 : 4;
884 if (ins
->oprs
[c
-064].segment
!= segment
) {
885 long reltype
= (size
== 2 ? OUT_REL2ADR
: OUT_REL4ADR
);
886 data
= ins
->oprs
[c
-064].offset
;
887 out (offset
, segment
, &data
, reltype
+insn_end
-offset
,
888 ins
->oprs
[c
-064].segment
, ins
->oprs
[c
-064].wrt
);
890 data
= ins
->oprs
[c
-064].offset
- insn_end
;
891 out (offset
, segment
, &data
,
892 OUT_ADDRESS
+size
, NO_SEG
, NO_SEG
);
897 case 070: case 071: case 072:
898 if (ins
->oprs
[c
-070].segment
!= segment
) {
899 data
= ins
->oprs
[c
-070].offset
;
900 out (offset
, segment
, &data
, OUT_REL4ADR
+insn_end
-offset
,
901 ins
->oprs
[c
-070].segment
, ins
->oprs
[c
-070].wrt
);
903 data
= ins
->oprs
[c
-070].offset
- insn_end
;
904 out (offset
, segment
, &data
,
905 OUT_ADDRESS
+4, NO_SEG
, NO_SEG
);
910 case 0130: case 0131: case 0132:
911 data
= ins
->oprs
[c
-0130].offset
;
912 if (is_sbyte(ins
, c
-0130, 16)) {
913 out (offset
, segment
, &data
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
916 if (ins
->oprs
[c
-0130].segment
== NO_SEG
&&
917 ins
->oprs
[c
-0130].wrt
== NO_SEG
&&
918 (data
< -65536L || data
> 65535L)) {
919 errfunc (ERR_WARNING
, "word value exceeds bounds");
921 out (offset
, segment
, &data
, OUT_ADDRESS
+2,
922 ins
->oprs
[c
-0130].segment
, ins
->oprs
[c
-0130].wrt
);
927 case 0133: case 0134: case 0135:
930 if (is_sbyte(ins
, c
-0133, 16)) bytes
[0] |= 2; /* s-bit */
931 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
935 case 0140: case 0141: case 0142:
936 data
= ins
->oprs
[c
-0140].offset
;
937 if (is_sbyte(ins
, c
-0140, 32)) {
938 out (offset
, segment
, &data
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
941 out (offset
, segment
, &data
, OUT_ADDRESS
+4,
942 ins
->oprs
[c
-0140].segment
, ins
->oprs
[c
-0140].wrt
);
947 case 0143: case 0144: case 0145:
950 if (is_sbyte(ins
, c
-0143, 32)) bytes
[0] |= 2; /* s-bit */
951 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
955 case 0300: case 0301: case 0302:
956 if (chsize (&ins
->oprs
[c
-0300], bits
)) {
958 out (offset
, segment
, bytes
,
959 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
968 out (offset
, segment
, bytes
,
969 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
978 out (offset
, segment
, bytes
,
979 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
991 out (offset
, segment
, bytes
,
992 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1001 out (offset
, segment
, bytes
,
1002 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1012 *bytes
= *codes
++ ^ condval
[ins
->condition
];
1013 out (offset
, segment
, bytes
,
1014 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1024 out (offset
, segment
, bytes
,
1025 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1029 case 0340: case 0341: case 0342:
1030 if (ins
->oprs
[0].segment
!= NO_SEG
)
1031 errfunc (ERR_PANIC
, "non-constant BSS size in pass two");
1033 long size
= ins
->oprs
[0].offset
<< (c
-0340);
1035 out (offset
, segment
, NULL
,
1036 OUT_RESERVE
+size
, NO_SEG
, NO_SEG
);
1041 case 0370: case 0371: case 0372:
1045 *bytes
= bits
==16 ? 3 : 5;
1046 out (offset
, segment
, bytes
,
1047 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1051 default: /* can't do it by 'case' statements */
1052 if (c
>=0100 && c
<=0277) { /* it's an EA */
1058 if (c
<=0177) /* pick rfield from operand b */
1059 rfield
= regval (&ins
->oprs
[c
&7]);
1060 else /* rfield is constant */
1063 if (!process_ea (&ins
->oprs
[(c
>>3)&7], &ea_data
, bits
, rfield
,
1066 errfunc (ERR_NONFATAL
, "invalid effective address");
1070 *p
++ = ea_data
.modrm
;
1071 if (ea_data
.sib_present
)
1075 out (offset
, segment
, bytes
, OUT_RAWDATA
+ s
,
1078 switch (ea_data
.bytes
) {
1082 if (ins
->oprs
[(c
>>3)&7].segment
!= NO_SEG
) {
1083 data
= ins
->oprs
[(c
>>3)&7].offset
;
1084 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
1085 ins
->oprs
[(c
>>3)&7].segment
,
1086 ins
->oprs
[(c
>>3)&7].wrt
);
1088 *bytes
= ins
->oprs
[(c
>>3)&7].offset
;
1089 out (offset
, segment
, bytes
, OUT_RAWDATA
+1,
1096 data
= ins
->oprs
[(c
>>3)&7].offset
;
1097 out (offset
, segment
, &data
,
1098 OUT_ADDRESS
+ea_data
.bytes
,
1099 ins
->oprs
[(c
>>3)&7].segment
, ins
->oprs
[(c
>>3)&7].wrt
);
1105 errfunc (ERR_PANIC
, "internal instruction table corrupt"
1106 ": instruction code 0x%02X given", c
);
1110 #include "regvals.c"
1112 static int regval (operand
*o
)
1114 if ( o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1115 errfunc (ERR_PANIC
, "invalid operand passed to regval()");
1117 return regvals
[o
->basereg
];
1120 static int matches (struct itemplate
*itemp
, insn
*instruction
)
1122 int i
, size
[3], asize
, oprs
, ret
;
1129 if (itemp
->opcode
!= instruction
->opcode
) return 0;
1132 * Count the operands
1134 if (itemp
->operands
!= instruction
->operands
) return 0;
1137 * Check that no spurious colons or TOs are present
1139 for (i
=0; i
<itemp
->operands
; i
++)
1140 if (instruction
->oprs
[i
].type
& ~itemp
->opd
[i
] & (COLON
|TO
))
1144 * Check that the operand flags all match up
1146 for (i
=0; i
<itemp
->operands
; i
++)
1147 if (itemp
->opd
[i
] & ~instruction
->oprs
[i
].type
||
1148 ((itemp
->opd
[i
] & SIZE_MASK
) &&
1149 ((itemp
->opd
[i
] ^ instruction
->oprs
[i
].type
) & SIZE_MASK
)))
1151 if ((itemp
->opd
[i
] & ~instruction
->oprs
[i
].type
& NON_SIZE
) ||
1152 (instruction
->oprs
[i
].type
& SIZE_MASK
))
1160 * Check operand sizes
1162 if (itemp
->flags
& IF_ARMASK
) {
1163 size
[0] = size
[1] = size
[2] = 0;
1165 switch (itemp
->flags
& IF_ARMASK
) {
1166 case IF_AR0
: i
= 0; break;
1167 case IF_AR1
: i
= 1; break;
1168 case IF_AR2
: i
= 2; break;
1169 default: break; /* Shouldn't happen */
1171 if (itemp
->flags
& IF_SB
) {
1173 } else if (itemp
->flags
& IF_SW
) {
1175 } else if (itemp
->flags
& IF_SD
) {
1180 if (itemp
->flags
& IF_SB
) {
1182 oprs
= itemp
->operands
;
1183 } else if (itemp
->flags
& IF_SW
) {
1185 oprs
= itemp
->operands
;
1186 } else if (itemp
->flags
& IF_SD
) {
1188 oprs
= itemp
->operands
;
1190 size
[0] = size
[1] = size
[2] = asize
;
1193 if (itemp
->flags
& (IF_SM
| IF_SM2
)) {
1194 oprs
= (itemp
->flags
& IF_SM2
? 2 : itemp
->operands
);
1196 for (i
=0; i
<oprs
; i
++) {
1197 if ( (asize
= itemp
->opd
[i
] & SIZE_MASK
) != 0) {
1199 for (j
=0; j
<oprs
; j
++)
1205 oprs
= itemp
->operands
;
1208 for (i
=0; i
<itemp
->operands
; i
++)
1209 if (!(itemp
->opd
[i
] & SIZE_MASK
) &&
1210 (instruction
->oprs
[i
].type
& SIZE_MASK
& ~size
[i
]))
1215 * Check template is okay at the set cpu level
1217 if ((itemp
->flags
& IF_PLEVEL
) > cpu
) return 3;
1220 * Check if special handling needed for Jumps
1222 if ((unsigned char)(itemp
->code
[0]) >= 0370) return 99;
1227 static ea
*process_ea (operand
*input
, ea
*output
, int addrbits
, int rfield
,
1230 if (!(REGISTER
& ~input
->type
)) { /* it's a single register */
1231 static int regs
[] = {
1232 R_AL
, R_CL
, R_DL
, R_BL
, R_AH
, R_CH
, R_DH
, R_BH
,
1233 R_AX
, R_CX
, R_DX
, R_BX
, R_SP
, R_BP
, R_SI
, R_DI
,
1234 R_EAX
, R_ECX
, R_EDX
, R_EBX
, R_ESP
, R_EBP
, R_ESI
, R_EDI
,
1235 R_MM0
, R_MM1
, R_MM2
, R_MM3
, R_MM4
, R_MM5
, R_MM6
, R_MM7
,
1236 R_XMM0
, R_XMM1
, R_XMM2
, R_XMM3
, R_XMM4
, R_XMM5
, R_XMM6
, R_XMM7
1240 for (i
=0; i
<elements(regs
); i
++)
1241 if (input
->basereg
== regs
[i
]) break;
1242 if (i
<elements(regs
)) {
1243 output
->sib_present
= FALSE
;/* no SIB necessary */
1244 output
->bytes
= 0; /* no offset necessary either */
1245 output
->modrm
= 0xC0 | (rfield
<< 3) | (i
& 7);
1249 } else { /* it's a memory reference */
1250 if (input
->basereg
==-1 && (input
->indexreg
==-1 || input
->scale
==0)) {
1251 /* it's a pure offset */
1252 if (input
->addr_size
)
1253 addrbits
= input
->addr_size
;
1254 output
->sib_present
= FALSE
;
1255 output
->bytes
= (addrbits
==32 ? 4 : 2);
1256 output
->modrm
= (addrbits
==32 ? 5 : 6) | (rfield
<< 3);
1258 else { /* it's an indirection */
1259 int i
=input
->indexreg
, b
=input
->basereg
, s
=input
->scale
;
1260 long o
=input
->offset
, seg
=input
->segment
;
1261 int hb
=input
->hintbase
, ht
=input
->hinttype
;
1264 if (s
==0) i
= -1; /* make this easy, at least */
1266 if (i
==R_EAX
|| i
==R_EBX
|| i
==R_ECX
|| i
==R_EDX
1267 || i
==R_EBP
|| i
==R_ESP
|| i
==R_ESI
|| i
==R_EDI
1268 || b
==R_EAX
|| b
==R_EBX
|| b
==R_ECX
|| b
==R_EDX
1269 || b
==R_EBP
|| b
==R_ESP
|| b
==R_ESI
|| b
==R_EDI
) {
1270 /* it must be a 32-bit memory reference. Firstly we have
1271 * to check that all registers involved are type Exx. */
1272 if (i
!=-1 && i
!=R_EAX
&& i
!=R_EBX
&& i
!=R_ECX
&& i
!=R_EDX
1273 && i
!=R_EBP
&& i
!=R_ESP
&& i
!=R_ESI
&& i
!=R_EDI
)
1275 if (b
!=-1 && b
!=R_EAX
&& b
!=R_EBX
&& b
!=R_ECX
&& b
!=R_EDX
1276 && b
!=R_EBP
&& b
!=R_ESP
&& b
!=R_ESI
&& b
!=R_EDI
)
1279 /* While we're here, ensure the user didn't specify WORD. */
1280 if (input
->addr_size
== 16)
1283 /* now reorganise base/index */
1284 if (s
== 1 && b
!= i
&& b
!= -1 && i
!= -1 &&
1285 ((hb
==b
&&ht
==EAH_NOTBASE
) || (hb
==i
&&ht
==EAH_MAKEBASE
)))
1286 t
= b
, b
= i
, i
= t
; /* swap if hints say so */
1287 if (b
==i
) /* convert EAX+2*EAX to 3*EAX */
1289 if (b
==-1 && s
==1 && !(hb
== i
&& ht
== EAH_NOTBASE
))
1290 b
= i
, i
= -1; /* make single reg base, unless hint */
1291 if (((s
==2 && i
!=R_ESP
&& !(input
->eaflags
& EAF_TIMESTWO
)) ||
1292 s
==3 || s
==5 || s
==9) && b
==-1)
1293 b
= i
, s
--; /* convert 3*EAX to EAX+2*EAX */
1294 if (i
==-1 && b
!=R_ESP
&& (input
->eaflags
& EAF_TIMESTWO
))
1295 i
= b
, b
= -1, s
= 1;
1296 /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */
1297 if (s
==1 && i
==R_ESP
) /* swap ESP into base if scale is 1 */
1299 if (i
==R_ESP
|| (s
!=1 && s
!=2 && s
!=4 && s
!=8 && i
!=-1))
1300 return NULL
; /* wrong, for various reasons */
1302 if (i
==-1 && b
!=R_ESP
) {/* no SIB needed */
1305 case R_EAX
: rm
= 0; break;
1306 case R_ECX
: rm
= 1; break;
1307 case R_EDX
: rm
= 2; break;
1308 case R_EBX
: rm
= 3; break;
1309 case R_EBP
: rm
= 5; break;
1310 case R_ESI
: rm
= 6; break;
1311 case R_EDI
: rm
= 7; break;
1312 case -1: rm
= 5; break;
1313 default: /* should never happen */
1316 if (b
==-1 || (b
!=R_EBP
&& o
==0 &&
1317 seg
==NO_SEG
&& !forw_ref
&&
1319 (EAF_BYTEOFFS
|EAF_WORDOFFS
))))
1321 else if (input
->eaflags
& EAF_BYTEOFFS
||
1322 (o
>=-128 && o
<=127 && seg
==NO_SEG
&& !forw_ref
&&
1323 !(input
->eaflags
& EAF_WORDOFFS
))) {
1329 output
->sib_present
= FALSE
;
1330 output
->bytes
= (b
==-1 || mod
==2 ? 4 : mod
);
1331 output
->modrm
= (mod
<<6) | (rfield
<<3) | rm
;
1333 else { /* we need a SIB */
1334 int mod
, scale
, index
, base
;
1337 case R_EAX
: base
= 0; break;
1338 case R_ECX
: base
= 1; break;
1339 case R_EDX
: base
= 2; break;
1340 case R_EBX
: base
= 3; break;
1341 case R_ESP
: base
= 4; break;
1342 case R_EBP
: case -1: base
= 5; break;
1343 case R_ESI
: base
= 6; break;
1344 case R_EDI
: base
= 7; break;
1345 default: /* then what the smeg is it? */
1346 return NULL
; /* panic */
1350 case R_EAX
: index
= 0; break;
1351 case R_ECX
: index
= 1; break;
1352 case R_EDX
: index
= 2; break;
1353 case R_EBX
: index
= 3; break;
1354 case -1: index
= 4; break;
1355 case R_EBP
: index
= 5; break;
1356 case R_ESI
: index
= 6; break;
1357 case R_EDI
: index
= 7; break;
1358 default: /* then what the smeg is it? */
1359 return NULL
; /* panic */
1364 case 1: scale
= 0; break;
1365 case 2: scale
= 1; break;
1366 case 4: scale
= 2; break;
1367 case 8: scale
= 3; break;
1368 default: /* then what the smeg is it? */
1369 return NULL
; /* panic */
1372 if (b
==-1 || (b
!=R_EBP
&& o
==0 &&
1373 seg
==NO_SEG
&& !forw_ref
&&
1375 (EAF_BYTEOFFS
|EAF_WORDOFFS
))))
1377 else if (input
->eaflags
& EAF_BYTEOFFS
||
1378 (o
>=-128 && o
<=127 && seg
==NO_SEG
&& !forw_ref
&&
1379 !(input
->eaflags
& EAF_WORDOFFS
)))
1384 output
->sib_present
= TRUE
;
1385 output
->bytes
= (b
==-1 || mod
==2 ? 4 : mod
);
1386 output
->modrm
= (mod
<<6) | (rfield
<<3) | 4;
1387 output
->sib
= (scale
<<6) | (index
<<3) | base
;
1390 else { /* it's 16-bit */
1393 /* check all registers are BX, BP, SI or DI */
1394 if ((b
!=-1 && b
!=R_BP
&& b
!=R_BX
&& b
!=R_SI
&& b
!=R_DI
) ||
1395 (i
!=-1 && i
!=R_BP
&& i
!=R_BX
&& i
!=R_SI
&& i
!=R_DI
))
1398 /* ensure the user didn't specify DWORD */
1399 if (input
->addr_size
== 32)
1402 if (s
!=1 && i
!=-1) return NULL
;/* no can do, in 16-bit EA */
1403 if (b
==-1 && i
!=-1) { int tmp
= b
; b
= i
; i
= tmp
; } /* swap */
1404 if ((b
==R_SI
|| b
==R_DI
) && i
!=-1)
1405 { int tmp
= b
; b
= i
; i
= tmp
; }
1406 /* have BX/BP as base, SI/DI index */
1407 if (b
==i
) return NULL
;/* shouldn't ever happen, in theory */
1408 if (i
!=-1 && b
!=-1 &&
1409 (i
==R_BP
|| i
==R_BX
|| b
==R_SI
|| b
==R_DI
))
1410 return NULL
; /* invalid combinations */
1411 if (b
==-1) /* pure offset: handled above */
1412 return NULL
; /* so if it gets to here, panic! */
1416 switch (i
*256 + b
) {
1417 case R_SI
*256+R_BX
: rm
=0; break;
1418 case R_DI
*256+R_BX
: rm
=1; break;
1419 case R_SI
*256+R_BP
: rm
=2; break;
1420 case R_DI
*256+R_BP
: rm
=3; break;
1424 case R_SI
: rm
=4; break;
1425 case R_DI
: rm
=5; break;
1426 case R_BP
: rm
=6; break;
1427 case R_BX
: rm
=7; break;
1429 if (rm
==-1) /* can't happen, in theory */
1430 return NULL
; /* so panic if it does */
1432 if (o
==0 && seg
==NO_SEG
&& !forw_ref
&& rm
!=6 &&
1433 !(input
->eaflags
& (EAF_BYTEOFFS
|EAF_WORDOFFS
)))
1435 else if (input
->eaflags
& EAF_BYTEOFFS
||
1436 (o
>=-128 && o
<=127 && seg
==NO_SEG
&& !forw_ref
&&
1437 !(input
->eaflags
& EAF_WORDOFFS
)))
1442 output
->sib_present
= FALSE
; /* no SIB - it's 16-bit */
1443 output
->bytes
= mod
; /* bytes of offset needed */
1444 output
->modrm
= (mod
<<6) | (rfield
<<3) | rm
;
1448 output
->size
= 1 + output
->sib_present
+ output
->bytes
;
1452 static int chsize (operand
*input
, int addrbits
)
1454 if (!(MEMORY
& ~input
->type
)) {
1455 int i
=input
->indexreg
, b
=input
->basereg
;
1457 if (input
->scale
==0) i
= -1;
1459 if (i
== -1 && b
== -1) /* pure offset */
1460 return (input
->addr_size
!= 0 && input
->addr_size
!= addrbits
);
1462 if (i
==R_EAX
|| i
==R_EBX
|| i
==R_ECX
|| i
==R_EDX
1463 || i
==R_EBP
|| i
==R_ESP
|| i
==R_ESI
|| i
==R_EDI
1464 || b
==R_EAX
|| b
==R_EBX
|| b
==R_ECX
|| b
==R_EDX
1465 || b
==R_EBP
|| b
==R_ESP
|| b
==R_ESI
|| b
==R_EDI
)
1466 return (addrbits
==16);
1468 return (addrbits
==32);