From 5db04b0965e3e7a9344a93de22caae3c111de2cc Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 15 May 2015 09:47:39 -0700 Subject: Support AMD64/Intel ISAs in assembler/disassembler AMD64 spec and Intel64 spec differ in direct unconditional branches in 64-bit mode. AMD64 supports direct unconditional branches with 16-bit offset via the data size prefix, which truncates RIP to 16 bits, while the data size prefix is ignored by Intel64. This patch adds -mamd64/-mintel64 option to x86-64 assembler and -Mamd64/-Mintel64 option to x86-64 disassembler. The most permissive ISA, which is AMD64, is the default. GDB can add an option, similar to (gdb) help set disassembly-flavor Set the disassembly flavor. The valid values are "att" and "intel", and the default value is "att". to select which ISA to disassemble. binutils/ PR binutis/18386 * doc/binutils.texi: Document -Mamd64 and -Mintel64. gas/ PR binutis/18386 * config/tc-i386.c (OPTION_MAMD64): New. (OPTION_MINTEL64): Likewise. (md_longopts): Add -mamd64 and -mintel64. (md_parse_option): Handle OPTION_MAMD64 and OPTION_MINTEL64. (md_show_usage): Add -mamd64 and -mintel64. * doc/c-i386.texi: Document -mamd64 and -mintel64. gas/testsuite/ PR binutis/18386 * gas/i386/i386.exp: Run x86-64-branch-2 and x86-64-branch-3. * gas/i386/x86-64-branch.d: Also pass -Mintel64 to objdump. * gas/i386/ilp32/x86-64-branch.d: Likewise. * gas/i386/x86-64-branch-2.d: New file. * gas/i386/x86-64-branch-2.s: Likewise. * gas/i386/x86-64-branch-3.l: Likewise. * gas/i386/x86-64-branch-3.s: Likewise. ld/testsuite/ PR binutis/18386 * ld-x86-64/tlsgdesc.dd: Also pass -Mintel64 to objdump. * ld-x86-64/tlspic.dd: Likewise. * ld-x86-64/x86-64.exp (x86_64tests): Also pass -Mintel64 to objdump for tlspic.dd and tlsgdesc.dd. opcodes/ PR binutis/18386 * i386-dis.c: Add comments for '@'. (x86_64_table): Use '@' on call/jmp for X86_64_E8/X86_64_E9. (enum x86_64_isa): New. (isa64): Likewise. (print_i386_disassembler_options): Add amd64 and intel64. (print_insn): Handle amd64 and intel64. (putop): Handle '@'. (OP_J): Don't ignore the operand size prefix for AMD64 in 64-bit. * i386-gen.c (cpu_flags): Add CpuAMD64 and CpuIntel64. * i386-opc.h (AMD64): New. (CpuIntel64): Likewise. (i386_cpu_flags): Add cpuamd64 and cpuintel64. * i386-opc.tbl: Add direct call/jmp with Disp16|Disp32 for AMD64. Mark direct call/jmp without Disp16|Disp32 as Intel64. * i386-init.h: Regenerated. * i386-tbl.h: Likewise. --- gas/ChangeLog | 10 ++++++++++ gas/config/tc-i386.c | 22 ++++++++++++++++++++++ gas/doc/c-i386.texi | 7 +++++++ gas/testsuite/ChangeLog | 11 +++++++++++ gas/testsuite/gas/i386/i386.exp | 2 ++ gas/testsuite/gas/i386/ilp32/x86-64-branch.d | 2 +- gas/testsuite/gas/i386/x86-64-branch-2.d | 15 +++++++++++++++ gas/testsuite/gas/i386/x86-64-branch-2.s | 7 +++++++ gas/testsuite/gas/i386/x86-64-branch-3.l | 17 +++++++++++++++++ gas/testsuite/gas/i386/x86-64-branch-3.s | 7 +++++++ gas/testsuite/gas/i386/x86-64-branch.d | 2 +- 11 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 gas/testsuite/gas/i386/x86-64-branch-2.d create mode 100644 gas/testsuite/gas/i386/x86-64-branch-2.s create mode 100644 gas/testsuite/gas/i386/x86-64-branch-3.l create mode 100644 gas/testsuite/gas/i386/x86-64-branch-3.s (limited to 'gas') diff --git a/gas/ChangeLog b/gas/ChangeLog index 9bc4a15..6cd3639 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,15 @@ 2015-05-15 H.J. Lu + PR binutis/18386 + * config/tc-i386.c (OPTION_MAMD64): New. + (OPTION_MINTEL64): Likewise. + (md_longopts): Add -mamd64 and -mintel64. + (md_parse_option): Handle OPTION_MAMD64 and OPTION_MINTEL64. + (md_show_usage): Add -mamd64 and -mintel64. + * doc/c-i386.texi: Document -mamd64 and -mintel64. + +2015-05-15 H.J. Lu + * config/tc-i386.c (shared): New. (OPTION_MSHARED): Likewise. (elf_symbol_resolved_in_segment_p): Add relocation argument. diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 254548f..34b5c28 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -9550,6 +9550,8 @@ const char *md_shortopts = "qn"; #define OPTION_OMIT_LOCK_PREFIX (OPTION_MD_BASE + 19) #define OPTION_MEVEXRCIG (OPTION_MD_BASE + 20) #define OPTION_MSHARED (OPTION_MD_BASE + 21) +#define OPTION_MAMD64 (OPTION_MD_BASE + 22) +#define OPTION_MINTEL64 (OPTION_MD_BASE + 23) struct option md_longopts[] = { @@ -9582,6 +9584,8 @@ struct option md_longopts[] = #endif {"momit-lock-prefix", required_argument, NULL, OPTION_OMIT_LOCK_PREFIX}, {"mevexrcig", required_argument, NULL, OPTION_MEVEXRCIG}, + {"mamd64", no_argument, NULL, OPTION_MAMD64}, + {"mintel64", no_argument, NULL, OPTION_MINTEL64}, {NULL, no_argument, NULL, 0} }; size_t md_longopts_size = sizeof (md_longopts); @@ -9898,6 +9902,20 @@ md_parse_option (int c, char *arg) as_fatal (_("invalid -momit-lock-prefix= option: `%s'"), arg); break; + case OPTION_MAMD64: + cpu_arch_flags.bitfield.cpuamd64 = 1; + cpu_arch_flags.bitfield.cpuintel64 = 0; + cpu_arch_isa_flags.bitfield.cpuamd64 = 1; + cpu_arch_isa_flags.bitfield.cpuintel64 = 0; + break; + + case OPTION_MINTEL64: + cpu_arch_flags.bitfield.cpuamd64 = 0; + cpu_arch_flags.bitfield.cpuintel64 = 1; + cpu_arch_isa_flags.bitfield.cpuamd64 = 0; + cpu_arch_isa_flags.bitfield.cpuintel64 = 1; + break; + default: return 0; } @@ -10063,6 +10081,10 @@ md_show_usage (FILE *stream) fprintf (stream, _("\ -momit-lock-prefix=[no|yes]\n\ strip all lock prefixes\n")); + fprintf (stream, _("\ + -mamd64 accept only AMD64 ISA\n")); + fprintf (stream, _("\ + -mintel64 accept only Intel64 ISA\n")); } #if ((defined (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \ diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi index ea08c63..6118987 100644 --- a/gas/doc/c-i386.texi +++ b/gas/doc/c-i386.texi @@ -339,6 +339,13 @@ of EVEX instruction with 00, which is the default. and @option{-mevexrcig=@var{rz}} will encode SAE-only EVEX instructions with 01, 10 and 11 RC bits, respectively. +@cindex @samp{-mamd64} option, x86-64 +@cindex @samp{-mintel64} option, x86-64 +@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. + @end table @c man end diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 95b7583..7f4b81b 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,5 +1,16 @@ 2015-05-15 H.J. Lu + PR binutis/18386 + * gas/i386/i386.exp: Run x86-64-branch-2 and x86-64-branch-3. + * gas/i386/x86-64-branch.d: Also pass -Mintel64 to objdump. + * gas/i386/ilp32/x86-64-branch.d: Likewise. + * gas/i386/x86-64-branch-2.d: New file. + * gas/i386/x86-64-branch-2.s: Likewise. + * gas/i386/x86-64-branch-3.l: Likewise. + * gas/i386/x86-64-branch-3.s: Likewise. + +2015-05-15 H.J. Lu + * gas/i386/i386.exp: Don't run pcrel for ELF targets. Run pcrel-elf, relax-4 and x86-64-relax-3 for ELF targets. * gas/i386/pcrel-elf.d: New file. diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index ff648b0..9ff38d3 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -770,6 +770,8 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t run_dump_test "x86-64-relax-3" run_dump_test "x86-64-jump" + run_dump_test "x86-64-branch-2" + run_list_test "x86-64-branch-3" "-al -mintel64" } set ASFLAGS "$old_ASFLAGS" diff --git a/gas/testsuite/gas/i386/ilp32/x86-64-branch.d b/gas/testsuite/gas/i386/ilp32/x86-64-branch.d index 9fcb8ca..8200282 100644 --- a/gas/testsuite/gas/i386/ilp32/x86-64-branch.d +++ b/gas/testsuite/gas/i386/ilp32/x86-64-branch.d @@ -1,6 +1,6 @@ #source: ../x86-64-branch.s #as: -J -#objdump: -drw +#objdump: -drw -Mintel64 #name: x86-64 (ILP32) branch .*: +file format .* diff --git a/gas/testsuite/gas/i386/x86-64-branch-2.d b/gas/testsuite/gas/i386/x86-64-branch-2.d new file mode 100644 index 0000000..5078daa --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-branch-2.d @@ -0,0 +1,15 @@ +#as: -J +#objdump: -dwr +#name: x86-64 branch 2 + +.*: +file format .* + +Disassembly of section .text: + +0+ : +[ ]*[a-f0-9]+: 66 e9 00 00 jmpw 4 2: R_X86_64_PC16 foo-0x2 + +0+4 : +[ ]*[a-f0-9]+: 89 c3 mov %eax,%ebx +[ ]*[a-f0-9]+: 66 e8 00 00 callw a 8: R_X86_64_PC16 foo-0x2 +#pass diff --git a/gas/testsuite/gas/i386/x86-64-branch-2.s b/gas/testsuite/gas/i386/x86-64-branch-2.s new file mode 100644 index 0000000..16c85a3 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-branch-2.s @@ -0,0 +1,7 @@ + .text + data16 jmp foo + +bar: + mov %eax, %ebx + + data16 call foo diff --git a/gas/testsuite/gas/i386/x86-64-branch-3.l b/gas/testsuite/gas/i386/x86-64-branch-3.l new file mode 100644 index 0000000..de3c2dd --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-branch-3.l @@ -0,0 +1,17 @@ +.*: Assembler messages: +.*:2: Warning: indirect jmp without `\*' +.*:7: Warning: indirect call without `\*' +GAS LISTING .* + + +[ ]*1[ ]+\.text +[ ]*2[ ]+0000 66FF2C25 data16 jmp foo +\*\*\*\* Warning: indirect jmp without `\*' +[ ]*2[ ]+00000000 +[ ]*3[ ]+ +[ ]*4[ ]+bar: +[ ]*5[ ]+0008 89C3 mov %eax, %ebx +[ ]*6[ ]+ +[ ]*7[ ]+000a 66FF1C25 data16 call foo +\*\*\*\* Warning: indirect call without `\*' +[ ]*7[ ]+00000000 diff --git a/gas/testsuite/gas/i386/x86-64-branch-3.s b/gas/testsuite/gas/i386/x86-64-branch-3.s new file mode 100644 index 0000000..16c85a3 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-branch-3.s @@ -0,0 +1,7 @@ + .text + data16 jmp foo + +bar: + mov %eax, %ebx + + data16 call foo diff --git a/gas/testsuite/gas/i386/x86-64-branch.d b/gas/testsuite/gas/i386/x86-64-branch.d index 49e17a4..612acc0 100644 --- a/gas/testsuite/gas/i386/x86-64-branch.d +++ b/gas/testsuite/gas/i386/x86-64-branch.d @@ -1,5 +1,5 @@ #as: -J -#objdump: -dw +#objdump: -dw -Mintel64 #name: x86-64 branch .*: +file format .* -- cgit v1.1