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 * \340 - reserve <operand 0> bytes of uninitialized storage.
97 * Operand 0 had better be a segmentless constant.
98 * \360 - no SSE prefix (== \364\331)
99 * \361 - 66 SSE prefix (== \366\331)
100 * \362 - F2 SSE prefix (== \364\332)
101 * \363 - F3 SSE prefix (== \364\333)
102 * \364 - operand-size prefix (0x66) not permitted
103 * \365 - address-size prefix (0x67) not permitted
104 * \366 - operand-size prefix (0x66) used as opcode extension
105 * \367 - address-size prefix (0x67) used as opcode extension
106 * \370,\371,\372 - match only if operand 0 meets byte jump criteria.
107 * 370 is used for Jcc, 371 is used for JMP.
108 * \373 - assemble 0x03 if bits==16, 0x05 if bits==32;
109 * used for conditional jump over longer jump
112 #include "compiler.h"
116 #include <inttypes.h>
120 #include "assemble.h"
125 /* Initialized to zero by the C standard */
126 static const uint8_t const_zero_buf
[256];
129 int sib_present
; /* is a SIB byte necessary? */
130 int bytes
; /* # of bytes of offset needed */
131 int size
; /* lazy - this is sib+bytes+1 */
132 uint8_t modrm
, sib
, rex
, rip
; /* the bytes themselves */
135 static uint32_t cpu
; /* cpu level received from nasm.c */
136 static efunc errfunc
;
137 static struct ofmt
*outfmt
;
138 static ListGen
*list
;
140 static int64_t calcsize(int32_t, int64_t, int, insn
*, const uint8_t *);
141 static void gencode(int32_t, int64_t, int, insn
*, const uint8_t *, int64_t);
142 static int matches(const struct itemplate
*, insn
*, int bits
);
143 static int32_t regflag(const operand
*);
144 static int32_t regval(const operand
*);
145 static int rexflags(int, int32_t, int);
146 static int op_rexflags(const operand
*, int);
147 static ea
*process_ea(operand
*, ea
*, int, int, int, int32_t, int);
148 static void add_asp(insn
*, int);
150 static int has_prefix(insn
* ins
, enum prefix_pos pos
, enum prefixes prefix
)
152 return ins
->prefixes
[pos
] == prefix
;
155 static void assert_no_prefix(insn
* ins
, enum prefix_pos pos
)
157 if (ins
->prefixes
[pos
])
158 errfunc(ERR_NONFATAL
, "invalid %s prefix",
159 prefix_name(ins
->prefixes
[pos
]));
162 static const char *size_name(int size
)
184 static void warn_overflow(int size
, int64_t data
)
187 int64_t lim
= ((int64_t)1 << (size
*8))-1;
189 if (data
< ~lim
|| data
> lim
)
190 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
191 "%s data exceeds bounds", size_name(size
));
195 * This routine wrappers the real output format's output routine,
196 * in order to pass a copy of the data off to the listing file
197 * generator at the same time.
199 static void out(int64_t offset
, int32_t segto
, const void *data
,
200 enum out_type type
, uint64_t size
,
201 int32_t segment
, int32_t wrt
)
203 static int32_t lineno
= 0; /* static!!! */
204 static char *lnfname
= NULL
;
207 if (type
== OUT_ADDRESS
&& segment
== NO_SEG
&& wrt
== NO_SEG
) {
209 * This is a non-relocated address, and we're going to
210 * convert it into RAWDATA format.
215 errfunc(ERR_PANIC
, "OUT_ADDRESS with size > 8");
219 WRITEADDR(q
, *(int64_t *)data
, size
);
224 list
->output(offset
, data
, type
, size
);
227 * this call to src_get determines when we call the
228 * debug-format-specific "linenum" function
229 * it updates lineno and lnfname to the current values
230 * returning 0 if "same as last time", -2 if lnfname
231 * changed, and the amount by which lineno changed,
232 * if it did. thus, these variables must be static
235 if (src_get(&lineno
, &lnfname
)) {
236 outfmt
->current_dfmt
->linenum(lnfname
, lineno
, segto
);
239 outfmt
->output(segto
, data
, type
, size
, segment
, wrt
);
242 static int jmp_match(int32_t segment
, int64_t offset
, int bits
,
243 insn
* ins
, const uint8_t *code
)
248 if (c
!= 0370 && c
!= 0371)
250 if (ins
->oprs
[0].opflags
& OPFLAG_FORWARD
) {
251 if ((optimizing
< 0 || (ins
->oprs
[0].type
& STRICT
))
255 return (pass0
== 0); /* match a forward reference */
257 isize
= calcsize(segment
, offset
, bits
, ins
, code
);
258 if (ins
->oprs
[0].segment
!= segment
)
260 isize
= ins
->oprs
[0].offset
- offset
- isize
; /* isize is now the delta */
261 if (isize
>= -128L && isize
<= 127L)
262 return 1; /* it is byte size */
267 int64_t assemble(int32_t segment
, int64_t offset
, int bits
, uint32_t cp
,
268 insn
* instruction
, struct ofmt
*output
, efunc error
,
271 const struct itemplate
*temp
;
276 int64_t start
= offset
;
277 int64_t wsize
= 0; /* size for DB etc. */
279 errfunc
= error
; /* to pass to other functions */
281 outfmt
= output
; /* likewise */
282 list
= listgen
; /* and again */
284 switch (instruction
->opcode
) {
314 int32_t t
= instruction
->times
;
317 "instruction->times < 0 (%ld) in assemble()", t
);
319 while (t
--) { /* repeat TIMES times */
320 for (e
= instruction
->eops
; e
; e
= e
->next
) {
321 if (e
->type
== EOT_DB_NUMBER
) {
323 if (e
->segment
!= NO_SEG
)
324 errfunc(ERR_NONFATAL
,
325 "one-byte relocation attempted");
327 uint8_t out_byte
= e
->offset
;
328 out(offset
, segment
, &out_byte
,
329 OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
331 } else if (wsize
> 8) {
332 errfunc(ERR_NONFATAL
,
333 "integer supplied to a DT, DO or DY"
336 out(offset
, segment
, &e
->offset
,
337 OUT_ADDRESS
, wsize
, e
->segment
, e
->wrt
);
339 } else if (e
->type
== EOT_DB_STRING
) {
342 out(offset
, segment
, e
->stringval
,
343 OUT_RAWDATA
, e
->stringlen
, NO_SEG
, NO_SEG
);
344 align
= e
->stringlen
% wsize
;
347 align
= wsize
- align
;
348 out(offset
, segment
, const_zero_buf
,
349 OUT_RAWDATA
, align
, NO_SEG
, NO_SEG
);
351 offset
+= e
->stringlen
+ align
;
354 if (t
> 0 && t
== instruction
->times
- 1) {
356 * Dummy call to list->output to give the offset to the
359 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
360 list
->uplevel(LIST_TIMES
);
363 if (instruction
->times
> 1)
364 list
->downlevel(LIST_TIMES
);
365 return offset
- start
;
368 if (instruction
->opcode
== I_INCBIN
) {
369 static char fname
[FILENAME_MAX
];
372 char *prefix
= "", *combine
;
373 char **pPrevPath
= NULL
;
375 len
= FILENAME_MAX
- 1;
376 if (len
> instruction
->eops
->stringlen
)
377 len
= instruction
->eops
->stringlen
;
378 strncpy(fname
, instruction
->eops
->stringval
, len
);
381 while (1) { /* added by alexfru: 'incbin' uses include paths */
382 combine
= nasm_malloc(strlen(prefix
) + len
+ 1);
383 strcpy(combine
, prefix
);
384 strcat(combine
, fname
);
386 if ((fp
= fopen(combine
, "rb")) != NULL
) {
392 pPrevPath
= pp_get_include_path_ptr(pPrevPath
);
393 if (pPrevPath
== NULL
)
399 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
401 else if (fseek(fp
, 0L, SEEK_END
) < 0)
402 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
405 static char buf
[2048];
406 int32_t t
= instruction
->times
;
410 if (instruction
->eops
->next
) {
411 base
= instruction
->eops
->next
->offset
;
413 if (instruction
->eops
->next
->next
&&
414 len
> instruction
->eops
->next
->next
->offset
)
415 len
= instruction
->eops
->next
->next
->offset
;
418 * Dummy call to list->output to give the offset to the
421 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
422 list
->uplevel(LIST_INCBIN
);
426 fseek(fp
, base
, SEEK_SET
);
430 fread(buf
, 1, (l
> (int32_t) sizeof(buf
) ? (int32_t) sizeof(buf
) : l
),
434 * This shouldn't happen unless the file
435 * actually changes while we are reading
439 "`incbin': unexpected EOF while"
440 " reading file `%s'", fname
);
441 t
= 0; /* Try to exit cleanly */
444 out(offset
, segment
, buf
, OUT_RAWDATA
, m
,
449 list
->downlevel(LIST_INCBIN
);
450 if (instruction
->times
> 1) {
452 * Dummy call to list->output to give the offset to the
455 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
456 list
->uplevel(LIST_TIMES
);
457 list
->downlevel(LIST_TIMES
);
460 return instruction
->times
* len
;
462 return 0; /* if we're here, there's an error */
465 /* Check to see if we need an address-size prefix */
466 add_asp(instruction
, bits
);
470 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++){
471 int m
= matches(temp
, instruction
, bits
);
474 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
476 if (m
== 100) { /* matches! */
477 const uint8_t *codes
= temp
->code
;
478 int64_t insn_size
= calcsize(segment
, offset
, bits
,
480 itimes
= instruction
->times
;
481 if (insn_size
< 0) /* shouldn't be, on pass two */
482 error(ERR_PANIC
, "errors made it through from pass one");
485 for (j
= 0; j
< MAXPREFIX
; j
++) {
487 switch (instruction
->prefixes
[j
]) {
503 "cs segment base generated, but will be ignored in 64-bit mode");
510 "ds segment base generated, but will be ignored in 64-bit mode");
517 "es segment base generated, but will be ignored in 64-bit mode");
530 "ss segment base generated, but will be ignored in 64-bit mode");
537 "segr6 and segr7 cannot be used as prefixes");
542 "16-bit addressing is not supported "
544 } else if (bits
!= 16)
554 "64-bit addressing is only supported "
578 error(ERR_PANIC
, "invalid instruction prefix");
581 out(offset
, segment
, &c
, OUT_RAWDATA
, 1,
586 insn_end
= offset
+ insn_size
;
587 gencode(segment
, offset
, bits
, instruction
, codes
,
590 if (itimes
> 0 && itimes
== instruction
->times
- 1) {
592 * Dummy call to list->output to give the offset to the
595 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
596 list
->uplevel(LIST_TIMES
);
599 if (instruction
->times
> 1)
600 list
->downlevel(LIST_TIMES
);
601 return offset
- start
;
602 } else if (m
> 0 && m
> size_prob
) {
608 if (temp
->opcode
== -1) { /* didn't match any instruction */
611 error(ERR_NONFATAL
, "operation size not specified");
614 error(ERR_NONFATAL
, "mismatch in operand sizes");
617 error(ERR_NONFATAL
, "no instruction for this cpu level");
620 error(ERR_NONFATAL
, "instruction not supported in 64-bit mode");
624 "invalid combination of opcode and operands");
631 int64_t insn_size(int32_t segment
, int64_t offset
, int bits
, uint32_t cp
,
632 insn
* instruction
, efunc error
)
634 const struct itemplate
*temp
;
636 errfunc
= error
; /* to pass to other functions */
639 if (instruction
->opcode
== -1)
642 if (instruction
->opcode
== I_DB
|| instruction
->opcode
== I_DW
||
643 instruction
->opcode
== I_DD
|| instruction
->opcode
== I_DQ
||
644 instruction
->opcode
== I_DT
|| instruction
->opcode
== I_DO
||
645 instruction
->opcode
== I_DY
) {
647 int32_t isize
, osize
, wsize
= 0; /* placate gcc */
650 switch (instruction
->opcode
) {
676 for (e
= instruction
->eops
; e
; e
= e
->next
) {
680 if (e
->type
== EOT_DB_NUMBER
)
682 else if (e
->type
== EOT_DB_STRING
)
683 osize
= e
->stringlen
;
685 align
= (-osize
) % wsize
;
688 isize
+= osize
+ align
;
690 return isize
* instruction
->times
;
693 if (instruction
->opcode
== I_INCBIN
) {
694 char fname
[FILENAME_MAX
];
697 char *prefix
= "", *combine
;
698 char **pPrevPath
= NULL
;
700 len
= FILENAME_MAX
- 1;
701 if (len
> instruction
->eops
->stringlen
)
702 len
= instruction
->eops
->stringlen
;
703 strncpy(fname
, instruction
->eops
->stringval
, len
);
706 /* added by alexfru: 'incbin' uses include paths */
708 combine
= nasm_malloc(strlen(prefix
) + len
+ 1);
709 strcpy(combine
, prefix
);
710 strcat(combine
, fname
);
712 if ((fp
= fopen(combine
, "rb")) != NULL
) {
718 pPrevPath
= pp_get_include_path_ptr(pPrevPath
);
719 if (pPrevPath
== NULL
)
725 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
727 else if (fseek(fp
, 0L, SEEK_END
) < 0)
728 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
733 if (instruction
->eops
->next
) {
734 len
-= instruction
->eops
->next
->offset
;
735 if (instruction
->eops
->next
->next
&&
736 len
> instruction
->eops
->next
->next
->offset
) {
737 len
= instruction
->eops
->next
->next
->offset
;
740 return instruction
->times
* len
;
742 return 0; /* if we're here, there's an error */
745 /* Check to see if we need an address-size prefix */
746 add_asp(instruction
, bits
);
748 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++) {
749 int m
= matches(temp
, instruction
, bits
);
751 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
754 /* we've matched an instruction. */
756 const uint8_t *codes
= temp
->code
;
759 isize
= calcsize(segment
, offset
, bits
, instruction
, codes
);
762 for (j
= 0; j
< MAXPREFIX
; j
++) {
763 switch (instruction
->prefixes
[j
]) {
789 return isize
* instruction
->times
;
792 return -1; /* didn't match any instruction */
795 static bool possible_sbyte(insn
* ins
, int op
)
797 return !(ins
->forw_ref
&& ins
->oprs
[op
].opflags
) &&
799 !(ins
->oprs
[op
].type
& STRICT
) &&
800 ins
->oprs
[op
].wrt
== NO_SEG
&& ins
->oprs
[op
].segment
== NO_SEG
;
803 /* check that opn[op] is a signed byte of size 16 or 32 */
804 static bool is_sbyte16(insn
* ins
, int op
)
808 if (!possible_sbyte(ins
, op
))
811 v
= ins
->oprs
[op
].offset
;
812 return v
>= -128 && v
<= 127;
815 static bool is_sbyte32(insn
* ins
, int op
)
819 if (!possible_sbyte(ins
, op
))
822 v
= ins
->oprs
[op
].offset
;
823 return v
>= -128 && v
<= 127;
826 /* check that opn[op] is a signed byte of size 32; warn if this is not
827 the original value when extended to 64 bits */
828 static bool is_sbyte64(insn
* ins
, int op
)
833 /* dead in the water on forward reference or External */
834 if (!possible_sbyte(ins
, op
))
837 v64
= ins
->oprs
[op
].offset
;
840 warn_overflow(32, v64
);
842 return v32
>= -128 && v32
<= 127;
844 static int64_t calcsize(int32_t segment
, int64_t offset
, int bits
,
845 insn
* ins
, const uint8_t *codes
)
852 ins
->rex
= 0; /* Ensure REX is reset */
854 if (ins
->prefixes
[PPS_OSIZE
] == P_O64
)
857 (void)segment
; /* Don't warn that this parameter is unused */
858 (void)offset
; /* Don't warn that this parameter is unused */
862 opx
= &ins
->oprs
[c
& 3];
867 codes
+= c
, length
+= c
;
880 op_rexflags(opx
, REX_B
|REX_H
|REX_P
|REX_W
);
911 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
912 length
+= (opx
->type
& BITS16
) ? 2 : 4;
914 length
+= (bits
== 16) ? 2 : 4;
926 length
+= ins
->addr_size
>> 3;
938 length
+= 8; /* MOV reg64/imm */
950 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
951 length
+= (opx
->type
& BITS16
) ? 2 : 4;
953 length
+= (bits
== 16) ? 2 : 4;
971 length
+= is_sbyte16(ins
, c
& 3) ? 1 : 2;
984 length
+= is_sbyte32(ins
, c
& 3) ? 1 : 4;
999 ins
->drexdst
= regval(opx
);
1006 ins
->rex
|= REX_D
|REX_OC
;
1007 ins
->drexdst
= regval(opx
);
1021 length
+= is_sbyte64(ins
, c
& 3) ? 1 : 4;
1029 ins
->drexdst
= regval(opx
);
1030 ins
->vex_m
= *codes
++;
1031 ins
->vex_wlp
= *codes
++;
1037 ins
->vex_m
= *codes
++;
1038 ins
->vex_wlp
= *codes
++;
1048 length
+= (bits
!= 16) && !has_prefix(ins
, PPS_ASIZE
, P_A16
);
1051 length
+= (bits
!= 32) && !has_prefix(ins
, PPS_ASIZE
, P_A32
);
1056 if (bits
!= 64 || has_prefix(ins
, PPS_ASIZE
, P_A16
) ||
1057 has_prefix(ins
, PPS_ASIZE
, P_A32
))
1066 length
+= (bits
!= 16);
1069 length
+= (bits
== 16);
1094 if (ins
->oprs
[0].segment
!= NO_SEG
)
1095 errfunc(ERR_NONFATAL
, "attempt to reserve non-constant"
1096 " quantity of BSS space");
1098 length
+= ins
->oprs
[0].offset
;
1121 default: /* can't do it by 'case' statements */
1122 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1126 ea_data
.rex
= 0; /* Ensure ea.REX is initially 0 */
1129 /* pick rfield from operand b */
1130 rflags
= regflag(&ins
->oprs
[c
& 7]);
1131 rfield
= nasm_regvals
[ins
->oprs
[c
& 7].basereg
];
1138 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1139 ins
->addr_size
, rfield
, rflags
, ins
->forw_ref
)) {
1140 errfunc(ERR_NONFATAL
, "invalid effective address");
1143 ins
->rex
|= ea_data
.rex
;
1144 length
+= ea_data
.size
;
1147 errfunc(ERR_PANIC
, "internal instruction table corrupt"
1148 ": instruction code 0x%02X given", c
);
1153 ins
->rex
&= rex_mask
;
1155 if (ins
->rex
& REX_V
) {
1156 int bad32
= REX_R
|REX_W
|REX_X
|REX_B
;
1158 if (ins
->rex
& REX_H
) {
1159 errfunc(ERR_NONFATAL
, "cannot use high register in vex instruction");
1162 switch (ins
->vex_wlp
& 030) {
1176 if (bits
!= 64 && ((ins
->rex
& bad32
) || ins
->drexdst
> 7)) {
1177 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1180 if (ins
->vex_m
!= 1 || (ins
->rex
& (REX_W
|REX_R
|REX_B
)))
1184 } else if (ins
->rex
& REX_D
) {
1185 if (ins
->rex
& REX_H
) {
1186 errfunc(ERR_NONFATAL
, "cannot use high register in drex instruction");
1189 if (bits
!= 64 && ((ins
->rex
& (REX_R
|REX_W
|REX_X
|REX_B
)) ||
1190 ins
->drexdst
> 7)) {
1191 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1195 } else if (ins
->rex
& REX_REAL
) {
1196 if (ins
->rex
& REX_H
) {
1197 errfunc(ERR_NONFATAL
, "cannot use high register in rex instruction");
1199 } else if (bits
== 64) {
1201 } else if ((ins
->rex
& REX_L
) &&
1202 !(ins
->rex
& (REX_P
|REX_W
|REX_X
|REX_B
)) &&
1205 assert_no_prefix(ins
, PPS_LREP
);
1208 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1216 #define EMIT_REX() \
1217 if (!(ins->rex & (REX_D|REX_V)) && (ins->rex & REX_REAL) && (bits == 64)) { \
1218 ins->rex = (ins->rex & REX_REAL)|REX_P; \
1219 out(offset, segment, &ins->rex, OUT_RAWDATA, 1, NO_SEG, NO_SEG); \
1224 static void gencode(int32_t segment
, int64_t offset
, int bits
,
1225 insn
* ins
, const uint8_t *codes
, int64_t insn_end
)
1227 static char condval
[] = { /* conditional opcodes */
1228 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
1229 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
1230 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
1236 struct operand
*opx
;
1240 opx
= &ins
->oprs
[c
& 3];
1246 out(offset
, segment
, codes
, OUT_RAWDATA
, c
, NO_SEG
, NO_SEG
);
1253 switch (ins
->oprs
[0].basereg
) {
1255 bytes
[0] = 0x0E + (c
== 0x04 ? 1 : 0);
1258 bytes
[0] = 0x1E + (c
== 0x04 ? 1 : 0);
1261 bytes
[0] = 0x06 + (c
== 0x04 ? 1 : 0);
1264 bytes
[0] = 0x16 + (c
== 0x04 ? 1 : 0);
1268 "bizarre 8086 segment register received");
1270 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1276 switch (ins
->oprs
[0].basereg
) {
1278 bytes
[0] = 0xA0 + (c
== 0x05 ? 1 : 0);
1281 bytes
[0] = 0xA8 + (c
== 0x05 ? 1 : 0);
1285 "bizarre 386 segment register received");
1287 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1296 bytes
[0] = *codes
++ + ((regval(opx
)) & 7);
1297 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1305 /* XXX: warns for legitimate optimizer actions */
1306 if (opx
->offset
< -128 || opx
->offset
> 127) {
1307 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1308 "signed byte value exceeds bounds");
1311 if (opx
->segment
!= NO_SEG
) {
1313 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1314 opx
->segment
, opx
->wrt
);
1316 bytes
[0] = opx
->offset
;
1317 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1327 if (opx
->offset
< -256 || opx
->offset
> 255) {
1328 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1329 "byte value exceeds bounds");
1331 if (opx
->segment
!= NO_SEG
) {
1333 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1334 opx
->segment
, opx
->wrt
);
1336 bytes
[0] = opx
->offset
;
1337 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1347 if (opx
->offset
< 0 || opx
->offset
> 255)
1348 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1349 "unsigned byte value exceeds bounds");
1350 if (opx
->segment
!= NO_SEG
) {
1352 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1353 opx
->segment
, opx
->wrt
);
1355 bytes
[0] = opx
->offset
;
1356 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1367 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1368 warn_overflow(2, data
);
1369 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1370 opx
->segment
, opx
->wrt
);
1378 if (opx
->type
& (BITS16
| BITS32
))
1379 size
= (opx
->type
& BITS16
) ? 2 : 4;
1381 size
= (bits
== 16) ? 2 : 4;
1383 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1384 warn_overflow(size
, data
);
1385 out(offset
, segment
, &data
, OUT_ADDRESS
, size
,
1386 opx
->segment
, opx
->wrt
);
1395 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1396 warn_overflow(4, data
);
1397 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1398 opx
->segment
, opx
->wrt
);
1407 size
= ins
->addr_size
>> 3;
1408 if (opx
->segment
== NO_SEG
&&
1410 warn_overflow(size
, data
);
1411 out(offset
, segment
, &data
, OUT_ADDRESS
, size
,
1412 opx
->segment
, opx
->wrt
);
1420 if (opx
->segment
!= segment
)
1421 errfunc(ERR_NONFATAL
,
1422 "short relative jump outside segment");
1423 data
= opx
->offset
- insn_end
;
1424 if (data
> 127 || data
< -128)
1425 errfunc(ERR_NONFATAL
, "short jump is out of range");
1427 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1435 data
= (int64_t)opx
->offset
;
1436 out(offset
, segment
, &data
, OUT_ADDRESS
, 8,
1437 opx
->segment
, opx
->wrt
);
1445 if (opx
->segment
!= segment
) {
1447 out(offset
, segment
, &data
,
1448 OUT_REL2ADR
, insn_end
- offset
,
1449 opx
->segment
, opx
->wrt
);
1451 data
= opx
->offset
- insn_end
;
1452 out(offset
, segment
, &data
,
1453 OUT_ADDRESS
, 2, NO_SEG
, NO_SEG
);
1462 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
1463 size
= (opx
->type
& BITS16
) ? 2 : 4;
1465 size
= (bits
== 16) ? 2 : 4;
1466 if (opx
->segment
!= segment
) {
1468 out(offset
, segment
, &data
,
1469 size
== 2 ? OUT_REL2ADR
: OUT_REL4ADR
,
1470 insn_end
- offset
, opx
->segment
, opx
->wrt
);
1472 data
= opx
->offset
- insn_end
;
1473 out(offset
, segment
, &data
,
1474 OUT_ADDRESS
, size
, NO_SEG
, NO_SEG
);
1483 if (opx
->segment
!= segment
) {
1485 out(offset
, segment
, &data
,
1486 OUT_REL4ADR
, insn_end
- offset
,
1487 opx
->segment
, opx
->wrt
);
1489 data
= opx
->offset
- insn_end
;
1490 out(offset
, segment
, &data
,
1491 OUT_ADDRESS
, 4, NO_SEG
, NO_SEG
);
1500 if (opx
->segment
== NO_SEG
)
1501 errfunc(ERR_NONFATAL
, "value referenced by FAR is not"
1504 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1505 outfmt
->segbase(1 + opx
->segment
),
1515 if (is_sbyte16(ins
, c
& 3)) {
1517 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1521 if (opx
->segment
== NO_SEG
&&
1523 warn_overflow(2, data
);
1524 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1525 opx
->segment
, opx
->wrt
);
1535 bytes
[0] = *codes
++;
1536 if (is_sbyte16(ins
, c
& 3))
1537 bytes
[0] |= 2; /* s-bit */
1538 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1547 if (is_sbyte32(ins
, c
& 3)) {
1549 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1553 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1554 opx
->segment
, opx
->wrt
);
1564 bytes
[0] = *codes
++;
1565 if (is_sbyte32(ins
, c
& 3))
1566 bytes
[0] |= 2; /* s-bit */
1567 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1583 (ins
->drexdst
<< 4) |
1584 (ins
->rex
& REX_OC
? 0x08 : 0) |
1585 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1587 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1593 opx
= &ins
->oprs
[c
>> 3];
1594 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1595 opx
= &ins
->oprs
[c
& 7];
1596 if (opx
->segment
!= NO_SEG
|| opx
->wrt
!= NO_SEG
) {
1597 errfunc(ERR_NONFATAL
,
1598 "non-absolute expression not permitted as argument %d",
1601 if (opx
->offset
& ~15) {
1602 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1603 "four-bit argument exceeds bounds");
1605 bytes
[0] |= opx
->offset
& 15;
1607 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1613 opx
= &ins
->oprs
[c
>> 4];
1614 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1616 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1622 opx
= &ins
->oprs
[c
];
1623 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1624 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1633 /* is_sbyte32() is right here, we have already warned */
1634 if (is_sbyte32(ins
, c
& 3)) {
1636 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1640 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1641 opx
->segment
, opx
->wrt
);
1652 if (ins
->vex_m
!= 1 || (ins
->rex
& (REX_W
|REX_X
|REX_B
))) {
1654 bytes
[1] = ins
->vex_m
| ((~ins
->rex
& 7) << 5);
1655 bytes
[2] = ((ins
->rex
& REX_W
) << (7-3)) |
1656 ((~ins
->drexdst
& 15)<< 3) | (ins
->vex_wlp
& 07);
1657 out(offset
, segment
, &bytes
, OUT_RAWDATA
, 3, NO_SEG
, NO_SEG
);
1661 bytes
[1] = ((~ins
->rex
& REX_R
) << (7-2)) |
1662 ((~ins
->drexdst
& 15) << 3) | (ins
->vex_wlp
& 07);
1663 out(offset
, segment
, &bytes
, OUT_RAWDATA
, 2, NO_SEG
, NO_SEG
);
1675 if (bits
== 32 && !has_prefix(ins
, PPS_ASIZE
, P_A16
)) {
1677 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1684 if (bits
!= 32 && !has_prefix(ins
, PPS_ASIZE
, P_A32
)) {
1686 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1708 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1717 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1732 *bytes
= *codes
++ ^ condval
[ins
->condition
];
1733 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1742 *bytes
= c
- 0332 + 0xF2;
1743 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1748 if (ins
->rex
& REX_R
) {
1750 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1753 ins
->rex
&= ~(REX_L
|REX_R
);
1760 if (ins
->oprs
[0].segment
!= NO_SEG
)
1761 errfunc(ERR_PANIC
, "non-constant BSS size in pass two");
1763 int64_t size
= ins
->oprs
[0].offset
;
1765 out(offset
, segment
, NULL
,
1766 OUT_RESERVE
, size
, NO_SEG
, NO_SEG
);
1776 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1782 bytes
[0] = c
- 0362 + 0xf2;
1783 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1793 *bytes
= c
- 0366 + 0x66;
1794 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1804 *bytes
= bits
== 16 ? 3 : 5;
1805 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1809 default: /* can't do it by 'case' statements */
1810 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1818 /* pick rfield from operand b */
1819 rflags
= regflag(&ins
->oprs
[c
& 7]);
1820 rfield
= nasm_regvals
[ins
->oprs
[c
& 7].basereg
];
1822 /* rfield is constant */
1828 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1829 ins
->addr_size
, rfield
, rflags
, ins
->forw_ref
)) {
1830 errfunc(ERR_NONFATAL
, "invalid effective address");
1835 *p
++ = ea_data
.modrm
;
1836 if (ea_data
.sib_present
)
1839 /* DREX suffixes come between the SIB and the displacement */
1840 if (ins
->rex
& REX_D
) {
1842 (ins
->drexdst
<< 4) |
1843 (ins
->rex
& REX_OC
? 0x08 : 0) |
1844 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1849 out(offset
, segment
, bytes
, OUT_RAWDATA
, s
, NO_SEG
, NO_SEG
);
1851 switch (ea_data
.bytes
) {
1855 if (ins
->oprs
[(c
>> 3) & 7].segment
!= NO_SEG
) {
1856 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1857 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1858 ins
->oprs
[(c
>> 3) & 7].segment
,
1859 ins
->oprs
[(c
>> 3) & 7].wrt
);
1861 *bytes
= ins
->oprs
[(c
>> 3) & 7].offset
;
1862 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1,
1870 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1871 warn_overflow(ea_data
.bytes
, data
);
1872 out(offset
, segment
, &data
,
1873 ea_data
.rip
? OUT_REL4ADR
: OUT_ADDRESS
,
1875 ins
->oprs
[(c
>> 3) & 7].segment
,
1876 ins
->oprs
[(c
>> 3) & 7].wrt
);
1882 errfunc(ERR_PANIC
, "internal instruction table corrupt"
1883 ": instruction code 0x%02X given", c
);
1889 static int32_t regflag(const operand
* o
)
1891 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1892 errfunc(ERR_PANIC
, "invalid operand passed to regflag()");
1894 return nasm_reg_flags
[o
->basereg
];
1897 static int32_t regval(const operand
* o
)
1899 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1900 errfunc(ERR_PANIC
, "invalid operand passed to regval()");
1902 return nasm_regvals
[o
->basereg
];
1905 static int op_rexflags(const operand
* o
, int mask
)
1910 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1911 errfunc(ERR_PANIC
, "invalid operand passed to op_rexflags()");
1914 flags
= nasm_reg_flags
[o
->basereg
];
1915 val
= nasm_regvals
[o
->basereg
];
1917 return rexflags(val
, flags
, mask
);
1920 static int rexflags(int val
, int32_t flags
, int mask
)
1925 rex
|= REX_B
|REX_X
|REX_R
;
1928 if (!(REG_HIGH
& ~flags
)) /* AH, CH, DH, BH */
1930 else if (!(REG8
& ~flags
) && val
>= 4) /* SPL, BPL, SIL, DIL */
1936 static int matches(const struct itemplate
*itemp
, insn
* instruction
, int bits
)
1938 int i
, size
[MAX_OPERANDS
], asize
, oprs
, ret
;
1945 if (itemp
->opcode
!= instruction
->opcode
)
1949 * Count the operands
1951 if (itemp
->operands
!= instruction
->operands
)
1955 * Check that no spurious colons or TOs are present
1957 for (i
= 0; i
< itemp
->operands
; i
++)
1958 if (instruction
->oprs
[i
].type
& ~itemp
->opd
[i
] & (COLON
| TO
))
1962 * Process size flags
1964 if (itemp
->flags
& IF_ARMASK
) {
1965 memset(size
, 0, sizeof size
);
1967 i
= ((itemp
->flags
& IF_ARMASK
) >> IF_ARSHFT
) - 1;
1969 switch (itemp
->flags
& IF_SMASK
) {
2006 switch (itemp
->flags
& IF_SMASK
) {
2041 for (i
= 0; i
< MAX_OPERANDS
; i
++)
2046 * Check that the operand flags all match up
2048 for (i
= 0; i
< itemp
->operands
; i
++) {
2049 int32_t type
= instruction
->oprs
[i
].type
;
2050 if (!(type
& SIZE_MASK
))
2053 if (itemp
->opd
[i
] & SAME_AS
) {
2054 int j
= itemp
->opd
[i
] & ~SAME_AS
;
2055 if (type
!= instruction
->oprs
[j
].type
||
2056 instruction
->oprs
[i
].basereg
!= instruction
->oprs
[j
].basereg
)
2058 } else if (itemp
->opd
[i
] & ~type
||
2059 ((itemp
->opd
[i
] & SIZE_MASK
) &&
2060 ((itemp
->opd
[i
] ^ type
) & SIZE_MASK
))) {
2061 if ((itemp
->opd
[i
] & ~type
& ~SIZE_MASK
) ||
2070 * Check operand sizes
2072 if (itemp
->flags
& (IF_SM
| IF_SM2
)) {
2073 oprs
= (itemp
->flags
& IF_SM2
? 2 : itemp
->operands
);
2075 for (i
= 0; i
< oprs
; i
++) {
2076 if ((asize
= itemp
->opd
[i
] & SIZE_MASK
) != 0) {
2078 for (j
= 0; j
< oprs
; j
++)
2084 oprs
= itemp
->operands
;
2087 for (i
= 0; i
< itemp
->operands
; i
++) {
2088 if (!(itemp
->opd
[i
] & SIZE_MASK
) &&
2089 (instruction
->oprs
[i
].type
& SIZE_MASK
& ~size
[i
]))
2094 * Check template is okay at the set cpu level
2096 if (((itemp
->flags
& IF_PLEVEL
) > cpu
))
2100 * Check if instruction is available in long mode
2102 if ((itemp
->flags
& IF_NOLONG
) && (bits
== 64))
2106 * Check if special handling needed for Jumps
2108 if ((uint8_t)(itemp
->code
[0]) >= 0370)
2114 static ea
*process_ea(operand
* input
, ea
* output
, int bits
,
2115 int addrbits
, int rfield
, int32_t rflags
, int forw_ref
)
2117 output
->rip
= false;
2119 /* REX flags for the rfield operand */
2120 output
->rex
|= rexflags(rfield
, rflags
, REX_R
|REX_P
|REX_W
|REX_H
);
2122 if (!(REGISTER
& ~input
->type
)) { /* register direct */
2126 if (input
->basereg
< EXPR_REG_START
/* Verify as Register */
2127 || input
->basereg
>= REG_ENUM_LIMIT
)
2130 i
= nasm_regvals
[input
->basereg
];
2133 return NULL
; /* Invalid EA register */
2135 output
->rex
|= op_rexflags(input
, REX_B
|REX_P
|REX_W
|REX_H
);
2137 output
->sib_present
= false; /* no SIB necessary */
2138 output
->bytes
= 0; /* no offset necessary either */
2139 output
->modrm
= 0xC0 | ((rfield
& 7) << 3) | (i
& 7);
2140 } else { /* it's a memory reference */
2141 if (input
->basereg
== -1
2142 && (input
->indexreg
== -1 || input
->scale
== 0)) {
2143 /* it's a pure offset */
2144 if (bits
== 64 && (~input
->type
& IP_REL
)) {
2145 int scale
, index
, base
;
2146 output
->sib_present
= true;
2150 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
2152 output
->modrm
= 4 | ((rfield
& 7) << 3);
2153 output
->rip
= false;
2155 output
->sib_present
= false;
2156 output
->bytes
= (addrbits
!= 16 ? 4 : 2);
2157 output
->modrm
= (addrbits
!= 16 ? 5 : 6) | ((rfield
& 7) << 3);
2158 output
->rip
= bits
== 64;
2160 } else { /* it's an indirection */
2161 int i
= input
->indexreg
, b
= input
->basereg
, s
= input
->scale
;
2162 int32_t o
= input
->offset
, seg
= input
->segment
;
2163 int hb
= input
->hintbase
, ht
= input
->hinttype
;
2166 int32_t ix
, bx
; /* register flags */
2169 i
= -1; /* make this easy, at least */
2171 if (i
>= EXPR_REG_START
&& i
< REG_ENUM_LIMIT
) {
2172 it
= nasm_regvals
[i
];
2173 ix
= nasm_reg_flags
[i
];
2179 if (b
>= EXPR_REG_START
&& b
< REG_ENUM_LIMIT
) {
2180 bt
= nasm_regvals
[b
];
2181 bx
= nasm_reg_flags
[b
];
2187 /* check for a 32/64-bit memory reference... */
2188 if ((ix
|bx
) & (BITS32
|BITS64
)) {
2189 /* it must be a 32/64-bit memory reference. Firstly we have
2190 * to check that all registers involved are type E/Rxx. */
2191 int32_t sok
= BITS32
|BITS64
;
2194 if (!(REG64
& ~ix
) || !(REG32
& ~ix
))
2202 return NULL
; /* Invalid register */
2203 if (~sok
& bx
& SIZE_MASK
)
2204 return NULL
; /* Invalid size */
2208 /* While we're here, ensure the user didn't specify
2210 if (input
->disp_size
== 16 || input
->disp_size
== 64)
2213 if (addrbits
== 16 ||
2214 (addrbits
== 32 && !(sok
& BITS32
)) ||
2215 (addrbits
== 64 && !(sok
& BITS64
)))
2218 /* now reorganize base/index */
2219 if (s
== 1 && bt
!= it
&& bt
!= -1 && it
!= -1 &&
2220 ((hb
== b
&& ht
== EAH_NOTBASE
)
2221 || (hb
== i
&& ht
== EAH_MAKEBASE
))) {
2222 /* swap if hints say so */
2223 t
= bt
, bt
= it
, it
= t
;
2224 t
= bx
, bx
= ix
, ix
= t
;
2226 if (bt
== it
) /* convert EAX+2*EAX to 3*EAX */
2227 bt
= -1, bx
= 0, s
++;
2228 if (bt
== -1 && s
== 1 && !(hb
== it
&& ht
== EAH_NOTBASE
)) {
2229 /* make single reg base, unless hint */
2230 bt
= it
, bx
= ix
, it
= -1, ix
= 0;
2232 if (((s
== 2 && it
!= REG_NUM_ESP
2233 && !(input
->eaflags
& EAF_TIMESTWO
)) || s
== 3
2234 || s
== 5 || s
== 9) && bt
== -1)
2235 bt
= it
, bx
= ix
, s
--; /* convert 3*EAX to EAX+2*EAX */
2236 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
2237 && (input
->eaflags
& EAF_TIMESTWO
))
2238 it
= bt
, ix
= bx
, bt
= -1, bx
= 0, s
= 1;
2239 /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */
2240 if (s
== 1 && it
== REG_NUM_ESP
) {
2241 /* swap ESP into base if scale is 1 */
2242 t
= it
, it
= bt
, bt
= t
;
2243 t
= ix
, ix
= bx
, bx
= t
;
2245 if (it
== REG_NUM_ESP
2246 || (s
!= 1 && s
!= 2 && s
!= 4 && s
!= 8 && it
!= -1))
2247 return NULL
; /* wrong, for various reasons */
2249 output
->rex
|= rexflags(it
, ix
, REX_X
);
2250 output
->rex
|= rexflags(bt
, bx
, REX_B
);
2252 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
) {
2261 if (rm
!= REG_NUM_EBP
&& o
== 0 &&
2262 seg
== NO_SEG
&& !forw_ref
&&
2264 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2266 else if (input
->eaflags
& EAF_BYTEOFFS
||
2267 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2269 && !(input
->eaflags
& EAF_WORDOFFS
)))
2275 output
->sib_present
= false;
2276 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
2277 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
2280 int mod
, scale
, index
, base
;
2300 default: /* then what the smeg is it? */
2301 return NULL
; /* panic */
2309 if (base
!= REG_NUM_EBP
&& o
== 0 &&
2310 seg
== NO_SEG
&& !forw_ref
&&
2312 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2314 else if (input
->eaflags
& EAF_BYTEOFFS
||
2315 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2317 && !(input
->eaflags
& EAF_WORDOFFS
)))
2323 output
->sib_present
= true;
2324 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
2325 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | 4;
2326 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
2328 } else { /* it's 16-bit */
2331 /* check for 64-bit long mode */
2335 /* check all registers are BX, BP, SI or DI */
2336 if ((b
!= -1 && b
!= R_BP
&& b
!= R_BX
&& b
!= R_SI
2337 && b
!= R_DI
) || (i
!= -1 && i
!= R_BP
&& i
!= R_BX
2338 && i
!= R_SI
&& i
!= R_DI
))
2341 /* ensure the user didn't specify DWORD/QWORD */
2342 if (input
->disp_size
== 32 || input
->disp_size
== 64)
2345 if (s
!= 1 && i
!= -1)
2346 return NULL
; /* no can do, in 16-bit EA */
2347 if (b
== -1 && i
!= -1) {
2352 if ((b
== R_SI
|| b
== R_DI
) && i
!= -1) {
2357 /* have BX/BP as base, SI/DI index */
2359 return NULL
; /* shouldn't ever happen, in theory */
2360 if (i
!= -1 && b
!= -1 &&
2361 (i
== R_BP
|| i
== R_BX
|| b
== R_SI
|| b
== R_DI
))
2362 return NULL
; /* invalid combinations */
2363 if (b
== -1) /* pure offset: handled above */
2364 return NULL
; /* so if it gets to here, panic! */
2368 switch (i
* 256 + b
) {
2369 case R_SI
* 256 + R_BX
:
2372 case R_DI
* 256 + R_BX
:
2375 case R_SI
* 256 + R_BP
:
2378 case R_DI
* 256 + R_BP
:
2396 if (rm
== -1) /* can't happen, in theory */
2397 return NULL
; /* so panic if it does */
2399 if (o
== 0 && seg
== NO_SEG
&& !forw_ref
&& rm
!= 6 &&
2400 !(input
->eaflags
& (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2402 else if (input
->eaflags
& EAF_BYTEOFFS
||
2403 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2405 && !(input
->eaflags
& EAF_WORDOFFS
)))
2410 output
->sib_present
= false; /* no SIB - it's 16-bit */
2411 output
->bytes
= mod
; /* bytes of offset needed */
2412 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
2417 output
->size
= 1 + output
->sib_present
+ output
->bytes
;
2421 static void add_asp(insn
*ins
, int addrbits
)
2426 valid
= (addrbits
== 64) ? 64|32 : 32|16;
2428 switch (ins
->prefixes
[PPS_ASIZE
]) {
2439 valid
&= (addrbits
== 32) ? 16 : 32;
2445 for (j
= 0; j
< ins
->operands
; j
++) {
2446 if (!(MEMORY
& ~ins
->oprs
[j
].type
)) {
2449 /* Verify as Register */
2450 if (ins
->oprs
[j
].indexreg
< EXPR_REG_START
2451 || ins
->oprs
[j
].indexreg
>= REG_ENUM_LIMIT
)
2454 i
= nasm_reg_flags
[ins
->oprs
[j
].indexreg
];
2456 /* Verify as Register */
2457 if (ins
->oprs
[j
].basereg
< EXPR_REG_START
2458 || ins
->oprs
[j
].basereg
>= REG_ENUM_LIMIT
)
2461 b
= nasm_reg_flags
[ins
->oprs
[j
].basereg
];
2463 if (ins
->oprs
[j
].scale
== 0)
2467 int ds
= ins
->oprs
[j
].disp_size
;
2468 if ((addrbits
!= 64 && ds
> 8) ||
2469 (addrbits
== 64 && ds
== 16))
2489 if (valid
& addrbits
) {
2490 ins
->addr_size
= addrbits
;
2491 } else if (valid
& ((addrbits
== 32) ? 16 : 32)) {
2492 /* Add an address size prefix */
2493 enum prefixes pref
= (addrbits
== 32) ? P_A16
: P_A32
;
2494 ins
->prefixes
[PPS_ASIZE
] = pref
;
2495 ins
->addr_size
= (addrbits
== 32) ? 16 : 32;
2498 errfunc(ERR_NONFATAL
, "impossible combination of address sizes");
2499 ins
->addr_size
= addrbits
; /* Error recovery */
2502 defdisp
= ins
->addr_size
== 16 ? 16 : 32;
2504 for (j
= 0; j
< ins
->operands
; j
++) {
2505 if (!(MEM_OFFS
& ~ins
->oprs
[j
].type
) &&
2506 (ins
->oprs
[j
].disp_size
? ins
->oprs
[j
].disp_size
: defdisp
)
2507 != ins
->addr_size
) {
2508 /* mem_offs sizes must match the address size; if not,
2509 strip the MEM_OFFS bit and match only EA instructions */
2510 ins
->oprs
[j
].type
&= ~(MEM_OFFS
& ~MEMORY
);