]> granicus.if.org Git - yasm/commitdiff
Preliminary GAS parser. Only a few instructions are supported at present.
authorPeter Johnson <peter@tortall.net>
Sun, 25 Sep 2005 04:25:26 +0000 (04:25 -0000)
committerPeter Johnson <peter@tortall.net>
Sun, 25 Sep 2005 04:25:26 +0000 (04:25 -0000)
This work is being done under contract with a company that has requested
to remain unnamed at the present time.

* bc-int.h (yasm_effaddr): Add strong flag to indicate if the effective
address is definitely an effective address; GAS does not use [] to designate
effective addresses so it's otherwise impossible to tell the difference
between "expr(,1)" and just "expr" (important for the relative jump
instructions).
* bytecode.h (yasm_ea_set_strong): New function to set the strong flag.
* bytecode.c (yasm_ea_set_strong): Implementation.
* x86bc.c (yasm_x86__ea_create_reg): Initialize strong flag.

* arch.h (yasm_insn_operand): Add deref flag to indicate use of "*foo" in
GAS syntax.
* arch.c (yasm_operand_create_reg, yasm_operand_create_segreg)
(yasm_operand_create_mem, yasm_operand_create_imm): Set deref flag to 0.

* gas: GAS syntax lexer and parser.  Not all directives are implemented yet
(some will require additional core bytecodes).

* elf-objfmt.c (elf_objfmt_section_switch): Add support for GAS-style
section flags.

* x86arch.h (yasm_arch_x86): Add parser setting.
* x86arch.c (x86_create): Check for gas parser and initialize setting.

* x86bc.c (yasm_x86__ea_create_expr): Transform val+RIP to val wrt RIP when
using the GAS parser (this is how GAS interprets "expr(%rip)").

* x86id.re: Too many changes to enumerate in detail.  Add new modifiers for
GAS suffixes.  Start using them in a couple instructions.  Split check_id
into subfunctions (still one entry point at present).
(yasm_x86__finalize_insn): Support new modifiers, reverse operands, derefs.

* yasm.c (main): Change all undef to extern when using GAS parser (this is
default GAS behavior).

svn path=/trunk/yasm/; revision=1239

39 files changed:
frontends/yasm/yasm.c
libyasm/arch.c
libyasm/arch.h
libyasm/bc-int.h
libyasm/bytecode.c
libyasm/bytecode.h
modules/arch/x86/x86arch.c
modules/arch/x86/x86arch.h
modules/arch/x86/x86bc.c
modules/arch/x86/x86id.re
modules/objfmts/elf/elf-objfmt.c
modules/parsers/Makefile.inc
modules/parsers/gas/Makefile.inc [new file with mode: 0644]
modules/parsers/gas/gas-bison.y [new file with mode: 0644]
modules/parsers/gas/gas-defs.h [new file with mode: 0644]
modules/parsers/gas/gas-parser.c [new file with mode: 0644]
modules/parsers/gas/gas-parser.h [new file with mode: 0644]
modules/parsers/gas/gas-token.re [new file with mode: 0644]
modules/parsers/gas/tests/Makefile.inc [new file with mode: 0644]
modules/parsers/gas/tests/amd64/Makefile.inc [new file with mode: 0644]
modules/parsers/gas/tests/amd64/gas_amd64_test.sh [new file with mode: 0755]
modules/parsers/gas/tests/amd64/riprel.asm [new file with mode: 0644]
modules/parsers/gas/tests/amd64/riprel.errwarn [new file with mode: 0644]
modules/parsers/gas/tests/amd64/riprel.hex [new file with mode: 0644]
modules/parsers/gas/tests/datavis.asm [new file with mode: 0644]
modules/parsers/gas/tests/datavis.errwarn [new file with mode: 0644]
modules/parsers/gas/tests/datavis.hex [new file with mode: 0644]
modules/parsers/gas/tests/datavis2.asm [new file with mode: 0644]
modules/parsers/gas/tests/datavis2.errwarn [new file with mode: 0644]
modules/parsers/gas/tests/datavis2.hex [new file with mode: 0644]
modules/parsers/gas/tests/gas_test.sh [new file with mode: 0755]
modules/parsers/gas/tests/jmpcall.asm [new file with mode: 0644]
modules/parsers/gas/tests/jmpcall.errwarn [new file with mode: 0644]
modules/parsers/gas/tests/jmpcall.hex [new file with mode: 0644]
modules/parsers/gas/tests/reggroup-err.asm [new file with mode: 0644]
modules/parsers/gas/tests/reggroup-err.errwarn [new file with mode: 0644]
modules/parsers/gas/tests/reggroup.asm [new file with mode: 0644]
modules/parsers/gas/tests/reggroup.errwarn [new file with mode: 0644]
modules/parsers/gas/tests/reggroup.hex [new file with mode: 0644]

index 10e39c8fc4b10f7f0a2c2cec72fadc1d245fa133..27eb8a210067961cb3b4832f9379f0427a1b47b2 100644 (file)
@@ -611,7 +611,9 @@ main(int argc, char *argv[])
        fclose(in);
 
     /* Check for undefined symbols */
-    yasm_symtab_parser_finalize(yasm_object_get_symtab(object), 0, NULL);
+    yasm_symtab_parser_finalize(yasm_object_get_symtab(object),
+                               strcmp(cur_parser_module->keyword, "gas")==0,
+                               cur_objfmt);
 
     if (yasm_get_num_errors(warning_error) > 0) {
        yasm_errwarn_output_all(yasm_object_get_linemap(object), warning_error,
index 140f259ab8241c3099ec3fc37167981ae3a5595c..90f7a2333917443d0d6a4975f322aa61e131aef3 100644 (file)
@@ -47,6 +47,7 @@ yasm_operand_create_reg(unsigned long reg)
     retval->data.reg = reg;
     retval->targetmod = 0;
     retval->size = 0;
+    retval->deref = 0;
 
     return retval;
 }
@@ -60,6 +61,7 @@ yasm_operand_create_segreg(unsigned long segreg)
     retval->data.reg = segreg;
     retval->targetmod = 0;
     retval->size = 0;
+    retval->deref = 0;
 
     return retval;
 }
@@ -73,6 +75,7 @@ yasm_operand_create_mem(/*@only@*/ yasm_effaddr *ea)
     retval->data.ea = ea;
     retval->targetmod = 0;
     retval->size = 0;
+    retval->deref = 0;
 
     return retval;
 }
@@ -93,6 +96,7 @@ yasm_operand_create_imm(/*@only@*/ yasm_expr *val)
        retval->data.val = val;
        retval->targetmod = 0;
        retval->size = 0;
+       retval->deref = 0;
     }
 
     return retval;
index 760c869fceb74651134cec5a670af51c6085c19a..f3e704f2e77b919204f1f2fd99c67c22cfe26fec 100644 (file)
@@ -246,6 +246,16 @@ struct yasm_insn_operand {
 
     /** Specified size of the operand, in bytes.  0 if not user-specified. */
     unsigned int size;
+
+    /** Nonzero if dereference.  Used for "*foo" in GAS.
+     * The reason for this is that by default in GAS, an unprefixed value
+     * is a memory address, except for jumps/calls, in which case it needs a
+     * "*" prefix to become a memory address (otherwise it's an immediate).
+     * This isn't knowable in the parser stage, so the parser sets this flag
+     * to indicate the "*" prefix has been used, and the arch needs to adjust
+     * the operand type appropriately depending on the instruction type.
+     */
+    int deref;
 };
 #endif
 
index 251e53d0843747854694556241600313715ecb8d..fbf8fced2b316dcccead49b2e9fdd915b8eeaa7e 100644 (file)
@@ -42,6 +42,10 @@ struct yasm_effaddr {
                                 */
     unsigned char nosplit;     /* 1 if reg*2 should not be split into
                                   reg+reg. (0 if not) */
+    unsigned char strong;      /* 1 if effective address is *definitely*
+                                * an effective address, e.g. in GAS if
+                                * expr(,1) form is used vs. just expr.
+                                */
 };
 
 struct yasm_immval {
index 05636a73901c0e91e35cecfea5f44a712e5aa745..2c212b0489a9ac23bfa2b308ba36c993b9d82aa4 100644 (file)
@@ -238,6 +238,15 @@ yasm_ea_set_nosplit(yasm_effaddr *ptr, unsigned int nosplit)
     ptr->nosplit = (unsigned char)nosplit;
 }
 
+void
+yasm_ea_set_strong(yasm_effaddr *ptr, unsigned int strong)
+{
+    if (!ptr)
+       return;
+
+    ptr->strong = (unsigned char)strong;
+}
+
 void
 yasm_ea_set_segreg(yasm_effaddr *ea, unsigned long segreg, unsigned long line)
 {
index 1bd9bbfcd4e635eb4a9991f82d90d56183ac9f19..79d940b9788d884fd132994e5d1c33f933a2f408 100644 (file)
@@ -92,6 +92,16 @@ void yasm_ea_set_len(yasm_effaddr *ea, unsigned int len);
  */
 void yasm_ea_set_nosplit(yasm_effaddr *ea, unsigned int nosplit);
 
+/** Set/clear strong flag of an effective address.
+ * The strong flag indicates if an effective address is *definitely* an
+ * effective address.  This is used in e.g. the GAS parser to differentiate
+ * between "expr" (which might or might not be an effective address) and
+ * "expr(,1)" (which is definitely an effective address).
+ * \param ea           effective address
+ * \param strong       strong flag setting (0=not strong, nonzero=strong)
+ */
+void yasm_ea_set_strong(yasm_effaddr *ea, unsigned int strong);
+
 /** Set segment override for an effective address.
  * Some architectures (such as x86) support segment overrides on effective
  * addresses.  A override of an override will result in a warning.
index eed01ce87eb048058d718fe0f9aa5ffaf45fc8d8..bdb23c8d0baaec1a4d0cd0dcdfca4e6391ab57d6 100644 (file)
@@ -62,7 +62,11 @@ x86_create(const char *machine, const char *parser,
     arch_x86->amd64_machine = amd64_machine;
     arch_x86->mode_bits = 0;
 
-    if (yasm__strcasecmp(parser, "nasm") != 0) {
+    if (yasm__strcasecmp(parser, "nasm") == 0)
+       arch_x86->parser = X86_PARSER_NASM;
+    else if (yasm__strcasecmp(parser, "gas") == 0)
+       arch_x86->parser = X86_PARSER_GAS;
+    else {
        yasm_xfree(arch_x86);
        *error = YASM_ARCH_CREATE_BAD_PARSER;
        return NULL;
index 84b434512a9705b2e8cf3910442ebb4ab85d6f1a..c3140e291b157d12b1a6a63d75ba3c64caf220af 100644 (file)
@@ -68,6 +68,10 @@ typedef struct yasm_arch_x86 {
     /* What instructions/features are enabled? */
     unsigned long cpu_enabled;
     unsigned int amd64_machine;
+    enum {
+       X86_PARSER_NASM,
+       X86_PARSER_GAS
+    } parser;
     unsigned char mode_bits;
 } yasm_arch_x86;
 
