]> granicus.if.org Git - yasm/commitdiff
Support standalone, segment, and REX prefixes in GAS mode.
authorPeter Johnson <peter@tortall.net>
Mon, 24 Oct 2005 04:48:37 +0000 (04:48 -0000)
committerPeter Johnson <peter@tortall.net>
Mon, 24 Oct 2005 04:48:37 +0000 (04:48 -0000)
* bytecode.c (yasm_bc_create_empty_insn): New function to create empty
instruction that can have prefixes applied to it, for standalone prefixes.
* bytecode.h (yasm_bc_create_empty_insn): Prototype.

* x86arch.h (x86_parse_insn_prefix): Add prefix types for segment registers
(X86_SEGREG) and REX bytes (X86_REX).
(yasm_x86__bc_apply_prefixes): Adjust prototype to include REX pointer (as
this isn't in the x86_common structure).
* x86bc.c (yasm_x86__bc_apply_prefixes): Support the new prefix types.

* x86id.re (x86_finalize_*): Use const x86_insn_info; all insn_infos are
const so these pointers should be as well.
(yasm_x86__finalize_insn): Handle empty instruction case by pointing to new
empty_insn info.
(empty_insn): New.
(yasm_x86__parse_check_prefix): Support GAS prefix naming, and REX and jump
hint prefixes (only in GAS mode at the moment).

* gas-bison.y: Add rules to handle segreg prefixes as well as standalone
prefixes (both segreg and others).

* gas-prefix.asm: New testcase that also hits the warning cases in
yasm_x86__bc_apply_prefixes X86_REX case.

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

libyasm/bytecode.c
libyasm/bytecode.h
modules/arch/x86/tests/gas64/Makefile.inc
modules/arch/x86/tests/gas64/gas-prefix.asm [new file with mode: 0644]
modules/arch/x86/tests/gas64/gas-prefix.errwarn [new file with mode: 0644]
modules/arch/x86/tests/gas64/gas-prefix.hex [new file with mode: 0644]
modules/arch/x86/x86arch.h
modules/arch/x86/x86bc.c
modules/arch/x86/x86id.re
modules/parsers/gas/gas-bison.y

index e86b9c777ed8e52de06a9de3cb7a03362c6b46dd..742b6356c42ac4ec580c14d8263e60f0fc2a90eb 100644 (file)
@@ -1153,6 +1153,25 @@ yasm_bc_create_insn(yasm_arch *arch, const unsigned long insn_data[4],
     return yasm_bc_create_common(&bc_insn_callback, insn, line);
 }
 
+yasm_bytecode *
+yasm_bc_create_empty_insn(yasm_arch *arch, unsigned long line)
+{
+    bytecode_insn *insn = yasm_xmalloc(sizeof(bytecode_insn));
+
+    insn->arch = arch;
+    insn->insn_data[0] = 0;
+    insn->insn_data[1] = 0;
+    insn->insn_data[2] = 0;
+    insn->insn_data[3] = 0;
+    insn->num_operands = 0;
+    insn->num_prefixes = 0;
+    insn->prefixes = NULL;
+    insn->num_segregs = 0;
+    insn->segregs = NULL;
+
+    return yasm_bc_create_common(&bc_insn_callback, insn, line);
+}
+
 void
 yasm_bc_insn_add_prefix(yasm_bytecode *bc, const unsigned long prefix_data[4])
 {
index d5cd85523ed640c692cc1a627aa4f24da50160cb..e9adcfd89d33654bb5afac2a4cfccea06ac590c8 100644 (file)
@@ -213,6 +213,15 @@ void yasm_bc_set_multiple(yasm_bytecode *bc, /*@keep@*/ yasm_expr *e);
     (yasm_arch *arch, const unsigned long insn_data[4], int num_operands,
      /*@null@*/ yasm_insn_operands *operands, unsigned long line);
 
+/** Create a bytecode that represents a single empty (0 length) instruction.
+ * This is used for handling solitary prefixes.
+ * \param arch         instruction's architecture
+ * \param line         virtual line (from yasm_linemap)
+ * \return Newly allocated bytecode.
+ */
+/*@only@*/ yasm_bytecode *yasm_bc_create_empty_insn(yasm_arch *arch,
+                                                   unsigned long line);
+
 /** Associate a prefix with an instruction bytecode.
  * \param bc           instruction bytecode
  * \param prefix_data  data the identifies the prefix
index 148f3f370e2881fdd6c277550f59d5d7083ca727..f8a1f87eda5019213de4b143ea207ea103362420 100644 (file)
@@ -27,6 +27,9 @@ EXTRA_DIST += modules/arch/x86/tests/gas64/gas-movsxs.hex
 EXTRA_DIST += modules/arch/x86/tests/gas64/gas-muldiv.asm
 EXTRA_DIST += modules/arch/x86/tests/gas64/gas-muldiv.errwarn
 EXTRA_DIST += modules/arch/x86/tests/gas64/gas-muldiv.hex
+EXTRA_DIST += modules/arch/x86/tests/gas64/gas-prefix.asm
+EXTRA_DIST += modules/arch/x86/tests/gas64/gas-prefix.errwarn
+EXTRA_DIST += modules/arch/x86/tests/gas64/gas-prefix.hex
 EXTRA_DIST += modules/arch/x86/tests/gas64/gas-retenter.asm
 EXTRA_DIST += modules/arch/x86/tests/gas64/gas-retenter.errwarn
 EXTRA_DIST += modules/arch/x86/tests/gas64/gas-retenter.hex
diff --git a/modules/arch/x86/tests/gas64/gas-prefix.asm b/modules/arch/x86/tests/gas64/gas-prefix.asm
new file mode 100644 (file)
index 0000000..7fa5ed4
--- /dev/null
@@ -0,0 +1,9 @@
+rep
+movsb
+rexx
+rexx rexy
+rex jmp foo
+rex movb $0, %ah
+rex movb $0, %sil
+rex64 movl $0, %eax
+foo:
diff --git a/modules/arch/x86/tests/gas64/gas-prefix.errwarn b/modules/arch/x86/tests/gas64/gas-prefix.errwarn
new file mode 100644 (file)
index 0000000..580f257
--- /dev/null
@@ -0,0 +1,4 @@
+-:4: warning: multiple REX prefixes, using leftmost
+-:5: warning: ignoring REX prefix on jump
+-:6: warning: REX prefix not allowed on this instruction, ignoring
+-:7: warning: overriding generated REX prefix
diff --git a/modules/arch/x86/tests/gas64/gas-prefix.hex b/modules/arch/x86/tests/gas64/gas-prefix.hex
new file mode 100644 (file)
index 0000000..61f99ae
--- /dev/null
@@ -0,0 +1,544 @@
+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 
+e0 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+40 
+00 
+00 
+00 
+00 
+00 
+40 
+00 
+05 
+00 
+01 
+00 
+f3 
+a4 
+44 
+44 
+eb 
+0b 
+b4 
+00 
+40 
+b6 
+00 
+48 
+b8 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+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 
+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 
+00 
+00 
+04 
+00 
+11 
+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 
+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 
+17 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+54 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+21 
+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 
+07 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+78 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+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 
+0f 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+7c 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+60 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+04 
+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 
+11 
+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 
index 98f8ef8bd7b2fdffc3f720568ffd0cdb4cb323ff..afb4a70c4f04ae6bf017e64f34d3eebf5a98aa48 100644 (file)
@@ -98,7 +98,9 @@ typedef enum {
 typedef enum {
     X86_LOCKREP = 1,
     X86_ADDRSIZE,
-    X86_OPERSIZE
+    X86_OPERSIZE,
+    X86_SEGREG,
+    X86_REX
 } x86_parse_insn_prefix;
 
 typedef enum {
@@ -247,8 +249,8 @@ void yasm_x86__bc_transform_jmp(yasm_bytecode *bc, x86_jmp *jmp);
 void yasm_x86__bc_transform_jmpfar(yasm_bytecode *bc, x86_jmpfar *jmpfar);
 
 void yasm_x86__bc_apply_prefixes
-    (x86_common *common, int num_prefixes, unsigned long **prefixes,
-     unsigned long line);
+    (x86_common *common, unsigned char *rex, int num_prefixes,
+     unsigned long **prefixes, unsigned long line);
 
 void yasm_x86__ea_init(yasm_effaddr *ea, unsigned int spare,
                       /*@null@*/ yasm_symrec *origin);
index b7f879f4c786b4b8161250eff0211faa80355667..3e1446419232bdb4fb4e3a5ead24436a63caea0b 100644 (file)
@@ -289,10 +289,12 @@ yasm_x86__ea_create_imm(yasm_expr *imm, unsigned int im_len)
 /*@=compmempass@*/
 
 void
-yasm_x86__bc_apply_prefixes(x86_common *common, int num_prefixes,
-                           unsigned long **prefixes, unsigned long line)
+yasm_x86__bc_apply_prefixes(x86_common *common, unsigned char *rex,
+                           int num_prefixes, unsigned long **prefixes,
+                           unsigned long line)
 {
     int i;
+    int first = 1;
 
     for (i=0; i<num_prefixes; i++) {
        switch ((x86_parse_insn_prefix)prefixes[i][0]) {
@@ -308,6 +310,36 @@ yasm_x86__bc_apply_prefixes(x86_common *common, int num_prefixes,
            case X86_OPERSIZE:
                common->opersize = (unsigned char)prefixes[i][1];
                break;
+           case X86_SEGREG:
+               /* This is a hack.. we should really be putting this in the
+                * the effective address!
+                */
+               common->lockrep_pre = (unsigned char)prefixes[i][1];
+               break;
+           case X86_REX:
+               if (!rex)
+                   yasm__warning(YASM_WARN_GENERAL, line,
+                       N_("ignoring REX prefix on jump"));
+               else if (*rex == 0xff)
+                   yasm__warning(YASM_WARN_GENERAL, line,
+                       N_("REX prefix not allowed on this instruction, ignoring"));
+               else {
+                   if (*rex != 0) {
+                       if (first)
+                           yasm__warning(YASM_WARN_GENERAL, line,
+                               N_("overriding generated REX prefix"));
+                       else
+                           yasm__warning(YASM_WARN_GENERAL, line,
+                               N_("multiple REX prefixes, using leftmost"));
+                   }
+                   /* Here we assume that we can't get this prefix in non
+                    * 64 bit mode due to checks in parse_check_prefix().
+                    */
+                   common->mode_bits = 64;
+                   *rex = (unsigned char)prefixes[i][1];
+               }
+               first = 0;
+               break;
        }
     }
 }
index 644ff6a34f9bbeb995ab6744111a1c109ccf3230..0f399fcc647233d8b6206f2d6c260f9296f377ff 100644 (file)
@@ -283,6 +283,11 @@ typedef struct x86_insn_info {
  * General instruction groupings
  */
 
+/* Empty instruction */
+static const x86_insn_info empty_insn[] = {
+    { CPU_Any, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, {0, 0, 0} }
+};
+
 /* Placeholder for instructions invalid in 64-bit mode */
 static const x86_insn_info not64_insn[] = {
     { CPU_Not64, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, {0, 0, 0} }
@@ -1990,7 +1995,7 @@ static const x86_insn_info xbts_insn[] = {
 
 
 static void
-x86_finalize_common(x86_common *common, x86_insn_info *info,
+x86_finalize_common(x86_common *common, const x86_insn_info *info,
                    unsigned int mode_bits)
 {
     common->addrsize = 0;
@@ -2000,7 +2005,7 @@ x86_finalize_common(x86_common *common, x86_insn_info *info,
 }
 
 static void
-x86_finalize_opcode(x86_opcode *opcode, x86_insn_info *info)
+x86_finalize_opcode(x86_opcode *opcode, const x86_insn_info *info)
 {
     opcode->len = info->opcode_len;
     opcode->opcode[0] = info->opcode[0];
@@ -2012,7 +2017,7 @@ static void
 x86_finalize_jmpfar(yasm_arch *arch, yasm_bytecode *bc,
                    const unsigned long data[4], int num_operands,
                    yasm_insn_operands *operands, int num_prefixes,
-                   unsigned long **prefixes, x86_insn_info *info)
+                   unsigned long **prefixes, const x86_insn_info *info)
 {
     x86_jmpfar *jmpfar;
     yasm_insn_operand *op;
@@ -2041,8 +2046,8 @@ x86_finalize_jmpfar(yasm_arch *arch, yasm_bytecode *bc,
            yasm_internal_error(N_("didn't get FAR expression in jmpfar"));
     }
 
-    yasm_x86__bc_apply_prefixes((x86_common *)jmpfar, num_prefixes, prefixes,
-                               bc->line);
+    yasm_x86__bc_apply_prefixes((x86_common *)jmpfar, NULL, num_prefixes,
+                               prefixes, bc->line);
 
     /* Transform the bytecode */
     yasm_x86__bc_transform_jmpfar(bc, jmpfar);
@@ -2052,7 +2057,7 @@ static void
 x86_finalize_jmp(yasm_arch *arch, yasm_bytecode *bc, yasm_bytecode *prev_bc,
                 const unsigned long data[4], int num_operands,
                 yasm_insn_operands *operands, int num_prefixes,
-                unsigned long **prefixes, x86_insn_info *jinfo)
+                unsigned long **prefixes, const x86_insn_info *jinfo)
 {
     yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
     x86_jmp *jmp;
@@ -2146,8 +2151,8 @@ x86_finalize_jmp(yasm_arch *arch, yasm_bytecode *bc, yasm_bytecode *prev_bc,
        yasm__error(bc->line,
                    N_("no NEAR form of that jump instruction exists"));
 
-    yasm_x86__bc_apply_prefixes((x86_common *)jmp, num_prefixes, prefixes,
-                               bc->line);
+    yasm_x86__bc_apply_prefixes((x86_common *)jmp, NULL, num_prefixes,
+                               prefixes, bc->line);
 
     /* Transform the bytecode */
     yasm_x86__bc_transform_jmp(bc, jmp);
@@ -2164,7 +2169,7 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
     yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
     x86_insn *insn;
     int num_info = (int)(data[1]&0xFF);
-    x86_insn_info *info = (x86_insn_info *)data[0];
+    const x86_insn_info *info = (const x86_insn_info *)data[0];
     unsigned long mod_data = data[1] >> 8;
     unsigned char mode_bits = (unsigned char)(data[3] & 0xFF);
     unsigned long suffix = (data[3]>>8) & 0xFF;
@@ -2178,6 +2183,11 @@ 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};
 
+    if (!info) {
+       num_info = 1;
+       info = empty_insn;
+    }
+
     /* Build local array of operands from list, since we know we have a max
      * of 3 operands.
      */
@@ -2804,8 +2814,8 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
     } else
        insn->imm = NULL;
 
-    yasm_x86__bc_apply_prefixes((x86_common *)insn, num_prefixes, prefixes,
-                               bc->line);
+    yasm_x86__bc_apply_prefixes((x86_common *)insn, &insn->rex, num_prefixes,
+                               prefixes, bc->line);
 
     if (insn->postop == X86_POSTOP_ADDRESS16 && insn->common.addrsize) {
        yasm__warning(YASM_WARN_GENERAL, bc->line,
@@ -3042,17 +3052,28 @@ yasm_x86__parse_check_prefix(yasm_arch *arch, unsigned long data[4],
     const char *oid = id;
     /*!re2c
        /* operand size overrides */
-       'o16'   {
+       'o16' | 'data16' | 'word'       {
+           if (oid[0] != 'o' && arch_x86->parser != X86_PARSER_GAS)
+               return 0;
            data[0] = X86_OPERSIZE;
            data[1] = 16;
            return 1;
        }
-       'o32'   {
+       'o32' | 'data32' | 'dword'      {
+           if (oid[0] != 'o' && arch_x86->parser != X86_PARSER_GAS)
+               return 0;
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line,
+                   N_("Cannot override data size to 32 bits in 64-bit mode"));
+               return 0;
+           }
            data[0] = X86_OPERSIZE;
            data[1] = 32;
            return 1;
        }
-       'o64'   {
+       'o64' | 'data64' | 'qword'      {
+           if (oid[0] != 'o' && arch_x86->parser != X86_PARSER_GAS)
+               return 0;
            if (arch_x86->mode_bits != 64) {
                yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a prefix in 64-bit mode"), oid);
@@ -3063,7 +3084,9 @@ yasm_x86__parse_check_prefix(yasm_arch *arch, unsigned long data[4],
            return 1;
        }
        /* address size overrides */
-       'a16'   {
+       'a16' | 'addr16' | 'aword'      {
+           if (oid[1] != '1' && arch_x86->parser != X86_PARSER_GAS)
+               return 0;
            if (arch_x86->mode_bits == 64) {
                yasm__error(line,
                    N_("Cannot override address size to 16 bits in 64-bit mode"));
@@ -3073,12 +3096,16 @@ yasm_x86__parse_check_prefix(yasm_arch *arch, unsigned long data[4],
            data[1] = 16;
            return 1;
        }
-       'a32'   {
+       'a32' | 'addr32' | 'adword'     {
+           if (oid[1] != '3' && arch_x86->parser != X86_PARSER_GAS)
+               return 0;
            data[0] = X86_ADDRSIZE;
            data[1] = 32;
            return 1;
        }
-       'a64'   {
+       'a64' | 'addr64' | 'aqword'     {
+           if (oid[1] != '6' && arch_x86->parser != X86_PARSER_GAS)
+               return 0;
            if (arch_x86->mode_bits != 64) {
                yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a prefix in 64-bit mode"), oid);
@@ -3106,6 +3133,152 @@ yasm_x86__parse_check_prefix(yasm_arch *arch, unsigned long data[4],
            return 1;
        }
 
+       /* other prefixes (limited to GAS-only at the moment) */
+       /* Hint taken/not taken (for jumps */
+       'ht'    {
+           if (arch_x86->parser != X86_PARSER_GAS)
+               return 0;
+           data[0] = X86_SEGREG;
+           data[1] = 0x3E;
+           return 1;
+       }
+       'hnt'   {
+           if (arch_x86->parser != X86_PARSER_GAS)
+               return 0;
+           data[0] = X86_SEGREG;
+           data[1] = 0x2E;
+           return 1;
+       }
+       /* REX byte explicit prefixes */
+       'rex'   {
+           if (arch_x86->parser != X86_PARSER_GAS
+               || arch_x86->mode_bits != 64)
+               return 0;
+           data[0] = X86_REX;
+           data[1] = 0x40;
+           return 1;
+       }
+       'rexz'  {
+           if (arch_x86->parser != X86_PARSER_GAS
+               || arch_x86->mode_bits != 64)
+               return 0;
+           data[0] = X86_REX;
+           data[1] = 0x41;
+           return 1;
+       }
+       'rexy'  {
+           if (arch_x86->parser != X86_PARSER_GAS
+               || arch_x86->mode_bits != 64)
+               return 0;
+           data[0] = X86_REX;
+           data[1] = 0x42;
+           return 1;
+       }
+       'rexyz' {
+           if (arch_x86->parser != X86_PARSER_GAS
+               || arch_x86->mode_bits != 64)
+               return 0;
+           data[0] = X86_REX;
+           data[1] = 0x43;
+           return 1;
+       }
+       'rexx'  {
+           if (arch_x86->parser != X86_PARSER_GAS
+               || arch_x86->mode_bits != 64)
+               return 0;
+           data[0] = X86_REX;
+           data[1] = 0x44;
+           return 1;
+       }
+       'rexxz' {
+           if (arch_x86->parser != X86_PARSER_GAS
+               || arch_x86->mode_bits != 64)
+               return 0;
+           data[0] = X86_REX;
+           data[1] = 0x45;
+           return 1;
+       }
+       'rexxy' {
+           if (arch_x86->parser != X86_PARSER_GAS
+               || arch_x86->mode_bits != 64)
+               return 0;
+           data[0] = X86_REX;
+           data[1] = 0x46;
+           return 1;
+       }
+       'rexxyz'    {
+           if (arch_x86->parser != X86_PARSER_GAS
+               || arch_x86->mode_bits != 64)
+               return 0;
+           data[0] = X86_REX;
+           data[1] = 0x47;
+           return 1;
+       }
+       'rex64' {
+           if (arch_x86->parser != X86_PARSER_GAS
+               || arch_x86->mode_bits != 64)
+               return 0;
+           data[0] = X86_REX;
+           data[1] = 0x48;
+           return 1;
+       }
+       'rex64z'    {
+           if (arch_x86->parser != X86_PARSER_GAS
+               || arch_x86->mode_bits != 64)
+               return 0;
+           data[0] = X86_REX;
+           data[1] = 0x49;
+           return 1;
+       }
+       'rex64y'    {
+           if (arch_x86->parser != X86_PARSER_GAS
+               || arch_x86->mode_bits != 64)
+               return 0;
+           data[0] = X86_REX;
+           data[1] = 0x4a;
+           return 1;
+       }
+       'rex64yz'   {
+           if (arch_x86->parser != X86_PARSER_GAS
+               || arch_x86->mode_bits != 64)
+               return 0;
+           data[0] = X86_REX;
+           data[1] = 0x4b;
+           return 1;
+       }
+       'rex64x'    {
+           if (arch_x86->parser != X86_PARSER_GAS
+               || arch_x86->mode_bits != 64)
+               return 0;
+           data[0] = X86_REX;
+           data[1] = 0x4c;
+           return 1;
+       }
+       'rex64xz'   {
+           if (arch_x86->parser != X86_PARSER_GAS
+               || arch_x86->mode_bits != 64)
+               return 0;
+           data[0] = X86_REX;
+           data[1] = 0x4d;
+           return 1;
+       }
+       'rex64xy'   {
+           if (arch_x86->parser != X86_PARSER_GAS
+               || arch_x86->mode_bits != 64)
+               return 0;
+           data[0] = X86_REX;
+           data[1] = 0x4e;
+           return 1;
+       }
+       'rex64xyz'  {
+           if (arch_x86->parser != X86_PARSER_GAS
+               || arch_x86->mode_bits != 64)
+               return 0;
+           data[0] = X86_REX;
+           data[1] = 0x4f;
+           return 1;
+       }
+
        /* catchalls */
        [\001-\377]+    {
            return 0;
index e81ae258138b894bbff66dd9d5df71ceff69a097..e29b21831bfe6db5c788cd0a255caaba3db7582d 100644 (file)
@@ -481,6 +481,18 @@ instr: INSN                {
        $$ = $2;
        yasm_bc_insn_add_prefix($$, $1);
     }
+    | SEGREG instr     {
+       $$ = $2;
+       yasm_bc_insn_add_seg_prefix($$, $1[0]);
+    }
+    | PREFIX {
+       $$ = yasm_bc_create_empty_insn(parser_gas->arch, cur_line);
+       yasm_bc_insn_add_prefix($$, $1);
+    }
+    | SEGREG {
+       $$ = yasm_bc_create_empty_insn(parser_gas->arch, cur_line);
+       yasm_bc_insn_add_seg_prefix($$, $1[0]);
+    }
     | ID {
        yasm__error(cur_line, N_("instruction not recognized: `%s'"), $1);
        $$ = NULL;