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 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 operand-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 meets byte jump criteria.
63 * 370 is used for Jcc, 371 is used for JMP.
64 * \373 - assemble 0x03 if bits==16, 0x05 if bits==32;
65 * used for conditional jump over longer jump
76 extern struct itemplate
*nasm_instructions
[];
79 int sib_present
; /* is a SIB byte necessary? */
80 int bytes
; /* # of bytes of offset needed */
81 int size
; /* lazy - this is sib+bytes+1 */
82 unsigned char modrm
, sib
; /* the bytes themselves */
85 static unsigned long cpu
; /* cpu level received from nasm.c */
87 static struct ofmt
*outfmt
;
90 static long calcsize (long, long, int, insn
*, char *);
91 static void gencode (long, long, int, insn
*, char *, long);
92 static int regval (operand
*o
);
93 static int matches (struct itemplate
*, insn
*);
94 static ea
* process_ea (operand
*, ea
*, int, int, int);
95 static int chsize (operand
*, int);
98 * This routine wrappers the real output format's output routine,
99 * in order to pass a copy of the data off to the listing file
100 * generator at the same time.
102 static void out (long offset
, long segto
, void *data
, unsigned long type
,
103 long segment
, long wrt
)
106 char *lnfname
= NULL
;
108 if ((type
& OUT_TYPMASK
) == OUT_ADDRESS
) {
109 if (segment
!= NO_SEG
|| wrt
!= NO_SEG
) {
111 * This address is relocated. We must write it as
112 * OUT_ADDRESS, so there's no work to be done here.
114 list
->output (offset
, data
, type
);
117 unsigned char p
[4], *q
= p
;
119 * This is a non-relocated address, and we're going to
120 * convert it into RAWDATA format.
122 if ((type
& OUT_SIZMASK
) == 4) {
123 WRITELONG (q
, * (long *) data
);
124 list
->output (offset
, p
, OUT_RAWDATA
+4);
127 WRITESHORT (q
, * (long *) data
);
128 list
->output (offset
, p
, OUT_RAWDATA
+2);
132 else if ((type
& OUT_TYPMASK
) == OUT_RAWDATA
) {
133 list
->output (offset
, data
, type
);
135 else if ((type
& OUT_TYPMASK
) == OUT_RESERVE
) {
136 list
->output (offset
, NULL
, type
);
138 else if ((type
& OUT_TYPMASK
) == OUT_REL2ADR
||
139 (type
& OUT_TYPMASK
) == OUT_REL4ADR
) {
140 list
->output (offset
, data
, type
);
143 if (src_get(&lineno
,&lnfname
))
145 outfmt
->current_dfmt
->linenum(lnfname
,lineno
,segto
);
146 if (lnfname
) nasm_free(lnfname
);
149 outfmt
->output (segto
, data
, type
, segment
, wrt
);
152 static int jmp_match (long segment
, long offset
, int bits
,
153 insn
*ins
, char *code
)
155 unsigned char c
= code
[0];
158 if (c
!= 0370 && c
!= 0371) return 0;
159 if (ins
->oprs
[0].opflags
& OPFLAG_FORWARD
) {
160 if ((optimizing
<0 || (ins
->oprs
[0].type
& STRICT
))
161 && c
==0370) return 1;
162 else return (pass0
==0); /* match a forward reference */
164 isize
= calcsize (segment
, offset
, bits
, ins
, code
);
165 if (ins
->oprs
[0].segment
!= segment
) return 0;
166 isize
= ins
->oprs
[0].offset
- offset
- isize
; /* isize is now the delta */
167 if (isize
>= -128L && isize
<= 127L) return 1; /* it is byte size */
173 long assemble (long segment
, long offset
, int bits
, unsigned long cp
,
174 insn
*instruction
, struct ofmt
*output
, efunc error
,
177 struct itemplate
*temp
;
183 long wsize
= 0; /* size for DB etc. */
185 errfunc
= error
; /* to pass to other functions */
187 outfmt
= output
; /* likewise */
188 list
= listgen
; /* and again */
190 switch (instruction
->opcode
)
193 case I_DB
: wsize
= 1; break;
194 case I_DW
: wsize
= 2; break;
195 case I_DD
: wsize
= 4; break;
196 case I_DQ
: wsize
= 8; break;
197 case I_DT
: wsize
= 10; break;
202 long t
= instruction
->times
;
204 errfunc(ERR_PANIC
, "instruction->times < 0 (%ld) in assemble()",t
);
206 while (t
--) /* repeat TIMES times */
208 for (e
= instruction
->eops
; e
; e
= e
->next
)
210 if (e
->type
== EOT_DB_NUMBER
)
213 if (e
->segment
!= NO_SEG
)
214 errfunc (ERR_NONFATAL
,
215 "one-byte relocation attempted");
217 unsigned char out_byte
= e
->offset
;
218 out (offset
, segment
, &out_byte
, OUT_RAWDATA
+1,
222 else if (wsize
> 5) {
223 errfunc (ERR_NONFATAL
, "integer supplied to a D%c"
224 " instruction", wsize
==8 ? 'Q' : 'T');
227 out (offset
, segment
, &e
->offset
,
228 OUT_ADDRESS
+wsize
, e
->segment
,
232 else if (e
->type
== EOT_DB_STRING
)
236 out (offset
, segment
, e
->stringval
,
237 OUT_RAWDATA
+e
->stringlen
, NO_SEG
, NO_SEG
);
238 align
= e
->stringlen
% wsize
;
241 align
= wsize
- align
;
242 out (offset
, segment
, "\0\0\0\0\0\0\0\0",
243 OUT_RAWDATA
+align
, NO_SEG
, NO_SEG
);
245 offset
+= e
->stringlen
+ align
;
248 if (t
> 0 && t
== instruction
->times
-1)
251 * Dummy call to list->output to give the offset to the
254 list
->output (offset
, NULL
, OUT_RAWDATA
);
255 list
->uplevel (LIST_TIMES
);
258 if (instruction
->times
> 1)
259 list
->downlevel (LIST_TIMES
);
260 return offset
- start
;
263 if (instruction
->opcode
== I_INCBIN
)
265 static char fname
[FILENAME_MAX
];
269 len
= FILENAME_MAX
-1;
270 if (len
> instruction
->eops
->stringlen
)
271 len
= instruction
->eops
->stringlen
;
272 strncpy (fname
, instruction
->eops
->stringval
, len
);
275 if ( (fp
= fopen(fname
, "rb")) == NULL
)
276 error (ERR_NONFATAL
, "`incbin': unable to open file `%s'", fname
);
277 else if (fseek(fp
, 0L, SEEK_END
) < 0)
278 error (ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
282 static char buf
[2048];
283 long t
= instruction
->times
;
287 if (instruction
->eops
->next
) {
288 base
= instruction
->eops
->next
->offset
;
290 if (instruction
->eops
->next
->next
&&
291 len
> instruction
->eops
->next
->next
->offset
)
292 len
= instruction
->eops
->next
->next
->offset
;
295 * Dummy call to list->output to give the offset to the
298 list
->output (offset
, NULL
, OUT_RAWDATA
);
299 list
->uplevel(LIST_INCBIN
);
304 fseek (fp
, base
, SEEK_SET
);
307 long m
= fread (buf
, 1, (l
>sizeof(buf
)?sizeof(buf
):l
),
311 * This shouldn't happen unless the file
312 * actually changes while we are reading
315 error (ERR_NONFATAL
, "`incbin': unexpected EOF while"
316 " reading file `%s'", fname
);
317 t
=0; /* Try to exit cleanly */
320 out (offset
, segment
, buf
, OUT_RAWDATA
+m
,
325 list
->downlevel(LIST_INCBIN
);
326 if (instruction
->times
> 1) {
328 * Dummy call to list->output to give the offset to the
331 list
->output (offset
, NULL
, OUT_RAWDATA
);
332 list
->uplevel(LIST_TIMES
);
333 list
->downlevel(LIST_TIMES
);
336 return instruction
->times
* len
;
338 return 0; /* if we're here, there's an error */
342 temp
= nasm_instructions
[instruction
->opcode
];
343 while (temp
->opcode
!= -1) {
344 int m
= matches (temp
, instruction
);
346 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
348 if (m
== 100) /* matches! */
350 char *codes
= temp
->code
;
351 long insn_size
= calcsize(segment
, offset
, bits
,
353 itimes
= instruction
->times
;
354 if (insn_size
< 0) /* shouldn't be, on pass two */
355 error (ERR_PANIC
, "errors made it through from pass one");
356 else while (itimes
--) {
357 insn_end
= offset
+ insn_size
;
358 for (j
=0; j
<instruction
->nprefix
; j
++) {
360 switch (instruction
->prefixes
[j
]) {
363 case P_REPNE
: case P_REPNZ
:
365 case P_REPE
: case P_REPZ
: case P_REP
:
367 case R_CS
: c
= 0x2E; break;
368 case R_DS
: c
= 0x3E; break;
369 case R_ES
: c
= 0x26; break;
370 case R_FS
: c
= 0x64; break;
371 case R_GS
: c
= 0x65; break;
372 case R_SS
: c
= 0x36; break;
391 "invalid instruction prefix");
394 out (offset
, segment
, &c
, OUT_RAWDATA
+1,
399 gencode (segment
, offset
, bits
, instruction
, codes
, insn_end
);
401 if (itimes
> 0 && itimes
== instruction
->times
-1) {
403 * Dummy call to list->output to give the offset to the
406 list
->output (offset
, NULL
, OUT_RAWDATA
);
407 list
->uplevel (LIST_TIMES
);
410 if (instruction
->times
> 1)
411 list
->downlevel (LIST_TIMES
);
412 return offset
- start
;
413 } else if (m
> 0 && m
> size_prob
) {
419 if (temp
->opcode
== -1) { /* didn't match any instruction */
420 if (size_prob
== 1) /* would have matched, but for size */
421 error (ERR_NONFATAL
, "operation size not specified");
422 else if (size_prob
== 2)
423 error (ERR_NONFATAL
, "mismatch in operand sizes");
424 else if (size_prob
== 3)
425 error (ERR_NONFATAL
, "no instruction for this cpu level");
428 "invalid combination of opcode and operands");
433 long insn_size (long segment
, long offset
, int bits
, unsigned long cp
,
434 insn
*instruction
, efunc error
)
436 struct itemplate
*temp
;
438 errfunc
= error
; /* to pass to other functions */
441 if (instruction
->opcode
== -1)
444 if (instruction
->opcode
== I_DB
||
445 instruction
->opcode
== I_DW
||
446 instruction
->opcode
== I_DD
||
447 instruction
->opcode
== I_DQ
||
448 instruction
->opcode
== I_DT
)
451 long isize
, osize
, wsize
= 0; /* placate gcc */
454 switch (instruction
->opcode
)
456 case I_DB
: wsize
= 1; break;
457 case I_DW
: wsize
= 2; break;
458 case I_DD
: wsize
= 4; break;
459 case I_DQ
: wsize
= 8; break;
460 case I_DT
: wsize
= 10; break;
463 for (e
= instruction
->eops
; e
; e
= e
->next
)
468 if (e
->type
== EOT_DB_NUMBER
)
470 else if (e
->type
== EOT_DB_STRING
)
471 osize
= e
->stringlen
;
473 align
= (-osize
) % wsize
;
476 isize
+= osize
+ align
;
478 return isize
* instruction
->times
;
481 if (instruction
->opcode
== I_INCBIN
)
483 char fname
[FILENAME_MAX
];
487 len
= FILENAME_MAX
-1;
488 if (len
> instruction
->eops
->stringlen
)
489 len
= instruction
->eops
->stringlen
;
490 strncpy (fname
, instruction
->eops
->stringval
, len
);
492 if ( (fp
= fopen(fname
, "rb")) == NULL
)
493 error (ERR_NONFATAL
, "`incbin': unable to open file `%s'", fname
);
494 else if (fseek(fp
, 0L, SEEK_END
) < 0)
495 error (ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
501 if (instruction
->eops
->next
)
503 len
-= instruction
->eops
->next
->offset
;
504 if (instruction
->eops
->next
->next
&&
505 len
> instruction
->eops
->next
->next
->offset
)
507 len
= instruction
->eops
->next
->next
->offset
;
510 return instruction
->times
* len
;
512 return 0; /* if we're here, there's an error */
515 temp
= nasm_instructions
[instruction
->opcode
];
516 while (temp
->opcode
!= -1) {
517 int m
= matches(temp
, instruction
);
519 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
522 /* we've matched an instruction. */
524 char * codes
= temp
->code
;
527 isize
= calcsize(segment
, offset
, bits
, instruction
, codes
);
530 for (j
= 0; j
< instruction
->nprefix
; j
++)
532 if ((instruction
->prefixes
[j
] != P_A16
&&
533 instruction
->prefixes
[j
] != P_O16
&& bits
==16) ||
534 (instruction
->prefixes
[j
] != P_A32
&&
535 instruction
->prefixes
[j
] != P_O32
&& bits
==32))
540 return isize
* instruction
->times
;
544 return -1; /* didn't match any instruction */
548 /* check that opn[op] is a signed byte of size 16 or 32,
549 and return the signed value*/
550 static int is_sbyte (insn
*ins
, int op
, int size
)
555 ret
= !(ins
->forw_ref
&& ins
->oprs
[op
].opflags
) && /* dead in the water on forward reference or External */
557 !(ins
->oprs
[op
].type
& STRICT
) &&
558 ins
->oprs
[op
].wrt
==NO_SEG
&& ins
->oprs
[op
].segment
==NO_SEG
;
560 v
= ins
->oprs
[op
].offset
;
561 if (size
==16) v
= (signed short)v
; /* sign extend if 16 bits */
563 return ret
&& v
>=-128L && v
<=127L;
566 static long calcsize (long segment
, long offset
, int bits
,
567 insn
*ins
, char *codes
)
572 (void) segment
; /* Don't warn that this parameter is unused */
573 (void) offset
; /* Don't warn that this parameter is unused */
575 while (*codes
) switch (c
= *codes
++) {
576 case 01: case 02: case 03:
577 codes
+= c
, length
+= c
; break;
578 case 04: case 05: case 06: case 07:
580 case 010: case 011: case 012:
581 codes
++, length
++; break;
584 case 014: case 015: case 016:
586 case 020: case 021: case 022:
588 case 024: case 025: case 026:
590 case 030: case 031: case 032:
592 case 034: case 035: case 036:
593 length
+= ((ins
->oprs
[c
-034].addr_size
?
594 ins
->oprs
[c
-034].addr_size
: bits
) == 16 ? 2 : 4); break;
597 case 040: case 041: case 042:
599 case 050: case 051: case 052:
601 case 060: case 061: case 062:
603 case 064: case 065: case 066:
604 if ( ins
->oprs
[c
-064].type
& (BITS16
|BITS32
) )
605 length
+= (ins
->oprs
[c
-064].type
& BITS16
) ? 2 : 4;
607 length
+= (bits
== 16) ? 2 : 4;
609 case 070: case 071: case 072:
611 case 0130: case 0131: case 0132:
612 length
+= is_sbyte(ins
, c
-0130, 16) ? 1 : 2; break;
613 case 0133: case 0134: case 0135:
614 codes
+=2; length
++; break;
615 case 0140: case 0141: case 0142:
616 length
+= is_sbyte(ins
, c
-0140, 32) ? 1 : 4; break;
617 case 0143: case 0144: case 0145:
618 codes
+=2; length
++; break;
619 case 0300: case 0301: case 0302:
620 length
+= chsize (&ins
->oprs
[c
-0300], bits
);
623 length
+= (bits
==32);
626 length
+= (bits
==16);
631 length
+= (bits
==32);
634 length
+= (bits
==16);
639 codes
++, length
++; break;
645 case 0340: case 0341: case 0342:
646 if (ins
->oprs
[0].segment
!= NO_SEG
)
647 errfunc (ERR_NONFATAL
, "attempt to reserve non-constant"
648 " quantity of BSS space");
650 length
+= ins
->oprs
[0].offset
<< (c
-0340);
652 case 0370: case 0371: case 0372:
656 default: /* can't do it by 'case' statements */
657 if (c
>=0100 && c
<=0277) { /* it's an EA */
659 if (!process_ea (&ins
->oprs
[(c
>>3)&7], &ea_data
, bits
, 0,
661 errfunc (ERR_NONFATAL
, "invalid effective address");
664 length
+= ea_data
.size
;
666 errfunc (ERR_PANIC
, "internal instruction table corrupt"
667 ": instruction code 0x%02X given", c
);
672 static void gencode (long segment
, long offset
, int bits
,
673 insn
*ins
, char *codes
, long insn_end
)
675 static char condval
[] = { /* conditional opcodes */
676 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
677 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
678 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
681 unsigned char bytes
[4];
685 switch (c
= *codes
++)
687 case 01: case 02: case 03:
688 out (offset
, segment
, codes
, OUT_RAWDATA
+c
, NO_SEG
, NO_SEG
);
694 switch (ins
->oprs
[0].basereg
)
697 bytes
[0] = 0x0E + (c
== 0x04 ? 1 : 0); break;
699 bytes
[0] = 0x1E + (c
== 0x04 ? 1 : 0); break;
701 bytes
[0] = 0x06 + (c
== 0x04 ? 1 : 0); break;
703 bytes
[0] = 0x16 + (c
== 0x04 ? 1 : 0); break;
705 errfunc (ERR_PANIC
, "bizarre 8086 segment register received");
707 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
712 switch (ins
->oprs
[0].basereg
) {
713 case R_FS
: bytes
[0] = 0xA0 + (c
== 0x05 ? 1 : 0); break;
714 case R_GS
: bytes
[0] = 0xA8 + (c
== 0x05 ? 1 : 0); break;
716 errfunc (ERR_PANIC
, "bizarre 386 segment register received");
718 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
722 case 010: case 011: case 012:
723 bytes
[0] = *codes
++ + regval(&ins
->oprs
[c
-010]);
724 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
730 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
734 case 014: case 015: case 016:
735 if (ins
->oprs
[c
-014].offset
< -128
736 || ins
->oprs
[c
-014].offset
> 127)
738 errfunc (ERR_WARNING
, "signed byte value exceeds bounds");
741 if (ins
->oprs
[c
-014].segment
!= NO_SEG
)
743 data
= ins
->oprs
[c
-014].offset
;
744 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
745 ins
->oprs
[c
-014].segment
, ins
->oprs
[c
-014].wrt
);
748 bytes
[0] = ins
->oprs
[c
-014].offset
;
749 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
754 case 020: case 021: case 022:
755 if (ins
->oprs
[c
-020].offset
< -256
756 || ins
->oprs
[c
-020].offset
> 255)
758 errfunc (ERR_WARNING
, "byte value exceeds bounds");
760 if (ins
->oprs
[c
-020].segment
!= NO_SEG
) {
761 data
= ins
->oprs
[c
-020].offset
;
762 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
763 ins
->oprs
[c
-020].segment
, ins
->oprs
[c
-020].wrt
);
766 bytes
[0] = ins
->oprs
[c
-020].offset
;
767 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
772 case 024: case 025: case 026:
773 if (ins
->oprs
[c
-024].offset
< 0 || ins
->oprs
[c
-024].offset
> 255)
774 errfunc (ERR_WARNING
, "unsigned byte value exceeds bounds");
775 if (ins
->oprs
[c
-024].segment
!= NO_SEG
) {
776 data
= ins
->oprs
[c
-024].offset
;
777 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
778 ins
->oprs
[c
-024].segment
, ins
->oprs
[c
-024].wrt
);
781 bytes
[0] = ins
->oprs
[c
-024].offset
;
782 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
787 case 030: case 031: case 032:
788 if (ins
->oprs
[c
-030].segment
== NO_SEG
&&
789 ins
->oprs
[c
-030].wrt
== NO_SEG
&&
790 (ins
->oprs
[c
-030].offset
< -65536L ||
791 ins
->oprs
[c
-030].offset
> 65535L))
793 errfunc (ERR_WARNING
, "word value exceeds bounds");
795 data
= ins
->oprs
[c
-030].offset
;
796 out (offset
, segment
, &data
, OUT_ADDRESS
+2,
797 ins
->oprs
[c
-030].segment
, ins
->oprs
[c
-030].wrt
);
801 case 034: case 035: case 036:
802 data
= ins
->oprs
[c
-034].offset
;
803 size
= ((ins
->oprs
[c
-034].addr_size
?
804 ins
->oprs
[c
-034].addr_size
: bits
) == 16 ? 2 : 4);
805 if (size
==2 && (data
< -65536L || data
> 65535L))
806 errfunc (ERR_WARNING
, "word value exceeds bounds");
807 out (offset
, segment
, &data
, OUT_ADDRESS
+size
,
808 ins
->oprs
[c
-034].segment
, ins
->oprs
[c
-034].wrt
);
813 if (ins
->oprs
[0].segment
== NO_SEG
)
814 errfunc (ERR_NONFATAL
, "value referenced by FAR is not"
817 out (offset
, segment
, &data
, OUT_ADDRESS
+2,
818 outfmt
->segbase(1+ins
->oprs
[0].segment
),
823 case 040: case 041: case 042:
824 data
= ins
->oprs
[c
-040].offset
;
825 out (offset
, segment
, &data
, OUT_ADDRESS
+4,
826 ins
->oprs
[c
-040].segment
, ins
->oprs
[c
-040].wrt
);
830 case 050: case 051: case 052:
831 if (ins
->oprs
[c
-050].segment
!= segment
)
832 errfunc (ERR_NONFATAL
, "short relative jump outside segment");
833 data
= ins
->oprs
[c
-050].offset
- insn_end
;
834 if (data
> 127 || data
< -128)
835 errfunc (ERR_NONFATAL
, "short jump is out of range");
837 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
841 case 060: case 061: case 062:
842 if (ins
->oprs
[c
-060].segment
!= segment
) {
843 data
= ins
->oprs
[c
-060].offset
;
844 out (offset
, segment
, &data
, OUT_REL2ADR
+insn_end
-offset
,
845 ins
->oprs
[c
-060].segment
, ins
->oprs
[c
-060].wrt
);
847 data
= ins
->oprs
[c
-060].offset
- insn_end
;
848 out (offset
, segment
, &data
,
849 OUT_ADDRESS
+2, NO_SEG
, NO_SEG
);
854 case 064: case 065: case 066:
855 if ( ins
->oprs
[c
-064].type
& (BITS16
|BITS32
) )
856 size
= (ins
->oprs
[c
-064].type
& BITS16
) ? 2 : 4;
858 size
= (bits
== 16) ? 2 : 4;
859 if (ins
->oprs
[c
-064].segment
!= segment
) {
860 long reltype
= (size
== 2 ? OUT_REL2ADR
: OUT_REL4ADR
);
861 data
= ins
->oprs
[c
-064].offset
;
862 out (offset
, segment
, &data
, reltype
+insn_end
-offset
,
863 ins
->oprs
[c
-064].segment
, ins
->oprs
[c
-064].wrt
);
865 data
= ins
->oprs
[c
-064].offset
- insn_end
;
866 out (offset
, segment
, &data
,
867 OUT_ADDRESS
+size
, NO_SEG
, NO_SEG
);
872 case 070: case 071: case 072:
873 if (ins
->oprs
[c
-070].segment
!= segment
) {
874 data
= ins
->oprs
[c
-070].offset
;
875 out (offset
, segment
, &data
, OUT_REL4ADR
+insn_end
-offset
,
876 ins
->oprs
[c
-070].segment
, ins
->oprs
[c
-070].wrt
);
878 data
= ins
->oprs
[c
-070].offset
- insn_end
;
879 out (offset
, segment
, &data
,
880 OUT_ADDRESS
+4, NO_SEG
, NO_SEG
);
885 case 0130: case 0131: case 0132:
886 data
= ins
->oprs
[c
-0130].offset
;
887 if (is_sbyte(ins
, c
-0130, 16)) {
888 out (offset
, segment
, &data
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
891 if (ins
->oprs
[c
-0130].segment
== NO_SEG
&&
892 ins
->oprs
[c
-0130].wrt
== NO_SEG
&&
893 (data
< -65536L || data
> 65535L)) {
894 errfunc (ERR_WARNING
, "word value exceeds bounds");
896 out (offset
, segment
, &data
, OUT_ADDRESS
+2,
897 ins
->oprs
[c
-0130].segment
, ins
->oprs
[c
-0130].wrt
);
902 case 0133: case 0134: case 0135:
905 if (is_sbyte(ins
, c
-0133, 16)) bytes
[0] |= 2; /* s-bit */
906 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
910 case 0140: case 0141: case 0142:
911 data
= ins
->oprs
[c
-0140].offset
;
912 if (is_sbyte(ins
, c
-0140, 32)) {
913 out (offset
, segment
, &data
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
916 out (offset
, segment
, &data
, OUT_ADDRESS
+4,
917 ins
->oprs
[c
-0140].segment
, ins
->oprs
[c
-0140].wrt
);
922 case 0143: case 0144: case 0145:
925 if (is_sbyte(ins
, c
-0143, 32)) bytes
[0] |= 2; /* s-bit */
926 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
930 case 0300: case 0301: case 0302:
931 if (chsize (&ins
->oprs
[c
-0300], bits
)) {
933 out (offset
, segment
, bytes
,
934 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
943 out (offset
, segment
, bytes
,
944 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
953 out (offset
, segment
, bytes
,
954 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
966 out (offset
, segment
, bytes
,
967 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
976 out (offset
, segment
, bytes
,
977 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
987 *bytes
= *codes
++ ^ condval
[ins
->condition
];
988 out (offset
, segment
, bytes
,
989 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
999 out (offset
, segment
, bytes
,
1000 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1004 case 0340: case 0341: case 0342:
1005 if (ins
->oprs
[0].segment
!= NO_SEG
)
1006 errfunc (ERR_PANIC
, "non-constant BSS size in pass two");
1008 long size
= ins
->oprs
[0].offset
<< (c
-0340);
1010 out (offset
, segment
, NULL
,
1011 OUT_RESERVE
+size
, NO_SEG
, NO_SEG
);
1016 case 0370: case 0371: case 0372:
1020 *bytes
= bits
==16 ? 3 : 5;
1021 out (offset
, segment
, bytes
,
1022 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1026 default: /* can't do it by 'case' statements */
1027 if (c
>=0100 && c
<=0277) { /* it's an EA */
1033 if (c
<=0177) /* pick rfield from operand b */
1034 rfield
= regval (&ins
->oprs
[c
&7]);
1035 else /* rfield is constant */
1038 if (!process_ea (&ins
->oprs
[(c
>>3)&7], &ea_data
, bits
, rfield
,
1041 errfunc (ERR_NONFATAL
, "invalid effective address");
1045 *p
++ = ea_data
.modrm
;
1046 if (ea_data
.sib_present
)
1050 out (offset
, segment
, bytes
, OUT_RAWDATA
+ s
,
1053 switch (ea_data
.bytes
) {
1057 if (ins
->oprs
[(c
>>3)&7].segment
!= NO_SEG
) {
1058 data
= ins
->oprs
[(c
>>3)&7].offset
;
1059 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
1060 ins
->oprs
[(c
>>3)&7].segment
,
1061 ins
->oprs
[(c
>>3)&7].wrt
);
1063 *bytes
= ins
->oprs
[(c
>>3)&7].offset
;
1064 out (offset
, segment
, bytes
, OUT_RAWDATA
+1,
1071 data
= ins
->oprs
[(c
>>3)&7].offset
;
1072 out (offset
, segment
, &data
,
1073 OUT_ADDRESS
+ea_data
.bytes
,
1074 ins
->oprs
[(c
>>3)&7].segment
, ins
->oprs
[(c
>>3)&7].wrt
);
1080 errfunc (ERR_PANIC
, "internal instruction table corrupt"
1081 ": instruction code 0x%02X given", c
);
1085 static int regval (operand
*o
)
1087 switch (o
->basereg
) {
1088 case R_EAX
: case R_AX
: case R_AL
: case R_ES
: case R_CR0
: case R_DR0
:
1089 case R_ST0
: case R_MM0
: case R_XMM0
:
1091 case R_ECX
: case R_CX
: case R_CL
: case R_CS
: case R_DR1
: case R_ST1
:
1092 case R_MM1
: case R_XMM1
:
1094 case R_EDX
: case R_DX
: case R_DL
: case R_SS
: case R_CR2
: case R_DR2
:
1095 case R_ST2
: case R_MM2
: case R_XMM2
:
1097 case R_EBX
: case R_BX
: case R_BL
: case R_DS
: case R_CR3
: case R_DR3
:
1098 case R_TR3
: case R_ST3
: case R_MM3
: case R_XMM3
:
1100 case R_ESP
: case R_SP
: case R_AH
: case R_FS
: case R_CR4
: case R_TR4
:
1101 case R_ST4
: case R_MM4
: case R_XMM4
:
1103 case R_EBP
: case R_BP
: case R_CH
: case R_GS
: case R_TR5
: case R_ST5
:
1104 case R_MM5
: case R_XMM5
:
1106 case R_ESI
: case R_SI
: case R_DH
: case R_DR6
: case R_TR6
: case R_ST6
:
1107 case R_MM6
: case R_XMM6
:
1109 case R_EDI
: case R_DI
: case R_BH
: case R_DR7
: case R_TR7
: case R_ST7
:
1110 case R_MM7
: case R_XMM7
:
1112 default: /* panic */
1113 errfunc (ERR_PANIC
, "invalid register operand given to regval()");
1118 static int matches (struct itemplate
*itemp
, insn
*instruction
)
1120 int i
, size
[3], asize
, oprs
, ret
;
1127 if (itemp
->opcode
!= instruction
->opcode
) return 0;
1130 * Count the operands
1132 if (itemp
->operands
!= instruction
->operands
) return 0;
1135 * Check that no spurious colons or TOs are present
1137 for (i
=0; i
<itemp
->operands
; i
++)
1138 if (instruction
->oprs
[i
].type
& ~itemp
->opd
[i
] & (COLON
|TO
))
1142 * Check that the operand flags all match up
1144 for (i
=0; i
<itemp
->operands
; i
++)
1145 if (itemp
->opd
[i
] & ~instruction
->oprs
[i
].type
||
1146 ((itemp
->opd
[i
] & SIZE_MASK
) &&
1147 ((itemp
->opd
[i
] ^ instruction
->oprs
[i
].type
) & SIZE_MASK
)))
1149 if ((itemp
->opd
[i
] & ~instruction
->oprs
[i
].type
& NON_SIZE
) ||
1150 (instruction
->oprs
[i
].type
& SIZE_MASK
))
1158 * Check operand sizes
1160 if (itemp
->flags
& IF_ARMASK
) {
1161 size
[0] = size
[1] = size
[2] = 0;
1163 switch (itemp
->flags
& IF_ARMASK
) {
1164 case IF_AR0
: i
= 0; break;
1165 case IF_AR1
: i
= 1; break;
1166 case IF_AR2
: i
= 2; break;
1167 default: break; /* Shouldn't happen */
1169 if (itemp
->flags
& IF_SB
) {
1171 } else if (itemp
->flags
& IF_SW
) {
1173 } else if (itemp
->flags
& IF_SD
) {
1178 if (itemp
->flags
& IF_SB
) {
1180 oprs
= itemp
->operands
;
1181 } else if (itemp
->flags
& IF_SW
) {
1183 oprs
= itemp
->operands
;
1184 } else if (itemp
->flags
& IF_SD
) {
1186 oprs
= itemp
->operands
;
1188 size
[0] = size
[1] = size
[2] = asize
;
1191 if (itemp
->flags
& (IF_SM
| IF_SM2
)) {
1192 oprs
= (itemp
->flags
& IF_SM2
? 2 : itemp
->operands
);
1194 for (i
=0; i
<oprs
; i
++) {
1195 if ( (asize
= itemp
->opd
[i
] & SIZE_MASK
) != 0) {
1197 for (j
=0; j
<oprs
; j
++)
1203 oprs
= itemp
->operands
;
1206 for (i
=0; i
<itemp
->operands
; i
++)
1207 if (!(itemp
->opd
[i
] & SIZE_MASK
) &&
1208 (instruction
->oprs
[i
].type
& SIZE_MASK
& ~size
[i
]))
1213 * Check template is okay at the set cpu level
1215 if ((itemp
->flags
& IF_PLEVEL
) > cpu
) return 3;
1218 * Check if special handling needed for Jumps
1220 if ((unsigned char)(itemp
->code
[0]) >= 0370) return 99;
1225 static ea
*process_ea (operand
*input
, ea
*output
, int addrbits
, int rfield
,
1228 if (!(REGISTER
& ~input
->type
)) { /* it's a single register */
1229 static int regs
[] = {
1230 R_AL
, R_CL
, R_DL
, R_BL
, R_AH
, R_CH
, R_DH
, R_BH
,
1231 R_AX
, R_CX
, R_DX
, R_BX
, R_SP
, R_BP
, R_SI
, R_DI
,
1232 R_EAX
, R_ECX
, R_EDX
, R_EBX
, R_ESP
, R_EBP
, R_ESI
, R_EDI
,
1233 R_MM0
, R_MM1
, R_MM2
, R_MM3
, R_MM4
, R_MM5
, R_MM6
, R_MM7
,
1234 R_XMM0
, R_XMM1
, R_XMM2
, R_XMM3
, R_XMM4
, R_XMM5
, R_XMM6
, R_XMM7
1238 for (i
=0; i
<elements(regs
); i
++)
1239 if (input
->basereg
== regs
[i
]) break;
1240 if (i
<elements(regs
)) {
1241 output
->sib_present
= FALSE
;/* no SIB necessary */
1242 output
->bytes
= 0; /* no offset necessary either */
1243 output
->modrm
= 0xC0 | (rfield
<< 3) | (i
& 7);
1247 } else { /* it's a memory reference */
1248 if (input
->basereg
==-1 && (input
->indexreg
==-1 || input
->scale
==0)) {
1249 /* it's a pure offset */
1250 if (input
->addr_size
)
1251 addrbits
= input
->addr_size
;
1252 output
->sib_present
= FALSE
;
1253 output
->bytes
= (addrbits
==32 ? 4 : 2);
1254 output
->modrm
= (addrbits
==32 ? 5 : 6) | (rfield
<< 3);
1256 else { /* it's an indirection */
1257 int i
=input
->indexreg
, b
=input
->basereg
, s
=input
->scale
;
1258 long o
=input
->offset
, seg
=input
->segment
;
1259 int hb
=input
->hintbase
, ht
=input
->hinttype
;
1262 if (s
==0) i
= -1; /* make this easy, at least */
1264 if (i
==R_EAX
|| i
==R_EBX
|| i
==R_ECX
|| i
==R_EDX
1265 || i
==R_EBP
|| i
==R_ESP
|| i
==R_ESI
|| i
==R_EDI
1266 || b
==R_EAX
|| b
==R_EBX
|| b
==R_ECX
|| b
==R_EDX
1267 || b
==R_EBP
|| b
==R_ESP
|| b
==R_ESI
|| b
==R_EDI
) {
1268 /* it must be a 32-bit memory reference. Firstly we have
1269 * to check that all registers involved are type Exx. */
1270 if (i
!=-1 && i
!=R_EAX
&& i
!=R_EBX
&& i
!=R_ECX
&& i
!=R_EDX
1271 && i
!=R_EBP
&& i
!=R_ESP
&& i
!=R_ESI
&& i
!=R_EDI
)
1273 if (b
!=-1 && b
!=R_EAX
&& b
!=R_EBX
&& b
!=R_ECX
&& b
!=R_EDX
1274 && b
!=R_EBP
&& b
!=R_ESP
&& b
!=R_ESI
&& b
!=R_EDI
)
1277 /* While we're here, ensure the user didn't specify WORD. */
1278 if (input
->addr_size
== 16)
1281 /* now reorganise base/index */
1282 if (s
== 1 && b
!= i
&& b
!= -1 && i
!= -1 &&
1283 ((hb
==b
&&ht
==EAH_NOTBASE
) || (hb
==i
&&ht
==EAH_MAKEBASE
)))
1284 t
= b
, b
= i
, i
= t
; /* swap if hints say so */
1285 if (b
==i
) /* convert EAX+2*EAX to 3*EAX */
1287 if (b
==-1 && s
==1 && !(hb
== i
&& ht
== EAH_NOTBASE
))
1288 b
= i
, i
= -1; /* make single reg base, unless hint */
1289 if (((s
==2 && i
!=R_ESP
&& !(input
->eaflags
& EAF_TIMESTWO
)) ||
1290 s
==3 || s
==5 || s
==9) && b
==-1)
1291 b
= i
, s
--; /* convert 3*EAX to EAX+2*EAX */
1292 if (s
==1 && i
==R_ESP
) /* swap ESP into base if scale is 1 */
1294 if (i
==R_ESP
|| (s
!=1 && s
!=2 && s
!=4 && s
!=8 && i
!=-1))
1295 return NULL
; /* wrong, for various reasons */
1297 if (i
==-1 && b
!=R_ESP
) {/* no SIB needed */
1300 case R_EAX
: rm
= 0; break;
1301 case R_ECX
: rm
= 1; break;
1302 case R_EDX
: rm
= 2; break;
1303 case R_EBX
: rm
= 3; break;
1304 case R_EBP
: rm
= 5; break;
1305 case R_ESI
: rm
= 6; break;
1306 case R_EDI
: rm
= 7; break;
1307 case -1: rm
= 5; break;
1308 default: /* should never happen */
1311 if (b
==-1 || (b
!=R_EBP
&& o
==0 &&
1312 seg
==NO_SEG
&& !forw_ref
&&
1314 (EAF_BYTEOFFS
|EAF_WORDOFFS
))))
1316 else if (input
->eaflags
& EAF_BYTEOFFS
||
1317 (o
>=-128 && o
<=127 && seg
==NO_SEG
&& !forw_ref
&&
1318 !(input
->eaflags
& EAF_WORDOFFS
))) {
1324 output
->sib_present
= FALSE
;
1325 output
->bytes
= (b
==-1 || mod
==2 ? 4 : mod
);
1326 output
->modrm
= (mod
<<6) | (rfield
<<3) | rm
;
1328 else { /* we need a SIB */
1329 int mod
, scale
, index
, base
;
1332 case R_EAX
: base
= 0; break;
1333 case R_ECX
: base
= 1; break;
1334 case R_EDX
: base
= 2; break;
1335 case R_EBX
: base
= 3; break;
1336 case R_ESP
: base
= 4; break;
1337 case R_EBP
: case -1: base
= 5; break;
1338 case R_ESI
: base
= 6; break;
1339 case R_EDI
: base
= 7; break;
1340 default: /* then what the smeg is it? */
1341 return NULL
; /* panic */
1345 case R_EAX
: index
= 0; break;
1346 case R_ECX
: index
= 1; break;
1347 case R_EDX
: index
= 2; break;
1348 case R_EBX
: index
= 3; break;
1349 case -1: index
= 4; break;
1350 case R_EBP
: index
= 5; break;
1351 case R_ESI
: index
= 6; break;
1352 case R_EDI
: index
= 7; break;
1353 default: /* then what the smeg is it? */
1354 return NULL
; /* panic */
1359 case 1: scale
= 0; break;
1360 case 2: scale
= 1; break;
1361 case 4: scale
= 2; break;
1362 case 8: scale
= 3; break;
1363 default: /* then what the smeg is it? */
1364 return NULL
; /* panic */
1367 if (b
==-1 || (b
!=R_EBP
&& o
==0 &&
1368 seg
==NO_SEG
&& !forw_ref
&&
1370 (EAF_BYTEOFFS
|EAF_WORDOFFS
))))
1372 else if (input
->eaflags
& EAF_BYTEOFFS
||
1373 (o
>=-128 && o
<=127 && seg
==NO_SEG
&& !forw_ref
&&
1374 !(input
->eaflags
& EAF_WORDOFFS
)))
1379 output
->sib_present
= TRUE
;
1380 output
->bytes
= (b
==-1 || mod
==2 ? 4 : mod
);
1381 output
->modrm
= (mod
<<6) | (rfield
<<3) | 4;
1382 output
->sib
= (scale
<<6) | (index
<<3) | base
;
1385 else { /* it's 16-bit */
1388 /* check all registers are BX, BP, SI or DI */
1389 if ((b
!=-1 && b
!=R_BP
&& b
!=R_BX
&& b
!=R_SI
&& b
!=R_DI
) ||
1390 (i
!=-1 && i
!=R_BP
&& i
!=R_BX
&& i
!=R_SI
&& i
!=R_DI
))
1393 /* ensure the user didn't specify DWORD */
1394 if (input
->addr_size
== 32)
1397 if (s
!=1 && i
!=-1) return NULL
;/* no can do, in 16-bit EA */
1398 if (b
==-1 && i
!=-1) { int tmp
= b
; b
= i
; i
= tmp
; } /* swap */
1399 if ((b
==R_SI
|| b
==R_DI
) && i
!=-1)
1400 { int tmp
= b
; b
= i
; i
= tmp
; }
1401 /* have BX/BP as base, SI/DI index */
1402 if (b
==i
) return NULL
;/* shouldn't ever happen, in theory */
1403 if (i
!=-1 && b
!=-1 &&
1404 (i
==R_BP
|| i
==R_BX
|| b
==R_SI
|| b
==R_DI
))
1405 return NULL
; /* invalid combinations */
1406 if (b
==-1) /* pure offset: handled above */
1407 return NULL
; /* so if it gets to here, panic! */
1411 switch (i
*256 + b
) {
1412 case R_SI
*256+R_BX
: rm
=0; break;
1413 case R_DI
*256+R_BX
: rm
=1; break;
1414 case R_SI
*256+R_BP
: rm
=2; break;
1415 case R_DI
*256+R_BP
: rm
=3; break;
1419 case R_SI
: rm
=4; break;
1420 case R_DI
: rm
=5; break;
1421 case R_BP
: rm
=6; break;
1422 case R_BX
: rm
=7; break;
1424 if (rm
==-1) /* can't happen, in theory */
1425 return NULL
; /* so panic if it does */
1427 if (o
==0 && seg
==NO_SEG
&& !forw_ref
&& rm
!=6 &&
1428 !(input
->eaflags
& (EAF_BYTEOFFS
|EAF_WORDOFFS
)))
1430 else if (input
->eaflags
& EAF_BYTEOFFS
||
1431 (o
>=-128 && o
<=127 && seg
==NO_SEG
&& !forw_ref
&&
1432 !(input
->eaflags
& EAF_WORDOFFS
)))
1437 output
->sib_present
= FALSE
; /* no SIB - it's 16-bit */
1438 output
->bytes
= mod
; /* bytes of offset needed */
1439 output
->modrm
= (mod
<<6) | (rfield
<<3) | rm
;
1443 output
->size
= 1 + output
->sib_present
+ output
->bytes
;
1447 static int chsize (operand
*input
, int addrbits
)
1449 if (!(MEMORY
& ~input
->type
)) {
1450 int i
=input
->indexreg
, b
=input
->basereg
;
1452 if (input
->scale
==0) i
= -1;
1454 if (i
== -1 && b
== -1) /* pure offset */
1455 return (input
->addr_size
!= 0 && input
->addr_size
!= addrbits
);
1457 if (i
==R_EAX
|| i
==R_EBX
|| i
==R_ECX
|| i
==R_EDX
1458 || i
==R_EBP
|| i
==R_ESP
|| i
==R_ESI
|| i
==R_EDI
1459 || b
==R_EAX
|| b
==R_EBX
|| b
==R_ECX
|| b
==R_EDX
1460 || b
==R_EBP
|| b
==R_ESP
|| b
==R_ESI
|| b
==R_EDI
)
1461 return (addrbits
==16);
1463 return (addrbits
==32);