0

Initial commit

This commit is contained in:
eleksir
2023-11-19 18:01:40 +03:00
commit 80ec8a7529
586 changed files with 29486 additions and 0 deletions

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

View File

@@ -0,0 +1,279 @@
From c6b72be421ded17e0c156070ba6e90aa6c335ed6 Mon Sep 17 00:00:00 2001
From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Tue, 16 Jan 2018 10:59:42 +0000
Subject: [PATCH 5/9] x86: Add -mindirect-branch= (documentation)
Add -mindirect-branch= option to convert indirect call and jump to call
and return thunks. The default is 'keep', which keeps indirect call and
jump unmodified. 'thunk' converts indirect call and jump to call and
return thunk. 'thunk-inline' converts indirect call and jump to inlined
call and return thunk. 'thunk-extern' converts indirect call and jump 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 indirect_branch.
2 kinds of thunks are geneated. Memory thunk where the function address
is at the top of the stack:
__x86_indirect_thunk:
call L2
L1:
pause
lfence
jmp L1
L2:
lea 8(%rsp), %rsp|lea 4(%esp), %esp
ret
Indirect jmp via memory, "jmp mem", is converted to
push memory
jmp __x86_indirect_thunk
Indirect call via memory, "call mem", is converted to
jmp L2
L1:
push [mem]
jmp __x86_indirect_thunk
L2:
call L1
Register thunk where the function address is in a register, reg:
__x86_indirect_thunk_reg:
call L2
L1:
pause
lfence
jmp L1
L2:
movq %reg, (%rsp)|movl %reg, (%esp)
ret
where reg is one of (r|e)ax, (r|e)dx, (r|e)cx, (r|e)bx, (r|e)si, (r|e)di,
(r|e)bp, r8, r9, r10, r11, r12, r13, r14 and r15.
Indirect jmp via register, "jmp reg", is converted to
jmp __x86_indirect_thunk_reg
Indirect call via register, "call reg", is converted to
call __x86_indirect_thunk_reg
gcc/
Backport from mainline
* config/i386/i386-opts.h (indirect_branch): New.
* config/i386/i386-protos.h (ix86_output_indirect_jmp): Likewise.
* config/i386/i386.c (ix86_using_red_zone): Disallow red-zone
with local indirect jump when converting indirect call and jump.
(ix86_set_indirect_branch_type): New.
(ix86_set_current_function): Call ix86_set_indirect_branch_type.
(indirectlabelno): New.
(indirect_thunk_needed): Likewise.
(indirect_thunk_bnd_needed): Likewise.
(indirect_thunks_used): Likewise.
(indirect_thunks_bnd_used): Likewise.
(INDIRECT_LABEL): Likewise.
(indirect_thunk_name): Likewise.
(output_indirect_thunk): Likewise.
(output_indirect_thunk_function): Likewise.
(ix86_output_indirect_branch_via_reg): Likewise.
(ix86_output_indirect_branch_via_push): Likewise.
(ix86_output_indirect_branch): Likewise.
(ix86_output_indirect_jmp): Likewise.
(ix86_code_end): Call output_indirect_thunk_function if needed.
(ix86_output_call_insn): Call ix86_output_indirect_branch if
needed.
(ix86_handle_fndecl_attribute): Handle indirect_branch.
(ix86_attribute_table): Add indirect_branch.
* config/i386/i386.h (machine_function): Add indirect_branch_type
and has_local_indirect_jump.
* config/i386/i386.md (indirect_jump): Set has_local_indirect_jump
to true.
(tablejump): Likewise.
(*indirect_jump): Use ix86_output_indirect_jmp.
(*tablejump_1): Likewise.
(simple_return_indirect_internal): Likewise.
* config/i386/i386.opt (mindirect-branch=): New option.
(indirect_branch): New.
(keep): Likewise.
(thunk): Likewise.
(thunk-inline): Likewise.
(thunk-extern): Likewise.
* doc/extend.texi: Document indirect_branch function attribute.
* doc/invoke.texi: Document -mindirect-branch= option.
gcc/testsuite/
Backport from mainline
* gcc.target/i386/indirect-thunk-1.c: New test.
* 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-attr-8.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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@256732 138bc75d-0d04-0410-961f-82ee72b054a4
[UBUNTU NOTES: Updated for gcc-5.4 to include defines for
FIRST_INT_REG, LAST_INT_REG, and LEGACY_INT_REGNO_P as defined in
https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=222269.
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, tyhicks]
---
src/gcc/config/i386/i386-opts.h | 13
src/gcc/config/i386/i386-protos.h | 1
src/gcc/config/i386/i386.c | 621 +++++++++++-
src/gcc/config/i386/i386.h | 12
src/gcc/config/i386/i386.md | 26
src/gcc/config/i386/i386.opt | 20
src/gcc/doc/extend.texi | 10
src/gcc/doc/invoke.texi | 14
src/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 20
src/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 20
src/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 21
src/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 21
src/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 44
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | 23
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | 21
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | 23
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | 22
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | 22
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | 21
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | 44
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c | 42
src/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | 20
src/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | 21
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | 19
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | 19
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | 20
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | 20
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | 43
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | 20
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | 20
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | 21
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | 21
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | 44
33 files changed, 1334 insertions(+), 15 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
Index: b/src/gcc/doc/extend.texi
===================================================================
--- a/src/gcc/doc/extend.texi
+++ b/src/gcc/doc/extend.texi
@@ -4119,6 +4119,16 @@ Specify which floating-point unit to use
@code{target("fpmath=sse,387")} option must be specified as
@code{target("fpmath=sse+387")} because the comma would separate
different options.
+
+@item indirect_branch("@var{choice}")
+@cindex @code{indirect_branch} function attribute, x86
+On x86 targets, the @code{indirect_branch} attribute causes the compiler
+to convert indirect call and jump with @var{choice}. @samp{keep}
+keeps indirect call and jump unmodified. @samp{thunk} converts indirect
+call and jump to call and return thunk. @samp{thunk-inline} converts
+indirect call and jump to inlined call and return thunk.
+@samp{thunk-extern} converts indirect call and jump to external call
+and return thunk provided in a separate object file.
@end table
On the PowerPC, the following options are allowed:
Index: b/src/gcc/doc/invoke.texi
===================================================================
--- a/src/gcc/doc/invoke.texi
+++ b/src/gcc/doc/invoke.texi
@@ -1090,7 +1090,8 @@ See RS/6000 and PowerPC Options.
-m32 -m64 -mx32 -m16 -mlarge-data-threshold=@var{num} @gol
-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}}
+-malign-data=@var{type} -mstack-protector-guard=@var{guard} @gol
+-mindirect-branch=@var{choice}}
@emph{x86 Windows Options}
@gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol
@@ -24017,6 +24018,17 @@ The default value of this option is enab
of the option is @option{-fno-sync-libcalls}. This option is used in
the implementation of the @file{libatomic} runtime library.
+@item -mindirect-branch=@var{choice}
+@opindex -mindirect-branch
+Convert indirect call and jump with @var{choice}. The default is
+@samp{keep}, which keeps indirect call and jump unmodified.
+@samp{thunk} converts indirect call and jump to call and return thunk.
+@samp{thunk-inline} converts indirect call and jump to inlined call
+and return thunk. @samp{thunk-extern} converts indirect call and jump
+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}.
+
@end table
@c man end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,300 @@
From 357311dd400f7f72d2132f2f94161ece39bf08c6 Mon Sep 17 00:00:00 2001
From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Tue, 16 Jan 2018 11:10:44 +0000
Subject: [PATCH 6/9] x86: Add -mfunction-return=
Add -mfunction-return= option to convert function return to call and
return thunks. The default is 'keep', which keeps function return
unmodified. 'thunk' converts function return to call and return thunk.
'thunk-inline' converts function return to inlined call and return thunk.
'thunk-extern' converts function return 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 function_return.
Function return thunk is the same as memory thunk for -mindirect-branch=
where the return address is at the top of the stack:
__x86_return_thunk:
call L2
L1:
pause
lfence
jmp L1
L2:
lea 8(%rsp), %rsp|lea 4(%esp), %esp
ret
and function return becomes
jmp __x86_return_thunk
-mindirect-branch= tests are updated with -mfunction-return=keep to
avoid false test failures when -mfunction-return=thunk is added to
RUNTESTFLAGS for "make check".
gcc/
Backport from mainline
2018-01-14 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/i386-protos.h (ix86_output_function_return): New.
* config/i386/i386.c (ix86_set_indirect_branch_type): Also
set function_return_type.
(indirect_thunk_name): Add ret_p to indicate thunk for function
return.
(output_indirect_thunk_function): Pass false to
indirect_thunk_name.
(ix86_output_indirect_branch_via_reg): Likewise.
(ix86_output_indirect_branch_via_push): Likewise.
(output_indirect_thunk_function): Create alias for function
return thunk if regno < 0.
(ix86_output_function_return): New function.
(ix86_handle_fndecl_attribute): Handle function_return.
(ix86_attribute_table): Add function_return.
* config/i386/i386.h (machine_function): Add
function_return_type.
* config/i386/i386.md (simple_return_internal): Use
ix86_output_function_return.
(simple_return_internal_long): Likewise.
* config/i386/i386.opt (mfunction-return=): New option.
(indirect_branch): Mention -mfunction-return=.
* doc/extend.texi: Document function_return function attribute.
* doc/invoke.texi: Document -mfunction-return= 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
-mfunction-return=keep.
* 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-attr-8.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-1.c: New test.
* 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-16.c: Likewise.
* gcc.target/i386/ret-thunk-2.c: Likewise.
* gcc.target/i386/ret-thunk-3.c: Likewise.
* gcc.target/i386/ret-thunk-4.c: Likewise.
* gcc.target/i386/ret-thunk-5.c: Likewise.
* gcc.target/i386/ret-thunk-6.c: Likewise.
* gcc.target/i386/ret-thunk-7.c: Likewise.
* gcc.target/i386/ret-thunk-8.c: Likewise.
* gcc.target/i386/ret-thunk-9.c: Likewise.
i386: Don't use ASM_OUTPUT_DEF for TARGET_MACHO
ASM_OUTPUT_DEF isn't defined for TARGET_MACHO. Use ASM_OUTPUT_LABEL to
generate the __x86_return_thunk label, instead of the set directive.
Update testcase to remove the __x86_return_thunk label check. Since
-fno-pic is ignored on Darwin, update testcases to sscan or "push"
only on Linux.
gcc/
Backport from mainline
2018-01-15 H.J. Lu <hongjiu.lu@intel.com>
PR target/83839
* config/i386/i386.c (output_indirect_thunk_function): Use
ASM_OUTPUT_LABEL, instead of ASM_OUTPUT_DEF, for TARGET_MACHO
for __x86.return_thunk.
gcc/testsuite/
Backport from mainline
2018-01-15 H.J. Lu <hongjiu.lu@intel.com>
PR target/83839
* gcc.target/i386/indirect-thunk-1.c: Scan for "push" only on
Linux.
* 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-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-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-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-7.c: Likewise.
* gcc.target/i386/indirect-thunk-register-1.c: Likewise.
* gcc.target/i386/indirect-thunk-register-3.c: Likewise.
* gcc.target/i386/indirect-thunk-register-4.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: Don't check the
__x86_return_thunk label.
Scan for "push" only for Linux.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@256734 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/i386-protos.h | 1
src/gcc/config/i386/i386.c | 152 +++++++++++-
src/gcc/config/i386/i386.h | 3
src/gcc/config/i386/i386.md | 9
src/gcc/config/i386/i386.opt | 6
src/gcc/doc/extend.texi | 9
src/gcc/doc/invoke.texi | 13 -
src/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 4
src/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 4
src/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 4
src/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 4
src/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 4
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | 4
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | 4
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | 4
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | 4
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | 4
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | 4
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | 4
src/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c | 2
src/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | 4
src/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | 4
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | 4
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | 4
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | 4
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | 4
src/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | 4
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | 4
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | 4
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | 4
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | 4
src/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | 4
src/gcc/testsuite/gcc.target/i386/ret-thunk-1.c | 13 +
src/gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 23 +
src/gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 23 +
src/gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 22 +
src/gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 22 +
src/gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 22 +
src/gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 22 +
src/gcc/testsuite/gcc.target/i386/ret-thunk-16.c | 18 +
src/gcc/testsuite/gcc.target/i386/ret-thunk-2.c | 13 +
src/gcc/testsuite/gcc.target/i386/ret-thunk-3.c | 12
src/gcc/testsuite/gcc.target/i386/ret-thunk-4.c | 12
src/gcc/testsuite/gcc.target/i386/ret-thunk-5.c | 15 +
src/gcc/testsuite/gcc.target/i386/ret-thunk-6.c | 14 +
src/gcc/testsuite/gcc.target/i386/ret-thunk-7.c | 13 +
src/gcc/testsuite/gcc.target/i386/ret-thunk-8.c | 14 +
src/gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 24 +
48 files changed, 507 insertions(+), 66 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-1.c
create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-10.c
create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-11.c
create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-12.c
create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-13.c
create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-14.c
create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-15.c
create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-16.c
create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-2.c
create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-3.c
create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-4.c
create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-5.c
create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-6.c
create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-7.c
create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-8.c
create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-9.c
Index: b/src/gcc/doc/extend.texi
===================================================================
--- a/src/gcc/doc/extend.texi
+++ b/src/gcc/doc/extend.texi
@@ -4129,6 +4129,15 @@ call and jump to call and return thunk.
indirect call and jump to inlined call and return thunk.
@samp{thunk-extern} converts indirect call and jump to external call
and return thunk provided in a separate object file.
+
+@item function_return("@var{choice}")
+@cindex @code{function_return} function attribute, x86
+On x86 targets, the @code{function_return} attribute causes the compiler
+to convert function return with @var{choice}. @samp{keep} keeps function
+return unmodified. @samp{thunk} converts function return to call and
+return thunk. @samp{thunk-inline} converts function return to inlined
+call and return thunk. @samp{thunk-extern} converts function return to
+external call and return thunk provided in a separate object file.
@end table
On the PowerPC, the following options are allowed:
Index: b/src/gcc/doc/invoke.texi
===================================================================
--- a/src/gcc/doc/invoke.texi
+++ b/src/gcc/doc/invoke.texi
@@ -1091,7 +1091,7 @@ 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}}
+-mindirect-branch=@var{choice} -mfunction-return=@var{choice}}
@emph{x86 Windows Options}
@gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol
@@ -24029,6 +24029,17 @@ to external call and return thunk provid
You can control this behavior for a specific function by using the
function attribute @code{indirect_branch}. @xref{Function Attributes}.
+@item -mfunction-return=@var{choice}
+@opindex -mfunction-return
+Convert function return with @var{choice}. The default is @samp{keep},
+which keeps function return unmodified. @samp{thunk} converts function
+return to call and return thunk. @samp{thunk-inline} converts function
+return to inlined call and return thunk. @samp{thunk-extern} converts
+function return 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{function_return}.
+@xref{Function Attributes}.
+
@end table
@c man end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,231 @@
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 (documentation)
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/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

