diff options
author | Juro Bystricky <juro.bystricky@intel.com> | 2018-03-01 10:32:43 -0800 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2018-03-14 07:54:06 -0700 |
commit | 6f57e8a418dfd917e492ee51485d8934d4696a39 (patch) | |
tree | 65e6bd9b52a374a1e479065dd54242fa939c6e47 | |
parent | 4732d2936cf22dbf2a3fd5548157fa281045e1a4 (diff) | |
download | poky-6f57e8a418dfd917e492ee51485d8934d4696a39.tar.gz |
gcc6: Backport few more patches
Backported series of patches from https://github.com/hjl-tools/gcc.git
branch /hjl/indirect/gcc-6-branch/master which contains
an IA patch series for security related issues
(From OE-Core rev: f59291f9a3a7ef65206ef0503ce27eb61dc95caf)
Signed-off-by: Juro Bystricky <juro.bystricky@intel.com>
Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
13 files changed, 7207 insertions, 0 deletions
diff --git a/meta/recipes-devtools/gcc/gcc-6.4.inc b/meta/recipes-devtools/gcc/gcc-6.4.inc index 1a4a0ed128..0216f57431 100644 --- a/meta/recipes-devtools/gcc/gcc-6.4.inc +++ b/meta/recipes-devtools/gcc/gcc-6.4.inc | |||
@@ -82,7 +82,20 @@ BACKPORTS = "\ | |||
82 | file://CVE-2016-6131.patch \ | 82 | file://CVE-2016-6131.patch \ |
83 | file://0057-ARM-PR-82445-suppress-32-bit-aligned-ldrd-strd-peeph.patch \ | 83 | file://0057-ARM-PR-82445-suppress-32-bit-aligned-ldrd-strd-peeph.patch \ |
84 | file://0001-enable-FL_LPAE-flag-for-armv7ve-cores.patch \ | 84 | file://0001-enable-FL_LPAE-flag-for-armv7ve-cores.patch \ |
85 | file://0001-i386-Move-struct-ix86_frame-to-machine_function.patch \ | ||
86 | file://0002-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch \ | ||
87 | file://0003-i386-Use-const-reference-of-struct-ix86_frame-to-avo.patch \ | ||
88 | file://0004-x86-Add-mindirect-branch.patch \ | ||
89 | file://0005-x86-Add-mfunction-return.patch \ | ||
90 | file://0006-x86-Add-mindirect-branch-register.patch \ | ||
91 | file://0007-x86-Add-V-register-operand-modifier.patch \ | ||
92 | file://0008-x86-Disallow-mindirect-branch-mfunction-return-with-.patch \ | ||
93 | file://0009-Use-INVALID_REGNUM-in-indirect-thunk-processing.patch \ | ||
94 | file://0010-i386-Pass-INVALID_REGNUM-as-invalid-register-number.patch \ | ||
95 | file://0011-i386-Update-mfunction-return-for-return-with-pop.patch \ | ||
96 | file://0012-i386-Add-TARGET_INDIRECT_BRANCH_REGISTER.patch \ | ||
85 | " | 97 | " |
98 | |||
86 | SRC_URI[md5sum] = "11ba51a0cfb8471927f387c8895fe232" | 99 | SRC_URI[md5sum] = "11ba51a0cfb8471927f387c8895fe232" |
87 | SRC_URI[sha256sum] = "850bf21eafdfe5cd5f6827148184c08c4a0852a37ccf36ce69855334d2c914d4" | 100 | SRC_URI[sha256sum] = "850bf21eafdfe5cd5f6827148184c08c4a0852a37ccf36ce69855334d2c914d4" |
88 | 101 | ||
diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0001-i386-Move-struct-ix86_frame-to-machine_function.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0001-i386-Move-struct-ix86_frame-to-machine_function.patch new file mode 100644 index 0000000000..00b0ffd156 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0001-i386-Move-struct-ix86_frame-to-machine_function.patch | |||
@@ -0,0 +1,247 @@ | |||
1 | From c2c7775c5587dc59b6756162d390d89d60971a16 Mon Sep 17 00:00:00 2001 | ||
2 | From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> | ||
3 | Date: Mon, 15 Jan 2018 11:27:24 +0000 | ||
4 | Subject: [PATCH 01/12] i386: Move struct ix86_frame to machine_function | ||
5 | |||
6 | Make ix86_frame available to i386 code generation. This is needed to | ||
7 | backport the patch set of -mindirect-branch= to mitigate variant #2 of | ||
8 | the speculative execution vulnerabilities on x86 processors identified | ||
9 | by CVE-2017-5715, aka Spectre. | ||
10 | |||
11 | Backport from mainline | ||
12 | 2017-06-01 Bernd Edlinger <bernd.edlinger@hotmail.de> | ||
13 | |||
14 | * config/i386/i386.c (ix86_frame): Moved to ... | ||
15 | * config/i386/i386.h (ix86_frame): Here. | ||
16 | (machine_function): Add frame. | ||
17 | * config/i386/i386.c (ix86_compute_frame_layout): Repace the | ||
18 | frame argument with &cfun->machine->frame. | ||
19 | (ix86_can_use_return_insn_p): Don't pass &frame to | ||
20 | ix86_compute_frame_layout. Copy frame from cfun->machine->frame. | ||
21 | (ix86_can_eliminate): Likewise. | ||
22 | (ix86_expand_prologue): Likewise. | ||
23 | (ix86_expand_epilogue): Likewise. | ||
24 | (ix86_expand_split_stack_prologue): Likewise. | ||
25 | |||
26 | |||
27 | Upstream-Status: Pending | ||
28 | |||
29 | Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> | ||
30 | |||
31 | --- | ||
32 | gcc/config/i386/i386.c | 68 ++++++++++---------------------------------------- | ||
33 | gcc/config/i386/i386.h | 53 ++++++++++++++++++++++++++++++++++++++- | ||
34 | 2 files changed, 65 insertions(+), 56 deletions(-) | ||
35 | |||
36 | diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c | ||
37 | index 8b5faac..a1ff32b 100644 | ||
38 | --- a/gcc/config/i386/i386.c | ||
39 | +++ b/gcc/config/i386/i386.c | ||
40 | @@ -2434,53 +2434,6 @@ struct GTY(()) stack_local_entry { | ||
41 | struct stack_local_entry *next; | ||
42 | }; | ||
43 | |||
44 | -/* Structure describing stack frame layout. | ||
45 | - Stack grows downward: | ||
46 | - | ||
47 | - [arguments] | ||
48 | - <- ARG_POINTER | ||
49 | - saved pc | ||
50 | - | ||
51 | - saved static chain if ix86_static_chain_on_stack | ||
52 | - | ||
53 | - saved frame pointer if frame_pointer_needed | ||
54 | - <- HARD_FRAME_POINTER | ||
55 | - [saved regs] | ||
56 | - <- regs_save_offset | ||
57 | - [padding0] | ||
58 | - | ||
59 | - [saved SSE regs] | ||
60 | - <- sse_regs_save_offset | ||
61 | - [padding1] | | ||
62 | - | <- FRAME_POINTER | ||
63 | - [va_arg registers] | | ||
64 | - | | ||
65 | - [frame] | | ||
66 | - | | ||
67 | - [padding2] | = to_allocate | ||
68 | - <- STACK_POINTER | ||
69 | - */ | ||
70 | -struct ix86_frame | ||
71 | -{ | ||
72 | - int nsseregs; | ||
73 | - int nregs; | ||
74 | - int va_arg_size; | ||
75 | - int red_zone_size; | ||
76 | - int outgoing_arguments_size; | ||
77 | - | ||
78 | - /* The offsets relative to ARG_POINTER. */ | ||
79 | - HOST_WIDE_INT frame_pointer_offset; | ||
80 | - HOST_WIDE_INT hard_frame_pointer_offset; | ||
81 | - HOST_WIDE_INT stack_pointer_offset; | ||
82 | - HOST_WIDE_INT hfp_save_offset; | ||
83 | - HOST_WIDE_INT reg_save_offset; | ||
84 | - HOST_WIDE_INT sse_reg_save_offset; | ||
85 | - | ||
86 | - /* When save_regs_using_mov is set, emit prologue using | ||
87 | - move instead of push instructions. */ | ||
88 | - bool save_regs_using_mov; | ||
89 | -}; | ||
90 | - | ||
91 | /* Which cpu are we scheduling for. */ | ||
92 | enum attr_cpu ix86_schedule; | ||
93 | |||
94 | @@ -2572,7 +2525,7 @@ static unsigned int ix86_function_arg_boundary (machine_mode, | ||
95 | const_tree); | ||
96 | static rtx ix86_static_chain (const_tree, bool); | ||
97 | static int ix86_function_regparm (const_tree, const_tree); | ||
98 | -static void ix86_compute_frame_layout (struct ix86_frame *); | ||
99 | +static void ix86_compute_frame_layout (void); | ||
100 | static bool ix86_expand_vector_init_one_nonzero (bool, machine_mode, | ||
101 | rtx, rtx, int); | ||
102 | static void ix86_add_new_builtins (HOST_WIDE_INT); | ||
103 | @@ -10944,7 +10897,8 @@ ix86_can_use_return_insn_p (void) | ||
104 | if (crtl->args.pops_args && crtl->args.size >= 32768) | ||
105 | return 0; | ||
106 | |||
107 | - ix86_compute_frame_layout (&frame); | ||
108 | + ix86_compute_frame_layout (); | ||
109 | + frame = cfun->machine->frame; | ||
110 | return (frame.stack_pointer_offset == UNITS_PER_WORD | ||
111 | && (frame.nregs + frame.nsseregs) == 0); | ||
112 | } | ||
113 | @@ -11355,8 +11309,8 @@ ix86_can_eliminate (const int from, const int to) | ||
114 | HOST_WIDE_INT | ||
115 | ix86_initial_elimination_offset (int from, int to) | ||
116 | { | ||
117 | - struct ix86_frame frame; | ||
118 | - ix86_compute_frame_layout (&frame); | ||
119 | + ix86_compute_frame_layout (); | ||
120 | + struct ix86_frame frame = cfun->machine->frame; | ||
121 | |||
122 | if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM) | ||
123 | return frame.hard_frame_pointer_offset; | ||
124 | @@ -11395,8 +11349,9 @@ ix86_builtin_setjmp_frame_value (void) | ||
125 | /* Fill structure ix86_frame about frame of currently computed function. */ | ||
126 | |||
127 | static void | ||
128 | -ix86_compute_frame_layout (struct ix86_frame *frame) | ||
129 | +ix86_compute_frame_layout (void) | ||
130 | { | ||
131 | + struct ix86_frame *frame = &cfun->machine->frame; | ||
132 | unsigned HOST_WIDE_INT stack_alignment_needed; | ||
133 | HOST_WIDE_INT offset; | ||
134 | unsigned HOST_WIDE_INT preferred_alignment; | ||
135 | @@ -12702,7 +12657,8 @@ ix86_expand_prologue (void) | ||
136 | m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET; | ||
137 | m->fs.sp_valid = true; | ||
138 | |||
139 | - ix86_compute_frame_layout (&frame); | ||
140 | + ix86_compute_frame_layout (); | ||
141 | + frame = m->frame; | ||
142 | |||
143 | if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl)) | ||
144 | { | ||
145 | @@ -13379,7 +13335,8 @@ ix86_expand_epilogue (int style) | ||
146 | bool using_drap; | ||
147 | |||
148 | ix86_finalize_stack_realign_flags (); | ||
149 | - ix86_compute_frame_layout (&frame); | ||
150 | + ix86_compute_frame_layout (); | ||
151 | + frame = m->frame; | ||
152 | |||
153 | m->fs.sp_valid = (!frame_pointer_needed | ||
154 | || (crtl->sp_is_unchanging | ||
155 | @@ -13876,7 +13833,8 @@ ix86_expand_split_stack_prologue (void) | ||
156 | gcc_assert (flag_split_stack && reload_completed); | ||
157 | |||
158 | ix86_finalize_stack_realign_flags (); | ||
159 | - ix86_compute_frame_layout (&frame); | ||
160 | + ix86_compute_frame_layout (); | ||
161 | + frame = cfun->machine->frame; | ||
162 | allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET; | ||
163 | |||
164 | /* This is the label we will branch to if we have enough stack | ||
165 | diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h | ||
166 | index 8113f83..5414416 100644 | ||
167 | --- a/gcc/config/i386/i386.h | ||
168 | +++ b/gcc/config/i386/i386.h | ||
169 | @@ -2427,9 +2427,56 @@ enum avx_u128_state | ||
170 | |||
171 | #define FASTCALL_PREFIX '@' | ||
172 | |||
173 | +#ifndef USED_FOR_TARGET | ||
174 | +/* Structure describing stack frame layout. | ||
175 | + Stack grows downward: | ||
176 | + | ||
177 | + [arguments] | ||
178 | + <- ARG_POINTER | ||
179 | + saved pc | ||
180 | + | ||
181 | + saved static chain if ix86_static_chain_on_stack | ||
182 | + | ||
183 | + saved frame pointer if frame_pointer_needed | ||
184 | + <- HARD_FRAME_POINTER | ||
185 | + [saved regs] | ||
186 | + <- regs_save_offset | ||
187 | + [padding0] | ||
188 | + | ||
189 | + [saved SSE regs] | ||
190 | + <- sse_regs_save_offset | ||
191 | + [padding1] | | ||
192 | + | <- FRAME_POINTER | ||
193 | + [va_arg registers] | | ||
194 | + | | ||
195 | + [frame] | | ||
196 | + | | ||
197 | + [padding2] | = to_allocate | ||
198 | + <- STACK_POINTER | ||
199 | + */ | ||
200 | +struct GTY(()) ix86_frame | ||
201 | +{ | ||
202 | + int nsseregs; | ||
203 | + int nregs; | ||
204 | + int va_arg_size; | ||
205 | + int red_zone_size; | ||
206 | + int outgoing_arguments_size; | ||
207 | + | ||
208 | + /* The offsets relative to ARG_POINTER. */ | ||
209 | + HOST_WIDE_INT frame_pointer_offset; | ||
210 | + HOST_WIDE_INT hard_frame_pointer_offset; | ||
211 | + HOST_WIDE_INT stack_pointer_offset; | ||
212 | + HOST_WIDE_INT hfp_save_offset; | ||
213 | + HOST_WIDE_INT reg_save_offset; | ||
214 | + HOST_WIDE_INT sse_reg_save_offset; | ||
215 | + | ||
216 | + /* When save_regs_using_mov is set, emit prologue using | ||
217 | + move instead of push instructions. */ | ||
218 | + bool save_regs_using_mov; | ||
219 | +}; | ||
220 | + | ||
221 | /* Machine specific frame tracking during prologue/epilogue generation. */ | ||
222 | |||
223 | -#ifndef USED_FOR_TARGET | ||
224 | struct GTY(()) machine_frame_state | ||
225 | { | ||
226 | /* This pair tracks the currently active CFA as reg+offset. When reg | ||
227 | @@ -2475,6 +2522,9 @@ struct GTY(()) machine_function { | ||
228 | int varargs_fpr_size; | ||
229 | int optimize_mode_switching[MAX_386_ENTITIES]; | ||
230 | |||
231 | + /* Cached initial frame layout for the current function. */ | ||
232 | + struct ix86_frame frame; | ||
233 | + | ||
234 | /* Number of saved registers USE_FAST_PROLOGUE_EPILOGUE | ||
235 | has been computed for. */ | ||
236 | int use_fast_prologue_epilogue_nregs; | ||
237 | @@ -2554,6 +2604,7 @@ struct GTY(()) machine_function { | ||
238 | #define ix86_current_function_calls_tls_descriptor \ | ||
239 | (ix86_tls_descriptor_calls_expanded_in_cfun && df_regs_ever_live_p (SP_REG)) | ||
240 | #define ix86_static_chain_on_stack (cfun->machine->static_chain_on_stack) | ||
241 | +#define ix86_red_zone_size (cfun->machine->frame.red_zone_size) | ||
242 | |||
243 | /* Control behavior of x86_file_start. */ | ||
244 | #define X86_FILE_START_VERSION_DIRECTIVE false | ||
245 | -- | ||
246 | 2.7.4 | ||
247 | |||
diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0002-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0002-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch new file mode 100644 index 0000000000..df65b08f93 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0002-i386-Use-reference-of-struct-ix86_frame-to-avoid-cop.patch | |||
@@ -0,0 +1,74 @@ | |||
1 | From fe2b3be3f4b6ec6b3a6f89c26016a3983b7cb351 Mon Sep 17 00:00:00 2001 | ||
2 | From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> | ||
3 | Date: Mon, 15 Jan 2018 11:28:44 +0000 | ||
4 | Subject: [PATCH 02/12] i386: Use reference of struct ix86_frame to avoid copy | ||
5 | |||
6 | When there is no need to make a copy of ix86_frame, we can use reference | ||
7 | of struct ix86_frame to avoid copy. | ||
8 | |||
9 | Backport from mainline | ||
10 | 2017-11-06 H.J. Lu <hongjiu.lu@intel.com> | ||
11 | |||
12 | * config/i386/i386.c (ix86_can_use_return_insn_p): Use reference | ||
13 | of struct ix86_frame. | ||
14 | (ix86_initial_elimination_offset): Likewise. | ||
15 | (ix86_expand_split_stack_prologue): Likewise. | ||
16 | |||
17 | Upstream-Status: Pending | ||
18 | |||
19 | Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> | ||
20 | |||
21 | --- | ||
22 | gcc/config/i386/i386.c | 8 +++----- | ||
23 | 1 file changed, 3 insertions(+), 5 deletions(-) | ||
24 | |||
25 | diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c | ||
26 | index a1ff32b..13ebf10 100644 | ||
27 | --- a/gcc/config/i386/i386.c | ||
28 | +++ b/gcc/config/i386/i386.c | ||
29 | @@ -10887,7 +10887,6 @@ symbolic_reference_mentioned_p (rtx op) | ||
30 | bool | ||
31 | ix86_can_use_return_insn_p (void) | ||
32 | { | ||
33 | - struct ix86_frame frame; | ||
34 | |||
35 | if (! reload_completed || frame_pointer_needed) | ||
36 | return 0; | ||
37 | @@ -10898,7 +10897,7 @@ ix86_can_use_return_insn_p (void) | ||
38 | return 0; | ||
39 | |||
40 | ix86_compute_frame_layout (); | ||
41 | - frame = cfun->machine->frame; | ||
42 | + struct ix86_frame &frame = cfun->machine->frame; | ||
43 | return (frame.stack_pointer_offset == UNITS_PER_WORD | ||
44 | && (frame.nregs + frame.nsseregs) == 0); | ||
45 | } | ||
46 | @@ -11310,7 +11309,7 @@ HOST_WIDE_INT | ||
47 | ix86_initial_elimination_offset (int from, int to) | ||
48 | { | ||
49 | ix86_compute_frame_layout (); | ||
50 | - struct ix86_frame frame = cfun->machine->frame; | ||
51 | + struct ix86_frame &frame = cfun->machine->frame; | ||
52 | |||
53 | if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM) | ||
54 | return frame.hard_frame_pointer_offset; | ||
55 | @@ -13821,7 +13820,6 @@ static GTY(()) rtx split_stack_fn_large; | ||
56 | void | ||
57 | ix86_expand_split_stack_prologue (void) | ||
58 | { | ||
59 | - struct ix86_frame frame; | ||
60 | HOST_WIDE_INT allocate; | ||
61 | unsigned HOST_WIDE_INT args_size; | ||
62 | rtx_code_label *label; | ||
63 | @@ -13834,7 +13832,7 @@ ix86_expand_split_stack_prologue (void) | ||
64 | |||
65 | ix86_finalize_stack_realign_flags (); | ||
66 | ix86_compute_frame_layout (); | ||
67 | - frame = cfun->machine->frame; | ||
68 | + struct ix86_frame &frame = cfun->machine->frame; | ||
69 | allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET; | ||
70 | |||
71 | /* This is the label we will branch to if we have enough stack | ||
72 | -- | ||
73 | 2.7.4 | ||
74 | |||
diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0003-i386-Use-const-reference-of-struct-ix86_frame-to-avo.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0003-i386-Use-const-reference-of-struct-ix86_frame-to-avo.patch new file mode 100644 index 0000000000..a5ffd85d6f --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0003-i386-Use-const-reference-of-struct-ix86_frame-to-avo.patch | |||
@@ -0,0 +1,131 @@ | |||
1 | From 82243732dc63e9b90396a5ae4ad99ca36af81355 Mon Sep 17 00:00:00 2001 | ||
2 | From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> | ||
3 | Date: Sat, 27 Jan 2018 13:10:24 +0000 | ||
4 | Subject: [PATCH 03/12] i386: Use const reference of struct ix86_frame to avoid | ||
5 | copy | ||
6 | |||
7 | We can use const reference of struct ix86_frame to avoid making a local | ||
8 | copy of ix86_frame. ix86_expand_epilogue makes a local copy of struct | ||
9 | ix86_frame and uses the reg_save_offset field as a local variable. This | ||
10 | patch uses a separate local variable for reg_save_offset. | ||
11 | |||
12 | Tested on x86-64 with ada. | ||
13 | |||
14 | Backport from mainline | ||
15 | PR target/83905 | ||
16 | * config/i386/i386.c (ix86_expand_prologue): Use cost reference | ||
17 | of struct ix86_frame. | ||
18 | (ix86_expand_epilogue): Likewise. Add a local variable for | ||
19 | the reg_save_offset field in struct ix86_frame. | ||
20 | |||
21 | git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@257123 138bc75d-0d04-0410-961f-82ee72b054a4 | ||
22 | |||
23 | Upstream-Status: Pending | ||
24 | |||
25 | Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> | ||
26 | |||
27 | --- | ||
28 | gcc/config/i386/i386.c | 24 ++++++++++++------------ | ||
29 | 1 file changed, 12 insertions(+), 12 deletions(-) | ||
30 | |||
31 | diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c | ||
32 | index 13ebf10..6c98f75 100644 | ||
33 | --- a/gcc/config/i386/i386.c | ||
34 | +++ b/gcc/config/i386/i386.c | ||
35 | @@ -12633,7 +12633,6 @@ ix86_expand_prologue (void) | ||
36 | { | ||
37 | struct machine_function *m = cfun->machine; | ||
38 | rtx insn, t; | ||
39 | - struct ix86_frame frame; | ||
40 | HOST_WIDE_INT allocate; | ||
41 | bool int_registers_saved; | ||
42 | bool sse_registers_saved; | ||
43 | @@ -12657,7 +12656,7 @@ ix86_expand_prologue (void) | ||
44 | m->fs.sp_valid = true; | ||
45 | |||
46 | ix86_compute_frame_layout (); | ||
47 | - frame = m->frame; | ||
48 | + const struct ix86_frame &frame = cfun->machine->frame; | ||
49 | |||
50 | if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl)) | ||
51 | { | ||
52 | @@ -13329,13 +13328,12 @@ ix86_expand_epilogue (int style) | ||
53 | { | ||
54 | struct machine_function *m = cfun->machine; | ||
55 | struct machine_frame_state frame_state_save = m->fs; | ||
56 | - struct ix86_frame frame; | ||
57 | bool restore_regs_via_mov; | ||
58 | bool using_drap; | ||
59 | |||
60 | ix86_finalize_stack_realign_flags (); | ||
61 | ix86_compute_frame_layout (); | ||
62 | - frame = m->frame; | ||
63 | + const struct ix86_frame &frame = cfun->machine->frame; | ||
64 | |||
65 | m->fs.sp_valid = (!frame_pointer_needed | ||
66 | || (crtl->sp_is_unchanging | ||
67 | @@ -13377,11 +13375,13 @@ ix86_expand_epilogue (int style) | ||
68 | + UNITS_PER_WORD); | ||
69 | } | ||
70 | |||
71 | + HOST_WIDE_INT reg_save_offset = frame.reg_save_offset; | ||
72 | + | ||
73 | /* Special care must be taken for the normal return case of a function | ||
74 | using eh_return: the eax and edx registers are marked as saved, but | ||
75 | not restored along this path. Adjust the save location to match. */ | ||
76 | if (crtl->calls_eh_return && style != 2) | ||
77 | - frame.reg_save_offset -= 2 * UNITS_PER_WORD; | ||
78 | + reg_save_offset -= 2 * UNITS_PER_WORD; | ||
79 | |||
80 | /* EH_RETURN requires the use of moves to function properly. */ | ||
81 | if (crtl->calls_eh_return) | ||
82 | @@ -13397,11 +13397,11 @@ ix86_expand_epilogue (int style) | ||
83 | else if (TARGET_EPILOGUE_USING_MOVE | ||
84 | && cfun->machine->use_fast_prologue_epilogue | ||
85 | && (frame.nregs > 1 | ||
86 | - || m->fs.sp_offset != frame.reg_save_offset)) | ||
87 | + || m->fs.sp_offset != reg_save_offset)) | ||
88 | restore_regs_via_mov = true; | ||
89 | else if (frame_pointer_needed | ||
90 | && !frame.nregs | ||
91 | - && m->fs.sp_offset != frame.reg_save_offset) | ||
92 | + && m->fs.sp_offset != reg_save_offset) | ||
93 | restore_regs_via_mov = true; | ||
94 | else if (frame_pointer_needed | ||
95 | && TARGET_USE_LEAVE | ||
96 | @@ -13439,7 +13439,7 @@ ix86_expand_epilogue (int style) | ||
97 | rtx t; | ||
98 | |||
99 | if (frame.nregs) | ||
100 | - ix86_emit_restore_regs_using_mov (frame.reg_save_offset, style == 2); | ||
101 | + ix86_emit_restore_regs_using_mov (reg_save_offset, style == 2); | ||
102 | |||
103 | /* eh_return epilogues need %ecx added to the stack pointer. */ | ||
104 | if (style == 2) | ||
105 | @@ -13529,19 +13529,19 @@ ix86_expand_epilogue (int style) | ||
106 | epilogues. */ | ||
107 | if (!m->fs.sp_valid | ||
108 | || (TARGET_SEH | ||
109 | - && (m->fs.sp_offset - frame.reg_save_offset | ||
110 | + && (m->fs.sp_offset - reg_save_offset | ||
111 | >= SEH_MAX_FRAME_SIZE))) | ||
112 | { | ||
113 | pro_epilogue_adjust_stack (stack_pointer_rtx, hard_frame_pointer_rtx, | ||
114 | GEN_INT (m->fs.fp_offset | ||
115 | - - frame.reg_save_offset), | ||
116 | + - reg_save_offset), | ||
117 | style, false); | ||
118 | } | ||
119 | - else if (m->fs.sp_offset != frame.reg_save_offset) | ||
120 | + else if (m->fs.sp_offset != reg_save_offset) | ||
121 | { | ||
122 | pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx, | ||
123 | GEN_INT (m->fs.sp_offset | ||
124 | - - frame.reg_save_offset), | ||
125 | + - reg_save_offset), | ||
126 | style, | ||
127 | m->fs.cfa_reg == stack_pointer_rtx); | ||
128 | } | ||
129 | -- | ||
130 | 2.7.4 | ||
131 | |||
diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0004-x86-Add-mindirect-branch.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0004-x86-Add-mindirect-branch.patch new file mode 100644 index 0000000000..a9d6e5ff2d --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0004-x86-Add-mindirect-branch.patch | |||
@@ -0,0 +1,2154 @@ | |||
1 | From 6140c2c0bb2b61e69d0da84315e0433ff3520aaa Mon Sep 17 00:00:00 2001 | ||
2 | From: "H.J. Lu" <hjl.tools@gmail.com> | ||
3 | Date: Sat, 6 Jan 2018 22:29:55 -0800 | ||
4 | Subject: [PATCH 04/12] x86: Add -mindirect-branch= | ||
5 | |||
6 | Add -mindirect-branch= option to convert indirect call and jump to call | ||
7 | and return thunks. The default is 'keep', which keeps indirect call and | ||
8 | jump unmodified. 'thunk' converts indirect call and jump to call and | ||
9 | return thunk. 'thunk-inline' converts indirect call and jump to inlined | ||
10 | call and return thunk. 'thunk-extern' converts indirect call and jump to | ||
11 | external call and return thunk provided in a separate object file. You | ||
12 | can control this behavior for a specific function by using the function | ||
13 | attribute indirect_branch. | ||
14 | |||
15 | 2 kinds of thunks are geneated. Memory thunk where the function address | ||
16 | is at the top of the stack: | ||
17 | |||
18 | __x86_indirect_thunk: | ||
19 | call L2 | ||
20 | L1: | ||
21 | pause | ||
22 | lfence | ||
23 | jmp L1 | ||
24 | L2: | ||
25 | lea 8(%rsp), %rsp|lea 4(%esp), %esp | ||
26 | ret | ||
27 | |||
28 | Indirect jmp via memory, "jmp mem", is converted to | ||
29 | |||
30 | push memory | ||
31 | jmp __x86_indirect_thunk | ||
32 | |||
33 | Indirect call via memory, "call mem", is converted to | ||
34 | |||
35 | jmp L2 | ||
36 | L1: | ||
37 | push [mem] | ||
38 | jmp __x86_indirect_thunk | ||
39 | L2: | ||
40 | call L1 | ||
41 | |||
42 | Register thunk where the function address is in a register, reg: | ||
43 | |||
44 | __x86_indirect_thunk_reg: | ||
45 | call L2 | ||
46 | L1: | ||
47 | pause | ||
48 | lfence | ||
49 | jmp L1 | ||
50 | L2: | ||
51 | movq %reg, (%rsp)|movl %reg, (%esp) | ||
52 | ret | ||
53 | |||
54 | where reg is one of (r|e)ax, (r|e)dx, (r|e)cx, (r|e)bx, (r|e)si, (r|e)di, | ||
55 | (r|e)bp, r8, r9, r10, r11, r12, r13, r14 and r15. | ||
56 | |||
57 | Indirect jmp via register, "jmp reg", is converted to | ||
58 | |||
59 | jmp __x86_indirect_thunk_reg | ||
60 | |||
61 | Indirect call via register, "call reg", is converted to | ||
62 | |||
63 | call __x86_indirect_thunk_reg | ||
64 | |||
65 | gcc/ | ||
66 | |||
67 | Backport from mainline | ||
68 | 2018-01-14 H.J. Lu <hongjiu.lu@intel.com> | ||
69 | |||
70 | * config/i386/i386-opts.h (indirect_branch): New. | ||
71 | * config/i386/i386-protos.h (ix86_output_indirect_jmp): Likewise. | ||
72 | * config/i386/i386.c (ix86_using_red_zone): Disallow red-zone | ||
73 | with local indirect jump when converting indirect call and jump. | ||
74 | (ix86_set_indirect_branch_type): New. | ||
75 | (ix86_set_current_function): Call ix86_set_indirect_branch_type. | ||
76 | (indirectlabelno): New. | ||
77 | (indirect_thunk_needed): Likewise. | ||
78 | (indirect_thunk_bnd_needed): Likewise. | ||
79 | (indirect_thunks_used): Likewise. | ||
80 | (indirect_thunks_bnd_used): Likewise. | ||
81 | (INDIRECT_LABEL): Likewise. | ||
82 | (indirect_thunk_name): Likewise. | ||
83 | (output_indirect_thunk): Likewise. | ||
84 | (output_indirect_thunk_function): Likewise. | ||
85 | (ix86_output_indirect_branch_via_reg): Likewise. | ||
86 | (ix86_output_indirect_branch_via_push): Likewise. | ||
87 | (ix86_output_indirect_branch): Likewise. | ||
88 | (ix86_output_indirect_jmp): Likewise. | ||
89 | (ix86_code_end): Call output_indirect_thunk_function if needed. | ||
90 | (ix86_output_call_insn): Call ix86_output_indirect_branch if | ||
91 | needed. | ||
92 | (ix86_handle_fndecl_attribute): Handle indirect_branch. | ||
93 | (ix86_attribute_table): Add indirect_branch. | ||
94 | * config/i386/i386.h (machine_function): Add indirect_branch_type | ||
95 | and has_local_indirect_jump. | ||
96 | * config/i386/i386.md (indirect_jump): Set has_local_indirect_jump | ||
97 | to true. | ||
98 | (tablejump): Likewise. | ||
99 | (*indirect_jump): Use ix86_output_indirect_jmp. | ||
100 | (*tablejump_1): Likewise. | ||
101 | (simple_return_indirect_internal): Likewise. | ||
102 | * config/i386/i386.opt (mindirect-branch=): New option. | ||
103 | (indirect_branch): New. | ||
104 | (keep): Likewise. | ||
105 | (thunk): Likewise. | ||
106 | (thunk-inline): Likewise. | ||
107 | (thunk-extern): Likewise. | ||
108 | * doc/extend.texi: Document indirect_branch function attribute. | ||
109 | * doc/invoke.texi: Document -mindirect-branch= option. | ||
110 | |||
111 | gcc/testsuite/ | ||
112 | |||
113 | Backport from mainline | ||
114 | 2018-01-14 H.J. Lu <hongjiu.lu@intel.com> | ||
115 | |||
116 | * gcc.target/i386/indirect-thunk-1.c: New test. | ||
117 | * gcc.target/i386/indirect-thunk-2.c: Likewise. | ||
118 | * gcc.target/i386/indirect-thunk-3.c: Likewise. | ||
119 | * gcc.target/i386/indirect-thunk-4.c: Likewise. | ||
120 | * gcc.target/i386/indirect-thunk-5.c: Likewise. | ||
121 | * gcc.target/i386/indirect-thunk-6.c: Likewise. | ||
122 | * gcc.target/i386/indirect-thunk-7.c: Likewise. | ||
123 | * gcc.target/i386/indirect-thunk-attr-1.c: Likewise. | ||
124 | * gcc.target/i386/indirect-thunk-attr-2.c: Likewise. | ||
125 | * gcc.target/i386/indirect-thunk-attr-3.c: Likewise. | ||
126 | * gcc.target/i386/indirect-thunk-attr-4.c: Likewise. | ||
127 | * gcc.target/i386/indirect-thunk-attr-5.c: Likewise. | ||
128 | * gcc.target/i386/indirect-thunk-attr-6.c: Likewise. | ||
129 | * gcc.target/i386/indirect-thunk-attr-7.c: Likewise. | ||
130 | * gcc.target/i386/indirect-thunk-attr-8.c: Likewise. | ||
131 | * gcc.target/i386/indirect-thunk-bnd-1.c: Likewise. | ||
132 | * gcc.target/i386/indirect-thunk-bnd-2.c: Likewise. | ||
133 | * gcc.target/i386/indirect-thunk-bnd-3.c: Likewise. | ||
134 | * gcc.target/i386/indirect-thunk-bnd-4.c: Likewise. | ||
135 | * gcc.target/i386/indirect-thunk-extern-1.c: Likewise. | ||
136 | * gcc.target/i386/indirect-thunk-extern-2.c: Likewise. | ||
137 | * gcc.target/i386/indirect-thunk-extern-3.c: Likewise. | ||
138 | * gcc.target/i386/indirect-thunk-extern-4.c: Likewise. | ||
139 | * gcc.target/i386/indirect-thunk-extern-5.c: Likewise. | ||
140 | * gcc.target/i386/indirect-thunk-extern-6.c: Likewise. | ||
141 | * gcc.target/i386/indirect-thunk-extern-7.c: Likewise. | ||
142 | * gcc.target/i386/indirect-thunk-inline-1.c: Likewise. | ||
143 | * gcc.target/i386/indirect-thunk-inline-2.c: Likewise. | ||
144 | * gcc.target/i386/indirect-thunk-inline-3.c: Likewise. | ||
145 | * gcc.target/i386/indirect-thunk-inline-4.c: Likewise. | ||
146 | * gcc.target/i386/indirect-thunk-inline-5.c: Likewise. | ||
147 | * gcc.target/i386/indirect-thunk-inline-6.c: Likewise. | ||
148 | * gcc.target/i386/indirect-thunk-inline-7.c: Likewise. | ||
149 | |||
150 | Upstream-Status: Pending | ||
151 | |||
152 | Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> | ||
153 | |||
154 | --- | ||
155 | gcc/config/i386/i386-opts.h | 13 + | ||
156 | gcc/config/i386/i386-protos.h | 1 + | ||
157 | gcc/config/i386/i386.c | 639 ++++++++++++++++++++- | ||
158 | gcc/config/i386/i386.h | 7 + | ||
159 | gcc/config/i386/i386.md | 26 +- | ||
160 | gcc/config/i386/i386.opt | 20 + | ||
161 | gcc/doc/extend.texi | 10 + | ||
162 | gcc/doc/invoke.texi | 13 +- | ||
163 | gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 20 + | ||
164 | gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 20 + | ||
165 | gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 21 + | ||
166 | gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 21 + | ||
167 | gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 17 + | ||
168 | gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 18 + | ||
169 | gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 44 ++ | ||
170 | .../gcc.target/i386/indirect-thunk-attr-1.c | 23 + | ||
171 | .../gcc.target/i386/indirect-thunk-attr-2.c | 21 + | ||
172 | .../gcc.target/i386/indirect-thunk-attr-3.c | 23 + | ||
173 | .../gcc.target/i386/indirect-thunk-attr-4.c | 22 + | ||
174 | .../gcc.target/i386/indirect-thunk-attr-5.c | 22 + | ||
175 | .../gcc.target/i386/indirect-thunk-attr-6.c | 21 + | ||
176 | .../gcc.target/i386/indirect-thunk-attr-7.c | 44 ++ | ||
177 | .../gcc.target/i386/indirect-thunk-attr-8.c | 42 ++ | ||
178 | .../gcc.target/i386/indirect-thunk-bnd-1.c | 20 + | ||
179 | .../gcc.target/i386/indirect-thunk-bnd-2.c | 21 + | ||
180 | .../gcc.target/i386/indirect-thunk-bnd-3.c | 19 + | ||
181 | .../gcc.target/i386/indirect-thunk-bnd-4.c | 20 + | ||
182 | .../gcc.target/i386/indirect-thunk-extern-1.c | 19 + | ||
183 | .../gcc.target/i386/indirect-thunk-extern-2.c | 19 + | ||
184 | .../gcc.target/i386/indirect-thunk-extern-3.c | 20 + | ||
185 | .../gcc.target/i386/indirect-thunk-extern-4.c | 20 + | ||
186 | .../gcc.target/i386/indirect-thunk-extern-5.c | 16 + | ||
187 | .../gcc.target/i386/indirect-thunk-extern-6.c | 17 + | ||
188 | .../gcc.target/i386/indirect-thunk-extern-7.c | 43 ++ | ||
189 | .../gcc.target/i386/indirect-thunk-inline-1.c | 20 + | ||
190 | .../gcc.target/i386/indirect-thunk-inline-2.c | 20 + | ||
191 | .../gcc.target/i386/indirect-thunk-inline-3.c | 21 + | ||
192 | .../gcc.target/i386/indirect-thunk-inline-4.c | 21 + | ||
193 | .../gcc.target/i386/indirect-thunk-inline-5.c | 17 + | ||
194 | .../gcc.target/i386/indirect-thunk-inline-6.c | 18 + | ||
195 | .../gcc.target/i386/indirect-thunk-inline-7.c | 44 ++ | ||
196 | 41 files changed, 1486 insertions(+), 17 deletions(-) | ||
197 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | ||
198 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | ||
199 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | ||
200 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | ||
201 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | ||
202 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | ||
203 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | ||
204 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | ||
205 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | ||
206 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | ||
207 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | ||
208 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | ||
209 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | ||
210 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | ||
211 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c | ||
212 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | ||
213 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | ||
214 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | ||
215 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | ||
216 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | ||
217 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | ||
218 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | ||
219 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | ||
220 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | ||
221 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | ||
222 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | ||
223 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | ||
224 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | ||
225 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | ||
226 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | ||
227 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | ||
228 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | ||
229 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | ||
230 | |||
231 | diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h | ||
232 | index b7f92e3..cc21152 100644 | ||
233 | --- a/gcc/config/i386/i386-opts.h | ||
234 | +++ b/gcc/config/i386/i386-opts.h | ||
235 | @@ -99,4 +99,17 @@ enum stack_protector_guard { | ||
236 | SSP_GLOBAL /* global canary */ | ||
237 | }; | ||
238 | |||
239 | +/* This is used to mitigate variant #2 of the speculative execution | ||
240 | + vulnerabilities on x86 processors identified by CVE-2017-5715, aka | ||
241 | + Spectre. They convert indirect branches and function returns to | ||
242 | + call and return thunks to avoid speculative execution via indirect | ||
243 | + call, jmp and ret. */ | ||
244 | +enum indirect_branch { | ||
245 | + indirect_branch_unset = 0, | ||
246 | + indirect_branch_keep, | ||
247 | + indirect_branch_thunk, | ||
248 | + indirect_branch_thunk_inline, | ||
249 | + indirect_branch_thunk_extern | ||
250 | +}; | ||
251 | + | ||
252 | #endif | ||
253 | diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h | ||
254 | index ff47bc1..eca4cbf 100644 | ||
255 | --- a/gcc/config/i386/i386-protos.h | ||
256 | +++ b/gcc/config/i386/i386-protos.h | ||
257 | @@ -311,6 +311,7 @@ extern enum attr_cpu ix86_schedule; | ||
258 | #endif | ||
259 | |||
260 | extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op); | ||
261 | +extern const char * ix86_output_indirect_jmp (rtx call_op, bool ret_p); | ||
262 | extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load, | ||
263 | enum machine_mode mode); | ||
264 | |||
265 | diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c | ||
266 | index 6c98f75..0b9fc4d 100644 | ||
267 | --- a/gcc/config/i386/i386.c | ||
268 | +++ b/gcc/config/i386/i386.c | ||
269 | @@ -3662,12 +3662,23 @@ make_pass_stv (gcc::context *ctxt) | ||
270 | return new pass_stv (ctxt); | ||
271 | } | ||
272 | |||
273 | -/* Return true if a red-zone is in use. */ | ||
274 | +/* Return true if a red-zone is in use. We can't use red-zone when | ||
275 | + there are local indirect jumps, like "indirect_jump" or "tablejump", | ||
276 | + which jumps to another place in the function, since "call" in the | ||
277 | + indirect thunk pushes the return address onto stack, destroying | ||
278 | + red-zone. | ||
279 | + | ||
280 | + TODO: If we can reserve the first 2 WORDs, for PUSH and, another | ||
281 | + for CALL, in red-zone, we can allow local indirect jumps with | ||
282 | + indirect thunk. */ | ||
283 | |||
284 | bool | ||
285 | ix86_using_red_zone (void) | ||
286 | { | ||
287 | - return TARGET_RED_ZONE && !TARGET_64BIT_MS_ABI; | ||
288 | + return (TARGET_RED_ZONE | ||
289 | + && !TARGET_64BIT_MS_ABI | ||
290 | + && (!cfun->machine->has_local_indirect_jump | ||
291 | + || cfun->machine->indirect_branch_type == indirect_branch_keep)); | ||
292 | } | ||
293 | |||
294 | /* Return a string that documents the current -m options. The caller is | ||
295 | @@ -6350,6 +6361,37 @@ ix86_reset_previous_fndecl (void) | ||
296 | ix86_previous_fndecl = NULL_TREE; | ||
297 | } | ||
298 | |||
299 | +/* Set the indirect_branch_type field from the function FNDECL. */ | ||
300 | + | ||
301 | +static void | ||
302 | +ix86_set_indirect_branch_type (tree fndecl) | ||
303 | +{ | ||
304 | + if (cfun->machine->indirect_branch_type == indirect_branch_unset) | ||
305 | + { | ||
306 | + tree attr = lookup_attribute ("indirect_branch", | ||
307 | + DECL_ATTRIBUTES (fndecl)); | ||
308 | + if (attr != NULL) | ||
309 | + { | ||
310 | + tree args = TREE_VALUE (attr); | ||
311 | + if (args == NULL) | ||
312 | + gcc_unreachable (); | ||
313 | + tree cst = TREE_VALUE (args); | ||
314 | + if (strcmp (TREE_STRING_POINTER (cst), "keep") == 0) | ||
315 | + cfun->machine->indirect_branch_type = indirect_branch_keep; | ||
316 | + else if (strcmp (TREE_STRING_POINTER (cst), "thunk") == 0) | ||
317 | + cfun->machine->indirect_branch_type = indirect_branch_thunk; | ||
318 | + else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") == 0) | ||
319 | + cfun->machine->indirect_branch_type = indirect_branch_thunk_inline; | ||
320 | + else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") == 0) | ||
321 | + cfun->machine->indirect_branch_type = indirect_branch_thunk_extern; | ||
322 | + else | ||
323 | + gcc_unreachable (); | ||
324 | + } | ||
325 | + else | ||
326 | + cfun->machine->indirect_branch_type = ix86_indirect_branch; | ||
327 | + } | ||
328 | +} | ||
329 | + | ||
330 | /* Establish appropriate back-end context for processing the function | ||
331 | FNDECL. The argument might be NULL to indicate processing at top | ||
332 | level, outside of any function scope. */ | ||
333 | @@ -6360,7 +6402,13 @@ ix86_set_current_function (tree fndecl) | ||
334 | several times in the course of compiling a function, and we don't want to | ||
335 | slow things down too much or call target_reinit when it isn't safe. */ | ||
336 | if (fndecl == ix86_previous_fndecl) | ||
337 | - return; | ||
338 | + { | ||
339 | + /* There may be 2 function bodies for the same function FNDECL, | ||
340 | + one is extern inline and one isn't. */ | ||
341 | + if (fndecl != NULL_TREE) | ||
342 | + ix86_set_indirect_branch_type (fndecl); | ||
343 | + return; | ||
344 | + } | ||
345 | |||
346 | tree old_tree; | ||
347 | if (ix86_previous_fndecl == NULL_TREE) | ||
348 | @@ -6377,6 +6425,8 @@ ix86_set_current_function (tree fndecl) | ||
349 | return; | ||
350 | } | ||
351 | |||
352 | + ix86_set_indirect_branch_type (fndecl); | ||
353 | + | ||
354 | tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl); | ||
355 | if (new_tree == NULL_TREE) | ||
356 | new_tree = target_option_default_node; | ||
357 | @@ -10962,6 +11012,220 @@ ix86_setup_frame_addresses (void) | ||
358 | # endif | ||
359 | #endif | ||
360 | |||
361 | +/* Label count for call and return thunks. It is used to make unique | ||
362 | + labels in call and return thunks. */ | ||
363 | +static int indirectlabelno; | ||
364 | + | ||
365 | +/* True if call and return thunk functions are needed. */ | ||
366 | +static bool indirect_thunk_needed = false; | ||
367 | +/* True if call and return thunk functions with the BND prefix are | ||
368 | + needed. */ | ||
369 | +static bool indirect_thunk_bnd_needed = false; | ||
370 | + | ||
371 | +/* Bit masks of integer registers, which contain branch target, used | ||
372 | + by call and return thunks functions. */ | ||
373 | +static int indirect_thunks_used; | ||
374 | +/* Bit masks of integer registers, which contain branch target, used | ||
375 | + by call and return thunks functions with the BND prefix. */ | ||
376 | +static int indirect_thunks_bnd_used; | ||
377 | + | ||
378 | +#ifndef INDIRECT_LABEL | ||
379 | +# define INDIRECT_LABEL "LIND" | ||
380 | +#endif | ||
381 | + | ||
382 | +/* Fills in the label name that should be used for the indirect thunk. */ | ||
383 | + | ||
384 | +static void | ||
385 | +indirect_thunk_name (char name[32], int regno, bool need_bnd_p) | ||
386 | +{ | ||
387 | + if (USE_HIDDEN_LINKONCE) | ||
388 | + { | ||
389 | + const char *bnd = need_bnd_p ? "_bnd" : ""; | ||
390 | + if (regno >= 0) | ||
391 | + { | ||
392 | + const char *reg_prefix; | ||
393 | + if (LEGACY_INT_REGNO_P (regno)) | ||
394 | + reg_prefix = TARGET_64BIT ? "r" : "e"; | ||
395 | + else | ||
396 | + reg_prefix = ""; | ||
397 | + sprintf (name, "__x86_indirect_thunk%s_%s%s", | ||
398 | + bnd, reg_prefix, reg_names[regno]); | ||
399 | + } | ||
400 | + else | ||
401 | + sprintf (name, "__x86_indirect_thunk%s", bnd); | ||
402 | + } | ||
403 | + else | ||
404 | + { | ||
405 | + if (regno >= 0) | ||
406 | + { | ||
407 | + if (need_bnd_p) | ||
408 | + ASM_GENERATE_INTERNAL_LABEL (name, "LITBR", regno); | ||
409 | + else | ||
410 | + ASM_GENERATE_INTERNAL_LABEL (name, "LITR", regno); | ||
411 | + } | ||
412 | + else | ||
413 | + { | ||
414 | + if (need_bnd_p) | ||
415 | + ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0); | ||
416 | + else | ||
417 | + ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0); | ||
418 | + } | ||
419 | + } | ||
420 | +} | ||
421 | + | ||
422 | +/* Output a call and return thunk for indirect branch. If BND_P is | ||
423 | + true, the BND prefix is needed. If REGNO != -1, the function | ||
424 | + address is in REGNO and the call and return thunk looks like: | ||
425 | + | ||
426 | + call L2 | ||
427 | + L1: | ||
428 | + pause | ||
429 | + jmp L1 | ||
430 | + L2: | ||
431 | + mov %REG, (%sp) | ||
432 | + ret | ||
433 | + | ||
434 | + Otherwise, the function address is on the top of stack and the | ||
435 | + call and return thunk looks like: | ||
436 | + | ||
437 | + call L2 | ||
438 | + L1: | ||
439 | + pause | ||
440 | + jmp L1 | ||
441 | + L2: | ||
442 | + lea WORD_SIZE(%sp), %sp | ||
443 | + ret | ||
444 | + */ | ||
445 | + | ||
446 | +static void | ||
447 | +output_indirect_thunk (bool need_bnd_p, int regno) | ||
448 | +{ | ||
449 | + char indirectlabel1[32]; | ||
450 | + char indirectlabel2[32]; | ||
451 | + | ||
452 | + ASM_GENERATE_INTERNAL_LABEL (indirectlabel1, INDIRECT_LABEL, | ||
453 | + indirectlabelno++); | ||
454 | + ASM_GENERATE_INTERNAL_LABEL (indirectlabel2, INDIRECT_LABEL, | ||
455 | + indirectlabelno++); | ||
456 | + | ||
457 | + /* Call */ | ||
458 | + if (need_bnd_p) | ||
459 | + fputs ("\tbnd call\t", asm_out_file); | ||
460 | + else | ||
461 | + fputs ("\tcall\t", asm_out_file); | ||
462 | + assemble_name_raw (asm_out_file, indirectlabel2); | ||
463 | + fputc ('\n', asm_out_file); | ||
464 | + | ||
465 | + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1); | ||
466 | + | ||
467 | + /* Pause + lfence. */ | ||
468 | + fprintf (asm_out_file, "\tpause\n\tlfence\n"); | ||
469 | + | ||
470 | + /* Jump. */ | ||
471 | + fputs ("\tjmp\t", asm_out_file); | ||
472 | + assemble_name_raw (asm_out_file, indirectlabel1); | ||
473 | + fputc ('\n', asm_out_file); | ||
474 | + | ||
475 | + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); | ||
476 | + | ||
477 | + if (regno >= 0) | ||
478 | + { | ||
479 | + /* MOV. */ | ||
480 | + rtx xops[2]; | ||
481 | + xops[0] = gen_rtx_MEM (word_mode, stack_pointer_rtx); | ||
482 | + xops[1] = gen_rtx_REG (word_mode, regno); | ||
483 | + output_asm_insn ("mov\t{%1, %0|%0, %1}", xops); | ||
484 | + } | ||
485 | + else | ||
486 | + { | ||
487 | + /* LEA. */ | ||
488 | + rtx xops[2]; | ||
489 | + xops[0] = stack_pointer_rtx; | ||
490 | + xops[1] = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD); | ||
491 | + output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops); | ||
492 | + } | ||
493 | + | ||
494 | + if (need_bnd_p) | ||
495 | + fputs ("\tbnd ret\n", asm_out_file); | ||
496 | + else | ||
497 | + fputs ("\tret\n", asm_out_file); | ||
498 | +} | ||
499 | + | ||
500 | +/* Output a funtion with a call and return thunk for indirect branch. | ||
501 | + If BND_P is true, the BND prefix is needed. If REGNO != -1, the | ||
502 | + function address is in REGNO. Otherwise, the function address is | ||
503 | + on the top of stack. */ | ||
504 | + | ||
505 | +static void | ||
506 | +output_indirect_thunk_function (bool need_bnd_p, int regno) | ||
507 | +{ | ||
508 | + char name[32]; | ||
509 | + tree decl; | ||
510 | + | ||
511 | + /* Create __x86_indirect_thunk/__x86_indirect_thunk_bnd. */ | ||
512 | + indirect_thunk_name (name, regno, need_bnd_p); | ||
513 | + decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, | ||
514 | + get_identifier (name), | ||
515 | + build_function_type_list (void_type_node, NULL_TREE)); | ||
516 | + DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL, | ||
517 | + NULL_TREE, void_type_node); | ||
518 | + TREE_PUBLIC (decl) = 1; | ||
519 | + TREE_STATIC (decl) = 1; | ||
520 | + DECL_IGNORED_P (decl) = 1; | ||
521 | + | ||
522 | +#if TARGET_MACHO | ||
523 | + if (TARGET_MACHO) | ||
524 | + { | ||
525 | + switch_to_section (darwin_sections[picbase_thunk_section]); | ||
526 | + fputs ("\t.weak_definition\t", asm_out_file); | ||
527 | + assemble_name (asm_out_file, name); | ||
528 | + fputs ("\n\t.private_extern\t", asm_out_file); | ||
529 | + assemble_name (asm_out_file, name); | ||
530 | + putc ('\n', asm_out_file); | ||
531 | + ASM_OUTPUT_LABEL (asm_out_file, name); | ||
532 | + DECL_WEAK (decl) = 1; | ||
533 | + } | ||
534 | + else | ||
535 | +#endif | ||
536 | + if (USE_HIDDEN_LINKONCE) | ||
537 | + { | ||
538 | + cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl)); | ||
539 | + | ||
540 | + targetm.asm_out.unique_section (decl, 0); | ||
541 | + switch_to_section (get_named_section (decl, NULL, 0)); | ||
542 | + | ||
543 | + targetm.asm_out.globalize_label (asm_out_file, name); | ||
544 | + fputs ("\t.hidden\t", asm_out_file); | ||
545 | + assemble_name (asm_out_file, name); | ||
546 | + putc ('\n', asm_out_file); | ||
547 | + ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl); | ||
548 | + } | ||
549 | + else | ||
550 | + { | ||
551 | + switch_to_section (text_section); | ||
552 | + ASM_OUTPUT_LABEL (asm_out_file, name); | ||
553 | + } | ||
554 | + | ||
555 | + DECL_INITIAL (decl) = make_node (BLOCK); | ||
556 | + current_function_decl = decl; | ||
557 | + allocate_struct_function (decl, false); | ||
558 | + init_function_start (decl); | ||
559 | + /* We're about to hide the function body from callees of final_* by | ||
560 | + emitting it directly; tell them we're a thunk, if they care. */ | ||
561 | + cfun->is_thunk = true; | ||
562 | + first_function_block_is_cold = false; | ||
563 | + /* Make sure unwind info is emitted for the thunk if needed. */ | ||
564 | + final_start_function (emit_barrier (), asm_out_file, 1); | ||
565 | + | ||
566 | + output_indirect_thunk (need_bnd_p, regno); | ||
567 | + | ||
568 | + final_end_function (); | ||
569 | + init_insn_lengths (); | ||
570 | + free_after_compilation (cfun); | ||
571 | + set_cfun (NULL); | ||
572 | + current_function_decl = NULL; | ||
573 | +} | ||
574 | + | ||
575 | static int pic_labels_used; | ||
576 | |||
577 | /* Fills in the label name that should be used for a pc thunk for | ||
578 | @@ -10988,11 +11252,32 @@ ix86_code_end (void) | ||
579 | rtx xops[2]; | ||
580 | int regno; | ||
581 | |||
582 | + if (indirect_thunk_needed) | ||
583 | + output_indirect_thunk_function (false, -1); | ||
584 | + if (indirect_thunk_bnd_needed) | ||
585 | + output_indirect_thunk_function (true, -1); | ||
586 | + | ||
587 | + for (regno = FIRST_REX_INT_REG; regno <= LAST_REX_INT_REG; regno++) | ||
588 | + { | ||
589 | + int i = regno - FIRST_REX_INT_REG + LAST_INT_REG + 1; | ||
590 | + if ((indirect_thunks_used & (1 << i))) | ||
591 | + output_indirect_thunk_function (false, regno); | ||
592 | + | ||
593 | + if ((indirect_thunks_bnd_used & (1 << i))) | ||
594 | + output_indirect_thunk_function (true, regno); | ||
595 | + } | ||
596 | + | ||
597 | for (regno = AX_REG; regno <= SP_REG; regno++) | ||
598 | { | ||
599 | char name[32]; | ||
600 | tree decl; | ||
601 | |||
602 | + if ((indirect_thunks_used & (1 << regno))) | ||
603 | + output_indirect_thunk_function (false, regno); | ||
604 | + | ||
605 | + if ((indirect_thunks_bnd_used & (1 << regno))) | ||
606 | + output_indirect_thunk_function (true, regno); | ||
607 | + | ||
608 | if (!(pic_labels_used & (1 << regno))) | ||
609 | continue; | ||
610 | |||
611 | @@ -27369,12 +27654,292 @@ ix86_nopic_noplt_attribute_p (rtx call_op) | ||
612 | return false; | ||
613 | } | ||
614 | |||
615 | +/* Output indirect branch via a call and return thunk. CALL_OP is a | ||
616 | + register which contains the branch target. XASM is the assembly | ||
617 | + template for CALL_OP. Branch is a tail call if SIBCALL_P is true. | ||
618 | + A normal call is converted to: | ||
619 | + | ||
620 | + call __x86_indirect_thunk_reg | ||
621 | + | ||
622 | + and a tail call is converted to: | ||
623 | + | ||
624 | + jmp __x86_indirect_thunk_reg | ||
625 | + */ | ||
626 | + | ||
627 | +static void | ||
628 | +ix86_output_indirect_branch_via_reg (rtx call_op, bool sibcall_p) | ||
629 | +{ | ||
630 | + char thunk_name_buf[32]; | ||
631 | + char *thunk_name; | ||
632 | + bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn); | ||
633 | + int regno = REGNO (call_op); | ||
634 | + | ||
635 | + if (cfun->machine->indirect_branch_type | ||
636 | + != indirect_branch_thunk_inline) | ||
637 | + { | ||
638 | + if (cfun->machine->indirect_branch_type == indirect_branch_thunk) | ||
639 | + { | ||
640 | + int i = regno; | ||
641 | + if (i >= FIRST_REX_INT_REG) | ||
642 | + i -= (FIRST_REX_INT_REG - LAST_INT_REG - 1); | ||
643 | + if (need_bnd_p) | ||
644 | + indirect_thunks_bnd_used |= 1 << i; | ||
645 | + else | ||
646 | + indirect_thunks_used |= 1 << i; | ||
647 | + } | ||
648 | + indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); | ||
649 | + thunk_name = thunk_name_buf; | ||
650 | + } | ||
651 | + else | ||
652 | + thunk_name = NULL; | ||
653 | + | ||
654 | + if (sibcall_p) | ||
655 | + { | ||
656 | + if (thunk_name != NULL) | ||
657 | + { | ||
658 | + if (need_bnd_p) | ||
659 | + fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); | ||
660 | + else | ||
661 | + fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); | ||
662 | + } | ||
663 | + else | ||
664 | + output_indirect_thunk (need_bnd_p, regno); | ||
665 | + } | ||
666 | + else | ||
667 | + { | ||
668 | + if (thunk_name != NULL) | ||
669 | + { | ||
670 | + if (need_bnd_p) | ||
671 | + fprintf (asm_out_file, "\tbnd call\t%s\n", thunk_name); | ||
672 | + else | ||
673 | + fprintf (asm_out_file, "\tcall\t%s\n", thunk_name); | ||
674 | + return; | ||
675 | + } | ||
676 | + | ||
677 | + char indirectlabel1[32]; | ||
678 | + char indirectlabel2[32]; | ||
679 | + | ||
680 | + ASM_GENERATE_INTERNAL_LABEL (indirectlabel1, | ||
681 | + INDIRECT_LABEL, | ||
682 | + indirectlabelno++); | ||
683 | + ASM_GENERATE_INTERNAL_LABEL (indirectlabel2, | ||
684 | + INDIRECT_LABEL, | ||
685 | + indirectlabelno++); | ||
686 | + | ||
687 | + /* Jump. */ | ||
688 | + if (need_bnd_p) | ||
689 | + fputs ("\tbnd jmp\t", asm_out_file); | ||
690 | + else | ||
691 | + fputs ("\tjmp\t", asm_out_file); | ||
692 | + assemble_name_raw (asm_out_file, indirectlabel2); | ||
693 | + fputc ('\n', asm_out_file); | ||
694 | + | ||
695 | + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1); | ||
696 | + | ||
697 | + if (thunk_name != NULL) | ||
698 | + { | ||
699 | + if (need_bnd_p) | ||
700 | + fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); | ||
701 | + else | ||
702 | + fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); | ||
703 | + } | ||
704 | + else | ||
705 | + output_indirect_thunk (need_bnd_p, regno); | ||
706 | + | ||
707 | + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); | ||
708 | + | ||
709 | + /* Call. */ | ||
710 | + if (need_bnd_p) | ||
711 | + fputs ("\tbnd call\t", asm_out_file); | ||
712 | + else | ||
713 | + fputs ("\tcall\t", asm_out_file); | ||
714 | + assemble_name_raw (asm_out_file, indirectlabel1); | ||
715 | + fputc ('\n', asm_out_file); | ||
716 | + } | ||
717 | +} | ||
718 | + | ||
719 | +/* Output indirect branch via a call and return thunk. CALL_OP is | ||
720 | + the branch target. XASM is the assembly template for CALL_OP. | ||
721 | + Branch is a tail call if SIBCALL_P is true. A normal call is | ||
722 | + converted to: | ||
723 | + | ||
724 | + jmp L2 | ||
725 | + L1: | ||
726 | + push CALL_OP | ||
727 | + jmp __x86_indirect_thunk | ||
728 | + L2: | ||
729 | + call L1 | ||
730 | + | ||
731 | + and a tail call is converted to: | ||
732 | + | ||
733 | + push CALL_OP | ||
734 | + jmp __x86_indirect_thunk | ||
735 | + */ | ||
736 | + | ||
737 | +static void | ||
738 | +ix86_output_indirect_branch_via_push (rtx call_op, const char *xasm, | ||
739 | + bool sibcall_p) | ||
740 | +{ | ||
741 | + char thunk_name_buf[32]; | ||
742 | + char *thunk_name; | ||
743 | + char push_buf[64]; | ||
744 | + bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn); | ||
745 | + int regno = -1; | ||
746 | + | ||
747 | + if (cfun->machine->indirect_branch_type | ||
748 | + != indirect_branch_thunk_inline) | ||
749 | + { | ||
750 | + if (cfun->machine->indirect_branch_type == indirect_branch_thunk) | ||
751 | + { | ||
752 | + if (need_bnd_p) | ||
753 | + indirect_thunk_bnd_needed = true; | ||
754 | + else | ||
755 | + indirect_thunk_needed = true; | ||
756 | + } | ||
757 | + indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); | ||
758 | + thunk_name = thunk_name_buf; | ||
759 | + } | ||
760 | + else | ||
761 | + thunk_name = NULL; | ||
762 | + | ||
763 | + snprintf (push_buf, sizeof (push_buf), "push{%c}\t%s", | ||
764 | + TARGET_64BIT ? 'q' : 'l', xasm); | ||
765 | + | ||
766 | + if (sibcall_p) | ||
767 | + { | ||
768 | + output_asm_insn (push_buf, &call_op); | ||
769 | + if (thunk_name != NULL) | ||
770 | + { | ||
771 | + if (need_bnd_p) | ||
772 | + fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); | ||
773 | + else | ||
774 | + fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); | ||
775 | + } | ||
776 | + else | ||
777 | + output_indirect_thunk (need_bnd_p, regno); | ||
778 | + } | ||
779 | + else | ||
780 | + { | ||
781 | + char indirectlabel1[32]; | ||
782 | + char indirectlabel2[32]; | ||
783 | + | ||
784 | + ASM_GENERATE_INTERNAL_LABEL (indirectlabel1, | ||
785 | + INDIRECT_LABEL, | ||
786 | + indirectlabelno++); | ||
787 | + ASM_GENERATE_INTERNAL_LABEL (indirectlabel2, | ||
788 | + INDIRECT_LABEL, | ||
789 | + indirectlabelno++); | ||
790 | + | ||
791 | + /* Jump. */ | ||
792 | + if (need_bnd_p) | ||
793 | + fputs ("\tbnd jmp\t", asm_out_file); | ||
794 | + else | ||
795 | + fputs ("\tjmp\t", asm_out_file); | ||
796 | + assemble_name_raw (asm_out_file, indirectlabel2); | ||
797 | + fputc ('\n', asm_out_file); | ||
798 | + | ||
799 | + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1); | ||
800 | + | ||
801 | + /* An external function may be called via GOT, instead of PLT. */ | ||
802 | + if (MEM_P (call_op)) | ||
803 | + { | ||
804 | + struct ix86_address parts; | ||
805 | + rtx addr = XEXP (call_op, 0); | ||
806 | + if (ix86_decompose_address (addr, &parts) | ||
807 | + && parts.base == stack_pointer_rtx) | ||
808 | + { | ||
809 | + /* Since call will adjust stack by -UNITS_PER_WORD, | ||
810 | + we must convert "disp(stack, index, scale)" to | ||
811 | + "disp+UNITS_PER_WORD(stack, index, scale)". */ | ||
812 | + if (parts.index) | ||
813 | + { | ||
814 | + addr = gen_rtx_MULT (Pmode, parts.index, | ||
815 | + GEN_INT (parts.scale)); | ||
816 | + addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, | ||
817 | + addr); | ||
818 | + } | ||
819 | + else | ||
820 | + addr = stack_pointer_rtx; | ||
821 | + | ||
822 | + rtx disp; | ||
823 | + if (parts.disp != NULL_RTX) | ||
824 | + disp = plus_constant (Pmode, parts.disp, | ||
825 | + UNITS_PER_WORD); | ||
826 | + else | ||
827 | + disp = GEN_INT (UNITS_PER_WORD); | ||
828 | + | ||
829 | + addr = gen_rtx_PLUS (Pmode, addr, disp); | ||
830 | + call_op = gen_rtx_MEM (GET_MODE (call_op), addr); | ||
831 | + } | ||
832 | + } | ||
833 | + | ||
834 | + output_asm_insn (push_buf, &call_op); | ||
835 | + | ||
836 | + if (thunk_name != NULL) | ||
837 | + { | ||
838 | + if (need_bnd_p) | ||
839 | + fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); | ||
840 | + else | ||
841 | + fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); | ||
842 | + } | ||
843 | + else | ||
844 | + output_indirect_thunk (need_bnd_p, regno); | ||
845 | + | ||
846 | + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); | ||
847 | + | ||
848 | + /* Call. */ | ||
849 | + if (need_bnd_p) | ||
850 | + fputs ("\tbnd call\t", asm_out_file); | ||
851 | + else | ||
852 | + fputs ("\tcall\t", asm_out_file); | ||
853 | + assemble_name_raw (asm_out_file, indirectlabel1); | ||
854 | + fputc ('\n', asm_out_file); | ||
855 | + } | ||
856 | +} | ||
857 | + | ||
858 | +/* Output indirect branch via a call and return thunk. CALL_OP is | ||
859 | + the branch target. XASM is the assembly template for CALL_OP. | ||
860 | + Branch is a tail call if SIBCALL_P is true. */ | ||
861 | + | ||
862 | +static void | ||
863 | +ix86_output_indirect_branch (rtx call_op, const char *xasm, | ||
864 | + bool sibcall_p) | ||
865 | +{ | ||
866 | + if (REG_P (call_op)) | ||
867 | + ix86_output_indirect_branch_via_reg (call_op, sibcall_p); | ||
868 | + else | ||
869 | + ix86_output_indirect_branch_via_push (call_op, xasm, sibcall_p); | ||
870 | +} | ||
871 | +/* Output indirect jump. CALL_OP is the jump target. Jump is a | ||
872 | + function return if RET_P is true. */ | ||
873 | + | ||
874 | +const char * | ||
875 | +ix86_output_indirect_jmp (rtx call_op, bool ret_p) | ||
876 | +{ | ||
877 | + if (cfun->machine->indirect_branch_type != indirect_branch_keep) | ||
878 | + { | ||
879 | + /* We can't have red-zone if this isn't a function return since | ||
880 | + "call" in the indirect thunk pushes the return address onto | ||
881 | + stack, destroying red-zone. */ | ||
882 | + if (!ret_p && ix86_red_zone_size != 0) | ||
883 | + gcc_unreachable (); | ||
884 | + | ||
885 | + ix86_output_indirect_branch (call_op, "%0", true); | ||
886 | + return ""; | ||
887 | + } | ||
888 | + else | ||
889 | + return "%!jmp\t%A0"; | ||
890 | +} | ||
891 | + | ||
892 | /* Output the assembly for a call instruction. */ | ||
893 | |||
894 | const char * | ||
895 | ix86_output_call_insn (rtx_insn *insn, rtx call_op) | ||
896 | { | ||
897 | bool direct_p = constant_call_address_operand (call_op, VOIDmode); | ||
898 | + bool output_indirect_p | ||
899 | + = (!TARGET_SEH | ||
900 | + && cfun->machine->indirect_branch_type != indirect_branch_keep); | ||
901 | bool seh_nop_p = false; | ||
902 | const char *xasm; | ||
903 | |||
904 | @@ -27383,7 +27948,13 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op) | ||
905 | if (direct_p) | ||
906 | { | ||
907 | if (ix86_nopic_noplt_attribute_p (call_op)) | ||
908 | - xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; | ||
909 | + { | ||
910 | + direct_p = false; | ||
911 | + if (output_indirect_p) | ||
912 | + xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; | ||
913 | + else | ||
914 | + xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; | ||
915 | + } | ||
916 | else | ||
917 | xasm = "%!jmp\t%P0"; | ||
918 | } | ||
919 | @@ -27392,9 +27963,17 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op) | ||
920 | else if (TARGET_SEH) | ||
921 | xasm = "%!rex.W jmp\t%A0"; | ||
922 | else | ||
923 | - xasm = "%!jmp\t%A0"; | ||
924 | + { | ||
925 | + if (output_indirect_p) | ||
926 | + xasm = "%0"; | ||
927 | + else | ||
928 | + xasm = "%!jmp\t%A0"; | ||
929 | + } | ||
930 | |||
931 | - output_asm_insn (xasm, &call_op); | ||
932 | + if (output_indirect_p && !direct_p) | ||
933 | + ix86_output_indirect_branch (call_op, xasm, true); | ||
934 | + else | ||
935 | + output_asm_insn (xasm, &call_op); | ||
936 | return ""; | ||
937 | } | ||
938 | |||
939 | @@ -27431,14 +28010,28 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op) | ||
940 | if (direct_p) | ||
941 | { | ||
942 | if (ix86_nopic_noplt_attribute_p (call_op)) | ||
943 | - xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; | ||
944 | + { | ||
945 | + direct_p = false; | ||
946 | + if (output_indirect_p) | ||
947 | + xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; | ||
948 | + else | ||
949 | + xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}"; | ||
950 | + } | ||
951 | else | ||
952 | xasm = "%!call\t%P0"; | ||
953 | } | ||
954 | else | ||
955 | - xasm = "%!call\t%A0"; | ||
956 | + { | ||
957 | + if (output_indirect_p) | ||
958 | + xasm = "%0"; | ||
959 | + else | ||
960 | + xasm = "%!call\t%A0"; | ||
961 | + } | ||
962 | |||
963 | - output_asm_insn (xasm, &call_op); | ||
964 | + if (output_indirect_p && !direct_p) | ||
965 | + ix86_output_indirect_branch (call_op, xasm, false); | ||
966 | + else | ||
967 | + output_asm_insn (xasm, &call_op); | ||
968 | |||
969 | if (seh_nop_p) | ||
970 | return "nop"; | ||
971 | @@ -44836,7 +45429,7 @@ ix86_handle_struct_attribute (tree *node, tree name, tree, int, | ||
972 | } | ||
973 | |||
974 | static tree | ||
975 | -ix86_handle_fndecl_attribute (tree *node, tree name, tree, int, | ||
976 | +ix86_handle_fndecl_attribute (tree *node, tree name, tree args, int, | ||
977 | bool *no_add_attrs) | ||
978 | { | ||
979 | if (TREE_CODE (*node) != FUNCTION_DECL) | ||
980 | @@ -44845,6 +45438,29 @@ ix86_handle_fndecl_attribute (tree *node, tree name, tree, int, | ||
981 | name); | ||
982 | *no_add_attrs = true; | ||
983 | } | ||
984 | + | ||
985 | + if (is_attribute_p ("indirect_branch", name)) | ||
986 | + { | ||
987 | + tree cst = TREE_VALUE (args); | ||
988 | + if (TREE_CODE (cst) != STRING_CST) | ||
989 | + { | ||
990 | + warning (OPT_Wattributes, | ||
991 | + "%qE attribute requires a string constant argument", | ||
992 | + name); | ||
993 | + *no_add_attrs = true; | ||
994 | + } | ||
995 | + else if (strcmp (TREE_STRING_POINTER (cst), "keep") != 0 | ||
996 | + && strcmp (TREE_STRING_POINTER (cst), "thunk") != 0 | ||
997 | + && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") != 0 | ||
998 | + && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") != 0) | ||
999 | + { | ||
1000 | + warning (OPT_Wattributes, | ||
1001 | + "argument to %qE attribute is not " | ||
1002 | + "(keep|thunk|thunk-inline|thunk-extern)", name); | ||
1003 | + *no_add_attrs = true; | ||
1004 | + } | ||
1005 | + } | ||
1006 | + | ||
1007 | return NULL_TREE; | ||
1008 | } | ||
1009 | |||
1010 | @@ -49072,6 +49688,9 @@ static const struct attribute_spec ix86_attribute_table[] = | ||
1011 | false }, | ||
1012 | { "callee_pop_aggregate_return", 1, 1, false, true, true, | ||
1013 | ix86_handle_callee_pop_aggregate_return, true }, | ||
1014 | + { "indirect_branch", 1, 1, true, false, false, | ||
1015 | + ix86_handle_fndecl_attribute, false }, | ||
1016 | + | ||
1017 | /* End element. */ | ||
1018 | { NULL, 0, 0, false, false, false, NULL, false } | ||
1019 | }; | ||
1020 | diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h | ||
1021 | index 5414416..9dccdb0 100644 | ||
1022 | --- a/gcc/config/i386/i386.h | ||
1023 | +++ b/gcc/config/i386/i386.h | ||
1024 | @@ -2572,6 +2572,13 @@ struct GTY(()) machine_function { | ||
1025 | /* If true, it is safe to not save/restore DRAP register. */ | ||
1026 | BOOL_BITFIELD no_drap_save_restore : 1; | ||
1027 | |||
1028 | + /* How to generate indirec branch. */ | ||
1029 | + ENUM_BITFIELD(indirect_branch) indirect_branch_type : 3; | ||
1030 | + | ||
1031 | + /* If true, the current function has local indirect jumps, like | ||
1032 | + "indirect_jump" or "tablejump". */ | ||
1033 | + BOOL_BITFIELD has_local_indirect_jump : 1; | ||
1034 | + | ||
1035 | /* If true, there is register available for argument passing. This | ||
1036 | is used only in ix86_function_ok_for_sibcall by 32-bit to determine | ||
1037 | if there is scratch register available for indirect sibcall. In | ||
1038 | diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md | ||
1039 | index d2bfe31..153e162 100644 | ||
1040 | --- a/gcc/config/i386/i386.md | ||
1041 | +++ b/gcc/config/i386/i386.md | ||
1042 | @@ -11807,13 +11807,18 @@ | ||
1043 | { | ||
1044 | if (TARGET_X32) | ||
1045 | operands[0] = convert_memory_address (word_mode, operands[0]); | ||
1046 | + cfun->machine->has_local_indirect_jump = true; | ||
1047 | }) | ||
1048 | |||
1049 | (define_insn "*indirect_jump" | ||
1050 | [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))] | ||
1051 | "" | ||
1052 | - "%!jmp\t%A0" | ||
1053 | - [(set_attr "type" "ibr") | ||
1054 | + "* return ix86_output_indirect_jmp (operands[0], false);" | ||
1055 | + [(set (attr "type") | ||
1056 | + (if_then_else (match_test "(cfun->machine->indirect_branch_type | ||
1057 | + != indirect_branch_keep)") | ||
1058 | + (const_string "multi") | ||
1059 | + (const_string "ibr"))) | ||
1060 | (set_attr "length_immediate" "0") | ||
1061 | (set_attr "maybe_prefix_bnd" "1")]) | ||
1062 | |||
1063 | @@ -11856,14 +11861,19 @@ | ||
1064 | |||
1065 | if (TARGET_X32) | ||
1066 | operands[0] = convert_memory_address (word_mode, operands[0]); | ||
1067 | + cfun->machine->has_local_indirect_jump = true; | ||
1068 | }) | ||
1069 | |||
1070 | (define_insn "*tablejump_1" | ||
1071 | [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw")) | ||
1072 | (use (label_ref (match_operand 1)))] | ||
1073 | "" | ||
1074 | - "%!jmp\t%A0" | ||
1075 | - [(set_attr "type" "ibr") | ||
1076 | + "* return ix86_output_indirect_jmp (operands[0], false);" | ||
1077 | + [(set (attr "type") | ||
1078 | + (if_then_else (match_test "(cfun->machine->indirect_branch_type | ||
1079 | + != indirect_branch_keep)") | ||
1080 | + (const_string "multi") | ||
1081 | + (const_string "ibr"))) | ||
1082 | (set_attr "length_immediate" "0") | ||
1083 | (set_attr "maybe_prefix_bnd" "1")]) | ||
1084 | |||
1085 | @@ -12520,8 +12530,12 @@ | ||
1086 | [(simple_return) | ||
1087 | (use (match_operand:SI 0 "register_operand" "r"))] | ||
1088 | "reload_completed" | ||
1089 | - "%!jmp\t%A0" | ||
1090 | - [(set_attr "type" "ibr") | ||
1091 | + "* return ix86_output_indirect_jmp (operands[0], true);" | ||
1092 | + [(set (attr "type") | ||
1093 | + (if_then_else (match_test "(cfun->machine->indirect_branch_type | ||
1094 | + != indirect_branch_keep)") | ||
1095 | + (const_string "multi") | ||
1096 | + (const_string "ibr"))) | ||
1097 | (set_attr "length_immediate" "0") | ||
1098 | (set_attr "maybe_prefix_bnd" "1")]) | ||
1099 | |||
1100 | diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt | ||
1101 | index f304b62..5ffa334 100644 | ||
1102 | --- a/gcc/config/i386/i386.opt | ||
1103 | +++ b/gcc/config/i386/i386.opt | ||
1104 | @@ -897,3 +897,23 @@ Enum(stack_protector_guard) String(global) Value(SSP_GLOBAL) | ||
1105 | mmitigate-rop | ||
1106 | Target Var(flag_mitigate_rop) Init(0) | ||
1107 | Attempt to avoid generating instruction sequences containing ret bytes. | ||
1108 | + | ||
1109 | +mindirect-branch= | ||
1110 | +Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indirect_branch) Init(indirect_branch_keep) | ||
1111 | +Convert indirect call and jump to call and return thunks. | ||
1112 | + | ||
1113 | +Enum | ||
1114 | +Name(indirect_branch) Type(enum indirect_branch) | ||
1115 | +Known indirect branch choices (for use with the -mindirect-branch= option): | ||
1116 | + | ||
1117 | +EnumValue | ||
1118 | +Enum(indirect_branch) String(keep) Value(indirect_branch_keep) | ||
1119 | + | ||
1120 | +EnumValue | ||
1121 | +Enum(indirect_branch) String(thunk) Value(indirect_branch_thunk) | ||
1122 | + | ||
1123 | +EnumValue | ||
1124 | +Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline) | ||
1125 | + | ||
1126 | +EnumValue | ||
1127 | +Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern) | ||
1128 | diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi | ||
1129 | index 8cc4f7e..8668dae 100644 | ||
1130 | --- a/gcc/doc/extend.texi | ||
1131 | +++ b/gcc/doc/extend.texi | ||
1132 | @@ -5419,6 +5419,16 @@ Specify which floating-point unit to use. You must specify the | ||
1133 | @code{target("fpmath=sse,387")} option as | ||
1134 | @code{target("fpmath=sse+387")} because the comma would separate | ||
1135 | different options. | ||
1136 | + | ||
1137 | +@item indirect_branch("@var{choice}") | ||
1138 | +@cindex @code{indirect_branch} function attribute, x86 | ||
1139 | +On x86 targets, the @code{indirect_branch} attribute causes the compiler | ||
1140 | +to convert indirect call and jump with @var{choice}. @samp{keep} | ||
1141 | +keeps indirect call and jump unmodified. @samp{thunk} converts indirect | ||
1142 | +call and jump to call and return thunk. @samp{thunk-inline} converts | ||
1143 | +indirect call and jump to inlined call and return thunk. | ||
1144 | +@samp{thunk-extern} converts indirect call and jump to external call | ||
1145 | +and return thunk provided in a separate object file. | ||
1146 | @end table | ||
1147 | |||
1148 | On the x86, the inliner does not inline a | ||
1149 | diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi | ||
1150 | index b066f7b..ff9a194 100644 | ||
1151 | --- a/gcc/doc/invoke.texi | ||
1152 | +++ b/gcc/doc/invoke.texi | ||
1153 | @@ -1169,7 +1169,7 @@ See RS/6000 and PowerPC Options. | ||
1154 | -msse2avx -mfentry -mrecord-mcount -mnop-mcount -m8bit-idiv @gol | ||
1155 | -mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol | ||
1156 | -malign-data=@var{type} -mstack-protector-guard=@var{guard} @gol | ||
1157 | --mmitigate-rop} | ||
1158 | +-mmitigate-rop -mindirect-branch=@var{choice}} | ||
1159 | |||
1160 | @emph{x86 Windows Options} | ||
1161 | @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol | ||
1162 | @@ -24218,6 +24218,17 @@ opcodes, to mitigate against certain forms of attack. At the moment, | ||
1163 | this option is limited in what it can do and should not be relied | ||
1164 | on to provide serious protection. | ||
1165 | |||
1166 | +@item -mindirect-branch=@var{choice} | ||
1167 | +@opindex -mindirect-branch | ||
1168 | +Convert indirect call and jump with @var{choice}. The default is | ||
1169 | +@samp{keep}, which keeps indirect call and jump unmodified. | ||
1170 | +@samp{thunk} converts indirect call and jump to call and return thunk. | ||
1171 | +@samp{thunk-inline} converts indirect call and jump to inlined call | ||
1172 | +and return thunk. @samp{thunk-extern} converts indirect call and jump | ||
1173 | +to external call and return thunk provided in a separate object file. | ||
1174 | +You can control this behavior for a specific function by using the | ||
1175 | +function attribute @code{indirect_branch}. @xref{Function Attributes}. | ||
1176 | + | ||
1177 | @end table | ||
1178 | |||
1179 | These @samp{-m} switches are supported in addition to the above | ||
1180 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | ||
1181 | new file mode 100644 | ||
1182 | index 0000000..d983e1c | ||
1183 | --- /dev/null | ||
1184 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | ||
1185 | @@ -0,0 +1,20 @@ | ||
1186 | +/* { dg-do compile } */ | ||
1187 | +/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ | ||
1188 | + | ||
1189 | +typedef void (*dispatch_t)(long offset); | ||
1190 | + | ||
1191 | +dispatch_t dispatch; | ||
1192 | + | ||
1193 | +void | ||
1194 | +male_indirect_jump (long offset) | ||
1195 | +{ | ||
1196 | + dispatch(offset); | ||
1197 | +} | ||
1198 | + | ||
1199 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1200 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
1201 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
1202 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1203 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
1204 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
1205 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
1206 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | ||
1207 | new file mode 100644 | ||
1208 | index 0000000..58f09b4 | ||
1209 | --- /dev/null | ||
1210 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | ||
1211 | @@ -0,0 +1,20 @@ | ||
1212 | +/* { dg-do compile } */ | ||
1213 | +/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ | ||
1214 | + | ||
1215 | +typedef void (*dispatch_t)(long offset); | ||
1216 | + | ||
1217 | +dispatch_t dispatch[256]; | ||
1218 | + | ||
1219 | +void | ||
1220 | +male_indirect_jump (long offset) | ||
1221 | +{ | ||
1222 | + dispatch[offset](offset); | ||
1223 | +} | ||
1224 | + | ||
1225 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1226 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
1227 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
1228 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1229 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
1230 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
1231 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
1232 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | ||
1233 | new file mode 100644 | ||
1234 | index 0000000..f20d35c | ||
1235 | --- /dev/null | ||
1236 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | ||
1237 | @@ -0,0 +1,21 @@ | ||
1238 | +/* { dg-do compile } */ | ||
1239 | +/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ | ||
1240 | + | ||
1241 | +typedef void (*dispatch_t)(long offset); | ||
1242 | + | ||
1243 | +dispatch_t dispatch; | ||
1244 | + | ||
1245 | +int | ||
1246 | +male_indirect_jump (long offset) | ||
1247 | +{ | ||
1248 | + dispatch(offset); | ||
1249 | + return 0; | ||
1250 | +} | ||
1251 | + | ||
1252 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1253 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
1254 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
1255 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1256 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
1257 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
1258 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
1259 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | ||
1260 | new file mode 100644 | ||
1261 | index 0000000..0eff8fb | ||
1262 | --- /dev/null | ||
1263 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | ||
1264 | @@ -0,0 +1,21 @@ | ||
1265 | +/* { dg-do compile } */ | ||
1266 | +/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ | ||
1267 | + | ||
1268 | +typedef void (*dispatch_t)(long offset); | ||
1269 | + | ||
1270 | +dispatch_t dispatch[256]; | ||
1271 | + | ||
1272 | +int | ||
1273 | +male_indirect_jump (long offset) | ||
1274 | +{ | ||
1275 | + dispatch[offset](offset); | ||
1276 | + return 0; | ||
1277 | +} | ||
1278 | + | ||
1279 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1280 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
1281 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
1282 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1283 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
1284 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
1285 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
1286 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | ||
1287 | new file mode 100644 | ||
1288 | index 0000000..a25b20d | ||
1289 | --- /dev/null | ||
1290 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | ||
1291 | @@ -0,0 +1,17 @@ | ||
1292 | +/* { dg-do compile { target *-*-linux* } } */ | ||
1293 | +/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */ | ||
1294 | + | ||
1295 | +extern void bar (void); | ||
1296 | + | ||
1297 | +void | ||
1298 | +foo (void) | ||
1299 | +{ | ||
1300 | + bar (); | ||
1301 | +} | ||
1302 | + | ||
1303 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ | ||
1304 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ | ||
1305 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1306 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
1307 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
1308 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
1309 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | ||
1310 | new file mode 100644 | ||
1311 | index 0000000..cff114a | ||
1312 | --- /dev/null | ||
1313 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | ||
1314 | @@ -0,0 +1,18 @@ | ||
1315 | +/* { dg-do compile { target *-*-linux* } } */ | ||
1316 | +/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */ | ||
1317 | + | ||
1318 | +extern void bar (void); | ||
1319 | + | ||
1320 | +int | ||
1321 | +foo (void) | ||
1322 | +{ | ||
1323 | + bar (); | ||
1324 | + return 0; | ||
1325 | +} | ||
1326 | + | ||
1327 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ | ||
1328 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ | ||
1329 | +/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ | ||
1330 | +/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ | ||
1331 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
1332 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
1333 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | ||
1334 | new file mode 100644 | ||
1335 | index 0000000..afdb600 | ||
1336 | --- /dev/null | ||
1337 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | ||
1338 | @@ -0,0 +1,44 @@ | ||
1339 | +/* { dg-do compile } */ | ||
1340 | +/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ | ||
1341 | + | ||
1342 | +void func0 (void); | ||
1343 | +void func1 (void); | ||
1344 | +void func2 (void); | ||
1345 | +void func3 (void); | ||
1346 | +void func4 (void); | ||
1347 | +void func4 (void); | ||
1348 | +void func5 (void); | ||
1349 | + | ||
1350 | +void | ||
1351 | +bar (int i) | ||
1352 | +{ | ||
1353 | + switch (i) | ||
1354 | + { | ||
1355 | + default: | ||
1356 | + func0 (); | ||
1357 | + break; | ||
1358 | + case 1: | ||
1359 | + func1 (); | ||
1360 | + break; | ||
1361 | + case 2: | ||
1362 | + func2 (); | ||
1363 | + break; | ||
1364 | + case 3: | ||
1365 | + func3 (); | ||
1366 | + break; | ||
1367 | + case 4: | ||
1368 | + func4 (); | ||
1369 | + break; | ||
1370 | + case 5: | ||
1371 | + func5 (); | ||
1372 | + break; | ||
1373 | + } | ||
1374 | +} | ||
1375 | + | ||
1376 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ | ||
1377 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
1378 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
1379 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1380 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
1381 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
1382 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
1383 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | ||
1384 | new file mode 100644 | ||
1385 | index 0000000..d64d978 | ||
1386 | --- /dev/null | ||
1387 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | ||
1388 | @@ -0,0 +1,23 @@ | ||
1389 | +/* { dg-do compile } */ | ||
1390 | +/* { dg-options "-O2 -fno-pic" } */ | ||
1391 | + | ||
1392 | +typedef void (*dispatch_t)(long offset); | ||
1393 | + | ||
1394 | +dispatch_t dispatch; | ||
1395 | + | ||
1396 | +extern void male_indirect_jump (long) | ||
1397 | + __attribute__ ((indirect_branch("thunk"))); | ||
1398 | + | ||
1399 | +void | ||
1400 | +male_indirect_jump (long offset) | ||
1401 | +{ | ||
1402 | + dispatch(offset); | ||
1403 | +} | ||
1404 | + | ||
1405 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1406 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
1407 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
1408 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1409 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
1410 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
1411 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
1412 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | ||
1413 | new file mode 100644 | ||
1414 | index 0000000..9306745 | ||
1415 | --- /dev/null | ||
1416 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | ||
1417 | @@ -0,0 +1,21 @@ | ||
1418 | +/* { dg-do compile } */ | ||
1419 | +/* { dg-options "-O2 -fno-pic" } */ | ||
1420 | + | ||
1421 | +typedef void (*dispatch_t)(long offset); | ||
1422 | + | ||
1423 | +dispatch_t dispatch[256]; | ||
1424 | + | ||
1425 | +__attribute__ ((indirect_branch("thunk"))) | ||
1426 | +void | ||
1427 | +male_indirect_jump (long offset) | ||
1428 | +{ | ||
1429 | + dispatch[offset](offset); | ||
1430 | +} | ||
1431 | + | ||
1432 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1433 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
1434 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
1435 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1436 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
1437 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
1438 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
1439 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | ||
1440 | new file mode 100644 | ||
1441 | index 0000000..97744d6 | ||
1442 | --- /dev/null | ||
1443 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | ||
1444 | @@ -0,0 +1,23 @@ | ||
1445 | +/* { dg-do compile } */ | ||
1446 | +/* { dg-options "-O2 -fno-pic" } */ | ||
1447 | + | ||
1448 | +typedef void (*dispatch_t)(long offset); | ||
1449 | + | ||
1450 | +dispatch_t dispatch; | ||
1451 | +extern int male_indirect_jump (long) | ||
1452 | + __attribute__ ((indirect_branch("thunk-inline"))); | ||
1453 | + | ||
1454 | +int | ||
1455 | +male_indirect_jump (long offset) | ||
1456 | +{ | ||
1457 | + dispatch(offset); | ||
1458 | + return 0; | ||
1459 | +} | ||
1460 | + | ||
1461 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1462 | +/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ | ||
1463 | +/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ | ||
1464 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
1465 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
1466 | +/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ | ||
1467 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
1468 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | ||
1469 | new file mode 100644 | ||
1470 | index 0000000..bfce3ea | ||
1471 | --- /dev/null | ||
1472 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | ||
1473 | @@ -0,0 +1,22 @@ | ||
1474 | +/* { dg-do compile } */ | ||
1475 | +/* { dg-options "-O2 -fno-pic" } */ | ||
1476 | + | ||
1477 | +typedef void (*dispatch_t)(long offset); | ||
1478 | + | ||
1479 | +dispatch_t dispatch[256]; | ||
1480 | + | ||
1481 | +__attribute__ ((indirect_branch("thunk-inline"))) | ||
1482 | +int | ||
1483 | +male_indirect_jump (long offset) | ||
1484 | +{ | ||
1485 | + dispatch[offset](offset); | ||
1486 | + return 0; | ||
1487 | +} | ||
1488 | + | ||
1489 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1490 | +/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ | ||
1491 | +/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ | ||
1492 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
1493 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
1494 | +/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ | ||
1495 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
1496 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | ||
1497 | new file mode 100644 | ||
1498 | index 0000000..0833606 | ||
1499 | --- /dev/null | ||
1500 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | ||
1501 | @@ -0,0 +1,22 @@ | ||
1502 | +/* { dg-do compile } */ | ||
1503 | +/* { dg-options "-O2 -fno-pic" } */ | ||
1504 | + | ||
1505 | +typedef void (*dispatch_t)(long offset); | ||
1506 | + | ||
1507 | +dispatch_t dispatch; | ||
1508 | +extern int male_indirect_jump (long) | ||
1509 | + __attribute__ ((indirect_branch("thunk-extern"))); | ||
1510 | + | ||
1511 | +int | ||
1512 | +male_indirect_jump (long offset) | ||
1513 | +{ | ||
1514 | + dispatch(offset); | ||
1515 | + return 0; | ||
1516 | +} | ||
1517 | + | ||
1518 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1519 | +/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
1520 | +/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
1521 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
1522 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
1523 | +/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
1524 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | ||
1525 | new file mode 100644 | ||
1526 | index 0000000..2eba0fb | ||
1527 | --- /dev/null | ||
1528 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | ||
1529 | @@ -0,0 +1,21 @@ | ||
1530 | +/* { dg-do compile } */ | ||
1531 | +/* { dg-options "-O2 -fno-pic" } */ | ||
1532 | + | ||
1533 | +typedef void (*dispatch_t)(long offset); | ||
1534 | + | ||
1535 | +dispatch_t dispatch[256]; | ||
1536 | + | ||
1537 | +__attribute__ ((indirect_branch("thunk-extern"))) | ||
1538 | +int | ||
1539 | +male_indirect_jump (long offset) | ||
1540 | +{ | ||
1541 | + dispatch[offset](offset); | ||
1542 | + return 0; | ||
1543 | +} | ||
1544 | + | ||
1545 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1546 | +/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
1547 | +/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
1548 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
1549 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
1550 | +/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
1551 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | ||
1552 | new file mode 100644 | ||
1553 | index 0000000..f58427e | ||
1554 | --- /dev/null | ||
1555 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | ||
1556 | @@ -0,0 +1,44 @@ | ||
1557 | +/* { dg-do compile } */ | ||
1558 | +/* { dg-options "-O2 -fno-pic" } */ | ||
1559 | + | ||
1560 | +void func0 (void); | ||
1561 | +void func1 (void); | ||
1562 | +void func2 (void); | ||
1563 | +void func3 (void); | ||
1564 | +void func4 (void); | ||
1565 | +void func4 (void); | ||
1566 | +void func5 (void); | ||
1567 | + | ||
1568 | +__attribute__ ((indirect_branch("thunk-extern"))) | ||
1569 | +void | ||
1570 | +bar (int i) | ||
1571 | +{ | ||
1572 | + switch (i) | ||
1573 | + { | ||
1574 | + default: | ||
1575 | + func0 (); | ||
1576 | + break; | ||
1577 | + case 1: | ||
1578 | + func1 (); | ||
1579 | + break; | ||
1580 | + case 2: | ||
1581 | + func2 (); | ||
1582 | + break; | ||
1583 | + case 3: | ||
1584 | + func3 (); | ||
1585 | + break; | ||
1586 | + case 4: | ||
1587 | + func4 (); | ||
1588 | + break; | ||
1589 | + case 5: | ||
1590 | + func5 (); | ||
1591 | + break; | ||
1592 | + } | ||
1593 | +} | ||
1594 | + | ||
1595 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ | ||
1596 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
1597 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ | ||
1598 | +/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
1599 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ | ||
1600 | +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ | ||
1601 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c | ||
1602 | new file mode 100644 | ||
1603 | index 0000000..564ed39 | ||
1604 | --- /dev/null | ||
1605 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c | ||
1606 | @@ -0,0 +1,42 @@ | ||
1607 | +/* { dg-do compile } */ | ||
1608 | +/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ | ||
1609 | + | ||
1610 | +void func0 (void); | ||
1611 | +void func1 (void); | ||
1612 | +void func2 (void); | ||
1613 | +void func3 (void); | ||
1614 | +void func4 (void); | ||
1615 | +void func4 (void); | ||
1616 | +void func5 (void); | ||
1617 | + | ||
1618 | +__attribute__ ((indirect_branch("keep"))) | ||
1619 | +void | ||
1620 | +bar (int i) | ||
1621 | +{ | ||
1622 | + switch (i) | ||
1623 | + { | ||
1624 | + default: | ||
1625 | + func0 (); | ||
1626 | + break; | ||
1627 | + case 1: | ||
1628 | + func1 (); | ||
1629 | + break; | ||
1630 | + case 2: | ||
1631 | + func2 (); | ||
1632 | + break; | ||
1633 | + case 3: | ||
1634 | + func3 (); | ||
1635 | + break; | ||
1636 | + case 4: | ||
1637 | + func4 (); | ||
1638 | + break; | ||
1639 | + case 5: | ||
1640 | + func5 (); | ||
1641 | + break; | ||
1642 | + } | ||
1643 | +} | ||
1644 | + | ||
1645 | +/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ | ||
1646 | +/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
1647 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ | ||
1648 | +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ | ||
1649 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | ||
1650 | new file mode 100644 | ||
1651 | index 0000000..50fbee2 | ||
1652 | --- /dev/null | ||
1653 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | ||
1654 | @@ -0,0 +1,20 @@ | ||
1655 | +/* { dg-do compile { target { ! x32 } } } */ | ||
1656 | +/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ | ||
1657 | + | ||
1658 | +void (*dispatch) (char *); | ||
1659 | +char buf[10]; | ||
1660 | + | ||
1661 | +void | ||
1662 | +foo (void) | ||
1663 | +{ | ||
1664 | + dispatch (buf); | ||
1665 | +} | ||
1666 | + | ||
1667 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1668 | +/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ | ||
1669 | +/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ | ||
1670 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1671 | +/* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ | ||
1672 | +/* { dg-final { scan-assembler "bnd ret" } } */ | ||
1673 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
1674 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
1675 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | ||
1676 | new file mode 100644 | ||
1677 | index 0000000..2976e67 | ||
1678 | --- /dev/null | ||
1679 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | ||
1680 | @@ -0,0 +1,21 @@ | ||
1681 | +/* { dg-do compile { target { ! x32 } } } */ | ||
1682 | +/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ | ||
1683 | + | ||
1684 | +void (*dispatch) (char *); | ||
1685 | +char buf[10]; | ||
1686 | + | ||
1687 | +int | ||
1688 | +foo (void) | ||
1689 | +{ | ||
1690 | + dispatch (buf); | ||
1691 | + return 0; | ||
1692 | +} | ||
1693 | + | ||
1694 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1695 | +/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ | ||
1696 | +/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ | ||
1697 | +/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */ | ||
1698 | +/* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ | ||
1699 | +/* { dg-final { scan-assembler "bnd ret" } } */ | ||
1700 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
1701 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
1702 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | ||
1703 | new file mode 100644 | ||
1704 | index 0000000..da4bc98 | ||
1705 | --- /dev/null | ||
1706 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | ||
1707 | @@ -0,0 +1,19 @@ | ||
1708 | +/* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ | ||
1709 | +/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ | ||
1710 | + | ||
1711 | +void bar (char *); | ||
1712 | +char buf[10]; | ||
1713 | + | ||
1714 | +void | ||
1715 | +foo (void) | ||
1716 | +{ | ||
1717 | + bar (buf); | ||
1718 | +} | ||
1719 | + | ||
1720 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ | ||
1721 | +/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ | ||
1722 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1723 | +/* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ | ||
1724 | +/* { dg-final { scan-assembler "bnd ret" } } */ | ||
1725 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
1726 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
1727 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | ||
1728 | new file mode 100644 | ||
1729 | index 0000000..c64d12e | ||
1730 | --- /dev/null | ||
1731 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | ||
1732 | @@ -0,0 +1,20 @@ | ||
1733 | +/* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ | ||
1734 | +/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ | ||
1735 | + | ||
1736 | +void bar (char *); | ||
1737 | +char buf[10]; | ||
1738 | + | ||
1739 | +int | ||
1740 | +foo (void) | ||
1741 | +{ | ||
1742 | + bar (buf); | ||
1743 | + return 0; | ||
1744 | +} | ||
1745 | + | ||
1746 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ | ||
1747 | +/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk" } } */ | ||
1748 | +/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */ | ||
1749 | +/* { dg-final { scan-assembler-times "bnd call\[ \t\]*\.LIND" 2 } } */ | ||
1750 | +/* { dg-final { scan-assembler "bnd ret" } } */ | ||
1751 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
1752 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
1753 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | ||
1754 | new file mode 100644 | ||
1755 | index 0000000..49f27b4 | ||
1756 | --- /dev/null | ||
1757 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | ||
1758 | @@ -0,0 +1,19 @@ | ||
1759 | +/* { dg-do compile } */ | ||
1760 | +/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ | ||
1761 | + | ||
1762 | +typedef void (*dispatch_t)(long offset); | ||
1763 | + | ||
1764 | +dispatch_t dispatch; | ||
1765 | + | ||
1766 | +void | ||
1767 | +male_indirect_jump (long offset) | ||
1768 | +{ | ||
1769 | + dispatch(offset); | ||
1770 | +} | ||
1771 | + | ||
1772 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1773 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
1774 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
1775 | +/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
1776 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ | ||
1777 | +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ | ||
1778 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | ||
1779 | new file mode 100644 | ||
1780 | index 0000000..a1e3eb6 | ||
1781 | --- /dev/null | ||
1782 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | ||
1783 | @@ -0,0 +1,19 @@ | ||
1784 | +/* { dg-do compile } */ | ||
1785 | +/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ | ||
1786 | + | ||
1787 | +typedef void (*dispatch_t)(long offset); | ||
1788 | + | ||
1789 | +dispatch_t dispatch[256]; | ||
1790 | + | ||
1791 | +void | ||
1792 | +male_indirect_jump (long offset) | ||
1793 | +{ | ||
1794 | + dispatch[offset](offset); | ||
1795 | +} | ||
1796 | + | ||
1797 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1798 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
1799 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
1800 | +/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
1801 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ | ||
1802 | +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ | ||
1803 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | ||
1804 | new file mode 100644 | ||
1805 | index 0000000..395634e | ||
1806 | --- /dev/null | ||
1807 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | ||
1808 | @@ -0,0 +1,20 @@ | ||
1809 | +/* { dg-do compile } */ | ||
1810 | +/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ | ||
1811 | + | ||
1812 | +typedef void (*dispatch_t)(long offset); | ||
1813 | + | ||
1814 | +dispatch_t dispatch; | ||
1815 | + | ||
1816 | +int | ||
1817 | +male_indirect_jump (long offset) | ||
1818 | +{ | ||
1819 | + dispatch(offset); | ||
1820 | + return 0; | ||
1821 | +} | ||
1822 | + | ||
1823 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1824 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
1825 | +/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
1826 | +/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
1827 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
1828 | +/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
1829 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | ||
1830 | new file mode 100644 | ||
1831 | index 0000000..fd3f633 | ||
1832 | --- /dev/null | ||
1833 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | ||
1834 | @@ -0,0 +1,20 @@ | ||
1835 | +/* { dg-do compile } */ | ||
1836 | +/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ | ||
1837 | + | ||
1838 | +typedef void (*dispatch_t)(long offset); | ||
1839 | + | ||
1840 | +dispatch_t dispatch[256]; | ||
1841 | + | ||
1842 | +int | ||
1843 | +male_indirect_jump (long offset) | ||
1844 | +{ | ||
1845 | + dispatch[offset](offset); | ||
1846 | + return 0; | ||
1847 | +} | ||
1848 | + | ||
1849 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1850 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
1851 | +/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
1852 | +/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
1853 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
1854 | +/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
1855 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | ||
1856 | new file mode 100644 | ||
1857 | index 0000000..ba2f92b | ||
1858 | --- /dev/null | ||
1859 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | ||
1860 | @@ -0,0 +1,16 @@ | ||
1861 | +/* { dg-do compile { target *-*-linux* } } */ | ||
1862 | +/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */ | ||
1863 | + | ||
1864 | +extern void bar (void); | ||
1865 | + | ||
1866 | +void | ||
1867 | +foo (void) | ||
1868 | +{ | ||
1869 | + bar (); | ||
1870 | +} | ||
1871 | + | ||
1872 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ | ||
1873 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ | ||
1874 | +/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
1875 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ | ||
1876 | +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ | ||
1877 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | ||
1878 | new file mode 100644 | ||
1879 | index 0000000..0c5a2d4 | ||
1880 | --- /dev/null | ||
1881 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | ||
1882 | @@ -0,0 +1,17 @@ | ||
1883 | +/* { dg-do compile { target *-*-linux* } } */ | ||
1884 | +/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */ | ||
1885 | + | ||
1886 | +extern void bar (void); | ||
1887 | + | ||
1888 | +int | ||
1889 | +foo (void) | ||
1890 | +{ | ||
1891 | + bar (); | ||
1892 | + return 0; | ||
1893 | +} | ||
1894 | + | ||
1895 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ | ||
1896 | +/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */ | ||
1897 | +/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */ | ||
1898 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ | ||
1899 | +/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
1900 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | ||
1901 | new file mode 100644 | ||
1902 | index 0000000..6652523 | ||
1903 | --- /dev/null | ||
1904 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | ||
1905 | @@ -0,0 +1,43 @@ | ||
1906 | +/* { dg-do compile } */ | ||
1907 | +/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ | ||
1908 | + | ||
1909 | +void func0 (void); | ||
1910 | +void func1 (void); | ||
1911 | +void func2 (void); | ||
1912 | +void func3 (void); | ||
1913 | +void func4 (void); | ||
1914 | +void func4 (void); | ||
1915 | +void func5 (void); | ||
1916 | + | ||
1917 | +void | ||
1918 | +bar (int i) | ||
1919 | +{ | ||
1920 | + switch (i) | ||
1921 | + { | ||
1922 | + default: | ||
1923 | + func0 (); | ||
1924 | + break; | ||
1925 | + case 1: | ||
1926 | + func1 (); | ||
1927 | + break; | ||
1928 | + case 2: | ||
1929 | + func2 (); | ||
1930 | + break; | ||
1931 | + case 3: | ||
1932 | + func3 (); | ||
1933 | + break; | ||
1934 | + case 4: | ||
1935 | + func4 (); | ||
1936 | + break; | ||
1937 | + case 5: | ||
1938 | + func5 (); | ||
1939 | + break; | ||
1940 | + } | ||
1941 | +} | ||
1942 | + | ||
1943 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ | ||
1944 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
1945 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
1946 | +/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
1947 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ | ||
1948 | +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ | ||
1949 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | ||
1950 | new file mode 100644 | ||
1951 | index 0000000..68c0ff7 | ||
1952 | --- /dev/null | ||
1953 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | ||
1954 | @@ -0,0 +1,20 @@ | ||
1955 | +/* { dg-do compile } */ | ||
1956 | +/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ | ||
1957 | + | ||
1958 | +typedef void (*dispatch_t)(long offset); | ||
1959 | + | ||
1960 | +dispatch_t dispatch; | ||
1961 | + | ||
1962 | +void | ||
1963 | +male_indirect_jump (long offset) | ||
1964 | +{ | ||
1965 | + dispatch(offset); | ||
1966 | +} | ||
1967 | + | ||
1968 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1969 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1970 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
1971 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
1972 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
1973 | +/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ | ||
1974 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
1975 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | ||
1976 | new file mode 100644 | ||
1977 | index 0000000..e2da1fc | ||
1978 | --- /dev/null | ||
1979 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | ||
1980 | @@ -0,0 +1,20 @@ | ||
1981 | +/* { dg-do compile } */ | ||
1982 | +/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ | ||
1983 | + | ||
1984 | +typedef void (*dispatch_t)(long offset); | ||
1985 | + | ||
1986 | +dispatch_t dispatch[256]; | ||
1987 | + | ||
1988 | +void | ||
1989 | +male_indirect_jump (long offset) | ||
1990 | +{ | ||
1991 | + dispatch[offset](offset); | ||
1992 | +} | ||
1993 | + | ||
1994 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1995 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1996 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
1997 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
1998 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
1999 | +/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ | ||
2000 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
2001 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | ||
2002 | new file mode 100644 | ||
2003 | index 0000000..244fec7 | ||
2004 | --- /dev/null | ||
2005 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | ||
2006 | @@ -0,0 +1,21 @@ | ||
2007 | +/* { dg-do compile } */ | ||
2008 | +/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ | ||
2009 | + | ||
2010 | +typedef void (*dispatch_t)(long offset); | ||
2011 | + | ||
2012 | +dispatch_t dispatch; | ||
2013 | + | ||
2014 | +int | ||
2015 | +male_indirect_jump (long offset) | ||
2016 | +{ | ||
2017 | + dispatch(offset); | ||
2018 | + return 0; | ||
2019 | +} | ||
2020 | + | ||
2021 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
2022 | +/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ | ||
2023 | +/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ | ||
2024 | +/* { dg-final { scan-assembler-times {\tpause} 1 } } */ | ||
2025 | +/* { dg-final { scan-assembler-times {\tlfence} 1 } } */ | ||
2026 | +/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ | ||
2027 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
2028 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | ||
2029 | new file mode 100644 | ||
2030 | index 0000000..107ebe3 | ||
2031 | --- /dev/null | ||
2032 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | ||
2033 | @@ -0,0 +1,21 @@ | ||
2034 | +/* { dg-do compile } */ | ||
2035 | +/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ | ||
2036 | + | ||
2037 | +typedef void (*dispatch_t)(long offset); | ||
2038 | + | ||
2039 | +dispatch_t dispatch[256]; | ||
2040 | + | ||
2041 | +int | ||
2042 | +male_indirect_jump (long offset) | ||
2043 | +{ | ||
2044 | + dispatch[offset](offset); | ||
2045 | + return 0; | ||
2046 | +} | ||
2047 | + | ||
2048 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
2049 | +/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ | ||
2050 | +/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ | ||
2051 | +/* { dg-final { scan-assembler-times {\tpause} 1 } } */ | ||
2052 | +/* { dg-final { scan-assembler-times {\tlfence} 1 } } */ | ||
2053 | +/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ | ||
2054 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
2055 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | ||
2056 | new file mode 100644 | ||
2057 | index 0000000..17b04ef | ||
2058 | --- /dev/null | ||
2059 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | ||
2060 | @@ -0,0 +1,17 @@ | ||
2061 | +/* { dg-do compile { target *-*-linux* } } */ | ||
2062 | +/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */ | ||
2063 | + | ||
2064 | +extern void bar (void); | ||
2065 | + | ||
2066 | +void | ||
2067 | +foo (void) | ||
2068 | +{ | ||
2069 | + bar (); | ||
2070 | +} | ||
2071 | + | ||
2072 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ | ||
2073 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
2074 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
2075 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
2076 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
2077 | +/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ | ||
2078 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | ||
2079 | new file mode 100644 | ||
2080 | index 0000000..d9eb112 | ||
2081 | --- /dev/null | ||
2082 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | ||
2083 | @@ -0,0 +1,18 @@ | ||
2084 | +/* { dg-do compile { target *-*-linux* } } */ | ||
2085 | +/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */ | ||
2086 | + | ||
2087 | +extern void bar (void); | ||
2088 | + | ||
2089 | +int | ||
2090 | +foo (void) | ||
2091 | +{ | ||
2092 | + bar (); | ||
2093 | + return 0; | ||
2094 | +} | ||
2095 | + | ||
2096 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ | ||
2097 | +/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ | ||
2098 | +/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ | ||
2099 | +/* { dg-final { scan-assembler-times {\tpause} 1 } } */ | ||
2100 | +/* { dg-final { scan-assembler-times {\tlfence} 1 } } */ | ||
2101 | +/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ | ||
2102 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | ||
2103 | new file mode 100644 | ||
2104 | index 0000000..d02b1dc | ||
2105 | --- /dev/null | ||
2106 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | ||
2107 | @@ -0,0 +1,44 @@ | ||
2108 | +/* { dg-do compile } */ | ||
2109 | +/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ | ||
2110 | + | ||
2111 | +void func0 (void); | ||
2112 | +void func1 (void); | ||
2113 | +void func2 (void); | ||
2114 | +void func3 (void); | ||
2115 | +void func4 (void); | ||
2116 | +void func4 (void); | ||
2117 | +void func5 (void); | ||
2118 | + | ||
2119 | +void | ||
2120 | +bar (int i) | ||
2121 | +{ | ||
2122 | + switch (i) | ||
2123 | + { | ||
2124 | + default: | ||
2125 | + func0 (); | ||
2126 | + break; | ||
2127 | + case 1: | ||
2128 | + func1 (); | ||
2129 | + break; | ||
2130 | + case 2: | ||
2131 | + func2 (); | ||
2132 | + break; | ||
2133 | + case 3: | ||
2134 | + func3 (); | ||
2135 | + break; | ||
2136 | + case 4: | ||
2137 | + func4 (); | ||
2138 | + break; | ||
2139 | + case 5: | ||
2140 | + func5 (); | ||
2141 | + break; | ||
2142 | + } | ||
2143 | +} | ||
2144 | + | ||
2145 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ | ||
2146 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
2147 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
2148 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
2149 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
2150 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
2151 | +/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ | ||
2152 | -- | ||
2153 | 2.7.4 | ||
2154 | |||
diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0005-x86-Add-mfunction-return.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0005-x86-Add-mfunction-return.patch new file mode 100644 index 0000000000..5354c77d6f --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0005-x86-Add-mfunction-return.patch | |||
@@ -0,0 +1,1570 @@ | |||
1 | From e3270814b9e0caad63fbcdfd7ae9da2d52c97497 Mon Sep 17 00:00:00 2001 | ||
2 | From: "H.J. Lu" <hjl.tools@gmail.com> | ||
3 | Date: Sat, 6 Jan 2018 22:29:56 -0800 | ||
4 | Subject: [PATCH 05/12] x86: Add -mfunction-return= | ||
5 | |||
6 | Add -mfunction-return= option to convert function return to call and | ||
7 | return thunks. The default is 'keep', which keeps function return | ||
8 | unmodified. 'thunk' converts function return to call and return thunk. | ||
9 | 'thunk-inline' converts function return to inlined call and return thunk. | ||
10 | 'thunk-extern' converts function return to external call and return | ||
11 | thunk provided in a separate object file. You can control this behavior | ||
12 | for a specific function by using the function attribute function_return. | ||
13 | |||
14 | Function return thunk is the same as memory thunk for -mindirect-branch= | ||
15 | where the return address is at the top of the stack: | ||
16 | |||
17 | __x86_return_thunk: | ||
18 | call L2 | ||
19 | L1: | ||
20 | pause | ||
21 | lfence | ||
22 | jmp L1 | ||
23 | L2: | ||
24 | lea 8(%rsp), %rsp|lea 4(%esp), %esp | ||
25 | ret | ||
26 | |||
27 | and function return becomes | ||
28 | |||
29 | jmp __x86_return_thunk | ||
30 | |||
31 | -mindirect-branch= tests are updated with -mfunction-return=keep to | ||
32 | avoid false test failures when -mfunction-return=thunk is added to | ||
33 | RUNTESTFLAGS for "make check". | ||
34 | |||
35 | gcc/ | ||
36 | |||
37 | Backport from mainline | ||
38 | 2018-01-14 H.J. Lu <hongjiu.lu@intel.com> | ||
39 | |||
40 | * config/i386/i386-protos.h (ix86_output_function_return): New. | ||
41 | * config/i386/i386.c (ix86_set_indirect_branch_type): Also | ||
42 | set function_return_type. | ||
43 | (indirect_thunk_name): Add ret_p to indicate thunk for function | ||
44 | return. | ||
45 | (output_indirect_thunk_function): Pass false to | ||
46 | indirect_thunk_name. | ||
47 | (ix86_output_indirect_branch_via_reg): Likewise. | ||
48 | (ix86_output_indirect_branch_via_push): Likewise. | ||
49 | (output_indirect_thunk_function): Create alias for function | ||
50 | return thunk if regno < 0. | ||
51 | (ix86_output_function_return): New function. | ||
52 | (ix86_handle_fndecl_attribute): Handle function_return. | ||
53 | (ix86_attribute_table): Add function_return. | ||
54 | * config/i386/i386.h (machine_function): Add | ||
55 | function_return_type. | ||
56 | * config/i386/i386.md (simple_return_internal): Use | ||
57 | ix86_output_function_return. | ||
58 | (simple_return_internal_long): Likewise. | ||
59 | * config/i386/i386.opt (mfunction-return=): New option. | ||
60 | (indirect_branch): Mention -mfunction-return=. | ||
61 | * doc/extend.texi: Document function_return function attribute. | ||
62 | * doc/invoke.texi: Document -mfunction-return= option. | ||
63 | |||
64 | gcc/testsuite/ | ||
65 | |||
66 | Backport from mainline | ||
67 | 2018-01-14 H.J. Lu <hongjiu.lu@intel.com> | ||
68 | |||
69 | * gcc.target/i386/indirect-thunk-1.c (dg-options): Add | ||
70 | -mfunction-return=keep. | ||
71 | * gcc.target/i386/indirect-thunk-2.c: Likewise. | ||
72 | * gcc.target/i386/indirect-thunk-3.c: Likewise. | ||
73 | * gcc.target/i386/indirect-thunk-4.c: Likewise. | ||
74 | * gcc.target/i386/indirect-thunk-5.c: Likewise. | ||
75 | * gcc.target/i386/indirect-thunk-6.c: Likewise. | ||
76 | * gcc.target/i386/indirect-thunk-7.c: Likewise. | ||
77 | * gcc.target/i386/indirect-thunk-attr-1.c: Likewise. | ||
78 | * gcc.target/i386/indirect-thunk-attr-2.c: Likewise. | ||
79 | * gcc.target/i386/indirect-thunk-attr-3.c: Likewise. | ||
80 | * gcc.target/i386/indirect-thunk-attr-4.c: Likewise. | ||
81 | * gcc.target/i386/indirect-thunk-attr-5.c: Likewise. | ||
82 | * gcc.target/i386/indirect-thunk-attr-6.c: Likewise. | ||
83 | * gcc.target/i386/indirect-thunk-attr-7.c: Likewise. | ||
84 | * gcc.target/i386/indirect-thunk-attr-8.c: Likewise. | ||
85 | * gcc.target/i386/indirect-thunk-bnd-1.c: Likewise. | ||
86 | * gcc.target/i386/indirect-thunk-bnd-2.c: Likewise. | ||
87 | * gcc.target/i386/indirect-thunk-bnd-3.c: Likewise. | ||
88 | * gcc.target/i386/indirect-thunk-bnd-4.c: Likewise. | ||
89 | * gcc.target/i386/indirect-thunk-extern-1.c: Likewise. | ||
90 | * gcc.target/i386/indirect-thunk-extern-2.c: Likewise. | ||
91 | * gcc.target/i386/indirect-thunk-extern-3.c: Likewise. | ||
92 | * gcc.target/i386/indirect-thunk-extern-4.c: Likewise. | ||
93 | * gcc.target/i386/indirect-thunk-extern-5.c: Likewise. | ||
94 | * gcc.target/i386/indirect-thunk-extern-6.c: Likewise. | ||
95 | * gcc.target/i386/indirect-thunk-extern-7.c: Likewise. | ||
96 | * gcc.target/i386/indirect-thunk-inline-1.c: Likewise. | ||
97 | * gcc.target/i386/indirect-thunk-inline-2.c: Likewise. | ||
98 | * gcc.target/i386/indirect-thunk-inline-3.c: Likewise. | ||
99 | * gcc.target/i386/indirect-thunk-inline-4.c: Likewise. | ||
100 | * gcc.target/i386/indirect-thunk-inline-5.c: Likewise. | ||
101 | * gcc.target/i386/indirect-thunk-inline-6.c: Likewise. | ||
102 | * gcc.target/i386/indirect-thunk-inline-7.c: Likewise. | ||
103 | * gcc.target/i386/ret-thunk-1.c: New test. | ||
104 | * gcc.target/i386/ret-thunk-10.c: Likewise. | ||
105 | * gcc.target/i386/ret-thunk-11.c: Likewise. | ||
106 | * gcc.target/i386/ret-thunk-12.c: Likewise. | ||
107 | * gcc.target/i386/ret-thunk-13.c: Likewise. | ||
108 | * gcc.target/i386/ret-thunk-14.c: Likewise. | ||
109 | * gcc.target/i386/ret-thunk-15.c: Likewise. | ||
110 | * gcc.target/i386/ret-thunk-16.c: Likewise. | ||
111 | * gcc.target/i386/ret-thunk-2.c: Likewise. | ||
112 | * gcc.target/i386/ret-thunk-3.c: Likewise. | ||
113 | * gcc.target/i386/ret-thunk-4.c: Likewise. | ||
114 | * gcc.target/i386/ret-thunk-5.c: Likewise. | ||
115 | * gcc.target/i386/ret-thunk-6.c: Likewise. | ||
116 | * gcc.target/i386/ret-thunk-7.c: Likewise. | ||
117 | * gcc.target/i386/ret-thunk-8.c: Likewise. | ||
118 | * gcc.target/i386/ret-thunk-9.c: Likewise. | ||
119 | |||
120 | i386: Don't use ASM_OUTPUT_DEF for TARGET_MACHO | ||
121 | |||
122 | ASM_OUTPUT_DEF isn't defined for TARGET_MACHO. Use ASM_OUTPUT_LABEL to | ||
123 | generate the __x86_return_thunk label, instead of the set directive. | ||
124 | Update testcase to remove the __x86_return_thunk label check. Since | ||
125 | -fno-pic is ignored on Darwin, update testcases to sscan or "push" | ||
126 | only on Linux. | ||
127 | |||
128 | gcc/ | ||
129 | |||
130 | Backport from mainline | ||
131 | 2018-01-15 H.J. Lu <hongjiu.lu@intel.com> | ||
132 | |||
133 | PR target/83839 | ||
134 | * config/i386/i386.c (output_indirect_thunk_function): Use | ||
135 | ASM_OUTPUT_LABEL, instead of ASM_OUTPUT_DEF, for TARGET_MACHO | ||
136 | for __x86.return_thunk. | ||
137 | |||
138 | gcc/testsuite/ | ||
139 | |||
140 | Backport from mainline | ||
141 | 2018-01-15 H.J. Lu <hongjiu.lu@intel.com> | ||
142 | |||
143 | PR target/83839 | ||
144 | * gcc.target/i386/indirect-thunk-1.c: Scan for "push" only on | ||
145 | Linux. | ||
146 | * gcc.target/i386/indirect-thunk-2.c: Likewise. | ||
147 | * gcc.target/i386/indirect-thunk-3.c: Likewise. | ||
148 | * gcc.target/i386/indirect-thunk-4.c: Likewise. | ||
149 | * gcc.target/i386/indirect-thunk-7.c: Likewise. | ||
150 | * gcc.target/i386/indirect-thunk-attr-1.c: Likewise. | ||
151 | * gcc.target/i386/indirect-thunk-attr-2.c: Likewise. | ||
152 | * gcc.target/i386/indirect-thunk-attr-5.c: Likewise. | ||
153 | * gcc.target/i386/indirect-thunk-attr-6.c: Likewise. | ||
154 | * gcc.target/i386/indirect-thunk-attr-7.c: Likewise. | ||
155 | * gcc.target/i386/indirect-thunk-extern-1.c: Likewise. | ||
156 | * gcc.target/i386/indirect-thunk-extern-2.c: Likewise. | ||
157 | * gcc.target/i386/indirect-thunk-extern-3.c: Likewise. | ||
158 | * gcc.target/i386/indirect-thunk-extern-4.c: Likewise. | ||
159 | * gcc.target/i386/indirect-thunk-extern-7.c: Likewise. | ||
160 | * gcc.target/i386/indirect-thunk-register-1.c: Likewise. | ||
161 | * gcc.target/i386/indirect-thunk-register-3.c: Likewise. | ||
162 | * gcc.target/i386/indirect-thunk-register-4.c: Likewise. | ||
163 | * gcc.target/i386/ret-thunk-10.c: Likewise. | ||
164 | * gcc.target/i386/ret-thunk-11.c: Likewise. | ||
165 | * gcc.target/i386/ret-thunk-12.c: Likewise. | ||
166 | * gcc.target/i386/ret-thunk-13.c: Likewise. | ||
167 | * gcc.target/i386/ret-thunk-14.c: Likewise. | ||
168 | * gcc.target/i386/ret-thunk-15.c: Likewise. | ||
169 | * gcc.target/i386/ret-thunk-9.c: Don't check the | ||
170 | __x86_return_thunk label. | ||
171 | Scan for "push" only for Linux. | ||
172 | |||
173 | Upstream-Status: Pending | ||
174 | |||
175 | Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> | ||
176 | |||
177 | --- | ||
178 | gcc/config/i386/i386-protos.h | 1 + | ||
179 | gcc/config/i386/i386.c | 152 +++++++++++++++++++-- | ||
180 | gcc/config/i386/i386.h | 3 + | ||
181 | gcc/config/i386/i386.md | 9 +- | ||
182 | gcc/config/i386/i386.opt | 6 +- | ||
183 | gcc/doc/extend.texi | 9 ++ | ||
184 | gcc/doc/invoke.texi | 14 +- | ||
185 | gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 4 +- | ||
186 | gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 4 +- | ||
187 | gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 4 +- | ||
188 | gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 4 +- | ||
189 | gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 2 +- | ||
190 | gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 2 +- | ||
191 | gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 4 +- | ||
192 | .../gcc.target/i386/indirect-thunk-attr-1.c | 4 +- | ||
193 | .../gcc.target/i386/indirect-thunk-attr-2.c | 4 +- | ||
194 | .../gcc.target/i386/indirect-thunk-attr-3.c | 4 +- | ||
195 | .../gcc.target/i386/indirect-thunk-attr-4.c | 4 +- | ||
196 | .../gcc.target/i386/indirect-thunk-attr-5.c | 4 +- | ||
197 | .../gcc.target/i386/indirect-thunk-attr-6.c | 4 +- | ||
198 | .../gcc.target/i386/indirect-thunk-attr-7.c | 4 +- | ||
199 | .../gcc.target/i386/indirect-thunk-attr-8.c | 2 +- | ||
200 | .../gcc.target/i386/indirect-thunk-bnd-1.c | 4 +- | ||
201 | .../gcc.target/i386/indirect-thunk-bnd-2.c | 4 +- | ||
202 | .../gcc.target/i386/indirect-thunk-bnd-3.c | 2 +- | ||
203 | .../gcc.target/i386/indirect-thunk-bnd-4.c | 2 +- | ||
204 | .../gcc.target/i386/indirect-thunk-extern-1.c | 4 +- | ||
205 | .../gcc.target/i386/indirect-thunk-extern-2.c | 4 +- | ||
206 | .../gcc.target/i386/indirect-thunk-extern-3.c | 4 +- | ||
207 | .../gcc.target/i386/indirect-thunk-extern-4.c | 4 +- | ||
208 | .../gcc.target/i386/indirect-thunk-extern-5.c | 2 +- | ||
209 | .../gcc.target/i386/indirect-thunk-extern-6.c | 2 +- | ||
210 | .../gcc.target/i386/indirect-thunk-extern-7.c | 4 +- | ||
211 | .../gcc.target/i386/indirect-thunk-inline-1.c | 4 +- | ||
212 | .../gcc.target/i386/indirect-thunk-inline-2.c | 4 +- | ||
213 | .../gcc.target/i386/indirect-thunk-inline-3.c | 4 +- | ||
214 | .../gcc.target/i386/indirect-thunk-inline-4.c | 4 +- | ||
215 | .../gcc.target/i386/indirect-thunk-inline-5.c | 2 +- | ||
216 | .../gcc.target/i386/indirect-thunk-inline-6.c | 2 +- | ||
217 | .../gcc.target/i386/indirect-thunk-inline-7.c | 4 +- | ||
218 | gcc/testsuite/gcc.target/i386/ret-thunk-1.c | 13 ++ | ||
219 | gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 23 ++++ | ||
220 | gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 23 ++++ | ||
221 | gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 22 +++ | ||
222 | gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 22 +++ | ||
223 | gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 22 +++ | ||
224 | gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 22 +++ | ||
225 | gcc/testsuite/gcc.target/i386/ret-thunk-16.c | 18 +++ | ||
226 | gcc/testsuite/gcc.target/i386/ret-thunk-2.c | 13 ++ | ||
227 | gcc/testsuite/gcc.target/i386/ret-thunk-3.c | 12 ++ | ||
228 | gcc/testsuite/gcc.target/i386/ret-thunk-4.c | 12 ++ | ||
229 | gcc/testsuite/gcc.target/i386/ret-thunk-5.c | 15 ++ | ||
230 | gcc/testsuite/gcc.target/i386/ret-thunk-6.c | 14 ++ | ||
231 | gcc/testsuite/gcc.target/i386/ret-thunk-7.c | 13 ++ | ||
232 | gcc/testsuite/gcc.target/i386/ret-thunk-8.c | 14 ++ | ||
233 | gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 24 ++++ | ||
234 | 56 files changed, 516 insertions(+), 74 deletions(-) | ||
235 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-1.c | ||
236 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-10.c | ||
237 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-11.c | ||
238 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-12.c | ||
239 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-13.c | ||
240 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-14.c | ||
241 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-15.c | ||
242 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-16.c | ||
243 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-2.c | ||
244 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-3.c | ||
245 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-4.c | ||
246 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-5.c | ||
247 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-6.c | ||
248 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-7.c | ||
249 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-8.c | ||
250 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-9.c | ||
251 | |||
252 | diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h | ||
253 | index eca4cbf..620d70e 100644 | ||
254 | --- a/gcc/config/i386/i386-protos.h | ||
255 | +++ b/gcc/config/i386/i386-protos.h | ||
256 | @@ -312,6 +312,7 @@ extern enum attr_cpu ix86_schedule; | ||
257 | |||
258 | extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op); | ||
259 | extern const char * ix86_output_indirect_jmp (rtx call_op, bool ret_p); | ||
260 | +extern const char * ix86_output_function_return (bool long_p); | ||
261 | extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load, | ||
262 | enum machine_mode mode); | ||
263 | |||
264 | diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c | ||
265 | index 0b9fc4d..34e26a3 100644 | ||
266 | --- a/gcc/config/i386/i386.c | ||
267 | +++ b/gcc/config/i386/i386.c | ||
268 | @@ -6390,6 +6390,31 @@ ix86_set_indirect_branch_type (tree fndecl) | ||
269 | else | ||
270 | cfun->machine->indirect_branch_type = ix86_indirect_branch; | ||
271 | } | ||
272 | + | ||
273 | + if (cfun->machine->function_return_type == indirect_branch_unset) | ||
274 | + { | ||
275 | + tree attr = lookup_attribute ("function_return", | ||
276 | + DECL_ATTRIBUTES (fndecl)); | ||
277 | + if (attr != NULL) | ||
278 | + { | ||
279 | + tree args = TREE_VALUE (attr); | ||
280 | + if (args == NULL) | ||
281 | + gcc_unreachable (); | ||
282 | + tree cst = TREE_VALUE (args); | ||
283 | + if (strcmp (TREE_STRING_POINTER (cst), "keep") == 0) | ||
284 | + cfun->machine->function_return_type = indirect_branch_keep; | ||
285 | + else if (strcmp (TREE_STRING_POINTER (cst), "thunk") == 0) | ||
286 | + cfun->machine->function_return_type = indirect_branch_thunk; | ||
287 | + else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") == 0) | ||
288 | + cfun->machine->function_return_type = indirect_branch_thunk_inline; | ||
289 | + else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") == 0) | ||
290 | + cfun->machine->function_return_type = indirect_branch_thunk_extern; | ||
291 | + else | ||
292 | + gcc_unreachable (); | ||
293 | + } | ||
294 | + else | ||
295 | + cfun->machine->function_return_type = ix86_function_return; | ||
296 | + } | ||
297 | } | ||
298 | |||
299 | /* Establish appropriate back-end context for processing the function | ||
300 | @@ -11036,8 +11061,12 @@ static int indirect_thunks_bnd_used; | ||
301 | /* Fills in the label name that should be used for the indirect thunk. */ | ||
302 | |||
303 | static void | ||
304 | -indirect_thunk_name (char name[32], int regno, bool need_bnd_p) | ||
305 | +indirect_thunk_name (char name[32], int regno, bool need_bnd_p, | ||
306 | + bool ret_p) | ||
307 | { | ||
308 | + if (regno >= 0 && ret_p) | ||
309 | + gcc_unreachable (); | ||
310 | + | ||
311 | if (USE_HIDDEN_LINKONCE) | ||
312 | { | ||
313 | const char *bnd = need_bnd_p ? "_bnd" : ""; | ||
314 | @@ -11052,7 +11081,10 @@ indirect_thunk_name (char name[32], int regno, bool need_bnd_p) | ||
315 | bnd, reg_prefix, reg_names[regno]); | ||
316 | } | ||
317 | else | ||
318 | - sprintf (name, "__x86_indirect_thunk%s", bnd); | ||
319 | + { | ||
320 | + const char *ret = ret_p ? "return" : "indirect"; | ||
321 | + sprintf (name, "__x86_%s_thunk%s", ret, bnd); | ||
322 | + } | ||
323 | } | ||
324 | else | ||
325 | { | ||
326 | @@ -11065,10 +11097,20 @@ indirect_thunk_name (char name[32], int regno, bool need_bnd_p) | ||
327 | } | ||
328 | else | ||
329 | { | ||
330 | - if (need_bnd_p) | ||
331 | - ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0); | ||
332 | + if (ret_p) | ||
333 | + { | ||
334 | + if (need_bnd_p) | ||
335 | + ASM_GENERATE_INTERNAL_LABEL (name, "LRTB", 0); | ||
336 | + else | ||
337 | + ASM_GENERATE_INTERNAL_LABEL (name, "LRT", 0); | ||
338 | + } | ||
339 | else | ||
340 | - ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0); | ||
341 | + { | ||
342 | + if (need_bnd_p) | ||
343 | + ASM_GENERATE_INTERNAL_LABEL (name, "LITB", 0); | ||
344 | + else | ||
345 | + ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0); | ||
346 | + } | ||
347 | } | ||
348 | } | ||
349 | } | ||
350 | @@ -11163,7 +11205,7 @@ output_indirect_thunk_function (bool need_bnd_p, int regno) | ||
351 | tree decl; | ||
352 | |||
353 | /* Create __x86_indirect_thunk/__x86_indirect_thunk_bnd. */ | ||
354 | - indirect_thunk_name (name, regno, need_bnd_p); | ||
355 | + indirect_thunk_name (name, regno, need_bnd_p, false); | ||
356 | decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, | ||
357 | get_identifier (name), | ||
358 | build_function_type_list (void_type_node, NULL_TREE)); | ||
359 | @@ -11206,6 +11248,36 @@ output_indirect_thunk_function (bool need_bnd_p, int regno) | ||
360 | ASM_OUTPUT_LABEL (asm_out_file, name); | ||
361 | } | ||
362 | |||
363 | + if (regno < 0) | ||
364 | + { | ||
365 | + /* Create alias for __x86.return_thunk/__x86.return_thunk_bnd. */ | ||
366 | + char alias[32]; | ||
367 | + | ||
368 | + indirect_thunk_name (alias, regno, need_bnd_p, true); | ||
369 | +#if TARGET_MACHO | ||
370 | + if (TARGET_MACHO) | ||
371 | + { | ||
372 | + fputs ("\t.weak_definition\t", asm_out_file); | ||
373 | + assemble_name (asm_out_file, alias); | ||
374 | + fputs ("\n\t.private_extern\t", asm_out_file); | ||
375 | + assemble_name (asm_out_file, alias); | ||
376 | + putc ('\n', asm_out_file); | ||
377 | + ASM_OUTPUT_LABEL (asm_out_file, alias); | ||
378 | + } | ||
379 | +#else | ||
380 | + ASM_OUTPUT_DEF (asm_out_file, alias, name); | ||
381 | + if (USE_HIDDEN_LINKONCE) | ||
382 | + { | ||
383 | + fputs ("\t.globl\t", asm_out_file); | ||
384 | + assemble_name (asm_out_file, alias); | ||
385 | + putc ('\n', asm_out_file); | ||
386 | + fputs ("\t.hidden\t", asm_out_file); | ||
387 | + assemble_name (asm_out_file, alias); | ||
388 | + putc ('\n', asm_out_file); | ||
389 | + } | ||
390 | +#endif | ||
391 | + } | ||
392 | + | ||
393 | DECL_INITIAL (decl) = make_node (BLOCK); | ||
394 | current_function_decl = decl; | ||
395 | allocate_struct_function (decl, false); | ||
396 | @@ -27687,7 +27759,7 @@ ix86_output_indirect_branch_via_reg (rtx call_op, bool sibcall_p) | ||
397 | else | ||
398 | indirect_thunks_used |= 1 << i; | ||
399 | } | ||
400 | - indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); | ||
401 | + indirect_thunk_name (thunk_name_buf, regno, need_bnd_p, false); | ||
402 | thunk_name = thunk_name_buf; | ||
403 | } | ||
404 | else | ||
405 | @@ -27796,7 +27868,7 @@ ix86_output_indirect_branch_via_push (rtx call_op, const char *xasm, | ||
406 | else | ||
407 | indirect_thunk_needed = true; | ||
408 | } | ||
409 | - indirect_thunk_name (thunk_name_buf, regno, need_bnd_p); | ||
410 | + indirect_thunk_name (thunk_name_buf, regno, need_bnd_p, false); | ||
411 | thunk_name = thunk_name_buf; | ||
412 | } | ||
413 | else | ||
414 | @@ -27931,6 +28003,46 @@ ix86_output_indirect_jmp (rtx call_op, bool ret_p) | ||
415 | return "%!jmp\t%A0"; | ||
416 | } | ||
417 | |||
418 | +/* Output function return. CALL_OP is the jump target. Add a REP | ||
419 | + prefix to RET if LONG_P is true and function return is kept. */ | ||
420 | + | ||
421 | +const char * | ||
422 | +ix86_output_function_return (bool long_p) | ||
423 | +{ | ||
424 | + if (cfun->machine->function_return_type != indirect_branch_keep) | ||
425 | + { | ||
426 | + char thunk_name[32]; | ||
427 | + bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn); | ||
428 | + | ||
429 | + if (cfun->machine->function_return_type | ||
430 | + != indirect_branch_thunk_inline) | ||
431 | + { | ||
432 | + bool need_thunk = (cfun->machine->function_return_type | ||
433 | + == indirect_branch_thunk); | ||
434 | + indirect_thunk_name (thunk_name, -1, need_bnd_p, true); | ||
435 | + if (need_bnd_p) | ||
436 | + { | ||
437 | + indirect_thunk_bnd_needed |= need_thunk; | ||
438 | + fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); | ||
439 | + } | ||
440 | + else | ||
441 | + { | ||
442 | + indirect_thunk_needed |= need_thunk; | ||
443 | + fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); | ||
444 | + } | ||
445 | + } | ||
446 | + else | ||
447 | + output_indirect_thunk (need_bnd_p, -1); | ||
448 | + | ||
449 | + return ""; | ||
450 | + } | ||
451 | + | ||
452 | + if (!long_p || ix86_bnd_prefixed_insn_p (current_output_insn)) | ||
453 | + return "%!ret"; | ||
454 | + | ||
455 | + return "rep%; ret"; | ||
456 | +} | ||
457 | + | ||
458 | /* Output the assembly for a call instruction. */ | ||
459 | |||
460 | const char * | ||
461 | @@ -45461,6 +45573,28 @@ ix86_handle_fndecl_attribute (tree *node, tree name, tree args, int, | ||
462 | } | ||
463 | } | ||
464 | |||
465 | + if (is_attribute_p ("function_return", name)) | ||
466 | + { | ||
467 | + tree cst = TREE_VALUE (args); | ||
468 | + if (TREE_CODE (cst) != STRING_CST) | ||
469 | + { | ||
470 | + warning (OPT_Wattributes, | ||
471 | + "%qE attribute requires a string constant argument", | ||
472 | + name); | ||
473 | + *no_add_attrs = true; | ||
474 | + } | ||
475 | + else if (strcmp (TREE_STRING_POINTER (cst), "keep") != 0 | ||
476 | + && strcmp (TREE_STRING_POINTER (cst), "thunk") != 0 | ||
477 | + && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") != 0 | ||
478 | + && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") != 0) | ||
479 | + { | ||
480 | + warning (OPT_Wattributes, | ||
481 | + "argument to %qE attribute is not " | ||
482 | + "(keep|thunk|thunk-inline|thunk-extern)", name); | ||
483 | + *no_add_attrs = true; | ||
484 | + } | ||
485 | + } | ||
486 | + | ||
487 | return NULL_TREE; | ||
488 | } | ||
489 | |||
490 | @@ -49690,6 +49824,8 @@ static const struct attribute_spec ix86_attribute_table[] = | ||
491 | ix86_handle_callee_pop_aggregate_return, true }, | ||
492 | { "indirect_branch", 1, 1, true, false, false, | ||
493 | ix86_handle_fndecl_attribute, false }, | ||
494 | + { "function_return", 1, 1, true, false, false, | ||
495 | + ix86_handle_fndecl_attribute, false }, | ||
496 | |||
497 | /* End element. */ | ||
498 | { NULL, 0, 0, false, false, false, NULL, false } | ||
499 | diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h | ||
500 | index 9dccdb0..b34bc11 100644 | ||
501 | --- a/gcc/config/i386/i386.h | ||
502 | +++ b/gcc/config/i386/i386.h | ||
503 | @@ -2579,6 +2579,9 @@ struct GTY(()) machine_function { | ||
504 | "indirect_jump" or "tablejump". */ | ||
505 | BOOL_BITFIELD has_local_indirect_jump : 1; | ||
506 | |||
507 | + /* How to generate function return. */ | ||
508 | + ENUM_BITFIELD(indirect_branch) function_return_type : 3; | ||
509 | + | ||
510 | /* If true, there is register available for argument passing. This | ||
511 | is used only in ix86_function_ok_for_sibcall by 32-bit to determine | ||
512 | if there is scratch register available for indirect sibcall. In | ||
513 | diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md | ||
514 | index 153e162..2da671e 100644 | ||
515 | --- a/gcc/config/i386/i386.md | ||
516 | +++ b/gcc/config/i386/i386.md | ||
517 | @@ -12489,7 +12489,7 @@ | ||
518 | (define_insn "simple_return_internal" | ||
519 | [(simple_return)] | ||
520 | "reload_completed" | ||
521 | - "%!ret" | ||
522 | + "* return ix86_output_function_return (false);" | ||
523 | [(set_attr "length" "1") | ||
524 | (set_attr "atom_unit" "jeu") | ||
525 | (set_attr "length_immediate" "0") | ||
526 | @@ -12503,12 +12503,7 @@ | ||
527 | [(simple_return) | ||
528 | (unspec [(const_int 0)] UNSPEC_REP)] | ||
529 | "reload_completed" | ||
530 | -{ | ||
531 | - if (ix86_bnd_prefixed_insn_p (insn)) | ||
532 | - return "%!ret"; | ||
533 | - | ||
534 | - return "rep%; ret"; | ||
535 | -} | ||
536 | + "* return ix86_output_function_return (true);" | ||
537 | [(set_attr "length" "2") | ||
538 | (set_attr "atom_unit" "jeu") | ||
539 | (set_attr "length_immediate" "0") | ||
540 | diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt | ||
541 | index 5ffa334..ad5916f 100644 | ||
542 | --- a/gcc/config/i386/i386.opt | ||
543 | +++ b/gcc/config/i386/i386.opt | ||
544 | @@ -902,9 +902,13 @@ mindirect-branch= | ||
545 | Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_indirect_branch) Init(indirect_branch_keep) | ||
546 | Convert indirect call and jump to call and return thunks. | ||
547 | |||
548 | +mfunction-return= | ||
549 | +Target Report RejectNegative Joined Enum(indirect_branch) Var(ix86_function_return) Init(indirect_branch_keep) | ||
550 | +Convert function return to call and return thunk. | ||
551 | + | ||
552 | Enum | ||
553 | Name(indirect_branch) Type(enum indirect_branch) | ||
554 | -Known indirect branch choices (for use with the -mindirect-branch= option): | ||
555 | +Known indirect branch choices (for use with the -mindirect-branch=/-mfunction-return= options): | ||
556 | |||
557 | EnumValue | ||
558 | Enum(indirect_branch) String(keep) Value(indirect_branch_keep) | ||
559 | diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi | ||
560 | index 8668dae..2cb6bd1 100644 | ||
561 | --- a/gcc/doc/extend.texi | ||
562 | +++ b/gcc/doc/extend.texi | ||
563 | @@ -5429,6 +5429,15 @@ call and jump to call and return thunk. @samp{thunk-inline} converts | ||
564 | indirect call and jump to inlined call and return thunk. | ||
565 | @samp{thunk-extern} converts indirect call and jump to external call | ||
566 | and return thunk provided in a separate object file. | ||
567 | + | ||
568 | +@item function_return("@var{choice}") | ||
569 | +@cindex @code{function_return} function attribute, x86 | ||
570 | +On x86 targets, the @code{function_return} attribute causes the compiler | ||
571 | +to convert function return with @var{choice}. @samp{keep} keeps function | ||
572 | +return unmodified. @samp{thunk} converts function return to call and | ||
573 | +return thunk. @samp{thunk-inline} converts function return to inlined | ||
574 | +call and return thunk. @samp{thunk-extern} converts function return to | ||
575 | +external call and return thunk provided in a separate object file. | ||
576 | @end table | ||
577 | |||
578 | On the x86, the inliner does not inline a | ||
579 | diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi | ||
580 | index ff9a194..fa63dc5 100644 | ||
581 | --- a/gcc/doc/invoke.texi | ||
582 | +++ b/gcc/doc/invoke.texi | ||
583 | @@ -1169,7 +1169,8 @@ See RS/6000 and PowerPC Options. | ||
584 | -msse2avx -mfentry -mrecord-mcount -mnop-mcount -m8bit-idiv @gol | ||
585 | -mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol | ||
586 | -malign-data=@var{type} -mstack-protector-guard=@var{guard} @gol | ||
587 | --mmitigate-rop -mindirect-branch=@var{choice}} | ||
588 | +-mmitigate-rop -mindirect-branch=@var{choice} @gol | ||
589 | +-mfunction-return=@var{choice}} | ||
590 | |||
591 | @emph{x86 Windows Options} | ||
592 | @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol | ||
593 | @@ -24229,6 +24230,17 @@ to external call and return thunk provided in a separate object file. | ||
594 | You can control this behavior for a specific function by using the | ||
595 | function attribute @code{indirect_branch}. @xref{Function Attributes}. | ||
596 | |||
597 | +@item -mfunction-return=@var{choice} | ||
598 | +@opindex -mfunction-return | ||
599 | +Convert function return with @var{choice}. The default is @samp{keep}, | ||
600 | +which keeps function return unmodified. @samp{thunk} converts function | ||
601 | +return to call and return thunk. @samp{thunk-inline} converts function | ||
602 | +return to inlined call and return thunk. @samp{thunk-extern} converts | ||
603 | +function return to external call and return thunk provided in a separate | ||
604 | +object file. You can control this behavior for a specific function by | ||
605 | +using the function attribute @code{function_return}. | ||
606 | +@xref{Function Attributes}. | ||
607 | + | ||
608 | @end table | ||
609 | |||
610 | These @samp{-m} switches are supported in addition to the above | ||
611 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | ||
612 | index d983e1c..e365ef5 100644 | ||
613 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | ||
614 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | ||
615 | @@ -1,5 +1,5 @@ | ||
616 | /* { dg-do compile } */ | ||
617 | -/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ | ||
618 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ | ||
619 | |||
620 | typedef void (*dispatch_t)(long offset); | ||
621 | |||
622 | @@ -11,7 +11,7 @@ male_indirect_jump (long offset) | ||
623 | dispatch(offset); | ||
624 | } | ||
625 | |||
626 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
627 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
628 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
629 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
630 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
631 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | ||
632 | index 58f09b4..05a51ad 100644 | ||
633 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | ||
634 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | ||
635 | @@ -1,5 +1,5 @@ | ||
636 | /* { dg-do compile } */ | ||
637 | -/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ | ||
638 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ | ||
639 | |||
640 | typedef void (*dispatch_t)(long offset); | ||
641 | |||
642 | @@ -11,7 +11,7 @@ male_indirect_jump (long offset) | ||
643 | dispatch[offset](offset); | ||
644 | } | ||
645 | |||
646 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
647 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
648 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
649 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
650 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
651 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | ||
652 | index f20d35c..3c0d4c3 100644 | ||
653 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | ||
654 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | ||
655 | @@ -1,5 +1,5 @@ | ||
656 | /* { dg-do compile } */ | ||
657 | -/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ | ||
658 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ | ||
659 | |||
660 | typedef void (*dispatch_t)(long offset); | ||
661 | |||
662 | @@ -12,7 +12,7 @@ male_indirect_jump (long offset) | ||
663 | return 0; | ||
664 | } | ||
665 | |||
666 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
667 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
668 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
669 | /* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
670 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
671 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | ||
672 | index 0eff8fb..14d4ef6 100644 | ||
673 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | ||
674 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | ||
675 | @@ -1,5 +1,5 @@ | ||
676 | /* { dg-do compile } */ | ||
677 | -/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ | ||
678 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ | ||
679 | |||
680 | typedef void (*dispatch_t)(long offset); | ||
681 | |||
682 | @@ -12,7 +12,7 @@ male_indirect_jump (long offset) | ||
683 | return 0; | ||
684 | } | ||
685 | |||
686 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
687 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
688 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
689 | /* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
690 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
691 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | ||
692 | index a25b20d..b4836c3 100644 | ||
693 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | ||
694 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | ||
695 | @@ -1,5 +1,5 @@ | ||
696 | /* { dg-do compile { target *-*-linux* } } */ | ||
697 | -/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */ | ||
698 | +/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ | ||
699 | |||
700 | extern void bar (void); | ||
701 | |||
702 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | ||
703 | index cff114a..1f06bd1 100644 | ||
704 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | ||
705 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | ||
706 | @@ -1,5 +1,5 @@ | ||
707 | /* { dg-do compile { target *-*-linux* } } */ | ||
708 | -/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk" } */ | ||
709 | +/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ | ||
710 | |||
711 | extern void bar (void); | ||
712 | |||
713 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | ||
714 | index afdb600..bc6b47a 100644 | ||
715 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | ||
716 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | ||
717 | @@ -1,5 +1,5 @@ | ||
718 | /* { dg-do compile } */ | ||
719 | -/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ | ||
720 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ | ||
721 | |||
722 | void func0 (void); | ||
723 | void func1 (void); | ||
724 | @@ -35,7 +35,7 @@ bar (int i) | ||
725 | } | ||
726 | } | ||
727 | |||
728 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ | ||
729 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */ | ||
730 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
731 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
732 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
733 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | ||
734 | index d64d978..2257be3 100644 | ||
735 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | ||
736 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | ||
737 | @@ -1,5 +1,5 @@ | ||
738 | /* { dg-do compile } */ | ||
739 | -/* { dg-options "-O2 -fno-pic" } */ | ||
740 | +/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ | ||
741 | |||
742 | typedef void (*dispatch_t)(long offset); | ||
743 | |||
744 | @@ -14,7 +14,7 @@ male_indirect_jump (long offset) | ||
745 | dispatch(offset); | ||
746 | } | ||
747 | |||
748 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
749 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
750 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
751 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
752 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
753 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | ||
754 | index 9306745..e9cfdc5 100644 | ||
755 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | ||
756 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | ||
757 | @@ -1,5 +1,5 @@ | ||
758 | /* { dg-do compile } */ | ||
759 | -/* { dg-options "-O2 -fno-pic" } */ | ||
760 | +/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ | ||
761 | |||
762 | typedef void (*dispatch_t)(long offset); | ||
763 | |||
764 | @@ -12,7 +12,7 @@ male_indirect_jump (long offset) | ||
765 | dispatch[offset](offset); | ||
766 | } | ||
767 | |||
768 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
769 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
770 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
771 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
772 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
773 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | ||
774 | index 97744d6..f938db0 100644 | ||
775 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | ||
776 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | ||
777 | @@ -1,5 +1,5 @@ | ||
778 | /* { dg-do compile } */ | ||
779 | -/* { dg-options "-O2 -fno-pic" } */ | ||
780 | +/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ | ||
781 | |||
782 | typedef void (*dispatch_t)(long offset); | ||
783 | |||
784 | @@ -14,7 +14,7 @@ male_indirect_jump (long offset) | ||
785 | return 0; | ||
786 | } | ||
787 | |||
788 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
789 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
790 | /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ | ||
791 | /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ | ||
792 | /* { dg-final { scan-assembler {\tpause} } } */ | ||
793 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | ||
794 | index bfce3ea..4e58599 100644 | ||
795 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | ||
796 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | ||
797 | @@ -1,5 +1,5 @@ | ||
798 | /* { dg-do compile } */ | ||
799 | -/* { dg-options "-O2 -fno-pic" } */ | ||
800 | +/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ | ||
801 | |||
802 | typedef void (*dispatch_t)(long offset); | ||
803 | |||
804 | @@ -13,7 +13,7 @@ male_indirect_jump (long offset) | ||
805 | return 0; | ||
806 | } | ||
807 | |||
808 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
809 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
810 | /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ | ||
811 | /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ | ||
812 | /* { dg-final { scan-assembler {\tpause} } } */ | ||
813 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | ||
814 | index 0833606..b8d5024 100644 | ||
815 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | ||
816 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | ||
817 | @@ -1,5 +1,5 @@ | ||
818 | /* { dg-do compile } */ | ||
819 | -/* { dg-options "-O2 -fno-pic" } */ | ||
820 | +/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ | ||
821 | |||
822 | typedef void (*dispatch_t)(long offset); | ||
823 | |||
824 | @@ -14,7 +14,7 @@ male_indirect_jump (long offset) | ||
825 | return 0; | ||
826 | } | ||
827 | |||
828 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
829 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
830 | /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
831 | /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
832 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
833 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | ||
834 | index 2eba0fb..455adab 100644 | ||
835 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | ||
836 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | ||
837 | @@ -1,5 +1,5 @@ | ||
838 | /* { dg-do compile } */ | ||
839 | -/* { dg-options "-O2 -fno-pic" } */ | ||
840 | +/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ | ||
841 | |||
842 | typedef void (*dispatch_t)(long offset); | ||
843 | |||
844 | @@ -13,7 +13,7 @@ male_indirect_jump (long offset) | ||
845 | return 0; | ||
846 | } | ||
847 | |||
848 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
849 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
850 | /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
851 | /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
852 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
853 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | ||
854 | index f58427e..4595b84 100644 | ||
855 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | ||
856 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | ||
857 | @@ -1,5 +1,5 @@ | ||
858 | /* { dg-do compile } */ | ||
859 | -/* { dg-options "-O2 -fno-pic" } */ | ||
860 | +/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ | ||
861 | |||
862 | void func0 (void); | ||
863 | void func1 (void); | ||
864 | @@ -36,7 +36,7 @@ bar (int i) | ||
865 | } | ||
866 | } | ||
867 | |||
868 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ | ||
869 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */ | ||
870 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
871 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ | ||
872 | /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
873 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c | ||
874 | index 564ed39..d730d31 100644 | ||
875 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c | ||
876 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-8.c | ||
877 | @@ -1,5 +1,5 @@ | ||
878 | /* { dg-do compile } */ | ||
879 | -/* { dg-options "-O2 -mindirect-branch=thunk -fno-pic" } */ | ||
880 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ | ||
881 | |||
882 | void func0 (void); | ||
883 | void func1 (void); | ||
884 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | ||
885 | index 50fbee2..5e3e118 100644 | ||
886 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | ||
887 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | ||
888 | @@ -1,5 +1,5 @@ | ||
889 | /* { dg-do compile { target { ! x32 } } } */ | ||
890 | -/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ | ||
891 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ | ||
892 | |||
893 | void (*dispatch) (char *); | ||
894 | char buf[10]; | ||
895 | @@ -10,7 +10,7 @@ foo (void) | ||
896 | dispatch (buf); | ||
897 | } | ||
898 | |||
899 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
900 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
901 | /* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ | ||
902 | /* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ | ||
903 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
904 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | ||
905 | index 2976e67..2801aa4 100644 | ||
906 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | ||
907 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | ||
908 | @@ -1,5 +1,5 @@ | ||
909 | /* { dg-do compile { target { ! x32 } } } */ | ||
910 | -/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ | ||
911 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ | ||
912 | |||
913 | void (*dispatch) (char *); | ||
914 | char buf[10]; | ||
915 | @@ -11,7 +11,7 @@ foo (void) | ||
916 | return 0; | ||
917 | } | ||
918 | |||
919 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
920 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
921 | /* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ | ||
922 | /* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ | ||
923 | /* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */ | ||
924 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | ||
925 | index da4bc98..70b4fb3 100644 | ||
926 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | ||
927 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | ||
928 | @@ -1,5 +1,5 @@ | ||
929 | /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ | ||
930 | -/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ | ||
931 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ | ||
932 | |||
933 | void bar (char *); | ||
934 | char buf[10]; | ||
935 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | ||
936 | index c64d12e..3baf03e 100644 | ||
937 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | ||
938 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | ||
939 | @@ -1,5 +1,5 @@ | ||
940 | /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ | ||
941 | -/* { dg-options "-O2 -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ | ||
942 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ | ||
943 | |||
944 | void bar (char *); | ||
945 | char buf[10]; | ||
946 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | ||
947 | index 49f27b4..edeb264 100644 | ||
948 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | ||
949 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | ||
950 | @@ -1,5 +1,5 @@ | ||
951 | /* { dg-do compile } */ | ||
952 | -/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ | ||
953 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ | ||
954 | |||
955 | typedef void (*dispatch_t)(long offset); | ||
956 | |||
957 | @@ -11,7 +11,7 @@ male_indirect_jump (long offset) | ||
958 | dispatch(offset); | ||
959 | } | ||
960 | |||
961 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
962 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
963 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
964 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
965 | /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
966 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | ||
967 | index a1e3eb6..1d00413 100644 | ||
968 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | ||
969 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | ||
970 | @@ -1,5 +1,5 @@ | ||
971 | /* { dg-do compile } */ | ||
972 | -/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ | ||
973 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ | ||
974 | |||
975 | typedef void (*dispatch_t)(long offset); | ||
976 | |||
977 | @@ -11,7 +11,7 @@ male_indirect_jump (long offset) | ||
978 | dispatch[offset](offset); | ||
979 | } | ||
980 | |||
981 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
982 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
983 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
984 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
985 | /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
986 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | ||
987 | index 395634e..06ebf1c 100644 | ||
988 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | ||
989 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | ||
990 | @@ -1,5 +1,5 @@ | ||
991 | /* { dg-do compile } */ | ||
992 | -/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ | ||
993 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ | ||
994 | |||
995 | typedef void (*dispatch_t)(long offset); | ||
996 | |||
997 | @@ -12,7 +12,7 @@ male_indirect_jump (long offset) | ||
998 | return 0; | ||
999 | } | ||
1000 | |||
1001 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1002 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
1003 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
1004 | /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
1005 | /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
1006 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | ||
1007 | index fd3f633..1c8f944 100644 | ||
1008 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | ||
1009 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | ||
1010 | @@ -1,5 +1,5 @@ | ||
1011 | /* { dg-do compile } */ | ||
1012 | -/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ | ||
1013 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ | ||
1014 | |||
1015 | typedef void (*dispatch_t)(long offset); | ||
1016 | |||
1017 | @@ -12,7 +12,7 @@ male_indirect_jump (long offset) | ||
1018 | return 0; | ||
1019 | } | ||
1020 | |||
1021 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1022 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
1023 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
1024 | /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
1025 | /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
1026 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | ||
1027 | index ba2f92b..21740ac 100644 | ||
1028 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | ||
1029 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | ||
1030 | @@ -1,5 +1,5 @@ | ||
1031 | /* { dg-do compile { target *-*-linux* } } */ | ||
1032 | -/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */ | ||
1033 | +/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ | ||
1034 | |||
1035 | extern void bar (void); | ||
1036 | |||
1037 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | ||
1038 | index 0c5a2d4..a77c1f4 100644 | ||
1039 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | ||
1040 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | ||
1041 | @@ -1,5 +1,5 @@ | ||
1042 | /* { dg-do compile { target *-*-linux* } } */ | ||
1043 | -/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-extern" } */ | ||
1044 | +/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ | ||
1045 | |||
1046 | extern void bar (void); | ||
1047 | |||
1048 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | ||
1049 | index 6652523..86e9fd1 100644 | ||
1050 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | ||
1051 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | ||
1052 | @@ -1,5 +1,5 @@ | ||
1053 | /* { dg-do compile } */ | ||
1054 | -/* { dg-options "-O2 -mindirect-branch=thunk-extern -fno-pic" } */ | ||
1055 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ | ||
1056 | |||
1057 | void func0 (void); | ||
1058 | void func1 (void); | ||
1059 | @@ -35,7 +35,7 @@ bar (int i) | ||
1060 | } | ||
1061 | } | ||
1062 | |||
1063 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ | ||
1064 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */ | ||
1065 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
1066 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
1067 | /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
1068 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | ||
1069 | index 68c0ff7..3ecde87 100644 | ||
1070 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | ||
1071 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | ||
1072 | @@ -1,5 +1,5 @@ | ||
1073 | /* { dg-do compile } */ | ||
1074 | -/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ | ||
1075 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ | ||
1076 | |||
1077 | typedef void (*dispatch_t)(long offset); | ||
1078 | |||
1079 | @@ -11,7 +11,7 @@ male_indirect_jump (long offset) | ||
1080 | dispatch(offset); | ||
1081 | } | ||
1082 | |||
1083 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1084 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
1085 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1086 | /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
1087 | /* { dg-final { scan-assembler {\tpause} } } */ | ||
1088 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | ||
1089 | index e2da1fc..df32a19 100644 | ||
1090 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | ||
1091 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | ||
1092 | @@ -1,5 +1,5 @@ | ||
1093 | /* { dg-do compile } */ | ||
1094 | -/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ | ||
1095 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ | ||
1096 | |||
1097 | typedef void (*dispatch_t)(long offset); | ||
1098 | |||
1099 | @@ -11,7 +11,7 @@ male_indirect_jump (long offset) | ||
1100 | dispatch[offset](offset); | ||
1101 | } | ||
1102 | |||
1103 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1104 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
1105 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1106 | /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
1107 | /* { dg-final { scan-assembler {\tpause} } } */ | ||
1108 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | ||
1109 | index 244fec7..9540996 100644 | ||
1110 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | ||
1111 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | ||
1112 | @@ -1,5 +1,5 @@ | ||
1113 | /* { dg-do compile } */ | ||
1114 | -/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ | ||
1115 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ | ||
1116 | |||
1117 | typedef void (*dispatch_t)(long offset); | ||
1118 | |||
1119 | @@ -12,7 +12,7 @@ male_indirect_jump (long offset) | ||
1120 | return 0; | ||
1121 | } | ||
1122 | |||
1123 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1124 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
1125 | /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ | ||
1126 | /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ | ||
1127 | /* { dg-final { scan-assembler-times {\tpause} 1 } } */ | ||
1128 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | ||
1129 | index 107ebe3..f3db6e2 100644 | ||
1130 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | ||
1131 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | ||
1132 | @@ -1,5 +1,5 @@ | ||
1133 | /* { dg-do compile } */ | ||
1134 | -/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ | ||
1135 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ | ||
1136 | |||
1137 | typedef void (*dispatch_t)(long offset); | ||
1138 | |||
1139 | @@ -12,7 +12,7 @@ male_indirect_jump (long offset) | ||
1140 | return 0; | ||
1141 | } | ||
1142 | |||
1143 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { ! x32 } } } } */ | ||
1144 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
1145 | /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ | ||
1146 | /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ | ||
1147 | /* { dg-final { scan-assembler-times {\tpause} 1 } } */ | ||
1148 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | ||
1149 | index 17b04ef..0f687c3 100644 | ||
1150 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | ||
1151 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | ||
1152 | @@ -1,5 +1,5 @@ | ||
1153 | /* { dg-do compile { target *-*-linux* } } */ | ||
1154 | -/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */ | ||
1155 | +/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ | ||
1156 | |||
1157 | extern void bar (void); | ||
1158 | |||
1159 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | ||
1160 | index d9eb112..b27c6fc 100644 | ||
1161 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | ||
1162 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | ||
1163 | @@ -1,5 +1,5 @@ | ||
1164 | /* { dg-do compile { target *-*-linux* } } */ | ||
1165 | -/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch=thunk-inline" } */ | ||
1166 | +/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ | ||
1167 | |||
1168 | extern void bar (void); | ||
1169 | |||
1170 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | ||
1171 | index d02b1dc..764a375 100644 | ||
1172 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | ||
1173 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | ||
1174 | @@ -1,5 +1,5 @@ | ||
1175 | /* { dg-do compile } */ | ||
1176 | -/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ | ||
1177 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ | ||
1178 | |||
1179 | void func0 (void); | ||
1180 | void func1 (void); | ||
1181 | @@ -35,7 +35,7 @@ bar (int i) | ||
1182 | } | ||
1183 | } | ||
1184 | |||
1185 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { ! x32 } } } } */ | ||
1186 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */ | ||
1187 | /* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
1188 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1189 | /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
1190 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-1.c b/gcc/testsuite/gcc.target/i386/ret-thunk-1.c | ||
1191 | new file mode 100644 | ||
1192 | index 0000000..7223f67 | ||
1193 | --- /dev/null | ||
1194 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-1.c | ||
1195 | @@ -0,0 +1,13 @@ | ||
1196 | +/* { dg-do compile } */ | ||
1197 | +/* { dg-options "-O2 -mfunction-return=thunk" } */ | ||
1198 | + | ||
1199 | +void | ||
1200 | +foo (void) | ||
1201 | +{ | ||
1202 | +} | ||
1203 | + | ||
1204 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ | ||
1205 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1206 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
1207 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
1208 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
1209 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c | ||
1210 | new file mode 100644 | ||
1211 | index 0000000..3a6727b | ||
1212 | --- /dev/null | ||
1213 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c | ||
1214 | @@ -0,0 +1,23 @@ | ||
1215 | +/* { dg-do compile } */ | ||
1216 | +/* { dg-options "-O2 -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */ | ||
1217 | + | ||
1218 | +extern void (*bar) (void); | ||
1219 | + | ||
1220 | +int | ||
1221 | +foo (void) | ||
1222 | +{ | ||
1223 | + bar (); | ||
1224 | + return 0; | ||
1225 | +} | ||
1226 | + | ||
1227 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1228 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
1229 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ | ||
1230 | +/* { dg-final { scan-assembler-times {\tpause} 2 } } */ | ||
1231 | +/* { dg-final { scan-assembler-times {\tlfence} 2 } } */ | ||
1232 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ | ||
1233 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
1234 | +/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */ | ||
1235 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ | ||
1236 | +/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */ | ||
1237 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
1238 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c | ||
1239 | new file mode 100644 | ||
1240 | index 0000000..b8f6818 | ||
1241 | --- /dev/null | ||
1242 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c | ||
1243 | @@ -0,0 +1,23 @@ | ||
1244 | +/* { dg-do compile } */ | ||
1245 | +/* { dg-options "-O2 -mfunction-return=thunk-extern -mindirect-branch=thunk -fno-pic" } */ | ||
1246 | + | ||
1247 | +extern void (*bar) (void); | ||
1248 | + | ||
1249 | +int | ||
1250 | +foo (void) | ||
1251 | +{ | ||
1252 | + bar (); | ||
1253 | + return 0; | ||
1254 | +} | ||
1255 | + | ||
1256 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ | ||
1257 | +/* { dg-final { scan-assembler-times {\tpause} 1 } } */ | ||
1258 | +/* { dg-final { scan-assembler-times {\tlfence} 1 } } */ | ||
1259 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1260 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
1261 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ | ||
1262 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
1263 | +/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */ | ||
1264 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ | ||
1265 | +/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */ | ||
1266 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
1267 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c | ||
1268 | new file mode 100644 | ||
1269 | index 0000000..01b0a02 | ||
1270 | --- /dev/null | ||
1271 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c | ||
1272 | @@ -0,0 +1,22 @@ | ||
1273 | +/* { dg-do compile } */ | ||
1274 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ | ||
1275 | + | ||
1276 | +extern void (*bar) (void); | ||
1277 | + | ||
1278 | +int | ||
1279 | +foo (void) | ||
1280 | +{ | ||
1281 | + bar (); | ||
1282 | + return 0; | ||
1283 | +} | ||
1284 | + | ||
1285 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ | ||
1286 | +/* { dg-final { scan-assembler-times {\tpause} 1 } } */ | ||
1287 | +/* { dg-final { scan-assembler-times {\tlfence} 1 } } */ | ||
1288 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1289 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
1290 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
1291 | +/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */ | ||
1292 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ | ||
1293 | +/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */ | ||
1294 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
1295 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c | ||
1296 | new file mode 100644 | ||
1297 | index 0000000..4b497b5 | ||
1298 | --- /dev/null | ||
1299 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c | ||
1300 | @@ -0,0 +1,22 @@ | ||
1301 | +/* { dg-do compile } */ | ||
1302 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ | ||
1303 | + | ||
1304 | +extern void (*bar) (void); | ||
1305 | +extern int foo (void) __attribute__ ((function_return("thunk"))); | ||
1306 | + | ||
1307 | +int | ||
1308 | +foo (void) | ||
1309 | +{ | ||
1310 | + bar (); | ||
1311 | + return 0; | ||
1312 | +} | ||
1313 | + | ||
1314 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ | ||
1315 | +/* { dg-final { scan-assembler-times {\tpause} 2 } } */ | ||
1316 | +/* { dg-final { scan-assembler-times {\tlfence} 2 } } */ | ||
1317 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ | ||
1318 | +/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 3 } } */ | ||
1319 | +/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 3 } } */ | ||
1320 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_indirect_thunk" } } */ | ||
1321 | +/* { dg-final { scan-assembler-not "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ | ||
1322 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
1323 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c | ||
1324 | new file mode 100644 | ||
1325 | index 0000000..4ae4c44 | ||
1326 | --- /dev/null | ||
1327 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c | ||
1328 | @@ -0,0 +1,22 @@ | ||
1329 | +/* { dg-do compile } */ | ||
1330 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ | ||
1331 | + | ||
1332 | +extern void (*bar) (void); | ||
1333 | + | ||
1334 | +__attribute__ ((function_return("thunk-inline"))) | ||
1335 | +int | ||
1336 | +foo (void) | ||
1337 | +{ | ||
1338 | + bar (); | ||
1339 | + return 0; | ||
1340 | +} | ||
1341 | + | ||
1342 | +/* { dg-final { scan-assembler-times {\tpause} 1 } } */ | ||
1343 | +/* { dg-final { scan-assembler-times {\tlfence} 1 } } */ | ||
1344 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ | ||
1345 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1346 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
1347 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ | ||
1348 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
1349 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ | ||
1350 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
1351 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c | ||
1352 | new file mode 100644 | ||
1353 | index 0000000..5b5bc76 | ||
1354 | --- /dev/null | ||
1355 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c | ||
1356 | @@ -0,0 +1,22 @@ | ||
1357 | +/* { dg-do compile } */ | ||
1358 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -fno-pic" } */ | ||
1359 | + | ||
1360 | +extern void (*bar) (void); | ||
1361 | + | ||
1362 | +__attribute__ ((function_return("thunk-extern"), indirect_branch("thunk"))) | ||
1363 | +int | ||
1364 | +foo (void) | ||
1365 | +{ | ||
1366 | + bar (); | ||
1367 | + return 0; | ||
1368 | +} | ||
1369 | + | ||
1370 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ | ||
1371 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1372 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
1373 | +/* { dg-final { scan-assembler-times {\tpause} 1 } } */ | ||
1374 | +/* { dg-final { scan-assembler-times {\tlfence} 1 } } */ | ||
1375 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ | ||
1376 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
1377 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
1378 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
1379 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-16.c b/gcc/testsuite/gcc.target/i386/ret-thunk-16.c | ||
1380 | new file mode 100644 | ||
1381 | index 0000000..a16cad1 | ||
1382 | --- /dev/null | ||
1383 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-16.c | ||
1384 | @@ -0,0 +1,18 @@ | ||
1385 | +/* { dg-do compile } */ | ||
1386 | +/* { dg-options "-O2 -mfunction-return=thunk-inline -mindirect-branch=thunk-extern -fno-pic" } */ | ||
1387 | + | ||
1388 | +extern void (*bar) (void); | ||
1389 | + | ||
1390 | +__attribute__ ((function_return("keep"), indirect_branch("keep"))) | ||
1391 | +int | ||
1392 | +foo (void) | ||
1393 | +{ | ||
1394 | + bar (); | ||
1395 | + return 0; | ||
1396 | +} | ||
1397 | + | ||
1398 | +/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ | ||
1399 | +/* { dg-final { scan-assembler-not "__x86_return_thunk" } } */ | ||
1400 | +/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
1401 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ | ||
1402 | +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ | ||
1403 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-2.c b/gcc/testsuite/gcc.target/i386/ret-thunk-2.c | ||
1404 | new file mode 100644 | ||
1405 | index 0000000..c6659e3 | ||
1406 | --- /dev/null | ||
1407 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-2.c | ||
1408 | @@ -0,0 +1,13 @@ | ||
1409 | +/* { dg-do compile } */ | ||
1410 | +/* { dg-options "-O2 -mfunction-return=thunk-inline" } */ | ||
1411 | + | ||
1412 | +void | ||
1413 | +foo (void) | ||
1414 | +{ | ||
1415 | +} | ||
1416 | + | ||
1417 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1418 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
1419 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
1420 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
1421 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ | ||
1422 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-3.c b/gcc/testsuite/gcc.target/i386/ret-thunk-3.c | ||
1423 | new file mode 100644 | ||
1424 | index 0000000..0f7f388 | ||
1425 | --- /dev/null | ||
1426 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-3.c | ||
1427 | @@ -0,0 +1,12 @@ | ||
1428 | +/* { dg-do compile } */ | ||
1429 | +/* { dg-options "-O2 -mfunction-return=thunk-extern" } */ | ||
1430 | + | ||
1431 | +void | ||
1432 | +foo (void) | ||
1433 | +{ | ||
1434 | +} | ||
1435 | + | ||
1436 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ | ||
1437 | +/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
1438 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ | ||
1439 | +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ | ||
1440 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-4.c b/gcc/testsuite/gcc.target/i386/ret-thunk-4.c | ||
1441 | new file mode 100644 | ||
1442 | index 0000000..9ae37e8 | ||
1443 | --- /dev/null | ||
1444 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-4.c | ||
1445 | @@ -0,0 +1,12 @@ | ||
1446 | +/* { dg-do compile } */ | ||
1447 | +/* { dg-options "-O2 -mfunction-return=keep" } */ | ||
1448 | + | ||
1449 | +void | ||
1450 | +foo (void) | ||
1451 | +{ | ||
1452 | +} | ||
1453 | + | ||
1454 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ | ||
1455 | +/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
1456 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ | ||
1457 | +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ | ||
1458 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-5.c b/gcc/testsuite/gcc.target/i386/ret-thunk-5.c | ||
1459 | new file mode 100644 | ||
1460 | index 0000000..4bd0d2a | ||
1461 | --- /dev/null | ||
1462 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-5.c | ||
1463 | @@ -0,0 +1,15 @@ | ||
1464 | +/* { dg-do compile } */ | ||
1465 | +/* { dg-options "-O2 -mfunction-return=keep" } */ | ||
1466 | + | ||
1467 | +extern void foo (void) __attribute__ ((function_return("thunk"))); | ||
1468 | + | ||
1469 | +void | ||
1470 | +foo (void) | ||
1471 | +{ | ||
1472 | +} | ||
1473 | + | ||
1474 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ | ||
1475 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1476 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
1477 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
1478 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
1479 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-6.c b/gcc/testsuite/gcc.target/i386/ret-thunk-6.c | ||
1480 | new file mode 100644 | ||
1481 | index 0000000..053841f | ||
1482 | --- /dev/null | ||
1483 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-6.c | ||
1484 | @@ -0,0 +1,14 @@ | ||
1485 | +/* { dg-do compile } */ | ||
1486 | +/* { dg-options "-O2 -mfunction-return=keep" } */ | ||
1487 | + | ||
1488 | +__attribute__ ((function_return("thunk-inline"))) | ||
1489 | +void | ||
1490 | +foo (void) | ||
1491 | +{ | ||
1492 | +} | ||
1493 | + | ||
1494 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1495 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
1496 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
1497 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
1498 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ | ||
1499 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-7.c b/gcc/testsuite/gcc.target/i386/ret-thunk-7.c | ||
1500 | new file mode 100644 | ||
1501 | index 0000000..262e678 | ||
1502 | --- /dev/null | ||
1503 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-7.c | ||
1504 | @@ -0,0 +1,13 @@ | ||
1505 | +/* { dg-do compile } */ | ||
1506 | +/* { dg-options "-O2 -mfunction-return=keep" } */ | ||
1507 | + | ||
1508 | +__attribute__ ((function_return("thunk-extern"))) | ||
1509 | +void | ||
1510 | +foo (void) | ||
1511 | +{ | ||
1512 | +} | ||
1513 | + | ||
1514 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ | ||
1515 | +/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
1516 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ | ||
1517 | +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ | ||
1518 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-8.c b/gcc/testsuite/gcc.target/i386/ret-thunk-8.c | ||
1519 | new file mode 100644 | ||
1520 | index 0000000..c1658e9 | ||
1521 | --- /dev/null | ||
1522 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-8.c | ||
1523 | @@ -0,0 +1,14 @@ | ||
1524 | +/* { dg-do compile } */ | ||
1525 | +/* { dg-options "-O2 -mfunction-return=thunk-inline" } */ | ||
1526 | + | ||
1527 | +extern void foo (void) __attribute__ ((function_return("keep"))); | ||
1528 | + | ||
1529 | +void | ||
1530 | +foo (void) | ||
1531 | +{ | ||
1532 | +} | ||
1533 | + | ||
1534 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ | ||
1535 | +/* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
1536 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ | ||
1537 | +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ | ||
1538 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c | ||
1539 | new file mode 100644 | ||
1540 | index 0000000..fa24a1f | ||
1541 | --- /dev/null | ||
1542 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c | ||
1543 | @@ -0,0 +1,24 @@ | ||
1544 | +/* { dg-do compile } */ | ||
1545 | +/* { dg-options "-O2 -mfunction-return=thunk -mindirect-branch=thunk -fno-pic" } */ | ||
1546 | + | ||
1547 | +extern void (*bar) (void); | ||
1548 | + | ||
1549 | +int | ||
1550 | +foo (void) | ||
1551 | +{ | ||
1552 | + bar (); | ||
1553 | + return 0; | ||
1554 | +} | ||
1555 | + | ||
1556 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ | ||
1557 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
1558 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
1559 | +/* { dg-final { scan-assembler "__x86_indirect_thunk:" } } */ | ||
1560 | +/* { dg-final { scan-assembler-times {\tpause} 1 { target { ! x32 } } } } */ | ||
1561 | +/* { dg-final { scan-assembler-times {\tlfence} 1 { target { ! x32 } } } } */ | ||
1562 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ | ||
1563 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
1564 | +/* { dg-final { scan-assembler-times {\tpause} 2 { target { x32 } } } } */ | ||
1565 | +/* { dg-final { scan-assembler-times {\tlfence} 2 { target { x32 } } } } */ | ||
1566 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ | ||
1567 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
1568 | -- | ||
1569 | 2.7.4 | ||
1570 | |||
diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0006-x86-Add-mindirect-branch-register.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0006-x86-Add-mindirect-branch-register.patch new file mode 100644 index 0000000000..ad736913cd --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0006-x86-Add-mindirect-branch-register.patch | |||
@@ -0,0 +1,946 @@ | |||
1 | From 3f1c39fb543884d36e759a6dc196a8e914eb4f73 Mon Sep 17 00:00:00 2001 | ||
2 | From: "H.J. Lu" <hjl.tools@gmail.com> | ||
3 | Date: Sat, 6 Jan 2018 22:29:56 -0800 | ||
4 | Subject: [PATCH 06/12] x86: Add -mindirect-branch-register | ||
5 | |||
6 | Add -mindirect-branch-register to force indirect branch via register. | ||
7 | This is implemented by disabling patterns of indirect branch via memory, | ||
8 | similar to TARGET_X32. | ||
9 | |||
10 | -mindirect-branch= and -mfunction-return= tests are updated with | ||
11 | -mno-indirect-branch-register to avoid false test failures when | ||
12 | -mindirect-branch-register is added to RUNTESTFLAGS for "make check". | ||
13 | |||
14 | gcc/ | ||
15 | |||
16 | Backport from mainline | ||
17 | 2018-01-14 H.J. Lu <hongjiu.lu@intel.com> | ||
18 | |||
19 | * config/i386/constraints.md (Bs): Disallow memory operand for | ||
20 | -mindirect-branch-register. | ||
21 | (Bw): Likewise. | ||
22 | * config/i386/predicates.md (indirect_branch_operand): Likewise. | ||
23 | (GOT_memory_operand): Likewise. | ||
24 | (call_insn_operand): Likewise. | ||
25 | (sibcall_insn_operand): Likewise. | ||
26 | (GOT32_symbol_operand): Likewise. | ||
27 | * config/i386/i386.md (indirect_jump): Call convert_memory_address | ||
28 | for -mindirect-branch-register. | ||
29 | (tablejump): Likewise. | ||
30 | (*sibcall_memory): Likewise. | ||
31 | (*sibcall_value_memory): Likewise. | ||
32 | Disallow peepholes of indirect call and jump via memory for | ||
33 | -mindirect-branch-register. | ||
34 | (*call_pop): Replace m with Bw. | ||
35 | (*call_value_pop): Likewise. | ||
36 | (*sibcall_pop_memory): Replace m with Bs. | ||
37 | * config/i386/i386.opt (mindirect-branch-register): New option. | ||
38 | * doc/invoke.texi: Document -mindirect-branch-register option. | ||
39 | |||
40 | gcc/testsuite/ | ||
41 | |||
42 | Backport from mainline | ||
43 | 2018-01-14 H.J. Lu <hongjiu.lu@intel.com> | ||
44 | |||
45 | * gcc.target/i386/indirect-thunk-1.c (dg-options): Add | ||
46 | -mno-indirect-branch-register. | ||
47 | * gcc.target/i386/indirect-thunk-2.c: Likewise. | ||
48 | * gcc.target/i386/indirect-thunk-3.c: Likewise. | ||
49 | * gcc.target/i386/indirect-thunk-4.c: Likewise. | ||
50 | * gcc.target/i386/indirect-thunk-5.c: Likewise. | ||
51 | * gcc.target/i386/indirect-thunk-6.c: Likewise. | ||
52 | * gcc.target/i386/indirect-thunk-7.c: Likewise. | ||
53 | * gcc.target/i386/indirect-thunk-attr-1.c: Likewise. | ||
54 | * gcc.target/i386/indirect-thunk-attr-2.c: Likewise. | ||
55 | * gcc.target/i386/indirect-thunk-attr-3.c: Likewise. | ||
56 | * gcc.target/i386/indirect-thunk-attr-4.c: Likewise. | ||
57 | * gcc.target/i386/indirect-thunk-attr-5.c: Likewise. | ||
58 | * gcc.target/i386/indirect-thunk-attr-6.c: Likewise. | ||
59 | * gcc.target/i386/indirect-thunk-attr-7.c: Likewise. | ||
60 | * gcc.target/i386/indirect-thunk-bnd-1.c: Likewise. | ||
61 | * gcc.target/i386/indirect-thunk-bnd-2.c: Likewise. | ||
62 | * gcc.target/i386/indirect-thunk-bnd-3.c: Likewise. | ||
63 | * gcc.target/i386/indirect-thunk-bnd-4.c: Likewise. | ||
64 | * gcc.target/i386/indirect-thunk-extern-1.c: Likewise. | ||
65 | * gcc.target/i386/indirect-thunk-extern-2.c: Likewise. | ||
66 | * gcc.target/i386/indirect-thunk-extern-3.c: Likewise. | ||
67 | * gcc.target/i386/indirect-thunk-extern-4.c: Likewise. | ||
68 | * gcc.target/i386/indirect-thunk-extern-5.c: Likewise. | ||
69 | * gcc.target/i386/indirect-thunk-extern-6.c: Likewise. | ||
70 | * gcc.target/i386/indirect-thunk-extern-7.c: Likewise. | ||
71 | * gcc.target/i386/indirect-thunk-inline-1.c: Likewise. | ||
72 | * gcc.target/i386/indirect-thunk-inline-2.c: Likewise. | ||
73 | * gcc.target/i386/indirect-thunk-inline-3.c: Likewise. | ||
74 | * gcc.target/i386/indirect-thunk-inline-4.c: Likewise. | ||
75 | * gcc.target/i386/indirect-thunk-inline-5.c: Likewise. | ||
76 | * gcc.target/i386/indirect-thunk-inline-6.c: Likewise. | ||
77 | * gcc.target/i386/indirect-thunk-inline-7.c: Likewise. | ||
78 | * gcc.target/i386/ret-thunk-10.c: Likewise. | ||
79 | * gcc.target/i386/ret-thunk-11.c: Likewise. | ||
80 | * gcc.target/i386/ret-thunk-12.c: Likewise. | ||
81 | * gcc.target/i386/ret-thunk-13.c: Likewise. | ||
82 | * gcc.target/i386/ret-thunk-14.c: Likewise. | ||
83 | * gcc.target/i386/ret-thunk-15.c: Likewise. | ||
84 | * gcc.target/i386/ret-thunk-9.c: Likewise. | ||
85 | * gcc.target/i386/indirect-thunk-register-1.c: New test. | ||
86 | * gcc.target/i386/indirect-thunk-register-2.c: Likewise. | ||
87 | * gcc.target/i386/indirect-thunk-register-3.c: Likewise. | ||
88 | |||
89 | i386: Rename to ix86_indirect_branch_register | ||
90 | |||
91 | Rename the variable for -mindirect-branch-register to | ||
92 | ix86_indirect_branch_register to match the command-line option name. | ||
93 | |||
94 | Backport from mainline | ||
95 | 2018-01-15 H.J. Lu <hongjiu.lu@intel.com> | ||
96 | |||
97 | * config/i386/constraints.md (Bs): Replace | ||
98 | ix86_indirect_branch_thunk_register with | ||
99 | ix86_indirect_branch_register. | ||
100 | (Bw): Likewise. | ||
101 | * config/i386/i386.md (indirect_jump): Likewise. | ||
102 | (tablejump): Likewise. | ||
103 | (*sibcall_memory): Likewise. | ||
104 | (*sibcall_value_memory): Likewise. | ||
105 | Peepholes of indirect call and jump via memory: Likewise. | ||
106 | * config/i386/i386.opt: Likewise. | ||
107 | * config/i386/predicates.md (indirect_branch_operand): Likewise. | ||
108 | (GOT_memory_operand): Likewise. | ||
109 | (call_insn_operand): Likewise. | ||
110 | (sibcall_insn_operand): Likewise. | ||
111 | (GOT32_symbol_operand): Likewise. | ||
112 | |||
113 | x86: Rewrite ix86_indirect_branch_register logic | ||
114 | |||
115 | Rewrite ix86_indirect_branch_register logic with | ||
116 | |||
117 | (and (not (match_test "ix86_indirect_branch_register")) | ||
118 | (original condition before r256662)) | ||
119 | |||
120 | Backport from mainline | ||
121 | 2018-01-15 H.J. Lu <hongjiu.lu@intel.com> | ||
122 | |||
123 | * config/i386/predicates.md (constant_call_address_operand): | ||
124 | Rewrite ix86_indirect_branch_register logic. | ||
125 | (sibcall_insn_operand): Likewise. | ||
126 | |||
127 | Don't check ix86_indirect_branch_register for GOT operand | ||
128 | |||
129 | Since GOT_memory_operand and GOT32_symbol_operand are simple pattern | ||
130 | matches, don't check ix86_indirect_branch_register here. If needed, | ||
131 | -mindirect-branch= will convert indirect branch via GOT slot to a call | ||
132 | and return thunk. | ||
133 | |||
134 | Backport from mainline | ||
135 | 2018-01-15 H.J. Lu <hongjiu.lu@intel.com> | ||
136 | |||
137 | * config/i386/constraints.md (Bs): Update | ||
138 | ix86_indirect_branch_register check. Don't check | ||
139 | ix86_indirect_branch_register with GOT_memory_operand. | ||
140 | (Bw): Likewise. | ||
141 | * config/i386/predicates.md (GOT_memory_operand): Don't check | ||
142 | ix86_indirect_branch_register here. | ||
143 | (GOT32_symbol_operand): Likewise. | ||
144 | |||
145 | i386: Rewrite indirect_branch_operand logic | ||
146 | |||
147 | Backport from mainline | ||
148 | 2018-01-15 H.J. Lu <hongjiu.lu@intel.com> | ||
149 | |||
150 | * config/i386/predicates.md (indirect_branch_operand): Rewrite | ||
151 | ix86_indirect_branch_register logic. | ||
152 | |||
153 | Upstream-Status: Pending | ||
154 | |||
155 | Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> | ||
156 | |||
157 | --- | ||
158 | gcc/config/i386/constraints.md | 6 ++-- | ||
159 | gcc/config/i386/i386.md | 34 ++++++++++++++-------- | ||
160 | gcc/config/i386/i386.opt | 4 +++ | ||
161 | gcc/config/i386/predicates.md | 21 +++++++------ | ||
162 | gcc/doc/invoke.texi | 6 +++- | ||
163 | gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 2 +- | ||
164 | gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 2 +- | ||
165 | gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 2 +- | ||
166 | gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 2 +- | ||
167 | gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 2 +- | ||
168 | gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 2 +- | ||
169 | gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 2 +- | ||
170 | .../gcc.target/i386/indirect-thunk-attr-1.c | 2 +- | ||
171 | .../gcc.target/i386/indirect-thunk-attr-2.c | 2 +- | ||
172 | .../gcc.target/i386/indirect-thunk-attr-3.c | 2 +- | ||
173 | .../gcc.target/i386/indirect-thunk-attr-4.c | 2 +- | ||
174 | .../gcc.target/i386/indirect-thunk-attr-5.c | 2 +- | ||
175 | .../gcc.target/i386/indirect-thunk-attr-6.c | 2 +- | ||
176 | .../gcc.target/i386/indirect-thunk-attr-7.c | 2 +- | ||
177 | .../gcc.target/i386/indirect-thunk-bnd-1.c | 2 +- | ||
178 | .../gcc.target/i386/indirect-thunk-bnd-2.c | 2 +- | ||
179 | .../gcc.target/i386/indirect-thunk-bnd-3.c | 2 +- | ||
180 | .../gcc.target/i386/indirect-thunk-bnd-4.c | 2 +- | ||
181 | .../gcc.target/i386/indirect-thunk-extern-1.c | 2 +- | ||
182 | .../gcc.target/i386/indirect-thunk-extern-2.c | 2 +- | ||
183 | .../gcc.target/i386/indirect-thunk-extern-3.c | 2 +- | ||
184 | .../gcc.target/i386/indirect-thunk-extern-4.c | 2 +- | ||
185 | .../gcc.target/i386/indirect-thunk-extern-5.c | 2 +- | ||
186 | .../gcc.target/i386/indirect-thunk-extern-6.c | 2 +- | ||
187 | .../gcc.target/i386/indirect-thunk-extern-7.c | 2 +- | ||
188 | .../gcc.target/i386/indirect-thunk-inline-1.c | 2 +- | ||
189 | .../gcc.target/i386/indirect-thunk-inline-2.c | 2 +- | ||
190 | .../gcc.target/i386/indirect-thunk-inline-3.c | 2 +- | ||
191 | .../gcc.target/i386/indirect-thunk-inline-4.c | 2 +- | ||
192 | .../gcc.target/i386/indirect-thunk-inline-5.c | 2 +- | ||
193 | .../gcc.target/i386/indirect-thunk-inline-6.c | 2 +- | ||
194 | .../gcc.target/i386/indirect-thunk-inline-7.c | 2 +- | ||
195 | .../gcc.target/i386/indirect-thunk-register-1.c | 22 ++++++++++++++ | ||
196 | .../gcc.target/i386/indirect-thunk-register-2.c | 20 +++++++++++++ | ||
197 | .../gcc.target/i386/indirect-thunk-register-3.c | 19 ++++++++++++ | ||
198 | gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 2 +- | ||
199 | gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 2 +- | ||
200 | gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 2 +- | ||
201 | gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 2 +- | ||
202 | gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 2 +- | ||
203 | gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 2 +- | ||
204 | gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 2 +- | ||
205 | 47 files changed, 147 insertions(+), 63 deletions(-) | ||
206 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c | ||
207 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c | ||
208 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c | ||
209 | |||
210 | diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md | ||
211 | index 1a4c701..9204c8e 100644 | ||
212 | --- a/gcc/config/i386/constraints.md | ||
213 | +++ b/gcc/config/i386/constraints.md | ||
214 | @@ -172,14 +172,16 @@ | ||
215 | |||
216 | (define_constraint "Bs" | ||
217 | "@internal Sibcall memory operand." | ||
218 | - (ior (and (not (match_test "TARGET_X32")) | ||
219 | + (ior (and (not (match_test "ix86_indirect_branch_register")) | ||
220 | + (not (match_test "TARGET_X32")) | ||
221 | (match_operand 0 "sibcall_memory_operand")) | ||
222 | (and (match_test "TARGET_X32 && Pmode == DImode") | ||
223 | (match_operand 0 "GOT_memory_operand")))) | ||
224 | |||
225 | (define_constraint "Bw" | ||
226 | "@internal Call memory operand." | ||
227 | - (ior (and (not (match_test "TARGET_X32")) | ||
228 | + (ior (and (not (match_test "ix86_indirect_branch_register")) | ||
229 | + (not (match_test "TARGET_X32")) | ||
230 | (match_operand 0 "memory_operand")) | ||
231 | (and (match_test "TARGET_X32 && Pmode == DImode") | ||
232 | (match_operand 0 "GOT_memory_operand")))) | ||
233 | diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md | ||
234 | index 2da671e..05a88ff 100644 | ||
235 | --- a/gcc/config/i386/i386.md | ||
236 | +++ b/gcc/config/i386/i386.md | ||
237 | @@ -11805,7 +11805,7 @@ | ||
238 | [(set (pc) (match_operand 0 "indirect_branch_operand"))] | ||
239 | "" | ||
240 | { | ||
241 | - if (TARGET_X32) | ||
242 | + if (TARGET_X32 || ix86_indirect_branch_register) | ||
243 | operands[0] = convert_memory_address (word_mode, operands[0]); | ||
244 | cfun->machine->has_local_indirect_jump = true; | ||
245 | }) | ||
246 | @@ -11859,7 +11859,7 @@ | ||
247 | OPTAB_DIRECT); | ||
248 | } | ||
249 | |||
250 | - if (TARGET_X32) | ||
251 | + if (TARGET_X32 || ix86_indirect_branch_register) | ||
252 | operands[0] = convert_memory_address (word_mode, operands[0]); | ||
253 | cfun->machine->has_local_indirect_jump = true; | ||
254 | }) | ||
255 | @@ -12048,7 +12048,7 @@ | ||
256 | [(call (mem:QI (match_operand:W 0 "memory_operand" "m")) | ||
257 | (match_operand 1)) | ||
258 | (unspec [(const_int 0)] UNSPEC_PEEPSIB)] | ||
259 | - "!TARGET_X32" | ||
260 | + "!TARGET_X32 && !ix86_indirect_branch_register" | ||
261 | "* return ix86_output_call_insn (insn, operands[0]);" | ||
262 | [(set_attr "type" "call")]) | ||
263 | |||
264 | @@ -12057,7 +12057,9 @@ | ||
265 | (match_operand:W 1 "memory_operand")) | ||
266 | (call (mem:QI (match_dup 0)) | ||
267 | (match_operand 3))] | ||
268 | - "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1)) | ||
269 | + "!TARGET_X32 | ||
270 | + && !ix86_indirect_branch_register | ||
271 | + && SIBLING_CALL_P (peep2_next_insn (1)) | ||
272 | && !reg_mentioned_p (operands[0], | ||
273 | CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" | ||
274 | [(parallel [(call (mem:QI (match_dup 1)) | ||
275 | @@ -12070,7 +12072,9 @@ | ||
276 | (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) | ||
277 | (call (mem:QI (match_dup 0)) | ||
278 | (match_operand 3))] | ||
279 | - "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2)) | ||
280 | + "!TARGET_X32 | ||
281 | + && !ix86_indirect_branch_register | ||
282 | + && SIBLING_CALL_P (peep2_next_insn (2)) | ||
283 | && !reg_mentioned_p (operands[0], | ||
284 | CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" | ||
285 | [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) | ||
286 | @@ -12092,7 +12096,7 @@ | ||
287 | }) | ||
288 | |||
289 | (define_insn "*call_pop" | ||
290 | - [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz")) | ||
291 | + [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz")) | ||
292 | (match_operand 1)) | ||
293 | (set (reg:SI SP_REG) | ||
294 | (plus:SI (reg:SI SP_REG) | ||
295 | @@ -12112,7 +12116,7 @@ | ||
296 | [(set_attr "type" "call")]) | ||
297 | |||
298 | (define_insn "*sibcall_pop_memory" | ||
299 | - [(call (mem:QI (match_operand:SI 0 "memory_operand" "m")) | ||
300 | + [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs")) | ||
301 | (match_operand 1)) | ||
302 | (set (reg:SI SP_REG) | ||
303 | (plus:SI (reg:SI SP_REG) | ||
304 | @@ -12166,7 +12170,9 @@ | ||
305 | [(set (match_operand:W 0 "register_operand") | ||
306 | (match_operand:W 1 "memory_operand")) | ||
307 | (set (pc) (match_dup 0))] | ||
308 | - "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])" | ||
309 | + "!TARGET_X32 | ||
310 | + && !ix86_indirect_branch_register | ||
311 | + && peep2_reg_dead_p (2, operands[0])" | ||
312 | [(set (pc) (match_dup 1))]) | ||
313 | |||
314 | ;; Call subroutine, returning value in operand 0 | ||
315 | @@ -12244,7 +12250,7 @@ | ||
316 | (call (mem:QI (match_operand:W 1 "memory_operand" "m")) | ||
317 | (match_operand 2))) | ||
318 | (unspec [(const_int 0)] UNSPEC_PEEPSIB)] | ||
319 | - "!TARGET_X32" | ||
320 | + "!TARGET_X32 && !ix86_indirect_branch_register" | ||
321 | "* return ix86_output_call_insn (insn, operands[1]);" | ||
322 | [(set_attr "type" "callv")]) | ||
323 | |||
324 | @@ -12254,7 +12260,9 @@ | ||
325 | (set (match_operand 2) | ||
326 | (call (mem:QI (match_dup 0)) | ||
327 | (match_operand 3)))] | ||
328 | - "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1)) | ||
329 | + "!TARGET_X32 | ||
330 | + && !ix86_indirect_branch_register | ||
331 | + && SIBLING_CALL_P (peep2_next_insn (1)) | ||
332 | && !reg_mentioned_p (operands[0], | ||
333 | CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" | ||
334 | [(parallel [(set (match_dup 2) | ||
335 | @@ -12269,7 +12277,9 @@ | ||
336 | (set (match_operand 2) | ||
337 | (call (mem:QI (match_dup 0)) | ||
338 | (match_operand 3)))] | ||
339 | - "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2)) | ||
340 | + "!TARGET_X32 | ||
341 | + && !ix86_indirect_branch_register | ||
342 | + && SIBLING_CALL_P (peep2_next_insn (2)) | ||
343 | && !reg_mentioned_p (operands[0], | ||
344 | CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" | ||
345 | [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) | ||
346 | @@ -12294,7 +12304,7 @@ | ||
347 | |||
348 | (define_insn "*call_value_pop" | ||
349 | [(set (match_operand 0) | ||
350 | - (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz")) | ||
351 | + (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz")) | ||
352 | (match_operand 2))) | ||
353 | (set (reg:SI SP_REG) | ||
354 | (plus:SI (reg:SI SP_REG) | ||
355 | diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt | ||
356 | index ad5916f..a97f84f 100644 | ||
357 | --- a/gcc/config/i386/i386.opt | ||
358 | +++ b/gcc/config/i386/i386.opt | ||
359 | @@ -921,3 +921,7 @@ Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline) | ||
360 | |||
361 | EnumValue | ||
362 | Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern) | ||
363 | + | ||
364 | +mindirect-branch-register | ||
365 | +Target Report Var(ix86_indirect_branch_register) Init(0) | ||
366 | +Force indirect call and jump via register. | ||
367 | diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md | ||
368 | index 93dda7b..d1f0a7d 100644 | ||
369 | --- a/gcc/config/i386/predicates.md | ||
370 | +++ b/gcc/config/i386/predicates.md | ||
371 | @@ -593,7 +593,8 @@ | ||
372 | ;; Test for a valid operand for indirect branch. | ||
373 | (define_predicate "indirect_branch_operand" | ||
374 | (ior (match_operand 0 "register_operand") | ||
375 | - (and (not (match_test "TARGET_X32")) | ||
376 | + (and (not (match_test "ix86_indirect_branch_register")) | ||
377 | + (not (match_test "TARGET_X32")) | ||
378 | (match_operand 0 "memory_operand")))) | ||
379 | |||
380 | ;; Return true if OP is a memory operands that can be used in sibcalls. | ||
381 | @@ -636,20 +637,22 @@ | ||
382 | (ior (match_test "constant_call_address_operand | ||
383 | (op, mode == VOIDmode ? mode : Pmode)") | ||
384 | (match_operand 0 "call_register_no_elim_operand") | ||
385 | - (ior (and (not (match_test "TARGET_X32")) | ||
386 | - (match_operand 0 "memory_operand")) | ||
387 | - (and (match_test "TARGET_X32 && Pmode == DImode") | ||
388 | - (match_operand 0 "GOT_memory_operand"))))) | ||
389 | + (and (not (match_test "ix86_indirect_branch_register")) | ||
390 | + (ior (and (not (match_test "TARGET_X32")) | ||
391 | + (match_operand 0 "memory_operand")) | ||
392 | + (and (match_test "TARGET_X32 && Pmode == DImode") | ||
393 | + (match_operand 0 "GOT_memory_operand")))))) | ||
394 | |||
395 | ;; Similarly, but for tail calls, in which we cannot allow memory references. | ||
396 | (define_special_predicate "sibcall_insn_operand" | ||
397 | (ior (match_test "constant_call_address_operand | ||
398 | (op, mode == VOIDmode ? mode : Pmode)") | ||
399 | (match_operand 0 "register_no_elim_operand") | ||
400 | - (ior (and (not (match_test "TARGET_X32")) | ||
401 | - (match_operand 0 "sibcall_memory_operand")) | ||
402 | - (and (match_test "TARGET_X32 && Pmode == DImode") | ||
403 | - (match_operand 0 "GOT_memory_operand"))))) | ||
404 | + (and (not (match_test "ix86_indirect_branch_register")) | ||
405 | + (ior (and (not (match_test "TARGET_X32")) | ||
406 | + (match_operand 0 "sibcall_memory_operand")) | ||
407 | + (and (match_test "TARGET_X32 && Pmode == DImode") | ||
408 | + (match_operand 0 "GOT_memory_operand")))))) | ||
409 | |||
410 | ;; Return true if OP is a 32-bit GOT symbol operand. | ||
411 | (define_predicate "GOT32_symbol_operand" | ||
412 | diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi | ||
413 | index fa63dc5..ad9f295 100644 | ||
414 | --- a/gcc/doc/invoke.texi | ||
415 | +++ b/gcc/doc/invoke.texi | ||
416 | @@ -1170,7 +1170,7 @@ See RS/6000 and PowerPC Options. | ||
417 | -mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol | ||
418 | -malign-data=@var{type} -mstack-protector-guard=@var{guard} @gol | ||
419 | -mmitigate-rop -mindirect-branch=@var{choice} @gol | ||
420 | --mfunction-return=@var{choice}} | ||
421 | +-mfunction-return=@var{choice} -mindirect-branch-register} | ||
422 | |||
423 | @emph{x86 Windows Options} | ||
424 | @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol | ||
425 | @@ -24241,6 +24241,10 @@ object file. You can control this behavior for a specific function by | ||
426 | using the function attribute @code{function_return}. | ||
427 | @xref{Function Attributes}. | ||
428 | |||
429 | +@item -mindirect-branch-register | ||
430 | +@opindex -mindirect-branch-register | ||
431 | +Force indirect call and jump via register. | ||
432 | + | ||
433 | @end table | ||
434 | |||
435 | These @samp{-m} switches are supported in addition to the above | ||
436 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | ||
437 | index e365ef5..60d0988 100644 | ||
438 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | ||
439 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | ||
440 | @@ -1,5 +1,5 @@ | ||
441 | /* { dg-do compile } */ | ||
442 | -/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ | ||
443 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ | ||
444 | |||
445 | typedef void (*dispatch_t)(long offset); | ||
446 | |||
447 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | ||
448 | index 05a51ad..aac7516 100644 | ||
449 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | ||
450 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | ||
451 | @@ -1,5 +1,5 @@ | ||
452 | /* { dg-do compile } */ | ||
453 | -/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ | ||
454 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ | ||
455 | |||
456 | typedef void (*dispatch_t)(long offset); | ||
457 | |||
458 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | ||
459 | index 3c0d4c3..9e24a38 100644 | ||
460 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | ||
461 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | ||
462 | @@ -1,5 +1,5 @@ | ||
463 | /* { dg-do compile } */ | ||
464 | -/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ | ||
465 | +/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ | ||
466 | |||
467 | typedef void (*dispatch_t)(long offset); | ||
468 | |||
469 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | ||
470 | index 14d4ef6..127b5d9 100644 | ||
471 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | ||
472 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | ||
473 | @@ -1,5 +1,5 @@ | ||
474 | /* { dg-do compile } */ | ||
475 | -/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ | ||
476 | +/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ | ||
477 | |||
478 | typedef void (*dispatch_t)(long offset); | ||
479 | |||
480 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | ||
481 | index b4836c3..fcaa18d 100644 | ||
482 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | ||
483 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | ||
484 | @@ -1,5 +1,5 @@ | ||
485 | /* { dg-do compile { target *-*-linux* } } */ | ||
486 | -/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ | ||
487 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ | ||
488 | |||
489 | extern void bar (void); | ||
490 | |||
491 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | ||
492 | index 1f06bd1..e464928 100644 | ||
493 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | ||
494 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | ||
495 | @@ -1,5 +1,5 @@ | ||
496 | /* { dg-do compile { target *-*-linux* } } */ | ||
497 | -/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ | ||
498 | +/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk" } */ | ||
499 | |||
500 | extern void bar (void); | ||
501 | |||
502 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | ||
503 | index bc6b47a..17c2d0f 100644 | ||
504 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | ||
505 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | ||
506 | @@ -1,5 +1,5 @@ | ||
507 | /* { dg-do compile } */ | ||
508 | -/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ | ||
509 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ | ||
510 | |||
511 | void func0 (void); | ||
512 | void func1 (void); | ||
513 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | ||
514 | index 2257be3..9194ccf 100644 | ||
515 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | ||
516 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | ||
517 | @@ -1,5 +1,5 @@ | ||
518 | /* { dg-do compile } */ | ||
519 | -/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ | ||
520 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ | ||
521 | |||
522 | typedef void (*dispatch_t)(long offset); | ||
523 | |||
524 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | ||
525 | index e9cfdc5..e51f261 100644 | ||
526 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | ||
527 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | ||
528 | @@ -1,5 +1,5 @@ | ||
529 | /* { dg-do compile } */ | ||
530 | -/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ | ||
531 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ | ||
532 | |||
533 | typedef void (*dispatch_t)(long offset); | ||
534 | |||
535 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | ||
536 | index f938db0..4aeec18 100644 | ||
537 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | ||
538 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | ||
539 | @@ -1,5 +1,5 @@ | ||
540 | /* { dg-do compile } */ | ||
541 | -/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ | ||
542 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ | ||
543 | |||
544 | typedef void (*dispatch_t)(long offset); | ||
545 | |||
546 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | ||
547 | index 4e58599..ac0e599 100644 | ||
548 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | ||
549 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | ||
550 | @@ -1,5 +1,5 @@ | ||
551 | /* { dg-do compile } */ | ||
552 | -/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ | ||
553 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ | ||
554 | |||
555 | typedef void (*dispatch_t)(long offset); | ||
556 | |||
557 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | ||
558 | index b8d5024..573cf1e 100644 | ||
559 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | ||
560 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | ||
561 | @@ -1,5 +1,5 @@ | ||
562 | /* { dg-do compile } */ | ||
563 | -/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ | ||
564 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ | ||
565 | |||
566 | typedef void (*dispatch_t)(long offset); | ||
567 | |||
568 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | ||
569 | index 455adab..b2b37fc 100644 | ||
570 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | ||
571 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | ||
572 | @@ -1,5 +1,5 @@ | ||
573 | /* { dg-do compile } */ | ||
574 | -/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ | ||
575 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ | ||
576 | |||
577 | typedef void (*dispatch_t)(long offset); | ||
578 | |||
579 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | ||
580 | index 4595b84..4a43e19 100644 | ||
581 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | ||
582 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | ||
583 | @@ -1,5 +1,5 @@ | ||
584 | /* { dg-do compile } */ | ||
585 | -/* { dg-options "-O2 -mfunction-return=keep -fno-pic" } */ | ||
586 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */ | ||
587 | |||
588 | void func0 (void); | ||
589 | void func1 (void); | ||
590 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | ||
591 | index 5e3e118..ac84ab6 100644 | ||
592 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | ||
593 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | ||
594 | @@ -1,5 +1,5 @@ | ||
595 | /* { dg-do compile { target { ! x32 } } } */ | ||
596 | -/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ | ||
597 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ | ||
598 | |||
599 | void (*dispatch) (char *); | ||
600 | char buf[10]; | ||
601 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | ||
602 | index 2801aa4..ce655e8 100644 | ||
603 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | ||
604 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | ||
605 | @@ -1,5 +1,5 @@ | ||
606 | /* { dg-do compile { target { ! x32 } } } */ | ||
607 | -/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ | ||
608 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ | ||
609 | |||
610 | void (*dispatch) (char *); | ||
611 | char buf[10]; | ||
612 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | ||
613 | index 70b4fb3..d34485a 100644 | ||
614 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | ||
615 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | ||
616 | @@ -1,5 +1,5 @@ | ||
617 | /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ | ||
618 | -/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ | ||
619 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ | ||
620 | |||
621 | void bar (char *); | ||
622 | char buf[10]; | ||
623 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | ||
624 | index 3baf03e..0e19830 100644 | ||
625 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | ||
626 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | ||
627 | @@ -1,5 +1,5 @@ | ||
628 | /* { dg-do compile { target { *-*-linux* && { ! x32 } } } } */ | ||
629 | -/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ | ||
630 | +/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fcheck-pointer-bounds -mmpx -fpic -fno-plt" } */ | ||
631 | |||
632 | void bar (char *); | ||
633 | char buf[10]; | ||
634 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | ||
635 | index edeb264..579441f 100644 | ||
636 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | ||
637 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | ||
638 | @@ -1,5 +1,5 @@ | ||
639 | /* { dg-do compile } */ | ||
640 | -/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ | ||
641 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ | ||
642 | |||
643 | typedef void (*dispatch_t)(long offset); | ||
644 | |||
645 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | ||
646 | index 1d00413..c92e6f2 100644 | ||
647 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | ||
648 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | ||
649 | @@ -1,5 +1,5 @@ | ||
650 | /* { dg-do compile } */ | ||
651 | -/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ | ||
652 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ | ||
653 | |||
654 | typedef void (*dispatch_t)(long offset); | ||
655 | |||
656 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | ||
657 | index 06ebf1c..d9964c2 100644 | ||
658 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | ||
659 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | ||
660 | @@ -1,5 +1,5 @@ | ||
661 | /* { dg-do compile } */ | ||
662 | -/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ | ||
663 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ | ||
664 | |||
665 | typedef void (*dispatch_t)(long offset); | ||
666 | |||
667 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | ||
668 | index 1c8f944..d4dca4d 100644 | ||
669 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | ||
670 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | ||
671 | @@ -1,5 +1,5 @@ | ||
672 | /* { dg-do compile } */ | ||
673 | -/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ | ||
674 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ | ||
675 | |||
676 | typedef void (*dispatch_t)(long offset); | ||
677 | |||
678 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | ||
679 | index 21740ac..5c07e02 100644 | ||
680 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | ||
681 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | ||
682 | @@ -1,5 +1,5 @@ | ||
683 | /* { dg-do compile { target *-*-linux* } } */ | ||
684 | -/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ | ||
685 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ | ||
686 | |||
687 | extern void bar (void); | ||
688 | |||
689 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | ||
690 | index a77c1f4..3eb4406 100644 | ||
691 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | ||
692 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | ||
693 | @@ -1,5 +1,5 @@ | ||
694 | /* { dg-do compile { target *-*-linux* } } */ | ||
695 | -/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ | ||
696 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-extern" } */ | ||
697 | |||
698 | extern void bar (void); | ||
699 | |||
700 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | ||
701 | index 86e9fd1..aece938 100644 | ||
702 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | ||
703 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | ||
704 | @@ -1,5 +1,5 @@ | ||
705 | /* { dg-do compile } */ | ||
706 | -/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ | ||
707 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ | ||
708 | |||
709 | void func0 (void); | ||
710 | void func1 (void); | ||
711 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | ||
712 | index 3ecde87..3aba5e8 100644 | ||
713 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | ||
714 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | ||
715 | @@ -1,5 +1,5 @@ | ||
716 | /* { dg-do compile } */ | ||
717 | -/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ | ||
718 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ | ||
719 | |||
720 | typedef void (*dispatch_t)(long offset); | ||
721 | |||
722 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | ||
723 | index df32a19..0f0181d 100644 | ||
724 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | ||
725 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | ||
726 | @@ -1,5 +1,5 @@ | ||
727 | /* { dg-do compile } */ | ||
728 | -/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ | ||
729 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ | ||
730 | |||
731 | typedef void (*dispatch_t)(long offset); | ||
732 | |||
733 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | ||
734 | index 9540996..2eef6f3 100644 | ||
735 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | ||
736 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | ||
737 | @@ -1,5 +1,5 @@ | ||
738 | /* { dg-do compile } */ | ||
739 | -/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ | ||
740 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ | ||
741 | |||
742 | typedef void (*dispatch_t)(long offset); | ||
743 | |||
744 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | ||
745 | index f3db6e2..e825a10 100644 | ||
746 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | ||
747 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | ||
748 | @@ -1,5 +1,5 @@ | ||
749 | /* { dg-do compile } */ | ||
750 | -/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ | ||
751 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ | ||
752 | |||
753 | typedef void (*dispatch_t)(long offset); | ||
754 | |||
755 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | ||
756 | index 0f687c3..c6d77e1 100644 | ||
757 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | ||
758 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | ||
759 | @@ -1,5 +1,5 @@ | ||
760 | /* { dg-do compile { target *-*-linux* } } */ | ||
761 | -/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ | ||
762 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ | ||
763 | |||
764 | extern void bar (void); | ||
765 | |||
766 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | ||
767 | index b27c6fc..6454827 100644 | ||
768 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | ||
769 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | ||
770 | @@ -1,5 +1,5 @@ | ||
771 | /* { dg-do compile { target *-*-linux* } } */ | ||
772 | -/* { dg-options "-O2 -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ | ||
773 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fpic -fno-plt -mindirect-branch=thunk-inline" } */ | ||
774 | |||
775 | extern void bar (void); | ||
776 | |||
777 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | ||
778 | index 764a375..c67066c 100644 | ||
779 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | ||
780 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | ||
781 | @@ -1,5 +1,5 @@ | ||
782 | /* { dg-do compile } */ | ||
783 | -/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ | ||
784 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ | ||
785 | |||
786 | void func0 (void); | ||
787 | void func1 (void); | ||
788 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c | ||
789 | new file mode 100644 | ||
790 | index 0000000..7d396a3 | ||
791 | --- /dev/null | ||
792 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-1.c | ||
793 | @@ -0,0 +1,22 @@ | ||
794 | +/* { dg-do compile } */ | ||
795 | +/* { dg-options "-O2 -mindirect-branch=thunk -mindirect-branch-register -fno-pic" } */ | ||
796 | + | ||
797 | +typedef void (*dispatch_t)(long offset); | ||
798 | + | ||
799 | +dispatch_t dispatch; | ||
800 | + | ||
801 | +void | ||
802 | +male_indirect_jump (long offset) | ||
803 | +{ | ||
804 | + dispatch(offset); | ||
805 | +} | ||
806 | + | ||
807 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
808 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
809 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
810 | +/* { dg-final { scan-assembler "mov\[ \t\](%eax|%rax), \\((%esp|%rsp)\\)" } } */ | ||
811 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
812 | +/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */ | ||
813 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ | ||
814 | +/* { dg-final { scan-assembler-not "__x86_indirect_thunk\n" } } */ | ||
815 | +/* { dg-final { scan-assembler-not "__x86_indirect_thunk_bnd\n" } } */ | ||
816 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c | ||
817 | new file mode 100644 | ||
818 | index 0000000..e7e616b | ||
819 | --- /dev/null | ||
820 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-2.c | ||
821 | @@ -0,0 +1,20 @@ | ||
822 | +/* { dg-do compile } */ | ||
823 | +/* { dg-options "-O2 -mindirect-branch=thunk-inline -mindirect-branch-register -fno-pic" } */ | ||
824 | + | ||
825 | +typedef void (*dispatch_t)(long offset); | ||
826 | + | ||
827 | +dispatch_t dispatch; | ||
828 | + | ||
829 | +void | ||
830 | +male_indirect_jump (long offset) | ||
831 | +{ | ||
832 | + dispatch(offset); | ||
833 | +} | ||
834 | + | ||
835 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
836 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
837 | +/* { dg-final { scan-assembler "mov\[ \t\](%eax|%rax), \\((%esp|%rsp)\\)" } } */ | ||
838 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
839 | +/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */ | ||
840 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ | ||
841 | +/* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ | ||
842 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c | ||
843 | new file mode 100644 | ||
844 | index 0000000..5320e92 | ||
845 | --- /dev/null | ||
846 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-3.c | ||
847 | @@ -0,0 +1,19 @@ | ||
848 | +/* { dg-do compile } */ | ||
849 | +/* { dg-options "-O2 -mindirect-branch=thunk-extern -mindirect-branch-register -fno-pic" } */ | ||
850 | + | ||
851 | +typedef void (*dispatch_t)(long offset); | ||
852 | + | ||
853 | +dispatch_t dispatch; | ||
854 | + | ||
855 | +void | ||
856 | +male_indirect_jump (long offset) | ||
857 | +{ | ||
858 | + dispatch(offset); | ||
859 | +} | ||
860 | + | ||
861 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
862 | +/* { dg-final { scan-assembler-not "push(?:l|q)\[ \t\]*_?dispatch" } } */ | ||
863 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ | ||
864 | +/* { dg-final { scan-assembler-not {\t(pause|pause|nop)} } } */ | ||
865 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ | ||
866 | +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ | ||
867 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c | ||
868 | index 3a6727b..e6fea84 100644 | ||
869 | --- a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c | ||
870 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c | ||
871 | @@ -1,5 +1,5 @@ | ||
872 | /* { dg-do compile } */ | ||
873 | -/* { dg-options "-O2 -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */ | ||
874 | +/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=thunk-inline -mindirect-branch=thunk -fno-pic" } */ | ||
875 | |||
876 | extern void (*bar) (void); | ||
877 | |||
878 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c | ||
879 | index b8f6818..e239ec4 100644 | ||
880 | --- a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c | ||
881 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c | ||
882 | @@ -1,5 +1,5 @@ | ||
883 | /* { dg-do compile } */ | ||
884 | -/* { dg-options "-O2 -mfunction-return=thunk-extern -mindirect-branch=thunk -fno-pic" } */ | ||
885 | +/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=thunk-extern -mindirect-branch=thunk -fno-pic" } */ | ||
886 | |||
887 | extern void (*bar) (void); | ||
888 | |||
889 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c | ||
890 | index 01b0a02..fa31813 100644 | ||
891 | --- a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c | ||
892 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c | ||
893 | @@ -1,5 +1,5 @@ | ||
894 | /* { dg-do compile } */ | ||
895 | -/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ | ||
896 | +/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk -fno-pic" } */ | ||
897 | |||
898 | extern void (*bar) (void); | ||
899 | |||
900 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c | ||
901 | index 4b497b5..fd5b41f 100644 | ||
902 | --- a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c | ||
903 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c | ||
904 | @@ -1,5 +1,5 @@ | ||
905 | /* { dg-do compile } */ | ||
906 | -/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ | ||
907 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-inline -fno-pic" } */ | ||
908 | |||
909 | extern void (*bar) (void); | ||
910 | extern int foo (void) __attribute__ ((function_return("thunk"))); | ||
911 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c | ||
912 | index 4ae4c44..d606373 100644 | ||
913 | --- a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c | ||
914 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c | ||
915 | @@ -1,5 +1,5 @@ | ||
916 | /* { dg-do compile } */ | ||
917 | -/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ | ||
918 | +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */ | ||
919 | |||
920 | extern void (*bar) (void); | ||
921 | |||
922 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c | ||
923 | index 5b5bc76..75e45e2 100644 | ||
924 | --- a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c | ||
925 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c | ||
926 | @@ -1,5 +1,5 @@ | ||
927 | /* { dg-do compile } */ | ||
928 | -/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -fno-pic" } */ | ||
929 | +/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=keep -fno-pic" } */ | ||
930 | |||
931 | extern void (*bar) (void); | ||
932 | |||
933 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c | ||
934 | index fa24a1f..d1db41c 100644 | ||
935 | --- a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c | ||
936 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c | ||
937 | @@ -1,5 +1,5 @@ | ||
938 | /* { dg-do compile } */ | ||
939 | -/* { dg-options "-O2 -mfunction-return=thunk -mindirect-branch=thunk -fno-pic" } */ | ||
940 | +/* { dg-options "-O2 -mno-indirect-branch-register -mno-indirect-branch-register -mfunction-return=thunk -mindirect-branch=thunk -fno-pic" } */ | ||
941 | |||
942 | extern void (*bar) (void); | ||
943 | |||
944 | -- | ||
945 | 2.7.4 | ||
946 | |||
diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0007-x86-Add-V-register-operand-modifier.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0007-x86-Add-V-register-operand-modifier.patch new file mode 100644 index 0000000000..cec84fefb2 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0007-x86-Add-V-register-operand-modifier.patch | |||
@@ -0,0 +1,139 @@ | |||
1 | From 8f0efd692eb8db06d6c00b759c872bd2170b7f7b Mon Sep 17 00:00:00 2001 | ||
2 | From: "H.J. Lu" <hjl.tools@gmail.com> | ||
3 | Date: Sat, 6 Jan 2018 22:29:56 -0800 | ||
4 | Subject: [PATCH 07/12] x86: Add 'V' register operand modifier | ||
5 | |||
6 | Add 'V', a special modifier which prints the name of the full integer | ||
7 | register without '%'. For | ||
8 | |||
9 | extern void (*func_p) (void); | ||
10 | |||
11 | void | ||
12 | foo (void) | ||
13 | { | ||
14 | asm ("call __x86_indirect_thunk_%V0" : : "a" (func_p)); | ||
15 | } | ||
16 | |||
17 | it generates: | ||
18 | |||
19 | foo: | ||
20 | movq func_p(%rip), %rax | ||
21 | call __x86_indirect_thunk_rax | ||
22 | ret | ||
23 | |||
24 | gcc/ | ||
25 | |||
26 | Backport from mainline | ||
27 | 2018-01-14 H.J. Lu <hongjiu.lu@intel.com> | ||
28 | |||
29 | * config/i386/i386.c (print_reg): Print the name of the full | ||
30 | integer register without '%'. | ||
31 | (ix86_print_operand): Handle 'V'. | ||
32 | * doc/extend.texi: Document 'V' modifier. | ||
33 | |||
34 | gcc/testsuite/ | ||
35 | |||
36 | Backport from mainline | ||
37 | 2018-01-14 H.J. Lu <hongjiu.lu@intel.com> | ||
38 | |||
39 | * gcc.target/i386/indirect-thunk-register-4.c: New test. | ||
40 | |||
41 | Upstream-Status: Pending | ||
42 | |||
43 | Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> | ||
44 | |||
45 | --- | ||
46 | gcc/config/i386/i386.c | 13 ++++++++++++- | ||
47 | gcc/doc/extend.texi | 3 +++ | ||
48 | gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c | 13 +++++++++++++ | ||
49 | 3 files changed, 28 insertions(+), 1 deletion(-) | ||
50 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c | ||
51 | |||
52 | diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c | ||
53 | index 34e26a3..eeca7e5 100644 | ||
54 | --- a/gcc/config/i386/i386.c | ||
55 | +++ b/gcc/config/i386/i386.c | ||
56 | @@ -16869,6 +16869,7 @@ put_condition_code (enum rtx_code code, machine_mode mode, bool reverse, | ||
57 | If CODE is 'h', pretend the reg is the 'high' byte register. | ||
58 | If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op. | ||
59 | If CODE is 'd', duplicate the operand for AVX instruction. | ||
60 | + If CODE is 'V', print naked full integer register name without %. | ||
61 | */ | ||
62 | |||
63 | void | ||
64 | @@ -16879,7 +16880,7 @@ print_reg (rtx x, int code, FILE *file) | ||
65 | unsigned int regno; | ||
66 | bool duplicated; | ||
67 | |||
68 | - if (ASSEMBLER_DIALECT == ASM_ATT) | ||
69 | + if (ASSEMBLER_DIALECT == ASM_ATT && code != 'V') | ||
70 | putc ('%', file); | ||
71 | |||
72 | if (x == pc_rtx) | ||
73 | @@ -16922,6 +16923,14 @@ print_reg (rtx x, int code, FILE *file) | ||
74 | && regno != FPSR_REG | ||
75 | && regno != FPCR_REG); | ||
76 | |||
77 | + if (code == 'V') | ||
78 | + { | ||
79 | + if (GENERAL_REGNO_P (regno)) | ||
80 | + msize = GET_MODE_SIZE (word_mode); | ||
81 | + else | ||
82 | + error ("'V' modifier on non-integer register"); | ||
83 | + } | ||
84 | + | ||
85 | duplicated = code == 'd' && TARGET_AVX; | ||
86 | |||
87 | switch (msize) | ||
88 | @@ -17035,6 +17044,7 @@ print_reg (rtx x, int code, FILE *file) | ||
89 | & -- print some in-use local-dynamic symbol name. | ||
90 | H -- print a memory address offset by 8; used for sse high-parts | ||
91 | Y -- print condition for XOP pcom* instruction. | ||
92 | + V -- print naked full integer register name without %. | ||
93 | + -- print a branch hint as 'cs' or 'ds' prefix | ||
94 | ; -- print a semicolon (after prefixes due to bug in older gas). | ||
95 | ~ -- print "i" if TARGET_AVX2, "f" otherwise. | ||
96 | @@ -17259,6 +17269,7 @@ ix86_print_operand (FILE *file, rtx x, int code) | ||
97 | case 'X': | ||
98 | case 'P': | ||
99 | case 'p': | ||
100 | + case 'V': | ||
101 | break; | ||
102 | |||
103 | case 's': | ||
104 | diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi | ||
105 | index 2cb6bd1..76ba1d4 100644 | ||
106 | --- a/gcc/doc/extend.texi | ||
107 | +++ b/gcc/doc/extend.texi | ||
108 | @@ -8511,6 +8511,9 @@ The table below shows the list of supported modifiers and their effects. | ||
109 | @tab @code{2} | ||
110 | @end multitable | ||
111 | |||
112 | +@code{V} is a special modifier which prints the name of the full integer | ||
113 | +register without @code{%}. | ||
114 | + | ||
115 | @anchor{x86floatingpointasmoperands} | ||
116 | @subsubsection x86 Floating-Point @code{asm} Operands | ||
117 | |||
118 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c | ||
119 | new file mode 100644 | ||
120 | index 0000000..f0cd9b7 | ||
121 | --- /dev/null | ||
122 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-register-4.c | ||
123 | @@ -0,0 +1,13 @@ | ||
124 | +/* { dg-do compile } */ | ||
125 | +/* { dg-options "-O2 -mindirect-branch=keep -fno-pic" } */ | ||
126 | + | ||
127 | +extern void (*func_p) (void); | ||
128 | + | ||
129 | +void | ||
130 | +foo (void) | ||
131 | +{ | ||
132 | + asm("call __x86_indirect_thunk_%V0" : : "a" (func_p)); | ||
133 | +} | ||
134 | + | ||
135 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_eax" { target ia32 } } } */ | ||
136 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_rax" { target { ! ia32 } } } } */ | ||
137 | -- | ||
138 | 2.7.4 | ||
139 | |||
diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0008-x86-Disallow-mindirect-branch-mfunction-return-with-.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0008-x86-Disallow-mindirect-branch-mfunction-return-with-.patch new file mode 100644 index 0000000000..d8a581013a --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0008-x86-Disallow-mindirect-branch-mfunction-return-with-.patch | |||
@@ -0,0 +1,304 @@ | |||
1 | From 8e0d9bf93e2e2ec03c544572aef4b03a8e7090f3 Mon Sep 17 00:00:00 2001 | ||
2 | From: "H.J. Lu" <hjl.tools@gmail.com> | ||
3 | Date: Sat, 13 Jan 2018 18:01:54 -0800 | ||
4 | Subject: [PATCH 08/12] x86: Disallow -mindirect-branch=/-mfunction-return= | ||
5 | with -mcmodel=large | ||
6 | |||
7 | Since the thunk function may not be reachable in large code model, | ||
8 | -mcmodel=large is incompatible with -mindirect-branch=thunk, | ||
9 | -mindirect-branch=thunk-extern, -mfunction-return=thunk and | ||
10 | -mfunction-return=thunk-extern. Issue an error when they are used with | ||
11 | -mcmodel=large. | ||
12 | |||
13 | gcc/ | ||
14 | |||
15 | Backport from mainline | ||
16 | 2018-01-14 H.J. Lu <hongjiu.lu@intel.com> | ||
17 | |||
18 | * config/i386/i386.c (ix86_set_indirect_branch_type): Disallow | ||
19 | -mcmodel=large with -mindirect-branch=thunk, | ||
20 | -mindirect-branch=thunk-extern, -mfunction-return=thunk and | ||
21 | -mfunction-return=thunk-extern. | ||
22 | * doc/invoke.texi: Document -mcmodel=large is incompatible with | ||
23 | -mindirect-branch=thunk, -mindirect-branch=thunk-extern, | ||
24 | -mfunction-return=thunk and -mfunction-return=thunk-extern. | ||
25 | |||
26 | gcc/testsuite/ | ||
27 | |||
28 | Backport from mainline | ||
29 | 2018-01-14 H.J. Lu <hongjiu.lu@intel.com> | ||
30 | |||
31 | * gcc.target/i386/indirect-thunk-10.c: New test. | ||
32 | * gcc.target/i386/indirect-thunk-8.c: Likewise. | ||
33 | * gcc.target/i386/indirect-thunk-9.c: Likewise. | ||
34 | * gcc.target/i386/indirect-thunk-attr-10.c: Likewise. | ||
35 | * gcc.target/i386/indirect-thunk-attr-11.c: Likewise. | ||
36 | * gcc.target/i386/indirect-thunk-attr-9.c: Likewise. | ||
37 | * gcc.target/i386/ret-thunk-17.c: Likewise. | ||
38 | * gcc.target/i386/ret-thunk-18.c: Likewise. | ||
39 | * gcc.target/i386/ret-thunk-19.c: Likewise. | ||
40 | * gcc.target/i386/ret-thunk-20.c: Likewise. | ||
41 | * gcc.target/i386/ret-thunk-21.c: Likewise. | ||
42 | |||
43 | Upstream-Status: Pending | ||
44 | |||
45 | Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> | ||
46 | |||
47 | --- | ||
48 | gcc/config/i386/i386.c | 26 ++++++++++++++++++++++ | ||
49 | gcc/doc/invoke.texi | 11 +++++++++ | ||
50 | gcc/testsuite/gcc.target/i386/indirect-thunk-10.c | 7 ++++++ | ||
51 | gcc/testsuite/gcc.target/i386/indirect-thunk-8.c | 7 ++++++ | ||
52 | gcc/testsuite/gcc.target/i386/indirect-thunk-9.c | 7 ++++++ | ||
53 | .../gcc.target/i386/indirect-thunk-attr-10.c | 9 ++++++++ | ||
54 | .../gcc.target/i386/indirect-thunk-attr-11.c | 9 ++++++++ | ||
55 | .../gcc.target/i386/indirect-thunk-attr-9.c | 9 ++++++++ | ||
56 | gcc/testsuite/gcc.target/i386/ret-thunk-17.c | 7 ++++++ | ||
57 | gcc/testsuite/gcc.target/i386/ret-thunk-18.c | 8 +++++++ | ||
58 | gcc/testsuite/gcc.target/i386/ret-thunk-19.c | 8 +++++++ | ||
59 | gcc/testsuite/gcc.target/i386/ret-thunk-20.c | 9 ++++++++ | ||
60 | gcc/testsuite/gcc.target/i386/ret-thunk-21.c | 9 ++++++++ | ||
61 | 13 files changed, 126 insertions(+) | ||
62 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-10.c | ||
63 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-8.c | ||
64 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-9.c | ||
65 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c | ||
66 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c | ||
67 | create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c | ||
68 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-17.c | ||
69 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-18.c | ||
70 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-19.c | ||
71 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-20.c | ||
72 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-21.c | ||
73 | |||
74 | diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c | ||
75 | index eeca7e5..9c038be 100644 | ||
76 | --- a/gcc/config/i386/i386.c | ||
77 | +++ b/gcc/config/i386/i386.c | ||
78 | @@ -6389,6 +6389,19 @@ ix86_set_indirect_branch_type (tree fndecl) | ||
79 | } | ||
80 | else | ||
81 | cfun->machine->indirect_branch_type = ix86_indirect_branch; | ||
82 | + | ||
83 | + /* -mcmodel=large is not compatible with -mindirect-branch=thunk | ||
84 | + nor -mindirect-branch=thunk-extern. */ | ||
85 | + if ((ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC) | ||
86 | + && ((cfun->machine->indirect_branch_type | ||
87 | + == indirect_branch_thunk_extern) | ||
88 | + || (cfun->machine->indirect_branch_type | ||
89 | + == indirect_branch_thunk))) | ||
90 | + error ("%<-mindirect-branch=%s%> and %<-mcmodel=large%> are not " | ||
91 | + "compatible", | ||
92 | + ((cfun->machine->indirect_branch_type | ||
93 | + == indirect_branch_thunk_extern) | ||
94 | + ? "thunk-extern" : "thunk")); | ||
95 | } | ||
96 | |||
97 | if (cfun->machine->function_return_type == indirect_branch_unset) | ||
98 | @@ -6414,6 +6427,19 @@ ix86_set_indirect_branch_type (tree fndecl) | ||
99 | } | ||
100 | else | ||
101 | cfun->machine->function_return_type = ix86_function_return; | ||
102 | + | ||
103 | + /* -mcmodel=large is not compatible with -mfunction-return=thunk | ||
104 | + nor -mfunction-return=thunk-extern. */ | ||
105 | + if ((ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC) | ||
106 | + && ((cfun->machine->function_return_type | ||
107 | + == indirect_branch_thunk_extern) | ||
108 | + || (cfun->machine->function_return_type | ||
109 | + == indirect_branch_thunk))) | ||
110 | + error ("%<-mfunction-return=%s%> and %<-mcmodel=large%> are not " | ||
111 | + "compatible", | ||
112 | + ((cfun->machine->function_return_type | ||
113 | + == indirect_branch_thunk_extern) | ||
114 | + ? "thunk-extern" : "thunk")); | ||
115 | } | ||
116 | } | ||
117 | |||
118 | diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi | ||
119 | index ad9f295..48e827f 100644 | ||
120 | --- a/gcc/doc/invoke.texi | ||
121 | +++ b/gcc/doc/invoke.texi | ||
122 | @@ -24230,6 +24230,11 @@ to external call and return thunk provided in a separate object file. | ||
123 | You can control this behavior for a specific function by using the | ||
124 | function attribute @code{indirect_branch}. @xref{Function Attributes}. | ||
125 | |||
126 | +Note that @option{-mcmodel=large} is incompatible with | ||
127 | +@option{-mindirect-branch=thunk} nor | ||
128 | +@option{-mindirect-branch=thunk-extern} since the thunk function may | ||
129 | +not be reachable in large code model. | ||
130 | + | ||
131 | @item -mfunction-return=@var{choice} | ||
132 | @opindex -mfunction-return | ||
133 | Convert function return with @var{choice}. The default is @samp{keep}, | ||
134 | @@ -24241,6 +24246,12 @@ object file. You can control this behavior for a specific function by | ||
135 | using the function attribute @code{function_return}. | ||
136 | @xref{Function Attributes}. | ||
137 | |||
138 | +Note that @option{-mcmodel=large} is incompatible with | ||
139 | +@option{-mfunction-return=thunk} nor | ||
140 | +@option{-mfunction-return=thunk-extern} since the thunk function may | ||
141 | +not be reachable in large code model. | ||
142 | + | ||
143 | + | ||
144 | @item -mindirect-branch-register | ||
145 | @opindex -mindirect-branch-register | ||
146 | Force indirect call and jump via register. | ||
147 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-10.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-10.c | ||
148 | new file mode 100644 | ||
149 | index 0000000..a0674bd | ||
150 | --- /dev/null | ||
151 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-10.c | ||
152 | @@ -0,0 +1,7 @@ | ||
153 | +/* { dg-do compile { target { lp64 } } } */ | ||
154 | +/* { dg-options "-O2 -mindirect-branch=thunk-inline -mfunction-return=keep -mcmodel=large" } */ | ||
155 | + | ||
156 | +void | ||
157 | +bar (void) | ||
158 | +{ | ||
159 | +} | ||
160 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-8.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-8.c | ||
161 | new file mode 100644 | ||
162 | index 0000000..7a80a89 | ||
163 | --- /dev/null | ||
164 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-8.c | ||
165 | @@ -0,0 +1,7 @@ | ||
166 | +/* { dg-do compile { target { lp64 } } } */ | ||
167 | +/* { dg-options "-O2 -mindirect-branch=thunk -mfunction-return=keep -mcmodel=large" } */ | ||
168 | + | ||
169 | +void | ||
170 | +bar (void) | ||
171 | +{ /* { dg-error "'-mindirect-branch=thunk' and '-mcmodel=large' are not compatible" } */ | ||
172 | +} | ||
173 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-9.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-9.c | ||
174 | new file mode 100644 | ||
175 | index 0000000..d4d45c5 | ||
176 | --- /dev/null | ||
177 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-9.c | ||
178 | @@ -0,0 +1,7 @@ | ||
179 | +/* { dg-do compile { target { lp64 } } } */ | ||
180 | +/* { dg-options "-O2 -mindirect-branch=thunk-extern -mfunction-return=keep -mcmodel=large" } */ | ||
181 | + | ||
182 | +void | ||
183 | +bar (void) | ||
184 | +{ /* { dg-error "'-mindirect-branch=thunk-extern' and '-mcmodel=large' are not compatible" } */ | ||
185 | +} | ||
186 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c | ||
187 | new file mode 100644 | ||
188 | index 0000000..3a2aead | ||
189 | --- /dev/null | ||
190 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-10.c | ||
191 | @@ -0,0 +1,9 @@ | ||
192 | +/* { dg-do compile { target { lp64 } } } */ | ||
193 | +/* { dg-options "-O2 -mindirect-branch=keep -mfunction-return=keep -mcmodel=large" } */ | ||
194 | +/* { dg-additional-options "-fPIC" { target fpic } } */ | ||
195 | + | ||
196 | +__attribute__ ((indirect_branch("thunk-extern"))) | ||
197 | +void | ||
198 | +bar (void) | ||
199 | +{ /* { dg-error "'-mindirect-branch=thunk-extern' and '-mcmodel=large' are not compatible" } */ | ||
200 | +} | ||
201 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c | ||
202 | new file mode 100644 | ||
203 | index 0000000..8e52f03 | ||
204 | --- /dev/null | ||
205 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-11.c | ||
206 | @@ -0,0 +1,9 @@ | ||
207 | +/* { dg-do compile { target { lp64 } } } */ | ||
208 | +/* { dg-options "-O2 -mindirect-branch=keep -mfunction-return=keep -mcmodel=large" } */ | ||
209 | +/* { dg-additional-options "-fPIC" { target fpic } } */ | ||
210 | + | ||
211 | +__attribute__ ((indirect_branch("thunk-inline"))) | ||
212 | +void | ||
213 | +bar (void) | ||
214 | +{ | ||
215 | +} | ||
216 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c | ||
217 | new file mode 100644 | ||
218 | index 0000000..bdaa4f6 | ||
219 | --- /dev/null | ||
220 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-9.c | ||
221 | @@ -0,0 +1,9 @@ | ||
222 | +/* { dg-do compile { target { lp64 } } } */ | ||
223 | +/* { dg-options "-O2 -mindirect-branch=keep -mfunction-return=keep -mcmodel=large" } */ | ||
224 | +/* { dg-additional-options "-fPIC" { target fpic } } */ | ||
225 | + | ||
226 | +__attribute__ ((indirect_branch("thunk"))) | ||
227 | +void | ||
228 | +bar (void) | ||
229 | +{ /* { dg-error "'-mindirect-branch=thunk' and '-mcmodel=large' are not compatible" } */ | ||
230 | +} | ||
231 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-17.c b/gcc/testsuite/gcc.target/i386/ret-thunk-17.c | ||
232 | new file mode 100644 | ||
233 | index 0000000..0605e2c | ||
234 | --- /dev/null | ||
235 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-17.c | ||
236 | @@ -0,0 +1,7 @@ | ||
237 | +/* { dg-do compile { target { lp64 } } } */ | ||
238 | +/* { dg-options "-O2 -mfunction-return=thunk -mindirect-branch=keep -mcmodel=large" } */ | ||
239 | + | ||
240 | +void | ||
241 | +bar (void) | ||
242 | +{ /* { dg-error "'-mfunction-return=thunk' and '-mcmodel=large' are not compatible" } */ | ||
243 | +} | ||
244 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-18.c b/gcc/testsuite/gcc.target/i386/ret-thunk-18.c | ||
245 | new file mode 100644 | ||
246 | index 0000000..307019d | ||
247 | --- /dev/null | ||
248 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-18.c | ||
249 | @@ -0,0 +1,8 @@ | ||
250 | +/* { dg-do compile { target { lp64 } } } */ | ||
251 | +/* { dg-options "-O2 -mfunction-return=thunk-extern -mindirect-branch=keep -mcmodel=large" } */ | ||
252 | +/* { dg-additional-options "-fPIC" { target fpic } } */ | ||
253 | + | ||
254 | +void | ||
255 | +bar (void) | ||
256 | +{ /* { dg-error "'-mfunction-return=thunk-extern' and '-mcmodel=large' are not compatible" } */ | ||
257 | +} | ||
258 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-19.c b/gcc/testsuite/gcc.target/i386/ret-thunk-19.c | ||
259 | new file mode 100644 | ||
260 | index 0000000..772617f | ||
261 | --- /dev/null | ||
262 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-19.c | ||
263 | @@ -0,0 +1,8 @@ | ||
264 | +/* { dg-do compile { target { lp64 } } } */ | ||
265 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -mcmodel=large" } */ | ||
266 | + | ||
267 | +__attribute__ ((function_return("thunk"))) | ||
268 | +void | ||
269 | +bar (void) | ||
270 | +{ /* { dg-error "'-mfunction-return=thunk' and '-mcmodel=large' are not compatible" } */ | ||
271 | +} | ||
272 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-20.c b/gcc/testsuite/gcc.target/i386/ret-thunk-20.c | ||
273 | new file mode 100644 | ||
274 | index 0000000..1e9f9bd | ||
275 | --- /dev/null | ||
276 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-20.c | ||
277 | @@ -0,0 +1,9 @@ | ||
278 | +/* { dg-do compile { target { lp64 } } } */ | ||
279 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -mcmodel=large" } */ | ||
280 | +/* { dg-additional-options "-fPIC" { target fpic } } */ | ||
281 | + | ||
282 | +__attribute__ ((function_return("thunk-extern"))) | ||
283 | +void | ||
284 | +bar (void) | ||
285 | +{ /* { dg-error "'-mfunction-return=thunk-extern' and '-mcmodel=large' are not compatible" } */ | ||
286 | +} | ||
287 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-21.c b/gcc/testsuite/gcc.target/i386/ret-thunk-21.c | ||
288 | new file mode 100644 | ||
289 | index 0000000..eea07f7 | ||
290 | --- /dev/null | ||
291 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-21.c | ||
292 | @@ -0,0 +1,9 @@ | ||
293 | +/* { dg-do compile { target { lp64 } } } */ | ||
294 | +/* { dg-options "-O2 -mfunction-return=keep -mindirect-branch=keep -mcmodel=large" } */ | ||
295 | +/* { dg-additional-options "-fPIC" { target fpic } } */ | ||
296 | + | ||
297 | +__attribute__ ((function_return("thunk-inline"))) | ||
298 | +void | ||
299 | +bar (void) | ||
300 | +{ | ||
301 | +} | ||
302 | -- | ||
303 | 2.7.4 | ||
304 | |||
diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0009-Use-INVALID_REGNUM-in-indirect-thunk-processing.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0009-Use-INVALID_REGNUM-in-indirect-thunk-processing.patch new file mode 100644 index 0000000000..7364a2c36a --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0009-Use-INVALID_REGNUM-in-indirect-thunk-processing.patch | |||
@@ -0,0 +1,126 @@ | |||
1 | From 3eff2adada2b1667b0e76496fa559e0c248ecd84 Mon Sep 17 00:00:00 2001 | ||
2 | From: uros <uros@138bc75d-0d04-0410-961f-82ee72b054a4> | ||
3 | Date: Thu, 25 Jan 2018 19:39:01 +0000 | ||
4 | Subject: [PATCH 09/12] Use INVALID_REGNUM in indirect thunk processing | ||
5 | |||
6 | Backport from mainline | ||
7 | 2018-01-17 Uros Bizjak <ubizjak@gmail.com> | ||
8 | |||
9 | * config/i386/i386.c (indirect_thunk_name): Declare regno | ||
10 | as unsigned int. Compare regno with INVALID_REGNUM. | ||
11 | (output_indirect_thunk): Ditto. | ||
12 | (output_indirect_thunk_function): Ditto. | ||
13 | (ix86_code_end): Declare regno as unsigned int. Use INVALID_REGNUM | ||
14 | in the call to output_indirect_thunk_function. | ||
15 | |||
16 | git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@257067 138bc75d-0d04-0410-961f-82ee72b054a4 | ||
17 | |||
18 | Upstream-Status: Pending | ||
19 | |||
20 | Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> | ||
21 | |||
22 | --- | ||
23 | gcc/config/i386/i386.c | 30 +++++++++++++++--------------- | ||
24 | 1 file changed, 15 insertions(+), 15 deletions(-) | ||
25 | |||
26 | diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c | ||
27 | index 9c038be..4012657 100644 | ||
28 | --- a/gcc/config/i386/i386.c | ||
29 | +++ b/gcc/config/i386/i386.c | ||
30 | @@ -11087,16 +11087,16 @@ static int indirect_thunks_bnd_used; | ||
31 | /* Fills in the label name that should be used for the indirect thunk. */ | ||
32 | |||
33 | static void | ||
34 | -indirect_thunk_name (char name[32], int regno, bool need_bnd_p, | ||
35 | - bool ret_p) | ||
36 | +indirect_thunk_name (char name[32], unsigned int regno, | ||
37 | + bool need_bnd_p, bool ret_p) | ||
38 | { | ||
39 | - if (regno >= 0 && ret_p) | ||
40 | + if (regno != INVALID_REGNUM && ret_p) | ||
41 | gcc_unreachable (); | ||
42 | |||
43 | if (USE_HIDDEN_LINKONCE) | ||
44 | { | ||
45 | const char *bnd = need_bnd_p ? "_bnd" : ""; | ||
46 | - if (regno >= 0) | ||
47 | + if (regno != INVALID_REGNUM) | ||
48 | { | ||
49 | const char *reg_prefix; | ||
50 | if (LEGACY_INT_REGNO_P (regno)) | ||
51 | @@ -11114,7 +11114,7 @@ indirect_thunk_name (char name[32], int regno, bool need_bnd_p, | ||
52 | } | ||
53 | else | ||
54 | { | ||
55 | - if (regno >= 0) | ||
56 | + if (regno != INVALID_REGNUM) | ||
57 | { | ||
58 | if (need_bnd_p) | ||
59 | ASM_GENERATE_INTERNAL_LABEL (name, "LITBR", regno); | ||
60 | @@ -11166,7 +11166,7 @@ indirect_thunk_name (char name[32], int regno, bool need_bnd_p, | ||
61 | */ | ||
62 | |||
63 | static void | ||
64 | -output_indirect_thunk (bool need_bnd_p, int regno) | ||
65 | +output_indirect_thunk (bool need_bnd_p, unsigned int regno) | ||
66 | { | ||
67 | char indirectlabel1[32]; | ||
68 | char indirectlabel2[32]; | ||
69 | @@ -11196,7 +11196,7 @@ output_indirect_thunk (bool need_bnd_p, int regno) | ||
70 | |||
71 | ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2); | ||
72 | |||
73 | - if (regno >= 0) | ||
74 | + if (regno != INVALID_REGNUM) | ||
75 | { | ||
76 | /* MOV. */ | ||
77 | rtx xops[2]; | ||
78 | @@ -11220,12 +11220,12 @@ output_indirect_thunk (bool need_bnd_p, int regno) | ||
79 | } | ||
80 | |||
81 | /* Output a funtion with a call and return thunk for indirect branch. | ||
82 | - If BND_P is true, the BND prefix is needed. If REGNO != -1, the | ||
83 | - function address is in REGNO. Otherwise, the function address is | ||
84 | + If BND_P is true, the BND prefix is needed. If REGNO != INVALID_REGNUM, | ||
85 | + the function address is in REGNO. Otherwise, the function address is | ||
86 | on the top of stack. */ | ||
87 | |||
88 | static void | ||
89 | -output_indirect_thunk_function (bool need_bnd_p, int regno) | ||
90 | +output_indirect_thunk_function (bool need_bnd_p, unsigned int regno) | ||
91 | { | ||
92 | char name[32]; | ||
93 | tree decl; | ||
94 | @@ -11274,7 +11274,7 @@ output_indirect_thunk_function (bool need_bnd_p, int regno) | ||
95 | ASM_OUTPUT_LABEL (asm_out_file, name); | ||
96 | } | ||
97 | |||
98 | - if (regno < 0) | ||
99 | + if (regno == INVALID_REGNUM) | ||
100 | { | ||
101 | /* Create alias for __x86.return_thunk/__x86.return_thunk_bnd. */ | ||
102 | char alias[32]; | ||
103 | @@ -11348,16 +11348,16 @@ static void | ||
104 | ix86_code_end (void) | ||
105 | { | ||
106 | rtx xops[2]; | ||
107 | - int regno; | ||
108 | + unsigned int regno; | ||
109 | |||
110 | if (indirect_thunk_needed) | ||
111 | - output_indirect_thunk_function (false, -1); | ||
112 | + output_indirect_thunk_function (false, INVALID_REGNUM); | ||
113 | if (indirect_thunk_bnd_needed) | ||
114 | - output_indirect_thunk_function (true, -1); | ||
115 | + output_indirect_thunk_function (true, INVALID_REGNUM); | ||
116 | |||
117 | for (regno = FIRST_REX_INT_REG; regno <= LAST_REX_INT_REG; regno++) | ||
118 | { | ||
119 | - int i = regno - FIRST_REX_INT_REG + LAST_INT_REG + 1; | ||
120 | + unsigned int i = regno - FIRST_REX_INT_REG + LAST_INT_REG + 1; | ||
121 | if ((indirect_thunks_used & (1 << i))) | ||
122 | output_indirect_thunk_function (false, regno); | ||
123 | |||
124 | -- | ||
125 | 2.7.4 | ||
126 | |||
diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0010-i386-Pass-INVALID_REGNUM-as-invalid-register-number.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0010-i386-Pass-INVALID_REGNUM-as-invalid-register-number.patch new file mode 100644 index 0000000000..080d741983 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0010-i386-Pass-INVALID_REGNUM-as-invalid-register-number.patch | |||
@@ -0,0 +1,46 @@ | |||
1 | From c4300d9ad683e693c90d02d4f1b13183bf2d4acc Mon Sep 17 00:00:00 2001 | ||
2 | From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> | ||
3 | Date: Fri, 2 Feb 2018 16:47:02 +0000 | ||
4 | Subject: [PATCH 10/12] i386: Pass INVALID_REGNUM as invalid register number | ||
5 | |||
6 | Backport from mainline | ||
7 | * config/i386/i386.c (ix86_output_function_return): Pass | ||
8 | INVALID_REGNUM, instead of -1, as invalid register number to | ||
9 | indirect_thunk_name and output_indirect_thunk. | ||
10 | |||
11 | git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@257341 138bc75d-0d04-0410-961f-82ee72b054a4 | ||
12 | |||
13 | Upstream-Status: Pending | ||
14 | |||
15 | Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> | ||
16 | |||
17 | --- | ||
18 | gcc/config/i386/i386.c | 5 +++-- | ||
19 | 1 file changed, 3 insertions(+), 2 deletions(-) | ||
20 | |||
21 | diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c | ||
22 | index 4012657..66502ee 100644 | ||
23 | --- a/gcc/config/i386/i386.c | ||
24 | +++ b/gcc/config/i386/i386.c | ||
25 | @@ -28056,7 +28056,8 @@ ix86_output_function_return (bool long_p) | ||
26 | { | ||
27 | bool need_thunk = (cfun->machine->function_return_type | ||
28 | == indirect_branch_thunk); | ||
29 | - indirect_thunk_name (thunk_name, -1, need_bnd_p, true); | ||
30 | + indirect_thunk_name (thunk_name, INVALID_REGNUM, need_bnd_p, | ||
31 | + true); | ||
32 | if (need_bnd_p) | ||
33 | { | ||
34 | indirect_thunk_bnd_needed |= need_thunk; | ||
35 | @@ -28069,7 +28070,7 @@ ix86_output_function_return (bool long_p) | ||
36 | } | ||
37 | } | ||
38 | else | ||
39 | - output_indirect_thunk (need_bnd_p, -1); | ||
40 | + output_indirect_thunk (need_bnd_p, INVALID_REGNUM); | ||
41 | |||
42 | return ""; | ||
43 | } | ||
44 | -- | ||
45 | 2.7.4 | ||
46 | |||
diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0011-i386-Update-mfunction-return-for-return-with-pop.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0011-i386-Update-mfunction-return-for-return-with-pop.patch new file mode 100644 index 0000000000..3b036fbe18 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0011-i386-Update-mfunction-return-for-return-with-pop.patch | |||
@@ -0,0 +1,453 @@ | |||
1 | From b3a2269c7884378a9afd394ac7e669aab0443b57 Mon Sep 17 00:00:00 2001 | ||
2 | From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> | ||
3 | Date: Mon, 26 Feb 2018 15:29:30 +0000 | ||
4 | Subject: [PATCH 11/12] i386: Update -mfunction-return= for return with pop | ||
5 | |||
6 | When -mfunction-return= is used, simple_return_pop_internal should pop | ||
7 | return address into ECX register, adjust stack by bytes to pop from stack | ||
8 | and jump to the return thunk via ECX register. | ||
9 | |||
10 | Revision 257992 removed the bool argument from ix86_output_indirect_jmp. | ||
11 | Update comments to reflect it. | ||
12 | |||
13 | Tested on i686 and x86-64. | ||
14 | |||
15 | Backport from mainline | ||
16 | * config/i386/i386.c (ix86_output_indirect_jmp): Update comments. | ||
17 | |||
18 | PR target/84530 | ||
19 | * config/i386/i386-protos.h (ix86_output_indirect_jmp): Remove | ||
20 | the bool argument. | ||
21 | (ix86_output_indirect_function_return): New prototype. | ||
22 | (ix86_split_simple_return_pop_internal): Likewise. | ||
23 | * config/i386/i386.c (indirect_return_via_cx): New. | ||
24 | (indirect_return_via_cx_bnd): Likewise. | ||
25 | (indirect_thunk_name): Handle return va CX_REG. | ||
26 | (output_indirect_thunk_function): Create alias for | ||
27 | __x86_return_thunk_[re]cx and __x86_return_thunk_[re]cx_bnd. | ||
28 | (ix86_output_indirect_jmp): Remove the bool argument. | ||
29 | (ix86_output_indirect_function_return): New function. | ||
30 | (ix86_split_simple_return_pop_internal): Likewise. | ||
31 | * config/i386/i386.md (*indirect_jump): Don't pass false | ||
32 | to ix86_output_indirect_jmp. | ||
33 | (*tablejump_1): Likewise. | ||
34 | (simple_return_pop_internal): Change it to define_insn_and_split. | ||
35 | Call ix86_split_simple_return_pop_internal to split it for | ||
36 | -mfunction-return=. | ||
37 | (simple_return_indirect_internal): Call | ||
38 | ix86_output_indirect_function_return instead of | ||
39 | ix86_output_indirect_jmp. | ||
40 | |||
41 | gcc/testsuite/ | ||
42 | |||
43 | Backport from mainline | ||
44 | PR target/84530 | ||
45 | * gcc.target/i386/ret-thunk-22.c: New test. | ||
46 | * gcc.target/i386/ret-thunk-23.c: Likewise. | ||
47 | * gcc.target/i386/ret-thunk-24.c: Likewise. | ||
48 | * gcc.target/i386/ret-thunk-25.c: Likewise. | ||
49 | * gcc.target/i386/ret-thunk-26.c: Likewise. | ||
50 | |||
51 | Upstream-Status: Pending | ||
52 | |||
53 | Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> | ||
54 | |||
55 | --- | ||
56 | gcc/config/i386/i386-protos.h | 4 +- | ||
57 | gcc/config/i386/i386.c | 127 +++++++++++++++++++++++---- | ||
58 | gcc/config/i386/i386.md | 11 ++- | ||
59 | gcc/testsuite/gcc.target/i386/ret-thunk-22.c | 15 ++++ | ||
60 | gcc/testsuite/gcc.target/i386/ret-thunk-23.c | 15 ++++ | ||
61 | gcc/testsuite/gcc.target/i386/ret-thunk-24.c | 15 ++++ | ||
62 | gcc/testsuite/gcc.target/i386/ret-thunk-25.c | 15 ++++ | ||
63 | gcc/testsuite/gcc.target/i386/ret-thunk-26.c | 40 +++++++++ | ||
64 | 8 files changed, 222 insertions(+), 20 deletions(-) | ||
65 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-22.c | ||
66 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-23.c | ||
67 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-24.c | ||
68 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-25.c | ||
69 | create mode 100644 gcc/testsuite/gcc.target/i386/ret-thunk-26.c | ||
70 | |||
71 | diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h | ||
72 | index 620d70e..c7a0ccb5 100644 | ||
73 | --- a/gcc/config/i386/i386-protos.h | ||
74 | +++ b/gcc/config/i386/i386-protos.h | ||
75 | @@ -311,8 +311,10 @@ extern enum attr_cpu ix86_schedule; | ||
76 | #endif | ||
77 | |||
78 | extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op); | ||
79 | -extern const char * ix86_output_indirect_jmp (rtx call_op, bool ret_p); | ||
80 | +extern const char * ix86_output_indirect_jmp (rtx call_op); | ||
81 | extern const char * ix86_output_function_return (bool long_p); | ||
82 | +extern const char * ix86_output_indirect_function_return (rtx ret_op); | ||
83 | +extern void ix86_split_simple_return_pop_internal (rtx); | ||
84 | extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load, | ||
85 | enum machine_mode mode); | ||
86 | |||
87 | diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c | ||
88 | index 66502ee..21c3c18 100644 | ||
89 | --- a/gcc/config/i386/i386.c | ||
90 | +++ b/gcc/config/i386/i386.c | ||
91 | @@ -11080,6 +11080,12 @@ static int indirect_thunks_used; | ||
92 | by call and return thunks functions with the BND prefix. */ | ||
93 | static int indirect_thunks_bnd_used; | ||
94 | |||
95 | +/* True if return thunk function via CX is needed. */ | ||
96 | +static bool indirect_return_via_cx; | ||
97 | +/* True if return thunk function via CX with the BND prefix is | ||
98 | + needed. */ | ||
99 | +static bool indirect_return_via_cx_bnd; | ||
100 | + | ||
101 | #ifndef INDIRECT_LABEL | ||
102 | # define INDIRECT_LABEL "LIND" | ||
103 | #endif | ||
104 | @@ -11090,12 +11096,13 @@ static void | ||
105 | indirect_thunk_name (char name[32], unsigned int regno, | ||
106 | bool need_bnd_p, bool ret_p) | ||
107 | { | ||
108 | - if (regno != INVALID_REGNUM && ret_p) | ||
109 | + if (regno != INVALID_REGNUM && regno != CX_REG && ret_p) | ||
110 | gcc_unreachable (); | ||
111 | |||
112 | if (USE_HIDDEN_LINKONCE) | ||
113 | { | ||
114 | const char *bnd = need_bnd_p ? "_bnd" : ""; | ||
115 | + const char *ret = ret_p ? "return" : "indirect"; | ||
116 | if (regno != INVALID_REGNUM) | ||
117 | { | ||
118 | const char *reg_prefix; | ||
119 | @@ -11103,14 +11110,11 @@ indirect_thunk_name (char name[32], unsigned int regno, | ||
120 | reg_prefix = TARGET_64BIT ? "r" : "e"; | ||
121 | else | ||
122 | reg_prefix = ""; | ||
123 | - sprintf (name, "__x86_indirect_thunk%s_%s%s", | ||
124 | - bnd, reg_prefix, reg_names[regno]); | ||
125 | + sprintf (name, "__x86_%s_thunk%s_%s%s", | ||
126 | + ret, bnd, reg_prefix, reg_names[regno]); | ||
127 | } | ||
128 | else | ||
129 | - { | ||
130 | - const char *ret = ret_p ? "return" : "indirect"; | ||
131 | - sprintf (name, "__x86_%s_thunk%s", ret, bnd); | ||
132 | - } | ||
133 | + sprintf (name, "__x86_%s_thunk%s", ret, bnd); | ||
134 | } | ||
135 | else | ||
136 | { | ||
137 | @@ -11274,9 +11278,23 @@ output_indirect_thunk_function (bool need_bnd_p, unsigned int regno) | ||
138 | ASM_OUTPUT_LABEL (asm_out_file, name); | ||
139 | } | ||
140 | |||
141 | + /* Create alias for __x86_return_thunk/__x86_return_thunk_bnd or | ||
142 | + __x86_return_thunk_ecx/__x86_return_thunk_ecx_bnd. */ | ||
143 | + bool need_alias; | ||
144 | if (regno == INVALID_REGNUM) | ||
145 | + need_alias = true; | ||
146 | + else if (regno == CX_REG) | ||
147 | + { | ||
148 | + if (need_bnd_p) | ||
149 | + need_alias = indirect_return_via_cx_bnd; | ||
150 | + else | ||
151 | + need_alias = indirect_return_via_cx; | ||
152 | + } | ||
153 | + else | ||
154 | + need_alias = false; | ||
155 | + | ||
156 | + if (need_alias) | ||
157 | { | ||
158 | - /* Create alias for __x86.return_thunk/__x86.return_thunk_bnd. */ | ||
159 | char alias[32]; | ||
160 | |||
161 | indirect_thunk_name (alias, regno, need_bnd_p, true); | ||
162 | @@ -28019,18 +28037,17 @@ ix86_output_indirect_branch (rtx call_op, const char *xasm, | ||
163 | else | ||
164 | ix86_output_indirect_branch_via_push (call_op, xasm, sibcall_p); | ||
165 | } | ||
166 | -/* Output indirect jump. CALL_OP is the jump target. Jump is a | ||
167 | - function return if RET_P is true. */ | ||
168 | + | ||
169 | +/* Output indirect jump. CALL_OP is the jump target. */ | ||
170 | |||
171 | const char * | ||
172 | -ix86_output_indirect_jmp (rtx call_op, bool ret_p) | ||
173 | +ix86_output_indirect_jmp (rtx call_op) | ||
174 | { | ||
175 | if (cfun->machine->indirect_branch_type != indirect_branch_keep) | ||
176 | { | ||
177 | - /* We can't have red-zone if this isn't a function return since | ||
178 | - "call" in the indirect thunk pushes the return address onto | ||
179 | - stack, destroying red-zone. */ | ||
180 | - if (!ret_p && ix86_red_zone_size != 0) | ||
181 | + /* We can't have red-zone since "call" in the indirect thunk | ||
182 | + pushes the return address onto stack, destroying red-zone. */ | ||
183 | + if (ix86_red_zone_size != 0) | ||
184 | gcc_unreachable (); | ||
185 | |||
186 | ix86_output_indirect_branch (call_op, "%0", true); | ||
187 | @@ -28081,6 +28098,86 @@ ix86_output_function_return (bool long_p) | ||
188 | return "rep%; ret"; | ||
189 | } | ||
190 | |||
191 | +/* Output indirect function return. RET_OP is the function return | ||
192 | + target. */ | ||
193 | + | ||
194 | +const char * | ||
195 | +ix86_output_indirect_function_return (rtx ret_op) | ||
196 | +{ | ||
197 | + if (cfun->machine->function_return_type != indirect_branch_keep) | ||
198 | + { | ||
199 | + char thunk_name[32]; | ||
200 | + bool need_bnd_p = ix86_bnd_prefixed_insn_p (current_output_insn); | ||
201 | + unsigned int regno = REGNO (ret_op); | ||
202 | + gcc_assert (regno == CX_REG); | ||
203 | + | ||
204 | + if (cfun->machine->function_return_type | ||
205 | + != indirect_branch_thunk_inline) | ||
206 | + { | ||
207 | + bool need_thunk = (cfun->machine->function_return_type | ||
208 | + == indirect_branch_thunk); | ||
209 | + indirect_thunk_name (thunk_name, regno, need_bnd_p, true); | ||
210 | + if (need_bnd_p) | ||
211 | + { | ||
212 | + if (need_thunk) | ||
213 | + { | ||
214 | + indirect_return_via_cx_bnd = true; | ||
215 | + indirect_thunks_bnd_used |= 1 << CX_REG; | ||
216 | + } | ||
217 | + fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name); | ||
218 | + } | ||
219 | + else | ||
220 | + { | ||
221 | + if (need_thunk) | ||
222 | + { | ||
223 | + indirect_return_via_cx = true; | ||
224 | + indirect_thunks_used |= 1 << CX_REG; | ||
225 | + } | ||
226 | + fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name); | ||
227 | + } | ||
228 | + } | ||
229 | + else | ||
230 | + output_indirect_thunk (need_bnd_p, regno); | ||
231 | + | ||
232 | + return ""; | ||
233 | + } | ||
234 | + else | ||
235 | + return "%!jmp\t%A0"; | ||
236 | +} | ||
237 | + | ||
238 | +/* Split simple return with popping POPC bytes from stack to indirect | ||
239 | + branch with stack adjustment . */ | ||
240 | + | ||
241 | +void | ||
242 | +ix86_split_simple_return_pop_internal (rtx popc) | ||
243 | +{ | ||
244 | + struct machine_function *m = cfun->machine; | ||
245 | + rtx ecx = gen_rtx_REG (SImode, CX_REG); | ||
246 | + rtx_insn *insn; | ||
247 | + | ||
248 | + /* There is no "pascal" calling convention in any 64bit ABI. */ | ||
249 | + gcc_assert (!TARGET_64BIT); | ||
250 | + | ||
251 | + insn = emit_insn (gen_pop (ecx)); | ||
252 | + m->fs.cfa_offset -= UNITS_PER_WORD; | ||
253 | + m->fs.sp_offset -= UNITS_PER_WORD; | ||
254 | + | ||
255 | + rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD); | ||
256 | + x = gen_rtx_SET (stack_pointer_rtx, x); | ||
257 | + add_reg_note (insn, REG_CFA_ADJUST_CFA, x); | ||
258 | + add_reg_note (insn, REG_CFA_REGISTER, gen_rtx_SET (ecx, pc_rtx)); | ||
259 | + RTX_FRAME_RELATED_P (insn) = 1; | ||
260 | + | ||
261 | + x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, popc); | ||
262 | + x = gen_rtx_SET (stack_pointer_rtx, x); | ||
263 | + insn = emit_insn (x); | ||
264 | + add_reg_note (insn, REG_CFA_ADJUST_CFA, x); | ||
265 | + RTX_FRAME_RELATED_P (insn) = 1; | ||
266 | + | ||
267 | + /* Now return address is in ECX. */ | ||
268 | + emit_jump_insn (gen_simple_return_indirect_internal (ecx)); | ||
269 | +} | ||
270 | + | ||
271 | /* Output the assembly for a call instruction. */ | ||
272 | |||
273 | const char * | ||
274 | diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md | ||
275 | index 05a88ff..857466a 100644 | ||
276 | --- a/gcc/config/i386/i386.md | ||
277 | +++ b/gcc/config/i386/i386.md | ||
278 | @@ -11813,7 +11813,7 @@ | ||
279 | (define_insn "*indirect_jump" | ||
280 | [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))] | ||
281 | "" | ||
282 | - "* return ix86_output_indirect_jmp (operands[0], false);" | ||
283 | + "* return ix86_output_indirect_jmp (operands[0]);" | ||
284 | [(set (attr "type") | ||
285 | (if_then_else (match_test "(cfun->machine->indirect_branch_type | ||
286 | != indirect_branch_keep)") | ||
287 | @@ -11868,7 +11868,7 @@ | ||
288 | [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw")) | ||
289 | (use (label_ref (match_operand 1)))] | ||
290 | "" | ||
291 | - "* return ix86_output_indirect_jmp (operands[0], false);" | ||
292 | + "* return ix86_output_indirect_jmp (operands[0]);" | ||
293 | [(set (attr "type") | ||
294 | (if_then_else (match_test "(cfun->machine->indirect_branch_type | ||
295 | != indirect_branch_keep)") | ||
296 | @@ -12520,11 +12520,14 @@ | ||
297 | (set_attr "prefix_rep" "1") | ||
298 | (set_attr "modrm" "0")]) | ||
299 | |||
300 | -(define_insn "simple_return_pop_internal" | ||
301 | +(define_insn_and_split "simple_return_pop_internal" | ||
302 | [(simple_return) | ||
303 | (use (match_operand:SI 0 "const_int_operand"))] | ||
304 | "reload_completed" | ||
305 | "%!ret\t%0" | ||
306 | + "&& cfun->machine->function_return_type != indirect_branch_keep" | ||
307 | + [(const_int 0)] | ||
308 | + "ix86_split_simple_return_pop_internal (operands[0]); DONE;" | ||
309 | [(set_attr "length" "3") | ||
310 | (set_attr "atom_unit" "jeu") | ||
311 | (set_attr "length_immediate" "2") | ||
312 | @@ -12535,7 +12538,7 @@ | ||
313 | [(simple_return) | ||
314 | (use (match_operand:SI 0 "register_operand" "r"))] | ||
315 | "reload_completed" | ||
316 | - "* return ix86_output_indirect_jmp (operands[0], true);" | ||
317 | + "* return ix86_output_indirect_function_return (operands[0]);" | ||
318 | [(set (attr "type") | ||
319 | (if_then_else (match_test "(cfun->machine->indirect_branch_type | ||
320 | != indirect_branch_keep)") | ||
321 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-22.c b/gcc/testsuite/gcc.target/i386/ret-thunk-22.c | ||
322 | new file mode 100644 | ||
323 | index 0000000..89e086d | ||
324 | --- /dev/null | ||
325 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-22.c | ||
326 | @@ -0,0 +1,15 @@ | ||
327 | +/* PR target/r84530 */ | ||
328 | +/* { dg-do compile { target ia32 } } */ | ||
329 | +/* { dg-options "-O2 -mfunction-return=thunk" } */ | ||
330 | + | ||
331 | +struct s { _Complex unsigned short x; }; | ||
332 | +struct s gs = { 100 + 200i }; | ||
333 | +struct s __attribute__((noinline)) foo (void) { return gs; } | ||
334 | + | ||
335 | +/* { dg-final { scan-assembler-times "popl\[\\t \]*%ecx" 1 } } */ | ||
336 | +/* { dg-final { scan-assembler "lea\[l\]?\[\\t \]*4\\(%esp\\), %esp" } } */ | ||
337 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk_ecx" } } */ | ||
338 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
339 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
340 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
341 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
342 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-23.c b/gcc/testsuite/gcc.target/i386/ret-thunk-23.c | ||
343 | new file mode 100644 | ||
344 | index 0000000..43f0cca | ||
345 | --- /dev/null | ||
346 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-23.c | ||
347 | @@ -0,0 +1,15 @@ | ||
348 | +/* PR target/r84530 */ | ||
349 | +/* { dg-do compile { target ia32 } } */ | ||
350 | +/* { dg-options "-O2 -mfunction-return=thunk-extern" } */ | ||
351 | + | ||
352 | +struct s { _Complex unsigned short x; }; | ||
353 | +struct s gs = { 100 + 200i }; | ||
354 | +struct s __attribute__((noinline)) foo (void) { return gs; } | ||
355 | + | ||
356 | +/* { dg-final { scan-assembler-times "popl\[\\t \]*%ecx" 1 } } */ | ||
357 | +/* { dg-final { scan-assembler "lea\[l\]?\[\\t \]*4\\(%esp\\), %esp" } } */ | ||
358 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk_ecx" } } */ | ||
359 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ | ||
360 | +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ | ||
361 | +/* { dg-final { scan-assembler-not {\tpause} } } */ | ||
362 | +/* { dg-final { scan-assembler-not {\tlfence} } } */ | ||
363 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-24.c b/gcc/testsuite/gcc.target/i386/ret-thunk-24.c | ||
364 | new file mode 100644 | ||
365 | index 0000000..8729e35 | ||
366 | --- /dev/null | ||
367 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-24.c | ||
368 | @@ -0,0 +1,15 @@ | ||
369 | +/* PR target/r84530 */ | ||
370 | +/* { dg-do compile { target ia32 } } */ | ||
371 | +/* { dg-options "-O2 -mfunction-return=thunk-inline" } */ | ||
372 | + | ||
373 | +struct s { _Complex unsigned short x; }; | ||
374 | +struct s gs = { 100 + 200i }; | ||
375 | +struct s __attribute__((noinline)) foo (void) { return gs; } | ||
376 | + | ||
377 | +/* { dg-final { scan-assembler-times "popl\[\\t \]*%ecx" 1 } } */ | ||
378 | +/* { dg-final { scan-assembler "lea\[l\]?\[\\t \]*4\\(%esp\\), %esp" } } */ | ||
379 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk_ecx" } } */ | ||
380 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
381 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
382 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
383 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
384 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-25.c b/gcc/testsuite/gcc.target/i386/ret-thunk-25.c | ||
385 | new file mode 100644 | ||
386 | index 0000000..f73553c | ||
387 | --- /dev/null | ||
388 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-25.c | ||
389 | @@ -0,0 +1,15 @@ | ||
390 | +/* PR target/r84530 */ | ||
391 | +/* { dg-do compile { target ia32 } } */ | ||
392 | +/* { dg-options "-O2 -mfunction-return=thunk -fcheck-pointer-bounds -mmpx -fno-pic" } */ | ||
393 | + | ||
394 | +struct s { _Complex unsigned short x; }; | ||
395 | +struct s gs = { 100 + 200i }; | ||
396 | +struct s __attribute__((noinline)) foo (void) { return gs; } | ||
397 | + | ||
398 | +/* { dg-final { scan-assembler-times "popl\[\\t \]*%ecx" 1 } } */ | ||
399 | +/* { dg-final { scan-assembler "lea\[l\]?\[\\t \]*4\\(%esp\\), %esp" } } */ | ||
400 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk_bnd_ecx" } } */ | ||
401 | +/* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
402 | +/* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
403 | +/* { dg-final { scan-assembler {\tpause} } } */ | ||
404 | +/* { dg-final { scan-assembler {\tlfence} } } */ | ||
405 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-26.c b/gcc/testsuite/gcc.target/i386/ret-thunk-26.c | ||
406 | new file mode 100644 | ||
407 | index 0000000..9144e98 | ||
408 | --- /dev/null | ||
409 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-26.c | ||
410 | @@ -0,0 +1,40 @@ | ||
411 | +/* PR target/r84530 */ | ||
412 | +/* { dg-do run } */ | ||
413 | +/* { dg-options "-Os -mfunction-return=thunk" } */ | ||
414 | + | ||
415 | +struct S { int i; }; | ||
416 | +__attribute__((const, noinline, noclone)) | ||
417 | +struct S foo (int x) | ||
418 | +{ | ||
419 | + struct S s; | ||
420 | + s.i = x; | ||
421 | + return s; | ||
422 | +} | ||
423 | + | ||
424 | +int a[2048], b[2048], c[2048], d[2048]; | ||
425 | +struct S e[2048]; | ||
426 | + | ||
427 | +__attribute__((noinline, noclone)) void | ||
428 | +bar (void) | ||
429 | +{ | ||
430 | + int i; | ||
431 | + for (i = 0; i < 1024; i++) | ||
432 | + { | ||
433 | + e[i] = foo (i); | ||
434 | + a[i+2] = a[i] + a[i+1]; | ||
435 | + b[10] = b[10] + i; | ||
436 | + c[i] = c[2047 - i]; | ||
437 | + d[i] = d[i + 1]; | ||
438 | + } | ||
439 | +} | ||
440 | + | ||
441 | +int | ||
442 | +main () | ||
443 | +{ | ||
444 | + int i; | ||
445 | + bar (); | ||
446 | + for (i = 0; i < 1024; i++) | ||
447 | + if (e[i].i != i) | ||
448 | + __builtin_abort (); | ||
449 | + return 0; | ||
450 | +} | ||
451 | -- | ||
452 | 2.7.4 | ||
453 | |||
diff --git a/meta/recipes-devtools/gcc/gcc-6.4/backport/0012-i386-Add-TARGET_INDIRECT_BRANCH_REGISTER.patch b/meta/recipes-devtools/gcc/gcc-6.4/backport/0012-i386-Add-TARGET_INDIRECT_BRANCH_REGISTER.patch new file mode 100644 index 0000000000..b50ac5cb02 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-6.4/backport/0012-i386-Add-TARGET_INDIRECT_BRANCH_REGISTER.patch | |||
@@ -0,0 +1,1004 @@ | |||
1 | From 7ba192d11a43d24ce427a3dfce0ad0592bd52830 Mon Sep 17 00:00:00 2001 | ||
2 | From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> | ||
3 | Date: Mon, 26 Feb 2018 17:00:46 +0000 | ||
4 | Subject: [PATCH 12/12] i386: Add TARGET_INDIRECT_BRANCH_REGISTER | ||
5 | |||
6 | For | ||
7 | |||
8 | --- | ||
9 | struct C { | ||
10 | virtual ~C(); | ||
11 | virtual void f(); | ||
12 | }; | ||
13 | |||
14 | void | ||
15 | f (C *p) | ||
16 | { | ||
17 | p->f(); | ||
18 | p->f(); | ||
19 | } | ||
20 | --- | ||
21 | |||
22 | -mindirect-branch=thunk-extern -O2 on x86-64 GNU/Linux generates: | ||
23 | |||
24 | _Z1fP1C: | ||
25 | .LFB0: | ||
26 | .cfi_startproc | ||
27 | pushq %rbx | ||
28 | .cfi_def_cfa_offset 16 | ||
29 | .cfi_offset 3, -16 | ||
30 | movq (%rdi), %rax | ||
31 | movq %rdi, %rbx | ||
32 | jmp .LIND1 | ||
33 | .LIND0: | ||
34 | pushq 16(%rax) | ||
35 | jmp __x86_indirect_thunk | ||
36 | .LIND1: | ||
37 | call .LIND0 | ||
38 | movq (%rbx), %rax | ||
39 | movq %rbx, %rdi | ||
40 | popq %rbx | ||
41 | .cfi_def_cfa_offset 8 | ||
42 | movq 16(%rax), %rax | ||
43 | jmp __x86_indirect_thunk_rax | ||
44 | .cfi_endproc | ||
45 | |||
46 | x86-64 is supposed to have asynchronous unwind tables by default, but | ||
47 | there is nothing that reflects the change in the (relative) frame | ||
48 | address after .LIND0. That region really has to be moved outside of | ||
49 | the .cfi_startproc/.cfi_endproc bracket. | ||
50 | |||
51 | This patch adds TARGET_INDIRECT_BRANCH_REGISTER to force indirect | ||
52 | branch via register whenever -mindirect-branch= is used. Now, | ||
53 | -mindirect-branch=thunk-extern -O2 on x86-64 GNU/Linux generates: | ||
54 | |||
55 | _Z1fP1C: | ||
56 | .LFB0: | ||
57 | .cfi_startproc | ||
58 | pushq %rbx | ||
59 | .cfi_def_cfa_offset 16 | ||
60 | .cfi_offset 3, -16 | ||
61 | movq (%rdi), %rax | ||
62 | movq %rdi, %rbx | ||
63 | movq 16(%rax), %rax | ||
64 | call __x86_indirect_thunk_rax | ||
65 | movq (%rbx), %rax | ||
66 | movq %rbx, %rdi | ||
67 | popq %rbx | ||
68 | .cfi_def_cfa_offset 8 | ||
69 | movq 16(%rax), %rax | ||
70 | jmp __x86_indirect_thunk_rax | ||
71 | .cfi_endproc | ||
72 | |||
73 | so that "-mindirect-branch=thunk-extern" is equivalent to | ||
74 | "-mindirect-branch=thunk-extern -mindirect-branch-register", which is | ||
75 | used by Linux kernel. | ||
76 | |||
77 | gcc/ | ||
78 | |||
79 | Backport from mainline | ||
80 | PR target/84039 | ||
81 | * config/i386/constraints.md (Bs): Replace | ||
82 | ix86_indirect_branch_register with | ||
83 | TARGET_INDIRECT_BRANCH_REGISTER. | ||
84 | (Bw): Likewise. | ||
85 | * config/i386/i386.md (indirect_jump): Likewise. | ||
86 | (tablejump): Likewise. | ||
87 | (*sibcall_memory): Likewise. | ||
88 | (*sibcall_value_memory): Likewise. | ||
89 | Peepholes of indirect call and jump via memory: Likewise. | ||
90 | (*sibcall_GOT_32): Disallowed for TARGET_INDIRECT_BRANCH_REGISTER. | ||
91 | (*sibcall_value_GOT_32): Likewise. | ||
92 | * config/i386/predicates.md (indirect_branch_operand): Likewise. | ||
93 | (GOT_memory_operand): Likewise. | ||
94 | (call_insn_operand): Likewise. | ||
95 | (sibcall_insn_operand): Likewise. | ||
96 | (GOT32_symbol_operand): Likewise. | ||
97 | * config/i386/i386.h (TARGET_INDIRECT_BRANCH_REGISTER): New. | ||
98 | |||
99 | gcc/testsuite/ | ||
100 | |||
101 | Backport from mainline | ||
102 | PR target/84039 | ||
103 | * gcc.target/i386/indirect-thunk-1.c: Updated. | ||
104 | * gcc.target/i386/indirect-thunk-2.c: Likewise. | ||
105 | * gcc.target/i386/indirect-thunk-3.c: Likewise. | ||
106 | * gcc.target/i386/indirect-thunk-4.c: Likewise. | ||
107 | * gcc.target/i386/indirect-thunk-5.c: Likewise. | ||
108 | * gcc.target/i386/indirect-thunk-6.c: Likewise. | ||
109 | * gcc.target/i386/indirect-thunk-7.c: Likewise. | ||
110 | * gcc.target/i386/indirect-thunk-attr-1.c: Likewise. | ||
111 | * gcc.target/i386/indirect-thunk-attr-2.c: Likewise. | ||
112 | * gcc.target/i386/indirect-thunk-attr-3.c: Likewise. | ||
113 | * gcc.target/i386/indirect-thunk-attr-4.c: Likewise. | ||
114 | * gcc.target/i386/indirect-thunk-attr-5.c: Likewise. | ||
115 | * gcc.target/i386/indirect-thunk-attr-6.c: Likewise. | ||
116 | * gcc.target/i386/indirect-thunk-attr-7.c: Likewise. | ||
117 | * gcc.target/i386/indirect-thunk-bnd-1.c: Likewise. | ||
118 | * gcc.target/i386/indirect-thunk-bnd-2.c: Likewise. | ||
119 | * gcc.target/i386/indirect-thunk-bnd-3.c: Likewise. | ||
120 | * gcc.target/i386/indirect-thunk-bnd-4.c: Likewise. | ||
121 | * gcc.target/i386/indirect-thunk-extern-1.c: Likewise. | ||
122 | * gcc.target/i386/indirect-thunk-extern-2.c: Likewise. | ||
123 | * gcc.target/i386/indirect-thunk-extern-3.c: Likewise. | ||
124 | * gcc.target/i386/indirect-thunk-extern-4.c: Likewise. | ||
125 | * gcc.target/i386/indirect-thunk-extern-5.c: Likewise. | ||
126 | * gcc.target/i386/indirect-thunk-extern-6.c: Likewise. | ||
127 | * gcc.target/i386/indirect-thunk-extern-7.c: Likewise. | ||
128 | * gcc.target/i386/indirect-thunk-inline-1.c: Likewise. | ||
129 | * gcc.target/i386/indirect-thunk-inline-2.c: Likewise. | ||
130 | * gcc.target/i386/indirect-thunk-inline-3.c: Likewise. | ||
131 | * gcc.target/i386/indirect-thunk-inline-4.c: Likewise. | ||
132 | * gcc.target/i386/indirect-thunk-inline-5.c: Likewise. | ||
133 | * gcc.target/i386/indirect-thunk-inline-6.c: Likewise. | ||
134 | * gcc.target/i386/indirect-thunk-inline-7.c: Likewise. | ||
135 | * gcc.target/i386/ret-thunk-9.c: Likewise. | ||
136 | * gcc.target/i386/ret-thunk-10.c: Likewise. | ||
137 | * gcc.target/i386/ret-thunk-11.c: Likewise. | ||
138 | * gcc.target/i386/ret-thunk-12.c: Likewise. | ||
139 | * gcc.target/i386/ret-thunk-13.c: Likewise. | ||
140 | * gcc.target/i386/ret-thunk-14.c: Likewise. | ||
141 | * gcc.target/i386/ret-thunk-15.c: Likewise. | ||
142 | |||
143 | Upstream-Status: Pending | ||
144 | |||
145 | Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> | ||
146 | |||
147 | --- | ||
148 | gcc/config/i386/constraints.md | 4 ++-- | ||
149 | gcc/config/i386/i386.h | 5 ++++ | ||
150 | gcc/config/i386/i386.md | 28 +++++++++++++--------- | ||
151 | gcc/config/i386/predicates.md | 6 ++--- | ||
152 | gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | 5 ++-- | ||
153 | gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | 5 ++-- | ||
154 | gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | 5 ++-- | ||
155 | gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | 5 ++-- | ||
156 | gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | 6 +++-- | ||
157 | gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | 12 ++++++---- | ||
158 | gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | 5 ++-- | ||
159 | .../gcc.target/i386/indirect-thunk-attr-1.c | 5 ++-- | ||
160 | .../gcc.target/i386/indirect-thunk-attr-2.c | 5 ++-- | ||
161 | .../gcc.target/i386/indirect-thunk-attr-3.c | 3 +-- | ||
162 | .../gcc.target/i386/indirect-thunk-attr-4.c | 3 +-- | ||
163 | .../gcc.target/i386/indirect-thunk-attr-5.c | 9 ++++--- | ||
164 | .../gcc.target/i386/indirect-thunk-attr-6.c | 9 ++++--- | ||
165 | .../gcc.target/i386/indirect-thunk-attr-7.c | 5 ++-- | ||
166 | .../gcc.target/i386/indirect-thunk-bnd-1.c | 6 ++--- | ||
167 | .../gcc.target/i386/indirect-thunk-bnd-2.c | 6 ++--- | ||
168 | .../gcc.target/i386/indirect-thunk-bnd-3.c | 5 ++-- | ||
169 | .../gcc.target/i386/indirect-thunk-bnd-4.c | 7 +++--- | ||
170 | .../gcc.target/i386/indirect-thunk-extern-1.c | 5 ++-- | ||
171 | .../gcc.target/i386/indirect-thunk-extern-2.c | 5 ++-- | ||
172 | .../gcc.target/i386/indirect-thunk-extern-3.c | 9 ++++--- | ||
173 | .../gcc.target/i386/indirect-thunk-extern-4.c | 6 ++--- | ||
174 | .../gcc.target/i386/indirect-thunk-extern-5.c | 6 +++-- | ||
175 | .../gcc.target/i386/indirect-thunk-extern-6.c | 8 +++---- | ||
176 | .../gcc.target/i386/indirect-thunk-extern-7.c | 5 ++-- | ||
177 | .../gcc.target/i386/indirect-thunk-inline-1.c | 2 +- | ||
178 | .../gcc.target/i386/indirect-thunk-inline-2.c | 2 +- | ||
179 | .../gcc.target/i386/indirect-thunk-inline-3.c | 2 +- | ||
180 | .../gcc.target/i386/indirect-thunk-inline-4.c | 2 +- | ||
181 | .../gcc.target/i386/indirect-thunk-inline-5.c | 3 ++- | ||
182 | .../gcc.target/i386/indirect-thunk-inline-6.c | 3 ++- | ||
183 | .../gcc.target/i386/indirect-thunk-inline-7.c | 4 ++-- | ||
184 | gcc/testsuite/gcc.target/i386/ret-thunk-10.c | 9 +++---- | ||
185 | gcc/testsuite/gcc.target/i386/ret-thunk-11.c | 9 +++---- | ||
186 | gcc/testsuite/gcc.target/i386/ret-thunk-12.c | 8 +++---- | ||
187 | gcc/testsuite/gcc.target/i386/ret-thunk-13.c | 5 ++-- | ||
188 | gcc/testsuite/gcc.target/i386/ret-thunk-14.c | 7 +++--- | ||
189 | gcc/testsuite/gcc.target/i386/ret-thunk-15.c | 7 +++--- | ||
190 | gcc/testsuite/gcc.target/i386/ret-thunk-9.c | 13 ++++------ | ||
191 | 43 files changed, 128 insertions(+), 141 deletions(-) | ||
192 | |||
193 | diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md | ||
194 | index 9204c8e..ef684a9 100644 | ||
195 | --- a/gcc/config/i386/constraints.md | ||
196 | +++ b/gcc/config/i386/constraints.md | ||
197 | @@ -172,7 +172,7 @@ | ||
198 | |||
199 | (define_constraint "Bs" | ||
200 | "@internal Sibcall memory operand." | ||
201 | - (ior (and (not (match_test "ix86_indirect_branch_register")) | ||
202 | + (ior (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER")) | ||
203 | (not (match_test "TARGET_X32")) | ||
204 | (match_operand 0 "sibcall_memory_operand")) | ||
205 | (and (match_test "TARGET_X32 && Pmode == DImode") | ||
206 | @@ -180,7 +180,7 @@ | ||
207 | |||
208 | (define_constraint "Bw" | ||
209 | "@internal Call memory operand." | ||
210 | - (ior (and (not (match_test "ix86_indirect_branch_register")) | ||
211 | + (ior (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER")) | ||
212 | (not (match_test "TARGET_X32")) | ||
213 | (match_operand 0 "memory_operand")) | ||
214 | (and (match_test "TARGET_X32 && Pmode == DImode") | ||
215 | diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h | ||
216 | index b34bc11..1816d71 100644 | ||
217 | --- a/gcc/config/i386/i386.h | ||
218 | +++ b/gcc/config/i386/i386.h | ||
219 | @@ -2676,6 +2676,11 @@ extern void debug_dispatch_window (int); | ||
220 | #define TARGET_RECIP_VEC_DIV ((recip_mask & RECIP_MASK_VEC_DIV) != 0) | ||
221 | #define TARGET_RECIP_VEC_SQRT ((recip_mask & RECIP_MASK_VEC_SQRT) != 0) | ||
222 | |||
223 | + | ||
224 | +#define TARGET_INDIRECT_BRANCH_REGISTER \ | ||
225 | + (ix86_indirect_branch_register \ | ||
226 | + || cfun->machine->indirect_branch_type != indirect_branch_keep) | ||
227 | + | ||
228 | #define IX86_HLE_ACQUIRE (1 << 16) | ||
229 | #define IX86_HLE_RELEASE (1 << 17) | ||
230 | |||
231 | diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md | ||
232 | index 857466a..6a6dc26 100644 | ||
233 | --- a/gcc/config/i386/i386.md | ||
234 | +++ b/gcc/config/i386/i386.md | ||
235 | @@ -11805,7 +11805,7 @@ | ||
236 | [(set (pc) (match_operand 0 "indirect_branch_operand"))] | ||
237 | "" | ||
238 | { | ||
239 | - if (TARGET_X32 || ix86_indirect_branch_register) | ||
240 | + if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER) | ||
241 | operands[0] = convert_memory_address (word_mode, operands[0]); | ||
242 | cfun->machine->has_local_indirect_jump = true; | ||
243 | }) | ||
244 | @@ -11859,7 +11859,7 @@ | ||
245 | OPTAB_DIRECT); | ||
246 | } | ||
247 | |||
248 | - if (TARGET_X32 || ix86_indirect_branch_register) | ||
249 | + if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER) | ||
250 | operands[0] = convert_memory_address (word_mode, operands[0]); | ||
251 | cfun->machine->has_local_indirect_jump = true; | ||
252 | }) | ||
253 | @@ -12029,7 +12029,10 @@ | ||
254 | (match_operand:SI 0 "register_no_elim_operand" "U") | ||
255 | (match_operand:SI 1 "GOT32_symbol_operand")))) | ||
256 | (match_operand 2))] | ||
257 | - "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)" | ||
258 | + "!TARGET_MACHO | ||
259 | + && !TARGET_64BIT | ||
260 | + && !TARGET_INDIRECT_BRANCH_REGISTER | ||
261 | + && SIBLING_CALL_P (insn)" | ||
262 | { | ||
263 | rtx fnaddr = gen_rtx_PLUS (Pmode, operands[0], operands[1]); | ||
264 | fnaddr = gen_const_mem (Pmode, fnaddr); | ||
265 | @@ -12048,7 +12051,7 @@ | ||
266 | [(call (mem:QI (match_operand:W 0 "memory_operand" "m")) | ||
267 | (match_operand 1)) | ||
268 | (unspec [(const_int 0)] UNSPEC_PEEPSIB)] | ||
269 | - "!TARGET_X32 && !ix86_indirect_branch_register" | ||
270 | + "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER" | ||
271 | "* return ix86_output_call_insn (insn, operands[0]);" | ||
272 | [(set_attr "type" "call")]) | ||
273 | |||
274 | @@ -12058,7 +12061,7 @@ | ||
275 | (call (mem:QI (match_dup 0)) | ||
276 | (match_operand 3))] | ||
277 | "!TARGET_X32 | ||
278 | - && !ix86_indirect_branch_register | ||
279 | + && !TARGET_INDIRECT_BRANCH_REGISTER | ||
280 | && SIBLING_CALL_P (peep2_next_insn (1)) | ||
281 | && !reg_mentioned_p (operands[0], | ||
282 | CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" | ||
283 | @@ -12073,7 +12076,7 @@ | ||
284 | (call (mem:QI (match_dup 0)) | ||
285 | (match_operand 3))] | ||
286 | "!TARGET_X32 | ||
287 | - && !ix86_indirect_branch_register | ||
288 | + && !TARGET_INDIRECT_BRANCH_REGISTER | ||
289 | && SIBLING_CALL_P (peep2_next_insn (2)) | ||
290 | && !reg_mentioned_p (operands[0], | ||
291 | CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" | ||
292 | @@ -12171,7 +12174,7 @@ | ||
293 | (match_operand:W 1 "memory_operand")) | ||
294 | (set (pc) (match_dup 0))] | ||
295 | "!TARGET_X32 | ||
296 | - && !ix86_indirect_branch_register | ||
297 | + && !TARGET_INDIRECT_BRANCH_REGISTER | ||
298 | && peep2_reg_dead_p (2, operands[0])" | ||
299 | [(set (pc) (match_dup 1))]) | ||
300 | |||
301 | @@ -12229,7 +12232,10 @@ | ||
302 | (match_operand:SI 1 "register_no_elim_operand" "U") | ||
303 | (match_operand:SI 2 "GOT32_symbol_operand")))) | ||
304 | (match_operand 3)))] | ||
305 | - "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)" | ||
306 | + "!TARGET_MACHO | ||
307 | + && !TARGET_64BIT | ||
308 | + && !TARGET_INDIRECT_BRANCH_REGISTER | ||
309 | + && SIBLING_CALL_P (insn)" | ||
310 | { | ||
311 | rtx fnaddr = gen_rtx_PLUS (Pmode, operands[1], operands[2]); | ||
312 | fnaddr = gen_const_mem (Pmode, fnaddr); | ||
313 | @@ -12250,7 +12256,7 @@ | ||
314 | (call (mem:QI (match_operand:W 1 "memory_operand" "m")) | ||
315 | (match_operand 2))) | ||
316 | (unspec [(const_int 0)] UNSPEC_PEEPSIB)] | ||
317 | - "!TARGET_X32 && !ix86_indirect_branch_register" | ||
318 | + "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER" | ||
319 | "* return ix86_output_call_insn (insn, operands[1]);" | ||
320 | [(set_attr "type" "callv")]) | ||
321 | |||
322 | @@ -12261,7 +12267,7 @@ | ||
323 | (call (mem:QI (match_dup 0)) | ||
324 | (match_operand 3)))] | ||
325 | "!TARGET_X32 | ||
326 | - && !ix86_indirect_branch_register | ||
327 | + && !TARGET_INDIRECT_BRANCH_REGISTER | ||
328 | && SIBLING_CALL_P (peep2_next_insn (1)) | ||
329 | && !reg_mentioned_p (operands[0], | ||
330 | CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" | ||
331 | @@ -12278,7 +12284,7 @@ | ||
332 | (call (mem:QI (match_dup 0)) | ||
333 | (match_operand 3)))] | ||
334 | "!TARGET_X32 | ||
335 | - && !ix86_indirect_branch_register | ||
336 | + && !TARGET_INDIRECT_BRANCH_REGISTER | ||
337 | && SIBLING_CALL_P (peep2_next_insn (2)) | ||
338 | && !reg_mentioned_p (operands[0], | ||
339 | CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" | ||
340 | diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md | ||
341 | index d1f0a7d..5f8a98f 100644 | ||
342 | --- a/gcc/config/i386/predicates.md | ||
343 | +++ b/gcc/config/i386/predicates.md | ||
344 | @@ -593,7 +593,7 @@ | ||
345 | ;; Test for a valid operand for indirect branch. | ||
346 | (define_predicate "indirect_branch_operand" | ||
347 | (ior (match_operand 0 "register_operand") | ||
348 | - (and (not (match_test "ix86_indirect_branch_register")) | ||
349 | + (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER")) | ||
350 | (not (match_test "TARGET_X32")) | ||
351 | (match_operand 0 "memory_operand")))) | ||
352 | |||
353 | @@ -637,7 +637,7 @@ | ||
354 | (ior (match_test "constant_call_address_operand | ||
355 | (op, mode == VOIDmode ? mode : Pmode)") | ||
356 | (match_operand 0 "call_register_no_elim_operand") | ||
357 | - (and (not (match_test "ix86_indirect_branch_register")) | ||
358 | + (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER")) | ||
359 | (ior (and (not (match_test "TARGET_X32")) | ||
360 | (match_operand 0 "memory_operand")) | ||
361 | (and (match_test "TARGET_X32 && Pmode == DImode") | ||
362 | @@ -648,7 +648,7 @@ | ||
363 | (ior (match_test "constant_call_address_operand | ||
364 | (op, mode == VOIDmode ? mode : Pmode)") | ||
365 | (match_operand 0 "register_no_elim_operand") | ||
366 | - (and (not (match_test "ix86_indirect_branch_register")) | ||
367 | + (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER")) | ||
368 | (ior (and (not (match_test "TARGET_X32")) | ||
369 | (match_operand 0 "sibcall_memory_operand")) | ||
370 | (and (match_test "TARGET_X32 && Pmode == DImode") | ||
371 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | ||
372 | index 60d0988..6e94d2c 100644 | ||
373 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | ||
374 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c | ||
375 | @@ -11,9 +11,8 @@ male_indirect_jump (long offset) | ||
376 | dispatch(offset); | ||
377 | } | ||
378 | |||
379 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
380 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
381 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
382 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ | ||
383 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
384 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
385 | /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
386 | /* { dg-final { scan-assembler {\tpause} } } */ | ||
387 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | ||
388 | index aac7516..3c46707 100644 | ||
389 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | ||
390 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c | ||
391 | @@ -11,9 +11,8 @@ male_indirect_jump (long offset) | ||
392 | dispatch[offset](offset); | ||
393 | } | ||
394 | |||
395 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
396 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
397 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
398 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ | ||
399 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
400 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
401 | /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
402 | /* { dg-final { scan-assembler {\tpause} } } */ | ||
403 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | ||
404 | index 9e24a38..2c7fb52 100644 | ||
405 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | ||
406 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c | ||
407 | @@ -12,9 +12,8 @@ male_indirect_jump (long offset) | ||
408 | return 0; | ||
409 | } | ||
410 | |||
411 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
412 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
413 | -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
414 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ | ||
415 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
416 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
417 | /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
418 | /* { dg-final { scan-assembler {\tpause} } } */ | ||
419 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | ||
420 | index 127b5d9..0d3f895 100644 | ||
421 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | ||
422 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c | ||
423 | @@ -12,9 +12,8 @@ male_indirect_jump (long offset) | ||
424 | return 0; | ||
425 | } | ||
426 | |||
427 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
428 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
429 | -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
430 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ | ||
431 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
432 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
433 | /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
434 | /* { dg-final { scan-assembler {\tpause} } } */ | ||
435 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | ||
436 | index fcaa18d..fb26c00 100644 | ||
437 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | ||
438 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c | ||
439 | @@ -9,8 +9,10 @@ foo (void) | ||
440 | bar (); | ||
441 | } | ||
442 | |||
443 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ | ||
444 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ | ||
445 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */ | ||
446 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target x32 } } } */ | ||
447 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */ | ||
448 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { ! x32 } } } } */ | ||
449 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
450 | /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
451 | /* { dg-final { scan-assembler {\tpause} } } */ | ||
452 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | ||
453 | index e464928..aa03fbd 100644 | ||
454 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | ||
455 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c | ||
456 | @@ -10,9 +10,13 @@ foo (void) | ||
457 | return 0; | ||
458 | } | ||
459 | |||
460 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ | ||
461 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ | ||
462 | -/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ | ||
463 | -/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ | ||
464 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */ | ||
465 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target x32 } } } */ | ||
466 | +/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 { target x32 } } } */ | ||
467 | +/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 { target x32 } } } */ | ||
468 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */ | ||
469 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { ! x32 } } } } */ | ||
470 | +/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
471 | +/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
472 | /* { dg-final { scan-assembler {\tpause} } } */ | ||
473 | /* { dg-final { scan-assembler {\tlfence} } } */ | ||
474 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | ||
475 | index 17c2d0f..3c72036 100644 | ||
476 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | ||
477 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c | ||
478 | @@ -35,9 +35,8 @@ bar (int i) | ||
479 | } | ||
480 | } | ||
481 | |||
482 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */ | ||
483 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
484 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
485 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */ | ||
486 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
487 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
488 | /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
489 | /* { dg-final { scan-assembler {\tpause} } } */ | ||
490 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | ||
491 | index 9194ccf..7106407 100644 | ||
492 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | ||
493 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c | ||
494 | @@ -14,9 +14,8 @@ male_indirect_jump (long offset) | ||
495 | dispatch(offset); | ||
496 | } | ||
497 | |||
498 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
499 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
500 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
501 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ | ||
502 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
503 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
504 | /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
505 | /* { dg-final { scan-assembler {\tpause} } } */ | ||
506 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | ||
507 | index e51f261..27c7e5b 100644 | ||
508 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | ||
509 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c | ||
510 | @@ -12,9 +12,8 @@ male_indirect_jump (long offset) | ||
511 | dispatch[offset](offset); | ||
512 | } | ||
513 | |||
514 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
515 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
516 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
517 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ | ||
518 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
519 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
520 | /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
521 | /* { dg-final { scan-assembler {\tpause} } } */ | ||
522 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | ||
523 | index 4aeec18..89a2bac 100644 | ||
524 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | ||
525 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c | ||
526 | @@ -14,10 +14,9 @@ male_indirect_jump (long offset) | ||
527 | return 0; | ||
528 | } | ||
529 | |||
530 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
531 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ | ||
532 | /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ | ||
533 | /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ | ||
534 | /* { dg-final { scan-assembler {\tpause} } } */ | ||
535 | /* { dg-final { scan-assembler {\tlfence} } } */ | ||
536 | /* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ | ||
537 | -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
538 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | ||
539 | index ac0e599..3eb83c3 100644 | ||
540 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | ||
541 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c | ||
542 | @@ -13,10 +13,9 @@ male_indirect_jump (long offset) | ||
543 | return 0; | ||
544 | } | ||
545 | |||
546 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
547 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ | ||
548 | /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ | ||
549 | /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ | ||
550 | /* { dg-final { scan-assembler {\tpause} } } */ | ||
551 | /* { dg-final { scan-assembler {\tlfence} } } */ | ||
552 | /* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */ | ||
553 | -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
554 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | ||
555 | index 573cf1e..0098dd1 100644 | ||
556 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | ||
557 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c | ||
558 | @@ -14,9 +14,8 @@ male_indirect_jump (long offset) | ||
559 | return 0; | ||
560 | } | ||
561 | |||
562 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
563 | -/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
564 | -/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
565 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
566 | -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
567 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ | ||
568 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
569 | /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
570 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ | ||
571 | +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ | ||
572 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | ||
573 | index b2b37fc..ece8de1 100644 | ||
574 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | ||
575 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c | ||
576 | @@ -13,9 +13,8 @@ male_indirect_jump (long offset) | ||
577 | return 0; | ||
578 | } | ||
579 | |||
580 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
581 | -/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
582 | -/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
583 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
584 | -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
585 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ | ||
586 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
587 | /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
588 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ | ||
589 | +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ | ||
590 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | ||
591 | index 4a43e19..d53fc88 100644 | ||
592 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | ||
593 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c | ||
594 | @@ -36,9 +36,8 @@ bar (int i) | ||
595 | } | ||
596 | } | ||
597 | |||
598 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */ | ||
599 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
600 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ | ||
601 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */ | ||
602 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
603 | /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
604 | /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ | ||
605 | /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ | ||
606 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | ||
607 | index ac84ab6..73d16ba 100644 | ||
608 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | ||
609 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c | ||
610 | @@ -10,9 +10,9 @@ foo (void) | ||
611 | dispatch (buf); | ||
612 | } | ||
613 | |||
614 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
615 | -/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ | ||
616 | -/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ | ||
617 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ | ||
618 | +/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd_rax" { target lp64 } } } */ | ||
619 | +/* { dg-final { scan-assembler "bnd call\[ \t\]*__x86_indirect_thunk_bnd_eax" { target ia32 } } } */ | ||
620 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
621 | /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ | ||
622 | /* { dg-final { scan-assembler "bnd ret" } } */ | ||
623 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | ||
624 | index ce655e8..856751a 100644 | ||
625 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | ||
626 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c | ||
627 | @@ -11,10 +11,8 @@ foo (void) | ||
628 | return 0; | ||
629 | } | ||
630 | |||
631 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
632 | -/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */ | ||
633 | -/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ | ||
634 | -/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */ | ||
635 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ | ||
636 | +/* { dg-final { scan-assembler "bnd call\[ \t\]*__x86_indirect_thunk_bnd_(r|e)ax" } } */ | ||
637 | /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ | ||
638 | /* { dg-final { scan-assembler "bnd ret" } } */ | ||
639 | /* { dg-final { scan-assembler {\tpause} } } */ | ||
640 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | ||
641 | index d34485a..42312f6 100644 | ||
642 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | ||
643 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c | ||
644 | @@ -10,8 +10,9 @@ foo (void) | ||
645 | bar (buf); | ||
646 | } | ||
647 | |||
648 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ | ||
649 | -/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */ | ||
650 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" } } */ | ||
651 | +/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd_rax" { target lp64 } } } */ | ||
652 | +/* { dg-final { scan-assembler "bnd call\[ \t\]*__x86_indirect_thunk_bnd_eax" { target ia32 } } } */ | ||
653 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
654 | /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */ | ||
655 | /* { dg-final { scan-assembler "bnd ret" } } */ | ||
656 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | ||
657 | index 0e19830..c8ca102 100644 | ||
658 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | ||
659 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c | ||
660 | @@ -11,10 +11,9 @@ foo (void) | ||
661 | return 0; | ||
662 | } | ||
663 | |||
664 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ | ||
665 | -/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk" } } */ | ||
666 | -/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */ | ||
667 | -/* { dg-final { scan-assembler-times "bnd call\[ \t\]*\.LIND" 2 } } */ | ||
668 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" } } */ | ||
669 | +/* { dg-final { scan-assembler "bnd call\[ \t\]*__x86_indirect_thunk_bnd_(r|e)ax" } } */ | ||
670 | +/* { dg-final { scan-assembler-times "bnd call\[ \t\]*\.LIND" 1 } } */ | ||
671 | /* { dg-final { scan-assembler "bnd ret" } } */ | ||
672 | /* { dg-final { scan-assembler {\tpause} } } */ | ||
673 | /* { dg-final { scan-assembler {\tlfence} } } */ | ||
674 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | ||
675 | index 579441f..c09dd0a 100644 | ||
676 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | ||
677 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c | ||
678 | @@ -11,9 +11,8 @@ male_indirect_jump (long offset) | ||
679 | dispatch(offset); | ||
680 | } | ||
681 | |||
682 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
683 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
684 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
685 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ | ||
686 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
687 | /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
688 | /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ | ||
689 | /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ | ||
690 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | ||
691 | index c92e6f2..826425a 100644 | ||
692 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | ||
693 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c | ||
694 | @@ -11,9 +11,8 @@ male_indirect_jump (long offset) | ||
695 | dispatch[offset](offset); | ||
696 | } | ||
697 | |||
698 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
699 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
700 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
701 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ | ||
702 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
703 | /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
704 | /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ | ||
705 | /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ | ||
706 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | ||
707 | index d9964c2..3856268 100644 | ||
708 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | ||
709 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c | ||
710 | @@ -12,9 +12,8 @@ male_indirect_jump (long offset) | ||
711 | return 0; | ||
712 | } | ||
713 | |||
714 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
715 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
716 | -/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
717 | -/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
718 | -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
719 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ | ||
720 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
721 | /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
722 | +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ | ||
723 | +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ | ||
724 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | ||
725 | index d4dca4d..1ae49b1 100644 | ||
726 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | ||
727 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c | ||
728 | @@ -12,9 +12,7 @@ male_indirect_jump (long offset) | ||
729 | return 0; | ||
730 | } | ||
731 | |||
732 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
733 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
734 | -/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
735 | -/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */ | ||
736 | /* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
737 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ | ||
738 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
739 | /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
740 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | ||
741 | index 5c07e02..5328239 100644 | ||
742 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | ||
743 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c | ||
744 | @@ -9,8 +9,10 @@ foo (void) | ||
745 | bar (); | ||
746 | } | ||
747 | |||
748 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ | ||
749 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ | ||
750 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */ | ||
751 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target x32 } } } */ | ||
752 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */ | ||
753 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { ! x32 } } } } */ | ||
754 | /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
755 | /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ | ||
756 | /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ | ||
757 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | ||
758 | index 3eb4406..8ae4348 100644 | ||
759 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | ||
760 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c | ||
761 | @@ -10,8 +10,8 @@ foo (void) | ||
762 | return 0; | ||
763 | } | ||
764 | |||
765 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ | ||
766 | -/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */ | ||
767 | -/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */ | ||
768 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */ | ||
769 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */ | ||
770 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target x32 } } } */ | ||
771 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */ | ||
772 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { ! x32 } } } } */ | ||
773 | /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
774 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | ||
775 | index aece938..2b9a33e 100644 | ||
776 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | ||
777 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c | ||
778 | @@ -35,9 +35,8 @@ bar (int i) | ||
779 | } | ||
780 | } | ||
781 | |||
782 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */ | ||
783 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
784 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
785 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */ | ||
786 | +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
787 | /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */ | ||
788 | /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */ | ||
789 | /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */ | ||
790 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | ||
791 | index 3aba5e8..869d904 100644 | ||
792 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | ||
793 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c | ||
794 | @@ -11,7 +11,7 @@ male_indirect_jump (long offset) | ||
795 | dispatch(offset); | ||
796 | } | ||
797 | |||
798 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
799 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ | ||
800 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
801 | /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
802 | /* { dg-final { scan-assembler {\tpause} } } */ | ||
803 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | ||
804 | index 0f0181d..c5c16ed 100644 | ||
805 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | ||
806 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c | ||
807 | @@ -11,7 +11,7 @@ male_indirect_jump (long offset) | ||
808 | dispatch[offset](offset); | ||
809 | } | ||
810 | |||
811 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
812 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ | ||
813 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
814 | /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
815 | /* { dg-final { scan-assembler {\tpause} } } */ | ||
816 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | ||
817 | index 2eef6f3..4a63ebe 100644 | ||
818 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | ||
819 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c | ||
820 | @@ -12,7 +12,7 @@ male_indirect_jump (long offset) | ||
821 | return 0; | ||
822 | } | ||
823 | |||
824 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
825 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ | ||
826 | /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ | ||
827 | /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ | ||
828 | /* { dg-final { scan-assembler-times {\tpause} 1 } } */ | ||
829 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | ||
830 | index e825a10..a395ffc 100644 | ||
831 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | ||
832 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c | ||
833 | @@ -12,7 +12,7 @@ male_indirect_jump (long offset) | ||
834 | return 0; | ||
835 | } | ||
836 | |||
837 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */ | ||
838 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */ | ||
839 | /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ | ||
840 | /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ | ||
841 | /* { dg-final { scan-assembler-times {\tpause} 1 } } */ | ||
842 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | ||
843 | index c6d77e1..21cbfd3 100644 | ||
844 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | ||
845 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c | ||
846 | @@ -9,7 +9,8 @@ foo (void) | ||
847 | bar (); | ||
848 | } | ||
849 | |||
850 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ | ||
851 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */ | ||
852 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */ | ||
853 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
854 | /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
855 | /* { dg-final { scan-assembler {\tpause} } } */ | ||
856 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | ||
857 | index 6454827..d1300f1 100644 | ||
858 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | ||
859 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c | ||
860 | @@ -10,7 +10,8 @@ foo (void) | ||
861 | return 0; | ||
862 | } | ||
863 | |||
864 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */ | ||
865 | +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */ | ||
866 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */ | ||
867 | /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */ | ||
868 | /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */ | ||
869 | /* { dg-final { scan-assembler-times {\tpause} 1 } } */ | ||
870 | diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | ||
871 | index c67066c..ea00924 100644 | ||
872 | --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | ||
873 | +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c | ||
874 | @@ -35,8 +35,8 @@ bar (int i) | ||
875 | } | ||
876 | } | ||
877 | |||
878 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */ | ||
879 | -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
880 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */ | ||
881 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%(r|e)ax" } } */ | ||
882 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
883 | /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
884 | /* { dg-final { scan-assembler {\tpause} } } */ | ||
885 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c | ||
886 | index e6fea84..af9023a 100644 | ||
887 | --- a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c | ||
888 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c | ||
889 | @@ -15,9 +15,6 @@ foo (void) | ||
890 | /* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ | ||
891 | /* { dg-final { scan-assembler-times {\tpause} 2 } } */ | ||
892 | /* { dg-final { scan-assembler-times {\tlfence} 2 } } */ | ||
893 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ | ||
894 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
895 | -/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */ | ||
896 | -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ | ||
897 | -/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */ | ||
898 | -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
899 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
900 | +/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" } } */ | ||
901 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ | ||
902 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c | ||
903 | index e239ec4..ba467c5 100644 | ||
904 | --- a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c | ||
905 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c | ||
906 | @@ -15,9 +15,6 @@ foo (void) | ||
907 | /* { dg-final { scan-assembler-times {\tlfence} 1 } } */ | ||
908 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
909 | /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
910 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ | ||
911 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
912 | -/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */ | ||
913 | -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ | ||
914 | -/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */ | ||
915 | -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
916 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
917 | +/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" } } */ | ||
918 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ | ||
919 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c | ||
920 | index fa31813..43e57ca 100644 | ||
921 | --- a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c | ||
922 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c | ||
923 | @@ -15,8 +15,6 @@ foo (void) | ||
924 | /* { dg-final { scan-assembler-times {\tlfence} 1 } } */ | ||
925 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
926 | /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
927 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
928 | -/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } } } } */ | ||
929 | -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ | ||
930 | -/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } } } } */ | ||
931 | -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
932 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
933 | +/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" } } */ | ||
934 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ | ||
935 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c | ||
936 | index fd5b41f..55f156c 100644 | ||
937 | --- a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c | ||
938 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c | ||
939 | @@ -14,9 +14,8 @@ foo (void) | ||
940 | /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */ | ||
941 | /* { dg-final { scan-assembler-times {\tpause} 2 } } */ | ||
942 | /* { dg-final { scan-assembler-times {\tlfence} 2 } } */ | ||
943 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ | ||
944 | /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 3 } } */ | ||
945 | /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 3 } } */ | ||
946 | /* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_indirect_thunk" } } */ | ||
947 | -/* { dg-final { scan-assembler-not "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ | ||
948 | -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
949 | +/* { dg-final { scan-assembler-not "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
950 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ | ||
951 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c | ||
952 | index d606373..1c79043 100644 | ||
953 | --- a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c | ||
954 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c | ||
955 | @@ -16,7 +16,6 @@ foo (void) | ||
956 | /* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */ | ||
957 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
958 | /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
959 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ | ||
960 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
961 | -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ | ||
962 | -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
963 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?bar" { target *-*-linux* } } } */ | ||
964 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
965 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ | ||
966 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c | ||
967 | index 75e45e2..58aba31 100644 | ||
968 | --- a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c | ||
969 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c | ||
970 | @@ -16,7 +16,6 @@ foo (void) | ||
971 | /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
972 | /* { dg-final { scan-assembler-times {\tpause} 1 } } */ | ||
973 | /* { dg-final { scan-assembler-times {\tlfence} 1 } } */ | ||
974 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ | ||
975 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
976 | -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */ | ||
977 | -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
978 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?bar" { target *-*-linux* } } } */ | ||
979 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
980 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ | ||
981 | diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c | ||
982 | index d1db41c..d2df8b8 100644 | ||
983 | --- a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c | ||
984 | +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c | ||
985 | @@ -14,11 +14,8 @@ foo (void) | ||
986 | /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */ | ||
987 | /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */ | ||
988 | /* { dg-final { scan-assembler "__x86_indirect_thunk:" } } */ | ||
989 | -/* { dg-final { scan-assembler-times {\tpause} 1 { target { ! x32 } } } } */ | ||
990 | -/* { dg-final { scan-assembler-times {\tlfence} 1 { target { ! x32 } } } } */ | ||
991 | -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */ | ||
992 | -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */ | ||
993 | -/* { dg-final { scan-assembler-times {\tpause} 2 { target { x32 } } } } */ | ||
994 | -/* { dg-final { scan-assembler-times {\tlfence} 2 { target { x32 } } } } */ | ||
995 | -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */ | ||
996 | -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */ | ||
997 | +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?bar" { target *-*-linux* } } } */ | ||
998 | +/* { dg-final { scan-assembler-times {\tpause} 2 } } */ | ||
999 | +/* { dg-final { scan-assembler-times {\tlfence} 2 } } */ | ||
1000 | +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */ | ||
1001 | +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */ | ||
1002 | -- | ||
1003 | 2.7.4 | ||
1004 | |||