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], \4[012] and \5[456]
29 * depending on assembly mode or the address-size override
31 * \50, \51, \52 - a byte relative operand, from operand 0, 1 or 2
32 * \54, \55, \56 - a qword immediate operand, from operand 0, 1 or 2
33 * \60, \61, \62 - a word relative operand, from operand 0, 1 or 2
34 * \64, \65, \66 - select between \6[012] and \7[012] depending on 16/32 bit
35 * assembly mode or the operand-size override on the operand
36 * \70, \71, \72 - a long relative operand, from operand 0, 1 or 2
37 * \1ab - a ModRM, calculated on EA in operand a, with the spare
38 * field the register value of operand b.
39 * \130,\131,\132 - an immediate word or signed byte for operand 0, 1, or 2
40 * \133,\134,\135 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
41 * is a signed byte rather than a word.
42 * \140,\141,\142 - an immediate dword or signed byte for operand 0, 1, or 2
43 * \143,\144,\145 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
44 * is a signed byte rather than a dword.
45 * \150,\151,\152 - an immediate qword or signed byte for operand 0, 1, or 2
46 * \153,\154,\155 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
47 * is a signed byte rather than a qword.
48 * \2ab - a ModRM, calculated on EA in operand a, with the spare
49 * field equal to digit b.
50 * \30x - might be an 0x67 byte, depending on the address size of
51 * the memory reference in operand x.
52 * \310 - indicates fixed 16-bit address size, i.e. optional 0x67.
53 * \311 - indicates fixed 32-bit address size, i.e. optional 0x67.
54 * \312 - (disassembler only) marker on LOOP, LOOPxx instructions.
55 * \313 - indicates fixed 64-bit address size, 0x67 invalid.
56 * \320 - indicates fixed 16-bit operand size, i.e. optional 0x66.
57 * \321 - indicates fixed 32-bit operand size, i.e. optional 0x66.
58 * \322 - indicates that this instruction is only valid when the
59 * operand size is the default (instruction to disassembler,
60 * generates no code in the assembler)
61 * \323 - indicates fixed 64-bit operand size, REX on extensions only.
62 * \324 - indicates 64-bit operand size requiring REX prefix.
63 * \330 - a literal byte follows in the code stream, to be added
64 * to the condition code value of the instruction.
65 * \331 - instruction not valid with REP prefix. Hint for
66 * disassembler only; for SSE instructions.
67 * \332 - disassemble a rep (0xF3 byte) prefix as repe not rep.
68 * \333 - REP prefix (0xF3 byte); for SSE instructions. Not encoded
69 * as a literal byte in order to aid the disassembler.
70 * \334 - LOCK prefix used instead of REX.R
71 * \340 - reserve <operand 0> bytes of uninitialized storage.
72 * Operand 0 had better be a segmentless constant.
73 * \366 - operand-size override prefix (0x66); to ensure proper
75 * \370,\371,\372 - match only if operand 0 meets byte jump criteria.
76 * 370 is used for Jcc, 371 is used for JMP.
77 * \373 - assemble 0x03 if bits==16, 0x05 if bits==32;
78 * used for conditional jump over longer jump
93 extern struct itemplate
*nasm_instructions
[];
96 int sib_present
; /* is a SIB byte necessary? */
97 int bytes
; /* # of bytes of offset needed */
98 int size
; /* lazy - this is sib+bytes+1 */
99 uint8_t modrm
, sib
, rex
, rip
; /* the bytes themselves */
102 static uint32_t cpu
; /* cpu level received from nasm.c */
103 static efunc errfunc
;
104 static struct ofmt
*outfmt
;
105 static ListGen
*list
;
107 static int32_t calcsize(int32_t, int32_t, int, insn
*, const char *);
108 static void gencode(int32_t, int32_t, int, insn
*, const char *, int32_t);
109 static int matches(struct itemplate
*, insn
*, int bits
);
110 static int32_t regflag(const operand
*);
111 static int32_t regval(const operand
*);
112 static int rexflags(int, int32_t, int);
113 static int op_rexflags(const operand
*, int);
114 static ea
*process_ea(operand
*, ea
*, int, int, int32_t, int);
115 static int chsize(operand
*, int);
117 static void assert_no_prefix(insn
* ins
, int prefix
)
121 for (j
= 0; j
< ins
->nprefix
; j
++) {
122 if (ins
->prefixes
[j
] == prefix
) {
123 errfunc(ERR_NONFATAL
, "invalid %s prefix", prefix_name(prefix
));
130 * This routine wrappers the real output format's output routine,
131 * in order to pass a copy of the data off to the listing file
132 * generator at the same time.
134 static void out(int32_t offset
, int32_t segto
, const void *data
,
135 uint32_t type
, int32_t segment
, int32_t wrt
)
137 static int32_t lineno
= 0; /* static!!! */
138 static char *lnfname
= NULL
;
140 if ((type
& OUT_TYPMASK
) == OUT_ADDRESS
) {
141 if (segment
!= NO_SEG
|| wrt
!= NO_SEG
) {
143 * This address is relocated. We must write it as
144 * OUT_ADDRESS, so there's no work to be done here.
146 list
->output(offset
, data
, type
);
148 uint8_t p
[8], *q
= p
;
150 * This is a non-relocated address, and we're going to
151 * convert it into RAWDATA format.
153 if ((type
& OUT_SIZMASK
) == 4) {
154 WRITELONG(q
, *(int32_t *)data
);
155 list
->output(offset
, p
, OUT_RAWDATA
+ 4);
156 } else if ((type
& OUT_SIZMASK
) == 8) {
157 WRITEDLONG(q
, *(int64_t *)data
);
158 list
->output(offset
, p
, OUT_RAWDATA
+ 8);
160 WRITESHORT(q
, *(int32_t *)data
);
161 list
->output(offset
, p
, OUT_RAWDATA
+ 2);
164 } else if ((type
& OUT_TYPMASK
) == OUT_RAWDATA
) {
165 list
->output(offset
, data
, type
);
166 } else if ((type
& OUT_TYPMASK
) == OUT_RESERVE
) {
167 list
->output(offset
, NULL
, type
);
168 } else if ((type
& OUT_TYPMASK
) == OUT_REL2ADR
||
169 (type
& OUT_TYPMASK
) == OUT_REL4ADR
) {
170 list
->output(offset
, data
, type
);
174 * this call to src_get determines when we call the
175 * debug-format-specific "linenum" function
176 * it updates lineno and lnfname to the current values
177 * returning 0 if "same as last time", -2 if lnfname
178 * changed, and the amount by which lineno changed,
179 * if it did. thus, these variables must be static
182 if (src_get(&lineno
, &lnfname
)) {
183 outfmt
->current_dfmt
->linenum(lnfname
, lineno
, segto
);
186 outfmt
->output(segto
, data
, type
, segment
, wrt
);
189 static int jmp_match(int32_t segment
, int32_t offset
, int bits
,
190 insn
* ins
, const char *code
)
195 if (c
!= 0370 && c
!= 0371)
197 if (ins
->oprs
[0].opflags
& OPFLAG_FORWARD
) {
198 if ((optimizing
< 0 || (ins
->oprs
[0].type
& STRICT
))
202 return (pass0
== 0); /* match a forward reference */
204 isize
= calcsize(segment
, offset
, bits
, ins
, code
);
205 if (ins
->oprs
[0].segment
!= segment
)
207 isize
= ins
->oprs
[0].offset
- offset
- isize
; /* isize is now the delta */
208 if (isize
>= -128L && isize
<= 127L)
209 return 1; /* it is byte size */
214 int32_t assemble(int32_t segment
, int32_t offset
, int bits
, uint32_t cp
,
215 insn
* instruction
, struct ofmt
*output
, efunc error
,
218 struct itemplate
*temp
;
223 int32_t start
= offset
;
224 int32_t wsize
= 0; /* size for DB etc. */
226 errfunc
= error
; /* to pass to other functions */
228 outfmt
= output
; /* likewise */
229 list
= listgen
; /* and again */
231 switch (instruction
->opcode
) {
253 int32_t t
= instruction
->times
;
256 "instruction->times < 0 (%ld) in assemble()", t
);
258 while (t
--) { /* repeat TIMES times */
259 for (e
= instruction
->eops
; e
; e
= e
->next
) {
260 if (e
->type
== EOT_DB_NUMBER
) {
262 if (e
->segment
!= NO_SEG
)
263 errfunc(ERR_NONFATAL
,
264 "one-byte relocation attempted");
266 uint8_t out_byte
= e
->offset
;
267 out(offset
, segment
, &out_byte
,
268 OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
270 } else if (wsize
> 8) {
271 errfunc(ERR_NONFATAL
, "integer supplied to a DT"
274 out(offset
, segment
, &e
->offset
,
275 OUT_ADDRESS
+ wsize
, e
->segment
, e
->wrt
);
277 } else if (e
->type
== EOT_DB_STRING
) {
280 out(offset
, segment
, e
->stringval
,
281 OUT_RAWDATA
+ e
->stringlen
, NO_SEG
, NO_SEG
);
282 align
= e
->stringlen
% wsize
;
285 align
= wsize
- align
;
286 out(offset
, segment
, "\0\0\0\0\0\0\0\0",
287 OUT_RAWDATA
+ align
, NO_SEG
, NO_SEG
);
289 offset
+= e
->stringlen
+ align
;
292 if (t
> 0 && t
== instruction
->times
- 1) {
294 * Dummy call to list->output to give the offset to the
297 list
->output(offset
, NULL
, OUT_RAWDATA
);
298 list
->uplevel(LIST_TIMES
);
301 if (instruction
->times
> 1)
302 list
->downlevel(LIST_TIMES
);
303 return offset
- start
;
306 if (instruction
->opcode
== I_INCBIN
) {
307 static char fname
[FILENAME_MAX
];
310 char *prefix
= "", *combine
;
311 char **pPrevPath
= NULL
;
313 len
= FILENAME_MAX
- 1;
314 if (len
> instruction
->eops
->stringlen
)
315 len
= instruction
->eops
->stringlen
;
316 strncpy(fname
, instruction
->eops
->stringval
, len
);
319 while (1) { /* added by alexfru: 'incbin' uses include paths */
320 combine
= nasm_malloc(strlen(prefix
) + len
+ 1);
321 strcpy(combine
, prefix
);
322 strcat(combine
, fname
);
324 if ((fp
= fopen(combine
, "rb")) != NULL
) {
330 pPrevPath
= pp_get_include_path_ptr(pPrevPath
);
331 if (pPrevPath
== NULL
)
337 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
339 else if (fseek(fp
, 0L, SEEK_END
) < 0)
340 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
343 static char buf
[2048];
344 int32_t t
= instruction
->times
;
348 if (instruction
->eops
->next
) {
349 base
= instruction
->eops
->next
->offset
;
351 if (instruction
->eops
->next
->next
&&
352 len
> instruction
->eops
->next
->next
->offset
)
353 len
= instruction
->eops
->next
->next
->offset
;
356 * Dummy call to list->output to give the offset to the
359 list
->output(offset
, NULL
, OUT_RAWDATA
);
360 list
->uplevel(LIST_INCBIN
);
364 fseek(fp
, base
, SEEK_SET
);
368 fread(buf
, 1, (l
> sizeof(buf
) ? sizeof(buf
) : l
),
372 * This shouldn't happen unless the file
373 * actually changes while we are reading
377 "`incbin': unexpected EOF while"
378 " reading file `%s'", fname
);
379 t
= 0; /* Try to exit cleanly */
382 out(offset
, segment
, buf
, OUT_RAWDATA
+ m
,
387 list
->downlevel(LIST_INCBIN
);
388 if (instruction
->times
> 1) {
390 * Dummy call to list->output to give the offset to the
393 list
->output(offset
, NULL
, OUT_RAWDATA
);
394 list
->uplevel(LIST_TIMES
);
395 list
->downlevel(LIST_TIMES
);
398 return instruction
->times
* len
;
400 return 0; /* if we're here, there's an error */
405 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++){
406 int m
= matches(temp
, instruction
, bits
);
409 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
411 if (m
== 100) { /* matches! */
412 const char *codes
= temp
->code
;
413 int32_t insn_size
= calcsize(segment
, offset
, bits
,
415 itimes
= instruction
->times
;
416 if (insn_size
< 0) /* shouldn't be, on pass two */
417 error(ERR_PANIC
, "errors made it through from pass one");
420 for (j
= 0; j
< instruction
->nprefix
; j
++) {
422 switch (instruction
->prefixes
[j
]) {
438 "cs segment base ignored in 64-bit mode");
445 "ds segment base ignored in 64-bit mode");
452 "es segment base ignored in 64-bit mode");
465 "ss segment base ignored in 64-bit mode");
472 "segr6 and segr7 cannot be used as prefixes");
477 "16-bit addressing is not supported "
497 error(ERR_PANIC
, "invalid instruction prefix");
500 out(offset
, segment
, &c
, OUT_RAWDATA
+ 1,
505 insn_end
= offset
+ insn_size
;
506 gencode(segment
, offset
, bits
, instruction
, codes
,
509 if (itimes
> 0 && itimes
== instruction
->times
- 1) {
511 * Dummy call to list->output to give the offset to the
514 list
->output(offset
, NULL
, OUT_RAWDATA
);
515 list
->uplevel(LIST_TIMES
);
518 if (instruction
->times
> 1)
519 list
->downlevel(LIST_TIMES
);
520 return offset
- start
;
521 } else if (m
> 0 && m
> size_prob
) {
527 if (temp
->opcode
== -1) { /* didn't match any instruction */
530 error(ERR_NONFATAL
, "operation size not specified");
533 error(ERR_NONFATAL
, "mismatch in operand sizes");
536 error(ERR_NONFATAL
, "no instruction for this cpu level");
539 error(ERR_NONFATAL
, "instruction not supported in 64-bit mode");
543 "invalid combination of opcode and operands");
550 int32_t insn_size(int32_t segment
, int32_t offset
, int bits
, uint32_t cp
,
551 insn
* instruction
, efunc error
)
553 struct itemplate
*temp
;
555 errfunc
= error
; /* to pass to other functions */
558 if (instruction
->opcode
== -1)
561 if (instruction
->opcode
== I_DB
||
562 instruction
->opcode
== I_DW
||
563 instruction
->opcode
== I_DD
||
564 instruction
->opcode
== I_DQ
|| instruction
->opcode
== I_DT
) {
566 int32_t isize
, osize
, wsize
= 0; /* placate gcc */
569 switch (instruction
->opcode
) {
587 for (e
= instruction
->eops
; e
; e
= e
->next
) {
591 if (e
->type
== EOT_DB_NUMBER
)
593 else if (e
->type
== EOT_DB_STRING
)
594 osize
= e
->stringlen
;
596 align
= (-osize
) % wsize
;
599 isize
+= osize
+ align
;
601 return isize
* instruction
->times
;
604 if (instruction
->opcode
== I_INCBIN
) {
605 char fname
[FILENAME_MAX
];
608 char *prefix
= "", *combine
;
609 char **pPrevPath
= NULL
;
611 len
= FILENAME_MAX
- 1;
612 if (len
> instruction
->eops
->stringlen
)
613 len
= instruction
->eops
->stringlen
;
614 strncpy(fname
, instruction
->eops
->stringval
, len
);
617 while (1) { /* added by alexfru: 'incbin' uses include paths */
618 combine
= nasm_malloc(strlen(prefix
) + len
+ 1);
619 strcpy(combine
, prefix
);
620 strcat(combine
, fname
);
622 if ((fp
= fopen(combine
, "rb")) != NULL
) {
628 pPrevPath
= pp_get_include_path_ptr(pPrevPath
);
629 if (pPrevPath
== NULL
)
635 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
637 else if (fseek(fp
, 0L, SEEK_END
) < 0)
638 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
643 if (instruction
->eops
->next
) {
644 len
-= instruction
->eops
->next
->offset
;
645 if (instruction
->eops
->next
->next
&&
646 len
> instruction
->eops
->next
->next
->offset
) {
647 len
= instruction
->eops
->next
->next
->offset
;
650 return instruction
->times
* len
;
652 return 0; /* if we're here, there's an error */
655 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++) {
656 int m
= matches(temp
, instruction
, bits
);
658 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
661 /* we've matched an instruction. */
663 const char *codes
= temp
->code
;
666 isize
= calcsize(segment
, offset
, bits
, instruction
, codes
);
669 for (j
= 0; j
< instruction
->nprefix
; j
++) {
670 if ((instruction
->prefixes
[j
] != P_A16
&&
671 instruction
->prefixes
[j
] != P_O16
&& bits
== 16) ||
672 (instruction
->prefixes
[j
] != P_A32
&&
673 instruction
->prefixes
[j
] != P_O32
&& bits
>= 32)) {
677 return isize
* instruction
->times
;
680 return -1; /* didn't match any instruction */
683 /* check that opn[op] is a signed byte of size 16 or 32,
684 and return the signed value*/
685 static int is_sbyte(insn
* ins
, int op
, int size
)
690 ret
= !(ins
->forw_ref
&& ins
->oprs
[op
].opflags
) && /* dead in the water on forward reference or External */
692 !(ins
->oprs
[op
].type
& STRICT
) &&
693 ins
->oprs
[op
].wrt
== NO_SEG
&& ins
->oprs
[op
].segment
== NO_SEG
;
695 v
= ins
->oprs
[op
].offset
;
697 v
= (int16_t)v
; /* sign extend if 16 bits */
699 return ret
&& v
>= -128L && v
<= 127L;
702 static int32_t calcsize(int32_t segment
, int32_t offset
, int bits
,
703 insn
* ins
, const char *codes
)
708 ins
->rex
= 0; /* Ensure REX is reset */
710 (void)segment
; /* Don't warn that this parameter is unused */
711 (void)offset
; /* Don't warn that this parameter is unused */
714 switch (c
= *codes
++) {
718 codes
+= c
, length
+= c
;
730 op_rexflags(&ins
->oprs
[c
- 010], REX_B
|REX_H
|REX_P
|REX_W
);
759 if (ins
->oprs
[c
- 034].type
& (BITS16
| BITS32
| BITS64
))
760 length
+= (ins
->oprs
[c
- 034].type
& BITS16
) ? 2 : 4;
762 length
+= (bits
== 16) ? 2 : 4;
775 length
+= ((ins
->oprs
[c
- 044].addr_size
?
776 ins
->oprs
[c
- 044].addr_size
: bits
) >> 3);
786 length
+= 8; /* MOV reg64/imm */
796 if (ins
->oprs
[c
- 064].type
& (BITS16
| BITS32
| BITS64
))
797 length
+= (ins
->oprs
[c
- 064].type
& BITS16
) ? 2 : 4;
799 length
+= (bits
== 16) ? 2 : 4;
809 length
+= is_sbyte(ins
, c
- 0130, 16) ? 1 : 2;
820 length
+= is_sbyte(ins
, c
- 0140, 32) ? 1 : 4;
831 length
+= chsize(&ins
->oprs
[c
- 0300], bits
);
834 length
+= (bits
!= 16);
837 length
+= (bits
!= 32);
844 length
+= (bits
!= 16);
847 length
+= (bits
== 16);
867 assert_no_prefix(ins
, P_LOCK
);
873 if (ins
->oprs
[0].segment
!= NO_SEG
)
874 errfunc(ERR_NONFATAL
, "attempt to reserve non-constant"
875 " quantity of BSS space");
877 length
+= ins
->oprs
[0].offset
<< (c
- 0340);
889 default: /* can't do it by 'case' statements */
890 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
894 ea_data
.rex
= 0; /* Ensure ea.REX is initially 0 */
897 /* pick rfield from operand b */
898 rflags
= regflag(&ins
->oprs
[c
& 7]);
899 rfield
= regvals
[ins
->oprs
[c
& 7].basereg
];
906 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
907 rfield
, rflags
, ins
->forw_ref
)) {
908 errfunc(ERR_NONFATAL
, "invalid effective address");
911 ins
->rex
|= ea_data
.rex
;
912 length
+= ea_data
.size
;
915 errfunc(ERR_PANIC
, "internal instruction table corrupt"
916 ": instruction code 0x%02X given", c
);
919 ins
->rex
&= rex_mask
;
920 if (ins
->rex
& REX_REAL
) {
921 if (ins
->rex
& REX_H
) {
922 errfunc(ERR_NONFATAL
, "cannot use high register in rex instruction");
924 } else if (bits
== 64 ||
925 ((ins
->rex
& REX_L
) &&
926 !(ins
->rex
& (REX_P
|REX_W
|REX_X
|REX_B
)) &&
930 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
939 if((ins->rex & REX_REAL) && (bits == 64)) { \
940 ins->rex = (ins->rex & REX_REAL)|REX_P; \
941 out(offset, segment, &ins->rex, OUT_RAWDATA+1, NO_SEG, NO_SEG); \
946 static void gencode(int32_t segment
, int32_t offset
, int bits
,
947 insn
* ins
, const char *codes
, int32_t insn_end
)
949 static char condval
[] = { /* conditional opcodes */
950 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
951 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
952 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
960 switch (c
= *codes
++) {
965 out(offset
, segment
, codes
, OUT_RAWDATA
+ c
, NO_SEG
, NO_SEG
);
972 switch (ins
->oprs
[0].basereg
) {
974 bytes
[0] = 0x0E + (c
== 0x04 ? 1 : 0);
977 bytes
[0] = 0x1E + (c
== 0x04 ? 1 : 0);
980 bytes
[0] = 0x06 + (c
== 0x04 ? 1 : 0);
983 bytes
[0] = 0x16 + (c
== 0x04 ? 1 : 0);
987 "bizarre 8086 segment register received");
989 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
995 switch (ins
->oprs
[0].basereg
) {
997 bytes
[0] = 0xA0 + (c
== 0x05 ? 1 : 0);
1000 bytes
[0] = 0xA8 + (c
== 0x05 ? 1 : 0);
1004 "bizarre 386 segment register received");
1006 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1014 bytes
[0] = *codes
++ + ((regval(&ins
->oprs
[c
- 010])) & 7);
1015 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1021 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1028 if (ins
->oprs
[c
- 014].offset
< -128
1029 || ins
->oprs
[c
- 014].offset
> 127) {
1030 errfunc(ERR_WARNING
, "signed byte value exceeds bounds");
1033 if (ins
->oprs
[c
- 014].segment
!= NO_SEG
) {
1034 data
= ins
->oprs
[c
- 014].offset
;
1035 out(offset
, segment
, &data
, OUT_ADDRESS
+ 1,
1036 ins
->oprs
[c
- 014].segment
, ins
->oprs
[c
- 014].wrt
);
1038 bytes
[0] = ins
->oprs
[c
- 014].offset
;
1039 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
,
1048 if (ins
->oprs
[c
- 020].offset
< -256
1049 || ins
->oprs
[c
- 020].offset
> 255) {
1050 errfunc(ERR_WARNING
, "byte value exceeds bounds");
1052 if (ins
->oprs
[c
- 020].segment
!= NO_SEG
) {
1053 data
= ins
->oprs
[c
- 020].offset
;
1054 out(offset
, segment
, &data
, OUT_ADDRESS
+ 1,
1055 ins
->oprs
[c
- 020].segment
, ins
->oprs
[c
- 020].wrt
);
1057 bytes
[0] = ins
->oprs
[c
- 020].offset
;
1058 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
,
1067 if (ins
->oprs
[c
- 024].offset
< 0
1068 || ins
->oprs
[c
- 024].offset
> 255)
1069 errfunc(ERR_WARNING
, "unsigned byte value exceeds bounds");
1070 if (ins
->oprs
[c
- 024].segment
!= NO_SEG
) {
1071 data
= ins
->oprs
[c
- 024].offset
;
1072 out(offset
, segment
, &data
, OUT_ADDRESS
+ 1,
1073 ins
->oprs
[c
- 024].segment
, ins
->oprs
[c
- 024].wrt
);
1075 bytes
[0] = ins
->oprs
[c
- 024].offset
;
1076 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
,
1085 if (ins
->oprs
[c
- 030].segment
== NO_SEG
&&
1086 ins
->oprs
[c
- 030].wrt
== NO_SEG
&&
1087 (ins
->oprs
[c
- 030].offset
< -65536L ||
1088 ins
->oprs
[c
- 030].offset
> 65535L)) {
1089 errfunc(ERR_WARNING
, "word value exceeds bounds");
1091 data
= ins
->oprs
[c
- 030].offset
;
1092 out(offset
, segment
, &data
, OUT_ADDRESS
+ 2,
1093 ins
->oprs
[c
- 030].segment
, ins
->oprs
[c
- 030].wrt
);
1100 if (ins
->oprs
[c
- 034].type
& (BITS16
| BITS32
))
1101 size
= (ins
->oprs
[c
- 034].type
& BITS16
) ? 2 : 4;
1103 size
= (bits
== 16) ? 2 : 4;
1104 data
= ins
->oprs
[c
- 034].offset
;
1105 if (size
== 2 && (data
< -65536L || data
> 65535L))
1106 errfunc(ERR_WARNING
, "word value exceeds bounds");
1107 out(offset
, segment
, &data
, OUT_ADDRESS
+ size
,
1108 ins
->oprs
[c
- 034].segment
, ins
->oprs
[c
- 034].wrt
);
1113 if (ins
->oprs
[0].segment
== NO_SEG
)
1114 errfunc(ERR_NONFATAL
, "value referenced by FAR is not"
1117 out(offset
, segment
, &data
, OUT_ADDRESS
+ 2,
1118 outfmt
->segbase(1 + ins
->oprs
[0].segment
),
1126 data
= ins
->oprs
[c
- 040].offset
;
1127 out(offset
, segment
, &data
, OUT_ADDRESS
+ 4,
1128 ins
->oprs
[c
- 040].segment
, ins
->oprs
[c
- 040].wrt
);
1135 data
= ins
->oprs
[c
- 044].offset
;
1136 size
= ((ins
->oprs
[c
- 044].addr_size
?
1137 ins
->oprs
[c
- 044].addr_size
: bits
) >> 3);
1138 if (size
== 2 && (data
< -65536L || data
> 65535L))
1139 errfunc(ERR_WARNING
, "word value exceeds bounds");
1140 out(offset
, segment
, &data
, OUT_ADDRESS
+ size
,
1141 ins
->oprs
[c
- 044].segment
, ins
->oprs
[c
- 044].wrt
);
1148 if (ins
->oprs
[c
- 050].segment
!= segment
)
1149 errfunc(ERR_NONFATAL
,
1150 "short relative jump outside segment");
1151 data
= ins
->oprs
[c
- 050].offset
- insn_end
;
1152 if (data
> 127 || data
< -128)
1153 errfunc(ERR_NONFATAL
, "short jump is out of range");
1155 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1162 data
= (int64_t)ins
->oprs
[c
- 054].offset
;
1163 out(offset
, segment
, &data
, OUT_ADDRESS
+ 8,
1164 ins
->oprs
[c
- 054].segment
, ins
->oprs
[c
- 054].wrt
);
1171 if (ins
->oprs
[c
- 060].segment
!= segment
) {
1172 data
= ins
->oprs
[c
- 060].offset
;
1173 out(offset
, segment
, &data
,
1174 OUT_REL2ADR
+ insn_end
- offset
,
1175 ins
->oprs
[c
- 060].segment
, ins
->oprs
[c
- 060].wrt
);
1177 data
= ins
->oprs
[c
- 060].offset
- insn_end
;
1178 out(offset
, segment
, &data
,
1179 OUT_ADDRESS
+ 2, NO_SEG
, NO_SEG
);
1187 if (ins
->oprs
[c
- 064].type
& (BITS16
| BITS32
| BITS64
))
1188 size
= (ins
->oprs
[c
- 064].type
& BITS16
) ? 2 : 4;
1190 size
= (bits
== 16) ? 2 : 4;
1191 if (ins
->oprs
[c
- 064].segment
!= segment
) {
1192 int32_t reltype
= (size
== 2 ? OUT_REL2ADR
: OUT_REL4ADR
);
1193 data
= ins
->oprs
[c
- 064].offset
;
1194 out(offset
, segment
, &data
, reltype
+ insn_end
- offset
,
1195 ins
->oprs
[c
- 064].segment
, ins
->oprs
[c
- 064].wrt
);
1197 data
= ins
->oprs
[c
- 064].offset
- insn_end
;
1198 out(offset
, segment
, &data
,
1199 OUT_ADDRESS
+ size
, NO_SEG
, NO_SEG
);
1207 if (ins
->oprs
[c
- 070].segment
!= segment
) {
1208 data
= ins
->oprs
[c
- 070].offset
;
1209 out(offset
, segment
, &data
,
1210 OUT_REL4ADR
+ insn_end
- offset
,
1211 ins
->oprs
[c
- 070].segment
, ins
->oprs
[c
- 070].wrt
);
1213 data
= ins
->oprs
[c
- 070].offset
- insn_end
;
1214 out(offset
, segment
, &data
,
1215 OUT_ADDRESS
+ 4, NO_SEG
, NO_SEG
);
1223 data
= ins
->oprs
[c
- 0130].offset
;
1224 if (is_sbyte(ins
, c
- 0130, 16)) {
1226 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
,
1230 if (ins
->oprs
[c
- 0130].segment
== NO_SEG
&&
1231 ins
->oprs
[c
- 0130].wrt
== NO_SEG
&&
1232 (data
< -65536L || data
> 65535L)) {
1233 errfunc(ERR_WARNING
, "word value exceeds bounds");
1235 out(offset
, segment
, &data
, OUT_ADDRESS
+ 2,
1236 ins
->oprs
[c
- 0130].segment
, ins
->oprs
[c
- 0130].wrt
);
1246 bytes
[0] = *codes
++;
1247 if (is_sbyte(ins
, c
- 0133, 16))
1248 bytes
[0] |= 2; /* s-bit */
1249 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1256 data
= ins
->oprs
[c
- 0140].offset
;
1257 if (is_sbyte(ins
, c
- 0140, 32)) {
1259 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
,
1263 out(offset
, segment
, &data
, OUT_ADDRESS
+ 4,
1264 ins
->oprs
[c
- 0140].segment
, ins
->oprs
[c
- 0140].wrt
);
1274 bytes
[0] = *codes
++;
1275 if (is_sbyte(ins
, c
- 0143, 32))
1276 bytes
[0] |= 2; /* s-bit */
1277 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1284 if (chsize(&ins
->oprs
[c
- 0300], bits
)) {
1286 out(offset
, segment
, bytes
,
1287 OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1296 out(offset
, segment
, bytes
,
1297 OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1306 out(offset
, segment
, bytes
,
1307 OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1323 out(offset
, segment
, bytes
,
1324 OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1333 out(offset
, segment
, bytes
,
1334 OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1349 *bytes
= *codes
++ ^ condval
[ins
->condition
];
1350 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1360 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1365 if (ins
->rex
& REX_R
) {
1367 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1370 ins
->rex
&= ~(REX_L
|REX_R
);
1376 if (ins
->oprs
[0].segment
!= NO_SEG
)
1377 errfunc(ERR_PANIC
, "non-constant BSS size in pass two");
1379 int32_t size
= ins
->oprs
[0].offset
<< (c
- 0340);
1381 out(offset
, segment
, NULL
,
1382 OUT_RESERVE
+ size
, NO_SEG
, NO_SEG
);
1389 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1398 *bytes
= bits
== 16 ? 3 : 5;
1399 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1403 default: /* can't do it by 'case' statements */
1404 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1412 /* pick rfield from operand b */
1413 rflags
= regflag(&ins
->oprs
[c
& 7]);
1414 rfield
= regvals
[ins
->oprs
[c
& 7].basereg
];
1416 /* rfield is constant */
1422 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1423 rfield
, rflags
, ins
->forw_ref
)) {
1424 errfunc(ERR_NONFATAL
, "invalid effective address");
1428 *p
++ = ea_data
.modrm
;
1429 if (ea_data
.sib_present
)
1433 out(offset
, segment
, bytes
, OUT_RAWDATA
+ s
,
1436 switch (ea_data
.bytes
) {
1440 if (ins
->oprs
[(c
>> 3) & 7].segment
!= NO_SEG
) {
1441 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1442 out(offset
, segment
, &data
, OUT_ADDRESS
+ 1,
1443 ins
->oprs
[(c
>> 3) & 7].segment
,
1444 ins
->oprs
[(c
>> 3) & 7].wrt
);
1446 *bytes
= ins
->oprs
[(c
>> 3) & 7].offset
;
1447 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1,
1455 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1456 if (ea_data
.rip
&& (ins
->oprs
[(c
>> 3) & 7].segment
== 0xFFFFFFFF))
1457 ea_data
.rip
= 0; /* Make distinction between Symbols and Immediates */
1458 out(offset
, segment
, &data
, /* RIP = Relative, not Absolute */
1459 (ea_data
.rip
? OUT_REL4ADR
: OUT_ADDRESS
) + ea_data
.bytes
,
1460 ins
->oprs
[(c
>> 3) & 7].segment
,
1461 ins
->oprs
[(c
>> 3) & 7].wrt
);
1467 errfunc(ERR_PANIC
, "internal instruction table corrupt"
1468 ": instruction code 0x%02X given", c
);
1472 static int32_t regflag(const operand
* o
)
1474 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1475 errfunc(ERR_PANIC
, "invalid operand passed to regflag()");
1477 return reg_flags
[o
->basereg
];
1480 static int32_t regval(const operand
* o
)
1482 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1483 errfunc(ERR_PANIC
, "invalid operand passed to regval()");
1485 return regvals
[o
->basereg
];
1488 static int op_rexflags(const operand
* o
, int mask
)
1493 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1494 errfunc(ERR_PANIC
, "invalid operand passed to op_rexflags()");
1497 flags
= reg_flags
[o
->basereg
];
1498 val
= regvals
[o
->basereg
];
1500 return rexflags(val
, flags
, mask
);
1503 static int rexflags(int val
, int32_t flags
, int mask
)
1508 rex
|= REX_B
|REX_X
|REX_R
;
1511 if (!(REG_HIGH
& ~flags
)) /* AH, CH, DH, BH */
1513 else if (!(REG8
& ~flags
) && val
>= 4) /* SPL, BPL, SIL, DIL */
1519 static int matches(struct itemplate
*itemp
, insn
* instruction
, int bits
)
1521 int i
, size
[3], asize
, oprs
, ret
;
1528 if (itemp
->opcode
!= instruction
->opcode
)
1532 * Count the operands
1534 if (itemp
->operands
!= instruction
->operands
)
1538 * Check that no spurious colons or TOs are present
1540 for (i
= 0; i
< itemp
->operands
; i
++)
1541 if (instruction
->oprs
[i
].type
& ~itemp
->opd
[i
] & (COLON
| TO
))
1545 * Check that the operand flags all match up
1547 for (i
= 0; i
< itemp
->operands
; i
++)
1548 if (itemp
->opd
[i
] & ~instruction
->oprs
[i
].type
||
1549 ((itemp
->opd
[i
] & SIZE_MASK
) &&
1550 ((itemp
->opd
[i
] ^ instruction
->oprs
[i
].type
) & SIZE_MASK
))) {
1551 if ((itemp
->opd
[i
] & ~instruction
->oprs
[i
].type
& ~SIZE_MASK
) ||
1552 (instruction
->oprs
[i
].type
& SIZE_MASK
))
1559 * Check operand sizes
1561 if (itemp
->flags
& IF_ARMASK
) {
1562 size
[0] = size
[1] = size
[2] = 0;
1564 switch (itemp
->flags
& IF_ARMASK
) {
1575 break; /* Shouldn't happen */
1577 if (itemp
->flags
& IF_SB
) {
1579 } else if (itemp
->flags
& IF_SW
) {
1581 } else if (itemp
->flags
& IF_SD
) {
1583 } else if (itemp
->flags
& IF_SQ
) {
1588 if (itemp
->flags
& IF_SB
) {
1590 oprs
= itemp
->operands
;
1591 } else if (itemp
->flags
& IF_SW
) {
1593 oprs
= itemp
->operands
;
1594 } else if (itemp
->flags
& IF_SD
) {
1596 oprs
= itemp
->operands
;
1597 } else if (itemp
->flags
& IF_SQ
) {
1599 oprs
= itemp
->operands
;
1601 size
[0] = size
[1] = size
[2] = asize
;
1604 if (itemp
->flags
& (IF_SM
| IF_SM2
)) {
1605 oprs
= (itemp
->flags
& IF_SM2
? 2 : itemp
->operands
);
1607 for (i
= 0; i
< oprs
; i
++) {
1608 if ((asize
= itemp
->opd
[i
] & SIZE_MASK
) != 0) {
1610 for (j
= 0; j
< oprs
; j
++)
1616 oprs
= itemp
->operands
;
1619 for (i
= 0; i
< itemp
->operands
; i
++) {
1620 if (!(itemp
->opd
[i
] & SIZE_MASK
) &&
1621 (instruction
->oprs
[i
].type
& SIZE_MASK
& ~size
[i
]))
1626 * Check template is okay at the set cpu level
1628 if (((itemp
->flags
& IF_PLEVEL
) > cpu
))
1632 * Check if instruction is available in long mode
1634 if ((itemp
->flags
& IF_NOLONG
) && (bits
== 64))
1638 * Check if special handling needed for Jumps
1640 if ((uint8_t)(itemp
->code
[0]) >= 0370)
1646 static ea
*process_ea(operand
* input
, ea
* output
, int addrbits
,
1647 int rfield
, int32_t rflags
, int forw_ref
)
1649 output
->rip
= FALSE
;
1651 /* REX flags for the rfield operand */
1652 output
->rex
|= rexflags(rfield
, rflags
, REX_R
|REX_P
|REX_W
|REX_H
);
1654 if (!(REGISTER
& ~input
->type
)) { /* register direct */
1658 if (input
->basereg
< EXPR_REG_START
/* Verify as Register */
1659 || input
->basereg
>= REG_ENUM_LIMIT
)
1662 i
= regvals
[input
->basereg
];
1665 return NULL
; /* Invalid EA register */
1667 output
->rex
|= op_rexflags(input
, REX_B
|REX_P
|REX_W
|REX_H
);
1669 output
->sib_present
= FALSE
; /* no SIB necessary */
1670 output
->bytes
= 0; /* no offset necessary either */
1671 output
->modrm
= 0xC0 | ((rfield
& 7) << 3) | (i
& 7);
1672 } else { /* it's a memory reference */
1673 if (input
->basereg
== -1
1674 && (input
->indexreg
== -1 || input
->scale
== 0)) {
1675 /* it's a pure offset */
1676 if (input
->addr_size
)
1677 addrbits
= input
->addr_size
;
1679 if (globalbits
== 64 && (~input
->type
& IP_REL
)) {
1680 int scale
, index
, base
;
1681 output
->sib_present
= TRUE
;
1685 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
1687 output
->modrm
= 4 | ((rfield
& 7) << 3);
1688 output
->rip
= FALSE
;
1690 output
->sib_present
= FALSE
;
1691 output
->bytes
= (addrbits
!= 16 ? 4 : 2);
1692 output
->modrm
= (addrbits
!= 16 ? 5 : 6) | ((rfield
& 7) << 3);
1693 output
->rip
= globalbits
== 64;
1695 } else { /* it's an indirection */
1696 int i
= input
->indexreg
, b
= input
->basereg
, s
= input
->scale
;
1697 int32_t o
= input
->offset
, seg
= input
->segment
;
1698 int hb
= input
->hintbase
, ht
= input
->hinttype
;
1701 int32_t ix
, bx
; /* register flags */
1704 i
= -1; /* make this easy, at least */
1706 if (i
>= EXPR_REG_START
&& i
< REG_ENUM_LIMIT
) {
1714 if (b
!= -1 && b
>= EXPR_REG_START
&& b
< REG_ENUM_LIMIT
) {
1722 /* check for a 32/64-bit memory reference... */
1723 if ((ix
|bx
) & (BITS32
|BITS64
)) {
1724 /* it must be a 32/64-bit memory reference. Firstly we have
1725 * to check that all registers involved are type E/Rxx. */
1726 int32_t sok
= BITS32
|BITS64
;
1729 if (!(REG64
& ~ix
) || !(REG32
& ~ix
))
1737 return NULL
; /* Invalid register */
1738 if (~sok
& bx
& SIZE_MASK
)
1739 return NULL
; /* Invalid size */
1743 /* While we're here, ensure the user didn't specify WORD. */
1744 if (input
->addr_size
== 16 ||
1745 (input
->addr_size
== 32 && !(sok
& BITS32
)) ||
1746 (input
->addr_size
== 64 && !(sok
& BITS64
)))
1749 /* now reorganize base/index */
1750 if (s
== 1 && bt
!= it
&& bt
!= -1 && it
!= -1 &&
1751 ((hb
== b
&& ht
== EAH_NOTBASE
)
1752 || (hb
== i
&& ht
== EAH_MAKEBASE
))) {
1753 /* swap if hints say so */
1754 t
= bt
, bt
= it
, it
= t
;
1755 t
= bx
, bx
= ix
, ix
= t
;
1757 if (bt
== it
) /* convert EAX+2*EAX to 3*EAX */
1758 bt
= -1, bx
= 0, s
++;
1759 if (bt
== -1 && s
== 1 && !(hb
== it
&& ht
== EAH_NOTBASE
)) {
1760 /* make single reg base, unless hint */
1761 bt
= it
, bx
= ix
, it
= -1, ix
= 0;
1763 if (((s
== 2 && t
!= REG_NUM_ESP
1764 && !(input
->eaflags
& EAF_TIMESTWO
)) || s
== 3
1765 || s
== 5 || s
== 9) && bt
== -1)
1766 bt
= it
, bx
= ix
, s
--; /* convert 3*EAX to EAX+2*EAX */
1767 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
1768 && (input
->eaflags
& EAF_TIMESTWO
))
1769 it
= bt
, ix
= bx
, bt
= -1, bx
= 0, s
= 1;
1770 /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */
1771 if (s
== 1 && it
== REG_NUM_ESP
) {
1772 /* swap ESP into base if scale is 1 */
1773 t
= it
, it
= bt
, bt
= t
;
1774 t
= ix
, ix
= bx
, bx
= t
;
1776 if (it
== REG_NUM_ESP
1777 || (s
!= 1 && s
!= 2 && s
!= 4 && s
!= 8 && it
!= -1))
1778 return NULL
; /* wrong, for various reasons */
1780 output
->rex
|= rexflags(it
, ix
, REX_X
);
1781 output
->rex
|= rexflags(bt
, bx
, REX_B
);
1783 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
) {
1792 if (rm
!= REG_NUM_EBP
&& o
== 0 &&
1793 seg
== NO_SEG
&& !forw_ref
&&
1795 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
1797 else if (input
->eaflags
& EAF_BYTEOFFS
||
1798 (o
>= -128 && o
<= 127 && seg
== NO_SEG
1800 && !(input
->eaflags
& EAF_WORDOFFS
)))
1806 output
->sib_present
= FALSE
;
1807 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
1808 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
1811 int mod
, scale
, index
, base
;
1831 default: /* then what the smeg is it? */
1832 return NULL
; /* panic */
1840 if (base
!= REG_NUM_EBP
&& o
== 0 &&
1841 seg
== NO_SEG
&& !forw_ref
&&
1843 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
1845 else if (input
->eaflags
& EAF_BYTEOFFS
||
1846 (o
>= -128 && o
<= 127 && seg
== NO_SEG
1848 && !(input
->eaflags
& EAF_WORDOFFS
)))
1854 output
->sib_present
= TRUE
;
1855 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
1856 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | 4;
1857 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
1859 } else { /* it's 16-bit */
1862 /* check for 64-bit long mode */
1866 /* check all registers are BX, BP, SI or DI */
1867 if ((b
!= -1 && b
!= R_BP
&& b
!= R_BX
&& b
!= R_SI
1868 && b
!= R_DI
) || (i
!= -1 && i
!= R_BP
&& i
!= R_BX
1869 && i
!= R_SI
&& i
!= R_DI
))
1872 /* ensure the user didn't specify DWORD/QWORD */
1873 if (input
->addr_size
== 32 || input
->addr_size
== 64)
1876 if (s
!= 1 && i
!= -1)
1877 return NULL
; /* no can do, in 16-bit EA */
1878 if (b
== -1 && i
!= -1) {
1883 if ((b
== R_SI
|| b
== R_DI
) && i
!= -1) {
1888 /* have BX/BP as base, SI/DI index */
1890 return NULL
; /* shouldn't ever happen, in theory */
1891 if (i
!= -1 && b
!= -1 &&
1892 (i
== R_BP
|| i
== R_BX
|| b
== R_SI
|| b
== R_DI
))
1893 return NULL
; /* invalid combinations */
1894 if (b
== -1) /* pure offset: handled above */
1895 return NULL
; /* so if it gets to here, panic! */
1899 switch (i
* 256 + b
) {
1900 case R_SI
* 256 + R_BX
:
1903 case R_DI
* 256 + R_BX
:
1906 case R_SI
* 256 + R_BP
:
1909 case R_DI
* 256 + R_BP
:
1927 if (rm
== -1) /* can't happen, in theory */
1928 return NULL
; /* so panic if it does */
1930 if (o
== 0 && seg
== NO_SEG
&& !forw_ref
&& rm
!= 6 &&
1931 !(input
->eaflags
& (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
1933 else if (input
->eaflags
& EAF_BYTEOFFS
||
1934 (o
>= -128 && o
<= 127 && seg
== NO_SEG
1936 && !(input
->eaflags
& EAF_WORDOFFS
)))
1941 output
->sib_present
= FALSE
; /* no SIB - it's 16-bit */
1942 output
->bytes
= mod
; /* bytes of offset needed */
1943 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
1948 output
->size
= 1 + output
->sib_present
+ output
->bytes
;
1952 static int chsize(operand
* input
, int addrbits
)
1954 if (!(MEMORY
& ~input
->type
)) {
1957 if (input
->indexreg
< EXPR_REG_START
/* Verify as Register */
1958 || input
->indexreg
>= REG_ENUM_LIMIT
)
1961 i
= reg_flags
[input
->indexreg
];
1963 if (input
->basereg
< EXPR_REG_START
/* Verify as Register */
1964 || input
->basereg
>= REG_ENUM_LIMIT
)
1967 b
= reg_flags
[input
->basereg
];
1969 if (input
->scale
== 0)
1972 if (!i
&& !b
) /* pure offset */
1973 return (input
->addr_size
!= 0 && input
->addr_size
!= addrbits
);
1975 if (!(REG32
& ~i
) || !(REG32
& ~b
))
1976 return (addrbits
!= 32);
1978 return (addrbits
== 32);