x86: Accept Intel64 only instruction by default

Message ID 20200207203450.3236-1-hjl.tools@gmail.com
State New
Headers show
Series
  • x86: Accept Intel64 only instruction by default
Related show

Commit Message

H.J. Lu Feb. 7, 2020, 8:34 p.m.
Commit d835a58baae720 disabled sysenter/sysenter in 64-bit mode by
default.  By default, assembler should accept Intel64 only and AMD64
ISAs since there are no conflicts.

gas/

	PR gas/25516
	* config/tc-i386.c (intel64): Renamed to ...
	(isa64): This.
	(match_template): Accept Intel64 only instruction by default.
	(i386_displacement): Updated.
	(md_parse_option): Updated.
	* c-i386.texi: Update -mamd64/-mintel64 documentation.
	* testsuite/gas/i386/i386.exp: Run x86-64-sysenter.  Pass
	-mamd64 to x86-64-sysenter-amd.
	* testsuite/gas/i386/x86-64-sysenter.d: New file.

opcodes/

	PR gas/25516
	* i386-gen.c (opcode_modifiers): Replace AMD64 and Intel64
	with ISA64.
	* i386-opc.h (AMD64): Removed.
	(Intel64): Likewose.
	(AMD64): New.
	(INTEL64): Likewise.
	(INTEL64ONLY): Likewise.
	(i386_opcode_modifier): Replace amd64 and intel64 with isa64.
	* i386-opc.tbl (Amd64): New.
	(Intel64): Likewise.
	(Intel64Only): Likewise.
	Replace AMD64 with Amd64.  Update sysenter/sysenter with
	Cpu64 and Intel64Only.  Remove AMD64 from sysenter/sysenter.
	* i386-tbl.h: Regenerated.
---
 gas/config/tc-i386.c                     |   40 +-
 gas/doc/c-i386.texi                      |    3 +-
 gas/testsuite/gas/i386/i386.exp          |    3 +-
 gas/testsuite/gas/i386/x86-64-sysenter.d |    5 +
 opcodes/i386-gen.c                       |    3 +-
 opcodes/i386-opc.h                       |   17 +-
 opcodes/i386-opc.tbl                     |   26 +-
 opcodes/i386-tbl.h                       | 7858 +++++++++++-----------
 8 files changed, 3995 insertions(+), 3960 deletions(-)
 create mode 100644 gas/testsuite/gas/i386/x86-64-sysenter.d

Comments

H.J. Lu Feb. 7, 2020, 10:52 p.m. | #1
On Fri, Feb 7, 2020 at 12:34 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>

> Commit d835a58baae720 disabled sysenter/sysenter in 64-bit mode by

> default.  By default, assembler should accept Intel64 only and AMD64

> ISAs since there are no conflicts.


It should read "By default, assembler should accept common, Intel64 only
and AMD64 ISAs since there are no conflicts."

> gas/

>

>         PR gas/25516

>         * config/tc-i386.c (intel64): Renamed to ...

>         (isa64): This.

>         (match_template): Accept Intel64 only instruction by default.

>         (i386_displacement): Updated.

>         (md_parse_option): Updated.

>         * c-i386.texi: Update -mamd64/-mintel64 documentation.

>         * testsuite/gas/i386/i386.exp: Run x86-64-sysenter.  Pass

>         -mamd64 to x86-64-sysenter-amd.

>         * testsuite/gas/i386/x86-64-sysenter.d: New file.

>

> opcodes/

>

>         PR gas/25516

>         * i386-gen.c (opcode_modifiers): Replace AMD64 and Intel64

>         with ISA64.

>         * i386-opc.h (AMD64): Removed.

>         (Intel64): Likewose.

>         (AMD64): New.

>         (INTEL64): Likewise.

>         (INTEL64ONLY): Likewise.

>         (i386_opcode_modifier): Replace amd64 and intel64 with isa64.

>         * i386-opc.tbl (Amd64): New.

>         (Intel64): Likewise.

>         (Intel64Only): Likewise.

>         Replace AMD64 with Amd64.  Update sysenter/sysenter with

>         Cpu64 and Intel64Only.  Remove AMD64 from sysenter/sysenter.

>         * i386-tbl.h: Regenerated.

> ---

>  gas/config/tc-i386.c                     |   40 +-

>  gas/doc/c-i386.texi                      |    3 +-

>  gas/testsuite/gas/i386/i386.exp          |    3 +-

>  gas/testsuite/gas/i386/x86-64-sysenter.d |    5 +

>  opcodes/i386-gen.c                       |    3 +-

>  opcodes/i386-opc.h                       |   17 +-

>  opcodes/i386-opc.tbl                     |   26 +-

>  opcodes/i386-tbl.h                       | 7858 +++++++++++-----------

>  8 files changed, 3995 insertions(+), 3960 deletions(-)

>  create mode 100644 gas/testsuite/gas/i386/x86-64-sysenter.d

>

> diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c

> index 945ceb28d69..413e7d346f9 100644

> --- a/gas/config/tc-i386.c

> +++ b/gas/config/tc-i386.c

> @@ -598,9 +598,11 @@ static int shared = 0;

>     0 if att syntax.  */

>  static int intel_syntax = 0;

>

> -/* 1 for Intel64 ISA,

> -   0 if AMD64 ISA.  */

> -static int intel64;

> +enum x86_64_isa

> +{

> +  amd64 = 1,   /* AMD64 ISA.  */

> +  intel64      /* Intel64 ISA.  */

> +} isa64;

>

>  /* 1 for intel mnemonic,

>     0 if att mnemonic.  */

> @@ -5805,14 +5807,32 @@ match_template (char mnem_suffix)

>        if (intel_mnemonic && t->opcode_modifier.attmnemonic)

>         continue;

>

> -      /* Check AT&T/Intel syntax and Intel64/AMD64 ISA.   */

> +      /* Check AT&T/Intel syntax.  */

>        i.error = unsupported_syntax;

>        if ((intel_syntax && t->opcode_modifier.attsyntax)

> -         || (!intel_syntax && t->opcode_modifier.intelsyntax)

> -         || (intel64 && t->opcode_modifier.amd64)

> -         || (!intel64 && t->opcode_modifier.intel64))

> +         || (!intel_syntax && t->opcode_modifier.intelsyntax))

>         continue;

>

> +      /* Check Intel64/AMD64 ISA.   */

> +      switch (isa64)

