• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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