View File

@@ -0,0 +1,812 @@
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/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,65 @@
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 (documentation)
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/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

View File

@@ -0,0 +1,125 @@
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/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,275 @@
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/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

@@ -0,0 +1,102 @@
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/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.

View File

@@ -0,0 +1,27 @@
--- ./gcc/Makefile.in.orig 2010-04-02 02:49:06.000000000 -0500
+++ ./gcc/Makefile.in 2010-08-01 16:55:30.088318841 -0500
@@ -3864,9 +3864,9 @@
chmod a+r $${fix_dir}/limits.h; \
done
# Install the README
- rm -f include-fixed/README
- cp $(srcdir)/../fixincludes/README-fixinc include-fixed/README
- chmod a+r include-fixed/README
+# rm -f include-fixed/README
+# cp $(srcdir)/../fixincludes/README-fixinc include-fixed/README
+# chmod a+r include-fixed/README
$(STAMP) $@
.PHONY: install-gcc-tooldir
@@ -3947,10 +3947,7 @@
(TARGET_MACHINE='$(target)'; srcdir=`cd $(srcdir); ${PWD_COMMAND}`; \
SHELL='$(SHELL)'; MACRO_LIST=`${PWD_COMMAND}`/macro_list ; \
gcc_dir=`${PWD_COMMAND}` ; \
- export TARGET_MACHINE srcdir SHELL MACRO_LIST && \
- cd $(build_objdir)/fixincludes && \
- $(SHELL) ./fixinc.sh "$${gcc_dir}/$${fix_dir}" \
- $(SYSTEM_HEADER_DIR) $(OTHER_FIXINCLUDES_DIRS) ); \
+ export TARGET_MACHINE srcdir SHELL MACRO_LIST ); \
rm -f $${fix_dir}/syslimits.h; \
if [ -f $${fix_dir}/limits.h ]; then \
mv $${fix_dir}/limits.h $${fix_dir}/syslimits.h; \

