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 - REP prefix (0xF2 byte) used as opcode extension.
68 * \333 - REP prefix (0xF3 byte) used as opcode extension.
69 * \334 - LOCK prefix used instead of REX.R
70 * \335 - disassemble a rep (0xF3 byte) prefix as repe not rep.
71 * \340 - reserve <operand 0> bytes of uninitialized storage.
72 * Operand 0 had better be a segmentless constant.
73 * \364 - operand-size prefix (0x66) not permitted
74 * \365 - address-size prefix (0x67) not permitted
75 * \366 - operand-size prefix (0x66) used as opcode extension
76 * \367 - address-size prefix (0x67) used as opcode extension
77 * \370,\371,\372 - match only if operand 0 meets byte jump criteria.
78 * 370 is used for Jcc, 371 is used for JMP.
79 * \373 - assemble 0x03 if bits==16, 0x05 if bits==32;
80 * used for conditional jump over longer jump
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(const 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 const 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
) {
255 int32_t t
= instruction
->times
;
258 "instruction->times < 0 (%ld) in assemble()", t
);
260 while (t
--) { /* repeat TIMES times */
261 for (e
= instruction
->eops
; e
; e
= e
->next
) {
262 if (e
->type
== EOT_DB_NUMBER
) {
264 if (e
->segment
!= NO_SEG
)
265 errfunc(ERR_NONFATAL
,
266 "one-byte relocation attempted");
268 uint8_t out_byte
= e
->offset
;
269 out(offset
, segment
, &out_byte
,
270 OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
272 } else if (wsize
> 8) {
273 errfunc(ERR_NONFATAL
, "integer supplied to a DT"
276 out(offset
, segment
, &e
->offset
,
277 OUT_ADDRESS
+ wsize
, e
->segment
, e
->wrt
);
279 } else if (e
->type
== EOT_DB_STRING
) {
282 out(offset
, segment
, e
->stringval
,
283 OUT_RAWDATA
+ e
->stringlen
, NO_SEG
, NO_SEG
);
284 align
= e
->stringlen
% wsize
;
287 align
= wsize
- align
;
288 out(offset
, segment
, "\0\0\0\0\0\0\0\0",
289 OUT_RAWDATA
+ align
, NO_SEG
, NO_SEG
);
291 offset
+= e
->stringlen
+ align
;
294 if (t
> 0 && t
== instruction
->times
- 1) {
296 * Dummy call to list->output to give the offset to the
299 list
->output(offset
, NULL
, OUT_RAWDATA
);
300 list
->uplevel(LIST_TIMES
);
303 if (instruction
->times
> 1)
304 list
->downlevel(LIST_TIMES
);
305 return offset
- start
;
308 if (instruction
->opcode
== I_INCBIN
) {
309 static char fname
[FILENAME_MAX
];
312 char *prefix
= "", *combine
;
313 char **pPrevPath
= NULL
;
315 len
= FILENAME_MAX
- 1;
316 if (len
> instruction
->eops
->stringlen
)
317 len
= instruction
->eops
->stringlen
;
318 strncpy(fname
, instruction
->eops
->stringval
, len
);
321 while (1) { /* added by alexfru: 'incbin' uses include paths */
322 combine
= nasm_malloc(strlen(prefix
) + len
+ 1);
323 strcpy(combine
, prefix
);
324 strcat(combine
, fname
);
326 if ((fp
= fopen(combine
, "rb")) != NULL
) {
332 pPrevPath
= pp_get_include_path_ptr(pPrevPath
);
333 if (pPrevPath
== NULL
)
339 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
341 else if (fseek(fp
, 0L, SEEK_END
) < 0)
342 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
345 static char buf
[2048];
346 int32_t t
= instruction
->times
;
350 if (instruction
->eops
->next
) {
351 base
= instruction
->eops
->next
->offset
;
353 if (instruction
->eops
->next
->next
&&
354 len
> instruction
->eops
->next
->next
->offset
)
355 len
= instruction
->eops
->next
->next
->offset
;
358 * Dummy call to list->output to give the offset to the
361 list
->output(offset
, NULL
, OUT_RAWDATA
);
362 list
->uplevel(LIST_INCBIN
);
366 fseek(fp
, base
, SEEK_SET
);
370 fread(buf
, 1, (l
> sizeof(buf
) ? sizeof(buf
) : l
),
374 * This shouldn't happen unless the file
375 * actually changes while we are reading
379 "`incbin': unexpected EOF while"
380 " reading file `%s'", fname
);
381 t
= 0; /* Try to exit cleanly */
384 out(offset
, segment
, buf
, OUT_RAWDATA
+ m
,
389 list
->downlevel(LIST_INCBIN
);
390 if (instruction
->times
> 1) {
392 * Dummy call to list->output to give the offset to the
395 list
->output(offset
, NULL
, OUT_RAWDATA
);
396 list
->uplevel(LIST_TIMES
);
397 list
->downlevel(LIST_TIMES
);
400 return instruction
->times
* len
;
402 return 0; /* if we're here, there's an error */
407 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++){
408 int m
= matches(temp
, instruction
, bits
);
411 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
413 if (m
== 100) { /* matches! */
414 const char *codes
= temp
->code
;
415 int32_t insn_size
= calcsize(segment
, offset
, bits
,
417 itimes
= instruction
->times
;
418 if (insn_size
< 0) /* shouldn't be, on pass two */
419 error(ERR_PANIC
, "errors made it through from pass one");
422 for (j
= 0; j
< instruction
->nprefix
; j
++) {
424 switch (instruction
->prefixes
[j
]) {
440 "cs segment base ignored in 64-bit mode");
447 "ds segment base ignored in 64-bit mode");
454 "es segment base ignored in 64-bit mode");
467 "ss segment base ignored in 64-bit mode");
474 "segr6 and segr7 cannot be used as prefixes");
479 "16-bit addressing is not supported "
499 error(ERR_PANIC
, "invalid instruction prefix");
502 out(offset
, segment
, &c
, OUT_RAWDATA
+ 1,
507 insn_end
= offset
+ insn_size
;
508 gencode(segment
, offset
, bits
, instruction
, codes
,
511 if (itimes
> 0 && itimes
== instruction
->times
- 1) {
513 * Dummy call to list->output to give the offset to the
516 list
->output(offset
, NULL
, OUT_RAWDATA
);
517 list
->uplevel(LIST_TIMES
);
520 if (instruction
->times
> 1)
521 list
->downlevel(LIST_TIMES
);
522 return offset
- start
;
523 } else if (m
> 0 && m
> size_prob
) {
529 if (temp
->opcode
== -1) { /* didn't match any instruction */
532 error(ERR_NONFATAL
, "operation size not specified");
535 error(ERR_NONFATAL
, "mismatch in operand sizes");
538 error(ERR_NONFATAL
, "no instruction for this cpu level");
541 error(ERR_NONFATAL
, "instruction not supported in 64-bit mode");
545 "invalid combination of opcode and operands");
552 int32_t insn_size(int32_t segment
, int32_t offset
, int bits
, uint32_t cp
,
553 insn
* instruction
, efunc error
)
555 const struct itemplate
*temp
;
557 errfunc
= error
; /* to pass to other functions */
560 if (instruction
->opcode
== -1)
563 if (instruction
->opcode
== I_DB
||
564 instruction
->opcode
== I_DW
||
565 instruction
->opcode
== I_DD
||
566 instruction
->opcode
== I_DQ
|| instruction
->opcode
== I_DT
) {
568 int32_t isize
, osize
, wsize
= 0; /* placate gcc */
571 switch (instruction
->opcode
) {
591 for (e
= instruction
->eops
; e
; e
= e
->next
) {
595 if (e
->type
== EOT_DB_NUMBER
)
597 else if (e
->type
== EOT_DB_STRING
)
598 osize
= e
->stringlen
;
600 align
= (-osize
) % wsize
;
603 isize
+= osize
+ align
;
605 return isize
* instruction
->times
;
608 if (instruction
->opcode
== I_INCBIN
) {
609 char fname
[FILENAME_MAX
];
612 char *prefix
= "", *combine
;
613 char **pPrevPath
= NULL
;
615 len
= FILENAME_MAX
- 1;
616 if (len
> instruction
->eops
->stringlen
)
617 len
= instruction
->eops
->stringlen
;
618 strncpy(fname
, instruction
->eops
->stringval
, len
);
621 while (1) { /* added by alexfru: 'incbin' uses include paths */
622 combine
= nasm_malloc(strlen(prefix
) + len
+ 1);
623 strcpy(combine
, prefix
);
624 strcat(combine
, fname
);
626 if ((fp
= fopen(combine
, "rb")) != NULL
) {
632 pPrevPath
= pp_get_include_path_ptr(pPrevPath
);
633 if (pPrevPath
== NULL
)
639 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
641 else if (fseek(fp
, 0L, SEEK_END
) < 0)
642 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
647 if (instruction
->eops
->next
) {
648 len
-= instruction
->eops
->next
->offset
;
649 if (instruction
->eops
->next
->next
&&
650 len
> instruction
->eops
->next
->next
->offset
) {
651 len
= instruction
->eops
->next
->next
->offset
;
654 return instruction
->times
* len
;
656 return 0; /* if we're here, there's an error */
659 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++) {
660 int m
= matches(temp
, instruction
, bits
);
662 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
665 /* we've matched an instruction. */
667 const char *codes
= temp
->code
;
670 isize
= calcsize(segment
, offset
, bits
, instruction
, codes
);
673 for (j
= 0; j
< instruction
->nprefix
; j
++) {
674 if ((instruction
->prefixes
[j
] != P_A16
&&
675 instruction
->prefixes
[j
] != P_O16
&& bits
== 16) ||
676 (instruction
->prefixes
[j
] != P_A32
&&
677 instruction
->prefixes
[j
] != P_O32
&& bits
>= 32)) {
681 return isize
* instruction
->times
;
684 return -1; /* didn't match any instruction */
687 /* check that opn[op] is a signed byte of size 16 or 32,
688 and return the signed value*/
689 static int is_sbyte(insn
* ins
, int op
, int size
)
694 ret
= !(ins
->forw_ref
&& ins
->oprs
[op
].opflags
) && /* dead in the water on forward reference or External */
696 !(ins
->oprs
[op
].type
& STRICT
) &&
697 ins
->oprs
[op
].wrt
== NO_SEG
&& ins
->oprs
[op
].segment
== NO_SEG
;
699 v
= ins
->oprs
[op
].offset
;
701 v
= (int16_t)v
; /* sign extend if 16 bits */
703 return ret
&& v
>= -128L && v
<= 127L;
706 static int32_t calcsize(int32_t segment
, int32_t offset
, int bits
,
707 insn
* ins
, const char *codes
)
712 ins
->rex
= 0; /* Ensure REX is reset */
714 (void)segment
; /* Don't warn that this parameter is unused */
715 (void)offset
; /* Don't warn that this parameter is unused */
718 switch (c
= *codes
++) {
722 codes
+= c
, length
+= c
;
734 op_rexflags(&ins
->oprs
[c
- 010], REX_B
|REX_H
|REX_P
|REX_W
);
763 if (ins
->oprs
[c
- 034].type
& (BITS16
| BITS32
| BITS64
))
764 length
+= (ins
->oprs
[c
- 034].type
& BITS16
) ? 2 : 4;
766 length
+= (bits
== 16) ? 2 : 4;
779 length
+= ((ins
->oprs
[c
- 044].addr_size
?
780 ins
->oprs
[c
- 044].addr_size
: bits
) >> 3);
790 length
+= 8; /* MOV reg64/imm */
800 if (ins
->oprs
[c
- 064].type
& (BITS16
| BITS32
| BITS64
))
801 length
+= (ins
->oprs
[c
- 064].type
& BITS16
) ? 2 : 4;
803 length
+= (bits
== 16) ? 2 : 4;
813 length
+= is_sbyte(ins
, c
- 0130, 16) ? 1 : 2;
824 length
+= is_sbyte(ins
, c
- 0140, 32) ? 1 : 4;
835 length
+= chsize(&ins
->oprs
[c
- 0300], bits
);
838 length
+= (bits
!= 16);
841 length
+= (bits
!= 32);
848 length
+= (bits
!= 16);
851 length
+= (bits
== 16);
871 assert_no_prefix(ins
, P_LOCK
);
879 if (ins
->oprs
[0].segment
!= NO_SEG
)
880 errfunc(ERR_NONFATAL
, "attempt to reserve non-constant"
881 " quantity of BSS space");
883 length
+= ins
->oprs
[0].offset
<< (c
- 0340);
899 default: /* can't do it by 'case' statements */
900 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
904 ea_data
.rex
= 0; /* Ensure ea.REX is initially 0 */
907 /* pick rfield from operand b */
908 rflags
= regflag(&ins
->oprs
[c
& 7]);
909 rfield
= regvals
[ins
->oprs
[c
& 7].basereg
];
916 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
917 rfield
, rflags
, ins
->forw_ref
)) {
918 errfunc(ERR_NONFATAL
, "invalid effective address");
921 ins
->rex
|= ea_data
.rex
;
922 length
+= ea_data
.size
;
925 errfunc(ERR_PANIC
, "internal instruction table corrupt"
926 ": instruction code 0x%02X given", c
);
929 ins
->rex
&= rex_mask
;
930 if (ins
->rex
& REX_REAL
) {
931 if (ins
->rex
& REX_H
) {
932 errfunc(ERR_NONFATAL
, "cannot use high register in rex instruction");
934 } else if (bits
== 64 ||
935 ((ins
->rex
& REX_L
) &&
936 !(ins
->rex
& (REX_P
|REX_W
|REX_X
|REX_B
)) &&
940 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
949 if((ins->rex & REX_REAL) && (bits == 64)) { \
950 ins->rex = (ins->rex & REX_REAL)|REX_P; \
951 out(offset, segment, &ins->rex, OUT_RAWDATA+1, NO_SEG, NO_SEG); \
956 static void gencode(int32_t segment
, int32_t offset
, int bits
,
957 insn
* ins
, const char *codes
, int32_t insn_end
)
959 static char condval
[] = { /* conditional opcodes */
960 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
961 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
962 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
970 switch (c
= *codes
++) {
975 out(offset
, segment
, codes
, OUT_RAWDATA
+ c
, NO_SEG
, NO_SEG
);
982 switch (ins
->oprs
[0].basereg
) {
984 bytes
[0] = 0x0E + (c
== 0x04 ? 1 : 0);
987 bytes
[0] = 0x1E + (c
== 0x04 ? 1 : 0);
990 bytes
[0] = 0x06 + (c
== 0x04 ? 1 : 0);
993 bytes
[0] = 0x16 + (c
== 0x04 ? 1 : 0);
997 "bizarre 8086 segment register received");
999 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1005 switch (ins
->oprs
[0].basereg
) {
1007 bytes
[0] = 0xA0 + (c
== 0x05 ? 1 : 0);
1010 bytes
[0] = 0xA8 + (c
== 0x05 ? 1 : 0);
1014 "bizarre 386 segment register received");
1016 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1024 bytes
[0] = *codes
++ + ((regval(&ins
->oprs
[c
- 010])) & 7);
1025 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1031 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1038 if (ins
->oprs
[c
- 014].offset
< -128
1039 || ins
->oprs
[c
- 014].offset
> 127) {
1040 errfunc(ERR_WARNING
, "signed byte value exceeds bounds");
1043 if (ins
->oprs
[c
- 014].segment
!= NO_SEG
) {
1044 data
= ins
->oprs
[c
- 014].offset
;
1045 out(offset
, segment
, &data
, OUT_ADDRESS
+ 1,
1046 ins
->oprs
[c
- 014].segment
, ins
->oprs
[c
- 014].wrt
);
1048 bytes
[0] = ins
->oprs
[c
- 014].offset
;
1049 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
,
1058 if (ins
->oprs
[c
- 020].offset
< -256
1059 || ins
->oprs
[c
- 020].offset
> 255) {
1060 errfunc(ERR_WARNING
, "byte value exceeds bounds");
1062 if (ins
->oprs
[c
- 020].segment
!= NO_SEG
) {
1063 data
= ins
->oprs
[c
- 020].offset
;
1064 out(offset
, segment
, &data
, OUT_ADDRESS
+ 1,
1065 ins
->oprs
[c
- 020].segment
, ins
->oprs
[c
- 020].wrt
);
1067 bytes
[0] = ins
->oprs
[c
- 020].offset
;
1068 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
,
1077 if (ins
->oprs
[c
- 024].offset
< 0
1078 || ins
->oprs
[c
- 024].offset
> 255)
1079 errfunc(ERR_WARNING
, "unsigned byte value exceeds bounds");
1080 if (ins
->oprs
[c
- 024].segment
!= NO_SEG
) {
1081 data
= ins
->oprs
[c
- 024].offset
;
1082 out(offset
, segment
, &data
, OUT_ADDRESS
+ 1,
1083 ins
->oprs
[c
- 024].segment
, ins
->oprs
[c
- 024].wrt
);
1085 bytes
[0] = ins
->oprs
[c
- 024].offset
;
1086 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
,
1095 if (ins
->oprs
[c
- 030].segment
== NO_SEG
&&
1096 ins
->oprs
[c
- 030].wrt
== NO_SEG
&&
1097 (ins
->oprs
[c
- 030].offset
< -65536L ||
1098 ins
->oprs
[c
- 030].offset
> 65535L)) {
1099 errfunc(ERR_WARNING
, "word value exceeds bounds");
1101 data
= ins
->oprs
[c
- 030].offset
;
1102 out(offset
, segment
, &data
, OUT_ADDRESS
+ 2,
1103 ins
->oprs
[c
- 030].segment
, ins
->oprs
[c
- 030].wrt
);
1110 if (ins
->oprs
[c
- 034].type
& (BITS16
| BITS32
))
1111 size
= (ins
->oprs
[c
- 034].type
& BITS16
) ? 2 : 4;
1113 size
= (bits
== 16) ? 2 : 4;
1114 data
= ins
->oprs
[c
- 034].offset
;
1115 if (size
== 2 && (data
< -65536L || data
> 65535L))
1116 errfunc(ERR_WARNING
, "word value exceeds bounds");
1117 out(offset
, segment
, &data
, OUT_ADDRESS
+ size
,
1118 ins
->oprs
[c
- 034].segment
, ins
->oprs
[c
- 034].wrt
);
1123 if (ins
->oprs
[0].segment
== NO_SEG
)
1124 errfunc(ERR_NONFATAL
, "value referenced by FAR is not"
1127 out(offset
, segment
, &data
, OUT_ADDRESS
+ 2,
1128 outfmt
->segbase(1 + ins
->oprs
[0].segment
),
1136 data
= ins
->oprs
[c
- 040].offset
;
1137 out(offset
, segment
, &data
, OUT_ADDRESS
+ 4,
1138 ins
->oprs
[c
- 040].segment
, ins
->oprs
[c
- 040].wrt
);
1145 data
= ins
->oprs
[c
- 044].offset
;
1146 size
= ((ins
->oprs
[c
- 044].addr_size
?
1147 ins
->oprs
[c
- 044].addr_size
: bits
) >> 3);
1148 if (size
== 2 && (data
< -65536L || data
> 65535L))
1149 errfunc(ERR_WARNING
, "word value exceeds bounds");
1150 out(offset
, segment
, &data
, OUT_ADDRESS
+ size
,
1151 ins
->oprs
[c
- 044].segment
, ins
->oprs
[c
- 044].wrt
);
1158 if (ins
->oprs
[c
- 050].segment
!= segment
)
1159 errfunc(ERR_NONFATAL
,
1160 "short relative jump outside segment");
1161 data
= ins
->oprs
[c
- 050].offset
- insn_end
;
1162 if (data
> 127 || data
< -128)
1163 errfunc(ERR_NONFATAL
, "short jump is out of range");
1165 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1172 data
= (int64_t)ins
->oprs
[c
- 054].offset
;
1173 out(offset
, segment
, &data
, OUT_ADDRESS
+ 8,
1174 ins
->oprs
[c
- 054].segment
, ins
->oprs
[c
- 054].wrt
);
1181 if (ins
->oprs
[c
- 060].segment
!= segment
) {
1182 data
= ins
->oprs
[c
- 060].offset
;
1183 out(offset
, segment
, &data
,
1184 OUT_REL2ADR
+ insn_end
- offset
,
1185 ins
->oprs
[c
- 060].segment
, ins
->oprs
[c
- 060].wrt
);
1187 data
= ins
->oprs
[c
- 060].offset
- insn_end
;
1188 out(offset
, segment
, &data
,
1189 OUT_ADDRESS
+ 2, NO_SEG
, NO_SEG
);
1197 if (ins
->oprs
[c
- 064].type
& (BITS16
| BITS32
| BITS64
))
1198 size
= (ins
->oprs
[c
- 064].type
& BITS16
) ? 2 : 4;
1200 size
= (bits
== 16) ? 2 : 4;
1201 if (ins
->oprs
[c
- 064].segment
!= segment
) {
1202 int32_t reltype
= (size
== 2 ? OUT_REL2ADR
: OUT_REL4ADR
);
1203 data
= ins
->oprs
[c
- 064].offset
;
1204 out(offset
, segment
, &data
, reltype
+ insn_end
- offset
,
1205 ins
->oprs
[c
- 064].segment
, ins
->oprs
[c
- 064].wrt
);
1207 data
= ins
->oprs
[c
- 064].offset
- insn_end
;
1208 out(offset
, segment
, &data
,
1209 OUT_ADDRESS
+ size
, NO_SEG
, NO_SEG
);
1217 if (ins
->oprs
[c
- 070].segment
!= segment
) {
1218 data
= ins
->oprs
[c
- 070].offset
;
1219 out(offset
, segment
, &data
,
1220 OUT_REL4ADR
+ insn_end
- offset
,
1221 ins
->oprs
[c
- 070].segment
, ins
->oprs
[c
- 070].wrt
);
1223 data
= ins
->oprs
[c
- 070].offset
- insn_end
;
1224 out(offset
, segment
, &data
,
1225 OUT_ADDRESS
+ 4, NO_SEG
, NO_SEG
);
1233 data
= ins
->oprs
[c
- 0130].offset
;
1234 if (is_sbyte(ins
, c
- 0130, 16)) {
1236 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
,
1240 if (ins
->oprs
[c
- 0130].segment
== NO_SEG
&&
1241 ins
->oprs
[c
- 0130].wrt
== NO_SEG
&&
1242 (data
< -65536L || data
> 65535L)) {
1243 errfunc(ERR_WARNING
, "word value exceeds bounds");
1245 out(offset
, segment
, &data
, OUT_ADDRESS
+ 2,
1246 ins
->oprs
[c
- 0130].segment
, ins
->oprs
[c
- 0130].wrt
);
1256 bytes
[0] = *codes
++;
1257 if (is_sbyte(ins
, c
- 0133, 16))
1258 bytes
[0] |= 2; /* s-bit */
1259 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1266 data
= ins
->oprs
[c
- 0140].offset
;
1267 if (is_sbyte(ins
, c
- 0140, 32)) {
1269 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
,
1273 out(offset
, segment
, &data
, OUT_ADDRESS
+ 4,
1274 ins
->oprs
[c
- 0140].segment
, ins
->oprs
[c
- 0140].wrt
);
1284 bytes
[0] = *codes
++;
1285 if (is_sbyte(ins
, c
- 0143, 32))
1286 bytes
[0] |= 2; /* s-bit */
1287 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1294 if (chsize(&ins
->oprs
[c
- 0300], bits
)) {
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
);
1316 out(offset
, segment
, bytes
,
1317 OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1333 out(offset
, segment
, bytes
,
1334 OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1343 out(offset
, segment
, bytes
,
1344 OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1359 *bytes
= *codes
++ ^ condval
[ins
->condition
];
1360 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1369 *bytes
= c
- 0332 + 0xF2;
1370 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1375 if (ins
->rex
& REX_R
) {
1377 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1380 ins
->rex
&= ~(REX_L
|REX_R
);
1389 if (ins
->oprs
[0].segment
!= NO_SEG
)
1390 errfunc(ERR_PANIC
, "non-constant BSS size in pass two");
1392 int32_t size
= ins
->oprs
[0].offset
<< (c
- 0340);
1394 out(offset
, segment
, NULL
,
1395 OUT_RESERVE
+ size
, NO_SEG
, NO_SEG
);
1406 *bytes
= c
- 0366 + 0x66;
1407 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1417 *bytes
= bits
== 16 ? 3 : 5;
1418 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1422 default: /* can't do it by 'case' statements */
1423 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1431 /* pick rfield from operand b */
1432 rflags
= regflag(&ins
->oprs
[c
& 7]);
1433 rfield
= regvals
[ins
->oprs
[c
& 7].basereg
];
1435 /* rfield is constant */
1441 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1442 rfield
, rflags
, ins
->forw_ref
)) {
1443 errfunc(ERR_NONFATAL
, "invalid effective address");
1447 *p
++ = ea_data
.modrm
;
1448 if (ea_data
.sib_present
)
1452 out(offset
, segment
, bytes
, OUT_RAWDATA
+ s
,
1455 switch (ea_data
.bytes
) {
1459 if (ins
->oprs
[(c
>> 3) & 7].segment
!= NO_SEG
) {
1460 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1461 out(offset
, segment
, &data
, OUT_ADDRESS
+ 1,
1462 ins
->oprs
[(c
>> 3) & 7].segment
,
1463 ins
->oprs
[(c
>> 3) & 7].wrt
);
1465 *bytes
= ins
->oprs
[(c
>> 3) & 7].offset
;
1466 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1,
1474 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1475 if (ea_data
.rip
&& (ins
->oprs
[(c
>> 3) & 7].segment
== 0xFFFFFFFF))
1476 ea_data
.rip
= 0; /* Make distinction between Symbols and Immediates */
1477 out(offset
, segment
, &data
, /* RIP = Relative, not Absolute */
1478 (ea_data
.rip
? OUT_REL4ADR
: OUT_ADDRESS
) + ea_data
.bytes
,
1479 ins
->oprs
[(c
>> 3) & 7].segment
,
1480 ins
->oprs
[(c
>> 3) & 7].wrt
);
1486 errfunc(ERR_PANIC
, "internal instruction table corrupt"
1487 ": instruction code 0x%02X given", c
);
1491 static int32_t regflag(const operand
* o
)
1493 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1494 errfunc(ERR_PANIC
, "invalid operand passed to regflag()");
1496 return reg_flags
[o
->basereg
];
1499 static int32_t regval(const operand
* o
)
1501 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1502 errfunc(ERR_PANIC
, "invalid operand passed to regval()");
1504 return regvals
[o
->basereg
];
1507 static int op_rexflags(const operand
* o
, int mask
)
1512 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1513 errfunc(ERR_PANIC
, "invalid operand passed to op_rexflags()");
1516 flags
= reg_flags
[o
->basereg
];
1517 val
= regvals
[o
->basereg
];
1519 return rexflags(val
, flags
, mask
);
1522 static int rexflags(int val
, int32_t flags
, int mask
)
1527 rex
|= REX_B
|REX_X
|REX_R
;
1530 if (!(REG_HIGH
& ~flags
)) /* AH, CH, DH, BH */
1532 else if (!(REG8
& ~flags
) && val
>= 4) /* SPL, BPL, SIL, DIL */
1538 static int matches(const struct itemplate
*itemp
, insn
* instruction
, int bits
)
1540 int i
, size
[3], asize
, oprs
, ret
;
1547 if (itemp
->opcode
!= instruction
->opcode
)
1551 * Count the operands
1553 if (itemp
->operands
!= instruction
->operands
)
1557 * Check that no spurious colons or TOs are present
1559 for (i
= 0; i
< itemp
->operands
; i
++)
1560 if (instruction
->oprs
[i
].type
& ~itemp
->opd
[i
] & (COLON
| TO
))
1564 * Check that the operand flags all match up
1566 for (i
= 0; i
< itemp
->operands
; i
++) {
1567 if (itemp
->opd
[i
] & ~instruction
->oprs
[i
].type
||
1568 ((itemp
->opd
[i
] & SIZE_MASK
) &&
1569 ((itemp
->opd
[i
] ^ instruction
->oprs
[i
].type
) & SIZE_MASK
))) {
1570 if ((itemp
->opd
[i
] & ~instruction
->oprs
[i
].type
& ~SIZE_MASK
) ||
1571 (instruction
->oprs
[i
].type
& SIZE_MASK
))
1579 * Check operand sizes
1581 if (itemp
->flags
& IF_ARMASK
) {
1582 size
[0] = size
[1] = size
[2] = 0;
1584 switch (itemp
->flags
& IF_ARMASK
) {
1595 break; /* Shouldn't happen */
1597 if (itemp
->flags
& IF_SB
) {
1599 } else if (itemp
->flags
& IF_SW
) {
1601 } else if (itemp
->flags
& IF_SD
) {
1603 } else if (itemp
->flags
& IF_SQ
) {
1608 if (itemp
->flags
& IF_SB
) {
1610 oprs
= itemp
->operands
;
1611 } else if (itemp
->flags
& IF_SW
) {
1613 oprs
= itemp
->operands
;
1614 } else if (itemp
->flags
& IF_SD
) {
1616 oprs
= itemp
->operands
;
1617 } else if (itemp
->flags
& IF_SQ
) {
1619 oprs
= itemp
->operands
;
1621 size
[0] = size
[1] = size
[2] = asize
;
1624 if (itemp
->flags
& (IF_SM
| IF_SM2
)) {
1625 oprs
= (itemp
->flags
& IF_SM2
? 2 : itemp
->operands
);
1627 for (i
= 0; i
< oprs
; i
++) {
1628 if ((asize
= itemp
->opd
[i
] & SIZE_MASK
) != 0) {
1630 for (j
= 0; j
< oprs
; j
++)
1636 oprs
= itemp
->operands
;
1639 for (i
= 0; i
< itemp
->operands
; i
++) {
1640 if (!(itemp
->opd
[i
] & SIZE_MASK
) &&
1641 (instruction
->oprs
[i
].type
& SIZE_MASK
& ~size
[i
]))
1646 * Check template is okay at the set cpu level
1648 if (((itemp
->flags
& IF_PLEVEL
) > cpu
))
1652 * Check if instruction is available in long mode
1654 if ((itemp
->flags
& IF_NOLONG
) && (bits
== 64))
1658 * Check if special handling needed for Jumps
1660 if ((uint8_t)(itemp
->code
[0]) >= 0370)
1666 static ea
*process_ea(operand
* input
, ea
* output
, int addrbits
,
1667 int rfield
, int32_t rflags
, int forw_ref
)
1669 output
->rip
= FALSE
;
1671 /* REX flags for the rfield operand */
1672 output
->rex
|= rexflags(rfield
, rflags
, REX_R
|REX_P
|REX_W
|REX_H
);
1674 if (!(REGISTER
& ~input
->type
)) { /* register direct */
1678 if (input
->basereg
< EXPR_REG_START
/* Verify as Register */
1679 || input
->basereg
>= REG_ENUM_LIMIT
)
1682 i
= regvals
[input
->basereg
];
1685 return NULL
; /* Invalid EA register */
1687 output
->rex
|= op_rexflags(input
, REX_B
|REX_P
|REX_W
|REX_H
);
1689 output
->sib_present
= FALSE
; /* no SIB necessary */
1690 output
->bytes
= 0; /* no offset necessary either */
1691 output
->modrm
= 0xC0 | ((rfield
& 7) << 3) | (i
& 7);
1692 } else { /* it's a memory reference */
1693 if (input
->basereg
== -1
1694 && (input
->indexreg
== -1 || input
->scale
== 0)) {
1695 /* it's a pure offset */
1696 if (input
->addr_size
)
1697 addrbits
= input
->addr_size
;
1699 if (globalbits
== 64 && (~input
->type
& IP_REL
)) {
1700 int scale
, index
, base
;
1701 output
->sib_present
= TRUE
;
1705 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
1707 output
->modrm
= 4 | ((rfield
& 7) << 3);
1708 output
->rip
= FALSE
;
1710 output
->sib_present
= FALSE
;
1711 output
->bytes
= (addrbits
!= 16 ? 4 : 2);
1712 output
->modrm
= (addrbits
!= 16 ? 5 : 6) | ((rfield
& 7) << 3);
1713 output
->rip
= globalbits
== 64;
1715 } else { /* it's an indirection */
1716 int i
= input
->indexreg
, b
= input
->basereg
, s
= input
->scale
;
1717 int32_t o
= input
->offset
, seg
= input
->segment
;
1718 int hb
= input
->hintbase
, ht
= input
->hinttype
;
1721 int32_t ix
, bx
; /* register flags */
1724 i
= -1; /* make this easy, at least */
1726 if (i
>= EXPR_REG_START
&& i
< REG_ENUM_LIMIT
) {
1734 if (b
!= -1 && b
>= EXPR_REG_START
&& b
< REG_ENUM_LIMIT
) {
1742 /* check for a 32/64-bit memory reference... */
1743 if ((ix
|bx
) & (BITS32
|BITS64
)) {
1744 /* it must be a 32/64-bit memory reference. Firstly we have
1745 * to check that all registers involved are type E/Rxx. */
1746 int32_t sok
= BITS32
|BITS64
;
1749 if (!(REG64
& ~ix
) || !(REG32
& ~ix
))
1757 return NULL
; /* Invalid register */
1758 if (~sok
& bx
& SIZE_MASK
)
1759 return NULL
; /* Invalid size */
1763 /* While we're here, ensure the user didn't specify WORD. */
1764 if (input
->addr_size
== 16 ||
1765 (input
->addr_size
== 32 && !(sok
& BITS32
)) ||
1766 (input
->addr_size
== 64 && !(sok
& BITS64
)))
1769 /* now reorganize base/index */
1770 if (s
== 1 && bt
!= it
&& bt
!= -1 && it
!= -1 &&
1771 ((hb
== b
&& ht
== EAH_NOTBASE
)
1772 || (hb
== i
&& ht
== EAH_MAKEBASE
))) {
1773 /* swap if hints say so */
1774 t
= bt
, bt
= it
, it
= t
;
1775 t
= bx
, bx
= ix
, ix
= t
;
1777 if (bt
== it
) /* convert EAX+2*EAX to 3*EAX */
1778 bt
= -1, bx
= 0, s
++;
1779 if (bt
== -1 && s
== 1 && !(hb
== it
&& ht
== EAH_NOTBASE
)) {
1780 /* make single reg base, unless hint */
1781 bt
= it
, bx
= ix
, it
= -1, ix
= 0;
1783 if (((s
== 2 && it
!= REG_NUM_ESP
1784 && !(input
->eaflags
& EAF_TIMESTWO
)) || s
== 3
1785 || s
== 5 || s
== 9) && bt
== -1)
1786 bt
= it
, bx
= ix
, s
--; /* convert 3*EAX to EAX+2*EAX */
1787 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
1788 && (input
->eaflags
& EAF_TIMESTWO
))
1789 it
= bt
, ix
= bx
, bt
= -1, bx
= 0, s
= 1;
1790 /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */
1791 if (s
== 1 && it
== REG_NUM_ESP
) {
1792 /* swap ESP into base if scale is 1 */
1793 t
= it
, it
= bt
, bt
= t
;
1794 t
= ix
, ix
= bx
, bx
= t
;
1796 if (it
== REG_NUM_ESP
1797 || (s
!= 1 && s
!= 2 && s
!= 4 && s
!= 8 && it
!= -1))
1798 return NULL
; /* wrong, for various reasons */
1800 output
->rex
|= rexflags(it
, ix
, REX_X
);
1801 output
->rex
|= rexflags(bt
, bx
, REX_B
);
1803 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
) {
1812 if (rm
!= REG_NUM_EBP
&& o
== 0 &&
1813 seg
== NO_SEG
&& !forw_ref
&&
1815 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
1817 else if (input
->eaflags
& EAF_BYTEOFFS
||
1818 (o
>= -128 && o
<= 127 && seg
== NO_SEG
1820 && !(input
->eaflags
& EAF_WORDOFFS
)))
1826 output
->sib_present
= FALSE
;
1827 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
1828 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
1831 int mod
, scale
, index
, base
;
1851 default: /* then what the smeg is it? */
1852 return NULL
; /* panic */
1860 if (base
!= REG_NUM_EBP
&& o
== 0 &&
1861 seg
== NO_SEG
&& !forw_ref
&&
1863 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
1865 else if (input
->eaflags
& EAF_BYTEOFFS
||
1866 (o
>= -128 && o
<= 127 && seg
== NO_SEG
1868 && !(input
->eaflags
& EAF_WORDOFFS
)))
1874 output
->sib_present
= TRUE
;
1875 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
1876 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | 4;
1877 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
1879 } else { /* it's 16-bit */
1882 /* check for 64-bit long mode */
1886 /* check all registers are BX, BP, SI or DI */
1887 if ((b
!= -1 && b
!= R_BP
&& b
!= R_BX
&& b
!= R_SI
1888 && b
!= R_DI
) || (i
!= -1 && i
!= R_BP
&& i
!= R_BX
1889 && i
!= R_SI
&& i
!= R_DI
))
1892 /* ensure the user didn't specify DWORD/QWORD */
1893 if (input
->addr_size
== 32 || input
->addr_size
== 64)
1896 if (s
!= 1 && i
!= -1)
1897 return NULL
; /* no can do, in 16-bit EA */
1898 if (b
== -1 && i
!= -1) {
1903 if ((b
== R_SI
|| b
== R_DI
) && i
!= -1) {
1908 /* have BX/BP as base, SI/DI index */
1910 return NULL
; /* shouldn't ever happen, in theory */
1911 if (i
!= -1 && b
!= -1 &&
1912 (i
== R_BP
|| i
== R_BX
|| b
== R_SI
|| b
== R_DI
))
1913 return NULL
; /* invalid combinations */
1914 if (b
== -1) /* pure offset: handled above */
1915 return NULL
; /* so if it gets to here, panic! */
1919 switch (i
* 256 + b
) {
1920 case R_SI
* 256 + R_BX
:
1923 case R_DI
* 256 + R_BX
:
1926 case R_SI
* 256 + R_BP
:
1929 case R_DI
* 256 + R_BP
:
1947 if (rm
== -1) /* can't happen, in theory */
1948 return NULL
; /* so panic if it does */
1950 if (o
== 0 && seg
== NO_SEG
&& !forw_ref
&& rm
!= 6 &&
1951 !(input
->eaflags
& (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
1953 else if (input
->eaflags
& EAF_BYTEOFFS
||
1954 (o
>= -128 && o
<= 127 && seg
== NO_SEG
1956 && !(input
->eaflags
& EAF_WORDOFFS
)))
1961 output
->sib_present
= FALSE
; /* no SIB - it's 16-bit */
1962 output
->bytes
= mod
; /* bytes of offset needed */
1963 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
1968 output
->size
= 1 + output
->sib_present
+ output
->bytes
;
1972 static int chsize(operand
* input
, int addrbits
)
1974 if (!(MEMORY
& ~input
->type
)) {
1977 if (input
->indexreg
< EXPR_REG_START
/* Verify as Register */
1978 || input
->indexreg
>= REG_ENUM_LIMIT
)
1981 i
= reg_flags
[input
->indexreg
];
1983 if (input
->basereg
< EXPR_REG_START
/* Verify as Register */
1984 || input
->basereg
>= REG_ENUM_LIMIT
)
1987 b
= reg_flags
[input
->basereg
];
1989 if (input
->scale
== 0)
1992 if (!i
&& !b
) /* pure offset */
1993 return (input
->addr_size
!= 0 && input
->addr_size
!= addrbits
);
1995 if (!(REG32
& ~i
) || !(REG32
& ~b
))
1996 return (addrbits
!= 32);
1998 return (addrbits
== 32);