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
, "integer supplied to a DT, DO or DY"
331 out(offset
, segment
, &e
->offset
,
332 OUT_ADDRESS
, wsize
, e
->segment
, e
->wrt
);
334 } else if (e
->type
== EOT_DB_STRING
) {
337 out(offset
, segment
, e
->stringval
,
338 OUT_RAWDATA
, e
->stringlen
, NO_SEG
, NO_SEG
);
339 align
= e
->stringlen
% wsize
;
342 align
= wsize
- align
;
343 out(offset
, segment
, const_zero_buf
,
344 OUT_RAWDATA
, align
, NO_SEG
, NO_SEG
);
346 offset
+= e
->stringlen
+ align
;
349 if (t
> 0 && t
== instruction
->times
- 1) {
351 * Dummy call to list->output to give the offset to the
354 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
355 list
->uplevel(LIST_TIMES
);
358 if (instruction
->times
> 1)
359 list
->downlevel(LIST_TIMES
);
360 return offset
- start
;
363 if (instruction
->opcode
== I_INCBIN
) {
364 static char fname
[FILENAME_MAX
];
367 char *prefix
= "", *combine
;
368 char **pPrevPath
= NULL
;
370 len
= FILENAME_MAX
- 1;
371 if (len
> instruction
->eops
->stringlen
)
372 len
= instruction
->eops
->stringlen
;
373 strncpy(fname
, instruction
->eops
->stringval
, len
);
376 while (1) { /* added by alexfru: 'incbin' uses include paths */
377 combine
= nasm_malloc(strlen(prefix
) + len
+ 1);
378 strcpy(combine
, prefix
);
379 strcat(combine
, fname
);
381 if ((fp
= fopen(combine
, "rb")) != NULL
) {
387 pPrevPath
= pp_get_include_path_ptr(pPrevPath
);
388 if (pPrevPath
== NULL
)
394 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
396 else if (fseek(fp
, 0L, SEEK_END
) < 0)
397 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
400 static char buf
[2048];
401 int32_t t
= instruction
->times
;
405 if (instruction
->eops
->next
) {
406 base
= instruction
->eops
->next
->offset
;
408 if (instruction
->eops
->next
->next
&&
409 len
> instruction
->eops
->next
->next
->offset
)
410 len
= instruction
->eops
->next
->next
->offset
;
413 * Dummy call to list->output to give the offset to the
416 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
417 list
->uplevel(LIST_INCBIN
);
421 fseek(fp
, base
, SEEK_SET
);
425 fread(buf
, 1, (l
> (int32_t) sizeof(buf
) ? (int32_t) sizeof(buf
) : l
),
429 * This shouldn't happen unless the file
430 * actually changes while we are reading
434 "`incbin': unexpected EOF while"
435 " reading file `%s'", fname
);
436 t
= 0; /* Try to exit cleanly */
439 out(offset
, segment
, buf
, OUT_RAWDATA
, m
,
444 list
->downlevel(LIST_INCBIN
);
445 if (instruction
->times
> 1) {
447 * Dummy call to list->output to give the offset to the
450 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
451 list
->uplevel(LIST_TIMES
);
452 list
->downlevel(LIST_TIMES
);
455 return instruction
->times
* len
;
457 return 0; /* if we're here, there's an error */
460 /* Check to see if we need an address-size prefix */
461 add_asp(instruction
, bits
);
465 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++){
466 int m
= matches(temp
, instruction
, bits
);
469 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
471 if (m
== 100) { /* matches! */
472 const uint8_t *codes
= temp
->code
;
473 int64_t insn_size
= calcsize(segment
, offset
, bits
,
475 itimes
= instruction
->times
;
476 if (insn_size
< 0) /* shouldn't be, on pass two */
477 error(ERR_PANIC
, "errors made it through from pass one");
480 for (j
= 0; j
< MAXPREFIX
; j
++) {
482 switch (instruction
->prefixes
[j
]) {
498 "cs segment base generated, but will be ignored in 64-bit mode");
505 "ds segment base generated, but will be ignored in 64-bit mode");
512 "es segment base generated, but will be ignored in 64-bit mode");
525 "ss segment base generated, but will be ignored in 64-bit mode");
532 "segr6 and segr7 cannot be used as prefixes");
537 "16-bit addressing is not supported "
539 } else if (bits
!= 16)
549 "64-bit addressing is only supported "
573 error(ERR_PANIC
, "invalid instruction prefix");
576 out(offset
, segment
, &c
, OUT_RAWDATA
, 1,
581 insn_end
= offset
+ insn_size
;
582 gencode(segment
, offset
, bits
, instruction
, codes
,
585 if (itimes
> 0 && itimes
== instruction
->times
- 1) {
587 * Dummy call to list->output to give the offset to the
590 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
591 list
->uplevel(LIST_TIMES
);
594 if (instruction
->times
> 1)
595 list
->downlevel(LIST_TIMES
);
596 return offset
- start
;
597 } else if (m
> 0 && m
> size_prob
) {
603 if (temp
->opcode
== -1) { /* didn't match any instruction */
606 error(ERR_NONFATAL
, "operation size not specified");
609 error(ERR_NONFATAL
, "mismatch in operand sizes");
612 error(ERR_NONFATAL
, "no instruction for this cpu level");
615 error(ERR_NONFATAL
, "instruction not supported in 64-bit mode");
619 "invalid combination of opcode and operands");
626 int64_t insn_size(int32_t segment
, int64_t offset
, int bits
, uint32_t cp
,
627 insn
* instruction
, efunc error
)
629 const struct itemplate
*temp
;
631 errfunc
= error
; /* to pass to other functions */
634 if (instruction
->opcode
== -1)
637 if (instruction
->opcode
== I_DB
|| instruction
->opcode
== I_DW
||
638 instruction
->opcode
== I_DD
|| instruction
->opcode
== I_DQ
||
639 instruction
->opcode
== I_DT
|| instruction
->opcode
== I_DO
||
640 instruction
->opcode
== I_DY
) {
642 int32_t isize
, osize
, wsize
= 0; /* placate gcc */
645 switch (instruction
->opcode
) {
671 for (e
= instruction
->eops
; e
; e
= e
->next
) {
675 if (e
->type
== EOT_DB_NUMBER
)
677 else if (e
->type
== EOT_DB_STRING
)
678 osize
= e
->stringlen
;
680 align
= (-osize
) % wsize
;
683 isize
+= osize
+ align
;
685 return isize
* instruction
->times
;
688 if (instruction
->opcode
== I_INCBIN
) {
689 char fname
[FILENAME_MAX
];
692 char *prefix
= "", *combine
;
693 char **pPrevPath
= NULL
;
695 len
= FILENAME_MAX
- 1;
696 if (len
> instruction
->eops
->stringlen
)
697 len
= instruction
->eops
->stringlen
;
698 strncpy(fname
, instruction
->eops
->stringval
, len
);
701 /* added by alexfru: 'incbin' uses include paths */
703 combine
= nasm_malloc(strlen(prefix
) + len
+ 1);
704 strcpy(combine
, prefix
);
705 strcat(combine
, fname
);
707 if ((fp
= fopen(combine
, "rb")) != NULL
) {
713 pPrevPath
= pp_get_include_path_ptr(pPrevPath
);
714 if (pPrevPath
== NULL
)
720 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
722 else if (fseek(fp
, 0L, SEEK_END
) < 0)
723 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
728 if (instruction
->eops
->next
) {
729 len
-= instruction
->eops
->next
->offset
;
730 if (instruction
->eops
->next
->next
&&
731 len
> instruction
->eops
->next
->next
->offset
) {
732 len
= instruction
->eops
->next
->next
->offset
;
735 return instruction
->times
* len
;
737 return 0; /* if we're here, there's an error */
740 /* Check to see if we need an address-size prefix */
741 add_asp(instruction
, bits
);
743 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++) {
744 int m
= matches(temp
, instruction
, bits
);
746 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
749 /* we've matched an instruction. */
751 const uint8_t *codes
= temp
->code
;
754 isize
= calcsize(segment
, offset
, bits
, instruction
, codes
);
757 for (j
= 0; j
< MAXPREFIX
; j
++) {
758 switch (instruction
->prefixes
[j
]) {
784 return isize
* instruction
->times
;
787 return -1; /* didn't match any instruction */
790 static bool possible_sbyte(insn
* ins
, int op
)
792 return !(ins
->forw_ref
&& ins
->oprs
[op
].opflags
) &&
794 !(ins
->oprs
[op
].type
& STRICT
) &&
795 ins
->oprs
[op
].wrt
== NO_SEG
&& ins
->oprs
[op
].segment
== NO_SEG
;
798 /* check that opn[op] is a signed byte of size 16 or 32 */
799 static bool is_sbyte16(insn
* ins
, int op
)
803 if (!possible_sbyte(ins
, op
))
806 v
= ins
->oprs
[op
].offset
;
807 return v
>= -128 && v
<= 127;
810 static bool is_sbyte32(insn
* ins
, int op
)
814 if (!possible_sbyte(ins
, op
))
817 v
= ins
->oprs
[op
].offset
;
818 return v
>= -128 && v
<= 127;
821 /* check that opn[op] is a signed byte of size 32; warn if this is not
822 the original value when extended to 64 bits */
823 static bool is_sbyte64(insn
* ins
, int op
)
828 /* dead in the water on forward reference or External */
829 if (!possible_sbyte(ins
, op
))
832 v64
= ins
->oprs
[op
].offset
;
835 warn_overflow(32, v64
);
837 return v32
>= -128 && v32
<= 127;
839 static int64_t calcsize(int32_t segment
, int64_t offset
, int bits
,
840 insn
* ins
, const uint8_t *codes
)
847 ins
->rex
= 0; /* Ensure REX is reset */
849 if (ins
->prefixes
[PPS_OSIZE
] == P_O64
)
852 (void)segment
; /* Don't warn that this parameter is unused */
853 (void)offset
; /* Don't warn that this parameter is unused */
857 opx
= &ins
->oprs
[c
& 3];
862 codes
+= c
, length
+= c
;
875 op_rexflags(opx
, REX_B
|REX_H
|REX_P
|REX_W
);
906 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
907 length
+= (opx
->type
& BITS16
) ? 2 : 4;
909 length
+= (bits
== 16) ? 2 : 4;
921 length
+= ins
->addr_size
>> 3;
933 length
+= 8; /* MOV reg64/imm */
945 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
946 length
+= (opx
->type
& BITS16
) ? 2 : 4;
948 length
+= (bits
== 16) ? 2 : 4;
966 length
+= is_sbyte16(ins
, c
& 3) ? 1 : 2;
979 length
+= is_sbyte32(ins
, c
& 3) ? 1 : 4;
994 ins
->drexdst
= regval(opx
);
1001 ins
->rex
|= REX_D
|REX_OC
;
1002 ins
->drexdst
= regval(opx
);
1015 length
+= is_sbyte64(ins
, c
& 3) ? 1 : 4;
1023 ins
->drexdst
= regval(opx
);
1024 ins
->vex_m
= *codes
++;
1025 ins
->vex_wlp
= *codes
++;
1031 ins
->vex_m
= *codes
++;
1032 ins
->vex_wlp
= *codes
++;
1042 length
+= (bits
!= 16) && !has_prefix(ins
, PPS_ASIZE
, P_A16
);
1045 length
+= (bits
!= 32) && !has_prefix(ins
, PPS_ASIZE
, P_A32
);
1050 if (bits
!= 64 || has_prefix(ins
, PPS_ASIZE
, P_A16
) ||
1051 has_prefix(ins
, PPS_ASIZE
, P_A32
))
1060 length
+= (bits
!= 16);
1063 length
+= (bits
== 16);
1088 if (ins
->oprs
[0].segment
!= NO_SEG
)
1089 errfunc(ERR_NONFATAL
, "attempt to reserve non-constant"
1090 " quantity of BSS space");
1092 length
+= ins
->oprs
[0].offset
;
1115 default: /* can't do it by 'case' statements */
1116 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1120 ea_data
.rex
= 0; /* Ensure ea.REX is initially 0 */
1123 /* pick rfield from operand b */
1124 rflags
= regflag(&ins
->oprs
[c
& 7]);
1125 rfield
= nasm_regvals
[ins
->oprs
[c
& 7].basereg
];
1132 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1133 ins
->addr_size
, rfield
, rflags
, ins
->forw_ref
)) {
1134 errfunc(ERR_NONFATAL
, "invalid effective address");
1137 ins
->rex
|= ea_data
.rex
;
1138 length
+= ea_data
.size
;
1141 errfunc(ERR_PANIC
, "internal instruction table corrupt"
1142 ": instruction code 0x%02X given", c
);
1147 ins
->rex
&= rex_mask
;
1149 if (ins
->rex
& REX_V
) {
1150 int bad32
= REX_R
|REX_W
|REX_X
|REX_B
;
1152 if (ins
->rex
& REX_H
) {
1153 errfunc(ERR_NONFATAL
, "cannot use high register in vex instruction");
1156 switch (ins
->vex_wlp
& 030) {
1169 if (bits
!= 64 && ((ins
->rex
& bad32
) || ins
->drexdst
> 7)) {
1170 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1173 if (ins
->vex_m
!= 1 || (ins
->rex
& (REX_W
|REX_R
|REX_B
)))
1177 } else if (ins
->rex
& REX_D
) {
1178 if (ins
->rex
& REX_H
) {
1179 errfunc(ERR_NONFATAL
, "cannot use high register in drex instruction");
1182 if (bits
!= 64 && ((ins
->rex
& (REX_R
|REX_W
|REX_X
|REX_B
)) ||
1183 ins
->drexdst
> 7)) {
1184 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1188 } else if (ins
->rex
& REX_REAL
) {
1189 if (ins
->rex
& REX_H
) {
1190 errfunc(ERR_NONFATAL
, "cannot use high register in rex instruction");
1192 } else if (bits
== 64) {
1194 } else if ((ins
->rex
& REX_L
) &&
1195 !(ins
->rex
& (REX_P
|REX_W
|REX_X
|REX_B
)) &&
1198 assert_no_prefix(ins
, PPS_LREP
);
1201 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1209 #define EMIT_REX() \
1210 if (!(ins->rex & (REX_D|REX_V)) && (ins->rex & REX_REAL) && (bits == 64)) { \
1211 ins->rex = (ins->rex & REX_REAL)|REX_P; \
1212 out(offset, segment, &ins->rex, OUT_RAWDATA, 1, NO_SEG, NO_SEG); \
1217 static void gencode(int32_t segment
, int64_t offset
, int bits
,
1218 insn
* ins
, const uint8_t *codes
, int64_t insn_end
)
1220 static char condval
[] = { /* conditional opcodes */
1221 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
1222 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
1223 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
1229 struct operand
*opx
;
1233 opx
= &ins
->oprs
[c
& 3];
1239 out(offset
, segment
, codes
, OUT_RAWDATA
, c
, NO_SEG
, NO_SEG
);
1246 switch (ins
->oprs
[0].basereg
) {
1248 bytes
[0] = 0x0E + (c
== 0x04 ? 1 : 0);
1251 bytes
[0] = 0x1E + (c
== 0x04 ? 1 : 0);
1254 bytes
[0] = 0x06 + (c
== 0x04 ? 1 : 0);
1257 bytes
[0] = 0x16 + (c
== 0x04 ? 1 : 0);
1261 "bizarre 8086 segment register received");
1263 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1269 switch (ins
->oprs
[0].basereg
) {
1271 bytes
[0] = 0xA0 + (c
== 0x05 ? 1 : 0);
1274 bytes
[0] = 0xA8 + (c
== 0x05 ? 1 : 0);
1278 "bizarre 386 segment register received");
1280 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1289 bytes
[0] = *codes
++ + ((regval(opx
)) & 7);
1290 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1298 /* XXX: warns for legitimate optimizer actions */
1299 if (opx
->offset
< -128 || opx
->offset
> 127) {
1300 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1301 "signed byte value exceeds bounds");
1304 if (opx
->segment
!= NO_SEG
) {
1306 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1307 opx
->segment
, opx
->wrt
);
1309 bytes
[0] = opx
->offset
;
1310 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1320 if (opx
->offset
< -256 || opx
->offset
> 255) {
1321 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1322 "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 if (opx
->offset
< 0 || opx
->offset
> 255)
1341 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1342 "unsigned byte value exceeds bounds");
1343 if (opx
->segment
!= NO_SEG
) {
1345 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1346 opx
->segment
, opx
->wrt
);
1348 bytes
[0] = opx
->offset
;
1349 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1360 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1361 warn_overflow(2, data
);
1362 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1363 opx
->segment
, opx
->wrt
);
1371 if (opx
->type
& (BITS16
| BITS32
))
1372 size
= (opx
->type
& BITS16
) ? 2 : 4;
1374 size
= (bits
== 16) ? 2 : 4;
1376 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1377 warn_overflow(size
, data
);
1378 out(offset
, segment
, &data
, OUT_ADDRESS
, size
,
1379 opx
->segment
, opx
->wrt
);
1388 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1389 warn_overflow(4, data
);
1390 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1391 opx
->segment
, opx
->wrt
);
1400 size
= ins
->addr_size
>> 3;
1401 if (opx
->segment
== NO_SEG
&&
1403 warn_overflow(size
, data
);
1404 out(offset
, segment
, &data
, OUT_ADDRESS
, size
,
1405 opx
->segment
, opx
->wrt
);
1413 if (opx
->segment
!= segment
)
1414 errfunc(ERR_NONFATAL
,
1415 "short relative jump outside segment");
1416 data
= opx
->offset
- insn_end
;
1417 if (data
> 127 || data
< -128)
1418 errfunc(ERR_NONFATAL
, "short jump is out of range");
1420 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1428 data
= (int64_t)opx
->offset
;
1429 out(offset
, segment
, &data
, OUT_ADDRESS
, 8,
1430 opx
->segment
, opx
->wrt
);
1438 if (opx
->segment
!= segment
) {
1440 out(offset
, segment
, &data
,
1441 OUT_REL2ADR
, insn_end
- offset
,
1442 opx
->segment
, opx
->wrt
);
1444 data
= opx
->offset
- insn_end
;
1445 out(offset
, segment
, &data
,
1446 OUT_ADDRESS
, 2, NO_SEG
, NO_SEG
);
1455 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
1456 size
= (opx
->type
& BITS16
) ? 2 : 4;
1458 size
= (bits
== 16) ? 2 : 4;
1459 if (opx
->segment
!= segment
) {
1461 out(offset
, segment
, &data
,
1462 size
== 2 ? OUT_REL2ADR
: OUT_REL4ADR
,
1463 insn_end
- offset
, opx
->segment
, opx
->wrt
);
1465 data
= opx
->offset
- insn_end
;
1466 out(offset
, segment
, &data
,
1467 OUT_ADDRESS
, size
, NO_SEG
, NO_SEG
);
1476 if (opx
->segment
!= segment
) {
1478 out(offset
, segment
, &data
,
1479 OUT_REL4ADR
, insn_end
- offset
,
1480 opx
->segment
, opx
->wrt
);
1482 data
= opx
->offset
- insn_end
;
1483 out(offset
, segment
, &data
,
1484 OUT_ADDRESS
, 4, NO_SEG
, NO_SEG
);
1493 if (opx
->segment
== NO_SEG
)
1494 errfunc(ERR_NONFATAL
, "value referenced by FAR is not"
1497 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1498 outfmt
->segbase(1 + opx
->segment
),
1508 if (is_sbyte16(ins
, c
& 3)) {
1510 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1514 if (opx
->segment
== NO_SEG
&&
1516 warn_overflow(2, data
);
1517 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1518 opx
->segment
, opx
->wrt
);
1528 bytes
[0] = *codes
++;
1529 if (is_sbyte16(ins
, c
& 3))
1530 bytes
[0] |= 2; /* s-bit */
1531 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1540 if (is_sbyte32(ins
, c
& 3)) {
1542 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1546 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1547 opx
->segment
, opx
->wrt
);
1557 bytes
[0] = *codes
++;
1558 if (is_sbyte32(ins
, c
& 3))
1559 bytes
[0] |= 2; /* s-bit */
1560 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1576 (ins
->drexdst
<< 4) |
1577 (ins
->rex
& REX_OC
? 0x08 : 0) |
1578 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1580 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1586 opx
= &ins
->oprs
[c
>> 3];
1587 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1588 opx
= &ins
->oprs
[c
& 7];
1589 if (opx
->segment
!= NO_SEG
|| opx
->wrt
!= NO_SEG
) {
1590 errfunc(ERR_NONFATAL
,
1591 "non-absolute expression not permitted as argument %d",
1594 if (opx
->offset
& ~15) {
1595 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1596 "four-bit argument exceeds bounds");
1598 bytes
[0] |= opx
->offset
& 15;
1600 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1606 opx
= &ins
->oprs
[c
>> 4];
1607 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1609 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1618 /* is_sbyte32() is right here, we have already warned */
1619 if (is_sbyte32(ins
, c
& 3)) {
1621 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1625 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1626 opx
->segment
, opx
->wrt
);
1637 if (ins
->vex_m
!= 1 || (ins
->rex
& (REX_W
|REX_X
|REX_B
))) {
1639 bytes
[1] = ins
->vex_m
| ((~ins
->rex
& 7) << 5);
1640 bytes
[2] = ((ins
->rex
& REX_W
) << (7-3)) |
1641 ((~ins
->drexdst
& 15)<< 3) | (ins
->vex_wlp
& 07);
1642 out(offset
, segment
, &bytes
, OUT_RAWDATA
, 3, NO_SEG
, NO_SEG
);
1646 bytes
[1] = ((~ins
->rex
& REX_R
) << (7-2)) |
1647 ((~ins
->drexdst
& 15) << 3) | (ins
->vex_wlp
& 07);
1648 out(offset
, segment
, &bytes
, OUT_RAWDATA
, 2, NO_SEG
, NO_SEG
);
1660 if (bits
== 32 && !has_prefix(ins
, PPS_ASIZE
, P_A16
)) {
1662 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1669 if (bits
!= 32 && !has_prefix(ins
, PPS_ASIZE
, P_A32
)) {
1671 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1693 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1702 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1717 *bytes
= *codes
++ ^ condval
[ins
->condition
];
1718 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1727 *bytes
= c
- 0332 + 0xF2;
1728 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1733 if (ins
->rex
& REX_R
) {
1735 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1738 ins
->rex
&= ~(REX_L
|REX_R
);
1745 if (ins
->oprs
[0].segment
!= NO_SEG
)
1746 errfunc(ERR_PANIC
, "non-constant BSS size in pass two");
1748 int64_t size
= ins
->oprs
[0].offset
;
1750 out(offset
, segment
, NULL
,
1751 OUT_RESERVE
, size
, NO_SEG
, NO_SEG
);
1761 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1767 bytes
[0] = c
- 0362 + 0xf2;
1768 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1778 *bytes
= c
- 0366 + 0x66;
1779 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1789 *bytes
= bits
== 16 ? 3 : 5;
1790 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1794 default: /* can't do it by 'case' statements */
1795 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1803 /* pick rfield from operand b */
1804 rflags
= regflag(&ins
->oprs
[c
& 7]);
1805 rfield
= nasm_regvals
[ins
->oprs
[c
& 7].basereg
];
1807 /* rfield is constant */
1813 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1814 ins
->addr_size
, rfield
, rflags
, ins
->forw_ref
)) {
1815 errfunc(ERR_NONFATAL
, "invalid effective address");
1820 *p
++ = ea_data
.modrm
;
1821 if (ea_data
.sib_present
)
1824 /* DREX suffixes come between the SIB and the displacement */
1825 if (ins
->rex
& REX_D
) {
1827 (ins
->drexdst
<< 4) |
1828 (ins
->rex
& REX_OC
? 0x08 : 0) |
1829 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1834 out(offset
, segment
, bytes
, OUT_RAWDATA
, s
, NO_SEG
, NO_SEG
);
1836 switch (ea_data
.bytes
) {
1840 if (ins
->oprs
[(c
>> 3) & 7].segment
!= NO_SEG
) {
1841 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1842 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1843 ins
->oprs
[(c
>> 3) & 7].segment
,
1844 ins
->oprs
[(c
>> 3) & 7].wrt
);
1846 *bytes
= ins
->oprs
[(c
>> 3) & 7].offset
;
1847 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1,
1855 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1856 warn_overflow(ea_data
.bytes
, data
);
1857 out(offset
, segment
, &data
,
1858 ea_data
.rip
? OUT_REL4ADR
: OUT_ADDRESS
,
1860 ins
->oprs
[(c
>> 3) & 7].segment
,
1861 ins
->oprs
[(c
>> 3) & 7].wrt
);
1867 errfunc(ERR_PANIC
, "internal instruction table corrupt"
1868 ": instruction code 0x%02X given", c
);
1874 static int32_t regflag(const operand
* o
)
1876 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1877 errfunc(ERR_PANIC
, "invalid operand passed to regflag()");
1879 return nasm_reg_flags
[o
->basereg
];
1882 static int32_t regval(const operand
* o
)
1884 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1885 errfunc(ERR_PANIC
, "invalid operand passed to regval()");
1887 return nasm_regvals
[o
->basereg
];
1890 static int op_rexflags(const operand
* o
, int mask
)
1895 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1896 errfunc(ERR_PANIC
, "invalid operand passed to op_rexflags()");
1899 flags
= nasm_reg_flags
[o
->basereg
];
1900 val
= nasm_regvals
[o
->basereg
];
1902 return rexflags(val
, flags
, mask
);
1905 static int rexflags(int val
, int32_t flags
, int mask
)
1910 rex
|= REX_B
|REX_X
|REX_R
;
1913 if (!(REG_HIGH
& ~flags
)) /* AH, CH, DH, BH */
1915 else if (!(REG8
& ~flags
) && val
>= 4) /* SPL, BPL, SIL, DIL */
1921 static int matches(const struct itemplate
*itemp
, insn
* instruction
, int bits
)
1923 int i
, size
[MAX_OPERANDS
], asize
, oprs
, ret
;
1930 if (itemp
->opcode
!= instruction
->opcode
)
1934 * Count the operands
1936 if (itemp
->operands
!= instruction
->operands
)
1940 * Check that no spurious colons or TOs are present
1942 for (i
= 0; i
< itemp
->operands
; i
++)
1943 if (instruction
->oprs
[i
].type
& ~itemp
->opd
[i
] & (COLON
| TO
))
1947 * Process size flags
1949 if (itemp
->flags
& IF_ARMASK
) {
1950 memset(size
, 0, sizeof size
);
1952 i
= ((itemp
->flags
& IF_ARMASK
) >> IF_ARSHFT
) - 1;
1954 switch (itemp
->flags
& IF_SMASK
) {
1991 switch (itemp
->flags
& IF_SMASK
) {
2026 for (i
= 0; i
< MAX_OPERANDS
; i
++)
2031 * Check that the operand flags all match up
2033 for (i
= 0; i
< itemp
->operands
; i
++) {
2034 int32_t type
= instruction
->oprs
[i
].type
;
2035 if (!(type
& SIZE_MASK
))
2038 if (itemp
->opd
[i
] & SAME_AS
) {
2039 int j
= itemp
->opd
[i
] & ~SAME_AS
;
2040 if (type
!= instruction
->oprs
[j
].type
||
2041 instruction
->oprs
[i
].basereg
!= instruction
->oprs
[j
].basereg
)
2043 } else if (itemp
->opd
[i
] & ~type
||
2044 ((itemp
->opd
[i
] & SIZE_MASK
) &&
2045 ((itemp
->opd
[i
] ^ type
) & SIZE_MASK
))) {
2046 if ((itemp
->opd
[i
] & ~type
& ~SIZE_MASK
) ||
2055 * Check operand sizes
2057 if (itemp
->flags
& (IF_SM
| IF_SM2
)) {
2058 oprs
= (itemp
->flags
& IF_SM2
? 2 : itemp
->operands
);
2060 for (i
= 0; i
< oprs
; i
++) {
2061 if ((asize
= itemp
->opd
[i
] & SIZE_MASK
) != 0) {
2063 for (j
= 0; j
< oprs
; j
++)
2069 oprs
= itemp
->operands
;
2072 for (i
= 0; i
< itemp
->operands
; i
++) {
2073 if (!(itemp
->opd
[i
] & SIZE_MASK
) &&
2074 (instruction
->oprs
[i
].type
& SIZE_MASK
& ~size
[i
]))
2079 * Check template is okay at the set cpu level
2081 if (((itemp
->flags
& IF_PLEVEL
) > cpu
))
2085 * Check if instruction is available in long mode
2087 if ((itemp
->flags
& IF_NOLONG
) && (bits
== 64))
2091 * Check if special handling needed for Jumps
2093 if ((uint8_t)(itemp
->code
[0]) >= 0370)
2099 static ea
*process_ea(operand
* input
, ea
* output
, int bits
,
2100 int addrbits
, int rfield
, int32_t rflags
, int forw_ref
)
2102 output
->rip
= false;
2104 /* REX flags for the rfield operand */
2105 output
->rex
|= rexflags(rfield
, rflags
, REX_R
|REX_P
|REX_W
|REX_H
);
2107 if (!(REGISTER
& ~input
->type
)) { /* register direct */
2111 if (input
->basereg
< EXPR_REG_START
/* Verify as Register */
2112 || input
->basereg
>= REG_ENUM_LIMIT
)
2115 i
= nasm_regvals
[input
->basereg
];
2118 return NULL
; /* Invalid EA register */
2120 output
->rex
|= op_rexflags(input
, REX_B
|REX_P
|REX_W
|REX_H
);
2122 output
->sib_present
= false; /* no SIB necessary */
2123 output
->bytes
= 0; /* no offset necessary either */
2124 output
->modrm
= 0xC0 | ((rfield
& 7) << 3) | (i
& 7);
2125 } else { /* it's a memory reference */
2126 if (input
->basereg
== -1
2127 && (input
->indexreg
== -1 || input
->scale
== 0)) {
2128 /* it's a pure offset */
2129 if (bits
== 64 && (~input
->type
& IP_REL
)) {
2130 int scale
, index
, base
;
2131 output
->sib_present
= true;
2135 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
2137 output
->modrm
= 4 | ((rfield
& 7) << 3);
2138 output
->rip
= false;
2140 output
->sib_present
= false;
2141 output
->bytes
= (addrbits
!= 16 ? 4 : 2);
2142 output
->modrm
= (addrbits
!= 16 ? 5 : 6) | ((rfield
& 7) << 3);
2143 output
->rip
= bits
== 64;
2145 } else { /* it's an indirection */
2146 int i
= input
->indexreg
, b
= input
->basereg
, s
= input
->scale
;
2147 int32_t o
= input
->offset
, seg
= input
->segment
;
2148 int hb
= input
->hintbase
, ht
= input
->hinttype
;
2151 int32_t ix
, bx
; /* register flags */
2154 i
= -1; /* make this easy, at least */
2156 if (i
>= EXPR_REG_START
&& i
< REG_ENUM_LIMIT
) {
2157 it
= nasm_regvals
[i
];
2158 ix
= nasm_reg_flags
[i
];
2164 if (b
>= EXPR_REG_START
&& b
< REG_ENUM_LIMIT
) {
2165 bt
= nasm_regvals
[b
];
2166 bx
= nasm_reg_flags
[b
];
2172 /* check for a 32/64-bit memory reference... */
2173 if ((ix
|bx
) & (BITS32
|BITS64
)) {
2174 /* it must be a 32/64-bit memory reference. Firstly we have
2175 * to check that all registers involved are type E/Rxx. */
2176 int32_t sok
= BITS32
|BITS64
;
2179 if (!(REG64
& ~ix
) || !(REG32
& ~ix
))
2187 return NULL
; /* Invalid register */
2188 if (~sok
& bx
& SIZE_MASK
)
2189 return NULL
; /* Invalid size */
2193 /* While we're here, ensure the user didn't specify
2195 if (input
->disp_size
== 16 || input
->disp_size
== 64)
2198 if (addrbits
== 16 ||
2199 (addrbits
== 32 && !(sok
& BITS32
)) ||
2200 (addrbits
== 64 && !(sok
& BITS64
)))
2203 /* now reorganize base/index */
2204 if (s
== 1 && bt
!= it
&& bt
!= -1 && it
!= -1 &&
2205 ((hb
== b
&& ht
== EAH_NOTBASE
)
2206 || (hb
== i
&& ht
== EAH_MAKEBASE
))) {
2207 /* swap if hints say so */
2208 t
= bt
, bt
= it
, it
= t
;
2209 t
= bx
, bx
= ix
, ix
= t
;
2211 if (bt
== it
) /* convert EAX+2*EAX to 3*EAX */
2212 bt
= -1, bx
= 0, s
++;
2213 if (bt
== -1 && s
== 1 && !(hb
== it
&& ht
== EAH_NOTBASE
)) {
2214 /* make single reg base, unless hint */
2215 bt
= it
, bx
= ix
, it
= -1, ix
= 0;
2217 if (((s
== 2 && it
!= REG_NUM_ESP
2218 && !(input
->eaflags
& EAF_TIMESTWO
)) || s
== 3
2219 || s
== 5 || s
== 9) && bt
== -1)
2220 bt
= it
, bx
= ix
, s
--; /* convert 3*EAX to EAX+2*EAX */
2221 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
2222 && (input
->eaflags
& EAF_TIMESTWO
))
2223 it
= bt
, ix
= bx
, bt
= -1, bx
= 0, s
= 1;
2224 /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */
2225 if (s
== 1 && it
== REG_NUM_ESP
) {
2226 /* swap ESP into base if scale is 1 */
2227 t
= it
, it
= bt
, bt
= t
;
2228 t
= ix
, ix
= bx
, bx
= t
;
2230 if (it
== REG_NUM_ESP
2231 || (s
!= 1 && s
!= 2 && s
!= 4 && s
!= 8 && it
!= -1))
2232 return NULL
; /* wrong, for various reasons */
2234 output
->rex
|= rexflags(it
, ix
, REX_X
);
2235 output
->rex
|= rexflags(bt
, bx
, REX_B
);
2237 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
) {
2246 if (rm
!= REG_NUM_EBP
&& o
== 0 &&
2247 seg
== NO_SEG
&& !forw_ref
&&
2249 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2251 else if (input
->eaflags
& EAF_BYTEOFFS
||
2252 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2254 && !(input
->eaflags
& EAF_WORDOFFS
)))
2260 output
->sib_present
= false;
2261 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
2262 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
2265 int mod
, scale
, index
, base
;
2285 default: /* then what the smeg is it? */
2286 return NULL
; /* panic */
2294 if (base
!= REG_NUM_EBP
&& o
== 0 &&
2295 seg
== NO_SEG
&& !forw_ref
&&
2297 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2299 else if (input
->eaflags
& EAF_BYTEOFFS
||
2300 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2302 && !(input
->eaflags
& EAF_WORDOFFS
)))
2308 output
->sib_present
= true;
2309 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
2310 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | 4;
2311 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
2313 } else { /* it's 16-bit */
2316 /* check for 64-bit long mode */
2320 /* check all registers are BX, BP, SI or DI */
2321 if ((b
!= -1 && b
!= R_BP
&& b
!= R_BX
&& b
!= R_SI
2322 && b
!= R_DI
) || (i
!= -1 && i
!= R_BP
&& i
!= R_BX
2323 && i
!= R_SI
&& i
!= R_DI
))
2326 /* ensure the user didn't specify DWORD/QWORD */
2327 if (input
->disp_size
== 32 || input
->disp_size
== 64)
2330 if (s
!= 1 && i
!= -1)
2331 return NULL
; /* no can do, in 16-bit EA */
2332 if (b
== -1 && i
!= -1) {
2337 if ((b
== R_SI
|| b
== R_DI
) && i
!= -1) {
2342 /* have BX/BP as base, SI/DI index */
2344 return NULL
; /* shouldn't ever happen, in theory */
2345 if (i
!= -1 && b
!= -1 &&
2346 (i
== R_BP
|| i
== R_BX
|| b
== R_SI
|| b
== R_DI
))
2347 return NULL
; /* invalid combinations */
2348 if (b
== -1) /* pure offset: handled above */
2349 return NULL
; /* so if it gets to here, panic! */
2353 switch (i
* 256 + b
) {
2354 case R_SI
* 256 + R_BX
:
2357 case R_DI
* 256 + R_BX
:
2360 case R_SI
* 256 + R_BP
:
2363 case R_DI
* 256 + R_BP
:
2381 if (rm
== -1) /* can't happen, in theory */
2382 return NULL
; /* so panic if it does */
2384 if (o
== 0 && seg
== NO_SEG
&& !forw_ref
&& rm
!= 6 &&
2385 !(input
->eaflags
& (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2387 else if (input
->eaflags
& EAF_BYTEOFFS
||
2388 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2390 && !(input
->eaflags
& EAF_WORDOFFS
)))
2395 output
->sib_present
= false; /* no SIB - it's 16-bit */
2396 output
->bytes
= mod
; /* bytes of offset needed */
2397 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
2402 output
->size
= 1 + output
->sib_present
+ output
->bytes
;
2406 static void add_asp(insn
*ins
, int addrbits
)
2411 valid
= (addrbits
== 64) ? 64|32 : 32|16;
2413 switch (ins
->prefixes
[PPS_ASIZE
]) {
2424 valid
&= (addrbits
== 32) ? 16 : 32;
2430 for (j
= 0; j
< ins
->operands
; j
++) {
2431 if (!(MEMORY
& ~ins
->oprs
[j
].type
)) {
2434 /* Verify as Register */
2435 if (ins
->oprs
[j
].indexreg
< EXPR_REG_START
2436 || ins
->oprs
[j
].indexreg
>= REG_ENUM_LIMIT
)
2439 i
= nasm_reg_flags
[ins
->oprs
[j
].indexreg
];
2441 /* Verify as Register */
2442 if (ins
->oprs
[j
].basereg
< EXPR_REG_START
2443 || ins
->oprs
[j
].basereg
>= REG_ENUM_LIMIT
)
2446 b
= nasm_reg_flags
[ins
->oprs
[j
].basereg
];
2448 if (ins
->oprs
[j
].scale
== 0)
2452 int ds
= ins
->oprs
[j
].disp_size
;
2453 if ((addrbits
!= 64 && ds
> 8) ||
2454 (addrbits
== 64 && ds
== 16))
2474 if (valid
& addrbits
) {
2475 ins
->addr_size
= addrbits
;
2476 } else if (valid
& ((addrbits
== 32) ? 16 : 32)) {
2477 /* Add an address size prefix */
2478 enum prefixes pref
= (addrbits
== 32) ? P_A16
: P_A32
;
2479 ins
->prefixes
[PPS_ASIZE
] = pref
;
2480 ins
->addr_size
= (addrbits
== 32) ? 16 : 32;
2483 errfunc(ERR_NONFATAL
, "impossible combination of address sizes");
2484 ins
->addr_size
= addrbits
; /* Error recovery */
2487 defdisp
= ins
->addr_size
== 16 ? 16 : 32;
2489 for (j
= 0; j
< ins
->operands
; j
++) {
2490 if (!(MEM_OFFS
& ~ins
->oprs
[j
].type
) &&
2491 (ins
->oprs
[j
].disp_size
? ins
->oprs
[j
].disp_size
: defdisp
)
2492 != ins
->addr_size
) {
2493 /* mem_offs sizes must match the address size; if not,
2494 strip the MEM_OFFS bit and match only EA instructions */
2495 ins
->oprs
[j
].type
&= ~(MEM_OFFS
& ~MEMORY
);