From 5990e377e5a339bce715fabfc3e45b24b459a7af Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 12 Feb 2020 16:19:03 +0100 Subject: x86-64: Intel64 adjustments for insns dealing with far pointers AMD and Intel differ in their handling of far indirect branches as well as LFS/LGS/LSS: AMD CPUs ignore REX.W while Intel ones honors it. (Note how the latter three were hybrids so far, while far branches were fully AMD-like.) --- gas/ChangeLog | 17 +++++++++++++++++ gas/config/tc-i386-intel.c | 6 ++++-- gas/config/tc-i386.c | 2 +- gas/doc/c-i386.texi | 12 ++++++++++++ gas/testsuite/gas/i386/i386.exp | 1 + gas/testsuite/gas/i386/x86-64-branch-3.d | 2 ++ gas/testsuite/gas/i386/x86-64-branch-3.s | 3 +++ gas/testsuite/gas/i386/x86-64-branch-5.l | 19 +++++++++++++++++++ gas/testsuite/gas/i386/x86-64-branch-5.s | 19 +++++++++++++++++++ gas/testsuite/gas/i386/x86-64-intel64.d | 4 ++++ gas/testsuite/gas/i386/x86-64-intel64.s | 6 ++++++ 11 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 gas/testsuite/gas/i386/x86-64-branch-5.l create mode 100644 gas/testsuite/gas/i386/x86-64-branch-5.s (limited to 'gas') diff --git a/gas/ChangeLog b/gas/ChangeLog index 3e08345..e7fac95 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,22 @@ 2020-02-12 Jan Beulich + PR gas/24546 + * config/tc-i386.c (match_template): Apply AMD64 check to 64-bit + code only. + * config/tc-i386-intel.c (i386_intel_operand): Also handle + CALL/JMP in O_tbyte_ptr case. + * doc/c-i386.texi: Mention far call and full pointer load ISA + differences. + * testsuite/gas/i386/x86-64-branch-3.s, + testsuite/gas/i386/x86-64-intel64.s: Add 64-bit far call cases. + * testsuite/gas/i386/x86-64-branch-3.d, + testsuite/gas/i386/x86-64-intel64.d: Adjust expectations. + * testsuite/gas/i386/x86-64-branch-5.l, + testsuite/gas/i386/x86-64-branch-5.s: New. + * testsuite/gas/i386/i386.exp: Run new test. + +2020-02-12 Jan Beulich + PR gas/25438 * config/tc-i386.c (REGISTER_WARNINGS): Delete. (check_byte_reg): Skip only source operand of CRC32. Drop Non- diff --git a/gas/config/tc-i386-intel.c b/gas/config/tc-i386-intel.c index bb8d320..76fc997 100644 --- a/gas/config/tc-i386-intel.c +++ b/gas/config/tc-i386-intel.c @@ -694,9 +694,11 @@ i386_intel_operand (char *operand_string, int got_a_float) if (got_a_float == 1) suffix = LONG_DOUBLE_MNEM_SUFFIX; else if ((current_templates->start->operand_types[0].bitfield.fword - || current_templates->start->operand_types[0].bitfield.tbyte) + || current_templates->start->operand_types[0].bitfield.tbyte + || current_templates->start->opcode_modifier.jump == JUMP_DWORD + || current_templates->start->opcode_modifier.jump == JUMP) && flag_code == CODE_64BIT) - suffix = QWORD_MNEM_SUFFIX; /* l[fgs]s, [ls][gi]dt */ + suffix = QWORD_MNEM_SUFFIX; /* l[fgs]s, [ls][gi]dt, call, jmp */ else i.types[this_operand].bitfield.byte = 1; /* cause an error */ break; diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 314fd72..ac141b8 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -5827,7 +5827,7 @@ match_template (char mnem_suffix) break; case intel64: /* -mintel64: Don't accept AMD64. */ - if (t->opcode_modifier.isa64 == AMD64) + if (t->opcode_modifier.isa64 == AMD64 && flag_code == CODE_64BIT) continue; break; } diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi index f0189cc..4eaf533 100644 --- a/gas/doc/c-i386.texi +++ b/gas/doc/c-i386.texi @@ -1455,6 +1455,18 @@ There are some discrepancies between AMD64 and Intel64 ISAs. @item For @samp{movsxd} with 16-bit destination register, AMD64 supports 32-bit source operand and Intel64 supports 16-bit source operand. + +@item For far branches (with explicit memory operand), both ISAs support +32- and 16-bit operand size. Intel64 additionally supports 64-bit +operand size, encoded as @samp{ljmpq} and @samp{lcallq} in AT&T syntax +and with an explicit @samp{tbyte ptr} operand size specifier in Intel +syntax. + +@item @samp{lfs}, @samp{lgs}, and @samp{lss} similarly allow for 16- +and 32-bit operand size (32- and 48-bit memory operand) in both ISAs, +while Intel64 additionally supports 64-bit operand sise (80-bit memory +operands). + @end itemize @node i386-Bugs diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index c428041..2ca8a94 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -1140,6 +1140,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t run_dump_test "x86-64-branch-2" run_dump_test "x86-64-branch-3" run_list_test "x86-64-branch-4" "-al -mintel64" + run_list_test "x86-64-branch-5" "-al" run_dump_test "x86-64-gotpcrel" run_dump_test "x86-64-gotpcrel-no-relax" diff --git a/gas/testsuite/gas/i386/x86-64-branch-3.d b/gas/testsuite/gas/i386/x86-64-branch-3.d index 7b9e21d..1d0e64e 100644 --- a/gas/testsuite/gas/i386/x86-64-branch-3.d +++ b/gas/testsuite/gas/i386/x86-64-branch-3.d @@ -16,4 +16,6 @@ Disassembly of section .text: [ ]*[a-f0-9]+: 66 48 e8 00 00 00 00 data16 rex\.W callq 1c 18: R_X86_64_PLT32 foo-0x4 [ ]*[a-f0-9]+: 66 c7 f8 00 00 xbeginw 21 1f: R_X86_64_PC16 foo-0x2 [ ]*[a-f0-9]+: 66 48 c7 f8 00 00 00 00 data16 xbeginq 29 25: R_X86_64_PLT32 foo-0x4 +[ ]*[a-f0-9]+: 48 ff 18 lcallq \*\(%rax\) +[ ]*[a-f0-9]+: 48 ff 29 ljmpq \*\(%rcx\) #pass diff --git a/gas/testsuite/gas/i386/x86-64-branch-3.s b/gas/testsuite/gas/i386/x86-64-branch-3.s index cc16487..898e5d9 100644 --- a/gas/testsuite/gas/i386/x86-64-branch-3.s +++ b/gas/testsuite/gas/i386/x86-64-branch-3.s @@ -10,3 +10,6 @@ bar: data16 xbegin foo data16 rex.w xbegin foo + + lcallq *(%rax) + ljmpq *(%rcx) diff --git a/gas/testsuite/gas/i386/x86-64-branch-5.l b/gas/testsuite/gas/i386/x86-64-branch-5.l new file mode 100644 index 0000000..188b6c2 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-branch-5.l @@ -0,0 +1,19 @@ +.*: Assembler messages: +.*:2: Error: unsupported syntax for `lcall' +.*:3: Error: unsupported syntax for `lfs' +.*:4: Error: unsupported syntax for `lfs' +.*:5: Error: unsupported syntax for `lgs' +.*:6: Error: unsupported syntax for `lgs' +.*:7: Error: unsupported syntax for `ljmp' +.*:8: Error: unsupported syntax for `lss' +.*:9: Error: unsupported syntax for `lss' +.*:12: Error: unsupported syntax for `call' +.*:13: Error: unsupported syntax for `lfs' +.*:14: Error: unsupported syntax for `lfs' +.*:15: Error: unsupported syntax for `lgs' +.*:16: Error: unsupported syntax for `lgs' +.*:17: Error: unsupported syntax for `jmp' +.*:18: Error: unsupported syntax for `lss' +.*:19: Error: unsupported syntax for `lss' +GAS LISTING .* +#pass diff --git a/gas/testsuite/gas/i386/x86-64-branch-5.s b/gas/testsuite/gas/i386/x86-64-branch-5.s new file mode 100644 index 0000000..f6a4ee2 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-branch-5.s @@ -0,0 +1,19 @@ + .text + lcallq *(%rax) + lfs (%rax), %rax + lfsq (%rax), %rax + lgs (%rax), %rax + lgsq (%rax), %rax + ljmpq *(%rax) + lss (%rax), %rax + lssq (%rax), %rax + + .intel_syntax noprefix + call TBYTE PTR [rax] + lfs rax, [rax] + lfs rax, TBYTE PTR [rax] + lgs rax, [rax] + lgs rax, TBYTE PTR [rax] + jmp TBYTE PTR [rax] + lss rax, [rax] + lss rax, TBYTE PTR [rax] diff --git a/gas/testsuite/gas/i386/x86-64-intel64.d b/gas/testsuite/gas/i386/x86-64-intel64.d index cae797b..10c820f 100644 --- a/gas/testsuite/gas/i386/x86-64-intel64.d +++ b/gas/testsuite/gas/i386/x86-64-intel64.d @@ -12,6 +12,8 @@ Disassembly of section .text: [ ]*[a-f0-9]+: 48 0f b5 11 lgs \(%rcx\),%rdx [ ]*[a-f0-9]+: 48 0f b2 1a lss \(%rdx\),%rbx [ ]*[a-f0-9]+: 48 0f b2 1a lss \(%rdx\),%rbx +[ ]*[a-f0-9]+: 48 ff 18 rex\.W lcall \*\(%rax\) +[ ]*[a-f0-9]+: 48 ff 29 rex\.W ljmp \*\(%rcx\) [ ]*[a-f0-9]+: 0f 05 syscall [ ]*[a-f0-9]+: 0f 07 sysret [ ]*[a-f0-9]+: 48 0f 07 sysretq * @@ -21,4 +23,6 @@ Disassembly of section .text: [ ]*[a-f0-9]+: 48 0f b5 0a lgs \(%rdx\),%rcx [ ]*[a-f0-9]+: 48 0f b2 13 lss \(%rbx\),%rdx [ ]*[a-f0-9]+: 48 0f b2 13 lss \(%rbx\),%rdx +[ ]*[a-f0-9]+: 48 ff 19 rex\.W lcall \*\(%rcx\) +[ ]*[a-f0-9]+: 48 ff 2a rex\.W ljmp \*\(%rdx\) #pass diff --git a/gas/testsuite/gas/i386/x86-64-intel64.s b/gas/testsuite/gas/i386/x86-64-intel64.s index d7852ab..7097877 100644 --- a/gas/testsuite/gas/i386/x86-64-intel64.s +++ b/gas/testsuite/gas/i386/x86-64-intel64.s @@ -10,6 +10,9 @@ _start: lss (%rdx), %rbx lssq (%rdx), %rbx + lcallq *(%rax) + ljmpq *(%rcx) + syscall sysretl sysretq @@ -21,3 +24,6 @@ _start: lgs rcx, tbyte ptr [rdx] lss rdx, [rbx] lss rdx, tbyte ptr [rbx] + + call tbyte ptr [rcx] + jmp tbyte ptr [rdx] -- cgit v1.1