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..\13 - a literal byte follows in the code stream, to be added
16 * to the register value of operand 0..3
17 * \14..\17 - a signed byte immediate operand, from operand 0..3
18 * \20..\23 - a byte immediate operand, from operand 0..3
19 * \24..\27 - an unsigned byte immediate operand, from operand 0..3
20 * \30..\33 - a word immediate operand, from operand 0..3
21 * \34..\37 - select between \3[0-3] and \4[0-3] depending on 16/32 bit
22 * assembly mode or the operand-size override on the operand
23 * \40..\43 - a long immediate operand, from operand 0..3
24 * \44..\47 - select between \3[0-3], \4[0-3] and \5[4-7]
25 * depending on assembly mode or the address-size override
27 * \50..\53 - a byte relative operand, from operand 0..3
28 * \54..\57 - a qword immediate operand, from operand 0..3
29 * \60..\63 - a word relative operand, from operand 0..3
30 * \64..\67 - select between \6[0-3] and \7[0-3] depending on 16/32 bit
31 * assembly mode or the operand-size override on the operand
32 * \70..\73 - a long relative operand, from operand 0..3
33 * \74..\77 - a word constant, from the _segment_ part of operand 0..3
34 * \1ab - a ModRM, calculated on EA in operand a, with the spare
35 * field the register value of operand b.
36 * \140..\143 - an immediate word or signed byte for operand 0..3
37 * \144..\147 - or 2 (s-field) into next opcode byte if operand 0..3
38 * is a signed byte rather than a word.
39 * \150..\153 - an immediate dword or signed byte for operand 0..3
40 * \154..\157 - or 2 (s-field) into next opcode byte if operand 0..3
41 * is a signed byte rather than a dword.
42 * \160..\163 - this instruction uses DREX rather than REX, with the
43 * OC0 field set to 0, and the dest field taken from
45 * \164..\167 - this instruction uses DREX rather than REX, with the
46 * OC0 field set to 1, and the dest field taken from
48 * \170 - encodes the literal byte 0. (Some compilers don't take
49 * kindly to a zero byte in the _middle_ of a compile time
50 * string constant, so I had to put this hack in.)
51 * \171 - placement of DREX suffix in the absence of an EA
52 * \2ab - a ModRM, calculated on EA in operand a, with the spare
53 * field equal to digit b.
54 * \30x - might be an 0x67 byte, depending on the address size of
55 * the memory reference in operand x.
56 * \310 - indicates fixed 16-bit address size, i.e. optional 0x67.
57 * \311 - indicates fixed 32-bit address size, i.e. optional 0x67.
58 * \312 - (disassembler only) marker on LOOP, LOOPxx instructions.
59 * \313 - indicates fixed 64-bit address size, 0x67 invalid.
60 * \320 - indicates fixed 16-bit operand size, i.e. optional 0x66.
61 * \321 - indicates fixed 32-bit operand size, i.e. optional 0x66.
62 * \322 - indicates that this instruction is only valid when the
63 * operand size is the default (instruction to disassembler,
64 * generates no code in the assembler)
65 * \323 - indicates fixed 64-bit operand size, REX on extensions only.
66 * \324 - indicates 64-bit operand size requiring REX prefix.
67 * \330 - a literal byte follows in the code stream, to be added
68 * to the condition code value of the instruction.
69 * \331 - instruction not valid with REP prefix. Hint for
70 * disassembler only; for SSE instructions.
71 * \332 - REP prefix (0xF2 byte) used as opcode extension.
72 * \333 - REP prefix (0xF3 byte) used as opcode extension.
73 * \334 - LOCK prefix used instead of REX.R
74 * \335 - disassemble a rep (0xF3 byte) prefix as repe not rep.
75 * \340 - reserve <operand 0> bytes of uninitialized storage.
76 * Operand 0 had better be a segmentless constant.
77 * \364 - operand-size prefix (0x66) not permitted
78 * \365 - address-size prefix (0x67) not permitted
79 * \366 - operand-size prefix (0x66) used as opcode extension
80 * \367 - address-size prefix (0x67) used as opcode extension
81 * \370,\371,\372 - match only if operand 0 meets byte jump criteria.
82 * 370 is used for Jcc, 371 is used for JMP.
83 * \373 - assemble 0x03 if bits==16, 0x05 if bits==32;
84 * used for conditional jump over longer jump
100 int sib_present
; /* is a SIB byte necessary? */
101 int bytes
; /* # of bytes of offset needed */
102 int size
; /* lazy - this is sib+bytes+1 */
103 uint8_t modrm
, sib
, rex
, rip
; /* the bytes themselves */
106 static uint32_t cpu
; /* cpu level received from nasm.c */
107 static efunc errfunc
;
108 static struct ofmt
*outfmt
;
109 static ListGen
*list
;
111 static int32_t calcsize(int32_t, int32_t, int, insn
*, const char *);
112 static void gencode(int32_t, int32_t, int, insn
*, const char *, int32_t);
113 static int matches(const struct itemplate
*, insn
*, int bits
);
114 static int32_t regflag(const operand
*);
115 static int32_t regval(const operand
*);
116 static int rexflags(int, int32_t, int);
117 static int op_rexflags(const operand
*, int);
118 static ea
*process_ea(operand
*, ea
*, int, int, int32_t, int);
119 static int chsize(operand
*, int);
121 static void assert_no_prefix(insn
* ins
, int prefix
)
125 for (j
= 0; j
< ins
->nprefix
; j
++) {
126 if (ins
->prefixes
[j
] == prefix
) {
127 errfunc(ERR_NONFATAL
, "invalid %s prefix", prefix_name(prefix
));
134 * This routine wrappers the real output format's output routine,
135 * in order to pass a copy of the data off to the listing file
136 * generator at the same time.
138 static void out(int32_t offset
, int32_t segto
, const void *data
,
139 uint32_t type
, int32_t segment
, int32_t wrt
)
141 static int32_t lineno
= 0; /* static!!! */
142 static char *lnfname
= NULL
;
144 if ((type
& OUT_TYPMASK
) == OUT_ADDRESS
) {
145 if (segment
!= NO_SEG
|| wrt
!= NO_SEG
) {
147 * This address is relocated. We must write it as
148 * OUT_ADDRESS, so there's no work to be done here.
150 list
->output(offset
, data
, type
);
152 uint8_t p
[8], *q
= p
;
154 * This is a non-relocated address, and we're going to
155 * convert it into RAWDATA format.
157 if ((type
& OUT_SIZMASK
) == 4) {
158 WRITELONG(q
, *(int32_t *)data
);
159 list
->output(offset
, p
, OUT_RAWDATA
+ 4);
160 } else if ((type
& OUT_SIZMASK
) == 8) {
161 WRITEDLONG(q
, *(int64_t *)data
);
162 list
->output(offset
, p
, OUT_RAWDATA
+ 8);
164 WRITESHORT(q
, *(int32_t *)data
);
165 list
->output(offset
, p
, OUT_RAWDATA
+ 2);
168 } else if ((type
& OUT_TYPMASK
) == OUT_RAWDATA
) {
169 list
->output(offset
, data
, type
);
170 } else if ((type
& OUT_TYPMASK
) == OUT_RESERVE
) {
171 list
->output(offset
, NULL
, type
);
172 } else if ((type
& OUT_TYPMASK
) == OUT_REL2ADR
||
173 (type
& OUT_TYPMASK
) == OUT_REL4ADR
) {
174 list
->output(offset
, data
, type
);
178 * this call to src_get determines when we call the
179 * debug-format-specific "linenum" function
180 * it updates lineno and lnfname to the current values
181 * returning 0 if "same as last time", -2 if lnfname
182 * changed, and the amount by which lineno changed,
183 * if it did. thus, these variables must be static
186 if (src_get(&lineno
, &lnfname
)) {
187 outfmt
->current_dfmt
->linenum(lnfname
, lineno
, segto
);
190 outfmt
->output(segto
, data
, type
, segment
, wrt
);
193 static int jmp_match(int32_t segment
, int32_t offset
, int bits
,
194 insn
* ins
, const char *code
)
199 if (c
!= 0370 && c
!= 0371)
201 if (ins
->oprs
[0].opflags
& OPFLAG_FORWARD
) {
202 if ((optimizing
< 0 || (ins
->oprs
[0].type
& STRICT
))
206 return (pass0
== 0); /* match a forward reference */
208 isize
= calcsize(segment
, offset
, bits
, ins
, code
);
209 if (ins
->oprs
[0].segment
!= segment
)
211 isize
= ins
->oprs
[0].offset
- offset
- isize
; /* isize is now the delta */
212 if (isize
>= -128L && isize
<= 127L)
213 return 1; /* it is byte size */
218 int32_t assemble(int32_t segment
, int32_t offset
, int bits
, uint32_t cp
,
219 insn
* instruction
, struct ofmt
*output
, efunc error
,
222 const struct itemplate
*temp
;
227 int32_t start
= offset
;
228 int32_t wsize
= 0; /* size for DB etc. */
230 errfunc
= error
; /* to pass to other functions */
232 outfmt
= output
; /* likewise */
233 list
= listgen
; /* and again */
235 switch (instruction
->opcode
) {
262 int32_t t
= instruction
->times
;
265 "instruction->times < 0 (%ld) in assemble()", t
);
267 while (t
--) { /* repeat TIMES times */
268 for (e
= instruction
->eops
; e
; e
= e
->next
) {
269 if (e
->type
== EOT_DB_NUMBER
) {
271 if (e
->segment
!= NO_SEG
)
272 errfunc(ERR_NONFATAL
,
273 "one-byte relocation attempted");
275 uint8_t out_byte
= e
->offset
;
276 out(offset
, segment
, &out_byte
,
277 OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
279 } else if (wsize
> 8) {
280 errfunc(ERR_NONFATAL
, "integer supplied to a DT"
283 out(offset
, segment
, &e
->offset
,
284 OUT_ADDRESS
+ wsize
, e
->segment
, e
->wrt
);
286 } else if (e
->type
== EOT_DB_STRING
) {
289 out(offset
, segment
, e
->stringval
,
290 OUT_RAWDATA
+ e
->stringlen
, NO_SEG
, NO_SEG
);
291 align
= e
->stringlen
% wsize
;
294 align
= wsize
- align
;
295 out(offset
, segment
, "\0\0\0\0\0\0\0\0",
296 OUT_RAWDATA
+ align
, NO_SEG
, NO_SEG
);
298 offset
+= e
->stringlen
+ align
;
301 if (t
> 0 && t
== instruction
->times
- 1) {
303 * Dummy call to list->output to give the offset to the
306 list
->output(offset
, NULL
, OUT_RAWDATA
);
307 list
->uplevel(LIST_TIMES
);
310 if (instruction
->times
> 1)
311 list
->downlevel(LIST_TIMES
);
312 return offset
- start
;
315 if (instruction
->opcode
== I_INCBIN
) {
316 static char fname
[FILENAME_MAX
];
319 char *prefix
= "", *combine
;
320 char **pPrevPath
= NULL
;
322 len
= FILENAME_MAX
- 1;
323 if (len
> instruction
->eops
->stringlen
)
324 len
= instruction
->eops
->stringlen
;
325 strncpy(fname
, instruction
->eops
->stringval
, len
);
328 while (1) { /* added by alexfru: 'incbin' uses include paths */
329 combine
= nasm_malloc(strlen(prefix
) + len
+ 1);
330 strcpy(combine
, prefix
);
331 strcat(combine
, fname
);
333 if ((fp
= fopen(combine
, "rb")) != NULL
) {
339 pPrevPath
= pp_get_include_path_ptr(pPrevPath
);
340 if (pPrevPath
== NULL
)
346 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
348 else if (fseek(fp
, 0L, SEEK_END
) < 0)
349 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
352 static char buf
[2048];
353 int32_t t
= instruction
->times
;
357 if (instruction
->eops
->next
) {
358 base
= instruction
->eops
->next
->offset
;
360 if (instruction
->eops
->next
->next
&&
361 len
> instruction
->eops
->next
->next
->offset
)
362 len
= instruction
->eops
->next
->next
->offset
;
365 * Dummy call to list->output to give the offset to the
368 list
->output(offset
, NULL
, OUT_RAWDATA
);
369 list
->uplevel(LIST_INCBIN
);
373 fseek(fp
, base
, SEEK_SET
);
377 fread(buf
, 1, (l
> sizeof(buf
) ? sizeof(buf
) : l
),
381 * This shouldn't happen unless the file
382 * actually changes while we are reading
386 "`incbin': unexpected EOF while"
387 " reading file `%s'", fname
);
388 t
= 0; /* Try to exit cleanly */
391 out(offset
, segment
, buf
, OUT_RAWDATA
+ m
,
396 list
->downlevel(LIST_INCBIN
);
397 if (instruction
->times
> 1) {
399 * Dummy call to list->output to give the offset to the
402 list
->output(offset
, NULL
, OUT_RAWDATA
);
403 list
->uplevel(LIST_TIMES
);
404 list
->downlevel(LIST_TIMES
);
407 return instruction
->times
* len
;
409 return 0; /* if we're here, there's an error */
414 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++){
415 int m
= matches(temp
, instruction
, bits
);
418 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
420 if (m
== 100) { /* matches! */
421 const char *codes
= temp
->code
;
422 int32_t insn_size
= calcsize(segment
, offset
, bits
,
424 itimes
= instruction
->times
;
425 if (insn_size
< 0) /* shouldn't be, on pass two */
426 error(ERR_PANIC
, "errors made it through from pass one");
429 for (j
= 0; j
< instruction
->nprefix
; j
++) {
431 switch (instruction
->prefixes
[j
]) {
447 "cs segment base ignored in 64-bit mode");
454 "ds segment base ignored in 64-bit mode");
461 "es segment base ignored in 64-bit mode");
474 "ss segment base ignored in 64-bit mode");
481 "segr6 and segr7 cannot be used as prefixes");
486 "16-bit addressing is not supported "
506 error(ERR_PANIC
, "invalid instruction prefix");
509 out(offset
, segment
, &c
, OUT_RAWDATA
+ 1,
514 insn_end
= offset
+ insn_size
;
515 gencode(segment
, offset
, bits
, instruction
, codes
,
518 if (itimes
> 0 && itimes
== instruction
->times
- 1) {
520 * Dummy call to list->output to give the offset to the
523 list
->output(offset
, NULL
, OUT_RAWDATA
);
524 list
->uplevel(LIST_TIMES
);
527 if (instruction
->times
> 1)
528 list
->downlevel(LIST_TIMES
);
529 return offset
- start
;
530 } else if (m
> 0 && m
> size_prob
) {
536 if (temp
->opcode
== -1) { /* didn't match any instruction */
539 error(ERR_NONFATAL
, "operation size not specified");
542 error(ERR_NONFATAL
, "mismatch in operand sizes");
545 error(ERR_NONFATAL
, "no instruction for this cpu level");
548 error(ERR_NONFATAL
, "instruction not supported in 64-bit mode");
552 "invalid combination of opcode and operands");
559 int32_t insn_size(int32_t segment
, int32_t offset
, int bits
, uint32_t cp
,
560 insn
* instruction
, efunc error
)
562 const struct itemplate
*temp
;
564 errfunc
= error
; /* to pass to other functions */
567 if (instruction
->opcode
== -1)
570 if (instruction
->opcode
== I_DB
|| instruction
->opcode
== I_DW
||
571 instruction
->opcode
== I_DD
|| instruction
->opcode
== I_DQ
||
572 instruction
->opcode
== I_DT
|| instruction
->opcode
== I_DO
) {
574 int32_t isize
, osize
, wsize
= 0; /* placate gcc */
577 switch (instruction
->opcode
) {
600 for (e
= instruction
->eops
; e
; e
= e
->next
) {
604 if (e
->type
== EOT_DB_NUMBER
)
606 else if (e
->type
== EOT_DB_STRING
)
607 osize
= e
->stringlen
;
609 align
= (-osize
) % wsize
;
612 isize
+= osize
+ align
;
614 return isize
* instruction
->times
;
617 if (instruction
->opcode
== I_INCBIN
) {
618 char fname
[FILENAME_MAX
];
621 char *prefix
= "", *combine
;
622 char **pPrevPath
= NULL
;
624 len
= FILENAME_MAX
- 1;
625 if (len
> instruction
->eops
->stringlen
)
626 len
= instruction
->eops
->stringlen
;
627 strncpy(fname
, instruction
->eops
->stringval
, len
);
630 while (1) { /* added by alexfru: 'incbin' uses include paths */
631 combine
= nasm_malloc(strlen(prefix
) + len
+ 1);
632 strcpy(combine
, prefix
);
633 strcat(combine
, fname
);
635 if ((fp
= fopen(combine
, "rb")) != NULL
) {
641 pPrevPath
= pp_get_include_path_ptr(pPrevPath
);
642 if (pPrevPath
== NULL
)
648 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
650 else if (fseek(fp
, 0L, SEEK_END
) < 0)
651 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
656 if (instruction
->eops
->next
) {
657 len
-= instruction
->eops
->next
->offset
;
658 if (instruction
->eops
->next
->next
&&
659 len
> instruction
->eops
->next
->next
->offset
) {
660 len
= instruction
->eops
->next
->next
->offset
;
663 return instruction
->times
* len
;
665 return 0; /* if we're here, there's an error */
668 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++) {
669 int m
= matches(temp
, instruction
, bits
);
671 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
674 /* we've matched an instruction. */
676 const char *codes
= temp
->code
;
679 isize
= calcsize(segment
, offset
, bits
, instruction
, codes
);
682 for (j
= 0; j
< instruction
->nprefix
; j
++) {
683 if ((instruction
->prefixes
[j
] != P_A16
&&
684 instruction
->prefixes
[j
] != P_O16
&& bits
== 16) ||
685 (instruction
->prefixes
[j
] != P_A32
&&
686 instruction
->prefixes
[j
] != P_O32
&& bits
>= 32)) {
690 return isize
* instruction
->times
;
693 return -1; /* didn't match any instruction */
696 /* check that opn[op] is a signed byte of size 16 or 32,
697 and return the signed value*/
698 static int is_sbyte(insn
* ins
, int op
, int size
)
703 ret
= !(ins
->forw_ref
&& ins
->oprs
[op
].opflags
) && /* dead in the water on forward reference or External */
705 !(ins
->oprs
[op
].type
& STRICT
) &&
706 ins
->oprs
[op
].wrt
== NO_SEG
&& ins
->oprs
[op
].segment
== NO_SEG
;
708 v
= ins
->oprs
[op
].offset
;
710 v
= (int16_t)v
; /* sign extend if 16 bits */
712 return ret
&& v
>= -128L && v
<= 127L;
715 static int32_t calcsize(int32_t segment
, int32_t offset
, int bits
,
716 insn
* ins
, const char *codes
)
721 ins
->rex
= 0; /* Ensure REX is reset */
723 (void)segment
; /* Don't warn that this parameter is unused */
724 (void)offset
; /* Don't warn that this parameter is unused */
727 switch (c
= *codes
++) {
731 codes
+= c
, length
+= c
;
744 op_rexflags(&ins
->oprs
[c
- 010], REX_B
|REX_H
|REX_P
|REX_W
);
775 if (ins
->oprs
[c
- 034].type
& (BITS16
| BITS32
| BITS64
))
776 length
+= (ins
->oprs
[c
- 034].type
& BITS16
) ? 2 : 4;
778 length
+= (bits
== 16) ? 2 : 4;
790 length
+= ((ins
->oprs
[c
- 044].addr_size
?
791 ins
->oprs
[c
- 044].addr_size
: bits
) >> 3);
803 length
+= 8; /* MOV reg64/imm */
815 if (ins
->oprs
[c
- 064].type
& (BITS16
| BITS32
| BITS64
))
816 length
+= (ins
->oprs
[c
- 064].type
& BITS16
) ? 2 : 4;
818 length
+= (bits
== 16) ? 2 : 4;
836 length
+= is_sbyte(ins
, c
- 0140, 16) ? 1 : 2;
849 length
+= is_sbyte(ins
, c
- 0150, 32) ? 1 : 4;
864 ins
->drexdst
= regval(&ins
->oprs
[c
& 3]);
871 ins
->rex
|= REX_D
|REX_OC
;
872 ins
->drexdst
= regval(&ins
->oprs
[c
& 3]);
883 length
+= chsize(&ins
->oprs
[c
- 0300], bits
);
886 length
+= (bits
!= 16);
889 length
+= (bits
!= 32);
896 length
+= (bits
!= 16);
899 length
+= (bits
== 16);
919 assert_no_prefix(ins
, P_LOCK
);
927 if (ins
->oprs
[0].segment
!= NO_SEG
)
928 errfunc(ERR_NONFATAL
, "attempt to reserve non-constant"
929 " quantity of BSS space");
931 length
+= ins
->oprs
[0].offset
<< (c
- 0340);
947 default: /* can't do it by 'case' statements */
948 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
952 ea_data
.rex
= 0; /* Ensure ea.REX is initially 0 */
955 /* pick rfield from operand b */
956 rflags
= regflag(&ins
->oprs
[c
& 7]);
957 rfield
= regvals
[ins
->oprs
[c
& 7].basereg
];
964 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
965 rfield
, rflags
, ins
->forw_ref
)) {
966 errfunc(ERR_NONFATAL
, "invalid effective address");
969 ins
->rex
|= ea_data
.rex
;
970 length
+= ea_data
.size
;
973 errfunc(ERR_PANIC
, "internal instruction table corrupt"
974 ": instruction code 0x%02X given", c
);
977 ins
->rex
&= rex_mask
;
979 if (ins
->rex
& REX_D
) {
980 if (ins
->rex
& REX_H
) {
981 errfunc(ERR_NONFATAL
, "cannot use high register in drex instruction");
984 if (bits
!= 64 && ((ins
->rex
& (REX_W
|REX_X
|REX_B
)) ||
986 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
990 } else if (ins
->rex
& REX_REAL
) {
991 if (ins
->rex
& REX_H
) {
992 errfunc(ERR_NONFATAL
, "cannot use high register in rex instruction");
994 } else if (bits
== 64 ||
995 ((ins
->rex
& REX_L
) &&
996 !(ins
->rex
& (REX_P
|REX_W
|REX_X
|REX_B
)) &&
1000 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1008 #define EMIT_REX() \
1009 if (!(ins->rex & REX_D) && (ins->rex & REX_REAL) && (bits == 64)) { \
1010 ins->rex = (ins->rex & REX_REAL)|REX_P; \
1011 out(offset, segment, &ins->rex, OUT_RAWDATA+1, NO_SEG, NO_SEG); \
1016 static void gencode(int32_t segment
, int32_t offset
, int bits
,
1017 insn
* ins
, const char *codes
, int32_t insn_end
)
1019 static char condval
[] = { /* conditional opcodes */
1020 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
1021 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
1022 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
1030 switch (c
= *codes
++) {
1035 out(offset
, segment
, codes
, OUT_RAWDATA
+ c
, NO_SEG
, NO_SEG
);
1042 switch (ins
->oprs
[0].basereg
) {
1044 bytes
[0] = 0x0E + (c
== 0x04 ? 1 : 0);
1047 bytes
[0] = 0x1E + (c
== 0x04 ? 1 : 0);
1050 bytes
[0] = 0x06 + (c
== 0x04 ? 1 : 0);
1053 bytes
[0] = 0x16 + (c
== 0x04 ? 1 : 0);
1057 "bizarre 8086 segment register received");
1059 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1065 switch (ins
->oprs
[0].basereg
) {
1067 bytes
[0] = 0xA0 + (c
== 0x05 ? 1 : 0);
1070 bytes
[0] = 0xA8 + (c
== 0x05 ? 1 : 0);
1074 "bizarre 386 segment register received");
1076 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1085 bytes
[0] = *codes
++ + ((regval(&ins
->oprs
[c
- 010])) & 7);
1086 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1094 if (ins
->oprs
[c
- 014].offset
< -128
1095 || ins
->oprs
[c
- 014].offset
> 127) {
1096 errfunc(ERR_WARNING
, "signed byte value exceeds bounds");
1099 if (ins
->oprs
[c
- 014].segment
!= NO_SEG
) {
1100 data
= ins
->oprs
[c
- 014].offset
;
1101 out(offset
, segment
, &data
, OUT_ADDRESS
+ 1,
1102 ins
->oprs
[c
- 014].segment
, ins
->oprs
[c
- 014].wrt
);
1104 bytes
[0] = ins
->oprs
[c
- 014].offset
;
1105 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
,
1115 if (ins
->oprs
[c
- 020].offset
< -256
1116 || ins
->oprs
[c
- 020].offset
> 255) {
1117 errfunc(ERR_WARNING
, "byte value exceeds bounds");
1119 if (ins
->oprs
[c
- 020].segment
!= NO_SEG
) {
1120 data
= ins
->oprs
[c
- 020].offset
;
1121 out(offset
, segment
, &data
, OUT_ADDRESS
+ 1,
1122 ins
->oprs
[c
- 020].segment
, ins
->oprs
[c
- 020].wrt
);
1124 bytes
[0] = ins
->oprs
[c
- 020].offset
;
1125 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
,
1135 if (ins
->oprs
[c
- 024].offset
< 0
1136 || ins
->oprs
[c
- 024].offset
> 255)
1137 errfunc(ERR_WARNING
, "unsigned byte value exceeds bounds");
1138 if (ins
->oprs
[c
- 024].segment
!= NO_SEG
) {
1139 data
= ins
->oprs
[c
- 024].offset
;
1140 out(offset
, segment
, &data
, OUT_ADDRESS
+ 1,
1141 ins
->oprs
[c
- 024].segment
, ins
->oprs
[c
- 024].wrt
);
1143 bytes
[0] = ins
->oprs
[c
- 024].offset
;
1144 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
,
1154 if (ins
->oprs
[c
- 030].segment
== NO_SEG
&&
1155 ins
->oprs
[c
- 030].wrt
== NO_SEG
&&
1156 (ins
->oprs
[c
- 030].offset
< -65536L ||
1157 ins
->oprs
[c
- 030].offset
> 65535L)) {
1158 errfunc(ERR_WARNING
, "word value exceeds bounds");
1160 data
= ins
->oprs
[c
- 030].offset
;
1161 out(offset
, segment
, &data
, OUT_ADDRESS
+ 2,
1162 ins
->oprs
[c
- 030].segment
, ins
->oprs
[c
- 030].wrt
);
1170 if (ins
->oprs
[c
- 034].type
& (BITS16
| BITS32
))
1171 size
= (ins
->oprs
[c
- 034].type
& BITS16
) ? 2 : 4;
1173 size
= (bits
== 16) ? 2 : 4;
1174 data
= ins
->oprs
[c
- 034].offset
;
1175 if (size
== 2 && (data
< -65536L || data
> 65535L))
1176 errfunc(ERR_WARNING
, "word value exceeds bounds");
1177 out(offset
, segment
, &data
, OUT_ADDRESS
+ size
,
1178 ins
->oprs
[c
- 034].segment
, ins
->oprs
[c
- 034].wrt
);
1186 data
= ins
->oprs
[c
- 040].offset
;
1187 out(offset
, segment
, &data
, OUT_ADDRESS
+ 4,
1188 ins
->oprs
[c
- 040].segment
, ins
->oprs
[c
- 040].wrt
);
1196 data
= ins
->oprs
[c
- 044].offset
;
1197 size
= ((ins
->oprs
[c
- 044].addr_size
?
1198 ins
->oprs
[c
- 044].addr_size
: bits
) >> 3);
1199 if (size
== 2 && (data
< -65536L || data
> 65535L))
1200 errfunc(ERR_WARNING
, "word value exceeds bounds");
1201 out(offset
, segment
, &data
, OUT_ADDRESS
+ size
,
1202 ins
->oprs
[c
- 044].segment
, ins
->oprs
[c
- 044].wrt
);
1210 if (ins
->oprs
[c
- 050].segment
!= segment
)
1211 errfunc(ERR_NONFATAL
,
1212 "short relative jump outside segment");
1213 data
= ins
->oprs
[c
- 050].offset
- insn_end
;
1214 if (data
> 127 || data
< -128)
1215 errfunc(ERR_NONFATAL
, "short jump is out of range");
1217 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1225 data
= (int64_t)ins
->oprs
[c
- 054].offset
;
1226 out(offset
, segment
, &data
, OUT_ADDRESS
+ 8,
1227 ins
->oprs
[c
- 054].segment
, ins
->oprs
[c
- 054].wrt
);
1235 if (ins
->oprs
[c
- 060].segment
!= segment
) {
1236 data
= ins
->oprs
[c
- 060].offset
;
1237 out(offset
, segment
, &data
,
1238 OUT_REL2ADR
+ insn_end
- offset
,
1239 ins
->oprs
[c
- 060].segment
, ins
->oprs
[c
- 060].wrt
);
1241 data
= ins
->oprs
[c
- 060].offset
- insn_end
;
1242 out(offset
, segment
, &data
,
1243 OUT_ADDRESS
+ 2, NO_SEG
, NO_SEG
);
1252 if (ins
->oprs
[c
- 064].type
& (BITS16
| BITS32
| BITS64
))
1253 size
= (ins
->oprs
[c
- 064].type
& BITS16
) ? 2 : 4;
1255 size
= (bits
== 16) ? 2 : 4;
1256 if (ins
->oprs
[c
- 064].segment
!= segment
) {
1257 int32_t reltype
= (size
== 2 ? OUT_REL2ADR
: OUT_REL4ADR
);
1258 data
= ins
->oprs
[c
- 064].offset
;
1259 out(offset
, segment
, &data
, reltype
+ insn_end
- offset
,
1260 ins
->oprs
[c
- 064].segment
, ins
->oprs
[c
- 064].wrt
);
1262 data
= ins
->oprs
[c
- 064].offset
- insn_end
;
1263 out(offset
, segment
, &data
,
1264 OUT_ADDRESS
+ size
, NO_SEG
, NO_SEG
);
1273 if (ins
->oprs
[c
- 070].segment
!= segment
) {
1274 data
= ins
->oprs
[c
- 070].offset
;
1275 out(offset
, segment
, &data
,
1276 OUT_REL4ADR
+ insn_end
- offset
,
1277 ins
->oprs
[c
- 070].segment
, ins
->oprs
[c
- 070].wrt
);
1279 data
= ins
->oprs
[c
- 070].offset
- insn_end
;
1280 out(offset
, segment
, &data
,
1281 OUT_ADDRESS
+ 4, NO_SEG
, NO_SEG
);
1290 if (ins
->oprs
[c
- 074].segment
== NO_SEG
)
1291 errfunc(ERR_NONFATAL
, "value referenced by FAR is not"
1294 out(offset
, segment
, &data
, OUT_ADDRESS
+ 2,
1295 outfmt
->segbase(1 + ins
->oprs
[c
- 074].segment
),
1296 ins
->oprs
[c
- 074].wrt
);
1304 data
= ins
->oprs
[c
- 0140].offset
;
1305 if (is_sbyte(ins
, c
- 0140, 16)) {
1307 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
,
1311 if (ins
->oprs
[c
- 0140].segment
== NO_SEG
&&
1312 ins
->oprs
[c
- 0140].wrt
== NO_SEG
&&
1313 (data
< -65536L || data
> 65535L)) {
1314 errfunc(ERR_WARNING
, "word value exceeds bounds");
1316 out(offset
, segment
, &data
, OUT_ADDRESS
+ 2,
1317 ins
->oprs
[c
- 0140].segment
, ins
->oprs
[c
- 0140].wrt
);
1328 bytes
[0] = *codes
++;
1329 if (is_sbyte(ins
, c
- 0144, 16))
1330 bytes
[0] |= 2; /* s-bit */
1331 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1339 data
= ins
->oprs
[c
- 0150].offset
;
1340 if (is_sbyte(ins
, c
- 0150, 32)) {
1342 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
,
1346 out(offset
, segment
, &data
, OUT_ADDRESS
+ 4,
1347 ins
->oprs
[c
- 0150].segment
, ins
->oprs
[c
- 0150].wrt
);
1358 bytes
[0] = *codes
++;
1359 if (is_sbyte(ins
, c
- 0154, 32))
1360 bytes
[0] |= 2; /* s-bit */
1361 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1377 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1383 (ins
->drexdst
<< 4) |
1384 (ins
->rex
& REX_OC
? 0x08 : 0) |
1385 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1387 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1395 if (chsize(&ins
->oprs
[c
- 0300], bits
)) {
1397 out(offset
, segment
, bytes
,
1398 OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1407 out(offset
, segment
, bytes
,
1408 OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1417 out(offset
, segment
, bytes
,
1418 OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1434 out(offset
, segment
, bytes
,
1435 OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1444 out(offset
, segment
, bytes
,
1445 OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1460 *bytes
= *codes
++ ^ condval
[ins
->condition
];
1461 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1470 *bytes
= c
- 0332 + 0xF2;
1471 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1476 if (ins
->rex
& REX_R
) {
1478 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1481 ins
->rex
&= ~(REX_L
|REX_R
);
1490 if (ins
->oprs
[0].segment
!= NO_SEG
)
1491 errfunc(ERR_PANIC
, "non-constant BSS size in pass two");
1493 int32_t size
= ins
->oprs
[0].offset
<< (c
- 0340);
1495 out(offset
, segment
, NULL
,
1496 OUT_RESERVE
+ size
, NO_SEG
, NO_SEG
);
1507 *bytes
= c
- 0366 + 0x66;
1508 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1518 *bytes
= bits
== 16 ? 3 : 5;
1519 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1, NO_SEG
, NO_SEG
);
1523 default: /* can't do it by 'case' statements */
1524 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1532 /* pick rfield from operand b */
1533 rflags
= regflag(&ins
->oprs
[c
& 7]);
1534 rfield
= regvals
[ins
->oprs
[c
& 7].basereg
];
1536 /* rfield is constant */
1542 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1543 rfield
, rflags
, ins
->forw_ref
)) {
1544 errfunc(ERR_NONFATAL
, "invalid effective address");
1548 *p
++ = ea_data
.modrm
;
1549 if (ea_data
.sib_present
)
1552 /* DREX suffixes come between the SIB and the displacement */
1553 if (ins
->rex
& REX_D
) {
1555 (ins
->drexdst
<< 4) |
1556 (ins
->rex
& REX_OC
? 0x08 : 0) |
1557 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1562 out(offset
, segment
, bytes
, OUT_RAWDATA
+ s
,
1565 switch (ea_data
.bytes
) {
1569 if (ins
->oprs
[(c
>> 3) & 7].segment
!= NO_SEG
) {
1570 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1571 out(offset
, segment
, &data
, OUT_ADDRESS
+ 1,
1572 ins
->oprs
[(c
>> 3) & 7].segment
,
1573 ins
->oprs
[(c
>> 3) & 7].wrt
);
1575 *bytes
= ins
->oprs
[(c
>> 3) & 7].offset
;
1576 out(offset
, segment
, bytes
, OUT_RAWDATA
+ 1,
1584 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1585 if (ea_data
.rip
&& (ins
->oprs
[(c
>> 3) & 7].segment
== 0xFFFFFFFF))
1586 ea_data
.rip
= 0; /* Make distinction between Symbols and Immediates */
1587 out(offset
, segment
, &data
, /* RIP = Relative, not Absolute */
1588 (ea_data
.rip
? OUT_REL4ADR
: OUT_ADDRESS
) + ea_data
.bytes
,
1589 ins
->oprs
[(c
>> 3) & 7].segment
,
1590 ins
->oprs
[(c
>> 3) & 7].wrt
);
1596 errfunc(ERR_PANIC
, "internal instruction table corrupt"
1597 ": instruction code 0x%02X given", c
);
1601 static int32_t regflag(const operand
* o
)
1603 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1604 errfunc(ERR_PANIC
, "invalid operand passed to regflag()");
1606 return reg_flags
[o
->basereg
];
1609 static int32_t regval(const operand
* o
)
1611 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1612 errfunc(ERR_PANIC
, "invalid operand passed to regval()");
1614 return regvals
[o
->basereg
];
1617 static int op_rexflags(const operand
* o
, int mask
)
1622 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1623 errfunc(ERR_PANIC
, "invalid operand passed to op_rexflags()");
1626 flags
= reg_flags
[o
->basereg
];
1627 val
= regvals
[o
->basereg
];
1629 return rexflags(val
, flags
, mask
);
1632 static int rexflags(int val
, int32_t flags
, int mask
)
1637 rex
|= REX_B
|REX_X
|REX_R
;
1640 if (!(REG_HIGH
& ~flags
)) /* AH, CH, DH, BH */
1642 else if (!(REG8
& ~flags
) && val
>= 4) /* SPL, BPL, SIL, DIL */
1648 static int matches(const struct itemplate
*itemp
, insn
* instruction
, int bits
)
1650 int i
, size
[MAX_OPERANDS
], asize
, oprs
, ret
;
1657 if (itemp
->opcode
!= instruction
->opcode
)
1661 * Count the operands
1663 if (itemp
->operands
!= instruction
->operands
)
1667 * Check that no spurious colons or TOs are present
1669 for (i
= 0; i
< itemp
->operands
; i
++)
1670 if (instruction
->oprs
[i
].type
& ~itemp
->opd
[i
] & (COLON
| TO
))
1674 * Check that the operand flags all match up
1676 for (i
= 0; i
< itemp
->operands
; i
++) {
1677 if (itemp
->opd
[i
] & SAME_AS
) {
1678 int j
= itemp
->opd
[i
] & ~SAME_AS
;
1679 if (instruction
->oprs
[i
].type
!= instruction
->oprs
[j
].type
||
1680 instruction
->oprs
[i
].basereg
!= instruction
->oprs
[j
].basereg
)
1682 } else if (itemp
->opd
[i
] & ~instruction
->oprs
[i
].type
||
1683 ((itemp
->opd
[i
] & SIZE_MASK
) &&
1684 ((itemp
->opd
[i
] ^ instruction
->oprs
[i
].type
) & SIZE_MASK
))) {
1685 if ((itemp
->opd
[i
] & ~instruction
->oprs
[i
].type
& ~SIZE_MASK
) ||
1686 (instruction
->oprs
[i
].type
& SIZE_MASK
))
1694 * Check operand sizes
1696 if (itemp
->flags
& IF_ARMASK
) {
1697 memset(size
, 0, sizeof size
);
1699 switch (itemp
->flags
& IF_ARMASK
) {
1713 break; /* Shouldn't happen */
1715 switch (itemp
->flags
& IF_SMASK
) {
1736 switch (itemp
->flags
& IF_SMASK
) {
1739 oprs
= itemp
->operands
;
1743 oprs
= itemp
->operands
;
1747 oprs
= itemp
->operands
;
1751 oprs
= itemp
->operands
;
1755 oprs
= itemp
->operands
;
1760 for (i
= 0; i
< MAX_OPERANDS
; i
++)
1764 if (itemp
->flags
& (IF_SM
| IF_SM2
)) {
1765 oprs
= (itemp
->flags
& IF_SM2
? 2 : itemp
->operands
);
1767 for (i
= 0; i
< oprs
; i
++) {
1768 if ((asize
= itemp
->opd
[i
] & SIZE_MASK
) != 0) {
1770 for (j
= 0; j
< oprs
; j
++)
1776 oprs
= itemp
->operands
;
1779 for (i
= 0; i
< itemp
->operands
; i
++) {
1780 if (!(itemp
->opd
[i
] & SIZE_MASK
) &&
1781 (instruction
->oprs
[i
].type
& SIZE_MASK
& ~size
[i
]))
1786 * Check template is okay at the set cpu level
1788 if (((itemp
->flags
& IF_PLEVEL
) > cpu
))
1792 * Check if instruction is available in long mode
1794 if ((itemp
->flags
& IF_NOLONG
) && (bits
== 64))
1798 * Check if special handling needed for Jumps
1800 if ((uint8_t)(itemp
->code
[0]) >= 0370)
1806 static ea
*process_ea(operand
* input
, ea
* output
, int addrbits
,
1807 int rfield
, int32_t rflags
, int forw_ref
)
1809 output
->rip
= FALSE
;
1811 /* REX flags for the rfield operand */
1812 output
->rex
|= rexflags(rfield
, rflags
, REX_R
|REX_P
|REX_W
|REX_H
);
1814 if (!(REGISTER
& ~input
->type
)) { /* register direct */
1818 if (input
->basereg
< EXPR_REG_START
/* Verify as Register */
1819 || input
->basereg
>= REG_ENUM_LIMIT
)
1822 i
= regvals
[input
->basereg
];
1825 return NULL
; /* Invalid EA register */
1827 output
->rex
|= op_rexflags(input
, REX_B
|REX_P
|REX_W
|REX_H
);
1829 output
->sib_present
= FALSE
; /* no SIB necessary */
1830 output
->bytes
= 0; /* no offset necessary either */
1831 output
->modrm
= 0xC0 | ((rfield
& 7) << 3) | (i
& 7);
1832 } else { /* it's a memory reference */
1833 if (input
->basereg
== -1
1834 && (input
->indexreg
== -1 || input
->scale
== 0)) {
1835 /* it's a pure offset */
1836 if (input
->addr_size
)
1837 addrbits
= input
->addr_size
;
1839 if (globalbits
== 64 && (~input
->type
& IP_REL
)) {
1840 int scale
, index
, base
;
1841 output
->sib_present
= TRUE
;
1845 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
1847 output
->modrm
= 4 | ((rfield
& 7) << 3);
1848 output
->rip
= FALSE
;
1850 output
->sib_present
= FALSE
;
1851 output
->bytes
= (addrbits
!= 16 ? 4 : 2);
1852 output
->modrm
= (addrbits
!= 16 ? 5 : 6) | ((rfield
& 7) << 3);
1853 output
->rip
= globalbits
== 64;
1855 } else { /* it's an indirection */
1856 int i
= input
->indexreg
, b
= input
->basereg
, s
= input
->scale
;
1857 int32_t o
= input
->offset
, seg
= input
->segment
;
1858 int hb
= input
->hintbase
, ht
= input
->hinttype
;
1861 int32_t ix
, bx
; /* register flags */
1864 i
= -1; /* make this easy, at least */
1866 if (i
>= EXPR_REG_START
&& i
< REG_ENUM_LIMIT
) {
1874 if (b
!= -1 && b
>= EXPR_REG_START
&& b
< REG_ENUM_LIMIT
) {
1882 /* check for a 32/64-bit memory reference... */
1883 if ((ix
|bx
) & (BITS32
|BITS64
)) {
1884 /* it must be a 32/64-bit memory reference. Firstly we have
1885 * to check that all registers involved are type E/Rxx. */
1886 int32_t sok
= BITS32
|BITS64
;
1889 if (!(REG64
& ~ix
) || !(REG32
& ~ix
))
1897 return NULL
; /* Invalid register */
1898 if (~sok
& bx
& SIZE_MASK
)
1899 return NULL
; /* Invalid size */
1903 /* While we're here, ensure the user didn't specify WORD. */
1904 if (input
->addr_size
== 16 ||
1905 (input
->addr_size
== 32 && !(sok
& BITS32
)) ||
1906 (input
->addr_size
== 64 && !(sok
& BITS64
)))
1909 /* now reorganize base/index */
1910 if (s
== 1 && bt
!= it
&& bt
!= -1 && it
!= -1 &&
1911 ((hb
== b
&& ht
== EAH_NOTBASE
)
1912 || (hb
== i
&& ht
== EAH_MAKEBASE
))) {
1913 /* swap if hints say so */
1914 t
= bt
, bt
= it
, it
= t
;
1915 t
= bx
, bx
= ix
, ix
= t
;
1917 if (bt
== it
) /* convert EAX+2*EAX to 3*EAX */
1918 bt
= -1, bx
= 0, s
++;
1919 if (bt
== -1 && s
== 1 && !(hb
== it
&& ht
== EAH_NOTBASE
)) {
1920 /* make single reg base, unless hint */
1921 bt
= it
, bx
= ix
, it
= -1, ix
= 0;
1923 if (((s
== 2 && it
!= REG_NUM_ESP
1924 && !(input
->eaflags
& EAF_TIMESTWO
)) || s
== 3
1925 || s
== 5 || s
== 9) && bt
== -1)
1926 bt
= it
, bx
= ix
, s
--; /* convert 3*EAX to EAX+2*EAX */
1927 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
1928 && (input
->eaflags
& EAF_TIMESTWO
))
1929 it
= bt
, ix
= bx
, bt
= -1, bx
= 0, s
= 1;
1930 /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */
1931 if (s
== 1 && it
== REG_NUM_ESP
) {
1932 /* swap ESP into base if scale is 1 */
1933 t
= it
, it
= bt
, bt
= t
;
1934 t
= ix
, ix
= bx
, bx
= t
;
1936 if (it
== REG_NUM_ESP
1937 || (s
!= 1 && s
!= 2 && s
!= 4 && s
!= 8 && it
!= -1))
1938 return NULL
; /* wrong, for various reasons */
1940 output
->rex
|= rexflags(it
, ix
, REX_X
);
1941 output
->rex
|= rexflags(bt
, bx
, REX_B
);
1943 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
) {
1952 if (rm
!= REG_NUM_EBP
&& o
== 0 &&
1953 seg
== NO_SEG
&& !forw_ref
&&
1955 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
1957 else if (input
->eaflags
& EAF_BYTEOFFS
||
1958 (o
>= -128 && o
<= 127 && seg
== NO_SEG
1960 && !(input
->eaflags
& EAF_WORDOFFS
)))
1966 output
->sib_present
= FALSE
;
1967 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
1968 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
1971 int mod
, scale
, index
, base
;
1991 default: /* then what the smeg is it? */
1992 return NULL
; /* panic */
2000 if (base
!= REG_NUM_EBP
&& o
== 0 &&
2001 seg
== NO_SEG
&& !forw_ref
&&
2003 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2005 else if (input
->eaflags
& EAF_BYTEOFFS
||
2006 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2008 && !(input
->eaflags
& EAF_WORDOFFS
)))
2014 output
->sib_present
= TRUE
;
2015 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
2016 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | 4;
2017 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
2019 } else { /* it's 16-bit */
2022 /* check for 64-bit long mode */
2026 /* check all registers are BX, BP, SI or DI */
2027 if ((b
!= -1 && b
!= R_BP
&& b
!= R_BX
&& b
!= R_SI
2028 && b
!= R_DI
) || (i
!= -1 && i
!= R_BP
&& i
!= R_BX
2029 && i
!= R_SI
&& i
!= R_DI
))
2032 /* ensure the user didn't specify DWORD/QWORD */
2033 if (input
->addr_size
== 32 || input
->addr_size
== 64)
2036 if (s
!= 1 && i
!= -1)
2037 return NULL
; /* no can do, in 16-bit EA */
2038 if (b
== -1 && i
!= -1) {
2043 if ((b
== R_SI
|| b
== R_DI
) && i
!= -1) {
2048 /* have BX/BP as base, SI/DI index */
2050 return NULL
; /* shouldn't ever happen, in theory */
2051 if (i
!= -1 && b
!= -1 &&
2052 (i
== R_BP
|| i
== R_BX
|| b
== R_SI
|| b
== R_DI
))
2053 return NULL
; /* invalid combinations */
2054 if (b
== -1) /* pure offset: handled above */
2055 return NULL
; /* so if it gets to here, panic! */
2059 switch (i
* 256 + b
) {
2060 case R_SI
* 256 + R_BX
:
2063 case R_DI
* 256 + R_BX
:
2066 case R_SI
* 256 + R_BP
:
2069 case R_DI
* 256 + R_BP
:
2087 if (rm
== -1) /* can't happen, in theory */
2088 return NULL
; /* so panic if it does */
2090 if (o
== 0 && seg
== NO_SEG
&& !forw_ref
&& rm
!= 6 &&
2091 !(input
->eaflags
& (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2093 else if (input
->eaflags
& EAF_BYTEOFFS
||
2094 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2096 && !(input
->eaflags
& EAF_WORDOFFS
)))
2101 output
->sib_present
= FALSE
; /* no SIB - it's 16-bit */
2102 output
->bytes
= mod
; /* bytes of offset needed */
2103 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
2108 output
->size
= 1 + output
->sib_present
+ output
->bytes
;
2112 static int chsize(operand
* input
, int addrbits
)
2114 if (!(MEMORY
& ~input
->type
)) {
2117 if (input
->indexreg
< EXPR_REG_START
/* Verify as Register */
2118 || input
->indexreg
>= REG_ENUM_LIMIT
)
2121 i
= reg_flags
[input
->indexreg
];
2123 if (input
->basereg
< EXPR_REG_START
/* Verify as Register */
2124 || input
->basereg
>= REG_ENUM_LIMIT
)
2127 b
= reg_flags
[input
->basereg
];
2129 if (input
->scale
== 0)
2132 if (!i
&& !b
) /* pure offset */
2133 return (input
->addr_size
!= 0 && input
->addr_size
!= addrbits
);
2135 if (!(REG32
& ~i
) || !(REG32
& ~b
))
2136 return (addrbits
!= 32);
2138 return (addrbits
== 32);