> +       {

> +       default:

> +         /* Default: Don't accept Intel64.  */

> +         if (t->opcode_modifier.isa64 == INTEL64)

> +           continue;

> +         break;

> +       case amd64:

> +         /* -mamd64: Don't accept Intel64 and Intel64 only.  */

> +         if (t->opcode_modifier.isa64 >= INTEL64)

> +           continue;

> +         break;

> +       case intel64:

> +         /* -mintel64: Don't accept AMD64.  */

> +         if (t->opcode_modifier.isa64 == AMD64)

> +           continue;

> +         break;

> +       }

> +

>        /* Check the suffix.  */

>        i.error = invalid_instruction_suffix;

>        if ((t->opcode_modifier.no_bsuf && suffix_check.no_bsuf)

> @@ -9963,7 +9983,7 @@ i386_displacement (char *disp_start, char *disp_end)

>           if (t->opcode_modifier.jump

>               != current_templates->start->opcode_modifier.jump)

>             break;

> -         if (t->opcode_modifier.intel64)

> +         if ((t->opcode_modifier.isa64 >= INTEL64))

>             has_intel64 = TRUE;

>         }

>        if (t < current_templates->end)

> @@ -12525,11 +12545,11 @@ md_parse_option (int c, const char *arg)

>        break;

>

>      case OPTION_MAMD64:

> -      intel64 = 0;

> +      isa64 = amd64;

>        break;

>

>      case OPTION_MINTEL64:

> -      intel64 = 1;

> +      isa64 = intel64;

>        break;

>

>      case 'O':

> diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi

> index 9fb681e8729..9ff0d995dd6 100644

> --- a/gas/doc/c-i386.texi

> +++ b/gas/doc/c-i386.texi

> @@ -488,7 +488,8 @@ with 01, 10 and 11 RC bits, respectively.

>  @item -mamd64

>  @itemx -mintel64

>  This option specifies that the assembler should accept only AMD64 or

> -Intel64 ISA in 64-bit mode.  The default is to accept both.

> +Intel64 ISA in 64-bit mode.  The default is to accept Intel64 only

> +and AMD64 ISAs.


Same here.  Common ISAs should be accepted by default.

>  @cindex @samp{-O0} option, i386

>  @cindex @samp{-O0} option, x86-64

> diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp

> index 59b14150c29..c4280417c58 100644

> --- a/gas/testsuite/gas/i386/i386.exp

> +++ b/gas/testsuite/gas/i386/i386.exp

> @@ -728,10 +728,11 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t

>      run_dump_test "x86-64-nops-5"

>      run_dump_test "x86-64-nops-5-k8"

>      run_dump_test "x86-64-nops-7"

> +    run_dump_test "x86-64-sysenter"

>      run_dump_test "x86-64-sysenter-intel"

>      run_dump_test "x86-64-sysenter-mixed"

>      run_dump_test "x86-64-sysenter-amd"

> -    run_list_test "x86-64-sysenter-amd"

> +    run_list_test "x86-64-sysenter-amd" "-mamd64"

>      run_dump_test "noreg64"

>      run_list_test "noreg64"

>      run_list_test "cvtsi2sX"

> diff --git a/gas/testsuite/gas/i386/x86-64-sysenter.d b/gas/testsuite/gas/i386/x86-64-sysenter.d

> new file mode 100644

> index 00000000000..65d21a0eb4b

> --- /dev/null

> +++ b/gas/testsuite/gas/i386/x86-64-sysenter.d

> @@ -0,0 +1,5 @@

> +#as:

> +#objdump: -dw

> +#name: x86-64 sysenter (Default)

> +#source: x86-64-sysenter-amd.s

> +#dump: x86-64-sysenter-intel.d

> diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c

> index 2784799486d..d7e29aabbe9 100644

> --- a/opcodes/i386-gen.c

> +++ b/opcodes/i386-gen.c

> @@ -666,8 +666,7 @@ static bitfield opcode_modifiers[] =

>    BITFIELD (ATTMnemonic),

>    BITFIELD (ATTSyntax),

>    BITFIELD (IntelSyntax),

> -  BITFIELD (AMD64),

> -  BITFIELD (Intel64),

> +  BITFIELD (ISA64),

>  };

>

>  #define CLASS(n) #n, n

> diff --git a/opcodes/i386-opc.h b/opcodes/i386-opc.h

> index cdc7cb23e8c..ce8f0bb93d2 100644

> --- a/opcodes/i386-opc.h

> +++ b/opcodes/i386-opc.h

> @@ -638,10 +638,16 @@ enum

>    ATTSyntax,

>    /* Intel syntax.  */

>    IntelSyntax,

> -  /* AMD64.  */

> -  AMD64,

> -  /* Intel64.  */

> -  Intel64,

> +  /* ISA64:

> +       0: Common to AMD64 and Intel64.

> +       1: AMD64.

> +       2: Intel64.

> +       3: Only in Intel64.

> +   */

> +#define AMD64          1

> +#define INTEL64                2

> +#define INTEL64ONLY    3

> +  ISA64,

>    /* The last bitfield in i386_opcode_modifier.  */

>    Opcode_Modifier_Num

>  };

> @@ -705,8 +711,7 @@ typedef struct i386_opcode_modifier

>    unsigned int attmnemonic:1;

>    unsigned int attsyntax:1;

>    unsigned int intelsyntax:1;

> -  unsigned int amd64:1;

> -  unsigned int intel64:1;

> +  unsigned int isa64:2;

>  } i386_opcode_modifier;

>

>  /* Operand classes.  */

> diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl

> index 1dff2dd289c..6841747990e 100644

> --- a/opcodes/i386-opc.tbl

> +++ b/opcodes/i386-opc.tbl

> @@ -82,6 +82,10 @@

>  #define EVexLIG EVex=EVEXLIG

>  #define EVexDYN EVex=EVEXDYN

>

> +#define Amd64          ISA64=AMD64

> +#define Intel64                ISA64=INTEL64

> +#define Intel64Only    ISA64=INTEL64ONLY

> +

>  // The EVEX purpose of StaticRounding appears only together with SAE. Re-use

>  // the bit to mark commutative VEX encodings where swapping the source

>  // operands may allow to switch from 3-byte to 2-byte VEX encoding.

> @@ -136,7 +140,7 @@ movsx, 2, 0xfbe, None, 2, Cpu386, Modrm|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf

>  movsx, 2, 0xfbf, None, 2, Cpu386, Modrm|No_bSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IntelSyntax, { Reg16|Word|BaseIndex, Reg32|Reg64 }

