aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCaroline Tice <cmtice@google.com>2018-01-29 21:36:52 (GMT)
committerCaroline Tice <cmtice@google.com>2018-01-29 22:19:21 (GMT)
commitd64d815b3af9d2653d924ea2e1ebb21ee8b043b7 (patch)
tree41ddc808254fa6b40de6540413015909760ec306
parent430f43829fa42b459ccbb53b44843c54c8ba4550 (diff)
downloadtoolchain_gcc-d64d815b3af9d2653d924ea2e1ebb21ee8b043b7.zip
toolchain_gcc-d64d815b3af9d2653d924ea2e1ebb21ee8b043b7.tar.gz
toolchain_gcc-d64d815b3af9d2653d924ea2e1ebb21ee8b043b7.tar.bz2
[GCC] Update with latest retpoline fixes from Intel.
Intel has updated their retpoline patches since we created our original patch. This CL updates our retpoline changes to match the latest from Intel. Bug: None Test: Tested extensively in ChromeOS. Built x86 platform & kernel images in Android. Change-Id: Id1a18cb1f1f4461832a017cb5c5d59e5400d9d08
-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 567e705..ce14811 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 e98cd8c..f446207 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 ccd2f15..975a84d 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 e32ba52..f5eff3d 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 3b4a860..502037b 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 8266f3e..10afa38 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 4c0914a..dfef300 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 698ecd6..297657a 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 46ae832..555d665 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 0000000..a0674bd
--- /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 7c81008..009732c 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 46685d9..dab7ac2 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 8f70177..44cc5f5 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 008ccac..17c2d0f 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 0000000..7a80a89
--- /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 0000000..d4d45c5
--- /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 88c87c1..a3c7e00 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 0000000..3a2aead
--- /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 0000000..8e52f03
--- /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 80f3705..a8ca60e 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 7f56725..4aeec18 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 fd4ab1d..ac0e599 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 1ffbf3b..573cf1e 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 1559072..b2b37fc 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 58347f3..4a43e19 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 3a7cbf0..d730d31 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 0000000..bdaa4f6
--- /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 03a4bd0..be19d72 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 216b60a..7e761bc 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 1537239..d9964c2 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 c82e530..d4dca4d 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 a2614e5..aece938 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 58f2de9..a2d1677 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 cfccefd..1b93e84 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 6fe5ce7..2eef6f3 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 65cd997..e825a10 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 3482bfe..c67066c 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 fefeaec..0000000
--- 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 8975cf3..0000000
--- 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 d103c4d..0000000
--- 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 081f512..0000000
--- 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 0000000..0cf8dae
--- /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 4c75a0a..e7e616b 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 0000000..5320e92
--- /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 0000000..f0cd9b7
--- /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 406956f..7223f67 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 aecea42..6de9b8c 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 fee8609..3659803 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 851115a..5fb1a4d 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 7acb6fa..fd5b41f 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 bf340fa..d606373 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 735f864..2038644 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 cf39205..a16cad1 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 0000000..0605e2c
--- /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 0000000..307019d
--- /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 0000000..772617f
--- /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 190947c..c6659e3 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 0000000..1e9f9bd
--- /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 0000000..eea07f7
--- /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 d71de3a..0f7f388 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 68c2212..9ae37e8 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 28c576e..4bd0d2a 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 10ad40b..053841f 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 7ac0bea..262e678 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 777ab7c..c1658e9 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 0b285ca..d34dd4e 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 } } } */