1 /*
2 * x86 identifier recognition and instruction handling
3 *
4 * Copyright (C) 2002-2007 Peter Johnson
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27 #include <ctype.h>
28 #include <util.h>
29
30 #include <libyasm.h>
31 #include <libyasm/phash.h>
32
33 #include "modules/arch/x86/x86arch.h"
34
35
36 static const char *cpu_find_reverse(unsigned int cpu0, unsigned int cpu1,
37 unsigned int cpu2);
38
39 /* Opcode modifiers. */
40 #define MOD_Gap 0 /* Eats a parameter / does nothing */
41 #define MOD_PreAdd 1 /* Parameter adds to "special" prefix */
42 #define MOD_Op0Add 2 /* Parameter adds to opcode byte 0 */
43 #define MOD_Op1Add 3 /* Parameter adds to opcode byte 1 */
44 #define MOD_Op2Add 4 /* Parameter adds to opcode byte 2 */
45 #define MOD_SpAdd 5 /* Parameter adds to "spare" value */
46 #define MOD_OpSizeR 6 /* Parameter replaces opersize */
47 #define MOD_Imm8 7 /* Parameter is included as immediate byte */
48 #define MOD_AdSizeR 8 /* Parameter replaces addrsize (jmp only) */
49 #define MOD_DOpS64R 9 /* Parameter replaces default 64-bit opersize */
50 #define MOD_Op1AddSp 10 /* Parameter is added as "spare" to opcode byte 2 */
51 #define MOD_SetVEX 11 /* Parameter replaces internal VEX prefix value */
52
53 /* GAS suffix flags for instructions */
54 enum x86_gas_suffix_flags {
55 SUF_Z = 1<<0, /* no suffix */
56 SUF_B = 1<<1,
57 SUF_W = 1<<2,
58 SUF_L = 1<<3,
59 SUF_Q = 1<<4,
60 SUF_S = 1<<5,
61 SUF_MASK = SUF_Z|SUF_B|SUF_W|SUF_L|SUF_Q|SUF_S,
62
63 /* Flags only used in x86_insn_info */
64 GAS_ONLY = 1<<6, /* Only available in GAS mode */
65 GAS_ILLEGAL = 1<<7, /* Illegal in GAS mode */
66 GAS_NO_REV = 1<<8 /* Don't reverse operands in GAS mode */
67 };
68
69 /* Miscellaneous flag tests for instructions */
70 enum x86_misc_flags {
71 /* These are tested against BITS==64. */
72 ONLY_64 = 1<<0, /* Only available in 64-bit mode */
73 NOT_64 = 1<<1, /* Not available (invalid) in 64-bit mode */
74 /* These are tested against whether the base instruction is an AVX one. */
75 ONLY_AVX = 1<<2, /* Only available in AVX instruction */
76 NOT_AVX = 1<<3 /* Not available (invalid) in AVX instruction */
77 };
78
79 enum x86_operand_type {
80 OPT_Imm = 0, /* immediate */
81 OPT_Reg = 1, /* any general purpose or FPU register */
82 OPT_Mem = 2, /* memory */
83 OPT_RM = 3, /* any general purpose or FPU register OR memory */
84 OPT_SIMDReg = 4, /* any MMX or XMM register */
85 OPT_SIMDRM = 5, /* any MMX or XMM register OR memory */
86 OPT_SegReg = 6, /* any segment register */
87 OPT_CRReg = 7, /* any CR register */
88 OPT_DRReg = 8, /* any DR register */
89 OPT_TRReg = 9, /* any TR register */
90 OPT_ST0 = 10, /* ST0 */
91 OPT_Areg = 11, /* AL/AX/EAX/RAX (depending on size) */
92 OPT_Creg = 12, /* CL/CX/ECX/RCX (depending on size) */
93 OPT_Dreg = 13, /* DL/DX/EDX/RDX (depending on size) */
94 OPT_CS = 14, /* CS */
95 OPT_DS = 15, /* DS */
96 OPT_ES = 16, /* ES */
97 OPT_FS = 17, /* FS */
98 OPT_GS = 18, /* GS */
99 OPT_SS = 19, /* SS */
100 OPT_CR4 = 20, /* CR4 */
101 /* memory offset (an EA, but with no registers allowed)
102 * [special case for MOV opcode]
103 */
104 OPT_MemOffs = 21,
105 OPT_Imm1 = 22, /* immediate, value=1 (for special-case shift) */
106 /* immediate, does not contain SEG:OFF (for jmp/call) */
107 OPT_ImmNotSegOff = 23,
108 OPT_XMM0 = 24, /* XMM0 */
109 /* AX/EAX/RAX memory operand only (EA) [special case for SVM opcodes]
110 */
111 OPT_MemrAX = 25,
112 /* EAX memory operand only (EA) [special case for SVM skinit opcode] */
113 OPT_MemEAX = 26,
114 /* XMM VSIB memory operand */
115 OPT_MemXMMIndex = 27,
116 /* YMM VSIB memory operand */
117 OPT_MemYMMIndex = 28
118 };
119
120 enum x86_operand_size {
121 /* any size acceptable/no size spec acceptable (dep. on strict) */
122 OPS_Any = 0,
123 /* 8/16/32/64/80/128/256 bits (from user or reg size) */
124 OPS_8 = 1,
125 OPS_16 = 2,
126 OPS_32 = 3,
127 OPS_64 = 4,
128 OPS_80 = 5,
129 OPS_128 = 6,
130 OPS_256 = 7,
131 /* current BITS setting; when this is used the size matched
132 * gets stored into the opersize as well.
133 */
134 OPS_BITS = 8
135 };
136
137 enum x86_operand_targetmod {
138 OPTM_None = 0, /* no target mod acceptable */
139 OPTM_Near = 1, /* NEAR */
140 OPTM_Short = 2, /* SHORT */
141 OPTM_Far = 3, /* FAR (or SEG:OFF immediate) */
142 OPTM_To = 4 /* TO */
143 };
144
145 enum x86_operand_action {
146 OPA_None = 0, /* does nothing (operand data is discarded) */
147 OPA_EA = 1, /* operand data goes into ea field */
148 OPA_Imm = 2, /* operand data goes into imm field */
149 OPA_SImm = 3, /* operand data goes into sign-extended imm field */
150 OPA_Spare = 4, /* operand data goes into "spare" field */
151 OPA_Op0Add = 5, /* operand data is added to opcode byte 0 */
152 OPA_Op1Add = 6, /* operand data is added to opcode byte 1 */
153 /* operand data goes into BOTH ea and spare
154 * (special case for imul opcode)
155 */
156 OPA_SpareEA = 7,
157 /* relative jump (outputs a jmp instead of normal insn) */
158 OPA_JmpRel = 8,
159 /* operand size goes into address size (jmp only) */
160 OPA_AdSizeR = 9,
161 /* far jump (outputs a farjmp instead of normal insn) */
162 OPA_JmpFar = 10,
163 /* ea operand only sets address size (no actual ea field) */
164 OPA_AdSizeEA = 11,
165 OPA_VEX = 12, /* operand data goes into VEX/XOP "vvvv" field */
166 /* operand data goes into BOTH VEX/XOP "vvvv" field and ea field */
167 OPA_EAVEX = 13,
168 /* operand data goes into BOTH VEX/XOP "vvvv" field and spare field */
169 OPA_SpareVEX = 14,
170 /* operand data goes into upper 4 bits of immediate byte (VEX is4 field) */
171 OPA_VEXImmSrc = 15,
172 /* operand data goes into bottom 4 bits of immediate byte
173 * (currently only VEX imz2 field)
174 */
175 OPA_VEXImm = 16
176 };
177
178 enum x86_operand_post_action {
179 OPAP_None = 0,
180 /* sign-extended imm8 that could expand to a large imm16/32 */
181 OPAP_SImm8 = 1,
182 /* could become a short opcode mov with bits=64 and a32 prefix */
183 OPAP_ShortMov = 2,
184 /* forced 16-bit address size (override ignored, no prefix) */
185 OPAP_A16 = 3,
186 /* large imm64 that can become a sign-extended imm32 */
187 OPAP_SImm32Avail = 4
188 };
189
190 typedef struct x86_info_operand {
191 /* Operand types. These are more detailed than the "general" types for all
192 * architectures, as they include the size, for instance.
193 */
194
195 /* general type (must be exact match, except for RM types): */
196 unsigned int type:5;
197
198 /* size (user-specified, or from register size) */
199 unsigned int size:4;
200
201 /* size implicit or explicit ("strictness" of size matching on
202 * non-registers -- registers are always strictly matched):
203 * 0 = user size must exactly match size above.
204 * 1 = user size either unspecified or exactly match size above.
205 */
206 unsigned int relaxed:1;
207
208 /* effective address size
209 * 0 = any address size allowed except for 64-bit
210 * 1 = only 64-bit address size allowed
211 */
212 unsigned int eas64:1;
213
214 /* target modification */
215 unsigned int targetmod:3;
216
217 /* Actions: what to do with the operand if the instruction matches.
218 * Essentially describes what part of the output bytecode gets the
219 * operand. This may require conversion (e.g. a register going into
220 * an ea field). Naturally, only one of each of these may be contained
221 * in the operands of a single insn_info structure.
222 */
223 unsigned int action:5;
224
225 /* Postponed actions: actions which can't be completed at
226 * parse-time due to possibly dependent expressions. For these, some
227 * additional data (stored in the second byte of the opcode with a
228 * one-byte opcode) is passed to later stages of the assembler with
229 * flags set to indicate postponed actions.
230 */
231 unsigned int post_action:3;
232 } x86_info_operand;
233
234 typedef struct x86_insn_info {
235 /* GAS suffix flags */
236 unsigned int gas_flags:9; /* Enabled for these GAS suffixes */
237
238 /* Tests against BITS==64, AVX, and XOP */
239 unsigned int misc_flags:5;
240
241 /* The CPU feature flags needed to execute this instruction. This is OR'ed
242 * with arch-specific data[2]. This combined value is compared with
243 * cpu_enabled to see if all bits set here are set in cpu_enabled--if so,
244 * the instruction is available on this CPU.
245 */
246 unsigned int cpu0:6;
247 unsigned int cpu1:6;
248 unsigned int cpu2:6;
249
250 /* Opcode modifiers for variations of instruction. As each modifier reads
251 * its parameter in LSB->MSB order from the arch-specific data[1] from the
252 * lexer data, and the LSB of the arch-specific data[1] is reserved for the
253 * count of insn_info structures in the instruction grouping, there can
254 * only be a maximum of 3 modifiers.
255 */
256 unsigned char modifiers[3];
257
258 /* Operand Size */
259 unsigned char opersize;
260
261 /* Default operand size in 64-bit mode (0 = 32-bit for readability). */
262 unsigned char def_opersize_64;
263
264 /* A special instruction prefix, used for some of the Intel SSE and SSE2
265 * instructions. Intel calls these 3-byte opcodes, but in AMD64's 64-bit
266 * mode, they're treated like normal prefixes (e.g. the REX prefix needs
267 * to be *after* the F2/F3/66 "prefix").
268 * (0=no special prefix)
269 * 0xC0 - 0xCF indicate a VEX prefix, with the four LSBs holding "WLpp":
270 * W: VEX.W field (meaning depends on opcode)
271 * L: 0=128-bit, 1=256-bit
272 * pp: SIMD prefix designation:
273 * 00: None
274 * 01: 66
275 * 10: F3
276 * 11: F2
277 * 0x80 - 0x8F indicate a XOP prefix, with the four LSBs holding "WLpp":
278 * same meanings as VEX prefix.
279 */
280 unsigned char special_prefix;
281
282 /* The length of the basic opcode */
283 unsigned char opcode_len;
284
285 /* The basic 1-3 byte opcode (not including the special instruction
286 * prefix).
287 */
288 unsigned char opcode[3];
289
290 /* The 3-bit "spare" value (extended opcode) for the R/M byte field */
291 unsigned char spare;
292
293 /* The number of operands this form of the instruction takes */
294 unsigned int num_operands:4;
295
296 /* The index into the insn_operands array which contains the type of each
297 * operand, see above
298 */
299 unsigned int operands_index:12;
300 } x86_insn_info;
301
302 typedef struct x86_id_insn {
303 yasm_insn insn; /* base structure */
304
305 /* instruction parse group - NULL if empty instruction (just prefixes) */
306 /*@null@*/ const x86_insn_info *group;
307
308 /* CPU feature flags enabled at the time of parsing the instruction */
309 wordptr cpu_enabled;
310
311 /* Modifier data */
312 unsigned char mod_data[3];
313
314 /* Number of elements in the instruction parse group */
315 unsigned int num_info:8;
316
317 /* BITS setting active at the time of parsing the instruction */
318 unsigned int mode_bits:8;
319
320 /* Suffix flags */
321 unsigned int suffix:9;
322
323 /* Tests against BITS==64 and AVX */
324 unsigned int misc_flags:5;
325
326 /* Parser enabled at the time of parsing the instruction */
327 unsigned int parser:2;
328
329 /* Strict forced setting at the time of parsing the instruction */
330 unsigned int force_strict:1;
331
332 /* Default rel setting at the time of parsing the instruction */
333 unsigned int default_rel:1;
334 } x86_id_insn;
335
336 static void x86_id_insn_destroy(void *contents);
337 static void x86_id_insn_print(const void *contents, FILE *f, int indent_level);
338 static void x86_id_insn_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
339
340 static const yasm_bytecode_callback x86_id_insn_callback = {
341 x86_id_insn_destroy,
342 x86_id_insn_print,
343 x86_id_insn_finalize,
344 NULL,
345 yasm_bc_calc_len_common,
346 yasm_bc_expand_common,
347 yasm_bc_tobytes_common,
348 YASM_BC_SPECIAL_INSN
349 };
350
351 #include "x86insns.c"
352
353 /* Looks for the first SIMD register match for the purposes of VSIB matching.
354 * Full legality checking is performed in EA code.
355 */
356 static int
x86_expr_contains_simd_cb(const yasm_expr__item * ei,void * d)357 x86_expr_contains_simd_cb(const yasm_expr__item *ei, void *d)
358 {
359 int ymm = *((int *)d);
360 if (ei->type != YASM_EXPR_REG)
361 return 0;
362 switch ((x86_expritem_reg_size)(ei->data.reg & ~0xFUL)) {
363 case X86_XMMREG:
364 if (!ymm)
365 return 1;
366 break;
367 case X86_YMMREG:
368 if (ymm)
369 return 1;
370 break;
371 default:
372 break;
373 }
374 return 0;
375 }
376
377 static int
x86_expr_contains_simd(const yasm_expr * e,int ymm)378 x86_expr_contains_simd(const yasm_expr *e, int ymm)
379 {
380 return yasm_expr__traverse_leaves_in_const(e, &ymm,
381 x86_expr_contains_simd_cb);
382 }
383
384 static void
x86_finalize_common(x86_common * common,const x86_insn_info * info,unsigned int mode_bits)385 x86_finalize_common(x86_common *common, const x86_insn_info *info,
386 unsigned int mode_bits)
387 {
388 common->addrsize = 0;
389 common->opersize = info->opersize;
390 common->lockrep_pre = 0;
391 common->mode_bits = (unsigned char)mode_bits;
392 }
393
394 static void
x86_finalize_opcode(x86_opcode * opcode,const x86_insn_info * info)395 x86_finalize_opcode(x86_opcode *opcode, const x86_insn_info *info)
396 {
397 opcode->len = info->opcode_len;
398 opcode->opcode[0] = info->opcode[0];
399 opcode->opcode[1] = info->opcode[1];
400 opcode->opcode[2] = info->opcode[2];
401 }
402
403 /* Clear operands so they don't get destroyed after we've copied references. */
404 static void
x86_id_insn_clear_operands(x86_id_insn * id_insn)405 x86_id_insn_clear_operands(x86_id_insn *id_insn)
406 {
407 yasm_insn_operand *op = yasm_insn_ops_first(&id_insn->insn);
408 while (op) {
409 op->type = YASM_INSN__OPERAND_REG;
410 op = yasm_insn_op_next(op);
411 }
412 }
413
414 static void
x86_finalize_jmpfar(yasm_bytecode * bc,yasm_bytecode * prev_bc,const x86_insn_info * info)415 x86_finalize_jmpfar(yasm_bytecode *bc, yasm_bytecode *prev_bc,
416 const x86_insn_info *info)
417 {
418 x86_id_insn *id_insn = (x86_id_insn *)bc->contents;
419 unsigned char *mod_data = id_insn->mod_data;
420 unsigned int mode_bits = id_insn->mode_bits;
421 x86_jmpfar *jmpfar;
422 yasm_insn_operand *op;
423 unsigned int i;
424
425 jmpfar = yasm_xmalloc(sizeof(x86_jmpfar));
426 x86_finalize_common(&jmpfar->common, info, mode_bits);
427 x86_finalize_opcode(&jmpfar->opcode, info);
428
429 op = yasm_insn_ops_first(&id_insn->insn);
430
431 if (op->type == YASM_INSN__OPERAND_IMM && op->seg) {
432 /* SEG:OFF */
433 if (yasm_value_finalize_expr(&jmpfar->segment, op->seg, prev_bc, 16))
434 yasm_error_set(YASM_ERROR_TOO_COMPLEX,
435 N_("jump target segment too complex"));
436 if (yasm_value_finalize_expr(&jmpfar->offset, op->data.val, prev_bc,
437 0))
438 yasm_error_set(YASM_ERROR_TOO_COMPLEX,
439 N_("jump target offset too complex"));
440 } else if (op->targetmod == X86_FAR) {
441 /* "FAR imm" target needs to become "seg imm:imm". */
442 yasm_expr *e = yasm_expr_create_branch(YASM_EXPR_SEG,
443 yasm_expr_copy(op->data.val),
444 op->data.val->line);
445 if (yasm_value_finalize_expr(&jmpfar->offset, op->data.val, prev_bc, 0)
446 || yasm_value_finalize_expr(&jmpfar->segment, e, prev_bc, 16))
447 yasm_error_set(YASM_ERROR_TOO_COMPLEX,
448 N_("jump target expression too complex"));
449 } else if (yasm_insn_op_next(op)) {
450 /* Two operand form (gas) */
451 yasm_insn_operand *op2 = yasm_insn_op_next(op);
452 if (yasm_value_finalize_expr(&jmpfar->segment, op->data.val, prev_bc,
453 16))
454 yasm_error_set(YASM_ERROR_TOO_COMPLEX,
455 N_("jump target segment too complex"));
456 if (yasm_value_finalize_expr(&jmpfar->offset, op2->data.val, prev_bc,
457 0))
458 yasm_error_set(YASM_ERROR_TOO_COMPLEX,
459 N_("jump target offset too complex"));
460 if (op2->size == OPS_BITS)
461 jmpfar->common.opersize = (unsigned char)mode_bits;
462 } else
463 yasm_internal_error(N_("didn't get FAR expression in jmpfar"));
464
465 /* Apply modifiers */
466 for (i=0; i<NELEMS(info->modifiers); i++) {
467 switch (info->modifiers[i]) {
468 case MOD_Gap:
469 break;
470 case MOD_Op0Add:
471 jmpfar->opcode.opcode[0] += mod_data[i];
472 break;
473 case MOD_Op1Add:
474 jmpfar->opcode.opcode[1] += mod_data[i];
475 break;
476 case MOD_Op2Add:
477 jmpfar->opcode.opcode[2] += mod_data[i];
478 break;
479 case MOD_Op1AddSp:
480 jmpfar->opcode.opcode[1] += mod_data[i]<<3;
481 break;
482 default:
483 break;
484 }
485 }
486
487 yasm_x86__bc_apply_prefixes((x86_common *)jmpfar, NULL,
488 info->def_opersize_64,
489 id_insn->insn.num_prefixes,
490 id_insn->insn.prefixes);
491
492 x86_id_insn_clear_operands(id_insn);
493
494 /* Transform the bytecode */
495 yasm_x86__bc_transform_jmpfar(bc, jmpfar);
496 }
497
498 static void
x86_finalize_jmp(yasm_bytecode * bc,yasm_bytecode * prev_bc,const x86_insn_info * jinfo)499 x86_finalize_jmp(yasm_bytecode *bc, yasm_bytecode *prev_bc,
500 const x86_insn_info *jinfo)
501 {
502 x86_id_insn *id_insn = (x86_id_insn *)bc->contents;
503 x86_jmp *jmp;
504 int num_info = id_insn->num_info;
505 const x86_insn_info *info = id_insn->group;
506 unsigned char *mod_data = id_insn->mod_data;
507 unsigned int mode_bits = id_insn->mode_bits;
508 /*unsigned char suffix = id_insn->suffix;*/
509 yasm_insn_operand *op;
510 static const unsigned char size_lookup[] =
511 {0, 8, 16, 32, 64, 80, 128, 0, 0}; /* 256 not needed */
512 unsigned int i;
513
514 /* We know the target is in operand 0, but sanity check for Imm. */
515 op = yasm_insn_ops_first(&id_insn->insn);
516 if (op->type != YASM_INSN__OPERAND_IMM)
517 yasm_internal_error(N_("invalid operand conversion"));
518
519 jmp = yasm_xmalloc(sizeof(x86_jmp));
520 x86_finalize_common(&jmp->common, jinfo, mode_bits);
521 if (yasm_value_finalize_expr(&jmp->target, op->data.val, prev_bc, 0))
522 yasm_error_set(YASM_ERROR_TOO_COMPLEX,
523 N_("jump target expression too complex"));
524 if (jmp->target.seg_of || jmp->target.rshift || jmp->target.curpos_rel)
525 yasm_error_set(YASM_ERROR_VALUE, N_("invalid jump target"));
526 yasm_value_set_curpos_rel(&jmp->target, bc, 0);
527 jmp->target.jump_target = 1;
528
529 /* See if the user explicitly specified short/near/far. */
530 switch (insn_operands[jinfo->operands_index+0].targetmod) {
531 case OPTM_Short:
532 jmp->op_sel = JMP_SHORT_FORCED;
533 break;
534 case OPTM_Near:
535 jmp->op_sel = JMP_NEAR_FORCED;
536 break;
537 default:
538 jmp->op_sel = JMP_NONE;
539 }
540
541 /* Check for address size setting in second operand, if present */
542 if (jinfo->num_operands > 1 &&
543 insn_operands[jinfo->operands_index+1].action == OPA_AdSizeR)
544 jmp->common.addrsize = (unsigned char)
545 size_lookup[insn_operands[jinfo->operands_index+1].size];
546
547 /* Check for address size override */
548 for (i=0; i<NELEMS(jinfo->modifiers); i++) {
549 if (jinfo->modifiers[i] == MOD_AdSizeR)
550 jmp->common.addrsize = mod_data[i];
551 }
552
553 /* Scan through other infos for this insn looking for short/near versions.
554 * Needs to match opersize and number of operands, also be within CPU.
555 */
556 jmp->shortop.len = 0;
557 jmp->nearop.len = 0;
558 for (; num_info>0 && (jmp->shortop.len == 0 || jmp->nearop.len == 0);
559 num_info--, info++) {
560 /* Match CPU */
561 if (mode_bits != 64 && (info->misc_flags & ONLY_64))
562 continue;
563 if (mode_bits == 64 && (info->misc_flags & NOT_64))
564 continue;
565
566 if (!BitVector_bit_test(id_insn->cpu_enabled, info->cpu0) ||
567 !BitVector_bit_test(id_insn->cpu_enabled, info->cpu1) ||
568 !BitVector_bit_test(id_insn->cpu_enabled, info->cpu2))
569 continue;
570
571 if (info->num_operands == 0)
572 continue;
573
574 if (insn_operands[info->operands_index+0].action != OPA_JmpRel)
575 continue;
576
577 if (info->opersize != jmp->common.opersize)
578 continue;
579
580 switch (insn_operands[info->operands_index+0].targetmod) {
581 case OPTM_Short:
582 x86_finalize_opcode(&jmp->shortop, info);
583 for (i=0; i<NELEMS(info->modifiers); i++) {
584 if (info->modifiers[i] == MOD_Op0Add)
585 jmp->shortop.opcode[0] += mod_data[i];
586 }
587 break;
588 case OPTM_Near:
589 x86_finalize_opcode(&jmp->nearop, info);
590 for (i=0; i<NELEMS(info->modifiers); i++) {
591 if (info->modifiers[i] == MOD_Op1Add)
592 jmp->nearop.opcode[1] += mod_data[i];
593 }
594 break;
595 }
596 }
597
598 if ((jmp->op_sel == JMP_SHORT_FORCED) && (jmp->shortop.len == 0))
599 yasm_error_set(YASM_ERROR_TYPE,
600 N_("no SHORT form of that jump instruction exists"));
601 if ((jmp->op_sel == JMP_NEAR_FORCED) && (jmp->nearop.len == 0))
602 yasm_error_set(YASM_ERROR_TYPE,
603 N_("no NEAR form of that jump instruction exists"));
604
605 if (jmp->op_sel == JMP_NONE) {
606 if (jmp->nearop.len == 0)
607 jmp->op_sel = JMP_SHORT_FORCED;
608 if (jmp->shortop.len == 0)
609 jmp->op_sel = JMP_NEAR_FORCED;
610 }
611
612 yasm_x86__bc_apply_prefixes((x86_common *)jmp, NULL,
613 jinfo->def_opersize_64,
614 id_insn->insn.num_prefixes,
615 id_insn->insn.prefixes);
616
617 x86_id_insn_clear_operands(id_insn);
618
619 /* Transform the bytecode */
620 yasm_x86__bc_transform_jmp(bc, jmp);
621 }
622
623 static const x86_insn_info *
x86_find_match(x86_id_insn * id_insn,yasm_insn_operand ** ops,yasm_insn_operand ** rev_ops,const unsigned int * size_lookup,int bypass)624 x86_find_match(x86_id_insn *id_insn, yasm_insn_operand **ops,
625 yasm_insn_operand **rev_ops, const unsigned int *size_lookup,
626 int bypass)
627 {
628 const x86_insn_info *info = id_insn->group;
629 unsigned int num_info = id_insn->num_info;
630 unsigned int suffix = id_insn->suffix;
631 unsigned int mode_bits = id_insn->mode_bits;
632 int found = 0;
633
634 /* Just do a simple linear search through the info array for a match.
635 * First match wins.
636 */
637 for (; num_info>0 && !found; num_info--, info++) {
638 yasm_insn_operand *op, **use_ops;
639 const x86_info_operand *info_ops =
640 &insn_operands[info->operands_index];
641 unsigned int gas_flags = info->gas_flags;
642 unsigned int misc_flags = info->misc_flags;
643 unsigned int size;
644 int mismatch = 0;
645 unsigned int i;
646
647 /* Match CPU */
648 if (mode_bits != 64 && (misc_flags & ONLY_64))
649 continue;
650 if (mode_bits == 64 && (misc_flags & NOT_64))
651 continue;
652
653 if (bypass != 8 &&
654 (!BitVector_bit_test(id_insn->cpu_enabled, info->cpu0) ||
655 !BitVector_bit_test(id_insn->cpu_enabled, info->cpu1) ||
656 !BitVector_bit_test(id_insn->cpu_enabled, info->cpu2)))
657 continue;
658
659 /* Match # of operands */
660 if (id_insn->insn.num_operands != info->num_operands)
661 continue;
662
663 /* Match AVX */
664 if (!(id_insn->misc_flags & ONLY_AVX) && (misc_flags & ONLY_AVX))
665 continue;
666 if ((id_insn->misc_flags & ONLY_AVX) && (misc_flags & NOT_AVX))
667 continue;
668
669 /* Match parser mode */
670 if ((gas_flags & GAS_ONLY) && id_insn->parser != X86_PARSER_GAS)
671 continue;
672 if ((gas_flags & GAS_ILLEGAL) && id_insn->parser == X86_PARSER_GAS)
673 continue;
674
675 /* Match suffix (if required) */
676 if (id_insn->parser == X86_PARSER_GAS
677 && ((suffix & SUF_MASK) & (gas_flags & SUF_MASK)) == 0)
678 continue;
679
680 /* Use reversed operands in GAS mode if not otherwise specified */
681 use_ops = ops;
682 if (id_insn->parser == X86_PARSER_GAS && !(gas_flags & GAS_NO_REV))
683 use_ops = rev_ops;
684
685 if (id_insn->insn.num_operands == 0) {
686 found = 1; /* no operands -> must have a match here. */
687 break;
688 }
689
690 /* Match each operand type and size */
691 for (i = 0, op = use_ops[0]; op && i<info->num_operands && !mismatch;
692 op = use_ops[++i]) {
693 /* Check operand type */
694 switch (info_ops[i].type) {
695 case OPT_Imm:
696 if (op->type != YASM_INSN__OPERAND_IMM)
697 mismatch = 1;
698 break;
699 case OPT_RM:
700 if (op->type == YASM_INSN__OPERAND_MEMORY)
701 break;
702 /*@fallthrough@*/
703 case OPT_Reg:
704 if (op->type != YASM_INSN__OPERAND_REG)
705 mismatch = 1;
706 else {
707 switch ((x86_expritem_reg_size)(op->data.reg&~0xFUL)) {
708 case X86_REG8:
709 case X86_REG8X:
710 case X86_REG16:
711 case X86_REG32:
712 case X86_REG64:
713 case X86_FPUREG:
714 break;
715 default:
716 mismatch = 1;
717 break;
718 }
719 }
720 break;
721 case OPT_Mem:
722 if (op->type != YASM_INSN__OPERAND_MEMORY)
723 mismatch = 1;
724 break;
725 case OPT_SIMDRM:
726 if (op->type == YASM_INSN__OPERAND_MEMORY)
727 break;
728 /*@fallthrough@*/
729 case OPT_SIMDReg:
730 if (op->type != YASM_INSN__OPERAND_REG)
731 mismatch = 1;
732 else {
733 switch ((x86_expritem_reg_size)(op->data.reg&~0xFUL)) {
734 case X86_MMXREG:
735 case X86_XMMREG:
736 case X86_YMMREG:
737 break;
738 default:
739 mismatch = 1;
740 break;
741 }
742 }
743 break;
744 case OPT_SegReg:
745 if (op->type != YASM_INSN__OPERAND_SEGREG)
746 mismatch = 1;
747 break;
748 case OPT_CRReg:
749 if (op->type != YASM_INSN__OPERAND_REG ||
750 (op->data.reg & ~0xFUL) != X86_CRREG)
751 mismatch = 1;
752 break;
753 case OPT_DRReg:
754 if (op->type != YASM_INSN__OPERAND_REG ||
755 (op->data.reg & ~0xFUL) != X86_DRREG)
756 mismatch = 1;
757 break;
758 case OPT_TRReg:
759 if (op->type != YASM_INSN__OPERAND_REG ||
760 (op->data.reg & ~0xFUL) != X86_TRREG)
761 mismatch = 1;
762 break;
763 case OPT_ST0:
764 if (op->type != YASM_INSN__OPERAND_REG ||
765 op->data.reg != X86_FPUREG)
766 mismatch = 1;
767 break;
768 case OPT_Areg:
769 if (op->type != YASM_INSN__OPERAND_REG ||
770 (info_ops[i].size == OPS_8 &&
771 op->data.reg != (X86_REG8 | 0) &&
772 op->data.reg != (X86_REG8X | 0)) ||
773 (info_ops[i].size == OPS_16 &&
774 op->data.reg != (X86_REG16 | 0)) ||
775 (info_ops[i].size == OPS_32 &&
776 op->data.reg != (X86_REG32 | 0)) ||
777 (info_ops[i].size == OPS_64 &&
778 op->data.reg != (X86_REG64 | 0)))
779 mismatch = 1;
780 break;
781 case OPT_Creg:
782 if (op->type != YASM_INSN__OPERAND_REG ||
783 (info_ops[i].size == OPS_8 &&
784 op->data.reg != (X86_REG8 | 1) &&
785 op->data.reg != (X86_REG8X | 1)) ||
786 (info_ops[i].size == OPS_16 &&
787 op->data.reg != (X86_REG16 | 1)) ||
788 (info_ops[i].size == OPS_32 &&
789 op->data.reg != (X86_REG32 | 1)) ||
790 (info_ops[i].size == OPS_64 &&
791 op->data.reg != (X86_REG64 | 1)))
792 mismatch = 1;
793 break;
794 case OPT_Dreg:
795 if (op->type != YASM_INSN__OPERAND_REG ||
796 (info_ops[i].size == OPS_8 &&
797 op->data.reg != (X86_REG8 | 2) &&
798 op->data.reg != (X86_REG8X | 2)) ||
799 (info_ops[i].size == OPS_16 &&
800 op->data.reg != (X86_REG16 | 2)) ||
801 (info_ops[i].size == OPS_32 &&
802 op->data.reg != (X86_REG32 | 2)) ||
803 (info_ops[i].size == OPS_64 &&
804 op->data.reg != (X86_REG64 | 2)))
805 mismatch = 1;
806 break;
807 case OPT_CS:
808 if (op->type != YASM_INSN__OPERAND_SEGREG ||
809 (op->data.reg & 0xF) != 1)
810 mismatch = 1;
811 break;
812 case OPT_DS:
813 if (op->type != YASM_INSN__OPERAND_SEGREG ||
814 (op->data.reg & 0xF) != 3)
815 mismatch = 1;
816 break;
817 case OPT_ES:
818 if (op->type != YASM_INSN__OPERAND_SEGREG ||
819 (op->data.reg & 0xF) != 0)
820 mismatch = 1;
821 break;
822 case OPT_FS:
823 if (op->type != YASM_INSN__OPERAND_SEGREG ||
824 (op->data.reg & 0xF) != 4)
825 mismatch = 1;
826 break;
827 case OPT_GS:
828 if (op->type != YASM_INSN__OPERAND_SEGREG ||
829 (op->data.reg & 0xF) != 5)
830 mismatch = 1;
831 break;
832 case OPT_SS:
833 if (op->type != YASM_INSN__OPERAND_SEGREG ||
834 (op->data.reg & 0xF) != 2)
835 mismatch = 1;
836 break;
837 case OPT_CR4:
838 if (op->type != YASM_INSN__OPERAND_REG ||
839 op->data.reg != (X86_CRREG | 4))
840 mismatch = 1;
841 break;
842 case OPT_MemOffs:
843 if (op->type != YASM_INSN__OPERAND_MEMORY ||
844 yasm_expr__contains(op->data.ea->disp.abs,
845 YASM_EXPR_REG) ||
846 op->data.ea->pc_rel ||
847 (!op->data.ea->not_pc_rel && id_insn->default_rel &&
848 op->data.ea->disp.size != 64))
849 mismatch = 1;
850 break;
851 case OPT_Imm1:
852 if (op->type == YASM_INSN__OPERAND_IMM) {
853 const yasm_intnum *num;
854 num = yasm_expr_get_intnum(&op->data.val, 0);
855 if (!num || !yasm_intnum_is_pos1(num))
856 mismatch = 1;
857 } else
858 mismatch = 1;
859 break;
860 case OPT_ImmNotSegOff:
861 if (op->type != YASM_INSN__OPERAND_IMM ||
862 op->targetmod != 0 || op->seg)
863 mismatch = 1;
864 break;
865 case OPT_XMM0:
866 if (op->type != YASM_INSN__OPERAND_REG ||
867 op->data.reg != X86_XMMREG)
868 mismatch = 1;
869 break;
870 case OPT_MemrAX: {
871 const uintptr_t *regp;
872 if (op->type != YASM_INSN__OPERAND_MEMORY ||
873 !(regp = yasm_expr_get_reg(&op->data.ea->disp.abs, 0)) ||
874 (*regp != (X86_REG16 | 0) &&
875 *regp != (X86_REG32 | 0) &&
876 *regp != (X86_REG64 | 0)))
877 mismatch = 1;
878 break;
879 }
880 case OPT_MemEAX: {
881 const uintptr_t *regp;
882 if (op->type != YASM_INSN__OPERAND_MEMORY ||
883 !(regp = yasm_expr_get_reg(&op->data.ea->disp.abs, 0)) ||
884 *regp != (X86_REG32 | 0))
885 mismatch = 1;
886 break;
887 }
888 case OPT_MemXMMIndex:
889 if (op->type != YASM_INSN__OPERAND_MEMORY ||
890 !x86_expr_contains_simd(op->data.ea->disp.abs, 0))
891 mismatch = 1;
892 break;
893 case OPT_MemYMMIndex:
894 if (op->type != YASM_INSN__OPERAND_MEMORY ||
895 !x86_expr_contains_simd(op->data.ea->disp.abs, 1))
896 mismatch = 1;
897 break;
898 default:
899 yasm_internal_error(N_("invalid operand type"));
900 }
901
902 if (mismatch)
903 break;
904
905 /* Check operand size */
906 size = size_lookup[info_ops[i].size];
907 if (id_insn->parser == X86_PARSER_GAS) {
908 /* Require relaxed operands for GAS mode (don't allow
909 * per-operand sizing).
910 */
911 if (op->type == YASM_INSN__OPERAND_REG && op->size == 0) {
912 /* Register size must exactly match */
913 if (yasm_x86__get_reg_size(op->data.reg) != size)
914 mismatch = 1;
915 } else if ((info_ops[i].type == OPT_Imm
916 || info_ops[i].type == OPT_ImmNotSegOff
917 || info_ops[i].type == OPT_Imm1)
918 && !info_ops[i].relaxed
919 && info_ops[i].action != OPA_JmpRel)
920 mismatch = 1;
921 } else {
922 if (op->type == YASM_INSN__OPERAND_REG && op->size == 0) {
923 /* Register size must exactly match */
924 if ((bypass == 4 && i == 0) || (bypass == 5 && i == 1)
925 || (bypass == 6 && i == 2))
926 ;
927 else if (yasm_x86__get_reg_size(op->data.reg) != size)
928 mismatch = 1;
929 } else {
930 if ((bypass == 1 && i == 0) || (bypass == 2 && i == 1)
931 || (bypass == 3 && i == 2))
932 ;
933 else if (info_ops[i].relaxed) {
934 /* Relaxed checking */
935 if (size != 0 && op->size != size && op->size != 0)
936 mismatch = 1;
937 } else {
938 /* Strict checking */
939 if (op->size != size)
940 mismatch = 1;
941 }
942 }
943 }
944
945 if (mismatch)
946 break;
947
948 /* Check for 64-bit effective address size in NASM mode */
949 if (id_insn->parser != X86_PARSER_GAS &&
950 op->type == YASM_INSN__OPERAND_MEMORY) {
951 if (info_ops[i].eas64) {
952 if (op->data.ea->disp.size != 64)
953 mismatch = 1;
954 } else if (op->data.ea->disp.size == 64)
955 mismatch = 1;
956 }
957
958 if (mismatch)
959 break;
960
961 /* Check target modifier */
962 switch (info_ops[i].targetmod) {
963 case OPTM_None:
964 if (op->targetmod != 0)
965 mismatch = 1;
966 break;
967 case OPTM_Near:
968 if (op->targetmod != X86_NEAR)
969 mismatch = 1;
970 break;
971 case OPTM_Short:
972 if (op->targetmod != X86_SHORT)
973 mismatch = 1;
974 break;
975 case OPTM_Far:
976 if (op->targetmod != X86_FAR)
977 mismatch = 1;
978 break;
979 case OPTM_To:
980 if (op->targetmod != X86_TO)
981 mismatch = 1;
982 break;
983 default:
984 yasm_internal_error(N_("invalid target modifier type"));
985 }
986 }
987
988 if (!mismatch) {
989 found = 1;
990 break;
991 }
992 }
993
994 if (!found)
995 return NULL;
996 return info;
997 }
998
999 static void
x86_match_error(x86_id_insn * id_insn,yasm_insn_operand ** ops,yasm_insn_operand ** rev_ops,const unsigned int * size_lookup)1000 x86_match_error(x86_id_insn *id_insn, yasm_insn_operand **ops,
1001 yasm_insn_operand **rev_ops, const unsigned int *size_lookup)
1002 {
1003 const x86_insn_info *i;
1004 int ni;
1005 int found;
1006 int bypass;
1007
1008 /* Check for matching # of operands */
1009 found = 0;
1010 for (ni=id_insn->num_info, i=id_insn->group; ni>0; ni--, i++) {
1011 if (id_insn->insn.num_operands == i->num_operands) {
1012 found = 1;
1013 break;
1014 }
1015 }
1016 if (!found) {
1017 yasm_error_set(YASM_ERROR_TYPE, N_("invalid number of operands"));
1018 return;
1019 }
1020
1021 for (bypass=1; bypass<9; bypass++) {
1022 i = x86_find_match(id_insn, ops, rev_ops, size_lookup, bypass);
1023 if (i)
1024 break;
1025 }
1026
1027 switch (bypass) {
1028 case 1:
1029 case 4:
1030 yasm_error_set(YASM_ERROR_TYPE,
1031 N_("invalid size for operand %d"), 1);
1032 break;
1033 case 2:
1034 case 5:
1035 yasm_error_set(YASM_ERROR_TYPE,
1036 N_("invalid size for operand %d"), 2);
1037 break;
1038 case 3:
1039 case 6:
1040 yasm_error_set(YASM_ERROR_TYPE,
1041 N_("invalid size for operand %d"), 3);
1042 break;
1043 case 7:
1044 yasm_error_set(YASM_ERROR_TYPE,
1045 N_("one of source operand 1 or 3 must match dest operand"));
1046 break;
1047 case 8:
1048 {
1049 unsigned int cpu0 = i->cpu0, cpu1 = i->cpu1, cpu2 = i->cpu2;
1050 yasm_error_set(YASM_ERROR_TYPE,
1051 N_("requires CPU%s"),
1052 cpu_find_reverse(cpu0, cpu1, cpu2));
1053 break;
1054 }
1055 default:
1056 yasm_error_set(YASM_ERROR_TYPE,
1057 N_("invalid combination of opcode and operands"));
1058 }
1059 }
1060
1061 static void
x86_id_insn_finalize(yasm_bytecode * bc,yasm_bytecode * prev_bc)1062 x86_id_insn_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
1063 {
1064 x86_id_insn *id_insn = (x86_id_insn *)bc->contents;
1065 x86_insn *insn;
1066 const x86_insn_info *info = id_insn->group;
1067 unsigned int mode_bits = id_insn->mode_bits;
1068 unsigned char *mod_data = id_insn->mod_data;
1069 yasm_insn_operand *op, *ops[5], *rev_ops[5];
1070 /*@null@*/ yasm_expr *imm;
1071 unsigned char im_len;
1072 unsigned char im_sign;
1073 unsigned char spare;
1074 unsigned char vexdata, vexreg;
1075 unsigned int i;
1076 unsigned int size_lookup[] = {0, 8, 16, 32, 64, 80, 128, 256, 0};
1077 unsigned long do_postop = 0;
1078
1079 size_lookup[OPS_BITS] = mode_bits;
1080
1081 yasm_insn_finalize(&id_insn->insn);
1082
1083 /* Build local array of operands from list, since we know we have a max
1084 * of 5 operands.
1085 */
1086 if (id_insn->insn.num_operands > 5) {
1087 yasm_error_set(YASM_ERROR_TYPE, N_("too many operands"));
1088 return;
1089 }
1090 ops[0] = ops[1] = ops[2] = ops[3] = ops[4] = NULL;
1091 for (i = 0, op = yasm_insn_ops_first(&id_insn->insn);
1092 op && i < id_insn->insn.num_operands;
1093 op = yasm_insn_op_next(op), i++)
1094 ops[i] = op;
1095
1096 /* If we're running in GAS mode, build a reverse array of the operands
1097 * as most GAS instructions have reversed operands from Intel style.
1098 */
1099 if (id_insn->parser == X86_PARSER_GAS) {
1100 rev_ops[0] = rev_ops[1] = rev_ops[2] = rev_ops[3] = rev_ops[4] = NULL;
1101 for (i = id_insn->insn.num_operands-1,
1102 op = yasm_insn_ops_first(&id_insn->insn);
1103 op; op = yasm_insn_op_next(op), i--)
1104 rev_ops[i] = op;
1105 }
1106
1107 /* If we're running in GAS mode, look at the first insn_info to see
1108 * if this is a relative jump (OPA_JmpRel). If so, run through the
1109 * operands and adjust for dereferences / lack thereof.
1110 */
1111 if (id_insn->parser == X86_PARSER_GAS
1112 && insn_operands[info->operands_index+0].action == OPA_JmpRel) {
1113 for (i = 0, op = ops[0]; op; op = ops[++i]) {
1114 if (!op->deref && (op->type == YASM_INSN__OPERAND_REG
1115 || (op->type == YASM_INSN__OPERAND_MEMORY
1116 && op->data.ea->strong)))
1117 yasm_warn_set(YASM_WARN_GENERAL,
1118 N_("indirect call without `*'"));
1119 if (!op->deref && op->type == YASM_INSN__OPERAND_MEMORY
1120 && !op->data.ea->strong) {
1121 /* Memory that is not dereferenced, and not strong, is
1122 * actually an immediate for the purposes of relative jumps.
1123 */
1124 if (op->data.ea->segreg != 0)
1125 yasm_warn_set(YASM_WARN_GENERAL,
1126 N_("skipping prefixes on this instruction"));
1127 imm = op->data.ea->disp.abs;
1128 op->data.ea->disp.abs = NULL;
1129 yasm_x86__ea_destroy(op->data.ea);
1130 op->type = YASM_INSN__OPERAND_IMM;
1131 op->data.val = imm;
1132 }
1133 }
1134 }
1135
1136 info = x86_find_match(id_insn, ops, rev_ops, size_lookup, 0);
1137
1138 if (!info) {
1139 /* Didn't find a match */
1140 x86_match_error(id_insn, ops, rev_ops, size_lookup);
1141 return;
1142 }
1143
1144 if (id_insn->insn.num_operands > 0) {
1145 switch (insn_operands[info->operands_index+0].action) {
1146 case OPA_JmpRel:
1147 /* Shortcut to JmpRel */
1148 x86_finalize_jmp(bc, prev_bc, info);
1149 return;
1150 case OPA_JmpFar:
1151 /* Shortcut to JmpFar */
1152 x86_finalize_jmpfar(bc, prev_bc, info);
1153 return;
1154 }
1155 }
1156
1157 /* Copy what we can from info */
1158 insn = yasm_xmalloc(sizeof(x86_insn));
1159 x86_finalize_common(&insn->common, info, mode_bits);
1160 x86_finalize_opcode(&insn->opcode, info);
1161 insn->x86_ea = NULL;
1162 imm = NULL;
1163 insn->def_opersize_64 = info->def_opersize_64;
1164 insn->special_prefix = info->special_prefix;
1165 spare = info->spare;
1166 vexdata = 0;
1167 vexreg = 0;
1168 im_len = 0;
1169 im_sign = 0;
1170 insn->postop = X86_POSTOP_NONE;
1171 insn->rex = 0;
1172
1173 /* Move VEX/XOP data (stored in special prefix) to separate location to
1174 * allow overriding of special prefix by modifiers.
1175 */
1176 if ((insn->special_prefix & 0xF0) == 0xC0 ||
1177 (insn->special_prefix & 0xF0) == 0x80) {
1178 vexdata = insn->special_prefix;
1179 insn->special_prefix = 0;
1180 }
1181
1182 /* Apply modifiers */
1183 for (i=0; i<NELEMS(info->modifiers); i++) {
1184 switch (info->modifiers[i]) {
1185 case MOD_Gap:
1186 break;
1187 case MOD_PreAdd:
1188 insn->special_prefix += mod_data[i];
1189 break;
1190 case MOD_Op0Add:
1191 insn->opcode.opcode[0] += mod_data[i];
1192 break;
1193 case MOD_Op1Add:
1194 insn->opcode.opcode[1] += mod_data[i];
1195 break;
1196 case MOD_Op2Add:
1197 insn->opcode.opcode[2] += mod_data[i];
1198 break;
1199 case MOD_SpAdd:
1200 spare += mod_data[i];
1201 break;
1202 case MOD_OpSizeR:
1203 insn->common.opersize = mod_data[i];
1204 break;
1205 case MOD_Imm8:
1206 imm = yasm_expr_create_ident(yasm_expr_int(
1207 yasm_intnum_create_uint(mod_data[i])), bc->line);
1208 im_len = 8;
1209 break;
1210 case MOD_DOpS64R:
1211 insn->def_opersize_64 = mod_data[i];
1212 break;
1213 case MOD_Op1AddSp:
1214 insn->opcode.opcode[1] += mod_data[i]<<3;
1215 break;
1216 case MOD_SetVEX:
1217 vexdata = mod_data[i];
1218 break;
1219 default:
1220 break;
1221 }
1222 }
1223
1224 /* In 64-bit mode, if opersize is 64 and default is not 64,
1225 * force REX byte.
1226 */
1227 if (mode_bits == 64 && insn->common.opersize == 64 &&
1228 insn->def_opersize_64 != 64)
1229 insn->rex = 0x48;
1230
1231 /* Go through operands and assign */
1232 if (id_insn->insn.num_operands > 0) {
1233 yasm_insn_operand **use_ops = ops;
1234 const x86_info_operand *info_ops =
1235 &insn_operands[info->operands_index];
1236
1237 /* Use reversed operands in GAS mode if not otherwise specified */
1238 if (id_insn->parser == X86_PARSER_GAS
1239 && !(info->gas_flags & GAS_NO_REV))
1240 use_ops = rev_ops;
1241
1242 for (i = 0, op = use_ops[0]; op && i<info->num_operands;
1243 op = use_ops[++i]) {
1244 switch (info_ops[i].action) {
1245 case OPA_None:
1246 /* Throw away the operand contents */
1247 switch (op->type) {
1248 case YASM_INSN__OPERAND_REG:
1249 case YASM_INSN__OPERAND_SEGREG:
1250 break;
1251 case YASM_INSN__OPERAND_MEMORY:
1252 yasm_x86__ea_destroy(op->data.ea);
1253 break;
1254 case YASM_INSN__OPERAND_IMM:
1255 yasm_expr_destroy(op->data.val);
1256 break;
1257 }
1258 break;
1259 case OPA_EA:
1260 switch (op->type) {
1261 case YASM_INSN__OPERAND_REG:
1262 insn->x86_ea =
1263 yasm_x86__ea_create_reg(insn->x86_ea,
1264 (unsigned long)op->data.reg, &insn->rex,
1265 mode_bits);
1266 break;
1267 case YASM_INSN__OPERAND_SEGREG:
1268 yasm_internal_error(
1269 N_("invalid operand conversion"));
1270 case YASM_INSN__OPERAND_MEMORY:
1271 if (op->seg)
1272 yasm_error_set(YASM_ERROR_VALUE,
1273 N_("invalid segment in effective address"));
1274 insn->x86_ea = (x86_effaddr *)op->data.ea;
1275 if (info_ops[i].type == OPT_MemOffs)
1276 /* Special-case for MOV MemOffs instruction */
1277 yasm_x86__ea_set_disponly(insn->x86_ea);
1278 else if (info_ops[i].type == OPT_MemXMMIndex) {
1279 /* Remember VSIB mode */
1280 insn->x86_ea->vsib_mode = 1;
1281 insn->x86_ea->need_sib = 1;
1282 } else if (info_ops[i].type == OPT_MemYMMIndex) {
1283 /* Remember VSIB mode */
1284 insn->x86_ea->vsib_mode = 2;
1285 insn->x86_ea->need_sib = 1;
1286 } else if (id_insn->default_rel &&
1287 !op->data.ea->not_pc_rel &&
1288 op->data.ea->segreg != 0x6404 &&
1289 op->data.ea->segreg != 0x6505 &&
1290 !yasm_expr__contains(
1291 op->data.ea->disp.abs, YASM_EXPR_REG))
1292 /* Enable default PC-rel if no regs and segreg
1293 * is not FS or GS.
1294 */
1295 insn->x86_ea->ea.pc_rel = 1;
1296 break;
1297 case YASM_INSN__OPERAND_IMM:
1298 insn->x86_ea =
1299 yasm_x86__ea_create_imm(insn->x86_ea,
1300 op->data.val,
1301 size_lookup[info_ops[i].size]);
1302 break;
1303 }
1304 break;
1305 case OPA_EAVEX:
1306 if (op->type != YASM_INSN__OPERAND_REG)
1307 yasm_internal_error(N_("invalid operand conversion"));
1308 insn->x86_ea =
1309 yasm_x86__ea_create_reg(insn->x86_ea,
1310 (unsigned long)op->data.reg, &insn->rex, mode_bits);
1311 vexreg = op->data.reg & 0xF;
1312 break;
1313 case OPA_Imm:
1314 if (op->seg)
1315 yasm_error_set(YASM_ERROR_VALUE,
1316 N_("immediate does not support segment"));
1317 if (op->type == YASM_INSN__OPERAND_IMM) {
1318 imm = op->data.val;
1319 im_len = size_lookup[info_ops[i].size];
1320 } else
1321 yasm_internal_error(N_("invalid operand conversion"));
1322 break;
1323 case OPA_SImm:
1324 if (op->seg)
1325 yasm_error_set(YASM_ERROR_VALUE,
1326 N_("immediate does not support segment"));
1327 if (op->type == YASM_INSN__OPERAND_IMM) {
1328 imm = op->data.val;
1329 im_len = size_lookup[info_ops[i].size];
1330 im_sign = 1;
1331 } else
1332 yasm_internal_error(N_("invalid operand conversion"));
1333 break;
1334 case OPA_Spare:
1335 if (op->type == YASM_INSN__OPERAND_SEGREG)
1336 spare = (unsigned char)(op->data.reg&7);
1337 else if (op->type == YASM_INSN__OPERAND_REG) {
1338 if (yasm_x86__set_rex_from_reg(&insn->rex, &spare,
1339 op->data.reg, mode_bits, X86_REX_R))
1340 return;
1341 } else
1342 yasm_internal_error(N_("invalid operand conversion"));
1343 break;
1344 case OPA_SpareVEX:
1345 if (op->type != YASM_INSN__OPERAND_REG)
1346 yasm_internal_error(N_("invalid operand conversion"));
1347 if (yasm_x86__set_rex_from_reg(&insn->rex, &spare,
1348 op->data.reg, mode_bits, X86_REX_R))
1349 return;
1350 vexreg = op->data.reg & 0xF;
1351 break;
1352 case OPA_Op0Add:
1353 if (op->type == YASM_INSN__OPERAND_REG) {
1354 unsigned char opadd;
1355 if (yasm_x86__set_rex_from_reg(&insn->rex, &opadd,
1356 op->data.reg, mode_bits, X86_REX_B))
1357 return;
1358 insn->opcode.opcode[0] += opadd;
1359 } else
1360 yasm_internal_error(N_("invalid operand conversion"));
1361 break;
1362 case OPA_Op1Add:
1363 if (op->type == YASM_INSN__OPERAND_REG) {
1364 unsigned char opadd;
1365 if (yasm_x86__set_rex_from_reg(&insn->rex, &opadd,
1366 op->data.reg, mode_bits, X86_REX_B))
1367 return;
1368 insn->opcode.opcode[1] += opadd;
1369 } else
1370 yasm_internal_error(N_("invalid operand conversion"));
1371 break;
1372 case OPA_SpareEA:
1373 if (op->type == YASM_INSN__OPERAND_REG) {
1374 insn->x86_ea =
1375 yasm_x86__ea_create_reg(insn->x86_ea,
1376 (unsigned long)op->data.reg, &insn->rex,
1377 mode_bits);
1378 if (!insn->x86_ea ||
1379 yasm_x86__set_rex_from_reg(&insn->rex, &spare,
1380 op->data.reg, mode_bits, X86_REX_R)) {
1381 if (insn->x86_ea)
1382 yasm_xfree(insn->x86_ea);
1383 yasm_xfree(insn);
1384 return;
1385 }
1386 } else
1387 yasm_internal_error(N_("invalid operand conversion"));
1388 break;
1389 case OPA_AdSizeEA: {
1390 const uintptr_t *regp = NULL;
1391 /* Only implement this for OPT_MemrAX and OPT_MemEAX
1392 * for now.
1393 */
1394 if (op->type != YASM_INSN__OPERAND_MEMORY ||
1395 !(regp = yasm_expr_get_reg(&op->data.ea->disp.abs, 0)))
1396 yasm_internal_error(N_("invalid operand conversion"));
1397 /* 64-bit mode does not allow 16-bit addresses */
1398 if (mode_bits == 64 && *regp == (X86_REG16 | 0))
1399 yasm_error_set(YASM_ERROR_TYPE,
1400 N_("16-bit addresses not supported in 64-bit mode"));
1401 else if (*regp == (X86_REG16 | 0))
1402 insn->common.addrsize = 16;
1403 else if (*regp == (X86_REG32 | 0))
1404 insn->common.addrsize = 32;
1405 else if (mode_bits == 64 && *regp == (X86_REG64 | 0))
1406 insn->common.addrsize = 64;
1407 else
1408 yasm_error_set(YASM_ERROR_TYPE,
1409 N_("unsupported address size"));
1410 yasm_x86__ea_destroy(op->data.ea);
1411 break;
1412 }
1413 case OPA_VEX:
1414 if (op->type != YASM_INSN__OPERAND_REG)
1415 yasm_internal_error(N_("invalid operand conversion"));
1416 vexreg = op->data.reg & 0xF;
1417 break;
1418 case OPA_VEXImmSrc:
1419 if (op->type != YASM_INSN__OPERAND_REG)
1420 yasm_internal_error(N_("invalid operand conversion"));
1421
1422 if (!imm) {
1423 imm = yasm_expr_create_ident(
1424 yasm_expr_int(
1425 yasm_intnum_create_uint((op->data.reg << 4)
1426 & 0xF0)),
1427 bc->line);
1428 } else {
1429 imm = yasm_expr_create(
1430 YASM_EXPR_OR,
1431 yasm_expr_expr(yasm_expr_create(
1432 YASM_EXPR_AND,
1433 yasm_expr_expr(imm),
1434 yasm_expr_int(yasm_intnum_create_uint(0x0F)),
1435 bc->line)),
1436 yasm_expr_int(
1437 yasm_intnum_create_uint((op->data.reg << 4)
1438 & 0xF0)),
1439 bc->line);
1440 }
1441 im_len = 8;
1442 break;
1443 case OPA_VEXImm:
1444 if (op->type != YASM_INSN__OPERAND_IMM)
1445 yasm_internal_error(N_("invalid operand conversion"));
1446
1447 if (!imm)
1448 imm = op->data.val;
1449 else {
1450 imm = yasm_expr_create(
1451 YASM_EXPR_OR,
1452 yasm_expr_expr(yasm_expr_create(
1453 YASM_EXPR_AND,
1454 yasm_expr_expr(op->data.val),
1455 yasm_expr_int(yasm_intnum_create_uint(0x0F)),
1456 bc->line)),
1457 yasm_expr_expr(yasm_expr_create(
1458 YASM_EXPR_AND,
1459 yasm_expr_expr(imm),
1460 yasm_expr_int(yasm_intnum_create_uint(0xF0)),
1461 bc->line)),
1462 bc->line);
1463 }
1464 im_len = 8;
1465 break;
1466 default:
1467 yasm_internal_error(N_("unknown operand action"));
1468 }
1469
1470 if (info_ops[i].size == OPS_BITS)
1471 insn->common.opersize = (unsigned char)mode_bits;
1472
1473 switch (info_ops[i].post_action) {
1474 case OPAP_None:
1475 break;
1476 case OPAP_SImm8:
1477 /* Check operand strictness; if strict and non-8-bit,
1478 * pre-emptively expand to full size.
1479 * For unspecified size case, still optimize.
1480 */
1481 if (!(id_insn->force_strict || op->strict)
1482 || op->size == 0)
1483 insn->postop = X86_POSTOP_SIGNEXT_IMM8;
1484 else if (op->size != 8) {
1485 insn->opcode.opcode[0] =
1486 insn->opcode.opcode[insn->opcode.len];
1487 insn->opcode.len = 1;
1488 }
1489 break;
1490 case OPAP_ShortMov:
1491 do_postop = OPAP_ShortMov;
1492 break;
1493 case OPAP_A16:
1494 insn->postop = X86_POSTOP_ADDRESS16;
1495 break;
1496 case OPAP_SImm32Avail:
1497 do_postop = OPAP_SImm32Avail;
1498 break;
1499 default:
1500 yasm_internal_error(
1501 N_("unknown operand postponed action"));
1502 }
1503 }
1504 }
1505
1506 if (insn->x86_ea) {
1507 yasm_x86__ea_init(insn->x86_ea, spare, prev_bc);
1508 for (i=0; i<id_insn->insn.num_segregs; i++)
1509 yasm_ea_set_segreg(&insn->x86_ea->ea, id_insn->insn.segregs[i]);
1510 } else if (id_insn->insn.num_segregs > 0 && insn->special_prefix == 0) {
1511 if (id_insn->insn.num_segregs > 1)
1512 yasm_warn_set(YASM_WARN_GENERAL,
1513 N_("multiple segment overrides, using leftmost"));
1514 insn->special_prefix = (unsigned char)
1515 (id_insn->insn.segregs[id_insn->insn.num_segregs-1]>>8);
1516 } else if (id_insn->insn.num_segregs > 0)
1517 yasm_internal_error(N_("unhandled segment prefix"));
1518
1519 if (imm) {
1520 insn->imm = yasm_xmalloc(sizeof(yasm_value));
1521 if (yasm_value_finalize_expr(insn->imm, imm, prev_bc, im_len))
1522 yasm_error_set(YASM_ERROR_TOO_COMPLEX,
1523 N_("immediate expression too complex"));
1524 insn->imm->sign = im_sign;
1525 } else
1526 insn->imm = NULL;
1527
1528 yasm_x86__bc_apply_prefixes((x86_common *)insn, &insn->rex,
1529 insn->def_opersize_64,
1530 id_insn->insn.num_prefixes,
1531 id_insn->insn.prefixes);
1532
1533 if (insn->postop == X86_POSTOP_ADDRESS16 && insn->common.addrsize) {
1534 yasm_warn_set(YASM_WARN_GENERAL, N_("address size override ignored"));
1535 insn->common.addrsize = 0;
1536 }
1537
1538 /* Handle non-span-dependent post-ops here */
1539 switch (do_postop) {
1540 case OPAP_ShortMov:
1541 /* Long (modrm+sib) mov instructions in amd64 can be optimized into
1542 * short mov instructions if a 32-bit address override is applied in
1543 * 64-bit mode to an EA of just an offset (no registers) and the
1544 * target register is al/ax/eax/rax.
1545 *
1546 * We don't want to do this if we're in default rel mode.
1547 */
1548 if (!id_insn->default_rel &&
1549 insn->common.mode_bits == 64 &&
1550 insn->common.addrsize == 32 &&
1551 (!insn->x86_ea->ea.disp.abs ||
1552 !yasm_expr__contains(insn->x86_ea->ea.disp.abs,
1553 YASM_EXPR_REG))) {
1554 yasm_x86__ea_set_disponly(insn->x86_ea);
1555 /* Make the short form permanent. */
1556 insn->opcode.opcode[0] = insn->opcode.opcode[1];
1557 }
1558 insn->opcode.opcode[1] = 0; /* avoid possible confusion */
1559 break;
1560 case OPAP_SImm32Avail:
1561 /* Used for 64-bit mov immediate, which can take a sign-extended
1562 * imm32 as well as imm64 values. The imm32 form is put in the
1563 * second byte of the opcode and its ModRM byte is put in the third
1564 * byte of the opcode.
1565 */
1566 if (!insn->imm->abs ||
1567 (yasm_expr_get_intnum(&insn->imm->abs, 0) &&
1568 yasm_intnum_check_size(
1569 yasm_expr_get_intnum(&insn->imm->abs, 0), 32, 0, 1))) {
1570 /* Throwaway REX byte */
1571 unsigned char rex_temp = 0;
1572
1573 /* Build ModRM EA - CAUTION: this depends on
1574 * opcode 0 being a mov instruction!
1575 */
1576 insn->x86_ea = yasm_x86__ea_create_reg(insn->x86_ea,
1577 (unsigned long)insn->opcode.opcode[0]-0xB8, &rex_temp, 64);
1578
1579 /* Make the imm32s form permanent. */
1580 insn->opcode.opcode[0] = insn->opcode.opcode[1];
1581 insn->imm->size = 32;
1582 }
1583 insn->opcode.opcode[1] = 0; /* avoid possible confusion */
1584 break;
1585 default:
1586 break;
1587 }
1588
1589 /* Convert to VEX/XOP prefixes if requested.
1590 * To save space in the insn structure, the VEX/XOP prefix is written into
1591 * special_prefix and the first 2 bytes of the instruction are set to
1592 * the second two VEX/XOP bytes. During calc_len() it may be shortened to
1593 * one VEX byte (this can only be done after knowledge of REX value); this
1594 * further optimization is not possible for XOP.
1595 */
1596 if (vexdata) {
1597 int xop = ((vexdata & 0xF0) == 0x80);
1598 unsigned char vex1 = 0xE0; /* R=X=B=1, mmmmm=0 */
1599 unsigned char vex2;
1600
1601 if (xop) {
1602 /* Look at the first bytes of the opcode for the XOP mmmmm field.
1603 * Leave R=X=B=1 for now.
1604 */
1605 if (insn->opcode.opcode[0] != 0x08 &&
1606 insn->opcode.opcode[0] != 0x09)
1607 yasm_internal_error(N_("first opcode byte of XOP must be 0x08 or 0x09"));
1608 vex1 |= insn->opcode.opcode[0];
1609 /* Move opcode byte back one byte to make room for XOP prefix. */
1610 insn->opcode.opcode[2] = insn->opcode.opcode[1];
1611 } else {
1612 /* Look at the first bytes of the opcode to see what leading bytes
1613 * to encode in the VEX mmmmm field. Leave R=X=B=1 for now.
1614 */
1615 if (insn->opcode.opcode[0] != 0x0F)
1616 yasm_internal_error(N_("first opcode byte of VEX must be 0x0F"));
1617
1618 if (insn->opcode.opcode[1] == 0x38)
1619 vex1 |= 0x02; /* implied 0x0F 0x38 */
1620 else if (insn->opcode.opcode[1] == 0x3A)
1621 vex1 |= 0x03; /* implied 0x0F 0x3A */
1622 else {
1623 /* Originally a 0F-only opcode; move opcode byte back one
1624 * position to make room for VEX prefix.
1625 */
1626 insn->opcode.opcode[2] = insn->opcode.opcode[1];
1627 vex1 |= 0x01; /* implied 0x0F */
1628 }
1629 }
1630
1631 /* Check for update of special prefix by modifiers */
1632 if (insn->special_prefix != 0) {
1633 vexdata &= ~0x03;
1634 switch (insn->special_prefix) {
1635 case 0x66:
1636 vexdata |= 0x01;
1637 break;
1638 case 0xF3:
1639 vexdata |= 0x02;
1640 break;
1641 case 0xF2:
1642 vexdata |= 0x03;
1643 break;
1644 default:
1645 yasm_internal_error(N_("unrecognized special prefix"));
1646 }
1647 }
1648
1649 /* 2nd VEX byte is WvvvvLpp.
1650 * W, L, pp come from vexdata
1651 * vvvv comes from 1s complement of vexreg
1652 */
1653 vex2 = (((vexdata & 0x8) << 4) | /* W */
1654 ((15 - (vexreg & 0xF)) << 3) | /* vvvv */
1655 (vexdata & 0x7)); /* Lpp */
1656
1657 /* Save to special_prefix and opcode */
1658 insn->special_prefix = xop ? 0x8F : 0xC4; /* VEX/XOP prefix */
1659 insn->opcode.opcode[0] = vex1;
1660 insn->opcode.opcode[1] = vex2;
1661 insn->opcode.len = 3; /* two prefix bytes and 1 opcode byte */
1662 }
1663
1664 x86_id_insn_clear_operands(id_insn);
1665
1666 /* Transform the bytecode */
1667 yasm_x86__bc_transform_insn(bc, insn);
1668 }
1669
1670 /* Static parse data structure for instructions */
1671 typedef struct insnprefix_parse_data {
1672 const char *name;
1673
1674 /* instruction parse group - NULL if prefix */
1675 /*@null@*/ const x86_insn_info *group;
1676
1677 /* For instruction, number of elements in group.
1678 * For prefix, prefix type shifted right by 8.
1679 */
1680 unsigned int num_info:8;
1681
1682 /* For instruction, GAS suffix flags.
1683 * For prefix, prefix value.
1684 */
1685 unsigned int flags:8;
1686
1687 /* Instruction modifier data. */
1688 unsigned int mod_data0:8;
1689 unsigned int mod_data1:8;
1690 unsigned int mod_data2:8;
1691
1692 /* Tests against BITS==64 and AVX */
1693 unsigned int misc_flags:6;
1694
1695 /* CPU flags */
1696 unsigned int cpu0:6;
1697 unsigned int cpu1:6;
1698 unsigned int cpu2:6;
1699 } insnprefix_parse_data;
1700
1701 /* Pull in all parse data */
1702 #include "x86insn_nasm.c"
1703 #include "x86insn_gas.c"
1704
1705 static const char *
cpu_find_reverse(unsigned int cpu0,unsigned int cpu1,unsigned int cpu2)1706 cpu_find_reverse(unsigned int cpu0, unsigned int cpu1, unsigned int cpu2)
1707 {
1708 static char cpuname[200];
1709 wordptr cpu = BitVector_Create(128, TRUE);
1710
1711 if (cpu0 != CPU_Any)
1712 BitVector_Bit_On(cpu, cpu0);
1713 if (cpu1 != CPU_Any)
1714 BitVector_Bit_On(cpu, cpu1);
1715 if (cpu2 != CPU_Any)
1716 BitVector_Bit_On(cpu, cpu2);
1717
1718 cpuname[0] = '\0';
1719
1720 if (BitVector_bit_test(cpu, CPU_Prot))
1721 strcat(cpuname, " Protected");
1722 if (BitVector_bit_test(cpu, CPU_Undoc))
1723 strcat(cpuname, " Undocumented");
1724 if (BitVector_bit_test(cpu, CPU_Obs))
1725 strcat(cpuname, " Obsolete");
1726 if (BitVector_bit_test(cpu, CPU_Priv))
1727 strcat(cpuname, " Privileged");
1728
1729 if (BitVector_bit_test(cpu, CPU_FPU))
1730 strcat(cpuname, " FPU");
1731 if (BitVector_bit_test(cpu, CPU_MMX))
1732 strcat(cpuname, " MMX");
1733 if (BitVector_bit_test(cpu, CPU_SSE))
1734 strcat(cpuname, " SSE");
1735 if (BitVector_bit_test(cpu, CPU_SSE2))
1736 strcat(cpuname, " SSE2");
1737 if (BitVector_bit_test(cpu, CPU_SSE3))
1738 strcat(cpuname, " SSE3");
1739 if (BitVector_bit_test(cpu, CPU_3DNow))
1740 strcat(cpuname, " 3DNow");
1741 if (BitVector_bit_test(cpu, CPU_Cyrix))
1742 strcat(cpuname, " Cyrix");
1743 if (BitVector_bit_test(cpu, CPU_AMD))
1744 strcat(cpuname, " AMD");
1745 if (BitVector_bit_test(cpu, CPU_SMM))
1746 strcat(cpuname, " SMM");
1747 if (BitVector_bit_test(cpu, CPU_SVM))
1748 strcat(cpuname, " SVM");
1749 if (BitVector_bit_test(cpu, CPU_PadLock))
1750 strcat(cpuname, " PadLock");
1751 if (BitVector_bit_test(cpu, CPU_EM64T))
1752 strcat(cpuname, " EM64T");
1753 if (BitVector_bit_test(cpu, CPU_SSSE3))
1754 strcat(cpuname, " SSSE3");
1755 if (BitVector_bit_test(cpu, CPU_SSE41))
1756 strcat(cpuname, " SSE4.1");
1757 if (BitVector_bit_test(cpu, CPU_SSE42))
1758 strcat(cpuname, " SSE4.2");
1759
1760 if (BitVector_bit_test(cpu, CPU_186))
1761 strcat(cpuname, " 186");
1762 if (BitVector_bit_test(cpu, CPU_286))
1763 strcat(cpuname, " 286");
1764 if (BitVector_bit_test(cpu, CPU_386))
1765 strcat(cpuname, " 386");
1766 if (BitVector_bit_test(cpu, CPU_486))
1767 strcat(cpuname, " 486");
1768 if (BitVector_bit_test(cpu, CPU_586))
1769 strcat(cpuname, " 586");
1770 if (BitVector_bit_test(cpu, CPU_686))
1771 strcat(cpuname, " 686");
1772 if (BitVector_bit_test(cpu, CPU_P3))
1773 strcat(cpuname, " P3");
1774 if (BitVector_bit_test(cpu, CPU_P4))
1775 strcat(cpuname, " P4");
1776 if (BitVector_bit_test(cpu, CPU_IA64))
1777 strcat(cpuname, " IA64");
1778 if (BitVector_bit_test(cpu, CPU_K6))
1779 strcat(cpuname, " K6");
1780 if (BitVector_bit_test(cpu, CPU_Athlon))
1781 strcat(cpuname, " Athlon");
1782 if (BitVector_bit_test(cpu, CPU_Hammer))
1783 strcat(cpuname, " Hammer");
1784
1785 BitVector_Destroy(cpu);
1786 return cpuname;
1787 }
1788
1789 yasm_arch_insnprefix
yasm_x86__parse_check_insnprefix(yasm_arch * arch,const char * id,size_t id_len,unsigned long line,yasm_bytecode ** bc,uintptr_t * prefix)1790 yasm_x86__parse_check_insnprefix(yasm_arch *arch, const char *id,
1791 size_t id_len, unsigned long line,
1792 yasm_bytecode **bc, uintptr_t *prefix)
1793 {
1794 yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
1795 /*@null@*/ const insnprefix_parse_data *pdata;
1796 size_t i;
1797 static char lcaseid[17];
1798
1799 *bc = (yasm_bytecode *)NULL;
1800 *prefix = 0;
1801
1802 if (id_len > 16)
1803 return YASM_ARCH_NOTINSNPREFIX;
1804 for (i=0; i<id_len; i++)
1805 lcaseid[i] = tolower(id[i]);
1806 lcaseid[id_len] = '\0';
1807
1808 switch (PARSER(arch_x86)) {
1809 case X86_PARSER_NASM:
1810 pdata = insnprefix_nasm_find(lcaseid, id_len);
1811 break;
1812 case X86_PARSER_TASM:
1813 pdata = insnprefix_nasm_find(lcaseid, id_len);
1814 break;
1815 case X86_PARSER_GAS:
1816 pdata = insnprefix_gas_find(lcaseid, id_len);
1817 break;
1818 default:
1819 pdata = NULL;
1820 }
1821 if (!pdata)
1822 return YASM_ARCH_NOTINSNPREFIX;
1823
1824 if (pdata->group) {
1825 x86_id_insn *id_insn;
1826 wordptr cpu_enabled = arch_x86->cpu_enables[arch_x86->active_cpu];
1827 unsigned int cpu0, cpu1, cpu2;
1828
1829 if (arch_x86->mode_bits != 64 && (pdata->misc_flags & ONLY_64)) {
1830 yasm_warn_set(YASM_WARN_GENERAL,
1831 N_("`%s' is an instruction in 64-bit mode"), id);
1832 return YASM_ARCH_NOTINSNPREFIX;
1833 }
1834 if (arch_x86->mode_bits == 64 && (pdata->misc_flags & NOT_64)) {
1835 yasm_error_set(YASM_ERROR_GENERAL,
1836 N_("`%s' invalid in 64-bit mode"), id);
1837 id_insn = yasm_xmalloc(sizeof(x86_id_insn));
1838 yasm_insn_initialize(&id_insn->insn);
1839 id_insn->group = not64_insn;
1840 id_insn->cpu_enabled = cpu_enabled;
1841 id_insn->mod_data[0] = 0;
1842 id_insn->mod_data[1] = 0;
1843 id_insn->mod_data[2] = 0;
1844 id_insn->num_info = NELEMS(not64_insn);
1845 id_insn->mode_bits = arch_x86->mode_bits;
1846 id_insn->suffix = 0;
1847 id_insn->misc_flags = 0;
1848 id_insn->parser = PARSER(arch_x86);
1849
1850 id_insn->force_strict = arch_x86->force_strict != 0;
1851 id_insn->default_rel = arch_x86->default_rel != 0;
1852 *bc = yasm_bc_create_common(&x86_id_insn_callback, id_insn, line);
1853 return YASM_ARCH_INSN;
1854 }
1855
1856 cpu0 = pdata->cpu0;
1857 cpu1 = pdata->cpu1;
1858 cpu2 = pdata->cpu2;
1859
1860 if (!BitVector_bit_test(cpu_enabled, cpu0) ||
1861 !BitVector_bit_test(cpu_enabled, cpu1) ||
1862 !BitVector_bit_test(cpu_enabled, cpu2)) {
1863 yasm_warn_set(YASM_WARN_GENERAL,
1864 N_("`%s' is an instruction in CPU%s"), id,
1865 cpu_find_reverse(cpu0, cpu1, cpu2));
1866 return YASM_ARCH_NOTINSNPREFIX;
1867 }
1868
1869 id_insn = yasm_xmalloc(sizeof(x86_id_insn));
1870 yasm_insn_initialize(&id_insn->insn);
1871 id_insn->group = pdata->group;
1872 id_insn->cpu_enabled = cpu_enabled;
1873 id_insn->mod_data[0] = pdata->mod_data0;
1874 id_insn->mod_data[1] = pdata->mod_data1;
1875 id_insn->mod_data[2] = pdata->mod_data2;
1876 id_insn->num_info = pdata->num_info;
1877 id_insn->mode_bits = arch_x86->mode_bits;
1878 id_insn->suffix = pdata->flags;
1879 id_insn->misc_flags = pdata->misc_flags;
1880 id_insn->parser = PARSER(arch_x86);
1881 id_insn->force_strict = arch_x86->force_strict != 0;
1882 id_insn->default_rel = arch_x86->default_rel != 0;
1883 *bc = yasm_bc_create_common(&x86_id_insn_callback, id_insn, line);
1884 return YASM_ARCH_INSN;
1885 } else {
1886 unsigned long type = pdata->num_info<<8;
1887 unsigned long value = pdata->flags;
1888
1889 if (arch_x86->mode_bits == 64 && type == X86_OPERSIZE && value == 32) {
1890 yasm_error_set(YASM_ERROR_GENERAL,
1891 N_("Cannot override data size to 32 bits in 64-bit mode"));
1892 return YASM_ARCH_NOTINSNPREFIX;
1893 }
1894
1895 if (arch_x86->mode_bits == 64 && type == X86_ADDRSIZE && value == 16) {
1896 yasm_error_set(YASM_ERROR_GENERAL,
1897 N_("Cannot override address size to 16 bits in 64-bit mode"));
1898 return YASM_ARCH_NOTINSNPREFIX;
1899 }
1900
1901 if (arch_x86->mode_bits != 64 && (pdata->misc_flags & ONLY_64)) {
1902 yasm_warn_set(YASM_WARN_GENERAL,
1903 N_("`%s' is a prefix in 64-bit mode"), id);
1904 return YASM_ARCH_NOTINSNPREFIX;
1905 }
1906 *prefix = type|value;
1907 return YASM_ARCH_PREFIX;
1908 }
1909 }
1910
1911 static void
x86_id_insn_destroy(void * contents)1912 x86_id_insn_destroy(void *contents)
1913 {
1914 x86_id_insn *id_insn = (x86_id_insn *)contents;
1915 yasm_insn_delete(&id_insn->insn, yasm_x86__ea_destroy);
1916 yasm_xfree(contents);
1917 }
1918
1919 static void
x86_id_insn_print(const void * contents,FILE * f,int indent_level)1920 x86_id_insn_print(const void *contents, FILE *f, int indent_level)
1921 {
1922 const x86_id_insn *id_insn = (const x86_id_insn *)contents;
1923 yasm_insn_print(&id_insn->insn, f, indent_level);
1924 /*TODO*/
1925 }
1926
1927 /*@only@*/ yasm_bytecode *
yasm_x86__create_empty_insn(yasm_arch * arch,unsigned long line)1928 yasm_x86__create_empty_insn(yasm_arch *arch, unsigned long line)
1929 {
1930 yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
1931 x86_id_insn *id_insn = yasm_xmalloc(sizeof(x86_id_insn));
1932
1933 yasm_insn_initialize(&id_insn->insn);
1934 id_insn->group = empty_insn;
1935 id_insn->cpu_enabled = arch_x86->cpu_enables[arch_x86->active_cpu];
1936 id_insn->mod_data[0] = 0;
1937 id_insn->mod_data[1] = 0;
1938 id_insn->mod_data[2] = 0;
1939 id_insn->num_info = NELEMS(empty_insn);
1940 id_insn->mode_bits = arch_x86->mode_bits;
1941 id_insn->suffix = (PARSER(arch_x86) == X86_PARSER_GAS) ? SUF_Z : 0;
1942 id_insn->misc_flags = 0;
1943 id_insn->parser = PARSER(arch_x86);
1944 id_insn->force_strict = arch_x86->force_strict != 0;
1945 id_insn->default_rel = arch_x86->default_rel != 0;
1946
1947 return yasm_bc_create_common(&x86_id_insn_callback, id_insn, line);
1948 }
1949
1950