>  movsx, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_ldSuf|Rex64|IntelSyntax, { Reg32|Dword|BaseIndex, Reg64 }

>  movsxd, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32|Unspecified|BaseIndex, Reg32|Reg64 }

> -movsxd, 2, 0x63, None, 1, Cpu64, AMD64|Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32|Unspecified|BaseIndex, Reg16 }

> +movsxd, 2, 0x63, None, 1, Cpu64, Amd64|Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32|Unspecified|BaseIndex, Reg16 }

>  movsxd, 2, 0x63, None, 1, Cpu64, Intel64|Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg16|Unspecified|BaseIndex, Reg16 }

>

>  // Move with zero extend.

> @@ -373,10 +377,10 @@ shrd, 2, 0xfad, None, 2, Cpu386, Modrm|CheckRegSize|No_bSuf|No_sSuf|No_ldSuf, {

>

>  // Control transfer instructions.

>  call, 1, 0xe8, None, 1, CpuNo64, JumpDword|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp16|Disp32 }

> -call, 1, 0xe8, None, 1, Cpu64, AMD64|JumpDword|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Disp16|Disp32S }

> +call, 1, 0xe8, None, 1, Cpu64, Amd64|JumpDword|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Disp16|Disp32S }

>  call, 1, 0xe8, None, 1, Cpu64, Intel64|JumpDword|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Disp32S }

>  call, 1, 0xff, 0x2, 1, CpuNo64, Modrm|JumpAbsolute|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg32|Unspecified|BaseIndex }

> -call, 1, 0xff, 0x2, 1, Cpu64, AMD64|Modrm|JumpAbsolute|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg64|Unspecified|BaseIndex }

> +call, 1, 0xff, 0x2, 1, Cpu64, Amd64|Modrm|JumpAbsolute|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg64|Unspecified|BaseIndex }

>  call, 1, 0xff, 0x2, 1, Cpu64, Intel64|Modrm|JumpAbsolute|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg64|Unspecified|BaseIndex }

>  // Intel Syntax

>  call, 2, 0x9a, None, 1, CpuNo64, JumpInterSegment|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm16, Imm16|Imm32 }

> @@ -386,10 +390,10 @@ lcall, 2, 0x9a, None, 1, CpuNo64, JumpInterSegment|DefaultSize|No_bSuf|No_sSuf|N

>  lcall, 1, 0xff, 0x3, 1, 0, Modrm|JumpAbsolute|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Unspecified|BaseIndex }

>

>  jmp, 1, 0xeb, None, 1, CpuNo64, Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp16|Disp32 }

> -jmp, 1, 0xeb, None, 1, Cpu64, AMD64|Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp16|Disp32S }

> +jmp, 1, 0xeb, None, 1, Cpu64, Amd64|Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp16|Disp32S }

>  jmp, 1, 0xeb, None, 1, Cpu64, Intel64|Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp32S }

>  jmp, 1, 0xff, 0x4, 1, CpuNo64, Modrm|JumpAbsolute|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg32|Unspecified|BaseIndex }

> -jmp, 1, 0xff, 0x4, 1, Cpu64, AMD64|Modrm|JumpAbsolute|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg64|Unspecified|BaseIndex }

> +jmp, 1, 0xff, 0x4, 1, Cpu64, Amd64|Modrm|JumpAbsolute|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg64|Unspecified|BaseIndex }

>  jmp, 1, 0xff, 0x4, 1, Cpu64, Intel64|Modrm|JumpAbsolute|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg64|Unspecified|BaseIndex }

>  // Intel Syntax.

>  jmp, 2, 0xea, None, 1, CpuNo64, JumpInterSegment|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm16, Imm16|Imm32 }

> @@ -400,8 +404,8 @@ ljmp, 1, 0xff, 0x5, 1, 0, Modrm|JumpAbsolute|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, {

>

>  ret, 0, 0xc3, None, 1, CpuNo64, DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|RepPrefixOk|BNDPrefixOk, { 0 }

>  ret, 1, 0xc2, None, 1, CpuNo64, DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|RepPrefixOk|BNDPrefixOk, { Imm16 }

> -ret, 0, 0xc3, None, 1, Cpu64, AMD64|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { 0 }

> -ret, 1, 0xc2, None, 1, Cpu64, AMD64|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { Imm16 }

> +ret, 0, 0xc3, None, 1, Cpu64, Amd64|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { 0 }

> +ret, 1, 0xc2, None, 1, Cpu64, Amd64|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { Imm16 }

>  ret, 0, 0xc3, None, 1, Cpu64, Intel64|Size64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { 0 }

>  ret, 1, 0xc2, None, 1, Cpu64, Intel64|Size64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { Imm16 }

>  lret, 0, 0xcb, None, 1, 0, DefaultSize|No_bSuf|No_sSuf|No_ldSuf, { 0 }

> @@ -909,10 +913,10 @@ rdmsr, 0, 0xf32, None, 2, Cpu586, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldS

>  cmpxchg8b, 1, 0xfc7, 0x1, 2, Cpu586, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|IsLockable|NoRex64|HLEPrefixOk, { Qword|Unspecified|BaseIndex }

>

>  // Pentium II/Pentium Pro extensions.

> -sysenter, 0, 0xf34, None, 2, Cpu686, Intel64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }

> -sysenter, 0, 0xf34, None, 2, Cpu686|CpuNo64, AMD64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }

> -sysexit, 0, 0xf35, None, 2, Cpu686, Intel64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }

> -sysexit, 0, 0xf35, None, 2, Cpu686|CpuNo64, AMD64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }

> +sysenter, 0, 0xf34, None, 2, Cpu64, Intel64Only|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }

> +sysenter, 0, 0xf34, None, 2, Cpu686|CpuNo64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }

> +sysexit, 0, 0xf35, None, 2, Cpu64, Intel64Only|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }

> +sysexit, 0, 0xf35, None, 2, Cpu686|CpuNo64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }

>  fxsave, 1, 0xfae, 0x0, 2, CpuFXSR, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf, { Unspecified|BaseIndex }

>  fxsave64, 1, 0xfae, 0x0, 2, CpuFXSR|Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|Rex64, { Unspecified|BaseIndex }

>  fxrstor, 1, 0xfae, 0x1, 2, CpuFXSR, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf, { Unspecified|BaseIndex }




-- 
H.J.
Jan Beulich Feb. 10, 2020, 9:03 a.m. | #2
On 07.02.2020 21:34, H.J. Lu wrote:
> --- a/opcodes/i386-opc.h

