]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/s390/s390.c
Add a apply_pass_by_reference_rules helper
[thirdparty/gcc.git] / gcc / config / s390 / s390.c
CommitLineData
4673c1a0 1/* Subroutines used for code generation on IBM S/390 and zSeries
fbd26352 2 Copyright (C) 1999-2019 Free Software Foundation, Inc.
4673c1a0 3 Contributed by Hartmut Penner (hpenner@de.ibm.com) and
e68d6a13 4 Ulrich Weigand (uweigand@de.ibm.com) and
5 Andreas Krebbel (Andreas.Krebbel@de.ibm.com).
4673c1a0 6
1e98c8f3 7This file is part of GCC.
4673c1a0 8
1e98c8f3 9GCC is free software; you can redistribute it and/or modify it under
10the terms of the GNU General Public License as published by the Free
038d1e19 11Software Foundation; either version 3, or (at your option) any later
1e98c8f3 12version.
4673c1a0 13
1e98c8f3 14GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15WARRANTY; without even the implied warranty of MERCHANTABILITY or
16FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17for more details.
4673c1a0 18
19You should have received a copy of the GNU General Public License
038d1e19 20along with GCC; see the file COPYING3. If not see
21<http://www.gnu.org/licenses/>. */
4673c1a0 22
785790dc 23#define IN_TARGET_CODE 1
24
4673c1a0 25#include "config.h"
4673c1a0 26#include "system.h"
805e22b2 27#include "coretypes.h"
9ef16211 28#include "backend.h"
c1eb80de 29#include "target.h"
7a0cee35 30#include "target-globals.h"
c1eb80de 31#include "rtl.h"
9ef16211 32#include "tree.h"
33#include "gimple.h"
c1eb80de 34#include "cfghooks.h"
35#include "cfgloop.h"
9ef16211 36#include "df.h"
ad7b10a2 37#include "memmodel.h"
c1eb80de 38#include "tm_p.h"
39#include "stringpool.h"
30a86690 40#include "attribs.h"
c1eb80de 41#include "expmed.h"
42#include "optabs.h"
43#include "regs.h"
44#include "emit-rtl.h"
45#include "recog.h"
46#include "cgraph.h"
47#include "diagnostic-core.h"
7a0cee35 48#include "diagnostic.h"
b20a8bb4 49#include "alias.h"
b20a8bb4 50#include "fold-const.h"
9ed99284 51#include "print-tree.h"
9ed99284 52#include "stor-layout.h"
53#include "varasm.h"
54#include "calls.h"
4673c1a0 55#include "conditions.h"
56#include "output.h"
57#include "insn-attr.h"
58#include "flags.h"
59#include "except.h"
d53441c8 60#include "dojump.h"
61#include "explow.h"
d53441c8 62#include "stmt.h"
4673c1a0 63#include "expr.h"
c10847b9 64#include "reload.h"
94ea8568 65#include "cfgrtl.h"
66#include "cfganal.h"
67#include "lcm.h"
68#include "cfgbuild.h"
69#include "cfgcleanup.h"
7baa5366 70#include "debug.h"
a1f71e15 71#include "langhooks.h"
bc61cadb 72#include "internal-fn.h"
73#include "gimple-fold.h"
74#include "tree-eh.h"
a8783bee 75#include "gimplify.h"
c0717306 76#include "params.h"
fba5dd52 77#include "opts.h"
0b8be04c 78#include "tree-pass.h"
79#include "context.h"
f7715905 80#include "builtins.h"
15e472ec 81#include "rtl-iter.h"
76a4c804 82#include "intl.h"
80fc7f56 83#include "tm-constrs.h"
d5a90e99 84#include "tree-vrp.h"
85#include "symbol-summary.h"
86#include "ipa-prop.h"
87#include "ipa-fnsummary.h"
b3041173 88#include "sched-int.h"
4673c1a0 89
0c71fb4f 90/* This file should be included last. */
4b498588 91#include "target-def.h"
92
b395382f 93static bool s390_hard_regno_mode_ok (unsigned int, machine_mode);
94
7a0cee35 95/* Remember the last target of s390_set_current_function. */
96static GTY(()) tree s390_previous_fndecl;
97
18925d38 98/* Define the specific costs for a given cpu. */
99
ffead1ca 100struct processor_costs
18925d38 101{
260075cc 102 /* multiplication */
18925d38 103 const int m; /* cost of an M instruction. */
104 const int mghi; /* cost of an MGHI instruction. */
105 const int mh; /* cost of an MH instruction. */
106 const int mhi; /* cost of an MHI instruction. */
9cd3f3e6 107 const int ml; /* cost of an ML instruction. */
18925d38 108 const int mr; /* cost of an MR instruction. */
109 const int ms; /* cost of an MS instruction. */
110 const int msg; /* cost of an MSG instruction. */
111 const int msgf; /* cost of an MSGF instruction. */
112 const int msgfr; /* cost of an MSGFR instruction. */
113 const int msgr; /* cost of an MSGR instruction. */
114 const int msr; /* cost of an MSR instruction. */
115 const int mult_df; /* cost of multiplication in DFmode. */
429f9fdb 116 const int mxbr;
260075cc 117 /* square root */
429f9fdb 118 const int sqxbr; /* cost of square root in TFmode. */
9cd3f3e6 119 const int sqdbr; /* cost of square root in DFmode. */
120 const int sqebr; /* cost of square root in SFmode. */
260075cc 121 /* multiply and add */
d95e38cf 122 const int madbr; /* cost of multiply and add in DFmode. */
123 const int maebr; /* cost of multiply and add in SFmode. */
260075cc 124 /* division */
429f9fdb 125 const int dxbr;
260075cc 126 const int ddbr;
260075cc 127 const int debr;
3f074425 128 const int dlgr;
129 const int dlr;
130 const int dr;
131 const int dsgfr;
132 const int dsgr;
18925d38 133};
134
7a0cee35 135#define s390_cost ((const struct processor_costs *)(s390_cost_pointer))
18925d38 136
137static const
ffead1ca 138struct processor_costs z900_cost =
18925d38 139{
140 COSTS_N_INSNS (5), /* M */
141 COSTS_N_INSNS (10), /* MGHI */
142 COSTS_N_INSNS (5), /* MH */
143 COSTS_N_INSNS (4), /* MHI */
9cd3f3e6 144 COSTS_N_INSNS (5), /* ML */
18925d38 145 COSTS_N_INSNS (5), /* MR */
146 COSTS_N_INSNS (4), /* MS */
147 COSTS_N_INSNS (15), /* MSG */
148 COSTS_N_INSNS (7), /* MSGF */
149 COSTS_N_INSNS (7), /* MSGFR */
150 COSTS_N_INSNS (10), /* MSGR */
151 COSTS_N_INSNS (4), /* MSR */
152 COSTS_N_INSNS (7), /* multiplication in DFmode */
429f9fdb 153 COSTS_N_INSNS (13), /* MXBR */
154 COSTS_N_INSNS (136), /* SQXBR */
9cd3f3e6 155 COSTS_N_INSNS (44), /* SQDBR */
156 COSTS_N_INSNS (35), /* SQEBR */
d95e38cf 157 COSTS_N_INSNS (18), /* MADBR */
158 COSTS_N_INSNS (13), /* MAEBR */
429f9fdb 159 COSTS_N_INSNS (134), /* DXBR */
260075cc 160 COSTS_N_INSNS (30), /* DDBR */
260075cc 161 COSTS_N_INSNS (27), /* DEBR */
3f074425 162 COSTS_N_INSNS (220), /* DLGR */
163 COSTS_N_INSNS (34), /* DLR */
164 COSTS_N_INSNS (34), /* DR */
165 COSTS_N_INSNS (32), /* DSGFR */
166 COSTS_N_INSNS (32), /* DSGR */
18925d38 167};
168
169static const
ffead1ca 170struct processor_costs z990_cost =
18925d38 171{
172 COSTS_N_INSNS (4), /* M */
173 COSTS_N_INSNS (2), /* MGHI */
174 COSTS_N_INSNS (2), /* MH */
175 COSTS_N_INSNS (2), /* MHI */
9cd3f3e6 176 COSTS_N_INSNS (4), /* ML */
18925d38 177 COSTS_N_INSNS (4), /* MR */
178 COSTS_N_INSNS (5), /* MS */
179 COSTS_N_INSNS (6), /* MSG */
180 COSTS_N_INSNS (4), /* MSGF */
181 COSTS_N_INSNS (4), /* MSGFR */
182 COSTS_N_INSNS (4), /* MSGR */
183 COSTS_N_INSNS (4), /* MSR */
184 COSTS_N_INSNS (1), /* multiplication in DFmode */
429f9fdb 185 COSTS_N_INSNS (28), /* MXBR */
186 COSTS_N_INSNS (130), /* SQXBR */
9cd3f3e6 187 COSTS_N_INSNS (66), /* SQDBR */
188 COSTS_N_INSNS (38), /* SQEBR */
d95e38cf 189 COSTS_N_INSNS (1), /* MADBR */
190 COSTS_N_INSNS (1), /* MAEBR */
429f9fdb 191 COSTS_N_INSNS (60), /* DXBR */
260075cc 192 COSTS_N_INSNS (40), /* DDBR */
095798e3 193 COSTS_N_INSNS (26), /* DEBR */
3f074425 194 COSTS_N_INSNS (176), /* DLGR */
195 COSTS_N_INSNS (31), /* DLR */
196 COSTS_N_INSNS (31), /* DR */
197 COSTS_N_INSNS (31), /* DSGFR */
198 COSTS_N_INSNS (31), /* DSGR */
18925d38 199};
200
163277cf 201static const
ffead1ca 202struct processor_costs z9_109_cost =
163277cf 203{
204 COSTS_N_INSNS (4), /* M */
205 COSTS_N_INSNS (2), /* MGHI */
206 COSTS_N_INSNS (2), /* MH */
207 COSTS_N_INSNS (2), /* MHI */
208 COSTS_N_INSNS (4), /* ML */
209 COSTS_N_INSNS (4), /* MR */
210 COSTS_N_INSNS (5), /* MS */
211 COSTS_N_INSNS (6), /* MSG */
212 COSTS_N_INSNS (4), /* MSGF */
213 COSTS_N_INSNS (4), /* MSGFR */
214 COSTS_N_INSNS (4), /* MSGR */
215 COSTS_N_INSNS (4), /* MSR */
216 COSTS_N_INSNS (1), /* multiplication in DFmode */
429f9fdb 217 COSTS_N_INSNS (28), /* MXBR */
218 COSTS_N_INSNS (130), /* SQXBR */
163277cf 219 COSTS_N_INSNS (66), /* SQDBR */
220 COSTS_N_INSNS (38), /* SQEBR */
221 COSTS_N_INSNS (1), /* MADBR */
222 COSTS_N_INSNS (1), /* MAEBR */
429f9fdb 223 COSTS_N_INSNS (60), /* DXBR */
163277cf 224 COSTS_N_INSNS (40), /* DDBR */
095798e3 225 COSTS_N_INSNS (26), /* DEBR */
163277cf 226 COSTS_N_INSNS (30), /* DLGR */
227 COSTS_N_INSNS (23), /* DLR */
228 COSTS_N_INSNS (23), /* DR */
229 COSTS_N_INSNS (24), /* DSGFR */
230 COSTS_N_INSNS (24), /* DSGR */
231};
18925d38 232
a850370e 233static const
234struct processor_costs z10_cost =
235{
510c2327 236 COSTS_N_INSNS (10), /* M */
237 COSTS_N_INSNS (10), /* MGHI */
238 COSTS_N_INSNS (10), /* MH */
239 COSTS_N_INSNS (10), /* MHI */
240 COSTS_N_INSNS (10), /* ML */
241 COSTS_N_INSNS (10), /* MR */
242 COSTS_N_INSNS (10), /* MS */
243 COSTS_N_INSNS (10), /* MSG */
244 COSTS_N_INSNS (10), /* MSGF */
245 COSTS_N_INSNS (10), /* MSGFR */
246 COSTS_N_INSNS (10), /* MSGR */
247 COSTS_N_INSNS (10), /* MSR */
b0eacf26 248 COSTS_N_INSNS (1) , /* multiplication in DFmode */
510c2327 249 COSTS_N_INSNS (50), /* MXBR */
250 COSTS_N_INSNS (120), /* SQXBR */
251 COSTS_N_INSNS (52), /* SQDBR */
a850370e 252 COSTS_N_INSNS (38), /* SQEBR */
b0eacf26 253 COSTS_N_INSNS (1), /* MADBR */
254 COSTS_N_INSNS (1), /* MAEBR */
510c2327 255 COSTS_N_INSNS (111), /* DXBR */
256 COSTS_N_INSNS (39), /* DDBR */
257 COSTS_N_INSNS (32), /* DEBR */
258 COSTS_N_INSNS (160), /* DLGR */
259 COSTS_N_INSNS (71), /* DLR */
260 COSTS_N_INSNS (71), /* DR */
261 COSTS_N_INSNS (71), /* DSGFR */
262 COSTS_N_INSNS (71), /* DSGR */
a850370e 263};
264
33d033da 265static const
266struct processor_costs z196_cost =
267{
268 COSTS_N_INSNS (7), /* M */
269 COSTS_N_INSNS (5), /* MGHI */
270 COSTS_N_INSNS (5), /* MH */
271 COSTS_N_INSNS (5), /* MHI */
272 COSTS_N_INSNS (7), /* ML */
273 COSTS_N_INSNS (7), /* MR */
274 COSTS_N_INSNS (6), /* MS */
275 COSTS_N_INSNS (8), /* MSG */
276 COSTS_N_INSNS (6), /* MSGF */
277 COSTS_N_INSNS (6), /* MSGFR */
278 COSTS_N_INSNS (8), /* MSGR */
279 COSTS_N_INSNS (6), /* MSR */
280 COSTS_N_INSNS (1) , /* multiplication in DFmode */
281 COSTS_N_INSNS (40), /* MXBR B+40 */
282 COSTS_N_INSNS (100), /* SQXBR B+100 */
283 COSTS_N_INSNS (42), /* SQDBR B+42 */
284 COSTS_N_INSNS (28), /* SQEBR B+28 */
285 COSTS_N_INSNS (1), /* MADBR B */
286 COSTS_N_INSNS (1), /* MAEBR B */
287 COSTS_N_INSNS (101), /* DXBR B+101 */
288 COSTS_N_INSNS (29), /* DDBR */
289 COSTS_N_INSNS (22), /* DEBR */
290 COSTS_N_INSNS (160), /* DLGR cracked */
291 COSTS_N_INSNS (160), /* DLR cracked */
292 COSTS_N_INSNS (160), /* DR expanded */
293 COSTS_N_INSNS (160), /* DSGFR cracked */
294 COSTS_N_INSNS (160), /* DSGR cracked */
295};
296
81769881 297static const
298struct processor_costs zEC12_cost =
299{
300 COSTS_N_INSNS (7), /* M */
301 COSTS_N_INSNS (5), /* MGHI */
302 COSTS_N_INSNS (5), /* MH */
303 COSTS_N_INSNS (5), /* MHI */
304 COSTS_N_INSNS (7), /* ML */
305 COSTS_N_INSNS (7), /* MR */
306 COSTS_N_INSNS (6), /* MS */
307 COSTS_N_INSNS (8), /* MSG */
308 COSTS_N_INSNS (6), /* MSGF */
309 COSTS_N_INSNS (6), /* MSGFR */
310 COSTS_N_INSNS (8), /* MSGR */
311 COSTS_N_INSNS (6), /* MSR */
312 COSTS_N_INSNS (1) , /* multiplication in DFmode */
313 COSTS_N_INSNS (40), /* MXBR B+40 */
314 COSTS_N_INSNS (100), /* SQXBR B+100 */
315 COSTS_N_INSNS (42), /* SQDBR B+42 */
316 COSTS_N_INSNS (28), /* SQEBR B+28 */
317 COSTS_N_INSNS (1), /* MADBR B */
318 COSTS_N_INSNS (1), /* MAEBR B */
319 COSTS_N_INSNS (131), /* DXBR B+131 */
320 COSTS_N_INSNS (29), /* DDBR */
321 COSTS_N_INSNS (22), /* DEBR */
322 COSTS_N_INSNS (160), /* DLGR cracked */
323 COSTS_N_INSNS (160), /* DLR cracked */
324 COSTS_N_INSNS (160), /* DR expanded */
325 COSTS_N_INSNS (160), /* DSGFR cracked */
326 COSTS_N_INSNS (160), /* DSGR cracked */
327};
328
6ef12d3a 329const struct s390_processor processor_table[] =
330{
331 { "z900", "z900", PROCESSOR_2064_Z900, &z900_cost, 5 },
332 { "z990", "z990", PROCESSOR_2084_Z990, &z990_cost, 6 },
333 { "z9-109", "z9-109", PROCESSOR_2094_Z9_109, &z9_109_cost, 7 },
334 { "z9-ec", "z9-ec", PROCESSOR_2094_Z9_EC, &z9_109_cost, 7 },
335 { "z10", "z10", PROCESSOR_2097_Z10, &z10_cost, 8 },
336 { "z196", "z196", PROCESSOR_2817_Z196, &z196_cost, 9 },
337 { "zEC12", "zEC12", PROCESSOR_2827_ZEC12, &zEC12_cost, 10 },
338 { "z13", "z13", PROCESSOR_2964_Z13, &zEC12_cost, 11 },
339 { "z14", "arch12", PROCESSOR_3906_Z14, &zEC12_cost, 12 },
b3b57123 340 { "arch13", "", PROCESSOR_8561_ARCH13, &zEC12_cost, 13 },
6ef12d3a 341 { "native", "", PROCESSOR_NATIVE, NULL, 0 }
7a0cee35 342};
343
4673c1a0 344extern int reload_completed;
345
8a2a84e3 346/* Kept up to date using the SCHED_VARIABLE_ISSUE hook. */
93e0956b 347static rtx_insn *last_scheduled_insn;
9f3ec181 348#define NUM_SIDES 2
c3a8613e 349
350#define MAX_SCHED_UNITS 4
351static int last_scheduled_unit_distance[MAX_SCHED_UNITS][NUM_SIDES];
9f3ec181 352
353/* Estimate of number of cycles a long-running insn occupies an
354 execution unit. */
c3a8613e 355static int fxd_longrunning[NUM_SIDES];
356static int fpd_longrunning[NUM_SIDES];
9f3ec181 357
0cb69051 358/* The maximum score added for an instruction whose unit hasn't been
359 in use for MAX_SCHED_MIX_DISTANCE steps. Increase this value to
360 give instruction mix scheduling more priority over instruction
361 grouping. */
c3a8613e 362#define MAX_SCHED_MIX_SCORE 2
0cb69051 363
364/* The maximum distance up to which individual scores will be
365 calculated. Everything beyond this gives MAX_SCHED_MIX_SCORE.
366 Increase this with the OOO windows size of the machine. */
c3a8613e 367#define MAX_SCHED_MIX_DISTANCE 70
8a2a84e3 368
56769981 369/* Structure used to hold the components of a S/390 memory
370 address. A legitimate address on S/390 is of the general
371 form
372 base + index + displacement
373 where any of the components is optional.
374
375 base and index are registers of the class ADDR_REGS,
376 displacement is an unsigned 12-bit immediate constant. */
4673c1a0 377
ccaaf998 378/* The max number of insns of backend generated memset/memcpy/memcmp
379 loops. This value is used in the unroll adjust hook to detect such
380 loops. Current max is 9 coming from the memcmp loop. */
381#define BLOCK_MEM_OPS_LOOP_INSNS 9
382
4673c1a0 383struct s390_address
384{
385 rtx base;
386 rtx indx;
387 rtx disp;
e5537457 388 bool pointer;
05b58257 389 bool literal_pool;
4673c1a0 390};
391
67928721 392/* Few accessor macros for struct cfun->machine->s390_frame_layout. */
393
394#define cfun_frame_layout (cfun->machine->frame_layout)
395#define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)
ff4ce128 396#define cfun_save_arg_fprs_p (!!(TARGET_64BIT \
397 ? cfun_frame_layout.fpr_bitmap & 0x0f \
398 : cfun_frame_layout.fpr_bitmap & 0x03))
399#define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr_slot - \
b5fdc416 400 cfun_frame_layout.first_save_gpr_slot + 1) * UNITS_PER_LONG)
29439367 401#define cfun_set_fpr_save(REGNO) (cfun->machine->frame_layout.fpr_bitmap |= \
6a2469fe 402 (1 << (REGNO - FPR0_REGNUM)))
29439367 403#define cfun_fpr_save_p(REGNO) (!!(cfun->machine->frame_layout.fpr_bitmap & \
6a2469fe 404 (1 << (REGNO - FPR0_REGNUM))))
ff4ce128 405#define cfun_gpr_save_slot(REGNO) \
406 cfun->machine->frame_layout.gpr_save_slots[REGNO]
67928721 407
6902d973 408/* Number of GPRs and FPRs used for argument passing. */
409#define GP_ARG_NUM_REG 5
410#define FP_ARG_NUM_REG (TARGET_64BIT? 4 : 2)
76a4c804 411#define VEC_ARG_NUM_REG 8
6902d973 412
cb888f33 413/* A couple of shortcuts. */
414#define CONST_OK_FOR_J(x) \
415 CONST_OK_FOR_CONSTRAINT_P((x), 'J', "J")
416#define CONST_OK_FOR_K(x) \
417 CONST_OK_FOR_CONSTRAINT_P((x), 'K', "K")
163277cf 418#define CONST_OK_FOR_Os(x) \
9f522e0c 419 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Os")
163277cf 420#define CONST_OK_FOR_Op(x) \
9f522e0c 421 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Op")
163277cf 422#define CONST_OK_FOR_On(x) \
9f522e0c 423 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "On")
cb888f33 424
8f1128bb 425#define REGNO_PAIR_OK(REGNO, MODE) \
74f68e49 426 (s390_hard_regno_nregs ((REGNO), (MODE)) == 1 || !((REGNO) & 1))
8f1128bb 427
73df8a45 428/* That's the read ahead of the dynamic branch prediction unit in
33d033da 429 bytes on a z10 (or higher) CPU. */
430#define PREDICT_DISTANCE (TARGET_Z10 ? 384 : 2048)
73df8a45 431
db7a90aa 432/* Masks per jump target register indicating which thunk need to be
433 generated. */
434static GTY(()) int indirect_branch_prez10thunk_mask = 0;
435static GTY(()) int indirect_branch_z10thunk_mask = 0;
436
437#define INDIRECT_BRANCH_NUM_OPTIONS 4
438
439enum s390_indirect_branch_option
440 {
441 s390_opt_indirect_branch_jump = 0,
442 s390_opt_indirect_branch_call,
443 s390_opt_function_return_reg,
444 s390_opt_function_return_mem
445 };
446
447static GTY(()) int indirect_branch_table_label_no[INDIRECT_BRANCH_NUM_OPTIONS] = { 0 };
448const char *indirect_branch_table_label[INDIRECT_BRANCH_NUM_OPTIONS] = \
449 { "LJUMP", "LCALL", "LRETREG", "LRETMEM" };
450const char *indirect_branch_table_name[INDIRECT_BRANCH_NUM_OPTIONS] = \
451 { ".s390_indirect_jump", ".s390_indirect_call",
452 ".s390_return_reg", ".s390_return_mem" };
453
454bool
455s390_return_addr_from_memory ()
456{
457 return cfun_gpr_save_slot(RETURN_REGNUM) == SAVE_SLOT_STACK;
458}
07f32359 459
6b7cfb9c 460/* Indicate which ABI has been used for passing vector args.
461 0 - no vector type arguments have been passed where the ABI is relevant
462 1 - the old ABI has been used
463 2 - a vector type argument has been passed either in a vector register
464 or on the stack by value */
465static int s390_vector_abi = 0;
466
467/* Set the vector ABI marker if TYPE is subject to the vector ABI
468 switch. The vector ABI affects only vector data types. There are
469 two aspects of the vector ABI relevant here:
470
471 1. vectors >= 16 bytes have an alignment of 8 bytes with the new
472 ABI and natural alignment with the old.
473
474 2. vector <= 16 bytes are passed in VRs or by value on the stack
475 with the new ABI but by reference on the stack with the old.
476
477 If ARG_P is true TYPE is used for a function argument or return
478 value. The ABI marker then is set for all vector data types. If
479 ARG_P is false only type 1 vectors are being checked. */
480
481static void
482s390_check_type_for_vector_abi (const_tree type, bool arg_p, bool in_struct_p)
483{
484 static hash_set<const_tree> visited_types_hash;
485
486 if (s390_vector_abi)
487 return;
488
489 if (type == NULL_TREE || TREE_CODE (type) == ERROR_MARK)
490 return;
491
492 if (visited_types_hash.contains (type))
493 return;
494
495 visited_types_hash.add (type);
496
497 if (VECTOR_TYPE_P (type))
498 {
499 int type_size = int_size_in_bytes (type);
500
501 /* Outside arguments only the alignment is changing and this
502 only happens for vector types >= 16 bytes. */
503 if (!arg_p && type_size < 16)
504 return;
505
506 /* In arguments vector types > 16 are passed as before (GCC
507 never enforced the bigger alignment for arguments which was
508 required by the old vector ABI). However, it might still be
509 ABI relevant due to the changed alignment if it is a struct
510 member. */
511 if (arg_p && type_size > 16 && !in_struct_p)
512 return;
513
514 s390_vector_abi = TARGET_VX_ABI ? 2 : 1;
515 }
516 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
517 {
518 /* ARRAY_TYPE: Since with neither of the ABIs we have more than
519 natural alignment there will never be ABI dependent padding
520 in an array type. That's why we do not set in_struct_p to
521 true here. */
522 s390_check_type_for_vector_abi (TREE_TYPE (type), arg_p, in_struct_p);
523 }
524 else if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE)
525 {
526 tree arg_chain;
527
528 /* Check the return type. */
529 s390_check_type_for_vector_abi (TREE_TYPE (type), true, false);
530
531 for (arg_chain = TYPE_ARG_TYPES (type);
532 arg_chain;
533 arg_chain = TREE_CHAIN (arg_chain))
534 s390_check_type_for_vector_abi (TREE_VALUE (arg_chain), true, false);
535 }
536 else if (RECORD_OR_UNION_TYPE_P (type))
537 {
538 tree field;
539
540 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
541 {
542 if (TREE_CODE (field) != FIELD_DECL)
543 continue;
544
545 s390_check_type_for_vector_abi (TREE_TYPE (field), arg_p, true);
546 }
547 }
548}
549
550
07f32359 551/* System z builtins. */
552
553#include "s390-builtins.h"
554
a8aefbef 555const unsigned int bflags_builtin[S390_BUILTIN_MAX + 1] =
07f32359 556 {
557#undef B_DEF
558#undef OB_DEF
559#undef OB_DEF_VAR
a8aefbef 560#define B_DEF(NAME, PATTERN, ATTRS, BFLAGS, ...) BFLAGS,
07f32359 561#define OB_DEF(...)
562#define OB_DEF_VAR(...)
563#include "s390-builtins.def"
564 0
565 };
566
a8aefbef 567const unsigned int opflags_builtin[S390_BUILTIN_MAX + 1] =
568 {
569#undef B_DEF
570#undef OB_DEF
571#undef OB_DEF_VAR
572#define B_DEF(NAME, PATTERN, ATTRS, BFLAGS, OPFLAGS, ...) OPFLAGS,
573#define OB_DEF(...)
574#define OB_DEF_VAR(...)
575#include "s390-builtins.def"
576 0
577 };
578
579const unsigned int bflags_overloaded_builtin[S390_OVERLOADED_BUILTIN_MAX + 1] =
580 {
581#undef B_DEF
582#undef OB_DEF
583#undef OB_DEF_VAR
584#define B_DEF(...)
585#define OB_DEF(NAME, FIRST_VAR_NAME, LAST_VAR_NAME, BFLAGS, ...) BFLAGS,
586#define OB_DEF_VAR(...)
587#include "s390-builtins.def"
588 0
589 };
590
063ed3cf 591const unsigned int
592bflags_overloaded_builtin_var[S390_OVERLOADED_BUILTIN_VAR_MAX + 1] =
593 {
594#undef B_DEF
595#undef OB_DEF
596#undef OB_DEF_VAR
597#define B_DEF(...)
598#define OB_DEF(...)
599#define OB_DEF_VAR(NAME, PATTERN, FLAGS, OPFLAGS, FNTYPE) FLAGS,
600#include "s390-builtins.def"
601 0
602 };
603
a8aefbef 604const unsigned int
605opflags_overloaded_builtin_var[S390_OVERLOADED_BUILTIN_VAR_MAX + 1] =
07f32359 606 {
607#undef B_DEF
608#undef OB_DEF
609#undef OB_DEF_VAR
610#define B_DEF(...)
611#define OB_DEF(...)
063ed3cf 612#define OB_DEF_VAR(NAME, PATTERN, FLAGS, OPFLAGS, FNTYPE) OPFLAGS,
07f32359 613#include "s390-builtins.def"
614 0
615 };
616
617tree s390_builtin_types[BT_MAX];
618tree s390_builtin_fn_types[BT_FN_MAX];
619tree s390_builtin_decls[S390_BUILTIN_MAX +
620 S390_OVERLOADED_BUILTIN_MAX +
621 S390_OVERLOADED_BUILTIN_VAR_MAX];
622
623static enum insn_code const code_for_builtin[S390_BUILTIN_MAX + 1] = {
624#undef B_DEF
625#undef OB_DEF
626#undef OB_DEF_VAR
627#define B_DEF(NAME, PATTERN, ...) CODE_FOR_##PATTERN,
628#define OB_DEF(...)
629#define OB_DEF_VAR(...)
630
631#include "s390-builtins.def"
632 CODE_FOR_nothing
633};
634
635static void
636s390_init_builtins (void)
637{
638 /* These definitions are being used in s390-builtins.def. */
639 tree returns_twice_attr = tree_cons (get_identifier ("returns_twice"),
640 NULL, NULL);
641 tree noreturn_attr = tree_cons (get_identifier ("noreturn"), NULL, NULL);
642 tree c_uint64_type_node;
643
644 /* The uint64_type_node from tree.c is not compatible to the C99
645 uint64_t data type. What we want is c_uint64_type_node from
646 c-common.c. But since backend code is not supposed to interface
647 with the frontend we recreate it here. */
648 if (TARGET_64BIT)
649 c_uint64_type_node = long_unsigned_type_node;
650 else
651 c_uint64_type_node = long_long_unsigned_type_node;
652
653#undef DEF_TYPE
f9378734 654#define DEF_TYPE(INDEX, NODE, CONST_P) \
7a0cee35 655 if (s390_builtin_types[INDEX] == NULL) \
a8aefbef 656 s390_builtin_types[INDEX] = (!CONST_P) ? \
657 (NODE) : build_type_variant ((NODE), 1, 0);
07f32359 658
659#undef DEF_POINTER_TYPE
f9378734 660#define DEF_POINTER_TYPE(INDEX, INDEX_BASE) \
7a0cee35 661 if (s390_builtin_types[INDEX] == NULL) \
a8aefbef 662 s390_builtin_types[INDEX] = \
663 build_pointer_type (s390_builtin_types[INDEX_BASE]);
07f32359 664
665#undef DEF_DISTINCT_TYPE
f9378734 666#define DEF_DISTINCT_TYPE(INDEX, INDEX_BASE) \
7a0cee35 667 if (s390_builtin_types[INDEX] == NULL) \
a8aefbef 668 s390_builtin_types[INDEX] = \
669 build_distinct_type_copy (s390_builtin_types[INDEX_BASE]);
07f32359 670
671#undef DEF_VECTOR_TYPE
f9378734 672#define DEF_VECTOR_TYPE(INDEX, INDEX_BASE, ELEMENTS) \
7a0cee35 673 if (s390_builtin_types[INDEX] == NULL) \
a8aefbef 674 s390_builtin_types[INDEX] = \
675 build_vector_type (s390_builtin_types[INDEX_BASE], ELEMENTS);
07f32359 676
677#undef DEF_OPAQUE_VECTOR_TYPE
f9378734 678#define DEF_OPAQUE_VECTOR_TYPE(INDEX, INDEX_BASE, ELEMENTS) \
7a0cee35 679 if (s390_builtin_types[INDEX] == NULL) \
a8aefbef 680 s390_builtin_types[INDEX] = \
681 build_opaque_vector_type (s390_builtin_types[INDEX_BASE], ELEMENTS);
07f32359 682
683#undef DEF_FN_TYPE
f9378734 684#define DEF_FN_TYPE(INDEX, args...) \
7a0cee35 685 if (s390_builtin_fn_types[INDEX] == NULL) \
a8aefbef 686 s390_builtin_fn_types[INDEX] = \
7a0cee35 687 build_function_type_list (args, NULL_TREE);
07f32359 688#undef DEF_OV_TYPE
689#define DEF_OV_TYPE(...)
690#include "s390-builtin-types.def"
691
692#undef B_DEF
a8aefbef 693#define B_DEF(NAME, PATTERN, ATTRS, BFLAGS, OPFLAGS, FNTYPE) \
7a0cee35 694 if (s390_builtin_decls[S390_BUILTIN_##NAME] == NULL) \
a8aefbef 695 s390_builtin_decls[S390_BUILTIN_##NAME] = \
696 add_builtin_function ("__builtin_" #NAME, \
697 s390_builtin_fn_types[FNTYPE], \
698 S390_BUILTIN_##NAME, \
699 BUILT_IN_MD, \
700 NULL, \
701 ATTRS);
07f32359 702#undef OB_DEF
a8aefbef 703#define OB_DEF(NAME, FIRST_VAR_NAME, LAST_VAR_NAME, BFLAGS, FNTYPE) \
7a0cee35 704 if (s390_builtin_decls[S390_OVERLOADED_BUILTIN_##NAME + S390_BUILTIN_MAX] \
705 == NULL) \
a8aefbef 706 s390_builtin_decls[S390_OVERLOADED_BUILTIN_##NAME + S390_BUILTIN_MAX] = \
707 add_builtin_function ("__builtin_" #NAME, \
708 s390_builtin_fn_types[FNTYPE], \
709 S390_OVERLOADED_BUILTIN_##NAME + S390_BUILTIN_MAX, \
710 BUILT_IN_MD, \
711 NULL, \
712 0);
07f32359 713#undef OB_DEF_VAR
714#define OB_DEF_VAR(...)
715#include "s390-builtins.def"
716
717}
718
719/* Return true if ARG is appropriate as argument number ARGNUM of
720 builtin DECL. The operand flags from s390-builtins.def have to
721 passed as OP_FLAGS. */
722bool
723s390_const_operand_ok (tree arg, int argnum, int op_flags, tree decl)
724{
725 if (O_UIMM_P (op_flags))
726 {
727 int bitwidths[] = { 1, 2, 3, 4, 5, 8, 12, 16, 32 };
728 int bitwidth = bitwidths[op_flags - O_U1];
729
730 if (!tree_fits_uhwi_p (arg)
b422d8c0 731 || tree_to_uhwi (arg) > (HOST_WIDE_INT_1U << bitwidth) - 1)
07f32359 732 {
1adf3e20 733 error ("constant argument %d for builtin %qF is out of range "
734 "(0..%wu)", argnum, decl,
735 (HOST_WIDE_INT_1U << bitwidth) - 1);
07f32359 736 return false;
737 }
738 }
739
740 if (O_SIMM_P (op_flags))
741 {
742 int bitwidths[] = { 2, 3, 4, 5, 8, 12, 16, 32 };
743 int bitwidth = bitwidths[op_flags - O_S2];
744
745 if (!tree_fits_shwi_p (arg)
b422d8c0 746 || tree_to_shwi (arg) < -(HOST_WIDE_INT_1 << (bitwidth - 1))
747 || tree_to_shwi (arg) > ((HOST_WIDE_INT_1 << (bitwidth - 1)) - 1))
07f32359 748 {
1adf3e20 749 error ("constant argument %d for builtin %qF is out of range "
750 "(%wd..%wd)", argnum, decl,
751 -(HOST_WIDE_INT_1 << (bitwidth - 1)),
752 (HOST_WIDE_INT_1 << (bitwidth - 1)) - 1);
07f32359 753 return false;
754 }
755 }
756 return true;
757}
758
759/* Expand an expression EXP that calls a built-in function,
760 with result going to TARGET if that's convenient
761 (and in mode MODE if that's convenient).
762 SUBTARGET may be used as the target for computing one of EXP's operands.
763 IGNORE is nonzero if the value is to be ignored. */
764
765static rtx
766s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
767 machine_mode mode ATTRIBUTE_UNUSED,
768 int ignore ATTRIBUTE_UNUSED)
769{
674b3578 770#define MAX_ARGS 6
07f32359 771
772 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
d1170f8d 773 unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
07f32359 774 enum insn_code icode;
775 rtx op[MAX_ARGS], pat;
776 int arity;
777 bool nonvoid;
778 tree arg;
779 call_expr_arg_iterator iter;
a8aefbef 780 unsigned int all_op_flags = opflags_for_builtin (fcode);
07f32359 781 machine_mode last_vec_mode = VOIDmode;
782
783 if (TARGET_DEBUG_ARG)
784 {
785 fprintf (stderr,
7a0cee35 786 "s390_expand_builtin, code = %4d, %s, bflags = 0x%x\n",
787 (int)fcode, IDENTIFIER_POINTER (DECL_NAME (fndecl)),
788 bflags_for_builtin (fcode));
07f32359 789 }
790
7a0cee35 791 if (S390_USE_TARGET_ATTRIBUTE)
792 {
793 unsigned int bflags;
794
795 bflags = bflags_for_builtin (fcode);
796 if ((bflags & B_HTM) && !TARGET_HTM)
797 {
2f6d557f 798 error ("builtin %qF is not supported without %<-mhtm%> "
799 "(default with %<-march=zEC12%> and higher).", fndecl);
7a0cee35 800 return const0_rtx;
801 }
c9213ca0 802 if (((bflags & B_VX) || (bflags & B_VXE)) && !TARGET_VX)
7a0cee35 803 {
2f6d557f 804 error ("builtin %qF requires %<-mvx%> "
805 "(default with %<-march=z13%> and higher).", fndecl);
7a0cee35 806 return const0_rtx;
807 }
c9213ca0 808
809 if ((bflags & B_VXE) && !TARGET_VXE)
810 {
a168a775 811 error ("Builtin %qF requires z14 or higher.", fndecl);
c9213ca0 812 return const0_rtx;
813 }
7a0cee35 814 }
07f32359 815 if (fcode >= S390_OVERLOADED_BUILTIN_VAR_OFFSET
816 && fcode < S390_ALL_BUILTIN_MAX)
817 {
818 gcc_unreachable ();
819 }
820 else if (fcode < S390_OVERLOADED_BUILTIN_OFFSET)
821 {
822 icode = code_for_builtin[fcode];
823 /* Set a flag in the machine specific cfun part in order to support
824 saving/restoring of FPRs. */
825 if (fcode == S390_BUILTIN_tbegin || fcode == S390_BUILTIN_tbegin_retry)
826 cfun->machine->tbegin_p = true;
827 }
828 else if (fcode < S390_OVERLOADED_BUILTIN_VAR_OFFSET)
829 {
19abb0ad 830 error ("unresolved overloaded builtin");
07f32359 831 return const0_rtx;
832 }
833 else
834 internal_error ("bad builtin fcode");
835
836 if (icode == 0)
837 internal_error ("bad builtin icode");
838
839 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
840
841 if (nonvoid)
842 {
843 machine_mode tmode = insn_data[icode].operand[0].mode;
844 if (!target
845 || GET_MODE (target) != tmode
846 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
847 target = gen_reg_rtx (tmode);
848
849 /* There are builtins (e.g. vec_promote) with no vector
850 arguments but an element selector. So we have to also look
851 at the vector return type when emitting the modulo
852 operation. */
853 if (VECTOR_MODE_P (insn_data[icode].operand[0].mode))
854 last_vec_mode = insn_data[icode].operand[0].mode;
855 }
856
857 arity = 0;
858 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
859 {
b0c401ca 860 rtx tmp_rtx;
07f32359 861 const struct insn_operand_data *insn_op;
862 unsigned int op_flags = all_op_flags & ((1 << O_SHIFT) - 1);
863
864 all_op_flags = all_op_flags >> O_SHIFT;
865
866 if (arg == error_mark_node)
867 return NULL_RTX;
868 if (arity >= MAX_ARGS)
869 return NULL_RTX;
870
871 if (O_IMM_P (op_flags)
872 && TREE_CODE (arg) != INTEGER_CST)
873 {
874 error ("constant value required for builtin %qF argument %d",
875 fndecl, arity + 1);
876 return const0_rtx;
877 }
878
879 if (!s390_const_operand_ok (arg, arity + 1, op_flags, fndecl))
880 return const0_rtx;
881
882 insn_op = &insn_data[icode].operand[arity + nonvoid];
883 op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, EXPAND_NORMAL);
884
0570ddf1 885 /* expand_expr truncates constants to the target mode only if it
886 is "convenient". However, our checks below rely on this
887 being done. */
888 if (CONST_INT_P (op[arity])
889 && SCALAR_INT_MODE_P (insn_op->mode)
890 && GET_MODE (op[arity]) != insn_op->mode)
891 op[arity] = GEN_INT (trunc_int_for_mode (INTVAL (op[arity]),
892 insn_op->mode));
893
07f32359 894 /* Wrap the expanded RTX for pointer types into a MEM expr with
895 the proper mode. This allows us to use e.g. (match_operand
896 "memory_operand"..) in the insn patterns instead of (mem
897 (match_operand "address_operand)). This is helpful for
898 patterns not just accepting MEMs. */
899 if (POINTER_TYPE_P (TREE_TYPE (arg))
900 && insn_op->predicate != address_operand)
901 op[arity] = gen_rtx_MEM (insn_op->mode, op[arity]);
902
903 /* Expand the module operation required on element selectors. */
904 if (op_flags == O_ELEM)
905 {
906 gcc_assert (last_vec_mode != VOIDmode);
907 op[arity] = simplify_expand_binop (SImode, code_to_optab (AND),
908 op[arity],
909 GEN_INT (GET_MODE_NUNITS (last_vec_mode) - 1),
910 NULL_RTX, 1, OPTAB_DIRECT);
911 }
912
913 /* Record the vector mode used for an element selector. This assumes:
914 1. There is no builtin with two different vector modes and an element selector
9f522e0c 915 2. The element selector comes after the vector type it is referring to.
07f32359 916 This currently the true for all the builtins but FIXME we
917 should better check for that. */
918 if (VECTOR_MODE_P (insn_op->mode))
919 last_vec_mode = insn_op->mode;
920
921 if (insn_op->predicate (op[arity], insn_op->mode))
922 {
923 arity++;
924 continue;
925 }
926
ac80cfb4 927 /* A memory operand is rejected by the memory_operand predicate.
928 Try making the address legal by copying it into a register. */
07f32359 929 if (MEM_P (op[arity])
930 && insn_op->predicate == memory_operand
931 && (GET_MODE (XEXP (op[arity], 0)) == Pmode
932 || GET_MODE (XEXP (op[arity], 0)) == VOIDmode))
933 {
934 op[arity] = replace_equiv_address (op[arity],
935 copy_to_mode_reg (Pmode,
936 XEXP (op[arity], 0)));
937 }
b0c401ca 938 /* Some of the builtins require different modes/types than the
939 pattern in order to implement a specific API. Instead of
940 adding many expanders which do the mode change we do it here.
941 E.g. s390_vec_add_u128 required to have vector unsigned char
942 arguments is mapped to addti3. */
943 else if (insn_op->mode != VOIDmode
944 && GET_MODE (op[arity]) != VOIDmode
945 && GET_MODE (op[arity]) != insn_op->mode
946 && ((tmp_rtx = simplify_gen_subreg (insn_op->mode, op[arity],
947 GET_MODE (op[arity]), 0))
948 != NULL_RTX))
949 {
950 op[arity] = tmp_rtx;
951 }
ac80cfb4 952
953 /* The predicate rejects the operand although the mode is fine.
954 Copy the operand to register. */
955 if (!insn_op->predicate (op[arity], insn_op->mode)
956 && (GET_MODE (op[arity]) == insn_op->mode
957 || GET_MODE (op[arity]) == VOIDmode
958 || (insn_op->predicate == address_operand
959 && GET_MODE (op[arity]) == Pmode)))
07f32359 960 {
961 /* An address_operand usually has VOIDmode in the expander
962 so we cannot use this. */
963 machine_mode target_mode =
964 (insn_op->predicate == address_operand
af8303fa 965 ? (machine_mode) Pmode : insn_op->mode);
07f32359 966 op[arity] = copy_to_mode_reg (target_mode, op[arity]);
967 }
968
969 if (!insn_op->predicate (op[arity], insn_op->mode))
970 {
19abb0ad 971 error ("invalid argument %d for builtin %qF", arity + 1, fndecl);
07f32359 972 return const0_rtx;
973 }
974 arity++;
975 }
976
07f32359 977 switch (arity)
978 {
979 case 0:
980 pat = GEN_FCN (icode) (target);
981 break;
982 case 1:
983 if (nonvoid)
9f522e0c 984 pat = GEN_FCN (icode) (target, op[0]);
07f32359 985 else
986 pat = GEN_FCN (icode) (op[0]);
987 break;
988 case 2:
989 if (nonvoid)
990 pat = GEN_FCN (icode) (target, op[0], op[1]);
991 else
992 pat = GEN_FCN (icode) (op[0], op[1]);
993 break;
994 case 3:
995 if (nonvoid)
996 pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
997 else
998 pat = GEN_FCN (icode) (op[0], op[1], op[2]);
999 break;
1000 case 4:
1001 if (nonvoid)
1002 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
1003 else
1004 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
1005 break;
1006 case 5:
1007 if (nonvoid)
1008 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3], op[4]);
1009 else
1010 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4]);
1011 break;
1012 case 6:
1013 if (nonvoid)
1014 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3], op[4], op[5]);
1015 else
1016 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5]);
1017 break;
1018 default:
1019 gcc_unreachable ();
1020 }
1021 if (!pat)
1022 return NULL_RTX;
1023 emit_insn (pat);
1024
1025 if (nonvoid)
1026 return target;
1027 else
1028 return const0_rtx;
1029}
1030
1031
11762b83 1032static const int s390_hotpatch_hw_max = 1000000;
1033static int s390_hotpatch_hw_before_label = 0;
1034static int s390_hotpatch_hw_after_label = 0;
77bc9912 1035
1036/* Check whether the hotpatch attribute is applied to a function and, if it has
1037 an argument, the argument is valid. */
1038
1039static tree
1040s390_handle_hotpatch_attribute (tree *node, tree name, tree args,
1041 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
1042{
11762b83 1043 tree expr;
1044 tree expr2;
1045 int err;
1046
77bc9912 1047 if (TREE_CODE (*node) != FUNCTION_DECL)
1048 {
1049 warning (OPT_Wattributes, "%qE attribute only applies to functions",
1050 name);
1051 *no_add_attrs = true;
1052 }
11762b83 1053 if (args != NULL && TREE_CHAIN (args) != NULL)
1054 {
1055 expr = TREE_VALUE (args);
1056 expr2 = TREE_VALUE (TREE_CHAIN (args));
1057 }
1058 if (args == NULL || TREE_CHAIN (args) == NULL)
1059 err = 1;
1060 else if (TREE_CODE (expr) != INTEGER_CST
1061 || !INTEGRAL_TYPE_P (TREE_TYPE (expr))
e3d0f65c 1062 || wi::gtu_p (wi::to_wide (expr), s390_hotpatch_hw_max))
11762b83 1063 err = 1;
1064 else if (TREE_CODE (expr2) != INTEGER_CST
1065 || !INTEGRAL_TYPE_P (TREE_TYPE (expr2))
e3d0f65c 1066 || wi::gtu_p (wi::to_wide (expr2), s390_hotpatch_hw_max))
11762b83 1067 err = 1;
1068 else
1069 err = 0;
1070 if (err)
77bc9912 1071 {
11762b83 1072 error ("requested %qE attribute is not a comma separated pair of"
1073 " non-negative integer constants or too large (max. %d)", name,
1074 s390_hotpatch_hw_max);
1075 *no_add_attrs = true;
77bc9912 1076 }
1077
1078 return NULL_TREE;
1079}
1080
07f32359 1081/* Expand the s390_vector_bool type attribute. */
1082
1083static tree
1084s390_handle_vectorbool_attribute (tree *node, tree name ATTRIBUTE_UNUSED,
1085 tree args ATTRIBUTE_UNUSED,
1086 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
1087{
1088 tree type = *node, result = NULL_TREE;
1089 machine_mode mode;
1090
1091 while (POINTER_TYPE_P (type)
1092 || TREE_CODE (type) == FUNCTION_TYPE
1093 || TREE_CODE (type) == METHOD_TYPE
1094 || TREE_CODE (type) == ARRAY_TYPE)
1095 type = TREE_TYPE (type);
1096
1097 mode = TYPE_MODE (type);
1098 switch (mode)
1099 {
916ace94 1100 case E_DImode: case E_V2DImode:
1101 result = s390_builtin_types[BT_BV2DI];
1102 break;
1103 case E_SImode: case E_V4SImode:
1104 result = s390_builtin_types[BT_BV4SI];
1105 break;
1106 case E_HImode: case E_V8HImode:
1107 result = s390_builtin_types[BT_BV8HI];
1108 break;
1109 case E_QImode: case E_V16QImode:
1110 result = s390_builtin_types[BT_BV16QI];
1111 break;
1112 default:
1113 break;
07f32359 1114 }
1115
1116 *no_add_attrs = true; /* No need to hang on to the attribute. */
1117
1118 if (result)
1119 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
1120
1121 return NULL_TREE;
1122}
1123
db7a90aa 1124/* Check syntax of function decl attributes having a string type value. */
1125
1126static tree
1127s390_handle_string_attribute (tree *node, tree name ATTRIBUTE_UNUSED,
1128 tree args ATTRIBUTE_UNUSED,
1129 int flags ATTRIBUTE_UNUSED,
1130 bool *no_add_attrs)
1131{
1132 tree cst;
1133
1134 if (TREE_CODE (*node) != FUNCTION_DECL)
1135 {
1136 warning (OPT_Wattributes, "%qE attribute only applies to functions",
1137 name);
1138 *no_add_attrs = true;
1139 }
1140
1141 cst = TREE_VALUE (args);
1142
1143 if (TREE_CODE (cst) != STRING_CST)
1144 {
1145 warning (OPT_Wattributes,
1146 "%qE attribute requires a string constant argument",
1147 name);
1148 *no_add_attrs = true;
1149 }
1150
1151 if (is_attribute_p ("indirect_branch", name)
1152 || is_attribute_p ("indirect_branch_call", name)
1153 || is_attribute_p ("function_return", name)
1154 || is_attribute_p ("function_return_reg", name)
1155 || is_attribute_p ("function_return_mem", name))
1156 {
1157 if (strcmp (TREE_STRING_POINTER (cst), "keep") != 0
1158 && strcmp (TREE_STRING_POINTER (cst), "thunk") != 0
1159 && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") != 0)
1160 {
1161 warning (OPT_Wattributes,
1162 "argument to %qE attribute is not "
1163 "(keep|thunk|thunk-extern)", name);
1164 *no_add_attrs = true;
1165 }
1166 }
1167
1168 if (is_attribute_p ("indirect_branch_jump", name)
1169 && strcmp (TREE_STRING_POINTER (cst), "keep") != 0
1170 && strcmp (TREE_STRING_POINTER (cst), "thunk") != 0
1171 && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") != 0
1172 && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") != 0)
1173 {
1174 warning (OPT_Wattributes,
1175 "argument to %qE attribute is not "
1176 "(keep|thunk|thunk-inline|thunk-extern)", name);
1177 *no_add_attrs = true;
1178 }
1179
1180 return NULL_TREE;
1181}
1182
77bc9912 1183static const struct attribute_spec s390_attribute_table[] = {
672bc44d 1184 { "hotpatch", 2, 2, true, false, false, false,
1185 s390_handle_hotpatch_attribute, NULL },
1186 { "s390_vector_bool", 0, 0, false, true, false, true,
1187 s390_handle_vectorbool_attribute, NULL },
db7a90aa 1188 { "indirect_branch", 1, 1, true, false, false, false,
1189 s390_handle_string_attribute, NULL },
1190 { "indirect_branch_jump", 1, 1, true, false, false, false,
1191 s390_handle_string_attribute, NULL },
1192 { "indirect_branch_call", 1, 1, true, false, false, false,
1193 s390_handle_string_attribute, NULL },
1194 { "function_return", 1, 1, true, false, false, false,
1195 s390_handle_string_attribute, NULL },
1196 { "function_return_reg", 1, 1, true, false, false, false,
1197 s390_handle_string_attribute, NULL },
1198 { "function_return_mem", 1, 1, true, false, false, false,
1199 s390_handle_string_attribute, NULL },
1200
77bc9912 1201 /* End element. */
672bc44d 1202 { NULL, 0, 0, false, false, false, false, NULL, NULL }
77bc9912 1203};
1204
6d0afa28 1205/* Return the alignment for LABEL. We default to the -falign-labels
1206 value except for the literal pool base label. */
1207int
56d95ea5 1208s390_label_align (rtx_insn *label)
6d0afa28 1209{
50fc2d35 1210 rtx_insn *prev_insn = prev_active_insn (label);
1211 rtx set, src;
6d0afa28 1212
1213 if (prev_insn == NULL_RTX)
1214 goto old;
1215
50fc2d35 1216 set = single_set (prev_insn);
6d0afa28 1217
50fc2d35 1218 if (set == NULL_RTX)
6d0afa28 1219 goto old;
1220
50fc2d35 1221 src = SET_SRC (set);
6d0afa28 1222
1223 /* Don't align literal pool base labels. */
50fc2d35 1224 if (GET_CODE (src) == UNSPEC
1225 && XINT (src, 1) == UNSPEC_MAIN_BASE)
6d0afa28 1226 return 0;
1227
1228 old:
6fceef7a 1229 return align_labels.levels[0].log;
6d0afa28 1230}
1231
9852c8ae 1232static GTY(()) rtx got_symbol;
1233
1234/* Return the GOT table symbol. The symbol will be created when the
1235 function is invoked for the first time. */
1236
1237static rtx
1238s390_got_symbol (void)
1239{
1240 if (!got_symbol)
1241 {
1242 got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1243 SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
1244 }
1245
1246 return got_symbol;
1247}
1248
f77c4496 1249static scalar_int_mode
0ef89dfd 1250s390_libgcc_cmp_return_mode (void)
1251{
1252 return TARGET_64BIT ? DImode : SImode;
1253}
1254
f77c4496 1255static scalar_int_mode
0ef89dfd 1256s390_libgcc_shift_count_mode (void)
1257{
1258 return TARGET_64BIT ? DImode : SImode;
1259}
1260
f77c4496 1261static scalar_int_mode
b5fdc416 1262s390_unwind_word_mode (void)
1263{
1264 return TARGET_64BIT ? DImode : SImode;
1265}
1266
36868490 1267/* Return true if the back end supports mode MODE. */
1268static bool
8aec1ebb 1269s390_scalar_mode_supported_p (scalar_mode mode)
36868490 1270{
b5fdc416 1271 /* In contrast to the default implementation reject TImode constants on 31bit
1272 TARGET_ZARCH for ABI compliance. */
1273 if (!TARGET_64BIT && TARGET_ZARCH && mode == TImode)
1274 return false;
1275
36868490 1276 if (DECIMAL_FLOAT_MODE_P (mode))
8e72d11d 1277 return default_decimal_float_supported_p ();
b5fdc416 1278
1279 return default_scalar_mode_supported_p (mode);
36868490 1280}
1281
76a4c804 1282/* Return true if the back end supports vector mode MODE. */
1283static bool
1284s390_vector_mode_supported_p (machine_mode mode)
1285{
1286 machine_mode inner;
1287
1288 if (!VECTOR_MODE_P (mode)
1289 || !TARGET_VX
1290 || GET_MODE_SIZE (mode) > 16)
1291 return false;
1292
1293 inner = GET_MODE_INNER (mode);
1294
1295 switch (inner)
1296 {
916ace94 1297 case E_QImode:
1298 case E_HImode:
1299 case E_SImode:
1300 case E_DImode:
1301 case E_TImode:
1302 case E_SFmode:
1303 case E_DFmode:
1304 case E_TFmode:
76a4c804 1305 return true;
1306 default:
1307 return false;
1308 }
1309}
1310
1e639cb0 1311/* Set the has_landing_pad_p flag in struct machine_function to VALUE. */
1312
1313void
1314s390_set_has_landing_pad_p (bool value)
1315{
1316 cfun->machine->has_landing_pad_p = value;
1317}
6902d973 1318
9c93d843 1319/* If two condition code modes are compatible, return a condition code
1320 mode which is compatible with both. Otherwise, return
1321 VOIDmode. */
1322
3754d046 1323static machine_mode
1324s390_cc_modes_compatible (machine_mode m1, machine_mode m2)
9c93d843 1325{
1326 if (m1 == m2)
1327 return m1;
1328
1329 switch (m1)
1330 {
916ace94 1331 case E_CCZmode:
9c93d843 1332 if (m2 == CCUmode || m2 == CCTmode || m2 == CCZ1mode
1333 || m2 == CCSmode || m2 == CCSRmode || m2 == CCURmode)
9f522e0c 1334 return m2;
9c93d843 1335 return VOIDmode;
1336
916ace94 1337 case E_CCSmode:
1338 case E_CCUmode:
1339 case E_CCTmode:
1340 case E_CCSRmode:
1341 case E_CCURmode:
1342 case E_CCZ1mode:
9c93d843 1343 if (m2 == CCZmode)
1344 return m1;
ffead1ca 1345
9c93d843 1346 return VOIDmode;
1347
1348 default:
1349 return VOIDmode;
1350 }
1351 return VOIDmode;
1352}
1353
56769981 1354/* Return true if SET either doesn't set the CC register, or else
f81e845f 1355 the source and destination have matching CC modes and that
56769981 1356 CC mode is at least as constrained as REQ_MODE. */
f81e845f 1357
e5537457 1358static bool
3754d046 1359s390_match_ccmode_set (rtx set, machine_mode req_mode)
4673c1a0 1360{
3754d046 1361 machine_mode set_mode;
4673c1a0 1362
32eda510 1363 gcc_assert (GET_CODE (set) == SET);
4673c1a0 1364
abc57c35 1365 /* These modes are supposed to be used only in CC consumer
1366 patterns. */
1367 gcc_assert (req_mode != CCVIALLmode && req_mode != CCVIANYmode
1368 && req_mode != CCVFALLmode && req_mode != CCVFANYmode);
1369
4673c1a0 1370 if (GET_CODE (SET_DEST (set)) != REG || !CC_REGNO_P (REGNO (SET_DEST (set))))
1371 return 1;
1372
1373 set_mode = GET_MODE (SET_DEST (set));
1374 switch (set_mode)
1375 {
916ace94 1376 case E_CCZ1mode:
1377 case E_CCSmode:
1378 case E_CCSRmode:
1379 case E_CCUmode:
1380 case E_CCURmode:
1720014d 1381 case E_CCOmode:
916ace94 1382 case E_CCLmode:
1383 case E_CCL1mode:
1384 case E_CCL2mode:
1385 case E_CCL3mode:
1386 case E_CCT1mode:
1387 case E_CCT2mode:
1388 case E_CCT3mode:
1389 case E_CCVEQmode:
1390 case E_CCVIHmode:
1391 case E_CCVIHUmode:
1392 case E_CCVFHmode:
1393 case E_CCVFHEmode:
c6821d1c 1394 if (req_mode != set_mode)
9f522e0c 1395 return 0;
2eb8fe23 1396 break;
c6821d1c 1397
916ace94 1398 case E_CCZmode:
c6821d1c 1399 if (req_mode != CCSmode && req_mode != CCUmode && req_mode != CCTmode
d90d26d8 1400 && req_mode != CCSRmode && req_mode != CCURmode
1401 && req_mode != CCZ1mode)
9f522e0c 1402 return 0;
4673c1a0 1403 break;
3c482144 1404
916ace94 1405 case E_CCAPmode:
1406 case E_CCANmode:
3c482144 1407 if (req_mode != CCAmode)
9f522e0c 1408 return 0;
3c482144 1409 break;
f81e845f 1410
4673c1a0 1411 default:
32eda510 1412 gcc_unreachable ();
4673c1a0 1413 }
f81e845f 1414
4673c1a0 1415 return (GET_MODE (SET_SRC (set)) == set_mode);
1416}
1417
f81e845f 1418/* Return true if every SET in INSN that sets the CC register
1419 has source and destination with matching CC modes and that
1420 CC mode is at least as constrained as REQ_MODE.
c6821d1c 1421 If REQ_MODE is VOIDmode, always return false. */
f81e845f 1422
e5537457 1423bool
3754d046 1424s390_match_ccmode (rtx_insn *insn, machine_mode req_mode)
4673c1a0 1425{
1426 int i;
1427
c6821d1c 1428 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
1429 if (req_mode == VOIDmode)
e5537457 1430 return false;
c6821d1c 1431
4673c1a0 1432 if (GET_CODE (PATTERN (insn)) == SET)
1433 return s390_match_ccmode_set (PATTERN (insn), req_mode);
1434
1435 if (GET_CODE (PATTERN (insn)) == PARALLEL)
1436 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
9f522e0c 1437 {
1438 rtx set = XVECEXP (PATTERN (insn), 0, i);
1439 if (GET_CODE (set) == SET)
1440 if (!s390_match_ccmode_set (set, req_mode))
1441 return false;
1442 }
4673c1a0 1443
e5537457 1444 return true;
4673c1a0 1445}
1446
f81e845f 1447/* If a test-under-mask instruction can be used to implement
c6821d1c 1448 (compare (and ... OP1) OP2), return the CC mode required
f81e845f 1449 to do that. Otherwise, return VOIDmode.
c6821d1c 1450 MIXED is true if the instruction can distinguish between
1451 CC1 and CC2 for mixed selected bits (TMxx), it is false
1452 if the instruction cannot (TM). */
1453
3754d046 1454machine_mode
e5537457 1455s390_tm_ccmode (rtx op1, rtx op2, bool mixed)
c6821d1c 1456{
1457 int bit0, bit1;
1458
ba0e61d6 1459 /* ??? Fixme: should work on CONST_WIDE_INT as well. */
c6821d1c 1460 if (GET_CODE (op1) != CONST_INT || GET_CODE (op2) != CONST_INT)
1461 return VOIDmode;
1462
eeba5f25 1463 /* Selected bits all zero: CC0.
1464 e.g.: int a; if ((a & (16 + 128)) == 0) */
c6821d1c 1465 if (INTVAL (op2) == 0)
1466 return CCTmode;
1467
ffead1ca 1468 /* Selected bits all one: CC3.
eeba5f25 1469 e.g.: int a; if ((a & (16 + 128)) == 16 + 128) */
c6821d1c 1470 if (INTVAL (op2) == INTVAL (op1))
1471 return CCT3mode;
1472
eeba5f25 1473 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. e.g.:
1474 int a;
1475 if ((a & (16 + 128)) == 16) -> CCT1
1476 if ((a & (16 + 128)) == 128) -> CCT2 */
c6821d1c 1477 if (mixed)
1478 {
1479 bit1 = exact_log2 (INTVAL (op2));
1480 bit0 = exact_log2 (INTVAL (op1) ^ INTVAL (op2));
1481 if (bit0 != -1 && bit1 != -1)
9f522e0c 1482 return bit0 > bit1 ? CCT1mode : CCT2mode;
c6821d1c 1483 }
1484
1485 return VOIDmode;
1486}
1487
f81e845f 1488/* Given a comparison code OP (EQ, NE, etc.) and the operands
1489 OP0 and OP1 of a COMPARE, return the mode to be used for the
2eb8fe23 1490 comparison. */
1491
3754d046 1492machine_mode
b40da9a7 1493s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
2eb8fe23 1494{
1495 switch (code)
1496 {
1497 case EQ:
1498 case NE:
9be33ca2 1499 if ((GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
1500 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
1501 return CCAPmode;
3c482144 1502 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
cb888f33 1503 && CONST_OK_FOR_K (INTVAL (XEXP (op0, 1))))
3c482144 1504 return CCAPmode;
e9fd5349 1505 if ((GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
1506 || GET_CODE (op1) == NEG)
1507 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
2eb8fe23 1508 return CCLmode;
1509
c6821d1c 1510 if (GET_CODE (op0) == AND)
1511 {
1512 /* Check whether we can potentially do it via TM. */
3754d046 1513 machine_mode ccmode;
c6821d1c 1514 ccmode = s390_tm_ccmode (XEXP (op0, 1), op1, 1);
1515 if (ccmode != VOIDmode)
1516 {
1517 /* Relax CCTmode to CCZmode to allow fall-back to AND
1518 if that turns out to be beneficial. */
9f522e0c 1519 return ccmode == CCTmode ? CCZmode : ccmode;
c6821d1c 1520 }
1521 }
1522
f81e845f 1523 if (register_operand (op0, HImode)
c6821d1c 1524 && GET_CODE (op1) == CONST_INT
1525 && (INTVAL (op1) == -1 || INTVAL (op1) == 65535))
1526 return CCT3mode;
f81e845f 1527 if (register_operand (op0, QImode)
c6821d1c 1528 && GET_CODE (op1) == CONST_INT
1529 && (INTVAL (op1) == -1 || INTVAL (op1) == 255))
1530 return CCT3mode;
1531
2eb8fe23 1532 return CCZmode;
1533
1534 case LE:
1535 case LT:
1536 case GE:
1537 case GT:
eeba5f25 1538 /* The only overflow condition of NEG and ABS happens when
1539 -INT_MAX is used as parameter, which stays negative. So
ffead1ca 1540 we have an overflow from a positive value to a negative.
eeba5f25 1541 Using CCAP mode the resulting cc can be used for comparisons. */
9be33ca2 1542 if ((GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
1543 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
1544 return CCAPmode;
eeba5f25 1545
9f522e0c 1546 /* If constants are involved in an add instruction it is possible to use
1547 the resulting cc for comparisons with zero. Knowing the sign of the
0975351b 1548 constant the overflow behavior gets predictable. e.g.:
9f522e0c 1549 int a, b; if ((b = a + c) > 0)
1550 with c as a constant value: c < 0 -> CCAN and c >= 0 -> CCAP */
9be33ca2 1551 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
ea14438e 1552 && (CONST_OK_FOR_K (INTVAL (XEXP (op0, 1)))
1553 || (CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0, 1)), 'O', "Os")
1554 /* Avoid INT32_MIN on 32 bit. */
1555 && (!TARGET_ZARCH || INTVAL (XEXP (op0, 1)) != -0x7fffffff - 1))))
9be33ca2 1556 {
1557 if (INTVAL (XEXP((op0), 1)) < 0)
1558 return CCANmode;
1559 else
1560 return CCAPmode;
1561 }
1562 /* Fall through. */
2eb8fe23 1563 case UNORDERED:
1564 case ORDERED:
1565 case UNEQ:
1566 case UNLE:
1567 case UNLT:
1568 case UNGE:
1569 case UNGT:
1570 case LTGT:
c6821d1c 1571 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
1572 && GET_CODE (op1) != CONST_INT)
1573 return CCSRmode;
2eb8fe23 1574 return CCSmode;
1575
2eb8fe23 1576 case LTU:
1577 case GEU:
e9fd5349 1578 if (GET_CODE (op0) == PLUS
1579 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
c6821d1c 1580 return CCL1mode;
1581
1582 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
1583 && GET_CODE (op1) != CONST_INT)
1584 return CCURmode;
1585 return CCUmode;
1586
1587 case LEU:
2eb8fe23 1588 case GTU:
e9fd5349 1589 if (GET_CODE (op0) == MINUS
1590 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
c6821d1c 1591 return CCL2mode;
1592
1593 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
1594 && GET_CODE (op1) != CONST_INT)
1595 return CCURmode;
2eb8fe23 1596 return CCUmode;
1597
1598 default:
32eda510 1599 gcc_unreachable ();
2eb8fe23 1600 }
1601}
1602
ebe32bb0 1603/* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
1604 that we can implement more efficiently. */
1605
d5065e6e 1606static void
1607s390_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
1608 bool op0_preserve_value)
ebe32bb0 1609{
d5065e6e 1610 if (op0_preserve_value)
1611 return;
1612
ebe32bb0 1613 /* Convert ZERO_EXTRACT back to AND to enable TM patterns. */
1614 if ((*code == EQ || *code == NE)
1615 && *op1 == const0_rtx
1616 && GET_CODE (*op0) == ZERO_EXTRACT
1617 && GET_CODE (XEXP (*op0, 1)) == CONST_INT
1618 && GET_CODE (XEXP (*op0, 2)) == CONST_INT
1619 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0, 0))))
1620 {
1621 rtx inner = XEXP (*op0, 0);
1622 HOST_WIDE_INT modesize = GET_MODE_BITSIZE (GET_MODE (inner));
1623 HOST_WIDE_INT len = INTVAL (XEXP (*op0, 1));
1624 HOST_WIDE_INT pos = INTVAL (XEXP (*op0, 2));
1625
1626 if (len > 0 && len < modesize
1627 && pos >= 0 && pos + len <= modesize
1628 && modesize <= HOST_BITS_PER_WIDE_INT)
1629 {
1630 unsigned HOST_WIDE_INT block;
b422d8c0 1631 block = (HOST_WIDE_INT_1U << len) - 1;
ebe32bb0 1632 block <<= modesize - pos - len;
1633
1634 *op0 = gen_rtx_AND (GET_MODE (inner), inner,
1635 gen_int_mode (block, GET_MODE (inner)));
1636 }
1637 }
1638
1639 /* Narrow AND of memory against immediate to enable TM. */
1640 if ((*code == EQ || *code == NE)
1641 && *op1 == const0_rtx
1642 && GET_CODE (*op0) == AND
1643 && GET_CODE (XEXP (*op0, 1)) == CONST_INT
1644 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0, 0))))
1645 {
1646 rtx inner = XEXP (*op0, 0);
1647 rtx mask = XEXP (*op0, 1);
1648
1649 /* Ignore paradoxical SUBREGs if all extra bits are masked out. */
1650 if (GET_CODE (inner) == SUBREG
1651 && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (inner)))
1652 && (GET_MODE_SIZE (GET_MODE (inner))
1653 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner))))
1654 && ((INTVAL (mask)
9f522e0c 1655 & GET_MODE_MASK (GET_MODE (inner))
1656 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (inner))))
ebe32bb0 1657 == 0))
1658 inner = SUBREG_REG (inner);
1659
1660 /* Do not change volatile MEMs. */
1661 if (MEM_P (inner) && !MEM_VOLATILE_P (inner))
1662 {
1663 int part = s390_single_part (XEXP (*op0, 1),
1664 GET_MODE (inner), QImode, 0);
1665 if (part >= 0)
1666 {
1667 mask = gen_int_mode (s390_extract_part (mask, QImode, 0), QImode);
1668 inner = adjust_address_nv (inner, QImode, part);
1669 *op0 = gen_rtx_AND (QImode, inner, mask);
1670 }
1671 }
1672 }
1673
1674 /* Narrow comparisons against 0xffff to HImode if possible. */
ebe32bb0 1675 if ((*code == EQ || *code == NE)
1676 && GET_CODE (*op1) == CONST_INT
1677 && INTVAL (*op1) == 0xffff
1678 && SCALAR_INT_MODE_P (GET_MODE (*op0))
ffead1ca 1679 && (nonzero_bits (*op0, GET_MODE (*op0))
b422d8c0 1680 & ~HOST_WIDE_INT_UC (0xffff)) == 0)
ebe32bb0 1681 {
1682 *op0 = gen_lowpart (HImode, *op0);
1683 *op1 = constm1_rtx;
1684 }
80b53886 1685
5ada7a14 1686 /* Remove redundant UNSPEC_STRCMPCC_TO_INT conversions if possible. */
80b53886 1687 if (GET_CODE (*op0) == UNSPEC
5ada7a14 1688 && XINT (*op0, 1) == UNSPEC_STRCMPCC_TO_INT
80b53886 1689 && XVECLEN (*op0, 0) == 1
1690 && GET_MODE (XVECEXP (*op0, 0, 0)) == CCUmode
1691 && GET_CODE (XVECEXP (*op0, 0, 0)) == REG
1692 && REGNO (XVECEXP (*op0, 0, 0)) == CC_REGNUM
1693 && *op1 == const0_rtx)
1694 {
1695 enum rtx_code new_code = UNKNOWN;
1696 switch (*code)
1697 {
1698 case EQ: new_code = EQ; break;
1699 case NE: new_code = NE; break;
dd16a4bd 1700 case LT: new_code = GTU; break;
1701 case GT: new_code = LTU; break;
1702 case LE: new_code = GEU; break;
1703 case GE: new_code = LEU; break;
80b53886 1704 default: break;
1705 }
1706
1707 if (new_code != UNKNOWN)
1708 {
1709 *op0 = XVECEXP (*op0, 0, 0);
1710 *code = new_code;
1711 }
1712 }
9c93d843 1713
5ada7a14 1714 /* Remove redundant UNSPEC_CC_TO_INT conversions if possible. */
27784c70 1715 if (GET_CODE (*op0) == UNSPEC
5ada7a14 1716 && XINT (*op0, 1) == UNSPEC_CC_TO_INT
27784c70 1717 && XVECLEN (*op0, 0) == 1
27784c70 1718 && GET_CODE (XVECEXP (*op0, 0, 0)) == REG
1719 && REGNO (XVECEXP (*op0, 0, 0)) == CC_REGNUM
5ada7a14 1720 && CONST_INT_P (*op1))
27784c70 1721 {
1722 enum rtx_code new_code = UNKNOWN;
5ada7a14 1723 switch (GET_MODE (XVECEXP (*op0, 0, 0)))
27784c70 1724 {
916ace94 1725 case E_CCZmode:
1726 case E_CCRAWmode:
5ada7a14 1727 switch (*code)
1728 {
1729 case EQ: new_code = EQ; break;
1730 case NE: new_code = NE; break;
1731 default: break;
1732 }
1733 break;
1734 default: break;
27784c70 1735 }
1736
1737 if (new_code != UNKNOWN)
1738 {
5ada7a14 1739 /* For CCRAWmode put the required cc mask into the second
1740 operand. */
9f522e0c 1741 if (GET_MODE (XVECEXP (*op0, 0, 0)) == CCRAWmode
1742 && INTVAL (*op1) >= 0 && INTVAL (*op1) <= 3)
5ada7a14 1743 *op1 = gen_rtx_CONST_INT (VOIDmode, 1 << (3 - INTVAL (*op1)));
27784c70 1744 *op0 = XVECEXP (*op0, 0, 0);
1745 *code = new_code;
1746 }
1747 }
1748
9c93d843 1749 /* Simplify cascaded EQ, NE with const0_rtx. */
1750 if ((*code == NE || *code == EQ)
1751 && (GET_CODE (*op0) == EQ || GET_CODE (*op0) == NE)
1752 && GET_MODE (*op0) == SImode
1753 && GET_MODE (XEXP (*op0, 0)) == CCZ1mode
1754 && REG_P (XEXP (*op0, 0))
1755 && XEXP (*op0, 1) == const0_rtx
1756 && *op1 == const0_rtx)
1757 {
1758 if ((*code == EQ && GET_CODE (*op0) == NE)
9f522e0c 1759 || (*code == NE && GET_CODE (*op0) == EQ))
9c93d843 1760 *code = EQ;
1761 else
1762 *code = NE;
1763 *op0 = XEXP (*op0, 0);
1764 }
a0631a8a 1765
1766 /* Prefer register over memory as first operand. */
1767 if (MEM_P (*op0) && REG_P (*op1))
1768 {
1769 rtx tem = *op0; *op0 = *op1; *op1 = tem;
d5065e6e 1770 *code = (int)swap_condition ((enum rtx_code)*code);
a0631a8a 1771 }
26233f43 1772
e17ed6ec 1773 /* A comparison result is compared against zero. Replace it with
1774 the (perhaps inverted) original comparison.
1775 This probably should be done by simplify_relational_operation. */
1776 if ((*code == EQ || *code == NE)
1777 && *op1 == const0_rtx
1778 && COMPARISON_P (*op0)
1779 && CC_REG_P (XEXP (*op0, 0)))
1780 {
1781 enum rtx_code new_code;
1782
1783 if (*code == EQ)
1784 new_code = reversed_comparison_code_parts (GET_CODE (*op0),
1785 XEXP (*op0, 0),
1786 XEXP (*op1, 0), NULL);
1787 else
1788 new_code = GET_CODE (*op0);
1789
1790 if (new_code != UNKNOWN)
1791 {
1792 *code = new_code;
1793 *op1 = XEXP (*op0, 1);
1794 *op0 = XEXP (*op0, 0);
1795 }
1796 }
92d5e9eb 1797
1798 /* ~a==b -> ~(a^b)==0 ~a!=b -> ~(a^b)!=0 */
1799 if (TARGET_ARCH13
1800 && (*code == EQ || *code == NE)
1801 && (GET_MODE (*op0) == DImode || GET_MODE (*op0) == SImode)
1802 && GET_CODE (*op0) == NOT)
1803 {
1804 machine_mode mode = GET_MODE (*op0);
1805 *op0 = gen_rtx_XOR (mode, XEXP (*op0, 0), *op1);
1806 *op0 = gen_rtx_NOT (mode, *op0);
1807 *op1 = const0_rtx;
1808 }
1809
1810 /* a&b == -1 -> ~a|~b == 0 a|b == -1 -> ~a&~b == 0 */
1811 if (TARGET_ARCH13
1812 && (*code == EQ || *code == NE)
1813 && (GET_CODE (*op0) == AND || GET_CODE (*op0) == IOR)
1814 && (GET_MODE (*op0) == DImode || GET_MODE (*op0) == SImode)
1815 && CONST_INT_P (*op1)
1816 && *op1 == constm1_rtx)
1817 {
1818 machine_mode mode = GET_MODE (*op0);
1819 rtx op00 = gen_rtx_NOT (mode, XEXP (*op0, 0));
1820 rtx op01 = gen_rtx_NOT (mode, XEXP (*op0, 1));
1821
1822 if (GET_CODE (*op0) == AND)
1823 *op0 = gen_rtx_IOR (mode, op00, op01);
1824 else
1825 *op0 = gen_rtx_AND (mode, op00, op01);
1826
1827 *op1 = const0_rtx;
1828 }
ebe32bb0 1829}
1830
26233f43 1831
0d656e8b 1832/* Emit a compare instruction suitable to implement the comparison
1833 OP0 CODE OP1. Return the correct condition RTL to be placed in
1834 the IF_THEN_ELSE of the conditional branch testing the result. */
1835
1836rtx
1837s390_emit_compare (enum rtx_code code, rtx op0, rtx op1)
1838{
3754d046 1839 machine_mode mode = s390_select_ccmode (code, op0, op1);
8e58aded 1840 rtx cc;
0d656e8b 1841
29c098f6 1842 if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
8e58aded 1843 {
26233f43 1844 /* Do not output a redundant compare instruction if a
1845 compare_and_swap pattern already computed the result and the
1846 machine modes are compatible. */
8e58aded 1847 gcc_assert (s390_cc_modes_compatible (GET_MODE (op0), mode)
1848 == GET_MODE (op0));
1849 cc = op0;
1850 }
891e3096 1851 else
1852 {
8e58aded 1853 cc = gen_rtx_REG (mode, CC_REGNUM);
d1f9b275 1854 emit_insn (gen_rtx_SET (cc, gen_rtx_COMPARE (mode, op0, op1)));
891e3096 1855 }
8e58aded 1856
ffead1ca 1857 return gen_rtx_fmt_ee (code, VOIDmode, cc, const0_rtx);
0d656e8b 1858}
1859
918db08a 1860/* If MEM is not a legitimate compare-and-swap memory operand, return a new
1861 MEM, whose address is a pseudo containing the original MEM's address. */
1862
1863static rtx
1864s390_legitimize_cs_operand (rtx mem)
1865{
1866 rtx tmp;
1867
1868 if (!contains_symbol_ref_p (mem))
1869 return mem;
1870 tmp = gen_reg_rtx (Pmode);
1871 emit_move_insn (tmp, copy_rtx (XEXP (mem, 0)));
1872 return change_address (mem, VOIDmode, tmp);
1873}
1874
8deb3959 1875/* Emit a SImode compare and swap instruction setting MEM to NEW_RTX if OLD
db1f11e3 1876 matches CMP.
1877 Return the correct condition RTL to be placed in the IF_THEN_ELSE of the
1878 conditional branch testing the result. */
1879
1880static rtx
8c753480 1881s390_emit_compare_and_swap (enum rtx_code code, rtx old, rtx mem,
d90d26d8 1882 rtx cmp, rtx new_rtx, machine_mode ccmode)
db1f11e3 1883{
d90d26d8 1884 rtx cc;
1885
918db08a 1886 mem = s390_legitimize_cs_operand (mem);
d90d26d8 1887 cc = gen_rtx_REG (ccmode, CC_REGNUM);
1888 switch (GET_MODE (mem))
1889 {
916ace94 1890 case E_SImode:
d90d26d8 1891 emit_insn (gen_atomic_compare_and_swapsi_internal (old, mem, cmp,
1892 new_rtx, cc));
1893 break;
916ace94 1894 case E_DImode:
d90d26d8 1895 emit_insn (gen_atomic_compare_and_swapdi_internal (old, mem, cmp,
1896 new_rtx, cc));
1897 break;
916ace94 1898 case E_TImode:
d90d26d8 1899 emit_insn (gen_atomic_compare_and_swapti_internal (old, mem, cmp,
1900 new_rtx, cc));
1901 break;
916ace94 1902 case E_QImode:
1903 case E_HImode:
d90d26d8 1904 default:
1905 gcc_unreachable ();
1906 }
1907 return s390_emit_compare (code, cc, const0_rtx);
db1f11e3 1908}
1909
5ada7a14 1910/* Emit a jump instruction to TARGET and return it. If COND is
1911 NULL_RTX, emit an unconditional jump, else a conditional jump under
1912 condition COND. */
0d656e8b 1913
93e0956b 1914rtx_insn *
0d656e8b 1915s390_emit_jump (rtx target, rtx cond)
1916{
1917 rtx insn;
1918
1919 target = gen_rtx_LABEL_REF (VOIDmode, target);
1920 if (cond)
1921 target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, target, pc_rtx);
1922
d1f9b275 1923 insn = gen_rtx_SET (pc_rtx, target);
5ada7a14 1924 return emit_jump_insn (insn);
0d656e8b 1925}
1926
f81e845f 1927/* Return branch condition mask to implement a branch
80b53886 1928 specified by CODE. Return -1 for invalid comparisons. */
2eb8fe23 1929
8cc5de33 1930int
b40da9a7 1931s390_branch_condition_mask (rtx code)
f81e845f 1932{
2eb8fe23 1933 const int CC0 = 1 << 3;
1934 const int CC1 = 1 << 2;
1935 const int CC2 = 1 << 1;
1936 const int CC3 = 1 << 0;
1937
32eda510 1938 gcc_assert (GET_CODE (XEXP (code, 0)) == REG);
1939 gcc_assert (REGNO (XEXP (code, 0)) == CC_REGNUM);
5ada7a14 1940 gcc_assert (XEXP (code, 1) == const0_rtx
1941 || (GET_MODE (XEXP (code, 0)) == CCRAWmode
1942 && CONST_INT_P (XEXP (code, 1))));
1943
2eb8fe23 1944
1945 switch (GET_MODE (XEXP (code, 0)))
1946 {
916ace94 1947 case E_CCZmode:
1948 case E_CCZ1mode:
2eb8fe23 1949 switch (GET_CODE (code))
9f522e0c 1950 {
1951 case EQ: return CC0;
2eb8fe23 1952 case NE: return CC1 | CC2 | CC3;
80b53886 1953 default: return -1;
9f522e0c 1954 }
2eb8fe23 1955 break;
1956
916ace94 1957 case E_CCT1mode:
c6821d1c 1958 switch (GET_CODE (code))
9f522e0c 1959 {
1960 case EQ: return CC1;
c6821d1c 1961 case NE: return CC0 | CC2 | CC3;
80b53886 1962 default: return -1;
9f522e0c 1963 }
c6821d1c 1964 break;
1965
916ace94 1966 case E_CCT2mode:
c6821d1c 1967 switch (GET_CODE (code))
9f522e0c 1968 {
1969 case EQ: return CC2;
c6821d1c 1970 case NE: return CC0 | CC1 | CC3;
80b53886 1971 default: return -1;
9f522e0c 1972 }
c6821d1c 1973 break;
1974
916ace94 1975 case E_CCT3mode:
c6821d1c 1976 switch (GET_CODE (code))
9f522e0c 1977 {
1978 case EQ: return CC3;
c6821d1c 1979 case NE: return CC0 | CC1 | CC2;
80b53886 1980 default: return -1;
9f522e0c 1981 }
c6821d1c 1982 break;
1983
916ace94 1984 case E_CCLmode:
2eb8fe23 1985 switch (GET_CODE (code))
9f522e0c 1986 {
1987 case EQ: return CC0 | CC2;
2eb8fe23 1988 case NE: return CC1 | CC3;
80b53886 1989 default: return -1;
9f522e0c 1990 }
c6821d1c 1991 break;
1992
916ace94 1993 case E_CCL1mode:
c6821d1c 1994 switch (GET_CODE (code))
9f522e0c 1995 {
c6821d1c 1996 case LTU: return CC2 | CC3; /* carry */
1997 case GEU: return CC0 | CC1; /* no carry */
80b53886 1998 default: return -1;
9f522e0c 1999 }
c6821d1c 2000 break;
2001
916ace94 2002 case E_CCL2mode:
c6821d1c 2003 switch (GET_CODE (code))
9f522e0c 2004 {
c6821d1c 2005 case GTU: return CC0 | CC1; /* borrow */
2006 case LEU: return CC2 | CC3; /* no borrow */
80b53886 2007 default: return -1;
9f522e0c 2008 }
2eb8fe23 2009 break;
2010
916ace94 2011 case E_CCL3mode:
3b699fc7 2012 switch (GET_CODE (code))
2013 {
2014 case EQ: return CC0 | CC2;
2015 case NE: return CC1 | CC3;
2016 case LTU: return CC1;
2017 case GTU: return CC3;
2018 case LEU: return CC1 | CC2;
2019 case GEU: return CC2 | CC3;
80b53886 2020 default: return -1;
3b699fc7 2021 }
2022
916ace94 2023 case E_CCUmode:
2eb8fe23 2024 switch (GET_CODE (code))
9f522e0c 2025 {
2026 case EQ: return CC0;
2027 case NE: return CC1 | CC2 | CC3;
2028 case LTU: return CC1;
2029 case GTU: return CC2;
2030 case LEU: return CC0 | CC1;
2031 case GEU: return CC0 | CC2;
80b53886 2032 default: return -1;
9f522e0c 2033 }
2eb8fe23 2034 break;
2035
916ace94 2036 case E_CCURmode:
c6821d1c 2037 switch (GET_CODE (code))
9f522e0c 2038 {
2039 case EQ: return CC0;
2040 case NE: return CC2 | CC1 | CC3;
2041 case LTU: return CC2;
2042 case GTU: return CC1;
2043 case LEU: return CC0 | CC2;
2044 case GEU: return CC0 | CC1;
80b53886 2045 default: return -1;
9f522e0c 2046 }
c6821d1c 2047 break;
2048
916ace94 2049 case E_CCAPmode:
3c482144 2050 switch (GET_CODE (code))
9f522e0c 2051 {
2052 case EQ: return CC0;
2053 case NE: return CC1 | CC2 | CC3;
2054 case LT: return CC1 | CC3;
2055 case GT: return CC2;
2056 case LE: return CC0 | CC1 | CC3;
2057 case GE: return CC0 | CC2;
80b53886 2058 default: return -1;
9f522e0c 2059 }
3c482144 2060 break;
2061
916ace94 2062 case E_CCANmode:
3c482144 2063 switch (GET_CODE (code))
9f522e0c 2064 {
2065 case EQ: return CC0;
2066 case NE: return CC1 | CC2 | CC3;
2067 case LT: return CC1;
2068 case GT: return CC2 | CC3;
2069 case LE: return CC0 | CC1;
2070 case GE: return CC0 | CC2 | CC3;
80b53886 2071 default: return -1;
9f522e0c 2072 }
3c482144 2073 break;
2074
1720014d 2075 case E_CCOmode:
2076 switch (GET_CODE (code))
2077 {
2078 case EQ: return CC0 | CC1 | CC2;
2079 case NE: return CC3;
2080 default: return -1;
2081 }
2082 break;
2083
916ace94 2084 case E_CCSmode:
2eb8fe23 2085 switch (GET_CODE (code))
9f522e0c 2086 {
2087 case EQ: return CC0;
2088 case NE: return CC1 | CC2 | CC3;
2089 case LT: return CC1;
2090 case GT: return CC2;
2091 case LE: return CC0 | CC1;
2092 case GE: return CC0 | CC2;
2eb8fe23 2093 case UNORDERED: return CC3;
2094 case ORDERED: return CC0 | CC1 | CC2;
2095 case UNEQ: return CC0 | CC3;
9f522e0c 2096 case UNLT: return CC1 | CC3;
2097 case UNGT: return CC2 | CC3;
2098 case UNLE: return CC0 | CC1 | CC3;
2099 case UNGE: return CC0 | CC2 | CC3;
2eb8fe23 2100 case LTGT: return CC1 | CC2;
80b53886 2101 default: return -1;
9f522e0c 2102 }
c6821d1c 2103 break;
2104
916ace94 2105 case E_CCSRmode:
c6821d1c 2106 switch (GET_CODE (code))
9f522e0c 2107 {
2108 case EQ: return CC0;
2109 case NE: return CC2 | CC1 | CC3;
2110 case LT: return CC2;
2111 case GT: return CC1;
2112 case LE: return CC0 | CC2;
2113 case GE: return CC0 | CC1;
c6821d1c 2114 case UNORDERED: return CC3;
2115 case ORDERED: return CC0 | CC2 | CC1;
2116 case UNEQ: return CC0 | CC3;
9f522e0c 2117 case UNLT: return CC2 | CC3;
2118 case UNGT: return CC1 | CC3;
2119 case UNLE: return CC0 | CC2 | CC3;
2120 case UNGE: return CC0 | CC1 | CC3;
c6821d1c 2121 case LTGT: return CC2 | CC1;
80b53886 2122 default: return -1;
9f522e0c 2123 }
c6821d1c 2124 break;
2eb8fe23 2125
26233f43 2126 /* Vector comparison modes. */
abc57c35 2127 /* CC2 will never be set. It however is part of the negated
2128 masks. */
916ace94 2129 case E_CCVIALLmode:
26233f43 2130 switch (GET_CODE (code))
2131 {
abc57c35 2132 case EQ:
2133 case GTU:
2134 case GT:
2135 case GE: return CC0;
2136 /* The inverted modes are in fact *any* modes. */
2137 case NE:
2138 case LEU:
2139 case LE:
2140 case LT: return CC3 | CC1 | CC2;
26233f43 2141 default: return -1;
2142 }
07f32359 2143
916ace94 2144 case E_CCVIANYmode:
07f32359 2145 switch (GET_CODE (code))
2146 {
abc57c35 2147 case EQ:
2148 case GTU:
2149 case GT:
2150 case GE: return CC0 | CC1;
2151 /* The inverted modes are in fact *all* modes. */
2152 case NE:
2153 case LEU:
2154 case LE:
2155 case LT: return CC3 | CC2;
07f32359 2156 default: return -1;
2157 }
916ace94 2158 case E_CCVFALLmode:
26233f43 2159 switch (GET_CODE (code))
2160 {
abc57c35 2161 case EQ:
2162 case GT:
26233f43 2163 case GE: return CC0;
abc57c35 2164 /* The inverted modes are in fact *any* modes. */
2165 case NE:
2166 case UNLE:
2167 case UNLT: return CC3 | CC1 | CC2;
26233f43 2168 default: return -1;
2169 }
07f32359 2170
916ace94 2171 case E_CCVFANYmode:
07f32359 2172 switch (GET_CODE (code))
2173 {
abc57c35 2174 case EQ:
2175 case GT:
07f32359 2176 case GE: return CC0 | CC1;
abc57c35 2177 /* The inverted modes are in fact *all* modes. */
2178 case NE:
2179 case UNLE:
2180 case UNLT: return CC3 | CC2;
07f32359 2181 default: return -1;
2182 }
2183
916ace94 2184 case E_CCRAWmode:
5ada7a14 2185 switch (GET_CODE (code))
2186 {
2187 case EQ:
2188 return INTVAL (XEXP (code, 1));
2189 case NE:
2190 return (INTVAL (XEXP (code, 1))) ^ 0xf;
2191 default:
2192 gcc_unreachable ();
2193 }
2194
2eb8fe23 2195 default:
80b53886 2196 return -1;
2eb8fe23 2197 }
2198}
2199
e68d6a13 2200
2201/* Return branch condition mask to implement a compare and branch
2202 specified by CODE. Return -1 for invalid comparisons. */
2203
2204int
2205s390_compare_and_branch_condition_mask (rtx code)
2206{
2207 const int CC0 = 1 << 3;
2208 const int CC1 = 1 << 2;
2209 const int CC2 = 1 << 1;
2210
2211 switch (GET_CODE (code))
2212 {
2213 case EQ:
2214 return CC0;
2215 case NE:
2216 return CC1 | CC2;
2217 case LT:
2218 case LTU:
2219 return CC1;
2220 case GT:
2221 case GTU:
2222 return CC2;
2223 case LE:
2224 case LEU:
2225 return CC0 | CC1;
2226 case GE:
2227 case GEU:
2228 return CC0 | CC2;
2229 default:
2230 gcc_unreachable ();
2231 }
2232 return -1;
2233}
2234
f81e845f 2235/* If INV is false, return assembler mnemonic string to implement
2236 a branch specified by CODE. If INV is true, return mnemonic
2eb8fe23 2237 for the corresponding inverted branch. */
2238
2239static const char *
b40da9a7 2240s390_branch_condition_mnemonic (rtx code, int inv)
2eb8fe23 2241{
e68d6a13 2242 int mask;
2243
c8834c5f 2244 static const char *const mnemonic[16] =
2eb8fe23 2245 {
2246 NULL, "o", "h", "nle",
2247 "l", "nhe", "lh", "ne",
2248 "e", "nlh", "he", "nl",
2249 "le", "nh", "no", NULL
2250 };
2251
e68d6a13 2252 if (GET_CODE (XEXP (code, 0)) == REG
2253 && REGNO (XEXP (code, 0)) == CC_REGNUM
5ada7a14 2254 && (XEXP (code, 1) == const0_rtx
2255 || (GET_MODE (XEXP (code, 0)) == CCRAWmode
2256 && CONST_INT_P (XEXP (code, 1)))))
e68d6a13 2257 mask = s390_branch_condition_mask (code);
2258 else
2259 mask = s390_compare_and_branch_condition_mask (code);
2260
80b53886 2261 gcc_assert (mask >= 0);
2eb8fe23 2262
2263 if (inv)
2264 mask ^= 15;
2265
32eda510 2266 gcc_assert (mask >= 1 && mask <= 14);
2eb8fe23 2267
2268 return mnemonic[mask];
2269}
2270
64a1078f 2271/* Return the part of op which has a value different from def.
2272 The size of the part is determined by mode.
f588eb9f 2273 Use this function only if you already know that op really
64a1078f 2274 contains such a part. */
8b4a4127 2275
64a1078f 2276unsigned HOST_WIDE_INT
3754d046 2277s390_extract_part (rtx op, machine_mode mode, int def)
8b4a4127 2278{
64a1078f 2279 unsigned HOST_WIDE_INT value = 0;
2280 int max_parts = HOST_BITS_PER_WIDE_INT / GET_MODE_BITSIZE (mode);
2281 int part_bits = GET_MODE_BITSIZE (mode);
b422d8c0 2282 unsigned HOST_WIDE_INT part_mask = (HOST_WIDE_INT_1U << part_bits) - 1;
64a1078f 2283 int i;
f588eb9f 2284
64a1078f 2285 for (i = 0; i < max_parts; i++)
8b4a4127 2286 {
64a1078f 2287 if (i == 0)
b422d8c0 2288 value = UINTVAL (op);
8b4a4127 2289 else
64a1078f 2290 value >>= part_bits;
f588eb9f 2291
64a1078f 2292 if ((value & part_mask) != (def & part_mask))
2293 return value & part_mask;
8b4a4127 2294 }
f588eb9f 2295
32eda510 2296 gcc_unreachable ();
8b4a4127 2297}
2298
2299/* If OP is an integer constant of mode MODE with exactly one
64a1078f 2300 part of mode PART_MODE unequal to DEF, return the number of that
2301 part. Otherwise, return -1. */
8b4a4127 2302
2303int
f588eb9f 2304s390_single_part (rtx op,
3754d046 2305 machine_mode mode,
2306 machine_mode part_mode,
64a1078f 2307 int def)
2308{
2309 unsigned HOST_WIDE_INT value = 0;
2310 int n_parts = GET_MODE_SIZE (mode) / GET_MODE_SIZE (part_mode);
0451e449 2311 unsigned HOST_WIDE_INT part_mask
b422d8c0 2312 = (HOST_WIDE_INT_1U << GET_MODE_BITSIZE (part_mode)) - 1;
64a1078f 2313 int i, part = -1;
2314
2315 if (GET_CODE (op) != CONST_INT)
2316 return -1;
f588eb9f 2317
64a1078f 2318 for (i = 0; i < n_parts; i++)
2319 {
2320 if (i == 0)
b422d8c0 2321 value = UINTVAL (op);
8b4a4127 2322 else
64a1078f 2323 value >>= GET_MODE_BITSIZE (part_mode);
f588eb9f 2324
64a1078f 2325 if ((value & part_mask) != (def & part_mask))
2326 {
2327 if (part != -1)
2328 return -1;
2329 else
2330 part = i;
2331 }
8b4a4127 2332 }
64a1078f 2333 return part == -1 ? -1 : n_parts - 1 - part;
8b4a4127 2334}
2335
e68d6a13 2336/* Return true if IN contains a contiguous bitfield in the lower SIZE
e64f5133 2337 bits and no other bits are set in (the lower SIZE bits of) IN.
e68d6a13 2338
e64f5133 2339 PSTART and PEND can be used to obtain the start and end
2340 position (inclusive) of the bitfield relative to 64
2341 bits. *PSTART / *PEND gives the position of the first/last bit
2342 of the bitfield counting from the highest order bit starting
2343 with zero. */
e68d6a13 2344
2345bool
e64f5133 2346s390_contiguous_bitmask_nowrap_p (unsigned HOST_WIDE_INT in, int size,
2347 int *pstart, int *pend)
e68d6a13 2348{
e64f5133 2349 int start;
2350 int end = -1;
b422d8c0 2351 int lowbit = HOST_BITS_PER_WIDE_INT - 1;
2352 int highbit = HOST_BITS_PER_WIDE_INT - size;
2353 unsigned HOST_WIDE_INT bitmask = HOST_WIDE_INT_1U;
e64f5133 2354
2355 gcc_assert (!!pstart == !!pend);
2356 for (start = lowbit; start >= highbit; bitmask <<= 1, start--)
2357 if (end == -1)
2358 {
2359 /* Look for the rightmost bit of a contiguous range of ones. */
2360 if (bitmask & in)
2361 /* Found it. */
2362 end = start;
2363 }
2364 else
2365 {
2366 /* Look for the firt zero bit after the range of ones. */
2367 if (! (bitmask & in))
2368 /* Found it. */
2369 break;
2370 }
2371 /* We're one past the last one-bit. */
2372 start++;
e68d6a13 2373
e64f5133 2374 if (end == -1)
2375 /* No one bits found. */
2376 return false;
2377
2378 if (start > highbit)
e68d6a13 2379 {
e64f5133 2380 unsigned HOST_WIDE_INT mask;
2381
2382 /* Calculate a mask for all bits beyond the contiguous bits. */
b422d8c0 2383 mask = ((~HOST_WIDE_INT_0U >> highbit)
2384 & (~HOST_WIDE_INT_0U << (lowbit - start + 1)));
e64f5133 2385 if (mask & in)
2386 /* There are more bits set beyond the first range of one bits. */
2387 return false;
e68d6a13 2388 }
2389
e64f5133 2390 if (pstart)
2391 {
2392 *pstart = start;
2393 *pend = end;
2394 }
e68d6a13 2395
e64f5133 2396 return true;
2397}
e68d6a13 2398
e64f5133 2399/* Same as s390_contiguous_bitmask_nowrap_p but also returns true
2400 if ~IN contains a contiguous bitfield. In that case, *END is <
2401 *START.
76a4c804 2402
e64f5133 2403 If WRAP_P is true, a bitmask that wraps around is also tested.
2404 When a wraparoud occurs *START is greater than *END (in
2405 non-null pointers), and the uppermost (64 - SIZE) bits are thus
2406 part of the range. If WRAP_P is false, no wraparound is
2407 tested. */
e68d6a13 2408
e64f5133 2409bool
2410s390_contiguous_bitmask_p (unsigned HOST_WIDE_INT in, bool wrap_p,
2411 int size, int *start, int *end)
2412{
b422d8c0 2413 int bs = HOST_BITS_PER_WIDE_INT;
e64f5133 2414 bool b;
2415
2416 gcc_assert (!!start == !!end);
b422d8c0 2417 if ((in & ((~HOST_WIDE_INT_0U) >> (bs - size))) == 0)
e64f5133 2418 /* This cannot be expressed as a contiguous bitmask. Exit early because
2419 the second call of s390_contiguous_bitmask_nowrap_p would accept this as
2420 a valid bitmask. */
e68d6a13 2421 return false;
e64f5133 2422 b = s390_contiguous_bitmask_nowrap_p (in, size, start, end);
2423 if (b)
2424 return true;
2425 if (! wrap_p)
2426 return false;
2427 b = s390_contiguous_bitmask_nowrap_p (~in, size, start, end);
2428 if (b && start)
2429 {
2430 int s = *start;
2431 int e = *end;
e68d6a13 2432
e64f5133 2433 gcc_assert (s >= 1);
2434 *start = ((e + 1) & (bs - 1));
2435 *end = ((s - 1 + bs) & (bs - 1));
2436 }
e68d6a13 2437
e64f5133 2438 return b;
e68d6a13 2439}
2440
76a4c804 2441/* Return true if OP contains the same contiguous bitfield in *all*
2442 its elements. START and END can be used to obtain the start and
2443 end position of the bitfield.
2444
2445 START/STOP give the position of the first/last bit of the bitfield
2446 counting from the lowest order bit starting with zero. In order to
2447 use these values for S/390 instructions this has to be converted to
2448 "bits big endian" style. */
2449
2450bool
2451s390_contiguous_bitmask_vector_p (rtx op, int *start, int *end)
2452{
2453 unsigned HOST_WIDE_INT mask;
e64f5133 2454 int size;
62fdb8e4 2455 rtx elt;
e64f5133 2456 bool b;
76a4c804 2457
e64f5133 2458 gcc_assert (!!start == !!end);
62fdb8e4 2459 if (!const_vec_duplicate_p (op, &elt)
2460 || !CONST_INT_P (elt))
76a4c804 2461 return false;
2462
76a4c804 2463 size = GET_MODE_UNIT_BITSIZE (GET_MODE (op));
f81e57c4 2464
2465 /* We cannot deal with V1TI/V1TF. This would require a vgmq. */
2466 if (size > 64)
2467 return false;
2468
62fdb8e4 2469 mask = UINTVAL (elt);
e64f5133 2470
2471 b = s390_contiguous_bitmask_p (mask, true, size, start, end);
2472 if (b)
76a4c804 2473 {
e64f5133 2474 if (start)
2475 {
b422d8c0 2476 *start -= (HOST_BITS_PER_WIDE_INT - size);
2477 *end -= (HOST_BITS_PER_WIDE_INT - size);
e64f5133 2478 }
76a4c804 2479 return true;
2480 }
e64f5133 2481 else
2482 return false;
76a4c804 2483}
2484
2485/* Return true if C consists only of byte chunks being either 0 or
2486 0xff. If MASK is !=NULL a byte mask is generated which is
2487 appropriate for the vector generate byte mask instruction. */
2488
2489bool
2490s390_bytemask_vector_p (rtx op, unsigned *mask)
2491{
2492 int i;
2493 unsigned tmp_mask = 0;
2494 int nunit, unit_size;
2495
2496 if (!VECTOR_MODE_P (GET_MODE (op))
2497 || GET_CODE (op) != CONST_VECTOR
2498 || !CONST_INT_P (XVECEXP (op, 0, 0)))
2499 return false;
2500
2501 nunit = GET_MODE_NUNITS (GET_MODE (op));
2502 unit_size = GET_MODE_UNIT_SIZE (GET_MODE (op));
2503
2504 for (i = 0; i < nunit; i++)
2505 {
2506 unsigned HOST_WIDE_INT c;
2507 int j;
2508
2509 if (!CONST_INT_P (XVECEXP (op, 0, i)))
2510 return false;
2511
2512 c = UINTVAL (XVECEXP (op, 0, i));
2513 for (j = 0; j < unit_size; j++)
2514 {
2515 if ((c & 0xff) != 0 && (c & 0xff) != 0xff)
2516 return false;
2517 tmp_mask |= (c & 1) << ((nunit - 1 - i) * unit_size + j);
2518 c = c >> BITS_PER_UNIT;
2519 }
2520 }
2521
2522 if (mask != NULL)
2523 *mask = tmp_mask;
2524
2525 return true;
2526}
2527
6bc28655 2528/* Check whether a rotate of ROTL followed by an AND of CONTIG is
2529 equivalent to a shift followed by the AND. In particular, CONTIG
2530 should not overlap the (rotated) bit 0/bit 63 gap. Negative values
2531 for ROTL indicate a rotate to the right. */
2532
2533bool
2534s390_extzv_shift_ok (int bitsize, int rotl, unsigned HOST_WIDE_INT contig)
2535{
e64f5133 2536 int start, end;
6bc28655 2537 bool ok;
2538
e64f5133 2539 ok = s390_contiguous_bitmask_nowrap_p (contig, bitsize, &start, &end);
6bc28655 2540 gcc_assert (ok);
2541
e64f5133 2542 if (rotl >= 0)
2543 return (64 - end >= rotl);
2544 else
2545 {
2546 /* Translate "- rotate right" in BITSIZE mode to "rotate left" in
2547 DIMode. */
2548 rotl = -rotl + (64 - bitsize);
2549 return (start >= rotl);
2550 }
6bc28655 2551}
2552
f81e845f 2553/* Check whether we can (and want to) split a double-word
2554 move in mode MODE from SRC to DST into two single-word
66795431 2555 moves, moving the subword FIRST_SUBWORD first. */
2556
2557bool
3754d046 2558s390_split_ok_p (rtx dst, rtx src, machine_mode mode, int first_subword)
66795431 2559{
76a4c804 2560 /* Floating point and vector registers cannot be split. */
2561 if (FP_REG_P (src) || FP_REG_P (dst) || VECTOR_REG_P (src) || VECTOR_REG_P (dst))
66795431 2562 return false;
2563
66795431 2564 /* Non-offsettable memory references cannot be split. */
2565 if ((GET_CODE (src) == MEM && !offsettable_memref_p (src))
2566 || (GET_CODE (dst) == MEM && !offsettable_memref_p (dst)))
2567 return false;
2568
2569 /* Moving the first subword must not clobber a register
2570 needed to move the second subword. */
2571 if (register_operand (dst, mode))
2572 {
2573 rtx subreg = operand_subword (dst, first_subword, 0, mode);
2574 if (reg_overlap_mentioned_p (subreg, src))
9f522e0c 2575 return false;
66795431 2576 }
2577
2578 return true;
2579}
2580
74bdf297 2581/* Return true if it can be proven that [MEM1, MEM1 + SIZE]
2582 and [MEM2, MEM2 + SIZE] do overlap and false
2583 otherwise. */
2584
2585bool
2586s390_overlap_p (rtx mem1, rtx mem2, HOST_WIDE_INT size)
2587{
2588 rtx addr1, addr2, addr_delta;
2589 HOST_WIDE_INT delta;
2590
2591 if (GET_CODE (mem1) != MEM || GET_CODE (mem2) != MEM)
2592 return true;
2593
2594 if (size == 0)
2595 return false;
2596
2597 addr1 = XEXP (mem1, 0);
2598 addr2 = XEXP (mem2, 0);
2599
2600 addr_delta = simplify_binary_operation (MINUS, Pmode, addr2, addr1);
2601
2602 /* This overlapping check is used by peepholes merging memory block operations.
2603 Overlapping operations would otherwise be recognized by the S/390 hardware
ffead1ca 2604 and would fall back to a slower implementation. Allowing overlapping
74bdf297 2605 operations would lead to slow code but not to wrong code. Therefore we are
ffead1ca 2606 somewhat optimistic if we cannot prove that the memory blocks are
74bdf297 2607 overlapping.
2608 That's why we return false here although this may accept operations on
2609 overlapping memory areas. */
2610 if (!addr_delta || GET_CODE (addr_delta) != CONST_INT)
2611 return false;
2612
2613 delta = INTVAL (addr_delta);
2614
2615 if (delta == 0
2616 || (delta > 0 && delta < size)
2617 || (delta < 0 && -delta < size))
2618 return true;
2619
2620 return false;
2621}
2622
9dffd3ff 2623/* Check whether the address of memory reference MEM2 equals exactly
2624 the address of memory reference MEM1 plus DELTA. Return true if
2625 we can prove this to be the case, false otherwise. */
2626
2627bool
2628s390_offset_p (rtx mem1, rtx mem2, rtx delta)
2629{
2630 rtx addr1, addr2, addr_delta;
2631
2632 if (GET_CODE (mem1) != MEM || GET_CODE (mem2) != MEM)
2633 return false;
2634
2635 addr1 = XEXP (mem1, 0);
2636 addr2 = XEXP (mem2, 0);
2637
2638 addr_delta = simplify_binary_operation (MINUS, Pmode, addr2, addr1);
2639 if (!addr_delta || !rtx_equal_p (addr_delta, delta))
2640 return false;
2641
2642 return true;
2643}
2644
3e247a31 2645/* Expand logical operator CODE in mode MODE with operands OPERANDS. */
2646
2647void
3754d046 2648s390_expand_logical_operator (enum rtx_code code, machine_mode mode,
3e247a31 2649 rtx *operands)
2650{
3754d046 2651 machine_mode wmode = mode;
3e247a31 2652 rtx dst = operands[0];
2653 rtx src1 = operands[1];
2654 rtx src2 = operands[2];
2655 rtx op, clob, tem;
2656
2657 /* If we cannot handle the operation directly, use a temp register. */
2658 if (!s390_logical_operator_ok_p (operands))
2659 dst = gen_reg_rtx (mode);
2660
2661 /* QImode and HImode patterns make sense only if we have a destination
2662 in memory. Otherwise perform the operation in SImode. */
2663 if ((mode == QImode || mode == HImode) && GET_CODE (dst) != MEM)
2664 wmode = SImode;
2665
2666 /* Widen operands if required. */
2667 if (mode != wmode)
2668 {
2669 if (GET_CODE (dst) == SUBREG
2670 && (tem = simplify_subreg (wmode, dst, mode, 0)) != 0)
2671 dst = tem;
2672 else if (REG_P (dst))
2673 dst = gen_rtx_SUBREG (wmode, dst, 0);
2674 else
9f522e0c 2675 dst = gen_reg_rtx (wmode);
3e247a31 2676
2677 if (GET_CODE (src1) == SUBREG
2678 && (tem = simplify_subreg (wmode, src1, mode, 0)) != 0)
2679 src1 = tem;
2680 else if (GET_MODE (src1) != VOIDmode)
2681 src1 = gen_rtx_SUBREG (wmode, force_reg (mode, src1), 0);
2682
2683 if (GET_CODE (src2) == SUBREG
2684 && (tem = simplify_subreg (wmode, src2, mode, 0)) != 0)
2685 src2 = tem;
2686 else if (GET_MODE (src2) != VOIDmode)
2687 src2 = gen_rtx_SUBREG (wmode, force_reg (mode, src2), 0);
2688 }
2689
2690 /* Emit the instruction. */
d1f9b275 2691 op = gen_rtx_SET (dst, gen_rtx_fmt_ee (code, wmode, src1, src2));
3e247a31 2692 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
2693 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
2694
2695 /* Fix up the destination if needed. */
2696 if (dst != operands[0])
2697 emit_move_insn (operands[0], gen_lowpart (mode, dst));
2698}
2699
2700/* Check whether OPERANDS are OK for a logical operation (AND, IOR, XOR). */
2701
2702bool
2703s390_logical_operator_ok_p (rtx *operands)
2704{
2705 /* If the destination operand is in memory, it needs to coincide
2706 with one of the source operands. After reload, it has to be
2707 the first source operand. */
2708 if (GET_CODE (operands[0]) == MEM)
2709 return rtx_equal_p (operands[0], operands[1])
2710 || (!reload_completed && rtx_equal_p (operands[0], operands[2]));
2711
2712 return true;
2713}
2714
3f56e755 2715/* Narrow logical operation CODE of memory operand MEMOP with immediate
2716 operand IMMOP to switch from SS to SI type instructions. */
2717
2718void
2719s390_narrow_logical_operator (enum rtx_code code, rtx *memop, rtx *immop)
2720{
2721 int def = code == AND ? -1 : 0;
2722 HOST_WIDE_INT mask;
2723 int part;
2724
2725 gcc_assert (GET_CODE (*memop) == MEM);
2726 gcc_assert (!MEM_VOLATILE_P (*memop));
2727
2728 mask = s390_extract_part (*immop, QImode, def);
2729 part = s390_single_part (*immop, GET_MODE (*memop), QImode, def);
2730 gcc_assert (part >= 0);
2731
2732 *memop = adjust_address (*memop, QImode, part);
2733 *immop = gen_int_mode (mask, QImode);
2734}
2735
2eb8fe23 2736
875862bf 2737/* How to allocate a 'struct machine_function'. */
2738
2739static struct machine_function *
2740s390_init_machine_status (void)
2741{
25a27413 2742 return ggc_cleared_alloc<machine_function> ();
875862bf 2743}
2744
4673c1a0 2745/* Map for smallest class containing reg regno. */
2746
c8834c5f 2747const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
76a4c804 2748{ GENERAL_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS, /* 0 */
2749 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS, /* 4 */
2750 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS, /* 8 */
2751 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS, /* 12 */
2752 FP_REGS, FP_REGS, FP_REGS, FP_REGS, /* 16 */
2753 FP_REGS, FP_REGS, FP_REGS, FP_REGS, /* 20 */
2754 FP_REGS, FP_REGS, FP_REGS, FP_REGS, /* 24 */
2755 FP_REGS, FP_REGS, FP_REGS, FP_REGS, /* 28 */
2756 ADDR_REGS, CC_REGS, ADDR_REGS, ADDR_REGS, /* 32 */
2757 ACCESS_REGS, ACCESS_REGS, VEC_REGS, VEC_REGS, /* 36 */
2758 VEC_REGS, VEC_REGS, VEC_REGS, VEC_REGS, /* 40 */
2759 VEC_REGS, VEC_REGS, VEC_REGS, VEC_REGS, /* 44 */
2760 VEC_REGS, VEC_REGS, VEC_REGS, VEC_REGS, /* 48 */
2761 VEC_REGS, VEC_REGS /* 52 */
4673c1a0 2762};
2763
71343e6b 2764/* Return attribute type of insn. */
2765
2766static enum attr_type
ed3e6e5d 2767s390_safe_attr_type (rtx_insn *insn)
71343e6b 2768{
2769 if (recog_memoized (insn) >= 0)
2770 return get_attr_type (insn);
2771 else
2772 return TYPE_NONE;
2773}
4673c1a0 2774
50a42dec 2775/* Return attribute relative_long of insn. */
2776
2777static bool
2778s390_safe_relative_long_p (rtx_insn *insn)
2779{
2780 if (recog_memoized (insn) >= 0)
2781 return get_attr_relative_long (insn) == RELATIVE_LONG_YES;
2782 else
2783 return false;
2784}
2785
51aa1e9c 2786/* Return true if DISP is a valid short displacement. */
2787
e5537457 2788static bool
b40da9a7 2789s390_short_displacement (rtx disp)
51aa1e9c 2790{
2791 /* No displacement is OK. */
2792 if (!disp)
e5537457 2793 return true;
51aa1e9c 2794
a7b49046 2795 /* Without the long displacement facility we don't need to
2796 distingiush between long and short displacement. */
2797 if (!TARGET_LONG_DISPLACEMENT)
2798 return true;
2799
51aa1e9c 2800 /* Integer displacement in range. */
2801 if (GET_CODE (disp) == CONST_INT)
2802 return INTVAL (disp) >= 0 && INTVAL (disp) < 4096;
2803
2804 /* GOT offset is not OK, the GOT can be large. */
2805 if (GET_CODE (disp) == CONST
2806 && GET_CODE (XEXP (disp, 0)) == UNSPEC
a6e4e903 2807 && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOT
9f522e0c 2808 || XINT (XEXP (disp, 0), 1) == UNSPEC_GOTNTPOFF))
e5537457 2809 return false;
51aa1e9c 2810
2811 /* All other symbolic constants are literal pool references,
2812 which are OK as the literal pool must be small. */
2813 if (GET_CODE (disp) == CONST)
e5537457 2814 return true;
51aa1e9c 2815
e5537457 2816 return false;
51aa1e9c 2817}
2818
d4bb7aa3 2819/* Attempts to split `ref', which should be UNSPEC_LTREF, into (base + `disp').
2820 If successful, also determines the
06f2bd29 2821 following characteristics of `ref': `is_ptr' - whether it can be an
2822 LA argument, `is_base_ptr' - whether the resulting base is a well-known
2823 base register (stack/frame pointer, etc), `is_pool_ptr` - whether it is
2824 considered a literal pool pointer for purposes of avoiding two different
2825 literal pool pointers per insn during or after reload (`B' constraint). */
2826static bool
2827s390_decompose_constant_pool_ref (rtx *ref, rtx *disp, bool *is_ptr,
d4bb7aa3 2828 bool *is_base_ptr, bool *is_pool_ptr)
06f2bd29 2829{
2830 if (!*ref)
2831 return true;
2832
2833 if (GET_CODE (*ref) == UNSPEC)
2834 switch (XINT (*ref, 1))
2835 {
2836 case UNSPEC_LTREF:
2837 if (!*disp)
2838 *disp = gen_rtx_UNSPEC (Pmode,
2839 gen_rtvec (1, XVECEXP (*ref, 0, 0)),
2840 UNSPEC_LTREL_OFFSET);
2841 else
2842 return false;
2843
2844 *ref = XVECEXP (*ref, 0, 1);
2845 break;
2846
06f2bd29 2847 default:
2848 return false;
2849 }
2850
2851 if (!REG_P (*ref) || GET_MODE (*ref) != Pmode)
2852 return false;
2853
2854 if (REGNO (*ref) == STACK_POINTER_REGNUM
2855 || REGNO (*ref) == FRAME_POINTER_REGNUM
2856 || ((reload_completed || reload_in_progress)
2857 && frame_pointer_needed
2858 && REGNO (*ref) == HARD_FRAME_POINTER_REGNUM)
2859 || REGNO (*ref) == ARG_POINTER_REGNUM
2860 || (flag_pic
2861 && REGNO (*ref) == PIC_OFFSET_TABLE_REGNUM))
2862 *is_ptr = *is_base_ptr = true;
2863
2864 if ((reload_completed || reload_in_progress)
2865 && *ref == cfun->machine->base_reg)
2866 *is_ptr = *is_base_ptr = *is_pool_ptr = true;
2867
2868 return true;
2869}
2870
875862bf 2871/* Decompose a RTL expression ADDR for a memory address into
2872 its components, returned in OUT.
a5004c3d 2873
e5537457 2874 Returns false if ADDR is not a valid memory address, true
875862bf 2875 otherwise. If OUT is NULL, don't return the components,
2876 but check for validity only.
a5004c3d 2877
875862bf 2878 Note: Only addresses in canonical form are recognized.
2879 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
2880 canonical form so that they will be recognized. */
64a1078f 2881
875862bf 2882static int
edd89d66 2883s390_decompose_address (rtx addr, struct s390_address *out)
875862bf 2884{
2885 HOST_WIDE_INT offset = 0;
2886 rtx base = NULL_RTX;
2887 rtx indx = NULL_RTX;
2888 rtx disp = NULL_RTX;
2889 rtx orig_disp;
e5537457 2890 bool pointer = false;
2891 bool base_ptr = false;
2892 bool indx_ptr = false;
05b58257 2893 bool literal_pool = false;
2894
2895 /* We may need to substitute the literal pool base register into the address
2896 below. However, at this point we do not know which register is going to
2897 be used as base, so we substitute the arg pointer register. This is going
2898 to be treated as holding a pointer below -- it shouldn't be used for any
2899 other purpose. */
2900 rtx fake_pool_base = gen_rtx_REG (Pmode, ARG_POINTER_REGNUM);
3f56e755 2901
875862bf 2902 /* Decompose address into base + index + displacement. */
3f56e755 2903
875862bf 2904 if (GET_CODE (addr) == REG || GET_CODE (addr) == UNSPEC)
2905 base = addr;
3f56e755 2906
875862bf 2907 else if (GET_CODE (addr) == PLUS)
6b1c8423 2908 {
875862bf 2909 rtx op0 = XEXP (addr, 0);
2910 rtx op1 = XEXP (addr, 1);
2911 enum rtx_code code0 = GET_CODE (op0);
2912 enum rtx_code code1 = GET_CODE (op1);
6b1c8423 2913
875862bf 2914 if (code0 == REG || code0 == UNSPEC)
2915 {
2916 if (code1 == REG || code1 == UNSPEC)
2917 {
2918 indx = op0; /* index + base */
2919 base = op1;
2920 }
6b1c8423 2921
875862bf 2922 else
2923 {
2924 base = op0; /* base + displacement */
2925 disp = op1;
2926 }
2927 }
a5004c3d 2928
875862bf 2929 else if (code0 == PLUS)
51aa1e9c 2930 {
875862bf 2931 indx = XEXP (op0, 0); /* index + base + disp */
2932 base = XEXP (op0, 1);
2933 disp = op1;
51aa1e9c 2934 }
51aa1e9c 2935
875862bf 2936 else
51aa1e9c 2937 {
e5537457 2938 return false;
51aa1e9c 2939 }
875862bf 2940 }
51aa1e9c 2941
875862bf 2942 else
2943 disp = addr; /* displacement */
51aa1e9c 2944
875862bf 2945 /* Extract integer part of displacement. */
2946 orig_disp = disp;
2947 if (disp)
2948 {
2949 if (GET_CODE (disp) == CONST_INT)
51aa1e9c 2950 {
875862bf 2951 offset = INTVAL (disp);
2952 disp = NULL_RTX;
51aa1e9c 2953 }
875862bf 2954 else if (GET_CODE (disp) == CONST
2955 && GET_CODE (XEXP (disp, 0)) == PLUS
2956 && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT)
2957 {
2958 offset = INTVAL (XEXP (XEXP (disp, 0), 1));
2959 disp = XEXP (XEXP (disp, 0), 0);
2960 }
2961 }
51aa1e9c 2962
875862bf 2963 /* Strip off CONST here to avoid special case tests later. */
2964 if (disp && GET_CODE (disp) == CONST)
2965 disp = XEXP (disp, 0);
63ebd742 2966
875862bf 2967 /* We can convert literal pool addresses to
2968 displacements by basing them off the base register. */
2969 if (disp && GET_CODE (disp) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (disp))
2970 {
58ad9b54 2971 if (base || indx)
2972 return false;
2973
2974 base = fake_pool_base, literal_pool = true;
875862bf 2975
2976 /* Mark up the displacement. */
2977 disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp),
2978 UNSPEC_LTREL_OFFSET);
51aa1e9c 2979 }
a5004c3d 2980
875862bf 2981 /* Validate base register. */
06f2bd29 2982 if (!s390_decompose_constant_pool_ref (&base, &disp, &pointer, &base_ptr,
d4bb7aa3 2983 &literal_pool))
06f2bd29 2984 return false;
875862bf 2985
2986 /* Validate index register. */
06f2bd29 2987 if (!s390_decompose_constant_pool_ref (&indx, &disp, &pointer, &indx_ptr,
d4bb7aa3 2988 &literal_pool))
06f2bd29 2989 return false;
f588eb9f 2990
875862bf 2991 /* Prefer to use pointer as base, not index. */
2992 if (base && indx && !base_ptr
2993 && (indx_ptr || (!REG_POINTER (base) && REG_POINTER (indx))))
2994 {
2995 rtx tmp = base;
2996 base = indx;
2997 indx = tmp;
2998 }
64a1078f 2999
875862bf 3000 /* Validate displacement. */
3001 if (!disp)
3002 {
ffead1ca 3003 /* If virtual registers are involved, the displacement will change later
3004 anyway as the virtual registers get eliminated. This could make a
3005 valid displacement invalid, but it is more likely to make an invalid
3006 displacement valid, because we sometimes access the register save area
119114cb 3007 via negative offsets to one of those registers.
875862bf 3008 Thus we don't check the displacement for validity here. If after
3009 elimination the displacement turns out to be invalid after all,
3010 this is fixed up by reload in any case. */
7b1bda1c 3011 /* LRA maintains always displacements up to date and we need to
3012 know the displacement is right during all LRA not only at the
3013 final elimination. */
3014 if (lra_in_progress
3015 || (base != arg_pointer_rtx
3016 && indx != arg_pointer_rtx
3017 && base != return_address_pointer_rtx
3018 && indx != return_address_pointer_rtx
3019 && base != frame_pointer_rtx
3020 && indx != frame_pointer_rtx
3021 && base != virtual_stack_vars_rtx
3022 && indx != virtual_stack_vars_rtx))
875862bf 3023 if (!DISP_IN_RANGE (offset))
e5537457 3024 return false;
875862bf 3025 }
3026 else
3027 {
3028 /* All the special cases are pointers. */
e5537457 3029 pointer = true;
64a1078f 3030
875862bf 3031 /* In the small-PIC case, the linker converts @GOT
9f522e0c 3032 and @GOTNTPOFF offsets to possible displacements. */
875862bf 3033 if (GET_CODE (disp) == UNSPEC
9f522e0c 3034 && (XINT (disp, 1) == UNSPEC_GOT
875862bf 3035 || XINT (disp, 1) == UNSPEC_GOTNTPOFF)
875862bf 3036 && flag_pic == 1)
9f522e0c 3037 {
875862bf 3038 ;
9f522e0c 3039 }
64a1078f 3040
1ed7a160 3041 /* Accept pool label offsets. */
3042 else if (GET_CODE (disp) == UNSPEC
3043 && XINT (disp, 1) == UNSPEC_POOL_OFFSET)
3044 ;
64a1078f 3045
875862bf 3046 /* Accept literal pool references. */
3047 else if (GET_CODE (disp) == UNSPEC
3048 && XINT (disp, 1) == UNSPEC_LTREL_OFFSET)
9f522e0c 3049 {
cf8ffe7d 3050 /* In case CSE pulled a non literal pool reference out of
3051 the pool we have to reject the address. This is
3052 especially important when loading the GOT pointer on non
3053 zarch CPUs. In this case the literal pool contains an lt
3054 relative offset to the _GLOBAL_OFFSET_TABLE_ label which
3055 will most likely exceed the displacement. */
3056 if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF
3057 || !CONSTANT_POOL_ADDRESS_P (XVECEXP (disp, 0, 0)))
3058 return false;
3059
875862bf 3060 orig_disp = gen_rtx_CONST (Pmode, disp);
3061 if (offset)
3062 {
3063 /* If we have an offset, make sure it does not
7bd6e754 3064 exceed the size of the constant pool entry.
3065 Otherwise we might generate an out-of-range
3066 displacement for the base register form. */
875862bf 3067 rtx sym = XVECEXP (disp, 0, 0);
3068 if (offset >= GET_MODE_SIZE (get_pool_mode (sym)))
e5537457 3069 return false;
64a1078f 3070
9f522e0c 3071 orig_disp = plus_constant (Pmode, orig_disp, offset);
875862bf 3072 }
9f522e0c 3073 }
875862bf 3074
3075 else
e5537457 3076 return false;
64a1078f 3077 }
3078
875862bf 3079 if (!base && !indx)
e5537457 3080 pointer = true;
875862bf 3081
3082 if (out)
3083 {
3084 out->base = base;
3085 out->indx = indx;
3086 out->disp = orig_disp;
3087 out->pointer = pointer;
05b58257 3088 out->literal_pool = literal_pool;
875862bf 3089 }
3090
e5537457 3091 return true;
64a1078f 3092}
3093
2be7449b 3094/* Decompose a RTL expression OP for an address style operand into its
3095 components, and return the base register in BASE and the offset in
3096 OFFSET. While OP looks like an address it is never supposed to be
3097 used as such.
6d6be381 3098
2be7449b 3099 Return true if OP is a valid address operand, false if not. */
6d6be381 3100
3101bool
2be7449b 3102s390_decompose_addrstyle_without_index (rtx op, rtx *base,
3103 HOST_WIDE_INT *offset)
6d6be381 3104{
6191f2a0 3105 rtx off = NULL_RTX;
6d6be381 3106
6d6be381 3107 /* We can have an integer constant, an address register,
3108 or a sum of the two. */
6191f2a0 3109 if (CONST_SCALAR_INT_P (op))
6d6be381 3110 {
6191f2a0 3111 off = op;
6d6be381 3112 op = NULL_RTX;
3113 }
6191f2a0 3114 if (op && GET_CODE (op) == PLUS && CONST_SCALAR_INT_P (XEXP (op, 1)))
6d6be381 3115 {
6191f2a0 3116 off = XEXP (op, 1);
6d6be381 3117 op = XEXP (op, 0);
3118 }
3119 while (op && GET_CODE (op) == SUBREG)
3120 op = SUBREG_REG (op);
3121
3122 if (op && GET_CODE (op) != REG)
3123 return false;
3124
3125 if (offset)
6191f2a0 3126 {
3127 if (off == NULL_RTX)
3128 *offset = 0;
3129 else if (CONST_INT_P (off))
3130 *offset = INTVAL (off);
3131 else if (CONST_WIDE_INT_P (off))
3132 /* The offset will anyway be cut down to 12 bits so take just
3133 the lowest order chunk of the wide int. */
3134 *offset = CONST_WIDE_INT_ELT (off, 0);
3135 else
3136 gcc_unreachable ();
3137 }
6d6be381 3138 if (base)
3139 *base = op;
3140
3141 return true;
3142}
3143
c243c9ea 3144/* Check that OP is a valid shift count operand.
3145 It should be of the following structure:
3146 (subreg (and (plus (reg imm_op)) 2^k-1) 7)
3147 where subreg, and and plus are optional.
3148
3149 If IMPLICIT_MASK is > 0 and OP contains and
3150 (AND ... immediate)
3151 it is checked whether IMPLICIT_MASK and the immediate match.
3152 Otherwise, no checking is performed.
3153 */
3154bool
3155s390_valid_shift_count (rtx op, HOST_WIDE_INT implicit_mask)
3156{
3157 /* Strip subreg. */
3158 while (GET_CODE (op) == SUBREG && subreg_lowpart_p (op))
3159 op = XEXP (op, 0);
3160
3161 /* Check for an and with proper constant. */
3162 if (GET_CODE (op) == AND)
3163 {
3164 rtx op1 = XEXP (op, 0);
3165 rtx imm = XEXP (op, 1);
3166
3167 if (GET_CODE (op1) == SUBREG && subreg_lowpart_p (op1))
3168 op1 = XEXP (op1, 0);
3169
3170 if (!(register_operand (op1, GET_MODE (op1)) || GET_CODE (op1) == PLUS))
3171 return false;
3172
3173 if (!immediate_operand (imm, GET_MODE (imm)))
3174 return false;
3175
3176 HOST_WIDE_INT val = INTVAL (imm);
3177 if (implicit_mask > 0
3178 && (val & implicit_mask) != implicit_mask)
3179 return false;
3180
3181 op = op1;
3182 }
3183
3184 /* Check the rest. */
3185 return s390_decompose_addrstyle_without_index (op, NULL, NULL);
3186}
6d6be381 3187
875862bf 3188/* Return true if CODE is a valid address without index. */
fab7adbf 3189
875862bf 3190bool
3191s390_legitimate_address_without_index_p (rtx op)
3192{
3193 struct s390_address addr;
3194
3195 if (!s390_decompose_address (XEXP (op, 0), &addr))
3196 return false;
3197 if (addr.indx)
3198 return false;
3199
3200 return true;
3201}
3202
59bc01b3 3203
2a672556 3204/* Return TRUE if ADDR is an operand valid for a load/store relative
3205 instruction. Be aware that the alignment of the operand needs to
3206 be checked separately.
3207 Valid addresses are single references or a sum of a reference and a
3208 constant integer. Return these parts in SYMREF and ADDEND. You can
3209 pass NULL in REF and/or ADDEND if you are not interested in these
a0cb7918 3210 values. */
875862bf 3211
a7b49046 3212static bool
2a672556 3213s390_loadrelative_operand_p (rtx addr, rtx *symref, HOST_WIDE_INT *addend)
875862bf 3214{
a7b49046 3215 HOST_WIDE_INT tmpaddend = 0;
875862bf 3216
a7b49046 3217 if (GET_CODE (addr) == CONST)
3218 addr = XEXP (addr, 0);
3219
3220 if (GET_CODE (addr) == PLUS)
875862bf 3221 {
2a672556 3222 if (!CONST_INT_P (XEXP (addr, 1)))
a7b49046 3223 return false;
875862bf 3224
2a672556 3225 tmpaddend = INTVAL (XEXP (addr, 1));
3226 addr = XEXP (addr, 0);
3227 }
62cb5855 3228
a0cb7918 3229 if (GET_CODE (addr) == SYMBOL_REF
2a672556 3230 || (GET_CODE (addr) == UNSPEC
3231 && (XINT (addr, 1) == UNSPEC_GOTENT
f5edbf1d 3232 || XINT (addr, 1) == UNSPEC_PLT)))
2a672556 3233 {
3234 if (symref)
3235 *symref = addr;
3236 if (addend)
3237 *addend = tmpaddend;
62cb5855 3238
2a672556 3239 return true;
3240 }
3241 return false;
62cb5855 3242}
a7b49046 3243
3244/* Return true if the address in OP is valid for constraint letter C
3245 if wrapped in a MEM rtx. Set LIT_POOL_OK to true if it literal
3246 pool MEMs should be accepted. Only the Q, R, S, T constraint
3247 letters are allowed for C. */
875862bf 3248
a7b49046 3249static int
3250s390_check_qrst_address (char c, rtx op, bool lit_pool_ok)
3251{
a0cb7918 3252 rtx symref;
a7b49046 3253 struct s390_address addr;
3254 bool decomposed = false;
3255
ff03121f 3256 if (!address_operand (op, GET_MODE (op)))
3257 return 0;
3258
a7b49046 3259 /* This check makes sure that no symbolic address (except literal
3260 pool references) are accepted by the R or T constraints. */
a0cb7918 3261 if (s390_loadrelative_operand_p (op, &symref, NULL)
7f118bfb 3262 && (!lit_pool_ok
3263 || !SYMBOL_REF_P (symref)
3264 || !CONSTANT_POOL_ADDRESS_P (symref)))
f3959569 3265 return 0;
3266
3267 /* Ensure literal pool references are only accepted if LIT_POOL_OK. */
3268 if (!lit_pool_ok)
875862bf 3269 {
a7b49046 3270 if (!s390_decompose_address (op, &addr))
875862bf 3271 return 0;
f3959569 3272 if (addr.literal_pool)
875862bf 3273 return 0;
a7b49046 3274 decomposed = true;
875862bf 3275 }
3276
7396c35d 3277 /* With reload, we sometimes get intermediate address forms that are
3278 actually invalid as-is, but we need to accept them in the most
3279 generic cases below ('R' or 'T'), since reload will in fact fix
3280 them up. LRA behaves differently here; we never see such forms,
3281 but on the other hand, we need to strictly reject every invalid
7bd6e754 3282 address form. After both reload and LRA invalid address forms
3283 must be rejected, because nothing will fix them up later. Perform
3284 this check right up front. */
3285 if (lra_in_progress || reload_completed)
7396c35d 3286 {
3287 if (!decomposed && !s390_decompose_address (op, &addr))
3288 return 0;
3289 decomposed = true;
3290 }
3291
875862bf 3292 switch (c)
3293 {
a7b49046 3294 case 'Q': /* no index short displacement */
3295 if (!decomposed && !s390_decompose_address (op, &addr))
875862bf 3296 return 0;
3297 if (addr.indx)
3298 return 0;
a7b49046 3299 if (!s390_short_displacement (addr.disp))
875862bf 3300 return 0;
a7b49046 3301 break;
875862bf 3302
a7b49046 3303 case 'R': /* with index short displacement */
875862bf 3304 if (TARGET_LONG_DISPLACEMENT)
3305 {
a7b49046 3306 if (!decomposed && !s390_decompose_address (op, &addr))
875862bf 3307 return 0;
3308 if (!s390_short_displacement (addr.disp))
3309 return 0;
3310 }
a7b49046 3311 /* Any invalid address here will be fixed up by reload,
3312 so accept it for the most generic constraint. */
875862bf 3313 break;
3314
a7b49046 3315 case 'S': /* no index long displacement */
a7b49046 3316 if (!decomposed && !s390_decompose_address (op, &addr))
875862bf 3317 return 0;
3318 if (addr.indx)
3319 return 0;
875862bf 3320 break;
3321
a7b49046 3322 case 'T': /* with index long displacement */
a7b49046 3323 /* Any invalid address here will be fixed up by reload,
3324 so accept it for the most generic constraint. */
875862bf 3325 break;
7396c35d 3326
a7b49046 3327 default:
3328 return 0;
3329 }
3330 return 1;
3331}
875862bf 3332
875862bf 3333
a7b49046 3334/* Evaluates constraint strings described by the regular expression
7396c35d 3335 ([A|B|Z](Q|R|S|T))|Y and returns 1 if OP is a valid operand for
a7b49046 3336 the constraint given in STR, or 0 else. */
3337
3338int
3339s390_mem_constraint (const char *str, rtx op)
3340{
3341 char c = str[0];
3342
3343 switch (c)
3344 {
3345 case 'A':
3346 /* Check for offsettable variants of memory constraints. */
3347 if (!MEM_P (op) || MEM_VOLATILE_P (op))
875862bf 3348 return 0;
a7b49046 3349 if ((reload_completed || reload_in_progress)
3350 ? !offsettable_memref_p (op) : !offsettable_nonstrict_memref_p (op))
e68d6a13 3351 return 0;
a7b49046 3352 return s390_check_qrst_address (str[1], XEXP (op, 0), true);
3353 case 'B':
3354 /* Check for non-literal-pool variants of memory constraints. */
3355 if (!MEM_P (op))
875862bf 3356 return 0;
a7b49046 3357 return s390_check_qrst_address (str[1], XEXP (op, 0), false);
3358 case 'Q':
3359 case 'R':
3360 case 'S':
3361 case 'T':
3362 if (GET_CODE (op) != MEM)
3363 return 0;
3364 return s390_check_qrst_address (c, XEXP (op, 0), true);
875862bf 3365 case 'Y':
6d6be381 3366 /* Simply check for the basic form of a shift count. Reload will
3367 take care of making sure we have a proper base register. */
2be7449b 3368 if (!s390_decompose_addrstyle_without_index (op, NULL, NULL))
6d6be381 3369 return 0;
3370 break;
a7b49046 3371 case 'Z':
3372 return s390_check_qrst_address (str[1], op, true);
875862bf 3373 default:
3374 return 0;
3375 }
875862bf 3376 return 1;
3377}
3378
59bc01b3 3379
59bc01b3 3380/* Evaluates constraint strings starting with letter O. Input
3381 parameter C is the second letter following the "O" in the constraint
3382 string. Returns 1 if VALUE meets the respective constraint and 0
3383 otherwise. */
875862bf 3384
e863b008 3385int
59bc01b3 3386s390_O_constraint_str (const char c, HOST_WIDE_INT value)
e863b008 3387{
59bc01b3 3388 if (!TARGET_EXTIMM)
3389 return 0;
e863b008 3390
59bc01b3 3391 switch (c)
e863b008 3392 {
59bc01b3 3393 case 's':
3394 return trunc_int_for_mode (value, SImode) == value;
3395
3396 case 'p':
3397 return value == 0
3398 || s390_single_part (GEN_INT (value), DImode, SImode, 0) == 1;
3399
3400 case 'n':
29847ec4 3401 return s390_single_part (GEN_INT (value - 1), DImode, SImode, -1) == 1;
59bc01b3 3402
e863b008 3403 default:
59bc01b3 3404 gcc_unreachable ();
e863b008 3405 }
3406}
3407
59bc01b3 3408
3409/* Evaluates constraint strings starting with letter N. Parameter STR
3410 contains the letters following letter "N" in the constraint string.
3411 Returns true if VALUE matches the constraint. */
e863b008 3412
875862bf 3413int
59bc01b3 3414s390_N_constraint_str (const char *str, HOST_WIDE_INT value)
875862bf 3415{
3754d046 3416 machine_mode mode, part_mode;
875862bf 3417 int def;
3418 int part, part_goal;
3419
875862bf 3420
59bc01b3 3421 if (str[0] == 'x')
3422 part_goal = -1;
3423 else
3424 part_goal = str[0] - '0';
875862bf 3425
59bc01b3 3426 switch (str[1])
3427 {
3428 case 'Q':
3429 part_mode = QImode;
875862bf 3430 break;
59bc01b3 3431 case 'H':
3432 part_mode = HImode;
163277cf 3433 break;
59bc01b3 3434 case 'S':
3435 part_mode = SImode;
3436 break;
3437 default:
3438 return 0;
3439 }
163277cf 3440
59bc01b3 3441 switch (str[2])
3442 {
3443 case 'H':
3444 mode = HImode;
3445 break;
3446 case 'S':
3447 mode = SImode;
3448 break;
3449 case 'D':
3450 mode = DImode;
3451 break;
3452 default:
3453 return 0;
3454 }
53239c89 3455
59bc01b3 3456 switch (str[3])
3457 {
3458 case '0':
3459 def = 0;
3460 break;
3461 case 'F':
3462 def = -1;
3463 break;
875862bf 3464 default:
3465 return 0;
3466 }
3467
59bc01b3 3468 if (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (part_mode))
3469 return 0;
3470
3471 part = s390_single_part (GEN_INT (value), mode, part_mode, def);
3472 if (part < 0)
3473 return 0;
3474 if (part_goal != -1 && part_goal != part)
3475 return 0;
3476
875862bf 3477 return 1;
3478}
3479
59bc01b3 3480
3481/* Returns true if the input parameter VALUE is a float zero. */
3482
3483int
3484s390_float_const_zero_p (rtx value)
3485{
3486 return (GET_MODE_CLASS (GET_MODE (value)) == MODE_FLOAT
3487 && value == CONST0_RTX (GET_MODE (value)));
3488}
3489
fa7a995b 3490/* Implement TARGET_REGISTER_MOVE_COST. */
3491
3492static int
5fe5762e 3493s390_register_move_cost (machine_mode mode,
9f522e0c 3494 reg_class_t from, reg_class_t to)
fa7a995b 3495{
5fe5762e 3496 /* On s390, copy between fprs and gprs is expensive. */
3497
3498 /* It becomes somewhat faster having ldgr/lgdr. */
3499 if (TARGET_Z10 && GET_MODE_SIZE (mode) == 8)
3500 {
3501 /* ldgr is single cycle. */
3502 if (reg_classes_intersect_p (from, GENERAL_REGS)
3503 && reg_classes_intersect_p (to, FP_REGS))
3504 return 1;
3505 /* lgdr needs 3 cycles. */
3506 if (reg_classes_intersect_p (to, GENERAL_REGS)
3507 && reg_classes_intersect_p (from, FP_REGS))
3508 return 3;
3509 }
3510
3511 /* Otherwise copying is done via memory. */
3512 if ((reg_classes_intersect_p (from, GENERAL_REGS)
3513 && reg_classes_intersect_p (to, FP_REGS))
3514 || (reg_classes_intersect_p (from, FP_REGS)
3515 && reg_classes_intersect_p (to, GENERAL_REGS)))
fa7a995b 3516 return 10;
3517
5f52e883 3518 /* We usually do not want to copy via CC. */
3519 if (reg_classes_intersect_p (from, CC_REGS)
3520 || reg_classes_intersect_p (to, CC_REGS))
3521 return 5;
3522
fa7a995b 3523 return 1;
3524}
3525
3526/* Implement TARGET_MEMORY_MOVE_COST. */
3527
3528static int
3754d046 3529s390_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
fa7a995b 3530 reg_class_t rclass ATTRIBUTE_UNUSED,
3531 bool in ATTRIBUTE_UNUSED)
3532{
9a071c9f 3533 return 2;
fa7a995b 3534}
59bc01b3 3535
875862bf 3536/* Compute a (partial) cost for rtx X. Return true if the complete
3537 cost has been computed, and false if subexpressions should be
016d030e 3538 scanned. In either case, *TOTAL contains the cost result. The
3539 initial value of *TOTAL is the default value computed by
3540 rtx_cost. It may be left unmodified. OUTER_CODE contains the
3541 code of the superexpression of x. */
875862bf 3542
3543static bool
5ae4887d 3544s390_rtx_costs (rtx x, machine_mode mode, int outer_code,
3545 int opno ATTRIBUTE_UNUSED,
20d892d1 3546 int *total, bool speed ATTRIBUTE_UNUSED)
fab7adbf 3547{
5ae4887d 3548 int code = GET_CODE (x);
fab7adbf 3549 switch (code)
3550 {
3551 case CONST:
fab7adbf 3552 case CONST_INT:
fab7adbf 3553 case LABEL_REF:
3554 case SYMBOL_REF:
3555 case CONST_DOUBLE:
ba0e61d6 3556 case CONST_WIDE_INT:
3f074425 3557 case MEM:
fab7adbf 3558 *total = 0;
3559 return true;
3560
c70e1aad 3561 case SET:
3562 {
3563 /* Without this a conditional move instruction would be
3564 accounted as 3 * COSTS_N_INSNS (set, if_then_else,
3565 comparison operator). That's a bit pessimistic. */
3566
3567 if (!TARGET_Z196 || GET_CODE (SET_SRC (x)) != IF_THEN_ELSE)
3568 return false;
3569
3570 rtx cond = XEXP (SET_SRC (x), 0);
3571
3572 if (!CC_REG_P (XEXP (cond, 0)) || !CONST_INT_P (XEXP (cond, 1)))
3573 return false;
3574
3575 /* It is going to be a load/store on condition. Make it
3576 slightly more expensive than a normal load. */
3577 *total = COSTS_N_INSNS (1) + 1;
3578
3579 rtx dst = SET_DEST (x);
3580 rtx then = XEXP (SET_SRC (x), 1);
3581 rtx els = XEXP (SET_SRC (x), 2);
3582
3583 /* It is a real IF-THEN-ELSE. An additional move will be
3584 needed to implement that. */
dbeb7608 3585 if (!TARGET_ARCH13
3586 && reload_completed
c70e1aad 3587 && !rtx_equal_p (dst, then)
3588 && !rtx_equal_p (dst, els))
3589 *total += COSTS_N_INSNS (1) / 2;
3590
3591 /* A minor penalty for constants we cannot directly handle. */
3592 if ((CONST_INT_P (then) || CONST_INT_P (els))
3593 && (!TARGET_Z13 || MEM_P (dst)
3594 || (CONST_INT_P (then) && !satisfies_constraint_K (then))
3595 || (CONST_INT_P (els) && !satisfies_constraint_K (els))))
3596 *total += COSTS_N_INSNS (1) / 2;
3597
3598 /* A store on condition can only handle register src operands. */
3599 if (MEM_P (dst) && (!REG_P (then) || !REG_P (els)))
3600 *total += COSTS_N_INSNS (1) / 2;
3601
3602 return true;
3603 }
02a8efd2 3604 case IOR:
92d5e9eb 3605
3606 /* nnrk, nngrk */
3607 if (TARGET_ARCH13
3608 && (mode == SImode || mode == DImode)
3609 && GET_CODE (XEXP (x, 0)) == NOT
3610 && GET_CODE (XEXP (x, 1)) == NOT)
3611 {
3612 *total = COSTS_N_INSNS (1);
3613 if (!REG_P (XEXP (XEXP (x, 0), 0)))
3614 *total += 1;
3615 if (!REG_P (XEXP (XEXP (x, 1), 0)))
3616 *total += 1;
3617 return true;
3618 }
3619
02a8efd2 3620 /* risbg */
3621 if (GET_CODE (XEXP (x, 0)) == AND
3622 && GET_CODE (XEXP (x, 1)) == ASHIFT
3623 && REG_P (XEXP (XEXP (x, 0), 0))
3624 && REG_P (XEXP (XEXP (x, 1), 0))
3625 && CONST_INT_P (XEXP (XEXP (x, 0), 1))
3626 && CONST_INT_P (XEXP (XEXP (x, 1), 1))
3627 && (UINTVAL (XEXP (XEXP (x, 0), 1)) ==
b422d8c0 3628 (HOST_WIDE_INT_1U << UINTVAL (XEXP (XEXP (x, 1), 1))) - 1))
02a8efd2 3629 {
3630 *total = COSTS_N_INSNS (2);
3631 return true;
3632 }
0f57593c 3633
3634 /* ~AND on a 128 bit mode. This can be done using a vector
3635 instruction. */
3636 if (TARGET_VXE
3637 && GET_CODE (XEXP (x, 0)) == NOT
3638 && GET_CODE (XEXP (x, 1)) == NOT
3639 && REG_P (XEXP (XEXP (x, 0), 0))
3640 && REG_P (XEXP (XEXP (x, 1), 0))
3641 && GET_MODE_SIZE (GET_MODE (XEXP (XEXP (x, 0), 0))) == 16
3642 && s390_hard_regno_mode_ok (VR0_REGNUM,
3643 GET_MODE (XEXP (XEXP (x, 0), 0))))
3644 {
3645 *total = COSTS_N_INSNS (1);
3646 return true;
3647 }
92d5e9eb 3648
3649 *total = COSTS_N_INSNS (1);
3650 return false;
3651
3652 case AND:
3653 /* nork, nogrk */
3654 if (TARGET_ARCH13
3655 && (mode == SImode || mode == DImode)
3656 && GET_CODE (XEXP (x, 0)) == NOT
3657 && GET_CODE (XEXP (x, 1)) == NOT)
3658 {
3659 *total = COSTS_N_INSNS (1);
3660 if (!REG_P (XEXP (XEXP (x, 0), 0)))
3661 *total += 1;
3662 if (!REG_P (XEXP (XEXP (x, 1), 0)))
3663 *total += 1;
3664 return true;
3665 }
0903985d 3666 /* fallthrough */
fab7adbf 3667 case ASHIFT:
3668 case ASHIFTRT:
3669 case LSHIFTRT:
18925d38 3670 case ROTATE:
3671 case ROTATERT:
fab7adbf 3672 case XOR:
fab7adbf 3673 case NEG:
3674 case NOT:
9cd3f3e6 3675 case PLUS:
3676 case MINUS:
9cd3f3e6 3677 *total = COSTS_N_INSNS (1);
3678 return false;
3679
ffead1ca 3680 case MULT:
5ae4887d 3681 switch (mode)
18925d38 3682 {
916ace94 3683 case E_SImode:
9cd3f3e6 3684 {
18925d38 3685 rtx left = XEXP (x, 0);
3686 rtx right = XEXP (x, 1);
3687 if (GET_CODE (right) == CONST_INT
cb888f33 3688 && CONST_OK_FOR_K (INTVAL (right)))
18925d38 3689 *total = s390_cost->mhi;
3690 else if (GET_CODE (left) == SIGN_EXTEND)
3691 *total = s390_cost->mh;
3692 else
3693 *total = s390_cost->ms; /* msr, ms, msy */
3694 break;
3695 }
916ace94 3696 case E_DImode:
18925d38 3697 {
3698 rtx left = XEXP (x, 0);
3699 rtx right = XEXP (x, 1);
b5fdc416 3700 if (TARGET_ZARCH)
18925d38 3701 {
3702 if (GET_CODE (right) == CONST_INT
cb888f33 3703 && CONST_OK_FOR_K (INTVAL (right)))
18925d38 3704 *total = s390_cost->mghi;
3705 else if (GET_CODE (left) == SIGN_EXTEND)
3706 *total = s390_cost->msgf;
3707 else
3708 *total = s390_cost->msg; /* msgr, msg */
3709 }
3710 else /* TARGET_31BIT */
3711 {
3712 if (GET_CODE (left) == SIGN_EXTEND
3713 && GET_CODE (right) == SIGN_EXTEND)
3714 /* mulsidi case: mr, m */
3715 *total = s390_cost->m;
9cd3f3e6 3716 else if (GET_CODE (left) == ZERO_EXTEND
f5edbf1d 3717 && GET_CODE (right) == ZERO_EXTEND)
9cd3f3e6 3718 /* umulsidi case: ml, mlr */
3719 *total = s390_cost->ml;
18925d38 3720 else
3721 /* Complex calculation is required. */
3722 *total = COSTS_N_INSNS (40);
3723 }
3724 break;
3725 }
916ace94 3726 case E_SFmode:
3727 case E_DFmode:
18925d38 3728 *total = s390_cost->mult_df;
3729 break;
916ace94 3730 case E_TFmode:
429f9fdb 3731 *total = s390_cost->mxbr;
3732 break;
18925d38 3733 default:
3734 return false;
3735 }
3736 return false;
fab7adbf 3737
81470015 3738 case FMA:
5ae4887d 3739 switch (mode)
81470015 3740 {
916ace94 3741 case E_DFmode:
81470015 3742 *total = s390_cost->madbr;
3743 break;
916ace94 3744 case E_SFmode:
81470015 3745 *total = s390_cost->maebr;
3746 break;
3747 default:
3748 return false;
3749 }
3750 /* Negate in the third argument is free: FMSUB. */
3751 if (GET_CODE (XEXP (x, 2)) == NEG)
3752 {
5ae4887d 3753 *total += (rtx_cost (XEXP (x, 0), mode, FMA, 0, speed)
3754 + rtx_cost (XEXP (x, 1), mode, FMA, 1, speed)
3755 + rtx_cost (XEXP (XEXP (x, 2), 0), mode, FMA, 2, speed));
81470015 3756 return true;
3757 }
3758 return false;
3759
3f074425 3760 case UDIV:
3761 case UMOD:
9f522e0c 3762 if (mode == TImode) /* 128 bit division */
3f074425 3763 *total = s390_cost->dlgr;
5ae4887d 3764 else if (mode == DImode)
3f074425 3765 {
3766 rtx right = XEXP (x, 1);
3767 if (GET_CODE (right) == ZERO_EXTEND) /* 64 by 32 bit division */
3768 *total = s390_cost->dlr;
9f522e0c 3769 else /* 64 by 64 bit division */
3f074425 3770 *total = s390_cost->dlgr;
3771 }
5ae4887d 3772 else if (mode == SImode) /* 32 bit division */
3f074425 3773 *total = s390_cost->dlr;
3774 return false;
3775
fab7adbf 3776 case DIV:
3f074425 3777 case MOD:
5ae4887d 3778 if (mode == DImode)
3f074425 3779 {
3780 rtx right = XEXP (x, 1);
3781 if (GET_CODE (right) == ZERO_EXTEND) /* 64 by 32 bit division */
b5fdc416 3782 if (TARGET_ZARCH)
3f074425 3783 *total = s390_cost->dsgfr;
3784 else
3785 *total = s390_cost->dr;
9f522e0c 3786 else /* 64 by 64 bit division */
3f074425 3787 *total = s390_cost->dsgr;
3788 }
5ae4887d 3789 else if (mode == SImode) /* 32 bit division */
3f074425 3790 *total = s390_cost->dlr;
5ae4887d 3791 else if (mode == SFmode)
260075cc 3792 {
095798e3 3793 *total = s390_cost->debr;
260075cc 3794 }
5ae4887d 3795 else if (mode == DFmode)
260075cc 3796 {
095798e3 3797 *total = s390_cost->ddbr;
260075cc 3798 }
5ae4887d 3799 else if (mode == TFmode)
429f9fdb 3800 {
095798e3 3801 *total = s390_cost->dxbr;
429f9fdb 3802 }
18925d38 3803 return false;
3804
9cd3f3e6 3805 case SQRT:
5ae4887d 3806 if (mode == SFmode)
9cd3f3e6 3807 *total = s390_cost->sqebr;
5ae4887d 3808 else if (mode == DFmode)
9cd3f3e6 3809 *total = s390_cost->sqdbr;
429f9fdb 3810 else /* TFmode */
3811 *total = s390_cost->sqxbr;
9cd3f3e6 3812 return false;
3813
18925d38 3814 case SIGN_EXTEND:
9cd3f3e6 3815 case ZERO_EXTEND:
3f074425 3816 if (outer_code == MULT || outer_code == DIV || outer_code == MOD
3817 || outer_code == PLUS || outer_code == MINUS
3818 || outer_code == COMPARE)
18925d38 3819 *total = 0;
3820 return false;
fab7adbf 3821
3f074425 3822 case COMPARE:
3823 *total = COSTS_N_INSNS (1);
92d5e9eb 3824
3825 /* nxrk, nxgrk ~(a^b)==0 */
3826 if (TARGET_ARCH13
3827 && GET_CODE (XEXP (x, 0)) == NOT
3828 && XEXP (x, 1) == const0_rtx
3829 && GET_CODE (XEXP (XEXP (x, 0), 0)) == XOR
3830 && (GET_MODE (XEXP (x, 0)) == SImode || GET_MODE (XEXP (x, 0)) == DImode)
3831 && mode == CCZmode)
3832 {
3833 if (!REG_P (XEXP (XEXP (XEXP (x, 0), 0), 0)))
3834 *total += 1;
3835 if (!REG_P (XEXP (XEXP (XEXP (x, 0), 0), 1)))
3836 *total += 1;
3837 return true;
3838 }
3839
3840 /* nnrk, nngrk, nork, nogrk */
3841 if (TARGET_ARCH13
3842 && (GET_CODE (XEXP (x, 0)) == AND || GET_CODE (XEXP (x, 0)) == IOR)
3843 && XEXP (x, 1) == const0_rtx
3844 && (GET_MODE (XEXP (x, 0)) == SImode || GET_MODE (XEXP (x, 0)) == DImode)
3845 && GET_CODE (XEXP (XEXP (x, 0), 0)) == NOT
3846 && GET_CODE (XEXP (XEXP (x, 0), 1)) == NOT
3847 && mode == CCZmode)
3848 {
3849 if (!REG_P (XEXP (XEXP (XEXP (x, 0), 0), 0)))
3850 *total += 1;
3851 if (!REG_P (XEXP (XEXP (XEXP (x, 0), 1), 0)))
3852 *total += 1;
3853 return true;
3854 }
3855
3f074425 3856 if (GET_CODE (XEXP (x, 0)) == AND
3857 && GET_CODE (XEXP (x, 1)) == CONST_INT
3858 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
3859 {
3860 rtx op0 = XEXP (XEXP (x, 0), 0);
3861 rtx op1 = XEXP (XEXP (x, 0), 1);
3862 rtx op2 = XEXP (x, 1);
3863
3864 if (memory_operand (op0, GET_MODE (op0))
3865 && s390_tm_ccmode (op1, op2, 0) != VOIDmode)
3866 return true;
3867 if (register_operand (op0, GET_MODE (op0))
3868 && s390_tm_ccmode (op1, op2, 1) != VOIDmode)
3869 return true;
3870 }
3871 return false;
3872
fab7adbf 3873 default:
3874 return false;
3875 }
3876}
3877
ee9c19ee 3878/* Return the cost of an address rtx ADDR. */
3879
ec0457a8 3880static int
3754d046 3881s390_address_cost (rtx addr, machine_mode mode ATTRIBUTE_UNUSED,
d9c5e5f4 3882 addr_space_t as ATTRIBUTE_UNUSED,
3883 bool speed ATTRIBUTE_UNUSED)
ee9c19ee 3884{
3885 struct s390_address ad;
3886 if (!s390_decompose_address (addr, &ad))
3887 return 1000;
3888
3889 return ad.indx? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
3890}
3891
292e369f 3892/* Implement targetm.vectorize.builtin_vectorization_cost. */
3893static int
3894s390_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3895 tree vectype,
3896 int misalign ATTRIBUTE_UNUSED)
3897{
3898 switch (type_of_cost)
3899 {
3900 case scalar_stmt:
3901 case scalar_load:
3902 case scalar_store:
3903 case vector_stmt:
3904 case vector_load:
3905 case vector_store:
72e995da 3906 case vector_gather_load:
3907 case vector_scatter_store:
292e369f 3908 case vec_to_scalar:
3909 case scalar_to_vec:
3910 case cond_branch_not_taken:
3911 case vec_perm:
3912 case vec_promote_demote:
3913 case unaligned_load:
3914 case unaligned_store:
3915 return 1;
3916
3917 case cond_branch_taken:
3918 return 3;
3919
3920 case vec_construct:
3921 return TYPE_VECTOR_SUBPARTS (vectype) - 1;
3922
3923 default:
3924 gcc_unreachable ();
3925 }
3926}
3927
be00aaa8 3928/* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
3929 otherwise return 0. */
3930
3931int
edd89d66 3932tls_symbolic_operand (rtx op)
be00aaa8 3933{
be00aaa8 3934 if (GET_CODE (op) != SYMBOL_REF)
3935 return 0;
a3e33162 3936 return SYMBOL_REF_TLS_MODEL (op);
be00aaa8 3937}
4673c1a0 3938\f
923cf36d 3939/* Split DImode access register reference REG (on 64-bit) into its constituent
3940 low and high parts, and store them into LO and HI. Note that gen_lowpart/
3941 gen_highpart cannot be used as they assume all registers are word-sized,
3942 while our access registers have only half that size. */
3943
3944void
3945s390_split_access_reg (rtx reg, rtx *lo, rtx *hi)
3946{
3947 gcc_assert (TARGET_64BIT);
3948 gcc_assert (ACCESS_REG_P (reg));
3949 gcc_assert (GET_MODE (reg) == DImode);
3950 gcc_assert (!(REGNO (reg) & 1));
3951
3952 *lo = gen_rtx_REG (SImode, REGNO (reg) + 1);
3953 *hi = gen_rtx_REG (SImode, REGNO (reg));
3954}
4673c1a0 3955
56769981 3956/* Return true if OP contains a symbol reference */
4673c1a0 3957
e5537457 3958bool
b40da9a7 3959symbolic_reference_mentioned_p (rtx op)
4673c1a0 3960{
edd89d66 3961 const char *fmt;
3962 int i;
4673c1a0 3963
3964 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
3965 return 1;
3966
3967 fmt = GET_RTX_FORMAT (GET_CODE (op));
3968 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
3969 {
3970 if (fmt[i] == 'E')
3971 {
edd89d66 3972 int j;
4673c1a0 3973
3974 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
3975 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
3976 return 1;
3977 }
3978
3979 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
3980 return 1;
3981 }
3982
3983 return 0;
3984}
3985
be00aaa8 3986/* Return true if OP contains a reference to a thread-local symbol. */
3987
e5537457 3988bool
b40da9a7 3989tls_symbolic_reference_mentioned_p (rtx op)
be00aaa8 3990{
edd89d66 3991 const char *fmt;
3992 int i;
be00aaa8 3993
3994 if (GET_CODE (op) == SYMBOL_REF)
3995 return tls_symbolic_operand (op);
3996
3997 fmt = GET_RTX_FORMAT (GET_CODE (op));
3998 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
3999 {
4000 if (fmt[i] == 'E')
4001 {
edd89d66 4002 int j;
be00aaa8 4003
4004 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
4005 if (tls_symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
e5537457 4006 return true;
be00aaa8 4007 }
4008
4009 else if (fmt[i] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op, i)))
e5537457 4010 return true;
be00aaa8 4011 }
4012
e5537457 4013 return false;
be00aaa8 4014}
4015
4673c1a0 4016
f81e845f 4017/* Return true if OP is a legitimate general operand when
4018 generating PIC code. It is given that flag_pic is on
ba0e61d6 4019 and that OP satisfies CONSTANT_P. */
56769981 4020
4673c1a0 4021int
edd89d66 4022legitimate_pic_operand_p (rtx op)
4673c1a0 4023{
8b4a4127 4024 /* Accept all non-symbolic constants. */
4673c1a0 4025 if (!SYMBOLIC_CONST (op))
4026 return 1;
4027
6dea6aa2 4028 /* Accept addresses that can be expressed relative to (pc). */
4029 if (larl_operand (op, VOIDmode))
4030 return 1;
4031
f81e845f 4032 /* Reject everything else; must be handled
be00aaa8 4033 via emit_symbolic_move. */
4673c1a0 4034 return 0;
4035}
4036
56769981 4037/* Returns true if the constant value OP is a legitimate general operand.
ba0e61d6 4038 It is given that OP satisfies CONSTANT_P. */
56769981 4039
ca316360 4040static bool
3754d046 4041s390_legitimate_constant_p (machine_mode mode, rtx op)
4673c1a0 4042{
abf3beed 4043 if (TARGET_VX && VECTOR_MODE_P (mode) && GET_CODE (op) == CONST_VECTOR)
76a4c804 4044 {
4045 if (GET_MODE_SIZE (mode) != 16)
4046 return 0;
4047
80fc7f56 4048 if (!satisfies_constraint_j00 (op)
4049 && !satisfies_constraint_jm1 (op)
4050 && !satisfies_constraint_jKK (op)
4051 && !satisfies_constraint_jxx (op)
4052 && !satisfies_constraint_jyy (op))
76a4c804 4053 return 0;
4054 }
4055
8b4a4127 4056 /* Accept all non-symbolic constants. */
4673c1a0 4057 if (!SYMBOLIC_CONST (op))
4058 return 1;
4059
be00aaa8 4060 /* Accept immediate LARL operands. */
f5edbf1d 4061 if (larl_operand (op, mode))
be00aaa8 4062 return 1;
4063
4064 /* Thread-local symbols are never legal constants. This is
4065 so that emit_call knows that computing such addresses
4066 might require a function call. */
4067 if (TLS_SYMBOLIC_CONST (op))
4068 return 0;
4069
4673c1a0 4070 /* In the PIC case, symbolic constants must *not* be
4071 forced into the literal pool. We accept them here,
be00aaa8 4072 so that they will be handled by emit_symbolic_move. */
4673c1a0 4073 if (flag_pic)
4074 return 1;
4075
4673c1a0 4076 /* All remaining non-PIC symbolic constants are
4077 forced into the literal pool. */
4078 return 0;
4079}
4080
be00aaa8 4081/* Determine if it's legal to put X into the constant pool. This
4082 is not possible if X contains the address of a symbol that is
4083 not constant (TLS) or not known at final link time (PIC). */
4084
4085static bool
3754d046 4086s390_cannot_force_const_mem (machine_mode mode, rtx x)
be00aaa8 4087{
4088 switch (GET_CODE (x))
4089 {
4090 case CONST_INT:
4091 case CONST_DOUBLE:
ba0e61d6 4092 case CONST_WIDE_INT:
76a4c804 4093 case CONST_VECTOR:
be00aaa8 4094 /* Accept all non-symbolic constants. */
4095 return false;
4096
4097 case LABEL_REF:
4098 /* Labels are OK iff we are non-PIC. */
4099 return flag_pic != 0;
4100
4101 case SYMBOL_REF:
4102 /* 'Naked' TLS symbol references are never OK,
9f522e0c 4103 non-TLS symbols are OK iff we are non-PIC. */
be00aaa8 4104 if (tls_symbolic_operand (x))
4105 return true;
4106 else
4107 return flag_pic != 0;
4108
4109 case CONST:
7d7d7bd2 4110 return s390_cannot_force_const_mem (mode, XEXP (x, 0));
be00aaa8 4111 case PLUS:
4112 case MINUS:
7d7d7bd2 4113 return s390_cannot_force_const_mem (mode, XEXP (x, 0))
4114 || s390_cannot_force_const_mem (mode, XEXP (x, 1));
be00aaa8 4115
4116 case UNSPEC:
4117 switch (XINT (x, 1))
4118 {
4119 /* Only lt-relative or GOT-relative UNSPECs are OK. */
12ef3745 4120 case UNSPEC_LTREL_OFFSET:
4121 case UNSPEC_GOT:
4122 case UNSPEC_GOTOFF:
4123 case UNSPEC_PLTOFF:
be00aaa8 4124 case UNSPEC_TLSGD:
4125 case UNSPEC_TLSLDM:
4126 case UNSPEC_NTPOFF:
4127 case UNSPEC_DTPOFF:
4128 case UNSPEC_GOTNTPOFF:
4129 case UNSPEC_INDNTPOFF:
4130 return false;
4131
d345b493 4132 /* If the literal pool shares the code section, be put
4133 execute template placeholders into the pool as well. */
4134 case UNSPEC_INSN:
be00aaa8 4135 default:
4136 return true;
4137 }
4138 break;
4139
4140 default:
32eda510 4141 gcc_unreachable ();
be00aaa8 4142 }
4143}
4144
8b4a4127 4145/* Returns true if the constant value OP is a legitimate general
f81e845f 4146 operand during and after reload. The difference to
8b4a4127 4147 legitimate_constant_p is that this function will not accept
4148 a constant that would need to be forced to the literal pool
33d033da 4149 before it can be used as operand.
4150 This function accepts all constants which can be loaded directly
4151 into a GPR. */
8b4a4127 4152
e5537457 4153bool
edd89d66 4154legitimate_reload_constant_p (rtx op)
8b4a4127 4155{
51aa1e9c 4156 /* Accept la(y) operands. */
f81e845f 4157 if (GET_CODE (op) == CONST_INT
51aa1e9c 4158 && DISP_IN_RANGE (INTVAL (op)))
e5537457 4159 return true;
51aa1e9c 4160
163277cf 4161 /* Accept l(g)hi/l(g)fi operands. */
8b4a4127 4162 if (GET_CODE (op) == CONST_INT
163277cf 4163 && (CONST_OK_FOR_K (INTVAL (op)) || CONST_OK_FOR_Os (INTVAL (op))))
e5537457 4164 return true;
8b4a4127 4165
4166 /* Accept lliXX operands. */
dafc8d45 4167 if (TARGET_ZARCH
53239c89 4168 && GET_CODE (op) == CONST_INT
4169 && trunc_int_for_mode (INTVAL (op), word_mode) == INTVAL (op)
4170 && s390_single_part (op, word_mode, HImode, 0) >= 0)
e5537457 4171 return true;
8b4a4127 4172
163277cf 4173 if (TARGET_EXTIMM
4174 && GET_CODE (op) == CONST_INT
4175 && trunc_int_for_mode (INTVAL (op), word_mode) == INTVAL (op)
4176 && s390_single_part (op, word_mode, SImode, 0) >= 0)
4177 return true;
4178
8b4a4127 4179 /* Accept larl operands. */
f5edbf1d 4180 if (larl_operand (op, VOIDmode))
e5537457 4181 return true;
8b4a4127 4182
70037005 4183 /* Accept floating-point zero operands that fit into a single GPR. */
4184 if (GET_CODE (op) == CONST_DOUBLE
4185 && s390_float_const_zero_p (op)
4186 && GET_MODE_SIZE (GET_MODE (op)) <= UNITS_PER_WORD)
4187 return true;
4188
53239c89 4189 /* Accept double-word operands that can be split. */
ba0e61d6 4190 if (GET_CODE (op) == CONST_WIDE_INT
4191 || (GET_CODE (op) == CONST_INT
4192 && trunc_int_for_mode (INTVAL (op), word_mode) != INTVAL (op)))
53239c89 4193 {
3754d046 4194 machine_mode dword_mode = word_mode == SImode ? DImode : TImode;
53239c89 4195 rtx hi = operand_subword (op, 0, 0, dword_mode);
4196 rtx lo = operand_subword (op, 1, 0, dword_mode);
4197 return legitimate_reload_constant_p (hi)
4198 && legitimate_reload_constant_p (lo);
4199 }
4200
8b4a4127 4201 /* Everything else cannot be handled without reload. */
e5537457 4202 return false;
8b4a4127 4203}
4204
33d033da 4205/* Returns true if the constant value OP is a legitimate fp operand
4206 during and after reload.
4207 This function accepts all constants which can be loaded directly
4208 into an FPR. */
4209
4210static bool
4211legitimate_reload_fp_constant_p (rtx op)
4212{
4213 /* Accept floating-point zero operands if the load zero instruction
81769881 4214 can be used. Prior to z196 the load fp zero instruction caused a
4215 performance penalty if the result is used as BFP number. */
33d033da 4216 if (TARGET_Z196
4217 && GET_CODE (op) == CONST_DOUBLE
4218 && s390_float_const_zero_p (op))
4219 return true;
4220
4221 return false;
4222}
4223
76a4c804 4224/* Returns true if the constant value OP is a legitimate vector operand
4225 during and after reload.
4226 This function accepts all constants which can be loaded directly
4227 into an VR. */
4228
4229static bool
4230legitimate_reload_vector_constant_p (rtx op)
4231{
76a4c804 4232 if (TARGET_VX && GET_MODE_SIZE (GET_MODE (op)) == 16
80fc7f56 4233 && (satisfies_constraint_j00 (op)
4234 || satisfies_constraint_jm1 (op)
4235 || satisfies_constraint_jKK (op)
4236 || satisfies_constraint_jxx (op)
4237 || satisfies_constraint_jyy (op)))
76a4c804 4238 return true;
4239
4240 return false;
4241}
4242
8deb3959 4243/* Given an rtx OP being reloaded into a reg required to be in class RCLASS,
8b4a4127 4244 return the class of reg to actually use. */
4245
3359ccfd 4246static reg_class_t
4247s390_preferred_reload_class (rtx op, reg_class_t rclass)
8b4a4127 4248{
8b4a4127 4249 switch (GET_CODE (op))
4250 {
70037005 4251 /* Constants we cannot reload into general registers
4252 must be forced into the literal pool. */
76a4c804 4253 case CONST_VECTOR:
8b4a4127 4254 case CONST_DOUBLE:
4255 case CONST_INT:
ba0e61d6 4256 case CONST_WIDE_INT:
70037005 4257 if (reg_class_subset_p (GENERAL_REGS, rclass)
4258 && legitimate_reload_constant_p (op))
4259 return GENERAL_REGS;
4260 else if (reg_class_subset_p (ADDR_REGS, rclass)
4261 && legitimate_reload_constant_p (op))
4262 return ADDR_REGS;
33d033da 4263 else if (reg_class_subset_p (FP_REGS, rclass)
4264 && legitimate_reload_fp_constant_p (op))
4265 return FP_REGS;
76a4c804 4266 else if (reg_class_subset_p (VEC_REGS, rclass)
4267 && legitimate_reload_vector_constant_p (op))
4268 return VEC_REGS;
4269
33d033da 4270 return NO_REGS;
8b4a4127 4271
4272 /* If a symbolic constant or a PLUS is reloaded,
0b300c86 4273 it is most likely being used as an address, so
4274 prefer ADDR_REGS. If 'class' is not a superset
4275 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
de47476b 4276 case CONST:
37c55f71 4277 /* Symrefs cannot be pushed into the literal pool with -fPIC
4278 so we *MUST NOT* return NO_REGS for these cases
9f522e0c 4279 (s390_cannot_force_const_mem will return true).
37c55f71 4280
4281 On the other hand we MUST return NO_REGS for symrefs with
4282 invalid addend which might have been pushed to the literal
4283 pool (no -fPIC). Usually we would expect them to be
4284 handled via secondary reload but this does not happen if
4285 they are used as literal pool slot replacement in reload
4286 inheritance (see emit_input_reload_insns). */
f5edbf1d 4287 if (GET_CODE (XEXP (op, 0)) == PLUS
de47476b 4288 && GET_CODE (XEXP (XEXP(op, 0), 0)) == SYMBOL_REF
4289 && GET_CODE (XEXP (XEXP(op, 0), 1)) == CONST_INT)
4290 {
37c55f71 4291 if (flag_pic && reg_class_subset_p (ADDR_REGS, rclass))
de47476b 4292 return ADDR_REGS;
4293 else
4294 return NO_REGS;
4295 }
4296 /* fallthrough */
8b4a4127 4297 case LABEL_REF:
4298 case SYMBOL_REF:
08d88e72 4299 if (!legitimate_reload_constant_p (op))
9f522e0c 4300 return NO_REGS;
08d88e72 4301 /* fallthrough */
4302 case PLUS:
4303 /* load address will be used. */
8deb3959 4304 if (reg_class_subset_p (ADDR_REGS, rclass))
08d88e72 4305 return ADDR_REGS;
0b300c86 4306 else
4307 return NO_REGS;
8b4a4127 4308
4309 default:
4310 break;
4311 }
4312
8deb3959 4313 return rclass;
8b4a4127 4314}
4673c1a0 4315
e68d6a13 4316/* Return true if ADDR is SYMBOL_REF + addend with addend being a
4317 multiple of ALIGNMENT and the SYMBOL_REF being naturally
4318 aligned. */
4319
4320bool
4321s390_check_symref_alignment (rtx addr, HOST_WIDE_INT alignment)
4322{
4323 HOST_WIDE_INT addend;
4324 rtx symref;
4325
78affa36 4326 /* The "required alignment" might be 0 (e.g. for certain structs
4327 accessed via BLKmode). Early abort in this case, as well as when
4328 an alignment > 8 is required. */
4329 if (alignment < 2 || alignment > 8)
4330 return false;
4331
2a672556 4332 if (!s390_loadrelative_operand_p (addr, &symref, &addend))
4333 return false;
62cb5855 4334
2a672556 4335 if (addend & (alignment - 1))
e68d6a13 4336 return false;
4337
78affa36 4338 if (GET_CODE (symref) == SYMBOL_REF)
4339 {
63cd2315 4340 /* s390_encode_section_info is not called for anchors, since they don't
4341 have corresponding VAR_DECLs. Therefore, we cannot rely on
4342 SYMBOL_FLAG_NOTALIGN{2,4,8}_P returning useful information. */
4343 if (SYMBOL_REF_ANCHOR_P (symref))
4344 {
4345 HOST_WIDE_INT block_offset = SYMBOL_REF_BLOCK_OFFSET (symref);
4346 unsigned int block_alignment = (SYMBOL_REF_BLOCK (symref)->alignment
4347 / BITS_PER_UNIT);
4348
4349 gcc_assert (block_offset >= 0);
4350 return ((block_offset & (alignment - 1)) == 0
4351 && block_alignment >= alignment);
4352 }
4353
78affa36 4354 /* We have load-relative instructions for 2-byte, 4-byte, and
9f522e0c 4355 8-byte alignment so allow only these. */
78affa36 4356 switch (alignment)
4357 {
4358 case 8: return !SYMBOL_FLAG_NOTALIGN8_P (symref);
4359 case 4: return !SYMBOL_FLAG_NOTALIGN4_P (symref);
4360 case 2: return !SYMBOL_FLAG_NOTALIGN2_P (symref);
4361 default: return false;
4362 }
4363 }
2a672556 4364
4365 if (GET_CODE (symref) == UNSPEC
4366 && alignment <= UNITS_PER_LONG)
4367 return true;
4368
4369 return false;
e68d6a13 4370}
4371
4372/* ADDR is moved into REG using larl. If ADDR isn't a valid larl
4373 operand SCRATCH is used to reload the even part of the address and
4374 adding one. */
4375
4376void
4377s390_reload_larl_operand (rtx reg, rtx addr, rtx scratch)
4378{
4379 HOST_WIDE_INT addend;
4380 rtx symref;
4381
2a672556 4382 if (!s390_loadrelative_operand_p (addr, &symref, &addend))
e68d6a13 4383 gcc_unreachable ();
4384
4385 if (!(addend & 1))
4386 /* Easy case. The addend is even so larl will do fine. */
4387 emit_move_insn (reg, addr);
4388 else
4389 {
4390 /* We can leave the scratch register untouched if the target
4391 register is a valid base register. */
4392 if (REGNO (reg) < FIRST_PSEUDO_REGISTER
4393 && REGNO_REG_CLASS (REGNO (reg)) == ADDR_REGS)
4394 scratch = reg;
4395
4396 gcc_assert (REGNO (scratch) < FIRST_PSEUDO_REGISTER);
4397 gcc_assert (REGNO_REG_CLASS (REGNO (scratch)) == ADDR_REGS);
4398
4399 if (addend != 1)
4400 emit_move_insn (scratch,
4401 gen_rtx_CONST (Pmode,
4402 gen_rtx_PLUS (Pmode, symref,
4403 GEN_INT (addend - 1))));
4404 else
4405 emit_move_insn (scratch, symref);
4406
4407 /* Increment the address using la in order to avoid clobbering cc. */
de47476b 4408 s390_load_address (reg, gen_rtx_PLUS (Pmode, scratch, const1_rtx));
e68d6a13 4409 }
4410}
4411
4412/* Generate what is necessary to move between REG and MEM using
4413 SCRATCH. The direction is given by TOMEM. */
4414
4415void
4416s390_reload_symref_address (rtx reg, rtx mem, rtx scratch, bool tomem)
4417{
4418 /* Reload might have pulled a constant out of the literal pool.
4419 Force it back in. */
4420 if (CONST_INT_P (mem) || GET_CODE (mem) == CONST_DOUBLE
ba0e61d6 4421 || GET_CODE (mem) == CONST_WIDE_INT
76a4c804 4422 || GET_CODE (mem) == CONST_VECTOR
e68d6a13 4423 || GET_CODE (mem) == CONST)
4424 mem = force_const_mem (GET_MODE (reg), mem);
4425
4426 gcc_assert (MEM_P (mem));
4427
4428 /* For a load from memory we can leave the scratch register
4429 untouched if the target register is a valid base register. */
4430 if (!tomem
4431 && REGNO (reg) < FIRST_PSEUDO_REGISTER
4432 && REGNO_REG_CLASS (REGNO (reg)) == ADDR_REGS
4433 && GET_MODE (reg) == GET_MODE (scratch))
4434 scratch = reg;
4435
4436 /* Load address into scratch register. Since we can't have a
4437 secondary reload for a secondary reload we have to cover the case
4438 where larl would need a secondary reload here as well. */
4439 s390_reload_larl_operand (scratch, XEXP (mem, 0), scratch);
4440
4441 /* Now we can use a standard load/store to do the move. */
4442 if (tomem)
4443 emit_move_insn (replace_equiv_address (mem, scratch), reg);
4444 else
4445 emit_move_insn (reg, replace_equiv_address (mem, scratch));
4446}
4447
328d5423 4448/* Inform reload about cases where moving X with a mode MODE to a register in
8deb3959 4449 RCLASS requires an extra scratch or immediate register. Return the class
328d5423 4450 needed for the immediate register. */
429f9fdb 4451
964229b7 4452static reg_class_t
4453s390_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i,
3754d046 4454 machine_mode mode, secondary_reload_info *sri)
328d5423 4455{
964229b7 4456 enum reg_class rclass = (enum reg_class) rclass_i;
4457
328d5423 4458 /* Intermediate register needed. */
8deb3959 4459 if (reg_classes_intersect_p (CC_REGS, rclass))
bcbf02a5 4460 return GENERAL_REGS;
4461
76a4c804 4462 if (TARGET_VX)
4463 {
4464 /* The vst/vl vector move instructions allow only for short
4465 displacements. */
4466 if (MEM_P (x)
4467 && GET_CODE (XEXP (x, 0)) == PLUS
4468 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
4469 && !SHORT_DISP_IN_RANGE(INTVAL (XEXP (XEXP (x, 0), 1)))
4470 && reg_class_subset_p (rclass, VEC_REGS)
4471 && (!reg_class_subset_p (rclass, FP_REGS)
4472 || (GET_MODE_SIZE (mode) > 8
4473 && s390_class_max_nregs (FP_REGS, mode) == 1)))
4474 {
4475 if (in_p)
4476 sri->icode = (TARGET_64BIT ?
4477 CODE_FOR_reloaddi_la_in :
4478 CODE_FOR_reloadsi_la_in);
4479 else
4480 sri->icode = (TARGET_64BIT ?
4481 CODE_FOR_reloaddi_la_out :
4482 CODE_FOR_reloadsi_la_out);
4483 }
4484 }
4485
e68d6a13 4486 if (TARGET_Z10)
4487 {
08d88e72 4488 HOST_WIDE_INT offset;
4489 rtx symref;
4490
e68d6a13 4491 /* On z10 several optimizer steps may generate larl operands with
4492 an odd addend. */
4493 if (in_p
2a672556 4494 && s390_loadrelative_operand_p (x, &symref, &offset)
e68d6a13 4495 && mode == Pmode
78affa36 4496 && !SYMBOL_FLAG_NOTALIGN2_P (symref)
08d88e72 4497 && (offset & 1) == 1)
e68d6a13 4498 sri->icode = ((mode == DImode) ? CODE_FOR_reloaddi_larl_odd_addend_z10
4499 : CODE_FOR_reloadsi_larl_odd_addend_z10);
4500
ddb92daa 4501 /* Handle all the (mem (symref)) accesses we cannot use the z10
4502 instructions for. */
e68d6a13 4503 if (MEM_P (x)
2a672556 4504 && s390_loadrelative_operand_p (XEXP (x, 0), NULL, NULL)
ddb92daa 4505 && (mode == QImode
a1142483 4506 || !reg_class_subset_p (rclass, GENERAL_REGS)
ddb92daa 4507 || GET_MODE_SIZE (mode) > UNITS_PER_WORD
4508 || !s390_check_symref_alignment (XEXP (x, 0),
4509 GET_MODE_SIZE (mode))))
e68d6a13 4510 {
4511#define __SECONDARY_RELOAD_CASE(M,m) \
916ace94 4512 case E_##M##mode: \
e68d6a13 4513 if (TARGET_64BIT) \
4514 sri->icode = in_p ? CODE_FOR_reload##m##di_toreg_z10 : \
9f522e0c 4515 CODE_FOR_reload##m##di_tomem_z10; \
e68d6a13 4516 else \
9f522e0c 4517 sri->icode = in_p ? CODE_FOR_reload##m##si_toreg_z10 : \
4518 CODE_FOR_reload##m##si_tomem_z10; \
e68d6a13 4519 break;
4520
4521 switch (GET_MODE (x))
4522 {
4523 __SECONDARY_RELOAD_CASE (QI, qi);
4524 __SECONDARY_RELOAD_CASE (HI, hi);
4525 __SECONDARY_RELOAD_CASE (SI, si);
4526 __SECONDARY_RELOAD_CASE (DI, di);
4527 __SECONDARY_RELOAD_CASE (TI, ti);
4528 __SECONDARY_RELOAD_CASE (SF, sf);
4529 __SECONDARY_RELOAD_CASE (DF, df);
4530 __SECONDARY_RELOAD_CASE (TF, tf);
4531 __SECONDARY_RELOAD_CASE (SD, sd);
4532 __SECONDARY_RELOAD_CASE (DD, dd);
4533 __SECONDARY_RELOAD_CASE (TD, td);
76a4c804 4534 __SECONDARY_RELOAD_CASE (V1QI, v1qi);
4535 __SECONDARY_RELOAD_CASE (V2QI, v2qi);
4536 __SECONDARY_RELOAD_CASE (V4QI, v4qi);
4537 __SECONDARY_RELOAD_CASE (V8QI, v8qi);
4538 __SECONDARY_RELOAD_CASE (V16QI, v16qi);
4539 __SECONDARY_RELOAD_CASE (V1HI, v1hi);
4540 __SECONDARY_RELOAD_CASE (V2HI, v2hi);
4541 __SECONDARY_RELOAD_CASE (V4HI, v4hi);
4542 __SECONDARY_RELOAD_CASE (V8HI, v8hi);
4543 __SECONDARY_RELOAD_CASE (V1SI, v1si);
4544 __SECONDARY_RELOAD_CASE (V2SI, v2si);
4545 __SECONDARY_RELOAD_CASE (V4SI, v4si);
4546 __SECONDARY_RELOAD_CASE (V1DI, v1di);
4547 __SECONDARY_RELOAD_CASE (V2DI, v2di);
4548 __SECONDARY_RELOAD_CASE (V1TI, v1ti);
4549 __SECONDARY_RELOAD_CASE (V1SF, v1sf);
4550 __SECONDARY_RELOAD_CASE (V2SF, v2sf);
4551 __SECONDARY_RELOAD_CASE (V4SF, v4sf);
4552 __SECONDARY_RELOAD_CASE (V1DF, v1df);
4553 __SECONDARY_RELOAD_CASE (V2DF, v2df);
4554 __SECONDARY_RELOAD_CASE (V1TF, v1tf);
e68d6a13 4555 default:
4556 gcc_unreachable ();
4557 }
4558#undef __SECONDARY_RELOAD_CASE
4559 }
4560 }
4561
328d5423 4562 /* We need a scratch register when loading a PLUS expression which
4563 is not a legitimate operand of the LOAD ADDRESS instruction. */
7b1bda1c 4564 /* LRA can deal with transformation of plus op very well -- so we
4565 don't need to prompt LRA in this case. */
4566 if (! lra_in_progress && in_p && s390_plus_operand (x, mode))
328d5423 4567 sri->icode = (TARGET_64BIT ?
4568 CODE_FOR_reloaddi_plus : CODE_FOR_reloadsi_plus);
4569
efec32e0 4570 /* Performing a multiword move from or to memory we have to make sure the
328d5423 4571 second chunk in memory is addressable without causing a displacement
4572 overflow. If that would be the case we calculate the address in
4573 a scratch register. */
4574 if (MEM_P (x)
4575 && GET_CODE (XEXP (x, 0)) == PLUS
4576 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
4577 && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (x, 0), 1))
6938bdf8 4578 + GET_MODE_SIZE (mode) - 1))
328d5423 4579 {
efec32e0 4580 /* For GENERAL_REGS a displacement overflow is no problem if occurring
328d5423 4581 in a s_operand address since we may fallback to lm/stm. So we only
4582 have to care about overflows in the b+i+d case. */
8deb3959 4583 if ((reg_classes_intersect_p (GENERAL_REGS, rclass)
328d5423 4584 && s390_class_max_nregs (GENERAL_REGS, mode) > 1
4585 && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS)
4586 /* For FP_REGS no lm/stm is available so this check is triggered
4587 for displacement overflows in b+i+d and b+d like addresses. */
8deb3959 4588 || (reg_classes_intersect_p (FP_REGS, rclass)
328d5423 4589 && s390_class_max_nregs (FP_REGS, mode) > 1))
4590 {
4591 if (in_p)
4592 sri->icode = (TARGET_64BIT ?
76a4c804 4593 CODE_FOR_reloaddi_la_in :
4594 CODE_FOR_reloadsi_la_in);
328d5423 4595 else
4596 sri->icode = (TARGET_64BIT ?
76a4c804 4597 CODE_FOR_reloaddi_la_out :
4598 CODE_FOR_reloadsi_la_out);
328d5423 4599 }
4600 }
bcbf02a5 4601
08b5e262 4602 /* A scratch address register is needed when a symbolic constant is
4603 copied to r0 compiling with -fPIC. In other cases the target
4604 register might be used as temporary (see legitimize_pic_address). */
8deb3959 4605 if (in_p && SYMBOLIC_CONST (x) && flag_pic == 2 && rclass != ADDR_REGS)
08b5e262 4606 sri->icode = (TARGET_64BIT ?
4607 CODE_FOR_reloaddi_PIC_addr :
4608 CODE_FOR_reloadsi_PIC_addr);
4609
328d5423 4610 /* Either scratch or no register needed. */
66795431 4611 return NO_REGS;
4612}
4613
c836e75b 4614/* Implement TARGET_SECONDARY_MEMORY_NEEDED.
4615
4616 We need secondary memory to move data between GPRs and FPRs.
4617
4618 - With DFP the ldgr lgdr instructions are available. Due to the
4619 different alignment we cannot use them for SFmode. For 31 bit a
4620 64 bit value in GPR would be a register pair so here we still
4621 need to go via memory.
4622
4623 - With z13 we can do the SF/SImode moves with vlgvf. Due to the
4624 overlapping of FPRs and VRs we still disallow TF/TD modes to be
4625 in full VRs so as before also on z13 we do these moves via
4626 memory.
4627
4628 FIXME: Should we try splitting it into two vlgvg's/vlvg's instead? */
4629
4630static bool
4631s390_secondary_memory_needed (machine_mode mode,
4632 reg_class_t class1, reg_class_t class2)
4633{
4634 return (((reg_classes_intersect_p (class1, VEC_REGS)
4635 && reg_classes_intersect_p (class2, GENERAL_REGS))
4636 || (reg_classes_intersect_p (class1, GENERAL_REGS)
4637 && reg_classes_intersect_p (class2, VEC_REGS)))
4638 && (!TARGET_DFP || !TARGET_64BIT || GET_MODE_SIZE (mode) != 8)
4639 && (!TARGET_VX || (SCALAR_FLOAT_MODE_P (mode)
4640 && GET_MODE_SIZE (mode) > 8)));
4641}
4642
1041f930 4643/* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE.
4644
4645 get_secondary_mem widens its argument to BITS_PER_WORD which loses on 64bit
4646 because the movsi and movsf patterns don't handle r/f moves. */
4647
4648static machine_mode
4649s390_secondary_memory_needed_mode (machine_mode mode)
4650{
4651 if (GET_MODE_BITSIZE (mode) < 32)
4652 return mode_for_size (32, GET_MODE_CLASS (mode), 0).require ();
4653 return mode;
4654}
4655
64f977d6 4656/* Generate code to load SRC, which is PLUS that is not a
4657 legitimate operand for the LA instruction, into TARGET.
4658 SCRATCH may be used as scratch register. */
4659
4660void
edd89d66 4661s390_expand_plus_operand (rtx target, rtx src,
4662 rtx scratch)
64f977d6 4663{
e7f0624a 4664 rtx sum1, sum2;
8ba34dcd 4665 struct s390_address ad;
dc4951d9 4666
dc4951d9 4667 /* src must be a PLUS; get its two operands. */
32eda510 4668 gcc_assert (GET_CODE (src) == PLUS);
4669 gcc_assert (GET_MODE (src) == Pmode);
64f977d6 4670
c10847b9 4671 /* Check if any of the two operands is already scheduled
4672 for replacement by reload. This can happen e.g. when
4673 float registers occur in an address. */
4674 sum1 = find_replacement (&XEXP (src, 0));
4675 sum2 = find_replacement (&XEXP (src, 1));
a5004c3d 4676 src = gen_rtx_PLUS (Pmode, sum1, sum2);
a5004c3d 4677
e7f0624a 4678 /* If the address is already strictly valid, there's nothing to do. */
4679 if (!s390_decompose_address (src, &ad)
1e280623 4680 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
4681 || (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx))))
64f977d6 4682 {
e7f0624a 4683 /* Otherwise, one of the operands cannot be an address register;
9f522e0c 4684 we reload its value into the scratch register. */
e7f0624a 4685 if (true_regnum (sum1) < 1 || true_regnum (sum1) > 15)
4686 {
4687 emit_move_insn (scratch, sum1);
4688 sum1 = scratch;
4689 }
4690 if (true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
4691 {
4692 emit_move_insn (scratch, sum2);
4693 sum2 = scratch;
4694 }
64f977d6 4695
e7f0624a 4696 /* According to the way these invalid addresses are generated
9f522e0c 4697 in reload.c, it should never happen (at least on s390) that
4698 *neither* of the PLUS components, after find_replacements
4699 was applied, is an address register. */
e7f0624a 4700 if (sum1 == scratch && sum2 == scratch)
4701 {
4702 debug_rtx (src);
32eda510 4703 gcc_unreachable ();
e7f0624a 4704 }
64f977d6 4705
e7f0624a 4706 src = gen_rtx_PLUS (Pmode, sum1, sum2);
64f977d6 4707 }
4708
4709 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
4710 is only ever performed on addresses, so we can mark the
4711 sum as legitimate for LA in any case. */
4fbc4db5 4712 s390_load_address (target, src);
64f977d6 4713}
4714
4715
e5537457 4716/* Return true if ADDR is a valid memory address.
875862bf 4717 STRICT specifies whether strict register checking applies. */
4673c1a0 4718
fd50b071 4719static bool
3754d046 4720s390_legitimate_address_p (machine_mode mode, rtx addr, bool strict)
4673c1a0 4721{
875862bf 4722 struct s390_address ad;
e68d6a13 4723
4724 if (TARGET_Z10
4725 && larl_operand (addr, VOIDmode)
4726 && (mode == VOIDmode
4727 || s390_check_symref_alignment (addr, GET_MODE_SIZE (mode))))
4728 return true;
4729
875862bf 4730 if (!s390_decompose_address (addr, &ad))
e5537457 4731 return false;
8ba34dcd 4732
4556f83e 4733 /* The vector memory instructions only support short displacements.
4734 Reject invalid displacements early to prevent plenty of lay
4735 instructions to be generated later which then cannot be merged
4736 properly. */
4737 if (TARGET_VX
4738 && VECTOR_MODE_P (mode)
4739 && ad.disp != NULL_RTX
4740 && CONST_INT_P (ad.disp)
4741 && !SHORT_DISP_IN_RANGE (INTVAL (ad.disp)))
4742 return false;
4743
8ba34dcd 4744 if (strict)
4745 {
1e280623 4746 if (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
e5537457 4747 return false;
1e280623 4748
4749 if (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx)))
e5537457 4750 return false;
8ba34dcd 4751 }
4752 else
4753 {
ffead1ca 4754 if (ad.base
1e280623 4755 && !(REGNO (ad.base) >= FIRST_PSEUDO_REGISTER
4756 || REGNO_REG_CLASS (REGNO (ad.base)) == ADDR_REGS))
e5537457 4757 return false;
ffead1ca 4758
1e280623 4759 if (ad.indx
4760 && !(REGNO (ad.indx) >= FIRST_PSEUDO_REGISTER
4761 || REGNO_REG_CLASS (REGNO (ad.indx)) == ADDR_REGS))
4762 return false;
8ba34dcd 4763 }
e5537457 4764 return true;
4673c1a0 4765}
4766
e5537457 4767/* Return true if OP is a valid operand for the LA instruction.
2eb8fe23 4768 In 31-bit, we need to prove that the result is used as an
4769 address, as LA performs only a 31-bit addition. */
4770
e5537457 4771bool
edd89d66 4772legitimate_la_operand_p (rtx op)
2eb8fe23 4773{
4774 struct s390_address addr;
8ba34dcd 4775 if (!s390_decompose_address (op, &addr))
e5537457 4776 return false;
2eb8fe23 4777
e5537457 4778 return (TARGET_64BIT || addr.pointer);
64f977d6 4779}
2eb8fe23 4780
e5537457 4781/* Return true if it is valid *and* preferable to use LA to
c6061690 4782 compute the sum of OP1 and OP2. */
f81e845f 4783
e5537457 4784bool
c6061690 4785preferred_la_operand_p (rtx op1, rtx op2)
a40b2054 4786{
4787 struct s390_address addr;
c6061690 4788
4789 if (op2 != const0_rtx)
4790 op1 = gen_rtx_PLUS (Pmode, op1, op2);
4791
4792 if (!s390_decompose_address (op1, &addr))
e5537457 4793 return false;
1e280623 4794 if (addr.base && !REGNO_OK_FOR_BASE_P (REGNO (addr.base)))
e5537457 4795 return false;
1e280623 4796 if (addr.indx && !REGNO_OK_FOR_INDEX_P (REGNO (addr.indx)))
e5537457 4797 return false;
a40b2054 4798
ca434dcf 4799 /* Avoid LA instructions with index (and base) register on z196 or
4800 later; it is preferable to use regular add instructions when
4801 possible. Starting with zEC12 the la with index register is
4802 "uncracked" again but still slower than a regular add. */
4803 if (addr.indx && s390_tune >= PROCESSOR_2817_Z196)
33d033da 4804 return false;
4805
a40b2054 4806 if (!TARGET_64BIT && !addr.pointer)
e5537457 4807 return false;
a40b2054 4808
4809 if (addr.pointer)
e5537457 4810 return true;
a40b2054 4811
ec3b9583 4812 if ((addr.base && REG_P (addr.base) && REG_POINTER (addr.base))
4813 || (addr.indx && REG_P (addr.indx) && REG_POINTER (addr.indx)))
e5537457 4814 return true;
a40b2054 4815
e5537457 4816 return false;
a40b2054 4817}
4818
4fbc4db5 4819/* Emit a forced load-address operation to load SRC into DST.
4820 This will use the LOAD ADDRESS instruction even in situations
4821 where legitimate_la_operand_p (SRC) returns false. */
2eb8fe23 4822
4fbc4db5 4823void
b40da9a7 4824s390_load_address (rtx dst, rtx src)
64f977d6 4825{
4fbc4db5 4826 if (TARGET_64BIT)
4827 emit_move_insn (dst, src);
4828 else
4829 emit_insn (gen_force_la_31 (dst, src));
2eb8fe23 4830}
4831
9852c8ae 4832/* Return true if it ok to use SYMBOL_REF in a relative address. */
4833
4834bool
4835s390_rel_address_ok_p (rtx symbol_ref)
4836{
4837 tree decl;
4838
4839 if (symbol_ref == s390_got_symbol () || CONSTANT_POOL_ADDRESS_P (symbol_ref))
4840 return true;
4841
4842 decl = SYMBOL_REF_DECL (symbol_ref);
4843
4844 if (!flag_pic || SYMBOL_REF_LOCAL_P (symbol_ref))
4845 return (s390_pic_data_is_text_relative
4846 || (decl
4847 && TREE_CODE (decl) == FUNCTION_DECL));
4848
4849 return false;
4850}
4851
4673c1a0 4852/* Return a legitimate reference for ORIG (an address) using the
4853 register REG. If REG is 0, a new pseudo is generated.
4854
4855 There are two types of references that must be handled:
4856
4857 1. Global data references must load the address from the GOT, via
4858 the PIC reg. An insn is emitted to do this load, and the reg is
4859 returned.
4860
4861 2. Static data references, constant pool addresses, and code labels
4862 compute the address as an offset from the GOT, whose base is in
a3e33162 4863 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
4673c1a0 4864 differentiate them from global data objects. The returned
4865 address is the PIC reg + an unspec constant.
4866
bc409cb4 4867 TARGET_LEGITIMIZE_ADDRESS_P rejects symbolic references unless the PIC
4673c1a0 4868 reg also appears in the address. */
4869
4870rtx
b40da9a7 4871legitimize_pic_address (rtx orig, rtx reg)
4673c1a0 4872{
4873 rtx addr = orig;
2a672556 4874 rtx addend = const0_rtx;
8deb3959 4875 rtx new_rtx = orig;
4673c1a0 4876
1ed004b7 4877 gcc_assert (!TLS_SYMBOLIC_CONST (addr));
4878
2a672556 4879 if (GET_CODE (addr) == CONST)
4880 addr = XEXP (addr, 0);
4881
4882 if (GET_CODE (addr) == PLUS)
4673c1a0 4883 {
2a672556 4884 addend = XEXP (addr, 1);
4885 addr = XEXP (addr, 0);
4886 }
4887
4888 if ((GET_CODE (addr) == LABEL_REF
9852c8ae 4889 || (SYMBOL_REF_P (addr) && s390_rel_address_ok_p (addr))
2a672556 4890 || (GET_CODE (addr) == UNSPEC &&
4891 (XINT (addr, 1) == UNSPEC_GOTENT
f5edbf1d 4892 || XINT (addr, 1) == UNSPEC_PLT)))
2a672556 4893 && GET_CODE (addend) == CONST_INT)
4894 {
4895 /* This can be locally addressed. */
4896
4897 /* larl_operand requires UNSPECs to be wrapped in a const rtx. */
4898 rtx const_addr = (GET_CODE (addr) == UNSPEC ?
4899 gen_rtx_CONST (Pmode, addr) : addr);
4900
f5edbf1d 4901 if (larl_operand (const_addr, VOIDmode)
b422d8c0 4902 && INTVAL (addend) < HOST_WIDE_INT_1 << 31
4903 && INTVAL (addend) >= -(HOST_WIDE_INT_1 << 31))
2a672556 4904 {
4905 if (INTVAL (addend) & 1)
4906 {
4907 /* LARL can't handle odd offsets, so emit a pair of LARL
4908 and LA. */
4909 rtx temp = reg? reg : gen_reg_rtx (Pmode);
4910
4911 if (!DISP_IN_RANGE (INTVAL (addend)))
4912 {
4913 HOST_WIDE_INT even = INTVAL (addend) - 1;
4914 addr = gen_rtx_PLUS (Pmode, addr, GEN_INT (even));
4915 addr = gen_rtx_CONST (Pmode, addr);
4916 addend = const1_rtx;
4917 }
4918
4919 emit_move_insn (temp, addr);
4920 new_rtx = gen_rtx_PLUS (Pmode, temp, addend);
4921
4922 if (reg != 0)
4923 {
4924 s390_load_address (reg, new_rtx);
4925 new_rtx = reg;
4926 }
4927 }
4928 else
4929 {
4930 /* If the offset is even, we can just use LARL. This
4931 will happen automatically. */
4932 }
4933 }
4673c1a0 4934 else
2a672556 4935 {
4936 /* No larl - Access local symbols relative to the GOT. */
4673c1a0 4937
2a672556 4938 rtx temp = reg? reg : gen_reg_rtx (Pmode);
4673c1a0 4939
12ef3745 4940 if (reload_in_progress || reload_completed)
3072d30e 4941 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
12ef3745 4942
2a672556 4943 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
4944 if (addend != const0_rtx)
4945 addr = gen_rtx_PLUS (Pmode, addr, addend);
4946 addr = gen_rtx_CONST (Pmode, addr);
4947 addr = force_const_mem (Pmode, addr);
4673c1a0 4948 emit_move_insn (temp, addr);
4949
2a672556 4950 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
4951 if (reg != 0)
4952 {
4953 s390_load_address (reg, new_rtx);
4954 new_rtx = reg;
4955 }
4956 }
4673c1a0 4957 }
2a672556 4958 else if (GET_CODE (addr) == SYMBOL_REF && addend == const0_rtx)
4673c1a0 4959 {
2a672556 4960 /* A non-local symbol reference without addend.
4961
4962 The symbol ref is wrapped into an UNSPEC to make sure the
4963 proper operand modifier (@GOT or @GOTENT) will be emitted.
4964 This will tell the linker to put the symbol into the GOT.
4965
4966 Additionally the code dereferencing the GOT slot is emitted here.
4967
4968 An addend to the symref needs to be added afterwards.
4969 legitimize_pic_address calls itself recursively to handle
4970 that case. So no need to do it here. */
4971
4673c1a0 4972 if (reg == 0)
9f522e0c 4973 reg = gen_reg_rtx (Pmode);
4673c1a0 4974
2a672556 4975 if (TARGET_Z10)
4976 {
4977 /* Use load relative if possible.
4978 lgrl <target>, sym@GOTENT */
4979 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTENT);
4980 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
4981 new_rtx = gen_const_mem (GET_MODE (reg), new_rtx);
4982
4983 emit_move_insn (reg, new_rtx);
4984 new_rtx = reg;
4985 }
4986 else if (flag_pic == 1)
9f522e0c 4987 {
4988 /* Assume GOT offset is a valid displacement operand (< 4k
4989 or < 512k with z990). This is handled the same way in
4990 both 31- and 64-bit code (@GOT).
4991 lg <target>, sym@GOT(r12) */
4673c1a0 4992
9a2a66ae 4993 if (reload_in_progress || reload_completed)
3072d30e 4994 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
4673c1a0 4995
9f522e0c 4996 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
4997 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
4998 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
4999 new_rtx = gen_const_mem (Pmode, new_rtx);
f5edbf1d 5000 emit_move_insn (reg, new_rtx);
5001 new_rtx = reg;
5002 }
5003 else
5004 {
5005 /* If the GOT offset might be >= 4k, we determine the position
5006 of the GOT entry via a PC-relative LARL (@GOTENT).
2a672556 5007 larl temp, sym@GOTENT
9f522e0c 5008 lg <target>, 0(temp) */
4673c1a0 5009
9f522e0c 5010 rtx temp = reg ? reg : gen_reg_rtx (Pmode);
08b5e262 5011
5012 gcc_assert (REGNO (temp) >= FIRST_PSEUDO_REGISTER
5013 || REGNO_REG_CLASS (REGNO (temp)) == ADDR_REGS);
4673c1a0 5014
9f522e0c 5015 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTENT);
5016 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
2a672556 5017 emit_move_insn (temp, new_rtx);
2a672556 5018 new_rtx = gen_const_mem (Pmode, temp);
f5edbf1d 5019 emit_move_insn (reg, new_rtx);
4673c1a0 5020
f5edbf1d 5021 new_rtx = reg;
5022 }
f81e845f 5023 }
2a672556 5024 else if (GET_CODE (addr) == UNSPEC && GET_CODE (addend) == CONST_INT)
4673c1a0 5025 {
2a672556 5026 gcc_assert (XVECLEN (addr, 0) == 1);
5027 switch (XINT (addr, 1))
4673c1a0 5028 {
2a672556 5029 /* These address symbols (or PLT slots) relative to the GOT
5030 (not GOT slots!). In general this will exceed the
5031 displacement range so these value belong into the literal
5032 pool. */
5033 case UNSPEC_GOTOFF:
5034 case UNSPEC_PLTOFF:
5035 new_rtx = force_const_mem (Pmode, orig);
5036 break;
4673c1a0 5037
2a672556 5038 /* For -fPIC the GOT size might exceed the displacement
5039 range so make sure the value is in the literal pool. */
5040 case UNSPEC_GOT:
5041 if (flag_pic == 2)
5042 new_rtx = force_const_mem (Pmode, orig);
5043 break;
4673c1a0 5044
2a672556 5045 /* For @GOTENT larl is used. This is handled like local
5046 symbol refs. */
5047 case UNSPEC_GOTENT:
5048 gcc_unreachable ();
5049 break;
4673c1a0 5050
f5edbf1d 5051 /* For @PLT larl is used. This is handled like local
5052 symbol refs. */
2a672556 5053 case UNSPEC_PLT:
f5edbf1d 5054 gcc_unreachable ();
2a672556 5055 break;
5056
5057 /* Everything else cannot happen. */
5058 default:
5059 gcc_unreachable ();
5060 }
5061 }
5062 else if (addend != const0_rtx)
5063 {
5064 /* Otherwise, compute the sum. */
4673c1a0 5065
2a672556 5066 rtx base = legitimize_pic_address (addr, reg);
5067 new_rtx = legitimize_pic_address (addend,
5068 base == reg ? NULL_RTX : reg);
5069 if (GET_CODE (new_rtx) == CONST_INT)
5070 new_rtx = plus_constant (Pmode, base, INTVAL (new_rtx));
5071 else
5072 {
5073 if (GET_CODE (new_rtx) == PLUS && CONSTANT_P (XEXP (new_rtx, 1)))
5074 {
5075 base = gen_rtx_PLUS (Pmode, base, XEXP (new_rtx, 0));
5076 new_rtx = XEXP (new_rtx, 1);
4673c1a0 5077 }
2a672556 5078 new_rtx = gen_rtx_PLUS (Pmode, base, new_rtx);
4673c1a0 5079 }
2a672556 5080
5081 if (GET_CODE (new_rtx) == CONST)
5082 new_rtx = XEXP (new_rtx, 0);
5083 new_rtx = force_operand (new_rtx, 0);
4673c1a0 5084 }
2a672556 5085
8deb3959 5086 return new_rtx;
4673c1a0 5087}
5088
be00aaa8 5089/* Load the thread pointer into a register. */
5090
cc87d0c5 5091rtx
5092s390_get_thread_pointer (void)
be00aaa8 5093{
923cf36d 5094 rtx tp = gen_reg_rtx (Pmode);
be00aaa8 5095
923cf36d 5096 emit_move_insn (tp, gen_rtx_REG (Pmode, TP_REGNUM));
be00aaa8 5097 mark_reg_pointer (tp, BITS_PER_WORD);
5098
5099 return tp;
5100}
5101
7346ca58 5102/* Emit a tls call insn. The call target is the SYMBOL_REF stored
5103 in s390_tls_symbol which always refers to __tls_get_offset.
5104 The returned offset is written to RESULT_REG and an USE rtx is
5105 generated for TLS_CALL. */
be00aaa8 5106
5107static GTY(()) rtx s390_tls_symbol;
7346ca58 5108
5109static void
5110s390_emit_tls_call_insn (rtx result_reg, rtx tls_call)
be00aaa8 5111{
7346ca58 5112 rtx insn;
f588eb9f 5113
c60a7572 5114 if (!flag_pic)
5115 emit_insn (s390_load_got ());
7346ca58 5116
be00aaa8 5117 if (!s390_tls_symbol)
5118 s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset");
5119
f588eb9f 5120 insn = s390_emit_call (s390_tls_symbol, tls_call, result_reg,
5121 gen_rtx_REG (Pmode, RETURN_REGNUM));
7346ca58 5122
5123 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), result_reg);
9c2a0c05 5124 RTL_CONST_CALL_P (insn) = 1;
be00aaa8 5125}
5126
5127/* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5128 this (thread-local) address. REG may be used as temporary. */
5129
5130static rtx
b40da9a7 5131legitimize_tls_address (rtx addr, rtx reg)
be00aaa8 5132{
db7dd023 5133 rtx new_rtx, tls_call, temp, base, r2;
5134 rtx_insn *insn;
be00aaa8 5135
5136 if (GET_CODE (addr) == SYMBOL_REF)
5137 switch (tls_symbolic_operand (addr))
5138 {
5139 case TLS_MODEL_GLOBAL_DYNAMIC:
5140 start_sequence ();
5141 r2 = gen_rtx_REG (Pmode, 2);
5142 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLSGD);
8deb3959 5143 new_rtx = gen_rtx_CONST (Pmode, tls_call);
5144 new_rtx = force_const_mem (Pmode, new_rtx);
5145 emit_move_insn (r2, new_rtx);
7346ca58 5146 s390_emit_tls_call_insn (r2, tls_call);
be00aaa8 5147 insn = get_insns ();
5148 end_sequence ();
5149
8deb3959 5150 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
be00aaa8 5151 temp = gen_reg_rtx (Pmode);
8deb3959 5152 emit_libcall_block (insn, temp, r2, new_rtx);
be00aaa8 5153
8deb3959 5154 new_rtx = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
be00aaa8 5155 if (reg != 0)
5156 {
8deb3959 5157 s390_load_address (reg, new_rtx);
5158 new_rtx = reg;
be00aaa8 5159 }
5160 break;
5161
5162 case TLS_MODEL_LOCAL_DYNAMIC:
5163 start_sequence ();
5164 r2 = gen_rtx_REG (Pmode, 2);
5165 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM);
8deb3959 5166 new_rtx = gen_rtx_CONST (Pmode, tls_call);
5167 new_rtx = force_const_mem (Pmode, new_rtx);
5168 emit_move_insn (r2, new_rtx);
7346ca58 5169 s390_emit_tls_call_insn (r2, tls_call);
be00aaa8 5170 insn = get_insns ();
5171 end_sequence ();
5172
8deb3959 5173 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM_NTPOFF);
be00aaa8 5174 temp = gen_reg_rtx (Pmode);
8deb3959 5175 emit_libcall_block (insn, temp, r2, new_rtx);
be00aaa8 5176
8deb3959 5177 new_rtx = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
be00aaa8 5178 base = gen_reg_rtx (Pmode);
8deb3959 5179 s390_load_address (base, new_rtx);
be00aaa8 5180
8deb3959 5181 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_DTPOFF);
5182 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
5183 new_rtx = force_const_mem (Pmode, new_rtx);
be00aaa8 5184 temp = gen_reg_rtx (Pmode);
8deb3959 5185 emit_move_insn (temp, new_rtx);
be00aaa8 5186
8deb3959 5187 new_rtx = gen_rtx_PLUS (Pmode, base, temp);
be00aaa8 5188 if (reg != 0)
5189 {
8deb3959 5190 s390_load_address (reg, new_rtx);
5191 new_rtx = reg;
be00aaa8 5192 }
5193 break;
5194
5195 case TLS_MODEL_INITIAL_EXEC:
5196 if (flag_pic == 1)
5197 {
5198 /* Assume GOT offset < 4k. This is handled the same way
5199 in both 31- and 64-bit code. */
5200
5201 if (reload_in_progress || reload_completed)
3072d30e 5202 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
be00aaa8 5203
8deb3959 5204 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
5205 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
5206 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
5207 new_rtx = gen_const_mem (Pmode, new_rtx);
be00aaa8 5208 temp = gen_reg_rtx (Pmode);
8deb3959 5209 emit_move_insn (temp, new_rtx);
be00aaa8 5210 }
f5edbf1d 5211 else
be00aaa8 5212 {
5213 /* If the GOT offset might be >= 4k, we determine the position
5214 of the GOT entry via a PC-relative LARL. */
5215
8deb3959 5216 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
5217 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
be00aaa8 5218 temp = gen_reg_rtx (Pmode);
8deb3959 5219 emit_move_insn (temp, new_rtx);
be00aaa8 5220
8deb3959 5221 new_rtx = gen_const_mem (Pmode, temp);
be00aaa8 5222 temp = gen_reg_rtx (Pmode);
8deb3959 5223 emit_move_insn (temp, new_rtx);
be00aaa8 5224 }
be00aaa8 5225
8deb3959 5226 new_rtx = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
be00aaa8 5227 if (reg != 0)
5228 {
8deb3959 5229 s390_load_address (reg, new_rtx);
5230 new_rtx = reg;
be00aaa8 5231 }
5232 break;
5233
5234 case TLS_MODEL_LOCAL_EXEC:
8deb3959 5235 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
5236 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
5237 new_rtx = force_const_mem (Pmode, new_rtx);
9f522e0c 5238 temp = gen_reg_rtx (Pmode);
8deb3959 5239 emit_move_insn (temp, new_rtx);
be00aaa8 5240
8deb3959 5241 new_rtx = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
be00aaa8 5242 if (reg != 0)
5243 {
8deb3959 5244 s390_load_address (reg, new_rtx);
5245 new_rtx = reg;
be00aaa8 5246 }
5247 break;
5248
5249 default:
32eda510 5250 gcc_unreachable ();
be00aaa8 5251 }
5252
5253 else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == UNSPEC)
5254 {
5255 switch (XINT (XEXP (addr, 0), 1))
5256 {
5257 case UNSPEC_INDNTPOFF:
8deb3959 5258 new_rtx = addr;
be00aaa8 5259 break;
5260
5261 default:
32eda510 5262 gcc_unreachable ();
be00aaa8 5263 }
5264 }
5265
b7ace65c 5266 else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == PLUS
5267 && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
5268 {
8deb3959 5269 new_rtx = XEXP (XEXP (addr, 0), 0);
5270 if (GET_CODE (new_rtx) != SYMBOL_REF)
5271 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
b7ace65c 5272
8deb3959 5273 new_rtx = legitimize_tls_address (new_rtx, reg);
29c05e22 5274 new_rtx = plus_constant (Pmode, new_rtx,
5275 INTVAL (XEXP (XEXP (addr, 0), 1)));
8deb3959 5276 new_rtx = force_operand (new_rtx, 0);
b7ace65c 5277 }
5278
be00aaa8 5279 else
32eda510 5280 gcc_unreachable (); /* for now ... */
be00aaa8 5281
8deb3959 5282 return new_rtx;
be00aaa8 5283}
5284
08b5e262 5285/* Emit insns making the address in operands[1] valid for a standard
5286 move to operands[0]. operands[1] is replaced by an address which
5287 should be used instead of the former RTX to emit the move
5288 pattern. */
4673c1a0 5289
5290void
b40da9a7 5291emit_symbolic_move (rtx *operands)
4673c1a0 5292{
e1ba4a27 5293 rtx temp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
4673c1a0 5294
be00aaa8 5295 if (GET_CODE (operands[0]) == MEM)
4673c1a0 5296 operands[1] = force_reg (Pmode, operands[1]);
be00aaa8 5297 else if (TLS_SYMBOLIC_CONST (operands[1]))
5298 operands[1] = legitimize_tls_address (operands[1], temp);
5299 else if (flag_pic)
4673c1a0 5300 operands[1] = legitimize_pic_address (operands[1], temp);
5301}
5302
56769981 5303/* Try machine-dependent ways of modifying an illegitimate address X
4673c1a0 5304 to be legitimate. If we find one, return the new, valid address.
4673c1a0 5305
5306 OLDX is the address as it was before break_out_memory_refs was called.
5307 In some cases it is useful to look at this to decide what needs to be done.
5308
56769981 5309 MODE is the mode of the operand pointed to by X.
4673c1a0 5310
5311 When -fpic is used, special handling is needed for symbolic references.
5312 See comments by legitimize_pic_address for details. */
5313
41e3a0c7 5314static rtx
5315s390_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
3754d046 5316 machine_mode mode ATTRIBUTE_UNUSED)
4673c1a0 5317{
2eb8fe23 5318 rtx constant_term = const0_rtx;
4673c1a0 5319
be00aaa8 5320 if (TLS_SYMBOLIC_CONST (x))
5321 {
5322 x = legitimize_tls_address (x, 0);
5323
fd50b071 5324 if (s390_legitimate_address_p (mode, x, FALSE))
be00aaa8 5325 return x;
5326 }
1ed004b7 5327 else if (GET_CODE (x) == PLUS
ffead1ca 5328 && (TLS_SYMBOLIC_CONST (XEXP (x, 0))
1ed004b7 5329 || TLS_SYMBOLIC_CONST (XEXP (x, 1))))
5330 {
5331 return x;
5332 }
be00aaa8 5333 else if (flag_pic)
4673c1a0 5334 {
2eb8fe23 5335 if (SYMBOLIC_CONST (x)
9f522e0c 5336 || (GET_CODE (x) == PLUS
5337 && (SYMBOLIC_CONST (XEXP (x, 0))
5338 || SYMBOLIC_CONST (XEXP (x, 1)))))
2eb8fe23 5339 x = legitimize_pic_address (x, 0);
5340
fd50b071 5341 if (s390_legitimate_address_p (mode, x, FALSE))
2eb8fe23 5342 return x;
4673c1a0 5343 }
4673c1a0 5344
2eb8fe23 5345 x = eliminate_constant_term (x, &constant_term);
56769981 5346
de84f805 5347 /* Optimize loading of large displacements by splitting them
5348 into the multiple of 4K and the rest; this allows the
f81e845f 5349 former to be CSE'd if possible.
de84f805 5350
5351 Don't do this if the displacement is added to a register
5352 pointing into the stack frame, as the offsets will
5353 change later anyway. */
5354
5355 if (GET_CODE (constant_term) == CONST_INT
51aa1e9c 5356 && !TARGET_LONG_DISPLACEMENT
5357 && !DISP_IN_RANGE (INTVAL (constant_term))
de84f805 5358 && !(REG_P (x) && REGNO_PTR_FRAME_P (REGNO (x))))
5359 {
5360 HOST_WIDE_INT lower = INTVAL (constant_term) & 0xfff;
5361 HOST_WIDE_INT upper = INTVAL (constant_term) ^ lower;
5362
5363 rtx temp = gen_reg_rtx (Pmode);
5364 rtx val = force_operand (GEN_INT (upper), temp);
5365 if (val != temp)
5366 emit_move_insn (temp, val);
5367
5368 x = gen_rtx_PLUS (Pmode, x, temp);
5369 constant_term = GEN_INT (lower);
5370 }
5371
2eb8fe23 5372 if (GET_CODE (x) == PLUS)
4673c1a0 5373 {
2eb8fe23 5374 if (GET_CODE (XEXP (x, 0)) == REG)
5375 {
edd89d66 5376 rtx temp = gen_reg_rtx (Pmode);
5377 rtx val = force_operand (XEXP (x, 1), temp);
2eb8fe23 5378 if (val != temp)
5379 emit_move_insn (temp, val);
5380
5381 x = gen_rtx_PLUS (Pmode, XEXP (x, 0), temp);
5382 }
5383
5384 else if (GET_CODE (XEXP (x, 1)) == REG)
5385 {
edd89d66 5386 rtx temp = gen_reg_rtx (Pmode);
5387 rtx val = force_operand (XEXP (x, 0), temp);
2eb8fe23 5388 if (val != temp)
5389 emit_move_insn (temp, val);
5390
5391 x = gen_rtx_PLUS (Pmode, temp, XEXP (x, 1));
5392 }
4673c1a0 5393 }
2eb8fe23 5394
5395 if (constant_term != const0_rtx)
5396 x = gen_rtx_PLUS (Pmode, x, constant_term);
5397
5398 return x;
4673c1a0 5399}
5400
e4542435 5401/* Try a machine-dependent way of reloading an illegitimate address AD
851d9296 5402 operand. If we find one, push the reload and return the new address.
e4542435 5403
5404 MODE is the mode of the enclosing MEM. OPNUM is the operand number
5405 and TYPE is the reload type of the current reload. */
5406
ffead1ca 5407rtx
3754d046 5408legitimize_reload_address (rtx ad, machine_mode mode ATTRIBUTE_UNUSED,
e4542435 5409 int opnum, int type)
5410{
5411 if (!optimize || TARGET_LONG_DISPLACEMENT)
5412 return NULL_RTX;
5413
5414 if (GET_CODE (ad) == PLUS)
5415 {
5416 rtx tem = simplify_binary_operation (PLUS, Pmode,
5417 XEXP (ad, 0), XEXP (ad, 1));
5418 if (tem)
5419 ad = tem;
5420 }
5421
5422 if (GET_CODE (ad) == PLUS
5423 && GET_CODE (XEXP (ad, 0)) == REG
5424 && GET_CODE (XEXP (ad, 1)) == CONST_INT
5425 && !DISP_IN_RANGE (INTVAL (XEXP (ad, 1))))
5426 {
5427 HOST_WIDE_INT lower = INTVAL (XEXP (ad, 1)) & 0xfff;
5428 HOST_WIDE_INT upper = INTVAL (XEXP (ad, 1)) ^ lower;
8deb3959 5429 rtx cst, tem, new_rtx;
e4542435 5430
5431 cst = GEN_INT (upper);
5432 if (!legitimate_reload_constant_p (cst))
5433 cst = force_const_mem (Pmode, cst);
5434
5435 tem = gen_rtx_PLUS (Pmode, XEXP (ad, 0), cst);
8deb3959 5436 new_rtx = gen_rtx_PLUS (Pmode, tem, GEN_INT (lower));
e4542435 5437
5438 push_reload (XEXP (tem, 1), 0, &XEXP (tem, 1), 0,
ffead1ca 5439 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
e4542435 5440 opnum, (enum reload_type) type);
8deb3959 5441 return new_rtx;
e4542435 5442 }
5443
5444 return NULL_RTX;
5445}
5446
4fbc4db5 5447/* Emit code to move LEN bytes from DST to SRC. */
5448
daa87e5a 5449bool
f135a8d4 5450s390_expand_cpymem (rtx dst, rtx src, rtx len)
4fbc4db5 5451{
daa87e5a 5452 /* When tuning for z10 or higher we rely on the Glibc functions to
5453 do the right thing. Only for constant lengths below 64k we will
5454 generate inline code. */
5455 if (s390_tune >= PROCESSOR_2097_Z10
5456 && (GET_CODE (len) != CONST_INT || INTVAL (len) > (1<<16)))
5457 return false;
5458
d044af2a 5459 /* Expand memcpy for constant length operands without a loop if it
5460 is shorter that way.
5461
5462 With a constant length argument a
5463 memcpy loop (without pfd) is 36 bytes -> 6 * mvc */
5464 if (GET_CODE (len) == CONST_INT
5465 && INTVAL (len) >= 0
5466 && INTVAL (len) <= 256 * 6
5467 && (!TARGET_MVCLE || INTVAL (len) <= 256))
4fbc4db5 5468 {
d044af2a 5469 HOST_WIDE_INT o, l;
5470
5471 for (l = INTVAL (len), o = 0; l > 0; l -= 256, o += 256)
5472 {
5473 rtx newdst = adjust_address (dst, BLKmode, o);
5474 rtx newsrc = adjust_address (src, BLKmode, o);
f135a8d4 5475 emit_insn (gen_cpymem_short (newdst, newsrc,
d044af2a 5476 GEN_INT (l > 256 ? 255 : l - 1)));
5477 }
4fbc4db5 5478 }
5479
5480 else if (TARGET_MVCLE)
5481 {
f135a8d4 5482 emit_insn (gen_cpymem_long (dst, src, convert_to_mode (Pmode, len, 1)));
4fbc4db5 5483 }
5484
5485 else
5486 {
5487 rtx dst_addr, src_addr, count, blocks, temp;
79f6a8ed 5488 rtx_code_label *loop_start_label = gen_label_rtx ();
5489 rtx_code_label *loop_end_label = gen_label_rtx ();
5490 rtx_code_label *end_label = gen_label_rtx ();
3754d046 5491 machine_mode mode;
4fbc4db5 5492
5493 mode = GET_MODE (len);
5494 if (mode == VOIDmode)
9f522e0c 5495 mode = Pmode;
4fbc4db5 5496
4fbc4db5 5497 dst_addr = gen_reg_rtx (Pmode);
5498 src_addr = gen_reg_rtx (Pmode);
5499 count = gen_reg_rtx (mode);
5500 blocks = gen_reg_rtx (mode);
5501
5502 convert_move (count, len, 1);
f81e845f 5503 emit_cmp_and_jump_insns (count, const0_rtx,
4fbc4db5 5504 EQ, NULL_RTX, mode, 1, end_label);
5505
5506 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
5507 emit_move_insn (src_addr, force_operand (XEXP (src, 0), NULL_RTX));
5508 dst = change_address (dst, VOIDmode, dst_addr);
5509 src = change_address (src, VOIDmode, src_addr);
f81e845f 5510
b9c74b4d 5511 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1,
5512 OPTAB_DIRECT);
4fbc4db5 5513 if (temp != count)
9f522e0c 5514 emit_move_insn (count, temp);
4fbc4db5 5515
b9c74b4d 5516 temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1,
5517 OPTAB_DIRECT);
4fbc4db5 5518 if (temp != blocks)
9f522e0c 5519 emit_move_insn (blocks, temp);
4fbc4db5 5520
4ee9c684 5521 emit_cmp_and_jump_insns (blocks, const0_rtx,
5522 EQ, NULL_RTX, mode, 1, loop_end_label);
7746964e 5523
5524 emit_label (loop_start_label);
4fbc4db5 5525
d5de7805 5526 if (TARGET_Z10
5527 && (GET_CODE (len) != CONST_INT || INTVAL (len) > 768))
5528 {
5529 rtx prefetch;
5530
5531 /* Issue a read prefetch for the +3 cache line. */
5532 prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, src_addr, GEN_INT (768)),
5533 const0_rtx, const0_rtx);
5534 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
5535 emit_insn (prefetch);
5536
5537 /* Issue a write prefetch for the +3 cache line. */
5538 prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (768)),
5539 const1_rtx, const0_rtx);
5540 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
5541 emit_insn (prefetch);
5542 }
5543
f135a8d4 5544 emit_insn (gen_cpymem_short (dst, src, GEN_INT (255)));
f81e845f 5545 s390_load_address (dst_addr,
4fbc4db5 5546 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
f81e845f 5547 s390_load_address (src_addr,
4fbc4db5 5548 gen_rtx_PLUS (Pmode, src_addr, GEN_INT (256)));
f81e845f 5549
b9c74b4d 5550 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1,
5551 OPTAB_DIRECT);
4fbc4db5 5552 if (temp != blocks)
9f522e0c 5553 emit_move_insn (blocks, temp);
4fbc4db5 5554
4ee9c684 5555 emit_cmp_and_jump_insns (blocks, const0_rtx,
5556 EQ, NULL_RTX, mode, 1, loop_end_label);
7746964e 5557
5558 emit_jump (loop_start_label);
4ee9c684 5559 emit_label (loop_end_label);
4fbc4db5 5560
f135a8d4 5561 emit_insn (gen_cpymem_short (dst, src,
31838f66 5562 convert_to_mode (Pmode, count, 1)));
4fbc4db5 5563 emit_label (end_label);
5564 }
daa87e5a 5565 return true;
4fbc4db5 5566}
5567
805a133b 5568/* Emit code to set LEN bytes at DST to VAL.
5569 Make use of clrmem if VAL is zero. */
4fbc4db5 5570
5571void
805a133b 5572s390_expand_setmem (rtx dst, rtx len, rtx val)
4fbc4db5 5573{
2b1d59f5 5574 if (GET_CODE (len) == CONST_INT && INTVAL (len) <= 0)
1ed6fd08 5575 return;
5576
805a133b 5577 gcc_assert (GET_CODE (val) == CONST_INT || GET_MODE (val) == QImode);
ffead1ca 5578
2b1d59f5 5579 /* Expand setmem/clrmem for a constant length operand without a
5580 loop if it will be shorter that way.
f7db343b 5581 clrmem loop (with PFD) is 30 bytes -> 5 * xc
5582 clrmem loop (without PFD) is 24 bytes -> 4 * xc
5583 setmem loop (with PFD) is 38 bytes -> ~4 * (mvi/stc + mvc)
5584 setmem loop (without PFD) is 32 bytes -> ~4 * (mvi/stc + mvc) */
2b1d59f5 5585 if (GET_CODE (len) == CONST_INT
f7db343b 5586 && ((val == const0_rtx
5587 && (INTVAL (len) <= 256 * 4
5588 || (INTVAL (len) <= 256 * 5 && TARGET_SETMEM_PFD(val,len))))
5589 || (val != const0_rtx && INTVAL (len) <= 257 * 4))
2b1d59f5 5590 && (!TARGET_MVCLE || INTVAL (len) <= 256))
4fbc4db5 5591 {
2b1d59f5 5592 HOST_WIDE_INT o, l;
ffead1ca 5593
2b1d59f5 5594 if (val == const0_rtx)
5595 /* clrmem: emit 256 byte blockwise XCs. */
5596 for (l = INTVAL (len), o = 0; l > 0; l -= 256, o += 256)
5597 {
5598 rtx newdst = adjust_address (dst, BLKmode, o);
5599 emit_insn (gen_clrmem_short (newdst,
5600 GEN_INT (l > 256 ? 255 : l - 1)));
5601 }
5602 else
5603 /* setmem: emit 1(mvi) + 256(mvc) byte blockwise memsets by
5604 setting first byte to val and using a 256 byte mvc with one
5605 byte overlap to propagate the byte. */
5606 for (l = INTVAL (len), o = 0; l > 0; l -= 257, o += 257)
5607 {
5608 rtx newdst = adjust_address (dst, BLKmode, o);
5609 emit_move_insn (adjust_address (dst, QImode, o), val);
5610 if (l > 1)
5611 {
5612 rtx newdstp1 = adjust_address (dst, BLKmode, o + 1);
f135a8d4 5613 emit_insn (gen_cpymem_short (newdstp1, newdst,
2b1d59f5 5614 GEN_INT (l > 257 ? 255 : l - 2)));
5615 }
5616 }
4fbc4db5 5617 }
5618
5619 else if (TARGET_MVCLE)
5620 {
805a133b 5621 val = force_not_mem (convert_modes (Pmode, QImode, val, 1));
00091884 5622 if (TARGET_64BIT)
5623 emit_insn (gen_setmem_long_di (dst, convert_to_mode (Pmode, len, 1),
5624 val));
5625 else
5626 emit_insn (gen_setmem_long_si (dst, convert_to_mode (Pmode, len, 1),
5627 val));
4fbc4db5 5628 }
5629
5630 else
5631 {
b5fdc416 5632 rtx dst_addr, count, blocks, temp, dstp1 = NULL_RTX;
79f6a8ed 5633 rtx_code_label *loop_start_label = gen_label_rtx ();
4b6f12fb 5634 rtx_code_label *onebyte_end_label = gen_label_rtx ();
5635 rtx_code_label *zerobyte_end_label = gen_label_rtx ();
5636 rtx_code_label *restbyte_end_label = gen_label_rtx ();
3754d046 5637 machine_mode mode;
4fbc4db5 5638
5639 mode = GET_MODE (len);
5640 if (mode == VOIDmode)
4b6f12fb 5641 mode = Pmode;
4fbc4db5 5642
4fbc4db5 5643 dst_addr = gen_reg_rtx (Pmode);
4fbc4db5 5644 count = gen_reg_rtx (mode);
5645 blocks = gen_reg_rtx (mode);
5646
5647 convert_move (count, len, 1);
f81e845f 5648 emit_cmp_and_jump_insns (count, const0_rtx,
4b6f12fb 5649 EQ, NULL_RTX, mode, 1, zerobyte_end_label,
6394f7ee 5650 profile_probability::very_unlikely ());
4fbc4db5 5651
4b6f12fb 5652 /* We need to make a copy of the target address since memset is
5653 supposed to return it unmodified. We have to make it here
5654 already since the new reg is used at onebyte_end_label. */
4fbc4db5 5655 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
5656 dst = change_address (dst, VOIDmode, dst_addr);
f81e845f 5657
4b6f12fb 5658 if (val != const0_rtx)
805a133b 5659 {
4b6f12fb 5660 /* When using the overlapping mvc the original target
5661 address is only accessed as single byte entity (even by
5662 the mvc reading this value). */
5b2a69fa 5663 set_mem_size (dst, 1);
4b6f12fb 5664 dstp1 = adjust_address (dst, VOIDmode, 1);
5665 emit_cmp_and_jump_insns (count,
5666 const1_rtx, EQ, NULL_RTX, mode, 1,
6394f7ee 5667 onebyte_end_label,
5668 profile_probability::very_unlikely ());
805a133b 5669 }
4b6f12fb 5670
5671 /* There is one unconditional (mvi+mvc)/xc after the loop
5672 dealing with the rest of the bytes, subtracting two (mvi+mvc)
5673 or one (xc) here leaves this number of bytes to be handled by
5674 it. */
5675 temp = expand_binop (mode, add_optab, count,
5676 val == const0_rtx ? constm1_rtx : GEN_INT (-2),
5677 count, 1, OPTAB_DIRECT);
4fbc4db5 5678 if (temp != count)
4b6f12fb 5679 emit_move_insn (count, temp);
4fbc4db5 5680
b9c74b4d 5681 temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1,
5682 OPTAB_DIRECT);
4fbc4db5 5683 if (temp != blocks)
4b6f12fb 5684 emit_move_insn (blocks, temp);
4fbc4db5 5685
4ee9c684 5686 emit_cmp_and_jump_insns (blocks, const0_rtx,
4b6f12fb 5687 EQ, NULL_RTX, mode, 1, restbyte_end_label);
5688
5689 emit_jump (loop_start_label);
5690
5691 if (val != const0_rtx)
5692 {
5693 /* The 1 byte != 0 special case. Not handled efficiently
5694 since we require two jumps for that. However, this
5695 should be very rare. */
5696 emit_label (onebyte_end_label);
5697 emit_move_insn (adjust_address (dst, QImode, 0), val);
5698 emit_jump (zerobyte_end_label);
5699 }
7746964e 5700
5701 emit_label (loop_start_label);
4fbc4db5 5702
f7db343b 5703 if (TARGET_SETMEM_PFD (val, len))
d5de7805 5704 {
f7db343b 5705 /* Issue a write prefetch. */
5706 rtx distance = GEN_INT (TARGET_SETMEM_PREFETCH_DISTANCE);
5707 rtx prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, dst_addr, distance),
d5de7805 5708 const1_rtx, const0_rtx);
5709 emit_insn (prefetch);
5710 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
5711 }
5712
805a133b 5713 if (val == const0_rtx)
5714 emit_insn (gen_clrmem_short (dst, GEN_INT (255)));
5715 else
4b6f12fb 5716 {
5717 /* Set the first byte in the block to the value and use an
5718 overlapping mvc for the block. */
5719 emit_move_insn (adjust_address (dst, QImode, 0), val);
f135a8d4 5720 emit_insn (gen_cpymem_short (dstp1, dst, GEN_INT (254)));
4b6f12fb 5721 }
f81e845f 5722 s390_load_address (dst_addr,
4fbc4db5 5723 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
f81e845f 5724
b9c74b4d 5725 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1,
5726 OPTAB_DIRECT);
4fbc4db5 5727 if (temp != blocks)
4b6f12fb 5728 emit_move_insn (blocks, temp);
4fbc4db5 5729
4ee9c684 5730 emit_cmp_and_jump_insns (blocks, const0_rtx,
4b6f12fb 5731 NE, NULL_RTX, mode, 1, loop_start_label);
7746964e 5732
4b6f12fb 5733 emit_label (restbyte_end_label);
4fbc4db5 5734
805a133b 5735 if (val == const0_rtx)
4b6f12fb 5736 emit_insn (gen_clrmem_short (dst, convert_to_mode (Pmode, count, 1)));
805a133b 5737 else
4b6f12fb 5738 {
5739 /* Set the first byte in the block to the value and use an
5740 overlapping mvc for the block. */
5741 emit_move_insn (adjust_address (dst, QImode, 0), val);
5742 /* execute only uses the lowest 8 bits of count that's
5743 exactly what we need here. */
f135a8d4 5744 emit_insn (gen_cpymem_short (dstp1, dst,
4b6f12fb 5745 convert_to_mode (Pmode, count, 1)));
5746 }
5747
5748 emit_label (zerobyte_end_label);
4fbc4db5 5749 }
5750}
5751
5752/* Emit code to compare LEN bytes at OP0 with those at OP1,
5753 and return the result in TARGET. */
5754
daa87e5a 5755bool
b40da9a7 5756s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
4fbc4db5 5757{
80b53886 5758 rtx ccreg = gen_rtx_REG (CCUmode, CC_REGNUM);
dd16a4bd 5759 rtx tmp;
5760
daa87e5a 5761 /* When tuning for z10 or higher we rely on the Glibc functions to
5762 do the right thing. Only for constant lengths below 64k we will
5763 generate inline code. */
5764 if (s390_tune >= PROCESSOR_2097_Z10
5765 && (GET_CODE (len) != CONST_INT || INTVAL (len) > (1<<16)))
5766 return false;
5767
dd16a4bd 5768 /* As the result of CMPINT is inverted compared to what we need,
5769 we have to swap the operands. */
5770 tmp = op0; op0 = op1; op1 = tmp;
4fbc4db5 5771
4fbc4db5 5772 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
5773 {
5774 if (INTVAL (len) > 0)
9f522e0c 5775 {
5776 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (INTVAL (len) - 1)));
5777 emit_insn (gen_cmpint (target, ccreg));
5778 }
4fbc4db5 5779 else
9f522e0c 5780 emit_move_insn (target, const0_rtx);
4fbc4db5 5781 }
bcbf02a5 5782 else if (TARGET_MVCLE)
4fbc4db5 5783 {
31838f66 5784 emit_insn (gen_cmpmem_long (op0, op1, convert_to_mode (Pmode, len, 1)));
dd16a4bd 5785 emit_insn (gen_cmpint (target, ccreg));
4fbc4db5 5786 }
4fbc4db5 5787 else
5788 {
5789 rtx addr0, addr1, count, blocks, temp;
79f6a8ed 5790 rtx_code_label *loop_start_label = gen_label_rtx ();
5791 rtx_code_label *loop_end_label = gen_label_rtx ();
5792 rtx_code_label *end_label = gen_label_rtx ();
3754d046 5793 machine_mode mode;
4fbc4db5 5794
5795 mode = GET_MODE (len);
5796 if (mode == VOIDmode)
9f522e0c 5797 mode = Pmode;
4fbc4db5 5798
4fbc4db5 5799 addr0 = gen_reg_rtx (Pmode);
5800 addr1 = gen_reg_rtx (Pmode);
5801 count = gen_reg_rtx (mode);
5802 blocks = gen_reg_rtx (mode);
5803
5804 convert_move (count, len, 1);
f81e845f 5805 emit_cmp_and_jump_insns (count, const0_rtx,
4fbc4db5 5806 EQ, NULL_RTX, mode, 1, end_label);
5807
5808 emit_move_insn (addr0, force_operand (XEXP (op0, 0), NULL_RTX));
5809 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
5810 op0 = change_address (op0, VOIDmode, addr0);
5811 op1 = change_address (op1, VOIDmode, addr1);
f81e845f 5812
b9c74b4d 5813 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1,
5814 OPTAB_DIRECT);
4fbc4db5 5815 if (temp != count)
9f522e0c 5816 emit_move_insn (count, temp);
4fbc4db5 5817
b9c74b4d 5818 temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1,
5819 OPTAB_DIRECT);
4fbc4db5 5820 if (temp != blocks)
9f522e0c 5821 emit_move_insn (blocks, temp);
4fbc4db5 5822
4ee9c684 5823 emit_cmp_and_jump_insns (blocks, const0_rtx,
5824 EQ, NULL_RTX, mode, 1, loop_end_label);
7746964e 5825
5826 emit_label (loop_start_label);
4fbc4db5 5827
d5de7805 5828 if (TARGET_Z10
5829 && (GET_CODE (len) != CONST_INT || INTVAL (len) > 512))
5830 {
5831 rtx prefetch;
5832
5833 /* Issue a read prefetch for the +2 cache line of operand 1. */
5834 prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, addr0, GEN_INT (512)),
5835 const0_rtx, const0_rtx);
5836 emit_insn (prefetch);
5837 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
5838
5839 /* Issue a read prefetch for the +2 cache line of operand 2. */
5840 prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, addr1, GEN_INT (512)),
5841 const0_rtx, const0_rtx);
5842 emit_insn (prefetch);
5843 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
5844 }
5845
31838f66 5846 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (255)));
80b53886 5847 temp = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
f81e845f 5848 temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
4fbc4db5 5849 gen_rtx_LABEL_REF (VOIDmode, end_label), pc_rtx);
d1f9b275 5850 temp = gen_rtx_SET (pc_rtx, temp);
4fbc4db5 5851 emit_jump_insn (temp);
5852
f81e845f 5853 s390_load_address (addr0,
4fbc4db5 5854 gen_rtx_PLUS (Pmode, addr0, GEN_INT (256)));
f81e845f 5855 s390_load_address (addr1,
4fbc4db5 5856 gen_rtx_PLUS (Pmode, addr1, GEN_INT (256)));
f81e845f 5857
b9c74b4d 5858 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1,
5859 OPTAB_DIRECT);
4fbc4db5 5860 if (temp != blocks)
9f522e0c 5861 emit_move_insn (blocks, temp);
4fbc4db5 5862
4ee9c684 5863 emit_cmp_and_jump_insns (blocks, const0_rtx,
5864 EQ, NULL_RTX, mode, 1, loop_end_label);
7746964e 5865
5866 emit_jump (loop_start_label);
4ee9c684 5867 emit_label (loop_end_label);
4fbc4db5 5868
f588eb9f 5869 emit_insn (gen_cmpmem_short (op0, op1,
31838f66 5870 convert_to_mode (Pmode, count, 1)));
4fbc4db5 5871 emit_label (end_label);
5872
dd16a4bd 5873 emit_insn (gen_cmpint (target, ccreg));
4fbc4db5 5874 }
daa87e5a 5875 return true;
4fbc4db5 5876}
5877
76a4c804 5878/* Emit a conditional jump to LABEL for condition code mask MASK using
5879 comparsion operator COMPARISON. Return the emitted jump insn. */
5880
26cd1198 5881static rtx_insn *
76a4c804 5882s390_emit_ccraw_jump (HOST_WIDE_INT mask, enum rtx_code comparison, rtx label)
5883{
5884 rtx temp;
5885
5886 gcc_assert (comparison == EQ || comparison == NE);
5887 gcc_assert (mask > 0 && mask < 15);
5888
5889 temp = gen_rtx_fmt_ee (comparison, VOIDmode,
5890 gen_rtx_REG (CCRAWmode, CC_REGNUM), GEN_INT (mask));
5891 temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
5892 gen_rtx_LABEL_REF (VOIDmode, label), pc_rtx);
5893 temp = gen_rtx_SET (pc_rtx, temp);
5894 return emit_jump_insn (temp);
5895}
5896
5897/* Emit the instructions to implement strlen of STRING and store the
5898 result in TARGET. The string has the known ALIGNMENT. This
5899 version uses vector instructions and is therefore not appropriate
5900 for targets prior to z13. */
5901
5902void
5903s390_expand_vec_strlen (rtx target, rtx string, rtx alignment)
5904{
76a4c804 5905 rtx highest_index_to_load_reg = gen_reg_rtx (Pmode);
5906 rtx str_reg = gen_reg_rtx (V16QImode);
5907 rtx str_addr_base_reg = gen_reg_rtx (Pmode);
5908 rtx str_idx_reg = gen_reg_rtx (Pmode);
5909 rtx result_reg = gen_reg_rtx (V16QImode);
5910 rtx is_aligned_label = gen_label_rtx ();
5911 rtx into_loop_label = NULL_RTX;
5912 rtx loop_start_label = gen_label_rtx ();
5913 rtx temp;
5914 rtx len = gen_reg_rtx (QImode);
5915 rtx cond;
5916
5917 s390_load_address (str_addr_base_reg, XEXP (string, 0));
5918 emit_move_insn (str_idx_reg, const0_rtx);
5919
5920 if (INTVAL (alignment) < 16)
5921 {
5922 /* Check whether the address happens to be aligned properly so
5923 jump directly to the aligned loop. */
5924 emit_cmp_and_jump_insns (gen_rtx_AND (Pmode,
5925 str_addr_base_reg, GEN_INT (15)),
5926 const0_rtx, EQ, NULL_RTX,
5927 Pmode, 1, is_aligned_label);
5928
5929 temp = gen_reg_rtx (Pmode);
5930 temp = expand_binop (Pmode, and_optab, str_addr_base_reg,
5931 GEN_INT (15), temp, 1, OPTAB_DIRECT);
5932 gcc_assert (REG_P (temp));
5933 highest_index_to_load_reg =
5934 expand_binop (Pmode, sub_optab, GEN_INT (15), temp,
5935 highest_index_to_load_reg, 1, OPTAB_DIRECT);
5936 gcc_assert (REG_P (highest_index_to_load_reg));
5937 emit_insn (gen_vllv16qi (str_reg,
5938 convert_to_mode (SImode, highest_index_to_load_reg, 1),
5939 gen_rtx_MEM (BLKmode, str_addr_base_reg)));
5940
5941 into_loop_label = gen_label_rtx ();
5942 s390_emit_jump (into_loop_label, NULL_RTX);
5943 emit_barrier ();
5944 }
5945
5946 emit_label (is_aligned_label);
5947 LABEL_NUSES (is_aligned_label) = INTVAL (alignment) < 16 ? 2 : 1;
5948
5949 /* Reaching this point we are only performing 16 bytes aligned
5950 loads. */
5951 emit_move_insn (highest_index_to_load_reg, GEN_INT (15));
5952
5953 emit_label (loop_start_label);
5954 LABEL_NUSES (loop_start_label) = 1;
5955
5956 /* Load 16 bytes of the string into VR. */
5957 emit_move_insn (str_reg,
5958 gen_rtx_MEM (V16QImode,
5959 gen_rtx_PLUS (Pmode, str_idx_reg,
5960 str_addr_base_reg)));
5961 if (into_loop_label != NULL_RTX)
5962 {
5963 emit_label (into_loop_label);
5964 LABEL_NUSES (into_loop_label) = 1;
5965 }
5966
5967 /* Increment string index by 16 bytes. */
5968 expand_binop (Pmode, add_optab, str_idx_reg, GEN_INT (16),
5969 str_idx_reg, 1, OPTAB_DIRECT);
5970
5971 emit_insn (gen_vec_vfenesv16qi (result_reg, str_reg, str_reg,
5972 GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS)));
5973
5974 add_int_reg_note (s390_emit_ccraw_jump (8, NE, loop_start_label),
61cb1816 5975 REG_BR_PROB,
5976 profile_probability::very_likely ().to_reg_br_prob_note ());
447443f5 5977 emit_insn (gen_vec_extractv16qiqi (len, result_reg, GEN_INT (7)));
76a4c804 5978
5979 /* If the string pointer wasn't aligned we have loaded less then 16
5980 bytes and the remaining bytes got filled with zeros (by vll).
5981 Now we have to check whether the resulting index lies within the
5982 bytes actually part of the string. */
5983
5984 cond = s390_emit_compare (GT, convert_to_mode (Pmode, len, 1),
5985 highest_index_to_load_reg);
5986 s390_load_address (highest_index_to_load_reg,
5987 gen_rtx_PLUS (Pmode, highest_index_to_load_reg,
5988 const1_rtx));
5989 if (TARGET_64BIT)
5990 emit_insn (gen_movdicc (str_idx_reg, cond,
5991 highest_index_to_load_reg, str_idx_reg));
5992 else
5993 emit_insn (gen_movsicc (str_idx_reg, cond,
5994 highest_index_to_load_reg, str_idx_reg));
5995
61cb1816 5996 add_reg_br_prob_note (s390_emit_jump (is_aligned_label, cond),
9f522e0c 5997 profile_probability::very_unlikely ());
76a4c804 5998
5999 expand_binop (Pmode, add_optab, str_idx_reg,
6000 GEN_INT (-16), str_idx_reg, 1, OPTAB_DIRECT);
6001 /* FIXME: len is already zero extended - so avoid the llgcr emitted
6002 here. */
6003 temp = expand_binop (Pmode, add_optab, str_idx_reg,
6004 convert_to_mode (Pmode, len, 1),
6005 target, 1, OPTAB_DIRECT);
6006 if (temp != target)
6007 emit_move_insn (target, temp);
6008}
3b699fc7 6009
664ff6a0 6010void
6011s390_expand_vec_movstr (rtx result, rtx dst, rtx src)
6012{
664ff6a0 6013 rtx temp = gen_reg_rtx (Pmode);
6014 rtx src_addr = XEXP (src, 0);
6015 rtx dst_addr = XEXP (dst, 0);
6016 rtx src_addr_reg = gen_reg_rtx (Pmode);
6017 rtx dst_addr_reg = gen_reg_rtx (Pmode);
6018 rtx offset = gen_reg_rtx (Pmode);
6019 rtx vsrc = gen_reg_rtx (V16QImode);
6020 rtx vpos = gen_reg_rtx (V16QImode);
6021 rtx loadlen = gen_reg_rtx (SImode);
6022 rtx gpos_qi = gen_reg_rtx(QImode);
6023 rtx gpos = gen_reg_rtx (SImode);
6024 rtx done_label = gen_label_rtx ();
6025 rtx loop_label = gen_label_rtx ();
6026 rtx exit_label = gen_label_rtx ();
6027 rtx full_label = gen_label_rtx ();
6028
6029 /* Perform a quick check for string ending on the first up to 16
6030 bytes and exit early if successful. */
6031
6032 emit_insn (gen_vlbb (vsrc, src, GEN_INT (6)));
6033 emit_insn (gen_lcbb (loadlen, src_addr, GEN_INT (6)));
6034 emit_insn (gen_vfenezv16qi (vpos, vsrc, vsrc));
447443f5 6035 emit_insn (gen_vec_extractv16qiqi (gpos_qi, vpos, GEN_INT (7)));
664ff6a0 6036 emit_move_insn (gpos, gen_rtx_SUBREG (SImode, gpos_qi, 0));
6037 /* gpos is the byte index if a zero was found and 16 otherwise.
6038 So if it is lower than the loaded bytes we have a hit. */
6039 emit_cmp_and_jump_insns (gpos, loadlen, GE, NULL_RTX, SImode, 1,
6040 full_label);
6041 emit_insn (gen_vstlv16qi (vsrc, gpos, dst));
6042
6043 force_expand_binop (Pmode, add_optab, dst_addr, gpos, result,
6044 1, OPTAB_DIRECT);
6045 emit_jump (exit_label);
6046 emit_barrier ();
6047
6048 emit_label (full_label);
6049 LABEL_NUSES (full_label) = 1;
6050
6051 /* Calculate `offset' so that src + offset points to the last byte
6052 before 16 byte alignment. */
6053
6054 /* temp = src_addr & 0xf */
6055 force_expand_binop (Pmode, and_optab, src_addr, GEN_INT (15), temp,
6056 1, OPTAB_DIRECT);
6057
6058 /* offset = 0xf - temp */
6059 emit_move_insn (offset, GEN_INT (15));
6060 force_expand_binop (Pmode, sub_optab, offset, temp, offset,
6061 1, OPTAB_DIRECT);
6062
6063 /* Store `offset' bytes in the dstination string. The quick check
6064 has loaded at least `offset' bytes into vsrc. */
6065
6066 emit_insn (gen_vstlv16qi (vsrc, gen_lowpart (SImode, offset), dst));
6067
6068 /* Advance to the next byte to be loaded. */
6069 force_expand_binop (Pmode, add_optab, offset, const1_rtx, offset,
6070 1, OPTAB_DIRECT);
6071
6072 /* Make sure the addresses are single regs which can be used as a
6073 base. */
6074 emit_move_insn (src_addr_reg, src_addr);
6075 emit_move_insn (dst_addr_reg, dst_addr);
6076
6077 /* MAIN LOOP */
6078
6079 emit_label (loop_label);
6080 LABEL_NUSES (loop_label) = 1;
6081
6082 emit_move_insn (vsrc,
6083 gen_rtx_MEM (V16QImode,
6084 gen_rtx_PLUS (Pmode, src_addr_reg, offset)));
6085
6086 emit_insn (gen_vec_vfenesv16qi (vpos, vsrc, vsrc,
6087 GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS)));
6088 add_int_reg_note (s390_emit_ccraw_jump (8, EQ, done_label),
61cb1816 6089 REG_BR_PROB, profile_probability::very_unlikely ()
6090 .to_reg_br_prob_note ());
664ff6a0 6091
6092 emit_move_insn (gen_rtx_MEM (V16QImode,
6093 gen_rtx_PLUS (Pmode, dst_addr_reg, offset)),
6094 vsrc);
6095 /* offset += 16 */
6096 force_expand_binop (Pmode, add_optab, offset, GEN_INT (16),
6097 offset, 1, OPTAB_DIRECT);
6098
6099 emit_jump (loop_label);
6100 emit_barrier ();
6101
6102 /* REGULAR EXIT */
6103
6104 /* We are done. Add the offset of the zero character to the dst_addr
6105 pointer to get the result. */
6106
6107 emit_label (done_label);
6108 LABEL_NUSES (done_label) = 1;
6109
6110 force_expand_binop (Pmode, add_optab, dst_addr_reg, offset, dst_addr_reg,
6111 1, OPTAB_DIRECT);
6112
447443f5 6113 emit_insn (gen_vec_extractv16qiqi (gpos_qi, vpos, GEN_INT (7)));
664ff6a0 6114 emit_move_insn (gpos, gen_rtx_SUBREG (SImode, gpos_qi, 0));
6115
6116 emit_insn (gen_vstlv16qi (vsrc, gpos, gen_rtx_MEM (BLKmode, dst_addr_reg)));
6117
6118 force_expand_binop (Pmode, add_optab, dst_addr_reg, gpos, result,
6119 1, OPTAB_DIRECT);
6120
6121 /* EARLY EXIT */
6122
6123 emit_label (exit_label);
6124 LABEL_NUSES (exit_label) = 1;
6125}
6126
6127
3b699fc7 6128/* Expand conditional increment or decrement using alc/slb instructions.
6129 Should generate code setting DST to either SRC or SRC + INCREMENT,
6130 depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
eeba5f25 6131 Returns true if successful, false otherwise.
6132
6133 That makes it possible to implement some if-constructs without jumps e.g.:
6134 (borrow = CC0 | CC1 and carry = CC2 | CC3)
6135 unsigned int a, b, c;
6136 if (a < b) c++; -> CCU b > a -> CC2; c += carry;
6137 if (a < b) c--; -> CCL3 a - b -> borrow; c -= borrow;
6138 if (a <= b) c++; -> CCL3 b - a -> borrow; c += carry;
6139 if (a <= b) c--; -> CCU a <= b -> borrow; c -= borrow;
6140
6141 Checks for EQ and NE with a nonzero value need an additional xor e.g.:
6142 if (a == b) c++; -> CCL3 a ^= b; 0 - a -> borrow; c += carry;
6143 if (a == b) c--; -> CCU a ^= b; a <= 0 -> CC0 | CC1; c -= borrow;
6144 if (a != b) c++; -> CCU a ^= b; a > 0 -> CC2; c += carry;
6145 if (a != b) c--; -> CCL3 a ^= b; 0 - a -> borrow; c -= borrow; */
3b699fc7 6146
6147bool
6148s390_expand_addcc (enum rtx_code cmp_code, rtx cmp_op0, rtx cmp_op1,
6149 rtx dst, rtx src, rtx increment)
6150{
3754d046 6151 machine_mode cmp_mode;
6152 machine_mode cc_mode;
3b699fc7 6153 rtx op_res;
6154 rtx insn;
6155 rtvec p;
32eda510 6156 int ret;
3b699fc7 6157
6158 if ((GET_MODE (cmp_op0) == SImode || GET_MODE (cmp_op0) == VOIDmode)
6159 && (GET_MODE (cmp_op1) == SImode || GET_MODE (cmp_op1) == VOIDmode))
6160 cmp_mode = SImode;
6161 else if ((GET_MODE (cmp_op0) == DImode || GET_MODE (cmp_op0) == VOIDmode)
6162 && (GET_MODE (cmp_op1) == DImode || GET_MODE (cmp_op1) == VOIDmode))
6163 cmp_mode = DImode;
6164 else
6165 return false;
6166
6167 /* Try ADD LOGICAL WITH CARRY. */
6168 if (increment == const1_rtx)
6169 {
6170 /* Determine CC mode to use. */
6171 if (cmp_code == EQ || cmp_code == NE)
6172 {
6173 if (cmp_op1 != const0_rtx)
6174 {
6175 cmp_op0 = expand_simple_binop (cmp_mode, XOR, cmp_op0, cmp_op1,
6176 NULL_RTX, 0, OPTAB_WIDEN);
6177 cmp_op1 = const0_rtx;
6178 }
6179
6180 cmp_code = cmp_code == EQ ? LEU : GTU;
6181 }
6182
6183 if (cmp_code == LTU || cmp_code == LEU)
6184 {
6185 rtx tem = cmp_op0;
6186 cmp_op0 = cmp_op1;
6187 cmp_op1 = tem;
6188 cmp_code = swap_condition (cmp_code);
6189 }
6190
6191 switch (cmp_code)
6192 {
6193 case GTU:
6194 cc_mode = CCUmode;
6195 break;
6196
6197 case GEU:
6198 cc_mode = CCL3mode;
6199 break;
6200
6201 default:
6202 return false;
6203 }
6204
6205 /* Emit comparison instruction pattern. */
6206 if (!register_operand (cmp_op0, cmp_mode))
6207 cmp_op0 = force_reg (cmp_mode, cmp_op0);
6208
d1f9b275 6209 insn = gen_rtx_SET (gen_rtx_REG (cc_mode, CC_REGNUM),
3b699fc7 6210 gen_rtx_COMPARE (cc_mode, cmp_op0, cmp_op1));
6211 /* We use insn_invalid_p here to add clobbers if required. */
dae9d0e7 6212 ret = insn_invalid_p (emit_insn (insn), false);
32eda510 6213 gcc_assert (!ret);
3b699fc7 6214
6215 /* Emit ALC instruction pattern. */
6216 op_res = gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
6217 gen_rtx_REG (cc_mode, CC_REGNUM),
6218 const0_rtx);
6219
6220 if (src != const0_rtx)
6221 {
6222 if (!register_operand (src, GET_MODE (dst)))
6223 src = force_reg (GET_MODE (dst), src);
6224
6f4afa7e 6225 op_res = gen_rtx_PLUS (GET_MODE (dst), op_res, src);
6226 op_res = gen_rtx_PLUS (GET_MODE (dst), op_res, const0_rtx);
3b699fc7 6227 }
6228
6229 p = rtvec_alloc (2);
ffead1ca 6230 RTVEC_ELT (p, 0) =
9f522e0c 6231 gen_rtx_SET (dst, op_res);
ffead1ca 6232 RTVEC_ELT (p, 1) =
3b699fc7 6233 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
6234 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
6235
6236 return true;
6237 }
6238
6239 /* Try SUBTRACT LOGICAL WITH BORROW. */
6240 if (increment == constm1_rtx)
6241 {
6242 /* Determine CC mode to use. */
6243 if (cmp_code == EQ || cmp_code == NE)
6244 {
6245 if (cmp_op1 != const0_rtx)
6246 {
6247 cmp_op0 = expand_simple_binop (cmp_mode, XOR, cmp_op0, cmp_op1,
6248 NULL_RTX, 0, OPTAB_WIDEN);
6249 cmp_op1 = const0_rtx;
6250 }
6251
6252 cmp_code = cmp_code == EQ ? LEU : GTU;
6253 }
6254
6255 if (cmp_code == GTU || cmp_code == GEU)
6256 {
6257 rtx tem = cmp_op0;
6258 cmp_op0 = cmp_op1;
6259 cmp_op1 = tem;
6260 cmp_code = swap_condition (cmp_code);
6261 }
6262
6263 switch (cmp_code)
6264 {
6265 case LEU:
6266 cc_mode = CCUmode;
6267 break;
6268
6269 case LTU:
6270 cc_mode = CCL3mode;
6271 break;
6272
6273 default:
6274 return false;
6275 }
6276
6277 /* Emit comparison instruction pattern. */
6278 if (!register_operand (cmp_op0, cmp_mode))
6279 cmp_op0 = force_reg (cmp_mode, cmp_op0);
6280
d1f9b275 6281 insn = gen_rtx_SET (gen_rtx_REG (cc_mode, CC_REGNUM),
3b699fc7 6282 gen_rtx_COMPARE (cc_mode, cmp_op0, cmp_op1));
6283 /* We use insn_invalid_p here to add clobbers if required. */
dae9d0e7 6284 ret = insn_invalid_p (emit_insn (insn), false);
32eda510 6285 gcc_assert (!ret);
3b699fc7 6286
6287 /* Emit SLB instruction pattern. */
6288 if (!register_operand (src, GET_MODE (dst)))
6289 src = force_reg (GET_MODE (dst), src);
6290
ffead1ca 6291 op_res = gen_rtx_MINUS (GET_MODE (dst),
6292 gen_rtx_MINUS (GET_MODE (dst), src, const0_rtx),
6293 gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
6294 gen_rtx_REG (cc_mode, CC_REGNUM),
3b699fc7 6295 const0_rtx));
6296 p = rtvec_alloc (2);
ffead1ca 6297 RTVEC_ELT (p, 0) =
9f522e0c 6298 gen_rtx_SET (dst, op_res);
ffead1ca 6299 RTVEC_ELT (p, 1) =
3b699fc7 6300 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
6301 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
6302
6303 return true;
6304 }
6305
6306 return false;
6307}
6308
e68d6a13 6309/* Expand code for the insv template. Return true if successful. */
0349cc73 6310
e68d6a13 6311bool
0349cc73 6312s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src)
6313{
6314 int bitsize = INTVAL (op1);
6315 int bitpos = INTVAL (op2);
3754d046 6316 machine_mode mode = GET_MODE (dest);
6317 machine_mode smode;
8c753480 6318 int smode_bsize, mode_bsize;
6319 rtx op, clobber;
0349cc73 6320
0bc377b9 6321 if (bitsize + bitpos > GET_MODE_BITSIZE (mode))
31efd1ec 6322 return false;
6323
8c753480 6324 /* Generate INSERT IMMEDIATE (IILL et al). */
6325 /* (set (ze (reg)) (const_int)). */
6326 if (TARGET_ZARCH
6327 && register_operand (dest, word_mode)
6328 && (bitpos % 16) == 0
6329 && (bitsize % 16) == 0
6330 && const_int_operand (src, VOIDmode))
e68d6a13 6331 {
8c753480 6332 HOST_WIDE_INT val = INTVAL (src);
6333 int regpos = bitpos + bitsize;
e68d6a13 6334
8c753480 6335 while (regpos > bitpos)
6336 {
3754d046 6337 machine_mode putmode;
8c753480 6338 int putsize;
6339
6340 if (TARGET_EXTIMM && (regpos % 32 == 0) && (regpos >= bitpos + 32))
6341 putmode = SImode;
6342 else
6343 putmode = HImode;
e68d6a13 6344
8c753480 6345 putsize = GET_MODE_BITSIZE (putmode);
6346 regpos -= putsize;
6347 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest,
6348 GEN_INT (putsize),
6349 GEN_INT (regpos)),
6350 gen_int_mode (val, putmode));
6351 val >>= putsize;
6352 }
6353 gcc_assert (regpos == bitpos);
e68d6a13 6354 return true;
6355 }
6356
1a5d4b27 6357 smode = smallest_int_mode_for_size (bitsize);
8c753480 6358 smode_bsize = GET_MODE_BITSIZE (smode);
6359 mode_bsize = GET_MODE_BITSIZE (mode);
0349cc73 6360
8c753480 6361 /* Generate STORE CHARACTERS UNDER MASK (STCM et al). */
0349cc73 6362 if (bitpos == 0
8c753480 6363 && (bitsize % BITS_PER_UNIT) == 0
6364 && MEM_P (dest)
0349cc73 6365 && (register_operand (src, word_mode)
6366 || const_int_operand (src, VOIDmode)))
6367 {
6368 /* Emit standard pattern if possible. */
8c753480 6369 if (smode_bsize == bitsize)
6370 {
6371 emit_move_insn (adjust_address (dest, smode, 0),
6372 gen_lowpart (smode, src));
6373 return true;
6374 }
0349cc73 6375
6376 /* (set (ze (mem)) (const_int)). */
6377 else if (const_int_operand (src, VOIDmode))
6378 {
6379 int size = bitsize / BITS_PER_UNIT;
8c753480 6380 rtx src_mem = adjust_address (force_const_mem (word_mode, src),
6381 BLKmode,
6382 UNITS_PER_WORD - size);
0349cc73 6383
6384 dest = adjust_address (dest, BLKmode, 0);
5b2a69fa 6385 set_mem_size (dest, size);
f135a8d4 6386 s390_expand_cpymem (dest, src_mem, GEN_INT (size));
8c753480 6387 return true;
0349cc73 6388 }
ffead1ca 6389
0349cc73 6390 /* (set (ze (mem)) (reg)). */
6391 else if (register_operand (src, word_mode))
6392 {
8c753480 6393 if (bitsize <= 32)
0349cc73 6394 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest, op1,
6395 const0_rtx), src);
6396 else
6397 {
6398 /* Emit st,stcmh sequence. */
8c753480 6399 int stcmh_width = bitsize - 32;
0349cc73 6400 int size = stcmh_width / BITS_PER_UNIT;
6401
ffead1ca 6402 emit_move_insn (adjust_address (dest, SImode, size),
0349cc73 6403 gen_lowpart (SImode, src));
5b2a69fa 6404 set_mem_size (dest, size);
8c753480 6405 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest,
6406 GEN_INT (stcmh_width),
6407 const0_rtx),
6408 gen_rtx_LSHIFTRT (word_mode, src, GEN_INT (32)));
0349cc73 6409 }
8c753480 6410 return true;
0349cc73 6411 }
8c753480 6412 }
0349cc73 6413
8c753480 6414 /* Generate INSERT CHARACTERS UNDER MASK (IC, ICM et al). */
6415 if ((bitpos % BITS_PER_UNIT) == 0
6416 && (bitsize % BITS_PER_UNIT) == 0
6417 && (bitpos & 32) == ((bitpos + bitsize - 1) & 32)
6418 && MEM_P (src)
6419 && (mode == DImode || mode == SImode)
6420 && register_operand (dest, mode))
6421 {
6422 /* Emit a strict_low_part pattern if possible. */
6423 if (smode_bsize == bitsize && bitpos == mode_bsize - smode_bsize)
6424 {
6425 op = gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (smode, dest));
d1f9b275 6426 op = gen_rtx_SET (op, gen_lowpart (smode, src));
8c753480 6427 clobber = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
6428 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clobber)));
6429 return true;
6430 }
6431
6432 /* ??? There are more powerful versions of ICM that are not
6433 completely represented in the md file. */
0349cc73 6434 }
6435
8c753480 6436 /* For z10, generate ROTATE THEN INSERT SELECTED BITS (RISBG et al). */
6437 if (TARGET_Z10 && (mode == DImode || mode == SImode))
0349cc73 6438 {
3754d046 6439 machine_mode mode_s = GET_MODE (src);
0349cc73 6440
678c417b 6441 if (CONSTANT_P (src))
0349cc73 6442 {
02a8efd2 6443 /* For constant zero values the representation with AND
6444 appears to be folded in more situations than the (set
6445 (zero_extract) ...).
6446 We only do this when the start and end of the bitfield
6447 remain in the same SImode chunk. That way nihf or nilf
6448 can be used.
6449 The AND patterns might still generate a risbg for this. */
6450 if (src == const0_rtx && bitpos / 32 == (bitpos + bitsize - 1) / 32)
6451 return false;
6452 else
6453 src = force_reg (mode, src);
8c753480 6454 }
6455 else if (mode_s != mode)
6456 {
6457 gcc_assert (GET_MODE_BITSIZE (mode_s) >= bitsize);
6458 src = force_reg (mode_s, src);
6459 src = gen_lowpart (mode, src);
6460 }
0349cc73 6461
99274008 6462 op = gen_rtx_ZERO_EXTRACT (mode, dest, op1, op2),
d1f9b275 6463 op = gen_rtx_SET (op, src);
81769881 6464
6465 if (!TARGET_ZEC12)
6466 {
6467 clobber = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
6468 op = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clobber));
6469 }
6470 emit_insn (op);
0349cc73 6471
0349cc73 6472 return true;
6473 }
6474
6475 return false;
6476}
3b699fc7 6477
7cc66daf 6478/* A subroutine of s390_expand_cs_hqi and s390_expand_atomic which returns a
6479 register that holds VAL of mode MODE shifted by COUNT bits. */
182f815e 6480
6481static inline rtx
3754d046 6482s390_expand_mask_and_shift (rtx val, machine_mode mode, rtx count)
182f815e 6483{
6484 val = expand_simple_binop (SImode, AND, val, GEN_INT (GET_MODE_MASK (mode)),
6485 NULL_RTX, 1, OPTAB_DIRECT);
ffead1ca 6486 return expand_simple_binop (SImode, ASHIFT, val, count,
182f815e 6487 NULL_RTX, 1, OPTAB_DIRECT);
6488}
6489
76a4c804 6490/* Generate a vector comparison COND of CMP_OP1 and CMP_OP2 and store
6491 the result in TARGET. */
6492
6493void
6494s390_expand_vec_compare (rtx target, enum rtx_code cond,
6495 rtx cmp_op1, rtx cmp_op2)
6496{
6497 machine_mode mode = GET_MODE (target);
6498 bool neg_p = false, swap_p = false;
6499 rtx tmp;
6500
80912819 6501 if (GET_MODE_CLASS (GET_MODE (cmp_op1)) == MODE_VECTOR_FLOAT)
76a4c804 6502 {
6503 switch (cond)
6504 {
6505 /* NE a != b -> !(a == b) */
6506 case NE: cond = EQ; neg_p = true; break;
6507 /* UNGT a u> b -> !(b >= a) */
6508 case UNGT: cond = GE; neg_p = true; swap_p = true; break;
6509 /* UNGE a u>= b -> !(b > a) */
6510 case UNGE: cond = GT; neg_p = true; swap_p = true; break;
6511 /* LE: a <= b -> b >= a */
6512 case LE: cond = GE; swap_p = true; break;
6513 /* UNLE: a u<= b -> !(a > b) */
6514 case UNLE: cond = GT; neg_p = true; break;
6515 /* LT: a < b -> b > a */
6516 case LT: cond = GT; swap_p = true; break;
6517 /* UNLT: a u< b -> !(a >= b) */
6518 case UNLT: cond = GE; neg_p = true; break;
6519 case UNEQ:
4772a699 6520 emit_insn (gen_vec_cmpuneq (target, cmp_op1, cmp_op2));
76a4c804 6521 return;
6522 case LTGT:
4772a699 6523 emit_insn (gen_vec_cmpltgt (target, cmp_op1, cmp_op2));
76a4c804 6524 return;
6525 case ORDERED:
4772a699 6526 emit_insn (gen_vec_ordered (target, cmp_op1, cmp_op2));
76a4c804 6527 return;
6528 case UNORDERED:
4772a699 6529 emit_insn (gen_vec_unordered (target, cmp_op1, cmp_op2));
76a4c804 6530 return;
6531 default: break;
6532 }
6533 }
6534 else
6535 {
6536 switch (cond)
6537 {
6538 /* NE: a != b -> !(a == b) */
6539 case NE: cond = EQ; neg_p = true; break;
6540 /* GE: a >= b -> !(b > a) */
6541 case GE: cond = GT; neg_p = true; swap_p = true; break;
6542 /* GEU: a >= b -> !(b > a) */
6543 case GEU: cond = GTU; neg_p = true; swap_p = true; break;
6544 /* LE: a <= b -> !(a > b) */
6545 case LE: cond = GT; neg_p = true; break;
6546 /* LEU: a <= b -> !(a > b) */
6547 case LEU: cond = GTU; neg_p = true; break;
6548 /* LT: a < b -> b > a */
6549 case LT: cond = GT; swap_p = true; break;
6550 /* LTU: a < b -> b > a */
6551 case LTU: cond = GTU; swap_p = true; break;
6552 default: break;
6553 }
6554 }
6555
6556 if (swap_p)
6557 {
6558 tmp = cmp_op1; cmp_op1 = cmp_op2; cmp_op2 = tmp;
6559 }
6560
6561 emit_insn (gen_rtx_SET (target, gen_rtx_fmt_ee (cond,
6562 mode,
6563 cmp_op1, cmp_op2)));
6564 if (neg_p)
6565 emit_insn (gen_rtx_SET (target, gen_rtx_NOT (mode, target)));
6566}
6567
07f32359 6568/* Expand the comparison CODE of CMP1 and CMP2 and copy 1 or 0 into
6569 TARGET if either all (ALL_P is true) or any (ALL_P is false) of the
abc57c35 6570 elements in CMP1 and CMP2 fulfill the comparison.
6571 This function is only used to emit patterns for the vx builtins and
6572 therefore only handles comparison codes required by the
6573 builtins. */
07f32359 6574void
6575s390_expand_vec_compare_cc (rtx target, enum rtx_code code,
6576 rtx cmp1, rtx cmp2, bool all_p)
6577{
abc57c35 6578 machine_mode cc_producer_mode, cc_consumer_mode, scratch_mode;
07f32359 6579 rtx tmp_reg = gen_reg_rtx (SImode);
6580 bool swap_p = false;
6581
6582 if (GET_MODE_CLASS (GET_MODE (cmp1)) == MODE_VECTOR_INT)
6583 {
6584 switch (code)
6585 {
abc57c35 6586 case EQ:
6587 case NE:
6588 cc_producer_mode = CCVEQmode;
6589 break;
6590 case GE:
6591 case LT:
6592 code = swap_condition (code);
6593 swap_p = true;
6594 /* fallthrough */
6595 case GT:
6596 case LE:
6597 cc_producer_mode = CCVIHmode;
6598 break;
6599 case GEU:
6600 case LTU:
6601 code = swap_condition (code);
6602 swap_p = true;
6603 /* fallthrough */
6604 case GTU:
6605 case LEU:
6606 cc_producer_mode = CCVIHUmode;
6607 break;
6608 default:
6609 gcc_unreachable ();
07f32359 6610 }
abc57c35 6611
07f32359 6612 scratch_mode = GET_MODE (cmp1);
abc57c35 6613 /* These codes represent inverted CC interpretations. Inverting
6614 an ALL CC mode results in an ANY CC mode and the other way
6615 around. Invert the all_p flag here to compensate for
6616 that. */
6617 if (code == NE || code == LE || code == LEU)
6618 all_p = !all_p;
6619
6620 cc_consumer_mode = all_p ? CCVIALLmode : CCVIANYmode;
07f32359 6621 }
abc57c35 6622 else if (GET_MODE_CLASS (GET_MODE (cmp1)) == MODE_VECTOR_FLOAT)
07f32359 6623 {
abc57c35 6624 bool inv_p = false;
6625
07f32359 6626 switch (code)
6627 {
abc57c35 6628 case EQ: cc_producer_mode = CCVEQmode; break;
6629 case NE: cc_producer_mode = CCVEQmode; inv_p = true; break;
6630 case GT: cc_producer_mode = CCVFHmode; break;
6631 case GE: cc_producer_mode = CCVFHEmode; break;
6632 case UNLE: cc_producer_mode = CCVFHmode; inv_p = true; break;
6633 case UNLT: cc_producer_mode = CCVFHEmode; inv_p = true; break;
6634 case LT: cc_producer_mode = CCVFHmode; code = GT; swap_p = true; break;
6635 case LE: cc_producer_mode = CCVFHEmode; code = GE; swap_p = true; break;
07f32359 6636 default: gcc_unreachable ();
6637 }
12bdf7c0 6638 scratch_mode = mode_for_int_vector (GET_MODE (cmp1)).require ();
abc57c35 6639
6640 if (inv_p)
6641 all_p = !all_p;
6642
6643 cc_consumer_mode = all_p ? CCVFALLmode : CCVFANYmode;
07f32359 6644 }
6645 else
6646 gcc_unreachable ();
6647
07f32359 6648 if (swap_p)
6649 {
6650 rtx tmp = cmp2;
6651 cmp2 = cmp1;
6652 cmp1 = tmp;
6653 }
6654
6655 emit_insn (gen_rtx_PARALLEL (VOIDmode,
6656 gen_rtvec (2, gen_rtx_SET (
abc57c35 6657 gen_rtx_REG (cc_producer_mode, CC_REGNUM),
6658 gen_rtx_COMPARE (cc_producer_mode, cmp1, cmp2)),
07f32359 6659 gen_rtx_CLOBBER (VOIDmode,
6660 gen_rtx_SCRATCH (scratch_mode)))));
6661 emit_move_insn (target, const0_rtx);
6662 emit_move_insn (tmp_reg, const1_rtx);
6663
6664 emit_move_insn (target,
6665 gen_rtx_IF_THEN_ELSE (SImode,
abc57c35 6666 gen_rtx_fmt_ee (code, VOIDmode,
6667 gen_rtx_REG (cc_consumer_mode, CC_REGNUM),
07f32359 6668 const0_rtx),
abc57c35 6669 tmp_reg, target));
07f32359 6670}
6671
e17ed6ec 6672/* Invert the comparison CODE applied to a CC mode. This is only safe
6673 if we know whether there result was created by a floating point
6674 compare or not. For the CCV modes this is encoded as part of the
6675 mode. */
6676enum rtx_code
6677s390_reverse_condition (machine_mode mode, enum rtx_code code)
6678{
6679 /* Reversal of FP compares takes care -- an ordered compare
6680 becomes an unordered compare and vice versa. */
6681 if (mode == CCVFALLmode || mode == CCVFANYmode)
6682 return reverse_condition_maybe_unordered (code);
6683 else if (mode == CCVIALLmode || mode == CCVIANYmode)
6684 return reverse_condition (code);
6685 else
6686 gcc_unreachable ();
6687}
6688
76a4c804 6689/* Generate a vector comparison expression loading either elements of
6690 THEN or ELS into TARGET depending on the comparison COND of CMP_OP1
6691 and CMP_OP2. */
6692
6693void
6694s390_expand_vcond (rtx target, rtx then, rtx els,
6695 enum rtx_code cond, rtx cmp_op1, rtx cmp_op2)
6696{
6697 rtx tmp;
6698 machine_mode result_mode;
6699 rtx result_target;
6700
651e0407 6701 machine_mode target_mode = GET_MODE (target);
6702 machine_mode cmp_mode = GET_MODE (cmp_op1);
6703 rtx op = (cond == LT) ? els : then;
6704
6705 /* Try to optimize x < 0 ? -1 : 0 into (signed) x >> 31
6706 and x < 0 ? 1 : 0 into (unsigned) x >> 31. Likewise
6707 for short and byte (x >> 15 and x >> 7 respectively). */
6708 if ((cond == LT || cond == GE)
6709 && target_mode == cmp_mode
6710 && cmp_op2 == CONST0_RTX (cmp_mode)
6711 && op == CONST0_RTX (target_mode)
6712 && s390_vector_mode_supported_p (target_mode)
6713 && GET_MODE_CLASS (target_mode) == MODE_VECTOR_INT)
6714 {
6715 rtx negop = (cond == LT) ? then : els;
6716
6717 int shift = GET_MODE_BITSIZE (GET_MODE_INNER (target_mode)) - 1;
6718
6719 /* if x < 0 ? 1 : 0 or if x >= 0 ? 0 : 1 */
6720 if (negop == CONST1_RTX (target_mode))
6721 {
6722 rtx res = expand_simple_binop (cmp_mode, LSHIFTRT, cmp_op1,
6723 GEN_INT (shift), target,
6724 1, OPTAB_DIRECT);
6725 if (res != target)
6726 emit_move_insn (target, res);
6727 return;
6728 }
6729
6730 /* if x < 0 ? -1 : 0 or if x >= 0 ? 0 : -1 */
a991c8aa 6731 else if (all_ones_operand (negop, target_mode))
651e0407 6732 {
6733 rtx res = expand_simple_binop (cmp_mode, ASHIFTRT, cmp_op1,
6734 GEN_INT (shift), target,
6735 0, OPTAB_DIRECT);
6736 if (res != target)
6737 emit_move_insn (target, res);
6738 return;
6739 }
6740 }
6741
76a4c804 6742 /* We always use an integral type vector to hold the comparison
6743 result. */
12bdf7c0 6744 result_mode = mode_for_int_vector (cmp_mode).require ();
76a4c804 6745 result_target = gen_reg_rtx (result_mode);
6746
651e0407 6747 /* We allow vector immediates as comparison operands that
6748 can be handled by the optimization above but not by the
6749 following code. Hence, force them into registers here. */
76a4c804 6750 if (!REG_P (cmp_op1))
b088ff4b 6751 cmp_op1 = force_reg (GET_MODE (cmp_op1), cmp_op1);
76a4c804 6752
6753 if (!REG_P (cmp_op2))
b088ff4b 6754 cmp_op2 = force_reg (GET_MODE (cmp_op2), cmp_op2);
76a4c804 6755
6756 s390_expand_vec_compare (result_target, cond,
6757 cmp_op1, cmp_op2);
6758
6759 /* If the results are supposed to be either -1 or 0 we are done
6760 since this is what our compare instructions generate anyway. */
a991c8aa 6761 if (all_ones_operand (then, GET_MODE (then))
76a4c804 6762 && const0_operand (els, GET_MODE (els)))
6763 {
651e0407 6764 emit_move_insn (target, gen_rtx_SUBREG (target_mode,
76a4c804 6765 result_target, 0));
6766 return;
6767 }
6768
6769 /* Otherwise we will do a vsel afterwards. */
6770 /* This gets triggered e.g.
6771 with gcc.c-torture/compile/pr53410-1.c */
6772 if (!REG_P (then))
651e0407 6773 then = force_reg (target_mode, then);
76a4c804 6774
6775 if (!REG_P (els))
651e0407 6776 els = force_reg (target_mode, els);
76a4c804 6777
6778 tmp = gen_rtx_fmt_ee (EQ, VOIDmode,
6779 result_target,
6780 CONST0_RTX (result_mode));
6781
6782 /* We compared the result against zero above so we have to swap then
6783 and els here. */
651e0407 6784 tmp = gen_rtx_IF_THEN_ELSE (target_mode, tmp, els, then);
76a4c804 6785
651e0407 6786 gcc_assert (target_mode == GET_MODE (then));
76a4c804 6787 emit_insn (gen_rtx_SET (target, tmp));
6788}
6789
6790/* Emit the RTX necessary to initialize the vector TARGET with values
6791 in VALS. */
6792void
6793s390_expand_vec_init (rtx target, rtx vals)
6794{
6795 machine_mode mode = GET_MODE (target);
6796 machine_mode inner_mode = GET_MODE_INNER (mode);
6797 int n_elts = GET_MODE_NUNITS (mode);
6798 bool all_same = true, all_regs = true, all_const_int = true;
6799 rtx x;
6800 int i;
6801
6802 for (i = 0; i < n_elts; ++i)
6803 {
6804 x = XVECEXP (vals, 0, i);
6805
6806 if (!CONST_INT_P (x))
6807 all_const_int = false;
6808
6809 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
6810 all_same = false;
6811
6812 if (!REG_P (x))
6813 all_regs = false;
6814 }
6815
6816 /* Use vector gen mask or vector gen byte mask if possible. */
6817 if (all_same && all_const_int
6818 && (XVECEXP (vals, 0, 0) == const0_rtx
6819 || s390_contiguous_bitmask_vector_p (XVECEXP (vals, 0, 0),
6820 NULL, NULL)
6821 || s390_bytemask_vector_p (XVECEXP (vals, 0, 0), NULL)))
6822 {
6823 emit_insn (gen_rtx_SET (target,
6824 gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0))));
6825 return;
6826 }
6827
d4323ae9 6828 /* Use vector replicate instructions. vlrep/vrepi/vrep */
76a4c804 6829 if (all_same)
6830 {
d4323ae9 6831 rtx elem = XVECEXP (vals, 0, 0);
6832
6833 /* vec_splats accepts general_operand as source. */
6834 if (!general_operand (elem, GET_MODE (elem)))
6835 elem = force_reg (inner_mode, elem);
6836
6837 emit_insn (gen_rtx_SET (target, gen_rtx_VEC_DUPLICATE (mode, elem)));
76a4c804 6838 return;
6839 }
6840
f413810a 6841 if (all_regs
6842 && REG_P (target)
6843 && n_elts == 2
6844 && GET_MODE_SIZE (inner_mode) == 8)
76a4c804 6845 {
6846 /* Use vector load pair. */
6847 emit_insn (gen_rtx_SET (target,
6848 gen_rtx_VEC_CONCAT (mode,
6849 XVECEXP (vals, 0, 0),
6850 XVECEXP (vals, 0, 1))));
6851 return;
6852 }
bd97b7d0 6853
6854 /* Use vector load logical element and zero. */
6855 if (TARGET_VXE && (mode == V4SImode || mode == V4SFmode))
6856 {
6857 bool found = true;
6858
6859 x = XVECEXP (vals, 0, 0);
6860 if (memory_operand (x, inner_mode))
6861 {
6862 for (i = 1; i < n_elts; ++i)
6863 found = found && XVECEXP (vals, 0, i) == const0_rtx;
6864
6865 if (found)
6866 {
6867 machine_mode half_mode = (inner_mode == SFmode
6868 ? V2SFmode : V2SImode);
6869 emit_insn (gen_rtx_SET (target,
6870 gen_rtx_VEC_CONCAT (mode,
6871 gen_rtx_VEC_CONCAT (half_mode,
6872 x,
6873 const0_rtx),
6874 gen_rtx_VEC_CONCAT (half_mode,
6875 const0_rtx,
6876 const0_rtx))));
6877 return;
6878 }
6879 }
6880 }
76a4c804 6881
6882 /* We are about to set the vector elements one by one. Zero out the
6883 full register first in order to help the data flow framework to
6884 detect it as full VR set. */
6885 emit_insn (gen_rtx_SET (target, CONST0_RTX (mode)));
6886
6887 /* Unfortunately the vec_init expander is not allowed to fail. So
6888 we have to implement the fallback ourselves. */
6889 for (i = 0; i < n_elts; i++)
4ba2579e 6890 {
6891 rtx elem = XVECEXP (vals, 0, i);
6892 if (!general_operand (elem, GET_MODE (elem)))
6893 elem = force_reg (inner_mode, elem);
6894
6895 emit_insn (gen_rtx_SET (target,
6896 gen_rtx_UNSPEC (mode,
6897 gen_rtvec (3, elem,
6898 GEN_INT (i), target),
6899 UNSPEC_VEC_SET)));
6900 }
76a4c804 6901}
6902
182f815e 6903/* Structure to hold the initial parameters for a compare_and_swap operation
ffead1ca 6904 in HImode and QImode. */
182f815e 6905
6906struct alignment_context
6907{
ffead1ca 6908 rtx memsi; /* SI aligned memory location. */
182f815e 6909 rtx shift; /* Bit offset with regard to lsb. */
6910 rtx modemask; /* Mask of the HQImode shifted by SHIFT bits. */
6911 rtx modemaski; /* ~modemask */
191ec5a2 6912 bool aligned; /* True if memory is aligned, false else. */
182f815e 6913};
6914
7cc66daf 6915/* A subroutine of s390_expand_cs_hqi and s390_expand_atomic to initialize
6916 structure AC for transparent simplifying, if the memory alignment is known
6917 to be at least 32bit. MEM is the memory location for the actual operation
6918 and MODE its mode. */
182f815e 6919
6920static void
6921init_alignment_context (struct alignment_context *ac, rtx mem,
3754d046 6922 machine_mode mode)
182f815e 6923{
6924 ac->shift = GEN_INT (GET_MODE_SIZE (SImode) - GET_MODE_SIZE (mode));
6925 ac->aligned = (MEM_ALIGN (mem) >= GET_MODE_BITSIZE (SImode));
6926
6927 if (ac->aligned)
6928 ac->memsi = adjust_address (mem, SImode, 0); /* Memory is aligned. */
6929 else
6930 {
6931 /* Alignment is unknown. */
6932 rtx byteoffset, addr, align;
6933
6934 /* Force the address into a register. */
6935 addr = force_reg (Pmode, XEXP (mem, 0));
6936
6937 /* Align it to SImode. */
6938 align = expand_simple_binop (Pmode, AND, addr,
6939 GEN_INT (-GET_MODE_SIZE (SImode)),
6940 NULL_RTX, 1, OPTAB_DIRECT);
6941 /* Generate MEM. */
6942 ac->memsi = gen_rtx_MEM (SImode, align);
6943 MEM_VOLATILE_P (ac->memsi) = MEM_VOLATILE_P (mem);
bd1da572 6944 set_mem_alias_set (ac->memsi, ALIAS_SET_MEMORY_BARRIER);
182f815e 6945 set_mem_align (ac->memsi, GET_MODE_BITSIZE (SImode));
6946
6947 /* Calculate shiftcount. */
6948 byteoffset = expand_simple_binop (Pmode, AND, addr,
6949 GEN_INT (GET_MODE_SIZE (SImode) - 1),
6950 NULL_RTX, 1, OPTAB_DIRECT);
6951 /* As we already have some offset, evaluate the remaining distance. */
6952 ac->shift = expand_simple_binop (SImode, MINUS, ac->shift, byteoffset,
6953 NULL_RTX, 1, OPTAB_DIRECT);
182f815e 6954 }
8c753480 6955
182f815e 6956 /* Shift is the byte count, but we need the bitcount. */
8c753480 6957 ac->shift = expand_simple_binop (SImode, ASHIFT, ac->shift, GEN_INT (3),
6958 NULL_RTX, 1, OPTAB_DIRECT);
6959
182f815e 6960 /* Calculate masks. */
ffead1ca 6961 ac->modemask = expand_simple_binop (SImode, ASHIFT,
8c753480 6962 GEN_INT (GET_MODE_MASK (mode)),
6963 ac->shift, NULL_RTX, 1, OPTAB_DIRECT);
6964 ac->modemaski = expand_simple_unop (SImode, NOT, ac->modemask,
6965 NULL_RTX, 1);
6966}
6967
6968/* A subroutine of s390_expand_cs_hqi. Insert INS into VAL. If possible,
6969 use a single insv insn into SEQ2. Otherwise, put prep insns in SEQ1 and
6970 perform the merge in SEQ2. */
6971
6972static rtx
6973s390_two_part_insv (struct alignment_context *ac, rtx *seq1, rtx *seq2,
3754d046 6974 machine_mode mode, rtx val, rtx ins)
8c753480 6975{
6976 rtx tmp;
6977
6978 if (ac->aligned)
6979 {
6980 start_sequence ();
6981 tmp = copy_to_mode_reg (SImode, val);
6982 if (s390_expand_insv (tmp, GEN_INT (GET_MODE_BITSIZE (mode)),
6983 const0_rtx, ins))
6984 {
6985 *seq1 = NULL;
6986 *seq2 = get_insns ();
6987 end_sequence ();
6988 return tmp;
6989 }
6990 end_sequence ();
6991 }
6992
6993 /* Failed to use insv. Generate a two part shift and mask. */
6994 start_sequence ();
6995 tmp = s390_expand_mask_and_shift (ins, mode, ac->shift);
6996 *seq1 = get_insns ();
6997 end_sequence ();
6998
6999 start_sequence ();
7000 tmp = expand_simple_binop (SImode, IOR, tmp, val, NULL_RTX, 1, OPTAB_DIRECT);
7001 *seq2 = get_insns ();
7002 end_sequence ();
7003
7004 return tmp;
182f815e 7005}
7006
7007/* Expand an atomic compare and swap operation for HImode and QImode. MEM is
8c753480 7008 the memory location, CMP the old value to compare MEM with and NEW_RTX the
7009 value to set if CMP == MEM. */
182f815e 7010
d90d26d8 7011static void
3754d046 7012s390_expand_cs_hqi (machine_mode mode, rtx btarget, rtx vtarget, rtx mem,
8c753480 7013 rtx cmp, rtx new_rtx, bool is_weak)
182f815e 7014{
7015 struct alignment_context ac;
77e58889 7016 rtx cmpv, newv, val, cc, seq0, seq1, seq2, seq3;
182f815e 7017 rtx res = gen_reg_rtx (SImode);
79f6a8ed 7018 rtx_code_label *csloop = NULL, *csend = NULL;
182f815e 7019
182f815e 7020 gcc_assert (MEM_P (mem));
7021
7022 init_alignment_context (&ac, mem, mode);
7023
182f815e 7024 /* Load full word. Subsequent loads are performed by CS. */
7025 val = expand_simple_binop (SImode, AND, ac.memsi, ac.modemaski,
7026 NULL_RTX, 1, OPTAB_DIRECT);
7027
8c753480 7028 /* Prepare insertions of cmp and new_rtx into the loaded value. When
7029 possible, we try to use insv to make this happen efficiently. If
7030 that fails we'll generate code both inside and outside the loop. */
7031 cmpv = s390_two_part_insv (&ac, &seq0, &seq2, mode, val, cmp);
7032 newv = s390_two_part_insv (&ac, &seq1, &seq3, mode, val, new_rtx);
7033
7034 if (seq0)
7035 emit_insn (seq0);
7036 if (seq1)
7037 emit_insn (seq1);
7038
182f815e 7039 /* Start CS loop. */
8c753480 7040 if (!is_weak)
7041 {
7042 /* Begin assuming success. */
7043 emit_move_insn (btarget, const1_rtx);
7044
7045 csloop = gen_label_rtx ();
7046 csend = gen_label_rtx ();
7047 emit_label (csloop);
7048 }
7049
ffead1ca 7050 /* val = "<mem>00..0<mem>"
182f815e 7051 * cmp = "00..0<cmp>00..0"
ffead1ca 7052 * new = "00..0<new>00..0"
182f815e 7053 */
7054
8c753480 7055 emit_insn (seq2);
7056 emit_insn (seq3);
7057
d90d26d8 7058 cc = s390_emit_compare_and_swap (EQ, res, ac.memsi, cmpv, newv, CCZ1mode);
8c753480 7059 if (is_weak)
7060 emit_insn (gen_cstorecc4 (btarget, cc, XEXP (cc, 0), XEXP (cc, 1)));
182f815e 7061 else
182f815e 7062 {
77e58889 7063 rtx tmp;
7064
8c753480 7065 /* Jump to end if we're done (likely?). */
7066 s390_emit_jump (csend, cc);
7067
77e58889 7068 /* Check for changes outside mode, and loop internal if so.
7069 Arrange the moves so that the compare is adjacent to the
7070 branch so that we can generate CRJ. */
7071 tmp = copy_to_reg (val);
7072 force_expand_binop (SImode, and_optab, res, ac.modemaski, val,
7073 1, OPTAB_DIRECT);
7074 cc = s390_emit_compare (NE, val, tmp);
8c753480 7075 s390_emit_jump (csloop, cc);
7076
7077 /* Failed. */
7078 emit_move_insn (btarget, const0_rtx);
7079 emit_label (csend);
182f815e 7080 }
ffead1ca 7081
182f815e 7082 /* Return the correct part of the bitfield. */
8c753480 7083 convert_move (vtarget, expand_simple_binop (SImode, LSHIFTRT, res, ac.shift,
7084 NULL_RTX, 1, OPTAB_DIRECT), 1);
182f815e 7085}
7086
d90d26d8 7087/* Variant of s390_expand_cs for SI, DI and TI modes. */
7088static void
7089s390_expand_cs_tdsi (machine_mode mode, rtx btarget, rtx vtarget, rtx mem,
7090 rtx cmp, rtx new_rtx, bool is_weak)
7091{
7092 rtx output = vtarget;
7093 rtx_code_label *skip_cs_label = NULL;
7094 bool do_const_opt = false;
7095
7096 if (!register_operand (output, mode))
7097 output = gen_reg_rtx (mode);
7098
7099 /* If IS_WEAK is true and the INPUT value is a constant, compare the memory
7100 with the constant first and skip the compare_and_swap because its very
7101 expensive and likely to fail anyway.
7102 Note 1: This is done only for IS_WEAK. C11 allows optimizations that may
7103 cause spurious in that case.
7104 Note 2: It may be useful to do this also for non-constant INPUT.
7105 Note 3: Currently only targets with "load on condition" are supported
7106 (z196 and newer). */
7107
7108 if (TARGET_Z196
7109 && (mode == SImode || mode == DImode))
7110 do_const_opt = (is_weak && CONST_INT_P (cmp));
7111
7112 if (do_const_opt)
7113 {
d90d26d8 7114 rtx cc = gen_rtx_REG (CCZmode, CC_REGNUM);
7115
7116 skip_cs_label = gen_label_rtx ();
7117 emit_move_insn (btarget, const0_rtx);
7118 if (CONST_INT_P (cmp) && INTVAL (cmp) == 0)
7119 {
7120 rtvec lt = rtvec_alloc (2);
7121
7122 /* Load-and-test + conditional jump. */
7123 RTVEC_ELT (lt, 0)
7124 = gen_rtx_SET (cc, gen_rtx_COMPARE (CCZmode, mem, cmp));
7125 RTVEC_ELT (lt, 1) = gen_rtx_SET (output, mem);
7126 emit_insn (gen_rtx_PARALLEL (VOIDmode, lt));
7127 }
7128 else
7129 {
7130 emit_move_insn (output, mem);
7131 emit_insn (gen_rtx_SET (cc, gen_rtx_COMPARE (CCZmode, output, cmp)));
7132 }
7133 s390_emit_jump (skip_cs_label, gen_rtx_NE (VOIDmode, cc, const0_rtx));
9f522e0c 7134 add_reg_br_prob_note (get_last_insn (),
7135 profile_probability::very_unlikely ());
d90d26d8 7136 /* If the jump is not taken, OUTPUT is the expected value. */
7137 cmp = output;
7138 /* Reload newval to a register manually, *after* the compare and jump
7139 above. Otherwise Reload might place it before the jump. */
7140 }
7141 else
7142 cmp = force_reg (mode, cmp);
7143 new_rtx = force_reg (mode, new_rtx);
7144 s390_emit_compare_and_swap (EQ, output, mem, cmp, new_rtx,
7145 (do_const_opt) ? CCZmode : CCZ1mode);
7146 if (skip_cs_label != NULL)
7147 emit_label (skip_cs_label);
7148
7149 /* We deliberately accept non-register operands in the predicate
7150 to ensure the write back to the output operand happens *before*
7151 the store-flags code below. This makes it easier for combine
7152 to merge the store-flags code with a potential test-and-branch
7153 pattern following (immediately!) afterwards. */
7154 if (output != vtarget)
7155 emit_move_insn (vtarget, output);
7156
7157 if (do_const_opt)
7158 {
7159 rtx cc, cond, ite;
7160
7161 /* Do not use gen_cstorecc4 here because it writes either 1 or 0, but
7162 btarget has already been initialized with 0 above. */
7163 cc = gen_rtx_REG (CCZmode, CC_REGNUM);
7164 cond = gen_rtx_EQ (VOIDmode, cc, const0_rtx);
7165 ite = gen_rtx_IF_THEN_ELSE (SImode, cond, const1_rtx, btarget);
7166 emit_insn (gen_rtx_SET (btarget, ite));
7167 }
7168 else
7169 {
7170 rtx cc, cond;
7171
7172 cc = gen_rtx_REG (CCZ1mode, CC_REGNUM);
7173 cond = gen_rtx_EQ (SImode, cc, const0_rtx);
7174 emit_insn (gen_cstorecc4 (btarget, cond, cc, const0_rtx));
7175 }
7176}
7177
7178/* Expand an atomic compare and swap operation. MEM is the memory location,
7179 CMP the old value to compare MEM with and NEW_RTX the value to set if
7180 CMP == MEM. */
7181
7182void
7183s390_expand_cs (machine_mode mode, rtx btarget, rtx vtarget, rtx mem,
7184 rtx cmp, rtx new_rtx, bool is_weak)
7185{
7186 switch (mode)
7187 {
916ace94 7188 case E_TImode:
7189 case E_DImode:
7190 case E_SImode:
d90d26d8 7191 s390_expand_cs_tdsi (mode, btarget, vtarget, mem, cmp, new_rtx, is_weak);
7192 break;
916ace94 7193 case E_HImode:
7194 case E_QImode:
d90d26d8 7195 s390_expand_cs_hqi (mode, btarget, vtarget, mem, cmp, new_rtx, is_weak);
7196 break;
7197 default:
7198 gcc_unreachable ();
7199 }
7200}
7201
7202/* Expand an atomic_exchange operation simulated with a compare-and-swap loop.
7203 The memory location MEM is set to INPUT. OUTPUT is set to the previous value
7204 of MEM. */
7205
7206void
7207s390_expand_atomic_exchange_tdsi (rtx output, rtx mem, rtx input)
7208{
7209 machine_mode mode = GET_MODE (mem);
7210 rtx_code_label *csloop;
7211
7212 if (TARGET_Z196
7213 && (mode == DImode || mode == SImode)
7214 && CONST_INT_P (input) && INTVAL (input) == 0)
7215 {
7216 emit_move_insn (output, const0_rtx);
7217 if (mode == DImode)
7218 emit_insn (gen_atomic_fetch_anddi (output, mem, const0_rtx, input));
7219 else
7220 emit_insn (gen_atomic_fetch_andsi (output, mem, const0_rtx, input));
7221 return;
7222 }
7223
7224 input = force_reg (mode, input);
7225 emit_move_insn (output, mem);
7226 csloop = gen_label_rtx ();
7227 emit_label (csloop);
7228 s390_emit_jump (csloop, s390_emit_compare_and_swap (NE, output, mem, output,
7229 input, CCZ1mode));
7230}
7231
7cc66daf 7232/* Expand an atomic operation CODE of mode MODE. MEM is the memory location
85694bac 7233 and VAL the value to play with. If AFTER is true then store the value
7cc66daf 7234 MEM holds after the operation, if AFTER is false then store the value MEM
7235 holds before the operation. If TARGET is zero then discard that value, else
7236 store it to TARGET. */
7237
7238void
3754d046 7239s390_expand_atomic (machine_mode mode, enum rtx_code code,
7cc66daf 7240 rtx target, rtx mem, rtx val, bool after)
7241{
7242 struct alignment_context ac;
7243 rtx cmp;
8deb3959 7244 rtx new_rtx = gen_reg_rtx (SImode);
7cc66daf 7245 rtx orig = gen_reg_rtx (SImode);
79f6a8ed 7246 rtx_code_label *csloop = gen_label_rtx ();
7cc66daf 7247
7248 gcc_assert (!target || register_operand (target, VOIDmode));
7249 gcc_assert (MEM_P (mem));
7250
7251 init_alignment_context (&ac, mem, mode);
7252
7253 /* Shift val to the correct bit positions.
7254 Preserve "icm", but prevent "ex icm". */
7255 if (!(ac.aligned && code == SET && MEM_P (val)))
7256 val = s390_expand_mask_and_shift (val, mode, ac.shift);
7257
7258 /* Further preparation insns. */
7259 if (code == PLUS || code == MINUS)
7260 emit_move_insn (orig, val);
7261 else if (code == MULT || code == AND) /* val = "11..1<val>11..1" */
7262 val = expand_simple_binop (SImode, XOR, val, ac.modemaski,
7263 NULL_RTX, 1, OPTAB_DIRECT);
7264
7265 /* Load full word. Subsequent loads are performed by CS. */
7266 cmp = force_reg (SImode, ac.memsi);
7267
7268 /* Start CS loop. */
7269 emit_label (csloop);
8deb3959 7270 emit_move_insn (new_rtx, cmp);
7cc66daf 7271
7272 /* Patch new with val at correct position. */
7273 switch (code)
7274 {
7275 case PLUS:
7276 case MINUS:
8deb3959 7277 val = expand_simple_binop (SImode, code, new_rtx, orig,
7cc66daf 7278 NULL_RTX, 1, OPTAB_DIRECT);
7279 val = expand_simple_binop (SImode, AND, val, ac.modemask,
7280 NULL_RTX, 1, OPTAB_DIRECT);
7281 /* FALLTHRU */
ffead1ca 7282 case SET:
7cc66daf 7283 if (ac.aligned && MEM_P (val))
b634c730 7284 store_bit_field (new_rtx, GET_MODE_BITSIZE (mode), 0,
292237f3 7285 0, 0, SImode, val, false);
7cc66daf 7286 else
7287 {
8deb3959 7288 new_rtx = expand_simple_binop (SImode, AND, new_rtx, ac.modemaski,
7cc66daf 7289 NULL_RTX, 1, OPTAB_DIRECT);
8deb3959 7290 new_rtx = expand_simple_binop (SImode, IOR, new_rtx, val,
7cc66daf 7291 NULL_RTX, 1, OPTAB_DIRECT);
7292 }
7293 break;
7294 case AND:
7295 case IOR:
7296 case XOR:
8deb3959 7297 new_rtx = expand_simple_binop (SImode, code, new_rtx, val,
7cc66daf 7298 NULL_RTX, 1, OPTAB_DIRECT);
7299 break;
7300 case MULT: /* NAND */
8deb3959 7301 new_rtx = expand_simple_binop (SImode, AND, new_rtx, val,
7cc66daf 7302 NULL_RTX, 1, OPTAB_DIRECT);
636c17b8 7303 new_rtx = expand_simple_binop (SImode, XOR, new_rtx, ac.modemask,
7304 NULL_RTX, 1, OPTAB_DIRECT);
7cc66daf 7305 break;
7306 default:
7307 gcc_unreachable ();
7308 }
7cc66daf 7309
db1f11e3 7310 s390_emit_jump (csloop, s390_emit_compare_and_swap (NE, cmp,
d90d26d8 7311 ac.memsi, cmp, new_rtx,
7312 CCZ1mode));
7cc66daf 7313
7314 /* Return the correct part of the bitfield. */
7315 if (target)
7316 convert_move (target, expand_simple_binop (SImode, LSHIFTRT,
8deb3959 7317 after ? new_rtx : cmp, ac.shift,
7cc66daf 7318 NULL_RTX, 1, OPTAB_DIRECT), 1);
7319}
7320
40af64cc 7321/* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
03c118d5 7322 We need to emit DTP-relative relocations. */
7323
40af64cc 7324static void s390_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
7325
7326static void
b40da9a7 7327s390_output_dwarf_dtprel (FILE *file, int size, rtx x)
03c118d5 7328{
7329 switch (size)
7330 {
7331 case 4:
7332 fputs ("\t.long\t", file);
7333 break;
7334 case 8:
7335 fputs ("\t.quad\t", file);
7336 break;
7337 default:
32eda510 7338 gcc_unreachable ();
03c118d5 7339 }
7340 output_addr_const (file, x);
7341 fputs ("@DTPOFF", file);
7342}
7343
76a4c804 7344/* Return the proper mode for REGNO being represented in the dwarf
7345 unwind table. */
7346machine_mode
7347s390_dwarf_frame_reg_mode (int regno)
7348{
7349 machine_mode save_mode = default_dwarf_frame_reg_mode (regno);
7350
52de7525 7351 /* Make sure not to return DImode for any GPR with -m31 -mzarch. */
7352 if (GENERAL_REGNO_P (regno))
7353 save_mode = Pmode;
7354
76a4c804 7355 /* The rightmost 64 bits of vector registers are call-clobbered. */
7356 if (GET_MODE_SIZE (save_mode) > 8)
7357 save_mode = DImode;
7358
7359 return save_mode;
7360}
7361
4257b08a 7362#ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
eddcdde1 7363/* Implement TARGET_MANGLE_TYPE. */
4257b08a 7364
7365static const char *
a9f1838b 7366s390_mangle_type (const_tree type)
4257b08a 7367{
07f32359 7368 type = TYPE_MAIN_VARIANT (type);
7369
7370 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
7371 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
7372 return NULL;
7373
7374 if (type == s390_builtin_types[BT_BV16QI]) return "U6__boolc";
7375 if (type == s390_builtin_types[BT_BV8HI]) return "U6__bools";
7376 if (type == s390_builtin_types[BT_BV4SI]) return "U6__booli";
7377 if (type == s390_builtin_types[BT_BV2DI]) return "U6__booll";
7378
4257b08a 7379 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
7380 && TARGET_LONG_DOUBLE_128)
7381 return "g";
7382
7383 /* For all other types, use normal C++ mangling. */
7384 return NULL;
7385}
7386#endif
7387
e93986bb 7388/* In the name of slightly smaller debug output, and to cater to
06b27565 7389 general assembler lossage, recognize various UNSPEC sequences
e93986bb 7390 and turn them back into a direct symbol reference. */
7391
07576557 7392static rtx
b40da9a7 7393s390_delegitimize_address (rtx orig_x)
e93986bb 7394{
3b6b647c 7395 rtx x, y;
e93986bb 7396
3b6b647c 7397 orig_x = delegitimize_mem_from_attrs (orig_x);
7398 x = orig_x;
4796d433 7399
7400 /* Extract the symbol ref from:
7401 (plus:SI (reg:SI 12 %r12)
9f522e0c 7402 (const:SI (unspec:SI [(symbol_ref/f:SI ("*.LC0"))]
7403 UNSPEC_GOTOFF/PLTOFF)))
2b2b857a 7404 and
7405 (plus:SI (reg:SI 12 %r12)
9f522e0c 7406 (const:SI (plus:SI (unspec:SI [(symbol_ref:SI ("L"))]
7407 UNSPEC_GOTOFF/PLTOFF)
2b2b857a 7408 (const_int 4 [0x4])))) */
4796d433 7409 if (GET_CODE (x) == PLUS
7410 && REG_P (XEXP (x, 0))
7411 && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM
7412 && GET_CODE (XEXP (x, 1)) == CONST)
7413 {
b6382e93 7414 HOST_WIDE_INT offset = 0;
7415
4796d433 7416 /* The const operand. */
7417 y = XEXP (XEXP (x, 1), 0);
2b2b857a 7418
7419 if (GET_CODE (y) == PLUS
7420 && GET_CODE (XEXP (y, 1)) == CONST_INT)
b6382e93 7421 {
7422 offset = INTVAL (XEXP (y, 1));
7423 y = XEXP (y, 0);
7424 }
2b2b857a 7425
4796d433 7426 if (GET_CODE (y) == UNSPEC
2b2b857a 7427 && (XINT (y, 1) == UNSPEC_GOTOFF
7428 || XINT (y, 1) == UNSPEC_PLTOFF))
29c05e22 7429 return plus_constant (Pmode, XVECEXP (y, 0, 0), offset);
4796d433 7430 }
7431
e93986bb 7432 if (GET_CODE (x) != MEM)
7433 return orig_x;
7434
7435 x = XEXP (x, 0);
7436 if (GET_CODE (x) == PLUS
7437 && GET_CODE (XEXP (x, 1)) == CONST
7438 && GET_CODE (XEXP (x, 0)) == REG
7439 && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM)
7440 {
7441 y = XEXP (XEXP (x, 1), 0);
7442 if (GET_CODE (y) == UNSPEC
12ef3745 7443 && XINT (y, 1) == UNSPEC_GOT)
54cb44a3 7444 y = XVECEXP (y, 0, 0);
7445 else
7446 return orig_x;
e93986bb 7447 }
54cb44a3 7448 else if (GET_CODE (x) == CONST)
e93986bb 7449 {
2b2b857a 7450 /* Extract the symbol ref from:
7451 (mem:QI (const:DI (unspec:DI [(symbol_ref:DI ("foo"))]
9f522e0c 7452 UNSPEC_PLT/GOTENT))) */
2b2b857a 7453
e93986bb 7454 y = XEXP (x, 0);
7455 if (GET_CODE (y) == UNSPEC
2b2b857a 7456 && (XINT (y, 1) == UNSPEC_GOTENT
7457 || XINT (y, 1) == UNSPEC_PLT))
54cb44a3 7458 y = XVECEXP (y, 0, 0);
7459 else
7460 return orig_x;
e93986bb 7461 }
54cb44a3 7462 else
7463 return orig_x;
e93986bb 7464
54cb44a3 7465 if (GET_MODE (orig_x) != Pmode)
7466 {
2b03de53 7467 if (GET_MODE (orig_x) == BLKmode)
7468 return orig_x;
54cb44a3 7469 y = lowpart_subreg (GET_MODE (orig_x), y, Pmode);
7470 if (y == NULL_RTX)
7471 return orig_x;
7472 }
7473 return y;
e93986bb 7474}
2eb8fe23 7475
805a133b 7476/* Output operand OP to stdio stream FILE.
7477 OP is an address (register + offset) which is not used to address data;
7478 instead the rightmost bits are interpreted as the value. */
63ebd742 7479
7480static void
2be7449b 7481print_addrstyle_operand (FILE *file, rtx op)
63ebd742 7482{
6d6be381 7483 HOST_WIDE_INT offset;
7484 rtx base;
9a09ba70 7485
6d6be381 7486 /* Extract base register and offset. */
2be7449b 7487 if (!s390_decompose_addrstyle_without_index (op, &base, &offset))
6d6be381 7488 gcc_unreachable ();
63ebd742 7489
7490 /* Sanity check. */
6d6be381 7491 if (base)
32eda510 7492 {
6d6be381 7493 gcc_assert (GET_CODE (base) == REG);
7494 gcc_assert (REGNO (base) < FIRST_PSEUDO_REGISTER);
7495 gcc_assert (REGNO_REG_CLASS (REGNO (base)) == ADDR_REGS);
32eda510 7496 }
63ebd742 7497
805a133b 7498 /* Offsets are constricted to twelve bits. */
7499 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset & ((1 << 12) - 1));
6d6be381 7500 if (base)
7501 fprintf (file, "(%s)", reg_names[REGNO (base)]);
63ebd742 7502}
7503
c243c9ea 7504/* Print the shift count operand OP to FILE.
7505 OP is an address-style operand in a form which
7506 s390_valid_shift_count permits. Subregs and no-op
7507 and-masking of the operand are stripped. */
7508
7509static void
7510print_shift_count_operand (FILE *file, rtx op)
7511{
7512 /* No checking of the and mask required here. */
7513 if (!s390_valid_shift_count (op, 0))
7514 gcc_unreachable ();
7515
7516 while (op && GET_CODE (op) == SUBREG)
7517 op = SUBREG_REG (op);
7518
7519 if (GET_CODE (op) == AND)
7520 op = XEXP (op, 0);
7521
7522 print_addrstyle_operand (file, op);
7523}
7524
06877232 7525/* Assigns the number of NOP halfwords to be emitted before and after the
7526 function label to *HW_BEFORE and *HW_AFTER. Both pointers must not be NULL.
7527 If hotpatching is disabled for the function, the values are set to zero.
7528*/
77bc9912 7529
06877232 7530static void
11762b83 7531s390_function_num_hotpatch_hw (tree decl,
7532 int *hw_before,
7533 int *hw_after)
77bc9912 7534{
7535 tree attr;
7536
11762b83 7537 attr = lookup_attribute ("hotpatch", DECL_ATTRIBUTES (decl));
7538
7539 /* Handle the arguments of the hotpatch attribute. The values
7540 specified via attribute might override the cmdline argument
7541 values. */
7542 if (attr)
77bc9912 7543 {
11762b83 7544 tree args = TREE_VALUE (attr);
7545
7546 *hw_before = TREE_INT_CST_LOW (TREE_VALUE (args));
7547 *hw_after = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (args)));
77bc9912 7548 }
11762b83 7549 else
77bc9912 7550 {
11762b83 7551 /* Use the values specified by the cmdline arguments. */
7552 *hw_before = s390_hotpatch_hw_before_label;
7553 *hw_after = s390_hotpatch_hw_after_label;
77bc9912 7554 }
77bc9912 7555}
7556
7a0cee35 7557/* Write the current .machine and .machinemode specification to the assembler
7558 file. */
7559
14d7e7e6 7560#ifdef HAVE_AS_MACHINE_MACHINEMODE
7a0cee35 7561static void
7562s390_asm_output_machine_for_arch (FILE *asm_out_file)
7563{
7564 fprintf (asm_out_file, "\t.machinemode %s\n",
7565 (TARGET_ZARCH) ? "zarch" : "esa");
a168a775 7566 fprintf (asm_out_file, "\t.machine \"%s",
7567 processor_table[s390_arch].binutils_name);
7a0cee35 7568 if (S390_USE_ARCHITECTURE_MODIFIERS)
7569 {
7570 int cpu_flags;
7571
7572 cpu_flags = processor_flags_table[(int) s390_arch];
7573 if (TARGET_HTM && !(cpu_flags & PF_TX))
7574 fprintf (asm_out_file, "+htm");
7575 else if (!TARGET_HTM && (cpu_flags & PF_TX))
7576 fprintf (asm_out_file, "+nohtm");
7577 if (TARGET_VX && !(cpu_flags & PF_VX))
7578 fprintf (asm_out_file, "+vx");
7579 else if (!TARGET_VX && (cpu_flags & PF_VX))
7580 fprintf (asm_out_file, "+novx");
7581 }
7582 fprintf (asm_out_file, "\"\n");
7583}
7584
7585/* Write an extra function header before the very start of the function. */
7586
7587void
7588s390_asm_output_function_prefix (FILE *asm_out_file,
7589 const char *fnname ATTRIBUTE_UNUSED)
7590{
7591 if (DECL_FUNCTION_SPECIFIC_TARGET (current_function_decl) == NULL)
7592 return;
7593 /* Since only the function specific options are saved but not the indications
7594 which options are set, it's too much work here to figure out which options
7595 have actually changed. Thus, generate .machine and .machinemode whenever a
7596 function has the target attribute or pragma. */
7597 fprintf (asm_out_file, "\t.machinemode push\n");
7598 fprintf (asm_out_file, "\t.machine push\n");
7599 s390_asm_output_machine_for_arch (asm_out_file);
7600}
7601
7602/* Write an extra function footer after the very end of the function. */
7603
7604void
7605s390_asm_declare_function_size (FILE *asm_out_file,
0491d54f 7606 const char *fnname, tree decl)
7a0cee35 7607{
0491d54f 7608 if (!flag_inhibit_size_directive)
7609 ASM_OUTPUT_MEASURED_SIZE (asm_out_file, fnname);
7a0cee35 7610 if (DECL_FUNCTION_SPECIFIC_TARGET (decl) == NULL)
7611 return;
7612 fprintf (asm_out_file, "\t.machine pop\n");
7613 fprintf (asm_out_file, "\t.machinemode pop\n");
7614}
7615#endif
7616
77bc9912 7617/* Write the extra assembler code needed to declare a function properly. */
7618
7619void
7620s390_asm_output_function_label (FILE *asm_out_file, const char *fname,
7621 tree decl)
7622{
11762b83 7623 int hw_before, hw_after;
77bc9912 7624
06877232 7625 s390_function_num_hotpatch_hw (decl, &hw_before, &hw_after);
7626 if (hw_before > 0)
77bc9912 7627 {
f4252e72 7628 unsigned int function_alignment;
77bc9912 7629 int i;
7630
7631 /* Add a trampoline code area before the function label and initialize it
7632 with two-byte nop instructions. This area can be overwritten with code
7633 that jumps to a patched version of the function. */
2a4536cc 7634 asm_fprintf (asm_out_file, "\tnopr\t%%r0"
06877232 7635 "\t# pre-label NOPs for hotpatch (%d halfwords)\n",
7636 hw_before);
7637 for (i = 1; i < hw_before; i++)
2a4536cc 7638 fputs ("\tnopr\t%r0\n", asm_out_file);
06877232 7639
77bc9912 7640 /* Note: The function label must be aligned so that (a) the bytes of the
7641 following nop do not cross a cacheline boundary, and (b) a jump address
7642 (eight bytes for 64 bit targets, 4 bytes for 32 bit targets) can be
7643 stored directly before the label without crossing a cacheline
7644 boundary. All this is necessary to make sure the trampoline code can
06877232 7645 be changed atomically.
7646 This alignment is done automatically using the FOUNCTION_BOUNDARY, but
7647 if there are NOPs before the function label, the alignment is placed
7648 before them. So it is necessary to duplicate the alignment after the
7649 NOPs. */
f4252e72 7650 function_alignment = MAX (8, DECL_ALIGN (decl) / BITS_PER_UNIT);
7651 if (! DECL_USER_ALIGN (decl))
6fceef7a 7652 function_alignment
7653 = MAX (function_alignment,
7654 (unsigned int) align_functions.levels[0].get_value ());
06877232 7655 fputs ("\t# alignment for hotpatch\n", asm_out_file);
6fceef7a 7656 ASM_OUTPUT_ALIGN (asm_out_file, align_functions.levels[0].log);
77bc9912 7657 }
7658
7a0cee35 7659 if (S390_USE_TARGET_ATTRIBUTE && TARGET_DEBUG_ARG)
7660 {
7661 asm_fprintf (asm_out_file, "\t# fn:%s ar%d\n", fname, s390_arch);
7662 asm_fprintf (asm_out_file, "\t# fn:%s tu%d\n", fname, s390_tune);
7663 asm_fprintf (asm_out_file, "\t# fn:%s sg%d\n", fname, s390_stack_guard);
7664 asm_fprintf (asm_out_file, "\t# fn:%s ss%d\n", fname, s390_stack_size);
7665 asm_fprintf (asm_out_file, "\t# fn:%s bc%d\n", fname, s390_branch_cost);
7666 asm_fprintf (asm_out_file, "\t# fn:%s wf%d\n", fname,
7667 s390_warn_framesize);
7668 asm_fprintf (asm_out_file, "\t# fn:%s ba%d\n", fname, TARGET_BACKCHAIN);
7669 asm_fprintf (asm_out_file, "\t# fn:%s hd%d\n", fname, TARGET_HARD_DFP);
7670 asm_fprintf (asm_out_file, "\t# fn:%s hf%d\n", fname, !TARGET_SOFT_FLOAT);
7671 asm_fprintf (asm_out_file, "\t# fn:%s ht%d\n", fname, TARGET_OPT_HTM);
7672 asm_fprintf (asm_out_file, "\t# fn:%s vx%d\n", fname, TARGET_OPT_VX);
7673 asm_fprintf (asm_out_file, "\t# fn:%s ps%d\n", fname,
7674 TARGET_PACKED_STACK);
7675 asm_fprintf (asm_out_file, "\t# fn:%s se%d\n", fname, TARGET_SMALL_EXEC);
7676 asm_fprintf (asm_out_file, "\t# fn:%s mv%d\n", fname, TARGET_MVCLE);
7677 asm_fprintf (asm_out_file, "\t# fn:%s zv%d\n", fname, TARGET_ZVECTOR);
7678 asm_fprintf (asm_out_file, "\t# fn:%s wd%d\n", fname,
7679 s390_warn_dynamicstack_p);
7680 }
77bc9912 7681 ASM_OUTPUT_LABEL (asm_out_file, fname);
06877232 7682 if (hw_after > 0)
7683 asm_fprintf (asm_out_file,
7684 "\t# post-label NOPs for hotpatch (%d halfwords)\n",
7685 hw_after);
77bc9912 7686}
7687
f588eb9f 7688/* Output machine-dependent UNSPECs occurring in address constant X
74d2529d 7689 in assembler syntax to stdio stream FILE. Returns true if the
7690 constant X could be recognized, false otherwise. */
4673c1a0 7691
1a561788 7692static bool
74d2529d 7693s390_output_addr_const_extra (FILE *file, rtx x)
4673c1a0 7694{
74d2529d 7695 if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 1)
7696 switch (XINT (x, 1))
7697 {
7698 case UNSPEC_GOTENT:
7699 output_addr_const (file, XVECEXP (x, 0, 0));
7700 fprintf (file, "@GOTENT");
7701 return true;
7702 case UNSPEC_GOT:
7703 output_addr_const (file, XVECEXP (x, 0, 0));
7704 fprintf (file, "@GOT");
7705 return true;
7706 case UNSPEC_GOTOFF:
7707 output_addr_const (file, XVECEXP (x, 0, 0));
7708 fprintf (file, "@GOTOFF");
7709 return true;
7710 case UNSPEC_PLT:
7711 output_addr_const (file, XVECEXP (x, 0, 0));
7712 fprintf (file, "@PLT");
7713 return true;
7714 case UNSPEC_PLTOFF:
7715 output_addr_const (file, XVECEXP (x, 0, 0));
7716 fprintf (file, "@PLTOFF");
7717 return true;
7718 case UNSPEC_TLSGD:
7719 output_addr_const (file, XVECEXP (x, 0, 0));
7720 fprintf (file, "@TLSGD");
7721 return true;
7722 case UNSPEC_TLSLDM:
7723 assemble_name (file, get_some_local_dynamic_name ());
7724 fprintf (file, "@TLSLDM");
7725 return true;
7726 case UNSPEC_DTPOFF:
7727 output_addr_const (file, XVECEXP (x, 0, 0));
7728 fprintf (file, "@DTPOFF");
7729 return true;
7730 case UNSPEC_NTPOFF:
7731 output_addr_const (file, XVECEXP (x, 0, 0));
7732 fprintf (file, "@NTPOFF");
7733 return true;
7734 case UNSPEC_GOTNTPOFF:
7735 output_addr_const (file, XVECEXP (x, 0, 0));
7736 fprintf (file, "@GOTNTPOFF");
7737 return true;
7738 case UNSPEC_INDNTPOFF:
7739 output_addr_const (file, XVECEXP (x, 0, 0));
7740 fprintf (file, "@INDNTPOFF");
7741 return true;
7742 }
4673c1a0 7743
1ed7a160 7744 if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 2)
7745 switch (XINT (x, 1))
7746 {
7747 case UNSPEC_POOL_OFFSET:
7748 x = gen_rtx_MINUS (GET_MODE (x), XVECEXP (x, 0, 0), XVECEXP (x, 0, 1));
7749 output_addr_const (file, x);
7750 return true;
7751 }
74d2529d 7752 return false;
4673c1a0 7753}
7754
f81e845f 7755/* Output address operand ADDR in assembler syntax to
56769981 7756 stdio stream FILE. */
4673c1a0 7757
7758void
b40da9a7 7759print_operand_address (FILE *file, rtx addr)
4673c1a0 7760{
7761 struct s390_address ad;
883b2519 7762 memset (&ad, 0, sizeof (s390_address));
4673c1a0 7763
2a672556 7764 if (s390_loadrelative_operand_p (addr, NULL, NULL))
e68d6a13 7765 {
53b9033c 7766 if (!TARGET_Z10)
7767 {
902602ef 7768 output_operand_lossage ("symbolic memory references are "
7769 "only supported on z10 or later");
53b9033c 7770 return;
7771 }
e68d6a13 7772 output_addr_const (file, addr);
7773 return;
7774 }
7775
8ba34dcd 7776 if (!s390_decompose_address (addr, &ad)
1e280623 7777 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
7778 || (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx))))
3284a242 7779 output_operand_lossage ("cannot decompose address");
f81e845f 7780
4673c1a0 7781 if (ad.disp)
74d2529d 7782 output_addr_const (file, ad.disp);
4673c1a0 7783 else
7784 fprintf (file, "0");
7785
7786 if (ad.base && ad.indx)
7787 fprintf (file, "(%s,%s)", reg_names[REGNO (ad.indx)],
9f522e0c 7788 reg_names[REGNO (ad.base)]);
4673c1a0 7789 else if (ad.base)
7790 fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
7791}
7792
f81e845f 7793/* Output operand X in assembler syntax to stdio stream FILE.
7794 CODE specified the format flag. The following format flags
56769981 7795 are recognized:
7796
f0075e6e 7797 'A': On z14 or higher: If operand is a mem print the alignment
7798 hint usable with vl/vst prefixed by a comma.
56769981 7799 'C': print opcode suffix for branch condition.
7800 'D': print opcode suffix for inverse branch condition.
f1443d23 7801 'E': print opcode suffix for branch on index instruction.
cc87d0c5 7802 'G': print the size of the operand in bytes.
0d46035f 7803 'J': print tls_load/tls_gdcall/tls_ldcall suffix
7804 'M': print the second word of a TImode operand.
7805 'N': print the second word of a DImode operand.
76a4c804 7806 'O': print only the displacement of a memory reference or address.
7807 'R': print only the base register of a memory reference or address.
0574acbe 7808 'S': print S-type memory reference (base+displacement).
2be7449b 7809 'Y': print address style operand without index (e.g. shift count or setmem
7810 operand).
56769981 7811
45981c0a 7812 'b': print integer X as if it's an unsigned byte.
e68d6a13 7813 'c': print integer X as if it's an signed byte.
76a4c804 7814 'e': "end" contiguous bitmask X in either DImode or vector inner mode.
7815 'f': "end" contiguous bitmask X in SImode.
b9059d39 7816 'h': print integer X as if it's a signed halfword.
64a1078f 7817 'i': print the first nonzero HImode part of X.
b9059d39 7818 'j': print the first HImode part unequal to -1 of X.
7819 'k': print the first nonzero SImode part of X.
7820 'm': print the first SImode part unequal to -1 of X.
0d46035f 7821 'o': print integer X as if it's an unsigned 32bit word.
76a4c804 7822 's': "start" of contiguous bitmask X in either DImode or vector inner mode.
7823 't': CONST_INT: "start" of contiguous bitmask X in SImode.
9f522e0c 7824 CONST_VECTOR: Generate a bitmask for vgbm instruction.
0d46035f 7825 'x': print integer X as if it's an unsigned halfword.
76a4c804 7826 'v': print register number as vector register (v1 instead of f1).
0d46035f 7827*/
4673c1a0 7828
7829void
b40da9a7 7830print_operand (FILE *file, rtx x, int code)
4673c1a0 7831{
0d46035f 7832 HOST_WIDE_INT ival;
7833
4673c1a0 7834 switch (code)
7835 {
f0075e6e 7836 case 'A':
7837#ifdef HAVE_AS_VECTOR_LOADSTORE_ALIGNMENT_HINTS
7838 if (TARGET_Z14 && MEM_P (x))
7839 {
7840 if (MEM_ALIGN (x) >= 128)
7841 fprintf (file, ",4");
7842 else if (MEM_ALIGN (x) == 64)
7843 fprintf (file, ",3");
7844 }
7845#endif
7846 return;
4673c1a0 7847 case 'C':
2eb8fe23 7848 fprintf (file, s390_branch_condition_mnemonic (x, FALSE));
4673c1a0 7849 return;
7850
7851 case 'D':
2eb8fe23 7852 fprintf (file, s390_branch_condition_mnemonic (x, TRUE));
4673c1a0 7853 return;
7854
f1443d23 7855 case 'E':
7856 if (GET_CODE (x) == LE)
7857 fprintf (file, "l");
7858 else if (GET_CODE (x) == GT)
7859 fprintf (file, "h");
7860 else
902602ef 7861 output_operand_lossage ("invalid comparison operator "
7862 "for 'E' output modifier");
f1443d23 7863 return;
7864
be00aaa8 7865 case 'J':
7866 if (GET_CODE (x) == SYMBOL_REF)
7867 {
7868 fprintf (file, "%s", ":tls_load:");
7869 output_addr_const (file, x);
7870 }
7871 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD)
7872 {
7873 fprintf (file, "%s", ":tls_gdcall:");
7874 output_addr_const (file, XVECEXP (x, 0, 0));
7875 }
7876 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM)
7877 {
7878 fprintf (file, "%s", ":tls_ldcall:");
3677652f 7879 const char *name = get_some_local_dynamic_name ();
7880 gcc_assert (name);
7881 assemble_name (file, name);
be00aaa8 7882 }
7883 else
902602ef 7884 output_operand_lossage ("invalid reference for 'J' output modifier");
be00aaa8 7885 return;
7886
cc87d0c5 7887 case 'G':
7888 fprintf (file, "%u", GET_MODE_SIZE (GET_MODE (x)));
7889 return;
7890
4673c1a0 7891 case 'O':
7892 {
9f522e0c 7893 struct s390_address ad;
32eda510 7894 int ret;
4673c1a0 7895
76a4c804 7896 ret = s390_decompose_address (MEM_P (x) ? XEXP (x, 0) : x, &ad);
53b9033c 7897
7898 if (!ret
7899 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
7900 || ad.indx)
7901 {
902602ef 7902 output_operand_lossage ("invalid address for 'O' output modifier");
53b9033c 7903 return;
7904 }
4673c1a0 7905
9f522e0c 7906 if (ad.disp)
7907 output_addr_const (file, ad.disp);
7908 else
7909 fprintf (file, "0");
4673c1a0 7910 }
7911 return;
7912
7913 case 'R':
7914 {
9f522e0c 7915 struct s390_address ad;
32eda510 7916 int ret;
4673c1a0 7917
76a4c804 7918 ret = s390_decompose_address (MEM_P (x) ? XEXP (x, 0) : x, &ad);
53b9033c 7919
7920 if (!ret
7921 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
7922 || ad.indx)
7923 {
902602ef 7924 output_operand_lossage ("invalid address for 'R' output modifier");
53b9033c 7925 return;
7926 }
4673c1a0 7927
9f522e0c 7928 if (ad.base)
7929 fprintf (file, "%s", reg_names[REGNO (ad.base)]);
7930 else
7931 fprintf (file, "0");
4673c1a0 7932 }
7933 return;
7934
0574acbe 7935 case 'S':
7936 {
7937 struct s390_address ad;
32eda510 7938 int ret;
0574acbe 7939
53b9033c 7940 if (!MEM_P (x))
7941 {
902602ef 7942 output_operand_lossage ("memory reference expected for "
7943 "'S' output modifier");
53b9033c 7944 return;
7945 }
32eda510 7946 ret = s390_decompose_address (XEXP (x, 0), &ad);
53b9033c 7947
7948 if (!ret
7949 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
7950 || ad.indx)
7951 {
902602ef 7952 output_operand_lossage ("invalid address for 'S' output modifier");
53b9033c 7953 return;
7954 }
0574acbe 7955
7956 if (ad.disp)
7957 output_addr_const (file, ad.disp);
7958 else
7959 fprintf (file, "0");
7960
7961 if (ad.base)
7962 fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
7963 }
7964 return;
7965
4673c1a0 7966 case 'N':
7967 if (GET_CODE (x) == REG)
7968 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
7969 else if (GET_CODE (x) == MEM)
29c05e22 7970 x = change_address (x, VOIDmode,
7971 plus_constant (Pmode, XEXP (x, 0), 4));
4673c1a0 7972 else
902602ef 7973 output_operand_lossage ("register or memory expression expected "
7974 "for 'N' output modifier");
4673c1a0 7975 break;
7976
7977 case 'M':
7978 if (GET_CODE (x) == REG)
7979 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
7980 else if (GET_CODE (x) == MEM)
29c05e22 7981 x = change_address (x, VOIDmode,
7982 plus_constant (Pmode, XEXP (x, 0), 8));
4673c1a0 7983 else
902602ef 7984 output_operand_lossage ("register or memory expression expected "
7985 "for 'M' output modifier");
4673c1a0 7986 break;
63ebd742 7987
7988 case 'Y':
c243c9ea 7989 print_shift_count_operand (file, x);
63ebd742 7990 return;
4673c1a0 7991 }
7992
7993 switch (GET_CODE (x))
7994 {
7995 case REG:
76a4c804 7996 /* Print FP regs as fx instead of vx when they are accessed
7997 through non-vector mode. */
7998 if (code == 'v'
7999 || VECTOR_NOFP_REG_P (x)
8000 || (FP_REG_P (x) && VECTOR_MODE_P (GET_MODE (x)))
8001 || (VECTOR_REG_P (x)
8002 && (GET_MODE_SIZE (GET_MODE (x)) /
8003 s390_class_max_nregs (FP_REGS, GET_MODE (x))) > 8))
8004 fprintf (file, "%%v%s", reg_names[REGNO (x)] + 2);
8005 else
8006 fprintf (file, "%s", reg_names[REGNO (x)]);
4673c1a0 8007 break;
8008
8009 case MEM:
3c047fe9 8010 output_address (GET_MODE (x), XEXP (x, 0));
4673c1a0 8011 break;
8012
8013 case CONST:
8014 case CODE_LABEL:
8015 case LABEL_REF:
8016 case SYMBOL_REF:
74d2529d 8017 output_addr_const (file, x);
4673c1a0 8018 break;
8019
8020 case CONST_INT:
0d46035f 8021 ival = INTVAL (x);
8022 switch (code)
8023 {
8024 case 0:
8025 break;
8026 case 'b':
8027 ival &= 0xff;
8028 break;
8029 case 'c':
8030 ival = ((ival & 0xff) ^ 0x80) - 0x80;
8031 break;
8032 case 'x':
8033 ival &= 0xffff;
8034 break;
8035 case 'h':
8036 ival = ((ival & 0xffff) ^ 0x8000) - 0x8000;
8037 break;
8038 case 'i':
8039 ival = s390_extract_part (x, HImode, 0);
8040 break;
8041 case 'j':
8042 ival = s390_extract_part (x, HImode, -1);
8043 break;
8044 case 'k':
8045 ival = s390_extract_part (x, SImode, 0);
8046 break;
8047 case 'm':
8048 ival = s390_extract_part (x, SImode, -1);
8049 break;
8050 case 'o':
8051 ival &= 0xffffffff;
8052 break;
8053 case 'e': case 'f':
8054 case 's': case 't':
8055 {
e64f5133 8056 int start, end;
8057 int len;
0d46035f 8058 bool ok;
8059
8060 len = (code == 's' || code == 'e' ? 64 : 32);
e64f5133 8061 ok = s390_contiguous_bitmask_p (ival, true, len, &start, &end);
0d46035f 8062 gcc_assert (ok);
8063 if (code == 's' || code == 't')
e64f5133 8064 ival = start;
0d46035f 8065 else
e64f5133 8066 ival = end;
0d46035f 8067 }
8068 break;
8069 default:
8070 output_operand_lossage ("invalid constant for output modifier '%c'", code);
8071 }
8072 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival);
8b4a4127 8073 break;
8074
ba0e61d6 8075 case CONST_WIDE_INT:
8b4a4127 8076 if (code == 'b')
9f522e0c 8077 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
ba0e61d6 8078 CONST_WIDE_INT_ELT (x, 0) & 0xff);
4673c1a0 8079 else if (code == 'x')
9f522e0c 8080 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
ba0e61d6 8081 CONST_WIDE_INT_ELT (x, 0) & 0xffff);
4673c1a0 8082 else if (code == 'h')
9f522e0c 8083 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
ba0e61d6 8084 ((CONST_WIDE_INT_ELT (x, 0) & 0xffff) ^ 0x8000) - 0x8000);
4673c1a0 8085 else
53b9033c 8086 {
8087 if (code == 0)
902602ef 8088 output_operand_lossage ("invalid constant - try using "
8089 "an output modifier");
53b9033c 8090 else
902602ef 8091 output_operand_lossage ("invalid constant for output modifier '%c'",
8092 code);
53b9033c 8093 }
4673c1a0 8094 break;
76a4c804 8095 case CONST_VECTOR:
8096 switch (code)
8097 {
80fc7f56 8098 case 'h':
8099 gcc_assert (const_vec_duplicate_p (x));
8100 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
8101 ((INTVAL (XVECEXP (x, 0, 0)) & 0xffff) ^ 0x8000) - 0x8000);
8102 break;
76a4c804 8103 case 'e':
8104 case 's':
8105 {
e64f5133 8106 int start, end;
76a4c804 8107 bool ok;
8108
e64f5133 8109 ok = s390_contiguous_bitmask_vector_p (x, &start, &end);
76a4c804 8110 gcc_assert (ok);
e64f5133 8111 ival = (code == 's') ? start : end;
76a4c804 8112 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival);
8113 }
8114 break;
8115 case 't':
8116 {
8117 unsigned mask;
8118 bool ok = s390_bytemask_vector_p (x, &mask);
8119 gcc_assert (ok);
8120 fprintf (file, "%u", mask);
8121 }
8122 break;
8123
8124 default:
8125 output_operand_lossage ("invalid constant vector for output "
8126 "modifier '%c'", code);
8127 }
8128 break;
4673c1a0 8129
8130 default:
53b9033c 8131 if (code == 0)
902602ef 8132 output_operand_lossage ("invalid expression - try using "
8133 "an output modifier");
53b9033c 8134 else
902602ef 8135 output_operand_lossage ("invalid expression for output "
8136 "modifier '%c'", code);
4673c1a0 8137 break;
8138 }
8139}
8140
58356836 8141/* Target hook for assembling integer objects. We need to define it
8142 here to work a round a bug in some versions of GAS, which couldn't
8143 handle values smaller than INT_MIN when printed in decimal. */
8144
8145static bool
b40da9a7 8146s390_assemble_integer (rtx x, unsigned int size, int aligned_p)
58356836 8147{
8148 if (size == 8 && aligned_p
8149 && GET_CODE (x) == CONST_INT && INTVAL (x) < INT_MIN)
8150 {
4840a03a 8151 fprintf (asm_out_file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n",
8152 INTVAL (x));
58356836 8153 return true;
8154 }
8155 return default_assemble_integer (x, size, aligned_p);
8156}
8157
f81e845f 8158/* Returns true if register REGNO is used for forming
56769981 8159 a memory address in expression X. */
4673c1a0 8160
e5537457 8161static bool
b40da9a7 8162reg_used_in_mem_p (int regno, rtx x)
4673c1a0 8163{
8164 enum rtx_code code = GET_CODE (x);
8165 int i, j;
8166 const char *fmt;
f81e845f 8167
4673c1a0 8168 if (code == MEM)
8169 {
2ec77a7c 8170 if (refers_to_regno_p (regno, XEXP (x, 0)))
e5537457 8171 return true;
4673c1a0 8172 }
f81e845f 8173 else if (code == SET
8b4a4127 8174 && GET_CODE (SET_DEST (x)) == PC)
8175 {
2ec77a7c 8176 if (refers_to_regno_p (regno, SET_SRC (x)))
e5537457 8177 return true;
8b4a4127 8178 }
4673c1a0 8179
8180 fmt = GET_RTX_FORMAT (code);
8181 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
8182 {
8183 if (fmt[i] == 'e'
8184 && reg_used_in_mem_p (regno, XEXP (x, i)))
e5537457 8185 return true;
f81e845f 8186
4673c1a0 8187 else if (fmt[i] == 'E')
8188 for (j = 0; j < XVECLEN (x, i); j++)
8189 if (reg_used_in_mem_p (regno, XVECEXP (x, i, j)))
e5537457 8190 return true;
4673c1a0 8191 }
e5537457 8192 return false;
4673c1a0 8193}
8194
0c034860 8195/* Returns true if expression DEP_RTX sets an address register
56769981 8196 used by instruction INSN to address memory. */
4673c1a0 8197
e5537457 8198static bool
ed3e6e5d 8199addr_generation_dependency_p (rtx dep_rtx, rtx_insn *insn)
4673c1a0 8200{
8b4a4127 8201 rtx target, pat;
4673c1a0 8202
aa90bb35 8203 if (NONJUMP_INSN_P (dep_rtx))
77985f1a 8204 dep_rtx = PATTERN (dep_rtx);
71343e6b 8205
4673c1a0 8206 if (GET_CODE (dep_rtx) == SET)
8207 {
8208 target = SET_DEST (dep_rtx);
147b6a2d 8209 if (GET_CODE (target) == STRICT_LOW_PART)
8210 target = XEXP (target, 0);
8211 while (GET_CODE (target) == SUBREG)
8212 target = SUBREG_REG (target);
8213
4673c1a0 8214 if (GET_CODE (target) == REG)
8215 {
8216 int regno = REGNO (target);
8217
71343e6b 8218 if (s390_safe_attr_type (insn) == TYPE_LA)
8b4a4127 8219 {
8220 pat = PATTERN (insn);
8221 if (GET_CODE (pat) == PARALLEL)
8222 {
32eda510 8223 gcc_assert (XVECLEN (pat, 0) == 2);
8b4a4127 8224 pat = XVECEXP (pat, 0, 0);
8225 }
32eda510 8226 gcc_assert (GET_CODE (pat) == SET);
2ec77a7c 8227 return refers_to_regno_p (regno, SET_SRC (pat));
8b4a4127 8228 }
71343e6b 8229 else if (get_attr_atype (insn) == ATYPE_AGEN)
8b4a4127 8230 return reg_used_in_mem_p (regno, PATTERN (insn));
8231 }
4673c1a0 8232 }
e5537457 8233 return false;
4673c1a0 8234}
8235
71343e6b 8236/* Return 1, if dep_insn sets register used in insn in the agen unit. */
8237
f81e845f 8238int
ed3e6e5d 8239s390_agen_dep_p (rtx_insn *dep_insn, rtx_insn *insn)
f81e845f 8240{
71343e6b 8241 rtx dep_rtx = PATTERN (dep_insn);
8242 int i;
f81e845f 8243
8244 if (GET_CODE (dep_rtx) == SET
71343e6b 8245 && addr_generation_dependency_p (dep_rtx, insn))
8246 return 1;
8247 else if (GET_CODE (dep_rtx) == PARALLEL)
8248 {
8249 for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
8250 {
8251 if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i), insn))
8252 return 1;
8253 }
8254 }
8255 return 0;
8256}
8257
510c2327 8258
e51ae8ff 8259/* A C statement (sans semicolon) to update the integer scheduling priority
8260 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
8261 reduce the priority to execute INSN later. Do not define this macro if
f81e845f 8262 you do not need to adjust the scheduling priorities of insns.
e51ae8ff 8263
f81e845f 8264 A STD instruction should be scheduled earlier,
e51ae8ff 8265 in order to use the bypass. */
e51ae8ff 8266static int
18282db0 8267s390_adjust_priority (rtx_insn *insn, int priority)
e51ae8ff 8268{
8269 if (! INSN_P (insn))
8270 return priority;
8271
9aae2901 8272 if (s390_tune <= PROCESSOR_2064_Z900)
e51ae8ff 8273 return priority;
8274
8275 switch (s390_safe_attr_type (insn))
8276 {
11f88fec 8277 case TYPE_FSTOREDF:
8278 case TYPE_FSTORESF:
e51ae8ff 8279 priority = priority << 3;
8280 break;
8281 case TYPE_STORE:
76dbb8df 8282 case TYPE_STM:
e51ae8ff 8283 priority = priority << 1;
8284 break;
8285 default:
9f522e0c 8286 break;
e51ae8ff 8287 }
8288 return priority;
8289}
369293ed 8290
b0eacf26 8291
71343e6b 8292/* The number of instructions that can be issued per cycle. */
369293ed 8293
71343e6b 8294static int
b40da9a7 8295s390_issue_rate (void)
71343e6b 8296{
a850370e 8297 switch (s390_tune)
8298 {
8299 case PROCESSOR_2084_Z990:
8300 case PROCESSOR_2094_Z9_109:
9aae2901 8301 case PROCESSOR_2094_Z9_EC:
33d033da 8302 case PROCESSOR_2817_Z196:
a850370e 8303 return 3;
8304 case PROCESSOR_2097_Z10:
8305 return 2;
117d67d0 8306 case PROCESSOR_2064_Z900:
5ed1f72b 8307 /* Starting with EC12 we use the sched_reorder hook to take care
8308 of instruction dispatch constraints. The algorithm only
8309 picks the best instruction and assumes only a single
8310 instruction gets issued per cycle. */
8311 case PROCESSOR_2827_ZEC12:
117d67d0 8312 case PROCESSOR_2964_Z13:
a168a775 8313 case PROCESSOR_3906_Z14:
a850370e 8314 default:
8315 return 1;
8316 }
71343e6b 8317}
369293ed 8318
e51ae8ff 8319static int
b40da9a7 8320s390_first_cycle_multipass_dfa_lookahead (void)
e51ae8ff 8321{
a65ea517 8322 return 4;
e51ae8ff 8323}
8324
20074f87 8325static void
50a42dec 8326annotate_constant_pool_refs_1 (rtx *x)
20074f87 8327{
8328 int i, j;
8329 const char *fmt;
8330
32eda510 8331 gcc_assert (GET_CODE (*x) != SYMBOL_REF
8332 || !CONSTANT_POOL_ADDRESS_P (*x));
20074f87 8333
8334 /* Literal pool references can only occur inside a MEM ... */
8335 if (GET_CODE (*x) == MEM)
8336 {
8337 rtx memref = XEXP (*x, 0);
8338
8339 if (GET_CODE (memref) == SYMBOL_REF
8340 && CONSTANT_POOL_ADDRESS_P (memref))
8341 {
8342 rtx base = cfun->machine->base_reg;
8343 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, memref, base),
8344 UNSPEC_LTREF);
8345
8346 *x = replace_equiv_address (*x, addr);
8347 return;
8348 }
8349
8350 if (GET_CODE (memref) == CONST
8351 && GET_CODE (XEXP (memref, 0)) == PLUS
8352 && GET_CODE (XEXP (XEXP (memref, 0), 1)) == CONST_INT
8353 && GET_CODE (XEXP (XEXP (memref, 0), 0)) == SYMBOL_REF
8354 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (memref, 0), 0)))
8355 {
8356 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (memref, 0), 1));
8357 rtx sym = XEXP (XEXP (memref, 0), 0);
8358 rtx base = cfun->machine->base_reg;
8359 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, sym, base),
8360 UNSPEC_LTREF);
8361
29c05e22 8362 *x = replace_equiv_address (*x, plus_constant (Pmode, addr, off));
20074f87 8363 return;
8364 }
8365 }
8366
8367 /* ... or a load-address type pattern. */
8368 if (GET_CODE (*x) == SET)
8369 {
8370 rtx addrref = SET_SRC (*x);
8371
8372 if (GET_CODE (addrref) == SYMBOL_REF
8373 && CONSTANT_POOL_ADDRESS_P (addrref))
8374 {
8375 rtx base = cfun->machine->base_reg;
8376 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, addrref, base),
8377 UNSPEC_LTREF);
8378
8379 SET_SRC (*x) = addr;
8380 return;
8381 }
8382
8383 if (GET_CODE (addrref) == CONST
8384 && GET_CODE (XEXP (addrref, 0)) == PLUS
8385 && GET_CODE (XEXP (XEXP (addrref, 0), 1)) == CONST_INT
8386 && GET_CODE (XEXP (XEXP (addrref, 0), 0)) == SYMBOL_REF
8387 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (addrref, 0), 0)))
8388 {
8389 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (addrref, 0), 1));
8390 rtx sym = XEXP (XEXP (addrref, 0), 0);
8391 rtx base = cfun->machine->base_reg;
8392 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, sym, base),
8393 UNSPEC_LTREF);
8394
29c05e22 8395 SET_SRC (*x) = plus_constant (Pmode, addr, off);
20074f87 8396 return;
8397 }
8398 }
8399
20074f87 8400 fmt = GET_RTX_FORMAT (GET_CODE (*x));
8401 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
8402 {
8403 if (fmt[i] == 'e')
9f522e0c 8404 {
50a42dec 8405 annotate_constant_pool_refs_1 (&XEXP (*x, i));
9f522e0c 8406 }
20074f87 8407 else if (fmt[i] == 'E')
9f522e0c 8408 {
8409 for (j = 0; j < XVECLEN (*x, i); j++)
50a42dec 8410 annotate_constant_pool_refs_1 (&XVECEXP (*x, i, j));
9f522e0c 8411 }
20074f87 8412 }
8413}
8414
50a42dec 8415/* Annotate every literal pool reference in INSN by an UNSPEC_LTREF expression.
8416 Fix up MEMs as required.
8417 Skip insns which support relative addressing, because they do not use a base
8418 register. */
0756cebb 8419
50a42dec 8420static void
8421annotate_constant_pool_refs (rtx_insn *insn)
8422{
8423 if (s390_safe_relative_long_p (insn))
8424 return;
8425 annotate_constant_pool_refs_1 (&PATTERN (insn));
8426}
0756cebb 8427
8428static void
50a42dec 8429find_constant_pool_ref_1 (rtx x, rtx *ref)
0756cebb 8430{
8431 int i, j;
8432 const char *fmt;
8433
c2c1332a 8434 /* Likewise POOL_ENTRY insns. */
8435 if (GET_CODE (x) == UNSPEC_VOLATILE
8436 && XINT (x, 1) == UNSPECV_POOL_ENTRY)
8437 return;
12ef3745 8438
32eda510 8439 gcc_assert (GET_CODE (x) != SYMBOL_REF
9f522e0c 8440 || !CONSTANT_POOL_ADDRESS_P (x));
20074f87 8441
8442 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_LTREF)
0756cebb 8443 {
20074f87 8444 rtx sym = XVECEXP (x, 0, 0);
32eda510 8445 gcc_assert (GET_CODE (sym) == SYMBOL_REF
9f522e0c 8446 && CONSTANT_POOL_ADDRESS_P (sym));
20074f87 8447
0756cebb 8448 if (*ref == NULL_RTX)
20074f87 8449 *ref = sym;
ffead1ca 8450 else
32eda510 8451 gcc_assert (*ref == sym);
20074f87 8452
8453 return;
0756cebb 8454 }
8455
8456 fmt = GET_RTX_FORMAT (GET_CODE (x));
8457 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
8458 {
8459 if (fmt[i] == 'e')
9f522e0c 8460 {
50a42dec 8461 find_constant_pool_ref_1 (XEXP (x, i), ref);
9f522e0c 8462 }
0756cebb 8463 else if (fmt[i] == 'E')
9f522e0c 8464 {
8465 for (j = 0; j < XVECLEN (x, i); j++)
50a42dec 8466 find_constant_pool_ref_1 (XVECEXP (x, i, j), ref);
9f522e0c 8467 }
0756cebb 8468 }
8469}
8470
50a42dec 8471/* Find an annotated literal pool symbol referenced in INSN,
8472 and store it at REF. Will abort if INSN contains references to
8473 more than one such pool symbol; multiple references to the same
8474 symbol are allowed, however.
8475
8476 The rtx pointed to by REF must be initialized to NULL_RTX
8477 by the caller before calling this routine.
8478
8479 Skip insns which support relative addressing, because they do not use a base
8480 register. */
8481
8482static void
8483find_constant_pool_ref (rtx_insn *insn, rtx *ref)
8484{
8485 if (s390_safe_relative_long_p (insn))
8486 return;
8487 find_constant_pool_ref_1 (PATTERN (insn), ref);
8488}
0756cebb 8489
8490static void
50a42dec 8491replace_constant_pool_ref_1 (rtx *x, rtx ref, rtx offset)
0756cebb 8492{
8493 int i, j;
8494 const char *fmt;
8495
32eda510 8496 gcc_assert (*x != ref);
0756cebb 8497
20074f87 8498 if (GET_CODE (*x) == UNSPEC
8499 && XINT (*x, 1) == UNSPEC_LTREF
8500 && XVECEXP (*x, 0, 0) == ref)
0756cebb 8501 {
20074f87 8502 *x = gen_rtx_PLUS (Pmode, XVECEXP (*x, 0, 1), offset);
8503 return;
0756cebb 8504 }
8505
20074f87 8506 if (GET_CODE (*x) == PLUS
8507 && GET_CODE (XEXP (*x, 1)) == CONST_INT
8508 && GET_CODE (XEXP (*x, 0)) == UNSPEC
8509 && XINT (XEXP (*x, 0), 1) == UNSPEC_LTREF
8510 && XVECEXP (XEXP (*x, 0), 0, 0) == ref)
0756cebb 8511 {
20074f87 8512 rtx addr = gen_rtx_PLUS (Pmode, XVECEXP (XEXP (*x, 0), 0, 1), offset);
29c05e22 8513 *x = plus_constant (Pmode, addr, INTVAL (XEXP (*x, 1)));
20074f87 8514 return;
0756cebb 8515 }
8516
8517 fmt = GET_RTX_FORMAT (GET_CODE (*x));
8518 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
8519 {
8520 if (fmt[i] == 'e')
9f522e0c 8521 {
50a42dec 8522 replace_constant_pool_ref_1 (&XEXP (*x, i), ref, offset);
9f522e0c 8523 }
0756cebb 8524 else if (fmt[i] == 'E')
9f522e0c 8525 {
8526 for (j = 0; j < XVECLEN (*x, i); j++)
50a42dec 8527 replace_constant_pool_ref_1 (&XVECEXP (*x, i, j), ref, offset);
9f522e0c 8528 }
0756cebb 8529 }
8530}
8531
50a42dec 8532/* Replace every reference to the annotated literal pool
8533 symbol REF in INSN by its base plus OFFSET.
8534 Skip insns which support relative addressing, because they do not use a base
8535 register. */
8536
8537static void
8538replace_constant_pool_ref (rtx_insn *insn, rtx ref, rtx offset)
8539{
8540 if (s390_safe_relative_long_p (insn))
8541 return;
8542 replace_constant_pool_ref_1 (&PATTERN (insn), ref, offset);
8543}
8544
12ef3745 8545/* We keep a list of constants which we have to add to internal
0756cebb 8546 constant tables in the middle of large functions. */
8547
02b901ef 8548#define NR_C_MODES 32
3754d046 8549machine_mode constant_modes[NR_C_MODES] =
0756cebb 8550{
36868490 8551 TFmode, TImode, TDmode,
02b901ef 8552 V16QImode, V8HImode, V4SImode, V2DImode, V1TImode,
8553 V4SFmode, V2DFmode, V1TFmode,
36868490 8554 DFmode, DImode, DDmode,
76a4c804 8555 V8QImode, V4HImode, V2SImode, V1DImode, V2SFmode, V1DFmode,
36868490 8556 SFmode, SImode, SDmode,
76a4c804 8557 V4QImode, V2HImode, V1SImode, V1SFmode,
0756cebb 8558 HImode,
76a4c804 8559 V2QImode, V1HImode,
8560 QImode,
8561 V1QImode
0756cebb 8562};
8563
0756cebb 8564struct constant
8565{
8566 struct constant *next;
8567 rtx value;
93e0956b 8568 rtx_code_label *label;
0756cebb 8569};
8570
8571struct constant_pool
8572{
8573 struct constant_pool *next;
93e0956b 8574 rtx_insn *first_insn;
8575 rtx_insn *pool_insn;
96be3ab6 8576 bitmap insns;
93e0956b 8577 rtx_insn *emit_pool_after;
0756cebb 8578
8579 struct constant *constants[NR_C_MODES];
d345b493 8580 struct constant *execute;
93e0956b 8581 rtx_code_label *label;
0756cebb 8582 int size;
8583};
8584
875862bf 8585/* Allocate new constant_pool structure. */
8586
8587static struct constant_pool *
8588s390_alloc_pool (void)
8589{
8590 struct constant_pool *pool;
8591 int i;
8592
8593 pool = (struct constant_pool *) xmalloc (sizeof *pool);
8594 pool->next = NULL;
8595 for (i = 0; i < NR_C_MODES; i++)
8596 pool->constants[i] = NULL;
8597
8598 pool->execute = NULL;
8599 pool->label = gen_label_rtx ();
93e0956b 8600 pool->first_insn = NULL;
8601 pool->pool_insn = NULL;
875862bf 8602 pool->insns = BITMAP_ALLOC (NULL);
8603 pool->size = 0;
93e0956b 8604 pool->emit_pool_after = NULL;
875862bf 8605
8606 return pool;
8607}
0756cebb 8608
8609/* Create new constant pool covering instructions starting at INSN
8610 and chain it to the end of POOL_LIST. */
8611
8612static struct constant_pool *
93e0956b 8613s390_start_pool (struct constant_pool **pool_list, rtx_insn *insn)
0756cebb 8614{
8615 struct constant_pool *pool, **prev;
0756cebb 8616
c2c1332a 8617 pool = s390_alloc_pool ();
0756cebb 8618 pool->first_insn = insn;
96be3ab6 8619
0756cebb 8620 for (prev = pool_list; *prev; prev = &(*prev)->next)
8621 ;
8622 *prev = pool;
8623
8624 return pool;
8625}
8626
96be3ab6 8627/* End range of instructions covered by POOL at INSN and emit
8628 placeholder insn representing the pool. */
0756cebb 8629
8630static void
93e0956b 8631s390_end_pool (struct constant_pool *pool, rtx_insn *insn)
0756cebb 8632{
96be3ab6 8633 rtx pool_size = GEN_INT (pool->size + 8 /* alignment slop */);
8634
8635 if (!insn)
8636 insn = get_last_insn ();
8637
8638 pool->pool_insn = emit_insn_after (gen_pool (pool_size), insn);
8639 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
8640}
8641
8642/* Add INSN to the list of insns covered by POOL. */
8643
8644static void
b40da9a7 8645s390_add_pool_insn (struct constant_pool *pool, rtx insn)
96be3ab6 8646{
8647 bitmap_set_bit (pool->insns, INSN_UID (insn));
0756cebb 8648}
8649
8650/* Return pool out of POOL_LIST that covers INSN. */
8651
8652static struct constant_pool *
b40da9a7 8653s390_find_pool (struct constant_pool *pool_list, rtx insn)
0756cebb 8654{
0756cebb 8655 struct constant_pool *pool;
8656
0756cebb 8657 for (pool = pool_list; pool; pool = pool->next)
96be3ab6 8658 if (bitmap_bit_p (pool->insns, INSN_UID (insn)))
0756cebb 8659 break;
8660
8661 return pool;
8662}
8663
96be3ab6 8664/* Add constant VAL of mode MODE to the constant pool POOL. */
0756cebb 8665
96be3ab6 8666static void
3754d046 8667s390_add_constant (struct constant_pool *pool, rtx val, machine_mode mode)
0756cebb 8668{
8669 struct constant *c;
0756cebb 8670 int i;
8671
8672 for (i = 0; i < NR_C_MODES; i++)
8673 if (constant_modes[i] == mode)
8674 break;
32eda510 8675 gcc_assert (i != NR_C_MODES);
0756cebb 8676
8677 for (c = pool->constants[i]; c != NULL; c = c->next)
8678 if (rtx_equal_p (val, c->value))
8679 break;
8680
8681 if (c == NULL)
8682 {
8683 c = (struct constant *) xmalloc (sizeof *c);
8684 c->value = val;
8685 c->label = gen_label_rtx ();
8686 c->next = pool->constants[i];
8687 pool->constants[i] = c;
8688 pool->size += GET_MODE_SIZE (mode);
8689 }
96be3ab6 8690}
0756cebb 8691
1ed7a160 8692/* Return an rtx that represents the offset of X from the start of
8693 pool POOL. */
8694
8695static rtx
8696s390_pool_offset (struct constant_pool *pool, rtx x)
8697{
8698 rtx label;
8699
8700 label = gen_rtx_LABEL_REF (GET_MODE (x), pool->label);
8701 x = gen_rtx_UNSPEC (GET_MODE (x), gen_rtvec (2, x, label),
8702 UNSPEC_POOL_OFFSET);
8703 return gen_rtx_CONST (GET_MODE (x), x);
8704}
8705
96be3ab6 8706/* Find constant VAL of mode MODE in the constant pool POOL.
8707 Return an RTX describing the distance from the start of
8708 the pool to the location of the new constant. */
f81e845f 8709
96be3ab6 8710static rtx
b40da9a7 8711s390_find_constant (struct constant_pool *pool, rtx val,
3754d046 8712 machine_mode mode)
96be3ab6 8713{
8714 struct constant *c;
96be3ab6 8715 int i;
f81e845f 8716
96be3ab6 8717 for (i = 0; i < NR_C_MODES; i++)
8718 if (constant_modes[i] == mode)
8719 break;
32eda510 8720 gcc_assert (i != NR_C_MODES);
f81e845f 8721
96be3ab6 8722 for (c = pool->constants[i]; c != NULL; c = c->next)
8723 if (rtx_equal_p (val, c->value))
8724 break;
f81e845f 8725
32eda510 8726 gcc_assert (c);
f81e845f 8727
1ed7a160 8728 return s390_pool_offset (pool, gen_rtx_LABEL_REF (Pmode, c->label));
0756cebb 8729}
8730
875862bf 8731/* Check whether INSN is an execute. Return the label_ref to its
8732 execute target template if so, NULL_RTX otherwise. */
8733
8734static rtx
8735s390_execute_label (rtx insn)
8736{
db7a90aa 8737 if (INSN_P (insn)
875862bf 8738 && GET_CODE (PATTERN (insn)) == PARALLEL
8739 && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == UNSPEC
db7a90aa 8740 && (XINT (XVECEXP (PATTERN (insn), 0, 0), 1) == UNSPEC_EXECUTE
8741 || XINT (XVECEXP (PATTERN (insn), 0, 0), 1) == UNSPEC_EXECUTE_JUMP))
8742 {
8743 if (XINT (XVECEXP (PATTERN (insn), 0, 0), 1) == UNSPEC_EXECUTE)
8744 return XVECEXP (XVECEXP (PATTERN (insn), 0, 0), 0, 2);
8745 else
8746 {
8747 gcc_assert (JUMP_P (insn));
8748 /* For jump insns as execute target:
8749 - There is one operand less in the parallel (the
8750 modification register of the execute is always 0).
8751 - The execute target label is wrapped into an
8752 if_then_else in order to hide it from jump analysis. */
8753 return XEXP (XVECEXP (XVECEXP (PATTERN (insn), 0, 0), 0, 0), 0);
8754 }
8755 }
875862bf 8756
8757 return NULL_RTX;
8758}
8759
d345b493 8760/* Find execute target for INSN in the constant pool POOL.
8761 Return an RTX describing the distance from the start of
8762 the pool to the location of the execute target. */
8763
8764static rtx
8765s390_find_execute (struct constant_pool *pool, rtx insn)
8766{
8767 struct constant *c;
d345b493 8768
8769 for (c = pool->execute; c != NULL; c = c->next)
8770 if (INSN_UID (insn) == INSN_UID (c->value))
8771 break;
8772
32eda510 8773 gcc_assert (c);
d345b493 8774
1ed7a160 8775 return s390_pool_offset (pool, gen_rtx_LABEL_REF (Pmode, c->label));
d345b493 8776}
8777
875862bf 8778/* For an execute INSN, extract the execute target template. */
d345b493 8779
8780static rtx
875862bf 8781s390_execute_target (rtx insn)
d345b493 8782{
875862bf 8783 rtx pattern = PATTERN (insn);
8784 gcc_assert (s390_execute_label (insn));
d345b493 8785
8786 if (XVECLEN (pattern, 0) == 2)
8787 {
8788 pattern = copy_rtx (XVECEXP (pattern, 0, 1));
8789 }
8790 else
8791 {
8792 rtvec vec = rtvec_alloc (XVECLEN (pattern, 0) - 1);
8793 int i;
8794
8795 for (i = 0; i < XVECLEN (pattern, 0) - 1; i++)
8796 RTVEC_ELT (vec, i) = copy_rtx (XVECEXP (pattern, 0, i + 1));
8797
8798 pattern = gen_rtx_PARALLEL (VOIDmode, vec);
8799 }
8800
8801 return pattern;
8802}
8803
8804/* Indicate that INSN cannot be duplicated. This is the case for
8805 execute insns that carry a unique label. */
8806
8807static bool
18282db0 8808s390_cannot_copy_insn_p (rtx_insn *insn)
d345b493 8809{
8810 rtx label = s390_execute_label (insn);
8811 return label && label != const0_rtx;
8812}
8813
c2c1332a 8814/* Dump out the constants in POOL. If REMOTE_LABEL is true,
8815 do not emit the pool base label. */
0756cebb 8816
d345b493 8817static void
c2c1332a 8818s390_dump_pool (struct constant_pool *pool, bool remote_label)
0756cebb 8819{
8820 struct constant *c;
93e0956b 8821 rtx_insn *insn = pool->pool_insn;
0756cebb 8822 int i;
8823
d345b493 8824 /* Switch to rodata section. */
f5edbf1d 8825 insn = emit_insn_after (gen_pool_section_start (), insn);
8826 INSN_ADDRESSES_NEW (insn, -1);
d345b493 8827
8828 /* Ensure minimum pool alignment. */
f5edbf1d 8829 insn = emit_insn_after (gen_pool_align (GEN_INT (8)), insn);
0756cebb 8830 INSN_ADDRESSES_NEW (insn, -1);
8831
d345b493 8832 /* Emit pool base label. */
c2c1332a 8833 if (!remote_label)
8834 {
8835 insn = emit_label_after (pool->label, insn);
8836 INSN_ADDRESSES_NEW (insn, -1);
8837 }
0756cebb 8838
8839 /* Dump constants in descending alignment requirement order,
8840 ensuring proper alignment for every constant. */
8841 for (i = 0; i < NR_C_MODES; i++)
8842 for (c = pool->constants[i]; c; c = c->next)
8843 {
12ef3745 8844 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
b2ed6df1 8845 rtx value = copy_rtx (c->value);
96be3ab6 8846 if (GET_CODE (value) == CONST
8847 && GET_CODE (XEXP (value, 0)) == UNSPEC
12ef3745 8848 && XINT (XEXP (value, 0), 1) == UNSPEC_LTREL_OFFSET
96be3ab6 8849 && XVECLEN (XEXP (value, 0), 0) == 1)
1ed7a160 8850 value = s390_pool_offset (pool, XVECEXP (XEXP (value, 0), 0, 0));
96be3ab6 8851
0756cebb 8852 insn = emit_label_after (c->label, insn);
8853 INSN_ADDRESSES_NEW (insn, -1);
df82fb76 8854
f588eb9f 8855 value = gen_rtx_UNSPEC_VOLATILE (constant_modes[i],
df82fb76 8856 gen_rtvec (1, value),
8857 UNSPECV_POOL_ENTRY);
8858 insn = emit_insn_after (value, insn);
0756cebb 8859 INSN_ADDRESSES_NEW (insn, -1);
8860 }
8861
d345b493 8862 /* Ensure minimum alignment for instructions. */
8863 insn = emit_insn_after (gen_pool_align (GEN_INT (2)), insn);
0756cebb 8864 INSN_ADDRESSES_NEW (insn, -1);
8865
d345b493 8866 /* Output in-pool execute template insns. */
8867 for (c = pool->execute; c; c = c->next)
8868 {
d345b493 8869 insn = emit_label_after (c->label, insn);
8870 INSN_ADDRESSES_NEW (insn, -1);
8871
8872 insn = emit_insn_after (s390_execute_target (c->value), insn);
8873 INSN_ADDRESSES_NEW (insn, -1);
8874 }
8875
8876 /* Switch back to previous section. */
f5edbf1d 8877 insn = emit_insn_after (gen_pool_section_end (), insn);
8878 INSN_ADDRESSES_NEW (insn, -1);
d345b493 8879
0756cebb 8880 insn = emit_barrier_after (insn);
8881 INSN_ADDRESSES_NEW (insn, -1);
8882
96be3ab6 8883 /* Remove placeholder insn. */
8884 remove_insn (pool->pool_insn);
d345b493 8885}
8886
0756cebb 8887/* Free all memory used by POOL. */
8888
8889static void
b40da9a7 8890s390_free_pool (struct constant_pool *pool)
0756cebb 8891{
d345b493 8892 struct constant *c, *next;
0756cebb 8893 int i;
8894
8895 for (i = 0; i < NR_C_MODES; i++)
d345b493 8896 for (c = pool->constants[i]; c; c = next)
8897 {
8898 next = c->next;
8899 free (c);
8900 }
8901
8902 for (c = pool->execute; c; c = next)
0756cebb 8903 {
d345b493 8904 next = c->next;
8905 free (c);
0756cebb 8906 }
8907
4d6e8511 8908 BITMAP_FREE (pool->insns);
0756cebb 8909 free (pool);
f81e845f 8910}
0756cebb 8911
0756cebb 8912
c2c1332a 8913/* Collect main literal pool. Return NULL on overflow. */
8914
8915static struct constant_pool *
8916s390_mainpool_start (void)
8917{
8918 struct constant_pool *pool;
93e0956b 8919 rtx_insn *insn;
c2c1332a 8920
8921 pool = s390_alloc_pool ();
8922
8923 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8924 {
aa90bb35 8925 if (NONJUMP_INSN_P (insn)
20074f87 8926 && GET_CODE (PATTERN (insn)) == SET
8927 && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC_VOLATILE
8928 && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPECV_MAIN_POOL)
c2c1332a 8929 {
7a64c761 8930 /* There might be two main_pool instructions if base_reg
8931 is call-clobbered; one for shrink-wrapped code and one
8932 for the rest. We want to keep the first. */
8933 if (pool->pool_insn)
8934 {
8935 insn = PREV_INSN (insn);
8936 delete_insn (NEXT_INSN (insn));
8937 continue;
8938 }
c2c1332a 8939 pool->pool_insn = insn;
8940 }
8941
f5edbf1d 8942 if (NONJUMP_INSN_P (insn) || CALL_P (insn))
c2c1332a 8943 {
8944 rtx pool_ref = NULL_RTX;
50a42dec 8945 find_constant_pool_ref (insn, &pool_ref);
c2c1332a 8946 if (pool_ref)
8947 {
8948 rtx constant = get_pool_constant (pool_ref);
3754d046 8949 machine_mode mode = get_pool_mode (pool_ref);
c2c1332a 8950 s390_add_constant (pool, constant, mode);
8951 }
8952 }
86428198 8953
8954 /* If hot/cold partitioning is enabled we have to make sure that
8955 the literal pool is emitted in the same section where the
8956 initialization of the literal pool base pointer takes place.
8957 emit_pool_after is only used in the non-overflow case on non
8958 Z cpus where we can emit the literal pool at the end of the
8959 function body within the text section. */
8960 if (NOTE_P (insn)
7338c728 8961 && NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS
8962 && !pool->emit_pool_after)
8963 pool->emit_pool_after = PREV_INSN (insn);
c2c1332a 8964 }
8965
32eda510 8966 gcc_assert (pool->pool_insn || pool->size == 0);
c2c1332a 8967
8968 if (pool->size >= 4096)
8969 {
7de9f7aa 8970 /* We're going to chunkify the pool, so remove the main
8971 pool placeholder insn. */
8972 remove_insn (pool->pool_insn);
8973
c2c1332a 8974 s390_free_pool (pool);
8975 pool = NULL;
8976 }
8977
86428198 8978 /* If the functions ends with the section where the literal pool
8979 should be emitted set the marker to its end. */
7338c728 8980 if (pool && !pool->emit_pool_after)
86428198 8981 pool->emit_pool_after = get_last_insn ();
8982
c2c1332a 8983 return pool;
8984}
8985
8986/* POOL holds the main literal pool as collected by s390_mainpool_start.
8987 Modify the current function to output the pool constants as well as
20074f87 8988 the pool register setup instruction. */
c2c1332a 8989
8990static void
20074f87 8991s390_mainpool_finish (struct constant_pool *pool)
c2c1332a 8992{
4fed3f99 8993 rtx base_reg = cfun->machine->base_reg;
f5edbf1d 8994 rtx set;
8995 rtx_insn *insn;
c2c1332a 8996
8997 /* If the pool is empty, we're done. */
8998 if (pool->size == 0)
8999 {
4fed3f99 9000 /* We don't actually need a base register after all. */
9001 cfun->machine->base_reg = NULL_RTX;
9002
9003 if (pool->pool_insn)
9004 remove_insn (pool->pool_insn);
c2c1332a 9005 s390_free_pool (pool);
9006 return;
9007 }
9008
9009 /* We need correct insn addresses. */
9010 shorten_branches (get_insns ());
9011
f5edbf1d 9012 /* Use a LARL to load the pool register. The pool is
c2c1332a 9013 located in the .rodata section, so we emit it after the function. */
f5edbf1d 9014 set = gen_main_base_64 (base_reg, pool->label);
9015 insn = emit_insn_after (set, pool->pool_insn);
9016 INSN_ADDRESSES_NEW (insn, -1);
9017 remove_insn (pool->pool_insn);
c2c1332a 9018
f5edbf1d 9019 insn = get_last_insn ();
9020 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
9021 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
c2c1332a 9022
f5edbf1d 9023 s390_dump_pool (pool, 0);
c2c1332a 9024
9025 /* Replace all literal pool references. */
9026
91a55c11 9027 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
c2c1332a 9028 {
aa90bb35 9029 if (NONJUMP_INSN_P (insn) || CALL_P (insn))
9f522e0c 9030 {
9031 rtx addr, pool_ref = NULL_RTX;
50a42dec 9032 find_constant_pool_ref (insn, &pool_ref);
9f522e0c 9033 if (pool_ref)
9034 {
d345b493 9035 if (s390_execute_label (insn))
9036 addr = s390_find_execute (pool, insn);
9037 else
9038 addr = s390_find_constant (pool, get_pool_constant (pool_ref),
9039 get_pool_mode (pool_ref));
9040
50a42dec 9041 replace_constant_pool_ref (insn, pool_ref, addr);
9f522e0c 9042 INSN_CODE (insn) = -1;
9043 }
9044 }
c2c1332a 9045 }
9046
9047
9048 /* Free the pool. */
9049 s390_free_pool (pool);
9050}
9051
20074f87 9052/* Chunkify the literal pool. */
4673c1a0 9053
0756cebb 9054#define S390_POOL_CHUNK_MIN 0xc00
9055#define S390_POOL_CHUNK_MAX 0xe00
9056
f81e845f 9057static struct constant_pool *
20074f87 9058s390_chunkify_start (void)
4673c1a0 9059{
0756cebb 9060 struct constant_pool *curr_pool = NULL, *pool_list = NULL;
0756cebb 9061 bitmap far_labels;
93e0956b 9062 rtx_insn *insn;
4673c1a0 9063
9a2a66ae 9064 /* We need correct insn addresses. */
9065
9066 shorten_branches (get_insns ());
9067
12ef3745 9068 /* Scan all insns and move literals to pool chunks. */
479ca6e8 9069
479ca6e8 9070 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4673c1a0 9071 {
f5edbf1d 9072 if (NONJUMP_INSN_P (insn) || CALL_P (insn))
0756cebb 9073 {
96be3ab6 9074 rtx pool_ref = NULL_RTX;
50a42dec 9075 find_constant_pool_ref (insn, &pool_ref);
0756cebb 9076 if (pool_ref)
9077 {
12ef3745 9078 rtx constant = get_pool_constant (pool_ref);
3754d046 9079 machine_mode mode = get_pool_mode (pool_ref);
12ef3745 9080
0756cebb 9081 if (!curr_pool)
9082 curr_pool = s390_start_pool (&pool_list, insn);
9083
12ef3745 9084 s390_add_constant (curr_pool, constant, mode);
96be3ab6 9085 s390_add_pool_insn (curr_pool, insn);
0756cebb 9086 }
9087 }
9088
91f71fa3 9089 if (JUMP_P (insn) || JUMP_TABLE_DATA_P (insn) || LABEL_P (insn))
12ef3745 9090 {
9091 if (curr_pool)
9092 s390_add_pool_insn (curr_pool, insn);
12ef3745 9093 }
96be3ab6 9094
f5edbf1d 9095 if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION)
9096 continue;
86428198 9097
f81e845f 9098 if (!curr_pool
0756cebb 9099 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn)
f5edbf1d 9100 || INSN_ADDRESSES (INSN_UID (insn)) == -1)
4673c1a0 9101 continue;
479ca6e8 9102
f5edbf1d 9103 if (curr_pool->size < S390_POOL_CHUNK_MAX)
9104 continue;
96be3ab6 9105
f5edbf1d 9106 s390_end_pool (curr_pool, NULL);
9107 curr_pool = NULL;
4673c1a0 9108 }
9fa6d5d9 9109
96be3ab6 9110 if (curr_pool)
93e0956b 9111 s390_end_pool (curr_pool, NULL);
0756cebb 9112
f81e845f 9113 /* Find all labels that are branched into
479ca6e8 9114 from an insn belonging to a different chunk. */
9fa6d5d9 9115
4d6e8511 9116 far_labels = BITMAP_ALLOC (NULL);
a8ef833a 9117
479ca6e8 9118 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4673c1a0 9119 {
c86d86ff 9120 rtx_jump_table_data *table;
245402e7 9121
0756cebb 9122 /* Labels marked with LABEL_PRESERVE_P can be target
9123 of non-local jumps, so we have to mark them.
9124 The same holds for named labels.
9125
9126 Don't do that, however, if it is the label before
9127 a jump table. */
9128
aa90bb35 9129 if (LABEL_P (insn)
0756cebb 9130 && (LABEL_PRESERVE_P (insn) || LABEL_NAME (insn)))
9131 {
93e0956b 9132 rtx_insn *vec_insn = NEXT_INSN (insn);
77985f1a 9133 if (! vec_insn || ! JUMP_TABLE_DATA_P (vec_insn))
0756cebb 9134 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (insn));
9135 }
245402e7 9136 /* Check potential targets in a table jump (casesi_jump). */
9137 else if (tablejump_p (insn, NULL, &table))
9138 {
9139 rtx vec_pat = PATTERN (table);
9140 int i, diff_p = GET_CODE (vec_pat) == ADDR_DIFF_VEC;
9141
9142 for (i = 0; i < XVECLEN (vec_pat, diff_p); i++)
9143 {
9144 rtx label = XEXP (XVECEXP (vec_pat, diff_p, i), 0);
0756cebb 9145
245402e7 9146 if (s390_find_pool (pool_list, label)
9147 != s390_find_pool (pool_list, insn))
9148 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
9149 }
9150 }
9151 /* If we have a direct jump (conditional or unconditional),
9152 check all potential targets. */
aa90bb35 9153 else if (JUMP_P (insn))
479ca6e8 9154 {
245402e7 9155 rtx pat = PATTERN (insn);
0cd9a9a9 9156
245402e7 9157 if (GET_CODE (pat) == PARALLEL)
3c482144 9158 pat = XVECEXP (pat, 0, 0);
9159
245402e7 9160 if (GET_CODE (pat) == SET)
9161 {
96be3ab6 9162 rtx label = JUMP_LABEL (insn);
7a64c761 9163 if (label && !ANY_RETURN_P (label))
479ca6e8 9164 {
245402e7 9165 if (s390_find_pool (pool_list, label)
0756cebb 9166 != s390_find_pool (pool_list, insn))
9167 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
479ca6e8 9168 }
0756cebb 9169 }
245402e7 9170 }
4673c1a0 9171 }
9fa6d5d9 9172
0756cebb 9173 /* Insert base register reload insns before every pool. */
9174
9175 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
96be3ab6 9176 {
f5edbf1d 9177 rtx new_insn = gen_reload_base_64 (cfun->machine->base_reg,
9178 curr_pool->label);
93e0956b 9179 rtx_insn *insn = curr_pool->first_insn;
96be3ab6 9180 INSN_ADDRESSES_NEW (emit_insn_before (new_insn, insn), -1);
9181 }
0756cebb 9182
9183 /* Insert base register reload insns at every far label. */
479ca6e8 9184
479ca6e8 9185 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
aa90bb35 9186 if (LABEL_P (insn)
9f522e0c 9187 && bitmap_bit_p (far_labels, CODE_LABEL_NUMBER (insn)))
0756cebb 9188 {
9189 struct constant_pool *pool = s390_find_pool (pool_list, insn);
9190 if (pool)
9191 {
f5edbf1d 9192 rtx new_insn = gen_reload_base_64 (cfun->machine->base_reg,
9193 pool->label);
96be3ab6 9194 INSN_ADDRESSES_NEW (emit_insn_after (new_insn, insn), -1);
0756cebb 9195 }
9196 }
9197
96be3ab6 9198
4d6e8511 9199 BITMAP_FREE (far_labels);
479ca6e8 9200
479ca6e8 9201
9202 /* Recompute insn addresses. */
9203
9204 init_insn_lengths ();
9205 shorten_branches (get_insns ());
4673c1a0 9206
96be3ab6 9207 return pool_list;
9208}
4673c1a0 9209
96be3ab6 9210/* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
f81e845f 9211 After we have decided to use this list, finish implementing
20074f87 9212 all changes to the current function as required. */
f81e845f 9213
96be3ab6 9214static void
20074f87 9215s390_chunkify_finish (struct constant_pool *pool_list)
96be3ab6 9216{
96be3ab6 9217 struct constant_pool *curr_pool = NULL;
93e0956b 9218 rtx_insn *insn;
f81e845f 9219
9220
96be3ab6 9221 /* Replace all literal pool references. */
9222
f81e845f 9223 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
96be3ab6 9224 {
9225 curr_pool = s390_find_pool (pool_list, insn);
9226 if (!curr_pool)
9227 continue;
9228
aa90bb35 9229 if (NONJUMP_INSN_P (insn) || CALL_P (insn))
9f522e0c 9230 {
9231 rtx addr, pool_ref = NULL_RTX;
50a42dec 9232 find_constant_pool_ref (insn, &pool_ref);
9f522e0c 9233 if (pool_ref)
9234 {
d345b493 9235 if (s390_execute_label (insn))
9236 addr = s390_find_execute (curr_pool, insn);
9237 else
9238 addr = s390_find_constant (curr_pool,
9239 get_pool_constant (pool_ref),
9240 get_pool_mode (pool_ref));
9241
50a42dec 9242 replace_constant_pool_ref (insn, pool_ref, addr);
9f522e0c 9243 INSN_CODE (insn) = -1;
9244 }
9245 }
96be3ab6 9246 }
9247
9248 /* Dump out all literal pools. */
f81e845f 9249
96be3ab6 9250 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
c2c1332a 9251 s390_dump_pool (curr_pool, 0);
f81e845f 9252
96be3ab6 9253 /* Free pool list. */
9254
9255 while (pool_list)
9256 {
9257 struct constant_pool *next = pool_list->next;
9258 s390_free_pool (pool_list);
9259 pool_list = next;
9260 }
9261}
9262
74d2529d 9263/* Output the constant pool entry EXP in mode MODE with alignment ALIGN. */
df82fb76 9264
9265void
3754d046 9266s390_output_pool_entry (rtx exp, machine_mode mode, unsigned int align)
df82fb76 9267{
df82fb76 9268 switch (GET_MODE_CLASS (mode))
9269 {
9270 case MODE_FLOAT:
36868490 9271 case MODE_DECIMAL_FLOAT:
32eda510 9272 gcc_assert (GET_CODE (exp) == CONST_DOUBLE);
df82fb76 9273
0f97e0f5 9274 assemble_real (*CONST_DOUBLE_REAL_VALUE (exp),
9275 as_a <scalar_float_mode> (mode), align);
df82fb76 9276 break;
9277
9278 case MODE_INT:
74d2529d 9279 assemble_integer (exp, GET_MODE_SIZE (mode), align, 1);
af2a449c 9280 mark_symbol_refs_as_used (exp);
df82fb76 9281 break;
9282
76a4c804 9283 case MODE_VECTOR_INT:
9284 case MODE_VECTOR_FLOAT:
9285 {
9286 int i;
9287 machine_mode inner_mode;
9288 gcc_assert (GET_CODE (exp) == CONST_VECTOR);
9289
9290 inner_mode = GET_MODE_INNER (GET_MODE (exp));
9291 for (i = 0; i < XVECLEN (exp, 0); i++)
9292 s390_output_pool_entry (XVECEXP (exp, 0, i),
9293 inner_mode,
9294 i == 0
9295 ? align
9296 : GET_MODE_BITSIZE (inner_mode));
9297 }
9298 break;
9299
df82fb76 9300 default:
32eda510 9301 gcc_unreachable ();
df82fb76 9302 }
9303}
9304
9305
875862bf 9306/* Return an RTL expression representing the value of the return address
9307 for the frame COUNT steps up from the current frame. FRAME is the
9308 frame pointer of that frame. */
0756cebb 9309
875862bf 9310rtx
9311s390_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
0756cebb 9312{
875862bf 9313 int offset;
9314 rtx addr;
96be3ab6 9315
875862bf 9316 /* Without backchain, we fail for all but the current frame. */
9a2a66ae 9317
875862bf 9318 if (!TARGET_BACKCHAIN && count > 0)
9319 return NULL_RTX;
9a2a66ae 9320
875862bf 9321 /* For the current frame, we need to make sure the initial
9322 value of RETURN_REGNUM is actually saved. */
9a2a66ae 9323
875862bf 9324 if (count == 0)
f5edbf1d 9325 return get_hard_reg_initial_val (Pmode, RETURN_REGNUM);
9a2a66ae 9326
875862bf 9327 if (TARGET_PACKED_STACK)
b5fdc416 9328 offset = -2 * UNITS_PER_LONG;
875862bf 9329 else
b5fdc416 9330 offset = RETURN_REGNUM * UNITS_PER_LONG;
9a2a66ae 9331
29c05e22 9332 addr = plus_constant (Pmode, frame, offset);
875862bf 9333 addr = memory_address (Pmode, addr);
9334 return gen_rtx_MEM (Pmode, addr);
9335}
9a2a66ae 9336
875862bf 9337/* Return an RTL expression representing the back chain stored in
9338 the current stack frame. */
5fe74ca1 9339
875862bf 9340rtx
9341s390_back_chain_rtx (void)
9342{
9343 rtx chain;
5fe74ca1 9344
875862bf 9345 gcc_assert (TARGET_BACKCHAIN);
5fe74ca1 9346
875862bf 9347 if (TARGET_PACKED_STACK)
29c05e22 9348 chain = plus_constant (Pmode, stack_pointer_rtx,
b5fdc416 9349 STACK_POINTER_OFFSET - UNITS_PER_LONG);
875862bf 9350 else
9351 chain = stack_pointer_rtx;
5fe74ca1 9352
875862bf 9353 chain = gen_rtx_MEM (Pmode, chain);
9354 return chain;
9355}
9a2a66ae 9356
875862bf 9357/* Find first call clobbered register unused in a function.
9358 This could be used as base register in a leaf function
9359 or for holding the return address before epilogue. */
9a2a66ae 9360
875862bf 9361static int
9362find_unused_clobbered_reg (void)
9363{
9364 int i;
9365 for (i = 0; i < 6; i++)
3072d30e 9366 if (!df_regs_ever_live_p (i))
875862bf 9367 return i;
9368 return 0;
9369}
9a2a66ae 9370
1e639cb0 9371
ffead1ca 9372/* Helper function for s390_regs_ever_clobbered. Sets the fields in DATA for all
1e639cb0 9373 clobbered hard regs in SETREG. */
9374
9375static void
81a410b1 9376s390_reg_clobbered_rtx (rtx setreg, const_rtx set_insn ATTRIBUTE_UNUSED, void *data)
1e639cb0 9377{
ff4ce128 9378 char *regs_ever_clobbered = (char *)data;
1e639cb0 9379 unsigned int i, regno;
3754d046 9380 machine_mode mode = GET_MODE (setreg);
1e639cb0 9381
9382 if (GET_CODE (setreg) == SUBREG)
9383 {
9384 rtx inner = SUBREG_REG (setreg);
5ada7a14 9385 if (!GENERAL_REG_P (inner) && !FP_REG_P (inner))
1e639cb0 9386 return;
9387 regno = subreg_regno (setreg);
9388 }
5ada7a14 9389 else if (GENERAL_REG_P (setreg) || FP_REG_P (setreg))
1e639cb0 9390 regno = REGNO (setreg);
9391 else
9392 return;
9393
9394 for (i = regno;
16b9e38b 9395 i < end_hard_regno (mode, regno);
1e639cb0 9396 i++)
9397 regs_ever_clobbered[i] = 1;
9398}
9399
9400/* Walks through all basic blocks of the current function looking
9401 for clobbered hard regs using s390_reg_clobbered_rtx. The fields
9402 of the passed integer array REGS_EVER_CLOBBERED are set to one for
9403 each of those regs. */
9404
9405static void
ff4ce128 9406s390_regs_ever_clobbered (char regs_ever_clobbered[])
1e639cb0 9407{
9408 basic_block cur_bb;
93e0956b 9409 rtx_insn *cur_insn;
1e639cb0 9410 unsigned int i;
9411
ff4ce128 9412 memset (regs_ever_clobbered, 0, 32);
1e639cb0 9413
9414 /* For non-leaf functions we have to consider all call clobbered regs to be
9415 clobbered. */
d5bf7b64 9416 if (!crtl->is_leaf)
1e639cb0 9417 {
5ada7a14 9418 for (i = 0; i < 32; i++)
1e639cb0 9419 regs_ever_clobbered[i] = call_really_used_regs[i];
9420 }
9421
9422 /* Make the "magic" eh_return registers live if necessary. For regs_ever_live
9423 this work is done by liveness analysis (mark_regs_live_at_end).
9424 Special care is needed for functions containing landing pads. Landing pads
9425 may use the eh registers, but the code which sets these registers is not
9426 contained in that function. Hence s390_regs_ever_clobbered is not able to
9427 deal with this automatically. */
18d50ae6 9428 if (crtl->calls_eh_return || cfun->machine->has_landing_pad_p)
1e639cb0 9429 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM ; i++)
ffead1ca 9430 if (crtl->calls_eh_return
9431 || (cfun->machine->has_landing_pad_p
3072d30e 9432 && df_regs_ever_live_p (EH_RETURN_DATA_REGNO (i))))
220be973 9433 regs_ever_clobbered[EH_RETURN_DATA_REGNO (i)] = 1;
1e639cb0 9434
9435 /* For nonlocal gotos all call-saved registers have to be saved.
9436 This flag is also set for the unwinding code in libgcc.
9437 See expand_builtin_unwind_init. For regs_ever_live this is done by
9438 reload. */
ff4ce128 9439 if (crtl->saves_all_registers)
5ada7a14 9440 for (i = 0; i < 32; i++)
1e639cb0 9441 if (!call_really_used_regs[i])
9442 regs_ever_clobbered[i] = 1;
9443
fc00614f 9444 FOR_EACH_BB_FN (cur_bb, cfun)
1e639cb0 9445 {
9446 FOR_BB_INSNS (cur_bb, cur_insn)
9447 {
ff4ce128 9448 rtx pat;
9449
9450 if (!INSN_P (cur_insn))
9451 continue;
9452
9453 pat = PATTERN (cur_insn);
9454
9455 /* Ignore GPR restore insns. */
9456 if (epilogue_completed && RTX_FRAME_RELATED_P (cur_insn))
9457 {
9458 if (GET_CODE (pat) == SET
9459 && GENERAL_REG_P (SET_DEST (pat)))
9460 {
9461 /* lgdr */
9462 if (GET_MODE (SET_SRC (pat)) == DImode
9463 && FP_REG_P (SET_SRC (pat)))
9464 continue;
9465
9466 /* l / lg */
9467 if (GET_CODE (SET_SRC (pat)) == MEM)
9468 continue;
9469 }
9470
9471 /* lm / lmg */
9472 if (GET_CODE (pat) == PARALLEL
9473 && load_multiple_operation (pat, VOIDmode))
9474 continue;
9475 }
9476
9477 note_stores (pat,
9478 s390_reg_clobbered_rtx,
9479 regs_ever_clobbered);
1e639cb0 9480 }
9481 }
9482}
9483
ffead1ca 9484/* Determine the frame area which actually has to be accessed
9485 in the function epilogue. The values are stored at the
875862bf 9486 given pointers AREA_BOTTOM (address of the lowest used stack
ffead1ca 9487 address) and AREA_TOP (address of the first item which does
875862bf 9488 not belong to the stack frame). */
5fe74ca1 9489
875862bf 9490static void
9491s390_frame_area (int *area_bottom, int *area_top)
9492{
9493 int b, t;
5fe74ca1 9494
875862bf 9495 b = INT_MAX;
9496 t = INT_MIN;
67928721 9497
9498 if (cfun_frame_layout.first_restore_gpr != -1)
9499 {
9500 b = (cfun_frame_layout.gprs_offset
b5fdc416 9501 + cfun_frame_layout.first_restore_gpr * UNITS_PER_LONG);
67928721 9502 t = b + (cfun_frame_layout.last_restore_gpr
b5fdc416 9503 - cfun_frame_layout.first_restore_gpr + 1) * UNITS_PER_LONG;
67928721 9504 }
9505
9506 if (TARGET_64BIT && cfun_save_high_fprs_p)
9507 {
9508 b = MIN (b, cfun_frame_layout.f8_offset);
9509 t = MAX (t, (cfun_frame_layout.f8_offset
9510 + cfun_frame_layout.high_fprs * 8));
9511 }
9512
9513 if (!TARGET_64BIT)
29439367 9514 {
6a2469fe 9515 if (cfun_fpr_save_p (FPR4_REGNUM))
67928721 9516 {
29439367 9517 b = MIN (b, cfun_frame_layout.f4_offset);
9518 t = MAX (t, cfun_frame_layout.f4_offset + 8);
67928721 9519 }
6a2469fe 9520 if (cfun_fpr_save_p (FPR6_REGNUM))
29439367 9521 {
9522 b = MIN (b, cfun_frame_layout.f4_offset + 8);
9523 t = MAX (t, cfun_frame_layout.f4_offset + 16);
9524 }
9525 }
67928721 9526 *area_bottom = b;
9527 *area_top = t;
9528}
ff4ce128 9529/* Update gpr_save_slots in the frame layout trying to make use of
9530 FPRs as GPR save slots.
9531 This is a helper routine of s390_register_info. */
8b4a4127 9532
9533static void
ff4ce128 9534s390_register_info_gprtofpr ()
8b4a4127 9535{
ff4ce128 9536 int save_reg_slot = FPR0_REGNUM;
8b4a4127 9537 int i, j;
8b4a4127 9538
ff4ce128 9539 if (!TARGET_Z10 || !TARGET_HARD_FLOAT || !crtl->is_leaf)
9540 return;
1e639cb0 9541
a8078ffb 9542 /* builtin_eh_return needs to be able to modify the return address
9543 on the stack. It could also adjust the FPR save slot instead but
9544 is it worth the trouble?! */
9545 if (crtl->calls_eh_return)
9546 return;
9547
ff4ce128 9548 for (i = 15; i >= 6; i--)
5ada7a14 9549 {
1d3cea74 9550 if (cfun_gpr_save_slot (i) == SAVE_SLOT_NONE)
ff4ce128 9551 continue;
68bc0408 9552
ff4ce128 9553 /* Advance to the next FP register which can be used as a
9554 GPR save slot. */
9555 while ((!call_really_used_regs[save_reg_slot]
9556 || df_regs_ever_live_p (save_reg_slot)
9557 || cfun_fpr_save_p (save_reg_slot))
9558 && FP_REGNO_P (save_reg_slot))
9559 save_reg_slot++;
9560 if (!FP_REGNO_P (save_reg_slot))
9561 {
9562 /* We only want to use ldgr/lgdr if we can get rid of
9563 stm/lm entirely. So undo the gpr slot allocation in
9564 case we ran out of FPR save slots. */
9565 for (j = 6; j <= 15; j++)
9566 if (FP_REGNO_P (cfun_gpr_save_slot (j)))
1d3cea74 9567 cfun_gpr_save_slot (j) = SAVE_SLOT_STACK;
ff4ce128 9568 break;
68bc0408 9569 }
ff4ce128 9570 cfun_gpr_save_slot (i) = save_reg_slot++;
5ada7a14 9571 }
ff4ce128 9572}
5ada7a14 9573
ff4ce128 9574/* Set the bits in fpr_bitmap for FPRs which need to be saved due to
9575 stdarg.
9576 This is a helper routine for s390_register_info. */
1e639cb0 9577
ff4ce128 9578static void
9579s390_register_info_stdarg_fpr ()
9580{
9581 int i;
9582 int min_fpr;
9583 int max_fpr;
9584
9585 /* Save the FP argument regs for stdarg. f0, f2 for 31 bit and
9586 f0-f4 for 64 bit. */
9587 if (!cfun->stdarg
9588 || !TARGET_HARD_FLOAT
9589 || !cfun->va_list_fpr_size
9590 || crtl->args.info.fprs >= FP_ARG_NUM_REG)
9591 return;
9592
9593 min_fpr = crtl->args.info.fprs;
1d3cea74 9594 max_fpr = min_fpr + cfun->va_list_fpr_size - 1;
9595 if (max_fpr >= FP_ARG_NUM_REG)
9596 max_fpr = FP_ARG_NUM_REG - 1;
ff4ce128 9597
1d3cea74 9598 /* FPR argument regs start at f0. */
9599 min_fpr += FPR0_REGNUM;
9600 max_fpr += FPR0_REGNUM;
9601
9602 for (i = min_fpr; i <= max_fpr; i++)
9603 cfun_set_fpr_save (i);
ff4ce128 9604}
9605
9606/* Reserve the GPR save slots for GPRs which need to be saved due to
9607 stdarg.
9608 This is a helper routine for s390_register_info. */
9609
9610static void
9611s390_register_info_stdarg_gpr ()
9612{
9613 int i;
9614 int min_gpr;
9615 int max_gpr;
9616
9617 if (!cfun->stdarg
9618 || !cfun->va_list_gpr_size
9619 || crtl->args.info.gprs >= GP_ARG_NUM_REG)
9620 return;
9621
9622 min_gpr = crtl->args.info.gprs;
1d3cea74 9623 max_gpr = min_gpr + cfun->va_list_gpr_size - 1;
9624 if (max_gpr >= GP_ARG_NUM_REG)
9625 max_gpr = GP_ARG_NUM_REG - 1;
9626
9627 /* GPR argument regs start at r2. */
9628 min_gpr += GPR2_REGNUM;
9629 max_gpr += GPR2_REGNUM;
9630
9631 /* If r6 was supposed to be saved into an FPR and now needs to go to
9632 the stack for vararg we have to adjust the restore range to make
9633 sure that the restore is done from stack as well. */
9634 if (FP_REGNO_P (cfun_gpr_save_slot (GPR6_REGNUM))
9635 && min_gpr <= GPR6_REGNUM
9636 && max_gpr >= GPR6_REGNUM)
9637 {
9638 if (cfun_frame_layout.first_restore_gpr == -1
9639 || cfun_frame_layout.first_restore_gpr > GPR6_REGNUM)
9640 cfun_frame_layout.first_restore_gpr = GPR6_REGNUM;
9641 if (cfun_frame_layout.last_restore_gpr == -1
9642 || cfun_frame_layout.last_restore_gpr < GPR6_REGNUM)
9643 cfun_frame_layout.last_restore_gpr = GPR6_REGNUM;
9644 }
9645
9646 if (cfun_frame_layout.first_save_gpr == -1
9647 || cfun_frame_layout.first_save_gpr > min_gpr)
9648 cfun_frame_layout.first_save_gpr = min_gpr;
9649
9650 if (cfun_frame_layout.last_save_gpr == -1
9651 || cfun_frame_layout.last_save_gpr < max_gpr)
9652 cfun_frame_layout.last_save_gpr = max_gpr;
9653
9654 for (i = min_gpr; i <= max_gpr; i++)
9655 cfun_gpr_save_slot (i) = SAVE_SLOT_STACK;
9656}
9657
9658/* Calculate the save and restore ranges for stm(g) and lm(g) in the
9659 prologue and epilogue. */
ff4ce128 9660
1d3cea74 9661static void
9662s390_register_info_set_ranges ()
9663{
9664 int i, j;
9665
9666 /* Find the first and the last save slot supposed to use the stack
9667 to set the restore range.
9668 Vararg regs might be marked as save to stack but only the
9669 call-saved regs really need restoring (i.e. r6). This code
9670 assumes that the vararg regs have not yet been recorded in
9671 cfun_gpr_save_slot. */
9672 for (i = 0; i < 16 && cfun_gpr_save_slot (i) != SAVE_SLOT_STACK; i++);
9673 for (j = 15; j > i && cfun_gpr_save_slot (j) != SAVE_SLOT_STACK; j--);
9674 cfun_frame_layout.first_restore_gpr = (i == 16) ? -1 : i;
9675 cfun_frame_layout.last_restore_gpr = (i == 16) ? -1 : j;
1d3cea74 9676 cfun_frame_layout.first_save_gpr = (i == 16) ? -1 : i;
9677 cfun_frame_layout.last_save_gpr = (i == 16) ? -1 : j;
ff4ce128 9678}
9679
9680/* The GPR and FPR save slots in cfun->machine->frame_layout are set
9681 for registers which need to be saved in function prologue.
9682 This function can be used until the insns emitted for save/restore
9683 of the regs are visible in the RTL stream. */
9684
9685static void
9686s390_register_info ()
9687{
1d3cea74 9688 int i;
ff4ce128 9689 char clobbered_regs[32];
9690
9691 gcc_assert (!epilogue_completed);
9692
9693 if (reload_completed)
9694 /* After reload we rely on our own routine to determine which
9695 registers need saving. */
9696 s390_regs_ever_clobbered (clobbered_regs);
9697 else
9698 /* During reload we use regs_ever_live as a base since reload
9699 does changes in there which we otherwise would not be aware
9700 of. */
9701 for (i = 0; i < 32; i++)
9702 clobbered_regs[i] = df_regs_ever_live_p (i);
9703
9704 for (i = 0; i < 32; i++)
9705 clobbered_regs[i] = clobbered_regs[i] && !global_regs[i];
9706
9707 /* Mark the call-saved FPRs which need to be saved.
9708 This needs to be done before checking the special GPRs since the
9709 stack pointer usage depends on whether high FPRs have to be saved
9710 or not. */
9711 cfun_frame_layout.fpr_bitmap = 0;
9712 cfun_frame_layout.high_fprs = 0;
9713 for (i = FPR0_REGNUM; i <= FPR15_REGNUM; i++)
9714 if (clobbered_regs[i] && !call_really_used_regs[i])
9715 {
9716 cfun_set_fpr_save (i);
9717 if (i >= FPR8_REGNUM)
9718 cfun_frame_layout.high_fprs++;
9719 }
9a2a66ae 9720
c6d481f7 9721 /* Register 12 is used for GOT address, but also as temp in prologue
9722 for split-stack stdarg functions (unless r14 is available). */
9723 clobbered_regs[12]
9724 |= ((flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM))
9725 || (flag_split_stack && cfun->stdarg
9726 && (crtl->is_leaf || TARGET_TPF_PROFILING
9727 || has_hard_reg_initial_val (Pmode, RETURN_REGNUM))));
4fed3f99 9728
ffead1ca 9729 clobbered_regs[BASE_REGNUM]
77beec48 9730 |= (cfun->machine->base_reg
ff4ce128 9731 && REGNO (cfun->machine->base_reg) == BASE_REGNUM);
4fed3f99 9732
ff4ce128 9733 clobbered_regs[HARD_FRAME_POINTER_REGNUM]
9734 |= !!frame_pointer_needed;
9735
9736 /* On pre z900 machines this might take until machine dependent
9737 reorg to decide.
9738 save_return_addr_p will only be set on non-zarch machines so
9739 there is no risk that r14 goes into an FPR instead of a stack
9740 slot. */
1e639cb0 9741 clobbered_regs[RETURN_REGNUM]
d5bf7b64 9742 |= (!crtl->is_leaf
9bee2845 9743 || TARGET_TPF_PROFILING
77beec48 9744 || cfun_frame_layout.save_return_addr_p
ff4ce128 9745 || crtl->calls_eh_return);
4fed3f99 9746
1e639cb0 9747 clobbered_regs[STACK_POINTER_REGNUM]
d5bf7b64 9748 |= (!crtl->is_leaf
77beec48 9749 || TARGET_TPF_PROFILING
9750 || cfun_save_high_fprs_p
9751 || get_frame_size () > 0
68bc0408 9752 || (reload_completed && cfun_frame_layout.frame_size > 0)
ff4ce128 9753 || cfun->calls_alloca);
9754
1d3cea74 9755 memset (cfun_frame_layout.gpr_save_slots, SAVE_SLOT_NONE, 16);
1e639cb0 9756
beee1f75 9757 for (i = 6; i < 16; i++)
ff4ce128 9758 if (clobbered_regs[i])
1d3cea74 9759 cfun_gpr_save_slot (i) = SAVE_SLOT_STACK;
9a2a66ae 9760
ff4ce128 9761 s390_register_info_stdarg_fpr ();
9762 s390_register_info_gprtofpr ();
1d3cea74 9763 s390_register_info_set_ranges ();
ff4ce128 9764 /* stdarg functions might need to save GPRs 2 to 6. This might
1d3cea74 9765 override the GPR->FPR save decision made by
9766 s390_register_info_gprtofpr for r6 since vararg regs must go to
9767 the stack. */
ff4ce128 9768 s390_register_info_stdarg_gpr ();
ff4ce128 9769}
9a2a66ae 9770
f374a534 9771/* Return true if REGNO is a global register, but not one
9772 of the special ones that need to be saved/restored in anyway. */
9773
9774static inline bool
9775global_not_special_regno_p (int regno)
9776{
9777 return (global_regs[regno]
9778 /* These registers are special and need to be
9779 restored in any case. */
9780 && !(regno == STACK_POINTER_REGNUM
9781 || regno == RETURN_REGNUM
9782 || regno == BASE_REGNUM
9783 || (flag_pic && regno == (int)PIC_OFFSET_TABLE_REGNUM)));
9784}
9785
ff4ce128 9786/* This function is called by s390_optimize_prologue in order to get
9787 rid of unnecessary GPR save/restore instructions. The register info
9788 for the GPRs is re-computed and the ranges are re-calculated. */
6902d973 9789
ff4ce128 9790static void
9791s390_optimize_register_info ()
9792{
9793 char clobbered_regs[32];
1d3cea74 9794 int i;
6902d973 9795
ff4ce128 9796 gcc_assert (epilogue_completed);
beee1f75 9797
ff4ce128 9798 s390_regs_ever_clobbered (clobbered_regs);
6902d973 9799
f374a534 9800 /* Global registers do not need to be saved and restored unless it
9801 is one of our special regs. (r12, r13, r14, or r15). */
ff4ce128 9802 for (i = 0; i < 32; i++)
f374a534 9803 clobbered_regs[i] = clobbered_regs[i] && !global_not_special_regno_p (i);
6902d973 9804
ff4ce128 9805 /* There is still special treatment needed for cases invisible to
9806 s390_regs_ever_clobbered. */
9807 clobbered_regs[RETURN_REGNUM]
9808 |= (TARGET_TPF_PROFILING
9809 /* When expanding builtin_return_addr in ESA mode we do not
9810 know whether r14 will later be needed as scratch reg when
9811 doing branch splitting. So the builtin always accesses the
9812 r14 save slot and we need to stick to the save/restore
9813 decision for r14 even if it turns out that it didn't get
9814 clobbered. */
9815 || cfun_frame_layout.save_return_addr_p
9816 || crtl->calls_eh_return);
9817
1d3cea74 9818 memset (cfun_frame_layout.gpr_save_slots, SAVE_SLOT_NONE, 6);
ff4ce128 9819
9820 for (i = 6; i < 16; i++)
9821 if (!clobbered_regs[i])
1d3cea74 9822 cfun_gpr_save_slot (i) = SAVE_SLOT_NONE;
ff4ce128 9823
1d3cea74 9824 s390_register_info_set_ranges ();
ff4ce128 9825 s390_register_info_stdarg_gpr ();
67928721 9826}
9827
4fed3f99 9828/* Fill cfun->machine with info about frame of current function. */
67928721 9829
9830static void
4fed3f99 9831s390_frame_info (void)
67928721 9832{
62eb9236 9833 HOST_WIDE_INT lowest_offset;
67928721 9834
ff4ce128 9835 cfun_frame_layout.first_save_gpr_slot = cfun_frame_layout.first_save_gpr;
9836 cfun_frame_layout.last_save_gpr_slot = cfun_frame_layout.last_save_gpr;
9837
9838 /* The va_arg builtin uses a constant distance of 16 *
9839 UNITS_PER_LONG (r0-r15) to reach the FPRs from the reg_save_area
9840 pointer. So even if we are going to save the stack pointer in an
9841 FPR we need the stack space in order to keep the offsets
9842 correct. */
9843 if (cfun->stdarg && cfun_save_arg_fprs_p)
9844 {
9845 cfun_frame_layout.last_save_gpr_slot = STACK_POINTER_REGNUM;
9846
9847 if (cfun_frame_layout.first_save_gpr_slot == -1)
9848 cfun_frame_layout.first_save_gpr_slot = STACK_POINTER_REGNUM;
9849 }
9850
67928721 9851 cfun_frame_layout.frame_size = get_frame_size ();
67928721 9852 if (!TARGET_64BIT && cfun_frame_layout.frame_size > 0x7fff0000)
c05be867 9853 fatal_error (input_location,
9854 "total size of local variables exceeds architecture limit");
ffead1ca 9855
646a946e 9856 if (!TARGET_PACKED_STACK)
67928721 9857 {
62eb9236 9858 /* Fixed stack layout. */
67928721 9859 cfun_frame_layout.backchain_offset = 0;
b5fdc416 9860 cfun_frame_layout.f0_offset = 16 * UNITS_PER_LONG;
67928721 9861 cfun_frame_layout.f4_offset = cfun_frame_layout.f0_offset + 2 * 8;
9862 cfun_frame_layout.f8_offset = -cfun_frame_layout.high_fprs * 8;
5214e6ae 9863 cfun_frame_layout.gprs_offset = (cfun_frame_layout.first_save_gpr_slot
b5fdc416 9864 * UNITS_PER_LONG);
67928721 9865 }
62eb9236 9866 else if (TARGET_BACKCHAIN)
67928721 9867 {
62eb9236 9868 /* Kernel stack layout - packed stack, backchain, no float */
9869 gcc_assert (TARGET_SOFT_FLOAT);
67928721 9870 cfun_frame_layout.backchain_offset = (STACK_POINTER_OFFSET
b5fdc416 9871 - UNITS_PER_LONG);
62eb9236 9872
9873 /* The distance between the backchain and the return address
9874 save slot must not change. So we always need a slot for the
9875 stack pointer which resides in between. */
9876 cfun_frame_layout.last_save_gpr_slot = STACK_POINTER_REGNUM;
9877
ffead1ca 9878 cfun_frame_layout.gprs_offset
62eb9236 9879 = cfun_frame_layout.backchain_offset - cfun_gprs_save_area_size;
ffead1ca 9880
62eb9236 9881 /* FPRs will not be saved. Nevertheless pick sane values to
9882 keep area calculations valid. */
9883 cfun_frame_layout.f0_offset =
9884 cfun_frame_layout.f4_offset =
9885 cfun_frame_layout.f8_offset = cfun_frame_layout.gprs_offset;
67928721 9886 }
62eb9236 9887 else
67928721 9888 {
031bdf83 9889 int num_fprs;
9890
62eb9236 9891 /* Packed stack layout without backchain. */
ffead1ca 9892
031bdf83 9893 /* With stdarg FPRs need their dedicated slots. */
9894 num_fprs = (TARGET_64BIT && cfun->stdarg ? 2
9895 : (cfun_fpr_save_p (FPR4_REGNUM) +
9896 cfun_fpr_save_p (FPR6_REGNUM)));
9897 cfun_frame_layout.f4_offset = STACK_POINTER_OFFSET - 8 * num_fprs;
9898
9899 num_fprs = (cfun->stdarg ? 2
9900 : (cfun_fpr_save_p (FPR0_REGNUM)
9901 + cfun_fpr_save_p (FPR2_REGNUM)));
9902 cfun_frame_layout.f0_offset = cfun_frame_layout.f4_offset - 8 * num_fprs;
ffead1ca 9903
9904 cfun_frame_layout.gprs_offset
67928721 9905 = cfun_frame_layout.f0_offset - cfun_gprs_save_area_size;
62eb9236 9906
9907 cfun_frame_layout.f8_offset = (cfun_frame_layout.gprs_offset
9908 - cfun_frame_layout.high_fprs * 8);
67928721 9909 }
9910
62eb9236 9911 if (cfun_save_high_fprs_p)
9912 cfun_frame_layout.frame_size += cfun_frame_layout.high_fprs * 8;
9913
9914 if (!crtl->is_leaf)
9915 cfun_frame_layout.frame_size += crtl->outgoing_args_size;
9916
9917 /* In the following cases we have to allocate a STACK_POINTER_OFFSET
9918 sized area at the bottom of the stack. This is required also for
9919 leaf functions. When GCC generates a local stack reference it
9920 will always add STACK_POINTER_OFFSET to all these references. */
d5bf7b64 9921 if (crtl->is_leaf
67928721 9922 && !TARGET_TPF_PROFILING
9923 && cfun_frame_layout.frame_size == 0
ff4ce128 9924 && !cfun->calls_alloca)
67928721 9925 return;
9926
62eb9236 9927 /* Calculate the number of bytes we have used in our own register
9928 save area. With the packed stack layout we can re-use the
9929 remaining bytes for normal stack elements. */
67928721 9930
62eb9236 9931 if (TARGET_PACKED_STACK)
9932 lowest_offset = MIN (MIN (cfun_frame_layout.f0_offset,
9933 cfun_frame_layout.f4_offset),
9934 cfun_frame_layout.gprs_offset);
9935 else
9936 lowest_offset = 0;
ffead1ca 9937
62eb9236 9938 if (TARGET_BACKCHAIN)
9939 lowest_offset = MIN (lowest_offset, cfun_frame_layout.backchain_offset);
ffead1ca 9940
62eb9236 9941 cfun_frame_layout.frame_size += STACK_POINTER_OFFSET - lowest_offset;
67928721 9942
62eb9236 9943 /* If under 31 bit an odd number of gprs has to be saved we have to
9944 adjust the frame size to sustain 8 byte alignment of stack
9945 frames. */
9946 cfun_frame_layout.frame_size = ((cfun_frame_layout.frame_size +
9947 STACK_BOUNDARY / BITS_PER_UNIT - 1)
9948 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
8b4a4127 9949}
9950
4fed3f99 9951/* Generate frame layout. Fills in register and frame data for the current
9952 function in cfun->machine. This routine can be called multiple times;
9953 it will re-do the complete frame layout every time. */
8b4a4127 9954
4fed3f99 9955static void
9956s390_init_frame_layout (void)
4673c1a0 9957{
4fed3f99 9958 HOST_WIDE_INT frame_size;
9959 int base_used;
ff4ce128 9960
b85ca4c8 9961 /* After LRA the frame layout is supposed to be read-only and should
9962 not be re-computed. */
9963 if (reload_completed)
9964 return;
beee1f75 9965
4fed3f99 9966 do
9967 {
9968 frame_size = cfun_frame_layout.frame_size;
9969
9970 /* Try to predict whether we'll need the base register. */
f5edbf1d 9971 base_used = crtl->uses_const_pool
3ea2a559 9972 || (!DISP_IN_RANGE (frame_size)
9973 && !CONST_OK_FOR_K (frame_size));
4fed3f99 9974
9975 /* Decide which register to use as literal pool base. In small
9976 leaf functions, try to use an unused call-clobbered register
9977 as base register to avoid save/restore overhead. */
9978 if (!base_used)
9979 cfun->machine->base_reg = NULL_RTX;
4fed3f99 9980 else
fee9fc9f 9981 {
9982 int br = 0;
9983
9984 if (crtl->is_leaf)
9985 /* Prefer r5 (most likely to be free). */
9986 for (br = 5; br >= 2 && df_regs_ever_live_p (br); br--)
9987 ;
9988 cfun->machine->base_reg =
009c4697 9989 gen_rtx_REG (Pmode, (br >= 2) ? br : BASE_REGNUM);
fee9fc9f 9990 }
67928721 9991
ff4ce128 9992 s390_register_info ();
4fed3f99 9993 s390_frame_info ();
9994 }
9995 while (frame_size != cfun_frame_layout.frame_size);
4673c1a0 9996}
9997
5ada7a14 9998/* Remove the FPR clobbers from a tbegin insn if it can be proven that
9999 the TX is nonescaping. A transaction is considered escaping if
10000 there is at least one path from tbegin returning CC0 to the
10001 function exit block without an tend.
10002
10003 The check so far has some limitations:
10004 - only single tbegin/tend BBs are supported
10005 - the first cond jump after tbegin must separate the CC0 path from ~CC0
10006 - when CC is copied to a GPR and the CC0 check is done with the GPR
10007 this is not supported
10008*/
10009
10010static void
10011s390_optimize_nonescaping_tx (void)
10012{
10013 const unsigned int CC0 = 1 << 3;
10014 basic_block tbegin_bb = NULL;
10015 basic_block tend_bb = NULL;
10016 basic_block bb;
93e0956b 10017 rtx_insn *insn;
5ada7a14 10018 bool result = true;
10019 int bb_index;
93e0956b 10020 rtx_insn *tbegin_insn = NULL;
5ada7a14 10021
10022 if (!cfun->machine->tbegin_p)
10023 return;
10024
a28770e1 10025 for (bb_index = 0; bb_index < n_basic_blocks_for_fn (cfun); bb_index++)
5ada7a14 10026 {
f5a6b05f 10027 bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
5ada7a14 10028
91dfd73e 10029 if (!bb)
10030 continue;
10031
5ada7a14 10032 FOR_BB_INSNS (bb, insn)
10033 {
10034 rtx ite, cc, pat, target;
10035 unsigned HOST_WIDE_INT mask;
10036
10037 if (!INSN_P (insn) || INSN_CODE (insn) <= 0)
10038 continue;
10039
10040 pat = PATTERN (insn);
10041
10042 if (GET_CODE (pat) == PARALLEL)
10043 pat = XVECEXP (pat, 0, 0);
10044
10045 if (GET_CODE (pat) != SET
10046 || GET_CODE (SET_SRC (pat)) != UNSPEC_VOLATILE)
10047 continue;
10048
10049 if (XINT (SET_SRC (pat), 1) == UNSPECV_TBEGIN)
10050 {
91a55c11 10051 rtx_insn *tmp;
5ada7a14 10052
10053 tbegin_insn = insn;
10054
10055 /* Just return if the tbegin doesn't have clobbers. */
10056 if (GET_CODE (PATTERN (insn)) != PARALLEL)
10057 return;
10058
10059 if (tbegin_bb != NULL)
10060 return;
10061
10062 /* Find the next conditional jump. */
10063 for (tmp = NEXT_INSN (insn);
10064 tmp != NULL_RTX;
10065 tmp = NEXT_INSN (tmp))
10066 {
10067 if (reg_set_p (gen_rtx_REG (CCmode, CC_REGNUM), tmp))
10068 return;
10069 if (!JUMP_P (tmp))
10070 continue;
10071
10072 ite = SET_SRC (PATTERN (tmp));
10073 if (GET_CODE (ite) != IF_THEN_ELSE)
10074 continue;
10075
10076 cc = XEXP (XEXP (ite, 0), 0);
10077 if (!REG_P (cc) || !CC_REGNO_P (REGNO (cc))
10078 || GET_MODE (cc) != CCRAWmode
10079 || GET_CODE (XEXP (XEXP (ite, 0), 1)) != CONST_INT)
10080 return;
10081
10082 if (bb->succs->length () != 2)
10083 return;
10084
10085 mask = INTVAL (XEXP (XEXP (ite, 0), 1));
10086 if (GET_CODE (XEXP (ite, 0)) == NE)
10087 mask ^= 0xf;
10088
10089 if (mask == CC0)
10090 target = XEXP (ite, 1);
10091 else if (mask == (CC0 ^ 0xf))
10092 target = XEXP (ite, 2);
10093 else
10094 return;
10095
10096 {
10097 edge_iterator ei;
10098 edge e1, e2;
10099
10100 ei = ei_start (bb->succs);
10101 e1 = ei_safe_edge (ei);
10102 ei_next (&ei);
10103 e2 = ei_safe_edge (ei);
10104
10105 if (e2->flags & EDGE_FALLTHRU)
10106 {
10107 e2 = e1;
10108 e1 = ei_safe_edge (ei);
10109 }
10110
10111 if (!(e1->flags & EDGE_FALLTHRU))
10112 return;
10113
10114 tbegin_bb = (target == pc_rtx) ? e1->dest : e2->dest;
10115 }
10116 if (tmp == BB_END (bb))
10117 break;
10118 }
10119 }
10120
10121 if (XINT (SET_SRC (pat), 1) == UNSPECV_TEND)
10122 {
10123 if (tend_bb != NULL)
10124 return;
10125 tend_bb = bb;
10126 }
10127 }
10128 }
10129
10130 /* Either we successfully remove the FPR clobbers here or we are not
10131 able to do anything for this TX. Both cases don't qualify for
10132 another look. */
10133 cfun->machine->tbegin_p = false;
10134
10135 if (tbegin_bb == NULL || tend_bb == NULL)
10136 return;
10137
10138 calculate_dominance_info (CDI_POST_DOMINATORS);
10139 result = dominated_by_p (CDI_POST_DOMINATORS, tbegin_bb, tend_bb);
10140 free_dominance_info (CDI_POST_DOMINATORS);
10141
10142 if (!result)
10143 return;
10144
91dfd73e 10145 PATTERN (tbegin_insn) = gen_rtx_PARALLEL (VOIDmode,
10146 gen_rtvec (2,
10147 XVECEXP (PATTERN (tbegin_insn), 0, 0),
10148 XVECEXP (PATTERN (tbegin_insn), 0, 1)));
5ada7a14 10149 INSN_CODE (tbegin_insn) = -1;
10150 df_insn_rescan (tbegin_insn);
10151
10152 return;
10153}
10154
74f68e49 10155/* Implement TARGET_HARD_REGNO_NREGS. Because all registers in a class
10156 have the same size, this is equivalent to CLASS_MAX_NREGS. */
10157
10158static unsigned int
10159s390_hard_regno_nregs (unsigned int regno, machine_mode mode)
10160{
10161 return s390_class_max_nregs (REGNO_REG_CLASS (regno), mode);
10162}
10163
10164/* Implement TARGET_HARD_REGNO_MODE_OK.
10165
10166 Integer modes <= word size fit into any GPR.
10167 Integer modes > word size fit into successive GPRs, starting with
10168 an even-numbered register.
10169 SImode and DImode fit into FPRs as well.
10170
10171 Floating point modes <= word size fit into any FPR or GPR.
10172 Floating point modes > word size (i.e. DFmode on 32-bit) fit
10173 into any FPR, or an even-odd GPR pair.
10174 TFmode fits only into an even-odd FPR pair.
10175
10176 Complex floating point modes fit either into two FPRs, or into
10177 successive GPRs (again starting with an even number).
10178 TCmode fits only into two successive even-odd FPR pairs.
10179
10180 Condition code modes fit only into the CC register. */
8f1128bb 10181
b395382f 10182static bool
3754d046 10183s390_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
8f1128bb 10184{
76a4c804 10185 if (!TARGET_VX && VECTOR_NOFP_REGNO_P (regno))
10186 return false;
10187
8f1128bb 10188 switch (REGNO_REG_CLASS (regno))
10189 {
76a4c804 10190 case VEC_REGS:
10191 return ((GET_MODE_CLASS (mode) == MODE_INT
10192 && s390_class_max_nregs (VEC_REGS, mode) == 1)
10193 || mode == DFmode
80912819 10194 || (TARGET_VXE && mode == SFmode)
76a4c804 10195 || s390_vector_mode_supported_p (mode));
10196 break;
8f1128bb 10197 case FP_REGS:
76a4c804 10198 if (TARGET_VX
10199 && ((GET_MODE_CLASS (mode) == MODE_INT
10200 && s390_class_max_nregs (FP_REGS, mode) == 1)
10201 || mode == DFmode
10202 || s390_vector_mode_supported_p (mode)))
10203 return true;
10204
8f1128bb 10205 if (REGNO_PAIR_OK (regno, mode))
10206 {
10207 if (mode == SImode || mode == DImode)
10208 return true;
10209
10210 if (FLOAT_MODE_P (mode) && GET_MODE_CLASS (mode) != MODE_VECTOR_FLOAT)
10211 return true;
10212 }
10213 break;
10214 case ADDR_REGS:
10215 if (FRAME_REGNO_P (regno) && mode == Pmode)
10216 return true;
10217
10218 /* fallthrough */
10219 case GENERAL_REGS:
10220 if (REGNO_PAIR_OK (regno, mode))
10221 {
b5fdc416 10222 if (TARGET_ZARCH
36868490 10223 || (mode != TFmode && mode != TCmode && mode != TDmode))
8f1128bb 10224 return true;
ffead1ca 10225 }
8f1128bb 10226 break;
10227 case CC_REGS:
10228 if (GET_MODE_CLASS (mode) == MODE_CC)
10229 return true;
10230 break;
10231 case ACCESS_REGS:
10232 if (REGNO_PAIR_OK (regno, mode))
10233 {
10234 if (mode == SImode || mode == Pmode)
10235 return true;
10236 }
10237 break;
10238 default:
10239 return false;
10240 }
ffead1ca 10241
8f1128bb 10242 return false;
10243}
10244
5f6dcf1a 10245/* Implement TARGET_MODES_TIEABLE_P. */
10246
10247static bool
10248s390_modes_tieable_p (machine_mode mode1, machine_mode mode2)
10249{
10250 return ((mode1 == SFmode || mode1 == DFmode)
10251 == (mode2 == SFmode || mode2 == DFmode));
10252}
10253
d1a5573e 10254/* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
10255
10256bool
10257s390_hard_regno_rename_ok (unsigned int old_reg, unsigned int new_reg)
10258{
10259 /* Once we've decided upon a register to use as base register, it must
10260 no longer be used for any other purpose. */
10261 if (cfun->machine->base_reg)
10262 if (REGNO (cfun->machine->base_reg) == old_reg
10263 || REGNO (cfun->machine->base_reg) == new_reg)
10264 return false;
10265
ff4ce128 10266 /* Prevent regrename from using call-saved regs which haven't
10267 actually been saved. This is necessary since regrename assumes
10268 the backend save/restore decisions are based on
10269 df_regs_ever_live. Since we have our own routine we have to tell
10270 regrename manually about it. */
10271 if (GENERAL_REGNO_P (new_reg)
10272 && !call_really_used_regs[new_reg]
1d3cea74 10273 && cfun_gpr_save_slot (new_reg) == SAVE_SLOT_NONE)
ff4ce128 10274 return false;
10275
10276 return true;
10277}
10278
10279/* Return nonzero if register REGNO can be used as a scratch register
10280 in peephole2. */
10281
10282static bool
10283s390_hard_regno_scratch_ok (unsigned int regno)
10284{
10285 /* See s390_hard_regno_rename_ok. */
10286 if (GENERAL_REGNO_P (regno)
10287 && !call_really_used_regs[regno]
1d3cea74 10288 && cfun_gpr_save_slot (regno) == SAVE_SLOT_NONE)
ff4ce128 10289 return false;
10290
d1a5573e 10291 return true;
10292}
10293
5da94e60 10294/* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED. When generating
10295 code that runs in z/Architecture mode, but conforms to the 31-bit
10296 ABI, GPRs can hold 8 bytes; the ABI guarantees only that the lower 4
10297 bytes are saved across calls, however. */
10298
10299static bool
5c62f29a 10300s390_hard_regno_call_part_clobbered (rtx_insn *insn ATTRIBUTE_UNUSED,
10301 unsigned int regno, machine_mode mode)
5da94e60 10302{
10303 if (!TARGET_64BIT
10304 && TARGET_ZARCH
10305 && GET_MODE_SIZE (mode) > 4
10306 && ((regno >= 6 && regno <= 15) || regno == 32))
10307 return true;
10308
10309 if (TARGET_VX
10310 && GET_MODE_SIZE (mode) > 8
10311 && (((TARGET_64BIT && regno >= 24 && regno <= 31))
10312 || (!TARGET_64BIT && (regno == 18 || regno == 19))))
10313 return true;
10314
10315 return false;
10316}
10317
8f1128bb 10318/* Maximum number of registers to represent a value of mode MODE
8deb3959 10319 in a register of class RCLASS. */
8f1128bb 10320
6c2d82ab 10321int
3754d046 10322s390_class_max_nregs (enum reg_class rclass, machine_mode mode)
8f1128bb 10323{
76a4c804 10324 int reg_size;
10325 bool reg_pair_required_p = false;
10326
8deb3959 10327 switch (rclass)
8f1128bb 10328 {
10329 case FP_REGS:
76a4c804 10330 case VEC_REGS:
10331 reg_size = TARGET_VX ? 16 : 8;
10332
10333 /* TF and TD modes would fit into a VR but we put them into a
10334 register pair since we do not have 128bit FP instructions on
10335 full VRs. */
10336 if (TARGET_VX
10337 && SCALAR_FLOAT_MODE_P (mode)
10338 && GET_MODE_SIZE (mode) >= 16)
10339 reg_pair_required_p = true;
10340
10341 /* Even if complex types would fit into a single FPR/VR we force
10342 them into a register pair to deal with the parts more easily.
10343 (FIXME: What about complex ints?) */
8f1128bb 10344 if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
76a4c804 10345 reg_pair_required_p = true;
10346 break;
8f1128bb 10347 case ACCESS_REGS:
76a4c804 10348 reg_size = 4;
10349 break;
8f1128bb 10350 default:
76a4c804 10351 reg_size = UNITS_PER_WORD;
8f1128bb 10352 break;
10353 }
76a4c804 10354
10355 if (reg_pair_required_p)
10356 return 2 * ((GET_MODE_SIZE (mode) / 2 + reg_size - 1) / reg_size);
10357
10358 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
10359}
10360
b56a9dbc 10361/* Implement TARGET_CAN_CHANGE_MODE_CLASS. */
76a4c804 10362
b56a9dbc 10363static bool
10364s390_can_change_mode_class (machine_mode from_mode,
10365 machine_mode to_mode,
10366 reg_class_t rclass)
76a4c804 10367{
10368 machine_mode small_mode;
10369 machine_mode big_mode;
10370
80912819 10371 /* V1TF and TF have different representations in vector
10372 registers. */
10373 if (reg_classes_intersect_p (VEC_REGS, rclass)
10374 && ((from_mode == V1TFmode && to_mode == TFmode)
10375 || (from_mode == TFmode && to_mode == V1TFmode)))
b56a9dbc 10376 return false;
80912819 10377
76a4c804 10378 if (GET_MODE_SIZE (from_mode) == GET_MODE_SIZE (to_mode))
b56a9dbc 10379 return true;
76a4c804 10380
10381 if (GET_MODE_SIZE (from_mode) < GET_MODE_SIZE (to_mode))
10382 {
10383 small_mode = from_mode;
10384 big_mode = to_mode;
10385 }
10386 else
10387 {
10388 small_mode = to_mode;
10389 big_mode = from_mode;
10390 }
10391
10392 /* Values residing in VRs are little-endian style. All modes are
10393 placed left-aligned in an VR. This means that we cannot allow
10394 switching between modes with differing sizes. Also if the vector
10395 facility is available we still place TFmode values in VR register
10396 pairs, since the only instructions we have operating on TFmodes
10397 only deal with register pairs. Therefore we have to allow DFmode
10398 subregs of TFmodes to enable the TFmode splitters. */
10399 if (reg_classes_intersect_p (VEC_REGS, rclass)
10400 && (GET_MODE_SIZE (small_mode) < 8
10401 || s390_class_max_nregs (VEC_REGS, big_mode) == 1))
b56a9dbc 10402 return false;
76a4c804 10403
10404 /* Likewise for access registers, since they have only half the
10405 word size on 64-bit. */
10406 if (reg_classes_intersect_p (ACCESS_REGS, rclass))
b56a9dbc 10407 return false;
76a4c804 10408
b56a9dbc 10409 return true;
8f1128bb 10410}
10411
7b1bda1c 10412/* Return true if we use LRA instead of reload pass. */
10413static bool
10414s390_lra_p (void)
10415{
10416 return s390_lra_flag;
10417}
10418
4fed3f99 10419/* Return true if register FROM can be eliminated via register TO. */
10420
cd90919d 10421static bool
10422s390_can_eliminate (const int from, const int to)
4fed3f99 10423{
f5edbf1d 10424 /* We have not marked the base register as fixed.
d1a5573e 10425 Instead, we have an elimination rule BASE_REGNUM -> BASE_REGNUM.
10426 If a function requires the base register, we say here that this
10427 elimination cannot be performed. This will cause reload to free
10428 up the base register (as if it were fixed). On the other hand,
10429 if the current function does *not* require the base register, we
10430 say here the elimination succeeds, which in turn allows reload
10431 to allocate the base register for any other purpose. */
10432 if (from == BASE_REGNUM && to == BASE_REGNUM)
10433 {
f5edbf1d 10434 s390_init_frame_layout ();
10435 return cfun->machine->base_reg == NULL_RTX;
d1a5573e 10436 }
10437
10438 /* Everything else must point into the stack frame. */
4fed3f99 10439 gcc_assert (to == STACK_POINTER_REGNUM
10440 || to == HARD_FRAME_POINTER_REGNUM);
10441
10442 gcc_assert (from == FRAME_POINTER_REGNUM
10443 || from == ARG_POINTER_REGNUM
10444 || from == RETURN_ADDRESS_POINTER_REGNUM);
10445
10446 /* Make sure we actually saved the return address. */
10447 if (from == RETURN_ADDRESS_POINTER_REGNUM)
18d50ae6 10448 if (!crtl->calls_eh_return
10449 && !cfun->stdarg
4fed3f99 10450 && !cfun_frame_layout.save_return_addr_p)
10451 return false;
10452
10453 return true;
10454}
10455
10456/* Return offset between register FROM and TO initially after prolog. */
7cbfc974 10457
10458HOST_WIDE_INT
4fed3f99 10459s390_initial_elimination_offset (int from, int to)
7cbfc974 10460{
4fed3f99 10461 HOST_WIDE_INT offset;
7cbfc974 10462
4fed3f99 10463 /* ??? Why are we called for non-eliminable pairs? */
10464 if (!s390_can_eliminate (from, to))
10465 return 0;
10466
10467 switch (from)
10468 {
10469 case FRAME_POINTER_REGNUM:
ffead1ca 10470 offset = (get_frame_size()
119114cb 10471 + STACK_POINTER_OFFSET
abe32cce 10472 + crtl->outgoing_args_size);
4fed3f99 10473 break;
67928721 10474
4fed3f99 10475 case ARG_POINTER_REGNUM:
10476 s390_init_frame_layout ();
10477 offset = cfun_frame_layout.frame_size + STACK_POINTER_OFFSET;
10478 break;
10479
10480 case RETURN_ADDRESS_POINTER_REGNUM:
10481 s390_init_frame_layout ();
ff4ce128 10482
10483 if (cfun_frame_layout.first_save_gpr_slot == -1)
10484 {
10485 /* If it turns out that for stdarg nothing went into the reg
10486 save area we also do not need the return address
10487 pointer. */
10488 if (cfun->stdarg && !cfun_save_arg_fprs_p)
10489 return 0;
10490
10491 gcc_unreachable ();
10492 }
10493
10494 /* In order to make the following work it is not necessary for
10495 r14 to have a save slot. It is sufficient if one other GPR
10496 got one. Since the GPRs are always stored without gaps we
10497 are able to calculate where the r14 save slot would
10498 reside. */
10499 offset = (cfun_frame_layout.frame_size + cfun_frame_layout.gprs_offset +
10500 (RETURN_REGNUM - cfun_frame_layout.first_save_gpr_slot) *
10501 UNITS_PER_LONG);
4fed3f99 10502 break;
10503
d1a5573e 10504 case BASE_REGNUM:
10505 offset = 0;
10506 break;
10507
4fed3f99 10508 default:
10509 gcc_unreachable ();
10510 }
10511
10512 return offset;
7cbfc974 10513}
10514
8b4a4127 10515/* Emit insn to save fpr REGNUM at offset OFFSET relative
f81e845f 10516 to register BASE. Return generated insn. */
56769981 10517
4673c1a0 10518static rtx
b40da9a7 10519save_fpr (rtx base, int offset, int regnum)
4673c1a0 10520{
8b4a4127 10521 rtx addr;
29c05e22 10522 addr = gen_rtx_MEM (DFmode, plus_constant (Pmode, base, offset));
ce1d5a67 10523
10524 if (regnum >= 16 && regnum <= (16 + FP_ARG_NUM_REG))
10525 set_mem_alias_set (addr, get_varargs_alias_set ());
10526 else
10527 set_mem_alias_set (addr, get_frame_alias_set ());
4673c1a0 10528
8b4a4127 10529 return emit_move_insn (addr, gen_rtx_REG (DFmode, regnum));
10530}
4673c1a0 10531
8b4a4127 10532/* Emit insn to restore fpr REGNUM from offset OFFSET relative
f81e845f 10533 to register BASE. Return generated insn. */
4673c1a0 10534
8b4a4127 10535static rtx
b40da9a7 10536restore_fpr (rtx base, int offset, int regnum)
8b4a4127 10537{
10538 rtx addr;
29c05e22 10539 addr = gen_rtx_MEM (DFmode, plus_constant (Pmode, base, offset));
ce1d5a67 10540 set_mem_alias_set (addr, get_frame_alias_set ());
4673c1a0 10541
8b4a4127 10542 return emit_move_insn (gen_rtx_REG (DFmode, regnum), addr);
4673c1a0 10543}
10544
9a2a66ae 10545/* Generate insn to save registers FIRST to LAST into
f81e845f 10546 the register save area located at offset OFFSET
9a2a66ae 10547 relative to register BASE. */
4673c1a0 10548
9a2a66ae 10549static rtx
b40da9a7 10550save_gprs (rtx base, int offset, int first, int last)
4673c1a0 10551{
9a2a66ae 10552 rtx addr, insn, note;
10553 int i;
10554
29c05e22 10555 addr = plus_constant (Pmode, base, offset);
9a2a66ae 10556 addr = gen_rtx_MEM (Pmode, addr);
ce1d5a67 10557
10558 set_mem_alias_set (addr, get_frame_alias_set ());
9a2a66ae 10559
10560 /* Special-case single register. */
10561 if (first == last)
10562 {
10563 if (TARGET_64BIT)
9f522e0c 10564 insn = gen_movdi (addr, gen_rtx_REG (Pmode, first));
9a2a66ae 10565 else
9f522e0c 10566 insn = gen_movsi (addr, gen_rtx_REG (Pmode, first));
9a2a66ae 10567
a3cd0f6a 10568 if (!global_not_special_regno_p (first))
10569 RTX_FRAME_RELATED_P (insn) = 1;
9a2a66ae 10570 return insn;
10571 }
10572
10573
10574 insn = gen_store_multiple (addr,
10575 gen_rtx_REG (Pmode, first),
10576 GEN_INT (last - first + 1));
10577
18d50ae6 10578 if (first <= 6 && cfun->stdarg)
ce1d5a67 10579 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
10580 {
10581 rtx mem = XEXP (XVECEXP (PATTERN (insn), 0, i), 0);
ffead1ca 10582
ce1d5a67 10583 if (first + i <= 6)
10584 set_mem_alias_set (mem, get_varargs_alias_set ());
10585 }
9a2a66ae 10586
10587 /* We need to set the FRAME_RELATED flag on all SETs
10588 inside the store-multiple pattern.
10589
10590 However, we must not emit DWARF records for registers 2..5
f81e845f 10591 if they are stored for use by variable arguments ...
9a2a66ae 10592
3ce7ff97 10593 ??? Unfortunately, it is not enough to simply not the
9a2a66ae 10594 FRAME_RELATED flags for those SETs, because the first SET
10595 of the PARALLEL is always treated as if it had the flag
10596 set, even if it does not. Therefore we emit a new pattern
10597 without those registers as REG_FRAME_RELATED_EXPR note. */
10598
a3cd0f6a 10599 if (first >= 6 && !global_not_special_regno_p (first))
9a2a66ae 10600 {
10601 rtx pat = PATTERN (insn);
10602
10603 for (i = 0; i < XVECLEN (pat, 0); i++)
a3cd0f6a 10604 if (GET_CODE (XVECEXP (pat, 0, i)) == SET
10605 && !global_not_special_regno_p (REGNO (SET_SRC (XVECEXP (pat,
10606 0, i)))))
9a2a66ae 10607 RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1;
10608
10609 RTX_FRAME_RELATED_P (insn) = 1;
10610 }
10611 else if (last >= 6)
10612 {
a3cd0f6a 10613 int start;
10614
10615 for (start = first >= 6 ? first : 6; start <= last; start++)
10616 if (!global_not_special_regno_p (start))
10617 break;
10618
10619 if (start > last)
10620 return insn;
10621
29c05e22 10622 addr = plus_constant (Pmode, base,
10623 offset + (start - first) * UNITS_PER_LONG);
ff4ce128 10624
10625 if (start == last)
10626 {
10627 if (TARGET_64BIT)
10628 note = gen_movdi (gen_rtx_MEM (Pmode, addr),
10629 gen_rtx_REG (Pmode, start));
10630 else
10631 note = gen_movsi (gen_rtx_MEM (Pmode, addr),
10632 gen_rtx_REG (Pmode, start));
10633 note = PATTERN (note);
10634
10635 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
10636 RTX_FRAME_RELATED_P (insn) = 1;
10637
10638 return insn;
10639 }
10640
f81e845f 10641 note = gen_store_multiple (gen_rtx_MEM (Pmode, addr),
a3cd0f6a 10642 gen_rtx_REG (Pmode, start),
10643 GEN_INT (last - start + 1));
9a2a66ae 10644 note = PATTERN (note);
10645
b9c74b4d 10646 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
9a2a66ae 10647
10648 for (i = 0; i < XVECLEN (note, 0); i++)
a3cd0f6a 10649 if (GET_CODE (XVECEXP (note, 0, i)) == SET
10650 && !global_not_special_regno_p (REGNO (SET_SRC (XVECEXP (note,
10651 0, i)))))
9a2a66ae 10652 RTX_FRAME_RELATED_P (XVECEXP (note, 0, i)) = 1;
10653
10654 RTX_FRAME_RELATED_P (insn) = 1;
10655 }
10656
10657 return insn;
8b4a4127 10658}
4673c1a0 10659
9a2a66ae 10660/* Generate insn to restore registers FIRST to LAST from
f81e845f 10661 the register save area located at offset OFFSET
9a2a66ae 10662 relative to register BASE. */
4673c1a0 10663
9a2a66ae 10664static rtx
b40da9a7 10665restore_gprs (rtx base, int offset, int first, int last)
8b4a4127 10666{
9a2a66ae 10667 rtx addr, insn;
10668
29c05e22 10669 addr = plus_constant (Pmode, base, offset);
9a2a66ae 10670 addr = gen_rtx_MEM (Pmode, addr);
ce1d5a67 10671 set_mem_alias_set (addr, get_frame_alias_set ());
9a2a66ae 10672
10673 /* Special-case single register. */
10674 if (first == last)
10675 {
10676 if (TARGET_64BIT)
9f522e0c 10677 insn = gen_movdi (gen_rtx_REG (Pmode, first), addr);
9a2a66ae 10678 else
9f522e0c 10679 insn = gen_movsi (gen_rtx_REG (Pmode, first), addr);
9a2a66ae 10680
ff4ce128 10681 RTX_FRAME_RELATED_P (insn) = 1;
9a2a66ae 10682 return insn;
10683 }
10684
10685 insn = gen_load_multiple (gen_rtx_REG (Pmode, first),
10686 addr,
10687 GEN_INT (last - first + 1));
ff4ce128 10688 RTX_FRAME_RELATED_P (insn) = 1;
9a2a66ae 10689 return insn;
8b4a4127 10690}
4673c1a0 10691
20074f87 10692/* Return insn sequence to load the GOT register. */
12ef3745 10693
93e0956b 10694rtx_insn *
20074f87 10695s390_load_got (void)
12ef3745 10696{
93e0956b 10697 rtx_insn *insns;
20074f87 10698
c60a7572 10699 /* We cannot use pic_offset_table_rtx here since we use this
10700 function also for non-pic if __tls_get_offset is called and in
10701 that case PIC_OFFSET_TABLE_REGNUM as well as pic_offset_table_rtx
10702 aren't usable. */
10703 rtx got_rtx = gen_rtx_REG (Pmode, 12);
10704
20074f87 10705 start_sequence ();
10706
f5edbf1d 10707 emit_move_insn (got_rtx, s390_got_symbol ());
20074f87 10708
10709 insns = get_insns ();
10710 end_sequence ();
10711 return insns;
12ef3745 10712}
10713
062c49fd 10714/* This ties together stack memory (MEM with an alias set of frame_alias_set)
10715 and the change to the stack pointer. */
10716
10717static void
10718s390_emit_stack_tie (void)
10719{
10720 rtx mem = gen_frame_mem (BLKmode,
10721 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
10722
10723 emit_insn (gen_stack_tie (mem));
10724}
10725
ff4ce128 10726/* Copy GPRS into FPR save slots. */
10727
10728static void
10729s390_save_gprs_to_fprs (void)
10730{
10731 int i;
10732
10733 if (!TARGET_Z10 || !TARGET_HARD_FLOAT || !crtl->is_leaf)
10734 return;
10735
10736 for (i = 6; i < 16; i++)
10737 {
10738 if (FP_REGNO_P (cfun_gpr_save_slot (i)))
10739 {
93e0956b 10740 rtx_insn *insn =
ff4ce128 10741 emit_move_insn (gen_rtx_REG (DImode, cfun_gpr_save_slot (i)),
10742 gen_rtx_REG (DImode, i));
10743 RTX_FRAME_RELATED_P (insn) = 1;
c5dad799 10744 /* This prevents dwarf2cfi from interpreting the set. Doing
10745 so it might emit def_cfa_register infos setting an FPR as
10746 new CFA. */
9e165059 10747 add_reg_note (insn, REG_CFA_REGISTER, copy_rtx (PATTERN (insn)));
ff4ce128 10748 }
10749 }
10750}
10751
10752/* Restore GPRs from FPR save slots. */
10753
10754static void
10755s390_restore_gprs_from_fprs (void)
10756{
10757 int i;
10758
10759 if (!TARGET_Z10 || !TARGET_HARD_FLOAT || !crtl->is_leaf)
10760 return;
10761
4788a5ca 10762 /* Restore the GPRs starting with the stack pointer. That way the
10763 stack pointer already has its original value when it comes to
10764 restoring the hard frame pointer. So we can set the cfa reg back
10765 to the stack pointer. */
10766 for (i = STACK_POINTER_REGNUM; i >= 6; i--)
ff4ce128 10767 {
54530437 10768 rtx_insn *insn;
10769
10770 if (!FP_REGNO_P (cfun_gpr_save_slot (i)))
10771 continue;
10772
10773 rtx fpr = gen_rtx_REG (DImode, cfun_gpr_save_slot (i));
10774
10775 if (i == STACK_POINTER_REGNUM)
10776 insn = emit_insn (gen_stack_restore_from_fpr (fpr));
10777 else
10778 insn = emit_move_insn (gen_rtx_REG (DImode, i), fpr);
10779
10780 df_set_regs_ever_live (i, true);
10781 add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (DImode, i));
4788a5ca 10782
10783 /* If either the stack pointer or the frame pointer get restored
10784 set the CFA value to its value at function start. Doing this
10785 for the frame pointer results in .cfi_def_cfa_register 15
10786 what is ok since if the stack pointer got modified it has
10787 been restored already. */
10788 if (i == STACK_POINTER_REGNUM || i == HARD_FRAME_POINTER_REGNUM)
54530437 10789 add_reg_note (insn, REG_CFA_DEF_CFA,
10790 plus_constant (Pmode, stack_pointer_rtx,
10791 STACK_POINTER_OFFSET));
10792 RTX_FRAME_RELATED_P (insn) = 1;
ff4ce128 10793 }
10794}
10795
4673c1a0 10796
0b8be04c 10797/* A pass run immediately before shrink-wrapping and prologue and epilogue
10798 generation. */
10799
0b8be04c 10800namespace {
10801
10802const pass_data pass_data_s390_early_mach =
10803{
10804 RTL_PASS, /* type */
10805 "early_mach", /* name */
10806 OPTGROUP_NONE, /* optinfo_flags */
0b8be04c 10807 TV_MACH_DEP, /* tv_id */
10808 0, /* properties_required */
10809 0, /* properties_provided */
10810 0, /* properties_destroyed */
10811 0, /* todo_flags_start */
8b88439e 10812 ( TODO_df_verify | TODO_df_finish ), /* todo_flags_finish */
0b8be04c 10813};
20074f87 10814
0b8be04c 10815class pass_s390_early_mach : public rtl_opt_pass
10816{
10817public:
10818 pass_s390_early_mach (gcc::context *ctxt)
10819 : rtl_opt_pass (pass_data_s390_early_mach, ctxt)
10820 {}
10821
10822 /* opt_pass methods: */
65b0537f 10823 virtual unsigned int execute (function *);
0b8be04c 10824
10825}; // class pass_s390_early_mach
10826
65b0537f 10827unsigned int
10828pass_s390_early_mach::execute (function *fun)
10829{
93e0956b 10830 rtx_insn *insn;
65b0537f 10831
10832 /* Try to get rid of the FPR clobbers. */
10833 s390_optimize_nonescaping_tx ();
10834
10835 /* Re-compute register info. */
10836 s390_register_info ();
10837
10838 /* If we're using a base register, ensure that it is always valid for
10839 the first non-prologue instruction. */
10840 if (fun->machine->base_reg)
10841 emit_insn_at_entry (gen_main_pool (fun->machine->base_reg));
10842
10843 /* Annotate all constant pool references to let the scheduler know
10844 they implicitly use the base register. */
10845 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
10846 if (INSN_P (insn))
10847 {
50a42dec 10848 annotate_constant_pool_refs (insn);
65b0537f 10849 df_insn_rescan (insn);
10850 }
10851 return 0;
10852}
10853
0b8be04c 10854} // anon namespace
10855
07c30acd 10856rtl_opt_pass *
10857make_pass_s390_early_mach (gcc::context *ctxt)
10858{
10859 return new pass_s390_early_mach (ctxt);
10860}
10861
82e9b0b4 10862/* Calculate TARGET = REG + OFFSET as s390_emit_prologue would do it.
10863 - push too big immediates to the literal pool and annotate the refs
10864 - emit frame related notes for stack pointer changes. */
10865
10866static rtx
10867s390_prologue_plus_offset (rtx target, rtx reg, rtx offset, bool frame_related_p)
10868{
50a42dec 10869 rtx_insn *insn;
82e9b0b4 10870 rtx orig_offset = offset;
10871
10872 gcc_assert (REG_P (target));
10873 gcc_assert (REG_P (reg));
10874 gcc_assert (CONST_INT_P (offset));
10875
10876 if (offset == const0_rtx) /* lr/lgr */
10877 {
10878 insn = emit_move_insn (target, reg);
10879 }
10880 else if (DISP_IN_RANGE (INTVAL (offset))) /* la */
10881 {
10882 insn = emit_move_insn (target, gen_rtx_PLUS (Pmode, reg,
10883 offset));
10884 }
10885 else
10886 {
10887 if (!satisfies_constraint_K (offset) /* ahi/aghi */
10888 && (!TARGET_EXTIMM
10889 || (!satisfies_constraint_Op (offset) /* alfi/algfi */
10890 && !satisfies_constraint_On (offset)))) /* slfi/slgfi */
10891 offset = force_const_mem (Pmode, offset);
10892
10893 if (target != reg)
10894 {
10895 insn = emit_move_insn (target, reg);
10896 RTX_FRAME_RELATED_P (insn) = frame_related_p ? 1 : 0;
10897 }
10898
10899 insn = emit_insn (gen_add2_insn (target, offset));
10900
10901 if (!CONST_INT_P (offset))
10902 {
50a42dec 10903 annotate_constant_pool_refs (insn);
82e9b0b4 10904
10905 if (frame_related_p)
10906 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
10907 gen_rtx_SET (target,
10908 gen_rtx_PLUS (Pmode, target,
10909 orig_offset)));
10910 }
10911 }
10912
10913 RTX_FRAME_RELATED_P (insn) = frame_related_p ? 1 : 0;
10914
10915 /* If this is a stack adjustment and we are generating a stack clash
10916 prologue, then add a REG_STACK_CHECK note to signal that this insn
10917 should be left alone. */
10918 if (flag_stack_clash_protection && target == stack_pointer_rtx)
10919 add_reg_note (insn, REG_STACK_CHECK, const0_rtx);
10920
10921 return insn;
10922}
10923
10924/* Emit a compare instruction with a volatile memory access as stack
10925 probe. It does not waste store tags and does not clobber any
10926 registers apart from the condition code. */
10927static void
10928s390_emit_stack_probe (rtx addr)
10929{
10930 rtx tmp = gen_rtx_MEM (Pmode, addr);
10931 MEM_VOLATILE_P (tmp) = 1;
10932 s390_emit_compare (EQ, gen_rtx_REG (Pmode, 0), tmp);
10933 emit_insn (gen_blockage ());
10934}
10935
10936/* Use a runtime loop if we have to emit more probes than this. */
10937#define MIN_UNROLL_PROBES 3
10938
10939/* Allocate SIZE bytes of stack space, using TEMP_REG as a temporary
10940 if necessary. LAST_PROBE_OFFSET contains the offset of the closest
10941 probe relative to the stack pointer.
10942
10943 Note that SIZE is negative.
10944
10945 The return value is true if TEMP_REG has been clobbered. */
10946static bool
10947allocate_stack_space (rtx size, HOST_WIDE_INT last_probe_offset,
10948 rtx temp_reg)
10949{
10950 bool temp_reg_clobbered_p = false;
10951 HOST_WIDE_INT probe_interval
10952 = 1 << PARAM_VALUE (PARAM_STACK_CLASH_PROTECTION_PROBE_INTERVAL);
10953 HOST_WIDE_INT guard_size
10954 = 1 << PARAM_VALUE (PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE);
10955
10956 if (flag_stack_clash_protection)
10957 {
10958 if (last_probe_offset + -INTVAL (size) < guard_size)
10959 dump_stack_clash_frame_info (NO_PROBE_SMALL_FRAME, true);
10960 else
10961 {
10962 rtx offset = GEN_INT (probe_interval - UNITS_PER_LONG);
10963 HOST_WIDE_INT rounded_size = -INTVAL (size) & -probe_interval;
10964 HOST_WIDE_INT num_probes = rounded_size / probe_interval;
10965 HOST_WIDE_INT residual = -INTVAL (size) - rounded_size;
10966
10967 if (num_probes < MIN_UNROLL_PROBES)
10968 {
10969 /* Emit unrolled probe statements. */
10970
10971 for (unsigned int i = 0; i < num_probes; i++)
10972 {
10973 s390_prologue_plus_offset (stack_pointer_rtx,
10974 stack_pointer_rtx,
10975 GEN_INT (-probe_interval), true);
10976 s390_emit_stack_probe (gen_rtx_PLUS (Pmode,
10977 stack_pointer_rtx,
10978 offset));
10979 }
10980 dump_stack_clash_frame_info (PROBE_INLINE, residual != 0);
10981 }
10982 else
10983 {
10984 /* Emit a loop probing the pages. */
10985
10986 rtx_code_label *loop_start_label = gen_label_rtx ();
10987
10988 /* From now on temp_reg will be the CFA register. */
10989 s390_prologue_plus_offset (temp_reg, stack_pointer_rtx,
10990 GEN_INT (-rounded_size), true);
10991 emit_label (loop_start_label);
10992
10993 s390_prologue_plus_offset (stack_pointer_rtx,
10994 stack_pointer_rtx,
10995 GEN_INT (-probe_interval), false);
10996 s390_emit_stack_probe (gen_rtx_PLUS (Pmode,
10997 stack_pointer_rtx,
10998 offset));
10999 emit_cmp_and_jump_insns (stack_pointer_rtx, temp_reg,
11000 GT, NULL_RTX,
11001 Pmode, 1, loop_start_label);
11002
11003 /* Without this make_edges ICEes. */
11004 JUMP_LABEL (get_last_insn ()) = loop_start_label;
11005 LABEL_NUSES (loop_start_label) = 1;
11006
11007 /* That's going to be a NOP since stack pointer and
11008 temp_reg are supposed to be the same here. We just
11009 emit it to set the CFA reg back to r15. */
11010 s390_prologue_plus_offset (stack_pointer_rtx, temp_reg,
11011 const0_rtx, true);
11012 temp_reg_clobbered_p = true;
11013 dump_stack_clash_frame_info (PROBE_LOOP, residual != 0);
11014 }
11015
11016 /* Handle any residual allocation request. */
11017 s390_prologue_plus_offset (stack_pointer_rtx,
11018 stack_pointer_rtx,
11019 GEN_INT (-residual), true);
11020 last_probe_offset += residual;
11021 if (last_probe_offset >= probe_interval)
11022 s390_emit_stack_probe (gen_rtx_PLUS (Pmode,
11023 stack_pointer_rtx,
11024 GEN_INT (residual
11025 - UNITS_PER_LONG)));
11026
11027 return temp_reg_clobbered_p;
11028 }
11029 }
11030
11031 /* Subtract frame size from stack pointer. */
11032 s390_prologue_plus_offset (stack_pointer_rtx,
11033 stack_pointer_rtx,
11034 size, true);
11035
11036 return temp_reg_clobbered_p;
11037}
11038
0b8be04c 11039/* Expand the prologue into a bunch of separate insns. */
11040
11041void
11042s390_emit_prologue (void)
11043{
11044 rtx insn, addr;
11045 rtx temp_reg;
11046 int i;
11047 int offset;
11048 int next_fpr = 0;
20074f87 11049
f81e845f 11050 /* Choose best register to use for temp use within prologue.
c6d481f7 11051 TPF with profiling must avoid the register 14 - the tracing function
11052 needs the original contents of r14 to be preserved. */
f81e845f 11053
ffead1ca 11054 if (!has_hard_reg_initial_val (Pmode, RETURN_REGNUM)
d5bf7b64 11055 && !crtl->is_leaf
1e639cb0 11056 && !TARGET_TPF_PROFILING)
8b4a4127 11057 temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
c6d481f7 11058 else if (flag_split_stack && cfun->stdarg)
11059 temp_reg = gen_rtx_REG (Pmode, 12);
4673c1a0 11060 else
8b4a4127 11061 temp_reg = gen_rtx_REG (Pmode, 1);
4673c1a0 11062
82e9b0b4 11063 /* When probing for stack-clash mitigation, we have to track the distance
11064 between the stack pointer and closest known reference.
11065
5714ec4b 11066 Most of the time we have to make a worst case assumption. The
82e9b0b4 11067 only exception is when TARGET_BACKCHAIN is active, in which case
11068 we know *sp (offset 0) was written. */
11069 HOST_WIDE_INT probe_interval
11070 = 1 << PARAM_VALUE (PARAM_STACK_CLASH_PROTECTION_PROBE_INTERVAL);
11071 HOST_WIDE_INT last_probe_offset
11072 = (TARGET_BACKCHAIN
11073 ? (TARGET_PACKED_STACK ? STACK_POINTER_OFFSET - UNITS_PER_LONG : 0)
11074 : probe_interval - (STACK_BOUNDARY / UNITS_PER_WORD));
11075
ff4ce128 11076 s390_save_gprs_to_fprs ();
11077
8b4a4127 11078 /* Save call saved gprs. */
67928721 11079 if (cfun_frame_layout.first_save_gpr != -1)
4ac7fd98 11080 {
ffead1ca 11081 insn = save_gprs (stack_pointer_rtx,
11082 cfun_frame_layout.gprs_offset +
b5fdc416 11083 UNITS_PER_LONG * (cfun_frame_layout.first_save_gpr
5214e6ae 11084 - cfun_frame_layout.first_save_gpr_slot),
ffead1ca 11085 cfun_frame_layout.first_save_gpr,
4ac7fd98 11086 cfun_frame_layout.last_save_gpr);
82e9b0b4 11087
11088 /* This is not 100% correct. If we have more than one register saved,
11089 then LAST_PROBE_OFFSET can move even closer to sp. */
11090 last_probe_offset
11091 = (cfun_frame_layout.gprs_offset +
11092 UNITS_PER_LONG * (cfun_frame_layout.first_save_gpr
11093 - cfun_frame_layout.first_save_gpr_slot));
11094
4ac7fd98 11095 emit_insn (insn);
11096 }
8b4a4127 11097
c2c1332a 11098 /* Dummy insn to mark literal pool slot. */
f81e845f 11099
4fed3f99 11100 if (cfun->machine->base_reg)
11101 emit_insn (gen_main_pool (cfun->machine->base_reg));
f81e845f 11102
67928721 11103 offset = cfun_frame_layout.f0_offset;
8b4a4127 11104
67928721 11105 /* Save f0 and f2. */
6a2469fe 11106 for (i = FPR0_REGNUM; i <= FPR0_REGNUM + 1; i++)
67928721 11107 {
29439367 11108 if (cfun_fpr_save_p (i))
67928721 11109 {
29439367 11110 save_fpr (stack_pointer_rtx, offset, i);
82e9b0b4 11111 if (offset < last_probe_offset)
11112 last_probe_offset = offset;
67928721 11113 offset += 8;
11114 }
031bdf83 11115 else if (!TARGET_PACKED_STACK || cfun->stdarg)
11116 offset += 8;
67928721 11117 }
4673c1a0 11118
67928721 11119 /* Save f4 and f6. */
11120 offset = cfun_frame_layout.f4_offset;
6a2469fe 11121 for (i = FPR4_REGNUM; i <= FPR4_REGNUM + 1; i++)
67928721 11122 {
29439367 11123 if (cfun_fpr_save_p (i))
8b4a4127 11124 {
29439367 11125 insn = save_fpr (stack_pointer_rtx, offset, i);
82e9b0b4 11126 if (offset < last_probe_offset)
11127 last_probe_offset = offset;
67928721 11128 offset += 8;
11129
031bdf83 11130 /* If f4 and f6 are call clobbered they are saved due to
11131 stdargs and therefore are not frame related. */
29439367 11132 if (!call_really_used_regs[i])
67928721 11133 RTX_FRAME_RELATED_P (insn) = 1;
8b4a4127 11134 }
031bdf83 11135 else if (!TARGET_PACKED_STACK || call_really_used_regs[i])
67928721 11136 offset += 8;
11137 }
11138
646a946e 11139 if (TARGET_PACKED_STACK
67928721 11140 && cfun_save_high_fprs_p
11141 && cfun_frame_layout.f8_offset + cfun_frame_layout.high_fprs * 8 > 0)
11142 {
11143 offset = (cfun_frame_layout.f8_offset
11144 + (cfun_frame_layout.high_fprs - 1) * 8);
11145
6a2469fe 11146 for (i = FPR15_REGNUM; i >= FPR8_REGNUM && offset >= 0; i--)
29439367 11147 if (cfun_fpr_save_p (i))
67928721 11148 {
29439367 11149 insn = save_fpr (stack_pointer_rtx, offset, i);
82e9b0b4 11150 if (offset < last_probe_offset)
11151 last_probe_offset = offset;
ffead1ca 11152
67928721 11153 RTX_FRAME_RELATED_P (insn) = 1;
11154 offset -= 8;
11155 }
11156 if (offset >= cfun_frame_layout.f8_offset)
29439367 11157 next_fpr = i;
67928721 11158 }
ffead1ca 11159
646a946e 11160 if (!TARGET_PACKED_STACK)
6a2469fe 11161 next_fpr = cfun_save_high_fprs_p ? FPR15_REGNUM : 0;
4673c1a0 11162
8c0dd614 11163 if (flag_stack_usage_info)
7810b579 11164 current_function_static_stack_size = cfun_frame_layout.frame_size;
11165
8b4a4127 11166 /* Decrement stack pointer. */
4673c1a0 11167
67928721 11168 if (cfun_frame_layout.frame_size > 0)
8b4a4127 11169 {
67928721 11170 rtx frame_off = GEN_INT (-cfun_frame_layout.frame_size);
82e9b0b4 11171 rtx_insn *stack_pointer_backup_loc;
11172 bool temp_reg_clobbered_p;
4673c1a0 11173
cbb300e8 11174 if (s390_stack_size)
82e9b0b4 11175 {
00d233e6 11176 HOST_WIDE_INT stack_guard;
cbb300e8 11177
00d233e6 11178 if (s390_stack_guard)
11179 stack_guard = s390_stack_guard;
cbb300e8 11180 else
00d233e6 11181 {
11182 /* If no value for stack guard is provided the smallest power of 2
11183 larger than the current frame size is chosen. */
11184 stack_guard = 1;
11185 while (stack_guard < cfun_frame_layout.frame_size)
11186 stack_guard <<= 1;
11187 }
cbb300e8 11188
00d233e6 11189 if (cfun_frame_layout.frame_size >= s390_stack_size)
11190 {
8ad6fff9 11191 warning (0, "frame size of function %qs is %wd"
00d233e6 11192 " bytes exceeding user provided stack limit of "
8ad6fff9 11193 "%d bytes. "
00d233e6 11194 "An unconditional trap is added.",
11195 current_function_name(), cfun_frame_layout.frame_size,
11196 s390_stack_size);
11197 emit_insn (gen_trap ());
482869e7 11198 emit_barrier ();
00d233e6 11199 }
11200 else
11201 {
b437383e 11202 /* stack_guard has to be smaller than s390_stack_size.
11203 Otherwise we would emit an AND with zero which would
11204 not match the test under mask pattern. */
11205 if (stack_guard >= s390_stack_size)
11206 {
7fe62d25 11207 warning (0, "frame size of function %qs is %wd"
b437383e 11208 " bytes which is more than half the stack size. "
11209 "The dynamic check would not be reliable. "
11210 "No check emitted for this function.",
11211 current_function_name(),
11212 cfun_frame_layout.frame_size);
11213 }
00d233e6 11214 else
b437383e 11215 {
11216 HOST_WIDE_INT stack_check_mask = ((s390_stack_size - 1)
11217 & ~(stack_guard - 1));
11218
11219 rtx t = gen_rtx_AND (Pmode, stack_pointer_rtx,
11220 GEN_INT (stack_check_mask));
11221 if (TARGET_64BIT)
11222 emit_insn (gen_ctrapdi4 (gen_rtx_EQ (VOIDmode,
11223 t, const0_rtx),
11224 t, const0_rtx, const0_rtx));
11225 else
11226 emit_insn (gen_ctrapsi4 (gen_rtx_EQ (VOIDmode,
11227 t, const0_rtx),
11228 t, const0_rtx, const0_rtx));
11229 }
00d233e6 11230 }
9f522e0c 11231 }
cbb300e8 11232
ffead1ca 11233 if (s390_warn_framesize > 0
cbb300e8 11234 && cfun_frame_layout.frame_size >= s390_warn_framesize)
7fe62d25 11235 warning (0, "frame size of %qs is %wd bytes",
cbb300e8 11236 current_function_name (), cfun_frame_layout.frame_size);
11237
11238 if (s390_warn_dynamicstack_p && cfun->calls_alloca)
c3ceba8e 11239 warning (0, "%qs uses dynamic stack allocation", current_function_name ());
cbb300e8 11240
82e9b0b4 11241 /* Save the location where we could backup the incoming stack
11242 pointer. */
11243 stack_pointer_backup_loc = get_last_insn ();
f81e845f 11244
82e9b0b4 11245 temp_reg_clobbered_p = allocate_stack_space (frame_off, last_probe_offset,
11246 temp_reg);
8b4a4127 11247
82e9b0b4 11248 if (TARGET_BACKCHAIN || next_fpr)
51aa1e9c 11249 {
82e9b0b4 11250 if (temp_reg_clobbered_p)
11251 {
11252 /* allocate_stack_space had to make use of temp_reg and
11253 we need it to hold a backup of the incoming stack
11254 pointer. Calculate back that value from the current
11255 stack pointer. */
11256 s390_prologue_plus_offset (temp_reg, stack_pointer_rtx,
11257 GEN_INT (cfun_frame_layout.frame_size),
11258 false);
11259 }
11260 else
11261 {
11262 /* allocate_stack_space didn't actually required
11263 temp_reg. Insert the stack pointer backup insn
11264 before the stack pointer decrement code - knowing now
11265 that the value will survive. */
11266 emit_insn_after (gen_move_insn (temp_reg, stack_pointer_rtx),
11267 stack_pointer_backup_loc);
11268 }
51aa1e9c 11269 }
8b4a4127 11270
8b4a4127 11271 /* Set backchain. */
f81e845f 11272
e5c64bfc 11273 if (TARGET_BACKCHAIN)
4673c1a0 11274 {
67928721 11275 if (cfun_frame_layout.backchain_offset)
ffead1ca 11276 addr = gen_rtx_MEM (Pmode,
29c05e22 11277 plus_constant (Pmode, stack_pointer_rtx,
67928721 11278 cfun_frame_layout.backchain_offset));
11279 else
ffead1ca 11280 addr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
ce1d5a67 11281 set_mem_alias_set (addr, get_frame_alias_set ());
8b4a4127 11282 insn = emit_insn (gen_move_insn (addr, temp_reg));
4673c1a0 11283 }
90524d70 11284
cbeb677e 11285 /* If we support non-call exceptions (e.g. for Java),
90524d70 11286 we need to make sure the backchain pointer is set up
11287 before any possibly trapping memory access. */
cbeb677e 11288 if (TARGET_BACKCHAIN && cfun->can_throw_non_call_exceptions)
90524d70 11289 {
11290 addr = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
18b42941 11291 emit_clobber (addr);
90524d70 11292 }
8b4a4127 11293 }
82e9b0b4 11294 else if (flag_stack_clash_protection)
11295 dump_stack_clash_frame_info (NO_PROBE_NO_FRAME, false);
4673c1a0 11296
8b4a4127 11297 /* Save fprs 8 - 15 (64 bit ABI). */
f81e845f 11298
67928721 11299 if (cfun_save_high_fprs_p && next_fpr)
8b4a4127 11300 {
062c49fd 11301 /* If the stack might be accessed through a different register
11302 we have to make sure that the stack pointer decrement is not
11303 moved below the use of the stack slots. */
11304 s390_emit_stack_tie ();
11305
ffead1ca 11306 insn = emit_insn (gen_add2_insn (temp_reg,
67928721 11307 GEN_INT (cfun_frame_layout.f8_offset)));
11308
11309 offset = 0;
4673c1a0 11310
6a2469fe 11311 for (i = FPR8_REGNUM; i <= next_fpr; i++)
29439367 11312 if (cfun_fpr_save_p (i))
8b4a4127 11313 {
29c05e22 11314 rtx addr = plus_constant (Pmode, stack_pointer_rtx,
67928721 11315 cfun_frame_layout.frame_size
11316 + cfun_frame_layout.f8_offset
11317 + offset);
ffead1ca 11318
67928721 11319 insn = save_fpr (temp_reg, offset, i);
11320 offset += 8;
8b4a4127 11321 RTX_FRAME_RELATED_P (insn) = 1;
b9c74b4d 11322 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
d1f9b275 11323 gen_rtx_SET (gen_rtx_MEM (DFmode, addr),
b9c74b4d 11324 gen_rtx_REG (DFmode, i)));
8b4a4127 11325 }
11326 }
f81e845f 11327
8b4a4127 11328 /* Set frame pointer, if needed. */
f81e845f 11329
5a5e802f 11330 if (frame_pointer_needed)
8b4a4127 11331 {
11332 insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
11333 RTX_FRAME_RELATED_P (insn) = 1;
11334 }
4673c1a0 11335
8b4a4127 11336 /* Set up got pointer, if needed. */
f81e845f 11337
3072d30e 11338 if (flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM))
20074f87 11339 {
93e0956b 11340 rtx_insn *insns = s390_load_got ();
20074f87 11341
91a55c11 11342 for (rtx_insn *insn = insns; insn; insn = NEXT_INSN (insn))
50a42dec 11343 annotate_constant_pool_refs (insn);
20074f87 11344
11345 emit_insn (insns);
11346 }
f81e845f 11347
de253666 11348 if (TARGET_TPF_PROFILING)
f81e845f 11349 {
11350 /* Generate a BAS instruction to serve as a function
11351 entry intercept to facilitate the use of tracing
346fecd5 11352 algorithms located at the branch target. */
11353 emit_insn (gen_prologue_tpf ());
f81e845f 11354
11355 /* Emit a blockage here so that all code
11356 lies between the profiling mechanisms. */
11357 emit_insn (gen_blockage ());
11358 }
8b4a4127 11359}
4673c1a0 11360
d2833c15 11361/* Expand the epilogue into a bunch of separate insns. */
4673c1a0 11362
8b4a4127 11363void
7346ca58 11364s390_emit_epilogue (bool sibcall)
8b4a4127 11365{
4c554177 11366 rtx frame_pointer, return_reg = NULL_RTX, cfa_restores = NULL_RTX;
abd8f04d 11367 int area_bottom, area_top, offset = 0;
67928721 11368 int next_offset;
78c2b526 11369 int i;
4673c1a0 11370
de253666 11371 if (TARGET_TPF_PROFILING)
f81e845f 11372 {
11373
11374 /* Generate a BAS instruction to serve as a function
11375 entry intercept to facilitate the use of tracing
346fecd5 11376 algorithms located at the branch target. */
f81e845f 11377
f81e845f 11378 /* Emit a blockage here so that all code
9f522e0c 11379 lies between the profiling mechanisms. */
f81e845f 11380 emit_insn (gen_blockage ());
11381
346fecd5 11382 emit_insn (gen_epilogue_tpf ());
f81e845f 11383 }
11384
8b4a4127 11385 /* Check whether to use frame or stack pointer for restore. */
4673c1a0 11386
ffead1ca 11387 frame_pointer = (frame_pointer_needed
67928721 11388 ? hard_frame_pointer_rtx : stack_pointer_rtx);
4673c1a0 11389
67928721 11390 s390_frame_area (&area_bottom, &area_top);
4673c1a0 11391
f81e845f 11392 /* Check whether we can access the register save area.
8b4a4127 11393 If not, increment the frame pointer as required. */
4673c1a0 11394
8b4a4127 11395 if (area_top <= area_bottom)
11396 {
11397 /* Nothing to restore. */
11398 }
67928721 11399 else if (DISP_IN_RANGE (cfun_frame_layout.frame_size + area_bottom)
9f522e0c 11400 && DISP_IN_RANGE (cfun_frame_layout.frame_size + area_top - 1))
8b4a4127 11401 {
11402 /* Area is in range. */
67928721 11403 offset = cfun_frame_layout.frame_size;
8b4a4127 11404 }
11405 else
11406 {
50a42dec 11407 rtx_insn *insn;
11408 rtx frame_off, cfa;
4673c1a0 11409
f81e845f 11410 offset = area_bottom < 0 ? -area_bottom : 0;
67928721 11411 frame_off = GEN_INT (cfun_frame_layout.frame_size - offset);
4673c1a0 11412
d1f9b275 11413 cfa = gen_rtx_SET (frame_pointer,
a3cd0f6a 11414 gen_rtx_PLUS (Pmode, frame_pointer, frame_off));
51aa1e9c 11415 if (DISP_IN_RANGE (INTVAL (frame_off)))
11416 {
50a42dec 11417 rtx set;
11418
11419 set = gen_rtx_SET (frame_pointer,
11420 gen_rtx_PLUS (Pmode, frame_pointer, frame_off));
11421 insn = emit_insn (set);
51aa1e9c 11422 }
11423 else
11424 {
cb888f33 11425 if (!CONST_OK_FOR_K (INTVAL (frame_off)))
51aa1e9c 11426 frame_off = force_const_mem (Pmode, frame_off);
4673c1a0 11427
51aa1e9c 11428 insn = emit_insn (gen_add2_insn (frame_pointer, frame_off));
50a42dec 11429 annotate_constant_pool_refs (insn);
51aa1e9c 11430 }
a3cd0f6a 11431 add_reg_note (insn, REG_CFA_ADJUST_CFA, cfa);
11432 RTX_FRAME_RELATED_P (insn) = 1;
8b4a4127 11433 }
4673c1a0 11434
8b4a4127 11435 /* Restore call saved fprs. */
11436
11437 if (TARGET_64BIT)
4673c1a0 11438 {
67928721 11439 if (cfun_save_high_fprs_p)
11440 {
11441 next_offset = cfun_frame_layout.f8_offset;
6a2469fe 11442 for (i = FPR8_REGNUM; i <= FPR15_REGNUM; i++)
67928721 11443 {
29439367 11444 if (cfun_fpr_save_p (i))
67928721 11445 {
11446 restore_fpr (frame_pointer,
11447 offset + next_offset, i);
a3cd0f6a 11448 cfa_restores
11449 = alloc_reg_note (REG_CFA_RESTORE,
11450 gen_rtx_REG (DFmode, i), cfa_restores);
67928721 11451 next_offset += 8;
11452 }
11453 }
11454 }
ffead1ca 11455
4673c1a0 11456 }
11457 else
11458 {
67928721 11459 next_offset = cfun_frame_layout.f4_offset;
29439367 11460 /* f4, f6 */
6a2469fe 11461 for (i = FPR4_REGNUM; i <= FPR4_REGNUM + 1; i++)
67928721 11462 {
29439367 11463 if (cfun_fpr_save_p (i))
67928721 11464 {
11465 restore_fpr (frame_pointer,
11466 offset + next_offset, i);
a3cd0f6a 11467 cfa_restores
11468 = alloc_reg_note (REG_CFA_RESTORE,
11469 gen_rtx_REG (DFmode, i), cfa_restores);
67928721 11470 next_offset += 8;
11471 }
646a946e 11472 else if (!TARGET_PACKED_STACK)
67928721 11473 next_offset += 8;
11474 }
ffead1ca 11475
8b4a4127 11476 }
4673c1a0 11477
8b4a4127 11478 /* Restore call saved gprs. */
11479
67928721 11480 if (cfun_frame_layout.first_restore_gpr != -1)
8b4a4127 11481 {
9a2a66ae 11482 rtx insn, addr;
43935856 11483 int i;
11484
f81e845f 11485 /* Check for global register and save them
43935856 11486 to stack location from where they get restored. */
11487
67928721 11488 for (i = cfun_frame_layout.first_restore_gpr;
11489 i <= cfun_frame_layout.last_restore_gpr;
43935856 11490 i++)
11491 {
a3cd0f6a 11492 if (global_not_special_regno_p (i))
43935856 11493 {
29c05e22 11494 addr = plus_constant (Pmode, frame_pointer,
ffead1ca 11495 offset + cfun_frame_layout.gprs_offset
5214e6ae 11496 + (i - cfun_frame_layout.first_save_gpr_slot)
b5fdc416 11497 * UNITS_PER_LONG);
43935856 11498 addr = gen_rtx_MEM (Pmode, addr);
ce1d5a67 11499 set_mem_alias_set (addr, get_frame_alias_set ());
43935856 11500 emit_move_insn (addr, gen_rtx_REG (Pmode, i));
f81e845f 11501 }
a3cd0f6a 11502 else
11503 cfa_restores
11504 = alloc_reg_note (REG_CFA_RESTORE,
11505 gen_rtx_REG (Pmode, i), cfa_restores);
43935856 11506 }
8b4a4127 11507
b5e83b9b 11508 /* Fetch return address from stack before load multiple,
11509 this will do good for scheduling.
11510
11511 Only do this if we already decided that r14 needs to be
11512 saved to a stack slot. (And not just because r14 happens to
11513 be in between two GPRs which need saving.) Otherwise it
11514 would be difficult to take that decision back in
11515 s390_optimize_prologue.
11516
11517 This optimization is only helpful on in-order machines. */
11518 if (! sibcall
11519 && cfun_gpr_save_slot (RETURN_REGNUM) == SAVE_SLOT_STACK
11520 && s390_tune <= PROCESSOR_2097_Z10)
11521 {
11522 int return_regnum = find_unused_clobbered_reg();
db7a90aa 11523 if (!return_regnum
11524 || (TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION
11525 && !TARGET_CPU_Z10
11526 && return_regnum == INDIRECT_BRANCH_THUNK_REGNUM))
11527 {
11528 gcc_assert (INDIRECT_BRANCH_THUNK_REGNUM != 4);
11529 return_regnum = 4;
11530 }
b5e83b9b 11531 return_reg = gen_rtx_REG (Pmode, return_regnum);
11532
11533 addr = plus_constant (Pmode, frame_pointer,
11534 offset + cfun_frame_layout.gprs_offset
11535 + (RETURN_REGNUM
11536 - cfun_frame_layout.first_save_gpr_slot)
11537 * UNITS_PER_LONG);
11538 addr = gen_rtx_MEM (Pmode, addr);
11539 set_mem_alias_set (addr, get_frame_alias_set ());
11540 emit_move_insn (return_reg, addr);
d7c99e1a 11541
b5e83b9b 11542 /* Once we did that optimization we have to make sure
11543 s390_optimize_prologue does not try to remove the store
11544 of r14 since we will not be able to find the load issued
11545 here. */
11546 cfun_frame_layout.save_return_addr_p = true;
4673c1a0 11547 }
8b4a4127 11548
67928721 11549 insn = restore_gprs (frame_pointer,
11550 offset + cfun_frame_layout.gprs_offset
ffead1ca 11551 + (cfun_frame_layout.first_restore_gpr
5214e6ae 11552 - cfun_frame_layout.first_save_gpr_slot)
b5fdc416 11553 * UNITS_PER_LONG,
67928721 11554 cfun_frame_layout.first_restore_gpr,
11555 cfun_frame_layout.last_restore_gpr);
a3cd0f6a 11556 insn = emit_insn (insn);
11557 REG_NOTES (insn) = cfa_restores;
11558 add_reg_note (insn, REG_CFA_DEF_CFA,
29c05e22 11559 plus_constant (Pmode, stack_pointer_rtx,
11560 STACK_POINTER_OFFSET));
a3cd0f6a 11561 RTX_FRAME_RELATED_P (insn) = 1;
8b4a4127 11562 }
4673c1a0 11563
ff4ce128 11564 s390_restore_gprs_from_fprs ();
11565
7346ca58 11566 if (! sibcall)
4c554177 11567 {
11568 if (!return_reg && !s390_can_use_return_insn ())
11569 /* We planned to emit (return), be we are not allowed to. */
11570 return_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
11571
11572 if (return_reg)
11573 /* Emit (return) and (use). */
11574 emit_jump_insn (gen_return_use (return_reg));
11575 else
11576 /* The fact that RETURN_REGNUM is used is already reflected by
11577 EPILOGUE_USES. Emit plain (return). */
11578 emit_jump_insn (gen_return ());
11579 }
4673c1a0 11580}
11581
7a64c761 11582/* Implement TARGET_SET_UP_BY_PROLOGUE. */
11583
11584static void
11585s300_set_up_by_prologue (hard_reg_set_container *regs)
11586{
11587 if (cfun->machine->base_reg
11588 && !call_really_used_regs[REGNO (cfun->machine->base_reg)])
11589 SET_HARD_REG_BIT (regs->set, REGNO (cfun->machine->base_reg));
11590}
11591
c6d481f7 11592/* -fsplit-stack support. */
11593
11594/* A SYMBOL_REF for __morestack. */
11595static GTY(()) rtx morestack_ref;
11596
11597/* When using -fsplit-stack, the allocation routines set a field in
11598 the TCB to the bottom of the stack plus this much space, measured
11599 in bytes. */
11600
11601#define SPLIT_STACK_AVAILABLE 1024
11602
11603/* Emit -fsplit-stack prologue, which goes before the regular function
11604 prologue. */
11605
11606void
11607s390_expand_split_stack_prologue (void)
11608{
11609 rtx r1, guard, cc = NULL;
11610 rtx_insn *insn;
11611 /* Offset from thread pointer to __private_ss. */
11612 int psso = TARGET_64BIT ? 0x38 : 0x20;
11613 /* Pointer size in bytes. */
11614 /* Frame size and argument size - the two parameters to __morestack. */
11615 HOST_WIDE_INT frame_size = cfun_frame_layout.frame_size;
11616 /* Align argument size to 8 bytes - simplifies __morestack code. */
11617 HOST_WIDE_INT args_size = crtl->args.size >= 0
11618 ? ((crtl->args.size + 7) & ~7)
11619 : 0;
11620 /* Label to be called by __morestack. */
11621 rtx_code_label *call_done = NULL;
11622 rtx_code_label *parm_base = NULL;
11623 rtx tmp;
11624
11625 gcc_assert (flag_split_stack && reload_completed);
c6d481f7 11626
11627 r1 = gen_rtx_REG (Pmode, 1);
11628
11629 /* If no stack frame will be allocated, don't do anything. */
11630 if (!frame_size)
11631 {
11632 if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
11633 {
11634 /* If va_start is used, just use r15. */
11635 emit_move_insn (r1,
11636 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
11637 GEN_INT (STACK_POINTER_OFFSET)));
11638
11639 }
11640 return;
11641 }
11642
11643 if (morestack_ref == NULL_RTX)
11644 {
11645 morestack_ref = gen_rtx_SYMBOL_REF (Pmode, "__morestack");
11646 SYMBOL_REF_FLAGS (morestack_ref) |= (SYMBOL_FLAG_LOCAL
11647 | SYMBOL_FLAG_FUNCTION);
11648 }
11649
11650 if (CONST_OK_FOR_K (frame_size) || CONST_OK_FOR_Op (frame_size))
11651 {
11652 /* If frame_size will fit in an add instruction, do a stack space
11653 check, and only call __morestack if there's not enough space. */
11654
11655 /* Get thread pointer. r1 is the only register we can always destroy - r0
11656 could contain a static chain (and cannot be used to address memory
11657 anyway), r2-r6 can contain parameters, and r6-r15 are callee-saved. */
11658 emit_move_insn (r1, gen_rtx_REG (Pmode, TP_REGNUM));
11659 /* Aim at __private_ss. */
11660 guard = gen_rtx_MEM (Pmode, plus_constant (Pmode, r1, psso));
11661
11662 /* If less that 1kiB used, skip addition and compare directly with
11663 __private_ss. */
11664 if (frame_size > SPLIT_STACK_AVAILABLE)
11665 {
11666 emit_move_insn (r1, guard);
11667 if (TARGET_64BIT)
11668 emit_insn (gen_adddi3 (r1, r1, GEN_INT (frame_size)));
11669 else
11670 emit_insn (gen_addsi3 (r1, r1, GEN_INT (frame_size)));
11671 guard = r1;
11672 }
11673
11674 /* Compare the (maybe adjusted) guard with the stack pointer. */
11675 cc = s390_emit_compare (LT, stack_pointer_rtx, guard);
11676 }
11677
11678 call_done = gen_label_rtx ();
11679 parm_base = gen_label_rtx ();
11680
11681 /* Emit the parameter block. */
11682 tmp = gen_split_stack_data (parm_base, call_done,
11683 GEN_INT (frame_size),
11684 GEN_INT (args_size));
11685 insn = emit_insn (tmp);
11686 add_reg_note (insn, REG_LABEL_OPERAND, call_done);
11687 LABEL_NUSES (call_done)++;
11688 add_reg_note (insn, REG_LABEL_OPERAND, parm_base);
11689 LABEL_NUSES (parm_base)++;
11690
11691 /* %r1 = litbase. */
11692 insn = emit_move_insn (r1, gen_rtx_LABEL_REF (VOIDmode, parm_base));
11693 add_reg_note (insn, REG_LABEL_OPERAND, parm_base);
11694 LABEL_NUSES (parm_base)++;
11695
11696 /* Now, we need to call __morestack. It has very special calling
11697 conventions: it preserves param/return/static chain registers for
11698 calling main function body, and looks for its own parameters at %r1. */
11699
11700 if (cc != NULL)
11701 {
11702 tmp = gen_split_stack_cond_call (morestack_ref, cc, call_done);
11703
11704 insn = emit_jump_insn (tmp);
11705 JUMP_LABEL (insn) = call_done;
11706 LABEL_NUSES (call_done)++;
11707
11708 /* Mark the jump as very unlikely to be taken. */
9f522e0c 11709 add_reg_br_prob_note (insn,
11710 profile_probability::very_unlikely ());
c6d481f7 11711
11712 if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
11713 {
11714 /* If va_start is used, and __morestack was not called, just use
11715 r15. */
11716 emit_move_insn (r1,
11717 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
11718 GEN_INT (STACK_POINTER_OFFSET)));
11719 }
11720 }
11721 else
11722 {
11723 tmp = gen_split_stack_call (morestack_ref, call_done);
11724 insn = emit_jump_insn (tmp);
11725 JUMP_LABEL (insn) = call_done;
11726 LABEL_NUSES (call_done)++;
11727 emit_barrier ();
11728 }
11729
11730 /* __morestack will call us here. */
11731
11732 emit_label (call_done);
11733}
11734
11735/* We may have to tell the dataflow pass that the split stack prologue
11736 is initializing a register. */
11737
11738static void
11739s390_live_on_entry (bitmap regs)
11740{
11741 if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
11742 {
11743 gcc_assert (flag_split_stack);
11744 bitmap_set_bit (regs, 1);
11745 }
11746}
11747
7a64c761 11748/* Return true if the function can use simple_return to return outside
11749 of a shrink-wrapped region. At present shrink-wrapping is supported
11750 in all cases. */
11751
11752bool
11753s390_can_use_simple_return_insn (void)
11754{
11755 return true;
11756}
11757
11758/* Return true if the epilogue is guaranteed to contain only a return
11759 instruction and if a direct return can therefore be used instead.
11760 One of the main advantages of using direct return instructions
11761 is that we can then use conditional returns. */
11762
11763bool
11764s390_can_use_return_insn (void)
11765{
11766 int i;
11767
11768 if (!reload_completed)
11769 return false;
11770
11771 if (crtl->profile)
11772 return false;
11773
11774 if (TARGET_TPF_PROFILING)
11775 return false;
11776
11777 for (i = 0; i < 16; i++)
1d3cea74 11778 if (cfun_gpr_save_slot (i) != SAVE_SLOT_NONE)
7a64c761 11779 return false;
11780
06fa0630 11781 /* For 31 bit this is not covered by the frame_size check below
11782 since f4, f6 are saved in the register save area without needing
11783 additional stack space. */
11784 if (!TARGET_64BIT
11785 && (cfun_fpr_save_p (FPR4_REGNUM) || cfun_fpr_save_p (FPR6_REGNUM)))
11786 return false;
11787
7a64c761 11788 if (cfun->machine->base_reg
11789 && !call_really_used_regs[REGNO (cfun->machine->base_reg)])
11790 return false;
11791
11792 return cfun_frame_layout.frame_size == 0;
11793}
4673c1a0 11794
76a4c804 11795/* The VX ABI differs for vararg functions. Therefore we need the
11796 prototype of the callee to be available when passing vector type
11797 values. */
11798static const char *
11799s390_invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
11800{
11801 return ((TARGET_VX_ABI
11802 && typelist == 0
11803 && VECTOR_TYPE_P (TREE_TYPE (val))
11804 && (funcdecl == NULL_TREE
11805 || (TREE_CODE (funcdecl) == FUNCTION_DECL
11806 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
19abb0ad 11807 ? N_("vector argument passed to unprototyped function")
76a4c804 11808 : NULL);
11809}
11810
11811
f81e845f 11812/* Return the size in bytes of a function argument of
56769981 11813 type TYPE and/or mode MODE. At least one of TYPE or
11814 MODE must be specified. */
4673c1a0 11815
11816static int
3754d046 11817s390_function_arg_size (machine_mode mode, const_tree type)
4673c1a0 11818{
11819 if (type)
11820 return int_size_in_bytes (type);
11821
0c034860 11822 /* No type info available for some library calls ... */
4673c1a0 11823 if (mode != BLKmode)
11824 return GET_MODE_SIZE (mode);
11825
11826 /* If we have neither type nor mode, abort */
32eda510 11827 gcc_unreachable ();
4673c1a0 11828}
11829
76a4c804 11830/* Return true if a function argument of type TYPE and mode MODE
11831 is to be passed in a vector register, if available. */
11832
11833bool
11834s390_function_arg_vector (machine_mode mode, const_tree type)
11835{
11836 if (!TARGET_VX_ABI)
11837 return false;
11838
11839 if (s390_function_arg_size (mode, type) > 16)
11840 return false;
11841
11842 /* No type info available for some library calls ... */
11843 if (!type)
11844 return VECTOR_MODE_P (mode);
11845
11846 /* The ABI says that record types with a single member are treated
11847 just like that member would be. */
11848 while (TREE_CODE (type) == RECORD_TYPE)
11849 {
11850 tree field, single = NULL_TREE;
11851
11852 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
11853 {
11854 if (TREE_CODE (field) != FIELD_DECL)
11855 continue;
11856
11857 if (single == NULL_TREE)
11858 single = TREE_TYPE (field);
11859 else
11860 return false;
11861 }
11862
11863 if (single == NULL_TREE)
11864 return false;
11865 else
11866 {
11867 /* If the field declaration adds extra byte due to
11868 e.g. padding this is not accepted as vector type. */
11869 if (int_size_in_bytes (single) <= 0
11870 || int_size_in_bytes (single) != int_size_in_bytes (type))
11871 return false;
11872 type = single;
11873 }
11874 }
11875
11876 return VECTOR_TYPE_P (type);
11877}
11878
59652f3f 11879/* Return true if a function argument of type TYPE and mode MODE
11880 is to be passed in a floating-point register, if available. */
11881
11882static bool
3754d046 11883s390_function_arg_float (machine_mode mode, const_tree type)
59652f3f 11884{
76a4c804 11885 if (s390_function_arg_size (mode, type) > 8)
201e502c 11886 return false;
11887
59652f3f 11888 /* Soft-float changes the ABI: no floating-point registers are used. */
11889 if (TARGET_SOFT_FLOAT)
11890 return false;
11891
11892 /* No type info available for some library calls ... */
11893 if (!type)
36868490 11894 return mode == SFmode || mode == DFmode || mode == SDmode || mode == DDmode;
59652f3f 11895
11896 /* The ABI says that record types with a single member are treated
11897 just like that member would be. */
11898 while (TREE_CODE (type) == RECORD_TYPE)
11899 {
11900 tree field, single = NULL_TREE;
11901
1767a056 11902 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
59652f3f 11903 {
11904 if (TREE_CODE (field) != FIELD_DECL)
11905 continue;
11906
11907 if (single == NULL_TREE)
11908 single = TREE_TYPE (field);
11909 else
11910 return false;
11911 }
11912
11913 if (single == NULL_TREE)
11914 return false;
11915 else
11916 type = single;
11917 }
11918
11919 return TREE_CODE (type) == REAL_TYPE;
11920}
11921
201e502c 11922/* Return true if a function argument of type TYPE and mode MODE
11923 is to be passed in an integer register, or a pair of integer
11924 registers, if available. */
11925
11926static bool
3754d046 11927s390_function_arg_integer (machine_mode mode, const_tree type)
201e502c 11928{
11929 int size = s390_function_arg_size (mode, type);
11930 if (size > 8)
11931 return false;
11932
11933 /* No type info available for some library calls ... */
11934 if (!type)
11935 return GET_MODE_CLASS (mode) == MODE_INT
36868490 11936 || (TARGET_SOFT_FLOAT && SCALAR_FLOAT_MODE_P (mode));
201e502c 11937
11938 /* We accept small integral (and similar) types. */
11939 if (INTEGRAL_TYPE_P (type)
f588eb9f 11940 || POINTER_TYPE_P (type)
bd3e12e5 11941 || TREE_CODE (type) == NULLPTR_TYPE
201e502c 11942 || TREE_CODE (type) == OFFSET_TYPE
11943 || (TARGET_SOFT_FLOAT && TREE_CODE (type) == REAL_TYPE))
11944 return true;
11945
11946 /* We also accept structs of size 1, 2, 4, 8 that are not
f588eb9f 11947 passed in floating-point registers. */
201e502c 11948 if (AGGREGATE_TYPE_P (type)
11949 && exact_log2 (size) >= 0
11950 && !s390_function_arg_float (mode, type))
11951 return true;
11952
11953 return false;
11954}
11955
06ac7813 11956/* Return 1 if a function argument ARG is to be passed by reference.
11957 The ABI specifies that only structures of size 1, 2, 4, or 8 bytes
11958 are passed by value, all other structures (and complex numbers) are
11959 passed by reference. */
56769981 11960
b981d932 11961static bool
06ac7813 11962s390_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
4673c1a0 11963{
06ac7813 11964 int size = s390_function_arg_size (arg.mode, arg.type);
76a4c804 11965
06ac7813 11966 if (s390_function_arg_vector (arg.mode, arg.type))
76a4c804 11967 return false;
11968
201e502c 11969 if (size > 8)
11970 return true;
4673c1a0 11971
06ac7813 11972 if (tree type = arg.type)
4673c1a0 11973 {
201e502c 11974 if (AGGREGATE_TYPE_P (type) && exact_log2 (size) < 0)
9f522e0c 11975 return true;
4673c1a0 11976
201e502c 11977 if (TREE_CODE (type) == COMPLEX_TYPE
11978 || TREE_CODE (type) == VECTOR_TYPE)
76a4c804 11979 return true;
4673c1a0 11980 }
f81e845f 11981
76a4c804 11982 return false;
4673c1a0 11983}
11984
0a1b83e3 11985/* Update the data in CUM to advance over argument ARG. */
4673c1a0 11986
12bc26aa 11987static void
0a1b83e3 11988s390_function_arg_advance (cumulative_args_t cum_v,
11989 const function_arg_info &arg)
4673c1a0 11990{
39cba157 11991 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
11992
0a1b83e3 11993 if (s390_function_arg_vector (arg.mode, arg.type))
76a4c804 11994 {
11995 /* We are called for unnamed vector stdarg arguments which are
11996 passed on the stack. In this case this hook does not have to
11997 do anything since stack arguments are tracked by common
11998 code. */
0a1b83e3 11999 if (!arg.named)
76a4c804 12000 return;
12001 cum->vrs += 1;
12002 }
0a1b83e3 12003 else if (s390_function_arg_float (arg.mode, arg.type))
4673c1a0 12004 {
59652f3f 12005 cum->fprs += 1;
4673c1a0 12006 }
0a1b83e3 12007 else if (s390_function_arg_integer (arg.mode, arg.type))
4673c1a0 12008 {
0a1b83e3 12009 int size = s390_function_arg_size (arg.mode, arg.type);
b5fdc416 12010 cum->gprs += ((size + UNITS_PER_LONG - 1) / UNITS_PER_LONG);
4673c1a0 12011 }
201e502c 12012 else
32eda510 12013 gcc_unreachable ();
4673c1a0 12014}
12015
56769981 12016/* Define where to put the arguments to a function.
12017 Value is zero to push the argument on the stack,
12018 or a hard register in which to store the argument.
12019
56769981 12020 CUM is a variable of type CUMULATIVE_ARGS which gives info about
12021 the preceding args and about the function being called.
4b4b9420 12022 ARG is a description of the argument.
56769981 12023
12024 On S/390, we use general purpose registers 2 through 6 to
12025 pass integer, pointer, and certain structure arguments, and
12026 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
12027 to pass floating point arguments. All remaining arguments
12028 are pushed to the stack. */
4673c1a0 12029
12bc26aa 12030static rtx
4b4b9420 12031s390_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
4673c1a0 12032{
39cba157 12033 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
12034
4b4b9420 12035 if (!arg.named)
12036 s390_check_type_for_vector_abi (arg.type, true, false);
76a4c804 12037
4b4b9420 12038 if (s390_function_arg_vector (arg.mode, arg.type))
76a4c804 12039 {
12040 /* Vector arguments being part of the ellipsis are passed on the
12041 stack. */
4b4b9420 12042 if (!arg.named || (cum->vrs + 1 > VEC_ARG_NUM_REG))
76a4c804 12043 return NULL_RTX;
12044
4b4b9420 12045 return gen_rtx_REG (arg.mode, cum->vrs + FIRST_VEC_ARG_REGNO);
76a4c804 12046 }
4b4b9420 12047 else if (s390_function_arg_float (arg.mode, arg.type))
4673c1a0 12048 {
6902d973 12049 if (cum->fprs + 1 > FP_ARG_NUM_REG)
76a4c804 12050 return NULL_RTX;
4673c1a0 12051 else
4b4b9420 12052 return gen_rtx_REG (arg.mode, cum->fprs + 16);
4673c1a0 12053 }
4b4b9420 12054 else if (s390_function_arg_integer (arg.mode, arg.type))
4673c1a0 12055 {
4b4b9420 12056 int size = s390_function_arg_size (arg.mode, arg.type);
b5fdc416 12057 int n_gprs = (size + UNITS_PER_LONG - 1) / UNITS_PER_LONG;
4673c1a0 12058
6902d973 12059 if (cum->gprs + n_gprs > GP_ARG_NUM_REG)
76a4c804 12060 return NULL_RTX;
b5fdc416 12061 else if (n_gprs == 1 || UNITS_PER_WORD == UNITS_PER_LONG)
4b4b9420 12062 return gen_rtx_REG (arg.mode, cum->gprs + 2);
b5fdc416 12063 else if (n_gprs == 2)
12064 {
12065 rtvec p = rtvec_alloc (2);
12066
12067 RTVEC_ELT (p, 0)
12068 = gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, cum->gprs + 2),
12069 const0_rtx);
12070 RTVEC_ELT (p, 1)
12071 = gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, cum->gprs + 3),
12072 GEN_INT (4));
12073
4b4b9420 12074 return gen_rtx_PARALLEL (arg.mode, p);
b5fdc416 12075 }
4673c1a0 12076 }
201e502c 12077
4b4b9420 12078 /* After the real arguments, expand_call calls us once again with an
12079 end marker. Whatever we return here is passed as operand 2 to the
12080 call expanders.
201e502c 12081
12082 We don't need this feature ... */
4b4b9420 12083 else if (arg.end_marker_p ())
201e502c 12084 return const0_rtx;
12085
32eda510 12086 gcc_unreachable ();
201e502c 12087}
12088
d7ab0e3d 12089/* Implement TARGET_FUNCTION_ARG_BOUNDARY. Vector arguments are
12090 left-justified when placed on the stack during parameter passing. */
12091
12092static pad_direction
12093s390_function_arg_padding (machine_mode mode, const_tree type)
12094{
12095 if (s390_function_arg_vector (mode, type))
12096 return PAD_UPWARD;
12097
12098 return default_function_arg_padding (mode, type);
12099}
12100
201e502c 12101/* Return true if return values of type TYPE should be returned
12102 in a memory buffer whose address is passed by the caller as
12103 hidden first argument. */
12104
12105static bool
fb80456a 12106s390_return_in_memory (const_tree type, const_tree fundecl ATTRIBUTE_UNUSED)
201e502c 12107{
12108 /* We accept small integral (and similar) types. */
12109 if (INTEGRAL_TYPE_P (type)
f588eb9f 12110 || POINTER_TYPE_P (type)
201e502c 12111 || TREE_CODE (type) == OFFSET_TYPE
12112 || TREE_CODE (type) == REAL_TYPE)
12113 return int_size_in_bytes (type) > 8;
12114
76a4c804 12115 /* vector types which fit into a VR. */
12116 if (TARGET_VX_ABI
12117 && VECTOR_TYPE_P (type)
12118 && int_size_in_bytes (type) <= 16)
12119 return false;
12120
201e502c 12121 /* Aggregates and similar constructs are always returned
12122 in memory. */
12123 if (AGGREGATE_TYPE_P (type)
12124 || TREE_CODE (type) == COMPLEX_TYPE
76a4c804 12125 || VECTOR_TYPE_P (type))
201e502c 12126 return true;
12127
12128 /* ??? We get called on all sorts of random stuff from
12129 aggregate_value_p. We can't abort, but it's not clear
12130 what's safe to return. Pretend it's a struct I guess. */
12131 return true;
12132}
12133
3b2411a8 12134/* Function arguments and return values are promoted to word size. */
12135
3754d046 12136static machine_mode
12137s390_promote_function_mode (const_tree type, machine_mode mode,
9f522e0c 12138 int *punsignedp,
12139 const_tree fntype ATTRIBUTE_UNUSED,
12140 int for_return ATTRIBUTE_UNUSED)
3b2411a8 12141{
12142 if (INTEGRAL_MODE_P (mode)
b5fdc416 12143 && GET_MODE_SIZE (mode) < UNITS_PER_LONG)
3b2411a8 12144 {
adaf4ef0 12145 if (type != NULL_TREE && POINTER_TYPE_P (type))
3b2411a8 12146 *punsignedp = POINTERS_EXTEND_UNSIGNED;
12147 return Pmode;
12148 }
12149
12150 return mode;
12151}
12152
dc3b3062 12153/* Define where to return a (scalar) value of type RET_TYPE.
12154 If RET_TYPE is null, define where to return a (scalar)
201e502c 12155 value of mode MODE from a libcall. */
12156
dc3b3062 12157static rtx
3754d046 12158s390_function_and_libcall_value (machine_mode mode,
dc3b3062 12159 const_tree ret_type,
12160 const_tree fntype_or_decl,
12161 bool outgoing ATTRIBUTE_UNUSED)
201e502c 12162{
76a4c804 12163 /* For vector return types it is important to use the RET_TYPE
12164 argument whenever available since the middle-end might have
12165 changed the mode to a scalar mode. */
12166 bool vector_ret_type_p = ((ret_type && VECTOR_TYPE_P (ret_type))
12167 || (!ret_type && VECTOR_MODE_P (mode)));
12168
dc3b3062 12169 /* For normal functions perform the promotion as
12170 promote_function_mode would do. */
12171 if (ret_type)
201e502c 12172 {
dc3b3062 12173 int unsignedp = TYPE_UNSIGNED (ret_type);
12174 mode = promote_function_mode (ret_type, mode, &unsignedp,
12175 fntype_or_decl, 1);
201e502c 12176 }
12177
76a4c804 12178 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT
12179 || SCALAR_FLOAT_MODE_P (mode)
12180 || (TARGET_VX_ABI && vector_ret_type_p));
12181 gcc_assert (GET_MODE_SIZE (mode) <= (TARGET_VX_ABI ? 16 : 8));
201e502c 12182
76a4c804 12183 if (TARGET_VX_ABI && vector_ret_type_p)
12184 return gen_rtx_REG (mode, FIRST_VEC_ARG_REGNO);
12185 else if (TARGET_HARD_FLOAT && SCALAR_FLOAT_MODE_P (mode))
201e502c 12186 return gen_rtx_REG (mode, 16);
b5fdc416 12187 else if (GET_MODE_SIZE (mode) <= UNITS_PER_LONG
12188 || UNITS_PER_LONG == UNITS_PER_WORD)
201e502c 12189 return gen_rtx_REG (mode, 2);
b5fdc416 12190 else if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_LONG)
12191 {
dc3b3062 12192 /* This case is triggered when returning a 64 bit value with
12193 -m31 -mzarch. Although the value would fit into a single
12194 register it has to be forced into a 32 bit register pair in
12195 order to match the ABI. */
b5fdc416 12196 rtvec p = rtvec_alloc (2);
12197
12198 RTVEC_ELT (p, 0)
12199 = gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, 2), const0_rtx);
12200 RTVEC_ELT (p, 1)
12201 = gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, 3), GEN_INT (4));
12202
12203 return gen_rtx_PARALLEL (mode, p);
12204 }
12205
12206 gcc_unreachable ();
4673c1a0 12207}
12208
dc3b3062 12209/* Define where to return a scalar return value of type RET_TYPE. */
12210
12211static rtx
12212s390_function_value (const_tree ret_type, const_tree fn_decl_or_type,
12213 bool outgoing)
12214{
12215 return s390_function_and_libcall_value (TYPE_MODE (ret_type), ret_type,
12216 fn_decl_or_type, outgoing);
12217}
12218
12219/* Define where to return a scalar libcall return value of mode
12220 MODE. */
12221
12222static rtx
3754d046 12223s390_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
dc3b3062 12224{
12225 return s390_function_and_libcall_value (mode, NULL_TREE,
12226 NULL_TREE, true);
12227}
12228
4673c1a0 12229
56769981 12230/* Create and return the va_list datatype.
12231
12232 On S/390, va_list is an array type equivalent to
12233
12234 typedef struct __va_list_tag
9f522e0c 12235 {
12236 long __gpr;
12237 long __fpr;
12238 void *__overflow_arg_area;
12239 void *__reg_save_area;
12240 } va_list[1];
56769981 12241
12242 where __gpr and __fpr hold the number of general purpose
12243 or floating point arguments used up to now, respectively,
f81e845f 12244 __overflow_arg_area points to the stack location of the
56769981 12245 next argument passed on the stack, and __reg_save_area
12246 always points to the start of the register area in the
12247 call frame of the current function. The function prologue
12248 saves all registers used for argument passing into this
12249 area if the function uses variable arguments. */
4673c1a0 12250
2e15d750 12251static tree
12252s390_build_builtin_va_list (void)
4673c1a0 12253{
12254 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
12255
5ebb663d 12256 record = lang_hooks.types.make_type (RECORD_TYPE);
4673c1a0 12257
12258 type_decl =
54e46243 12259 build_decl (BUILTINS_LOCATION,
12260 TYPE_DECL, get_identifier ("__va_list_tag"), record);
4673c1a0 12261
54e46243 12262 f_gpr = build_decl (BUILTINS_LOCATION,
12263 FIELD_DECL, get_identifier ("__gpr"),
4673c1a0 12264 long_integer_type_node);
54e46243 12265 f_fpr = build_decl (BUILTINS_LOCATION,
12266 FIELD_DECL, get_identifier ("__fpr"),
4673c1a0 12267 long_integer_type_node);
54e46243 12268 f_ovf = build_decl (BUILTINS_LOCATION,
12269 FIELD_DECL, get_identifier ("__overflow_arg_area"),
4673c1a0 12270 ptr_type_node);
54e46243 12271 f_sav = build_decl (BUILTINS_LOCATION,
12272 FIELD_DECL, get_identifier ("__reg_save_area"),
4673c1a0 12273 ptr_type_node);
12274
6902d973 12275 va_list_gpr_counter_field = f_gpr;
12276 va_list_fpr_counter_field = f_fpr;
12277
4673c1a0 12278 DECL_FIELD_CONTEXT (f_gpr) = record;
12279 DECL_FIELD_CONTEXT (f_fpr) = record;
12280 DECL_FIELD_CONTEXT (f_ovf) = record;
12281 DECL_FIELD_CONTEXT (f_sav) = record;
12282
bc907808 12283 TYPE_STUB_DECL (record) = type_decl;
4673c1a0 12284 TYPE_NAME (record) = type_decl;
12285 TYPE_FIELDS (record) = f_gpr;
1767a056 12286 DECL_CHAIN (f_gpr) = f_fpr;
12287 DECL_CHAIN (f_fpr) = f_ovf;
12288 DECL_CHAIN (f_ovf) = f_sav;
4673c1a0 12289
12290 layout_type (record);
12291
12292 /* The correct type is an array type of one element. */
12293 return build_array_type (record, build_index_type (size_zero_node));
12294}
12295
56769981 12296/* Implement va_start by filling the va_list structure VALIST.
7ccc713a 12297 STDARG_P is always true, and ignored.
12298 NEXTARG points to the first anonymous stack argument.
56769981 12299
8ef587dc 12300 The following global variables are used to initialize
56769981 12301 the va_list structure:
12302
abe32cce 12303 crtl->args.info:
56769981 12304 holds number of gprs and fprs used for named arguments.
abe32cce 12305 crtl->args.arg_offset_rtx:
56769981 12306 holds the offset of the first anonymous stack argument
12307 (relative to the virtual arg pointer). */
4673c1a0 12308
8a58ed0a 12309static void
b40da9a7 12310s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
4673c1a0 12311{
12312 HOST_WIDE_INT n_gpr, n_fpr;
12313 int off;
12314 tree f_gpr, f_fpr, f_ovf, f_sav;
12315 tree gpr, fpr, ovf, sav, t;
12316
12317 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
1767a056 12318 f_fpr = DECL_CHAIN (f_gpr);
12319 f_ovf = DECL_CHAIN (f_fpr);
12320 f_sav = DECL_CHAIN (f_ovf);
4673c1a0 12321
170efcd4 12322 valist = build_simple_mem_ref (valist);
ed03eadb 12323 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
12324 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
12325 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
12326 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
4673c1a0 12327
12328 /* Count number of gp and fp argument registers used. */
12329
abe32cce 12330 n_gpr = crtl->args.info.gprs;
12331 n_fpr = crtl->args.info.fprs;
4673c1a0 12332
6902d973 12333 if (cfun->va_list_gpr_size)
12334 {
75a70cf9 12335 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
12336 build_int_cst (NULL_TREE, n_gpr));
6902d973 12337 TREE_SIDE_EFFECTS (t) = 1;
12338 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
12339 }
4673c1a0 12340
6902d973 12341 if (cfun->va_list_fpr_size)
12342 {
75a70cf9 12343 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9f522e0c 12344 build_int_cst (NULL_TREE, n_fpr));
6902d973 12345 TREE_SIDE_EFFECTS (t) = 1;
12346 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
12347 }
4673c1a0 12348
c6d481f7 12349 if (flag_split_stack
12350 && (lookup_attribute ("no_split_stack", DECL_ATTRIBUTES (cfun->decl))
9f522e0c 12351 == NULL)
c6d481f7 12352 && cfun->machine->split_stack_varargs_pointer == NULL_RTX)
12353 {
12354 rtx reg;
12355 rtx_insn *seq;
12356
12357 reg = gen_reg_rtx (Pmode);
12358 cfun->machine->split_stack_varargs_pointer = reg;
12359
12360 start_sequence ();
12361 emit_move_insn (reg, gen_rtx_REG (Pmode, 1));
12362 seq = get_insns ();
12363 end_sequence ();
12364
12365 push_topmost_sequence ();
12366 emit_insn_after (seq, entry_of_function ());
12367 pop_topmost_sequence ();
12368 }
12369
76a4c804 12370 /* Find the overflow area.
12371 FIXME: This currently is too pessimistic when the vector ABI is
12372 enabled. In that case we *always* set up the overflow area
12373 pointer. */
6902d973 12374 if (n_gpr + cfun->va_list_gpr_size > GP_ARG_NUM_REG
76a4c804 12375 || n_fpr + cfun->va_list_fpr_size > FP_ARG_NUM_REG
12376 || TARGET_VX_ABI)
6902d973 12377 {
c6d481f7 12378 if (cfun->machine->split_stack_varargs_pointer == NULL_RTX)
9f522e0c 12379 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
c6d481f7 12380 else
9f522e0c 12381 t = make_tree (TREE_TYPE (ovf), cfun->machine->split_stack_varargs_pointer);
4673c1a0 12382
abe32cce 12383 off = INTVAL (crtl->args.arg_offset_rtx);
6902d973 12384 off = off < 0 ? 0 : off;
12385 if (TARGET_DEBUG_ARG)
12386 fprintf (stderr, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
12387 (int)n_gpr, (int)n_fpr, off);
4673c1a0 12388
2cc66f2a 12389 t = fold_build_pointer_plus_hwi (t, off);
4673c1a0 12390
75a70cf9 12391 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
6902d973 12392 TREE_SIDE_EFFECTS (t) = 1;
12393 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
12394 }
4673c1a0 12395
12396 /* Find the register save area. */
6902d973 12397 if ((cfun->va_list_gpr_size && n_gpr < GP_ARG_NUM_REG)
12398 || (cfun->va_list_fpr_size && n_fpr < FP_ARG_NUM_REG))
12399 {
12400 t = make_tree (TREE_TYPE (sav), return_address_pointer_rtx);
2cc66f2a 12401 t = fold_build_pointer_plus_hwi (t, -RETURN_REGNUM * UNITS_PER_LONG);
ffead1ca 12402
75a70cf9 12403 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
6902d973 12404 TREE_SIDE_EFFECTS (t) = 1;
12405 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
12406 }
4673c1a0 12407}
12408
f81e845f 12409/* Implement va_arg by updating the va_list structure
56769981 12410 VALIST as required to retrieve an argument of type
f81e845f 12411 TYPE, and returning that argument.
12412
56769981 12413 Generates code equivalent to:
f81e845f 12414
4673c1a0 12415 if (integral value) {
12416 if (size <= 4 && args.gpr < 5 ||
9f522e0c 12417 size > 4 && args.gpr < 4 )
4673c1a0 12418 ret = args.reg_save_area[args.gpr+8]
12419 else
12420 ret = *args.overflow_arg_area++;
76a4c804 12421 } else if (vector value) {
12422 ret = *args.overflow_arg_area;
12423 args.overflow_arg_area += size / 8;
4673c1a0 12424 } else if (float value) {
12425 if (args.fgpr < 2)
12426 ret = args.reg_save_area[args.fpr+64]
12427 else
12428 ret = *args.overflow_arg_area++;
12429 } else if (aggregate value) {
12430 if (args.gpr < 5)
12431 ret = *args.reg_save_area[args.gpr]
12432 else
12433 ret = **args.overflow_arg_area++;
12434 } */
12435
875862bf 12436static tree
ffead1ca 12437s390_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
75a70cf9 12438 gimple_seq *post_p ATTRIBUTE_UNUSED)
4673c1a0 12439{
12440 tree f_gpr, f_fpr, f_ovf, f_sav;
12441 tree gpr, fpr, ovf, sav, reg, t, u;
12442 int indirect_p, size, n_reg, sav_ofs, sav_scale, max_reg;
883b2519 12443 tree lab_false, lab_over = NULL_TREE;
76a4c804 12444 tree addr = create_tmp_var (ptr_type_node, "addr");
12445 bool left_align_p; /* How a value < UNITS_PER_LONG is aligned within
12446 a stack slot. */
4673c1a0 12447
12448 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
1767a056 12449 f_fpr = DECL_CHAIN (f_gpr);
12450 f_ovf = DECL_CHAIN (f_fpr);
12451 f_sav = DECL_CHAIN (f_ovf);
4673c1a0 12452
ed03eadb 12453 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
12454 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
ed03eadb 12455 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
4673c1a0 12456
75a70cf9 12457 /* The tree for args* cannot be shared between gpr/fpr and ovf since
12458 both appear on a lhs. */
12459 valist = unshare_expr (valist);
12460 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
12461
4673c1a0 12462 size = int_size_in_bytes (type);
12463
6b7cfb9c 12464 s390_check_type_for_vector_abi (type, true, false);
12465
f2e4e070 12466 if (pass_va_arg_by_reference (type))
4673c1a0 12467 {
12468 if (TARGET_DEBUG_ARG)
12469 {
12470 fprintf (stderr, "va_arg: aggregate type");
12471 debug_tree (type);
12472 }
12473
12474 /* Aggregates are passed by reference. */
12475 indirect_p = 1;
12476 reg = gpr;
12477 n_reg = 1;
99e8a714 12478
646a946e 12479 /* kernel stack layout on 31 bit: It is assumed here that no padding
99e8a714 12480 will be added by s390_frame_info because for va_args always an even
12481 number of gprs has to be saved r15-r2 = 14 regs. */
b5fdc416 12482 sav_ofs = 2 * UNITS_PER_LONG;
12483 sav_scale = UNITS_PER_LONG;
12484 size = UNITS_PER_LONG;
6902d973 12485 max_reg = GP_ARG_NUM_REG - n_reg;
76a4c804 12486 left_align_p = false;
12487 }
12488 else if (s390_function_arg_vector (TYPE_MODE (type), type))
12489 {
12490 if (TARGET_DEBUG_ARG)
12491 {
12492 fprintf (stderr, "va_arg: vector type");
12493 debug_tree (type);
12494 }
12495
12496 indirect_p = 0;
12497 reg = NULL_TREE;
12498 n_reg = 0;
12499 sav_ofs = 0;
12500 sav_scale = 8;
12501 max_reg = 0;
12502 left_align_p = true;
4673c1a0 12503 }
59652f3f 12504 else if (s390_function_arg_float (TYPE_MODE (type), type))
4673c1a0 12505 {
12506 if (TARGET_DEBUG_ARG)
12507 {
12508 fprintf (stderr, "va_arg: float type");
12509 debug_tree (type);
12510 }
12511
12512 /* FP args go in FP registers, if present. */
12513 indirect_p = 0;
12514 reg = fpr;
12515 n_reg = 1;
b5fdc416 12516 sav_ofs = 16 * UNITS_PER_LONG;
4673c1a0 12517 sav_scale = 8;
6902d973 12518 max_reg = FP_ARG_NUM_REG - n_reg;
76a4c804 12519 left_align_p = false;
4673c1a0 12520 }
12521 else
12522 {
12523 if (TARGET_DEBUG_ARG)
12524 {
12525 fprintf (stderr, "va_arg: other type");
12526 debug_tree (type);
12527 }
12528
12529 /* Otherwise into GP registers. */
12530 indirect_p = 0;
12531 reg = gpr;
b5fdc416 12532 n_reg = (size + UNITS_PER_LONG - 1) / UNITS_PER_LONG;
99e8a714 12533
646a946e 12534 /* kernel stack layout on 31 bit: It is assumed here that no padding
12535 will be added by s390_frame_info because for va_args always an even
12536 number of gprs has to be saved r15-r2 = 14 regs. */
b5fdc416 12537 sav_ofs = 2 * UNITS_PER_LONG;
f81e845f 12538
b5fdc416 12539 if (size < UNITS_PER_LONG)
12540 sav_ofs += UNITS_PER_LONG - size;
4673c1a0 12541
b5fdc416 12542 sav_scale = UNITS_PER_LONG;
6902d973 12543 max_reg = GP_ARG_NUM_REG - n_reg;
76a4c804 12544 left_align_p = false;
4673c1a0 12545 }
12546
12547 /* Pull the value out of the saved registers ... */
12548
76a4c804 12549 if (reg != NULL_TREE)
12550 {
12551 /*
12552 if (reg > ((typeof (reg))max_reg))
9f522e0c 12553 goto lab_false;
4673c1a0 12554
9f522e0c 12555 addr = sav + sav_ofs + reg * save_scale;
4673c1a0 12556
76a4c804 12557 goto lab_over;
4673c1a0 12558
9f522e0c 12559 lab_false:
76a4c804 12560 */
12561
12562 lab_false = create_artificial_label (UNKNOWN_LOCATION);
12563 lab_over = create_artificial_label (UNKNOWN_LOCATION);
12564
12565 t = fold_convert (TREE_TYPE (reg), size_int (max_reg));
12566 t = build2 (GT_EXPR, boolean_type_node, reg, t);
12567 u = build1 (GOTO_EXPR, void_type_node, lab_false);
12568 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
12569 gimplify_and_add (t, pre_p);
4673c1a0 12570
76a4c804 12571 t = fold_build_pointer_plus_hwi (sav, sav_ofs);
12572 u = build2 (MULT_EXPR, TREE_TYPE (reg), reg,
12573 fold_convert (TREE_TYPE (reg), size_int (sav_scale)));
12574 t = fold_build_pointer_plus (t, u);
4673c1a0 12575
76a4c804 12576 gimplify_assign (addr, t, pre_p);
4673c1a0 12577
76a4c804 12578 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
12579
12580 gimple_seq_add_stmt (pre_p, gimple_build_label (lab_false));
12581 }
4673c1a0 12582
12583 /* ... Otherwise out of the overflow area. */
12584
875862bf 12585 t = ovf;
76a4c804 12586 if (size < UNITS_PER_LONG && !left_align_p)
2cc66f2a 12587 t = fold_build_pointer_plus_hwi (t, UNITS_PER_LONG - size);
875862bf 12588
12589 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
12590
75a70cf9 12591 gimplify_assign (addr, t, pre_p);
875862bf 12592
76a4c804 12593 if (size < UNITS_PER_LONG && left_align_p)
12594 t = fold_build_pointer_plus_hwi (t, UNITS_PER_LONG);
12595 else
12596 t = fold_build_pointer_plus_hwi (t, size);
12597
75a70cf9 12598 gimplify_assign (ovf, t, pre_p);
875862bf 12599
76a4c804 12600 if (reg != NULL_TREE)
12601 gimple_seq_add_stmt (pre_p, gimple_build_label (lab_over));
875862bf 12602
12603
12604 /* Increment register save count. */
12605
76a4c804 12606 if (n_reg > 0)
12607 {
12608 u = build2 (PREINCREMENT_EXPR, TREE_TYPE (reg), reg,
12609 fold_convert (TREE_TYPE (reg), size_int (n_reg)));
12610 gimplify_and_add (u, pre_p);
12611 }
875862bf 12612
12613 if (indirect_p)
12614 {
8115f0af 12615 t = build_pointer_type_for_mode (build_pointer_type (type),
12616 ptr_mode, true);
875862bf 12617 addr = fold_convert (t, addr);
12618 addr = build_va_arg_indirect_ref (addr);
12619 }
12620 else
12621 {
8115f0af 12622 t = build_pointer_type_for_mode (type, ptr_mode, true);
875862bf 12623 addr = fold_convert (t, addr);
12624 }
12625
12626 return build_va_arg_indirect_ref (addr);
12627}
12628
5ada7a14 12629/* Emit rtl for the tbegin or tbegin_retry (RETRY != NULL_RTX)
12630 expanders.
12631 DEST - Register location where CC will be stored.
12632 TDB - Pointer to a 256 byte area where to store the transaction.
9f522e0c 12633 diagnostic block. NULL if TDB is not needed.
5ada7a14 12634 RETRY - Retry count value. If non-NULL a retry loop for CC2
9f522e0c 12635 is emitted
5ada7a14 12636 CLOBBER_FPRS_P - If true clobbers for all FPRs are emitted as part
9f522e0c 12637 of the tbegin instruction pattern. */
5ada7a14 12638
12639void
12640s390_expand_tbegin (rtx dest, rtx tdb, rtx retry, bool clobber_fprs_p)
12641{
91dfd73e 12642 rtx retry_plus_two = gen_reg_rtx (SImode);
5ada7a14 12643 rtx retry_reg = gen_reg_rtx (SImode);
79f6a8ed 12644 rtx_code_label *retry_label = NULL;
5ada7a14 12645
12646 if (retry != NULL_RTX)
12647 {
12648 emit_move_insn (retry_reg, retry);
91dfd73e 12649 emit_insn (gen_addsi3 (retry_plus_two, retry_reg, const2_rtx));
12650 emit_insn (gen_addsi3 (retry_reg, retry_reg, const1_rtx));
5ada7a14 12651 retry_label = gen_label_rtx ();
12652 emit_label (retry_label);
12653 }
12654
12655 if (clobber_fprs_p)
044a78dc 12656 {
12657 if (TARGET_VX)
12658 emit_insn (gen_tbegin_1_z13 (gen_rtx_CONST_INT (VOIDmode, TBEGIN_MASK),
12659 tdb));
12660 else
12661 emit_insn (gen_tbegin_1 (gen_rtx_CONST_INT (VOIDmode, TBEGIN_MASK),
12662 tdb));
12663 }
5ada7a14 12664 else
91dfd73e 12665 emit_insn (gen_tbegin_nofloat_1 (gen_rtx_CONST_INT (VOIDmode, TBEGIN_MASK),
12666 tdb));
5ada7a14 12667
91dfd73e 12668 emit_move_insn (dest, gen_rtx_UNSPEC (SImode,
12669 gen_rtvec (1, gen_rtx_REG (CCRAWmode,
12670 CC_REGNUM)),
12671 UNSPEC_CC_TO_INT));
5ada7a14 12672 if (retry != NULL_RTX)
12673 {
d089210f 12674 const int CC0 = 1 << 3;
12675 const int CC1 = 1 << 2;
12676 const int CC3 = 1 << 0;
12677 rtx jump;
5ada7a14 12678 rtx count = gen_reg_rtx (SImode);
93e0956b 12679 rtx_code_label *leave_label = gen_label_rtx ();
d089210f 12680
12681 /* Exit for success and permanent failures. */
5ada7a14 12682 jump = s390_emit_jump (leave_label,
12683 gen_rtx_EQ (VOIDmode,
12684 gen_rtx_REG (CCRAWmode, CC_REGNUM),
d089210f 12685 gen_rtx_CONST_INT (VOIDmode, CC0 | CC1 | CC3)));
12686 LABEL_NUSES (leave_label) = 1;
5ada7a14 12687
12688 /* CC2 - transient failure. Perform retry with ppa. */
91dfd73e 12689 emit_move_insn (count, retry_plus_two);
5ada7a14 12690 emit_insn (gen_subsi3 (count, count, retry_reg));
12691 emit_insn (gen_tx_assist (count));
12692 jump = emit_jump_insn (gen_doloop_si64 (retry_label,
12693 retry_reg,
12694 retry_reg));
12695 JUMP_LABEL (jump) = retry_label;
12696 LABEL_NUSES (retry_label) = 1;
d089210f 12697 emit_label (leave_label);
5ada7a14 12698 }
5ada7a14 12699}
12700
5ada7a14 12701
751c914e 12702/* Return the decl for the target specific builtin with the function
12703 code FCODE. */
12704
12705static tree
12706s390_builtin_decl (unsigned fcode, bool initialized_p ATTRIBUTE_UNUSED)
12707{
12708 if (fcode >= S390_BUILTIN_MAX)
12709 return error_mark_node;
12710
12711 return s390_builtin_decls[fcode];
12712}
12713
d44f2f7c 12714/* We call mcount before the function prologue. So a profiled leaf
12715 function should stay a leaf function. */
12716
12717static bool
12718s390_keep_leaf_when_profiled ()
12719{
12720 return true;
12721}
5ada7a14 12722
875862bf 12723/* Output assembly code for the trampoline template to
12724 stdio stream FILE.
12725
12726 On S/390, we use gpr 1 internally in the trampoline code;
12727 gpr 0 is used to hold the static chain. */
12728
4d946732 12729static void
12730s390_asm_trampoline_template (FILE *file)
875862bf 12731{
12732 rtx op[2];
12733 op[0] = gen_rtx_REG (Pmode, 0);
12734 op[1] = gen_rtx_REG (Pmode, 1);
12735
12736 if (TARGET_64BIT)
12737 {
29335855 12738 output_asm_insn ("basr\t%1,0", op); /* 2 byte */
12739 output_asm_insn ("lmg\t%0,%1,14(%1)", op); /* 6 byte */
12740 output_asm_insn ("br\t%1", op); /* 2 byte */
875862bf 12741 ASM_OUTPUT_SKIP (file, (HOST_WIDE_INT)(TRAMPOLINE_SIZE - 10));
12742 }
12743 else
12744 {
29335855 12745 output_asm_insn ("basr\t%1,0", op); /* 2 byte */
12746 output_asm_insn ("lm\t%0,%1,6(%1)", op); /* 4 byte */
12747 output_asm_insn ("br\t%1", op); /* 2 byte */
875862bf 12748 ASM_OUTPUT_SKIP (file, (HOST_WIDE_INT)(TRAMPOLINE_SIZE - 8));
12749 }
12750}
12751
12752/* Emit RTL insns to initialize the variable parts of a trampoline.
12753 FNADDR is an RTX for the address of the function's pure code.
12754 CXT is an RTX for the static chain value for the function. */
12755
4d946732 12756static void
12757s390_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
875862bf 12758{
4d946732 12759 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
12760 rtx mem;
8a2a84e3 12761
4d946732 12762 emit_block_move (m_tramp, assemble_trampoline_template (),
29335855 12763 GEN_INT (2 * UNITS_PER_LONG), BLOCK_OP_NORMAL);
4d946732 12764
29335855 12765 mem = adjust_address (m_tramp, Pmode, 2 * UNITS_PER_LONG);
4d946732 12766 emit_move_insn (mem, cxt);
29335855 12767 mem = adjust_address (m_tramp, Pmode, 3 * UNITS_PER_LONG);
4d946732 12768 emit_move_insn (mem, fnaddr);
875862bf 12769}
12770
5013a217 12771static void
12772output_asm_nops (const char *user, int hw)
12773{
12774 asm_fprintf (asm_out_file, "\t# NOPs for %s (%d halfwords)\n", user, hw);
12775 while (hw > 0)
12776 {
f5edbf1d 12777 if (hw >= 3)
12778 {
12779 output_asm_insn ("brcl\t0,0", NULL);
12780 hw -= 3;
9f522e0c 12781 }
5013a217 12782 else if (hw >= 2)
9f522e0c 12783 {
12784 output_asm_insn ("bc\t0,0", NULL);
12785 hw -= 2;
12786 }
5013a217 12787 else
9f522e0c 12788 {
12789 output_asm_insn ("bcr\t0,0", NULL);
12790 hw -= 1;
12791 }
5013a217 12792 }
12793}
12794
875862bf 12795/* Output assembler code to FILE to increment profiler label # LABELNO
12796 for profiling a function entry. */
12797
12798void
12799s390_function_profiler (FILE *file, int labelno)
12800{
d2567bb6 12801 rtx op[8];
875862bf 12802
12803 char label[128];
12804 ASM_GENERATE_INTERNAL_LABEL (label, "LP", labelno);
12805
12806 fprintf (file, "# function profiler \n");
12807
12808 op[0] = gen_rtx_REG (Pmode, RETURN_REGNUM);
12809 op[1] = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
29c05e22 12810 op[1] = gen_rtx_MEM (Pmode, plus_constant (Pmode, op[1], UNITS_PER_LONG));
d2567bb6 12811 op[7] = GEN_INT (UNITS_PER_LONG);
875862bf 12812
12813 op[2] = gen_rtx_REG (Pmode, 1);
12814 op[3] = gen_rtx_SYMBOL_REF (Pmode, label);
12815 SYMBOL_REF_FLAGS (op[3]) = SYMBOL_FLAG_LOCAL;
12816
2832ed10 12817 op[4] = gen_rtx_SYMBOL_REF (Pmode, flag_fentry ? "__fentry__" : "_mcount");
875862bf 12818 if (flag_pic)
12819 {
12820 op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), UNSPEC_PLT);
12821 op[4] = gen_rtx_CONST (Pmode, op[4]);
12822 }
12823
06477d3e 12824 if (flag_record_mcount)
12825 fprintf (file, "1:\n");
12826
2832ed10 12827 if (flag_fentry)
12828 {
5013a217 12829 if (flag_nop_mcount)
9f522e0c 12830 output_asm_nops ("-mnop-mcount", /* brasl */ 3);
5013a217 12831 else if (cfun->static_chain_decl)
9f522e0c 12832 warning (OPT_Wcannot_profile, "nested functions cannot be profiled "
2f6d557f 12833 "with %<-mfentry%> on s390");
2832ed10 12834 else
9f522e0c 12835 output_asm_insn ("brasl\t0,%4", op);
2832ed10 12836 }
12837 else if (TARGET_64BIT)
875862bf 12838 {
5013a217 12839 if (flag_nop_mcount)
9f522e0c 12840 output_asm_nops ("-mnop-mcount", /* stg */ 3 + /* larl */ 3 +
12841 /* brasl */ 3 + /* lg */ 3);
5013a217 12842 else
9f522e0c 12843 {
12844 output_asm_insn ("stg\t%0,%1", op);
12845 if (flag_dwarf2_cfi_asm)
12846 output_asm_insn (".cfi_rel_offset\t%0,%7", op);
12847 output_asm_insn ("larl\t%2,%3", op);
12848 output_asm_insn ("brasl\t%0,%4", op);
12849 output_asm_insn ("lg\t%0,%1", op);
12850 if (flag_dwarf2_cfi_asm)
12851 output_asm_insn (".cfi_restore\t%0", op);
12852 }
875862bf 12853 }
f5edbf1d 12854 else
4bc40d24 12855 {
5013a217 12856 if (flag_nop_mcount)
9f522e0c 12857 output_asm_nops ("-mnop-mcount", /* st */ 2 + /* larl */ 3 +
12858 /* brasl */ 3 + /* l */ 2);
5013a217 12859 else
9f522e0c 12860 {
12861 output_asm_insn ("st\t%0,%1", op);
12862 if (flag_dwarf2_cfi_asm)
12863 output_asm_insn (".cfi_rel_offset\t%0,%7", op);
12864 output_asm_insn ("larl\t%2,%3", op);
12865 output_asm_insn ("brasl\t%0,%4", op);
12866 output_asm_insn ("l\t%0,%1", op);
12867 if (flag_dwarf2_cfi_asm)
f5edbf1d 12868 output_asm_insn (".cfi_restore\t%0", op);
12869 }
875862bf 12870 }
06477d3e 12871
12872 if (flag_record_mcount)
12873 {
12874 fprintf (file, "\t.section __mcount_loc, \"a\",@progbits\n");
12875 fprintf (file, "\t.%s 1b\n", TARGET_64BIT ? "quad" : "long");
12876 fprintf (file, "\t.previous\n");
12877 }
875862bf 12878}
12879
12880/* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
12881 into its SYMBOL_REF_FLAGS. */
12882
12883static void
12884s390_encode_section_info (tree decl, rtx rtl, int first)
12885{
12886 default_encode_section_info (decl, rtl, first);
12887
e68d6a13 12888 if (TREE_CODE (decl) == VAR_DECL)
12889 {
78affa36 12890 /* Store the alignment to be able to check if we can use
12891 a larl/load-relative instruction. We only handle the cases
ea283725 12892 that can go wrong (i.e. no FUNC_DECLs). */
09d899d1 12893 if (DECL_ALIGN (decl) == 0 || DECL_ALIGN (decl) % 16)
78affa36 12894 SYMBOL_FLAG_SET_NOTALIGN2 (XEXP (rtl, 0));
ea283725 12895 else if (DECL_ALIGN (decl) % 32)
12896 SYMBOL_FLAG_SET_NOTALIGN4 (XEXP (rtl, 0));
12897 else if (DECL_ALIGN (decl) % 64)
12898 SYMBOL_FLAG_SET_NOTALIGN8 (XEXP (rtl, 0));
e68d6a13 12899 }
12900
12901 /* Literal pool references don't have a decl so they are handled
12902 differently here. We rely on the information in the MEM_ALIGN
78affa36 12903 entry to decide upon the alignment. */
e68d6a13 12904 if (MEM_P (rtl)
12905 && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF
ea283725 12906 && TREE_CONSTANT_POOL_ADDRESS_P (XEXP (rtl, 0)))
78affa36 12907 {
09d899d1 12908 if (MEM_ALIGN (rtl) == 0 || MEM_ALIGN (rtl) % 16)
78affa36 12909 SYMBOL_FLAG_SET_NOTALIGN2 (XEXP (rtl, 0));
ea283725 12910 else if (MEM_ALIGN (rtl) % 32)
12911 SYMBOL_FLAG_SET_NOTALIGN4 (XEXP (rtl, 0));
12912 else if (MEM_ALIGN (rtl) % 64)
12913 SYMBOL_FLAG_SET_NOTALIGN8 (XEXP (rtl, 0));
78affa36 12914 }
875862bf 12915}
12916
12917/* Output thunk to FILE that implements a C++ virtual function call (with
12918 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
12919 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
12920 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
12921 relative to the resulting this pointer. */
12922
12923static void
12924s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
12925 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
12926 tree function)
12927{
f8b27095 12928 const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk));
875862bf 12929 rtx op[10];
12930 int nonlocal = 0;
12931
f8b27095 12932 assemble_start_function (thunk, fnname);
21a38800 12933 /* Make sure unwind info is emitted for the thunk if needed. */
12934 final_start_function (emit_barrier (), file, 1);
12935
875862bf 12936 /* Operand 0 is the target function. */
12937 op[0] = XEXP (DECL_RTL (function), 0);
12938 if (flag_pic && !SYMBOL_REF_LOCAL_P (op[0]))
12939 {
12940 nonlocal = 1;
12941 op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]),
12942 TARGET_64BIT ? UNSPEC_PLT : UNSPEC_GOT);
12943 op[0] = gen_rtx_CONST (Pmode, op[0]);
12944 }
12945
12946 /* Operand 1 is the 'this' pointer. */
12947 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
12948 op[1] = gen_rtx_REG (Pmode, 3);
12949 else
12950 op[1] = gen_rtx_REG (Pmode, 2);
12951
12952 /* Operand 2 is the delta. */
12953 op[2] = GEN_INT (delta);
12954
12955 /* Operand 3 is the vcall_offset. */
12956 op[3] = GEN_INT (vcall_offset);
12957
12958 /* Operand 4 is the temporary register. */
12959 op[4] = gen_rtx_REG (Pmode, 1);
12960
12961 /* Operands 5 to 8 can be used as labels. */
12962 op[5] = NULL_RTX;
12963 op[6] = NULL_RTX;
12964 op[7] = NULL_RTX;
12965 op[8] = NULL_RTX;
12966
12967 /* Operand 9 can be used for temporary register. */
12968 op[9] = NULL_RTX;
12969
12970 /* Generate code. */
12971 if (TARGET_64BIT)
12972 {
12973 /* Setup literal pool pointer if required. */
12974 if ((!DISP_IN_RANGE (delta)
163277cf 12975 && !CONST_OK_FOR_K (delta)
12976 && !CONST_OK_FOR_Os (delta))
875862bf 12977 || (!DISP_IN_RANGE (vcall_offset)
163277cf 12978 && !CONST_OK_FOR_K (vcall_offset)
12979 && !CONST_OK_FOR_Os (vcall_offset)))
875862bf 12980 {
12981 op[5] = gen_label_rtx ();
12982 output_asm_insn ("larl\t%4,%5", op);
12983 }
12984
12985 /* Add DELTA to this pointer. */
12986 if (delta)
12987 {
cb888f33 12988 if (CONST_OK_FOR_J (delta))
875862bf 12989 output_asm_insn ("la\t%1,%2(%1)", op);
12990 else if (DISP_IN_RANGE (delta))
12991 output_asm_insn ("lay\t%1,%2(%1)", op);
cb888f33 12992 else if (CONST_OK_FOR_K (delta))
875862bf 12993 output_asm_insn ("aghi\t%1,%2", op);
9f522e0c 12994 else if (CONST_OK_FOR_Os (delta))
12995 output_asm_insn ("agfi\t%1,%2", op);
875862bf 12996 else
12997 {
12998 op[6] = gen_label_rtx ();
12999 output_asm_insn ("agf\t%1,%6-%5(%4)", op);
13000 }
13001 }
13002
13003 /* Perform vcall adjustment. */
13004 if (vcall_offset)
13005 {
13006 if (DISP_IN_RANGE (vcall_offset))
13007 {
13008 output_asm_insn ("lg\t%4,0(%1)", op);
13009 output_asm_insn ("ag\t%1,%3(%4)", op);
13010 }
cb888f33 13011 else if (CONST_OK_FOR_K (vcall_offset))
875862bf 13012 {
13013 output_asm_insn ("lghi\t%4,%3", op);
13014 output_asm_insn ("ag\t%4,0(%1)", op);
13015 output_asm_insn ("ag\t%1,0(%4)", op);
13016 }
9f522e0c 13017 else if (CONST_OK_FOR_Os (vcall_offset))
13018 {
13019 output_asm_insn ("lgfi\t%4,%3", op);
13020 output_asm_insn ("ag\t%4,0(%1)", op);
13021 output_asm_insn ("ag\t%1,0(%4)", op);
13022 }
875862bf 13023 else
13024 {
13025 op[7] = gen_label_rtx ();
13026 output_asm_insn ("llgf\t%4,%7-%5(%4)", op);
13027 output_asm_insn ("ag\t%4,0(%1)", op);
13028 output_asm_insn ("ag\t%1,0(%4)", op);
13029 }
13030 }
13031
13032 /* Jump to target. */
13033 output_asm_insn ("jg\t%0", op);
13034
13035 /* Output literal pool if required. */
13036 if (op[5])
13037 {
13038 output_asm_insn (".align\t4", op);
13039 targetm.asm_out.internal_label (file, "L",
13040 CODE_LABEL_NUMBER (op[5]));
13041 }
13042 if (op[6])
13043 {
13044 targetm.asm_out.internal_label (file, "L",
13045 CODE_LABEL_NUMBER (op[6]));
13046 output_asm_insn (".long\t%2", op);
13047 }
13048 if (op[7])
13049 {
13050 targetm.asm_out.internal_label (file, "L",
13051 CODE_LABEL_NUMBER (op[7]));
13052 output_asm_insn (".long\t%3", op);
13053 }
13054 }
13055 else
13056 {
13057 /* Setup base pointer if required. */
13058 if (!vcall_offset
13059 || (!DISP_IN_RANGE (delta)
9f522e0c 13060 && !CONST_OK_FOR_K (delta)
163277cf 13061 && !CONST_OK_FOR_Os (delta))
875862bf 13062 || (!DISP_IN_RANGE (delta)
9f522e0c 13063 && !CONST_OK_FOR_K (vcall_offset)
163277cf 13064 && !CONST_OK_FOR_Os (vcall_offset)))
875862bf 13065 {
13066 op[5] = gen_label_rtx ();
13067 output_asm_insn ("basr\t%4,0", op);
13068 targetm.asm_out.internal_label (file, "L",
13069 CODE_LABEL_NUMBER (op[5]));
13070 }
13071
13072 /* Add DELTA to this pointer. */
13073 if (delta)
13074 {
cb888f33 13075 if (CONST_OK_FOR_J (delta))
875862bf 13076 output_asm_insn ("la\t%1,%2(%1)", op);
13077 else if (DISP_IN_RANGE (delta))
13078 output_asm_insn ("lay\t%1,%2(%1)", op);
cb888f33 13079 else if (CONST_OK_FOR_K (delta))
875862bf 13080 output_asm_insn ("ahi\t%1,%2", op);
163277cf 13081 else if (CONST_OK_FOR_Os (delta))
9f522e0c 13082 output_asm_insn ("afi\t%1,%2", op);
875862bf 13083 else
13084 {
13085 op[6] = gen_label_rtx ();
13086 output_asm_insn ("a\t%1,%6-%5(%4)", op);
13087 }
13088 }
13089
13090 /* Perform vcall adjustment. */
13091 if (vcall_offset)
9f522e0c 13092 {
cb888f33 13093 if (CONST_OK_FOR_J (vcall_offset))
875862bf 13094 {
0451e449 13095 output_asm_insn ("l\t%4,0(%1)", op);
875862bf 13096 output_asm_insn ("a\t%1,%3(%4)", op);
13097 }
13098 else if (DISP_IN_RANGE (vcall_offset))
13099 {
0451e449 13100 output_asm_insn ("l\t%4,0(%1)", op);
875862bf 13101 output_asm_insn ("ay\t%1,%3(%4)", op);
13102 }
cb888f33 13103 else if (CONST_OK_FOR_K (vcall_offset))
875862bf 13104 {
13105 output_asm_insn ("lhi\t%4,%3", op);
13106 output_asm_insn ("a\t%4,0(%1)", op);
13107 output_asm_insn ("a\t%1,0(%4)", op);
13108 }
163277cf 13109 else if (CONST_OK_FOR_Os (vcall_offset))
9f522e0c 13110 {
13111 output_asm_insn ("iilf\t%4,%3", op);
13112 output_asm_insn ("a\t%4,0(%1)", op);
13113 output_asm_insn ("a\t%1,0(%4)", op);
13114 }
875862bf 13115 else
13116 {
13117 op[7] = gen_label_rtx ();
13118 output_asm_insn ("l\t%4,%7-%5(%4)", op);
13119 output_asm_insn ("a\t%4,0(%1)", op);
13120 output_asm_insn ("a\t%1,0(%4)", op);
13121 }
4673c1a0 13122
875862bf 13123 /* We had to clobber the base pointer register.
13124 Re-setup the base pointer (with a different base). */
13125 op[5] = gen_label_rtx ();
13126 output_asm_insn ("basr\t%4,0", op);
13127 targetm.asm_out.internal_label (file, "L",
13128 CODE_LABEL_NUMBER (op[5]));
13129 }
4673c1a0 13130
875862bf 13131 /* Jump to target. */
13132 op[8] = gen_label_rtx ();
4673c1a0 13133
875862bf 13134 if (!flag_pic)
13135 output_asm_insn ("l\t%4,%8-%5(%4)", op);
13136 else if (!nonlocal)
13137 output_asm_insn ("a\t%4,%8-%5(%4)", op);
13138 /* We cannot call through .plt, since .plt requires %r12 loaded. */
13139 else if (flag_pic == 1)
13140 {
13141 output_asm_insn ("a\t%4,%8-%5(%4)", op);
13142 output_asm_insn ("l\t%4,%0(%4)", op);
13143 }
13144 else if (flag_pic == 2)
13145 {
13146 op[9] = gen_rtx_REG (Pmode, 0);
13147 output_asm_insn ("l\t%9,%8-4-%5(%4)", op);
13148 output_asm_insn ("a\t%4,%8-%5(%4)", op);
13149 output_asm_insn ("ar\t%4,%9", op);
13150 output_asm_insn ("l\t%4,0(%4)", op);
13151 }
4673c1a0 13152
875862bf 13153 output_asm_insn ("br\t%4", op);
4673c1a0 13154
875862bf 13155 /* Output literal pool. */
13156 output_asm_insn (".align\t4", op);
4673c1a0 13157
875862bf 13158 if (nonlocal && flag_pic == 2)
13159 output_asm_insn (".long\t%0", op);
13160 if (nonlocal)
13161 {
13162 op[0] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
13163 SYMBOL_REF_FLAGS (op[0]) = SYMBOL_FLAG_LOCAL;
13164 }
d93e0d9f 13165
875862bf 13166 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[8]));
13167 if (!flag_pic)
13168 output_asm_insn (".long\t%0", op);
13169 else
13170 output_asm_insn (".long\t%0-%5", op);
4673c1a0 13171
875862bf 13172 if (op[6])
13173 {
13174 targetm.asm_out.internal_label (file, "L",
13175 CODE_LABEL_NUMBER (op[6]));
13176 output_asm_insn (".long\t%2", op);
13177 }
13178 if (op[7])
13179 {
13180 targetm.asm_out.internal_label (file, "L",
13181 CODE_LABEL_NUMBER (op[7]));
13182 output_asm_insn (".long\t%3", op);
13183 }
4673c1a0 13184 }
21a38800 13185 final_end_function ();
f8b27095 13186 assemble_end_function (thunk, fnname);
4673c1a0 13187}
13188
db7a90aa 13189/* Output either an indirect jump or a an indirect call
13190 (RETURN_ADDR_REGNO != INVALID_REGNUM) with target register REGNO
13191 using a branch trampoline disabling branch target prediction. */
13192
13193void
13194s390_indirect_branch_via_thunk (unsigned int regno,
13195 unsigned int return_addr_regno,
13196 rtx comparison_operator,
13197 enum s390_indirect_branch_type type)
13198{
13199 enum s390_indirect_branch_option option;
13200
13201 if (type == s390_indirect_branch_type_return)
13202 {
13203 if (s390_return_addr_from_memory ())
13204 option = s390_opt_function_return_mem;
13205 else
13206 option = s390_opt_function_return_reg;
13207 }
13208 else if (type == s390_indirect_branch_type_jump)
13209 option = s390_opt_indirect_branch_jump;
13210 else if (type == s390_indirect_branch_type_call)
13211 option = s390_opt_indirect_branch_call;
13212 else
13213 gcc_unreachable ();
13214
13215 if (TARGET_INDIRECT_BRANCH_TABLE)
13216 {
13217 char label[32];
13218
13219 ASM_GENERATE_INTERNAL_LABEL (label,
13220 indirect_branch_table_label[option],
13221 indirect_branch_table_label_no[option]++);
13222 ASM_OUTPUT_LABEL (asm_out_file, label);
13223 }
13224
13225 if (return_addr_regno != INVALID_REGNUM)
13226 {
13227 gcc_assert (comparison_operator == NULL_RTX);
13228 fprintf (asm_out_file, " \tbrasl\t%%r%d,", return_addr_regno);
13229 }
13230 else
13231 {
13232 fputs (" \tjg", asm_out_file);
13233 if (comparison_operator != NULL_RTX)
13234 print_operand (asm_out_file, comparison_operator, 'C');
13235
13236 fputs ("\t", asm_out_file);
13237 }
13238
13239 if (TARGET_CPU_Z10)
13240 fprintf (asm_out_file,
13241 TARGET_INDIRECT_BRANCH_THUNK_NAME_EXRL "\n",
13242 regno);
13243 else
13244 fprintf (asm_out_file,
13245 TARGET_INDIRECT_BRANCH_THUNK_NAME_EX "\n",
13246 INDIRECT_BRANCH_THUNK_REGNUM, regno);
13247
13248 if ((option == s390_opt_indirect_branch_jump
13249 && cfun->machine->indirect_branch_jump == indirect_branch_thunk)
13250 || (option == s390_opt_indirect_branch_call
13251 && cfun->machine->indirect_branch_call == indirect_branch_thunk)
13252 || (option == s390_opt_function_return_reg
13253 && cfun->machine->function_return_reg == indirect_branch_thunk)
13254 || (option == s390_opt_function_return_mem
13255 && cfun->machine->function_return_mem == indirect_branch_thunk))
13256 {
13257 if (TARGET_CPU_Z10)
13258 indirect_branch_z10thunk_mask |= (1 << regno);
13259 else
13260 indirect_branch_prez10thunk_mask |= (1 << regno);
13261 }
13262}
13263
13264/* Output an inline thunk for indirect jumps. EXECUTE_TARGET can
13265 either be an address register or a label pointing to the location
13266 of the jump instruction. */
13267
13268void
13269s390_indirect_branch_via_inline_thunk (rtx execute_target)
13270{
13271 if (TARGET_INDIRECT_BRANCH_TABLE)
13272 {
13273 char label[32];
13274
13275 ASM_GENERATE_INTERNAL_LABEL (label,
13276 indirect_branch_table_label[s390_opt_indirect_branch_jump],
13277 indirect_branch_table_label_no[s390_opt_indirect_branch_jump]++);
13278 ASM_OUTPUT_LABEL (asm_out_file, label);
13279 }
13280
13281 if (!TARGET_ZARCH)
13282 fputs ("\t.machinemode zarch\n", asm_out_file);
13283
13284 if (REG_P (execute_target))
13285 fprintf (asm_out_file, "\tex\t%%r0,0(%%r%d)\n", REGNO (execute_target));
13286 else
13287 output_asm_insn ("\texrl\t%%r0,%0", &execute_target);
13288
13289 if (!TARGET_ZARCH)
13290 fputs ("\t.machinemode esa\n", asm_out_file);
13291
13292 fputs ("0:\tj\t0b\n", asm_out_file);
13293}
13294
875862bf 13295static bool
f77c4496 13296s390_valid_pointer_mode (scalar_int_mode mode)
875862bf 13297{
13298 return (mode == SImode || (TARGET_64BIT && mode == DImode));
13299}
56769981 13300
347301d6 13301/* Checks whether the given CALL_EXPR would use a caller
875862bf 13302 saved register. This is used to decide whether sibling call
13303 optimization could be performed on the respective function
13304 call. */
be00aaa8 13305
875862bf 13306static bool
347301d6 13307s390_call_saved_register_used (tree call_expr)
be00aaa8 13308{
39cba157 13309 CUMULATIVE_ARGS cum_v;
13310 cumulative_args_t cum;
875862bf 13311 tree parameter;
875862bf 13312 rtx parm_rtx;
347301d6 13313 int reg, i;
be00aaa8 13314
39cba157 13315 INIT_CUMULATIVE_ARGS (cum_v, NULL, NULL, 0, 0);
13316 cum = pack_cumulative_args (&cum_v);
be00aaa8 13317
347301d6 13318 for (i = 0; i < call_expr_nargs (call_expr); i++)
875862bf 13319 {
347301d6 13320 parameter = CALL_EXPR_ARG (call_expr, i);
32eda510 13321 gcc_assert (parameter);
be00aaa8 13322
875862bf 13323 /* For an undeclared variable passed as parameter we will get
13324 an ERROR_MARK node here. */
13325 if (TREE_CODE (parameter) == ERROR_MARK)
13326 return true;
be00aaa8 13327
76a4c804 13328 /* We assume that in the target function all parameters are
13329 named. This only has an impact on vector argument register
13330 usage none of which is call-saved. */
cae9bfc3 13331 function_arg_info arg (TREE_TYPE (parameter), /*named=*/true);
13332 apply_pass_by_reference_rules (&cum_v, arg);
be00aaa8 13333
4b4b9420 13334 parm_rtx = s390_function_arg (cum, arg);
be00aaa8 13335
0a1b83e3 13336 s390_function_arg_advance (cum, arg);
be00aaa8 13337
b5fdc416 13338 if (!parm_rtx)
13339 continue;
13340
13341 if (REG_P (parm_rtx))
9f522e0c 13342 {
10fa8f76 13343 for (reg = 0; reg < REG_NREGS (parm_rtx); reg++)
b5fdc416 13344 if (!call_used_regs[reg + REGNO (parm_rtx)])
9f522e0c 13345 return true;
b5fdc416 13346 }
13347
13348 if (GET_CODE (parm_rtx) == PARALLEL)
875862bf 13349 {
b5fdc416 13350 int i;
cc6a115b 13351
b5fdc416 13352 for (i = 0; i < XVECLEN (parm_rtx, 0); i++)
13353 {
13354 rtx r = XEXP (XVECEXP (parm_rtx, 0, i), 0);
b5fdc416 13355
13356 gcc_assert (REG_P (r));
13357
10fa8f76 13358 for (reg = 0; reg < REG_NREGS (r); reg++)
b5fdc416 13359 if (!call_used_regs[reg + REGNO (r)])
13360 return true;
13361 }
875862bf 13362 }
b5fdc416 13363
875862bf 13364 }
13365 return false;
13366}
be00aaa8 13367
875862bf 13368/* Return true if the given call expression can be
13369 turned into a sibling call.
13370 DECL holds the declaration of the function to be called whereas
13371 EXP is the call expression itself. */
be00aaa8 13372
875862bf 13373static bool
13374s390_function_ok_for_sibcall (tree decl, tree exp)
13375{
13376 /* The TPF epilogue uses register 1. */
13377 if (TARGET_TPF_PROFILING)
13378 return false;
be00aaa8 13379
875862bf 13380 /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
13381 which would have to be restored before the sibcall. */
a47b0dc3 13382 if (!TARGET_64BIT && flag_pic && decl && !targetm.binds_local_p (decl))
875862bf 13383 return false;
be00aaa8 13384
db7a90aa 13385 /* The thunks for indirect branches require r1 if no exrl is
13386 available. r1 might not be available when doing a sibling
13387 call. */
13388 if (TARGET_INDIRECT_BRANCH_NOBP_CALL
13389 && !TARGET_CPU_Z10
13390 && !decl)
13391 return false;
13392
875862bf 13393 /* Register 6 on s390 is available as an argument register but unfortunately
13394 "caller saved". This makes functions needing this register for arguments
13395 not suitable for sibcalls. */
347301d6 13396 return !s390_call_saved_register_used (exp);
875862bf 13397}
be00aaa8 13398
875862bf 13399/* Return the fixed registers used for condition codes. */
be00aaa8 13400
875862bf 13401static bool
13402s390_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
13403{
13404 *p1 = CC_REGNUM;
13405 *p2 = INVALID_REGNUM;
ffead1ca 13406
875862bf 13407 return true;
13408}
be00aaa8 13409
875862bf 13410/* This function is used by the call expanders of the machine description.
13411 It emits the call insn itself together with the necessary operations
13412 to adjust the target address and returns the emitted insn.
13413 ADDR_LOCATION is the target address rtx
13414 TLS_CALL the location of the thread-local symbol
13415 RESULT_REG the register where the result of the call should be stored
13416 RETADDR_REG the register where the return address should be stored
9f522e0c 13417 If this parameter is NULL_RTX the call is considered
13418 to be a sibling call. */
be00aaa8 13419
93e0956b 13420rtx_insn *
875862bf 13421s390_emit_call (rtx addr_location, rtx tls_call, rtx result_reg,
13422 rtx retaddr_reg)
4673c1a0 13423{
875862bf 13424 bool plt_call = false;
93e0956b 13425 rtx_insn *insn;
db7a90aa 13426 rtx vec[4] = { NULL_RTX };
13427 int elts = 0;
13428 rtx *call = &vec[0];
13429 rtx *clobber_ret_reg = &vec[1];
13430 rtx *use = &vec[2];
13431 rtx *clobber_thunk_reg = &vec[3];
13432 int i;
4a1c604e 13433
875862bf 13434 /* Direct function calls need special treatment. */
13435 if (GET_CODE (addr_location) == SYMBOL_REF)
4673c1a0 13436 {
875862bf 13437 /* When calling a global routine in PIC mode, we must
9f522e0c 13438 replace the symbol itself with the PLT stub. */
875862bf 13439 if (flag_pic && !SYMBOL_REF_LOCAL_P (addr_location))
9f522e0c 13440 {
aa5b4778 13441 if (TARGET_64BIT || retaddr_reg != NULL_RTX)
9c7185f7 13442 {
13443 addr_location = gen_rtx_UNSPEC (Pmode,
13444 gen_rtvec (1, addr_location),
13445 UNSPEC_PLT);
13446 addr_location = gen_rtx_CONST (Pmode, addr_location);
13447 plt_call = true;
13448 }
13449 else
13450 /* For -fpic code the PLT entries might use r12 which is
13451 call-saved. Therefore we cannot do a sibcall when
13452 calling directly using a symbol ref. When reaching
13453 this point we decided (in s390_function_ok_for_sibcall)
13454 to do a sibcall for a function pointer but one of the
13455 optimizers was able to get rid of the function pointer
13456 by propagating the symbol ref into the call. This
13457 optimization is illegal for S/390 so we turn the direct
13458 call into a indirect call again. */
13459 addr_location = force_reg (Pmode, addr_location);
875862bf 13460 }
4673c1a0 13461 }
875862bf 13462
13463 /* If it is already an indirect call or the code above moved the
13464 SYMBOL_REF to somewhere else make sure the address can be found in
13465 register 1. */
13466 if (retaddr_reg == NULL_RTX
13467 && GET_CODE (addr_location) != SYMBOL_REF
13468 && !plt_call)
4673c1a0 13469 {
875862bf 13470 emit_move_insn (gen_rtx_REG (Pmode, SIBCALL_REGNUM), addr_location);
13471 addr_location = gen_rtx_REG (Pmode, SIBCALL_REGNUM);
4673c1a0 13472 }
4673c1a0 13473
db7a90aa 13474 if (TARGET_INDIRECT_BRANCH_NOBP_CALL
13475 && GET_CODE (addr_location) != SYMBOL_REF
13476 && !plt_call)
13477 {
13478 /* Indirect branch thunks require the target to be a single GPR. */
13479 addr_location = force_reg (Pmode, addr_location);
13480
13481 /* Without exrl the indirect branch thunks need an additional
13482 register for larl;ex */
13483 if (!TARGET_CPU_Z10)
13484 {
13485 *clobber_thunk_reg = gen_rtx_REG (Pmode, INDIRECT_BRANCH_THUNK_REGNUM);
13486 *clobber_thunk_reg = gen_rtx_CLOBBER (VOIDmode, *clobber_thunk_reg);
13487 }
13488 }
13489
875862bf 13490 addr_location = gen_rtx_MEM (QImode, addr_location);
db7a90aa 13491 *call = gen_rtx_CALL (VOIDmode, addr_location, const0_rtx);
8b4a4127 13492
875862bf 13493 if (result_reg != NULL_RTX)
db7a90aa 13494 *call = gen_rtx_SET (result_reg, *call);
8b4a4127 13495
875862bf 13496 if (retaddr_reg != NULL_RTX)
13497 {
db7a90aa 13498 *clobber_ret_reg = gen_rtx_CLOBBER (VOIDmode, retaddr_reg);
f81e845f 13499
875862bf 13500 if (tls_call != NULL_RTX)
db7a90aa 13501 *use = gen_rtx_USE (VOIDmode, tls_call);
13502 }
13503
8b4a4127 13504
db7a90aa 13505 for (i = 0; i < 4; i++)
13506 if (vec[i] != NULL_RTX)
13507 elts++;
13508
13509 if (elts > 1)
13510 {
13511 rtvec v;
13512 int e = 0;
13513
13514 v = rtvec_alloc (elts);
13515 for (i = 0; i < 4; i++)
13516 if (vec[i] != NULL_RTX)
13517 {
13518 RTVEC_ELT (v, e) = vec[i];
13519 e++;
13520 }
13521
13522 *call = gen_rtx_PARALLEL (VOIDmode, v);
875862bf 13523 }
8b4a4127 13524
db7a90aa 13525 insn = emit_call_insn (*call);
8b4a4127 13526
875862bf 13527 /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
13528 if ((!TARGET_64BIT && plt_call) || tls_call != NULL_RTX)
13529 {
13530 /* s390_function_ok_for_sibcall should
13531 have denied sibcalls in this case. */
32eda510 13532 gcc_assert (retaddr_reg != NULL_RTX);
c60a7572 13533 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), gen_rtx_REG (Pmode, 12));
875862bf 13534 }
13535 return insn;
13536}
8b4a4127 13537
b2d7ede1 13538/* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
8b4a4127 13539
b2d7ede1 13540static void
875862bf 13541s390_conditional_register_usage (void)
13542{
13543 int i;
8b4a4127 13544
8b4a4127 13545 if (flag_pic)
13546 {
875862bf 13547 fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
13548 call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
8b4a4127 13549 }
f5edbf1d 13550 fixed_regs[BASE_REGNUM] = 0;
13551 call_used_regs[BASE_REGNUM] = 0;
13552 fixed_regs[RETURN_REGNUM] = 0;
13553 call_used_regs[RETURN_REGNUM] = 0;
875862bf 13554 if (TARGET_64BIT)
8b4a4127 13555 {
6a2469fe 13556 for (i = FPR8_REGNUM; i <= FPR15_REGNUM; i++)
875862bf 13557 call_used_regs[i] = call_really_used_regs[i] = 0;
8b4a4127 13558 }
13559 else
13560 {
6a2469fe 13561 call_used_regs[FPR4_REGNUM] = call_really_used_regs[FPR4_REGNUM] = 0;
13562 call_used_regs[FPR6_REGNUM] = call_really_used_regs[FPR6_REGNUM] = 0;
875862bf 13563 }
8b4a4127 13564
875862bf 13565 if (TARGET_SOFT_FLOAT)
13566 {
6a2469fe 13567 for (i = FPR0_REGNUM; i <= FPR15_REGNUM; i++)
875862bf 13568 call_used_regs[i] = fixed_regs[i] = 1;
8b4a4127 13569 }
76a4c804 13570
13571 /* Disable v16 - v31 for non-vector target. */
13572 if (!TARGET_VX)
13573 {
13574 for (i = VR16_REGNUM; i <= VR31_REGNUM; i++)
13575 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
13576 }
8b4a4127 13577}
13578
875862bf 13579/* Corresponding function to eh_return expander. */
7811991d 13580
875862bf 13581static GTY(()) rtx s390_tpf_eh_return_symbol;
13582void
13583s390_emit_tpf_eh_return (rtx target)
7811991d 13584{
93e0956b 13585 rtx_insn *insn;
13586 rtx reg, orig_ra;
525d1294 13587
875862bf 13588 if (!s390_tpf_eh_return_symbol)
13589 s390_tpf_eh_return_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tpf_eh_return");
13590
13591 reg = gen_rtx_REG (Pmode, 2);
bcd3133e 13592 orig_ra = gen_rtx_REG (Pmode, 3);
875862bf 13593
13594 emit_move_insn (reg, target);
bcd3133e 13595 emit_move_insn (orig_ra, get_hard_reg_initial_val (Pmode, RETURN_REGNUM));
875862bf 13596 insn = s390_emit_call (s390_tpf_eh_return_symbol, NULL_RTX, reg,
9f522e0c 13597 gen_rtx_REG (Pmode, RETURN_REGNUM));
875862bf 13598 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
bcd3133e 13599 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), orig_ra);
875862bf 13600
13601 emit_move_insn (EH_RETURN_HANDLER_RTX, reg);
be00aaa8 13602}
13603
875862bf 13604/* Rework the prologue/epilogue to avoid saving/restoring
13605 registers unnecessarily. */
c20f8a1d 13606
6988553d 13607static void
875862bf 13608s390_optimize_prologue (void)
c6933ba6 13609{
93e0956b 13610 rtx_insn *insn, *new_insn, *next_insn;
c20f8a1d 13611
875862bf 13612 /* Do a final recompute of the frame-related data. */
ff4ce128 13613 s390_optimize_register_info ();
c20f8a1d 13614
875862bf 13615 /* If all special registers are in fact used, there's nothing we
13616 can do, so no point in walking the insn list. */
c20f8a1d 13617
ffead1ca 13618 if (cfun_frame_layout.first_save_gpr <= BASE_REGNUM
f5edbf1d 13619 && cfun_frame_layout.last_save_gpr >= BASE_REGNUM)
875862bf 13620 return;
c20f8a1d 13621
875862bf 13622 /* Search for prologue/epilogue insns and replace them. */
875862bf 13623 for (insn = get_insns (); insn; insn = next_insn)
13624 {
13625 int first, last, off;
13626 rtx set, base, offset;
ff4ce128 13627 rtx pat;
c20f8a1d 13628
875862bf 13629 next_insn = NEXT_INSN (insn);
d7bec695 13630
ff4ce128 13631 if (! NONJUMP_INSN_P (insn) || ! RTX_FRAME_RELATED_P (insn))
875862bf 13632 continue;
c20f8a1d 13633
ff4ce128 13634 pat = PATTERN (insn);
13635
13636 /* Remove ldgr/lgdr instructions used for saving and restore
13637 GPRs if possible. */
54530437 13638 if (TARGET_Z10)
13639 {
13640 rtx tmp_pat = pat;
ff4ce128 13641
54530437 13642 if (INSN_CODE (insn) == CODE_FOR_stack_restore_from_fpr)
13643 tmp_pat = XVECEXP (pat, 0, 0);
ff4ce128 13644
54530437 13645 if (GET_CODE (tmp_pat) == SET
13646 && GET_MODE (SET_SRC (tmp_pat)) == DImode
13647 && REG_P (SET_SRC (tmp_pat))
13648 && REG_P (SET_DEST (tmp_pat)))
13649 {
13650 int src_regno = REGNO (SET_SRC (tmp_pat));
13651 int dest_regno = REGNO (SET_DEST (tmp_pat));
13652 int gpr_regno;
13653 int fpr_regno;
13654
13655 if (!((GENERAL_REGNO_P (src_regno)
13656 && FP_REGNO_P (dest_regno))
13657 || (FP_REGNO_P (src_regno)
13658 && GENERAL_REGNO_P (dest_regno))))
13659 continue;
ff4ce128 13660
54530437 13661 gpr_regno = GENERAL_REGNO_P (src_regno) ? src_regno : dest_regno;
13662 fpr_regno = FP_REGNO_P (src_regno) ? src_regno : dest_regno;
ff4ce128 13663
54530437 13664 /* GPR must be call-saved, FPR must be call-clobbered. */
13665 if (!call_really_used_regs[fpr_regno]
13666 || call_really_used_regs[gpr_regno])
13667 continue;
13668
13669 /* It must not happen that what we once saved in an FPR now
13670 needs a stack slot. */
13671 gcc_assert (cfun_gpr_save_slot (gpr_regno) != SAVE_SLOT_STACK);
13672
13673 if (cfun_gpr_save_slot (gpr_regno) == SAVE_SLOT_NONE)
13674 {
13675 remove_insn (insn);
13676 continue;
13677 }
ff4ce128 13678 }
13679 }
13680
13681 if (GET_CODE (pat) == PARALLEL
13682 && store_multiple_operation (pat, VOIDmode))
c20f8a1d 13683 {
ff4ce128 13684 set = XVECEXP (pat, 0, 0);
875862bf 13685 first = REGNO (SET_SRC (set));
ff4ce128 13686 last = first + XVECLEN (pat, 0) - 1;
875862bf 13687 offset = const0_rtx;
13688 base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
13689 off = INTVAL (offset);
c20f8a1d 13690
875862bf 13691 if (GET_CODE (base) != REG || off < 0)
13692 continue;
43944aa4 13693 if (cfun_frame_layout.first_save_gpr != -1
13694 && (cfun_frame_layout.first_save_gpr < first
13695 || cfun_frame_layout.last_save_gpr > last))
13696 continue;
875862bf 13697 if (REGNO (base) != STACK_POINTER_REGNUM
13698 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
13699 continue;
13700 if (first > BASE_REGNUM || last < BASE_REGNUM)
13701 continue;
13702
13703 if (cfun_frame_layout.first_save_gpr != -1)
c20f8a1d 13704 {
93e0956b 13705 rtx s_pat = save_gprs (base,
875862bf 13706 off + (cfun_frame_layout.first_save_gpr
b5fdc416 13707 - first) * UNITS_PER_LONG,
875862bf 13708 cfun_frame_layout.first_save_gpr,
13709 cfun_frame_layout.last_save_gpr);
93e0956b 13710 new_insn = emit_insn_before (s_pat, insn);
875862bf 13711 INSN_ADDRESSES_NEW (new_insn, -1);
c20f8a1d 13712 }
c20f8a1d 13713
875862bf 13714 remove_insn (insn);
13715 continue;
c20f8a1d 13716 }
13717
43944aa4 13718 if (cfun_frame_layout.first_save_gpr == -1
ff4ce128 13719 && GET_CODE (pat) == SET
13720 && GENERAL_REG_P (SET_SRC (pat))
13721 && GET_CODE (SET_DEST (pat)) == MEM)
c20f8a1d 13722 {
ff4ce128 13723 set = pat;
875862bf 13724 first = REGNO (SET_SRC (set));
13725 offset = const0_rtx;
13726 base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
13727 off = INTVAL (offset);
c20f8a1d 13728
875862bf 13729 if (GET_CODE (base) != REG || off < 0)
13730 continue;
13731 if (REGNO (base) != STACK_POINTER_REGNUM
13732 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
13733 continue;
c20f8a1d 13734
875862bf 13735 remove_insn (insn);
13736 continue;
c20f8a1d 13737 }
13738
ff4ce128 13739 if (GET_CODE (pat) == PARALLEL
13740 && load_multiple_operation (pat, VOIDmode))
d7bec695 13741 {
ff4ce128 13742 set = XVECEXP (pat, 0, 0);
875862bf 13743 first = REGNO (SET_DEST (set));
ff4ce128 13744 last = first + XVECLEN (pat, 0) - 1;
875862bf 13745 offset = const0_rtx;
13746 base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
13747 off = INTVAL (offset);
d7bec695 13748
875862bf 13749 if (GET_CODE (base) != REG || off < 0)
13750 continue;
ff4ce128 13751
43944aa4 13752 if (cfun_frame_layout.first_restore_gpr != -1
13753 && (cfun_frame_layout.first_restore_gpr < first
13754 || cfun_frame_layout.last_restore_gpr > last))
13755 continue;
875862bf 13756 if (REGNO (base) != STACK_POINTER_REGNUM
13757 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
13758 continue;
13759 if (first > BASE_REGNUM || last < BASE_REGNUM)
13760 continue;
c20f8a1d 13761
875862bf 13762 if (cfun_frame_layout.first_restore_gpr != -1)
13763 {
93e0956b 13764 rtx rpat = restore_gprs (base,
875862bf 13765 off + (cfun_frame_layout.first_restore_gpr
b5fdc416 13766 - first) * UNITS_PER_LONG,
875862bf 13767 cfun_frame_layout.first_restore_gpr,
13768 cfun_frame_layout.last_restore_gpr);
8240ec0e 13769
13770 /* Remove REG_CFA_RESTOREs for registers that we no
13771 longer need to save. */
93e0956b 13772 REG_NOTES (rpat) = REG_NOTES (insn);
13773 for (rtx *ptr = &REG_NOTES (rpat); *ptr; )
8240ec0e 13774 if (REG_NOTE_KIND (*ptr) == REG_CFA_RESTORE
13775 && ((int) REGNO (XEXP (*ptr, 0))
13776 < cfun_frame_layout.first_restore_gpr))
13777 *ptr = XEXP (*ptr, 1);
13778 else
13779 ptr = &XEXP (*ptr, 1);
93e0956b 13780 new_insn = emit_insn_before (rpat, insn);
8240ec0e 13781 RTX_FRAME_RELATED_P (new_insn) = 1;
875862bf 13782 INSN_ADDRESSES_NEW (new_insn, -1);
13783 }
d7bec695 13784
875862bf 13785 remove_insn (insn);
13786 continue;
d7bec695 13787 }
13788
43944aa4 13789 if (cfun_frame_layout.first_restore_gpr == -1
ff4ce128 13790 && GET_CODE (pat) == SET
13791 && GENERAL_REG_P (SET_DEST (pat))
13792 && GET_CODE (SET_SRC (pat)) == MEM)
c20f8a1d 13793 {
ff4ce128 13794 set = pat;
875862bf 13795 first = REGNO (SET_DEST (set));
13796 offset = const0_rtx;
13797 base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
13798 off = INTVAL (offset);
f81e845f 13799
875862bf 13800 if (GET_CODE (base) != REG || off < 0)
13801 continue;
ff4ce128 13802
875862bf 13803 if (REGNO (base) != STACK_POINTER_REGNUM
13804 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
13805 continue;
5a5e802f 13806
875862bf 13807 remove_insn (insn);
13808 continue;
13809 }
13810 }
5a5e802f 13811}
13812
33d033da 13813/* On z10 and later the dynamic branch prediction must see the
13814 backward jump within a certain windows. If not it falls back to
13815 the static prediction. This function rearranges the loop backward
13816 branch in a way which makes the static prediction always correct.
13817 The function returns true if it added an instruction. */
73df8a45 13818static bool
93e0956b 13819s390_fix_long_loop_prediction (rtx_insn *insn)
73df8a45 13820{
13821 rtx set = single_set (insn);
db7dd023 13822 rtx code_label, label_ref;
158a522b 13823 rtx_insn *uncond_jump;
93e0956b 13824 rtx_insn *cur_insn;
73df8a45 13825 rtx tmp;
13826 int distance;
13827
13828 /* This will exclude branch on count and branch on index patterns
13829 since these are correctly statically predicted. */
13830 if (!set
13831 || SET_DEST (set) != pc_rtx
13832 || GET_CODE (SET_SRC(set)) != IF_THEN_ELSE)
13833 return false;
13834
7a64c761 13835 /* Skip conditional returns. */
13836 if (ANY_RETURN_P (XEXP (SET_SRC (set), 1))
13837 && XEXP (SET_SRC (set), 2) == pc_rtx)
13838 return false;
13839
73df8a45 13840 label_ref = (GET_CODE (XEXP (SET_SRC (set), 1)) == LABEL_REF ?
13841 XEXP (SET_SRC (set), 1) : XEXP (SET_SRC (set), 2));
13842
13843 gcc_assert (GET_CODE (label_ref) == LABEL_REF);
13844
13845 code_label = XEXP (label_ref, 0);
13846
13847 if (INSN_ADDRESSES (INSN_UID (code_label)) == -1
13848 || INSN_ADDRESSES (INSN_UID (insn)) == -1
13849 || (INSN_ADDRESSES (INSN_UID (insn))
33d033da 13850 - INSN_ADDRESSES (INSN_UID (code_label)) < PREDICT_DISTANCE))
73df8a45 13851 return false;
13852
13853 for (distance = 0, cur_insn = PREV_INSN (insn);
33d033da 13854 distance < PREDICT_DISTANCE - 6;
73df8a45 13855 distance += get_attr_length (cur_insn), cur_insn = PREV_INSN (cur_insn))
13856 if (!cur_insn || JUMP_P (cur_insn) || LABEL_P (cur_insn))
13857 return false;
13858
db7dd023 13859 rtx_code_label *new_label = gen_label_rtx ();
73df8a45 13860 uncond_jump = emit_jump_insn_after (
d1f9b275 13861 gen_rtx_SET (pc_rtx,
73df8a45 13862 gen_rtx_LABEL_REF (VOIDmode, code_label)),
13863 insn);
13864 emit_label_after (new_label, uncond_jump);
13865
13866 tmp = XEXP (SET_SRC (set), 1);
13867 XEXP (SET_SRC (set), 1) = XEXP (SET_SRC (set), 2);
13868 XEXP (SET_SRC (set), 2) = tmp;
13869 INSN_CODE (insn) = -1;
13870
13871 XEXP (label_ref, 0) = new_label;
13872 JUMP_LABEL (insn) = new_label;
13873 JUMP_LABEL (uncond_jump) = code_label;
13874
13875 return true;
13876}
13877
3b14a2e6 13878/* Returns 1 if INSN reads the value of REG for purposes not related
13879 to addressing of memory, and 0 otherwise. */
13880static int
93e0956b 13881s390_non_addr_reg_read_p (rtx reg, rtx_insn *insn)
3b14a2e6 13882{
13883 return reg_referenced_p (reg, PATTERN (insn))
13884 && !reg_used_in_mem_p (REGNO (reg), PATTERN (insn));
13885}
13886
512d9edf 13887/* Starting from INSN find_cond_jump looks downwards in the insn
13888 stream for a single jump insn which is the last user of the
13889 condition code set in INSN. */
93e0956b 13890static rtx_insn *
13891find_cond_jump (rtx_insn *insn)
512d9edf 13892{
13893 for (; insn; insn = NEXT_INSN (insn))
13894 {
13895 rtx ite, cc;
13896
13897 if (LABEL_P (insn))
13898 break;
13899
13900 if (!JUMP_P (insn))
13901 {
13902 if (reg_mentioned_p (gen_rtx_REG (CCmode, CC_REGNUM), insn))
13903 break;
13904 continue;
13905 }
13906
13907 /* This will be triggered by a return. */
13908 if (GET_CODE (PATTERN (insn)) != SET)
13909 break;
13910
13911 gcc_assert (SET_DEST (PATTERN (insn)) == pc_rtx);
13912 ite = SET_SRC (PATTERN (insn));
13913
13914 if (GET_CODE (ite) != IF_THEN_ELSE)
13915 break;
13916
13917 cc = XEXP (XEXP (ite, 0), 0);
13918 if (!REG_P (cc) || !CC_REGNO_P (REGNO (cc)))
13919 break;
13920
13921 if (find_reg_note (insn, REG_DEAD, cc))
13922 return insn;
13923 break;
13924 }
13925
93e0956b 13926 return NULL;
512d9edf 13927}
13928
13929/* Swap the condition in COND and the operands in OP0 and OP1 so that
13930 the semantics does not change. If NULL_RTX is passed as COND the
13931 function tries to find the conditional jump starting with INSN. */
13932static void
93e0956b 13933s390_swap_cmp (rtx cond, rtx *op0, rtx *op1, rtx_insn *insn)
512d9edf 13934{
13935 rtx tmp = *op0;
13936
13937 if (cond == NULL_RTX)
13938 {
50fc2d35 13939 rtx_insn *jump = find_cond_jump (NEXT_INSN (insn));
13940 rtx set = jump ? single_set (jump) : NULL_RTX;
512d9edf 13941
50fc2d35 13942 if (set == NULL_RTX)
512d9edf 13943 return;
13944
50fc2d35 13945 cond = XEXP (SET_SRC (set), 0);
512d9edf 13946 }
13947
13948 *op0 = *op1;
13949 *op1 = tmp;
13950 PUT_CODE (cond, swap_condition (GET_CODE (cond)));
13951}
3b14a2e6 13952
13953/* On z10, instructions of the compare-and-branch family have the
13954 property to access the register occurring as second operand with
13955 its bits complemented. If such a compare is grouped with a second
13956 instruction that accesses the same register non-complemented, and
13957 if that register's value is delivered via a bypass, then the
13958 pipeline recycles, thereby causing significant performance decline.
13959 This function locates such situations and exchanges the two
73df8a45 13960 operands of the compare. The function return true whenever it
13961 added an insn. */
13962static bool
93e0956b 13963s390_z10_optimize_cmp (rtx_insn *insn)
3b14a2e6 13964{
93e0956b 13965 rtx_insn *prev_insn, *next_insn;
73df8a45 13966 bool insn_added_p = false;
13967 rtx cond, *op0, *op1;
3b14a2e6 13968
73df8a45 13969 if (GET_CODE (PATTERN (insn)) == PARALLEL)
3b14a2e6 13970 {
73df8a45 13971 /* Handle compare and branch and branch on count
13972 instructions. */
13973 rtx pattern = single_set (insn);
512d9edf 13974
73df8a45 13975 if (!pattern
13976 || SET_DEST (pattern) != pc_rtx
13977 || GET_CODE (SET_SRC (pattern)) != IF_THEN_ELSE)
13978 return false;
3b14a2e6 13979
73df8a45 13980 cond = XEXP (SET_SRC (pattern), 0);
13981 op0 = &XEXP (cond, 0);
13982 op1 = &XEXP (cond, 1);
13983 }
13984 else if (GET_CODE (PATTERN (insn)) == SET)
13985 {
13986 rtx src, dest;
3b14a2e6 13987
73df8a45 13988 /* Handle normal compare instructions. */
13989 src = SET_SRC (PATTERN (insn));
13990 dest = SET_DEST (PATTERN (insn));
512d9edf 13991
73df8a45 13992 if (!REG_P (dest)
13993 || !CC_REGNO_P (REGNO (dest))
13994 || GET_CODE (src) != COMPARE)
13995 return false;
512d9edf 13996
73df8a45 13997 /* s390_swap_cmp will try to find the conditional
13998 jump when passing NULL_RTX as condition. */
13999 cond = NULL_RTX;
14000 op0 = &XEXP (src, 0);
14001 op1 = &XEXP (src, 1);
14002 }
14003 else
14004 return false;
512d9edf 14005
73df8a45 14006 if (!REG_P (*op0) || !REG_P (*op1))
14007 return false;
512d9edf 14008
cc6056e1 14009 if (GET_MODE_CLASS (GET_MODE (*op0)) != MODE_INT)
14010 return false;
14011
73df8a45 14012 /* Swap the COMPARE arguments and its mask if there is a
14013 conflicting access in the previous insn. */
bc1c8bc5 14014 prev_insn = prev_active_insn (insn);
73df8a45 14015 if (prev_insn != NULL_RTX && INSN_P (prev_insn)
14016 && reg_referenced_p (*op1, PATTERN (prev_insn)))
14017 s390_swap_cmp (cond, op0, op1, insn);
14018
14019 /* Check if there is a conflict with the next insn. If there
14020 was no conflict with the previous insn, then swap the
14021 COMPARE arguments and its mask. If we already swapped
14022 the operands, or if swapping them would cause a conflict
14023 with the previous insn, issue a NOP after the COMPARE in
14024 order to separate the two instuctions. */
bc1c8bc5 14025 next_insn = next_active_insn (insn);
73df8a45 14026 if (next_insn != NULL_RTX && INSN_P (next_insn)
14027 && s390_non_addr_reg_read_p (*op1, next_insn))
14028 {
512d9edf 14029 if (prev_insn != NULL_RTX && INSN_P (prev_insn)
73df8a45 14030 && s390_non_addr_reg_read_p (*op0, prev_insn))
512d9edf 14031 {
73df8a45 14032 if (REGNO (*op1) == 0)
9fe9bef6 14033 emit_insn_after (gen_nop_lr1 (), insn);
512d9edf 14034 else
9fe9bef6 14035 emit_insn_after (gen_nop_lr0 (), insn);
73df8a45 14036 insn_added_p = true;
3b14a2e6 14037 }
73df8a45 14038 else
14039 s390_swap_cmp (cond, op0, op1, insn);
3b14a2e6 14040 }
73df8a45 14041 return insn_added_p;
3b14a2e6 14042}
14043
987860a9 14044/* Number of INSNs to be scanned backward in the last BB of the loop
14045 and forward in the first BB of the loop. This usually should be a
14046 bit more than the number of INSNs which could go into one
14047 group. */
14048#define S390_OSC_SCAN_INSN_NUM 5
14049
14050/* Scan LOOP for static OSC collisions and return true if a osc_break
14051 should be issued for this loop. */
14052static bool
14053s390_adjust_loop_scan_osc (struct loop* loop)
14054
14055{
14056 HARD_REG_SET modregs, newregs;
14057 rtx_insn *insn, *store_insn = NULL;
14058 rtx set;
14059 struct s390_address addr_store, addr_load;
14060 subrtx_iterator::array_type array;
14061 int insn_count;
14062
14063 CLEAR_HARD_REG_SET (modregs);
14064
14065 insn_count = 0;
14066 FOR_BB_INSNS_REVERSE (loop->latch, insn)
14067 {
14068 if (!INSN_P (insn) || INSN_CODE (insn) <= 0)
14069 continue;
14070
14071 insn_count++;
14072 if (insn_count > S390_OSC_SCAN_INSN_NUM)
14073 return false;
14074
14075 find_all_hard_reg_sets (insn, &newregs, true);
14076 IOR_HARD_REG_SET (modregs, newregs);
14077
14078 set = single_set (insn);
14079 if (!set)
14080 continue;
14081
14082 if (MEM_P (SET_DEST (set))
14083 && s390_decompose_address (XEXP (SET_DEST (set), 0), &addr_store))
14084 {
14085 store_insn = insn;
14086 break;
14087 }
14088 }
14089
14090 if (store_insn == NULL_RTX)
14091 return false;
14092
14093 insn_count = 0;
14094 FOR_BB_INSNS (loop->header, insn)
14095 {
14096 if (!INSN_P (insn) || INSN_CODE (insn) <= 0)
14097 continue;
14098
14099 if (insn == store_insn)
14100 return false;
14101
14102 insn_count++;
14103 if (insn_count > S390_OSC_SCAN_INSN_NUM)
14104 return false;
14105
14106 find_all_hard_reg_sets (insn, &newregs, true);
14107 IOR_HARD_REG_SET (modregs, newregs);
14108
14109 set = single_set (insn);
14110 if (!set)
14111 continue;
14112
14113 /* An intermediate store disrupts static OSC checking
14114 anyway. */
14115 if (MEM_P (SET_DEST (set))
14116 && s390_decompose_address (XEXP (SET_DEST (set), 0), NULL))
14117 return false;
14118
14119 FOR_EACH_SUBRTX (iter, array, SET_SRC (set), NONCONST)
14120 if (MEM_P (*iter)
14121 && s390_decompose_address (XEXP (*iter, 0), &addr_load)
14122 && rtx_equal_p (addr_load.base, addr_store.base)
14123 && rtx_equal_p (addr_load.indx, addr_store.indx)
14124 && rtx_equal_p (addr_load.disp, addr_store.disp))
14125 {
14126 if ((addr_load.base != NULL_RTX
14127 && TEST_HARD_REG_BIT (modregs, REGNO (addr_load.base)))
14128 || (addr_load.indx != NULL_RTX
14129 && TEST_HARD_REG_BIT (modregs, REGNO (addr_load.indx))))
14130 return true;
14131 }
14132 }
14133 return false;
14134}
14135
14136/* Look for adjustments which can be done on simple innermost
14137 loops. */
14138static void
14139s390_adjust_loops ()
14140{
14141 struct loop *loop = NULL;
14142
14143 df_analyze ();
14144 compute_bb_for_insn ();
14145
14146 /* Find the loops. */
14147 loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
14148
14149 FOR_EACH_LOOP (loop, LI_ONLY_INNERMOST)
14150 {
14151 if (dump_file)
14152 {
14153 flow_loop_dump (loop, dump_file, NULL, 0);
14154 fprintf (dump_file, ";; OSC loop scan Loop: ");
14155 }
14156 if (loop->latch == NULL
14157 || pc_set (BB_END (loop->latch)) == NULL_RTX
14158 || !s390_adjust_loop_scan_osc (loop))
14159 {
14160 if (dump_file)
14161 {
14162 if (loop->latch == NULL)
14163 fprintf (dump_file, " muliple backward jumps\n");
14164 else
14165 {
14166 fprintf (dump_file, " header insn: %d latch insn: %d ",
14167 INSN_UID (BB_HEAD (loop->header)),
14168 INSN_UID (BB_END (loop->latch)));
14169 if (pc_set (BB_END (loop->latch)) == NULL_RTX)
14170 fprintf (dump_file, " loop does not end with jump\n");
14171 else
14172 fprintf (dump_file, " not instrumented\n");
14173 }
14174 }
14175 }
14176 else
14177 {
14178 rtx_insn *new_insn;
14179
14180 if (dump_file)
14181 fprintf (dump_file, " adding OSC break insn: ");
14182 new_insn = emit_insn_before (gen_osc_break (),
14183 BB_END (loop->latch));
14184 INSN_ADDRESSES_NEW (new_insn, -1);
14185 }
14186 }
14187
14188 loop_optimizer_finalize ();
14189
14190 df_finish_pass (false);
14191}
14192
875862bf 14193/* Perform machine-dependent processing. */
7346ca58 14194
875862bf 14195static void
14196s390_reorg (void)
7346ca58 14197{
696157c2 14198 struct constant_pool *pool;
f5edbf1d 14199 rtx_insn *insn;
f4252e72 14200 int hw_before, hw_after;
7346ca58 14201
987860a9 14202 if (s390_tune == PROCESSOR_2964_Z13)
14203 s390_adjust_loops ();
14204
875862bf 14205 /* Make sure all splits have been performed; splits after
14206 machine_dependent_reorg might confuse insn length counts. */
14207 split_all_insns_noflow ();
f588eb9f 14208
875862bf 14209 /* Install the main literal pool and the associated base
696157c2 14210 register load insns. The literal pool might be > 4096 bytes in
14211 size, so that some of its elements cannot be directly accessed.
7346ca58 14212
696157c2 14213 To fix this, we split the single literal pool into multiple
875862bf 14214 pool chunks, reloading the pool base register at various
14215 points throughout the function to ensure it always points to
696157c2 14216 the pool chunk the following code expects. */
44a61e21 14217
696157c2 14218 /* Collect the literal pool. */
14219 pool = s390_mainpool_start ();
14220 if (pool)
875862bf 14221 {
696157c2 14222 /* Finish up literal pool related changes. */
14223 s390_mainpool_finish (pool);
14224 }
14225 else
14226 {
14227 /* If literal pool overflowed, chunkify it. */
14228 pool = s390_chunkify_start ();
14229 s390_chunkify_finish (pool);
80aaaa56 14230 }
80aaaa56 14231
babfdedf 14232 /* Generate out-of-pool execute target insns. */
f5edbf1d 14233 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
babfdedf 14234 {
93e0956b 14235 rtx label;
f5edbf1d 14236 rtx_insn *target;
babfdedf 14237
f5edbf1d 14238 label = s390_execute_label (insn);
14239 if (!label)
14240 continue;
babfdedf 14241
f5edbf1d 14242 gcc_assert (label != const0_rtx);
babfdedf 14243
f5edbf1d 14244 target = emit_label (XEXP (label, 0));
14245 INSN_ADDRESSES_NEW (target, -1);
babfdedf 14246
f5edbf1d 14247 if (JUMP_P (insn))
14248 {
14249 target = emit_jump_insn (s390_execute_target (insn));
14250 /* This is important in order to keep a table jump
14251 pointing at the jump table label. Only this makes it
14252 being recognized as table jump. */
14253 JUMP_LABEL (target) = JUMP_LABEL (insn);
babfdedf 14254 }
f5edbf1d 14255 else
14256 target = emit_insn (s390_execute_target (insn));
14257 INSN_ADDRESSES_NEW (target, -1);
babfdedf 14258 }
14259
14260 /* Try to optimize prologue and epilogue further. */
875862bf 14261 s390_optimize_prologue ();
3b14a2e6 14262
33d033da 14263 /* Walk over the insns and do some >=z10 specific changes. */
117d67d0 14264 if (s390_tune >= PROCESSOR_2097_Z10)
73df8a45 14265 {
93e0956b 14266 rtx_insn *insn;
73df8a45 14267 bool insn_added_p = false;
14268
14269 /* The insn lengths and addresses have to be up to date for the
14270 following manipulations. */
14271 shorten_branches (get_insns ());
14272
14273 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
14274 {
14275 if (!INSN_P (insn) || INSN_CODE (insn) <= 0)
14276 continue;
14277
14278 if (JUMP_P (insn))
33d033da 14279 insn_added_p |= s390_fix_long_loop_prediction (insn);
73df8a45 14280
33d033da 14281 if ((GET_CODE (PATTERN (insn)) == PARALLEL
14282 || GET_CODE (PATTERN (insn)) == SET)
14283 && s390_tune == PROCESSOR_2097_Z10)
73df8a45 14284 insn_added_p |= s390_z10_optimize_cmp (insn);
14285 }
14286
14287 /* Adjust branches if we added new instructions. */
14288 if (insn_added_p)
14289 shorten_branches (get_insns ());
14290 }
f4252e72 14291
14292 s390_function_num_hotpatch_hw (current_function_decl, &hw_before, &hw_after);
14293 if (hw_after > 0)
14294 {
14295 rtx_insn *insn;
14296
06877232 14297 /* Insert NOPs for hotpatching. */
f4252e72 14298 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8ae6e291 14299 /* Emit NOPs
14300 1. inside the area covered by debug information to allow setting
14301 breakpoints at the NOPs,
14302 2. before any insn which results in an asm instruction,
14303 3. before in-function labels to avoid jumping to the NOPs, for
14304 example as part of a loop,
14305 4. before any barrier in case the function is completely empty
14306 (__builtin_unreachable ()) and has neither internal labels nor
14307 active insns.
14308 */
14309 if (active_insn_p (insn) || BARRIER_P (insn) || LABEL_P (insn))
14310 break;
14311 /* Output a series of NOPs before the first active insn. */
14312 while (insn && hw_after > 0)
f4252e72 14313 {
f5edbf1d 14314 if (hw_after >= 3)
f4252e72 14315 {
8ae6e291 14316 emit_insn_before (gen_nop_6_byte (), insn);
f4252e72 14317 hw_after -= 3;
14318 }
14319 else if (hw_after >= 2)
14320 {
8ae6e291 14321 emit_insn_before (gen_nop_4_byte (), insn);
f4252e72 14322 hw_after -= 2;
14323 }
14324 else
14325 {
8ae6e291 14326 emit_insn_before (gen_nop_2_byte (), insn);
f4252e72 14327 hw_after -= 1;
14328 }
14329 }
f4252e72 14330 }
875862bf 14331}
7346ca58 14332
8a2a84e3 14333/* Return true if INSN is a fp load insn writing register REGNO. */
14334static inline bool
ed3e6e5d 14335s390_fpload_toreg (rtx_insn *insn, unsigned int regno)
8a2a84e3 14336{
14337 rtx set;
14338 enum attr_type flag = s390_safe_attr_type (insn);
14339
14340 if (flag != TYPE_FLOADSF && flag != TYPE_FLOADDF)
14341 return false;
14342
14343 set = single_set (insn);
14344
14345 if (set == NULL_RTX)
14346 return false;
14347
14348 if (!REG_P (SET_DEST (set)) || !MEM_P (SET_SRC (set)))
14349 return false;
14350
14351 if (REGNO (SET_DEST (set)) != regno)
14352 return false;
14353
14354 return true;
14355}
14356
14357/* This value describes the distance to be avoided between an
2fbe7a32 14358 arithmetic fp instruction and an fp load writing the same register.
8a2a84e3 14359 Z10_EARLYLOAD_DISTANCE - 1 as well as Z10_EARLYLOAD_DISTANCE + 1 is
14360 fine but the exact value has to be avoided. Otherwise the FP
14361 pipeline will throw an exception causing a major penalty. */
14362#define Z10_EARLYLOAD_DISTANCE 7
14363
14364/* Rearrange the ready list in order to avoid the situation described
14365 for Z10_EARLYLOAD_DISTANCE. A problematic load instruction is
14366 moved to the very end of the ready list. */
14367static void
b24ef467 14368s390_z10_prevent_earlyload_conflicts (rtx_insn **ready, int *nready_p)
8a2a84e3 14369{
14370 unsigned int regno;
14371 int nready = *nready_p;
b24ef467 14372 rtx_insn *tmp;
8a2a84e3 14373 int i;
93e0956b 14374 rtx_insn *insn;
8a2a84e3 14375 rtx set;
14376 enum attr_type flag;
14377 int distance;
14378
14379 /* Skip DISTANCE - 1 active insns. */
14380 for (insn = last_scheduled_insn, distance = Z10_EARLYLOAD_DISTANCE - 1;
14381 distance > 0 && insn != NULL_RTX;
14382 distance--, insn = prev_active_insn (insn))
14383 if (CALL_P (insn) || JUMP_P (insn))
14384 return;
14385
14386 if (insn == NULL_RTX)
14387 return;
14388
14389 set = single_set (insn);
14390
14391 if (set == NULL_RTX || !REG_P (SET_DEST (set))
14392 || GET_MODE_CLASS (GET_MODE (SET_DEST (set))) != MODE_FLOAT)
14393 return;
14394
14395 flag = s390_safe_attr_type (insn);
14396
14397 if (flag == TYPE_FLOADSF || flag == TYPE_FLOADDF)
14398 return;
14399
14400 regno = REGNO (SET_DEST (set));
14401 i = nready - 1;
14402
14403 while (!s390_fpload_toreg (ready[i], regno) && i > 0)
14404 i--;
14405
14406 if (!i)
14407 return;
14408
14409 tmp = ready[i];
b24ef467 14410 memmove (&ready[1], &ready[0], sizeof (rtx_insn *) * i);
8a2a84e3 14411 ready[0] = tmp;
14412}
14413
b3041173 14414/* Returns TRUE if BB is entered via a fallthru edge and all other
c3a8613e 14415 incoming edges are less than likely. */
b3041173 14416static bool
14417s390_bb_fallthru_entry_likely (basic_block bb)
14418{
14419 edge e, fallthru_edge;
14420 edge_iterator ei;
14421
14422 if (!bb)
14423 return false;
14424
14425 fallthru_edge = find_fallthru_edge (bb->preds);
14426 if (!fallthru_edge)
14427 return false;
14428
14429 FOR_EACH_EDGE (e, ei, bb->preds)
14430 if (e != fallthru_edge
c3a8613e 14431 && e->probability >= profile_probability::likely ())
b3041173 14432 return false;
14433
14434 return true;
14435}
81769881 14436
c3a8613e 14437struct s390_sched_state
14438{
14439 /* Number of insns in the group. */
14440 int group_state;
14441 /* Execution side of the group. */
14442 int side;
14443 /* Group can only hold two insns. */
14444 bool group_of_two;
14445} s390_sched_state;
81769881 14446
c3a8613e 14447static struct s390_sched_state sched_state = {0, 1, false};
81769881 14448
0cb69051 14449#define S390_SCHED_ATTR_MASK_CRACKED 0x1
14450#define S390_SCHED_ATTR_MASK_EXPANDED 0x2
14451#define S390_SCHED_ATTR_MASK_ENDGROUP 0x4
14452#define S390_SCHED_ATTR_MASK_GROUPALONE 0x8
c3a8613e 14453#define S390_SCHED_ATTR_MASK_GROUPOFTWO 0x10
81769881 14454
14455static unsigned int
d3ffa7b4 14456s390_get_sched_attrmask (rtx_insn *insn)
81769881 14457{
14458 unsigned int mask = 0;
14459
0cb69051 14460 switch (s390_tune)
14461 {
14462 case PROCESSOR_2827_ZEC12:
14463 if (get_attr_zEC12_cracked (insn))
14464 mask |= S390_SCHED_ATTR_MASK_CRACKED;
14465 if (get_attr_zEC12_expanded (insn))
14466 mask |= S390_SCHED_ATTR_MASK_EXPANDED;
14467 if (get_attr_zEC12_endgroup (insn))
14468 mask |= S390_SCHED_ATTR_MASK_ENDGROUP;
14469 if (get_attr_zEC12_groupalone (insn))
14470 mask |= S390_SCHED_ATTR_MASK_GROUPALONE;
14471 break;
14472 case PROCESSOR_2964_Z13:
14473 if (get_attr_z13_cracked (insn))
14474 mask |= S390_SCHED_ATTR_MASK_CRACKED;
14475 if (get_attr_z13_expanded (insn))
14476 mask |= S390_SCHED_ATTR_MASK_EXPANDED;
14477 if (get_attr_z13_endgroup (insn))
14478 mask |= S390_SCHED_ATTR_MASK_ENDGROUP;
14479 if (get_attr_z13_groupalone (insn))
14480 mask |= S390_SCHED_ATTR_MASK_GROUPALONE;
c3a8613e 14481 if (get_attr_z13_groupoftwo (insn))
14482 mask |= S390_SCHED_ATTR_MASK_GROUPOFTWO;
14483 break;
14484 case PROCESSOR_3906_Z14:
14485 if (get_attr_z14_cracked (insn))
14486 mask |= S390_SCHED_ATTR_MASK_CRACKED;
14487 if (get_attr_z14_expanded (insn))
14488 mask |= S390_SCHED_ATTR_MASK_EXPANDED;
14489 if (get_attr_z14_endgroup (insn))
14490 mask |= S390_SCHED_ATTR_MASK_ENDGROUP;
14491 if (get_attr_z14_groupalone (insn))
14492 mask |= S390_SCHED_ATTR_MASK_GROUPALONE;
14493 if (get_attr_z14_groupoftwo (insn))
14494 mask |= S390_SCHED_ATTR_MASK_GROUPOFTWO;
0cb69051 14495 break;
b3b57123 14496 case PROCESSOR_8561_ARCH13:
14497 if (get_attr_arch13_cracked (insn))
14498 mask |= S390_SCHED_ATTR_MASK_CRACKED;
14499 if (get_attr_arch13_expanded (insn))
14500 mask |= S390_SCHED_ATTR_MASK_EXPANDED;
14501 if (get_attr_arch13_endgroup (insn))
14502 mask |= S390_SCHED_ATTR_MASK_ENDGROUP;
14503 if (get_attr_arch13_groupalone (insn))
14504 mask |= S390_SCHED_ATTR_MASK_GROUPALONE;
14505 if (get_attr_arch13_groupoftwo (insn))
14506 mask |= S390_SCHED_ATTR_MASK_GROUPOFTWO;
14507 break;
0cb69051 14508 default:
14509 gcc_unreachable ();
14510 }
14511 return mask;
14512}
14513
14514static unsigned int
14515s390_get_unit_mask (rtx_insn *insn, int *units)
14516{
14517 unsigned int mask = 0;
14518
14519 switch (s390_tune)
14520 {
14521 case PROCESSOR_2964_Z13:
fef19ece 14522 *units = 4;
0cb69051 14523 if (get_attr_z13_unit_lsu (insn))
14524 mask |= 1 << 0;
fef19ece 14525 if (get_attr_z13_unit_fxa (insn))
0cb69051 14526 mask |= 1 << 1;
fef19ece 14527 if (get_attr_z13_unit_fxb (insn))
0cb69051 14528 mask |= 1 << 2;
fef19ece 14529 if (get_attr_z13_unit_vfu (insn))
14530 mask |= 1 << 3;
0cb69051 14531 break;
c3a8613e 14532 case PROCESSOR_3906_Z14:
14533 *units = 4;
14534 if (get_attr_z14_unit_lsu (insn))
14535 mask |= 1 << 0;
14536 if (get_attr_z14_unit_fxa (insn))
14537 mask |= 1 << 1;
14538 if (get_attr_z14_unit_fxb (insn))
14539 mask |= 1 << 2;
14540 if (get_attr_z14_unit_vfu (insn))
14541 mask |= 1 << 3;
14542 break;
b3b57123 14543 case PROCESSOR_8561_ARCH13:
14544 *units = 4;
14545 if (get_attr_arch13_unit_lsu (insn))
14546 mask |= 1 << 0;
14547 if (get_attr_arch13_unit_fxa (insn))
14548 mask |= 1 << 1;
14549 if (get_attr_arch13_unit_fxb (insn))
14550 mask |= 1 << 2;
14551 if (get_attr_arch13_unit_vfu (insn))
14552 mask |= 1 << 3;
14553 break;
0cb69051 14554 default:
14555 gcc_unreachable ();
14556 }
81769881 14557 return mask;
14558}
14559
c3a8613e 14560static bool
14561s390_is_fpd (rtx_insn *insn)
14562{
14563 if (insn == NULL_RTX)
14564 return false;
14565
b3b57123 14566 return get_attr_z13_unit_fpd (insn) || get_attr_z14_unit_fpd (insn)
14567 || get_attr_arch13_unit_fpd (insn);
c3a8613e 14568}
14569
14570static bool
14571s390_is_fxd (rtx_insn *insn)
14572{
14573 if (insn == NULL_RTX)
14574 return false;
14575
b3b57123 14576 return get_attr_z13_unit_fxd (insn) || get_attr_z14_unit_fxd (insn)
14577 || get_attr_arch13_unit_fxd (insn);
c3a8613e 14578}
14579
14580/* Returns TRUE if INSN is a long-running instruction. */
14581static bool
14582s390_is_longrunning (rtx_insn *insn)
14583{
14584 if (insn == NULL_RTX)
14585 return false;
14586
14587 return s390_is_fxd (insn) || s390_is_fpd (insn);
14588}
14589
14590
81769881 14591/* Return the scheduling score for INSN. The higher the score the
14592 better. The score is calculated from the OOO scheduling attributes
c3a8613e 14593 of INSN and the scheduling state sched_state. */
81769881 14594static int
d3ffa7b4 14595s390_sched_score (rtx_insn *insn)
81769881 14596{
14597 unsigned int mask = s390_get_sched_attrmask (insn);
14598 int score = 0;
14599
c3a8613e 14600 switch (sched_state.group_state)
81769881 14601 {
14602 case 0:
14603 /* Try to put insns into the first slot which would otherwise
14604 break a group. */
0cb69051 14605 if ((mask & S390_SCHED_ATTR_MASK_CRACKED) != 0
14606 || (mask & S390_SCHED_ATTR_MASK_EXPANDED) != 0)
81769881 14607 score += 5;
0cb69051 14608 if ((mask & S390_SCHED_ATTR_MASK_GROUPALONE) != 0)
81769881 14609 score += 10;
c3a8613e 14610 break;
81769881 14611 case 1:
14612 /* Prefer not cracked insns while trying to put together a
14613 group. */
0cb69051 14614 if ((mask & S390_SCHED_ATTR_MASK_CRACKED) == 0
14615 && (mask & S390_SCHED_ATTR_MASK_EXPANDED) == 0
14616 && (mask & S390_SCHED_ATTR_MASK_GROUPALONE) == 0)
81769881 14617 score += 10;
0cb69051 14618 if ((mask & S390_SCHED_ATTR_MASK_ENDGROUP) == 0)
81769881 14619 score += 5;
c3a8613e 14620 /* If we are in a group of two already, try to schedule another
14621 group-of-two insn to avoid shortening another group. */
14622 if (sched_state.group_of_two
14623 && (mask & S390_SCHED_ATTR_MASK_GROUPOFTWO) != 0)
14624 score += 15;
81769881 14625 break;
14626 case 2:
14627 /* Prefer not cracked insns while trying to put together a
14628 group. */
0cb69051 14629 if ((mask & S390_SCHED_ATTR_MASK_CRACKED) == 0
14630 && (mask & S390_SCHED_ATTR_MASK_EXPANDED) == 0
14631 && (mask & S390_SCHED_ATTR_MASK_GROUPALONE) == 0)
81769881 14632 score += 10;
14633 /* Prefer endgroup insns in the last slot. */
0cb69051 14634 if ((mask & S390_SCHED_ATTR_MASK_ENDGROUP) != 0)
81769881 14635 score += 10;
c3a8613e 14636 /* Try to avoid group-of-two insns in the last slot as they will
14637 shorten this group as well as the next one. */
14638 if ((mask & S390_SCHED_ATTR_MASK_GROUPOFTWO) != 0)
14639 score = MAX (0, score - 15);
81769881 14640 break;
14641 }
0cb69051 14642
c9213ca0 14643 if (s390_tune >= PROCESSOR_2964_Z13)
0cb69051 14644 {
14645 int units, i;
14646 unsigned unit_mask, m = 1;
14647
14648 unit_mask = s390_get_unit_mask (insn, &units);
14649 gcc_assert (units <= MAX_SCHED_UNITS);
14650
14651 /* Add a score in range 0..MAX_SCHED_MIX_SCORE depending on how long
14652 ago the last insn of this unit type got scheduled. This is
14653 supposed to help providing a proper instruction mix to the
14654 CPU. */
14655 for (i = 0; i < units; i++, m <<= 1)
14656 if (m & unit_mask)
c3a8613e 14657 score += (last_scheduled_unit_distance[i][sched_state.side]
14658 * MAX_SCHED_MIX_SCORE / MAX_SCHED_MIX_DISTANCE);
9f3ec181 14659
c3a8613e 14660 int other_side = 1 - sched_state.side;
9f3ec181 14661
14662 /* Try to delay long-running insns when side is busy. */
c3a8613e 14663 if (s390_is_longrunning (insn))
9f3ec181 14664 {
c3a8613e 14665 if (s390_is_fxd (insn))
14666 {
14667 if (fxd_longrunning[sched_state.side]
14668 && fxd_longrunning[other_side]
14669 <= fxd_longrunning[sched_state.side])
14670 score = MAX (0, score - 10);
14671
14672 else if (fxd_longrunning[other_side]
14673 >= fxd_longrunning[sched_state.side])
14674 score += 10;
14675 }
9f3ec181 14676
c3a8613e 14677 if (s390_is_fpd (insn))
14678 {
14679 if (fpd_longrunning[sched_state.side]
14680 && fpd_longrunning[other_side]
14681 <= fpd_longrunning[sched_state.side])
14682 score = MAX (0, score - 10);
14683
14684 else if (fpd_longrunning[other_side]
14685 >= fpd_longrunning[sched_state.side])
14686 score += 10;
14687 }
9f3ec181 14688 }
0cb69051 14689 }
9f3ec181 14690
81769881 14691 return score;
14692}
14693
8a2a84e3 14694/* This function is called via hook TARGET_SCHED_REORDER before
4246a5c7 14695 issuing one insn from list READY which contains *NREADYP entries.
8a2a84e3 14696 For target z10 it reorders load instructions to avoid early load
14697 conflicts in the floating point pipeline */
14698static int
81769881 14699s390_sched_reorder (FILE *file, int verbose,
b24ef467 14700 rtx_insn **ready, int *nreadyp, int clock ATTRIBUTE_UNUSED)
8a2a84e3 14701{
117d67d0 14702 if (s390_tune == PROCESSOR_2097_Z10
14703 && reload_completed
14704 && *nreadyp > 1)
14705 s390_z10_prevent_earlyload_conflicts (ready, nreadyp);
8a2a84e3 14706
117d67d0 14707 if (s390_tune >= PROCESSOR_2827_ZEC12
81769881 14708 && reload_completed
14709 && *nreadyp > 1)
14710 {
14711 int i;
14712 int last_index = *nreadyp - 1;
14713 int max_index = -1;
14714 int max_score = -1;
b24ef467 14715 rtx_insn *tmp;
81769881 14716
14717 /* Just move the insn with the highest score to the top (the
14718 end) of the list. A full sort is not needed since a conflict
14719 in the hazard recognition cannot happen. So the top insn in
14720 the ready list will always be taken. */
14721 for (i = last_index; i >= 0; i--)
14722 {
14723 int score;
14724
14725 if (recog_memoized (ready[i]) < 0)
14726 continue;
14727
14728 score = s390_sched_score (ready[i]);
14729 if (score > max_score)
14730 {
14731 max_score = score;
14732 max_index = i;
14733 }
14734 }
14735
14736 if (max_index != -1)
14737 {
14738 if (max_index != last_index)
14739 {
14740 tmp = ready[max_index];
14741 ready[max_index] = ready[last_index];
14742 ready[last_index] = tmp;
14743
14744 if (verbose > 5)
14745 fprintf (file,
0cb69051 14746 ";;\t\tBACKEND: move insn %d to the top of list\n",
81769881 14747 INSN_UID (ready[last_index]));
14748 }
14749 else if (verbose > 5)
14750 fprintf (file,
0cb69051 14751 ";;\t\tBACKEND: best insn %d already on top\n",
81769881 14752 INSN_UID (ready[last_index]));
14753 }
14754
14755 if (verbose > 5)
14756 {
14757 fprintf (file, "ready list ooo attributes - sched state: %d\n",
c3a8613e 14758 sched_state.group_state);
81769881 14759
14760 for (i = last_index; i >= 0; i--)
14761 {
0cb69051 14762 unsigned int sched_mask;
14763 rtx_insn *insn = ready[i];
14764
14765 if (recog_memoized (insn) < 0)
81769881 14766 continue;
0cb69051 14767
14768 sched_mask = s390_get_sched_attrmask (insn);
14769 fprintf (file, ";;\t\tBACKEND: insn %d score: %d: ",
14770 INSN_UID (insn),
14771 s390_sched_score (insn));
14772#define PRINT_SCHED_ATTR(M, ATTR) fprintf (file, "%s ",\
14773 ((M) & sched_mask) ? #ATTR : "");
14774 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_CRACKED, cracked);
14775 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_EXPANDED, expanded);
14776 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_ENDGROUP, endgroup);
14777 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_GROUPALONE, groupalone);
14778#undef PRINT_SCHED_ATTR
c9213ca0 14779 if (s390_tune >= PROCESSOR_2964_Z13)
0cb69051 14780 {
14781 unsigned int unit_mask, m = 1;
14782 int units, j;
14783
14784 unit_mask = s390_get_unit_mask (insn, &units);
14785 fprintf (file, "(units:");
14786 for (j = 0; j < units; j++, m <<= 1)
14787 if (m & unit_mask)
14788 fprintf (file, " u%d", j);
14789 fprintf (file, ")");
14790 }
81769881 14791 fprintf (file, "\n");
14792 }
14793 }
14794 }
14795
8a2a84e3 14796 return s390_issue_rate ();
14797}
14798
81769881 14799
8a2a84e3 14800/* This function is called via hook TARGET_SCHED_VARIABLE_ISSUE after
14801 the scheduler has issued INSN. It stores the last issued insn into
14802 last_scheduled_insn in order to make it available for
14803 s390_sched_reorder. */
14804static int
18282db0 14805s390_sched_variable_issue (FILE *file, int verbose, rtx_insn *insn, int more)
8a2a84e3 14806{
14807 last_scheduled_insn = insn;
14808
c3a8613e 14809 bool ends_group = false;
9f3ec181 14810
117d67d0 14811 if (s390_tune >= PROCESSOR_2827_ZEC12
81769881 14812 && reload_completed
14813 && recog_memoized (insn) >= 0)
14814 {
14815 unsigned int mask = s390_get_sched_attrmask (insn);
14816
c3a8613e 14817 if ((mask & S390_SCHED_ATTR_MASK_GROUPOFTWO) != 0)
14818 sched_state.group_of_two = true;
9f3ec181 14819
c3a8613e 14820 /* If this is a group-of-two insn, we actually ended the last group
14821 and this insn is the first one of the new group. */
14822 if (sched_state.group_state == 2 && sched_state.group_of_two)
81769881 14823 {
c3a8613e 14824 sched_state.side = sched_state.side ? 0 : 1;
14825 sched_state.group_state = 0;
14826 }
14827
14828 /* Longrunning and side bookkeeping. */
14829 for (int i = 0; i < 2; i++)
14830 {
14831 fxd_longrunning[i] = MAX (0, fxd_longrunning[i] - 1);
14832 fpd_longrunning[i] = MAX (0, fpd_longrunning[i] - 1);
14833 }
14834
14835 unsigned latency = insn_default_latency (insn);
14836 if (s390_is_longrunning (insn))
14837 {
14838 if (s390_is_fxd (insn))
14839 fxd_longrunning[sched_state.side] = latency;
14840 else
14841 fpd_longrunning[sched_state.side] = latency;
81769881 14842 }
0cb69051 14843
c9213ca0 14844 if (s390_tune >= PROCESSOR_2964_Z13)
0cb69051 14845 {
14846 int units, i;
14847 unsigned unit_mask, m = 1;
14848
14849 unit_mask = s390_get_unit_mask (insn, &units);
14850 gcc_assert (units <= MAX_SCHED_UNITS);
14851
14852 for (i = 0; i < units; i++, m <<= 1)
14853 if (m & unit_mask)
c3a8613e 14854 last_scheduled_unit_distance[i][sched_state.side] = 0;
14855 else if (last_scheduled_unit_distance[i][sched_state.side]
14856 < MAX_SCHED_MIX_DISTANCE)
14857 last_scheduled_unit_distance[i][sched_state.side]++;
0cb69051 14858 }
14859
c3a8613e 14860 if ((mask & S390_SCHED_ATTR_MASK_CRACKED) != 0
14861 || (mask & S390_SCHED_ATTR_MASK_EXPANDED) != 0
14862 || (mask & S390_SCHED_ATTR_MASK_GROUPALONE) != 0
14863 || (mask & S390_SCHED_ATTR_MASK_ENDGROUP) != 0)
9f3ec181 14864 {
c3a8613e 14865 sched_state.group_state = 0;
14866 ends_group = true;
9f3ec181 14867 }
c3a8613e 14868 else
9f3ec181 14869 {
c3a8613e 14870 switch (sched_state.group_state)
14871 {
14872 case 0:
14873 sched_state.group_state++;
14874 break;
14875 case 1:
14876 sched_state.group_state++;
14877 if (sched_state.group_of_two)
14878 {
14879 sched_state.group_state = 0;
14880 ends_group = true;
14881 }
14882 break;
14883 case 2:
14884 sched_state.group_state++;
14885 ends_group = true;
14886 break;
14887 }
9f3ec181 14888 }
14889
81769881 14890 if (verbose > 5)
14891 {
0cb69051 14892 unsigned int sched_mask;
14893
14894 sched_mask = s390_get_sched_attrmask (insn);
14895
14896 fprintf (file, ";;\t\tBACKEND: insn %d: ", INSN_UID (insn));
14897#define PRINT_SCHED_ATTR(M, ATTR) fprintf (file, "%s ", ((M) & sched_mask) ? #ATTR : "");
14898 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_CRACKED, cracked);
14899 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_EXPANDED, expanded);
14900 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_ENDGROUP, endgroup);
14901 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_GROUPALONE, groupalone);
14902#undef PRINT_SCHED_ATTR
14903
c9213ca0 14904 if (s390_tune >= PROCESSOR_2964_Z13)
0cb69051 14905 {
14906 unsigned int unit_mask, m = 1;
14907 int units, j;
14908
14909 unit_mask = s390_get_unit_mask (insn, &units);
14910 fprintf (file, "(units:");
14911 for (j = 0; j < units; j++, m <<= 1)
14912 if (m & unit_mask)
14913 fprintf (file, " %d", j);
14914 fprintf (file, ")");
14915 }
c3a8613e 14916 fprintf (file, " sched state: %d\n", sched_state.group_state);
0cb69051 14917
c9213ca0 14918 if (s390_tune >= PROCESSOR_2964_Z13)
0cb69051 14919 {
14920 int units, j;
14921
14922 s390_get_unit_mask (insn, &units);
14923
c3a8613e 14924 fprintf (file, ";;\t\tBACKEND: units on this side unused for: ");
0cb69051 14925 for (j = 0; j < units; j++)
c3a8613e 14926 fprintf (file, "%d:%d ", j,
14927 last_scheduled_unit_distance[j][sched_state.side]);
0cb69051 14928 fprintf (file, "\n");
14929 }
81769881 14930 }
c3a8613e 14931
14932 /* If this insn ended a group, the next will be on the other side. */
14933 if (ends_group)
14934 {
14935 sched_state.group_state = 0;
14936 sched_state.side = sched_state.side ? 0 : 1;
14937 sched_state.group_of_two = false;
14938 }
81769881 14939 }
14940
8a2a84e3 14941 if (GET_CODE (PATTERN (insn)) != USE
14942 && GET_CODE (PATTERN (insn)) != CLOBBER)
14943 return more - 1;
14944 else
14945 return more;
14946}
7346ca58 14947
494d0169 14948static void
14949s390_sched_init (FILE *file ATTRIBUTE_UNUSED,
14950 int verbose ATTRIBUTE_UNUSED,
14951 int max_ready ATTRIBUTE_UNUSED)
14952{
b3041173 14953 /* If the next basic block is most likely entered via a fallthru edge
14954 we keep the last sched state. Otherwise we start a new group.
14955 The scheduler traverses basic blocks in "instruction stream" ordering
c3a8613e 14956 so if we see a fallthru edge here, sched_state will be of its
b3041173 14957 source block.
14958
14959 current_sched_info->prev_head is the insn before the first insn of the
14960 block of insns to be scheduled.
14961 */
14962 rtx_insn *insn = current_sched_info->prev_head
14963 ? NEXT_INSN (current_sched_info->prev_head) : NULL;
14964 basic_block bb = insn ? BLOCK_FOR_INSN (insn) : NULL;
14965 if (s390_tune < PROCESSOR_2964_Z13 || !s390_bb_fallthru_entry_likely (bb))
c3a8613e 14966 {
14967 last_scheduled_insn = NULL;
14968 memset (last_scheduled_unit_distance, 0,
14969 MAX_SCHED_UNITS * NUM_SIDES * sizeof (int));
14970 sched_state.group_state = 0;
14971 sched_state.group_of_two = false;
14972 }
494d0169 14973}
14974
9ccaa774 14975/* This target hook implementation for TARGET_LOOP_UNROLL_ADJUST calculates
33d033da 14976 a new number struct loop *loop should be unrolled if tuned for cpus with
14977 a built-in stride prefetcher.
14978 The loop is analyzed for memory accesses by calling check_dpu for
9ccaa774 14979 each rtx of the loop. Depending on the loop_depth and the amount of
14980 memory accesses a new number <=nunroll is returned to improve the
67cf9b55 14981 behavior of the hardware prefetch unit. */
9ccaa774 14982static unsigned
14983s390_loop_unroll_adjust (unsigned nunroll, struct loop *loop)
14984{
14985 basic_block *bbs;
93e0956b 14986 rtx_insn *insn;
9ccaa774 14987 unsigned i;
14988 unsigned mem_count = 0;
14989
117d67d0 14990 if (s390_tune < PROCESSOR_2097_Z10)
9ccaa774 14991 return nunroll;
14992
14993 /* Count the number of memory references within the loop body. */
14994 bbs = get_loop_body (loop);
15e472ec 14995 subrtx_iterator::array_type array;
9ccaa774 14996 for (i = 0; i < loop->num_nodes; i++)
15e472ec 14997 FOR_BB_INSNS (bbs[i], insn)
14998 if (INSN_P (insn) && INSN_CODE (insn) != -1)
ccaaf998 14999 {
15000 rtx set;
15001
15002 /* The runtime of small loops with memory block operations
15003 will be determined by the memory operation. Doing
15004 unrolling doesn't help here. Measurements to confirm
15005 this where only done on recent CPU levels. So better do
15006 not change anything for older CPUs. */
15007 if (s390_tune >= PROCESSOR_2964_Z13
15008 && loop->ninsns <= BLOCK_MEM_OPS_LOOP_INSNS
15009 && ((set = single_set (insn)) != NULL_RTX)
15010 && ((GET_MODE (SET_DEST (set)) == BLKmode
15011 && (GET_MODE (SET_SRC (set)) == BLKmode
15012 || SET_SRC (set) == const0_rtx))
15013 || (GET_CODE (SET_SRC (set)) == COMPARE
15014 && GET_MODE (XEXP (SET_SRC (set), 0)) == BLKmode
15015 && GET_MODE (XEXP (SET_SRC (set), 1)) == BLKmode)))
15016 return 1;
15017
15018 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
15019 if (MEM_P (*iter))
15020 mem_count += 1;
15021 }
9ccaa774 15022 free (bbs);
15023
15024 /* Prevent division by zero, and we do not need to adjust nunroll in this case. */
15025 if (mem_count == 0)
15026 return nunroll;
15027
15028 switch (loop_depth(loop))
15029 {
15030 case 1:
15031 return MIN (nunroll, 28 / mem_count);
15032 case 2:
15033 return MIN (nunroll, 22 / mem_count);
15034 default:
15035 return MIN (nunroll, 16 / mem_count);
15036 }
15037}
15038
7a0cee35 15039/* Restore the current options. This is a hook function and also called
15040 internally. */
15041
0b8be04c 15042static void
7a0cee35 15043s390_function_specific_restore (struct gcc_options *opts,
15044 struct cl_target_option *ptr ATTRIBUTE_UNUSED)
0b8be04c 15045{
7a0cee35 15046 opts->x_s390_cost_pointer = (long)processor_table[opts->x_s390_tune].cost;
15047}
0b8be04c 15048
908d23b5 15049static void
15050s390_default_align (struct gcc_options *opts)
15051{
15052 /* Set the default function alignment to 16 in order to get rid of
15053 some unwanted performance effects. */
15054 if (opts->x_flag_align_functions && !opts->x_str_align_functions
15055 && opts->x_s390_tune >= PROCESSOR_2964_Z13)
15056 opts->x_str_align_functions = "16";
15057}
15058
15059static void
15060s390_override_options_after_change (void)
15061{
15062 s390_default_align (&global_options);
15063}
15064
7a0cee35 15065static void
6ef12d3a 15066s390_option_override_internal (struct gcc_options *opts,
7a0cee35 15067 const struct gcc_options *opts_set)
15068{
0b8be04c 15069 /* Architecture mode defaults according to ABI. */
7a0cee35 15070 if (!(opts_set->x_target_flags & MASK_ZARCH))
0b8be04c 15071 {
15072 if (TARGET_64BIT)
7a0cee35 15073 opts->x_target_flags |= MASK_ZARCH;
0b8be04c 15074 else
7a0cee35 15075 opts->x_target_flags &= ~MASK_ZARCH;
0b8be04c 15076 }
15077
7a0cee35 15078 /* Set the march default in case it hasn't been specified on cmdline. */
15079 if (!opts_set->x_s390_arch)
3bd8520f 15080 opts->x_s390_arch = PROCESSOR_2064_Z900;
3bd8520f 15081
7a0cee35 15082 opts->x_s390_arch_flags = processor_flags_table[(int) opts->x_s390_arch];
0b8be04c 15083
15084 /* Determine processor to tune for. */
7a0cee35 15085 if (!opts_set->x_s390_tune)
15086 opts->x_s390_tune = opts->x_s390_arch;
3bd8520f 15087
7a0cee35 15088 opts->x_s390_tune_flags = processor_flags_table[opts->x_s390_tune];
0b8be04c 15089
15090 /* Sanity checks. */
7a0cee35 15091 if (opts->x_s390_arch == PROCESSOR_NATIVE
15092 || opts->x_s390_tune == PROCESSOR_NATIVE)
db249f37 15093 gcc_unreachable ();
7a0cee35 15094 if (TARGET_64BIT && !TARGET_ZARCH_P (opts->x_target_flags))
0b8be04c 15095 error ("64-bit ABI not supported in ESA/390 mode");
15096
db7a90aa 15097 if (opts->x_s390_indirect_branch == indirect_branch_thunk_inline
15098 || opts->x_s390_indirect_branch_call == indirect_branch_thunk_inline
15099 || opts->x_s390_function_return == indirect_branch_thunk_inline
15100 || opts->x_s390_function_return_reg == indirect_branch_thunk_inline
15101 || opts->x_s390_function_return_mem == indirect_branch_thunk_inline)
2f6d557f 15102 error ("thunk-inline is only supported with %<-mindirect-branch-jump%>");
db7a90aa 15103
15104 if (opts->x_s390_indirect_branch != indirect_branch_keep)
15105 {
15106 if (!opts_set->x_s390_indirect_branch_call)
15107 opts->x_s390_indirect_branch_call = opts->x_s390_indirect_branch;
15108
15109 if (!opts_set->x_s390_indirect_branch_jump)
15110 opts->x_s390_indirect_branch_jump = opts->x_s390_indirect_branch;
15111 }
15112
15113 if (opts->x_s390_function_return != indirect_branch_keep)
15114 {
15115 if (!opts_set->x_s390_function_return_reg)
15116 opts->x_s390_function_return_reg = opts->x_s390_function_return;
15117
15118 if (!opts_set->x_s390_function_return_mem)
15119 opts->x_s390_function_return_mem = opts->x_s390_function_return;
15120 }
15121
0b8be04c 15122 /* Enable hardware transactions if available and not explicitly
15123 disabled by user. E.g. with -m31 -march=zEC12 -mzarch */
7a0cee35 15124 if (!TARGET_OPT_HTM_P (opts_set->x_target_flags))
15125 {
15126 if (TARGET_CPU_HTM_P (opts) && TARGET_ZARCH_P (opts->x_target_flags))
15127 opts->x_target_flags |= MASK_OPT_HTM;
15128 else
15129 opts->x_target_flags &= ~MASK_OPT_HTM;
15130 }
0b8be04c 15131
7a0cee35 15132 if (TARGET_OPT_VX_P (opts_set->x_target_flags))
cc79fcc9 15133 {
7a0cee35 15134 if (TARGET_OPT_VX_P (opts->x_target_flags))
cc79fcc9 15135 {
7a0cee35 15136 if (!TARGET_CPU_VX_P (opts))
cc79fcc9 15137 error ("hardware vector support not available on %s",
7a0cee35 15138 processor_table[(int)opts->x_s390_arch].name);
15139 if (TARGET_SOFT_FLOAT_P (opts->x_target_flags))
2f6d557f 15140 error ("hardware vector support not available with "
15141 "%<-msoft-float%>");
cc79fcc9 15142 }
15143 }
7a0cee35 15144 else
15145 {
15146 if (TARGET_CPU_VX_P (opts))
15147 /* Enable vector support if available and not explicitly disabled
15148 by user. E.g. with -m31 -march=z13 -mzarch */
15149 opts->x_target_flags |= MASK_OPT_VX;
15150 else
15151 opts->x_target_flags &= ~MASK_OPT_VX;
15152 }
cc79fcc9 15153
7a0cee35 15154 /* Use hardware DFP if available and not explicitly disabled by
15155 user. E.g. with -m31 -march=z10 -mzarch */
15156 if (!TARGET_HARD_DFP_P (opts_set->x_target_flags))
15157 {
15158 if (TARGET_DFP_P (opts))
15159 opts->x_target_flags |= MASK_HARD_DFP;
15160 else
15161 opts->x_target_flags &= ~MASK_HARD_DFP;
15162 }
15163
15164 if (TARGET_HARD_DFP_P (opts->x_target_flags) && !TARGET_DFP_P (opts))
0b8be04c 15165 {
7a0cee35 15166 if (TARGET_HARD_DFP_P (opts_set->x_target_flags))
0b8be04c 15167 {
7a0cee35 15168 if (!TARGET_CPU_DFP_P (opts))
0b8be04c 15169 error ("hardware decimal floating point instructions"
7a0cee35 15170 " not available on %s",
15171 processor_table[(int)opts->x_s390_arch].name);
15172 if (!TARGET_ZARCH_P (opts->x_target_flags))
0b8be04c 15173 error ("hardware decimal floating point instructions"
15174 " not available in ESA/390 mode");
15175 }
15176 else
7a0cee35 15177 opts->x_target_flags &= ~MASK_HARD_DFP;
0b8be04c 15178 }
15179
7a0cee35 15180 if (TARGET_SOFT_FLOAT_P (opts_set->x_target_flags)
15181 && TARGET_SOFT_FLOAT_P (opts->x_target_flags))
0b8be04c 15182 {
7a0cee35 15183 if (TARGET_HARD_DFP_P (opts_set->x_target_flags)
15184 && TARGET_HARD_DFP_P (opts->x_target_flags))
2f6d557f 15185 error ("%<-mhard-dfp%> can%'t be used in conjunction with "
15186 "%<-msoft-float%>");
0b8be04c 15187
7a0cee35 15188 opts->x_target_flags &= ~MASK_HARD_DFP;
0b8be04c 15189 }
15190
7a0cee35 15191 if (TARGET_BACKCHAIN_P (opts->x_target_flags)
15192 && TARGET_PACKED_STACK_P (opts->x_target_flags)
15193 && TARGET_HARD_FLOAT_P (opts->x_target_flags))
2f6d557f 15194 error ("%<-mbackchain%> %<-mpacked-stack%> %<-mhard-float%> are not "
15195 "supported in combination");
0b8be04c 15196
7a0cee35 15197 if (opts->x_s390_stack_size)
0b8be04c 15198 {
7a0cee35 15199 if (opts->x_s390_stack_guard >= opts->x_s390_stack_size)
0b8be04c 15200 error ("stack size must be greater than the stack guard value");
7a0cee35 15201 else if (opts->x_s390_stack_size > 1 << 16)
0b8be04c 15202 error ("stack size must not be greater than 64k");
15203 }
7a0cee35 15204 else if (opts->x_s390_stack_guard)
2f6d557f 15205 error ("%<-mstack-guard%> implies use of %<-mstack-size%>");
0b8be04c 15206
e7ac5daa 15207 /* Our implementation of the stack probe requires the probe interval
15208 to be used as displacement in an address operand. The maximum
15209 probe interval currently is 64k. This would exceed short
15210 displacements. Trim that value down to 4k if that happens. This
15211 might result in too many probes being generated only on the
15212 oldest supported machine level z900. */
15213 if (!DISP_IN_RANGE ((1 << PARAM_VALUE (PARAM_STACK_CLASH_PROTECTION_PROBE_INTERVAL))))
15214 set_param_value ("stack-clash-protection-probe-interval", 12,
15215 opts->x_param_values,
15216 opts_set->x_param_values);
15217
0b8be04c 15218#ifdef TARGET_DEFAULT_LONG_DOUBLE_128
7a0cee35 15219 if (!TARGET_LONG_DOUBLE_128_P (opts_set->x_target_flags))
15220 opts->x_target_flags |= MASK_LONG_DOUBLE_128;
0b8be04c 15221#endif
15222
7a0cee35 15223 if (opts->x_s390_tune >= PROCESSOR_2097_Z10)
0b8be04c 15224 {
15225 maybe_set_param_value (PARAM_MAX_UNROLLED_INSNS, 100,
7a0cee35 15226 opts->x_param_values,
15227 opts_set->x_param_values);
0b8be04c 15228 maybe_set_param_value (PARAM_MAX_UNROLL_TIMES, 32,
7a0cee35 15229 opts->x_param_values,
15230 opts_set->x_param_values);
0b8be04c 15231 maybe_set_param_value (PARAM_MAX_COMPLETELY_PEELED_INSNS, 2000,
7a0cee35 15232 opts->x_param_values,
15233 opts_set->x_param_values);
0b8be04c 15234 maybe_set_param_value (PARAM_MAX_COMPLETELY_PEEL_TIMES, 64,
7a0cee35 15235 opts->x_param_values,
15236 opts_set->x_param_values);
0b8be04c 15237 }
15238
15239 maybe_set_param_value (PARAM_MAX_PENDING_LIST_LENGTH, 256,
7a0cee35 15240 opts->x_param_values,
15241 opts_set->x_param_values);
0b8be04c 15242 /* values for loop prefetching */
15243 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE, 256,
7a0cee35 15244 opts->x_param_values,
15245 opts_set->x_param_values);
0b8be04c 15246 maybe_set_param_value (PARAM_L1_CACHE_SIZE, 128,
7a0cee35 15247 opts->x_param_values,
15248 opts_set->x_param_values);
0b8be04c 15249 /* s390 has more than 2 levels and the size is much larger. Since
15250 we are always running virtualized assume that we only get a small
15251 part of the caches above l1. */
15252 maybe_set_param_value (PARAM_L2_CACHE_SIZE, 1500,
7a0cee35 15253 opts->x_param_values,
15254 opts_set->x_param_values);
0b8be04c 15255 maybe_set_param_value (PARAM_PREFETCH_MIN_INSN_TO_MEM_RATIO, 2,
7a0cee35 15256 opts->x_param_values,
15257 opts_set->x_param_values);
0b8be04c 15258 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES, 6,
7a0cee35 15259 opts->x_param_values,
15260 opts_set->x_param_values);
15261
15262 /* Use the alternative scheduling-pressure algorithm by default. */
15263 maybe_set_param_value (PARAM_SCHED_PRESSURE_ALGORITHM, 2,
9f522e0c 15264 opts->x_param_values,
15265 opts_set->x_param_values);
7a0cee35 15266
e328d74f 15267 maybe_set_param_value (PARAM_MIN_VECT_LOOP_BOUND, 2,
15268 opts->x_param_values,
15269 opts_set->x_param_values);
15270
b85751a7 15271 /* Use aggressive inlining parameters. */
15272 if (opts->x_s390_tune >= PROCESSOR_2964_Z13)
15273 {
15274 maybe_set_param_value (PARAM_INLINE_MIN_SPEEDUP, 2,
15275 opts->x_param_values,
15276 opts_set->x_param_values);
15277
15278 maybe_set_param_value (PARAM_MAX_INLINE_INSNS_AUTO, 80,
15279 opts->x_param_values,
15280 opts_set->x_param_values);
15281 }
15282
908d23b5 15283 /* Set the default alignment. */
15284 s390_default_align (opts);
15285
7a0cee35 15286 /* Call target specific restore function to do post-init work. At the moment,
15287 this just sets opts->x_s390_cost_pointer. */
15288 s390_function_specific_restore (opts, NULL);
2832ed10 15289
15290 /* Check whether -mfentry is supported. It cannot be used in 31-bit mode,
15291 because 31-bit PLT stubs assume that %r12 contains GOT address, which is
15292 not the case when the code runs before the prolog. */
15293 if (opts->x_flag_fentry && !TARGET_64BIT)
2f6d557f 15294 error ("%<-mfentry%> is supported only for 64-bit CPUs");
7a0cee35 15295}
15296
15297static void
15298s390_option_override (void)
15299{
15300 unsigned int i;
15301 cl_deferred_option *opt;
15302 vec<cl_deferred_option> *v =
15303 (vec<cl_deferred_option> *) s390_deferred_options;
15304
15305 if (v)
15306 FOR_EACH_VEC_ELT (*v, i, opt)
15307 {
15308 switch (opt->opt_index)
15309 {
15310 case OPT_mhotpatch_:
15311 {
15312 int val1;
15313 int val2;
32f065b3 15314 char *s = strtok (ASTRDUP (opt->arg), ",");
15315 char *t = strtok (NULL, "\0");
7a0cee35 15316
7a0cee35 15317 if (t != NULL)
15318 {
7a0cee35 15319 val1 = integral_argument (s);
15320 val2 = integral_argument (t);
15321 }
15322 else
15323 {
15324 val1 = -1;
15325 val2 = -1;
15326 }
15327 if (val1 == -1 || val2 == -1)
15328 {
15329 /* argument is not a plain number */
15330 error ("arguments to %qs should be non-negative integers",
15331 "-mhotpatch=n,m");
15332 break;
15333 }
15334 else if (val1 > s390_hotpatch_hw_max
15335 || val2 > s390_hotpatch_hw_max)
15336 {
15337 error ("argument to %qs is too large (max. %d)",
15338 "-mhotpatch=n,m", s390_hotpatch_hw_max);
15339 break;
15340 }
15341 s390_hotpatch_hw_before_label = val1;
15342 s390_hotpatch_hw_after_label = val2;
15343 break;
15344 }
15345 default:
15346 gcc_unreachable ();
15347 }
15348 }
15349
15350 /* Set up function hooks. */
15351 init_machine_status = s390_init_machine_status;
15352
6ef12d3a 15353 s390_option_override_internal (&global_options, &global_options_set);
7a0cee35 15354
15355 /* Save the initial options in case the user does function specific
15356 options. */
15357 target_option_default_node = build_target_option_node (&global_options);
15358 target_option_current_node = target_option_default_node;
0b8be04c 15359
15360 /* This cannot reside in s390_option_optimization_table since HAVE_prefetch
15361 requires the arch flags to be evaluated already. Since prefetching
15362 is beneficial on s390, we enable it if available. */
15363 if (flag_prefetch_loop_arrays < 0 && HAVE_prefetch && optimize >= 3)
15364 flag_prefetch_loop_arrays = 1;
15365
9852c8ae 15366 if (!s390_pic_data_is_text_relative && !flag_pic)
2f6d557f 15367 error ("%<-mno-pic-data-is-text-relative%> cannot be used without "
15368 "%<-fpic%>/%<-fPIC%>");
9852c8ae 15369
0b8be04c 15370 if (TARGET_TPF)
15371 {
15372 /* Don't emit DWARF3/4 unless specifically selected. The TPF
15373 debuggers do not yet support DWARF 3/4. */
9f522e0c 15374 if (!global_options_set.x_dwarf_strict)
0b8be04c 15375 dwarf_strict = 1;
15376 if (!global_options_set.x_dwarf_version)
15377 dwarf_version = 2;
15378 }
0b8be04c 15379}
15380
7a0cee35 15381#if S390_USE_TARGET_ATTRIBUTE
15382/* Inner function to process the attribute((target(...))), take an argument and
15383 set the current options from the argument. If we have a list, recursively go
15384 over the list. */
15385
15386static bool
15387s390_valid_target_attribute_inner_p (tree args,
15388 struct gcc_options *opts,
15389 struct gcc_options *new_opts_set,
15390 bool force_pragma)
15391{
15392 char *next_optstr;
15393 bool ret = true;
15394
15395#define S390_ATTRIB(S,O,A) { S, sizeof (S)-1, O, A, 0 }
15396#define S390_PRAGMA(S,O,A) { S, sizeof (S)-1, O, A, 1 }
15397 static const struct
15398 {
15399 const char *string;
15400 size_t len;
15401 int opt;
15402 int has_arg;
15403 int only_as_pragma;
15404 } attrs[] = {
15405 /* enum options */
15406 S390_ATTRIB ("arch=", OPT_march_, 1),
15407 S390_ATTRIB ("tune=", OPT_mtune_, 1),
15408 /* uinteger options */
15409 S390_ATTRIB ("stack-guard=", OPT_mstack_guard_, 1),
15410 S390_ATTRIB ("stack-size=", OPT_mstack_size_, 1),
15411 S390_ATTRIB ("branch-cost=", OPT_mbranch_cost_, 1),
15412 S390_ATTRIB ("warn-framesize=", OPT_mwarn_framesize_, 1),
15413 /* flag options */
15414 S390_ATTRIB ("backchain", OPT_mbackchain, 0),
15415 S390_ATTRIB ("hard-dfp", OPT_mhard_dfp, 0),
15416 S390_ATTRIB ("hard-float", OPT_mhard_float, 0),
15417 S390_ATTRIB ("htm", OPT_mhtm, 0),
15418 S390_ATTRIB ("vx", OPT_mvx, 0),
15419 S390_ATTRIB ("packed-stack", OPT_mpacked_stack, 0),
15420 S390_ATTRIB ("small-exec", OPT_msmall_exec, 0),
15421 S390_ATTRIB ("soft-float", OPT_msoft_float, 0),
15422 S390_ATTRIB ("mvcle", OPT_mmvcle, 0),
15423 S390_PRAGMA ("zvector", OPT_mzvector, 0),
15424 /* boolean options */
15425 S390_ATTRIB ("warn-dynamicstack", OPT_mwarn_dynamicstack, 0),
15426 };
15427#undef S390_ATTRIB
15428#undef S390_PRAGMA
15429
15430 /* If this is a list, recurse to get the options. */
15431 if (TREE_CODE (args) == TREE_LIST)
15432 {
15433 bool ret = true;
15434 int num_pragma_values;
15435 int i;
15436
15437 /* Note: attribs.c:decl_attributes prepends the values from
15438 current_target_pragma to the list of target attributes. To determine
15439 whether we're looking at a value of the attribute or the pragma we
15440 assume that the first [list_length (current_target_pragma)] values in
15441 the list are the values from the pragma. */
15442 num_pragma_values = (!force_pragma && current_target_pragma != NULL)
15443 ? list_length (current_target_pragma) : 0;
15444 for (i = 0; args; args = TREE_CHAIN (args), i++)
15445 {
15446 bool is_pragma;
15447
15448 is_pragma = (force_pragma || i < num_pragma_values);
15449 if (TREE_VALUE (args)
15450 && !s390_valid_target_attribute_inner_p (TREE_VALUE (args),
15451 opts, new_opts_set,
15452 is_pragma))
15453 {
15454 ret = false;
15455 }
15456 }
15457 return ret;
15458 }
15459
15460 else if (TREE_CODE (args) != STRING_CST)
15461 {
15462 error ("attribute %<target%> argument not a string");
15463 return false;
15464 }
15465
15466 /* Handle multiple arguments separated by commas. */
15467 next_optstr = ASTRDUP (TREE_STRING_POINTER (args));
15468
15469 while (next_optstr && *next_optstr != '\0')
15470 {
15471 char *p = next_optstr;
15472 char *orig_p = p;
15473 char *comma = strchr (next_optstr, ',');
15474 size_t len, opt_len;
15475 int opt;
15476 bool opt_set_p;
15477 char ch;
15478 unsigned i;
15479 int mask = 0;
15480 enum cl_var_type var_type;
15481 bool found;
15482
15483 if (comma)
15484 {
15485 *comma = '\0';
15486 len = comma - next_optstr;
15487 next_optstr = comma + 1;
15488 }
15489 else
15490 {
15491 len = strlen (p);
15492 next_optstr = NULL;
15493 }
15494
15495 /* Recognize no-xxx. */
15496 if (len > 3 && p[0] == 'n' && p[1] == 'o' && p[2] == '-')
15497 {
15498 opt_set_p = false;
15499 p += 3;
15500 len -= 3;
15501 }
15502 else
15503 opt_set_p = true;
15504
15505 /* Find the option. */
15506 ch = *p;
15507 found = false;
15508 for (i = 0; i < ARRAY_SIZE (attrs); i++)
15509 {
15510 opt_len = attrs[i].len;
15511 if (ch == attrs[i].string[0]
15512 && ((attrs[i].has_arg) ? len > opt_len : len == opt_len)
15513 && memcmp (p, attrs[i].string, opt_len) == 0)
15514 {
15515 opt = attrs[i].opt;
15516 if (!opt_set_p && cl_options[opt].cl_reject_negative)
15517 continue;
15518 mask = cl_options[opt].var_value;
15519 var_type = cl_options[opt].var_type;
15520 found = true;
15521 break;
15522 }
15523 }
15524
15525 /* Process the option. */
15526 if (!found)
15527 {
15528 error ("attribute(target(\"%s\")) is unknown", orig_p);
15529 return false;
15530 }
15531 else if (attrs[i].only_as_pragma && !force_pragma)
15532 {
15533 /* Value is not allowed for the target attribute. */
19abb0ad 15534 error ("value %qs is not supported by attribute %<target%>",
7a0cee35 15535 attrs[i].string);
15536 return false;
15537 }
15538
15539 else if (var_type == CLVC_BIT_SET || var_type == CLVC_BIT_CLEAR)
15540 {
15541 if (var_type == CLVC_BIT_CLEAR)
15542 opt_set_p = !opt_set_p;
15543
15544 if (opt_set_p)
15545 opts->x_target_flags |= mask;
15546 else
15547 opts->x_target_flags &= ~mask;
15548 new_opts_set->x_target_flags |= mask;
15549 }
15550
15551 else if (cl_options[opt].var_type == CLVC_BOOLEAN)
15552 {
15553 int value;
15554
15555 if (cl_options[opt].cl_uinteger)
15556 {
15557 /* Unsigned integer argument. Code based on the function
15558 decode_cmdline_option () in opts-common.c. */
15559 value = integral_argument (p + opt_len);
15560 }
15561 else
15562 value = (opt_set_p) ? 1 : 0;
15563
15564 if (value != -1)
15565 {
15566 struct cl_decoded_option decoded;
15567
15568 /* Value range check; only implemented for numeric and boolean
15569 options at the moment. */
15570 generate_option (opt, NULL, value, CL_TARGET, &decoded);
15571 s390_handle_option (opts, new_opts_set, &decoded, input_location);
15572 set_option (opts, new_opts_set, opt, value,
15573 p + opt_len, DK_UNSPECIFIED, input_location,
15574 global_dc);
15575 }
15576 else
15577 {
15578 error ("attribute(target(\"%s\")) is unknown", orig_p);
15579 ret = false;
15580 }
15581 }
15582
15583 else if (cl_options[opt].var_type == CLVC_ENUM)
15584 {
15585 bool arg_ok;
15586 int value;
15587
15588 arg_ok = opt_enum_arg_to_value (opt, p + opt_len, &value, CL_TARGET);
15589 if (arg_ok)
15590 set_option (opts, new_opts_set, opt, value,
15591 p + opt_len, DK_UNSPECIFIED, input_location,
15592 global_dc);
15593 else
15594 {
15595 error ("attribute(target(\"%s\")) is unknown", orig_p);
15596 ret = false;
15597 }
15598 }
15599
15600 else
15601 gcc_unreachable ();
15602 }
15603 return ret;
15604}
15605
15606/* Return a TARGET_OPTION_NODE tree of the target options listed or NULL. */
15607
15608tree
15609s390_valid_target_attribute_tree (tree args,
15610 struct gcc_options *opts,
15611 const struct gcc_options *opts_set,
15612 bool force_pragma)
15613{
15614 tree t = NULL_TREE;
15615 struct gcc_options new_opts_set;
15616
15617 memset (&new_opts_set, 0, sizeof (new_opts_set));
15618
15619 /* Process each of the options on the chain. */
15620 if (! s390_valid_target_attribute_inner_p (args, opts, &new_opts_set,
15621 force_pragma))
15622 return error_mark_node;
15623
15624 /* If some option was set (even if it has not changed), rerun
15625 s390_option_override_internal, and then save the options away. */
15626 if (new_opts_set.x_target_flags
15627 || new_opts_set.x_s390_arch
15628 || new_opts_set.x_s390_tune
15629 || new_opts_set.x_s390_stack_guard
15630 || new_opts_set.x_s390_stack_size
15631 || new_opts_set.x_s390_branch_cost
15632 || new_opts_set.x_s390_warn_framesize
15633 || new_opts_set.x_s390_warn_dynamicstack_p)
15634 {
15635 const unsigned char *src = (const unsigned char *)opts_set;
15636 unsigned char *dest = (unsigned char *)&new_opts_set;
15637 unsigned int i;
15638
15639 /* Merge the original option flags into the new ones. */
15640 for (i = 0; i < sizeof(*opts_set); i++)
15641 dest[i] |= src[i];
15642
15643 /* Do any overrides, such as arch=xxx, or tune=xxx support. */
6ef12d3a 15644 s390_option_override_internal (opts, &new_opts_set);
7a0cee35 15645 /* Save the current options unless we are validating options for
15646 #pragma. */
15647 t = build_target_option_node (opts);
15648 }
15649 return t;
15650}
15651
15652/* Hook to validate attribute((target("string"))). */
15653
15654static bool
15655s390_valid_target_attribute_p (tree fndecl,
15656 tree ARG_UNUSED (name),
15657 tree args,
15658 int ARG_UNUSED (flags))
15659{
15660 struct gcc_options func_options;
15661 tree new_target, new_optimize;
15662 bool ret = true;
15663
15664 /* attribute((target("default"))) does nothing, beyond
15665 affecting multi-versioning. */
15666 if (TREE_VALUE (args)
15667 && TREE_CODE (TREE_VALUE (args)) == STRING_CST
15668 && TREE_CHAIN (args) == NULL_TREE
15669 && strcmp (TREE_STRING_POINTER (TREE_VALUE (args)), "default") == 0)
15670 return true;
15671
15672 tree old_optimize = build_optimization_node (&global_options);
15673
15674 /* Get the optimization options of the current function. */
15675 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
15676
15677 if (!func_optimize)
15678 func_optimize = old_optimize;
15679
15680 /* Init func_options. */
15681 memset (&func_options, 0, sizeof (func_options));
15682 init_options_struct (&func_options, NULL);
15683 lang_hooks.init_options_struct (&func_options);
15684
15685 cl_optimization_restore (&func_options, TREE_OPTIMIZATION (func_optimize));
15686
15687 /* Initialize func_options to the default before its target options can
15688 be set. */
15689 cl_target_option_restore (&func_options,
15690 TREE_TARGET_OPTION (target_option_default_node));
15691
15692 new_target = s390_valid_target_attribute_tree (args, &func_options,
15693 &global_options_set,
15694 (args ==
15695 current_target_pragma));
15696 new_optimize = build_optimization_node (&func_options);
15697 if (new_target == error_mark_node)
15698 ret = false;
15699 else if (fndecl && new_target)
15700 {
15701 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
15702 if (old_optimize != new_optimize)
15703 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
15704 }
15705 return ret;
15706}
15707
d5a90e99 15708/* Hook to determine if one function can safely inline another. */
15709
15710static bool
15711s390_can_inline_p (tree caller, tree callee)
15712{
15713 tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
15714 tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
15715
15716 if (!callee_tree)
15717 callee_tree = target_option_default_node;
15718 if (!caller_tree)
15719 caller_tree = target_option_default_node;
15720 if (callee_tree == caller_tree)
15721 return true;
15722
15723 struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
15724 struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
15725 bool ret = true;
15726
15727 if ((caller_opts->x_target_flags & ~(MASK_SOFT_FLOAT | MASK_HARD_DFP))
15728 != (callee_opts->x_target_flags & ~(MASK_SOFT_FLOAT | MASK_HARD_DFP)))
15729 ret = false;
15730
15731 /* Don't inline functions to be compiled for a more recent arch into a
15732 function for an older arch. */
15733 else if (caller_opts->x_s390_arch < callee_opts->x_s390_arch)
15734 ret = false;
15735
15736 /* Inlining a hard float function into a soft float function is only
15737 allowed if the hard float function doesn't actually make use of
15738 floating point.
15739
15740 We are called from FEs for multi-versioning call optimization, so
15741 beware of ipa_fn_summaries not available. */
15742 else if (((TARGET_SOFT_FLOAT_P (caller_opts->x_target_flags)
15743 && !TARGET_SOFT_FLOAT_P (callee_opts->x_target_flags))
15744 || (!TARGET_HARD_DFP_P (caller_opts->x_target_flags)
15745 && TARGET_HARD_DFP_P (callee_opts->x_target_flags)))
15746 && (! ipa_fn_summaries
15747 || ipa_fn_summaries->get
15748 (cgraph_node::get (callee))->fp_expressions))
15749 ret = false;
15750
15751 return ret;
15752}
a818fd0b 15753#endif
d5a90e99 15754
db7a90aa 15755/* Set VAL to correct enum value according to the indirect-branch or
15756 function-return attribute in ATTR. */
15757
15758static inline void
15759s390_indirect_branch_attrvalue (tree attr, enum indirect_branch *val)
15760{
15761 const char *str = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)));
15762 if (strcmp (str, "keep") == 0)
15763 *val = indirect_branch_keep;
15764 else if (strcmp (str, "thunk") == 0)
15765 *val = indirect_branch_thunk;
15766 else if (strcmp (str, "thunk-inline") == 0)
15767 *val = indirect_branch_thunk_inline;
15768 else if (strcmp (str, "thunk-extern") == 0)
15769 *val = indirect_branch_thunk_extern;
15770}
15771
15772/* Memorize the setting for -mindirect-branch* and -mfunction-return*
15773 from either the cmdline or the function attributes in
15774 cfun->machine. */
15775
15776static void
15777s390_indirect_branch_settings (tree fndecl)
15778{
15779 tree attr;
15780
15781 if (!fndecl)
15782 return;
15783
15784 /* Initialize with the cmdline options and let the attributes
15785 override it. */
15786 cfun->machine->indirect_branch_jump = s390_indirect_branch_jump;
15787 cfun->machine->indirect_branch_call = s390_indirect_branch_call;
15788
15789 cfun->machine->function_return_reg = s390_function_return_reg;
15790 cfun->machine->function_return_mem = s390_function_return_mem;
15791
15792 if ((attr = lookup_attribute ("indirect_branch",
15793 DECL_ATTRIBUTES (fndecl))))
15794 {
15795 s390_indirect_branch_attrvalue (attr,
15796 &cfun->machine->indirect_branch_jump);
15797 s390_indirect_branch_attrvalue (attr,
15798 &cfun->machine->indirect_branch_call);
15799 }
15800
15801 if ((attr = lookup_attribute ("indirect_branch_jump",
15802 DECL_ATTRIBUTES (fndecl))))
15803 s390_indirect_branch_attrvalue (attr, &cfun->machine->indirect_branch_jump);
15804
15805 if ((attr = lookup_attribute ("indirect_branch_call",
15806 DECL_ATTRIBUTES (fndecl))))
15807 s390_indirect_branch_attrvalue (attr, &cfun->machine->indirect_branch_call);
15808
15809 if ((attr = lookup_attribute ("function_return",
15810 DECL_ATTRIBUTES (fndecl))))
15811 {
15812 s390_indirect_branch_attrvalue (attr,
15813 &cfun->machine->function_return_reg);
15814 s390_indirect_branch_attrvalue (attr,
15815 &cfun->machine->function_return_mem);
15816 }
15817
15818 if ((attr = lookup_attribute ("function_return_reg",
15819 DECL_ATTRIBUTES (fndecl))))
15820 s390_indirect_branch_attrvalue (attr, &cfun->machine->function_return_reg);
15821
15822 if ((attr = lookup_attribute ("function_return_mem",
15823 DECL_ATTRIBUTES (fndecl))))
15824 s390_indirect_branch_attrvalue (attr, &cfun->machine->function_return_mem);
15825}
15826
a818fd0b 15827#if S390_USE_TARGET_ATTRIBUTE
7a0cee35 15828/* Restore targets globals from NEW_TREE and invalidate s390_previous_fndecl
15829 cache. */
15830
15831void
15832s390_activate_target_options (tree new_tree)
15833{
15834 cl_target_option_restore (&global_options, TREE_TARGET_OPTION (new_tree));
15835 if (TREE_TARGET_GLOBALS (new_tree))
15836 restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
15837 else if (new_tree == target_option_default_node)
15838 restore_target_globals (&default_target_globals);
15839 else
15840 TREE_TARGET_GLOBALS (new_tree) = save_target_globals_default_opts ();
15841 s390_previous_fndecl = NULL_TREE;
15842}
a818fd0b 15843#endif
7a0cee35 15844
15845/* Establish appropriate back-end context for processing the function
15846 FNDECL. The argument might be NULL to indicate processing at top
15847 level, outside of any function scope. */
15848static void
15849s390_set_current_function (tree fndecl)
15850{
a818fd0b 15851#if S390_USE_TARGET_ATTRIBUTE
7a0cee35 15852 /* Only change the context if the function changes. This hook is called
15853 several times in the course of compiling a function, and we don't want to
15854 slow things down too much or call target_reinit when it isn't safe. */
15855 if (fndecl == s390_previous_fndecl)
d126e623 15856 {
15857 s390_indirect_branch_settings (fndecl);
15858 return;
15859 }
7a0cee35 15860
15861 tree old_tree;
15862 if (s390_previous_fndecl == NULL_TREE)
15863 old_tree = target_option_current_node;
15864 else if (DECL_FUNCTION_SPECIFIC_TARGET (s390_previous_fndecl))
15865 old_tree = DECL_FUNCTION_SPECIFIC_TARGET (s390_previous_fndecl);
15866 else
15867 old_tree = target_option_default_node;
15868
15869 if (fndecl == NULL_TREE)
15870 {
15871 if (old_tree != target_option_current_node)
15872 s390_activate_target_options (target_option_current_node);
15873 return;
15874 }
15875
15876 tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
15877 if (new_tree == NULL_TREE)
15878 new_tree = target_option_default_node;
15879
15880 if (old_tree != new_tree)
15881 s390_activate_target_options (new_tree);
15882 s390_previous_fndecl = fndecl;
a818fd0b 15883#endif
db7a90aa 15884 s390_indirect_branch_settings (fndecl);
7a0cee35 15885}
7a0cee35 15886
a83f0e2c 15887/* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
15888
15889static bool
89da42b6 15890s390_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
a83f0e2c 15891 unsigned int align ATTRIBUTE_UNUSED,
15892 enum by_pieces_operation op ATTRIBUTE_UNUSED,
15893 bool speed_p ATTRIBUTE_UNUSED)
15894{
15895 return (size == 1 || size == 2
15896 || size == 4 || (TARGET_ZARCH && size == 8));
15897}
15898
90f58e2a 15899/* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV hook. */
15900
15901static void
15902s390_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
15903{
07f32359 15904 tree sfpc = s390_builtin_decls[S390_BUILTIN_s390_sfpc];
15905 tree efpc = s390_builtin_decls[S390_BUILTIN_s390_efpc];
90f58e2a 15906 tree call_efpc = build_call_expr (efpc, 0);
9550ce87 15907 tree fenv_var = create_tmp_var_raw (unsigned_type_node);
90f58e2a 15908
15909#define FPC_EXCEPTION_MASK HOST_WIDE_INT_UC (0xf8000000)
15910#define FPC_FLAGS_MASK HOST_WIDE_INT_UC (0x00f80000)
15911#define FPC_DXC_MASK HOST_WIDE_INT_UC (0x0000ff00)
15912#define FPC_EXCEPTION_MASK_SHIFT HOST_WIDE_INT_UC (24)
15913#define FPC_FLAGS_SHIFT HOST_WIDE_INT_UC (16)
15914#define FPC_DXC_SHIFT HOST_WIDE_INT_UC (8)
15915
15916 /* Generates the equivalent of feholdexcept (&fenv_var)
15917
15918 fenv_var = __builtin_s390_efpc ();
15919 __builtin_s390_sfpc (fenv_var & mask) */
15920 tree old_fpc = build2 (MODIFY_EXPR, unsigned_type_node, fenv_var, call_efpc);
15921 tree new_fpc =
15922 build2 (BIT_AND_EXPR, unsigned_type_node, fenv_var,
15923 build_int_cst (unsigned_type_node,
15924 ~(FPC_DXC_MASK | FPC_FLAGS_MASK |
15925 FPC_EXCEPTION_MASK)));
15926 tree set_new_fpc = build_call_expr (sfpc, 1, new_fpc);
15927 *hold = build2 (COMPOUND_EXPR, void_type_node, old_fpc, set_new_fpc);
15928
15929 /* Generates the equivalent of feclearexcept (FE_ALL_EXCEPT)
15930
15931 __builtin_s390_sfpc (__builtin_s390_efpc () & mask) */
15932 new_fpc = build2 (BIT_AND_EXPR, unsigned_type_node, call_efpc,
15933 build_int_cst (unsigned_type_node,
15934 ~(FPC_DXC_MASK | FPC_FLAGS_MASK)));
15935 *clear = build_call_expr (sfpc, 1, new_fpc);
15936
15937 /* Generates the equivalent of feupdateenv (fenv_var)
15938
15939 old_fpc = __builtin_s390_efpc ();
15940 __builtin_s390_sfpc (fenv_var);
15941 __atomic_feraiseexcept ((old_fpc & FPC_FLAGS_MASK) >> FPC_FLAGS_SHIFT); */
15942
9550ce87 15943 old_fpc = create_tmp_var_raw (unsigned_type_node);
90f58e2a 15944 tree store_old_fpc = build2 (MODIFY_EXPR, void_type_node,
15945 old_fpc, call_efpc);
15946
15947 set_new_fpc = build_call_expr (sfpc, 1, fenv_var);
15948
15949 tree raise_old_except = build2 (BIT_AND_EXPR, unsigned_type_node, old_fpc,
15950 build_int_cst (unsigned_type_node,
15951 FPC_FLAGS_MASK));
15952 raise_old_except = build2 (RSHIFT_EXPR, unsigned_type_node, raise_old_except,
15953 build_int_cst (unsigned_type_node,
15954 FPC_FLAGS_SHIFT));
15955 tree atomic_feraiseexcept
15956 = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT);
15957 raise_old_except = build_call_expr (atomic_feraiseexcept,
15958 1, raise_old_except);
15959
15960 *update = build2 (COMPOUND_EXPR, void_type_node,
15961 build2 (COMPOUND_EXPR, void_type_node,
15962 store_old_fpc, set_new_fpc),
15963 raise_old_except);
15964
15965#undef FPC_EXCEPTION_MASK
15966#undef FPC_FLAGS_MASK
15967#undef FPC_DXC_MASK
15968#undef FPC_EXCEPTION_MASK_SHIFT
15969#undef FPC_FLAGS_SHIFT
15970#undef FPC_DXC_SHIFT
15971}
15972
76a4c804 15973/* Return the vector mode to be used for inner mode MODE when doing
15974 vectorization. */
15975static machine_mode
4c1a1be2 15976s390_preferred_simd_mode (scalar_mode mode)
76a4c804 15977{
4de9f101 15978 if (TARGET_VXE)
15979 switch (mode)
15980 {
15981 case E_SFmode:
15982 return V4SFmode;
15983 default:;
15984 }
15985
76a4c804 15986 if (TARGET_VX)
15987 switch (mode)
15988 {
916ace94 15989 case E_DFmode:
76a4c804 15990 return V2DFmode;
916ace94 15991 case E_DImode:
76a4c804 15992 return V2DImode;
916ace94 15993 case E_SImode:
76a4c804 15994 return V4SImode;
916ace94 15995 case E_HImode:
76a4c804 15996 return V8HImode;
916ace94 15997 case E_QImode:
76a4c804 15998 return V16QImode;
15999 default:;
16000 }
16001 return word_mode;
16002}
16003
16004/* Our hardware does not require vectors to be strictly aligned. */
16005static bool
16006s390_support_vector_misalignment (machine_mode mode ATTRIBUTE_UNUSED,
16007 const_tree type ATTRIBUTE_UNUSED,
16008 int misalignment ATTRIBUTE_UNUSED,
16009 bool is_packed ATTRIBUTE_UNUSED)
16010{
6bb09dc9 16011 if (TARGET_VX)
16012 return true;
16013
16014 return default_builtin_support_vector_misalignment (mode, type, misalignment,
16015 is_packed);
76a4c804 16016}
16017
16018/* The vector ABI requires vector types to be aligned on an 8 byte
16019 boundary (our stack alignment). However, we allow this to be
16020 overriden by the user, while this definitely breaks the ABI. */
16021static HOST_WIDE_INT
16022s390_vector_alignment (const_tree type)
16023{
16024 if (!TARGET_VX_ABI)
16025 return default_vector_alignment (type);
16026
16027 if (TYPE_USER_ALIGN (type))
16028 return TYPE_ALIGN (type);
16029
16030 return MIN (64, tree_to_shwi (TYPE_SIZE (type)));
16031}
16032
579d67ba 16033/* Implement TARGET_CONSTANT_ALIGNMENT. Alignment on even addresses for
16034 LARL instruction. */
16035
16036static HOST_WIDE_INT
16037s390_constant_alignment (const_tree, HOST_WIDE_INT align)
16038{
16039 return MAX (align, 16);
16040}
16041
14d7e7e6 16042#ifdef HAVE_AS_MACHINE_MACHINEMODE
16043/* Implement TARGET_ASM_FILE_START. */
16044static void
16045s390_asm_file_start (void)
16046{
b904831d 16047 default_file_start ();
14d7e7e6 16048 s390_asm_output_machine_for_arch (asm_out_file);
16049}
16050#endif
16051
6b7cfb9c 16052/* Implement TARGET_ASM_FILE_END. */
16053static void
16054s390_asm_file_end (void)
16055{
16056#ifdef HAVE_AS_GNU_ATTRIBUTE
16057 varpool_node *vnode;
16058 cgraph_node *cnode;
16059
16060 FOR_EACH_VARIABLE (vnode)
16061 if (TREE_PUBLIC (vnode->decl))
16062 s390_check_type_for_vector_abi (TREE_TYPE (vnode->decl), false, false);
16063
16064 FOR_EACH_FUNCTION (cnode)
16065 if (TREE_PUBLIC (cnode->decl))
16066 s390_check_type_for_vector_abi (TREE_TYPE (cnode->decl), false, false);
16067
16068
16069 if (s390_vector_abi != 0)
16070 fprintf (asm_out_file, "\t.gnu_attribute 8, %d\n",
16071 s390_vector_abi);
16072#endif
16073 file_end_indicate_exec_stack ();
c6d481f7 16074
16075 if (flag_split_stack)
16076 file_end_indicate_split_stack ();
6b7cfb9c 16077}
76a4c804 16078
f0c550e7 16079/* Return true if TYPE is a vector bool type. */
16080static inline bool
16081s390_vector_bool_type_p (const_tree type)
16082{
16083 return TYPE_VECTOR_OPAQUE (type);
16084}
16085
16086/* Return the diagnostic message string if the binary operation OP is
16087 not permitted on TYPE1 and TYPE2, NULL otherwise. */
16088static const char*
16089s390_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1, const_tree type2)
16090{
16091 bool bool1_p, bool2_p;
16092 bool plusminus_p;
16093 bool muldiv_p;
16094 bool compare_p;
16095 machine_mode mode1, mode2;
16096
16097 if (!TARGET_ZVECTOR)
16098 return NULL;
16099
16100 if (!VECTOR_TYPE_P (type1) || !VECTOR_TYPE_P (type2))
16101 return NULL;
16102
16103 bool1_p = s390_vector_bool_type_p (type1);
16104 bool2_p = s390_vector_bool_type_p (type2);
16105
16106 /* Mixing signed and unsigned types is forbidden for all
16107 operators. */
16108 if (!bool1_p && !bool2_p
16109 && TYPE_UNSIGNED (type1) != TYPE_UNSIGNED (type2))
d0abd9e0 16110 return N_("types differ in signedness");
f0c550e7 16111
16112 plusminus_p = (op == PLUS_EXPR || op == MINUS_EXPR);
16113 muldiv_p = (op == MULT_EXPR || op == RDIV_EXPR || op == TRUNC_DIV_EXPR
16114 || op == CEIL_DIV_EXPR || op == FLOOR_DIV_EXPR
16115 || op == ROUND_DIV_EXPR);
16116 compare_p = (op == LT_EXPR || op == LE_EXPR || op == GT_EXPR || op == GE_EXPR
16117 || op == EQ_EXPR || op == NE_EXPR);
16118
16119 if (bool1_p && bool2_p && (plusminus_p || muldiv_p))
16120 return N_("binary operator does not support two vector bool operands");
16121
16122 if (bool1_p != bool2_p && (muldiv_p || compare_p))
16123 return N_("binary operator does not support vector bool operand");
16124
16125 mode1 = TYPE_MODE (type1);
16126 mode2 = TYPE_MODE (type2);
16127
16128 if (bool1_p != bool2_p && plusminus_p
16129 && (GET_MODE_CLASS (mode1) == MODE_VECTOR_FLOAT
16130 || GET_MODE_CLASS (mode2) == MODE_VECTOR_FLOAT))
16131 return N_("binary operator does not support mixing vector "
16132 "bool with floating point vector operands");
16133
16134 return NULL;
16135}
16136
1de60655 16137/* Implement TARGET_C_EXCESS_PRECISION.
16138
16139 FIXME: For historical reasons, float_t and double_t are typedef'ed to
16140 double on s390, causing operations on float_t to operate in a higher
16141 precision than is necessary. However, it is not the case that SFmode
16142 operations have implicit excess precision, and we generate more optimal
16143 code if we let the compiler know no implicit extra precision is added.
16144
16145 That means when we are compiling with -fexcess-precision=fast, the value
16146 we set for FLT_EVAL_METHOD will be out of line with the actual precision of
16147 float_t (though they would be correct for -fexcess-precision=standard).
16148
16149 A complete fix would modify glibc to remove the unnecessary typedef
16150 of float_t to double. */
16151
16152static enum flt_eval_method
16153s390_excess_precision (enum excess_precision_type type)
16154{
16155 switch (type)
16156 {
16157 case EXCESS_PRECISION_TYPE_IMPLICIT:
16158 case EXCESS_PRECISION_TYPE_FAST:
16159 /* The fastest type to promote to will always be the native type,
16160 whether that occurs with implicit excess precision or
16161 otherwise. */
16162 return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
16163 case EXCESS_PRECISION_TYPE_STANDARD:
16164 /* Otherwise, when we are in a standards compliant mode, to
16165 ensure consistency with the implementation in glibc, report that
16166 float is evaluated to the range and precision of double. */
16167 return FLT_EVAL_METHOD_PROMOTE_TO_DOUBLE;
16168 default:
16169 gcc_unreachable ();
16170 }
16171 return FLT_EVAL_METHOD_UNPREDICTABLE;
16172}
16173
fff1179b 16174/* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */
16175
16176static unsigned HOST_WIDE_INT
16177s390_asan_shadow_offset (void)
16178{
16179 return TARGET_64BIT ? HOST_WIDE_INT_1U << 52 : HOST_WIDE_INT_UC (0x20000000);
16180}
16181
db7a90aa 16182#ifdef HAVE_GAS_HIDDEN
16183# define USE_HIDDEN_LINKONCE 1
16184#else
16185# define USE_HIDDEN_LINKONCE 0
16186#endif
16187
16188/* Output an indirect branch trampoline for target register REGNO. */
16189
16190static void
16191s390_output_indirect_thunk_function (unsigned int regno, bool z10_p)
16192{
16193 tree decl;
16194 char thunk_label[32];
16195 int i;
16196
16197 if (z10_p)
16198 sprintf (thunk_label, TARGET_INDIRECT_BRANCH_THUNK_NAME_EXRL, regno);
16199 else
16200 sprintf (thunk_label, TARGET_INDIRECT_BRANCH_THUNK_NAME_EX,
16201 INDIRECT_BRANCH_THUNK_REGNUM, regno);
16202
16203 decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
16204 get_identifier (thunk_label),
16205 build_function_type_list (void_type_node, NULL_TREE));
16206 DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,
16207 NULL_TREE, void_type_node);
16208 TREE_PUBLIC (decl) = 1;
16209 TREE_STATIC (decl) = 1;
16210 DECL_IGNORED_P (decl) = 1;
16211
16212 if (USE_HIDDEN_LINKONCE)
16213 {
16214 cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl));
16215
16216 targetm.asm_out.unique_section (decl, 0);
16217 switch_to_section (get_named_section (decl, NULL, 0));
16218
16219 targetm.asm_out.globalize_label (asm_out_file, thunk_label);
16220 fputs ("\t.hidden\t", asm_out_file);
16221 assemble_name (asm_out_file, thunk_label);
16222 putc ('\n', asm_out_file);
16223 ASM_DECLARE_FUNCTION_NAME (asm_out_file, thunk_label, decl);
16224 }
16225 else
16226 {
16227 switch_to_section (text_section);
16228 ASM_OUTPUT_LABEL (asm_out_file, thunk_label);
16229 }
16230
16231 DECL_INITIAL (decl) = make_node (BLOCK);
16232 current_function_decl = decl;
16233 allocate_struct_function (decl, false);
16234 init_function_start (decl);
16235 cfun->is_thunk = true;
16236 first_function_block_is_cold = false;
16237 final_start_function (emit_barrier (), asm_out_file, 1);
16238
16239 /* This makes CFI at least usable for indirect jumps.
16240
16241 Stopping in the thunk: backtrace will point to the thunk target
16242 is if it was interrupted by a signal. For a call this means that
16243 the call chain will be: caller->callee->thunk */
49033c9c 16244 if (flag_asynchronous_unwind_tables && flag_dwarf2_cfi_asm)
db7a90aa 16245 {
16246 fputs ("\t.cfi_signal_frame\n", asm_out_file);
16247 fprintf (asm_out_file, "\t.cfi_return_column %d\n", regno);
16248 for (i = 0; i < FPR15_REGNUM; i++)
16249 fprintf (asm_out_file, "\t.cfi_same_value %s\n", reg_names[i]);
16250 }
16251
16252 if (z10_p)
16253 {
16254 /* exrl 0,1f */
16255
16256 /* We generate a thunk for z10 compiled code although z10 is
16257 currently not enabled. Tell the assembler to accept the
16258 instruction. */
16259 if (!TARGET_CPU_Z10)
16260 {
16261 fputs ("\t.machine push\n", asm_out_file);
16262 fputs ("\t.machine z10\n", asm_out_file);
16263 }
16264 /* We use exrl even if -mzarch hasn't been specified on the
16265 command line so we have to tell the assembler to accept
16266 it. */
16267 if (!TARGET_ZARCH)
16268 fputs ("\t.machinemode zarch\n", asm_out_file);
16269
16270 fputs ("\texrl\t0,1f\n", asm_out_file);
16271
16272 if (!TARGET_ZARCH)
16273 fputs ("\t.machinemode esa\n", asm_out_file);
16274
16275 if (!TARGET_CPU_Z10)
16276 fputs ("\t.machine pop\n", asm_out_file);
16277 }
f5edbf1d 16278 else
db7a90aa 16279 {
16280 /* larl %r1,1f */
16281 fprintf (asm_out_file, "\tlarl\t%%r%d,1f\n",
16282 INDIRECT_BRANCH_THUNK_REGNUM);
16283
16284 /* ex 0,0(%r1) */
16285 fprintf (asm_out_file, "\tex\t0,0(%%r%d)\n",
16286 INDIRECT_BRANCH_THUNK_REGNUM);
16287 }
db7a90aa 16288
16289 /* 0: j 0b */
16290 fputs ("0:\tj\t0b\n", asm_out_file);
16291
16292 /* 1: br <regno> */
16293 fprintf (asm_out_file, "1:\tbr\t%%r%d\n", regno);
16294
16295 final_end_function ();
16296 init_insn_lengths ();
16297 free_after_compilation (cfun);
16298 set_cfun (NULL);
16299 current_function_decl = NULL;
16300}
16301
16302/* Implement the asm.code_end target hook. */
16303
16304static void
16305s390_code_end (void)
16306{
16307 int i;
16308
16309 for (i = 1; i < 16; i++)
16310 {
16311 if (indirect_branch_z10thunk_mask & (1 << i))
16312 s390_output_indirect_thunk_function (i, true);
16313
16314 if (indirect_branch_prez10thunk_mask & (1 << i))
16315 s390_output_indirect_thunk_function (i, false);
16316 }
16317
16318 if (TARGET_INDIRECT_BRANCH_TABLE)
16319 {
16320 int o;
16321 int i;
16322
16323 for (o = 0; o < INDIRECT_BRANCH_NUM_OPTIONS; o++)
16324 {
16325 if (indirect_branch_table_label_no[o] == 0)
16326 continue;
16327
16328 switch_to_section (get_section (indirect_branch_table_name[o],
16329 0,
16330 NULL_TREE));
16331 for (i = 0; i < indirect_branch_table_label_no[o]; i++)
16332 {
16333 char label_start[32];
16334
16335 ASM_GENERATE_INTERNAL_LABEL (label_start,
16336 indirect_branch_table_label[o], i);
16337
16338 fputs ("\t.long\t", asm_out_file);
16339 assemble_name_raw (asm_out_file, label_start);
16340 fputs ("-.\n", asm_out_file);
16341 }
16342 switch_to_section (current_function_section ());
16343 }
16344 }
16345}
16346
16347/* Implement the TARGET_CASE_VALUES_THRESHOLD target hook. */
16348
16349unsigned int
16350s390_case_values_threshold (void)
16351{
16352 /* Disabling branch prediction for indirect jumps makes jump tables
16353 much more expensive. */
16354 if (TARGET_INDIRECT_BRANCH_NOBP_JUMP)
16355 return 20;
16356
16357 return default_case_values_threshold ();
16358}
16359
4788a5ca 16360/* Evaluate the insns between HEAD and TAIL and do back-end to install
16361 back-end specific dependencies.
16362
16363 Establish an ANTI dependency between r11 and r15 restores from FPRs
16364 to prevent the instructions scheduler from reordering them since
16365 this would break CFI. No further handling in the sched_reorder
16366 hook is required since the r11 and r15 restore will never appear in
16367 the same ready list with that change. */
16368void
16369s390_sched_dependencies_evaluation (rtx_insn *head, rtx_insn *tail)
16370{
16371 if (!frame_pointer_needed || !epilogue_completed)
16372 return;
16373
16374 while (head != tail && DEBUG_INSN_P (head))
16375 head = NEXT_INSN (head);
16376
16377 rtx_insn *r15_restore = NULL, *r11_restore = NULL;
16378
16379 for (rtx_insn *insn = tail; insn != head; insn = PREV_INSN (insn))
16380 {
16381 rtx set = single_set (insn);
16382 if (!INSN_P (insn)
16383 || !RTX_FRAME_RELATED_P (insn)
16384 || set == NULL_RTX
16385 || !REG_P (SET_DEST (set))
16386 || !FP_REG_P (SET_SRC (set)))
16387 continue;
16388
16389 if (REGNO (SET_DEST (set)) == HARD_FRAME_POINTER_REGNUM)
16390 r11_restore = insn;
16391
16392 if (REGNO (SET_DEST (set)) == STACK_POINTER_REGNUM)
16393 r15_restore = insn;
16394 }
16395
16396 if (r11_restore == NULL || r15_restore == NULL)
16397 return;
16398 add_dependence (r11_restore, r15_restore, REG_DEP_ANTI);
16399}
16400
2aa1dcc8 16401/* Implement TARGET_SHIFT_TRUNCATION_MASK for integer shifts. */
4788a5ca 16402
2aa1dcc8 16403static unsigned HOST_WIDE_INT
16404s390_shift_truncation_mask (machine_mode mode)
16405{
16406 return mode == DImode || mode == SImode ? 63 : 0;
16407}
4788a5ca 16408
875862bf 16409/* Initialize GCC target structure. */
f588eb9f 16410
875862bf 16411#undef TARGET_ASM_ALIGNED_HI_OP
16412#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
16413#undef TARGET_ASM_ALIGNED_DI_OP
16414#define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
16415#undef TARGET_ASM_INTEGER
16416#define TARGET_ASM_INTEGER s390_assemble_integer
7346ca58 16417
875862bf 16418#undef TARGET_ASM_OPEN_PAREN
16419#define TARGET_ASM_OPEN_PAREN ""
f588eb9f 16420
875862bf 16421#undef TARGET_ASM_CLOSE_PAREN
16422#define TARGET_ASM_CLOSE_PAREN ""
7346ca58 16423
4c834714 16424#undef TARGET_OPTION_OVERRIDE
16425#define TARGET_OPTION_OVERRIDE s390_option_override
16426
8a23256f 16427#ifdef TARGET_THREAD_SSP_OFFSET
16428#undef TARGET_STACK_PROTECT_GUARD
16429#define TARGET_STACK_PROTECT_GUARD hook_tree_void_null
16430#endif
16431
875862bf 16432#undef TARGET_ENCODE_SECTION_INFO
16433#define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
7346ca58 16434
b5fdc416 16435#undef TARGET_SCALAR_MODE_SUPPORTED_P
16436#define TARGET_SCALAR_MODE_SUPPORTED_P s390_scalar_mode_supported_p
16437
875862bf 16438#ifdef HAVE_AS_TLS
16439#undef TARGET_HAVE_TLS
16440#define TARGET_HAVE_TLS true
16441#endif
16442#undef TARGET_CANNOT_FORCE_CONST_MEM
16443#define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
7346ca58 16444
875862bf 16445#undef TARGET_DELEGITIMIZE_ADDRESS
16446#define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
7346ca58 16447
41e3a0c7 16448#undef TARGET_LEGITIMIZE_ADDRESS
16449#define TARGET_LEGITIMIZE_ADDRESS s390_legitimize_address
16450
875862bf 16451#undef TARGET_RETURN_IN_MEMORY
16452#define TARGET_RETURN_IN_MEMORY s390_return_in_memory
f588eb9f 16453
5ada7a14 16454#undef TARGET_INIT_BUILTINS
16455#define TARGET_INIT_BUILTINS s390_init_builtins
16456#undef TARGET_EXPAND_BUILTIN
16457#define TARGET_EXPAND_BUILTIN s390_expand_builtin
751c914e 16458#undef TARGET_BUILTIN_DECL
16459#define TARGET_BUILTIN_DECL s390_builtin_decl
5ada7a14 16460
1a561788 16461#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
16462#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA s390_output_addr_const_extra
16463
875862bf 16464#undef TARGET_ASM_OUTPUT_MI_THUNK
16465#define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
16466#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
a9f1838b 16467#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
7346ca58 16468
1de60655 16469#undef TARGET_C_EXCESS_PRECISION
16470#define TARGET_C_EXCESS_PRECISION s390_excess_precision
16471
875862bf 16472#undef TARGET_SCHED_ADJUST_PRIORITY
16473#define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
16474#undef TARGET_SCHED_ISSUE_RATE
16475#define TARGET_SCHED_ISSUE_RATE s390_issue_rate
16476#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
16477#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
f588eb9f 16478
8a2a84e3 16479#undef TARGET_SCHED_VARIABLE_ISSUE
16480#define TARGET_SCHED_VARIABLE_ISSUE s390_sched_variable_issue
16481#undef TARGET_SCHED_REORDER
16482#define TARGET_SCHED_REORDER s390_sched_reorder
494d0169 16483#undef TARGET_SCHED_INIT
16484#define TARGET_SCHED_INIT s390_sched_init
8a2a84e3 16485
875862bf 16486#undef TARGET_CANNOT_COPY_INSN_P
16487#define TARGET_CANNOT_COPY_INSN_P s390_cannot_copy_insn_p
16488#undef TARGET_RTX_COSTS
16489#define TARGET_RTX_COSTS s390_rtx_costs
16490#undef TARGET_ADDRESS_COST
16491#define TARGET_ADDRESS_COST s390_address_cost
fa7a995b 16492#undef TARGET_REGISTER_MOVE_COST
16493#define TARGET_REGISTER_MOVE_COST s390_register_move_cost
16494#undef TARGET_MEMORY_MOVE_COST
16495#define TARGET_MEMORY_MOVE_COST s390_memory_move_cost
292e369f 16496#undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
16497#define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
16498 s390_builtin_vectorization_cost
f588eb9f 16499
875862bf 16500#undef TARGET_MACHINE_DEPENDENT_REORG
16501#define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
71597dac 16502
875862bf 16503#undef TARGET_VALID_POINTER_MODE
16504#define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
f588eb9f 16505
875862bf 16506#undef TARGET_BUILD_BUILTIN_VA_LIST
16507#define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
8a58ed0a 16508#undef TARGET_EXPAND_BUILTIN_VA_START
16509#define TARGET_EXPAND_BUILTIN_VA_START s390_va_start
fff1179b 16510#undef TARGET_ASAN_SHADOW_OFFSET
16511#define TARGET_ASAN_SHADOW_OFFSET s390_asan_shadow_offset
875862bf 16512#undef TARGET_GIMPLIFY_VA_ARG_EXPR
16513#define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg
b33c41a1 16514
3b2411a8 16515#undef TARGET_PROMOTE_FUNCTION_MODE
16516#define TARGET_PROMOTE_FUNCTION_MODE s390_promote_function_mode
875862bf 16517#undef TARGET_PASS_BY_REFERENCE
16518#define TARGET_PASS_BY_REFERENCE s390_pass_by_reference
b33c41a1 16519
908d23b5 16520#undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
16521#define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE s390_override_options_after_change
16522
875862bf 16523#undef TARGET_FUNCTION_OK_FOR_SIBCALL
16524#define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
12bc26aa 16525#undef TARGET_FUNCTION_ARG
16526#define TARGET_FUNCTION_ARG s390_function_arg
16527#undef TARGET_FUNCTION_ARG_ADVANCE
16528#define TARGET_FUNCTION_ARG_ADVANCE s390_function_arg_advance
d7ab0e3d 16529#undef TARGET_FUNCTION_ARG_PADDING
16530#define TARGET_FUNCTION_ARG_PADDING s390_function_arg_padding
dc3b3062 16531#undef TARGET_FUNCTION_VALUE
16532#define TARGET_FUNCTION_VALUE s390_function_value
16533#undef TARGET_LIBCALL_VALUE
16534#define TARGET_LIBCALL_VALUE s390_libcall_value
76a4c804 16535#undef TARGET_STRICT_ARGUMENT_NAMING
16536#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
b33c41a1 16537
d44f2f7c 16538#undef TARGET_KEEP_LEAF_WHEN_PROFILED
16539#define TARGET_KEEP_LEAF_WHEN_PROFILED s390_keep_leaf_when_profiled
16540
875862bf 16541#undef TARGET_FIXED_CONDITION_CODE_REGS
16542#define TARGET_FIXED_CONDITION_CODE_REGS s390_fixed_condition_code_regs
b33c41a1 16543
875862bf 16544#undef TARGET_CC_MODES_COMPATIBLE
16545#define TARGET_CC_MODES_COMPATIBLE s390_cc_modes_compatible
b33c41a1 16546
1606e68a 16547#undef TARGET_INVALID_WITHIN_DOLOOP
18282db0 16548#define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_const_rtx_insn_null
e75dabf7 16549
40af64cc 16550#ifdef HAVE_AS_TLS
16551#undef TARGET_ASM_OUTPUT_DWARF_DTPREL
16552#define TARGET_ASM_OUTPUT_DWARF_DTPREL s390_output_dwarf_dtprel
16553#endif
16554
76a4c804 16555#undef TARGET_DWARF_FRAME_REG_MODE
16556#define TARGET_DWARF_FRAME_REG_MODE s390_dwarf_frame_reg_mode
16557
4257b08a 16558#ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
eddcdde1 16559#undef TARGET_MANGLE_TYPE
16560#define TARGET_MANGLE_TYPE s390_mangle_type
4257b08a 16561#endif
16562
36868490 16563#undef TARGET_SCALAR_MODE_SUPPORTED_P
16564#define TARGET_SCALAR_MODE_SUPPORTED_P s390_scalar_mode_supported_p
16565
76a4c804 16566#undef TARGET_VECTOR_MODE_SUPPORTED_P
16567#define TARGET_VECTOR_MODE_SUPPORTED_P s390_vector_mode_supported_p
16568
3359ccfd 16569#undef TARGET_PREFERRED_RELOAD_CLASS
16570#define TARGET_PREFERRED_RELOAD_CLASS s390_preferred_reload_class
16571
328d5423 16572#undef TARGET_SECONDARY_RELOAD
16573#define TARGET_SECONDARY_RELOAD s390_secondary_reload
c836e75b 16574#undef TARGET_SECONDARY_MEMORY_NEEDED
16575#define TARGET_SECONDARY_MEMORY_NEEDED s390_secondary_memory_needed
1041f930 16576#undef TARGET_SECONDARY_MEMORY_NEEDED_MODE
16577#define TARGET_SECONDARY_MEMORY_NEEDED_MODE s390_secondary_memory_needed_mode
328d5423 16578
0ef89dfd 16579#undef TARGET_LIBGCC_CMP_RETURN_MODE
16580#define TARGET_LIBGCC_CMP_RETURN_MODE s390_libgcc_cmp_return_mode
16581
16582#undef TARGET_LIBGCC_SHIFT_COUNT_MODE
16583#define TARGET_LIBGCC_SHIFT_COUNT_MODE s390_libgcc_shift_count_mode
16584
fd50b071 16585#undef TARGET_LEGITIMATE_ADDRESS_P
16586#define TARGET_LEGITIMATE_ADDRESS_P s390_legitimate_address_p
16587
ca316360 16588#undef TARGET_LEGITIMATE_CONSTANT_P
16589#define TARGET_LEGITIMATE_CONSTANT_P s390_legitimate_constant_p
16590
7b1bda1c 16591#undef TARGET_LRA_P
16592#define TARGET_LRA_P s390_lra_p
16593
cd90919d 16594#undef TARGET_CAN_ELIMINATE
16595#define TARGET_CAN_ELIMINATE s390_can_eliminate
16596
b2d7ede1 16597#undef TARGET_CONDITIONAL_REGISTER_USAGE
16598#define TARGET_CONDITIONAL_REGISTER_USAGE s390_conditional_register_usage
16599
9ccaa774 16600#undef TARGET_LOOP_UNROLL_ADJUST
16601#define TARGET_LOOP_UNROLL_ADJUST s390_loop_unroll_adjust
16602
4d946732 16603#undef TARGET_ASM_TRAMPOLINE_TEMPLATE
16604#define TARGET_ASM_TRAMPOLINE_TEMPLATE s390_asm_trampoline_template
16605#undef TARGET_TRAMPOLINE_INIT
16606#define TARGET_TRAMPOLINE_INIT s390_trampoline_init
16607
8805debf 16608/* PR 79421 */
16609#undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
16610#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1
16611
b5fdc416 16612#undef TARGET_UNWIND_WORD_MODE
16613#define TARGET_UNWIND_WORD_MODE s390_unwind_word_mode
16614
d5065e6e 16615#undef TARGET_CANONICALIZE_COMPARISON
16616#define TARGET_CANONICALIZE_COMPARISON s390_canonicalize_comparison
16617
ff4ce128 16618#undef TARGET_HARD_REGNO_SCRATCH_OK
16619#define TARGET_HARD_REGNO_SCRATCH_OK s390_hard_regno_scratch_ok
16620
74f68e49 16621#undef TARGET_HARD_REGNO_NREGS
16622#define TARGET_HARD_REGNO_NREGS s390_hard_regno_nregs
b395382f 16623#undef TARGET_HARD_REGNO_MODE_OK
16624#define TARGET_HARD_REGNO_MODE_OK s390_hard_regno_mode_ok
5f6dcf1a 16625#undef TARGET_MODES_TIEABLE_P
16626#define TARGET_MODES_TIEABLE_P s390_modes_tieable_p
b395382f 16627
5da94e60 16628#undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED
16629#define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
16630 s390_hard_regno_call_part_clobbered
16631
77bc9912 16632#undef TARGET_ATTRIBUTE_TABLE
16633#define TARGET_ATTRIBUTE_TABLE s390_attribute_table
16634
11762b83 16635#undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
16636#define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_const_tree_true
77bc9912 16637
7a64c761 16638#undef TARGET_SET_UP_BY_PROLOGUE
16639#define TARGET_SET_UP_BY_PROLOGUE s300_set_up_by_prologue
16640
c6d481f7 16641#undef TARGET_EXTRA_LIVE_ON_ENTRY
16642#define TARGET_EXTRA_LIVE_ON_ENTRY s390_live_on_entry
16643
a83f0e2c 16644#undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
16645#define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
16646 s390_use_by_pieces_infrastructure_p
16647
90f58e2a 16648#undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
16649#define TARGET_ATOMIC_ASSIGN_EXPAND_FENV s390_atomic_assign_expand_fenv
16650
76a4c804 16651#undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
16652#define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN s390_invalid_arg_for_unprototyped_fn
16653
16654#undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
16655#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE s390_preferred_simd_mode
16656
16657#undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
16658#define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT s390_support_vector_misalignment
16659
16660#undef TARGET_VECTOR_ALIGNMENT
16661#define TARGET_VECTOR_ALIGNMENT s390_vector_alignment
16662
f0c550e7 16663#undef TARGET_INVALID_BINARY_OP
16664#define TARGET_INVALID_BINARY_OP s390_invalid_binary_op
16665
14d7e7e6 16666#ifdef HAVE_AS_MACHINE_MACHINEMODE
16667#undef TARGET_ASM_FILE_START
16668#define TARGET_ASM_FILE_START s390_asm_file_start
16669#endif
16670
6b7cfb9c 16671#undef TARGET_ASM_FILE_END
16672#define TARGET_ASM_FILE_END s390_asm_file_end
16673
7a0cee35 16674#undef TARGET_SET_CURRENT_FUNCTION
16675#define TARGET_SET_CURRENT_FUNCTION s390_set_current_function
16676
a818fd0b 16677#if S390_USE_TARGET_ATTRIBUTE
7a0cee35 16678#undef TARGET_OPTION_VALID_ATTRIBUTE_P
16679#define TARGET_OPTION_VALID_ATTRIBUTE_P s390_valid_target_attribute_p
d5a90e99 16680
16681#undef TARGET_CAN_INLINE_P
16682#define TARGET_CAN_INLINE_P s390_can_inline_p
7a0cee35 16683#endif
16684
16685#undef TARGET_OPTION_RESTORE
16686#define TARGET_OPTION_RESTORE s390_function_specific_restore
16687
b56a9dbc 16688#undef TARGET_CAN_CHANGE_MODE_CLASS
16689#define TARGET_CAN_CHANGE_MODE_CLASS s390_can_change_mode_class
16690
579d67ba 16691#undef TARGET_CONSTANT_ALIGNMENT
16692#define TARGET_CONSTANT_ALIGNMENT s390_constant_alignment
16693
db7a90aa 16694#undef TARGET_ASM_CODE_END
16695#define TARGET_ASM_CODE_END s390_code_end
16696
16697#undef TARGET_CASE_VALUES_THRESHOLD
16698#define TARGET_CASE_VALUES_THRESHOLD s390_case_values_threshold
16699
4788a5ca 16700#undef TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK
16701#define TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK \
16702 s390_sched_dependencies_evaluation
16703
2aa1dcc8 16704#undef TARGET_SHIFT_TRUNCATION_MASK
16705#define TARGET_SHIFT_TRUNCATION_MASK s390_shift_truncation_mask
4788a5ca 16706
63cd2315 16707/* Use only short displacement, since long displacement is not available for
16708 the floating point instructions. */
16709#undef TARGET_MAX_ANCHOR_OFFSET
16710#define TARGET_MAX_ANCHOR_OFFSET 0xfff
16711
875862bf 16712struct gcc_target targetm = TARGET_INITIALIZER;
f588eb9f 16713
5a5e802f 16714#include "gt-s390.h"