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 * \274..\277 - a signed byte immediate operand, from operand 0..3,
74 * which is to be extended to the operand size.
75 * \310 - indicates fixed 16-bit address size, i.e. optional 0x67.
76 * \311 - indicates fixed 32-bit address size, i.e. optional 0x67.
77 * \312 - (disassembler only) marker on LOOP, LOOPxx instructions.
78 * \313 - indicates fixed 64-bit address size, 0x67 invalid.
79 * \314 - (disassembler only) invalid with REX.B
80 * \315 - (disassembler only) invalid with REX.X
81 * \316 - (disassembler only) invalid with REX.R
82 * \317 - (disassembler only) invalid with REX.W
83 * \320 - indicates fixed 16-bit operand size, i.e. optional 0x66.
84 * \321 - indicates fixed 32-bit operand size, i.e. optional 0x66.
85 * \322 - indicates that this instruction is only valid when the
86 * operand size is the default (instruction to disassembler,
87 * generates no code in the assembler)
88 * \323 - indicates fixed 64-bit operand size, REX on extensions only.
89 * \324 - indicates 64-bit operand size requiring REX prefix.
90 * \330 - a literal byte follows in the code stream, to be added
91 * to the condition code value of the instruction.
92 * \331 - instruction not valid with REP prefix. Hint for
93 * disassembler only; for SSE instructions.
94 * \332 - REP prefix (0xF2 byte) used as opcode extension.
95 * \333 - REP prefix (0xF3 byte) used as opcode extension.
96 * \334 - LOCK prefix used instead of REX.R
97 * \335 - disassemble a rep (0xF3 byte) prefix as repe not rep.
98 * \336 - force a REP(E) prefix (0xF2) even if not specified.
99 * \337 - force a REPNE prefix (0xF3) even if not specified.
100 * \336-\337 are still listed as prefixes in the disassembler.
101 * \340 - reserve <operand 0> bytes of uninitialized storage.
102 * Operand 0 had better be a segmentless constant.
103 * \360 - no SSE prefix (== \364\331)
104 * \361 - 66 SSE prefix (== \366\331)
105 * \362 - F2 SSE prefix (== \364\332)
106 * \363 - F3 SSE prefix (== \364\333)
107 * \364 - operand-size prefix (0x66) not permitted
108 * \365 - address-size prefix (0x67) not permitted
109 * \366 - operand-size prefix (0x66) used as opcode extension
110 * \367 - address-size prefix (0x67) used as opcode extension
111 * \370,\371,\372 - match only if operand 0 meets byte jump criteria.
112 * 370 is used for Jcc, 371 is used for JMP.
113 * \373 - assemble 0x03 if bits==16, 0x05 if bits==32;
114 * used for conditional jump over longer jump
117 #include "compiler.h"
121 #include <inttypes.h>
125 #include "assemble.h"
129 /* Initialized to zero by the C standard */
130 static const uint8_t const_zero_buf
[256];
133 int sib_present
; /* is a SIB byte necessary? */
134 int bytes
; /* # of bytes of offset needed */
135 int size
; /* lazy - this is sib+bytes+1 */
136 uint8_t modrm
, sib
, rex
, rip
; /* the bytes themselves */
139 static uint32_t cpu
; /* cpu level received from nasm.c */
140 static efunc errfunc
;
141 static struct ofmt
*outfmt
;
142 static ListGen
*list
;
144 static int64_t calcsize(int32_t, int64_t, int, insn
*, const uint8_t *);
145 static void gencode(int32_t segment
, int64_t offset
, int bits
,
146 insn
* ins
, const struct itemplate
*temp
,
148 static int matches(const struct itemplate
*, insn
*, int bits
);
149 static int32_t regflag(const operand
*);
150 static int32_t regval(const operand
*);
151 static int rexflags(int, int32_t, int);
152 static int op_rexflags(const operand
*, int);
153 static ea
*process_ea(operand
*, ea
*, int, int, int, int32_t);
154 static void add_asp(insn
*, int);
156 static int has_prefix(insn
* ins
, enum prefix_pos pos
, enum prefixes prefix
)
158 return ins
->prefixes
[pos
] == prefix
;
161 static void assert_no_prefix(insn
* ins
, enum prefix_pos pos
)
163 if (ins
->prefixes
[pos
])
164 errfunc(ERR_NONFATAL
, "invalid %s prefix",
165 prefix_name(ins
->prefixes
[pos
]));
168 static const char *size_name(int size
)
190 static void warn_overflow(int size
, const struct operand
*o
)
192 if (size
< 8 && o
->wrt
== NO_SEG
&& o
->segment
== NO_SEG
) {
193 int64_t lim
= ((int64_t)1 << (size
*8))-1;
194 int64_t data
= o
->offset
;
196 if (data
< ~lim
|| data
> lim
)
197 errfunc(ERR_WARNING
| ERR_PASS2
| ERR_WARN_NOV
,
198 "%s data exceeds bounds", size_name(size
));
202 * This routine wrappers the real output format's output routine,
203 * in order to pass a copy of the data off to the listing file
204 * generator at the same time.
206 static void out(int64_t offset
, int32_t segto
, const void *data
,
207 enum out_type type
, uint64_t size
,
208 int32_t segment
, int32_t wrt
)
210 static int32_t lineno
= 0; /* static!!! */
211 static char *lnfname
= NULL
;
214 if (type
== OUT_ADDRESS
&& segment
== NO_SEG
&& wrt
== NO_SEG
) {
216 * This is a non-relocated address, and we're going to
217 * convert it into RAWDATA format.
222 errfunc(ERR_PANIC
, "OUT_ADDRESS with size > 8");
226 WRITEADDR(q
, *(int64_t *)data
, size
);
231 list
->output(offset
, data
, type
, size
);
234 * this call to src_get determines when we call the
235 * debug-format-specific "linenum" function
236 * it updates lineno and lnfname to the current values
237 * returning 0 if "same as last time", -2 if lnfname
238 * changed, and the amount by which lineno changed,
239 * if it did. thus, these variables must be static
242 if (src_get(&lineno
, &lnfname
)) {
243 outfmt
->current_dfmt
->linenum(lnfname
, lineno
, segto
);
246 outfmt
->output(segto
, data
, type
, size
, segment
, wrt
);
249 static bool jmp_match(int32_t segment
, int64_t offset
, int bits
,
250 insn
* ins
, const uint8_t *code
)
255 if ((c
!= 0370 && c
!= 0371) || (ins
->oprs
[0].type
& STRICT
))
259 if (optimizing
< 0 && c
== 0371)
262 isize
= calcsize(segment
, offset
, bits
, ins
, code
);
263 if (ins
->oprs
[0].segment
!= segment
)
266 isize
= ins
->oprs
[0].offset
- offset
- isize
; /* isize is delta */
267 return (isize
>= -128 && isize
<= 127); /* is it byte size? */
270 int64_t assemble(int32_t segment
, int64_t offset
, int bits
, uint32_t cp
,
271 insn
* instruction
, struct ofmt
*output
, efunc error
,
274 const struct itemplate
*temp
;
279 int64_t start
= offset
;
280 int64_t wsize
= 0; /* size for DB etc. */
282 errfunc
= error
; /* to pass to other functions */
284 outfmt
= output
; /* likewise */
285 list
= listgen
; /* and again */
287 switch (instruction
->opcode
) {
317 int32_t t
= instruction
->times
;
320 "instruction->times < 0 (%ld) in assemble()", t
);
322 while (t
--) { /* repeat TIMES times */
323 for (e
= instruction
->eops
; e
; e
= e
->next
) {
324 if (e
->type
== EOT_DB_NUMBER
) {
326 if (e
->segment
!= NO_SEG
)
327 errfunc(ERR_NONFATAL
,
328 "one-byte relocation attempted");
330 uint8_t out_byte
= e
->offset
;
331 out(offset
, segment
, &out_byte
,
332 OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
334 } else if (wsize
> 8) {
335 errfunc(ERR_NONFATAL
,
336 "integer supplied to a DT, DO or DY"
339 out(offset
, segment
, &e
->offset
,
340 OUT_ADDRESS
, wsize
, e
->segment
, e
->wrt
);
342 } else if (e
->type
== EOT_DB_STRING
||
343 e
->type
== EOT_DB_STRING_FREE
) {
346 out(offset
, segment
, e
->stringval
,
347 OUT_RAWDATA
, e
->stringlen
, NO_SEG
, NO_SEG
);
348 align
= e
->stringlen
% wsize
;
351 align
= wsize
- align
;
352 out(offset
, segment
, const_zero_buf
,
353 OUT_RAWDATA
, align
, NO_SEG
, NO_SEG
);
355 offset
+= e
->stringlen
+ align
;
358 if (t
> 0 && t
== instruction
->times
- 1) {
360 * Dummy call to list->output to give the offset to the
363 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
364 list
->uplevel(LIST_TIMES
);
367 if (instruction
->times
> 1)
368 list
->downlevel(LIST_TIMES
);
369 return offset
- start
;
372 if (instruction
->opcode
== I_INCBIN
) {
373 const char *fname
= instruction
->eops
->stringval
;
376 fp
= fopen(fname
, "rb");
378 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
380 } else if (fseek(fp
, 0L, SEEK_END
) < 0) {
381 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
384 static char buf
[4096];
385 size_t t
= instruction
->times
;
390 if (instruction
->eops
->next
) {
391 base
= instruction
->eops
->next
->offset
;
393 if (instruction
->eops
->next
->next
&&
394 len
> (size_t)instruction
->eops
->next
->next
->offset
)
395 len
= (size_t)instruction
->eops
->next
->next
->offset
;
398 * Dummy call to list->output to give the offset to the
401 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
402 list
->uplevel(LIST_INCBIN
);
406 fseek(fp
, base
, SEEK_SET
);
410 fread(buf
, 1, (l
> (int32_t) sizeof(buf
) ? (int32_t) sizeof(buf
) : l
),
414 * This shouldn't happen unless the file
415 * actually changes while we are reading
419 "`incbin': unexpected EOF while"
420 " reading file `%s'", fname
);
421 t
= 0; /* Try to exit cleanly */
424 out(offset
, segment
, buf
, OUT_RAWDATA
, m
,
429 list
->downlevel(LIST_INCBIN
);
430 if (instruction
->times
> 1) {
432 * Dummy call to list->output to give the offset to the
435 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
436 list
->uplevel(LIST_TIMES
);
437 list
->downlevel(LIST_TIMES
);
440 return instruction
->times
* len
;
442 return 0; /* if we're here, there's an error */
445 /* Check to see if we need an address-size prefix */
446 add_asp(instruction
, bits
);
450 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++){
451 int m
= matches(temp
, instruction
, bits
);
453 (m
== 99 && jmp_match(segment
, offset
, bits
,
454 instruction
, temp
->code
))) {
456 int64_t insn_size
= calcsize(segment
, offset
, bits
,
457 instruction
, temp
->code
);
458 itimes
= instruction
->times
;
459 if (insn_size
< 0) /* shouldn't be, on pass two */
460 error(ERR_PANIC
, "errors made it through from pass one");
463 for (j
= 0; j
< MAXPREFIX
; j
++) {
465 switch (instruction
->prefixes
[j
]) {
480 error(ERR_WARNING
| ERR_PASS2
,
481 "cs segment base generated, but will be ignored in 64-bit mode");
487 error(ERR_WARNING
| ERR_PASS2
,
488 "ds segment base generated, but will be ignored in 64-bit mode");
494 error(ERR_WARNING
| ERR_PASS2
,
495 "es segment base generated, but will be ignored in 64-bit mode");
507 error(ERR_WARNING
| ERR_PASS2
,
508 "ss segment base generated, but will be ignored in 64-bit mode");
515 "segr6 and segr7 cannot be used as prefixes");
520 "16-bit addressing is not supported "
522 } else if (bits
!= 16)
532 "64-bit addressing is only supported "
556 error(ERR_PANIC
, "invalid instruction prefix");
559 out(offset
, segment
, &c
, OUT_RAWDATA
, 1,
564 insn_end
= offset
+ insn_size
;
565 gencode(segment
, offset
, bits
, instruction
,
568 if (itimes
> 0 && itimes
== instruction
->times
- 1) {
570 * Dummy call to list->output to give the offset to the
573 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
574 list
->uplevel(LIST_TIMES
);
577 if (instruction
->times
> 1)
578 list
->downlevel(LIST_TIMES
);
579 return offset
- start
;
580 } else if (m
> 0 && m
> size_prob
) {
585 if (temp
->opcode
== -1) { /* didn't match any instruction */
588 error(ERR_NONFATAL
, "operation size not specified");
591 error(ERR_NONFATAL
, "mismatch in operand sizes");
594 error(ERR_NONFATAL
, "no instruction for this cpu level");
597 error(ERR_NONFATAL
, "instruction not supported in 64-bit mode");
601 "invalid combination of opcode and operands");
608 int64_t insn_size(int32_t segment
, int64_t offset
, int bits
, uint32_t cp
,
609 insn
* instruction
, efunc error
)
611 const struct itemplate
*temp
;
613 errfunc
= error
; /* to pass to other functions */
616 if (instruction
->opcode
== -1)
619 if (instruction
->opcode
== I_DB
|| instruction
->opcode
== I_DW
||
620 instruction
->opcode
== I_DD
|| instruction
->opcode
== I_DQ
||
621 instruction
->opcode
== I_DT
|| instruction
->opcode
== I_DO
||
622 instruction
->opcode
== I_DY
) {
624 int32_t isize
, osize
, wsize
= 0; /* placate gcc */
627 switch (instruction
->opcode
) {
653 for (e
= instruction
->eops
; e
; e
= e
->next
) {
657 if (e
->type
== EOT_DB_NUMBER
)
659 else if (e
->type
== EOT_DB_STRING
||
660 e
->type
== EOT_DB_STRING_FREE
)
661 osize
= e
->stringlen
;
663 align
= (-osize
) % wsize
;
666 isize
+= osize
+ align
;
668 return isize
* instruction
->times
;
671 if (instruction
->opcode
== I_INCBIN
) {
672 const char *fname
= instruction
->eops
->stringval
;
676 fp
= fopen(fname
, "rb");
678 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
680 else if (fseek(fp
, 0L, SEEK_END
) < 0)
681 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
686 if (instruction
->eops
->next
) {
687 len
-= instruction
->eops
->next
->offset
;
688 if (instruction
->eops
->next
->next
&&
689 len
> (size_t)instruction
->eops
->next
->next
->offset
) {
690 len
= (size_t)instruction
->eops
->next
->next
->offset
;
693 return instruction
->times
* len
;
695 return 0; /* if we're here, there's an error */
698 /* Check to see if we need an address-size prefix */
699 add_asp(instruction
, bits
);
701 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++) {
702 int m
= matches(temp
, instruction
, bits
);
704 (m
== 99 && jmp_match(segment
, offset
, bits
,
705 instruction
, temp
->code
))) {
706 /* we've matched an instruction. */
708 const uint8_t *codes
= temp
->code
;
711 isize
= calcsize(segment
, offset
, bits
, instruction
, codes
);
714 for (j
= 0; j
< MAXPREFIX
; j
++) {
715 switch (instruction
->prefixes
[j
]) {
741 return isize
* instruction
->times
;
744 return -1; /* didn't match any instruction */
747 static bool possible_sbyte(operand
*o
)
749 return !(o
->opflags
& OPFLAG_FORWARD
) &&
750 optimizing
>= 0 && !(o
->type
& STRICT
);
753 /* check that opn[op] is a signed byte of size 16 or 32 */
754 static bool is_sbyte16(operand
*o
)
758 if (!possible_sbyte(o
))
762 return v
>= -128 && v
<= 127;
765 static bool is_sbyte32(operand
*o
)
769 if (!possible_sbyte(o
))
773 return v
>= -128 && v
<= 127;
776 /* check that opn[op] is a signed byte of size 32; warn if this is not
777 the original value when extended to 64 bits */
778 static bool is_sbyte64(operand
*o
)
783 if (!(o
->wrt
== NO_SEG
&& o
->segment
== NO_SEG
))
784 return false; /* Not a pure immediate */
790 errfunc(ERR_WARNING
| ERR_PASS2
| ERR_WARN_NOV
,
791 "signed dword immediate exceeds bounds");
793 /* dead in the water on forward reference or External */
794 if (!possible_sbyte(o
))
798 return v
>= -128 && v
<= 127;
800 static int64_t calcsize(int32_t segment
, int64_t offset
, int bits
,
801 insn
* ins
, const uint8_t *codes
)
808 ins
->rex
= 0; /* Ensure REX is reset */
810 if (ins
->prefixes
[PPS_OSIZE
] == P_O64
)
813 (void)segment
; /* Don't warn that this parameter is unused */
814 (void)offset
; /* Don't warn that this parameter is unused */
818 opx
= &ins
->oprs
[c
& 3];
823 codes
+= c
, length
+= c
;
836 op_rexflags(opx
, REX_B
|REX_H
|REX_P
|REX_W
);
867 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
868 length
+= (opx
->type
& BITS16
) ? 2 : 4;
870 length
+= (bits
== 16) ? 2 : 4;
882 length
+= ins
->addr_size
>> 3;
894 length
+= 8; /* MOV reg64/imm */
906 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
907 length
+= (opx
->type
& BITS16
) ? 2 : 4;
909 length
+= (bits
== 16) ? 2 : 4;
927 length
+= is_sbyte16(opx
) ? 1 : 2;
940 length
+= is_sbyte32(opx
) ? 1 : 4;
955 ins
->drexdst
= regval(opx
);
962 ins
->rex
|= REX_D
|REX_OC
;
963 ins
->drexdst
= regval(opx
);
977 length
+= is_sbyte64(opx
) ? 1 : 4;
984 ins
->drexdst
= regval(opx
);
985 ins
->vex_m
= *codes
++;
986 ins
->vex_wlp
= *codes
++;
991 ins
->vex_m
= *codes
++;
992 ins
->vex_wlp
= *codes
++;
1008 length
+= (bits
!= 16) && !has_prefix(ins
, PPS_ASIZE
, P_A16
);
1011 length
+= (bits
!= 32) && !has_prefix(ins
, PPS_ASIZE
, P_A32
);
1016 if (bits
!= 64 || has_prefix(ins
, PPS_ASIZE
, P_A16
) ||
1017 has_prefix(ins
, PPS_ASIZE
, P_A32
))
1026 length
+= (bits
!= 16);
1029 length
+= (bits
== 16);
1054 if (!ins
->prefixes
[PPS_LREP
])
1055 ins
->prefixes
[PPS_LREP
] = P_REP
;
1058 if (!ins
->prefixes
[PPS_LREP
])
1059 ins
->prefixes
[PPS_LREP
] = P_REPNE
;
1062 if (ins
->oprs
[0].segment
!= NO_SEG
)
1063 errfunc(ERR_NONFATAL
, "attempt to reserve non-constant"
1064 " quantity of BSS space");
1066 length
+= ins
->oprs
[0].offset
;
1089 default: /* can't do it by 'case' statements */
1090 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1094 ea_data
.rex
= 0; /* Ensure ea.REX is initially 0 */
1097 /* pick rfield from operand b */
1098 rflags
= regflag(&ins
->oprs
[c
& 7]);
1099 rfield
= nasm_regvals
[ins
->oprs
[c
& 7].basereg
];
1106 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1107 ins
->addr_size
, rfield
, rflags
)) {
1108 errfunc(ERR_NONFATAL
, "invalid effective address");
1111 ins
->rex
|= ea_data
.rex
;
1112 length
+= ea_data
.size
;
1115 errfunc(ERR_PANIC
, "internal instruction table corrupt"
1116 ": instruction code 0x%02X given", c
);
1121 ins
->rex
&= rex_mask
;
1123 if (ins
->rex
& REX_V
) {
1124 int bad32
= REX_R
|REX_W
|REX_X
|REX_B
;
1126 if (ins
->rex
& REX_H
) {
1127 errfunc(ERR_NONFATAL
, "cannot use high register in vex instruction");
1130 switch (ins
->vex_wlp
& 030) {
1144 if (bits
!= 64 && ((ins
->rex
& bad32
) || ins
->drexdst
> 7)) {
1145 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1148 if (ins
->vex_m
!= 1 || (ins
->rex
& (REX_W
|REX_R
|REX_B
)))
1152 } else if (ins
->rex
& REX_D
) {
1153 if (ins
->rex
& REX_H
) {
1154 errfunc(ERR_NONFATAL
, "cannot use high register in drex instruction");
1157 if (bits
!= 64 && ((ins
->rex
& (REX_R
|REX_W
|REX_X
|REX_B
)) ||
1158 ins
->drexdst
> 7)) {
1159 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1163 } else if (ins
->rex
& REX_REAL
) {
1164 if (ins
->rex
& REX_H
) {
1165 errfunc(ERR_NONFATAL
, "cannot use high register in rex instruction");
1167 } else if (bits
== 64) {
1169 } else if ((ins
->rex
& REX_L
) &&
1170 !(ins
->rex
& (REX_P
|REX_W
|REX_X
|REX_B
)) &&
1173 assert_no_prefix(ins
, PPS_LREP
);
1176 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1184 #define EMIT_REX() \
1185 if (!(ins->rex & (REX_D|REX_V)) && (ins->rex & REX_REAL) && (bits == 64)) { \
1186 ins->rex = (ins->rex & REX_REAL)|REX_P; \
1187 out(offset, segment, &ins->rex, OUT_RAWDATA, 1, NO_SEG, NO_SEG); \
1192 static void gencode(int32_t segment
, int64_t offset
, int bits
,
1193 insn
* ins
, const struct itemplate
*temp
,
1196 static char condval
[] = { /* conditional opcodes */
1197 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
1198 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
1199 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
1205 struct operand
*opx
;
1206 const uint8_t *codes
= temp
->code
;
1210 opx
= &ins
->oprs
[c
& 3];
1216 out(offset
, segment
, codes
, OUT_RAWDATA
, c
, NO_SEG
, NO_SEG
);
1223 switch (ins
->oprs
[0].basereg
) {
1225 bytes
[0] = 0x0E + (c
== 0x04 ? 1 : 0);
1228 bytes
[0] = 0x1E + (c
== 0x04 ? 1 : 0);
1231 bytes
[0] = 0x06 + (c
== 0x04 ? 1 : 0);
1234 bytes
[0] = 0x16 + (c
== 0x04 ? 1 : 0);
1238 "bizarre 8086 segment register received");
1240 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1246 switch (ins
->oprs
[0].basereg
) {
1248 bytes
[0] = 0xA0 + (c
== 0x05 ? 1 : 0);
1251 bytes
[0] = 0xA8 + (c
== 0x05 ? 1 : 0);
1255 "bizarre 386 segment register received");
1257 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1266 bytes
[0] = *codes
++ + ((regval(opx
)) & 7);
1267 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1275 /* The test for BITS8 and SBYTE here is intended to avoid
1276 warning on optimizer actions due to SBYTE, while still
1277 warn on explicit BYTE directives. Also warn, obviously,
1278 if the optimizer isn't enabled. */
1279 if (((opx
->type
& BITS8
) ||
1280 !(opx
->type
& temp
->opd
[c
& 3] & BYTENESS
)) &&
1281 (opx
->offset
< -128 || opx
->offset
> 127)) {
1282 errfunc(ERR_WARNING
| ERR_PASS2
| ERR_WARN_NOV
,
1283 "signed byte value exceeds bounds");
1285 if (opx
->segment
!= NO_SEG
) {
1287 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1288 opx
->segment
, opx
->wrt
);
1290 bytes
[0] = opx
->offset
;
1291 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1301 if (opx
->offset
< -256 || opx
->offset
> 255) {
1302 errfunc(ERR_WARNING
| ERR_PASS2
| ERR_WARN_NOV
,
1303 "byte value exceeds bounds");
1305 if (opx
->segment
!= NO_SEG
) {
1307 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1308 opx
->segment
, opx
->wrt
);
1310 bytes
[0] = opx
->offset
;
1311 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1321 if (opx
->offset
< 0 || opx
->offset
> 255)
1322 errfunc(ERR_WARNING
| ERR_PASS2
| ERR_WARN_NOV
,
1323 "unsigned byte value exceeds bounds");
1324 if (opx
->segment
!= NO_SEG
) {
1326 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1327 opx
->segment
, opx
->wrt
);
1329 bytes
[0] = opx
->offset
;
1330 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1340 warn_overflow(2, opx
);
1342 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1343 opx
->segment
, opx
->wrt
);
1351 if (opx
->type
& (BITS16
| BITS32
))
1352 size
= (opx
->type
& BITS16
) ? 2 : 4;
1354 size
= (bits
== 16) ? 2 : 4;
1355 warn_overflow(size
, opx
);
1357 out(offset
, segment
, &data
, OUT_ADDRESS
, size
,
1358 opx
->segment
, opx
->wrt
);
1366 warn_overflow(4, opx
);
1368 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1369 opx
->segment
, opx
->wrt
);
1378 size
= ins
->addr_size
>> 3;
1379 warn_overflow(size
, opx
);
1380 out(offset
, segment
, &data
, OUT_ADDRESS
, size
,
1381 opx
->segment
, opx
->wrt
);
1389 if (opx
->segment
!= segment
)
1390 errfunc(ERR_NONFATAL
,
1391 "short relative jump outside segment");
1392 data
= opx
->offset
- insn_end
;
1393 if (data
> 127 || data
< -128)
1394 errfunc(ERR_NONFATAL
, "short jump is out of range");
1396 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1404 data
= (int64_t)opx
->offset
;
1405 out(offset
, segment
, &data
, OUT_ADDRESS
, 8,
1406 opx
->segment
, opx
->wrt
);
1414 if (opx
->segment
!= segment
) {
1416 out(offset
, segment
, &data
,
1417 OUT_REL2ADR
, insn_end
- offset
,
1418 opx
->segment
, opx
->wrt
);
1420 data
= opx
->offset
- insn_end
;
1421 out(offset
, segment
, &data
,
1422 OUT_ADDRESS
, 2, NO_SEG
, NO_SEG
);
1431 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
1432 size
= (opx
->type
& BITS16
) ? 2 : 4;
1434 size
= (bits
== 16) ? 2 : 4;
1435 if (opx
->segment
!= segment
) {
1437 out(offset
, segment
, &data
,
1438 size
== 2 ? OUT_REL2ADR
: OUT_REL4ADR
,
1439 insn_end
- offset
, opx
->segment
, opx
->wrt
);
1441 data
= opx
->offset
- insn_end
;
1442 out(offset
, segment
, &data
,
1443 OUT_ADDRESS
, size
, NO_SEG
, NO_SEG
);
1452 if (opx
->segment
!= segment
) {
1454 out(offset
, segment
, &data
,
1455 OUT_REL4ADR
, insn_end
- offset
,
1456 opx
->segment
, opx
->wrt
);
1458 data
= opx
->offset
- insn_end
;
1459 out(offset
, segment
, &data
,
1460 OUT_ADDRESS
, 4, NO_SEG
, NO_SEG
);
1469 if (opx
->segment
== NO_SEG
)
1470 errfunc(ERR_NONFATAL
, "value referenced by FAR is not"
1473 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1474 outfmt
->segbase(1 + opx
->segment
),
1484 warn_overflow(2, opx
);
1485 if (is_sbyte16(opx
)) {
1487 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1491 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1492 opx
->segment
, opx
->wrt
);
1502 bytes
[0] = *codes
++;
1503 if (is_sbyte16(opx
))
1504 bytes
[0] |= 2; /* s-bit */
1505 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1514 warn_overflow(4, opx
);
1515 if (is_sbyte32(opx
)) {
1517 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1521 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1522 opx
->segment
, opx
->wrt
);
1532 bytes
[0] = *codes
++;
1533 if (is_sbyte32(opx
))
1534 bytes
[0] |= 2; /* s-bit */
1535 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1551 (ins
->drexdst
<< 4) |
1552 (ins
->rex
& REX_OC
? 0x08 : 0) |
1553 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1555 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1561 opx
= &ins
->oprs
[c
>> 3];
1562 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1563 opx
= &ins
->oprs
[c
& 7];
1564 if (opx
->segment
!= NO_SEG
|| opx
->wrt
!= NO_SEG
) {
1565 errfunc(ERR_NONFATAL
,
1566 "non-absolute expression not permitted as argument %d",
1569 if (opx
->offset
& ~15) {
1570 errfunc(ERR_WARNING
| ERR_PASS2
| ERR_WARN_NOV
,
1571 "four-bit argument exceeds bounds");
1573 bytes
[0] |= opx
->offset
& 15;
1575 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1581 opx
= &ins
->oprs
[c
>> 4];
1582 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1584 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1590 opx
= &ins
->oprs
[c
];
1591 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1592 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1601 warn_overflow(4, opx
);
1602 if (is_sbyte64(opx
)) {
1604 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1608 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1609 opx
->segment
, opx
->wrt
);
1620 if (ins
->vex_m
!= 1 || (ins
->rex
& (REX_W
|REX_X
|REX_B
))) {
1622 bytes
[1] = ins
->vex_m
| ((~ins
->rex
& 7) << 5);
1623 bytes
[2] = ((ins
->rex
& REX_W
) << (7-3)) |
1624 ((~ins
->drexdst
& 15)<< 3) | (ins
->vex_wlp
& 07);
1625 out(offset
, segment
, &bytes
, OUT_RAWDATA
, 3, NO_SEG
, NO_SEG
);
1629 bytes
[1] = ((~ins
->rex
& REX_R
) << (7-2)) |
1630 ((~ins
->drexdst
& 15) << 3) | (ins
->vex_wlp
& 07);
1631 out(offset
, segment
, &bytes
, OUT_RAWDATA
, 2, NO_SEG
, NO_SEG
);
1644 if (ins
->rex
& REX_W
)
1646 else if (ins
->prefixes
[PPS_OSIZE
] == P_O16
)
1648 else if (ins
->prefixes
[PPS_OSIZE
] == P_O32
)
1653 um
= (uint64_t)2 << (s
-1);
1656 if (uv
> 127 && uv
< (uint64_t)-128 &&
1657 (uv
< um
-128 || uv
> um
-1)) {
1658 errfunc(ERR_WARNING
| ERR_PASS2
| ERR_WARN_NOV
,
1659 "signed byte value exceeds bounds");
1661 if (opx
->segment
!= NO_SEG
) {
1663 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1664 opx
->segment
, opx
->wrt
);
1667 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1681 if (bits
== 32 && !has_prefix(ins
, PPS_ASIZE
, P_A16
)) {
1683 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1690 if (bits
!= 32 && !has_prefix(ins
, PPS_ASIZE
, P_A32
)) {
1692 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1714 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1723 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1738 *bytes
= *codes
++ ^ condval
[ins
->condition
];
1739 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1748 *bytes
= c
- 0332 + 0xF2;
1749 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1754 if (ins
->rex
& REX_R
) {
1756 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1759 ins
->rex
&= ~(REX_L
|REX_R
);
1770 if (ins
->oprs
[0].segment
!= NO_SEG
)
1771 errfunc(ERR_PANIC
, "non-constant BSS size in pass two");
1773 int64_t size
= ins
->oprs
[0].offset
;
1775 out(offset
, segment
, NULL
,
1776 OUT_RESERVE
, size
, NO_SEG
, NO_SEG
);
1786 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1792 bytes
[0] = c
- 0362 + 0xf2;
1793 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1803 *bytes
= c
- 0366 + 0x66;
1804 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1814 *bytes
= bits
== 16 ? 3 : 5;
1815 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1819 default: /* can't do it by 'case' statements */
1820 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1829 /* pick rfield from operand b */
1830 rflags
= regflag(&ins
->oprs
[c
& 7]);
1831 rfield
= nasm_regvals
[ins
->oprs
[c
& 7].basereg
];
1833 /* rfield is constant */
1839 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1840 ins
->addr_size
, rfield
, rflags
)) {
1841 errfunc(ERR_NONFATAL
, "invalid effective address");
1846 *p
++ = ea_data
.modrm
;
1847 if (ea_data
.sib_present
)
1850 /* DREX suffixes come between the SIB and the displacement */
1851 if (ins
->rex
& REX_D
) {
1853 (ins
->drexdst
<< 4) |
1854 (ins
->rex
& REX_OC
? 0x08 : 0) |
1855 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1860 out(offset
, segment
, bytes
, OUT_RAWDATA
, s
, NO_SEG
, NO_SEG
);
1863 * Make sure the address gets the right offset in case
1864 * the line breaks in the .lst file (BR 1197827)
1869 switch (ea_data
.bytes
) {
1873 if (ins
->oprs
[(c
>> 3) & 7].segment
!= NO_SEG
) {
1874 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1875 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1876 ins
->oprs
[(c
>> 3) & 7].segment
,
1877 ins
->oprs
[(c
>> 3) & 7].wrt
);
1879 *bytes
= ins
->oprs
[(c
>> 3) & 7].offset
;
1880 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1,
1888 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1889 warn_overflow(ea_data
.bytes
, opx
);
1892 data
-= insn_end
- (offset
+ea_data
.bytes
);
1897 out(offset
, segment
, &data
, type
, ea_data
.bytes
,
1898 ins
->oprs
[(c
>> 3) & 7].segment
,
1899 ins
->oprs
[(c
>> 3) & 7].wrt
);
1904 errfunc(ERR_PANIC
, "internal instruction table corrupt"
1905 ": instruction code 0x%02X given", c
);
1911 static int32_t regflag(const operand
* o
)
1913 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1914 errfunc(ERR_PANIC
, "invalid operand passed to regflag()");
1916 return nasm_reg_flags
[o
->basereg
];
1919 static int32_t regval(const operand
* o
)
1921 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1922 errfunc(ERR_PANIC
, "invalid operand passed to regval()");
1924 return nasm_regvals
[o
->basereg
];
1927 static int op_rexflags(const operand
* o
, int mask
)
1932 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1933 errfunc(ERR_PANIC
, "invalid operand passed to op_rexflags()");
1936 flags
= nasm_reg_flags
[o
->basereg
];
1937 val
= nasm_regvals
[o
->basereg
];
1939 return rexflags(val
, flags
, mask
);
1942 static int rexflags(int val
, int32_t flags
, int mask
)
1947 rex
|= REX_B
|REX_X
|REX_R
;
1950 if (!(REG_HIGH
& ~flags
)) /* AH, CH, DH, BH */
1952 else if (!(REG8
& ~flags
) && val
>= 4) /* SPL, BPL, SIL, DIL */
1958 static int matches(const struct itemplate
*itemp
, insn
* instruction
, int bits
)
1960 int i
, size
[MAX_OPERANDS
], asize
, oprs
, ret
;
1967 if (itemp
->opcode
!= instruction
->opcode
)
1971 * Count the operands
1973 if (itemp
->operands
!= instruction
->operands
)
1977 * Check that no spurious colons or TOs are present
1979 for (i
= 0; i
< itemp
->operands
; i
++)
1980 if (instruction
->oprs
[i
].type
& ~itemp
->opd
[i
] & (COLON
| TO
))
1984 * Process size flags
1986 if (itemp
->flags
& IF_ARMASK
) {
1987 memset(size
, 0, sizeof size
);
1989 i
= ((itemp
->flags
& IF_ARMASK
) >> IF_ARSHFT
) - 1;
1991 switch (itemp
->flags
& IF_SMASK
) {
2028 switch (itemp
->flags
& IF_SMASK
) {
2063 for (i
= 0; i
< MAX_OPERANDS
; i
++)
2068 * Check that the operand flags all match up
2070 for (i
= 0; i
< itemp
->operands
; i
++) {
2071 int32_t type
= instruction
->oprs
[i
].type
;
2072 if (!(type
& SIZE_MASK
))
2075 if (itemp
->opd
[i
] & SAME_AS
) {
2076 int j
= itemp
->opd
[i
] & ~SAME_AS
;
2077 if (type
!= instruction
->oprs
[j
].type
||
2078 instruction
->oprs
[i
].basereg
!= instruction
->oprs
[j
].basereg
)
2080 } else if (itemp
->opd
[i
] & ~type
||
2081 ((itemp
->opd
[i
] & SIZE_MASK
) &&
2082 ((itemp
->opd
[i
] ^ type
) & SIZE_MASK
))) {
2083 if ((itemp
->opd
[i
] & ~type
& ~SIZE_MASK
) ||
2092 * Check operand sizes
2094 if (itemp
->flags
& (IF_SM
| IF_SM2
)) {
2095 oprs
= (itemp
->flags
& IF_SM2
? 2 : itemp
->operands
);
2097 for (i
= 0; i
< oprs
; i
++) {
2098 if ((asize
= itemp
->opd
[i
] & SIZE_MASK
) != 0) {
2100 for (j
= 0; j
< oprs
; j
++)
2106 oprs
= itemp
->operands
;
2109 for (i
= 0; i
< itemp
->operands
; i
++) {
2110 if (!(itemp
->opd
[i
] & SIZE_MASK
) &&
2111 (instruction
->oprs
[i
].type
& SIZE_MASK
& ~size
[i
]))
2116 * Check template is okay at the set cpu level
2118 if (((itemp
->flags
& IF_PLEVEL
) > cpu
))
2122 * Check if instruction is available in long mode
2124 if ((itemp
->flags
& IF_NOLONG
) && (bits
== 64))
2128 * Check if special handling needed for Jumps
2130 if ((uint8_t)(itemp
->code
[0]) >= 0370)
2136 static ea
*process_ea(operand
* input
, ea
* output
, int bits
,
2137 int addrbits
, int rfield
, int32_t rflags
)
2139 bool forw_ref
= !!(input
->opflags
& OPFLAG_FORWARD
);
2141 output
->rip
= false;
2143 /* REX flags for the rfield operand */
2144 output
->rex
|= rexflags(rfield
, rflags
, REX_R
|REX_P
|REX_W
|REX_H
);
2146 if (!(REGISTER
& ~input
->type
)) { /* register direct */
2150 if (input
->basereg
< EXPR_REG_START
/* Verify as Register */
2151 || input
->basereg
>= REG_ENUM_LIMIT
)
2154 i
= nasm_regvals
[input
->basereg
];
2157 return NULL
; /* Invalid EA register */
2159 output
->rex
|= op_rexflags(input
, REX_B
|REX_P
|REX_W
|REX_H
);
2161 output
->sib_present
= false; /* no SIB necessary */
2162 output
->bytes
= 0; /* no offset necessary either */
2163 output
->modrm
= 0xC0 | ((rfield
& 7) << 3) | (i
& 7);
2164 } else { /* it's a memory reference */
2165 if (input
->basereg
== -1
2166 && (input
->indexreg
== -1 || input
->scale
== 0)) {
2167 /* it's a pure offset */
2168 if (bits
== 64 && (~input
->type
& IP_REL
)) {
2169 int scale
, index
, base
;
2170 output
->sib_present
= true;
2174 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
2176 output
->modrm
= 4 | ((rfield
& 7) << 3);
2177 output
->rip
= false;
2179 output
->sib_present
= false;
2180 output
->bytes
= (addrbits
!= 16 ? 4 : 2);
2181 output
->modrm
= (addrbits
!= 16 ? 5 : 6) | ((rfield
& 7) << 3);
2182 output
->rip
= bits
== 64;
2184 } else { /* it's an indirection */
2185 int i
= input
->indexreg
, b
= input
->basereg
, s
= input
->scale
;
2186 int32_t o
= input
->offset
, seg
= input
->segment
;
2187 int hb
= input
->hintbase
, ht
= input
->hinttype
;
2190 int32_t ix
, bx
; /* register flags */
2193 i
= -1; /* make this easy, at least */
2195 if (i
>= EXPR_REG_START
&& i
< REG_ENUM_LIMIT
) {
2196 it
= nasm_regvals
[i
];
2197 ix
= nasm_reg_flags
[i
];
2203 if (b
>= EXPR_REG_START
&& b
< REG_ENUM_LIMIT
) {
2204 bt
= nasm_regvals
[b
];
2205 bx
= nasm_reg_flags
[b
];
2211 /* check for a 32/64-bit memory reference... */
2212 if ((ix
|bx
) & (BITS32
|BITS64
)) {
2213 /* it must be a 32/64-bit memory reference. Firstly we have
2214 * to check that all registers involved are type E/Rxx. */
2215 int32_t sok
= BITS32
|BITS64
;
2218 if (!(REG64
& ~ix
) || !(REG32
& ~ix
))
2226 return NULL
; /* Invalid register */
2227 if (~sok
& bx
& SIZE_MASK
)
2228 return NULL
; /* Invalid size */
2232 /* While we're here, ensure the user didn't specify
2234 if (input
->disp_size
== 16 || input
->disp_size
== 64)
2237 if (addrbits
== 16 ||
2238 (addrbits
== 32 && !(sok
& BITS32
)) ||
2239 (addrbits
== 64 && !(sok
& BITS64
)))
2242 /* now reorganize base/index */
2243 if (s
== 1 && bt
!= it
&& bt
!= -1 && it
!= -1 &&
2244 ((hb
== b
&& ht
== EAH_NOTBASE
)
2245 || (hb
== i
&& ht
== EAH_MAKEBASE
))) {
2246 /* swap if hints say so */
2247 t
= bt
, bt
= it
, it
= t
;
2248 t
= bx
, bx
= ix
, ix
= t
;
2250 if (bt
== it
) /* convert EAX+2*EAX to 3*EAX */
2251 bt
= -1, bx
= 0, s
++;
2252 if (bt
== -1 && s
== 1 && !(hb
== it
&& ht
== EAH_NOTBASE
)) {
2253 /* make single reg base, unless hint */
2254 bt
= it
, bx
= ix
, it
= -1, ix
= 0;
2256 if (((s
== 2 && it
!= REG_NUM_ESP
2257 && !(input
->eaflags
& EAF_TIMESTWO
)) || s
== 3
2258 || s
== 5 || s
== 9) && bt
== -1)
2259 bt
= it
, bx
= ix
, s
--; /* convert 3*EAX to EAX+2*EAX */
2260 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
2261 && (input
->eaflags
& EAF_TIMESTWO
))
2262 it
= bt
, ix
= bx
, bt
= -1, bx
= 0, s
= 1;
2263 /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */
2264 if (s
== 1 && it
== REG_NUM_ESP
) {
2265 /* swap ESP into base if scale is 1 */
2266 t
= it
, it
= bt
, bt
= t
;
2267 t
= ix
, ix
= bx
, bx
= t
;
2269 if (it
== REG_NUM_ESP
2270 || (s
!= 1 && s
!= 2 && s
!= 4 && s
!= 8 && it
!= -1))
2271 return NULL
; /* wrong, for various reasons */
2273 output
->rex
|= rexflags(it
, ix
, REX_X
);
2274 output
->rex
|= rexflags(bt
, bx
, REX_B
);
2276 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
) {
2285 if (rm
!= REG_NUM_EBP
&& o
== 0 &&
2286 seg
== NO_SEG
&& !forw_ref
&&
2288 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2290 else if (input
->eaflags
& EAF_BYTEOFFS
||
2291 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2293 && !(input
->eaflags
& EAF_WORDOFFS
)))
2299 output
->sib_present
= false;
2300 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
2301 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
2304 int mod
, scale
, index
, base
;
2324 default: /* then what the smeg is it? */
2325 return NULL
; /* panic */
2333 if (base
!= REG_NUM_EBP
&& o
== 0 &&
2334 seg
== NO_SEG
&& !forw_ref
&&
2336 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2338 else if (input
->eaflags
& EAF_BYTEOFFS
||
2339 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2341 && !(input
->eaflags
& EAF_WORDOFFS
)))
2347 output
->sib_present
= true;
2348 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
2349 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | 4;
2350 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
2352 } else { /* it's 16-bit */
2355 /* check for 64-bit long mode */
2359 /* check all registers are BX, BP, SI or DI */
2360 if ((b
!= -1 && b
!= R_BP
&& b
!= R_BX
&& b
!= R_SI
2361 && b
!= R_DI
) || (i
!= -1 && i
!= R_BP
&& i
!= R_BX
2362 && i
!= R_SI
&& i
!= R_DI
))
2365 /* ensure the user didn't specify DWORD/QWORD */
2366 if (input
->disp_size
== 32 || input
->disp_size
== 64)
2369 if (s
!= 1 && i
!= -1)
2370 return NULL
; /* no can do, in 16-bit EA */
2371 if (b
== -1 && i
!= -1) {
2376 if ((b
== R_SI
|| b
== R_DI
) && i
!= -1) {
2381 /* have BX/BP as base, SI/DI index */
2383 return NULL
; /* shouldn't ever happen, in theory */
2384 if (i
!= -1 && b
!= -1 &&
2385 (i
== R_BP
|| i
== R_BX
|| b
== R_SI
|| b
== R_DI
))
2386 return NULL
; /* invalid combinations */
2387 if (b
== -1) /* pure offset: handled above */
2388 return NULL
; /* so if it gets to here, panic! */
2392 switch (i
* 256 + b
) {
2393 case R_SI
* 256 + R_BX
:
2396 case R_DI
* 256 + R_BX
:
2399 case R_SI
* 256 + R_BP
:
2402 case R_DI
* 256 + R_BP
:
2420 if (rm
== -1) /* can't happen, in theory */
2421 return NULL
; /* so panic if it does */
2423 if (o
== 0 && seg
== NO_SEG
&& !forw_ref
&& rm
!= 6 &&
2424 !(input
->eaflags
& (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2426 else if (input
->eaflags
& EAF_BYTEOFFS
||
2427 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2429 && !(input
->eaflags
& EAF_WORDOFFS
)))
2434 output
->sib_present
= false; /* no SIB - it's 16-bit */
2435 output
->bytes
= mod
; /* bytes of offset needed */
2436 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
2441 output
->size
= 1 + output
->sib_present
+ output
->bytes
;
2445 static void add_asp(insn
*ins
, int addrbits
)
2450 valid
= (addrbits
== 64) ? 64|32 : 32|16;
2452 switch (ins
->prefixes
[PPS_ASIZE
]) {
2463 valid
&= (addrbits
== 32) ? 16 : 32;
2469 for (j
= 0; j
< ins
->operands
; j
++) {
2470 if (!(MEMORY
& ~ins
->oprs
[j
].type
)) {
2473 /* Verify as Register */
2474 if (ins
->oprs
[j
].indexreg
< EXPR_REG_START
2475 || ins
->oprs
[j
].indexreg
>= REG_ENUM_LIMIT
)
2478 i
= nasm_reg_flags
[ins
->oprs
[j
].indexreg
];
2480 /* Verify as Register */
2481 if (ins
->oprs
[j
].basereg
< EXPR_REG_START
2482 || ins
->oprs
[j
].basereg
>= REG_ENUM_LIMIT
)
2485 b
= nasm_reg_flags
[ins
->oprs
[j
].basereg
];
2487 if (ins
->oprs
[j
].scale
== 0)
2491 int ds
= ins
->oprs
[j
].disp_size
;
2492 if ((addrbits
!= 64 && ds
> 8) ||
2493 (addrbits
== 64 && ds
== 16))
2513 if (valid
& addrbits
) {
2514 ins
->addr_size
= addrbits
;
2515 } else if (valid
& ((addrbits
== 32) ? 16 : 32)) {
2516 /* Add an address size prefix */
2517 enum prefixes pref
= (addrbits
== 32) ? P_A16
: P_A32
;
2518 ins
->prefixes
[PPS_ASIZE
] = pref
;
2519 ins
->addr_size
= (addrbits
== 32) ? 16 : 32;
2522 errfunc(ERR_NONFATAL
, "impossible combination of address sizes");
2523 ins
->addr_size
= addrbits
; /* Error recovery */
2526 defdisp
= ins
->addr_size
== 16 ? 16 : 32;
2528 for (j
= 0; j
< ins
->operands
; j
++) {
2529 if (!(MEM_OFFS
& ~ins
->oprs
[j
].type
) &&
2530 (ins
->oprs
[j
].disp_size
? ins
->oprs
[j
].disp_size
: defdisp
)
2531 != ins
->addr_size
) {
2532 /* mem_offs sizes must match the address size; if not,
2533 strip the MEM_OFFS bit and match only EA instructions */
2534 ins
->oprs
[j
].type
&= ~(MEM_OFFS
& ~MEMORY
);