> +++ b/opcodes/i386-opc.h

> @@ -638,10 +638,16 @@ enum

>    ATTSyntax,

>    /* Intel syntax.  */

>    IntelSyntax,

> -  /* AMD64.  */

> -  AMD64,

> -  /* Intel64.  */

> -  Intel64,

> +  /* ISA64:

> +	0: Common to AMD64 and Intel64.

> +	1: AMD64.

> +	2: Intel64.

> +	3: Only in Intel64.

> +   */

> +#define AMD64		1

> +#define INTEL64		2

> +#define INTEL64ONLY	3

> +  ISA64,


I think the comment should warn that the order here cannot be
changed without other code adjustments.

> --- a/opcodes/i386-opc.tbl

> +++ b/opcodes/i386-opc.tbl

> @@ -82,6 +82,10 @@

>  #define EVexLIG EVex=EVEXLIG

>  #define EVexDYN EVex=EVEXDYN

>  

> +#define Amd64		ISA64=AMD64

> +#define Intel64		ISA64=INTEL64

> +#define Intel64Only	ISA64=INTEL64ONLY

> +

>  // The EVEX purpose of StaticRounding appears only together with SAE. Re-use

>  // the bit to mark commutative VEX encodings where swapping the source

>  // operands may allow to switch from 3-byte to 2-byte VEX encoding.


Would you mind moving the addition up, at least ahead of all the VEX-/
EVEX-related #define-s?

Thanks, Jan
H.J. Lu Feb. 10, 2020, 4:35 p.m. | #3
On Mon, Feb 10, 2020 at 1:03 AM Jan Beulich <jbeulich@suse.com> wrote:
>

> On 07.02.2020 21:34, H.J. Lu wrote:

> > --- a/opcodes/i386-opc.h

> > +++ b/opcodes/i386-opc.h

> > @@ -638,10 +638,16 @@ enum

> >    ATTSyntax,

> >    /* Intel syntax.  */

> >    IntelSyntax,

> > -  /* AMD64.  */

> > -  AMD64,

> > -  /* Intel64.  */

> > -  Intel64,

> > +  /* ISA64:

> > +     0: Common to AMD64 and Intel64.

> > +     1: AMD64.

> > +     2: Intel64.

> > +     3: Only in Intel64.

> > +   */

> > +#define AMD64                1

> > +#define INTEL64              2

> > +#define INTEL64ONLY  3

> > +  ISA64,

>

> I think the comment should warn that the order here cannot be

> changed without other code adjustments.


Done.

> > --- a/opcodes/i386-opc.tbl

> > +++ b/opcodes/i386-opc.tbl

> > @@ -82,6 +82,10 @@

> >  #define EVexLIG EVex=EVEXLIG

> >  #define EVexDYN EVex=EVEXDYN

> >

> > +#define Amd64                ISA64=AMD64

> > +#define Intel64              ISA64=INTEL64

> > +#define Intel64Only  ISA64=INTEL64ONLY

> > +

> >  // The EVEX purpose of StaticRounding appears only together with SAE. Re-use

> >  // the bit to mark commutative VEX encodings where swapping the source

> >  // operands may allow to switch from 3-byte to 2-byte VEX encoding.

>

> Would you mind moving the addition up, at least ahead of all the VEX-/

> EVEX-related #define-s?

>


Done.

This is what I am checking into master.  I will backport it to
binutils 2.34 branch.

Thanks.

-- 
H.J.
From f19a073a9be42c34a54592e27193bb9cc65b2043 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Fri, 7 Feb 2020 05:58:29 -0800
Subject: [PATCH] x86: Accept Intel64 only instruction by default

Commit d835a58baae720 disabled sysenter/sysenter in 64-bit mode by
default.  By default, assembler should accept common, Intel64 only
and AMD64 ISAs since there are no conflicts.

gas/

	PR gas/25516
	* config/tc-i386.c (intel64): Renamed to ...
	(isa64): This.
	(match_template): Accept Intel64 only instruction by default.
	(i386_displacement): Updated.
	(md_parse_option): Updated.
	* c-i386.texi: Update -mamd64/-mintel64 documentation.
	* testsuite/gas/i386/i386.exp: Run x86-64-sysenter.  Pass
	-mamd64 to x86-64-sysenter-amd.
	* testsuite/gas/i386/x86-64-sysenter.d: New file.

opcodes/

	PR gas/25516
	* i386-gen.c (opcode_modifiers): Replace AMD64 and Intel64
	with ISA64.
	* i386-opc.h (AMD64): Removed.
	(Intel64): Likewose.
	(AMD64): New.
	(INTEL64): Likewise.
	(INTEL64ONLY): Likewise.
	(i386_opcode_modifier): Replace amd64 and intel64 with isa64.
	* i386-opc.tbl (Amd64): New.
	(Intel64): Likewise.
	(Intel64Only): Likewise.
	Replace AMD64 with Amd64.  Update sysenter/sysenter with
	Cpu64 and Intel64Only.  Remove AMD64 from sysenter/sysenter.
	* i386-tbl.h: Regenerated.
---
 gas/config/tc-i386.c                     |   40 +-
 gas/doc/c-i386.texi                      |    3 +-
 gas/testsuite/gas/i386/i386.exp          |    3 +-
 gas/testsuite/gas/i386/x86-64-sysenter.d |    5 +
 opcodes/i386-gen.c                       |    3 +-
 opcodes/i386-opc.h                       |   17 +-
 opcodes/i386-opc.tbl                     |   26 +-
 opcodes/i386-tbl.h                       | 7858 +++++++++++-----------
 8 files changed, 3995 insertions(+), 3960 deletions(-)
 create mode 100644 gas/testsuite/gas/i386/x86-64-sysenter.d

diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 945ceb28d6..543fe25b4d 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -598,9 +598,11 @@ static int shared = 0;
    0 if att syntax.  */
 static int intel_syntax = 0;
 
-/* 1 for Intel64 ISA,
-   0 if AMD64 ISA.  */
-static int intel64;
+static enum x86_64_isa
+{
+  amd64 = 1,	/* AMD64 ISA.  */
+  intel64	/* Intel64 ISA.  */
+} isa64;
 
 /* 1 for intel mnemonic,
    0 if att mnemonic.  */
@@ -5805,14 +5807,32 @@ match_template (char mnem_suffix)
       if (intel_mnemonic && t->opcode_modifier.attmnemonic)
 	continue;
 
