summaryrefslogtreecommitdiff
path: root/gcc48-rh1537828-8.patch
blob: 4f309a799efd0ce511da1b8cc5f65c84588f5443 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
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* } } } } */