124
gcc5/patches/gcc.66782.diff Normal file
View File

@@ -0,0 +1,124 @@
Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md (revision 225539)
+++ config/i386/i386.md (working copy)
@@ -108,6 +108,7 @@
UNSPEC_LD_MPIC ; load_macho_picbase
UNSPEC_TRUNC_NOOP
UNSPEC_DIV_ALREADY_SPLIT
+ UNSPEC_MS_TO_SYSV_CALL
UNSPEC_PAUSE
UNSPEC_LEA_ADDR
UNSPEC_XBEGIN_ABORT
@@ -11584,6 +11585,15 @@
"* return ix86_output_call_insn (insn, operands[0]);"
[(set_attr "type" "call")])
+(define_insn "*call_rex64_ms_sysv"
+ [(match_parallel 2 "call_rex64_ms_sysv_operation"
+ [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rBwBz"))
+ (match_operand 1))
+ (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
+ "TARGET_64BIT && !SIBLING_CALL_P (insn)"
+ "* return ix86_output_call_insn (insn, operands[0]);"
+ [(set_attr "type" "call")])
+
(define_insn "*sibcall"
[(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
(match_operand 1))]
@@ -11808,6 +11818,16 @@
(match_dup 3)))
(unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
+(define_insn "*call_value_rex64_ms_sysv"
+ [(match_parallel 3 "call_rex64_ms_sysv_operation"
+ [(set (match_operand 0)
+ (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rBwBz"))
+ (match_operand 2)))
+ (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
+ "TARGET_64BIT && !SIBLING_CALL_P (insn)"
+ "* return ix86_output_call_insn (insn, operands[1]);"
+ [(set_attr "type" "callv")])
+
(define_expand "call_value_pop"
[(parallel [(set (match_operand 0)
(call (match_operand:QI 1)
Index: config/i386/predicates.md
===================================================================
--- config/i386/predicates.md (revision 225533)
+++ config/i386/predicates.md (working copy)
@@ -616,6 +616,36 @@
&& XINT (XEXP (op, 0), 1) == UNSPEC_GOTPCREL);
})
+;; Return true if OP is a call from MS ABI to SYSV ABI function.
+(define_predicate "call_rex64_ms_sysv_operation"
+ (match_code "parallel")
+{
+ unsigned creg_size = ARRAY_SIZE (x86_64_ms_sysv_extra_clobbered_registers);
+ unsigned i;
+
+ if ((unsigned) XVECLEN (op, 0) != creg_size + 2)
+ return false;
+
+ for (i = 0; i < creg_size; i++)
+ {
+ rtx elt = XVECEXP (op, 0, i+2);
+ enum machine_mode mode;
+ unsigned regno;
+
+ if (GET_CODE (elt) != CLOBBER
+ || GET_CODE (SET_DEST (elt)) != REG)
+ return false;
+
+ regno = x86_64_ms_sysv_extra_clobbered_registers[i];
+ mode = SSE_REGNO_P (regno) ? TImode : DImode;
+
+ if (GET_MODE (SET_DEST (elt)) != mode
+ || REGNO (SET_DEST (elt)) != regno)
+ return false;
+ }
+ return true;
+})
+
;; Match exactly zero.
(define_predicate "const0_operand"
(match_code "const_int,const_wide_int,const_double,const_vector")
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c (revision 225533)
+++ config/i386/i386.c (working copy)
@@ -25639,7 +25639,9 @@
rtx callarg2,
rtx pop, bool sibcall)
{
- rtx vec[3];
+ unsigned int const cregs_size
+ = ARRAY_SIZE (x86_64_ms_sysv_extra_clobbered_registers);
+ rtx vec[3 + cregs_size];
rtx use = NULL, call;
unsigned int vec_len = 0;
@@ -25742,16 +25744,18 @@
if (TARGET_64BIT_MS_ABI
&& (!callarg2 || INTVAL (callarg2) != -2))
{
- int const cregs_size
- = ARRAY_SIZE (x86_64_ms_sysv_extra_clobbered_registers);
- int i;
+ unsigned i;
+ vec[vec_len++] = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, const0_rtx),
+ UNSPEC_MS_TO_SYSV_CALL);
+
for (i = 0; i < cregs_size; i++)
{
int regno = x86_64_ms_sysv_extra_clobbered_registers[i];
machine_mode mode = SSE_REGNO_P (regno) ? TImode : DImode;
- clobber_reg (&use, gen_rtx_REG (mode, regno));
+ vec[vec_len++]
+ = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (mode, regno));
}
}

View File

@@ -0,0 +1,13 @@
--- ./gcc/config/i386/i386.c.orig 2015-11-18 09:45:26.000000000 -0600
+++ ./gcc/config/i386/i386.c 2016-02-05 13:50:07.202981920 -0600
@@ -9677,6 +9677,10 @@
if (TARGET_64BIT_MS_ABI && get_frame_size () > SEH_MAX_FRAME_SIZE)
return true;
+ /* SSE saves require frame-pointer when stack is misaligned. */
+ if (TARGET_64BIT_MS_ABI && ix86_incoming_stack_boundary < 128)
+ return true;
+
/* In ix86_option_override_internal, TARGET_OMIT_LEAF_FRAME_POINTER
turns off the frame pointer by default. Turn it back on now if
we've not got a leaf function. */

View File

@@ -0,0 +1,31 @@
--- libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc 2018/04/25 07:39:32 259630
+++ libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc 2018/05/24 20:07:25 260687
@@ -138,7 +138,6 @@
# include <sys/procfs.h>
#endif
#include <sys/user.h>
-#include <sys/ustat.h>
#include <linux/cyclades.h>
#include <linux/if_eql.h>
#include <linux/if_plip.h>
@@ -231,7 +230,19 @@
#endif // SANITIZER_LINUX || SANITIZER_FREEBSD
#if SANITIZER_LINUX && !SANITIZER_ANDROID
- unsigned struct_ustat_sz = sizeof(struct ustat);
+ // Use pre-computed size of struct ustat to avoid <sys/ustat.h> which
+ // has been removed from glibc 2.28.
+#if defined(__aarch64__) || defined(__s390x__) || defined (__mips64) \
+ || defined(__powerpc64__) || defined(__arch64__) || defined(__sparcv9) \
+ || defined(__x86_64__)
+#define SIZEOF_STRUCT_USTAT 32
+#elif defined(__arm__) || defined(__i386__) || defined(__mips__) \
+ || defined(__powerpc__) || defined(__s390__)
+#define SIZEOF_STRUCT_USTAT 20
+#else
+#error Unknown size of struct ustat
+#endif
+ unsigned struct_ustat_sz = SIZEOF_STRUCT_USTAT;
unsigned struct_rlimit64_sz = sizeof(struct rlimit64);
unsigned struct_statvfs64_sz = sizeof(struct statvfs64);
#endif // SANITIZER_LINUX && !SANITIZER_ANDROID

View File

@@ -0,0 +1,12 @@
--- libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h 2020-02-28 11:49:29.763277856 +0000
+++ libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h 2020-02-28 11:49:45.092909823 +0000
@@ -198,8 +198,7 @@
unsigned long long __unused1;
unsigned long long __unused2;
#else
- unsigned short mode;
- unsigned short __pad1;
+ unsigned int mode;
unsigned short __seq;
unsigned short __pad2;
#if defined(__x86_64__) && !defined(_LP64)

View File

@@ -0,0 +1,37 @@
(this patch has to be applied after the glibc-2.28 one)
diff -Naur gcc-5.5.0.orig/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc gcc-5.5.0/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc
--- gcc-5.5.0.orig/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc 2021-08-19 12:21:14.786000000 +0200
+++ gcc-5.5.0/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc 2021-08-19 12:22:30.135000000 +0200
@@ -138,7 +138,6 @@
#include <sys/statvfs.h>
#include <sys/timex.h>
#include <sys/user.h>
-#include <linux/cyclades.h>
#include <linux/if_eql.h>
#include <linux/if_plip.h>
#include <linux/lp.h>
@@ -387,7 +386,6 @@
#if SANITIZER_LINUX && !SANITIZER_ANDROID
unsigned struct_ax25_parms_struct_sz = sizeof(struct ax25_parms_struct);
- unsigned struct_cyclades_monitor_sz = sizeof(struct cyclades_monitor);
#if EV_VERSION > (0x010000)
unsigned struct_input_keymap_entry_sz = sizeof(struct input_keymap_entry);
#else
@@ -754,15 +752,6 @@
#endif // SANITIZER_LINUX || SANITIZER_FREEBSD
#if SANITIZER_LINUX && !SANITIZER_ANDROID
- unsigned IOCTL_CYGETDEFTHRESH = CYGETDEFTHRESH;
- unsigned IOCTL_CYGETDEFTIMEOUT = CYGETDEFTIMEOUT;
- unsigned IOCTL_CYGETMON = CYGETMON;
- unsigned IOCTL_CYGETTHRESH = CYGETTHRESH;
- unsigned IOCTL_CYGETTIMEOUT = CYGETTIMEOUT;
- unsigned IOCTL_CYSETDEFTHRESH = CYSETDEFTHRESH;
- unsigned IOCTL_CYSETDEFTIMEOUT = CYSETDEFTIMEOUT;
- unsigned IOCTL_CYSETTHRESH = CYSETTHRESH;
- unsigned IOCTL_CYSETTIMEOUT = CYSETTIMEOUT;
unsigned IOCTL_EQL_EMANCIPATE = EQL_EMANCIPATE;
unsigned IOCTL_EQL_ENSLAVE = EQL_ENSLAVE;
unsigned IOCTL_EQL_GETMASTRCFG = EQL_GETMASTRCFG;