-      /* Check AT&T/Intel syntax and Intel64/AMD64 ISA.   */
+      /* Check AT&T/Intel syntax.  */
       i.error = unsupported_syntax;
       if ((intel_syntax && t->opcode_modifier.attsyntax)
-	  || (!intel_syntax && t->opcode_modifier.intelsyntax)
-	  || (intel64 && t->opcode_modifier.amd64)
-	  || (!intel64 && t->opcode_modifier.intel64))
+	  || (!intel_syntax && t->opcode_modifier.intelsyntax))
 	continue;
 
+      /* Check Intel64/AMD64 ISA.   */
+      switch (isa64)
+	{
+	default:
+	  /* Default: Don't accept Intel64.  */
+	  if (t->opcode_modifier.isa64 == INTEL64)
+	    continue;
+	  break;
+	case amd64:
+	  /* -mamd64: Don't accept Intel64 and Intel64 only.  */
+	  if (t->opcode_modifier.isa64 >= INTEL64)
+	    continue;
+	  break;
+	case intel64:
+	  /* -mintel64: Don't accept AMD64.  */
+	  if (t->opcode_modifier.isa64 == AMD64)
+	    continue;
+	  break;
+	}
+
       /* Check the suffix.  */
       i.error = invalid_instruction_suffix;
       if ((t->opcode_modifier.no_bsuf && suffix_check.no_bsuf)
@@ -9963,7 +9983,7 @@ i386_displacement (char *disp_start, char *disp_end)
 	  if (t->opcode_modifier.jump
 	      != current_templates->start->opcode_modifier.jump)
 	    break;
-	  if (t->opcode_modifier.intel64)
+	  if ((t->opcode_modifier.isa64 >= INTEL64))
 	    has_intel64 = TRUE;
 	}
       if (t < current_templates->end)
@@ -12525,11 +12545,11 @@ md_parse_option (int c, const char *arg)
       break;
 
     case OPTION_MAMD64:
-      intel64 = 0;
+      isa64 = amd64;
       break;
 
     case OPTION_MINTEL64:
-      intel64 = 1;
+      isa64 = intel64;
       break;
 
     case 'O':
diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi
index 9fb681e872..f0189ccb44 100644
--- a/gas/doc/c-i386.texi
+++ b/gas/doc/c-i386.texi
@@ -488,7 +488,8 @@ with 01, 10 and 11 RC bits, respectively.
 @item -mamd64
 @itemx -mintel64
 This option specifies that the assembler should accept only AMD64 or
-Intel64 ISA in 64-bit mode.  The default is to accept both.
+Intel64 ISA in 64-bit mode.  The default is to accept common, Intel64
+only and AMD64 ISAs.
 
 @cindex @samp{-O0} option, i386
 @cindex @samp{-O0} option, x86-64
diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
index 59b14150c2..c4280417c5 100644
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -728,10 +728,11 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t
     run_dump_test "x86-64-nops-5"
     run_dump_test "x86-64-nops-5-k8"
     run_dump_test "x86-64-nops-7"
+    run_dump_test "x86-64-sysenter"
     run_dump_test "x86-64-sysenter-intel"
     run_dump_test "x86-64-sysenter-mixed"
     run_dump_test "x86-64-sysenter-amd"
-    run_list_test "x86-64-sysenter-amd"
+    run_list_test "x86-64-sysenter-amd" "-mamd64"
     run_dump_test "noreg64"
     run_list_test "noreg64"
     run_list_test "cvtsi2sX"
diff --git a/gas/testsuite/gas/i386/x86-64-sysenter.d b/gas/testsuite/gas/i386/x86-64-sysenter.d
new file mode 100644
index 0000000000..65d21a0eb4
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-sysenter.d
@@ -0,0 +1,5 @@
+#as:
+#objdump: -dw
+#name: x86-64 sysenter (Default)
+#source: x86-64-sysenter-amd.s
+#dump: x86-64-sysenter-intel.d
diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c
index 2784799486..d7e29aabbe 100644
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -666,8 +666,7 @@ static bitfield opcode_modifiers[] =
   BITFIELD (ATTMnemonic),
   BITFIELD (ATTSyntax),
   BITFIELD (IntelSyntax),
-  BITFIELD (AMD64),
-  BITFIELD (Intel64),
+  BITFIELD (ISA64),
 };
 
 #define CLASS(n) #n, n
diff --git a/opcodes/i386-opc.h b/opcodes/i386-opc.h
index cdc7cb23e8..ecd441e99c 100644
--- a/opcodes/i386-opc.h
+++ b/opcodes/i386-opc.h
@@ -638,10 +638,16 @@ enum
   ATTSyntax,
   /* Intel syntax.  */
   IntelSyntax,
-  /* AMD64.  */
-  AMD64,
-  /* Intel64.  */
-  Intel64,
+  /* ISA64: Don't change the order without other code adjustments.
+	0: Common to AMD64 and Intel64.
+	1: AMD64.
+	2: Intel64.
+	3: Only in Intel64.
+   */
+#define AMD64		1
+#define INTEL64		2
+#define INTEL64ONLY	3
+  ISA64,
   /* The last bitfield in i386_opcode_modifier.  */
   Opcode_Modifier_Num
 };
@@ -705,8 +711,7 @@ typedef struct i386_opcode_modifier
   unsigned int attmnemonic:1;
   unsigned int attsyntax:1;
   unsigned int intelsyntax:1;
-  unsigned int amd64:1;
-  unsigned int intel64:1;
+  unsigned int isa64:2;
 } i386_opcode_modifier;
 
 /* Operand classes.  */
diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl
index 1dff2dd289..6531ef262c 100644
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -22,6 +22,10 @@
 #include "i386-opc.h"
 #undef None
 
+#define Amd64		ISA64=AMD64
+#define Intel64		ISA64=INTEL64
+#define Intel64Only	ISA64=INTEL64ONLY
+
 #define Reg8  Class=Reg|Byte
 #define Reg16 Class=Reg|Word
 #define Reg32 Class=Reg|Dword
@@ -136,7 +140,7 @@ movsx, 2, 0xfbe, None, 2, Cpu386, Modrm|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf
 movsx, 2, 0xfbf, None, 2, Cpu386, Modrm|No_bSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IntelSyntax, { Reg16|Word|BaseIndex, Reg32|Reg64 }
 movsx, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_ldSuf|Rex64|IntelSyntax, { Reg32|Dword|BaseIndex, Reg64 }
 movsxd, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32|Unspecified|BaseIndex, Reg32|Reg64 }
