aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc')
-rw-r--r--gcc-4.9/gcc/config/i386/constraints.md3
-rw-r--r--gcc-4.9/gcc/config/i386/i386-opts.h11
-rw-r--r--gcc-4.9/gcc/config/i386/i386.c269
-rw-r--r--gcc-4.9/gcc/config/i386/i386.md22
-rw-r--r--gcc-4.9/gcc/config/i386/i386.opt22
-rw-r--r--gcc-4.9/gcc/config/i386/predicates.md6
-rw-r--r--gcc-4.9/gcc/doc/extend.texi19
-rw-r--r--gcc-4.9/gcc/doc/invoke.texi39
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c9
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-10.c7
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c11
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c9
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c9
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c10
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-8.c7
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-9.c7
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c9
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c9
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c9
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c9
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c8
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c8
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c8
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c8
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c9
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c4
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c9
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c8
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c10
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c8
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c8
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c9
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c8
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c8
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c8
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c8
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c9
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c19
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c19
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c19
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c19
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c21
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c (renamed from gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c)9
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c19
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c13
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-1.c3
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-10.c15
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-11.c15
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-12.c13
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-13.c11
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-14.c11
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-15.c11
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-16.c6
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-17.c7
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-18.c8
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-19.c8
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-2.c3
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-20.c9
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-21.c9
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-3.c4
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-4.c4
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-5.c3
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-6.c3
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-7.c4
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-8.c4
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-9.c15
66 files changed, 628 insertions, 310 deletions
diff --git a/gcc-4.9/gcc/config/i386/constraints.md b/gcc-4.9/gcc/config/i386/constraints.md
index 567e70564..ce1481122 100644
--- a/gcc-4.9/gcc/config/i386/constraints.md
+++ b/gcc-4.9/gcc/config/i386/constraints.md
@@ -153,7 +153,8 @@
(define_constraint "w"
"@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")))
;; Integer constant constraints.
diff --git a/gcc-4.9/gcc/config/i386/i386-opts.h b/gcc-4.9/gcc/config/i386/i386-opts.h
index e98cd8c1e..f44620781 100644
--- a/gcc-4.9/gcc/config/i386/i386-opts.h
+++ b/gcc-4.9/gcc/config/i386/i386-opts.h
@@ -93,6 +93,11 @@ enum stack_protector_guard {
SSP_GLOBAL /* global canary */
};
+/* This is used to mitigate variant #2 of the speculative execution
+ vulnerabilities on x86 processors identified by CVE-2017-5715, aka
+ Spectre. They convert indirect branches and function returns to
+ call and return thunks to avoid speculative execution via indirect
+ call, jmp and ret. */
enum indirect_branch {
indirect_branch_unset = 0,
indirect_branch_keep,
@@ -101,10 +106,4 @@ enum indirect_branch {
indirect_branch_thunk_extern
};
-enum indirect_branch_loop {
- indirect_branch_loop_lfence,
- indirect_branch_loop_pause,
- indirect_branch_loop_nop
-};
-
#endif
diff --git a/gcc-4.9/gcc/config/i386/i386.c b/gcc-4.9/gcc/config/i386/i386.c
index ccd2f150b..975a84dea 100644
--- a/gcc-4.9/gcc/config/i386/i386.c
+++ b/gcc-4.9/gcc/config/i386/i386.c
@@ -2515,7 +2515,11 @@ make_pass_insert_vzeroupper (gcc::context *ctxt)
there are local indirect jumps, like "indirect_jump" or "tablejump",
which jumps to another place in the function, since "call" in the
indirect thunk pushes the return address onto stack, destroying
- red-zone. */
+ red-zone.
+
+ TODO: If we can reserve the first 2 WORDs, for PUSH and, another
+ for CALL, in red-zone, we can allow local indirect jumps with
+ indirect thunk. */
static inline bool
ix86_using_red_zone (void)
@@ -4954,6 +4958,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)
@@ -4979,6 +4996,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"));
}
}
@@ -9168,9 +9198,15 @@ ix86_setup_frame_addresses (void)
# endif
#endif
+/* Label count for call and return thunks. It is used to make unique
+ labels in call and return thunks. */
static int indirectlabelno;
+
+/* True if call and return thunk functions are needed. */
static bool indirect_thunk_needed = false;
+/* Bit masks of integer registers, which contain branch target, used
+ by call and return thunks functions. */
static int indirect_thunks_used;
#ifndef INDIRECT_LABEL
@@ -9194,13 +9230,13 @@ indirect_thunk_name (char name[32], int regno, bool ret_p)
reg_prefix = TARGET_64BIT ? "r" : "e";
else
reg_prefix = "";
- sprintf (name, "__x86.indirect_thunk.%s%s",
+ sprintf (name, "__x86_indirect_thunk_%s%s",
reg_prefix, reg_names[regno]);
}
else
{
const char *ret = ret_p ? "return" : "indirect";
- sprintf (name, "__x86.%s_thunk", ret);
+ sprintf (name, "__x86_%s_thunk", ret);
}
}
else
@@ -9217,6 +9253,30 @@ indirect_thunk_name (char name[32], int regno, bool ret_p)
}
}
+/* Output a call and return thunk for indirect branch. If REGNO != -1,
+ the function address is in REGNO and the call and return thunk looks
+ like:
+
+ call L2
+ L1:
+ pause
+ jmp L1
+ L2:
+ mov %REG, (%sp)
+ ret
+
+ Otherwise, the function address is on the top of stack and the
+ call and return thunk looks like:
+
+ call L2
+ L1:
+ pause
+ jmp L1
+ L2:
+ lea WORD_SIZE(%sp), %sp
+ ret
+ */
+
static void
output_indirect_thunk (int regno)
{
@@ -9235,23 +9295,8 @@ output_indirect_thunk (int regno)
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
- switch (ix86_indirect_branch_loop)
- {
- case indirect_branch_loop_lfence:
- /* lfence. */
- fprintf (asm_out_file, "\tlfence\n");
- break;
- case indirect_branch_loop_pause:
- /* pause. */
- fprintf (asm_out_file, "\tpause\n");
- break;
- case indirect_branch_loop_nop:
- /* nop. */
- fprintf (asm_out_file, "\tnop\n");
- break;
- default:
- gcc_unreachable ();
- }
+ /* Pause + lfence. */
+ fprintf (asm_out_file, "\tpause\n\tlfence\n");
/* Jump. */
fputs ("\tjmp\t", asm_out_file);
@@ -9280,13 +9325,17 @@ output_indirect_thunk (int regno)
fputs ("\tret\n", asm_out_file);
}
+/* Output a funtion with a call and return thunk for indirect branch.
+ If REGNO != -1, the function address is in REGNO. Otherwise, the
+ function address is on the top of stack. */
+
static void
output_indirect_thunk_function (int regno)
{
char name[32];
tree decl;
- /* Create __x86.indirect_thunk. */
+ /* Create __x86_indirect_thunk. */
indirect_thunk_name (name, regno, false);
decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
get_identifier (name),
@@ -9332,11 +9381,10 @@ output_indirect_thunk_function (int regno)
if (regno < 0)
{
- /* Create alias for __x86.return_thunk. */
+ /* Create alias for __x86_return_thunk. */
char alias[32];
indirect_thunk_name (alias, regno, true);
- ASM_OUTPUT_DEF (asm_out_file, alias, name);
#if TARGET_MACHO
if (TARGET_MACHO)
{
@@ -9345,8 +9393,10 @@ output_indirect_thunk_function (int regno)
fputs ("\n\t.private_extern\t", asm_out_file);
assemble_name (asm_out_file, alias);
putc ('\n', asm_out_file);
+ ASM_OUTPUT_LABEL (asm_out_file, alias);
}
#else
+ ASM_OUTPUT_DEF (asm_out_file, alias, name);
if (USE_HIDDEN_LINKONCE)
{
fputs ("\t.globl\t", asm_out_file);
@@ -10981,6 +11031,7 @@ ix86_expand_prologue (void)
{
struct machine_function *m = cfun->machine;
rtx insn, t;
+ struct ix86_frame frame;
bool pic_reg_used;
HOST_WIDE_INT allocate;
bool int_registers_saved;
@@ -11004,7 +11055,7 @@ ix86_expand_prologue (void)
m->fs.sp_valid = true;
ix86_compute_frame_layout ();
- struct ix86_frame &frame = m->frame;
+ frame = m->frame;
if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl))
{
@@ -11737,12 +11788,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 = m->frame;
+ frame = m->frame;
m->fs.sp_valid = (!frame_pointer_needed
|| (crtl->sp_is_unchanging
@@ -14931,7 +14983,7 @@ put_condition_code (enum rtx_code code, enum 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 register name without %.
+ If CODE is 'V', print naked full integer register name without %.
*/
void
@@ -14976,6 +15028,13 @@ print_reg (rtx x, int code, FILE *file)
code = 32;
else if (code == 'g')
code = 64;
+ else if (code == 'V')
+ {
+ if (GENERAL_REGNO_P (regno))
+ code = GET_MODE_SIZE (word_mode);
+ else
+ error ("'V' modifier on non-integer register");
+ }
else
code = GET_MODE_SIZE (GET_MODE (x));
@@ -15142,7 +15201,7 @@ get_some_local_dynamic_name (void)
& -- 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 register name without %.
+ 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.
@@ -25304,48 +25363,131 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
return call;
}
+/* Output indirect branch via a call and return thunk. CALL_OP is a
+ register which contains the branch target. XASM is the assembly
+ template for CALL_OP. Branch is a tail call if SIBCALL_P is true.
+ A normal call is converted to:
+
+ call __x86_indirect_thunk_reg
+
+ and a tail call is converted to:
+
+ jmp __x86_indirect_thunk_reg
+ */
+
static void
-ix86_output_indirect_branch (rtx call_op, const char *xasm,
- bool sibcall_p)
+ix86_output_indirect_branch_via_reg (rtx call_op, bool sibcall_p)
{
char thunk_name_buf[32];
char *thunk_name;
- char push_buf[64];
- int regno;
-
- if (REG_P (call_op))
- regno = REGNO (call_op);
- else
- regno = -1;
+ int regno = REGNO (call_op);
if (cfun->machine->indirect_branch_type
!= indirect_branch_thunk_inline)
{
if (cfun->machine->indirect_branch_type == indirect_branch_thunk)
- {
- if (regno >= 0)
- {
- int i = regno;
- if (i >= FIRST_REX_INT_REG)
- i -= (FIRST_REX_INT_REG - SP_REG - 1);
- indirect_thunks_used |= 1 << i;
- }
- else
- indirect_thunk_needed = true;
- }
+ {
+ int i = regno;
+ if (i >= FIRST_REX_INT_REG)
+ i -= (FIRST_REX_INT_REG - SP_REG - 1);
+ indirect_thunks_used |= 1 << i;
+ }
indirect_thunk_name (thunk_name_buf, regno, false);
thunk_name = thunk_name_buf;
}
else
thunk_name = NULL;
+ if (sibcall_p)
+ {
+ if (thunk_name != NULL)
+ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);
+ else
+ output_indirect_thunk (regno);
+ }
+ else
+ {
+ if (thunk_name != NULL)
+ {
+ fprintf (asm_out_file, "\tcall\t%s\n", thunk_name);
+ return;
+ }
+
+ char indirectlabel1[32];
+ char indirectlabel2[32];
+
+ ASM_GENERATE_INTERNAL_LABEL (indirectlabel1,
+ INDIRECT_LABEL,
+ indirectlabelno++);
+ ASM_GENERATE_INTERNAL_LABEL (indirectlabel2,
+ INDIRECT_LABEL,
+ indirectlabelno++);
+
+ /* Jump. */
+ fputs ("\tjmp\t", asm_out_file);
+ assemble_name_raw (asm_out_file, indirectlabel2);
+ fputc ('\n', asm_out_file);
+
+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
+
+ if (thunk_name != NULL)
+ fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);
+ else
+ output_indirect_thunk (regno);
+
+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
+
+ /* Call. */
+ fputs ("\tcall\t", asm_out_file);
+ assemble_name_raw (asm_out_file, indirectlabel1);
+ fputc ('\n', asm_out_file);
+ }
+}
+
+/* Output indirect branch via a call and return thunk. CALL_OP is
+ the branch target. XASM is the assembly template for CALL_OP.
+ Branch is a tail call if SIBCALL_P is true. A normal call is
+ converted to:
+
+ jmp L2
+ L1:
+ push CALL_OP
+ jmp __x86_indirect_thunk
+ L2:
+ call L1
+
+ and a tail call is converted to:
+
+ push CALL_OP
+ jmp __x86_indirect_thunk
+ */
+
+static void
+ix86_output_indirect_branch_via_push (rtx call_op, const char *xasm,
+ bool sibcall_p)
+{
+ char thunk_name_buf[32];
+ char *thunk_name;
+ char push_buf[64];
+ int regno = -1;
+
+ if (cfun->machine->indirect_branch_type
+ != indirect_branch_thunk_inline)
+ {
+ if (cfun->machine->indirect_branch_type == indirect_branch_thunk)
+ indirect_thunk_needed = true;
+ indirect_thunk_name (thunk_name_buf, regno, false);
+ thunk_name = thunk_name_buf;
+ }
+ else
+ thunk_name = NULL;
+
snprintf (push_buf, sizeof (push_buf), "push{%c}\t%s",
TARGET_64BIT ? 'q' : 'l', xasm);
if (sibcall_p)
{
- if (regno < 0)
- output_asm_insn (push_buf, &call_op);
+ output_asm_insn (push_buf, &call_op);
if (thunk_name != NULL)
fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);
else
@@ -25353,12 +25495,6 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm,
}
else
{
- if (regno >= 0 && thunk_name != NULL)
- {
- fprintf (asm_out_file, "\tcall\t%s\n", thunk_name);
- return;
- }
-
char indirectlabel1[32];
char indirectlabel2[32];
@@ -25376,6 +25512,7 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm,
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
+ /* An external function may be called via GOT, instead of PLT. */
if (MEM_P (call_op))
{
struct ix86_address parts;
@@ -25408,8 +25545,7 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm,
}
}
- if (regno < 0)
- output_asm_insn (push_buf, &call_op);
+ output_asm_insn (push_buf, &call_op);
if (thunk_name != NULL)
fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);
@@ -25425,6 +25561,22 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm,
}
}
+/* Output indirect branch via a call and return thunk. CALL_OP is
+ the branch target. XASM is the assembly template for CALL_OP.
+ Branch is a tail call if SIBCALL_P is true. */
+
+static void
+ix86_output_indirect_branch (rtx call_op, const char *xasm,
+ bool sibcall_p)
+{
+ if (REG_P (call_op))
+ ix86_output_indirect_branch_via_reg (call_op, sibcall_p);
+ else
+ ix86_output_indirect_branch_via_push (call_op, xasm, sibcall_p);
+}
+/* Output indirect jump. CALL_OP is the jump target. Jump is a
+ function return if RET_P is true. */
+
const char *
ix86_output_indirect_jmp (rtx call_op, bool ret_p)
{
@@ -25468,6 +25620,9 @@ ix86_nopic_noplt_attribute_p (rtx call_op)
return false;
}
+/* Output function return. CALL_OP is the jump target. Add a REP
+ prefix to RET if LONG_P is true and function return is kept. */
+
const char *
ix86_output_function_return (bool long_p)
{
diff --git a/gcc-4.9/gcc/config/i386/i386.md b/gcc-4.9/gcc/config/i386/i386.md
index e32ba52a6..f5eff3d90 100644
--- a/gcc-4.9/gcc/config/i386/i386.md
+++ b/gcc-4.9/gcc/config/i386/i386.md
@@ -11140,7 +11140,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;
})
@@ -11149,7 +11149,11 @@
[(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
""
"* return ix86_output_indirect_jmp (operands[0], false);"
- [(set_attr "type" "ibr")
+ [(set (attr "type")
+ (if_then_else (match_test "(cfun->machine->indirect_branch_type
+ != indirect_branch_keep)")
+ (const_string "multi")
+ (const_string "ibr")))
(set_attr "length_immediate" "0")])
(define_expand "tablejump"
@@ -11189,7 +11193,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;
})
@@ -11199,7 +11203,11 @@
(use (label_ref (match_operand 1)))]
""
"* return ix86_output_indirect_jmp (operands[0], false);"
- [(set_attr "type" "ibr")
+ [(set (attr "type")
+ (if_then_else (match_test "(cfun->machine->indirect_branch_type
+ != indirect_branch_keep)")
+ (const_string "multi")
+ (const_string "ibr")))
(set_attr "length_immediate" "0")])
;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
@@ -11620,7 +11628,11 @@
(use (match_operand:SI 0 "register_operand" "r"))]
"reload_completed"
"* return ix86_output_indirect_jmp (operands[0], true);"
- [(set_attr "type" "ibr")
+ [(set (attr "type")
+ (if_then_else (match_test "(cfun->machine->indirect_branch_type
+ != indirect_branch_keep)")
+ (const_string "multi")
+ (const_string "ibr")))
(set_attr "length_immediate" "0")])
(define_insn "nop"
diff --git a/gcc-4.9/gcc/config/i386/i386.opt b/gcc-4.9/gcc/config/i386/i386.opt
index 3b4a86066..502037b68 100644
--- a/gcc-4.9/gcc/config/i386/i386.opt
+++ b/gcc-4.9/gcc/config/i386/i386.opt
@@ -797,11 +797,11 @@ Enum(stack_protector_guard) String(global) Value(SSP_GLOBAL)
mindirect-branch=
Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indirect_branch) Init(indirect_branch_keep)
-Update indirect call and jump.
+Convert indirect call and jump to call and return thunks.
mfunction-return=
Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_function_return) Init(indirect_branch_keep)
-Update function return.
+Convert function return to call and return thunk.
Enum
Name(indirect_branch) Type(enum indirect_branch)
@@ -819,18 +819,6 @@ Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline)
EnumValue
Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern)
-mindirect-branch-loop=
-Target Report RejectNegative Joined Enum(indirect_branch_loop) Var(ix86_indirect_branch_loop) Undocumented Init(indirect_branch_loop_lfence)
-
-Enum
-Name(indirect_branch_loop) Type(enum indirect_branch_loop)
-Known loop choices (for use with the -mindirect-branch-loop= option):
-
-EnumValue
-Enum(indirect_branch_loop) String(lfence) Value(indirect_branch_loop_lfence)
-
-EnumValue
-Enum(indirect_branch_loop) String(pause) Value(indirect_branch_loop_pause)
-
-EnumValue
-Enum(indirect_branch_loop) String(nop) Value(indirect_branch_loop_nop)
+mindirect-branch-register
+Target Report Var(ix86_indirect_branch_register) Init(0)
+Force indirect call and jump via register.
diff --git a/gcc-4.9/gcc/config/i386/predicates.md b/gcc-4.9/gcc/config/i386/predicates.md
index 8266f3eaf..10afa385c 100644
--- a/gcc-4.9/gcc/config/i386/predicates.md
+++ b/gcc-4.9/gcc/config/i386/predicates.md
@@ -584,7 +584,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.
@@ -593,7 +594,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.
diff --git a/gcc-4.9/gcc/doc/extend.texi b/gcc-4.9/gcc/doc/extend.texi
index 4c0914a35..dfef30042 100644
--- a/gcc-4.9/gcc/doc/extend.texi
+++ b/gcc-4.9/gcc/doc/extend.texi
@@ -4088,6 +4088,25 @@ Specify which floating-point unit to use. The
@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.
+
+@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:
diff --git a/gcc-4.9/gcc/doc/invoke.texi b/gcc-4.9/gcc/doc/invoke.texi
index 698ecd659..297657a39 100644
--- a/gcc-4.9/gcc/doc/invoke.texi
+++ b/gcc-4.9/gcc/doc/invoke.texi
@@ -694,7 +694,8 @@ Objective-C and Objective-C++ Dialects}.
-m32 -m64 -mx32 -m16 -mlarge-data-threshold=@var{num} @gol
-msse2avx -mfentry -m8bit-idiv @gol
-mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol
--mstack-protector-guard=@var{guard}}
+-mstack-protector-guard=@var{guard} -mindirect-branch=@var{choice} @gol
+-mfunction-return=@var{choice} -mindirect-branch-register}
@emph{i386 and x86-64 Windows Options}
@gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol
@@ -16021,6 +16022,42 @@ locations are @samp{global} for global canary or @samp{tls} for per-thread
canary in the TLS block (the default). This option has effect only when
@option{-fstack-protector} or @option{-fstack-protector-all} is specified.
+@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}.
+
+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},
+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}.
+
+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.
+
@end table
These @samp{-m} switches are supported in addition to the above
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
index 46ae8329b..555d6656b 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
+++ b/gcc-4.9/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);
@@ -11,9 +11,10 @@ male_indirect_jump (long offset)
dispatch(offset);
}
-/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tpause} } } */
/* { dg-final { scan-assembler {\tlfence} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-10.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-10.c
new file mode 100644
index 000000000..a0674bd23
--- /dev/null
+++ b/gcc-4.9/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-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
index 7c8100822..009732cb9 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
+++ b/gcc-4.9/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);
@@ -11,9 +11,10 @@ male_indirect_jump (long offset)
dispatch[offset](offset);
}
-/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
- /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tpause} } } */
/* { dg-final { scan-assembler {\tlfence} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
index 46685d9a6..dab7ac2ef 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
+++ b/gcc-4.9/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 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
typedef void (*dispatch_t)(long offset);
@@ -12,9 +12,10 @@ male_indirect_jump (long offset)
return 0;
}
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tpause} } } */
/* { dg-final { scan-assembler {\tlfence} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
index 8f701775c..44cc5f52f 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
+++ b/gcc-4.9/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 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
typedef void (*dispatch_t)(long offset);
@@ -12,9 +12,10 @@ male_indirect_jump (long offset)
return 0;
}
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tpause} } } */
/* { dg-final { scan-assembler {\tlfence} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
index 008ccac3a..17c2d0faf 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
@@ -1,11 +1,12 @@
/* { 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);
void func2 (void);
void func3 (void);
void func4 (void);
+void func4 (void);
void func5 (void);
void
@@ -34,9 +35,10 @@ bar (int i)
}
}
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tpause} } } */
/* { dg-final { scan-assembler {\tlfence} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-8.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-8.c
new file mode 100644
index 000000000..7a80a8986
--- /dev/null
+++ b/gcc-4.9/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-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-9.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-9.c
new file mode 100644
index 000000000..d4d45c511
--- /dev/null
+++ b/gcc-4.9/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-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
index 88c87c10d..a3c7e0071 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
+++ b/gcc-4.9/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);
@@ -14,9 +14,10 @@ male_indirect_jump (long offset)
dispatch(offset);
}
-/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tpause} } } */
/* { dg-final { scan-assembler {\tlfence} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c
new file mode 100644
index 000000000..3a2aeaddb
--- /dev/null
+++ b/gcc-4.9/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-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c
new file mode 100644
index 000000000..8e52f032b
--- /dev/null
+++ b/gcc-4.9/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-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
index 80f370564..a8ca60ec6 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
+++ b/gcc-4.9/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);
@@ -12,9 +12,10 @@ male_indirect_jump (long offset)
dispatch[offset](offset);
}
-/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tpause} } } */
/* { dg-final { scan-assembler {\tlfence} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
index 7f56725e6..4aeec1833 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
+++ b/gcc-4.9/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);
@@ -14,8 +14,10 @@ male_indirect_jump (long offset)
return 0;
}
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+/* { dg-final { scan-assembler {\tpause} } } */
+/* { dg-final { scan-assembler {\tlfence} } } */
+/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
index fd4ab1dba..ac0e5999f 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
+++ b/gcc-4.9/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);
@@ -13,8 +13,10 @@ male_indirect_jump (long offset)
return 0;
}
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+/* { dg-final { scan-assembler {\tpause} } } */
+/* { dg-final { scan-assembler {\tlfence} } } */
+/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
index 1ffbf3b11..573cf1ef0 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
+++ b/gcc-4.9/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);
@@ -14,9 +14,9 @@ male_indirect_jump (long offset)
return 0;
}
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
index 155907291..b2b37fc6e 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
+++ b/gcc-4.9/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);
@@ -13,9 +13,9 @@ male_indirect_jump (long offset)
return 0;
}
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
index 58347f315..4a43e1999 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
@@ -1,11 +1,12 @@
/* { 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);
void func2 (void);
void func3 (void);
void func4 (void);
+void func4 (void);
void func5 (void);
__attribute__ ((indirect_branch("thunk-extern")))
@@ -35,9 +36,9 @@ bar (int i)
}
}
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */
/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c
index 3a7cbf03f..d730d31bd 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c
@@ -6,6 +6,7 @@ void func1 (void);
void func2 (void);
void func3 (void);
void func4 (void);
+void func4 (void);
void func5 (void);
__attribute__ ((indirect_branch("keep")))
@@ -35,6 +36,7 @@ bar (int i)
}
}
-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
+/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c
new file mode 100644
index 000000000..bdaa4f691
--- /dev/null
+++ b/gcc-4.9/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-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
index 03a4bd0aa..be19d7219 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
+++ b/gcc-4.9/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);
@@ -11,9 +11,9 @@ male_indirect_jump (long offset)
dispatch(offset);
}
-/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
index 216b60a5e..7e761bc46 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
+++ b/gcc-4.9/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);
@@ -11,9 +11,9 @@ male_indirect_jump (long offset)
dispatch[offset](offset);
}
-/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
- /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
index 153723941..d9964c25b 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
+++ b/gcc-4.9/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);
@@ -12,9 +12,9 @@ male_indirect_jump (long offset)
return 0;
}
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
index c82e53068..d4dca4dc5 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
+++ b/gcc-4.9/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);
@@ -12,9 +12,9 @@ male_indirect_jump (long offset)
return 0;
}
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
index a2614e56c..aece93836 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
@@ -1,11 +1,12 @@
/* { 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);
void func2 (void);
void func3 (void);
void func4 (void);
+void func4 (void);
void func5 (void);
void
@@ -34,9 +35,9 @@ bar (int i)
}
}
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
index 58f2de923..a2d16771b 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
+++ b/gcc-4.9/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);
@@ -11,8 +11,10 @@ male_indirect_jump (long offset)
dispatch(offset);
}
-/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+/* { dg-final { scan-assembler {\tpause} } } */
+/* { dg-final { scan-assembler {\tlfence} } } */
+/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
index cfccefd24..1b93e8469 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
+++ b/gcc-4.9/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);
@@ -11,8 +11,10 @@ male_indirect_jump (long offset)
dispatch[offset](offset);
}
-/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+/* { dg-final { scan-assembler {\tpause} } } */
+/* { dg-final { scan-assembler {\tlfence} } } */
+/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
index 6fe5ce71a..2eef6f35a 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
+++ b/gcc-4.9/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);
@@ -12,8 +12,10 @@ male_indirect_jump (long offset)
return 0;
}
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+/* { dg-final { scan-assembler-times {\tpause} 1 } } */
+/* { dg-final { scan-assembler-times {\tlfence} 1 } } */
+/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
index 65cd997a3..e825a10f1 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
+++ b/gcc-4.9/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);
@@ -12,8 +12,10 @@ male_indirect_jump (long offset)
return 0;
}
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+/* { dg-final { scan-assembler-times {\tpause} 1 } } */
+/* { dg-final { scan-assembler-times {\tlfence} 1 } } */
+/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
index 3482bfeda..c67066cf1 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
@@ -1,11 +1,12 @@
/* { 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);
void func2 (void);
void func3 (void);
void func4 (void);
+void func4 (void);
void func5 (void);
void
@@ -34,8 +35,10 @@ bar (int i)
}
}
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */
/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
+/* { dg-final { scan-assembler {\tpause} } } */
+/* { dg-final { scan-assembler {\tlfence} } } */
+/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c
deleted file mode 100644
index fefeaece8..000000000
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-1.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=pause -fno-pic" } */
-
-typedef void (*dispatch_t)(long offset);
-
-dispatch_t dispatch;
-
-void
-male_indirect_jump (long offset)
-{
- dispatch(offset);
-}
-
-/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } *
-/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
-/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
-/* { dg-final { scan-assembler {\tpause} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c
deleted file mode 100644
index 8975cf35c..000000000
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-2.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=nop -fno-pic" } */
-
-typedef void (*dispatch_t)(long offset);
-
-dispatch_t dispatch[256];
-
-void
-male_indirect_jump (long offset)
-{
- dispatch[offset](offset);
-}
-
-/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
-/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
-/* { dg-final { scan-assembler {\tnop} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c
deleted file mode 100644
index d103c4d6a..000000000
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-3.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-loop=lfence -fno-pic" } */
-
-typedef void (*dispatch_t)(long offset);
-
-dispatch_t dispatch;
-
-void
-male_indirect_jump (long offset)
-{
- dispatch(offset);
-}
-
-/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
-/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
-/* { dg-final { scan-assembler {\tlfence} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c
deleted file mode 100644
index 081f51250..000000000
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-5.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -mindirect-branch=thunk-extern -mindirect-branch-loop=pause -fno-pic" } */
-
-typedef void (*dispatch_t)(long offset);
-
-dispatch_t dispatch;
-
-void
-male_indirect_jump (long offset)
-{
- dispatch(offset);
-}
-
-/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
-/* { dg-final { scan-assembler-not {\t(lfence|pause|nop)} } } */
-/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
-/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c
new file mode 100644
index 000000000..0cf8daeb5
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c
@@ -0,0 +1,21 @@
+/* { 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" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c
index 4c75a0a3a..e7e616bb2 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-loop-4.c
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mindirect-branch=thunk-inline -mindirect-branch-loop=pause -fno-pic" } */
+/* { dg-options "-O2 -mindirect-branch=thunk-inline -mindirect-branch-register -fno-pic" } */
typedef void (*dispatch_t)(long offset);
@@ -11,9 +11,10 @@ male_indirect_jump (long offset)
dispatch(offset);
}
-/* { dg-final { scan-assembler "(push|mov)(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */
/* { 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 "__x86.indirect_thunk" } } */
-/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+/* { 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" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c
new file mode 100644
index 000000000..5320e923b
--- /dev/null
+++ b/gcc-4.9/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" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c
new file mode 100644
index 000000000..f0cd9b75b
--- /dev/null
+++ b/gcc-4.9/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 } } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-1.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-1.c
index 406956f48..7223f67ba 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-1.c
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-1.c
@@ -6,7 +6,8 @@ foo (void)
{
}
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */
/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tpause} } } */
/* { dg-final { scan-assembler {\tlfence} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
index aecea4224..6de9b8c9f 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
+++ b/gcc-4.9/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 -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */
extern void (*bar) (void);
@@ -12,11 +12,12 @@ foo (void)
/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */
+/* { dg-final { scan-assembler-times {\tpause} 2 } } */
/* { dg-final { scan-assembler-times {\tlfence} 2 } } */
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */
-/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x32 } } } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */
+/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */
/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
index fee860922..365980375 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
+++ b/gcc-4.9/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 -mfunction-return=thunk-extern -mindirect-branch=thunk -fno-pic" } */
extern void (*bar) (void);
@@ -10,13 +10,14 @@ foo (void)
return 0;
}
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */
+/* { dg-final { scan-assembler-times {\tpause} 1 } } */
/* { dg-final { scan-assembler-times {\tlfence} 1 } } */
/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */
-/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x3 } } } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */
+/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */
/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
index 851115ac5..5fb1a4de7 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
+++ b/gcc-4.9/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 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */
extern void (*bar) (void);
@@ -10,12 +10,13 @@ foo (void)
return 0;
}
-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */
+/* { dg-final { scan-assembler-times {\tpause} 1 } } */
/* { dg-final { scan-assembler-times {\tlfence} 1 } } */
/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "__x86.indirect_thunk:" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */
-/* { dg-final { scan-assembler "__x86.indirect_thunk\.(r|e)ax:" { target { x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */
+/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */
/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
index 7acb6fa5e..fd5b41fdd 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
+++ b/gcc-4.9/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")));
@@ -11,11 +11,12 @@ foo (void)
return 0;
}
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */
+/* { dg-final { scan-assembler-times {\tpause} 2 } } */
/* { dg-final { scan-assembler-times {\tlfence} 2 } } */
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */
/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 3 } } */
/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 3 } } */
-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.indirect_thunk" } } */
-/* { dg-final { scan-assembler-not "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_indirect_thunk" } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */
/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-14.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
index bf340fac7..d606373ea 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
+++ b/gcc-4.9/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);
@@ -11,11 +11,12 @@ foo (void)
return 0;
}
+/* { dg-final { scan-assembler-times {\tpause} 1 } } */
/* { dg-final { scan-assembler-times {\tlfence} 1 } } */
-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */
/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */
/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
index 735f8648c..2038644aa 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
+++ b/gcc-4.9/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 -mfunction-return=keep -mindirect-branch=keep -fno-pic" } */
extern void (*bar) (void);
@@ -11,11 +11,12 @@ foo (void)
return 0;
}
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */
/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler-times {\tpause} 1 } } */
/* { dg-final { scan-assembler-times {\tlfence} 1 } } */
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-16.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-16.c
index cf3920563..a16cad16a 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-16.c
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-16.c
@@ -11,8 +11,8 @@ foo (void)
return 0;
}
-/* { dg-final { scan-assembler-not "__x86.indirect_thunk" } } */
-/* { dg-final { scan-assembler-not "__x86.return_thunk" } } */
-/* { dg-final { scan-assembler-not {\tlfence} } } */
+/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
+/* { dg-final { scan-assembler-not "__x86_return_thunk" } } */
+/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-17.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-17.c
new file mode 100644
index 000000000..0605e2c65
--- /dev/null
+++ b/gcc-4.9/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-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-18.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-18.c
new file mode 100644
index 000000000..307019dc2
--- /dev/null
+++ b/gcc-4.9/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-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-19.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-19.c
new file mode 100644
index 000000000..772617f40
--- /dev/null
+++ b/gcc-4.9/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-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-2.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-2.c
index 190947cc2..c6659e3ad 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-2.c
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-2.c
@@ -8,5 +8,6 @@ foo (void)
/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tpause} } } */
/* { dg-final { scan-assembler {\tlfence} } } */
-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-20.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-20.c
new file mode 100644
index 000000000..1e9f9bd5a
--- /dev/null
+++ b/gcc-4.9/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-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-21.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-21.c
new file mode 100644
index 000000000..eea07f7ab
--- /dev/null
+++ b/gcc-4.9/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)
+{
+}
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-3.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-3.c
index d71de3ac5..0f7f388f4 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-3.c
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-3.c
@@ -6,7 +6,7 @@ foo (void)
{
}
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
-/* { dg-final { scan-assembler-not {\tlfence} } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */
+/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-4.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-4.c
index 68c22122f..9ae37e835 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-4.c
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-4.c
@@ -6,7 +6,7 @@ foo (void)
{
}
-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
-/* { dg-final { scan-assembler-not {\tlfence} } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */
+/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-5.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-5.c
index 28c576e22..4bd0d2a27 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-5.c
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-5.c
@@ -8,7 +8,8 @@ foo (void)
{
}
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */
/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tpause} } } */
/* { dg-final { scan-assembler {\tlfence} } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-6.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-6.c
index 10ad40b9c..053841f6f 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-6.c
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-6.c
@@ -9,5 +9,6 @@ foo (void)
/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler {\tpause} } } */
/* { dg-final { scan-assembler {\tlfence} } } */
-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-7.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-7.c
index 7ac0beaa7..262e67801 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-7.c
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-7.c
@@ -7,7 +7,7 @@ foo (void)
{
}
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
-/* { dg-final { scan-assembler-not {\tlfence} } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */
+/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-8.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-8.c
index 777ab7c80..c1658e966 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-8.c
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-8.c
@@ -8,7 +8,7 @@ foo (void)
{
}
-/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86.return_thunk" } } */
-/* { dg-final { scan-assembler-not {\tlfence} } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */
+/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
index 0b285caa2..d34dd4e6d 100644
--- a/gcc-4.9/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
+++ b/gcc-4.9/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 -mfunction-return=thunk -mindirect-branch=thunk -fno-pic" } */
extern void (*bar) (void);
@@ -10,14 +10,15 @@ foo (void)
return 0;
}
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.return_thunk" } } */
-/* { dg-final { scan-assembler-not "__x86.return_thunk:" } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */
/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
-/* { dg-final { scan-assembler "__x86.indirect_thunk:" } } */
+/* { dg-final { scan-assembler "__x86_indirect_thunk:" } } */
+/* { dg-final { scan-assembler-times {\tpause} 1 { target { ! x32 } } } } */
/* { dg-final { scan-assembler-times {\tlfence} 1 { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86.indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler-times {\tpause} 2 { target { x32 } } } } */
/* { dg-final { scan-assembler-times {\tlfence} 2 { target { x32 } } } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86.indirect_thunk\.(r|e)ax" { target { x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */
/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */