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
36static 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 */
54enum 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 */
70enum 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
79enum 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
120enum 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
137enum 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
145enum 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
178enum 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
190typedef 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
234typedef 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
302typedef 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
336static void x86_id_insn_destroy(void *contents);
337static void x86_id_insn_print(const void *contents, FILE *f, int indent_level);
338static void x86_id_insn_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
339
340static 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 */
356static int
357x86_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
377static int
378x86_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
384static void
385x86_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
394static void
395x86_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. */
404static void
405x86_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
414static void
415x86_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
498static void
499x86_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
623static const x86_insn_info *
624x86_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
999static void
1000x86_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
1061static void
1062x86_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 */
1671typedef 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
1705static const char *
1706cpu_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
1789yasm_arch_insnprefix
1790yasm_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
1911static void
1912x86_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
1919static void
1920x86_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 *
1928yasm_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