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 bool jmp_match(int32_t segment
, int64_t offset
, int bits
,
245 insn
* ins
, const uint8_t *code
)
250 if ((c
!= 0370 && c
!= 0371) || (ins
->oprs
[0].type
& STRICT
))
254 if (optimizing
< 0 && c
== 0371)
257 isize
= calcsize(segment
, offset
, bits
, ins
, code
);
258 if (ins
->oprs
[0].segment
!= segment
)
261 isize
= ins
->oprs
[0].offset
- offset
- isize
; /* isize is delta */
262 return (isize
>= -128 && isize
<= 127); /* is it byte size? */
265 int64_t assemble(int32_t segment
, int64_t offset
, int bits
, uint32_t cp
,
266 insn
* instruction
, struct ofmt
*output
, efunc error
,
269 const struct itemplate
*temp
;
274 int64_t start
= offset
;
275 int64_t wsize
= 0; /* size for DB etc. */
277 errfunc
= error
; /* to pass to other functions */
279 outfmt
= output
; /* likewise */
280 list
= listgen
; /* and again */
282 switch (instruction
->opcode
) {
312 int32_t t
= instruction
->times
;
315 "instruction->times < 0 (%ld) in assemble()", t
);
317 while (t
--) { /* repeat TIMES times */
318 for (e
= instruction
->eops
; e
; e
= e
->next
) {
319 if (e
->type
== EOT_DB_NUMBER
) {
321 if (e
->segment
!= NO_SEG
)
322 errfunc(ERR_NONFATAL
,
323 "one-byte relocation attempted");
325 uint8_t out_byte
= e
->offset
;
326 out(offset
, segment
, &out_byte
,
327 OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
329 } else if (wsize
> 8) {
330 errfunc(ERR_NONFATAL
,
331 "integer supplied to a DT, DO or DY"
334 out(offset
, segment
, &e
->offset
,
335 OUT_ADDRESS
, wsize
, e
->segment
, e
->wrt
);
337 } else if (e
->type
== EOT_DB_STRING
||
338 e
->type
== EOT_DB_STRING_FREE
) {
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 const char *fname
= instruction
->eops
->stringval
;
371 fp
= fopen(fname
, "rb");
373 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
375 } else if (fseek(fp
, 0L, SEEK_END
) < 0) {
376 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
379 static char buf
[4096];
380 size_t t
= instruction
->times
;
385 if (instruction
->eops
->next
) {
386 base
= instruction
->eops
->next
->offset
;
388 if (instruction
->eops
->next
->next
&&
389 len
> (size_t)instruction
->eops
->next
->next
->offset
)
390 len
= (size_t)instruction
->eops
->next
->next
->offset
;
393 * Dummy call to list->output to give the offset to the
396 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
397 list
->uplevel(LIST_INCBIN
);
401 fseek(fp
, base
, SEEK_SET
);
405 fread(buf
, 1, (l
> (int32_t) sizeof(buf
) ? (int32_t) sizeof(buf
) : l
),
409 * This shouldn't happen unless the file
410 * actually changes while we are reading
414 "`incbin': unexpected EOF while"
415 " reading file `%s'", fname
);
416 t
= 0; /* Try to exit cleanly */
419 out(offset
, segment
, buf
, OUT_RAWDATA
, m
,
424 list
->downlevel(LIST_INCBIN
);
425 if (instruction
->times
> 1) {
427 * Dummy call to list->output to give the offset to the
430 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
431 list
->uplevel(LIST_TIMES
);
432 list
->downlevel(LIST_TIMES
);
435 return instruction
->times
* len
;
437 return 0; /* if we're here, there's an error */
440 /* Check to see if we need an address-size prefix */
441 add_asp(instruction
, bits
);
445 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++){
446 int m
= matches(temp
, instruction
, bits
);
448 (m
== 99 && jmp_match(segment
, offset
, bits
,
449 instruction
, temp
->code
))) {
451 const uint8_t *codes
= temp
->code
;
452 int64_t insn_size
= calcsize(segment
, offset
, bits
,
454 itimes
= instruction
->times
;
455 if (insn_size
< 0) /* shouldn't be, on pass two */
456 error(ERR_PANIC
, "errors made it through from pass one");
459 for (j
= 0; j
< MAXPREFIX
; j
++) {
461 switch (instruction
->prefixes
[j
]) {
477 "cs segment base generated, but will be ignored in 64-bit mode");
484 "ds segment base generated, but will be ignored in 64-bit mode");
491 "es segment base generated, but will be ignored in 64-bit mode");
504 "ss segment base generated, but will be ignored in 64-bit mode");
511 "segr6 and segr7 cannot be used as prefixes");
516 "16-bit addressing is not supported "
518 } else if (bits
!= 16)
528 "64-bit addressing is only supported "
552 error(ERR_PANIC
, "invalid instruction prefix");
555 out(offset
, segment
, &c
, OUT_RAWDATA
, 1,
560 insn_end
= offset
+ insn_size
;
561 gencode(segment
, offset
, bits
, instruction
, codes
,
564 if (itimes
> 0 && itimes
== instruction
->times
- 1) {
566 * Dummy call to list->output to give the offset to the
569 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
570 list
->uplevel(LIST_TIMES
);
573 if (instruction
->times
> 1)
574 list
->downlevel(LIST_TIMES
);
575 return offset
- start
;
576 } else if (m
> 0 && m
> size_prob
) {
581 if (temp
->opcode
== -1) { /* didn't match any instruction */
584 error(ERR_NONFATAL
, "operation size not specified");
587 error(ERR_NONFATAL
, "mismatch in operand sizes");
590 error(ERR_NONFATAL
, "no instruction for this cpu level");
593 error(ERR_NONFATAL
, "instruction not supported in 64-bit mode");
597 "invalid combination of opcode and operands");
604 int64_t insn_size(int32_t segment
, int64_t offset
, int bits
, uint32_t cp
,
605 insn
* instruction
, efunc error
)
607 const struct itemplate
*temp
;
609 errfunc
= error
; /* to pass to other functions */
612 if (instruction
->opcode
== -1)
615 if (instruction
->opcode
== I_DB
|| instruction
->opcode
== I_DW
||
616 instruction
->opcode
== I_DD
|| instruction
->opcode
== I_DQ
||
617 instruction
->opcode
== I_DT
|| instruction
->opcode
== I_DO
||
618 instruction
->opcode
== I_DY
) {
620 int32_t isize
, osize
, wsize
= 0; /* placate gcc */
623 switch (instruction
->opcode
) {
649 for (e
= instruction
->eops
; e
; e
= e
->next
) {
653 if (e
->type
== EOT_DB_NUMBER
)
655 else if (e
->type
== EOT_DB_STRING
||
656 e
->type
== EOT_DB_STRING_FREE
)
657 osize
= e
->stringlen
;
659 align
= (-osize
) % wsize
;
662 isize
+= osize
+ align
;
664 return isize
* instruction
->times
;
667 if (instruction
->opcode
== I_INCBIN
) {
668 const char *fname
= instruction
->eops
->stringval
;
672 fp
= fopen(fname
, "rb");
674 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
676 else if (fseek(fp
, 0L, SEEK_END
) < 0)
677 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
682 if (instruction
->eops
->next
) {
683 len
-= instruction
->eops
->next
->offset
;
684 if (instruction
->eops
->next
->next
&&
685 len
> (size_t)instruction
->eops
->next
->next
->offset
) {
686 len
= (size_t)instruction
->eops
->next
->next
->offset
;
689 return instruction
->times
* len
;
691 return 0; /* if we're here, there's an error */
694 /* Check to see if we need an address-size prefix */
695 add_asp(instruction
, bits
);
697 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++) {
698 int m
= matches(temp
, instruction
, bits
);
700 (m
== 99 && jmp_match(segment
, offset
, bits
,
701 instruction
, temp
->code
))) {
702 /* we've matched an instruction. */
704 const uint8_t *codes
= temp
->code
;
707 isize
= calcsize(segment
, offset
, bits
, instruction
, codes
);
710 for (j
= 0; j
< MAXPREFIX
; j
++) {
711 switch (instruction
->prefixes
[j
]) {
737 return isize
* instruction
->times
;
740 return -1; /* didn't match any instruction */
743 static bool possible_sbyte(operand
*o
)
745 return !(o
->opflags
& OPFLAG_FORWARD
) &&
746 optimizing
>= 0 && !(o
->type
& STRICT
) &&
747 o
->wrt
== NO_SEG
&& o
->segment
== NO_SEG
;
750 /* check that opn[op] is a signed byte of size 16 or 32 */
751 static bool is_sbyte16(operand
*o
)
755 if (!possible_sbyte(o
))
759 return v
>= -128 && v
<= 127;
762 static bool is_sbyte32(operand
*o
)
766 if (!possible_sbyte(o
))
770 return v
>= -128 && v
<= 127;
773 /* check that opn[op] is a signed byte of size 32; warn if this is not
774 the original value when extended to 64 bits */
775 static bool is_sbyte64(operand
*o
)
780 /* dead in the water on forward reference or External */
781 if (!possible_sbyte(o
))
787 warn_overflow(32, v64
);
789 return v32
>= -128 && v32
<= 127;
791 static int64_t calcsize(int32_t segment
, int64_t offset
, int bits
,
792 insn
* ins
, const uint8_t *codes
)
799 ins
->rex
= 0; /* Ensure REX is reset */
801 if (ins
->prefixes
[PPS_OSIZE
] == P_O64
)
804 (void)segment
; /* Don't warn that this parameter is unused */
805 (void)offset
; /* Don't warn that this parameter is unused */
809 opx
= &ins
->oprs
[c
& 3];
814 codes
+= c
, length
+= c
;
827 op_rexflags(opx
, REX_B
|REX_H
|REX_P
|REX_W
);
858 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
859 length
+= (opx
->type
& BITS16
) ? 2 : 4;
861 length
+= (bits
== 16) ? 2 : 4;
873 length
+= ins
->addr_size
>> 3;
885 length
+= 8; /* MOV reg64/imm */
897 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
898 length
+= (opx
->type
& BITS16
) ? 2 : 4;
900 length
+= (bits
== 16) ? 2 : 4;
918 length
+= is_sbyte16(opx
) ? 1 : 2;
931 length
+= is_sbyte32(opx
) ? 1 : 4;
946 ins
->drexdst
= regval(opx
);
953 ins
->rex
|= REX_D
|REX_OC
;
954 ins
->drexdst
= regval(opx
);
968 length
+= is_sbyte64(opx
) ? 1 : 4;
975 ins
->drexdst
= regval(opx
);
976 ins
->vex_m
= *codes
++;
977 ins
->vex_wlp
= *codes
++;
982 ins
->vex_m
= *codes
++;
983 ins
->vex_wlp
= *codes
++;
993 length
+= (bits
!= 16) && !has_prefix(ins
, PPS_ASIZE
, P_A16
);
996 length
+= (bits
!= 32) && !has_prefix(ins
, PPS_ASIZE
, P_A32
);
1001 if (bits
!= 64 || has_prefix(ins
, PPS_ASIZE
, P_A16
) ||
1002 has_prefix(ins
, PPS_ASIZE
, P_A32
))
1011 length
+= (bits
!= 16);
1014 length
+= (bits
== 16);
1039 if (!ins
->prefixes
[PPS_LREP
])
1040 ins
->prefixes
[PPS_LREP
] = P_REP
;
1043 if (!ins
->prefixes
[PPS_LREP
])
1044 ins
->prefixes
[PPS_LREP
] = P_REPNE
;
1047 if (ins
->oprs
[0].segment
!= NO_SEG
)
1048 errfunc(ERR_NONFATAL
, "attempt to reserve non-constant"
1049 " quantity of BSS space");
1051 length
+= ins
->oprs
[0].offset
;
1074 default: /* can't do it by 'case' statements */
1075 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1079 ea_data
.rex
= 0; /* Ensure ea.REX is initially 0 */
1082 /* pick rfield from operand b */
1083 rflags
= regflag(&ins
->oprs
[c
& 7]);
1084 rfield
= nasm_regvals
[ins
->oprs
[c
& 7].basereg
];
1091 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1092 ins
->addr_size
, rfield
, rflags
)) {
1093 errfunc(ERR_NONFATAL
, "invalid effective address");
1096 ins
->rex
|= ea_data
.rex
;
1097 length
+= ea_data
.size
;
1100 errfunc(ERR_PANIC
, "internal instruction table corrupt"
1101 ": instruction code 0x%02X given", c
);
1106 ins
->rex
&= rex_mask
;
1108 if (ins
->rex
& REX_V
) {
1109 int bad32
= REX_R
|REX_W
|REX_X
|REX_B
;
1111 if (ins
->rex
& REX_H
) {
1112 errfunc(ERR_NONFATAL
, "cannot use high register in vex instruction");
1115 switch (ins
->vex_wlp
& 030) {
1129 if (bits
!= 64 && ((ins
->rex
& bad32
) || ins
->drexdst
> 7)) {
1130 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1133 if (ins
->vex_m
!= 1 || (ins
->rex
& (REX_W
|REX_R
|REX_B
)))
1137 } else if (ins
->rex
& REX_D
) {
1138 if (ins
->rex
& REX_H
) {
1139 errfunc(ERR_NONFATAL
, "cannot use high register in drex instruction");
1142 if (bits
!= 64 && ((ins
->rex
& (REX_R
|REX_W
|REX_X
|REX_B
)) ||
1143 ins
->drexdst
> 7)) {
1144 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1148 } else if (ins
->rex
& REX_REAL
) {
1149 if (ins
->rex
& REX_H
) {
1150 errfunc(ERR_NONFATAL
, "cannot use high register in rex instruction");
1152 } else if (bits
== 64) {
1154 } else if ((ins
->rex
& REX_L
) &&
1155 !(ins
->rex
& (REX_P
|REX_W
|REX_X
|REX_B
)) &&
1158 assert_no_prefix(ins
, PPS_LREP
);
1161 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1169 #define EMIT_REX() \
1170 if (!(ins->rex & (REX_D|REX_V)) && (ins->rex & REX_REAL) && (bits == 64)) { \
1171 ins->rex = (ins->rex & REX_REAL)|REX_P; \
1172 out(offset, segment, &ins->rex, OUT_RAWDATA, 1, NO_SEG, NO_SEG); \
1177 static void gencode(int32_t segment
, int64_t offset
, int bits
,
1178 insn
* ins
, const uint8_t *codes
, int64_t insn_end
)
1180 static char condval
[] = { /* conditional opcodes */
1181 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
1182 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
1183 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
1189 struct operand
*opx
;
1193 opx
= &ins
->oprs
[c
& 3];
1199 out(offset
, segment
, codes
, OUT_RAWDATA
, c
, NO_SEG
, NO_SEG
);
1206 switch (ins
->oprs
[0].basereg
) {
1208 bytes
[0] = 0x0E + (c
== 0x04 ? 1 : 0);
1211 bytes
[0] = 0x1E + (c
== 0x04 ? 1 : 0);
1214 bytes
[0] = 0x06 + (c
== 0x04 ? 1 : 0);
1217 bytes
[0] = 0x16 + (c
== 0x04 ? 1 : 0);
1221 "bizarre 8086 segment register received");
1223 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1229 switch (ins
->oprs
[0].basereg
) {
1231 bytes
[0] = 0xA0 + (c
== 0x05 ? 1 : 0);
1234 bytes
[0] = 0xA8 + (c
== 0x05 ? 1 : 0);
1238 "bizarre 386 segment register received");
1240 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1249 bytes
[0] = *codes
++ + ((regval(opx
)) & 7);
1250 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1258 /* XXX: warns for legitimate optimizer actions */
1259 if (opx
->offset
< -128 || opx
->offset
> 127) {
1260 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1261 "signed byte value exceeds bounds");
1264 if (opx
->segment
!= NO_SEG
) {
1266 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1267 opx
->segment
, opx
->wrt
);
1269 bytes
[0] = opx
->offset
;
1270 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1280 if (opx
->offset
< -256 || opx
->offset
> 255) {
1281 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1282 "byte value exceeds bounds");
1284 if (opx
->segment
!= NO_SEG
) {
1286 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1287 opx
->segment
, opx
->wrt
);
1289 bytes
[0] = opx
->offset
;
1290 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1300 if (opx
->offset
< 0 || opx
->offset
> 255)
1301 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1302 "unsigned byte value exceeds bounds");
1303 if (opx
->segment
!= NO_SEG
) {
1305 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1306 opx
->segment
, opx
->wrt
);
1308 bytes
[0] = opx
->offset
;
1309 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1320 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1321 warn_overflow(2, data
);
1322 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1323 opx
->segment
, opx
->wrt
);
1331 if (opx
->type
& (BITS16
| BITS32
))
1332 size
= (opx
->type
& BITS16
) ? 2 : 4;
1334 size
= (bits
== 16) ? 2 : 4;
1336 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1337 warn_overflow(size
, data
);
1338 out(offset
, segment
, &data
, OUT_ADDRESS
, size
,
1339 opx
->segment
, opx
->wrt
);
1348 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1349 warn_overflow(4, data
);
1350 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1351 opx
->segment
, opx
->wrt
);
1360 size
= ins
->addr_size
>> 3;
1361 if (opx
->segment
== NO_SEG
&&
1363 warn_overflow(size
, data
);
1364 out(offset
, segment
, &data
, OUT_ADDRESS
, size
,
1365 opx
->segment
, opx
->wrt
);
1373 if (opx
->segment
!= segment
)
1374 errfunc(ERR_NONFATAL
,
1375 "short relative jump outside segment");
1376 data
= opx
->offset
- insn_end
;
1377 if (data
> 127 || data
< -128)
1378 errfunc(ERR_NONFATAL
, "short jump is out of range");
1380 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1388 data
= (int64_t)opx
->offset
;
1389 out(offset
, segment
, &data
, OUT_ADDRESS
, 8,
1390 opx
->segment
, opx
->wrt
);
1398 if (opx
->segment
!= segment
) {
1400 out(offset
, segment
, &data
,
1401 OUT_REL2ADR
, insn_end
- offset
,
1402 opx
->segment
, opx
->wrt
);
1404 data
= opx
->offset
- insn_end
;
1405 out(offset
, segment
, &data
,
1406 OUT_ADDRESS
, 2, NO_SEG
, NO_SEG
);
1415 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
1416 size
= (opx
->type
& BITS16
) ? 2 : 4;
1418 size
= (bits
== 16) ? 2 : 4;
1419 if (opx
->segment
!= segment
) {
1421 out(offset
, segment
, &data
,
1422 size
== 2 ? OUT_REL2ADR
: OUT_REL4ADR
,
1423 insn_end
- offset
, opx
->segment
, opx
->wrt
);
1425 data
= opx
->offset
- insn_end
;
1426 out(offset
, segment
, &data
,
1427 OUT_ADDRESS
, size
, NO_SEG
, NO_SEG
);
1436 if (opx
->segment
!= segment
) {
1438 out(offset
, segment
, &data
,
1439 OUT_REL4ADR
, insn_end
- offset
,
1440 opx
->segment
, opx
->wrt
);
1442 data
= opx
->offset
- insn_end
;
1443 out(offset
, segment
, &data
,
1444 OUT_ADDRESS
, 4, NO_SEG
, NO_SEG
);
1453 if (opx
->segment
== NO_SEG
)
1454 errfunc(ERR_NONFATAL
, "value referenced by FAR is not"
1457 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1458 outfmt
->segbase(1 + opx
->segment
),
1468 if (is_sbyte16(opx
)) {
1470 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1474 if (opx
->segment
== NO_SEG
&&
1476 warn_overflow(2, data
);
1477 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1478 opx
->segment
, opx
->wrt
);
1488 bytes
[0] = *codes
++;
1489 if (is_sbyte16(opx
))
1490 bytes
[0] |= 2; /* s-bit */
1491 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1500 if (is_sbyte32(opx
)) {
1502 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1506 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1507 opx
->segment
, opx
->wrt
);
1517 bytes
[0] = *codes
++;
1518 if (is_sbyte32(opx
))
1519 bytes
[0] |= 2; /* s-bit */
1520 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1536 (ins
->drexdst
<< 4) |
1537 (ins
->rex
& REX_OC
? 0x08 : 0) |
1538 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1540 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1546 opx
= &ins
->oprs
[c
>> 3];
1547 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1548 opx
= &ins
->oprs
[c
& 7];
1549 if (opx
->segment
!= NO_SEG
|| opx
->wrt
!= NO_SEG
) {
1550 errfunc(ERR_NONFATAL
,
1551 "non-absolute expression not permitted as argument %d",
1554 if (opx
->offset
& ~15) {
1555 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1556 "four-bit argument exceeds bounds");
1558 bytes
[0] |= opx
->offset
& 15;
1560 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1566 opx
= &ins
->oprs
[c
>> 4];
1567 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1569 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1575 opx
= &ins
->oprs
[c
];
1576 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1577 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1586 /* is_sbyte32() is right here, we have already warned */
1587 if (is_sbyte32(opx
)) {
1589 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1593 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1594 opx
->segment
, opx
->wrt
);
1605 if (ins
->vex_m
!= 1 || (ins
->rex
& (REX_W
|REX_X
|REX_B
))) {
1607 bytes
[1] = ins
->vex_m
| ((~ins
->rex
& 7) << 5);
1608 bytes
[2] = ((ins
->rex
& REX_W
) << (7-3)) |
1609 ((~ins
->drexdst
& 15)<< 3) | (ins
->vex_wlp
& 07);
1610 out(offset
, segment
, &bytes
, OUT_RAWDATA
, 3, NO_SEG
, NO_SEG
);
1614 bytes
[1] = ((~ins
->rex
& REX_R
) << (7-2)) |
1615 ((~ins
->drexdst
& 15) << 3) | (ins
->vex_wlp
& 07);
1616 out(offset
, segment
, &bytes
, OUT_RAWDATA
, 2, NO_SEG
, NO_SEG
);
1628 if (bits
== 32 && !has_prefix(ins
, PPS_ASIZE
, P_A16
)) {
1630 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1637 if (bits
!= 32 && !has_prefix(ins
, PPS_ASIZE
, P_A32
)) {
1639 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1661 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1670 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1685 *bytes
= *codes
++ ^ condval
[ins
->condition
];
1686 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1695 *bytes
= c
- 0332 + 0xF2;
1696 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1701 if (ins
->rex
& REX_R
) {
1703 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1706 ins
->rex
&= ~(REX_L
|REX_R
);
1717 if (ins
->oprs
[0].segment
!= NO_SEG
)
1718 errfunc(ERR_PANIC
, "non-constant BSS size in pass two");
1720 int64_t size
= ins
->oprs
[0].offset
;
1722 out(offset
, segment
, NULL
,
1723 OUT_RESERVE
, size
, NO_SEG
, NO_SEG
);
1733 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1739 bytes
[0] = c
- 0362 + 0xf2;
1740 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1750 *bytes
= c
- 0366 + 0x66;
1751 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1761 *bytes
= bits
== 16 ? 3 : 5;
1762 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1766 default: /* can't do it by 'case' statements */
1767 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1775 /* pick rfield from operand b */
1776 rflags
= regflag(&ins
->oprs
[c
& 7]);
1777 rfield
= nasm_regvals
[ins
->oprs
[c
& 7].basereg
];
1779 /* rfield is constant */
1785 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1786 ins
->addr_size
, rfield
, rflags
)) {
1787 errfunc(ERR_NONFATAL
, "invalid effective address");
1792 *p
++ = ea_data
.modrm
;
1793 if (ea_data
.sib_present
)
1796 /* DREX suffixes come between the SIB and the displacement */
1797 if (ins
->rex
& REX_D
) {
1799 (ins
->drexdst
<< 4) |
1800 (ins
->rex
& REX_OC
? 0x08 : 0) |
1801 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1806 out(offset
, segment
, bytes
, OUT_RAWDATA
, s
, NO_SEG
, NO_SEG
);
1809 * Make sure the address gets the right offset in case
1810 * the line breaks in the .lst file (BR 1197827)
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
);