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 * \336 - force a REP(E) prefix (0xF2) even if not specified.
97 * \337 - force a REPNE prefix (0xF3) even if not specified.
98 * \336-\337 are still listed as prefixes in the disassembler.
99 * \340 - reserve <operand 0> bytes of uninitialized storage.
100 * Operand 0 had better be a segmentless constant.
101 * \360 - no SSE prefix (== \364\331)
102 * \361 - 66 SSE prefix (== \366\331)
103 * \362 - F2 SSE prefix (== \364\332)
104 * \363 - F3 SSE prefix (== \364\333)
105 * \364 - operand-size prefix (0x66) not permitted
106 * \365 - address-size prefix (0x67) not permitted
107 * \366 - operand-size prefix (0x66) used as opcode extension
108 * \367 - address-size prefix (0x67) used as opcode extension
109 * \370,\371,\372 - match only if operand 0 meets byte jump criteria.
110 * 370 is used for Jcc, 371 is used for JMP.
111 * \373 - assemble 0x03 if bits==16, 0x05 if bits==32;
112 * used for conditional jump over longer jump
115 #include "compiler.h"
119 #include <inttypes.h>
123 #include "assemble.h"
127 /* Initialized to zero by the C standard */
128 static const uint8_t const_zero_buf
[256];
131 int sib_present
; /* is a SIB byte necessary? */
132 int bytes
; /* # of bytes of offset needed */
133 int size
; /* lazy - this is sib+bytes+1 */
134 uint8_t modrm
, sib
, rex
, rip
; /* the bytes themselves */
137 static uint32_t cpu
; /* cpu level received from nasm.c */
138 static efunc errfunc
;
139 static struct ofmt
*outfmt
;
140 static ListGen
*list
;
142 static int64_t calcsize(int32_t, int64_t, int, insn
*, const uint8_t *);
143 static void gencode(int32_t, int64_t, int, insn
*, const uint8_t *, int64_t);
144 static int matches(const struct itemplate
*, insn
*, int bits
);
145 static int32_t regflag(const operand
*);
146 static int32_t regval(const operand
*);
147 static int rexflags(int, int32_t, int);
148 static int op_rexflags(const operand
*, int);
149 static ea
*process_ea(operand
*, ea
*, int, int, int, int32_t);
150 static void add_asp(insn
*, int);
152 static int has_prefix(insn
* ins
, enum prefix_pos pos
, enum prefixes prefix
)
154 return ins
->prefixes
[pos
] == prefix
;
157 static void assert_no_prefix(insn
* ins
, enum prefix_pos pos
)
159 if (ins
->prefixes
[pos
])
160 errfunc(ERR_NONFATAL
, "invalid %s prefix",
161 prefix_name(ins
->prefixes
[pos
]));
164 static const char *size_name(int size
)
186 static void warn_overflow(int size
, int64_t data
)
189 int64_t lim
= ((int64_t)1 << (size
*8))-1;
191 if (data
< ~lim
|| data
> lim
)
192 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
193 "%s data exceeds bounds", size_name(size
));
197 * This routine wrappers the real output format's output routine,
198 * in order to pass a copy of the data off to the listing file
199 * generator at the same time.
201 static void out(int64_t offset
, int32_t segto
, const void *data
,
202 enum out_type type
, uint64_t size
,
203 int32_t segment
, int32_t wrt
)
205 static int32_t lineno
= 0; /* static!!! */
206 static char *lnfname
= NULL
;
209 if (type
== OUT_ADDRESS
&& segment
== NO_SEG
&& wrt
== NO_SEG
) {
211 * This is a non-relocated address, and we're going to
212 * convert it into RAWDATA format.
217 errfunc(ERR_PANIC
, "OUT_ADDRESS with size > 8");
221 WRITEADDR(q
, *(int64_t *)data
, size
);
226 list
->output(offset
, data
, type
, size
);
229 * this call to src_get determines when we call the
230 * debug-format-specific "linenum" function
231 * it updates lineno and lnfname to the current values
232 * returning 0 if "same as last time", -2 if lnfname
233 * changed, and the amount by which lineno changed,
234 * if it did. thus, these variables must be static
237 if (src_get(&lineno
, &lnfname
)) {
238 outfmt
->current_dfmt
->linenum(lnfname
, lineno
, segto
);
241 outfmt
->output(segto
, data
, type
, size
, segment
, wrt
);
244 static int jmp_match(int32_t segment
, int64_t offset
, int bits
,
245 insn
* ins
, const uint8_t *code
)
250 if (c
!= 0370 && c
!= 0371)
252 if (ins
->oprs
[0].opflags
& OPFLAG_FORWARD
) {
253 if ((optimizing
< 0 || (ins
->oprs
[0].type
& STRICT
))
257 return (pass0
== 0); /* match a forward reference */
259 isize
= calcsize(segment
, offset
, bits
, ins
, code
);
260 if (ins
->oprs
[0].segment
!= segment
)
262 isize
= ins
->oprs
[0].offset
- offset
- isize
; /* isize is now the delta */
263 if (isize
>= -128L && isize
<= 127L)
264 return 1; /* it is byte size */
269 int64_t assemble(int32_t segment
, int64_t offset
, int bits
, uint32_t cp
,
270 insn
* instruction
, struct ofmt
*output
, efunc error
,
273 const struct itemplate
*temp
;
278 int64_t start
= offset
;
279 int64_t wsize
= 0; /* size for DB etc. */
281 errfunc
= error
; /* to pass to other functions */
283 outfmt
= output
; /* likewise */
284 list
= listgen
; /* and again */
286 switch (instruction
->opcode
) {
316 int32_t t
= instruction
->times
;
319 "instruction->times < 0 (%ld) in assemble()", t
);
321 while (t
--) { /* repeat TIMES times */
322 for (e
= instruction
->eops
; e
; e
= e
->next
) {
323 if (e
->type
== EOT_DB_NUMBER
) {
325 if (e
->segment
!= NO_SEG
)
326 errfunc(ERR_NONFATAL
,
327 "one-byte relocation attempted");
329 uint8_t out_byte
= e
->offset
;
330 out(offset
, segment
, &out_byte
,
331 OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
333 } else if (wsize
> 8) {
334 errfunc(ERR_NONFATAL
,
335 "integer supplied to a DT, DO or DY"
338 out(offset
, segment
, &e
->offset
,
339 OUT_ADDRESS
, wsize
, e
->segment
, e
->wrt
);
341 } else if (e
->type
== EOT_DB_STRING
||
342 e
->type
== EOT_DB_STRING_FREE
) {
345 out(offset
, segment
, e
->stringval
,
346 OUT_RAWDATA
, e
->stringlen
, NO_SEG
, NO_SEG
);
347 align
= e
->stringlen
% wsize
;
350 align
= wsize
- align
;
351 out(offset
, segment
, const_zero_buf
,
352 OUT_RAWDATA
, align
, NO_SEG
, NO_SEG
);
354 offset
+= e
->stringlen
+ align
;
357 if (t
> 0 && t
== instruction
->times
- 1) {
359 * Dummy call to list->output to give the offset to the
362 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
363 list
->uplevel(LIST_TIMES
);
366 if (instruction
->times
> 1)
367 list
->downlevel(LIST_TIMES
);
368 return offset
- start
;
371 if (instruction
->opcode
== I_INCBIN
) {
372 const char *fname
= instruction
->eops
->stringval
;
375 fp
= fopen(fname
, "rb");
377 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
379 } else if (fseek(fp
, 0L, SEEK_END
) < 0) {
380 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
383 static char buf
[4096];
384 size_t t
= instruction
->times
;
389 if (instruction
->eops
->next
) {
390 base
= instruction
->eops
->next
->offset
;
392 if (instruction
->eops
->next
->next
&&
393 len
> (size_t)instruction
->eops
->next
->next
->offset
)
394 len
= (size_t)instruction
->eops
->next
->next
->offset
;
397 * Dummy call to list->output to give the offset to the
400 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
401 list
->uplevel(LIST_INCBIN
);
405 fseek(fp
, base
, SEEK_SET
);
409 fread(buf
, 1, (l
> (int32_t) sizeof(buf
) ? (int32_t) sizeof(buf
) : l
),
413 * This shouldn't happen unless the file
414 * actually changes while we are reading
418 "`incbin': unexpected EOF while"
419 " reading file `%s'", fname
);
420 t
= 0; /* Try to exit cleanly */
423 out(offset
, segment
, buf
, OUT_RAWDATA
, m
,
428 list
->downlevel(LIST_INCBIN
);
429 if (instruction
->times
> 1) {
431 * Dummy call to list->output to give the offset to the
434 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
435 list
->uplevel(LIST_TIMES
);
436 list
->downlevel(LIST_TIMES
);
439 return instruction
->times
* len
;
441 return 0; /* if we're here, there's an error */
444 /* Check to see if we need an address-size prefix */
445 add_asp(instruction
, bits
);
449 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++){
450 int m
= matches(temp
, instruction
, bits
);
453 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
455 if (m
== 100) { /* matches! */
456 const uint8_t *codes
= temp
->code
;
457 int64_t insn_size
= calcsize(segment
, offset
, bits
,
459 itimes
= instruction
->times
;
460 if (insn_size
< 0) /* shouldn't be, on pass two */
461 error(ERR_PANIC
, "errors made it through from pass one");
464 for (j
= 0; j
< MAXPREFIX
; j
++) {
466 switch (instruction
->prefixes
[j
]) {
482 "cs segment base generated, but will be ignored in 64-bit mode");
489 "ds segment base generated, but will be ignored in 64-bit mode");
496 "es segment base generated, but will be ignored in 64-bit mode");
509 "ss segment base generated, but will be ignored in 64-bit mode");
516 "segr6 and segr7 cannot be used as prefixes");
521 "16-bit addressing is not supported "
523 } else if (bits
!= 16)
533 "64-bit addressing is only supported "
557 error(ERR_PANIC
, "invalid instruction prefix");
560 out(offset
, segment
, &c
, OUT_RAWDATA
, 1,
565 insn_end
= offset
+ insn_size
;
566 gencode(segment
, offset
, bits
, instruction
, codes
,
569 if (itimes
> 0 && itimes
== instruction
->times
- 1) {
571 * Dummy call to list->output to give the offset to the
574 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
575 list
->uplevel(LIST_TIMES
);
578 if (instruction
->times
> 1)
579 list
->downlevel(LIST_TIMES
);
580 return offset
- start
;
581 } else if (m
> 0 && m
> size_prob
) {
587 if (temp
->opcode
== -1) { /* didn't match any instruction */
590 error(ERR_NONFATAL
, "operation size not specified");
593 error(ERR_NONFATAL
, "mismatch in operand sizes");
596 error(ERR_NONFATAL
, "no instruction for this cpu level");
599 error(ERR_NONFATAL
, "instruction not supported in 64-bit mode");
603 "invalid combination of opcode and operands");
610 int64_t insn_size(int32_t segment
, int64_t offset
, int bits
, uint32_t cp
,
611 insn
* instruction
, efunc error
)
613 const struct itemplate
*temp
;
615 errfunc
= error
; /* to pass to other functions */
618 if (instruction
->opcode
== -1)
621 if (instruction
->opcode
== I_DB
|| instruction
->opcode
== I_DW
||
622 instruction
->opcode
== I_DD
|| instruction
->opcode
== I_DQ
||
623 instruction
->opcode
== I_DT
|| instruction
->opcode
== I_DO
||
624 instruction
->opcode
== I_DY
) {
626 int32_t isize
, osize
, wsize
= 0; /* placate gcc */
629 switch (instruction
->opcode
) {
655 for (e
= instruction
->eops
; e
; e
= e
->next
) {
659 if (e
->type
== EOT_DB_NUMBER
)
661 else if (e
->type
== EOT_DB_STRING
||
662 e
->type
== EOT_DB_STRING_FREE
)
663 osize
= e
->stringlen
;
665 align
= (-osize
) % wsize
;
668 isize
+= osize
+ align
;
670 return isize
* instruction
->times
;
673 if (instruction
->opcode
== I_INCBIN
) {
674 const char *fname
= instruction
->eops
->stringval
;
678 fp
= fopen(fname
, "rb");
680 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
682 else if (fseek(fp
, 0L, SEEK_END
) < 0)
683 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
688 if (instruction
->eops
->next
) {
689 len
-= instruction
->eops
->next
->offset
;
690 if (instruction
->eops
->next
->next
&&
691 len
> (size_t)instruction
->eops
->next
->next
->offset
) {
692 len
= (size_t)instruction
->eops
->next
->next
->offset
;
695 return instruction
->times
* len
;
697 return 0; /* if we're here, there's an error */
700 /* Check to see if we need an address-size prefix */
701 add_asp(instruction
, bits
);
703 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++) {
704 int m
= matches(temp
, instruction
, bits
);
706 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
709 /* we've matched an instruction. */
711 const uint8_t *codes
= temp
->code
;
714 isize
= calcsize(segment
, offset
, bits
, instruction
, codes
);
717 for (j
= 0; j
< MAXPREFIX
; j
++) {
718 switch (instruction
->prefixes
[j
]) {
744 return isize
* instruction
->times
;
747 return -1; /* didn't match any instruction */
750 static bool possible_sbyte(operand
*o
)
752 return !(o
->opflags
& OPFLAG_FORWARD
) &&
753 optimizing
>= 0 && !(o
->type
& STRICT
) &&
754 o
->wrt
== NO_SEG
&& o
->segment
== NO_SEG
;
757 /* check that opn[op] is a signed byte of size 16 or 32 */
758 static bool is_sbyte16(operand
*o
)
762 if (!possible_sbyte(o
))
766 return v
>= -128 && v
<= 127;
769 static bool is_sbyte32(operand
*o
)
773 if (!possible_sbyte(o
))
777 return v
>= -128 && v
<= 127;
780 /* check that opn[op] is a signed byte of size 32; warn if this is not
781 the original value when extended to 64 bits */
782 static bool is_sbyte64(operand
*o
)
787 /* dead in the water on forward reference or External */
788 if (!possible_sbyte(o
))
794 warn_overflow(32, v64
);
796 return v32
>= -128 && v32
<= 127;
798 static int64_t calcsize(int32_t segment
, int64_t offset
, int bits
,
799 insn
* ins
, const uint8_t *codes
)
806 ins
->rex
= 0; /* Ensure REX is reset */
808 if (ins
->prefixes
[PPS_OSIZE
] == P_O64
)
811 (void)segment
; /* Don't warn that this parameter is unused */
812 (void)offset
; /* Don't warn that this parameter is unused */
816 opx
= &ins
->oprs
[c
& 3];
821 codes
+= c
, length
+= c
;
834 op_rexflags(opx
, REX_B
|REX_H
|REX_P
|REX_W
);
865 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
866 length
+= (opx
->type
& BITS16
) ? 2 : 4;
868 length
+= (bits
== 16) ? 2 : 4;
880 length
+= ins
->addr_size
>> 3;
892 length
+= 8; /* MOV reg64/imm */
904 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
905 length
+= (opx
->type
& BITS16
) ? 2 : 4;
907 length
+= (bits
== 16) ? 2 : 4;
925 length
+= is_sbyte16(opx
) ? 1 : 2;
938 length
+= is_sbyte32(opx
) ? 1 : 4;
953 ins
->drexdst
= regval(opx
);
960 ins
->rex
|= REX_D
|REX_OC
;
961 ins
->drexdst
= regval(opx
);
975 length
+= is_sbyte64(opx
) ? 1 : 4;
982 ins
->drexdst
= regval(opx
);
983 ins
->vex_m
= *codes
++;
984 ins
->vex_wlp
= *codes
++;
989 ins
->vex_m
= *codes
++;
990 ins
->vex_wlp
= *codes
++;
1000 length
+= (bits
!= 16) && !has_prefix(ins
, PPS_ASIZE
, P_A16
);
1003 length
+= (bits
!= 32) && !has_prefix(ins
, PPS_ASIZE
, P_A32
);
1008 if (bits
!= 64 || has_prefix(ins
, PPS_ASIZE
, P_A16
) ||
1009 has_prefix(ins
, PPS_ASIZE
, P_A32
))
1018 length
+= (bits
!= 16);
1021 length
+= (bits
== 16);
1046 if (!ins
->prefixes
[PPS_LREP
])
1047 ins
->prefixes
[PPS_LREP
] = P_REP
;
1050 if (!ins
->prefixes
[PPS_LREP
])
1051 ins
->prefixes
[PPS_LREP
] = P_REPNE
;
1054 if (ins
->oprs
[0].segment
!= NO_SEG
)
1055 errfunc(ERR_NONFATAL
, "attempt to reserve non-constant"
1056 " quantity of BSS space");
1058 length
+= ins
->oprs
[0].offset
;
1081 default: /* can't do it by 'case' statements */
1082 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1086 ea_data
.rex
= 0; /* Ensure ea.REX is initially 0 */
1089 /* pick rfield from operand b */
1090 rflags
= regflag(&ins
->oprs
[c
& 7]);
1091 rfield
= nasm_regvals
[ins
->oprs
[c
& 7].basereg
];
1098 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1099 ins
->addr_size
, rfield
, rflags
)) {
1100 errfunc(ERR_NONFATAL
, "invalid effective address");
1103 ins
->rex
|= ea_data
.rex
;
1104 length
+= ea_data
.size
;
1107 errfunc(ERR_PANIC
, "internal instruction table corrupt"
1108 ": instruction code 0x%02X given", c
);
1113 ins
->rex
&= rex_mask
;
1115 if (ins
->rex
& REX_V
) {
1116 int bad32
= REX_R
|REX_W
|REX_X
|REX_B
;
1118 if (ins
->rex
& REX_H
) {
1119 errfunc(ERR_NONFATAL
, "cannot use high register in vex instruction");
1122 switch (ins
->vex_wlp
& 030) {
1136 if (bits
!= 64 && ((ins
->rex
& bad32
) || ins
->drexdst
> 7)) {
1137 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1140 if (ins
->vex_m
!= 1 || (ins
->rex
& (REX_W
|REX_R
|REX_B
)))
1144 } else if (ins
->rex
& REX_D
) {
1145 if (ins
->rex
& REX_H
) {
1146 errfunc(ERR_NONFATAL
, "cannot use high register in drex instruction");
1149 if (bits
!= 64 && ((ins
->rex
& (REX_R
|REX_W
|REX_X
|REX_B
)) ||
1150 ins
->drexdst
> 7)) {
1151 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1155 } else if (ins
->rex
& REX_REAL
) {
1156 if (ins
->rex
& REX_H
) {
1157 errfunc(ERR_NONFATAL
, "cannot use high register in rex instruction");
1159 } else if (bits
== 64) {
1161 } else if ((ins
->rex
& REX_L
) &&
1162 !(ins
->rex
& (REX_P
|REX_W
|REX_X
|REX_B
)) &&
1165 assert_no_prefix(ins
, PPS_LREP
);
1168 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1176 #define EMIT_REX() \
1177 if (!(ins->rex & (REX_D|REX_V)) && (ins->rex & REX_REAL) && (bits == 64)) { \
1178 ins->rex = (ins->rex & REX_REAL)|REX_P; \
1179 out(offset, segment, &ins->rex, OUT_RAWDATA, 1, NO_SEG, NO_SEG); \
1184 static void gencode(int32_t segment
, int64_t offset
, int bits
,
1185 insn
* ins
, const uint8_t *codes
, int64_t insn_end
)
1187 static char condval
[] = { /* conditional opcodes */
1188 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
1189 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
1190 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
1196 struct operand
*opx
;
1200 opx
= &ins
->oprs
[c
& 3];
1206 out(offset
, segment
, codes
, OUT_RAWDATA
, c
, NO_SEG
, NO_SEG
);
1213 switch (ins
->oprs
[0].basereg
) {
1215 bytes
[0] = 0x0E + (c
== 0x04 ? 1 : 0);
1218 bytes
[0] = 0x1E + (c
== 0x04 ? 1 : 0);
1221 bytes
[0] = 0x06 + (c
== 0x04 ? 1 : 0);
1224 bytes
[0] = 0x16 + (c
== 0x04 ? 1 : 0);
1228 "bizarre 8086 segment register received");
1230 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1236 switch (ins
->oprs
[0].basereg
) {
1238 bytes
[0] = 0xA0 + (c
== 0x05 ? 1 : 0);
1241 bytes
[0] = 0xA8 + (c
== 0x05 ? 1 : 0);
1245 "bizarre 386 segment register received");
1247 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1256 bytes
[0] = *codes
++ + ((regval(opx
)) & 7);
1257 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1265 /* XXX: warns for legitimate optimizer actions */
1266 if (opx
->offset
< -128 || opx
->offset
> 127) {
1267 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1268 "signed byte value exceeds bounds");
1271 if (opx
->segment
!= NO_SEG
) {
1273 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1274 opx
->segment
, opx
->wrt
);
1276 bytes
[0] = opx
->offset
;
1277 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1287 if (opx
->offset
< -256 || opx
->offset
> 255) {
1288 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1289 "byte value exceeds bounds");
1291 if (opx
->segment
!= NO_SEG
) {
1293 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1294 opx
->segment
, opx
->wrt
);
1296 bytes
[0] = opx
->offset
;
1297 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1307 if (opx
->offset
< 0 || opx
->offset
> 255)
1308 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1309 "unsigned byte value exceeds bounds");
1310 if (opx
->segment
!= NO_SEG
) {
1312 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1313 opx
->segment
, opx
->wrt
);
1315 bytes
[0] = opx
->offset
;
1316 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1327 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1328 warn_overflow(2, data
);
1329 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1330 opx
->segment
, opx
->wrt
);
1338 if (opx
->type
& (BITS16
| BITS32
))
1339 size
= (opx
->type
& BITS16
) ? 2 : 4;
1341 size
= (bits
== 16) ? 2 : 4;
1343 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1344 warn_overflow(size
, data
);
1345 out(offset
, segment
, &data
, OUT_ADDRESS
, size
,
1346 opx
->segment
, opx
->wrt
);
1355 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1356 warn_overflow(4, data
);
1357 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1358 opx
->segment
, opx
->wrt
);
1367 size
= ins
->addr_size
>> 3;
1368 if (opx
->segment
== NO_SEG
&&
1370 warn_overflow(size
, data
);
1371 out(offset
, segment
, &data
, OUT_ADDRESS
, size
,
1372 opx
->segment
, opx
->wrt
);
1380 if (opx
->segment
!= segment
)
1381 errfunc(ERR_NONFATAL
,
1382 "short relative jump outside segment");
1383 data
= opx
->offset
- insn_end
;
1384 if (data
> 127 || data
< -128)
1385 errfunc(ERR_NONFATAL
, "short jump is out of range");
1387 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1395 data
= (int64_t)opx
->offset
;
1396 out(offset
, segment
, &data
, OUT_ADDRESS
, 8,
1397 opx
->segment
, opx
->wrt
);
1405 if (opx
->segment
!= segment
) {
1407 out(offset
, segment
, &data
,
1408 OUT_REL2ADR
, insn_end
- offset
,
1409 opx
->segment
, opx
->wrt
);
1411 data
= opx
->offset
- insn_end
;
1412 out(offset
, segment
, &data
,
1413 OUT_ADDRESS
, 2, NO_SEG
, NO_SEG
);
1422 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
1423 size
= (opx
->type
& BITS16
) ? 2 : 4;
1425 size
= (bits
== 16) ? 2 : 4;
1426 if (opx
->segment
!= segment
) {
1428 out(offset
, segment
, &data
,
1429 size
== 2 ? OUT_REL2ADR
: OUT_REL4ADR
,
1430 insn_end
- offset
, opx
->segment
, opx
->wrt
);
1432 data
= opx
->offset
- insn_end
;
1433 out(offset
, segment
, &data
,
1434 OUT_ADDRESS
, size
, NO_SEG
, NO_SEG
);
1443 if (opx
->segment
!= segment
) {
1445 out(offset
, segment
, &data
,
1446 OUT_REL4ADR
, insn_end
- offset
,
1447 opx
->segment
, opx
->wrt
);
1449 data
= opx
->offset
- insn_end
;
1450 out(offset
, segment
, &data
,
1451 OUT_ADDRESS
, 4, NO_SEG
, NO_SEG
);
1460 if (opx
->segment
== NO_SEG
)
1461 errfunc(ERR_NONFATAL
, "value referenced by FAR is not"
1464 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1465 outfmt
->segbase(1 + opx
->segment
),
1475 if (is_sbyte16(opx
)) {
1477 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1481 if (opx
->segment
== NO_SEG
&&
1483 warn_overflow(2, data
);
1484 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1485 opx
->segment
, opx
->wrt
);
1495 bytes
[0] = *codes
++;
1496 if (is_sbyte16(opx
))
1497 bytes
[0] |= 2; /* s-bit */
1498 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1507 if (is_sbyte32(opx
)) {
1509 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1513 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1514 opx
->segment
, opx
->wrt
);
1524 bytes
[0] = *codes
++;
1525 if (is_sbyte32(opx
))
1526 bytes
[0] |= 2; /* s-bit */
1527 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1543 (ins
->drexdst
<< 4) |
1544 (ins
->rex
& REX_OC
? 0x08 : 0) |
1545 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1547 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1553 opx
= &ins
->oprs
[c
>> 3];
1554 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1555 opx
= &ins
->oprs
[c
& 7];
1556 if (opx
->segment
!= NO_SEG
|| opx
->wrt
!= NO_SEG
) {
1557 errfunc(ERR_NONFATAL
,
1558 "non-absolute expression not permitted as argument %d",
1561 if (opx
->offset
& ~15) {
1562 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1563 "four-bit argument exceeds bounds");
1565 bytes
[0] |= opx
->offset
& 15;
1567 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1573 opx
= &ins
->oprs
[c
>> 4];
1574 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1576 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1582 opx
= &ins
->oprs
[c
];
1583 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1584 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1593 /* is_sbyte32() is right here, we have already warned */
1594 if (is_sbyte32(opx
)) {
1596 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1600 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1601 opx
->segment
, opx
->wrt
);
1612 if (ins
->vex_m
!= 1 || (ins
->rex
& (REX_W
|REX_X
|REX_B
))) {
1614 bytes
[1] = ins
->vex_m
| ((~ins
->rex
& 7) << 5);
1615 bytes
[2] = ((ins
->rex
& REX_W
) << (7-3)) |
1616 ((~ins
->drexdst
& 15)<< 3) | (ins
->vex_wlp
& 07);
1617 out(offset
, segment
, &bytes
, OUT_RAWDATA
, 3, NO_SEG
, NO_SEG
);
1621 bytes
[1] = ((~ins
->rex
& REX_R
) << (7-2)) |
1622 ((~ins
->drexdst
& 15) << 3) | (ins
->vex_wlp
& 07);
1623 out(offset
, segment
, &bytes
, OUT_RAWDATA
, 2, NO_SEG
, NO_SEG
);
1635 if (bits
== 32 && !has_prefix(ins
, PPS_ASIZE
, P_A16
)) {
1637 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1644 if (bits
!= 32 && !has_prefix(ins
, PPS_ASIZE
, P_A32
)) {
1646 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1668 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1677 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1692 *bytes
= *codes
++ ^ condval
[ins
->condition
];
1693 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1702 *bytes
= c
- 0332 + 0xF2;
1703 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1708 if (ins
->rex
& REX_R
) {
1710 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1713 ins
->rex
&= ~(REX_L
|REX_R
);
1724 if (ins
->oprs
[0].segment
!= NO_SEG
)
1725 errfunc(ERR_PANIC
, "non-constant BSS size in pass two");
1727 int64_t size
= ins
->oprs
[0].offset
;
1729 out(offset
, segment
, NULL
,
1730 OUT_RESERVE
, size
, NO_SEG
, NO_SEG
);
1740 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1746 bytes
[0] = c
- 0362 + 0xf2;
1747 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1757 *bytes
= c
- 0366 + 0x66;
1758 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1768 *bytes
= bits
== 16 ? 3 : 5;
1769 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1773 default: /* can't do it by 'case' statements */
1774 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1782 /* pick rfield from operand b */
1783 rflags
= regflag(&ins
->oprs
[c
& 7]);
1784 rfield
= nasm_regvals
[ins
->oprs
[c
& 7].basereg
];
1786 /* rfield is constant */
1792 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1793 ins
->addr_size
, rfield
, rflags
)) {
1794 errfunc(ERR_NONFATAL
, "invalid effective address");
1799 *p
++ = ea_data
.modrm
;
1800 if (ea_data
.sib_present
)
1803 /* DREX suffixes come between the SIB and the displacement */
1804 if (ins
->rex
& REX_D
) {
1806 (ins
->drexdst
<< 4) |
1807 (ins
->rex
& REX_OC
? 0x08 : 0) |
1808 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1813 out(offset
, segment
, bytes
, OUT_RAWDATA
, s
, NO_SEG
, NO_SEG
);
1815 switch (ea_data
.bytes
) {
1819 if (ins
->oprs
[(c
>> 3) & 7].segment
!= NO_SEG
) {
1820 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1821 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1822 ins
->oprs
[(c
>> 3) & 7].segment
,
1823 ins
->oprs
[(c
>> 3) & 7].wrt
);
1825 *bytes
= ins
->oprs
[(c
>> 3) & 7].offset
;
1826 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1,
1834 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1835 warn_overflow(ea_data
.bytes
, data
);
1836 out(offset
, segment
, &data
,
1837 ea_data
.rip
? OUT_REL4ADR
: OUT_ADDRESS
,
1839 ins
->oprs
[(c
>> 3) & 7].segment
,
1840 ins
->oprs
[(c
>> 3) & 7].wrt
);
1846 errfunc(ERR_PANIC
, "internal instruction table corrupt"
1847 ": instruction code 0x%02X given", c
);
1853 static int32_t regflag(const operand
* o
)
1855 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1856 errfunc(ERR_PANIC
, "invalid operand passed to regflag()");
1858 return nasm_reg_flags
[o
->basereg
];
1861 static int32_t regval(const operand
* o
)
1863 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1864 errfunc(ERR_PANIC
, "invalid operand passed to regval()");
1866 return nasm_regvals
[o
->basereg
];
1869 static int op_rexflags(const operand
* o
, int mask
)
1874 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1875 errfunc(ERR_PANIC
, "invalid operand passed to op_rexflags()");
1878 flags
= nasm_reg_flags
[o
->basereg
];
1879 val
= nasm_regvals
[o
->basereg
];
1881 return rexflags(val
, flags
, mask
);
1884 static int rexflags(int val
, int32_t flags
, int mask
)
1889 rex
|= REX_B
|REX_X
|REX_R
;
1892 if (!(REG_HIGH
& ~flags
)) /* AH, CH, DH, BH */
1894 else if (!(REG8
& ~flags
) && val
>= 4) /* SPL, BPL, SIL, DIL */
1900 static int matches(const struct itemplate
*itemp
, insn
* instruction
, int bits
)
1902 int i
, size
[MAX_OPERANDS
], asize
, oprs
, ret
;
1909 if (itemp
->opcode
!= instruction
->opcode
)
1913 * Count the operands
1915 if (itemp
->operands
!= instruction
->operands
)
1919 * Check that no spurious colons or TOs are present
1921 for (i
= 0; i
< itemp
->operands
; i
++)
1922 if (instruction
->oprs
[i
].type
& ~itemp
->opd
[i
] & (COLON
| TO
))
1926 * Process size flags
1928 if (itemp
->flags
& IF_ARMASK
) {
1929 memset(size
, 0, sizeof size
);
1931 i
= ((itemp
->flags
& IF_ARMASK
) >> IF_ARSHFT
) - 1;
1933 switch (itemp
->flags
& IF_SMASK
) {
1970 switch (itemp
->flags
& IF_SMASK
) {
2005 for (i
= 0; i
< MAX_OPERANDS
; i
++)
2010 * Check that the operand flags all match up
2012 for (i
= 0; i
< itemp
->operands
; i
++) {
2013 int32_t type
= instruction
->oprs
[i
].type
;
2014 if (!(type
& SIZE_MASK
))
2017 if (itemp
->opd
[i
] & SAME_AS
) {
2018 int j
= itemp
->opd
[i
] & ~SAME_AS
;
2019 if (type
!= instruction
->oprs
[j
].type
||
2020 instruction
->oprs
[i
].basereg
!= instruction
->oprs
[j
].basereg
)
2022 } else if (itemp
->opd
[i
] & ~type
||
2023 ((itemp
->opd
[i
] & SIZE_MASK
) &&
2024 ((itemp
->opd
[i
] ^ type
) & SIZE_MASK
))) {
2025 if ((itemp
->opd
[i
] & ~type
& ~SIZE_MASK
) ||
2034 * Check operand sizes
2036 if (itemp
->flags
& (IF_SM
| IF_SM2
)) {
2037 oprs
= (itemp
->flags
& IF_SM2
? 2 : itemp
->operands
);
2039 for (i
= 0; i
< oprs
; i
++) {
2040 if ((asize
= itemp
->opd
[i
] & SIZE_MASK
) != 0) {
2042 for (j
= 0; j
< oprs
; j
++)
2048 oprs
= itemp
->operands
;
2051 for (i
= 0; i
< itemp
->operands
; i
++) {
2052 if (!(itemp
->opd
[i
] & SIZE_MASK
) &&
2053 (instruction
->oprs
[i
].type
& SIZE_MASK
& ~size
[i
]))
2058 * Check template is okay at the set cpu level
2060 if (((itemp
->flags
& IF_PLEVEL
) > cpu
))
2064 * Check if instruction is available in long mode
2066 if ((itemp
->flags
& IF_NOLONG
) && (bits
== 64))
2070 * Check if special handling needed for Jumps
2072 if ((uint8_t)(itemp
->code
[0]) >= 0370)
2078 static ea
*process_ea(operand
* input
, ea
* output
, int bits
,
2079 int addrbits
, int rfield
, int32_t rflags
)
2081 bool forw_ref
= !!(input
->opflags
& OPFLAG_FORWARD
);
2083 output
->rip
= false;
2085 /* REX flags for the rfield operand */
2086 output
->rex
|= rexflags(rfield
, rflags
, REX_R
|REX_P
|REX_W
|REX_H
);
2088 if (!(REGISTER
& ~input
->type
)) { /* register direct */
2092 if (input
->basereg
< EXPR_REG_START
/* Verify as Register */
2093 || input
->basereg
>= REG_ENUM_LIMIT
)
2096 i
= nasm_regvals
[input
->basereg
];
2099 return NULL
; /* Invalid EA register */
2101 output
->rex
|= op_rexflags(input
, REX_B
|REX_P
|REX_W
|REX_H
);
2103 output
->sib_present
= false; /* no SIB necessary */
2104 output
->bytes
= 0; /* no offset necessary either */
2105 output
->modrm
= 0xC0 | ((rfield
& 7) << 3) | (i
& 7);
2106 } else { /* it's a memory reference */
2107 if (input
->basereg
== -1
2108 && (input
->indexreg
== -1 || input
->scale
== 0)) {
2109 /* it's a pure offset */
2110 if (bits
== 64 && (~input
->type
& IP_REL
)) {
2111 int scale
, index
, base
;
2112 output
->sib_present
= true;
2116 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
2118 output
->modrm
= 4 | ((rfield
& 7) << 3);
2119 output
->rip
= false;
2121 output
->sib_present
= false;
2122 output
->bytes
= (addrbits
!= 16 ? 4 : 2);
2123 output
->modrm
= (addrbits
!= 16 ? 5 : 6) | ((rfield
& 7) << 3);
2124 output
->rip
= bits
== 64;
2126 } else { /* it's an indirection */
2127 int i
= input
->indexreg
, b
= input
->basereg
, s
= input
->scale
;
2128 int32_t o
= input
->offset
, seg
= input
->segment
;
2129 int hb
= input
->hintbase
, ht
= input
->hinttype
;
2132 int32_t ix
, bx
; /* register flags */
2135 i
= -1; /* make this easy, at least */
2137 if (i
>= EXPR_REG_START
&& i
< REG_ENUM_LIMIT
) {
2138 it
= nasm_regvals
[i
];
2139 ix
= nasm_reg_flags
[i
];
2145 if (b
>= EXPR_REG_START
&& b
< REG_ENUM_LIMIT
) {
2146 bt
= nasm_regvals
[b
];
2147 bx
= nasm_reg_flags
[b
];
2153 /* check for a 32/64-bit memory reference... */
2154 if ((ix
|bx
) & (BITS32
|BITS64
)) {
2155 /* it must be a 32/64-bit memory reference. Firstly we have
2156 * to check that all registers involved are type E/Rxx. */
2157 int32_t sok
= BITS32
|BITS64
;
2160 if (!(REG64
& ~ix
) || !(REG32
& ~ix
))
2168 return NULL
; /* Invalid register */
2169 if (~sok
& bx
& SIZE_MASK
)
2170 return NULL
; /* Invalid size */
2174 /* While we're here, ensure the user didn't specify
2176 if (input
->disp_size
== 16 || input
->disp_size
== 64)
2179 if (addrbits
== 16 ||
2180 (addrbits
== 32 && !(sok
& BITS32
)) ||
2181 (addrbits
== 64 && !(sok
& BITS64
)))
2184 /* now reorganize base/index */
2185 if (s
== 1 && bt
!= it
&& bt
!= -1 && it
!= -1 &&
2186 ((hb
== b
&& ht
== EAH_NOTBASE
)
2187 || (hb
== i
&& ht
== EAH_MAKEBASE
))) {
2188 /* swap if hints say so */
2189 t
= bt
, bt
= it
, it
= t
;
2190 t
= bx
, bx
= ix
, ix
= t
;
2192 if (bt
== it
) /* convert EAX+2*EAX to 3*EAX */
2193 bt
= -1, bx
= 0, s
++;
2194 if (bt
== -1 && s
== 1 && !(hb
== it
&& ht
== EAH_NOTBASE
)) {
2195 /* make single reg base, unless hint */
2196 bt
= it
, bx
= ix
, it
= -1, ix
= 0;
2198 if (((s
== 2 && it
!= REG_NUM_ESP
2199 && !(input
->eaflags
& EAF_TIMESTWO
)) || s
== 3
2200 || s
== 5 || s
== 9) && bt
== -1)
2201 bt
= it
, bx
= ix
, s
--; /* convert 3*EAX to EAX+2*EAX */
2202 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
2203 && (input
->eaflags
& EAF_TIMESTWO
))
2204 it
= bt
, ix
= bx
, bt
= -1, bx
= 0, s
= 1;
2205 /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */
2206 if (s
== 1 && it
== REG_NUM_ESP
) {
2207 /* swap ESP into base if scale is 1 */
2208 t
= it
, it
= bt
, bt
= t
;
2209 t
= ix
, ix
= bx
, bx
= t
;
2211 if (it
== REG_NUM_ESP
2212 || (s
!= 1 && s
!= 2 && s
!= 4 && s
!= 8 && it
!= -1))
2213 return NULL
; /* wrong, for various reasons */
2215 output
->rex
|= rexflags(it
, ix
, REX_X
);
2216 output
->rex
|= rexflags(bt
, bx
, REX_B
);
2218 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
) {
2227 if (rm
!= REG_NUM_EBP
&& o
== 0 &&
2228 seg
== NO_SEG
&& !forw_ref
&&
2230 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2232 else if (input
->eaflags
& EAF_BYTEOFFS
||
2233 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2235 && !(input
->eaflags
& EAF_WORDOFFS
)))
2241 output
->sib_present
= false;
2242 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
2243 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
2246 int mod
, scale
, index
, base
;
2266 default: /* then what the smeg is it? */
2267 return NULL
; /* panic */
2275 if (base
!= REG_NUM_EBP
&& o
== 0 &&
2276 seg
== NO_SEG
&& !forw_ref
&&
2278 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2280 else if (input
->eaflags
& EAF_BYTEOFFS
||
2281 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2283 && !(input
->eaflags
& EAF_WORDOFFS
)))
2289 output
->sib_present
= true;
2290 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
2291 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | 4;
2292 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
2294 } else { /* it's 16-bit */
2297 /* check for 64-bit long mode */
2301 /* check all registers are BX, BP, SI or DI */
2302 if ((b
!= -1 && b
!= R_BP
&& b
!= R_BX
&& b
!= R_SI
2303 && b
!= R_DI
) || (i
!= -1 && i
!= R_BP
&& i
!= R_BX
2304 && i
!= R_SI
&& i
!= R_DI
))
2307 /* ensure the user didn't specify DWORD/QWORD */
2308 if (input
->disp_size
== 32 || input
->disp_size
== 64)
2311 if (s
!= 1 && i
!= -1)
2312 return NULL
; /* no can do, in 16-bit EA */
2313 if (b
== -1 && i
!= -1) {
2318 if ((b
== R_SI
|| b
== R_DI
) && i
!= -1) {
2323 /* have BX/BP as base, SI/DI index */
2325 return NULL
; /* shouldn't ever happen, in theory */
2326 if (i
!= -1 && b
!= -1 &&
2327 (i
== R_BP
|| i
== R_BX
|| b
== R_SI
|| b
== R_DI
))
2328 return NULL
; /* invalid combinations */
2329 if (b
== -1) /* pure offset: handled above */
2330 return NULL
; /* so if it gets to here, panic! */
2334 switch (i
* 256 + b
) {
2335 case R_SI
* 256 + R_BX
:
2338 case R_DI
* 256 + R_BX
:
2341 case R_SI
* 256 + R_BP
:
2344 case R_DI
* 256 + R_BP
:
2362 if (rm
== -1) /* can't happen, in theory */
2363 return NULL
; /* so panic if it does */
2365 if (o
== 0 && seg
== NO_SEG
&& !forw_ref
&& rm
!= 6 &&
2366 !(input
->eaflags
& (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2368 else if (input
->eaflags
& EAF_BYTEOFFS
||
2369 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2371 && !(input
->eaflags
& EAF_WORDOFFS
)))
2376 output
->sib_present
= false; /* no SIB - it's 16-bit */
2377 output
->bytes
= mod
; /* bytes of offset needed */
2378 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
2383 output
->size
= 1 + output
->sib_present
+ output
->bytes
;
2387 static void add_asp(insn
*ins
, int addrbits
)
2392 valid
= (addrbits
== 64) ? 64|32 : 32|16;
2394 switch (ins
->prefixes
[PPS_ASIZE
]) {
2405 valid
&= (addrbits
== 32) ? 16 : 32;
2411 for (j
= 0; j
< ins
->operands
; j
++) {
2412 if (!(MEMORY
& ~ins
->oprs
[j
].type
)) {
2415 /* Verify as Register */
2416 if (ins
->oprs
[j
].indexreg
< EXPR_REG_START
2417 || ins
->oprs
[j
].indexreg
>= REG_ENUM_LIMIT
)
2420 i
= nasm_reg_flags
[ins
->oprs
[j
].indexreg
];
2422 /* Verify as Register */
2423 if (ins
->oprs
[j
].basereg
< EXPR_REG_START
2424 || ins
->oprs
[j
].basereg
>= REG_ENUM_LIMIT
)
2427 b
= nasm_reg_flags
[ins
->oprs
[j
].basereg
];
2429 if (ins
->oprs
[j
].scale
== 0)
2433 int ds
= ins
->oprs
[j
].disp_size
;
2434 if ((addrbits
!= 64 && ds
> 8) ||
2435 (addrbits
== 64 && ds
== 16))
2455 if (valid
& addrbits
) {
2456 ins
->addr_size
= addrbits
;
2457 } else if (valid
& ((addrbits
== 32) ? 16 : 32)) {
2458 /* Add an address size prefix */
2459 enum prefixes pref
= (addrbits
== 32) ? P_A16
: P_A32
;
2460 ins
->prefixes
[PPS_ASIZE
] = pref
;
2461 ins
->addr_size
= (addrbits
== 32) ? 16 : 32;
2464 errfunc(ERR_NONFATAL
, "impossible combination of address sizes");
2465 ins
->addr_size
= addrbits
; /* Error recovery */
2468 defdisp
= ins
->addr_size
== 16 ? 16 : 32;
2470 for (j
= 0; j
< ins
->operands
; j
++) {
2471 if (!(MEM_OFFS
& ~ins
->oprs
[j
].type
) &&
2472 (ins
->oprs
[j
].disp_size
? ins
->oprs
[j
].disp_size
: defdisp
)
2473 != ins
->addr_size
) {
2474 /* mem_offs sizes must match the address size; if not,
2475 strip the MEM_OFFS bit and match only EA instructions */
2476 ins
->oprs
[j
].type
&= ~(MEM_OFFS
& ~MEMORY
);