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:
69 * ww = 2 for W used as REX.W
71 * \310 - indicates fixed 16-bit address size, i.e. optional 0x67.
72 * \311 - indicates fixed 32-bit address size, i.e. optional 0x67.
73 * \312 - (disassembler only) marker on LOOP, LOOPxx instructions.
74 * \313 - indicates fixed 64-bit address size, 0x67 invalid.
75 * \314 - (disassembler only) invalid with REX.B
76 * \315 - (disassembler only) invalid with REX.X
77 * \316 - (disassembler only) invalid with REX.R
78 * \317 - (disassembler only) invalid with REX.W
79 * \320 - indicates fixed 16-bit operand size, i.e. optional 0x66.
80 * \321 - indicates fixed 32-bit operand size, i.e. optional 0x66.
81 * \322 - indicates that this instruction is only valid when the
82 * operand size is the default (instruction to disassembler,
83 * generates no code in the assembler)
84 * \323 - indicates fixed 64-bit operand size, REX on extensions only.
85 * \324 - indicates 64-bit operand size requiring REX prefix.
86 * \330 - a literal byte follows in the code stream, to be added
87 * to the condition code value of the instruction.
88 * \331 - instruction not valid with REP prefix. Hint for
89 * disassembler only; for SSE instructions.
90 * \332 - REP prefix (0xF2 byte) used as opcode extension.
91 * \333 - REP prefix (0xF3 byte) used as opcode extension.
92 * \334 - LOCK prefix used instead of REX.R
93 * \335 - disassemble a rep (0xF3 byte) prefix as repe not rep.
94 * \340 - reserve <operand 0> bytes of uninitialized storage.
95 * Operand 0 had better be a segmentless constant.
96 * \360 - no SSE prefix (== \364\331)
97 * \361 - 66 SSE prefix (== \366\331)
98 * \362 - F2 SSE prefix (== \364\332)
99 * \363 - F3 SSE prefix (== \364\333)
100 * \364 - operand-size prefix (0x66) not permitted
101 * \365 - address-size prefix (0x67) not permitted
102 * \366 - operand-size prefix (0x66) used as opcode extension
103 * \367 - address-size prefix (0x67) used as opcode extension
104 * \370,\371,\372 - match only if operand 0 meets byte jump criteria.
105 * 370 is used for Jcc, 371 is used for JMP.
106 * \373 - assemble 0x03 if bits==16, 0x05 if bits==32;
107 * used for conditional jump over longer jump
110 #include "compiler.h"
114 #include <inttypes.h>
118 #include "assemble.h"
123 /* Initialized to zero by the C standard */
124 static const uint8_t const_zero_buf
[256];
127 int sib_present
; /* is a SIB byte necessary? */
128 int bytes
; /* # of bytes of offset needed */
129 int size
; /* lazy - this is sib+bytes+1 */
130 uint8_t modrm
, sib
, rex
, rip
; /* the bytes themselves */
133 static uint32_t cpu
; /* cpu level received from nasm.c */
134 static efunc errfunc
;
135 static struct ofmt
*outfmt
;
136 static ListGen
*list
;
138 static int64_t calcsize(int32_t, int64_t, int, insn
*, const uint8_t *);
139 static void gencode(int32_t, int64_t, int, insn
*, const uint8_t *, int64_t);
140 static int matches(const struct itemplate
*, insn
*, int bits
);
141 static int32_t regflag(const operand
*);
142 static int32_t regval(const operand
*);
143 static int rexflags(int, int32_t, int);
144 static int op_rexflags(const operand
*, int);
145 static ea
*process_ea(operand
*, ea
*, int, int, int, int32_t, int);
146 static void add_asp(insn
*, int);
148 static int has_prefix(insn
* ins
, enum prefix_pos pos
, enum prefixes prefix
)
150 return ins
->prefixes
[pos
] == prefix
;
153 static void assert_no_prefix(insn
* ins
, enum prefix_pos pos
)
155 if (ins
->prefixes
[pos
])
156 errfunc(ERR_NONFATAL
, "invalid %s prefix",
157 prefix_name(ins
->prefixes
[pos
]));
160 static const char *size_name(int size
)
182 static void warn_overflow(int size
, int64_t data
)
185 int64_t lim
= ((int64_t)1 << (size
*8))-1;
187 if (data
< ~lim
|| data
> lim
)
188 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
189 "%s data exceeds bounds", size_name(size
));
193 * This routine wrappers the real output format's output routine,
194 * in order to pass a copy of the data off to the listing file
195 * generator at the same time.
197 static void out(int64_t offset
, int32_t segto
, const void *data
,
198 enum out_type type
, uint64_t size
,
199 int32_t segment
, int32_t wrt
)
201 static int32_t lineno
= 0; /* static!!! */
202 static char *lnfname
= NULL
;
205 if (type
== OUT_ADDRESS
&& segment
== NO_SEG
&& wrt
== NO_SEG
) {
207 * This is a non-relocated address, and we're going to
208 * convert it into RAWDATA format.
213 errfunc(ERR_PANIC
, "OUT_ADDRESS with size > 8");
217 WRITEADDR(q
, *(int64_t *)data
, size
);
222 list
->output(offset
, data
, type
, size
);
225 * this call to src_get determines when we call the
226 * debug-format-specific "linenum" function
227 * it updates lineno and lnfname to the current values
228 * returning 0 if "same as last time", -2 if lnfname
229 * changed, and the amount by which lineno changed,
230 * if it did. thus, these variables must be static
233 if (src_get(&lineno
, &lnfname
)) {
234 outfmt
->current_dfmt
->linenum(lnfname
, lineno
, segto
);
237 outfmt
->output(segto
, data
, type
, size
, segment
, wrt
);
240 static int jmp_match(int32_t segment
, int64_t offset
, int bits
,
241 insn
* ins
, const uint8_t *code
)
246 if (c
!= 0370 && c
!= 0371)
248 if (ins
->oprs
[0].opflags
& OPFLAG_FORWARD
) {
249 if ((optimizing
< 0 || (ins
->oprs
[0].type
& STRICT
))
253 return (pass0
== 0); /* match a forward reference */
255 isize
= calcsize(segment
, offset
, bits
, ins
, code
);
256 if (ins
->oprs
[0].segment
!= segment
)
258 isize
= ins
->oprs
[0].offset
- offset
- isize
; /* isize is now the delta */
259 if (isize
>= -128L && isize
<= 127L)
260 return 1; /* it is byte size */
265 int64_t assemble(int32_t segment
, int64_t offset
, int bits
, uint32_t cp
,
266 insn
* instruction
, struct ofmt
*output
, efunc error
,
269 const struct itemplate
*temp
;
274 int64_t start
= offset
;
275 int64_t wsize
= 0; /* size for DB etc. */
277 errfunc
= error
; /* to pass to other functions */
279 outfmt
= output
; /* likewise */
280 list
= listgen
; /* and again */
282 switch (instruction
->opcode
) {
312 int32_t t
= instruction
->times
;
315 "instruction->times < 0 (%ld) in assemble()", t
);
317 while (t
--) { /* repeat TIMES times */
318 for (e
= instruction
->eops
; e
; e
= e
->next
) {
319 if (e
->type
== EOT_DB_NUMBER
) {
321 if (e
->segment
!= NO_SEG
)
322 errfunc(ERR_NONFATAL
,
323 "one-byte relocation attempted");
325 uint8_t out_byte
= e
->offset
;
326 out(offset
, segment
, &out_byte
,
327 OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
329 } else if (wsize
> 8) {
330 errfunc(ERR_NONFATAL
,
331 "integer supplied to a DT, DO or DY"
334 out(offset
, segment
, &e
->offset
,
335 OUT_ADDRESS
, wsize
, e
->segment
, e
->wrt
);
337 } else if (e
->type
== EOT_DB_STRING
) {
340 out(offset
, segment
, e
->stringval
,
341 OUT_RAWDATA
, e
->stringlen
, NO_SEG
, NO_SEG
);
342 align
= e
->stringlen
% wsize
;
345 align
= wsize
- align
;
346 out(offset
, segment
, const_zero_buf
,
347 OUT_RAWDATA
, align
, NO_SEG
, NO_SEG
);
349 offset
+= e
->stringlen
+ align
;
352 if (t
> 0 && t
== instruction
->times
- 1) {
354 * Dummy call to list->output to give the offset to the
357 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
358 list
->uplevel(LIST_TIMES
);
361 if (instruction
->times
> 1)
362 list
->downlevel(LIST_TIMES
);
363 return offset
- start
;
366 if (instruction
->opcode
== I_INCBIN
) {
367 static char fname
[FILENAME_MAX
];
370 char *prefix
= "", *combine
;
371 char **pPrevPath
= NULL
;
373 len
= FILENAME_MAX
- 1;
374 if (len
> instruction
->eops
->stringlen
)
375 len
= instruction
->eops
->stringlen
;
376 strncpy(fname
, instruction
->eops
->stringval
, len
);
379 while (1) { /* added by alexfru: 'incbin' uses include paths */
380 combine
= nasm_malloc(strlen(prefix
) + len
+ 1);
381 strcpy(combine
, prefix
);
382 strcat(combine
, fname
);
384 if ((fp
= fopen(combine
, "rb")) != NULL
) {
390 pPrevPath
= pp_get_include_path_ptr(pPrevPath
);
391 if (pPrevPath
== NULL
)
397 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
399 else if (fseek(fp
, 0L, SEEK_END
) < 0)
400 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
403 static char buf
[2048];
404 int32_t t
= instruction
->times
;
408 if (instruction
->eops
->next
) {
409 base
= instruction
->eops
->next
->offset
;
411 if (instruction
->eops
->next
->next
&&
412 len
> instruction
->eops
->next
->next
->offset
)
413 len
= instruction
->eops
->next
->next
->offset
;
416 * Dummy call to list->output to give the offset to the
419 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
420 list
->uplevel(LIST_INCBIN
);
424 fseek(fp
, base
, SEEK_SET
);
428 fread(buf
, 1, (l
> (int32_t) sizeof(buf
) ? (int32_t) sizeof(buf
) : l
),
432 * This shouldn't happen unless the file
433 * actually changes while we are reading
437 "`incbin': unexpected EOF while"
438 " reading file `%s'", fname
);
439 t
= 0; /* Try to exit cleanly */
442 out(offset
, segment
, buf
, OUT_RAWDATA
, m
,
447 list
->downlevel(LIST_INCBIN
);
448 if (instruction
->times
> 1) {
450 * Dummy call to list->output to give the offset to the
453 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
454 list
->uplevel(LIST_TIMES
);
455 list
->downlevel(LIST_TIMES
);
458 return instruction
->times
* len
;
460 return 0; /* if we're here, there's an error */
463 /* Check to see if we need an address-size prefix */
464 add_asp(instruction
, bits
);
468 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++){
469 int m
= matches(temp
, instruction
, bits
);
472 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
474 if (m
== 100) { /* matches! */
475 const uint8_t *codes
= temp
->code
;
476 int64_t insn_size
= calcsize(segment
, offset
, bits
,
478 itimes
= instruction
->times
;
479 if (insn_size
< 0) /* shouldn't be, on pass two */
480 error(ERR_PANIC
, "errors made it through from pass one");
483 for (j
= 0; j
< MAXPREFIX
; j
++) {
485 switch (instruction
->prefixes
[j
]) {
501 "cs segment base generated, but will be ignored in 64-bit mode");
508 "ds segment base generated, but will be ignored in 64-bit mode");
515 "es segment base generated, but will be ignored in 64-bit mode");
528 "ss segment base generated, but will be ignored in 64-bit mode");
535 "segr6 and segr7 cannot be used as prefixes");
540 "16-bit addressing is not supported "
542 } else if (bits
!= 16)
552 "64-bit addressing is only supported "
576 error(ERR_PANIC
, "invalid instruction prefix");
579 out(offset
, segment
, &c
, OUT_RAWDATA
, 1,
584 insn_end
= offset
+ insn_size
;
585 gencode(segment
, offset
, bits
, instruction
, codes
,
588 if (itimes
> 0 && itimes
== instruction
->times
- 1) {
590 * Dummy call to list->output to give the offset to the
593 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
594 list
->uplevel(LIST_TIMES
);
597 if (instruction
->times
> 1)
598 list
->downlevel(LIST_TIMES
);
599 return offset
- start
;
600 } else if (m
> 0 && m
> size_prob
) {
606 if (temp
->opcode
== -1) { /* didn't match any instruction */
609 error(ERR_NONFATAL
, "operation size not specified");
612 error(ERR_NONFATAL
, "mismatch in operand sizes");
615 error(ERR_NONFATAL
, "no instruction for this cpu level");
618 error(ERR_NONFATAL
, "instruction not supported in 64-bit mode");
622 "invalid combination of opcode and operands");
629 int64_t insn_size(int32_t segment
, int64_t offset
, int bits
, uint32_t cp
,
630 insn
* instruction
, efunc error
)
632 const struct itemplate
*temp
;
634 errfunc
= error
; /* to pass to other functions */
637 if (instruction
->opcode
== -1)
640 if (instruction
->opcode
== I_DB
|| instruction
->opcode
== I_DW
||
641 instruction
->opcode
== I_DD
|| instruction
->opcode
== I_DQ
||
642 instruction
->opcode
== I_DT
|| instruction
->opcode
== I_DO
||
643 instruction
->opcode
== I_DY
) {
645 int32_t isize
, osize
, wsize
= 0; /* placate gcc */
648 switch (instruction
->opcode
) {
674 for (e
= instruction
->eops
; e
; e
= e
->next
) {
678 if (e
->type
== EOT_DB_NUMBER
)
680 else if (e
->type
== EOT_DB_STRING
)
681 osize
= e
->stringlen
;
683 align
= (-osize
) % wsize
;
686 isize
+= osize
+ align
;
688 return isize
* instruction
->times
;
691 if (instruction
->opcode
== I_INCBIN
) {
692 char fname
[FILENAME_MAX
];
695 char *prefix
= "", *combine
;
696 char **pPrevPath
= NULL
;
698 len
= FILENAME_MAX
- 1;
699 if (len
> instruction
->eops
->stringlen
)
700 len
= instruction
->eops
->stringlen
;
701 strncpy(fname
, instruction
->eops
->stringval
, len
);
704 /* added by alexfru: 'incbin' uses include paths */
706 combine
= nasm_malloc(strlen(prefix
) + len
+ 1);
707 strcpy(combine
, prefix
);
708 strcat(combine
, fname
);
710 if ((fp
= fopen(combine
, "rb")) != NULL
) {
716 pPrevPath
= pp_get_include_path_ptr(pPrevPath
);
717 if (pPrevPath
== NULL
)
723 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
725 else if (fseek(fp
, 0L, SEEK_END
) < 0)
726 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
731 if (instruction
->eops
->next
) {
732 len
-= instruction
->eops
->next
->offset
;
733 if (instruction
->eops
->next
->next
&&
734 len
> instruction
->eops
->next
->next
->offset
) {
735 len
= instruction
->eops
->next
->next
->offset
;
738 return instruction
->times
* len
;
740 return 0; /* if we're here, there's an error */
743 /* Check to see if we need an address-size prefix */
744 add_asp(instruction
, bits
);
746 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++) {
747 int m
= matches(temp
, instruction
, bits
);
749 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
752 /* we've matched an instruction. */
754 const uint8_t *codes
= temp
->code
;
757 isize
= calcsize(segment
, offset
, bits
, instruction
, codes
);
760 for (j
= 0; j
< MAXPREFIX
; j
++) {
761 switch (instruction
->prefixes
[j
]) {
787 return isize
* instruction
->times
;
790 return -1; /* didn't match any instruction */
793 static bool possible_sbyte(insn
* ins
, int op
)
795 return !(ins
->forw_ref
&& ins
->oprs
[op
].opflags
) &&
797 !(ins
->oprs
[op
].type
& STRICT
) &&
798 ins
->oprs
[op
].wrt
== NO_SEG
&& ins
->oprs
[op
].segment
== NO_SEG
;
801 /* check that opn[op] is a signed byte of size 16 or 32 */
802 static bool is_sbyte16(insn
* ins
, int op
)
806 if (!possible_sbyte(ins
, op
))
809 v
= ins
->oprs
[op
].offset
;
810 return v
>= -128 && v
<= 127;
813 static bool is_sbyte32(insn
* ins
, int op
)
817 if (!possible_sbyte(ins
, op
))
820 v
= ins
->oprs
[op
].offset
;
821 return v
>= -128 && v
<= 127;
824 /* check that opn[op] is a signed byte of size 32; warn if this is not
825 the original value when extended to 64 bits */
826 static bool is_sbyte64(insn
* ins
, int op
)
831 /* dead in the water on forward reference or External */
832 if (!possible_sbyte(ins
, op
))
835 v64
= ins
->oprs
[op
].offset
;
838 warn_overflow(32, v64
);
840 return v32
>= -128 && v32
<= 127;
842 static int64_t calcsize(int32_t segment
, int64_t offset
, int bits
,
843 insn
* ins
, const uint8_t *codes
)
850 ins
->rex
= 0; /* Ensure REX is reset */
852 if (ins
->prefixes
[PPS_OSIZE
] == P_O64
)
855 (void)segment
; /* Don't warn that this parameter is unused */
856 (void)offset
; /* Don't warn that this parameter is unused */
860 opx
= &ins
->oprs
[c
& 3];
865 codes
+= c
, length
+= c
;
878 op_rexflags(opx
, REX_B
|REX_H
|REX_P
|REX_W
);
909 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
910 length
+= (opx
->type
& BITS16
) ? 2 : 4;
912 length
+= (bits
== 16) ? 2 : 4;
924 length
+= ins
->addr_size
>> 3;
936 length
+= 8; /* MOV reg64/imm */
948 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
949 length
+= (opx
->type
& BITS16
) ? 2 : 4;
951 length
+= (bits
== 16) ? 2 : 4;
969 length
+= is_sbyte16(ins
, c
& 3) ? 1 : 2;
982 length
+= is_sbyte32(ins
, c
& 3) ? 1 : 4;
997 ins
->drexdst
= regval(opx
);
1004 ins
->rex
|= REX_D
|REX_OC
;
1005 ins
->drexdst
= regval(opx
);
1019 length
+= is_sbyte64(ins
, c
& 3) ? 1 : 4;
1027 ins
->drexdst
= regval(opx
);
1028 ins
->vex_m
= *codes
++;
1029 ins
->vex_wlp
= *codes
++;
1035 ins
->vex_m
= *codes
++;
1036 ins
->vex_wlp
= *codes
++;
1046 length
+= (bits
!= 16) && !has_prefix(ins
, PPS_ASIZE
, P_A16
);
1049 length
+= (bits
!= 32) && !has_prefix(ins
, PPS_ASIZE
, P_A32
);
1054 if (bits
!= 64 || has_prefix(ins
, PPS_ASIZE
, P_A16
) ||
1055 has_prefix(ins
, PPS_ASIZE
, P_A32
))
1064 length
+= (bits
!= 16);
1067 length
+= (bits
== 16);
1092 if (ins
->oprs
[0].segment
!= NO_SEG
)
1093 errfunc(ERR_NONFATAL
, "attempt to reserve non-constant"
1094 " quantity of BSS space");
1096 length
+= ins
->oprs
[0].offset
;
1119 default: /* can't do it by 'case' statements */
1120 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1124 ea_data
.rex
= 0; /* Ensure ea.REX is initially 0 */
1127 /* pick rfield from operand b */
1128 rflags
= regflag(&ins
->oprs
[c
& 7]);
1129 rfield
= nasm_regvals
[ins
->oprs
[c
& 7].basereg
];
1136 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1137 ins
->addr_size
, rfield
, rflags
, ins
->forw_ref
)) {
1138 errfunc(ERR_NONFATAL
, "invalid effective address");
1141 ins
->rex
|= ea_data
.rex
;
1142 length
+= ea_data
.size
;
1145 errfunc(ERR_PANIC
, "internal instruction table corrupt"
1146 ": instruction code 0x%02X given", c
);
1151 ins
->rex
&= rex_mask
;
1153 if (ins
->rex
& REX_V
) {
1154 int bad32
= REX_R
|REX_W
|REX_X
|REX_B
;
1156 if (ins
->rex
& REX_H
) {
1157 errfunc(ERR_NONFATAL
, "cannot use high register in vex instruction");
1160 switch (ins
->vex_wlp
& 030) {
1173 if (bits
!= 64 && ((ins
->rex
& bad32
) || ins
->drexdst
> 7)) {
1174 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1177 if (ins
->vex_m
!= 1 || (ins
->rex
& (REX_W
|REX_R
|REX_B
)))
1181 } else if (ins
->rex
& REX_D
) {
1182 if (ins
->rex
& REX_H
) {
1183 errfunc(ERR_NONFATAL
, "cannot use high register in drex instruction");
1186 if (bits
!= 64 && ((ins
->rex
& (REX_R
|REX_W
|REX_X
|REX_B
)) ||
1187 ins
->drexdst
> 7)) {
1188 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1192 } else if (ins
->rex
& REX_REAL
) {
1193 if (ins
->rex
& REX_H
) {
1194 errfunc(ERR_NONFATAL
, "cannot use high register in rex instruction");
1196 } else if (bits
== 64) {
1198 } else if ((ins
->rex
& REX_L
) &&
1199 !(ins
->rex
& (REX_P
|REX_W
|REX_X
|REX_B
)) &&
1202 assert_no_prefix(ins
, PPS_LREP
);
1205 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1213 #define EMIT_REX() \
1214 if (!(ins->rex & (REX_D|REX_V)) && (ins->rex & REX_REAL) && (bits == 64)) { \
1215 ins->rex = (ins->rex & REX_REAL)|REX_P; \
1216 out(offset, segment, &ins->rex, OUT_RAWDATA, 1, NO_SEG, NO_SEG); \
1221 static void gencode(int32_t segment
, int64_t offset
, int bits
,
1222 insn
* ins
, const uint8_t *codes
, int64_t insn_end
)
1224 static char condval
[] = { /* conditional opcodes */
1225 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
1226 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
1227 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
1233 struct operand
*opx
;
1237 opx
= &ins
->oprs
[c
& 3];
1243 out(offset
, segment
, codes
, OUT_RAWDATA
, c
, NO_SEG
, NO_SEG
);
1250 switch (ins
->oprs
[0].basereg
) {
1252 bytes
[0] = 0x0E + (c
== 0x04 ? 1 : 0);
1255 bytes
[0] = 0x1E + (c
== 0x04 ? 1 : 0);
1258 bytes
[0] = 0x06 + (c
== 0x04 ? 1 : 0);
1261 bytes
[0] = 0x16 + (c
== 0x04 ? 1 : 0);
1265 "bizarre 8086 segment register received");
1267 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1273 switch (ins
->oprs
[0].basereg
) {
1275 bytes
[0] = 0xA0 + (c
== 0x05 ? 1 : 0);
1278 bytes
[0] = 0xA8 + (c
== 0x05 ? 1 : 0);
1282 "bizarre 386 segment register received");
1284 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1293 bytes
[0] = *codes
++ + ((regval(opx
)) & 7);
1294 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1302 /* XXX: warns for legitimate optimizer actions */
1303 if (opx
->offset
< -128 || opx
->offset
> 127) {
1304 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1305 "signed byte value exceeds bounds");
1308 if (opx
->segment
!= NO_SEG
) {
1310 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1311 opx
->segment
, opx
->wrt
);
1313 bytes
[0] = opx
->offset
;
1314 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1324 if (opx
->offset
< -256 || opx
->offset
> 255) {
1325 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1326 "byte value exceeds bounds");
1328 if (opx
->segment
!= NO_SEG
) {
1330 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1331 opx
->segment
, opx
->wrt
);
1333 bytes
[0] = opx
->offset
;
1334 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1344 if (opx
->offset
< 0 || opx
->offset
> 255)
1345 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1346 "unsigned byte value exceeds bounds");
1347 if (opx
->segment
!= NO_SEG
) {
1349 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1350 opx
->segment
, opx
->wrt
);
1352 bytes
[0] = opx
->offset
;
1353 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1364 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1365 warn_overflow(2, data
);
1366 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1367 opx
->segment
, opx
->wrt
);
1375 if (opx
->type
& (BITS16
| BITS32
))
1376 size
= (opx
->type
& BITS16
) ? 2 : 4;
1378 size
= (bits
== 16) ? 2 : 4;
1380 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1381 warn_overflow(size
, data
);
1382 out(offset
, segment
, &data
, OUT_ADDRESS
, size
,
1383 opx
->segment
, opx
->wrt
);
1392 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1393 warn_overflow(4, data
);
1394 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1395 opx
->segment
, opx
->wrt
);
1404 size
= ins
->addr_size
>> 3;
1405 if (opx
->segment
== NO_SEG
&&
1407 warn_overflow(size
, data
);
1408 out(offset
, segment
, &data
, OUT_ADDRESS
, size
,
1409 opx
->segment
, opx
->wrt
);
1417 if (opx
->segment
!= segment
)
1418 errfunc(ERR_NONFATAL
,
1419 "short relative jump outside segment");
1420 data
= opx
->offset
- insn_end
;
1421 if (data
> 127 || data
< -128)
1422 errfunc(ERR_NONFATAL
, "short jump is out of range");
1424 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1432 data
= (int64_t)opx
->offset
;
1433 out(offset
, segment
, &data
, OUT_ADDRESS
, 8,
1434 opx
->segment
, opx
->wrt
);
1442 if (opx
->segment
!= segment
) {
1444 out(offset
, segment
, &data
,
1445 OUT_REL2ADR
, insn_end
- offset
,
1446 opx
->segment
, opx
->wrt
);
1448 data
= opx
->offset
- insn_end
;
1449 out(offset
, segment
, &data
,
1450 OUT_ADDRESS
, 2, NO_SEG
, NO_SEG
);
1459 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
1460 size
= (opx
->type
& BITS16
) ? 2 : 4;
1462 size
= (bits
== 16) ? 2 : 4;
1463 if (opx
->segment
!= segment
) {
1465 out(offset
, segment
, &data
,
1466 size
== 2 ? OUT_REL2ADR
: OUT_REL4ADR
,
1467 insn_end
- offset
, opx
->segment
, opx
->wrt
);
1469 data
= opx
->offset
- insn_end
;
1470 out(offset
, segment
, &data
,
1471 OUT_ADDRESS
, size
, NO_SEG
, NO_SEG
);
1480 if (opx
->segment
!= segment
) {
1482 out(offset
, segment
, &data
,
1483 OUT_REL4ADR
, insn_end
- offset
,
1484 opx
->segment
, opx
->wrt
);
1486 data
= opx
->offset
- insn_end
;
1487 out(offset
, segment
, &data
,
1488 OUT_ADDRESS
, 4, NO_SEG
, NO_SEG
);
1497 if (opx
->segment
== NO_SEG
)
1498 errfunc(ERR_NONFATAL
, "value referenced by FAR is not"
1501 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1502 outfmt
->segbase(1 + opx
->segment
),
1512 if (is_sbyte16(ins
, c
& 3)) {
1514 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1518 if (opx
->segment
== NO_SEG
&&
1520 warn_overflow(2, data
);
1521 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1522 opx
->segment
, opx
->wrt
);
1532 bytes
[0] = *codes
++;
1533 if (is_sbyte16(ins
, c
& 3))
1534 bytes
[0] |= 2; /* s-bit */
1535 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1544 if (is_sbyte32(ins
, c
& 3)) {
1546 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1550 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1551 opx
->segment
, opx
->wrt
);
1561 bytes
[0] = *codes
++;
1562 if (is_sbyte32(ins
, c
& 3))
1563 bytes
[0] |= 2; /* s-bit */
1564 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1580 (ins
->drexdst
<< 4) |
1581 (ins
->rex
& REX_OC
? 0x08 : 0) |
1582 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1584 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1590 opx
= &ins
->oprs
[c
>> 3];
1591 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1592 opx
= &ins
->oprs
[c
& 7];
1593 if (opx
->segment
!= NO_SEG
|| opx
->wrt
!= NO_SEG
) {
1594 errfunc(ERR_NONFATAL
,
1595 "non-absolute expression not permitted as argument %d",
1598 if (opx
->offset
& ~15) {
1599 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1600 "four-bit argument exceeds bounds");
1602 bytes
[0] |= opx
->offset
& 15;
1604 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1610 opx
= &ins
->oprs
[c
>> 4];
1611 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1613 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1619 opx
= &ins
->oprs
[c
];
1620 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1621 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1630 /* is_sbyte32() is right here, we have already warned */
1631 if (is_sbyte32(ins
, c
& 3)) {
1633 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1637 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1638 opx
->segment
, opx
->wrt
);
1649 if (ins
->vex_m
!= 1 || (ins
->rex
& (REX_W
|REX_X
|REX_B
))) {
1651 bytes
[1] = ins
->vex_m
| ((~ins
->rex
& 7) << 5);
1652 bytes
[2] = ((ins
->rex
& REX_W
) << (7-3)) |
1653 ((~ins
->drexdst
& 15)<< 3) | (ins
->vex_wlp
& 07);
1654 out(offset
, segment
, &bytes
, OUT_RAWDATA
, 3, NO_SEG
, NO_SEG
);
1658 bytes
[1] = ((~ins
->rex
& REX_R
) << (7-2)) |
1659 ((~ins
->drexdst
& 15) << 3) | (ins
->vex_wlp
& 07);
1660 out(offset
, segment
, &bytes
, OUT_RAWDATA
, 2, NO_SEG
, NO_SEG
);
1672 if (bits
== 32 && !has_prefix(ins
, PPS_ASIZE
, P_A16
)) {
1674 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1681 if (bits
!= 32 && !has_prefix(ins
, PPS_ASIZE
, P_A32
)) {
1683 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1705 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1714 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1729 *bytes
= *codes
++ ^ condval
[ins
->condition
];
1730 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1739 *bytes
= c
- 0332 + 0xF2;
1740 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1745 if (ins
->rex
& REX_R
) {
1747 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1750 ins
->rex
&= ~(REX_L
|REX_R
);
1757 if (ins
->oprs
[0].segment
!= NO_SEG
)
1758 errfunc(ERR_PANIC
, "non-constant BSS size in pass two");
1760 int64_t size
= ins
->oprs
[0].offset
;
1762 out(offset
, segment
, NULL
,
1763 OUT_RESERVE
, size
, NO_SEG
, NO_SEG
);
1773 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1779 bytes
[0] = c
- 0362 + 0xf2;
1780 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1790 *bytes
= c
- 0366 + 0x66;
1791 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1801 *bytes
= bits
== 16 ? 3 : 5;
1802 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1806 default: /* can't do it by 'case' statements */
1807 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1815 /* pick rfield from operand b */
1816 rflags
= regflag(&ins
->oprs
[c
& 7]);
1817 rfield
= nasm_regvals
[ins
->oprs
[c
& 7].basereg
];
1819 /* rfield is constant */
1825 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1826 ins
->addr_size
, rfield
, rflags
, ins
->forw_ref
)) {
1827 errfunc(ERR_NONFATAL
, "invalid effective address");
1832 *p
++ = ea_data
.modrm
;
1833 if (ea_data
.sib_present
)
1836 /* DREX suffixes come between the SIB and the displacement */
1837 if (ins
->rex
& REX_D
) {
1839 (ins
->drexdst
<< 4) |
1840 (ins
->rex
& REX_OC
? 0x08 : 0) |
1841 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1846 out(offset
, segment
, bytes
, OUT_RAWDATA
, s
, NO_SEG
, NO_SEG
);
1848 switch (ea_data
.bytes
) {
1852 if (ins
->oprs
[(c
>> 3) & 7].segment
!= NO_SEG
) {
1853 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1854 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1855 ins
->oprs
[(c
>> 3) & 7].segment
,
1856 ins
->oprs
[(c
>> 3) & 7].wrt
);
1858 *bytes
= ins
->oprs
[(c
>> 3) & 7].offset
;
1859 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1,
1867 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1868 warn_overflow(ea_data
.bytes
, data
);
1869 out(offset
, segment
, &data
,
1870 ea_data
.rip
? OUT_REL4ADR
: OUT_ADDRESS
,
1872 ins
->oprs
[(c
>> 3) & 7].segment
,
1873 ins
->oprs
[(c
>> 3) & 7].wrt
);
1879 errfunc(ERR_PANIC
, "internal instruction table corrupt"
1880 ": instruction code 0x%02X given", c
);
1886 static int32_t regflag(const operand
* o
)
1888 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1889 errfunc(ERR_PANIC
, "invalid operand passed to regflag()");
1891 return nasm_reg_flags
[o
->basereg
];
1894 static int32_t regval(const operand
* o
)
1896 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1897 errfunc(ERR_PANIC
, "invalid operand passed to regval()");
1899 return nasm_regvals
[o
->basereg
];
1902 static int op_rexflags(const operand
* o
, int mask
)
1907 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1908 errfunc(ERR_PANIC
, "invalid operand passed to op_rexflags()");
1911 flags
= nasm_reg_flags
[o
->basereg
];
1912 val
= nasm_regvals
[o
->basereg
];
1914 return rexflags(val
, flags
, mask
);
1917 static int rexflags(int val
, int32_t flags
, int mask
)
1922 rex
|= REX_B
|REX_X
|REX_R
;
1925 if (!(REG_HIGH
& ~flags
)) /* AH, CH, DH, BH */
1927 else if (!(REG8
& ~flags
) && val
>= 4) /* SPL, BPL, SIL, DIL */
1933 static int matches(const struct itemplate
*itemp
, insn
* instruction
, int bits
)
1935 int i
, size
[MAX_OPERANDS
], asize
, oprs
, ret
;
1942 if (itemp
->opcode
!= instruction
->opcode
)
1946 * Count the operands
1948 if (itemp
->operands
!= instruction
->operands
)
1952 * Check that no spurious colons or TOs are present
1954 for (i
= 0; i
< itemp
->operands
; i
++)
1955 if (instruction
->oprs
[i
].type
& ~itemp
->opd
[i
] & (COLON
| TO
))
1959 * Process size flags
1961 if (itemp
->flags
& IF_ARMASK
) {
1962 memset(size
, 0, sizeof size
);
1964 i
= ((itemp
->flags
& IF_ARMASK
) >> IF_ARSHFT
) - 1;
1966 switch (itemp
->flags
& IF_SMASK
) {
2003 switch (itemp
->flags
& IF_SMASK
) {
2038 for (i
= 0; i
< MAX_OPERANDS
; i
++)
2043 * Check that the operand flags all match up
2045 for (i
= 0; i
< itemp
->operands
; i
++) {
2046 int32_t type
= instruction
->oprs
[i
].type
;
2047 if (!(type
& SIZE_MASK
))
2050 if (itemp
->opd
[i
] & SAME_AS
) {
2051 int j
= itemp
->opd
[i
] & ~SAME_AS
;
2052 if (type
!= instruction
->oprs
[j
].type
||
2053 instruction
->oprs
[i
].basereg
!= instruction
->oprs
[j
].basereg
)
2055 } else if (itemp
->opd
[i
] & ~type
||
2056 ((itemp
->opd
[i
] & SIZE_MASK
) &&
2057 ((itemp
->opd
[i
] ^ type
) & SIZE_MASK
))) {
2058 if ((itemp
->opd
[i
] & ~type
& ~SIZE_MASK
) ||
2067 * Check operand sizes
2069 if (itemp
->flags
& (IF_SM
| IF_SM2
)) {
2070 oprs
= (itemp
->flags
& IF_SM2
? 2 : itemp
->operands
);
2072 for (i
= 0; i
< oprs
; i
++) {
2073 if ((asize
= itemp
->opd
[i
] & SIZE_MASK
) != 0) {
2075 for (j
= 0; j
< oprs
; j
++)
2081 oprs
= itemp
->operands
;
2084 for (i
= 0; i
< itemp
->operands
; i
++) {
2085 if (!(itemp
->opd
[i
] & SIZE_MASK
) &&
2086 (instruction
->oprs
[i
].type
& SIZE_MASK
& ~size
[i
]))
2091 * Check template is okay at the set cpu level
2093 if (((itemp
->flags
& IF_PLEVEL
) > cpu
))
2097 * Check if instruction is available in long mode
2099 if ((itemp
->flags
& IF_NOLONG
) && (bits
== 64))
2103 * Check if special handling needed for Jumps
2105 if ((uint8_t)(itemp
->code
[0]) >= 0370)
2111 static ea
*process_ea(operand
* input
, ea
* output
, int bits
,
2112 int addrbits
, int rfield
, int32_t rflags
, int forw_ref
)
2114 output
->rip
= false;
2116 /* REX flags for the rfield operand */
2117 output
->rex
|= rexflags(rfield
, rflags
, REX_R
|REX_P
|REX_W
|REX_H
);
2119 if (!(REGISTER
& ~input
->type
)) { /* register direct */
2123 if (input
->basereg
< EXPR_REG_START
/* Verify as Register */
2124 || input
->basereg
>= REG_ENUM_LIMIT
)
2127 i
= nasm_regvals
[input
->basereg
];
2130 return NULL
; /* Invalid EA register */
2132 output
->rex
|= op_rexflags(input
, REX_B
|REX_P
|REX_W
|REX_H
);
2134 output
->sib_present
= false; /* no SIB necessary */
2135 output
->bytes
= 0; /* no offset necessary either */
2136 output
->modrm
= 0xC0 | ((rfield
& 7) << 3) | (i
& 7);
2137 } else { /* it's a memory reference */
2138 if (input
->basereg
== -1
2139 && (input
->indexreg
== -1 || input
->scale
== 0)) {
2140 /* it's a pure offset */
2141 if (bits
== 64 && (~input
->type
& IP_REL
)) {
2142 int scale
, index
, base
;
2143 output
->sib_present
= true;
2147 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
2149 output
->modrm
= 4 | ((rfield
& 7) << 3);
2150 output
->rip
= false;
2152 output
->sib_present
= false;
2153 output
->bytes
= (addrbits
!= 16 ? 4 : 2);
2154 output
->modrm
= (addrbits
!= 16 ? 5 : 6) | ((rfield
& 7) << 3);
2155 output
->rip
= bits
== 64;
2157 } else { /* it's an indirection */
2158 int i
= input
->indexreg
, b
= input
->basereg
, s
= input
->scale
;
2159 int32_t o
= input
->offset
, seg
= input
->segment
;
2160 int hb
= input
->hintbase
, ht
= input
->hinttype
;
2163 int32_t ix
, bx
; /* register flags */
2166 i
= -1; /* make this easy, at least */
2168 if (i
>= EXPR_REG_START
&& i
< REG_ENUM_LIMIT
) {
2169 it
= nasm_regvals
[i
];
2170 ix
= nasm_reg_flags
[i
];
2176 if (b
>= EXPR_REG_START
&& b
< REG_ENUM_LIMIT
) {
2177 bt
= nasm_regvals
[b
];
2178 bx
= nasm_reg_flags
[b
];
2184 /* check for a 32/64-bit memory reference... */
2185 if ((ix
|bx
) & (BITS32
|BITS64
)) {
2186 /* it must be a 32/64-bit memory reference. Firstly we have
2187 * to check that all registers involved are type E/Rxx. */
2188 int32_t sok
= BITS32
|BITS64
;
2191 if (!(REG64
& ~ix
) || !(REG32
& ~ix
))
2199 return NULL
; /* Invalid register */
2200 if (~sok
& bx
& SIZE_MASK
)
2201 return NULL
; /* Invalid size */
2205 /* While we're here, ensure the user didn't specify
2207 if (input
->disp_size
== 16 || input
->disp_size
== 64)
2210 if (addrbits
== 16 ||
2211 (addrbits
== 32 && !(sok
& BITS32
)) ||
2212 (addrbits
== 64 && !(sok
& BITS64
)))
2215 /* now reorganize base/index */
2216 if (s
== 1 && bt
!= it
&& bt
!= -1 && it
!= -1 &&
2217 ((hb
== b
&& ht
== EAH_NOTBASE
)
2218 || (hb
== i
&& ht
== EAH_MAKEBASE
))) {
2219 /* swap if hints say so */
2220 t
= bt
, bt
= it
, it
= t
;
2221 t
= bx
, bx
= ix
, ix
= t
;
2223 if (bt
== it
) /* convert EAX+2*EAX to 3*EAX */
2224 bt
= -1, bx
= 0, s
++;
2225 if (bt
== -1 && s
== 1 && !(hb
== it
&& ht
== EAH_NOTBASE
)) {
2226 /* make single reg base, unless hint */
2227 bt
= it
, bx
= ix
, it
= -1, ix
= 0;
2229 if (((s
== 2 && it
!= REG_NUM_ESP
2230 && !(input
->eaflags
& EAF_TIMESTWO
)) || s
== 3
2231 || s
== 5 || s
== 9) && bt
== -1)
2232 bt
= it
, bx
= ix
, s
--; /* convert 3*EAX to EAX+2*EAX */
2233 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
2234 && (input
->eaflags
& EAF_TIMESTWO
))
2235 it
= bt
, ix
= bx
, bt
= -1, bx
= 0, s
= 1;
2236 /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */
2237 if (s
== 1 && it
== REG_NUM_ESP
) {
2238 /* swap ESP into base if scale is 1 */
2239 t
= it
, it
= bt
, bt
= t
;
2240 t
= ix
, ix
= bx
, bx
= t
;
2242 if (it
== REG_NUM_ESP
2243 || (s
!= 1 && s
!= 2 && s
!= 4 && s
!= 8 && it
!= -1))
2244 return NULL
; /* wrong, for various reasons */
2246 output
->rex
|= rexflags(it
, ix
, REX_X
);
2247 output
->rex
|= rexflags(bt
, bx
, REX_B
);
2249 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
) {
2258 if (rm
!= REG_NUM_EBP
&& o
== 0 &&
2259 seg
== NO_SEG
&& !forw_ref
&&
2261 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2263 else if (input
->eaflags
& EAF_BYTEOFFS
||
2264 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2266 && !(input
->eaflags
& EAF_WORDOFFS
)))
2272 output
->sib_present
= false;
2273 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
2274 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
2277 int mod
, scale
, index
, base
;
2297 default: /* then what the smeg is it? */
2298 return NULL
; /* panic */
2306 if (base
!= REG_NUM_EBP
&& o
== 0 &&
2307 seg
== NO_SEG
&& !forw_ref
&&
2309 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2311 else if (input
->eaflags
& EAF_BYTEOFFS
||
2312 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2314 && !(input
->eaflags
& EAF_WORDOFFS
)))
2320 output
->sib_present
= true;
2321 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
2322 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | 4;
2323 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
2325 } else { /* it's 16-bit */
2328 /* check for 64-bit long mode */
2332 /* check all registers are BX, BP, SI or DI */
2333 if ((b
!= -1 && b
!= R_BP
&& b
!= R_BX
&& b
!= R_SI
2334 && b
!= R_DI
) || (i
!= -1 && i
!= R_BP
&& i
!= R_BX
2335 && i
!= R_SI
&& i
!= R_DI
))
2338 /* ensure the user didn't specify DWORD/QWORD */
2339 if (input
->disp_size
== 32 || input
->disp_size
== 64)
2342 if (s
!= 1 && i
!= -1)
2343 return NULL
; /* no can do, in 16-bit EA */
2344 if (b
== -1 && i
!= -1) {
2349 if ((b
== R_SI
|| b
== R_DI
) && i
!= -1) {
2354 /* have BX/BP as base, SI/DI index */
2356 return NULL
; /* shouldn't ever happen, in theory */
2357 if (i
!= -1 && b
!= -1 &&
2358 (i
== R_BP
|| i
== R_BX
|| b
== R_SI
|| b
== R_DI
))
2359 return NULL
; /* invalid combinations */
2360 if (b
== -1) /* pure offset: handled above */
2361 return NULL
; /* so if it gets to here, panic! */
2365 switch (i
* 256 + b
) {
2366 case R_SI
* 256 + R_BX
:
2369 case R_DI
* 256 + R_BX
:
2372 case R_SI
* 256 + R_BP
:
2375 case R_DI
* 256 + R_BP
:
2393 if (rm
== -1) /* can't happen, in theory */
2394 return NULL
; /* so panic if it does */
2396 if (o
== 0 && seg
== NO_SEG
&& !forw_ref
&& rm
!= 6 &&
2397 !(input
->eaflags
& (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2399 else if (input
->eaflags
& EAF_BYTEOFFS
||
2400 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2402 && !(input
->eaflags
& EAF_WORDOFFS
)))
2407 output
->sib_present
= false; /* no SIB - it's 16-bit */
2408 output
->bytes
= mod
; /* bytes of offset needed */
2409 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
2414 output
->size
= 1 + output
->sib_present
+ output
->bytes
;
2418 static void add_asp(insn
*ins
, int addrbits
)
2423 valid
= (addrbits
== 64) ? 64|32 : 32|16;
2425 switch (ins
->prefixes
[PPS_ASIZE
]) {
2436 valid
&= (addrbits
== 32) ? 16 : 32;
2442 for (j
= 0; j
< ins
->operands
; j
++) {
2443 if (!(MEMORY
& ~ins
->oprs
[j
].type
)) {
2446 /* Verify as Register */
2447 if (ins
->oprs
[j
].indexreg
< EXPR_REG_START
2448 || ins
->oprs
[j
].indexreg
>= REG_ENUM_LIMIT
)
2451 i
= nasm_reg_flags
[ins
->oprs
[j
].indexreg
];
2453 /* Verify as Register */
2454 if (ins
->oprs
[j
].basereg
< EXPR_REG_START
2455 || ins
->oprs
[j
].basereg
>= REG_ENUM_LIMIT
)
2458 b
= nasm_reg_flags
[ins
->oprs
[j
].basereg
];
2460 if (ins
->oprs
[j
].scale
== 0)
2464 int ds
= ins
->oprs
[j
].disp_size
;
2465 if ((addrbits
!= 64 && ds
> 8) ||
2466 (addrbits
== 64 && ds
== 16))
2486 if (valid
& addrbits
) {
2487 ins
->addr_size
= addrbits
;
2488 } else if (valid
& ((addrbits
== 32) ? 16 : 32)) {
2489 /* Add an address size prefix */
2490 enum prefixes pref
= (addrbits
== 32) ? P_A16
: P_A32
;
2491 ins
->prefixes
[PPS_ASIZE
] = pref
;
2492 ins
->addr_size
= (addrbits
== 32) ? 16 : 32;
2495 errfunc(ERR_NONFATAL
, "impossible combination of address sizes");
2496 ins
->addr_size
= addrbits
; /* Error recovery */
2499 defdisp
= ins
->addr_size
== 16 ? 16 : 32;
2501 for (j
= 0; j
< ins
->operands
; j
++) {
2502 if (!(MEM_OFFS
& ~ins
->oprs
[j
].type
) &&
2503 (ins
->oprs
[j
].disp_size
? ins
->oprs
[j
].disp_size
: defdisp
)
2504 != ins
->addr_size
) {
2505 /* mem_offs sizes must match the address size; if not,
2506 strip the MEM_OFFS bit and match only EA instructions */
2507 ins
->oprs
[j
].type
&= ~(MEM_OFFS
& ~MEMORY
);