1 | /* ----------------------------------------------------------------------- * |
2 | * |
3 | * Copyright 1996-2018 The NASM Authors - All Rights Reserved |
4 | * See the file AUTHORS included with the NASM distribution for |
5 | * the specific copyright holders. |
6 | * |
7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following |
9 | * conditions are met: |
10 | * |
11 | * * Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. |
13 | * * Redistributions in binary form must reproduce the above |
14 | * copyright notice, this list of conditions and the following |
15 | * disclaimer in the documentation and/or other materials provided |
16 | * with the distribution. |
17 | * |
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
19 | * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
20 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
21 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
24 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
25 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
26 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
29 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
30 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
31 | * |
32 | * ----------------------------------------------------------------------- */ |
33 | |
34 | /* |
35 | * assemble.c code generation for the Netwide Assembler |
36 | * |
37 | * Bytecode specification |
38 | * ---------------------- |
39 | * |
40 | * |
41 | * Codes Mnemonic Explanation |
42 | * |
43 | * \0 terminates the code. (Unless it's a literal of course.) |
44 | * \1..\4 that many literal bytes follow in the code stream |
45 | * \5 add 4 to the primary operand number (b, low octdigit) |
46 | * \6 add 4 to the secondary operand number (a, middle octdigit) |
47 | * \7 add 4 to both the primary and the secondary operand number |
48 | * \10..\13 a literal byte follows in the code stream, to be added |
49 | * to the register value of operand 0..3 |
50 | * \14..\17 the position of index register operand in MIB (BND insns) |
51 | * \20..\23 ib a byte immediate operand, from operand 0..3 |
52 | * \24..\27 ib,u a zero-extended byte immediate operand, from operand 0..3 |
53 | * \30..\33 iw a word immediate operand, from operand 0..3 |
54 | * \34..\37 iwd select between \3[0-3] and \4[0-3] depending on 16/32 bit |
55 | * assembly mode or the operand-size override on the operand |
56 | * \40..\43 id a long immediate operand, from operand 0..3 |
57 | * \44..\47 iwdq select between \3[0-3], \4[0-3] and \5[4-7] |
58 | * depending on the address size of the instruction. |
59 | * \50..\53 rel8 a byte relative operand, from operand 0..3 |
60 | * \54..\57 iq a qword immediate operand, from operand 0..3 |
61 | * \60..\63 rel16 a word relative operand, from operand 0..3 |
62 | * \64..\67 rel select between \6[0-3] and \7[0-3] depending on 16/32 bit |
63 | * assembly mode or the operand-size override on the operand |
64 | * \70..\73 rel32 a long relative operand, from operand 0..3 |
65 | * \74..\77 seg a word constant, from the _segment_ part of operand 0..3 |
66 | * \1ab a ModRM, calculated on EA in operand a, with the spare |
67 | * field the register value of operand b. |
68 | * \172\ab the register number from operand a in bits 7..4, with |
69 | * the 4-bit immediate from operand b in bits 3..0. |
70 | * \173\xab the register number from operand a in bits 7..4, with |
71 | * the value b in bits 3..0. |
72 | * \174..\177 the register number from operand 0..3 in bits 7..4, and |
73 | * an arbitrary value in bits 3..0 (assembled as zero.) |
74 | * \2ab a ModRM, calculated on EA in operand a, with the spare |
75 | * field equal to digit b. |
76 | * |
77 | * \240..\243 this instruction uses EVEX rather than REX or VEX/XOP, with the |
78 | * V field taken from operand 0..3. |
79 | * \250 this instruction uses EVEX rather than REX or VEX/XOP, with the |
80 | * V field set to 1111b. |
81 | * |
82 | * EVEX prefixes are followed by the sequence: |
83 | * \cm\wlp\tup where cm is: |
84 | * cc 00m mmm |
85 | * c = 2 for EVEX and mmmm is the M field (EVEX.P0[3:0]) |
86 | * and wlp is: |
87 | * 00 wwl lpp |
88 | * [l0] ll = 0 (.128, .lz) |
89 | * [l1] ll = 1 (.256) |
90 | * [l2] ll = 2 (.512) |
91 | * [lig] ll = 3 for EVEX.L'L don't care (always assembled as 0) |
92 | * |
93 | * [w0] ww = 0 for W = 0 |
94 | * [w1] ww = 1 for W = 1 |
95 | * [wig] ww = 2 for W don't care (always assembled as 0) |
96 | * [ww] ww = 3 for W used as REX.W |
97 | * |
98 | * [p0] pp = 0 for no prefix |
99 | * [60] pp = 1 for legacy prefix 60 |
100 | * [f3] pp = 2 |
101 | * [f2] pp = 3 |
102 | * |
103 | * tup is tuple type for Disp8*N from %tuple_codes in insns.pl |
104 | * (compressed displacement encoding) |
105 | * |
106 | * \254..\257 id,s a signed 32-bit operand to be extended to 64 bits. |
107 | * \260..\263 this instruction uses VEX/XOP rather than REX, with the |
108 | * V field taken from operand 0..3. |
109 | * \270 this instruction uses VEX/XOP rather than REX, with the |
110 | * V field set to 1111b. |
111 | * |
112 | * VEX/XOP prefixes are followed by the sequence: |
113 | * \tmm\wlp where mm is the M field; and wlp is: |
114 | * 00 wwl lpp |
115 | * [l0] ll = 0 for L = 0 (.128, .lz) |
116 | * [l1] ll = 1 for L = 1 (.256) |
117 | * [lig] ll = 2 for L don't care (always assembled as 0) |
118 | * |
119 | * [w0] ww = 0 for W = 0 |
120 | * [w1 ] ww = 1 for W = 1 |
121 | * [wig] ww = 2 for W don't care (always assembled as 0) |
122 | * [ww] ww = 3 for W used as REX.W |
123 | * |
124 | * t = 0 for VEX (C4/C5), t = 1 for XOP (8F). |
125 | * |
126 | * \271 hlexr instruction takes XRELEASE (F3) with or without lock |
127 | * \272 hlenl instruction takes XACQUIRE/XRELEASE with or without lock |
128 | * \273 hle instruction takes XACQUIRE/XRELEASE with lock only |
129 | * \274..\277 ib,s a byte immediate operand, from operand 0..3, sign-extended |
130 | * to the operand size (if o16/o32/o64 present) or the bit size |
131 | * \310 a16 indicates fixed 16-bit address size, i.e. optional 0x67. |
132 | * \311 a32 indicates fixed 32-bit address size, i.e. optional 0x67. |
133 | * \312 adf (disassembler only) invalid with non-default address size. |
134 | * \313 a64 indicates fixed 64-bit address size, 0x67 invalid. |
135 | * \314 norexb (disassembler only) invalid with REX.B |
136 | * \315 norexx (disassembler only) invalid with REX.X |
137 | * \316 norexr (disassembler only) invalid with REX.R |
138 | * \317 norexw (disassembler only) invalid with REX.W |
139 | * \320 o16 indicates fixed 16-bit operand size, i.e. optional 0x66. |
140 | * \321 o32 indicates fixed 32-bit operand size, i.e. optional 0x66. |
141 | * \322 odf indicates that this instruction is only valid when the |
142 | * operand size is the default (instruction to disassembler, |
143 | * generates no code in the assembler) |
144 | * \323 o64nw indicates fixed 64-bit operand size, REX on extensions only. |
145 | * \324 o64 indicates 64-bit operand size requiring REX prefix. |
146 | * \325 nohi instruction which always uses spl/bpl/sil/dil |
147 | * \326 nof3 instruction not valid with 0xF3 REP prefix. Hint for |
148 | disassembler only; for SSE instructions. |
149 | * \330 a literal byte follows in the code stream, to be added |
150 | * to the condition code value of the instruction. |
151 | * \331 norep instruction not valid with REP prefix. Hint for |
152 | * disassembler only; for SSE instructions. |
153 | * \332 f2i REP prefix (0xF2 byte) used as opcode extension. |
154 | * \333 f3i REP prefix (0xF3 byte) used as opcode extension. |
155 | * \334 rex.l LOCK prefix used as REX.R (used in non-64-bit mode) |
156 | * \335 repe disassemble a rep (0xF3 byte) prefix as repe not rep. |
157 | * \336 mustrep force a REP(E) prefix (0xF3) even if not specified. |
158 | * \337 mustrepne force a REPNE prefix (0xF2) even if not specified. |
159 | * \336-\337 are still listed as prefixes in the disassembler. |
160 | * \340 resb reserve <operand 0> bytes of uninitialized storage. |
161 | * Operand 0 had better be a segmentless constant. |
162 | * \341 wait this instruction needs a WAIT "prefix" |
163 | * \360 np no SSE prefix (== \364\331) |
164 | * \361 66 SSE prefix (== \366\331) |
165 | * \364 !osp operand-size prefix (0x66) not permitted |
166 | * \365 !asp address-size prefix (0x67) not permitted |
167 | * \366 operand-size prefix (0x66) used as opcode extension |
168 | * \367 address-size prefix (0x67) used as opcode extension |
169 | * \370,\371 jcc8 match only if operand 0 meets byte jump criteria. |
170 | * jmp8 370 is used for Jcc, 371 is used for JMP. |
171 | * \373 jlen assemble 0x03 if bits==16, 0x05 if bits==32; |
172 | * used for conditional jump over longer jump |
173 | * \374 vsibx|vm32x|vm64x this instruction takes an XMM VSIB memory EA |
174 | * \375 vsiby|vm32y|vm64y this instruction takes an YMM VSIB memory EA |
175 | * \376 vsibz|vm32z|vm64z this instruction takes an ZMM VSIB memory EA |
176 | */ |
177 | |
178 | #include "compiler.h" |
179 | |
180 | #include <stdio.h> |
181 | #include <string.h> |
182 | #include <stdlib.h> |
183 | |
184 | #include "nasm.h" |
185 | #include "nasmlib.h" |
186 | #include "error.h" |
187 | #include "assemble.h" |
188 | #include "insns.h" |
189 | #include "tables.h" |
190 | #include "disp8.h" |
191 | #include "listing.h" |
192 | |
193 | enum match_result { |
194 | /* |
195 | * Matching errors. These should be sorted so that more specific |
196 | * errors come later in the sequence. |
197 | */ |
198 | MERR_INVALOP, |
199 | MERR_OPSIZEMISSING, |
200 | MERR_OPSIZEMISMATCH, |
201 | MERR_BRNOTHERE, |
202 | MERR_BRNUMMISMATCH, |
203 | MERR_MASKNOTHERE, |
204 | MERR_DECONOTHERE, |
205 | MERR_BADCPU, |
206 | MERR_BADMODE, |
207 | MERR_BADHLE, |
208 | MERR_ENCMISMATCH, |
209 | MERR_BADBND, |
210 | MERR_BADREPNE, |
211 | MERR_REGSETSIZE, |
212 | MERR_REGSET, |
213 | /* |
214 | * Matching success; the conditional ones first |
215 | */ |
216 | MOK_JUMP, /* Matching OK but needs jmp_match() */ |
217 | MOK_GOOD /* Matching unconditionally OK */ |
218 | }; |
219 | |
220 | typedef struct { |
221 | enum ea_type type; /* what kind of EA is this? */ |
222 | int sib_present; /* is a SIB byte necessary? */ |
223 | int bytes; /* # of bytes of offset needed */ |
224 | int size; /* lazy - this is sib+bytes+1 */ |
225 | uint8_t modrm, sib, rex, rip; /* the bytes themselves */ |
226 | int8_t disp8; /* compressed displacement for EVEX */ |
227 | } ea; |
228 | |
229 | #define GEN_SIB(scale, index, base) \ |
230 | (((scale) << 6) | ((index) << 3) | ((base))) |
231 | |
232 | #define GEN_MODRM(mod, reg, rm) \ |
233 | (((mod) << 6) | (((reg) & 7) << 3) | ((rm) & 7)) |
234 | |
235 | static int64_t calcsize(int32_t, int64_t, int, insn *, |
236 | const struct itemplate *); |
237 | static int emit_prefix(struct out_data *data, const int bits, insn *ins); |
238 | static void gencode(struct out_data *data, insn *ins); |
239 | static enum match_result find_match(const struct itemplate **tempp, |
240 | insn *instruction, |
241 | int32_t segment, int64_t offset, int bits); |
242 | static enum match_result matches(const struct itemplate *, insn *, int bits); |
243 | static opflags_t regflag(const operand *); |
244 | static int32_t regval(const operand *); |
245 | static int rexflags(int, opflags_t, int); |
246 | static int op_rexflags(const operand *, int); |
247 | static int op_evexflags(const operand *, int, uint8_t); |
248 | static void add_asp(insn *, int); |
249 | |
250 | static enum ea_type process_ea(operand *, ea *, int, int, |
251 | opflags_t, insn *, const char **); |
252 | |
253 | static inline bool absolute_op(const struct operand *o) |
254 | { |
255 | return o->segment == NO_SEG && o->wrt == NO_SEG && |
256 | !(o->opflags & OPFLAG_RELATIVE); |
257 | } |
258 | |
259 | static int has_prefix(insn * ins, enum prefix_pos pos, int prefix) |
260 | { |
261 | return ins->prefixes[pos] == prefix; |
262 | } |
263 | |
264 | static void assert_no_prefix(insn * ins, enum prefix_pos pos) |
265 | { |
266 | if (ins->prefixes[pos]) |
267 | nasm_error(ERR_NONFATAL, "invalid %s prefix" , |
268 | prefix_name(ins->prefixes[pos])); |
269 | } |
270 | |
271 | static const char *size_name(int size) |
272 | { |
273 | switch (size) { |
274 | case 1: |
275 | return "byte" ; |
276 | case 2: |
277 | return "word" ; |
278 | case 4: |
279 | return "dword" ; |
280 | case 8: |
281 | return "qword" ; |
282 | case 10: |
283 | return "tword" ; |
284 | case 16: |
285 | return "oword" ; |
286 | case 32: |
287 | return "yword" ; |
288 | case 64: |
289 | return "zword" ; |
290 | default: |
291 | return "???" ; |
292 | } |
293 | } |
294 | |
295 | static void warn_overflow(int size) |
296 | { |
297 | nasm_error(ERR_WARNING | ERR_PASS2 | WARN_NOV, |
298 | "%s data exceeds bounds" , size_name(size)); |
299 | } |
300 | |
301 | static void warn_overflow_const(int64_t data, int size) |
302 | { |
303 | if (overflow_general(data, size)) |
304 | warn_overflow(size); |
305 | } |
306 | |
307 | static void warn_overflow_out(int64_t data, int size, enum out_sign sign) |
308 | { |
309 | bool err; |
310 | |
311 | switch (sign) { |
312 | case OUT_WRAP: |
313 | err = overflow_general(data, size); |
314 | break; |
315 | case OUT_SIGNED: |
316 | err = overflow_signed(data, size); |
317 | break; |
318 | case OUT_UNSIGNED: |
319 | err = overflow_unsigned(data, size); |
320 | break; |
321 | default: |
322 | panic(); |
323 | break; |
324 | } |
325 | |
326 | if (err) |
327 | warn_overflow(size); |
328 | } |
329 | |
330 | /* |
331 | * This routine wrappers the real output format's output routine, |
332 | * in order to pass a copy of the data off to the listing file |
333 | * generator at the same time, flatten unnecessary relocations, |
334 | * and verify backend compatibility. |
335 | */ |
336 | static void out(struct out_data *data) |
337 | { |
338 | static int32_t lineno = 0; /* static!!! */ |
339 | static const char *lnfname = NULL; |
340 | union { |
341 | uint8_t b[8]; |
342 | uint64_t q; |
343 | } xdata; |
344 | size_t asize, amax; |
345 | uint64_t zeropad = 0; |
346 | int64_t addrval; |
347 | int32_t fixseg; /* Segment for which to produce fixed data */ |
348 | |
349 | if (!data->size) |
350 | return; /* Nothing to do */ |
351 | |
352 | /* |
353 | * Convert addresses to RAWDATA if possible |
354 | * XXX: not all backends want this for global symbols!!!! |
355 | */ |
356 | switch (data->type) { |
357 | case OUT_ADDRESS: |
358 | addrval = data->toffset; |
359 | fixseg = NO_SEG; /* Absolute address is fixed data */ |
360 | goto address; |
361 | |
362 | case OUT_RELADDR: |
363 | addrval = data->toffset - data->relbase; |
364 | fixseg = data->segment; /* Our own segment is fixed data */ |
365 | goto address; |
366 | |
367 | address: |
368 | nasm_assert(data->size <= 8); |
369 | asize = data->size; |
370 | amax = ofmt->maxbits >> 3; /* Maximum address size in bytes */ |
371 | if ((ofmt->flags & OFMT_KEEP_ADDR) == 0 && data->tsegment == fixseg && |
372 | data->twrt == NO_SEG) { |
373 | warn_overflow_out(addrval, asize, data->sign); |
374 | xdata.q = cpu_to_le64(addrval); |
375 | data->data = xdata.b; |
376 | data->type = OUT_RAWDATA; |
377 | asize = amax = 0; /* No longer an address */ |
378 | } |
379 | break; |
380 | |
381 | case OUT_SEGMENT: |
382 | nasm_assert(data->size <= 8); |
383 | asize = data->size; |
384 | amax = 2; |
385 | break; |
386 | |
387 | default: |
388 | asize = amax = 0; /* Not an address */ |
389 | break; |
390 | } |
391 | |
392 | /* |
393 | * this call to src_get determines when we call the |
394 | * debug-format-specific "linenum" function |
395 | * it updates lineno and lnfname to the current values |
396 | * returning 0 if "same as last time", -2 if lnfname |
397 | * changed, and the amount by which lineno changed, |
398 | * if it did. thus, these variables must be static |
399 | */ |
400 | |
401 | if (src_get(&lineno, &lnfname)) |
402 | dfmt->linenum(lnfname, lineno, data->segment); |
403 | |
404 | if (asize > amax) { |
405 | if (data->type == OUT_RELADDR || data->sign == OUT_SIGNED) { |
406 | nasm_error(ERR_NONFATAL, |
407 | "%u-bit signed relocation unsupported by output format %s" , |
408 | (unsigned int)(asize << 3), ofmt->shortname); |
409 | } else { |
410 | nasm_error(ERR_WARNING | WARN_ZEXTRELOC, |
411 | "%u-bit %s relocation zero-extended from %u bits" , |
412 | (unsigned int)(asize << 3), |
413 | data->type == OUT_SEGMENT ? "segment" : "unsigned" , |
414 | (unsigned int)(amax << 3)); |
415 | } |
416 | zeropad = data->size - amax; |
417 | data->size = amax; |
418 | } |
419 | lfmt->output(data); |
420 | ofmt->output(data); |
421 | data->offset += data->size; |
422 | data->insoffs += data->size; |
423 | |
424 | if (zeropad) { |
425 | data->type = OUT_ZERODATA; |
426 | data->size = zeropad; |
427 | lfmt->output(data); |
428 | ofmt->output(data); |
429 | data->offset += zeropad; |
430 | data->insoffs += zeropad; |
431 | data->size += zeropad; /* Restore original size value */ |
432 | } |
433 | } |
434 | |
435 | static inline void out_rawdata(struct out_data *data, const void *rawdata, |
436 | size_t size) |
437 | { |
438 | data->type = OUT_RAWDATA; |
439 | data->data = rawdata; |
440 | data->size = size; |
441 | out(data); |
442 | } |
443 | |
444 | static void out_rawbyte(struct out_data *data, uint8_t byte) |
445 | { |
446 | data->type = OUT_RAWDATA; |
447 | data->data = &byte; |
448 | data->size = 1; |
449 | out(data); |
450 | } |
451 | |
452 | static inline void out_reserve(struct out_data *data, uint64_t size) |
453 | { |
454 | data->type = OUT_RESERVE; |
455 | data->size = size; |
456 | out(data); |
457 | } |
458 | |
459 | static void out_segment(struct out_data *data, const struct operand *opx) |
460 | { |
461 | if (opx->opflags & OPFLAG_RELATIVE) |
462 | nasm_error(ERR_NONFATAL, "segment references cannot be relative" ); |
463 | |
464 | data->type = OUT_SEGMENT; |
465 | data->sign = OUT_UNSIGNED; |
466 | data->size = 2; |
467 | data->toffset = opx->offset; |
468 | data->tsegment = ofmt->segbase(opx->segment | 1); |
469 | data->twrt = opx->wrt; |
470 | out(data); |
471 | } |
472 | |
473 | static void out_imm(struct out_data *data, const struct operand *opx, |
474 | int size, enum out_sign sign) |
475 | { |
476 | if (opx->segment != NO_SEG && (opx->segment & 1)) { |
477 | /* |
478 | * This is actually a segment reference, but eval() has |
479 | * already called ofmt->segbase() for us. Sigh. |
480 | */ |
481 | if (size < 2) |
482 | nasm_error(ERR_NONFATAL, "segment reference must be 16 bits" ); |
483 | |
484 | data->type = OUT_SEGMENT; |
485 | } else { |
486 | data->type = (opx->opflags & OPFLAG_RELATIVE) |
487 | ? OUT_RELADDR : OUT_ADDRESS; |
488 | } |
489 | data->sign = sign; |
490 | data->toffset = opx->offset; |
491 | data->tsegment = opx->segment; |
492 | data->twrt = opx->wrt; |
493 | /* |
494 | * XXX: improve this if at some point in the future we can |
495 | * distinguish the subtrahend in expressions like [foo - bar] |
496 | * where bar is a symbol in the current segment. However, at the |
497 | * current point, if OPFLAG_RELATIVE is set that subtraction has |
498 | * already occurred. |
499 | */ |
500 | data->relbase = 0; |
501 | data->size = size; |
502 | out(data); |
503 | } |
504 | |
505 | static void out_reladdr(struct out_data *data, const struct operand *opx, |
506 | int size) |
507 | { |
508 | if (opx->opflags & OPFLAG_RELATIVE) |
509 | nasm_error(ERR_NONFATAL, "invalid use of self-relative expression" ); |
510 | |
511 | data->type = OUT_RELADDR; |
512 | data->sign = OUT_SIGNED; |
513 | data->size = size; |
514 | data->toffset = opx->offset; |
515 | data->tsegment = opx->segment; |
516 | data->twrt = opx->wrt; |
517 | data->relbase = data->offset + (data->inslen - data->insoffs); |
518 | out(data); |
519 | } |
520 | |
521 | static bool jmp_match(int32_t segment, int64_t offset, int bits, |
522 | insn * ins, const struct itemplate *temp) |
523 | { |
524 | int64_t isize; |
525 | const uint8_t *code = temp->code; |
526 | uint8_t c = code[0]; |
527 | bool is_byte; |
528 | |
529 | if (((c & ~1) != 0370) || (ins->oprs[0].type & STRICT)) |
530 | return false; |
531 | if (!optimizing.level || (optimizing.flag & OPTIM_DISABLE_JMP_MATCH)) |
532 | return false; |
533 | if (optimizing.level < 0 && c == 0371) |
534 | return false; |
535 | |
536 | isize = calcsize(segment, offset, bits, ins, temp); |
537 | |
538 | if (ins->oprs[0].opflags & OPFLAG_UNKNOWN) |
539 | /* Be optimistic in pass 1 */ |
540 | return true; |
541 | |
542 | if (ins->oprs[0].segment != segment) |
543 | return false; |
544 | |
545 | isize = ins->oprs[0].offset - offset - isize; /* isize is delta */ |
546 | is_byte = (isize >= -128 && isize <= 127); /* is it byte size? */ |
547 | |
548 | if (is_byte && c == 0371 && ins->prefixes[PPS_REP] == P_BND) { |
549 | /* jmp short (opcode eb) cannot be used with bnd prefix. */ |
550 | ins->prefixes[PPS_REP] = P_none; |
551 | nasm_error(ERR_WARNING | WARN_BND | ERR_PASS2 , |
552 | "jmp short does not init bnd regs - bnd prefix dropped." ); |
553 | } |
554 | |
555 | return is_byte; |
556 | } |
557 | |
558 | /* This is totally just a wild guess what is reasonable... */ |
559 | #define INCBIN_MAX_BUF (ZERO_BUF_SIZE * 16) |
560 | |
561 | int64_t assemble(int32_t segment, int64_t start, int bits, insn *instruction) |
562 | { |
563 | struct out_data data; |
564 | const struct itemplate *temp; |
565 | enum match_result m; |
566 | int64_t wsize; /* size for DB etc. */ |
567 | |
568 | nasm_zero(data); |
569 | data.offset = start; |
570 | data.segment = segment; |
571 | data.itemp = NULL; |
572 | data.bits = bits; |
573 | |
574 | wsize = db_bytes(instruction->opcode); |
575 | if (wsize == -1) |
576 | return 0; |
577 | |
578 | if (wsize) { |
579 | extop *e; |
580 | |
581 | list_for_each(e, instruction->eops) { |
582 | if (e->type == EOT_DB_NUMBER) { |
583 | if (wsize > 8) { |
584 | nasm_error(ERR_NONFATAL, |
585 | "integer supplied to a DT, DO, DY or DZ" |
586 | " instruction" ); |
587 | } else { |
588 | data.insoffs = 0; |
589 | data.inslen = data.size = wsize; |
590 | data.toffset = e->offset; |
591 | data.twrt = e->wrt; |
592 | data.relbase = 0; |
593 | if (e->segment != NO_SEG && (e->segment & 1)) { |
594 | data.tsegment = e->segment; |
595 | data.type = OUT_SEGMENT; |
596 | data.sign = OUT_UNSIGNED; |
597 | } else { |
598 | data.tsegment = e->segment; |
599 | data.type = e->relative ? OUT_RELADDR : OUT_ADDRESS; |
600 | data.sign = OUT_WRAP; |
601 | } |
602 | out(&data); |
603 | } |
604 | } else if (e->type == EOT_DB_STRING || |
605 | e->type == EOT_DB_STRING_FREE) { |
606 | int align = e->stringlen % wsize; |
607 | if (align) |
608 | align = wsize - align; |
609 | |
610 | data.insoffs = 0; |
611 | data.inslen = e->stringlen + align; |
612 | |
613 | out_rawdata(&data, e->stringval, e->stringlen); |
614 | out_rawdata(&data, zero_buffer, align); |
615 | } |
616 | } |
617 | } else if (instruction->opcode == I_INCBIN) { |
618 | const char *fname = instruction->eops->stringval; |
619 | FILE *fp; |
620 | size_t t = instruction->times; /* INCBIN handles TIMES by itself */ |
621 | off_t base = 0; |
622 | off_t len; |
623 | const void *map = NULL; |
624 | char *buf = NULL; |
625 | size_t blk = 0; /* Buffered I/O block size */ |
626 | size_t m = 0; /* Bytes last read */ |
627 | |
628 | if (!t) |
629 | goto done; |
630 | |
631 | fp = nasm_open_read(fname, NF_BINARY|NF_FORMAP); |
632 | if (!fp) { |
633 | nasm_error(ERR_NONFATAL, "`incbin': unable to open file `%s'" , |
634 | fname); |
635 | goto done; |
636 | } |
637 | |
638 | len = nasm_file_size(fp); |
639 | |
640 | if (len == (off_t)-1) { |
641 | nasm_error(ERR_NONFATAL, "`incbin': unable to get length of file `%s'" , |
642 | fname); |
643 | goto close_done; |
644 | } |
645 | |
646 | if (instruction->eops->next) { |
647 | base = instruction->eops->next->offset; |
648 | if (base >= len) { |
649 | len = 0; |
650 | } else { |
651 | len -= base; |
652 | if (instruction->eops->next->next && |
653 | len > (off_t)instruction->eops->next->next->offset) |
654 | len = (off_t)instruction->eops->next->next->offset; |
655 | } |
656 | } |
657 | |
658 | lfmt->set_offset(data.offset); |
659 | lfmt->uplevel(LIST_INCBIN); |
660 | |
661 | if (!len) |
662 | goto end_incbin; |
663 | |
664 | /* Try to map file data */ |
665 | map = nasm_map_file(fp, base, len); |
666 | if (!map) { |
667 | blk = len < (off_t)INCBIN_MAX_BUF ? (size_t)len : INCBIN_MAX_BUF; |
668 | buf = nasm_malloc(blk); |
669 | } |
670 | |
671 | while (t--) { |
672 | /* |
673 | * Consider these irrelevant for INCBIN, since it is fully |
674 | * possible that these might be (way) bigger than an int |
675 | * can hold; there is, however, no reason to widen these |
676 | * types just for INCBIN. data.inslen == 0 signals to the |
677 | * backend that these fields are meaningless, if at all |
678 | * needed. |
679 | */ |
680 | data.insoffs = 0; |
681 | data.inslen = 0; |
682 | |
683 | if (map) { |
684 | out_rawdata(&data, map, len); |
685 | } else if ((off_t)m == len) { |
686 | out_rawdata(&data, buf, len); |
687 | } else { |
688 | off_t l = len; |
689 | |
690 | if (fseeko(fp, base, SEEK_SET) < 0 || ferror(fp)) { |
691 | nasm_error(ERR_NONFATAL, |
692 | "`incbin': unable to seek on file `%s'" , |
693 | fname); |
694 | goto end_incbin; |
695 | } |
696 | while (l > 0) { |
697 | m = fread(buf, 1, l < (off_t)blk ? (size_t)l : blk, fp); |
698 | if (!m || feof(fp)) { |
699 | /* |
700 | * This shouldn't happen unless the file |
701 | * actually changes while we are reading |
702 | * it. |
703 | */ |
704 | nasm_error(ERR_NONFATAL, |
705 | "`incbin': unexpected EOF while" |
706 | " reading file `%s'" , fname); |
707 | goto end_incbin; |
708 | } |
709 | out_rawdata(&data, buf, m); |
710 | l -= m; |
711 | } |
712 | } |
713 | } |
714 | end_incbin: |
715 | lfmt->downlevel(LIST_INCBIN); |
716 | if (instruction->times > 1) { |
717 | lfmt->uplevel(LIST_TIMES); |
718 | lfmt->downlevel(LIST_TIMES); |
719 | } |
720 | if (ferror(fp)) { |
721 | nasm_error(ERR_NONFATAL, |
722 | "`incbin': error while" |
723 | " reading file `%s'" , fname); |
724 | } |
725 | close_done: |
726 | if (buf) |
727 | nasm_free(buf); |
728 | if (map) |
729 | nasm_unmap_file(map, len); |
730 | fclose(fp); |
731 | done: |
732 | instruction->times = 1; /* Tell the upper layer not to iterate */ |
733 | ; |
734 | } else { |
735 | /* "Real" instruction */ |
736 | |
737 | /* Check to see if we need an address-size prefix */ |
738 | add_asp(instruction, bits); |
739 | |
740 | m = find_match(&temp, instruction, data.segment, data.offset, bits); |
741 | |
742 | if (m == MOK_GOOD) { |
743 | /* Matches! */ |
744 | int64_t insn_size = calcsize(data.segment, data.offset, |
745 | bits, instruction, temp); |
746 | nasm_assert(insn_size >= 0); |
747 | |
748 | data.itemp = temp; |
749 | data.bits = bits; |
750 | data.insoffs = 0; |
751 | data.inslen = insn_size; |
752 | |
753 | gencode(&data, instruction); |
754 | nasm_assert(data.insoffs == insn_size); |
755 | } else { |
756 | /* No match */ |
757 | switch (m) { |
758 | case MERR_OPSIZEMISSING: |
759 | nasm_error(ERR_NONFATAL, "operation size not specified" ); |
760 | break; |
761 | case MERR_OPSIZEMISMATCH: |
762 | nasm_error(ERR_NONFATAL, "mismatch in operand sizes" ); |
763 | break; |
764 | case MERR_BRNOTHERE: |
765 | nasm_error(ERR_NONFATAL, |
766 | "broadcast not permitted on this operand" ); |
767 | break; |
768 | case MERR_BRNUMMISMATCH: |
769 | nasm_error(ERR_NONFATAL, |
770 | "mismatch in the number of broadcasting elements" ); |
771 | break; |
772 | case MERR_MASKNOTHERE: |
773 | nasm_error(ERR_NONFATAL, |
774 | "mask not permitted on this operand" ); |
775 | break; |
776 | case MERR_DECONOTHERE: |
777 | nasm_error(ERR_NONFATAL, "unsupported mode decorator for instruction" ); |
778 | break; |
779 | case MERR_BADCPU: |
780 | nasm_error(ERR_NONFATAL, "no instruction for this cpu level" ); |
781 | break; |
782 | case MERR_BADMODE: |
783 | nasm_error(ERR_NONFATAL, "instruction not supported in %d-bit mode" , |
784 | bits); |
785 | break; |
786 | case MERR_ENCMISMATCH: |
787 | nasm_error(ERR_NONFATAL, "specific encoding scheme not available" ); |
788 | break; |
789 | case MERR_BADBND: |
790 | nasm_error(ERR_NONFATAL, "bnd prefix is not allowed" ); |
791 | break; |
792 | case MERR_BADREPNE: |
793 | nasm_error(ERR_NONFATAL, "%s prefix is not allowed" , |
794 | (has_prefix(instruction, PPS_REP, P_REPNE) ? |
795 | "repne" : "repnz" )); |
796 | break; |
797 | case MERR_REGSETSIZE: |
798 | nasm_error(ERR_NONFATAL, "invalid register set size" ); |
799 | break; |
800 | case MERR_REGSET: |
801 | nasm_error(ERR_NONFATAL, "register set not valid for operand" ); |
802 | break; |
803 | default: |
804 | nasm_error(ERR_NONFATAL, |
805 | "invalid combination of opcode and operands" ); |
806 | break; |
807 | } |
808 | |
809 | instruction->times = 1; /* Avoid repeated error messages */ |
810 | } |
811 | } |
812 | return data.offset - start; |
813 | } |
814 | |
815 | int64_t insn_size(int32_t segment, int64_t offset, int bits, insn *instruction) |
816 | { |
817 | const struct itemplate *temp; |
818 | enum match_result m; |
819 | |
820 | if (instruction->opcode == I_none) |
821 | return 0; |
822 | |
823 | if (opcode_is_db(instruction->opcode)) { |
824 | extop *e; |
825 | int32_t isize, osize, wsize; |
826 | |
827 | isize = 0; |
828 | wsize = db_bytes(instruction->opcode); |
829 | nasm_assert(wsize > 0); |
830 | |
831 | list_for_each(e, instruction->eops) { |
832 | int32_t align; |
833 | |
834 | osize = 0; |
835 | if (e->type == EOT_DB_NUMBER) { |
836 | osize = 1; |
837 | warn_overflow_const(e->offset, wsize); |
838 | } else if (e->type == EOT_DB_STRING || |
839 | e->type == EOT_DB_STRING_FREE) |
840 | osize = e->stringlen; |
841 | |
842 | align = (-osize) % wsize; |
843 | if (align < 0) |
844 | align += wsize; |
845 | isize += osize + align; |
846 | } |
847 | return isize; |
848 | } |
849 | |
850 | if (instruction->opcode == I_INCBIN) { |
851 | const char *fname = instruction->eops->stringval; |
852 | off_t len; |
853 | |
854 | len = nasm_file_size_by_path(fname); |
855 | if (len == (off_t)-1) { |
856 | nasm_error(ERR_NONFATAL, "`incbin': unable to get length of file `%s'" , |
857 | fname); |
858 | return 0; |
859 | } |
860 | |
861 | if (instruction->eops->next) { |
862 | if (len <= (off_t)instruction->eops->next->offset) { |
863 | len = 0; |
864 | } else { |
865 | len -= instruction->eops->next->offset; |
866 | if (instruction->eops->next->next && |
867 | len > (off_t)instruction->eops->next->next->offset) { |
868 | len = (off_t)instruction->eops->next->next->offset; |
869 | } |
870 | } |
871 | } |
872 | |
873 | len *= instruction->times; |
874 | instruction->times = 1; /* Tell the upper layer to not iterate */ |
875 | |
876 | return len; |
877 | } |
878 | |
879 | /* Check to see if we need an address-size prefix */ |
880 | add_asp(instruction, bits); |
881 | |
882 | m = find_match(&temp, instruction, segment, offset, bits); |
883 | if (m == MOK_GOOD) { |
884 | /* we've matched an instruction. */ |
885 | return calcsize(segment, offset, bits, instruction, temp); |
886 | } else { |
887 | return -1; /* didn't match any instruction */ |
888 | } |
889 | } |
890 | |
891 | static void bad_hle_warn(const insn * ins, uint8_t hleok) |
892 | { |
893 | enum prefixes rep_pfx = ins->prefixes[PPS_REP]; |
894 | enum whatwarn { w_none, w_lock, w_inval } ww; |
895 | static const enum whatwarn warn[2][4] = |
896 | { |
897 | { w_inval, w_inval, w_none, w_lock }, /* XACQUIRE */ |
898 | { w_inval, w_none, w_none, w_lock }, /* XRELEASE */ |
899 | }; |
900 | unsigned int n; |
901 | |
902 | n = (unsigned int)rep_pfx - P_XACQUIRE; |
903 | if (n > 1) |
904 | return; /* Not XACQUIRE/XRELEASE */ |
905 | |
906 | ww = warn[n][hleok]; |
907 | if (!is_class(MEMORY, ins->oprs[0].type)) |
908 | ww = w_inval; /* HLE requires operand 0 to be memory */ |
909 | |
910 | switch (ww) { |
911 | case w_none: |
912 | break; |
913 | |
914 | case w_lock: |
915 | if (ins->prefixes[PPS_LOCK] != P_LOCK) { |
916 | nasm_error(ERR_WARNING | WARN_HLE | ERR_PASS2, |
917 | "%s with this instruction requires lock" , |
918 | prefix_name(rep_pfx)); |
919 | } |
920 | break; |
921 | |
922 | case w_inval: |
923 | nasm_error(ERR_WARNING | WARN_HLE | ERR_PASS2, |
924 | "%s invalid with this instruction" , |
925 | prefix_name(rep_pfx)); |
926 | break; |
927 | } |
928 | } |
929 | |
930 | /* Common construct */ |
931 | #define case3(x) case (x): case (x)+1: case (x)+2 |
932 | #define case4(x) case3(x): case (x)+3 |
933 | |
934 | static int64_t calcsize(int32_t segment, int64_t offset, int bits, |
935 | insn * ins, const struct itemplate *temp) |
936 | { |
937 | const uint8_t *codes = temp->code; |
938 | int64_t length = 0; |
939 | uint8_t c; |
940 | int rex_mask = ~0; |
941 | int op1, op2; |
942 | struct operand *opx; |
943 | uint8_t opex = 0; |
944 | enum ea_type eat; |
945 | uint8_t hleok = 0; |
946 | bool lockcheck = true; |
947 | enum reg_enum mib_index = R_none; /* For a separate index MIB reg form */ |
948 | const char *errmsg; |
949 | |
950 | ins->rex = 0; /* Ensure REX is reset */ |
951 | eat = EA_SCALAR; /* Expect a scalar EA */ |
952 | memset(ins->evex_p, 0, 3); /* Ensure EVEX is reset */ |
953 | |
954 | if (ins->prefixes[PPS_OSIZE] == P_O64) |
955 | ins->rex |= REX_W; |
956 | |
957 | (void)segment; /* Don't warn that this parameter is unused */ |
958 | (void)offset; /* Don't warn that this parameter is unused */ |
959 | |
960 | while (*codes) { |
961 | c = *codes++; |
962 | op1 = (c & 3) + ((opex & 1) << 2); |
963 | op2 = ((c >> 3) & 3) + ((opex & 2) << 1); |
964 | opx = &ins->oprs[op1]; |
965 | opex = 0; /* For the next iteration */ |
966 | |
967 | switch (c) { |
968 | case4(01): |
969 | codes += c, length += c; |
970 | break; |
971 | |
972 | case3(05): |
973 | opex = c; |
974 | break; |
975 | |
976 | case4(010): |
977 | ins->rex |= |
978 | op_rexflags(opx, REX_B|REX_H|REX_P|REX_W); |
979 | codes++, length++; |
980 | break; |
981 | |
982 | case4(014): |
983 | /* this is an index reg of MIB operand */ |
984 | mib_index = opx->basereg; |
985 | break; |
986 | |
987 | case4(020): |
988 | case4(024): |
989 | length++; |
990 | break; |
991 | |
992 | case4(030): |
993 | length += 2; |
994 | break; |
995 | |
996 | case4(034): |
997 | if (opx->type & (BITS16 | BITS32 | BITS64)) |
998 | length += (opx->type & BITS16) ? 2 : 4; |
999 | else |
1000 | length += (bits == 16) ? 2 : 4; |
1001 | break; |
1002 | |
1003 | case4(040): |
1004 | length += 4; |
1005 | break; |
1006 | |
1007 | case4(044): |
1008 | length += ins->addr_size >> 3; |
1009 | break; |
1010 | |
1011 | case4(050): |
1012 | length++; |
1013 | break; |
1014 | |
1015 | case4(054): |
1016 | length += 8; /* MOV reg64/imm */ |
1017 | break; |
1018 | |
1019 | case4(060): |
1020 | length += 2; |
1021 | break; |
1022 | |
1023 | case4(064): |
1024 | if (opx->type & (BITS16 | BITS32 | BITS64)) |
1025 | length += (opx->type & BITS16) ? 2 : 4; |
1026 | else |
1027 | length += (bits == 16) ? 2 : 4; |
1028 | break; |
1029 | |
1030 | case4(070): |
1031 | length += 4; |
1032 | break; |
1033 | |
1034 | case4(074): |
1035 | length += 2; |
1036 | break; |
1037 | |
1038 | case 0172: |
1039 | case 0173: |
1040 | codes++; |
1041 | length++; |
1042 | break; |
1043 | |
1044 | case4(0174): |
1045 | length++; |
1046 | break; |
1047 | |
1048 | case4(0240): |
1049 | ins->rex |= REX_EV; |
1050 | ins->vexreg = regval(opx); |
1051 | ins->evex_p[2] |= op_evexflags(opx, EVEX_P2VP, 2); /* High-16 NDS */ |
1052 | ins->vex_cm = *codes++; |
1053 | ins->vex_wlp = *codes++; |
1054 | ins->evex_tuple = (*codes++ - 0300); |
1055 | break; |
1056 | |
1057 | case 0250: |
1058 | ins->rex |= REX_EV; |
1059 | ins->vexreg = 0; |
1060 | ins->vex_cm = *codes++; |
1061 | ins->vex_wlp = *codes++; |
1062 | ins->evex_tuple = (*codes++ - 0300); |
1063 | break; |
1064 | |
1065 | case4(0254): |
1066 | length += 4; |
1067 | break; |
1068 | |
1069 | case4(0260): |
1070 | ins->rex |= REX_V; |
1071 | ins->vexreg = regval(opx); |
1072 | ins->vex_cm = *codes++; |
1073 | ins->vex_wlp = *codes++; |
1074 | break; |
1075 | |
1076 | case 0270: |
1077 | ins->rex |= REX_V; |
1078 | ins->vexreg = 0; |
1079 | ins->vex_cm = *codes++; |
1080 | ins->vex_wlp = *codes++; |
1081 | break; |
1082 | |
1083 | case3(0271): |
1084 | hleok = c & 3; |
1085 | break; |
1086 | |
1087 | case4(0274): |
1088 | length++; |
1089 | break; |
1090 | |
1091 | case4(0300): |
1092 | break; |
1093 | |
1094 | case 0310: |
1095 | if (bits == 64) |
1096 | return -1; |
1097 | length += (bits != 16) && !has_prefix(ins, PPS_ASIZE, P_A16); |
1098 | break; |
1099 | |
1100 | case 0311: |
1101 | length += (bits != 32) && !has_prefix(ins, PPS_ASIZE, P_A32); |
1102 | break; |
1103 | |
1104 | case 0312: |
1105 | break; |
1106 | |
1107 | case 0313: |
1108 | if (bits != 64 || has_prefix(ins, PPS_ASIZE, P_A16) || |
1109 | has_prefix(ins, PPS_ASIZE, P_A32)) |
1110 | return -1; |
1111 | break; |
1112 | |
1113 | case4(0314): |
1114 | break; |
1115 | |
1116 | case 0320: |
1117 | { |
1118 | enum prefixes pfx = ins->prefixes[PPS_OSIZE]; |
1119 | if (pfx == P_O16) |
1120 | break; |
1121 | if (pfx != P_none) |
1122 | nasm_error(ERR_WARNING | ERR_PASS2, "invalid operand size prefix" ); |
1123 | else |
1124 | ins->prefixes[PPS_OSIZE] = P_O16; |
1125 | break; |
1126 | } |
1127 | |
1128 | case 0321: |
1129 | { |
1130 | enum prefixes pfx = ins->prefixes[PPS_OSIZE]; |
1131 | if (pfx == P_O32) |
1132 | break; |
1133 | if (pfx != P_none) |
1134 | nasm_error(ERR_WARNING | ERR_PASS2, "invalid operand size prefix" ); |
1135 | else |
1136 | ins->prefixes[PPS_OSIZE] = P_O32; |
1137 | break; |
1138 | } |
1139 | |
1140 | case 0322: |
1141 | break; |
1142 | |
1143 | case 0323: |
1144 | rex_mask &= ~REX_W; |
1145 | break; |
1146 | |
1147 | case 0324: |
1148 | ins->rex |= REX_W; |
1149 | break; |
1150 | |
1151 | case 0325: |
1152 | ins->rex |= REX_NH; |
1153 | break; |
1154 | |
1155 | case 0326: |
1156 | break; |
1157 | |
1158 | case 0330: |
1159 | codes++, length++; |
1160 | break; |
1161 | |
1162 | case 0331: |
1163 | break; |
1164 | |
1165 | case 0332: |
1166 | case 0333: |
1167 | length++; |
1168 | break; |
1169 | |
1170 | case 0334: |
1171 | ins->rex |= REX_L; |
1172 | break; |
1173 | |
1174 | case 0335: |
1175 | break; |
1176 | |
1177 | case 0336: |
1178 | if (!ins->prefixes[PPS_REP]) |
1179 | ins->prefixes[PPS_REP] = P_REP; |
1180 | break; |
1181 | |
1182 | case 0337: |
1183 | if (!ins->prefixes[PPS_REP]) |
1184 | ins->prefixes[PPS_REP] = P_REPNE; |
1185 | break; |
1186 | |
1187 | case 0340: |
1188 | if (!absolute_op(&ins->oprs[0])) |
1189 | nasm_error(ERR_NONFATAL, "attempt to reserve non-constant" |
1190 | " quantity of BSS space" ); |
1191 | else if (ins->oprs[0].opflags & OPFLAG_FORWARD) |
1192 | nasm_error(ERR_WARNING | ERR_PASS1, |
1193 | "forward reference in RESx can have unpredictable results" ); |
1194 | else |
1195 | length += ins->oprs[0].offset; |
1196 | break; |
1197 | |
1198 | case 0341: |
1199 | if (!ins->prefixes[PPS_WAIT]) |
1200 | ins->prefixes[PPS_WAIT] = P_WAIT; |
1201 | break; |
1202 | |
1203 | case 0360: |
1204 | break; |
1205 | |
1206 | case 0361: |
1207 | length++; |
1208 | break; |
1209 | |
1210 | case 0364: |
1211 | case 0365: |
1212 | break; |
1213 | |
1214 | case 0366: |
1215 | case 0367: |
1216 | length++; |
1217 | break; |
1218 | |
1219 | case 0370: |
1220 | case 0371: |
1221 | break; |
1222 | |
1223 | case 0373: |
1224 | length++; |
1225 | break; |
1226 | |
1227 | case 0374: |
1228 | eat = EA_XMMVSIB; |
1229 | break; |
1230 | |
1231 | case 0375: |
1232 | eat = EA_YMMVSIB; |
1233 | break; |
1234 | |
1235 | case 0376: |
1236 | eat = EA_ZMMVSIB; |
1237 | break; |
1238 | |
1239 | case4(0100): |
1240 | case4(0110): |
1241 | case4(0120): |
1242 | case4(0130): |
1243 | case4(0200): |
1244 | case4(0204): |
1245 | case4(0210): |
1246 | case4(0214): |
1247 | case4(0220): |
1248 | case4(0224): |
1249 | case4(0230): |
1250 | case4(0234): |
1251 | { |
1252 | ea ea_data; |
1253 | int rfield; |
1254 | opflags_t rflags; |
1255 | struct operand *opy = &ins->oprs[op2]; |
1256 | struct operand *op_er_sae; |
1257 | |
1258 | ea_data.rex = 0; /* Ensure ea.REX is initially 0 */ |
1259 | |
1260 | if (c <= 0177) { |
1261 | /* pick rfield from operand b (opx) */ |
1262 | rflags = regflag(opx); |
1263 | rfield = nasm_regvals[opx->basereg]; |
1264 | } else { |
1265 | rflags = 0; |
1266 | rfield = c & 7; |
1267 | } |
1268 | |
1269 | /* EVEX.b1 : evex_brerop contains the operand position */ |
1270 | op_er_sae = (ins->evex_brerop >= 0 ? |
1271 | &ins->oprs[ins->evex_brerop] : NULL); |
1272 | |
1273 | if (op_er_sae && (op_er_sae->decoflags & (ER | SAE))) { |
1274 | /* set EVEX.b */ |
1275 | ins->evex_p[2] |= EVEX_P2B; |
1276 | if (op_er_sae->decoflags & ER) { |
1277 | /* set EVEX.RC (rounding control) */ |
1278 | ins->evex_p[2] |= ((ins->evex_rm - BRC_RN) << 5) |
1279 | & EVEX_P2RC; |
1280 | } |
1281 | } else { |
1282 | /* set EVEX.L'L (vector length) */ |
1283 | ins->evex_p[2] |= ((ins->vex_wlp << (5 - 2)) & EVEX_P2LL); |
1284 | ins->evex_p[1] |= ((ins->vex_wlp << (7 - 4)) & EVEX_P1W); |
1285 | if (opy->decoflags & BRDCAST_MASK) { |
1286 | /* set EVEX.b */ |
1287 | ins->evex_p[2] |= EVEX_P2B; |
1288 | } |
1289 | } |
1290 | |
1291 | if (itemp_has(temp, IF_MIB)) { |
1292 | opy->eaflags |= EAF_MIB; |
1293 | /* |
1294 | * if a separate form of MIB (ICC style) is used, |
1295 | * the index reg info is merged into mem operand |
1296 | */ |
1297 | if (mib_index != R_none) { |
1298 | opy->indexreg = mib_index; |
1299 | opy->scale = 1; |
1300 | opy->hintbase = mib_index; |
1301 | opy->hinttype = EAH_NOTBASE; |
1302 | } |
1303 | } |
1304 | |
1305 | if (process_ea(opy, &ea_data, bits, |
1306 | rfield, rflags, ins, &errmsg) != eat) { |
1307 | nasm_error(ERR_NONFATAL, "%s" , errmsg); |
1308 | return -1; |
1309 | } else { |
1310 | ins->rex |= ea_data.rex; |
1311 | length += ea_data.size; |
1312 | } |
1313 | } |
1314 | break; |
1315 | |
1316 | default: |
1317 | nasm_panic(0, "internal instruction table corrupt" |
1318 | ": instruction code \\%o (0x%02X) given" , c, c); |
1319 | break; |
1320 | } |
1321 | } |
1322 | |
1323 | ins->rex &= rex_mask; |
1324 | |
1325 | if (ins->rex & REX_NH) { |
1326 | if (ins->rex & REX_H) { |
1327 | nasm_error(ERR_NONFATAL, "instruction cannot use high registers" ); |
1328 | return -1; |
1329 | } |
1330 | ins->rex &= ~REX_P; /* Don't force REX prefix due to high reg */ |
1331 | } |
1332 | |
1333 | switch (ins->prefixes[PPS_VEX]) { |
1334 | case P_EVEX: |
1335 | if (!(ins->rex & REX_EV)) |
1336 | return -1; |
1337 | break; |
1338 | case P_VEX3: |
1339 | case P_VEX2: |
1340 | if (!(ins->rex & REX_V)) |
1341 | return -1; |
1342 | break; |
1343 | default: |
1344 | break; |
1345 | } |
1346 | |
1347 | if (ins->rex & (REX_V | REX_EV)) { |
1348 | int bad32 = REX_R|REX_W|REX_X|REX_B; |
1349 | |
1350 | if (ins->rex & REX_H) { |
1351 | nasm_error(ERR_NONFATAL, "cannot use high register in AVX instruction" ); |
1352 | return -1; |
1353 | } |
1354 | switch (ins->vex_wlp & 060) { |
1355 | case 000: |
1356 | case 040: |
1357 | ins->rex &= ~REX_W; |
1358 | break; |
1359 | case 020: |
1360 | ins->rex |= REX_W; |
1361 | bad32 &= ~REX_W; |
1362 | break; |
1363 | case 060: |
1364 | /* Follow REX_W */ |
1365 | break; |
1366 | } |
1367 | |
1368 | if (bits != 64 && ((ins->rex & bad32) || ins->vexreg > 7)) { |
1369 | nasm_error(ERR_NONFATAL, "invalid operands in non-64-bit mode" ); |
1370 | return -1; |
1371 | } else if (!(ins->rex & REX_EV) && |
1372 | ((ins->vexreg > 15) || (ins->evex_p[0] & 0xf0))) { |
1373 | nasm_error(ERR_NONFATAL, "invalid high-16 register in non-AVX-512" ); |
1374 | return -1; |
1375 | } |
1376 | if (ins->rex & REX_EV) |
1377 | length += 4; |
1378 | else if (ins->vex_cm != 1 || (ins->rex & (REX_W|REX_X|REX_B)) || |
1379 | ins->prefixes[PPS_VEX] == P_VEX3) |
1380 | length += 3; |
1381 | else |
1382 | length += 2; |
1383 | } else if (ins->rex & REX_MASK) { |
1384 | if (ins->rex & REX_H) { |
1385 | nasm_error(ERR_NONFATAL, "cannot use high register in rex instruction" ); |
1386 | return -1; |
1387 | } else if (bits == 64) { |
1388 | length++; |
1389 | } else if ((ins->rex & REX_L) && |
1390 | !(ins->rex & (REX_P|REX_W|REX_X|REX_B)) && |
1391 | iflag_cpu_level_ok(&cpu, IF_X86_64)) { |
1392 | /* LOCK-as-REX.R */ |
1393 | assert_no_prefix(ins, PPS_LOCK); |
1394 | lockcheck = false; /* Already errored, no need for warning */ |
1395 | length++; |
1396 | } else { |
1397 | nasm_error(ERR_NONFATAL, "invalid operands in non-64-bit mode" ); |
1398 | return -1; |
1399 | } |
1400 | } |
1401 | |
1402 | if (has_prefix(ins, PPS_LOCK, P_LOCK) && lockcheck && |
1403 | (!itemp_has(temp,IF_LOCK) || !is_class(MEMORY, ins->oprs[0].type))) { |
1404 | nasm_error(ERR_WARNING | WARN_LOCK | ERR_PASS2 , |
1405 | "instruction is not lockable" ); |
1406 | } |
1407 | |
1408 | bad_hle_warn(ins, hleok); |
1409 | |
1410 | /* |
1411 | * when BND prefix is set by DEFAULT directive, |
1412 | * BND prefix is added to every appropriate instruction line |
1413 | * unless it is overridden by NOBND prefix. |
1414 | */ |
1415 | if (globalbnd && |
1416 | (itemp_has(temp, IF_BND) && !has_prefix(ins, PPS_REP, P_NOBND))) |
1417 | ins->prefixes[PPS_REP] = P_BND; |
1418 | |
1419 | /* |
1420 | * Add length of legacy prefixes |
1421 | */ |
1422 | length += emit_prefix(NULL, bits, ins); |
1423 | |
1424 | return length; |
1425 | } |
1426 | |
1427 | static inline void emit_rex(struct out_data *data, insn *ins) |
1428 | { |
1429 | if (data->bits == 64) { |
1430 | if ((ins->rex & REX_MASK) && |
1431 | !(ins->rex & (REX_V | REX_EV)) && |
1432 | !ins->rex_done) { |
1433 | uint8_t rex = (ins->rex & REX_MASK) | REX_P; |
1434 | out_rawbyte(data, rex); |
1435 | ins->rex_done = true; |
1436 | } |
1437 | } |
1438 | } |
1439 | |
1440 | static int emit_prefix(struct out_data *data, const int bits, insn *ins) |
1441 | { |
1442 | int bytes = 0; |
1443 | int j; |
1444 | |
1445 | for (j = 0; j < MAXPREFIX; j++) { |
1446 | uint8_t c = 0; |
1447 | switch (ins->prefixes[j]) { |
1448 | case P_WAIT: |
1449 | c = 0x9B; |
1450 | break; |
1451 | case P_LOCK: |
1452 | c = 0xF0; |
1453 | break; |
1454 | case P_REPNE: |
1455 | case P_REPNZ: |
1456 | case P_XACQUIRE: |
1457 | case P_BND: |
1458 | c = 0xF2; |
1459 | break; |
1460 | case P_REPE: |
1461 | case P_REPZ: |
1462 | case P_REP: |
1463 | case P_XRELEASE: |
1464 | c = 0xF3; |
1465 | break; |
1466 | case R_CS: |
1467 | if (bits == 64) { |
1468 | nasm_error(ERR_WARNING | ERR_PASS2, |
1469 | "cs segment base generated, but will be ignored in 64-bit mode" ); |
1470 | } |
1471 | c = 0x2E; |
1472 | break; |
1473 | case R_DS: |
1474 | if (bits == 64) { |
1475 | nasm_error(ERR_WARNING | ERR_PASS2, |
1476 | "ds segment base generated, but will be ignored in 64-bit mode" ); |
1477 | } |
1478 | c = 0x3E; |
1479 | break; |
1480 | case R_ES: |
1481 | if (bits == 64) { |
1482 | nasm_error(ERR_WARNING | ERR_PASS2, |
1483 | "es segment base generated, but will be ignored in 64-bit mode" ); |
1484 | } |
1485 | c = 0x26; |
1486 | break; |
1487 | case R_FS: |
1488 | c = 0x64; |
1489 | break; |
1490 | case R_GS: |
1491 | c = 0x65; |
1492 | break; |
1493 | case R_SS: |
1494 | if (bits == 64) { |
1495 | nasm_error(ERR_WARNING | ERR_PASS2, |
1496 | "ss segment base generated, but will be ignored in 64-bit mode" ); |
1497 | } |
1498 | c = 0x36; |
1499 | break; |
1500 | case R_SEGR6: |
1501 | case R_SEGR7: |
1502 | nasm_error(ERR_NONFATAL, |
1503 | "segr6 and segr7 cannot be used as prefixes" ); |
1504 | break; |
1505 | case P_A16: |
1506 | if (bits == 64) { |
1507 | nasm_error(ERR_NONFATAL, |
1508 | "16-bit addressing is not supported " |
1509 | "in 64-bit mode" ); |
1510 | } else if (bits != 16) |
1511 | c = 0x67; |
1512 | break; |
1513 | case P_A32: |
1514 | if (bits != 32) |
1515 | c = 0x67; |
1516 | break; |
1517 | case P_A64: |
1518 | if (bits != 64) { |
1519 | nasm_error(ERR_NONFATAL, |
1520 | "64-bit addressing is only supported " |
1521 | "in 64-bit mode" ); |
1522 | } |
1523 | break; |
1524 | case P_ASP: |
1525 | c = 0x67; |
1526 | break; |
1527 | case P_O16: |
1528 | if (bits != 16) |
1529 | c = 0x66; |
1530 | break; |
1531 | case P_O32: |
1532 | if (bits == 16) |
1533 | c = 0x66; |
1534 | break; |
1535 | case P_O64: |
1536 | /* REX.W */ |
1537 | break; |
1538 | case P_OSP: |
1539 | c = 0x66; |
1540 | break; |
1541 | case P_EVEX: |
1542 | case P_VEX3: |
1543 | case P_VEX2: |
1544 | case P_NOBND: |
1545 | case P_none: |
1546 | break; |
1547 | default: |
1548 | nasm_panic(0, "invalid instruction prefix" ); |
1549 | } |
1550 | if (c) { |
1551 | if (data) |
1552 | out_rawbyte(data, c); |
1553 | bytes++; |
1554 | } |
1555 | } |
1556 | return bytes; |
1557 | } |
1558 | |
1559 | static void gencode(struct out_data *data, insn *ins) |
1560 | { |
1561 | uint8_t c; |
1562 | uint8_t bytes[4]; |
1563 | int64_t size; |
1564 | int op1, op2; |
1565 | struct operand *opx; |
1566 | const uint8_t *codes = data->itemp->code; |
1567 | uint8_t opex = 0; |
1568 | enum ea_type eat = EA_SCALAR; |
1569 | int r; |
1570 | const int bits = data->bits; |
1571 | const char *errmsg; |
1572 | |
1573 | ins->rex_done = false; |
1574 | |
1575 | emit_prefix(data, bits, ins); |
1576 | |
1577 | while (*codes) { |
1578 | c = *codes++; |
1579 | op1 = (c & 3) + ((opex & 1) << 2); |
1580 | op2 = ((c >> 3) & 3) + ((opex & 2) << 1); |
1581 | opx = &ins->oprs[op1]; |
1582 | opex = 0; /* For the next iteration */ |
1583 | |
1584 | |
1585 | switch (c) { |
1586 | case 01: |
1587 | case 02: |
1588 | case 03: |
1589 | case 04: |
1590 | emit_rex(data, ins); |
1591 | out_rawdata(data, codes, c); |
1592 | codes += c; |
1593 | break; |
1594 | |
1595 | case 05: |
1596 | case 06: |
1597 | case 07: |
1598 | opex = c; |
1599 | break; |
1600 | |
1601 | case4(010): |
1602 | emit_rex(data, ins); |
1603 | out_rawbyte(data, *codes++ + (regval(opx) & 7)); |
1604 | break; |
1605 | |
1606 | case4(014): |
1607 | break; |
1608 | |
1609 | case4(020): |
1610 | out_imm(data, opx, 1, OUT_WRAP); |
1611 | break; |
1612 | |
1613 | case4(024): |
1614 | out_imm(data, opx, 1, OUT_UNSIGNED); |
1615 | break; |
1616 | |
1617 | case4(030): |
1618 | out_imm(data, opx, 2, OUT_WRAP); |
1619 | break; |
1620 | |
1621 | case4(034): |
1622 | if (opx->type & (BITS16 | BITS32)) |
1623 | size = (opx->type & BITS16) ? 2 : 4; |
1624 | else |
1625 | size = (bits == 16) ? 2 : 4; |
1626 | out_imm(data, opx, size, OUT_WRAP); |
1627 | break; |
1628 | |
1629 | case4(040): |
1630 | out_imm(data, opx, 4, OUT_WRAP); |
1631 | break; |
1632 | |
1633 | case4(044): |
1634 | size = ins->addr_size >> 3; |
1635 | out_imm(data, opx, size, OUT_WRAP); |
1636 | break; |
1637 | |
1638 | case4(050): |
1639 | if (opx->segment == data->segment) { |
1640 | int64_t delta = opx->offset - data->offset |
1641 | - (data->inslen - data->insoffs); |
1642 | if (delta > 127 || delta < -128) |
1643 | nasm_error(ERR_NONFATAL, "short jump is out of range" ); |
1644 | } |
1645 | out_reladdr(data, opx, 1); |
1646 | break; |
1647 | |
1648 | case4(054): |
1649 | out_imm(data, opx, 8, OUT_WRAP); |
1650 | break; |
1651 | |
1652 | case4(060): |
1653 | out_reladdr(data, opx, 2); |
1654 | break; |
1655 | |
1656 | case4(064): |
1657 | if (opx->type & (BITS16 | BITS32 | BITS64)) |
1658 | size = (opx->type & BITS16) ? 2 : 4; |
1659 | else |
1660 | size = (bits == 16) ? 2 : 4; |
1661 | |
1662 | out_reladdr(data, opx, size); |
1663 | break; |
1664 | |
1665 | case4(070): |
1666 | out_reladdr(data, opx, 4); |
1667 | break; |
1668 | |
1669 | case4(074): |
1670 | if (opx->segment == NO_SEG) |
1671 | nasm_error(ERR_NONFATAL, "value referenced by FAR is not" |
1672 | " relocatable" ); |
1673 | out_segment(data, opx); |
1674 | break; |
1675 | |
1676 | case 0172: |
1677 | { |
1678 | int mask = ins->prefixes[PPS_VEX] == P_EVEX ? 7 : 15; |
1679 | const struct operand *opy; |
1680 | |
1681 | c = *codes++; |
1682 | opx = &ins->oprs[c >> 3]; |
1683 | opy = &ins->oprs[c & 7]; |
1684 | if (!absolute_op(opy)) { |
1685 | nasm_error(ERR_NONFATAL, |
1686 | "non-absolute expression not permitted as argument %d" , |
1687 | c & 7); |
1688 | } else if (opy->offset & ~mask) { |
1689 | nasm_error(ERR_WARNING | ERR_PASS2 | WARN_NOV, |
1690 | "is4 argument exceeds bounds" ); |
1691 | } |
1692 | c = opy->offset & mask; |
1693 | goto emit_is4; |
1694 | } |
1695 | |
1696 | case 0173: |
1697 | c = *codes++; |
1698 | opx = &ins->oprs[c >> 4]; |
1699 | c &= 15; |
1700 | goto emit_is4; |
1701 | |
1702 | case4(0174): |
1703 | c = 0; |
1704 | emit_is4: |
1705 | r = nasm_regvals[opx->basereg]; |
1706 | out_rawbyte(data, (r << 4) | ((r & 0x10) >> 1) | c); |
1707 | break; |
1708 | |
1709 | case4(0254): |
1710 | if (absolute_op(opx) && |
1711 | (int32_t)opx->offset != (int64_t)opx->offset) { |
1712 | nasm_error(ERR_WARNING | ERR_PASS2 | WARN_NOV, |
1713 | "signed dword immediate exceeds bounds" ); |
1714 | } |
1715 | out_imm(data, opx, 4, OUT_SIGNED); |
1716 | break; |
1717 | |
1718 | case4(0240): |
1719 | case 0250: |
1720 | codes += 3; |
1721 | ins->evex_p[2] |= op_evexflags(&ins->oprs[0], |
1722 | EVEX_P2Z | EVEX_P2AAA, 2); |
1723 | ins->evex_p[2] ^= EVEX_P2VP; /* 1's complement */ |
1724 | bytes[0] = 0x62; |
1725 | /* EVEX.X can be set by either REX or EVEX for different reasons */ |
1726 | bytes[1] = ((((ins->rex & 7) << 5) | |
1727 | (ins->evex_p[0] & (EVEX_P0X | EVEX_P0RP))) ^ 0xf0) | |
1728 | (ins->vex_cm & EVEX_P0MM); |
1729 | bytes[2] = ((ins->rex & REX_W) << (7 - 3)) | |
1730 | ((~ins->vexreg & 15) << 3) | |
1731 | (1 << 2) | (ins->vex_wlp & 3); |
1732 | bytes[3] = ins->evex_p[2]; |
1733 | out_rawdata(data, bytes, 4); |
1734 | break; |
1735 | |
1736 | case4(0260): |
1737 | case 0270: |
1738 | codes += 2; |
1739 | if (ins->vex_cm != 1 || (ins->rex & (REX_W|REX_X|REX_B)) || |
1740 | ins->prefixes[PPS_VEX] == P_VEX3) { |
1741 | bytes[0] = (ins->vex_cm >> 6) ? 0x8f : 0xc4; |
1742 | bytes[1] = (ins->vex_cm & 31) | ((~ins->rex & 7) << 5); |
1743 | bytes[2] = ((ins->rex & REX_W) << (7-3)) | |
1744 | ((~ins->vexreg & 15)<< 3) | (ins->vex_wlp & 07); |
1745 | out_rawdata(data, bytes, 3); |
1746 | } else { |
1747 | bytes[0] = 0xc5; |
1748 | bytes[1] = ((~ins->rex & REX_R) << (7-2)) | |
1749 | ((~ins->vexreg & 15) << 3) | (ins->vex_wlp & 07); |
1750 | out_rawdata(data, bytes, 2); |
1751 | } |
1752 | break; |
1753 | |
1754 | case 0271: |
1755 | case 0272: |
1756 | case 0273: |
1757 | break; |
1758 | |
1759 | case4(0274): |
1760 | { |
1761 | uint64_t uv, um; |
1762 | int s; |
1763 | |
1764 | if (absolute_op(opx)) { |
1765 | if (ins->rex & REX_W) |
1766 | s = 64; |
1767 | else if (ins->prefixes[PPS_OSIZE] == P_O16) |
1768 | s = 16; |
1769 | else if (ins->prefixes[PPS_OSIZE] == P_O32) |
1770 | s = 32; |
1771 | else |
1772 | s = bits; |
1773 | |
1774 | um = (uint64_t)2 << (s-1); |
1775 | uv = opx->offset; |
1776 | |
1777 | if (uv > 127 && uv < (uint64_t)-128 && |
1778 | (uv < um-128 || uv > um-1)) { |
1779 | /* If this wasn't explicitly byte-sized, warn as though we |
1780 | * had fallen through to the imm16/32/64 case. |
1781 | */ |
1782 | nasm_error(ERR_WARNING | ERR_PASS2 | WARN_NOV, |
1783 | "%s value exceeds bounds" , |
1784 | (opx->type & BITS8) ? "signed byte" : |
1785 | s == 16 ? "word" : |
1786 | s == 32 ? "dword" : |
1787 | "signed dword" ); |
1788 | } |
1789 | |
1790 | /* Output as a raw byte to avoid byte overflow check */ |
1791 | out_rawbyte(data, (uint8_t)uv); |
1792 | } else { |
1793 | out_imm(data, opx, 1, OUT_WRAP); /* XXX: OUT_SIGNED? */ |
1794 | } |
1795 | break; |
1796 | } |
1797 | |
1798 | case4(0300): |
1799 | break; |
1800 | |
1801 | case 0310: |
1802 | if (bits == 32 && !has_prefix(ins, PPS_ASIZE, P_A16)) |
1803 | out_rawbyte(data, 0x67); |
1804 | break; |
1805 | |
1806 | case 0311: |
1807 | if (bits != 32 && !has_prefix(ins, PPS_ASIZE, P_A32)) |
1808 | out_rawbyte(data, 0x67); |
1809 | break; |
1810 | |
1811 | case 0312: |
1812 | break; |
1813 | |
1814 | case 0313: |
1815 | ins->rex = 0; |
1816 | break; |
1817 | |
1818 | case4(0314): |
1819 | break; |
1820 | |
1821 | case 0320: |
1822 | case 0321: |
1823 | break; |
1824 | |
1825 | case 0322: |
1826 | case 0323: |
1827 | break; |
1828 | |
1829 | case 0324: |
1830 | ins->rex |= REX_W; |
1831 | break; |
1832 | |
1833 | case 0325: |
1834 | break; |
1835 | |
1836 | case 0326: |
1837 | break; |
1838 | |
1839 | case 0330: |
1840 | out_rawbyte(data, *codes++ ^ get_cond_opcode(ins->condition)); |
1841 | break; |
1842 | |
1843 | case 0331: |
1844 | break; |
1845 | |
1846 | case 0332: |
1847 | case 0333: |
1848 | out_rawbyte(data, c - 0332 + 0xF2); |
1849 | break; |
1850 | |
1851 | case 0334: |
1852 | if (ins->rex & REX_R) |
1853 | out_rawbyte(data, 0xF0); |
1854 | ins->rex &= ~(REX_L|REX_R); |
1855 | break; |
1856 | |
1857 | case 0335: |
1858 | break; |
1859 | |
1860 | case 0336: |
1861 | case 0337: |
1862 | break; |
1863 | |
1864 | case 0340: |
1865 | if (ins->oprs[0].segment != NO_SEG) |
1866 | nasm_panic(0, "non-constant BSS size in pass two" ); |
1867 | |
1868 | out_reserve(data, ins->oprs[0].offset); |
1869 | break; |
1870 | |
1871 | case 0341: |
1872 | break; |
1873 | |
1874 | case 0360: |
1875 | break; |
1876 | |
1877 | case 0361: |
1878 | out_rawbyte(data, 0x66); |
1879 | break; |
1880 | |
1881 | case 0364: |
1882 | case 0365: |
1883 | break; |
1884 | |
1885 | case 0366: |
1886 | case 0367: |
1887 | out_rawbyte(data, c - 0366 + 0x66); |
1888 | break; |
1889 | |
1890 | case3(0370): |
1891 | break; |
1892 | |
1893 | case 0373: |
1894 | out_rawbyte(data, bits == 16 ? 3 : 5); |
1895 | break; |
1896 | |
1897 | case 0374: |
1898 | eat = EA_XMMVSIB; |
1899 | break; |
1900 | |
1901 | case 0375: |
1902 | eat = EA_YMMVSIB; |
1903 | break; |
1904 | |
1905 | case 0376: |
1906 | eat = EA_ZMMVSIB; |
1907 | break; |
1908 | |
1909 | case4(0100): |
1910 | case4(0110): |
1911 | case4(0120): |
1912 | case4(0130): |
1913 | case4(0200): |
1914 | case4(0204): |
1915 | case4(0210): |
1916 | case4(0214): |
1917 | case4(0220): |
1918 | case4(0224): |
1919 | case4(0230): |
1920 | case4(0234): |
1921 | { |
1922 | ea ea_data; |
1923 | int rfield; |
1924 | opflags_t rflags; |
1925 | uint8_t *p; |
1926 | struct operand *opy = &ins->oprs[op2]; |
1927 | |
1928 | if (c <= 0177) { |
1929 | /* pick rfield from operand b (opx) */ |
1930 | rflags = regflag(opx); |
1931 | rfield = nasm_regvals[opx->basereg]; |
1932 | } else { |
1933 | /* rfield is constant */ |
1934 | rflags = 0; |
1935 | rfield = c & 7; |
1936 | } |
1937 | |
1938 | if (process_ea(opy, &ea_data, bits, |
1939 | rfield, rflags, ins, &errmsg) != eat) |
1940 | nasm_error(ERR_NONFATAL, "%s" , errmsg); |
1941 | |
1942 | p = bytes; |
1943 | *p++ = ea_data.modrm; |
1944 | if (ea_data.sib_present) |
1945 | *p++ = ea_data.sib; |
1946 | out_rawdata(data, bytes, p - bytes); |
1947 | |
1948 | /* |
1949 | * Make sure the address gets the right offset in case |
1950 | * the line breaks in the .lst file (BR 1197827) |
1951 | */ |
1952 | |
1953 | if (ea_data.bytes) { |
1954 | /* use compressed displacement, if available */ |
1955 | if (ea_data.disp8) { |
1956 | out_rawbyte(data, ea_data.disp8); |
1957 | } else if (ea_data.rip) { |
1958 | out_reladdr(data, opy, ea_data.bytes); |
1959 | } else { |
1960 | int asize = ins->addr_size >> 3; |
1961 | |
1962 | if (overflow_general(opy->offset, asize) || |
1963 | signed_bits(opy->offset, ins->addr_size) != |
1964 | signed_bits(opy->offset, ea_data.bytes << 3)) |
1965 | warn_overflow(ea_data.bytes); |
1966 | |
1967 | out_imm(data, opy, ea_data.bytes, |
1968 | (asize > ea_data.bytes) |
1969 | ? OUT_SIGNED : OUT_WRAP); |
1970 | } |
1971 | } |
1972 | } |
1973 | break; |
1974 | |
1975 | default: |
1976 | nasm_panic(0, "internal instruction table corrupt" |
1977 | ": instruction code \\%o (0x%02X) given" , c, c); |
1978 | break; |
1979 | } |
1980 | } |
1981 | } |
1982 | |
1983 | static opflags_t regflag(const operand * o) |
1984 | { |
1985 | if (!is_register(o->basereg)) |
1986 | nasm_panic(0, "invalid operand passed to regflag()" ); |
1987 | return nasm_reg_flags[o->basereg]; |
1988 | } |
1989 | |
1990 | static int32_t regval(const operand * o) |
1991 | { |
1992 | if (!is_register(o->basereg)) |
1993 | nasm_panic(0, "invalid operand passed to regval()" ); |
1994 | return nasm_regvals[o->basereg]; |
1995 | } |
1996 | |
1997 | static int op_rexflags(const operand * o, int mask) |
1998 | { |
1999 | opflags_t flags; |
2000 | int val; |
2001 | |
2002 | if (!is_register(o->basereg)) |
2003 | nasm_panic(0, "invalid operand passed to op_rexflags()" ); |
2004 | |
2005 | flags = nasm_reg_flags[o->basereg]; |
2006 | val = nasm_regvals[o->basereg]; |
2007 | |
2008 | return rexflags(val, flags, mask); |
2009 | } |
2010 | |
2011 | static int rexflags(int val, opflags_t flags, int mask) |
2012 | { |
2013 | int rex = 0; |
2014 | |
2015 | if (val >= 0 && (val & 8)) |
2016 | rex |= REX_B|REX_X|REX_R; |
2017 | if (flags & BITS64) |
2018 | rex |= REX_W; |
2019 | if (!(REG_HIGH & ~flags)) /* AH, CH, DH, BH */ |
2020 | rex |= REX_H; |
2021 | else if (!(REG8 & ~flags) && val >= 4) /* SPL, BPL, SIL, DIL */ |
2022 | rex |= REX_P; |
2023 | |
2024 | return rex & mask; |
2025 | } |
2026 | |
2027 | static int evexflags(int val, decoflags_t deco, |
2028 | int mask, uint8_t byte) |
2029 | { |
2030 | int evex = 0; |
2031 | |
2032 | switch (byte) { |
2033 | case 0: |
2034 | if (val >= 0 && (val & 16)) |
2035 | evex |= (EVEX_P0RP | EVEX_P0X); |
2036 | break; |
2037 | case 2: |
2038 | if (val >= 0 && (val & 16)) |
2039 | evex |= EVEX_P2VP; |
2040 | if (deco & Z) |
2041 | evex |= EVEX_P2Z; |
2042 | if (deco & OPMASK_MASK) |
2043 | evex |= deco & EVEX_P2AAA; |
2044 | break; |
2045 | } |
2046 | return evex & mask; |
2047 | } |
2048 | |
2049 | static int op_evexflags(const operand * o, int mask, uint8_t byte) |
2050 | { |
2051 | int val; |
2052 | |
2053 | val = nasm_regvals[o->basereg]; |
2054 | |
2055 | return evexflags(val, o->decoflags, mask, byte); |
2056 | } |
2057 | |
2058 | static enum match_result find_match(const struct itemplate **tempp, |
2059 | insn *instruction, |
2060 | int32_t segment, int64_t offset, int bits) |
2061 | { |
2062 | const struct itemplate *temp; |
2063 | enum match_result m, merr; |
2064 | opflags_t xsizeflags[MAX_OPERANDS]; |
2065 | bool opsizemissing = false; |
2066 | int8_t broadcast = instruction->evex_brerop; |
2067 | int i; |
2068 | |
2069 | /* broadcasting uses a different data element size */ |
2070 | for (i = 0; i < instruction->operands; i++) |
2071 | if (i == broadcast) |
2072 | xsizeflags[i] = instruction->oprs[i].decoflags & BRSIZE_MASK; |
2073 | else |
2074 | xsizeflags[i] = instruction->oprs[i].type & SIZE_MASK; |
2075 | |
2076 | merr = MERR_INVALOP; |
2077 | |
2078 | for (temp = nasm_instructions[instruction->opcode]; |
2079 | temp->opcode != I_none; temp++) { |
2080 | m = matches(temp, instruction, bits); |
2081 | if (m == MOK_JUMP) { |
2082 | if (jmp_match(segment, offset, bits, instruction, temp)) |
2083 | m = MOK_GOOD; |
2084 | else |
2085 | m = MERR_INVALOP; |
2086 | } else if (m == MERR_OPSIZEMISSING && !itemp_has(temp, IF_SX)) { |
2087 | /* |
2088 | * Missing operand size and a candidate for fuzzy matching... |
2089 | */ |
2090 | for (i = 0; i < temp->operands; i++) |
2091 | if (i == broadcast) |
2092 | xsizeflags[i] |= temp->deco[i] & BRSIZE_MASK; |
2093 | else |
2094 | xsizeflags[i] |= temp->opd[i] & SIZE_MASK; |
2095 | opsizemissing = true; |
2096 | } |
2097 | if (m > merr) |
2098 | merr = m; |
2099 | if (merr == MOK_GOOD) |
2100 | goto done; |
2101 | } |
2102 | |
2103 | /* No match, but see if we can get a fuzzy operand size match... */ |
2104 | if (!opsizemissing) |
2105 | goto done; |
2106 | |
2107 | for (i = 0; i < instruction->operands; i++) { |
2108 | /* |
2109 | * We ignore extrinsic operand sizes on registers, so we should |
2110 | * never try to fuzzy-match on them. This also resolves the case |
2111 | * when we have e.g. "xmmrm128" in two different positions. |
2112 | */ |
2113 | if (is_class(REGISTER, instruction->oprs[i].type)) |
2114 | continue; |
2115 | |
2116 | /* This tests if xsizeflags[i] has more than one bit set */ |
2117 | if ((xsizeflags[i] & (xsizeflags[i]-1))) |
2118 | goto done; /* No luck */ |
2119 | |
2120 | if (i == broadcast) { |
2121 | instruction->oprs[i].decoflags |= xsizeflags[i]; |
2122 | instruction->oprs[i].type |= (xsizeflags[i] == BR_BITS32 ? |
2123 | BITS32 : BITS64); |
2124 | } else { |
2125 | instruction->oprs[i].type |= xsizeflags[i]; /* Set the size */ |
2126 | } |
2127 | } |
2128 | |
2129 | /* Try matching again... */ |
2130 | for (temp = nasm_instructions[instruction->opcode]; |
2131 | temp->opcode != I_none; temp++) { |
2132 | m = matches(temp, instruction, bits); |
2133 | if (m == MOK_JUMP) { |
2134 | if (jmp_match(segment, offset, bits, instruction, temp)) |
2135 | m = MOK_GOOD; |
2136 | else |
2137 | m = MERR_INVALOP; |
2138 | } |
2139 | if (m > merr) |
2140 | merr = m; |
2141 | if (merr == MOK_GOOD) |
2142 | goto done; |
2143 | } |
2144 | |
2145 | done: |
2146 | *tempp = temp; |
2147 | return merr; |
2148 | } |
2149 | |
2150 | static uint8_t get_broadcast_num(opflags_t opflags, opflags_t brsize) |
2151 | { |
2152 | unsigned int opsize = (opflags & SIZE_MASK) >> SIZE_SHIFT; |
2153 | uint8_t brcast_num; |
2154 | |
2155 | if (brsize > BITS64) |
2156 | nasm_error(ERR_FATAL, |
2157 | "size of broadcasting element is greater than 64 bits" ); |
2158 | |
2159 | /* |
2160 | * The shift term is to take care of the extra BITS80 inserted |
2161 | * between BITS64 and BITS128. |
2162 | */ |
2163 | brcast_num = ((opsize / (BITS64 >> SIZE_SHIFT)) * (BITS64 / brsize)) |
2164 | >> (opsize > (BITS64 >> SIZE_SHIFT)); |
2165 | |
2166 | return brcast_num; |
2167 | } |
2168 | |
2169 | static enum match_result matches(const struct itemplate *itemp, |
2170 | insn *instruction, int bits) |
2171 | { |
2172 | opflags_t size[MAX_OPERANDS], asize; |
2173 | bool opsizemissing = false; |
2174 | int i, oprs; |
2175 | |
2176 | /* |
2177 | * Check the opcode |
2178 | */ |
2179 | if (itemp->opcode != instruction->opcode) |
2180 | return MERR_INVALOP; |
2181 | |
2182 | /* |
2183 | * Count the operands |
2184 | */ |
2185 | if (itemp->operands != instruction->operands) |
2186 | return MERR_INVALOP; |
2187 | |
2188 | /* |
2189 | * Is it legal? |
2190 | */ |
2191 | if (!(optimizing.level > 0) && itemp_has(itemp, IF_OPT)) |
2192 | return MERR_INVALOP; |
2193 | |
2194 | /* |
2195 | * {evex} available? |
2196 | */ |
2197 | switch (instruction->prefixes[PPS_VEX]) { |
2198 | case P_EVEX: |
2199 | if (!itemp_has(itemp, IF_EVEX)) |
2200 | return MERR_ENCMISMATCH; |
2201 | break; |
2202 | case P_VEX3: |
2203 | case P_VEX2: |
2204 | if (!itemp_has(itemp, IF_VEX)) |
2205 | return MERR_ENCMISMATCH; |
2206 | break; |
2207 | default: |
2208 | break; |
2209 | } |
2210 | |
2211 | /* |
2212 | * Check that no spurious colons or TOs are present |
2213 | */ |
2214 | for (i = 0; i < itemp->operands; i++) |
2215 | if (instruction->oprs[i].type & ~itemp->opd[i] & (COLON | TO)) |
2216 | return MERR_INVALOP; |
2217 | |
2218 | /* |
2219 | * Process size flags |
2220 | */ |
2221 | switch (itemp_smask(itemp)) { |
2222 | case IF_GENBIT(IF_SB): |
2223 | asize = BITS8; |
2224 | break; |
2225 | case IF_GENBIT(IF_SW): |
2226 | asize = BITS16; |
2227 | break; |
2228 | case IF_GENBIT(IF_SD): |
2229 | asize = BITS32; |
2230 | break; |
2231 | case IF_GENBIT(IF_SQ): |
2232 | asize = BITS64; |
2233 | break; |
2234 | case IF_GENBIT(IF_SO): |
2235 | asize = BITS128; |
2236 | break; |
2237 | case IF_GENBIT(IF_SY): |
2238 | asize = BITS256; |
2239 | break; |
2240 | case IF_GENBIT(IF_SZ): |
2241 | asize = BITS512; |
2242 | break; |
2243 | case IF_GENBIT(IF_SIZE): |
2244 | switch (bits) { |
2245 | case 16: |
2246 | asize = BITS16; |
2247 | break; |
2248 | case 32: |
2249 | asize = BITS32; |
2250 | break; |
2251 | case 64: |
2252 | asize = BITS64; |
2253 | break; |
2254 | default: |
2255 | asize = 0; |
2256 | break; |
2257 | } |
2258 | break; |
2259 | default: |
2260 | asize = 0; |
2261 | break; |
2262 | } |
2263 | |
2264 | if (itemp_armask(itemp)) { |
2265 | /* S- flags only apply to a specific operand */ |
2266 | i = itemp_arg(itemp); |
2267 | memset(size, 0, sizeof size); |
2268 | size[i] = asize; |
2269 | } else { |
2270 | /* S- flags apply to all operands */ |
2271 | for (i = 0; i < MAX_OPERANDS; i++) |
2272 | size[i] = asize; |
2273 | } |
2274 | |
2275 | /* |
2276 | * Check that the operand flags all match up, |
2277 | * it's a bit tricky so lets be verbose: |
2278 | * |
2279 | * 1) Find out the size of operand. If instruction |
2280 | * doesn't have one specified -- we're trying to |
2281 | * guess it either from template (IF_S* flag) or |
2282 | * from code bits. |
2283 | * |
2284 | * 2) If template operand do not match the instruction OR |
2285 | * template has an operand size specified AND this size differ |
2286 | * from which instruction has (perhaps we got it from code bits) |
2287 | * we are: |
2288 | * a) Check that only size of instruction and operand is differ |
2289 | * other characteristics do match |
2290 | * b) Perhaps it's a register specified in instruction so |
2291 | * for such a case we just mark that operand as "size |
2292 | * missing" and this will turn on fuzzy operand size |
2293 | * logic facility (handled by a caller) |
2294 | */ |
2295 | for (i = 0; i < itemp->operands; i++) { |
2296 | opflags_t type = instruction->oprs[i].type; |
2297 | decoflags_t deco = instruction->oprs[i].decoflags; |
2298 | decoflags_t ideco = itemp->deco[i]; |
2299 | bool is_broadcast = deco & BRDCAST_MASK; |
2300 | uint8_t brcast_num = 0; |
2301 | opflags_t template_opsize, insn_opsize; |
2302 | |
2303 | if (!(type & SIZE_MASK)) |
2304 | type |= size[i]; |
2305 | |
2306 | insn_opsize = type & SIZE_MASK; |
2307 | if (!is_broadcast) { |
2308 | template_opsize = itemp->opd[i] & SIZE_MASK; |
2309 | } else { |
2310 | decoflags_t deco_brsize = ideco & BRSIZE_MASK; |
2311 | |
2312 | if (~ideco & BRDCAST_MASK) |
2313 | return MERR_BRNOTHERE; |
2314 | |
2315 | /* |
2316 | * when broadcasting, the element size depends on |
2317 | * the instruction type. decorator flag should match. |
2318 | */ |
2319 | if (deco_brsize) { |
2320 | template_opsize = (deco_brsize == BR_BITS32 ? BITS32 : BITS64); |
2321 | /* calculate the proper number : {1to<brcast_num>} */ |
2322 | brcast_num = get_broadcast_num(itemp->opd[i], template_opsize); |
2323 | } else { |
2324 | template_opsize = 0; |
2325 | } |
2326 | } |
2327 | |
2328 | if (~ideco & deco & OPMASK_MASK) |
2329 | return MERR_MASKNOTHERE; |
2330 | |
2331 | if (~ideco & deco & (Z_MASK|STATICRND_MASK|SAE_MASK)) |
2332 | return MERR_DECONOTHERE; |
2333 | |
2334 | if (itemp->opd[i] & ~type & ~(SIZE_MASK|REGSET_MASK)) |
2335 | return MERR_INVALOP; |
2336 | |
2337 | if (~itemp->opd[i] & type & REGSET_MASK) |
2338 | return (itemp->opd[i] & REGSET_MASK) |
2339 | ? MERR_REGSETSIZE : MERR_REGSET; |
2340 | |
2341 | if (template_opsize) { |
2342 | if (template_opsize != insn_opsize) { |
2343 | if (insn_opsize) { |
2344 | return MERR_INVALOP; |
2345 | } else if (!is_class(REGISTER, type)) { |
2346 | /* |
2347 | * Note: we don't honor extrinsic operand sizes for registers, |
2348 | * so "missing operand size" for a register should be |
2349 | * considered a wildcard match rather than an error. |
2350 | */ |
2351 | opsizemissing = true; |
2352 | } |
2353 | } else if (is_broadcast && |
2354 | (brcast_num != |
2355 | (2U << ((deco & BRNUM_MASK) >> BRNUM_SHIFT)))) { |
2356 | /* |
2357 | * broadcasting opsize matches but the number of repeated memory |
2358 | * element does not match. |
2359 | * if 64b double precision float is broadcasted to ymm (256b), |
2360 | * broadcasting decorator must be {1to4}. |
2361 | */ |
2362 | return MERR_BRNUMMISMATCH; |
2363 | } |
2364 | } |
2365 | } |
2366 | |
2367 | if (opsizemissing) |
2368 | return MERR_OPSIZEMISSING; |
2369 | |
2370 | /* |
2371 | * Check operand sizes |
2372 | */ |
2373 | if (itemp_has(itemp, IF_SM) || itemp_has(itemp, IF_SM2)) { |
2374 | oprs = (itemp_has(itemp, IF_SM2) ? 2 : itemp->operands); |
2375 | for (i = 0; i < oprs; i++) { |
2376 | asize = itemp->opd[i] & SIZE_MASK; |
2377 | if (asize) { |
2378 | for (i = 0; i < oprs; i++) |
2379 | size[i] = asize; |
2380 | break; |
2381 | } |
2382 | } |
2383 | } else { |
2384 | oprs = itemp->operands; |
2385 | } |
2386 | |
2387 | for (i = 0; i < itemp->operands; i++) { |
2388 | if (!(itemp->opd[i] & SIZE_MASK) && |
2389 | (instruction->oprs[i].type & SIZE_MASK & ~size[i])) |
2390 | return MERR_OPSIZEMISMATCH; |
2391 | } |
2392 | |
2393 | /* |
2394 | * Check template is okay at the set cpu level |
2395 | */ |
2396 | if (iflag_cmp_cpu_level(&insns_flags[itemp->iflag_idx], &cpu) > 0) |
2397 | return MERR_BADCPU; |
2398 | |
2399 | /* |
2400 | * Verify the appropriate long mode flag. |
2401 | */ |
2402 | if (itemp_has(itemp, (bits == 64 ? IF_NOLONG : IF_LONG))) |
2403 | return MERR_BADMODE; |
2404 | |
2405 | /* |
2406 | * If we have a HLE prefix, look for the NOHLE flag |
2407 | */ |
2408 | if (itemp_has(itemp, IF_NOHLE) && |
2409 | (has_prefix(instruction, PPS_REP, P_XACQUIRE) || |
2410 | has_prefix(instruction, PPS_REP, P_XRELEASE))) |
2411 | return MERR_BADHLE; |
2412 | |
2413 | /* |
2414 | * Check if special handling needed for Jumps |
2415 | */ |
2416 | if ((itemp->code[0] & ~1) == 0370) |
2417 | return MOK_JUMP; |
2418 | |
2419 | /* |
2420 | * Check if BND prefix is allowed. |
2421 | * Other 0xF2 (REPNE/REPNZ) prefix is prohibited. |
2422 | */ |
2423 | if (!itemp_has(itemp, IF_BND) && |
2424 | (has_prefix(instruction, PPS_REP, P_BND) || |
2425 | has_prefix(instruction, PPS_REP, P_NOBND))) |
2426 | return MERR_BADBND; |
2427 | else if (itemp_has(itemp, IF_BND) && |
2428 | (has_prefix(instruction, PPS_REP, P_REPNE) || |
2429 | has_prefix(instruction, PPS_REP, P_REPNZ))) |
2430 | return MERR_BADREPNE; |
2431 | |
2432 | return MOK_GOOD; |
2433 | } |
2434 | |
2435 | /* |
2436 | * Check if ModR/M.mod should/can be 01. |
2437 | * - EAF_BYTEOFFS is set |
2438 | * - offset can fit in a byte when EVEX is not used |
2439 | * - offset can be compressed when EVEX is used |
2440 | */ |
2441 | #define IS_MOD_01() (!(input->eaflags & EAF_WORDOFFS) && \ |
2442 | (ins->rex & REX_EV ? seg == NO_SEG && !forw_ref && \ |
2443 | is_disp8n(input, ins, &output->disp8) : \ |
2444 | input->eaflags & EAF_BYTEOFFS || (o >= -128 && \ |
2445 | o <= 127 && seg == NO_SEG && !forw_ref))) |
2446 | |
2447 | static enum ea_type process_ea(operand *input, ea *output, int bits, |
2448 | int rfield, opflags_t rflags, insn *ins, |
2449 | const char **errmsg) |
2450 | { |
2451 | bool forw_ref = !!(input->opflags & OPFLAG_UNKNOWN); |
2452 | int addrbits = ins->addr_size; |
2453 | int eaflags = input->eaflags; |
2454 | |
2455 | *errmsg = "invalid effective address" ; /* Default error message */ |
2456 | |
2457 | output->type = EA_SCALAR; |
2458 | output->rip = false; |
2459 | output->disp8 = 0; |
2460 | |
2461 | /* REX flags for the rfield operand */ |
2462 | output->rex |= rexflags(rfield, rflags, REX_R | REX_P | REX_W | REX_H); |
2463 | /* EVEX.R' flag for the REG operand */ |
2464 | ins->evex_p[0] |= evexflags(rfield, 0, EVEX_P0RP, 0); |
2465 | |
2466 | if (is_class(REGISTER, input->type)) { |
2467 | /* |
2468 | * It's a direct register. |
2469 | */ |
2470 | if (!is_register(input->basereg)) |
2471 | goto err; |
2472 | |
2473 | if (!is_reg_class(REG_EA, input->basereg)) |
2474 | goto err; |
2475 | |
2476 | /* broadcasting is not available with a direct register operand. */ |
2477 | if (input->decoflags & BRDCAST_MASK) { |
2478 | *errmsg = "broadcast not allowed with register operand" ; |
2479 | goto err; |
2480 | } |
2481 | |
2482 | output->rex |= op_rexflags(input, REX_B | REX_P | REX_W | REX_H); |
2483 | ins->evex_p[0] |= op_evexflags(input, EVEX_P0X, 0); |
2484 | output->sib_present = false; /* no SIB necessary */ |
2485 | output->bytes = 0; /* no offset necessary either */ |
2486 | output->modrm = GEN_MODRM(3, rfield, nasm_regvals[input->basereg]); |
2487 | } else { |
2488 | /* |
2489 | * It's a memory reference. |
2490 | */ |
2491 | |
2492 | /* Embedded rounding or SAE is not available with a mem ref operand. */ |
2493 | if (input->decoflags & (ER | SAE)) { |
2494 | *errmsg = "embedded rounding is available only with " |
2495 | "register-register operations" ; |
2496 | goto err; |
2497 | } |
2498 | |
2499 | if (input->basereg == -1 && |
2500 | (input->indexreg == -1 || input->scale == 0)) { |
2501 | /* |
2502 | * It's a pure offset. |
2503 | */ |
2504 | if (bits == 64 && ((input->type & IP_REL) == IP_REL)) { |
2505 | if (input->segment == NO_SEG || |
2506 | (input->opflags & OPFLAG_RELATIVE)) { |
2507 | nasm_error(ERR_WARNING | ERR_PASS2, |
2508 | "absolute address can not be RIP-relative" ); |
2509 | input->type &= ~IP_REL; |
2510 | input->type |= MEMORY; |
2511 | } |
2512 | } |
2513 | |
2514 | if (bits == 64 && |
2515 | !(IP_REL & ~input->type) && (eaflags & EAF_MIB)) { |
2516 | *errmsg = "RIP-relative addressing is prohibited for MIB" ; |
2517 | goto err; |
2518 | } |
2519 | |
2520 | if (eaflags & EAF_BYTEOFFS || |
2521 | (eaflags & EAF_WORDOFFS && |
2522 | input->disp_size != (addrbits != 16 ? 32 : 16))) { |
2523 | nasm_error(ERR_WARNING | ERR_PASS1, |
2524 | "displacement size ignored on absolute address" ); |
2525 | } |
2526 | |
2527 | if (bits == 64 && (~input->type & IP_REL)) { |
2528 | output->sib_present = true; |
2529 | output->sib = GEN_SIB(0, 4, 5); |
2530 | output->bytes = 4; |
2531 | output->modrm = GEN_MODRM(0, rfield, 4); |
2532 | output->rip = false; |
2533 | } else { |
2534 | output->sib_present = false; |
2535 | output->bytes = (addrbits != 16 ? 4 : 2); |
2536 | output->modrm = GEN_MODRM(0, rfield, |
2537 | (addrbits != 16 ? 5 : 6)); |
2538 | output->rip = bits == 64; |
2539 | } |
2540 | } else { |
2541 | /* |
2542 | * It's an indirection. |
2543 | */ |
2544 | int i = input->indexreg, b = input->basereg, s = input->scale; |
2545 | int32_t seg = input->segment; |
2546 | int hb = input->hintbase, ht = input->hinttype; |
2547 | int t, it, bt; /* register numbers */ |
2548 | opflags_t x, ix, bx; /* register flags */ |
2549 | |
2550 | if (s == 0) |
2551 | i = -1; /* make this easy, at least */ |
2552 | |
2553 | if (is_register(i)) { |
2554 | it = nasm_regvals[i]; |
2555 | ix = nasm_reg_flags[i]; |
2556 | } else { |
2557 | it = -1; |
2558 | ix = 0; |
2559 | } |
2560 | |
2561 | if (is_register(b)) { |
2562 | bt = nasm_regvals[b]; |
2563 | bx = nasm_reg_flags[b]; |
2564 | } else { |
2565 | bt = -1; |
2566 | bx = 0; |
2567 | } |
2568 | |
2569 | /* if either one are a vector register... */ |
2570 | if ((ix|bx) & (XMMREG|YMMREG|ZMMREG) & ~REG_EA) { |
2571 | opflags_t sok = BITS32 | BITS64; |
2572 | int32_t o = input->offset; |
2573 | int mod, scale, index, base; |
2574 | |
2575 | /* |
2576 | * For a vector SIB, one has to be a vector and the other, |
2577 | * if present, a GPR. The vector must be the index operand. |
2578 | */ |
2579 | if (it == -1 || (bx & (XMMREG|YMMREG|ZMMREG) & ~REG_EA)) { |
2580 | if (s == 0) |
2581 | s = 1; |
2582 | else if (s != 1) |
2583 | goto err; |
2584 | |
2585 | t = bt, bt = it, it = t; |
2586 | x = bx, bx = ix, ix = x; |
2587 | } |
2588 | |
2589 | if (bt != -1) { |
2590 | if (REG_GPR & ~bx) |
2591 | goto err; |
2592 | if (!(REG64 & ~bx) || !(REG32 & ~bx)) |
2593 | sok &= bx; |
2594 | else |
2595 | goto err; |
2596 | } |
2597 | |
2598 | /* |
2599 | * While we're here, ensure the user didn't specify |
2600 | * WORD or QWORD |
2601 | */ |
2602 | if (input->disp_size == 16 || input->disp_size == 64) |
2603 | goto err; |
2604 | |
2605 | if (addrbits == 16 || |
2606 | (addrbits == 32 && !(sok & BITS32)) || |
2607 | (addrbits == 64 && !(sok & BITS64))) |
2608 | goto err; |
2609 | |
2610 | output->type = ((ix & ZMMREG & ~REG_EA) ? EA_ZMMVSIB |
2611 | : ((ix & YMMREG & ~REG_EA) |
2612 | ? EA_YMMVSIB : EA_XMMVSIB)); |
2613 | |
2614 | output->rex |= rexflags(it, ix, REX_X); |
2615 | output->rex |= rexflags(bt, bx, REX_B); |
2616 | ins->evex_p[2] |= evexflags(it, 0, EVEX_P2VP, 2); |
2617 | |
2618 | index = it & 7; /* it is known to be != -1 */ |
2619 | |
2620 | switch (s) { |
2621 | case 1: |
2622 | scale = 0; |
2623 | break; |
2624 | case 2: |
2625 | scale = 1; |
2626 | break; |
2627 | case 4: |
2628 | scale = 2; |
2629 | break; |
2630 | case 8: |
2631 | scale = 3; |
2632 | break; |
2633 | default: /* then what the smeg is it? */ |
2634 | goto err; /* panic */ |
2635 | } |
2636 | |
2637 | if (bt == -1) { |
2638 | base = 5; |
2639 | mod = 0; |
2640 | } else { |
2641 | base = (bt & 7); |
2642 | if (base != REG_NUM_EBP && o == 0 && |
2643 | seg == NO_SEG && !forw_ref && |
2644 | !(eaflags & (EAF_BYTEOFFS | EAF_WORDOFFS))) |
2645 | mod = 0; |
2646 | else if (IS_MOD_01()) |
2647 | mod = 1; |
2648 | else |
2649 | mod = 2; |
2650 | } |
2651 | |
2652 | output->sib_present = true; |
2653 | output->bytes = (bt == -1 || mod == 2 ? 4 : mod); |
2654 | output->modrm = GEN_MODRM(mod, rfield, 4); |
2655 | output->sib = GEN_SIB(scale, index, base); |
2656 | } else if ((ix|bx) & (BITS32|BITS64)) { |
2657 | /* |
2658 | * it must be a 32/64-bit memory reference. Firstly we have |
2659 | * to check that all registers involved are type E/Rxx. |
2660 | */ |
2661 | opflags_t sok = BITS32 | BITS64; |
2662 | int32_t o = input->offset; |
2663 | |
2664 | if (it != -1) { |
2665 | if (!(REG64 & ~ix) || !(REG32 & ~ix)) |
2666 | sok &= ix; |
2667 | else |
2668 | goto err; |
2669 | } |
2670 | |
2671 | if (bt != -1) { |
2672 | if (REG_GPR & ~bx) |
2673 | goto err; /* Invalid register */ |
2674 | if (~sok & bx & SIZE_MASK) |
2675 | goto err; /* Invalid size */ |
2676 | sok &= bx; |
2677 | } |
2678 | |
2679 | /* |
2680 | * While we're here, ensure the user didn't specify |
2681 | * WORD or QWORD |
2682 | */ |
2683 | if (input->disp_size == 16 || input->disp_size == 64) |
2684 | goto err; |
2685 | |
2686 | if (addrbits == 16 || |
2687 | (addrbits == 32 && !(sok & BITS32)) || |
2688 | (addrbits == 64 && !(sok & BITS64))) |
2689 | goto err; |
2690 | |
2691 | /* now reorganize base/index */ |
2692 | if (s == 1 && bt != it && bt != -1 && it != -1 && |
2693 | ((hb == b && ht == EAH_NOTBASE) || |
2694 | (hb == i && ht == EAH_MAKEBASE))) { |
2695 | /* swap if hints say so */ |
2696 | t = bt, bt = it, it = t; |
2697 | x = bx, bx = ix, ix = x; |
2698 | } |
2699 | |
2700 | if (bt == -1 && s == 1 && !(hb == i && ht == EAH_NOTBASE)) { |
2701 | /* make single reg base, unless hint */ |
2702 | bt = it, bx = ix, it = -1, ix = 0; |
2703 | } |
2704 | if (eaflags & EAF_MIB) { |
2705 | /* only for mib operands */ |
2706 | if (it == -1 && (hb == b && ht == EAH_NOTBASE)) { |
2707 | /* |
2708 | * make a single reg index [reg*1]. |
2709 | * gas uses this form for an explicit index register. |
2710 | */ |
2711 | it = bt, ix = bx, bt = -1, bx = 0, s = 1; |
2712 | } |
2713 | if ((ht == EAH_SUMMED) && bt == -1) { |
2714 | /* separate once summed index into [base, index] */ |
2715 | bt = it, bx = ix, s--; |
2716 | } |
2717 | } else { |
2718 | if (((s == 2 && it != REG_NUM_ESP && |
2719 | (!(eaflags & EAF_TIMESTWO) || (ht == EAH_SUMMED))) || |
2720 | s == 3 || s == 5 || s == 9) && bt == -1) { |
2721 | /* convert 3*EAX to EAX+2*EAX */ |
2722 | bt = it, bx = ix, s--; |
2723 | } |
2724 | if (it == -1 && (bt & 7) != REG_NUM_ESP && |
2725 | (eaflags & EAF_TIMESTWO) && |
2726 | (hb == b && ht == EAH_NOTBASE)) { |
2727 | /* |
2728 | * convert [NOSPLIT EAX*1] |
2729 | * to sib format with 0x0 displacement - [EAX*1+0]. |
2730 | */ |
2731 | it = bt, ix = bx, bt = -1, bx = 0, s = 1; |
2732 | } |
2733 | } |
2734 | if (s == 1 && it == REG_NUM_ESP) { |
2735 | /* swap ESP into base if scale is 1 */ |
2736 | t = it, it = bt, bt = t; |
2737 | x = ix, ix = bx, bx = x; |
2738 | } |
2739 | if (it == REG_NUM_ESP || |
2740 | (s != 1 && s != 2 && s != 4 && s != 8 && it != -1)) |
2741 | goto err; /* wrong, for various reasons */ |
2742 | |
2743 | output->rex |= rexflags(it, ix, REX_X); |
2744 | output->rex |= rexflags(bt, bx, REX_B); |
2745 | |
2746 | if (it == -1 && (bt & 7) != REG_NUM_ESP) { |
2747 | /* no SIB needed */ |
2748 | int mod, rm; |
2749 | |
2750 | if (bt == -1) { |
2751 | rm = 5; |
2752 | mod = 0; |
2753 | } else { |
2754 | rm = (bt & 7); |
2755 | if (rm != REG_NUM_EBP && o == 0 && |
2756 | seg == NO_SEG && !forw_ref && |
2757 | !(eaflags & (EAF_BYTEOFFS | EAF_WORDOFFS))) |
2758 | mod = 0; |
2759 | else if (IS_MOD_01()) |
2760 | mod = 1; |
2761 | else |
2762 | mod = 2; |
2763 | } |
2764 | |
2765 | output->sib_present = false; |
2766 | output->bytes = (bt == -1 || mod == 2 ? 4 : mod); |
2767 | output->modrm = GEN_MODRM(mod, rfield, rm); |
2768 | } else { |
2769 | /* we need a SIB */ |
2770 | int mod, scale, index, base; |
2771 | |
2772 | if (it == -1) |
2773 | index = 4, s = 1; |
2774 | else |
2775 | index = (it & 7); |
2776 | |
2777 | switch (s) { |
2778 | case 1: |
2779 | scale = 0; |
2780 | break; |
2781 | case 2: |
2782 | scale = 1; |
2783 | break; |
2784 | case 4: |
2785 | scale = 2; |
2786 | break; |
2787 | case 8: |
2788 | scale = 3; |
2789 | break; |
2790 | default: /* then what the smeg is it? */ |
2791 | goto err; /* panic */ |
2792 | } |
2793 | |
2794 | if (bt == -1) { |
2795 | base = 5; |
2796 | mod = 0; |
2797 | } else { |
2798 | base = (bt & 7); |
2799 | if (base != REG_NUM_EBP && o == 0 && |
2800 | seg == NO_SEG && !forw_ref && |
2801 | !(eaflags & (EAF_BYTEOFFS | EAF_WORDOFFS))) |
2802 | mod = 0; |
2803 | else if (IS_MOD_01()) |
2804 | mod = 1; |
2805 | else |
2806 | mod = 2; |
2807 | } |
2808 | |
2809 | output->sib_present = true; |
2810 | output->bytes = (bt == -1 || mod == 2 ? 4 : mod); |
2811 | output->modrm = GEN_MODRM(mod, rfield, 4); |
2812 | output->sib = GEN_SIB(scale, index, base); |
2813 | } |
2814 | } else { /* it's 16-bit */ |
2815 | int mod, rm; |
2816 | int16_t o = input->offset; |
2817 | |
2818 | /* check for 64-bit long mode */ |
2819 | if (addrbits == 64) |
2820 | goto err; |
2821 | |
2822 | /* check all registers are BX, BP, SI or DI */ |
2823 | if ((b != -1 && b != R_BP && b != R_BX && b != R_SI && b != R_DI) || |
2824 | (i != -1 && i != R_BP && i != R_BX && i != R_SI && i != R_DI)) |
2825 | goto err; |
2826 | |
2827 | /* ensure the user didn't specify DWORD/QWORD */ |
2828 | if (input->disp_size == 32 || input->disp_size == 64) |
2829 | goto err; |
2830 | |
2831 | if (s != 1 && i != -1) |
2832 | goto err; /* no can do, in 16-bit EA */ |
2833 | if (b == -1 && i != -1) { |
2834 | int tmp = b; |
2835 | b = i; |
2836 | i = tmp; |
2837 | } /* swap */ |
2838 | if ((b == R_SI || b == R_DI) && i != -1) { |
2839 | int tmp = b; |
2840 | b = i; |
2841 | i = tmp; |
2842 | } |
2843 | /* have BX/BP as base, SI/DI index */ |
2844 | if (b == i) |
2845 | goto err; /* shouldn't ever happen, in theory */ |
2846 | if (i != -1 && b != -1 && |
2847 | (i == R_BP || i == R_BX || b == R_SI || b == R_DI)) |
2848 | goto err; /* invalid combinations */ |
2849 | if (b == -1) /* pure offset: handled above */ |
2850 | goto err; /* so if it gets to here, panic! */ |
2851 | |
2852 | rm = -1; |
2853 | if (i != -1) |
2854 | switch (i * 256 + b) { |
2855 | case R_SI * 256 + R_BX: |
2856 | rm = 0; |
2857 | break; |
2858 | case R_DI * 256 + R_BX: |
2859 | rm = 1; |
2860 | break; |
2861 | case R_SI * 256 + R_BP: |
2862 | rm = 2; |
2863 | break; |
2864 | case R_DI * 256 + R_BP: |
2865 | rm = 3; |
2866 | break; |
2867 | } else |
2868 | switch (b) { |
2869 | case R_SI: |
2870 | rm = 4; |
2871 | break; |
2872 | case R_DI: |
2873 | rm = 5; |
2874 | break; |
2875 | case R_BP: |
2876 | rm = 6; |
2877 | break; |
2878 | case R_BX: |
2879 | rm = 7; |
2880 | break; |
2881 | } |
2882 | if (rm == -1) /* can't happen, in theory */ |
2883 | goto err; /* so panic if it does */ |
2884 | |
2885 | if (o == 0 && seg == NO_SEG && !forw_ref && rm != 6 && |
2886 | !(eaflags & (EAF_BYTEOFFS | EAF_WORDOFFS))) |
2887 | mod = 0; |
2888 | else if (IS_MOD_01()) |
2889 | mod = 1; |
2890 | else |
2891 | mod = 2; |
2892 | |
2893 | output->sib_present = false; /* no SIB - it's 16-bit */ |
2894 | output->bytes = mod; /* bytes of offset needed */ |
2895 | output->modrm = GEN_MODRM(mod, rfield, rm); |
2896 | } |
2897 | } |
2898 | } |
2899 | |
2900 | output->size = 1 + output->sib_present + output->bytes; |
2901 | return output->type; |
2902 | |
2903 | err: |
2904 | return output->type = EA_INVALID; |
2905 | } |
2906 | |
2907 | static void add_asp(insn *ins, int addrbits) |
2908 | { |
2909 | int j, valid; |
2910 | int defdisp; |
2911 | |
2912 | valid = (addrbits == 64) ? 64|32 : 32|16; |
2913 | |
2914 | switch (ins->prefixes[PPS_ASIZE]) { |
2915 | case P_A16: |
2916 | valid &= 16; |
2917 | break; |
2918 | case P_A32: |
2919 | valid &= 32; |
2920 | break; |
2921 | case P_A64: |
2922 | valid &= 64; |
2923 | break; |
2924 | case P_ASP: |
2925 | valid &= (addrbits == 32) ? 16 : 32; |
2926 | break; |
2927 | default: |
2928 | break; |
2929 | } |
2930 | |
2931 | for (j = 0; j < ins->operands; j++) { |
2932 | if (is_class(MEMORY, ins->oprs[j].type)) { |
2933 | opflags_t i, b; |
2934 | |
2935 | /* Verify as Register */ |
2936 | if (!is_register(ins->oprs[j].indexreg)) |
2937 | i = 0; |
2938 | else |
2939 | i = nasm_reg_flags[ins->oprs[j].indexreg]; |
2940 | |
2941 | /* Verify as Register */ |
2942 | if (!is_register(ins->oprs[j].basereg)) |
2943 | b = 0; |
2944 | else |
2945 | b = nasm_reg_flags[ins->oprs[j].basereg]; |
2946 | |
2947 | if (ins->oprs[j].scale == 0) |
2948 | i = 0; |
2949 | |
2950 | if (!i && !b) { |
2951 | int ds = ins->oprs[j].disp_size; |
2952 | if ((addrbits != 64 && ds > 8) || |
2953 | (addrbits == 64 && ds == 16)) |
2954 | valid &= ds; |
2955 | } else { |
2956 | if (!(REG16 & ~b)) |
2957 | valid &= 16; |
2958 | if (!(REG32 & ~b)) |
2959 | valid &= 32; |
2960 | if (!(REG64 & ~b)) |
2961 | valid &= 64; |
2962 | |
2963 | if (!(REG16 & ~i)) |
2964 | valid &= 16; |
2965 | if (!(REG32 & ~i)) |
2966 | valid &= 32; |
2967 | if (!(REG64 & ~i)) |
2968 | valid &= 64; |
2969 | } |
2970 | } |
2971 | } |
2972 | |
2973 | if (valid & addrbits) { |
2974 | ins->addr_size = addrbits; |
2975 | } else if (valid & ((addrbits == 32) ? 16 : 32)) { |
2976 | /* Add an address size prefix */ |
2977 | ins->prefixes[PPS_ASIZE] = (addrbits == 32) ? P_A16 : P_A32;; |
2978 | ins->addr_size = (addrbits == 32) ? 16 : 32; |
2979 | } else { |
2980 | /* Impossible... */ |
2981 | nasm_error(ERR_NONFATAL, "impossible combination of address sizes" ); |
2982 | ins->addr_size = addrbits; /* Error recovery */ |
2983 | } |
2984 | |
2985 | defdisp = ins->addr_size == 16 ? 16 : 32; |
2986 | |
2987 | for (j = 0; j < ins->operands; j++) { |
2988 | if (!(MEM_OFFS & ~ins->oprs[j].type) && |
2989 | (ins->oprs[j].disp_size ? ins->oprs[j].disp_size : defdisp) != ins->addr_size) { |
2990 | /* |
2991 | * mem_offs sizes must match the address size; if not, |
2992 | * strip the MEM_OFFS bit and match only EA instructions |
2993 | */ |
2994 | ins->oprs[j].type &= ~(MEM_OFFS & ~MEMORY); |
2995 | } |
2996 | } |
2997 | } |
2998 | |