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 segment
, int64_t offset
, int bits
,
144 insn
* ins
, const struct itemplate
*temp
,
146 static int matches(const struct itemplate
*, insn
*, int bits
);
147 static int32_t regflag(const operand
*);
148 static int32_t regval(const operand
*);
149 static int rexflags(int, int32_t, int);
150 static int op_rexflags(const operand
*, int);
151 static ea
*process_ea(operand
*, ea
*, int, int, int, int32_t);
152 static void add_asp(insn
*, int);
154 static int has_prefix(insn
* ins
, enum prefix_pos pos
, enum prefixes prefix
)
156 return ins
->prefixes
[pos
] == prefix
;
159 static void assert_no_prefix(insn
* ins
, enum prefix_pos pos
)
161 if (ins
->prefixes
[pos
])
162 errfunc(ERR_NONFATAL
, "invalid %s prefix",
163 prefix_name(ins
->prefixes
[pos
]));
166 static const char *size_name(int size
)
188 static void warn_overflow(int size
, const struct operand
*o
)
190 if (size
< 8 && o
->wrt
== NO_SEG
&& o
->segment
== NO_SEG
) {
191 int64_t lim
= ((int64_t)1 << (size
*8))-1;
192 int64_t data
= o
->offset
;
194 if (data
< ~lim
|| data
> lim
)
195 errfunc(ERR_WARNING
| ERR_PASS2
| ERR_WARN_NOV
,
196 "%s data exceeds bounds", size_name(size
));
200 * This routine wrappers the real output format's output routine,
201 * in order to pass a copy of the data off to the listing file
202 * generator at the same time.
204 static void out(int64_t offset
, int32_t segto
, const void *data
,
205 enum out_type type
, uint64_t size
,
206 int32_t segment
, int32_t wrt
)
208 static int32_t lineno
= 0; /* static!!! */
209 static char *lnfname
= NULL
;
212 if (type
== OUT_ADDRESS
&& segment
== NO_SEG
&& wrt
== NO_SEG
) {
214 * This is a non-relocated address, and we're going to
215 * convert it into RAWDATA format.
220 errfunc(ERR_PANIC
, "OUT_ADDRESS with size > 8");
224 WRITEADDR(q
, *(int64_t *)data
, size
);
229 list
->output(offset
, data
, type
, size
);
232 * this call to src_get determines when we call the
233 * debug-format-specific "linenum" function
234 * it updates lineno and lnfname to the current values
235 * returning 0 if "same as last time", -2 if lnfname
236 * changed, and the amount by which lineno changed,
237 * if it did. thus, these variables must be static
240 if (src_get(&lineno
, &lnfname
)) {
241 outfmt
->current_dfmt
->linenum(lnfname
, lineno
, segto
);
244 outfmt
->output(segto
, data
, type
, size
, segment
, wrt
);
247 static bool jmp_match(int32_t segment
, int64_t offset
, int bits
,
248 insn
* ins
, const uint8_t *code
)
253 if ((c
!= 0370 && c
!= 0371) || (ins
->oprs
[0].type
& STRICT
))
257 if (optimizing
< 0 && c
== 0371)
260 isize
= calcsize(segment
, offset
, bits
, ins
, code
);
261 if (ins
->oprs
[0].segment
!= segment
)
264 isize
= ins
->oprs
[0].offset
- offset
- isize
; /* isize is delta */
265 return (isize
>= -128 && isize
<= 127); /* is it byte size? */
268 int64_t assemble(int32_t segment
, int64_t offset
, int bits
, uint32_t cp
,
269 insn
* instruction
, struct ofmt
*output
, efunc error
,
272 const struct itemplate
*temp
;
277 int64_t start
= offset
;
278 int64_t wsize
= 0; /* size for DB etc. */
280 errfunc
= error
; /* to pass to other functions */
282 outfmt
= output
; /* likewise */
283 list
= listgen
; /* and again */
285 switch (instruction
->opcode
) {
315 int32_t t
= instruction
->times
;
318 "instruction->times < 0 (%ld) in assemble()", t
);
320 while (t
--) { /* repeat TIMES times */
321 for (e
= instruction
->eops
; e
; e
= e
->next
) {
322 if (e
->type
== EOT_DB_NUMBER
) {
324 if (e
->segment
!= NO_SEG
)
325 errfunc(ERR_NONFATAL
,
326 "one-byte relocation attempted");
328 uint8_t out_byte
= e
->offset
;
329 out(offset
, segment
, &out_byte
,
330 OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
332 } else if (wsize
> 8) {
333 errfunc(ERR_NONFATAL
,
334 "integer supplied to a DT, DO or DY"
337 out(offset
, segment
, &e
->offset
,
338 OUT_ADDRESS
, wsize
, e
->segment
, e
->wrt
);
340 } else if (e
->type
== EOT_DB_STRING
||
341 e
->type
== EOT_DB_STRING_FREE
) {
344 out(offset
, segment
, e
->stringval
,
345 OUT_RAWDATA
, e
->stringlen
, NO_SEG
, NO_SEG
);
346 align
= e
->stringlen
% wsize
;
349 align
= wsize
- align
;
350 out(offset
, segment
, const_zero_buf
,
351 OUT_RAWDATA
, align
, NO_SEG
, NO_SEG
);
353 offset
+= e
->stringlen
+ align
;
356 if (t
> 0 && t
== instruction
->times
- 1) {
358 * Dummy call to list->output to give the offset to the
361 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
362 list
->uplevel(LIST_TIMES
);
365 if (instruction
->times
> 1)
366 list
->downlevel(LIST_TIMES
);
367 return offset
- start
;
370 if (instruction
->opcode
== I_INCBIN
) {
371 const char *fname
= instruction
->eops
->stringval
;
374 fp
= fopen(fname
, "rb");
376 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
378 } else if (fseek(fp
, 0L, SEEK_END
) < 0) {
379 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
382 static char buf
[4096];
383 size_t t
= instruction
->times
;
388 if (instruction
->eops
->next
) {
389 base
= instruction
->eops
->next
->offset
;
391 if (instruction
->eops
->next
->next
&&
392 len
> (size_t)instruction
->eops
->next
->next
->offset
)
393 len
= (size_t)instruction
->eops
->next
->next
->offset
;
396 * Dummy call to list->output to give the offset to the
399 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
400 list
->uplevel(LIST_INCBIN
);
404 fseek(fp
, base
, SEEK_SET
);
408 fread(buf
, 1, (l
> (int32_t) sizeof(buf
) ? (int32_t) sizeof(buf
) : l
),
412 * This shouldn't happen unless the file
413 * actually changes while we are reading
417 "`incbin': unexpected EOF while"
418 " reading file `%s'", fname
);
419 t
= 0; /* Try to exit cleanly */
422 out(offset
, segment
, buf
, OUT_RAWDATA
, m
,
427 list
->downlevel(LIST_INCBIN
);
428 if (instruction
->times
> 1) {
430 * Dummy call to list->output to give the offset to the
433 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
434 list
->uplevel(LIST_TIMES
);
435 list
->downlevel(LIST_TIMES
);
438 return instruction
->times
* len
;
440 return 0; /* if we're here, there's an error */
443 /* Check to see if we need an address-size prefix */
444 add_asp(instruction
, bits
);
448 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++){
449 int m
= matches(temp
, instruction
, bits
);
451 (m
== 99 && jmp_match(segment
, offset
, bits
,
452 instruction
, temp
->code
))) {
454 int64_t insn_size
= calcsize(segment
, offset
, bits
,
455 instruction
, temp
->code
);
456 itimes
= instruction
->times
;
457 if (insn_size
< 0) /* shouldn't be, on pass two */
458 error(ERR_PANIC
, "errors made it through from pass one");
461 for (j
= 0; j
< MAXPREFIX
; j
++) {
463 switch (instruction
->prefixes
[j
]) {
478 error(ERR_WARNING
| ERR_PASS2
,
479 "cs segment base generated, but will be ignored in 64-bit mode");
485 error(ERR_WARNING
| ERR_PASS2
,
486 "ds segment base generated, but will be ignored in 64-bit mode");
492 error(ERR_WARNING
| ERR_PASS2
,
493 "es segment base generated, but will be ignored in 64-bit mode");
505 error(ERR_WARNING
| ERR_PASS2
,
506 "ss segment base generated, but will be ignored in 64-bit mode");
513 "segr6 and segr7 cannot be used as prefixes");
518 "16-bit addressing is not supported "
520 } else if (bits
!= 16)
530 "64-bit addressing is only supported "
554 error(ERR_PANIC
, "invalid instruction prefix");
557 out(offset
, segment
, &c
, OUT_RAWDATA
, 1,
562 insn_end
= offset
+ insn_size
;
563 gencode(segment
, offset
, bits
, instruction
,
566 if (itimes
> 0 && itimes
== instruction
->times
- 1) {
568 * Dummy call to list->output to give the offset to the
571 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
572 list
->uplevel(LIST_TIMES
);
575 if (instruction
->times
> 1)
576 list
->downlevel(LIST_TIMES
);
577 return offset
- start
;
578 } else if (m
> 0 && m
> size_prob
) {
583 if (temp
->opcode
== -1) { /* didn't match any instruction */
586 error(ERR_NONFATAL
, "operation size not specified");
589 error(ERR_NONFATAL
, "mismatch in operand sizes");
592 error(ERR_NONFATAL
, "no instruction for this cpu level");
595 error(ERR_NONFATAL
, "instruction not supported in 64-bit mode");
599 "invalid combination of opcode and operands");
606 int64_t insn_size(int32_t segment
, int64_t offset
, int bits
, uint32_t cp
,
607 insn
* instruction
, efunc error
)
609 const struct itemplate
*temp
;
611 errfunc
= error
; /* to pass to other functions */
614 if (instruction
->opcode
== -1)
617 if (instruction
->opcode
== I_DB
|| instruction
->opcode
== I_DW
||
618 instruction
->opcode
== I_DD
|| instruction
->opcode
== I_DQ
||
619 instruction
->opcode
== I_DT
|| instruction
->opcode
== I_DO
||
620 instruction
->opcode
== I_DY
) {
622 int32_t isize
, osize
, wsize
= 0; /* placate gcc */
625 switch (instruction
->opcode
) {
651 for (e
= instruction
->eops
; e
; e
= e
->next
) {
655 if (e
->type
== EOT_DB_NUMBER
)
657 else if (e
->type
== EOT_DB_STRING
||
658 e
->type
== EOT_DB_STRING_FREE
)
659 osize
= e
->stringlen
;
661 align
= (-osize
) % wsize
;
664 isize
+= osize
+ align
;
666 return isize
* instruction
->times
;
669 if (instruction
->opcode
== I_INCBIN
) {
670 const char *fname
= instruction
->eops
->stringval
;
674 fp
= fopen(fname
, "rb");
676 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
678 else if (fseek(fp
, 0L, SEEK_END
) < 0)
679 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
684 if (instruction
->eops
->next
) {
685 len
-= instruction
->eops
->next
->offset
;
686 if (instruction
->eops
->next
->next
&&
687 len
> (size_t)instruction
->eops
->next
->next
->offset
) {
688 len
= (size_t)instruction
->eops
->next
->next
->offset
;
691 return instruction
->times
* len
;
693 return 0; /* if we're here, there's an error */
696 /* Check to see if we need an address-size prefix */
697 add_asp(instruction
, bits
);
699 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++) {
700 int m
= matches(temp
, instruction
, bits
);
702 (m
== 99 && jmp_match(segment
, offset
, bits
,
703 instruction
, temp
->code
))) {
704 /* we've matched an instruction. */
706 const uint8_t *codes
= temp
->code
;
709 isize
= calcsize(segment
, offset
, bits
, instruction
, codes
);
712 for (j
= 0; j
< MAXPREFIX
; j
++) {
713 switch (instruction
->prefixes
[j
]) {
739 return isize
* instruction
->times
;
742 return -1; /* didn't match any instruction */
745 static bool possible_sbyte(operand
*o
)
747 return !(o
->opflags
& OPFLAG_FORWARD
) &&
748 optimizing
>= 0 && !(o
->type
& STRICT
);
751 /* check that opn[op] is a signed byte of size 16 or 32 */
752 static bool is_sbyte16(operand
*o
)
756 if (!possible_sbyte(o
))
760 return v
>= -128 && v
<= 127;
763 static bool is_sbyte32(operand
*o
)
767 if (!possible_sbyte(o
))
771 return v
>= -128 && v
<= 127;
774 /* check that opn[op] is a signed byte of size 32; warn if this is not
775 the original value when extended to 64 bits */
776 static bool is_sbyte64(operand
*o
)
781 if (!(o
->wrt
== NO_SEG
&& o
->segment
== NO_SEG
))
782 return false; /* Not a pure immediate */
788 errfunc(ERR_WARNING
| ERR_PASS2
| ERR_WARN_NOV
,
789 "signed dword immediate exceeds bounds");
791 /* dead in the water on forward reference or External */
792 if (!possible_sbyte(o
))
796 return v
>= -128 && v
<= 127;
798 static int64_t calcsize(int32_t segment
, int64_t offset
, int bits
,
799 insn
* ins
, const uint8_t *codes
)
806 ins
->rex
= 0; /* Ensure REX is reset */
808 if (ins
->prefixes
[PPS_OSIZE
] == P_O64
)
811 (void)segment
; /* Don't warn that this parameter is unused */
812 (void)offset
; /* Don't warn that this parameter is unused */
816 opx
= &ins
->oprs
[c
& 3];
821 codes
+= c
, length
+= c
;
834 op_rexflags(opx
, REX_B
|REX_H
|REX_P
|REX_W
);
865 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
866 length
+= (opx
->type
& BITS16
) ? 2 : 4;
868 length
+= (bits
== 16) ? 2 : 4;
880 length
+= ins
->addr_size
>> 3;
892 length
+= 8; /* MOV reg64/imm */
904 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
905 length
+= (opx
->type
& BITS16
) ? 2 : 4;
907 length
+= (bits
== 16) ? 2 : 4;
925 length
+= is_sbyte16(opx
) ? 1 : 2;
938 length
+= is_sbyte32(opx
) ? 1 : 4;
953 ins
->drexdst
= regval(opx
);
960 ins
->rex
|= REX_D
|REX_OC
;
961 ins
->drexdst
= regval(opx
);
975 length
+= is_sbyte64(opx
) ? 1 : 4;
982 ins
->drexdst
= regval(opx
);
983 ins
->vex_m
= *codes
++;
984 ins
->vex_wlp
= *codes
++;
989 ins
->vex_m
= *codes
++;
990 ins
->vex_wlp
= *codes
++;
1000 length
+= (bits
!= 16) && !has_prefix(ins
, PPS_ASIZE
, P_A16
);
1003 length
+= (bits
!= 32) && !has_prefix(ins
, PPS_ASIZE
, P_A32
);
1008 if (bits
!= 64 || has_prefix(ins
, PPS_ASIZE
, P_A16
) ||
1009 has_prefix(ins
, PPS_ASIZE
, P_A32
))
1018 length
+= (bits
!= 16);
1021 length
+= (bits
== 16);
1046 if (!ins
->prefixes
[PPS_LREP
])
1047 ins
->prefixes
[PPS_LREP
] = P_REP
;
1050 if (!ins
->prefixes
[PPS_LREP
])
1051 ins
->prefixes
[PPS_LREP
] = P_REPNE
;
1054 if (ins
->oprs
[0].segment
!= NO_SEG
)
1055 errfunc(ERR_NONFATAL
, "attempt to reserve non-constant"
1056 " quantity of BSS space");
1058 length
+= ins
->oprs
[0].offset
;
1081 default: /* can't do it by 'case' statements */
1082 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1086 ea_data
.rex
= 0; /* Ensure ea.REX is initially 0 */
1089 /* pick rfield from operand b */
1090 rflags
= regflag(&ins
->oprs
[c
& 7]);
1091 rfield
= nasm_regvals
[ins
->oprs
[c
& 7].basereg
];
1098 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1099 ins
->addr_size
, rfield
, rflags
)) {
1100 errfunc(ERR_NONFATAL
, "invalid effective address");
1103 ins
->rex
|= ea_data
.rex
;
1104 length
+= ea_data
.size
;
1107 errfunc(ERR_PANIC
, "internal instruction table corrupt"
1108 ": instruction code 0x%02X given", c
);
1113 ins
->rex
&= rex_mask
;
1115 if (ins
->rex
& REX_V
) {
1116 int bad32
= REX_R
|REX_W
|REX_X
|REX_B
;
1118 if (ins
->rex
& REX_H
) {
1119 errfunc(ERR_NONFATAL
, "cannot use high register in vex instruction");
1122 switch (ins
->vex_wlp
& 030) {
1136 if (bits
!= 64 && ((ins
->rex
& bad32
) || ins
->drexdst
> 7)) {
1137 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1140 if (ins
->vex_m
!= 1 || (ins
->rex
& (REX_W
|REX_R
|REX_B
)))
1144 } else if (ins
->rex
& REX_D
) {
1145 if (ins
->rex
& REX_H
) {
1146 errfunc(ERR_NONFATAL
, "cannot use high register in drex instruction");
1149 if (bits
!= 64 && ((ins
->rex
& (REX_R
|REX_W
|REX_X
|REX_B
)) ||
1150 ins
->drexdst
> 7)) {
1151 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1155 } else if (ins
->rex
& REX_REAL
) {
1156 if (ins
->rex
& REX_H
) {
1157 errfunc(ERR_NONFATAL
, "cannot use high register in rex instruction");
1159 } else if (bits
== 64) {
1161 } else if ((ins
->rex
& REX_L
) &&
1162 !(ins
->rex
& (REX_P
|REX_W
|REX_X
|REX_B
)) &&
1165 assert_no_prefix(ins
, PPS_LREP
);
1168 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1176 #define EMIT_REX() \
1177 if (!(ins->rex & (REX_D|REX_V)) && (ins->rex & REX_REAL) && (bits == 64)) { \
1178 ins->rex = (ins->rex & REX_REAL)|REX_P; \
1179 out(offset, segment, &ins->rex, OUT_RAWDATA, 1, NO_SEG, NO_SEG); \
1184 static void gencode(int32_t segment
, int64_t offset
, int bits
,
1185 insn
* ins
, const struct itemplate
*temp
,
1188 static char condval
[] = { /* conditional opcodes */
1189 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
1190 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
1191 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
1197 struct operand
*opx
;
1198 const uint8_t *codes
= temp
->code
;
1202 opx
= &ins
->oprs
[c
& 3];
1208 out(offset
, segment
, codes
, OUT_RAWDATA
, c
, NO_SEG
, NO_SEG
);
1215 switch (ins
->oprs
[0].basereg
) {
1217 bytes
[0] = 0x0E + (c
== 0x04 ? 1 : 0);
1220 bytes
[0] = 0x1E + (c
== 0x04 ? 1 : 0);
1223 bytes
[0] = 0x06 + (c
== 0x04 ? 1 : 0);
1226 bytes
[0] = 0x16 + (c
== 0x04 ? 1 : 0);
1230 "bizarre 8086 segment register received");
1232 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1238 switch (ins
->oprs
[0].basereg
) {
1240 bytes
[0] = 0xA0 + (c
== 0x05 ? 1 : 0);
1243 bytes
[0] = 0xA8 + (c
== 0x05 ? 1 : 0);
1247 "bizarre 386 segment register received");
1249 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1258 bytes
[0] = *codes
++ + ((regval(opx
)) & 7);
1259 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1267 /* The test for BITS8 and SBYTE here is intended to avoid
1268 warning on optimizer actions due to SBYTE, while still
1269 warn on explicit BYTE directives. Also warn, obviously,
1270 if the optimizer isn't enabled. */
1271 if (((opx
->type
& BITS8
) ||
1272 !(opx
->type
& temp
->opd
[c
& 3] & BYTENESS
)) &&
1273 (opx
->offset
< -128 || opx
->offset
> 127)) {
1274 errfunc(ERR_WARNING
| ERR_PASS2
| ERR_WARN_NOV
,
1275 "signed byte value exceeds bounds");
1277 if (opx
->segment
!= NO_SEG
) {
1279 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1280 opx
->segment
, opx
->wrt
);
1282 bytes
[0] = opx
->offset
;
1283 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1293 if (opx
->offset
< -256 || opx
->offset
> 255) {
1294 errfunc(ERR_WARNING
| ERR_PASS2
| ERR_WARN_NOV
,
1295 "byte value exceeds bounds");
1297 if (opx
->segment
!= NO_SEG
) {
1299 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1300 opx
->segment
, opx
->wrt
);
1302 bytes
[0] = opx
->offset
;
1303 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1313 if (opx
->offset
< 0 || opx
->offset
> 255)
1314 errfunc(ERR_WARNING
| ERR_PASS2
| ERR_WARN_NOV
,
1315 "unsigned byte value exceeds bounds");
1316 if (opx
->segment
!= NO_SEG
) {
1318 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1319 opx
->segment
, opx
->wrt
);
1321 bytes
[0] = opx
->offset
;
1322 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1332 warn_overflow(2, opx
);
1334 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1335 opx
->segment
, opx
->wrt
);
1343 if (opx
->type
& (BITS16
| BITS32
))
1344 size
= (opx
->type
& BITS16
) ? 2 : 4;
1346 size
= (bits
== 16) ? 2 : 4;
1347 warn_overflow(size
, opx
);
1349 out(offset
, segment
, &data
, OUT_ADDRESS
, size
,
1350 opx
->segment
, opx
->wrt
);
1358 warn_overflow(4, opx
);
1360 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1361 opx
->segment
, opx
->wrt
);
1370 size
= ins
->addr_size
>> 3;
1371 warn_overflow(size
, opx
);
1372 out(offset
, segment
, &data
, OUT_ADDRESS
, size
,
1373 opx
->segment
, opx
->wrt
);
1381 if (opx
->segment
!= segment
)
1382 errfunc(ERR_NONFATAL
,
1383 "short relative jump outside segment");
1384 data
= opx
->offset
- insn_end
;
1385 if (data
> 127 || data
< -128)
1386 errfunc(ERR_NONFATAL
, "short jump is out of range");
1388 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1396 data
= (int64_t)opx
->offset
;
1397 out(offset
, segment
, &data
, OUT_ADDRESS
, 8,
1398 opx
->segment
, opx
->wrt
);
1406 if (opx
->segment
!= segment
) {
1408 out(offset
, segment
, &data
,
1409 OUT_REL2ADR
, insn_end
- offset
,
1410 opx
->segment
, opx
->wrt
);
1412 data
= opx
->offset
- insn_end
;
1413 out(offset
, segment
, &data
,
1414 OUT_ADDRESS
, 2, NO_SEG
, NO_SEG
);
1423 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
1424 size
= (opx
->type
& BITS16
) ? 2 : 4;
1426 size
= (bits
== 16) ? 2 : 4;
1427 if (opx
->segment
!= segment
) {
1429 out(offset
, segment
, &data
,
1430 size
== 2 ? OUT_REL2ADR
: OUT_REL4ADR
,
1431 insn_end
- offset
, opx
->segment
, opx
->wrt
);
1433 data
= opx
->offset
- insn_end
;
1434 out(offset
, segment
, &data
,
1435 OUT_ADDRESS
, size
, NO_SEG
, NO_SEG
);
1444 if (opx
->segment
!= segment
) {
1446 out(offset
, segment
, &data
,
1447 OUT_REL4ADR
, insn_end
- offset
,
1448 opx
->segment
, opx
->wrt
);
1450 data
= opx
->offset
- insn_end
;
1451 out(offset
, segment
, &data
,
1452 OUT_ADDRESS
, 4, NO_SEG
, NO_SEG
);
1461 if (opx
->segment
== NO_SEG
)
1462 errfunc(ERR_NONFATAL
, "value referenced by FAR is not"
1465 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1466 outfmt
->segbase(1 + opx
->segment
),
1476 warn_overflow(2, opx
);
1477 if (is_sbyte16(opx
)) {
1479 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1483 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1484 opx
->segment
, opx
->wrt
);
1494 bytes
[0] = *codes
++;
1495 if (is_sbyte16(opx
))
1496 bytes
[0] |= 2; /* s-bit */
1497 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1506 warn_overflow(4, opx
);
1507 if (is_sbyte32(opx
)) {
1509 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1513 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1514 opx
->segment
, opx
->wrt
);
1524 bytes
[0] = *codes
++;
1525 if (is_sbyte32(opx
))
1526 bytes
[0] |= 2; /* s-bit */
1527 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1543 (ins
->drexdst
<< 4) |
1544 (ins
->rex
& REX_OC
? 0x08 : 0) |
1545 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1547 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1553 opx
= &ins
->oprs
[c
>> 3];
1554 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1555 opx
= &ins
->oprs
[c
& 7];
1556 if (opx
->segment
!= NO_SEG
|| opx
->wrt
!= NO_SEG
) {
1557 errfunc(ERR_NONFATAL
,
1558 "non-absolute expression not permitted as argument %d",
1561 if (opx
->offset
& ~15) {
1562 errfunc(ERR_WARNING
| ERR_PASS2
| ERR_WARN_NOV
,
1563 "four-bit argument exceeds bounds");
1565 bytes
[0] |= opx
->offset
& 15;
1567 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1573 opx
= &ins
->oprs
[c
>> 4];
1574 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1576 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1582 opx
= &ins
->oprs
[c
];
1583 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1584 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1593 warn_overflow(4, opx
);
1594 if (is_sbyte64(opx
)) {
1596 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1600 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1601 opx
->segment
, opx
->wrt
);
1612 if (ins
->vex_m
!= 1 || (ins
->rex
& (REX_W
|REX_X
|REX_B
))) {
1614 bytes
[1] = ins
->vex_m
| ((~ins
->rex
& 7) << 5);
1615 bytes
[2] = ((ins
->rex
& REX_W
) << (7-3)) |
1616 ((~ins
->drexdst
& 15)<< 3) | (ins
->vex_wlp
& 07);
1617 out(offset
, segment
, &bytes
, OUT_RAWDATA
, 3, NO_SEG
, NO_SEG
);
1621 bytes
[1] = ((~ins
->rex
& REX_R
) << (7-2)) |
1622 ((~ins
->drexdst
& 15) << 3) | (ins
->vex_wlp
& 07);
1623 out(offset
, segment
, &bytes
, OUT_RAWDATA
, 2, NO_SEG
, NO_SEG
);
1635 if (bits
== 32 && !has_prefix(ins
, PPS_ASIZE
, P_A16
)) {
1637 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1644 if (bits
!= 32 && !has_prefix(ins
, PPS_ASIZE
, P_A32
)) {
1646 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1668 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1677 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1692 *bytes
= *codes
++ ^ condval
[ins
->condition
];
1693 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1702 *bytes
= c
- 0332 + 0xF2;
1703 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1708 if (ins
->rex
& REX_R
) {
1710 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1713 ins
->rex
&= ~(REX_L
|REX_R
);
1724 if (ins
->oprs
[0].segment
!= NO_SEG
)
1725 errfunc(ERR_PANIC
, "non-constant BSS size in pass two");
1727 int64_t size
= ins
->oprs
[0].offset
;
1729 out(offset
, segment
, NULL
,
1730 OUT_RESERVE
, size
, NO_SEG
, NO_SEG
);
1740 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1746 bytes
[0] = c
- 0362 + 0xf2;
1747 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1757 *bytes
= c
- 0366 + 0x66;
1758 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1768 *bytes
= bits
== 16 ? 3 : 5;
1769 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1773 default: /* can't do it by 'case' statements */
1774 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1783 /* pick rfield from operand b */
1784 rflags
= regflag(&ins
->oprs
[c
& 7]);
1785 rfield
= nasm_regvals
[ins
->oprs
[c
& 7].basereg
];
1787 /* rfield is constant */
1793 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1794 ins
->addr_size
, rfield
, rflags
)) {
1795 errfunc(ERR_NONFATAL
, "invalid effective address");
1800 *p
++ = ea_data
.modrm
;
1801 if (ea_data
.sib_present
)
1804 /* DREX suffixes come between the SIB and the displacement */
1805 if (ins
->rex
& REX_D
) {
1807 (ins
->drexdst
<< 4) |
1808 (ins
->rex
& REX_OC
? 0x08 : 0) |
1809 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1814 out(offset
, segment
, bytes
, OUT_RAWDATA
, s
, NO_SEG
, NO_SEG
);
1817 * Make sure the address gets the right offset in case
1818 * the line breaks in the .lst file (BR 1197827)
1823 switch (ea_data
.bytes
) {
1827 if (ins
->oprs
[(c
>> 3) & 7].segment
!= NO_SEG
) {
1828 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1829 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1830 ins
->oprs
[(c
>> 3) & 7].segment
,
1831 ins
->oprs
[(c
>> 3) & 7].wrt
);
1833 *bytes
= ins
->oprs
[(c
>> 3) & 7].offset
;
1834 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1,
1842 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1843 warn_overflow(ea_data
.bytes
, opx
);
1846 data
-= insn_end
- (offset
+ea_data
.bytes
);
1851 out(offset
, segment
, &data
, type
, ea_data
.bytes
,
1852 ins
->oprs
[(c
>> 3) & 7].segment
,
1853 ins
->oprs
[(c
>> 3) & 7].wrt
);
1858 errfunc(ERR_PANIC
, "internal instruction table corrupt"
1859 ": instruction code 0x%02X given", c
);
1865 static int32_t regflag(const operand
* o
)
1867 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1868 errfunc(ERR_PANIC
, "invalid operand passed to regflag()");
1870 return nasm_reg_flags
[o
->basereg
];
1873 static int32_t regval(const operand
* o
)
1875 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1876 errfunc(ERR_PANIC
, "invalid operand passed to regval()");
1878 return nasm_regvals
[o
->basereg
];
1881 static int op_rexflags(const operand
* o
, int mask
)
1886 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1887 errfunc(ERR_PANIC
, "invalid operand passed to op_rexflags()");
1890 flags
= nasm_reg_flags
[o
->basereg
];
1891 val
= nasm_regvals
[o
->basereg
];
1893 return rexflags(val
, flags
, mask
);
1896 static int rexflags(int val
, int32_t flags
, int mask
)
1901 rex
|= REX_B
|REX_X
|REX_R
;
1904 if (!(REG_HIGH
& ~flags
)) /* AH, CH, DH, BH */
1906 else if (!(REG8
& ~flags
) && val
>= 4) /* SPL, BPL, SIL, DIL */
1912 static int matches(const struct itemplate
*itemp
, insn
* instruction
, int bits
)
1914 int i
, size
[MAX_OPERANDS
], asize
, oprs
, ret
;
1921 if (itemp
->opcode
!= instruction
->opcode
)
1925 * Count the operands
1927 if (itemp
->operands
!= instruction
->operands
)
1931 * Check that no spurious colons or TOs are present
1933 for (i
= 0; i
< itemp
->operands
; i
++)
1934 if (instruction
->oprs
[i
].type
& ~itemp
->opd
[i
] & (COLON
| TO
))
1938 * Process size flags
1940 if (itemp
->flags
& IF_ARMASK
) {
1941 memset(size
, 0, sizeof size
);
1943 i
= ((itemp
->flags
& IF_ARMASK
) >> IF_ARSHFT
) - 1;
1945 switch (itemp
->flags
& IF_SMASK
) {
1982 switch (itemp
->flags
& IF_SMASK
) {
2017 for (i
= 0; i
< MAX_OPERANDS
; i
++)
2022 * Check that the operand flags all match up
2024 for (i
= 0; i
< itemp
->operands
; i
++) {
2025 int32_t type
= instruction
->oprs
[i
].type
;
2026 if (!(type
& SIZE_MASK
))
2029 if (itemp
->opd
[i
] & SAME_AS
) {
2030 int j
= itemp
->opd
[i
] & ~SAME_AS
;
2031 if (type
!= instruction
->oprs
[j
].type
||
2032 instruction
->oprs
[i
].basereg
!= instruction
->oprs
[j
].basereg
)
2034 } else if (itemp
->opd
[i
] & ~type
||
2035 ((itemp
->opd
[i
] & SIZE_MASK
) &&
2036 ((itemp
->opd
[i
] ^ type
) & SIZE_MASK
))) {
2037 if ((itemp
->opd
[i
] & ~type
& ~SIZE_MASK
) ||
2046 * Check operand sizes
2048 if (itemp
->flags
& (IF_SM
| IF_SM2
)) {
2049 oprs
= (itemp
->flags
& IF_SM2
? 2 : itemp
->operands
);
2051 for (i
= 0; i
< oprs
; i
++) {
2052 if ((asize
= itemp
->opd
[i
] & SIZE_MASK
) != 0) {
2054 for (j
= 0; j
< oprs
; j
++)
2060 oprs
= itemp
->operands
;
2063 for (i
= 0; i
< itemp
->operands
; i
++) {
2064 if (!(itemp
->opd
[i
] & SIZE_MASK
) &&
2065 (instruction
->oprs
[i
].type
& SIZE_MASK
& ~size
[i
]))
2070 * Check template is okay at the set cpu level
2072 if (((itemp
->flags
& IF_PLEVEL
) > cpu
))
2076 * Check if instruction is available in long mode
2078 if ((itemp
->flags
& IF_NOLONG
) && (bits
== 64))
2082 * Check if special handling needed for Jumps
2084 if ((uint8_t)(itemp
->code
[0]) >= 0370)
2090 static ea
*process_ea(operand
* input
, ea
* output
, int bits
,
2091 int addrbits
, int rfield
, int32_t rflags
)
2093 bool forw_ref
= !!(input
->opflags
& OPFLAG_FORWARD
);
2095 output
->rip
= false;
2097 /* REX flags for the rfield operand */
2098 output
->rex
|= rexflags(rfield
, rflags
, REX_R
|REX_P
|REX_W
|REX_H
);
2100 if (!(REGISTER
& ~input
->type
)) { /* register direct */
2104 if (input
->basereg
< EXPR_REG_START
/* Verify as Register */
2105 || input
->basereg
>= REG_ENUM_LIMIT
)
2108 i
= nasm_regvals
[input
->basereg
];
2111 return NULL
; /* Invalid EA register */
2113 output
->rex
|= op_rexflags(input
, REX_B
|REX_P
|REX_W
|REX_H
);
2115 output
->sib_present
= false; /* no SIB necessary */
2116 output
->bytes
= 0; /* no offset necessary either */
2117 output
->modrm
= 0xC0 | ((rfield
& 7) << 3) | (i
& 7);
2118 } else { /* it's a memory reference */
2119 if (input
->basereg
== -1
2120 && (input
->indexreg
== -1 || input
->scale
== 0)) {
2121 /* it's a pure offset */
2122 if (bits
== 64 && (~input
->type
& IP_REL
)) {
2123 int scale
, index
, base
;
2124 output
->sib_present
= true;
2128 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
2130 output
->modrm
= 4 | ((rfield
& 7) << 3);
2131 output
->rip
= false;
2133 output
->sib_present
= false;
2134 output
->bytes
= (addrbits
!= 16 ? 4 : 2);
2135 output
->modrm
= (addrbits
!= 16 ? 5 : 6) | ((rfield
& 7) << 3);
2136 output
->rip
= bits
== 64;
2138 } else { /* it's an indirection */
2139 int i
= input
->indexreg
, b
= input
->basereg
, s
= input
->scale
;
2140 int32_t o
= input
->offset
, seg
= input
->segment
;
2141 int hb
= input
->hintbase
, ht
= input
->hinttype
;
2144 int32_t ix
, bx
; /* register flags */
2147 i
= -1; /* make this easy, at least */
2149 if (i
>= EXPR_REG_START
&& i
< REG_ENUM_LIMIT
) {
2150 it
= nasm_regvals
[i
];
2151 ix
= nasm_reg_flags
[i
];
2157 if (b
>= EXPR_REG_START
&& b
< REG_ENUM_LIMIT
) {
2158 bt
= nasm_regvals
[b
];
2159 bx
= nasm_reg_flags
[b
];
2165 /* check for a 32/64-bit memory reference... */
2166 if ((ix
|bx
) & (BITS32
|BITS64
)) {
2167 /* it must be a 32/64-bit memory reference. Firstly we have
2168 * to check that all registers involved are type E/Rxx. */
2169 int32_t sok
= BITS32
|BITS64
;
2172 if (!(REG64
& ~ix
) || !(REG32
& ~ix
))
2180 return NULL
; /* Invalid register */
2181 if (~sok
& bx
& SIZE_MASK
)
2182 return NULL
; /* Invalid size */
2186 /* While we're here, ensure the user didn't specify
2188 if (input
->disp_size
== 16 || input
->disp_size
== 64)
2191 if (addrbits
== 16 ||
2192 (addrbits
== 32 && !(sok
& BITS32
)) ||
2193 (addrbits
== 64 && !(sok
& BITS64
)))
2196 /* now reorganize base/index */
2197 if (s
== 1 && bt
!= it
&& bt
!= -1 && it
!= -1 &&
2198 ((hb
== b
&& ht
== EAH_NOTBASE
)
2199 || (hb
== i
&& ht
== EAH_MAKEBASE
))) {
2200 /* swap if hints say so */
2201 t
= bt
, bt
= it
, it
= t
;
2202 t
= bx
, bx
= ix
, ix
= t
;
2204 if (bt
== it
) /* convert EAX+2*EAX to 3*EAX */
2205 bt
= -1, bx
= 0, s
++;
2206 if (bt
== -1 && s
== 1 && !(hb
== it
&& ht
== EAH_NOTBASE
)) {
2207 /* make single reg base, unless hint */
2208 bt
= it
, bx
= ix
, it
= -1, ix
= 0;
2210 if (((s
== 2 && it
!= REG_NUM_ESP
2211 && !(input
->eaflags
& EAF_TIMESTWO
)) || s
== 3
2212 || s
== 5 || s
== 9) && bt
== -1)
2213 bt
= it
, bx
= ix
, s
--; /* convert 3*EAX to EAX+2*EAX */
2214 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
2215 && (input
->eaflags
& EAF_TIMESTWO
))
2216 it
= bt
, ix
= bx
, bt
= -1, bx
= 0, s
= 1;
2217 /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */
2218 if (s
== 1 && it
== REG_NUM_ESP
) {
2219 /* swap ESP into base if scale is 1 */
2220 t
= it
, it
= bt
, bt
= t
;
2221 t
= ix
, ix
= bx
, bx
= t
;
2223 if (it
== REG_NUM_ESP
2224 || (s
!= 1 && s
!= 2 && s
!= 4 && s
!= 8 && it
!= -1))
2225 return NULL
; /* wrong, for various reasons */
2227 output
->rex
|= rexflags(it
, ix
, REX_X
);
2228 output
->rex
|= rexflags(bt
, bx
, REX_B
);
2230 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
) {
2239 if (rm
!= REG_NUM_EBP
&& o
== 0 &&
2240 seg
== NO_SEG
&& !forw_ref
&&
2242 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2244 else if (input
->eaflags
& EAF_BYTEOFFS
||
2245 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2247 && !(input
->eaflags
& EAF_WORDOFFS
)))
2253 output
->sib_present
= false;
2254 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
2255 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
2258 int mod
, scale
, index
, base
;
2278 default: /* then what the smeg is it? */
2279 return NULL
; /* panic */
2287 if (base
!= REG_NUM_EBP
&& o
== 0 &&
2288 seg
== NO_SEG
&& !forw_ref
&&
2290 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2292 else if (input
->eaflags
& EAF_BYTEOFFS
||
2293 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2295 && !(input
->eaflags
& EAF_WORDOFFS
)))
2301 output
->sib_present
= true;
2302 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
2303 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | 4;
2304 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
2306 } else { /* it's 16-bit */
2309 /* check for 64-bit long mode */
2313 /* check all registers are BX, BP, SI or DI */
2314 if ((b
!= -1 && b
!= R_BP
&& b
!= R_BX
&& b
!= R_SI
2315 && b
!= R_DI
) || (i
!= -1 && i
!= R_BP
&& i
!= R_BX
2316 && i
!= R_SI
&& i
!= R_DI
))
2319 /* ensure the user didn't specify DWORD/QWORD */
2320 if (input
->disp_size
== 32 || input
->disp_size
== 64)
2323 if (s
!= 1 && i
!= -1)
2324 return NULL
; /* no can do, in 16-bit EA */
2325 if (b
== -1 && i
!= -1) {
2330 if ((b
== R_SI
|| b
== R_DI
) && i
!= -1) {
2335 /* have BX/BP as base, SI/DI index */
2337 return NULL
; /* shouldn't ever happen, in theory */
2338 if (i
!= -1 && b
!= -1 &&
2339 (i
== R_BP
|| i
== R_BX
|| b
== R_SI
|| b
== R_DI
))
2340 return NULL
; /* invalid combinations */
2341 if (b
== -1) /* pure offset: handled above */
2342 return NULL
; /* so if it gets to here, panic! */
2346 switch (i
* 256 + b
) {
2347 case R_SI
* 256 + R_BX
:
2350 case R_DI
* 256 + R_BX
:
2353 case R_SI
* 256 + R_BP
:
2356 case R_DI
* 256 + R_BP
:
2374 if (rm
== -1) /* can't happen, in theory */
2375 return NULL
; /* so panic if it does */
2377 if (o
== 0 && seg
== NO_SEG
&& !forw_ref
&& rm
!= 6 &&
2378 !(input
->eaflags
& (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2380 else if (input
->eaflags
& EAF_BYTEOFFS
||
2381 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2383 && !(input
->eaflags
& EAF_WORDOFFS
)))
2388 output
->sib_present
= false; /* no SIB - it's 16-bit */
2389 output
->bytes
= mod
; /* bytes of offset needed */
2390 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
2395 output
->size
= 1 + output
->sib_present
+ output
->bytes
;
2399 static void add_asp(insn
*ins
, int addrbits
)
2404 valid
= (addrbits
== 64) ? 64|32 : 32|16;
2406 switch (ins
->prefixes
[PPS_ASIZE
]) {
2417 valid
&= (addrbits
== 32) ? 16 : 32;
2423 for (j
= 0; j
< ins
->operands
; j
++) {
2424 if (!(MEMORY
& ~ins
->oprs
[j
].type
)) {
2427 /* Verify as Register */
2428 if (ins
->oprs
[j
].indexreg
< EXPR_REG_START
2429 || ins
->oprs
[j
].indexreg
>= REG_ENUM_LIMIT
)
2432 i
= nasm_reg_flags
[ins
->oprs
[j
].indexreg
];
2434 /* Verify as Register */
2435 if (ins
->oprs
[j
].basereg
< EXPR_REG_START
2436 || ins
->oprs
[j
].basereg
>= REG_ENUM_LIMIT
)
2439 b
= nasm_reg_flags
[ins
->oprs
[j
].basereg
];
2441 if (ins
->oprs
[j
].scale
== 0)
2445 int ds
= ins
->oprs
[j
].disp_size
;
2446 if ((addrbits
!= 64 && ds
> 8) ||
2447 (addrbits
== 64 && ds
== 16))
2467 if (valid
& addrbits
) {
2468 ins
->addr_size
= addrbits
;
2469 } else if (valid
& ((addrbits
== 32) ? 16 : 32)) {
2470 /* Add an address size prefix */
2471 enum prefixes pref
= (addrbits
== 32) ? P_A16
: P_A32
;
2472 ins
->prefixes
[PPS_ASIZE
] = pref
;
2473 ins
->addr_size
= (addrbits
== 32) ? 16 : 32;
2476 errfunc(ERR_NONFATAL
, "impossible combination of address sizes");
2477 ins
->addr_size
= addrbits
; /* Error recovery */
2480 defdisp
= ins
->addr_size
== 16 ? 16 : 32;
2482 for (j
= 0; j
< ins
->operands
; j
++) {
2483 if (!(MEM_OFFS
& ~ins
->oprs
[j
].type
) &&
2484 (ins
->oprs
[j
].disp_size
? ins
->oprs
[j
].disp_size
: defdisp
)
2485 != ins
->addr_size
) {
2486 /* mem_offs sizes must match the address size; if not,
2487 strip the MEM_OFFS bit and match only EA instructions */
2488 ins
->oprs
[j
].type
&= ~(MEM_OFFS
& ~MEMORY
);