-movsxd, 2, 0x63, None, 1, Cpu64, AMD64|Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32|Unspecified|BaseIndex, Reg16 }
+movsxd, 2, 0x63, None, 1, Cpu64, Amd64|Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32|Unspecified|BaseIndex, Reg16 }
 movsxd, 2, 0x63, None, 1, Cpu64, Intel64|Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg16|Unspecified|BaseIndex, Reg16 }
 
 // Move with zero extend.
@@ -373,10 +377,10 @@ shrd, 2, 0xfad, None, 2, Cpu386, Modrm|CheckRegSize|No_bSuf|No_sSuf|No_ldSuf, {
 
 // Control transfer instructions.
 call, 1, 0xe8, None, 1, CpuNo64, JumpDword|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp16|Disp32 }
-call, 1, 0xe8, None, 1, Cpu64, AMD64|JumpDword|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Disp16|Disp32S }
+call, 1, 0xe8, None, 1, Cpu64, Amd64|JumpDword|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Disp16|Disp32S }
 call, 1, 0xe8, None, 1, Cpu64, Intel64|JumpDword|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Disp32S }
 call, 1, 0xff, 0x2, 1, CpuNo64, Modrm|JumpAbsolute|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg32|Unspecified|BaseIndex }
-call, 1, 0xff, 0x2, 1, Cpu64, AMD64|Modrm|JumpAbsolute|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg64|Unspecified|BaseIndex }
+call, 1, 0xff, 0x2, 1, Cpu64, Amd64|Modrm|JumpAbsolute|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg64|Unspecified|BaseIndex }
 call, 1, 0xff, 0x2, 1, Cpu64, Intel64|Modrm|JumpAbsolute|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg64|Unspecified|BaseIndex }
 // Intel Syntax
 call, 2, 0x9a, None, 1, CpuNo64, JumpInterSegment|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm16, Imm16|Imm32 }
@@ -386,10 +390,10 @@ lcall, 2, 0x9a, None, 1, CpuNo64, JumpInterSegment|DefaultSize|No_bSuf|No_sSuf|N
 lcall, 1, 0xff, 0x3, 1, 0, Modrm|JumpAbsolute|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Unspecified|BaseIndex }
 
 jmp, 1, 0xeb, None, 1, CpuNo64, Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp16|Disp32 }
-jmp, 1, 0xeb, None, 1, Cpu64, AMD64|Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp16|Disp32S }
+jmp, 1, 0xeb, None, 1, Cpu64, Amd64|Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp16|Disp32S }
 jmp, 1, 0xeb, None, 1, Cpu64, Intel64|Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp32S }
 jmp, 1, 0xff, 0x4, 1, CpuNo64, Modrm|JumpAbsolute|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg32|Unspecified|BaseIndex }
-jmp, 1, 0xff, 0x4, 1, Cpu64, AMD64|Modrm|JumpAbsolute|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg64|Unspecified|BaseIndex }
+jmp, 1, 0xff, 0x4, 1, Cpu64, Amd64|Modrm|JumpAbsolute|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg64|Unspecified|BaseIndex }
 jmp, 1, 0xff, 0x4, 1, Cpu64, Intel64|Modrm|JumpAbsolute|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg64|Unspecified|BaseIndex }
 // Intel Syntax.
 jmp, 2, 0xea, None, 1, CpuNo64, JumpInterSegment|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm16, Imm16|Imm32 }
@@ -400,8 +404,8 @@ ljmp, 1, 0xff, 0x5, 1, 0, Modrm|JumpAbsolute|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, {
 
 ret, 0, 0xc3, None, 1, CpuNo64, DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|RepPrefixOk|BNDPrefixOk, { 0 }
 ret, 1, 0xc2, None, 1, CpuNo64, DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|RepPrefixOk|BNDPrefixOk, { Imm16 }
-ret, 0, 0xc3, None, 1, Cpu64, AMD64|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { 0 }
-ret, 1, 0xc2, None, 1, Cpu64, AMD64|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { Imm16 }
+ret, 0, 0xc3, None, 1, Cpu64, Amd64|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { 0 }
+ret, 1, 0xc2, None, 1, Cpu64, Amd64|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { Imm16 }
 ret, 0, 0xc3, None, 1, Cpu64, Intel64|Size64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { 0 }
 ret, 1, 0xc2, None, 1, Cpu64, Intel64|Size64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { Imm16 }
 lret, 0, 0xcb, None, 1, 0, DefaultSize|No_bSuf|No_sSuf|No_ldSuf, { 0 }
@@ -909,10 +913,10 @@ rdmsr, 0, 0xf32, None, 2, Cpu586, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldS
 cmpxchg8b, 1, 0xfc7, 0x1, 2, Cpu586, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|IsLockable|NoRex64|HLEPrefixOk, { Qword|Unspecified|BaseIndex }
 
 // Pentium II/Pentium Pro extensions.
-sysenter, 0, 0xf34, None, 2, Cpu686, Intel64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
-sysenter, 0, 0xf34, None, 2, Cpu686|CpuNo64, AMD64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
-sysexit, 0, 0xf35, None, 2, Cpu686, Intel64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
-sysexit, 0, 0xf35, None, 2, Cpu686|CpuNo64, AMD64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
+sysenter, 0, 0xf34, None, 2, Cpu64, Intel64Only|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
+sysenter, 0, 0xf34, None, 2, Cpu686|CpuNo64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
+sysexit, 0, 0xf35, None, 2, Cpu64, Intel64Only|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
+sysexit, 0, 0xf35, None, 2, Cpu686|CpuNo64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
 fxsave, 1, 0xfae, 0x0, 2, CpuFXSR, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf, { Unspecified|BaseIndex }
 fxsave64, 1, 0xfae, 0x0, 2, CpuFXSR|Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|Rex64, { Unspecified|BaseIndex }
 fxrstor, 1, 0xfae, 0x1, 2, CpuFXSR, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf, { Unspecified|BaseIndex }

Patch

diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 945ceb28d69..413e7d346f9 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -598,9 +598,11 @@  static int shared = 0;
    0 if att syntax.  */
 static int intel_syntax = 0;
 
-/* 1 for Intel64 ISA,
-   0 if AMD64 ISA.  */
-static int intel64;
+enum x86_64_isa
+{
+  amd64 = 1,	/* AMD64 ISA.  */
+  intel64	/* Intel64 ISA.  */
+} isa64;
 
 /* 1 for intel mnemonic,
    0 if att mnemonic.  */
@@ -5805,14 +5807,32 @@  match_template (char mnem_suffix)
       if (intel_mnemonic && t->opcode_modifier.attmnemonic)
 	continue;
 
-      /* Check AT&T/Intel syntax and Intel64/AMD64 ISA.   */
+      /* Check AT&T/Intel syntax.  */
       i.error = unsupported_syntax;
       if ((intel_syntax && t->opcode_modifier.attsyntax)
-	  || (!intel_syntax && t->opcode_modifier.intelsyntax)
-	  || (intel64 && t->opcode_modifier.amd64)
-	  || (!intel64 && t->opcode_modifier.intel64))
+	  || (!intel_syntax && t->opcode_modifier.intelsyntax))
 	continue;
 