index c35274e9c883ed11704d840ddc79e72e87f014e7..1d7114a5c26785a807aa69ecb6f886f093cf2037 100644 (file)
@@ -206,6 +206,7 @@ yasm_x86__ea_create_reg(unsigned long reg, unsigned char *rex,
     x86_ea->ea.disp = (yasm_expr *)NULL;
     x86_ea->ea.len = 0;
     x86_ea->ea.nosplit = 0;
+    x86_ea->ea.strong = 0;
     x86_ea->ea.segreg = 0;
     x86_ea->modrm = 0xC0 | rm; /* Mod=11, R/M=Reg, Reg=0 */
     x86_ea->valid_modrm = 1;
@@ -221,11 +222,27 @@ yasm_x86__ea_create_reg(unsigned long reg, unsigned char *rex,
 yasm_effaddr *
 yasm_x86__ea_create_expr(yasm_arch *arch, yasm_expr *e)
 {
+    yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
     x86_effaddr *x86_ea;
 
     x86_ea = yasm_xmalloc(sizeof(x86_effaddr));
 
     x86_ea->ea.callback = &x86_ea_callback;
+    if (arch_x86->parser == X86_PARSER_GAS) {
+       /* Need to change foo+rip into foo wrt rip.
+        * Note this assumes a particular ordering coming from the parser
+        * to work (it's not very smart)!
+        */
+       if (e->op == YASM_EXPR_ADD && e->terms[0].type == YASM_EXPR_REG
+           && e->terms[0].data.reg == X86_RIP) {
+           /* replace register with 0 */
+           e->terms[0].type = YASM_EXPR_INT;
+           e->terms[0].data.intn = yasm_intnum_create_uint(0);
+           /* build new wrt expression */
+           e = yasm_expr_create(YASM_EXPR_WRT, yasm_expr_expr(e),
+                                yasm_expr_reg(X86_RIP), e->line);
+       }
+    }
     x86_ea->ea.disp = e;
     x86_ea->ea.len = 0;
     x86_ea->ea.nosplit = 0;
index 5bf90e262614d2e6e16ce5da046c992df5d02d65..96b5d660fb56880f0359fa6f6316b7c3df531483 100644 (file)
@@ -52,6 +52,17 @@ RCSID("$Id$");
 #define MOD_AdSizeR (1UL<<10)  /* Parameter replaces addrsize (jmp only) */
 #define MOD_DOpS64R (1UL<<11)  /* Parameter replaces default 64-bit opersize */
 
+/* Modifiers that aren't: these are used with the GAS parser to indicate
+ * special cases.
+ */
+#define MOD_GasNoRev   (1UL<<15)       /* Don't reverse operands */
+#define MOD_GasSufB    (1UL<<16)       /* GAS B suffix ok */
+#define MOD_GasSufW    (1UL<<17)       /* GAS W suffix ok */
+#define MOD_GasSufL    (1UL<<18)       /* GAS L suffix ok */
+#define MOD_GasSufQ    (1UL<<19)       /* GAS Q suffix ok */
+#define MOD_GasSuf_SHIFT 16
+#define MOD_GasSuf_MASK        (0xFUL<<16)
+
 /* Modifiers that aren't actually used as modifiers.  Rather, if set, bits
  * 20-27 in the modifier are used as an index into an array.
  * Obviously, only one of these may be set at a time.
@@ -255,7 +266,9 @@ typedef struct x86_insn_info {
     unsigned long operands[3];
 } x86_insn_info;
 
-/* Define lexer arch-specific data with 0-3 modifiers. */
+/* Define lexer arch-specific data with 0-3 modifiers.
+ * This assumes arch_x86 is locally defined.
+ */
 #define DEF_INSN_DATA(group, mod, cpu) do { \
     data[0] = (unsigned long)group##_insn; \
     data[1] = ((mod)<<8) | \
@@ -264,11 +277,6 @@ typedef struct x86_insn_info {
     data[3] = arch_x86->mode_bits; \
     } while (0)
 
-#define RET_INSN(group, mod, cpu)      do { \
-    DEF_INSN_DATA(group, mod, cpu); \
-    return YASM_ARCH_CHECK_ID_INSN; \
-    } while (0)
-
 /*
  * General instruction groupings
  */
@@ -338,21 +346,21 @@ static const x86_insn_info vmxthreebytemem_insn[] = {
 /* Move instructions */
 static const x86_insn_info mov_insn[] = {
     /* Absolute forms for non-64-bit mode */
-    { CPU_Not64, 0, 0, 0, 0, 1, {0xA0, 0, 0}, 0, 2,
+    { CPU_Not64, MOD_GasSufB, 0, 0, 0, 1, {0xA0, 0, 0}, 0, 2,
       {OPT_Areg|OPS_8|OPA_None, OPT_MemOffs|OPS_8|OPS_Relaxed|OPA_EA, 0} },
-    { CPU_Not64, 0, 16, 0, 0, 1, {0xA1, 0, 0}, 0, 2,
+    { CPU_Not64, MOD_GasSufW, 16, 0, 0, 1, {0xA1, 0, 0}, 0, 2,
       {OPT_Areg|OPS_16|OPA_None, OPT_MemOffs|OPS_16|OPS_Relaxed|OPA_EA, 0} },
-    { CPU_386|CPU_Not64, 0, 32, 0, 0, 1, {0xA1, 0, 0}, 0, 2,
+    { CPU_386|CPU_Not64, MOD_GasSufL, 32, 0, 0, 1, {0xA1, 0, 0}, 0, 2,
       {OPT_Areg|OPS_32|OPA_None, OPT_MemOffs|OPS_32|OPS_Relaxed|OPA_EA, 0} },
 
-    { CPU_Not64, 0, 0, 0, 0, 1, {0xA2, 0, 0}, 0, 2,
+    { CPU_Not64, MOD_GasSufB, 0, 0, 0, 1, {0xA2, 0, 0}, 0, 2,
       {OPT_MemOffs|OPS_8|OPS_Relaxed|OPA_EA, OPT_Areg|OPS_8|OPA_None, 0} },
-    { CPU_Not64, 0, 16, 0, 0, 1, {0xA3, 0, 0}, 0, 2,
+    { CPU_Not64, MOD_GasSufW, 16, 0, 0, 1, {0xA3, 0, 0}, 0, 2,
       {OPT_MemOffs|OPS_16|OPS_Relaxed|OPA_EA, OPT_Areg|OPS_16|OPA_None, 0} },
-    { CPU_386|CPU_Not64, 0, 32, 0, 0, 1, {0xA3, 0, 0}, 0, 2,
+    { CPU_386|CPU_Not64, MOD_GasSufL, 32, 0, 0, 1, {0xA3, 0, 0}, 0, 2,
       {OPT_MemOffs|OPS_32|OPS_Relaxed|OPA_EA, OPT_Areg|OPS_32|OPA_None, 0} },
 
-    /* 64-bit absolute forms for 64-bit mode */
+    /* 64-bit absolute forms for 64-bit mode.  Disabled for GAS, see movabs */
     { CPU_Hammer|CPU_64, 0, 0, 0, 0, 1, {0xA0, 0, 0}, 0, 2,
       {OPT_Areg|OPS_8|OPA_None,
        OPT_MemOffs|OPS_8|OPS_Relaxed|OPEAS_64|OPA_EA, 0} },
@@ -380,121 +388,156 @@ static const x86_insn_info mov_insn[] = {
        OPT_Areg|OPS_64|OPA_None, 0} },
 
     /* General 32-bit forms using Areg / short absolute option */
-    { CPU_Any, 0, 0, 0, 0, 1, {0x88, 0xA2, 0}, 0, 2,
+    { CPU_Any, MOD_GasSufB, 0, 0, 0, 1, {0x88, 0xA2, 0}, 0, 2,
       {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA|OPAP_ShortMov, OPT_Areg|OPS_8|OPA_Spare,
        0} },
-    { CPU_Any, 0, 16, 0, 0, 1, {0x89, 0xA3, 0}, 0, 2,
+    { CPU_Any, MOD_GasSufW, 16, 0, 0, 1, {0x89, 0xA3, 0}, 0, 2,
       {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA|OPAP_ShortMov,
        OPT_Areg|OPS_16|OPA_Spare, 0} },
-    { CPU_386, 0, 32, 0, 0, 1, {0x89, 0xA3, 0}, 0, 2,
+    { CPU_386, MOD_GasSufL, 32, 0, 0, 1, {0x89, 0xA3, 0}, 0, 2,
       {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA|OPAP_ShortMov,
        OPT_Areg|OPS_32|OPA_Spare, 0} },
-    { CPU_Hammer|CPU_64, 0, 64, 0, 0, 1, {0x89, 0xA3, 0}, 0, 2,
+    { CPU_Hammer|CPU_64, MOD_GasSufQ, 64, 0, 0, 1, {0x89, 0xA3, 0}, 0, 2,
       {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA|OPAP_ShortMov,
        OPT_Areg|OPS_64|OPA_Spare, 0} },
 
     /* General 32-bit forms */
-    { CPU_Any, 0, 0, 0, 0, 1, {0x88, 0, 0}, 0, 2,
+    { CPU_Any, MOD_GasSufB, 0, 0, 0, 1, {0x88, 0, 0}, 0, 2,
       {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_8|OPA_Spare, 0} },
-    { CPU_Any, 0, 16, 0, 0, 1, {0x89, 0, 0}, 0, 2,
+    { CPU_Any, MOD_GasSufW, 16, 0, 0, 1, {0x89, 0, 0}, 0, 2,
       {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, 0} },
-    { CPU_386, 0, 32, 0, 0, 1, {0x89, 0, 0}, 0, 2,
+    { CPU_386, MOD_GasSufL, 32, 0, 0, 1, {0x89, 0, 0}, 0, 2,
       {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, 0} },
-    { CPU_Hammer|CPU_64, 0, 64, 0, 0, 1, {0x89, 0, 0}, 0, 2,
+    { CPU_Hammer|CPU_64, MOD_GasSufQ, 64, 0, 0, 1, {0x89, 0, 0}, 0, 2,
       {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, 0} },
 
     /* General 32-bit forms using Areg / short absolute option */
-    { CPU_Any, 0, 0, 0, 0, 1, {0x8A, 0xA0, 0}, 0, 2,
+    { CPU_Any, MOD_GasSufB, 0, 0, 0, 1, {0x8A, 0xA0, 0}, 0, 2,
       {OPT_Areg|OPS_8|OPA_Spare, OPT_RM|OPS_8|OPS_Relaxed|OPA_EA|OPAP_ShortMov,
        0} },
-    { CPU_Any, 0, 16, 0, 0, 1, {0x8B, 0xA1, 0}, 0, 2,
+    { CPU_Any, MOD_GasSufW, 16, 0, 0, 1, {0x8B, 0xA1, 0}, 0, 2,
       {OPT_Areg|OPS_16|OPA_Spare,
        OPT_RM|OPS_16|OPS_Relaxed|OPA_EA|OPAP_ShortMov, 0} },
-    { CPU_386, 0, 32, 0, 0, 1, {0x8B, 0xA1, 0}, 0, 2,
+    { CPU_386, MOD_GasSufL, 32, 0, 0, 1, {0x8B, 0xA1, 0}, 0, 2,
       {OPT_Areg|OPS_32|OPA_Spare,
        OPT_RM|OPS_32|OPS_Relaxed|OPA_EA|OPAP_ShortMov, 0} },
-    { CPU_Hammer|CPU_64, 0, 64, 0, 0, 1, {0x8B, 0xA1, 0}, 0, 2,
+    { CPU_Hammer|CPU_64, MOD_GasSufQ, 64, 0, 0, 1, {0x8B, 0xA1, 0}, 0, 2,
       {OPT_Areg|OPS_64|OPA_Spare,
        OPT_RM|OPS_64|OPS_Relaxed|OPA_EA|OPAP_ShortMov, 0} },
 
     /* General 32-bit forms */
-    { CPU_Any, 0, 0, 0, 0, 1, {0x8A, 0, 0}, 0, 2,
+    { CPU_Any, MOD_GasSufB, 0, 0, 0, 1, {0x8A, 0, 0}, 0, 2,
       {OPT_Reg|OPS_8|OPA_Spare, OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, 0} },
-    { CPU_Any, 0, 16, 0, 0, 1, {0x8B, 0, 0}, 0, 2,
+    { CPU_Any, MOD_GasSufW, 16, 0, 0, 1, {0x8B, 0, 0}, 0, 2,
       {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0} },
-    { CPU_386, 0, 32, 0, 0, 1, {0x8B, 0, 0}, 0, 2,
+    { CPU_386, MOD_GasSufL, 32, 0, 0, 1, {0x8B, 0, 0}, 0, 2,
       {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} },
-    { CPU_Hammer|CPU_64, 0, 64, 0, 0, 1, {0x8B, 0, 0}, 0, 2,
+    { CPU_Hammer|CPU_64, MOD_GasSufQ, 64, 0, 0, 1, {0x8B, 0, 0}, 0, 2,
       {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, 0} },
 
     /* Segment register forms */
-    { CPU_Any, 0, 0, 0, 0, 1, {0x8C, 0, 0}, 0, 2,
+    { CPU_Any, MOD_GasSufW, 0, 0, 0, 1, {0x8C, 0, 0}, 0, 2,
       {OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA,
        OPT_SegReg|OPS_16|OPS_Relaxed|OPA_Spare, 0} },
-    { CPU_Any, 0, 16, 0, 0, 1, {0x8C, 0, 0}, 0, 2,
+    { CPU_Any, MOD_GasSufW, 16, 0, 0, 1, {0x8C, 0, 0}, 0, 2,
       {OPT_Reg|OPS_16|OPA_EA, OPT_SegReg|OPS_16|OPS_Relaxed|OPA_Spare, 0} },
-    { CPU_386, 0, 32, 0, 0, 1, {0x8C, 0, 0}, 0, 2,
+    { CPU_386, MOD_GasSufL, 32, 0, 0, 1, {0x8C, 0, 0}, 0, 2,
       {OPT_Reg|OPS_32|OPA_EA, OPT_SegReg|OPS_16|OPS_Relaxed|OPA_Spare, 0} },
-    { CPU_Hammer|CPU_64, 0, 64, 0, 0, 1, {0x8C, 0, 0}, 0, 2,
+    { CPU_Hammer|CPU_64, MOD_GasSufQ, 64, 0, 0, 1, {0x8C, 0, 0}, 0, 2,
       {OPT_Reg|OPS_64|OPA_EA, OPT_SegReg|OPS_16|OPS_Relaxed|OPA_Spare, 0} },
 
-    { CPU_Any, 0, 0, 0, 0, 1, {0x8E, 0, 0}, 0, 2,
+    { CPU_Any, MOD_GasSufW, 0, 0, 0, 1, {0x8E, 0, 0}, 0, 2,
       {OPT_SegReg|OPS_16|OPS_Relaxed|OPA_Spare,
        OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0} },
-    { CPU_386, 0, 0, 0, 0, 1, {0x8E, 0, 0}, 0, 2,
+    { CPU_386, MOD_GasSufL, 0, 0, 0, 1, {0x8E, 0, 0}, 0, 2,
       {OPT_SegReg|OPS_16|OPS_Relaxed|OPA_Spare, OPT_Reg|OPS_32|OPA_EA, 0} },
-    { CPU_Hammer|CPU_64, 0, 0, 0, 0, 1, {0x8E, 0, 0}, 0, 2,
+    { CPU_Hammer|CPU_64, MOD_GasSufQ, 0, 0, 0, 1, {0x8E, 0, 0}, 0, 2,
       {OPT_SegReg|OPS_16|OPS_Relaxed|OPA_Spare, OPT_Reg|OPS_64|OPA_EA, 0} },
 
     /* Immediate forms */
-    { CPU_Any, 0, 0, 0, 0, 1, {0xB0, 0, 0}, 0, 2,
+    { CPU_Any, MOD_GasSufB, 0, 0, 0, 1, {0xB0, 0, 0}, 0, 2,
       {OPT_Reg|OPS_8|OPA_Op0Add, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} },
-    { CPU_Any, 0, 16, 0, 0, 1, {0xB8, 0, 0}, 0, 2,
+    { CPU_Any, MOD_GasSufW, 16, 0, 0, 1, {0xB8, 0, 0}, 0, 2,
       {OPT_Reg|OPS_16|OPA_Op0Add, OPT_Imm|OPS_16|OPS_Relaxed|OPA_Imm, 0} },
-    { CPU_386, 0, 32, 0, 0, 1, {0xB8, 0, 0}, 0, 2,
+    { CPU_386, MOD_GasSufL, 32, 0, 0, 1, {0xB8, 0, 0}, 0, 2,
       {OPT_Reg|OPS_32|OPA_Op0Add, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} },
-    { CPU_Hammer|CPU_64, 0, 64, 0, 0, 1, {0xB8, 0, 0}, 0, 2,
+    { CPU_Hammer|CPU_64, MOD_GasSufQ, 64, 0, 0, 1, {0xB8, 0, 0}, 0, 2,
       {OPT_Reg|OPS_64|OPA_Op0Add, OPT_Imm|OPS_64|OPS_Relaxed|OPA_Imm, 0} },
     /* Need two sets here, one for strictness on left side, one for right. */
-    { CPU_Any, 0, 0, 0, 0, 1, {0xC6, 0, 0}, 0, 2,
+    { CPU_Any, MOD_GasSufB, 0, 0, 0, 1, {0xC6, 0, 0}, 0, 2,
       {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_8|OPA_Imm, 0} },
-    { CPU_Any, 0, 16, 0, 0, 1, {0xC7, 0, 0}, 0, 2,
+    { CPU_Any, MOD_GasSufW, 16, 0, 0, 1, {0xC7, 0, 0}, 0, 2,
       {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_16|OPA_Imm, 0} },
-    { CPU_386, 0, 32, 0, 0, 1, {0xC7, 0, 0}, 0, 2,
+    { CPU_386, MOD_GasSufL, 32, 0, 0, 1, {0xC7, 0, 0}, 0, 2,
       {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_32|OPA_Imm, 0} },
-    { CPU_Hammer|CPU_64, 0, 64, 0, 0, 1, {0xC7, 0, 0}, 0, 2,
+    { CPU_Hammer|CPU_64, MOD_GasSufQ, 64, 0, 0, 1, {0xC7, 0, 0}, 0, 2,
       {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_32|OPA_Imm, 0} },
-    { CPU_Any, 0, 0, 0, 0, 1, {0xC6, 0, 0}, 0, 2,
+    { CPU_Any, MOD_GasSufB, 0, 0, 0, 1, {0xC6, 0, 0}, 0, 2,
       {OPT_RM|OPS_8|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} },
-    { CPU_Any, 0, 16, 0, 0, 1, {0xC7, 0, 0}, 0, 2,
+    { CPU_Any, MOD_GasSufW, 16, 0, 0, 1, {0xC7, 0, 0}, 0, 2,
       {OPT_RM|OPS_16|OPA_EA, OPT_Imm|OPS_16|OPS_Relaxed|OPA_Imm, 0} },
-    { CPU_386, 0, 32, 0, 0, 1, {0xC7, 0, 0}, 0, 2,
+    { CPU_386, MOD_GasSufL, 32, 0, 0, 1, {0xC7, 0, 0}, 0, 2,
       {OPT_RM|OPS_32|OPA_EA, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} },
-    { CPU_Hammer|CPU_64, 0, 64, 0, 0, 1, {0xC7, 0, 0}, 0, 2,
+    { CPU_Hammer|CPU_64, MOD_GasSufQ, 64, 0, 0, 1, {0xC7, 0, 0}, 0, 2,
       {OPT_RM|OPS_64|OPA_EA, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} },
 
     /* CR/DR forms */
-    { CPU_586|CPU_Priv|CPU_Not64, 0, 0, 0, 0, 2, {0x0F, 0x22, 0}, 0, 2,
-      {OPT_CR4|OPS_32|OPA_Spare, OPT_Reg|OPS_32|OPA_EA, 0} },
-    { CPU_386|CPU_Priv|CPU_Not64, 0, 0, 0, 0, 2, {0x0F, 0x22, 0}, 0, 2,
-      {OPT_CRReg|OPS_32|OPA_Spare, OPT_Reg|OPS_32|OPA_EA, 0} },
-    { CPU_Hammer|CPU_Priv|CPU_64, 0, 0, 0, 0, 2, {0x0F, 0x22, 0}, 0, 2,
-      {OPT_CRReg|OPS_32|OPA_Spare, OPT_Reg|OPS_64|OPA_EA, 0} },
-    { CPU_586|CPU_Priv|CPU_Not64, 0, 0, 0, 0, 2, {0x0F, 0x20, 0}, 0, 2,
-      {OPT_Reg|OPS_32|OPA_EA, OPT_CR4|OPS_32|OPA_Spare, 0} },
-    { CPU_386|CPU_Priv|CPU_Not64, 0, 0, 0, 0, 2, {0x0F, 0x20, 0}, 0, 2,
-      {OPT_Reg|OPS_32|OPA_EA, OPT_CRReg|OPS_32|OPA_Spare, 0} },
-    { CPU_Hammer|CPU_Priv|CPU_64, 0, 0, 0, 0, 2, {0x0F, 0x20, 0}, 0, 2,
-      {OPT_Reg|OPS_64|OPA_EA, OPT_CRReg|OPS_32|OPA_Spare, 0} },
-
-    { CPU_386|CPU_Priv|CPU_Not64, 0, 0, 0, 0, 2, {0x0F, 0x23, 0}, 0, 2,
-      {OPT_DRReg|OPS_32|OPA_Spare, OPT_Reg|OPS_32|OPA_EA, 0} },
-    { CPU_Hammer|CPU_Priv|CPU_64, 0, 0, 0, 0, 2, {0x0F, 0x23, 0}, 0, 2,
-      {OPT_DRReg|OPS_32|OPA_Spare, OPT_Reg|OPS_64|OPA_EA, 0} },
-    { CPU_386|CPU_Priv|CPU_Not64, 0, 0, 0, 0, 2, {0x0F, 0x21, 0}, 0, 2,
-      {OPT_Reg|OPS_32|OPA_EA, OPT_DRReg|OPS_32|OPA_Spare, 0} },
-    { CPU_Hammer|CPU_Priv|CPU_64, 0, 0, 0, 0, 2, {0x0F, 0x21, 0}, 0, 2,
-      {OPT_Reg|OPS_64|OPA_EA, OPT_DRReg|OPS_32|OPA_Spare, 0} }
+    { CPU_586|CPU_Priv|CPU_Not64, MOD_GasSufL, 0, 0, 0, 2, {0x0F, 0x22, 0}, 0,
+      2, {OPT_CR4|OPS_32|OPA_Spare, OPT_Reg|OPS_32|OPA_EA, 0} },
+    { CPU_386|CPU_Priv|CPU_Not64, MOD_GasSufL, 0, 0, 0, 2, {0x0F, 0x22, 0}, 0,
+      2, {OPT_CRReg|OPS_32|OPA_Spare, OPT_Reg|OPS_32|OPA_EA, 0} },
+    { CPU_Hammer|CPU_Priv|CPU_64, MOD_GasSufL, 0, 0, 0, 2, {0x0F, 0x22, 0}, 0,
+      2, {OPT_CRReg|OPS_32|OPA_Spare, OPT_Reg|OPS_64|OPA_EA, 0} },
+    { CPU_586|CPU_Priv|CPU_Not64, MOD_GasSufL, 0, 0, 0, 2, {0x0F, 0x20, 0}, 0,
+      2, {OPT_Reg|OPS_32|OPA_EA, OPT_CR4|OPS_32|OPA_Spare, 0} },
+    { CPU_386|CPU_Priv|CPU_Not64, MOD_GasSufL, 0, 0, 0, 2, {0x0F, 0x20, 0}, 0,
+      2, {OPT_Reg|OPS_32|OPA_EA, OPT_CRReg|OPS_32|OPA_Spare, 0} },
+    { CPU_Hammer|CPU_Priv|CPU_64, MOD_GasSufQ, 0, 0, 0, 2, {0x0F, 0x20, 0}, 0,
+      2, {OPT_Reg|OPS_64|OPA_EA, OPT_CRReg|OPS_32|OPA_Spare, 0} },
+
+    { CPU_386|CPU_Priv|CPU_Not64, MOD_GasSufL, 0, 0, 0, 2, {0x0F, 0x23, 0}, 0,
+      2, {OPT_DRReg|OPS_32|OPA_Spare, OPT_Reg|OPS_32|OPA_EA, 0} },
+    { CPU_Hammer|CPU_Priv|CPU_64, MOD_GasSufL, 0, 0, 0, 2, {0x0F, 0x23, 0}, 0,
+      2, {OPT_DRReg|OPS_32|OPA_Spare, OPT_Reg|OPS_64|OPA_EA, 0} },
+    { CPU_386|CPU_Priv|CPU_Not64, MOD_GasSufL, 0, 0, 0, 2, {0x0F, 0x21, 0}, 0,
+      2, {OPT_Reg|OPS_32|OPA_EA, OPT_DRReg|OPS_32|OPA_Spare, 0} },
+    { CPU_Hammer|CPU_Priv|CPU_64, MOD_GasSufQ, 0, 0, 0, 2, {0x0F, 0x21, 0}, 0,
+      2, {OPT_Reg|OPS_64|OPA_EA, OPT_DRReg|OPS_32|OPA_Spare, 0} }
+};
+
+/* 64-bit absolute move (for GAS).
+ * These are disabled for GAS for normal mov above.
+ */
+static const x86_insn_info movabs_insn[] = {
+    { CPU_Hammer|CPU_64, MOD_GasSufB, 0, 0, 0, 1, {0xA0, 0, 0}, 0, 2,
+      {OPT_Areg|OPS_8|OPA_None,
+       OPT_MemOffs|OPS_8|OPS_Relaxed|OPEAS_64|OPA_EA, 0} },
+    { CPU_Hammer|CPU_64, MOD_GasSufW, 16, 0, 0, 1, {0xA1, 0, 0}, 0, 2,
+      {OPT_Areg|OPS_16|OPA_None,
+       OPT_MemOffs|OPS_16|OPS_Relaxed|OPEAS_64|OPA_EA, 0} },
+    { CPU_Hammer|CPU_64, MOD_GasSufL, 32, 0, 0, 1, {0xA1, 0, 0}, 0, 2,
+      {OPT_Areg|OPS_32|OPA_None,
+       OPT_MemOffs|OPS_32|OPS_Relaxed|OPEAS_64|OPA_EA, 0} },
+    { CPU_Hammer|CPU_64, MOD_GasSufQ, 64, 0, 0, 1, {0xA1, 0, 0}, 0, 2,
+      {OPT_Areg|OPS_64|OPA_None,
+       OPT_MemOffs|OPS_64|OPS_Relaxed|OPEAS_64|OPA_EA, 0} },
+
+    { CPU_Hammer|CPU_64, MOD_GasSufB, 0, 0, 0, 1, {0xA2, 0, 0}, 0, 2,
+      {OPT_MemOffs|OPS_8|OPS_Relaxed|OPEAS_64|OPA_EA,
+       OPT_Areg|OPS_8|OPA_None, 0} },
+    { CPU_Hammer|CPU_64, MOD_GasSufW, 16, 0, 0, 1, {0xA3, 0, 0}, 0, 2,
+      {OPT_MemOffs|OPS_16|OPS_Relaxed|OPEAS_64|OPA_EA,
+       OPT_Areg|OPS_16|OPA_None, 0} },
+    { CPU_Hammer|CPU_64, MOD_GasSufL, 32, 0, 0, 1, {0xA3, 0, 0}, 0, 2,
+      {OPT_MemOffs|OPS_32|OPS_Relaxed|OPEAS_64|OPA_EA,
+       OPT_Areg|OPS_32|OPA_None, 0} },
+    { CPU_Hammer|CPU_64, MOD_GasSufQ, 64, 0, 0, 1, {0xA3, 0, 0}, 0, 2,
+      {OPT_MemOffs|OPS_64|OPS_Relaxed|OPEAS_64|OPA_EA,
+       OPT_Areg|OPS_64|OPA_None, 0} },
+
+    /* 64-bit immediate form */
+    { CPU_Hammer|CPU_64, MOD_GasSufQ, 64, 0, 0, 1, {0xB8, 0, 0}, 0, 2,
+      {OPT_Reg|OPS_64|OPA_Op0Add, OPT_Imm|OPS_64|OPS_Relaxed|OPA_Imm, 0} },
 };
 
 /* Move with sign/zero extend */
@@ -519,61 +562,61 @@ static const x86_insn_info movsxd_insn[] = {
 
 /* Push instructions */
 static const x86_insn_info push_insn[] = {
-    { CPU_Any, 0, 16, 64, 0, 1, {0x50, 0, 0}, 0, 1,
+    { CPU_Any, MOD_GasSufW, 16, 64, 0, 1, {0x50, 0, 0}, 0, 1,
       {OPT_Reg|OPS_16|OPA_Op0Add, 0, 0} },
-    { CPU_386|CPU_Not64, 0, 32, 0, 0, 1, {0x50, 0, 0}, 0, 1,
+    { CPU_386|CPU_Not64, MOD_GasSufL, 32, 0, 0, 1, {0x50, 0, 0}, 0, 1,
       {OPT_Reg|OPS_32|OPA_Op0Add, 0, 0} },
-    { CPU_Hammer|CPU_64, 0, 0, 64, 0, 1, {0x50, 0, 0}, 0, 1,
+    { CPU_Hammer|CPU_64, MOD_GasSufQ, 0, 64, 0, 1, {0x50, 0, 0}, 0, 1,
       {OPT_Reg|OPS_64|OPA_Op0Add, 0, 0} },
-    { CPU_Any, 0, 16, 64, 0, 1, {0xFF, 0, 0}, 6, 1,
+    { CPU_Any, MOD_GasSufW, 16, 64, 0, 1, {0xFF, 0, 0}, 6, 1,
       {OPT_RM|OPS_16|OPA_EA, 0, 0} },
-    { CPU_386|CPU_Not64, 0, 32, 0, 0, 1, {0xFF, 0, 0}, 6, 1,
+    { CPU_386|CPU_Not64, MOD_GasSufL, 32, 0, 0, 1, {0xFF, 0, 0}, 6, 1,
       {OPT_RM|OPS_32|OPA_EA, 0, 0} },
-    { CPU_Hammer|CPU_64, 0, 0, 64, 0, 1, {0xFF, 0, 0}, 6, 1,
+    { CPU_Hammer|CPU_64, MOD_GasSufQ, 0, 64, 0, 1, {0xFF, 0, 0}, 6, 1,
       {OPT_RM|OPS_64|OPA_EA, 0, 0} },
-    { CPU_Any, 0, 0, 64, 0, 1, {0x6A, 0, 0}, 0, 1,
+    { CPU_Any, MOD_GasSufQ, 0, 64, 0, 1, {0x6A, 0, 0}, 0, 1,
       {OPT_Imm|OPS_8|OPA_SImm, 0, 0} },
-    { CPU_Any, 0, 16, 64, 0, 1, {0x68, 0, 0}, 0, 1,
+    { CPU_Any, MOD_GasSufW, 16, 64, 0, 1, {0x68, 0, 0}, 0, 1,
       {OPT_Imm|OPS_16|OPA_Imm, 0, 0} },
-    { CPU_386|CPU_Not64, 0, 32, 0, 0, 1, {0x68, 0, 0}, 0, 1,
+    { CPU_386|CPU_Not64, MOD_GasSufL, 32, 0, 0, 1, {0x68, 0, 0}, 0, 1,
       {OPT_Imm|OPS_32|OPA_Imm, 0, 0} },
-    { CPU_Hammer|CPU_64, 0, 64, 64, 0, 1, {0x68, 0, 0}, 0, 1,
+    { CPU_Hammer|CPU_64, MOD_GasSufQ, 64, 64, 0, 1, {0x68, 0, 0}, 0, 1,
       {OPT_Imm|OPS_32|OPA_SImm, 0, 0} },
     { CPU_Not64, 0, 0, 0, 0, 1, {0x0E, 0, 0}, 0, 1,
       {OPT_CS|OPS_Any|OPA_None, 0, 0} },
-    { CPU_Not64, 0, 16, 0, 0, 1, {0x0E, 0, 0}, 0, 1,
+    { CPU_Not64, MOD_GasSufW, 16, 0, 0, 1, {0x0E, 0, 0}, 0, 1,
       {OPT_CS|OPS_16|OPA_None, 0, 0} },
-    { CPU_Not64, 0, 32, 0, 0, 1, {0x0E, 0, 0}, 0, 1,
+    { CPU_Not64, MOD_GasSufL, 32, 0, 0, 1, {0x0E, 0, 0}, 0, 1,
       {OPT_CS|OPS_32|OPA_None, 0, 0} },
     { CPU_Not64, 0, 0, 0, 0, 1, {0x16, 0, 0}, 0, 1,
       {OPT_SS|OPS_Any|OPA_None, 0, 0} },
-    { CPU_Not64, 0, 16, 0, 0, 1, {0x16, 0, 0}, 0, 1,
+    { CPU_Not64, MOD_GasSufW, 16, 0, 0, 1, {0x16, 0, 0}, 0, 1,
       {OPT_SS|OPS_16|OPA_None, 0, 0} },
-    { CPU_Not64, 0, 32, 0, 0, 1, {0x16, 0, 0}, 0, 1,
+    { CPU_Not64, MOD_GasSufL, 32, 0, 0, 1, {0x16, 0, 0}, 0, 1,
       {OPT_SS|OPS_32|OPA_None, 0, 0} },
     { CPU_Not64, 0, 0, 0, 0, 1, {0x1E, 0, 0}, 0, 1,
       {OPT_DS|OPS_Any|OPA_None, 0, 0} },
-    { CPU_Not64, 0, 16, 0, 0, 1, {0x1E, 0, 0}, 0, 1,
+    { CPU_Not64, MOD_GasSufW, 16, 0, 0, 1, {0x1E, 0, 0}, 0, 1,
       {OPT_DS|OPS_16|OPA_None, 0, 0} },
-    { CPU_Not64, 0, 32, 0, 0, 1, {0x1E, 0, 0}, 0, 1,
+    { CPU_Not64, MOD_GasSufL, 32, 0, 0, 1, {0x1E, 0, 0}, 0, 1,
       {OPT_DS|OPS_32|OPA_None, 0, 0} },
     { CPU_Not64, 0, 0, 0, 0, 1, {0x06, 0, 0}, 0, 1,
       {OPT_ES|OPS_Any|OPA_None, 0, 0} },
-    { CPU_Not64, 0, 16, 0, 0, 1, {0x06, 0, 0}, 0, 1,
+    { CPU_Not64, MOD_GasSufW, 16, 0, 0, 1, {0x06, 0, 0}, 0, 1,
       {OPT_ES|OPS_16|OPA_None, 0, 0} },
-    { CPU_Not64, 0, 32, 0, 0, 1, {0x06, 0, 0}, 0, 1,
+    { CPU_Not64, MOD_GasSufL, 32, 0, 0, 1, {0x06, 0, 0}, 0, 1,
       {OPT_ES|OPS_32|OPA_None, 0, 0} },
     { CPU_386, 0, 0, 0, 0, 2, {0x0F, 0xA0, 0}, 0, 1,
       {OPT_FS|OPS_Any|OPA_None, 0, 0} },
-    { CPU_386, 0, 16, 0, 0, 2, {0x0F, 0xA0, 0}, 0, 1,
+    { CPU_386, MOD_GasSufW, 16, 0, 0, 2, {0x0F, 0xA0, 0}, 0, 1,
       {OPT_FS|OPS_16|OPA_None, 0, 0} },
-    { CPU_386, 0, 32, 0, 0, 2, {0x0F, 0xA0, 0}, 0, 1,
+    { CPU_386, MOD_GasSufL, 32, 0, 0, 2, {0x0F, 0xA0, 0}, 0, 1,
       {OPT_FS|OPS_32|OPA_None, 0, 0} },
     { CPU_386, 0, 0, 0, 0, 2, {0x0F, 0xA8, 0}, 0, 1,
       {OPT_GS|OPS_Any|OPA_None, 0, 0} },
-    { CPU_386, 0, 16, 0, 0, 2, {0x0F, 0xA8, 0}, 0, 1,
+    { CPU_386, MOD_GasSufW, 16, 0, 0, 2, {0x0F, 0xA8, 0}, 0, 1,
       {OPT_GS|OPS_16|OPA_None, 0, 0} },
-    { CPU_386, 0, 32, 0, 0, 2, {0x0F, 0xA8, 0}, 0, 1,
+    { CPU_386, MOD_GasSufL, 32, 0, 0, 2, {0x0F, 0xA8, 0}, 0, 1,
       {OPT_GS|OPS_32|OPA_None, 0, 0} }
 };
 
@@ -693,11 +736,11 @@ static const x86_insn_info out_insn[] = {
 
 /* Load effective address */
 static const x86_insn_info lea_insn[] = {
-    { CPU_Any, 0, 16, 0, 0, 1, {0x8D, 0, 0}, 0, 2,
+    { CPU_Any, MOD_GasSufW, 16, 0, 0, 1, {0x8D, 0, 0}, 0, 2,
       {OPT_Reg|OPS_16|OPA_Spare, OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0} },
-    { CPU_386, 0, 32, 0, 0, 1, {0x8D, 0, 0}, 0, 2,
+    { CPU_386, MOD_GasSufL, 32, 0, 0, 1, {0x8D, 0, 0}, 0, 2,
       {OPT_Reg|OPS_32|OPA_Spare, OPT_Mem|OPS_32|OPS_Relaxed|OPA_EA, 0} },
-    { CPU_Hammer|CPU_64, 0, 64, 0, 0, 1, {0x8D, 0, 0}, 0, 2,
+    { CPU_Hammer|CPU_64, MOD_GasSufQ, 64, 0, 0, 1, {0x8D, 0, 0}, 0, 2,
       {OPT_Reg|OPS_64|OPA_Spare, OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, 0} }
 };
 
@@ -717,57 +760,60 @@ static const x86_insn_info lfgss_insn[] = {
 
 /* Arithmetic - general */
 static const x86_insn_info arith_insn[] = {
-    { CPU_Any, MOD_Op0Add, 0, 0, 0, 1, {0x04, 0, 0}, 0, 2,
+    { CPU_Any, MOD_Op0Add|MOD_GasSufB, 0, 0, 0, 1, {0x04, 0, 0}, 0, 2,
       {OPT_Areg|OPS_8|OPA_None, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} },
-    { CPU_Any, MOD_Op0Add, 16, 0, 0, 1, {0x05, 0, 0}, 0, 2,
+    { CPU_Any, MOD_Op0Add|MOD_GasSufW, 16, 0, 0, 1, {0x05, 0, 0}, 0, 2,
       {OPT_Areg|OPS_16|OPA_None, OPT_Imm|OPS_16|OPS_Relaxed|OPA_Imm, 0} },
-    { CPU_386, MOD_Op0Add, 32, 0, 0, 1, {0x05, 0, 0}, 0, 2,
+    { CPU_386, MOD_Op0Add|MOD_GasSufL, 32, 0, 0, 1, {0x05, 0, 0}, 0, 2,
       {OPT_Areg|OPS_32|OPA_None, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} },
-    { CPU_Hammer|CPU_64, MOD_Op0Add, 64, 0, 0, 1, {0x05, 0, 0}, 0, 2,
-      {OPT_Areg|OPS_64|OPA_None, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} },
+    { CPU_Hammer|CPU_64, MOD_Op0Add|MOD_GasSufQ, 64, 0, 0, 1, {0x05, 0, 0}, 0,
+      2, {OPT_Areg|OPS_64|OPA_None, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} },
 
-    { CPU_Any, MOD_Gap0|MOD_SpAdd, 0, 0, 0, 1, {0x80, 0, 0}, 0, 2,
+    { CPU_Any, MOD_Gap0|MOD_SpAdd|MOD_GasSufB, 0, 0, 0, 1, {0x80, 0, 0}, 0, 2,
       {OPT_RM|OPS_8|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} },
-    { CPU_Any, MOD_Gap0|MOD_SpAdd, 0, 0, 0, 1, {0x80, 0, 0}, 0, 2,
+    { CPU_Any, MOD_Gap0|MOD_SpAdd|MOD_GasSufB, 0, 0, 0, 1, {0x80, 0, 0}, 0, 2,
       {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_8|OPA_Imm, 0} },
-    { CPU_Any, MOD_Gap0|MOD_SpAdd, 16, 0, 0, 1, {0x83, 0, 0}, 0, 2,
+    { CPU_Any, MOD_Gap0|MOD_SpAdd|MOD_GasSufW, 16, 0, 0, 1, {0x83, 0, 0}, 0, 2,
       {OPT_RM|OPS_16|OPA_EA, OPT_Imm|OPS_8|OPA_SImm, 0} },
-    { CPU_Any, MOD_Gap0|MOD_SpAdd, 16, 0, 0, 1, {0x81, 0x83, 0}, 0, 2,
-      {OPT_RM|OPS_16|OPA_EA,
-       OPT_Imm|OPS_16|OPS_Relaxed|OPA_Imm|OPAP_SImm8Avail, 0} },
-    { CPU_Any, MOD_Gap0|MOD_SpAdd, 16, 0, 0, 1, {0x81, 0, 0}, 0, 2,
+    { CPU_Any, MOD_Gap0|MOD_SpAdd|MOD_GasSufW, 16, 0, 0, 1, {0x81, 0x83, 0}, 0,
+      2, {OPT_RM|OPS_16|OPA_EA,
+         OPT_Imm|OPS_16|OPS_Relaxed|OPA_Imm|OPAP_SImm8Avail, 0} },
+    { CPU_Any, MOD_Gap0|MOD_SpAdd|MOD_GasSufW, 16, 0, 0, 1, {0x81, 0, 0}, 0, 2,
       {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_16|OPA_Imm, 0} },
-    { CPU_386, MOD_Gap0|MOD_SpAdd, 32, 0, 0, 1, {0x83, 0, 0}, 0, 2,
+    { CPU_386, MOD_Gap0|MOD_SpAdd|MOD_GasSufL, 32, 0, 0, 1, {0x83, 0, 0}, 0, 2,
       {OPT_RM|OPS_32|OPA_EA, OPT_Imm|OPS_8|OPA_SImm, 0} },
-    { CPU_386, MOD_Gap0|MOD_SpAdd, 32, 0, 0, 1, {0x81, 0x83, 0}, 0, 2,
-      {OPT_RM|OPS_32|OPA_EA,
-       OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm|OPAP_SImm8Avail, 0} },
-    { CPU_386, MOD_Gap0|MOD_SpAdd, 32, 0, 0, 1, {0x81, 0, 0}, 0, 2,
+    { CPU_386, MOD_Gap0|MOD_SpAdd|MOD_GasSufL, 32, 0, 0, 1, {0x81, 0x83, 0}, 0,
+      2, {OPT_RM|OPS_32|OPA_EA,
+         OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm|OPAP_SImm8Avail, 0} },
+    { CPU_386, MOD_Gap0|MOD_SpAdd|MOD_GasSufL, 32, 0, 0, 1, {0x81, 0, 0}, 0, 2,
       {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_32|OPA_Imm, 0} },
-    { CPU_Hammer|CPU_64, MOD_Gap0|MOD_SpAdd, 64, 0, 0, 1, {0x83, 0, 0}, 0, 2,
+    { CPU_Hammer|CPU_64, MOD_Gap0|MOD_SpAdd|MOD_GasSufQ, 64, 0, 0, 1,
+      {0x83, 0, 0}, 0, 2,
       {OPT_RM|OPS_64|OPA_EA, OPT_Imm|OPS_8|OPA_SImm, 0} },
-    { CPU_Hammer|CPU_64, MOD_Gap0|MOD_SpAdd, 64, 0, 0, 1, {0x81, 0x83, 0},
-      0, 2, {OPT_RM|OPS_64|OPA_EA,
-                    OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm|OPAP_SImm8Avail, 0} },
-    { CPU_Hammer|CPU_64, MOD_Gap0|MOD_SpAdd, 64, 0, 0, 1, {0x81, 0, 0}, 0, 2,
+    { CPU_Hammer|CPU_64, MOD_Gap0|MOD_SpAdd|MOD_GasSufQ, 64, 0, 0, 1,
+      {0x81, 0x83, 0}, 0, 2,
+      {OPT_RM|OPS_64|OPA_EA,
+       OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm|OPAP_SImm8Avail, 0} },
+    { CPU_Hammer|CPU_64, MOD_Gap0|MOD_SpAdd|MOD_GasSufQ, 64, 0, 0, 1,
+      {0x81, 0, 0}, 0, 2,
       {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_32|OPA_Imm, 0} },
 
-    { CPU_Any, MOD_Op0Add, 0, 0, 0, 1, {0x00, 0, 0}, 0, 2,
+    { CPU_Any, MOD_Op0Add|MOD_GasSufB, 0, 0, 0, 1, {0x00, 0, 0}, 0, 2,
       {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_8|OPA_Spare, 0} },
-    { CPU_Any, MOD_Op0Add, 16, 0, 0, 1, {0x01, 0, 0}, 0, 2,
+    { CPU_Any, MOD_Op0Add|MOD_GasSufW, 16, 0, 0, 1, {0x01, 0, 0}, 0, 2,
       {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, 0} },
-    { CPU_386, MOD_Op0Add, 32, 0, 0, 1, {0x01, 0, 0}, 0, 2,
+    { CPU_386, MOD_Op0Add|MOD_GasSufL, 32, 0, 0, 1, {0x01, 0, 0}, 0, 2,
       {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, 0} },
-    { CPU_Hammer|CPU_64, MOD_Op0Add, 64, 0, 0, 1, {0x01, 0, 0}, 0, 2,
-      {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, 0} },
-    { CPU_Any, MOD_Op0Add, 0, 0, 0, 1, {0x02, 0, 0}, 0, 2,
+    { CPU_Hammer|CPU_64, MOD_Op0Add|MOD_GasSufQ, 64, 0, 0, 1, {0x01, 0, 0}, 0,
+      2, {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, 0} },
+    { CPU_Any, MOD_Op0Add|MOD_GasSufB, 0, 0, 0, 1, {0x02, 0, 0}, 0, 2,
       {OPT_Reg|OPS_8|OPA_Spare, OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, 0} },
-    { CPU_Any, MOD_Op0Add, 16, 0, 0, 1, {0x03, 0, 0}, 0, 2,
+    { CPU_Any, MOD_Op0Add|MOD_GasSufW, 16, 0, 0, 1, {0x03, 0, 0}, 0, 2,
       {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0} },
-    { CPU_386, MOD_Op0Add, 32, 0, 0, 1, {0x03, 0, 0}, 0, 2,
+    { CPU_386, MOD_Op0Add|MOD_GasSufL, 32, 0, 0, 1, {0x03, 0, 0}, 0, 2,
       {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} },
-    { CPU_Hammer|CPU_64, MOD_Op0Add, 64, 0, 0, 1, {0x03, 0, 0}, 0, 2,
-      {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, 0} }
+    { CPU_Hammer|CPU_64, MOD_Op0Add|MOD_GasSufQ, 64, 0, 0, 1, {0x03, 0, 0}, 0,
+      2, {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, 0} }
 };
 
 /* Arithmetic - inc/dec */
@@ -1820,7 +1866,8 @@ x86_finalize_jmp(yasm_arch *arch, yasm_bytecode *bc, yasm_bytecode *prev_bc,
     int num_info = (int)(data[1]&0xFF);
     x86_insn_info *info = (x86_insn_info *)data[0];
     unsigned long mod_data = data[1] >> 8;
-    unsigned char mode_bits = (unsigned char)data[3];
+    unsigned char mode_bits = (unsigned char)(data[3] & 0xFF);
+    /*unsigned char suffix = (unsigned char)((data[3]>>8) & 0xFF);*/
     yasm_insn_operand *op;
     static const unsigned char size_lookup[] = {0, 8, 16, 32, 64, 80, 128, 0};
 
@@ -1926,9 +1973,10 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
     int num_info = (int)(data[1]&0xFF);
     x86_insn_info *info = (x86_insn_info *)data[0];
     unsigned long mod_data = data[1] >> 8;
-    unsigned char mode_bits = (unsigned char)data[3];
+    unsigned char mode_bits = (unsigned char)(data[3] & 0xFF);
+    unsigned long suffix = (data[3]>>8) & 0xFF;
     int found = 0;
-    yasm_insn_operand *op;
+    yasm_insn_operand *op, *ops[4], *rev_ops[4], **use_ops;
     /*@null@*/ yasm_symrec *origin;
     /*@null@*/ yasm_expr *imm;
     unsigned char im_len;
@@ -1937,9 +1985,60 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
     int i;
     static const unsigned int size_lookup[] = {0, 1, 2, 4, 8, 10, 16, 0};
 
-    /* First look for SEG:OFF operands and apply X86_FAR_SEGOFF targetmod. */
-    for (i = 0, op = yasm_ops_first(operands); op && i<info->num_operands;
-        op = yasm_operand_next(op), i++) {
+    /* Build local array of operands from list, since we know we have a max
+     * of 3 operands.
+     */
+    if (num_operands > 3) {
+       yasm__error(bc->line, N_("too many operands"));
+       return;
+    }
+    ops[0] = ops[1] = ops[2] = ops[3] = NULL;
+    for (i = 0, op = yasm_ops_first(operands); op && i < num_operands;
+        op = yasm_operand_next(op), i++)
+       ops[i] = op;
+    use_ops = ops;
+
+    /* If we're running in GAS mode, build a reverse array of the operands
+     * as most GAS instructions have reversed operands from Intel style.
+     */
+    if (arch_x86->parser == X86_PARSER_GAS) {
+       rev_ops[0] = rev_ops[1] = rev_ops[2] = rev_ops[3] = NULL;
+       for (i = num_operands-1, op = yasm_ops_first(operands); op && i >= 0;
+            op = yasm_operand_next(op), i--)
+           rev_ops[i] = op;
+       use_ops = rev_ops;
+    }
+
+    /* If we're running in GAS mode, look at the first insn_info to see
+     * if this is a relative jump (OPA_JmpRel).  If so, run through the
+     * operands and adjust for dereferences / lack thereof.
+     */
+    if (arch_x86->parser == X86_PARSER_GAS
+       && (info->operands[0] & OPA_MASK) == OPA_JmpRel) {
+       for (i = 0, op = ops[0]; op; op = ops[++i]) {
+           if (!op->deref && (op->type == YASM_INSN__OPERAND_REG
+                              || (op->type == YASM_INSN__OPERAND_MEMORY
+                                  && op->data.ea->strong)))
+               yasm__warning(YASM_WARN_GENERAL, bc->line,
+                             N_("indirect call without `*'"));
+           if (!op->deref && op->type == YASM_INSN__OPERAND_MEMORY
+               && !op->data.ea->strong) {
+               /* Memory that is not dereferenced, and not strong, is
+                * actually an immediate for the purposes of relative jumps.
+                */
+               if (op->data.ea->segreg != 0)
+                   yasm__warning(YASM_WARN_GENERAL, bc->line,
+                                 N_("skipping prefixes on this instruction"));
+               imm = yasm_expr_copy(op->data.ea->disp);
+               yasm_ea_destroy(op->data.ea);
+               op->type = YASM_INSN__OPERAND_IMM;
+               op->data.val = imm;
+           }
+       }
+    }
+
+    /* Look for SEG:OFF operands and apply X86_FAR_SEGOFF targetmod. */
+    for (i = 0, op = ops[0]; op; op = ops[++i]) {
        if (op->type == YASM_INSN__OPERAND_IMM && op->targetmod == 0 &&
            yasm_expr_is_op(op->data.val, YASM_EXPR_SEGOFF))
            op->targetmod = X86_FAR_SEGOFF;
@@ -1969,14 +2068,18 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
        if (num_operands != info->num_operands)
            continue;
 
+       /* Match suffix (if required) */
+       if (suffix != 0 && ((suffix<<MOD_GasSuf_SHIFT) & info->modifiers) == 0)
+           continue;
+
        if (!operands) {
            found = 1;      /* no operands -> must have a match here. */
            break;
        }
 
        /* Match each operand type and size */
-       for(i = 0, op = yasm_ops_first(operands); op && i<info->num_operands &&
-           !mismatch; op = yasm_operand_next(op), i++) {
+       for (i = 0, op = use_ops[0]; op && i<info->num_operands && !mismatch;
+            op = use_ops[++i]) {
            /* Check operand type */
            switch ((int)(info->operands[i] & OPT_MASK)) {
                case OPT_Imm:
@@ -2140,19 +2243,28 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
 
            /* Check operand size */
            size = size_lookup[(info->operands[i] & OPS_MASK)>>OPS_SHIFT];
-           if (op->type == YASM_INSN__OPERAND_REG && op->size == 0) {
-               /* Register size must exactly match */
-               if (yasm_x86__get_reg_size(arch, op->data.reg) != size)
+           if (suffix != 0) {
+               /* Require relaxed operands for suffix mode (don't allow
+                * per-operand sizing).
+                */
+               if ((info->operands[i] & OPT_MASK) == OPT_Imm
+                   && (info->operands[i] & OPS_RMASK) != OPS_Relaxed)
                    mismatch = 1;
            } else {
-               if ((info->operands[i] & OPS_RMASK) == OPS_Relaxed) {
-                   /* Relaxed checking */
-                   if (size != 0 && op->size != size && op->size != 0)
+               if (op->type == YASM_INSN__OPERAND_REG && op->size == 0) {
+                   /* Register size must exactly match */
+                   if (yasm_x86__get_reg_size(arch, op->data.reg) != size)
                        mismatch = 1;
                } else {
-                   /* Strict checking */
-                   if (op->size != size)
-                       mismatch = 1;
+                   if ((info->operands[i] & OPS_RMASK) == OPS_Relaxed) {
+                       /* Relaxed checking */
+                       if (size != 0 && op->size != size && op->size != 0)
+                           mismatch = 1;
+                   } else {
+                       /* Strict checking */
+                       if (op->size != size)
+                           mismatch = 1;
+                   }
                }
            }
 
@@ -2318,8 +2430,8 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
 
     /* Go through operands and assign */
     if (operands) {
-       for(i = 0, op = yasm_ops_first(operands); op && i<info->num_operands;
-           op = yasm_operand_next(op), i++) {
+       for (i = 0, op = use_ops[0]; op && i<info->num_operands;
+            op = use_ops[++i]) {
            switch ((int)(info->operands[i] & OPA_MASK)) {
                case OPA_None:
                    /* Throw away the operand contents */
@@ -2674,13 +2786,10 @@ yasm_x86__parse_cpu(yasm_arch *arch, const char *id, unsigned long line)
     */
 }
 
-yasm_arch_check_id_retval
-yasm_x86__parse_check_id(yasm_arch *arch, unsigned long data[4],
-                        const char *id, unsigned long line)
+static yasm_arch_check_id_retval
+yasm_x86__parse_check_targetmod(yasm_arch *arch, unsigned long data[4],
+                               const char *id, unsigned long line)
 {
-    yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
-    const char *oid = id;
-    /*const char *marker;*/
     /*!re2c
        /* target modifiers */
        N E A R         {
@@ -2700,6 +2809,24 @@ yasm_x86__parse_check_id(yasm_arch *arch, unsigned long data[4],
            return YASM_ARCH_CHECK_ID_TARGETMOD;
        }
 
+       /* catchalls */
+       [\001-\377]+    {
+           return YASM_ARCH_CHECK_ID_NONE;
+       }
+       [\000]  {
+           return YASM_ARCH_CHECK_ID_NONE;
+       }
+    */
+    return YASM_ARCH_CHECK_ID_NONE;
+}
+
+static yasm_arch_check_id_retval
+yasm_x86__parse_check_prefix(yasm_arch *arch, unsigned long data[4],
+                            const char *id, unsigned long line)
+{
+    yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
+    const char *oid = id;
+    /*!re2c
        /* operand size overrides */
        O "16"  {
            data[0] = X86_OPERSIZE;
@@ -2780,6 +2907,24 @@ yasm_x86__parse_check_id(yasm_arch *arch, unsigned long data[4],
            return YASM_ARCH_CHECK_ID_PREFIX;
        }
 
+       /* catchalls */
+       [\001-\377]+    {
+           return YASM_ARCH_CHECK_ID_NONE;
+       }
+       [\000]  {
+           return YASM_ARCH_CHECK_ID_NONE;
+       }
+    */
+    return YASM_ARCH_CHECK_ID_NONE;
+}
+
+static yasm_arch_check_id_retval
+yasm_x86__parse_check_reg(yasm_arch *arch, unsigned long data[4],
+                         const char *id, unsigned long line)
+{
+    yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
+    const char *oid = id;
+    /*!re2c
        /* control, debug, and test registers */
        C R [02-48]     {
            if (arch_x86->mode_bits != 64 && oid[2] == '8') {
@@ -2804,10 +2949,24 @@ yasm_x86__parse_check_id(yasm_arch *arch, unsigned long data[4],
            data[0] = X86_FPUREG | (oid[2]-'0');
            return YASM_ARCH_CHECK_ID_REG;
        }
+       S T             {
+           if (arch_x86->parser == X86_PARSER_GAS) {
+               data[0] = X86_FPUREG;
+               return YASM_ARCH_CHECK_ID_REGGROUP;
+           } else
+               return YASM_ARCH_CHECK_ID_NONE;
+       }
        M M [0-7]       {
            data[0] = X86_MMXREG | (oid[2]-'0');
            return YASM_ARCH_CHECK_ID_REG;
        }
+       M M             {
+           if (arch_x86->parser == X86_PARSER_GAS) {
+               data[0] = X86_MMXREG;
+               return YASM_ARCH_CHECK_ID_REGGROUP;
+           } else
+               return YASM_ARCH_CHECK_ID_NONE;
+       }
        X M M [0-9]     {
            if (arch_x86->mode_bits != 64 &&
                (oid[3] == '8' || oid[3] == '9')) {
@@ -2827,6 +2986,13 @@ yasm_x86__parse_check_id(yasm_arch *arch, unsigned long data[4],
            data[0] = X86_XMMREG | (10+oid[4]-'0');
            return YASM_ARCH_CHECK_ID_REG;
        }
+       X M M           {
+           if (arch_x86->parser == X86_PARSER_GAS) {
+               data[0] = X86_XMMREG;
+               return YASM_ARCH_CHECK_ID_REGGROUP;
+           } else
+               return YASM_ARCH_CHECK_ID_NONE;
+       }
 
        /* integer registers */
        R A X   {
@@ -3074,941 +3240,859 @@ yasm_x86__parse_check_id(yasm_arch *arch, unsigned long data[4],
            return YASM_ARCH_CHECK_ID_REG;
        }
 
+       /* catchalls */
+       [\001-\377]+    {
+           return YASM_ARCH_CHECK_ID_NONE;
+       }
+       [\000]  {
+           return YASM_ARCH_CHECK_ID_NONE;
+       }
+    */
+    return YASM_ARCH_CHECK_ID_NONE;
+}
+
+#define RET_INSN(nosuffixsize, group, mod, cpu)        do { \
+    suffix = (id-oid) > nosuffixsize; \
+    DEF_INSN_DATA(group, mod, cpu); \
+    goto done; \
+    } while (0)
+
+/* No suffix version of RET_INSN */
+#define RET_INSN_NS(group, mod, cpu)   do { \
+    DEF_INSN_DATA(group, mod, cpu); \
+    goto done; \
+    } while (0)
+
+#define RET_INSN_GAS(nosuffixsize, group, mod, cpu) do { \
+    if (arch_x86->parser != X86_PARSER_GAS) \
+       return YASM_ARCH_CHECK_ID_NONE; \
+    RET_INSN(nosuffixsize, group, mod, cpu); \
+    } while (0)
+
+#define RET_INSN_NONGAS(nosuffixsize, group, mod, cpu) do { \
+    if (arch_x86->parser == X86_PARSER_GAS) \
+       return YASM_ARCH_CHECK_ID_NONE; \
+    RET_INSN(nosuffixsize, group, mod, cpu); \
+    } while (0)
+
+static yasm_arch_check_id_retval
+yasm_x86__parse_check_insn(yasm_arch *arch, unsigned long data[4],
+                          const char *id, unsigned long line)
+{
+    yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
+    const char *oid = id;
+    /*const char *marker;*/
+    int suffix = 0;
+    int not64 = 0;
+    int warn64 = 0;
+
+    /*!re2c
        /* instructions */
 
        /* Move */
-       M O V { RET_INSN(mov, 0, CPU_Any); }
+       M O V [bBwWlLqQ]? { RET_INSN(3, mov, 0, CPU_Any); }
+       M O V A B S [bBwWlLqQ]? { RET_INSN_GAS(6, movabs, 0, CPU_Hammer|CPU_64); }
        /* Move with sign/zero extend */
-       M O V S X { RET_INSN(movszx, 0xBE, CPU_386); }
+       M O V S X [bBwWlL]? { RET_INSN(5, movszx, 0xBE, CPU_386); }
        M O V S X D {
-           if (arch_x86->mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, line,
-                             N_("`%s' is an instruction in 64-bit mode"),
-                             oid);
-               return YASM_ARCH_CHECK_ID_NONE;
-           }
-           RET_INSN(movsxd, 0, CPU_Hammer|CPU_64);
+           warn64 = 1;
+           RET_INSN(6, movsxd, 0, CPU_Hammer|CPU_64);
        }
-       M O V Z X { RET_INSN(movszx, 0xB6, CPU_386); }
+       M O V Z X { RET_INSN(5, movszx, 0xB6, CPU_386); }
        /* Push instructions */
-       P U S H { RET_INSN(push, 0, CPU_Any); }
+       P U S H [wWlLqQ]? { RET_INSN(4, push, 0, CPU_Any); }
        P U S H A {
-           if (arch_x86->mode_bits == 64) {
-               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
-               RET_INSN(not64, 0, CPU_Not64);
-           }
-           RET_INSN(onebyte, 0x0060, CPU_186);
+           not64 = 1;
+           RET_INSN(5, onebyte, 0x0060, CPU_186);
        }
        P U S H A D {
-           if (arch_x86->mode_bits == 64) {
-               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
-               RET_INSN(not64, 0, CPU_Not64);
-           }
-           RET_INSN(onebyte, 0x2060, CPU_386);
+           not64 = 1;
+           RET_INSN(6, onebyte, 0x2060, CPU_386);
        }
        P U S H A W {
-           if (arch_x86->mode_bits == 64) {
-               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
-               RET_INSN(not64, 0, CPU_Not64);
-           }
-           RET_INSN(onebyte, 0x1060, CPU_186);
+           not64 = 1;
+           RET_INSN(6, onebyte, 0x1060, CPU_186);
        }
        /* Pop instructions */
-       P O P { RET_INSN(pop, 0, CPU_Any); }
+       P O P [wWlLqQ]? { RET_INSN(3, pop, 0, CPU_Any); }
        P O P A {
-           if (arch_x86->mode_bits == 64) {
-               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
-               RET_INSN(not64, 0, CPU_Not64);
-           }
-           RET_INSN(onebyte, 0x0061, CPU_186);
+           not64 = 1;
+           RET_INSN(4, onebyte, 0x0061, CPU_186);
        }
        P O P A D {
-           if (arch_x86->mode_bits == 64) {
-               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
-               RET_INSN(not64, 0, CPU_Not64);
-           }
-           RET_INSN(onebyte, 0x2061, CPU_386);
+           not64 = 1;
+           RET_INSN(5, onebyte, 0x2061, CPU_386);
+       }
+       P O P A L {
+           not64 = 1;
+           RET_INSN_GAS(5, onebyte, 0x2061, CPU_386);
        }
        P O P A W {
-           if (arch_x86->mode_bits == 64) {
-               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
-               RET_INSN(not64, 0, CPU_Not64);
-           }
-           RET_INSN(onebyte, 0x1061, CPU_186);
+           not64 = 1;
+           RET_INSN(5, onebyte, 0x1061, CPU_186);
        }
        /* Exchange */
-       X C H G { RET_INSN(xchg, 0, CPU_Any); }
+       X C H G { RET_INSN(4, xchg, 0, CPU_Any); }
        /* In/out from ports */
-       I N { RET_INSN(in, 0, CPU_Any); }
-       O U T { RET_INSN(out, 0, CPU_Any); }
+       I N { RET_INSN(2, in, 0, CPU_Any); }
+       O U T { RET_INSN(3, out, 0, CPU_Any); }
        /* Load effective address */
-       L E A { RET_INSN(lea, 0, CPU_Any); }
+       L E A [wWlLqQ]? { RET_INSN(3, lea, 0, CPU_Any); }
        /* Load segment registers from memory */
        L D S {
-           if (arch_x86->mode_bits == 64) {
-               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
-               RET_INSN(not64, 0, CPU_Not64);
-           }
-           RET_INSN(ldes, 0xC5, CPU_Any);
+           not64 = 1;
+           RET_INSN(3, ldes, 0xC5, CPU_Any);
        }
        L E S {
-           if (arch_x86->mode_bits == 64) {
-               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
-               RET_INSN(not64, 0, CPU_Not64);
-           }
-           RET_INSN(ldes, 0xC4, CPU_Any);
+           not64 = 1;
+           RET_INSN(3, ldes, 0xC4, CPU_Any);
        }
-       L F S { RET_INSN(lfgss, 0xB4, CPU_386); }
-       L G S { RET_INSN(lfgss, 0xB5, CPU_386); }
-       L S S { RET_INSN(lfgss, 0xB2, CPU_386); }
+       L F S { RET_INSN(3, lfgss, 0xB4, CPU_386); }
+       L G S { RET_INSN(3, lfgss, 0xB5, CPU_386); }
+       L S S { RET_INSN(3, lfgss, 0xB2, CPU_386); }
        /* Flags register instructions */
-       C L C { RET_INSN(onebyte, 0x00F8, CPU_Any); }
-       C L D { RET_INSN(onebyte, 0x00FC, CPU_Any); }
-       C L I { RET_INSN(onebyte, 0x00FA, CPU_Any); }
-       C L T S { RET_INSN(twobyte, 0x0F06, CPU_286|CPU_Priv); }
-       C M C { RET_INSN(onebyte, 0x00F5, CPU_Any); }
+       C L C { RET_INSN(3, onebyte, 0x00F8, CPU_Any); }
+       C L D { RET_INSN(3, onebyte, 0x00FC, CPU_Any); }
+       C L I { RET_INSN(3, onebyte, 0x00FA, CPU_Any); }
+       C L T S { RET_INSN(4, twobyte, 0x0F06, CPU_286|CPU_Priv); }
+       C M C { RET_INSN(3, onebyte, 0x00F5, CPU_Any); }
        L A H F {
-           if (arch_x86->mode_bits == 64) {
-               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
-               RET_INSN(not64, 0, CPU_Not64);
-           }
-           RET_INSN(onebyte, 0x009F, CPU_Any);
+           not64 = 1;
+           RET_INSN(4, onebyte, 0x009F, CPU_Any);
        }
        S A H F {
-           if (arch_x86->mode_bits == 64) {
-               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
-               RET_INSN(not64, 0, CPU_Not64);
-           }
-           RET_INSN(onebyte, 0x009E, CPU_Any);
+           not64 = 1;
+           RET_INSN(4, onebyte, 0x009E, CPU_Any);
        }
-       P U S H F { RET_INSN(onebyte, 0x009C, CPU_Any); }
-       P U S H F D { RET_INSN(onebyte, 0x209C, CPU_386); }
-       P U S H F W { RET_INSN(onebyte, 0x109C, CPU_Any); }
+       P U S H F { RET_INSN(5, onebyte, 0x009C, CPU_Any); }
+       P U S H F D { RET_INSN_NONGAS(6, onebyte, 0x209C, CPU_386); }
+       P U S H F W { RET_INSN(6, onebyte, 0x109C, CPU_Any); }
        P U S H F Q {
-           if (arch_x86->mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, line,
-                             N_("`%s' is an instruction in 64-bit mode"),
-                             oid);
-               return YASM_ARCH_CHECK_ID_NONE;
-           }
-           RET_INSN(onebyte, 0x409C, CPU_Hammer|CPU_64);
+           warn64 = 1;
+           RET_INSN(6, onebyte, 0x409C, CPU_Hammer|CPU_64);
        }
-       P O P F { RET_INSN(onebyte, 0x40009D, CPU_Any); }
+       P O P F { RET_INSN(4, onebyte, 0x40009D, CPU_Any); }
        P O P F D {
-           if (arch_x86->mode_bits == 64) {
-               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
-               RET_INSN(not64, 0, CPU_Not64);
-           }
-           RET_INSN(onebyte, 0x00209D, CPU_386);
+           not64 = 1;
+           RET_INSN(5, onebyte, 0x00209D, CPU_386);
        }
-       P O P F W { RET_INSN(onebyte, 0x40109D, CPU_Any); }
+       P O P F W { RET_INSN(5, onebyte, 0x40109D, CPU_Any); }
        P O P F Q {
-           if (arch_x86->mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, line,
-                             N_("`%s' is an instruction in 64-bit mode"),
-                             oid);
-               return YASM_ARCH_CHECK_ID_NONE;
-           }
-           RET_INSN(onebyte, 0x40409D, CPU_Hammer|CPU_64);
+           warn64 = 1;
+           RET_INSN(5, onebyte, 0x40409D, CPU_Hammer|CPU_64);
        }
-       S T C { RET_INSN(onebyte, 0x00F9, CPU_Any); }
-       S T D { RET_INSN(onebyte, 0x00FD, CPU_Any); }
-       S T I { RET_INSN(onebyte, 0x00FB, CPU_Any); }
+       S T C { RET_INSN(3, onebyte, 0x00F9, CPU_Any); }
+       S T D { RET_INSN(3, onebyte, 0x00FD, CPU_Any); }
+       S T I { RET_INSN(3, onebyte, 0x00FB, CPU_Any); }
        /* Arithmetic */
-       A D D { RET_INSN(arith, 0x0000, CPU_Any); }
-       I N C { RET_INSN(incdec, 0x0040, CPU_Any); }
-       S U B { RET_INSN(arith, 0x0528, CPU_Any); }
-       D E C { RET_INSN(incdec, 0x0148, CPU_Any); }
-       S B B { RET_INSN(arith, 0x0318, CPU_Any); }
-       C M P { RET_INSN(arith, 0x0738, CPU_Any); }
-       T E S T { RET_INSN(test, 0, CPU_Any); }
-       A N D { RET_INSN(arith, 0x0420, CPU_Any); }
-       O R { RET_INSN(arith, 0x0108, CPU_Any); }
-       X O R { RET_INSN(arith, 0x0630, CPU_Any); }
-       A D C { RET_INSN(arith, 0x0210, CPU_Any); }
-       N E G { RET_INSN(f6, 0x03, CPU_Any); }
-       N O T { RET_INSN(f6, 0x02, CPU_Any); }
+       A D D [bBwWlLqQ]? { RET_INSN(3, arith, 0x0000, CPU_Any); }
+       I N C [bBwWlLqQ]? { RET_INSN(3, incdec, 0x0040, CPU_Any); }
+       S U B [bBwWlLqQ]? { RET_INSN(3, arith, 0x0528, CPU_Any); }
+       D E C [bBwWlLqQ]? { RET_INSN(3, incdec, 0x0148, CPU_Any); }
+       S B B [bBwWlLqQ]? { RET_INSN(3, arith, 0x0318, CPU_Any); }
+       C M P [bBwWlLqQ]? { RET_INSN(3, arith, 0x0738, CPU_Any); }
+       T E S T [bBwWlLqQ]? { RET_INSN(4, test, 0, CPU_Any); }
+       A N D [bBwWlLqQ]? { RET_INSN(3, arith, 0x0420, CPU_Any); }
+       O R [bBwWlLqQ]? { RET_INSN(2, arith, 0x0108, CPU_Any); }
+       X O R [bBwWlLqQ]? { RET_INSN(3, arith, 0x0630, CPU_Any); }
+       A D C [bBwWlLqQ]? { RET_INSN(3, arith, 0x0210, CPU_Any); }
+       N E G [bBwWlLqQ]? { RET_INSN(3, f6, 0x03, CPU_Any); }
+       N O T [bBwWlLqQ]? { RET_INSN(3, f6, 0x02, CPU_Any); }
        A A A {
-           if (arch_x86->mode_bits == 64) {
-               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
-               RET_INSN(not64, 0, CPU_Not64);
-           }
-           RET_INSN(onebyte, 0x0037, CPU_Any);
+           not64 = 1;
+           RET_INSN(3, onebyte, 0x0037, CPU_Any);
        }
        A A S {
-           if (arch_x86->mode_bits == 64) {
-               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
-               RET_INSN(not64, 0, CPU_Not64);
-           }
-           RET_INSN(onebyte, 0x003F, CPU_Any);
+           not64 = 1;
+           RET_INSN(3, onebyte, 0x003F, CPU_Any);
        }
        D A A {
-           if (arch_x86->mode_bits == 64) {
-               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
-               RET_INSN(not64, 0, CPU_Not64);
-           }
-           RET_INSN(onebyte, 0x0027, CPU_Any);
+           not64 = 1;
+           RET_INSN(3, onebyte, 0x0027, CPU_Any);
        }
        D A S {
-           if (arch_x86->mode_bits == 64) {
-               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
-               RET_INSN(not64, 0, CPU_Not64);
-           }
-           RET_INSN(onebyte, 0x002F, CPU_Any);
+           not64 = 1;
+           RET_INSN(3, onebyte, 0x002F, CPU_Any);
        }
        A A D {
-           if (arch_x86->mode_bits == 64) {
-               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
-               RET_INSN(not64, 0, CPU_Not64);
-           }
-           RET_INSN(aadm, 0x01, CPU_Any);
+           not64 = 1;
+           RET_INSN(3, aadm, 0x01, CPU_Any);
        }
        A A M {
-           if (arch_x86->mode_bits == 64) {
-               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
-               RET_INSN(not64, 0, CPU_Not64);
-           }
-           RET_INSN(aadm, 0x00, CPU_Any);
+           not64 = 1;
+           RET_INSN(3, aadm, 0x00, CPU_Any);
        }
        /* Conversion instructions */
-       C B W { RET_INSN(onebyte, 0x1098, CPU_Any); }
-       C W D E { RET_INSN(onebyte, 0x2098, CPU_386); }
+       C B W { RET_INSN(3, onebyte, 0x1098, CPU_Any); }
+       C W D E { RET_INSN(4, onebyte, 0x2098, CPU_386); }
        C D Q E {
-           if (arch_x86->mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, line,
-                             N_("`%s' is an instruction in 64-bit mode"),
-                             oid);
-               return YASM_ARCH_CHECK_ID_NONE;
-           }
-           RET_INSN(onebyte, 0x4098, CPU_Hammer|CPU_64);
+           warn64 = 1;
+           RET_INSN(4, onebyte, 0x4098, CPU_Hammer|CPU_64);
        }
-       C W D { RET_INSN(onebyte, 0x1099, CPU_Any); }
-       C D Q { RET_INSN(onebyte, 0x2099, CPU_386); }
+       C W D { RET_INSN(3, onebyte, 0x1099, CPU_Any); }
+       C D Q { RET_INSN(3, onebyte, 0x2099, CPU_386); }
        C D O {
-           if (arch_x86->mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, line,
-                             N_("`%s' is an instruction in 64-bit mode"),
-                             oid);
-               return YASM_ARCH_CHECK_ID_NONE;
-           }
-           RET_INSN(onebyte, 0x4099, CPU_Hammer|CPU_64);
+           warn64 = 1;
+           RET_INSN(3, onebyte, 0x4099, CPU_Hammer|CPU_64);
        }
        /* Multiplication and division */
-       M U L { RET_INSN(f6, 0x04, CPU_Any); }
-       I M U L { RET_INSN(imul, 0, CPU_Any); }
-       D I V { RET_INSN(f6, 0x06, CPU_Any); }
-       I D I V { RET_INSN(f6, 0x07, CPU_Any); }
+       M U L { RET_INSN(3, f6, 0x04, CPU_Any); }
+       I M U L { RET_INSN(4, imul, 0, CPU_Any); }
+       D I V { RET_INSN(3, f6, 0x06, CPU_Any); }
+       I D I V { RET_INSN(4, f6, 0x07, CPU_Any); }
        /* Shifts */
-       R O L { RET_INSN(shift, 0x00, CPU_Any); }
-       R O R { RET_INSN(shift, 0x01, CPU_Any); }
-       R C L { RET_INSN(shift, 0x02, CPU_Any); }
-       R C R { RET_INSN(shift, 0x03, CPU_Any); }
-       S A L { RET_INSN(shift, 0x04, CPU_Any); }
-       S H L { RET_INSN(shift, 0x04, CPU_Any); }
-       S H R { RET_INSN(shift, 0x05, CPU_Any); }
-       S A R { RET_INSN(shift, 0x07, CPU_Any); }
-       S H L D { RET_INSN(shlrd, 0xA4, CPU_386); }
-       S H R D { RET_INSN(shlrd, 0xAC, CPU_386); }
+       R O L { RET_INSN(3, shift, 0x00, CPU_Any); }
+       R O R { RET_INSN(3, shift, 0x01, CPU_Any); }
+       R C L { RET_INSN(3, shift, 0x02, CPU_Any); }
+       R C R { RET_INSN(3, shift, 0x03, CPU_Any); }
+       S A L { RET_INSN(3, shift, 0x04, CPU_Any); }
+       S H L { RET_INSN(3, shift, 0x04, CPU_Any); }
+       S H R { RET_INSN(3, shift, 0x05, CPU_Any); }
+       S A R { RET_INSN(3, shift, 0x07, CPU_Any); }
+       S H L D { RET_INSN(4, shlrd, 0xA4, CPU_386); }
+       S H R D { RET_INSN(4, shlrd, 0xAC, CPU_386); }
        /* Control transfer instructions (unconditional) */
-       C A L L { RET_INSN(call, 0, CPU_Any); }
-       J M P { RET_INSN(jmp, 0, CPU_Any); }
-       R E T { RET_INSN(retnf, 0xC2, CPU_Any); }
-       R E T N { RET_INSN(retnf, 0xC2, CPU_Any); }
-       R E T F { RET_INSN(retnf, 0xCA, CPU_Any); }
-       E N T E R { RET_INSN(enter, 0, CPU_186); }
-       L E A V E { RET_INSN(onebyte, 0x4000C9, CPU_186); }
+       C A L L { RET_INSN(4, call, 0, CPU_Any); }
+       J M P { RET_INSN(3, jmp, 0, CPU_Any); }
+       R E T { RET_INSN(3, retnf, 0xC2, CPU_Any); }
+       R E T N { RET_INSN(4, retnf, 0xC2, CPU_Any); }
+       R E T F { RET_INSN(4, retnf, 0xCA, CPU_Any); }
+       E N T E R { RET_INSN(5, enter, 0, CPU_186); }
+       L E A V E { RET_INSN(5, onebyte, 0x4000C9, CPU_186); }
        /* Conditional jumps */
-       J O { RET_INSN(jcc, 0x00, CPU_Any); }
-       J N O { RET_INSN(jcc, 0x01, CPU_Any); }
-       J B { RET_INSN(jcc, 0x02, CPU_Any); }
-       J C { RET_INSN(jcc, 0x02, CPU_Any); }
-       J N A E { RET_INSN(jcc, 0x02, CPU_Any); }
-       J N B { RET_INSN(jcc, 0x03, CPU_Any); }
-       J N C { RET_INSN(jcc, 0x03, CPU_Any); }
-       J A E { RET_INSN(jcc, 0x03, CPU_Any); }
-       J E { RET_INSN(jcc, 0x04, CPU_Any); }
-       J Z { RET_INSN(jcc, 0x04, CPU_Any); }
-       J N E { RET_INSN(jcc, 0x05, CPU_Any); }
-       J N Z { RET_INSN(jcc, 0x05, CPU_Any); }
-       J B E { RET_INSN(jcc, 0x06, CPU_Any); }
-       J N A { RET_INSN(jcc, 0x06, CPU_Any); }
-       J N B E { RET_INSN(jcc, 0x07, CPU_Any); }
-       J A { RET_INSN(jcc, 0x07, CPU_Any); }
-       J S { RET_INSN(jcc, 0x08, CPU_Any); }
-       J N S { RET_INSN(jcc, 0x09, CPU_Any); }
-       J P { RET_INSN(jcc, 0x0A, CPU_Any); }
-       J P E { RET_INSN(jcc, 0x0A, CPU_Any); }
-       J N P { RET_INSN(jcc, 0x0B, CPU_Any); }
-       J P O { RET_INSN(jcc, 0x0B, CPU_Any); }
-       J L { RET_INSN(jcc, 0x0C, CPU_Any); }
-       J N G E { RET_INSN(jcc, 0x0C, CPU_Any); }
-       J N L { RET_INSN(jcc, 0x0D, CPU_Any); }
-       J G E { RET_INSN(jcc, 0x0D, CPU_Any); }
-       J L E { RET_INSN(jcc, 0x0E, CPU_Any); }
-       J N G { RET_INSN(jcc, 0x0E, CPU_Any); }
-       J N L E { RET_INSN(jcc, 0x0F, CPU_Any); }
-       J G { RET_INSN(jcc, 0x0F, CPU_Any); }
-       J C X Z { RET_INSN(jcxz, 16, CPU_Any); }
-       J E C X Z { RET_INSN(jcxz, 32, CPU_386); }
+       J O { RET_INSN(2, jcc, 0x00, CPU_Any); }
+       J N O { RET_INSN(3, jcc, 0x01, CPU_Any); }
+       J B { RET_INSN(2, jcc, 0x02, CPU_Any); }
+       J C { RET_INSN(2, jcc, 0x02, CPU_Any); }
+       J N A E { RET_INSN(4, jcc, 0x02, CPU_Any); }
+       J N B { RET_INSN(3, jcc, 0x03, CPU_Any); }
+       J N C { RET_INSN(3, jcc, 0x03, CPU_Any); }
+       J A E { RET_INSN(3, jcc, 0x03, CPU_Any); }
+       J E { RET_INSN(2, jcc, 0x04, CPU_Any); }
+       J Z { RET_INSN(2, jcc, 0x04, CPU_Any); }
+       J N E { RET_INSN(3, jcc, 0x05, CPU_Any); }
+       J N Z { RET_INSN(3, jcc, 0x05, CPU_Any); }
+       J B E { RET_INSN(3, jcc, 0x06, CPU_Any); }
+       J N A { RET_INSN(3, jcc, 0x06, CPU_Any); }
+       J N B E { RET_INSN(4, jcc, 0x07, CPU_Any); }
+       J A { RET_INSN(2, jcc, 0x07, CPU_Any); }
+       J S { RET_INSN(2, jcc, 0x08, CPU_Any); }
+       J N S { RET_INSN(3, jcc, 0x09, CPU_Any); }
+       J P { RET_INSN(2, jcc, 0x0A, CPU_Any); }
+       J P E { RET_INSN(3, jcc, 0x0A, CPU_Any); }
+       J N P { RET_INSN(3, jcc, 0x0B, CPU_Any); }
+       J P O { RET_INSN(3, jcc, 0x0B, CPU_Any); }
+       J L { RET_INSN(2, jcc, 0x0C, CPU_Any); }
+       J N G E { RET_INSN(4, jcc, 0x0C, CPU_Any); }
+       J N L { RET_INSN(3, jcc, 0x0D, CPU_Any); }
+       J G E { RET_INSN(3, jcc, 0x0D, CPU_Any); }
+       J L E { RET_INSN(3, jcc, 0x0E, CPU_Any); }
+       J N G { RET_INSN(3, jcc, 0x0E, CPU_Any); }
+       J N L E { RET_INSN(3, jcc, 0x0F, CPU_Any); }
+       J G { RET_INSN(2, jcc, 0x0F, CPU_Any); }
+       J C X Z { RET_INSN(4, jcxz, 16, CPU_Any); }
+       J E C X Z { RET_INSN(5, jcxz, 32, CPU_386); }
        J R C X Z {
-           if (arch_x86->mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, line,
-                             N_("`%s' is an instruction in 64-bit mode"),
-                             oid);
-               return YASM_ARCH_CHECK_ID_NONE;
-           }
-           RET_INSN(jcxz, 64, CPU_Hammer|CPU_64);
+           warn64 = 1;
+           RET_INSN(5, jcxz, 64, CPU_Hammer|CPU_64);
        }
        /* Loop instructions */
-       L O O P { RET_INSN(loop, 0x02, CPU_Any); }
-       L O O P Z { RET_INSN(loop, 0x01, CPU_Any); }
-       L O O P E { RET_INSN(loop, 0x01, CPU_Any); }
-       L O O P N Z { RET_INSN(loop, 0x00, CPU_Any); }
-       L O O P N E { RET_INSN(loop, 0x00, CPU_Any); }
+       L O O P { RET_INSN(4, loop, 0x02, CPU_Any); }
+       L O O P Z { RET_INSN(5, loop, 0x01, CPU_Any); }
+       L O O P E { RET_INSN(5, loop, 0x01, CPU_Any); }
+       L O O P N Z { RET_INSN(6, loop, 0x00, CPU_Any); }
+       L O O P N E { RET_INSN(6, loop, 0x00, CPU_Any); }
        /* Set byte on flag instructions */
-       S E T O { RET_INSN(setcc, 0x00, CPU_386); }
-       S E T N O { RET_INSN(setcc, 0x01, CPU_386); }
-       S E T B { RET_INSN(setcc, 0x02, CPU_386); }
-       S E T C { RET_INSN(setcc, 0x02, CPU_386); }
-       S E T N A E { RET_INSN(setcc, 0x02, CPU_386); }
-       S E T N B { RET_INSN(setcc, 0x03, CPU_386); }
-       S E T N C { RET_INSN(setcc, 0x03, CPU_386); }
-       S E T A E { RET_INSN(setcc, 0x03, CPU_386); }
-       S E T E { RET_INSN(setcc, 0x04, CPU_386); }
-       S E T Z { RET_INSN(setcc, 0x04, CPU_386); }
-       S E T N E { RET_INSN(setcc, 0x05, CPU_386); }
-       S E T N Z { RET_INSN(setcc, 0x05, CPU_386); }
-       S E T B E { RET_INSN(setcc, 0x06, CPU_386); }
-       S E T N A { RET_INSN(setcc, 0x06, CPU_386); }
-       S E T N B E { RET_INSN(setcc, 0x07, CPU_386); }
-       S E T A { RET_INSN(setcc, 0x07, CPU_386); }
-       S E T S { RET_INSN(setcc, 0x08, CPU_386); }
-       S E T N S { RET_INSN(setcc, 0x09, CPU_386); }
-       S E T P { RET_INSN(setcc, 0x0A, CPU_386); }
-       S E T P E { RET_INSN(setcc, 0x0A, CPU_386); }
-       S E T N P { RET_INSN(setcc, 0x0B, CPU_386); }
-       S E T P O { RET_INSN(setcc, 0x0B, CPU_386); }
-       S E T L { RET_INSN(setcc, 0x0C, CPU_386); }
-       S E T N G E { RET_INSN(setcc, 0x0C, CPU_386); }
-       S E T N L { RET_INSN(setcc, 0x0D, CPU_386); }
-       S E T G E { RET_INSN(setcc, 0x0D, CPU_386); }
-       S E T L E { RET_INSN(setcc, 0x0E, CPU_386); }
-       S E T N G { RET_INSN(setcc, 0x0E, CPU_386); }
-       S E T N L E { RET_INSN(setcc, 0x0F, CPU_386); }
-       S E T G { RET_INSN(setcc, 0x0F, CPU_386); }
+       S E T O { RET_INSN(4, setcc, 0x00, CPU_386); }
+       S E T N O { RET_INSN(5, setcc, 0x01, CPU_386); }
+       S E T B { RET_INSN(4, setcc, 0x02, CPU_386); }
+       S E T C { RET_INSN(4, setcc, 0x02, CPU_386); }
+       S E T N A E { RET_INSN(6, setcc, 0x02, CPU_386); }
+       S E T N B { RET_INSN(5, setcc, 0x03, CPU_386); }
+       S E T N C { RET_INSN(5, setcc, 0x03, CPU_386); }
+       S E T A E { RET_INSN(5, setcc, 0x03, CPU_386); }
+       S E T E { RET_INSN(4, setcc, 0x04, CPU_386); }
+       S E T Z { RET_INSN(4, setcc, 0x04, CPU_386); }
+       S E T N E { RET_INSN(5, setcc, 0x05, CPU_386); }
+       S E T N Z { RET_INSN(5, setcc, 0x05, CPU_386); }
+       S E T B E { RET_INSN(5, setcc, 0x06, CPU_386); }
+       S E T N A { RET_INSN(5, setcc, 0x06, CPU_386); }
+       S E T N B E { RET_INSN(6, setcc, 0x07, CPU_386); }
+       S E T A { RET_INSN(4, setcc, 0x07, CPU_386); }
+       S E T S { RET_INSN(4, setcc, 0x08, CPU_386); }
+       S E T N S { RET_INSN(5, setcc, 0x09, CPU_386); }
+       S E T P { RET_INSN(4, setcc, 0x0A, CPU_386); }
+       S E T P E { RET_INSN(5, setcc, 0x0A, CPU_386); }
+       S E T N P { RET_INSN(5, setcc, 0x0B, CPU_386); }
+       S E T P O { RET_INSN(5, setcc, 0x0B, CPU_386); }
+       S E T L { RET_INSN(4, setcc, 0x0C, CPU_386); }
+       S E T N G E { RET_INSN(6, setcc, 0x0C, CPU_386); }
+       S E T N L { RET_INSN(5, setcc, 0x0D, CPU_386); }
+       S E T G E { RET_INSN(5, setcc, 0x0D, CPU_386); }
+       S E T L E { RET_INSN(5, setcc, 0x0E, CPU_386); }
+       S E T N G { RET_INSN(5, setcc, 0x0E, CPU_386); }
+       S E T N L E { RET_INSN(6, setcc, 0x0F, CPU_386); }
+       S E T G { RET_INSN(4, setcc, 0x0F, CPU_386); }
        /* String instructions. */
-       C M P S B { RET_INSN(onebyte, 0x00A6, CPU_Any); }
-       C M P S W { RET_INSN(onebyte, 0x10A7, CPU_Any); }
-       C M P S D { RET_INSN(cmpsd, 0, CPU_Any); }
+       C M P S B { RET_INSN(5, onebyte, 0x00A6, CPU_Any); }
+       C M P S W { RET_INSN(5, onebyte, 0x10A7, CPU_Any); }
+       C M P S D { RET_INSN(5, cmpsd, 0, CPU_Any); }
        C M P S Q {
-           if (arch_x86->mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, line,
-                             N_("`%s' is an instruction in 64-bit mode"),
-                             oid);
-               return YASM_ARCH_CHECK_ID_NONE;
-           }
-           RET_INSN(onebyte, 0x40A7, CPU_Hammer|CPU_64);
-       }
-       I N S B { RET_INSN(onebyte, 0x006C, CPU_Any); }
-       I N S W { RET_INSN(onebyte, 0x106D, CPU_Any); }
-       I N S D { RET_INSN(onebyte, 0x206D, CPU_386); }
-       O U T S B { RET_INSN(onebyte, 0x006E, CPU_Any); }
-       O U T S W { RET_INSN(onebyte, 0x106F, CPU_Any); }
-       O U T S D { RET_INSN(onebyte, 0x206F, CPU_386); }
-       L O D S B { RET_INSN(onebyte, 0x00AC, CPU_Any); }
-       L O D S W { RET_INSN(onebyte, 0x10AD, CPU_Any); }
-       L O D S D { RET_INSN(onebyte, 0x20AD, CPU_386); }
+           warn64 = 1;
+           RET_INSN(5, onebyte, 0x40A7, CPU_Hammer|CPU_64);
+       }
+       I N S B { RET_INSN(4, onebyte, 0x006C, CPU_Any); }
+       I N S W { RET_INSN(4, onebyte, 0x106D, CPU_Any); }
+       I N S D { RET_INSN(4, onebyte, 0x206D, CPU_386); }
+       O U T S B { RET_INSN(5, onebyte, 0x006E, CPU_Any); }
+       O U T S W { RET_INSN(5, onebyte, 0x106F, CPU_Any); }
+       O U T S D { RET_INSN(5, onebyte, 0x206F, CPU_386); }
+       L O D S B { RET_INSN(5, onebyte, 0x00AC, CPU_Any); }
+       L O D S W { RET_INSN(5, onebyte, 0x10AD, CPU_Any); }
+       L O D S D { RET_INSN(5, onebyte, 0x20AD, CPU_386); }
        L O D S Q {
-           if (arch_x86->mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, line,
-                             N_("`%s' is an instruction in 64-bit mode"),
-                             oid);
-               return YASM_ARCH_CHECK_ID_NONE;
-           }
-           RET_INSN(onebyte, 0x40AD, CPU_Hammer|CPU_64);
+           warn64 = 1;
+           RET_INSN(5, onebyte, 0x40AD, CPU_Hammer|CPU_64);
        }
-       M O V S B { RET_INSN(onebyte, 0x00A4, CPU_Any); }
-       M O V S W { RET_INSN(onebyte, 0x10A5, CPU_Any); }
-       M O V S D { RET_INSN(movsd, 0, CPU_Any); }
+       M O V S B { RET_INSN(5, onebyte, 0x00A4, CPU_Any); }
+       M O V S W { RET_INSN(5, onebyte, 0x10A5, CPU_Any); }
+       M O V S D { RET_INSN(5, movsd, 0, CPU_Any); }
        M O V S Q {
-           if (arch_x86->mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, line,
-                             N_("`%s' is an instruction in 64-bit mode"),
-                             oid);
-               return YASM_ARCH_CHECK_ID_NONE;
-           }
-           RET_INSN(onebyte, 0x40A5, CPU_Any);
+           warn64 = 1;
+           RET_INSN(5, onebyte, 0x40A5, CPU_Any);
        }
-       S C A S B { RET_INSN(onebyte, 0x00AE, CPU_Any); }
-       S C A S W { RET_INSN(onebyte, 0x10AF, CPU_Any); }
-       S C A S D { RET_INSN(onebyte, 0x20AF, CPU_386); }
+       S C A S B { RET_INSN(5, onebyte, 0x00AE, CPU_Any); }
+       S C A S W { RET_INSN(5, onebyte, 0x10AF, CPU_Any); }
+       S C A S D { RET_INSN(5, onebyte, 0x20AF, CPU_386); }
        S C A S Q {
-           if (arch_x86->mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, line,
-                             N_("`%s' is an instruction in 64-bit mode"),
-                             oid);
-               return YASM_ARCH_CHECK_ID_NONE;
-           }
-           RET_INSN(onebyte, 0x40AF, CPU_Hammer|CPU_64);
+           warn64 = 1;
+           RET_INSN(5, onebyte, 0x40AF, CPU_Hammer|CPU_64);
        }
-       S T O S B { RET_INSN(onebyte, 0x00AA, CPU_Any); }
-       S T O S W { RET_INSN(onebyte, 0x10AB, CPU_Any); }
-       S T O S D { RET_INSN(onebyte, 0x20AB, CPU_386); }
+       S T O S B { RET_INSN(5, onebyte, 0x00AA, CPU_Any); }
+       S T O S W { RET_INSN(5, onebyte, 0x10AB, CPU_Any); }
+       S T O S D { RET_INSN(5, onebyte, 0x20AB, CPU_386); }
        S T O S Q {
-           if (arch_x86->mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, line,
-                             N_("`%s' is an instruction in 64-bit mode"),
-                             oid);
-               return YASM_ARCH_CHECK_ID_NONE;
-           }
-           RET_INSN(onebyte, 0x40AB, CPU_Hammer|CPU_64);
+           warn64 = 1;
+           RET_INSN(5, onebyte, 0x40AB, CPU_Hammer|CPU_64);
        }
-       X L A T B? { RET_INSN(onebyte, 0x00D7, CPU_Any); }
+       X L A T B? { RET_INSN(5, onebyte, 0x00D7, CPU_Any); }
        /* Bit manipulation */
-       B S F { RET_INSN(bsfr, 0xBC, CPU_386); }
-       B S R { RET_INSN(bsfr, 0xBD, CPU_386); }
-       B T { RET_INSN(bittest, 0x04A3, CPU_386); }
-       B T C { RET_INSN(bittest, 0x07BB, CPU_386); }
-       B T R { RET_INSN(bittest, 0x06B3, CPU_386); }
-       B T S { RET_INSN(bittest, 0x05AB, CPU_386); }
+       B S F { RET_INSN(3, bsfr, 0xBC, CPU_386); }
+       B S R { RET_INSN(3, bsfr, 0xBD, CPU_386); }
+       B T { RET_INSN(2, bittest, 0x04A3, CPU_386); }
+       B T C { RET_INSN(3, bittest, 0x07BB, CPU_386); }
+       B T R { RET_INSN(3, bittest, 0x06B3, CPU_386); }
+       B T S { RET_INSN(3, bittest, 0x05AB, CPU_386); }
        /* Interrupts and operating system instructions */
-       I N T { RET_INSN(int, 0, CPU_Any); }
-       I N T "3" { RET_INSN(onebyte, 0x00CC, CPU_Any); }
-       I N T "03" { RET_INSN(onebyte, 0x00CC, CPU_Any); }
+       I N T { RET_INSN(3, int, 0, CPU_Any); }
+       I N T "3" { RET_INSN(4, onebyte, 0x00CC, CPU_Any); }
+       I N T "03" { RET_INSN(5, onebyte, 0x00CC, CPU_Any); }
        I N T O {
-           if (arch_x86->mode_bits == 64) {
-               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
-               RET_INSN(not64, 0, CPU_Not64);
-           }
-           RET_INSN(onebyte, 0x00CE, CPU_Any);
+           not64 = 1;
+           RET_INSN(4, onebyte, 0x00CE, CPU_Any);
        }
-       I R E T { RET_INSN(onebyte, 0x00CF, CPU_Any); }
-       I R E T W { RET_INSN(onebyte, 0x10CF, CPU_Any); }
-       I R E T D { RET_INSN(onebyte, 0x20CF, CPU_386); }
+       I R E T { RET_INSN(4, onebyte, 0x00CF, CPU_Any); }
+       I R E T W { RET_INSN(5, onebyte, 0x10CF, CPU_Any); }
+       I R E T D { RET_INSN(5, onebyte, 0x20CF, CPU_386); }
        I R E T Q {
-           if (arch_x86->mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, line,
-                             N_("`%s' is an instruction in 64-bit mode"),
-                             oid);
-               return YASM_ARCH_CHECK_ID_NONE;
-           }
-           RET_INSN(onebyte, 0x40CF, CPU_Hammer|CPU_64);
+           warn64 = 1;
+           RET_INSN(5, onebyte, 0x40CF, CPU_Hammer|CPU_64);
        }
-       R S M { RET_INSN(twobyte, 0x0FAA, CPU_586|CPU_SMM); }
+       R S M { RET_INSN(3, twobyte, 0x0FAA, CPU_586|CPU_SMM); }
        B O U N D {
-           if (arch_x86->mode_bits == 64) {
-               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
-               RET_INSN(not64, 0, CPU_Not64);
-           }
-           RET_INSN(bound, 0, CPU_186);
+           not64 = 1;
+           RET_INSN(5, bound, 0, CPU_186);
        }
-       H L T { RET_INSN(onebyte, 0x00F4, CPU_Priv); }
-       N O P { RET_INSN(onebyte, 0x0090, CPU_Any); }
+       H L T { RET_INSN(3, onebyte, 0x00F4, CPU_Priv); }
+       N O P { RET_INSN(3, onebyte, 0x0090, CPU_Any); }
        /* Protection control */
        A R P L {
-           if (arch_x86->mode_bits == 64) {
-               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
-               RET_INSN(not64, 0, CPU_Not64);
-           }
-           RET_INSN(arpl, 0, CPU_286|CPU_Prot);
-       }
-       L A R { RET_INSN(bsfr, 0x02, CPU_286|CPU_Prot); }
-       L G D T { RET_INSN(twobytemem, 0x020F01, CPU_286|CPU_Priv); }
-       L I D T { RET_INSN(twobytemem, 0x030F01, CPU_286|CPU_Priv); }
-       L L D T { RET_INSN(prot286, 0x0200, CPU_286|CPU_Prot|CPU_Priv); }
-       L M S W { RET_INSN(prot286, 0x0601, CPU_286|CPU_Priv); }
-       L S L { RET_INSN(bsfr, 0x03, CPU_286|CPU_Prot); }
-       L T R { RET_INSN(prot286, 0x0300, CPU_286|CPU_Prot|CPU_Priv); }
-       S G D T { RET_INSN(twobytemem, 0x000F01, CPU_286|CPU_Priv); }
-       S I D T { RET_INSN(twobytemem, 0x010F01, CPU_286|CPU_Priv); }
-       S L D T { RET_INSN(sldtmsw, 0x0000, CPU_286); }
-       S M S W { RET_INSN(sldtmsw, 0x0401, CPU_286); }
-       S T R { RET_INSN(str, 0, CPU_286|CPU_Prot); }
-       V E R R { RET_INSN(prot286, 0x0400, CPU_286|CPU_Prot); }
-       V E R W { RET_INSN(prot286, 0x0500, CPU_286|CPU_Prot); }
+           not64 = 1;
+           RET_INSN(4, arpl, 0, CPU_286|CPU_Prot);
+       }
+       L A R { RET_INSN(3, bsfr, 0x02, CPU_286|CPU_Prot); }
+       L G D T { RET_INSN(4, twobytemem, 0x020F01, CPU_286|CPU_Priv); }
+       L I D T { RET_INSN(4, twobytemem, 0x030F01, CPU_286|CPU_Priv); }
+       L L D T { RET_INSN(4, prot286, 0x0200, CPU_286|CPU_Prot|CPU_Priv); }
+       L M S W { RET_INSN(4, prot286, 0x0601, CPU_286|CPU_Priv); }
+       L S L { RET_INSN(3, bsfr, 0x03, CPU_286|CPU_Prot); }
+       L T R { RET_INSN(3, prot286, 0x0300, CPU_286|CPU_Prot|CPU_Priv); }
+       S G D T { RET_INSN(4, twobytemem, 0x000F01, CPU_286|CPU_Priv); }
+       S I D T { RET_INSN(4, twobytemem, 0x010F01, CPU_286|CPU_Priv); }
+       S L D T { RET_INSN(4, sldtmsw, 0x0000, CPU_286); }
+       S M S W { RET_INSN(4, sldtmsw, 0x0401, CPU_286); }
+       S T R { RET_INSN(3, str, 0, CPU_286|CPU_Prot); }
+       V E R R { RET_INSN(4, prot286, 0x0400, CPU_286|CPU_Prot); }
+       V E R W { RET_INSN(4, prot286, 0x0500, CPU_286|CPU_Prot); }
        /* Floating point instructions */
-       F L D { RET_INSN(fldstp, 0x0500C0, CPU_FPU); }
-       F I L D { RET_INSN(fildstp, 0x050200, CPU_FPU); }
-       F B L D { RET_INSN(fbldstp, 0x04, CPU_FPU); }
-       F S T { RET_INSN(fst, 0, CPU_FPU); }
-       F I S T { RET_INSN(fiarith, 0x02DB, CPU_FPU); }
-       F S T P { RET_INSN(fldstp, 0x0703D8, CPU_FPU); }
-       F I S T P { RET_INSN(fildstp, 0x070203, CPU_FPU); }
-       F B S T P { RET_INSN(fbldstp, 0x06, CPU_FPU); }
-       F X C H { RET_INSN(fxch, 0, CPU_FPU); }
-       F C O M { RET_INSN(fcom, 0x02D0, CPU_FPU); }
-       F I C O M { RET_INSN(fiarith, 0x02DA, CPU_FPU); }
-       F C O M P { RET_INSN(fcom, 0x03D8, CPU_FPU); }
-       F I C O M P { RET_INSN(fiarith, 0x03DA, CPU_FPU); }
-       F C O M P P { RET_INSN(twobyte, 0xDED9, CPU_FPU); }
-       F U C O M { RET_INSN(fcom2, 0xDDE0, CPU_286|CPU_FPU); }
-       F U C O M P { RET_INSN(fcom2, 0xDDE8, CPU_286|CPU_FPU); }
-       F U C O M P P { RET_INSN(twobyte, 0xDAE9, CPU_286|CPU_FPU); }
-       F T S T { RET_INSN(twobyte, 0xD9E4, CPU_FPU); }
-       F X A M { RET_INSN(twobyte, 0xD9E5, CPU_FPU); }
-       F L D "1" { RET_INSN(twobyte, 0xD9E8, CPU_FPU); }
-       F L D L "2" T { RET_INSN(twobyte, 0xD9E9, CPU_FPU); }
-       F L D L "2" E { RET_INSN(twobyte, 0xD9EA, CPU_FPU); }
-       F L D P I { RET_INSN(twobyte, 0xD9EB, CPU_FPU); }
-       F L D L G "2" { RET_INSN(twobyte, 0xD9EC, CPU_FPU); }
-       F L D L N "2" { RET_INSN(twobyte, 0xD9ED, CPU_FPU); }
-       F L D Z { RET_INSN(twobyte, 0xD9EE, CPU_FPU); }
-       F A D D { RET_INSN(farith, 0x00C0C0, CPU_FPU); }
-       F A D D P { RET_INSN(farithp, 0xC0, CPU_FPU); }
-       F I A D D { RET_INSN(fiarith, 0x00DA, CPU_FPU); }
-       F S U B { RET_INSN(farith, 0x04E0E8, CPU_FPU); }
-       F I S U B { RET_INSN(fiarith, 0x04DA, CPU_FPU); }
-       F S U B P { RET_INSN(farithp, 0xE8, CPU_FPU); }
-       F S U B R { RET_INSN(farith, 0x05E8E0, CPU_FPU); }
-       F I S U B R { RET_INSN(fiarith, 0x05DA, CPU_FPU); }
-       F S U B R P { RET_INSN(farithp, 0xE0, CPU_FPU); }
-       F M U L { RET_INSN(farith, 0x01C8C8, CPU_FPU); }
-       F I M U L { RET_INSN(fiarith, 0x01DA, CPU_FPU); }
-       F M U L P { RET_INSN(farithp, 0xC8, CPU_FPU); }
-       F D I V { RET_INSN(farith, 0x06F0F8, CPU_FPU); }
-       F I D I V { RET_INSN(fiarith, 0x06DA, CPU_FPU); }
-       F D I V P { RET_INSN(farithp, 0xF8, CPU_FPU); }
-       F D I V R { RET_INSN(farith, 0x07F8F0, CPU_FPU); }
-       F I D I V R { RET_INSN(fiarith, 0x07DA, CPU_FPU); }
-       F D I V R P { RET_INSN(farithp, 0xF0, CPU_FPU); }
-       F "2" X M "1" { RET_INSN(twobyte, 0xD9F0, CPU_FPU); }
-       F Y L "2" X { RET_INSN(twobyte, 0xD9F1, CPU_FPU); }
-       F P T A N { RET_INSN(twobyte, 0xD9F2, CPU_FPU); }
-       F P A T A N { RET_INSN(twobyte, 0xD9F3, CPU_FPU); }
-       F X T R A C T { RET_INSN(twobyte, 0xD9F4, CPU_FPU); }
-       F P R E M "1" { RET_INSN(twobyte, 0xD9F5, CPU_286|CPU_FPU); }
-       F D E C S T P { RET_INSN(twobyte, 0xD9F6, CPU_FPU); }
-       F I N C S T P { RET_INSN(twobyte, 0xD9F7, CPU_FPU); }
-       F P R E M { RET_INSN(twobyte, 0xD9F8, CPU_FPU); }
-       F Y L "2" X P "1" { RET_INSN(twobyte, 0xD9F9, CPU_FPU); }
-       F S Q R T { RET_INSN(twobyte, 0xD9FA, CPU_FPU); }
-       F S I N C O S { RET_INSN(twobyte, 0xD9FB, CPU_286|CPU_FPU); }
-       F R N D I N T { RET_INSN(twobyte, 0xD9FC, CPU_FPU); }
-       F S C A L E { RET_INSN(twobyte, 0xD9FD, CPU_FPU); }
-       F S I N { RET_INSN(twobyte, 0xD9FE, CPU_286|CPU_FPU); }
-       F C O S { RET_INSN(twobyte, 0xD9FF, CPU_286|CPU_FPU); }
-       F C H S { RET_INSN(twobyte, 0xD9E0, CPU_FPU); }
-       F A B S { RET_INSN(twobyte, 0xD9E1, CPU_FPU); }
-       F N I N I T { RET_INSN(twobyte, 0xDBE3, CPU_FPU); }
-       F I N I T { RET_INSN(threebyte, 0x9BDBE3UL, CPU_FPU); }
-       F L D C W { RET_INSN(fldnstcw, 0x05, CPU_FPU); }
-       F N S T C W { RET_INSN(fldnstcw, 0x07, CPU_FPU); }
-       F S T C W { RET_INSN(fstcw, 0, CPU_FPU); }
-       F N S T S W { RET_INSN(fnstsw, 0, CPU_FPU); }
-       F S T S W { RET_INSN(fstsw, 0, CPU_FPU); }
-       F N C L E X { RET_INSN(twobyte, 0xDBE2, CPU_FPU); }
-       F C L E X { RET_INSN(threebyte, 0x9BDBE2UL, CPU_FPU); }
-       F N S T E N V { RET_INSN(onebytemem, 0x06D9, CPU_FPU); }
-       F S T E N V { RET_INSN(twobytemem, 0x069BD9, CPU_FPU); }
-       F L D E N V { RET_INSN(onebytemem, 0x04D9, CPU_FPU); }
-       F N S A V E { RET_INSN(onebytemem, 0x06DD, CPU_FPU); }
-       F S A V E { RET_INSN(twobytemem, 0x069BDD, CPU_FPU); }
-       F R S T O R { RET_INSN(onebytemem, 0x04DD, CPU_FPU); }
-       F F R E E { RET_INSN(ffree, 0xDD, CPU_FPU); }
-       F F R E E P { RET_INSN(ffree, 0xDF, CPU_686|CPU_FPU|CPU_Undoc); }
-       F N O P { RET_INSN(twobyte, 0xD9D0, CPU_FPU); }
-       F W A I T { RET_INSN(onebyte, 0x009B, CPU_FPU); }
+       F L D { RET_INSN(3, fldstp, 0x0500C0, CPU_FPU); }
+       F I L D { RET_INSN(4, fildstp, 0x050200, CPU_FPU); }
+       F B L D { RET_INSN(4, fbldstp, 0x04, CPU_FPU); }
+       F S T { RET_INSN(3, fst, 0, CPU_FPU); }
+       F I S T { RET_INSN(4, fiarith, 0x02DB, CPU_FPU); }
+       F S T P { RET_INSN(4, fldstp, 0x0703D8, CPU_FPU); }
+       F I S T P { RET_INSN(5, fildstp, 0x070203, CPU_FPU); }
+       F B S T P { RET_INSN(5, fbldstp, 0x06, CPU_FPU); }
+       F X C H { RET_INSN(4, fxch, 0, CPU_FPU); }
+       F C O M { RET_INSN(4, fcom, 0x02D0, CPU_FPU); }
+       F I C O M { RET_INSN(5, fiarith, 0x02DA, CPU_FPU); }
+       F C O M P { RET_INSN(5, fcom, 0x03D8, CPU_FPU); }
+       F I C O M P { RET_INSN(6, fiarith, 0x03DA, CPU_FPU); }
+       F C O M P P { RET_INSN(6, twobyte, 0xDED9, CPU_FPU); }
+       F U C O M { RET_INSN(5, fcom2, 0xDDE0, CPU_286|CPU_FPU); }
+       F U C O M P { RET_INSN(6, fcom2, 0xDDE8, CPU_286|CPU_FPU); }
+       F U C O M P P { RET_INSN(7, twobyte, 0xDAE9, CPU_286|CPU_FPU); }
+       F T S T { RET_INSN(4, twobyte, 0xD9E4, CPU_FPU); }
+       F X A M { RET_INSN(4, twobyte, 0xD9E5, CPU_FPU); }
+       F L D "1" { RET_INSN(4, twobyte, 0xD9E8, CPU_FPU); }
+       F L D L "2" T { RET_INSN(6, twobyte, 0xD9E9, CPU_FPU); }
+       F L D L "2" E { RET_INSN(6, twobyte, 0xD9EA, CPU_FPU); }
+       F L D P I { RET_INSN(5, twobyte, 0xD9EB, CPU_FPU); }
+       F L D L G "2" { RET_INSN(6, twobyte, 0xD9EC, CPU_FPU); }
+       F L D L N "2" { RET_INSN(6, twobyte, 0xD9ED, CPU_FPU); }
+       F L D Z { RET_INSN(4, twobyte, 0xD9EE, CPU_FPU); }
+       F A D D { RET_INSN(4, farith, 0x00C0C0, CPU_FPU); }
+       F A D D P { RET_INSN(5, farithp, 0xC0, CPU_FPU); }
+       F I A D D { RET_INSN(5, fiarith, 0x00DA, CPU_FPU); }
+       F S U B { RET_INSN(4, farith, 0x04E0E8, CPU_FPU); }
+       F I S U B { RET_INSN(5, fiarith, 0x04DA, CPU_FPU); }
+       F S U B P { RET_INSN(5, farithp, 0xE8, CPU_FPU); }
+       F S U B R { RET_INSN(5, farith, 0x05E8E0, CPU_FPU); }
+       F I S U B R { RET_INSN(6, fiarith, 0x05DA, CPU_FPU); }
+       F S U B R P { RET_INSN(6, farithp, 0xE0, CPU_FPU); }
+       F M U L { RET_INSN(4, farith, 0x01C8C8, CPU_FPU); }
+       F I M U L { RET_INSN(5, fiarith, 0x01DA, CPU_FPU); }
+       F M U L P { RET_INSN(5, farithp, 0xC8, CPU_FPU); }
+       F D I V { RET_INSN(4, farith, 0x06F0F8, CPU_FPU); }
+       F I D I V { RET_INSN(5, fiarith, 0x06DA, CPU_FPU); }
+       F D I V P { RET_INSN(5, farithp, 0xF8, CPU_FPU); }
+       F D I V R { RET_INSN(5, farith, 0x07F8F0, CPU_FPU); }
+       F I D I V R { RET_INSN(6, fiarith, 0x07DA, CPU_FPU); }
+       F D I V R P { RET_INSN(6, farithp, 0xF0, CPU_FPU); }
+       F "2" X M "1" { RET_INSN(5, twobyte, 0xD9F0, CPU_FPU); }
+       F Y L "2" X { RET_INSN(5, twobyte, 0xD9F1, CPU_FPU); }
+       F P T A N { RET_INSN(5, twobyte, 0xD9F2, CPU_FPU); }
+       F P A T A N { RET_INSN(6, twobyte, 0xD9F3, CPU_FPU); }
+       F X T R A C T { RET_INSN(7, twobyte, 0xD9F4, CPU_FPU); }
+       F P R E M "1" { RET_INSN(6, twobyte, 0xD9F5, CPU_286|CPU_FPU); }
+       F D E C S T P { RET_INSN(7, twobyte, 0xD9F6, CPU_FPU); }
+       F I N C S T P { RET_INSN(7, twobyte, 0xD9F7, CPU_FPU); }
+       F P R E M { RET_INSN(5, twobyte, 0xD9F8, CPU_FPU); }
+       F Y L "2" X P "1" { RET_INSN(7, twobyte, 0xD9F9, CPU_FPU); }
+       F S Q R T { RET_INSN(5, twobyte, 0xD9FA, CPU_FPU); }
+       F S I N C O S { RET_INSN(7, twobyte, 0xD9FB, CPU_286|CPU_FPU); }
+       F R N D I N T { RET_INSN(7, twobyte, 0xD9FC, CPU_FPU); }
+       F S C A L E { RET_INSN(6, twobyte, 0xD9FD, CPU_FPU); }
+       F S I N { RET_INSN(4, twobyte, 0xD9FE, CPU_286|CPU_FPU); }
+       F C O S { RET_INSN(4, twobyte, 0xD9FF, CPU_286|CPU_FPU); }
+       F C H S { RET_INSN(4, twobyte, 0xD9E0, CPU_FPU); }
+       F A B S { RET_INSN(4, twobyte, 0xD9E1, CPU_FPU); }
+       F N I N I T { RET_INSN(6, twobyte, 0xDBE3, CPU_FPU); }
+       F I N I T { RET_INSN(5, threebyte, 0x9BDBE3UL, CPU_FPU); }
+       F L D C W { RET_INSN(5, fldnstcw, 0x05, CPU_FPU); }
+       F N S T C W { RET_INSN(6, fldnstcw, 0x07, CPU_FPU); }
+       F S T C W { RET_INSN(5, fstcw, 0, CPU_FPU); }
+       F N S T S W { RET_INSN(6, fnstsw, 0, CPU_FPU); }
+       F S T S W { RET_INSN(5, fstsw, 0, CPU_FPU); }
+       F N C L E X { RET_INSN(6, twobyte, 0xDBE2, CPU_FPU); }
+       F C L E X { RET_INSN(5, threebyte, 0x9BDBE2UL, CPU_FPU); }
+       F N S T E N V { RET_INSN(7, onebytemem, 0x06D9, CPU_FPU); }
+       F S T E N V { RET_INSN(6, twobytemem, 0x069BD9, CPU_FPU); }
+       F L D E N V { RET_INSN(6, onebytemem, 0x04D9, CPU_FPU); }
+       F N S A V E { RET_INSN(6, onebytemem, 0x06DD, CPU_FPU); }
+       F S A V E { RET_INSN(5, twobytemem, 0x069BDD, CPU_FPU); }
+       F R S T O R { RET_INSN(6, onebytemem, 0x04DD, CPU_FPU); }
+       F F R E E { RET_INSN(5, ffree, 0xDD, CPU_FPU); }
+       F F R E E P { RET_INSN(6, ffree, 0xDF, CPU_686|CPU_FPU|CPU_Undoc); }
+       F N O P { RET_INSN(4, twobyte, 0xD9D0, CPU_FPU); }
+       F W A I T { RET_INSN(5, onebyte, 0x009B, CPU_FPU); }
        /* Prefixes (should the others be here too? should wait be a prefix? */
-       W A I T { RET_INSN(onebyte, 0x009B, CPU_Any); }
+       W A I T { RET_INSN(4, onebyte, 0x009B, CPU_Any); }
        /* 486 extensions */
-       B S W A P { RET_INSN(bswap, 0, CPU_486); }
-       X A D D { RET_INSN(cmpxchgxadd, 0xC0, CPU_486); }
-       C M P X C H G { RET_INSN(cmpxchgxadd, 0xB0, CPU_486); }
-       C M P X C H G "486" { RET_INSN(cmpxchgxadd, 0xA6, CPU_486|CPU_Undoc); }
-       I N V D { RET_INSN(twobyte, 0x0F08, CPU_486|CPU_Priv); }
-       W B I N V D { RET_INSN(twobyte, 0x0F09, CPU_486|CPU_Priv); }
-       I N V L P G { RET_INSN(twobytemem, 0x070F01, CPU_486|CPU_Priv); }
+       B S W A P { RET_INSN(5, bswap, 0, CPU_486); }
+       X A D D { RET_INSN(4, cmpxchgxadd, 0xC0, CPU_486); }
+       C M P X C H G { RET_INSN(7, cmpxchgxadd, 0xB0, CPU_486); }
+       C M P X C H G "486" { RET_INSN(10, cmpxchgxadd, 0xA6, CPU_486|CPU_Undoc); }
+       I N V D { RET_INSN(4, twobyte, 0x0F08, CPU_486|CPU_Priv); }
+       W B I N V D { RET_INSN(6, twobyte, 0x0F09, CPU_486|CPU_Priv); }
+       I N V L P G { RET_INSN(6, twobytemem, 0x070F01, CPU_486|CPU_Priv); }
        /* 586+ and late 486 extensions */
-       C P U I D { RET_INSN(twobyte, 0x0FA2, CPU_486); }
+       C P U I D { RET_INSN(5, twobyte, 0x0FA2, CPU_486); }
        /* Pentium extensions */
-       W R M S R { RET_INSN(twobyte, 0x0F30, CPU_586|CPU_Priv); }
-       R D T S C { RET_INSN(twobyte, 0x0F31, CPU_586); }
-       R D M S R { RET_INSN(twobyte, 0x0F32, CPU_586|CPU_Priv); }
-       C M P X C H G "8" B { RET_INSN(cmpxchg8b, 0, CPU_586); }
+       W R M S R { RET_INSN(5, twobyte, 0x0F30, CPU_586|CPU_Priv); }
+       R D T S C { RET_INSN(5, twobyte, 0x0F31, CPU_586); }
+       R D M S R { RET_INSN(5, twobyte, 0x0F32, CPU_586|CPU_Priv); }
+       C M P X C H G "8" B { RET_INSN(9, cmpxchg8b, 0, CPU_586); }
        /* Pentium II/Pentium Pro extensions */
        S Y S E N T E R {
-           if (arch_x86->mode_bits == 64) {
-               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
-               RET_INSN(not64, 0, CPU_Not64);
-           }
-           RET_INSN(twobyte, 0x0F34, CPU_686);
+           not64 = 1;
+           RET_INSN(8, twobyte, 0x0F34, CPU_686);
        }
        S Y S E X I T {
-           if (arch_x86->mode_bits == 64) {
-               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
-               RET_INSN(not64, 0, CPU_Not64);
-           }
-           RET_INSN(twobyte, 0x0F35, CPU_686|CPU_Priv);
-       }
-       F X S A V E { RET_INSN(twobytemem, 0x000FAE, CPU_686|CPU_FPU); }
-       F X R S T O R { RET_INSN(twobytemem, 0x010FAE, CPU_686|CPU_FPU); }
-       R D P M C { RET_INSN(twobyte, 0x0F33, CPU_686); }
-       U D "2" { RET_INSN(twobyte, 0x0F0B, CPU_286); }
-       U D "1" { RET_INSN(twobyte, 0x0FB9, CPU_286|CPU_Undoc); }
-       C M O V O { RET_INSN(cmovcc, 0x00, CPU_686); }
-       C M O V N O { RET_INSN(cmovcc, 0x01, CPU_686); }
-       C M O V B { RET_INSN(cmovcc, 0x02, CPU_686); }
-       C M O V C { RET_INSN(cmovcc, 0x02, CPU_686); }
-       C M O V N A E { RET_INSN(cmovcc, 0x02, CPU_686); }
-       C M O V N B { RET_INSN(cmovcc, 0x03, CPU_686); }
-       C M O V N C { RET_INSN(cmovcc, 0x03, CPU_686); }
-       C M O V A E { RET_INSN(cmovcc, 0x03, CPU_686); }
-       C M O V E { RET_INSN(cmovcc, 0x04, CPU_686); }
-       C M O V Z { RET_INSN(cmovcc, 0x04, CPU_686); }
-       C M O V N E { RET_INSN(cmovcc, 0x05, CPU_686); }
-       C M O V N Z { RET_INSN(cmovcc, 0x05, CPU_686); }
-       C M O V B E { RET_INSN(cmovcc, 0x06, CPU_686); }
-       C M O V N A { RET_INSN(cmovcc, 0x06, CPU_686); }
-       C M O V N B E { RET_INSN(cmovcc, 0x07, CPU_686); }
-       C M O V A { RET_INSN(cmovcc, 0x07, CPU_686); }
-       C M O V S { RET_INSN(cmovcc, 0x08, CPU_686); }
-       C M O V N S { RET_INSN(cmovcc, 0x09, CPU_686); }
-       C M O V P { RET_INSN(cmovcc, 0x0A, CPU_686); }
-       C M O V P E { RET_INSN(cmovcc, 0x0A, CPU_686); }
-       C M O V N P { RET_INSN(cmovcc, 0x0B, CPU_686); }
-       C M O V P O { RET_INSN(cmovcc, 0x0B, CPU_686); }
-       C M O V L { RET_INSN(cmovcc, 0x0C, CPU_686); }
-       C M O V N G E { RET_INSN(cmovcc, 0x0C, CPU_686); }
-       C M O V N L { RET_INSN(cmovcc, 0x0D, CPU_686); }
-       C M O V G E { RET_INSN(cmovcc, 0x0D, CPU_686); }
-       C M O V L E { RET_INSN(cmovcc, 0x0E, CPU_686); }
-       C M O V N G { RET_INSN(cmovcc, 0x0E, CPU_686); }
-       C M O V N L E { RET_INSN(cmovcc, 0x0F, CPU_686); }
-       C M O V G { RET_INSN(cmovcc, 0x0F, CPU_686); }
-       F C M O V B { RET_INSN(fcmovcc, 0xDAC0, CPU_686|CPU_FPU); }
-       F C M O V E { RET_INSN(fcmovcc, 0xDAC8, CPU_686|CPU_FPU); }
-       F C M O V B E { RET_INSN(fcmovcc, 0xDAD0, CPU_686|CPU_FPU); }
-       F C M O V U { RET_INSN(fcmovcc, 0xDAD8, CPU_686|CPU_FPU); }
-       F C M O V N B { RET_INSN(fcmovcc, 0xDBC0, CPU_686|CPU_FPU); }
-       F C M O V N E { RET_INSN(fcmovcc, 0xDBC8, CPU_686|CPU_FPU); }
-       F C M O V N B E { RET_INSN(fcmovcc, 0xDBD0, CPU_686|CPU_FPU); }
-       F C M O V U { RET_INSN(fcmovcc, 0xDBD8, CPU_686|CPU_FPU); }
-       F C O M I { RET_INSN(fcom2, 0xDBF0, CPU_686|CPU_FPU); }
-       F U C O M I { RET_INSN(fcom2, 0xDBE8, CPU_686|CPU_FPU); }
-       F C O M I P { RET_INSN(fcom2, 0xDFF0, CPU_686|CPU_FPU); }
-       F U C O M I P { RET_INSN(fcom2, 0xDFE8, CPU_686|CPU_FPU); }
+           not64 = 1;
+           RET_INSN(7, twobyte, 0x0F35, CPU_686|CPU_Priv);
+       }
+       F X S A V E { RET_INSN(6, twobytemem, 0x000FAE, CPU_686|CPU_FPU); }
+       F X R S T O R { RET_INSN(7, twobytemem, 0x010FAE, CPU_686|CPU_FPU); }
+       R D P M C { RET_INSN(5, twobyte, 0x0F33, CPU_686); }
+       U D "2" { RET_INSN(3, twobyte, 0x0F0B, CPU_286); }
+       U D "1" { RET_INSN(3, twobyte, 0x0FB9, CPU_286|CPU_Undoc); }
+       C M O V O { RET_INSN(5, cmovcc, 0x00, CPU_686); }
+       C M O V N O { RET_INSN(6, cmovcc, 0x01, CPU_686); }
+       C M O V B { RET_INSN(5, cmovcc, 0x02, CPU_686); }
+       C M O V C { RET_INSN(5, cmovcc, 0x02, CPU_686); }
+       C M O V N A E { RET_INSN(7, cmovcc, 0x02, CPU_686); }
+       C M O V N B { RET_INSN(6, cmovcc, 0x03, CPU_686); }
+       C M O V N C { RET_INSN(6, cmovcc, 0x03, CPU_686); }
+       C M O V A E { RET_INSN(6, cmovcc, 0x03, CPU_686); }
+       C M O V E { RET_INSN(5, cmovcc, 0x04, CPU_686); }
+       C M O V Z { RET_INSN(5, cmovcc, 0x04, CPU_686); }
+       C M O V N E { RET_INSN(6, cmovcc, 0x05, CPU_686); }
+       C M O V N Z { RET_INSN(6, cmovcc, 0x05, CPU_686); }
+       C M O V B E { RET_INSN(6, cmovcc, 0x06, CPU_686); }
+       C M O V N A { RET_INSN(6, cmovcc, 0x06, CPU_686); }
+       C M O V N B E { RET_INSN(7, cmovcc, 0x07, CPU_686); }
+       C M O V A { RET_INSN(5, cmovcc, 0x07, CPU_686); }
+       C M O V S { RET_INSN(5, cmovcc, 0x08, CPU_686); }
+       C M O V N S { RET_INSN(6, cmovcc, 0x09, CPU_686); }
+       C M O V P { RET_INSN(5, cmovcc, 0x0A, CPU_686); }
+       C M O V P E { RET_INSN(6, cmovcc, 0x0A, CPU_686); }
+       C M O V N P { RET_INSN(6, cmovcc, 0x0B, CPU_686); }
+       C M O V P O { RET_INSN(6, cmovcc, 0x0B, CPU_686); }
+       C M O V L { RET_INSN(5, cmovcc, 0x0C, CPU_686); }
+       C M O V N G E { RET_INSN(7, cmovcc, 0x0C, CPU_686); }
+       C M O V N L { RET_INSN(6, cmovcc, 0x0D, CPU_686); }
+       C M O V G E { RET_INSN(6, cmovcc, 0x0D, CPU_686); }
+       C M O V L E { RET_INSN(6, cmovcc, 0x0E, CPU_686); }
+       C M O V N G { RET_INSN(6, cmovcc, 0x0E, CPU_686); }
+       C M O V N L E { RET_INSN(7, cmovcc, 0x0F, CPU_686); }
+       C M O V G { RET_INSN(5, cmovcc, 0x0F, CPU_686); }
+       F C M O V B { RET_INSN(6, fcmovcc, 0xDAC0, CPU_686|CPU_FPU); }
+       F C M O V E { RET_INSN(6, fcmovcc, 0xDAC8, CPU_686|CPU_FPU); }
+       F C M O V B E { RET_INSN(7, fcmovcc, 0xDAD0, CPU_686|CPU_FPU); }
+       F C M O V U { RET_INSN(6, fcmovcc, 0xDAD8, CPU_686|CPU_FPU); }
+       F C M O V N B { RET_INSN(7, fcmovcc, 0xDBC0, CPU_686|CPU_FPU); }
+       F C M O V N E { RET_INSN(7, fcmovcc, 0xDBC8, CPU_686|CPU_FPU); }
+       F C M O V N B E { RET_INSN(8, fcmovcc, 0xDBD0, CPU_686|CPU_FPU); }
+       F C M O V U { RET_INSN(6, fcmovcc, 0xDBD8, CPU_686|CPU_FPU); }
+       F C O M I { RET_INSN(5, fcom2, 0xDBF0, CPU_686|CPU_FPU); }
+       F U C O M I { RET_INSN(6, fcom2, 0xDBE8, CPU_686|CPU_FPU); }
+       F C O M I P { RET_INSN(6, fcom2, 0xDFF0, CPU_686|CPU_FPU); }
+       F U C O M I P { RET_INSN(7, fcom2, 0xDFE8, CPU_686|CPU_FPU); }
        /* Pentium4 extensions */
-       M O V N T I { RET_INSN(movnti, 0, CPU_P4); }
-       C L F L U S H { RET_INSN(clflush, 0, CPU_P3); }
-       L F E N C E { RET_INSN(threebyte, 0x0FAEE8, CPU_P3); }
-       M F E N C E { RET_INSN(threebyte, 0x0FAEF0, CPU_P3); }
-       P A U S E { RET_INSN(onebyte_prefix, 0xF390, CPU_P4); }
+       M O V N T I { RET_INSN(6, movnti, 0, CPU_P4); }
+       C L F L U S H { RET_INSN(7, clflush, 0, CPU_P3); }
+       L F E N C E { RET_INSN(6, threebyte, 0x0FAEE8, CPU_P3); }
+       M F E N C E { RET_INSN(6, threebyte, 0x0FAEF0, CPU_P3); }
+       P A U S E { RET_INSN(5, onebyte_prefix, 0xF390, CPU_P4); }
        /* MMX/SSE2 instructions */
-       E M M S { RET_INSN(twobyte, 0x0F77, CPU_MMX); }
-       M O V D { RET_INSN(movd, 0, CPU_MMX); }
-       M O V Q { RET_INSN(movq, 0, CPU_MMX); }
-       P A C K S S D W { RET_INSN(mmxsse2, 0x6B, CPU_MMX); }
-       P A C K S S W B { RET_INSN(mmxsse2, 0x63, CPU_MMX); }
-       P A C K U S W B { RET_INSN(mmxsse2, 0x67, CPU_MMX); }
-       P A D D B { RET_INSN(mmxsse2, 0xFC, CPU_MMX); }
-       P A D D W { RET_INSN(mmxsse2, 0xFD, CPU_MMX); }
-       P A D D D { RET_INSN(mmxsse2, 0xFE, CPU_MMX); }
-       P A D D Q { RET_INSN(mmxsse2, 0xD4, CPU_MMX); }
-       P A D D S B { RET_INSN(mmxsse2, 0xEC, CPU_MMX); }
-       P A D D S W { RET_INSN(mmxsse2, 0xED, CPU_MMX); }
-       P A D D U S B { RET_INSN(mmxsse2, 0xDC, CPU_MMX); }
-       P A D D U S W { RET_INSN(mmxsse2, 0xDD, CPU_MMX); }
-       P A N D { RET_INSN(mmxsse2, 0xDB, CPU_MMX); }
-       P A N D N { RET_INSN(mmxsse2, 0xDF, CPU_MMX); }
-       P C M P E Q B { RET_INSN(mmxsse2, 0x74, CPU_MMX); }
-       P C M P E Q W { RET_INSN(mmxsse2, 0x75, CPU_MMX); }
-       P C M P E Q D { RET_INSN(mmxsse2, 0x76, CPU_MMX); }
-       P C M P G T B { RET_INSN(mmxsse2, 0x64, CPU_MMX); }
-       P C M P G T W { RET_INSN(mmxsse2, 0x65, CPU_MMX); }
-       P C M P G T D { RET_INSN(mmxsse2, 0x66, CPU_MMX); }
-       P M A D D W D { RET_INSN(mmxsse2, 0xF5, CPU_MMX); }
-       P M U L H W { RET_INSN(mmxsse2, 0xE5, CPU_MMX); }
-       P M U L L W { RET_INSN(mmxsse2, 0xD5, CPU_MMX); }
-       P O R { RET_INSN(mmxsse2, 0xEB, CPU_MMX); }
-       P S L L W { RET_INSN(pshift, 0x0671F1, CPU_MMX); }
-       P S L L D { RET_INSN(pshift, 0x0672F2, CPU_MMX); }
-       P S L L Q { RET_INSN(pshift, 0x0673F3, CPU_MMX); }
-       P S R A W { RET_INSN(pshift, 0x0471E1, CPU_MMX); }
-       P S R A D { RET_INSN(pshift, 0x0472E2, CPU_MMX); }
-       P S R L W { RET_INSN(pshift, 0x0271D1, CPU_MMX); }
-       P S R L D { RET_INSN(pshift, 0x0272D2, CPU_MMX); }
-       P S R L Q { RET_INSN(pshift, 0x0273D3, CPU_MMX); }
-       P S U B B { RET_INSN(mmxsse2, 0xF8, CPU_MMX); }
-       P S U B W { RET_INSN(mmxsse2, 0xF9, CPU_MMX); }
-       P S U B D { RET_INSN(mmxsse2, 0xFA, CPU_MMX); }
-       P S U B Q { RET_INSN(mmxsse2, 0xFB, CPU_MMX); }
-       P S U B S B { RET_INSN(mmxsse2, 0xE8, CPU_MMX); }
-       P S U B S W { RET_INSN(mmxsse2, 0xE9, CPU_MMX); }
-       P S U B U S B { RET_INSN(mmxsse2, 0xD8, CPU_MMX); }
-       P S U B U S W { RET_INSN(mmxsse2, 0xD9, CPU_MMX); }
-       P U N P C K H B W { RET_INSN(mmxsse2, 0x68, CPU_MMX); }
-       P U N P C K H W D { RET_INSN(mmxsse2, 0x69, CPU_MMX); }
-       P U N P C K H D Q { RET_INSN(mmxsse2, 0x6A, CPU_MMX); }
-       P U N P C K L B W { RET_INSN(mmxsse2, 0x60, CPU_MMX); }
-       P U N P C K L W D { RET_INSN(mmxsse2, 0x61, CPU_MMX); }
-       P U N P C K L D Q { RET_INSN(mmxsse2, 0x62, CPU_MMX); }
-       P X O R { RET_INSN(mmxsse2, 0xEF, CPU_MMX); }
+       E M M S { RET_INSN(4, twobyte, 0x0F77, CPU_MMX); }
+       M O V D { RET_INSN(4, movd, 0, CPU_MMX); }
+       M O V Q { RET_INSN(4, movq, 0, CPU_MMX); }
+       P A C K S S D W { RET_INSN(8, mmxsse2, 0x6B, CPU_MMX); }
+       P A C K S S W B { RET_INSN(8, mmxsse2, 0x63, CPU_MMX); }
+       P A C K U S W B { RET_INSN(8, mmxsse2, 0x67, CPU_MMX); }
+       P A D D B { RET_INSN(5, mmxsse2, 0xFC, CPU_MMX); }
+       P A D D W { RET_INSN(5, mmxsse2, 0xFD, CPU_MMX); }
+       P A D D D { RET_INSN(5, mmxsse2, 0xFE, CPU_MMX); }
+       P A D D Q { RET_INSN(5, mmxsse2, 0xD4, CPU_MMX); }
+       P A D D S B { RET_INSN(6, mmxsse2, 0xEC, CPU_MMX); }
+       P A D D S W { RET_INSN(6, mmxsse2, 0xED, CPU_MMX); }
+       P A D D U S B { RET_INSN(7, mmxsse2, 0xDC, CPU_MMX); }
+       P A D D U S W { RET_INSN(7, mmxsse2, 0xDD, CPU_MMX); }
+       P A N D { RET_INSN(4, mmxsse2, 0xDB, CPU_MMX); }
+       P A N D N { RET_INSN(5, mmxsse2, 0xDF, CPU_MMX); }
+       P C M P E Q B { RET_INSN(7, mmxsse2, 0x74, CPU_MMX); }
+       P C M P E Q W { RET_INSN(7, mmxsse2, 0x75, CPU_MMX); }
+       P C M P E Q D { RET_INSN(7, mmxsse2, 0x76, CPU_MMX); }
+       P C M P G T B { RET_INSN(7, mmxsse2, 0x64, CPU_MMX); }
+       P C M P G T W { RET_INSN(7, mmxsse2, 0x65, CPU_MMX); }
+       P C M P G T D { RET_INSN(7, mmxsse2, 0x66, CPU_MMX); }
+       P M A D D W D { RET_INSN(7, mmxsse2, 0xF5, CPU_MMX); }
+       P M U L H W { RET_INSN(6, mmxsse2, 0xE5, CPU_MMX); }
+       P M U L L W { RET_INSN(6, mmxsse2, 0xD5, CPU_MMX); }
+       P O R { RET_INSN(3, mmxsse2, 0xEB, CPU_MMX); }
+       P S L L W { RET_INSN(5, pshift, 0x0671F1, CPU_MMX); }
+       P S L L D { RET_INSN(5, pshift, 0x0672F2, CPU_MMX); }
+       P S L L Q { RET_INSN(5, pshift, 0x0673F3, CPU_MMX); }
+       P S R A W { RET_INSN(5, pshift, 0x0471E1, CPU_MMX); }
+       P S R A D { RET_INSN(5, pshift, 0x0472E2, CPU_MMX); }
+       P S R L W { RET_INSN(5, pshift, 0x0271D1, CPU_MMX); }
+       P S R L D { RET_INSN(5, pshift, 0x0272D2, CPU_MMX); }
+       P S R L Q { RET_INSN(5, pshift, 0x0273D3, CPU_MMX); }
+       P S U B B { RET_INSN(5, mmxsse2, 0xF8, CPU_MMX); }
+       P S U B W { RET_INSN(5, mmxsse2, 0xF9, CPU_MMX); }
+       P S U B D { RET_INSN(5, mmxsse2, 0xFA, CPU_MMX); }
+       P S U B Q { RET_INSN(5, mmxsse2, 0xFB, CPU_MMX); }
+       P S U B S B { RET_INSN(6, mmxsse2, 0xE8, CPU_MMX); }
+       P S U B S W { RET_INSN(6, mmxsse2, 0xE9, CPU_MMX); }
+       P S U B U S B { RET_INSN(7, mmxsse2, 0xD8, CPU_MMX); }
+       P S U B U S W { RET_INSN(7, mmxsse2, 0xD9, CPU_MMX); }
+       P U N P C K H B W { RET_INSN(9, mmxsse2, 0x68, CPU_MMX); }
+       P U N P C K H W D { RET_INSN(9, mmxsse2, 0x69, CPU_MMX); }
+       P U N P C K H D Q { RET_INSN(9, mmxsse2, 0x6A, CPU_MMX); }
+       P U N P C K L B W { RET_INSN(9, mmxsse2, 0x60, CPU_MMX); }
+       P U N P C K L W D { RET_INSN(9, mmxsse2, 0x61, CPU_MMX); }
+       P U N P C K L D Q { RET_INSN(9, mmxsse2, 0x62, CPU_MMX); }
+       P X O R { RET_INSN(4, mmxsse2, 0xEF, CPU_MMX); }
        /* PIII (Katmai) new instructions / SIMD instructions */
-       A D D P S { RET_INSN(sseps, 0x58, CPU_SSE); }
-       A D D S S { RET_INSN(ssess, 0xF358, CPU_SSE); }
-       A N D N P S { RET_INSN(sseps, 0x55, CPU_SSE); }
-       A N D P S { RET_INSN(sseps, 0x54, CPU_SSE); }
-       C M P E Q P S { RET_INSN(ssecmpps, 0x00, CPU_SSE); }
-       C M P E Q S S { RET_INSN(ssecmpss, 0x00F3, CPU_SSE); }
-       C M P L E P S { RET_INSN(ssecmpps, 0x02, CPU_SSE); }
-       C M P L E S S { RET_INSN(ssecmpss, 0x02F3, CPU_SSE); }
-       C M P L T P S { RET_INSN(ssecmpps, 0x01, CPU_SSE); }
-       C M P L T S S { RET_INSN(ssecmpss, 0x01F3, CPU_SSE); }
-       C M P N E Q P S { RET_INSN(ssecmpps, 0x04, CPU_SSE); }
-       C M P N E Q S S { RET_INSN(ssecmpss, 0x04F3, CPU_SSE); }
-       C M P N L E P S { RET_INSN(ssecmpps, 0x06, CPU_SSE); }
-       C M P N L E S S { RET_INSN(ssecmpss, 0x06F3, CPU_SSE); }
-       C M P N L T P S { RET_INSN(ssecmpps, 0x05, CPU_SSE); }
-       C M P N L T S S { RET_INSN(ssecmpss, 0x05F3, CPU_SSE); }
-       C M P O R D P S { RET_INSN(ssecmpps, 0x07, CPU_SSE); }
-       C M P O R D S S { RET_INSN(ssecmpss, 0x07F3, CPU_SSE); }
-       C M P U N O R D P S { RET_INSN(ssecmpps, 0x03, CPU_SSE); }
-       C M P U N O R D S S { RET_INSN(ssecmpss, 0x03F3, CPU_SSE); }
-       C M P P S { RET_INSN(ssepsimm, 0xC2, CPU_SSE); }
-       C M P S S { RET_INSN(ssessimm, 0xF3C2, CPU_SSE); }
-       C O M I S S { RET_INSN(sseps, 0x2F, CPU_SSE); }
-       C V T P I "2" P S { RET_INSN(cvt_xmm_mm_ps, 0x2A, CPU_SSE); }
-       C V T P S "2" P I { RET_INSN(cvt_mm_xmm64, 0x2D, CPU_SSE); }
-       C V T S I "2" S S { RET_INSN(cvt_xmm_rmx, 0xF32A, CPU_SSE); }
-       C V T S S "2" S I { RET_INSN(cvt_rx_xmm32, 0xF32D, CPU_SSE); }
-       C V T T P S "2" P I { RET_INSN(cvt_mm_xmm64, 0x2C, CPU_SSE); }
-       C V T T S S "2" S I { RET_INSN(cvt_rx_xmm32, 0xF32C, CPU_SSE); }
-       D I V P S { RET_INSN(sseps, 0x5E, CPU_SSE); }
-       D I V S S { RET_INSN(ssess, 0xF35E, CPU_SSE); }
-       L D M X C S R { RET_INSN(ldstmxcsr, 0x02, CPU_SSE); }
-       M A S K M O V Q { RET_INSN(maskmovq, 0, CPU_P3|CPU_MMX); }
-       M A X P S { RET_INSN(sseps, 0x5F, CPU_SSE); }
-       M A X S S { RET_INSN(ssess, 0xF35F, CPU_SSE); }
-       M I N P S { RET_INSN(sseps, 0x5D, CPU_SSE); }
-       M I N S S { RET_INSN(ssess, 0xF35D, CPU_SSE); }
-       M O V A P S { RET_INSN(movaups, 0x28, CPU_SSE); }
-       M O V H L P S { RET_INSN(movhllhps, 0x12, CPU_SSE); }
-       M O V H P S { RET_INSN(movhlps, 0x16, CPU_SSE); }
-       M O V L H P S { RET_INSN(movhllhps, 0x16, CPU_SSE); }
-       M O V L P S { RET_INSN(movhlps, 0x12, CPU_SSE); }
-       M O V M S K P S { RET_INSN(movmskps, 0, CPU_SSE); }
-       M O V N T P S { RET_INSN(movntps, 0, CPU_SSE); }
-       M O V N T Q { RET_INSN(movntq, 0, CPU_SSE); }
-       M O V S S { RET_INSN(movss, 0, CPU_SSE); }
-       M O V U P S { RET_INSN(movaups, 0x10, CPU_SSE); }
-       M U L P S { RET_INSN(sseps, 0x59, CPU_SSE); }
-       M U L S S { RET_INSN(ssess, 0xF359, CPU_SSE); }
-       O R P S { RET_INSN(sseps, 0x56, CPU_SSE); }
-       P A V G B { RET_INSN(mmxsse2, 0xE0, CPU_P3|CPU_MMX); }
-       P A V G W { RET_INSN(mmxsse2, 0xE3, CPU_P3|CPU_MMX); }
-       P E X T R W { RET_INSN(pextrw, 0, CPU_P3|CPU_MMX); }
-       P I N S R W { RET_INSN(pinsrw, 0, CPU_P3|CPU_MMX); }
-       P M A X S W { RET_INSN(mmxsse2, 0xEE, CPU_P3|CPU_MMX); }
-       P M A X U B { RET_INSN(mmxsse2, 0xDE, CPU_P3|CPU_MMX); }
-       P M I N S W { RET_INSN(mmxsse2, 0xEA, CPU_P3|CPU_MMX); }
-       P M I N U B { RET_INSN(mmxsse2, 0xDA, CPU_P3|CPU_MMX); }
-       P M O V M S K B { RET_INSN(pmovmskb, 0, CPU_SSE); }
-       P M U L H U W { RET_INSN(mmxsse2, 0xE4, CPU_P3|CPU_MMX); }
-       P R E F E T C H N T A { RET_INSN(twobytemem, 0x000F18, CPU_P3); }
-       P R E F E T C H T "0" { RET_INSN(twobytemem, 0x010F18, CPU_P3); }
-       P R E F E T C H T "1" { RET_INSN(twobytemem, 0x020F18, CPU_P3); }
-       P R E F E T C H T "2" { RET_INSN(twobytemem, 0x030F18, CPU_P3); }
-       P S A D B W { RET_INSN(mmxsse2, 0xF6, CPU_P3|CPU_MMX); }
-       P S H U F W { RET_INSN(pshufw, 0, CPU_P3|CPU_MMX); }
-       R C P P S { RET_INSN(sseps, 0x53, CPU_SSE); }
-       R C P S S { RET_INSN(ssess, 0xF353, CPU_SSE); }
-       R S Q R T P S { RET_INSN(sseps, 0x52, CPU_SSE); }
-       R S Q R T S S { RET_INSN(ssess, 0xF352, CPU_SSE); }
-       S F E N C E { RET_INSN(threebyte, 0x0FAEF8, CPU_P3); }
-       S H U F P S { RET_INSN(ssepsimm, 0xC6, CPU_SSE); }
-       S Q R T P S { RET_INSN(sseps, 0x51, CPU_SSE); }
-       S Q R T S S { RET_INSN(ssess, 0xF351, CPU_SSE); }
-       S T M X C S R { RET_INSN(ldstmxcsr, 0x03, CPU_SSE); }
-       S U B P S { RET_INSN(sseps, 0x5C, CPU_SSE); }
-       S U B S S { RET_INSN(ssess, 0xF35C, CPU_SSE); }
-       U C O M I S S { RET_INSN(ssess, 0x2E, CPU_SSE); }
-       U N P C K H P S { RET_INSN(sseps, 0x15, CPU_SSE); }
-       U N P C K L P S { RET_INSN(sseps, 0x14, CPU_SSE); }
-       X O R P S { RET_INSN(sseps, 0x57, CPU_SSE); }
+       A D D P S { RET_INSN(5, sseps, 0x58, CPU_SSE); }
+       A D D S S { RET_INSN(5, ssess, 0xF358, CPU_SSE); }
+       A N D N P S { RET_INSN(6, sseps, 0x55, CPU_SSE); }
+       A N D P S { RET_INSN(5, sseps, 0x54, CPU_SSE); }
+       C M P E Q P S { RET_INSN(7, ssecmpps, 0x00, CPU_SSE); }
+       C M P E Q S S { RET_INSN(7, ssecmpss, 0x00F3, CPU_SSE); }
+       C M P L E P S { RET_INSN(7, ssecmpps, 0x02, CPU_SSE); }
+       C M P L E S S { RET_INSN(7, ssecmpss, 0x02F3, CPU_SSE); }
+       C M P L T P S { RET_INSN(7, ssecmpps, 0x01, CPU_SSE); }
+       C M P L T S S { RET_INSN(7, ssecmpss, 0x01F3, CPU_SSE); }
+       C M P N E Q P S { RET_INSN(8, ssecmpps, 0x04, CPU_SSE); }
+       C M P N E Q S S { RET_INSN(8, ssecmpss, 0x04F3, CPU_SSE); }
+       C M P N L E P S { RET_INSN(8, ssecmpps, 0x06, CPU_SSE); }
+       C M P N L E S S { RET_INSN(8, ssecmpss, 0x06F3, CPU_SSE); }
+       C M P N L T P S { RET_INSN(8, ssecmpps, 0x05, CPU_SSE); }
+       C M P N L T S S { RET_INSN(8, ssecmpss, 0x05F3, CPU_SSE); }
+       C M P O R D P S { RET_INSN(8, ssecmpps, 0x07, CPU_SSE); }
+       C M P O R D S S { RET_INSN(8, ssecmpss, 0x07F3, CPU_SSE); }
+       C M P U N O R D P S { RET_INSN(10, ssecmpps, 0x03, CPU_SSE); }
+       C M P U N O R D S S { RET_INSN(10, ssecmpss, 0x03F3, CPU_SSE); }
+       C M P P S { RET_INSN(5, ssepsimm, 0xC2, CPU_SSE); }
+       C M P S S { RET_INSN(5, ssessimm, 0xF3C2, CPU_SSE); }
+       C O M I S S { RET_INSN(6, sseps, 0x2F, CPU_SSE); }
+       C V T P I "2" P S { RET_INSN(8, cvt_xmm_mm_ps, 0x2A, CPU_SSE); }
+       C V T P S "2" P I { RET_INSN(8, cvt_mm_xmm64, 0x2D, CPU_SSE); }
+       C V T S I "2" S S { RET_INSN(8, cvt_xmm_rmx, 0xF32A, CPU_SSE); }
+       C V T S S "2" S I { RET_INSN(8, cvt_rx_xmm32, 0xF32D, CPU_SSE); }
+       C V T T P S "2" P I { RET_INSN(9, cvt_mm_xmm64, 0x2C, CPU_SSE); }
+       C V T T S S "2" S I { RET_INSN(9, cvt_rx_xmm32, 0xF32C, CPU_SSE); }
+       D I V P S { RET_INSN(5, sseps, 0x5E, CPU_SSE); }
+       D I V S S { RET_INSN(5, ssess, 0xF35E, CPU_SSE); }
+       L D M X C S R { RET_INSN(7, ldstmxcsr, 0x02, CPU_SSE); }
+       M A S K M O V Q { RET_INSN(8, maskmovq, 0, CPU_P3|CPU_MMX); }
+       M A X P S { RET_INSN(5, sseps, 0x5F, CPU_SSE); }
+       M A X S S { RET_INSN_NS(ssess, 0xF35F, CPU_SSE); }
+       M I N P S { RET_INSN_NS(sseps, 0x5D, CPU_SSE); }
+       M I N S S { RET_INSN_NS(ssess, 0xF35D, CPU_SSE); }
+       M O V A P S { RET_INSN_NS(movaups, 0x28, CPU_SSE); }
+       M O V H L P S { RET_INSN_NS(movhllhps, 0x12, CPU_SSE); }
+       M O V H P S { RET_INSN_NS(movhlps, 0x16, CPU_SSE); }
+       M O V L H P S { RET_INSN_NS(movhllhps, 0x16, CPU_SSE); }
+       M O V L P S { RET_INSN_NS(movhlps, 0x12, CPU_SSE); }
+       M O V M S K P S { RET_INSN_NS(movmskps, 0, CPU_SSE); }
+       M O V N T P S { RET_INSN_NS(movntps, 0, CPU_SSE); }
+       M O V N T Q { RET_INSN_NS(movntq, 0, CPU_SSE); }
+       M O V S S { RET_INSN_NS(movss, 0, CPU_SSE); }
+       M O V U P S { RET_INSN_NS(movaups, 0x10, CPU_SSE); }
+       M U L P S { RET_INSN_NS(sseps, 0x59, CPU_SSE); }
+       M U L S S { RET_INSN_NS(ssess, 0xF359, CPU_SSE); }
+       O R P S { RET_INSN_NS(sseps, 0x56, CPU_SSE); }
+       P A V G B { RET_INSN_NS(mmxsse2, 0xE0, CPU_P3|CPU_MMX); }
+       P A V G W { RET_INSN_NS(mmxsse2, 0xE3, CPU_P3|CPU_MMX); }
+       P E X T R W { RET_INSN_NS(pextrw, 0, CPU_P3|CPU_MMX); }
+       P I N S R W { RET_INSN_NS(pinsrw, 0, CPU_P3|CPU_MMX); }
+       P M A X S W { RET_INSN_NS(mmxsse2, 0xEE, CPU_P3|CPU_MMX); }
+       P M A X U B { RET_INSN_NS(mmxsse2, 0xDE, CPU_P3|CPU_MMX); }
+       P M I N S W { RET_INSN_NS(mmxsse2, 0xEA, CPU_P3|CPU_MMX); }
+       P M I N U B { RET_INSN_NS(mmxsse2, 0xDA, CPU_P3|CPU_MMX); }
+       P M O V M S K B { RET_INSN_NS(pmovmskb, 0, CPU_SSE); }
+       P M U L H U W { RET_INSN_NS(mmxsse2, 0xE4, CPU_P3|CPU_MMX); }
+       P R E F E T C H N T A { RET_INSN_NS(twobytemem, 0x000F18, CPU_P3); }
+       P R E F E T C H T "0" { RET_INSN_NS(twobytemem, 0x010F18, CPU_P3); }
+       P R E F E T C H T "1" { RET_INSN_NS(twobytemem, 0x020F18, CPU_P3); }
+       P R E F E T C H T "2" { RET_INSN_NS(twobytemem, 0x030F18, CPU_P3); }
+       P S A D B W { RET_INSN_NS(mmxsse2, 0xF6, CPU_P3|CPU_MMX); }
+       P S H U F W { RET_INSN_NS(pshufw, 0, CPU_P3|CPU_MMX); }
+       R C P P S { RET_INSN_NS(sseps, 0x53, CPU_SSE); }
+       R C P S S { RET_INSN_NS(ssess, 0xF353, CPU_SSE); }
+       R S Q R T P S { RET_INSN_NS(sseps, 0x52, CPU_SSE); }
+       R S Q R T S S { RET_INSN_NS(ssess, 0xF352, CPU_SSE); }
+       S F E N C E { RET_INSN_NS(threebyte, 0x0FAEF8, CPU_P3); }
+       S H U F P S { RET_INSN_NS(ssepsimm, 0xC6, CPU_SSE); }
+       S Q R T P S { RET_INSN_NS(sseps, 0x51, CPU_SSE); }
+       S Q R T S S { RET_INSN_NS(ssess, 0xF351, CPU_SSE); }
+       S T M X C S R { RET_INSN_NS(ldstmxcsr, 0x03, CPU_SSE); }
+       S U B P S { RET_INSN_NS(sseps, 0x5C, CPU_SSE); }
+       S U B S S { RET_INSN_NS(ssess, 0xF35C, CPU_SSE); }
+       U C O M I S S { RET_INSN_NS(ssess, 0x2E, CPU_SSE); }
+       U N P C K H P S { RET_INSN_NS(sseps, 0x15, CPU_SSE); }
+       U N P C K L P S { RET_INSN_NS(sseps, 0x14, CPU_SSE); }
+       X O R P S { RET_INSN_NS(sseps, 0x57, CPU_SSE); }
        /* SSE2 instructions */
-       A D D P D { RET_INSN(ssess, 0x6658, CPU_SSE2); }
-       A D D S D { RET_INSN(ssess, 0xF258, CPU_SSE2); }
-       A N D N P D { RET_INSN(ssess, 0x6655, CPU_SSE2); }
-       A N D P D { RET_INSN(ssess, 0x6654, CPU_SSE2); }
-       C M P E Q P D { RET_INSN(ssecmpss, 0x0066, CPU_SSE2); }
-       C M P E Q S D { RET_INSN(ssecmpss, 0x00F2, CPU_SSE2); }
-       C M P L E P D { RET_INSN(ssecmpss, 0x0266, CPU_SSE2); }
-       C M P L E S D { RET_INSN(ssecmpss, 0x02F2, CPU_SSE2); }
-       C M P L T P D { RET_INSN(ssecmpss, 0x0166, CPU_SSE2); }
-       C M P L T S D { RET_INSN(ssecmpss, 0x01F2, CPU_SSE2); }
-       C M P N E Q P D { RET_INSN(ssecmpss, 0x0466, CPU_SSE2); }
-       C M P N E Q S D { RET_INSN(ssecmpss, 0x04F2, CPU_SSE2); }
-       C M P N L E P D { RET_INSN(ssecmpss, 0x0666, CPU_SSE2); }
-       C M P N L E S D { RET_INSN(ssecmpss, 0x06F2, CPU_SSE2); }
-       C M P N L T P D { RET_INSN(ssecmpss, 0x0566, CPU_SSE2); }
-       C M P N L T S D { RET_INSN(ssecmpss, 0x05F2, CPU_SSE2); }
-       C M P O R D P D { RET_INSN(ssecmpss, 0x0766, CPU_SSE2); }
-       C M P O R D S D { RET_INSN(ssecmpss, 0x07F2, CPU_SSE2); }
-       C M P U N O R D P D { RET_INSN(ssecmpss, 0x0366, CPU_SSE2); }
-       C M P U N O R D S D { RET_INSN(ssecmpss, 0x03F2, CPU_SSE2); }
-       C M P P D { RET_INSN(ssessimm, 0x66C2, CPU_SSE2); }
+       A D D P D { RET_INSN_NS(ssess, 0x6658, CPU_SSE2); }
+       A D D S D { RET_INSN_NS(ssess, 0xF258, CPU_SSE2); }
+       A N D N P D { RET_INSN_NS(ssess, 0x6655, CPU_SSE2); }
+       A N D P D { RET_INSN_NS(ssess, 0x6654, CPU_SSE2); }
+       C M P E Q P D { RET_INSN_NS(ssecmpss, 0x0066, CPU_SSE2); }
+       C M P E Q S D { RET_INSN_NS(ssecmpss, 0x00F2, CPU_SSE2); }
+       C M P L E P D { RET_INSN_NS(ssecmpss, 0x0266, CPU_SSE2); }
+       C M P L E S D { RET_INSN_NS(ssecmpss, 0x02F2, CPU_SSE2); }
+       C M P L T P D { RET_INSN_NS(ssecmpss, 0x0166, CPU_SSE2); }
+       C M P L T S D { RET_INSN_NS(ssecmpss, 0x01F2, CPU_SSE2); }
+       C M P N E Q P D { RET_INSN_NS(ssecmpss, 0x0466, CPU_SSE2); }
+       C M P N E Q S D { RET_INSN_NS(ssecmpss, 0x04F2, CPU_SSE2); }
+       C M P N L E P D { RET_INSN_NS(ssecmpss, 0x0666, CPU_SSE2); }
+       C M P N L E S D { RET_INSN_NS(ssecmpss, 0x06F2, CPU_SSE2); }
+       C M P N L T P D { RET_INSN_NS(ssecmpss, 0x0566, CPU_SSE2); }
+       C M P N L T S D { RET_INSN_NS(ssecmpss, 0x05F2, CPU_SSE2); }
+       C M P O R D P D { RET_INSN_NS(ssecmpss, 0x0766, CPU_SSE2); }
+       C M P O R D S D { RET_INSN_NS(ssecmpss, 0x07F2, CPU_SSE2); }
+       C M P U N O R D P D { RET_INSN_NS(ssecmpss, 0x0366, CPU_SSE2); }
+       C M P U N O R D S D { RET_INSN_NS(ssecmpss, 0x03F2, CPU_SSE2); }
+       C M P P D { RET_INSN_NS(ssessimm, 0x66C2, CPU_SSE2); }
        /* C M P S D is in string instructions above */
-       C O M I S D { RET_INSN(ssess, 0x662F, CPU_SSE2); }
-       C V T P I "2" P D { RET_INSN(cvt_xmm_mm_ss, 0x662A, CPU_SSE2); }
-       C V T S I "2" S D { RET_INSN(cvt_xmm_rmx, 0xF22A, CPU_SSE2); }
-       D I V P D { RET_INSN(ssess, 0x665E, CPU_SSE2); }
-       D I V S D { RET_INSN(ssess, 0xF25E, CPU_SSE2); }
-       M A X P D { RET_INSN(ssess, 0x665F, CPU_SSE2); }
-       M A X S D { RET_INSN(ssess, 0xF25F, CPU_SSE2); }
-       M I N P D { RET_INSN(ssess, 0x665D, CPU_SSE2); }
-       M I N S D { RET_INSN(ssess, 0xF25D, CPU_SSE2); }
-       M O V A P D { RET_INSN(movaupd, 0x28, CPU_SSE2); }
-       M O V H P D { RET_INSN(movhlpd, 0x16, CPU_SSE2); }
-       M O V L P D { RET_INSN(movhlpd, 0x12, CPU_SSE2); }
-       M O V M S K P D { RET_INSN(movmskpd, 0, CPU_SSE2); }
-       M O V N T P D { RET_INSN(movntpddq, 0x2B, CPU_SSE2); }
-       M O V N T D Q { RET_INSN(movntpddq, 0xE7, CPU_SSE2); }
+       C O M I S D { RET_INSN_NS(ssess, 0x662F, CPU_SSE2); }
+       C V T P I "2" P D { RET_INSN_NS(cvt_xmm_mm_ss, 0x662A, CPU_SSE2); }
+       C V T S I "2" S D { RET_INSN_NS(cvt_xmm_rmx, 0xF22A, CPU_SSE2); }
+       D I V P D { RET_INSN_NS(ssess, 0x665E, CPU_SSE2); }
+       D I V S D { RET_INSN_NS(ssess, 0xF25E, CPU_SSE2); }
+       M A X P D { RET_INSN_NS(ssess, 0x665F, CPU_SSE2); }
+       M A X S D { RET_INSN_NS(ssess, 0xF25F, CPU_SSE2); }
+       M I N P D { RET_INSN_NS(ssess, 0x665D, CPU_SSE2); }
+       M I N S D { RET_INSN_NS(ssess, 0xF25D, CPU_SSE2); }
+       M O V A P D { RET_INSN_NS(movaupd, 0x28, CPU_SSE2); }
+       M O V H P D { RET_INSN_NS(movhlpd, 0x16, CPU_SSE2); }
+       M O V L P D { RET_INSN_NS(movhlpd, 0x12, CPU_SSE2); }
+       M O V M S K P D { RET_INSN_NS(movmskpd, 0, CPU_SSE2); }
+       M O V N T P D { RET_INSN_NS(movntpddq, 0x2B, CPU_SSE2); }
+       M O V N T D Q { RET_INSN_NS(movntpddq, 0xE7, CPU_SSE2); }
        /* M O V S D is in string instructions above */
-       M O V U P D { RET_INSN(movaupd, 0x10, CPU_SSE2); }
-       M U L P D { RET_INSN(ssess, 0x6659, CPU_SSE2); }
-       M U L S D { RET_INSN(ssess, 0xF259, CPU_SSE2); }
-       O R P D { RET_INSN(ssess, 0x6656, CPU_SSE2); }
-       S H U F P D { RET_INSN(ssessimm, 0x66C6, CPU_SSE2); }
-       S Q R T P D { RET_INSN(ssess, 0x6651, CPU_SSE2); }
-       S Q R T S D { RET_INSN(ssess, 0xF251, CPU_SSE2); }
-       S U B P D { RET_INSN(ssess, 0x665C, CPU_SSE2); }
-       S U B S D { RET_INSN(ssess, 0xF25C, CPU_SSE2); }
-       U C O M I S D { RET_INSN(ssess, 0x662E, CPU_SSE2); }
-       U N P C K H P D { RET_INSN(ssess, 0x6615, CPU_SSE2); }
-       U N P C K L P D { RET_INSN(ssess, 0x6614, CPU_SSE2); }
-       X O R P D { RET_INSN(ssess, 0x6657, CPU_SSE2); }
-       C V T D Q "2" P D { RET_INSN(cvt_xmm_xmm64_ss, 0xF3E6, CPU_SSE2); }
-       C V T P D "2" D Q { RET_INSN(ssess, 0xF2E6, CPU_SSE2); }
-       C V T D Q "2" P S { RET_INSN(sseps, 0x5B, CPU_SSE2); }
-       C V T P D "2" P I { RET_INSN(cvt_mm_xmm, 0x662D, CPU_SSE2); }
-       C V T P D "2" P S { RET_INSN(ssess, 0x665A, CPU_SSE2); }
-       C V T P S "2" P D { RET_INSN(cvt_xmm_xmm64_ps, 0x5A, CPU_SSE2); }
-       C V T P S "2" D Q { RET_INSN(ssess, 0x665B, CPU_SSE2); }
-       C V T S D "2" S I { RET_INSN(cvt_rx_xmm64, 0xF22D, CPU_SSE2); }
-       C V T S D "2" S S { RET_INSN(cvt_xmm_xmm64_ss, 0xF25A, CPU_SSE2); }
+       M O V U P D { RET_INSN_NS(movaupd, 0x10, CPU_SSE2); }
+       M U L P D { RET_INSN_NS(ssess, 0x6659, CPU_SSE2); }
+       M U L S D { RET_INSN_NS(ssess, 0xF259, CPU_SSE2); }
+       O R P D { RET_INSN_NS(ssess, 0x6656, CPU_SSE2); }
+       S H U F P D { RET_INSN_NS(ssessimm, 0x66C6, CPU_SSE2); }
+       S Q R T P D { RET_INSN_NS(ssess, 0x6651, CPU_SSE2); }
+       S Q R T S D { RET_INSN_NS(ssess, 0xF251, CPU_SSE2); }
+       S U B P D { RET_INSN_NS(ssess, 0x665C, CPU_SSE2); }
+       S U B S D { RET_INSN_NS(ssess, 0xF25C, CPU_SSE2); }
+       U C O M I S D { RET_INSN_NS(ssess, 0x662E, CPU_SSE2); }
+       U N P C K H P D { RET_INSN_NS(ssess, 0x6615, CPU_SSE2); }
+       U N P C K L P D { RET_INSN_NS(ssess, 0x6614, CPU_SSE2); }
+       X O R P D { RET_INSN_NS(ssess, 0x6657, CPU_SSE2); }
+       C V T D Q "2" P D { RET_INSN_NS(cvt_xmm_xmm64_ss, 0xF3E6, CPU_SSE2); }
+       C V T P D "2" D Q { RET_INSN_NS(ssess, 0xF2E6, CPU_SSE2); }
+       C V T D Q "2" P S { RET_INSN_NS(sseps, 0x5B, CPU_SSE2); }
+       C V T P D "2" P I { RET_INSN_NS(cvt_mm_xmm, 0x662D, CPU_SSE2); }
+       C V T P D "2" P S { RET_INSN_NS(ssess, 0x665A, CPU_SSE2); }
+       C V T P S "2" P D { RET_INSN_NS(cvt_xmm_xmm64_ps, 0x5A, CPU_SSE2); }
+       C V T P S "2" D Q { RET_INSN_NS(ssess, 0x665B, CPU_SSE2); }
+       C V T S D "2" S I { RET_INSN_NS(cvt_rx_xmm64, 0xF22D, CPU_SSE2); }
+       C V T S D "2" S S { RET_INSN_NS(cvt_xmm_xmm64_ss, 0xF25A, CPU_SSE2); }
        /* P4 VMX Instructions */
-       V M C A L L     { RET_INSN(threebyte, 0x0F01C1, CPU_P4); }
-       V M L A U N C H { RET_INSN(threebyte, 0x0F01C2, CPU_P4); }
-       V M R E S U M E { RET_INSN(threebyte, 0x0F01C3, CPU_P4); }
-       V M X O F F     { RET_INSN(threebyte, 0x0F01C4, CPU_P4); }
-       V M R E A D   { RET_INSN(vmxmemrd, 0x0F78, CPU_P4); }
-       V M W R I T E { RET_INSN(vmxmemwr, 0x0F79, CPU_P4); }
-       V M P T R L D { RET_INSN(vmxtwobytemem, 0x06C7, CPU_P4); }
-       V M P T R S T { RET_INSN(vmxtwobytemem, 0x07C7, CPU_P4); }
-       V M C L E A R { RET_INSN(vmxthreebytemem, 0x0666C7, CPU_P4); }
-       V M X O N     { RET_INSN(vmxthreebytemem, 0x06F3C7, CPU_P4); }
-       C V T S S "2" S D { RET_INSN(cvt_xmm_xmm32, 0xF35A, CPU_SSE2); }
-       C V T T P D "2" P I { RET_INSN(cvt_mm_xmm, 0x662C, CPU_SSE2); }
-       C V T T S D "2" S I { RET_INSN(cvt_rx_xmm64, 0xF22C, CPU_SSE2); }
-       C V T T P D "2" D Q { RET_INSN(ssess, 0x66E6, CPU_SSE2); }
-       C V T T P S "2" D Q { RET_INSN(ssess, 0xF35B, CPU_SSE2); }
-       M A S K M O V D Q U { RET_INSN(maskmovdqu, 0, CPU_SSE2); }
-       M O V D Q A { RET_INSN(movdqau, 0x66, CPU_SSE2); }
-       M O V D Q U { RET_INSN(movdqau, 0xF3, CPU_SSE2); }
-       M O V D Q "2" Q { RET_INSN(movdq2q, 0, CPU_SSE2); }
-       M O V Q "2" D Q { RET_INSN(movq2dq, 0, CPU_SSE2); }
-       P M U L U D Q { RET_INSN(mmxsse2, 0xF4, CPU_SSE2); }
-       P S H U F D { RET_INSN(ssessimm, 0x6670, CPU_SSE2); }
-       P S H U F H W { RET_INSN(ssessimm, 0xF370, CPU_SSE2); }
-       P S H U F L W { RET_INSN(ssessimm, 0xF270, CPU_SSE2); }
-       P S L L D Q { RET_INSN(pslrldq, 0x07, CPU_SSE2); }
-       P S R L D Q { RET_INSN(pslrldq, 0x03, CPU_SSE2); }
-       P U N P C K H Q D Q { RET_INSN(ssess, 0x666D, CPU_SSE2); }
-       P U N P C K L Q D Q { RET_INSN(ssess, 0x666C, CPU_SSE2); }
+       V M C A L L     { RET_INSN_NS(threebyte, 0x0F01C1, CPU_P4); }
+       V M L A U N C H { RET_INSN_NS(threebyte, 0x0F01C2, CPU_P4); }
+       V M R E S U M E { RET_INSN_NS(threebyte, 0x0F01C3, CPU_P4); }
+       V M X O F F     { RET_INSN_NS(threebyte, 0x0F01C4, CPU_P4); }
+       V M R E A D   { RET_INSN_NS(vmxmemrd, 0x0F78, CPU_P4); }
+       V M W R I T E { RET_INSN_NS(vmxmemwr, 0x0F79, CPU_P4); }
+       V M P T R L D { RET_INSN_NS(vmxtwobytemem, 0x06C7, CPU_P4); }
+       V M P T R S T { RET_INSN_NS(vmxtwobytemem, 0x07C7, CPU_P4); }
+       V M C L E A R { RET_INSN_NS(vmxthreebytemem, 0x0666C7, CPU_P4); }
+       V M X O N     { RET_INSN_NS(vmxthreebytemem, 0x06F3C7, CPU_P4); }
+       C V T S S "2" S D { RET_INSN_NS(cvt_xmm_xmm32, 0xF35A, CPU_SSE2); }
+       C V T T P D "2" P I { RET_INSN_NS(cvt_mm_xmm, 0x662C, CPU_SSE2); }
+       C V T T S D "2" S I { RET_INSN_NS(cvt_rx_xmm64, 0xF22C, CPU_SSE2); }
+       C V T T P D "2" D Q { RET_INSN_NS(ssess, 0x66E6, CPU_SSE2); }
+       C V T T P S "2" D Q { RET_INSN_NS(ssess, 0xF35B, CPU_SSE2); }
+       M A S K M O V D Q U { RET_INSN_NS(maskmovdqu, 0, CPU_SSE2); }
+       M O V D Q A { RET_INSN_NS(movdqau, 0x66, CPU_SSE2); }
+       M O V D Q U { RET_INSN_NS(movdqau, 0xF3, CPU_SSE2); }
+       M O V D Q "2" Q { RET_INSN_NS(movdq2q, 0, CPU_SSE2); }
+       M O V Q "2" D Q { RET_INSN_NS(movq2dq, 0, CPU_SSE2); }
+       P M U L U D Q { RET_INSN_NS(mmxsse2, 0xF4, CPU_SSE2); }
+       P S H U F D { RET_INSN_NS(ssessimm, 0x6670, CPU_SSE2); }
+       P S H U F H W { RET_INSN_NS(ssessimm, 0xF370, CPU_SSE2); }
+       P S H U F L W { RET_INSN_NS(ssessimm, 0xF270, CPU_SSE2); }
+       P S L L D Q { RET_INSN_NS(pslrldq, 0x07, CPU_SSE2); }
+       P S R L D Q { RET_INSN_NS(pslrldq, 0x03, CPU_SSE2); }
+       P U N P C K H Q D Q { RET_INSN_NS(ssess, 0x666D, CPU_SSE2); }
+       P U N P C K L Q D Q { RET_INSN_NS(ssess, 0x666C, CPU_SSE2); }
        /* SSE3 / PNI (Prescott New Instructions) instructions */
-       A D D S U B P D { RET_INSN(ssess, 0x66D0, CPU_SSE3); }
-       A D D S U B P S { RET_INSN(ssess, 0xF2D0, CPU_SSE3); }
-       F I S T T P { RET_INSN(fildstp, 0x010001, CPU_SSE3); }
-       H A D D P D { RET_INSN(ssess, 0x667C, CPU_SSE3); }
-       H A D D P S { RET_INSN(ssess, 0xF27C, CPU_SSE3); }
-       H S U B P D { RET_INSN(ssess, 0x667D, CPU_SSE3); }
-       H S U B P S { RET_INSN(ssess, 0xF27D, CPU_SSE3); }
-       L D D Q U { RET_INSN(lddqu, 0, CPU_SSE3); }
-       M O N I T O R { RET_INSN(threebyte, 0x0F01C8, CPU_SSE3); }
-       M O V D D U P { RET_INSN(cvt_xmm_xmm64_ss, 0xF212, CPU_SSE3); }
-       M O V S H D U P { RET_INSN(ssess, 0xF316, CPU_SSE3); }
-       M O V S L D U P { RET_INSN(ssess, 0xF312, CPU_SSE3); }
-       M W A I T { RET_INSN(threebyte, 0x0F01C9, CPU_SSE3); }
+       A D D S U B P D { RET_INSN_NS(ssess, 0x66D0, CPU_SSE3); }
+       A D D S U B P S { RET_INSN_NS(ssess, 0xF2D0, CPU_SSE3); }
+       F I S T T P { RET_INSN_NS(fildstp, 0x010001, CPU_SSE3); }
+       H A D D P D { RET_INSN_NS(ssess, 0x667C, CPU_SSE3); }
+       H A D D P S { RET_INSN_NS(ssess, 0xF27C, CPU_SSE3); }
+       H S U B P D { RET_INSN_NS(ssess, 0x667D, CPU_SSE3); }
+       H S U B P S { RET_INSN_NS(ssess, 0xF27D, CPU_SSE3); }
+       L D D Q U { RET_INSN_NS(lddqu, 0, CPU_SSE3); }
+       M O N I T O R { RET_INSN_NS(threebyte, 0x0F01C8, CPU_SSE3); }
+       M O V D D U P { RET_INSN_NS(cvt_xmm_xmm64_ss, 0xF212, CPU_SSE3); }
+       M O V S H D U P { RET_INSN_NS(ssess, 0xF316, CPU_SSE3); }
+       M O V S L D U P { RET_INSN_NS(ssess, 0xF312, CPU_SSE3); }
+       M W A I T { RET_INSN_NS(threebyte, 0x0F01C9, CPU_SSE3); }
        /* AMD 3DNow! instructions */
-       P R E F E T C H { RET_INSN(twobytemem, 0x000F0D, CPU_3DNow); }
-       P R E F E T C H W { RET_INSN(twobytemem, 0x010F0D, CPU_3DNow); }
-       F E M M S { RET_INSN(twobyte, 0x0F0E, CPU_3DNow); }
-       P A V G U S B { RET_INSN(now3d, 0xBF, CPU_3DNow); }
-       P F "2" I D { RET_INSN(now3d, 0x1D, CPU_3DNow); }
-       P F "2" I W { RET_INSN(now3d, 0x1C, CPU_Athlon|CPU_3DNow); }
-       P F A C C { RET_INSN(now3d, 0xAE, CPU_3DNow); }
-       P F A D D { RET_INSN(now3d, 0x9E, CPU_3DNow); }
-       P F C M P E Q { RET_INSN(now3d, 0xB0, CPU_3DNow); }
-       P F C M P G E { RET_INSN(now3d, 0x90, CPU_3DNow); }
-       P F C M P G T { RET_INSN(now3d, 0xA0, CPU_3DNow); }
-       P F M A X { RET_INSN(now3d, 0xA4, CPU_3DNow); }
-       P F M I N { RET_INSN(now3d, 0x94, CPU_3DNow); }
-       P F M U L { RET_INSN(now3d, 0xB4, CPU_3DNow); }
-       P F N A C C { RET_INSN(now3d, 0x8A, CPU_Athlon|CPU_3DNow); }
-       P F P N A C C { RET_INSN(now3d, 0x8E, CPU_Athlon|CPU_3DNow); }
-       P F R C P { RET_INSN(now3d, 0x96, CPU_3DNow); }
-       P F R C P I T "1" { RET_INSN(now3d, 0xA6, CPU_3DNow); }
-       P F R C P I T "2" { RET_INSN(now3d, 0xB6, CPU_3DNow); }
-       P F R S Q I T "1" { RET_INSN(now3d, 0xA7, CPU_3DNow); }
-       P F R S Q R T { RET_INSN(now3d, 0x97, CPU_3DNow); }
-       P F S U B { RET_INSN(now3d, 0x9A, CPU_3DNow); }
-       P F S U B R { RET_INSN(now3d, 0xAA, CPU_3DNow); }
-       P I "2" F D { RET_INSN(now3d, 0x0D, CPU_3DNow); }
-       P I "2" F W { RET_INSN(now3d, 0x0C, CPU_Athlon|CPU_3DNow); }
-       P M U L H R W A { RET_INSN(now3d, 0xB7, CPU_3DNow); }
-       P S W A P D { RET_INSN(now3d, 0xBB, CPU_Athlon|CPU_3DNow); }
+       P R E F E T C H { RET_INSN_NS(twobytemem, 0x000F0D, CPU_3DNow); }
+       P R E F E T C H W { RET_INSN_NS(twobytemem, 0x010F0D, CPU_3DNow); }
+       F E M M S { RET_INSN_NS(twobyte, 0x0F0E, CPU_3DNow); }
+       P A V G U S B { RET_INSN_NS(now3d, 0xBF, CPU_3DNow); }
+       P F "2" I D { RET_INSN_NS(now3d, 0x1D, CPU_3DNow); }
+       P F "2" I W { RET_INSN_NS(now3d, 0x1C, CPU_Athlon|CPU_3DNow); }
+       P F A C C { RET_INSN_NS(now3d, 0xAE, CPU_3DNow); }
+       P F A D D { RET_INSN_NS(now3d, 0x9E, CPU_3DNow); }
+       P F C M P E Q { RET_INSN_NS(now3d, 0xB0, CPU_3DNow); }
+       P F C M P G E { RET_INSN_NS(now3d, 0x90, CPU_3DNow); }
+       P F C M P G T { RET_INSN_NS(now3d, 0xA0, CPU_3DNow); }
+       P F M A X { RET_INSN_NS(now3d, 0xA4, CPU_3DNow); }
+       P F M I N { RET_INSN_NS(now3d, 0x94, CPU_3DNow); }
+       P F M U L { RET_INSN_NS(now3d, 0xB4, CPU_3DNow); }
+       P F N A C C { RET_INSN_NS(now3d, 0x8A, CPU_Athlon|CPU_3DNow); }
+       P F P N A C C { RET_INSN_NS(now3d, 0x8E, CPU_Athlon|CPU_3DNow); }
+       P F R C P { RET_INSN_NS(now3d, 0x96, CPU_3DNow); }
+       P F R C P I T "1" { RET_INSN_NS(now3d, 0xA6, CPU_3DNow); }
+       P F R C P I T "2" { RET_INSN_NS(now3d, 0xB6, CPU_3DNow); }
+       P F R S Q I T "1" { RET_INSN_NS(now3d, 0xA7, CPU_3DNow); }
+       P F R S Q R T { RET_INSN_NS(now3d, 0x97, CPU_3DNow); }
+       P F S U B { RET_INSN(5, now3d, 0x9A, CPU_3DNow); }
+       P F S U B R { RET_INSN(6, now3d, 0xAA, CPU_3DNow); }
+       P I "2" F D { RET_INSN(5, now3d, 0x0D, CPU_3DNow); }
+       P I "2" F W { RET_INSN(5, now3d, 0x0C, CPU_Athlon|CPU_3DNow); }
+       P M U L H R W A { RET_INSN(8, now3d, 0xB7, CPU_3DNow); }
+       P S W A P D { RET_INSN(6, now3d, 0xBB, CPU_Athlon|CPU_3DNow); }
        /* AMD extensions */
-       S Y S C A L L { RET_INSN(twobyte, 0x0F05, CPU_686|CPU_AMD); }
-       S Y S R E T { RET_INSN(twobyte, 0x0F07, CPU_686|CPU_AMD|CPU_Priv); }
+       S Y S C A L L { RET_INSN(7, twobyte, 0x0F05, CPU_686|CPU_AMD); }
+       S Y S R E T { RET_INSN(6, twobyte, 0x0F07, CPU_686|CPU_AMD|CPU_Priv); }
        /* AMD x86-64 extensions */
        S W A P G S {
-           if (arch_x86->mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, line,
-                             N_("`%s' is an instruction in 64-bit mode"),
-                             oid);
-               return YASM_ARCH_CHECK_ID_NONE;
-           }
-           RET_INSN(threebyte, 0x0F01F8, CPU_Hammer|CPU_64);
+           warn64 = 1;
+           RET_INSN(6, threebyte, 0x0F01F8, CPU_Hammer|CPU_64);
        }
        /* Cyrix MMX instructions */
-       P A D D S I W { RET_INSN(cyrixmmx, 0x51, CPU_Cyrix|CPU_MMX); }
-       P A V E B { RET_INSN(cyrixmmx, 0x50, CPU_Cyrix|CPU_MMX); }
-       P D I S T I B { RET_INSN(cyrixmmx, 0x54, CPU_Cyrix|CPU_MMX); }
-       P M A C H R I W { RET_INSN(pmachriw, 0, CPU_Cyrix|CPU_MMX); }
-       P M A G W { RET_INSN(cyrixmmx, 0x52, CPU_Cyrix|CPU_MMX); }
-       P M U L H R I W { RET_INSN(cyrixmmx, 0x5D, CPU_Cyrix|CPU_MMX); }
-       P M U L H R W C { RET_INSN(cyrixmmx, 0x59, CPU_Cyrix|CPU_MMX); }
-       P M V G E Z B { RET_INSN(cyrixmmx, 0x5C, CPU_Cyrix|CPU_MMX); }
-       P M V L Z B { RET_INSN(cyrixmmx, 0x5B, CPU_Cyrix|CPU_MMX); }
-       P M V N Z B { RET_INSN(cyrixmmx, 0x5A, CPU_Cyrix|CPU_MMX); }
-       P M V Z B { RET_INSN(cyrixmmx, 0x58, CPU_Cyrix|CPU_MMX); }
-       P S U B S I W { RET_INSN(cyrixmmx, 0x55, CPU_Cyrix|CPU_MMX); }
+       P A D D S I W { RET_INSN(7, cyrixmmx, 0x51, CPU_Cyrix|CPU_MMX); }
+       P A V E B { RET_INSN(5, cyrixmmx, 0x50, CPU_Cyrix|CPU_MMX); }
+       P D I S T I B { RET_INSN(7, cyrixmmx, 0x54, CPU_Cyrix|CPU_MMX); }
+       P M A C H R I W { RET_INSN(8, pmachriw, 0, CPU_Cyrix|CPU_MMX); }
+       P M A G W { RET_INSN(5, cyrixmmx, 0x52, CPU_Cyrix|CPU_MMX); }
+       P M U L H R I W { RET_INSN(8, cyrixmmx, 0x5D, CPU_Cyrix|CPU_MMX); }
+       P M U L H R W C { RET_INSN(8, cyrixmmx, 0x59, CPU_Cyrix|CPU_MMX); }
+       P M V G E Z B { RET_INSN(7, cyrixmmx, 0x5C, CPU_Cyrix|CPU_MMX); }
+       P M V L Z B { RET_INSN(6, cyrixmmx, 0x5B, CPU_Cyrix|CPU_MMX); }
+       P M V N Z B { RET_INSN(6, cyrixmmx, 0x5A, CPU_Cyrix|CPU_MMX); }
+       P M V Z B { RET_INSN(5, cyrixmmx, 0x58, CPU_Cyrix|CPU_MMX); }
+       P S U B S I W { RET_INSN(7, cyrixmmx, 0x55, CPU_Cyrix|CPU_MMX); }
        /* Cyrix extensions */
-       R D S H R { RET_INSN(twobyte, 0x0F36, CPU_686|CPU_Cyrix|CPU_SMM); }
-       R S D C { RET_INSN(rsdc, 0, CPU_486|CPU_Cyrix|CPU_SMM); }
-       R S L D T { RET_INSN(cyrixsmm, 0x7B, CPU_486|CPU_Cyrix|CPU_SMM); }
-       R S T S { RET_INSN(cyrixsmm, 0x7D, CPU_486|CPU_Cyrix|CPU_SMM); }
-       S V D C { RET_INSN(svdc, 0, CPU_486|CPU_Cyrix|CPU_SMM); }
-       S V L D T { RET_INSN(cyrixsmm, 0x7A, CPU_486|CPU_Cyrix|CPU_SMM); }
-       S V T S { RET_INSN(cyrixsmm, 0x7C, CPU_486|CPU_Cyrix|CPU_SMM); }
-       S M I N T { RET_INSN(twobyte, 0x0F38, CPU_686|CPU_Cyrix); }
-       S M I N T O L D { RET_INSN(twobyte, 0x0F7E, CPU_486|CPU_Cyrix|CPU_Obs); }
-       W R S H R { RET_INSN(twobyte, 0x0F37, CPU_686|CPU_Cyrix|CPU_SMM); }
+       R D S H R { RET_INSN(5, twobyte, 0x0F36, CPU_686|CPU_Cyrix|CPU_SMM); }
+       R S D C { RET_INSN(4, rsdc, 0, CPU_486|CPU_Cyrix|CPU_SMM); }
+       R S L D T { RET_INSN(5, cyrixsmm, 0x7B, CPU_486|CPU_Cyrix|CPU_SMM); }
+       R S T S { RET_INSN(4, cyrixsmm, 0x7D, CPU_486|CPU_Cyrix|CPU_SMM); }
+       S V D C { RET_INSN(4, svdc, 0, CPU_486|CPU_Cyrix|CPU_SMM); }
+       S V L D T { RET_INSN(5, cyrixsmm, 0x7A, CPU_486|CPU_Cyrix|CPU_SMM); }
+       S V T S { RET_INSN(4, cyrixsmm, 0x7C, CPU_486|CPU_Cyrix|CPU_SMM); }
+       S M I N T { RET_INSN(5, twobyte, 0x0F38, CPU_686|CPU_Cyrix); }
+       S M I N T O L D { RET_INSN(8, twobyte, 0x0F7E, CPU_486|CPU_Cyrix|CPU_Obs); }
+       W R S H R { RET_INSN(5, twobyte, 0x0F37, CPU_686|CPU_Cyrix|CPU_SMM); }
        /* Obsolete/undocumented instructions */
-       F S E T P M { RET_INSN(twobyte, 0xDBE4, CPU_286|CPU_FPU|CPU_Obs); }
-       I B T S { RET_INSN(ibts, 0, CPU_386|CPU_Undoc|CPU_Obs); }
-       L O A D A L L { RET_INSN(twobyte, 0x0F07, CPU_386|CPU_Undoc); }
-       L O A D A L L "286" { RET_INSN(twobyte, 0x0F05, CPU_286|CPU_Undoc); }
+       F S E T P M { RET_INSN(6, twobyte, 0xDBE4, CPU_286|CPU_FPU|CPU_Obs); }
+       I B T S { RET_INSN(4, ibts, 0, CPU_386|CPU_Undoc|CPU_Obs); }
+       L O A D A L L { RET_INSN(7, twobyte, 0x0F07, CPU_386|CPU_Undoc); }
+       L O A D A L L "286" { RET_INSN(10, twobyte, 0x0F05, CPU_286|CPU_Undoc); }
        S A L C {
-           if (arch_x86->mode_bits == 64) {
-               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
-               RET_INSN(not64, 0, CPU_Not64);
-           }
-           RET_INSN(onebyte, 0x00D6, CPU_Undoc);
+           not64 = 1;
+           RET_INSN(4, onebyte, 0x00D6, CPU_Undoc);
        }
-       S M I { RET_INSN(onebyte, 0x00F1, CPU_386|CPU_Undoc); }
-       U M O V { RET_INSN(umov, 0, CPU_386|CPU_Undoc); }
-       X B T S { RET_INSN(xbts, 0, CPU_386|CPU_Undoc|CPU_Obs); }
+       S M I { RET_INSN(3, onebyte, 0x00F1, CPU_386|CPU_Undoc); }
+       U M O V { RET_INSN(4, umov, 0, CPU_386|CPU_Undoc); }
+       X B T S { RET_INSN(4, xbts, 0, CPU_386|CPU_Undoc|CPU_Obs); }
 
 
        /* catchalls */
@@ -4019,4 +4103,69 @@ yasm_x86__parse_check_id(yasm_arch *arch, unsigned long data[4],
            return YASM_ARCH_CHECK_ID_NONE;
        }
     */
+done:
+    if (suffix) {
+       /* If not using the GAS parser, no instructions have suffixes. */
+       if (arch_x86->parser != X86_PARSER_GAS)
+           return YASM_ARCH_CHECK_ID_NONE;
+
+       /* Match suffixes */
+       switch (id[-1]) {
+           case 'b':
+           case 'B':
+               data[3] |= (MOD_GasSufB >> MOD_GasSuf_SHIFT) << 8;
+               break;
+           case 'w':
+           case 'W':
+               data[3] |= (MOD_GasSufW >> MOD_GasSuf_SHIFT) << 8;
+               break;
+           case 'l':
+           case 'L':
+               data[3] |= (MOD_GasSufL >> MOD_GasSuf_SHIFT) << 8;
+               break;
+           case 'q':
+           case 'Q':
+               data[3] |= (MOD_GasSufQ >> MOD_GasSuf_SHIFT) << 8;
+               break;
+           default:
+               yasm_internal_error(N_("unrecognized suffix"));
+       }
+    }
+    if (warn64 && arch_x86->mode_bits != 64) {
+       yasm__warning(YASM_WARN_GENERAL, line,
+                     N_("`%s' is an instruction in 64-bit mode"),
+                     oid);
+       return YASM_ARCH_CHECK_ID_NONE;
+    }
+    if (not64 && arch_x86->mode_bits == 64) {
+       yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
+       DEF_INSN_DATA(not64, 0, CPU_Not64);
+       return YASM_ARCH_CHECK_ID_INSN;
+    }
+    return YASM_ARCH_CHECK_ID_INSN;
+}
+
+yasm_arch_check_id_retval
+yasm_x86__parse_check_id(yasm_arch *arch, unsigned long data[4],
+                        const char *id, unsigned long line)
+{
+    yasm_arch_check_id_retval rv;
+
+    rv = yasm_x86__parse_check_reg(arch, data, id, line);
+    if (rv != YASM_ARCH_CHECK_ID_NONE)
+       return rv;
+
+    rv = yasm_x86__parse_check_insn(arch, data, id, line);
+    if (rv != YASM_ARCH_CHECK_ID_NONE)
+       return rv;
+
+    rv = yasm_x86__parse_check_prefix(arch, data, id, line);
+    if (rv != YASM_ARCH_CHECK_ID_NONE)
+       return rv;
+
+    rv = yasm_x86__parse_check_targetmod(arch, data, id, line);
+    if (rv != YASM_ARCH_CHECK_ID_NONE)
+       return rv;
+
+    return YASM_ARCH_CHECK_ID_NONE;
 }
index 1e63ae2bd6e9a332ead7fe29b368b2a7e9982f40..af0622a209016abd808167184bfc08b9bdd5220f 100644 (file)
@@ -742,11 +742,29 @@ elf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
 
        if (match)
            ;
-       else if (yasm__strcasecmp(vp->val, "progbits") == 0) {
+       else if (yasm__strncasecmp(vp->val, "gas_", 4) == 0) {
+           /* GAS-style flags */
+           flags = 0;
+           for (i=4; i<strlen(vp->val); i++) {
+               switch (vp->val[i]) {
+                   case 'a':
+                       flags |= SHF_ALLOC;
+                       break;
+                   case 'w':
+                       flags |= SHF_WRITE;
+                       break;
+                   case 'x':
+                       flags |= SHF_EXECINSTR;
+                       break;
+               }
+           }
+       } else if (yasm__strcasecmp(vp->val, "progbits") == 0) {
            type |= SHT_PROGBITS;
        }
-       else if (yasm__strcasecmp(vp->val, "noprogbits") == 0) {
+       else if (yasm__strcasecmp(vp->val, "noprogbits") == 0 ||
+                yasm__strcasecmp(vp->val, "nobits") == 0) {
            type &= ~SHT_PROGBITS;
+           type |= SHT_NOBITS;
        }
        else if (yasm__strcasecmp(vp->val, "align") == 0 && vp->param) {
             /*@dependent@*/ /*@null@*/ const yasm_intnum *align_expr;
index 64eab57f1a937aef70db0a7bc90979eb6a6137f3..eabd5f60e967874e1f8a6010143a2cd18332ed06 100644 (file)
@@ -1,5 +1,7 @@
 # $Id$
 
+EXTRA_DIST += modules/parsers/gas/Makefile.inc
 EXTRA_DIST += modules/parsers/nasm/Makefile.inc
 
+include modules/parsers/gas/Makefile.inc
 include modules/parsers/nasm/Makefile.inc
diff --git a/modules/parsers/gas/Makefile.inc b/modules/parsers/gas/Makefile.inc
new file mode 100644 (file)
index 0000000..5b6e2f7
--- /dev/null
@@ -0,0 +1,28 @@
+# $Id$
+
+libyasm_a_SOURCES += modules/parsers/gas/gas-parser.c
+libyasm_a_SOURCES += modules/parsers/gas/gas-parser.h
+libyasm_a_SOURCES += modules/parsers/gas/gas-defs.h
+libyasm_a_SOURCES += modules/parsers/gas/gas-bison.y
+libyasm_a_SOURCES += gas-bison.h
+libyasm_a_SOURCES += gas-token.c
+
+YASM_MODULES += parser_gas
+
+gas-token.c: $(srcdir)/modules/parsers/gas/gas-token.re re2c$(EXEEXT) cleanup$(EXEEXT)
+       $(top_builddir)/re2c$(EXEEXT) -b $(srcdir)/modules/parsers/gas/gas-token.re \
+       | $(top_builddir)/cleanup$(EXEEXT) \
+       | sed "/^#l/ s,re2c-out\.c,$@," > $@
+
+BUILT_SOURCES += gas-bison.c
+BUILT_SOURCES += gas-bison.h
+BUILT_SOURCES += gas-token.c
+
+CLEANFILES += gas-bison.c
+CLEANFILES += gas-bison.h
+CLEANFILES += gas-token.c
+
+EXTRA_DIST += modules/parsers/gas/tests/Makefile.inc
+EXTRA_DIST += modules/parsers/gas/gas-token.re
+
+include modules/parsers/gas/tests/Makefile.inc
diff --git a/modules/parsers/gas/gas-bison.y b/modules/parsers/gas/gas-bison.y
new file mode 100644 (file)
index 0000000..1e3b020
--- /dev/null
@@ -0,0 +1,726 @@
+/*
+ * GAS-compatible bison parser
+ *
+ *  Copyright (C) 2005  Peter Johnson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of other contributors
+ *    may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+%{
+#include <util.h>
+RCSID("$Id$");
+
+#define YASM_LIB_INTERNAL
+#define YASM_EXPR_INTERNAL
+#include <libyasm.h>
+
+#ifdef STDC_HEADERS
+# include <math.h>
+#endif
+
+#include "modules/parsers/gas/gas-parser.h"
+#include "modules/parsers/gas/gas-defs.h"
+
+static void define_label(yasm_parser_gas *parser_gas, char *name, int local);
+static yasm_section *gas_get_section(yasm_parser_gas *parser_gas, char *name,
+                                    /*@null@*/ char *flags,
+                                    /*@null@*/ char *type);
+static void gas_switch_section(yasm_parser_gas *parser_gas, char *name,
+                              /*@null@*/ char *flags, /*@null@*/ char *type);
+static yasm_bytecode *gas_define_strings(yasm_parser_gas *parser_gas,
+                                        yasm_valparamhead *vps, int withzero);
+static yasm_bytecode *gas_define_data(yasm_parser_gas *parser_gas,
+                                     yasm_valparamhead *vps,
+                                     unsigned int size);
+static void gas_parser_directive
+    (yasm_parser_gas *parser_gas, const char *name,
+     yasm_valparamhead *valparams,
+     /*@null@*/ yasm_valparamhead *objext_valparams);
+
+#define gas_parser_error(s)    yasm__parser_error(cur_line, s)
+#define YYPARSE_PARAM  parser_gas_arg
+#define YYLEX_PARAM    parser_gas_arg
+#define parser_gas     ((yasm_parser_gas *)parser_gas_arg)
+#define gas_parser_debug   (parser_gas->debug)
+
+/*@-usedef -nullassign -memtrans -usereleased -compdef -mustfree@*/
+%}
+
+%pure_parser
+
+%union {
+    unsigned int int_info;
+    char *str_val;
+    yasm_intnum *intn;
+    yasm_floatnum *flt;
+    yasm_symrec *sym;
+    unsigned long arch_data[4];
+    yasm_effaddr *ea;
+    yasm_expr *exp;
+    yasm_bytecode *bc;
+    yasm_valparamhead valparams;
+    struct {
+       yasm_insn_operands operands;
+       int num_operands;
+    } insn_operands;
+    yasm_insn_operand *insn_operand;
+}
+
+%token <intn> INTNUM
+%token <flt> FLTNUM
+%token <str_val> STRING
+%token <int_info> SIZE_OVERRIDE
+%token <int_info> DECLARE_DATA
+%token <int_info> RESERVE_SPACE
+%token <arch_data> INSN PREFIX REG REGGROUP SEGREG TARGETMOD
+%token LEFT_OP RIGHT_OP
+%token <str_val> ID DIR_ID
+%token LINE
+%token DIR_2BYTE DIR_4BYTE DIR_ALIGN DIR_ASCII DIR_ASCIZ DIR_BALIGN
+%token DIR_BSS DIR_BYTE DIR_COMM DIR_DATA DIR_DOUBLE DIR_ENDR DIR_EXTERN
+%token DIR_EQU DIR_FILE DIR_FLOAT DIR_GLOBAL DIR_IDENT DIR_INT DIR_LOC
+%token DIR_LCOMM DIR_OCTA DIR_ORG DIR_P2ALIGN DIR_REPT DIR_SECTION
+%token DIR_SHORT DIR_SIZE DIR_SKIP DIR_STRING
+%token DIR_TEXT DIR_TFLOAT DIR_TYPE DIR_QUAD DIR_WORD
+
+%type <bc> line lineexp instr
+
+%type <str_val> label_id
+%type <ea> memaddr
+%type <exp> expr regmemexpr
+%type <sym> explabel
+%type <valparams> strvals datavals strvals2 datavals2
+%type <insn_operands> operands
+%type <insn_operand> operand
+
+%left '-' '+'
+%left '|' '&' '^' '!'
+%left '*' '/' '%' LEFT_OP RIGHT_OP
+%nonassoc UNARYOP
+
+%%
+input: /* empty */
+    | input line    {
+       parser_gas->temp_bc =
+           yasm_section_bcs_append(parser_gas->cur_section, $2);
+       if (parser_gas->temp_bc)
+           parser_gas->prev_bc = parser_gas->temp_bc;
+       if (parser_gas->save_input)
+           yasm_linemap_add_source(parser_gas->linemap,
+               parser_gas->temp_bc,
+               parser_gas->save_line[parser_gas->save_last ^ 1]);
+       yasm_linemap_goto_next(parser_gas->linemap);
+    }
+;
+
+line: '\n'             { $$ = (yasm_bytecode *)NULL; }
+    | lineexp '\n'
+    | error '\n'       {
+       yasm__error(cur_line,
+                   N_("label or instruction expected at start of line"));
+       $$ = (yasm_bytecode *)NULL;
+       yyerrok;
+    }
+;
+
+lineexp: instr
+    | label_id ':'             {
+       $$ = (yasm_bytecode *)NULL;
+       define_label(parser_gas, $1, 0);
+    }
+    | label_id ':' instr       {
+       $$ = $3;
+       define_label(parser_gas, $1, 0);
+    }
+    /* Alignment directives */
+    | DIR_ALIGN datavals2 {
+       /* FIXME: Whether this is power-of-two or not depends on arch */
+       /*@dependent@*/ yasm_valparam *bound, *fill = NULL, *maxskip = NULL;
+       bound = yasm_vps_first(&$2);
+       if (bound)
+           fill = yasm_vps_next(bound);
+       else
+           yasm__error(cur_line,
+                       N_("align directive must specify alignment"));
+       if (fill)
+           maxskip = yasm_vps_next(fill);
+       $$ = (yasm_bytecode *)NULL;
+    }
+    | DIR_P2ALIGN datavals2 {
+       $$ = (yasm_bytecode *)NULL;
+    }
+    | DIR_BALIGN datavals2 {
+       $$ = (yasm_bytecode *)NULL;
+    }
+    | DIR_ORG expr {
+       $$ = (yasm_bytecode *)NULL;
+    }
+    /* Data visibility directives */
+    | DIR_GLOBAL label_id {
+       yasm_objfmt_global_declare(parser_gas->objfmt, $2, NULL, cur_line);
+       yasm_xfree($2);
+       $$ = NULL;
+    }
+    | DIR_COMM label_id ',' expr {
+       yasm_objfmt_common_declare(parser_gas->objfmt, $2, $4, NULL, cur_line);
+       yasm_xfree($2);
+       $$ = NULL;
+    }
+    | DIR_COMM label_id ',' expr ',' expr {
+       /* Give third parameter as objext valparam for use as alignment */
+       yasm_valparamhead vps;
+       yasm_valparam *vp;
+
+       yasm_vps_initialize(&vps);
+       vp = yasm_vp_create(NULL, $6);
+       yasm_vps_append(&vps, vp);
+
+       yasm_objfmt_common_declare(parser_gas->objfmt, $2, $4, &vps, cur_line);
+
+       yasm_vps_delete(&vps);
+       yasm_xfree($2);
+       $$ = NULL;
+    }
+    | DIR_EXTERN label_id {
+       /* Go ahead and do it, even though all undef become extern */
+       yasm_objfmt_extern_declare(parser_gas->objfmt, $2, NULL, cur_line);
+       yasm_xfree($2);
+       $$ = NULL;
+    }
+    | DIR_LCOMM label_id ',' expr {
+       /* Put into .bss section. */
+       /*@dependent@*/ yasm_section *bss =
+           gas_get_section(parser_gas, yasm__xstrdup(".bss"), NULL, NULL);
+       /* TODO: default alignment */
+       yasm_symtab_define_label(p_symtab, $2, yasm_section_bcs_last(bss), 1,
+                                cur_line);
+       yasm_section_bcs_append(bss, yasm_bc_create_reserve($4, 1, cur_line));
+       yasm_xfree($2);
+       $$ = NULL;
+    }
+    | DIR_LCOMM label_id ',' expr ',' expr {
+       /* Put into .bss section. */
+       /*@dependent@*/ yasm_section *bss =
+           gas_get_section(parser_gas, yasm__xstrdup(".bss"), NULL, NULL);
+       /* TODO: force alignment */
+       yasm_symtab_define_label(p_symtab, $2, yasm_section_bcs_last(bss), 1,
+                                cur_line);
+       yasm_section_bcs_append(bss, yasm_bc_create_reserve($4, 1, cur_line));
+       yasm_xfree($2);
+       $$ = NULL;
+    }
+    /* Integer data definition directives */
+    | DIR_ASCII strvals {
+       $$ = gas_define_strings(parser_gas, &$2, 0);
+       yasm_vps_delete(&$2);
+    }
+    | DIR_ASCIZ strvals {
+       $$ = gas_define_strings(parser_gas, &$2, 1);
+       yasm_vps_delete(&$2);
+    }
+    | DIR_BYTE datavals {
+       $$ = gas_define_data(parser_gas, &$2, 1);
+       yasm_vps_delete(&$2);
+    }
+    | DIR_SHORT datavals {
+       /* TODO: This should depend on arch */
+       $$ = gas_define_data(parser_gas, &$2, 2);
+       yasm_vps_delete(&$2);
+    }
+    | DIR_WORD datavals {
+       $$ = gas_define_data(parser_gas, &$2,
+                            yasm_arch_wordsize(parser_gas->arch));
+       yasm_vps_delete(&$2);
+    }
+    | DIR_INT datavals {
+       /* TODO: This should depend on arch */
+       $$ = gas_define_data(parser_gas, &$2, 4);
+       yasm_vps_delete(&$2);
+    }
+    | DIR_2BYTE datavals {
+       $$ = gas_define_data(parser_gas, &$2, 2);
+       yasm_vps_delete(&$2);
+    }
+    | DIR_4BYTE datavals {
+       $$ = gas_define_data(parser_gas, &$2, 4);
+       yasm_vps_delete(&$2);
+    }
+    | DIR_QUAD datavals {
+       $$ = gas_define_data(parser_gas, &$2, 8);
+       yasm_vps_delete(&$2);
+    }
+    | DIR_OCTA datavals {
+       $$ = gas_define_data(parser_gas, &$2, 16);
+       yasm_vps_delete(&$2);
+    }
+    /* Floating point data definition directives */
+    | DIR_FLOAT datavals {
+       $$ = gas_define_data(parser_gas, &$2, 4);
+       yasm_vps_delete(&$2);
+    }
+    | DIR_DOUBLE datavals {
+       $$ = gas_define_data(parser_gas, &$2, 8);
+       yasm_vps_delete(&$2);
+    }
+    | DIR_TFLOAT datavals {
+       $$ = gas_define_data(parser_gas, &$2, 10);
+       yasm_vps_delete(&$2);
+    }
+    /* Empty space / fill data definition directives */
+    | DIR_SKIP expr {
+       $$ = yasm_bc_create_reserve($2, 1, cur_line);
+    }
+    | DIR_SKIP expr ',' expr {
+       yasm_datavalhead dvs;
+
+       yasm_dvs_initialize(&dvs);
+       yasm_dvs_append(&dvs, yasm_dv_create_expr($4));
+       $$ = yasm_bc_create_data(&dvs, 1, cur_line);
+
+       yasm_bc_set_multiple($$, $2);
+    }
+    /* Section directives */
+    | DIR_TEXT {
+       gas_switch_section(parser_gas, yasm__xstrdup(".text"), NULL, NULL);
+       $$ = NULL;
+    }
+    | DIR_DATA {
+       gas_switch_section(parser_gas, yasm__xstrdup(".data"), NULL, NULL);
+       $$ = NULL;
+    }
+    | DIR_BSS {
+       gas_switch_section(parser_gas, yasm__xstrdup(".bss"), NULL, NULL);
+       $$ = NULL;
+    }
+    | DIR_SECTION label_id {
+       gas_switch_section(parser_gas, $2, NULL, NULL);
+       $$ = NULL;
+    }
+    | DIR_SECTION label_id ',' STRING {
+       gas_switch_section(parser_gas, $2, $4, NULL);
+       $$ = NULL;
+    }
+    | DIR_SECTION label_id ',' STRING ',' '@' label_id {
+       gas_switch_section(parser_gas, $2, $4, $7);
+       $$ = NULL;
+    }
+    /* Other directives */
+    | DIR_IDENT strvals {
+       /* Put text into .comment section. */
+       /*@dependent@*/ yasm_section *comment =
+           gas_get_section(parser_gas, yasm__xstrdup(".comment"), NULL, NULL);
+       /* To match GAS output, if the comment section is empty, put an
+        * initial 0 byte in the section.
+        */
+       if (yasm_section_bcs_first(comment) == yasm_section_bcs_last(comment)) {
+           yasm_datavalhead dvs;
+
+           yasm_dvs_initialize(&dvs);
+           yasm_dvs_append(&dvs, yasm_dv_create_expr(
+               p_expr_new_ident(yasm_expr_int(yasm_intnum_create_uint(0)))));
+           yasm_section_bcs_append(comment,
+                                   yasm_bc_create_data(&dvs, 1, cur_line));
+       }
+       yasm_section_bcs_append(comment,
+                               gas_define_strings(parser_gas, &$2, 1));
+       yasm_vps_delete(&$2);
+       $$ = NULL;
+    }
+    | DIR_FILE INTNUM STRING {
+       /* TODO */
+       $$ = NULL;
+    }
+    | DIR_LOC INTNUM INTNUM INTNUM {
+       /* TODO */
+       $$ = NULL;
+    }
+    | DIR_TYPE label_id ',' '@' label_id {
+       /* TODO */
+       $$ = NULL;
+    }
+    | DIR_SIZE label_id ',' expr {
+       /* TODO */
+       $$ = NULL;
+    }
+    | DIR_ID datavals  {
+       yasm__warning(YASM_WARN_GENERAL, cur_line,
+                     N_("directive `%s' not recognized"), $1);
+       $$ = (yasm_bytecode *)NULL;
+       yasm_xfree($1);
+       yasm_vps_delete(&$2);
+    }
+    | DIR_ID error     {
+       yasm__warning(YASM_WARN_GENERAL, cur_line,
+                     N_("directive `%s' not recognized"), $1);
+       $$ = (yasm_bytecode *)NULL;
+       yasm_xfree($1);
+    }
+    | label_id '=' expr        {
+       $$ = (yasm_bytecode *)NULL;
+       yasm_symtab_define_equ(p_symtab, $1, $3, cur_line);
+       yasm_xfree($1);
+    }
+;
+
+instr: INSN            {
+       $$ = yasm_bc_create_insn(parser_gas->arch, $1, 0, NULL, cur_line);
+    }
+    | INSN operands    {
+       $$ = yasm_bc_create_insn(parser_gas->arch, $1, $2.num_operands,
+                                &$2.operands, cur_line);
+    }
+    | INSN error       {
+       yasm__error(cur_line, N_("expression syntax error"));
+       $$ = NULL;
+    }
+    | PREFIX instr     {
+       $$ = $2;
+       yasm_bc_insn_add_prefix($$, $1);
+    }
+    | ID {
+       yasm__error(cur_line, N_("instruction not recognized: `%s'"), $1);
+       $$ = NULL;
+    }
+    | ID operands {
+       yasm__error(cur_line, N_("instruction not recognized: `%s'"), $1);
+       $$ = NULL;
+    }
+    | ID error {
+       yasm__error(cur_line, N_("instruction not recognized: `%s'"), $1);
+       $$ = NULL;
+    }
+;
+
+strvals: /* empty */   { yasm_vps_initialize(&$$); }
+    | strvals2
+;
+
+strvals2: STRING               {
+       yasm_valparam *vp = yasm_vp_create($1, NULL);
+       yasm_vps_initialize(&$$);
+       yasm_vps_append(&$$, vp);
+    }
+    | strvals2 ',' STRING      {
+       yasm_valparam *vp = yasm_vp_create($3, NULL);
+       yasm_vps_append(&$1, vp);
+       $$ = $1;
+    }
+    | strvals2 ',' ',' STRING  {
+       yasm_valparam *vp = yasm_vp_create(NULL, NULL);
+       yasm_vps_append(&$1, vp);
+       vp = yasm_vp_create($4, NULL);
+       yasm_vps_append(&$1, vp);
+       $$ = $1;
+    }
+;
+
+datavals: /* empty */  { yasm_vps_initialize(&$$); }
+    | datavals2
+;
+
+datavals2: expr                        {
+       yasm_valparam *vp = yasm_vp_create(NULL, $1);
+       yasm_vps_initialize(&$$);
+       yasm_vps_append(&$$, vp);
+    }
+    | datavals2 ',' expr       {
+       yasm_valparam *vp = yasm_vp_create(NULL, $3);
+       yasm_vps_append(&$1, vp);
+       $$ = $1;
+    }
+    | datavals2 ',' ',' expr   {
+       yasm_valparam *vp = yasm_vp_create(NULL, NULL);
+       yasm_vps_append(&$1, vp);
+       vp = yasm_vp_create(NULL, $4);
+       yasm_vps_append(&$1, vp);
+       $$ = $1;
+    }
+;
+
+/* instruction operands */
+operands: operand          {
+       yasm_ops_initialize(&$$.operands);
+       yasm_ops_append(&$$.operands, $1);
+       $$.num_operands = 1;
+    }
+    | operands ',' operand  {
+       yasm_ops_append(&$1.operands, $3);
+       $$.operands = $1.operands;
+       $$.num_operands = $1.num_operands+1;
+    }
+;
+
+regmemexpr: '(' REG ')'            {
+       $$ = p_expr_new_ident(yasm_expr_reg($2[0]));
+    }
+    | '(' ',' REG ')'      {
+       $$ = p_expr_new(yasm_expr_reg($3[0]), YASM_EXPR_MUL,
+                       yasm_expr_int(yasm_intnum_create_uint(1)));
+    }
+    | '(' ',' INTNUM ')'    {
+       if (yasm_intnum_get_uint($3) != 1)
+           yasm__warning(YASM_WARN_GENERAL, cur_line,
+                         N_("scale factor of %u without an index register"),
+                         yasm_intnum_get_uint($3));
+       $$ = p_expr_new(yasm_expr_int(yasm_intnum_create_uint(0)),
+                       YASM_EXPR_MUL, yasm_expr_int($3));
+    }
+    | '(' REG ',' REG ')'  {
+       $$ = p_expr_new(yasm_expr_reg($2[0]), YASM_EXPR_ADD,
+           yasm_expr_expr(p_expr_new(yasm_expr_reg($4[0]), YASM_EXPR_MUL,
+               yasm_expr_int(yasm_intnum_create_uint(1)))));
+    }
+    | '(' ',' REG ',' INTNUM ')'  {
+       $$ = p_expr_new(yasm_expr_reg($3[0]), YASM_EXPR_MUL,
+                       yasm_expr_int($5));
+    }
+    | '(' REG ',' REG ',' INTNUM ')'  {
+       $$ = p_expr_new(yasm_expr_reg($2[0]), YASM_EXPR_ADD,
+           yasm_expr_expr(p_expr_new(yasm_expr_reg($4[0]), YASM_EXPR_MUL,
+                                     yasm_expr_int($6))));
+    }
+;
+
+/* memory addresses */
+memaddr: expr              {
+       $$ = yasm_arch_ea_create(parser_gas->arch, $1);
+    }
+    | regmemexpr           {
+       $$ = yasm_arch_ea_create(parser_gas->arch, $1);
+       yasm_ea_set_strong($$, 1);
+    }
+    | expr regmemexpr      {
+       $$ = yasm_arch_ea_create(parser_gas->arch,
+                                p_expr_new_tree($2, YASM_EXPR_ADD, $1));
+       yasm_ea_set_strong($$, 1);
+    }
+    | SEGREG ':' memaddr  {
+       $$ = $3;
+       yasm_ea_set_segreg($$, $1[0], cur_line);
+    }
+;
+
+operand: memaddr           { $$ = yasm_operand_create_mem($1); }
+    | REG                  { $$ = yasm_operand_create_reg($1[0]); }
+    | REGGROUP             { $$ = yasm_operand_create_reg($1[0]); }
+    | REGGROUP '(' INTNUM ')'  {
+       unsigned long reg =
+           yasm_arch_reggroup_get_reg(parser_gas->arch, $1[0],
+                                      yasm_intnum_get_uint($3));
+       yasm_intnum_destroy($3);
+       if (reg == 0) {
+           yasm__error(cur_line, N_("bad register index `%u'"),
+                       yasm_intnum_get_uint($3));
+           $$ = yasm_operand_create_reg($1[0]);
+       } else
+           $$ = yasm_operand_create_reg(reg);
+    }
+    | '$' expr             { $$ = yasm_operand_create_imm($2); }
+    | '*' REG              {
+       $$ = yasm_operand_create_reg($2[0]);
+       $$->deref = 1;
+    }
+    | '*' memaddr          {
+       $$ = yasm_operand_create_mem($2);
+       $$->deref = 1;
+    }
+;
+
+/* Expressions */
+expr: INTNUM           { $$ = p_expr_new_ident(yasm_expr_int($1)); }
+    | FLTNUM           { $$ = p_expr_new_ident(yasm_expr_float($1)); }
+    | explabel         { $$ = p_expr_new_ident(yasm_expr_sym($1)); }
+    | expr '|' expr    { $$ = p_expr_new_tree($1, YASM_EXPR_OR, $3); }
+    | expr '^' expr    { $$ = p_expr_new_tree($1, YASM_EXPR_XOR, $3); }
+    | expr '&' expr    { $$ = p_expr_new_tree($1, YASM_EXPR_AND, $3); }
+    | expr '!' expr    { $$ = p_expr_new_tree($1, YASM_EXPR_NOR, $3); }
+    | expr LEFT_OP expr        { $$ = p_expr_new_tree($1, YASM_EXPR_SHL, $3); }
+    | expr RIGHT_OP expr { $$ = p_expr_new_tree($1, YASM_EXPR_SHR, $3); }
+    | expr '+' expr    { $$ = p_expr_new_tree($1, YASM_EXPR_ADD, $3); }
+    | expr '-' expr    { $$ = p_expr_new_tree($1, YASM_EXPR_SUB, $3); }
+    | expr '*' expr    { $$ = p_expr_new_tree($1, YASM_EXPR_MUL, $3); }
+    | expr '/' expr    { $$ = p_expr_new_tree($1, YASM_EXPR_DIV, $3); }
+    | expr '%' expr    { $$ = p_expr_new_tree($1, YASM_EXPR_MOD, $3); }
+    | '+' expr %prec UNARYOP   { $$ = $2; }
+    | '-' expr %prec UNARYOP   { $$ = p_expr_new_branch(YASM_EXPR_NEG, $2); }
+    | '~' expr %prec UNARYOP   { $$ = p_expr_new_branch(YASM_EXPR_NOT, $2); }
+    | '(' expr ')'     { $$ = $2; }
+;
+
+explabel: label_id     {
+       /* "." references the current assembly position */
+       if ($1[1] == '\0' && $1[0] == '.')
+           $$ = yasm_symtab_define_label(p_symtab, ".", parser_gas->prev_bc,
+                                         0, cur_line);
+       else
+           $$ = yasm_symtab_use(p_symtab, $1, cur_line);
+       yasm_xfree($1);
+    }
+    | label_id '@' label_id {
+       /* TODO: this is needed for shared objects, e.g. sym@PLT */
+       $$ = yasm_symtab_use(p_symtab, $1, cur_line);
+       yasm_xfree($1);
+       yasm_xfree($3);
+    }
+;
+
+label_id: ID | DIR_ID;
+
+%%
+/*@=usedef =nullassign =memtrans =usereleased =compdef =mustfree@*/
+
+#undef parser_gas
+
+static void
+define_label(yasm_parser_gas *parser_gas, char *name, int local)
+{
+    if (!local) {
+       if (parser_gas->locallabel_base)
+           yasm_xfree(parser_gas->locallabel_base);
+       parser_gas->locallabel_base_len = strlen(name);
+       parser_gas->locallabel_base =
+           yasm_xmalloc(parser_gas->locallabel_base_len+1);
+       strcpy(parser_gas->locallabel_base, name);
+    }
+
+    yasm_symtab_define_label(p_symtab, name, parser_gas->prev_bc, 1,
+                            cur_line);
+    yasm_xfree(name);
+}
+
+static yasm_section *
+gas_get_section(yasm_parser_gas *parser_gas, char *name,
+               /*@null@*/ char *flags, /*@null@*/ char *type)
+{
+    yasm_valparamhead vps;
+    yasm_valparam *vp;
+    char *gasflags;
+    yasm_section *new_section;
+
+    yasm_vps_initialize(&vps);
+    vp = yasm_vp_create(name, NULL);
+    yasm_vps_append(&vps, vp);
+
+    if (flags) {
+       gasflags = yasm_xmalloc(5+strlen(flags));
+       strcpy(gasflags, "gas_");
+       strcat(gasflags, flags);
+    } else
+       gasflags = yasm__xstrdup("gas_");
+    vp = yasm_vp_create(gasflags, NULL);
+    yasm_vps_append(&vps, vp);
+
+    if (type) {
+       vp = yasm_vp_create(type, NULL);
+       yasm_vps_append(&vps, vp);
+    }
+
+    new_section = yasm_objfmt_section_switch(parser_gas->objfmt, &vps, NULL,
+                                            cur_line);
+
+    yasm_vps_delete(&vps);
+    return new_section;
+}
+
+static void
+gas_switch_section(yasm_parser_gas *parser_gas, char *name,
+                  /*@null@*/ char *flags, /*@null@*/ char *type)
+{
+    yasm_section *new_section;
+
+    new_section = gas_get_section(parser_gas, name, flags, type);
+    if (new_section) {
+       parser_gas->cur_section = new_section;
+       parser_gas->prev_bc = yasm_section_bcs_last(new_section);
+    } else
+       yasm__error(cur_line, N_("invalid section name `%s'"), name);
+}
+
+static yasm_bytecode *
+gas_define_strings(yasm_parser_gas *parser_gas, yasm_valparamhead *vps,
+                  int withzero)
+{
+    if (yasm_vps_first(vps)) {
+       yasm_datavalhead dvs;
+       yasm_valparam *cur;
+
+       yasm_dvs_initialize(&dvs);
+       yasm_vps_foreach(cur, vps) {
+           if (!cur->val)
+               yasm__error(cur_line, N_("missing string value"));
+           else {
+               yasm_dvs_append(&dvs, yasm_dv_create_string(cur->val));
+               cur->val = NULL;
+               if (withzero)
+                   yasm_dvs_append(&dvs, yasm_dv_create_expr(
+                       p_expr_new_ident(yasm_expr_int(
+                           yasm_intnum_create_uint(0)))));
+           }
+       }
+       return yasm_bc_create_data(&dvs, 1, cur_line);
+    } else
+       return NULL;
+}
+
+static yasm_bytecode *
+gas_define_data(yasm_parser_gas *parser_gas, yasm_valparamhead *vps,
+               unsigned int size)
+{
+    if (yasm_vps_first(vps)) {
+       yasm_datavalhead dvs;
+       yasm_valparam *cur;
+
+       yasm_dvs_initialize(&dvs);
+       yasm_vps_foreach(cur, vps) {
+           if (!cur->param)
+               yasm__error(cur_line, N_("missing data value"));
+           else
+               yasm_dvs_append(&dvs, yasm_dv_create_expr(cur->param));
+           cur->param = NULL;
+       }
+       return yasm_bc_create_data(&dvs, size, cur_line);
+    } else
+       return NULL;
+}
+
+static void
+gas_parser_directive(yasm_parser_gas *parser_gas, const char *name,
+                     yasm_valparamhead *valparams,
+                     yasm_valparamhead *objext_valparams)
+{
+    unsigned long line = cur_line;
+
+    /* Handle (mostly) output-format independent directives here */
+    if (!yasm_arch_parse_directive(parser_gas->arch, name, valparams,
+                   objext_valparams, parser_gas->object, line)) {
+       ;
+    } else if (yasm_objfmt_directive(parser_gas->objfmt, name, valparams,
+                                    objext_valparams, line)) {
+       yasm__error(line, N_("unrecognized directive [%s]"), name);
+    }
+
+    yasm_vps_delete(valparams);
+    if (objext_valparams)
+       yasm_vps_delete(objext_valparams);
+}
diff --git a/modules/parsers/gas/gas-defs.h b/modules/parsers/gas/gas-defs.h
new file mode 100644 (file)
index 0000000..5991a5f
--- /dev/null
@@ -0,0 +1,88 @@
+/* $Id$
+ * Variable name redefinitions for GAS-compatible parser
+ *
+ *  Copyright (C) 2005  Peter Johnson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of other contributors
+ *    may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#define yy_create_buffer       gas_parser__create_buffer
+#define yy_delete_buffer       gas_parser__delete_buffer
+#define yy_init_buffer         gas_parser__init_buffer
+#define yy_load_buffer_state   gas_parser__load_buffer_state
+#define yy_switch_to_buffer    gas_parser__switch_to_buffer
+#define yyact                  gas_parser_act
+#define yyback                 gas_parser_back
+#define yybgin                 gas_parser_bgin
+#define yychar                 gas_parser_char
+#define yychk                  gas_parser_chk
+#define yycrank                        gas_parser_crank
+#define yydebug                        gas_parser_debug
+#define yydef                  gas_parser_def
+#define yyerrflag              gas_parser_errflag
+#define yyerror                        gas_parser_error
+#define yyestate               gas_parser_estate
+#define yyexca                 gas_parser_exca
+#define yyextra                        gas_parser_extra
+#define yyfnd                  gas_parser_fnd
+#define yyin                   gas_parser_in
+#define yyinput                        gas_parser_input
+#define yyleng                 gas_parser_leng
+#define yylex                  gas_parser_lex
+#define yylineno               gas_parser_lineno
+#define yylook                 gas_parser_look
+#define yylsp                  gas_parser_lsp
+#define yylstate               gas_parser_lstate
+#define yylval                 gas_parser_lval
+#define yymatch                        gas_parser_match
+#define yymorfg                        gas_parser_morfg
+#define yynerrs                        gas_parser_nerrs
+#define yyolsp                 gas_parser_olsp
+#define yyout                  gas_parser_out
+#define yyoutput               gas_parser_output
+#define yypact                 gas_parser_pact
+#define yyparse                        gas_parser_parse
+#define yypgo                  gas_parser_pgo
+#define yyprevious             gas_parser_previous
+#define yyps                   gas_parser_ps
+#define yypv                   gas_parser_pv
+#define yyr1                   gas_parser_r1
+#define yyr2                   gas_parser_r2
+#define yyreds                 gas_parser_reds
+#define yyrestart              gas_parser_restart
+#define yys                    gas_parser_s
+#define yysbuf                 gas_parser_sbuf
+#define yysptr                 gas_parser_sptr
+#define yystate                        gas_parser_state
+#define yysvec                 gas_parser_svec
+#define yytchar                        gas_parser_tchar
+#define yytext                 gas_parser_text
+#define yytmp                  gas_parser_tmp
+#define yytoks                 gas_parser_toks
+#define yytop                  gas_parser_top
+#define yyunput                        gas_parser_unput
+#define yyv                    gas_parser_v
+#define yyval                  gas_parser_val
+#define yyvstop                        gas_parser_vstop
+/*#define yywrap                       gas_parser_wrap*/
diff --git a/modules/parsers/gas/gas-parser.c b/modules/parsers/gas/gas-parser.c
new file mode 100644 (file)
index 0000000..31bf78a
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * GAS-compatible parser
+ *
+ *  Copyright (C) 2005  Peter Johnson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of other contributors
+ *    may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <util.h>
+/*@unused@*/ RCSID("$Id$");
+
+#define YASM_LIB_INTERNAL
+#include <libyasm.h>
+
+#include "gas-parser.h"
+
+
+static void
+gas_parser_do_parse(yasm_object *object, yasm_preproc *pp, yasm_arch *a,
+                    yasm_objfmt *of, FILE *f, const char *in_filename,
+                    int save_input, yasm_section *def_sect)
+{
+    yasm_parser_gas parser_gas;
+
+    parser_gas.object = object;
+    parser_gas.linemap = yasm_object_get_linemap(parser_gas.object);
+    parser_gas.symtab = yasm_object_get_symtab(parser_gas.object);
+
+    parser_gas.in = f;
+
+    parser_gas.locallabel_base = (char *)NULL;
+    parser_gas.locallabel_base_len = 0;
+
+    parser_gas.preproc = pp;
+    parser_gas.arch = a;
+    parser_gas.objfmt = of;
+
+    parser_gas.cur_section = def_sect;
+    parser_gas.prev_bc = yasm_section_bcs_first(def_sect);
+
+    parser_gas.save_input = save_input;
+    parser_gas.save_last = 0;
+
+    /* initialize scanner structure */
+    parser_gas.s.bot = NULL;
+    parser_gas.s.tok = NULL;
+    parser_gas.s.ptr = NULL;
+    parser_gas.s.cur = NULL;
+    parser_gas.s.pos = NULL;
+    parser_gas.s.lim = NULL;
+    parser_gas.s.top = NULL;
+    parser_gas.s.eof = NULL;
+    parser_gas.s.tchar = 0;
+    parser_gas.s.tline = 0;
+    parser_gas.s.cline = 1;
+
+    parser_gas.state = INITIAL;
+
+    /* yacc debugging, needs YYDEBUG set in bison.y.in to work */
+    parser_gas.debug = 1;
+
+    gas_parser_parse(&parser_gas);
+
+    gas_parser_cleanup(&parser_gas);
+
+    /* Free locallabel base if necessary */
+    if (parser_gas.locallabel_base)
+       yasm_xfree(parser_gas.locallabel_base);
+}
+
+/* Define valid preprocessors to use with this parser */
+static const char *gas_parser_preproc_keywords[] = {
+    "raw",
+    NULL
+};
+
+/* Define parser structure -- see parser.h for details */
+yasm_parser_module yasm_gas_LTX_parser = {
+    "GNU AS (GAS)-compatible parser",
+    "gas",
+    gas_parser_preproc_keywords,
+    "raw",
+    gas_parser_do_parse
+};
diff --git a/modules/parsers/gas/gas-parser.h b/modules/parsers/gas/gas-parser.h
new file mode 100644 (file)
index 0000000..5013796
--- /dev/null
@@ -0,0 +1,89 @@
+/* $Id$
+ * GAS-compatible parser header file
+ *
+ *  Copyright (C) 2005  Peter Johnson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of other contributors
+ *    may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef YASM_NASM_PARSER_H
+#define YASM_NASM_PARSER_H
+
+#include "gas-bison.h"
+
+#define YYCTYPE                char
+typedef struct Scanner {
+    YYCTYPE            *bot, *tok, *ptr, *cur, *pos, *lim, *top, *eof;
+    unsigned int       tchar, tline, cline;
+} Scanner;
+
+#define MAX_SAVED_LINE_LEN  80
+
+typedef struct yasm_parser_gas {
+    FILE *in;
+    int debug;
+
+    /*@only@*/ yasm_object *object;
+    /*@dependent@*/ yasm_section *cur_section;
+
+    /* last "base" label for local (.) labels */
+    /*@null@*/ char *locallabel_base;
+    size_t locallabel_base_len;
+
+    /*@dependent@*/ yasm_preproc *preproc;
+    /*@dependent@*/ yasm_arch *arch;
+    /*@dependent@*/ yasm_objfmt *objfmt;
+
+    /*@dependent@*/ yasm_linemap *linemap;
+    /*@dependent@*/ yasm_symtab *symtab;
+
+    /*@null@*/ yasm_bytecode *prev_bc;
+    yasm_bytecode *temp_bc;
+
+    int save_input;
+    YYCTYPE save_line[2][MAX_SAVED_LINE_LEN];
+    int save_last;
+
+    Scanner s;
+    enum {
+       INITIAL,
+       SECTION_DIRECTIVE
+    } state;
+} yasm_parser_gas;
+
+/* shorter access names to commonly used parser_gas fields */
+#define p_symtab       (parser_gas->symtab)
+
+#define cur_line       (yasm_linemap_get_current(parser_gas->linemap))
+
+#define p_expr_new(l,o,r)      yasm_expr_create(o,l,r,cur_line)
+#define p_expr_new_tree(l,o,r) yasm_expr_create_tree(l,o,r,cur_line)
+#define p_expr_new_branch(o,r) yasm_expr_create_branch(o,r,cur_line)
+#define p_expr_new_ident(r)    yasm_expr_create_ident(r,cur_line)
+
+int gas_parser_parse(void *parser_gas_arg);
+void gas_parser_cleanup(yasm_parser_gas *parser_gas);
+int gas_parser_lex(YYSTYPE *lvalp, yasm_parser_gas *parser_gas);
+
+#endif
diff --git a/modules/parsers/gas/gas-token.re b/modules/parsers/gas/gas-token.re
new file mode 100644 (file)
index 0000000..84542d0
--- /dev/null
@@ -0,0 +1,535 @@
+/*
+ * GAS-compatible re2c lexer
+ *
+ *  Copyright (C) 2005  Peter Johnson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of other contributors
+ *    may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <util.h>
+RCSID("$Id$");
+
+#define YASM_LIB_INTERNAL
+#include <libyasm.h>
+
+#include "modules/parsers/gas/gas-parser.h"
+#include "modules/parsers/gas/gas-defs.h"
+
+
+#define BSIZE  8192
+
+#define YYCURSOR       cursor
+#define YYLIMIT                (s->lim)
+#define YYMARKER       (s->ptr)
+#define YYFILL(n)      {cursor = fill(parser_gas, cursor);}
+
+#define RETURN(i)      {s->cur = cursor; return i;}
+
+#define SCANINIT()     { \
+       s->tchar = cursor - s->pos; \
+       s->tline = s->cline; \
+       s->tok = cursor; \
+    }
+
+#define TOKLEN         (size_t)(cursor-s->tok)
+
+
+static YYCTYPE *
+fill(yasm_parser_gas *parser_gas, YYCTYPE *cursor)
+{
+    Scanner *s = &parser_gas->s;
+    int first = 0;
+    if(!s->eof){
+       size_t cnt = s->tok - s->bot;
+       if(cnt){
+           memcpy(s->bot, s->tok, (size_t)(s->lim - s->tok));
+           s->tok = s->bot;
+           s->ptr -= cnt;
+           cursor -= cnt;
+           s->pos -= cnt;
+           s->lim -= cnt;
+       }
+       if (!s->bot)
+           first = 1;
+       if((s->top - s->lim) < BSIZE){
+           char *buf = yasm_xmalloc((size_t)(s->lim - s->bot) + BSIZE);
+           memcpy(buf, s->tok, (size_t)(s->lim - s->tok));
+           s->tok = buf;
+           s->ptr = &buf[s->ptr - s->bot];
+           cursor = &buf[cursor - s->bot];
+           s->pos = &buf[s->pos - s->bot];
+           s->lim = &buf[s->lim - s->bot];
+           s->top = &s->lim[BSIZE];
+           if (s->bot)
+               yasm_xfree(s->bot);
+           s->bot = buf;
+       }
+       if((cnt = yasm_preproc_input(parser_gas->preproc, s->lim,
+                                    BSIZE)) == 0) {
+           s->eof = &s->lim[cnt]; *s->eof++ = '\n';
+       }
+       s->lim += cnt;
+       if (first && parser_gas->save_input) {
+           int i;
+           char *saveline;
+           parser_gas->save_last ^= 1;
+           saveline = parser_gas->save_line[parser_gas->save_last];
+           /* save next line into cur_line */
+           for (i=0; i<79 && &s->tok[i] < s->lim && s->tok[i] != '\n'; i++)
+               saveline[i] = s->tok[i];
+           saveline[i] = '\0';
+       }
+    }
+    return cursor;
+}
+
+static YYCTYPE *
+save_line(yasm_parser_gas *parser_gas, YYCTYPE *cursor)
+{
+    Scanner *s = &parser_gas->s;
+    int i = 0;
+    char *saveline;
+
+    parser_gas->save_last ^= 1;
+    saveline = parser_gas->save_line[parser_gas->save_last];
+
+    /* save next line into cur_line */
+    if ((YYLIMIT - YYCURSOR) < 80)
+       YYFILL(80);
+    for (i=0; i<79 && &cursor[i] < s->lim && cursor[i] != '\n'; i++)
+       saveline[i] = cursor[i];
+    saveline[i] = '\0';
+    return cursor;
+}
+
+void
+gas_parser_cleanup(yasm_parser_gas *parser_gas)
+{
+    if (parser_gas->s.bot)
+       yasm_xfree(parser_gas->s.bot);
+}
+
+/* starting size of string buffer */
+#define STRBUF_ALLOC_SIZE      128
+
+/* string buffer used when parsing strings/character constants */
+static char *strbuf = (char *)NULL;
+
+/* length of strbuf (including terminating NULL character) */
+static size_t strbuf_size = 0;
+
+static void
+strbuf_append(size_t count, YYCTYPE *cursor, Scanner *s, unsigned long line,
+             int ch)
+{
+    if (cursor == s->eof)
+       yasm__error(line, N_("unexpected end of file in string"));
+    strbuf[count] = ch;
+
+    if (count >= strbuf_size) {
+       strbuf = yasm_xrealloc(strbuf, strbuf_size + STRBUF_ALLOC_SIZE);
+       strbuf_size += STRBUF_ALLOC_SIZE;
+    }
+}
+
+/*!re2c
+  any = [\000-\377];
+  digit = [0-9];
+  iletter = [a-zA-Z];
+  bindigit = [01];
+  octdigit = [0-7];
+  hexdigit = [0-9a-fA-F];
+  ws = [ \t\r];
+  dquot = ["];
+  A = [aA];
+  B = [bB];
+  C = [cC];
+  D = [dD];
+  E = [eE];
+  F = [fF];
+  G = [gG];
+  H = [hH];
+  I = [iI];
+  J = [jJ];
+  K = [kK];
+  L = [lL];
+  M = [mM];
+  N = [nN];
+  O = [oO];
+  P = [pP];
+  Q = [qQ];
+  R = [rR];
+  S = [sS];
+  T = [tT];
+  U = [uU];
+  V = [vV];
+  W = [wW];
+  X = [xX];
+  Y = [yY];
+  Z = [zZ];
+*/
+
+
+int
+gas_parser_lex(YYSTYPE *lvalp, yasm_parser_gas *parser_gas)
+{
+    Scanner *s = &parser_gas->s;
+    YYCTYPE *cursor = s->cur;
+    size_t count;
+    YYCTYPE savech;
+    yasm_arch_check_id_retval check_id_ret;
+
+    /* Catch EOF */
+    if (s->eof && cursor == s->eof)
+       return 0;
+
+    /* Jump to proper "exclusive" states */
+    switch (parser_gas->state) {
+       case SECTION_DIRECTIVE:
+           goto section_directive;
+       default:
+           break;
+    }
+
+scan:
+    SCANINIT();
+
+    /*!re2c
+       /* standard decimal integer */
+       ([1-9] digit*) | "0" {
+           savech = s->tok[TOKLEN];
+           s->tok[TOKLEN] = '\0';
+           lvalp->intn = yasm_intnum_create_dec(s->tok, cur_line);
+           s->tok[TOKLEN] = savech;
+           RETURN(INTNUM);
+       }
+
+       /* 0b10010011 - binary number */
+       "0" B bindigit+ {
+           savech = s->tok[TOKLEN];
+           s->tok[TOKLEN] = '\0';
+           lvalp->intn = yasm_intnum_create_bin(s->tok+2, cur_line);
+           s->tok[TOKLEN] = savech;
+           RETURN(INTNUM);
+       }
+
+       /* 0777 - octal number */
+       "0" octdigit+ {
+           savech = s->tok[TOKLEN];
+           s->tok[TOKLEN] = '\0';
+           lvalp->intn = yasm_intnum_create_oct(s->tok, cur_line);
+           s->tok[TOKLEN] = savech;
+           RETURN(INTNUM);
+       }
+
+       /* 0xAA - hexidecimal number */
+       "0x" hexdigit+ {
+           savech = s->tok[TOKLEN];
+           s->tok[TOKLEN] = '\0';
+           /* skip 0 and x */
+           lvalp->intn = yasm_intnum_create_hex(s->tok+2, cur_line);
+           s->tok[TOKLEN] = savech;
+           RETURN(INTNUM);
+       }
+
+       /* floating point value */
+       "0" [DdEeFfTt] [-+]? (digit+)? ("." digit*)? (E [-+]? digit+)? {
+           savech = s->tok[TOKLEN];
+           s->tok[TOKLEN] = '\0';
+           lvalp->flt = yasm_floatnum_create(s->tok+2);
+           s->tok[TOKLEN] = savech;
+           RETURN(FLTNUM);
+       }
+
+       /* character constant values */
+       ['] {
+           goto charconst;
+       }
+
+       /* string constant values */
+       dquot {
+           goto stringconst;
+       }
+
+       /* operators */
+       "<<"                    { RETURN(LEFT_OP); }
+       ">>"                    { RETURN(RIGHT_OP); }
+       "<"                     { RETURN(LEFT_OP); }
+       ">"                     { RETURN(RIGHT_OP); }
+       [-+|^!*&/~$():@=,]      { RETURN(s->tok[0]); }
+
+       /* arch-independent directives */
+       ".2byte"        { RETURN(DIR_2BYTE); }
+       ".4byte"        { RETURN(DIR_4BYTE); }
+       ".8byte"        { RETURN(DIR_QUAD); }
+       ".align"        { RETURN(DIR_ALIGN); }
+       ".ascii"        { RETURN(DIR_ASCII); }
+       ".asciz"        { RETURN(DIR_ASCIZ); }
+       ".balign"       { RETURN(DIR_BALIGN); }
+       ".bss"          { RETURN(DIR_BSS); }
+       ".byte"         { RETURN(DIR_BYTE); }
+       ".comm"         { RETURN(DIR_COMM); }
+       ".data"         { RETURN(DIR_DATA); }
+       ".double"       { RETURN(DIR_DOUBLE); }
+       ".endr"         { RETURN(DIR_ENDR); }
+       ".equ"          { RETURN(DIR_EQU); }
+       ".extern"       { RETURN(DIR_EXTERN); }
+       ".file"         { RETURN(DIR_FILE); }
+       ".float"        { RETURN(DIR_FLOAT); }
+       ".global"       { RETURN(DIR_GLOBAL); }
+       ".globl"        { RETURN(DIR_GLOBAL); }
+       ".hword"        { RETURN(DIR_SHORT); }
+       ".ident"        { RETURN(DIR_IDENT); }
+       ".int"          { RETURN(DIR_INT); }
+       ".lcomm"        { RETURN(DIR_LCOMM); }
+       ".loc"          { RETURN(DIR_LOC); }
+       ".long"         { RETURN(DIR_INT); }
+       ".octa"         { RETURN(DIR_OCTA); }
+       ".org"          { RETURN(DIR_ORG); }
+       ".p2align"      { RETURN(DIR_P2ALIGN); }
+       ".rept"         { RETURN(DIR_REPT); }
+       ".section"      {
+           parser_gas->state = SECTION_DIRECTIVE;
+           RETURN(DIR_SECTION);
+       }
+       ".set"          { RETURN(DIR_EQU); }
+       ".short"        { RETURN(DIR_SHORT); }
+       ".single"       { RETURN(DIR_FLOAT); }
+       ".size"         { RETURN(DIR_SIZE); }
+       ".skip"         { RETURN(DIR_SKIP); }
+       ".space"        { RETURN(DIR_SKIP); }
+       ".string"       { RETURN(DIR_ASCIZ); }
+       ".text"         { RETURN(DIR_TEXT); }
+       ".tfloat"       { RETURN(DIR_TFLOAT); }
+       ".type"         { RETURN(DIR_TYPE); }
+       ".quad"         { RETURN(DIR_QUAD); }
+       ".word"         { RETURN(DIR_WORD); }
+
+       /* label or maybe directive */
+       [.][a-zA-Z0-9_$.]* {
+           lvalp->str_val = yasm__xstrndup(s->tok, TOKLEN);
+           RETURN(DIR_ID);
+       }
+
+       /* label */
+       [_][a-zA-Z0-9_$.]* {
+           lvalp->str_val = yasm__xstrndup(s->tok, TOKLEN);
+           RETURN(ID);
+       }
+
+       /* register or segment register */
+       [%][a-z0-9]+ {
+           savech = s->tok[TOKLEN];
+           s->tok[TOKLEN] = '\0';
+           check_id_ret = yasm_arch_parse_check_id(parser_gas->arch,
+                                                   lvalp->arch_data, s->tok+1,
+                                                   cur_line);
+           s->tok[TOKLEN] = savech;
+           switch (check_id_ret) {
+               case YASM_ARCH_CHECK_ID_REG:
+                   RETURN(REG);
+               case YASM_ARCH_CHECK_ID_REGGROUP:
+                   RETURN(REGGROUP);
+               case YASM_ARCH_CHECK_ID_SEGREG:
+                   RETURN(SEGREG);
+               default:
+                   s->tok[TOKLEN] = '\0';
+                   yasm__error(cur_line,
+                       N_("Unrecognized register name `%s'"), s->tok);
+                   s->tok[TOKLEN] = savech;
+                   lvalp->arch_data[0] = 0;
+                   lvalp->arch_data[1] = 0;
+                   lvalp->arch_data[2] = 0;
+                   lvalp->arch_data[3] = 0;
+                   RETURN(REG);
+           }
+       }
+
+       /* identifier that may be an instruction, etc. */
+       [a-zA-Z][a-zA-Z0-9_$.]* {
+           savech = s->tok[TOKLEN];
+           s->tok[TOKLEN] = '\0';
+           check_id_ret = yasm_arch_parse_check_id(parser_gas->arch,
+                                                   lvalp->arch_data, s->tok,
+                                                   cur_line);
+           s->tok[TOKLEN] = savech;
+           switch (check_id_ret) {
+               case YASM_ARCH_CHECK_ID_NONE:
+                   /* Just an identifier, return as such. */
+                   lvalp->str_val = yasm__xstrndup(s->tok, TOKLEN);
+                   RETURN(ID);
+               case YASM_ARCH_CHECK_ID_INSN:
+                   RETURN(INSN);
+               case YASM_ARCH_CHECK_ID_PREFIX:
+                   RETURN(PREFIX);
+               case YASM_ARCH_CHECK_ID_TARGETMOD:
+                   RETURN(TARGETMOD);
+               case YASM_ARCH_CHECK_ID_REG:
+               case YASM_ARCH_CHECK_ID_SEGREG:
+                   lvalp->str_val = yasm__xstrndup(s->tok, TOKLEN);
+                   RETURN(ID);
+               default:
+                   yasm__warning(YASM_WARN_GENERAL, cur_line,
+                       N_("Arch feature not supported, treating as identifier"));
+                   lvalp->str_val = yasm__xstrndup(s->tok, TOKLEN);
+                   RETURN(ID);
+           }
+       }
+
+       "#" (any \ [\n])*       { goto scan; }
+
+       ws+                     { goto scan; }
+
+       "\n"                    {
+           if (parser_gas->save_input && cursor != s->eof)
+               cursor = save_line(parser_gas, cursor);
+           parser_gas->state = INITIAL;
+           RETURN(s->tok[0]);
+       }
+
+       any {
+           yasm__warning(YASM_WARN_UNREC_CHAR, cur_line,
+                         N_("ignoring unrecognized character `%s'"),
+                         yasm__conv_unprint(s->tok[0]));
+           goto scan;
+       }
+    */
+
+    /* .section directive (the section name portion thereof) */
+section_directive:
+    SCANINIT();
+
+    /*!re2c
+       [a-zA-Z0-9_$.-]+ {
+           lvalp->str_val = yasm__xstrndup(s->tok, TOKLEN);
+           parser_gas->state = INITIAL;
+           RETURN(ID);
+       }
+
+       dquot                   { goto stringconst; }
+
+       ws+                     { goto section_directive; }
+
+       ","                     {
+           parser_gas->state = INITIAL;
+           RETURN(s->tok[0]);
+       }
+
+       "\n"                    {
+           if (parser_gas->save_input && cursor != s->eof)
+               cursor = save_line(parser_gas, cursor);
+           parser_gas->state = INITIAL;
+           RETURN(s->tok[0]);
+       }
+
+       any {
+           yasm__warning(YASM_WARN_UNREC_CHAR, cur_line,
+                         N_("ignoring unrecognized character `%s'"),
+                         yasm__conv_unprint(s->tok[0]));
+           goto section_directive;
+       }
+    */
+
+    /* character constant values */
+charconst:
+    /*TODO*/
+
+    /* string constant values */
+stringconst:
+    strbuf = yasm_xmalloc(STRBUF_ALLOC_SIZE);
+    strbuf_size = STRBUF_ALLOC_SIZE;
+    count = 0;
+
+stringconst_scan:
+    SCANINIT();
+
+    /*!re2c
+       /* Escaped constants */
+       "\\b"   {
+           strbuf_append(count++, cursor, s, cur_line, '\b');
+           goto stringconst_scan;
+       }
+       "\\f"   {
+           strbuf_append(count++, cursor, s, cur_line, '\f');
+           goto stringconst_scan;
+       }
+       "\\n"   {
+           strbuf_append(count++, cursor, s, cur_line, '\n');
+           goto stringconst_scan;
+       }
+       "\\r"   {
+           strbuf_append(count++, cursor, s, cur_line, '\r');
+           goto stringconst_scan;
+       }
+       "\\t"   {
+           strbuf_append(count++, cursor, s, cur_line, '\t');
+           goto stringconst_scan;
+       }
+       "\\" digit digit digit  {
+           savech = s->tok[TOKLEN];
+           s->tok[TOKLEN] = '\0';
+           lvalp->intn = yasm_intnum_create_oct(s->tok+1, cur_line);
+           s->tok[TOKLEN] = savech;
+
+           strbuf_append(count++, cursor, s, cur_line,
+                         yasm_intnum_get_int(lvalp->intn));
+           yasm_intnum_destroy(lvalp->intn);
+           goto stringconst_scan;
+       }
+       "\\" X hexdigit+    {
+           savech = s->tok[TOKLEN];
+           s->tok[TOKLEN] = '\0';
+           lvalp->intn = yasm_intnum_create_hex(s->tok+2, cur_line);
+           s->tok[TOKLEN] = savech;
+
+           strbuf_append(count++, cursor, s, cur_line,
+                         yasm_intnum_get_int(lvalp->intn));
+           yasm_intnum_destroy(lvalp->intn);
+           goto stringconst_scan;
+       }
+       "\\\\"      {
+           strbuf_append(count++, cursor, s, cur_line, '\\');
+           goto stringconst_scan;
+       }
+       "\\\""      {
+           strbuf_append(count++, cursor, s, cur_line, '"');
+           goto stringconst_scan;
+       }
+       /*"\\" any    {
+           strbuf_append(count++, cursor, s, cur_line, s->tok[0]);
+           goto stringconst_scan;
+       }*/
+
+       dquot   {
+           strbuf_append(count, cursor, s, cur_line, '\0');
+           lvalp->str_val = strbuf;
+           RETURN(STRING);
+       }
+
+       any     {
+           strbuf_append(count++, cursor, s, cur_line, s->tok[0]);
+           goto stringconst_scan;
+       }
+    */
+}
diff --git a/modules/parsers/gas/tests/Makefile.inc b/modules/parsers/gas/tests/Makefile.inc
new file mode 100644 (file)
index 0000000..dbe3323
--- /dev/null
@@ -0,0 +1,23 @@
+# $Id$
+
+TESTS += modules/parsers/gas/tests/gas_test.sh
+
+EXTRA_DIST += modules/parsers/gas/tests/gas_test.sh
+EXTRA_DIST += modules/parsers/gas/tests/datavis.asm
+EXTRA_DIST += modules/parsers/gas/tests/datavis.errwarn
+EXTRA_DIST += modules/parsers/gas/tests/datavis.hex
+EXTRA_DIST += modules/parsers/gas/tests/datavis2.asm
+EXTRA_DIST += modules/parsers/gas/tests/datavis2.errwarn
+EXTRA_DIST += modules/parsers/gas/tests/datavis2.hex
+EXTRA_DIST += modules/parsers/gas/tests/jmpcall.asm
+EXTRA_DIST += modules/parsers/gas/tests/jmpcall.errwarn
+EXTRA_DIST += modules/parsers/gas/tests/jmpcall.hex
+EXTRA_DIST += modules/parsers/gas/tests/reggroup-err.asm
+EXTRA_DIST += modules/parsers/gas/tests/reggroup-err.errwarn
+EXTRA_DIST += modules/parsers/gas/tests/reggroup.asm
+EXTRA_DIST += modules/parsers/gas/tests/reggroup.errwarn
+EXTRA_DIST += modules/parsers/gas/tests/reggroup.hex
+
+EXTRA_DIST += modules/parsers/gas/tests/amd64/Makefile.inc
+
+include modules/parsers/gas/tests/amd64/Makefile.inc
diff --git a/modules/parsers/gas/tests/amd64/Makefile.inc b/modules/parsers/gas/tests/amd64/Makefile.inc
new file mode 100644 (file)
index 0000000..c935760
--- /dev/null
@@ -0,0 +1,9 @@
+# $Id$
+
+TESTS += modules/parsers/gas/tests/amd64/gas_amd64_test.sh
+
+EXTRA_DIST += modules/parsers/gas/tests/amd64/gas_amd64_test.sh
+EXTRA_DIST += modules/parsers/gas/tests/amd64/riprel.asm
+EXTRA_DIST += modules/parsers/gas/tests/amd64/riprel.errwarn
+EXTRA_DIST += modules/parsers/gas/tests/amd64/riprel.hex
+
diff --git a/modules/parsers/gas/tests/amd64/gas_amd64_test.sh b/modules/parsers/gas/tests/amd64/gas_amd64_test.sh
new file mode 100755 (executable)
index 0000000..3e2226a
--- /dev/null
@@ -0,0 +1,4 @@
+#! /bin/sh
+# $Id$
+${srcdir}/out_test.sh gas_amd64_test modules/parsers/gas/tests/amd64 "gas-compat parser" "-f elf -m amd64 -p gas" ".o"
+exit $?
diff --git a/modules/parsers/gas/tests/amd64/riprel.asm b/modules/parsers/gas/tests/amd64/riprel.asm
new file mode 100644 (file)
index 0000000..3cd8425
--- /dev/null
@@ -0,0 +1 @@
+mov %rax,foo(%rip)
diff --git a/modules/parsers/gas/tests/amd64/riprel.errwarn b/modules/parsers/gas/tests/amd64/riprel.errwarn
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/modules/parsers/gas/tests/amd64/riprel.hex b/modules/parsers/gas/tests/amd64/riprel.hex
new file mode 100644 (file)
index 0000000..437b656
--- /dev/null
@@ -0,0 +1,640 @@
+7f 
+45 
+4c 
+46 
+02 
+01 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+3e 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+40 
+00 
+00 
+00 
+00 
+00 
+40 
+00 
+06 
+00 
+01 
+00 
+48 
+89 
+05 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+fc 
+ff 
+ff 
+ff 
+ff 
+ff 
+ff 
+ff 
+00 
+2e 
+74 
+65 
+78 
+74 
+00 
+2e 
+72 
+65 
+6c 
+61 
+2e 
+74 
+65 
+78 
+74 
+00 
+2e 
+73 
+74 
+72 
+74 
+61 
+62 
+00 
+2e 
+73 
+79 
+6d 
+74 
+61 
+62 
+00 
+2e 
+73 
+68 
+73 
+74 
+72 
+74 
+61 
+62 
+00 
+00 
+2d 
+00 
+66 
+6f 
+6f 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+04 
+00 
+f1 
+ff 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+22 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+60 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+2c 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+12 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+8c 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+07 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+1a 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+94 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+60 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+08 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+18 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+06 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+40 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+07 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+07 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+48 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+18 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+08 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+18 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
diff --git a/modules/parsers/gas/tests/datavis.asm b/modules/parsers/gas/tests/datavis.asm
new file mode 100644 (file)
index 0000000..1bae755
--- /dev/null
@@ -0,0 +1,39 @@
+#.file "string"
+.extern extsym2
+.global label1
+.globl label2
+.text
+       call    extsym
+       call    extsym2
+.data
+label1:
+.ascii "baz"
+.asciz "foo"
+.string "bar", "str2"
+.byte 1, 2, 070, 0x12
+.byte
+
+.section .xx, "", @ progbits
+.hword 0
+.short 5
+.word 10
+.long 15
+.int 30
+.quad 20
+.octa 40
+
+.section .yy, "w", @nobits
+.skip 4
+.skip 4, 1
+
+.bss
+label2:
+.skip 4
+.skip 4, 1
+
+.section .data2
+.float 0E1e10
+.double 0E-1.11
+.skip 4
+.skip 4, 1
+.tfloat 0E+3.14e2
diff --git a/modules/parsers/gas/tests/datavis.errwarn b/modules/parsers/gas/tests/datavis.errwarn
new file mode 100644 (file)
index 0000000..3f7b1fe
--- /dev/null
@@ -0,0 +1 @@
+-:37: warning: uninitialized space declared in code/data section: zeroing
diff --git a/modules/parsers/gas/tests/datavis.hex b/modules/parsers/gas/tests/datavis.hex
new file mode 100644 (file)
index 0000000..b5a76fb
--- /dev/null
@@ -0,0 +1,920 @@
+7f 
+45 
+4c 
+46 
+01 
+01 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+03 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+e0 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+34 
+00 
+00 
+00 
+00 
+00 
+28 
+00 
+0b 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+e8 
+fc 
+ff 
+ff 
+ff 
+e8 
+fc 
+ff 
+ff 
+ff 
+00 
+00 
+01 
+00 
+00 
+00 
+02 
+0b 
+00 
+00 
+06 
+00 
+00 
+00 
+02 
+08 
+00 
+00 
+62 
+61 
+7a 
+66 
+6f 
+6f 
+00 
+62 
+61 
+72 
+00 
+73 
+74 
+72 
+32 
+00 
+01 
+02 
+38 
+12 
+00 
+00 
+05 
+00 
+0a 
+00 
+0f 
+00 
+00 
+00 
+1e 
+00 
+00 
+00 
+14 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+28 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+f9 
+02 
+15 
+50 
+c3 
+f5 
+28 
+5c 
+8f 
+c2 
+f1 
+bf 
+00 
+00 
+00 
+00 
+01 
+01 
+01 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+9d 
+07 
+40 
+00 
+2e 
+74 
+65 
+78 
+74 
+00 
+2e 
+64 
+61 
+74 
+61 
+00 
+2e 
+78 
+78 
+00 
+2e 
+79 
+79 
+00 
+2e 
+62 
+73 
+73 
+00 
+2e 
+64 
+61 
+74 
+61 
+32 
+00 
+2e 
+72 
+65 
+6c 
+2e 
+74 
+65 
+78 
+74 
+00 
+2e 
+73 
+74 
+72 
+74 
+61 
+62 
+00 
+2e 
+73 
+79 
+6d 
+74 
+61 
+62 
+00 
+2e 
+73 
+68 
+73 
+74 
+72 
+74 
+61 
+62 
+00 
+00 
+00 
+00 
+00 
+2d 
+00 
+65 
+78 
+74 
+73 
+79 
+6d 
+32 
+00 
+6c 
+61 
+62 
+65 
+6c 
+31 
+00 
+6c 
+61 
+62 
+65 
+6c 
+32 
+00 
+65 
+78 
+74 
+73 
+79 
+6d 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+f1 
+ff 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+0a 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+09 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+08 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+07 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+06 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+04 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+0b 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+00 
+06 
+00 
+12 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+00 
+09 
+00 
+19 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+3b 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+b4 
+00 
+00 
+00 
+45 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+2b 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+fc 
+00 
+00 
+00 
+20 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+33 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+1c 
+01 
+00 
+00 
+c0 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+08 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+06 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+40 
+00 
+00 
+00 
+0a 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+21 
+00 
+00 
+00 
+09 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+4c 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+08 
+00 
+00 
+00 
+07 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+5c 
+00 
+00 
+00 
+14 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+0d 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+70 
+00 
+00 
+00 
+26 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+11 
+00 
+00 
+00 
+08 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+08 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+15 
+00 
+00 
+00 
+08 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+08 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+1a 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+96 
+00 
+00 
+00 
+1e 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
diff --git a/modules/parsers/gas/tests/datavis2.asm b/modules/parsers/gas/tests/datavis2.asm
new file mode 100644 (file)
index 0000000..9d0d515
--- /dev/null
@@ -0,0 +1,13 @@
+       .section .eh_frame, "",@progbits
+.EHCIE:
+       .4byte 0x10
+       .4byte 0x0
+       .2byte 1
+       .8byte 4
+       .byte   0x01, 0x00, 0x01, 0x78, 0x10, 0x00, 0x0c, 0x07
+       .byte   0x08, 0x90, 0x01, 0x00
+
+       .section .debug_line, ""
+       .section        .note.GNU-stack,"",@progbits
+       .ident  "# : compiled with : "
+       .ident  "second ident"
diff --git a/modules/parsers/gas/tests/datavis2.errwarn b/modules/parsers/gas/tests/datavis2.errwarn
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/modules/parsers/gas/tests/datavis2.hex b/modules/parsers/gas/tests/datavis2.hex
new file mode 100644 (file)
index 0000000..3526b01
--- /dev/null
@@ -0,0 +1,712 @@
+7f 
+45 
+4c 
+46 
+01 
+01 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+03 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+60 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+34 
+00 
+00 
+00 
+00 
+00 
+28 
+00 
+09 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+01 
+78 
+10 
+00 
+0c 
+07 
+08 
+90 
+01 
+00 
+00 
+23 
+20 
+3a 
+20 
+63 
+6f 
+6d 
+70 
+69 
+6c 
+65 
+64 
+20 
+77 
+69 
+74 
+68 
+20 
+3a 
+20 
+00 
+73 
+65 
+63 
+6f 
+6e 
+64 
+20 
+69 
+64 
+65 
+6e 
+74 
+00 
+00 
+00 
+00 
+00 
+2e 
+74 
+65 
+78 
+74 
+00 
+2e 
+65 
+68 
+5f 
+66 
+72 
+61 
+6d 
+65 
+00 
+2e 
+64 
+65 
+62 
+75 
+67 
+5f 
+6c 
+69 
+6e 
+65 
+00 
+2e 
+6e 
+6f 
+74 
+65 
+2e 
+47 
+4e 
+55 
+2d 
+73 
+74 
+61 
+63 
+6b 
+00 
+2e 
+63 
+6f 
+6d 
+6d 
+65 
+6e 
+74 
+00 
+2e 
+73 
+74 
+72 
+74 
+61 
+62 
+00 
+2e 
+73 
+79 
+6d 
+74 
+61 
+62 
+00 
+2e 
+73 
+68 
+73 
+74 
+72 
+74 
+61 
+62 
+00 
+00 
+2d 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+f1 
+ff 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+08 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+07 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+06 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+05 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+05 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+46 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+84 
+00 
+00 
+00 
+50 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+36 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+d4 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+3e 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+d8 
+00 
+00 
+00 
+80 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+08 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+06 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+40 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+07 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+40 
+00 
+00 
+00 
+1e 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+11 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+5e 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+1d 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+5e 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+2d 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+5e 
+00 
+00 
+00 
+23 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
diff --git a/modules/parsers/gas/tests/gas_test.sh b/modules/parsers/gas/tests/gas_test.sh
new file mode 100755 (executable)
index 0000000..bce85d3
--- /dev/null
@@ -0,0 +1,4 @@
+#! /bin/sh
+# $Id$
+${srcdir}/out_test.sh gas_test modules/parsers/gas/tests "gas-compat parser" "-f elf -p gas" ".o"
+exit $?
diff --git a/modules/parsers/gas/tests/jmpcall.asm b/modules/parsers/gas/tests/jmpcall.asm
new file mode 100644 (file)
index 0000000..269ff22
--- /dev/null
@@ -0,0 +1,13 @@
+#.text
+label:
+       call    *%eax
+       call    %eax
+       call    *(%eax)
+       call    (%eax)
+       call    label(,1)
+       call    label
+       call    label+5
+       call    *label
+       call    *label(%eax)
+       jmp     %fs:label
+       jmp     *%fs:label
diff --git a/modules/parsers/gas/tests/jmpcall.errwarn b/modules/parsers/gas/tests/jmpcall.errwarn
new file mode 100644 (file)
index 0000000..6c9ed60
--- /dev/null
@@ -0,0 +1,4 @@
+-:4: warning: indirect call without `*'
+-:6: warning: indirect call without `*'
+-:7: warning: indirect call without `*'
+-:12: warning: skipping prefixes on this instruction
diff --git a/modules/parsers/gas/tests/jmpcall.hex b/modules/parsers/gas/tests/jmpcall.hex
new file mode 100644 (file)
index 0000000..6677cf9
--- /dev/null
@@ -0,0 +1,496 @@
+7f 
+45 
+4c 
+46 
+01 
+01 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+03 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+34 
+00 
+00 
+00 
+00 
+00 
+28 
+00 
+06 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+ff 
+d0 
+ff 
+d0 
+ff 
+10 
+ff 
+10 
+ff 
+15 
+00 
+00 
+00 
+00 
+e8 
+ed 
+ff 
+ff 
+ff 
+e8 
+ed 
+ff 
+ff 
+ff 
+ff 
+15 
+00 
+00 
+00 
+00 
+ff 
+90 
+00 
+00 
+00 
+00 
+eb 
+da 
+64 
+ff 
+25 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+0a 
+00 
+00 
+00 
+01 
+03 
+00 
+00 
+1a 
+00 
+00 
+00 
+01 
+03 
+00 
+00 
+20 
+00 
+00 
+00 
+01 
+03 
+00 
+00 
+29 
+00 
+00 
+00 
+01 
+03 
+00 
+00 
+00 
+2e 
+74 
+65 
+78 
+74 
+00 
+2e 
+72 
+65 
+6c 
+2e 
+74 
+65 
+78 
+74 
+00 
+2e 
+73 
+74 
+72 
+74 
+61 
+62 
+00 
+2e 
+73 
+79 
+6d 
+74 
+61 
+62 
+00 
+2e 
+73 
+68 
+73 
+74 
+72 
+74 
+61 
+62 
+00 
+00 
+00 
+2d 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+f1 
+ff 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+21 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+90 
+00 
+00 
+00 
+2b 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+11 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+bc 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+19 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+c0 
+00 
+00 
+00 
+40 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+06 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+40 
+00 
+00 
+00 
+2d 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+07 
+00 
+00 
+00 
+09 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+70 
+00 
+00 
+00 
+20 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+08 
+00 
+00 
+00 
diff --git a/modules/parsers/gas/tests/reggroup-err.asm b/modules/parsers/gas/tests/reggroup-err.asm
new file mode 100644 (file)
index 0000000..fc6ca79
--- /dev/null
@@ -0,0 +1,5 @@
+       fadd    %st (2)
+       fadd    %st (2), %st(0)
+       fadd    %st (2), %st
+       fadd    %st, %st
+       fadd    %st (8)
diff --git a/modules/parsers/gas/tests/reggroup-err.errwarn b/modules/parsers/gas/tests/reggroup-err.errwarn
new file mode 100644 (file)
index 0000000..1b6d02b
--- /dev/null
@@ -0,0 +1 @@
+-:5: bad register index `8'
diff --git a/modules/parsers/gas/tests/reggroup.asm b/modules/parsers/gas/tests/reggroup.asm
new file mode 100644 (file)
index 0000000..5c0d0bf
--- /dev/null
@@ -0,0 +1,5 @@
+       fadd    %st (2)
+       fadd    %st (2), %st(0)
+       fadd    %st (2), %st
+       fadd    %st, %st
+#      fadd    %st (8)
diff --git a/modules/parsers/gas/tests/reggroup.errwarn b/modules/parsers/gas/tests/reggroup.errwarn
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/modules/parsers/gas/tests/reggroup.hex b/modules/parsers/gas/tests/reggroup.hex
new file mode 100644 (file)
index 0000000..e265ffb
--- /dev/null
@@ -0,0 +1,360 @@
+7f 
+45 
+4c 
+46 
+01 
+01 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+03 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+a0 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+34 
+00 
+00 
+00 
+00 
+00 
+28 
+00 
+05 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+d8 
+c2 
+d8 
+c2 
+d8 
+c2 
+d8 
+c0 
+00 
+2e 
+74 
+65 
+78 
+74 
+00 
+2e 
+73 
+74 
+72 
+74 
+61 
+62 
+00 
+2e 
+73 
+79 
+6d 
+74 
+61 
+62 
+00 
+2e 
+73 
+68 
+73 
+74 
+72 
+74 
+61 
+62 
+00 
+00 
+00 
+00 
+00 
+2d 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+f1 
+ff 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+17 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+48 
+00 
+00 
+00 
+21 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+07 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+6c 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+0f 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+70 
+00 
+00 
+00 
+30 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+06 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+40 
+00 
+00 
+00 
+08 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+00 
+00 
+00 
+00