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
)
108 static long lineno
= 0; /* static!!! */
109 static 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
);
147 * this call to src_get determines when we call the
148 * debug-format-specific "linenum" function
149 * it updates lineno and lnfname to the current values
150 * returning 0 if "same as last time", -2 if lnfname
151 * changed, and the amount by which lineno changed,
152 * if it did. thus, these variables must be static
155 if (src_get(&lineno
,&lnfname
))
157 outfmt
->current_dfmt
->linenum(lnfname
,lineno
,segto
);
158 if (lnfname
) nasm_free(lnfname
);
161 outfmt
->output (segto
, data
, type
, segment
, wrt
);
164 static int jmp_match (long segment
, long offset
, int bits
,
165 insn
*ins
, const char *code
)
167 unsigned char c
= code
[0];
170 if (c
!= 0370 && c
!= 0371) return 0;
171 if (ins
->oprs
[0].opflags
& OPFLAG_FORWARD
) {
172 if ((optimizing
<0 || (ins
->oprs
[0].type
& STRICT
))
173 && c
==0370) return 1;
174 else return (pass0
==0); /* match a forward reference */
176 isize
= calcsize (segment
, offset
, bits
, ins
, code
);
177 if (ins
->oprs
[0].segment
!= segment
) return 0;
178 isize
= ins
->oprs
[0].offset
- offset
- isize
; /* isize is now the delta */
179 if (isize
>= -128L && isize
<= 127L) return 1; /* it is byte size */
185 long assemble (long segment
, long offset
, int bits
, unsigned long cp
,
186 insn
*instruction
, struct ofmt
*output
, efunc error
,
189 struct itemplate
*temp
;
195 long wsize
= 0; /* size for DB etc. */
197 errfunc
= error
; /* to pass to other functions */
199 outfmt
= output
; /* likewise */
200 list
= listgen
; /* and again */
202 switch (instruction
->opcode
)
205 case I_DB
: wsize
= 1; break;
206 case I_DW
: wsize
= 2; break;
207 case I_DD
: wsize
= 4; break;
208 case I_DQ
: wsize
= 8; break;
209 case I_DT
: wsize
= 10; break;
214 long t
= instruction
->times
;
216 errfunc(ERR_PANIC
, "instruction->times < 0 (%ld) in assemble()",t
);
218 while (t
--) /* repeat TIMES times */
220 for (e
= instruction
->eops
; e
; e
= e
->next
)
222 if (e
->type
== EOT_DB_NUMBER
)
225 if (e
->segment
!= NO_SEG
)
226 errfunc (ERR_NONFATAL
,
227 "one-byte relocation attempted");
229 unsigned char out_byte
= e
->offset
;
230 out (offset
, segment
, &out_byte
, OUT_RAWDATA
+1,
234 else if (wsize
> 5) {
235 errfunc (ERR_NONFATAL
, "integer supplied to a D%c"
236 " instruction", wsize
==8 ? 'Q' : 'T');
239 out (offset
, segment
, &e
->offset
,
240 OUT_ADDRESS
+wsize
, e
->segment
,
244 else if (e
->type
== EOT_DB_STRING
)
248 out (offset
, segment
, e
->stringval
,
249 OUT_RAWDATA
+e
->stringlen
, NO_SEG
, NO_SEG
);
250 align
= e
->stringlen
% wsize
;
253 align
= wsize
- align
;
254 out (offset
, segment
, "\0\0\0\0\0\0\0\0",
255 OUT_RAWDATA
+align
, NO_SEG
, NO_SEG
);
257 offset
+= e
->stringlen
+ align
;
260 if (t
> 0 && t
== instruction
->times
-1)
263 * Dummy call to list->output to give the offset to the
266 list
->output (offset
, NULL
, OUT_RAWDATA
);
267 list
->uplevel (LIST_TIMES
);
270 if (instruction
->times
> 1)
271 list
->downlevel (LIST_TIMES
);
272 return offset
- start
;
275 if (instruction
->opcode
== I_INCBIN
)
277 static char fname
[FILENAME_MAX
];
280 char *prefix
= "", *combine
;
281 char** pPrevPath
= NULL
;
283 len
= FILENAME_MAX
-1;
284 if (len
> instruction
->eops
->stringlen
)
285 len
= instruction
->eops
->stringlen
;
286 strncpy (fname
, instruction
->eops
->stringval
, len
);
289 while (1) /* added by alexfru: 'incbin' uses include paths */
291 combine
= nasm_malloc(strlen(prefix
) + len
+ 1);
292 strcpy(combine
, prefix
);
293 strcat(combine
, fname
);
295 if ( (fp
= fopen(combine
, "rb")) != NULL
)
302 pPrevPath
= pp_get_include_path_ptr (pPrevPath
);
303 if (pPrevPath
== NULL
)
309 error (ERR_NONFATAL
, "`incbin': unable to open file `%s'", fname
);
310 else if (fseek(fp
, 0L, SEEK_END
) < 0)
311 error (ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
315 static char buf
[2048];
316 long t
= instruction
->times
;
320 if (instruction
->eops
->next
) {
321 base
= instruction
->eops
->next
->offset
;
323 if (instruction
->eops
->next
->next
&&
324 len
> instruction
->eops
->next
->next
->offset
)
325 len
= instruction
->eops
->next
->next
->offset
;
328 * Dummy call to list->output to give the offset to the
331 list
->output (offset
, NULL
, OUT_RAWDATA
);
332 list
->uplevel(LIST_INCBIN
);
337 fseek (fp
, base
, SEEK_SET
);
340 long m
= fread (buf
, 1, (l
>sizeof(buf
)?sizeof(buf
):l
),
344 * This shouldn't happen unless the file
345 * actually changes while we are reading
348 error (ERR_NONFATAL
, "`incbin': unexpected EOF while"
349 " reading file `%s'", fname
);
350 t
=0; /* Try to exit cleanly */
353 out (offset
, segment
, buf
, OUT_RAWDATA
+m
,
358 list
->downlevel(LIST_INCBIN
);
359 if (instruction
->times
> 1) {
361 * Dummy call to list->output to give the offset to the
364 list
->output (offset
, NULL
, OUT_RAWDATA
);
365 list
->uplevel(LIST_TIMES
);
366 list
->downlevel(LIST_TIMES
);
369 return instruction
->times
* len
;
371 return 0; /* if we're here, there's an error */
375 temp
= nasm_instructions
[instruction
->opcode
];
376 while (temp
->opcode
!= -1) {
377 int m
= matches (temp
, instruction
);
379 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
381 if (m
== 100) /* matches! */
383 const char *codes
= temp
->code
;
384 long insn_size
= calcsize(segment
, offset
, bits
,
386 itimes
= instruction
->times
;
387 if (insn_size
< 0) /* shouldn't be, on pass two */
388 error (ERR_PANIC
, "errors made it through from pass one");
389 else while (itimes
--) {
390 for (j
=0; j
<instruction
->nprefix
; j
++) {
392 switch (instruction
->prefixes
[j
]) {
395 case P_REPNE
: case P_REPNZ
:
397 case P_REPE
: case P_REPZ
: case P_REP
:
399 case R_CS
: c
= 0x2E; break;
400 case R_DS
: c
= 0x3E; break;
401 case R_ES
: c
= 0x26; break;
402 case R_FS
: c
= 0x64; break;
403 case R_GS
: c
= 0x65; break;
404 case R_SS
: c
= 0x36; break;
407 error (ERR_NONFATAL
, "segr6 and segr7 cannot be used as prefixes");
427 "invalid instruction prefix");
430 out (offset
, segment
, &c
, OUT_RAWDATA
+1,
435 insn_end
= offset
+ insn_size
;
436 gencode (segment
, offset
, bits
, instruction
, codes
, insn_end
);
438 if (itimes
> 0 && itimes
== instruction
->times
-1) {
440 * Dummy call to list->output to give the offset to the
443 list
->output (offset
, NULL
, OUT_RAWDATA
);
444 list
->uplevel (LIST_TIMES
);
447 if (instruction
->times
> 1)
448 list
->downlevel (LIST_TIMES
);
449 return offset
- start
;
450 } else if (m
> 0 && m
> size_prob
) {
456 if (temp
->opcode
== -1) { /* didn't match any instruction */
457 if (size_prob
== 1) /* would have matched, but for size */
458 error (ERR_NONFATAL
, "operation size not specified");
459 else if (size_prob
== 2)
460 error (ERR_NONFATAL
, "mismatch in operand sizes");
461 else if (size_prob
== 3)
462 error (ERR_NONFATAL
, "no instruction for this cpu level");
465 "invalid combination of opcode and operands");
470 long insn_size (long segment
, long offset
, int bits
, unsigned long cp
,
471 insn
*instruction
, efunc error
)
473 struct itemplate
*temp
;
475 errfunc
= error
; /* to pass to other functions */
478 if (instruction
->opcode
== -1)
481 if (instruction
->opcode
== I_DB
||
482 instruction
->opcode
== I_DW
||
483 instruction
->opcode
== I_DD
||
484 instruction
->opcode
== I_DQ
||
485 instruction
->opcode
== I_DT
)
488 long isize
, osize
, wsize
= 0; /* placate gcc */
491 switch (instruction
->opcode
)
493 case I_DB
: wsize
= 1; break;
494 case I_DW
: wsize
= 2; break;
495 case I_DD
: wsize
= 4; break;
496 case I_DQ
: wsize
= 8; break;
497 case I_DT
: wsize
= 10; break;
500 for (e
= instruction
->eops
; e
; e
= e
->next
)
505 if (e
->type
== EOT_DB_NUMBER
)
507 else if (e
->type
== EOT_DB_STRING
)
508 osize
= e
->stringlen
;
510 align
= (-osize
) % wsize
;
513 isize
+= osize
+ align
;
515 return isize
* instruction
->times
;
518 if (instruction
->opcode
== I_INCBIN
)
520 char fname
[FILENAME_MAX
];
523 char *prefix
= "", *combine
;
524 char** pPrevPath
= NULL
;
526 len
= FILENAME_MAX
-1;
527 if (len
> instruction
->eops
->stringlen
)
528 len
= instruction
->eops
->stringlen
;
529 strncpy (fname
, instruction
->eops
->stringval
, len
);
532 while (1) /* added by alexfru: 'incbin' uses include paths */
534 combine
= nasm_malloc(strlen(prefix
) + len
+ 1);
535 strcpy(combine
, prefix
);
536 strcat(combine
, fname
);
538 if ( (fp
= fopen(combine
, "rb")) != NULL
)
545 pPrevPath
= pp_get_include_path_ptr (pPrevPath
);
546 if (pPrevPath
== NULL
)
552 error (ERR_NONFATAL
, "`incbin': unable to open file `%s'", fname
);
553 else if (fseek(fp
, 0L, SEEK_END
) < 0)
554 error (ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
560 if (instruction
->eops
->next
)
562 len
-= instruction
->eops
->next
->offset
;
563 if (instruction
->eops
->next
->next
&&
564 len
> instruction
->eops
->next
->next
->offset
)
566 len
= instruction
->eops
->next
->next
->offset
;
569 return instruction
->times
* len
;
571 return 0; /* if we're here, there's an error */
574 temp
= nasm_instructions
[instruction
->opcode
];
575 while (temp
->opcode
!= -1) {
576 int m
= matches(temp
, instruction
);
578 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
581 /* we've matched an instruction. */
583 const char * codes
= temp
->code
;
586 isize
= calcsize(segment
, offset
, bits
, instruction
, codes
);
589 for (j
= 0; j
< instruction
->nprefix
; j
++)
591 if ((instruction
->prefixes
[j
] != P_A16
&&
592 instruction
->prefixes
[j
] != P_O16
&& bits
==16) ||
593 (instruction
->prefixes
[j
] != P_A32
&&
594 instruction
->prefixes
[j
] != P_O32
&& bits
==32))
599 return isize
* instruction
->times
;
603 return -1; /* didn't match any instruction */
607 /* check that opn[op] is a signed byte of size 16 or 32,
608 and return the signed value*/
609 static int is_sbyte (insn
*ins
, int op
, int size
)
614 ret
= !(ins
->forw_ref
&& ins
->oprs
[op
].opflags
) && /* dead in the water on forward reference or External */
616 !(ins
->oprs
[op
].type
& STRICT
) &&
617 ins
->oprs
[op
].wrt
==NO_SEG
&& ins
->oprs
[op
].segment
==NO_SEG
;
619 v
= ins
->oprs
[op
].offset
;
620 if (size
==16) v
= (signed short)v
; /* sign extend if 16 bits */
622 return ret
&& v
>=-128L && v
<=127L;
625 static long calcsize (long segment
, long offset
, int bits
,
626 insn
*ins
, const char *codes
)
631 (void) segment
; /* Don't warn that this parameter is unused */
632 (void) offset
; /* Don't warn that this parameter is unused */
634 while (*codes
) switch (c
= *codes
++) {
635 case 01: case 02: case 03:
636 codes
+= c
, length
+= c
; break;
637 case 04: case 05: case 06: case 07:
639 case 010: case 011: case 012:
640 codes
++, length
++; break;
643 case 014: case 015: case 016:
645 case 020: case 021: case 022:
647 case 024: case 025: case 026:
649 case 030: case 031: case 032:
651 case 034: case 035: case 036:
652 if ( ins
->oprs
[c
-034].type
& (BITS16
|BITS32
) )
653 length
+= (ins
->oprs
[c
-034].type
& BITS16
) ? 2 : 4;
655 length
+= (bits
== 16) ? 2 : 4;
659 case 040: case 041: case 042:
661 case 044: case 045: case 046:
662 length
+= ((ins
->oprs
[c
-044].addr_size
?
663 ins
->oprs
[c
-044].addr_size
: bits
) == 16 ? 2 : 4); break;
664 case 050: case 051: case 052:
666 case 060: case 061: case 062:
668 case 064: case 065: case 066:
669 if ( ins
->oprs
[c
-064].type
& (BITS16
|BITS32
) )
670 length
+= (ins
->oprs
[c
-064].type
& BITS16
) ? 2 : 4;
672 length
+= (bits
== 16) ? 2 : 4;
674 case 070: case 071: case 072:
676 case 0130: case 0131: case 0132:
677 length
+= is_sbyte(ins
, c
-0130, 16) ? 1 : 2; break;
678 case 0133: case 0134: case 0135:
679 codes
+=2; length
++; break;
680 case 0140: case 0141: case 0142:
681 length
+= is_sbyte(ins
, c
-0140, 32) ? 1 : 4; break;
682 case 0143: case 0144: case 0145:
683 codes
+=2; length
++; break;
684 case 0300: case 0301: case 0302:
685 length
+= chsize (&ins
->oprs
[c
-0300], bits
);
688 length
+= (bits
==32);
691 length
+= (bits
==16);
696 length
+= (bits
==32);
699 length
+= (bits
==16);
704 codes
++, length
++; break;
710 case 0340: case 0341: case 0342:
711 if (ins
->oprs
[0].segment
!= NO_SEG
)
712 errfunc (ERR_NONFATAL
, "attempt to reserve non-constant"
713 " quantity of BSS space");
715 length
+= ins
->oprs
[0].offset
<< (c
-0340);
717 case 0370: case 0371: case 0372:
721 default: /* can't do it by 'case' statements */
722 if (c
>=0100 && c
<=0277) { /* it's an EA */
724 if (!process_ea (&ins
->oprs
[(c
>>3)&7], &ea_data
, bits
, 0,
726 errfunc (ERR_NONFATAL
, "invalid effective address");
729 length
+= ea_data
.size
;
731 errfunc (ERR_PANIC
, "internal instruction table corrupt"
732 ": instruction code 0x%02X given", c
);
737 static void gencode (long segment
, long offset
, int bits
,
738 insn
*ins
, const char *codes
, long insn_end
)
740 static char condval
[] = { /* conditional opcodes */
741 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
742 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
743 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
746 unsigned char bytes
[4];
750 switch (c
= *codes
++)
752 case 01: case 02: case 03:
753 out (offset
, segment
, codes
, OUT_RAWDATA
+c
, NO_SEG
, NO_SEG
);
759 switch (ins
->oprs
[0].basereg
)
762 bytes
[0] = 0x0E + (c
== 0x04 ? 1 : 0); break;
764 bytes
[0] = 0x1E + (c
== 0x04 ? 1 : 0); break;
766 bytes
[0] = 0x06 + (c
== 0x04 ? 1 : 0); break;
768 bytes
[0] = 0x16 + (c
== 0x04 ? 1 : 0); break;
770 errfunc (ERR_PANIC
, "bizarre 8086 segment register received");
772 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
777 switch (ins
->oprs
[0].basereg
) {
778 case R_FS
: bytes
[0] = 0xA0 + (c
== 0x05 ? 1 : 0); break;
779 case R_GS
: bytes
[0] = 0xA8 + (c
== 0x05 ? 1 : 0); break;
781 errfunc (ERR_PANIC
, "bizarre 386 segment register received");
783 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
787 case 010: case 011: case 012:
788 bytes
[0] = *codes
++ + regval(&ins
->oprs
[c
-010]);
789 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
795 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
799 case 014: case 015: case 016:
800 if (ins
->oprs
[c
-014].offset
< -128
801 || ins
->oprs
[c
-014].offset
> 127)
803 errfunc (ERR_WARNING
, "signed byte value exceeds bounds");
806 if (ins
->oprs
[c
-014].segment
!= NO_SEG
)
808 data
= ins
->oprs
[c
-014].offset
;
809 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
810 ins
->oprs
[c
-014].segment
, ins
->oprs
[c
-014].wrt
);
813 bytes
[0] = ins
->oprs
[c
-014].offset
;
814 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
819 case 020: case 021: case 022:
820 if (ins
->oprs
[c
-020].offset
< -256
821 || ins
->oprs
[c
-020].offset
> 255)
823 errfunc (ERR_WARNING
, "byte value exceeds bounds");
825 if (ins
->oprs
[c
-020].segment
!= NO_SEG
) {
826 data
= ins
->oprs
[c
-020].offset
;
827 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
828 ins
->oprs
[c
-020].segment
, ins
->oprs
[c
-020].wrt
);
831 bytes
[0] = ins
->oprs
[c
-020].offset
;
832 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
837 case 024: case 025: case 026:
838 if (ins
->oprs
[c
-024].offset
< 0 || ins
->oprs
[c
-024].offset
> 255)
839 errfunc (ERR_WARNING
, "unsigned byte value exceeds bounds");
840 if (ins
->oprs
[c
-024].segment
!= NO_SEG
) {
841 data
= ins
->oprs
[c
-024].offset
;
842 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
843 ins
->oprs
[c
-024].segment
, ins
->oprs
[c
-024].wrt
);
846 bytes
[0] = ins
->oprs
[c
-024].offset
;
847 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
852 case 030: case 031: case 032:
853 if (ins
->oprs
[c
-030].segment
== NO_SEG
&&
854 ins
->oprs
[c
-030].wrt
== NO_SEG
&&
855 (ins
->oprs
[c
-030].offset
< -65536L ||
856 ins
->oprs
[c
-030].offset
> 65535L))
858 errfunc (ERR_WARNING
, "word value exceeds bounds");
860 data
= ins
->oprs
[c
-030].offset
;
861 out (offset
, segment
, &data
, OUT_ADDRESS
+2,
862 ins
->oprs
[c
-030].segment
, ins
->oprs
[c
-030].wrt
);
866 case 034: case 035: case 036:
867 if ( ins
->oprs
[c
-034].type
& (BITS16
|BITS32
) )
868 size
= (ins
->oprs
[c
-034].type
& BITS16
) ? 2 : 4;
870 size
= (bits
== 16) ? 2 : 4;
871 data
= ins
->oprs
[c
-034].offset
;
872 if (size
==2 && (data
< -65536L || data
> 65535L))
873 errfunc (ERR_WARNING
, "word value exceeds bounds");
874 out (offset
, segment
, &data
, OUT_ADDRESS
+size
,
875 ins
->oprs
[c
-034].segment
, ins
->oprs
[c
-034].wrt
);
880 if (ins
->oprs
[0].segment
== NO_SEG
)
881 errfunc (ERR_NONFATAL
, "value referenced by FAR is not"
884 out (offset
, segment
, &data
, OUT_ADDRESS
+2,
885 outfmt
->segbase(1+ins
->oprs
[0].segment
),
890 case 040: case 041: case 042:
891 data
= ins
->oprs
[c
-040].offset
;
892 out (offset
, segment
, &data
, OUT_ADDRESS
+4,
893 ins
->oprs
[c
-040].segment
, ins
->oprs
[c
-040].wrt
);
897 case 044: case 045: case 046:
898 data
= ins
->oprs
[c
-044].offset
;
899 size
= ((ins
->oprs
[c
-044].addr_size
?
900 ins
->oprs
[c
-044].addr_size
: bits
) == 16 ? 2 : 4);
901 if (size
==2 && (data
< -65536L || data
> 65535L))
902 errfunc (ERR_WARNING
, "word value exceeds bounds");
903 out (offset
, segment
, &data
, OUT_ADDRESS
+size
,
904 ins
->oprs
[c
-044].segment
, ins
->oprs
[c
-044].wrt
);
908 case 050: case 051: case 052:
909 if (ins
->oprs
[c
-050].segment
!= segment
)
910 errfunc (ERR_NONFATAL
, "short relative jump outside segment");
911 data
= ins
->oprs
[c
-050].offset
- insn_end
;
912 if (data
> 127 || data
< -128)
913 errfunc (ERR_NONFATAL
, "short jump is out of range");
915 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
919 case 060: case 061: case 062:
920 if (ins
->oprs
[c
-060].segment
!= segment
) {
921 data
= ins
->oprs
[c
-060].offset
;
922 out (offset
, segment
, &data
, OUT_REL2ADR
+insn_end
-offset
,
923 ins
->oprs
[c
-060].segment
, ins
->oprs
[c
-060].wrt
);
925 data
= ins
->oprs
[c
-060].offset
- insn_end
;
926 out (offset
, segment
, &data
,
927 OUT_ADDRESS
+2, NO_SEG
, NO_SEG
);
932 case 064: case 065: case 066:
933 if ( ins
->oprs
[c
-064].type
& (BITS16
|BITS32
) )
934 size
= (ins
->oprs
[c
-064].type
& BITS16
) ? 2 : 4;
936 size
= (bits
== 16) ? 2 : 4;
937 if (ins
->oprs
[c
-064].segment
!= segment
) {
938 long reltype
= (size
== 2 ? OUT_REL2ADR
: OUT_REL4ADR
);
939 data
= ins
->oprs
[c
-064].offset
;
940 out (offset
, segment
, &data
, reltype
+insn_end
-offset
,
941 ins
->oprs
[c
-064].segment
, ins
->oprs
[c
-064].wrt
);
943 data
= ins
->oprs
[c
-064].offset
- insn_end
;
944 out (offset
, segment
, &data
,
945 OUT_ADDRESS
+size
, NO_SEG
, NO_SEG
);
950 case 070: case 071: case 072:
951 if (ins
->oprs
[c
-070].segment
!= segment
) {
952 data
= ins
->oprs
[c
-070].offset
;
953 out (offset
, segment
, &data
, OUT_REL4ADR
+insn_end
-offset
,
954 ins
->oprs
[c
-070].segment
, ins
->oprs
[c
-070].wrt
);
956 data
= ins
->oprs
[c
-070].offset
- insn_end
;
957 out (offset
, segment
, &data
,
958 OUT_ADDRESS
+4, NO_SEG
, NO_SEG
);
963 case 0130: case 0131: case 0132:
964 data
= ins
->oprs
[c
-0130].offset
;
965 if (is_sbyte(ins
, c
-0130, 16)) {
967 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
970 if (ins
->oprs
[c
-0130].segment
== NO_SEG
&&
971 ins
->oprs
[c
-0130].wrt
== NO_SEG
&&
972 (data
< -65536L || data
> 65535L)) {
973 errfunc (ERR_WARNING
, "word value exceeds bounds");
975 out (offset
, segment
, &data
, OUT_ADDRESS
+2,
976 ins
->oprs
[c
-0130].segment
, ins
->oprs
[c
-0130].wrt
);
981 case 0133: case 0134: case 0135:
984 if (is_sbyte(ins
, c
-0133, 16)) bytes
[0] |= 2; /* s-bit */
985 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
989 case 0140: case 0141: case 0142:
990 data
= ins
->oprs
[c
-0140].offset
;
991 if (is_sbyte(ins
, c
-0140, 32)) {
993 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
996 out (offset
, segment
, &data
, OUT_ADDRESS
+4,
997 ins
->oprs
[c
-0140].segment
, ins
->oprs
[c
-0140].wrt
);
1002 case 0143: case 0144: case 0145:
1004 bytes
[0] = *codes
++;
1005 if (is_sbyte(ins
, c
-0143, 32)) bytes
[0] |= 2; /* s-bit */
1006 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1010 case 0300: case 0301: case 0302:
1011 if (chsize (&ins
->oprs
[c
-0300], bits
)) {
1013 out (offset
, segment
, bytes
,
1014 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1023 out (offset
, segment
, bytes
,
1024 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1033 out (offset
, segment
, bytes
,
1034 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1046 out (offset
, segment
, bytes
,
1047 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1056 out (offset
, segment
, bytes
,
1057 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1067 *bytes
= *codes
++ ^ condval
[ins
->condition
];
1068 out (offset
, segment
, bytes
,
1069 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1079 out (offset
, segment
, bytes
,
1080 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1084 case 0340: case 0341: case 0342:
1085 if (ins
->oprs
[0].segment
!= NO_SEG
)
1086 errfunc (ERR_PANIC
, "non-constant BSS size in pass two");
1088 long size
= ins
->oprs
[0].offset
<< (c
-0340);
1090 out (offset
, segment
, NULL
,
1091 OUT_RESERVE
+size
, NO_SEG
, NO_SEG
);
1096 case 0370: case 0371: case 0372:
1100 *bytes
= bits
==16 ? 3 : 5;
1101 out (offset
, segment
, bytes
,
1102 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1106 default: /* can't do it by 'case' statements */
1107 if (c
>=0100 && c
<=0277) { /* it's an EA */
1113 if (c
<=0177) /* pick rfield from operand b */
1114 rfield
= regval (&ins
->oprs
[c
&7]);
1115 else /* rfield is constant */
1118 if (!process_ea (&ins
->oprs
[(c
>>3)&7], &ea_data
, bits
, rfield
,
1121 errfunc (ERR_NONFATAL
, "invalid effective address");
1125 *p
++ = ea_data
.modrm
;
1126 if (ea_data
.sib_present
)
1130 out (offset
, segment
, bytes
, OUT_RAWDATA
+ s
,
1133 switch (ea_data
.bytes
) {
1137 if (ins
->oprs
[(c
>>3)&7].segment
!= NO_SEG
) {
1138 data
= ins
->oprs
[(c
>>3)&7].offset
;
1139 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
1140 ins
->oprs
[(c
>>3)&7].segment
,
1141 ins
->oprs
[(c
>>3)&7].wrt
);
1143 *bytes
= ins
->oprs
[(c
>>3)&7].offset
;
1144 out (offset
, segment
, bytes
, OUT_RAWDATA
+1,
1151 data
= ins
->oprs
[(c
>>3)&7].offset
;
1152 out (offset
, segment
, &data
,
1153 OUT_ADDRESS
+ea_data
.bytes
,
1154 ins
->oprs
[(c
>>3)&7].segment
, ins
->oprs
[(c
>>3)&7].wrt
);
1160 errfunc (ERR_PANIC
, "internal instruction table corrupt"
1161 ": instruction code 0x%02X given", c
);
1165 #include "regvals.c"
1167 static int regval (operand
*o
)
1169 if ( o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1170 errfunc (ERR_PANIC
, "invalid operand passed to regval()");
1172 return regvals
[o
->basereg
];
1175 static int matches (struct itemplate
*itemp
, insn
*instruction
)
1177 int i
, size
[3], asize
, oprs
, ret
;
1184 if (itemp
->opcode
!= instruction
->opcode
) return 0;
1187 * Count the operands
1189 if (itemp
->operands
!= instruction
->operands
) return 0;
1192 * Check that no spurious colons or TOs are present
1194 for (i
=0; i
<itemp
->operands
; i
++)
1195 if (instruction
->oprs
[i
].type
& ~itemp
->opd
[i
] & (COLON
|TO
))
1199 * Check that the operand flags all match up
1201 for (i
=0; i
<itemp
->operands
; i
++)
1202 if (itemp
->opd
[i
] & ~instruction
->oprs
[i
].type
||
1203 ((itemp
->opd
[i
] & SIZE_MASK
) &&
1204 ((itemp
->opd
[i
] ^ instruction
->oprs
[i
].type
) & SIZE_MASK
)))
1206 if ((itemp
->opd
[i
] & ~instruction
->oprs
[i
].type
& NON_SIZE
) ||
1207 (instruction
->oprs
[i
].type
& SIZE_MASK
))
1215 * Check operand sizes
1217 if (itemp
->flags
& IF_ARMASK
) {
1218 size
[0] = size
[1] = size
[2] = 0;
1220 switch (itemp
->flags
& IF_ARMASK
) {
1221 case IF_AR0
: i
= 0; break;
1222 case IF_AR1
: i
= 1; break;
1223 case IF_AR2
: i
= 2; break;
1224 default: break; /* Shouldn't happen */
1226 if (itemp
->flags
& IF_SB
) {
1228 } else if (itemp
->flags
& IF_SW
) {
1230 } else if (itemp
->flags
& IF_SD
) {
1235 if (itemp
->flags
& IF_SB
) {
1237 oprs
= itemp
->operands
;
1238 } else if (itemp
->flags
& IF_SW
) {
1240 oprs
= itemp
->operands
;
1241 } else if (itemp
->flags
& IF_SD
) {
1243 oprs
= itemp
->operands
;
1245 size
[0] = size
[1] = size
[2] = asize
;
1248 if (itemp
->flags
& (IF_SM
| IF_SM2
)) {
1249 oprs
= (itemp
->flags
& IF_SM2
? 2 : itemp
->operands
);
1251 for (i
=0; i
<oprs
; i
++) {
1252 if ( (asize
= itemp
->opd
[i
] & SIZE_MASK
) != 0) {
1254 for (j
=0; j
<oprs
; j
++)
1260 oprs
= itemp
->operands
;
1263 for (i
=0; i
<itemp
->operands
; i
++)
1264 if (!(itemp
->opd
[i
] & SIZE_MASK
) &&
1265 (instruction
->oprs
[i
].type
& SIZE_MASK
& ~size
[i
]))
1270 * Check template is okay at the set cpu level
1272 if ((itemp
->flags
& IF_PLEVEL
) > cpu
) return 3;
1275 * Check if special handling needed for Jumps
1277 if ((unsigned char)(itemp
->code
[0]) >= 0370) return 99;
1282 static ea
*process_ea (operand
*input
, ea
*output
, int addrbits
, int rfield
,
1285 if (!(REGISTER
& ~input
->type
)) { /* it's a single register */
1286 static int regs
[] = {
1287 R_AL
, R_CL
, R_DL
, R_BL
, R_AH
, R_CH
, R_DH
, R_BH
,
1288 R_AX
, R_CX
, R_DX
, R_BX
, R_SP
, R_BP
, R_SI
, R_DI
,
1289 R_EAX
, R_ECX
, R_EDX
, R_EBX
, R_ESP
, R_EBP
, R_ESI
, R_EDI
,
1290 R_MM0
, R_MM1
, R_MM2
, R_MM3
, R_MM4
, R_MM5
, R_MM6
, R_MM7
,
1291 R_XMM0
, R_XMM1
, R_XMM2
, R_XMM3
, R_XMM4
, R_XMM5
, R_XMM6
, R_XMM7
1295 for (i
=0; i
<elements(regs
); i
++)
1296 if (input
->basereg
== regs
[i
]) break;
1297 if (i
<elements(regs
)) {
1298 output
->sib_present
= FALSE
;/* no SIB necessary */
1299 output
->bytes
= 0; /* no offset necessary either */
1300 output
->modrm
= 0xC0 | (rfield
<< 3) | (i
& 7);
1304 } else { /* it's a memory reference */
1305 if (input
->basereg
==-1 && (input
->indexreg
==-1 || input
->scale
==0)) {
1306 /* it's a pure offset */
1307 if (input
->addr_size
)
1308 addrbits
= input
->addr_size
;
1309 output
->sib_present
= FALSE
;
1310 output
->bytes
= (addrbits
==32 ? 4 : 2);
1311 output
->modrm
= (addrbits
==32 ? 5 : 6) | (rfield
<< 3);
1313 else { /* it's an indirection */
1314 int i
=input
->indexreg
, b
=input
->basereg
, s
=input
->scale
;
1315 long o
=input
->offset
, seg
=input
->segment
;
1316 int hb
=input
->hintbase
, ht
=input
->hinttype
;
1319 if (s
==0) i
= -1; /* make this easy, at least */
1321 if (i
==R_EAX
|| i
==R_EBX
|| i
==R_ECX
|| i
==R_EDX
1322 || i
==R_EBP
|| i
==R_ESP
|| i
==R_ESI
|| i
==R_EDI
1323 || b
==R_EAX
|| b
==R_EBX
|| b
==R_ECX
|| b
==R_EDX
1324 || b
==R_EBP
|| b
==R_ESP
|| b
==R_ESI
|| b
==R_EDI
) {
1325 /* it must be a 32-bit memory reference. Firstly we have
1326 * to check that all registers involved are type Exx. */
1327 if (i
!=-1 && i
!=R_EAX
&& i
!=R_EBX
&& i
!=R_ECX
&& i
!=R_EDX
1328 && i
!=R_EBP
&& i
!=R_ESP
&& i
!=R_ESI
&& i
!=R_EDI
)
1330 if (b
!=-1 && b
!=R_EAX
&& b
!=R_EBX
&& b
!=R_ECX
&& b
!=R_EDX
1331 && b
!=R_EBP
&& b
!=R_ESP
&& b
!=R_ESI
&& b
!=R_EDI
)
1334 /* While we're here, ensure the user didn't specify WORD. */
1335 if (input
->addr_size
== 16)
1338 /* now reorganise base/index */
1339 if (s
== 1 && b
!= i
&& b
!= -1 && i
!= -1 &&
1340 ((hb
==b
&&ht
==EAH_NOTBASE
) || (hb
==i
&&ht
==EAH_MAKEBASE
)))
1341 t
= b
, b
= i
, i
= t
; /* swap if hints say so */
1342 if (b
==i
) /* convert EAX+2*EAX to 3*EAX */
1344 if (b
==-1 && s
==1 && !(hb
== i
&& ht
== EAH_NOTBASE
))
1345 b
= i
, i
= -1; /* make single reg base, unless hint */
1346 if (((s
==2 && i
!=R_ESP
&& !(input
->eaflags
& EAF_TIMESTWO
)) ||
1347 s
==3 || s
==5 || s
==9) && b
==-1)
1348 b
= i
, s
--; /* convert 3*EAX to EAX+2*EAX */
1349 if (i
==-1 && b
!=R_ESP
&& (input
->eaflags
& EAF_TIMESTWO
))
1350 i
= b
, b
= -1, s
= 1;
1351 /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */
1352 if (s
==1 && i
==R_ESP
) /* swap ESP into base if scale is 1 */
1354 if (i
==R_ESP
|| (s
!=1 && s
!=2 && s
!=4 && s
!=8 && i
!=-1))
1355 return NULL
; /* wrong, for various reasons */
1357 if (i
==-1 && b
!=R_ESP
) {/* no SIB needed */
1360 case R_EAX
: rm
= 0; break;
1361 case R_ECX
: rm
= 1; break;
1362 case R_EDX
: rm
= 2; break;
1363 case R_EBX
: rm
= 3; break;
1364 case R_EBP
: rm
= 5; break;
1365 case R_ESI
: rm
= 6; break;
1366 case R_EDI
: rm
= 7; break;
1367 case -1: rm
= 5; break;
1368 default: /* should never happen */
1371 if (b
==-1 || (b
!=R_EBP
&& o
==0 &&
1372 seg
==NO_SEG
&& !forw_ref
&&
1374 (EAF_BYTEOFFS
|EAF_WORDOFFS
))))
1376 else if (input
->eaflags
& EAF_BYTEOFFS
||
1377 (o
>=-128 && o
<=127 && seg
==NO_SEG
&& !forw_ref
&&
1378 !(input
->eaflags
& EAF_WORDOFFS
))) {
1384 output
->sib_present
= FALSE
;
1385 output
->bytes
= (b
==-1 || mod
==2 ? 4 : mod
);
1386 output
->modrm
= (mod
<<6) | (rfield
<<3) | rm
;
1388 else { /* we need a SIB */
1389 int mod
, scale
, index
, base
;
1392 case R_EAX
: base
= 0; break;
1393 case R_ECX
: base
= 1; break;
1394 case R_EDX
: base
= 2; break;
1395 case R_EBX
: base
= 3; break;
1396 case R_ESP
: base
= 4; break;
1397 case R_EBP
: case -1: base
= 5; break;
1398 case R_ESI
: base
= 6; break;
1399 case R_EDI
: base
= 7; break;
1400 default: /* then what the smeg is it? */
1401 return NULL
; /* panic */
1405 case R_EAX
: index
= 0; break;
1406 case R_ECX
: index
= 1; break;
1407 case R_EDX
: index
= 2; break;
1408 case R_EBX
: index
= 3; break;
1409 case -1: index
= 4; break;
1410 case R_EBP
: index
= 5; break;
1411 case R_ESI
: index
= 6; break;
1412 case R_EDI
: index
= 7; break;
1413 default: /* then what the smeg is it? */
1414 return NULL
; /* panic */
1419 case 1: scale
= 0; break;
1420 case 2: scale
= 1; break;
1421 case 4: scale
= 2; break;
1422 case 8: scale
= 3; break;
1423 default: /* then what the smeg is it? */
1424 return NULL
; /* panic */
1427 if (b
==-1 || (b
!=R_EBP
&& o
==0 &&
1428 seg
==NO_SEG
&& !forw_ref
&&
1430 (EAF_BYTEOFFS
|EAF_WORDOFFS
))))
1432 else if (input
->eaflags
& EAF_BYTEOFFS
||
1433 (o
>=-128 && o
<=127 && seg
==NO_SEG
&& !forw_ref
&&
1434 !(input
->eaflags
& EAF_WORDOFFS
)))
1439 output
->sib_present
= TRUE
;
1440 output
->bytes
= (b
==-1 || mod
==2 ? 4 : mod
);
1441 output
->modrm
= (mod
<<6) | (rfield
<<3) | 4;
1442 output
->sib
= (scale
<<6) | (index
<<3) | base
;
1445 else { /* it's 16-bit */
1448 /* check all registers are BX, BP, SI or DI */
1449 if ((b
!=-1 && b
!=R_BP
&& b
!=R_BX
&& b
!=R_SI
&& b
!=R_DI
) ||
1450 (i
!=-1 && i
!=R_BP
&& i
!=R_BX
&& i
!=R_SI
&& i
!=R_DI
))
1453 /* ensure the user didn't specify DWORD */
1454 if (input
->addr_size
== 32)
1457 if (s
!=1 && i
!=-1) return NULL
;/* no can do, in 16-bit EA */
1458 if (b
==-1 && i
!=-1) { int tmp
= b
; b
= i
; i
= tmp
; } /* swap */
1459 if ((b
==R_SI
|| b
==R_DI
) && i
!=-1)
1460 { int tmp
= b
; b
= i
; i
= tmp
; }
1461 /* have BX/BP as base, SI/DI index */
1462 if (b
==i
) return NULL
;/* shouldn't ever happen, in theory */
1463 if (i
!=-1 && b
!=-1 &&
1464 (i
==R_BP
|| i
==R_BX
|| b
==R_SI
|| b
==R_DI
))
1465 return NULL
; /* invalid combinations */
1466 if (b
==-1) /* pure offset: handled above */
1467 return NULL
; /* so if it gets to here, panic! */
1471 switch (i
*256 + b
) {
1472 case R_SI
*256+R_BX
: rm
=0; break;
1473 case R_DI
*256+R_BX
: rm
=1; break;
1474 case R_SI
*256+R_BP
: rm
=2; break;
1475 case R_DI
*256+R_BP
: rm
=3; break;
1479 case R_SI
: rm
=4; break;
1480 case R_DI
: rm
=5; break;
1481 case R_BP
: rm
=6; break;
1482 case R_BX
: rm
=7; break;
1484 if (rm
==-1) /* can't happen, in theory */
1485 return NULL
; /* so panic if it does */
1487 if (o
==0 && seg
==NO_SEG
&& !forw_ref
&& rm
!=6 &&
1488 !(input
->eaflags
& (EAF_BYTEOFFS
|EAF_WORDOFFS
)))
1490 else if (input
->eaflags
& EAF_BYTEOFFS
||
1491 (o
>=-128 && o
<=127 && seg
==NO_SEG
&& !forw_ref
&&
1492 !(input
->eaflags
& EAF_WORDOFFS
)))
1497 output
->sib_present
= FALSE
; /* no SIB - it's 16-bit */
1498 output
->bytes
= mod
; /* bytes of offset needed */
1499 output
->modrm
= (mod
<<6) | (rfield
<<3) | rm
;
1503 output
->size
= 1 + output
->sib_present
+ output
->bytes
;
1507 static int chsize (operand
*input
, int addrbits
)
1509 if (!(MEMORY
& ~input
->type
)) {
1510 int i
=input
->indexreg
, b
=input
->basereg
;
1512 if (input
->scale
==0) i
= -1;
1514 if (i
== -1 && b
== -1) /* pure offset */
1515 return (input
->addr_size
!= 0 && input
->addr_size
!= addrbits
);
1517 if (i
==R_EAX
|| i
==R_EBX
|| i
==R_ECX
|| i
==R_EDX
1518 || i
==R_EBP
|| i
==R_ESP
|| i
==R_ESI
|| i
==R_EDI
1519 || b
==R_EAX
|| b
==R_EBX
|| b
==R_ECX
|| b
==R_EDX
1520 || b
==R_EBP
|| b
==R_ESP
|| b
==R_ESI
|| b
==R_EDI
)
1521 return (addrbits
==16);
1523 return (addrbits
==32);