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 /* The test for BITS8 and SBYTE here is intended to avoid
1259 warning on optimizer actions due to SBYTE, while still
1260 warn on explicit BYTE directives. Also warn, obviously,
1261 if the optimizer isn't enabled. */
1262 if (((opx
->type
& BITS8
) ||
1263 !(opx
->type
& (SBYTE16
|SBYTE32
|SBYTE64
))) &&
1264 (opx
->offset
< -128 || opx
->offset
> 127)) {
1265 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1266 "signed byte value exceeds bounds");
1268 if (opx
->segment
!= NO_SEG
) {
1270 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1271 opx
->segment
, opx
->wrt
);
1273 bytes
[0] = opx
->offset
;
1274 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1284 if (opx
->offset
< -256 || opx
->offset
> 255) {
1285 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1286 "byte value exceeds bounds");
1288 if (opx
->segment
!= NO_SEG
) {
1290 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1291 opx
->segment
, opx
->wrt
);
1293 bytes
[0] = opx
->offset
;
1294 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1304 if (opx
->offset
< 0 || opx
->offset
> 255)
1305 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1306 "unsigned byte value exceeds bounds");
1307 if (opx
->segment
!= NO_SEG
) {
1309 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1310 opx
->segment
, opx
->wrt
);
1312 bytes
[0] = opx
->offset
;
1313 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1324 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1325 warn_overflow(2, data
);
1326 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1327 opx
->segment
, opx
->wrt
);
1335 if (opx
->type
& (BITS16
| BITS32
))
1336 size
= (opx
->type
& BITS16
) ? 2 : 4;
1338 size
= (bits
== 16) ? 2 : 4;
1340 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1341 warn_overflow(size
, data
);
1342 out(offset
, segment
, &data
, OUT_ADDRESS
, size
,
1343 opx
->segment
, opx
->wrt
);
1352 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1353 warn_overflow(4, data
);
1354 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1355 opx
->segment
, opx
->wrt
);
1364 size
= ins
->addr_size
>> 3;
1365 if (opx
->segment
== NO_SEG
&&
1367 warn_overflow(size
, data
);
1368 out(offset
, segment
, &data
, OUT_ADDRESS
, size
,
1369 opx
->segment
, opx
->wrt
);
1377 if (opx
->segment
!= segment
)
1378 errfunc(ERR_NONFATAL
,
1379 "short relative jump outside segment");
1380 data
= opx
->offset
- insn_end
;
1381 if (data
> 127 || data
< -128)
1382 errfunc(ERR_NONFATAL
, "short jump is out of range");
1384 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1392 data
= (int64_t)opx
->offset
;
1393 out(offset
, segment
, &data
, OUT_ADDRESS
, 8,
1394 opx
->segment
, opx
->wrt
);
1402 if (opx
->segment
!= segment
) {
1404 out(offset
, segment
, &data
,
1405 OUT_REL2ADR
, insn_end
- offset
,
1406 opx
->segment
, opx
->wrt
);
1408 data
= opx
->offset
- insn_end
;
1409 out(offset
, segment
, &data
,
1410 OUT_ADDRESS
, 2, NO_SEG
, NO_SEG
);
1419 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
1420 size
= (opx
->type
& BITS16
) ? 2 : 4;
1422 size
= (bits
== 16) ? 2 : 4;
1423 if (opx
->segment
!= segment
) {
1425 out(offset
, segment
, &data
,
1426 size
== 2 ? OUT_REL2ADR
: OUT_REL4ADR
,
1427 insn_end
- offset
, opx
->segment
, opx
->wrt
);
1429 data
= opx
->offset
- insn_end
;
1430 out(offset
, segment
, &data
,
1431 OUT_ADDRESS
, size
, NO_SEG
, NO_SEG
);
1440 if (opx
->segment
!= segment
) {
1442 out(offset
, segment
, &data
,
1443 OUT_REL4ADR
, insn_end
- offset
,
1444 opx
->segment
, opx
->wrt
);
1446 data
= opx
->offset
- insn_end
;
1447 out(offset
, segment
, &data
,
1448 OUT_ADDRESS
, 4, NO_SEG
, NO_SEG
);
1457 if (opx
->segment
== NO_SEG
)
1458 errfunc(ERR_NONFATAL
, "value referenced by FAR is not"
1461 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1462 outfmt
->segbase(1 + opx
->segment
),
1472 if (is_sbyte16(opx
)) {
1474 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1478 if (opx
->segment
== NO_SEG
&&
1480 warn_overflow(2, data
);
1481 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1482 opx
->segment
, opx
->wrt
);
1492 bytes
[0] = *codes
++;
1493 if (is_sbyte16(opx
))
1494 bytes
[0] |= 2; /* s-bit */
1495 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1504 if (is_sbyte32(opx
)) {
1506 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1510 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1511 opx
->segment
, opx
->wrt
);
1521 bytes
[0] = *codes
++;
1522 if (is_sbyte32(opx
))
1523 bytes
[0] |= 2; /* s-bit */
1524 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1540 (ins
->drexdst
<< 4) |
1541 (ins
->rex
& REX_OC
? 0x08 : 0) |
1542 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1544 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1550 opx
= &ins
->oprs
[c
>> 3];
1551 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1552 opx
= &ins
->oprs
[c
& 7];
1553 if (opx
->segment
!= NO_SEG
|| opx
->wrt
!= NO_SEG
) {
1554 errfunc(ERR_NONFATAL
,
1555 "non-absolute expression not permitted as argument %d",
1558 if (opx
->offset
& ~15) {
1559 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1560 "four-bit argument exceeds bounds");
1562 bytes
[0] |= opx
->offset
& 15;
1564 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1570 opx
= &ins
->oprs
[c
>> 4];
1571 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1573 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1579 opx
= &ins
->oprs
[c
];
1580 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1581 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1590 /* is_sbyte32() is right here, we have already warned */
1591 if (is_sbyte32(opx
)) {
1593 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1597 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1598 opx
->segment
, opx
->wrt
);
1609 if (ins
->vex_m
!= 1 || (ins
->rex
& (REX_W
|REX_X
|REX_B
))) {
1611 bytes
[1] = ins
->vex_m
| ((~ins
->rex
& 7) << 5);
1612 bytes
[2] = ((ins
->rex
& REX_W
) << (7-3)) |
1613 ((~ins
->drexdst
& 15)<< 3) | (ins
->vex_wlp
& 07);
1614 out(offset
, segment
, &bytes
, OUT_RAWDATA
, 3, NO_SEG
, NO_SEG
);
1618 bytes
[1] = ((~ins
->rex
& REX_R
) << (7-2)) |
1619 ((~ins
->drexdst
& 15) << 3) | (ins
->vex_wlp
& 07);
1620 out(offset
, segment
, &bytes
, OUT_RAWDATA
, 2, NO_SEG
, NO_SEG
);
1632 if (bits
== 32 && !has_prefix(ins
, PPS_ASIZE
, P_A16
)) {
1634 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1641 if (bits
!= 32 && !has_prefix(ins
, PPS_ASIZE
, P_A32
)) {
1643 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1665 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1674 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1689 *bytes
= *codes
++ ^ condval
[ins
->condition
];
1690 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1699 *bytes
= c
- 0332 + 0xF2;
1700 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1705 if (ins
->rex
& REX_R
) {
1707 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1710 ins
->rex
&= ~(REX_L
|REX_R
);
1721 if (ins
->oprs
[0].segment
!= NO_SEG
)
1722 errfunc(ERR_PANIC
, "non-constant BSS size in pass two");
1724 int64_t size
= ins
->oprs
[0].offset
;
1726 out(offset
, segment
, NULL
,
1727 OUT_RESERVE
, size
, NO_SEG
, NO_SEG
);
1737 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1743 bytes
[0] = c
- 0362 + 0xf2;
1744 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1754 *bytes
= c
- 0366 + 0x66;
1755 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1765 *bytes
= bits
== 16 ? 3 : 5;
1766 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1770 default: /* can't do it by 'case' statements */
1771 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1779 /* pick rfield from operand b */
1780 rflags
= regflag(&ins
->oprs
[c
& 7]);
1781 rfield
= nasm_regvals
[ins
->oprs
[c
& 7].basereg
];
1783 /* rfield is constant */
1789 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1790 ins
->addr_size
, rfield
, rflags
)) {
1791 errfunc(ERR_NONFATAL
, "invalid effective address");
1796 *p
++ = ea_data
.modrm
;
1797 if (ea_data
.sib_present
)
1800 /* DREX suffixes come between the SIB and the displacement */
1801 if (ins
->rex
& REX_D
) {
1803 (ins
->drexdst
<< 4) |
1804 (ins
->rex
& REX_OC
? 0x08 : 0) |
1805 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1810 out(offset
, segment
, bytes
, OUT_RAWDATA
, s
, NO_SEG
, NO_SEG
);
1813 * Make sure the address gets the right offset in case
1814 * the line breaks in the .lst file (BR 1197827)
1819 switch (ea_data
.bytes
) {
1823 if (ins
->oprs
[(c
>> 3) & 7].segment
!= NO_SEG
) {
1824 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1825 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1826 ins
->oprs
[(c
>> 3) & 7].segment
,
1827 ins
->oprs
[(c
>> 3) & 7].wrt
);
1829 *bytes
= ins
->oprs
[(c
>> 3) & 7].offset
;
1830 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1,
1838 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1839 warn_overflow(ea_data
.bytes
, data
);
1840 out(offset
, segment
, &data
,
1841 ea_data
.rip
? OUT_REL4ADR
: OUT_ADDRESS
,
1843 ins
->oprs
[(c
>> 3) & 7].segment
,
1844 ins
->oprs
[(c
>> 3) & 7].wrt
);
1850 errfunc(ERR_PANIC
, "internal instruction table corrupt"
1851 ": instruction code 0x%02X given", c
);
1857 static int32_t regflag(const operand
* o
)
1859 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1860 errfunc(ERR_PANIC
, "invalid operand passed to regflag()");
1862 return nasm_reg_flags
[o
->basereg
];
1865 static int32_t regval(const operand
* o
)
1867 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1868 errfunc(ERR_PANIC
, "invalid operand passed to regval()");
1870 return nasm_regvals
[o
->basereg
];
1873 static int op_rexflags(const operand
* o
, int mask
)
1878 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1879 errfunc(ERR_PANIC
, "invalid operand passed to op_rexflags()");
1882 flags
= nasm_reg_flags
[o
->basereg
];
1883 val
= nasm_regvals
[o
->basereg
];
1885 return rexflags(val
, flags
, mask
);
1888 static int rexflags(int val
, int32_t flags
, int mask
)
1893 rex
|= REX_B
|REX_X
|REX_R
;
1896 if (!(REG_HIGH
& ~flags
)) /* AH, CH, DH, BH */
1898 else if (!(REG8
& ~flags
) && val
>= 4) /* SPL, BPL, SIL, DIL */
1904 static int matches(const struct itemplate
*itemp
, insn
* instruction
, int bits
)
1906 int i
, size
[MAX_OPERANDS
], asize
, oprs
, ret
;
1913 if (itemp
->opcode
!= instruction
->opcode
)
1917 * Count the operands
1919 if (itemp
->operands
!= instruction
->operands
)
1923 * Check that no spurious colons or TOs are present
1925 for (i
= 0; i
< itemp
->operands
; i
++)
1926 if (instruction
->oprs
[i
].type
& ~itemp
->opd
[i
] & (COLON
| TO
))
1930 * Process size flags
1932 if (itemp
->flags
& IF_ARMASK
) {
1933 memset(size
, 0, sizeof size
);
1935 i
= ((itemp
->flags
& IF_ARMASK
) >> IF_ARSHFT
) - 1;
1937 switch (itemp
->flags
& IF_SMASK
) {
1974 switch (itemp
->flags
& IF_SMASK
) {
2009 for (i
= 0; i
< MAX_OPERANDS
; i
++)
2014 * Check that the operand flags all match up
2016 for (i
= 0; i
< itemp
->operands
; i
++) {
2017 int32_t type
= instruction
->oprs
[i
].type
;
2018 if (!(type
& SIZE_MASK
))
2021 if (itemp
->opd
[i
] & SAME_AS
) {
2022 int j
= itemp
->opd
[i
] & ~SAME_AS
;
2023 if (type
!= instruction
->oprs
[j
].type
||
2024 instruction
->oprs
[i
].basereg
!= instruction
->oprs
[j
].basereg
)
2026 } else if (itemp
->opd
[i
] & ~type
||
2027 ((itemp
->opd
[i
] & SIZE_MASK
) &&
2028 ((itemp
->opd
[i
] ^ type
) & SIZE_MASK
))) {
2029 if ((itemp
->opd
[i
] & ~type
& ~SIZE_MASK
) ||
2038 * Check operand sizes
2040 if (itemp
->flags
& (IF_SM
| IF_SM2
)) {
2041 oprs
= (itemp
->flags
& IF_SM2
? 2 : itemp
->operands
);
2043 for (i
= 0; i
< oprs
; i
++) {
2044 if ((asize
= itemp
->opd
[i
] & SIZE_MASK
) != 0) {
2046 for (j
= 0; j
< oprs
; j
++)
2052 oprs
= itemp
->operands
;
2055 for (i
= 0; i
< itemp
->operands
; i
++) {
2056 if (!(itemp
->opd
[i
] & SIZE_MASK
) &&
2057 (instruction
->oprs
[i
].type
& SIZE_MASK
& ~size
[i
]))
2062 * Check template is okay at the set cpu level
2064 if (((itemp
->flags
& IF_PLEVEL
) > cpu
))
2068 * Check if instruction is available in long mode
2070 if ((itemp
->flags
& IF_NOLONG
) && (bits
== 64))
2074 * Check if special handling needed for Jumps
2076 if ((uint8_t)(itemp
->code
[0]) >= 0370)
2082 static ea
*process_ea(operand
* input
, ea
* output
, int bits
,
2083 int addrbits
, int rfield
, int32_t rflags
)
2085 bool forw_ref
= !!(input
->opflags
& OPFLAG_FORWARD
);
2087 output
->rip
= false;
2089 /* REX flags for the rfield operand */
2090 output
->rex
|= rexflags(rfield
, rflags
, REX_R
|REX_P
|REX_W
|REX_H
);
2092 if (!(REGISTER
& ~input
->type
)) { /* register direct */
2096 if (input
->basereg
< EXPR_REG_START
/* Verify as Register */
2097 || input
->basereg
>= REG_ENUM_LIMIT
)
2100 i
= nasm_regvals
[input
->basereg
];
2103 return NULL
; /* Invalid EA register */
2105 output
->rex
|= op_rexflags(input
, REX_B
|REX_P
|REX_W
|REX_H
);
2107 output
->sib_present
= false; /* no SIB necessary */
2108 output
->bytes
= 0; /* no offset necessary either */
2109 output
->modrm
= 0xC0 | ((rfield
& 7) << 3) | (i
& 7);
2110 } else { /* it's a memory reference */
2111 if (input
->basereg
== -1
2112 && (input
->indexreg
== -1 || input
->scale
== 0)) {
2113 /* it's a pure offset */
2114 if (bits
== 64 && (~input
->type
& IP_REL
)) {
2115 int scale
, index
, base
;
2116 output
->sib_present
= true;
2120 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
2122 output
->modrm
= 4 | ((rfield
& 7) << 3);
2123 output
->rip
= false;
2125 output
->sib_present
= false;
2126 output
->bytes
= (addrbits
!= 16 ? 4 : 2);
2127 output
->modrm
= (addrbits
!= 16 ? 5 : 6) | ((rfield
& 7) << 3);
2128 output
->rip
= bits
== 64;
2130 } else { /* it's an indirection */
2131 int i
= input
->indexreg
, b
= input
->basereg
, s
= input
->scale
;
2132 int32_t o
= input
->offset
, seg
= input
->segment
;
2133 int hb
= input
->hintbase
, ht
= input
->hinttype
;
2136 int32_t ix
, bx
; /* register flags */
2139 i
= -1; /* make this easy, at least */
2141 if (i
>= EXPR_REG_START
&& i
< REG_ENUM_LIMIT
) {
2142 it
= nasm_regvals
[i
];
2143 ix
= nasm_reg_flags
[i
];
2149 if (b
>= EXPR_REG_START
&& b
< REG_ENUM_LIMIT
) {
2150 bt
= nasm_regvals
[b
];
2151 bx
= nasm_reg_flags
[b
];
2157 /* check for a 32/64-bit memory reference... */
2158 if ((ix
|bx
) & (BITS32
|BITS64
)) {
2159 /* it must be a 32/64-bit memory reference. Firstly we have
2160 * to check that all registers involved are type E/Rxx. */
2161 int32_t sok
= BITS32
|BITS64
;
2164 if (!(REG64
& ~ix
) || !(REG32
& ~ix
))
2172 return NULL
; /* Invalid register */
2173 if (~sok
& bx
& SIZE_MASK
)
2174 return NULL
; /* Invalid size */
2178 /* While we're here, ensure the user didn't specify
2180 if (input
->disp_size
== 16 || input
->disp_size
== 64)
2183 if (addrbits
== 16 ||
2184 (addrbits
== 32 && !(sok
& BITS32
)) ||
2185 (addrbits
== 64 && !(sok
& BITS64
)))
2188 /* now reorganize base/index */
2189 if (s
== 1 && bt
!= it
&& bt
!= -1 && it
!= -1 &&
2190 ((hb
== b
&& ht
== EAH_NOTBASE
)
2191 || (hb
== i
&& ht
== EAH_MAKEBASE
))) {
2192 /* swap if hints say so */
2193 t
= bt
, bt
= it
, it
= t
;
2194 t
= bx
, bx
= ix
, ix
= t
;
2196 if (bt
== it
) /* convert EAX+2*EAX to 3*EAX */
2197 bt
= -1, bx
= 0, s
++;
2198 if (bt
== -1 && s
== 1 && !(hb
== it
&& ht
== EAH_NOTBASE
)) {
2199 /* make single reg base, unless hint */
2200 bt
= it
, bx
= ix
, it
= -1, ix
= 0;
2202 if (((s
== 2 && it
!= REG_NUM_ESP
2203 && !(input
->eaflags
& EAF_TIMESTWO
)) || s
== 3
2204 || s
== 5 || s
== 9) && bt
== -1)
2205 bt
= it
, bx
= ix
, s
--; /* convert 3*EAX to EAX+2*EAX */
2206 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
2207 && (input
->eaflags
& EAF_TIMESTWO
))
2208 it
= bt
, ix
= bx
, bt
= -1, bx
= 0, s
= 1;
2209 /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */
2210 if (s
== 1 && it
== REG_NUM_ESP
) {
2211 /* swap ESP into base if scale is 1 */
2212 t
= it
, it
= bt
, bt
= t
;
2213 t
= ix
, ix
= bx
, bx
= t
;
2215 if (it
== REG_NUM_ESP
2216 || (s
!= 1 && s
!= 2 && s
!= 4 && s
!= 8 && it
!= -1))
2217 return NULL
; /* wrong, for various reasons */
2219 output
->rex
|= rexflags(it
, ix
, REX_X
);
2220 output
->rex
|= rexflags(bt
, bx
, REX_B
);
2222 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
) {
2231 if (rm
!= REG_NUM_EBP
&& o
== 0 &&
2232 seg
== NO_SEG
&& !forw_ref
&&
2234 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2236 else if (input
->eaflags
& EAF_BYTEOFFS
||
2237 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2239 && !(input
->eaflags
& EAF_WORDOFFS
)))
2245 output
->sib_present
= false;
2246 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
2247 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
2250 int mod
, scale
, index
, base
;
2270 default: /* then what the smeg is it? */
2271 return NULL
; /* panic */
2279 if (base
!= REG_NUM_EBP
&& o
== 0 &&
2280 seg
== NO_SEG
&& !forw_ref
&&
2282 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2284 else if (input
->eaflags
& EAF_BYTEOFFS
||
2285 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2287 && !(input
->eaflags
& EAF_WORDOFFS
)))
2293 output
->sib_present
= true;
2294 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
2295 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | 4;
2296 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
2298 } else { /* it's 16-bit */
2301 /* check for 64-bit long mode */
2305 /* check all registers are BX, BP, SI or DI */
2306 if ((b
!= -1 && b
!= R_BP
&& b
!= R_BX
&& b
!= R_SI
2307 && b
!= R_DI
) || (i
!= -1 && i
!= R_BP
&& i
!= R_BX
2308 && i
!= R_SI
&& i
!= R_DI
))
2311 /* ensure the user didn't specify DWORD/QWORD */
2312 if (input
->disp_size
== 32 || input
->disp_size
== 64)
2315 if (s
!= 1 && i
!= -1)
2316 return NULL
; /* no can do, in 16-bit EA */
2317 if (b
== -1 && i
!= -1) {
2322 if ((b
== R_SI
|| b
== R_DI
) && i
!= -1) {
2327 /* have BX/BP as base, SI/DI index */
2329 return NULL
; /* shouldn't ever happen, in theory */
2330 if (i
!= -1 && b
!= -1 &&
2331 (i
== R_BP
|| i
== R_BX
|| b
== R_SI
|| b
== R_DI
))
2332 return NULL
; /* invalid combinations */
2333 if (b
== -1) /* pure offset: handled above */
2334 return NULL
; /* so if it gets to here, panic! */
2338 switch (i
* 256 + b
) {
2339 case R_SI
* 256 + R_BX
:
2342 case R_DI
* 256 + R_BX
:
2345 case R_SI
* 256 + R_BP
:
2348 case R_DI
* 256 + R_BP
:
2366 if (rm
== -1) /* can't happen, in theory */
2367 return NULL
; /* so panic if it does */
2369 if (o
== 0 && seg
== NO_SEG
&& !forw_ref
&& rm
!= 6 &&
2370 !(input
->eaflags
& (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2372 else if (input
->eaflags
& EAF_BYTEOFFS
||
2373 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2375 && !(input
->eaflags
& EAF_WORDOFFS
)))
2380 output
->sib_present
= false; /* no SIB - it's 16-bit */
2381 output
->bytes
= mod
; /* bytes of offset needed */
2382 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
2387 output
->size
= 1 + output
->sib_present
+ output
->bytes
;
2391 static void add_asp(insn
*ins
, int addrbits
)
2396 valid
= (addrbits
== 64) ? 64|32 : 32|16;
2398 switch (ins
->prefixes
[PPS_ASIZE
]) {
2409 valid
&= (addrbits
== 32) ? 16 : 32;
2415 for (j
= 0; j
< ins
->operands
; j
++) {
2416 if (!(MEMORY
& ~ins
->oprs
[j
].type
)) {
2419 /* Verify as Register */
2420 if (ins
->oprs
[j
].indexreg
< EXPR_REG_START
2421 || ins
->oprs
[j
].indexreg
>= REG_ENUM_LIMIT
)
2424 i
= nasm_reg_flags
[ins
->oprs
[j
].indexreg
];
2426 /* Verify as Register */
2427 if (ins
->oprs
[j
].basereg
< EXPR_REG_START
2428 || ins
->oprs
[j
].basereg
>= REG_ENUM_LIMIT
)
2431 b
= nasm_reg_flags
[ins
->oprs
[j
].basereg
];
2433 if (ins
->oprs
[j
].scale
== 0)
2437 int ds
= ins
->oprs
[j
].disp_size
;
2438 if ((addrbits
!= 64 && ds
> 8) ||
2439 (addrbits
== 64 && ds
== 16))
2459 if (valid
& addrbits
) {
2460 ins
->addr_size
= addrbits
;
2461 } else if (valid
& ((addrbits
== 32) ? 16 : 32)) {
2462 /* Add an address size prefix */
2463 enum prefixes pref
= (addrbits
== 32) ? P_A16
: P_A32
;
2464 ins
->prefixes
[PPS_ASIZE
] = pref
;
2465 ins
->addr_size
= (addrbits
== 32) ? 16 : 32;
2468 errfunc(ERR_NONFATAL
, "impossible combination of address sizes");
2469 ins
->addr_size
= addrbits
; /* Error recovery */
2472 defdisp
= ins
->addr_size
== 16 ? 16 : 32;
2474 for (j
= 0; j
< ins
->operands
; j
++) {
2475 if (!(MEM_OFFS
& ~ins
->oprs
[j
].type
) &&
2476 (ins
->oprs
[j
].disp_size
? ins
->oprs
[j
].disp_size
: defdisp
)
2477 != ins
->addr_size
) {
2478 /* mem_offs sizes must match the address size; if not,
2479 strip the MEM_OFFS bit and match only EA instructions */
2480 ins
->oprs
[j
].type
&= ~(MEM_OFFS
& ~MEMORY
);