New version 5.5-2017.10 with retpoline support patches

This commit is contained in:
Andrey Bondrov 2018-03-15 18:24:33 +10:00
parent e1bb95cf02
commit 6eac6210dc
11 changed files with 5123 additions and 5 deletions

View file

@ -1,3 +1,3 @@
sources:
gcc-x32-seed.tar.xz: c656c8f0d0f17a94f0a21ec65ba6633b56e6ea47
gcc-linaro-5.4-2017.05.tar.xz: 3376af91629331fc4c3344d5aa0301c124b964db
gcc-linaro-5.5-2017.10.tar.xz: f31ffa46619262a227727eab5ae5d7569cd3989c

View file

@ -0,0 +1,239 @@
From 11a3b9034935080b9996caf07fca6353309006f1 Mon Sep 17 00:00:00 2001
From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Mon, 15 Jan 2018 11:27:24 +0000
Subject: [PATCH 1/9] i386: Move struct ix86_frame to machine_function
Make ix86_frame available to i386 code generation. This is needed to
backport the patch set of -mindirect-branch= to mitigate variant #2 of
the speculative execution vulnerabilities on x86 processors identified
by CVE-2017-5715, aka Spectre.
Backport from mainline
* config/i386/i386.c (ix86_frame): Moved to ...
* config/i386/i386.h (ix86_frame): Here.
(machine_function): Add frame.
* config/i386/i386.c (ix86_compute_frame_layout): Repace the
frame argument with &cfun->machine->frame.
(ix86_can_use_return_insn_p): Don't pass &frame to
ix86_compute_frame_layout. Copy frame from cfun->machine->frame.
(ix86_can_eliminate): Likewise.
(ix86_expand_prologue): Likewise.
(ix86_expand_epilogue): Likewise.
(ix86_expand_split_stack_prologue): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@256691 138bc75d-0d04-0410-961f-82ee72b054a4
---
src/gcc/config/i386/i386.c | 68 ++++++++-------------------------------------
src/gcc/config/i386/i386.h | 53 ++++++++++++++++++++++++++++++++++-
2 files changed, 65 insertions(+), 56 deletions(-)
Index: b/src/gcc/config/i386/i386.c
===================================================================
--- a/src/gcc/config/i386/i386.c
+++ b/src/gcc/config/i386/i386.c
@@ -2306,53 +2306,6 @@ struct GTY(()) stack_local_entry {
struct stack_local_entry *next;
};
-/* Structure describing stack frame layout.
- Stack grows downward:
-
- [arguments]
- <- ARG_POINTER
- saved pc
-
- saved static chain if ix86_static_chain_on_stack
-
- saved frame pointer if frame_pointer_needed
- <- HARD_FRAME_POINTER
- [saved regs]
- <- regs_save_offset
- [padding0]
-
- [saved SSE regs]
- <- sse_regs_save_offset
- [padding1] |
- | <- FRAME_POINTER
- [va_arg registers] |
- |
- [frame] |
- |
- [padding2] | = to_allocate
- <- STACK_POINTER
- */
-struct ix86_frame
-{
- int nsseregs;
- int nregs;
- int va_arg_size;
- int red_zone_size;
- int outgoing_arguments_size;
-
- /* The offsets relative to ARG_POINTER. */
- HOST_WIDE_INT frame_pointer_offset;
- HOST_WIDE_INT hard_frame_pointer_offset;
- HOST_WIDE_INT stack_pointer_offset;
- HOST_WIDE_INT hfp_save_offset;
- HOST_WIDE_INT reg_save_offset;
- HOST_WIDE_INT sse_reg_save_offset;
-
- /* When save_regs_using_mov is set, emit prologue using
- move instead of push instructions. */
- bool save_regs_using_mov;
-};
-
/* Which cpu are we scheduling for. */
enum attr_cpu ix86_schedule;
@@ -2443,7 +2396,7 @@ static unsigned int ix86_function_arg_bo
const_tree);
static rtx ix86_static_chain (const_tree, bool);
static int ix86_function_regparm (const_tree, const_tree);
-static void ix86_compute_frame_layout (struct ix86_frame *);
+static void ix86_compute_frame_layout (void);
static bool ix86_expand_vector_init_one_nonzero (bool, machine_mode,
rtx, rtx, int);
static void ix86_add_new_builtins (HOST_WIDE_INT);
@@ -9664,7 +9617,8 @@ ix86_can_use_return_insn_p (void)
if (crtl->args.pops_args && crtl->args.size >= 32768)
return 0;
- ix86_compute_frame_layout (&frame);
+ ix86_compute_frame_layout ();
+ frame = cfun->machine->frame;
return (frame.stack_pointer_offset == UNITS_PER_WORD
&& (frame.nregs + frame.nsseregs) == 0);
}
@@ -10073,8 +10027,8 @@ ix86_can_eliminate (const int from, cons
HOST_WIDE_INT
ix86_initial_elimination_offset (int from, int to)
{
- struct ix86_frame frame;
- ix86_compute_frame_layout (&frame);
+ ix86_compute_frame_layout ();
+ struct ix86_frame frame = cfun->machine->frame;
if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
return frame.hard_frame_pointer_offset;
@@ -10113,8 +10067,9 @@ ix86_builtin_setjmp_frame_value (void)
/* Fill structure ix86_frame about frame of currently computed function. */
static void
-ix86_compute_frame_layout (struct ix86_frame *frame)
+ix86_compute_frame_layout (void)
{
+ struct ix86_frame *frame = &cfun->machine->frame;
unsigned HOST_WIDE_INT stack_alignment_needed;
HOST_WIDE_INT offset;
unsigned HOST_WIDE_INT preferred_alignment;
@@ -11417,7 +11372,8 @@ ix86_expand_prologue (void)
m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET;
m->fs.sp_valid = true;
- ix86_compute_frame_layout (&frame);
+ ix86_compute_frame_layout ();
+ frame = m->frame;
if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl))
{
@@ -12083,7 +12039,8 @@ ix86_expand_epilogue (int style)
bool using_drap;
ix86_finalize_stack_realign_flags ();
- ix86_compute_frame_layout (&frame);
+ ix86_compute_frame_layout ();
+ frame = m->frame;
m->fs.sp_valid = (!frame_pointer_needed
|| (crtl->sp_is_unchanging
@@ -12546,7 +12503,8 @@ ix86_expand_split_stack_prologue (void)
gcc_assert (flag_split_stack && reload_completed);
ix86_finalize_stack_realign_flags ();
- ix86_compute_frame_layout (&frame);
+ ix86_compute_frame_layout ();
+ frame = cfun->machine->frame;
allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET;
/* This is the label we will branch to if we have enough stack
Index: b/src/gcc/config/i386/i386.h
===================================================================
--- a/src/gcc/config/i386/i386.h
+++ b/src/gcc/config/i386/i386.h
@@ -2409,9 +2409,56 @@ enum avx_u128_state
#define FASTCALL_PREFIX '@'
+#ifndef USED_FOR_TARGET
+/* Structure describing stack frame layout.
+ Stack grows downward:
+
+ [arguments]
+ <- ARG_POINTER
+ saved pc
+
+ saved static chain if ix86_static_chain_on_stack
+
+ saved frame pointer if frame_pointer_needed
+ <- HARD_FRAME_POINTER
+ [saved regs]
+ <- regs_save_offset
+ [padding0]
+
+ [saved SSE regs]
+ <- sse_regs_save_offset
+ [padding1] |
+ | <- FRAME_POINTER
+ [va_arg registers] |
+ |
+ [frame] |
+ |
+ [padding2] | = to_allocate
+ <- STACK_POINTER
+ */
+struct GTY(()) ix86_frame
+{
+ int nsseregs;
+ int nregs;
+ int va_arg_size;
+ int red_zone_size;
+ int outgoing_arguments_size;
+
+ /* The offsets relative to ARG_POINTER. */
+ HOST_WIDE_INT frame_pointer_offset;
+ HOST_WIDE_INT hard_frame_pointer_offset;
+ HOST_WIDE_INT stack_pointer_offset;
+ HOST_WIDE_INT hfp_save_offset;
+ HOST_WIDE_INT reg_save_offset;
+ HOST_WIDE_INT sse_reg_save_offset;
+
+ /* When save_regs_using_mov is set, emit prologue using
+ move instead of push instructions. */
+ bool save_regs_using_mov;
+};
+
/* Machine specific frame tracking during prologue/epilogue generation. */
-#ifndef USED_FOR_TARGET
struct GTY(()) machine_frame_state
{
/* This pair tracks the currently active CFA as reg+offset. When reg
@@ -2457,6 +2504,9 @@ struct GTY(()) machine_function {
int varargs_fpr_size;
int optimize_mode_switching[MAX_386_ENTITIES];
+ /* Cached initial frame layout for the current function. */
+ struct ix86_frame frame;
+
/* Number of saved registers USE_FAST_PROLOGUE_EPILOGUE
has been computed for. */
int use_fast_prologue_epilogue_nregs;
@@ -2524,6 +2574,7 @@ struct GTY(()) machine_function {
#define ix86_current_function_calls_tls_descriptor \
(ix86_tls_descriptor_calls_expanded_in_cfun && df_regs_ever_live_p (SP_REG))
#define ix86_static_chain_on_stack (cfun->machine->static_chain_on_stack)
+#define ix86_red_zone_size (cfun->machine->frame.red_zone_size)
/* Control behavior of x86_file_start. */
#define X86_FILE_START_VERSION_DIRECTIVE false

View file

@ -0,0 +1,72 @@
From 18202ba32cb8de22fc43a5839235a751d0f5c4d9 Mon Sep 17 00:00:00 2001
From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Mon, 15 Jan 2018 11:28:44 +0000
Subject: [PATCH 2/9] i386: Use reference of struct ix86_frame to avoid copy
When there is no need to make a copy of ix86_frame, we can use reference
of struct ix86_frame to avoid copy.
Backport from mainline
* config/i386/i386.c (ix86_can_use_return_insn_p): Use reference
of struct ix86_frame.
(ix86_initial_elimination_offset): Likewise.
(ix86_expand_split_stack_prologue): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@256692 138bc75d-0d04-0410-961f-82ee72b054a4
---
gcc/config/i386/i386.c | 9 +++------
gcc/testsuite/ChangeLog | 8 ++++++++
2 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 8133372..397ef7c 100644
--- a/src/gcc/config/i386/i386.c
+++ b/src/gcc/config/i386/i386.c
@@ -11843,8 +11843,6 @@ symbolic_reference_mentioned_p (rtx op)
bool
ix86_can_use_return_insn_p (void)
{
- struct ix86_frame frame;
-
if (! reload_completed || frame_pointer_needed)
return 0;
@@ -11857,7 +11855,7 @@ ix86_can_use_return_insn_p (void)
return 0;
ix86_compute_frame_layout ();
- frame = cfun->machine->frame;
+ struct ix86_frame &frame = cfun->machine->frame;
return (frame.stack_pointer_offset == UNITS_PER_WORD
&& (frame.nregs + frame.nsseregs) == 0);
}
@@ -12344,7 +12342,7 @@ HOST_WIDE_INT
ix86_initial_elimination_offset (int from, int to)
{
ix86_compute_frame_layout ();
- struct ix86_frame frame = cfun->machine->frame;
+ struct ix86_frame &frame = cfun->machine->frame;
if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
return frame.hard_frame_pointer_offset;
@@ -14860,7 +14858,6 @@ static GTY(()) rtx split_stack_fn_large;
void
ix86_expand_split_stack_prologue (void)
{
- struct ix86_frame frame;
HOST_WIDE_INT allocate;
unsigned HOST_WIDE_INT args_size;
rtx_code_label *label;
@@ -14873,7 +14870,7 @@ ix86_expand_split_stack_prologue (void)
ix86_finalize_stack_realign_flags ();
ix86_compute_frame_layout ();
- frame = cfun->machine->frame;
+ struct ix86_frame &frame = cfun->machine->frame;
allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET;
/* This is the label we will branch to if we have enough stack
--
2.7.4

View file

@ -0,0 +1,59 @@
From 839ca2d69157ef03c8df0ab912dacdb991738694 Mon Sep 17 00:00:00 2001
From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Mon, 15 Jan 2018 11:33:42 +0000
Subject: [PATCH 3/9] i386: More use reference of struct ix86_frame to avoid copy
When there is no need to make a copy of ix86_frame, we can use reference
of struct ix86_frame to avoid copy.
Backport from mainline
* config/i386/i386.c (ix86_expand_prologue): Use reference of
struct ix86_frame.
(ix86_expand_epilogue): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@256695 138bc75d-0d04-0410-961f-82ee72b054a4
---
gcc/ChangeLog | 7 +++++++
gcc/config/i386/i386.c | 6 ++----
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 397ef7c..986e6d7 100644
--- a/src/gcc/config/i386/i386.c
+++ b/src/gcc/config/i386/i386.c
@@ -13667,7 +13667,6 @@ ix86_expand_prologue (void)
{
struct machine_function *m = cfun->machine;
rtx insn, t;
- struct ix86_frame frame;
HOST_WIDE_INT allocate;
bool int_registers_saved;
bool sse_registers_saved;
@@ -13691,7 +13690,7 @@ ix86_expand_prologue (void)
m->fs.sp_valid = true;
ix86_compute_frame_layout ();
- frame = m->frame;
+ struct ix86_frame &frame = cfun->machine->frame;
if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl))
{
@@ -14354,13 +14353,12 @@ ix86_expand_epilogue (int style)
{
struct machine_function *m = cfun->machine;
struct machine_frame_state frame_state_save = m->fs;
- struct ix86_frame frame;
bool restore_regs_via_mov;
bool using_drap;
ix86_finalize_stack_realign_flags ();
ix86_compute_frame_layout ();
- frame = m->frame;
+ struct ix86_frame &frame = cfun->machine->frame;
m->fs.sp_valid = (!frame_pointer_needed
|| (crtl->sp_is_unchanging
--
2.7.4

View file

@ -0,0 +1,63 @@
From c25b81ba01fa9ac0c1baa3aabd64190c47928f03 Mon Sep 17 00:00:00 2001
From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Tue, 16 Jan 2018 12:49:29 +0000
Subject: [PATCH 4/9] i386: Don't use reference of struct ix86_frame
Use reference of struct ix86_frame in ix86_expand_prologue and
ix86_expand_epilogue caused:
raised STORAGE_ERROR : stack overflow or erroneous memory access
make[5]: *** [/export/gnu/import/git/sources/gcc/gcc/ada/Make-generated.in:45: ada/sinfo.h] Error 1
on trunk when bootstrapping GCC with ada on x86-64.
* config/i386/i386.c (ix86_expand_prologue): Don't use reference
of struct ix86_frame.
(ix86_expand_epilogue): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@256742 138bc75d-0d04-0410-961f-82ee72b054a4
---
gcc/ChangeLog | 10 ++++++++++
gcc/config/i386/i386.c | 6 ++++--
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index e758387..ba2abc5 100644
--- a/src/gcc/config/i386/i386.c
+++ b/src/gcc/config/i386/i386.c
@@ -14061,6 +14061,7 @@ ix86_expand_prologue (void)
{
struct machine_function *m = cfun->machine;
rtx insn, t;
+ struct ix86_frame frame;
HOST_WIDE_INT allocate;
bool int_registers_saved;
bool sse_registers_saved;
@@ -14084,7 +14085,7 @@ ix86_expand_prologue (void)
m->fs.sp_valid = true;
ix86_compute_frame_layout ();
- struct ix86_frame &frame = cfun->machine->frame;
+ frame = m->frame;
if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl))
{
@@ -14747,12 +14748,13 @@ ix86_expand_epilogue (int style)
{
struct machine_function *m = cfun->machine;
struct machine_frame_state frame_state_save = m->fs;
+ struct ix86_frame frame;
bool restore_regs_via_mov;
bool using_drap;
ix86_finalize_stack_realign_flags ();
ix86_compute_frame_layout ();
- struct ix86_frame &frame = cfun->machine->frame;
+ frame = m->frame;
m->fs.sp_valid = (!frame_pointer_needed
|| (crtl->sp_is_unchanging
--
2.7.4

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,837 @@
From 86118fbdbafe6af54b2da467e1073c49e1742116 Mon Sep 17 00:00:00 2001
From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Tue, 16 Jan 2018 11:17:49 +0000
Subject: [PATCH 7/9] x86: Add -mindirect-branch-register
Add -mindirect-branch-register to force indirect branch via register.
This is implemented by disabling patterns of indirect branch via memory,
similar to TARGET_X32.
-mindirect-branch= and -mfunction-return= tests are updated with
-mno-indirect-branch-register to avoid false test failures when
-mindirect-branch-register is added to RUNTESTFLAGS for "make check".
gcc/
Backport from mainline
2018-01-14 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/constraints.md (Bs): Disallow memory operand for
-mindirect-branch-register.
(Bw): Likewise.
* config/i386/predicates.md (indirect_branch_operand): Likewise.
(GOT_memory_operand): Likewise.
(call_insn_operand): Likewise.
(sibcall_insn_operand): Likewise.
(GOT32_symbol_operand): Likewise.
* config/i386/i386.md (indirect_jump): Call convert_memory_address
for -mindirect-branch-register.
(tablejump): Likewise.
(*sibcall_memory): Likewise.
(*sibcall_value_memory): Likewise.
Disallow peepholes of indirect call and jump via memory for
-mindirect-branch-register.
(*call_pop): Replace m with Bw.
(*call_value_pop): Likewise.
(*sibcall_pop_memory): Replace m with Bs.
* config/i386/i386.opt (mindirect-branch-register): New option.
* doc/invoke.texi: Document -mindirect-branch-register option.
gcc/testsuite/
Backport from mainline
2018-01-14 H.J. Lu <hongjiu.lu@intel.com>
* gcc.target/i386/indirect-thunk-1.c (dg-options): Add
-mno-indirect-branch-register.
* gcc.target/i386/indirect-thunk-2.c: Likewise.
* gcc.target/i386/indirect-thunk-3.c: Likewise.
* gcc.target/i386/indirect-thunk-4.c: Likewise.
* gcc.target/i386/indirect-thunk-5.c: Likewise.
* gcc.target/i386/indirect-thunk-6.c: Likewise.
* gcc.target/i386/indirect-thunk-7.c: Likewise.
* gcc.target/i386/indirect-thunk-attr-1.c: Likewise.
* gcc.target/i386/indirect-thunk-attr-2.c: Likewise.
* gcc.target/i386/indirect-thunk-attr-3.c: Likewise.
* gcc.target/i386/indirect-thunk-attr-4.c: Likewise.
* gcc.target/i386/indirect-thunk-attr-5.c: Likewise.
* gcc.target/i386/indirect-thunk-attr-6.c: Likewise.
* gcc.target/i386/indirect-thunk-attr-7.c: Likewise.
* gcc.target/i386/indirect-thunk-bnd-1.c: Likewise.
* gcc.target/i386/indirect-thunk-bnd-2.c: Likewise.
* gcc.target/i386/indirect-thunk-bnd-3.c: Likewise.
* gcc.target/i386/indirect-thunk-bnd-4.c: Likewise.
* gcc.target/i386/indirect-thunk-extern-1.c: Likewise.
* gcc.target/i386/indirect-thunk-extern-2.c: Likewise.
* gcc.target/i386/indirect-thunk-extern-3.c: Likewise.
* gcc.target/i386/indirect-thunk-extern-4.c: Likewise.
* gcc.target/i386/indirect-thunk-extern-5.c: Likewise.
* gcc.target/i386/indirect-thunk-extern-6.c: Likewise.
* gcc.target/i386/indirect-thunk-extern-7.c: Likewise.
* gcc.target/i386/indirect-thunk-inline-1.c: Likewise.
* gcc.target/i386/indirect-thunk-inline-2.c: Likewise.
* gcc.target/i386/indirect-thunk-inline-3.c: Likewise.
* gcc.target/i386/indirect-thunk-inline-4.c: Likewise.
* gcc.target/i386/indirect-thunk-inline-5.c: Likewise.
* gcc.target/i386/indirect-thunk-inline-6.c: Likewise.
* gcc.target/i386/indirect-thunk-inline-7.c: Likewise.
* gcc.target/i386/ret-thunk-10.c: Likewise.
* gcc.target/i386/ret-thunk-11.c: Likewise.
* gcc.target/i386/ret-thunk-12.c: Likewise.
* gcc.target/i386/ret-thunk-13.c: Likewise.
* gcc.target/i386/ret-thunk-14.c: Likewise.
* gcc.target/i386/ret-thunk-15.c: Likewise.
* gcc.target/i386/ret-thunk-9.c: Likewise.
* gcc.target/i386/indirect-thunk-register-1.c: New test.
* gcc.target/i386/indirect-thunk-register-2.c: Likewise.
* gcc.target/i386/indirect-thunk-register-3.c: Likewise.
i386: Rename to ix86_indirect_branch_register
Rename the variable for -mindirect-branch-register to
ix86_indirect_branch_register to match the command-line option name.
Backport from mainline
2018-01-15 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/constraints.md (Bs): Replace
ix86_indirect_branch_thunk_register with
ix86_indirect_branch_register.
(Bw): Likewise.
* config/i386/i386.md (indirect_jump): Likewise.
(tablejump): Likewise.
(*sibcall_memory): Likewise.
(*sibcall_value_memory): Likewise.
Peepholes of indirect call and jump via memory: Likewise.
* config/i386/i386.opt: Likewise.
* config/i386/predicates.md (indirect_branch_operand): Likewise.
(GOT_memory_operand): Likewise.
(call_insn_operand): Likewise.
(sibcall_insn_operand): Likewise.
(GOT32_symbol_operand): Likewise.
x86: Rewrite ix86_indirect_branch_register logic
Rewrite ix86_indirect_branch_register logic with
(and (not (match_test "ix86_indirect_branch_register"))
(original condition before r256662))
Backport from mainline
2018-01-15 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/predicates.md (constant_call_address_operand):
Rewrite ix86_indirect_branch_register logic.
(sibcall_insn_operand): Likewise.
Don't check ix86_indirect_branch_register for GOT operand
Since GOT_memory_operand and GOT32_symbol_operand are simple pattern
matches, don't check ix86_indirect_branch_register here. If needed,
-mindirect-branch= will convert indirect branch via GOT slot to a call
and return thunk.
Backport from mainline
2018-01-15 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/constraints.md (Bs): Update
ix86_indirect_branch_register check. Don't check
ix86_indirect_branch_register with GOT_memory_operand.
(Bw): Likewise.
* config/i386/predicates.md (GOT_memory_operand): Don't check
ix86_indirect_branch_register here.
(GOT32_symbol_operand): Likewise.
i386: Rewrite indirect_branch_operand logic
Backport from mainline
2018-01-15 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/predicates.md (indirect_branch_operand): Rewrite
ix86_indirect_branch_register logic.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@256735 138bc75d-0d04-0410-961f-82ee72b054a4
[Ubuntu note: Dropped indirect-thunk-5.c, indirect-thunk-6.c,
indirect-thunk-bnd-3.c, indirect-thunk-bnd-4.c,
indirect-thunk-extern-5.c, indirect-thunk-extern-6.c,
indirect-thunk-inline-5.c, and indirect-thunk-inline-6.c tests due
to gcc 5.4 and earlier not supporting the -fno-plt option.
--sbeattie,]
---
src/gcc/config/i386/constraints.md | 6 +
src/gcc/config/i386/i386.md | 34 ++++++----
src/gcc/config/i386/i386.opt | 4 +
src/gcc/config/i386/predicates.md | 9 +-
src/gcc/doc/invoke.texi | 7 +-
src/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c | 22 ++++++
src/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c | 20 +++++
src/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c | 19 +++++
src/gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 2
src/gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 2
src/gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 2
src/gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 2
src/gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 2
src/gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 2
src/gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 2
39 files changed, 134 insertions(+), 49 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c
Index: b/src/gcc/config/i386/constraints.md
===================================================================
--- a/src/gcc/config/i386/constraints.md
+++ b/src/gcc/config/i386/constraints.md
@@ -157,12 +157,14 @@
(define_constraint "Bs"
"@internal Sibcall memory operand."
- (and (not (match_test "TARGET_X32"))
+ (and (not (match_test "ix86_indirect_branch_register"))
+ (not (match_test "TARGET_X32"))
(match_operand 0 "sibcall_memory_operand")))
(define_constraint "Bw"
"@internal Call memory operand."
- (and (not (match_test "TARGET_X32"))
+ (and (not (match_test "ix86_indirect_branch_register"))
+ (not (match_test "TARGET_X32"))
(match_operand 0 "memory_operand")))
(define_constraint "Bz"
Index: b/src/gcc/config/i386/i386.md
===================================================================
--- a/src/gcc/config/i386/i386.md
+++ b/src/gcc/config/i386/i386.md
@@ -11554,7 +11554,7 @@
[(set (pc) (match_operand 0 "indirect_branch_operand"))]
""
{
- if (TARGET_X32)
+ if (TARGET_X32 || ix86_indirect_branch_register)
operands[0] = convert_memory_address (word_mode, operands[0]);
cfun->machine->has_local_indirect_jump = true;
})
@@ -11607,7 +11607,7 @@
OPTAB_DIRECT);
}
- if (TARGET_X32)
+ if (TARGET_X32 || ix86_indirect_branch_register)
operands[0] = convert_memory_address (word_mode, operands[0]);
cfun->machine->has_local_indirect_jump = true;
})
@@ -11764,7 +11764,7 @@
[(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
(match_operand 1))
(unspec [(const_int 0)] UNSPEC_PEEPSIB)]
- "!TARGET_X32"
+ "!TARGET_X32 && !ix86_indirect_branch_register"
"* return ix86_output_call_insn (insn, operands[0]);"
[(set_attr "type" "call")])
@@ -11773,7 +11773,9 @@
(match_operand:W 1 "memory_operand"))
(call (mem:QI (match_dup 0))
(match_operand 3))]
- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
+ "!TARGET_X32
+ && !ix86_indirect_branch_register
+ && SIBLING_CALL_P (peep2_next_insn (1))
&& peep2_reg_dead_p (2, operands[0])"
[(parallel [(call (mem:QI (match_dup 1))
(match_dup 3))
@@ -11785,7 +11787,9 @@
(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
(call (mem:QI (match_dup 0))
(match_operand 3))]
- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
+ "!TARGET_X32
+ && !ix86_indirect_branch_register
+ && SIBLING_CALL_P (peep2_next_insn (2))
&& peep2_reg_dead_p (3, operands[0])"
[(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
(parallel [(call (mem:QI (match_dup 1))
@@ -11806,7 +11810,7 @@
})
(define_insn "*call_pop"
- [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
+ [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
(match_operand 1))
(set (reg:SI SP_REG)
(plus:SI (reg:SI SP_REG)
@@ -11826,7 +11830,7 @@
[(set_attr "type" "call")])
(define_insn "*sibcall_pop_memory"
- [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
+ [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
(match_operand 1))
(set (reg:SI SP_REG)
(plus:SI (reg:SI SP_REG)
@@ -11878,7 +11882,9 @@
[(set (match_operand:W 0 "register_operand")
(match_operand:W 1 "memory_operand"))
(set (pc) (match_dup 0))]
- "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
+ "!TARGET_X32
+ && !ix86_indirect_branch_register
+ && peep2_reg_dead_p (2, operands[0])"
[(set (pc) (match_dup 1))])
;; Call subroutine, returning value in operand 0
@@ -11928,7 +11934,7 @@
(call (mem:QI (match_operand:W 1 "memory_operand" "m"))
(match_operand 2)))
(unspec [(const_int 0)] UNSPEC_PEEPSIB)]
- "!TARGET_X32"
+ "!TARGET_X32 && !ix86_indirect_branch_register"
"* return ix86_output_call_insn (insn, operands[1]);"
[(set_attr "type" "callv")])
@@ -11938,7 +11944,9 @@
(set (match_operand 2)
(call (mem:QI (match_dup 0))
(match_operand 3)))]
- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
+ "!TARGET_X32
+ && !ix86_indirect_branch_register
+ && SIBLING_CALL_P (peep2_next_insn (1))
&& peep2_reg_dead_p (2, operands[0])"
[(parallel [(set (match_dup 2)
(call (mem:QI (match_dup 1))
@@ -11952,7 +11960,9 @@
(set (match_operand 2)
(call (mem:QI (match_dup 0))
(match_operand 3)))]
- "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
+ "!TARGET_X32
+ && !ix86_indirect_branch_register
+ && SIBLING_CALL_P (peep2_next_insn (2))
&& peep2_reg_dead_p (3, operands[0])"
[(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
(parallel [(set (match_dup 2)
@@ -11976,7 +11986,7 @@
(define_insn "*call_value_pop"
[(set (match_operand 0)
- (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
+ (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
(match_operand 2)))
(set (reg:SI SP_REG)
(plus:SI (reg:SI SP_REG)
Index: b/src/gcc/config/i386/i386.opt
===================================================================
--- a/src/gcc/config/i386/i386.opt
+++ b/src/gcc/config/i386/i386.opt
@@ -900,3 +900,7 @@ Enum(indirect_branch) String(thunk-inlin
EnumValue
Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern)
+
+mindirect-branch-register
+Target Report Var(ix86_indirect_branch_register) Init(0)
+Force indirect call and jump via register.
Index: b/src/gcc/config/i386/predicates.md
===================================================================
--- a/src/gcc/config/i386/predicates.md
+++ b/src/gcc/config/i386/predicates.md
@@ -607,7 +607,8 @@
;; Test for a valid operand for indirect branch.
(define_predicate "indirect_branch_operand"
(ior (match_operand 0 "register_operand")
- (and (not (match_test "TARGET_X32"))
+ (and (not (match_test "ix86_indirect_branch_register"))
+ (not (match_test "TARGET_X32"))
(match_operand 0 "memory_operand"))))
;; Test for a valid operand for a call instruction.
@@ -616,7 +617,8 @@
(ior (match_test "constant_call_address_operand
(op, mode == VOIDmode ? mode : Pmode)")
(match_operand 0 "call_register_no_elim_operand")
- (and (not (match_test "TARGET_X32"))
+ (and (not (match_test "ix86_indirect_branch_register"))
+ (not (match_test "TARGET_X32"))
(match_operand 0 "memory_operand"))))
;; Similarly, but for tail calls, in which we cannot allow memory references.
@@ -624,7 +626,8 @@
(ior (match_test "constant_call_address_operand
(op, mode == VOIDmode ? mode : Pmode)")
(match_operand 0 "register_no_elim_operand")
- (and (not (match_test "TARGET_X32"))
+ (and (not (match_test "ix86_indirect_branch_register"))
+ (not (match_test "TARGET_X32"))
(match_operand 0 "sibcall_memory_operand"))))
;; Match exactly zero.
Index: b/src/gcc/doc/invoke.texi
===================================================================
--- a/src/gcc/doc/invoke.texi
+++ b/src/gcc/doc/invoke.texi
@@ -1091,7 +1091,8 @@ See RS/6000 and PowerPC Options.
-msse2avx -mfentry -mrecord-mcount -mnop-mcount -m8bit-idiv @gol
-mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol
-malign-data=@var{type} -mstack-protector-guard=@var{guard} @gol
--mindirect-branch=@var{choice} -mfunction-return=@var{choice}}
+-mindirect-branch=@var{choice} -mfunction-return=@var{choice} @gol
+-mindirect-branch-register}
@emph{x86 Windows Options}
@gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol
@@ -24040,6 +24041,10 @@ object file. You can control this behav
using the function attribute @code{function_return}.
@xref{Function Attributes}.
+@item -mindirect-branch-register
+@opindex -mindirect-branch-register
+Force indirect call and jump via register.
+
@end table
@c man end
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
void func0 (void);
void func1 (void);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */
void func0 (void);
void func1 (void);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target { ! x32 } } } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */
void (*dispatch) (char *);
char buf[10];
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target { ! x32 } } } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */
void (*dispatch) (char *);
char buf[10];
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
void func0 (void);
void func1 (void);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
typedef void (*dispatch_t)(long offset);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
void func0 (void);
void func1 (void);
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c
===================================================================
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-register -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch;
+
+void
+male_indirect_jump (long offset)
+{
+ dispatch(offset);
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "mov\[ \t\](%eax|%rax), \\((%esp|%rsp)\\)" } } */
+/* { dg-final { scan-assembler {\tpause} } } */
+/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
+/* { dg-final { scan-assembler-not "__x86_indirect_thunk\n" } } */
+/* { dg-final { scan-assembler-not "__x86_indirect_thunk_bnd\n" } } */
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c
===================================================================
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mindirect-branch=thunk-inline -mindirect-branch-register -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch;
+
+void
+male_indirect_jump (long offset)
+{
+ dispatch(offset);
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "mov\[ \t\](%eax|%rax), \\((%esp|%rsp)\\)" } } */
+/* { dg-final { scan-assembler {\tpause} } } */
+/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
+/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
Index: b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c
===================================================================
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mindirect-branch=thunk-extern -mindirect-branch-register -fno-pic" } */
+
+typedef void (*dispatch_t)(long offset);
+
+dispatch_t dispatch;
+
+void
+male_indirect_jump (long offset)
+{
+ dispatch(offset);
+}
+
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
+/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
+/* { dg-final { scan-assembler-not {\t(pause|pause|nop)} } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
Index: b/src/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
+++ b/src/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */
extern void (*bar) (void);
Index: b/src/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
+++ b/src/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=thunk-extern -mindirect-branch=thunk -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=thunk-extern -mindirect-branch=thunk -fno-pic" } */
extern void (*bar) (void);
Index: b/src/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
+++ b/src/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
extern void (*bar) (void);
Index: b/src/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
+++ b/src/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */
extern void (*bar) (void);
extern int foo (void) __attribute__ ((function_return("thunk")));
Index: b/src/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
+++ b/src/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
extern void (*bar) (void);
Index: b/src/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
+++ b/src/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=keep -fno-pic" } */
extern void (*bar) (void);
Index: b/src/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
===================================================================
--- a/src/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
+++ b/src/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mfunction-return=thunk -mindirect-branch=thunk -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=thunk -mindirect-branch=thunk -fno-pic" } */
extern void (*bar) (void);

View file

@ -0,0 +1,139 @@
From 8a47615dd04a02fdae9691f5ad73fd5a5530c156 Mon Sep 17 00:00:00 2001
From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Tue, 16 Jan 2018 11:19:51 +0000
Subject: [PATCH 8/9] x86: Add 'V' register operand modifier
Add 'V', a special modifier which prints the name of the full integer
register without '%'. For
extern void (*func_p) (void);
void
foo (void)
{
asm ("call __x86_indirect_thunk_%V0" : : "a" (func_p));
}
it generates:
foo:
movq func_p(%rip), %rax
call __x86_indirect_thunk_rax
ret
gcc/
Backport from mainline
2018-01-14 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/i386.c (print_reg): Print the name of the full
integer register without '%'.
(ix86_print_operand): Handle 'V'.
* doc/extend.texi: Document 'V' modifier.
gcc/testsuite/
Backport from mainline
2018-01-14 H.J. Lu <hongjiu.lu@intel.com>
* gcc.target/i386/indirect-thunk-register-4.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@256736 138bc75d-0d04-0410-961f-82ee72b054a4
---
gcc/ChangeLog | 10 ++++++++++
gcc/config/i386/i386.c | 13 ++++++++++++-
gcc/doc/extend.texi | 3 +++
gcc/testsuite/ChangeLog | 7 +++++++
gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c | 13 +++++++++++++
5 files changed, 45 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 8fb8902..1bbdd0c 100644
--- a/src/gcc/config/i386/i386.c
+++ b/src/gcc/config/i386/i386.c
@@ -17941,6 +17941,7 @@ put_condition_code (enum rtx_code code, machine_mode mode, bool reverse,
If CODE is 'h', pretend the reg is the 'high' byte register.
If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op.
If CODE is 'd', duplicate the operand for AVX instruction.
+ If CODE is 'V', print naked full integer register name without %.
*/
void
@@ -17951,7 +17952,7 @@ print_reg (rtx x, int code, FILE *file)
unsigned int regno;
bool duplicated = code == 'd' && TARGET_AVX;
- if (ASSEMBLER_DIALECT == ASM_ATT)
+ if (ASSEMBLER_DIALECT == ASM_ATT && code != 'V')
putc ('%', file);
if (x == pc_rtx)
@@ -17999,6 +18000,14 @@ print_reg (rtx x, int code, FILE *file)
else
code = GET_MODE_SIZE (GET_MODE (x));
+ if (code == 'V')
+ {
+ if (GENERAL_REGNO_P (regno))
+ code = GET_MODE_SIZE (word_mode);
+ else
+ error ("'V' modifier on non-integer register");
+ }
+
/* Irritatingly, AMD extended registers use different naming convention
from the normal registers: "r%d[bwd]" */
if (REX_INT_REGNO_P (regno))
@@ -18118,6 +18127,7 @@ print_reg (rtx x, int code, FILE *file)
& -- print some in-use local-dynamic symbol name.
H -- print a memory address offset by 8; used for sse high-parts
Y -- print condition for XOP pcom* instruction.
+ V -- print naked full integer register name without %.
+ -- print a branch hint as 'cs' or 'ds' prefix
; -- print a semicolon (after prefixes due to bug in older gas).
~ -- print "i" if TARGET_AVX2, "f" otherwise.
@@ -18342,6 +18352,7 @@ ix86_print_operand (FILE *file, rtx x, int code)
case 'X':
case 'P':
case 'p':
+ case 'V':
break;
case 's':
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 46e0a36..9db9e0e 100644
--- a/src/gcc/doc/extend.texi
+++ b/src/gcc/doc/extend.texi
@@ -8778,6 +8778,9 @@ The table below shows the list of supported modifiers and their effects.
@tab @code{2}
@end multitable
+@code{V} is a special modifier which prints the name of the full integer
+register without @code{%}.
+
@anchor{x86floatingpointasmoperands}
@subsubsection x86 Floating-Point @code{asm} Operands
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c
new file mode 100644
index 0000000..f0cd9b7
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mindirect-branch=keep -fno-pic" } */
+
+extern void (*func_p) (void);
+
+void
+foo (void)
+{
+ asm("call __x86_indirect_thunk_%V0" : : "a" (func_p));
+}
+
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_eax" { target ia32 } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_rax" { target { ! ia32 } } } } */
--
2.7.4

View file

@ -0,0 +1,304 @@
From 5d1c53c6fd593de2360c1a2ae44ebf5fa3c5263b Mon Sep 17 00:00:00 2001
From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Tue, 16 Jan 2018 11:22:01 +0000
Subject: [PATCH 9/9] x86: Disallow -mindirect-branch=/-mfunction-return= with
-mcmodel=large
Since the thunk function may not be reachable in large code model,
-mcmodel=large is incompatible with -mindirect-branch=thunk,
-mindirect-branch=thunk-extern, -mfunction-return=thunk and
-mfunction-return=thunk-extern. Issue an error when they are used with
-mcmodel=large.
gcc/
Backport from mainline
2018-01-14 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/i386.c (ix86_set_indirect_branch_type): Disallow
-mcmodel=large with -mindirect-branch=thunk,
-mindirect-branch=thunk-extern, -mfunction-return=thunk and
-mfunction-return=thunk-extern.
* doc/invoke.texi: Document -mcmodel=large is incompatible with
-mindirect-branch=thunk, -mindirect-branch=thunk-extern,
-mfunction-return=thunk and -mfunction-return=thunk-extern.
gcc/testsuite/
Backport from mainline
2018-01-14 H.J. Lu <hongjiu.lu@intel.com>
* gcc.target/i386/indirect-thunk-10.c: New test.
* gcc.target/i386/indirect-thunk-8.c: Likewise.
* gcc.target/i386/indirect-thunk-9.c: Likewise.
* gcc.target/i386/indirect-thunk-attr-10.c: Likewise.
* gcc.target/i386/indirect-thunk-attr-11.c: Likewise.
* gcc.target/i386/indirect-thunk-attr-9.c: Likewise.
* gcc.target/i386/ret-thunk-17.c: Likewise.
* gcc.target/i386/ret-thunk-18.c: Likewise.
* gcc.target/i386/ret-thunk-19.c: Likewise.
* gcc.target/i386/ret-thunk-20.c: Likewise.
* gcc.target/i386/ret-thunk-21.c: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@256737 138bc75d-0d04-0410-961f-82ee72b054a4
---
gcc/ChangeLog | 13 +++++++++++
gcc/config/i386/i386.c | 26 ++++++++++++++++++++++
gcc/doc/invoke.texi | 11 +++++++++
gcc/testsuite/ChangeLog | 17 ++++++++++++++
gcc/testsuite/gcc.target/i386/indirect-thunk-10.c | 7 ++++++
gcc/testsuite/gcc.target/i386/indirect-thunk-8.c | 7 ++++++
gcc/testsuite/gcc.target/i386/indirect-thunk-9.c | 7 ++++++
.../gcc.target/i386/indirect-thunk-attr-10.c | 9 ++++++++
.../gcc.target/i386/indirect-thunk-attr-11.c | 9 ++++++++
.../gcc.target/i386/indirect-thunk-attr-9.c | 9 ++++++++
gcc/testsuite/gcc.target/i386/ret-thunk-17.c | 7 ++++++
gcc/testsuite/gcc.target/i386/ret-thunk-18.c | 8 +++++++
gcc/testsuite/gcc.target/i386/ret-thunk-19.c | 8 +++++++
gcc/testsuite/gcc.target/i386/ret-thunk-20.c | 9 ++++++++
gcc/testsuite/gcc.target/i386/ret-thunk-21.c | 9 ++++++++
15 files changed, 156 insertions(+)
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-10.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-8.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-9.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c
create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-17.c
create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-18.c
create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-19.c
create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-20.c
create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-21.c
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 1bbdd0c..e758387 100644
--- a/src/gcc/config/i386/i386.c
+++ b/src/gcc/config/i386/i386.c
@@ -7187,6 +7187,19 @@ ix86_set_indirect_branch_type (tree fndecl)
}
else
cfun->machine->indirect_branch_type = ix86_indirect_branch;
+
+ /* -mcmodel=large is not compatible with -mindirect-branch=thunk
+ nor -mindirect-branch=thunk-extern. */
+ if ((ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
+ && ((cfun->machine->indirect_branch_type
+ == indirect_branch_thunk_extern)
+ || (cfun->machine->indirect_branch_type
+ == indirect_branch_thunk)))
+ error ("%<-mindirect-branch=%s%> and %<-mcmodel=large%> are not "
+ "compatible",
+ ((cfun->machine->indirect_branch_type
+ == indirect_branch_thunk_extern)
+ ? "thunk-extern" : "thunk"));
}
if (cfun->machine->function_return_type == indirect_branch_unset)
@@ -7212,6 +7225,19 @@ ix86_set_indirect_branch_type (tree fndecl)
}
else
cfun->machine->function_return_type = ix86_function_return;
+
+ /* -mcmodel=large is not compatible with -mfunction-return=thunk
+ nor -mfunction-return=thunk-extern. */
+ if ((ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
+ && ((cfun->machine->function_return_type
+ == indirect_branch_thunk_extern)
+ || (cfun->machine->function_return_type
+ == indirect_branch_thunk)))
+ error ("%<-mfunction-return=%s%> and %<-mcmodel=large%> are not "
+ "compatible",
+ ((cfun->machine->function_return_type
+ == indirect_branch_thunk_extern)
+ ? "thunk-extern" : "thunk"));
}
}
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 1e572b1..6f3c344 100644
--- a/src/gcc/doc/invoke.texi
+++ b/src/gcc/doc/invoke.texi
@@ -25699,6 +25699,11 @@ to external call and return thunk provided in a separate object file.
You can control this behavior for a specific function by using the
function attribute @code{indirect_branch}. @xref{Function Attributes}.
+Note that @option{-mcmodel=large} is incompatible with
+@option{-mindirect-branch=thunk} nor
+@option{-mindirect-branch=thunk-extern} since the thunk function may
+not be reachable in large code model.
+
@item -mfunction-return=@var{choice}
@opindex -mfunction-return
Convert function return with @var{choice}. The default is @samp{keep},
@@ -25710,6 +25715,12 @@ object file. You can control this behavior for a specific function by
using the function attribute @code{function_return}.
@xref{Function Attributes}.
+Note that @option{-mcmodel=large} is incompatible with
+@option{-mfunction-return=thunk} nor
+@option{-mfunction-return=thunk-extern} since the thunk function may
+not be reachable in large code model.
+
+
@item -mindirect-branch-register
@opindex -mindirect-branch-register
Force indirect call and jump via register.
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-10.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-10.c
new file mode 100644
index 0000000..a0674bd
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-10.c
@@ -0,0 +1,7 @@
+/* { dg-do compile { target { lp64 } } } */
+/* { dg-options "-O2 -mindirect-branch=thunk-inline -mfunction-return=keep -mcmodel=large" } */
+
+void
+bar (void)
+{
+}
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-8.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-8.c
new file mode 100644
index 0000000..7a80a89
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-8.c
@@ -0,0 +1,7 @@
+/* { dg-do compile { target { lp64 } } } */
+/* { dg-options "-O2 -mindirect-branch=thunk -mfunction-return=keep -mcmodel=large" } */
+
+void
+bar (void)
+{ /* { dg-error "'-mindirect-branch=thunk' and '-mcmodel=large' are not compatible" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-9.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-9.c
new file mode 100644
index 0000000..d4d45c5
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-9.c
@@ -0,0 +1,7 @@
+/* { dg-do compile { target { lp64 } } } */
+/* { dg-options "-O2 -mindirect-branch=thunk-extern -mfunction-return=keep -mcmodel=large" } */
+
+void
+bar (void)
+{ /* { dg-error "'-mindirect-branch=thunk-extern' and '-mcmodel=large' are not compatible" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c
new file mode 100644
index 0000000..3a2aead
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { lp64 } } } */
+/* { dg-options "-O2 -mindirect-branch=keep -mfunction-return=keep -mcmodel=large" } */
+/* { dg-additional-options "-fPIC" { target fpic } } */
+
+__attribute__ ((indirect_branch("thunk-extern")))
+void
+bar (void)
+{ /* { dg-error "'-mindirect-branch=thunk-extern' and '-mcmodel=large' are not compatible" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c
new file mode 100644
index 0000000..8e52f03
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { lp64 } } } */
+/* { dg-options "-O2 -mindirect-branch=keep -mfunction-return=keep -mcmodel=large" } */
+/* { dg-additional-options "-fPIC" { target fpic } } */
+
+__attribute__ ((indirect_branch("thunk-inline")))
+void
+bar (void)
+{
+}
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c
new file mode 100644
index 0000000..bdaa4f6
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { lp64 } } } */
+/* { dg-options "-O2 -mindirect-branch=keep -mfunction-return=keep -mcmodel=large" } */
+/* { dg-additional-options "-fPIC" { target fpic } } */
+
+__attribute__ ((indirect_branch("thunk")))
+void
+bar (void)
+{ /* { dg-error "'-mindirect-branch=thunk' and '-mcmodel=large' are not compatible" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-17.c b/gcc/testsuite/gcc.target/i386/ret-thunk-17.c
new file mode 100644
index 0000000..0605e2c
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/ret-thunk-17.c
@@ -0,0 +1,7 @@
+/* { dg-do compile { target { lp64 } } } */
+/* { dg-options "-O2 -mfunction-return=thunk -mindirect-branch=keep -mcmodel=large" } */
+
+void
+bar (void)
+{ /* { dg-error "'-mfunction-return=thunk' and '-mcmodel=large' are not compatible" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-18.c b/gcc/testsuite/gcc.target/i386/ret-thunk-18.c
new file mode 100644
index 0000000..307019d
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/ret-thunk-18.c
@@ -0,0 +1,8 @@
+/* { dg-do compile { target { lp64 } } } */
+/* { dg-options "-O2 -mfunction-return=thunk-extern -mindirect-branch=keep -mcmodel=large" } */
+/* { dg-additional-options "-fPIC" { target fpic } } */
+
+void
+bar (void)
+{ /* { dg-error "'-mfunction-return=thunk-extern' and '-mcmodel=large' are not compatible" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-19.c b/gcc/testsuite/gcc.target/i386/ret-thunk-19.c
new file mode 100644
index 0000000..772617f
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/ret-thunk-19.c
@@ -0,0 +1,8 @@
+/* { dg-do compile { target { lp64 } } } */
+/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -mcmodel=large" } */
+
+__attribute__ ((function_return("thunk")))
+void
+bar (void)
+{ /* { dg-error "'-mfunction-return=thunk' and '-mcmodel=large' are not compatible" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-20.c b/gcc/testsuite/gcc.target/i386/ret-thunk-20.c
new file mode 100644
index 0000000..1e9f9bd
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/ret-thunk-20.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { lp64 } } } */
+/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -mcmodel=large" } */
+/* { dg-additional-options "-fPIC" { target fpic } } */
+
+__attribute__ ((function_return("thunk-extern")))
+void
+bar (void)
+{ /* { dg-error "'-mfunction-return=thunk-extern' and '-mcmodel=large' are not compatible" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-21.c b/gcc/testsuite/gcc.target/i386/ret-thunk-21.c
new file mode 100644
index 0000000..eea07f7
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/ret-thunk-21.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { lp64 } } } */
+/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -mcmodel=large" } */
+/* { dg-additional-options "-fPIC" { target fpic } } */
+
+__attribute__ ((function_return("thunk-inline")))
+void
+bar (void)
+{
+}
--
2.7.4

View file

@ -1,3 +1,5 @@
%global _default_patch_fuzz 1
# functions with printf format attribute but with special parser and also
# receiving non constant format strings
%define Werror_cflags %{nil}
@ -18,9 +20,9 @@
%endif
%define system_compiler 1
%define majorver 5
%define branch 5.4
%define ver %{branch}.1
%define linaro 2017.05
%define branch 5.5
%define ver %{branch}.0
%define linaro 2017.10
%define linaro_spin %nil
%define alternatives /usr/sbin/update-alternatives
%define gcclibexecdir %{_libexecdir}/gcc/%{_target_platform}/%{ver}
@ -204,7 +206,7 @@ Name: gcc
%else
Name: gcc%{branch}
%endif
Release: 1
Release: 2
License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ with exceptions and LGPLv2+ and BSD
Group: Development/C
Url: http://gcc.gnu.org/
@ -254,6 +256,16 @@ Patch13: Gcc-4.8.2-arm-thumb2-CASE_VECTOR_SHORTEN_MODE.patch
# Fix for fileline_fn callback being NULL in libbacktrace sometimes
Patch15: gcc-4.9.1-libbacktrace-fix-null-callback.patch
Patch20: 0001-i386-Move-struct-ix86_frame-to-machine_function.diff
Patch21: 0002-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.diff
Patch22: 0003-i386-More-use-reference-of-struct-ix86_frame-to-avoi.diff
Patch23: 0004-i386-Don-t-use-reference-of-struct-ix86_frame.diff
Patch24: 0005-x86-Add-mindirect-branch.diff
Patch25: 0006-x86-Add-mfunction-return.diff
Patch26: 0007-x86-Add-mindirect-branch-register.diff
Patch27: 0008-x86-Add-V-register-operand-modifier.diff
Patch28: 0009-x86-Disallow-mindirect-branch-mfunction-return-with-.diff
BuildRequires: binutils >= 2.20.51.0.2
BuildRequires: dejagnu
BuildRequires: elfutils-devel >= 0.147
@ -2217,6 +2229,16 @@ Static liblsan.
%patch13 -p1 -b .short
%patch15 -p1 -b .libbacktrace
%patch20 -p2
%patch21 -p2
%patch22 -p2
%patch23 -p2
%patch24 -p2
%patch25 -p2
%patch26 -p2
%patch27 -p2
%patch28 -p2
aclocal -I config
autoconf