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 0..3.
50 * \173\xab - the register number from operand a in bits 7..4, with
51 * the value b in bits 0..3.
52 * \2ab - a ModRM, calculated on EA in operand a, with the spare
53 * field equal to digit b.
54 * \250..\253 - same as \150..\153, except warn if the 64-bit operand
55 * is not equal to the truncated and sign-extended 32-bit
56 * operand; used for 32-bit immediates in 64-bit mode.
57 * \260..\263 - this instruction uses VEX rather than REX, with the
58 * V field taken from operand 0..3.
59 * \270 - this instruction uses VEX rather than REX, with the
60 * V field set to 1111b.
62 * VEX prefixes are followed by the sequence:
63 * \mm\wlp where mm is the M field; and wlp is:
67 * ww = 2 for W used as REX.W
69 * \310 - indicates fixed 16-bit address size, i.e. optional 0x67.
70 * \311 - indicates fixed 32-bit address size, i.e. optional 0x67.
71 * \312 - (disassembler only) marker on LOOP, LOOPxx instructions.
72 * \313 - indicates fixed 64-bit address size, 0x67 invalid.
73 * \314 - (disassembler only) invalid with REX.B
74 * \315 - (disassembler only) invalid with REX.X
75 * \316 - (disassembler only) invalid with REX.R
76 * \317 - (disassembler only) invalid with REX.W
77 * \320 - indicates fixed 16-bit operand size, i.e. optional 0x66.
78 * \321 - indicates fixed 32-bit operand size, i.e. optional 0x66.
79 * \322 - indicates that this instruction is only valid when the
80 * operand size is the default (instruction to disassembler,
81 * generates no code in the assembler)
82 * \323 - indicates fixed 64-bit operand size, REX on extensions only.
83 * \324 - indicates 64-bit operand size requiring REX prefix.
84 * \330 - a literal byte follows in the code stream, to be added
85 * to the condition code value of the instruction.
86 * \331 - instruction not valid with REP prefix. Hint for
87 * disassembler only; for SSE instructions.
88 * \332 - REP prefix (0xF2 byte) used as opcode extension.
89 * \333 - REP prefix (0xF3 byte) used as opcode extension.
90 * \334 - LOCK prefix used instead of REX.R
91 * \335 - disassemble a rep (0xF3 byte) prefix as repe not rep.
92 * \340 - reserve <operand 0> bytes of uninitialized storage.
93 * Operand 0 had better be a segmentless constant.
94 * \360 - no SSE prefix (== \364\331)
95 * \361 - 66 SSE prefix (== \366\331)
96 * \362 - F2 SSE prefix (== \364\332)
97 * \363 - F3 SSE prefix (== \364\333)
98 * \364 - operand-size prefix (0x66) not permitted
99 * \365 - address-size prefix (0x67) not permitted
100 * \366 - operand-size prefix (0x66) used as opcode extension
101 * \367 - address-size prefix (0x67) used as opcode extension
102 * \370,\371,\372 - match only if operand 0 meets byte jump criteria.
103 * 370 is used for Jcc, 371 is used for JMP.
104 * \373 - assemble 0x03 if bits==16, 0x05 if bits==32;
105 * used for conditional jump over longer jump
108 #include "compiler.h"
112 #include <inttypes.h>
116 #include "assemble.h"
121 /* Initialized to zero by the C standard */
122 static const uint8_t const_zero_buf
[256];
125 int sib_present
; /* is a SIB byte necessary? */
126 int bytes
; /* # of bytes of offset needed */
127 int size
; /* lazy - this is sib+bytes+1 */
128 uint8_t modrm
, sib
, rex
, rip
; /* the bytes themselves */
131 static uint32_t cpu
; /* cpu level received from nasm.c */
132 static efunc errfunc
;
133 static struct ofmt
*outfmt
;
134 static ListGen
*list
;
136 static int64_t calcsize(int32_t, int64_t, int, insn
*, const uint8_t *);
137 static void gencode(int32_t, int64_t, int, insn
*, const uint8_t *, int64_t);
138 static int matches(const struct itemplate
*, insn
*, int bits
);
139 static int32_t regflag(const operand
*);
140 static int32_t regval(const operand
*);
141 static int rexflags(int, int32_t, int);
142 static int op_rexflags(const operand
*, int);
143 static ea
*process_ea(operand
*, ea
*, int, int, int, int32_t, int);
144 static void add_asp(insn
*, int);
146 static int has_prefix(insn
* ins
, enum prefix_pos pos
, enum prefixes prefix
)
148 return ins
->prefixes
[pos
] == prefix
;
151 static void assert_no_prefix(insn
* ins
, enum prefix_pos pos
)
153 if (ins
->prefixes
[pos
])
154 errfunc(ERR_NONFATAL
, "invalid %s prefix",
155 prefix_name(ins
->prefixes
[pos
]));
158 static const char *size_name(int size
)
180 static void warn_overflow(int size
, int64_t data
)
183 int64_t lim
= ((int64_t)1 << (size
*8))-1;
185 if (data
< ~lim
|| data
> lim
)
186 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
187 "%s data exceeds bounds", size_name(size
));
191 * This routine wrappers the real output format's output routine,
192 * in order to pass a copy of the data off to the listing file
193 * generator at the same time.
195 static void out(int64_t offset
, int32_t segto
, const void *data
,
196 enum out_type type
, uint64_t size
,
197 int32_t segment
, int32_t wrt
)
199 static int32_t lineno
= 0; /* static!!! */
200 static char *lnfname
= NULL
;
203 if (type
== OUT_ADDRESS
&& segment
== NO_SEG
&& wrt
== NO_SEG
) {
205 * This is a non-relocated address, and we're going to
206 * convert it into RAWDATA format.
211 errfunc(ERR_PANIC
, "OUT_ADDRESS with size > 8");
215 WRITEADDR(q
, *(int64_t *)data
, size
);
220 list
->output(offset
, data
, type
, size
);
223 * this call to src_get determines when we call the
224 * debug-format-specific "linenum" function
225 * it updates lineno and lnfname to the current values
226 * returning 0 if "same as last time", -2 if lnfname
227 * changed, and the amount by which lineno changed,
228 * if it did. thus, these variables must be static
231 if (src_get(&lineno
, &lnfname
)) {
232 outfmt
->current_dfmt
->linenum(lnfname
, lineno
, segto
);
235 outfmt
->output(segto
, data
, type
, size
, segment
, wrt
);
238 static int jmp_match(int32_t segment
, int64_t offset
, int bits
,
239 insn
* ins
, const uint8_t *code
)
244 if (c
!= 0370 && c
!= 0371)
246 if (ins
->oprs
[0].opflags
& OPFLAG_FORWARD
) {
247 if ((optimizing
< 0 || (ins
->oprs
[0].type
& STRICT
))
251 return (pass0
== 0); /* match a forward reference */
253 isize
= calcsize(segment
, offset
, bits
, ins
, code
);
254 if (ins
->oprs
[0].segment
!= segment
)
256 isize
= ins
->oprs
[0].offset
- offset
- isize
; /* isize is now the delta */
257 if (isize
>= -128L && isize
<= 127L)
258 return 1; /* it is byte size */
263 int64_t assemble(int32_t segment
, int64_t offset
, int bits
, uint32_t cp
,
264 insn
* instruction
, struct ofmt
*output
, efunc error
,
267 const struct itemplate
*temp
;
272 int64_t start
= offset
;
273 int64_t wsize
= 0; /* size for DB etc. */
275 errfunc
= error
; /* to pass to other functions */
277 outfmt
= output
; /* likewise */
278 list
= listgen
; /* and again */
280 switch (instruction
->opcode
) {
310 int32_t t
= instruction
->times
;
313 "instruction->times < 0 (%ld) in assemble()", t
);
315 while (t
--) { /* repeat TIMES times */
316 for (e
= instruction
->eops
; e
; e
= e
->next
) {
317 if (e
->type
== EOT_DB_NUMBER
) {
319 if (e
->segment
!= NO_SEG
)
320 errfunc(ERR_NONFATAL
,
321 "one-byte relocation attempted");
323 uint8_t out_byte
= e
->offset
;
324 out(offset
, segment
, &out_byte
,
325 OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
327 } else if (wsize
> 8) {
328 errfunc(ERR_NONFATAL
,
329 "integer supplied to a DT, DO or DY"
332 out(offset
, segment
, &e
->offset
,
333 OUT_ADDRESS
, wsize
, e
->segment
, e
->wrt
);
335 } else if (e
->type
== EOT_DB_STRING
) {
338 out(offset
, segment
, e
->stringval
,
339 OUT_RAWDATA
, e
->stringlen
, NO_SEG
, NO_SEG
);
340 align
= e
->stringlen
% wsize
;
343 align
= wsize
- align
;
344 out(offset
, segment
, const_zero_buf
,
345 OUT_RAWDATA
, align
, NO_SEG
, NO_SEG
);
347 offset
+= e
->stringlen
+ align
;
350 if (t
> 0 && t
== instruction
->times
- 1) {
352 * Dummy call to list->output to give the offset to the
355 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
356 list
->uplevel(LIST_TIMES
);
359 if (instruction
->times
> 1)
360 list
->downlevel(LIST_TIMES
);
361 return offset
- start
;
364 if (instruction
->opcode
== I_INCBIN
) {
365 static char fname
[FILENAME_MAX
];
368 char *prefix
= "", *combine
;
369 char **pPrevPath
= NULL
;
371 len
= FILENAME_MAX
- 1;
372 if (len
> instruction
->eops
->stringlen
)
373 len
= instruction
->eops
->stringlen
;
374 strncpy(fname
, instruction
->eops
->stringval
, len
);
377 while (1) { /* added by alexfru: 'incbin' uses include paths */
378 combine
= nasm_malloc(strlen(prefix
) + len
+ 1);
379 strcpy(combine
, prefix
);
380 strcat(combine
, fname
);
382 if ((fp
= fopen(combine
, "rb")) != NULL
) {
388 pPrevPath
= pp_get_include_path_ptr(pPrevPath
);
389 if (pPrevPath
== NULL
)
395 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
397 else if (fseek(fp
, 0L, SEEK_END
) < 0)
398 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
401 static char buf
[2048];
402 int32_t t
= instruction
->times
;
406 if (instruction
->eops
->next
) {
407 base
= instruction
->eops
->next
->offset
;
409 if (instruction
->eops
->next
->next
&&
410 len
> instruction
->eops
->next
->next
->offset
)
411 len
= instruction
->eops
->next
->next
->offset
;
414 * Dummy call to list->output to give the offset to the
417 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
418 list
->uplevel(LIST_INCBIN
);
422 fseek(fp
, base
, SEEK_SET
);
426 fread(buf
, 1, (l
> (int32_t) sizeof(buf
) ? (int32_t) sizeof(buf
) : l
),
430 * This shouldn't happen unless the file
431 * actually changes while we are reading
435 "`incbin': unexpected EOF while"
436 " reading file `%s'", fname
);
437 t
= 0; /* Try to exit cleanly */
440 out(offset
, segment
, buf
, OUT_RAWDATA
, m
,
445 list
->downlevel(LIST_INCBIN
);
446 if (instruction
->times
> 1) {
448 * Dummy call to list->output to give the offset to the
451 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
452 list
->uplevel(LIST_TIMES
);
453 list
->downlevel(LIST_TIMES
);
456 return instruction
->times
* len
;
458 return 0; /* if we're here, there's an error */
461 /* Check to see if we need an address-size prefix */
462 add_asp(instruction
, bits
);
466 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++){
467 int m
= matches(temp
, instruction
, bits
);
470 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
472 if (m
== 100) { /* matches! */
473 const uint8_t *codes
= temp
->code
;
474 int64_t insn_size
= calcsize(segment
, offset
, bits
,
476 itimes
= instruction
->times
;
477 if (insn_size
< 0) /* shouldn't be, on pass two */
478 error(ERR_PANIC
, "errors made it through from pass one");
481 for (j
= 0; j
< MAXPREFIX
; j
++) {
483 switch (instruction
->prefixes
[j
]) {
499 "cs segment base generated, but will be ignored in 64-bit mode");
506 "ds segment base generated, but will be ignored in 64-bit mode");
513 "es segment base generated, but will be ignored in 64-bit mode");
526 "ss segment base generated, but will be ignored in 64-bit mode");
533 "segr6 and segr7 cannot be used as prefixes");
538 "16-bit addressing is not supported "
540 } else if (bits
!= 16)
550 "64-bit addressing is only supported "
574 error(ERR_PANIC
, "invalid instruction prefix");
577 out(offset
, segment
, &c
, OUT_RAWDATA
, 1,
582 insn_end
= offset
+ insn_size
;
583 gencode(segment
, offset
, bits
, instruction
, codes
,
586 if (itimes
> 0 && itimes
== instruction
->times
- 1) {
588 * Dummy call to list->output to give the offset to the
591 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
592 list
->uplevel(LIST_TIMES
);
595 if (instruction
->times
> 1)
596 list
->downlevel(LIST_TIMES
);
597 return offset
- start
;
598 } else if (m
> 0 && m
> size_prob
) {
604 if (temp
->opcode
== -1) { /* didn't match any instruction */
607 error(ERR_NONFATAL
, "operation size not specified");
610 error(ERR_NONFATAL
, "mismatch in operand sizes");
613 error(ERR_NONFATAL
, "no instruction for this cpu level");
616 error(ERR_NONFATAL
, "instruction not supported in 64-bit mode");
620 "invalid combination of opcode and operands");
627 int64_t insn_size(int32_t segment
, int64_t offset
, int bits
, uint32_t cp
,
628 insn
* instruction
, efunc error
)
630 const struct itemplate
*temp
;
632 errfunc
= error
; /* to pass to other functions */
635 if (instruction
->opcode
== -1)
638 if (instruction
->opcode
== I_DB
|| instruction
->opcode
== I_DW
||
639 instruction
->opcode
== I_DD
|| instruction
->opcode
== I_DQ
||
640 instruction
->opcode
== I_DT
|| instruction
->opcode
== I_DO
||
641 instruction
->opcode
== I_DY
) {
643 int32_t isize
, osize
, wsize
= 0; /* placate gcc */
646 switch (instruction
->opcode
) {
672 for (e
= instruction
->eops
; e
; e
= e
->next
) {
676 if (e
->type
== EOT_DB_NUMBER
)
678 else if (e
->type
== EOT_DB_STRING
)
679 osize
= e
->stringlen
;
681 align
= (-osize
) % wsize
;
684 isize
+= osize
+ align
;
686 return isize
* instruction
->times
;
689 if (instruction
->opcode
== I_INCBIN
) {
690 char fname
[FILENAME_MAX
];
693 char *prefix
= "", *combine
;
694 char **pPrevPath
= NULL
;
696 len
= FILENAME_MAX
- 1;
697 if (len
> instruction
->eops
->stringlen
)
698 len
= instruction
->eops
->stringlen
;
699 strncpy(fname
, instruction
->eops
->stringval
, len
);
702 /* added by alexfru: 'incbin' uses include paths */
704 combine
= nasm_malloc(strlen(prefix
) + len
+ 1);
705 strcpy(combine
, prefix
);
706 strcat(combine
, fname
);
708 if ((fp
= fopen(combine
, "rb")) != NULL
) {
714 pPrevPath
= pp_get_include_path_ptr(pPrevPath
);
715 if (pPrevPath
== NULL
)
721 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
723 else if (fseek(fp
, 0L, SEEK_END
) < 0)
724 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
729 if (instruction
->eops
->next
) {
730 len
-= instruction
->eops
->next
->offset
;
731 if (instruction
->eops
->next
->next
&&
732 len
> instruction
->eops
->next
->next
->offset
) {
733 len
= instruction
->eops
->next
->next
->offset
;
736 return instruction
->times
* len
;
738 return 0; /* if we're here, there's an error */
741 /* Check to see if we need an address-size prefix */
742 add_asp(instruction
, bits
);
744 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++) {
745 int m
= matches(temp
, instruction
, bits
);
747 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
750 /* we've matched an instruction. */
752 const uint8_t *codes
= temp
->code
;
755 isize
= calcsize(segment
, offset
, bits
, instruction
, codes
);
758 for (j
= 0; j
< MAXPREFIX
; j
++) {
759 switch (instruction
->prefixes
[j
]) {
785 return isize
* instruction
->times
;
788 return -1; /* didn't match any instruction */
791 static bool possible_sbyte(insn
* ins
, int op
)
793 return !(ins
->forw_ref
&& ins
->oprs
[op
].opflags
) &&
795 !(ins
->oprs
[op
].type
& STRICT
) &&
796 ins
->oprs
[op
].wrt
== NO_SEG
&& ins
->oprs
[op
].segment
== NO_SEG
;
799 /* check that opn[op] is a signed byte of size 16 or 32 */
800 static bool is_sbyte16(insn
* ins
, int op
)
804 if (!possible_sbyte(ins
, op
))
807 v
= ins
->oprs
[op
].offset
;
808 return v
>= -128 && v
<= 127;
811 static bool is_sbyte32(insn
* ins
, int op
)
815 if (!possible_sbyte(ins
, op
))
818 v
= ins
->oprs
[op
].offset
;
819 return v
>= -128 && v
<= 127;
822 /* check that opn[op] is a signed byte of size 32; warn if this is not
823 the original value when extended to 64 bits */
824 static bool is_sbyte64(insn
* ins
, int op
)
829 /* dead in the water on forward reference or External */
830 if (!possible_sbyte(ins
, op
))
833 v64
= ins
->oprs
[op
].offset
;
836 warn_overflow(32, v64
);
838 return v32
>= -128 && v32
<= 127;
840 static int64_t calcsize(int32_t segment
, int64_t offset
, int bits
,
841 insn
* ins
, const uint8_t *codes
)
848 ins
->rex
= 0; /* Ensure REX is reset */
850 if (ins
->prefixes
[PPS_OSIZE
] == P_O64
)
853 (void)segment
; /* Don't warn that this parameter is unused */
854 (void)offset
; /* Don't warn that this parameter is unused */
858 opx
= &ins
->oprs
[c
& 3];
863 codes
+= c
, length
+= c
;
876 op_rexflags(opx
, REX_B
|REX_H
|REX_P
|REX_W
);
907 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
908 length
+= (opx
->type
& BITS16
) ? 2 : 4;
910 length
+= (bits
== 16) ? 2 : 4;
922 length
+= ins
->addr_size
>> 3;
934 length
+= 8; /* MOV reg64/imm */
946 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
947 length
+= (opx
->type
& BITS16
) ? 2 : 4;
949 length
+= (bits
== 16) ? 2 : 4;
967 length
+= is_sbyte16(ins
, c
& 3) ? 1 : 2;
980 length
+= is_sbyte32(ins
, c
& 3) ? 1 : 4;
995 ins
->drexdst
= regval(opx
);
1002 ins
->rex
|= REX_D
|REX_OC
;
1003 ins
->drexdst
= regval(opx
);
1016 length
+= is_sbyte64(ins
, c
& 3) ? 1 : 4;
1024 ins
->drexdst
= regval(opx
);
1025 ins
->vex_m
= *codes
++;
1026 ins
->vex_wlp
= *codes
++;
1032 ins
->vex_m
= *codes
++;
1033 ins
->vex_wlp
= *codes
++;
1043 length
+= (bits
!= 16) && !has_prefix(ins
, PPS_ASIZE
, P_A16
);
1046 length
+= (bits
!= 32) && !has_prefix(ins
, PPS_ASIZE
, P_A32
);
1051 if (bits
!= 64 || has_prefix(ins
, PPS_ASIZE
, P_A16
) ||
1052 has_prefix(ins
, PPS_ASIZE
, P_A32
))
1061 length
+= (bits
!= 16);
1064 length
+= (bits
== 16);
1089 if (ins
->oprs
[0].segment
!= NO_SEG
)
1090 errfunc(ERR_NONFATAL
, "attempt to reserve non-constant"
1091 " quantity of BSS space");
1093 length
+= ins
->oprs
[0].offset
;
1116 default: /* can't do it by 'case' statements */
1117 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1121 ea_data
.rex
= 0; /* Ensure ea.REX is initially 0 */
1124 /* pick rfield from operand b */
1125 rflags
= regflag(&ins
->oprs
[c
& 7]);
1126 rfield
= nasm_regvals
[ins
->oprs
[c
& 7].basereg
];
1133 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1134 ins
->addr_size
, rfield
, rflags
, ins
->forw_ref
)) {
1135 errfunc(ERR_NONFATAL
, "invalid effective address");
1138 ins
->rex
|= ea_data
.rex
;
1139 length
+= ea_data
.size
;
1142 errfunc(ERR_PANIC
, "internal instruction table corrupt"
1143 ": instruction code 0x%02X given", c
);
1148 ins
->rex
&= rex_mask
;
1150 if (ins
->rex
& REX_V
) {
1151 int bad32
= REX_R
|REX_W
|REX_X
|REX_B
;
1153 if (ins
->rex
& REX_H
) {
1154 errfunc(ERR_NONFATAL
, "cannot use high register in vex instruction");
1157 switch (ins
->vex_wlp
& 030) {
1170 if (bits
!= 64 && ((ins
->rex
& bad32
) || ins
->drexdst
> 7)) {
1171 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1174 if (ins
->vex_m
!= 1 || (ins
->rex
& (REX_W
|REX_R
|REX_B
)))
1178 } else if (ins
->rex
& REX_D
) {
1179 if (ins
->rex
& REX_H
) {
1180 errfunc(ERR_NONFATAL
, "cannot use high register in drex instruction");
1183 if (bits
!= 64 && ((ins
->rex
& (REX_R
|REX_W
|REX_X
|REX_B
)) ||
1184 ins
->drexdst
> 7)) {
1185 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1189 } else if (ins
->rex
& REX_REAL
) {
1190 if (ins
->rex
& REX_H
) {
1191 errfunc(ERR_NONFATAL
, "cannot use high register in rex instruction");
1193 } else if (bits
== 64) {
1195 } else if ((ins
->rex
& REX_L
) &&
1196 !(ins
->rex
& (REX_P
|REX_W
|REX_X
|REX_B
)) &&
1199 assert_no_prefix(ins
, PPS_LREP
);
1202 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1210 #define EMIT_REX() \
1211 if (!(ins->rex & (REX_D|REX_V)) && (ins->rex & REX_REAL) && (bits == 64)) { \
1212 ins->rex = (ins->rex & REX_REAL)|REX_P; \
1213 out(offset, segment, &ins->rex, OUT_RAWDATA, 1, NO_SEG, NO_SEG); \
1218 static void gencode(int32_t segment
, int64_t offset
, int bits
,
1219 insn
* ins
, const uint8_t *codes
, int64_t insn_end
)
1221 static char condval
[] = { /* conditional opcodes */
1222 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
1223 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
1224 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
1230 struct operand
*opx
;
1234 opx
= &ins
->oprs
[c
& 3];
1240 out(offset
, segment
, codes
, OUT_RAWDATA
, c
, NO_SEG
, NO_SEG
);
1247 switch (ins
->oprs
[0].basereg
) {
1249 bytes
[0] = 0x0E + (c
== 0x04 ? 1 : 0);
1252 bytes
[0] = 0x1E + (c
== 0x04 ? 1 : 0);
1255 bytes
[0] = 0x06 + (c
== 0x04 ? 1 : 0);
1258 bytes
[0] = 0x16 + (c
== 0x04 ? 1 : 0);
1262 "bizarre 8086 segment register received");
1264 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1270 switch (ins
->oprs
[0].basereg
) {
1272 bytes
[0] = 0xA0 + (c
== 0x05 ? 1 : 0);
1275 bytes
[0] = 0xA8 + (c
== 0x05 ? 1 : 0);
1279 "bizarre 386 segment register received");
1281 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1290 bytes
[0] = *codes
++ + ((regval(opx
)) & 7);
1291 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1299 /* XXX: warns for legitimate optimizer actions */
1300 if (opx
->offset
< -128 || opx
->offset
> 127) {
1301 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1302 "signed 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
< -256 || opx
->offset
> 255) {
1322 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1323 "byte value exceeds bounds");
1325 if (opx
->segment
!= NO_SEG
) {
1327 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1328 opx
->segment
, opx
->wrt
);
1330 bytes
[0] = opx
->offset
;
1331 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1341 if (opx
->offset
< 0 || opx
->offset
> 255)
1342 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1343 "unsigned byte value exceeds bounds");
1344 if (opx
->segment
!= NO_SEG
) {
1346 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1347 opx
->segment
, opx
->wrt
);
1349 bytes
[0] = opx
->offset
;
1350 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1361 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1362 warn_overflow(2, data
);
1363 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1364 opx
->segment
, opx
->wrt
);
1372 if (opx
->type
& (BITS16
| BITS32
))
1373 size
= (opx
->type
& BITS16
) ? 2 : 4;
1375 size
= (bits
== 16) ? 2 : 4;
1377 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1378 warn_overflow(size
, data
);
1379 out(offset
, segment
, &data
, OUT_ADDRESS
, size
,
1380 opx
->segment
, opx
->wrt
);
1389 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1390 warn_overflow(4, data
);
1391 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1392 opx
->segment
, opx
->wrt
);
1401 size
= ins
->addr_size
>> 3;
1402 if (opx
->segment
== NO_SEG
&&
1404 warn_overflow(size
, data
);
1405 out(offset
, segment
, &data
, OUT_ADDRESS
, size
,
1406 opx
->segment
, opx
->wrt
);
1414 if (opx
->segment
!= segment
)
1415 errfunc(ERR_NONFATAL
,
1416 "short relative jump outside segment");
1417 data
= opx
->offset
- insn_end
;
1418 if (data
> 127 || data
< -128)
1419 errfunc(ERR_NONFATAL
, "short jump is out of range");
1421 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1429 data
= (int64_t)opx
->offset
;
1430 out(offset
, segment
, &data
, OUT_ADDRESS
, 8,
1431 opx
->segment
, opx
->wrt
);
1439 if (opx
->segment
!= segment
) {
1441 out(offset
, segment
, &data
,
1442 OUT_REL2ADR
, insn_end
- offset
,
1443 opx
->segment
, opx
->wrt
);
1445 data
= opx
->offset
- insn_end
;
1446 out(offset
, segment
, &data
,
1447 OUT_ADDRESS
, 2, NO_SEG
, NO_SEG
);
1456 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
1457 size
= (opx
->type
& BITS16
) ? 2 : 4;
1459 size
= (bits
== 16) ? 2 : 4;
1460 if (opx
->segment
!= segment
) {
1462 out(offset
, segment
, &data
,
1463 size
== 2 ? OUT_REL2ADR
: OUT_REL4ADR
,
1464 insn_end
- offset
, opx
->segment
, opx
->wrt
);
1466 data
= opx
->offset
- insn_end
;
1467 out(offset
, segment
, &data
,
1468 OUT_ADDRESS
, size
, NO_SEG
, NO_SEG
);
1477 if (opx
->segment
!= segment
) {
1479 out(offset
, segment
, &data
,
1480 OUT_REL4ADR
, insn_end
- offset
,
1481 opx
->segment
, opx
->wrt
);
1483 data
= opx
->offset
- insn_end
;
1484 out(offset
, segment
, &data
,
1485 OUT_ADDRESS
, 4, NO_SEG
, NO_SEG
);
1494 if (opx
->segment
== NO_SEG
)
1495 errfunc(ERR_NONFATAL
, "value referenced by FAR is not"
1498 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1499 outfmt
->segbase(1 + opx
->segment
),
1509 if (is_sbyte16(ins
, c
& 3)) {
1511 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1515 if (opx
->segment
== NO_SEG
&&
1517 warn_overflow(2, data
);
1518 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1519 opx
->segment
, opx
->wrt
);
1529 bytes
[0] = *codes
++;
1530 if (is_sbyte16(ins
, c
& 3))
1531 bytes
[0] |= 2; /* s-bit */
1532 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1541 if (is_sbyte32(ins
, c
& 3)) {
1543 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1547 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1548 opx
->segment
, opx
->wrt
);
1558 bytes
[0] = *codes
++;
1559 if (is_sbyte32(ins
, c
& 3))
1560 bytes
[0] |= 2; /* s-bit */
1561 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1577 (ins
->drexdst
<< 4) |
1578 (ins
->rex
& REX_OC
? 0x08 : 0) |
1579 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1581 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1587 opx
= &ins
->oprs
[c
>> 3];
1588 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1589 opx
= &ins
->oprs
[c
& 7];
1590 if (opx
->segment
!= NO_SEG
|| opx
->wrt
!= NO_SEG
) {
1591 errfunc(ERR_NONFATAL
,
1592 "non-absolute expression not permitted as argument %d",
1595 if (opx
->offset
& ~15) {
1596 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1597 "four-bit argument exceeds bounds");
1599 bytes
[0] |= opx
->offset
& 15;
1601 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1607 opx
= &ins
->oprs
[c
>> 4];
1608 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1610 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1619 /* is_sbyte32() is right here, we have already warned */
1620 if (is_sbyte32(ins
, c
& 3)) {
1622 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1626 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1627 opx
->segment
, opx
->wrt
);
1638 if (ins
->vex_m
!= 1 || (ins
->rex
& (REX_W
|REX_X
|REX_B
))) {
1640 bytes
[1] = ins
->vex_m
| ((~ins
->rex
& 7) << 5);
1641 bytes
[2] = ((ins
->rex
& REX_W
) << (7-3)) |
1642 ((~ins
->drexdst
& 15)<< 3) | (ins
->vex_wlp
& 07);
1643 out(offset
, segment
, &bytes
, OUT_RAWDATA
, 3, NO_SEG
, NO_SEG
);
1647 bytes
[1] = ((~ins
->rex
& REX_R
) << (7-2)) |
1648 ((~ins
->drexdst
& 15) << 3) | (ins
->vex_wlp
& 07);
1649 out(offset
, segment
, &bytes
, OUT_RAWDATA
, 2, NO_SEG
, NO_SEG
);
1661 if (bits
== 32 && !has_prefix(ins
, PPS_ASIZE
, P_A16
)) {
1663 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1670 if (bits
!= 32 && !has_prefix(ins
, PPS_ASIZE
, P_A32
)) {
1672 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1694 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1703 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1718 *bytes
= *codes
++ ^ condval
[ins
->condition
];
1719 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1728 *bytes
= c
- 0332 + 0xF2;
1729 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1734 if (ins
->rex
& REX_R
) {
1736 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1739 ins
->rex
&= ~(REX_L
|REX_R
);
1746 if (ins
->oprs
[0].segment
!= NO_SEG
)
1747 errfunc(ERR_PANIC
, "non-constant BSS size in pass two");
1749 int64_t size
= ins
->oprs
[0].offset
;
1751 out(offset
, segment
, NULL
,
1752 OUT_RESERVE
, size
, NO_SEG
, NO_SEG
);
1762 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1768 bytes
[0] = c
- 0362 + 0xf2;
1769 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1779 *bytes
= c
- 0366 + 0x66;
1780 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1790 *bytes
= bits
== 16 ? 3 : 5;
1791 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1795 default: /* can't do it by 'case' statements */
1796 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1804 /* pick rfield from operand b */
1805 rflags
= regflag(&ins
->oprs
[c
& 7]);
1806 rfield
= nasm_regvals
[ins
->oprs
[c
& 7].basereg
];
1808 /* rfield is constant */
1814 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1815 ins
->addr_size
, rfield
, rflags
, ins
->forw_ref
)) {
1816 errfunc(ERR_NONFATAL
, "invalid effective address");
1821 *p
++ = ea_data
.modrm
;
1822 if (ea_data
.sib_present
)
1825 /* DREX suffixes come between the SIB and the displacement */
1826 if (ins
->rex
& REX_D
) {
1828 (ins
->drexdst
<< 4) |
1829 (ins
->rex
& REX_OC
? 0x08 : 0) |
1830 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1835 out(offset
, segment
, bytes
, OUT_RAWDATA
, s
, NO_SEG
, NO_SEG
);
1837 switch (ea_data
.bytes
) {
1841 if (ins
->oprs
[(c
>> 3) & 7].segment
!= NO_SEG
) {
1842 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1843 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1844 ins
->oprs
[(c
>> 3) & 7].segment
,
1845 ins
->oprs
[(c
>> 3) & 7].wrt
);
1847 *bytes
= ins
->oprs
[(c
>> 3) & 7].offset
;
1848 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1,
1856 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1857 warn_overflow(ea_data
.bytes
, data
);
1858 out(offset
, segment
, &data
,
1859 ea_data
.rip
? OUT_REL4ADR
: OUT_ADDRESS
,
1861 ins
->oprs
[(c
>> 3) & 7].segment
,
1862 ins
->oprs
[(c
>> 3) & 7].wrt
);
1868 errfunc(ERR_PANIC
, "internal instruction table corrupt"
1869 ": instruction code 0x%02X given", c
);
1875 static int32_t regflag(const operand
* o
)
1877 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1878 errfunc(ERR_PANIC
, "invalid operand passed to regflag()");
1880 return nasm_reg_flags
[o
->basereg
];
1883 static int32_t regval(const operand
* o
)
1885 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1886 errfunc(ERR_PANIC
, "invalid operand passed to regval()");
1888 return nasm_regvals
[o
->basereg
];
1891 static int op_rexflags(const operand
* o
, int mask
)
1896 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1897 errfunc(ERR_PANIC
, "invalid operand passed to op_rexflags()");
1900 flags
= nasm_reg_flags
[o
->basereg
];
1901 val
= nasm_regvals
[o
->basereg
];
1903 return rexflags(val
, flags
, mask
);
1906 static int rexflags(int val
, int32_t flags
, int mask
)
1911 rex
|= REX_B
|REX_X
|REX_R
;
1914 if (!(REG_HIGH
& ~flags
)) /* AH, CH, DH, BH */
1916 else if (!(REG8
& ~flags
) && val
>= 4) /* SPL, BPL, SIL, DIL */
1922 static int matches(const struct itemplate
*itemp
, insn
* instruction
, int bits
)
1924 int i
, size
[MAX_OPERANDS
], asize
, oprs
, ret
;
1931 if (itemp
->opcode
!= instruction
->opcode
)
1935 * Count the operands
1937 if (itemp
->operands
!= instruction
->operands
)
1941 * Check that no spurious colons or TOs are present
1943 for (i
= 0; i
< itemp
->operands
; i
++)
1944 if (instruction
->oprs
[i
].type
& ~itemp
->opd
[i
] & (COLON
| TO
))
1948 * Process size flags
1950 if (itemp
->flags
& IF_ARMASK
) {
1951 memset(size
, 0, sizeof size
);
1953 i
= ((itemp
->flags
& IF_ARMASK
) >> IF_ARSHFT
) - 1;
1955 switch (itemp
->flags
& IF_SMASK
) {
1992 switch (itemp
->flags
& IF_SMASK
) {
2027 for (i
= 0; i
< MAX_OPERANDS
; i
++)
2032 * Check that the operand flags all match up
2034 for (i
= 0; i
< itemp
->operands
; i
++) {
2035 int32_t type
= instruction
->oprs
[i
].type
;
2036 if (!(type
& SIZE_MASK
))
2039 if (itemp
->opd
[i
] & SAME_AS
) {
2040 int j
= itemp
->opd
[i
] & ~SAME_AS
;
2041 if (type
!= instruction
->oprs
[j
].type
||
2042 instruction
->oprs
[i
].basereg
!= instruction
->oprs
[j
].basereg
)
2044 } else if (itemp
->opd
[i
] & ~type
||
2045 ((itemp
->opd
[i
] & SIZE_MASK
) &&
2046 ((itemp
->opd
[i
] ^ type
) & SIZE_MASK
))) {
2047 if ((itemp
->opd
[i
] & ~type
& ~SIZE_MASK
) ||
2056 * Check operand sizes
2058 if (itemp
->flags
& (IF_SM
| IF_SM2
)) {
2059 oprs
= (itemp
->flags
& IF_SM2
? 2 : itemp
->operands
);
2061 for (i
= 0; i
< oprs
; i
++) {
2062 if ((asize
= itemp
->opd
[i
] & SIZE_MASK
) != 0) {
2064 for (j
= 0; j
< oprs
; j
++)
2070 oprs
= itemp
->operands
;
2073 for (i
= 0; i
< itemp
->operands
; i
++) {
2074 if (!(itemp
->opd
[i
] & SIZE_MASK
) &&
2075 (instruction
->oprs
[i
].type
& SIZE_MASK
& ~size
[i
]))
2080 * Check template is okay at the set cpu level
2082 if (((itemp
->flags
& IF_PLEVEL
) > cpu
))
2086 * Check if instruction is available in long mode
2088 if ((itemp
->flags
& IF_NOLONG
) && (bits
== 64))
2092 * Check if special handling needed for Jumps
2094 if ((uint8_t)(itemp
->code
[0]) >= 0370)
2100 static ea
*process_ea(operand
* input
, ea
* output
, int bits
,
2101 int addrbits
, int rfield
, int32_t rflags
, int forw_ref
)
2103 output
->rip
= false;
2105 /* REX flags for the rfield operand */
2106 output
->rex
|= rexflags(rfield
, rflags
, REX_R
|REX_P
|REX_W
|REX_H
);
2108 if (!(REGISTER
& ~input
->type
)) { /* register direct */
2112 if (input
->basereg
< EXPR_REG_START
/* Verify as Register */
2113 || input
->basereg
>= REG_ENUM_LIMIT
)
2116 i
= nasm_regvals
[input
->basereg
];
2119 return NULL
; /* Invalid EA register */
2121 output
->rex
|= op_rexflags(input
, REX_B
|REX_P
|REX_W
|REX_H
);
2123 output
->sib_present
= false; /* no SIB necessary */
2124 output
->bytes
= 0; /* no offset necessary either */
2125 output
->modrm
= 0xC0 | ((rfield
& 7) << 3) | (i
& 7);
2126 } else { /* it's a memory reference */
2127 if (input
->basereg
== -1
2128 && (input
->indexreg
== -1 || input
->scale
== 0)) {
2129 /* it's a pure offset */
2130 if (bits
== 64 && (~input
->type
& IP_REL
)) {
2131 int scale
, index
, base
;
2132 output
->sib_present
= true;
2136 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
2138 output
->modrm
= 4 | ((rfield
& 7) << 3);
2139 output
->rip
= false;
2141 output
->sib_present
= false;
2142 output
->bytes
= (addrbits
!= 16 ? 4 : 2);
2143 output
->modrm
= (addrbits
!= 16 ? 5 : 6) | ((rfield
& 7) << 3);
2144 output
->rip
= bits
== 64;
2146 } else { /* it's an indirection */
2147 int i
= input
->indexreg
, b
= input
->basereg
, s
= input
->scale
;
2148 int32_t o
= input
->offset
, seg
= input
->segment
;
2149 int hb
= input
->hintbase
, ht
= input
->hinttype
;
2152 int32_t ix
, bx
; /* register flags */
2155 i
= -1; /* make this easy, at least */
2157 if (i
>= EXPR_REG_START
&& i
< REG_ENUM_LIMIT
) {
2158 it
= nasm_regvals
[i
];
2159 ix
= nasm_reg_flags
[i
];
2165 if (b
>= EXPR_REG_START
&& b
< REG_ENUM_LIMIT
) {
2166 bt
= nasm_regvals
[b
];
2167 bx
= nasm_reg_flags
[b
];
2173 /* check for a 32/64-bit memory reference... */
2174 if ((ix
|bx
) & (BITS32
|BITS64
)) {
2175 /* it must be a 32/64-bit memory reference. Firstly we have
2176 * to check that all registers involved are type E/Rxx. */
2177 int32_t sok
= BITS32
|BITS64
;
2180 if (!(REG64
& ~ix
) || !(REG32
& ~ix
))
2188 return NULL
; /* Invalid register */
2189 if (~sok
& bx
& SIZE_MASK
)
2190 return NULL
; /* Invalid size */
2194 /* While we're here, ensure the user didn't specify
2196 if (input
->disp_size
== 16 || input
->disp_size
== 64)
2199 if (addrbits
== 16 ||
2200 (addrbits
== 32 && !(sok
& BITS32
)) ||
2201 (addrbits
== 64 && !(sok
& BITS64
)))
2204 /* now reorganize base/index */
2205 if (s
== 1 && bt
!= it
&& bt
!= -1 && it
!= -1 &&
2206 ((hb
== b
&& ht
== EAH_NOTBASE
)
2207 || (hb
== i
&& ht
== EAH_MAKEBASE
))) {
2208 /* swap if hints say so */
2209 t
= bt
, bt
= it
, it
= t
;
2210 t
= bx
, bx
= ix
, ix
= t
;
2212 if (bt
== it
) /* convert EAX+2*EAX to 3*EAX */
2213 bt
= -1, bx
= 0, s
++;
2214 if (bt
== -1 && s
== 1 && !(hb
== it
&& ht
== EAH_NOTBASE
)) {
2215 /* make single reg base, unless hint */
2216 bt
= it
, bx
= ix
, it
= -1, ix
= 0;
2218 if (((s
== 2 && it
!= REG_NUM_ESP
2219 && !(input
->eaflags
& EAF_TIMESTWO
)) || s
== 3
2220 || s
== 5 || s
== 9) && bt
== -1)
2221 bt
= it
, bx
= ix
, s
--; /* convert 3*EAX to EAX+2*EAX */
2222 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
2223 && (input
->eaflags
& EAF_TIMESTWO
))
2224 it
= bt
, ix
= bx
, bt
= -1, bx
= 0, s
= 1;
2225 /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */
2226 if (s
== 1 && it
== REG_NUM_ESP
) {
2227 /* swap ESP into base if scale is 1 */
2228 t
= it
, it
= bt
, bt
= t
;
2229 t
= ix
, ix
= bx
, bx
= t
;
2231 if (it
== REG_NUM_ESP
2232 || (s
!= 1 && s
!= 2 && s
!= 4 && s
!= 8 && it
!= -1))
2233 return NULL
; /* wrong, for various reasons */
2235 output
->rex
|= rexflags(it
, ix
, REX_X
);
2236 output
->rex
|= rexflags(bt
, bx
, REX_B
);
2238 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
) {
2247 if (rm
!= REG_NUM_EBP
&& o
== 0 &&
2248 seg
== NO_SEG
&& !forw_ref
&&
2250 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2252 else if (input
->eaflags
& EAF_BYTEOFFS
||
2253 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2255 && !(input
->eaflags
& EAF_WORDOFFS
)))
2261 output
->sib_present
= false;
2262 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
2263 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
2266 int mod
, scale
, index
, base
;
2286 default: /* then what the smeg is it? */
2287 return NULL
; /* panic */
2295 if (base
!= REG_NUM_EBP
&& o
== 0 &&
2296 seg
== NO_SEG
&& !forw_ref
&&
2298 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2300 else if (input
->eaflags
& EAF_BYTEOFFS
||
2301 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2303 && !(input
->eaflags
& EAF_WORDOFFS
)))
2309 output
->sib_present
= true;
2310 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
2311 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | 4;
2312 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
2314 } else { /* it's 16-bit */
2317 /* check for 64-bit long mode */
2321 /* check all registers are BX, BP, SI or DI */
2322 if ((b
!= -1 && b
!= R_BP
&& b
!= R_BX
&& b
!= R_SI
2323 && b
!= R_DI
) || (i
!= -1 && i
!= R_BP
&& i
!= R_BX
2324 && i
!= R_SI
&& i
!= R_DI
))
2327 /* ensure the user didn't specify DWORD/QWORD */
2328 if (input
->disp_size
== 32 || input
->disp_size
== 64)
2331 if (s
!= 1 && i
!= -1)
2332 return NULL
; /* no can do, in 16-bit EA */
2333 if (b
== -1 && i
!= -1) {
2338 if ((b
== R_SI
|| b
== R_DI
) && i
!= -1) {
2343 /* have BX/BP as base, SI/DI index */
2345 return NULL
; /* shouldn't ever happen, in theory */
2346 if (i
!= -1 && b
!= -1 &&
2347 (i
== R_BP
|| i
== R_BX
|| b
== R_SI
|| b
== R_DI
))
2348 return NULL
; /* invalid combinations */
2349 if (b
== -1) /* pure offset: handled above */
2350 return NULL
; /* so if it gets to here, panic! */
2354 switch (i
* 256 + b
) {
2355 case R_SI
* 256 + R_BX
:
2358 case R_DI
* 256 + R_BX
:
2361 case R_SI
* 256 + R_BP
:
2364 case R_DI
* 256 + R_BP
:
2382 if (rm
== -1) /* can't happen, in theory */
2383 return NULL
; /* so panic if it does */
2385 if (o
== 0 && seg
== NO_SEG
&& !forw_ref
&& rm
!= 6 &&
2386 !(input
->eaflags
& (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2388 else if (input
->eaflags
& EAF_BYTEOFFS
||
2389 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2391 && !(input
->eaflags
& EAF_WORDOFFS
)))
2396 output
->sib_present
= false; /* no SIB - it's 16-bit */
2397 output
->bytes
= mod
; /* bytes of offset needed */
2398 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
2403 output
->size
= 1 + output
->sib_present
+ output
->bytes
;
2407 static void add_asp(insn
*ins
, int addrbits
)
2412 valid
= (addrbits
== 64) ? 64|32 : 32|16;
2414 switch (ins
->prefixes
[PPS_ASIZE
]) {
2425 valid
&= (addrbits
== 32) ? 16 : 32;
2431 for (j
= 0; j
< ins
->operands
; j
++) {
2432 if (!(MEMORY
& ~ins
->oprs
[j
].type
)) {
2435 /* Verify as Register */
2436 if (ins
->oprs
[j
].indexreg
< EXPR_REG_START
2437 || ins
->oprs
[j
].indexreg
>= REG_ENUM_LIMIT
)
2440 i
= nasm_reg_flags
[ins
->oprs
[j
].indexreg
];
2442 /* Verify as Register */
2443 if (ins
->oprs
[j
].basereg
< EXPR_REG_START
2444 || ins
->oprs
[j
].basereg
>= REG_ENUM_LIMIT
)
2447 b
= nasm_reg_flags
[ins
->oprs
[j
].basereg
];
2449 if (ins
->oprs
[j
].scale
== 0)
2453 int ds
= ins
->oprs
[j
].disp_size
;
2454 if ((addrbits
!= 64 && ds
> 8) ||
2455 (addrbits
== 64 && ds
== 16))
2475 if (valid
& addrbits
) {
2476 ins
->addr_size
= addrbits
;
2477 } else if (valid
& ((addrbits
== 32) ? 16 : 32)) {
2478 /* Add an address size prefix */
2479 enum prefixes pref
= (addrbits
== 32) ? P_A16
: P_A32
;
2480 ins
->prefixes
[PPS_ASIZE
] = pref
;
2481 ins
->addr_size
= (addrbits
== 32) ? 16 : 32;
2484 errfunc(ERR_NONFATAL
, "impossible combination of address sizes");
2485 ins
->addr_size
= addrbits
; /* Error recovery */
2488 defdisp
= ins
->addr_size
== 16 ? 16 : 32;
2490 for (j
= 0; j
< ins
->operands
; j
++) {
2491 if (!(MEM_OFFS
& ~ins
->oprs
[j
].type
) &&
2492 (ins
->oprs
[j
].disp_size
? ins
->oprs
[j
].disp_size
: defdisp
)
2493 != ins
->addr_size
) {
2494 /* mem_offs sizes must match the address size; if not,
2495 strip the MEM_OFFS bit and match only EA instructions */
2496 ins
->oprs
[j
].type
&= ~(MEM_OFFS
& ~MEMORY
);