1 /* assemble.c code generation for the Netwide Assembler
3 * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
4 * Julian Hall. All rights reserved. The software is
5 * redistributable under the license given in the file "LICENSE"
6 * distributed in the NASM archive.
8 * the actual codes (C syntax, i.e. octal):
9 * \0 - terminates the code. (Unless it's a literal of course.)
10 * \1, \2, \3 - that many literal bytes follow in the code stream
11 * \4, \6 - the POP/PUSH (respectively) codes for CS, DS, ES, SS
12 * (POP is never used for CS) depending on operand 0
13 * \5, \7 - the second byte of POP/PUSH codes for FS, GS, depending
15 * \10..\13 - a literal byte follows in the code stream, to be added
16 * to the register value of operand 0..3
17 * \14..\17 - a signed byte immediate operand, from operand 0..3
18 * \20..\23 - a byte immediate operand, from operand 0..3
19 * \24..\27 - an unsigned byte immediate operand, from operand 0..3
20 * \30..\33 - a word immediate operand, from operand 0..3
21 * \34..\37 - select between \3[0-3] and \4[0-3] depending on 16/32 bit
22 * assembly mode or the operand-size override on the operand
23 * \40..\43 - a long immediate operand, from operand 0..3
24 * \44..\47 - select between \3[0-3], \4[0-3] and \5[4-7]
25 * depending on the address size of the instruction.
26 * \50..\53 - a byte relative operand, from operand 0..3
27 * \54..\57 - a qword immediate operand, from operand 0..3
28 * \60..\63 - a word relative operand, from operand 0..3
29 * \64..\67 - select between \6[0-3] and \7[0-3] depending on 16/32 bit
30 * assembly mode or the operand-size override on the operand
31 * \70..\73 - a long relative operand, from operand 0..3
32 * \74..\77 - a word constant, from the _segment_ part of operand 0..3
33 * \1ab - a ModRM, calculated on EA in operand a, with the spare
34 * field the register value of operand b.
35 * \140..\143 - an immediate word or signed byte for operand 0..3
36 * \144..\147 - or 2 (s-field) into opcode byte if operand 0..3
37 * is a signed byte rather than a word. Opcode byte follows.
38 * \150..\153 - an immediate dword or signed byte for operand 0..3
39 * \154..\157 - or 2 (s-field) into opcode byte if operand 0..3
40 * is a signed byte rather than a dword. Opcode byte follows.
41 * \160..\163 - this instruction uses DREX rather than REX, with the
42 * OC0 field set to 0, and the dest field taken from
44 * \164..\167 - this instruction uses DREX rather than REX, with the
45 * OC0 field set to 1, and the dest field taken from
47 * \171 - placement of DREX suffix in the absence of an EA
48 * \172\ab - the register number from operand a in bits 7..4, with
49 * the 4-bit immediate from operand b in bits 3..0.
50 * \173\xab - the register number from operand a in bits 7..4, with
51 * the value b in bits 3..0.
52 * \174\a - the register number from operand a in bits 7..4, and
53 * an arbitrary value in bits 3..0 (assembled as zero.)
54 * \2ab - a ModRM, calculated on EA in operand a, with the spare
55 * field equal to digit b.
56 * \250..\253 - same as \150..\153, except warn if the 64-bit operand
57 * is not equal to the truncated and sign-extended 32-bit
58 * operand; used for 32-bit immediates in 64-bit mode.
59 * \260..\263 - this instruction uses VEX rather than REX, with the
60 * V field taken from operand 0..3.
61 * \270 - this instruction uses VEX rather than REX, with the
62 * V field set to 1111b.
64 * VEX prefixes are followed by the sequence:
65 * \mm\wlp where mm is the M field; and wlp is:
67 * [w0] ww = 0 for W = 0
68 * [w1] ww = 1 for W = 1
69 * [wx] ww = 2 for W don't care (always assembled as 0)
70 * [ww] ww = 3 for W used as REX.W
73 * \310 - indicates fixed 16-bit address size, i.e. optional 0x67.
74 * \311 - indicates fixed 32-bit address size, i.e. optional 0x67.
75 * \312 - (disassembler only) marker on LOOP, LOOPxx instructions.
76 * \313 - indicates fixed 64-bit address size, 0x67 invalid.
77 * \314 - (disassembler only) invalid with REX.B
78 * \315 - (disassembler only) invalid with REX.X
79 * \316 - (disassembler only) invalid with REX.R
80 * \317 - (disassembler only) invalid with REX.W
81 * \320 - indicates fixed 16-bit operand size, i.e. optional 0x66.
82 * \321 - indicates fixed 32-bit operand size, i.e. optional 0x66.
83 * \322 - indicates that this instruction is only valid when the
84 * operand size is the default (instruction to disassembler,
85 * generates no code in the assembler)
86 * \323 - indicates fixed 64-bit operand size, REX on extensions only.
87 * \324 - indicates 64-bit operand size requiring REX prefix.
88 * \330 - a literal byte follows in the code stream, to be added
89 * to the condition code value of the instruction.
90 * \331 - instruction not valid with REP prefix. Hint for
91 * disassembler only; for SSE instructions.
92 * \332 - REP prefix (0xF2 byte) used as opcode extension.
93 * \333 - REP prefix (0xF3 byte) used as opcode extension.
94 * \334 - LOCK prefix used instead of REX.R
95 * \335 - disassemble a rep (0xF3 byte) prefix as repe not rep.
96 * \336 - force a REP(E) prefix (0xF2) even if not specified.
97 * \337 - force a REPNE prefix (0xF3) even if not specified.
98 * \336-\337 are still listed as prefixes in the disassembler.
99 * \340 - reserve <operand 0> bytes of uninitialized storage.
100 * Operand 0 had better be a segmentless constant.
101 * \360 - no SSE prefix (== \364\331)
102 * \361 - 66 SSE prefix (== \366\331)
103 * \362 - F2 SSE prefix (== \364\332)
104 * \363 - F3 SSE prefix (== \364\333)
105 * \364 - operand-size prefix (0x66) not permitted
106 * \365 - address-size prefix (0x67) not permitted
107 * \366 - operand-size prefix (0x66) used as opcode extension
108 * \367 - address-size prefix (0x67) used as opcode extension
109 * \370,\371,\372 - match only if operand 0 meets byte jump criteria.
110 * 370 is used for Jcc, 371 is used for JMP.
111 * \373 - assemble 0x03 if bits==16, 0x05 if bits==32;
112 * used for conditional jump over longer jump
115 #include "compiler.h"
119 #include <inttypes.h>
123 #include "assemble.h"
127 /* Initialized to zero by the C standard */
128 static const uint8_t const_zero_buf
[256];
131 int sib_present
; /* is a SIB byte necessary? */
132 int bytes
; /* # of bytes of offset needed */
133 int size
; /* lazy - this is sib+bytes+1 */
134 uint8_t modrm
, sib
, rex
, rip
; /* the bytes themselves */
137 static uint32_t cpu
; /* cpu level received from nasm.c */
138 static efunc errfunc
;
139 static struct ofmt
*outfmt
;
140 static ListGen
*list
;
142 static int64_t calcsize(int32_t, int64_t, int, insn
*, const uint8_t *);
143 static void gencode(int32_t, int64_t, int, insn
*, const uint8_t *, int64_t);
144 static int matches(const struct itemplate
*, insn
*, int bits
);
145 static int32_t regflag(const operand
*);
146 static int32_t regval(const operand
*);
147 static int rexflags(int, int32_t, int);
148 static int op_rexflags(const operand
*, int);
149 static ea
*process_ea(operand
*, ea
*, int, int, int, int32_t);
150 static void add_asp(insn
*, int);
152 static int has_prefix(insn
* ins
, enum prefix_pos pos
, enum prefixes prefix
)
154 return ins
->prefixes
[pos
] == prefix
;
157 static void assert_no_prefix(insn
* ins
, enum prefix_pos pos
)
159 if (ins
->prefixes
[pos
])
160 errfunc(ERR_NONFATAL
, "invalid %s prefix",
161 prefix_name(ins
->prefixes
[pos
]));
164 static const char *size_name(int size
)
186 static void warn_overflow(int size
, int64_t data
)
189 int64_t lim
= ((int64_t)1 << (size
*8))-1;
191 if (data
< ~lim
|| data
> lim
)
192 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
193 "%s data exceeds bounds", size_name(size
));
197 * This routine wrappers the real output format's output routine,
198 * in order to pass a copy of the data off to the listing file
199 * generator at the same time.
201 static void out(int64_t offset
, int32_t segto
, const void *data
,
202 enum out_type type
, uint64_t size
,
203 int32_t segment
, int32_t wrt
)
205 static int32_t lineno
= 0; /* static!!! */
206 static char *lnfname
= NULL
;
209 if (type
== OUT_ADDRESS
&& segment
== NO_SEG
&& wrt
== NO_SEG
) {
211 * This is a non-relocated address, and we're going to
212 * convert it into RAWDATA format.
217 errfunc(ERR_PANIC
, "OUT_ADDRESS with size > 8");
221 WRITEADDR(q
, *(int64_t *)data
, size
);
226 list
->output(offset
, data
, type
, size
);
229 * this call to src_get determines when we call the
230 * debug-format-specific "linenum" function
231 * it updates lineno and lnfname to the current values
232 * returning 0 if "same as last time", -2 if lnfname
233 * changed, and the amount by which lineno changed,
234 * if it did. thus, these variables must be static
237 if (src_get(&lineno
, &lnfname
)) {
238 outfmt
->current_dfmt
->linenum(lnfname
, lineno
, segto
);
241 outfmt
->output(segto
, data
, type
, size
, segment
, wrt
);
244 static int jmp_match(int32_t segment
, int64_t offset
, int bits
,
245 insn
* ins
, const uint8_t *code
)
250 if (c
!= 0370 && c
!= 0371)
252 if ((optimizing
<= 0 || (ins
->oprs
[0].type
& STRICT
)))
256 isize
= calcsize(segment
, offset
, bits
, ins
, code
);
257 if (ins
->oprs
[0].segment
!= segment
)
259 isize
= ins
->oprs
[0].offset
- offset
- isize
; /* isize is now the delta */
260 if (isize
>= -128L && isize
<= 127L)
261 return 1; /* it is byte size */
266 int64_t assemble(int32_t segment
, int64_t offset
, int bits
, uint32_t cp
,
267 insn
* instruction
, struct ofmt
*output
, efunc error
,
270 const struct itemplate
*temp
;
275 int64_t start
= offset
;
276 int64_t wsize
= 0; /* size for DB etc. */
278 errfunc
= error
; /* to pass to other functions */
280 outfmt
= output
; /* likewise */
281 list
= listgen
; /* and again */
283 switch (instruction
->opcode
) {
313 int32_t t
= instruction
->times
;
316 "instruction->times < 0 (%ld) in assemble()", t
);
318 while (t
--) { /* repeat TIMES times */
319 for (e
= instruction
->eops
; e
; e
= e
->next
) {
320 if (e
->type
== EOT_DB_NUMBER
) {
322 if (e
->segment
!= NO_SEG
)
323 errfunc(ERR_NONFATAL
,
324 "one-byte relocation attempted");
326 uint8_t out_byte
= e
->offset
;
327 out(offset
, segment
, &out_byte
,
328 OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
330 } else if (wsize
> 8) {
331 errfunc(ERR_NONFATAL
,
332 "integer supplied to a DT, DO or DY"
335 out(offset
, segment
, &e
->offset
,
336 OUT_ADDRESS
, wsize
, e
->segment
, e
->wrt
);
338 } else if (e
->type
== EOT_DB_STRING
||
339 e
->type
== EOT_DB_STRING_FREE
) {
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 const char *fname
= instruction
->eops
->stringval
;
372 fp
= fopen(fname
, "rb");
374 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
376 } else if (fseek(fp
, 0L, SEEK_END
) < 0) {
377 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
380 static char buf
[4096];
381 size_t t
= instruction
->times
;
386 if (instruction
->eops
->next
) {
387 base
= instruction
->eops
->next
->offset
;
389 if (instruction
->eops
->next
->next
&&
390 len
> (size_t)instruction
->eops
->next
->next
->offset
)
391 len
= (size_t)instruction
->eops
->next
->next
->offset
;
394 * Dummy call to list->output to give the offset to the
397 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
398 list
->uplevel(LIST_INCBIN
);
402 fseek(fp
, base
, SEEK_SET
);
406 fread(buf
, 1, (l
> (int32_t) sizeof(buf
) ? (int32_t) sizeof(buf
) : l
),
410 * This shouldn't happen unless the file
411 * actually changes while we are reading
415 "`incbin': unexpected EOF while"
416 " reading file `%s'", fname
);
417 t
= 0; /* Try to exit cleanly */
420 out(offset
, segment
, buf
, OUT_RAWDATA
, m
,
425 list
->downlevel(LIST_INCBIN
);
426 if (instruction
->times
> 1) {
428 * Dummy call to list->output to give the offset to the
431 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
432 list
->uplevel(LIST_TIMES
);
433 list
->downlevel(LIST_TIMES
);
436 return instruction
->times
* len
;
438 return 0; /* if we're here, there's an error */
441 /* Check to see if we need an address-size prefix */
442 add_asp(instruction
, bits
);
446 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++){
447 int m
= matches(temp
, instruction
, bits
);
450 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
452 if (m
== 100) { /* matches! */
453 const uint8_t *codes
= temp
->code
;
454 int64_t insn_size
= calcsize(segment
, offset
, bits
,
456 itimes
= instruction
->times
;
457 if (insn_size
< 0) /* shouldn't be, on pass two */
458 error(ERR_PANIC
, "errors made it through from pass one");
461 for (j
= 0; j
< MAXPREFIX
; j
++) {
463 switch (instruction
->prefixes
[j
]) {
479 "cs segment base generated, but will be ignored in 64-bit mode");
486 "ds segment base generated, but will be ignored in 64-bit mode");
493 "es segment base generated, but will be ignored in 64-bit mode");
506 "ss segment base generated, but will be ignored in 64-bit mode");
513 "segr6 and segr7 cannot be used as prefixes");
518 "16-bit addressing is not supported "
520 } else if (bits
!= 16)
530 "64-bit addressing is only supported "
554 error(ERR_PANIC
, "invalid instruction prefix");
557 out(offset
, segment
, &c
, OUT_RAWDATA
, 1,
562 insn_end
= offset
+ insn_size
;
563 gencode(segment
, offset
, bits
, instruction
, codes
,
566 if (itimes
> 0 && itimes
== instruction
->times
- 1) {
568 * Dummy call to list->output to give the offset to the
571 list
->output(offset
, NULL
, OUT_RAWDATA
, 0);
572 list
->uplevel(LIST_TIMES
);
575 if (instruction
->times
> 1)
576 list
->downlevel(LIST_TIMES
);
577 return offset
- start
;
578 } else if (m
> 0 && m
> size_prob
) {
584 if (temp
->opcode
== -1) { /* didn't match any instruction */
587 error(ERR_NONFATAL
, "operation size not specified");
590 error(ERR_NONFATAL
, "mismatch in operand sizes");
593 error(ERR_NONFATAL
, "no instruction for this cpu level");
596 error(ERR_NONFATAL
, "instruction not supported in 64-bit mode");
600 "invalid combination of opcode and operands");
607 int64_t insn_size(int32_t segment
, int64_t offset
, int bits
, uint32_t cp
,
608 insn
* instruction
, efunc error
)
610 const struct itemplate
*temp
;
612 errfunc
= error
; /* to pass to other functions */
615 if (instruction
->opcode
== -1)
618 if (instruction
->opcode
== I_DB
|| instruction
->opcode
== I_DW
||
619 instruction
->opcode
== I_DD
|| instruction
->opcode
== I_DQ
||
620 instruction
->opcode
== I_DT
|| instruction
->opcode
== I_DO
||
621 instruction
->opcode
== I_DY
) {
623 int32_t isize
, osize
, wsize
= 0; /* placate gcc */
626 switch (instruction
->opcode
) {
652 for (e
= instruction
->eops
; e
; e
= e
->next
) {
656 if (e
->type
== EOT_DB_NUMBER
)
658 else if (e
->type
== EOT_DB_STRING
||
659 e
->type
== EOT_DB_STRING_FREE
)
660 osize
= e
->stringlen
;
662 align
= (-osize
) % wsize
;
665 isize
+= osize
+ align
;
667 return isize
* instruction
->times
;
670 if (instruction
->opcode
== I_INCBIN
) {
671 const char *fname
= instruction
->eops
->stringval
;
675 fp
= fopen(fname
, "rb");
677 error(ERR_NONFATAL
, "`incbin': unable to open file `%s'",
679 else if (fseek(fp
, 0L, SEEK_END
) < 0)
680 error(ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
685 if (instruction
->eops
->next
) {
686 len
-= instruction
->eops
->next
->offset
;
687 if (instruction
->eops
->next
->next
&&
688 len
> (size_t)instruction
->eops
->next
->next
->offset
) {
689 len
= (size_t)instruction
->eops
->next
->next
->offset
;
692 return instruction
->times
* len
;
694 return 0; /* if we're here, there's an error */
697 /* Check to see if we need an address-size prefix */
698 add_asp(instruction
, bits
);
700 for (temp
= nasm_instructions
[instruction
->opcode
]; temp
->opcode
!= -1; temp
++) {
701 int m
= matches(temp
, instruction
, bits
);
703 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
706 /* we've matched an instruction. */
708 const uint8_t *codes
= temp
->code
;
711 isize
= calcsize(segment
, offset
, bits
, instruction
, codes
);
714 for (j
= 0; j
< MAXPREFIX
; j
++) {
715 switch (instruction
->prefixes
[j
]) {
741 return isize
* instruction
->times
;
744 return -1; /* didn't match any instruction */
747 static bool possible_sbyte(operand
*o
)
749 return !(o
->opflags
& OPFLAG_FORWARD
) &&
750 optimizing
>= 0 && !(o
->type
& STRICT
) &&
751 o
->wrt
== NO_SEG
&& o
->segment
== NO_SEG
;
754 /* check that opn[op] is a signed byte of size 16 or 32 */
755 static bool is_sbyte16(operand
*o
)
759 if (!possible_sbyte(o
))
763 return v
>= -128 && v
<= 127;
766 static bool is_sbyte32(operand
*o
)
770 if (!possible_sbyte(o
))
774 return v
>= -128 && v
<= 127;
777 /* check that opn[op] is a signed byte of size 32; warn if this is not
778 the original value when extended to 64 bits */
779 static bool is_sbyte64(operand
*o
)
784 /* dead in the water on forward reference or External */
785 if (!possible_sbyte(o
))
791 warn_overflow(32, v64
);
793 return v32
>= -128 && v32
<= 127;
795 static int64_t calcsize(int32_t segment
, int64_t offset
, int bits
,
796 insn
* ins
, const uint8_t *codes
)
803 ins
->rex
= 0; /* Ensure REX is reset */
805 if (ins
->prefixes
[PPS_OSIZE
] == P_O64
)
808 (void)segment
; /* Don't warn that this parameter is unused */
809 (void)offset
; /* Don't warn that this parameter is unused */
813 opx
= &ins
->oprs
[c
& 3];
818 codes
+= c
, length
+= c
;
831 op_rexflags(opx
, REX_B
|REX_H
|REX_P
|REX_W
);
862 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
863 length
+= (opx
->type
& BITS16
) ? 2 : 4;
865 length
+= (bits
== 16) ? 2 : 4;
877 length
+= ins
->addr_size
>> 3;
889 length
+= 8; /* MOV reg64/imm */
901 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
902 length
+= (opx
->type
& BITS16
) ? 2 : 4;
904 length
+= (bits
== 16) ? 2 : 4;
922 length
+= is_sbyte16(opx
) ? 1 : 2;
935 length
+= is_sbyte32(opx
) ? 1 : 4;
950 ins
->drexdst
= regval(opx
);
957 ins
->rex
|= REX_D
|REX_OC
;
958 ins
->drexdst
= regval(opx
);
972 length
+= is_sbyte64(opx
) ? 1 : 4;
979 ins
->drexdst
= regval(opx
);
980 ins
->vex_m
= *codes
++;
981 ins
->vex_wlp
= *codes
++;
986 ins
->vex_m
= *codes
++;
987 ins
->vex_wlp
= *codes
++;
997 length
+= (bits
!= 16) && !has_prefix(ins
, PPS_ASIZE
, P_A16
);
1000 length
+= (bits
!= 32) && !has_prefix(ins
, PPS_ASIZE
, P_A32
);
1005 if (bits
!= 64 || has_prefix(ins
, PPS_ASIZE
, P_A16
) ||
1006 has_prefix(ins
, PPS_ASIZE
, P_A32
))
1015 length
+= (bits
!= 16);
1018 length
+= (bits
== 16);
1043 if (!ins
->prefixes
[PPS_LREP
])
1044 ins
->prefixes
[PPS_LREP
] = P_REP
;
1047 if (!ins
->prefixes
[PPS_LREP
])
1048 ins
->prefixes
[PPS_LREP
] = P_REPNE
;
1051 if (ins
->oprs
[0].segment
!= NO_SEG
)
1052 errfunc(ERR_NONFATAL
, "attempt to reserve non-constant"
1053 " quantity of BSS space");
1055 length
+= ins
->oprs
[0].offset
;
1078 default: /* can't do it by 'case' statements */
1079 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1083 ea_data
.rex
= 0; /* Ensure ea.REX is initially 0 */
1086 /* pick rfield from operand b */
1087 rflags
= regflag(&ins
->oprs
[c
& 7]);
1088 rfield
= nasm_regvals
[ins
->oprs
[c
& 7].basereg
];
1095 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1096 ins
->addr_size
, rfield
, rflags
)) {
1097 errfunc(ERR_NONFATAL
, "invalid effective address");
1100 ins
->rex
|= ea_data
.rex
;
1101 length
+= ea_data
.size
;
1104 errfunc(ERR_PANIC
, "internal instruction table corrupt"
1105 ": instruction code 0x%02X given", c
);
1110 ins
->rex
&= rex_mask
;
1112 if (ins
->rex
& REX_V
) {
1113 int bad32
= REX_R
|REX_W
|REX_X
|REX_B
;
1115 if (ins
->rex
& REX_H
) {
1116 errfunc(ERR_NONFATAL
, "cannot use high register in vex instruction");
1119 switch (ins
->vex_wlp
& 030) {
1133 if (bits
!= 64 && ((ins
->rex
& bad32
) || ins
->drexdst
> 7)) {
1134 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1137 if (ins
->vex_m
!= 1 || (ins
->rex
& (REX_W
|REX_R
|REX_B
)))
1141 } else if (ins
->rex
& REX_D
) {
1142 if (ins
->rex
& REX_H
) {
1143 errfunc(ERR_NONFATAL
, "cannot use high register in drex instruction");
1146 if (bits
!= 64 && ((ins
->rex
& (REX_R
|REX_W
|REX_X
|REX_B
)) ||
1147 ins
->drexdst
> 7)) {
1148 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1152 } else if (ins
->rex
& REX_REAL
) {
1153 if (ins
->rex
& REX_H
) {
1154 errfunc(ERR_NONFATAL
, "cannot use high register in rex instruction");
1156 } else if (bits
== 64) {
1158 } else if ((ins
->rex
& REX_L
) &&
1159 !(ins
->rex
& (REX_P
|REX_W
|REX_X
|REX_B
)) &&
1162 assert_no_prefix(ins
, PPS_LREP
);
1165 errfunc(ERR_NONFATAL
, "invalid operands in non-64-bit mode");
1173 #define EMIT_REX() \
1174 if (!(ins->rex & (REX_D|REX_V)) && (ins->rex & REX_REAL) && (bits == 64)) { \
1175 ins->rex = (ins->rex & REX_REAL)|REX_P; \
1176 out(offset, segment, &ins->rex, OUT_RAWDATA, 1, NO_SEG, NO_SEG); \
1181 static void gencode(int32_t segment
, int64_t offset
, int bits
,
1182 insn
* ins
, const uint8_t *codes
, int64_t insn_end
)
1184 static char condval
[] = { /* conditional opcodes */
1185 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
1186 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
1187 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
1193 struct operand
*opx
;
1197 opx
= &ins
->oprs
[c
& 3];
1203 out(offset
, segment
, codes
, OUT_RAWDATA
, c
, NO_SEG
, NO_SEG
);
1210 switch (ins
->oprs
[0].basereg
) {
1212 bytes
[0] = 0x0E + (c
== 0x04 ? 1 : 0);
1215 bytes
[0] = 0x1E + (c
== 0x04 ? 1 : 0);
1218 bytes
[0] = 0x06 + (c
== 0x04 ? 1 : 0);
1221 bytes
[0] = 0x16 + (c
== 0x04 ? 1 : 0);
1225 "bizarre 8086 segment register received");
1227 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1233 switch (ins
->oprs
[0].basereg
) {
1235 bytes
[0] = 0xA0 + (c
== 0x05 ? 1 : 0);
1238 bytes
[0] = 0xA8 + (c
== 0x05 ? 1 : 0);
1242 "bizarre 386 segment register received");
1244 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1253 bytes
[0] = *codes
++ + ((regval(opx
)) & 7);
1254 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1262 /* XXX: warns for legitimate optimizer actions */
1263 if (opx
->offset
< -128 || opx
->offset
> 127) {
1264 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1265 "signed byte value exceeds bounds");
1268 if (opx
->segment
!= NO_SEG
) {
1270 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1271 opx
->segment
, opx
->wrt
);
1273 bytes
[0] = opx
->offset
;
1274 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1284 if (opx
->offset
< -256 || opx
->offset
> 255) {
1285 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1286 "byte value exceeds bounds");
1288 if (opx
->segment
!= NO_SEG
) {
1290 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1291 opx
->segment
, opx
->wrt
);
1293 bytes
[0] = opx
->offset
;
1294 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1304 if (opx
->offset
< 0 || opx
->offset
> 255)
1305 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1306 "unsigned byte value exceeds bounds");
1307 if (opx
->segment
!= NO_SEG
) {
1309 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1310 opx
->segment
, opx
->wrt
);
1312 bytes
[0] = opx
->offset
;
1313 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1324 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1325 warn_overflow(2, data
);
1326 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1327 opx
->segment
, opx
->wrt
);
1335 if (opx
->type
& (BITS16
| BITS32
))
1336 size
= (opx
->type
& BITS16
) ? 2 : 4;
1338 size
= (bits
== 16) ? 2 : 4;
1340 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1341 warn_overflow(size
, data
);
1342 out(offset
, segment
, &data
, OUT_ADDRESS
, size
,
1343 opx
->segment
, opx
->wrt
);
1352 if (opx
->segment
== NO_SEG
&& opx
->wrt
== NO_SEG
)
1353 warn_overflow(4, data
);
1354 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1355 opx
->segment
, opx
->wrt
);
1364 size
= ins
->addr_size
>> 3;
1365 if (opx
->segment
== NO_SEG
&&
1367 warn_overflow(size
, data
);
1368 out(offset
, segment
, &data
, OUT_ADDRESS
, size
,
1369 opx
->segment
, opx
->wrt
);
1377 if (opx
->segment
!= segment
)
1378 errfunc(ERR_NONFATAL
,
1379 "short relative jump outside segment");
1380 data
= opx
->offset
- insn_end
;
1381 if (data
> 127 || data
< -128)
1382 errfunc(ERR_NONFATAL
, "short jump is out of range");
1384 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1392 data
= (int64_t)opx
->offset
;
1393 out(offset
, segment
, &data
, OUT_ADDRESS
, 8,
1394 opx
->segment
, opx
->wrt
);
1402 if (opx
->segment
!= segment
) {
1404 out(offset
, segment
, &data
,
1405 OUT_REL2ADR
, insn_end
- offset
,
1406 opx
->segment
, opx
->wrt
);
1408 data
= opx
->offset
- insn_end
;
1409 out(offset
, segment
, &data
,
1410 OUT_ADDRESS
, 2, NO_SEG
, NO_SEG
);
1419 if (opx
->type
& (BITS16
| BITS32
| BITS64
))
1420 size
= (opx
->type
& BITS16
) ? 2 : 4;
1422 size
= (bits
== 16) ? 2 : 4;
1423 if (opx
->segment
!= segment
) {
1425 out(offset
, segment
, &data
,
1426 size
== 2 ? OUT_REL2ADR
: OUT_REL4ADR
,
1427 insn_end
- offset
, opx
->segment
, opx
->wrt
);
1429 data
= opx
->offset
- insn_end
;
1430 out(offset
, segment
, &data
,
1431 OUT_ADDRESS
, size
, NO_SEG
, NO_SEG
);
1440 if (opx
->segment
!= segment
) {
1442 out(offset
, segment
, &data
,
1443 OUT_REL4ADR
, insn_end
- offset
,
1444 opx
->segment
, opx
->wrt
);
1446 data
= opx
->offset
- insn_end
;
1447 out(offset
, segment
, &data
,
1448 OUT_ADDRESS
, 4, NO_SEG
, NO_SEG
);
1457 if (opx
->segment
== NO_SEG
)
1458 errfunc(ERR_NONFATAL
, "value referenced by FAR is not"
1461 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1462 outfmt
->segbase(1 + opx
->segment
),
1472 if (is_sbyte16(opx
)) {
1474 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1478 if (opx
->segment
== NO_SEG
&&
1480 warn_overflow(2, data
);
1481 out(offset
, segment
, &data
, OUT_ADDRESS
, 2,
1482 opx
->segment
, opx
->wrt
);
1492 bytes
[0] = *codes
++;
1493 if (is_sbyte16(opx
))
1494 bytes
[0] |= 2; /* s-bit */
1495 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1504 if (is_sbyte32(opx
)) {
1506 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1510 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1511 opx
->segment
, opx
->wrt
);
1521 bytes
[0] = *codes
++;
1522 if (is_sbyte32(opx
))
1523 bytes
[0] |= 2; /* s-bit */
1524 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1540 (ins
->drexdst
<< 4) |
1541 (ins
->rex
& REX_OC
? 0x08 : 0) |
1542 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1544 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1550 opx
= &ins
->oprs
[c
>> 3];
1551 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1552 opx
= &ins
->oprs
[c
& 7];
1553 if (opx
->segment
!= NO_SEG
|| opx
->wrt
!= NO_SEG
) {
1554 errfunc(ERR_NONFATAL
,
1555 "non-absolute expression not permitted as argument %d",
1558 if (opx
->offset
& ~15) {
1559 errfunc(ERR_WARNING
| ERR_WARN_NOV
,
1560 "four-bit argument exceeds bounds");
1562 bytes
[0] |= opx
->offset
& 15;
1564 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1570 opx
= &ins
->oprs
[c
>> 4];
1571 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1573 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1579 opx
= &ins
->oprs
[c
];
1580 bytes
[0] = nasm_regvals
[opx
->basereg
] << 4;
1581 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1590 /* is_sbyte32() is right here, we have already warned */
1591 if (is_sbyte32(opx
)) {
1593 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
,
1597 out(offset
, segment
, &data
, OUT_ADDRESS
, 4,
1598 opx
->segment
, opx
->wrt
);
1609 if (ins
->vex_m
!= 1 || (ins
->rex
& (REX_W
|REX_X
|REX_B
))) {
1611 bytes
[1] = ins
->vex_m
| ((~ins
->rex
& 7) << 5);
1612 bytes
[2] = ((ins
->rex
& REX_W
) << (7-3)) |
1613 ((~ins
->drexdst
& 15)<< 3) | (ins
->vex_wlp
& 07);
1614 out(offset
, segment
, &bytes
, OUT_RAWDATA
, 3, NO_SEG
, NO_SEG
);
1618 bytes
[1] = ((~ins
->rex
& REX_R
) << (7-2)) |
1619 ((~ins
->drexdst
& 15) << 3) | (ins
->vex_wlp
& 07);
1620 out(offset
, segment
, &bytes
, OUT_RAWDATA
, 2, NO_SEG
, NO_SEG
);
1632 if (bits
== 32 && !has_prefix(ins
, PPS_ASIZE
, P_A16
)) {
1634 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1641 if (bits
!= 32 && !has_prefix(ins
, PPS_ASIZE
, P_A32
)) {
1643 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1665 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1674 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1689 *bytes
= *codes
++ ^ condval
[ins
->condition
];
1690 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1699 *bytes
= c
- 0332 + 0xF2;
1700 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1705 if (ins
->rex
& REX_R
) {
1707 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1710 ins
->rex
&= ~(REX_L
|REX_R
);
1721 if (ins
->oprs
[0].segment
!= NO_SEG
)
1722 errfunc(ERR_PANIC
, "non-constant BSS size in pass two");
1724 int64_t size
= ins
->oprs
[0].offset
;
1726 out(offset
, segment
, NULL
,
1727 OUT_RESERVE
, size
, NO_SEG
, NO_SEG
);
1737 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1743 bytes
[0] = c
- 0362 + 0xf2;
1744 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1754 *bytes
= c
- 0366 + 0x66;
1755 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1765 *bytes
= bits
== 16 ? 3 : 5;
1766 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1, NO_SEG
, NO_SEG
);
1770 default: /* can't do it by 'case' statements */
1771 if (c
>= 0100 && c
<= 0277) { /* it's an EA */
1779 /* pick rfield from operand b */
1780 rflags
= regflag(&ins
->oprs
[c
& 7]);
1781 rfield
= nasm_regvals
[ins
->oprs
[c
& 7].basereg
];
1783 /* rfield is constant */
1789 (&ins
->oprs
[(c
>> 3) & 7], &ea_data
, bits
,
1790 ins
->addr_size
, rfield
, rflags
)) {
1791 errfunc(ERR_NONFATAL
, "invalid effective address");
1796 *p
++ = ea_data
.modrm
;
1797 if (ea_data
.sib_present
)
1800 /* DREX suffixes come between the SIB and the displacement */
1801 if (ins
->rex
& REX_D
) {
1803 (ins
->drexdst
<< 4) |
1804 (ins
->rex
& REX_OC
? 0x08 : 0) |
1805 (ins
->rex
& (REX_R
|REX_X
|REX_B
));
1810 out(offset
, segment
, bytes
, OUT_RAWDATA
, s
, NO_SEG
, NO_SEG
);
1812 switch (ea_data
.bytes
) {
1816 if (ins
->oprs
[(c
>> 3) & 7].segment
!= NO_SEG
) {
1817 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1818 out(offset
, segment
, &data
, OUT_ADDRESS
, 1,
1819 ins
->oprs
[(c
>> 3) & 7].segment
,
1820 ins
->oprs
[(c
>> 3) & 7].wrt
);
1822 *bytes
= ins
->oprs
[(c
>> 3) & 7].offset
;
1823 out(offset
, segment
, bytes
, OUT_RAWDATA
, 1,
1831 data
= ins
->oprs
[(c
>> 3) & 7].offset
;
1832 warn_overflow(ea_data
.bytes
, data
);
1833 out(offset
, segment
, &data
,
1834 ea_data
.rip
? OUT_REL4ADR
: OUT_ADDRESS
,
1836 ins
->oprs
[(c
>> 3) & 7].segment
,
1837 ins
->oprs
[(c
>> 3) & 7].wrt
);
1843 errfunc(ERR_PANIC
, "internal instruction table corrupt"
1844 ": instruction code 0x%02X given", c
);
1850 static int32_t regflag(const operand
* o
)
1852 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1853 errfunc(ERR_PANIC
, "invalid operand passed to regflag()");
1855 return nasm_reg_flags
[o
->basereg
];
1858 static int32_t regval(const operand
* o
)
1860 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1861 errfunc(ERR_PANIC
, "invalid operand passed to regval()");
1863 return nasm_regvals
[o
->basereg
];
1866 static int op_rexflags(const operand
* o
, int mask
)
1871 if (o
->basereg
< EXPR_REG_START
|| o
->basereg
>= REG_ENUM_LIMIT
) {
1872 errfunc(ERR_PANIC
, "invalid operand passed to op_rexflags()");
1875 flags
= nasm_reg_flags
[o
->basereg
];
1876 val
= nasm_regvals
[o
->basereg
];
1878 return rexflags(val
, flags
, mask
);
1881 static int rexflags(int val
, int32_t flags
, int mask
)
1886 rex
|= REX_B
|REX_X
|REX_R
;
1889 if (!(REG_HIGH
& ~flags
)) /* AH, CH, DH, BH */
1891 else if (!(REG8
& ~flags
) && val
>= 4) /* SPL, BPL, SIL, DIL */
1897 static int matches(const struct itemplate
*itemp
, insn
* instruction
, int bits
)
1899 int i
, size
[MAX_OPERANDS
], asize
, oprs
, ret
;
1906 if (itemp
->opcode
!= instruction
->opcode
)
1910 * Count the operands
1912 if (itemp
->operands
!= instruction
->operands
)
1916 * Check that no spurious colons or TOs are present
1918 for (i
= 0; i
< itemp
->operands
; i
++)
1919 if (instruction
->oprs
[i
].type
& ~itemp
->opd
[i
] & (COLON
| TO
))
1923 * Process size flags
1925 if (itemp
->flags
& IF_ARMASK
) {
1926 memset(size
, 0, sizeof size
);
1928 i
= ((itemp
->flags
& IF_ARMASK
) >> IF_ARSHFT
) - 1;
1930 switch (itemp
->flags
& IF_SMASK
) {
1967 switch (itemp
->flags
& IF_SMASK
) {
2002 for (i
= 0; i
< MAX_OPERANDS
; i
++)
2007 * Check that the operand flags all match up
2009 for (i
= 0; i
< itemp
->operands
; i
++) {
2010 int32_t type
= instruction
->oprs
[i
].type
;
2011 if (!(type
& SIZE_MASK
))
2014 if (itemp
->opd
[i
] & SAME_AS
) {
2015 int j
= itemp
->opd
[i
] & ~SAME_AS
;
2016 if (type
!= instruction
->oprs
[j
].type
||
2017 instruction
->oprs
[i
].basereg
!= instruction
->oprs
[j
].basereg
)
2019 } else if (itemp
->opd
[i
] & ~type
||
2020 ((itemp
->opd
[i
] & SIZE_MASK
) &&
2021 ((itemp
->opd
[i
] ^ type
) & SIZE_MASK
))) {
2022 if ((itemp
->opd
[i
] & ~type
& ~SIZE_MASK
) ||
2031 * Check operand sizes
2033 if (itemp
->flags
& (IF_SM
| IF_SM2
)) {
2034 oprs
= (itemp
->flags
& IF_SM2
? 2 : itemp
->operands
);
2036 for (i
= 0; i
< oprs
; i
++) {
2037 if ((asize
= itemp
->opd
[i
] & SIZE_MASK
) != 0) {
2039 for (j
= 0; j
< oprs
; j
++)
2045 oprs
= itemp
->operands
;
2048 for (i
= 0; i
< itemp
->operands
; i
++) {
2049 if (!(itemp
->opd
[i
] & SIZE_MASK
) &&
2050 (instruction
->oprs
[i
].type
& SIZE_MASK
& ~size
[i
]))
2055 * Check template is okay at the set cpu level
2057 if (((itemp
->flags
& IF_PLEVEL
) > cpu
))
2061 * Check if instruction is available in long mode
2063 if ((itemp
->flags
& IF_NOLONG
) && (bits
== 64))
2067 * Check if special handling needed for Jumps
2069 if ((uint8_t)(itemp
->code
[0]) >= 0370)
2075 static ea
*process_ea(operand
* input
, ea
* output
, int bits
,
2076 int addrbits
, int rfield
, int32_t rflags
)
2078 bool forw_ref
= !!(input
->opflags
& OPFLAG_FORWARD
);
2080 output
->rip
= false;
2082 /* REX flags for the rfield operand */
2083 output
->rex
|= rexflags(rfield
, rflags
, REX_R
|REX_P
|REX_W
|REX_H
);
2085 if (!(REGISTER
& ~input
->type
)) { /* register direct */
2089 if (input
->basereg
< EXPR_REG_START
/* Verify as Register */
2090 || input
->basereg
>= REG_ENUM_LIMIT
)
2093 i
= nasm_regvals
[input
->basereg
];
2096 return NULL
; /* Invalid EA register */
2098 output
->rex
|= op_rexflags(input
, REX_B
|REX_P
|REX_W
|REX_H
);
2100 output
->sib_present
= false; /* no SIB necessary */
2101 output
->bytes
= 0; /* no offset necessary either */
2102 output
->modrm
= 0xC0 | ((rfield
& 7) << 3) | (i
& 7);
2103 } else { /* it's a memory reference */
2104 if (input
->basereg
== -1
2105 && (input
->indexreg
== -1 || input
->scale
== 0)) {
2106 /* it's a pure offset */
2107 if (bits
== 64 && (~input
->type
& IP_REL
)) {
2108 int scale
, index
, base
;
2109 output
->sib_present
= true;
2113 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
2115 output
->modrm
= 4 | ((rfield
& 7) << 3);
2116 output
->rip
= false;
2118 output
->sib_present
= false;
2119 output
->bytes
= (addrbits
!= 16 ? 4 : 2);
2120 output
->modrm
= (addrbits
!= 16 ? 5 : 6) | ((rfield
& 7) << 3);
2121 output
->rip
= bits
== 64;
2123 } else { /* it's an indirection */
2124 int i
= input
->indexreg
, b
= input
->basereg
, s
= input
->scale
;
2125 int32_t o
= input
->offset
, seg
= input
->segment
;
2126 int hb
= input
->hintbase
, ht
= input
->hinttype
;
2129 int32_t ix
, bx
; /* register flags */
2132 i
= -1; /* make this easy, at least */
2134 if (i
>= EXPR_REG_START
&& i
< REG_ENUM_LIMIT
) {
2135 it
= nasm_regvals
[i
];
2136 ix
= nasm_reg_flags
[i
];
2142 if (b
>= EXPR_REG_START
&& b
< REG_ENUM_LIMIT
) {
2143 bt
= nasm_regvals
[b
];
2144 bx
= nasm_reg_flags
[b
];
2150 /* check for a 32/64-bit memory reference... */
2151 if ((ix
|bx
) & (BITS32
|BITS64
)) {
2152 /* it must be a 32/64-bit memory reference. Firstly we have
2153 * to check that all registers involved are type E/Rxx. */
2154 int32_t sok
= BITS32
|BITS64
;
2157 if (!(REG64
& ~ix
) || !(REG32
& ~ix
))
2165 return NULL
; /* Invalid register */
2166 if (~sok
& bx
& SIZE_MASK
)
2167 return NULL
; /* Invalid size */
2171 /* While we're here, ensure the user didn't specify
2173 if (input
->disp_size
== 16 || input
->disp_size
== 64)
2176 if (addrbits
== 16 ||
2177 (addrbits
== 32 && !(sok
& BITS32
)) ||
2178 (addrbits
== 64 && !(sok
& BITS64
)))
2181 /* now reorganize base/index */
2182 if (s
== 1 && bt
!= it
&& bt
!= -1 && it
!= -1 &&
2183 ((hb
== b
&& ht
== EAH_NOTBASE
)
2184 || (hb
== i
&& ht
== EAH_MAKEBASE
))) {
2185 /* swap if hints say so */
2186 t
= bt
, bt
= it
, it
= t
;
2187 t
= bx
, bx
= ix
, ix
= t
;
2189 if (bt
== it
) /* convert EAX+2*EAX to 3*EAX */
2190 bt
= -1, bx
= 0, s
++;
2191 if (bt
== -1 && s
== 1 && !(hb
== it
&& ht
== EAH_NOTBASE
)) {
2192 /* make single reg base, unless hint */
2193 bt
= it
, bx
= ix
, it
= -1, ix
= 0;
2195 if (((s
== 2 && it
!= REG_NUM_ESP
2196 && !(input
->eaflags
& EAF_TIMESTWO
)) || s
== 3
2197 || s
== 5 || s
== 9) && bt
== -1)
2198 bt
= it
, bx
= ix
, s
--; /* convert 3*EAX to EAX+2*EAX */
2199 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
2200 && (input
->eaflags
& EAF_TIMESTWO
))
2201 it
= bt
, ix
= bx
, bt
= -1, bx
= 0, s
= 1;
2202 /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */
2203 if (s
== 1 && it
== REG_NUM_ESP
) {
2204 /* swap ESP into base if scale is 1 */
2205 t
= it
, it
= bt
, bt
= t
;
2206 t
= ix
, ix
= bx
, bx
= t
;
2208 if (it
== REG_NUM_ESP
2209 || (s
!= 1 && s
!= 2 && s
!= 4 && s
!= 8 && it
!= -1))
2210 return NULL
; /* wrong, for various reasons */
2212 output
->rex
|= rexflags(it
, ix
, REX_X
);
2213 output
->rex
|= rexflags(bt
, bx
, REX_B
);
2215 if (it
== -1 && (bt
& 7) != REG_NUM_ESP
) {
2224 if (rm
!= REG_NUM_EBP
&& o
== 0 &&
2225 seg
== NO_SEG
&& !forw_ref
&&
2227 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2229 else if (input
->eaflags
& EAF_BYTEOFFS
||
2230 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2232 && !(input
->eaflags
& EAF_WORDOFFS
)))
2238 output
->sib_present
= false;
2239 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
2240 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
2243 int mod
, scale
, index
, base
;
2263 default: /* then what the smeg is it? */
2264 return NULL
; /* panic */
2272 if (base
!= REG_NUM_EBP
&& o
== 0 &&
2273 seg
== NO_SEG
&& !forw_ref
&&
2275 (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2277 else if (input
->eaflags
& EAF_BYTEOFFS
||
2278 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2280 && !(input
->eaflags
& EAF_WORDOFFS
)))
2286 output
->sib_present
= true;
2287 output
->bytes
= (bt
== -1 || mod
== 2 ? 4 : mod
);
2288 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | 4;
2289 output
->sib
= (scale
<< 6) | (index
<< 3) | base
;
2291 } else { /* it's 16-bit */
2294 /* check for 64-bit long mode */
2298 /* check all registers are BX, BP, SI or DI */
2299 if ((b
!= -1 && b
!= R_BP
&& b
!= R_BX
&& b
!= R_SI
2300 && b
!= R_DI
) || (i
!= -1 && i
!= R_BP
&& i
!= R_BX
2301 && i
!= R_SI
&& i
!= R_DI
))
2304 /* ensure the user didn't specify DWORD/QWORD */
2305 if (input
->disp_size
== 32 || input
->disp_size
== 64)
2308 if (s
!= 1 && i
!= -1)
2309 return NULL
; /* no can do, in 16-bit EA */
2310 if (b
== -1 && i
!= -1) {
2315 if ((b
== R_SI
|| b
== R_DI
) && i
!= -1) {
2320 /* have BX/BP as base, SI/DI index */
2322 return NULL
; /* shouldn't ever happen, in theory */
2323 if (i
!= -1 && b
!= -1 &&
2324 (i
== R_BP
|| i
== R_BX
|| b
== R_SI
|| b
== R_DI
))
2325 return NULL
; /* invalid combinations */
2326 if (b
== -1) /* pure offset: handled above */
2327 return NULL
; /* so if it gets to here, panic! */
2331 switch (i
* 256 + b
) {
2332 case R_SI
* 256 + R_BX
:
2335 case R_DI
* 256 + R_BX
:
2338 case R_SI
* 256 + R_BP
:
2341 case R_DI
* 256 + R_BP
:
2359 if (rm
== -1) /* can't happen, in theory */
2360 return NULL
; /* so panic if it does */
2362 if (o
== 0 && seg
== NO_SEG
&& !forw_ref
&& rm
!= 6 &&
2363 !(input
->eaflags
& (EAF_BYTEOFFS
| EAF_WORDOFFS
)))
2365 else if (input
->eaflags
& EAF_BYTEOFFS
||
2366 (o
>= -128 && o
<= 127 && seg
== NO_SEG
2368 && !(input
->eaflags
& EAF_WORDOFFS
)))
2373 output
->sib_present
= false; /* no SIB - it's 16-bit */
2374 output
->bytes
= mod
; /* bytes of offset needed */
2375 output
->modrm
= (mod
<< 6) | ((rfield
& 7) << 3) | rm
;
2380 output
->size
= 1 + output
->sib_present
+ output
->bytes
;
2384 static void add_asp(insn
*ins
, int addrbits
)
2389 valid
= (addrbits
== 64) ? 64|32 : 32|16;
2391 switch (ins
->prefixes
[PPS_ASIZE
]) {
2402 valid
&= (addrbits
== 32) ? 16 : 32;
2408 for (j
= 0; j
< ins
->operands
; j
++) {
2409 if (!(MEMORY
& ~ins
->oprs
[j
].type
)) {
2412 /* Verify as Register */
2413 if (ins
->oprs
[j
].indexreg
< EXPR_REG_START
2414 || ins
->oprs
[j
].indexreg
>= REG_ENUM_LIMIT
)
2417 i
= nasm_reg_flags
[ins
->oprs
[j
].indexreg
];
2419 /* Verify as Register */
2420 if (ins
->oprs
[j
].basereg
< EXPR_REG_START
2421 || ins
->oprs
[j
].basereg
>= REG_ENUM_LIMIT
)
2424 b
= nasm_reg_flags
[ins
->oprs
[j
].basereg
];
2426 if (ins
->oprs
[j
].scale
== 0)
2430 int ds
= ins
->oprs
[j
].disp_size
;
2431 if ((addrbits
!= 64 && ds
> 8) ||
2432 (addrbits
== 64 && ds
== 16))
2452 if (valid
& addrbits
) {
2453 ins
->addr_size
= addrbits
;
2454 } else if (valid
& ((addrbits
== 32) ? 16 : 32)) {
2455 /* Add an address size prefix */
2456 enum prefixes pref
= (addrbits
== 32) ? P_A16
: P_A32
;
2457 ins
->prefixes
[PPS_ASIZE
] = pref
;
2458 ins
->addr_size
= (addrbits
== 32) ? 16 : 32;
2461 errfunc(ERR_NONFATAL
, "impossible combination of address sizes");
2462 ins
->addr_size
= addrbits
; /* Error recovery */
2465 defdisp
= ins
->addr_size
== 16 ? 16 : 32;
2467 for (j
= 0; j
< ins
->operands
; j
++) {
2468 if (!(MEM_OFFS
& ~ins
->oprs
[j
].type
) &&
2469 (ins
->oprs
[j
].disp_size
? ins
->oprs
[j
].disp_size
: defdisp
)
2470 != ins
->addr_size
) {
2471 /* mem_offs sizes must match the address size; if not,
2472 strip the MEM_OFFS bit and match only EA instructions */
2473 ins
->oprs
[j
].type
&= ~(MEM_OFFS
& ~MEMORY
);