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 address-size override on the operand
32 * \70, \71, \72 - a long relative operand, from operand 0, 1 or 2
33 * \1ab - a ModRM, calculated on EA in operand a, with the spare
34 * field the register value of operand b.
35 * \130,\131,\132 - an immediate word or signed byte for operand 0, 1, or 2
36 * \133,\134,\135 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
37 * is a signed byte rather than a word.
38 * \140,\141,\142 - an immediate dword or signed byte for operand 0, 1, or 2
39 * \143,\144,\145 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
40 * is a signed byte rather than a dword.
41 * \2ab - a ModRM, calculated on EA in operand a, with the spare
42 * field equal to digit b.
43 * \30x - might be an 0x67 byte, depending on the address size of
44 * the memory reference in operand x.
45 * \310 - indicates fixed 16-bit address size, i.e. optional 0x67.
46 * \311 - indicates fixed 32-bit address size, i.e. optional 0x67.
47 * \312 - (disassembler only) marker on LOOP, LOOPxx instructions.
48 * \320 - indicates fixed 16-bit operand size, i.e. optional 0x66.
49 * \321 - indicates fixed 32-bit operand size, i.e. optional 0x66.
50 * \322 - indicates that this instruction is only valid when the
51 * operand size is the default (instruction to disassembler,
52 * generates no code in the assembler)
53 * \330 - a literal byte follows in the code stream, to be added
54 * to the condition code value of the instruction.
55 * \331 - instruction not valid with REP prefix. Hint for
56 * disassembler only; for SSE instructions.
57 * \332 - disassemble a rep (0xF3 byte) prefix as repe not rep.
58 * \333 - REP prefix (0xF3 byte); for SSE instructions. Not encoded
59 * as a literal byte in order to aid the disassembler.
60 * \340 - reserve <operand 0> bytes of uninitialised storage.
61 * Operand 0 had better be a segmentless constant.
62 * \370,\371,\372 - match only if operand 0, 1, 2 meets byte jump criteria.
63 * \373 - assemble 0x03 if bits==16, 0x05 if bits==32;
64 * used for conditional jump over longer jump
75 extern struct itemplate
*nasm_instructions
[];
78 int sib_present
; /* is a SIB byte necessary? */
79 int bytes
; /* # of bytes of offset needed */
80 int size
; /* lazy - this is sib+bytes+1 */
81 unsigned char modrm
, sib
; /* the bytes themselves */
84 static unsigned long cpu
; /* cpu level received from nasm.c */
86 static struct ofmt
*outfmt
;
89 static long calcsize (long, long, int, insn
*, char *);
90 static void gencode (long, long, int, insn
*, char *, long);
91 static int regval (operand
*o
);
92 static int matches (struct itemplate
*, insn
*);
93 static ea
* process_ea (operand
*, ea
*, int, int, int);
94 static int chsize (operand
*, int);
97 * This routine wrappers the real output format's output routine,
98 * in order to pass a copy of the data off to the listing file
99 * generator at the same time.
101 static void out (long offset
, long segto
, void *data
, unsigned long type
,
102 long segment
, long wrt
)
105 static char *lnfname
;
107 if ((type
& OUT_TYPMASK
) == OUT_ADDRESS
) {
108 if (segment
!= NO_SEG
|| wrt
!= NO_SEG
) {
110 * This address is relocated. We must write it as
111 * OUT_ADDRESS, so there's no work to be done here.
113 list
->output (offset
, data
, type
);
116 unsigned char p
[4], *q
= p
;
118 * This is a non-relocated address, and we're going to
119 * convert it into RAWDATA format.
121 if ((type
& OUT_SIZMASK
) == 4) {
122 WRITELONG (q
, * (long *) data
);
123 list
->output (offset
, p
, OUT_RAWDATA
+4);
126 WRITESHORT (q
, * (long *) data
);
127 list
->output (offset
, p
, OUT_RAWDATA
+2);
131 else if ((type
& OUT_TYPMASK
) == OUT_RAWDATA
) {
132 list
->output (offset
, data
, type
);
134 else if ((type
& OUT_TYPMASK
) == OUT_RESERVE
) {
135 list
->output (offset
, NULL
, type
);
137 else if ((type
& OUT_TYPMASK
) == OUT_REL2ADR
||
138 (type
& OUT_TYPMASK
) == OUT_REL4ADR
) {
139 list
->output (offset
, data
, type
);
142 if (src_get(&lineno
,&lnfname
))
143 outfmt
->current_dfmt
->linenum(lnfname
,lineno
,segto
);
145 outfmt
->output (segto
, data
, type
, segment
, wrt
);
148 static int jmp_match (long segment
, long offset
, int bits
,
149 insn
*ins
, char *code
)
151 unsigned char c
= code
[0];
154 if (c
!= 0370) return 0;
155 if (ins
->oprs
[0].opflags
& OPFLAG_FORWARD
) return (!pass0
); /* match a forward reference */
157 isize
= calcsize (segment
, offset
, bits
, ins
, code
);
158 if (ins
->oprs
[0].segment
!= segment
) return 0;
159 isize
= ins
->oprs
[0].offset
- offset
- isize
; /* isize is now the delta */
160 if (isize
>= -128L && isize
<= 127L) return 1; /* it is byte size */
166 long assemble (long segment
, long offset
, int bits
, unsigned long cp
,
167 insn
*instruction
, struct ofmt
*output
, efunc error
,
170 struct itemplate
*temp
;
176 long wsize
= 0; /* size for DB etc. */
178 errfunc
= error
; /* to pass to other functions */
180 outfmt
= output
; /* likewise */
181 list
= listgen
; /* and again */
183 switch (instruction
->opcode
)
186 case I_DB
: wsize
= 1; break;
187 case I_DW
: wsize
= 2; break;
188 case I_DD
: wsize
= 4; break;
189 case I_DQ
: wsize
= 8; break;
190 case I_DT
: wsize
= 10; break;
195 long t
= instruction
->times
;
197 errfunc(ERR_PANIC
, "instruction->times < 0 (%ld) in assemble()",t
);
199 while (t
--) /* repeat TIMES times */
201 for (e
= instruction
->eops
; e
; e
= e
->next
)
203 if (e
->type
== EOT_DB_NUMBER
)
206 if (e
->segment
!= NO_SEG
)
207 errfunc (ERR_NONFATAL
,
208 "one-byte relocation attempted");
210 unsigned char out_byte
= e
->offset
;
211 out (offset
, segment
, &out_byte
, OUT_RAWDATA
+1,
215 else if (wsize
> 5) {
216 errfunc (ERR_NONFATAL
, "integer supplied to a D%c"
217 " instruction", wsize
==8 ? 'Q' : 'T');
220 out (offset
, segment
, &e
->offset
,
221 OUT_ADDRESS
+wsize
, e
->segment
,
225 else if (e
->type
== EOT_DB_STRING
)
229 out (offset
, segment
, e
->stringval
,
230 OUT_RAWDATA
+e
->stringlen
, NO_SEG
, NO_SEG
);
231 align
= e
->stringlen
% wsize
;
234 align
= wsize
- align
;
235 out (offset
, segment
, "\0\0\0\0\0\0\0\0",
236 OUT_RAWDATA
+align
, NO_SEG
, NO_SEG
);
238 offset
+= e
->stringlen
+ align
;
241 if (t
> 0 && t
== instruction
->times
-1)
244 * Dummy call to list->output to give the offset to the
247 list
->output (offset
, NULL
, OUT_RAWDATA
);
248 list
->uplevel (LIST_TIMES
);
251 if (instruction
->times
> 1)
252 list
->downlevel (LIST_TIMES
);
253 return offset
- start
;
256 if (instruction
->opcode
== I_INCBIN
)
258 static char fname
[FILENAME_MAX
];
262 len
= FILENAME_MAX
-1;
263 if (len
> instruction
->eops
->stringlen
)
264 len
= instruction
->eops
->stringlen
;
265 strncpy (fname
, instruction
->eops
->stringval
, len
);
268 if ( (fp
= fopen(fname
, "rb")) == NULL
)
269 error (ERR_NONFATAL
, "`incbin': unable to open file `%s'", fname
);
270 else if (fseek(fp
, 0L, SEEK_END
) < 0)
271 error (ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
275 static char buf
[2048];
276 long t
= instruction
->times
;
280 if (instruction
->eops
->next
) {
281 base
= instruction
->eops
->next
->offset
;
283 if (instruction
->eops
->next
->next
&&
284 len
> instruction
->eops
->next
->next
->offset
)
285 len
= instruction
->eops
->next
->next
->offset
;
288 * Dummy call to list->output to give the offset to the
291 list
->output (offset
, NULL
, OUT_RAWDATA
);
292 list
->uplevel(LIST_INCBIN
);
297 fseek (fp
, base
, SEEK_SET
);
300 long m
= fread (buf
, 1, (l
>sizeof(buf
)?sizeof(buf
):l
),
304 * This shouldn't happen unless the file
305 * actually changes while we are reading
308 error (ERR_NONFATAL
, "`incbin': unexpected EOF while"
309 " reading file `%s'", fname
);
310 t
=0; /* Try to exit cleanly */
313 out (offset
, segment
, buf
, OUT_RAWDATA
+m
,
318 list
->downlevel(LIST_INCBIN
);
319 if (instruction
->times
> 1) {
321 * Dummy call to list->output to give the offset to the
324 list
->output (offset
, NULL
, OUT_RAWDATA
);
325 list
->uplevel(LIST_TIMES
);
326 list
->downlevel(LIST_TIMES
);
329 return instruction
->times
* len
;
331 return 0; /* if we're here, there's an error */
335 temp
= nasm_instructions
[instruction
->opcode
];
336 while (temp
->opcode
!= -1) {
337 int m
= matches (temp
, instruction
);
339 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
341 if (m
== 100) /* matches! */
343 char *codes
= temp
->code
;
344 long insn_size
= calcsize(segment
, offset
, bits
,
346 itimes
= instruction
->times
;
347 if (insn_size
< 0) /* shouldn't be, on pass two */
348 error (ERR_PANIC
, "errors made it through from pass one");
349 else while (itimes
--) {
350 insn_end
= offset
+ insn_size
;
351 for (j
=0; j
<instruction
->nprefix
; j
++) {
353 switch (instruction
->prefixes
[j
]) {
356 case P_REPNE
: case P_REPNZ
:
358 case P_REPE
: case P_REPZ
: case P_REP
:
360 case R_CS
: c
= 0x2E; break;
361 case R_DS
: c
= 0x3E; break;
362 case R_ES
: c
= 0x26; break;
363 case R_FS
: c
= 0x64; break;
364 case R_GS
: c
= 0x65; break;
365 case R_SS
: c
= 0x36; break;
384 "invalid instruction prefix");
387 out (offset
, segment
, &c
, OUT_RAWDATA
+1,
392 gencode (segment
, offset
, bits
, instruction
, codes
, insn_end
);
394 if (itimes
> 0 && itimes
== instruction
->times
-1) {
396 * Dummy call to list->output to give the offset to the
399 list
->output (offset
, NULL
, OUT_RAWDATA
);
400 list
->uplevel (LIST_TIMES
);
403 if (instruction
->times
> 1)
404 list
->downlevel (LIST_TIMES
);
405 return offset
- start
;
406 } else if (m
> 0 && m
> size_prob
) {
412 if (temp
->opcode
== -1) { /* didn't match any instruction */
413 if (size_prob
== 1) /* would have matched, but for size */
414 error (ERR_NONFATAL
, "operation size not specified");
415 else if (size_prob
== 2)
416 error (ERR_NONFATAL
, "mismatch in operand sizes");
417 else if (size_prob
== 3)
418 error (ERR_NONFATAL
, "no instruction for this cpu level");
421 "invalid combination of opcode and operands");
426 long insn_size (long segment
, long offset
, int bits
, unsigned long cp
,
427 insn
*instruction
, efunc error
)
429 struct itemplate
*temp
;
431 errfunc
= error
; /* to pass to other functions */
434 if (instruction
->opcode
== -1)
437 if (instruction
->opcode
== I_DB
||
438 instruction
->opcode
== I_DW
||
439 instruction
->opcode
== I_DD
||
440 instruction
->opcode
== I_DQ
||
441 instruction
->opcode
== I_DT
)
444 long isize
, osize
, wsize
= 0; /* placate gcc */
447 switch (instruction
->opcode
)
449 case I_DB
: wsize
= 1; break;
450 case I_DW
: wsize
= 2; break;
451 case I_DD
: wsize
= 4; break;
452 case I_DQ
: wsize
= 8; break;
453 case I_DT
: wsize
= 10; break;
456 for (e
= instruction
->eops
; e
; e
= e
->next
)
461 if (e
->type
== EOT_DB_NUMBER
)
463 else if (e
->type
== EOT_DB_STRING
)
464 osize
= e
->stringlen
;
466 align
= (-osize
) % wsize
;
469 isize
+= osize
+ align
;
471 return isize
* instruction
->times
;
474 if (instruction
->opcode
== I_INCBIN
)
476 char fname
[FILENAME_MAX
];
480 len
= FILENAME_MAX
-1;
481 if (len
> instruction
->eops
->stringlen
)
482 len
= instruction
->eops
->stringlen
;
483 strncpy (fname
, instruction
->eops
->stringval
, len
);
485 if ( (fp
= fopen(fname
, "rb")) == NULL
)
486 error (ERR_NONFATAL
, "`incbin': unable to open file `%s'", fname
);
487 else if (fseek(fp
, 0L, SEEK_END
) < 0)
488 error (ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
494 if (instruction
->eops
->next
)
496 len
-= instruction
->eops
->next
->offset
;
497 if (instruction
->eops
->next
->next
&&
498 len
> instruction
->eops
->next
->next
->offset
)
500 len
= instruction
->eops
->next
->next
->offset
;
503 return instruction
->times
* len
;
505 return 0; /* if we're here, there's an error */
508 temp
= nasm_instructions
[instruction
->opcode
];
509 while (temp
->opcode
!= -1) {
510 int m
= matches(temp
, instruction
);
512 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
515 /* we've matched an instruction. */
517 char * codes
= temp
->code
;
520 isize
= calcsize(segment
, offset
, bits
, instruction
, codes
);
523 for (j
= 0; j
< instruction
->nprefix
; j
++)
525 if ((instruction
->prefixes
[j
] != P_A16
&&
526 instruction
->prefixes
[j
] != P_O16
&& bits
==16) ||
527 (instruction
->prefixes
[j
] != P_A32
&&
528 instruction
->prefixes
[j
] != P_O32
&& bits
==32))
533 return isize
* instruction
->times
;
537 return -1; /* didn't match any instruction */
541 /* check that opn[op] is a signed byte of size 16 or 32,
542 and return the signed value*/
543 static int is_sbyte (insn
*ins
, int op
, int size
)
548 ret
= !(ins
->forw_ref
&& ins
->oprs
[op
].opflags
) && /* dead in the water on forward reference or External */
549 (optimizing
|| !(ins
->oprs
[op
].type
& (BITS16
|BITS32
))) &&
550 ins
->oprs
[op
].wrt
==NO_SEG
&& ins
->oprs
[op
].segment
==NO_SEG
;
552 v
= ins
->oprs
[op
].offset
;
553 if (size
==16) v
= (signed short)v
; /* sign extend if 16 bits */
555 return ret
&& v
>=-128L && v
<=127L;
558 static long calcsize (long segment
, long offset
, int bits
,
559 insn
*ins
, char *codes
)
564 (void) segment
; /* Don't warn that this parameter is unused */
565 (void) offset
; /* Don't warn that this parameter is unused */
567 while (*codes
) switch (c
= *codes
++) {
568 case 01: case 02: case 03:
569 codes
+= c
, length
+= c
; break;
570 case 04: case 05: case 06: case 07:
572 case 010: case 011: case 012:
573 codes
++, length
++; break;
576 case 014: case 015: case 016:
578 case 020: case 021: case 022:
580 case 024: case 025: case 026:
582 case 030: case 031: case 032:
584 case 034: case 035: case 036:
585 length
+= ((ins
->oprs
[c
-034].addr_size
?
586 ins
->oprs
[c
-034].addr_size
: bits
) == 16 ? 2 : 4); break;
589 case 040: case 041: case 042:
591 case 050: case 051: case 052:
593 case 060: case 061: case 062:
595 case 064: case 065: case 066:
596 length
+= ((ins
->oprs
[c
-064].addr_size
?
597 ins
->oprs
[c
-064].addr_size
: bits
) == 16 ? 2 : 4); break;
598 case 070: case 071: case 072:
600 case 0130: case 0131: case 0132:
601 length
+= is_sbyte(ins
, c
-0130, 16) ? 1 : 2; break;
602 case 0133: case 0134: case 0135:
603 codes
+=2; length
++; break;
604 case 0140: case 0141: case 0142:
605 length
+= is_sbyte(ins
, c
-0140, 32) ? 1 : 4; break;
606 case 0143: case 0144: case 0145:
607 codes
+=2; length
++; break;
608 case 0300: case 0301: case 0302:
609 length
+= chsize (&ins
->oprs
[c
-0300], bits
);
612 length
+= (bits
==32);
615 length
+= (bits
==16);
620 length
+= (bits
==32);
623 length
+= (bits
==16);
628 codes
++, length
++; break;
634 case 0340: case 0341: case 0342:
635 if (ins
->oprs
[0].segment
!= NO_SEG
)
636 errfunc (ERR_NONFATAL
, "attempt to reserve non-constant"
637 " quantity of BSS space");
639 length
+= ins
->oprs
[0].offset
<< (c
-0340);
641 case 0370: case 0371: case 0372:
645 default: /* can't do it by 'case' statements */
646 if (c
>=0100 && c
<=0277) { /* it's an EA */
648 if (!process_ea (&ins
->oprs
[(c
>>3)&7], &ea_data
, bits
, 0,
650 errfunc (ERR_NONFATAL
, "invalid effective address");
653 length
+= ea_data
.size
;
655 errfunc (ERR_PANIC
, "internal instruction table corrupt"
656 ": instruction code 0x%02X given", c
);
661 static void gencode (long segment
, long offset
, int bits
,
662 insn
*ins
, char *codes
, long insn_end
)
664 static char condval
[] = { /* conditional opcodes */
665 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
666 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
667 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
670 unsigned char bytes
[4];
674 switch (c
= *codes
++)
676 case 01: case 02: case 03:
677 out (offset
, segment
, codes
, OUT_RAWDATA
+c
, NO_SEG
, NO_SEG
);
683 switch (ins
->oprs
[0].basereg
)
686 bytes
[0] = 0x0E + (c
== 0x04 ? 1 : 0); break;
688 bytes
[0] = 0x1E + (c
== 0x04 ? 1 : 0); break;
690 bytes
[0] = 0x06 + (c
== 0x04 ? 1 : 0); break;
692 bytes
[0] = 0x16 + (c
== 0x04 ? 1 : 0); break;
694 errfunc (ERR_PANIC
, "bizarre 8086 segment register received");
696 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
701 switch (ins
->oprs
[0].basereg
) {
702 case R_FS
: bytes
[0] = 0xA0 + (c
== 0x05 ? 1 : 0); break;
703 case R_GS
: bytes
[0] = 0xA8 + (c
== 0x05 ? 1 : 0); break;
705 errfunc (ERR_PANIC
, "bizarre 386 segment register received");
707 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
711 case 010: case 011: case 012:
712 bytes
[0] = *codes
++ + regval(&ins
->oprs
[c
-010]);
713 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
719 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
723 case 014: case 015: case 016:
724 if (ins
->oprs
[c
-014].offset
< -128
725 || ins
->oprs
[c
-014].offset
> 127)
727 errfunc (ERR_WARNING
, "signed byte value exceeds bounds");
730 if (ins
->oprs
[c
-014].segment
!= NO_SEG
)
732 data
= ins
->oprs
[c
-014].offset
;
733 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
734 ins
->oprs
[c
-014].segment
, ins
->oprs
[c
-014].wrt
);
737 bytes
[0] = ins
->oprs
[c
-014].offset
;
738 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
743 case 020: case 021: case 022:
744 if (ins
->oprs
[c
-020].offset
< -256
745 || ins
->oprs
[c
-020].offset
> 255)
747 errfunc (ERR_WARNING
, "byte value exceeds bounds");
749 if (ins
->oprs
[c
-020].segment
!= NO_SEG
) {
750 data
= ins
->oprs
[c
-020].offset
;
751 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
752 ins
->oprs
[c
-020].segment
, ins
->oprs
[c
-020].wrt
);
755 bytes
[0] = ins
->oprs
[c
-020].offset
;
756 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
761 case 024: case 025: case 026:
762 if (ins
->oprs
[c
-024].offset
< 0 || ins
->oprs
[c
-024].offset
> 255)
763 errfunc (ERR_WARNING
, "unsigned byte value exceeds bounds");
764 if (ins
->oprs
[c
-024].segment
!= NO_SEG
) {
765 data
= ins
->oprs
[c
-024].offset
;
766 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
767 ins
->oprs
[c
-024].segment
, ins
->oprs
[c
-024].wrt
);
770 bytes
[0] = ins
->oprs
[c
-024].offset
;
771 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
776 case 030: case 031: case 032:
777 if (ins
->oprs
[c
-030].segment
== NO_SEG
&&
778 ins
->oprs
[c
-030].wrt
== NO_SEG
&&
779 (ins
->oprs
[c
-030].offset
< -65536L ||
780 ins
->oprs
[c
-030].offset
> 65535L))
782 errfunc (ERR_WARNING
, "word value exceeds bounds");
784 data
= ins
->oprs
[c
-030].offset
;
785 out (offset
, segment
, &data
, OUT_ADDRESS
+2,
786 ins
->oprs
[c
-030].segment
, ins
->oprs
[c
-030].wrt
);
790 case 034: case 035: case 036:
791 data
= ins
->oprs
[c
-034].offset
;
792 size
= ((ins
->oprs
[c
-034].addr_size
?
793 ins
->oprs
[c
-034].addr_size
: bits
) == 16 ? 2 : 4);
794 if (size
==2 && (data
< -65536L || data
> 65535L))
795 errfunc (ERR_WARNING
, "word value exceeds bounds");
796 out (offset
, segment
, &data
, OUT_ADDRESS
+size
,
797 ins
->oprs
[c
-034].segment
, ins
->oprs
[c
-034].wrt
);
802 if (ins
->oprs
[0].segment
== NO_SEG
)
803 errfunc (ERR_NONFATAL
, "value referenced by FAR is not"
806 out (offset
, segment
, &data
, OUT_ADDRESS
+2,
807 outfmt
->segbase(1+ins
->oprs
[0].segment
),
812 case 040: case 041: case 042:
813 data
= ins
->oprs
[c
-040].offset
;
814 out (offset
, segment
, &data
, OUT_ADDRESS
+4,
815 ins
->oprs
[c
-040].segment
, ins
->oprs
[c
-040].wrt
);
819 case 050: case 051: case 052:
820 if (ins
->oprs
[c
-050].segment
!= segment
)
821 errfunc (ERR_NONFATAL
, "short relative jump outside segment");
822 data
= ins
->oprs
[c
-050].offset
- insn_end
;
823 if (data
> 127 || data
< -128)
824 errfunc (ERR_NONFATAL
, "short jump is out of range");
826 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
830 case 060: case 061: case 062:
831 if (ins
->oprs
[c
-060].segment
!= segment
) {
832 data
= ins
->oprs
[c
-060].offset
;
833 out (offset
, segment
, &data
, OUT_REL2ADR
+insn_end
-offset
,
834 ins
->oprs
[c
-060].segment
, ins
->oprs
[c
-060].wrt
);
836 data
= ins
->oprs
[c
-060].offset
- insn_end
;
837 out (offset
, segment
, &data
,
838 OUT_ADDRESS
+2, NO_SEG
, NO_SEG
);
843 case 064: case 065: case 066:
844 size
= ((ins
->oprs
[c
-064].addr_size
?
845 ins
->oprs
[c
-064].addr_size
: bits
) == 16 ? 2 : 4);
846 if (ins
->oprs
[c
-064].segment
!= segment
) {
847 data
= ins
->oprs
[c
-064].offset
;
848 size
= (bits
== 16 ? OUT_REL2ADR
: OUT_REL4ADR
);
849 out (offset
, segment
, &data
, size
+insn_end
-offset
,
850 ins
->oprs
[c
-064].segment
, ins
->oprs
[c
-064].wrt
);
851 size
= (bits
== 16 ? 2 : 4);
853 data
= ins
->oprs
[c
-064].offset
- insn_end
;
854 out (offset
, segment
, &data
,
855 OUT_ADDRESS
+size
, NO_SEG
, NO_SEG
);
860 case 070: case 071: case 072:
861 if (ins
->oprs
[c
-070].segment
!= segment
) {
862 data
= ins
->oprs
[c
-070].offset
;
863 out (offset
, segment
, &data
, OUT_REL4ADR
+insn_end
-offset
,
864 ins
->oprs
[c
-070].segment
, ins
->oprs
[c
-070].wrt
);
866 data
= ins
->oprs
[c
-070].offset
- insn_end
;
867 out (offset
, segment
, &data
,
868 OUT_ADDRESS
+4, NO_SEG
, NO_SEG
);
873 case 0130: case 0131: case 0132:
874 data
= ins
->oprs
[c
-0130].offset
;
875 if (is_sbyte(ins
, c
-0130, 16)) {
876 out (offset
, segment
, &data
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
879 if (ins
->oprs
[c
-0130].segment
== NO_SEG
&&
880 ins
->oprs
[c
-0130].wrt
== NO_SEG
&&
881 (data
< -65536L || data
> 65535L)) {
882 errfunc (ERR_WARNING
, "word value exceeds bounds");
884 out (offset
, segment
, &data
, OUT_ADDRESS
+2,
885 ins
->oprs
[c
-0130].segment
, ins
->oprs
[c
-0130].wrt
);
890 case 0133: case 0134: case 0135:
893 if (is_sbyte(ins
, c
-0133, 16)) bytes
[0] |= 2; /* s-bit */
894 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
898 case 0140: case 0141: case 0142:
899 data
= ins
->oprs
[c
-0140].offset
;
900 if (is_sbyte(ins
, c
-0140, 32)) {
901 out (offset
, segment
, &data
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
904 out (offset
, segment
, &data
, OUT_ADDRESS
+4,
905 ins
->oprs
[c
-0140].segment
, ins
->oprs
[c
-0140].wrt
);
910 case 0143: case 0144: case 0145:
913 if (is_sbyte(ins
, c
-0143, 32)) bytes
[0] |= 2; /* s-bit */
914 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
918 case 0300: case 0301: case 0302:
919 if (chsize (&ins
->oprs
[c
-0300], bits
)) {
921 out (offset
, segment
, bytes
,
922 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
931 out (offset
, segment
, bytes
,
932 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
941 out (offset
, segment
, bytes
,
942 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
954 out (offset
, segment
, bytes
,
955 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
964 out (offset
, segment
, bytes
,
965 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
975 *bytes
= *codes
++ ^ condval
[ins
->condition
];
976 out (offset
, segment
, bytes
,
977 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
987 out (offset
, segment
, bytes
,
988 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
992 case 0340: case 0341: case 0342:
993 if (ins
->oprs
[0].segment
!= NO_SEG
)
994 errfunc (ERR_PANIC
, "non-constant BSS size in pass two");
996 long size
= ins
->oprs
[0].offset
<< (c
-0340);
998 out (offset
, segment
, NULL
,
999 OUT_RESERVE
+size
, NO_SEG
, NO_SEG
);
1004 case 0370: case 0371: case 0372:
1008 *bytes
= bits
==16 ? 3 : 5;
1009 out (offset
, segment
, bytes
,
1010 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1014 default: /* can't do it by 'case' statements */
1015 if (c
>=0100 && c
<=0277) { /* it's an EA */
1021 if (c
<=0177) /* pick rfield from operand b */
1022 rfield
= regval (&ins
->oprs
[c
&7]);
1023 else /* rfield is constant */
1026 if (!process_ea (&ins
->oprs
[(c
>>3)&7], &ea_data
, bits
, rfield
,
1029 errfunc (ERR_NONFATAL
, "invalid effective address");
1033 *p
++ = ea_data
.modrm
;
1034 if (ea_data
.sib_present
)
1038 out (offset
, segment
, bytes
, OUT_RAWDATA
+ s
,
1041 switch (ea_data
.bytes
) {
1045 if (ins
->oprs
[(c
>>3)&7].segment
!= NO_SEG
) {
1046 data
= ins
->oprs
[(c
>>3)&7].offset
;
1047 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
1048 ins
->oprs
[(c
>>3)&7].segment
,
1049 ins
->oprs
[(c
>>3)&7].wrt
);
1051 *bytes
= ins
->oprs
[(c
>>3)&7].offset
;
1052 out (offset
, segment
, bytes
, OUT_RAWDATA
+1,
1059 data
= ins
->oprs
[(c
>>3)&7].offset
;
1060 out (offset
, segment
, &data
,
1061 OUT_ADDRESS
+ea_data
.bytes
,
1062 ins
->oprs
[(c
>>3)&7].segment
, ins
->oprs
[(c
>>3)&7].wrt
);
1068 errfunc (ERR_PANIC
, "internal instruction table corrupt"
1069 ": instruction code 0x%02X given", c
);
1073 static int regval (operand
*o
)
1075 switch (o
->basereg
) {
1076 case R_EAX
: case R_AX
: case R_AL
: case R_ES
: case R_CR0
: case R_DR0
:
1077 case R_ST0
: case R_MM0
: case R_XMM0
:
1079 case R_ECX
: case R_CX
: case R_CL
: case R_CS
: case R_DR1
: case R_ST1
:
1080 case R_MM1
: case R_XMM1
:
1082 case R_EDX
: case R_DX
: case R_DL
: case R_SS
: case R_CR2
: case R_DR2
:
1083 case R_ST2
: case R_MM2
: case R_XMM2
:
1085 case R_EBX
: case R_BX
: case R_BL
: case R_DS
: case R_CR3
: case R_DR3
:
1086 case R_TR3
: case R_ST3
: case R_MM3
: case R_XMM3
:
1088 case R_ESP
: case R_SP
: case R_AH
: case R_FS
: case R_CR4
: case R_TR4
:
1089 case R_ST4
: case R_MM4
: case R_XMM4
:
1091 case R_EBP
: case R_BP
: case R_CH
: case R_GS
: case R_TR5
: case R_ST5
:
1092 case R_MM5
: case R_XMM5
:
1094 case R_ESI
: case R_SI
: case R_DH
: case R_DR6
: case R_TR6
: case R_ST6
:
1095 case R_MM6
: case R_XMM6
:
1097 case R_EDI
: case R_DI
: case R_BH
: case R_DR7
: case R_TR7
: case R_ST7
:
1098 case R_MM7
: case R_XMM7
:
1100 default: /* panic */
1101 errfunc (ERR_PANIC
, "invalid register operand given to regval()");
1106 static int matches (struct itemplate
*itemp
, insn
*instruction
)
1108 int i
, size
[3], asize
, oprs
, ret
;
1115 if (itemp
->opcode
!= instruction
->opcode
) return 0;
1118 * Count the operands
1120 if (itemp
->operands
!= instruction
->operands
) return 0;
1123 * Check that no spurious colons or TOs are present
1125 for (i
=0; i
<itemp
->operands
; i
++)
1126 if (instruction
->oprs
[i
].type
& ~itemp
->opd
[i
] & (COLON
|TO
))
1130 * Check that the operand flags all match up
1132 for (i
=0; i
<itemp
->operands
; i
++)
1133 if (itemp
->opd
[i
] & ~instruction
->oprs
[i
].type
||
1134 ((itemp
->opd
[i
] & SIZE_MASK
) &&
1135 ((itemp
->opd
[i
] ^ instruction
->oprs
[i
].type
) & SIZE_MASK
)))
1137 if ((itemp
->opd
[i
] & ~instruction
->oprs
[i
].type
& NON_SIZE
) ||
1138 (instruction
->oprs
[i
].type
& SIZE_MASK
))
1146 * Check operand sizes
1148 if (itemp
->flags
& IF_ARMASK
) {
1149 size
[0] = size
[1] = size
[2] = 0;
1151 switch (itemp
->flags
& IF_ARMASK
) {
1152 case IF_AR0
: i
= 0; break;
1153 case IF_AR1
: i
= 1; break;
1154 case IF_AR2
: i
= 2; break;
1155 default: break; /* Shouldn't happen */
1157 if (itemp
->flags
& IF_SB
) {
1159 } else if (itemp
->flags
& IF_SW
) {
1161 } else if (itemp
->flags
& IF_SD
) {
1166 if (itemp
->flags
& IF_SB
) {
1168 oprs
= itemp
->operands
;
1169 } else if (itemp
->flags
& IF_SW
) {
1171 oprs
= itemp
->operands
;
1172 } else if (itemp
->flags
& IF_SD
) {
1174 oprs
= itemp
->operands
;
1176 size
[0] = size
[1] = size
[2] = asize
;
1179 if (itemp
->flags
& (IF_SM
| IF_SM2
)) {
1180 oprs
= (itemp
->flags
& IF_SM2
? 2 : itemp
->operands
);
1182 for (i
=0; i
<oprs
; i
++) {
1183 if ( (asize
= itemp
->opd
[i
] & SIZE_MASK
) != 0) {
1185 for (j
=0; j
<oprs
; j
++)
1191 oprs
= itemp
->operands
;
1194 for (i
=0; i
<itemp
->operands
; i
++)
1195 if (!(itemp
->opd
[i
] & SIZE_MASK
) &&
1196 (instruction
->oprs
[i
].type
& SIZE_MASK
& ~size
[i
]))
1201 * Check template is okay at the set cpu level
1203 if ((itemp
->flags
& IF_PLEVEL
) > cpu
) return 3;
1206 * Check if special handling needed for Jumps
1208 if ((unsigned char)(itemp
->code
[0]) >= 0370) return 99;
1213 static ea
*process_ea (operand
*input
, ea
*output
, int addrbits
, int rfield
,
1216 if (!(REGISTER
& ~input
->type
)) { /* it's a single register */
1217 static int regs
[] = {
1218 R_AL
, R_CL
, R_DL
, R_BL
, R_AH
, R_CH
, R_DH
, R_BH
,
1219 R_AX
, R_CX
, R_DX
, R_BX
, R_SP
, R_BP
, R_SI
, R_DI
,
1220 R_EAX
, R_ECX
, R_EDX
, R_EBX
, R_ESP
, R_EBP
, R_ESI
, R_EDI
,
1221 R_MM0
, R_MM1
, R_MM2
, R_MM3
, R_MM4
, R_MM5
, R_MM6
, R_MM7
,
1222 R_XMM0
, R_XMM1
, R_XMM2
, R_XMM3
, R_XMM4
, R_XMM5
, R_XMM6
, R_XMM7
1226 for (i
=0; i
<elements(regs
); i
++)
1227 if (input
->basereg
== regs
[i
]) break;
1228 if (i
<elements(regs
)) {
1229 output
->sib_present
= FALSE
;/* no SIB necessary */
1230 output
->bytes
= 0; /* no offset necessary either */
1231 output
->modrm
= 0xC0 | (rfield
<< 3) | (i
& 7);
1235 } else { /* it's a memory reference */
1236 if (input
->basereg
==-1 && (input
->indexreg
==-1 || input
->scale
==0)) {
1237 /* it's a pure offset */
1238 if (input
->addr_size
)
1239 addrbits
= input
->addr_size
;
1240 output
->sib_present
= FALSE
;
1241 output
->bytes
= (addrbits
==32 ? 4 : 2);
1242 output
->modrm
= (addrbits
==32 ? 5 : 6) | (rfield
<< 3);
1244 else { /* it's an indirection */
1245 int i
=input
->indexreg
, b
=input
->basereg
, s
=input
->scale
;
1246 long o
=input
->offset
, seg
=input
->segment
;
1247 int hb
=input
->hintbase
, ht
=input
->hinttype
;
1250 if (s
==0) i
= -1; /* make this easy, at least */
1252 if (i
==R_EAX
|| i
==R_EBX
|| i
==R_ECX
|| i
==R_EDX
1253 || i
==R_EBP
|| i
==R_ESP
|| i
==R_ESI
|| i
==R_EDI
1254 || b
==R_EAX
|| b
==R_EBX
|| b
==R_ECX
|| b
==R_EDX
1255 || b
==R_EBP
|| b
==R_ESP
|| b
==R_ESI
|| b
==R_EDI
) {
1256 /* it must be a 32-bit memory reference. Firstly we have
1257 * to check that all registers involved are type Exx. */
1258 if (i
!=-1 && i
!=R_EAX
&& i
!=R_EBX
&& i
!=R_ECX
&& i
!=R_EDX
1259 && i
!=R_EBP
&& i
!=R_ESP
&& i
!=R_ESI
&& i
!=R_EDI
)
1261 if (b
!=-1 && b
!=R_EAX
&& b
!=R_EBX
&& b
!=R_ECX
&& b
!=R_EDX
1262 && b
!=R_EBP
&& b
!=R_ESP
&& b
!=R_ESI
&& b
!=R_EDI
)
1265 /* While we're here, ensure the user didn't specify WORD. */
1266 if (input
->addr_size
== 16)
1269 /* now reorganise base/index */
1270 if (s
== 1 && b
!= i
&& b
!= -1 && i
!= -1 &&
1271 ((hb
==b
&&ht
==EAH_NOTBASE
) || (hb
==i
&&ht
==EAH_MAKEBASE
)))
1272 t
= b
, b
= i
, i
= t
; /* swap if hints say so */
1273 if (b
==i
) /* convert EAX+2*EAX to 3*EAX */
1275 if (b
==-1 && s
==1 && !(hb
== i
&& ht
== EAH_NOTBASE
))
1276 b
= i
, i
= -1; /* make single reg base, unless hint */
1277 if (((s
==2 && i
!=R_ESP
&& !(input
->eaflags
& EAF_TIMESTWO
)) ||
1278 s
==3 || s
==5 || s
==9) && b
==-1)
1279 b
= i
, s
--; /* convert 3*EAX to EAX+2*EAX */
1280 if (s
==1 && i
==R_ESP
) /* swap ESP into base if scale is 1 */
1282 if (i
==R_ESP
|| (s
!=1 && s
!=2 && s
!=4 && s
!=8 && i
!=-1))
1283 return NULL
; /* wrong, for various reasons */
1285 if (i
==-1 && b
!=R_ESP
) {/* no SIB needed */
1288 case R_EAX
: rm
= 0; break;
1289 case R_ECX
: rm
= 1; break;
1290 case R_EDX
: rm
= 2; break;
1291 case R_EBX
: rm
= 3; break;
1292 case R_EBP
: rm
= 5; break;
1293 case R_ESI
: rm
= 6; break;
1294 case R_EDI
: rm
= 7; break;
1295 case -1: rm
= 5; break;
1296 default: /* should never happen */
1299 if (b
==-1 || (b
!=R_EBP
&& o
==0 &&
1300 seg
==NO_SEG
&& !forw_ref
&&
1302 (EAF_BYTEOFFS
|EAF_WORDOFFS
))))
1304 else if (input
->eaflags
& EAF_BYTEOFFS
||
1305 (o
>=-128 && o
<=127 && seg
==NO_SEG
&& !forw_ref
&&
1306 !(input
->eaflags
& EAF_WORDOFFS
))) {
1312 output
->sib_present
= FALSE
;
1313 output
->bytes
= (b
==-1 || mod
==2 ? 4 : mod
);
1314 output
->modrm
= (mod
<<6) | (rfield
<<3) | rm
;
1316 else { /* we need a SIB */
1317 int mod
, scale
, index
, base
;
1320 case R_EAX
: base
= 0; break;
1321 case R_ECX
: base
= 1; break;
1322 case R_EDX
: base
= 2; break;
1323 case R_EBX
: base
= 3; break;
1324 case R_ESP
: base
= 4; break;
1325 case R_EBP
: case -1: base
= 5; break;
1326 case R_ESI
: base
= 6; break;
1327 case R_EDI
: base
= 7; break;
1328 default: /* then what the smeg is it? */
1329 return NULL
; /* panic */
1333 case R_EAX
: index
= 0; break;
1334 case R_ECX
: index
= 1; break;
1335 case R_EDX
: index
= 2; break;
1336 case R_EBX
: index
= 3; break;
1337 case -1: index
= 4; break;
1338 case R_EBP
: index
= 5; break;
1339 case R_ESI
: index
= 6; break;
1340 case R_EDI
: index
= 7; break;
1341 default: /* then what the smeg is it? */
1342 return NULL
; /* panic */
1347 case 1: scale
= 0; break;
1348 case 2: scale
= 1; break;
1349 case 4: scale
= 2; break;
1350 case 8: scale
= 3; break;
1351 default: /* then what the smeg is it? */
1352 return NULL
; /* panic */
1355 if (b
==-1 || (b
!=R_EBP
&& o
==0 &&
1356 seg
==NO_SEG
&& !forw_ref
&&
1358 (EAF_BYTEOFFS
|EAF_WORDOFFS
))))
1360 else if (input
->eaflags
& EAF_BYTEOFFS
||
1361 (o
>=-128 && o
<=127 && seg
==NO_SEG
&& !forw_ref
&&
1362 !(input
->eaflags
& EAF_WORDOFFS
)))
1367 output
->sib_present
= TRUE
;
1368 output
->bytes
= (b
==-1 || mod
==2 ? 4 : mod
);
1369 output
->modrm
= (mod
<<6) | (rfield
<<3) | 4;
1370 output
->sib
= (scale
<<6) | (index
<<3) | base
;
1373 else { /* it's 16-bit */
1376 /* check all registers are BX, BP, SI or DI */
1377 if ((b
!=-1 && b
!=R_BP
&& b
!=R_BX
&& b
!=R_SI
&& b
!=R_DI
) ||
1378 (i
!=-1 && i
!=R_BP
&& i
!=R_BX
&& i
!=R_SI
&& i
!=R_DI
))
1381 /* ensure the user didn't specify DWORD */
1382 if (input
->addr_size
== 32)
1385 if (s
!=1 && i
!=-1) return NULL
;/* no can do, in 16-bit EA */
1386 if (b
==-1 && i
!=-1) b
^= i
^= b
^= i
; /* swap them round */
1387 if ((b
==R_SI
|| b
==R_DI
) && i
!=-1)
1388 b
^= i
^= b
^= i
; /* have BX/BP as base, SI/DI index */
1389 if (b
==i
) return NULL
;/* shouldn't ever happen, in theory */
1390 if (i
!=-1 && b
!=-1 &&
1391 (i
==R_BP
|| i
==R_BX
|| b
==R_SI
|| b
==R_DI
))
1392 return NULL
; /* invalid combinations */
1393 if (b
==-1) /* pure offset: handled above */
1394 return NULL
; /* so if it gets to here, panic! */
1398 switch (i
*256 + b
) {
1399 case R_SI
*256+R_BX
: rm
=0; break;
1400 case R_DI
*256+R_BX
: rm
=1; break;
1401 case R_SI
*256+R_BP
: rm
=2; break;
1402 case R_DI
*256+R_BP
: rm
=3; break;
1406 case R_SI
: rm
=4; break;
1407 case R_DI
: rm
=5; break;
1408 case R_BP
: rm
=6; break;
1409 case R_BX
: rm
=7; break;
1411 if (rm
==-1) /* can't happen, in theory */
1412 return NULL
; /* so panic if it does */
1414 if (o
==0 && seg
==NO_SEG
&& !forw_ref
&& rm
!=6 &&
1415 !(input
->eaflags
& (EAF_BYTEOFFS
|EAF_WORDOFFS
)))
1417 else if (input
->eaflags
& EAF_BYTEOFFS
||
1418 (o
>=-128 && o
<=127 && seg
==NO_SEG
&& !forw_ref
&&
1419 !(input
->eaflags
& EAF_WORDOFFS
)))
1424 output
->sib_present
= FALSE
; /* no SIB - it's 16-bit */
1425 output
->bytes
= mod
; /* bytes of offset needed */
1426 output
->modrm
= (mod
<<6) | (rfield
<<3) | rm
;
1430 output
->size
= 1 + output
->sib_present
+ output
->bytes
;
1434 static int chsize (operand
*input
, int addrbits
)
1436 if (!(MEMORY
& ~input
->type
)) {
1437 int i
=input
->indexreg
, b
=input
->basereg
;
1439 if (input
->scale
==0) i
= -1;
1441 if (i
== -1 && b
== -1) /* pure offset */
1442 return (input
->addr_size
!= 0 && input
->addr_size
!= addrbits
);
1444 if (i
==R_EAX
|| i
==R_EBX
|| i
==R_ECX
|| i
==R_EDX
1445 || i
==R_EBP
|| i
==R_ESP
|| i
==R_ESI
|| i
==R_EDI
1446 || b
==R_EAX
|| b
==R_EBX
|| b
==R_ECX
|| b
==R_EDX
1447 || b
==R_EBP
|| b
==R_ESP
|| b
==R_ESI
|| b
==R_EDI
)
1448 return (addrbits
==16);
1450 return (addrbits
==32);