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 for (j
=0; j
<instruction
->nprefix
; j
++) {
361 switch (instruction
->prefixes
[j
]) {
364 case P_REPNE
: case P_REPNZ
:
366 case P_REPE
: case P_REPZ
: case P_REP
:
368 case R_CS
: c
= 0x2E; break;
369 case R_DS
: c
= 0x3E; break;
370 case R_ES
: c
= 0x26; break;
371 case R_FS
: c
= 0x64; break;
372 case R_GS
: c
= 0x65; break;
373 case R_SS
: c
= 0x36; break;
376 error (ERR_NONFATAL
, "segr6 and segr7 cannot be used as prefixes");
396 "invalid instruction prefix");
399 out (offset
, segment
, &c
, OUT_RAWDATA
+1,
404 insn_end
= offset
+ insn_size
;
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)) {
914 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
917 if (ins
->oprs
[c
-0130].segment
== NO_SEG
&&
918 ins
->oprs
[c
-0130].wrt
== NO_SEG
&&
919 (data
< -65536L || data
> 65535L)) {
920 errfunc (ERR_WARNING
, "word value exceeds bounds");
922 out (offset
, segment
, &data
, OUT_ADDRESS
+2,
923 ins
->oprs
[c
-0130].segment
, ins
->oprs
[c
-0130].wrt
);
928 case 0133: case 0134: case 0135:
931 if (is_sbyte(ins
, c
-0133, 16)) bytes
[0] |= 2; /* s-bit */
932 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
936 case 0140: case 0141: case 0142:
937 data
= ins
->oprs
[c
-0140].offset
;
938 if (is_sbyte(ins
, c
-0140, 32)) {
940 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
943 out (offset
, segment
, &data
, OUT_ADDRESS
+4,
944 ins
->oprs
[c
-0140].segment
, ins
->oprs
[c
-0140].wrt
);
949 case 0143: case 0144: case 0145:
952 if (is_sbyte(ins
, c
-0143, 32)) bytes
[0] |= 2; /* s-bit */
953 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
957 case 0300: case 0301: case 0302:
958 if (chsize (&ins
->oprs
[c
-0300], bits
)) {
960 out (offset
, segment
, bytes
,
961 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
970 out (offset
, segment
, bytes
,
971 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
980 out (offset
, segment
, bytes
,
981 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
993 out (offset
, segment
, bytes
,
994 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1003 out (offset
, segment
, bytes
,
1004 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1014 *bytes
= *codes
++ ^ condval
[ins
->condition
];
1015 out (offset
, segment
, bytes
,
1016 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1026 out (offset
, segment
, bytes
,
1027 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1031 case 0340: case 0341: case 0342:
1032 if (ins
->oprs
[0].segment
!= NO_SEG
)
1033 errfunc (ERR_PANIC
, "non-constant BSS size in pass two");
1035 long size
= ins
->oprs
[0].offset
<< (c
-0340);
1037 out (offset
, segment
, NULL
,
1038 OUT_RESERVE
+size
, NO_SEG
, NO_SEG
);
1043 case 0370: case 0371: case 0372:
1047 *bytes
= bits
==16 ? 3 : 5;
1048 out (offset
, segment
, bytes
,
1049 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1053 default: /* can't do it by 'case' statements */
1054 if (c
>=0100 && c
<=0277) { /* it's an EA */
1060 if (c
<=0177) /* pick rfield from operand b */
1061 rfield
= regval (&ins
->oprs
[c
&7]);
1062 else /* rfield is constant */
1065 if (!process_ea (&ins
->oprs
[(c
>>3)&7], &ea_data
, bits
, rfield
,
1068 errfunc (ERR_NONFATAL
, "invalid effective address");
1072 *p
++ = ea_data
.modrm
;
1073 if (ea_data
.sib_present
)
1077 out (offset
, segment
, bytes
, OUT_RAWDATA
+ s
,
1080 switch (ea_data
.bytes
) {
1084 if (ins
->oprs
[(c
>>3)&7].segment
!= NO_SEG
) {
1085 data
= ins
->oprs
[(c
>>3)&7].offset
;
1086 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
1087 ins
->oprs
[(c
>>3)&7].segment
,
1088 ins
->oprs
[(c
>>3)&7].wrt
);
1090 *bytes
= ins
->oprs
[(c
>>3)&7].offset
;
1091 out (offset
, segment
, bytes
, OUT_RAWDATA
+1,
1098 data
= ins
->oprs
[(c
>>3)&7].offset
;
1099 out (offset
, segment
, &data
,
1100 OUT_ADDRESS
+ea_data
.bytes
,
1101 ins
->oprs
[(c
>>3)&7].segment
, ins
->oprs
[(c
>>3)&7].wrt
);
1107 errfunc (ERR_PANIC
, "internal instruction table corrupt"
1108 ": instruction code 0x%02X given", c
);
1112 #include "regvals.c"
1114 static int regval (operand
*o
)
1116 if ( o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1117 errfunc (ERR_PANIC
, "invalid operand passed to regval()");
1119 return regvals
[o
->basereg
];
1122 static int matches (struct itemplate
*itemp
, insn
*instruction
)
1124 int i
, size
[3], asize
, oprs
, ret
;
1131 if (itemp
->opcode
!= instruction
->opcode
) return 0;
1134 * Count the operands
1136 if (itemp
->operands
!= instruction
->operands
) return 0;
1139 * Check that no spurious colons or TOs are present
1141 for (i
=0; i
<itemp
->operands
; i
++)
1142 if (instruction
->oprs
[i
].type
& ~itemp
->opd
[i
] & (COLON
|TO
))
1146 * Check that the operand flags all match up
1148 for (i
=0; i
<itemp
->operands
; i
++)
1149 if (itemp
->opd
[i
] & ~instruction
->oprs
[i
].type
||
1150 ((itemp
->opd
[i
] & SIZE_MASK
) &&
1151 ((itemp
->opd
[i
] ^ instruction
->oprs
[i
].type
) & SIZE_MASK
)))
1153 if ((itemp
->opd
[i
] & ~instruction
->oprs
[i
].type
& NON_SIZE
) ||
1154 (instruction
->oprs
[i
].type
& SIZE_MASK
))
1162 * Check operand sizes
1164 if (itemp
->flags
& IF_ARMASK
) {
1165 size
[0] = size
[1] = size
[2] = 0;
1167 switch (itemp
->flags
& IF_ARMASK
) {
1168 case IF_AR0
: i
= 0; break;
1169 case IF_AR1
: i
= 1; break;
1170 case IF_AR2
: i
= 2; break;
1171 default: break; /* Shouldn't happen */
1173 if (itemp
->flags
& IF_SB
) {
1175 } else if (itemp
->flags
& IF_SW
) {
1177 } else if (itemp
->flags
& IF_SD
) {
1182 if (itemp
->flags
& IF_SB
) {
1184 oprs
= itemp
->operands
;
1185 } else if (itemp
->flags
& IF_SW
) {
1187 oprs
= itemp
->operands
;
1188 } else if (itemp
->flags
& IF_SD
) {
1190 oprs
= itemp
->operands
;
1192 size
[0] = size
[1] = size
[2] = asize
;
1195 if (itemp
->flags
& (IF_SM
| IF_SM2
)) {
1196 oprs
= (itemp
->flags
& IF_SM2
? 2 : itemp
->operands
);
1198 for (i
=0; i
<oprs
; i
++) {
1199 if ( (asize
= itemp
->opd
[i
] & SIZE_MASK
) != 0) {
1201 for (j
=0; j
<oprs
; j
++)
1207 oprs
= itemp
->operands
;
1210 for (i
=0; i
<itemp
->operands
; i
++)
1211 if (!(itemp
->opd
[i
] & SIZE_MASK
) &&
1212 (instruction
->oprs
[i
].type
& SIZE_MASK
& ~size
[i
]))
1217 * Check template is okay at the set cpu level
1219 if ((itemp
->flags
& IF_PLEVEL
) > cpu
) return 3;
1222 * Check if special handling needed for Jumps
1224 if ((unsigned char)(itemp
->code
[0]) >= 0370) return 99;
1229 static ea
*process_ea (operand
*input
, ea
*output
, int addrbits
, int rfield
,
1232 if (!(REGISTER
& ~input
->type
)) { /* it's a single register */
1233 static int regs
[] = {
1234 R_AL
, R_CL
, R_DL
, R_BL
, R_AH
, R_CH
, R_DH
, R_BH
,
1235 R_AX
, R_CX
, R_DX
, R_BX
, R_SP
, R_BP
, R_SI
, R_DI
,
1236 R_EAX
, R_ECX
, R_EDX
, R_EBX
, R_ESP
, R_EBP
, R_ESI
, R_EDI
,
1237 R_MM0
, R_MM1
, R_MM2
, R_MM3
, R_MM4
, R_MM5
, R_MM6
, R_MM7
,
1238 R_XMM0
, R_XMM1
, R_XMM2
, R_XMM3
, R_XMM4
, R_XMM5
, R_XMM6
, R_XMM7
1242 for (i
=0; i
<elements(regs
); i
++)
1243 if (input
->basereg
== regs
[i
]) break;
1244 if (i
<elements(regs
)) {
1245 output
->sib_present
= FALSE
;/* no SIB necessary */
1246 output
->bytes
= 0; /* no offset necessary either */
1247 output
->modrm
= 0xC0 | (rfield
<< 3) | (i
& 7);
1251 } else { /* it's a memory reference */
1252 if (input
->basereg
==-1 && (input
->indexreg
==-1 || input
->scale
==0)) {
1253 /* it's a pure offset */
1254 if (input
->addr_size
)
1255 addrbits
= input
->addr_size
;
1256 output
->sib_present
= FALSE
;
1257 output
->bytes
= (addrbits
==32 ? 4 : 2);
1258 output
->modrm
= (addrbits
==32 ? 5 : 6) | (rfield
<< 3);
1260 else { /* it's an indirection */
1261 int i
=input
->indexreg
, b
=input
->basereg
, s
=input
->scale
;
1262 long o
=input
->offset
, seg
=input
->segment
;
1263 int hb
=input
->hintbase
, ht
=input
->hinttype
;
1266 if (s
==0) i
= -1; /* make this easy, at least */
1268 if (i
==R_EAX
|| i
==R_EBX
|| i
==R_ECX
|| i
==R_EDX
1269 || i
==R_EBP
|| i
==R_ESP
|| i
==R_ESI
|| i
==R_EDI
1270 || b
==R_EAX
|| b
==R_EBX
|| b
==R_ECX
|| b
==R_EDX
1271 || b
==R_EBP
|| b
==R_ESP
|| b
==R_ESI
|| b
==R_EDI
) {
1272 /* it must be a 32-bit memory reference. Firstly we have
1273 * to check that all registers involved are type Exx. */
1274 if (i
!=-1 && i
!=R_EAX
&& i
!=R_EBX
&& i
!=R_ECX
&& i
!=R_EDX
1275 && i
!=R_EBP
&& i
!=R_ESP
&& i
!=R_ESI
&& i
!=R_EDI
)
1277 if (b
!=-1 && b
!=R_EAX
&& b
!=R_EBX
&& b
!=R_ECX
&& b
!=R_EDX
1278 && b
!=R_EBP
&& b
!=R_ESP
&& b
!=R_ESI
&& b
!=R_EDI
)
1281 /* While we're here, ensure the user didn't specify WORD. */
1282 if (input
->addr_size
== 16)
1285 /* now reorganise base/index */
1286 if (s
== 1 && b
!= i
&& b
!= -1 && i
!= -1 &&
1287 ((hb
==b
&&ht
==EAH_NOTBASE
) || (hb
==i
&&ht
==EAH_MAKEBASE
)))
1288 t
= b
, b
= i
, i
= t
; /* swap if hints say so */
1289 if (b
==i
) /* convert EAX+2*EAX to 3*EAX */
1291 if (b
==-1 && s
==1 && !(hb
== i
&& ht
== EAH_NOTBASE
))
1292 b
= i
, i
= -1; /* make single reg base, unless hint */
1293 if (((s
==2 && i
!=R_ESP
&& !(input
->eaflags
& EAF_TIMESTWO
)) ||
1294 s
==3 || s
==5 || s
==9) && b
==-1)
1295 b
= i
, s
--; /* convert 3*EAX to EAX+2*EAX */
1296 if (i
==-1 && b
!=R_ESP
&& (input
->eaflags
& EAF_TIMESTWO
))
1297 i
= b
, b
= -1, s
= 1;
1298 /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */
1299 if (s
==1 && i
==R_ESP
) /* swap ESP into base if scale is 1 */
1301 if (i
==R_ESP
|| (s
!=1 && s
!=2 && s
!=4 && s
!=8 && i
!=-1))
1302 return NULL
; /* wrong, for various reasons */
1304 if (i
==-1 && b
!=R_ESP
) {/* no SIB needed */
1307 case R_EAX
: rm
= 0; break;
1308 case R_ECX
: rm
= 1; break;
1309 case R_EDX
: rm
= 2; break;
1310 case R_EBX
: rm
= 3; break;
1311 case R_EBP
: rm
= 5; break;
1312 case R_ESI
: rm
= 6; break;
1313 case R_EDI
: rm
= 7; break;
1314 case -1: rm
= 5; break;
1315 default: /* should never happen */
1318 if (b
==-1 || (b
!=R_EBP
&& o
==0 &&
1319 seg
==NO_SEG
&& !forw_ref
&&
1321 (EAF_BYTEOFFS
|EAF_WORDOFFS
))))
1323 else if (input
->eaflags
& EAF_BYTEOFFS
||
1324 (o
>=-128 && o
<=127 && seg
==NO_SEG
&& !forw_ref
&&
1325 !(input
->eaflags
& EAF_WORDOFFS
))) {
1331 output
->sib_present
= FALSE
;
1332 output
->bytes
= (b
==-1 || mod
==2 ? 4 : mod
);
1333 output
->modrm
= (mod
<<6) | (rfield
<<3) | rm
;
1335 else { /* we need a SIB */
1336 int mod
, scale
, index
, base
;
1339 case R_EAX
: base
= 0; break;
1340 case R_ECX
: base
= 1; break;
1341 case R_EDX
: base
= 2; break;
1342 case R_EBX
: base
= 3; break;
1343 case R_ESP
: base
= 4; break;
1344 case R_EBP
: case -1: base
= 5; break;
1345 case R_ESI
: base
= 6; break;
1346 case R_EDI
: base
= 7; break;
1347 default: /* then what the smeg is it? */
1348 return NULL
; /* panic */
1352 case R_EAX
: index
= 0; break;
1353 case R_ECX
: index
= 1; break;
1354 case R_EDX
: index
= 2; break;
1355 case R_EBX
: index
= 3; break;
1356 case -1: index
= 4; break;
1357 case R_EBP
: index
= 5; break;
1358 case R_ESI
: index
= 6; break;
1359 case R_EDI
: index
= 7; break;
1360 default: /* then what the smeg is it? */
1361 return NULL
; /* panic */
1366 case 1: scale
= 0; break;
1367 case 2: scale
= 1; break;
1368 case 4: scale
= 2; break;
1369 case 8: scale
= 3; break;
1370 default: /* then what the smeg is it? */
1371 return NULL
; /* panic */
1374 if (b
==-1 || (b
!=R_EBP
&& o
==0 &&
1375 seg
==NO_SEG
&& !forw_ref
&&
1377 (EAF_BYTEOFFS
|EAF_WORDOFFS
))))
1379 else if (input
->eaflags
& EAF_BYTEOFFS
||
1380 (o
>=-128 && o
<=127 && seg
==NO_SEG
&& !forw_ref
&&
1381 !(input
->eaflags
& EAF_WORDOFFS
)))
1386 output
->sib_present
= TRUE
;
1387 output
->bytes
= (b
==-1 || mod
==2 ? 4 : mod
);
1388 output
->modrm
= (mod
<<6) | (rfield
<<3) | 4;
1389 output
->sib
= (scale
<<6) | (index
<<3) | base
;
1392 else { /* it's 16-bit */
1395 /* check all registers are BX, BP, SI or DI */
1396 if ((b
!=-1 && b
!=R_BP
&& b
!=R_BX
&& b
!=R_SI
&& b
!=R_DI
) ||
1397 (i
!=-1 && i
!=R_BP
&& i
!=R_BX
&& i
!=R_SI
&& i
!=R_DI
))
1400 /* ensure the user didn't specify DWORD */
1401 if (input
->addr_size
== 32)
1404 if (s
!=1 && i
!=-1) return NULL
;/* no can do, in 16-bit EA */
1405 if (b
==-1 && i
!=-1) { int tmp
= b
; b
= i
; i
= tmp
; } /* swap */
1406 if ((b
==R_SI
|| b
==R_DI
) && i
!=-1)
1407 { int tmp
= b
; b
= i
; i
= tmp
; }
1408 /* have BX/BP as base, SI/DI index */
1409 if (b
==i
) return NULL
;/* shouldn't ever happen, in theory */
1410 if (i
!=-1 && b
!=-1 &&
1411 (i
==R_BP
|| i
==R_BX
|| b
==R_SI
|| b
==R_DI
))
1412 return NULL
; /* invalid combinations */
1413 if (b
==-1) /* pure offset: handled above */
1414 return NULL
; /* so if it gets to here, panic! */
1418 switch (i
*256 + b
) {
1419 case R_SI
*256+R_BX
: rm
=0; break;
1420 case R_DI
*256+R_BX
: rm
=1; break;
1421 case R_SI
*256+R_BP
: rm
=2; break;
1422 case R_DI
*256+R_BP
: rm
=3; break;
1426 case R_SI
: rm
=4; break;
1427 case R_DI
: rm
=5; break;
1428 case R_BP
: rm
=6; break;
1429 case R_BX
: rm
=7; break;
1431 if (rm
==-1) /* can't happen, in theory */
1432 return NULL
; /* so panic if it does */
1434 if (o
==0 && seg
==NO_SEG
&& !forw_ref
&& rm
!=6 &&
1435 !(input
->eaflags
& (EAF_BYTEOFFS
|EAF_WORDOFFS
)))
1437 else if (input
->eaflags
& EAF_BYTEOFFS
||
1438 (o
>=-128 && o
<=127 && seg
==NO_SEG
&& !forw_ref
&&
1439 !(input
->eaflags
& EAF_WORDOFFS
)))
1444 output
->sib_present
= FALSE
; /* no SIB - it's 16-bit */
1445 output
->bytes
= mod
; /* bytes of offset needed */
1446 output
->modrm
= (mod
<<6) | (rfield
<<3) | rm
;
1450 output
->size
= 1 + output
->sib_present
+ output
->bytes
;
1454 static int chsize (operand
*input
, int addrbits
)
1456 if (!(MEMORY
& ~input
->type
)) {
1457 int i
=input
->indexreg
, b
=input
->basereg
;
1459 if (input
->scale
==0) i
= -1;
1461 if (i
== -1 && b
== -1) /* pure offset */
1462 return (input
->addr_size
!= 0 && input
->addr_size
!= addrbits
);
1464 if (i
==R_EAX
|| i
==R_EBX
|| i
==R_ECX
|| i
==R_EDX
1465 || i
==R_EBP
|| i
==R_ESP
|| i
==R_ESI
|| i
==R_EDI
1466 || b
==R_EAX
|| b
==R_EBX
|| b
==R_ECX
|| b
==R_EDX
1467 || b
==R_EBP
|| b
==R_ESP
|| b
==R_ESI
|| b
==R_EDI
)
1468 return (addrbits
==16);
1470 return (addrbits
==32);