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 license given in the file "LICENSE"
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 the address size of the instruction.
26 * \50..\53 - a byte relative operand, from operand 0..3
27 * \54..\57 - a qword immediate operand, from operand 0..3
28 * \60..\63 - a word relative operand, from operand 0..3
29 * \64..\67 - select between \6[0-3] and \7[0-3] depending on 16/32 bit
30 * assembly mode or the operand-size override on the operand
31 * \70..\73 - a long relative operand, from operand 0..3
32 * \74..\77 - a word constant, from the _segment_ part of operand 0..3
33 * \1ab - a ModRM, calculated on EA in operand a, with the spare
34 * field the register value of operand b.
35 * \140..\143 - an immediate word or signed byte for operand 0..3
36 * \144..\147 - or 2 (s-field) into opcode byte if operand 0..3
37 * is a signed byte rather than a word. Opcode byte follows.
38 * \150..\153 - an immediate dword or signed byte for operand 0..3
39 * \154..\157 - or 2 (s-field) into opcode byte if operand 0..3
40 * is a signed byte rather than a dword. Opcode byte follows.
41 * \160..\163 - this instruction uses DREX rather than REX, with the
42 * OC0 field set to 0, and the dest field taken from
44 * \164..\167 - this instruction uses DREX rather than REX, with the
45 * OC0 field set to 1, and the dest field taken from
47 * \171 - placement of DREX suffix in the absence of an EA
48 * \172\ab - the register number from operand a in bits 7..4, with
49 * the 4-bit immediate from operand b in bits 3..0.
50 * \173\xab - the register number from operand a in bits 7..4, with
51 * the value b in bits 3..0.
52 * \174\a - the register number from operand a in bits 7..4, and
53 * an arbitrary value in bits 3..0 (assembled as zero.)
54 * \2ab - a ModRM, calculated on EA in operand a, with the spare
55 * field equal to digit b.
56 * \250..\253 - same as \150..\153, except warn if the 64-bit operand
57 * is not equal to the truncated and sign-extended 32-bit
58 * operand; used for 32-bit immediates in 64-bit mode.
59 * \260..\263 - this instruction uses VEX rather than REX, with the
60 * V field taken from operand 0..3.
61 * \270 - this instruction uses VEX rather than REX, with the
62 * V field set to 1111b.
64 * VEX prefixes are followed by the sequence:
65 * \mm\wlp where mm is the M field; and wlp is:
67 * [w0] ww = 0 for W = 0
68 * [w1] ww = 1 for W = 1
69 * [wx] ww = 2 for W don't care (always assembled as 0)
70 * [ww] ww = 3 for W used as REX.W
73 * \310 - indicates fixed 16-bit address size, i.e. optional 0x67.
74 * \311 - indicates fixed 32-bit address size, i.e. optional 0x67.
75 * \312 - (disassembler only) marker on LOOP, LOOPxx instructions.
76 * \313 - indicates fixed 64-bit address size, 0x67 invalid.
77 * \314 - (disassembler only) invalid with REX.B
78 * \315 - (disassembler only) invalid with REX.X
79 * \316 - (disassembler only) invalid with REX.R
80 * \317 - (disassembler only) invalid with REX.W
81 * \320 - indicates fixed 16-bit operand size, i.e. optional 0x66.
82 * \321 - indicates fixed 32-bit operand size, i.e. optional 0x66.
83 * \322 - indicates that this instruction is only valid when the
84 * operand size is the default (instruction to disassembler,
85 * generates no code in the assembler)
86 * \323 - indicates fixed 64-bit operand size, REX on extensions only.
87 * \324 - indicates 64-bit operand size requiring REX prefix.
88 * \330 - a literal byte follows in the code stream, to be added
89 * to the condition code value of the instruction.
90 * \331 - instruction not valid with REP prefix. Hint for
91 * disassembler only; for SSE instructions.
92 * \332 - REP prefix (0xF2 byte) used as opcode extension.
93 * \333 - REP prefix (0xF3 byte) used as opcode extension.
94 * \334 - LOCK prefix used instead of REX.R
95 * \335 - disassemble a rep (0xF3 byte) prefix as repe not rep.
96 * \340 - reserve <operand 0> bytes of uninitialized storage.
97 * Operand 0 had better be a segmentless constant.
98 * \360 - no SSE prefix (== \364\331)
99 * \361 - 66 SSE prefix (== \366\331)
100 * \362 - F2 SSE prefix (== \364\332)
101 * \363 - F3 SSE prefix (== \364\333)
102 * \364 - operand-size prefix (0x66) not permitted
103 * \365 - address-size prefix (0x67) not permitted
104 * \366 - operand-size prefix (0x66) used as opcode extension
105 * \367 - address-size prefix (0x67) used as opcode extension
106 * \370,\371,\372 - match only if operand 0 meets byte jump criteria.
107 * 370 is used for Jcc, 371 is used for JMP.
108 * \373 - assemble 0x03 if bits==16, 0x05 if bits==32;
109 * used for conditional jump over longer jump
112 #include "compiler.h"
116 #include <inttypes.h>
120 #include "assemble.h"
124 /* Initialized to zero by the C standard */
125 static const uint8_t const_zero_buf
[256];
128 int sib_present
; /* is a SIB byte necessary? */
129 int bytes
; /* # of bytes of offset needed */
130 int size
; /* lazy - this is sib+bytes+1 */
131 uint8_t modrm
, sib
, rex
, rip
; /* the bytes themselves */
134 static uint32_t cpu
; /* cpu level received from nasm.c */
135 static efunc errfunc
;
136 static struct ofmt
*outfmt
;
137 static ListGen
*list
;
139 static int64_t calcsize(int32_t, int64_t, int, insn
*, const uint8_t *);
140 static void gencode(int32_t, int64_t, int, insn
*, const uint8_t *, int64_t);
141 static int matches(const struct itemplate
*, insn
*, int bits
);
142 static int32_t regflag(const operand
*);
143 static int32_t regval(const operand
*);
144 static int rexflags(int, int32_t, int);
145 static int op_rexflags(const operand
*, int);
146 static ea
*process_ea(operand
*, ea
*, int, int, int, int32_t, int);
147 static void add_asp(insn
*, int);
149 static int has_prefix(insn
* ins
, enum prefix_pos pos
, enum prefixes prefix
)
151 return ins
->prefixes
[pos
] == prefix
;
154 static void assert_no_prefix(insn
* ins
, enum prefix_pos pos
)
156 if (ins
->prefixes
[pos
])
157 errfunc(ERR_NONFATAL
, "invalid %s prefix",
158 prefix_name(ins
->prefixes
[pos
]));
161 static const char *size_name(int size
)
183 static void warn_overflow(int size
, int64_t data
)
186 int64_t lim
= ((int64_t)1 << (size
*8))-1;
188 if (data
< ~lim
|| data
> lim
)
189 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
190 "%s data exceeds bounds", size_name(size
));
194 * This routine wrappers the real output format's output routine,
195 * in order to pass a copy of the data off to the listing file
196 * generator at the same time.
198 static void out(int64_t offset
, int32_t segto
, const void *data
,
199 enum out_type type
, uint64_t size
,
200 int32_t segment
, int32_t wrt
)
202 static int32_t lineno
= 0; /* static!!! */
203 static char *lnfname
= NULL
;
206 if (type
== OUT_ADDRESS
&& segment
== NO_SEG
&& wrt
== NO_SEG
) {
208 * This is a non-relocated address, and we're going to
209 * convert it into RAWDATA format.
214 errfunc(ERR_PANIC
, "OUT_ADDRESS with size > 8");
218 WRITEADDR(q
, *(int64_t *)data
, size
);
223 list
->output(offset
, data
, type
, size
);
226 * this call to src_get determines when we call the
227 * debug-format-specific "linenum" function
228 * it updates lineno and lnfname to the current values
229 * returning 0 if "same as last time", -2 if lnfname
230 * changed, and the amount by which lineno changed,
231 * if it did. thus, these variables must be static
234 if (src_get(&lineno
, &lnfname
)) {
235 outfmt
->current_dfmt
->linenum(lnfname
, lineno
, segto
);
238 outfmt
->output(segto
, data
, type
, size
, segment
, wrt
);
241 static int jmp_match(int32_t segment
, int64_t offset
, int bits
,
242 insn
* ins
, const uint8_t *code
)
247 if (c
!= 0370 && c
!= 0371)
249 if (ins
->oprs
[0].opflags
& OPFLAG_FORWARD
) {
250 if ((optimizing
< 0 || (ins
->oprs
[0].type
& STRICT
))
254 return (pass0
== 0); /* match a forward reference */
256 isize
= calcsize(segment
, offset
, bits
, ins
, code
);
257 if (ins
->oprs
[0].segment
!= segment
)
259 isize
= ins
->oprs
[0].offset
- offset
- isize
; /* isize is now the delta */
260 if (isize
>= -128L && isize
<= 127L)
261 return 1; /* it is byte size */
266 int64_t assemble(int32_t segment
, int64_t offset
, int bits
, uint32_t cp
,
267 insn
* instruction
, struct ofmt
*output
, efunc error
,
270 const struct itemplate
*temp
;
275 int64_t start
= offset
;
276 int64_t wsize
= 0; /* size for DB etc. */
278 errfunc
= error
; /* to pass to other functions */
280 outfmt
= output
; /* likewise */
281 list
= listgen
; /* and again */
283 switch (instruction
->opcode
) {
313 int32_t t
= instruction
->times
;
316 "instruction->times < 0 (%ld) in assemble()", t
);
318 while (t
--) { /* repeat TIMES times */
319 for (e
= instruction
->eops
; e
; e
= e
->next
) {
320 if (e
->type
== EOT_DB_NUMBER
) {
322 if (e
->segment
!= NO_SEG
)
323 errfunc(ERR_NONFATAL
,
324 "one-byte relocation attempted");
326 uint8_t out_byte
= e
->offset
;
327 out(offset
, segment
, &out_byte
,
328 OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
330 } else if (wsize
> 8) {
331 errfunc(ERR_NONFATAL
,
332 "integer supplied to a DT, DO or DY"
335 out(offset
, segment
, &e
->offset
,
336 OUT_ADDRESS
, wsize
, e
->segment
, e
->wrt
);
338 } else if (e
->type
== EOT_DB_STRING
) {
341 out(offset
, segment
, e
->stringval
,
342 OUT_RAWDATA
, e
->stringlen
, NO_SEG
, NO_SEG
);
343 align
= e
->stringlen
% wsize
;
346 align
= wsize
- align
;
347 out(offset
, segment
, const_zero_buf
,
348 OUT_RAWDATA
, align
, NO_SEG
, NO_SEG
);
350 offset
+= e
->stringlen
+ align
;
353 if (t
> 0 && t
== instruction
->times
- 1) {
355 * Dummy call to list->output to give the offset to the
358 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
359 list
->uplevel(LIST_TIMES
);
362 if (instruction
->times
> 1)
363 list
->downlevel(LIST_TIMES
);
364 return offset
- start
;
367 if (instruction
->opcode
== I_INCBIN
) {
368 static char fname
[FILENAME_MAX
];
372 len
= FILENAME_MAX
- 1;
373 if (len
> instruction
->eops
->stringlen
)
374 len
= instruction
->eops
->stringlen
;
375 strncpy(fname
, instruction
->eops
->stringval
, len
);
378 fp
= fopen(fname
, "rb");
380 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
382 } else if (fseek(fp
, 0L, SEEK_END
) < 0) {
383 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
386 static char buf
[2048];
387 int32_t t
= instruction
->times
;
391 if (instruction
->eops
->next
) {
392 base
= instruction
->eops
->next
->offset
;
394 if (instruction
->eops
->next
->next
&&
395 len
> instruction
->eops
->next
->next
->offset
)
396 len
= instruction
->eops
->next
->next
->offset
;
399 * Dummy call to list->output to give the offset to the
402 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
403 list
->uplevel(LIST_INCBIN
);
407 fseek(fp
, base
, SEEK_SET
);
411 fread(buf
, 1, (l
> (int32_t) sizeof(buf
) ? (int32_t) sizeof(buf
) : l
),
415 * This shouldn't happen unless the file
416 * actually changes while we are reading
420 "`incbin': unexpected EOF while"
421 " reading file `%s'", fname
);
422 t
= 0; /* Try to exit cleanly */
425 out(offset
, segment
, buf
, OUT_RAWDATA
, m
,
430 list
->downlevel(LIST_INCBIN
);
431 if (instruction
->times
> 1) {
433 * Dummy call to list->output to give the offset to the
436 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
437 list
->uplevel(LIST_TIMES
);
438 list
->downlevel(LIST_TIMES
);
441 return instruction
->times
* len
;
443 return 0; /* if we're here, there's an error */
446 /* Check to see if we need an address-size prefix */
447 add_asp(instruction
, bits
);
451 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++){
452 int m
= matches(temp
, instruction
, bits
);
455 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
457 if (m
== 100) { /* matches! */
458 const uint8_t *codes
= temp
->code
;
459 int64_t insn_size
= calcsize(segment
, offset
, bits
,
461 itimes
= instruction
->times
;
462 if (insn_size
< 0) /* shouldn't be, on pass two */
463 error(ERR_PANIC
, "errors made it through from pass one");
466 for (j
= 0; j
< MAXPREFIX
; j
++) {
468 switch (instruction
->prefixes
[j
]) {
484 "cs segment base generated, but will be ignored in 64-bit mode");
491 "ds segment base generated, but will be ignored in 64-bit mode");
498 "es segment base generated, but will be ignored in 64-bit mode");
511 "ss segment base generated, but will be ignored in 64-bit mode");
518 "segr6 and segr7 cannot be used as prefixes");
523 "16-bit addressing is not supported "
525 } else if (bits
!= 16)
535 "64-bit addressing is only supported "
559 error(ERR_PANIC
, "invalid instruction prefix");
562 out(offset
, segment
, &c
, OUT_RAWDATA
, 1,
567 insn_end
= offset
+ insn_size
;
568 gencode(segment
, offset
, bits
, instruction
, codes
,
571 if (itimes
> 0 && itimes
== instruction
->times
- 1) {
573 * Dummy call to list->output to give the offset to the
576 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
577 list
->uplevel(LIST_TIMES
);
580 if (instruction
->times
> 1)
581 list
->downlevel(LIST_TIMES
);
582 return offset
- start
;
583 } else if (m
> 0 && m
> size_prob
) {
589 if (temp
->opcode
== -1) { /* didn't match any instruction */
592 error(ERR_NONFATAL
, "operation size not specified");
595 error(ERR_NONFATAL
, "mismatch in operand sizes");
598 error(ERR_NONFATAL
, "no instruction for this cpu level");
601 error(ERR_NONFATAL
, "instruction not supported in 64-bit mode");
605 "invalid combination of opcode and operands");
612 int64_t insn_size(int32_t segment
, int64_t offset
, int bits
, uint32_t cp
,
613 insn
* instruction
, efunc error
)
615 const struct itemplate
*temp
;
617 errfunc
= error
; /* to pass to other functions */
620 if (instruction
->opcode
== -1)
623 if (instruction
->opcode
== I_DB
|| instruction
->opcode
== I_DW
||
624 instruction
->opcode
== I_DD
|| instruction
->opcode
== I_DQ
||
625 instruction
->opcode
== I_DT
|| instruction
->opcode
== I_DO
||
626 instruction
->opcode
== I_DY
) {
628 int32_t isize
, osize
, wsize
= 0; /* placate gcc */
631 switch (instruction
->opcode
) {
657 for (e
= instruction
->eops
; e
; e
= e
->next
) {
661 if (e
->type
== EOT_DB_NUMBER
)
663 else if (e
->type
== EOT_DB_STRING
)
664 osize
= e
->stringlen
;
666 align
= (-osize
) % wsize
;
669 isize
+= osize
+ align
;
671 return isize
* instruction
->times
;
674 if (instruction
->opcode
== I_INCBIN
) {
675 char fname
[FILENAME_MAX
];
679 len
= FILENAME_MAX
- 1;
680 if (len
> instruction
->eops
->stringlen
)
681 len
= instruction
->eops
->stringlen
;
682 strncpy(fname
, instruction
->eops
->stringval
, len
);
685 fp
= fopen(fname
, "rb");
687 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
689 else if (fseek(fp
, 0L, SEEK_END
) < 0)
690 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
695 if (instruction
->eops
->next
) {
696 len
-= instruction
->eops
->next
->offset
;
697 if (instruction
->eops
->next
->next
&&
698 len
> instruction
->eops
->next
->next
->offset
) {
699 len
= instruction
->eops
->next
->next
->offset
;
702 return instruction
->times
* len
;
704 return 0; /* if we're here, there's an error */
707 /* Check to see if we need an address-size prefix */
708 add_asp(instruction
, bits
);
710 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++) {
711 int m
= matches(temp
, instruction
, bits
);
713 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
716 /* we've matched an instruction. */
718 const uint8_t *codes
= temp
->code
;
721 isize
= calcsize(segment
, offset
, bits
, instruction
, codes
);
724 for (j
= 0; j
< MAXPREFIX
; j
++) {
725 switch (instruction
->prefixes
[j
]) {
751 return isize
* instruction
->times
;
754 return -1; /* didn't match any instruction */
757 static bool possible_sbyte(insn
* ins
, int op
)
759 return !(ins
->forw_ref
&& ins
->oprs
[op
].opflags
) &&
761 !(ins
->oprs
[op
].type
& STRICT
) &&
762 ins
->oprs
[op
].wrt
== NO_SEG
&& ins
->oprs
[op
].segment
== NO_SEG
;
765 /* check that opn[op] is a signed byte of size 16 or 32 */
766 static bool is_sbyte16(insn
* ins
, int op
)
770 if (!possible_sbyte(ins
, op
))
773 v
= ins
->oprs
[op
].offset
;
774 return v
>= -128 && v
<= 127;
777 static bool is_sbyte32(insn
* ins
, int op
)
781 if (!possible_sbyte(ins
, op
))
784 v
= ins
->oprs
[op
].offset
;
785 return v
>= -128 && v
<= 127;
788 /* check that opn[op] is a signed byte of size 32; warn if this is not
789 the original value when extended to 64 bits */
790 static bool is_sbyte64(insn
* ins
, int op
)
795 /* dead in the water on forward reference or External */
796 if (!possible_sbyte(ins
, op
))
799 v64
= ins
->oprs
[op
].offset
;
802 warn_overflow(32, v64
);
804 return v32
>= -128 && v32
<= 127;
806 static int64_t calcsize(int32_t segment
, int64_t offset
, int bits
,
807 insn
* ins
, const uint8_t *codes
)
814 ins
->rex
= 0; /* Ensure REX is reset */
816 if (ins
->prefixes
[PPS_OSIZE
] == P_O64
)
819 (void)segment
; /* Don't warn that this parameter is unused */
820 (void)offset
; /* Don't warn that this parameter is unused */
824 opx
= &ins
->oprs
[c
& 3];
829 codes
+= c
, length
+= c
;
842 op_rexflags(opx
, REX_B
|REX_H
|REX_P
|REX_W
);
873 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
874 length
+= (opx
->type
& BITS16
) ? 2 : 4;
876 length
+= (bits
== 16) ? 2 : 4;
888 length
+= ins
->addr_size
>> 3;
900 length
+= 8; /* MOV reg64/imm */
912 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
913 length
+= (opx
->type
& BITS16
) ? 2 : 4;
915 length
+= (bits
== 16) ? 2 : 4;
933 length
+= is_sbyte16(ins
, c
& 3) ? 1 : 2;
946 length
+= is_sbyte32(ins
, c
& 3) ? 1 : 4;
961 ins
->drexdst
= regval(opx
);
968 ins
->rex
|= REX_D
|REX_OC
;
969 ins
->drexdst
= regval(opx
);
983 length
+= is_sbyte64(ins
, c
& 3) ? 1 : 4;
991 ins
->drexdst
= regval(opx
);
992 ins
->vex_m
= *codes
++;
993 ins
->vex_wlp
= *codes
++;
999 ins
->vex_m
= *codes
++;
1000 ins
->vex_wlp
= *codes
++;
1010 length
+= (bits
!= 16) && !has_prefix(ins
, PPS_ASIZE
, P_A16
);
1013 length
+= (bits
!= 32) && !has_prefix(ins
, PPS_ASIZE
, P_A32
);
1018 if (bits
!= 64 || has_prefix(ins
, PPS_ASIZE
, P_A16
) ||
1019 has_prefix(ins
, PPS_ASIZE
, P_A32
))
1028 length
+= (bits
!= 16);
1031 length
+= (bits
== 16);
1056 if (ins
->oprs
[0].segment
!= NO_SEG
)
1057 errfunc(ERR_NONFATAL
, "attempt to reserve non-constant"
1058 " quantity of BSS space");
1060 length
+= ins
->oprs
[0].offset
;
1083 default: /* can't do it by 'case' statements */
1084 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1088 ea_data
.rex
= 0; /* Ensure ea.REX is initially 0 */
1091 /* pick rfield from operand b */
1092 rflags
= regflag(&ins
->oprs
[c
& 7]);
1093 rfield
= nasm_regvals
[ins
->oprs
[c
& 7].basereg
];
1100 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1101 ins
->addr_size
, rfield
, rflags
, ins
->forw_ref
)) {
1102 errfunc(ERR_NONFATAL
, "invalid effective address");
1105 ins
->rex
|= ea_data
.rex
;
1106 length
+= ea_data
.size
;
1109 errfunc(ERR_PANIC
, "internal instruction table corrupt"
1110 ": instruction code 0x%02X given", c
);
1115 ins
->rex
&= rex_mask
;
1117 if (ins
->rex
& REX_V
) {
1118 int bad32
= REX_R
|REX_W
|REX_X
|REX_B
;
1120 if (ins
->rex
& REX_H
) {
1121 errfunc(ERR_NONFATAL
, "cannot use high register in vex instruction");
1124 switch (ins
->vex_wlp
& 030) {
1138 if (bits
!= 64 && ((ins
->rex
& bad32
) || ins
->drexdst
> 7)) {
1139 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1142 if (ins
->vex_m
!= 1 || (ins
->rex
& (REX_W
|REX_R
|REX_B
)))
1146 } else if (ins
->rex
& REX_D
) {
1147 if (ins
->rex
& REX_H
) {
1148 errfunc(ERR_NONFATAL
, "cannot use high register in drex instruction");
1151 if (bits
!= 64 && ((ins
->rex
& (REX_R
|REX_W
|REX_X
|REX_B
)) ||
1152 ins
->drexdst
> 7)) {
1153 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1157 } else if (ins
->rex
& REX_REAL
) {
1158 if (ins
->rex
& REX_H
) {
1159 errfunc(ERR_NONFATAL
, "cannot use high register in rex instruction");
1161 } else if (bits
== 64) {
1163 } else if ((ins
->rex
& REX_L
) &&
1164 !(ins
->rex
& (REX_P
|REX_W
|REX_X
|REX_B
)) &&
1167 assert_no_prefix(ins
, PPS_LREP
);
1170 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1178 #define EMIT_REX() \
1179 if (!(ins->rex & (REX_D|REX_V)) && (ins->rex & REX_REAL) && (bits == 64)) { \
1180 ins->rex = (ins->rex & REX_REAL)|REX_P; \
1181 out(offset, segment, &ins->rex, OUT_RAWDATA, 1, NO_SEG, NO_SEG); \
1186 static void gencode(int32_t segment
, int64_t offset
, int bits
,
1187 insn
* ins
, const uint8_t *codes
, int64_t insn_end
)
1189 static char condval
[] = { /* conditional opcodes */
1190 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
1191 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
1192 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
1198 struct operand
*opx
;
1202 opx
= &ins
->oprs
[c
& 3];
1208 out(offset
, segment
, codes
, OUT_RAWDATA
, c
, NO_SEG
, NO_SEG
);
1215 switch (ins
->oprs
[0].basereg
) {
1217 bytes
[0] = 0x0E + (c
== 0x04 ? 1 : 0);
1220 bytes
[0] = 0x1E + (c
== 0x04 ? 1 : 0);
1223 bytes
[0] = 0x06 + (c
== 0x04 ? 1 : 0);
1226 bytes
[0] = 0x16 + (c
== 0x04 ? 1 : 0);
1230 "bizarre 8086 segment register received");
1232 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1238 switch (ins
->oprs
[0].basereg
) {
1240 bytes
[0] = 0xA0 + (c
== 0x05 ? 1 : 0);
1243 bytes
[0] = 0xA8 + (c
== 0x05 ? 1 : 0);
1247 "bizarre 386 segment register received");
1249 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1258 bytes
[0] = *codes
++ + ((regval(opx
)) & 7);
1259 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1267 /* XXX: warns for legitimate optimizer actions */
1268 if (opx
->offset
< -128 || opx
->offset
> 127) {
1269 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1270 "signed byte value exceeds bounds");
1273 if (opx
->segment
!= NO_SEG
) {
1275 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1276 opx
->segment
, opx
->wrt
);
1278 bytes
[0] = opx
->offset
;
1279 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1289 if (opx
->offset
< -256 || opx
->offset
> 255) {
1290 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1291 "byte value exceeds bounds");
1293 if (opx
->segment
!= NO_SEG
) {
1295 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1296 opx
->segment
, opx
->wrt
);
1298 bytes
[0] = opx
->offset
;
1299 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1309 if (opx
->offset
< 0 || opx
->offset
> 255)
1310 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1311 "unsigned byte value exceeds bounds");
1312 if (opx
->segment
!= NO_SEG
) {
1314 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1315 opx
->segment
, opx
->wrt
);
1317 bytes
[0] = opx
->offset
;
1318 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1329 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1330 warn_overflow(2, data
);
1331 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1332 opx
->segment
, opx
->wrt
);
1340 if (opx
->type
& (BITS16
| BITS32
))
1341 size
= (opx
->type
& BITS16
) ? 2 : 4;
1343 size
= (bits
== 16) ? 2 : 4;
1345 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1346 warn_overflow(size
, data
);
1347 out(offset
, segment
, &data
, OUT_ADDRESS
, size
,
1348 opx
->segment
, opx
->wrt
);
1357 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1358 warn_overflow(4, data
);
1359 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1360 opx
->segment
, opx
->wrt
);
1369 size
= ins
->addr_size
>> 3;
1370 if (opx
->segment
== NO_SEG
&&
1372 warn_overflow(size
, data
);
1373 out(offset
, segment
, &data
, OUT_ADDRESS
, size
,
1374 opx
->segment
, opx
->wrt
);
1382 if (opx
->segment
!= segment
)
1383 errfunc(ERR_NONFATAL
,
1384 "short relative jump outside segment");
1385 data
= opx
->offset
- insn_end
;
1386 if (data
> 127 || data
< -128)
1387 errfunc(ERR_NONFATAL
, "short jump is out of range");
1389 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1397 data
= (int64_t)opx
->offset
;
1398 out(offset
, segment
, &data
, OUT_ADDRESS
, 8,
1399 opx
->segment
, opx
->wrt
);
1407 if (opx
->segment
!= segment
) {
1409 out(offset
, segment
, &data
,
1410 OUT_REL2ADR
, insn_end
- offset
,
1411 opx
->segment
, opx
->wrt
);
1413 data
= opx
->offset
- insn_end
;
1414 out(offset
, segment
, &data
,
1415 OUT_ADDRESS
, 2, NO_SEG
, NO_SEG
);
1424 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
1425 size
= (opx
->type
& BITS16
) ? 2 : 4;
1427 size
= (bits
== 16) ? 2 : 4;
1428 if (opx
->segment
!= segment
) {
1430 out(offset
, segment
, &data
,
1431 size
== 2 ? OUT_REL2ADR
: OUT_REL4ADR
,
1432 insn_end
- offset
, opx
->segment
, opx
->wrt
);
1434 data
= opx
->offset
- insn_end
;
1435 out(offset
, segment
, &data
,
1436 OUT_ADDRESS
, size
, NO_SEG
, NO_SEG
);
1445 if (opx
->segment
!= segment
) {
1447 out(offset
, segment
, &data
,
1448 OUT_REL4ADR
, insn_end
- offset
,
1449 opx
->segment
, opx
->wrt
);
1451 data
= opx
->offset
- insn_end
;
1452 out(offset
, segment
, &data
,
1453 OUT_ADDRESS
, 4, NO_SEG
, NO_SEG
);
1462 if (opx
->segment
== NO_SEG
)
1463 errfunc(ERR_NONFATAL
, "value referenced by FAR is not"
1466 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1467 outfmt
->segbase(1 + opx
->segment
),
1477 if (is_sbyte16(ins
, c
& 3)) {
1479 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1483 if (opx
->segment
== NO_SEG
&&
1485 warn_overflow(2, data
);
1486 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1487 opx
->segment
, opx
->wrt
);
1497 bytes
[0] = *codes
++;
1498 if (is_sbyte16(ins
, c
& 3))
1499 bytes
[0] |= 2; /* s-bit */
1500 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1509 if (is_sbyte32(ins
, c
& 3)) {
1511 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1515 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1516 opx
->segment
, opx
->wrt
);
1526 bytes
[0] = *codes
++;
1527 if (is_sbyte32(ins
, c
& 3))
1528 bytes
[0] |= 2; /* s-bit */
1529 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1545 (ins
->drexdst
<< 4) |
1546 (ins
->rex
& REX_OC
? 0x08 : 0) |
1547 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1549 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1555 opx
= &ins
->oprs
[c
>> 3];
1556 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1557 opx
= &ins
->oprs
[c
& 7];
1558 if (opx
->segment
!= NO_SEG
|| opx
->wrt
!= NO_SEG
) {
1559 errfunc(ERR_NONFATAL
,
1560 "non-absolute expression not permitted as argument %d",
1563 if (opx
->offset
& ~15) {
1564 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1565 "four-bit argument exceeds bounds");
1567 bytes
[0] |= opx
->offset
& 15;
1569 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1575 opx
= &ins
->oprs
[c
>> 4];
1576 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1578 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1584 opx
= &ins
->oprs
[c
];
1585 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1586 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1595 /* is_sbyte32() is right here, we have already warned */
1596 if (is_sbyte32(ins
, c
& 3)) {
1598 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1602 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1603 opx
->segment
, opx
->wrt
);
1614 if (ins
->vex_m
!= 1 || (ins
->rex
& (REX_W
|REX_X
|REX_B
))) {
1616 bytes
[1] = ins
->vex_m
| ((~ins
->rex
& 7) << 5);
1617 bytes
[2] = ((ins
->rex
& REX_W
) << (7-3)) |
1618 ((~ins
->drexdst
& 15)<< 3) | (ins
->vex_wlp
& 07);
1619 out(offset
, segment
, &bytes
, OUT_RAWDATA
, 3, NO_SEG
, NO_SEG
);
1623 bytes
[1] = ((~ins
->rex
& REX_R
) << (7-2)) |
1624 ((~ins
->drexdst
& 15) << 3) | (ins
->vex_wlp
& 07);
1625 out(offset
, segment
, &bytes
, OUT_RAWDATA
, 2, NO_SEG
, NO_SEG
);
1637 if (bits
== 32 && !has_prefix(ins
, PPS_ASIZE
, P_A16
)) {
1639 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1646 if (bits
!= 32 && !has_prefix(ins
, PPS_ASIZE
, P_A32
)) {
1648 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1670 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1679 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1694 *bytes
= *codes
++ ^ condval
[ins
->condition
];
1695 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1704 *bytes
= c
- 0332 + 0xF2;
1705 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1710 if (ins
->rex
& REX_R
) {
1712 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1715 ins
->rex
&= ~(REX_L
|REX_R
);
1722 if (ins
->oprs
[0].segment
!= NO_SEG
)
1723 errfunc(ERR_PANIC
, "non-constant BSS size in pass two");
1725 int64_t size
= ins
->oprs
[0].offset
;
1727 out(offset
, segment
, NULL
,
1728 OUT_RESERVE
, size
, NO_SEG
, NO_SEG
);
1738 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1744 bytes
[0] = c
- 0362 + 0xf2;
1745 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1755 *bytes
= c
- 0366 + 0x66;
1756 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1766 *bytes
= bits
== 16 ? 3 : 5;
1767 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1771 default: /* can't do it by 'case' statements */
1772 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1780 /* pick rfield from operand b */
1781 rflags
= regflag(&ins
->oprs
[c
& 7]);
1782 rfield
= nasm_regvals
[ins
->oprs
[c
& 7].basereg
];
1784 /* rfield is constant */
1790 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1791 ins
->addr_size
, rfield
, rflags
, ins
->forw_ref
)) {
1792 errfunc(ERR_NONFATAL
, "invalid effective address");
1797 *p
++ = ea_data
.modrm
;
1798 if (ea_data
.sib_present
)
1801 /* DREX suffixes come between the SIB and the displacement */
1802 if (ins
->rex
& REX_D
) {
1804 (ins
->drexdst
<< 4) |
1805 (ins
->rex
& REX_OC
? 0x08 : 0) |
1806 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1811 out(offset
, segment
, bytes
, OUT_RAWDATA
, s
, NO_SEG
, NO_SEG
);
1813 switch (ea_data
.bytes
) {
1817 if (ins
->oprs
[(c
>> 3) & 7].segment
!= NO_SEG
) {
1818 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1819 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1820 ins
->oprs
[(c
>> 3) & 7].segment
,
1821 ins
->oprs
[(c
>> 3) & 7].wrt
);
1823 *bytes
= ins
->oprs
[(c
>> 3) & 7].offset
;
1824 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1,
1832 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1833 warn_overflow(ea_data
.bytes
, data
);
1834 out(offset
, segment
, &data
,
1835 ea_data
.rip
? OUT_REL4ADR
: OUT_ADDRESS
,
1837 ins
->oprs
[(c
>> 3) & 7].segment
,
1838 ins
->oprs
[(c
>> 3) & 7].wrt
);
1844 errfunc(ERR_PANIC
, "internal instruction table corrupt"
1845 ": instruction code 0x%02X given", c
);
1851 static int32_t regflag(const operand
* o
)
1853 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1854 errfunc(ERR_PANIC
, "invalid operand passed to regflag()");
1856 return nasm_reg_flags
[o
->basereg
];
1859 static int32_t regval(const operand
* o
)
1861 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1862 errfunc(ERR_PANIC
, "invalid operand passed to regval()");
1864 return nasm_regvals
[o
->basereg
];
1867 static int op_rexflags(const operand
* o
, int mask
)
1872 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1873 errfunc(ERR_PANIC
, "invalid operand passed to op_rexflags()");
1876 flags
= nasm_reg_flags
[o
->basereg
];
1877 val
= nasm_regvals
[o
->basereg
];
1879 return rexflags(val
, flags
, mask
);
1882 static int rexflags(int val
, int32_t flags
, int mask
)
1887 rex
|= REX_B
|REX_X
|REX_R
;
1890 if (!(REG_HIGH
& ~flags
)) /* AH, CH, DH, BH */
1892 else if (!(REG8
& ~flags
) && val
>= 4) /* SPL, BPL, SIL, DIL */
1898 static int matches(const struct itemplate
*itemp
, insn
* instruction
, int bits
)
1900 int i
, size
[MAX_OPERANDS
], asize
, oprs
, ret
;
1907 if (itemp
->opcode
!= instruction
->opcode
)
1911 * Count the operands
1913 if (itemp
->operands
!= instruction
->operands
)
1917 * Check that no spurious colons or TOs are present
1919 for (i
= 0; i
< itemp
->operands
; i
++)
1920 if (instruction
->oprs
[i
].type
& ~itemp
->opd
[i
] & (COLON
| TO
))
1924 * Process size flags
1926 if (itemp
->flags
& IF_ARMASK
) {
1927 memset(size
, 0, sizeof size
);
1929 i
= ((itemp
->flags
& IF_ARMASK
) >> IF_ARSHFT
) - 1;
1931 switch (itemp
->flags
& IF_SMASK
) {
1968 switch (itemp
->flags
& IF_SMASK
) {
2003 for (i
= 0; i
< MAX_OPERANDS
; i
++)
2008 * Check that the operand flags all match up
2010 for (i
= 0; i
< itemp
->operands
; i
++) {
2011 int32_t type
= instruction
->oprs
[i
].type
;
2012 if (!(type
& SIZE_MASK
))
2015 if (itemp
->opd
[i
] & SAME_AS
) {
2016 int j
= itemp
->opd
[i
] & ~SAME_AS
;
2017 if (type
!= instruction
->oprs
[j
].type
||
2018 instruction
->oprs
[i
].basereg
!= instruction
->oprs
[j
].basereg
)
2020 } else if (itemp
->opd
[i
] & ~type
||
2021 ((itemp
->opd
[i
] & SIZE_MASK
) &&
2022 ((itemp
->opd
[i
] ^ type
) & SIZE_MASK
))) {
2023 if ((itemp
->opd
[i
] & ~type
& ~SIZE_MASK
) ||
2032 * Check operand sizes
2034 if (itemp
->flags
& (IF_SM
| IF_SM2
)) {
2035 oprs
= (itemp
->flags
& IF_SM2
? 2 : itemp
->operands
);
2037 for (i
= 0; i
< oprs
; i
++) {
2038 if ((asize
= itemp
->opd
[i
] & SIZE_MASK
) != 0) {
2040 for (j
= 0; j
< oprs
; j
++)
2046 oprs
= itemp
->operands
;
2049 for (i
= 0; i
< itemp
->operands
; i
++) {
2050 if (!(itemp
->opd
[i
] & SIZE_MASK
) &&
2051 (instruction
->oprs
[i
].type
& SIZE_MASK
& ~size
[i
]))
2056 * Check template is okay at the set cpu level
2058 if (((itemp
->flags
& IF_PLEVEL
) > cpu
))
2062 * Check if instruction is available in long mode
2064 if ((itemp
->flags
& IF_NOLONG
) && (bits
== 64))
2068 * Check if special handling needed for Jumps
2070 if ((uint8_t)(itemp
->code
[0]) >= 0370)
2076 static ea
*process_ea(operand
* input
, ea
* output
, int bits
,
2077 int addrbits
, int rfield
, int32_t rflags
, int forw_ref
)
2079 output
->rip
= false;
2081 /* REX flags for the rfield operand */
2082 output
->rex
|= rexflags(rfield
, rflags
, REX_R
|REX_P
|REX_W
|REX_H
);
2084 if (!(REGISTER
& ~input
->type
)) { /* register direct */
2088 if (input
->basereg
< EXPR_REG_START
/* Verify as Register */
2089 || input
->basereg
>= REG_ENUM_LIMIT
)
2092 i
= nasm_regvals
[input
->basereg
];
2095 return NULL
; /* Invalid EA register */
2097 output
->rex
|= op_rexflags(input
, REX_B
|REX_P
|REX_W
|REX_H
);
2099 output
->sib_present
= false; /* no SIB necessary */
2100 output
->bytes
= 0; /* no offset necessary either */
2101 output
->modrm
= 0xC0 | ((rfield
& 7) << 3) | (i
& 7);
2102 } else { /* it's a memory reference */
2103 if (input
->basereg
== -1
2104 && (input
->indexreg
== -1 || input
->scale
== 0)) {
2105 /* it's a pure offset */
2106 if (bits
== 64 && (~input
->type
& IP_REL
)) {
2107 int scale
, index
, base
;
2108 output
->sib_present
= true;
2112 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
2114 output
->modrm
= 4 | ((rfield
& 7) << 3);
2115 output
->rip
= false;
2117 output
->sib_present
= false;
2118 output
->bytes
= (addrbits
!= 16 ? 4 : 2);
2119 output
->modrm
= (addrbits
!= 16 ? 5 : 6) | ((rfield
& 7) << 3);
2120 output
->rip
= bits
== 64;
2122 } else { /* it's an indirection */
2123 int i
= input
->indexreg
, b
= input
->basereg
, s
= input
->scale
;
2124 int32_t o
= input
->offset
, seg
= input
->segment
;
2125 int hb
= input
->hintbase
, ht
= input
->hinttype
;
2128 int32_t ix
, bx
; /* register flags */
2131 i
= -1; /* make this easy, at least */
2133 if (i
>= EXPR_REG_START
&& i
< REG_ENUM_LIMIT
) {
2134 it
= nasm_regvals
[i
];
2135 ix
= nasm_reg_flags
[i
];
2141 if (b
>= EXPR_REG_START
&& b
< REG_ENUM_LIMIT
) {
2142 bt
= nasm_regvals
[b
];
2143 bx
= nasm_reg_flags
[b
];
2149 /* check for a 32/64-bit memory reference... */
2150 if ((ix
|bx
) & (BITS32
|BITS64
)) {
2151 /* it must be a 32/64-bit memory reference. Firstly we have
2152 * to check that all registers involved are type E/Rxx. */
2153 int32_t sok
= BITS32
|BITS64
;
2156 if (!(REG64
& ~ix
) || !(REG32
& ~ix
))
2164 return NULL
; /* Invalid register */
2165 if (~sok
& bx
& SIZE_MASK
)
2166 return NULL
; /* Invalid size */
2170 /* While we're here, ensure the user didn't specify
2172 if (input
->disp_size
== 16 || input
->disp_size
== 64)
2175 if (addrbits
== 16 ||
2176 (addrbits
== 32 && !(sok
& BITS32
)) ||
2177 (addrbits
== 64 && !(sok
& BITS64
)))
2180 /* now reorganize base/index */
2181 if (s
== 1 && bt
!= it
&& bt
!= -1 && it
!= -1 &&
2182 ((hb
== b
&& ht
== EAH_NOTBASE
)
2183 || (hb
== i
&& ht
== EAH_MAKEBASE
))) {
2184 /* swap if hints say so */
2185 t
= bt
, bt
= it
, it
= t
;
2186 t
= bx
, bx
= ix
, ix
= t
;
2188 if (bt
== it
) /* convert EAX+2*EAX to 3*EAX */
2189 bt
= -1, bx
= 0, s
++;
2190 if (bt
== -1 && s
== 1 && !(hb
== it
&& ht
== EAH_NOTBASE
)) {
2191 /* make single reg base, unless hint */
2192 bt
= it
, bx
= ix
, it
= -1, ix
= 0;
2194 if (((s
== 2 && it
!= REG_NUM_ESP
2195 && !(input
->eaflags
& EAF_TIMESTWO
)) || s
== 3
2196 || s
== 5 || s
== 9) && bt
== -1)
2197 bt
= it
, bx
= ix
, s
--; /* convert 3*EAX to EAX+2*EAX */
2198 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
2199 && (input
->eaflags
& EAF_TIMESTWO
))
2200 it
= bt
, ix
= bx
, bt
= -1, bx
= 0, s
= 1;
2201 /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */
2202 if (s
== 1 && it
== REG_NUM_ESP
) {
2203 /* swap ESP into base if scale is 1 */
2204 t
= it
, it
= bt
, bt
= t
;
2205 t
= ix
, ix
= bx
, bx
= t
;
2207 if (it
== REG_NUM_ESP
2208 || (s
!= 1 && s
!= 2 && s
!= 4 && s
!= 8 && it
!= -1))
2209 return NULL
; /* wrong, for various reasons */
2211 output
->rex
|= rexflags(it
, ix
, REX_X
);
2212 output
->rex
|= rexflags(bt
, bx
, REX_B
);
2214 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
) {
2223 if (rm
!= REG_NUM_EBP
&& o
== 0 &&
2224 seg
== NO_SEG
&& !forw_ref
&&
2226 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2228 else if (input
->eaflags
& EAF_BYTEOFFS
||
2229 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2231 && !(input
->eaflags
& EAF_WORDOFFS
)))
2237 output
->sib_present
= false;
2238 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
2239 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
2242 int mod
, scale
, index
, base
;
2262 default: /* then what the smeg is it? */
2263 return NULL
; /* panic */
2271 if (base
!= REG_NUM_EBP
&& o
== 0 &&
2272 seg
== NO_SEG
&& !forw_ref
&&
2274 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2276 else if (input
->eaflags
& EAF_BYTEOFFS
||
2277 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2279 && !(input
->eaflags
& EAF_WORDOFFS
)))
2285 output
->sib_present
= true;
2286 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
2287 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | 4;
2288 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
2290 } else { /* it's 16-bit */
2293 /* check for 64-bit long mode */
2297 /* check all registers are BX, BP, SI or DI */
2298 if ((b
!= -1 && b
!= R_BP
&& b
!= R_BX
&& b
!= R_SI
2299 && b
!= R_DI
) || (i
!= -1 && i
!= R_BP
&& i
!= R_BX
2300 && i
!= R_SI
&& i
!= R_DI
))
2303 /* ensure the user didn't specify DWORD/QWORD */
2304 if (input
->disp_size
== 32 || input
->disp_size
== 64)
2307 if (s
!= 1 && i
!= -1)
2308 return NULL
; /* no can do, in 16-bit EA */
2309 if (b
== -1 && i
!= -1) {
2314 if ((b
== R_SI
|| b
== R_DI
) && i
!= -1) {
2319 /* have BX/BP as base, SI/DI index */
2321 return NULL
; /* shouldn't ever happen, in theory */
2322 if (i
!= -1 && b
!= -1 &&
2323 (i
== R_BP
|| i
== R_BX
|| b
== R_SI
|| b
== R_DI
))
2324 return NULL
; /* invalid combinations */
2325 if (b
== -1) /* pure offset: handled above */
2326 return NULL
; /* so if it gets to here, panic! */
2330 switch (i
* 256 + b
) {
2331 case R_SI
* 256 + R_BX
:
2334 case R_DI
* 256 + R_BX
:
2337 case R_SI
* 256 + R_BP
:
2340 case R_DI
* 256 + R_BP
:
2358 if (rm
== -1) /* can't happen, in theory */
2359 return NULL
; /* so panic if it does */
2361 if (o
== 0 && seg
== NO_SEG
&& !forw_ref
&& rm
!= 6 &&
2362 !(input
->eaflags
& (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2364 else if (input
->eaflags
& EAF_BYTEOFFS
||
2365 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2367 && !(input
->eaflags
& EAF_WORDOFFS
)))
2372 output
->sib_present
= false; /* no SIB - it's 16-bit */
2373 output
->bytes
= mod
; /* bytes of offset needed */
2374 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
2379 output
->size
= 1 + output
->sib_present
+ output
->bytes
;
2383 static void add_asp(insn
*ins
, int addrbits
)
2388 valid
= (addrbits
== 64) ? 64|32 : 32|16;
2390 switch (ins
->prefixes
[PPS_ASIZE
]) {
2401 valid
&= (addrbits
== 32) ? 16 : 32;
2407 for (j
= 0; j
< ins
->operands
; j
++) {
2408 if (!(MEMORY
& ~ins
->oprs
[j
].type
)) {
2411 /* Verify as Register */
2412 if (ins
->oprs
[j
].indexreg
< EXPR_REG_START
2413 || ins
->oprs
[j
].indexreg
>= REG_ENUM_LIMIT
)
2416 i
= nasm_reg_flags
[ins
->oprs
[j
].indexreg
];
2418 /* Verify as Register */
2419 if (ins
->oprs
[j
].basereg
< EXPR_REG_START
2420 || ins
->oprs
[j
].basereg
>= REG_ENUM_LIMIT
)
2423 b
= nasm_reg_flags
[ins
->oprs
[j
].basereg
];
2425 if (ins
->oprs
[j
].scale
== 0)
2429 int ds
= ins
->oprs
[j
].disp_size
;
2430 if ((addrbits
!= 64 && ds
> 8) ||
2431 (addrbits
== 64 && ds
== 16))
2451 if (valid
& addrbits
) {
2452 ins
->addr_size
= addrbits
;
2453 } else if (valid
& ((addrbits
== 32) ? 16 : 32)) {
2454 /* Add an address size prefix */
2455 enum prefixes pref
= (addrbits
== 32) ? P_A16
: P_A32
;
2456 ins
->prefixes
[PPS_ASIZE
] = pref
;
2457 ins
->addr_size
= (addrbits
== 32) ? 16 : 32;
2460 errfunc(ERR_NONFATAL
, "impossible combination of address sizes");
2461 ins
->addr_size
= addrbits
; /* Error recovery */
2464 defdisp
= ins
->addr_size
== 16 ? 16 : 32;
2466 for (j
= 0; j
< ins
->operands
; j
++) {
2467 if (!(MEM_OFFS
& ~ins
->oprs
[j
].type
) &&
2468 (ins
->oprs
[j
].disp_size
? ins
->oprs
[j
].disp_size
: defdisp
)
2469 != ins
->addr_size
) {
2470 /* mem_offs sizes must match the address size; if not,
2471 strip the MEM_OFFS bit and match only EA instructions */
2472 ins
->oprs
[j
].type
&= ~(MEM_OFFS
& ~MEMORY
);