+      /* Check Intel64/AMD64 ISA.   */
+      switch (isa64)
+	{
+	default:
+	  /* Default: Don't accept Intel64.  */
+	  if (t->opcode_modifier.isa64 == INTEL64)
+	    continue;
+	  break;
+	case amd64:
+	  /* -mamd64: Don't accept Intel64 and Intel64 only.  */
+	  if (t->opcode_modifier.isa64 >= INTEL64)
+	    continue;
+	  break;
+	case intel64:
+	  /* -mintel64: Don't accept AMD64.  */
+	  if (t->opcode_modifier.isa64 == AMD64)
+	    continue;
+	  break;
+	}
+
       /* Check the suffix.  */
       i.error = invalid_instruction_suffix;
       if ((t->opcode_modifier.no_bsuf && suffix_check.no_bsuf)
@@ -9963,7 +9983,7 @@  i386_displacement (char *disp_start, char *disp_end)
 	  if (t->opcode_modifier.jump
 	      != current_templates->start->opcode_modifier.jump)
 	    break;
-	  if (t->opcode_modifier.intel64)
+	  if ((t->opcode_modifier.isa64 >= INTEL64))
 	    has_intel64 = TRUE;
 	}
       if (t < current_templates->end)
@@ -12525,11 +12545,11 @@  md_parse_option (int c, const char *arg)
       break;
 
     case OPTION_MAMD64:
-      intel64 = 0;
+      isa64 = amd64;
       break;
 
     case OPTION_MINTEL64:
-      intel64 = 1;
+      isa64 = intel64;
       break;
 
     case 'O':
diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi
index 9fb681e8729..9ff0d995dd6 100644
--- a/gas/doc/c-i386.texi
+++ b/gas/doc/c-i386.texi
@@ -488,7 +488,8 @@  with 01, 10 and 11 RC bits, respectively.
 @item -mamd64
 @itemx -mintel64
 This option specifies that the assembler should accept only AMD64 or
-Intel64 ISA in 64-bit mode.  The default is to accept both.
+Intel64 ISA in 64-bit mode.  The default is to accept Intel64 only
+and AMD64 ISAs.
 
 @cindex @samp{-O0} option, i386
 @cindex @samp{-O0} option, x86-64
diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
index 59b14150c29..c4280417c58 100644
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -728,10 +728,11 @@  if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t
     run_dump_test "x86-64-nops-5"
     run_dump_test "x86-64-nops-5-k8"
     run_dump_test "x86-64-nops-7"
+    run_dump_test "x86-64-sysenter"
     run_dump_test "x86-64-sysenter-intel"
     run_dump_test "x86-64-sysenter-mixed"
     run_dump_test "x86-64-sysenter-amd"
-    run_list_test "x86-64-sysenter-amd"
+    run_list_test "x86-64-sysenter-amd" "-mamd64"
     run_dump_test "noreg64"
     run_list_test "noreg64"
     run_list_test "cvtsi2sX"
diff --git a/gas/testsuite/gas/i386/x86-64-sysenter.d b/gas/testsuite/gas/i386/x86-64-sysenter.d
new file mode 100644
index 00000000000..65d21a0eb4b
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-sysenter.d
@@ -0,0 +1,5 @@ 
+#as:
+#objdump: -dw
+#name: x86-64 sysenter (Default)
+#source: x86-64-sysenter-amd.s
+#dump: x86-64-sysenter-intel.d
diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c
index 2784799486d..d7e29aabbe9 100644
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -666,8 +666,7 @@  static bitfield opcode_modifiers[] =
   BITFIELD (ATTMnemonic),
   BITFIELD (ATTSyntax),
   BITFIELD (IntelSyntax),
-  BITFIELD (AMD64),
-  BITFIELD (Intel64),
+  BITFIELD (ISA64),
 };
 
 #define CLASS(n) #n, n
diff --git a/opcodes/i386-opc.h b/opcodes/i386-opc.h
index cdc7cb23e8c..ce8f0bb93d2 100644
--- a/opcodes/i386-opc.h
+++ b/opcodes/i386-opc.h
@@ -638,10 +638,16 @@  enum
   ATTSyntax,
   /* Intel syntax.  */
   IntelSyntax,
-  /* AMD64.  */
-  AMD64,
-  /* Intel64.  */
-  Intel64,
+  /* ISA64:
+	0: Common to AMD64 and Intel64.
+	1: AMD64.
+	2: Intel64.
+	3: Only in Intel64.
+   */
+#define AMD64		1
+#define INTEL64		2
+#define INTEL64ONLY	3
+  ISA64,
   /* The last bitfield in i386_opcode_modifier.  */
   Opcode_Modifier_Num
 };
@@ -705,8 +711,7 @@  typedef struct i386_opcode_modifier
   unsigned int attmnemonic:1;
   unsigned int attsyntax:1;
   unsigned int intelsyntax:1;
-  unsigned int amd64:1;
-  unsigned int intel64:1;
+  unsigned int isa64:2;
 } i386_opcode_modifier;
 
 /* Operand classes.  */
diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl
index 1dff2dd289c..6841747990e 100644
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -82,6 +82,10 @@ 
 #define EVexLIG EVex=EVEXLIG
 #define EVexDYN EVex=EVEXDYN
 
+#define Amd64		ISA64=AMD64
+#define Intel64		ISA64=INTEL64
+#define Intel64Only	ISA64=INTEL64ONLY
+
 // The EVEX purpose of StaticRounding appears only together with SAE. Re-use
 // the bit to mark commutative VEX encodings where swapping the source
 // operands may allow to switch from 3-byte to 2-byte VEX encoding.
