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
79 extern struct itemplate
*nasm_instructions
[];
82 int sib_present
; /* is a SIB byte necessary? */
83 int bytes
; /* # of bytes of offset needed */
84 int size
; /* lazy - this is sib+bytes+1 */
85 unsigned char modrm
, sib
; /* the bytes themselves */
88 static unsigned long cpu
; /* cpu level received from nasm.c */
90 static struct ofmt
*outfmt
;
93 static long calcsize (long, long, int, insn
*, const char *);
94 static void gencode (long, long, int, insn
*, const char *, long);
95 static int regval (operand
*o
);
96 static int matches (struct itemplate
*, insn
*);
97 static ea
* process_ea (operand
*, ea
*, int, int, int);
98 static int chsize (operand
*, int);
101 * This routine wrappers the real output format's output routine,
102 * in order to pass a copy of the data off to the listing file
103 * generator at the same time.
105 static void out (long offset
, long segto
, const void *data
, unsigned long type
,
106 long segment
, long wrt
)
109 char *lnfname
= NULL
;
111 if ((type
& OUT_TYPMASK
) == OUT_ADDRESS
) {
112 if (segment
!= NO_SEG
|| wrt
!= NO_SEG
) {
114 * This address is relocated. We must write it as
115 * OUT_ADDRESS, so there's no work to be done here.
117 list
->output (offset
, data
, type
);
120 unsigned char p
[4], *q
= p
;
122 * This is a non-relocated address, and we're going to
123 * convert it into RAWDATA format.
125 if ((type
& OUT_SIZMASK
) == 4) {
126 WRITELONG (q
, * (long *) data
);
127 list
->output (offset
, p
, OUT_RAWDATA
+4);
130 WRITESHORT (q
, * (long *) data
);
131 list
->output (offset
, p
, OUT_RAWDATA
+2);
135 else if ((type
& OUT_TYPMASK
) == OUT_RAWDATA
) {
136 list
->output (offset
, data
, type
);
138 else if ((type
& OUT_TYPMASK
) == OUT_RESERVE
) {
139 list
->output (offset
, NULL
, type
);
141 else if ((type
& OUT_TYPMASK
) == OUT_REL2ADR
||
142 (type
& OUT_TYPMASK
) == OUT_REL4ADR
) {
143 list
->output (offset
, data
, type
);
146 if (src_get(&lineno
,&lnfname
))
148 outfmt
->current_dfmt
->linenum(lnfname
,lineno
,segto
);
149 if (lnfname
) nasm_free(lnfname
);
152 outfmt
->output (segto
, data
, type
, segment
, wrt
);
155 static int jmp_match (long segment
, long offset
, int bits
,
156 insn
*ins
, const char *code
)
158 unsigned char c
= code
[0];
161 if (c
!= 0370 && c
!= 0371) return 0;
162 if (ins
->oprs
[0].opflags
& OPFLAG_FORWARD
) {
163 if ((optimizing
<0 || (ins
->oprs
[0].type
& STRICT
))
164 && c
==0370) return 1;
165 else return (pass0
==0); /* match a forward reference */
167 isize
= calcsize (segment
, offset
, bits
, ins
, code
);
168 if (ins
->oprs
[0].segment
!= segment
) return 0;
169 isize
= ins
->oprs
[0].offset
- offset
- isize
; /* isize is now the delta */
170 if (isize
>= -128L && isize
<= 127L) return 1; /* it is byte size */
176 long assemble (long segment
, long offset
, int bits
, unsigned long cp
,
177 insn
*instruction
, struct ofmt
*output
, efunc error
,
180 struct itemplate
*temp
;
186 long wsize
= 0; /* size for DB etc. */
188 errfunc
= error
; /* to pass to other functions */
190 outfmt
= output
; /* likewise */
191 list
= listgen
; /* and again */
193 switch (instruction
->opcode
)
196 case I_DB
: wsize
= 1; break;
197 case I_DW
: wsize
= 2; break;
198 case I_DD
: wsize
= 4; break;
199 case I_DQ
: wsize
= 8; break;
200 case I_DT
: wsize
= 10; break;
205 long t
= instruction
->times
;
207 errfunc(ERR_PANIC
, "instruction->times < 0 (%ld) in assemble()",t
);
209 while (t
--) /* repeat TIMES times */
211 for (e
= instruction
->eops
; e
; e
= e
->next
)
213 if (e
->type
== EOT_DB_NUMBER
)
216 if (e
->segment
!= NO_SEG
)
217 errfunc (ERR_NONFATAL
,
218 "one-byte relocation attempted");
220 unsigned char out_byte
= e
->offset
;
221 out (offset
, segment
, &out_byte
, OUT_RAWDATA
+1,
225 else if (wsize
> 5) {
226 errfunc (ERR_NONFATAL
, "integer supplied to a D%c"
227 " instruction", wsize
==8 ? 'Q' : 'T');
230 out (offset
, segment
, &e
->offset
,
231 OUT_ADDRESS
+wsize
, e
->segment
,
235 else if (e
->type
== EOT_DB_STRING
)
239 out (offset
, segment
, e
->stringval
,
240 OUT_RAWDATA
+e
->stringlen
, NO_SEG
, NO_SEG
);
241 align
= e
->stringlen
% wsize
;
244 align
= wsize
- align
;
245 out (offset
, segment
, "\0\0\0\0\0\0\0\0",
246 OUT_RAWDATA
+align
, NO_SEG
, NO_SEG
);
248 offset
+= e
->stringlen
+ align
;
251 if (t
> 0 && t
== instruction
->times
-1)
254 * Dummy call to list->output to give the offset to the
257 list
->output (offset
, NULL
, OUT_RAWDATA
);
258 list
->uplevel (LIST_TIMES
);
261 if (instruction
->times
> 1)
262 list
->downlevel (LIST_TIMES
);
263 return offset
- start
;
266 if (instruction
->opcode
== I_INCBIN
)
268 static char fname
[FILENAME_MAX
];
271 char *prefix
= "", *combine
;
272 char** pPrevPath
= NULL
;
274 len
= FILENAME_MAX
-1;
275 if (len
> instruction
->eops
->stringlen
)
276 len
= instruction
->eops
->stringlen
;
277 strncpy (fname
, instruction
->eops
->stringval
, len
);
280 while (1) /* added by alexfru: 'incbin' uses include paths */
282 combine
= nasm_malloc(strlen(prefix
) + len
+ 1);
283 strcpy(combine
, prefix
);
284 strcat(combine
, fname
);
286 if ( (fp
= fopen(combine
, "rb")) != NULL
)
293 pPrevPath
= pp_get_include_path_ptr (pPrevPath
);
294 if (pPrevPath
== NULL
)
300 error (ERR_NONFATAL
, "`incbin': unable to open file `%s'", fname
);
301 else if (fseek(fp
, 0L, SEEK_END
) < 0)
302 error (ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
306 static char buf
[2048];
307 long t
= instruction
->times
;
311 if (instruction
->eops
->next
) {
312 base
= instruction
->eops
->next
->offset
;
314 if (instruction
->eops
->next
->next
&&
315 len
> instruction
->eops
->next
->next
->offset
)
316 len
= instruction
->eops
->next
->next
->offset
;
319 * Dummy call to list->output to give the offset to the
322 list
->output (offset
, NULL
, OUT_RAWDATA
);
323 list
->uplevel(LIST_INCBIN
);
328 fseek (fp
, base
, SEEK_SET
);
331 long m
= fread (buf
, 1, (l
>sizeof(buf
)?sizeof(buf
):l
),
335 * This shouldn't happen unless the file
336 * actually changes while we are reading
339 error (ERR_NONFATAL
, "`incbin': unexpected EOF while"
340 " reading file `%s'", fname
);
341 t
=0; /* Try to exit cleanly */
344 out (offset
, segment
, buf
, OUT_RAWDATA
+m
,
349 list
->downlevel(LIST_INCBIN
);
350 if (instruction
->times
> 1) {
352 * Dummy call to list->output to give the offset to the
355 list
->output (offset
, NULL
, OUT_RAWDATA
);
356 list
->uplevel(LIST_TIMES
);
357 list
->downlevel(LIST_TIMES
);
360 return instruction
->times
* len
;
362 return 0; /* if we're here, there's an error */
366 temp
= nasm_instructions
[instruction
->opcode
];
367 while (temp
->opcode
!= -1) {
368 int m
= matches (temp
, instruction
);
370 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
372 if (m
== 100) /* matches! */
374 const char *codes
= temp
->code
;
375 long insn_size
= calcsize(segment
, offset
, bits
,
377 itimes
= instruction
->times
;
378 if (insn_size
< 0) /* shouldn't be, on pass two */
379 error (ERR_PANIC
, "errors made it through from pass one");
380 else while (itimes
--) {
381 for (j
=0; j
<instruction
->nprefix
; j
++) {
383 switch (instruction
->prefixes
[j
]) {
386 case P_REPNE
: case P_REPNZ
:
388 case P_REPE
: case P_REPZ
: case P_REP
:
390 case R_CS
: c
= 0x2E; break;
391 case R_DS
: c
= 0x3E; break;
392 case R_ES
: c
= 0x26; break;
393 case R_FS
: c
= 0x64; break;
394 case R_GS
: c
= 0x65; break;
395 case R_SS
: c
= 0x36; break;
398 error (ERR_NONFATAL
, "segr6 and segr7 cannot be used as prefixes");
418 "invalid instruction prefix");
421 out (offset
, segment
, &c
, OUT_RAWDATA
+1,
426 insn_end
= offset
+ insn_size
;
427 gencode (segment
, offset
, bits
, instruction
, codes
, insn_end
);
429 if (itimes
> 0 && itimes
== instruction
->times
-1) {
431 * Dummy call to list->output to give the offset to the
434 list
->output (offset
, NULL
, OUT_RAWDATA
);
435 list
->uplevel (LIST_TIMES
);
438 if (instruction
->times
> 1)
439 list
->downlevel (LIST_TIMES
);
440 return offset
- start
;
441 } else if (m
> 0 && m
> size_prob
) {
447 if (temp
->opcode
== -1) { /* didn't match any instruction */
448 if (size_prob
== 1) /* would have matched, but for size */
449 error (ERR_NONFATAL
, "operation size not specified");
450 else if (size_prob
== 2)
451 error (ERR_NONFATAL
, "mismatch in operand sizes");
452 else if (size_prob
== 3)
453 error (ERR_NONFATAL
, "no instruction for this cpu level");
456 "invalid combination of opcode and operands");
461 long insn_size (long segment
, long offset
, int bits
, unsigned long cp
,
462 insn
*instruction
, efunc error
)
464 struct itemplate
*temp
;
466 errfunc
= error
; /* to pass to other functions */
469 if (instruction
->opcode
== -1)
472 if (instruction
->opcode
== I_DB
||
473 instruction
->opcode
== I_DW
||
474 instruction
->opcode
== I_DD
||
475 instruction
->opcode
== I_DQ
||
476 instruction
->opcode
== I_DT
)
479 long isize
, osize
, wsize
= 0; /* placate gcc */
482 switch (instruction
->opcode
)
484 case I_DB
: wsize
= 1; break;
485 case I_DW
: wsize
= 2; break;
486 case I_DD
: wsize
= 4; break;
487 case I_DQ
: wsize
= 8; break;
488 case I_DT
: wsize
= 10; break;
491 for (e
= instruction
->eops
; e
; e
= e
->next
)
496 if (e
->type
== EOT_DB_NUMBER
)
498 else if (e
->type
== EOT_DB_STRING
)
499 osize
= e
->stringlen
;
501 align
= (-osize
) % wsize
;
504 isize
+= osize
+ align
;
506 return isize
* instruction
->times
;
509 if (instruction
->opcode
== I_INCBIN
)
511 char fname
[FILENAME_MAX
];
514 char *prefix
= "", *combine
;
515 char** pPrevPath
= NULL
;
517 len
= FILENAME_MAX
-1;
518 if (len
> instruction
->eops
->stringlen
)
519 len
= instruction
->eops
->stringlen
;
520 strncpy (fname
, instruction
->eops
->stringval
, len
);
523 while (1) /* added by alexfru: 'incbin' uses include paths */
525 combine
= nasm_malloc(strlen(prefix
) + len
+ 1);
526 strcpy(combine
, prefix
);
527 strcat(combine
, fname
);
529 if ( (fp
= fopen(combine
, "rb")) != NULL
)
536 pPrevPath
= pp_get_include_path_ptr (pPrevPath
);
537 if (pPrevPath
== NULL
)
543 error (ERR_NONFATAL
, "`incbin': unable to open file `%s'", fname
);
544 else if (fseek(fp
, 0L, SEEK_END
) < 0)
545 error (ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
551 if (instruction
->eops
->next
)
553 len
-= instruction
->eops
->next
->offset
;
554 if (instruction
->eops
->next
->next
&&
555 len
> instruction
->eops
->next
->next
->offset
)
557 len
= instruction
->eops
->next
->next
->offset
;
560 return instruction
->times
* len
;
562 return 0; /* if we're here, there's an error */
565 temp
= nasm_instructions
[instruction
->opcode
];
566 while (temp
->opcode
!= -1) {
567 int m
= matches(temp
, instruction
);
569 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
572 /* we've matched an instruction. */
574 const char * codes
= temp
->code
;
577 isize
= calcsize(segment
, offset
, bits
, instruction
, codes
);
580 for (j
= 0; j
< instruction
->nprefix
; j
++)
582 if ((instruction
->prefixes
[j
] != P_A16
&&
583 instruction
->prefixes
[j
] != P_O16
&& bits
==16) ||
584 (instruction
->prefixes
[j
] != P_A32
&&
585 instruction
->prefixes
[j
] != P_O32
&& bits
==32))
590 return isize
* instruction
->times
;
594 return -1; /* didn't match any instruction */
598 /* check that opn[op] is a signed byte of size 16 or 32,
599 and return the signed value*/
600 static int is_sbyte (insn
*ins
, int op
, int size
)
605 ret
= !(ins
->forw_ref
&& ins
->oprs
[op
].opflags
) && /* dead in the water on forward reference or External */
607 !(ins
->oprs
[op
].type
& STRICT
) &&
608 ins
->oprs
[op
].wrt
==NO_SEG
&& ins
->oprs
[op
].segment
==NO_SEG
;
610 v
= ins
->oprs
[op
].offset
;
611 if (size
==16) v
= (signed short)v
; /* sign extend if 16 bits */
613 return ret
&& v
>=-128L && v
<=127L;
616 static long calcsize (long segment
, long offset
, int bits
,
617 insn
*ins
, const char *codes
)
622 (void) segment
; /* Don't warn that this parameter is unused */
623 (void) offset
; /* Don't warn that this parameter is unused */
625 while (*codes
) switch (c
= *codes
++) {
626 case 01: case 02: case 03:
627 codes
+= c
, length
+= c
; break;
628 case 04: case 05: case 06: case 07:
630 case 010: case 011: case 012:
631 codes
++, length
++; break;
634 case 014: case 015: case 016:
636 case 020: case 021: case 022:
638 case 024: case 025: case 026:
640 case 030: case 031: case 032:
642 case 034: case 035: case 036:
643 if ( ins
->oprs
[c
-034].type
& (BITS16
|BITS32
) )
644 length
+= (ins
->oprs
[c
-034].type
& BITS16
) ? 2 : 4;
646 length
+= (bits
== 16) ? 2 : 4;
650 case 040: case 041: case 042:
652 case 044: case 045: case 046:
653 length
+= ((ins
->oprs
[c
-044].addr_size
?
654 ins
->oprs
[c
-044].addr_size
: bits
) == 16 ? 2 : 4); break;
655 case 050: case 051: case 052:
657 case 060: case 061: case 062:
659 case 064: case 065: case 066:
660 if ( ins
->oprs
[c
-064].type
& (BITS16
|BITS32
) )
661 length
+= (ins
->oprs
[c
-064].type
& BITS16
) ? 2 : 4;
663 length
+= (bits
== 16) ? 2 : 4;
665 case 070: case 071: case 072:
667 case 0130: case 0131: case 0132:
668 length
+= is_sbyte(ins
, c
-0130, 16) ? 1 : 2; break;
669 case 0133: case 0134: case 0135:
670 codes
+=2; length
++; break;
671 case 0140: case 0141: case 0142:
672 length
+= is_sbyte(ins
, c
-0140, 32) ? 1 : 4; break;
673 case 0143: case 0144: case 0145:
674 codes
+=2; length
++; break;
675 case 0300: case 0301: case 0302:
676 length
+= chsize (&ins
->oprs
[c
-0300], bits
);
679 length
+= (bits
==32);
682 length
+= (bits
==16);
687 length
+= (bits
==32);
690 length
+= (bits
==16);
695 codes
++, length
++; break;
701 case 0340: case 0341: case 0342:
702 if (ins
->oprs
[0].segment
!= NO_SEG
)
703 errfunc (ERR_NONFATAL
, "attempt to reserve non-constant"
704 " quantity of BSS space");
706 length
+= ins
->oprs
[0].offset
<< (c
-0340);
708 case 0370: case 0371: case 0372:
712 default: /* can't do it by 'case' statements */
713 if (c
>=0100 && c
<=0277) { /* it's an EA */
715 if (!process_ea (&ins
->oprs
[(c
>>3)&7], &ea_data
, bits
, 0,
717 errfunc (ERR_NONFATAL
, "invalid effective address");
720 length
+= ea_data
.size
;
722 errfunc (ERR_PANIC
, "internal instruction table corrupt"
723 ": instruction code 0x%02X given", c
);
728 static void gencode (long segment
, long offset
, int bits
,
729 insn
*ins
, const char *codes
, long insn_end
)
731 static char condval
[] = { /* conditional opcodes */
732 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
733 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
734 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
737 unsigned char bytes
[4];
741 switch (c
= *codes
++)
743 case 01: case 02: case 03:
744 out (offset
, segment
, codes
, OUT_RAWDATA
+c
, NO_SEG
, NO_SEG
);
750 switch (ins
->oprs
[0].basereg
)
753 bytes
[0] = 0x0E + (c
== 0x04 ? 1 : 0); break;
755 bytes
[0] = 0x1E + (c
== 0x04 ? 1 : 0); break;
757 bytes
[0] = 0x06 + (c
== 0x04 ? 1 : 0); break;
759 bytes
[0] = 0x16 + (c
== 0x04 ? 1 : 0); break;
761 errfunc (ERR_PANIC
, "bizarre 8086 segment register received");
763 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
768 switch (ins
->oprs
[0].basereg
) {
769 case R_FS
: bytes
[0] = 0xA0 + (c
== 0x05 ? 1 : 0); break;
770 case R_GS
: bytes
[0] = 0xA8 + (c
== 0x05 ? 1 : 0); break;
772 errfunc (ERR_PANIC
, "bizarre 386 segment register received");
774 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
778 case 010: case 011: case 012:
779 bytes
[0] = *codes
++ + regval(&ins
->oprs
[c
-010]);
780 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
786 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
790 case 014: case 015: case 016:
791 if (ins
->oprs
[c
-014].offset
< -128
792 || ins
->oprs
[c
-014].offset
> 127)
794 errfunc (ERR_WARNING
, "signed byte value exceeds bounds");
797 if (ins
->oprs
[c
-014].segment
!= NO_SEG
)
799 data
= ins
->oprs
[c
-014].offset
;
800 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
801 ins
->oprs
[c
-014].segment
, ins
->oprs
[c
-014].wrt
);
804 bytes
[0] = ins
->oprs
[c
-014].offset
;
805 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
810 case 020: case 021: case 022:
811 if (ins
->oprs
[c
-020].offset
< -256
812 || ins
->oprs
[c
-020].offset
> 255)
814 errfunc (ERR_WARNING
, "byte value exceeds bounds");
816 if (ins
->oprs
[c
-020].segment
!= NO_SEG
) {
817 data
= ins
->oprs
[c
-020].offset
;
818 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
819 ins
->oprs
[c
-020].segment
, ins
->oprs
[c
-020].wrt
);
822 bytes
[0] = ins
->oprs
[c
-020].offset
;
823 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
828 case 024: case 025: case 026:
829 if (ins
->oprs
[c
-024].offset
< 0 || ins
->oprs
[c
-024].offset
> 255)
830 errfunc (ERR_WARNING
, "unsigned byte value exceeds bounds");
831 if (ins
->oprs
[c
-024].segment
!= NO_SEG
) {
832 data
= ins
->oprs
[c
-024].offset
;
833 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
834 ins
->oprs
[c
-024].segment
, ins
->oprs
[c
-024].wrt
);
837 bytes
[0] = ins
->oprs
[c
-024].offset
;
838 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
843 case 030: case 031: case 032:
844 if (ins
->oprs
[c
-030].segment
== NO_SEG
&&
845 ins
->oprs
[c
-030].wrt
== NO_SEG
&&
846 (ins
->oprs
[c
-030].offset
< -65536L ||
847 ins
->oprs
[c
-030].offset
> 65535L))
849 errfunc (ERR_WARNING
, "word value exceeds bounds");
851 data
= ins
->oprs
[c
-030].offset
;
852 out (offset
, segment
, &data
, OUT_ADDRESS
+2,
853 ins
->oprs
[c
-030].segment
, ins
->oprs
[c
-030].wrt
);
857 case 034: case 035: case 036:
858 if ( ins
->oprs
[c
-034].type
& (BITS16
|BITS32
) )
859 size
= (ins
->oprs
[c
-034].type
& BITS16
) ? 2 : 4;
861 size
= (bits
== 16) ? 2 : 4;
862 data
= ins
->oprs
[c
-034].offset
;
863 if (size
==2 && (data
< -65536L || data
> 65535L))
864 errfunc (ERR_WARNING
, "word value exceeds bounds");
865 out (offset
, segment
, &data
, OUT_ADDRESS
+size
,
866 ins
->oprs
[c
-034].segment
, ins
->oprs
[c
-034].wrt
);
871 if (ins
->oprs
[0].segment
== NO_SEG
)
872 errfunc (ERR_NONFATAL
, "value referenced by FAR is not"
875 out (offset
, segment
, &data
, OUT_ADDRESS
+2,
876 outfmt
->segbase(1+ins
->oprs
[0].segment
),
881 case 040: case 041: case 042:
882 data
= ins
->oprs
[c
-040].offset
;
883 out (offset
, segment
, &data
, OUT_ADDRESS
+4,
884 ins
->oprs
[c
-040].segment
, ins
->oprs
[c
-040].wrt
);
888 case 044: case 045: case 046:
889 data
= ins
->oprs
[c
-044].offset
;
890 size
= ((ins
->oprs
[c
-044].addr_size
?
891 ins
->oprs
[c
-044].addr_size
: bits
) == 16 ? 2 : 4);
892 if (size
==2 && (data
< -65536L || data
> 65535L))
893 errfunc (ERR_WARNING
, "word value exceeds bounds");
894 out (offset
, segment
, &data
, OUT_ADDRESS
+size
,
895 ins
->oprs
[c
-044].segment
, ins
->oprs
[c
-044].wrt
);
899 case 050: case 051: case 052:
900 if (ins
->oprs
[c
-050].segment
!= segment
)
901 errfunc (ERR_NONFATAL
, "short relative jump outside segment");
902 data
= ins
->oprs
[c
-050].offset
- insn_end
;
903 if (data
> 127 || data
< -128)
904 errfunc (ERR_NONFATAL
, "short jump is out of range");
906 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
910 case 060: case 061: case 062:
911 if (ins
->oprs
[c
-060].segment
!= segment
) {
912 data
= ins
->oprs
[c
-060].offset
;
913 out (offset
, segment
, &data
, OUT_REL2ADR
+insn_end
-offset
,
914 ins
->oprs
[c
-060].segment
, ins
->oprs
[c
-060].wrt
);
916 data
= ins
->oprs
[c
-060].offset
- insn_end
;
917 out (offset
, segment
, &data
,
918 OUT_ADDRESS
+2, NO_SEG
, NO_SEG
);
923 case 064: case 065: case 066:
924 if ( ins
->oprs
[c
-064].type
& (BITS16
|BITS32
) )
925 size
= (ins
->oprs
[c
-064].type
& BITS16
) ? 2 : 4;
927 size
= (bits
== 16) ? 2 : 4;
928 if (ins
->oprs
[c
-064].segment
!= segment
) {
929 long reltype
= (size
== 2 ? OUT_REL2ADR
: OUT_REL4ADR
);
930 data
= ins
->oprs
[c
-064].offset
;
931 out (offset
, segment
, &data
, reltype
+insn_end
-offset
,
932 ins
->oprs
[c
-064].segment
, ins
->oprs
[c
-064].wrt
);
934 data
= ins
->oprs
[c
-064].offset
- insn_end
;
935 out (offset
, segment
, &data
,
936 OUT_ADDRESS
+size
, NO_SEG
, NO_SEG
);
941 case 070: case 071: case 072:
942 if (ins
->oprs
[c
-070].segment
!= segment
) {
943 data
= ins
->oprs
[c
-070].offset
;
944 out (offset
, segment
, &data
, OUT_REL4ADR
+insn_end
-offset
,
945 ins
->oprs
[c
-070].segment
, ins
->oprs
[c
-070].wrt
);
947 data
= ins
->oprs
[c
-070].offset
- insn_end
;
948 out (offset
, segment
, &data
,
949 OUT_ADDRESS
+4, NO_SEG
, NO_SEG
);
954 case 0130: case 0131: case 0132:
955 data
= ins
->oprs
[c
-0130].offset
;
956 if (is_sbyte(ins
, c
-0130, 16)) {
958 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
961 if (ins
->oprs
[c
-0130].segment
== NO_SEG
&&
962 ins
->oprs
[c
-0130].wrt
== NO_SEG
&&
963 (data
< -65536L || data
> 65535L)) {
964 errfunc (ERR_WARNING
, "word value exceeds bounds");
966 out (offset
, segment
, &data
, OUT_ADDRESS
+2,
967 ins
->oprs
[c
-0130].segment
, ins
->oprs
[c
-0130].wrt
);
972 case 0133: case 0134: case 0135:
975 if (is_sbyte(ins
, c
-0133, 16)) bytes
[0] |= 2; /* s-bit */
976 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
980 case 0140: case 0141: case 0142:
981 data
= ins
->oprs
[c
-0140].offset
;
982 if (is_sbyte(ins
, c
-0140, 32)) {
984 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
987 out (offset
, segment
, &data
, OUT_ADDRESS
+4,
988 ins
->oprs
[c
-0140].segment
, ins
->oprs
[c
-0140].wrt
);
993 case 0143: case 0144: case 0145:
996 if (is_sbyte(ins
, c
-0143, 32)) bytes
[0] |= 2; /* s-bit */
997 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1001 case 0300: case 0301: case 0302:
1002 if (chsize (&ins
->oprs
[c
-0300], bits
)) {
1004 out (offset
, segment
, bytes
,
1005 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1014 out (offset
, segment
, bytes
,
1015 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1024 out (offset
, segment
, bytes
,
1025 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1037 out (offset
, segment
, bytes
,
1038 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1047 out (offset
, segment
, bytes
,
1048 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1058 *bytes
= *codes
++ ^ condval
[ins
->condition
];
1059 out (offset
, segment
, bytes
,
1060 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1070 out (offset
, segment
, bytes
,
1071 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1075 case 0340: case 0341: case 0342:
1076 if (ins
->oprs
[0].segment
!= NO_SEG
)
1077 errfunc (ERR_PANIC
, "non-constant BSS size in pass two");
1079 long size
= ins
->oprs
[0].offset
<< (c
-0340);
1081 out (offset
, segment
, NULL
,
1082 OUT_RESERVE
+size
, NO_SEG
, NO_SEG
);
1087 case 0370: case 0371: case 0372:
1091 *bytes
= bits
==16 ? 3 : 5;
1092 out (offset
, segment
, bytes
,
1093 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1097 default: /* can't do it by 'case' statements */
1098 if (c
>=0100 && c
<=0277) { /* it's an EA */
1104 if (c
<=0177) /* pick rfield from operand b */
1105 rfield
= regval (&ins
->oprs
[c
&7]);
1106 else /* rfield is constant */
1109 if (!process_ea (&ins
->oprs
[(c
>>3)&7], &ea_data
, bits
, rfield
,
1112 errfunc (ERR_NONFATAL
, "invalid effective address");
1116 *p
++ = ea_data
.modrm
;
1117 if (ea_data
.sib_present
)
1121 out (offset
, segment
, bytes
, OUT_RAWDATA
+ s
,
1124 switch (ea_data
.bytes
) {
1128 if (ins
->oprs
[(c
>>3)&7].segment
!= NO_SEG
) {
1129 data
= ins
->oprs
[(c
>>3)&7].offset
;
1130 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
1131 ins
->oprs
[(c
>>3)&7].segment
,
1132 ins
->oprs
[(c
>>3)&7].wrt
);
1134 *bytes
= ins
->oprs
[(c
>>3)&7].offset
;
1135 out (offset
, segment
, bytes
, OUT_RAWDATA
+1,
1142 data
= ins
->oprs
[(c
>>3)&7].offset
;
1143 out (offset
, segment
, &data
,
1144 OUT_ADDRESS
+ea_data
.bytes
,
1145 ins
->oprs
[(c
>>3)&7].segment
, ins
->oprs
[(c
>>3)&7].wrt
);
1151 errfunc (ERR_PANIC
, "internal instruction table corrupt"
1152 ": instruction code 0x%02X given", c
);
1156 #include "regvals.c"
1158 static int regval (operand
*o
)
1160 if ( o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1161 errfunc (ERR_PANIC
, "invalid operand passed to regval()");
1163 return regvals
[o
->basereg
];
1166 static int matches (struct itemplate
*itemp
, insn
*instruction
)
1168 int i
, size
[3], asize
, oprs
, ret
;
1175 if (itemp
->opcode
!= instruction
->opcode
) return 0;
1178 * Count the operands
1180 if (itemp
->operands
!= instruction
->operands
) return 0;
1183 * Check that no spurious colons or TOs are present
1185 for (i
=0; i
<itemp
->operands
; i
++)
1186 if (instruction
->oprs
[i
].type
& ~itemp
->opd
[i
] & (COLON
|TO
))
1190 * Check that the operand flags all match up
1192 for (i
=0; i
<itemp
->operands
; i
++)
1193 if (itemp
->opd
[i
] & ~instruction
->oprs
[i
].type
||
1194 ((itemp
->opd
[i
] & SIZE_MASK
) &&
1195 ((itemp
->opd
[i
] ^ instruction
->oprs
[i
].type
) & SIZE_MASK
)))
1197 if ((itemp
->opd
[i
] & ~instruction
->oprs
[i
].type
& NON_SIZE
) ||
1198 (instruction
->oprs
[i
].type
& SIZE_MASK
))
1206 * Check operand sizes
1208 if (itemp
->flags
& IF_ARMASK
) {
1209 size
[0] = size
[1] = size
[2] = 0;
1211 switch (itemp
->flags
& IF_ARMASK
) {
1212 case IF_AR0
: i
= 0; break;
1213 case IF_AR1
: i
= 1; break;
1214 case IF_AR2
: i
= 2; break;
1215 default: break; /* Shouldn't happen */
1217 if (itemp
->flags
& IF_SB
) {
1219 } else if (itemp
->flags
& IF_SW
) {
1221 } else if (itemp
->flags
& IF_SD
) {
1226 if (itemp
->flags
& IF_SB
) {
1228 oprs
= itemp
->operands
;
1229 } else if (itemp
->flags
& IF_SW
) {
1231 oprs
= itemp
->operands
;
1232 } else if (itemp
->flags
& IF_SD
) {
1234 oprs
= itemp
->operands
;
1236 size
[0] = size
[1] = size
[2] = asize
;
1239 if (itemp
->flags
& (IF_SM
| IF_SM2
)) {
1240 oprs
= (itemp
->flags
& IF_SM2
? 2 : itemp
->operands
);
1242 for (i
=0; i
<oprs
; i
++) {
1243 if ( (asize
= itemp
->opd
[i
] & SIZE_MASK
) != 0) {
1245 for (j
=0; j
<oprs
; j
++)
1251 oprs
= itemp
->operands
;
1254 for (i
=0; i
<itemp
->operands
; i
++)
1255 if (!(itemp
->opd
[i
] & SIZE_MASK
) &&
1256 (instruction
->oprs
[i
].type
& SIZE_MASK
& ~size
[i
]))
1261 * Check template is okay at the set cpu level
1263 if ((itemp
->flags
& IF_PLEVEL
) > cpu
) return 3;
1266 * Check if special handling needed for Jumps
1268 if ((unsigned char)(itemp
->code
[0]) >= 0370) return 99;
1273 static ea
*process_ea (operand
*input
, ea
*output
, int addrbits
, int rfield
,
1276 if (!(REGISTER
& ~input
->type
)) { /* it's a single register */
1277 static int regs
[] = {
1278 R_AL
, R_CL
, R_DL
, R_BL
, R_AH
, R_CH
, R_DH
, R_BH
,
1279 R_AX
, R_CX
, R_DX
, R_BX
, R_SP
, R_BP
, R_SI
, R_DI
,
1280 R_EAX
, R_ECX
, R_EDX
, R_EBX
, R_ESP
, R_EBP
, R_ESI
, R_EDI
,
1281 R_MM0
, R_MM1
, R_MM2
, R_MM3
, R_MM4
, R_MM5
, R_MM6
, R_MM7
,
1282 R_XMM0
, R_XMM1
, R_XMM2
, R_XMM3
, R_XMM4
, R_XMM5
, R_XMM6
, R_XMM7
1286 for (i
=0; i
<elements(regs
); i
++)
1287 if (input
->basereg
== regs
[i
]) break;
1288 if (i
<elements(regs
)) {
1289 output
->sib_present
= FALSE
;/* no SIB necessary */
1290 output
->bytes
= 0; /* no offset necessary either */
1291 output
->modrm
= 0xC0 | (rfield
<< 3) | (i
& 7);
1295 } else { /* it's a memory reference */
1296 if (input
->basereg
==-1 && (input
->indexreg
==-1 || input
->scale
==0)) {
1297 /* it's a pure offset */
1298 if (input
->addr_size
)
1299 addrbits
= input
->addr_size
;
1300 output
->sib_present
= FALSE
;
1301 output
->bytes
= (addrbits
==32 ? 4 : 2);
1302 output
->modrm
= (addrbits
==32 ? 5 : 6) | (rfield
<< 3);
1304 else { /* it's an indirection */
1305 int i
=input
->indexreg
, b
=input
->basereg
, s
=input
->scale
;
1306 long o
=input
->offset
, seg
=input
->segment
;
1307 int hb
=input
->hintbase
, ht
=input
->hinttype
;
1310 if (s
==0) i
= -1; /* make this easy, at least */
1312 if (i
==R_EAX
|| i
==R_EBX
|| i
==R_ECX
|| i
==R_EDX
1313 || i
==R_EBP
|| i
==R_ESP
|| i
==R_ESI
|| i
==R_EDI
1314 || b
==R_EAX
|| b
==R_EBX
|| b
==R_ECX
|| b
==R_EDX
1315 || b
==R_EBP
|| b
==R_ESP
|| b
==R_ESI
|| b
==R_EDI
) {
1316 /* it must be a 32-bit memory reference. Firstly we have
1317 * to check that all registers involved are type Exx. */
1318 if (i
!=-1 && i
!=R_EAX
&& i
!=R_EBX
&& i
!=R_ECX
&& i
!=R_EDX
1319 && i
!=R_EBP
&& i
!=R_ESP
&& i
!=R_ESI
&& i
!=R_EDI
)
1321 if (b
!=-1 && b
!=R_EAX
&& b
!=R_EBX
&& b
!=R_ECX
&& b
!=R_EDX
1322 && b
!=R_EBP
&& b
!=R_ESP
&& b
!=R_ESI
&& b
!=R_EDI
)
1325 /* While we're here, ensure the user didn't specify WORD. */
1326 if (input
->addr_size
== 16)
1329 /* now reorganise base/index */
1330 if (s
== 1 && b
!= i
&& b
!= -1 && i
!= -1 &&
1331 ((hb
==b
&&ht
==EAH_NOTBASE
) || (hb
==i
&&ht
==EAH_MAKEBASE
)))
1332 t
= b
, b
= i
, i
= t
; /* swap if hints say so */
1333 if (b
==i
) /* convert EAX+2*EAX to 3*EAX */
1335 if (b
==-1 && s
==1 && !(hb
== i
&& ht
== EAH_NOTBASE
))
1336 b
= i
, i
= -1; /* make single reg base, unless hint */
1337 if (((s
==2 && i
!=R_ESP
&& !(input
->eaflags
& EAF_TIMESTWO
)) ||
1338 s
==3 || s
==5 || s
==9) && b
==-1)
1339 b
= i
, s
--; /* convert 3*EAX to EAX+2*EAX */
1340 if (i
==-1 && b
!=R_ESP
&& (input
->eaflags
& EAF_TIMESTWO
))
1341 i
= b
, b
= -1, s
= 1;
1342 /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */
1343 if (s
==1 && i
==R_ESP
) /* swap ESP into base if scale is 1 */
1345 if (i
==R_ESP
|| (s
!=1 && s
!=2 && s
!=4 && s
!=8 && i
!=-1))
1346 return NULL
; /* wrong, for various reasons */
1348 if (i
==-1 && b
!=R_ESP
) {/* no SIB needed */
1351 case R_EAX
: rm
= 0; break;
1352 case R_ECX
: rm
= 1; break;
1353 case R_EDX
: rm
= 2; break;
1354 case R_EBX
: rm
= 3; break;
1355 case R_EBP
: rm
= 5; break;
1356 case R_ESI
: rm
= 6; break;
1357 case R_EDI
: rm
= 7; break;
1358 case -1: rm
= 5; break;
1359 default: /* should never happen */
1362 if (b
==-1 || (b
!=R_EBP
&& o
==0 &&
1363 seg
==NO_SEG
&& !forw_ref
&&
1365 (EAF_BYTEOFFS
|EAF_WORDOFFS
))))
1367 else if (input
->eaflags
& EAF_BYTEOFFS
||
1368 (o
>=-128 && o
<=127 && seg
==NO_SEG
&& !forw_ref
&&
1369 !(input
->eaflags
& EAF_WORDOFFS
))) {
1375 output
->sib_present
= FALSE
;
1376 output
->bytes
= (b
==-1 || mod
==2 ? 4 : mod
);
1377 output
->modrm
= (mod
<<6) | (rfield
<<3) | rm
;
1379 else { /* we need a SIB */
1380 int mod
, scale
, index
, base
;
1383 case R_EAX
: base
= 0; break;
1384 case R_ECX
: base
= 1; break;
1385 case R_EDX
: base
= 2; break;
1386 case R_EBX
: base
= 3; break;
1387 case R_ESP
: base
= 4; break;
1388 case R_EBP
: case -1: base
= 5; break;
1389 case R_ESI
: base
= 6; break;
1390 case R_EDI
: base
= 7; break;
1391 default: /* then what the smeg is it? */
1392 return NULL
; /* panic */
1396 case R_EAX
: index
= 0; break;
1397 case R_ECX
: index
= 1; break;
1398 case R_EDX
: index
= 2; break;
1399 case R_EBX
: index
= 3; break;
1400 case -1: index
= 4; break;
1401 case R_EBP
: index
= 5; break;
1402 case R_ESI
: index
= 6; break;
1403 case R_EDI
: index
= 7; break;
1404 default: /* then what the smeg is it? */
1405 return NULL
; /* panic */
1410 case 1: scale
= 0; break;
1411 case 2: scale
= 1; break;
1412 case 4: scale
= 2; break;
1413 case 8: scale
= 3; break;
1414 default: /* then what the smeg is it? */
1415 return NULL
; /* panic */
1418 if (b
==-1 || (b
!=R_EBP
&& o
==0 &&
1419 seg
==NO_SEG
&& !forw_ref
&&
1421 (EAF_BYTEOFFS
|EAF_WORDOFFS
))))
1423 else if (input
->eaflags
& EAF_BYTEOFFS
||
1424 (o
>=-128 && o
<=127 && seg
==NO_SEG
&& !forw_ref
&&
1425 !(input
->eaflags
& EAF_WORDOFFS
)))
1430 output
->sib_present
= TRUE
;
1431 output
->bytes
= (b
==-1 || mod
==2 ? 4 : mod
);
1432 output
->modrm
= (mod
<<6) | (rfield
<<3) | 4;
1433 output
->sib
= (scale
<<6) | (index
<<3) | base
;
1436 else { /* it's 16-bit */
1439 /* check all registers are BX, BP, SI or DI */
1440 if ((b
!=-1 && b
!=R_BP
&& b
!=R_BX
&& b
!=R_SI
&& b
!=R_DI
) ||
1441 (i
!=-1 && i
!=R_BP
&& i
!=R_BX
&& i
!=R_SI
&& i
!=R_DI
))
1444 /* ensure the user didn't specify DWORD */
1445 if (input
->addr_size
== 32)
1448 if (s
!=1 && i
!=-1) return NULL
;/* no can do, in 16-bit EA */
1449 if (b
==-1 && i
!=-1) { int tmp
= b
; b
= i
; i
= tmp
; } /* swap */
1450 if ((b
==R_SI
|| b
==R_DI
) && i
!=-1)
1451 { int tmp
= b
; b
= i
; i
= tmp
; }
1452 /* have BX/BP as base, SI/DI index */
1453 if (b
==i
) return NULL
;/* shouldn't ever happen, in theory */
1454 if (i
!=-1 && b
!=-1 &&
1455 (i
==R_BP
|| i
==R_BX
|| b
==R_SI
|| b
==R_DI
))
1456 return NULL
; /* invalid combinations */
1457 if (b
==-1) /* pure offset: handled above */
1458 return NULL
; /* so if it gets to here, panic! */
1462 switch (i
*256 + b
) {
1463 case R_SI
*256+R_BX
: rm
=0; break;
1464 case R_DI
*256+R_BX
: rm
=1; break;
1465 case R_SI
*256+R_BP
: rm
=2; break;
1466 case R_DI
*256+R_BP
: rm
=3; break;
1470 case R_SI
: rm
=4; break;
1471 case R_DI
: rm
=5; break;
1472 case R_BP
: rm
=6; break;
1473 case R_BX
: rm
=7; break;
1475 if (rm
==-1) /* can't happen, in theory */
1476 return NULL
; /* so panic if it does */
1478 if (o
==0 && seg
==NO_SEG
&& !forw_ref
&& rm
!=6 &&
1479 !(input
->eaflags
& (EAF_BYTEOFFS
|EAF_WORDOFFS
)))
1481 else if (input
->eaflags
& EAF_BYTEOFFS
||
1482 (o
>=-128 && o
<=127 && seg
==NO_SEG
&& !forw_ref
&&
1483 !(input
->eaflags
& EAF_WORDOFFS
)))
1488 output
->sib_present
= FALSE
; /* no SIB - it's 16-bit */
1489 output
->bytes
= mod
; /* bytes of offset needed */
1490 output
->modrm
= (mod
<<6) | (rfield
<<3) | rm
;
1494 output
->size
= 1 + output
->sib_present
+ output
->bytes
;
1498 static int chsize (operand
*input
, int addrbits
)
1500 if (!(MEMORY
& ~input
->type
)) {
1501 int i
=input
->indexreg
, b
=input
->basereg
;
1503 if (input
->scale
==0) i
= -1;
1505 if (i
== -1 && b
== -1) /* pure offset */
1506 return (input
->addr_size
!= 0 && input
->addr_size
!= addrbits
);
1508 if (i
==R_EAX
|| i
==R_EBX
|| i
==R_ECX
|| i
==R_EDX
1509 || i
==R_EBP
|| i
==R_ESP
|| i
==R_ESI
|| i
==R_EDI
1510 || b
==R_EAX
|| b
==R_EBX
|| b
==R_ECX
|| b
==R_EDX
1511 || b
==R_EBP
|| b
==R_ESP
|| b
==R_ESI
|| b
==R_EDI
)
1512 return (addrbits
==16);
1514 return (addrbits
==32);