You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
175 lines
6.0 KiB
175 lines
6.0 KiB
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c |
|
index a8238a001ee..34f27c597a2 100644 |
|
--- a/gcc/config/i386/i386.c |
|
+++ b/gcc/config/i386/i386.c |
|
@@ -8770,13 +8770,16 @@ ix86_setup_frame_addresses (void) |
|
labels in call and return thunks. */ |
|
static int indirectlabelno; |
|
|
|
-/* True if call and return thunk functions are needed. */ |
|
+/* True if call thunk function is needed. */ |
|
static bool indirect_thunk_needed = false; |
|
|
|
/* Bit masks of integer registers, which contain branch target, used |
|
- by call and return thunks functions. */ |
|
+ by call thunk functions. */ |
|
static int indirect_thunks_used; |
|
|
|
+/* True if return thunk function is needed. */ |
|
+static bool indirect_return_needed = false; |
|
+ |
|
/* True if return thunk function via CX is needed. */ |
|
static bool indirect_return_via_cx; |
|
|
|
@@ -8899,17 +8902,19 @@ output_indirect_thunk (int regno) |
|
} |
|
|
|
/* 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. */ |
|
+ If REGNO != UNVALID_REGNUM, |
|
+ the function address is in REGNO. Otherwise, the function address is |
|
+ on the top of stack. Thunk is used for function return if RET_P is |
|
+ true. */ |
|
|
|
static void |
|
-output_indirect_thunk_function (int regno) |
|
+output_indirect_thunk_function (unsigned int regno, bool ret_p) |
|
{ |
|
char name[32]; |
|
tree decl; |
|
|
|
/* Create __x86_indirect_thunk. */ |
|
- indirect_thunk_name (name, regno, false); |
|
+ indirect_thunk_name (name, regno, ret_p); |
|
decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, |
|
get_identifier (name), |
|
build_function_type_list (void_type_node, NULL_TREE)); |
|
@@ -8953,45 +8958,6 @@ output_indirect_thunk_function (int regno) |
|
ASM_OUTPUT_LABEL (asm_out_file, name); |
|
} |
|
|
|
- /* Create alias for __x86_return_thunk or |
|
- __x86_return_thunk_ecx. */ |
|
- bool need_alias; |
|
- if (regno == INVALID_REGNUM) |
|
- need_alias = true; |
|
- else if (regno == CX_REG) |
|
- need_alias = indirect_return_via_cx; |
|
- else |
|
- need_alias = false; |
|
- |
|
- if (need_alias) |
|
- { |
|
- char alias[32]; |
|
- |
|
- indirect_thunk_name (alias, regno, true); |
|
-#if TARGET_MACHO |
|
- if (TARGET_MACHO) |
|
- { |
|
- fputs ("\t.weak_definition\t", asm_out_file); |
|
- assemble_name (asm_out_file, alias); |
|
- 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); |
|
- assemble_name (asm_out_file, alias); |
|
- putc ('\n', asm_out_file); |
|
- fputs ("\t.hidden\t", asm_out_file); |
|
- assemble_name (asm_out_file, alias); |
|
- putc ('\n', asm_out_file); |
|
- } |
|
-#endif |
|
- } |
|
- |
|
DECL_INITIAL (decl) = make_node (BLOCK); |
|
current_function_decl = decl; |
|
allocate_struct_function (decl, false); |
|
@@ -9038,14 +9004,19 @@ ix86_code_end (void) |
|
rtx xops[2]; |
|
int regno; |
|
|
|
+ if (indirect_return_needed) |
|
+ output_indirect_thunk_function (INVALID_REGNUM, true); |
|
+ if (indirect_return_via_cx) |
|
+ output_indirect_thunk_function (CX_REG, true); |
|
if (indirect_thunk_needed) |
|
- output_indirect_thunk_function (-1); |
|
+ output_indirect_thunk_function (INVALID_REGNUM, false); |
|
|
|
for (regno = FIRST_REX_INT_REG; regno <= LAST_REX_INT_REG; regno++) |
|
{ |
|
int i = regno - FIRST_REX_INT_REG + LAST_INT_REG + 1; |
|
if ((indirect_thunks_used & (1 << i))) |
|
- output_indirect_thunk_function (regno); |
|
+ output_indirect_thunk_function (regno, false); |
|
+ |
|
} |
|
|
|
for (regno = AX_REG; regno <= SP_REG; regno++) |
|
@@ -9054,7 +9025,7 @@ ix86_code_end (void) |
|
tree decl; |
|
|
|
if ((indirect_thunks_used & (1 << regno))) |
|
- output_indirect_thunk_function (regno); |
|
+ output_indirect_thunk_function (regno, false); |
|
|
|
if (!(pic_labels_used & (1 << regno))) |
|
continue; |
|
@@ -24758,8 +24729,8 @@ ix86_output_function_return (bool long_p) |
|
{ |
|
bool need_thunk = (cfun->machine->function_return_type |
|
== indirect_branch_thunk); |
|
- indirect_thunk_name (thunk_name, -1, true); |
|
- indirect_thunk_needed |= need_thunk; |
|
+ indirect_thunk_name (thunk_name, INVALID_REGNUM, true); |
|
+ indirect_return_needed |= need_thunk; |
|
fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); |
|
} |
|
else |
|
@@ -24783,8 +24754,6 @@ ix86_output_indirect_function_return (rtx ret_op) |
|
if (cfun->machine->function_return_type != indirect_branch_keep) |
|
{ |
|
char thunk_name[32]; |
|
- enum indirect_thunk_prefix need_prefix |
|
- = indirect_thunk_need_prefix (current_output_insn); |
|
unsigned int regno = REGNO (ret_op); |
|
gcc_assert (regno == CX_REG); |
|
|
|
@@ -24793,7 +24762,7 @@ ix86_output_indirect_function_return (rtx ret_op) |
|
{ |
|
bool need_thunk = (cfun->machine->function_return_type |
|
== indirect_branch_thunk); |
|
- indirect_thunk_name (thunk_name, regno, need_prefix, true); |
|
+ indirect_thunk_name (thunk_name, regno, true); |
|
if (need_thunk) |
|
{ |
|
indirect_return_via_cx = true; |
|
@@ -24802,7 +24771,7 @@ ix86_output_indirect_function_return (rtx ret_op) |
|
fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); |
|
} |
|
else |
|
- output_indirect_thunk (need_prefix, regno); |
|
+ output_indirect_thunk (regno); |
|
|
|
return ""; |
|
} |
|
diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c |
|
index d1db41cc128..a605c26c46f 100644 |
|
--- a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c |
|
+++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c |
|
@@ -13,7 +13,7 @@ foo (void) |
|
/* { 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_return_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 } && *-*-linux* } } } } */
|
|
|