@@ -136,7 +140,7 @@  movsx, 2, 0xfbe, None, 2, Cpu386, Modrm|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf
 movsx, 2, 0xfbf, None, 2, Cpu386, Modrm|No_bSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IntelSyntax, { Reg16|Word|BaseIndex, Reg32|Reg64 }
 movsx, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_ldSuf|Rex64|IntelSyntax, { Reg32|Dword|BaseIndex, Reg64 }
 movsxd, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32|Unspecified|BaseIndex, Reg32|Reg64 }
-movsxd, 2, 0x63, None, 1, Cpu64, AMD64|Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32|Unspecified|BaseIndex, Reg16 }
+movsxd, 2, 0x63, None, 1, Cpu64, Amd64|Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32|Unspecified|BaseIndex, Reg16 }
 movsxd, 2, 0x63, None, 1, Cpu64, Intel64|Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg16|Unspecified|BaseIndex, Reg16 }
 
 // Move with zero extend.
@@ -373,10 +377,10 @@  shrd, 2, 0xfad, None, 2, Cpu386, Modrm|CheckRegSize|No_bSuf|No_sSuf|No_ldSuf, {
 
 // Control transfer instructions.
 call, 1, 0xe8, None, 1, CpuNo64, JumpDword|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp16|Disp32 }
-call, 1, 0xe8, None, 1, Cpu64, AMD64|JumpDword|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Disp16|Disp32S }
+call, 1, 0xe8, None, 1, Cpu64, Amd64|JumpDword|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Disp16|Disp32S }
 call, 1, 0xe8, None, 1, Cpu64, Intel64|JumpDword|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Disp32S }
 call, 1, 0xff, 0x2, 1, CpuNo64, Modrm|JumpAbsolute|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg32|Unspecified|BaseIndex }
-call, 1, 0xff, 0x2, 1, Cpu64, AMD64|Modrm|JumpAbsolute|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg64|Unspecified|BaseIndex }
+call, 1, 0xff, 0x2, 1, Cpu64, Amd64|Modrm|JumpAbsolute|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg64|Unspecified|BaseIndex }
 call, 1, 0xff, 0x2, 1, Cpu64, Intel64|Modrm|JumpAbsolute|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg64|Unspecified|BaseIndex }
 // Intel Syntax
 call, 2, 0x9a, None, 1, CpuNo64, JumpInterSegment|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm16, Imm16|Imm32 }
@@ -386,10 +390,10 @@  lcall, 2, 0x9a, None, 1, CpuNo64, JumpInterSegment|DefaultSize|No_bSuf|No_sSuf|N
 lcall, 1, 0xff, 0x3, 1, 0, Modrm|JumpAbsolute|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Unspecified|BaseIndex }
 
 jmp, 1, 0xeb, None, 1, CpuNo64, Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp16|Disp32 }
-jmp, 1, 0xeb, None, 1, Cpu64, AMD64|Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp16|Disp32S }
+jmp, 1, 0xeb, None, 1, Cpu64, Amd64|Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp16|Disp32S }
 jmp, 1, 0xeb, None, 1, Cpu64, Intel64|Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp32S }
 jmp, 1, 0xff, 0x4, 1, CpuNo64, Modrm|JumpAbsolute|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg32|Unspecified|BaseIndex }
-jmp, 1, 0xff, 0x4, 1, Cpu64, AMD64|Modrm|JumpAbsolute|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg64|Unspecified|BaseIndex }
+jmp, 1, 0xff, 0x4, 1, Cpu64, Amd64|Modrm|JumpAbsolute|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg16|Reg64|Unspecified|BaseIndex }
 jmp, 1, 0xff, 0x4, 1, Cpu64, Intel64|Modrm|JumpAbsolute|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk|NoTrackPrefixOk, { Reg64|Unspecified|BaseIndex }
 // Intel Syntax.
 jmp, 2, 0xea, None, 1, CpuNo64, JumpInterSegment|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm16, Imm16|Imm32 }
@@ -400,8 +404,8 @@  ljmp, 1, 0xff, 0x5, 1, 0, Modrm|JumpAbsolute|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, {
 
 ret, 0, 0xc3, None, 1, CpuNo64, DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|RepPrefixOk|BNDPrefixOk, { 0 }
 ret, 1, 0xc2, None, 1, CpuNo64, DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|RepPrefixOk|BNDPrefixOk, { Imm16 }
-ret, 0, 0xc3, None, 1, Cpu64, AMD64|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { 0 }
-ret, 1, 0xc2, None, 1, Cpu64, AMD64|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { Imm16 }
+ret, 0, 0xc3, None, 1, Cpu64, Amd64|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { 0 }
+ret, 1, 0xc2, None, 1, Cpu64, Amd64|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { Imm16 }
 ret, 0, 0xc3, None, 1, Cpu64, Intel64|Size64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { 0 }
 ret, 1, 0xc2, None, 1, Cpu64, Intel64|Size64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { Imm16 }
 lret, 0, 0xcb, None, 1, 0, DefaultSize|No_bSuf|No_sSuf|No_ldSuf, { 0 }
@@ -909,10 +913,10 @@  rdmsr, 0, 0xf32, None, 2, Cpu586, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldS
 cmpxchg8b, 1, 0xfc7, 0x1, 2, Cpu586, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|IsLockable|NoRex64|HLEPrefixOk, { Qword|Unspecified|BaseIndex }
 
 // Pentium II/Pentium Pro extensions.
-sysenter, 0, 0xf34, None, 2, Cpu686, Intel64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
-sysenter, 0, 0xf34, None, 2, Cpu686|CpuNo64, AMD64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
-sysexit, 0, 0xf35, None, 2, Cpu686, Intel64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
-sysexit, 0, 0xf35, None, 2, Cpu686|CpuNo64, AMD64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
+sysenter, 0, 0xf34, None, 2, Cpu64, Intel64Only|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
+sysenter, 0, 0xf34, None, 2, Cpu686|CpuNo64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
+sysexit, 0, 0xf35, None, 2, Cpu64, Intel64Only|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
+sysexit, 0, 0xf35, None, 2, Cpu686|CpuNo64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
 fxsave, 1, 0xfae, 0x0, 2, CpuFXSR, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf, { Unspecified|BaseIndex }
 fxsave64, 1, 0xfae, 0x0, 2, CpuFXSR|Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|Rex64, { Unspecified|BaseIndex }
 fxrstor, 1, 0xfae, 0x1, 2, CpuFXSR, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf, { Unspecified|BaseIndex }