]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/s390/s390.c
.
[thirdparty/gcc.git] / gcc / config / s390 / s390.c
CommitLineData
4673c1a0 1/* Subroutines used for code generation on IBM S/390 and zSeries
aad93da1 2 Copyright (C) 1999-2017 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
23#include "config.h"
4673c1a0 24#include "system.h"
805e22b2 25#include "coretypes.h"
9ef16211 26#include "backend.h"
c1eb80de 27#include "target.h"
7a0cee35 28#include "target-globals.h"
c1eb80de 29#include "rtl.h"
9ef16211 30#include "tree.h"
31#include "gimple.h"
c1eb80de 32#include "cfghooks.h"
33#include "cfgloop.h"
9ef16211 34#include "df.h"
ad7b10a2 35#include "memmodel.h"
c1eb80de 36#include "tm_p.h"
37#include "stringpool.h"
30a86690 38#include "attribs.h"
c1eb80de 39#include "expmed.h"
40#include "optabs.h"
41#include "regs.h"
42#include "emit-rtl.h"
43#include "recog.h"
44#include "cgraph.h"
45#include "diagnostic-core.h"
7a0cee35 46#include "diagnostic.h"
b20a8bb4 47#include "alias.h"
b20a8bb4 48#include "fold-const.h"
9ed99284 49#include "print-tree.h"
9ed99284 50#include "stor-layout.h"
51#include "varasm.h"
52#include "calls.h"
4673c1a0 53#include "conditions.h"
54#include "output.h"
55#include "insn-attr.h"
56#include "flags.h"
57#include "except.h"
d53441c8 58#include "dojump.h"
59#include "explow.h"
d53441c8 60#include "stmt.h"
4673c1a0 61#include "expr.h"
c10847b9 62#include "reload.h"
94ea8568 63#include "cfgrtl.h"
64#include "cfganal.h"
65#include "lcm.h"
66#include "cfgbuild.h"
67#include "cfgcleanup.h"
7baa5366 68#include "debug.h"
a1f71e15 69#include "langhooks.h"
bc61cadb 70#include "internal-fn.h"
71#include "gimple-fold.h"
72#include "tree-eh.h"
a8783bee 73#include "gimplify.h"
c0717306 74#include "params.h"
fba5dd52 75#include "opts.h"
0b8be04c 76#include "tree-pass.h"
77#include "context.h"
f7715905 78#include "builtins.h"
15e472ec 79#include "rtl-iter.h"
76a4c804 80#include "intl.h"
80fc7f56 81#include "tm-constrs.h"
4673c1a0 82
0c71fb4f 83/* This file should be included last. */
4b498588 84#include "target-def.h"
85
7a0cee35 86/* Remember the last target of s390_set_current_function. */
87static GTY(()) tree s390_previous_fndecl;
88
18925d38 89/* Define the specific costs for a given cpu. */
90
ffead1ca 91struct processor_costs
18925d38 92{
260075cc 93 /* multiplication */
18925d38 94 const int m; /* cost of an M instruction. */
95 const int mghi; /* cost of an MGHI instruction. */
96 const int mh; /* cost of an MH instruction. */
97 const int mhi; /* cost of an MHI instruction. */
9cd3f3e6 98 const int ml; /* cost of an ML instruction. */
18925d38 99 const int mr; /* cost of an MR instruction. */
100 const int ms; /* cost of an MS instruction. */
101 const int msg; /* cost of an MSG instruction. */
102 const int msgf; /* cost of an MSGF instruction. */
103 const int msgfr; /* cost of an MSGFR instruction. */
104 const int msgr; /* cost of an MSGR instruction. */
105 const int msr; /* cost of an MSR instruction. */
106 const int mult_df; /* cost of multiplication in DFmode. */
429f9fdb 107 const int mxbr;
260075cc 108 /* square root */
429f9fdb 109 const int sqxbr; /* cost of square root in TFmode. */
9cd3f3e6 110 const int sqdbr; /* cost of square root in DFmode. */
111 const int sqebr; /* cost of square root in SFmode. */
260075cc 112 /* multiply and add */
d95e38cf 113 const int madbr; /* cost of multiply and add in DFmode. */
114 const int maebr; /* cost of multiply and add in SFmode. */
260075cc 115 /* division */
429f9fdb 116 const int dxbr;
260075cc 117 const int ddbr;
260075cc 118 const int debr;
3f074425 119 const int dlgr;
120 const int dlr;
121 const int dr;
122 const int dsgfr;
123 const int dsgr;
18925d38 124};
125
7a0cee35 126#define s390_cost ((const struct processor_costs *)(s390_cost_pointer))
18925d38 127
128static const
ffead1ca 129struct processor_costs z900_cost =
18925d38 130{
131 COSTS_N_INSNS (5), /* M */
132 COSTS_N_INSNS (10), /* MGHI */
133 COSTS_N_INSNS (5), /* MH */
134 COSTS_N_INSNS (4), /* MHI */
9cd3f3e6 135 COSTS_N_INSNS (5), /* ML */
18925d38 136 COSTS_N_INSNS (5), /* MR */
137 COSTS_N_INSNS (4), /* MS */
138 COSTS_N_INSNS (15), /* MSG */
139 COSTS_N_INSNS (7), /* MSGF */
140 COSTS_N_INSNS (7), /* MSGFR */
141 COSTS_N_INSNS (10), /* MSGR */
142 COSTS_N_INSNS (4), /* MSR */
143 COSTS_N_INSNS (7), /* multiplication in DFmode */
429f9fdb 144 COSTS_N_INSNS (13), /* MXBR */
145 COSTS_N_INSNS (136), /* SQXBR */
9cd3f3e6 146 COSTS_N_INSNS (44), /* SQDBR */
147 COSTS_N_INSNS (35), /* SQEBR */
d95e38cf 148 COSTS_N_INSNS (18), /* MADBR */
149 COSTS_N_INSNS (13), /* MAEBR */
429f9fdb 150 COSTS_N_INSNS (134), /* DXBR */
260075cc 151 COSTS_N_INSNS (30), /* DDBR */
260075cc 152 COSTS_N_INSNS (27), /* DEBR */
3f074425 153 COSTS_N_INSNS (220), /* DLGR */
154 COSTS_N_INSNS (34), /* DLR */
155 COSTS_N_INSNS (34), /* DR */
156 COSTS_N_INSNS (32), /* DSGFR */
157 COSTS_N_INSNS (32), /* DSGR */
18925d38 158};
159
160static const
ffead1ca 161struct processor_costs z990_cost =
18925d38 162{
163 COSTS_N_INSNS (4), /* M */
164 COSTS_N_INSNS (2), /* MGHI */
165 COSTS_N_INSNS (2), /* MH */
166 COSTS_N_INSNS (2), /* MHI */
9cd3f3e6 167 COSTS_N_INSNS (4), /* ML */
18925d38 168 COSTS_N_INSNS (4), /* MR */
169 COSTS_N_INSNS (5), /* MS */
170 COSTS_N_INSNS (6), /* MSG */
171 COSTS_N_INSNS (4), /* MSGF */
172 COSTS_N_INSNS (4), /* MSGFR */
173 COSTS_N_INSNS (4), /* MSGR */
174 COSTS_N_INSNS (4), /* MSR */
175 COSTS_N_INSNS (1), /* multiplication in DFmode */
429f9fdb 176 COSTS_N_INSNS (28), /* MXBR */
177 COSTS_N_INSNS (130), /* SQXBR */
9cd3f3e6 178 COSTS_N_INSNS (66), /* SQDBR */
179 COSTS_N_INSNS (38), /* SQEBR */
d95e38cf 180 COSTS_N_INSNS (1), /* MADBR */
181 COSTS_N_INSNS (1), /* MAEBR */
429f9fdb 182 COSTS_N_INSNS (60), /* DXBR */
260075cc 183 COSTS_N_INSNS (40), /* DDBR */
095798e3 184 COSTS_N_INSNS (26), /* DEBR */
3f074425 185 COSTS_N_INSNS (176), /* DLGR */
186 COSTS_N_INSNS (31), /* DLR */
187 COSTS_N_INSNS (31), /* DR */
188 COSTS_N_INSNS (31), /* DSGFR */
189 COSTS_N_INSNS (31), /* DSGR */
18925d38 190};
191
163277cf 192static const
ffead1ca 193struct processor_costs z9_109_cost =
163277cf 194{
195 COSTS_N_INSNS (4), /* M */
196 COSTS_N_INSNS (2), /* MGHI */
197 COSTS_N_INSNS (2), /* MH */
198 COSTS_N_INSNS (2), /* MHI */
199 COSTS_N_INSNS (4), /* ML */
200 COSTS_N_INSNS (4), /* MR */
201 COSTS_N_INSNS (5), /* MS */
202 COSTS_N_INSNS (6), /* MSG */
203 COSTS_N_INSNS (4), /* MSGF */
204 COSTS_N_INSNS (4), /* MSGFR */
205 COSTS_N_INSNS (4), /* MSGR */
206 COSTS_N_INSNS (4), /* MSR */
207 COSTS_N_INSNS (1), /* multiplication in DFmode */
429f9fdb 208 COSTS_N_INSNS (28), /* MXBR */
209 COSTS_N_INSNS (130), /* SQXBR */
163277cf 210 COSTS_N_INSNS (66), /* SQDBR */
211 COSTS_N_INSNS (38), /* SQEBR */
212 COSTS_N_INSNS (1), /* MADBR */
213 COSTS_N_INSNS (1), /* MAEBR */
429f9fdb 214 COSTS_N_INSNS (60), /* DXBR */
163277cf 215 COSTS_N_INSNS (40), /* DDBR */
095798e3 216 COSTS_N_INSNS (26), /* DEBR */
163277cf 217 COSTS_N_INSNS (30), /* DLGR */
218 COSTS_N_INSNS (23), /* DLR */
219 COSTS_N_INSNS (23), /* DR */
220 COSTS_N_INSNS (24), /* DSGFR */
221 COSTS_N_INSNS (24), /* DSGR */
222};
18925d38 223
a850370e 224static const
225struct processor_costs z10_cost =
226{
510c2327 227 COSTS_N_INSNS (10), /* M */
228 COSTS_N_INSNS (10), /* MGHI */
229 COSTS_N_INSNS (10), /* MH */
230 COSTS_N_INSNS (10), /* MHI */
231 COSTS_N_INSNS (10), /* ML */
232 COSTS_N_INSNS (10), /* MR */
233 COSTS_N_INSNS (10), /* MS */
234 COSTS_N_INSNS (10), /* MSG */
235 COSTS_N_INSNS (10), /* MSGF */
236 COSTS_N_INSNS (10), /* MSGFR */
237 COSTS_N_INSNS (10), /* MSGR */
238 COSTS_N_INSNS (10), /* MSR */
b0eacf26 239 COSTS_N_INSNS (1) , /* multiplication in DFmode */
510c2327 240 COSTS_N_INSNS (50), /* MXBR */
241 COSTS_N_INSNS (120), /* SQXBR */
242 COSTS_N_INSNS (52), /* SQDBR */
a850370e 243 COSTS_N_INSNS (38), /* SQEBR */
b0eacf26 244 COSTS_N_INSNS (1), /* MADBR */
245 COSTS_N_INSNS (1), /* MAEBR */
510c2327 246 COSTS_N_INSNS (111), /* DXBR */
247 COSTS_N_INSNS (39), /* DDBR */
248 COSTS_N_INSNS (32), /* DEBR */
249 COSTS_N_INSNS (160), /* DLGR */
250 COSTS_N_INSNS (71), /* DLR */
251 COSTS_N_INSNS (71), /* DR */
252 COSTS_N_INSNS (71), /* DSGFR */
253 COSTS_N_INSNS (71), /* DSGR */
a850370e 254};
255
33d033da 256static const
257struct processor_costs z196_cost =
258{
259 COSTS_N_INSNS (7), /* M */
260 COSTS_N_INSNS (5), /* MGHI */
261 COSTS_N_INSNS (5), /* MH */
262 COSTS_N_INSNS (5), /* MHI */
263 COSTS_N_INSNS (7), /* ML */
264 COSTS_N_INSNS (7), /* MR */
265 COSTS_N_INSNS (6), /* MS */
266 COSTS_N_INSNS (8), /* MSG */
267 COSTS_N_INSNS (6), /* MSGF */
268 COSTS_N_INSNS (6), /* MSGFR */
269 COSTS_N_INSNS (8), /* MSGR */
270 COSTS_N_INSNS (6), /* MSR */
271 COSTS_N_INSNS (1) , /* multiplication in DFmode */
272 COSTS_N_INSNS (40), /* MXBR B+40 */
273 COSTS_N_INSNS (100), /* SQXBR B+100 */
274 COSTS_N_INSNS (42), /* SQDBR B+42 */
275 COSTS_N_INSNS (28), /* SQEBR B+28 */
276 COSTS_N_INSNS (1), /* MADBR B */
277 COSTS_N_INSNS (1), /* MAEBR B */
278 COSTS_N_INSNS (101), /* DXBR B+101 */
279 COSTS_N_INSNS (29), /* DDBR */
280 COSTS_N_INSNS (22), /* DEBR */
281 COSTS_N_INSNS (160), /* DLGR cracked */
282 COSTS_N_INSNS (160), /* DLR cracked */
283 COSTS_N_INSNS (160), /* DR expanded */
284 COSTS_N_INSNS (160), /* DSGFR cracked */
285 COSTS_N_INSNS (160), /* DSGR cracked */
286};
287
81769881 288static const
289struct processor_costs zEC12_cost =
290{
291 COSTS_N_INSNS (7), /* M */
292 COSTS_N_INSNS (5), /* MGHI */
293 COSTS_N_INSNS (5), /* MH */
294 COSTS_N_INSNS (5), /* MHI */
295 COSTS_N_INSNS (7), /* ML */
296 COSTS_N_INSNS (7), /* MR */
297 COSTS_N_INSNS (6), /* MS */
298 COSTS_N_INSNS (8), /* MSG */
299 COSTS_N_INSNS (6), /* MSGF */
300 COSTS_N_INSNS (6), /* MSGFR */
301 COSTS_N_INSNS (8), /* MSGR */
302 COSTS_N_INSNS (6), /* MSR */
303 COSTS_N_INSNS (1) , /* multiplication in DFmode */
304 COSTS_N_INSNS (40), /* MXBR B+40 */
305 COSTS_N_INSNS (100), /* SQXBR B+100 */
306 COSTS_N_INSNS (42), /* SQDBR B+42 */
307 COSTS_N_INSNS (28), /* SQEBR B+28 */
308 COSTS_N_INSNS (1), /* MADBR B */
309 COSTS_N_INSNS (1), /* MAEBR B */
310 COSTS_N_INSNS (131), /* DXBR B+131 */
311 COSTS_N_INSNS (29), /* DDBR */
312 COSTS_N_INSNS (22), /* DEBR */
313 COSTS_N_INSNS (160), /* DLGR cracked */
314 COSTS_N_INSNS (160), /* DLR cracked */
315 COSTS_N_INSNS (160), /* DR expanded */
316 COSTS_N_INSNS (160), /* DSGFR cracked */
317 COSTS_N_INSNS (160), /* DSGR cracked */
318};
319
7a0cee35 320static struct
321{
a168a775 322 /* The preferred name to be used in user visible output. */
7a0cee35 323 const char *const name;
a168a775 324 /* CPU name as it should be passed to Binutils via .machine */
325 const char *const binutils_name;
7a0cee35 326 const enum processor_type processor;
327 const struct processor_costs *cost;
328}
329const processor_table[] =
330{
a168a775 331 { "g5", "g5", PROCESSOR_9672_G5, &z900_cost },
332 { "g6", "g6", PROCESSOR_9672_G6, &z900_cost },
333 { "z900", "z900", PROCESSOR_2064_Z900, &z900_cost },
334 { "z990", "z990", PROCESSOR_2084_Z990, &z990_cost },
335 { "z9-109", "z9-109", PROCESSOR_2094_Z9_109, &z9_109_cost },
336 { "z9-ec", "z9-ec", PROCESSOR_2094_Z9_EC, &z9_109_cost },
337 { "z10", "z10", PROCESSOR_2097_Z10, &z10_cost },
338 { "z196", "z196", PROCESSOR_2817_Z196, &z196_cost },
339 { "zEC12", "zEC12", PROCESSOR_2827_ZEC12, &zEC12_cost },
340 { "z13", "z13", PROCESSOR_2964_Z13, &zEC12_cost },
341 { "z14", "arch12", PROCESSOR_3906_Z14, &zEC12_cost },
342 { "native", "", PROCESSOR_NATIVE, NULL }
7a0cee35 343};
344
4673c1a0 345extern int reload_completed;
346
8a2a84e3 347/* Kept up to date using the SCHED_VARIABLE_ISSUE hook. */
93e0956b 348static rtx_insn *last_scheduled_insn;
0cb69051 349#define MAX_SCHED_UNITS 3
350static int last_scheduled_unit_distance[MAX_SCHED_UNITS];
351
352/* The maximum score added for an instruction whose unit hasn't been
353 in use for MAX_SCHED_MIX_DISTANCE steps. Increase this value to
354 give instruction mix scheduling more priority over instruction
355 grouping. */
356#define MAX_SCHED_MIX_SCORE 8
357
358/* The maximum distance up to which individual scores will be
359 calculated. Everything beyond this gives MAX_SCHED_MIX_SCORE.
360 Increase this with the OOO windows size of the machine. */
361#define MAX_SCHED_MIX_DISTANCE 100
8a2a84e3 362
56769981 363/* Structure used to hold the components of a S/390 memory
364 address. A legitimate address on S/390 is of the general
365 form
366 base + index + displacement
367 where any of the components is optional.
368
369 base and index are registers of the class ADDR_REGS,
370 displacement is an unsigned 12-bit immediate constant. */
4673c1a0 371
372struct s390_address
373{
374 rtx base;
375 rtx indx;
376 rtx disp;
e5537457 377 bool pointer;
05b58257 378 bool literal_pool;
4673c1a0 379};
380
ffead1ca 381/* The following structure is embedded in the machine
67928721 382 specific part of struct function. */
383
fb1e4f4a 384struct GTY (()) s390_frame_layout
67928721 385{
386 /* Offset within stack frame. */
387 HOST_WIDE_INT gprs_offset;
388 HOST_WIDE_INT f0_offset;
389 HOST_WIDE_INT f4_offset;
390 HOST_WIDE_INT f8_offset;
391 HOST_WIDE_INT backchain_offset;
5214e6ae 392
393 /* Number of first and last gpr where slots in the register
394 save area are reserved for. */
395 int first_save_gpr_slot;
396 int last_save_gpr_slot;
397
ff4ce128 398 /* Location (FP register number) where GPRs (r0-r15) should
399 be saved to.
400 0 - does not need to be saved at all
401 -1 - stack slot */
1d3cea74 402#define SAVE_SLOT_NONE 0
403#define SAVE_SLOT_STACK -1
ff4ce128 404 signed char gpr_save_slots[16];
405
5a5e802f 406 /* Number of first and last gpr to be saved, restored. */
8b4a4127 407 int first_save_gpr;
408 int first_restore_gpr;
409 int last_save_gpr;
beee1f75 410 int last_restore_gpr;
8b4a4127 411
ffead1ca 412 /* Bits standing for floating point registers. Set, if the
413 respective register has to be saved. Starting with reg 16 (f0)
67928721 414 at the rightmost bit.
6a2469fe 415 Bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
416 fpr 15 13 11 9 14 12 10 8 7 5 3 1 6 4 2 0
417 reg 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 */
67928721 418 unsigned int fpr_bitmap;
419
420 /* Number of floating point registers f8-f15 which must be saved. */
421 int high_fprs;
422
9bee2845 423 /* Set if return address needs to be saved.
424 This flag is set by s390_return_addr_rtx if it could not use
425 the initial value of r14 and therefore depends on r14 saved
426 to the stack. */
67928721 427 bool save_return_addr_p;
428
5a5e802f 429 /* Size of stack frame. */
8b4a4127 430 HOST_WIDE_INT frame_size;
67928721 431};
432
433/* Define the structure for the machine field in struct function. */
434
fb1e4f4a 435struct GTY(()) machine_function
67928721 436{
437 struct s390_frame_layout frame_layout;
be00aaa8 438
20074f87 439 /* Literal pool base register. */
440 rtx base_reg;
441
4fed3f99 442 /* True if we may need to perform branch splitting. */
443 bool split_branches_pending_p;
444
1e639cb0 445 bool has_landing_pad_p;
5ada7a14 446
447 /* True if the current function may contain a tbegin clobbering
448 FPRs. */
449 bool tbegin_p;
c6d481f7 450
451 /* For -fsplit-stack support: A stack local which holds a pointer to
452 the stack arguments for a function with a variable number of
453 arguments. This is set at the start of the function and is used
454 to initialize the overflow_arg_area field of the va_list
455 structure. */
456 rtx split_stack_varargs_pointer;
8b4a4127 457};
458
67928721 459/* Few accessor macros for struct cfun->machine->s390_frame_layout. */
460
461#define cfun_frame_layout (cfun->machine->frame_layout)
462#define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)
ff4ce128 463#define cfun_save_arg_fprs_p (!!(TARGET_64BIT \
464 ? cfun_frame_layout.fpr_bitmap & 0x0f \
465 : cfun_frame_layout.fpr_bitmap & 0x03))
466#define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr_slot - \
b5fdc416 467 cfun_frame_layout.first_save_gpr_slot + 1) * UNITS_PER_LONG)
29439367 468#define cfun_set_fpr_save(REGNO) (cfun->machine->frame_layout.fpr_bitmap |= \
6a2469fe 469 (1 << (REGNO - FPR0_REGNUM)))
29439367 470#define cfun_fpr_save_p(REGNO) (!!(cfun->machine->frame_layout.fpr_bitmap & \
6a2469fe 471 (1 << (REGNO - FPR0_REGNUM))))
ff4ce128 472#define cfun_gpr_save_slot(REGNO) \
473 cfun->machine->frame_layout.gpr_save_slots[REGNO]
67928721 474
6902d973 475/* Number of GPRs and FPRs used for argument passing. */
476#define GP_ARG_NUM_REG 5
477#define FP_ARG_NUM_REG (TARGET_64BIT? 4 : 2)
76a4c804 478#define VEC_ARG_NUM_REG 8
6902d973 479
cb888f33 480/* A couple of shortcuts. */
481#define CONST_OK_FOR_J(x) \
482 CONST_OK_FOR_CONSTRAINT_P((x), 'J', "J")
483#define CONST_OK_FOR_K(x) \
484 CONST_OK_FOR_CONSTRAINT_P((x), 'K', "K")
163277cf 485#define CONST_OK_FOR_Os(x) \
486 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Os")
487#define CONST_OK_FOR_Op(x) \
488 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Op")
489#define CONST_OK_FOR_On(x) \
490 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "On")
cb888f33 491
8f1128bb 492#define REGNO_PAIR_OK(REGNO, MODE) \
493 (HARD_REGNO_NREGS ((REGNO), (MODE)) == 1 || !((REGNO) & 1))
494
73df8a45 495/* That's the read ahead of the dynamic branch prediction unit in
33d033da 496 bytes on a z10 (or higher) CPU. */
497#define PREDICT_DISTANCE (TARGET_Z10 ? 384 : 2048)
73df8a45 498
07f32359 499
6b7cfb9c 500/* Indicate which ABI has been used for passing vector args.
501 0 - no vector type arguments have been passed where the ABI is relevant
502 1 - the old ABI has been used
503 2 - a vector type argument has been passed either in a vector register
504 or on the stack by value */
505static int s390_vector_abi = 0;
506
507/* Set the vector ABI marker if TYPE is subject to the vector ABI
508 switch. The vector ABI affects only vector data types. There are
509 two aspects of the vector ABI relevant here:
510
511 1. vectors >= 16 bytes have an alignment of 8 bytes with the new
512 ABI and natural alignment with the old.
513
514 2. vector <= 16 bytes are passed in VRs or by value on the stack
515 with the new ABI but by reference on the stack with the old.
516
517 If ARG_P is true TYPE is used for a function argument or return
518 value. The ABI marker then is set for all vector data types. If
519 ARG_P is false only type 1 vectors are being checked. */
520
521static void
522s390_check_type_for_vector_abi (const_tree type, bool arg_p, bool in_struct_p)
523{
524 static hash_set<const_tree> visited_types_hash;
525
526 if (s390_vector_abi)
527 return;
528
529 if (type == NULL_TREE || TREE_CODE (type) == ERROR_MARK)
530 return;
531
532 if (visited_types_hash.contains (type))
533 return;
534
535 visited_types_hash.add (type);
536
537 if (VECTOR_TYPE_P (type))
538 {
539 int type_size = int_size_in_bytes (type);
540
541 /* Outside arguments only the alignment is changing and this
542 only happens for vector types >= 16 bytes. */
543 if (!arg_p && type_size < 16)
544 return;
545
546 /* In arguments vector types > 16 are passed as before (GCC
547 never enforced the bigger alignment for arguments which was
548 required by the old vector ABI). However, it might still be
549 ABI relevant due to the changed alignment if it is a struct
550 member. */
551 if (arg_p && type_size > 16 && !in_struct_p)
552 return;
553
554 s390_vector_abi = TARGET_VX_ABI ? 2 : 1;
555 }
556 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
557 {
558 /* ARRAY_TYPE: Since with neither of the ABIs we have more than
559 natural alignment there will never be ABI dependent padding
560 in an array type. That's why we do not set in_struct_p to
561 true here. */
562 s390_check_type_for_vector_abi (TREE_TYPE (type), arg_p, in_struct_p);
563 }
564 else if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE)
565 {
566 tree arg_chain;
567
568 /* Check the return type. */
569 s390_check_type_for_vector_abi (TREE_TYPE (type), true, false);
570
571 for (arg_chain = TYPE_ARG_TYPES (type);
572 arg_chain;
573 arg_chain = TREE_CHAIN (arg_chain))
574 s390_check_type_for_vector_abi (TREE_VALUE (arg_chain), true, false);
575 }
576 else if (RECORD_OR_UNION_TYPE_P (type))
577 {
578 tree field;
579
580 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
581 {
582 if (TREE_CODE (field) != FIELD_DECL)
583 continue;
584
585 s390_check_type_for_vector_abi (TREE_TYPE (field), arg_p, true);
586 }
587 }
588}
589
590
07f32359 591/* System z builtins. */
592
593#include "s390-builtins.h"
594
a8aefbef 595const unsigned int bflags_builtin[S390_BUILTIN_MAX + 1] =
07f32359 596 {
597#undef B_DEF
598#undef OB_DEF
599#undef OB_DEF_VAR
a8aefbef 600#define B_DEF(NAME, PATTERN, ATTRS, BFLAGS, ...) BFLAGS,
07f32359 601#define OB_DEF(...)
602#define OB_DEF_VAR(...)
603#include "s390-builtins.def"
604 0
605 };
606
a8aefbef 607const unsigned int opflags_builtin[S390_BUILTIN_MAX + 1] =
608 {
609#undef B_DEF
610#undef OB_DEF
611#undef OB_DEF_VAR
612#define B_DEF(NAME, PATTERN, ATTRS, BFLAGS, OPFLAGS, ...) OPFLAGS,
613#define OB_DEF(...)
614#define OB_DEF_VAR(...)
615#include "s390-builtins.def"
616 0
617 };
618
619const unsigned int bflags_overloaded_builtin[S390_OVERLOADED_BUILTIN_MAX + 1] =
620 {
621#undef B_DEF
622#undef OB_DEF
623#undef OB_DEF_VAR
624#define B_DEF(...)
625#define OB_DEF(NAME, FIRST_VAR_NAME, LAST_VAR_NAME, BFLAGS, ...) BFLAGS,
626#define OB_DEF_VAR(...)
627#include "s390-builtins.def"
628 0
629 };
630
063ed3cf 631const unsigned int
632bflags_overloaded_builtin_var[S390_OVERLOADED_BUILTIN_VAR_MAX + 1] =
633 {
634#undef B_DEF
635#undef OB_DEF
636#undef OB_DEF_VAR
637#define B_DEF(...)
638#define OB_DEF(...)
639#define OB_DEF_VAR(NAME, PATTERN, FLAGS, OPFLAGS, FNTYPE) FLAGS,
640#include "s390-builtins.def"
641 0
642 };
643
a8aefbef 644const unsigned int
645opflags_overloaded_builtin_var[S390_OVERLOADED_BUILTIN_VAR_MAX + 1] =
07f32359 646 {
647#undef B_DEF
648#undef OB_DEF
649#undef OB_DEF_VAR
650#define B_DEF(...)
651#define OB_DEF(...)
063ed3cf 652#define OB_DEF_VAR(NAME, PATTERN, FLAGS, OPFLAGS, FNTYPE) OPFLAGS,
07f32359 653#include "s390-builtins.def"
654 0
655 };
656
657tree s390_builtin_types[BT_MAX];
658tree s390_builtin_fn_types[BT_FN_MAX];
659tree s390_builtin_decls[S390_BUILTIN_MAX +
660 S390_OVERLOADED_BUILTIN_MAX +
661 S390_OVERLOADED_BUILTIN_VAR_MAX];
662
663static enum insn_code const code_for_builtin[S390_BUILTIN_MAX + 1] = {
664#undef B_DEF
665#undef OB_DEF
666#undef OB_DEF_VAR
667#define B_DEF(NAME, PATTERN, ...) CODE_FOR_##PATTERN,
668#define OB_DEF(...)
669#define OB_DEF_VAR(...)
670
671#include "s390-builtins.def"
672 CODE_FOR_nothing
673};
674
675static void
676s390_init_builtins (void)
677{
678 /* These definitions are being used in s390-builtins.def. */
679 tree returns_twice_attr = tree_cons (get_identifier ("returns_twice"),
680 NULL, NULL);
681 tree noreturn_attr = tree_cons (get_identifier ("noreturn"), NULL, NULL);
682 tree c_uint64_type_node;
683
684 /* The uint64_type_node from tree.c is not compatible to the C99
685 uint64_t data type. What we want is c_uint64_type_node from
686 c-common.c. But since backend code is not supposed to interface
687 with the frontend we recreate it here. */
688 if (TARGET_64BIT)
689 c_uint64_type_node = long_unsigned_type_node;
690 else
691 c_uint64_type_node = long_long_unsigned_type_node;
692
693#undef DEF_TYPE
f9378734 694#define DEF_TYPE(INDEX, NODE, CONST_P) \
7a0cee35 695 if (s390_builtin_types[INDEX] == NULL) \
a8aefbef 696 s390_builtin_types[INDEX] = (!CONST_P) ? \
697 (NODE) : build_type_variant ((NODE), 1, 0);
07f32359 698
699#undef DEF_POINTER_TYPE
f9378734 700#define DEF_POINTER_TYPE(INDEX, INDEX_BASE) \
7a0cee35 701 if (s390_builtin_types[INDEX] == NULL) \
a8aefbef 702 s390_builtin_types[INDEX] = \
703 build_pointer_type (s390_builtin_types[INDEX_BASE]);
07f32359 704
705#undef DEF_DISTINCT_TYPE
f9378734 706#define DEF_DISTINCT_TYPE(INDEX, INDEX_BASE) \
7a0cee35 707 if (s390_builtin_types[INDEX] == NULL) \
a8aefbef 708 s390_builtin_types[INDEX] = \
709 build_distinct_type_copy (s390_builtin_types[INDEX_BASE]);
07f32359 710
711#undef DEF_VECTOR_TYPE
f9378734 712#define DEF_VECTOR_TYPE(INDEX, INDEX_BASE, ELEMENTS) \
7a0cee35 713 if (s390_builtin_types[INDEX] == NULL) \
a8aefbef 714 s390_builtin_types[INDEX] = \
715 build_vector_type (s390_builtin_types[INDEX_BASE], ELEMENTS);
07f32359 716
717#undef DEF_OPAQUE_VECTOR_TYPE
f9378734 718#define DEF_OPAQUE_VECTOR_TYPE(INDEX, INDEX_BASE, ELEMENTS) \
7a0cee35 719 if (s390_builtin_types[INDEX] == NULL) \
a8aefbef 720 s390_builtin_types[INDEX] = \
721 build_opaque_vector_type (s390_builtin_types[INDEX_BASE], ELEMENTS);
07f32359 722
723#undef DEF_FN_TYPE
f9378734 724#define DEF_FN_TYPE(INDEX, args...) \
7a0cee35 725 if (s390_builtin_fn_types[INDEX] == NULL) \
a8aefbef 726 s390_builtin_fn_types[INDEX] = \
7a0cee35 727 build_function_type_list (args, NULL_TREE);
07f32359 728#undef DEF_OV_TYPE
729#define DEF_OV_TYPE(...)
730#include "s390-builtin-types.def"
731
732#undef B_DEF
a8aefbef 733#define B_DEF(NAME, PATTERN, ATTRS, BFLAGS, OPFLAGS, FNTYPE) \
7a0cee35 734 if (s390_builtin_decls[S390_BUILTIN_##NAME] == NULL) \
a8aefbef 735 s390_builtin_decls[S390_BUILTIN_##NAME] = \
736 add_builtin_function ("__builtin_" #NAME, \
737 s390_builtin_fn_types[FNTYPE], \
738 S390_BUILTIN_##NAME, \
739 BUILT_IN_MD, \
740 NULL, \
741 ATTRS);
07f32359 742#undef OB_DEF
a8aefbef 743#define OB_DEF(NAME, FIRST_VAR_NAME, LAST_VAR_NAME, BFLAGS, FNTYPE) \
7a0cee35 744 if (s390_builtin_decls[S390_OVERLOADED_BUILTIN_##NAME + S390_BUILTIN_MAX] \
745 == NULL) \
a8aefbef 746 s390_builtin_decls[S390_OVERLOADED_BUILTIN_##NAME + S390_BUILTIN_MAX] = \
747 add_builtin_function ("__builtin_" #NAME, \
748 s390_builtin_fn_types[FNTYPE], \
749 S390_OVERLOADED_BUILTIN_##NAME + S390_BUILTIN_MAX, \
750 BUILT_IN_MD, \
751 NULL, \
752 0);
07f32359 753#undef OB_DEF_VAR
754#define OB_DEF_VAR(...)
755#include "s390-builtins.def"
756
757}
758
759/* Return true if ARG is appropriate as argument number ARGNUM of
760 builtin DECL. The operand flags from s390-builtins.def have to
761 passed as OP_FLAGS. */
762bool
763s390_const_operand_ok (tree arg, int argnum, int op_flags, tree decl)
764{
765 if (O_UIMM_P (op_flags))
766 {
767 int bitwidths[] = { 1, 2, 3, 4, 5, 8, 12, 16, 32 };
768 int bitwidth = bitwidths[op_flags - O_U1];
769
770 if (!tree_fits_uhwi_p (arg)
b422d8c0 771 || tree_to_uhwi (arg) > (HOST_WIDE_INT_1U << bitwidth) - 1)
07f32359 772 {
773 error("constant argument %d for builtin %qF is out of range (0.."
774 HOST_WIDE_INT_PRINT_UNSIGNED ")",
775 argnum, decl,
b422d8c0 776 (HOST_WIDE_INT_1U << bitwidth) - 1);
07f32359 777 return false;
778 }
779 }
780
781 if (O_SIMM_P (op_flags))
782 {
783 int bitwidths[] = { 2, 3, 4, 5, 8, 12, 16, 32 };
784 int bitwidth = bitwidths[op_flags - O_S2];
785
786 if (!tree_fits_shwi_p (arg)
b422d8c0 787 || tree_to_shwi (arg) < -(HOST_WIDE_INT_1 << (bitwidth - 1))
788 || tree_to_shwi (arg) > ((HOST_WIDE_INT_1 << (bitwidth - 1)) - 1))
07f32359 789 {
790 error("constant argument %d for builtin %qF is out of range ("
791 HOST_WIDE_INT_PRINT_DEC ".."
792 HOST_WIDE_INT_PRINT_DEC ")",
793 argnum, decl,
b422d8c0 794 -(HOST_WIDE_INT_1 << (bitwidth - 1)),
795 (HOST_WIDE_INT_1 << (bitwidth - 1)) - 1);
07f32359 796 return false;
797 }
798 }
799 return true;
800}
801
802/* Expand an expression EXP that calls a built-in function,
803 with result going to TARGET if that's convenient
804 (and in mode MODE if that's convenient).
805 SUBTARGET may be used as the target for computing one of EXP's operands.
806 IGNORE is nonzero if the value is to be ignored. */
807
808static rtx
809s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
810 machine_mode mode ATTRIBUTE_UNUSED,
811 int ignore ATTRIBUTE_UNUSED)
812{
674b3578 813#define MAX_ARGS 6
07f32359 814
815 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
816 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
817 enum insn_code icode;
818 rtx op[MAX_ARGS], pat;
819 int arity;
820 bool nonvoid;
821 tree arg;
822 call_expr_arg_iterator iter;
a8aefbef 823 unsigned int all_op_flags = opflags_for_builtin (fcode);
07f32359 824 machine_mode last_vec_mode = VOIDmode;
825
826 if (TARGET_DEBUG_ARG)
827 {
828 fprintf (stderr,
7a0cee35 829 "s390_expand_builtin, code = %4d, %s, bflags = 0x%x\n",
830 (int)fcode, IDENTIFIER_POINTER (DECL_NAME (fndecl)),
831 bflags_for_builtin (fcode));
07f32359 832 }
833
7a0cee35 834 if (S390_USE_TARGET_ATTRIBUTE)
835 {
836 unsigned int bflags;
837
838 bflags = bflags_for_builtin (fcode);
839 if ((bflags & B_HTM) && !TARGET_HTM)
840 {
19abb0ad 841 error ("builtin %qF is not supported without -mhtm "
7a0cee35 842 "(default with -march=zEC12 and higher).", fndecl);
843 return const0_rtx;
844 }
c9213ca0 845 if (((bflags & B_VX) || (bflags & B_VXE)) && !TARGET_VX)
7a0cee35 846 {
063ed3cf 847 error ("builtin %qF requires -mvx "
7a0cee35 848 "(default with -march=z13 and higher).", fndecl);
849 return const0_rtx;
850 }
c9213ca0 851
852 if ((bflags & B_VXE) && !TARGET_VXE)
853 {
a168a775 854 error ("Builtin %qF requires z14 or higher.", fndecl);
c9213ca0 855 return const0_rtx;
856 }
7a0cee35 857 }
07f32359 858 if (fcode >= S390_OVERLOADED_BUILTIN_VAR_OFFSET
859 && fcode < S390_ALL_BUILTIN_MAX)
860 {
861 gcc_unreachable ();
862 }
863 else if (fcode < S390_OVERLOADED_BUILTIN_OFFSET)
864 {
865 icode = code_for_builtin[fcode];
866 /* Set a flag in the machine specific cfun part in order to support
867 saving/restoring of FPRs. */
868 if (fcode == S390_BUILTIN_tbegin || fcode == S390_BUILTIN_tbegin_retry)
869 cfun->machine->tbegin_p = true;
870 }
871 else if (fcode < S390_OVERLOADED_BUILTIN_VAR_OFFSET)
872 {
19abb0ad 873 error ("unresolved overloaded builtin");
07f32359 874 return const0_rtx;
875 }
876 else
877 internal_error ("bad builtin fcode");
878
879 if (icode == 0)
880 internal_error ("bad builtin icode");
881
882 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
883
884 if (nonvoid)
885 {
886 machine_mode tmode = insn_data[icode].operand[0].mode;
887 if (!target
888 || GET_MODE (target) != tmode
889 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
890 target = gen_reg_rtx (tmode);
891
892 /* There are builtins (e.g. vec_promote) with no vector
893 arguments but an element selector. So we have to also look
894 at the vector return type when emitting the modulo
895 operation. */
896 if (VECTOR_MODE_P (insn_data[icode].operand[0].mode))
897 last_vec_mode = insn_data[icode].operand[0].mode;
898 }
899
900 arity = 0;
901 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
902 {
b0c401ca 903 rtx tmp_rtx;
07f32359 904 const struct insn_operand_data *insn_op;
905 unsigned int op_flags = all_op_flags & ((1 << O_SHIFT) - 1);
906
907 all_op_flags = all_op_flags >> O_SHIFT;
908
909 if (arg == error_mark_node)
910 return NULL_RTX;
911 if (arity >= MAX_ARGS)
912 return NULL_RTX;
913
914 if (O_IMM_P (op_flags)
915 && TREE_CODE (arg) != INTEGER_CST)
916 {
917 error ("constant value required for builtin %qF argument %d",
918 fndecl, arity + 1);
919 return const0_rtx;
920 }
921
922 if (!s390_const_operand_ok (arg, arity + 1, op_flags, fndecl))
923 return const0_rtx;
924
925 insn_op = &insn_data[icode].operand[arity + nonvoid];
926 op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, EXPAND_NORMAL);
927
0570ddf1 928 /* expand_expr truncates constants to the target mode only if it
929 is "convenient". However, our checks below rely on this
930 being done. */
931 if (CONST_INT_P (op[arity])
932 && SCALAR_INT_MODE_P (insn_op->mode)
933 && GET_MODE (op[arity]) != insn_op->mode)
934 op[arity] = GEN_INT (trunc_int_for_mode (INTVAL (op[arity]),
935 insn_op->mode));
936
07f32359 937 /* Wrap the expanded RTX for pointer types into a MEM expr with
938 the proper mode. This allows us to use e.g. (match_operand
939 "memory_operand"..) in the insn patterns instead of (mem
940 (match_operand "address_operand)). This is helpful for
941 patterns not just accepting MEMs. */
942 if (POINTER_TYPE_P (TREE_TYPE (arg))
943 && insn_op->predicate != address_operand)
944 op[arity] = gen_rtx_MEM (insn_op->mode, op[arity]);
945
946 /* Expand the module operation required on element selectors. */
947 if (op_flags == O_ELEM)
948 {
949 gcc_assert (last_vec_mode != VOIDmode);
950 op[arity] = simplify_expand_binop (SImode, code_to_optab (AND),
951 op[arity],
952 GEN_INT (GET_MODE_NUNITS (last_vec_mode) - 1),
953 NULL_RTX, 1, OPTAB_DIRECT);
954 }
955
956 /* Record the vector mode used for an element selector. This assumes:
957 1. There is no builtin with two different vector modes and an element selector
958 2. The element selector comes after the vector type it is referring to.
959 This currently the true for all the builtins but FIXME we
960 should better check for that. */
961 if (VECTOR_MODE_P (insn_op->mode))
962 last_vec_mode = insn_op->mode;
963
964 if (insn_op->predicate (op[arity], insn_op->mode))
965 {
966 arity++;
967 continue;
968 }
969
970 if (MEM_P (op[arity])
971 && insn_op->predicate == memory_operand
972 && (GET_MODE (XEXP (op[arity], 0)) == Pmode
973 || GET_MODE (XEXP (op[arity], 0)) == VOIDmode))
974 {
975 op[arity] = replace_equiv_address (op[arity],
976 copy_to_mode_reg (Pmode,
977 XEXP (op[arity], 0)));
978 }
b0c401ca 979 /* Some of the builtins require different modes/types than the
980 pattern in order to implement a specific API. Instead of
981 adding many expanders which do the mode change we do it here.
982 E.g. s390_vec_add_u128 required to have vector unsigned char
983 arguments is mapped to addti3. */
984 else if (insn_op->mode != VOIDmode
985 && GET_MODE (op[arity]) != VOIDmode
986 && GET_MODE (op[arity]) != insn_op->mode
987 && ((tmp_rtx = simplify_gen_subreg (insn_op->mode, op[arity],
988 GET_MODE (op[arity]), 0))
989 != NULL_RTX))
990 {
991 op[arity] = tmp_rtx;
992 }
07f32359 993 else if (GET_MODE (op[arity]) == insn_op->mode
994 || GET_MODE (op[arity]) == VOIDmode
995 || (insn_op->predicate == address_operand
996 && GET_MODE (op[arity]) == Pmode))
997 {
998 /* An address_operand usually has VOIDmode in the expander
999 so we cannot use this. */
1000 machine_mode target_mode =
1001 (insn_op->predicate == address_operand
1002 ? Pmode : insn_op->mode);
1003 op[arity] = copy_to_mode_reg (target_mode, op[arity]);
1004 }
1005
1006 if (!insn_op->predicate (op[arity], insn_op->mode))
1007 {
19abb0ad 1008 error ("invalid argument %d for builtin %qF", arity + 1, fndecl);
07f32359 1009 return const0_rtx;
1010 }
1011 arity++;
1012 }
1013
07f32359 1014 switch (arity)
1015 {
1016 case 0:
1017 pat = GEN_FCN (icode) (target);
1018 break;
1019 case 1:
1020 if (nonvoid)
1021 pat = GEN_FCN (icode) (target, op[0]);
1022 else
1023 pat = GEN_FCN (icode) (op[0]);
1024 break;
1025 case 2:
1026 if (nonvoid)
1027 pat = GEN_FCN (icode) (target, op[0], op[1]);
1028 else
1029 pat = GEN_FCN (icode) (op[0], op[1]);
1030 break;
1031 case 3:
1032 if (nonvoid)
1033 pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
1034 else
1035 pat = GEN_FCN (icode) (op[0], op[1], op[2]);
1036 break;
1037 case 4:
1038 if (nonvoid)
1039 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
1040 else
1041 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
1042 break;
1043 case 5:
1044 if (nonvoid)
1045 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3], op[4]);
1046 else
1047 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4]);
1048 break;
1049 case 6:
1050 if (nonvoid)
1051 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3], op[4], op[5]);
1052 else
1053 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5]);
1054 break;
1055 default:
1056 gcc_unreachable ();
1057 }
1058 if (!pat)
1059 return NULL_RTX;
1060 emit_insn (pat);
1061
1062 if (nonvoid)
1063 return target;
1064 else
1065 return const0_rtx;
1066}
1067
1068
11762b83 1069static const int s390_hotpatch_hw_max = 1000000;
1070static int s390_hotpatch_hw_before_label = 0;
1071static int s390_hotpatch_hw_after_label = 0;
77bc9912 1072
1073/* Check whether the hotpatch attribute is applied to a function and, if it has
1074 an argument, the argument is valid. */
1075
1076static tree
1077s390_handle_hotpatch_attribute (tree *node, tree name, tree args,
1078 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
1079{
11762b83 1080 tree expr;
1081 tree expr2;
1082 int err;
1083
77bc9912 1084 if (TREE_CODE (*node) != FUNCTION_DECL)
1085 {
1086 warning (OPT_Wattributes, "%qE attribute only applies to functions",
1087 name);
1088 *no_add_attrs = true;
1089 }
11762b83 1090 if (args != NULL && TREE_CHAIN (args) != NULL)
1091 {
1092 expr = TREE_VALUE (args);
1093 expr2 = TREE_VALUE (TREE_CHAIN (args));
1094 }
1095 if (args == NULL || TREE_CHAIN (args) == NULL)
1096 err = 1;
1097 else if (TREE_CODE (expr) != INTEGER_CST
1098 || !INTEGRAL_TYPE_P (TREE_TYPE (expr))
1099 || wi::gtu_p (expr, s390_hotpatch_hw_max))
1100 err = 1;
1101 else if (TREE_CODE (expr2) != INTEGER_CST
1102 || !INTEGRAL_TYPE_P (TREE_TYPE (expr2))
1103 || wi::gtu_p (expr2, s390_hotpatch_hw_max))
1104 err = 1;
1105 else
1106 err = 0;
1107 if (err)
77bc9912 1108 {
11762b83 1109 error ("requested %qE attribute is not a comma separated pair of"
1110 " non-negative integer constants or too large (max. %d)", name,
1111 s390_hotpatch_hw_max);
1112 *no_add_attrs = true;
77bc9912 1113 }
1114
1115 return NULL_TREE;
1116}
1117
07f32359 1118/* Expand the s390_vector_bool type attribute. */
1119
1120static tree
1121s390_handle_vectorbool_attribute (tree *node, tree name ATTRIBUTE_UNUSED,
1122 tree args ATTRIBUTE_UNUSED,
1123 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
1124{
1125 tree type = *node, result = NULL_TREE;
1126 machine_mode mode;
1127
1128 while (POINTER_TYPE_P (type)
1129 || TREE_CODE (type) == FUNCTION_TYPE
1130 || TREE_CODE (type) == METHOD_TYPE
1131 || TREE_CODE (type) == ARRAY_TYPE)
1132 type = TREE_TYPE (type);
1133
1134 mode = TYPE_MODE (type);
1135 switch (mode)
1136 {
1137 case DImode: case V2DImode: result = s390_builtin_types[BT_BV2DI]; break;
1138 case SImode: case V4SImode: result = s390_builtin_types[BT_BV4SI]; break;
1139 case HImode: case V8HImode: result = s390_builtin_types[BT_BV8HI]; break;
1140 case QImode: case V16QImode: result = s390_builtin_types[BT_BV16QI];
1141 default: break;
1142 }
1143
1144 *no_add_attrs = true; /* No need to hang on to the attribute. */
1145
1146 if (result)
1147 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
1148
1149 return NULL_TREE;
1150}
1151
77bc9912 1152static const struct attribute_spec s390_attribute_table[] = {
07f32359 1153 { "hotpatch", 2, 2, true, false, false, s390_handle_hotpatch_attribute, false },
1154 { "s390_vector_bool", 0, 0, false, true, false, s390_handle_vectorbool_attribute, true },
77bc9912 1155 /* End element. */
1156 { NULL, 0, 0, false, false, false, NULL, false }
1157};
1158
6d0afa28 1159/* Return the alignment for LABEL. We default to the -falign-labels
1160 value except for the literal pool base label. */
1161int
56d95ea5 1162s390_label_align (rtx_insn *label)
6d0afa28 1163{
50fc2d35 1164 rtx_insn *prev_insn = prev_active_insn (label);
1165 rtx set, src;
6d0afa28 1166
1167 if (prev_insn == NULL_RTX)
1168 goto old;
1169
50fc2d35 1170 set = single_set (prev_insn);
6d0afa28 1171
50fc2d35 1172 if (set == NULL_RTX)
6d0afa28 1173 goto old;
1174
50fc2d35 1175 src = SET_SRC (set);
6d0afa28 1176
1177 /* Don't align literal pool base labels. */
50fc2d35 1178 if (GET_CODE (src) == UNSPEC
1179 && XINT (src, 1) == UNSPEC_MAIN_BASE)
6d0afa28 1180 return 0;
1181
1182 old:
1183 return align_labels_log;
1184}
1185
9852c8ae 1186static GTY(()) rtx got_symbol;
1187
1188/* Return the GOT table symbol. The symbol will be created when the
1189 function is invoked for the first time. */
1190
1191static rtx
1192s390_got_symbol (void)
1193{
1194 if (!got_symbol)
1195 {
1196 got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1197 SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
1198 }
1199
1200 return got_symbol;
1201}
1202
3754d046 1203static machine_mode
0ef89dfd 1204s390_libgcc_cmp_return_mode (void)
1205{
1206 return TARGET_64BIT ? DImode : SImode;
1207}
1208
3754d046 1209static machine_mode
0ef89dfd 1210s390_libgcc_shift_count_mode (void)
1211{
1212 return TARGET_64BIT ? DImode : SImode;
1213}
1214
3754d046 1215static machine_mode
b5fdc416 1216s390_unwind_word_mode (void)
1217{
1218 return TARGET_64BIT ? DImode : SImode;
1219}
1220
36868490 1221/* Return true if the back end supports mode MODE. */
1222static bool
3754d046 1223s390_scalar_mode_supported_p (machine_mode mode)
36868490 1224{
b5fdc416 1225 /* In contrast to the default implementation reject TImode constants on 31bit
1226 TARGET_ZARCH for ABI compliance. */
1227 if (!TARGET_64BIT && TARGET_ZARCH && mode == TImode)
1228 return false;
1229
36868490 1230 if (DECIMAL_FLOAT_MODE_P (mode))
8e72d11d 1231 return default_decimal_float_supported_p ();
b5fdc416 1232
1233 return default_scalar_mode_supported_p (mode);
36868490 1234}
1235
76a4c804 1236/* Return true if the back end supports vector mode MODE. */
1237static bool
1238s390_vector_mode_supported_p (machine_mode mode)
1239{
1240 machine_mode inner;
1241
1242 if (!VECTOR_MODE_P (mode)
1243 || !TARGET_VX
1244 || GET_MODE_SIZE (mode) > 16)
1245 return false;
1246
1247 inner = GET_MODE_INNER (mode);
1248
1249 switch (inner)
1250 {
1251 case QImode:
1252 case HImode:
1253 case SImode:
1254 case DImode:
1255 case TImode:
1256 case SFmode:
1257 case DFmode:
1258 case TFmode:
1259 return true;
1260 default:
1261 return false;
1262 }
1263}
1264
1e639cb0 1265/* Set the has_landing_pad_p flag in struct machine_function to VALUE. */
1266
1267void
1268s390_set_has_landing_pad_p (bool value)
1269{
1270 cfun->machine->has_landing_pad_p = value;
1271}
6902d973 1272
9c93d843 1273/* If two condition code modes are compatible, return a condition code
1274 mode which is compatible with both. Otherwise, return
1275 VOIDmode. */
1276
3754d046 1277static machine_mode
1278s390_cc_modes_compatible (machine_mode m1, machine_mode m2)
9c93d843 1279{
1280 if (m1 == m2)
1281 return m1;
1282
1283 switch (m1)
1284 {
1285 case CCZmode:
1286 if (m2 == CCUmode || m2 == CCTmode || m2 == CCZ1mode
1287 || m2 == CCSmode || m2 == CCSRmode || m2 == CCURmode)
1288 return m2;
1289 return VOIDmode;
1290
1291 case CCSmode:
1292 case CCUmode:
1293 case CCTmode:
1294 case CCSRmode:
1295 case CCURmode:
1296 case CCZ1mode:
1297 if (m2 == CCZmode)
1298 return m1;
ffead1ca 1299
9c93d843 1300 return VOIDmode;
1301
1302 default:
1303 return VOIDmode;
1304 }
1305 return VOIDmode;
1306}
1307
56769981 1308/* Return true if SET either doesn't set the CC register, or else
f81e845f 1309 the source and destination have matching CC modes and that
56769981 1310 CC mode is at least as constrained as REQ_MODE. */
f81e845f 1311
e5537457 1312static bool
3754d046 1313s390_match_ccmode_set (rtx set, machine_mode req_mode)
4673c1a0 1314{
3754d046 1315 machine_mode set_mode;
4673c1a0 1316
32eda510 1317 gcc_assert (GET_CODE (set) == SET);
4673c1a0 1318
abc57c35 1319 /* These modes are supposed to be used only in CC consumer
1320 patterns. */
1321 gcc_assert (req_mode != CCVIALLmode && req_mode != CCVIANYmode
1322 && req_mode != CCVFALLmode && req_mode != CCVFANYmode);
1323
4673c1a0 1324 if (GET_CODE (SET_DEST (set)) != REG || !CC_REGNO_P (REGNO (SET_DEST (set))))
1325 return 1;
1326
1327 set_mode = GET_MODE (SET_DEST (set));
1328 switch (set_mode)
1329 {
d90d26d8 1330 case CCZ1mode:
4673c1a0 1331 case CCSmode:
c6821d1c 1332 case CCSRmode:
4673c1a0 1333 case CCUmode:
c6821d1c 1334 case CCURmode:
2eb8fe23 1335 case CCLmode:
c6821d1c 1336 case CCL1mode:
1337 case CCL2mode:
3b699fc7 1338 case CCL3mode:
c6821d1c 1339 case CCT1mode:
1340 case CCT2mode:
1341 case CCT3mode:
26233f43 1342 case CCVEQmode:
abc57c35 1343 case CCVIHmode:
1344 case CCVIHUmode:
26233f43 1345 case CCVFHmode:
1346 case CCVFHEmode:
c6821d1c 1347 if (req_mode != set_mode)
2eb8fe23 1348 return 0;
1349 break;
c6821d1c 1350
4673c1a0 1351 case CCZmode:
c6821d1c 1352 if (req_mode != CCSmode && req_mode != CCUmode && req_mode != CCTmode
d90d26d8 1353 && req_mode != CCSRmode && req_mode != CCURmode
1354 && req_mode != CCZ1mode)
4673c1a0 1355 return 0;
1356 break;
3c482144 1357
1358 case CCAPmode:
1359 case CCANmode:
1360 if (req_mode != CCAmode)
1361 return 0;
1362 break;
f81e845f 1363
4673c1a0 1364 default:
32eda510 1365 gcc_unreachable ();
4673c1a0 1366 }
f81e845f 1367
4673c1a0 1368 return (GET_MODE (SET_SRC (set)) == set_mode);
1369}
1370
f81e845f 1371/* Return true if every SET in INSN that sets the CC register
1372 has source and destination with matching CC modes and that
1373 CC mode is at least as constrained as REQ_MODE.
c6821d1c 1374 If REQ_MODE is VOIDmode, always return false. */
f81e845f 1375
e5537457 1376bool
3754d046 1377s390_match_ccmode (rtx_insn *insn, machine_mode req_mode)
4673c1a0 1378{
1379 int i;
1380
c6821d1c 1381 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
1382 if (req_mode == VOIDmode)
e5537457 1383 return false;
c6821d1c 1384
4673c1a0 1385 if (GET_CODE (PATTERN (insn)) == SET)
1386 return s390_match_ccmode_set (PATTERN (insn), req_mode);
1387
1388 if (GET_CODE (PATTERN (insn)) == PARALLEL)
1389 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
1390 {
1391 rtx set = XVECEXP (PATTERN (insn), 0, i);
1392 if (GET_CODE (set) == SET)
1393 if (!s390_match_ccmode_set (set, req_mode))
e5537457 1394 return false;
4673c1a0 1395 }
1396
e5537457 1397 return true;
4673c1a0 1398}
1399
f81e845f 1400/* If a test-under-mask instruction can be used to implement
c6821d1c 1401 (compare (and ... OP1) OP2), return the CC mode required
f81e845f 1402 to do that. Otherwise, return VOIDmode.
c6821d1c 1403 MIXED is true if the instruction can distinguish between
1404 CC1 and CC2 for mixed selected bits (TMxx), it is false
1405 if the instruction cannot (TM). */
1406
3754d046 1407machine_mode
e5537457 1408s390_tm_ccmode (rtx op1, rtx op2, bool mixed)
c6821d1c 1409{
1410 int bit0, bit1;
1411
ba0e61d6 1412 /* ??? Fixme: should work on CONST_WIDE_INT as well. */
c6821d1c 1413 if (GET_CODE (op1) != CONST_INT || GET_CODE (op2) != CONST_INT)
1414 return VOIDmode;
1415
eeba5f25 1416 /* Selected bits all zero: CC0.
1417 e.g.: int a; if ((a & (16 + 128)) == 0) */
c6821d1c 1418 if (INTVAL (op2) == 0)
1419 return CCTmode;
1420
ffead1ca 1421 /* Selected bits all one: CC3.
eeba5f25 1422 e.g.: int a; if ((a & (16 + 128)) == 16 + 128) */
c6821d1c 1423 if (INTVAL (op2) == INTVAL (op1))
1424 return CCT3mode;
1425
eeba5f25 1426 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. e.g.:
1427 int a;
1428 if ((a & (16 + 128)) == 16) -> CCT1
1429 if ((a & (16 + 128)) == 128) -> CCT2 */
c6821d1c 1430 if (mixed)
1431 {
1432 bit1 = exact_log2 (INTVAL (op2));
1433 bit0 = exact_log2 (INTVAL (op1) ^ INTVAL (op2));
1434 if (bit0 != -1 && bit1 != -1)
1435 return bit0 > bit1 ? CCT1mode : CCT2mode;
1436 }
1437
1438 return VOIDmode;
1439}
1440
f81e845f 1441/* Given a comparison code OP (EQ, NE, etc.) and the operands
1442 OP0 and OP1 of a COMPARE, return the mode to be used for the
2eb8fe23 1443 comparison. */
1444
3754d046 1445machine_mode
b40da9a7 1446s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
2eb8fe23 1447{
1448 switch (code)
1449 {
1450 case EQ:
1451 case NE:
9be33ca2 1452 if ((GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
1453 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
1454 return CCAPmode;
3c482144 1455 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
cb888f33 1456 && CONST_OK_FOR_K (INTVAL (XEXP (op0, 1))))
3c482144 1457 return CCAPmode;
e9fd5349 1458 if ((GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
1459 || GET_CODE (op1) == NEG)
1460 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
2eb8fe23 1461 return CCLmode;
1462
c6821d1c 1463 if (GET_CODE (op0) == AND)
1464 {
1465 /* Check whether we can potentially do it via TM. */
3754d046 1466 machine_mode ccmode;
c6821d1c 1467 ccmode = s390_tm_ccmode (XEXP (op0, 1), op1, 1);
1468 if (ccmode != VOIDmode)
1469 {
1470 /* Relax CCTmode to CCZmode to allow fall-back to AND
1471 if that turns out to be beneficial. */
1472 return ccmode == CCTmode ? CCZmode : ccmode;
1473 }
1474 }
1475
f81e845f 1476 if (register_operand (op0, HImode)
c6821d1c 1477 && GET_CODE (op1) == CONST_INT
1478 && (INTVAL (op1) == -1 || INTVAL (op1) == 65535))
1479 return CCT3mode;
f81e845f 1480 if (register_operand (op0, QImode)
c6821d1c 1481 && GET_CODE (op1) == CONST_INT
1482 && (INTVAL (op1) == -1 || INTVAL (op1) == 255))
1483 return CCT3mode;
1484
2eb8fe23 1485 return CCZmode;
1486
1487 case LE:
1488 case LT:
1489 case GE:
1490 case GT:
eeba5f25 1491 /* The only overflow condition of NEG and ABS happens when
1492 -INT_MAX is used as parameter, which stays negative. So
ffead1ca 1493 we have an overflow from a positive value to a negative.
eeba5f25 1494 Using CCAP mode the resulting cc can be used for comparisons. */
9be33ca2 1495 if ((GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
1496 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
1497 return CCAPmode;
eeba5f25 1498
1499 /* If constants are involved in an add instruction it is possible to use
1500 the resulting cc for comparisons with zero. Knowing the sign of the
0975351b 1501 constant the overflow behavior gets predictable. e.g.:
ffead1ca 1502 int a, b; if ((b = a + c) > 0)
eeba5f25 1503 with c as a constant value: c < 0 -> CCAN and c >= 0 -> CCAP */
9be33ca2 1504 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
ea14438e 1505 && (CONST_OK_FOR_K (INTVAL (XEXP (op0, 1)))
1506 || (CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0, 1)), 'O', "Os")
1507 /* Avoid INT32_MIN on 32 bit. */
1508 && (!TARGET_ZARCH || INTVAL (XEXP (op0, 1)) != -0x7fffffff - 1))))
9be33ca2 1509 {
1510 if (INTVAL (XEXP((op0), 1)) < 0)
1511 return CCANmode;
1512 else
1513 return CCAPmode;
1514 }
1515 /* Fall through. */
2eb8fe23 1516 case UNORDERED:
1517 case ORDERED:
1518 case UNEQ:
1519 case UNLE:
1520 case UNLT:
1521 case UNGE:
1522 case UNGT:
1523 case LTGT:
c6821d1c 1524 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
1525 && GET_CODE (op1) != CONST_INT)
1526 return CCSRmode;
2eb8fe23 1527 return CCSmode;
1528
2eb8fe23 1529 case LTU:
1530 case GEU:
e9fd5349 1531 if (GET_CODE (op0) == PLUS
1532 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
c6821d1c 1533 return CCL1mode;
1534
1535 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
1536 && GET_CODE (op1) != CONST_INT)
1537 return CCURmode;
1538 return CCUmode;
1539
1540 case LEU:
2eb8fe23 1541 case GTU:
e9fd5349 1542 if (GET_CODE (op0) == MINUS
1543 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
c6821d1c 1544 return CCL2mode;
1545
1546 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
1547 && GET_CODE (op1) != CONST_INT)
1548 return CCURmode;
2eb8fe23 1549 return CCUmode;
1550
1551 default:
32eda510 1552 gcc_unreachable ();
2eb8fe23 1553 }
1554}
1555
ebe32bb0 1556/* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
1557 that we can implement more efficiently. */
1558
d5065e6e 1559static void
1560s390_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
1561 bool op0_preserve_value)
ebe32bb0 1562{
d5065e6e 1563 if (op0_preserve_value)
1564 return;
1565
ebe32bb0 1566 /* Convert ZERO_EXTRACT back to AND to enable TM patterns. */
1567 if ((*code == EQ || *code == NE)
1568 && *op1 == const0_rtx
1569 && GET_CODE (*op0) == ZERO_EXTRACT
1570 && GET_CODE (XEXP (*op0, 1)) == CONST_INT
1571 && GET_CODE (XEXP (*op0, 2)) == CONST_INT
1572 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0, 0))))
1573 {
1574 rtx inner = XEXP (*op0, 0);
1575 HOST_WIDE_INT modesize = GET_MODE_BITSIZE (GET_MODE (inner));
1576 HOST_WIDE_INT len = INTVAL (XEXP (*op0, 1));
1577 HOST_WIDE_INT pos = INTVAL (XEXP (*op0, 2));
1578
1579 if (len > 0 && len < modesize
1580 && pos >= 0 && pos + len <= modesize
1581 && modesize <= HOST_BITS_PER_WIDE_INT)
1582 {
1583 unsigned HOST_WIDE_INT block;
b422d8c0 1584 block = (HOST_WIDE_INT_1U << len) - 1;
ebe32bb0 1585 block <<= modesize - pos - len;
1586
1587 *op0 = gen_rtx_AND (GET_MODE (inner), inner,
1588 gen_int_mode (block, GET_MODE (inner)));
1589 }
1590 }
1591
1592 /* Narrow AND of memory against immediate to enable TM. */
1593 if ((*code == EQ || *code == NE)
1594 && *op1 == const0_rtx
1595 && GET_CODE (*op0) == AND
1596 && GET_CODE (XEXP (*op0, 1)) == CONST_INT
1597 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0, 0))))
1598 {
1599 rtx inner = XEXP (*op0, 0);
1600 rtx mask = XEXP (*op0, 1);
1601
1602 /* Ignore paradoxical SUBREGs if all extra bits are masked out. */
1603 if (GET_CODE (inner) == SUBREG
1604 && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (inner)))
1605 && (GET_MODE_SIZE (GET_MODE (inner))
1606 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner))))
1607 && ((INTVAL (mask)
1608 & GET_MODE_MASK (GET_MODE (inner))
1609 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (inner))))
1610 == 0))
1611 inner = SUBREG_REG (inner);
1612
1613 /* Do not change volatile MEMs. */
1614 if (MEM_P (inner) && !MEM_VOLATILE_P (inner))
1615 {
1616 int part = s390_single_part (XEXP (*op0, 1),
1617 GET_MODE (inner), QImode, 0);
1618 if (part >= 0)
1619 {
1620 mask = gen_int_mode (s390_extract_part (mask, QImode, 0), QImode);
1621 inner = adjust_address_nv (inner, QImode, part);
1622 *op0 = gen_rtx_AND (QImode, inner, mask);
1623 }
1624 }
1625 }
1626
1627 /* Narrow comparisons against 0xffff to HImode if possible. */
ebe32bb0 1628 if ((*code == EQ || *code == NE)
1629 && GET_CODE (*op1) == CONST_INT
1630 && INTVAL (*op1) == 0xffff
1631 && SCALAR_INT_MODE_P (GET_MODE (*op0))
ffead1ca 1632 && (nonzero_bits (*op0, GET_MODE (*op0))
b422d8c0 1633 & ~HOST_WIDE_INT_UC (0xffff)) == 0)
ebe32bb0 1634 {
1635 *op0 = gen_lowpart (HImode, *op0);
1636 *op1 = constm1_rtx;
1637 }
80b53886 1638
5ada7a14 1639 /* Remove redundant UNSPEC_STRCMPCC_TO_INT conversions if possible. */
80b53886 1640 if (GET_CODE (*op0) == UNSPEC
5ada7a14 1641 && XINT (*op0, 1) == UNSPEC_STRCMPCC_TO_INT
80b53886 1642 && XVECLEN (*op0, 0) == 1
1643 && GET_MODE (XVECEXP (*op0, 0, 0)) == CCUmode
1644 && GET_CODE (XVECEXP (*op0, 0, 0)) == REG
1645 && REGNO (XVECEXP (*op0, 0, 0)) == CC_REGNUM
1646 && *op1 == const0_rtx)
1647 {
1648 enum rtx_code new_code = UNKNOWN;
1649 switch (*code)
1650 {
1651 case EQ: new_code = EQ; break;
1652 case NE: new_code = NE; break;
dd16a4bd 1653 case LT: new_code = GTU; break;
1654 case GT: new_code = LTU; break;
1655 case LE: new_code = GEU; break;
1656 case GE: new_code = LEU; break;
80b53886 1657 default: break;
1658 }
1659
1660 if (new_code != UNKNOWN)
1661 {
1662 *op0 = XVECEXP (*op0, 0, 0);
1663 *code = new_code;
1664 }
1665 }
9c93d843 1666
5ada7a14 1667 /* Remove redundant UNSPEC_CC_TO_INT conversions if possible. */
27784c70 1668 if (GET_CODE (*op0) == UNSPEC
5ada7a14 1669 && XINT (*op0, 1) == UNSPEC_CC_TO_INT
27784c70 1670 && XVECLEN (*op0, 0) == 1
27784c70 1671 && GET_CODE (XVECEXP (*op0, 0, 0)) == REG
1672 && REGNO (XVECEXP (*op0, 0, 0)) == CC_REGNUM
5ada7a14 1673 && CONST_INT_P (*op1))
27784c70 1674 {
1675 enum rtx_code new_code = UNKNOWN;
5ada7a14 1676 switch (GET_MODE (XVECEXP (*op0, 0, 0)))
27784c70 1677 {
5ada7a14 1678 case CCZmode:
1679 case CCRAWmode:
1680 switch (*code)
1681 {
1682 case EQ: new_code = EQ; break;
1683 case NE: new_code = NE; break;
1684 default: break;
1685 }
1686 break;
1687 default: break;
27784c70 1688 }
1689
1690 if (new_code != UNKNOWN)
1691 {
5ada7a14 1692 /* For CCRAWmode put the required cc mask into the second
1693 operand. */
91dfd73e 1694 if (GET_MODE (XVECEXP (*op0, 0, 0)) == CCRAWmode
1695 && INTVAL (*op1) >= 0 && INTVAL (*op1) <= 3)
5ada7a14 1696 *op1 = gen_rtx_CONST_INT (VOIDmode, 1 << (3 - INTVAL (*op1)));
27784c70 1697 *op0 = XVECEXP (*op0, 0, 0);
1698 *code = new_code;
1699 }
1700 }
1701
9c93d843 1702 /* Simplify cascaded EQ, NE with const0_rtx. */
1703 if ((*code == NE || *code == EQ)
1704 && (GET_CODE (*op0) == EQ || GET_CODE (*op0) == NE)
1705 && GET_MODE (*op0) == SImode
1706 && GET_MODE (XEXP (*op0, 0)) == CCZ1mode
1707 && REG_P (XEXP (*op0, 0))
1708 && XEXP (*op0, 1) == const0_rtx
1709 && *op1 == const0_rtx)
1710 {
1711 if ((*code == EQ && GET_CODE (*op0) == NE)
1712 || (*code == NE && GET_CODE (*op0) == EQ))
1713 *code = EQ;
1714 else
1715 *code = NE;
1716 *op0 = XEXP (*op0, 0);
1717 }
a0631a8a 1718
1719 /* Prefer register over memory as first operand. */
1720 if (MEM_P (*op0) && REG_P (*op1))
1721 {
1722 rtx tem = *op0; *op0 = *op1; *op1 = tem;
d5065e6e 1723 *code = (int)swap_condition ((enum rtx_code)*code);
a0631a8a 1724 }
26233f43 1725
e17ed6ec 1726 /* A comparison result is compared against zero. Replace it with
1727 the (perhaps inverted) original comparison.
1728 This probably should be done by simplify_relational_operation. */
1729 if ((*code == EQ || *code == NE)
1730 && *op1 == const0_rtx
1731 && COMPARISON_P (*op0)
1732 && CC_REG_P (XEXP (*op0, 0)))
1733 {
1734 enum rtx_code new_code;
1735
1736 if (*code == EQ)
1737 new_code = reversed_comparison_code_parts (GET_CODE (*op0),
1738 XEXP (*op0, 0),
1739 XEXP (*op1, 0), NULL);
1740 else
1741 new_code = GET_CODE (*op0);
1742
1743 if (new_code != UNKNOWN)
1744 {
1745 *code = new_code;
1746 *op1 = XEXP (*op0, 1);
1747 *op0 = XEXP (*op0, 0);
1748 }
1749 }
ebe32bb0 1750}
1751
26233f43 1752
0d656e8b 1753/* Emit a compare instruction suitable to implement the comparison
1754 OP0 CODE OP1. Return the correct condition RTL to be placed in
1755 the IF_THEN_ELSE of the conditional branch testing the result. */
1756
1757rtx
1758s390_emit_compare (enum rtx_code code, rtx op0, rtx op1)
1759{
3754d046 1760 machine_mode mode = s390_select_ccmode (code, op0, op1);
8e58aded 1761 rtx cc;
0d656e8b 1762
29c098f6 1763 if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
8e58aded 1764 {
26233f43 1765 /* Do not output a redundant compare instruction if a
1766 compare_and_swap pattern already computed the result and the
1767 machine modes are compatible. */
8e58aded 1768 gcc_assert (s390_cc_modes_compatible (GET_MODE (op0), mode)
1769 == GET_MODE (op0));
1770 cc = op0;
1771 }
891e3096 1772 else
1773 {
8e58aded 1774 cc = gen_rtx_REG (mode, CC_REGNUM);
d1f9b275 1775 emit_insn (gen_rtx_SET (cc, gen_rtx_COMPARE (mode, op0, op1)));
891e3096 1776 }
8e58aded 1777
ffead1ca 1778 return gen_rtx_fmt_ee (code, VOIDmode, cc, const0_rtx);
0d656e8b 1779}
1780
8deb3959 1781/* Emit a SImode compare and swap instruction setting MEM to NEW_RTX if OLD
db1f11e3 1782 matches CMP.
1783 Return the correct condition RTL to be placed in the IF_THEN_ELSE of the
1784 conditional branch testing the result. */
1785
1786static rtx
8c753480 1787s390_emit_compare_and_swap (enum rtx_code code, rtx old, rtx mem,
d90d26d8 1788 rtx cmp, rtx new_rtx, machine_mode ccmode)
db1f11e3 1789{
d90d26d8 1790 rtx cc;
1791
1792 cc = gen_rtx_REG (ccmode, CC_REGNUM);
1793 switch (GET_MODE (mem))
1794 {
1795 case SImode:
1796 emit_insn (gen_atomic_compare_and_swapsi_internal (old, mem, cmp,
1797 new_rtx, cc));
1798 break;
1799 case DImode:
1800 emit_insn (gen_atomic_compare_and_swapdi_internal (old, mem, cmp,
1801 new_rtx, cc));
1802 break;
1803 case TImode:
1804 emit_insn (gen_atomic_compare_and_swapti_internal (old, mem, cmp,
1805 new_rtx, cc));
1806 break;
1807 case QImode:
1808 case HImode:
1809 default:
1810 gcc_unreachable ();
1811 }
1812 return s390_emit_compare (code, cc, const0_rtx);
db1f11e3 1813}
1814
5ada7a14 1815/* Emit a jump instruction to TARGET and return it. If COND is
1816 NULL_RTX, emit an unconditional jump, else a conditional jump under
1817 condition COND. */
0d656e8b 1818
93e0956b 1819rtx_insn *
0d656e8b 1820s390_emit_jump (rtx target, rtx cond)
1821{
1822 rtx insn;
1823
1824 target = gen_rtx_LABEL_REF (VOIDmode, target);
1825 if (cond)
1826 target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, target, pc_rtx);
1827
d1f9b275 1828 insn = gen_rtx_SET (pc_rtx, target);
5ada7a14 1829 return emit_jump_insn (insn);
0d656e8b 1830}
1831
f81e845f 1832/* Return branch condition mask to implement a branch
80b53886 1833 specified by CODE. Return -1 for invalid comparisons. */
2eb8fe23 1834
8cc5de33 1835int
b40da9a7 1836s390_branch_condition_mask (rtx code)
f81e845f 1837{
2eb8fe23 1838 const int CC0 = 1 << 3;
1839 const int CC1 = 1 << 2;
1840 const int CC2 = 1 << 1;
1841 const int CC3 = 1 << 0;
1842
32eda510 1843 gcc_assert (GET_CODE (XEXP (code, 0)) == REG);
1844 gcc_assert (REGNO (XEXP (code, 0)) == CC_REGNUM);
5ada7a14 1845 gcc_assert (XEXP (code, 1) == const0_rtx
1846 || (GET_MODE (XEXP (code, 0)) == CCRAWmode
1847 && CONST_INT_P (XEXP (code, 1))));
1848
2eb8fe23 1849
1850 switch (GET_MODE (XEXP (code, 0)))
1851 {
1852 case CCZmode:
9c93d843 1853 case CCZ1mode:
2eb8fe23 1854 switch (GET_CODE (code))
1855 {
1856 case EQ: return CC0;
1857 case NE: return CC1 | CC2 | CC3;
80b53886 1858 default: return -1;
2eb8fe23 1859 }
1860 break;
1861
c6821d1c 1862 case CCT1mode:
1863 switch (GET_CODE (code))
1864 {
1865 case EQ: return CC1;
1866 case NE: return CC0 | CC2 | CC3;
80b53886 1867 default: return -1;
c6821d1c 1868 }
1869 break;
1870
1871 case CCT2mode:
1872 switch (GET_CODE (code))
1873 {
1874 case EQ: return CC2;
1875 case NE: return CC0 | CC1 | CC3;
80b53886 1876 default: return -1;
c6821d1c 1877 }
1878 break;
1879
1880 case CCT3mode:
1881 switch (GET_CODE (code))
1882 {
1883 case EQ: return CC3;
1884 case NE: return CC0 | CC1 | CC2;
80b53886 1885 default: return -1;
c6821d1c 1886 }
1887 break;
1888
2eb8fe23 1889 case CCLmode:
1890 switch (GET_CODE (code))
1891 {
1892 case EQ: return CC0 | CC2;
1893 case NE: return CC1 | CC3;
80b53886 1894 default: return -1;
c6821d1c 1895 }
1896 break;
1897
1898 case CCL1mode:
1899 switch (GET_CODE (code))
1900 {
1901 case LTU: return CC2 | CC3; /* carry */
1902 case GEU: return CC0 | CC1; /* no carry */
80b53886 1903 default: return -1;
c6821d1c 1904 }
1905 break;
1906
1907 case CCL2mode:
1908 switch (GET_CODE (code))
1909 {
1910 case GTU: return CC0 | CC1; /* borrow */
1911 case LEU: return CC2 | CC3; /* no borrow */
80b53886 1912 default: return -1;
2eb8fe23 1913 }
1914 break;
1915
3b699fc7 1916 case CCL3mode:
1917 switch (GET_CODE (code))
1918 {
1919 case EQ: return CC0 | CC2;
1920 case NE: return CC1 | CC3;
1921 case LTU: return CC1;
1922 case GTU: return CC3;
1923 case LEU: return CC1 | CC2;
1924 case GEU: return CC2 | CC3;
80b53886 1925 default: return -1;
3b699fc7 1926 }
1927
2eb8fe23 1928 case CCUmode:
1929 switch (GET_CODE (code))
1930 {
1931 case EQ: return CC0;
1932 case NE: return CC1 | CC2 | CC3;
1933 case LTU: return CC1;
1934 case GTU: return CC2;
1935 case LEU: return CC0 | CC1;
1936 case GEU: return CC0 | CC2;
80b53886 1937 default: return -1;
2eb8fe23 1938 }
1939 break;
1940
c6821d1c 1941 case CCURmode:
1942 switch (GET_CODE (code))
1943 {
1944 case EQ: return CC0;
1945 case NE: return CC2 | CC1 | CC3;
1946 case LTU: return CC2;
1947 case GTU: return CC1;
1948 case LEU: return CC0 | CC2;
1949 case GEU: return CC0 | CC1;
80b53886 1950 default: return -1;
c6821d1c 1951 }
1952 break;
1953
3c482144 1954 case CCAPmode:
1955 switch (GET_CODE (code))
1956 {
1957 case EQ: return CC0;
1958 case NE: return CC1 | CC2 | CC3;
1959 case LT: return CC1 | CC3;
1960 case GT: return CC2;
1961 case LE: return CC0 | CC1 | CC3;
1962 case GE: return CC0 | CC2;
80b53886 1963 default: return -1;
3c482144 1964 }
1965 break;
1966
1967 case CCANmode:
1968 switch (GET_CODE (code))
1969 {
1970 case EQ: return CC0;
1971 case NE: return CC1 | CC2 | CC3;
1972 case LT: return CC1;
1973 case GT: return CC2 | CC3;
1974 case LE: return CC0 | CC1;
1975 case GE: return CC0 | CC2 | CC3;
80b53886 1976 default: return -1;
3c482144 1977 }
1978 break;
1979
2eb8fe23 1980 case CCSmode:
1981 switch (GET_CODE (code))
1982 {
1983 case EQ: return CC0;
1984 case NE: return CC1 | CC2 | CC3;
1985 case LT: return CC1;
1986 case GT: return CC2;
1987 case LE: return CC0 | CC1;
1988 case GE: return CC0 | CC2;
1989 case UNORDERED: return CC3;
1990 case ORDERED: return CC0 | CC1 | CC2;
1991 case UNEQ: return CC0 | CC3;
1992 case UNLT: return CC1 | CC3;
1993 case UNGT: return CC2 | CC3;
1994 case UNLE: return CC0 | CC1 | CC3;
1995 case UNGE: return CC0 | CC2 | CC3;
1996 case LTGT: return CC1 | CC2;
80b53886 1997 default: return -1;
2eb8fe23 1998 }
c6821d1c 1999 break;
2000
2001 case CCSRmode:
2002 switch (GET_CODE (code))
2003 {
2004 case EQ: return CC0;
2005 case NE: return CC2 | CC1 | CC3;
2006 case LT: return CC2;
2007 case GT: return CC1;
2008 case LE: return CC0 | CC2;
2009 case GE: return CC0 | CC1;
2010 case UNORDERED: return CC3;
2011 case ORDERED: return CC0 | CC2 | CC1;
2012 case UNEQ: return CC0 | CC3;
2013 case UNLT: return CC2 | CC3;
2014 case UNGT: return CC1 | CC3;
2015 case UNLE: return CC0 | CC2 | CC3;
2016 case UNGE: return CC0 | CC1 | CC3;
2017 case LTGT: return CC2 | CC1;
80b53886 2018 default: return -1;
c6821d1c 2019 }
2020 break;
2eb8fe23 2021
26233f43 2022 /* Vector comparison modes. */
abc57c35 2023 /* CC2 will never be set. It however is part of the negated
2024 masks. */
2025 case CCVIALLmode:
26233f43 2026 switch (GET_CODE (code))
2027 {
abc57c35 2028 case EQ:
2029 case GTU:
2030 case GT:
2031 case GE: return CC0;
2032 /* The inverted modes are in fact *any* modes. */
2033 case NE:
2034 case LEU:
2035 case LE:
2036 case LT: return CC3 | CC1 | CC2;
26233f43 2037 default: return -1;
2038 }
07f32359 2039
abc57c35 2040 case CCVIANYmode:
07f32359 2041 switch (GET_CODE (code))
2042 {
abc57c35 2043 case EQ:
2044 case GTU:
2045 case GT:
2046 case GE: return CC0 | CC1;
2047 /* The inverted modes are in fact *all* modes. */
2048 case NE:
2049 case LEU:
2050 case LE:
2051 case LT: return CC3 | CC2;
07f32359 2052 default: return -1;
2053 }
abc57c35 2054 case CCVFALLmode:
26233f43 2055 switch (GET_CODE (code))
2056 {
abc57c35 2057 case EQ:
2058 case GT:
26233f43 2059 case GE: return CC0;
abc57c35 2060 /* The inverted modes are in fact *any* modes. */
2061 case NE:
2062 case UNLE:
2063 case UNLT: return CC3 | CC1 | CC2;
26233f43 2064 default: return -1;
2065 }
07f32359 2066
abc57c35 2067 case CCVFANYmode:
07f32359 2068 switch (GET_CODE (code))
2069 {
abc57c35 2070 case EQ:
2071 case GT:
07f32359 2072 case GE: return CC0 | CC1;
abc57c35 2073 /* The inverted modes are in fact *all* modes. */
2074 case NE:
2075 case UNLE:
2076 case UNLT: return CC3 | CC2;
07f32359 2077 default: return -1;
2078 }
2079
5ada7a14 2080 case CCRAWmode:
2081 switch (GET_CODE (code))
2082 {
2083 case EQ:
2084 return INTVAL (XEXP (code, 1));
2085 case NE:
2086 return (INTVAL (XEXP (code, 1))) ^ 0xf;
2087 default:
2088 gcc_unreachable ();
2089 }
2090
2eb8fe23 2091 default:
80b53886 2092 return -1;
2eb8fe23 2093 }
2094}
2095
e68d6a13 2096
2097/* Return branch condition mask to implement a compare and branch
2098 specified by CODE. Return -1 for invalid comparisons. */
2099
2100int
2101s390_compare_and_branch_condition_mask (rtx code)
2102{
2103 const int CC0 = 1 << 3;
2104 const int CC1 = 1 << 2;
2105 const int CC2 = 1 << 1;
2106
2107 switch (GET_CODE (code))
2108 {
2109 case EQ:
2110 return CC0;
2111 case NE:
2112 return CC1 | CC2;
2113 case LT:
2114 case LTU:
2115 return CC1;
2116 case GT:
2117 case GTU:
2118 return CC2;
2119 case LE:
2120 case LEU:
2121 return CC0 | CC1;
2122 case GE:
2123 case GEU:
2124 return CC0 | CC2;
2125 default:
2126 gcc_unreachable ();
2127 }
2128 return -1;
2129}
2130
f81e845f 2131/* If INV is false, return assembler mnemonic string to implement
2132 a branch specified by CODE. If INV is true, return mnemonic
2eb8fe23 2133 for the corresponding inverted branch. */
2134
2135static const char *
b40da9a7 2136s390_branch_condition_mnemonic (rtx code, int inv)
2eb8fe23 2137{
e68d6a13 2138 int mask;
2139
c8834c5f 2140 static const char *const mnemonic[16] =
2eb8fe23 2141 {
2142 NULL, "o", "h", "nle",
2143 "l", "nhe", "lh", "ne",
2144 "e", "nlh", "he", "nl",
2145 "le", "nh", "no", NULL
2146 };
2147
e68d6a13 2148 if (GET_CODE (XEXP (code, 0)) == REG
2149 && REGNO (XEXP (code, 0)) == CC_REGNUM
5ada7a14 2150 && (XEXP (code, 1) == const0_rtx
2151 || (GET_MODE (XEXP (code, 0)) == CCRAWmode
2152 && CONST_INT_P (XEXP (code, 1)))))
e68d6a13 2153 mask = s390_branch_condition_mask (code);
2154 else
2155 mask = s390_compare_and_branch_condition_mask (code);
2156
80b53886 2157 gcc_assert (mask >= 0);
2eb8fe23 2158
2159 if (inv)
2160 mask ^= 15;
2161
32eda510 2162 gcc_assert (mask >= 1 && mask <= 14);
2eb8fe23 2163
2164 return mnemonic[mask];
2165}
2166
64a1078f 2167/* Return the part of op which has a value different from def.
2168 The size of the part is determined by mode.
f588eb9f 2169 Use this function only if you already know that op really
64a1078f 2170 contains such a part. */
8b4a4127 2171
64a1078f 2172unsigned HOST_WIDE_INT
3754d046 2173s390_extract_part (rtx op, machine_mode mode, int def)
8b4a4127 2174{
64a1078f 2175 unsigned HOST_WIDE_INT value = 0;
2176 int max_parts = HOST_BITS_PER_WIDE_INT / GET_MODE_BITSIZE (mode);
2177 int part_bits = GET_MODE_BITSIZE (mode);
b422d8c0 2178 unsigned HOST_WIDE_INT part_mask = (HOST_WIDE_INT_1U << part_bits) - 1;
64a1078f 2179 int i;
f588eb9f 2180
64a1078f 2181 for (i = 0; i < max_parts; i++)
8b4a4127 2182 {
64a1078f 2183 if (i == 0)
b422d8c0 2184 value = UINTVAL (op);
8b4a4127 2185 else
64a1078f 2186 value >>= part_bits;
f588eb9f 2187
64a1078f 2188 if ((value & part_mask) != (def & part_mask))
2189 return value & part_mask;
8b4a4127 2190 }
f588eb9f 2191
32eda510 2192 gcc_unreachable ();
8b4a4127 2193}
2194
2195/* If OP is an integer constant of mode MODE with exactly one
64a1078f 2196 part of mode PART_MODE unequal to DEF, return the number of that
2197 part. Otherwise, return -1. */
8b4a4127 2198
2199int
f588eb9f 2200s390_single_part (rtx op,
3754d046 2201 machine_mode mode,
2202 machine_mode part_mode,
64a1078f 2203 int def)
2204{
2205 unsigned HOST_WIDE_INT value = 0;
2206 int n_parts = GET_MODE_SIZE (mode) / GET_MODE_SIZE (part_mode);
0451e449 2207 unsigned HOST_WIDE_INT part_mask
b422d8c0 2208 = (HOST_WIDE_INT_1U << GET_MODE_BITSIZE (part_mode)) - 1;
64a1078f 2209 int i, part = -1;
2210
2211 if (GET_CODE (op) != CONST_INT)
2212 return -1;
f588eb9f 2213
64a1078f 2214 for (i = 0; i < n_parts; i++)
2215 {
2216 if (i == 0)
b422d8c0 2217 value = UINTVAL (op);
8b4a4127 2218 else
64a1078f 2219 value >>= GET_MODE_BITSIZE (part_mode);
f588eb9f 2220
64a1078f 2221 if ((value & part_mask) != (def & part_mask))
2222 {
2223 if (part != -1)
2224 return -1;
2225 else
2226 part = i;
2227 }
8b4a4127 2228 }
64a1078f 2229 return part == -1 ? -1 : n_parts - 1 - part;
8b4a4127 2230}
2231
e68d6a13 2232/* Return true if IN contains a contiguous bitfield in the lower SIZE
e64f5133 2233 bits and no other bits are set in (the lower SIZE bits of) IN.
e68d6a13 2234
e64f5133 2235 PSTART and PEND can be used to obtain the start and end
2236 position (inclusive) of the bitfield relative to 64
2237 bits. *PSTART / *PEND gives the position of the first/last bit
2238 of the bitfield counting from the highest order bit starting
2239 with zero. */
e68d6a13 2240
2241bool
e64f5133 2242s390_contiguous_bitmask_nowrap_p (unsigned HOST_WIDE_INT in, int size,
2243 int *pstart, int *pend)
e68d6a13 2244{
e64f5133 2245 int start;
2246 int end = -1;
b422d8c0 2247 int lowbit = HOST_BITS_PER_WIDE_INT - 1;
2248 int highbit = HOST_BITS_PER_WIDE_INT - size;
2249 unsigned HOST_WIDE_INT bitmask = HOST_WIDE_INT_1U;
e64f5133 2250
2251 gcc_assert (!!pstart == !!pend);
2252 for (start = lowbit; start >= highbit; bitmask <<= 1, start--)
2253 if (end == -1)
2254 {
2255 /* Look for the rightmost bit of a contiguous range of ones. */
2256 if (bitmask & in)
2257 /* Found it. */
2258 end = start;
2259 }
2260 else
2261 {
2262 /* Look for the firt zero bit after the range of ones. */
2263 if (! (bitmask & in))
2264 /* Found it. */
2265 break;
2266 }
2267 /* We're one past the last one-bit. */
2268 start++;
e68d6a13 2269
e64f5133 2270 if (end == -1)
2271 /* No one bits found. */
2272 return false;
2273
2274 if (start > highbit)
e68d6a13 2275 {
e64f5133 2276 unsigned HOST_WIDE_INT mask;
2277
2278 /* Calculate a mask for all bits beyond the contiguous bits. */
b422d8c0 2279 mask = ((~HOST_WIDE_INT_0U >> highbit)
2280 & (~HOST_WIDE_INT_0U << (lowbit - start + 1)));
e64f5133 2281 if (mask & in)
2282 /* There are more bits set beyond the first range of one bits. */
2283 return false;
e68d6a13 2284 }
2285
e64f5133 2286 if (pstart)
2287 {
2288 *pstart = start;
2289 *pend = end;
2290 }
e68d6a13 2291
e64f5133 2292 return true;
2293}
e68d6a13 2294
e64f5133 2295/* Same as s390_contiguous_bitmask_nowrap_p but also returns true
2296 if ~IN contains a contiguous bitfield. In that case, *END is <
2297 *START.
76a4c804 2298
e64f5133 2299 If WRAP_P is true, a bitmask that wraps around is also tested.
2300 When a wraparoud occurs *START is greater than *END (in
2301 non-null pointers), and the uppermost (64 - SIZE) bits are thus
2302 part of the range. If WRAP_P is false, no wraparound is
2303 tested. */
e68d6a13 2304
e64f5133 2305bool
2306s390_contiguous_bitmask_p (unsigned HOST_WIDE_INT in, bool wrap_p,
2307 int size, int *start, int *end)
2308{
b422d8c0 2309 int bs = HOST_BITS_PER_WIDE_INT;
e64f5133 2310 bool b;
2311
2312 gcc_assert (!!start == !!end);
b422d8c0 2313 if ((in & ((~HOST_WIDE_INT_0U) >> (bs - size))) == 0)
e64f5133 2314 /* This cannot be expressed as a contiguous bitmask. Exit early because
2315 the second call of s390_contiguous_bitmask_nowrap_p would accept this as
2316 a valid bitmask. */
e68d6a13 2317 return false;
e64f5133 2318 b = s390_contiguous_bitmask_nowrap_p (in, size, start, end);
2319 if (b)
2320 return true;
2321 if (! wrap_p)
2322 return false;
2323 b = s390_contiguous_bitmask_nowrap_p (~in, size, start, end);
2324 if (b && start)
2325 {
2326 int s = *start;
2327 int e = *end;
e68d6a13 2328
e64f5133 2329 gcc_assert (s >= 1);
2330 *start = ((e + 1) & (bs - 1));
2331 *end = ((s - 1 + bs) & (bs - 1));
2332 }
e68d6a13 2333
e64f5133 2334 return b;
e68d6a13 2335}
2336
76a4c804 2337/* Return true if OP contains the same contiguous bitfield in *all*
2338 its elements. START and END can be used to obtain the start and
2339 end position of the bitfield.
2340
2341 START/STOP give the position of the first/last bit of the bitfield
2342 counting from the lowest order bit starting with zero. In order to
2343 use these values for S/390 instructions this has to be converted to
2344 "bits big endian" style. */
2345
2346bool
2347s390_contiguous_bitmask_vector_p (rtx op, int *start, int *end)
2348{
2349 unsigned HOST_WIDE_INT mask;
e64f5133 2350 int size;
62fdb8e4 2351 rtx elt;
e64f5133 2352 bool b;
76a4c804 2353
e64f5133 2354 gcc_assert (!!start == !!end);
62fdb8e4 2355 if (!const_vec_duplicate_p (op, &elt)
2356 || !CONST_INT_P (elt))
76a4c804 2357 return false;
2358
76a4c804 2359 size = GET_MODE_UNIT_BITSIZE (GET_MODE (op));
f81e57c4 2360
2361 /* We cannot deal with V1TI/V1TF. This would require a vgmq. */
2362 if (size > 64)
2363 return false;
2364
62fdb8e4 2365 mask = UINTVAL (elt);
e64f5133 2366
2367 b = s390_contiguous_bitmask_p (mask, true, size, start, end);
2368 if (b)
76a4c804 2369 {
e64f5133 2370 if (start)
2371 {
b422d8c0 2372 *start -= (HOST_BITS_PER_WIDE_INT - size);
2373 *end -= (HOST_BITS_PER_WIDE_INT - size);
e64f5133 2374 }
76a4c804 2375 return true;
2376 }
e64f5133 2377 else
2378 return false;
76a4c804 2379}
2380
2381/* Return true if C consists only of byte chunks being either 0 or
2382 0xff. If MASK is !=NULL a byte mask is generated which is
2383 appropriate for the vector generate byte mask instruction. */
2384
2385bool
2386s390_bytemask_vector_p (rtx op, unsigned *mask)
2387{
2388 int i;
2389 unsigned tmp_mask = 0;
2390 int nunit, unit_size;
2391
2392 if (!VECTOR_MODE_P (GET_MODE (op))
2393 || GET_CODE (op) != CONST_VECTOR
2394 || !CONST_INT_P (XVECEXP (op, 0, 0)))
2395 return false;
2396
2397 nunit = GET_MODE_NUNITS (GET_MODE (op));
2398 unit_size = GET_MODE_UNIT_SIZE (GET_MODE (op));
2399
2400 for (i = 0; i < nunit; i++)
2401 {
2402 unsigned HOST_WIDE_INT c;
2403 int j;
2404
2405 if (!CONST_INT_P (XVECEXP (op, 0, i)))
2406 return false;
2407
2408 c = UINTVAL (XVECEXP (op, 0, i));
2409 for (j = 0; j < unit_size; j++)
2410 {
2411 if ((c & 0xff) != 0 && (c & 0xff) != 0xff)
2412 return false;
2413 tmp_mask |= (c & 1) << ((nunit - 1 - i) * unit_size + j);
2414 c = c >> BITS_PER_UNIT;
2415 }
2416 }
2417
2418 if (mask != NULL)
2419 *mask = tmp_mask;
2420
2421 return true;
2422}
2423
6bc28655 2424/* Check whether a rotate of ROTL followed by an AND of CONTIG is
2425 equivalent to a shift followed by the AND. In particular, CONTIG
2426 should not overlap the (rotated) bit 0/bit 63 gap. Negative values
2427 for ROTL indicate a rotate to the right. */
2428
2429bool
2430s390_extzv_shift_ok (int bitsize, int rotl, unsigned HOST_WIDE_INT contig)
2431{
e64f5133 2432 int start, end;
6bc28655 2433 bool ok;
2434
e64f5133 2435 ok = s390_contiguous_bitmask_nowrap_p (contig, bitsize, &start, &end);
6bc28655 2436 gcc_assert (ok);
2437
e64f5133 2438 if (rotl >= 0)
2439 return (64 - end >= rotl);
2440 else
2441 {
2442 /* Translate "- rotate right" in BITSIZE mode to "rotate left" in
2443 DIMode. */
2444 rotl = -rotl + (64 - bitsize);
2445 return (start >= rotl);
2446 }
6bc28655 2447}
2448
f81e845f 2449/* Check whether we can (and want to) split a double-word
2450 move in mode MODE from SRC to DST into two single-word
66795431 2451 moves, moving the subword FIRST_SUBWORD first. */
2452
2453bool
3754d046 2454s390_split_ok_p (rtx dst, rtx src, machine_mode mode, int first_subword)
66795431 2455{
76a4c804 2456 /* Floating point and vector registers cannot be split. */
2457 if (FP_REG_P (src) || FP_REG_P (dst) || VECTOR_REG_P (src) || VECTOR_REG_P (dst))
66795431 2458 return false;
2459
66795431 2460 /* Non-offsettable memory references cannot be split. */
2461 if ((GET_CODE (src) == MEM && !offsettable_memref_p (src))
2462 || (GET_CODE (dst) == MEM && !offsettable_memref_p (dst)))
2463 return false;
2464
2465 /* Moving the first subword must not clobber a register
2466 needed to move the second subword. */
2467 if (register_operand (dst, mode))
2468 {
2469 rtx subreg = operand_subword (dst, first_subword, 0, mode);
2470 if (reg_overlap_mentioned_p (subreg, src))
2471 return false;
2472 }
2473
2474 return true;
2475}
2476
74bdf297 2477/* Return true if it can be proven that [MEM1, MEM1 + SIZE]
2478 and [MEM2, MEM2 + SIZE] do overlap and false
2479 otherwise. */
2480
2481bool
2482s390_overlap_p (rtx mem1, rtx mem2, HOST_WIDE_INT size)
2483{
2484 rtx addr1, addr2, addr_delta;
2485 HOST_WIDE_INT delta;
2486
2487 if (GET_CODE (mem1) != MEM || GET_CODE (mem2) != MEM)
2488 return true;
2489
2490 if (size == 0)
2491 return false;
2492
2493 addr1 = XEXP (mem1, 0);
2494 addr2 = XEXP (mem2, 0);
2495
2496 addr_delta = simplify_binary_operation (MINUS, Pmode, addr2, addr1);
2497
2498 /* This overlapping check is used by peepholes merging memory block operations.
2499 Overlapping operations would otherwise be recognized by the S/390 hardware
ffead1ca 2500 and would fall back to a slower implementation. Allowing overlapping
74bdf297 2501 operations would lead to slow code but not to wrong code. Therefore we are
ffead1ca 2502 somewhat optimistic if we cannot prove that the memory blocks are
74bdf297 2503 overlapping.
2504 That's why we return false here although this may accept operations on
2505 overlapping memory areas. */
2506 if (!addr_delta || GET_CODE (addr_delta) != CONST_INT)
2507 return false;
2508
2509 delta = INTVAL (addr_delta);
2510
2511 if (delta == 0
2512 || (delta > 0 && delta < size)
2513 || (delta < 0 && -delta < size))
2514 return true;
2515
2516 return false;
2517}
2518
9dffd3ff 2519/* Check whether the address of memory reference MEM2 equals exactly
2520 the address of memory reference MEM1 plus DELTA. Return true if
2521 we can prove this to be the case, false otherwise. */
2522
2523bool
2524s390_offset_p (rtx mem1, rtx mem2, rtx delta)
2525{
2526 rtx addr1, addr2, addr_delta;
2527
2528 if (GET_CODE (mem1) != MEM || GET_CODE (mem2) != MEM)
2529 return false;
2530
2531 addr1 = XEXP (mem1, 0);
2532 addr2 = XEXP (mem2, 0);
2533
2534 addr_delta = simplify_binary_operation (MINUS, Pmode, addr2, addr1);
2535 if (!addr_delta || !rtx_equal_p (addr_delta, delta))
2536 return false;
2537
2538 return true;
2539}
2540
3e247a31 2541/* Expand logical operator CODE in mode MODE with operands OPERANDS. */
2542
2543void
3754d046 2544s390_expand_logical_operator (enum rtx_code code, machine_mode mode,
3e247a31 2545 rtx *operands)
2546{
3754d046 2547 machine_mode wmode = mode;
3e247a31 2548 rtx dst = operands[0];
2549 rtx src1 = operands[1];
2550 rtx src2 = operands[2];
2551 rtx op, clob, tem;
2552
2553 /* If we cannot handle the operation directly, use a temp register. */
2554 if (!s390_logical_operator_ok_p (operands))
2555 dst = gen_reg_rtx (mode);
2556
2557 /* QImode and HImode patterns make sense only if we have a destination
2558 in memory. Otherwise perform the operation in SImode. */
2559 if ((mode == QImode || mode == HImode) && GET_CODE (dst) != MEM)
2560 wmode = SImode;
2561
2562 /* Widen operands if required. */
2563 if (mode != wmode)
2564 {
2565 if (GET_CODE (dst) == SUBREG
2566 && (tem = simplify_subreg (wmode, dst, mode, 0)) != 0)
2567 dst = tem;
2568 else if (REG_P (dst))
2569 dst = gen_rtx_SUBREG (wmode, dst, 0);
2570 else
2571 dst = gen_reg_rtx (wmode);
2572
2573 if (GET_CODE (src1) == SUBREG
2574 && (tem = simplify_subreg (wmode, src1, mode, 0)) != 0)
2575 src1 = tem;
2576 else if (GET_MODE (src1) != VOIDmode)
2577 src1 = gen_rtx_SUBREG (wmode, force_reg (mode, src1), 0);
2578
2579 if (GET_CODE (src2) == SUBREG
2580 && (tem = simplify_subreg (wmode, src2, mode, 0)) != 0)
2581 src2 = tem;
2582 else if (GET_MODE (src2) != VOIDmode)
2583 src2 = gen_rtx_SUBREG (wmode, force_reg (mode, src2), 0);
2584 }
2585
2586 /* Emit the instruction. */
d1f9b275 2587 op = gen_rtx_SET (dst, gen_rtx_fmt_ee (code, wmode, src1, src2));
3e247a31 2588 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
2589 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
2590
2591 /* Fix up the destination if needed. */
2592 if (dst != operands[0])
2593 emit_move_insn (operands[0], gen_lowpart (mode, dst));
2594}
2595
2596/* Check whether OPERANDS are OK for a logical operation (AND, IOR, XOR). */
2597
2598bool
2599s390_logical_operator_ok_p (rtx *operands)
2600{
2601 /* If the destination operand is in memory, it needs to coincide
2602 with one of the source operands. After reload, it has to be
2603 the first source operand. */
2604 if (GET_CODE (operands[0]) == MEM)
2605 return rtx_equal_p (operands[0], operands[1])
2606 || (!reload_completed && rtx_equal_p (operands[0], operands[2]));
2607
2608 return true;
2609}
2610
3f56e755 2611/* Narrow logical operation CODE of memory operand MEMOP with immediate
2612 operand IMMOP to switch from SS to SI type instructions. */
2613
2614void
2615s390_narrow_logical_operator (enum rtx_code code, rtx *memop, rtx *immop)
2616{
2617 int def = code == AND ? -1 : 0;
2618 HOST_WIDE_INT mask;
2619 int part;
2620
2621 gcc_assert (GET_CODE (*memop) == MEM);
2622 gcc_assert (!MEM_VOLATILE_P (*memop));
2623
2624 mask = s390_extract_part (*immop, QImode, def);
2625 part = s390_single_part (*immop, GET_MODE (*memop), QImode, def);
2626 gcc_assert (part >= 0);
2627
2628 *memop = adjust_address (*memop, QImode, part);
2629 *immop = gen_int_mode (mask, QImode);
2630}
2631
2eb8fe23 2632
875862bf 2633/* How to allocate a 'struct machine_function'. */
2634
2635static struct machine_function *
2636s390_init_machine_status (void)
2637{
25a27413 2638 return ggc_cleared_alloc<machine_function> ();
875862bf 2639}
2640
4673c1a0 2641/* Map for smallest class containing reg regno. */
2642
c8834c5f 2643const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
76a4c804 2644{ GENERAL_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS, /* 0 */
2645 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS, /* 4 */
2646 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS, /* 8 */
2647 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS, /* 12 */
2648 FP_REGS, FP_REGS, FP_REGS, FP_REGS, /* 16 */
2649 FP_REGS, FP_REGS, FP_REGS, FP_REGS, /* 20 */
2650 FP_REGS, FP_REGS, FP_REGS, FP_REGS, /* 24 */
2651 FP_REGS, FP_REGS, FP_REGS, FP_REGS, /* 28 */
2652 ADDR_REGS, CC_REGS, ADDR_REGS, ADDR_REGS, /* 32 */
2653 ACCESS_REGS, ACCESS_REGS, VEC_REGS, VEC_REGS, /* 36 */
2654 VEC_REGS, VEC_REGS, VEC_REGS, VEC_REGS, /* 40 */
2655 VEC_REGS, VEC_REGS, VEC_REGS, VEC_REGS, /* 44 */
2656 VEC_REGS, VEC_REGS, VEC_REGS, VEC_REGS, /* 48 */
2657 VEC_REGS, VEC_REGS /* 52 */
4673c1a0 2658};
2659
71343e6b 2660/* Return attribute type of insn. */
2661
2662static enum attr_type
ed3e6e5d 2663s390_safe_attr_type (rtx_insn *insn)
71343e6b 2664{
2665 if (recog_memoized (insn) >= 0)
2666 return get_attr_type (insn);
2667 else
2668 return TYPE_NONE;
2669}
4673c1a0 2670
51aa1e9c 2671/* Return true if DISP is a valid short displacement. */
2672
e5537457 2673static bool
b40da9a7 2674s390_short_displacement (rtx disp)
51aa1e9c 2675{
2676 /* No displacement is OK. */
2677 if (!disp)
e5537457 2678 return true;
51aa1e9c 2679
a7b49046 2680 /* Without the long displacement facility we don't need to
2681 distingiush between long and short displacement. */
2682 if (!TARGET_LONG_DISPLACEMENT)
2683 return true;
2684
51aa1e9c 2685 /* Integer displacement in range. */
2686 if (GET_CODE (disp) == CONST_INT)
2687 return INTVAL (disp) >= 0 && INTVAL (disp) < 4096;
2688
2689 /* GOT offset is not OK, the GOT can be large. */
2690 if (GET_CODE (disp) == CONST
2691 && GET_CODE (XEXP (disp, 0)) == UNSPEC
a6e4e903 2692 && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOT
2693 || XINT (XEXP (disp, 0), 1) == UNSPEC_GOTNTPOFF))
e5537457 2694 return false;
51aa1e9c 2695
2696 /* All other symbolic constants are literal pool references,
2697 which are OK as the literal pool must be small. */
2698 if (GET_CODE (disp) == CONST)
e5537457 2699 return true;
51aa1e9c 2700
e5537457 2701 return false;
51aa1e9c 2702}
2703
875862bf 2704/* Decompose a RTL expression ADDR for a memory address into
2705 its components, returned in OUT.
a5004c3d 2706
e5537457 2707 Returns false if ADDR is not a valid memory address, true
875862bf 2708 otherwise. If OUT is NULL, don't return the components,
2709 but check for validity only.
a5004c3d 2710
875862bf 2711 Note: Only addresses in canonical form are recognized.
2712 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
2713 canonical form so that they will be recognized. */
64a1078f 2714
875862bf 2715static int
edd89d66 2716s390_decompose_address (rtx addr, struct s390_address *out)
875862bf 2717{
2718 HOST_WIDE_INT offset = 0;
2719 rtx base = NULL_RTX;
2720 rtx indx = NULL_RTX;
2721 rtx disp = NULL_RTX;
2722 rtx orig_disp;
e5537457 2723 bool pointer = false;
2724 bool base_ptr = false;
2725 bool indx_ptr = false;
05b58257 2726 bool literal_pool = false;
2727
2728 /* We may need to substitute the literal pool base register into the address
2729 below. However, at this point we do not know which register is going to
2730 be used as base, so we substitute the arg pointer register. This is going
2731 to be treated as holding a pointer below -- it shouldn't be used for any
2732 other purpose. */
2733 rtx fake_pool_base = gen_rtx_REG (Pmode, ARG_POINTER_REGNUM);
3f56e755 2734
875862bf 2735 /* Decompose address into base + index + displacement. */
3f56e755 2736
875862bf 2737 if (GET_CODE (addr) == REG || GET_CODE (addr) == UNSPEC)
2738 base = addr;
3f56e755 2739
875862bf 2740 else if (GET_CODE (addr) == PLUS)
6b1c8423 2741 {
875862bf 2742 rtx op0 = XEXP (addr, 0);
2743 rtx op1 = XEXP (addr, 1);
2744 enum rtx_code code0 = GET_CODE (op0);
2745 enum rtx_code code1 = GET_CODE (op1);
6b1c8423 2746
875862bf 2747 if (code0 == REG || code0 == UNSPEC)
2748 {
2749 if (code1 == REG || code1 == UNSPEC)
2750 {
2751 indx = op0; /* index + base */
2752 base = op1;
2753 }
6b1c8423 2754
875862bf 2755 else
2756 {
2757 base = op0; /* base + displacement */
2758 disp = op1;
2759 }
2760 }
a5004c3d 2761
875862bf 2762 else if (code0 == PLUS)
51aa1e9c 2763 {
875862bf 2764 indx = XEXP (op0, 0); /* index + base + disp */
2765 base = XEXP (op0, 1);
2766 disp = op1;
51aa1e9c 2767 }
51aa1e9c 2768
875862bf 2769 else
51aa1e9c 2770 {
e5537457 2771 return false;
51aa1e9c 2772 }
875862bf 2773 }
51aa1e9c 2774
875862bf 2775 else
2776 disp = addr; /* displacement */
51aa1e9c 2777
875862bf 2778 /* Extract integer part of displacement. */
2779 orig_disp = disp;
2780 if (disp)
2781 {
2782 if (GET_CODE (disp) == CONST_INT)
51aa1e9c 2783 {
875862bf 2784 offset = INTVAL (disp);
2785 disp = NULL_RTX;
51aa1e9c 2786 }
875862bf 2787 else if (GET_CODE (disp) == CONST
2788 && GET_CODE (XEXP (disp, 0)) == PLUS
2789 && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT)
2790 {
2791 offset = INTVAL (XEXP (XEXP (disp, 0), 1));
2792 disp = XEXP (XEXP (disp, 0), 0);
2793 }
2794 }
51aa1e9c 2795
875862bf 2796 /* Strip off CONST here to avoid special case tests later. */
2797 if (disp && GET_CODE (disp) == CONST)
2798 disp = XEXP (disp, 0);
63ebd742 2799
875862bf 2800 /* We can convert literal pool addresses to
2801 displacements by basing them off the base register. */
2802 if (disp && GET_CODE (disp) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (disp))
2803 {
58ad9b54 2804 if (base || indx)
2805 return false;
2806
2807 base = fake_pool_base, literal_pool = true;
875862bf 2808
2809 /* Mark up the displacement. */
2810 disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp),
2811 UNSPEC_LTREL_OFFSET);
51aa1e9c 2812 }
a5004c3d 2813
875862bf 2814 /* Validate base register. */
2815 if (base)
2816 {
2817 if (GET_CODE (base) == UNSPEC)
2818 switch (XINT (base, 1))
2819 {
2820 case UNSPEC_LTREF:
2821 if (!disp)
ffead1ca 2822 disp = gen_rtx_UNSPEC (Pmode,
875862bf 2823 gen_rtvec (1, XVECEXP (base, 0, 0)),
2824 UNSPEC_LTREL_OFFSET);
2825 else
e5537457 2826 return false;
a5004c3d 2827
05b58257 2828 base = XVECEXP (base, 0, 1);
875862bf 2829 break;
64a1078f 2830
875862bf 2831 case UNSPEC_LTREL_BASE:
05b58257 2832 if (XVECLEN (base, 0) == 1)
2833 base = fake_pool_base, literal_pool = true;
2834 else
2835 base = XVECEXP (base, 0, 1);
875862bf 2836 break;
64a1078f 2837
875862bf 2838 default:
e5537457 2839 return false;
875862bf 2840 }
64a1078f 2841
a25e52e9 2842 if (!REG_P (base) || GET_MODE (base) != Pmode)
e5537457 2843 return false;
875862bf 2844
05b58257 2845 if (REGNO (base) == STACK_POINTER_REGNUM
875862bf 2846 || REGNO (base) == FRAME_POINTER_REGNUM
2847 || ((reload_completed || reload_in_progress)
2848 && frame_pointer_needed
2849 && REGNO (base) == HARD_FRAME_POINTER_REGNUM)
2850 || REGNO (base) == ARG_POINTER_REGNUM
2851 || (flag_pic
2852 && REGNO (base) == PIC_OFFSET_TABLE_REGNUM))
e5537457 2853 pointer = base_ptr = true;
05b58257 2854
2855 if ((reload_completed || reload_in_progress)
2856 && base == cfun->machine->base_reg)
2857 pointer = base_ptr = literal_pool = true;
875862bf 2858 }
2859
2860 /* Validate index register. */
2861 if (indx)
64a1078f 2862 {
875862bf 2863 if (GET_CODE (indx) == UNSPEC)
2864 switch (XINT (indx, 1))
2865 {
2866 case UNSPEC_LTREF:
2867 if (!disp)
ffead1ca 2868 disp = gen_rtx_UNSPEC (Pmode,
875862bf 2869 gen_rtvec (1, XVECEXP (indx, 0, 0)),
2870 UNSPEC_LTREL_OFFSET);
2871 else
e5537457 2872 return false;
64a1078f 2873
05b58257 2874 indx = XVECEXP (indx, 0, 1);
875862bf 2875 break;
64a1078f 2876
875862bf 2877 case UNSPEC_LTREL_BASE:
05b58257 2878 if (XVECLEN (indx, 0) == 1)
2879 indx = fake_pool_base, literal_pool = true;
2880 else
2881 indx = XVECEXP (indx, 0, 1);
875862bf 2882 break;
64a1078f 2883
875862bf 2884 default:
e5537457 2885 return false;
875862bf 2886 }
64a1078f 2887
a25e52e9 2888 if (!REG_P (indx) || GET_MODE (indx) != Pmode)
e5537457 2889 return false;
64a1078f 2890
05b58257 2891 if (REGNO (indx) == STACK_POINTER_REGNUM
875862bf 2892 || REGNO (indx) == FRAME_POINTER_REGNUM
2893 || ((reload_completed || reload_in_progress)
2894 && frame_pointer_needed
2895 && REGNO (indx) == HARD_FRAME_POINTER_REGNUM)
2896 || REGNO (indx) == ARG_POINTER_REGNUM
2897 || (flag_pic
2898 && REGNO (indx) == PIC_OFFSET_TABLE_REGNUM))
e5537457 2899 pointer = indx_ptr = true;
05b58257 2900
2901 if ((reload_completed || reload_in_progress)
2902 && indx == cfun->machine->base_reg)
2903 pointer = indx_ptr = literal_pool = true;
875862bf 2904 }
f588eb9f 2905
875862bf 2906 /* Prefer to use pointer as base, not index. */
2907 if (base && indx && !base_ptr
2908 && (indx_ptr || (!REG_POINTER (base) && REG_POINTER (indx))))
2909 {
2910 rtx tmp = base;
2911 base = indx;
2912 indx = tmp;
2913 }
64a1078f 2914
875862bf 2915 /* Validate displacement. */
2916 if (!disp)
2917 {
ffead1ca 2918 /* If virtual registers are involved, the displacement will change later
2919 anyway as the virtual registers get eliminated. This could make a
2920 valid displacement invalid, but it is more likely to make an invalid
2921 displacement valid, because we sometimes access the register save area
119114cb 2922 via negative offsets to one of those registers.
875862bf 2923 Thus we don't check the displacement for validity here. If after
2924 elimination the displacement turns out to be invalid after all,
2925 this is fixed up by reload in any case. */
7b1bda1c 2926 /* LRA maintains always displacements up to date and we need to
2927 know the displacement is right during all LRA not only at the
2928 final elimination. */
2929 if (lra_in_progress
2930 || (base != arg_pointer_rtx
2931 && indx != arg_pointer_rtx
2932 && base != return_address_pointer_rtx
2933 && indx != return_address_pointer_rtx
2934 && base != frame_pointer_rtx
2935 && indx != frame_pointer_rtx
2936 && base != virtual_stack_vars_rtx
2937 && indx != virtual_stack_vars_rtx))
875862bf 2938 if (!DISP_IN_RANGE (offset))
e5537457 2939 return false;
875862bf 2940 }
2941 else
2942 {
2943 /* All the special cases are pointers. */
e5537457 2944 pointer = true;
64a1078f 2945
875862bf 2946 /* In the small-PIC case, the linker converts @GOT
2947 and @GOTNTPOFF offsets to possible displacements. */
2948 if (GET_CODE (disp) == UNSPEC
2949 && (XINT (disp, 1) == UNSPEC_GOT
2950 || XINT (disp, 1) == UNSPEC_GOTNTPOFF)
875862bf 2951 && flag_pic == 1)
2952 {
2953 ;
2954 }
64a1078f 2955
1ed7a160 2956 /* Accept pool label offsets. */
2957 else if (GET_CODE (disp) == UNSPEC
2958 && XINT (disp, 1) == UNSPEC_POOL_OFFSET)
2959 ;
64a1078f 2960
875862bf 2961 /* Accept literal pool references. */
2962 else if (GET_CODE (disp) == UNSPEC
2963 && XINT (disp, 1) == UNSPEC_LTREL_OFFSET)
2964 {
cf8ffe7d 2965 /* In case CSE pulled a non literal pool reference out of
2966 the pool we have to reject the address. This is
2967 especially important when loading the GOT pointer on non
2968 zarch CPUs. In this case the literal pool contains an lt
2969 relative offset to the _GLOBAL_OFFSET_TABLE_ label which
2970 will most likely exceed the displacement. */
2971 if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF
2972 || !CONSTANT_POOL_ADDRESS_P (XVECEXP (disp, 0, 0)))
2973 return false;
2974
875862bf 2975 orig_disp = gen_rtx_CONST (Pmode, disp);
2976 if (offset)
2977 {
2978 /* If we have an offset, make sure it does not
2979 exceed the size of the constant pool entry. */
2980 rtx sym = XVECEXP (disp, 0, 0);
2981 if (offset >= GET_MODE_SIZE (get_pool_mode (sym)))
e5537457 2982 return false;
64a1078f 2983
29c05e22 2984 orig_disp = plus_constant (Pmode, orig_disp, offset);
875862bf 2985 }
2986 }
2987
2988 else
e5537457 2989 return false;
64a1078f 2990 }
2991
875862bf 2992 if (!base && !indx)
e5537457 2993 pointer = true;
875862bf 2994
2995 if (out)
2996 {
2997 out->base = base;
2998 out->indx = indx;
2999 out->disp = orig_disp;
3000 out->pointer = pointer;
05b58257 3001 out->literal_pool = literal_pool;
875862bf 3002 }
3003
e5537457 3004 return true;
64a1078f 3005}
3006
2be7449b 3007/* Decompose a RTL expression OP for an address style operand into its
3008 components, and return the base register in BASE and the offset in
3009 OFFSET. While OP looks like an address it is never supposed to be
3010 used as such.
6d6be381 3011
2be7449b 3012 Return true if OP is a valid address operand, false if not. */
6d6be381 3013
3014bool
2be7449b 3015s390_decompose_addrstyle_without_index (rtx op, rtx *base,
3016 HOST_WIDE_INT *offset)
6d6be381 3017{
6191f2a0 3018 rtx off = NULL_RTX;
6d6be381 3019
6d6be381 3020 /* We can have an integer constant, an address register,
3021 or a sum of the two. */
6191f2a0 3022 if (CONST_SCALAR_INT_P (op))
6d6be381 3023 {
6191f2a0 3024 off = op;
6d6be381 3025 op = NULL_RTX;
3026 }
6191f2a0 3027 if (op && GET_CODE (op) == PLUS && CONST_SCALAR_INT_P (XEXP (op, 1)))
6d6be381 3028 {
6191f2a0 3029 off = XEXP (op, 1);
6d6be381 3030 op = XEXP (op, 0);
3031 }
3032 while (op && GET_CODE (op) == SUBREG)
3033 op = SUBREG_REG (op);
3034
3035 if (op && GET_CODE (op) != REG)
3036 return false;
3037
3038 if (offset)
6191f2a0 3039 {
3040 if (off == NULL_RTX)
3041 *offset = 0;
3042 else if (CONST_INT_P (off))
3043 *offset = INTVAL (off);
3044 else if (CONST_WIDE_INT_P (off))
3045 /* The offset will anyway be cut down to 12 bits so take just
3046 the lowest order chunk of the wide int. */
3047 *offset = CONST_WIDE_INT_ELT (off, 0);
3048 else
3049 gcc_unreachable ();
3050 }
6d6be381 3051 if (base)
3052 *base = op;
3053
3054 return true;
3055}
3056
3057
875862bf 3058/* Return true if CODE is a valid address without index. */
fab7adbf 3059
875862bf 3060bool
3061s390_legitimate_address_without_index_p (rtx op)
3062{
3063 struct s390_address addr;
3064
3065 if (!s390_decompose_address (XEXP (op, 0), &addr))
3066 return false;
3067 if (addr.indx)
3068 return false;
3069
3070 return true;
3071}
3072
59bc01b3 3073
2a672556 3074/* Return TRUE if ADDR is an operand valid for a load/store relative
3075 instruction. Be aware that the alignment of the operand needs to
3076 be checked separately.
3077 Valid addresses are single references or a sum of a reference and a
3078 constant integer. Return these parts in SYMREF and ADDEND. You can
3079 pass NULL in REF and/or ADDEND if you are not interested in these
3080 values. Literal pool references are *not* considered symbol
3081 references. */
875862bf 3082
a7b49046 3083static bool
2a672556 3084s390_loadrelative_operand_p (rtx addr, rtx *symref, HOST_WIDE_INT *addend)
875862bf 3085{
a7b49046 3086 HOST_WIDE_INT tmpaddend = 0;
875862bf 3087
a7b49046 3088 if (GET_CODE (addr) == CONST)
3089 addr = XEXP (addr, 0);
3090
3091 if (GET_CODE (addr) == PLUS)
875862bf 3092 {
2a672556 3093 if (!CONST_INT_P (XEXP (addr, 1)))
a7b49046 3094 return false;
875862bf 3095
2a672556 3096 tmpaddend = INTVAL (XEXP (addr, 1));
3097 addr = XEXP (addr, 0);
3098 }
62cb5855 3099
2a672556 3100 if ((GET_CODE (addr) == SYMBOL_REF && !CONSTANT_POOL_ADDRESS_P (addr))
3101 || (GET_CODE (addr) == UNSPEC
3102 && (XINT (addr, 1) == UNSPEC_GOTENT
3103 || (TARGET_CPU_ZARCH && XINT (addr, 1) == UNSPEC_PLT))))
3104 {
3105 if (symref)
3106 *symref = addr;
3107 if (addend)
3108 *addend = tmpaddend;
62cb5855 3109
2a672556 3110 return true;
3111 }
3112 return false;
62cb5855 3113}
a7b49046 3114
3115/* Return true if the address in OP is valid for constraint letter C
3116 if wrapped in a MEM rtx. Set LIT_POOL_OK to true if it literal
3117 pool MEMs should be accepted. Only the Q, R, S, T constraint
3118 letters are allowed for C. */
875862bf 3119
a7b49046 3120static int
3121s390_check_qrst_address (char c, rtx op, bool lit_pool_ok)
3122{
3123 struct s390_address addr;
3124 bool decomposed = false;
3125
ff03121f 3126 if (!address_operand (op, GET_MODE (op)))
3127 return 0;
3128
a7b49046 3129 /* This check makes sure that no symbolic address (except literal
3130 pool references) are accepted by the R or T constraints. */
2a672556 3131 if (s390_loadrelative_operand_p (op, NULL, NULL))
f3959569 3132 return 0;
3133
3134 /* Ensure literal pool references are only accepted if LIT_POOL_OK. */
3135 if (!lit_pool_ok)
875862bf 3136 {
a7b49046 3137 if (!s390_decompose_address (op, &addr))
875862bf 3138 return 0;
f3959569 3139 if (addr.literal_pool)
875862bf 3140 return 0;
a7b49046 3141 decomposed = true;
875862bf 3142 }
3143
7396c35d 3144 /* With reload, we sometimes get intermediate address forms that are
3145 actually invalid as-is, but we need to accept them in the most
3146 generic cases below ('R' or 'T'), since reload will in fact fix
3147 them up. LRA behaves differently here; we never see such forms,
3148 but on the other hand, we need to strictly reject every invalid
3149 address form. Perform this check right up front. */
3150 if (lra_in_progress)
3151 {
3152 if (!decomposed && !s390_decompose_address (op, &addr))
3153 return 0;
3154 decomposed = true;
3155 }
3156
875862bf 3157 switch (c)
3158 {
a7b49046 3159 case 'Q': /* no index short displacement */
3160 if (!decomposed && !s390_decompose_address (op, &addr))
875862bf 3161 return 0;
3162 if (addr.indx)
3163 return 0;
a7b49046 3164 if (!s390_short_displacement (addr.disp))
875862bf 3165 return 0;
a7b49046 3166 break;
875862bf 3167
a7b49046 3168 case 'R': /* with index short displacement */
875862bf 3169 if (TARGET_LONG_DISPLACEMENT)
3170 {
a7b49046 3171 if (!decomposed && !s390_decompose_address (op, &addr))
875862bf 3172 return 0;
3173 if (!s390_short_displacement (addr.disp))
3174 return 0;
3175 }
a7b49046 3176 /* Any invalid address here will be fixed up by reload,
3177 so accept it for the most generic constraint. */
875862bf 3178 break;
3179
a7b49046 3180 case 'S': /* no index long displacement */
a7b49046 3181 if (!decomposed && !s390_decompose_address (op, &addr))
875862bf 3182 return 0;
3183 if (addr.indx)
3184 return 0;
875862bf 3185 break;
3186
a7b49046 3187 case 'T': /* with index long displacement */
a7b49046 3188 /* Any invalid address here will be fixed up by reload,
3189 so accept it for the most generic constraint. */
875862bf 3190 break;
7396c35d 3191
a7b49046 3192 default:
3193 return 0;
3194 }
3195 return 1;
3196}
875862bf 3197
875862bf 3198
a7b49046 3199/* Evaluates constraint strings described by the regular expression
7396c35d 3200 ([A|B|Z](Q|R|S|T))|Y and returns 1 if OP is a valid operand for
a7b49046 3201 the constraint given in STR, or 0 else. */
3202
3203int
3204s390_mem_constraint (const char *str, rtx op)
3205{
3206 char c = str[0];
3207
3208 switch (c)
3209 {
3210 case 'A':
3211 /* Check for offsettable variants of memory constraints. */
3212 if (!MEM_P (op) || MEM_VOLATILE_P (op))
875862bf 3213 return 0;
a7b49046 3214 if ((reload_completed || reload_in_progress)
3215 ? !offsettable_memref_p (op) : !offsettable_nonstrict_memref_p (op))
e68d6a13 3216 return 0;
a7b49046 3217 return s390_check_qrst_address (str[1], XEXP (op, 0), true);
3218 case 'B':
3219 /* Check for non-literal-pool variants of memory constraints. */
3220 if (!MEM_P (op))
875862bf 3221 return 0;
a7b49046 3222 return s390_check_qrst_address (str[1], XEXP (op, 0), false);
3223 case 'Q':
3224 case 'R':
3225 case 'S':
3226 case 'T':
3227 if (GET_CODE (op) != MEM)
3228 return 0;
3229 return s390_check_qrst_address (c, XEXP (op, 0), true);
875862bf 3230 case 'Y':
6d6be381 3231 /* Simply check for the basic form of a shift count. Reload will
3232 take care of making sure we have a proper base register. */
2be7449b 3233 if (!s390_decompose_addrstyle_without_index (op, NULL, NULL))
6d6be381 3234 return 0;
3235 break;
a7b49046 3236 case 'Z':
3237 return s390_check_qrst_address (str[1], op, true);
875862bf 3238 default:
3239 return 0;
3240 }
875862bf 3241 return 1;
3242}
3243
59bc01b3 3244
59bc01b3 3245/* Evaluates constraint strings starting with letter O. Input
3246 parameter C is the second letter following the "O" in the constraint
3247 string. Returns 1 if VALUE meets the respective constraint and 0
3248 otherwise. */
875862bf 3249
e863b008 3250int
59bc01b3 3251s390_O_constraint_str (const char c, HOST_WIDE_INT value)
e863b008 3252{
59bc01b3 3253 if (!TARGET_EXTIMM)
3254 return 0;
e863b008 3255
59bc01b3 3256 switch (c)
e863b008 3257 {
59bc01b3 3258 case 's':
3259 return trunc_int_for_mode (value, SImode) == value;
3260
3261 case 'p':
3262 return value == 0
3263 || s390_single_part (GEN_INT (value), DImode, SImode, 0) == 1;
3264
3265 case 'n':
29847ec4 3266 return s390_single_part (GEN_INT (value - 1), DImode, SImode, -1) == 1;
59bc01b3 3267
e863b008 3268 default:
59bc01b3 3269 gcc_unreachable ();
e863b008 3270 }
3271}
3272
59bc01b3 3273
3274/* Evaluates constraint strings starting with letter N. Parameter STR
3275 contains the letters following letter "N" in the constraint string.
3276 Returns true if VALUE matches the constraint. */
e863b008 3277
875862bf 3278int
59bc01b3 3279s390_N_constraint_str (const char *str, HOST_WIDE_INT value)
875862bf 3280{
3754d046 3281 machine_mode mode, part_mode;
875862bf 3282 int def;
3283 int part, part_goal;
3284
875862bf 3285
59bc01b3 3286 if (str[0] == 'x')
3287 part_goal = -1;
3288 else
3289 part_goal = str[0] - '0';
875862bf 3290
59bc01b3 3291 switch (str[1])
3292 {
3293 case 'Q':
3294 part_mode = QImode;
875862bf 3295 break;
59bc01b3 3296 case 'H':
3297 part_mode = HImode;
163277cf 3298 break;
59bc01b3 3299 case 'S':
3300 part_mode = SImode;
3301 break;
3302 default:
3303 return 0;
3304 }
163277cf 3305
59bc01b3 3306 switch (str[2])
3307 {
3308 case 'H':
3309 mode = HImode;
3310 break;
3311 case 'S':
3312 mode = SImode;
3313 break;
3314 case 'D':
3315 mode = DImode;
3316 break;
3317 default:
3318 return 0;
3319 }
53239c89 3320
59bc01b3 3321 switch (str[3])
3322 {
3323 case '0':
3324 def = 0;
3325 break;
3326 case 'F':
3327 def = -1;
3328 break;
875862bf 3329 default:
3330 return 0;
3331 }
3332
59bc01b3 3333 if (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (part_mode))
3334 return 0;
3335
3336 part = s390_single_part (GEN_INT (value), mode, part_mode, def);
3337 if (part < 0)
3338 return 0;
3339 if (part_goal != -1 && part_goal != part)
3340 return 0;
3341
875862bf 3342 return 1;
3343}
3344
59bc01b3 3345
3346/* Returns true if the input parameter VALUE is a float zero. */
3347
3348int
3349s390_float_const_zero_p (rtx value)
3350{
3351 return (GET_MODE_CLASS (GET_MODE (value)) == MODE_FLOAT
3352 && value == CONST0_RTX (GET_MODE (value)));
3353}
3354
fa7a995b 3355/* Implement TARGET_REGISTER_MOVE_COST. */
3356
3357static int
5fe5762e 3358s390_register_move_cost (machine_mode mode,
fa7a995b 3359 reg_class_t from, reg_class_t to)
3360{
5fe5762e 3361 /* On s390, copy between fprs and gprs is expensive. */
3362
3363 /* It becomes somewhat faster having ldgr/lgdr. */
3364 if (TARGET_Z10 && GET_MODE_SIZE (mode) == 8)
3365 {
3366 /* ldgr is single cycle. */
3367 if (reg_classes_intersect_p (from, GENERAL_REGS)
3368 && reg_classes_intersect_p (to, FP_REGS))
3369 return 1;
3370 /* lgdr needs 3 cycles. */
3371 if (reg_classes_intersect_p (to, GENERAL_REGS)
3372 && reg_classes_intersect_p (from, FP_REGS))
3373 return 3;
3374 }
3375
3376 /* Otherwise copying is done via memory. */
3377 if ((reg_classes_intersect_p (from, GENERAL_REGS)
3378 && reg_classes_intersect_p (to, FP_REGS))
3379 || (reg_classes_intersect_p (from, FP_REGS)
3380 && reg_classes_intersect_p (to, GENERAL_REGS)))
fa7a995b 3381 return 10;
3382
3383 return 1;
3384}
3385
3386/* Implement TARGET_MEMORY_MOVE_COST. */
3387
3388static int
3754d046 3389s390_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
fa7a995b 3390 reg_class_t rclass ATTRIBUTE_UNUSED,
3391 bool in ATTRIBUTE_UNUSED)
3392{
9a071c9f 3393 return 2;
fa7a995b 3394}
59bc01b3 3395
875862bf 3396/* Compute a (partial) cost for rtx X. Return true if the complete
3397 cost has been computed, and false if subexpressions should be
016d030e 3398 scanned. In either case, *TOTAL contains the cost result. The
3399 initial value of *TOTAL is the default value computed by
3400 rtx_cost. It may be left unmodified. OUTER_CODE contains the
3401 code of the superexpression of x. */
875862bf 3402
3403static bool
5ae4887d 3404s390_rtx_costs (rtx x, machine_mode mode, int outer_code,
3405 int opno ATTRIBUTE_UNUSED,
20d892d1 3406 int *total, bool speed ATTRIBUTE_UNUSED)
fab7adbf 3407{
5ae4887d 3408 int code = GET_CODE (x);
fab7adbf 3409 switch (code)
3410 {
3411 case CONST:
fab7adbf 3412 case CONST_INT:
fab7adbf 3413 case LABEL_REF:
3414 case SYMBOL_REF:
3415 case CONST_DOUBLE:
ba0e61d6 3416 case CONST_WIDE_INT:
3f074425 3417 case MEM:
fab7adbf 3418 *total = 0;
3419 return true;
3420
c70e1aad 3421 case SET:
3422 {
3423 /* Without this a conditional move instruction would be
3424 accounted as 3 * COSTS_N_INSNS (set, if_then_else,
3425 comparison operator). That's a bit pessimistic. */
3426
3427 if (!TARGET_Z196 || GET_CODE (SET_SRC (x)) != IF_THEN_ELSE)
3428 return false;
3429
3430 rtx cond = XEXP (SET_SRC (x), 0);
3431
3432 if (!CC_REG_P (XEXP (cond, 0)) || !CONST_INT_P (XEXP (cond, 1)))
3433 return false;
3434
3435 /* It is going to be a load/store on condition. Make it
3436 slightly more expensive than a normal load. */
3437 *total = COSTS_N_INSNS (1) + 1;
3438
3439 rtx dst = SET_DEST (x);
3440 rtx then = XEXP (SET_SRC (x), 1);
3441 rtx els = XEXP (SET_SRC (x), 2);
3442
3443 /* It is a real IF-THEN-ELSE. An additional move will be
3444 needed to implement that. */
3445 if (reload_completed
3446 && !rtx_equal_p (dst, then)
3447 && !rtx_equal_p (dst, els))
3448 *total += COSTS_N_INSNS (1) / 2;
3449
3450 /* A minor penalty for constants we cannot directly handle. */
3451 if ((CONST_INT_P (then) || CONST_INT_P (els))
3452 && (!TARGET_Z13 || MEM_P (dst)
3453 || (CONST_INT_P (then) && !satisfies_constraint_K (then))
3454 || (CONST_INT_P (els) && !satisfies_constraint_K (els))))
3455 *total += COSTS_N_INSNS (1) / 2;
3456
3457 /* A store on condition can only handle register src operands. */
3458 if (MEM_P (dst) && (!REG_P (then) || !REG_P (els)))
3459 *total += COSTS_N_INSNS (1) / 2;
3460
3461 return true;
3462 }
02a8efd2 3463 case IOR:
3464 /* risbg */
3465 if (GET_CODE (XEXP (x, 0)) == AND
3466 && GET_CODE (XEXP (x, 1)) == ASHIFT
3467 && REG_P (XEXP (XEXP (x, 0), 0))
3468 && REG_P (XEXP (XEXP (x, 1), 0))
3469 && CONST_INT_P (XEXP (XEXP (x, 0), 1))
3470 && CONST_INT_P (XEXP (XEXP (x, 1), 1))
3471 && (UINTVAL (XEXP (XEXP (x, 0), 1)) ==
b422d8c0 3472 (HOST_WIDE_INT_1U << UINTVAL (XEXP (XEXP (x, 1), 1))) - 1))
02a8efd2 3473 {
3474 *total = COSTS_N_INSNS (2);
3475 return true;
3476 }
0f57593c 3477
3478 /* ~AND on a 128 bit mode. This can be done using a vector
3479 instruction. */
3480 if (TARGET_VXE
3481 && GET_CODE (XEXP (x, 0)) == NOT
3482 && GET_CODE (XEXP (x, 1)) == NOT
3483 && REG_P (XEXP (XEXP (x, 0), 0))
3484 && REG_P (XEXP (XEXP (x, 1), 0))
3485 && GET_MODE_SIZE (GET_MODE (XEXP (XEXP (x, 0), 0))) == 16
3486 && s390_hard_regno_mode_ok (VR0_REGNUM,
3487 GET_MODE (XEXP (XEXP (x, 0), 0))))
3488 {
3489 *total = COSTS_N_INSNS (1);
3490 return true;
3491 }
0903985d 3492 /* fallthrough */
fab7adbf 3493 case ASHIFT:
3494 case ASHIFTRT:
3495 case LSHIFTRT:
18925d38 3496 case ROTATE:
3497 case ROTATERT:
fab7adbf 3498 case AND:
fab7adbf 3499 case XOR:
fab7adbf 3500 case NEG:
3501 case NOT:
3502 *total = COSTS_N_INSNS (1);
18925d38 3503 return false;
fab7adbf 3504
9cd3f3e6 3505 case PLUS:
3506 case MINUS:
9cd3f3e6 3507 *total = COSTS_N_INSNS (1);
3508 return false;
3509
ffead1ca 3510 case MULT:
5ae4887d 3511 switch (mode)
18925d38 3512 {
3513 case SImode:
9cd3f3e6 3514 {
18925d38 3515 rtx left = XEXP (x, 0);
3516 rtx right = XEXP (x, 1);
3517 if (GET_CODE (right) == CONST_INT
cb888f33 3518 && CONST_OK_FOR_K (INTVAL (right)))
18925d38 3519 *total = s390_cost->mhi;
3520 else if (GET_CODE (left) == SIGN_EXTEND)
3521 *total = s390_cost->mh;
3522 else
3523 *total = s390_cost->ms; /* msr, ms, msy */
3524 break;
3525 }
3526 case DImode:
3527 {
3528 rtx left = XEXP (x, 0);
3529 rtx right = XEXP (x, 1);
b5fdc416 3530 if (TARGET_ZARCH)
18925d38 3531 {
3532 if (GET_CODE (right) == CONST_INT
cb888f33 3533 && CONST_OK_FOR_K (INTVAL (right)))
18925d38 3534 *total = s390_cost->mghi;
3535 else if (GET_CODE (left) == SIGN_EXTEND)
3536 *total = s390_cost->msgf;
3537 else
3538 *total = s390_cost->msg; /* msgr, msg */
3539 }
3540 else /* TARGET_31BIT */
3541 {
3542 if (GET_CODE (left) == SIGN_EXTEND
3543 && GET_CODE (right) == SIGN_EXTEND)
3544 /* mulsidi case: mr, m */
3545 *total = s390_cost->m;
9cd3f3e6 3546 else if (GET_CODE (left) == ZERO_EXTEND
3547 && GET_CODE (right) == ZERO_EXTEND
3548 && TARGET_CPU_ZARCH)
3549 /* umulsidi case: ml, mlr */
3550 *total = s390_cost->ml;
18925d38 3551 else
3552 /* Complex calculation is required. */
3553 *total = COSTS_N_INSNS (40);
3554 }
3555 break;
3556 }
3557 case SFmode:
3558 case DFmode:
3559 *total = s390_cost->mult_df;
3560 break;
429f9fdb 3561 case TFmode:
3562 *total = s390_cost->mxbr;
3563 break;
18925d38 3564 default:
3565 return false;
3566 }
3567 return false;
fab7adbf 3568
81470015 3569 case FMA:
5ae4887d 3570 switch (mode)
81470015 3571 {
3572 case DFmode:
3573 *total = s390_cost->madbr;
3574 break;
3575 case SFmode:
3576 *total = s390_cost->maebr;
3577 break;
3578 default:
3579 return false;
3580 }
3581 /* Negate in the third argument is free: FMSUB. */
3582 if (GET_CODE (XEXP (x, 2)) == NEG)
3583 {
5ae4887d 3584 *total += (rtx_cost (XEXP (x, 0), mode, FMA, 0, speed)
3585 + rtx_cost (XEXP (x, 1), mode, FMA, 1, speed)
3586 + rtx_cost (XEXP (XEXP (x, 2), 0), mode, FMA, 2, speed));
81470015 3587 return true;
3588 }
3589 return false;
3590
3f074425 3591 case UDIV:
3592 case UMOD:
5ae4887d 3593 if (mode == TImode) /* 128 bit division */
3f074425 3594 *total = s390_cost->dlgr;
5ae4887d 3595 else if (mode == DImode)
3f074425 3596 {
3597 rtx right = XEXP (x, 1);
3598 if (GET_CODE (right) == ZERO_EXTEND) /* 64 by 32 bit division */
3599 *total = s390_cost->dlr;
3600 else /* 64 by 64 bit division */
3601 *total = s390_cost->dlgr;
3602 }
5ae4887d 3603 else if (mode == SImode) /* 32 bit division */
3f074425 3604 *total = s390_cost->dlr;
3605 return false;
3606
fab7adbf 3607 case DIV:
3f074425 3608 case MOD:
5ae4887d 3609 if (mode == DImode)
3f074425 3610 {
3611 rtx right = XEXP (x, 1);
3612 if (GET_CODE (right) == ZERO_EXTEND) /* 64 by 32 bit division */
b5fdc416 3613 if (TARGET_ZARCH)
3f074425 3614 *total = s390_cost->dsgfr;
3615 else
3616 *total = s390_cost->dr;
3617 else /* 64 by 64 bit division */
3618 *total = s390_cost->dsgr;
3619 }
5ae4887d 3620 else if (mode == SImode) /* 32 bit division */
3f074425 3621 *total = s390_cost->dlr;
5ae4887d 3622 else if (mode == SFmode)
260075cc 3623 {
095798e3 3624 *total = s390_cost->debr;
260075cc 3625 }
5ae4887d 3626 else if (mode == DFmode)
260075cc 3627 {
095798e3 3628 *total = s390_cost->ddbr;
260075cc 3629 }
5ae4887d 3630 else if (mode == TFmode)
429f9fdb 3631 {
095798e3 3632 *total = s390_cost->dxbr;
429f9fdb 3633 }
18925d38 3634 return false;
3635
9cd3f3e6 3636 case SQRT:
5ae4887d 3637 if (mode == SFmode)
9cd3f3e6 3638 *total = s390_cost->sqebr;
5ae4887d 3639 else if (mode == DFmode)
9cd3f3e6 3640 *total = s390_cost->sqdbr;
429f9fdb 3641 else /* TFmode */
3642 *total = s390_cost->sqxbr;
9cd3f3e6 3643 return false;
3644
18925d38 3645 case SIGN_EXTEND:
9cd3f3e6 3646 case ZERO_EXTEND:
3f074425 3647 if (outer_code == MULT || outer_code == DIV || outer_code == MOD
3648 || outer_code == PLUS || outer_code == MINUS
3649 || outer_code == COMPARE)
18925d38 3650 *total = 0;
3651 return false;
fab7adbf 3652
3f074425 3653 case COMPARE:
3654 *total = COSTS_N_INSNS (1);
3655 if (GET_CODE (XEXP (x, 0)) == AND
3656 && GET_CODE (XEXP (x, 1)) == CONST_INT
3657 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
3658 {
3659 rtx op0 = XEXP (XEXP (x, 0), 0);
3660 rtx op1 = XEXP (XEXP (x, 0), 1);
3661 rtx op2 = XEXP (x, 1);
3662
3663 if (memory_operand (op0, GET_MODE (op0))
3664 && s390_tm_ccmode (op1, op2, 0) != VOIDmode)
3665 return true;
3666 if (register_operand (op0, GET_MODE (op0))
3667 && s390_tm_ccmode (op1, op2, 1) != VOIDmode)
3668 return true;
3669 }
3670 return false;
3671
fab7adbf 3672 default:
3673 return false;
3674 }
3675}
3676
ee9c19ee 3677/* Return the cost of an address rtx ADDR. */
3678
ec0457a8 3679static int
3754d046 3680s390_address_cost (rtx addr, machine_mode mode ATTRIBUTE_UNUSED,
d9c5e5f4 3681 addr_space_t as ATTRIBUTE_UNUSED,
3682 bool speed ATTRIBUTE_UNUSED)
ee9c19ee 3683{
3684 struct s390_address ad;
3685 if (!s390_decompose_address (addr, &ad))
3686 return 1000;
3687
3688 return ad.indx? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
3689}
3690
292e369f 3691/* Implement targetm.vectorize.builtin_vectorization_cost. */
3692static int
3693s390_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3694 tree vectype,
3695 int misalign ATTRIBUTE_UNUSED)
3696{
3697 switch (type_of_cost)
3698 {
3699 case scalar_stmt:
3700 case scalar_load:
3701 case scalar_store:
3702 case vector_stmt:
3703 case vector_load:
3704 case vector_store:
3705 case vec_to_scalar:
3706 case scalar_to_vec:
3707 case cond_branch_not_taken:
3708 case vec_perm:
3709 case vec_promote_demote:
3710 case unaligned_load:
3711 case unaligned_store:
3712 return 1;
3713
3714 case cond_branch_taken:
3715 return 3;
3716
3717 case vec_construct:
3718 return TYPE_VECTOR_SUBPARTS (vectype) - 1;
3719
3720 default:
3721 gcc_unreachable ();
3722 }
3723}
3724
be00aaa8 3725/* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
3726 otherwise return 0. */
3727
3728int
edd89d66 3729tls_symbolic_operand (rtx op)
be00aaa8 3730{
be00aaa8 3731 if (GET_CODE (op) != SYMBOL_REF)
3732 return 0;
a3e33162 3733 return SYMBOL_REF_TLS_MODEL (op);
be00aaa8 3734}
4673c1a0 3735\f
923cf36d 3736/* Split DImode access register reference REG (on 64-bit) into its constituent
3737 low and high parts, and store them into LO and HI. Note that gen_lowpart/
3738 gen_highpart cannot be used as they assume all registers are word-sized,
3739 while our access registers have only half that size. */
3740
3741void
3742s390_split_access_reg (rtx reg, rtx *lo, rtx *hi)
3743{
3744 gcc_assert (TARGET_64BIT);
3745 gcc_assert (ACCESS_REG_P (reg));
3746 gcc_assert (GET_MODE (reg) == DImode);
3747 gcc_assert (!(REGNO (reg) & 1));
3748
3749 *lo = gen_rtx_REG (SImode, REGNO (reg) + 1);
3750 *hi = gen_rtx_REG (SImode, REGNO (reg));
3751}
4673c1a0 3752
56769981 3753/* Return true if OP contains a symbol reference */
4673c1a0 3754
e5537457 3755bool
b40da9a7 3756symbolic_reference_mentioned_p (rtx op)
4673c1a0 3757{
edd89d66 3758 const char *fmt;
3759 int i;
4673c1a0 3760
3761 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
3762 return 1;
3763
3764 fmt = GET_RTX_FORMAT (GET_CODE (op));
3765 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
3766 {
3767 if (fmt[i] == 'E')
3768 {
edd89d66 3769 int j;
4673c1a0 3770
3771 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
3772 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
3773 return 1;
3774 }
3775
3776 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
3777 return 1;
3778 }
3779
3780 return 0;
3781}
3782
be00aaa8 3783/* Return true if OP contains a reference to a thread-local symbol. */
3784
e5537457 3785bool
b40da9a7 3786tls_symbolic_reference_mentioned_p (rtx op)
be00aaa8 3787{
edd89d66 3788 const char *fmt;
3789 int i;
be00aaa8 3790
3791 if (GET_CODE (op) == SYMBOL_REF)
3792 return tls_symbolic_operand (op);
3793
3794 fmt = GET_RTX_FORMAT (GET_CODE (op));
3795 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
3796 {
3797 if (fmt[i] == 'E')
3798 {
edd89d66 3799 int j;
be00aaa8 3800
3801 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
3802 if (tls_symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
e5537457 3803 return true;
be00aaa8 3804 }
3805
3806 else if (fmt[i] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op, i)))
e5537457 3807 return true;
be00aaa8 3808 }
3809
e5537457 3810 return false;
be00aaa8 3811}
3812
4673c1a0 3813
f81e845f 3814/* Return true if OP is a legitimate general operand when
3815 generating PIC code. It is given that flag_pic is on
ba0e61d6 3816 and that OP satisfies CONSTANT_P. */
56769981 3817
4673c1a0 3818int
edd89d66 3819legitimate_pic_operand_p (rtx op)
4673c1a0 3820{
8b4a4127 3821 /* Accept all non-symbolic constants. */
4673c1a0 3822 if (!SYMBOLIC_CONST (op))
3823 return 1;
3824
f81e845f 3825 /* Reject everything else; must be handled
be00aaa8 3826 via emit_symbolic_move. */
4673c1a0 3827 return 0;
3828}
3829
56769981 3830/* Returns true if the constant value OP is a legitimate general operand.
ba0e61d6 3831 It is given that OP satisfies CONSTANT_P. */
56769981 3832
ca316360 3833static bool
3754d046 3834s390_legitimate_constant_p (machine_mode mode, rtx op)
4673c1a0 3835{
abf3beed 3836 if (TARGET_VX && VECTOR_MODE_P (mode) && GET_CODE (op) == CONST_VECTOR)
76a4c804 3837 {
3838 if (GET_MODE_SIZE (mode) != 16)
3839 return 0;
3840
80fc7f56 3841 if (!satisfies_constraint_j00 (op)
3842 && !satisfies_constraint_jm1 (op)
3843 && !satisfies_constraint_jKK (op)
3844 && !satisfies_constraint_jxx (op)
3845 && !satisfies_constraint_jyy (op))
76a4c804 3846 return 0;
3847 }
3848
8b4a4127 3849 /* Accept all non-symbolic constants. */
4673c1a0 3850 if (!SYMBOLIC_CONST (op))
3851 return 1;
3852
be00aaa8 3853 /* Accept immediate LARL operands. */
ca316360 3854 if (TARGET_CPU_ZARCH && larl_operand (op, mode))
be00aaa8 3855 return 1;
3856
3857 /* Thread-local symbols are never legal constants. This is
3858 so that emit_call knows that computing such addresses
3859 might require a function call. */
3860 if (TLS_SYMBOLIC_CONST (op))
3861 return 0;
3862
4673c1a0 3863 /* In the PIC case, symbolic constants must *not* be
3864 forced into the literal pool. We accept them here,
be00aaa8 3865 so that they will be handled by emit_symbolic_move. */
4673c1a0 3866 if (flag_pic)
3867 return 1;
3868
4673c1a0 3869 /* All remaining non-PIC symbolic constants are
3870 forced into the literal pool. */
3871 return 0;
3872}
3873
be00aaa8 3874/* Determine if it's legal to put X into the constant pool. This
3875 is not possible if X contains the address of a symbol that is
3876 not constant (TLS) or not known at final link time (PIC). */
3877
3878static bool
3754d046 3879s390_cannot_force_const_mem (machine_mode mode, rtx x)
be00aaa8 3880{
3881 switch (GET_CODE (x))
3882 {
3883 case CONST_INT:
3884 case CONST_DOUBLE:
ba0e61d6 3885 case CONST_WIDE_INT:
76a4c804 3886 case CONST_VECTOR:
be00aaa8 3887 /* Accept all non-symbolic constants. */
3888 return false;
3889
3890 case LABEL_REF:
3891 /* Labels are OK iff we are non-PIC. */
3892 return flag_pic != 0;
3893
3894 case SYMBOL_REF:
3895 /* 'Naked' TLS symbol references are never OK,
3896 non-TLS symbols are OK iff we are non-PIC. */
3897 if (tls_symbolic_operand (x))
3898 return true;
3899 else
3900 return flag_pic != 0;
3901
3902 case CONST:
7d7d7bd2 3903 return s390_cannot_force_const_mem (mode, XEXP (x, 0));
be00aaa8 3904 case PLUS:
3905 case MINUS:
7d7d7bd2 3906 return s390_cannot_force_const_mem (mode, XEXP (x, 0))
3907 || s390_cannot_force_const_mem (mode, XEXP (x, 1));
be00aaa8 3908
3909 case UNSPEC:
3910 switch (XINT (x, 1))
3911 {
3912 /* Only lt-relative or GOT-relative UNSPECs are OK. */
12ef3745 3913 case UNSPEC_LTREL_OFFSET:
3914 case UNSPEC_GOT:
3915 case UNSPEC_GOTOFF:
3916 case UNSPEC_PLTOFF:
be00aaa8 3917 case UNSPEC_TLSGD:
3918 case UNSPEC_TLSLDM:
3919 case UNSPEC_NTPOFF:
3920 case UNSPEC_DTPOFF:
3921 case UNSPEC_GOTNTPOFF:
3922 case UNSPEC_INDNTPOFF:
3923 return false;
3924
d345b493 3925 /* If the literal pool shares the code section, be put
3926 execute template placeholders into the pool as well. */
3927 case UNSPEC_INSN:
3928 return TARGET_CPU_ZARCH;
3929
be00aaa8 3930 default:
3931 return true;
3932 }
3933 break;
3934
3935 default:
32eda510 3936 gcc_unreachable ();
be00aaa8 3937 }
3938}
3939
8b4a4127 3940/* Returns true if the constant value OP is a legitimate general
f81e845f 3941 operand during and after reload. The difference to
8b4a4127 3942 legitimate_constant_p is that this function will not accept
3943 a constant that would need to be forced to the literal pool
33d033da 3944 before it can be used as operand.
3945 This function accepts all constants which can be loaded directly
3946 into a GPR. */
8b4a4127 3947
e5537457 3948bool
edd89d66 3949legitimate_reload_constant_p (rtx op)
8b4a4127 3950{
51aa1e9c 3951 /* Accept la(y) operands. */
f81e845f 3952 if (GET_CODE (op) == CONST_INT
51aa1e9c 3953 && DISP_IN_RANGE (INTVAL (op)))
e5537457 3954 return true;
51aa1e9c 3955
163277cf 3956 /* Accept l(g)hi/l(g)fi operands. */
8b4a4127 3957 if (GET_CODE (op) == CONST_INT
163277cf 3958 && (CONST_OK_FOR_K (INTVAL (op)) || CONST_OK_FOR_Os (INTVAL (op))))
e5537457 3959 return true;
8b4a4127 3960
3961 /* Accept lliXX operands. */
dafc8d45 3962 if (TARGET_ZARCH
53239c89 3963 && GET_CODE (op) == CONST_INT
3964 && trunc_int_for_mode (INTVAL (op), word_mode) == INTVAL (op)
3965 && s390_single_part (op, word_mode, HImode, 0) >= 0)
e5537457 3966 return true;
8b4a4127 3967
163277cf 3968 if (TARGET_EXTIMM
3969 && GET_CODE (op) == CONST_INT
3970 && trunc_int_for_mode (INTVAL (op), word_mode) == INTVAL (op)
3971 && s390_single_part (op, word_mode, SImode, 0) >= 0)
3972 return true;
3973
8b4a4127 3974 /* Accept larl operands. */
dafc8d45 3975 if (TARGET_CPU_ZARCH
8b4a4127 3976 && larl_operand (op, VOIDmode))
e5537457 3977 return true;
8b4a4127 3978
70037005 3979 /* Accept floating-point zero operands that fit into a single GPR. */
3980 if (GET_CODE (op) == CONST_DOUBLE
3981 && s390_float_const_zero_p (op)
3982 && GET_MODE_SIZE (GET_MODE (op)) <= UNITS_PER_WORD)
3983 return true;
3984
53239c89 3985 /* Accept double-word operands that can be split. */
ba0e61d6 3986 if (GET_CODE (op) == CONST_WIDE_INT
3987 || (GET_CODE (op) == CONST_INT
3988 && trunc_int_for_mode (INTVAL (op), word_mode) != INTVAL (op)))
53239c89 3989 {
3754d046 3990 machine_mode dword_mode = word_mode == SImode ? DImode : TImode;
53239c89 3991 rtx hi = operand_subword (op, 0, 0, dword_mode);
3992 rtx lo = operand_subword (op, 1, 0, dword_mode);
3993 return legitimate_reload_constant_p (hi)
3994 && legitimate_reload_constant_p (lo);
3995 }
3996
8b4a4127 3997 /* Everything else cannot be handled without reload. */
e5537457 3998 return false;
8b4a4127 3999}
4000
33d033da 4001/* Returns true if the constant value OP is a legitimate fp operand
4002 during and after reload.
4003 This function accepts all constants which can be loaded directly
4004 into an FPR. */
4005
4006static bool
4007legitimate_reload_fp_constant_p (rtx op)
4008{
4009 /* Accept floating-point zero operands if the load zero instruction
81769881 4010 can be used. Prior to z196 the load fp zero instruction caused a
4011 performance penalty if the result is used as BFP number. */
33d033da 4012 if (TARGET_Z196
4013 && GET_CODE (op) == CONST_DOUBLE
4014 && s390_float_const_zero_p (op))
4015 return true;
4016
4017 return false;
4018}
4019
76a4c804 4020/* Returns true if the constant value OP is a legitimate vector operand
4021 during and after reload.
4022 This function accepts all constants which can be loaded directly
4023 into an VR. */
4024
4025static bool
4026legitimate_reload_vector_constant_p (rtx op)
4027{
76a4c804 4028 if (TARGET_VX && GET_MODE_SIZE (GET_MODE (op)) == 16
80fc7f56 4029 && (satisfies_constraint_j00 (op)
4030 || satisfies_constraint_jm1 (op)
4031 || satisfies_constraint_jKK (op)
4032 || satisfies_constraint_jxx (op)
4033 || satisfies_constraint_jyy (op)))
76a4c804 4034 return true;
4035
4036 return false;
4037}
4038
8deb3959 4039/* Given an rtx OP being reloaded into a reg required to be in class RCLASS,
8b4a4127 4040 return the class of reg to actually use. */
4041
3359ccfd 4042static reg_class_t
4043s390_preferred_reload_class (rtx op, reg_class_t rclass)
8b4a4127 4044{
8b4a4127 4045 switch (GET_CODE (op))
4046 {
70037005 4047 /* Constants we cannot reload into general registers
4048 must be forced into the literal pool. */
76a4c804 4049 case CONST_VECTOR:
8b4a4127 4050 case CONST_DOUBLE:
4051 case CONST_INT:
ba0e61d6 4052 case CONST_WIDE_INT:
70037005 4053 if (reg_class_subset_p (GENERAL_REGS, rclass)
4054 && legitimate_reload_constant_p (op))
4055 return GENERAL_REGS;
4056 else if (reg_class_subset_p (ADDR_REGS, rclass)
4057 && legitimate_reload_constant_p (op))
4058 return ADDR_REGS;
33d033da 4059 else if (reg_class_subset_p (FP_REGS, rclass)
4060 && legitimate_reload_fp_constant_p (op))
4061 return FP_REGS;
76a4c804 4062 else if (reg_class_subset_p (VEC_REGS, rclass)
4063 && legitimate_reload_vector_constant_p (op))
4064 return VEC_REGS;
4065
33d033da 4066 return NO_REGS;
8b4a4127 4067
4068 /* If a symbolic constant or a PLUS is reloaded,
0b300c86 4069 it is most likely being used as an address, so
4070 prefer ADDR_REGS. If 'class' is not a superset
4071 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
de47476b 4072 case CONST:
37c55f71 4073 /* Symrefs cannot be pushed into the literal pool with -fPIC
4074 so we *MUST NOT* return NO_REGS for these cases
4075 (s390_cannot_force_const_mem will return true).
4076
4077 On the other hand we MUST return NO_REGS for symrefs with
4078 invalid addend which might have been pushed to the literal
4079 pool (no -fPIC). Usually we would expect them to be
4080 handled via secondary reload but this does not happen if
4081 they are used as literal pool slot replacement in reload
4082 inheritance (see emit_input_reload_insns). */
de47476b 4083 if (TARGET_CPU_ZARCH
4084 && GET_CODE (XEXP (op, 0)) == PLUS
4085 && GET_CODE (XEXP (XEXP(op, 0), 0)) == SYMBOL_REF
4086 && GET_CODE (XEXP (XEXP(op, 0), 1)) == CONST_INT)
4087 {
37c55f71 4088 if (flag_pic && reg_class_subset_p (ADDR_REGS, rclass))
de47476b 4089 return ADDR_REGS;
4090 else
4091 return NO_REGS;
4092 }
4093 /* fallthrough */
8b4a4127 4094 case LABEL_REF:
4095 case SYMBOL_REF:
08d88e72 4096 if (!legitimate_reload_constant_p (op))
4097 return NO_REGS;
4098 /* fallthrough */
4099 case PLUS:
4100 /* load address will be used. */
8deb3959 4101 if (reg_class_subset_p (ADDR_REGS, rclass))
08d88e72 4102 return ADDR_REGS;
0b300c86 4103 else
4104 return NO_REGS;
8b4a4127 4105
4106 default:
4107 break;
4108 }
4109
8deb3959 4110 return rclass;
8b4a4127 4111}
4673c1a0 4112
e68d6a13 4113/* Return true if ADDR is SYMBOL_REF + addend with addend being a
4114 multiple of ALIGNMENT and the SYMBOL_REF being naturally
4115 aligned. */
4116
4117bool
4118s390_check_symref_alignment (rtx addr, HOST_WIDE_INT alignment)
4119{
4120 HOST_WIDE_INT addend;
4121 rtx symref;
4122
78affa36 4123 /* The "required alignment" might be 0 (e.g. for certain structs
4124 accessed via BLKmode). Early abort in this case, as well as when
4125 an alignment > 8 is required. */
4126 if (alignment < 2 || alignment > 8)
4127 return false;
4128
2a672556 4129 if (!s390_loadrelative_operand_p (addr, &symref, &addend))
4130 return false;
62cb5855 4131
2a672556 4132 if (addend & (alignment - 1))
e68d6a13 4133 return false;
4134
78affa36 4135 if (GET_CODE (symref) == SYMBOL_REF)
4136 {
4137 /* We have load-relative instructions for 2-byte, 4-byte, and
4138 8-byte alignment so allow only these. */
4139 switch (alignment)
4140 {
4141 case 8: return !SYMBOL_FLAG_NOTALIGN8_P (symref);
4142 case 4: return !SYMBOL_FLAG_NOTALIGN4_P (symref);
4143 case 2: return !SYMBOL_FLAG_NOTALIGN2_P (symref);
4144 default: return false;
4145 }
4146 }
2a672556 4147
4148 if (GET_CODE (symref) == UNSPEC
4149 && alignment <= UNITS_PER_LONG)
4150 return true;
4151
4152 return false;
e68d6a13 4153}
4154
4155/* ADDR is moved into REG using larl. If ADDR isn't a valid larl
4156 operand SCRATCH is used to reload the even part of the address and
4157 adding one. */
4158
4159void
4160s390_reload_larl_operand (rtx reg, rtx addr, rtx scratch)
4161{
4162 HOST_WIDE_INT addend;
4163 rtx symref;
4164
2a672556 4165 if (!s390_loadrelative_operand_p (addr, &symref, &addend))
e68d6a13 4166 gcc_unreachable ();
4167
4168 if (!(addend & 1))
4169 /* Easy case. The addend is even so larl will do fine. */
4170 emit_move_insn (reg, addr);
4171 else
4172 {
4173 /* We can leave the scratch register untouched if the target
4174 register is a valid base register. */
4175 if (REGNO (reg) < FIRST_PSEUDO_REGISTER
4176 && REGNO_REG_CLASS (REGNO (reg)) == ADDR_REGS)
4177 scratch = reg;
4178
4179 gcc_assert (REGNO (scratch) < FIRST_PSEUDO_REGISTER);
4180 gcc_assert (REGNO_REG_CLASS (REGNO (scratch)) == ADDR_REGS);
4181
4182 if (addend != 1)
4183 emit_move_insn (scratch,
4184 gen_rtx_CONST (Pmode,
4185 gen_rtx_PLUS (Pmode, symref,
4186 GEN_INT (addend - 1))));
4187 else
4188 emit_move_insn (scratch, symref);
4189
4190 /* Increment the address using la in order to avoid clobbering cc. */
de47476b 4191 s390_load_address (reg, gen_rtx_PLUS (Pmode, scratch, const1_rtx));
e68d6a13 4192 }
4193}
4194
4195/* Generate what is necessary to move between REG and MEM using
4196 SCRATCH. The direction is given by TOMEM. */
4197
4198void
4199s390_reload_symref_address (rtx reg, rtx mem, rtx scratch, bool tomem)
4200{
4201 /* Reload might have pulled a constant out of the literal pool.
4202 Force it back in. */
4203 if (CONST_INT_P (mem) || GET_CODE (mem) == CONST_DOUBLE
ba0e61d6 4204 || GET_CODE (mem) == CONST_WIDE_INT
76a4c804 4205 || GET_CODE (mem) == CONST_VECTOR
e68d6a13 4206 || GET_CODE (mem) == CONST)
4207 mem = force_const_mem (GET_MODE (reg), mem);
4208
4209 gcc_assert (MEM_P (mem));
4210
4211 /* For a load from memory we can leave the scratch register
4212 untouched if the target register is a valid base register. */
4213 if (!tomem
4214 && REGNO (reg) < FIRST_PSEUDO_REGISTER
4215 && REGNO_REG_CLASS (REGNO (reg)) == ADDR_REGS
4216 && GET_MODE (reg) == GET_MODE (scratch))
4217 scratch = reg;
4218
4219 /* Load address into scratch register. Since we can't have a
4220 secondary reload for a secondary reload we have to cover the case
4221 where larl would need a secondary reload here as well. */
4222 s390_reload_larl_operand (scratch, XEXP (mem, 0), scratch);
4223
4224 /* Now we can use a standard load/store to do the move. */
4225 if (tomem)
4226 emit_move_insn (replace_equiv_address (mem, scratch), reg);
4227 else
4228 emit_move_insn (reg, replace_equiv_address (mem, scratch));
4229}
4230
328d5423 4231/* Inform reload about cases where moving X with a mode MODE to a register in
8deb3959 4232 RCLASS requires an extra scratch or immediate register. Return the class
328d5423 4233 needed for the immediate register. */
429f9fdb 4234
964229b7 4235static reg_class_t
4236s390_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i,
3754d046 4237 machine_mode mode, secondary_reload_info *sri)
328d5423 4238{
964229b7 4239 enum reg_class rclass = (enum reg_class) rclass_i;
4240
328d5423 4241 /* Intermediate register needed. */
8deb3959 4242 if (reg_classes_intersect_p (CC_REGS, rclass))
bcbf02a5 4243 return GENERAL_REGS;
4244
76a4c804 4245 if (TARGET_VX)
4246 {
4247 /* The vst/vl vector move instructions allow only for short
4248 displacements. */
4249 if (MEM_P (x)
4250 && GET_CODE (XEXP (x, 0)) == PLUS
4251 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
4252 && !SHORT_DISP_IN_RANGE(INTVAL (XEXP (XEXP (x, 0), 1)))
4253 && reg_class_subset_p (rclass, VEC_REGS)
4254 && (!reg_class_subset_p (rclass, FP_REGS)
4255 || (GET_MODE_SIZE (mode) > 8
4256 && s390_class_max_nregs (FP_REGS, mode) == 1)))
4257 {
4258 if (in_p)
4259 sri->icode = (TARGET_64BIT ?
4260 CODE_FOR_reloaddi_la_in :
4261 CODE_FOR_reloadsi_la_in);
4262 else
4263 sri->icode = (TARGET_64BIT ?
4264 CODE_FOR_reloaddi_la_out :
4265 CODE_FOR_reloadsi_la_out);
4266 }
4267 }
4268
e68d6a13 4269 if (TARGET_Z10)
4270 {
08d88e72 4271 HOST_WIDE_INT offset;
4272 rtx symref;
4273
e68d6a13 4274 /* On z10 several optimizer steps may generate larl operands with
4275 an odd addend. */
4276 if (in_p
2a672556 4277 && s390_loadrelative_operand_p (x, &symref, &offset)
e68d6a13 4278 && mode == Pmode
78affa36 4279 && !SYMBOL_FLAG_NOTALIGN2_P (symref)
08d88e72 4280 && (offset & 1) == 1)
e68d6a13 4281 sri->icode = ((mode == DImode) ? CODE_FOR_reloaddi_larl_odd_addend_z10
4282 : CODE_FOR_reloadsi_larl_odd_addend_z10);
4283
ddb92daa 4284 /* Handle all the (mem (symref)) accesses we cannot use the z10
4285 instructions for. */
e68d6a13 4286 if (MEM_P (x)
2a672556 4287 && s390_loadrelative_operand_p (XEXP (x, 0), NULL, NULL)
ddb92daa 4288 && (mode == QImode
a1142483 4289 || !reg_class_subset_p (rclass, GENERAL_REGS)
ddb92daa 4290 || GET_MODE_SIZE (mode) > UNITS_PER_WORD
4291 || !s390_check_symref_alignment (XEXP (x, 0),
4292 GET_MODE_SIZE (mode))))
e68d6a13 4293 {
4294#define __SECONDARY_RELOAD_CASE(M,m) \
4295 case M##mode: \
4296 if (TARGET_64BIT) \
4297 sri->icode = in_p ? CODE_FOR_reload##m##di_toreg_z10 : \
4298 CODE_FOR_reload##m##di_tomem_z10; \
4299 else \
4300 sri->icode = in_p ? CODE_FOR_reload##m##si_toreg_z10 : \
4301 CODE_FOR_reload##m##si_tomem_z10; \
4302 break;
4303
4304 switch (GET_MODE (x))
4305 {
4306 __SECONDARY_RELOAD_CASE (QI, qi);
4307 __SECONDARY_RELOAD_CASE (HI, hi);
4308 __SECONDARY_RELOAD_CASE (SI, si);
4309 __SECONDARY_RELOAD_CASE (DI, di);
4310 __SECONDARY_RELOAD_CASE (TI, ti);
4311 __SECONDARY_RELOAD_CASE (SF, sf);
4312 __SECONDARY_RELOAD_CASE (DF, df);
4313 __SECONDARY_RELOAD_CASE (TF, tf);
4314 __SECONDARY_RELOAD_CASE (SD, sd);
4315 __SECONDARY_RELOAD_CASE (DD, dd);
4316 __SECONDARY_RELOAD_CASE (TD, td);
76a4c804 4317 __SECONDARY_RELOAD_CASE (V1QI, v1qi);
4318 __SECONDARY_RELOAD_CASE (V2QI, v2qi);
4319 __SECONDARY_RELOAD_CASE (V4QI, v4qi);
4320 __SECONDARY_RELOAD_CASE (V8QI, v8qi);
4321 __SECONDARY_RELOAD_CASE (V16QI, v16qi);
4322 __SECONDARY_RELOAD_CASE (V1HI, v1hi);
4323 __SECONDARY_RELOAD_CASE (V2HI, v2hi);
4324 __SECONDARY_RELOAD_CASE (V4HI, v4hi);
4325 __SECONDARY_RELOAD_CASE (V8HI, v8hi);
4326 __SECONDARY_RELOAD_CASE (V1SI, v1si);
4327 __SECONDARY_RELOAD_CASE (V2SI, v2si);
4328 __SECONDARY_RELOAD_CASE (V4SI, v4si);
4329 __SECONDARY_RELOAD_CASE (V1DI, v1di);
4330 __SECONDARY_RELOAD_CASE (V2DI, v2di);
4331 __SECONDARY_RELOAD_CASE (V1TI, v1ti);
4332 __SECONDARY_RELOAD_CASE (V1SF, v1sf);
4333 __SECONDARY_RELOAD_CASE (V2SF, v2sf);
4334 __SECONDARY_RELOAD_CASE (V4SF, v4sf);
4335 __SECONDARY_RELOAD_CASE (V1DF, v1df);
4336 __SECONDARY_RELOAD_CASE (V2DF, v2df);
4337 __SECONDARY_RELOAD_CASE (V1TF, v1tf);
e68d6a13 4338 default:
4339 gcc_unreachable ();
4340 }
4341#undef __SECONDARY_RELOAD_CASE
4342 }
4343 }
4344
328d5423 4345 /* We need a scratch register when loading a PLUS expression which
4346 is not a legitimate operand of the LOAD ADDRESS instruction. */
7b1bda1c 4347 /* LRA can deal with transformation of plus op very well -- so we
4348 don't need to prompt LRA in this case. */
4349 if (! lra_in_progress && in_p && s390_plus_operand (x, mode))
328d5423 4350 sri->icode = (TARGET_64BIT ?
4351 CODE_FOR_reloaddi_plus : CODE_FOR_reloadsi_plus);
4352
efec32e0 4353 /* Performing a multiword move from or to memory we have to make sure the
328d5423 4354 second chunk in memory is addressable without causing a displacement
4355 overflow. If that would be the case we calculate the address in
4356 a scratch register. */
4357 if (MEM_P (x)
4358 && GET_CODE (XEXP (x, 0)) == PLUS
4359 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
4360 && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (x, 0), 1))
6938bdf8 4361 + GET_MODE_SIZE (mode) - 1))
328d5423 4362 {
efec32e0 4363 /* For GENERAL_REGS a displacement overflow is no problem if occurring
328d5423 4364 in a s_operand address since we may fallback to lm/stm. So we only
4365 have to care about overflows in the b+i+d case. */
8deb3959 4366 if ((reg_classes_intersect_p (GENERAL_REGS, rclass)
328d5423 4367 && s390_class_max_nregs (GENERAL_REGS, mode) > 1
4368 && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS)
4369 /* For FP_REGS no lm/stm is available so this check is triggered
4370 for displacement overflows in b+i+d and b+d like addresses. */
8deb3959 4371 || (reg_classes_intersect_p (FP_REGS, rclass)
328d5423 4372 && s390_class_max_nregs (FP_REGS, mode) > 1))
4373 {
4374 if (in_p)
4375 sri->icode = (TARGET_64BIT ?
76a4c804 4376 CODE_FOR_reloaddi_la_in :
4377 CODE_FOR_reloadsi_la_in);
328d5423 4378 else
4379 sri->icode = (TARGET_64BIT ?
76a4c804 4380 CODE_FOR_reloaddi_la_out :
4381 CODE_FOR_reloadsi_la_out);
328d5423 4382 }
4383 }
bcbf02a5 4384
08b5e262 4385 /* A scratch address register is needed when a symbolic constant is
4386 copied to r0 compiling with -fPIC. In other cases the target
4387 register might be used as temporary (see legitimize_pic_address). */
8deb3959 4388 if (in_p && SYMBOLIC_CONST (x) && flag_pic == 2 && rclass != ADDR_REGS)
08b5e262 4389 sri->icode = (TARGET_64BIT ?
4390 CODE_FOR_reloaddi_PIC_addr :
4391 CODE_FOR_reloadsi_PIC_addr);
4392
328d5423 4393 /* Either scratch or no register needed. */
66795431 4394 return NO_REGS;
4395}
4396
64f977d6 4397/* Generate code to load SRC, which is PLUS that is not a
4398 legitimate operand for the LA instruction, into TARGET.
4399 SCRATCH may be used as scratch register. */
4400
4401void
edd89d66 4402s390_expand_plus_operand (rtx target, rtx src,
4403 rtx scratch)
64f977d6 4404{
e7f0624a 4405 rtx sum1, sum2;
8ba34dcd 4406 struct s390_address ad;
dc4951d9 4407
dc4951d9 4408 /* src must be a PLUS; get its two operands. */
32eda510 4409 gcc_assert (GET_CODE (src) == PLUS);
4410 gcc_assert (GET_MODE (src) == Pmode);
64f977d6 4411
c10847b9 4412 /* Check if any of the two operands is already scheduled
4413 for replacement by reload. This can happen e.g. when
4414 float registers occur in an address. */
4415 sum1 = find_replacement (&XEXP (src, 0));
4416 sum2 = find_replacement (&XEXP (src, 1));
a5004c3d 4417 src = gen_rtx_PLUS (Pmode, sum1, sum2);
a5004c3d 4418
e7f0624a 4419 /* If the address is already strictly valid, there's nothing to do. */
4420 if (!s390_decompose_address (src, &ad)
1e280623 4421 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
4422 || (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx))))
64f977d6 4423 {
e7f0624a 4424 /* Otherwise, one of the operands cannot be an address register;
4425 we reload its value into the scratch register. */
4426 if (true_regnum (sum1) < 1 || true_regnum (sum1) > 15)
4427 {
4428 emit_move_insn (scratch, sum1);
4429 sum1 = scratch;
4430 }
4431 if (true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
4432 {
4433 emit_move_insn (scratch, sum2);
4434 sum2 = scratch;
4435 }
64f977d6 4436
e7f0624a 4437 /* According to the way these invalid addresses are generated
4438 in reload.c, it should never happen (at least on s390) that
4439 *neither* of the PLUS components, after find_replacements
4440 was applied, is an address register. */
4441 if (sum1 == scratch && sum2 == scratch)
4442 {
4443 debug_rtx (src);
32eda510 4444 gcc_unreachable ();
e7f0624a 4445 }
64f977d6 4446
e7f0624a 4447 src = gen_rtx_PLUS (Pmode, sum1, sum2);
64f977d6 4448 }
4449
4450 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
4451 is only ever performed on addresses, so we can mark the
4452 sum as legitimate for LA in any case. */
4fbc4db5 4453 s390_load_address (target, src);
64f977d6 4454}
4455
4456
e5537457 4457/* Return true if ADDR is a valid memory address.
875862bf 4458 STRICT specifies whether strict register checking applies. */
4673c1a0 4459
fd50b071 4460static bool
3754d046 4461s390_legitimate_address_p (machine_mode mode, rtx addr, bool strict)
4673c1a0 4462{
875862bf 4463 struct s390_address ad;
e68d6a13 4464
4465 if (TARGET_Z10
4466 && larl_operand (addr, VOIDmode)
4467 && (mode == VOIDmode
4468 || s390_check_symref_alignment (addr, GET_MODE_SIZE (mode))))
4469 return true;
4470
875862bf 4471 if (!s390_decompose_address (addr, &ad))
e5537457 4472 return false;
8ba34dcd 4473
4474 if (strict)
4475 {
1e280623 4476 if (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
e5537457 4477 return false;
1e280623 4478
4479 if (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx)))
e5537457 4480 return false;
8ba34dcd 4481 }
4482 else
4483 {
ffead1ca 4484 if (ad.base
1e280623 4485 && !(REGNO (ad.base) >= FIRST_PSEUDO_REGISTER
4486 || REGNO_REG_CLASS (REGNO (ad.base)) == ADDR_REGS))
e5537457 4487 return false;
ffead1ca 4488
1e280623 4489 if (ad.indx
4490 && !(REGNO (ad.indx) >= FIRST_PSEUDO_REGISTER
4491 || REGNO_REG_CLASS (REGNO (ad.indx)) == ADDR_REGS))
4492 return false;
8ba34dcd 4493 }
e5537457 4494 return true;
4673c1a0 4495}
4496
e5537457 4497/* Return true if OP is a valid operand for the LA instruction.
2eb8fe23 4498 In 31-bit, we need to prove that the result is used as an
4499 address, as LA performs only a 31-bit addition. */
4500
e5537457 4501bool
edd89d66 4502legitimate_la_operand_p (rtx op)
2eb8fe23 4503{
4504 struct s390_address addr;
8ba34dcd 4505 if (!s390_decompose_address (op, &addr))
e5537457 4506 return false;
2eb8fe23 4507
e5537457 4508 return (TARGET_64BIT || addr.pointer);
64f977d6 4509}
2eb8fe23 4510
e5537457 4511/* Return true if it is valid *and* preferable to use LA to
c6061690 4512 compute the sum of OP1 and OP2. */
f81e845f 4513
e5537457 4514bool
c6061690 4515preferred_la_operand_p (rtx op1, rtx op2)
a40b2054 4516{
4517 struct s390_address addr;
c6061690 4518
4519 if (op2 != const0_rtx)
4520 op1 = gen_rtx_PLUS (Pmode, op1, op2);
4521
4522 if (!s390_decompose_address (op1, &addr))
e5537457 4523 return false;
1e280623 4524 if (addr.base && !REGNO_OK_FOR_BASE_P (REGNO (addr.base)))
e5537457 4525 return false;
1e280623 4526 if (addr.indx && !REGNO_OK_FOR_INDEX_P (REGNO (addr.indx)))
e5537457 4527 return false;
a40b2054 4528
33d033da 4529 /* Avoid LA instructions with index register on z196; it is
81769881 4530 preferable to use regular add instructions when possible.
4531 Starting with zEC12 the la with index register is "uncracked"
4532 again. */
33d033da 4533 if (addr.indx && s390_tune == PROCESSOR_2817_Z196)
4534 return false;
4535
a40b2054 4536 if (!TARGET_64BIT && !addr.pointer)
e5537457 4537 return false;
a40b2054 4538
4539 if (addr.pointer)
e5537457 4540 return true;
a40b2054 4541
ec3b9583 4542 if ((addr.base && REG_P (addr.base) && REG_POINTER (addr.base))
4543 || (addr.indx && REG_P (addr.indx) && REG_POINTER (addr.indx)))
e5537457 4544 return true;
a40b2054 4545
e5537457 4546 return false;
a40b2054 4547}
4548
4fbc4db5 4549/* Emit a forced load-address operation to load SRC into DST.
4550 This will use the LOAD ADDRESS instruction even in situations
4551 where legitimate_la_operand_p (SRC) returns false. */
2eb8fe23 4552
4fbc4db5 4553void
b40da9a7 4554s390_load_address (rtx dst, rtx src)
64f977d6 4555{
4fbc4db5 4556 if (TARGET_64BIT)
4557 emit_move_insn (dst, src);
4558 else
4559 emit_insn (gen_force_la_31 (dst, src));
2eb8fe23 4560}
4561
9852c8ae 4562/* Return true if it ok to use SYMBOL_REF in a relative address. */
4563
4564bool
4565s390_rel_address_ok_p (rtx symbol_ref)
4566{
4567 tree decl;
4568
4569 if (symbol_ref == s390_got_symbol () || CONSTANT_POOL_ADDRESS_P (symbol_ref))
4570 return true;
4571
4572 decl = SYMBOL_REF_DECL (symbol_ref);
4573
4574 if (!flag_pic || SYMBOL_REF_LOCAL_P (symbol_ref))
4575 return (s390_pic_data_is_text_relative
4576 || (decl
4577 && TREE_CODE (decl) == FUNCTION_DECL));
4578
4579 return false;
4580}
4581
4673c1a0 4582/* Return a legitimate reference for ORIG (an address) using the
4583 register REG. If REG is 0, a new pseudo is generated.
4584
4585 There are two types of references that must be handled:
4586
4587 1. Global data references must load the address from the GOT, via
4588 the PIC reg. An insn is emitted to do this load, and the reg is
4589 returned.
4590
4591 2. Static data references, constant pool addresses, and code labels
4592 compute the address as an offset from the GOT, whose base is in
a3e33162 4593 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
4673c1a0 4594 differentiate them from global data objects. The returned
4595 address is the PIC reg + an unspec constant.
4596
bc409cb4 4597 TARGET_LEGITIMIZE_ADDRESS_P rejects symbolic references unless the PIC
4673c1a0 4598 reg also appears in the address. */
4599
4600rtx
b40da9a7 4601legitimize_pic_address (rtx orig, rtx reg)
4673c1a0 4602{
4603 rtx addr = orig;
2a672556 4604 rtx addend = const0_rtx;
8deb3959 4605 rtx new_rtx = orig;
4673c1a0 4606
1ed004b7 4607 gcc_assert (!TLS_SYMBOLIC_CONST (addr));
4608
2a672556 4609 if (GET_CODE (addr) == CONST)
4610 addr = XEXP (addr, 0);
4611
4612 if (GET_CODE (addr) == PLUS)
4673c1a0 4613 {
2a672556 4614 addend = XEXP (addr, 1);
4615 addr = XEXP (addr, 0);
4616 }
4617
4618 if ((GET_CODE (addr) == LABEL_REF
9852c8ae 4619 || (SYMBOL_REF_P (addr) && s390_rel_address_ok_p (addr))
2a672556 4620 || (GET_CODE (addr) == UNSPEC &&
4621 (XINT (addr, 1) == UNSPEC_GOTENT
4622 || (TARGET_CPU_ZARCH && XINT (addr, 1) == UNSPEC_PLT))))
4623 && GET_CODE (addend) == CONST_INT)
4624 {
4625 /* This can be locally addressed. */
4626
4627 /* larl_operand requires UNSPECs to be wrapped in a const rtx. */
4628 rtx const_addr = (GET_CODE (addr) == UNSPEC ?
4629 gen_rtx_CONST (Pmode, addr) : addr);
4630
4631 if (TARGET_CPU_ZARCH
4632 && larl_operand (const_addr, VOIDmode)
b422d8c0 4633 && INTVAL (addend) < HOST_WIDE_INT_1 << 31
4634 && INTVAL (addend) >= -(HOST_WIDE_INT_1 << 31))
2a672556 4635 {
4636 if (INTVAL (addend) & 1)
4637 {
4638 /* LARL can't handle odd offsets, so emit a pair of LARL
4639 and LA. */
4640 rtx temp = reg? reg : gen_reg_rtx (Pmode);
4641
4642 if (!DISP_IN_RANGE (INTVAL (addend)))
4643 {
4644 HOST_WIDE_INT even = INTVAL (addend) - 1;
4645 addr = gen_rtx_PLUS (Pmode, addr, GEN_INT (even));
4646 addr = gen_rtx_CONST (Pmode, addr);
4647 addend = const1_rtx;
4648 }
4649
4650 emit_move_insn (temp, addr);
4651 new_rtx = gen_rtx_PLUS (Pmode, temp, addend);
4652
4653 if (reg != 0)
4654 {
4655 s390_load_address (reg, new_rtx);
4656 new_rtx = reg;
4657 }
4658 }
4659 else
4660 {
4661 /* If the offset is even, we can just use LARL. This
4662 will happen automatically. */
4663 }
4664 }
4673c1a0 4665 else
2a672556 4666 {
4667 /* No larl - Access local symbols relative to the GOT. */
4673c1a0 4668
2a672556 4669 rtx temp = reg? reg : gen_reg_rtx (Pmode);
4673c1a0 4670
12ef3745 4671 if (reload_in_progress || reload_completed)
3072d30e 4672 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
12ef3745 4673
2a672556 4674 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
4675 if (addend != const0_rtx)
4676 addr = gen_rtx_PLUS (Pmode, addr, addend);
4677 addr = gen_rtx_CONST (Pmode, addr);
4678 addr = force_const_mem (Pmode, addr);
4673c1a0 4679 emit_move_insn (temp, addr);
4680
2a672556 4681 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
4682 if (reg != 0)
4683 {
4684 s390_load_address (reg, new_rtx);
4685 new_rtx = reg;
4686 }
4687 }
4673c1a0 4688 }
2a672556 4689 else if (GET_CODE (addr) == SYMBOL_REF && addend == const0_rtx)
4673c1a0 4690 {
2a672556 4691 /* A non-local symbol reference without addend.
4692
4693 The symbol ref is wrapped into an UNSPEC to make sure the
4694 proper operand modifier (@GOT or @GOTENT) will be emitted.
4695 This will tell the linker to put the symbol into the GOT.
4696
4697 Additionally the code dereferencing the GOT slot is emitted here.
4698
4699 An addend to the symref needs to be added afterwards.
4700 legitimize_pic_address calls itself recursively to handle
4701 that case. So no need to do it here. */
4702
4673c1a0 4703 if (reg == 0)
4704 reg = gen_reg_rtx (Pmode);
4705
2a672556 4706 if (TARGET_Z10)
4707 {
4708 /* Use load relative if possible.
4709 lgrl <target>, sym@GOTENT */
4710 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTENT);
4711 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
4712 new_rtx = gen_const_mem (GET_MODE (reg), new_rtx);
4713
4714 emit_move_insn (reg, new_rtx);
4715 new_rtx = reg;
4716 }
4717 else if (flag_pic == 1)
4673c1a0 4718 {
2a672556 4719 /* Assume GOT offset is a valid displacement operand (< 4k
4720 or < 512k with z990). This is handled the same way in
4721 both 31- and 64-bit code (@GOT).
4722 lg <target>, sym@GOT(r12) */
4673c1a0 4723
9a2a66ae 4724 if (reload_in_progress || reload_completed)
3072d30e 4725 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
4673c1a0 4726
8deb3959 4727 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
4728 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
4729 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
4730 new_rtx = gen_const_mem (Pmode, new_rtx);
4731 emit_move_insn (reg, new_rtx);
4732 new_rtx = reg;
4673c1a0 4733 }
dafc8d45 4734 else if (TARGET_CPU_ZARCH)
4673c1a0 4735 {
4736 /* If the GOT offset might be >= 4k, we determine the position
2a672556 4737 of the GOT entry via a PC-relative LARL (@GOTENT).
4738 larl temp, sym@GOTENT
4739 lg <target>, 0(temp) */
4673c1a0 4740
08b5e262 4741 rtx temp = reg ? reg : gen_reg_rtx (Pmode);
4742
4743 gcc_assert (REGNO (temp) >= FIRST_PSEUDO_REGISTER
4744 || REGNO_REG_CLASS (REGNO (temp)) == ADDR_REGS);
4673c1a0 4745
8deb3959 4746 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTENT);
4747 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
2a672556 4748 emit_move_insn (temp, new_rtx);
4673c1a0 4749
2a672556 4750 new_rtx = gen_const_mem (Pmode, temp);
8deb3959 4751 emit_move_insn (reg, new_rtx);
2a672556 4752
8deb3959 4753 new_rtx = reg;
4673c1a0 4754 }
4755 else
4756 {
f81e845f 4757 /* If the GOT offset might be >= 4k, we have to load it
2a672556 4758 from the literal pool (@GOT).
4759
4760 lg temp, lit-litbase(r13)
4761 lg <target>, 0(temp)
4762 lit: .long sym@GOT */
4673c1a0 4763
08b5e262 4764 rtx temp = reg ? reg : gen_reg_rtx (Pmode);
4765
4766 gcc_assert (REGNO (temp) >= FIRST_PSEUDO_REGISTER
4767 || REGNO_REG_CLASS (REGNO (temp)) == ADDR_REGS);
4673c1a0 4768
9a2a66ae 4769 if (reload_in_progress || reload_completed)
3072d30e 4770 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
4673c1a0 4771
12ef3745 4772 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
525d1294 4773 addr = gen_rtx_CONST (Pmode, addr);
4774 addr = force_const_mem (Pmode, addr);
4673c1a0 4775 emit_move_insn (temp, addr);
4776
8deb3959 4777 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
4778 new_rtx = gen_const_mem (Pmode, new_rtx);
4779 emit_move_insn (reg, new_rtx);
4780 new_rtx = reg;
4673c1a0 4781 }
f81e845f 4782 }
2a672556 4783 else if (GET_CODE (addr) == UNSPEC && GET_CODE (addend) == CONST_INT)
4673c1a0 4784 {
2a672556 4785 gcc_assert (XVECLEN (addr, 0) == 1);
4786 switch (XINT (addr, 1))
4673c1a0 4787 {
2a672556 4788 /* These address symbols (or PLT slots) relative to the GOT
4789 (not GOT slots!). In general this will exceed the
4790 displacement range so these value belong into the literal
4791 pool. */
4792 case UNSPEC_GOTOFF:
4793 case UNSPEC_PLTOFF:
4794 new_rtx = force_const_mem (Pmode, orig);
4795 break;
4673c1a0 4796
2a672556 4797 /* For -fPIC the GOT size might exceed the displacement
4798 range so make sure the value is in the literal pool. */
4799 case UNSPEC_GOT:
4800 if (flag_pic == 2)
4801 new_rtx = force_const_mem (Pmode, orig);
4802 break;
4673c1a0 4803
2a672556 4804 /* For @GOTENT larl is used. This is handled like local
4805 symbol refs. */
4806 case UNSPEC_GOTENT:
4807 gcc_unreachable ();
4808 break;
4673c1a0 4809
2a672556 4810 /* @PLT is OK as is on 64-bit, must be converted to
4811 GOT-relative @PLTOFF on 31-bit. */
4812 case UNSPEC_PLT:
4813 if (!TARGET_CPU_ZARCH)
4673c1a0 4814 {
2a672556 4815 rtx temp = reg? reg : gen_reg_rtx (Pmode);
4816
4817 if (reload_in_progress || reload_completed)
4818 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
4819
4820 addr = XVECEXP (addr, 0, 0);
4821 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
4822 UNSPEC_PLTOFF);
4823 if (addend != const0_rtx)
4824 addr = gen_rtx_PLUS (Pmode, addr, addend);
4825 addr = gen_rtx_CONST (Pmode, addr);
4826 addr = force_const_mem (Pmode, addr);
4827 emit_move_insn (temp, addr);
4828
4829 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
4830 if (reg != 0)
4673c1a0 4831 {
2a672556 4832 s390_load_address (reg, new_rtx);
4833 new_rtx = reg;
4673c1a0 4834 }
2a672556 4835 }
4836 else
4837 /* On 64 bit larl can be used. This case is handled like
4838 local symbol refs. */
4839 gcc_unreachable ();
4840 break;
4841
4842 /* Everything else cannot happen. */
4843 default:
4844 gcc_unreachable ();
4845 }
4846 }
4847 else if (addend != const0_rtx)
4848 {
4849 /* Otherwise, compute the sum. */
4673c1a0 4850
2a672556 4851 rtx base = legitimize_pic_address (addr, reg);
4852 new_rtx = legitimize_pic_address (addend,
4853 base == reg ? NULL_RTX : reg);
4854 if (GET_CODE (new_rtx) == CONST_INT)
4855 new_rtx = plus_constant (Pmode, base, INTVAL (new_rtx));
4856 else
4857 {
4858 if (GET_CODE (new_rtx) == PLUS && CONSTANT_P (XEXP (new_rtx, 1)))
4859 {
4860 base = gen_rtx_PLUS (Pmode, base, XEXP (new_rtx, 0));
4861 new_rtx = XEXP (new_rtx, 1);
4673c1a0 4862 }
2a672556 4863 new_rtx = gen_rtx_PLUS (Pmode, base, new_rtx);
4673c1a0 4864 }
2a672556 4865
4866 if (GET_CODE (new_rtx) == CONST)
4867 new_rtx = XEXP (new_rtx, 0);
4868 new_rtx = force_operand (new_rtx, 0);
4673c1a0 4869 }
2a672556 4870
8deb3959 4871 return new_rtx;
4673c1a0 4872}
4873
be00aaa8 4874/* Load the thread pointer into a register. */
4875
cc87d0c5 4876rtx
4877s390_get_thread_pointer (void)
be00aaa8 4878{
923cf36d 4879 rtx tp = gen_reg_rtx (Pmode);
be00aaa8 4880
923cf36d 4881 emit_move_insn (tp, gen_rtx_REG (Pmode, TP_REGNUM));
be00aaa8 4882 mark_reg_pointer (tp, BITS_PER_WORD);
4883
4884 return tp;
4885}
4886
7346ca58 4887/* Emit a tls call insn. The call target is the SYMBOL_REF stored
4888 in s390_tls_symbol which always refers to __tls_get_offset.
4889 The returned offset is written to RESULT_REG and an USE rtx is
4890 generated for TLS_CALL. */
be00aaa8 4891
4892static GTY(()) rtx s390_tls_symbol;
7346ca58 4893
4894static void
4895s390_emit_tls_call_insn (rtx result_reg, rtx tls_call)
be00aaa8 4896{
7346ca58 4897 rtx insn;
f588eb9f 4898
c60a7572 4899 if (!flag_pic)
4900 emit_insn (s390_load_got ());
7346ca58 4901
be00aaa8 4902 if (!s390_tls_symbol)
4903 s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset");
4904
f588eb9f 4905 insn = s390_emit_call (s390_tls_symbol, tls_call, result_reg,
4906 gen_rtx_REG (Pmode, RETURN_REGNUM));
7346ca58 4907
4908 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), result_reg);
9c2a0c05 4909 RTL_CONST_CALL_P (insn) = 1;
be00aaa8 4910}
4911
4912/* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
4913 this (thread-local) address. REG may be used as temporary. */
4914
4915static rtx
b40da9a7 4916legitimize_tls_address (rtx addr, rtx reg)
be00aaa8 4917{
db7dd023 4918 rtx new_rtx, tls_call, temp, base, r2;
4919 rtx_insn *insn;
be00aaa8 4920
4921 if (GET_CODE (addr) == SYMBOL_REF)
4922 switch (tls_symbolic_operand (addr))
4923 {
4924 case TLS_MODEL_GLOBAL_DYNAMIC:
4925 start_sequence ();
4926 r2 = gen_rtx_REG (Pmode, 2);
4927 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLSGD);
8deb3959 4928 new_rtx = gen_rtx_CONST (Pmode, tls_call);
4929 new_rtx = force_const_mem (Pmode, new_rtx);
4930 emit_move_insn (r2, new_rtx);
7346ca58 4931 s390_emit_tls_call_insn (r2, tls_call);
be00aaa8 4932 insn = get_insns ();
4933 end_sequence ();
4934
8deb3959 4935 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
be00aaa8 4936 temp = gen_reg_rtx (Pmode);
8deb3959 4937 emit_libcall_block (insn, temp, r2, new_rtx);
be00aaa8 4938
8deb3959 4939 new_rtx = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
be00aaa8 4940 if (reg != 0)
4941 {
8deb3959 4942 s390_load_address (reg, new_rtx);
4943 new_rtx = reg;
be00aaa8 4944 }
4945 break;
4946
4947 case TLS_MODEL_LOCAL_DYNAMIC:
4948 start_sequence ();
4949 r2 = gen_rtx_REG (Pmode, 2);
4950 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM);
8deb3959 4951 new_rtx = gen_rtx_CONST (Pmode, tls_call);
4952 new_rtx = force_const_mem (Pmode, new_rtx);
4953 emit_move_insn (r2, new_rtx);
7346ca58 4954 s390_emit_tls_call_insn (r2, tls_call);
be00aaa8 4955 insn = get_insns ();
4956 end_sequence ();
4957
8deb3959 4958 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM_NTPOFF);
be00aaa8 4959 temp = gen_reg_rtx (Pmode);
8deb3959 4960 emit_libcall_block (insn, temp, r2, new_rtx);
be00aaa8 4961
8deb3959 4962 new_rtx = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
be00aaa8 4963 base = gen_reg_rtx (Pmode);
8deb3959 4964 s390_load_address (base, new_rtx);
be00aaa8 4965
8deb3959 4966 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_DTPOFF);
4967 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
4968 new_rtx = force_const_mem (Pmode, new_rtx);
be00aaa8 4969 temp = gen_reg_rtx (Pmode);
8deb3959 4970 emit_move_insn (temp, new_rtx);
be00aaa8 4971
8deb3959 4972 new_rtx = gen_rtx_PLUS (Pmode, base, temp);
be00aaa8 4973 if (reg != 0)
4974 {
8deb3959 4975 s390_load_address (reg, new_rtx);
4976 new_rtx = reg;
be00aaa8 4977 }
4978 break;
4979
4980 case TLS_MODEL_INITIAL_EXEC:
4981 if (flag_pic == 1)
4982 {
4983 /* Assume GOT offset < 4k. This is handled the same way
4984 in both 31- and 64-bit code. */
4985
4986 if (reload_in_progress || reload_completed)
3072d30e 4987 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
be00aaa8 4988
8deb3959 4989 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
4990 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
4991 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
4992 new_rtx = gen_const_mem (Pmode, new_rtx);
be00aaa8 4993 temp = gen_reg_rtx (Pmode);
8deb3959 4994 emit_move_insn (temp, new_rtx);
be00aaa8 4995 }
dafc8d45 4996 else if (TARGET_CPU_ZARCH)
be00aaa8 4997 {
4998 /* If the GOT offset might be >= 4k, we determine the position
4999 of the GOT entry via a PC-relative LARL. */
5000
8deb3959 5001 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
5002 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
be00aaa8 5003 temp = gen_reg_rtx (Pmode);
8deb3959 5004 emit_move_insn (temp, new_rtx);
be00aaa8 5005
8deb3959 5006 new_rtx = gen_const_mem (Pmode, temp);
be00aaa8 5007 temp = gen_reg_rtx (Pmode);
8deb3959 5008 emit_move_insn (temp, new_rtx);
be00aaa8 5009 }
5010 else if (flag_pic)
5011 {
f81e845f 5012 /* If the GOT offset might be >= 4k, we have to load it
be00aaa8 5013 from the literal pool. */
5014
5015 if (reload_in_progress || reload_completed)
3072d30e 5016 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
be00aaa8 5017
8deb3959 5018 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
5019 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
5020 new_rtx = force_const_mem (Pmode, new_rtx);
be00aaa8 5021 temp = gen_reg_rtx (Pmode);
8deb3959 5022 emit_move_insn (temp, new_rtx);
be00aaa8 5023
8deb3959 5024 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
5025 new_rtx = gen_const_mem (Pmode, new_rtx);
be00aaa8 5026
8deb3959 5027 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new_rtx, addr), UNSPEC_TLS_LOAD);
be00aaa8 5028 temp = gen_reg_rtx (Pmode);
d1f9b275 5029 emit_insn (gen_rtx_SET (temp, new_rtx));
be00aaa8 5030 }
5031 else
5032 {
5033 /* In position-dependent code, load the absolute address of
5034 the GOT entry from the literal pool. */
5035
8deb3959 5036 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
5037 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
5038 new_rtx = force_const_mem (Pmode, new_rtx);
be00aaa8 5039 temp = gen_reg_rtx (Pmode);
8deb3959 5040 emit_move_insn (temp, new_rtx);
be00aaa8 5041
8deb3959 5042 new_rtx = temp;
5043 new_rtx = gen_const_mem (Pmode, new_rtx);
5044 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new_rtx, addr), UNSPEC_TLS_LOAD);
be00aaa8 5045 temp = gen_reg_rtx (Pmode);
d1f9b275 5046 emit_insn (gen_rtx_SET (temp, new_rtx));
be00aaa8 5047 }
5048
8deb3959 5049 new_rtx = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
be00aaa8 5050 if (reg != 0)
5051 {
8deb3959 5052 s390_load_address (reg, new_rtx);
5053 new_rtx = reg;
be00aaa8 5054 }
5055 break;
5056
5057 case TLS_MODEL_LOCAL_EXEC:
8deb3959 5058 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
5059 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
5060 new_rtx = force_const_mem (Pmode, new_rtx);
be00aaa8 5061 temp = gen_reg_rtx (Pmode);
8deb3959 5062 emit_move_insn (temp, new_rtx);
be00aaa8 5063
8deb3959 5064 new_rtx = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
be00aaa8 5065 if (reg != 0)
5066 {
8deb3959 5067 s390_load_address (reg, new_rtx);
5068 new_rtx = reg;
be00aaa8 5069 }
5070 break;
5071
5072 default:
32eda510 5073 gcc_unreachable ();
be00aaa8 5074 }
5075
5076 else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == UNSPEC)
5077 {
5078 switch (XINT (XEXP (addr, 0), 1))
5079 {
5080 case UNSPEC_INDNTPOFF:
32eda510 5081 gcc_assert (TARGET_CPU_ZARCH);
8deb3959 5082 new_rtx = addr;
be00aaa8 5083 break;
5084
5085 default:
32eda510 5086 gcc_unreachable ();
be00aaa8 5087 }
5088 }
5089
b7ace65c 5090 else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == PLUS
5091 && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
5092 {
8deb3959 5093 new_rtx = XEXP (XEXP (addr, 0), 0);
5094 if (GET_CODE (new_rtx) != SYMBOL_REF)
5095 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
b7ace65c 5096
8deb3959 5097 new_rtx = legitimize_tls_address (new_rtx, reg);
29c05e22 5098 new_rtx = plus_constant (Pmode, new_rtx,
5099 INTVAL (XEXP (XEXP (addr, 0), 1)));
8deb3959 5100 new_rtx = force_operand (new_rtx, 0);
b7ace65c 5101 }
5102
be00aaa8 5103 else
32eda510 5104 gcc_unreachable (); /* for now ... */
be00aaa8 5105
8deb3959 5106 return new_rtx;
be00aaa8 5107}
5108
08b5e262 5109/* Emit insns making the address in operands[1] valid for a standard
5110 move to operands[0]. operands[1] is replaced by an address which
5111 should be used instead of the former RTX to emit the move
5112 pattern. */
4673c1a0 5113
5114void
b40da9a7 5115emit_symbolic_move (rtx *operands)
4673c1a0 5116{
e1ba4a27 5117 rtx temp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
4673c1a0 5118
be00aaa8 5119 if (GET_CODE (operands[0]) == MEM)
4673c1a0 5120 operands[1] = force_reg (Pmode, operands[1]);
be00aaa8 5121 else if (TLS_SYMBOLIC_CONST (operands[1]))
5122 operands[1] = legitimize_tls_address (operands[1], temp);
5123 else if (flag_pic)
4673c1a0 5124 operands[1] = legitimize_pic_address (operands[1], temp);
5125}
5126
56769981 5127/* Try machine-dependent ways of modifying an illegitimate address X
4673c1a0 5128 to be legitimate. If we find one, return the new, valid address.
4673c1a0 5129
5130 OLDX is the address as it was before break_out_memory_refs was called.
5131 In some cases it is useful to look at this to decide what needs to be done.
5132
56769981 5133 MODE is the mode of the operand pointed to by X.
4673c1a0 5134
5135 When -fpic is used, special handling is needed for symbolic references.
5136 See comments by legitimize_pic_address for details. */
5137
41e3a0c7 5138static rtx
5139s390_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
3754d046 5140 machine_mode mode ATTRIBUTE_UNUSED)
4673c1a0 5141{
2eb8fe23 5142 rtx constant_term = const0_rtx;
4673c1a0 5143
be00aaa8 5144 if (TLS_SYMBOLIC_CONST (x))
5145 {
5146 x = legitimize_tls_address (x, 0);
5147
fd50b071 5148 if (s390_legitimate_address_p (mode, x, FALSE))
be00aaa8 5149 return x;
5150 }
1ed004b7 5151 else if (GET_CODE (x) == PLUS
ffead1ca 5152 && (TLS_SYMBOLIC_CONST (XEXP (x, 0))
1ed004b7 5153 || TLS_SYMBOLIC_CONST (XEXP (x, 1))))
5154 {
5155 return x;
5156 }
be00aaa8 5157 else if (flag_pic)
4673c1a0 5158 {
2eb8fe23 5159 if (SYMBOLIC_CONST (x)
f81e845f 5160 || (GET_CODE (x) == PLUS
5161 && (SYMBOLIC_CONST (XEXP (x, 0))
2eb8fe23 5162 || SYMBOLIC_CONST (XEXP (x, 1)))))
5163 x = legitimize_pic_address (x, 0);
5164
fd50b071 5165 if (s390_legitimate_address_p (mode, x, FALSE))
2eb8fe23 5166 return x;
4673c1a0 5167 }
4673c1a0 5168
2eb8fe23 5169 x = eliminate_constant_term (x, &constant_term);
56769981 5170
de84f805 5171 /* Optimize loading of large displacements by splitting them
5172 into the multiple of 4K and the rest; this allows the
f81e845f 5173 former to be CSE'd if possible.
de84f805 5174
5175 Don't do this if the displacement is added to a register
5176 pointing into the stack frame, as the offsets will
5177 change later anyway. */
5178
5179 if (GET_CODE (constant_term) == CONST_INT
51aa1e9c 5180 && !TARGET_LONG_DISPLACEMENT
5181 && !DISP_IN_RANGE (INTVAL (constant_term))
de84f805 5182 && !(REG_P (x) && REGNO_PTR_FRAME_P (REGNO (x))))
5183 {
5184 HOST_WIDE_INT lower = INTVAL (constant_term) & 0xfff;
5185 HOST_WIDE_INT upper = INTVAL (constant_term) ^ lower;
5186
5187 rtx temp = gen_reg_rtx (Pmode);
5188 rtx val = force_operand (GEN_INT (upper), temp);
5189 if (val != temp)
5190 emit_move_insn (temp, val);
5191
5192 x = gen_rtx_PLUS (Pmode, x, temp);
5193 constant_term = GEN_INT (lower);
5194 }
5195
2eb8fe23 5196 if (GET_CODE (x) == PLUS)
4673c1a0 5197 {
2eb8fe23 5198 if (GET_CODE (XEXP (x, 0)) == REG)
5199 {
edd89d66 5200 rtx temp = gen_reg_rtx (Pmode);
5201 rtx val = force_operand (XEXP (x, 1), temp);
2eb8fe23 5202 if (val != temp)
5203 emit_move_insn (temp, val);
5204
5205 x = gen_rtx_PLUS (Pmode, XEXP (x, 0), temp);
5206 }
5207
5208 else if (GET_CODE (XEXP (x, 1)) == REG)
5209 {
edd89d66 5210 rtx temp = gen_reg_rtx (Pmode);
5211 rtx val = force_operand (XEXP (x, 0), temp);
2eb8fe23 5212 if (val != temp)
5213 emit_move_insn (temp, val);
5214
5215 x = gen_rtx_PLUS (Pmode, temp, XEXP (x, 1));
5216 }
4673c1a0 5217 }
2eb8fe23 5218
5219 if (constant_term != const0_rtx)
5220 x = gen_rtx_PLUS (Pmode, x, constant_term);
5221
5222 return x;
4673c1a0 5223}
5224
e4542435 5225/* Try a machine-dependent way of reloading an illegitimate address AD
851d9296 5226 operand. If we find one, push the reload and return the new address.
e4542435 5227
5228 MODE is the mode of the enclosing MEM. OPNUM is the operand number
5229 and TYPE is the reload type of the current reload. */
5230
ffead1ca 5231rtx
3754d046 5232legitimize_reload_address (rtx ad, machine_mode mode ATTRIBUTE_UNUSED,
e4542435 5233 int opnum, int type)
5234{
5235 if (!optimize || TARGET_LONG_DISPLACEMENT)
5236 return NULL_RTX;
5237
5238 if (GET_CODE (ad) == PLUS)
5239 {
5240 rtx tem = simplify_binary_operation (PLUS, Pmode,
5241 XEXP (ad, 0), XEXP (ad, 1));
5242 if (tem)
5243 ad = tem;
5244 }
5245
5246 if (GET_CODE (ad) == PLUS
5247 && GET_CODE (XEXP (ad, 0)) == REG
5248 && GET_CODE (XEXP (ad, 1)) == CONST_INT
5249 && !DISP_IN_RANGE (INTVAL (XEXP (ad, 1))))
5250 {
5251 HOST_WIDE_INT lower = INTVAL (XEXP (ad, 1)) & 0xfff;
5252 HOST_WIDE_INT upper = INTVAL (XEXP (ad, 1)) ^ lower;
8deb3959 5253 rtx cst, tem, new_rtx;
e4542435 5254
5255 cst = GEN_INT (upper);
5256 if (!legitimate_reload_constant_p (cst))
5257 cst = force_const_mem (Pmode, cst);
5258
5259 tem = gen_rtx_PLUS (Pmode, XEXP (ad, 0), cst);
8deb3959 5260 new_rtx = gen_rtx_PLUS (Pmode, tem, GEN_INT (lower));
e4542435 5261
5262 push_reload (XEXP (tem, 1), 0, &XEXP (tem, 1), 0,
ffead1ca 5263 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
e4542435 5264 opnum, (enum reload_type) type);
8deb3959 5265 return new_rtx;
e4542435 5266 }
5267
5268 return NULL_RTX;
5269}
5270
4fbc4db5 5271/* Emit code to move LEN bytes from DST to SRC. */
5272
daa87e5a 5273bool
008c057d 5274s390_expand_movmem (rtx dst, rtx src, rtx len)
4fbc4db5 5275{
daa87e5a 5276 /* When tuning for z10 or higher we rely on the Glibc functions to
5277 do the right thing. Only for constant lengths below 64k we will
5278 generate inline code. */
5279 if (s390_tune >= PROCESSOR_2097_Z10
5280 && (GET_CODE (len) != CONST_INT || INTVAL (len) > (1<<16)))
5281 return false;
5282
d044af2a 5283 /* Expand memcpy for constant length operands without a loop if it
5284 is shorter that way.
5285
5286 With a constant length argument a
5287 memcpy loop (without pfd) is 36 bytes -> 6 * mvc */
5288 if (GET_CODE (len) == CONST_INT
5289 && INTVAL (len) >= 0
5290 && INTVAL (len) <= 256 * 6
5291 && (!TARGET_MVCLE || INTVAL (len) <= 256))
4fbc4db5 5292 {
d044af2a 5293 HOST_WIDE_INT o, l;
5294
5295 for (l = INTVAL (len), o = 0; l > 0; l -= 256, o += 256)
5296 {
5297 rtx newdst = adjust_address (dst, BLKmode, o);
5298 rtx newsrc = adjust_address (src, BLKmode, o);
5299 emit_insn (gen_movmem_short (newdst, newsrc,
5300 GEN_INT (l > 256 ? 255 : l - 1)));
5301 }
4fbc4db5 5302 }
5303
5304 else if (TARGET_MVCLE)
5305 {
008c057d 5306 emit_insn (gen_movmem_long (dst, src, convert_to_mode (Pmode, len, 1)));
4fbc4db5 5307 }
5308
5309 else
5310 {
5311 rtx dst_addr, src_addr, count, blocks, temp;
79f6a8ed 5312 rtx_code_label *loop_start_label = gen_label_rtx ();
5313 rtx_code_label *loop_end_label = gen_label_rtx ();
5314 rtx_code_label *end_label = gen_label_rtx ();
3754d046 5315 machine_mode mode;
4fbc4db5 5316
5317 mode = GET_MODE (len);
5318 if (mode == VOIDmode)
31838f66 5319 mode = Pmode;
4fbc4db5 5320
4fbc4db5 5321 dst_addr = gen_reg_rtx (Pmode);
5322 src_addr = gen_reg_rtx (Pmode);
5323 count = gen_reg_rtx (mode);
5324 blocks = gen_reg_rtx (mode);
5325
5326 convert_move (count, len, 1);
f81e845f 5327 emit_cmp_and_jump_insns (count, const0_rtx,
4fbc4db5 5328 EQ, NULL_RTX, mode, 1, end_label);
5329
5330 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
5331 emit_move_insn (src_addr, force_operand (XEXP (src, 0), NULL_RTX));
5332 dst = change_address (dst, VOIDmode, dst_addr);
5333 src = change_address (src, VOIDmode, src_addr);
f81e845f 5334
b9c74b4d 5335 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1,
5336 OPTAB_DIRECT);
4fbc4db5 5337 if (temp != count)
5338 emit_move_insn (count, temp);
5339
b9c74b4d 5340 temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1,
5341 OPTAB_DIRECT);
4fbc4db5 5342 if (temp != blocks)
5343 emit_move_insn (blocks, temp);
5344
4ee9c684 5345 emit_cmp_and_jump_insns (blocks, const0_rtx,
5346 EQ, NULL_RTX, mode, 1, loop_end_label);
7746964e 5347
5348 emit_label (loop_start_label);
4fbc4db5 5349
d5de7805 5350 if (TARGET_Z10
5351 && (GET_CODE (len) != CONST_INT || INTVAL (len) > 768))
5352 {
5353 rtx prefetch;
5354
5355 /* Issue a read prefetch for the +3 cache line. */
5356 prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, src_addr, GEN_INT (768)),
5357 const0_rtx, const0_rtx);
5358 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
5359 emit_insn (prefetch);
5360
5361 /* Issue a write prefetch for the +3 cache line. */
5362 prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (768)),
5363 const1_rtx, const0_rtx);
5364 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
5365 emit_insn (prefetch);
5366 }
5367
008c057d 5368 emit_insn (gen_movmem_short (dst, src, GEN_INT (255)));
f81e845f 5369 s390_load_address (dst_addr,
4fbc4db5 5370 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
f81e845f 5371 s390_load_address (src_addr,
4fbc4db5 5372 gen_rtx_PLUS (Pmode, src_addr, GEN_INT (256)));
f81e845f 5373
b9c74b4d 5374 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1,
5375 OPTAB_DIRECT);
4fbc4db5 5376 if (temp != blocks)
5377 emit_move_insn (blocks, temp);
5378
4ee9c684 5379 emit_cmp_and_jump_insns (blocks, const0_rtx,
5380 EQ, NULL_RTX, mode, 1, loop_end_label);
7746964e 5381
5382 emit_jump (loop_start_label);
4ee9c684 5383 emit_label (loop_end_label);
4fbc4db5 5384
008c057d 5385 emit_insn (gen_movmem_short (dst, src,
31838f66 5386 convert_to_mode (Pmode, count, 1)));
4fbc4db5 5387 emit_label (end_label);
5388 }
daa87e5a 5389 return true;
4fbc4db5 5390}
5391
805a133b 5392/* Emit code to set LEN bytes at DST to VAL.
5393 Make use of clrmem if VAL is zero. */
4fbc4db5 5394
5395void
805a133b 5396s390_expand_setmem (rtx dst, rtx len, rtx val)
4fbc4db5 5397{
2b1d59f5 5398 if (GET_CODE (len) == CONST_INT && INTVAL (len) <= 0)
1ed6fd08 5399 return;
5400
805a133b 5401 gcc_assert (GET_CODE (val) == CONST_INT || GET_MODE (val) == QImode);
ffead1ca 5402
2b1d59f5 5403 /* Expand setmem/clrmem for a constant length operand without a
5404 loop if it will be shorter that way.
5405 With a constant length and without pfd argument a
5406 clrmem loop is 32 bytes -> 5.3 * xc
5407 setmem loop is 36 bytes -> 3.6 * (mvi/stc + mvc) */
5408 if (GET_CODE (len) == CONST_INT
5409 && ((INTVAL (len) <= 256 * 5 && val == const0_rtx)
5410 || INTVAL (len) <= 257 * 3)
5411 && (!TARGET_MVCLE || INTVAL (len) <= 256))
4fbc4db5 5412 {
2b1d59f5 5413 HOST_WIDE_INT o, l;
ffead1ca 5414
2b1d59f5 5415 if (val == const0_rtx)
5416 /* clrmem: emit 256 byte blockwise XCs. */
5417 for (l = INTVAL (len), o = 0; l > 0; l -= 256, o += 256)
5418 {
5419 rtx newdst = adjust_address (dst, BLKmode, o);
5420 emit_insn (gen_clrmem_short (newdst,
5421 GEN_INT (l > 256 ? 255 : l - 1)));
5422 }
5423 else
5424 /* setmem: emit 1(mvi) + 256(mvc) byte blockwise memsets by
5425 setting first byte to val and using a 256 byte mvc with one
5426 byte overlap to propagate the byte. */
5427 for (l = INTVAL (len), o = 0; l > 0; l -= 257, o += 257)
5428 {
5429 rtx newdst = adjust_address (dst, BLKmode, o);
5430 emit_move_insn (adjust_address (dst, QImode, o), val);
5431 if (l > 1)
5432 {
5433 rtx newdstp1 = adjust_address (dst, BLKmode, o + 1);
5434 emit_insn (gen_movmem_short (newdstp1, newdst,
5435 GEN_INT (l > 257 ? 255 : l - 2)));
5436 }
5437 }
4fbc4db5 5438 }
5439
5440 else if (TARGET_MVCLE)
5441 {
805a133b 5442 val = force_not_mem (convert_modes (Pmode, QImode, val, 1));
00091884 5443 if (TARGET_64BIT)
5444 emit_insn (gen_setmem_long_di (dst, convert_to_mode (Pmode, len, 1),
5445 val));
5446 else
5447 emit_insn (gen_setmem_long_si (dst, convert_to_mode (Pmode, len, 1),
5448 val));
4fbc4db5 5449 }
5450
5451 else
5452 {
b5fdc416 5453 rtx dst_addr, count, blocks, temp, dstp1 = NULL_RTX;
79f6a8ed 5454 rtx_code_label *loop_start_label = gen_label_rtx ();
4b6f12fb 5455 rtx_code_label *onebyte_end_label = gen_label_rtx ();
5456 rtx_code_label *zerobyte_end_label = gen_label_rtx ();
5457 rtx_code_label *restbyte_end_label = gen_label_rtx ();
3754d046 5458 machine_mode mode;
4fbc4db5 5459
5460 mode = GET_MODE (len);
5461 if (mode == VOIDmode)
4b6f12fb 5462 mode = Pmode;
4fbc4db5 5463
4fbc4db5 5464 dst_addr = gen_reg_rtx (Pmode);
4fbc4db5 5465 count = gen_reg_rtx (mode);
5466 blocks = gen_reg_rtx (mode);
5467
5468 convert_move (count, len, 1);
f81e845f 5469 emit_cmp_and_jump_insns (count, const0_rtx,
4b6f12fb 5470 EQ, NULL_RTX, mode, 1, zerobyte_end_label,
6394f7ee 5471 profile_probability::very_unlikely ());
4fbc4db5 5472
4b6f12fb 5473 /* We need to make a copy of the target address since memset is
5474 supposed to return it unmodified. We have to make it here
5475 already since the new reg is used at onebyte_end_label. */
4fbc4db5 5476 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
5477 dst = change_address (dst, VOIDmode, dst_addr);
f81e845f 5478
4b6f12fb 5479 if (val != const0_rtx)
805a133b 5480 {
4b6f12fb 5481 /* When using the overlapping mvc the original target
5482 address is only accessed as single byte entity (even by
5483 the mvc reading this value). */
5b2a69fa 5484 set_mem_size (dst, 1);
4b6f12fb 5485 dstp1 = adjust_address (dst, VOIDmode, 1);
5486 emit_cmp_and_jump_insns (count,
5487 const1_rtx, EQ, NULL_RTX, mode, 1,
6394f7ee 5488 onebyte_end_label,
5489 profile_probability::very_unlikely ());
805a133b 5490 }
4b6f12fb 5491
5492 /* There is one unconditional (mvi+mvc)/xc after the loop
5493 dealing with the rest of the bytes, subtracting two (mvi+mvc)
5494 or one (xc) here leaves this number of bytes to be handled by
5495 it. */
5496 temp = expand_binop (mode, add_optab, count,
5497 val == const0_rtx ? constm1_rtx : GEN_INT (-2),
5498 count, 1, OPTAB_DIRECT);
4fbc4db5 5499 if (temp != count)
4b6f12fb 5500 emit_move_insn (count, temp);
4fbc4db5 5501
b9c74b4d 5502 temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1,
5503 OPTAB_DIRECT);
4fbc4db5 5504 if (temp != blocks)
4b6f12fb 5505 emit_move_insn (blocks, temp);
4fbc4db5 5506
4ee9c684 5507 emit_cmp_and_jump_insns (blocks, const0_rtx,
4b6f12fb 5508 EQ, NULL_RTX, mode, 1, restbyte_end_label);
5509
5510 emit_jump (loop_start_label);
5511
5512 if (val != const0_rtx)
5513 {
5514 /* The 1 byte != 0 special case. Not handled efficiently
5515 since we require two jumps for that. However, this
5516 should be very rare. */
5517 emit_label (onebyte_end_label);
5518 emit_move_insn (adjust_address (dst, QImode, 0), val);
5519 emit_jump (zerobyte_end_label);
5520 }
7746964e 5521
5522 emit_label (loop_start_label);
4fbc4db5 5523
d5de7805 5524 if (TARGET_Z10
5525 && (GET_CODE (len) != CONST_INT || INTVAL (len) > 1024))
5526 {
5527 /* Issue a write prefetch for the +4 cache line. */
5528 rtx prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, dst_addr,
5529 GEN_INT (1024)),
5530 const1_rtx, const0_rtx);
5531 emit_insn (prefetch);
5532 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
5533 }
5534
805a133b 5535 if (val == const0_rtx)
5536 emit_insn (gen_clrmem_short (dst, GEN_INT (255)));
5537 else
4b6f12fb 5538 {
5539 /* Set the first byte in the block to the value and use an
5540 overlapping mvc for the block. */
5541 emit_move_insn (adjust_address (dst, QImode, 0), val);
5542 emit_insn (gen_movmem_short (dstp1, dst, GEN_INT (254)));
5543 }
f81e845f 5544 s390_load_address (dst_addr,
4fbc4db5 5545 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
f81e845f 5546
b9c74b4d 5547 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1,
5548 OPTAB_DIRECT);
4fbc4db5 5549 if (temp != blocks)
4b6f12fb 5550 emit_move_insn (blocks, temp);
4fbc4db5 5551
4ee9c684 5552 emit_cmp_and_jump_insns (blocks, const0_rtx,
4b6f12fb 5553 NE, NULL_RTX, mode, 1, loop_start_label);
7746964e 5554
4b6f12fb 5555 emit_label (restbyte_end_label);
4fbc4db5 5556
805a133b 5557 if (val == const0_rtx)
4b6f12fb 5558 emit_insn (gen_clrmem_short (dst, convert_to_mode (Pmode, count, 1)));
805a133b 5559 else
4b6f12fb 5560 {
5561 /* Set the first byte in the block to the value and use an
5562 overlapping mvc for the block. */
5563 emit_move_insn (adjust_address (dst, QImode, 0), val);
5564 /* execute only uses the lowest 8 bits of count that's
5565 exactly what we need here. */
5566 emit_insn (gen_movmem_short (dstp1, dst,
5567 convert_to_mode (Pmode, count, 1)));
5568 }
5569
5570 emit_label (zerobyte_end_label);
4fbc4db5 5571 }
5572}
5573
5574/* Emit code to compare LEN bytes at OP0 with those at OP1,
5575 and return the result in TARGET. */
5576
daa87e5a 5577bool
b40da9a7 5578s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
4fbc4db5 5579{
80b53886 5580 rtx ccreg = gen_rtx_REG (CCUmode, CC_REGNUM);
dd16a4bd 5581 rtx tmp;
5582
daa87e5a 5583 /* When tuning for z10 or higher we rely on the Glibc functions to
5584 do the right thing. Only for constant lengths below 64k we will
5585 generate inline code. */
5586 if (s390_tune >= PROCESSOR_2097_Z10
5587 && (GET_CODE (len) != CONST_INT || INTVAL (len) > (1<<16)))
5588 return false;
5589
dd16a4bd 5590 /* As the result of CMPINT is inverted compared to what we need,
5591 we have to swap the operands. */
5592 tmp = op0; op0 = op1; op1 = tmp;
4fbc4db5 5593
4fbc4db5 5594 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
5595 {
5596 if (INTVAL (len) > 0)
5597 {
31838f66 5598 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (INTVAL (len) - 1)));
dd16a4bd 5599 emit_insn (gen_cmpint (target, ccreg));
4fbc4db5 5600 }
5601 else
5602 emit_move_insn (target, const0_rtx);
5603 }
bcbf02a5 5604 else if (TARGET_MVCLE)
4fbc4db5 5605 {
31838f66 5606 emit_insn (gen_cmpmem_long (op0, op1, convert_to_mode (Pmode, len, 1)));
dd16a4bd 5607 emit_insn (gen_cmpint (target, ccreg));
4fbc4db5 5608 }
4fbc4db5 5609 else
5610 {
5611 rtx addr0, addr1, count, blocks, temp;
79f6a8ed 5612 rtx_code_label *loop_start_label = gen_label_rtx ();
5613 rtx_code_label *loop_end_label = gen_label_rtx ();
5614 rtx_code_label *end_label = gen_label_rtx ();
3754d046 5615 machine_mode mode;
4fbc4db5 5616
5617 mode = GET_MODE (len);
5618 if (mode == VOIDmode)
31838f66 5619 mode = Pmode;
4fbc4db5 5620
4fbc4db5 5621 addr0 = gen_reg_rtx (Pmode);
5622 addr1 = gen_reg_rtx (Pmode);
5623 count = gen_reg_rtx (mode);
5624 blocks = gen_reg_rtx (mode);
5625
5626 convert_move (count, len, 1);
f81e845f 5627 emit_cmp_and_jump_insns (count, const0_rtx,
4fbc4db5 5628 EQ, NULL_RTX, mode, 1, end_label);
5629
5630 emit_move_insn (addr0, force_operand (XEXP (op0, 0), NULL_RTX));
5631 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
5632 op0 = change_address (op0, VOIDmode, addr0);
5633 op1 = change_address (op1, VOIDmode, addr1);
f81e845f 5634
b9c74b4d 5635 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1,
5636 OPTAB_DIRECT);
4fbc4db5 5637 if (temp != count)
5638 emit_move_insn (count, temp);
5639
b9c74b4d 5640 temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1,
5641 OPTAB_DIRECT);
4fbc4db5 5642 if (temp != blocks)
5643 emit_move_insn (blocks, temp);
5644
4ee9c684 5645 emit_cmp_and_jump_insns (blocks, const0_rtx,
5646 EQ, NULL_RTX, mode, 1, loop_end_label);
7746964e 5647
5648 emit_label (loop_start_label);
4fbc4db5 5649
d5de7805 5650 if (TARGET_Z10
5651 && (GET_CODE (len) != CONST_INT || INTVAL (len) > 512))
5652 {
5653 rtx prefetch;
5654
5655 /* Issue a read prefetch for the +2 cache line of operand 1. */
5656 prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, addr0, GEN_INT (512)),
5657 const0_rtx, const0_rtx);
5658 emit_insn (prefetch);
5659 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
5660
5661 /* Issue a read prefetch for the +2 cache line of operand 2. */
5662 prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, addr1, GEN_INT (512)),
5663 const0_rtx, const0_rtx);
5664 emit_insn (prefetch);
5665 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
5666 }
5667
31838f66 5668 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (255)));
80b53886 5669 temp = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
f81e845f 5670 temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
4fbc4db5 5671 gen_rtx_LABEL_REF (VOIDmode, end_label), pc_rtx);
d1f9b275 5672 temp = gen_rtx_SET (pc_rtx, temp);
4fbc4db5 5673 emit_jump_insn (temp);
5674
f81e845f 5675 s390_load_address (addr0,
4fbc4db5 5676 gen_rtx_PLUS (Pmode, addr0, GEN_INT (256)));
f81e845f 5677 s390_load_address (addr1,
4fbc4db5 5678 gen_rtx_PLUS (Pmode, addr1, GEN_INT (256)));
f81e845f 5679
b9c74b4d 5680 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1,
5681 OPTAB_DIRECT);
4fbc4db5 5682 if (temp != blocks)
5683 emit_move_insn (blocks, temp);
5684
4ee9c684 5685 emit_cmp_and_jump_insns (blocks, const0_rtx,
5686 EQ, NULL_RTX, mode, 1, loop_end_label);
7746964e 5687
5688 emit_jump (loop_start_label);
4ee9c684 5689 emit_label (loop_end_label);
4fbc4db5 5690
f588eb9f 5691 emit_insn (gen_cmpmem_short (op0, op1,
31838f66 5692 convert_to_mode (Pmode, count, 1)));
4fbc4db5 5693 emit_label (end_label);
5694
dd16a4bd 5695 emit_insn (gen_cmpint (target, ccreg));
4fbc4db5 5696 }
daa87e5a 5697 return true;
4fbc4db5 5698}
5699
76a4c804 5700/* Emit a conditional jump to LABEL for condition code mask MASK using
5701 comparsion operator COMPARISON. Return the emitted jump insn. */
5702
26cd1198 5703static rtx_insn *
76a4c804 5704s390_emit_ccraw_jump (HOST_WIDE_INT mask, enum rtx_code comparison, rtx label)
5705{
5706 rtx temp;
5707
5708 gcc_assert (comparison == EQ || comparison == NE);
5709 gcc_assert (mask > 0 && mask < 15);
5710
5711 temp = gen_rtx_fmt_ee (comparison, VOIDmode,
5712 gen_rtx_REG (CCRAWmode, CC_REGNUM), GEN_INT (mask));
5713 temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
5714 gen_rtx_LABEL_REF (VOIDmode, label), pc_rtx);
5715 temp = gen_rtx_SET (pc_rtx, temp);
5716 return emit_jump_insn (temp);
5717}
5718
5719/* Emit the instructions to implement strlen of STRING and store the
5720 result in TARGET. The string has the known ALIGNMENT. This
5721 version uses vector instructions and is therefore not appropriate
5722 for targets prior to z13. */
5723
5724void
5725s390_expand_vec_strlen (rtx target, rtx string, rtx alignment)
5726{
76a4c804 5727 rtx highest_index_to_load_reg = gen_reg_rtx (Pmode);
5728 rtx str_reg = gen_reg_rtx (V16QImode);
5729 rtx str_addr_base_reg = gen_reg_rtx (Pmode);
5730 rtx str_idx_reg = gen_reg_rtx (Pmode);
5731 rtx result_reg = gen_reg_rtx (V16QImode);
5732 rtx is_aligned_label = gen_label_rtx ();
5733 rtx into_loop_label = NULL_RTX;
5734 rtx loop_start_label = gen_label_rtx ();
5735 rtx temp;
5736 rtx len = gen_reg_rtx (QImode);
5737 rtx cond;
5738
5739 s390_load_address (str_addr_base_reg, XEXP (string, 0));
5740 emit_move_insn (str_idx_reg, const0_rtx);
5741
5742 if (INTVAL (alignment) < 16)
5743 {
5744 /* Check whether the address happens to be aligned properly so
5745 jump directly to the aligned loop. */
5746 emit_cmp_and_jump_insns (gen_rtx_AND (Pmode,
5747 str_addr_base_reg, GEN_INT (15)),
5748 const0_rtx, EQ, NULL_RTX,
5749 Pmode, 1, is_aligned_label);
5750
5751 temp = gen_reg_rtx (Pmode);
5752 temp = expand_binop (Pmode, and_optab, str_addr_base_reg,
5753 GEN_INT (15), temp, 1, OPTAB_DIRECT);
5754 gcc_assert (REG_P (temp));
5755 highest_index_to_load_reg =
5756 expand_binop (Pmode, sub_optab, GEN_INT (15), temp,
5757 highest_index_to_load_reg, 1, OPTAB_DIRECT);
5758 gcc_assert (REG_P (highest_index_to_load_reg));
5759 emit_insn (gen_vllv16qi (str_reg,
5760 convert_to_mode (SImode, highest_index_to_load_reg, 1),
5761 gen_rtx_MEM (BLKmode, str_addr_base_reg)));
5762
5763 into_loop_label = gen_label_rtx ();
5764 s390_emit_jump (into_loop_label, NULL_RTX);
5765 emit_barrier ();
5766 }
5767
5768 emit_label (is_aligned_label);
5769 LABEL_NUSES (is_aligned_label) = INTVAL (alignment) < 16 ? 2 : 1;
5770
5771 /* Reaching this point we are only performing 16 bytes aligned
5772 loads. */
5773 emit_move_insn (highest_index_to_load_reg, GEN_INT (15));
5774
5775 emit_label (loop_start_label);
5776 LABEL_NUSES (loop_start_label) = 1;
5777
5778 /* Load 16 bytes of the string into VR. */
5779 emit_move_insn (str_reg,
5780 gen_rtx_MEM (V16QImode,
5781 gen_rtx_PLUS (Pmode, str_idx_reg,
5782 str_addr_base_reg)));
5783 if (into_loop_label != NULL_RTX)
5784 {
5785 emit_label (into_loop_label);
5786 LABEL_NUSES (into_loop_label) = 1;
5787 }
5788
5789 /* Increment string index by 16 bytes. */
5790 expand_binop (Pmode, add_optab, str_idx_reg, GEN_INT (16),
5791 str_idx_reg, 1, OPTAB_DIRECT);
5792
5793 emit_insn (gen_vec_vfenesv16qi (result_reg, str_reg, str_reg,
5794 GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS)));
5795
5796 add_int_reg_note (s390_emit_ccraw_jump (8, NE, loop_start_label),
61cb1816 5797 REG_BR_PROB,
5798 profile_probability::very_likely ().to_reg_br_prob_note ());
447443f5 5799 emit_insn (gen_vec_extractv16qiqi (len, result_reg, GEN_INT (7)));
76a4c804 5800
5801 /* If the string pointer wasn't aligned we have loaded less then 16
5802 bytes and the remaining bytes got filled with zeros (by vll).
5803 Now we have to check whether the resulting index lies within the
5804 bytes actually part of the string. */
5805
5806 cond = s390_emit_compare (GT, convert_to_mode (Pmode, len, 1),
5807 highest_index_to_load_reg);
5808 s390_load_address (highest_index_to_load_reg,
5809 gen_rtx_PLUS (Pmode, highest_index_to_load_reg,
5810 const1_rtx));
5811 if (TARGET_64BIT)
5812 emit_insn (gen_movdicc (str_idx_reg, cond,
5813 highest_index_to_load_reg, str_idx_reg));
5814 else
5815 emit_insn (gen_movsicc (str_idx_reg, cond,
5816 highest_index_to_load_reg, str_idx_reg));
5817
61cb1816 5818 add_reg_br_prob_note (s390_emit_jump (is_aligned_label, cond),
5819 profile_probability::very_unlikely ());
76a4c804 5820
5821 expand_binop (Pmode, add_optab, str_idx_reg,
5822 GEN_INT (-16), str_idx_reg, 1, OPTAB_DIRECT);
5823 /* FIXME: len is already zero extended - so avoid the llgcr emitted
5824 here. */
5825 temp = expand_binop (Pmode, add_optab, str_idx_reg,
5826 convert_to_mode (Pmode, len, 1),
5827 target, 1, OPTAB_DIRECT);
5828 if (temp != target)
5829 emit_move_insn (target, temp);
5830}
3b699fc7 5831
664ff6a0 5832void
5833s390_expand_vec_movstr (rtx result, rtx dst, rtx src)
5834{
664ff6a0 5835 rtx temp = gen_reg_rtx (Pmode);
5836 rtx src_addr = XEXP (src, 0);
5837 rtx dst_addr = XEXP (dst, 0);
5838 rtx src_addr_reg = gen_reg_rtx (Pmode);
5839 rtx dst_addr_reg = gen_reg_rtx (Pmode);
5840 rtx offset = gen_reg_rtx (Pmode);
5841 rtx vsrc = gen_reg_rtx (V16QImode);
5842 rtx vpos = gen_reg_rtx (V16QImode);
5843 rtx loadlen = gen_reg_rtx (SImode);
5844 rtx gpos_qi = gen_reg_rtx(QImode);
5845 rtx gpos = gen_reg_rtx (SImode);
5846 rtx done_label = gen_label_rtx ();
5847 rtx loop_label = gen_label_rtx ();
5848 rtx exit_label = gen_label_rtx ();
5849 rtx full_label = gen_label_rtx ();
5850
5851 /* Perform a quick check for string ending on the first up to 16
5852 bytes and exit early if successful. */
5853
5854 emit_insn (gen_vlbb (vsrc, src, GEN_INT (6)));
5855 emit_insn (gen_lcbb (loadlen, src_addr, GEN_INT (6)));
5856 emit_insn (gen_vfenezv16qi (vpos, vsrc, vsrc));
447443f5 5857 emit_insn (gen_vec_extractv16qiqi (gpos_qi, vpos, GEN_INT (7)));
664ff6a0 5858 emit_move_insn (gpos, gen_rtx_SUBREG (SImode, gpos_qi, 0));
5859 /* gpos is the byte index if a zero was found and 16 otherwise.
5860 So if it is lower than the loaded bytes we have a hit. */
5861 emit_cmp_and_jump_insns (gpos, loadlen, GE, NULL_RTX, SImode, 1,
5862 full_label);
5863 emit_insn (gen_vstlv16qi (vsrc, gpos, dst));
5864
5865 force_expand_binop (Pmode, add_optab, dst_addr, gpos, result,
5866 1, OPTAB_DIRECT);
5867 emit_jump (exit_label);
5868 emit_barrier ();
5869
5870 emit_label (full_label);
5871 LABEL_NUSES (full_label) = 1;
5872
5873 /* Calculate `offset' so that src + offset points to the last byte
5874 before 16 byte alignment. */
5875
5876 /* temp = src_addr & 0xf */
5877 force_expand_binop (Pmode, and_optab, src_addr, GEN_INT (15), temp,
5878 1, OPTAB_DIRECT);
5879
5880 /* offset = 0xf - temp */
5881 emit_move_insn (offset, GEN_INT (15));
5882 force_expand_binop (Pmode, sub_optab, offset, temp, offset,
5883 1, OPTAB_DIRECT);
5884
5885 /* Store `offset' bytes in the dstination string. The quick check
5886 has loaded at least `offset' bytes into vsrc. */
5887
5888 emit_insn (gen_vstlv16qi (vsrc, gen_lowpart (SImode, offset), dst));
5889
5890 /* Advance to the next byte to be loaded. */
5891 force_expand_binop (Pmode, add_optab, offset, const1_rtx, offset,
5892 1, OPTAB_DIRECT);
5893
5894 /* Make sure the addresses are single regs which can be used as a
5895 base. */
5896 emit_move_insn (src_addr_reg, src_addr);
5897 emit_move_insn (dst_addr_reg, dst_addr);
5898
5899 /* MAIN LOOP */
5900
5901 emit_label (loop_label);
5902 LABEL_NUSES (loop_label) = 1;
5903
5904 emit_move_insn (vsrc,
5905 gen_rtx_MEM (V16QImode,
5906 gen_rtx_PLUS (Pmode, src_addr_reg, offset)));
5907
5908 emit_insn (gen_vec_vfenesv16qi (vpos, vsrc, vsrc,
5909 GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS)));
5910 add_int_reg_note (s390_emit_ccraw_jump (8, EQ, done_label),
61cb1816 5911 REG_BR_PROB, profile_probability::very_unlikely ()
5912 .to_reg_br_prob_note ());
664ff6a0 5913
5914 emit_move_insn (gen_rtx_MEM (V16QImode,
5915 gen_rtx_PLUS (Pmode, dst_addr_reg, offset)),
5916 vsrc);
5917 /* offset += 16 */
5918 force_expand_binop (Pmode, add_optab, offset, GEN_INT (16),
5919 offset, 1, OPTAB_DIRECT);
5920
5921 emit_jump (loop_label);
5922 emit_barrier ();
5923
5924 /* REGULAR EXIT */
5925
5926 /* We are done. Add the offset of the zero character to the dst_addr
5927 pointer to get the result. */
5928
5929 emit_label (done_label);
5930 LABEL_NUSES (done_label) = 1;
5931
5932 force_expand_binop (Pmode, add_optab, dst_addr_reg, offset, dst_addr_reg,
5933 1, OPTAB_DIRECT);
5934
447443f5 5935 emit_insn (gen_vec_extractv16qiqi (gpos_qi, vpos, GEN_INT (7)));
664ff6a0 5936 emit_move_insn (gpos, gen_rtx_SUBREG (SImode, gpos_qi, 0));
5937
5938 emit_insn (gen_vstlv16qi (vsrc, gpos, gen_rtx_MEM (BLKmode, dst_addr_reg)));
5939
5940 force_expand_binop (Pmode, add_optab, dst_addr_reg, gpos, result,
5941 1, OPTAB_DIRECT);
5942
5943 /* EARLY EXIT */
5944
5945 emit_label (exit_label);
5946 LABEL_NUSES (exit_label) = 1;
5947}
5948
5949
3b699fc7 5950/* Expand conditional increment or decrement using alc/slb instructions.
5951 Should generate code setting DST to either SRC or SRC + INCREMENT,
5952 depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
eeba5f25 5953 Returns true if successful, false otherwise.
5954
5955 That makes it possible to implement some if-constructs without jumps e.g.:
5956 (borrow = CC0 | CC1 and carry = CC2 | CC3)
5957 unsigned int a, b, c;
5958 if (a < b) c++; -> CCU b > a -> CC2; c += carry;
5959 if (a < b) c--; -> CCL3 a - b -> borrow; c -= borrow;
5960 if (a <= b) c++; -> CCL3 b - a -> borrow; c += carry;
5961 if (a <= b) c--; -> CCU a <= b -> borrow; c -= borrow;
5962
5963 Checks for EQ and NE with a nonzero value need an additional xor e.g.:
5964 if (a == b) c++; -> CCL3 a ^= b; 0 - a -> borrow; c += carry;
5965 if (a == b) c--; -> CCU a ^= b; a <= 0 -> CC0 | CC1; c -= borrow;
5966 if (a != b) c++; -> CCU a ^= b; a > 0 -> CC2; c += carry;
5967 if (a != b) c--; -> CCL3 a ^= b; 0 - a -> borrow; c -= borrow; */
3b699fc7 5968
5969bool
5970s390_expand_addcc (enum rtx_code cmp_code, rtx cmp_op0, rtx cmp_op1,
5971 rtx dst, rtx src, rtx increment)
5972{
3754d046 5973 machine_mode cmp_mode;
5974 machine_mode cc_mode;
3b699fc7 5975 rtx op_res;
5976 rtx insn;
5977 rtvec p;
32eda510 5978 int ret;
3b699fc7 5979
5980 if ((GET_MODE (cmp_op0) == SImode || GET_MODE (cmp_op0) == VOIDmode)
5981 && (GET_MODE (cmp_op1) == SImode || GET_MODE (cmp_op1) == VOIDmode))
5982 cmp_mode = SImode;
5983 else if ((GET_MODE (cmp_op0) == DImode || GET_MODE (cmp_op0) == VOIDmode)
5984 && (GET_MODE (cmp_op1) == DImode || GET_MODE (cmp_op1) == VOIDmode))
5985 cmp_mode = DImode;
5986 else
5987 return false;
5988
5989 /* Try ADD LOGICAL WITH CARRY. */
5990 if (increment == const1_rtx)
5991 {
5992 /* Determine CC mode to use. */
5993 if (cmp_code == EQ || cmp_code == NE)
5994 {
5995 if (cmp_op1 != const0_rtx)
5996 {
5997 cmp_op0 = expand_simple_binop (cmp_mode, XOR, cmp_op0, cmp_op1,
5998 NULL_RTX, 0, OPTAB_WIDEN);
5999 cmp_op1 = const0_rtx;
6000 }
6001
6002 cmp_code = cmp_code == EQ ? LEU : GTU;
6003 }
6004
6005 if (cmp_code == LTU || cmp_code == LEU)
6006 {
6007 rtx tem = cmp_op0;
6008 cmp_op0 = cmp_op1;
6009 cmp_op1 = tem;
6010 cmp_code = swap_condition (cmp_code);
6011 }
6012
6013 switch (cmp_code)
6014 {
6015 case GTU:
6016 cc_mode = CCUmode;
6017 break;
6018
6019 case GEU:
6020 cc_mode = CCL3mode;
6021 break;
6022
6023 default:
6024 return false;
6025 }
6026
6027 /* Emit comparison instruction pattern. */
6028 if (!register_operand (cmp_op0, cmp_mode))
6029 cmp_op0 = force_reg (cmp_mode, cmp_op0);
6030
d1f9b275 6031 insn = gen_rtx_SET (gen_rtx_REG (cc_mode, CC_REGNUM),
3b699fc7 6032 gen_rtx_COMPARE (cc_mode, cmp_op0, cmp_op1));
6033 /* We use insn_invalid_p here to add clobbers if required. */
dae9d0e7 6034 ret = insn_invalid_p (emit_insn (insn), false);
32eda510 6035 gcc_assert (!ret);
3b699fc7 6036
6037 /* Emit ALC instruction pattern. */
6038 op_res = gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
6039 gen_rtx_REG (cc_mode, CC_REGNUM),
6040 const0_rtx);
6041
6042 if (src != const0_rtx)
6043 {
6044 if (!register_operand (src, GET_MODE (dst)))
6045 src = force_reg (GET_MODE (dst), src);
6046
6f4afa7e 6047 op_res = gen_rtx_PLUS (GET_MODE (dst), op_res, src);
6048 op_res = gen_rtx_PLUS (GET_MODE (dst), op_res, const0_rtx);
3b699fc7 6049 }
6050
6051 p = rtvec_alloc (2);
ffead1ca 6052 RTVEC_ELT (p, 0) =
d1f9b275 6053 gen_rtx_SET (dst, op_res);
ffead1ca 6054 RTVEC_ELT (p, 1) =
3b699fc7 6055 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
6056 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
6057
6058 return true;
6059 }
6060
6061 /* Try SUBTRACT LOGICAL WITH BORROW. */
6062 if (increment == constm1_rtx)
6063 {
6064 /* Determine CC mode to use. */
6065 if (cmp_code == EQ || cmp_code == NE)
6066 {
6067 if (cmp_op1 != const0_rtx)
6068 {
6069 cmp_op0 = expand_simple_binop (cmp_mode, XOR, cmp_op0, cmp_op1,
6070 NULL_RTX, 0, OPTAB_WIDEN);
6071 cmp_op1 = const0_rtx;
6072 }
6073
6074 cmp_code = cmp_code == EQ ? LEU : GTU;
6075 }
6076
6077 if (cmp_code == GTU || cmp_code == GEU)
6078 {
6079 rtx tem = cmp_op0;
6080 cmp_op0 = cmp_op1;
6081 cmp_op1 = tem;
6082 cmp_code = swap_condition (cmp_code);
6083 }
6084
6085 switch (cmp_code)
6086 {
6087 case LEU:
6088 cc_mode = CCUmode;
6089 break;
6090
6091 case LTU:
6092 cc_mode = CCL3mode;
6093 break;
6094
6095 default:
6096 return false;
6097 }
6098
6099 /* Emit comparison instruction pattern. */
6100 if (!register_operand (cmp_op0, cmp_mode))
6101 cmp_op0 = force_reg (cmp_mode, cmp_op0);
6102
d1f9b275 6103 insn = gen_rtx_SET (gen_rtx_REG (cc_mode, CC_REGNUM),
3b699fc7 6104 gen_rtx_COMPARE (cc_mode, cmp_op0, cmp_op1));
6105 /* We use insn_invalid_p here to add clobbers if required. */
dae9d0e7 6106 ret = insn_invalid_p (emit_insn (insn), false);
32eda510 6107 gcc_assert (!ret);
3b699fc7 6108
6109 /* Emit SLB instruction pattern. */
6110 if (!register_operand (src, GET_MODE (dst)))
6111 src = force_reg (GET_MODE (dst), src);
6112
ffead1ca 6113 op_res = gen_rtx_MINUS (GET_MODE (dst),
6114 gen_rtx_MINUS (GET_MODE (dst), src, const0_rtx),
6115 gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
6116 gen_rtx_REG (cc_mode, CC_REGNUM),
3b699fc7 6117 const0_rtx));
6118 p = rtvec_alloc (2);
ffead1ca 6119 RTVEC_ELT (p, 0) =
d1f9b275 6120 gen_rtx_SET (dst, op_res);
ffead1ca 6121 RTVEC_ELT (p, 1) =
3b699fc7 6122 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
6123 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
6124
6125 return true;
6126 }
6127
6128 return false;
6129}
6130
e68d6a13 6131/* Expand code for the insv template. Return true if successful. */
0349cc73 6132
e68d6a13 6133bool
0349cc73 6134s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src)
6135{
6136 int bitsize = INTVAL (op1);
6137 int bitpos = INTVAL (op2);
3754d046 6138 machine_mode mode = GET_MODE (dest);
6139 machine_mode smode;
8c753480 6140 int smode_bsize, mode_bsize;
6141 rtx op, clobber;
0349cc73 6142
0bc377b9 6143 if (bitsize + bitpos > GET_MODE_BITSIZE (mode))
31efd1ec 6144 return false;
6145
8c753480 6146 /* Generate INSERT IMMEDIATE (IILL et al). */
6147 /* (set (ze (reg)) (const_int)). */
6148 if (TARGET_ZARCH
6149 && register_operand (dest, word_mode)
6150 && (bitpos % 16) == 0
6151 && (bitsize % 16) == 0
6152 && const_int_operand (src, VOIDmode))
e68d6a13 6153 {
8c753480 6154 HOST_WIDE_INT val = INTVAL (src);
6155 int regpos = bitpos + bitsize;
e68d6a13 6156
8c753480 6157 while (regpos > bitpos)
6158 {
3754d046 6159 machine_mode putmode;
8c753480 6160 int putsize;
6161
6162 if (TARGET_EXTIMM && (regpos % 32 == 0) && (regpos >= bitpos + 32))
6163 putmode = SImode;
6164 else
6165 putmode = HImode;
e68d6a13 6166
8c753480 6167 putsize = GET_MODE_BITSIZE (putmode);
6168 regpos -= putsize;
6169 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest,
6170 GEN_INT (putsize),
6171 GEN_INT (regpos)),
6172 gen_int_mode (val, putmode));
6173 val >>= putsize;
6174 }
6175 gcc_assert (regpos == bitpos);
e68d6a13 6176 return true;
6177 }
6178
8c753480 6179 smode = smallest_mode_for_size (bitsize, MODE_INT);
6180 smode_bsize = GET_MODE_BITSIZE (smode);
6181 mode_bsize = GET_MODE_BITSIZE (mode);
0349cc73 6182
8c753480 6183 /* Generate STORE CHARACTERS UNDER MASK (STCM et al). */
0349cc73 6184 if (bitpos == 0
8c753480 6185 && (bitsize % BITS_PER_UNIT) == 0
6186 && MEM_P (dest)
0349cc73 6187 && (register_operand (src, word_mode)
6188 || const_int_operand (src, VOIDmode)))
6189 {
6190 /* Emit standard pattern if possible. */
8c753480 6191 if (smode_bsize == bitsize)
6192 {
6193 emit_move_insn (adjust_address (dest, smode, 0),
6194 gen_lowpart (smode, src));
6195 return true;
6196 }
0349cc73 6197
6198 /* (set (ze (mem)) (const_int)). */
6199 else if (const_int_operand (src, VOIDmode))
6200 {
6201 int size = bitsize / BITS_PER_UNIT;
8c753480 6202 rtx src_mem = adjust_address (force_const_mem (word_mode, src),
6203 BLKmode,
6204 UNITS_PER_WORD - size);
0349cc73 6205
6206 dest = adjust_address (dest, BLKmode, 0);
5b2a69fa 6207 set_mem_size (dest, size);
0349cc73 6208 s390_expand_movmem (dest, src_mem, GEN_INT (size));
8c753480 6209 return true;
0349cc73 6210 }
ffead1ca 6211
0349cc73 6212 /* (set (ze (mem)) (reg)). */
6213 else if (register_operand (src, word_mode))
6214 {
8c753480 6215 if (bitsize <= 32)
0349cc73 6216 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest, op1,
6217 const0_rtx), src);
6218 else
6219 {
6220 /* Emit st,stcmh sequence. */
8c753480 6221 int stcmh_width = bitsize - 32;
0349cc73 6222 int size = stcmh_width / BITS_PER_UNIT;
6223
ffead1ca 6224 emit_move_insn (adjust_address (dest, SImode, size),
0349cc73 6225 gen_lowpart (SImode, src));
5b2a69fa 6226 set_mem_size (dest, size);
8c753480 6227 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest,
6228 GEN_INT (stcmh_width),
6229 const0_rtx),
6230 gen_rtx_LSHIFTRT (word_mode, src, GEN_INT (32)));
0349cc73 6231 }
8c753480 6232 return true;
0349cc73 6233 }
8c753480 6234 }
0349cc73 6235
8c753480 6236 /* Generate INSERT CHARACTERS UNDER MASK (IC, ICM et al). */
6237 if ((bitpos % BITS_PER_UNIT) == 0
6238 && (bitsize % BITS_PER_UNIT) == 0
6239 && (bitpos & 32) == ((bitpos + bitsize - 1) & 32)
6240 && MEM_P (src)
6241 && (mode == DImode || mode == SImode)
6242 && register_operand (dest, mode))
6243 {
6244 /* Emit a strict_low_part pattern if possible. */
6245 if (smode_bsize == bitsize && bitpos == mode_bsize - smode_bsize)
6246 {
6247 op = gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (smode, dest));
d1f9b275 6248 op = gen_rtx_SET (op, gen_lowpart (smode, src));
8c753480 6249 clobber = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
6250 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clobber)));
6251 return true;
6252 }
6253
6254 /* ??? There are more powerful versions of ICM that are not
6255 completely represented in the md file. */
0349cc73 6256 }
6257
8c753480 6258 /* For z10, generate ROTATE THEN INSERT SELECTED BITS (RISBG et al). */
6259 if (TARGET_Z10 && (mode == DImode || mode == SImode))
0349cc73 6260 {
3754d046 6261 machine_mode mode_s = GET_MODE (src);
0349cc73 6262
678c417b 6263 if (CONSTANT_P (src))
0349cc73 6264 {
02a8efd2 6265 /* For constant zero values the representation with AND
6266 appears to be folded in more situations than the (set
6267 (zero_extract) ...).
6268 We only do this when the start and end of the bitfield
6269 remain in the same SImode chunk. That way nihf or nilf
6270 can be used.
6271 The AND patterns might still generate a risbg for this. */
6272 if (src == const0_rtx && bitpos / 32 == (bitpos + bitsize - 1) / 32)
6273 return false;
6274 else
6275 src = force_reg (mode, src);
8c753480 6276 }
6277 else if (mode_s != mode)
6278 {
6279 gcc_assert (GET_MODE_BITSIZE (mode_s) >= bitsize);
6280 src = force_reg (mode_s, src);
6281 src = gen_lowpart (mode, src);
6282 }
0349cc73 6283
99274008 6284 op = gen_rtx_ZERO_EXTRACT (mode, dest, op1, op2),
d1f9b275 6285 op = gen_rtx_SET (op, src);
81769881 6286
6287 if (!TARGET_ZEC12)
6288 {
6289 clobber = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
6290 op = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clobber));
6291 }
6292 emit_insn (op);
0349cc73 6293
0349cc73 6294 return true;
6295 }
6296
6297 return false;
6298}
3b699fc7 6299
7cc66daf 6300/* A subroutine of s390_expand_cs_hqi and s390_expand_atomic which returns a
6301 register that holds VAL of mode MODE shifted by COUNT bits. */
182f815e 6302
6303static inline rtx
3754d046 6304s390_expand_mask_and_shift (rtx val, machine_mode mode, rtx count)
182f815e 6305{
6306 val = expand_simple_binop (SImode, AND, val, GEN_INT (GET_MODE_MASK (mode)),
6307 NULL_RTX, 1, OPTAB_DIRECT);
ffead1ca 6308 return expand_simple_binop (SImode, ASHIFT, val, count,
182f815e 6309 NULL_RTX, 1, OPTAB_DIRECT);
6310}
6311
76a4c804 6312/* Generate a vector comparison COND of CMP_OP1 and CMP_OP2 and store
6313 the result in TARGET. */
6314
6315void
6316s390_expand_vec_compare (rtx target, enum rtx_code cond,
6317 rtx cmp_op1, rtx cmp_op2)
6318{
6319 machine_mode mode = GET_MODE (target);
6320 bool neg_p = false, swap_p = false;
6321 rtx tmp;
6322
80912819 6323 if (GET_MODE_CLASS (GET_MODE (cmp_op1)) == MODE_VECTOR_FLOAT)
76a4c804 6324 {
6325 switch (cond)
6326 {
6327 /* NE a != b -> !(a == b) */
6328 case NE: cond = EQ; neg_p = true; break;
6329 /* UNGT a u> b -> !(b >= a) */
6330 case UNGT: cond = GE; neg_p = true; swap_p = true; break;
6331 /* UNGE a u>= b -> !(b > a) */
6332 case UNGE: cond = GT; neg_p = true; swap_p = true; break;
6333 /* LE: a <= b -> b >= a */
6334 case LE: cond = GE; swap_p = true; break;
6335 /* UNLE: a u<= b -> !(a > b) */
6336 case UNLE: cond = GT; neg_p = true; break;
6337 /* LT: a < b -> b > a */
6338 case LT: cond = GT; swap_p = true; break;
6339 /* UNLT: a u< b -> !(a >= b) */
6340 case UNLT: cond = GE; neg_p = true; break;
6341 case UNEQ:
6342 emit_insn (gen_vec_cmpuneqv2df (target, cmp_op1, cmp_op2));
6343 return;
6344 case LTGT:
6345 emit_insn (gen_vec_cmpltgtv2df (target, cmp_op1, cmp_op2));
6346 return;
6347 case ORDERED:
6348 emit_insn (gen_vec_orderedv2df (target, cmp_op1, cmp_op2));
6349 return;
6350 case UNORDERED:
6351 emit_insn (gen_vec_unorderedv2df (target, cmp_op1, cmp_op2));
6352 return;
6353 default: break;
6354 }
6355 }
6356 else
6357 {
6358 switch (cond)
6359 {
6360 /* NE: a != b -> !(a == b) */
6361 case NE: cond = EQ; neg_p = true; break;
6362 /* GE: a >= b -> !(b > a) */
6363 case GE: cond = GT; neg_p = true; swap_p = true; break;
6364 /* GEU: a >= b -> !(b > a) */
6365 case GEU: cond = GTU; neg_p = true; swap_p = true; break;
6366 /* LE: a <= b -> !(a > b) */
6367 case LE: cond = GT; neg_p = true; break;
6368 /* LEU: a <= b -> !(a > b) */
6369 case LEU: cond = GTU; neg_p = true; break;
6370 /* LT: a < b -> b > a */
6371 case LT: cond = GT; swap_p = true; break;
6372 /* LTU: a < b -> b > a */
6373 case LTU: cond = GTU; swap_p = true; break;
6374 default: break;
6375 }
6376 }
6377
6378 if (swap_p)
6379 {
6380 tmp = cmp_op1; cmp_op1 = cmp_op2; cmp_op2 = tmp;
6381 }
6382
6383 emit_insn (gen_rtx_SET (target, gen_rtx_fmt_ee (cond,
6384 mode,
6385 cmp_op1, cmp_op2)));
6386 if (neg_p)
6387 emit_insn (gen_rtx_SET (target, gen_rtx_NOT (mode, target)));
6388}
6389
07f32359 6390/* Expand the comparison CODE of CMP1 and CMP2 and copy 1 or 0 into
6391 TARGET if either all (ALL_P is true) or any (ALL_P is false) of the
abc57c35 6392 elements in CMP1 and CMP2 fulfill the comparison.
6393 This function is only used to emit patterns for the vx builtins and
6394 therefore only handles comparison codes required by the
6395 builtins. */
07f32359 6396void
6397s390_expand_vec_compare_cc (rtx target, enum rtx_code code,
6398 rtx cmp1, rtx cmp2, bool all_p)
6399{
abc57c35 6400 machine_mode cc_producer_mode, cc_consumer_mode, scratch_mode;
07f32359 6401 rtx tmp_reg = gen_reg_rtx (SImode);
6402 bool swap_p = false;
6403
6404 if (GET_MODE_CLASS (GET_MODE (cmp1)) == MODE_VECTOR_INT)
6405 {
6406 switch (code)
6407 {
abc57c35 6408 case EQ:
6409 case NE:
6410 cc_producer_mode = CCVEQmode;
6411 break;
6412 case GE:
6413 case LT:
6414 code = swap_condition (code);
6415 swap_p = true;
6416 /* fallthrough */
6417 case GT:
6418 case LE:
6419 cc_producer_mode = CCVIHmode;
6420 break;
6421 case GEU:
6422 case LTU:
6423 code = swap_condition (code);
6424 swap_p = true;
6425 /* fallthrough */
6426 case GTU:
6427 case LEU:
6428 cc_producer_mode = CCVIHUmode;
6429 break;
6430 default:
6431 gcc_unreachable ();
07f32359 6432 }
abc57c35 6433
07f32359 6434 scratch_mode = GET_MODE (cmp1);
abc57c35 6435 /* These codes represent inverted CC interpretations. Inverting
6436 an ALL CC mode results in an ANY CC mode and the other way
6437 around. Invert the all_p flag here to compensate for
6438 that. */
6439 if (code == NE || code == LE || code == LEU)
6440 all_p = !all_p;
6441
6442 cc_consumer_mode = all_p ? CCVIALLmode : CCVIANYmode;
07f32359 6443 }
abc57c35 6444 else if (GET_MODE_CLASS (GET_MODE (cmp1)) == MODE_VECTOR_FLOAT)
07f32359 6445 {
abc57c35 6446 bool inv_p = false;
6447
07f32359 6448 switch (code)
6449 {
abc57c35 6450 case EQ: cc_producer_mode = CCVEQmode; break;
6451 case NE: cc_producer_mode = CCVEQmode; inv_p = true; break;
6452 case GT: cc_producer_mode = CCVFHmode; break;
6453 case GE: cc_producer_mode = CCVFHEmode; break;
6454 case UNLE: cc_producer_mode = CCVFHmode; inv_p = true; break;
6455 case UNLT: cc_producer_mode = CCVFHEmode; inv_p = true; break;
6456 case LT: cc_producer_mode = CCVFHmode; code = GT; swap_p = true; break;
6457 case LE: cc_producer_mode = CCVFHEmode; code = GE; swap_p = true; break;
07f32359 6458 default: gcc_unreachable ();
6459 }
abc57c35 6460 scratch_mode = mode_for_vector (
6461 int_mode_for_mode (GET_MODE_INNER (GET_MODE (cmp1))),
6462 GET_MODE_NUNITS (GET_MODE (cmp1)));
6463 gcc_assert (scratch_mode != BLKmode);
6464
6465 if (inv_p)
6466 all_p = !all_p;
6467
6468 cc_consumer_mode = all_p ? CCVFALLmode : CCVFANYmode;
07f32359 6469 }
6470 else
6471 gcc_unreachable ();
6472
07f32359 6473 if (swap_p)
6474 {
6475 rtx tmp = cmp2;
6476 cmp2 = cmp1;
6477 cmp1 = tmp;
6478 }
6479
6480 emit_insn (gen_rtx_PARALLEL (VOIDmode,
6481 gen_rtvec (2, gen_rtx_SET (
abc57c35 6482 gen_rtx_REG (cc_producer_mode, CC_REGNUM),
6483 gen_rtx_COMPARE (cc_producer_mode, cmp1, cmp2)),
07f32359 6484 gen_rtx_CLOBBER (VOIDmode,
6485 gen_rtx_SCRATCH (scratch_mode)))));
6486 emit_move_insn (target, const0_rtx);
6487 emit_move_insn (tmp_reg, const1_rtx);
6488
6489 emit_move_insn (target,
6490 gen_rtx_IF_THEN_ELSE (SImode,
abc57c35 6491 gen_rtx_fmt_ee (code, VOIDmode,
6492 gen_rtx_REG (cc_consumer_mode, CC_REGNUM),
07f32359 6493 const0_rtx),
abc57c35 6494 tmp_reg, target));
07f32359 6495}
6496
e17ed6ec 6497/* Invert the comparison CODE applied to a CC mode. This is only safe
6498 if we know whether there result was created by a floating point
6499 compare or not. For the CCV modes this is encoded as part of the
6500 mode. */
6501enum rtx_code
6502s390_reverse_condition (machine_mode mode, enum rtx_code code)
6503{
6504 /* Reversal of FP compares takes care -- an ordered compare
6505 becomes an unordered compare and vice versa. */
6506 if (mode == CCVFALLmode || mode == CCVFANYmode)
6507 return reverse_condition_maybe_unordered (code);
6508 else if (mode == CCVIALLmode || mode == CCVIANYmode)
6509 return reverse_condition (code);
6510 else
6511 gcc_unreachable ();
6512}
6513
76a4c804 6514/* Generate a vector comparison expression loading either elements of
6515 THEN or ELS into TARGET depending on the comparison COND of CMP_OP1
6516 and CMP_OP2. */
6517
6518void
6519s390_expand_vcond (rtx target, rtx then, rtx els,
6520 enum rtx_code cond, rtx cmp_op1, rtx cmp_op2)
6521{
6522 rtx tmp;
6523 machine_mode result_mode;
6524 rtx result_target;
6525
651e0407 6526 machine_mode target_mode = GET_MODE (target);
6527 machine_mode cmp_mode = GET_MODE (cmp_op1);
6528 rtx op = (cond == LT) ? els : then;
6529
6530 /* Try to optimize x < 0 ? -1 : 0 into (signed) x >> 31
6531 and x < 0 ? 1 : 0 into (unsigned) x >> 31. Likewise
6532 for short and byte (x >> 15 and x >> 7 respectively). */
6533 if ((cond == LT || cond == GE)
6534 && target_mode == cmp_mode
6535 && cmp_op2 == CONST0_RTX (cmp_mode)
6536 && op == CONST0_RTX (target_mode)
6537 && s390_vector_mode_supported_p (target_mode)
6538 && GET_MODE_CLASS (target_mode) == MODE_VECTOR_INT)
6539 {
6540 rtx negop = (cond == LT) ? then : els;
6541
6542 int shift = GET_MODE_BITSIZE (GET_MODE_INNER (target_mode)) - 1;
6543
6544 /* if x < 0 ? 1 : 0 or if x >= 0 ? 0 : 1 */
6545 if (negop == CONST1_RTX (target_mode))
6546 {
6547 rtx res = expand_simple_binop (cmp_mode, LSHIFTRT, cmp_op1,
6548 GEN_INT (shift), target,
6549 1, OPTAB_DIRECT);
6550 if (res != target)
6551 emit_move_insn (target, res);
6552 return;
6553 }
6554
6555 /* if x < 0 ? -1 : 0 or if x >= 0 ? 0 : -1 */
a991c8aa 6556 else if (all_ones_operand (negop, target_mode))
651e0407 6557 {
6558 rtx res = expand_simple_binop (cmp_mode, ASHIFTRT, cmp_op1,
6559 GEN_INT (shift), target,
6560 0, OPTAB_DIRECT);
6561 if (res != target)
6562 emit_move_insn (target, res);
6563 return;
6564 }
6565 }
6566
76a4c804 6567 /* We always use an integral type vector to hold the comparison
6568 result. */
80912819 6569 result_mode = mode_for_vector (int_mode_for_mode (GET_MODE_INNER (cmp_mode)),
6570 GET_MODE_NUNITS (cmp_mode));
76a4c804 6571 result_target = gen_reg_rtx (result_mode);
6572
651e0407 6573 /* We allow vector immediates as comparison operands that
6574 can be handled by the optimization above but not by the
6575 following code. Hence, force them into registers here. */
76a4c804 6576 if (!REG_P (cmp_op1))
b088ff4b 6577 cmp_op1 = force_reg (GET_MODE (cmp_op1), cmp_op1);
76a4c804 6578
6579 if (!REG_P (cmp_op2))
b088ff4b 6580 cmp_op2 = force_reg (GET_MODE (cmp_op2), cmp_op2);
76a4c804 6581
6582 s390_expand_vec_compare (result_target, cond,
6583 cmp_op1, cmp_op2);
6584
6585 /* If the results are supposed to be either -1 or 0 we are done
6586 since this is what our compare instructions generate anyway. */
a991c8aa 6587 if (all_ones_operand (then, GET_MODE (then))
76a4c804 6588 && const0_operand (els, GET_MODE (els)))
6589 {
651e0407 6590 emit_move_insn (target, gen_rtx_SUBREG (target_mode,
76a4c804 6591 result_target, 0));
6592 return;
6593 }
6594
6595 /* Otherwise we will do a vsel afterwards. */
6596 /* This gets triggered e.g.
6597 with gcc.c-torture/compile/pr53410-1.c */
6598 if (!REG_P (then))
651e0407 6599 then = force_reg (target_mode, then);
76a4c804 6600
6601 if (!REG_P (els))
651e0407 6602 els = force_reg (target_mode, els);
76a4c804 6603
6604 tmp = gen_rtx_fmt_ee (EQ, VOIDmode,
6605 result_target,
6606 CONST0_RTX (result_mode));
6607
6608 /* We compared the result against zero above so we have to swap then
6609 and els here. */
651e0407 6610 tmp = gen_rtx_IF_THEN_ELSE (target_mode, tmp, els, then);
76a4c804 6611
651e0407 6612 gcc_assert (target_mode == GET_MODE (then));
76a4c804 6613 emit_insn (gen_rtx_SET (target, tmp));
6614}
6615
6616/* Emit the RTX necessary to initialize the vector TARGET with values
6617 in VALS. */
6618void
6619s390_expand_vec_init (rtx target, rtx vals)
6620{
6621 machine_mode mode = GET_MODE (target);
6622 machine_mode inner_mode = GET_MODE_INNER (mode);
6623 int n_elts = GET_MODE_NUNITS (mode);
6624 bool all_same = true, all_regs = true, all_const_int = true;
6625 rtx x;
6626 int i;
6627
6628 for (i = 0; i < n_elts; ++i)
6629 {
6630 x = XVECEXP (vals, 0, i);
6631
6632 if (!CONST_INT_P (x))
6633 all_const_int = false;
6634
6635 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
6636 all_same = false;
6637
6638 if (!REG_P (x))
6639 all_regs = false;
6640 }
6641
6642 /* Use vector gen mask or vector gen byte mask if possible. */
6643 if (all_same && all_const_int
6644 && (XVECEXP (vals, 0, 0) == const0_rtx
6645 || s390_contiguous_bitmask_vector_p (XVECEXP (vals, 0, 0),
6646 NULL, NULL)
6647 || s390_bytemask_vector_p (XVECEXP (vals, 0, 0), NULL)))
6648 {
6649 emit_insn (gen_rtx_SET (target,
6650 gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0))));
6651 return;
6652 }
6653
6654 if (all_same)
6655 {
6656 emit_insn (gen_rtx_SET (target,
6657 gen_rtx_VEC_DUPLICATE (mode,
6658 XVECEXP (vals, 0, 0))));
6659 return;
6660 }
6661
f413810a 6662 if (all_regs
6663 && REG_P (target)
6664 && n_elts == 2
6665 && GET_MODE_SIZE (inner_mode) == 8)
76a4c804 6666 {
6667 /* Use vector load pair. */
6668 emit_insn (gen_rtx_SET (target,
6669 gen_rtx_VEC_CONCAT (mode,
6670 XVECEXP (vals, 0, 0),
6671 XVECEXP (vals, 0, 1))));
6672 return;
6673 }
bd97b7d0 6674
6675 /* Use vector load logical element and zero. */
6676 if (TARGET_VXE && (mode == V4SImode || mode == V4SFmode))
6677 {
6678 bool found = true;
6679
6680 x = XVECEXP (vals, 0, 0);
6681 if (memory_operand (x, inner_mode))
6682 {
6683 for (i = 1; i < n_elts; ++i)
6684 found = found && XVECEXP (vals, 0, i) == const0_rtx;
6685
6686 if (found)
6687 {
6688 machine_mode half_mode = (inner_mode == SFmode
6689 ? V2SFmode : V2SImode);
6690 emit_insn (gen_rtx_SET (target,
6691 gen_rtx_VEC_CONCAT (mode,
6692 gen_rtx_VEC_CONCAT (half_mode,
6693 x,
6694 const0_rtx),
6695 gen_rtx_VEC_CONCAT (half_mode,
6696 const0_rtx,
6697 const0_rtx))));
6698 return;
6699 }
6700 }
6701 }
76a4c804 6702
6703 /* We are about to set the vector elements one by one. Zero out the
6704 full register first in order to help the data flow framework to
6705 detect it as full VR set. */
6706 emit_insn (gen_rtx_SET (target, CONST0_RTX (mode)));
6707
6708 /* Unfortunately the vec_init expander is not allowed to fail. So
6709 we have to implement the fallback ourselves. */
6710 for (i = 0; i < n_elts; i++)
4ba2579e 6711 {
6712 rtx elem = XVECEXP (vals, 0, i);
6713 if (!general_operand (elem, GET_MODE (elem)))
6714 elem = force_reg (inner_mode, elem);
6715
6716 emit_insn (gen_rtx_SET (target,
6717 gen_rtx_UNSPEC (mode,
6718 gen_rtvec (3, elem,
6719 GEN_INT (i), target),
6720 UNSPEC_VEC_SET)));
6721 }
76a4c804 6722}
6723
182f815e 6724/* Structure to hold the initial parameters for a compare_and_swap operation
ffead1ca 6725 in HImode and QImode. */
182f815e 6726
6727struct alignment_context
6728{
ffead1ca 6729 rtx memsi; /* SI aligned memory location. */
182f815e 6730 rtx shift; /* Bit offset with regard to lsb. */
6731 rtx modemask; /* Mask of the HQImode shifted by SHIFT bits. */
6732 rtx modemaski; /* ~modemask */
191ec5a2 6733 bool aligned; /* True if memory is aligned, false else. */
182f815e 6734};
6735
7cc66daf 6736/* A subroutine of s390_expand_cs_hqi and s390_expand_atomic to initialize
6737 structure AC for transparent simplifying, if the memory alignment is known
6738 to be at least 32bit. MEM is the memory location for the actual operation
6739 and MODE its mode. */
182f815e 6740
6741static void
6742init_alignment_context (struct alignment_context *ac, rtx mem,
3754d046 6743 machine_mode mode)
182f815e 6744{
6745 ac->shift = GEN_INT (GET_MODE_SIZE (SImode) - GET_MODE_SIZE (mode));
6746 ac->aligned = (MEM_ALIGN (mem) >= GET_MODE_BITSIZE (SImode));
6747
6748 if (ac->aligned)
6749 ac->memsi = adjust_address (mem, SImode, 0); /* Memory is aligned. */
6750 else
6751 {
6752 /* Alignment is unknown. */
6753 rtx byteoffset, addr, align;
6754
6755 /* Force the address into a register. */
6756 addr = force_reg (Pmode, XEXP (mem, 0));
6757
6758 /* Align it to SImode. */
6759 align = expand_simple_binop (Pmode, AND, addr,
6760 GEN_INT (-GET_MODE_SIZE (SImode)),
6761 NULL_RTX, 1, OPTAB_DIRECT);
6762 /* Generate MEM. */
6763 ac->memsi = gen_rtx_MEM (SImode, align);
6764 MEM_VOLATILE_P (ac->memsi) = MEM_VOLATILE_P (mem);
bd1da572 6765 set_mem_alias_set (ac->memsi, ALIAS_SET_MEMORY_BARRIER);
182f815e 6766 set_mem_align (ac->memsi, GET_MODE_BITSIZE (SImode));
6767
6768 /* Calculate shiftcount. */
6769 byteoffset = expand_simple_binop (Pmode, AND, addr,
6770 GEN_INT (GET_MODE_SIZE (SImode) - 1),
6771 NULL_RTX, 1, OPTAB_DIRECT);
6772 /* As we already have some offset, evaluate the remaining distance. */
6773 ac->shift = expand_simple_binop (SImode, MINUS, ac->shift, byteoffset,
6774 NULL_RTX, 1, OPTAB_DIRECT);
182f815e 6775 }
8c753480 6776
182f815e 6777 /* Shift is the byte count, but we need the bitcount. */
8c753480 6778 ac->shift = expand_simple_binop (SImode, ASHIFT, ac->shift, GEN_INT (3),
6779 NULL_RTX, 1, OPTAB_DIRECT);
6780
182f815e 6781 /* Calculate masks. */
ffead1ca 6782 ac->modemask = expand_simple_binop (SImode, ASHIFT,
8c753480 6783 GEN_INT (GET_MODE_MASK (mode)),
6784 ac->shift, NULL_RTX, 1, OPTAB_DIRECT);
6785 ac->modemaski = expand_simple_unop (SImode, NOT, ac->modemask,
6786 NULL_RTX, 1);
6787}
6788
6789/* A subroutine of s390_expand_cs_hqi. Insert INS into VAL. If possible,
6790 use a single insv insn into SEQ2. Otherwise, put prep insns in SEQ1 and
6791 perform the merge in SEQ2. */
6792
6793static rtx
6794s390_two_part_insv (struct alignment_context *ac, rtx *seq1, rtx *seq2,
3754d046 6795 machine_mode mode, rtx val, rtx ins)
8c753480 6796{
6797 rtx tmp;
6798
6799 if (ac->aligned)
6800 {
6801 start_sequence ();
6802 tmp = copy_to_mode_reg (SImode, val);
6803 if (s390_expand_insv (tmp, GEN_INT (GET_MODE_BITSIZE (mode)),
6804 const0_rtx, ins))
6805 {
6806 *seq1 = NULL;
6807 *seq2 = get_insns ();
6808 end_sequence ();
6809 return tmp;
6810 }
6811 end_sequence ();
6812 }
6813
6814 /* Failed to use insv. Generate a two part shift and mask. */
6815 start_sequence ();
6816 tmp = s390_expand_mask_and_shift (ins, mode, ac->shift);
6817 *seq1 = get_insns ();
6818 end_sequence ();
6819
6820 start_sequence ();
6821 tmp = expand_simple_binop (SImode, IOR, tmp, val, NULL_RTX, 1, OPTAB_DIRECT);
6822 *seq2 = get_insns ();
6823 end_sequence ();
6824
6825 return tmp;
182f815e 6826}
6827
6828/* Expand an atomic compare and swap operation for HImode and QImode. MEM is
8c753480 6829 the memory location, CMP the old value to compare MEM with and NEW_RTX the
6830 value to set if CMP == MEM. */
182f815e 6831
d90d26d8 6832static void
3754d046 6833s390_expand_cs_hqi (machine_mode mode, rtx btarget, rtx vtarget, rtx mem,
8c753480 6834 rtx cmp, rtx new_rtx, bool is_weak)
182f815e 6835{
6836 struct alignment_context ac;
77e58889 6837 rtx cmpv, newv, val, cc, seq0, seq1, seq2, seq3;
182f815e 6838 rtx res = gen_reg_rtx (SImode);
79f6a8ed 6839 rtx_code_label *csloop = NULL, *csend = NULL;
182f815e 6840
182f815e 6841 gcc_assert (MEM_P (mem));
6842
6843 init_alignment_context (&ac, mem, mode);
6844
182f815e 6845 /* Load full word. Subsequent loads are performed by CS. */
6846 val = expand_simple_binop (SImode, AND, ac.memsi, ac.modemaski,
6847 NULL_RTX, 1, OPTAB_DIRECT);
6848
8c753480 6849 /* Prepare insertions of cmp and new_rtx into the loaded value. When
6850 possible, we try to use insv to make this happen efficiently. If
6851 that fails we'll generate code both inside and outside the loop. */
6852 cmpv = s390_two_part_insv (&ac, &seq0, &seq2, mode, val, cmp);
6853 newv = s390_two_part_insv (&ac, &seq1, &seq3, mode, val, new_rtx);
6854
6855 if (seq0)
6856 emit_insn (seq0);
6857 if (seq1)
6858 emit_insn (seq1);
6859
182f815e 6860 /* Start CS loop. */
8c753480 6861 if (!is_weak)
6862 {
6863 /* Begin assuming success. */
6864 emit_move_insn (btarget, const1_rtx);
6865
6866 csloop = gen_label_rtx ();
6867 csend = gen_label_rtx ();
6868 emit_label (csloop);
6869 }
6870
ffead1ca 6871 /* val = "<mem>00..0<mem>"
182f815e 6872 * cmp = "00..0<cmp>00..0"
ffead1ca 6873 * new = "00..0<new>00..0"
182f815e 6874 */
6875
8c753480 6876 emit_insn (seq2);
6877 emit_insn (seq3);
6878
d90d26d8 6879 cc = s390_emit_compare_and_swap (EQ, res, ac.memsi, cmpv, newv, CCZ1mode);
8c753480 6880 if (is_weak)
6881 emit_insn (gen_cstorecc4 (btarget, cc, XEXP (cc, 0), XEXP (cc, 1)));
182f815e 6882 else
182f815e 6883 {
77e58889 6884 rtx tmp;
6885
8c753480 6886 /* Jump to end if we're done (likely?). */
6887 s390_emit_jump (csend, cc);
6888
77e58889 6889 /* Check for changes outside mode, and loop internal if so.
6890 Arrange the moves so that the compare is adjacent to the
6891 branch so that we can generate CRJ. */
6892 tmp = copy_to_reg (val);
6893 force_expand_binop (SImode, and_optab, res, ac.modemaski, val,
6894 1, OPTAB_DIRECT);
6895 cc = s390_emit_compare (NE, val, tmp);
8c753480 6896 s390_emit_jump (csloop, cc);
6897
6898 /* Failed. */
6899 emit_move_insn (btarget, const0_rtx);
6900 emit_label (csend);
182f815e 6901 }
ffead1ca 6902
182f815e 6903 /* Return the correct part of the bitfield. */
8c753480 6904 convert_move (vtarget, expand_simple_binop (SImode, LSHIFTRT, res, ac.shift,
6905 NULL_RTX, 1, OPTAB_DIRECT), 1);
182f815e 6906}
6907
d90d26d8 6908/* Variant of s390_expand_cs for SI, DI and TI modes. */
6909static void
6910s390_expand_cs_tdsi (machine_mode mode, rtx btarget, rtx vtarget, rtx mem,
6911 rtx cmp, rtx new_rtx, bool is_weak)
6912{
6913 rtx output = vtarget;
6914 rtx_code_label *skip_cs_label = NULL;
6915 bool do_const_opt = false;
6916
6917 if (!register_operand (output, mode))
6918 output = gen_reg_rtx (mode);
6919
6920 /* If IS_WEAK is true and the INPUT value is a constant, compare the memory
6921 with the constant first and skip the compare_and_swap because its very
6922 expensive and likely to fail anyway.
6923 Note 1: This is done only for IS_WEAK. C11 allows optimizations that may
6924 cause spurious in that case.
6925 Note 2: It may be useful to do this also for non-constant INPUT.
6926 Note 3: Currently only targets with "load on condition" are supported
6927 (z196 and newer). */
6928
6929 if (TARGET_Z196
6930 && (mode == SImode || mode == DImode))
6931 do_const_opt = (is_weak && CONST_INT_P (cmp));
6932
6933 if (do_const_opt)
6934 {
d90d26d8 6935 rtx cc = gen_rtx_REG (CCZmode, CC_REGNUM);
6936
6937 skip_cs_label = gen_label_rtx ();
6938 emit_move_insn (btarget, const0_rtx);
6939 if (CONST_INT_P (cmp) && INTVAL (cmp) == 0)
6940 {
6941 rtvec lt = rtvec_alloc (2);
6942
6943 /* Load-and-test + conditional jump. */
6944 RTVEC_ELT (lt, 0)
6945 = gen_rtx_SET (cc, gen_rtx_COMPARE (CCZmode, mem, cmp));
6946 RTVEC_ELT (lt, 1) = gen_rtx_SET (output, mem);
6947 emit_insn (gen_rtx_PARALLEL (VOIDmode, lt));
6948 }
6949 else
6950 {
6951 emit_move_insn (output, mem);
6952 emit_insn (gen_rtx_SET (cc, gen_rtx_COMPARE (CCZmode, output, cmp)));
6953 }
6954 s390_emit_jump (skip_cs_label, gen_rtx_NE (VOIDmode, cc, const0_rtx));
61cb1816 6955 add_reg_br_prob_note (get_last_insn (),
6956 profile_probability::very_unlikely ());
d90d26d8 6957 /* If the jump is not taken, OUTPUT is the expected value. */
6958 cmp = output;
6959 /* Reload newval to a register manually, *after* the compare and jump
6960 above. Otherwise Reload might place it before the jump. */
6961 }
6962 else
6963 cmp = force_reg (mode, cmp);
6964 new_rtx = force_reg (mode, new_rtx);
6965 s390_emit_compare_and_swap (EQ, output, mem, cmp, new_rtx,
6966 (do_const_opt) ? CCZmode : CCZ1mode);
6967 if (skip_cs_label != NULL)
6968 emit_label (skip_cs_label);
6969
6970 /* We deliberately accept non-register operands in the predicate
6971 to ensure the write back to the output operand happens *before*
6972 the store-flags code below. This makes it easier for combine
6973 to merge the store-flags code with a potential test-and-branch
6974 pattern following (immediately!) afterwards. */
6975 if (output != vtarget)
6976 emit_move_insn (vtarget, output);
6977
6978 if (do_const_opt)
6979 {
6980 rtx cc, cond, ite;
6981
6982 /* Do not use gen_cstorecc4 here because it writes either 1 or 0, but
6983 btarget has already been initialized with 0 above. */
6984 cc = gen_rtx_REG (CCZmode, CC_REGNUM);
6985 cond = gen_rtx_EQ (VOIDmode, cc, const0_rtx);
6986 ite = gen_rtx_IF_THEN_ELSE (SImode, cond, const1_rtx, btarget);
6987 emit_insn (gen_rtx_SET (btarget, ite));
6988 }
6989 else
6990 {
6991 rtx cc, cond;
6992
6993 cc = gen_rtx_REG (CCZ1mode, CC_REGNUM);
6994 cond = gen_rtx_EQ (SImode, cc, const0_rtx);
6995 emit_insn (gen_cstorecc4 (btarget, cond, cc, const0_rtx));
6996 }
6997}
6998
6999/* Expand an atomic compare and swap operation. MEM is the memory location,
7000 CMP the old value to compare MEM with and NEW_RTX the value to set if
7001 CMP == MEM. */
7002
7003void
7004s390_expand_cs (machine_mode mode, rtx btarget, rtx vtarget, rtx mem,
7005 rtx cmp, rtx new_rtx, bool is_weak)
7006{
7007 switch (mode)
7008 {
7009 case TImode:
7010 case DImode:
7011 case SImode:
7012 s390_expand_cs_tdsi (mode, btarget, vtarget, mem, cmp, new_rtx, is_weak);
7013 break;
7014 case HImode:
7015 case QImode:
7016 s390_expand_cs_hqi (mode, btarget, vtarget, mem, cmp, new_rtx, is_weak);
7017 break;
7018 default:
7019 gcc_unreachable ();
7020 }
7021}
7022
7023/* Expand an atomic_exchange operation simulated with a compare-and-swap loop.
7024 The memory location MEM is set to INPUT. OUTPUT is set to the previous value
7025 of MEM. */
7026
7027void
7028s390_expand_atomic_exchange_tdsi (rtx output, rtx mem, rtx input)
7029{
7030 machine_mode mode = GET_MODE (mem);
7031 rtx_code_label *csloop;
7032
7033 if (TARGET_Z196
7034 && (mode == DImode || mode == SImode)
7035 && CONST_INT_P (input) && INTVAL (input) == 0)
7036 {
7037 emit_move_insn (output, const0_rtx);
7038 if (mode == DImode)
7039 emit_insn (gen_atomic_fetch_anddi (output, mem, const0_rtx, input));
7040 else
7041 emit_insn (gen_atomic_fetch_andsi (output, mem, const0_rtx, input));
7042 return;
7043 }
7044
7045 input = force_reg (mode, input);
7046 emit_move_insn (output, mem);
7047 csloop = gen_label_rtx ();
7048 emit_label (csloop);
7049 s390_emit_jump (csloop, s390_emit_compare_and_swap (NE, output, mem, output,
7050 input, CCZ1mode));
7051}
7052
7cc66daf 7053/* Expand an atomic operation CODE of mode MODE. MEM is the memory location
85694bac 7054 and VAL the value to play with. If AFTER is true then store the value
7cc66daf 7055 MEM holds after the operation, if AFTER is false then store the value MEM
7056 holds before the operation. If TARGET is zero then discard that value, else
7057 store it to TARGET. */
7058
7059void
3754d046 7060s390_expand_atomic (machine_mode mode, enum rtx_code code,
7cc66daf 7061 rtx target, rtx mem, rtx val, bool after)
7062{
7063 struct alignment_context ac;
7064 rtx cmp;
8deb3959 7065 rtx new_rtx = gen_reg_rtx (SImode);
7cc66daf 7066 rtx orig = gen_reg_rtx (SImode);
79f6a8ed 7067 rtx_code_label *csloop = gen_label_rtx ();
7cc66daf 7068
7069 gcc_assert (!target || register_operand (target, VOIDmode));
7070 gcc_assert (MEM_P (mem));
7071
7072 init_alignment_context (&ac, mem, mode);
7073
7074 /* Shift val to the correct bit positions.
7075 Preserve "icm", but prevent "ex icm". */
7076 if (!(ac.aligned && code == SET && MEM_P (val)))
7077 val = s390_expand_mask_and_shift (val, mode, ac.shift);
7078
7079 /* Further preparation insns. */
7080 if (code == PLUS || code == MINUS)
7081 emit_move_insn (orig, val);
7082 else if (code == MULT || code == AND) /* val = "11..1<val>11..1" */
7083 val = expand_simple_binop (SImode, XOR, val, ac.modemaski,
7084 NULL_RTX, 1, OPTAB_DIRECT);
7085
7086 /* Load full word. Subsequent loads are performed by CS. */
7087 cmp = force_reg (SImode, ac.memsi);
7088
7089 /* Start CS loop. */
7090 emit_label (csloop);
8deb3959 7091 emit_move_insn (new_rtx, cmp);
7cc66daf 7092
7093 /* Patch new with val at correct position. */
7094 switch (code)
7095 {
7096 case PLUS:
7097 case MINUS:
8deb3959 7098 val = expand_simple_binop (SImode, code, new_rtx, orig,
7cc66daf 7099 NULL_RTX, 1, OPTAB_DIRECT);
7100 val = expand_simple_binop (SImode, AND, val, ac.modemask,
7101 NULL_RTX, 1, OPTAB_DIRECT);
7102 /* FALLTHRU */
ffead1ca 7103 case SET:
7cc66daf 7104 if (ac.aligned && MEM_P (val))
b634c730 7105 store_bit_field (new_rtx, GET_MODE_BITSIZE (mode), 0,
292237f3 7106 0, 0, SImode, val, false);
7cc66daf 7107 else
7108 {
8deb3959 7109 new_rtx = expand_simple_binop (SImode, AND, new_rtx, ac.modemaski,
7cc66daf 7110 NULL_RTX, 1, OPTAB_DIRECT);
8deb3959 7111 new_rtx = expand_simple_binop (SImode, IOR, new_rtx, val,
7cc66daf 7112 NULL_RTX, 1, OPTAB_DIRECT);
7113 }
7114 break;
7115 case AND:
7116 case IOR:
7117 case XOR:
8deb3959 7118 new_rtx = expand_simple_binop (SImode, code, new_rtx, val,
7cc66daf 7119 NULL_RTX, 1, OPTAB_DIRECT);
7120 break;
7121 case MULT: /* NAND */
8deb3959 7122 new_rtx = expand_simple_binop (SImode, AND, new_rtx, val,
7cc66daf 7123 NULL_RTX, 1, OPTAB_DIRECT);
636c17b8 7124 new_rtx = expand_simple_binop (SImode, XOR, new_rtx, ac.modemask,
7125 NULL_RTX, 1, OPTAB_DIRECT);
7cc66daf 7126 break;
7127 default:
7128 gcc_unreachable ();
7129 }
7cc66daf 7130
db1f11e3 7131 s390_emit_jump (csloop, s390_emit_compare_and_swap (NE, cmp,
d90d26d8 7132 ac.memsi, cmp, new_rtx,
7133 CCZ1mode));
7cc66daf 7134
7135 /* Return the correct part of the bitfield. */
7136 if (target)
7137 convert_move (target, expand_simple_binop (SImode, LSHIFTRT,
8deb3959 7138 after ? new_rtx : cmp, ac.shift,
7cc66daf 7139 NULL_RTX, 1, OPTAB_DIRECT), 1);
7140}
7141
40af64cc 7142/* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
03c118d5 7143 We need to emit DTP-relative relocations. */
7144
40af64cc 7145static void s390_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
7146
7147static void
b40da9a7 7148s390_output_dwarf_dtprel (FILE *file, int size, rtx x)
03c118d5 7149{
7150 switch (size)
7151 {
7152 case 4:
7153 fputs ("\t.long\t", file);
7154 break;
7155 case 8:
7156 fputs ("\t.quad\t", file);
7157 break;
7158 default:
32eda510 7159 gcc_unreachable ();
03c118d5 7160 }
7161 output_addr_const (file, x);
7162 fputs ("@DTPOFF", file);
7163}
7164
76a4c804 7165/* Return the proper mode for REGNO being represented in the dwarf
7166 unwind table. */
7167machine_mode
7168s390_dwarf_frame_reg_mode (int regno)
7169{
7170 machine_mode save_mode = default_dwarf_frame_reg_mode (regno);
7171
52de7525 7172 /* Make sure not to return DImode for any GPR with -m31 -mzarch. */
7173 if (GENERAL_REGNO_P (regno))
7174 save_mode = Pmode;
7175
76a4c804 7176 /* The rightmost 64 bits of vector registers are call-clobbered. */
7177 if (GET_MODE_SIZE (save_mode) > 8)
7178 save_mode = DImode;
7179
7180 return save_mode;
7181}
7182
4257b08a 7183#ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
eddcdde1 7184/* Implement TARGET_MANGLE_TYPE. */
4257b08a 7185
7186static const char *
a9f1838b 7187s390_mangle_type (const_tree type)
4257b08a 7188{
07f32359 7189 type = TYPE_MAIN_VARIANT (type);
7190
7191 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
7192 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
7193 return NULL;
7194
7195 if (type == s390_builtin_types[BT_BV16QI]) return "U6__boolc";
7196 if (type == s390_builtin_types[BT_BV8HI]) return "U6__bools";
7197 if (type == s390_builtin_types[BT_BV4SI]) return "U6__booli";
7198 if (type == s390_builtin_types[BT_BV2DI]) return "U6__booll";
7199
4257b08a 7200 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
7201 && TARGET_LONG_DOUBLE_128)
7202 return "g";
7203
7204 /* For all other types, use normal C++ mangling. */
7205 return NULL;
7206}
7207#endif
7208
e93986bb 7209/* In the name of slightly smaller debug output, and to cater to
06b27565 7210 general assembler lossage, recognize various UNSPEC sequences
e93986bb 7211 and turn them back into a direct symbol reference. */
7212
07576557 7213static rtx
b40da9a7 7214s390_delegitimize_address (rtx orig_x)
e93986bb 7215{
3b6b647c 7216 rtx x, y;
e93986bb 7217
3b6b647c 7218 orig_x = delegitimize_mem_from_attrs (orig_x);
7219 x = orig_x;
4796d433 7220
7221 /* Extract the symbol ref from:
7222 (plus:SI (reg:SI 12 %r12)
7223 (const:SI (unspec:SI [(symbol_ref/f:SI ("*.LC0"))]
2b2b857a 7224 UNSPEC_GOTOFF/PLTOFF)))
7225 and
7226 (plus:SI (reg:SI 12 %r12)
7227 (const:SI (plus:SI (unspec:SI [(symbol_ref:SI ("L"))]
7228 UNSPEC_GOTOFF/PLTOFF)
7229 (const_int 4 [0x4])))) */
4796d433 7230 if (GET_CODE (x) == PLUS
7231 && REG_P (XEXP (x, 0))
7232 && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM
7233 && GET_CODE (XEXP (x, 1)) == CONST)
7234 {
b6382e93 7235 HOST_WIDE_INT offset = 0;
7236
4796d433 7237 /* The const operand. */
7238 y = XEXP (XEXP (x, 1), 0);
2b2b857a 7239
7240 if (GET_CODE (y) == PLUS
7241 && GET_CODE (XEXP (y, 1)) == CONST_INT)
b6382e93 7242 {
7243 offset = INTVAL (XEXP (y, 1));
7244 y = XEXP (y, 0);
7245 }
2b2b857a 7246
4796d433 7247 if (GET_CODE (y) == UNSPEC
2b2b857a 7248 && (XINT (y, 1) == UNSPEC_GOTOFF
7249 || XINT (y, 1) == UNSPEC_PLTOFF))
29c05e22 7250 return plus_constant (Pmode, XVECEXP (y, 0, 0), offset);
4796d433 7251 }
7252
e93986bb 7253 if (GET_CODE (x) != MEM)
7254 return orig_x;
7255
7256 x = XEXP (x, 0);
7257 if (GET_CODE (x) == PLUS
7258 && GET_CODE (XEXP (x, 1)) == CONST
7259 && GET_CODE (XEXP (x, 0)) == REG
7260 && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM)
7261 {
7262 y = XEXP (XEXP (x, 1), 0);
7263 if (GET_CODE (y) == UNSPEC
12ef3745 7264 && XINT (y, 1) == UNSPEC_GOT)
54cb44a3 7265 y = XVECEXP (y, 0, 0);
7266 else
7267 return orig_x;
e93986bb 7268 }
54cb44a3 7269 else if (GET_CODE (x) == CONST)
e93986bb 7270 {
2b2b857a 7271 /* Extract the symbol ref from:
7272 (mem:QI (const:DI (unspec:DI [(symbol_ref:DI ("foo"))]
7273 UNSPEC_PLT/GOTENT))) */
7274
e93986bb 7275 y = XEXP (x, 0);
7276 if (GET_CODE (y) == UNSPEC
2b2b857a 7277 && (XINT (y, 1) == UNSPEC_GOTENT
7278 || XINT (y, 1) == UNSPEC_PLT))
54cb44a3 7279 y = XVECEXP (y, 0, 0);
7280 else
7281 return orig_x;
e93986bb 7282 }
54cb44a3 7283 else
7284 return orig_x;
e93986bb 7285
54cb44a3 7286 if (GET_MODE (orig_x) != Pmode)
7287 {
2b03de53 7288 if (GET_MODE (orig_x) == BLKmode)
7289 return orig_x;
54cb44a3 7290 y = lowpart_subreg (GET_MODE (orig_x), y, Pmode);
7291 if (y == NULL_RTX)
7292 return orig_x;
7293 }
7294 return y;
e93986bb 7295}
2eb8fe23 7296
805a133b 7297/* Output operand OP to stdio stream FILE.
7298 OP is an address (register + offset) which is not used to address data;
7299 instead the rightmost bits are interpreted as the value. */
63ebd742 7300
7301static void
2be7449b 7302print_addrstyle_operand (FILE *file, rtx op)
63ebd742 7303{
6d6be381 7304 HOST_WIDE_INT offset;
7305 rtx base;
9a09ba70 7306
6d6be381 7307 /* Extract base register and offset. */
2be7449b 7308 if (!s390_decompose_addrstyle_without_index (op, &base, &offset))
6d6be381 7309 gcc_unreachable ();
63ebd742 7310
7311 /* Sanity check. */
6d6be381 7312 if (base)
32eda510 7313 {
6d6be381 7314 gcc_assert (GET_CODE (base) == REG);
7315 gcc_assert (REGNO (base) < FIRST_PSEUDO_REGISTER);
7316 gcc_assert (REGNO_REG_CLASS (REGNO (base)) == ADDR_REGS);
32eda510 7317 }
63ebd742 7318
805a133b 7319 /* Offsets are constricted to twelve bits. */
7320 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset & ((1 << 12) - 1));
6d6be381 7321 if (base)
7322 fprintf (file, "(%s)", reg_names[REGNO (base)]);
63ebd742 7323}
7324
06877232 7325/* Assigns the number of NOP halfwords to be emitted before and after the
7326 function label to *HW_BEFORE and *HW_AFTER. Both pointers must not be NULL.
7327 If hotpatching is disabled for the function, the values are set to zero.
7328*/
77bc9912 7329
06877232 7330static void
11762b83 7331s390_function_num_hotpatch_hw (tree decl,
7332 int *hw_before,
7333 int *hw_after)
77bc9912 7334{
7335 tree attr;
7336
11762b83 7337 attr = lookup_attribute ("hotpatch", DECL_ATTRIBUTES (decl));
7338
7339 /* Handle the arguments of the hotpatch attribute. The values
7340 specified via attribute might override the cmdline argument
7341 values. */
7342 if (attr)
77bc9912 7343 {
11762b83 7344 tree args = TREE_VALUE (attr);
7345
7346 *hw_before = TREE_INT_CST_LOW (TREE_VALUE (args));
7347 *hw_after = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (args)));
77bc9912 7348 }
11762b83 7349 else
77bc9912 7350 {
11762b83 7351 /* Use the values specified by the cmdline arguments. */
7352 *hw_before = s390_hotpatch_hw_before_label;
7353 *hw_after = s390_hotpatch_hw_after_label;
77bc9912 7354 }
77bc9912 7355}
7356
7a0cee35 7357/* Write the current .machine and .machinemode specification to the assembler
7358 file. */
7359
14d7e7e6 7360#ifdef HAVE_AS_MACHINE_MACHINEMODE
7a0cee35 7361static void
7362s390_asm_output_machine_for_arch (FILE *asm_out_file)
7363{
7364 fprintf (asm_out_file, "\t.machinemode %s\n",
7365 (TARGET_ZARCH) ? "zarch" : "esa");
a168a775 7366 fprintf (asm_out_file, "\t.machine \"%s",
7367 processor_table[s390_arch].binutils_name);
7a0cee35 7368 if (S390_USE_ARCHITECTURE_MODIFIERS)
7369 {
7370 int cpu_flags;
7371
7372 cpu_flags = processor_flags_table[(int) s390_arch];
7373 if (TARGET_HTM && !(cpu_flags & PF_TX))
7374 fprintf (asm_out_file, "+htm");
7375 else if (!TARGET_HTM && (cpu_flags & PF_TX))
7376 fprintf (asm_out_file, "+nohtm");
7377 if (TARGET_VX && !(cpu_flags & PF_VX))
7378 fprintf (asm_out_file, "+vx");
7379 else if (!TARGET_VX && (cpu_flags & PF_VX))
7380 fprintf (asm_out_file, "+novx");
7381 }
7382 fprintf (asm_out_file, "\"\n");
7383}
7384
7385/* Write an extra function header before the very start of the function. */
7386
7387void
7388s390_asm_output_function_prefix (FILE *asm_out_file,
7389 const char *fnname ATTRIBUTE_UNUSED)
7390{
7391 if (DECL_FUNCTION_SPECIFIC_TARGET (current_function_decl) == NULL)
7392 return;
7393 /* Since only the function specific options are saved but not the indications
7394 which options are set, it's too much work here to figure out which options
7395 have actually changed. Thus, generate .machine and .machinemode whenever a
7396 function has the target attribute or pragma. */
7397 fprintf (asm_out_file, "\t.machinemode push\n");
7398 fprintf (asm_out_file, "\t.machine push\n");
7399 s390_asm_output_machine_for_arch (asm_out_file);
7400}
7401
7402/* Write an extra function footer after the very end of the function. */
7403
7404void
7405s390_asm_declare_function_size (FILE *asm_out_file,
0491d54f 7406 const char *fnname, tree decl)
7a0cee35 7407{
0491d54f 7408 if (!flag_inhibit_size_directive)
7409 ASM_OUTPUT_MEASURED_SIZE (asm_out_file, fnname);
7a0cee35 7410 if (DECL_FUNCTION_SPECIFIC_TARGET (decl) == NULL)
7411 return;
7412 fprintf (asm_out_file, "\t.machine pop\n");
7413 fprintf (asm_out_file, "\t.machinemode pop\n");
7414}
7415#endif
7416
77bc9912 7417/* Write the extra assembler code needed to declare a function properly. */
7418
7419void
7420s390_asm_output_function_label (FILE *asm_out_file, const char *fname,
7421 tree decl)
7422{
11762b83 7423 int hw_before, hw_after;
77bc9912 7424
06877232 7425 s390_function_num_hotpatch_hw (decl, &hw_before, &hw_after);
7426 if (hw_before > 0)
77bc9912 7427 {
f4252e72 7428 unsigned int function_alignment;
77bc9912 7429 int i;
7430
7431 /* Add a trampoline code area before the function label and initialize it
7432 with two-byte nop instructions. This area can be overwritten with code
7433 that jumps to a patched version of the function. */
2a4536cc 7434 asm_fprintf (asm_out_file, "\tnopr\t%%r0"
06877232 7435 "\t# pre-label NOPs for hotpatch (%d halfwords)\n",
7436 hw_before);
7437 for (i = 1; i < hw_before; i++)
2a4536cc 7438 fputs ("\tnopr\t%r0\n", asm_out_file);
06877232 7439
77bc9912 7440 /* Note: The function label must be aligned so that (a) the bytes of the
7441 following nop do not cross a cacheline boundary, and (b) a jump address
7442 (eight bytes for 64 bit targets, 4 bytes for 32 bit targets) can be
7443 stored directly before the label without crossing a cacheline
7444 boundary. All this is necessary to make sure the trampoline code can
06877232 7445 be changed atomically.
7446 This alignment is done automatically using the FOUNCTION_BOUNDARY, but
7447 if there are NOPs before the function label, the alignment is placed
7448 before them. So it is necessary to duplicate the alignment after the
7449 NOPs. */
f4252e72 7450 function_alignment = MAX (8, DECL_ALIGN (decl) / BITS_PER_UNIT);
7451 if (! DECL_USER_ALIGN (decl))
7452 function_alignment = MAX (function_alignment,
7453 (unsigned int) align_functions);
06877232 7454 fputs ("\t# alignment for hotpatch\n", asm_out_file);
f4252e72 7455 ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (function_alignment));
77bc9912 7456 }
7457
7a0cee35 7458 if (S390_USE_TARGET_ATTRIBUTE && TARGET_DEBUG_ARG)
7459 {
7460 asm_fprintf (asm_out_file, "\t# fn:%s ar%d\n", fname, s390_arch);
7461 asm_fprintf (asm_out_file, "\t# fn:%s tu%d\n", fname, s390_tune);
7462 asm_fprintf (asm_out_file, "\t# fn:%s sg%d\n", fname, s390_stack_guard);
7463 asm_fprintf (asm_out_file, "\t# fn:%s ss%d\n", fname, s390_stack_size);
7464 asm_fprintf (asm_out_file, "\t# fn:%s bc%d\n", fname, s390_branch_cost);
7465 asm_fprintf (asm_out_file, "\t# fn:%s wf%d\n", fname,
7466 s390_warn_framesize);
7467 asm_fprintf (asm_out_file, "\t# fn:%s ba%d\n", fname, TARGET_BACKCHAIN);
7468 asm_fprintf (asm_out_file, "\t# fn:%s hd%d\n", fname, TARGET_HARD_DFP);
7469 asm_fprintf (asm_out_file, "\t# fn:%s hf%d\n", fname, !TARGET_SOFT_FLOAT);
7470 asm_fprintf (asm_out_file, "\t# fn:%s ht%d\n", fname, TARGET_OPT_HTM);
7471 asm_fprintf (asm_out_file, "\t# fn:%s vx%d\n", fname, TARGET_OPT_VX);
7472 asm_fprintf (asm_out_file, "\t# fn:%s ps%d\n", fname,
7473 TARGET_PACKED_STACK);
7474 asm_fprintf (asm_out_file, "\t# fn:%s se%d\n", fname, TARGET_SMALL_EXEC);
7475 asm_fprintf (asm_out_file, "\t# fn:%s mv%d\n", fname, TARGET_MVCLE);
7476 asm_fprintf (asm_out_file, "\t# fn:%s zv%d\n", fname, TARGET_ZVECTOR);
7477 asm_fprintf (asm_out_file, "\t# fn:%s wd%d\n", fname,
7478 s390_warn_dynamicstack_p);
7479 }
77bc9912 7480 ASM_OUTPUT_LABEL (asm_out_file, fname);
06877232 7481 if (hw_after > 0)
7482 asm_fprintf (asm_out_file,
7483 "\t# post-label NOPs for hotpatch (%d halfwords)\n",
7484 hw_after);
77bc9912 7485}
7486
f588eb9f 7487/* Output machine-dependent UNSPECs occurring in address constant X
74d2529d 7488 in assembler syntax to stdio stream FILE. Returns true if the
7489 constant X could be recognized, false otherwise. */
4673c1a0 7490
1a561788 7491static bool
74d2529d 7492s390_output_addr_const_extra (FILE *file, rtx x)
4673c1a0 7493{
74d2529d 7494 if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 1)
7495 switch (XINT (x, 1))
7496 {
7497 case UNSPEC_GOTENT:
7498 output_addr_const (file, XVECEXP (x, 0, 0));
7499 fprintf (file, "@GOTENT");
7500 return true;
7501 case UNSPEC_GOT:
7502 output_addr_const (file, XVECEXP (x, 0, 0));
7503 fprintf (file, "@GOT");
7504 return true;
7505 case UNSPEC_GOTOFF:
7506 output_addr_const (file, XVECEXP (x, 0, 0));
7507 fprintf (file, "@GOTOFF");
7508 return true;
7509 case UNSPEC_PLT:
7510 output_addr_const (file, XVECEXP (x, 0, 0));
7511 fprintf (file, "@PLT");
7512 return true;
7513 case UNSPEC_PLTOFF:
7514 output_addr_const (file, XVECEXP (x, 0, 0));
7515 fprintf (file, "@PLTOFF");
7516 return true;
7517 case UNSPEC_TLSGD:
7518 output_addr_const (file, XVECEXP (x, 0, 0));
7519 fprintf (file, "@TLSGD");
7520 return true;
7521 case UNSPEC_TLSLDM:
7522 assemble_name (file, get_some_local_dynamic_name ());
7523 fprintf (file, "@TLSLDM");
7524 return true;
7525 case UNSPEC_DTPOFF:
7526 output_addr_const (file, XVECEXP (x, 0, 0));
7527 fprintf (file, "@DTPOFF");
7528 return true;
7529 case UNSPEC_NTPOFF:
7530 output_addr_const (file, XVECEXP (x, 0, 0));
7531 fprintf (file, "@NTPOFF");
7532 return true;
7533 case UNSPEC_GOTNTPOFF:
7534 output_addr_const (file, XVECEXP (x, 0, 0));
7535 fprintf (file, "@GOTNTPOFF");
7536 return true;
7537 case UNSPEC_INDNTPOFF:
7538 output_addr_const (file, XVECEXP (x, 0, 0));
7539 fprintf (file, "@INDNTPOFF");
7540 return true;
7541 }
4673c1a0 7542
1ed7a160 7543 if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 2)
7544 switch (XINT (x, 1))
7545 {
7546 case UNSPEC_POOL_OFFSET:
7547 x = gen_rtx_MINUS (GET_MODE (x), XVECEXP (x, 0, 0), XVECEXP (x, 0, 1));
7548 output_addr_const (file, x);
7549 return true;
7550 }
74d2529d 7551 return false;
4673c1a0 7552}
7553
f81e845f 7554/* Output address operand ADDR in assembler syntax to
56769981 7555 stdio stream FILE. */
4673c1a0 7556
7557void
b40da9a7 7558print_operand_address (FILE *file, rtx addr)
4673c1a0 7559{
7560 struct s390_address ad;
883b2519 7561 memset (&ad, 0, sizeof (s390_address));
4673c1a0 7562
2a672556 7563 if (s390_loadrelative_operand_p (addr, NULL, NULL))
e68d6a13 7564 {
53b9033c 7565 if (!TARGET_Z10)
7566 {
902602ef 7567 output_operand_lossage ("symbolic memory references are "
7568 "only supported on z10 or later");
53b9033c 7569 return;
7570 }
e68d6a13 7571 output_addr_const (file, addr);
7572 return;
7573 }
7574
8ba34dcd 7575 if (!s390_decompose_address (addr, &ad)
1e280623 7576 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
7577 || (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx))))
3284a242 7578 output_operand_lossage ("cannot decompose address");
f81e845f 7579
4673c1a0 7580 if (ad.disp)
74d2529d 7581 output_addr_const (file, ad.disp);
4673c1a0 7582 else
7583 fprintf (file, "0");
7584
7585 if (ad.base && ad.indx)
7586 fprintf (file, "(%s,%s)", reg_names[REGNO (ad.indx)],
7587 reg_names[REGNO (ad.base)]);
7588 else if (ad.base)
7589 fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
7590}
7591
f81e845f 7592/* Output operand X in assembler syntax to stdio stream FILE.
7593 CODE specified the format flag. The following format flags
56769981 7594 are recognized:
7595
7596 'C': print opcode suffix for branch condition.
7597 'D': print opcode suffix for inverse branch condition.
f1443d23 7598 'E': print opcode suffix for branch on index instruction.
cc87d0c5 7599 'G': print the size of the operand in bytes.
0d46035f 7600 'J': print tls_load/tls_gdcall/tls_ldcall suffix
7601 'M': print the second word of a TImode operand.
7602 'N': print the second word of a DImode operand.
76a4c804 7603 'O': print only the displacement of a memory reference or address.
7604 'R': print only the base register of a memory reference or address.
0574acbe 7605 'S': print S-type memory reference (base+displacement).
2be7449b 7606 'Y': print address style operand without index (e.g. shift count or setmem
7607 operand).
56769981 7608
45981c0a 7609 'b': print integer X as if it's an unsigned byte.
e68d6a13 7610 'c': print integer X as if it's an signed byte.
76a4c804 7611 'e': "end" contiguous bitmask X in either DImode or vector inner mode.
7612 'f': "end" contiguous bitmask X in SImode.
b9059d39 7613 'h': print integer X as if it's a signed halfword.
64a1078f 7614 'i': print the first nonzero HImode part of X.
b9059d39 7615 'j': print the first HImode part unequal to -1 of X.
7616 'k': print the first nonzero SImode part of X.
7617 'm': print the first SImode part unequal to -1 of X.
0d46035f 7618 'o': print integer X as if it's an unsigned 32bit word.
76a4c804 7619 's': "start" of contiguous bitmask X in either DImode or vector inner mode.
7620 't': CONST_INT: "start" of contiguous bitmask X in SImode.
7621 CONST_VECTOR: Generate a bitmask for vgbm instruction.
0d46035f 7622 'x': print integer X as if it's an unsigned halfword.
76a4c804 7623 'v': print register number as vector register (v1 instead of f1).
0d46035f 7624*/
4673c1a0 7625
7626void
b40da9a7 7627print_operand (FILE *file, rtx x, int code)
4673c1a0 7628{
0d46035f 7629 HOST_WIDE_INT ival;
7630
4673c1a0 7631 switch (code)
7632 {
7633 case 'C':
2eb8fe23 7634 fprintf (file, s390_branch_condition_mnemonic (x, FALSE));
4673c1a0 7635 return;
7636
7637 case 'D':
2eb8fe23 7638 fprintf (file, s390_branch_condition_mnemonic (x, TRUE));
4673c1a0 7639 return;
7640
f1443d23 7641 case 'E':
7642 if (GET_CODE (x) == LE)
7643 fprintf (file, "l");
7644 else if (GET_CODE (x) == GT)
7645 fprintf (file, "h");
7646 else
902602ef 7647 output_operand_lossage ("invalid comparison operator "
7648 "for 'E' output modifier");
f1443d23 7649 return;
7650
be00aaa8 7651 case 'J':
7652 if (GET_CODE (x) == SYMBOL_REF)
7653 {
7654 fprintf (file, "%s", ":tls_load:");
7655 output_addr_const (file, x);
7656 }
7657 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD)
7658 {
7659 fprintf (file, "%s", ":tls_gdcall:");
7660 output_addr_const (file, XVECEXP (x, 0, 0));
7661 }
7662 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM)
7663 {
7664 fprintf (file, "%s", ":tls_ldcall:");
3677652f 7665 const char *name = get_some_local_dynamic_name ();
7666 gcc_assert (name);
7667 assemble_name (file, name);
be00aaa8 7668 }
7669 else
902602ef 7670 output_operand_lossage ("invalid reference for 'J' output modifier");
be00aaa8 7671 return;
7672
cc87d0c5 7673 case 'G':
7674 fprintf (file, "%u", GET_MODE_SIZE (GET_MODE (x)));
7675 return;
7676
4673c1a0 7677 case 'O':
7678 {
7679 struct s390_address ad;
32eda510 7680 int ret;
4673c1a0 7681
76a4c804 7682 ret = s390_decompose_address (MEM_P (x) ? XEXP (x, 0) : x, &ad);
53b9033c 7683
7684 if (!ret
7685 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
7686 || ad.indx)
7687 {
902602ef 7688 output_operand_lossage ("invalid address for 'O' output modifier");
53b9033c 7689 return;
7690 }
4673c1a0 7691
7692 if (ad.disp)
74d2529d 7693 output_addr_const (file, ad.disp);
4673c1a0 7694 else
7695 fprintf (file, "0");
7696 }
7697 return;
7698
7699 case 'R':
7700 {
7701 struct s390_address ad;
32eda510 7702 int ret;
4673c1a0 7703
76a4c804 7704 ret = s390_decompose_address (MEM_P (x) ? XEXP (x, 0) : x, &ad);
53b9033c 7705
7706 if (!ret
7707 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
7708 || ad.indx)
7709 {
902602ef 7710 output_operand_lossage ("invalid address for 'R' output modifier");
53b9033c 7711 return;
7712 }
4673c1a0 7713
7714 if (ad.base)
7715 fprintf (file, "%s", reg_names[REGNO (ad.base)]);
7716 else
7717 fprintf (file, "0");
7718 }
7719 return;
7720
0574acbe 7721 case 'S':
7722 {
7723 struct s390_address ad;
32eda510 7724 int ret;
0574acbe 7725
53b9033c 7726 if (!MEM_P (x))
7727 {
902602ef 7728 output_operand_lossage ("memory reference expected for "
7729 "'S' output modifier");
53b9033c 7730 return;
7731 }
32eda510 7732 ret = s390_decompose_address (XEXP (x, 0), &ad);
53b9033c 7733
7734 if (!ret
7735 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
7736 || ad.indx)
7737 {
902602ef 7738 output_operand_lossage ("invalid address for 'S' output modifier");
53b9033c 7739 return;
7740 }
0574acbe 7741
7742 if (ad.disp)
7743 output_addr_const (file, ad.disp);
7744 else
7745 fprintf (file, "0");
7746
7747 if (ad.base)
7748 fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
7749 }
7750 return;
7751
4673c1a0 7752 case 'N':
7753 if (GET_CODE (x) == REG)
7754 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
7755 else if (GET_CODE (x) == MEM)
29c05e22 7756 x = change_address (x, VOIDmode,
7757 plus_constant (Pmode, XEXP (x, 0), 4));
4673c1a0 7758 else
902602ef 7759 output_operand_lossage ("register or memory expression expected "
7760 "for 'N' output modifier");
4673c1a0 7761 break;
7762
7763 case 'M':
7764 if (GET_CODE (x) == REG)
7765 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
7766 else if (GET_CODE (x) == MEM)
29c05e22 7767 x = change_address (x, VOIDmode,
7768 plus_constant (Pmode, XEXP (x, 0), 8));
4673c1a0 7769 else
902602ef 7770 output_operand_lossage ("register or memory expression expected "
7771 "for 'M' output modifier");
4673c1a0 7772 break;
63ebd742 7773
7774 case 'Y':
2be7449b 7775 print_addrstyle_operand (file, x);
63ebd742 7776 return;
4673c1a0 7777 }
7778
7779 switch (GET_CODE (x))
7780 {
7781 case REG:
76a4c804 7782 /* Print FP regs as fx instead of vx when they are accessed
7783 through non-vector mode. */
7784 if (code == 'v'
7785 || VECTOR_NOFP_REG_P (x)
7786 || (FP_REG_P (x) && VECTOR_MODE_P (GET_MODE (x)))
7787 || (VECTOR_REG_P (x)
7788 && (GET_MODE_SIZE (GET_MODE (x)) /
7789 s390_class_max_nregs (FP_REGS, GET_MODE (x))) > 8))
7790 fprintf (file, "%%v%s", reg_names[REGNO (x)] + 2);
7791 else
7792 fprintf (file, "%s", reg_names[REGNO (x)]);
4673c1a0 7793 break;
7794
7795 case MEM:
3c047fe9 7796 output_address (GET_MODE (x), XEXP (x, 0));
4673c1a0 7797 break;
7798
7799 case CONST:
7800 case CODE_LABEL:
7801 case LABEL_REF:
7802 case SYMBOL_REF:
74d2529d 7803 output_addr_const (file, x);
4673c1a0 7804 break;
7805
7806 case CONST_INT:
0d46035f 7807 ival = INTVAL (x);
7808 switch (code)
7809 {
7810 case 0:
7811 break;
7812 case 'b':
7813 ival &= 0xff;
7814 break;
7815 case 'c':
7816 ival = ((ival & 0xff) ^ 0x80) - 0x80;
7817 break;
7818 case 'x':
7819 ival &= 0xffff;
7820 break;
7821 case 'h':
7822 ival = ((ival & 0xffff) ^ 0x8000) - 0x8000;
7823 break;
7824 case 'i':
7825 ival = s390_extract_part (x, HImode, 0);
7826 break;
7827 case 'j':
7828 ival = s390_extract_part (x, HImode, -1);
7829 break;
7830 case 'k':
7831 ival = s390_extract_part (x, SImode, 0);
7832 break;
7833 case 'm':
7834 ival = s390_extract_part (x, SImode, -1);
7835 break;
7836 case 'o':
7837 ival &= 0xffffffff;
7838 break;
7839 case 'e': case 'f':
7840 case 's': case 't':
7841 {
e64f5133 7842 int start, end;
7843 int len;
0d46035f 7844 bool ok;
7845
7846 len = (code == 's' || code == 'e' ? 64 : 32);
e64f5133 7847 ok = s390_contiguous_bitmask_p (ival, true, len, &start, &end);
0d46035f 7848 gcc_assert (ok);
7849 if (code == 's' || code == 't')
e64f5133 7850 ival = start;
0d46035f 7851 else
e64f5133 7852 ival = end;
0d46035f 7853 }
7854 break;
7855 default:
7856 output_operand_lossage ("invalid constant for output modifier '%c'", code);
7857 }
7858 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival);
8b4a4127 7859 break;
7860
ba0e61d6 7861 case CONST_WIDE_INT:
8b4a4127 7862 if (code == 'b')
ba0e61d6 7863 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
7864 CONST_WIDE_INT_ELT (x, 0) & 0xff);
4673c1a0 7865 else if (code == 'x')
ba0e61d6 7866 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
7867 CONST_WIDE_INT_ELT (x, 0) & 0xffff);
4673c1a0 7868 else if (code == 'h')
902602ef 7869 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
ba0e61d6 7870 ((CONST_WIDE_INT_ELT (x, 0) & 0xffff) ^ 0x8000) - 0x8000);
4673c1a0 7871 else
53b9033c 7872 {
7873 if (code == 0)
902602ef 7874 output_operand_lossage ("invalid constant - try using "
7875 "an output modifier");
53b9033c 7876 else
902602ef 7877 output_operand_lossage ("invalid constant for output modifier '%c'",
7878 code);
53b9033c 7879 }
4673c1a0 7880 break;
76a4c804 7881 case CONST_VECTOR:
7882 switch (code)
7883 {
80fc7f56 7884 case 'h':
7885 gcc_assert (const_vec_duplicate_p (x));
7886 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
7887 ((INTVAL (XVECEXP (x, 0, 0)) & 0xffff) ^ 0x8000) - 0x8000);
7888 break;
76a4c804 7889 case 'e':
7890 case 's':
7891 {
e64f5133 7892 int start, end;
76a4c804 7893 bool ok;
7894
e64f5133 7895 ok = s390_contiguous_bitmask_vector_p (x, &start, &end);
76a4c804 7896 gcc_assert (ok);
e64f5133 7897 ival = (code == 's') ? start : end;
76a4c804 7898 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival);
7899 }
7900 break;
7901 case 't':
7902 {
7903 unsigned mask;
7904 bool ok = s390_bytemask_vector_p (x, &mask);
7905 gcc_assert (ok);
7906 fprintf (file, "%u", mask);
7907 }
7908 break;
7909
7910 default:
7911 output_operand_lossage ("invalid constant vector for output "
7912 "modifier '%c'", code);
7913 }
7914 break;
4673c1a0 7915
7916 default:
53b9033c 7917 if (code == 0)
902602ef 7918 output_operand_lossage ("invalid expression - try using "
7919 "an output modifier");
53b9033c 7920 else
902602ef 7921 output_operand_lossage ("invalid expression for output "
7922 "modifier '%c'", code);
4673c1a0 7923 break;
7924 }
7925}
7926
58356836 7927/* Target hook for assembling integer objects. We need to define it
7928 here to work a round a bug in some versions of GAS, which couldn't
7929 handle values smaller than INT_MIN when printed in decimal. */
7930
7931static bool
b40da9a7 7932s390_assemble_integer (rtx x, unsigned int size, int aligned_p)
58356836 7933{
7934 if (size == 8 && aligned_p
7935 && GET_CODE (x) == CONST_INT && INTVAL (x) < INT_MIN)
7936 {
4840a03a 7937 fprintf (asm_out_file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n",
7938 INTVAL (x));
58356836 7939 return true;
7940 }
7941 return default_assemble_integer (x, size, aligned_p);
7942}
7943
f81e845f 7944/* Returns true if register REGNO is used for forming
56769981 7945 a memory address in expression X. */
4673c1a0 7946
e5537457 7947static bool
b40da9a7 7948reg_used_in_mem_p (int regno, rtx x)
4673c1a0 7949{
7950 enum rtx_code code = GET_CODE (x);
7951 int i, j;
7952 const char *fmt;
f81e845f 7953
4673c1a0 7954 if (code == MEM)
7955 {
2ec77a7c 7956 if (refers_to_regno_p (regno, XEXP (x, 0)))
e5537457 7957 return true;
4673c1a0 7958 }
f81e845f 7959 else if (code == SET
8b4a4127 7960 && GET_CODE (SET_DEST (x)) == PC)
7961 {
2ec77a7c 7962 if (refers_to_regno_p (regno, SET_SRC (x)))
e5537457 7963 return true;
8b4a4127 7964 }
4673c1a0 7965
7966 fmt = GET_RTX_FORMAT (code);
7967 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
7968 {
7969 if (fmt[i] == 'e'
7970 && reg_used_in_mem_p (regno, XEXP (x, i)))
e5537457 7971 return true;
f81e845f 7972
4673c1a0 7973 else if (fmt[i] == 'E')
7974 for (j = 0; j < XVECLEN (x, i); j++)
7975 if (reg_used_in_mem_p (regno, XVECEXP (x, i, j)))
e5537457 7976 return true;
4673c1a0 7977 }
e5537457 7978 return false;
4673c1a0 7979}
7980
0c034860 7981/* Returns true if expression DEP_RTX sets an address register
56769981 7982 used by instruction INSN to address memory. */
4673c1a0 7983
e5537457 7984static bool
ed3e6e5d 7985addr_generation_dependency_p (rtx dep_rtx, rtx_insn *insn)
4673c1a0 7986{
8b4a4127 7987 rtx target, pat;
4673c1a0 7988
aa90bb35 7989 if (NONJUMP_INSN_P (dep_rtx))
77985f1a 7990 dep_rtx = PATTERN (dep_rtx);
71343e6b 7991
4673c1a0 7992 if (GET_CODE (dep_rtx) == SET)
7993 {
7994 target = SET_DEST (dep_rtx);
147b6a2d 7995 if (GET_CODE (target) == STRICT_LOW_PART)
7996 target = XEXP (target, 0);
7997 while (GET_CODE (target) == SUBREG)
7998 target = SUBREG_REG (target);
7999
4673c1a0 8000 if (GET_CODE (target) == REG)
8001 {
8002 int regno = REGNO (target);
8003
71343e6b 8004 if (s390_safe_attr_type (insn) == TYPE_LA)
8b4a4127 8005 {
8006 pat = PATTERN (insn);
8007 if (GET_CODE (pat) == PARALLEL)
8008 {
32eda510 8009 gcc_assert (XVECLEN (pat, 0) == 2);
8b4a4127 8010 pat = XVECEXP (pat, 0, 0);
8011 }
32eda510 8012 gcc_assert (GET_CODE (pat) == SET);
2ec77a7c 8013 return refers_to_regno_p (regno, SET_SRC (pat));
8b4a4127 8014 }
71343e6b 8015 else if (get_attr_atype (insn) == ATYPE_AGEN)
8b4a4127 8016 return reg_used_in_mem_p (regno, PATTERN (insn));
8017 }
4673c1a0 8018 }
e5537457 8019 return false;
4673c1a0 8020}
8021
71343e6b 8022/* Return 1, if dep_insn sets register used in insn in the agen unit. */
8023
f81e845f 8024int
ed3e6e5d 8025s390_agen_dep_p (rtx_insn *dep_insn, rtx_insn *insn)
f81e845f 8026{
71343e6b 8027 rtx dep_rtx = PATTERN (dep_insn);
8028 int i;
f81e845f 8029
8030 if (GET_CODE (dep_rtx) == SET
71343e6b 8031 && addr_generation_dependency_p (dep_rtx, insn))
8032 return 1;
8033 else if (GET_CODE (dep_rtx) == PARALLEL)
8034 {
8035 for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
8036 {
8037 if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i), insn))
8038 return 1;
8039 }
8040 }
8041 return 0;
8042}
8043
510c2327 8044
e51ae8ff 8045/* A C statement (sans semicolon) to update the integer scheduling priority
8046 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
8047 reduce the priority to execute INSN later. Do not define this macro if
f81e845f 8048 you do not need to adjust the scheduling priorities of insns.
e51ae8ff 8049
f81e845f 8050 A STD instruction should be scheduled earlier,
e51ae8ff 8051 in order to use the bypass. */
e51ae8ff 8052static int
18282db0 8053s390_adjust_priority (rtx_insn *insn, int priority)
e51ae8ff 8054{
8055 if (! INSN_P (insn))
8056 return priority;
8057
9aae2901 8058 if (s390_tune <= PROCESSOR_2064_Z900)
e51ae8ff 8059 return priority;
8060
8061 switch (s390_safe_attr_type (insn))
8062 {
11f88fec 8063 case TYPE_FSTOREDF:
8064 case TYPE_FSTORESF:
e51ae8ff 8065 priority = priority << 3;
8066 break;
8067 case TYPE_STORE:
76dbb8df 8068 case TYPE_STM:
e51ae8ff 8069 priority = priority << 1;
8070 break;
8071 default:
8072 break;
8073 }
8074 return priority;
8075}
369293ed 8076
b0eacf26 8077
71343e6b 8078/* The number of instructions that can be issued per cycle. */
369293ed 8079
71343e6b 8080static int
b40da9a7 8081s390_issue_rate (void)
71343e6b 8082{
a850370e 8083 switch (s390_tune)
8084 {
8085 case PROCESSOR_2084_Z990:
8086 case PROCESSOR_2094_Z9_109:
9aae2901 8087 case PROCESSOR_2094_Z9_EC:
33d033da 8088 case PROCESSOR_2817_Z196:
a850370e 8089 return 3;
8090 case PROCESSOR_2097_Z10:
8091 return 2;
117d67d0 8092 case PROCESSOR_9672_G5:
8093 case PROCESSOR_9672_G6:
8094 case PROCESSOR_2064_Z900:
5ed1f72b 8095 /* Starting with EC12 we use the sched_reorder hook to take care
8096 of instruction dispatch constraints. The algorithm only
8097 picks the best instruction and assumes only a single
8098 instruction gets issued per cycle. */
8099 case PROCESSOR_2827_ZEC12:
117d67d0 8100 case PROCESSOR_2964_Z13:
a168a775 8101 case PROCESSOR_3906_Z14:
a850370e 8102 default:
8103 return 1;
8104 }
71343e6b 8105}
369293ed 8106
e51ae8ff 8107static int
b40da9a7 8108s390_first_cycle_multipass_dfa_lookahead (void)
e51ae8ff 8109{
a65ea517 8110 return 4;
e51ae8ff 8111}
8112
20074f87 8113/* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
8114 Fix up MEMs as required. */
8115
8116static void
8117annotate_constant_pool_refs (rtx *x)
8118{
8119 int i, j;
8120 const char *fmt;
8121
32eda510 8122 gcc_assert (GET_CODE (*x) != SYMBOL_REF
8123 || !CONSTANT_POOL_ADDRESS_P (*x));
20074f87 8124
8125 /* Literal pool references can only occur inside a MEM ... */
8126 if (GET_CODE (*x) == MEM)
8127 {
8128 rtx memref = XEXP (*x, 0);
8129
8130 if (GET_CODE (memref) == SYMBOL_REF
8131 && CONSTANT_POOL_ADDRESS_P (memref))
8132 {
8133 rtx base = cfun->machine->base_reg;
8134 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, memref, base),
8135 UNSPEC_LTREF);
8136
8137 *x = replace_equiv_address (*x, addr);
8138 return;
8139 }
8140
8141 if (GET_CODE (memref) == CONST
8142 && GET_CODE (XEXP (memref, 0)) == PLUS
8143 && GET_CODE (XEXP (XEXP (memref, 0), 1)) == CONST_INT
8144 && GET_CODE (XEXP (XEXP (memref, 0), 0)) == SYMBOL_REF
8145 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (memref, 0), 0)))
8146 {
8147 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (memref, 0), 1));
8148 rtx sym = XEXP (XEXP (memref, 0), 0);
8149 rtx base = cfun->machine->base_reg;
8150 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, sym, base),
8151 UNSPEC_LTREF);
8152
29c05e22 8153 *x = replace_equiv_address (*x, plus_constant (Pmode, addr, off));
20074f87 8154 return;
8155 }
8156 }
8157
8158 /* ... or a load-address type pattern. */
8159 if (GET_CODE (*x) == SET)
8160 {
8161 rtx addrref = SET_SRC (*x);
8162
8163 if (GET_CODE (addrref) == SYMBOL_REF
8164 && CONSTANT_POOL_ADDRESS_P (addrref))
8165 {
8166 rtx base = cfun->machine->base_reg;
8167 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, addrref, base),
8168 UNSPEC_LTREF);
8169
8170 SET_SRC (*x) = addr;
8171 return;
8172 }
8173
8174 if (GET_CODE (addrref) == CONST
8175 && GET_CODE (XEXP (addrref, 0)) == PLUS
8176 && GET_CODE (XEXP (XEXP (addrref, 0), 1)) == CONST_INT
8177 && GET_CODE (XEXP (XEXP (addrref, 0), 0)) == SYMBOL_REF
8178 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (addrref, 0), 0)))
8179 {
8180 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (addrref, 0), 1));
8181 rtx sym = XEXP (XEXP (addrref, 0), 0);
8182 rtx base = cfun->machine->base_reg;
8183 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, sym, base),
8184 UNSPEC_LTREF);
8185
29c05e22 8186 SET_SRC (*x) = plus_constant (Pmode, addr, off);
20074f87 8187 return;
8188 }
8189 }
8190
8191 /* Annotate LTREL_BASE as well. */
8192 if (GET_CODE (*x) == UNSPEC
8193 && XINT (*x, 1) == UNSPEC_LTREL_BASE)
8194 {
8195 rtx base = cfun->machine->base_reg;
8196 *x = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, XVECEXP (*x, 0, 0), base),
8197 UNSPEC_LTREL_BASE);
8198 return;
8199 }
8200
8201 fmt = GET_RTX_FORMAT (GET_CODE (*x));
8202 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
8203 {
8204 if (fmt[i] == 'e')
8205 {
8206 annotate_constant_pool_refs (&XEXP (*x, i));
8207 }
8208 else if (fmt[i] == 'E')
8209 {
8210 for (j = 0; j < XVECLEN (*x, i); j++)
8211 annotate_constant_pool_refs (&XVECEXP (*x, i, j));
8212 }
8213 }
8214}
8215
875862bf 8216/* Split all branches that exceed the maximum distance.
8217 Returns true if this created a new literal pool entry. */
8218
8219static int
8220s390_split_branches (void)
8221{
8222 rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
32eda510 8223 int new_literal = 0, ret;
93e0956b 8224 rtx_insn *insn;
ed7591be 8225 rtx pat, target;
875862bf 8226 rtx *label;
8227
8228 /* We need correct insn addresses. */
8229
8230 shorten_branches (get_insns ());
8231
8232 /* Find all branches that exceed 64KB, and split them. */
8233
8234 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8235 {
245402e7 8236 if (! JUMP_P (insn) || tablejump_p (insn, NULL, NULL))
875862bf 8237 continue;
8238
8239 pat = PATTERN (insn);
245402e7 8240 if (GET_CODE (pat) == PARALLEL)
875862bf 8241 pat = XVECEXP (pat, 0, 0);
8242 if (GET_CODE (pat) != SET || SET_DEST (pat) != pc_rtx)
8243 continue;
8244
8245 if (GET_CODE (SET_SRC (pat)) == LABEL_REF)
8246 {
8247 label = &SET_SRC (pat);
8248 }
8249 else if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE)
8250 {
8251 if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF)
8252 label = &XEXP (SET_SRC (pat), 1);
8253 else if (GET_CODE (XEXP (SET_SRC (pat), 2)) == LABEL_REF)
8254 label = &XEXP (SET_SRC (pat), 2);
8255 else
8256 continue;
8257 }
8258 else
8259 continue;
8260
8261 if (get_attr_length (insn) <= 4)
8262 continue;
8263
77beec48 8264 /* We are going to use the return register as scratch register,
8265 make sure it will be saved/restored by the prologue/epilogue. */
8266 cfun_frame_layout.save_return_addr_p = 1;
8267
875862bf 8268 if (!flag_pic)
8269 {
8270 new_literal = 1;
ed7591be 8271 rtx mem = force_const_mem (Pmode, *label);
d1f9b275 8272 rtx_insn *set_insn = emit_insn_before (gen_rtx_SET (temp_reg, mem),
8273 insn);
ed7591be 8274 INSN_ADDRESSES_NEW (set_insn, -1);
8275 annotate_constant_pool_refs (&PATTERN (set_insn));
875862bf 8276
8277 target = temp_reg;
8278 }
8279 else
8280 {
8281 new_literal = 1;
8282 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, *label),
8283 UNSPEC_LTREL_OFFSET);
8284 target = gen_rtx_CONST (Pmode, target);
8285 target = force_const_mem (Pmode, target);
d1f9b275 8286 rtx_insn *set_insn = emit_insn_before (gen_rtx_SET (temp_reg, target),
8287 insn);
ed7591be 8288 INSN_ADDRESSES_NEW (set_insn, -1);
8289 annotate_constant_pool_refs (&PATTERN (set_insn));
875862bf 8290
8291 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, XEXP (target, 0),
8292 cfun->machine->base_reg),
8293 UNSPEC_LTREL_BASE);
8294 target = gen_rtx_PLUS (Pmode, temp_reg, target);
8295 }
8296
32eda510 8297 ret = validate_change (insn, label, target, 0);
8298 gcc_assert (ret);
875862bf 8299 }
8300
8301 return new_literal;
8302}
8303
0756cebb 8304
ffead1ca 8305/* Find an annotated literal pool symbol referenced in RTX X,
8306 and store it at REF. Will abort if X contains references to
20074f87 8307 more than one such pool symbol; multiple references to the same
8308 symbol are allowed, however.
0756cebb 8309
f81e845f 8310 The rtx pointed to by REF must be initialized to NULL_RTX
0756cebb 8311 by the caller before calling this routine. */
8312
8313static void
b40da9a7 8314find_constant_pool_ref (rtx x, rtx *ref)
0756cebb 8315{
8316 int i, j;
8317 const char *fmt;
8318
12ef3745 8319 /* Ignore LTREL_BASE references. */
8320 if (GET_CODE (x) == UNSPEC
8321 && XINT (x, 1) == UNSPEC_LTREL_BASE)
8322 return;
c2c1332a 8323 /* Likewise POOL_ENTRY insns. */
8324 if (GET_CODE (x) == UNSPEC_VOLATILE
8325 && XINT (x, 1) == UNSPECV_POOL_ENTRY)
8326 return;
12ef3745 8327
32eda510 8328 gcc_assert (GET_CODE (x) != SYMBOL_REF
8329 || !CONSTANT_POOL_ADDRESS_P (x));
20074f87 8330
8331 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_LTREF)
0756cebb 8332 {
20074f87 8333 rtx sym = XVECEXP (x, 0, 0);
32eda510 8334 gcc_assert (GET_CODE (sym) == SYMBOL_REF
8335 && CONSTANT_POOL_ADDRESS_P (sym));
20074f87 8336
0756cebb 8337 if (*ref == NULL_RTX)
20074f87 8338 *ref = sym;
ffead1ca 8339 else
32eda510 8340 gcc_assert (*ref == sym);
20074f87 8341
8342 return;
0756cebb 8343 }
8344
8345 fmt = GET_RTX_FORMAT (GET_CODE (x));
8346 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
8347 {
8348 if (fmt[i] == 'e')
8349 {
8350 find_constant_pool_ref (XEXP (x, i), ref);
8351 }
8352 else if (fmt[i] == 'E')
8353 {
8354 for (j = 0; j < XVECLEN (x, i); j++)
8355 find_constant_pool_ref (XVECEXP (x, i, j), ref);
8356 }
8357 }
8358}
8359
ffead1ca 8360/* Replace every reference to the annotated literal pool
20074f87 8361 symbol REF in X by its base plus OFFSET. */
0756cebb 8362
8363static void
20074f87 8364replace_constant_pool_ref (rtx *x, rtx ref, rtx offset)
0756cebb 8365{
8366 int i, j;
8367 const char *fmt;
8368
32eda510 8369 gcc_assert (*x != ref);
0756cebb 8370
20074f87 8371 if (GET_CODE (*x) == UNSPEC
8372 && XINT (*x, 1) == UNSPEC_LTREF
8373 && XVECEXP (*x, 0, 0) == ref)
0756cebb 8374 {
20074f87 8375 *x = gen_rtx_PLUS (Pmode, XVECEXP (*x, 0, 1), offset);
8376 return;
0756cebb 8377 }
8378
20074f87 8379 if (GET_CODE (*x) == PLUS
8380 && GET_CODE (XEXP (*x, 1)) == CONST_INT
8381 && GET_CODE (XEXP (*x, 0)) == UNSPEC
8382 && XINT (XEXP (*x, 0), 1) == UNSPEC_LTREF
8383 && XVECEXP (XEXP (*x, 0), 0, 0) == ref)
0756cebb 8384 {
20074f87 8385 rtx addr = gen_rtx_PLUS (Pmode, XVECEXP (XEXP (*x, 0), 0, 1), offset);
29c05e22 8386 *x = plus_constant (Pmode, addr, INTVAL (XEXP (*x, 1)));
20074f87 8387 return;
0756cebb 8388 }
8389
8390 fmt = GET_RTX_FORMAT (GET_CODE (*x));
8391 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
8392 {
8393 if (fmt[i] == 'e')
8394 {
20074f87 8395 replace_constant_pool_ref (&XEXP (*x, i), ref, offset);
0756cebb 8396 }
8397 else if (fmt[i] == 'E')
8398 {
8399 for (j = 0; j < XVECLEN (*x, i); j++)
20074f87 8400 replace_constant_pool_ref (&XVECEXP (*x, i, j), ref, offset);
0756cebb 8401 }
8402 }
8403}
8404
f81e845f 8405/* Check whether X contains an UNSPEC_LTREL_BASE.
12ef3745 8406 Return its constant pool symbol if found, NULL_RTX otherwise. */
96be3ab6 8407
12ef3745 8408static rtx
b40da9a7 8409find_ltrel_base (rtx x)
96be3ab6 8410{
96be3ab6 8411 int i, j;
8412 const char *fmt;
8413
12ef3745 8414 if (GET_CODE (x) == UNSPEC
8415 && XINT (x, 1) == UNSPEC_LTREL_BASE)
8416 return XVECEXP (x, 0, 0);
96be3ab6 8417
8418 fmt = GET_RTX_FORMAT (GET_CODE (x));
8419 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
8420 {
8421 if (fmt[i] == 'e')
8422 {
12ef3745 8423 rtx fnd = find_ltrel_base (XEXP (x, i));
8424 if (fnd)
8425 return fnd;
96be3ab6 8426 }
8427 else if (fmt[i] == 'E')
8428 {
8429 for (j = 0; j < XVECLEN (x, i); j++)
12ef3745 8430 {
8431 rtx fnd = find_ltrel_base (XVECEXP (x, i, j));
8432 if (fnd)
8433 return fnd;
8434 }
96be3ab6 8435 }
8436 }
8437
12ef3745 8438 return NULL_RTX;
96be3ab6 8439}
8440
20074f87 8441/* Replace any occurrence of UNSPEC_LTREL_BASE in X with its base. */
96be3ab6 8442
8443static void
20074f87 8444replace_ltrel_base (rtx *x)
96be3ab6 8445{
12ef3745 8446 int i, j;
96be3ab6 8447 const char *fmt;
8448
12ef3745 8449 if (GET_CODE (*x) == UNSPEC
8450 && XINT (*x, 1) == UNSPEC_LTREL_BASE)
96be3ab6 8451 {
20074f87 8452 *x = XVECEXP (*x, 0, 1);
12ef3745 8453 return;
96be3ab6 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')
8460 {
20074f87 8461 replace_ltrel_base (&XEXP (*x, i));
96be3ab6 8462 }
8463 else if (fmt[i] == 'E')
8464 {
8465 for (j = 0; j < XVECLEN (*x, i); j++)
20074f87 8466 replace_ltrel_base (&XVECEXP (*x, i, j));
96be3ab6 8467 }
8468 }
8469}
8470
8471
12ef3745 8472/* We keep a list of constants which we have to add to internal
0756cebb 8473 constant tables in the middle of large functions. */
8474
02b901ef 8475#define NR_C_MODES 32
3754d046 8476machine_mode constant_modes[NR_C_MODES] =
0756cebb 8477{
36868490 8478 TFmode, TImode, TDmode,
02b901ef 8479 V16QImode, V8HImode, V4SImode, V2DImode, V1TImode,
8480 V4SFmode, V2DFmode, V1TFmode,
36868490 8481 DFmode, DImode, DDmode,
76a4c804 8482 V8QImode, V4HImode, V2SImode, V1DImode, V2SFmode, V1DFmode,
36868490 8483 SFmode, SImode, SDmode,
76a4c804 8484 V4QImode, V2HImode, V1SImode, V1SFmode,
0756cebb 8485 HImode,
76a4c804 8486 V2QImode, V1HImode,
8487 QImode,
8488 V1QImode
0756cebb 8489};
8490
0756cebb 8491struct constant
8492{
8493 struct constant *next;
8494 rtx value;
93e0956b 8495 rtx_code_label *label;
0756cebb 8496};
8497
8498struct constant_pool
8499{
8500 struct constant_pool *next;
93e0956b 8501 rtx_insn *first_insn;
8502 rtx_insn *pool_insn;
96be3ab6 8503 bitmap insns;
93e0956b 8504 rtx_insn *emit_pool_after;
0756cebb 8505
8506 struct constant *constants[NR_C_MODES];
d345b493 8507 struct constant *execute;
93e0956b 8508 rtx_code_label *label;
0756cebb 8509 int size;
8510};
8511
875862bf 8512/* Allocate new constant_pool structure. */
8513
8514static struct constant_pool *
8515s390_alloc_pool (void)
8516{
8517 struct constant_pool *pool;
8518 int i;
8519
8520 pool = (struct constant_pool *) xmalloc (sizeof *pool);
8521 pool->next = NULL;
8522 for (i = 0; i < NR_C_MODES; i++)
8523 pool->constants[i] = NULL;
8524
8525 pool->execute = NULL;
8526 pool->label = gen_label_rtx ();
93e0956b 8527 pool->first_insn = NULL;
8528 pool->pool_insn = NULL;
875862bf 8529 pool->insns = BITMAP_ALLOC (NULL);
8530 pool->size = 0;
93e0956b 8531 pool->emit_pool_after = NULL;
875862bf 8532
8533 return pool;
8534}
0756cebb 8535
8536/* Create new constant pool covering instructions starting at INSN
8537 and chain it to the end of POOL_LIST. */
8538
8539static struct constant_pool *
93e0956b 8540s390_start_pool (struct constant_pool **pool_list, rtx_insn *insn)
0756cebb 8541{
8542 struct constant_pool *pool, **prev;
0756cebb 8543
c2c1332a 8544 pool = s390_alloc_pool ();
0756cebb 8545 pool->first_insn = insn;
96be3ab6 8546
0756cebb 8547 for (prev = pool_list; *prev; prev = &(*prev)->next)
8548 ;
8549 *prev = pool;
8550
8551 return pool;
8552}
8553
96be3ab6 8554/* End range of instructions covered by POOL at INSN and emit
8555 placeholder insn representing the pool. */
0756cebb 8556
8557static void
93e0956b 8558s390_end_pool (struct constant_pool *pool, rtx_insn *insn)
0756cebb 8559{
96be3ab6 8560 rtx pool_size = GEN_INT (pool->size + 8 /* alignment slop */);
8561
8562 if (!insn)
8563 insn = get_last_insn ();
8564
8565 pool->pool_insn = emit_insn_after (gen_pool (pool_size), insn);
8566 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
8567}
8568
8569/* Add INSN to the list of insns covered by POOL. */
8570
8571static void
b40da9a7 8572s390_add_pool_insn (struct constant_pool *pool, rtx insn)
96be3ab6 8573{
8574 bitmap_set_bit (pool->insns, INSN_UID (insn));
0756cebb 8575}
8576
8577/* Return pool out of POOL_LIST that covers INSN. */
8578
8579static struct constant_pool *
b40da9a7 8580s390_find_pool (struct constant_pool *pool_list, rtx insn)
0756cebb 8581{
0756cebb 8582 struct constant_pool *pool;
8583
0756cebb 8584 for (pool = pool_list; pool; pool = pool->next)
96be3ab6 8585 if (bitmap_bit_p (pool->insns, INSN_UID (insn)))
0756cebb 8586 break;
8587
8588 return pool;
8589}
8590
96be3ab6 8591/* Add constant VAL of mode MODE to the constant pool POOL. */
0756cebb 8592
96be3ab6 8593static void
3754d046 8594s390_add_constant (struct constant_pool *pool, rtx val, machine_mode mode)
0756cebb 8595{
8596 struct constant *c;
0756cebb 8597 int i;
8598
8599 for (i = 0; i < NR_C_MODES; i++)
8600 if (constant_modes[i] == mode)
8601 break;
32eda510 8602 gcc_assert (i != NR_C_MODES);
0756cebb 8603
8604 for (c = pool->constants[i]; c != NULL; c = c->next)
8605 if (rtx_equal_p (val, c->value))
8606 break;
8607
8608 if (c == NULL)
8609 {
8610 c = (struct constant *) xmalloc (sizeof *c);
8611 c->value = val;
8612 c->label = gen_label_rtx ();
8613 c->next = pool->constants[i];
8614 pool->constants[i] = c;
8615 pool->size += GET_MODE_SIZE (mode);
8616 }
96be3ab6 8617}
0756cebb 8618
1ed7a160 8619/* Return an rtx that represents the offset of X from the start of
8620 pool POOL. */
8621
8622static rtx
8623s390_pool_offset (struct constant_pool *pool, rtx x)
8624{
8625 rtx label;
8626
8627 label = gen_rtx_LABEL_REF (GET_MODE (x), pool->label);
8628 x = gen_rtx_UNSPEC (GET_MODE (x), gen_rtvec (2, x, label),
8629 UNSPEC_POOL_OFFSET);
8630 return gen_rtx_CONST (GET_MODE (x), x);
8631}
8632
96be3ab6 8633/* Find constant VAL of mode MODE in the constant pool POOL.
8634 Return an RTX describing the distance from the start of
8635 the pool to the location of the new constant. */
f81e845f 8636
96be3ab6 8637static rtx
b40da9a7 8638s390_find_constant (struct constant_pool *pool, rtx val,
3754d046 8639 machine_mode mode)
96be3ab6 8640{
8641 struct constant *c;
96be3ab6 8642 int i;
f81e845f 8643
96be3ab6 8644 for (i = 0; i < NR_C_MODES; i++)
8645 if (constant_modes[i] == mode)
8646 break;
32eda510 8647 gcc_assert (i != NR_C_MODES);
f81e845f 8648
96be3ab6 8649 for (c = pool->constants[i]; c != NULL; c = c->next)
8650 if (rtx_equal_p (val, c->value))
8651 break;
f81e845f 8652
32eda510 8653 gcc_assert (c);
f81e845f 8654
1ed7a160 8655 return s390_pool_offset (pool, gen_rtx_LABEL_REF (Pmode, c->label));
0756cebb 8656}
8657
875862bf 8658/* Check whether INSN is an execute. Return the label_ref to its
8659 execute target template if so, NULL_RTX otherwise. */
8660
8661static rtx
8662s390_execute_label (rtx insn)
8663{
aa90bb35 8664 if (NONJUMP_INSN_P (insn)
875862bf 8665 && GET_CODE (PATTERN (insn)) == PARALLEL
8666 && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == UNSPEC
8667 && XINT (XVECEXP (PATTERN (insn), 0, 0), 1) == UNSPEC_EXECUTE)
8668 return XVECEXP (XVECEXP (PATTERN (insn), 0, 0), 0, 2);
8669
8670 return NULL_RTX;
8671}
8672
d345b493 8673/* Add execute target for INSN to the constant pool POOL. */
8674
8675static void
8676s390_add_execute (struct constant_pool *pool, rtx insn)
8677{
8678 struct constant *c;
8679
8680 for (c = pool->execute; c != NULL; c = c->next)
8681 if (INSN_UID (insn) == INSN_UID (c->value))
8682 break;
8683
8684 if (c == NULL)
8685 {
d345b493 8686 c = (struct constant *) xmalloc (sizeof *c);
8687 c->value = insn;
babfdedf 8688 c->label = gen_label_rtx ();
d345b493 8689 c->next = pool->execute;
8690 pool->execute = c;
babfdedf 8691 pool->size += 6;
d345b493 8692 }
8693}
8694
8695/* Find execute target for INSN in the constant pool POOL.
8696 Return an RTX describing the distance from the start of
8697 the pool to the location of the execute target. */
8698
8699static rtx
8700s390_find_execute (struct constant_pool *pool, rtx insn)
8701{
8702 struct constant *c;
d345b493 8703
8704 for (c = pool->execute; c != NULL; c = c->next)
8705 if (INSN_UID (insn) == INSN_UID (c->value))
8706 break;
8707
32eda510 8708 gcc_assert (c);
d345b493 8709
1ed7a160 8710 return s390_pool_offset (pool, gen_rtx_LABEL_REF (Pmode, c->label));
d345b493 8711}
8712
875862bf 8713/* For an execute INSN, extract the execute target template. */
d345b493 8714
8715static rtx
875862bf 8716s390_execute_target (rtx insn)
d345b493 8717{
875862bf 8718 rtx pattern = PATTERN (insn);
8719 gcc_assert (s390_execute_label (insn));
d345b493 8720
8721 if (XVECLEN (pattern, 0) == 2)
8722 {
8723 pattern = copy_rtx (XVECEXP (pattern, 0, 1));
8724 }
8725 else
8726 {
8727 rtvec vec = rtvec_alloc (XVECLEN (pattern, 0) - 1);
8728 int i;
8729
8730 for (i = 0; i < XVECLEN (pattern, 0) - 1; i++)
8731 RTVEC_ELT (vec, i) = copy_rtx (XVECEXP (pattern, 0, i + 1));
8732
8733 pattern = gen_rtx_PARALLEL (VOIDmode, vec);
8734 }
8735
8736 return pattern;
8737}
8738
8739/* Indicate that INSN cannot be duplicated. This is the case for
8740 execute insns that carry a unique label. */
8741
8742static bool
18282db0 8743s390_cannot_copy_insn_p (rtx_insn *insn)
d345b493 8744{
8745 rtx label = s390_execute_label (insn);
8746 return label && label != const0_rtx;
8747}
8748
c2c1332a 8749/* Dump out the constants in POOL. If REMOTE_LABEL is true,
8750 do not emit the pool base label. */
0756cebb 8751
d345b493 8752static void
c2c1332a 8753s390_dump_pool (struct constant_pool *pool, bool remote_label)
0756cebb 8754{
8755 struct constant *c;
93e0956b 8756 rtx_insn *insn = pool->pool_insn;
0756cebb 8757 int i;
8758
d345b493 8759 /* Switch to rodata section. */
8760 if (TARGET_CPU_ZARCH)
8761 {
8762 insn = emit_insn_after (gen_pool_section_start (), insn);
8763 INSN_ADDRESSES_NEW (insn, -1);
8764 }
8765
8766 /* Ensure minimum pool alignment. */
dafc8d45 8767 if (TARGET_CPU_ZARCH)
d345b493 8768 insn = emit_insn_after (gen_pool_align (GEN_INT (8)), insn);
0756cebb 8769 else
d345b493 8770 insn = emit_insn_after (gen_pool_align (GEN_INT (4)), insn);
0756cebb 8771 INSN_ADDRESSES_NEW (insn, -1);
8772
d345b493 8773 /* Emit pool base label. */
c2c1332a 8774 if (!remote_label)
8775 {
8776 insn = emit_label_after (pool->label, insn);
8777 INSN_ADDRESSES_NEW (insn, -1);
8778 }
0756cebb 8779
8780 /* Dump constants in descending alignment requirement order,
8781 ensuring proper alignment for every constant. */
8782 for (i = 0; i < NR_C_MODES; i++)
8783 for (c = pool->constants[i]; c; c = c->next)
8784 {
12ef3745 8785 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
b2ed6df1 8786 rtx value = copy_rtx (c->value);
96be3ab6 8787 if (GET_CODE (value) == CONST
8788 && GET_CODE (XEXP (value, 0)) == UNSPEC
12ef3745 8789 && XINT (XEXP (value, 0), 1) == UNSPEC_LTREL_OFFSET
96be3ab6 8790 && XVECLEN (XEXP (value, 0), 0) == 1)
1ed7a160 8791 value = s390_pool_offset (pool, XVECEXP (XEXP (value, 0), 0, 0));
96be3ab6 8792
0756cebb 8793 insn = emit_label_after (c->label, insn);
8794 INSN_ADDRESSES_NEW (insn, -1);
df82fb76 8795
f588eb9f 8796 value = gen_rtx_UNSPEC_VOLATILE (constant_modes[i],
df82fb76 8797 gen_rtvec (1, value),
8798 UNSPECV_POOL_ENTRY);
8799 insn = emit_insn_after (value, insn);
0756cebb 8800 INSN_ADDRESSES_NEW (insn, -1);
8801 }
8802
d345b493 8803 /* Ensure minimum alignment for instructions. */
8804 insn = emit_insn_after (gen_pool_align (GEN_INT (2)), insn);
0756cebb 8805 INSN_ADDRESSES_NEW (insn, -1);
8806
d345b493 8807 /* Output in-pool execute template insns. */
8808 for (c = pool->execute; c; c = c->next)
8809 {
d345b493 8810 insn = emit_label_after (c->label, insn);
8811 INSN_ADDRESSES_NEW (insn, -1);
8812
8813 insn = emit_insn_after (s390_execute_target (c->value), insn);
8814 INSN_ADDRESSES_NEW (insn, -1);
8815 }
8816
8817 /* Switch back to previous section. */
8818 if (TARGET_CPU_ZARCH)
8819 {
8820 insn = emit_insn_after (gen_pool_section_end (), insn);
8821 INSN_ADDRESSES_NEW (insn, -1);
8822 }
8823
0756cebb 8824 insn = emit_barrier_after (insn);
8825 INSN_ADDRESSES_NEW (insn, -1);
8826
96be3ab6 8827 /* Remove placeholder insn. */
8828 remove_insn (pool->pool_insn);
d345b493 8829}
8830
0756cebb 8831/* Free all memory used by POOL. */
8832
8833static void
b40da9a7 8834s390_free_pool (struct constant_pool *pool)
0756cebb 8835{
d345b493 8836 struct constant *c, *next;
0756cebb 8837 int i;
8838
8839 for (i = 0; i < NR_C_MODES; i++)
d345b493 8840 for (c = pool->constants[i]; c; c = next)
8841 {
8842 next = c->next;
8843 free (c);
8844 }
8845
8846 for (c = pool->execute; c; c = next)
0756cebb 8847 {
d345b493 8848 next = c->next;
8849 free (c);
0756cebb 8850 }
8851
4d6e8511 8852 BITMAP_FREE (pool->insns);
0756cebb 8853 free (pool);
f81e845f 8854}
0756cebb 8855
0756cebb 8856
c2c1332a 8857/* Collect main literal pool. Return NULL on overflow. */
8858
8859static struct constant_pool *
8860s390_mainpool_start (void)
8861{
8862 struct constant_pool *pool;
93e0956b 8863 rtx_insn *insn;
c2c1332a 8864
8865 pool = s390_alloc_pool ();
8866
8867 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8868 {
aa90bb35 8869 if (NONJUMP_INSN_P (insn)
20074f87 8870 && GET_CODE (PATTERN (insn)) == SET
8871 && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC_VOLATILE
8872 && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPECV_MAIN_POOL)
c2c1332a 8873 {
7a64c761 8874 /* There might be two main_pool instructions if base_reg
8875 is call-clobbered; one for shrink-wrapped code and one
8876 for the rest. We want to keep the first. */
8877 if (pool->pool_insn)
8878 {
8879 insn = PREV_INSN (insn);
8880 delete_insn (NEXT_INSN (insn));
8881 continue;
8882 }
c2c1332a 8883 pool->pool_insn = insn;
8884 }
8885
babfdedf 8886 if (!TARGET_CPU_ZARCH && s390_execute_label (insn))
d345b493 8887 {
8888 s390_add_execute (pool, insn);
8889 }
aa90bb35 8890 else if (NONJUMP_INSN_P (insn) || CALL_P (insn))
c2c1332a 8891 {
8892 rtx pool_ref = NULL_RTX;
8893 find_constant_pool_ref (PATTERN (insn), &pool_ref);
8894 if (pool_ref)
8895 {
8896 rtx constant = get_pool_constant (pool_ref);
3754d046 8897 machine_mode mode = get_pool_mode (pool_ref);
c2c1332a 8898 s390_add_constant (pool, constant, mode);
8899 }
8900 }
86428198 8901
8902 /* If hot/cold partitioning is enabled we have to make sure that
8903 the literal pool is emitted in the same section where the
8904 initialization of the literal pool base pointer takes place.
8905 emit_pool_after is only used in the non-overflow case on non
8906 Z cpus where we can emit the literal pool at the end of the
8907 function body within the text section. */
8908 if (NOTE_P (insn)
7338c728 8909 && NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS
8910 && !pool->emit_pool_after)
8911 pool->emit_pool_after = PREV_INSN (insn);
c2c1332a 8912 }
8913
32eda510 8914 gcc_assert (pool->pool_insn || pool->size == 0);
c2c1332a 8915
8916 if (pool->size >= 4096)
8917 {
7de9f7aa 8918 /* We're going to chunkify the pool, so remove the main
8919 pool placeholder insn. */
8920 remove_insn (pool->pool_insn);
8921
c2c1332a 8922 s390_free_pool (pool);
8923 pool = NULL;
8924 }
8925
86428198 8926 /* If the functions ends with the section where the literal pool
8927 should be emitted set the marker to its end. */
7338c728 8928 if (pool && !pool->emit_pool_after)
86428198 8929 pool->emit_pool_after = get_last_insn ();
8930
c2c1332a 8931 return pool;
8932}
8933
8934/* POOL holds the main literal pool as collected by s390_mainpool_start.
8935 Modify the current function to output the pool constants as well as
20074f87 8936 the pool register setup instruction. */
c2c1332a 8937
8938static void
20074f87 8939s390_mainpool_finish (struct constant_pool *pool)
c2c1332a 8940{
4fed3f99 8941 rtx base_reg = cfun->machine->base_reg;
c2c1332a 8942
8943 /* If the pool is empty, we're done. */
8944 if (pool->size == 0)
8945 {
4fed3f99 8946 /* We don't actually need a base register after all. */
8947 cfun->machine->base_reg = NULL_RTX;
8948
8949 if (pool->pool_insn)
8950 remove_insn (pool->pool_insn);
c2c1332a 8951 s390_free_pool (pool);
8952 return;
8953 }
8954
8955 /* We need correct insn addresses. */
8956 shorten_branches (get_insns ());
8957
dafc8d45 8958 /* On zSeries, we use a LARL to load the pool register. The pool is
c2c1332a 8959 located in the .rodata section, so we emit it after the function. */
dafc8d45 8960 if (TARGET_CPU_ZARCH)
c2c1332a 8961 {
ed7591be 8962 rtx set = gen_main_base_64 (base_reg, pool->label);
8963 rtx_insn *insn = emit_insn_after (set, pool->pool_insn);
c2c1332a 8964 INSN_ADDRESSES_NEW (insn, -1);
8965 remove_insn (pool->pool_insn);
f588eb9f 8966
8967 insn = get_last_insn ();
c2c1332a 8968 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
8969 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
8970
8971 s390_dump_pool (pool, 0);
8972 }
8973
dafc8d45 8974 /* On S/390, if the total size of the function's code plus literal pool
c2c1332a 8975 does not exceed 4096 bytes, we use BASR to set up a function base
8976 pointer, and emit the literal pool at the end of the function. */
86428198 8977 else if (INSN_ADDRESSES (INSN_UID (pool->emit_pool_after))
c2c1332a 8978 + pool->size + 8 /* alignment slop */ < 4096)
8979 {
ed7591be 8980 rtx set = gen_main_base_31_small (base_reg, pool->label);
8981 rtx_insn *insn = emit_insn_after (set, pool->pool_insn);
c2c1332a 8982 INSN_ADDRESSES_NEW (insn, -1);
8983 remove_insn (pool->pool_insn);
8984
8985 insn = emit_label_after (pool->label, insn);
8986 INSN_ADDRESSES_NEW (insn, -1);
8987
86428198 8988 /* emit_pool_after will be set by s390_mainpool_start to the
8989 last insn of the section where the literal pool should be
8990 emitted. */
8991 insn = pool->emit_pool_after;
8992
c2c1332a 8993 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
8994 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
8995
8996 s390_dump_pool (pool, 1);
8997 }
8998
8999 /* Otherwise, we emit an inline literal pool and use BASR to branch
9000 over it, setting up the pool register at the same time. */
9001 else
9002 {
ed7591be 9003 rtx_code_label *pool_end = gen_label_rtx ();
c2c1332a 9004
ed7591be 9005 rtx pat = gen_main_base_31_large (base_reg, pool->label, pool_end);
9006 rtx_insn *insn = emit_jump_insn_after (pat, pool->pool_insn);
12f0f6d7 9007 JUMP_LABEL (insn) = pool_end;
c2c1332a 9008 INSN_ADDRESSES_NEW (insn, -1);
9009 remove_insn (pool->pool_insn);
9010
9011 insn = emit_label_after (pool->label, insn);
9012 INSN_ADDRESSES_NEW (insn, -1);
9013
9014 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
9015 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
9016
9017 insn = emit_label_after (pool_end, pool->pool_insn);
9018 INSN_ADDRESSES_NEW (insn, -1);
9019
9020 s390_dump_pool (pool, 1);
9021 }
9022
9023
9024 /* Replace all literal pool references. */
9025
91a55c11 9026 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
c2c1332a 9027 {
9028 if (INSN_P (insn))
20074f87 9029 replace_ltrel_base (&PATTERN (insn));
c2c1332a 9030
aa90bb35 9031 if (NONJUMP_INSN_P (insn) || CALL_P (insn))
c2c1332a 9032 {
9033 rtx addr, pool_ref = NULL_RTX;
9034 find_constant_pool_ref (PATTERN (insn), &pool_ref);
9035 if (pool_ref)
9036 {
d345b493 9037 if (s390_execute_label (insn))
9038 addr = s390_find_execute (pool, insn);
9039 else
9040 addr = s390_find_constant (pool, get_pool_constant (pool_ref),
9041 get_pool_mode (pool_ref));
9042
c2c1332a 9043 replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
9044 INSN_CODE (insn) = -1;
9045 }
9046 }
9047 }
9048
9049
9050 /* Free the pool. */
9051 s390_free_pool (pool);
9052}
9053
9054/* POOL holds the main literal pool as collected by s390_mainpool_start.
9055 We have decided we cannot use this pool, so revert all changes
9056 to the current function that were done by s390_mainpool_start. */
9057static void
9058s390_mainpool_cancel (struct constant_pool *pool)
9059{
9060 /* We didn't actually change the instruction stream, so simply
9061 free the pool memory. */
9062 s390_free_pool (pool);
9063}
9064
9065
20074f87 9066/* Chunkify the literal pool. */
4673c1a0 9067
0756cebb 9068#define S390_POOL_CHUNK_MIN 0xc00
9069#define S390_POOL_CHUNK_MAX 0xe00
9070
f81e845f 9071static struct constant_pool *
20074f87 9072s390_chunkify_start (void)
4673c1a0 9073{
0756cebb 9074 struct constant_pool *curr_pool = NULL, *pool_list = NULL;
9075 int extra_size = 0;
9076 bitmap far_labels;
12ef3745 9077 rtx pending_ltrel = NULL_RTX;
93e0956b 9078 rtx_insn *insn;
4673c1a0 9079
b40da9a7 9080 rtx (*gen_reload_base) (rtx, rtx) =
dafc8d45 9081 TARGET_CPU_ZARCH? gen_reload_base_64 : gen_reload_base_31;
96be3ab6 9082
9083
9a2a66ae 9084 /* We need correct insn addresses. */
9085
9086 shorten_branches (get_insns ());
9087
12ef3745 9088 /* Scan all insns and move literals to pool chunks. */
479ca6e8 9089
479ca6e8 9090 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4673c1a0 9091 {
86428198 9092 bool section_switch_p = false;
9093
12ef3745 9094 /* Check for pending LTREL_BASE. */
9095 if (INSN_P (insn))
9096 {
9097 rtx ltrel_base = find_ltrel_base (PATTERN (insn));
9098 if (ltrel_base)
9099 {
32eda510 9100 gcc_assert (ltrel_base == pending_ltrel);
9101 pending_ltrel = NULL_RTX;
12ef3745 9102 }
9103 }
9104
babfdedf 9105 if (!TARGET_CPU_ZARCH && s390_execute_label (insn))
d345b493 9106 {
9107 if (!curr_pool)
9108 curr_pool = s390_start_pool (&pool_list, insn);
9109
9110 s390_add_execute (curr_pool, insn);
9111 s390_add_pool_insn (curr_pool, insn);
9112 }
aa90bb35 9113 else if (NONJUMP_INSN_P (insn) || CALL_P (insn))
0756cebb 9114 {
96be3ab6 9115 rtx pool_ref = NULL_RTX;
0756cebb 9116 find_constant_pool_ref (PATTERN (insn), &pool_ref);
9117 if (pool_ref)
9118 {
12ef3745 9119 rtx constant = get_pool_constant (pool_ref);
3754d046 9120 machine_mode mode = get_pool_mode (pool_ref);
12ef3745 9121
0756cebb 9122 if (!curr_pool)
9123 curr_pool = s390_start_pool (&pool_list, insn);
9124
12ef3745 9125 s390_add_constant (curr_pool, constant, mode);
96be3ab6 9126 s390_add_pool_insn (curr_pool, insn);
96be3ab6 9127
12ef3745 9128 /* Don't split the pool chunk between a LTREL_OFFSET load
9129 and the corresponding LTREL_BASE. */
9130 if (GET_CODE (constant) == CONST
9131 && GET_CODE (XEXP (constant, 0)) == UNSPEC
9132 && XINT (XEXP (constant, 0), 1) == UNSPEC_LTREL_OFFSET)
9133 {
32eda510 9134 gcc_assert (!pending_ltrel);
12ef3745 9135 pending_ltrel = pool_ref;
9136 }
0756cebb 9137 }
9138 }
9139
91f71fa3 9140 if (JUMP_P (insn) || JUMP_TABLE_DATA_P (insn) || LABEL_P (insn))
12ef3745 9141 {
9142 if (curr_pool)
9143 s390_add_pool_insn (curr_pool, insn);
9144 /* An LTREL_BASE must follow within the same basic block. */
32eda510 9145 gcc_assert (!pending_ltrel);
12ef3745 9146 }
96be3ab6 9147
414bc417 9148 if (NOTE_P (insn))
9149 switch (NOTE_KIND (insn))
9150 {
9151 case NOTE_INSN_SWITCH_TEXT_SECTIONS:
9152 section_switch_p = true;
9153 break;
9154 case NOTE_INSN_VAR_LOCATION:
9155 case NOTE_INSN_CALL_ARG_LOCATION:
9156 continue;
9157 default:
9158 break;
9159 }
86428198 9160
f81e845f 9161 if (!curr_pool
0756cebb 9162 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn)
9163 || INSN_ADDRESSES (INSN_UID (insn)) == -1)
4673c1a0 9164 continue;
479ca6e8 9165
dafc8d45 9166 if (TARGET_CPU_ZARCH)
4673c1a0 9167 {
0756cebb 9168 if (curr_pool->size < S390_POOL_CHUNK_MAX)
9169 continue;
479ca6e8 9170
93e0956b 9171 s390_end_pool (curr_pool, NULL);
0756cebb 9172 curr_pool = NULL;
9173 }
9174 else
4673c1a0 9175 {
0756cebb 9176 int chunk_size = INSN_ADDRESSES (INSN_UID (insn))
b40da9a7 9177 - INSN_ADDRESSES (INSN_UID (curr_pool->first_insn))
0756cebb 9178 + extra_size;
9179
9180 /* We will later have to insert base register reload insns.
9181 Those will have an effect on code size, which we need to
9182 consider here. This calculation makes rather pessimistic
9183 worst-case assumptions. */
aa90bb35 9184 if (LABEL_P (insn))
0756cebb 9185 extra_size += 6;
0756cebb 9186
9187 if (chunk_size < S390_POOL_CHUNK_MIN
86428198 9188 && curr_pool->size < S390_POOL_CHUNK_MIN
9189 && !section_switch_p)
0756cebb 9190 continue;
9191
9192 /* Pool chunks can only be inserted after BARRIERs ... */
aa90bb35 9193 if (BARRIER_P (insn))
0756cebb 9194 {
9195 s390_end_pool (curr_pool, insn);
9196 curr_pool = NULL;
9197 extra_size = 0;
9198 }
9199
9200 /* ... so if we don't find one in time, create one. */
86428198 9201 else if (chunk_size > S390_POOL_CHUNK_MAX
9202 || curr_pool->size > S390_POOL_CHUNK_MAX
9203 || section_switch_p)
0756cebb 9204 {
93e0956b 9205 rtx_insn *label, *jump, *barrier, *next, *prev;
0756cebb 9206
86428198 9207 if (!section_switch_p)
9208 {
9209 /* We can insert the barrier only after a 'real' insn. */
aa90bb35 9210 if (! NONJUMP_INSN_P (insn) && ! CALL_P (insn))
86428198 9211 continue;
9212 if (get_attr_length (insn) == 0)
9213 continue;
9214 /* Don't separate LTREL_BASE from the corresponding
414bc417 9215 LTREL_OFFSET load. */
86428198 9216 if (pending_ltrel)
9217 continue;
414bc417 9218 next = insn;
9219 do
9220 {
9221 insn = next;
9222 next = NEXT_INSN (insn);
9223 }
9224 while (next
9225 && NOTE_P (next)
9226 && (NOTE_KIND (next) == NOTE_INSN_VAR_LOCATION
9227 || NOTE_KIND (next) == NOTE_INSN_CALL_ARG_LOCATION));
86428198 9228 }
9229 else
9230 {
9231 gcc_assert (!pending_ltrel);
9232
9233 /* The old pool has to end before the section switch
9234 note in order to make it part of the current
9235 section. */
9236 insn = PREV_INSN (insn);
9237 }
96be3ab6 9238
b40da9a7 9239 label = gen_label_rtx ();
414bc417 9240 prev = insn;
9241 if (prev && NOTE_P (prev))
9242 prev = prev_nonnote_insn (prev);
9243 if (prev)
9244 jump = emit_jump_insn_after_setloc (gen_jump (label), insn,
d53c050c 9245 INSN_LOCATION (prev));
414bc417 9246 else
9247 jump = emit_jump_insn_after_noloc (gen_jump (label), insn);
0756cebb 9248 barrier = emit_barrier_after (jump);
9249 insn = emit_label_after (label, barrier);
9250 JUMP_LABEL (jump) = label;
9251 LABEL_NUSES (label) = 1;
9252
96be3ab6 9253 INSN_ADDRESSES_NEW (jump, -1);
9254 INSN_ADDRESSES_NEW (barrier, -1);
0756cebb 9255 INSN_ADDRESSES_NEW (insn, -1);
9256
9257 s390_end_pool (curr_pool, barrier);
9258 curr_pool = NULL;
9259 extra_size = 0;
9260 }
479ca6e8 9261 }
4673c1a0 9262 }
9fa6d5d9 9263
96be3ab6 9264 if (curr_pool)
93e0956b 9265 s390_end_pool (curr_pool, NULL);
32eda510 9266 gcc_assert (!pending_ltrel);
0756cebb 9267
f81e845f 9268 /* Find all labels that are branched into
479ca6e8 9269 from an insn belonging to a different chunk. */
9fa6d5d9 9270
4d6e8511 9271 far_labels = BITMAP_ALLOC (NULL);
a8ef833a 9272
479ca6e8 9273 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4673c1a0 9274 {
c86d86ff 9275 rtx_jump_table_data *table;
245402e7 9276
0756cebb 9277 /* Labels marked with LABEL_PRESERVE_P can be target
9278 of non-local jumps, so we have to mark them.
9279 The same holds for named labels.
9280
9281 Don't do that, however, if it is the label before
9282 a jump table. */
9283
aa90bb35 9284 if (LABEL_P (insn)
0756cebb 9285 && (LABEL_PRESERVE_P (insn) || LABEL_NAME (insn)))
9286 {
93e0956b 9287 rtx_insn *vec_insn = NEXT_INSN (insn);
77985f1a 9288 if (! vec_insn || ! JUMP_TABLE_DATA_P (vec_insn))
0756cebb 9289 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (insn));
9290 }
245402e7 9291 /* Check potential targets in a table jump (casesi_jump). */
9292 else if (tablejump_p (insn, NULL, &table))
9293 {
9294 rtx vec_pat = PATTERN (table);
9295 int i, diff_p = GET_CODE (vec_pat) == ADDR_DIFF_VEC;
9296
9297 for (i = 0; i < XVECLEN (vec_pat, diff_p); i++)
9298 {
9299 rtx label = XEXP (XVECEXP (vec_pat, diff_p, i), 0);
0756cebb 9300
245402e7 9301 if (s390_find_pool (pool_list, label)
9302 != s390_find_pool (pool_list, insn))
9303 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
9304 }
9305 }
9306 /* If we have a direct jump (conditional or unconditional),
9307 check all potential targets. */
aa90bb35 9308 else if (JUMP_P (insn))
479ca6e8 9309 {
245402e7 9310 rtx pat = PATTERN (insn);
0cd9a9a9 9311
245402e7 9312 if (GET_CODE (pat) == PARALLEL)
3c482144 9313 pat = XVECEXP (pat, 0, 0);
9314
245402e7 9315 if (GET_CODE (pat) == SET)
9316 {
96be3ab6 9317 rtx label = JUMP_LABEL (insn);
7a64c761 9318 if (label && !ANY_RETURN_P (label))
479ca6e8 9319 {
245402e7 9320 if (s390_find_pool (pool_list, label)
0756cebb 9321 != s390_find_pool (pool_list, insn))
9322 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
479ca6e8 9323 }
0756cebb 9324 }
245402e7 9325 }
4673c1a0 9326 }
9fa6d5d9 9327
0756cebb 9328 /* Insert base register reload insns before every pool. */
9329
9330 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
96be3ab6 9331 {
ffead1ca 9332 rtx new_insn = gen_reload_base (cfun->machine->base_reg,
20074f87 9333 curr_pool->label);
93e0956b 9334 rtx_insn *insn = curr_pool->first_insn;
96be3ab6 9335 INSN_ADDRESSES_NEW (emit_insn_before (new_insn, insn), -1);
9336 }
0756cebb 9337
9338 /* Insert base register reload insns at every far label. */
479ca6e8 9339
479ca6e8 9340 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
aa90bb35 9341 if (LABEL_P (insn)
0756cebb 9342 && bitmap_bit_p (far_labels, CODE_LABEL_NUMBER (insn)))
9343 {
9344 struct constant_pool *pool = s390_find_pool (pool_list, insn);
9345 if (pool)
9346 {
ffead1ca 9347 rtx new_insn = gen_reload_base (cfun->machine->base_reg,
20074f87 9348 pool->label);
96be3ab6 9349 INSN_ADDRESSES_NEW (emit_insn_after (new_insn, insn), -1);
0756cebb 9350 }
9351 }
9352
96be3ab6 9353
4d6e8511 9354 BITMAP_FREE (far_labels);
479ca6e8 9355
479ca6e8 9356
9357 /* Recompute insn addresses. */
9358
9359 init_insn_lengths ();
9360 shorten_branches (get_insns ());
4673c1a0 9361
96be3ab6 9362 return pool_list;
9363}
4673c1a0 9364
96be3ab6 9365/* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
f81e845f 9366 After we have decided to use this list, finish implementing
20074f87 9367 all changes to the current function as required. */
f81e845f 9368
96be3ab6 9369static void
20074f87 9370s390_chunkify_finish (struct constant_pool *pool_list)
96be3ab6 9371{
96be3ab6 9372 struct constant_pool *curr_pool = NULL;
93e0956b 9373 rtx_insn *insn;
f81e845f 9374
9375
96be3ab6 9376 /* Replace all literal pool references. */
9377
f81e845f 9378 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
96be3ab6 9379 {
12ef3745 9380 if (INSN_P (insn))
20074f87 9381 replace_ltrel_base (&PATTERN (insn));
12ef3745 9382
96be3ab6 9383 curr_pool = s390_find_pool (pool_list, insn);
9384 if (!curr_pool)
9385 continue;
9386
aa90bb35 9387 if (NONJUMP_INSN_P (insn) || CALL_P (insn))
96be3ab6 9388 {
9389 rtx addr, pool_ref = NULL_RTX;
9390 find_constant_pool_ref (PATTERN (insn), &pool_ref);
9391 if (pool_ref)
9392 {
d345b493 9393 if (s390_execute_label (insn))
9394 addr = s390_find_execute (curr_pool, insn);
9395 else
9396 addr = s390_find_constant (curr_pool,
9397 get_pool_constant (pool_ref),
9398 get_pool_mode (pool_ref));
9399
96be3ab6 9400 replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
9401 INSN_CODE (insn) = -1;
9402 }
96be3ab6 9403 }
9404 }
9405
9406 /* Dump out all literal pools. */
f81e845f 9407
96be3ab6 9408 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
c2c1332a 9409 s390_dump_pool (curr_pool, 0);
f81e845f 9410
96be3ab6 9411 /* Free pool list. */
9412
9413 while (pool_list)
9414 {
9415 struct constant_pool *next = pool_list->next;
9416 s390_free_pool (pool_list);
9417 pool_list = next;
9418 }
9419}
9420
9421/* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
9422 We have decided we cannot use this list, so revert all changes
9423 to the current function that were done by s390_chunkify_start. */
f81e845f 9424
96be3ab6 9425static void
b40da9a7 9426s390_chunkify_cancel (struct constant_pool *pool_list)
96be3ab6 9427{
9428 struct constant_pool *curr_pool = NULL;
93e0956b 9429 rtx_insn *insn;
96be3ab6 9430
9431 /* Remove all pool placeholder insns. */
9432
9433 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
9434 {
9435 /* Did we insert an extra barrier? Remove it. */
93e0956b 9436 rtx_insn *barrier = PREV_INSN (curr_pool->pool_insn);
9437 rtx_insn *jump = barrier? PREV_INSN (barrier) : NULL;
9438 rtx_insn *label = NEXT_INSN (curr_pool->pool_insn);
96be3ab6 9439
aa90bb35 9440 if (jump && JUMP_P (jump)
9441 && barrier && BARRIER_P (barrier)
9442 && label && LABEL_P (label)
96be3ab6 9443 && GET_CODE (PATTERN (jump)) == SET
9444 && SET_DEST (PATTERN (jump)) == pc_rtx
9445 && GET_CODE (SET_SRC (PATTERN (jump))) == LABEL_REF
9446 && XEXP (SET_SRC (PATTERN (jump)), 0) == label)
9447 {
9448 remove_insn (jump);
9449 remove_insn (barrier);
9450 remove_insn (label);
0756cebb 9451 }
4673c1a0 9452
96be3ab6 9453 remove_insn (curr_pool->pool_insn);
9454 }
9455
12ef3745 9456 /* Remove all base register reload insns. */
96be3ab6 9457
9458 for (insn = get_insns (); insn; )
9459 {
93e0956b 9460 rtx_insn *next_insn = NEXT_INSN (insn);
96be3ab6 9461
aa90bb35 9462 if (NONJUMP_INSN_P (insn)
96be3ab6 9463 && GET_CODE (PATTERN (insn)) == SET
9464 && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC
12ef3745 9465 && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPEC_RELOAD_BASE)
96be3ab6 9466 remove_insn (insn);
4673c1a0 9467
96be3ab6 9468 insn = next_insn;
9469 }
9470
9471 /* Free pool list. */
4673c1a0 9472
0756cebb 9473 while (pool_list)
4673c1a0 9474 {
0756cebb 9475 struct constant_pool *next = pool_list->next;
9476 s390_free_pool (pool_list);
9477 pool_list = next;
4673c1a0 9478 }
4673c1a0 9479}
9480
74d2529d 9481/* Output the constant pool entry EXP in mode MODE with alignment ALIGN. */
df82fb76 9482
9483void
3754d046 9484s390_output_pool_entry (rtx exp, machine_mode mode, unsigned int align)
df82fb76 9485{
df82fb76 9486 switch (GET_MODE_CLASS (mode))
9487 {
9488 case MODE_FLOAT:
36868490 9489 case MODE_DECIMAL_FLOAT:
32eda510 9490 gcc_assert (GET_CODE (exp) == CONST_DOUBLE);
df82fb76 9491
945f7b03 9492 assemble_real (*CONST_DOUBLE_REAL_VALUE (exp), mode, align);
df82fb76 9493 break;
9494
9495 case MODE_INT:
74d2529d 9496 assemble_integer (exp, GET_MODE_SIZE (mode), align, 1);
af2a449c 9497 mark_symbol_refs_as_used (exp);
df82fb76 9498 break;
9499
76a4c804 9500 case MODE_VECTOR_INT:
9501 case MODE_VECTOR_FLOAT:
9502 {
9503 int i;
9504 machine_mode inner_mode;
9505 gcc_assert (GET_CODE (exp) == CONST_VECTOR);
9506
9507 inner_mode = GET_MODE_INNER (GET_MODE (exp));
9508 for (i = 0; i < XVECLEN (exp, 0); i++)
9509 s390_output_pool_entry (XVECEXP (exp, 0, i),
9510 inner_mode,
9511 i == 0
9512 ? align
9513 : GET_MODE_BITSIZE (inner_mode));
9514 }
9515 break;
9516
df82fb76 9517 default:
32eda510 9518 gcc_unreachable ();
df82fb76 9519 }
9520}
9521
9522
875862bf 9523/* Return an RTL expression representing the value of the return address
9524 for the frame COUNT steps up from the current frame. FRAME is the
9525 frame pointer of that frame. */
0756cebb 9526
875862bf 9527rtx
9528s390_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
0756cebb 9529{
875862bf 9530 int offset;
9531 rtx addr;
96be3ab6 9532
875862bf 9533 /* Without backchain, we fail for all but the current frame. */
9a2a66ae 9534
875862bf 9535 if (!TARGET_BACKCHAIN && count > 0)
9536 return NULL_RTX;
9a2a66ae 9537
875862bf 9538 /* For the current frame, we need to make sure the initial
9539 value of RETURN_REGNUM is actually saved. */
9a2a66ae 9540
875862bf 9541 if (count == 0)
9a2a66ae 9542 {
1e639cb0 9543 /* On non-z architectures branch splitting could overwrite r14. */
9544 if (TARGET_CPU_ZARCH)
9545 return get_hard_reg_initial_val (Pmode, RETURN_REGNUM);
9546 else
9547 {
9548 cfun_frame_layout.save_return_addr_p = true;
9549 return gen_rtx_MEM (Pmode, return_address_pointer_rtx);
9550 }
875862bf 9551 }
9a2a66ae 9552
875862bf 9553 if (TARGET_PACKED_STACK)
b5fdc416 9554 offset = -2 * UNITS_PER_LONG;
875862bf 9555 else
b5fdc416 9556 offset = RETURN_REGNUM * UNITS_PER_LONG;
9a2a66ae 9557
29c05e22 9558 addr = plus_constant (Pmode, frame, offset);
875862bf 9559 addr = memory_address (Pmode, addr);
9560 return gen_rtx_MEM (Pmode, addr);
9561}
9a2a66ae 9562
875862bf 9563/* Return an RTL expression representing the back chain stored in
9564 the current stack frame. */
5fe74ca1 9565
875862bf 9566rtx
9567s390_back_chain_rtx (void)
9568{
9569 rtx chain;
5fe74ca1 9570
875862bf 9571 gcc_assert (TARGET_BACKCHAIN);
5fe74ca1 9572
875862bf 9573 if (TARGET_PACKED_STACK)
29c05e22 9574 chain = plus_constant (Pmode, stack_pointer_rtx,
b5fdc416 9575 STACK_POINTER_OFFSET - UNITS_PER_LONG);
875862bf 9576 else
9577 chain = stack_pointer_rtx;
5fe74ca1 9578
875862bf 9579 chain = gen_rtx_MEM (Pmode, chain);
9580 return chain;
9581}
9a2a66ae 9582
875862bf 9583/* Find first call clobbered register unused in a function.
9584 This could be used as base register in a leaf function
9585 or for holding the return address before epilogue. */
9a2a66ae 9586
875862bf 9587static int
9588find_unused_clobbered_reg (void)
9589{
9590 int i;
9591 for (i = 0; i < 6; i++)
3072d30e 9592 if (!df_regs_ever_live_p (i))
875862bf 9593 return i;
9594 return 0;
9595}
9a2a66ae 9596
1e639cb0 9597
ffead1ca 9598/* Helper function for s390_regs_ever_clobbered. Sets the fields in DATA for all
1e639cb0 9599 clobbered hard regs in SETREG. */
9600
9601static void
81a410b1 9602s390_reg_clobbered_rtx (rtx setreg, const_rtx set_insn ATTRIBUTE_UNUSED, void *data)
1e639cb0 9603{
ff4ce128 9604 char *regs_ever_clobbered = (char *)data;
1e639cb0 9605 unsigned int i, regno;
3754d046 9606 machine_mode mode = GET_MODE (setreg);
1e639cb0 9607
9608 if (GET_CODE (setreg) == SUBREG)
9609 {
9610 rtx inner = SUBREG_REG (setreg);
5ada7a14 9611 if (!GENERAL_REG_P (inner) && !FP_REG_P (inner))
1e639cb0 9612 return;
9613 regno = subreg_regno (setreg);
9614 }
5ada7a14 9615 else if (GENERAL_REG_P (setreg) || FP_REG_P (setreg))
1e639cb0 9616 regno = REGNO (setreg);
9617 else
9618 return;
9619
9620 for (i = regno;
9621 i < regno + HARD_REGNO_NREGS (regno, mode);
9622 i++)
9623 regs_ever_clobbered[i] = 1;
9624}
9625
9626/* Walks through all basic blocks of the current function looking
9627 for clobbered hard regs using s390_reg_clobbered_rtx. The fields
9628 of the passed integer array REGS_EVER_CLOBBERED are set to one for
9629 each of those regs. */
9630
9631static void
ff4ce128 9632s390_regs_ever_clobbered (char regs_ever_clobbered[])
1e639cb0 9633{
9634 basic_block cur_bb;
93e0956b 9635 rtx_insn *cur_insn;
1e639cb0 9636 unsigned int i;
9637
ff4ce128 9638 memset (regs_ever_clobbered, 0, 32);
1e639cb0 9639
9640 /* For non-leaf functions we have to consider all call clobbered regs to be
9641 clobbered. */
d5bf7b64 9642 if (!crtl->is_leaf)
1e639cb0 9643 {
5ada7a14 9644 for (i = 0; i < 32; i++)
1e639cb0 9645 regs_ever_clobbered[i] = call_really_used_regs[i];
9646 }
9647
9648 /* Make the "magic" eh_return registers live if necessary. For regs_ever_live
9649 this work is done by liveness analysis (mark_regs_live_at_end).
9650 Special care is needed for functions containing landing pads. Landing pads
9651 may use the eh registers, but the code which sets these registers is not
9652 contained in that function. Hence s390_regs_ever_clobbered is not able to
9653 deal with this automatically. */
18d50ae6 9654 if (crtl->calls_eh_return || cfun->machine->has_landing_pad_p)
1e639cb0 9655 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM ; i++)
ffead1ca 9656 if (crtl->calls_eh_return
9657 || (cfun->machine->has_landing_pad_p
3072d30e 9658 && df_regs_ever_live_p (EH_RETURN_DATA_REGNO (i))))
220be973 9659 regs_ever_clobbered[EH_RETURN_DATA_REGNO (i)] = 1;
1e639cb0 9660
9661 /* For nonlocal gotos all call-saved registers have to be saved.
9662 This flag is also set for the unwinding code in libgcc.
9663 See expand_builtin_unwind_init. For regs_ever_live this is done by
9664 reload. */
ff4ce128 9665 if (crtl->saves_all_registers)
5ada7a14 9666 for (i = 0; i < 32; i++)
1e639cb0 9667 if (!call_really_used_regs[i])
9668 regs_ever_clobbered[i] = 1;
9669
fc00614f 9670 FOR_EACH_BB_FN (cur_bb, cfun)
1e639cb0 9671 {
9672 FOR_BB_INSNS (cur_bb, cur_insn)
9673 {
ff4ce128 9674 rtx pat;
9675
9676 if (!INSN_P (cur_insn))
9677 continue;
9678
9679 pat = PATTERN (cur_insn);
9680
9681 /* Ignore GPR restore insns. */
9682 if (epilogue_completed && RTX_FRAME_RELATED_P (cur_insn))
9683 {
9684 if (GET_CODE (pat) == SET
9685 && GENERAL_REG_P (SET_DEST (pat)))
9686 {
9687 /* lgdr */
9688 if (GET_MODE (SET_SRC (pat)) == DImode
9689 && FP_REG_P (SET_SRC (pat)))
9690 continue;
9691
9692 /* l / lg */
9693 if (GET_CODE (SET_SRC (pat)) == MEM)
9694 continue;
9695 }
9696
9697 /* lm / lmg */
9698 if (GET_CODE (pat) == PARALLEL
9699 && load_multiple_operation (pat, VOIDmode))
9700 continue;
9701 }
9702
9703 note_stores (pat,
9704 s390_reg_clobbered_rtx,
9705 regs_ever_clobbered);
1e639cb0 9706 }
9707 }
9708}
9709
ffead1ca 9710/* Determine the frame area which actually has to be accessed
9711 in the function epilogue. The values are stored at the
875862bf 9712 given pointers AREA_BOTTOM (address of the lowest used stack
ffead1ca 9713 address) and AREA_TOP (address of the first item which does
875862bf 9714 not belong to the stack frame). */
5fe74ca1 9715
875862bf 9716static void
9717s390_frame_area (int *area_bottom, int *area_top)
9718{
9719 int b, t;
5fe74ca1 9720
875862bf 9721 b = INT_MAX;
9722 t = INT_MIN;
67928721 9723
9724 if (cfun_frame_layout.first_restore_gpr != -1)
9725 {
9726 b = (cfun_frame_layout.gprs_offset
b5fdc416 9727 + cfun_frame_layout.first_restore_gpr * UNITS_PER_LONG);
67928721 9728 t = b + (cfun_frame_layout.last_restore_gpr
b5fdc416 9729 - cfun_frame_layout.first_restore_gpr + 1) * UNITS_PER_LONG;
67928721 9730 }
9731
9732 if (TARGET_64BIT && cfun_save_high_fprs_p)
9733 {
9734 b = MIN (b, cfun_frame_layout.f8_offset);
9735 t = MAX (t, (cfun_frame_layout.f8_offset
9736 + cfun_frame_layout.high_fprs * 8));
9737 }
9738
9739 if (!TARGET_64BIT)
29439367 9740 {
6a2469fe 9741 if (cfun_fpr_save_p (FPR4_REGNUM))
67928721 9742 {
29439367 9743 b = MIN (b, cfun_frame_layout.f4_offset);
9744 t = MAX (t, cfun_frame_layout.f4_offset + 8);
67928721 9745 }
6a2469fe 9746 if (cfun_fpr_save_p (FPR6_REGNUM))
29439367 9747 {
9748 b = MIN (b, cfun_frame_layout.f4_offset + 8);
9749 t = MAX (t, cfun_frame_layout.f4_offset + 16);
9750 }
9751 }
67928721 9752 *area_bottom = b;
9753 *area_top = t;
9754}
ff4ce128 9755/* Update gpr_save_slots in the frame layout trying to make use of
9756 FPRs as GPR save slots.
9757 This is a helper routine of s390_register_info. */
8b4a4127 9758
9759static void
ff4ce128 9760s390_register_info_gprtofpr ()
8b4a4127 9761{
ff4ce128 9762 int save_reg_slot = FPR0_REGNUM;
8b4a4127 9763 int i, j;
8b4a4127 9764
ff4ce128 9765 if (!TARGET_Z10 || !TARGET_HARD_FLOAT || !crtl->is_leaf)
9766 return;
1e639cb0 9767
a8078ffb 9768 /* builtin_eh_return needs to be able to modify the return address
9769 on the stack. It could also adjust the FPR save slot instead but
9770 is it worth the trouble?! */
9771 if (crtl->calls_eh_return)
9772 return;
9773
ff4ce128 9774 for (i = 15; i >= 6; i--)
5ada7a14 9775 {
1d3cea74 9776 if (cfun_gpr_save_slot (i) == SAVE_SLOT_NONE)
ff4ce128 9777 continue;
68bc0408 9778
ff4ce128 9779 /* Advance to the next FP register which can be used as a
9780 GPR save slot. */
9781 while ((!call_really_used_regs[save_reg_slot]
9782 || df_regs_ever_live_p (save_reg_slot)
9783 || cfun_fpr_save_p (save_reg_slot))
9784 && FP_REGNO_P (save_reg_slot))
9785 save_reg_slot++;
9786 if (!FP_REGNO_P (save_reg_slot))
9787 {
9788 /* We only want to use ldgr/lgdr if we can get rid of
9789 stm/lm entirely. So undo the gpr slot allocation in
9790 case we ran out of FPR save slots. */
9791 for (j = 6; j <= 15; j++)
9792 if (FP_REGNO_P (cfun_gpr_save_slot (j)))
1d3cea74 9793 cfun_gpr_save_slot (j) = SAVE_SLOT_STACK;
ff4ce128 9794 break;
68bc0408 9795 }
ff4ce128 9796 cfun_gpr_save_slot (i) = save_reg_slot++;
5ada7a14 9797 }
ff4ce128 9798}
5ada7a14 9799
ff4ce128 9800/* Set the bits in fpr_bitmap for FPRs which need to be saved due to
9801 stdarg.
9802 This is a helper routine for s390_register_info. */
1e639cb0 9803
ff4ce128 9804static void
9805s390_register_info_stdarg_fpr ()
9806{
9807 int i;
9808 int min_fpr;
9809 int max_fpr;
9810
9811 /* Save the FP argument regs for stdarg. f0, f2 for 31 bit and
9812 f0-f4 for 64 bit. */
9813 if (!cfun->stdarg
9814 || !TARGET_HARD_FLOAT
9815 || !cfun->va_list_fpr_size
9816 || crtl->args.info.fprs >= FP_ARG_NUM_REG)
9817 return;
9818
9819 min_fpr = crtl->args.info.fprs;
1d3cea74 9820 max_fpr = min_fpr + cfun->va_list_fpr_size - 1;
9821 if (max_fpr >= FP_ARG_NUM_REG)
9822 max_fpr = FP_ARG_NUM_REG - 1;
ff4ce128 9823
1d3cea74 9824 /* FPR argument regs start at f0. */
9825 min_fpr += FPR0_REGNUM;
9826 max_fpr += FPR0_REGNUM;
9827
9828 for (i = min_fpr; i <= max_fpr; i++)
9829 cfun_set_fpr_save (i);
ff4ce128 9830}
9831
9832/* Reserve the GPR save slots for GPRs which need to be saved due to
9833 stdarg.
9834 This is a helper routine for s390_register_info. */
9835
9836static void
9837s390_register_info_stdarg_gpr ()
9838{
9839 int i;
9840 int min_gpr;
9841 int max_gpr;
9842
9843 if (!cfun->stdarg
9844 || !cfun->va_list_gpr_size
9845 || crtl->args.info.gprs >= GP_ARG_NUM_REG)
9846 return;
9847
9848 min_gpr = crtl->args.info.gprs;
1d3cea74 9849 max_gpr = min_gpr + cfun->va_list_gpr_size - 1;
9850 if (max_gpr >= GP_ARG_NUM_REG)
9851 max_gpr = GP_ARG_NUM_REG - 1;
9852
9853 /* GPR argument regs start at r2. */
9854 min_gpr += GPR2_REGNUM;
9855 max_gpr += GPR2_REGNUM;
9856
9857 /* If r6 was supposed to be saved into an FPR and now needs to go to
9858 the stack for vararg we have to adjust the restore range to make
9859 sure that the restore is done from stack as well. */
9860 if (FP_REGNO_P (cfun_gpr_save_slot (GPR6_REGNUM))
9861 && min_gpr <= GPR6_REGNUM
9862 && max_gpr >= GPR6_REGNUM)
9863 {
9864 if (cfun_frame_layout.first_restore_gpr == -1
9865 || cfun_frame_layout.first_restore_gpr > GPR6_REGNUM)
9866 cfun_frame_layout.first_restore_gpr = GPR6_REGNUM;
9867 if (cfun_frame_layout.last_restore_gpr == -1
9868 || cfun_frame_layout.last_restore_gpr < GPR6_REGNUM)
9869 cfun_frame_layout.last_restore_gpr = GPR6_REGNUM;
9870 }
9871
9872 if (cfun_frame_layout.first_save_gpr == -1
9873 || cfun_frame_layout.first_save_gpr > min_gpr)
9874 cfun_frame_layout.first_save_gpr = min_gpr;
9875
9876 if (cfun_frame_layout.last_save_gpr == -1
9877 || cfun_frame_layout.last_save_gpr < max_gpr)
9878 cfun_frame_layout.last_save_gpr = max_gpr;
9879
9880 for (i = min_gpr; i <= max_gpr; i++)
9881 cfun_gpr_save_slot (i) = SAVE_SLOT_STACK;
9882}
9883
9884/* Calculate the save and restore ranges for stm(g) and lm(g) in the
9885 prologue and epilogue. */
ff4ce128 9886
1d3cea74 9887static void
9888s390_register_info_set_ranges ()
9889{
9890 int i, j;
9891
9892 /* Find the first and the last save slot supposed to use the stack
9893 to set the restore range.
9894 Vararg regs might be marked as save to stack but only the
9895 call-saved regs really need restoring (i.e. r6). This code
9896 assumes that the vararg regs have not yet been recorded in
9897 cfun_gpr_save_slot. */
9898 for (i = 0; i < 16 && cfun_gpr_save_slot (i) != SAVE_SLOT_STACK; i++);
9899 for (j = 15; j > i && cfun_gpr_save_slot (j) != SAVE_SLOT_STACK; j--);
9900 cfun_frame_layout.first_restore_gpr = (i == 16) ? -1 : i;
9901 cfun_frame_layout.last_restore_gpr = (i == 16) ? -1 : j;
1d3cea74 9902 cfun_frame_layout.first_save_gpr = (i == 16) ? -1 : i;
9903 cfun_frame_layout.last_save_gpr = (i == 16) ? -1 : j;
ff4ce128 9904}
9905
9906/* The GPR and FPR save slots in cfun->machine->frame_layout are set
9907 for registers which need to be saved in function prologue.
9908 This function can be used until the insns emitted for save/restore
9909 of the regs are visible in the RTL stream. */
9910
9911static void
9912s390_register_info ()
9913{
1d3cea74 9914 int i;
ff4ce128 9915 char clobbered_regs[32];
9916
9917 gcc_assert (!epilogue_completed);
9918
9919 if (reload_completed)
9920 /* After reload we rely on our own routine to determine which
9921 registers need saving. */
9922 s390_regs_ever_clobbered (clobbered_regs);
9923 else
9924 /* During reload we use regs_ever_live as a base since reload
9925 does changes in there which we otherwise would not be aware
9926 of. */
9927 for (i = 0; i < 32; i++)
9928 clobbered_regs[i] = df_regs_ever_live_p (i);
9929
9930 for (i = 0; i < 32; i++)
9931 clobbered_regs[i] = clobbered_regs[i] && !global_regs[i];
9932
9933 /* Mark the call-saved FPRs which need to be saved.
9934 This needs to be done before checking the special GPRs since the
9935 stack pointer usage depends on whether high FPRs have to be saved
9936 or not. */
9937 cfun_frame_layout.fpr_bitmap = 0;
9938 cfun_frame_layout.high_fprs = 0;
9939 for (i = FPR0_REGNUM; i <= FPR15_REGNUM; i++)
9940 if (clobbered_regs[i] && !call_really_used_regs[i])
9941 {
9942 cfun_set_fpr_save (i);
9943 if (i >= FPR8_REGNUM)
9944 cfun_frame_layout.high_fprs++;
9945 }
9a2a66ae 9946
c6d481f7 9947 /* Register 12 is used for GOT address, but also as temp in prologue
9948 for split-stack stdarg functions (unless r14 is available). */
9949 clobbered_regs[12]
9950 |= ((flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM))
9951 || (flag_split_stack && cfun->stdarg
9952 && (crtl->is_leaf || TARGET_TPF_PROFILING
9953 || has_hard_reg_initial_val (Pmode, RETURN_REGNUM))));
4fed3f99 9954
ffead1ca 9955 clobbered_regs[BASE_REGNUM]
77beec48 9956 |= (cfun->machine->base_reg
ff4ce128 9957 && REGNO (cfun->machine->base_reg) == BASE_REGNUM);
4fed3f99 9958
ff4ce128 9959 clobbered_regs[HARD_FRAME_POINTER_REGNUM]
9960 |= !!frame_pointer_needed;
9961
9962 /* On pre z900 machines this might take until machine dependent
9963 reorg to decide.
9964 save_return_addr_p will only be set on non-zarch machines so
9965 there is no risk that r14 goes into an FPR instead of a stack
9966 slot. */
1e639cb0 9967 clobbered_regs[RETURN_REGNUM]
d5bf7b64 9968 |= (!crtl->is_leaf
9bee2845 9969 || TARGET_TPF_PROFILING
77beec48 9970 || cfun->machine->split_branches_pending_p
9971 || cfun_frame_layout.save_return_addr_p
ff4ce128 9972 || crtl->calls_eh_return);
4fed3f99 9973
1e639cb0 9974 clobbered_regs[STACK_POINTER_REGNUM]
d5bf7b64 9975 |= (!crtl->is_leaf
77beec48 9976 || TARGET_TPF_PROFILING
9977 || cfun_save_high_fprs_p
9978 || get_frame_size () > 0
68bc0408 9979 || (reload_completed && cfun_frame_layout.frame_size > 0)
ff4ce128 9980 || cfun->calls_alloca);
9981
1d3cea74 9982 memset (cfun_frame_layout.gpr_save_slots, SAVE_SLOT_NONE, 16);
1e639cb0 9983
beee1f75 9984 for (i = 6; i < 16; i++)
ff4ce128 9985 if (clobbered_regs[i])
1d3cea74 9986 cfun_gpr_save_slot (i) = SAVE_SLOT_STACK;
9a2a66ae 9987
ff4ce128 9988 s390_register_info_stdarg_fpr ();
9989 s390_register_info_gprtofpr ();
1d3cea74 9990 s390_register_info_set_ranges ();
ff4ce128 9991 /* stdarg functions might need to save GPRs 2 to 6. This might
1d3cea74 9992 override the GPR->FPR save decision made by
9993 s390_register_info_gprtofpr for r6 since vararg regs must go to
9994 the stack. */
ff4ce128 9995 s390_register_info_stdarg_gpr ();
ff4ce128 9996}
9a2a66ae 9997
ff4ce128 9998/* This function is called by s390_optimize_prologue in order to get
9999 rid of unnecessary GPR save/restore instructions. The register info
10000 for the GPRs is re-computed and the ranges are re-calculated. */
6902d973 10001
ff4ce128 10002static void
10003s390_optimize_register_info ()
10004{
10005 char clobbered_regs[32];
1d3cea74 10006 int i;
6902d973 10007
ff4ce128 10008 gcc_assert (epilogue_completed);
10009 gcc_assert (!cfun->machine->split_branches_pending_p);
beee1f75 10010
ff4ce128 10011 s390_regs_ever_clobbered (clobbered_regs);
6902d973 10012
ff4ce128 10013 for (i = 0; i < 32; i++)
10014 clobbered_regs[i] = clobbered_regs[i] && !global_regs[i];
6902d973 10015
ff4ce128 10016 /* There is still special treatment needed for cases invisible to
10017 s390_regs_ever_clobbered. */
10018 clobbered_regs[RETURN_REGNUM]
10019 |= (TARGET_TPF_PROFILING
10020 /* When expanding builtin_return_addr in ESA mode we do not
10021 know whether r14 will later be needed as scratch reg when
10022 doing branch splitting. So the builtin always accesses the
10023 r14 save slot and we need to stick to the save/restore
10024 decision for r14 even if it turns out that it didn't get
10025 clobbered. */
10026 || cfun_frame_layout.save_return_addr_p
10027 || crtl->calls_eh_return);
10028
1d3cea74 10029 memset (cfun_frame_layout.gpr_save_slots, SAVE_SLOT_NONE, 6);
ff4ce128 10030
10031 for (i = 6; i < 16; i++)
10032 if (!clobbered_regs[i])
1d3cea74 10033 cfun_gpr_save_slot (i) = SAVE_SLOT_NONE;
ff4ce128 10034
1d3cea74 10035 s390_register_info_set_ranges ();
ff4ce128 10036 s390_register_info_stdarg_gpr ();
67928721 10037}
10038
4fed3f99 10039/* Fill cfun->machine with info about frame of current function. */
67928721 10040
10041static void
4fed3f99 10042s390_frame_info (void)
67928721 10043{
62eb9236 10044 HOST_WIDE_INT lowest_offset;
67928721 10045
ff4ce128 10046 cfun_frame_layout.first_save_gpr_slot = cfun_frame_layout.first_save_gpr;
10047 cfun_frame_layout.last_save_gpr_slot = cfun_frame_layout.last_save_gpr;
10048
10049 /* The va_arg builtin uses a constant distance of 16 *
10050 UNITS_PER_LONG (r0-r15) to reach the FPRs from the reg_save_area
10051 pointer. So even if we are going to save the stack pointer in an
10052 FPR we need the stack space in order to keep the offsets
10053 correct. */
10054 if (cfun->stdarg && cfun_save_arg_fprs_p)
10055 {
10056 cfun_frame_layout.last_save_gpr_slot = STACK_POINTER_REGNUM;
10057
10058 if (cfun_frame_layout.first_save_gpr_slot == -1)
10059 cfun_frame_layout.first_save_gpr_slot = STACK_POINTER_REGNUM;
10060 }
10061
67928721 10062 cfun_frame_layout.frame_size = get_frame_size ();
67928721 10063 if (!TARGET_64BIT && cfun_frame_layout.frame_size > 0x7fff0000)
c05be867 10064 fatal_error (input_location,
10065 "total size of local variables exceeds architecture limit");
ffead1ca 10066
646a946e 10067 if (!TARGET_PACKED_STACK)
67928721 10068 {
62eb9236 10069 /* Fixed stack layout. */
67928721 10070 cfun_frame_layout.backchain_offset = 0;
b5fdc416 10071 cfun_frame_layout.f0_offset = 16 * UNITS_PER_LONG;
67928721 10072 cfun_frame_layout.f4_offset = cfun_frame_layout.f0_offset + 2 * 8;
10073 cfun_frame_layout.f8_offset = -cfun_frame_layout.high_fprs * 8;
5214e6ae 10074 cfun_frame_layout.gprs_offset = (cfun_frame_layout.first_save_gpr_slot
b5fdc416 10075 * UNITS_PER_LONG);
67928721 10076 }
62eb9236 10077 else if (TARGET_BACKCHAIN)
67928721 10078 {
62eb9236 10079 /* Kernel stack layout - packed stack, backchain, no float */
10080 gcc_assert (TARGET_SOFT_FLOAT);
67928721 10081 cfun_frame_layout.backchain_offset = (STACK_POINTER_OFFSET
b5fdc416 10082 - UNITS_PER_LONG);
62eb9236 10083
10084 /* The distance between the backchain and the return address
10085 save slot must not change. So we always need a slot for the
10086 stack pointer which resides in between. */
10087 cfun_frame_layout.last_save_gpr_slot = STACK_POINTER_REGNUM;
10088
ffead1ca 10089 cfun_frame_layout.gprs_offset
62eb9236 10090 = cfun_frame_layout.backchain_offset - cfun_gprs_save_area_size;
ffead1ca 10091
62eb9236 10092 /* FPRs will not be saved. Nevertheless pick sane values to
10093 keep area calculations valid. */
10094 cfun_frame_layout.f0_offset =
10095 cfun_frame_layout.f4_offset =
10096 cfun_frame_layout.f8_offset = cfun_frame_layout.gprs_offset;
67928721 10097 }
62eb9236 10098 else
67928721 10099 {
031bdf83 10100 int num_fprs;
10101
62eb9236 10102 /* Packed stack layout without backchain. */
ffead1ca 10103
031bdf83 10104 /* With stdarg FPRs need their dedicated slots. */
10105 num_fprs = (TARGET_64BIT && cfun->stdarg ? 2
10106 : (cfun_fpr_save_p (FPR4_REGNUM) +
10107 cfun_fpr_save_p (FPR6_REGNUM)));
10108 cfun_frame_layout.f4_offset = STACK_POINTER_OFFSET - 8 * num_fprs;
10109
10110 num_fprs = (cfun->stdarg ? 2
10111 : (cfun_fpr_save_p (FPR0_REGNUM)
10112 + cfun_fpr_save_p (FPR2_REGNUM)));
10113 cfun_frame_layout.f0_offset = cfun_frame_layout.f4_offset - 8 * num_fprs;
ffead1ca 10114
10115 cfun_frame_layout.gprs_offset
67928721 10116 = cfun_frame_layout.f0_offset - cfun_gprs_save_area_size;
62eb9236 10117
10118 cfun_frame_layout.f8_offset = (cfun_frame_layout.gprs_offset
10119 - cfun_frame_layout.high_fprs * 8);
67928721 10120 }
10121
62eb9236 10122 if (cfun_save_high_fprs_p)
10123 cfun_frame_layout.frame_size += cfun_frame_layout.high_fprs * 8;
10124
10125 if (!crtl->is_leaf)
10126 cfun_frame_layout.frame_size += crtl->outgoing_args_size;
10127
10128 /* In the following cases we have to allocate a STACK_POINTER_OFFSET
10129 sized area at the bottom of the stack. This is required also for
10130 leaf functions. When GCC generates a local stack reference it
10131 will always add STACK_POINTER_OFFSET to all these references. */
d5bf7b64 10132 if (crtl->is_leaf
67928721 10133 && !TARGET_TPF_PROFILING
10134 && cfun_frame_layout.frame_size == 0
ff4ce128 10135 && !cfun->calls_alloca)
67928721 10136 return;
10137
62eb9236 10138 /* Calculate the number of bytes we have used in our own register
10139 save area. With the packed stack layout we can re-use the
10140 remaining bytes for normal stack elements. */
67928721 10141
62eb9236 10142 if (TARGET_PACKED_STACK)
10143 lowest_offset = MIN (MIN (cfun_frame_layout.f0_offset,
10144 cfun_frame_layout.f4_offset),
10145 cfun_frame_layout.gprs_offset);
10146 else
10147 lowest_offset = 0;
ffead1ca 10148
62eb9236 10149 if (TARGET_BACKCHAIN)
10150 lowest_offset = MIN (lowest_offset, cfun_frame_layout.backchain_offset);
ffead1ca 10151
62eb9236 10152 cfun_frame_layout.frame_size += STACK_POINTER_OFFSET - lowest_offset;
67928721 10153
62eb9236 10154 /* If under 31 bit an odd number of gprs has to be saved we have to
10155 adjust the frame size to sustain 8 byte alignment of stack
10156 frames. */
10157 cfun_frame_layout.frame_size = ((cfun_frame_layout.frame_size +
10158 STACK_BOUNDARY / BITS_PER_UNIT - 1)
10159 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
8b4a4127 10160}
10161
4fed3f99 10162/* Generate frame layout. Fills in register and frame data for the current
10163 function in cfun->machine. This routine can be called multiple times;
10164 it will re-do the complete frame layout every time. */
8b4a4127 10165
4fed3f99 10166static void
10167s390_init_frame_layout (void)
4673c1a0 10168{
4fed3f99 10169 HOST_WIDE_INT frame_size;
10170 int base_used;
ff4ce128 10171
b85ca4c8 10172 /* After LRA the frame layout is supposed to be read-only and should
10173 not be re-computed. */
10174 if (reload_completed)
10175 return;
beee1f75 10176
4fed3f99 10177 /* On S/390 machines, we may need to perform branch splitting, which
10178 will require both base and return address register. We have no
10179 choice but to assume we're going to need them until right at the
10180 end of the machine dependent reorg phase. */
10181 if (!TARGET_CPU_ZARCH)
10182 cfun->machine->split_branches_pending_p = true;
10183
10184 do
10185 {
10186 frame_size = cfun_frame_layout.frame_size;
10187
10188 /* Try to predict whether we'll need the base register. */
10189 base_used = cfun->machine->split_branches_pending_p
18d50ae6 10190 || crtl->uses_const_pool
3ea2a559 10191 || (!DISP_IN_RANGE (frame_size)
10192 && !CONST_OK_FOR_K (frame_size));
4fed3f99 10193
10194 /* Decide which register to use as literal pool base. In small
10195 leaf functions, try to use an unused call-clobbered register
10196 as base register to avoid save/restore overhead. */
10197 if (!base_used)
10198 cfun->machine->base_reg = NULL_RTX;
4fed3f99 10199 else
fee9fc9f 10200 {
10201 int br = 0;
10202
10203 if (crtl->is_leaf)
10204 /* Prefer r5 (most likely to be free). */
10205 for (br = 5; br >= 2 && df_regs_ever_live_p (br); br--)
10206 ;
10207 cfun->machine->base_reg =
009c4697 10208 gen_rtx_REG (Pmode, (br >= 2) ? br : BASE_REGNUM);
fee9fc9f 10209 }
67928721 10210
ff4ce128 10211 s390_register_info ();
4fed3f99 10212 s390_frame_info ();
10213 }
10214 while (frame_size != cfun_frame_layout.frame_size);
4673c1a0 10215}
10216
5ada7a14 10217/* Remove the FPR clobbers from a tbegin insn if it can be proven that
10218 the TX is nonescaping. A transaction is considered escaping if
10219 there is at least one path from tbegin returning CC0 to the
10220 function exit block without an tend.
10221
10222 The check so far has some limitations:
10223 - only single tbegin/tend BBs are supported
10224 - the first cond jump after tbegin must separate the CC0 path from ~CC0
10225 - when CC is copied to a GPR and the CC0 check is done with the GPR
10226 this is not supported
10227*/
10228
10229static void
10230s390_optimize_nonescaping_tx (void)
10231{
10232 const unsigned int CC0 = 1 << 3;
10233 basic_block tbegin_bb = NULL;
10234 basic_block tend_bb = NULL;
10235 basic_block bb;
93e0956b 10236 rtx_insn *insn;
5ada7a14 10237 bool result = true;
10238 int bb_index;
93e0956b 10239 rtx_insn *tbegin_insn = NULL;
5ada7a14 10240
10241 if (!cfun->machine->tbegin_p)
10242 return;
10243
a28770e1 10244 for (bb_index = 0; bb_index < n_basic_blocks_for_fn (cfun); bb_index++)
5ada7a14 10245 {
f5a6b05f 10246 bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
5ada7a14 10247
91dfd73e 10248 if (!bb)
10249 continue;
10250
5ada7a14 10251 FOR_BB_INSNS (bb, insn)
10252 {
10253 rtx ite, cc, pat, target;
10254 unsigned HOST_WIDE_INT mask;
10255
10256 if (!INSN_P (insn) || INSN_CODE (insn) <= 0)
10257 continue;
10258
10259 pat = PATTERN (insn);
10260
10261 if (GET_CODE (pat) == PARALLEL)
10262 pat = XVECEXP (pat, 0, 0);
10263
10264 if (GET_CODE (pat) != SET
10265 || GET_CODE (SET_SRC (pat)) != UNSPEC_VOLATILE)
10266 continue;
10267
10268 if (XINT (SET_SRC (pat), 1) == UNSPECV_TBEGIN)
10269 {
91a55c11 10270 rtx_insn *tmp;
5ada7a14 10271
10272 tbegin_insn = insn;
10273
10274 /* Just return if the tbegin doesn't have clobbers. */
10275 if (GET_CODE (PATTERN (insn)) != PARALLEL)
10276 return;
10277
10278 if (tbegin_bb != NULL)
10279 return;
10280
10281 /* Find the next conditional jump. */
10282 for (tmp = NEXT_INSN (insn);
10283 tmp != NULL_RTX;
10284 tmp = NEXT_INSN (tmp))
10285 {
10286 if (reg_set_p (gen_rtx_REG (CCmode, CC_REGNUM), tmp))
10287 return;
10288 if (!JUMP_P (tmp))
10289 continue;
10290
10291 ite = SET_SRC (PATTERN (tmp));
10292 if (GET_CODE (ite) != IF_THEN_ELSE)
10293 continue;
10294
10295 cc = XEXP (XEXP (ite, 0), 0);
10296 if (!REG_P (cc) || !CC_REGNO_P (REGNO (cc))
10297 || GET_MODE (cc) != CCRAWmode
10298 || GET_CODE (XEXP (XEXP (ite, 0), 1)) != CONST_INT)
10299 return;
10300
10301 if (bb->succs->length () != 2)
10302 return;
10303
10304 mask = INTVAL (XEXP (XEXP (ite, 0), 1));
10305 if (GET_CODE (XEXP (ite, 0)) == NE)
10306 mask ^= 0xf;
10307
10308 if (mask == CC0)
10309 target = XEXP (ite, 1);
10310 else if (mask == (CC0 ^ 0xf))
10311 target = XEXP (ite, 2);
10312 else
10313 return;
10314
10315 {
10316 edge_iterator ei;
10317 edge e1, e2;
10318
10319 ei = ei_start (bb->succs);
10320 e1 = ei_safe_edge (ei);
10321 ei_next (&ei);
10322 e2 = ei_safe_edge (ei);
10323
10324 if (e2->flags & EDGE_FALLTHRU)
10325 {
10326 e2 = e1;
10327 e1 = ei_safe_edge (ei);
10328 }
10329
10330 if (!(e1->flags & EDGE_FALLTHRU))
10331 return;
10332
10333 tbegin_bb = (target == pc_rtx) ? e1->dest : e2->dest;
10334 }
10335 if (tmp == BB_END (bb))
10336 break;
10337 }
10338 }
10339
10340 if (XINT (SET_SRC (pat), 1) == UNSPECV_TEND)
10341 {
10342 if (tend_bb != NULL)
10343 return;
10344 tend_bb = bb;
10345 }
10346 }
10347 }
10348
10349 /* Either we successfully remove the FPR clobbers here or we are not
10350 able to do anything for this TX. Both cases don't qualify for
10351 another look. */
10352 cfun->machine->tbegin_p = false;
10353
10354 if (tbegin_bb == NULL || tend_bb == NULL)
10355 return;
10356
10357 calculate_dominance_info (CDI_POST_DOMINATORS);
10358 result = dominated_by_p (CDI_POST_DOMINATORS, tbegin_bb, tend_bb);
10359 free_dominance_info (CDI_POST_DOMINATORS);
10360
10361 if (!result)
10362 return;
10363
91dfd73e 10364 PATTERN (tbegin_insn) = gen_rtx_PARALLEL (VOIDmode,
10365 gen_rtvec (2,
10366 XVECEXP (PATTERN (tbegin_insn), 0, 0),
10367 XVECEXP (PATTERN (tbegin_insn), 0, 1)));
5ada7a14 10368 INSN_CODE (tbegin_insn) = -1;
10369 df_insn_rescan (tbegin_insn);
10370
10371 return;
10372}
10373
8f1128bb 10374/* Return true if it is legal to put a value with MODE into REGNO. */
10375
10376bool
3754d046 10377s390_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
8f1128bb 10378{
76a4c804 10379 if (!TARGET_VX && VECTOR_NOFP_REGNO_P (regno))
10380 return false;
10381
8f1128bb 10382 switch (REGNO_REG_CLASS (regno))
10383 {
76a4c804 10384 case VEC_REGS:
10385 return ((GET_MODE_CLASS (mode) == MODE_INT
10386 && s390_class_max_nregs (VEC_REGS, mode) == 1)
10387 || mode == DFmode
80912819 10388 || (TARGET_VXE && mode == SFmode)
76a4c804 10389 || s390_vector_mode_supported_p (mode));
10390 break;
8f1128bb 10391 case FP_REGS:
76a4c804 10392 if (TARGET_VX
10393 && ((GET_MODE_CLASS (mode) == MODE_INT
10394 && s390_class_max_nregs (FP_REGS, mode) == 1)
10395 || mode == DFmode
10396 || s390_vector_mode_supported_p (mode)))
10397 return true;
10398
8f1128bb 10399 if (REGNO_PAIR_OK (regno, mode))
10400 {
10401 if (mode == SImode || mode == DImode)
10402 return true;
10403
10404 if (FLOAT_MODE_P (mode) && GET_MODE_CLASS (mode) != MODE_VECTOR_FLOAT)
10405 return true;
10406 }
10407 break;
10408 case ADDR_REGS:
10409 if (FRAME_REGNO_P (regno) && mode == Pmode)
10410 return true;
10411
10412 /* fallthrough */
10413 case GENERAL_REGS:
10414 if (REGNO_PAIR_OK (regno, mode))
10415 {
b5fdc416 10416 if (TARGET_ZARCH
36868490 10417 || (mode != TFmode && mode != TCmode && mode != TDmode))
8f1128bb 10418 return true;
ffead1ca 10419 }
8f1128bb 10420 break;
10421 case CC_REGS:
10422 if (GET_MODE_CLASS (mode) == MODE_CC)
10423 return true;
10424 break;
10425 case ACCESS_REGS:
10426 if (REGNO_PAIR_OK (regno, mode))
10427 {
10428 if (mode == SImode || mode == Pmode)
10429 return true;
10430 }
10431 break;
10432 default:
10433 return false;
10434 }
ffead1ca 10435
8f1128bb 10436 return false;
10437}
10438
d1a5573e 10439/* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
10440
10441bool
10442s390_hard_regno_rename_ok (unsigned int old_reg, unsigned int new_reg)
10443{
10444 /* Once we've decided upon a register to use as base register, it must
10445 no longer be used for any other purpose. */
10446 if (cfun->machine->base_reg)
10447 if (REGNO (cfun->machine->base_reg) == old_reg
10448 || REGNO (cfun->machine->base_reg) == new_reg)
10449 return false;
10450
ff4ce128 10451 /* Prevent regrename from using call-saved regs which haven't
10452 actually been saved. This is necessary since regrename assumes
10453 the backend save/restore decisions are based on
10454 df_regs_ever_live. Since we have our own routine we have to tell
10455 regrename manually about it. */
10456 if (GENERAL_REGNO_P (new_reg)
10457 && !call_really_used_regs[new_reg]
1d3cea74 10458 && cfun_gpr_save_slot (new_reg) == SAVE_SLOT_NONE)
ff4ce128 10459 return false;
10460
10461 return true;
10462}
10463
10464/* Return nonzero if register REGNO can be used as a scratch register
10465 in peephole2. */
10466
10467static bool
10468s390_hard_regno_scratch_ok (unsigned int regno)
10469{
10470 /* See s390_hard_regno_rename_ok. */
10471 if (GENERAL_REGNO_P (regno)
10472 && !call_really_used_regs[regno]
1d3cea74 10473 && cfun_gpr_save_slot (regno) == SAVE_SLOT_NONE)
ff4ce128 10474 return false;
10475
d1a5573e 10476 return true;
10477}
10478
8f1128bb 10479/* Maximum number of registers to represent a value of mode MODE
8deb3959 10480 in a register of class RCLASS. */
8f1128bb 10481
6c2d82ab 10482int
3754d046 10483s390_class_max_nregs (enum reg_class rclass, machine_mode mode)
8f1128bb 10484{
76a4c804 10485 int reg_size;
10486 bool reg_pair_required_p = false;
10487
8deb3959 10488 switch (rclass)
8f1128bb 10489 {
10490 case FP_REGS:
76a4c804 10491 case VEC_REGS:
10492 reg_size = TARGET_VX ? 16 : 8;
10493
10494 /* TF and TD modes would fit into a VR but we put them into a
10495 register pair since we do not have 128bit FP instructions on
10496 full VRs. */
10497 if (TARGET_VX
10498 && SCALAR_FLOAT_MODE_P (mode)
10499 && GET_MODE_SIZE (mode) >= 16)
10500 reg_pair_required_p = true;
10501
10502 /* Even if complex types would fit into a single FPR/VR we force
10503 them into a register pair to deal with the parts more easily.
10504 (FIXME: What about complex ints?) */
8f1128bb 10505 if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
76a4c804 10506 reg_pair_required_p = true;
10507 break;
8f1128bb 10508 case ACCESS_REGS:
76a4c804 10509 reg_size = 4;
10510 break;
8f1128bb 10511 default:
76a4c804 10512 reg_size = UNITS_PER_WORD;
8f1128bb 10513 break;
10514 }
76a4c804 10515
10516 if (reg_pair_required_p)
10517 return 2 * ((GET_MODE_SIZE (mode) / 2 + reg_size - 1) / reg_size);
10518
10519 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
10520}
10521
10522/* Return TRUE if changing mode from FROM to TO should not be allowed
10523 for register class CLASS. */
10524
10525int
10526s390_cannot_change_mode_class (machine_mode from_mode,
10527 machine_mode to_mode,
10528 enum reg_class rclass)
10529{
10530 machine_mode small_mode;
10531 machine_mode big_mode;
10532
80912819 10533 /* V1TF and TF have different representations in vector
10534 registers. */
10535 if (reg_classes_intersect_p (VEC_REGS, rclass)
10536 && ((from_mode == V1TFmode && to_mode == TFmode)
10537 || (from_mode == TFmode && to_mode == V1TFmode)))
10538 return 1;
10539
76a4c804 10540 if (GET_MODE_SIZE (from_mode) == GET_MODE_SIZE (to_mode))
10541 return 0;
10542
10543 if (GET_MODE_SIZE (from_mode) < GET_MODE_SIZE (to_mode))
10544 {
10545 small_mode = from_mode;
10546 big_mode = to_mode;
10547 }
10548 else
10549 {
10550 small_mode = to_mode;
10551 big_mode = from_mode;
10552 }
10553
10554 /* Values residing in VRs are little-endian style. All modes are
10555 placed left-aligned in an VR. This means that we cannot allow
10556 switching between modes with differing sizes. Also if the vector
10557 facility is available we still place TFmode values in VR register
10558 pairs, since the only instructions we have operating on TFmodes
10559 only deal with register pairs. Therefore we have to allow DFmode
10560 subregs of TFmodes to enable the TFmode splitters. */
10561 if (reg_classes_intersect_p (VEC_REGS, rclass)
10562 && (GET_MODE_SIZE (small_mode) < 8
10563 || s390_class_max_nregs (VEC_REGS, big_mode) == 1))
10564 return 1;
10565
10566 /* Likewise for access registers, since they have only half the
10567 word size on 64-bit. */
10568 if (reg_classes_intersect_p (ACCESS_REGS, rclass))
10569 return 1;
10570
10571 return 0;
8f1128bb 10572}
10573
7b1bda1c 10574/* Return true if we use LRA instead of reload pass. */
10575static bool
10576s390_lra_p (void)
10577{
10578 return s390_lra_flag;
10579}
10580
4fed3f99 10581/* Return true if register FROM can be eliminated via register TO. */
10582
cd90919d 10583static bool
10584s390_can_eliminate (const int from, const int to)
4fed3f99 10585{
d1a5573e 10586 /* On zSeries machines, we have not marked the base register as fixed.
10587 Instead, we have an elimination rule BASE_REGNUM -> BASE_REGNUM.
10588 If a function requires the base register, we say here that this
10589 elimination cannot be performed. This will cause reload to free
10590 up the base register (as if it were fixed). On the other hand,
10591 if the current function does *not* require the base register, we
10592 say here the elimination succeeds, which in turn allows reload
10593 to allocate the base register for any other purpose. */
10594 if (from == BASE_REGNUM && to == BASE_REGNUM)
10595 {
10596 if (TARGET_CPU_ZARCH)
10597 {
10598 s390_init_frame_layout ();
10599 return cfun->machine->base_reg == NULL_RTX;
10600 }
10601
10602 return false;
10603 }
10604
10605 /* Everything else must point into the stack frame. */
4fed3f99 10606 gcc_assert (to == STACK_POINTER_REGNUM
10607 || to == HARD_FRAME_POINTER_REGNUM);
10608
10609 gcc_assert (from == FRAME_POINTER_REGNUM
10610 || from == ARG_POINTER_REGNUM
10611 || from == RETURN_ADDRESS_POINTER_REGNUM);
10612
10613 /* Make sure we actually saved the return address. */
10614 if (from == RETURN_ADDRESS_POINTER_REGNUM)
18d50ae6 10615 if (!crtl->calls_eh_return
10616 && !cfun->stdarg
4fed3f99 10617 && !cfun_frame_layout.save_return_addr_p)
10618 return false;
10619
10620 return true;
10621}
10622
10623/* Return offset between register FROM and TO initially after prolog. */
7cbfc974 10624
10625HOST_WIDE_INT
4fed3f99 10626s390_initial_elimination_offset (int from, int to)
7cbfc974 10627{
4fed3f99 10628 HOST_WIDE_INT offset;
7cbfc974 10629
4fed3f99 10630 /* ??? Why are we called for non-eliminable pairs? */
10631 if (!s390_can_eliminate (from, to))
10632 return 0;
10633
10634 switch (from)
10635 {
10636 case FRAME_POINTER_REGNUM:
ffead1ca 10637 offset = (get_frame_size()
119114cb 10638 + STACK_POINTER_OFFSET
abe32cce 10639 + crtl->outgoing_args_size);
4fed3f99 10640 break;
67928721 10641
4fed3f99 10642 case ARG_POINTER_REGNUM:
10643 s390_init_frame_layout ();
10644 offset = cfun_frame_layout.frame_size + STACK_POINTER_OFFSET;
10645 break;
10646
10647 case RETURN_ADDRESS_POINTER_REGNUM:
10648 s390_init_frame_layout ();
ff4ce128 10649
10650 if (cfun_frame_layout.first_save_gpr_slot == -1)
10651 {
10652 /* If it turns out that for stdarg nothing went into the reg
10653 save area we also do not need the return address
10654 pointer. */
10655 if (cfun->stdarg && !cfun_save_arg_fprs_p)
10656 return 0;
10657
10658 gcc_unreachable ();
10659 }
10660
10661 /* In order to make the following work it is not necessary for
10662 r14 to have a save slot. It is sufficient if one other GPR
10663 got one. Since the GPRs are always stored without gaps we
10664 are able to calculate where the r14 save slot would
10665 reside. */
10666 offset = (cfun_frame_layout.frame_size + cfun_frame_layout.gprs_offset +
10667 (RETURN_REGNUM - cfun_frame_layout.first_save_gpr_slot) *
10668 UNITS_PER_LONG);
4fed3f99 10669 break;
10670
d1a5573e 10671 case BASE_REGNUM:
10672 offset = 0;
10673 break;
10674
4fed3f99 10675 default:
10676 gcc_unreachable ();
10677 }
10678
10679 return offset;
7cbfc974 10680}
10681
8b4a4127 10682/* Emit insn to save fpr REGNUM at offset OFFSET relative
f81e845f 10683 to register BASE. Return generated insn. */
56769981 10684
4673c1a0 10685static rtx
b40da9a7 10686save_fpr (rtx base, int offset, int regnum)
4673c1a0 10687{
8b4a4127 10688 rtx addr;
29c05e22 10689 addr = gen_rtx_MEM (DFmode, plus_constant (Pmode, base, offset));
ce1d5a67 10690
10691 if (regnum >= 16 && regnum <= (16 + FP_ARG_NUM_REG))
10692 set_mem_alias_set (addr, get_varargs_alias_set ());
10693 else
10694 set_mem_alias_set (addr, get_frame_alias_set ());
4673c1a0 10695
8b4a4127 10696 return emit_move_insn (addr, gen_rtx_REG (DFmode, regnum));
10697}
4673c1a0 10698
8b4a4127 10699/* Emit insn to restore fpr REGNUM from offset OFFSET relative
f81e845f 10700 to register BASE. Return generated insn. */
4673c1a0 10701
8b4a4127 10702static rtx
b40da9a7 10703restore_fpr (rtx base, int offset, int regnum)
8b4a4127 10704{
10705 rtx addr;
29c05e22 10706 addr = gen_rtx_MEM (DFmode, plus_constant (Pmode, base, offset));
ce1d5a67 10707 set_mem_alias_set (addr, get_frame_alias_set ());
4673c1a0 10708
8b4a4127 10709 return emit_move_insn (gen_rtx_REG (DFmode, regnum), addr);
4673c1a0 10710}
10711
a3cd0f6a 10712/* Return true if REGNO is a global register, but not one
10713 of the special ones that need to be saved/restored in anyway. */
10714
10715static inline bool
10716global_not_special_regno_p (int regno)
10717{
10718 return (global_regs[regno]
10719 /* These registers are special and need to be
10720 restored in any case. */
10721 && !(regno == STACK_POINTER_REGNUM
10722 || regno == RETURN_REGNUM
10723 || regno == BASE_REGNUM
10724 || (flag_pic && regno == (int)PIC_OFFSET_TABLE_REGNUM)));
10725}
10726
9a2a66ae 10727/* Generate insn to save registers FIRST to LAST into
f81e845f 10728 the register save area located at offset OFFSET
9a2a66ae 10729 relative to register BASE. */
4673c1a0 10730
9a2a66ae 10731static rtx
b40da9a7 10732save_gprs (rtx base, int offset, int first, int last)
4673c1a0 10733{
9a2a66ae 10734 rtx addr, insn, note;
10735 int i;
10736
29c05e22 10737 addr = plus_constant (Pmode, base, offset);
9a2a66ae 10738 addr = gen_rtx_MEM (Pmode, addr);
ce1d5a67 10739
10740 set_mem_alias_set (addr, get_frame_alias_set ());
9a2a66ae 10741
10742 /* Special-case single register. */
10743 if (first == last)
10744 {
10745 if (TARGET_64BIT)
10746 insn = gen_movdi (addr, gen_rtx_REG (Pmode, first));
10747 else
10748 insn = gen_movsi (addr, gen_rtx_REG (Pmode, first));
10749
a3cd0f6a 10750 if (!global_not_special_regno_p (first))
10751 RTX_FRAME_RELATED_P (insn) = 1;
9a2a66ae 10752 return insn;
10753 }
10754
10755
10756 insn = gen_store_multiple (addr,
10757 gen_rtx_REG (Pmode, first),
10758 GEN_INT (last - first + 1));
10759
18d50ae6 10760 if (first <= 6 && cfun->stdarg)
ce1d5a67 10761 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
10762 {
10763 rtx mem = XEXP (XVECEXP (PATTERN (insn), 0, i), 0);
ffead1ca 10764
ce1d5a67 10765 if (first + i <= 6)
10766 set_mem_alias_set (mem, get_varargs_alias_set ());
10767 }
9a2a66ae 10768
10769 /* We need to set the FRAME_RELATED flag on all SETs
10770 inside the store-multiple pattern.
10771
10772 However, we must not emit DWARF records for registers 2..5
f81e845f 10773 if they are stored for use by variable arguments ...
9a2a66ae 10774
3ce7ff97 10775 ??? Unfortunately, it is not enough to simply not the
9a2a66ae 10776 FRAME_RELATED flags for those SETs, because the first SET
10777 of the PARALLEL is always treated as if it had the flag
10778 set, even if it does not. Therefore we emit a new pattern
10779 without those registers as REG_FRAME_RELATED_EXPR note. */
10780
a3cd0f6a 10781 if (first >= 6 && !global_not_special_regno_p (first))
9a2a66ae 10782 {
10783 rtx pat = PATTERN (insn);
10784
10785 for (i = 0; i < XVECLEN (pat, 0); i++)
a3cd0f6a 10786 if (GET_CODE (XVECEXP (pat, 0, i)) == SET
10787 && !global_not_special_regno_p (REGNO (SET_SRC (XVECEXP (pat,
10788 0, i)))))
9a2a66ae 10789 RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1;
10790
10791 RTX_FRAME_RELATED_P (insn) = 1;
10792 }
10793 else if (last >= 6)
10794 {
a3cd0f6a 10795 int start;
10796
10797 for (start = first >= 6 ? first : 6; start <= last; start++)
10798 if (!global_not_special_regno_p (start))
10799 break;
10800
10801 if (start > last)
10802 return insn;
10803
29c05e22 10804 addr = plus_constant (Pmode, base,
10805 offset + (start - first) * UNITS_PER_LONG);
ff4ce128 10806
10807 if (start == last)
10808 {
10809 if (TARGET_64BIT)
10810 note = gen_movdi (gen_rtx_MEM (Pmode, addr),
10811 gen_rtx_REG (Pmode, start));
10812 else
10813 note = gen_movsi (gen_rtx_MEM (Pmode, addr),
10814 gen_rtx_REG (Pmode, start));
10815 note = PATTERN (note);
10816
10817 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
10818 RTX_FRAME_RELATED_P (insn) = 1;
10819
10820 return insn;
10821 }
10822
f81e845f 10823 note = gen_store_multiple (gen_rtx_MEM (Pmode, addr),
a3cd0f6a 10824 gen_rtx_REG (Pmode, start),
10825 GEN_INT (last - start + 1));
9a2a66ae 10826 note = PATTERN (note);
10827
b9c74b4d 10828 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
9a2a66ae 10829
10830 for (i = 0; i < XVECLEN (note, 0); i++)
a3cd0f6a 10831 if (GET_CODE (XVECEXP (note, 0, i)) == SET
10832 && !global_not_special_regno_p (REGNO (SET_SRC (XVECEXP (note,
10833 0, i)))))
9a2a66ae 10834 RTX_FRAME_RELATED_P (XVECEXP (note, 0, i)) = 1;
10835
10836 RTX_FRAME_RELATED_P (insn) = 1;
10837 }
10838
10839 return insn;
8b4a4127 10840}
4673c1a0 10841
9a2a66ae 10842/* Generate insn to restore registers FIRST to LAST from
f81e845f 10843 the register save area located at offset OFFSET
9a2a66ae 10844 relative to register BASE. */
4673c1a0 10845
9a2a66ae 10846static rtx
b40da9a7 10847restore_gprs (rtx base, int offset, int first, int last)
8b4a4127 10848{
9a2a66ae 10849 rtx addr, insn;
10850
29c05e22 10851 addr = plus_constant (Pmode, base, offset);
9a2a66ae 10852 addr = gen_rtx_MEM (Pmode, addr);
ce1d5a67 10853 set_mem_alias_set (addr, get_frame_alias_set ());
9a2a66ae 10854
10855 /* Special-case single register. */
10856 if (first == last)
10857 {
10858 if (TARGET_64BIT)
10859 insn = gen_movdi (gen_rtx_REG (Pmode, first), addr);
10860 else
10861 insn = gen_movsi (gen_rtx_REG (Pmode, first), addr);
10862
ff4ce128 10863 RTX_FRAME_RELATED_P (insn) = 1;
9a2a66ae 10864 return insn;
10865 }
10866
10867 insn = gen_load_multiple (gen_rtx_REG (Pmode, first),
10868 addr,
10869 GEN_INT (last - first + 1));
ff4ce128 10870 RTX_FRAME_RELATED_P (insn) = 1;
9a2a66ae 10871 return insn;
8b4a4127 10872}
4673c1a0 10873
20074f87 10874/* Return insn sequence to load the GOT register. */
12ef3745 10875
93e0956b 10876rtx_insn *
20074f87 10877s390_load_got (void)
12ef3745 10878{
93e0956b 10879 rtx_insn *insns;
20074f87 10880
c60a7572 10881 /* We cannot use pic_offset_table_rtx here since we use this
10882 function also for non-pic if __tls_get_offset is called and in
10883 that case PIC_OFFSET_TABLE_REGNUM as well as pic_offset_table_rtx
10884 aren't usable. */
10885 rtx got_rtx = gen_rtx_REG (Pmode, 12);
10886
20074f87 10887 start_sequence ();
10888
dafc8d45 10889 if (TARGET_CPU_ZARCH)
12ef3745 10890 {
9852c8ae 10891 emit_move_insn (got_rtx, s390_got_symbol ());
12ef3745 10892 }
10893 else
10894 {
20074f87 10895 rtx offset;
12ef3745 10896
9852c8ae 10897 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, s390_got_symbol ()),
12ef3745 10898 UNSPEC_LTREL_OFFSET);
10899 offset = gen_rtx_CONST (Pmode, offset);
10900 offset = force_const_mem (Pmode, offset);
10901
c60a7572 10902 emit_move_insn (got_rtx, offset);
12ef3745 10903
f81e845f 10904 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (offset, 0)),
12ef3745 10905 UNSPEC_LTREL_BASE);
c60a7572 10906 offset = gen_rtx_PLUS (Pmode, got_rtx, offset);
12ef3745 10907
c60a7572 10908 emit_move_insn (got_rtx, offset);
12ef3745 10909 }
20074f87 10910
10911 insns = get_insns ();
10912 end_sequence ();
10913 return insns;
12ef3745 10914}
10915
062c49fd 10916/* This ties together stack memory (MEM with an alias set of frame_alias_set)
10917 and the change to the stack pointer. */
10918
10919static void
10920s390_emit_stack_tie (void)
10921{
10922 rtx mem = gen_frame_mem (BLKmode,
10923 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
10924
10925 emit_insn (gen_stack_tie (mem));
10926}
10927
ff4ce128 10928/* Copy GPRS into FPR save slots. */
10929
10930static void
10931s390_save_gprs_to_fprs (void)
10932{
10933 int i;
10934
10935 if (!TARGET_Z10 || !TARGET_HARD_FLOAT || !crtl->is_leaf)
10936 return;
10937
10938 for (i = 6; i < 16; i++)
10939 {
10940 if (FP_REGNO_P (cfun_gpr_save_slot (i)))
10941 {
93e0956b 10942 rtx_insn *insn =
ff4ce128 10943 emit_move_insn (gen_rtx_REG (DImode, cfun_gpr_save_slot (i)),
10944 gen_rtx_REG (DImode, i));
10945 RTX_FRAME_RELATED_P (insn) = 1;
c5dad799 10946 /* This prevents dwarf2cfi from interpreting the set. Doing
10947 so it might emit def_cfa_register infos setting an FPR as
10948 new CFA. */
9e165059 10949 add_reg_note (insn, REG_CFA_REGISTER, copy_rtx (PATTERN (insn)));
ff4ce128 10950 }
10951 }
10952}
10953
10954/* Restore GPRs from FPR save slots. */
10955
10956static void
10957s390_restore_gprs_from_fprs (void)
10958{
10959 int i;
10960
10961 if (!TARGET_Z10 || !TARGET_HARD_FLOAT || !crtl->is_leaf)
10962 return;
10963
10964 for (i = 6; i < 16; i++)
10965 {
54530437 10966 rtx_insn *insn;
10967
10968 if (!FP_REGNO_P (cfun_gpr_save_slot (i)))
10969 continue;
10970
10971 rtx fpr = gen_rtx_REG (DImode, cfun_gpr_save_slot (i));
10972
10973 if (i == STACK_POINTER_REGNUM)
10974 insn = emit_insn (gen_stack_restore_from_fpr (fpr));
10975 else
10976 insn = emit_move_insn (gen_rtx_REG (DImode, i), fpr);
10977
10978 df_set_regs_ever_live (i, true);
10979 add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (DImode, i));
10980 if (i == STACK_POINTER_REGNUM)
10981 add_reg_note (insn, REG_CFA_DEF_CFA,
10982 plus_constant (Pmode, stack_pointer_rtx,
10983 STACK_POINTER_OFFSET));
10984 RTX_FRAME_RELATED_P (insn) = 1;
ff4ce128 10985 }
10986}
10987
4673c1a0 10988
0b8be04c 10989/* A pass run immediately before shrink-wrapping and prologue and epilogue
10990 generation. */
10991
0b8be04c 10992namespace {
10993
10994const pass_data pass_data_s390_early_mach =
10995{
10996 RTL_PASS, /* type */
10997 "early_mach", /* name */
10998 OPTGROUP_NONE, /* optinfo_flags */
0b8be04c 10999 TV_MACH_DEP, /* tv_id */
11000 0, /* properties_required */
11001 0, /* properties_provided */
11002 0, /* properties_destroyed */
11003 0, /* todo_flags_start */
8b88439e 11004 ( TODO_df_verify | TODO_df_finish ), /* todo_flags_finish */
0b8be04c 11005};
20074f87 11006
0b8be04c 11007class pass_s390_early_mach : public rtl_opt_pass
11008{
11009public:
11010 pass_s390_early_mach (gcc::context *ctxt)
11011 : rtl_opt_pass (pass_data_s390_early_mach, ctxt)
11012 {}
11013
11014 /* opt_pass methods: */
65b0537f 11015 virtual unsigned int execute (function *);
0b8be04c 11016
11017}; // class pass_s390_early_mach
11018
65b0537f 11019unsigned int
11020pass_s390_early_mach::execute (function *fun)
11021{
93e0956b 11022 rtx_insn *insn;
65b0537f 11023
11024 /* Try to get rid of the FPR clobbers. */
11025 s390_optimize_nonescaping_tx ();
11026
11027 /* Re-compute register info. */
11028 s390_register_info ();
11029
11030 /* If we're using a base register, ensure that it is always valid for
11031 the first non-prologue instruction. */
11032 if (fun->machine->base_reg)
11033 emit_insn_at_entry (gen_main_pool (fun->machine->base_reg));
11034
11035 /* Annotate all constant pool references to let the scheduler know
11036 they implicitly use the base register. */
11037 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
11038 if (INSN_P (insn))
11039 {
11040 annotate_constant_pool_refs (&PATTERN (insn));
11041 df_insn_rescan (insn);
11042 }
11043 return 0;
11044}
11045
0b8be04c 11046} // anon namespace
11047
11048/* Expand the prologue into a bunch of separate insns. */
11049
11050void
11051s390_emit_prologue (void)
11052{
11053 rtx insn, addr;
11054 rtx temp_reg;
11055 int i;
11056 int offset;
11057 int next_fpr = 0;
20074f87 11058
f81e845f 11059 /* Choose best register to use for temp use within prologue.
c6d481f7 11060 TPF with profiling must avoid the register 14 - the tracing function
11061 needs the original contents of r14 to be preserved. */
f81e845f 11062
ffead1ca 11063 if (!has_hard_reg_initial_val (Pmode, RETURN_REGNUM)
d5bf7b64 11064 && !crtl->is_leaf
1e639cb0 11065 && !TARGET_TPF_PROFILING)
8b4a4127 11066 temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
c6d481f7 11067 else if (flag_split_stack && cfun->stdarg)
11068 temp_reg = gen_rtx_REG (Pmode, 12);
4673c1a0 11069 else
8b4a4127 11070 temp_reg = gen_rtx_REG (Pmode, 1);
4673c1a0 11071
ff4ce128 11072 s390_save_gprs_to_fprs ();
11073
8b4a4127 11074 /* Save call saved gprs. */
67928721 11075 if (cfun_frame_layout.first_save_gpr != -1)
4ac7fd98 11076 {
ffead1ca 11077 insn = save_gprs (stack_pointer_rtx,
11078 cfun_frame_layout.gprs_offset +
b5fdc416 11079 UNITS_PER_LONG * (cfun_frame_layout.first_save_gpr
5214e6ae 11080 - cfun_frame_layout.first_save_gpr_slot),
ffead1ca 11081 cfun_frame_layout.first_save_gpr,
4ac7fd98 11082 cfun_frame_layout.last_save_gpr);
11083 emit_insn (insn);
11084 }
8b4a4127 11085
c2c1332a 11086 /* Dummy insn to mark literal pool slot. */
f81e845f 11087
4fed3f99 11088 if (cfun->machine->base_reg)
11089 emit_insn (gen_main_pool (cfun->machine->base_reg));
f81e845f 11090
67928721 11091 offset = cfun_frame_layout.f0_offset;
8b4a4127 11092
67928721 11093 /* Save f0 and f2. */
6a2469fe 11094 for (i = FPR0_REGNUM; i <= FPR0_REGNUM + 1; i++)
67928721 11095 {
29439367 11096 if (cfun_fpr_save_p (i))
67928721 11097 {
29439367 11098 save_fpr (stack_pointer_rtx, offset, i);
67928721 11099 offset += 8;
11100 }
031bdf83 11101 else if (!TARGET_PACKED_STACK || cfun->stdarg)
11102 offset += 8;
67928721 11103 }
4673c1a0 11104
67928721 11105 /* Save f4 and f6. */
11106 offset = cfun_frame_layout.f4_offset;
6a2469fe 11107 for (i = FPR4_REGNUM; i <= FPR4_REGNUM + 1; i++)
67928721 11108 {
29439367 11109 if (cfun_fpr_save_p (i))
8b4a4127 11110 {
29439367 11111 insn = save_fpr (stack_pointer_rtx, offset, i);
67928721 11112 offset += 8;
11113
031bdf83 11114 /* If f4 and f6 are call clobbered they are saved due to
11115 stdargs and therefore are not frame related. */
29439367 11116 if (!call_really_used_regs[i])
67928721 11117 RTX_FRAME_RELATED_P (insn) = 1;
8b4a4127 11118 }
031bdf83 11119 else if (!TARGET_PACKED_STACK || call_really_used_regs[i])
67928721 11120 offset += 8;
11121 }
11122
646a946e 11123 if (TARGET_PACKED_STACK
67928721 11124 && cfun_save_high_fprs_p
11125 && cfun_frame_layout.f8_offset + cfun_frame_layout.high_fprs * 8 > 0)
11126 {
11127 offset = (cfun_frame_layout.f8_offset
11128 + (cfun_frame_layout.high_fprs - 1) * 8);
11129
6a2469fe 11130 for (i = FPR15_REGNUM; i >= FPR8_REGNUM && offset >= 0; i--)
29439367 11131 if (cfun_fpr_save_p (i))
67928721 11132 {
29439367 11133 insn = save_fpr (stack_pointer_rtx, offset, i);
ffead1ca 11134
67928721 11135 RTX_FRAME_RELATED_P (insn) = 1;
11136 offset -= 8;
11137 }
11138 if (offset >= cfun_frame_layout.f8_offset)
29439367 11139 next_fpr = i;
67928721 11140 }
ffead1ca 11141
646a946e 11142 if (!TARGET_PACKED_STACK)
6a2469fe 11143 next_fpr = cfun_save_high_fprs_p ? FPR15_REGNUM : 0;
4673c1a0 11144
8c0dd614 11145 if (flag_stack_usage_info)
7810b579 11146 current_function_static_stack_size = cfun_frame_layout.frame_size;
11147
8b4a4127 11148 /* Decrement stack pointer. */
4673c1a0 11149
67928721 11150 if (cfun_frame_layout.frame_size > 0)
8b4a4127 11151 {
67928721 11152 rtx frame_off = GEN_INT (-cfun_frame_layout.frame_size);
b9c74b4d 11153 rtx real_frame_off;
4673c1a0 11154
cbb300e8 11155 if (s390_stack_size)
11156 {
00d233e6 11157 HOST_WIDE_INT stack_guard;
cbb300e8 11158
00d233e6 11159 if (s390_stack_guard)
11160 stack_guard = s390_stack_guard;
cbb300e8 11161 else
00d233e6 11162 {
11163 /* If no value for stack guard is provided the smallest power of 2
11164 larger than the current frame size is chosen. */
11165 stack_guard = 1;
11166 while (stack_guard < cfun_frame_layout.frame_size)
11167 stack_guard <<= 1;
11168 }
cbb300e8 11169
00d233e6 11170 if (cfun_frame_layout.frame_size >= s390_stack_size)
11171 {
8ad6fff9 11172 warning (0, "frame size of function %qs is %wd"
00d233e6 11173 " bytes exceeding user provided stack limit of "
8ad6fff9 11174 "%d bytes. "
00d233e6 11175 "An unconditional trap is added.",
11176 current_function_name(), cfun_frame_layout.frame_size,
11177 s390_stack_size);
11178 emit_insn (gen_trap ());
482869e7 11179 emit_barrier ();
00d233e6 11180 }
11181 else
11182 {
b437383e 11183 /* stack_guard has to be smaller than s390_stack_size.
11184 Otherwise we would emit an AND with zero which would
11185 not match the test under mask pattern. */
11186 if (stack_guard >= s390_stack_size)
11187 {
7fe62d25 11188 warning (0, "frame size of function %qs is %wd"
b437383e 11189 " bytes which is more than half the stack size. "
11190 "The dynamic check would not be reliable. "
11191 "No check emitted for this function.",
11192 current_function_name(),
11193 cfun_frame_layout.frame_size);
11194 }
00d233e6 11195 else
b437383e 11196 {
11197 HOST_WIDE_INT stack_check_mask = ((s390_stack_size - 1)
11198 & ~(stack_guard - 1));
11199
11200 rtx t = gen_rtx_AND (Pmode, stack_pointer_rtx,
11201 GEN_INT (stack_check_mask));
11202 if (TARGET_64BIT)
11203 emit_insn (gen_ctrapdi4 (gen_rtx_EQ (VOIDmode,
11204 t, const0_rtx),
11205 t, const0_rtx, const0_rtx));
11206 else
11207 emit_insn (gen_ctrapsi4 (gen_rtx_EQ (VOIDmode,
11208 t, const0_rtx),
11209 t, const0_rtx, const0_rtx));
11210 }
00d233e6 11211 }
cbb300e8 11212 }
11213
ffead1ca 11214 if (s390_warn_framesize > 0
cbb300e8 11215 && cfun_frame_layout.frame_size >= s390_warn_framesize)
7fe62d25 11216 warning (0, "frame size of %qs is %wd bytes",
cbb300e8 11217 current_function_name (), cfun_frame_layout.frame_size);
11218
11219 if (s390_warn_dynamicstack_p && cfun->calls_alloca)
c3ceba8e 11220 warning (0, "%qs uses dynamic stack allocation", current_function_name ());
cbb300e8 11221
8b4a4127 11222 /* Save incoming stack pointer into temp reg. */
e5c64bfc 11223 if (TARGET_BACKCHAIN || next_fpr)
67928721 11224 insn = emit_insn (gen_move_insn (temp_reg, stack_pointer_rtx));
f81e845f 11225
1fc184ee 11226 /* Subtract frame size from stack pointer. */
8b4a4127 11227
51aa1e9c 11228 if (DISP_IN_RANGE (INTVAL (frame_off)))
11229 {
d1f9b275 11230 insn = gen_rtx_SET (stack_pointer_rtx,
ffead1ca 11231 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
b40da9a7 11232 frame_off));
51aa1e9c 11233 insn = emit_insn (insn);
11234 }
11235 else
11236 {
cb888f33 11237 if (!CONST_OK_FOR_K (INTVAL (frame_off)))
51aa1e9c 11238 frame_off = force_const_mem (Pmode, frame_off);
11239
11240 insn = emit_insn (gen_add2_insn (stack_pointer_rtx, frame_off));
20074f87 11241 annotate_constant_pool_refs (&PATTERN (insn));
51aa1e9c 11242 }
8b4a4127 11243
8b4a4127 11244 RTX_FRAME_RELATED_P (insn) = 1;
b9c74b4d 11245 real_frame_off = GEN_INT (-cfun_frame_layout.frame_size);
11246 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
d1f9b275 11247 gen_rtx_SET (stack_pointer_rtx,
b9c74b4d 11248 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
11249 real_frame_off)));
8b4a4127 11250
11251 /* Set backchain. */
f81e845f 11252
e5c64bfc 11253 if (TARGET_BACKCHAIN)
4673c1a0 11254 {
67928721 11255 if (cfun_frame_layout.backchain_offset)
ffead1ca 11256 addr = gen_rtx_MEM (Pmode,
29c05e22 11257 plus_constant (Pmode, stack_pointer_rtx,
67928721 11258 cfun_frame_layout.backchain_offset));
11259 else
ffead1ca 11260 addr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
ce1d5a67 11261 set_mem_alias_set (addr, get_frame_alias_set ());
8b4a4127 11262 insn = emit_insn (gen_move_insn (addr, temp_reg));
4673c1a0 11263 }
90524d70 11264
cbeb677e 11265 /* If we support non-call exceptions (e.g. for Java),
90524d70 11266 we need to make sure the backchain pointer is set up
11267 before any possibly trapping memory access. */
cbeb677e 11268 if (TARGET_BACKCHAIN && cfun->can_throw_non_call_exceptions)
90524d70 11269 {
11270 addr = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
18b42941 11271 emit_clobber (addr);
90524d70 11272 }
8b4a4127 11273 }
4673c1a0 11274
8b4a4127 11275 /* Save fprs 8 - 15 (64 bit ABI). */
f81e845f 11276
67928721 11277 if (cfun_save_high_fprs_p && next_fpr)
8b4a4127 11278 {
062c49fd 11279 /* If the stack might be accessed through a different register
11280 we have to make sure that the stack pointer decrement is not
11281 moved below the use of the stack slots. */
11282 s390_emit_stack_tie ();
11283
ffead1ca 11284 insn = emit_insn (gen_add2_insn (temp_reg,
67928721 11285 GEN_INT (cfun_frame_layout.f8_offset)));
11286
11287 offset = 0;
4673c1a0 11288
6a2469fe 11289 for (i = FPR8_REGNUM; i <= next_fpr; i++)
29439367 11290 if (cfun_fpr_save_p (i))
8b4a4127 11291 {
29c05e22 11292 rtx addr = plus_constant (Pmode, stack_pointer_rtx,
67928721 11293 cfun_frame_layout.frame_size
11294 + cfun_frame_layout.f8_offset
11295 + offset);
ffead1ca 11296
67928721 11297 insn = save_fpr (temp_reg, offset, i);
11298 offset += 8;
8b4a4127 11299 RTX_FRAME_RELATED_P (insn) = 1;
b9c74b4d 11300 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
d1f9b275 11301 gen_rtx_SET (gen_rtx_MEM (DFmode, addr),
b9c74b4d 11302 gen_rtx_REG (DFmode, i)));
8b4a4127 11303 }
11304 }
f81e845f 11305
8b4a4127 11306 /* Set frame pointer, if needed. */
f81e845f 11307
5a5e802f 11308 if (frame_pointer_needed)
8b4a4127 11309 {
11310 insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
11311 RTX_FRAME_RELATED_P (insn) = 1;
11312 }
4673c1a0 11313
8b4a4127 11314 /* Set up got pointer, if needed. */
f81e845f 11315
3072d30e 11316 if (flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM))
20074f87 11317 {
93e0956b 11318 rtx_insn *insns = s390_load_got ();
20074f87 11319
91a55c11 11320 for (rtx_insn *insn = insns; insn; insn = NEXT_INSN (insn))
3072d30e 11321 annotate_constant_pool_refs (&PATTERN (insn));
20074f87 11322
11323 emit_insn (insns);
11324 }
f81e845f 11325
de253666 11326 if (TARGET_TPF_PROFILING)
f81e845f 11327 {
11328 /* Generate a BAS instruction to serve as a function
11329 entry intercept to facilitate the use of tracing
346fecd5 11330 algorithms located at the branch target. */
11331 emit_insn (gen_prologue_tpf ());
f81e845f 11332
11333 /* Emit a blockage here so that all code
11334 lies between the profiling mechanisms. */
11335 emit_insn (gen_blockage ());
11336 }
8b4a4127 11337}
4673c1a0 11338
d2833c15 11339/* Expand the epilogue into a bunch of separate insns. */
4673c1a0 11340
8b4a4127 11341void
7346ca58 11342s390_emit_epilogue (bool sibcall)
8b4a4127 11343{
a3cd0f6a 11344 rtx frame_pointer, return_reg, cfa_restores = NULL_RTX;
abd8f04d 11345 int area_bottom, area_top, offset = 0;
67928721 11346 int next_offset;
8b4a4127 11347 rtvec p;
78c2b526 11348 int i;
4673c1a0 11349
de253666 11350 if (TARGET_TPF_PROFILING)
f81e845f 11351 {
11352
11353 /* Generate a BAS instruction to serve as a function
11354 entry intercept to facilitate the use of tracing
346fecd5 11355 algorithms located at the branch target. */
f81e845f 11356
f81e845f 11357 /* Emit a blockage here so that all code
11358 lies between the profiling mechanisms. */
11359 emit_insn (gen_blockage ());
11360
346fecd5 11361 emit_insn (gen_epilogue_tpf ());
f81e845f 11362 }
11363
8b4a4127 11364 /* Check whether to use frame or stack pointer for restore. */
4673c1a0 11365
ffead1ca 11366 frame_pointer = (frame_pointer_needed
67928721 11367 ? hard_frame_pointer_rtx : stack_pointer_rtx);
4673c1a0 11368
67928721 11369 s390_frame_area (&area_bottom, &area_top);
4673c1a0 11370
f81e845f 11371 /* Check whether we can access the register save area.
8b4a4127 11372 If not, increment the frame pointer as required. */
4673c1a0 11373
8b4a4127 11374 if (area_top <= area_bottom)
11375 {
11376 /* Nothing to restore. */
11377 }
67928721 11378 else if (DISP_IN_RANGE (cfun_frame_layout.frame_size + area_bottom)
11379 && DISP_IN_RANGE (cfun_frame_layout.frame_size + area_top - 1))
8b4a4127 11380 {
11381 /* Area is in range. */
67928721 11382 offset = cfun_frame_layout.frame_size;
8b4a4127 11383 }
11384 else
11385 {
a3cd0f6a 11386 rtx insn, frame_off, cfa;
4673c1a0 11387
f81e845f 11388 offset = area_bottom < 0 ? -area_bottom : 0;
67928721 11389 frame_off = GEN_INT (cfun_frame_layout.frame_size - offset);
4673c1a0 11390
d1f9b275 11391 cfa = gen_rtx_SET (frame_pointer,
a3cd0f6a 11392 gen_rtx_PLUS (Pmode, frame_pointer, frame_off));
51aa1e9c 11393 if (DISP_IN_RANGE (INTVAL (frame_off)))
11394 {
d1f9b275 11395 insn = gen_rtx_SET (frame_pointer,
51aa1e9c 11396 gen_rtx_PLUS (Pmode, frame_pointer, frame_off));
11397 insn = emit_insn (insn);
11398 }
11399 else
11400 {
cb888f33 11401 if (!CONST_OK_FOR_K (INTVAL (frame_off)))
51aa1e9c 11402 frame_off = force_const_mem (Pmode, frame_off);
4673c1a0 11403
51aa1e9c 11404 insn = emit_insn (gen_add2_insn (frame_pointer, frame_off));
20074f87 11405 annotate_constant_pool_refs (&PATTERN (insn));
51aa1e9c 11406 }
a3cd0f6a 11407 add_reg_note (insn, REG_CFA_ADJUST_CFA, cfa);
11408 RTX_FRAME_RELATED_P (insn) = 1;
8b4a4127 11409 }
4673c1a0 11410
8b4a4127 11411 /* Restore call saved fprs. */
11412
11413 if (TARGET_64BIT)
4673c1a0 11414 {
67928721 11415 if (cfun_save_high_fprs_p)
11416 {
11417 next_offset = cfun_frame_layout.f8_offset;
6a2469fe 11418 for (i = FPR8_REGNUM; i <= FPR15_REGNUM; i++)
67928721 11419 {
29439367 11420 if (cfun_fpr_save_p (i))
67928721 11421 {
11422 restore_fpr (frame_pointer,
11423 offset + next_offset, i);
a3cd0f6a 11424 cfa_restores
11425 = alloc_reg_note (REG_CFA_RESTORE,
11426 gen_rtx_REG (DFmode, i), cfa_restores);
67928721 11427 next_offset += 8;
11428 }
11429 }
11430 }
ffead1ca 11431
4673c1a0 11432 }
11433 else
11434 {
67928721 11435 next_offset = cfun_frame_layout.f4_offset;
29439367 11436 /* f4, f6 */
6a2469fe 11437 for (i = FPR4_REGNUM; i <= FPR4_REGNUM + 1; i++)
67928721 11438 {
29439367 11439 if (cfun_fpr_save_p (i))
67928721 11440 {
11441 restore_fpr (frame_pointer,
11442 offset + next_offset, i);
a3cd0f6a 11443 cfa_restores
11444 = alloc_reg_note (REG_CFA_RESTORE,
11445 gen_rtx_REG (DFmode, i), cfa_restores);
67928721 11446 next_offset += 8;
11447 }
646a946e 11448 else if (!TARGET_PACKED_STACK)
67928721 11449 next_offset += 8;
11450 }
ffead1ca 11451
8b4a4127 11452 }
4673c1a0 11453
8b4a4127 11454 /* Return register. */
11455
f81e845f 11456 return_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
8b4a4127 11457
11458 /* Restore call saved gprs. */
11459
67928721 11460 if (cfun_frame_layout.first_restore_gpr != -1)
8b4a4127 11461 {
9a2a66ae 11462 rtx insn, addr;
43935856 11463 int i;
11464
f81e845f 11465 /* Check for global register and save them
43935856 11466 to stack location from where they get restored. */
11467
67928721 11468 for (i = cfun_frame_layout.first_restore_gpr;
11469 i <= cfun_frame_layout.last_restore_gpr;
43935856 11470 i++)
11471 {
a3cd0f6a 11472 if (global_not_special_regno_p (i))
43935856 11473 {
29c05e22 11474 addr = plus_constant (Pmode, frame_pointer,
ffead1ca 11475 offset + cfun_frame_layout.gprs_offset
5214e6ae 11476 + (i - cfun_frame_layout.first_save_gpr_slot)
b5fdc416 11477 * UNITS_PER_LONG);
43935856 11478 addr = gen_rtx_MEM (Pmode, addr);
ce1d5a67 11479 set_mem_alias_set (addr, get_frame_alias_set ());
43935856 11480 emit_move_insn (addr, gen_rtx_REG (Pmode, i));
f81e845f 11481 }
a3cd0f6a 11482 else
11483 cfa_restores
11484 = alloc_reg_note (REG_CFA_RESTORE,
11485 gen_rtx_REG (Pmode, i), cfa_restores);
43935856 11486 }
8b4a4127 11487
b5e83b9b 11488 /* Fetch return address from stack before load multiple,
11489 this will do good for scheduling.
11490
11491 Only do this if we already decided that r14 needs to be
11492 saved to a stack slot. (And not just because r14 happens to
11493 be in between two GPRs which need saving.) Otherwise it
11494 would be difficult to take that decision back in
11495 s390_optimize_prologue.
11496
11497 This optimization is only helpful on in-order machines. */
11498 if (! sibcall
11499 && cfun_gpr_save_slot (RETURN_REGNUM) == SAVE_SLOT_STACK
11500 && s390_tune <= PROCESSOR_2097_Z10)
11501 {
11502 int return_regnum = find_unused_clobbered_reg();
11503 if (!return_regnum)
11504 return_regnum = 4;
11505 return_reg = gen_rtx_REG (Pmode, return_regnum);
11506
11507 addr = plus_constant (Pmode, frame_pointer,
11508 offset + cfun_frame_layout.gprs_offset
11509 + (RETURN_REGNUM
11510 - cfun_frame_layout.first_save_gpr_slot)
11511 * UNITS_PER_LONG);
11512 addr = gen_rtx_MEM (Pmode, addr);
11513 set_mem_alias_set (addr, get_frame_alias_set ());
11514 emit_move_insn (return_reg, addr);
d7c99e1a 11515
b5e83b9b 11516 /* Once we did that optimization we have to make sure
11517 s390_optimize_prologue does not try to remove the store
11518 of r14 since we will not be able to find the load issued
11519 here. */
11520 cfun_frame_layout.save_return_addr_p = true;
4673c1a0 11521 }
8b4a4127 11522
67928721 11523 insn = restore_gprs (frame_pointer,
11524 offset + cfun_frame_layout.gprs_offset
ffead1ca 11525 + (cfun_frame_layout.first_restore_gpr
5214e6ae 11526 - cfun_frame_layout.first_save_gpr_slot)
b5fdc416 11527 * UNITS_PER_LONG,
67928721 11528 cfun_frame_layout.first_restore_gpr,
11529 cfun_frame_layout.last_restore_gpr);
a3cd0f6a 11530 insn = emit_insn (insn);
11531 REG_NOTES (insn) = cfa_restores;
11532 add_reg_note (insn, REG_CFA_DEF_CFA,
29c05e22 11533 plus_constant (Pmode, stack_pointer_rtx,
11534 STACK_POINTER_OFFSET));
a3cd0f6a 11535 RTX_FRAME_RELATED_P (insn) = 1;
8b4a4127 11536 }
4673c1a0 11537
ff4ce128 11538 s390_restore_gprs_from_fprs ();
11539
7346ca58 11540 if (! sibcall)
11541 {
f81e845f 11542
7346ca58 11543 /* Return to caller. */
f588eb9f 11544
7346ca58 11545 p = rtvec_alloc (2);
f588eb9f 11546
1a860023 11547 RTVEC_ELT (p, 0) = ret_rtx;
7346ca58 11548 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, return_reg);
11549 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
11550 }
4673c1a0 11551}
11552
7a64c761 11553/* Implement TARGET_SET_UP_BY_PROLOGUE. */
11554
11555static void
11556s300_set_up_by_prologue (hard_reg_set_container *regs)
11557{
11558 if (cfun->machine->base_reg
11559 && !call_really_used_regs[REGNO (cfun->machine->base_reg)])
11560 SET_HARD_REG_BIT (regs->set, REGNO (cfun->machine->base_reg));
11561}
11562
c6d481f7 11563/* -fsplit-stack support. */
11564
11565/* A SYMBOL_REF for __morestack. */
11566static GTY(()) rtx morestack_ref;
11567
11568/* When using -fsplit-stack, the allocation routines set a field in
11569 the TCB to the bottom of the stack plus this much space, measured
11570 in bytes. */
11571
11572#define SPLIT_STACK_AVAILABLE 1024
11573
11574/* Emit -fsplit-stack prologue, which goes before the regular function
11575 prologue. */
11576
11577void
11578s390_expand_split_stack_prologue (void)
11579{
11580 rtx r1, guard, cc = NULL;
11581 rtx_insn *insn;
11582 /* Offset from thread pointer to __private_ss. */
11583 int psso = TARGET_64BIT ? 0x38 : 0x20;
11584 /* Pointer size in bytes. */
11585 /* Frame size and argument size - the two parameters to __morestack. */
11586 HOST_WIDE_INT frame_size = cfun_frame_layout.frame_size;
11587 /* Align argument size to 8 bytes - simplifies __morestack code. */
11588 HOST_WIDE_INT args_size = crtl->args.size >= 0
11589 ? ((crtl->args.size + 7) & ~7)
11590 : 0;
11591 /* Label to be called by __morestack. */
11592 rtx_code_label *call_done = NULL;
11593 rtx_code_label *parm_base = NULL;
11594 rtx tmp;
11595
11596 gcc_assert (flag_split_stack && reload_completed);
11597 if (!TARGET_CPU_ZARCH)
11598 {
11599 sorry ("CPUs older than z900 are not supported for -fsplit-stack");
11600 return;
11601 }
11602
11603 r1 = gen_rtx_REG (Pmode, 1);
11604
11605 /* If no stack frame will be allocated, don't do anything. */
11606 if (!frame_size)
11607 {
11608 if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
11609 {
11610 /* If va_start is used, just use r15. */
11611 emit_move_insn (r1,
11612 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
11613 GEN_INT (STACK_POINTER_OFFSET)));
11614
11615 }
11616 return;
11617 }
11618
11619 if (morestack_ref == NULL_RTX)
11620 {
11621 morestack_ref = gen_rtx_SYMBOL_REF (Pmode, "__morestack");
11622 SYMBOL_REF_FLAGS (morestack_ref) |= (SYMBOL_FLAG_LOCAL
11623 | SYMBOL_FLAG_FUNCTION);
11624 }
11625
11626 if (CONST_OK_FOR_K (frame_size) || CONST_OK_FOR_Op (frame_size))
11627 {
11628 /* If frame_size will fit in an add instruction, do a stack space
11629 check, and only call __morestack if there's not enough space. */
11630
11631 /* Get thread pointer. r1 is the only register we can always destroy - r0
11632 could contain a static chain (and cannot be used to address memory
11633 anyway), r2-r6 can contain parameters, and r6-r15 are callee-saved. */
11634 emit_move_insn (r1, gen_rtx_REG (Pmode, TP_REGNUM));
11635 /* Aim at __private_ss. */
11636 guard = gen_rtx_MEM (Pmode, plus_constant (Pmode, r1, psso));
11637
11638 /* If less that 1kiB used, skip addition and compare directly with
11639 __private_ss. */
11640 if (frame_size > SPLIT_STACK_AVAILABLE)
11641 {
11642 emit_move_insn (r1, guard);
11643 if (TARGET_64BIT)
11644 emit_insn (gen_adddi3 (r1, r1, GEN_INT (frame_size)));
11645 else
11646 emit_insn (gen_addsi3 (r1, r1, GEN_INT (frame_size)));
11647 guard = r1;
11648 }
11649
11650 /* Compare the (maybe adjusted) guard with the stack pointer. */
11651 cc = s390_emit_compare (LT, stack_pointer_rtx, guard);
11652 }
11653
11654 call_done = gen_label_rtx ();
11655 parm_base = gen_label_rtx ();
11656
11657 /* Emit the parameter block. */
11658 tmp = gen_split_stack_data (parm_base, call_done,
11659 GEN_INT (frame_size),
11660 GEN_INT (args_size));
11661 insn = emit_insn (tmp);
11662 add_reg_note (insn, REG_LABEL_OPERAND, call_done);
11663 LABEL_NUSES (call_done)++;
11664 add_reg_note (insn, REG_LABEL_OPERAND, parm_base);
11665 LABEL_NUSES (parm_base)++;
11666
11667 /* %r1 = litbase. */
11668 insn = emit_move_insn (r1, gen_rtx_LABEL_REF (VOIDmode, parm_base));
11669 add_reg_note (insn, REG_LABEL_OPERAND, parm_base);
11670 LABEL_NUSES (parm_base)++;
11671
11672 /* Now, we need to call __morestack. It has very special calling
11673 conventions: it preserves param/return/static chain registers for
11674 calling main function body, and looks for its own parameters at %r1. */
11675
11676 if (cc != NULL)
11677 {
11678 tmp = gen_split_stack_cond_call (morestack_ref, cc, call_done);
11679
11680 insn = emit_jump_insn (tmp);
11681 JUMP_LABEL (insn) = call_done;
11682 LABEL_NUSES (call_done)++;
11683
11684 /* Mark the jump as very unlikely to be taken. */
61cb1816 11685 add_reg_br_prob_note (insn,
11686 profile_probability::very_unlikely ());
c6d481f7 11687
11688 if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
11689 {
11690 /* If va_start is used, and __morestack was not called, just use
11691 r15. */
11692 emit_move_insn (r1,
11693 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
11694 GEN_INT (STACK_POINTER_OFFSET)));
11695 }
11696 }
11697 else
11698 {
11699 tmp = gen_split_stack_call (morestack_ref, call_done);
11700 insn = emit_jump_insn (tmp);
11701 JUMP_LABEL (insn) = call_done;
11702 LABEL_NUSES (call_done)++;
11703 emit_barrier ();
11704 }
11705
11706 /* __morestack will call us here. */
11707
11708 emit_label (call_done);
11709}
11710
11711/* We may have to tell the dataflow pass that the split stack prologue
11712 is initializing a register. */
11713
11714static void
11715s390_live_on_entry (bitmap regs)
11716{
11717 if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
11718 {
11719 gcc_assert (flag_split_stack);
11720 bitmap_set_bit (regs, 1);
11721 }
11722}
11723
7a64c761 11724/* Return true if the function can use simple_return to return outside
11725 of a shrink-wrapped region. At present shrink-wrapping is supported
11726 in all cases. */
11727
11728bool
11729s390_can_use_simple_return_insn (void)
11730{
11731 return true;
11732}
11733
11734/* Return true if the epilogue is guaranteed to contain only a return
11735 instruction and if a direct return can therefore be used instead.
11736 One of the main advantages of using direct return instructions
11737 is that we can then use conditional returns. */
11738
11739bool
11740s390_can_use_return_insn (void)
11741{
11742 int i;
11743
11744 if (!reload_completed)
11745 return false;
11746
11747 if (crtl->profile)
11748 return false;
11749
11750 if (TARGET_TPF_PROFILING)
11751 return false;
11752
11753 for (i = 0; i < 16; i++)
1d3cea74 11754 if (cfun_gpr_save_slot (i) != SAVE_SLOT_NONE)
7a64c761 11755 return false;
11756
06fa0630 11757 /* For 31 bit this is not covered by the frame_size check below
11758 since f4, f6 are saved in the register save area without needing
11759 additional stack space. */
11760 if (!TARGET_64BIT
11761 && (cfun_fpr_save_p (FPR4_REGNUM) || cfun_fpr_save_p (FPR6_REGNUM)))
11762 return false;
11763
7a64c761 11764 if (cfun->machine->base_reg
11765 && !call_really_used_regs[REGNO (cfun->machine->base_reg)])
11766 return false;
11767
11768 return cfun_frame_layout.frame_size == 0;
11769}
4673c1a0 11770
76a4c804 11771/* The VX ABI differs for vararg functions. Therefore we need the
11772 prototype of the callee to be available when passing vector type
11773 values. */
11774static const char *
11775s390_invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
11776{
11777 return ((TARGET_VX_ABI
11778 && typelist == 0
11779 && VECTOR_TYPE_P (TREE_TYPE (val))
11780 && (funcdecl == NULL_TREE
11781 || (TREE_CODE (funcdecl) == FUNCTION_DECL
11782 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
19abb0ad 11783 ? N_("vector argument passed to unprototyped function")
76a4c804 11784 : NULL);
11785}
11786
11787
f81e845f 11788/* Return the size in bytes of a function argument of
56769981 11789 type TYPE and/or mode MODE. At least one of TYPE or
11790 MODE must be specified. */
4673c1a0 11791
11792static int
3754d046 11793s390_function_arg_size (machine_mode mode, const_tree type)
4673c1a0 11794{
11795 if (type)
11796 return int_size_in_bytes (type);
11797
0c034860 11798 /* No type info available for some library calls ... */
4673c1a0 11799 if (mode != BLKmode)
11800 return GET_MODE_SIZE (mode);
11801
11802 /* If we have neither type nor mode, abort */
32eda510 11803 gcc_unreachable ();
4673c1a0 11804}
11805
76a4c804 11806/* Return true if a function argument of type TYPE and mode MODE
11807 is to be passed in a vector register, if available. */
11808
11809bool
11810s390_function_arg_vector (machine_mode mode, const_tree type)
11811{
11812 if (!TARGET_VX_ABI)
11813 return false;
11814
11815 if (s390_function_arg_size (mode, type) > 16)
11816 return false;
11817
11818 /* No type info available for some library calls ... */
11819 if (!type)
11820 return VECTOR_MODE_P (mode);
11821
11822 /* The ABI says that record types with a single member are treated
11823 just like that member would be. */
11824 while (TREE_CODE (type) == RECORD_TYPE)
11825 {
11826 tree field, single = NULL_TREE;
11827
11828 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
11829 {
11830 if (TREE_CODE (field) != FIELD_DECL)
11831 continue;
11832
11833 if (single == NULL_TREE)
11834 single = TREE_TYPE (field);
11835 else
11836 return false;
11837 }
11838
11839 if (single == NULL_TREE)
11840 return false;
11841 else
11842 {
11843 /* If the field declaration adds extra byte due to
11844 e.g. padding this is not accepted as vector type. */
11845 if (int_size_in_bytes (single) <= 0
11846 || int_size_in_bytes (single) != int_size_in_bytes (type))
11847 return false;
11848 type = single;
11849 }
11850 }
11851
11852 return VECTOR_TYPE_P (type);
11853}
11854
59652f3f 11855/* Return true if a function argument of type TYPE and mode MODE
11856 is to be passed in a floating-point register, if available. */
11857
11858static bool
3754d046 11859s390_function_arg_float (machine_mode mode, const_tree type)
59652f3f 11860{
76a4c804 11861 if (s390_function_arg_size (mode, type) > 8)
201e502c 11862 return false;
11863
59652f3f 11864 /* Soft-float changes the ABI: no floating-point registers are used. */
11865 if (TARGET_SOFT_FLOAT)
11866 return false;
11867
11868 /* No type info available for some library calls ... */
11869 if (!type)
36868490 11870 return mode == SFmode || mode == DFmode || mode == SDmode || mode == DDmode;
59652f3f 11871
11872 /* The ABI says that record types with a single member are treated
11873 just like that member would be. */
11874 while (TREE_CODE (type) == RECORD_TYPE)
11875 {
11876 tree field, single = NULL_TREE;
11877
1767a056 11878 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
59652f3f 11879 {
11880 if (TREE_CODE (field) != FIELD_DECL)
11881 continue;
11882
11883 if (single == NULL_TREE)
11884 single = TREE_TYPE (field);
11885 else
11886 return false;
11887 }
11888
11889 if (single == NULL_TREE)
11890 return false;
11891 else
11892 type = single;
11893 }
11894
11895 return TREE_CODE (type) == REAL_TYPE;
11896}
11897
201e502c 11898/* Return true if a function argument of type TYPE and mode MODE
11899 is to be passed in an integer register, or a pair of integer
11900 registers, if available. */
11901
11902static bool
3754d046 11903s390_function_arg_integer (machine_mode mode, const_tree type)
201e502c 11904{
11905 int size = s390_function_arg_size (mode, type);
11906 if (size > 8)
11907 return false;
11908
11909 /* No type info available for some library calls ... */
11910 if (!type)
11911 return GET_MODE_CLASS (mode) == MODE_INT
36868490 11912 || (TARGET_SOFT_FLOAT && SCALAR_FLOAT_MODE_P (mode));
201e502c 11913
11914 /* We accept small integral (and similar) types. */
11915 if (INTEGRAL_TYPE_P (type)
f588eb9f 11916 || POINTER_TYPE_P (type)
bd3e12e5 11917 || TREE_CODE (type) == NULLPTR_TYPE
201e502c 11918 || TREE_CODE (type) == OFFSET_TYPE
11919 || (TARGET_SOFT_FLOAT && TREE_CODE (type) == REAL_TYPE))
11920 return true;
11921
11922 /* We also accept structs of size 1, 2, 4, 8 that are not
f588eb9f 11923 passed in floating-point registers. */
201e502c 11924 if (AGGREGATE_TYPE_P (type)
11925 && exact_log2 (size) >= 0
11926 && !s390_function_arg_float (mode, type))
11927 return true;
11928
11929 return false;
11930}
11931
56769981 11932/* Return 1 if a function argument of type TYPE and mode MODE
11933 is to be passed by reference. The ABI specifies that only
11934 structures of size 1, 2, 4, or 8 bytes are passed by value,
11935 all other structures (and complex numbers) are passed by
11936 reference. */
11937
b981d932 11938static bool
39cba157 11939s390_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED,
3754d046 11940 machine_mode mode, const_tree type,
b981d932 11941 bool named ATTRIBUTE_UNUSED)
4673c1a0 11942{
11943 int size = s390_function_arg_size (mode, type);
76a4c804 11944
11945 if (s390_function_arg_vector (mode, type))
11946 return false;
11947
201e502c 11948 if (size > 8)
11949 return true;
4673c1a0 11950
11951 if (type)
11952 {
201e502c 11953 if (AGGREGATE_TYPE_P (type) && exact_log2 (size) < 0)
76a4c804 11954 return true;
4673c1a0 11955
201e502c 11956 if (TREE_CODE (type) == COMPLEX_TYPE
11957 || TREE_CODE (type) == VECTOR_TYPE)
76a4c804 11958 return true;
4673c1a0 11959 }
f81e845f 11960
76a4c804 11961 return false;
4673c1a0 11962}
11963
11964/* Update the data in CUM to advance over an argument of mode MODE and
11965 data type TYPE. (TYPE is null for libcalls where that information
56769981 11966 may not be available.). The boolean NAMED specifies whether the
11967 argument is a named argument (as opposed to an unnamed argument
11968 matching an ellipsis). */
4673c1a0 11969
12bc26aa 11970static void
3754d046 11971s390_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
76a4c804 11972 const_tree type, bool named)
4673c1a0 11973{
39cba157 11974 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
11975
76a4c804 11976 if (s390_function_arg_vector (mode, type))
11977 {
11978 /* We are called for unnamed vector stdarg arguments which are
11979 passed on the stack. In this case this hook does not have to
11980 do anything since stack arguments are tracked by common
11981 code. */
11982 if (!named)
11983 return;
11984 cum->vrs += 1;
11985 }
11986 else if (s390_function_arg_float (mode, type))
4673c1a0 11987 {
59652f3f 11988 cum->fprs += 1;
4673c1a0 11989 }
201e502c 11990 else if (s390_function_arg_integer (mode, type))
4673c1a0 11991 {
11992 int size = s390_function_arg_size (mode, type);
b5fdc416 11993 cum->gprs += ((size + UNITS_PER_LONG - 1) / UNITS_PER_LONG);
4673c1a0 11994 }
201e502c 11995 else
32eda510 11996 gcc_unreachable ();
4673c1a0 11997}
11998
56769981 11999/* Define where to put the arguments to a function.
12000 Value is zero to push the argument on the stack,
12001 or a hard register in which to store the argument.
12002
12003 MODE is the argument's machine mode.
12004 TYPE is the data type of the argument (as a tree).
12005 This is null for libcalls where that information may
12006 not be available.
12007 CUM is a variable of type CUMULATIVE_ARGS which gives info about
12008 the preceding args and about the function being called.
12009 NAMED is nonzero if this argument is a named parameter
f81e845f 12010 (otherwise it is an extra parameter matching an ellipsis).
56769981 12011
12012 On S/390, we use general purpose registers 2 through 6 to
12013 pass integer, pointer, and certain structure arguments, and
12014 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
12015 to pass floating point arguments. All remaining arguments
12016 are pushed to the stack. */
4673c1a0 12017
12bc26aa 12018static rtx
3754d046 12019s390_function_arg (cumulative_args_t cum_v, machine_mode mode,
76a4c804 12020 const_tree type, bool named)
4673c1a0 12021{
39cba157 12022 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
12023
6b7cfb9c 12024 if (!named)
12025 s390_check_type_for_vector_abi (type, true, false);
76a4c804 12026
12027 if (s390_function_arg_vector (mode, type))
12028 {
12029 /* Vector arguments being part of the ellipsis are passed on the
12030 stack. */
12031 if (!named || (cum->vrs + 1 > VEC_ARG_NUM_REG))
12032 return NULL_RTX;
12033
12034 return gen_rtx_REG (mode, cum->vrs + FIRST_VEC_ARG_REGNO);
12035 }
12036 else if (s390_function_arg_float (mode, type))
4673c1a0 12037 {
6902d973 12038 if (cum->fprs + 1 > FP_ARG_NUM_REG)
76a4c804 12039 return NULL_RTX;
4673c1a0 12040 else
1a83b3ff 12041 return gen_rtx_REG (mode, cum->fprs + 16);
4673c1a0 12042 }
201e502c 12043 else if (s390_function_arg_integer (mode, type))
4673c1a0 12044 {
12045 int size = s390_function_arg_size (mode, type);
b5fdc416 12046 int n_gprs = (size + UNITS_PER_LONG - 1) / UNITS_PER_LONG;
4673c1a0 12047
6902d973 12048 if (cum->gprs + n_gprs > GP_ARG_NUM_REG)
76a4c804 12049 return NULL_RTX;
b5fdc416 12050 else if (n_gprs == 1 || UNITS_PER_WORD == UNITS_PER_LONG)
1a83b3ff 12051 return gen_rtx_REG (mode, cum->gprs + 2);
b5fdc416 12052 else if (n_gprs == 2)
12053 {
12054 rtvec p = rtvec_alloc (2);
12055
12056 RTVEC_ELT (p, 0)
12057 = gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, cum->gprs + 2),
12058 const0_rtx);
12059 RTVEC_ELT (p, 1)
12060 = gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, cum->gprs + 3),
12061 GEN_INT (4));
12062
12063 return gen_rtx_PARALLEL (mode, p);
12064 }
4673c1a0 12065 }
201e502c 12066
12067 /* After the real arguments, expand_call calls us once again
12068 with a void_type_node type. Whatever we return here is
12069 passed as operand 2 to the call expanders.
12070
12071 We don't need this feature ... */
12072 else if (type == void_type_node)
12073 return const0_rtx;
12074
32eda510 12075 gcc_unreachable ();
201e502c 12076}
12077
12078/* Return true if return values of type TYPE should be returned
12079 in a memory buffer whose address is passed by the caller as
12080 hidden first argument. */
12081
12082static bool
fb80456a 12083s390_return_in_memory (const_tree type, const_tree fundecl ATTRIBUTE_UNUSED)
201e502c 12084{
12085 /* We accept small integral (and similar) types. */
12086 if (INTEGRAL_TYPE_P (type)
f588eb9f 12087 || POINTER_TYPE_P (type)
201e502c 12088 || TREE_CODE (type) == OFFSET_TYPE
12089 || TREE_CODE (type) == REAL_TYPE)
12090 return int_size_in_bytes (type) > 8;
12091
76a4c804 12092 /* vector types which fit into a VR. */
12093 if (TARGET_VX_ABI
12094 && VECTOR_TYPE_P (type)
12095 && int_size_in_bytes (type) <= 16)
12096 return false;
12097
201e502c 12098 /* Aggregates and similar constructs are always returned
12099 in memory. */
12100 if (AGGREGATE_TYPE_P (type)
12101 || TREE_CODE (type) == COMPLEX_TYPE
76a4c804 12102 || VECTOR_TYPE_P (type))
201e502c 12103 return true;
12104
12105 /* ??? We get called on all sorts of random stuff from
12106 aggregate_value_p. We can't abort, but it's not clear
12107 what's safe to return. Pretend it's a struct I guess. */
12108 return true;
12109}
12110
3b2411a8 12111/* Function arguments and return values are promoted to word size. */
12112
3754d046 12113static machine_mode
12114s390_promote_function_mode (const_tree type, machine_mode mode,
3b2411a8 12115 int *punsignedp,
12116 const_tree fntype ATTRIBUTE_UNUSED,
12117 int for_return ATTRIBUTE_UNUSED)
12118{
12119 if (INTEGRAL_MODE_P (mode)
b5fdc416 12120 && GET_MODE_SIZE (mode) < UNITS_PER_LONG)
3b2411a8 12121 {
adaf4ef0 12122 if (type != NULL_TREE && POINTER_TYPE_P (type))
3b2411a8 12123 *punsignedp = POINTERS_EXTEND_UNSIGNED;
12124 return Pmode;
12125 }
12126
12127 return mode;
12128}
12129
dc3b3062 12130/* Define where to return a (scalar) value of type RET_TYPE.
12131 If RET_TYPE is null, define where to return a (scalar)
201e502c 12132 value of mode MODE from a libcall. */
12133
dc3b3062 12134static rtx
3754d046 12135s390_function_and_libcall_value (machine_mode mode,
dc3b3062 12136 const_tree ret_type,
12137 const_tree fntype_or_decl,
12138 bool outgoing ATTRIBUTE_UNUSED)
201e502c 12139{
76a4c804 12140 /* For vector return types it is important to use the RET_TYPE
12141 argument whenever available since the middle-end might have
12142 changed the mode to a scalar mode. */
12143 bool vector_ret_type_p = ((ret_type && VECTOR_TYPE_P (ret_type))
12144 || (!ret_type && VECTOR_MODE_P (mode)));
12145
dc3b3062 12146 /* For normal functions perform the promotion as
12147 promote_function_mode would do. */
12148 if (ret_type)
201e502c 12149 {
dc3b3062 12150 int unsignedp = TYPE_UNSIGNED (ret_type);
12151 mode = promote_function_mode (ret_type, mode, &unsignedp,
12152 fntype_or_decl, 1);
201e502c 12153 }
12154
76a4c804 12155 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT
12156 || SCALAR_FLOAT_MODE_P (mode)
12157 || (TARGET_VX_ABI && vector_ret_type_p));
12158 gcc_assert (GET_MODE_SIZE (mode) <= (TARGET_VX_ABI ? 16 : 8));
201e502c 12159
76a4c804 12160 if (TARGET_VX_ABI && vector_ret_type_p)
12161 return gen_rtx_REG (mode, FIRST_VEC_ARG_REGNO);
12162 else if (TARGET_HARD_FLOAT && SCALAR_FLOAT_MODE_P (mode))
201e502c 12163 return gen_rtx_REG (mode, 16);
b5fdc416 12164 else if (GET_MODE_SIZE (mode) <= UNITS_PER_LONG
12165 || UNITS_PER_LONG == UNITS_PER_WORD)
201e502c 12166 return gen_rtx_REG (mode, 2);
b5fdc416 12167 else if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_LONG)
12168 {
dc3b3062 12169 /* This case is triggered when returning a 64 bit value with
12170 -m31 -mzarch. Although the value would fit into a single
12171 register it has to be forced into a 32 bit register pair in
12172 order to match the ABI. */
b5fdc416 12173 rtvec p = rtvec_alloc (2);
12174
12175 RTVEC_ELT (p, 0)
12176 = gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, 2), const0_rtx);
12177 RTVEC_ELT (p, 1)
12178 = gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, 3), GEN_INT (4));
12179
12180 return gen_rtx_PARALLEL (mode, p);
12181 }
12182
12183 gcc_unreachable ();
4673c1a0 12184}
12185
dc3b3062 12186/* Define where to return a scalar return value of type RET_TYPE. */
12187
12188static rtx
12189s390_function_value (const_tree ret_type, const_tree fn_decl_or_type,
12190 bool outgoing)
12191{
12192 return s390_function_and_libcall_value (TYPE_MODE (ret_type), ret_type,
12193 fn_decl_or_type, outgoing);
12194}
12195
12196/* Define where to return a scalar libcall return value of mode
12197 MODE. */
12198
12199static rtx
3754d046 12200s390_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
dc3b3062 12201{
12202 return s390_function_and_libcall_value (mode, NULL_TREE,
12203 NULL_TREE, true);
12204}
12205
4673c1a0 12206
56769981 12207/* Create and return the va_list datatype.
12208
12209 On S/390, va_list is an array type equivalent to
12210
12211 typedef struct __va_list_tag
12212 {
12213 long __gpr;
12214 long __fpr;
12215 void *__overflow_arg_area;
12216 void *__reg_save_area;
56769981 12217 } va_list[1];
12218
12219 where __gpr and __fpr hold the number of general purpose
12220 or floating point arguments used up to now, respectively,
f81e845f 12221 __overflow_arg_area points to the stack location of the
56769981 12222 next argument passed on the stack, and __reg_save_area
12223 always points to the start of the register area in the
12224 call frame of the current function. The function prologue
12225 saves all registers used for argument passing into this
12226 area if the function uses variable arguments. */
4673c1a0 12227
2e15d750 12228static tree
12229s390_build_builtin_va_list (void)
4673c1a0 12230{
12231 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
12232
5ebb663d 12233 record = lang_hooks.types.make_type (RECORD_TYPE);
4673c1a0 12234
12235 type_decl =
54e46243 12236 build_decl (BUILTINS_LOCATION,
12237 TYPE_DECL, get_identifier ("__va_list_tag"), record);
4673c1a0 12238
54e46243 12239 f_gpr = build_decl (BUILTINS_LOCATION,
12240 FIELD_DECL, get_identifier ("__gpr"),
4673c1a0 12241 long_integer_type_node);
54e46243 12242 f_fpr = build_decl (BUILTINS_LOCATION,
12243 FIELD_DECL, get_identifier ("__fpr"),
4673c1a0 12244 long_integer_type_node);
54e46243 12245 f_ovf = build_decl (BUILTINS_LOCATION,
12246 FIELD_DECL, get_identifier ("__overflow_arg_area"),
4673c1a0 12247 ptr_type_node);
54e46243 12248 f_sav = build_decl (BUILTINS_LOCATION,
12249 FIELD_DECL, get_identifier ("__reg_save_area"),
4673c1a0 12250 ptr_type_node);
12251
6902d973 12252 va_list_gpr_counter_field = f_gpr;
12253 va_list_fpr_counter_field = f_fpr;
12254
4673c1a0 12255 DECL_FIELD_CONTEXT (f_gpr) = record;
12256 DECL_FIELD_CONTEXT (f_fpr) = record;
12257 DECL_FIELD_CONTEXT (f_ovf) = record;
12258 DECL_FIELD_CONTEXT (f_sav) = record;
12259
bc907808 12260 TYPE_STUB_DECL (record) = type_decl;
4673c1a0 12261 TYPE_NAME (record) = type_decl;
12262 TYPE_FIELDS (record) = f_gpr;
1767a056 12263 DECL_CHAIN (f_gpr) = f_fpr;
12264 DECL_CHAIN (f_fpr) = f_ovf;
12265 DECL_CHAIN (f_ovf) = f_sav;
4673c1a0 12266
12267 layout_type (record);
12268
12269 /* The correct type is an array type of one element. */
12270 return build_array_type (record, build_index_type (size_zero_node));
12271}
12272
56769981 12273/* Implement va_start by filling the va_list structure VALIST.
7ccc713a 12274 STDARG_P is always true, and ignored.
12275 NEXTARG points to the first anonymous stack argument.
56769981 12276
8ef587dc 12277 The following global variables are used to initialize
56769981 12278 the va_list structure:
12279
abe32cce 12280 crtl->args.info:
56769981 12281 holds number of gprs and fprs used for named arguments.
abe32cce 12282 crtl->args.arg_offset_rtx:
56769981 12283 holds the offset of the first anonymous stack argument
12284 (relative to the virtual arg pointer). */
4673c1a0 12285
8a58ed0a 12286static void
b40da9a7 12287s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
4673c1a0 12288{
12289 HOST_WIDE_INT n_gpr, n_fpr;
12290 int off;
12291 tree f_gpr, f_fpr, f_ovf, f_sav;
12292 tree gpr, fpr, ovf, sav, t;
12293
12294 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
1767a056 12295 f_fpr = DECL_CHAIN (f_gpr);
12296 f_ovf = DECL_CHAIN (f_fpr);
12297 f_sav = DECL_CHAIN (f_ovf);
4673c1a0 12298
170efcd4 12299 valist = build_simple_mem_ref (valist);
ed03eadb 12300 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
12301 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
12302 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
12303 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
4673c1a0 12304
12305 /* Count number of gp and fp argument registers used. */
12306
abe32cce 12307 n_gpr = crtl->args.info.gprs;
12308 n_fpr = crtl->args.info.fprs;
4673c1a0 12309
6902d973 12310 if (cfun->va_list_gpr_size)
12311 {
75a70cf9 12312 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
12313 build_int_cst (NULL_TREE, n_gpr));
6902d973 12314 TREE_SIDE_EFFECTS (t) = 1;
12315 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
12316 }
4673c1a0 12317
6902d973 12318 if (cfun->va_list_fpr_size)
12319 {
75a70cf9 12320 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
ed03eadb 12321 build_int_cst (NULL_TREE, n_fpr));
6902d973 12322 TREE_SIDE_EFFECTS (t) = 1;
12323 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
12324 }
4673c1a0 12325
c6d481f7 12326 if (flag_split_stack
12327 && (lookup_attribute ("no_split_stack", DECL_ATTRIBUTES (cfun->decl))
12328 == NULL)
12329 && cfun->machine->split_stack_varargs_pointer == NULL_RTX)
12330 {
12331 rtx reg;
12332 rtx_insn *seq;
12333
12334 reg = gen_reg_rtx (Pmode);
12335 cfun->machine->split_stack_varargs_pointer = reg;
12336
12337 start_sequence ();
12338 emit_move_insn (reg, gen_rtx_REG (Pmode, 1));
12339 seq = get_insns ();
12340 end_sequence ();
12341
12342 push_topmost_sequence ();
12343 emit_insn_after (seq, entry_of_function ());
12344 pop_topmost_sequence ();
12345 }
12346
76a4c804 12347 /* Find the overflow area.
12348 FIXME: This currently is too pessimistic when the vector ABI is
12349 enabled. In that case we *always* set up the overflow area
12350 pointer. */
6902d973 12351 if (n_gpr + cfun->va_list_gpr_size > GP_ARG_NUM_REG
76a4c804 12352 || n_fpr + cfun->va_list_fpr_size > FP_ARG_NUM_REG
12353 || TARGET_VX_ABI)
6902d973 12354 {
c6d481f7 12355 if (cfun->machine->split_stack_varargs_pointer == NULL_RTX)
12356 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
12357 else
12358 t = make_tree (TREE_TYPE (ovf), cfun->machine->split_stack_varargs_pointer);
4673c1a0 12359
abe32cce 12360 off = INTVAL (crtl->args.arg_offset_rtx);
6902d973 12361 off = off < 0 ? 0 : off;
12362 if (TARGET_DEBUG_ARG)
12363 fprintf (stderr, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
12364 (int)n_gpr, (int)n_fpr, off);
4673c1a0 12365
2cc66f2a 12366 t = fold_build_pointer_plus_hwi (t, off);
4673c1a0 12367
75a70cf9 12368 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
6902d973 12369 TREE_SIDE_EFFECTS (t) = 1;
12370 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
12371 }
4673c1a0 12372
12373 /* Find the register save area. */
6902d973 12374 if ((cfun->va_list_gpr_size && n_gpr < GP_ARG_NUM_REG)
12375 || (cfun->va_list_fpr_size && n_fpr < FP_ARG_NUM_REG))
12376 {
12377 t = make_tree (TREE_TYPE (sav), return_address_pointer_rtx);
2cc66f2a 12378 t = fold_build_pointer_plus_hwi (t, -RETURN_REGNUM * UNITS_PER_LONG);
ffead1ca 12379
75a70cf9 12380 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
6902d973 12381 TREE_SIDE_EFFECTS (t) = 1;
12382 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
12383 }
4673c1a0 12384}
12385
f81e845f 12386/* Implement va_arg by updating the va_list structure
56769981 12387 VALIST as required to retrieve an argument of type
f81e845f 12388 TYPE, and returning that argument.
12389
56769981 12390 Generates code equivalent to:
f81e845f 12391
4673c1a0 12392 if (integral value) {
12393 if (size <= 4 && args.gpr < 5 ||
f81e845f 12394 size > 4 && args.gpr < 4 )
4673c1a0 12395 ret = args.reg_save_area[args.gpr+8]
12396 else
12397 ret = *args.overflow_arg_area++;
76a4c804 12398 } else if (vector value) {
12399 ret = *args.overflow_arg_area;
12400 args.overflow_arg_area += size / 8;
4673c1a0 12401 } else if (float value) {
12402 if (args.fgpr < 2)
12403 ret = args.reg_save_area[args.fpr+64]
12404 else
12405 ret = *args.overflow_arg_area++;
12406 } else if (aggregate value) {
12407 if (args.gpr < 5)
12408 ret = *args.reg_save_area[args.gpr]
12409 else
12410 ret = **args.overflow_arg_area++;
12411 } */
12412
875862bf 12413static tree
ffead1ca 12414s390_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
75a70cf9 12415 gimple_seq *post_p ATTRIBUTE_UNUSED)
4673c1a0 12416{
12417 tree f_gpr, f_fpr, f_ovf, f_sav;
12418 tree gpr, fpr, ovf, sav, reg, t, u;
12419 int indirect_p, size, n_reg, sav_ofs, sav_scale, max_reg;
883b2519 12420 tree lab_false, lab_over = NULL_TREE;
76a4c804 12421 tree addr = create_tmp_var (ptr_type_node, "addr");
12422 bool left_align_p; /* How a value < UNITS_PER_LONG is aligned within
12423 a stack slot. */
4673c1a0 12424
12425 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
1767a056 12426 f_fpr = DECL_CHAIN (f_gpr);
12427 f_ovf = DECL_CHAIN (f_fpr);
12428 f_sav = DECL_CHAIN (f_ovf);
4673c1a0 12429
ed03eadb 12430 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
12431 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
ed03eadb 12432 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
4673c1a0 12433
75a70cf9 12434 /* The tree for args* cannot be shared between gpr/fpr and ovf since
12435 both appear on a lhs. */
12436 valist = unshare_expr (valist);
12437 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
12438
4673c1a0 12439 size = int_size_in_bytes (type);
12440
6b7cfb9c 12441 s390_check_type_for_vector_abi (type, true, false);
12442
b981d932 12443 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
4673c1a0 12444 {
12445 if (TARGET_DEBUG_ARG)
12446 {
12447 fprintf (stderr, "va_arg: aggregate type");
12448 debug_tree (type);
12449 }
12450
12451 /* Aggregates are passed by reference. */
12452 indirect_p = 1;
12453 reg = gpr;
12454 n_reg = 1;
99e8a714 12455
646a946e 12456 /* kernel stack layout on 31 bit: It is assumed here that no padding
99e8a714 12457 will be added by s390_frame_info because for va_args always an even
12458 number of gprs has to be saved r15-r2 = 14 regs. */
b5fdc416 12459 sav_ofs = 2 * UNITS_PER_LONG;
12460 sav_scale = UNITS_PER_LONG;
12461 size = UNITS_PER_LONG;
6902d973 12462 max_reg = GP_ARG_NUM_REG - n_reg;
76a4c804 12463 left_align_p = false;
12464 }
12465 else if (s390_function_arg_vector (TYPE_MODE (type), type))
12466 {
12467 if (TARGET_DEBUG_ARG)
12468 {
12469 fprintf (stderr, "va_arg: vector type");
12470 debug_tree (type);
12471 }
12472
12473 indirect_p = 0;
12474 reg = NULL_TREE;
12475 n_reg = 0;
12476 sav_ofs = 0;
12477 sav_scale = 8;
12478 max_reg = 0;
12479 left_align_p = true;
4673c1a0 12480 }
59652f3f 12481 else if (s390_function_arg_float (TYPE_MODE (type), type))
4673c1a0 12482 {
12483 if (TARGET_DEBUG_ARG)
12484 {
12485 fprintf (stderr, "va_arg: float type");
12486 debug_tree (type);
12487 }
12488
12489 /* FP args go in FP registers, if present. */
12490 indirect_p = 0;
12491 reg = fpr;
12492 n_reg = 1;
b5fdc416 12493 sav_ofs = 16 * UNITS_PER_LONG;
4673c1a0 12494 sav_scale = 8;
6902d973 12495 max_reg = FP_ARG_NUM_REG - n_reg;
76a4c804 12496 left_align_p = false;
4673c1a0 12497 }
12498 else
12499 {
12500 if (TARGET_DEBUG_ARG)
12501 {
12502 fprintf (stderr, "va_arg: other type");
12503 debug_tree (type);
12504 }
12505
12506 /* Otherwise into GP registers. */
12507 indirect_p = 0;
12508 reg = gpr;
b5fdc416 12509 n_reg = (size + UNITS_PER_LONG - 1) / UNITS_PER_LONG;
99e8a714 12510
646a946e 12511 /* kernel stack layout on 31 bit: It is assumed here that no padding
12512 will be added by s390_frame_info because for va_args always an even
12513 number of gprs has to be saved r15-r2 = 14 regs. */
b5fdc416 12514 sav_ofs = 2 * UNITS_PER_LONG;
f81e845f 12515
b5fdc416 12516 if (size < UNITS_PER_LONG)
12517 sav_ofs += UNITS_PER_LONG - size;
4673c1a0 12518
b5fdc416 12519 sav_scale = UNITS_PER_LONG;
6902d973 12520 max_reg = GP_ARG_NUM_REG - n_reg;
76a4c804 12521 left_align_p = false;
4673c1a0 12522 }
12523
12524 /* Pull the value out of the saved registers ... */
12525
76a4c804 12526 if (reg != NULL_TREE)
12527 {
12528 /*
12529 if (reg > ((typeof (reg))max_reg))
12530 goto lab_false;
4673c1a0 12531
76a4c804 12532 addr = sav + sav_ofs + reg * save_scale;
4673c1a0 12533
76a4c804 12534 goto lab_over;
4673c1a0 12535
76a4c804 12536 lab_false:
12537 */
12538
12539 lab_false = create_artificial_label (UNKNOWN_LOCATION);
12540 lab_over = create_artificial_label (UNKNOWN_LOCATION);
12541
12542 t = fold_convert (TREE_TYPE (reg), size_int (max_reg));
12543 t = build2 (GT_EXPR, boolean_type_node, reg, t);
12544 u = build1 (GOTO_EXPR, void_type_node, lab_false);
12545 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
12546 gimplify_and_add (t, pre_p);
4673c1a0 12547
76a4c804 12548 t = fold_build_pointer_plus_hwi (sav, sav_ofs);
12549 u = build2 (MULT_EXPR, TREE_TYPE (reg), reg,
12550 fold_convert (TREE_TYPE (reg), size_int (sav_scale)));
12551 t = fold_build_pointer_plus (t, u);
4673c1a0 12552
76a4c804 12553 gimplify_assign (addr, t, pre_p);
4673c1a0 12554
76a4c804 12555 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
12556
12557 gimple_seq_add_stmt (pre_p, gimple_build_label (lab_false));
12558 }
4673c1a0 12559
12560 /* ... Otherwise out of the overflow area. */
12561
875862bf 12562 t = ovf;
76a4c804 12563 if (size < UNITS_PER_LONG && !left_align_p)
2cc66f2a 12564 t = fold_build_pointer_plus_hwi (t, UNITS_PER_LONG - size);
875862bf 12565
12566 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
12567
75a70cf9 12568 gimplify_assign (addr, t, pre_p);
875862bf 12569
76a4c804 12570 if (size < UNITS_PER_LONG && left_align_p)
12571 t = fold_build_pointer_plus_hwi (t, UNITS_PER_LONG);
12572 else
12573 t = fold_build_pointer_plus_hwi (t, size);
12574
75a70cf9 12575 gimplify_assign (ovf, t, pre_p);
875862bf 12576
76a4c804 12577 if (reg != NULL_TREE)
12578 gimple_seq_add_stmt (pre_p, gimple_build_label (lab_over));
875862bf 12579
12580
12581 /* Increment register save count. */
12582
76a4c804 12583 if (n_reg > 0)
12584 {
12585 u = build2 (PREINCREMENT_EXPR, TREE_TYPE (reg), reg,
12586 fold_convert (TREE_TYPE (reg), size_int (n_reg)));
12587 gimplify_and_add (u, pre_p);
12588 }
875862bf 12589
12590 if (indirect_p)
12591 {
8115f0af 12592 t = build_pointer_type_for_mode (build_pointer_type (type),
12593 ptr_mode, true);
875862bf 12594 addr = fold_convert (t, addr);
12595 addr = build_va_arg_indirect_ref (addr);
12596 }
12597 else
12598 {
8115f0af 12599 t = build_pointer_type_for_mode (type, ptr_mode, true);
875862bf 12600 addr = fold_convert (t, addr);
12601 }
12602
12603 return build_va_arg_indirect_ref (addr);
12604}
12605
5ada7a14 12606/* Emit rtl for the tbegin or tbegin_retry (RETRY != NULL_RTX)
12607 expanders.
12608 DEST - Register location where CC will be stored.
12609 TDB - Pointer to a 256 byte area where to store the transaction.
12610 diagnostic block. NULL if TDB is not needed.
12611 RETRY - Retry count value. If non-NULL a retry loop for CC2
12612 is emitted
12613 CLOBBER_FPRS_P - If true clobbers for all FPRs are emitted as part
12614 of the tbegin instruction pattern. */
12615
12616void
12617s390_expand_tbegin (rtx dest, rtx tdb, rtx retry, bool clobber_fprs_p)
12618{
91dfd73e 12619 rtx retry_plus_two = gen_reg_rtx (SImode);
5ada7a14 12620 rtx retry_reg = gen_reg_rtx (SImode);
79f6a8ed 12621 rtx_code_label *retry_label = NULL;
5ada7a14 12622
12623 if (retry != NULL_RTX)
12624 {
12625 emit_move_insn (retry_reg, retry);
91dfd73e 12626 emit_insn (gen_addsi3 (retry_plus_two, retry_reg, const2_rtx));
12627 emit_insn (gen_addsi3 (retry_reg, retry_reg, const1_rtx));
5ada7a14 12628 retry_label = gen_label_rtx ();
12629 emit_label (retry_label);
12630 }
12631
12632 if (clobber_fprs_p)
044a78dc 12633 {
12634 if (TARGET_VX)
12635 emit_insn (gen_tbegin_1_z13 (gen_rtx_CONST_INT (VOIDmode, TBEGIN_MASK),
12636 tdb));
12637 else
12638 emit_insn (gen_tbegin_1 (gen_rtx_CONST_INT (VOIDmode, TBEGIN_MASK),
12639 tdb));
12640 }
5ada7a14 12641 else
91dfd73e 12642 emit_insn (gen_tbegin_nofloat_1 (gen_rtx_CONST_INT (VOIDmode, TBEGIN_MASK),
12643 tdb));
5ada7a14 12644
91dfd73e 12645 emit_move_insn (dest, gen_rtx_UNSPEC (SImode,
12646 gen_rtvec (1, gen_rtx_REG (CCRAWmode,
12647 CC_REGNUM)),
12648 UNSPEC_CC_TO_INT));
5ada7a14 12649 if (retry != NULL_RTX)
12650 {
d089210f 12651 const int CC0 = 1 << 3;
12652 const int CC1 = 1 << 2;
12653 const int CC3 = 1 << 0;
12654 rtx jump;
5ada7a14 12655 rtx count = gen_reg_rtx (SImode);
93e0956b 12656 rtx_code_label *leave_label = gen_label_rtx ();
d089210f 12657
12658 /* Exit for success and permanent failures. */
5ada7a14 12659 jump = s390_emit_jump (leave_label,
12660 gen_rtx_EQ (VOIDmode,
12661 gen_rtx_REG (CCRAWmode, CC_REGNUM),
d089210f 12662 gen_rtx_CONST_INT (VOIDmode, CC0 | CC1 | CC3)));
12663 LABEL_NUSES (leave_label) = 1;
5ada7a14 12664
12665 /* CC2 - transient failure. Perform retry with ppa. */
91dfd73e 12666 emit_move_insn (count, retry_plus_two);
5ada7a14 12667 emit_insn (gen_subsi3 (count, count, retry_reg));
12668 emit_insn (gen_tx_assist (count));
12669 jump = emit_jump_insn (gen_doloop_si64 (retry_label,
12670 retry_reg,
12671 retry_reg));
12672 JUMP_LABEL (jump) = retry_label;
12673 LABEL_NUSES (retry_label) = 1;
d089210f 12674 emit_label (leave_label);
5ada7a14 12675 }
5ada7a14 12676}
12677
5ada7a14 12678
751c914e 12679/* Return the decl for the target specific builtin with the function
12680 code FCODE. */
12681
12682static tree
12683s390_builtin_decl (unsigned fcode, bool initialized_p ATTRIBUTE_UNUSED)
12684{
12685 if (fcode >= S390_BUILTIN_MAX)
12686 return error_mark_node;
12687
12688 return s390_builtin_decls[fcode];
12689}
12690
d44f2f7c 12691/* We call mcount before the function prologue. So a profiled leaf
12692 function should stay a leaf function. */
12693
12694static bool
12695s390_keep_leaf_when_profiled ()
12696{
12697 return true;
12698}
5ada7a14 12699
875862bf 12700/* Output assembly code for the trampoline template to
12701 stdio stream FILE.
12702
12703 On S/390, we use gpr 1 internally in the trampoline code;
12704 gpr 0 is used to hold the static chain. */
12705
4d946732 12706static void
12707s390_asm_trampoline_template (FILE *file)
875862bf 12708{
12709 rtx op[2];
12710 op[0] = gen_rtx_REG (Pmode, 0);
12711 op[1] = gen_rtx_REG (Pmode, 1);
12712
12713 if (TARGET_64BIT)
12714 {
29335855 12715 output_asm_insn ("basr\t%1,0", op); /* 2 byte */
12716 output_asm_insn ("lmg\t%0,%1,14(%1)", op); /* 6 byte */
12717 output_asm_insn ("br\t%1", op); /* 2 byte */
875862bf 12718 ASM_OUTPUT_SKIP (file, (HOST_WIDE_INT)(TRAMPOLINE_SIZE - 10));
12719 }
12720 else
12721 {
29335855 12722 output_asm_insn ("basr\t%1,0", op); /* 2 byte */
12723 output_asm_insn ("lm\t%0,%1,6(%1)", op); /* 4 byte */
12724 output_asm_insn ("br\t%1", op); /* 2 byte */
875862bf 12725 ASM_OUTPUT_SKIP (file, (HOST_WIDE_INT)(TRAMPOLINE_SIZE - 8));
12726 }
12727}
12728
12729/* Emit RTL insns to initialize the variable parts of a trampoline.
12730 FNADDR is an RTX for the address of the function's pure code.
12731 CXT is an RTX for the static chain value for the function. */
12732
4d946732 12733static void
12734s390_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
875862bf 12735{
4d946732 12736 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
12737 rtx mem;
8a2a84e3 12738
4d946732 12739 emit_block_move (m_tramp, assemble_trampoline_template (),
29335855 12740 GEN_INT (2 * UNITS_PER_LONG), BLOCK_OP_NORMAL);
4d946732 12741
29335855 12742 mem = adjust_address (m_tramp, Pmode, 2 * UNITS_PER_LONG);
4d946732 12743 emit_move_insn (mem, cxt);
29335855 12744 mem = adjust_address (m_tramp, Pmode, 3 * UNITS_PER_LONG);
4d946732 12745 emit_move_insn (mem, fnaddr);
875862bf 12746}
12747
875862bf 12748/* Output assembler code to FILE to increment profiler label # LABELNO
12749 for profiling a function entry. */
12750
12751void
12752s390_function_profiler (FILE *file, int labelno)
12753{
12754 rtx op[7];
12755
12756 char label[128];
12757 ASM_GENERATE_INTERNAL_LABEL (label, "LP", labelno);
12758
12759 fprintf (file, "# function profiler \n");
12760
12761 op[0] = gen_rtx_REG (Pmode, RETURN_REGNUM);
12762 op[1] = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
29c05e22 12763 op[1] = gen_rtx_MEM (Pmode, plus_constant (Pmode, op[1], UNITS_PER_LONG));
875862bf 12764
12765 op[2] = gen_rtx_REG (Pmode, 1);
12766 op[3] = gen_rtx_SYMBOL_REF (Pmode, label);
12767 SYMBOL_REF_FLAGS (op[3]) = SYMBOL_FLAG_LOCAL;
12768
12769 op[4] = gen_rtx_SYMBOL_REF (Pmode, "_mcount");
12770 if (flag_pic)
12771 {
12772 op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), UNSPEC_PLT);
12773 op[4] = gen_rtx_CONST (Pmode, op[4]);
12774 }
12775
12776 if (TARGET_64BIT)
12777 {
12778 output_asm_insn ("stg\t%0,%1", op);
12779 output_asm_insn ("larl\t%2,%3", op);
12780 output_asm_insn ("brasl\t%0,%4", op);
12781 output_asm_insn ("lg\t%0,%1", op);
12782 }
4bc40d24 12783 else if (TARGET_CPU_ZARCH)
12784 {
12785 output_asm_insn ("st\t%0,%1", op);
12786 output_asm_insn ("larl\t%2,%3", op);
12787 output_asm_insn ("brasl\t%0,%4", op);
12788 output_asm_insn ("l\t%0,%1", op);
12789 }
875862bf 12790 else if (!flag_pic)
12791 {
12792 op[6] = gen_label_rtx ();
12793
12794 output_asm_insn ("st\t%0,%1", op);
12795 output_asm_insn ("bras\t%2,%l6", op);
12796 output_asm_insn (".long\t%4", op);
12797 output_asm_insn (".long\t%3", op);
12798 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
12799 output_asm_insn ("l\t%0,0(%2)", op);
12800 output_asm_insn ("l\t%2,4(%2)", op);
12801 output_asm_insn ("basr\t%0,%0", op);
12802 output_asm_insn ("l\t%0,%1", op);
12803 }
12804 else
12805 {
12806 op[5] = gen_label_rtx ();
12807 op[6] = gen_label_rtx ();
12808
12809 output_asm_insn ("st\t%0,%1", op);
12810 output_asm_insn ("bras\t%2,%l6", op);
12811 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[5]));
12812 output_asm_insn (".long\t%4-%l5", op);
12813 output_asm_insn (".long\t%3-%l5", op);
12814 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
12815 output_asm_insn ("lr\t%0,%2", op);
12816 output_asm_insn ("a\t%0,0(%2)", op);
12817 output_asm_insn ("a\t%2,4(%2)", op);
12818 output_asm_insn ("basr\t%0,%0", op);
12819 output_asm_insn ("l\t%0,%1", op);
12820 }
12821}
12822
12823/* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
12824 into its SYMBOL_REF_FLAGS. */
12825
12826static void
12827s390_encode_section_info (tree decl, rtx rtl, int first)
12828{
12829 default_encode_section_info (decl, rtl, first);
12830
e68d6a13 12831 if (TREE_CODE (decl) == VAR_DECL)
12832 {
78affa36 12833 /* Store the alignment to be able to check if we can use
12834 a larl/load-relative instruction. We only handle the cases
ea283725 12835 that can go wrong (i.e. no FUNC_DECLs). */
09d899d1 12836 if (DECL_ALIGN (decl) == 0 || DECL_ALIGN (decl) % 16)
78affa36 12837 SYMBOL_FLAG_SET_NOTALIGN2 (XEXP (rtl, 0));
ea283725 12838 else if (DECL_ALIGN (decl) % 32)
12839 SYMBOL_FLAG_SET_NOTALIGN4 (XEXP (rtl, 0));
12840 else if (DECL_ALIGN (decl) % 64)
12841 SYMBOL_FLAG_SET_NOTALIGN8 (XEXP (rtl, 0));
e68d6a13 12842 }
12843
12844 /* Literal pool references don't have a decl so they are handled
12845 differently here. We rely on the information in the MEM_ALIGN
78affa36 12846 entry to decide upon the alignment. */
e68d6a13 12847 if (MEM_P (rtl)
12848 && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF
ea283725 12849 && TREE_CONSTANT_POOL_ADDRESS_P (XEXP (rtl, 0)))
78affa36 12850 {
09d899d1 12851 if (MEM_ALIGN (rtl) == 0 || MEM_ALIGN (rtl) % 16)
78affa36 12852 SYMBOL_FLAG_SET_NOTALIGN2 (XEXP (rtl, 0));
ea283725 12853 else if (MEM_ALIGN (rtl) % 32)
12854 SYMBOL_FLAG_SET_NOTALIGN4 (XEXP (rtl, 0));
12855 else if (MEM_ALIGN (rtl) % 64)
12856 SYMBOL_FLAG_SET_NOTALIGN8 (XEXP (rtl, 0));
78affa36 12857 }
875862bf 12858}
12859
12860/* Output thunk to FILE that implements a C++ virtual function call (with
12861 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
12862 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
12863 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
12864 relative to the resulting this pointer. */
12865
12866static void
12867s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
12868 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
12869 tree function)
12870{
12871 rtx op[10];
12872 int nonlocal = 0;
12873
21a38800 12874 /* Make sure unwind info is emitted for the thunk if needed. */
12875 final_start_function (emit_barrier (), file, 1);
12876
875862bf 12877 /* Operand 0 is the target function. */
12878 op[0] = XEXP (DECL_RTL (function), 0);
12879 if (flag_pic && !SYMBOL_REF_LOCAL_P (op[0]))
12880 {
12881 nonlocal = 1;
12882 op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]),
12883 TARGET_64BIT ? UNSPEC_PLT : UNSPEC_GOT);
12884 op[0] = gen_rtx_CONST (Pmode, op[0]);
12885 }
12886
12887 /* Operand 1 is the 'this' pointer. */
12888 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
12889 op[1] = gen_rtx_REG (Pmode, 3);
12890 else
12891 op[1] = gen_rtx_REG (Pmode, 2);
12892
12893 /* Operand 2 is the delta. */
12894 op[2] = GEN_INT (delta);
12895
12896 /* Operand 3 is the vcall_offset. */
12897 op[3] = GEN_INT (vcall_offset);
12898
12899 /* Operand 4 is the temporary register. */
12900 op[4] = gen_rtx_REG (Pmode, 1);
12901
12902 /* Operands 5 to 8 can be used as labels. */
12903 op[5] = NULL_RTX;
12904 op[6] = NULL_RTX;
12905 op[7] = NULL_RTX;
12906 op[8] = NULL_RTX;
12907
12908 /* Operand 9 can be used for temporary register. */
12909 op[9] = NULL_RTX;
12910
12911 /* Generate code. */
12912 if (TARGET_64BIT)
12913 {
12914 /* Setup literal pool pointer if required. */
12915 if ((!DISP_IN_RANGE (delta)
163277cf 12916 && !CONST_OK_FOR_K (delta)
12917 && !CONST_OK_FOR_Os (delta))
875862bf 12918 || (!DISP_IN_RANGE (vcall_offset)
163277cf 12919 && !CONST_OK_FOR_K (vcall_offset)
12920 && !CONST_OK_FOR_Os (vcall_offset)))
875862bf 12921 {
12922 op[5] = gen_label_rtx ();
12923 output_asm_insn ("larl\t%4,%5", op);
12924 }
12925
12926 /* Add DELTA to this pointer. */
12927 if (delta)
12928 {
cb888f33 12929 if (CONST_OK_FOR_J (delta))
875862bf 12930 output_asm_insn ("la\t%1,%2(%1)", op);
12931 else if (DISP_IN_RANGE (delta))
12932 output_asm_insn ("lay\t%1,%2(%1)", op);
cb888f33 12933 else if (CONST_OK_FOR_K (delta))
875862bf 12934 output_asm_insn ("aghi\t%1,%2", op);
163277cf 12935 else if (CONST_OK_FOR_Os (delta))
12936 output_asm_insn ("agfi\t%1,%2", op);
875862bf 12937 else
12938 {
12939 op[6] = gen_label_rtx ();
12940 output_asm_insn ("agf\t%1,%6-%5(%4)", op);
12941 }
12942 }
12943
12944 /* Perform vcall adjustment. */
12945 if (vcall_offset)
12946 {
12947 if (DISP_IN_RANGE (vcall_offset))
12948 {
12949 output_asm_insn ("lg\t%4,0(%1)", op);
12950 output_asm_insn ("ag\t%1,%3(%4)", op);
12951 }
cb888f33 12952 else if (CONST_OK_FOR_K (vcall_offset))
875862bf 12953 {
12954 output_asm_insn ("lghi\t%4,%3", op);
12955 output_asm_insn ("ag\t%4,0(%1)", op);
12956 output_asm_insn ("ag\t%1,0(%4)", op);
12957 }
163277cf 12958 else if (CONST_OK_FOR_Os (vcall_offset))
12959 {
12960 output_asm_insn ("lgfi\t%4,%3", op);
12961 output_asm_insn ("ag\t%4,0(%1)", op);
12962 output_asm_insn ("ag\t%1,0(%4)", op);
12963 }
875862bf 12964 else
12965 {
12966 op[7] = gen_label_rtx ();
12967 output_asm_insn ("llgf\t%4,%7-%5(%4)", op);
12968 output_asm_insn ("ag\t%4,0(%1)", op);
12969 output_asm_insn ("ag\t%1,0(%4)", op);
12970 }
12971 }
12972
12973 /* Jump to target. */
12974 output_asm_insn ("jg\t%0", op);
12975
12976 /* Output literal pool if required. */
12977 if (op[5])
12978 {
12979 output_asm_insn (".align\t4", op);
12980 targetm.asm_out.internal_label (file, "L",
12981 CODE_LABEL_NUMBER (op[5]));
12982 }
12983 if (op[6])
12984 {
12985 targetm.asm_out.internal_label (file, "L",
12986 CODE_LABEL_NUMBER (op[6]));
12987 output_asm_insn (".long\t%2", op);
12988 }
12989 if (op[7])
12990 {
12991 targetm.asm_out.internal_label (file, "L",
12992 CODE_LABEL_NUMBER (op[7]));
12993 output_asm_insn (".long\t%3", op);
12994 }
12995 }
12996 else
12997 {
12998 /* Setup base pointer if required. */
12999 if (!vcall_offset
13000 || (!DISP_IN_RANGE (delta)
163277cf 13001 && !CONST_OK_FOR_K (delta)
13002 && !CONST_OK_FOR_Os (delta))
875862bf 13003 || (!DISP_IN_RANGE (delta)
163277cf 13004 && !CONST_OK_FOR_K (vcall_offset)
13005 && !CONST_OK_FOR_Os (vcall_offset)))
875862bf 13006 {
13007 op[5] = gen_label_rtx ();
13008 output_asm_insn ("basr\t%4,0", op);
13009 targetm.asm_out.internal_label (file, "L",
13010 CODE_LABEL_NUMBER (op[5]));
13011 }
13012
13013 /* Add DELTA to this pointer. */
13014 if (delta)
13015 {
cb888f33 13016 if (CONST_OK_FOR_J (delta))
875862bf 13017 output_asm_insn ("la\t%1,%2(%1)", op);
13018 else if (DISP_IN_RANGE (delta))
13019 output_asm_insn ("lay\t%1,%2(%1)", op);
cb888f33 13020 else if (CONST_OK_FOR_K (delta))
875862bf 13021 output_asm_insn ("ahi\t%1,%2", op);
163277cf 13022 else if (CONST_OK_FOR_Os (delta))
13023 output_asm_insn ("afi\t%1,%2", op);
875862bf 13024 else
13025 {
13026 op[6] = gen_label_rtx ();
13027 output_asm_insn ("a\t%1,%6-%5(%4)", op);
13028 }
13029 }
13030
13031 /* Perform vcall adjustment. */
13032 if (vcall_offset)
13033 {
cb888f33 13034 if (CONST_OK_FOR_J (vcall_offset))
875862bf 13035 {
0451e449 13036 output_asm_insn ("l\t%4,0(%1)", op);
875862bf 13037 output_asm_insn ("a\t%1,%3(%4)", op);
13038 }
13039 else if (DISP_IN_RANGE (vcall_offset))
13040 {
0451e449 13041 output_asm_insn ("l\t%4,0(%1)", op);
875862bf 13042 output_asm_insn ("ay\t%1,%3(%4)", op);
13043 }
cb888f33 13044 else if (CONST_OK_FOR_K (vcall_offset))
875862bf 13045 {
13046 output_asm_insn ("lhi\t%4,%3", op);
13047 output_asm_insn ("a\t%4,0(%1)", op);
13048 output_asm_insn ("a\t%1,0(%4)", op);
13049 }
163277cf 13050 else if (CONST_OK_FOR_Os (vcall_offset))
13051 {
13052 output_asm_insn ("iilf\t%4,%3", op);
13053 output_asm_insn ("a\t%4,0(%1)", op);
13054 output_asm_insn ("a\t%1,0(%4)", op);
13055 }
875862bf 13056 else
13057 {
13058 op[7] = gen_label_rtx ();
13059 output_asm_insn ("l\t%4,%7-%5(%4)", op);
13060 output_asm_insn ("a\t%4,0(%1)", op);
13061 output_asm_insn ("a\t%1,0(%4)", op);
13062 }
4673c1a0 13063
875862bf 13064 /* We had to clobber the base pointer register.
13065 Re-setup the base pointer (with a different base). */
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 }
4673c1a0 13071
875862bf 13072 /* Jump to target. */
13073 op[8] = gen_label_rtx ();
4673c1a0 13074
875862bf 13075 if (!flag_pic)
13076 output_asm_insn ("l\t%4,%8-%5(%4)", op);
13077 else if (!nonlocal)
13078 output_asm_insn ("a\t%4,%8-%5(%4)", op);
13079 /* We cannot call through .plt, since .plt requires %r12 loaded. */
13080 else if (flag_pic == 1)
13081 {
13082 output_asm_insn ("a\t%4,%8-%5(%4)", op);
13083 output_asm_insn ("l\t%4,%0(%4)", op);
13084 }
13085 else if (flag_pic == 2)
13086 {
13087 op[9] = gen_rtx_REG (Pmode, 0);
13088 output_asm_insn ("l\t%9,%8-4-%5(%4)", op);
13089 output_asm_insn ("a\t%4,%8-%5(%4)", op);
13090 output_asm_insn ("ar\t%4,%9", op);
13091 output_asm_insn ("l\t%4,0(%4)", op);
13092 }
4673c1a0 13093
875862bf 13094 output_asm_insn ("br\t%4", op);
4673c1a0 13095
875862bf 13096 /* Output literal pool. */
13097 output_asm_insn (".align\t4", op);
4673c1a0 13098
875862bf 13099 if (nonlocal && flag_pic == 2)
13100 output_asm_insn (".long\t%0", op);
13101 if (nonlocal)
13102 {
13103 op[0] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
13104 SYMBOL_REF_FLAGS (op[0]) = SYMBOL_FLAG_LOCAL;
13105 }
d93e0d9f 13106
875862bf 13107 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[8]));
13108 if (!flag_pic)
13109 output_asm_insn (".long\t%0", op);
13110 else
13111 output_asm_insn (".long\t%0-%5", op);
4673c1a0 13112
875862bf 13113 if (op[6])
13114 {
13115 targetm.asm_out.internal_label (file, "L",
13116 CODE_LABEL_NUMBER (op[6]));
13117 output_asm_insn (".long\t%2", op);
13118 }
13119 if (op[7])
13120 {
13121 targetm.asm_out.internal_label (file, "L",
13122 CODE_LABEL_NUMBER (op[7]));
13123 output_asm_insn (".long\t%3", op);
13124 }
4673c1a0 13125 }
21a38800 13126 final_end_function ();
4673c1a0 13127}
13128
875862bf 13129static bool
3754d046 13130s390_valid_pointer_mode (machine_mode mode)
875862bf 13131{
13132 return (mode == SImode || (TARGET_64BIT && mode == DImode));
13133}
56769981 13134
347301d6 13135/* Checks whether the given CALL_EXPR would use a caller
875862bf 13136 saved register. This is used to decide whether sibling call
13137 optimization could be performed on the respective function
13138 call. */
be00aaa8 13139
875862bf 13140static bool
347301d6 13141s390_call_saved_register_used (tree call_expr)
be00aaa8 13142{
39cba157 13143 CUMULATIVE_ARGS cum_v;
13144 cumulative_args_t cum;
875862bf 13145 tree parameter;
3754d046 13146 machine_mode mode;
875862bf 13147 tree type;
13148 rtx parm_rtx;
347301d6 13149 int reg, i;
be00aaa8 13150
39cba157 13151 INIT_CUMULATIVE_ARGS (cum_v, NULL, NULL, 0, 0);
13152 cum = pack_cumulative_args (&cum_v);
be00aaa8 13153
347301d6 13154 for (i = 0; i < call_expr_nargs (call_expr); i++)
875862bf 13155 {
347301d6 13156 parameter = CALL_EXPR_ARG (call_expr, i);
32eda510 13157 gcc_assert (parameter);
be00aaa8 13158
875862bf 13159 /* For an undeclared variable passed as parameter we will get
13160 an ERROR_MARK node here. */
13161 if (TREE_CODE (parameter) == ERROR_MARK)
13162 return true;
be00aaa8 13163
32eda510 13164 type = TREE_TYPE (parameter);
13165 gcc_assert (type);
be00aaa8 13166
32eda510 13167 mode = TYPE_MODE (type);
13168 gcc_assert (mode);
be00aaa8 13169
76a4c804 13170 /* We assume that in the target function all parameters are
13171 named. This only has an impact on vector argument register
13172 usage none of which is call-saved. */
39cba157 13173 if (pass_by_reference (&cum_v, mode, type, true))
875862bf 13174 {
13175 mode = Pmode;
13176 type = build_pointer_type (type);
13177 }
be00aaa8 13178
76a4c804 13179 parm_rtx = s390_function_arg (cum, mode, type, true);
be00aaa8 13180
76a4c804 13181 s390_function_arg_advance (cum, mode, type, true);
be00aaa8 13182
b5fdc416 13183 if (!parm_rtx)
13184 continue;
13185
13186 if (REG_P (parm_rtx))
13187 {
cc6a115b 13188 for (reg = 0;
13189 reg < HARD_REGNO_NREGS (REGNO (parm_rtx), GET_MODE (parm_rtx));
13190 reg++)
b5fdc416 13191 if (!call_used_regs[reg + REGNO (parm_rtx)])
13192 return true;
13193 }
13194
13195 if (GET_CODE (parm_rtx) == PARALLEL)
875862bf 13196 {
b5fdc416 13197 int i;
cc6a115b 13198
b5fdc416 13199 for (i = 0; i < XVECLEN (parm_rtx, 0); i++)
13200 {
13201 rtx r = XEXP (XVECEXP (parm_rtx, 0, i), 0);
b5fdc416 13202
13203 gcc_assert (REG_P (r));
13204
cc6a115b 13205 for (reg = 0;
13206 reg < HARD_REGNO_NREGS (REGNO (r), GET_MODE (r));
13207 reg++)
b5fdc416 13208 if (!call_used_regs[reg + REGNO (r)])
13209 return true;
13210 }
875862bf 13211 }
b5fdc416 13212
875862bf 13213 }
13214 return false;
13215}
be00aaa8 13216
875862bf 13217/* Return true if the given call expression can be
13218 turned into a sibling call.
13219 DECL holds the declaration of the function to be called whereas
13220 EXP is the call expression itself. */
be00aaa8 13221
875862bf 13222static bool
13223s390_function_ok_for_sibcall (tree decl, tree exp)
13224{
13225 /* The TPF epilogue uses register 1. */
13226 if (TARGET_TPF_PROFILING)
13227 return false;
be00aaa8 13228
875862bf 13229 /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
13230 which would have to be restored before the sibcall. */
a47b0dc3 13231 if (!TARGET_64BIT && flag_pic && decl && !targetm.binds_local_p (decl))
875862bf 13232 return false;
be00aaa8 13233
875862bf 13234 /* Register 6 on s390 is available as an argument register but unfortunately
13235 "caller saved". This makes functions needing this register for arguments
13236 not suitable for sibcalls. */
347301d6 13237 return !s390_call_saved_register_used (exp);
875862bf 13238}
be00aaa8 13239
875862bf 13240/* Return the fixed registers used for condition codes. */
be00aaa8 13241
875862bf 13242static bool
13243s390_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
13244{
13245 *p1 = CC_REGNUM;
13246 *p2 = INVALID_REGNUM;
ffead1ca 13247
875862bf 13248 return true;
13249}
be00aaa8 13250
875862bf 13251/* This function is used by the call expanders of the machine description.
13252 It emits the call insn itself together with the necessary operations
13253 to adjust the target address and returns the emitted insn.
13254 ADDR_LOCATION is the target address rtx
13255 TLS_CALL the location of the thread-local symbol
13256 RESULT_REG the register where the result of the call should be stored
13257 RETADDR_REG the register where the return address should be stored
13258 If this parameter is NULL_RTX the call is considered
13259 to be a sibling call. */
be00aaa8 13260
93e0956b 13261rtx_insn *
875862bf 13262s390_emit_call (rtx addr_location, rtx tls_call, rtx result_reg,
13263 rtx retaddr_reg)
4673c1a0 13264{
875862bf 13265 bool plt_call = false;
93e0956b 13266 rtx_insn *insn;
875862bf 13267 rtx call;
13268 rtx clobber;
13269 rtvec vec;
4a1c604e 13270
875862bf 13271 /* Direct function calls need special treatment. */
13272 if (GET_CODE (addr_location) == SYMBOL_REF)
4673c1a0 13273 {
875862bf 13274 /* When calling a global routine in PIC mode, we must
13275 replace the symbol itself with the PLT stub. */
13276 if (flag_pic && !SYMBOL_REF_LOCAL_P (addr_location))
13277 {
aa5b4778 13278 if (TARGET_64BIT || retaddr_reg != NULL_RTX)
9c7185f7 13279 {
13280 addr_location = gen_rtx_UNSPEC (Pmode,
13281 gen_rtvec (1, addr_location),
13282 UNSPEC_PLT);
13283 addr_location = gen_rtx_CONST (Pmode, addr_location);
13284 plt_call = true;
13285 }
13286 else
13287 /* For -fpic code the PLT entries might use r12 which is
13288 call-saved. Therefore we cannot do a sibcall when
13289 calling directly using a symbol ref. When reaching
13290 this point we decided (in s390_function_ok_for_sibcall)
13291 to do a sibcall for a function pointer but one of the
13292 optimizers was able to get rid of the function pointer
13293 by propagating the symbol ref into the call. This
13294 optimization is illegal for S/390 so we turn the direct
13295 call into a indirect call again. */
13296 addr_location = force_reg (Pmode, addr_location);
875862bf 13297 }
13298
13299 /* Unless we can use the bras(l) insn, force the
13300 routine address into a register. */
13301 if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
13302 {
13303 if (flag_pic)
13304 addr_location = legitimize_pic_address (addr_location, 0);
13305 else
13306 addr_location = force_reg (Pmode, addr_location);
13307 }
4673c1a0 13308 }
875862bf 13309
13310 /* If it is already an indirect call or the code above moved the
13311 SYMBOL_REF to somewhere else make sure the address can be found in
13312 register 1. */
13313 if (retaddr_reg == NULL_RTX
13314 && GET_CODE (addr_location) != SYMBOL_REF
13315 && !plt_call)
4673c1a0 13316 {
875862bf 13317 emit_move_insn (gen_rtx_REG (Pmode, SIBCALL_REGNUM), addr_location);
13318 addr_location = gen_rtx_REG (Pmode, SIBCALL_REGNUM);
4673c1a0 13319 }
4673c1a0 13320
875862bf 13321 addr_location = gen_rtx_MEM (QImode, addr_location);
13322 call = gen_rtx_CALL (VOIDmode, addr_location, const0_rtx);
8b4a4127 13323
875862bf 13324 if (result_reg != NULL_RTX)
d1f9b275 13325 call = gen_rtx_SET (result_reg, call);
8b4a4127 13326
875862bf 13327 if (retaddr_reg != NULL_RTX)
13328 {
13329 clobber = gen_rtx_CLOBBER (VOIDmode, retaddr_reg);
f81e845f 13330
875862bf 13331 if (tls_call != NULL_RTX)
13332 vec = gen_rtvec (3, call, clobber,
13333 gen_rtx_USE (VOIDmode, tls_call));
13334 else
13335 vec = gen_rtvec (2, call, clobber);
8b4a4127 13336
875862bf 13337 call = gen_rtx_PARALLEL (VOIDmode, vec);
13338 }
8b4a4127 13339
875862bf 13340 insn = emit_call_insn (call);
8b4a4127 13341
875862bf 13342 /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
13343 if ((!TARGET_64BIT && plt_call) || tls_call != NULL_RTX)
13344 {
13345 /* s390_function_ok_for_sibcall should
13346 have denied sibcalls in this case. */
32eda510 13347 gcc_assert (retaddr_reg != NULL_RTX);
c60a7572 13348 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), gen_rtx_REG (Pmode, 12));
875862bf 13349 }
13350 return insn;
13351}
8b4a4127 13352
b2d7ede1 13353/* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
8b4a4127 13354
b2d7ede1 13355static void
875862bf 13356s390_conditional_register_usage (void)
13357{
13358 int i;
8b4a4127 13359
8b4a4127 13360 if (flag_pic)
13361 {
875862bf 13362 fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
13363 call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
8b4a4127 13364 }
875862bf 13365 if (TARGET_CPU_ZARCH)
8b4a4127 13366 {
d1a5573e 13367 fixed_regs[BASE_REGNUM] = 0;
13368 call_used_regs[BASE_REGNUM] = 0;
875862bf 13369 fixed_regs[RETURN_REGNUM] = 0;
13370 call_used_regs[RETURN_REGNUM] = 0;
8b4a4127 13371 }
875862bf 13372 if (TARGET_64BIT)
8b4a4127 13373 {
6a2469fe 13374 for (i = FPR8_REGNUM; i <= FPR15_REGNUM; i++)
875862bf 13375 call_used_regs[i] = call_really_used_regs[i] = 0;
8b4a4127 13376 }
13377 else
13378 {
6a2469fe 13379 call_used_regs[FPR4_REGNUM] = call_really_used_regs[FPR4_REGNUM] = 0;
13380 call_used_regs[FPR6_REGNUM] = call_really_used_regs[FPR6_REGNUM] = 0;
875862bf 13381 }
8b4a4127 13382
875862bf 13383 if (TARGET_SOFT_FLOAT)
13384 {
6a2469fe 13385 for (i = FPR0_REGNUM; i <= FPR15_REGNUM; i++)
875862bf 13386 call_used_regs[i] = fixed_regs[i] = 1;
8b4a4127 13387 }
76a4c804 13388
13389 /* Disable v16 - v31 for non-vector target. */
13390 if (!TARGET_VX)
13391 {
13392 for (i = VR16_REGNUM; i <= VR31_REGNUM; i++)
13393 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
13394 }
8b4a4127 13395}
13396
875862bf 13397/* Corresponding function to eh_return expander. */
7811991d 13398
875862bf 13399static GTY(()) rtx s390_tpf_eh_return_symbol;
13400void
13401s390_emit_tpf_eh_return (rtx target)
7811991d 13402{
93e0956b 13403 rtx_insn *insn;
13404 rtx reg, orig_ra;
525d1294 13405
875862bf 13406 if (!s390_tpf_eh_return_symbol)
13407 s390_tpf_eh_return_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tpf_eh_return");
13408
13409 reg = gen_rtx_REG (Pmode, 2);
bcd3133e 13410 orig_ra = gen_rtx_REG (Pmode, 3);
875862bf 13411
13412 emit_move_insn (reg, target);
bcd3133e 13413 emit_move_insn (orig_ra, get_hard_reg_initial_val (Pmode, RETURN_REGNUM));
875862bf 13414 insn = s390_emit_call (s390_tpf_eh_return_symbol, NULL_RTX, reg,
13415 gen_rtx_REG (Pmode, RETURN_REGNUM));
13416 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
bcd3133e 13417 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), orig_ra);
875862bf 13418
13419 emit_move_insn (EH_RETURN_HANDLER_RTX, reg);
be00aaa8 13420}
13421
875862bf 13422/* Rework the prologue/epilogue to avoid saving/restoring
13423 registers unnecessarily. */
c20f8a1d 13424
6988553d 13425static void
875862bf 13426s390_optimize_prologue (void)
c6933ba6 13427{
93e0956b 13428 rtx_insn *insn, *new_insn, *next_insn;
c20f8a1d 13429
875862bf 13430 /* Do a final recompute of the frame-related data. */
ff4ce128 13431 s390_optimize_register_info ();
c20f8a1d 13432
875862bf 13433 /* If all special registers are in fact used, there's nothing we
13434 can do, so no point in walking the insn list. */
c20f8a1d 13435
ffead1ca 13436 if (cfun_frame_layout.first_save_gpr <= BASE_REGNUM
875862bf 13437 && cfun_frame_layout.last_save_gpr >= BASE_REGNUM
ffead1ca 13438 && (TARGET_CPU_ZARCH
13439 || (cfun_frame_layout.first_save_gpr <= RETURN_REGNUM
875862bf 13440 && cfun_frame_layout.last_save_gpr >= RETURN_REGNUM)))
13441 return;
c20f8a1d 13442
875862bf 13443 /* Search for prologue/epilogue insns and replace them. */
c20f8a1d 13444
875862bf 13445 for (insn = get_insns (); insn; insn = next_insn)
13446 {
13447 int first, last, off;
13448 rtx set, base, offset;
ff4ce128 13449 rtx pat;
c20f8a1d 13450
875862bf 13451 next_insn = NEXT_INSN (insn);
d7bec695 13452
ff4ce128 13453 if (! NONJUMP_INSN_P (insn) || ! RTX_FRAME_RELATED_P (insn))
875862bf 13454 continue;
c20f8a1d 13455
ff4ce128 13456 pat = PATTERN (insn);
13457
13458 /* Remove ldgr/lgdr instructions used for saving and restore
13459 GPRs if possible. */
54530437 13460 if (TARGET_Z10)
13461 {
13462 rtx tmp_pat = pat;
ff4ce128 13463
54530437 13464 if (INSN_CODE (insn) == CODE_FOR_stack_restore_from_fpr)
13465 tmp_pat = XVECEXP (pat, 0, 0);
ff4ce128 13466
54530437 13467 if (GET_CODE (tmp_pat) == SET
13468 && GET_MODE (SET_SRC (tmp_pat)) == DImode
13469 && REG_P (SET_SRC (tmp_pat))
13470 && REG_P (SET_DEST (tmp_pat)))
13471 {
13472 int src_regno = REGNO (SET_SRC (tmp_pat));
13473 int dest_regno = REGNO (SET_DEST (tmp_pat));
13474 int gpr_regno;
13475 int fpr_regno;
13476
13477 if (!((GENERAL_REGNO_P (src_regno)
13478 && FP_REGNO_P (dest_regno))
13479 || (FP_REGNO_P (src_regno)
13480 && GENERAL_REGNO_P (dest_regno))))
13481 continue;
ff4ce128 13482
54530437 13483 gpr_regno = GENERAL_REGNO_P (src_regno) ? src_regno : dest_regno;
13484 fpr_regno = FP_REGNO_P (src_regno) ? src_regno : dest_regno;
ff4ce128 13485
54530437 13486 /* GPR must be call-saved, FPR must be call-clobbered. */
13487 if (!call_really_used_regs[fpr_regno]
13488 || call_really_used_regs[gpr_regno])
13489 continue;
13490
13491 /* It must not happen that what we once saved in an FPR now
13492 needs a stack slot. */
13493 gcc_assert (cfun_gpr_save_slot (gpr_regno) != SAVE_SLOT_STACK);
13494
13495 if (cfun_gpr_save_slot (gpr_regno) == SAVE_SLOT_NONE)
13496 {
13497 remove_insn (insn);
13498 continue;
13499 }
ff4ce128 13500 }
13501 }
13502
13503 if (GET_CODE (pat) == PARALLEL
13504 && store_multiple_operation (pat, VOIDmode))
c20f8a1d 13505 {
ff4ce128 13506 set = XVECEXP (pat, 0, 0);
875862bf 13507 first = REGNO (SET_SRC (set));
ff4ce128 13508 last = first + XVECLEN (pat, 0) - 1;
875862bf 13509 offset = const0_rtx;
13510 base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
13511 off = INTVAL (offset);
c20f8a1d 13512
875862bf 13513 if (GET_CODE (base) != REG || off < 0)
13514 continue;
43944aa4 13515 if (cfun_frame_layout.first_save_gpr != -1
13516 && (cfun_frame_layout.first_save_gpr < first
13517 || cfun_frame_layout.last_save_gpr > last))
13518 continue;
875862bf 13519 if (REGNO (base) != STACK_POINTER_REGNUM
13520 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
13521 continue;
13522 if (first > BASE_REGNUM || last < BASE_REGNUM)
13523 continue;
13524
13525 if (cfun_frame_layout.first_save_gpr != -1)
c20f8a1d 13526 {
93e0956b 13527 rtx s_pat = save_gprs (base,
875862bf 13528 off + (cfun_frame_layout.first_save_gpr
b5fdc416 13529 - first) * UNITS_PER_LONG,
875862bf 13530 cfun_frame_layout.first_save_gpr,
13531 cfun_frame_layout.last_save_gpr);
93e0956b 13532 new_insn = emit_insn_before (s_pat, insn);
875862bf 13533 INSN_ADDRESSES_NEW (new_insn, -1);
c20f8a1d 13534 }
c20f8a1d 13535
875862bf 13536 remove_insn (insn);
13537 continue;
c20f8a1d 13538 }
13539
43944aa4 13540 if (cfun_frame_layout.first_save_gpr == -1
ff4ce128 13541 && GET_CODE (pat) == SET
13542 && GENERAL_REG_P (SET_SRC (pat))
13543 && GET_CODE (SET_DEST (pat)) == MEM)
c20f8a1d 13544 {
ff4ce128 13545 set = pat;
875862bf 13546 first = REGNO (SET_SRC (set));
13547 offset = const0_rtx;
13548 base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
13549 off = INTVAL (offset);
c20f8a1d 13550
875862bf 13551 if (GET_CODE (base) != REG || off < 0)
13552 continue;
13553 if (REGNO (base) != STACK_POINTER_REGNUM
13554 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
13555 continue;
c20f8a1d 13556
875862bf 13557 remove_insn (insn);
13558 continue;
c20f8a1d 13559 }
13560
ff4ce128 13561 if (GET_CODE (pat) == PARALLEL
13562 && load_multiple_operation (pat, VOIDmode))
d7bec695 13563 {
ff4ce128 13564 set = XVECEXP (pat, 0, 0);
875862bf 13565 first = REGNO (SET_DEST (set));
ff4ce128 13566 last = first + XVECLEN (pat, 0) - 1;
875862bf 13567 offset = const0_rtx;
13568 base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
13569 off = INTVAL (offset);
d7bec695 13570
875862bf 13571 if (GET_CODE (base) != REG || off < 0)
13572 continue;
ff4ce128 13573
43944aa4 13574 if (cfun_frame_layout.first_restore_gpr != -1
13575 && (cfun_frame_layout.first_restore_gpr < first
13576 || cfun_frame_layout.last_restore_gpr > last))
13577 continue;
875862bf 13578 if (REGNO (base) != STACK_POINTER_REGNUM
13579 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
13580 continue;
13581 if (first > BASE_REGNUM || last < BASE_REGNUM)
13582 continue;
c20f8a1d 13583
875862bf 13584 if (cfun_frame_layout.first_restore_gpr != -1)
13585 {
93e0956b 13586 rtx rpat = restore_gprs (base,
875862bf 13587 off + (cfun_frame_layout.first_restore_gpr
b5fdc416 13588 - first) * UNITS_PER_LONG,
875862bf 13589 cfun_frame_layout.first_restore_gpr,
13590 cfun_frame_layout.last_restore_gpr);
8240ec0e 13591
13592 /* Remove REG_CFA_RESTOREs for registers that we no
13593 longer need to save. */
93e0956b 13594 REG_NOTES (rpat) = REG_NOTES (insn);
13595 for (rtx *ptr = &REG_NOTES (rpat); *ptr; )
8240ec0e 13596 if (REG_NOTE_KIND (*ptr) == REG_CFA_RESTORE
13597 && ((int) REGNO (XEXP (*ptr, 0))
13598 < cfun_frame_layout.first_restore_gpr))
13599 *ptr = XEXP (*ptr, 1);
13600 else
13601 ptr = &XEXP (*ptr, 1);
93e0956b 13602 new_insn = emit_insn_before (rpat, insn);
8240ec0e 13603 RTX_FRAME_RELATED_P (new_insn) = 1;
875862bf 13604 INSN_ADDRESSES_NEW (new_insn, -1);
13605 }
d7bec695 13606
875862bf 13607 remove_insn (insn);
13608 continue;
d7bec695 13609 }
13610
43944aa4 13611 if (cfun_frame_layout.first_restore_gpr == -1
ff4ce128 13612 && GET_CODE (pat) == SET
13613 && GENERAL_REG_P (SET_DEST (pat))
13614 && GET_CODE (SET_SRC (pat)) == MEM)
c20f8a1d 13615 {
ff4ce128 13616 set = pat;
875862bf 13617 first = REGNO (SET_DEST (set));
13618 offset = const0_rtx;
13619 base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
13620 off = INTVAL (offset);
f81e845f 13621
875862bf 13622 if (GET_CODE (base) != REG || off < 0)
13623 continue;
ff4ce128 13624
875862bf 13625 if (REGNO (base) != STACK_POINTER_REGNUM
13626 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
13627 continue;
5a5e802f 13628
875862bf 13629 remove_insn (insn);
13630 continue;
13631 }
13632 }
5a5e802f 13633}
13634
33d033da 13635/* On z10 and later the dynamic branch prediction must see the
13636 backward jump within a certain windows. If not it falls back to
13637 the static prediction. This function rearranges the loop backward
13638 branch in a way which makes the static prediction always correct.
13639 The function returns true if it added an instruction. */
73df8a45 13640static bool
93e0956b 13641s390_fix_long_loop_prediction (rtx_insn *insn)
73df8a45 13642{
13643 rtx set = single_set (insn);
db7dd023 13644 rtx code_label, label_ref;
158a522b 13645 rtx_insn *uncond_jump;
93e0956b 13646 rtx_insn *cur_insn;
73df8a45 13647 rtx tmp;
13648 int distance;
13649
13650 /* This will exclude branch on count and branch on index patterns
13651 since these are correctly statically predicted. */
13652 if (!set
13653 || SET_DEST (set) != pc_rtx
13654 || GET_CODE (SET_SRC(set)) != IF_THEN_ELSE)
13655 return false;
13656
7a64c761 13657 /* Skip conditional returns. */
13658 if (ANY_RETURN_P (XEXP (SET_SRC (set), 1))
13659 && XEXP (SET_SRC (set), 2) == pc_rtx)
13660 return false;
13661
73df8a45 13662 label_ref = (GET_CODE (XEXP (SET_SRC (set), 1)) == LABEL_REF ?
13663 XEXP (SET_SRC (set), 1) : XEXP (SET_SRC (set), 2));
13664
13665 gcc_assert (GET_CODE (label_ref) == LABEL_REF);
13666
13667 code_label = XEXP (label_ref, 0);
13668
13669 if (INSN_ADDRESSES (INSN_UID (code_label)) == -1
13670 || INSN_ADDRESSES (INSN_UID (insn)) == -1
13671 || (INSN_ADDRESSES (INSN_UID (insn))
33d033da 13672 - INSN_ADDRESSES (INSN_UID (code_label)) < PREDICT_DISTANCE))
73df8a45 13673 return false;
13674
13675 for (distance = 0, cur_insn = PREV_INSN (insn);
33d033da 13676 distance < PREDICT_DISTANCE - 6;
73df8a45 13677 distance += get_attr_length (cur_insn), cur_insn = PREV_INSN (cur_insn))
13678 if (!cur_insn || JUMP_P (cur_insn) || LABEL_P (cur_insn))
13679 return false;
13680
db7dd023 13681 rtx_code_label *new_label = gen_label_rtx ();
73df8a45 13682 uncond_jump = emit_jump_insn_after (
d1f9b275 13683 gen_rtx_SET (pc_rtx,
73df8a45 13684 gen_rtx_LABEL_REF (VOIDmode, code_label)),
13685 insn);
13686 emit_label_after (new_label, uncond_jump);
13687
13688 tmp = XEXP (SET_SRC (set), 1);
13689 XEXP (SET_SRC (set), 1) = XEXP (SET_SRC (set), 2);
13690 XEXP (SET_SRC (set), 2) = tmp;
13691 INSN_CODE (insn) = -1;
13692
13693 XEXP (label_ref, 0) = new_label;
13694 JUMP_LABEL (insn) = new_label;
13695 JUMP_LABEL (uncond_jump) = code_label;
13696
13697 return true;
13698}
13699
3b14a2e6 13700/* Returns 1 if INSN reads the value of REG for purposes not related
13701 to addressing of memory, and 0 otherwise. */
13702static int
93e0956b 13703s390_non_addr_reg_read_p (rtx reg, rtx_insn *insn)
3b14a2e6 13704{
13705 return reg_referenced_p (reg, PATTERN (insn))
13706 && !reg_used_in_mem_p (REGNO (reg), PATTERN (insn));
13707}
13708
512d9edf 13709/* Starting from INSN find_cond_jump looks downwards in the insn
13710 stream for a single jump insn which is the last user of the
13711 condition code set in INSN. */
93e0956b 13712static rtx_insn *
13713find_cond_jump (rtx_insn *insn)
512d9edf 13714{
13715 for (; insn; insn = NEXT_INSN (insn))
13716 {
13717 rtx ite, cc;
13718
13719 if (LABEL_P (insn))
13720 break;
13721
13722 if (!JUMP_P (insn))
13723 {
13724 if (reg_mentioned_p (gen_rtx_REG (CCmode, CC_REGNUM), insn))
13725 break;
13726 continue;
13727 }
13728
13729 /* This will be triggered by a return. */
13730 if (GET_CODE (PATTERN (insn)) != SET)
13731 break;
13732
13733 gcc_assert (SET_DEST (PATTERN (insn)) == pc_rtx);
13734 ite = SET_SRC (PATTERN (insn));
13735
13736 if (GET_CODE (ite) != IF_THEN_ELSE)
13737 break;
13738
13739 cc = XEXP (XEXP (ite, 0), 0);
13740 if (!REG_P (cc) || !CC_REGNO_P (REGNO (cc)))
13741 break;
13742
13743 if (find_reg_note (insn, REG_DEAD, cc))
13744 return insn;
13745 break;
13746 }
13747
93e0956b 13748 return NULL;
512d9edf 13749}
13750
13751/* Swap the condition in COND and the operands in OP0 and OP1 so that
13752 the semantics does not change. If NULL_RTX is passed as COND the
13753 function tries to find the conditional jump starting with INSN. */
13754static void
93e0956b 13755s390_swap_cmp (rtx cond, rtx *op0, rtx *op1, rtx_insn *insn)
512d9edf 13756{
13757 rtx tmp = *op0;
13758
13759 if (cond == NULL_RTX)
13760 {
50fc2d35 13761 rtx_insn *jump = find_cond_jump (NEXT_INSN (insn));
13762 rtx set = jump ? single_set (jump) : NULL_RTX;
512d9edf 13763
50fc2d35 13764 if (set == NULL_RTX)
512d9edf 13765 return;
13766
50fc2d35 13767 cond = XEXP (SET_SRC (set), 0);
512d9edf 13768 }
13769
13770 *op0 = *op1;
13771 *op1 = tmp;
13772 PUT_CODE (cond, swap_condition (GET_CODE (cond)));
13773}
3b14a2e6 13774
13775/* On z10, instructions of the compare-and-branch family have the
13776 property to access the register occurring as second operand with
13777 its bits complemented. If such a compare is grouped with a second
13778 instruction that accesses the same register non-complemented, and
13779 if that register's value is delivered via a bypass, then the
13780 pipeline recycles, thereby causing significant performance decline.
13781 This function locates such situations and exchanges the two
73df8a45 13782 operands of the compare. The function return true whenever it
13783 added an insn. */
13784static bool
93e0956b 13785s390_z10_optimize_cmp (rtx_insn *insn)
3b14a2e6 13786{
93e0956b 13787 rtx_insn *prev_insn, *next_insn;
73df8a45 13788 bool insn_added_p = false;
13789 rtx cond, *op0, *op1;
3b14a2e6 13790
73df8a45 13791 if (GET_CODE (PATTERN (insn)) == PARALLEL)
3b14a2e6 13792 {
73df8a45 13793 /* Handle compare and branch and branch on count
13794 instructions. */
13795 rtx pattern = single_set (insn);
512d9edf 13796
73df8a45 13797 if (!pattern
13798 || SET_DEST (pattern) != pc_rtx
13799 || GET_CODE (SET_SRC (pattern)) != IF_THEN_ELSE)
13800 return false;
3b14a2e6 13801
73df8a45 13802 cond = XEXP (SET_SRC (pattern), 0);
13803 op0 = &XEXP (cond, 0);
13804 op1 = &XEXP (cond, 1);
13805 }
13806 else if (GET_CODE (PATTERN (insn)) == SET)
13807 {
13808 rtx src, dest;
3b14a2e6 13809
73df8a45 13810 /* Handle normal compare instructions. */
13811 src = SET_SRC (PATTERN (insn));
13812 dest = SET_DEST (PATTERN (insn));
512d9edf 13813
73df8a45 13814 if (!REG_P (dest)
13815 || !CC_REGNO_P (REGNO (dest))
13816 || GET_CODE (src) != COMPARE)
13817 return false;
512d9edf 13818
73df8a45 13819 /* s390_swap_cmp will try to find the conditional
13820 jump when passing NULL_RTX as condition. */
13821 cond = NULL_RTX;
13822 op0 = &XEXP (src, 0);
13823 op1 = &XEXP (src, 1);
13824 }
13825 else
13826 return false;
512d9edf 13827
73df8a45 13828 if (!REG_P (*op0) || !REG_P (*op1))
13829 return false;
512d9edf 13830
cc6056e1 13831 if (GET_MODE_CLASS (GET_MODE (*op0)) != MODE_INT)
13832 return false;
13833
73df8a45 13834 /* Swap the COMPARE arguments and its mask if there is a
13835 conflicting access in the previous insn. */
bc1c8bc5 13836 prev_insn = prev_active_insn (insn);
73df8a45 13837 if (prev_insn != NULL_RTX && INSN_P (prev_insn)
13838 && reg_referenced_p (*op1, PATTERN (prev_insn)))
13839 s390_swap_cmp (cond, op0, op1, insn);
13840
13841 /* Check if there is a conflict with the next insn. If there
13842 was no conflict with the previous insn, then swap the
13843 COMPARE arguments and its mask. If we already swapped
13844 the operands, or if swapping them would cause a conflict
13845 with the previous insn, issue a NOP after the COMPARE in
13846 order to separate the two instuctions. */
bc1c8bc5 13847 next_insn = next_active_insn (insn);
73df8a45 13848 if (next_insn != NULL_RTX && INSN_P (next_insn)
13849 && s390_non_addr_reg_read_p (*op1, next_insn))
13850 {
512d9edf 13851 if (prev_insn != NULL_RTX && INSN_P (prev_insn)
73df8a45 13852 && s390_non_addr_reg_read_p (*op0, prev_insn))
512d9edf 13853 {
73df8a45 13854 if (REGNO (*op1) == 0)
13855 emit_insn_after (gen_nop1 (), insn);
512d9edf 13856 else
73df8a45 13857 emit_insn_after (gen_nop (), insn);
13858 insn_added_p = true;
3b14a2e6 13859 }
73df8a45 13860 else
13861 s390_swap_cmp (cond, op0, op1, insn);
3b14a2e6 13862 }
73df8a45 13863 return insn_added_p;
3b14a2e6 13864}
13865
987860a9 13866/* Number of INSNs to be scanned backward in the last BB of the loop
13867 and forward in the first BB of the loop. This usually should be a
13868 bit more than the number of INSNs which could go into one
13869 group. */
13870#define S390_OSC_SCAN_INSN_NUM 5
13871
13872/* Scan LOOP for static OSC collisions and return true if a osc_break
13873 should be issued for this loop. */
13874static bool
13875s390_adjust_loop_scan_osc (struct loop* loop)
13876
13877{
13878 HARD_REG_SET modregs, newregs;
13879 rtx_insn *insn, *store_insn = NULL;
13880 rtx set;
13881 struct s390_address addr_store, addr_load;
13882 subrtx_iterator::array_type array;
13883 int insn_count;
13884
13885 CLEAR_HARD_REG_SET (modregs);
13886
13887 insn_count = 0;
13888 FOR_BB_INSNS_REVERSE (loop->latch, insn)
13889 {
13890 if (!INSN_P (insn) || INSN_CODE (insn) <= 0)
13891 continue;
13892
13893 insn_count++;
13894 if (insn_count > S390_OSC_SCAN_INSN_NUM)
13895 return false;
13896
13897 find_all_hard_reg_sets (insn, &newregs, true);
13898 IOR_HARD_REG_SET (modregs, newregs);
13899
13900 set = single_set (insn);
13901 if (!set)
13902 continue;
13903
13904 if (MEM_P (SET_DEST (set))
13905 && s390_decompose_address (XEXP (SET_DEST (set), 0), &addr_store))
13906 {
13907 store_insn = insn;
13908 break;
13909 }
13910 }
13911
13912 if (store_insn == NULL_RTX)
13913 return false;
13914
13915 insn_count = 0;
13916 FOR_BB_INSNS (loop->header, insn)
13917 {
13918 if (!INSN_P (insn) || INSN_CODE (insn) <= 0)
13919 continue;
13920
13921 if (insn == store_insn)
13922 return false;
13923
13924 insn_count++;
13925 if (insn_count > S390_OSC_SCAN_INSN_NUM)
13926 return false;
13927
13928 find_all_hard_reg_sets (insn, &newregs, true);
13929 IOR_HARD_REG_SET (modregs, newregs);
13930
13931 set = single_set (insn);
13932 if (!set)
13933 continue;
13934
13935 /* An intermediate store disrupts static OSC checking
13936 anyway. */
13937 if (MEM_P (SET_DEST (set))
13938 && s390_decompose_address (XEXP (SET_DEST (set), 0), NULL))
13939 return false;
13940
13941 FOR_EACH_SUBRTX (iter, array, SET_SRC (set), NONCONST)
13942 if (MEM_P (*iter)
13943 && s390_decompose_address (XEXP (*iter, 0), &addr_load)
13944 && rtx_equal_p (addr_load.base, addr_store.base)
13945 && rtx_equal_p (addr_load.indx, addr_store.indx)
13946 && rtx_equal_p (addr_load.disp, addr_store.disp))
13947 {
13948 if ((addr_load.base != NULL_RTX
13949 && TEST_HARD_REG_BIT (modregs, REGNO (addr_load.base)))
13950 || (addr_load.indx != NULL_RTX
13951 && TEST_HARD_REG_BIT (modregs, REGNO (addr_load.indx))))
13952 return true;
13953 }
13954 }
13955 return false;
13956}
13957
13958/* Look for adjustments which can be done on simple innermost
13959 loops. */
13960static void
13961s390_adjust_loops ()
13962{
13963 struct loop *loop = NULL;
13964
13965 df_analyze ();
13966 compute_bb_for_insn ();
13967
13968 /* Find the loops. */
13969 loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
13970
13971 FOR_EACH_LOOP (loop, LI_ONLY_INNERMOST)
13972 {
13973 if (dump_file)
13974 {
13975 flow_loop_dump (loop, dump_file, NULL, 0);
13976 fprintf (dump_file, ";; OSC loop scan Loop: ");
13977 }
13978 if (loop->latch == NULL
13979 || pc_set (BB_END (loop->latch)) == NULL_RTX
13980 || !s390_adjust_loop_scan_osc (loop))
13981 {
13982 if (dump_file)
13983 {
13984 if (loop->latch == NULL)
13985 fprintf (dump_file, " muliple backward jumps\n");
13986 else
13987 {
13988 fprintf (dump_file, " header insn: %d latch insn: %d ",
13989 INSN_UID (BB_HEAD (loop->header)),
13990 INSN_UID (BB_END (loop->latch)));
13991 if (pc_set (BB_END (loop->latch)) == NULL_RTX)
13992 fprintf (dump_file, " loop does not end with jump\n");
13993 else
13994 fprintf (dump_file, " not instrumented\n");
13995 }
13996 }
13997 }
13998 else
13999 {
14000 rtx_insn *new_insn;
14001
14002 if (dump_file)
14003 fprintf (dump_file, " adding OSC break insn: ");
14004 new_insn = emit_insn_before (gen_osc_break (),
14005 BB_END (loop->latch));
14006 INSN_ADDRESSES_NEW (new_insn, -1);
14007 }
14008 }
14009
14010 loop_optimizer_finalize ();
14011
14012 df_finish_pass (false);
14013}
14014
875862bf 14015/* Perform machine-dependent processing. */
7346ca58 14016
875862bf 14017static void
14018s390_reorg (void)
7346ca58 14019{
875862bf 14020 bool pool_overflow = false;
f4252e72 14021 int hw_before, hw_after;
7346ca58 14022
987860a9 14023 if (s390_tune == PROCESSOR_2964_Z13)
14024 s390_adjust_loops ();
14025
875862bf 14026 /* Make sure all splits have been performed; splits after
14027 machine_dependent_reorg might confuse insn length counts. */
14028 split_all_insns_noflow ();
f588eb9f 14029
875862bf 14030 /* Install the main literal pool and the associated base
14031 register load insns.
f588eb9f 14032
875862bf 14033 In addition, there are two problematic situations we need
14034 to correct:
7346ca58 14035
875862bf 14036 - the literal pool might be > 4096 bytes in size, so that
14037 some of its elements cannot be directly accessed
7346ca58 14038
875862bf 14039 - a branch target might be > 64K away from the branch, so that
14040 it is not possible to use a PC-relative instruction.
7346ca58 14041
875862bf 14042 To fix those, we split the single literal pool into multiple
14043 pool chunks, reloading the pool base register at various
14044 points throughout the function to ensure it always points to
14045 the pool chunk the following code expects, and / or replace
14046 PC-relative branches by absolute branches.
7346ca58 14047
875862bf 14048 However, the two problems are interdependent: splitting the
14049 literal pool can move a branch further away from its target,
14050 causing the 64K limit to overflow, and on the other hand,
14051 replacing a PC-relative branch by an absolute branch means
14052 we need to put the branch target address into the literal
14053 pool, possibly causing it to overflow.
44a61e21 14054
875862bf 14055 So, we loop trying to fix up both problems until we manage
14056 to satisfy both conditions at the same time. Note that the
14057 loop is guaranteed to terminate as every pass of the loop
14058 strictly decreases the total number of PC-relative branches
14059 in the function. (This is not completely true as there
14060 might be branch-over-pool insns introduced by chunkify_start.
14061 Those never need to be split however.) */
44a61e21 14062
875862bf 14063 for (;;)
14064 {
14065 struct constant_pool *pool = NULL;
80aaaa56 14066
875862bf 14067 /* Collect the literal pool. */
14068 if (!pool_overflow)
14069 {
14070 pool = s390_mainpool_start ();
14071 if (!pool)
14072 pool_overflow = true;
14073 }
80aaaa56 14074
875862bf 14075 /* If literal pool overflowed, start to chunkify it. */
14076 if (pool_overflow)
14077 pool = s390_chunkify_start ();
80aaaa56 14078
875862bf 14079 /* Split out-of-range branches. If this has created new
14080 literal pool entries, cancel current chunk list and
14081 recompute it. zSeries machines have large branch
14082 instructions, so we never need to split a branch. */
14083 if (!TARGET_CPU_ZARCH && s390_split_branches ())
14084 {
14085 if (pool_overflow)
14086 s390_chunkify_cancel (pool);
14087 else
14088 s390_mainpool_cancel (pool);
80aaaa56 14089
875862bf 14090 continue;
14091 }
14092
14093 /* If we made it up to here, both conditions are satisfied.
14094 Finish up literal pool related changes. */
14095 if (pool_overflow)
14096 s390_chunkify_finish (pool);
14097 else
14098 s390_mainpool_finish (pool);
14099
14100 /* We're done splitting branches. */
14101 cfun->machine->split_branches_pending_p = false;
14102 break;
80aaaa56 14103 }
80aaaa56 14104
babfdedf 14105 /* Generate out-of-pool execute target insns. */
14106 if (TARGET_CPU_ZARCH)
14107 {
93e0956b 14108 rtx_insn *insn, *target;
14109 rtx label;
babfdedf 14110
14111 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
14112 {
14113 label = s390_execute_label (insn);
14114 if (!label)
14115 continue;
14116
14117 gcc_assert (label != const0_rtx);
14118
14119 target = emit_label (XEXP (label, 0));
14120 INSN_ADDRESSES_NEW (target, -1);
14121
14122 target = emit_insn (s390_execute_target (insn));
14123 INSN_ADDRESSES_NEW (target, -1);
14124 }
14125 }
14126
14127 /* Try to optimize prologue and epilogue further. */
875862bf 14128 s390_optimize_prologue ();
3b14a2e6 14129
33d033da 14130 /* Walk over the insns and do some >=z10 specific changes. */
117d67d0 14131 if (s390_tune >= PROCESSOR_2097_Z10)
73df8a45 14132 {
93e0956b 14133 rtx_insn *insn;
73df8a45 14134 bool insn_added_p = false;
14135
14136 /* The insn lengths and addresses have to be up to date for the
14137 following manipulations. */
14138 shorten_branches (get_insns ());
14139
14140 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
14141 {
14142 if (!INSN_P (insn) || INSN_CODE (insn) <= 0)
14143 continue;
14144
14145 if (JUMP_P (insn))
33d033da 14146 insn_added_p |= s390_fix_long_loop_prediction (insn);
73df8a45 14147
33d033da 14148 if ((GET_CODE (PATTERN (insn)) == PARALLEL
14149 || GET_CODE (PATTERN (insn)) == SET)
14150 && s390_tune == PROCESSOR_2097_Z10)
73df8a45 14151 insn_added_p |= s390_z10_optimize_cmp (insn);
14152 }
14153
14154 /* Adjust branches if we added new instructions. */
14155 if (insn_added_p)
14156 shorten_branches (get_insns ());
14157 }
f4252e72 14158
14159 s390_function_num_hotpatch_hw (current_function_decl, &hw_before, &hw_after);
14160 if (hw_after > 0)
14161 {
14162 rtx_insn *insn;
14163
06877232 14164 /* Insert NOPs for hotpatching. */
f4252e72 14165 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8ae6e291 14166 /* Emit NOPs
14167 1. inside the area covered by debug information to allow setting
14168 breakpoints at the NOPs,
14169 2. before any insn which results in an asm instruction,
14170 3. before in-function labels to avoid jumping to the NOPs, for
14171 example as part of a loop,
14172 4. before any barrier in case the function is completely empty
14173 (__builtin_unreachable ()) and has neither internal labels nor
14174 active insns.
14175 */
14176 if (active_insn_p (insn) || BARRIER_P (insn) || LABEL_P (insn))
14177 break;
14178 /* Output a series of NOPs before the first active insn. */
14179 while (insn && hw_after > 0)
f4252e72 14180 {
14181 if (hw_after >= 3 && TARGET_CPU_ZARCH)
14182 {
8ae6e291 14183 emit_insn_before (gen_nop_6_byte (), insn);
f4252e72 14184 hw_after -= 3;
14185 }
14186 else if (hw_after >= 2)
14187 {
8ae6e291 14188 emit_insn_before (gen_nop_4_byte (), insn);
f4252e72 14189 hw_after -= 2;
14190 }
14191 else
14192 {
8ae6e291 14193 emit_insn_before (gen_nop_2_byte (), insn);
f4252e72 14194 hw_after -= 1;
14195 }
14196 }
f4252e72 14197 }
875862bf 14198}
7346ca58 14199
8a2a84e3 14200/* Return true if INSN is a fp load insn writing register REGNO. */
14201static inline bool
ed3e6e5d 14202s390_fpload_toreg (rtx_insn *insn, unsigned int regno)
8a2a84e3 14203{
14204 rtx set;
14205 enum attr_type flag = s390_safe_attr_type (insn);
14206
14207 if (flag != TYPE_FLOADSF && flag != TYPE_FLOADDF)
14208 return false;
14209
14210 set = single_set (insn);
14211
14212 if (set == NULL_RTX)
14213 return false;
14214
14215 if (!REG_P (SET_DEST (set)) || !MEM_P (SET_SRC (set)))
14216 return false;
14217
14218 if (REGNO (SET_DEST (set)) != regno)
14219 return false;
14220
14221 return true;
14222}
14223
14224/* This value describes the distance to be avoided between an
2fbe7a32 14225 arithmetic fp instruction and an fp load writing the same register.
8a2a84e3 14226 Z10_EARLYLOAD_DISTANCE - 1 as well as Z10_EARLYLOAD_DISTANCE + 1 is
14227 fine but the exact value has to be avoided. Otherwise the FP
14228 pipeline will throw an exception causing a major penalty. */
14229#define Z10_EARLYLOAD_DISTANCE 7
14230
14231/* Rearrange the ready list in order to avoid the situation described
14232 for Z10_EARLYLOAD_DISTANCE. A problematic load instruction is
14233 moved to the very end of the ready list. */
14234static void
b24ef467 14235s390_z10_prevent_earlyload_conflicts (rtx_insn **ready, int *nready_p)
8a2a84e3 14236{
14237 unsigned int regno;
14238 int nready = *nready_p;
b24ef467 14239 rtx_insn *tmp;
8a2a84e3 14240 int i;
93e0956b 14241 rtx_insn *insn;
8a2a84e3 14242 rtx set;
14243 enum attr_type flag;
14244 int distance;
14245
14246 /* Skip DISTANCE - 1 active insns. */
14247 for (insn = last_scheduled_insn, distance = Z10_EARLYLOAD_DISTANCE - 1;
14248 distance > 0 && insn != NULL_RTX;
14249 distance--, insn = prev_active_insn (insn))
14250 if (CALL_P (insn) || JUMP_P (insn))
14251 return;
14252
14253 if (insn == NULL_RTX)
14254 return;
14255
14256 set = single_set (insn);
14257
14258 if (set == NULL_RTX || !REG_P (SET_DEST (set))
14259 || GET_MODE_CLASS (GET_MODE (SET_DEST (set))) != MODE_FLOAT)
14260 return;
14261
14262 flag = s390_safe_attr_type (insn);
14263
14264 if (flag == TYPE_FLOADSF || flag == TYPE_FLOADDF)
14265 return;
14266
14267 regno = REGNO (SET_DEST (set));
14268 i = nready - 1;
14269
14270 while (!s390_fpload_toreg (ready[i], regno) && i > 0)
14271 i--;
14272
14273 if (!i)
14274 return;
14275
14276 tmp = ready[i];
b24ef467 14277 memmove (&ready[1], &ready[0], sizeof (rtx_insn *) * i);
8a2a84e3 14278 ready[0] = tmp;
14279}
14280
81769881 14281
14282/* The s390_sched_state variable tracks the state of the current or
14283 the last instruction group.
14284
14285 0,1,2 number of instructions scheduled in the current group
14286 3 the last group is complete - normal insns
14287 4 the last group was a cracked/expanded insn */
14288
14289static int s390_sched_state;
14290
0cb69051 14291#define S390_SCHED_STATE_NORMAL 3
14292#define S390_SCHED_STATE_CRACKED 4
81769881 14293
0cb69051 14294#define S390_SCHED_ATTR_MASK_CRACKED 0x1
14295#define S390_SCHED_ATTR_MASK_EXPANDED 0x2
14296#define S390_SCHED_ATTR_MASK_ENDGROUP 0x4
14297#define S390_SCHED_ATTR_MASK_GROUPALONE 0x8
81769881 14298
14299static unsigned int
d3ffa7b4 14300s390_get_sched_attrmask (rtx_insn *insn)
81769881 14301{
14302 unsigned int mask = 0;
14303
0cb69051 14304 switch (s390_tune)
14305 {
14306 case PROCESSOR_2827_ZEC12:
14307 if (get_attr_zEC12_cracked (insn))
14308 mask |= S390_SCHED_ATTR_MASK_CRACKED;
14309 if (get_attr_zEC12_expanded (insn))
14310 mask |= S390_SCHED_ATTR_MASK_EXPANDED;
14311 if (get_attr_zEC12_endgroup (insn))
14312 mask |= S390_SCHED_ATTR_MASK_ENDGROUP;
14313 if (get_attr_zEC12_groupalone (insn))
14314 mask |= S390_SCHED_ATTR_MASK_GROUPALONE;
14315 break;
14316 case PROCESSOR_2964_Z13:
a168a775 14317 case PROCESSOR_3906_Z14:
0cb69051 14318 if (get_attr_z13_cracked (insn))
14319 mask |= S390_SCHED_ATTR_MASK_CRACKED;
14320 if (get_attr_z13_expanded (insn))
14321 mask |= S390_SCHED_ATTR_MASK_EXPANDED;
14322 if (get_attr_z13_endgroup (insn))
14323 mask |= S390_SCHED_ATTR_MASK_ENDGROUP;
14324 if (get_attr_z13_groupalone (insn))
14325 mask |= S390_SCHED_ATTR_MASK_GROUPALONE;
14326 break;
14327 default:
14328 gcc_unreachable ();
14329 }
14330 return mask;
14331}
14332
14333static unsigned int
14334s390_get_unit_mask (rtx_insn *insn, int *units)
14335{
14336 unsigned int mask = 0;
14337
14338 switch (s390_tune)
14339 {
14340 case PROCESSOR_2964_Z13:
a168a775 14341 case PROCESSOR_3906_Z14:
0cb69051 14342 *units = 3;
14343 if (get_attr_z13_unit_lsu (insn))
14344 mask |= 1 << 0;
14345 if (get_attr_z13_unit_fxu (insn))
14346 mask |= 1 << 1;
14347 if (get_attr_z13_unit_vfu (insn))
14348 mask |= 1 << 2;
14349 break;
14350 default:
14351 gcc_unreachable ();
14352 }
81769881 14353 return mask;
14354}
14355
14356/* Return the scheduling score for INSN. The higher the score the
14357 better. The score is calculated from the OOO scheduling attributes
14358 of INSN and the scheduling state s390_sched_state. */
14359static int
d3ffa7b4 14360s390_sched_score (rtx_insn *insn)
81769881 14361{
14362 unsigned int mask = s390_get_sched_attrmask (insn);
14363 int score = 0;
14364
14365 switch (s390_sched_state)
14366 {
14367 case 0:
14368 /* Try to put insns into the first slot which would otherwise
14369 break a group. */
0cb69051 14370 if ((mask & S390_SCHED_ATTR_MASK_CRACKED) != 0
14371 || (mask & S390_SCHED_ATTR_MASK_EXPANDED) != 0)
81769881 14372 score += 5;
0cb69051 14373 if ((mask & S390_SCHED_ATTR_MASK_GROUPALONE) != 0)
81769881 14374 score += 10;
0903985d 14375 /* fallthrough */
81769881 14376 case 1:
14377 /* Prefer not cracked insns while trying to put together a
14378 group. */
0cb69051 14379 if ((mask & S390_SCHED_ATTR_MASK_CRACKED) == 0
14380 && (mask & S390_SCHED_ATTR_MASK_EXPANDED) == 0
14381 && (mask & S390_SCHED_ATTR_MASK_GROUPALONE) == 0)
81769881 14382 score += 10;
0cb69051 14383 if ((mask & S390_SCHED_ATTR_MASK_ENDGROUP) == 0)
81769881 14384 score += 5;
14385 break;
14386 case 2:
14387 /* Prefer not cracked insns while trying to put together a
14388 group. */
0cb69051 14389 if ((mask & S390_SCHED_ATTR_MASK_CRACKED) == 0
14390 && (mask & S390_SCHED_ATTR_MASK_EXPANDED) == 0
14391 && (mask & S390_SCHED_ATTR_MASK_GROUPALONE) == 0)
81769881 14392 score += 10;
14393 /* Prefer endgroup insns in the last slot. */
0cb69051 14394 if ((mask & S390_SCHED_ATTR_MASK_ENDGROUP) != 0)
81769881 14395 score += 10;
14396 break;
0cb69051 14397 case S390_SCHED_STATE_NORMAL:
81769881 14398 /* Prefer not cracked insns if the last was not cracked. */
0cb69051 14399 if ((mask & S390_SCHED_ATTR_MASK_CRACKED) == 0
14400 && (mask & S390_SCHED_ATTR_MASK_EXPANDED) == 0)
81769881 14401 score += 5;
0cb69051 14402 if ((mask & S390_SCHED_ATTR_MASK_GROUPALONE) != 0)
81769881 14403 score += 10;
14404 break;
0cb69051 14405 case S390_SCHED_STATE_CRACKED:
81769881 14406 /* Try to keep cracked insns together to prevent them from
14407 interrupting groups. */
0cb69051 14408 if ((mask & S390_SCHED_ATTR_MASK_CRACKED) != 0
14409 || (mask & S390_SCHED_ATTR_MASK_EXPANDED) != 0)
81769881 14410 score += 5;
14411 break;
14412 }
0cb69051 14413
c9213ca0 14414 if (s390_tune >= PROCESSOR_2964_Z13)
0cb69051 14415 {
14416 int units, i;
14417 unsigned unit_mask, m = 1;
14418
14419 unit_mask = s390_get_unit_mask (insn, &units);
14420 gcc_assert (units <= MAX_SCHED_UNITS);
14421
14422 /* Add a score in range 0..MAX_SCHED_MIX_SCORE depending on how long
14423 ago the last insn of this unit type got scheduled. This is
14424 supposed to help providing a proper instruction mix to the
14425 CPU. */
14426 for (i = 0; i < units; i++, m <<= 1)
14427 if (m & unit_mask)
14428 score += (last_scheduled_unit_distance[i] * MAX_SCHED_MIX_SCORE /
14429 MAX_SCHED_MIX_DISTANCE);
14430 }
81769881 14431 return score;
14432}
14433
8a2a84e3 14434/* This function is called via hook TARGET_SCHED_REORDER before
4246a5c7 14435 issuing one insn from list READY which contains *NREADYP entries.
8a2a84e3 14436 For target z10 it reorders load instructions to avoid early load
14437 conflicts in the floating point pipeline */
14438static int
81769881 14439s390_sched_reorder (FILE *file, int verbose,
b24ef467 14440 rtx_insn **ready, int *nreadyp, int clock ATTRIBUTE_UNUSED)
8a2a84e3 14441{
117d67d0 14442 if (s390_tune == PROCESSOR_2097_Z10
14443 && reload_completed
14444 && *nreadyp > 1)
14445 s390_z10_prevent_earlyload_conflicts (ready, nreadyp);
8a2a84e3 14446
117d67d0 14447 if (s390_tune >= PROCESSOR_2827_ZEC12
81769881 14448 && reload_completed
14449 && *nreadyp > 1)
14450 {
14451 int i;
14452 int last_index = *nreadyp - 1;
14453 int max_index = -1;
14454 int max_score = -1;
b24ef467 14455 rtx_insn *tmp;
81769881 14456
14457 /* Just move the insn with the highest score to the top (the
14458 end) of the list. A full sort is not needed since a conflict
14459 in the hazard recognition cannot happen. So the top insn in
14460 the ready list will always be taken. */
14461 for (i = last_index; i >= 0; i--)
14462 {
14463 int score;
14464
14465 if (recog_memoized (ready[i]) < 0)
14466 continue;
14467
14468 score = s390_sched_score (ready[i]);
14469 if (score > max_score)
14470 {
14471 max_score = score;
14472 max_index = i;
14473 }
14474 }
14475
14476 if (max_index != -1)
14477 {
14478 if (max_index != last_index)
14479 {
14480 tmp = ready[max_index];
14481 ready[max_index] = ready[last_index];
14482 ready[last_index] = tmp;
14483
14484 if (verbose > 5)
14485 fprintf (file,
0cb69051 14486 ";;\t\tBACKEND: move insn %d to the top of list\n",
81769881 14487 INSN_UID (ready[last_index]));
14488 }
14489 else if (verbose > 5)
14490 fprintf (file,
0cb69051 14491 ";;\t\tBACKEND: best insn %d already on top\n",
81769881 14492 INSN_UID (ready[last_index]));
14493 }
14494
14495 if (verbose > 5)
14496 {
14497 fprintf (file, "ready list ooo attributes - sched state: %d\n",
14498 s390_sched_state);
14499
14500 for (i = last_index; i >= 0; i--)
14501 {
0cb69051 14502 unsigned int sched_mask;
14503 rtx_insn *insn = ready[i];
14504
14505 if (recog_memoized (insn) < 0)
81769881 14506 continue;
0cb69051 14507
14508 sched_mask = s390_get_sched_attrmask (insn);
14509 fprintf (file, ";;\t\tBACKEND: insn %d score: %d: ",
14510 INSN_UID (insn),
14511 s390_sched_score (insn));
14512#define PRINT_SCHED_ATTR(M, ATTR) fprintf (file, "%s ",\
14513 ((M) & sched_mask) ? #ATTR : "");
14514 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_CRACKED, cracked);
14515 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_EXPANDED, expanded);
14516 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_ENDGROUP, endgroup);
14517 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_GROUPALONE, groupalone);
14518#undef PRINT_SCHED_ATTR
c9213ca0 14519 if (s390_tune >= PROCESSOR_2964_Z13)
0cb69051 14520 {
14521 unsigned int unit_mask, m = 1;
14522 int units, j;
14523
14524 unit_mask = s390_get_unit_mask (insn, &units);
14525 fprintf (file, "(units:");
14526 for (j = 0; j < units; j++, m <<= 1)
14527 if (m & unit_mask)
14528 fprintf (file, " u%d", j);
14529 fprintf (file, ")");
14530 }
81769881 14531 fprintf (file, "\n");
14532 }
14533 }
14534 }
14535
8a2a84e3 14536 return s390_issue_rate ();
14537}
14538
81769881 14539
8a2a84e3 14540/* This function is called via hook TARGET_SCHED_VARIABLE_ISSUE after
14541 the scheduler has issued INSN. It stores the last issued insn into
14542 last_scheduled_insn in order to make it available for
14543 s390_sched_reorder. */
14544static int
18282db0 14545s390_sched_variable_issue (FILE *file, int verbose, rtx_insn *insn, int more)
8a2a84e3 14546{
14547 last_scheduled_insn = insn;
14548
117d67d0 14549 if (s390_tune >= PROCESSOR_2827_ZEC12
81769881 14550 && reload_completed
14551 && recog_memoized (insn) >= 0)
14552 {
14553 unsigned int mask = s390_get_sched_attrmask (insn);
14554
0cb69051 14555 if ((mask & S390_SCHED_ATTR_MASK_CRACKED) != 0
14556 || (mask & S390_SCHED_ATTR_MASK_EXPANDED) != 0)
14557 s390_sched_state = S390_SCHED_STATE_CRACKED;
14558 else if ((mask & S390_SCHED_ATTR_MASK_ENDGROUP) != 0
14559 || (mask & S390_SCHED_ATTR_MASK_GROUPALONE) != 0)
14560 s390_sched_state = S390_SCHED_STATE_NORMAL;
81769881 14561 else
14562 {
14563 /* Only normal insns are left (mask == 0). */
14564 switch (s390_sched_state)
14565 {
14566 case 0:
14567 case 1:
14568 case 2:
0cb69051 14569 case S390_SCHED_STATE_NORMAL:
14570 if (s390_sched_state == S390_SCHED_STATE_NORMAL)
81769881 14571 s390_sched_state = 1;
14572 else
14573 s390_sched_state++;
14574
14575 break;
0cb69051 14576 case S390_SCHED_STATE_CRACKED:
14577 s390_sched_state = S390_SCHED_STATE_NORMAL;
81769881 14578 break;
14579 }
14580 }
0cb69051 14581
c9213ca0 14582 if (s390_tune >= PROCESSOR_2964_Z13)
0cb69051 14583 {
14584 int units, i;
14585 unsigned unit_mask, m = 1;
14586
14587 unit_mask = s390_get_unit_mask (insn, &units);
14588 gcc_assert (units <= MAX_SCHED_UNITS);
14589
14590 for (i = 0; i < units; i++, m <<= 1)
14591 if (m & unit_mask)
14592 last_scheduled_unit_distance[i] = 0;
14593 else if (last_scheduled_unit_distance[i] < MAX_SCHED_MIX_DISTANCE)
14594 last_scheduled_unit_distance[i]++;
14595 }
14596
81769881 14597 if (verbose > 5)
14598 {
0cb69051 14599 unsigned int sched_mask;
14600
14601 sched_mask = s390_get_sched_attrmask (insn);
14602
14603 fprintf (file, ";;\t\tBACKEND: insn %d: ", INSN_UID (insn));
14604#define PRINT_SCHED_ATTR(M, ATTR) fprintf (file, "%s ", ((M) & sched_mask) ? #ATTR : "");
14605 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_CRACKED, cracked);
14606 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_EXPANDED, expanded);
14607 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_ENDGROUP, endgroup);
14608 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_GROUPALONE, groupalone);
14609#undef PRINT_SCHED_ATTR
14610
c9213ca0 14611 if (s390_tune >= PROCESSOR_2964_Z13)
0cb69051 14612 {
14613 unsigned int unit_mask, m = 1;
14614 int units, j;
14615
14616 unit_mask = s390_get_unit_mask (insn, &units);
14617 fprintf (file, "(units:");
14618 for (j = 0; j < units; j++, m <<= 1)
14619 if (m & unit_mask)
14620 fprintf (file, " %d", j);
14621 fprintf (file, ")");
14622 }
14623 fprintf (file, " sched state: %d\n", s390_sched_state);
14624
c9213ca0 14625 if (s390_tune >= PROCESSOR_2964_Z13)
0cb69051 14626 {
14627 int units, j;
14628
14629 s390_get_unit_mask (insn, &units);
14630
14631 fprintf (file, ";;\t\tBACKEND: units unused for: ");
14632 for (j = 0; j < units; j++)
14633 fprintf (file, "%d:%d ", j, last_scheduled_unit_distance[j]);
14634 fprintf (file, "\n");
14635 }
81769881 14636 }
14637 }
14638
8a2a84e3 14639 if (GET_CODE (PATTERN (insn)) != USE
14640 && GET_CODE (PATTERN (insn)) != CLOBBER)
14641 return more - 1;
14642 else
14643 return more;
14644}
7346ca58 14645
494d0169 14646static void
14647s390_sched_init (FILE *file ATTRIBUTE_UNUSED,
14648 int verbose ATTRIBUTE_UNUSED,
14649 int max_ready ATTRIBUTE_UNUSED)
14650{
93e0956b 14651 last_scheduled_insn = NULL;
0cb69051 14652 memset (last_scheduled_unit_distance, 0, MAX_SCHED_UNITS * sizeof (int));
81769881 14653 s390_sched_state = 0;
494d0169 14654}
14655
9ccaa774 14656/* This target hook implementation for TARGET_LOOP_UNROLL_ADJUST calculates
33d033da 14657 a new number struct loop *loop should be unrolled if tuned for cpus with
14658 a built-in stride prefetcher.
14659 The loop is analyzed for memory accesses by calling check_dpu for
9ccaa774 14660 each rtx of the loop. Depending on the loop_depth and the amount of
14661 memory accesses a new number <=nunroll is returned to improve the
67cf9b55 14662 behavior of the hardware prefetch unit. */
9ccaa774 14663static unsigned
14664s390_loop_unroll_adjust (unsigned nunroll, struct loop *loop)
14665{
14666 basic_block *bbs;
93e0956b 14667 rtx_insn *insn;
9ccaa774 14668 unsigned i;
14669 unsigned mem_count = 0;
14670
117d67d0 14671 if (s390_tune < PROCESSOR_2097_Z10)
9ccaa774 14672 return nunroll;
14673
14674 /* Count the number of memory references within the loop body. */
14675 bbs = get_loop_body (loop);
15e472ec 14676 subrtx_iterator::array_type array;
9ccaa774 14677 for (i = 0; i < loop->num_nodes; i++)
15e472ec 14678 FOR_BB_INSNS (bbs[i], insn)
14679 if (INSN_P (insn) && INSN_CODE (insn) != -1)
14680 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
14681 if (MEM_P (*iter))
14682 mem_count += 1;
9ccaa774 14683 free (bbs);
14684
14685 /* Prevent division by zero, and we do not need to adjust nunroll in this case. */
14686 if (mem_count == 0)
14687 return nunroll;
14688
14689 switch (loop_depth(loop))
14690 {
14691 case 1:
14692 return MIN (nunroll, 28 / mem_count);
14693 case 2:
14694 return MIN (nunroll, 22 / mem_count);
14695 default:
14696 return MIN (nunroll, 16 / mem_count);
14697 }
14698}
14699
7a0cee35 14700/* Restore the current options. This is a hook function and also called
14701 internally. */
14702
0b8be04c 14703static void
7a0cee35 14704s390_function_specific_restore (struct gcc_options *opts,
14705 struct cl_target_option *ptr ATTRIBUTE_UNUSED)
0b8be04c 14706{
7a0cee35 14707 opts->x_s390_cost_pointer = (long)processor_table[opts->x_s390_tune].cost;
14708}
0b8be04c 14709
7a0cee35 14710static void
3bd8520f 14711s390_option_override_internal (bool main_args_p,
14712 struct gcc_options *opts,
7a0cee35 14713 const struct gcc_options *opts_set)
14714{
3bd8520f 14715 const char *prefix;
14716 const char *suffix;
14717
14718 /* Set up prefix/suffix so the error messages refer to either the command
14719 line argument, or the attribute(target). */
14720 if (main_args_p)
14721 {
14722 prefix = "-m";
14723 suffix = "";
14724 }
14725 else
14726 {
14727 prefix = "option(\"";
14728 suffix = "\")";
14729 }
14730
14731
0b8be04c 14732 /* Architecture mode defaults according to ABI. */
7a0cee35 14733 if (!(opts_set->x_target_flags & MASK_ZARCH))
0b8be04c 14734 {
14735 if (TARGET_64BIT)
7a0cee35 14736 opts->x_target_flags |= MASK_ZARCH;
0b8be04c 14737 else
7a0cee35 14738 opts->x_target_flags &= ~MASK_ZARCH;
0b8be04c 14739 }
14740
7a0cee35 14741 /* Set the march default in case it hasn't been specified on cmdline. */
14742 if (!opts_set->x_s390_arch)
3bd8520f 14743 opts->x_s390_arch = PROCESSOR_2064_Z900;
14744 else if (opts->x_s390_arch == PROCESSOR_9672_G5
14745 || opts->x_s390_arch == PROCESSOR_9672_G6)
14746 warning (OPT_Wdeprecated, "%sarch=%s%s is deprecated and will be removed "
14747 "in future releases; use at least %sarch=z900%s",
14748 prefix, opts->x_s390_arch == PROCESSOR_9672_G5 ? "g5" : "g6",
14749 suffix, prefix, suffix);
14750
7a0cee35 14751 opts->x_s390_arch_flags = processor_flags_table[(int) opts->x_s390_arch];
0b8be04c 14752
14753 /* Determine processor to tune for. */
7a0cee35 14754 if (!opts_set->x_s390_tune)
14755 opts->x_s390_tune = opts->x_s390_arch;
3bd8520f 14756 else if (opts->x_s390_tune == PROCESSOR_9672_G5
14757 || opts->x_s390_tune == PROCESSOR_9672_G6)
14758 warning (OPT_Wdeprecated, "%stune=%s%s is deprecated and will be removed "
14759 "in future releases; use at least %stune=z900%s",
14760 prefix, opts->x_s390_tune == PROCESSOR_9672_G5 ? "g5" : "g6",
14761 suffix, prefix, suffix);
14762
7a0cee35 14763 opts->x_s390_tune_flags = processor_flags_table[opts->x_s390_tune];
0b8be04c 14764
14765 /* Sanity checks. */
7a0cee35 14766 if (opts->x_s390_arch == PROCESSOR_NATIVE
14767 || opts->x_s390_tune == PROCESSOR_NATIVE)
db249f37 14768 gcc_unreachable ();
7a0cee35 14769 if (TARGET_ZARCH_P (opts->x_target_flags) && !TARGET_CPU_ZARCH_P (opts))
14770 error ("z/Architecture mode not supported on %s",
14771 processor_table[(int)opts->x_s390_arch].name);
14772 if (TARGET_64BIT && !TARGET_ZARCH_P (opts->x_target_flags))
0b8be04c 14773 error ("64-bit ABI not supported in ESA/390 mode");
14774
0b8be04c 14775 /* Enable hardware transactions if available and not explicitly
14776 disabled by user. E.g. with -m31 -march=zEC12 -mzarch */
7a0cee35 14777 if (!TARGET_OPT_HTM_P (opts_set->x_target_flags))
14778 {
14779 if (TARGET_CPU_HTM_P (opts) && TARGET_ZARCH_P (opts->x_target_flags))
14780 opts->x_target_flags |= MASK_OPT_HTM;
14781 else
14782 opts->x_target_flags &= ~MASK_OPT_HTM;
14783 }
0b8be04c 14784
7a0cee35 14785 if (TARGET_OPT_VX_P (opts_set->x_target_flags))
cc79fcc9 14786 {
7a0cee35 14787 if (TARGET_OPT_VX_P (opts->x_target_flags))
cc79fcc9 14788 {
7a0cee35 14789 if (!TARGET_CPU_VX_P (opts))
cc79fcc9 14790 error ("hardware vector support not available on %s",
7a0cee35 14791 processor_table[(int)opts->x_s390_arch].name);
14792 if (TARGET_SOFT_FLOAT_P (opts->x_target_flags))
cc79fcc9 14793 error ("hardware vector support not available with -msoft-float");
14794 }
14795 }
7a0cee35 14796 else
14797 {
14798 if (TARGET_CPU_VX_P (opts))
14799 /* Enable vector support if available and not explicitly disabled
14800 by user. E.g. with -m31 -march=z13 -mzarch */
14801 opts->x_target_flags |= MASK_OPT_VX;
14802 else
14803 opts->x_target_flags &= ~MASK_OPT_VX;
14804 }
cc79fcc9 14805
7a0cee35 14806 /* Use hardware DFP if available and not explicitly disabled by
14807 user. E.g. with -m31 -march=z10 -mzarch */
14808 if (!TARGET_HARD_DFP_P (opts_set->x_target_flags))
14809 {
14810 if (TARGET_DFP_P (opts))
14811 opts->x_target_flags |= MASK_HARD_DFP;
14812 else
14813 opts->x_target_flags &= ~MASK_HARD_DFP;
14814 }
14815
14816 if (TARGET_HARD_DFP_P (opts->x_target_flags) && !TARGET_DFP_P (opts))
0b8be04c 14817 {
7a0cee35 14818 if (TARGET_HARD_DFP_P (opts_set->x_target_flags))
0b8be04c 14819 {
7a0cee35 14820 if (!TARGET_CPU_DFP_P (opts))
0b8be04c 14821 error ("hardware decimal floating point instructions"
7a0cee35 14822 " not available on %s",
14823 processor_table[(int)opts->x_s390_arch].name);
14824 if (!TARGET_ZARCH_P (opts->x_target_flags))
0b8be04c 14825 error ("hardware decimal floating point instructions"
14826 " not available in ESA/390 mode");
14827 }
14828 else
7a0cee35 14829 opts->x_target_flags &= ~MASK_HARD_DFP;
0b8be04c 14830 }
14831
7a0cee35 14832 if (TARGET_SOFT_FLOAT_P (opts_set->x_target_flags)
14833 && TARGET_SOFT_FLOAT_P (opts->x_target_flags))
0b8be04c 14834 {
7a0cee35 14835 if (TARGET_HARD_DFP_P (opts_set->x_target_flags)
14836 && TARGET_HARD_DFP_P (opts->x_target_flags))
0b8be04c 14837 error ("-mhard-dfp can%'t be used in conjunction with -msoft-float");
14838
7a0cee35 14839 opts->x_target_flags &= ~MASK_HARD_DFP;
0b8be04c 14840 }
14841
7a0cee35 14842 if (TARGET_BACKCHAIN_P (opts->x_target_flags)
14843 && TARGET_PACKED_STACK_P (opts->x_target_flags)
14844 && TARGET_HARD_FLOAT_P (opts->x_target_flags))
0b8be04c 14845 error ("-mbackchain -mpacked-stack -mhard-float are not supported "
14846 "in combination");
14847
7a0cee35 14848 if (opts->x_s390_stack_size)
0b8be04c 14849 {
7a0cee35 14850 if (opts->x_s390_stack_guard >= opts->x_s390_stack_size)
0b8be04c 14851 error ("stack size must be greater than the stack guard value");
7a0cee35 14852 else if (opts->x_s390_stack_size > 1 << 16)
0b8be04c 14853 error ("stack size must not be greater than 64k");
14854 }
7a0cee35 14855 else if (opts->x_s390_stack_guard)
0b8be04c 14856 error ("-mstack-guard implies use of -mstack-size");
14857
14858#ifdef TARGET_DEFAULT_LONG_DOUBLE_128
7a0cee35 14859 if (!TARGET_LONG_DOUBLE_128_P (opts_set->x_target_flags))
14860 opts->x_target_flags |= MASK_LONG_DOUBLE_128;
0b8be04c 14861#endif
14862
7a0cee35 14863 if (opts->x_s390_tune >= PROCESSOR_2097_Z10)
0b8be04c 14864 {
14865 maybe_set_param_value (PARAM_MAX_UNROLLED_INSNS, 100,
7a0cee35 14866 opts->x_param_values,
14867 opts_set->x_param_values);
0b8be04c 14868 maybe_set_param_value (PARAM_MAX_UNROLL_TIMES, 32,
7a0cee35 14869 opts->x_param_values,
14870 opts_set->x_param_values);
0b8be04c 14871 maybe_set_param_value (PARAM_MAX_COMPLETELY_PEELED_INSNS, 2000,
7a0cee35 14872 opts->x_param_values,
14873 opts_set->x_param_values);
0b8be04c 14874 maybe_set_param_value (PARAM_MAX_COMPLETELY_PEEL_TIMES, 64,
7a0cee35 14875 opts->x_param_values,
14876 opts_set->x_param_values);
0b8be04c 14877 }
14878
14879 maybe_set_param_value (PARAM_MAX_PENDING_LIST_LENGTH, 256,
7a0cee35 14880 opts->x_param_values,
14881 opts_set->x_param_values);
0b8be04c 14882 /* values for loop prefetching */
14883 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE, 256,
7a0cee35 14884 opts->x_param_values,
14885 opts_set->x_param_values);
0b8be04c 14886 maybe_set_param_value (PARAM_L1_CACHE_SIZE, 128,
7a0cee35 14887 opts->x_param_values,
14888 opts_set->x_param_values);
0b8be04c 14889 /* s390 has more than 2 levels and the size is much larger. Since
14890 we are always running virtualized assume that we only get a small
14891 part of the caches above l1. */
14892 maybe_set_param_value (PARAM_L2_CACHE_SIZE, 1500,
7a0cee35 14893 opts->x_param_values,
14894 opts_set->x_param_values);
0b8be04c 14895 maybe_set_param_value (PARAM_PREFETCH_MIN_INSN_TO_MEM_RATIO, 2,
7a0cee35 14896 opts->x_param_values,
14897 opts_set->x_param_values);
0b8be04c 14898 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES, 6,
7a0cee35 14899 opts->x_param_values,
14900 opts_set->x_param_values);
14901
14902 /* Use the alternative scheduling-pressure algorithm by default. */
14903 maybe_set_param_value (PARAM_SCHED_PRESSURE_ALGORITHM, 2,
14904 opts->x_param_values,
14905 opts_set->x_param_values);
14906
e328d74f 14907 maybe_set_param_value (PARAM_MIN_VECT_LOOP_BOUND, 2,
14908 opts->x_param_values,
14909 opts_set->x_param_values);
14910
7a0cee35 14911 /* Call target specific restore function to do post-init work. At the moment,
14912 this just sets opts->x_s390_cost_pointer. */
14913 s390_function_specific_restore (opts, NULL);
14914}
14915
14916static void
14917s390_option_override (void)
14918{
14919 unsigned int i;
14920 cl_deferred_option *opt;
14921 vec<cl_deferred_option> *v =
14922 (vec<cl_deferred_option> *) s390_deferred_options;
14923
14924 if (v)
14925 FOR_EACH_VEC_ELT (*v, i, opt)
14926 {
14927 switch (opt->opt_index)
14928 {
14929 case OPT_mhotpatch_:
14930 {
14931 int val1;
14932 int val2;
14933 char s[256];
14934 char *t;
14935
14936 strncpy (s, opt->arg, 256);
14937 s[255] = 0;
14938 t = strchr (s, ',');
14939 if (t != NULL)
14940 {
14941 *t = 0;
14942 t++;
14943 val1 = integral_argument (s);
14944 val2 = integral_argument (t);
14945 }
14946 else
14947 {
14948 val1 = -1;
14949 val2 = -1;
14950 }
14951 if (val1 == -1 || val2 == -1)
14952 {
14953 /* argument is not a plain number */
14954 error ("arguments to %qs should be non-negative integers",
14955 "-mhotpatch=n,m");
14956 break;
14957 }
14958 else if (val1 > s390_hotpatch_hw_max
14959 || val2 > s390_hotpatch_hw_max)
14960 {
14961 error ("argument to %qs is too large (max. %d)",
14962 "-mhotpatch=n,m", s390_hotpatch_hw_max);
14963 break;
14964 }
14965 s390_hotpatch_hw_before_label = val1;
14966 s390_hotpatch_hw_after_label = val2;
14967 break;
14968 }
14969 default:
14970 gcc_unreachable ();
14971 }
14972 }
14973
14974 /* Set up function hooks. */
14975 init_machine_status = s390_init_machine_status;
14976
3bd8520f 14977 s390_option_override_internal (true, &global_options, &global_options_set);
7a0cee35 14978
14979 /* Save the initial options in case the user does function specific
14980 options. */
14981 target_option_default_node = build_target_option_node (&global_options);
14982 target_option_current_node = target_option_default_node;
0b8be04c 14983
14984 /* This cannot reside in s390_option_optimization_table since HAVE_prefetch
14985 requires the arch flags to be evaluated already. Since prefetching
14986 is beneficial on s390, we enable it if available. */
14987 if (flag_prefetch_loop_arrays < 0 && HAVE_prefetch && optimize >= 3)
14988 flag_prefetch_loop_arrays = 1;
14989
9852c8ae 14990 if (!s390_pic_data_is_text_relative && !flag_pic)
14991 error ("-mno-pic-data-is-text-relative cannot be used without -fpic/-fPIC");
14992
0b8be04c 14993 if (TARGET_TPF)
14994 {
14995 /* Don't emit DWARF3/4 unless specifically selected. The TPF
14996 debuggers do not yet support DWARF 3/4. */
14997 if (!global_options_set.x_dwarf_strict)
14998 dwarf_strict = 1;
14999 if (!global_options_set.x_dwarf_version)
15000 dwarf_version = 2;
15001 }
15002
15003 /* Register a target-specific optimization-and-lowering pass
15004 to run immediately before prologue and epilogue generation.
15005
15006 Registering the pass must be done at start up. It's
15007 convenient to do it here. */
15008 opt_pass *new_pass = new pass_s390_early_mach (g);
15009 struct register_pass_info insert_pass_s390_early_mach =
15010 {
15011 new_pass, /* pass */
15012 "pro_and_epilogue", /* reference_pass_name */
15013 1, /* ref_pass_instance_number */
15014 PASS_POS_INSERT_BEFORE /* po_op */
15015 };
15016 register_pass (&insert_pass_s390_early_mach);
15017}
15018
7a0cee35 15019#if S390_USE_TARGET_ATTRIBUTE
15020/* Inner function to process the attribute((target(...))), take an argument and
15021 set the current options from the argument. If we have a list, recursively go
15022 over the list. */
15023
15024static bool
15025s390_valid_target_attribute_inner_p (tree args,
15026 struct gcc_options *opts,
15027 struct gcc_options *new_opts_set,
15028 bool force_pragma)
15029{
15030 char *next_optstr;
15031 bool ret = true;
15032
15033#define S390_ATTRIB(S,O,A) { S, sizeof (S)-1, O, A, 0 }
15034#define S390_PRAGMA(S,O,A) { S, sizeof (S)-1, O, A, 1 }
15035 static const struct
15036 {
15037 const char *string;
15038 size_t len;
15039 int opt;
15040 int has_arg;
15041 int only_as_pragma;
15042 } attrs[] = {
15043 /* enum options */
15044 S390_ATTRIB ("arch=", OPT_march_, 1),
15045 S390_ATTRIB ("tune=", OPT_mtune_, 1),
15046 /* uinteger options */
15047 S390_ATTRIB ("stack-guard=", OPT_mstack_guard_, 1),
15048 S390_ATTRIB ("stack-size=", OPT_mstack_size_, 1),
15049 S390_ATTRIB ("branch-cost=", OPT_mbranch_cost_, 1),
15050 S390_ATTRIB ("warn-framesize=", OPT_mwarn_framesize_, 1),
15051 /* flag options */
15052 S390_ATTRIB ("backchain", OPT_mbackchain, 0),
15053 S390_ATTRIB ("hard-dfp", OPT_mhard_dfp, 0),
15054 S390_ATTRIB ("hard-float", OPT_mhard_float, 0),
15055 S390_ATTRIB ("htm", OPT_mhtm, 0),
15056 S390_ATTRIB ("vx", OPT_mvx, 0),
15057 S390_ATTRIB ("packed-stack", OPT_mpacked_stack, 0),
15058 S390_ATTRIB ("small-exec", OPT_msmall_exec, 0),
15059 S390_ATTRIB ("soft-float", OPT_msoft_float, 0),
15060 S390_ATTRIB ("mvcle", OPT_mmvcle, 0),
15061 S390_PRAGMA ("zvector", OPT_mzvector, 0),
15062 /* boolean options */
15063 S390_ATTRIB ("warn-dynamicstack", OPT_mwarn_dynamicstack, 0),
15064 };
15065#undef S390_ATTRIB
15066#undef S390_PRAGMA
15067
15068 /* If this is a list, recurse to get the options. */
15069 if (TREE_CODE (args) == TREE_LIST)
15070 {
15071 bool ret = true;
15072 int num_pragma_values;
15073 int i;
15074
15075 /* Note: attribs.c:decl_attributes prepends the values from
15076 current_target_pragma to the list of target attributes. To determine
15077 whether we're looking at a value of the attribute or the pragma we
15078 assume that the first [list_length (current_target_pragma)] values in
15079 the list are the values from the pragma. */
15080 num_pragma_values = (!force_pragma && current_target_pragma != NULL)
15081 ? list_length (current_target_pragma) : 0;
15082 for (i = 0; args; args = TREE_CHAIN (args), i++)
15083 {
15084 bool is_pragma;
15085
15086 is_pragma = (force_pragma || i < num_pragma_values);
15087 if (TREE_VALUE (args)
15088 && !s390_valid_target_attribute_inner_p (TREE_VALUE (args),
15089 opts, new_opts_set,
15090 is_pragma))
15091 {
15092 ret = false;
15093 }
15094 }
15095 return ret;
15096 }
15097
15098 else if (TREE_CODE (args) != STRING_CST)
15099 {
15100 error ("attribute %<target%> argument not a string");
15101 return false;
15102 }
15103
15104 /* Handle multiple arguments separated by commas. */
15105 next_optstr = ASTRDUP (TREE_STRING_POINTER (args));
15106
15107 while (next_optstr && *next_optstr != '\0')
15108 {
15109 char *p = next_optstr;
15110 char *orig_p = p;
15111 char *comma = strchr (next_optstr, ',');
15112 size_t len, opt_len;
15113 int opt;
15114 bool opt_set_p;
15115 char ch;
15116 unsigned i;
15117 int mask = 0;
15118 enum cl_var_type var_type;
15119 bool found;
15120
15121 if (comma)
15122 {
15123 *comma = '\0';
15124 len = comma - next_optstr;
15125 next_optstr = comma + 1;
15126 }
15127 else
15128 {
15129 len = strlen (p);
15130 next_optstr = NULL;
15131 }
15132
15133 /* Recognize no-xxx. */
15134 if (len > 3 && p[0] == 'n' && p[1] == 'o' && p[2] == '-')
15135 {
15136 opt_set_p = false;
15137 p += 3;
15138 len -= 3;
15139 }
15140 else
15141 opt_set_p = true;
15142
15143 /* Find the option. */
15144 ch = *p;
15145 found = false;
15146 for (i = 0; i < ARRAY_SIZE (attrs); i++)
15147 {
15148 opt_len = attrs[i].len;
15149 if (ch == attrs[i].string[0]
15150 && ((attrs[i].has_arg) ? len > opt_len : len == opt_len)
15151 && memcmp (p, attrs[i].string, opt_len) == 0)
15152 {
15153 opt = attrs[i].opt;
15154 if (!opt_set_p && cl_options[opt].cl_reject_negative)
15155 continue;
15156 mask = cl_options[opt].var_value;
15157 var_type = cl_options[opt].var_type;
15158 found = true;
15159 break;
15160 }
15161 }
15162
15163 /* Process the option. */
15164 if (!found)
15165 {
15166 error ("attribute(target(\"%s\")) is unknown", orig_p);
15167 return false;
15168 }
15169 else if (attrs[i].only_as_pragma && !force_pragma)
15170 {
15171 /* Value is not allowed for the target attribute. */
19abb0ad 15172 error ("value %qs is not supported by attribute %<target%>",
7a0cee35 15173 attrs[i].string);
15174 return false;
15175 }
15176
15177 else if (var_type == CLVC_BIT_SET || var_type == CLVC_BIT_CLEAR)
15178 {
15179 if (var_type == CLVC_BIT_CLEAR)
15180 opt_set_p = !opt_set_p;
15181
15182 if (opt_set_p)
15183 opts->x_target_flags |= mask;
15184 else
15185 opts->x_target_flags &= ~mask;
15186 new_opts_set->x_target_flags |= mask;
15187 }
15188
15189 else if (cl_options[opt].var_type == CLVC_BOOLEAN)
15190 {
15191 int value;
15192
15193 if (cl_options[opt].cl_uinteger)
15194 {
15195 /* Unsigned integer argument. Code based on the function
15196 decode_cmdline_option () in opts-common.c. */
15197 value = integral_argument (p + opt_len);
15198 }
15199 else
15200 value = (opt_set_p) ? 1 : 0;
15201
15202 if (value != -1)
15203 {
15204 struct cl_decoded_option decoded;
15205
15206 /* Value range check; only implemented for numeric and boolean
15207 options at the moment. */
15208 generate_option (opt, NULL, value, CL_TARGET, &decoded);
15209 s390_handle_option (opts, new_opts_set, &decoded, input_location);
15210 set_option (opts, new_opts_set, opt, value,
15211 p + opt_len, DK_UNSPECIFIED, input_location,
15212 global_dc);
15213 }
15214 else
15215 {
15216 error ("attribute(target(\"%s\")) is unknown", orig_p);
15217 ret = false;
15218 }
15219 }
15220
15221 else if (cl_options[opt].var_type == CLVC_ENUM)
15222 {
15223 bool arg_ok;
15224 int value;
15225
15226 arg_ok = opt_enum_arg_to_value (opt, p + opt_len, &value, CL_TARGET);
15227 if (arg_ok)
15228 set_option (opts, new_opts_set, opt, value,
15229 p + opt_len, DK_UNSPECIFIED, input_location,
15230 global_dc);
15231 else
15232 {
15233 error ("attribute(target(\"%s\")) is unknown", orig_p);
15234 ret = false;
15235 }
15236 }
15237
15238 else
15239 gcc_unreachable ();
15240 }
15241 return ret;
15242}
15243
15244/* Return a TARGET_OPTION_NODE tree of the target options listed or NULL. */
15245
15246tree
15247s390_valid_target_attribute_tree (tree args,
15248 struct gcc_options *opts,
15249 const struct gcc_options *opts_set,
15250 bool force_pragma)
15251{
15252 tree t = NULL_TREE;
15253 struct gcc_options new_opts_set;
15254
15255 memset (&new_opts_set, 0, sizeof (new_opts_set));
15256
15257 /* Process each of the options on the chain. */
15258 if (! s390_valid_target_attribute_inner_p (args, opts, &new_opts_set,
15259 force_pragma))
15260 return error_mark_node;
15261
15262 /* If some option was set (even if it has not changed), rerun
15263 s390_option_override_internal, and then save the options away. */
15264 if (new_opts_set.x_target_flags
15265 || new_opts_set.x_s390_arch
15266 || new_opts_set.x_s390_tune
15267 || new_opts_set.x_s390_stack_guard
15268 || new_opts_set.x_s390_stack_size
15269 || new_opts_set.x_s390_branch_cost
15270 || new_opts_set.x_s390_warn_framesize
15271 || new_opts_set.x_s390_warn_dynamicstack_p)
15272 {
15273 const unsigned char *src = (const unsigned char *)opts_set;
15274 unsigned char *dest = (unsigned char *)&new_opts_set;
15275 unsigned int i;
15276
15277 /* Merge the original option flags into the new ones. */
15278 for (i = 0; i < sizeof(*opts_set); i++)
15279 dest[i] |= src[i];
15280
15281 /* Do any overrides, such as arch=xxx, or tune=xxx support. */
3bd8520f 15282 s390_option_override_internal (false, opts, &new_opts_set);
7a0cee35 15283 /* Save the current options unless we are validating options for
15284 #pragma. */
15285 t = build_target_option_node (opts);
15286 }
15287 return t;
15288}
15289
15290/* Hook to validate attribute((target("string"))). */
15291
15292static bool
15293s390_valid_target_attribute_p (tree fndecl,
15294 tree ARG_UNUSED (name),
15295 tree args,
15296 int ARG_UNUSED (flags))
15297{
15298 struct gcc_options func_options;
15299 tree new_target, new_optimize;
15300 bool ret = true;
15301
15302 /* attribute((target("default"))) does nothing, beyond
15303 affecting multi-versioning. */
15304 if (TREE_VALUE (args)
15305 && TREE_CODE (TREE_VALUE (args)) == STRING_CST
15306 && TREE_CHAIN (args) == NULL_TREE
15307 && strcmp (TREE_STRING_POINTER (TREE_VALUE (args)), "default") == 0)
15308 return true;
15309
15310 tree old_optimize = build_optimization_node (&global_options);
15311
15312 /* Get the optimization options of the current function. */
15313 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
15314
15315 if (!func_optimize)
15316 func_optimize = old_optimize;
15317
15318 /* Init func_options. */
15319 memset (&func_options, 0, sizeof (func_options));
15320 init_options_struct (&func_options, NULL);
15321 lang_hooks.init_options_struct (&func_options);
15322
15323 cl_optimization_restore (&func_options, TREE_OPTIMIZATION (func_optimize));
15324
15325 /* Initialize func_options to the default before its target options can
15326 be set. */
15327 cl_target_option_restore (&func_options,
15328 TREE_TARGET_OPTION (target_option_default_node));
15329
15330 new_target = s390_valid_target_attribute_tree (args, &func_options,
15331 &global_options_set,
15332 (args ==
15333 current_target_pragma));
15334 new_optimize = build_optimization_node (&func_options);
15335 if (new_target == error_mark_node)
15336 ret = false;
15337 else if (fndecl && new_target)
15338 {
15339 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
15340 if (old_optimize != new_optimize)
15341 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
15342 }
15343 return ret;
15344}
15345
15346/* Restore targets globals from NEW_TREE and invalidate s390_previous_fndecl
15347 cache. */
15348
15349void
15350s390_activate_target_options (tree new_tree)
15351{
15352 cl_target_option_restore (&global_options, TREE_TARGET_OPTION (new_tree));
15353 if (TREE_TARGET_GLOBALS (new_tree))
15354 restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
15355 else if (new_tree == target_option_default_node)
15356 restore_target_globals (&default_target_globals);
15357 else
15358 TREE_TARGET_GLOBALS (new_tree) = save_target_globals_default_opts ();
15359 s390_previous_fndecl = NULL_TREE;
15360}
15361
15362/* Establish appropriate back-end context for processing the function
15363 FNDECL. The argument might be NULL to indicate processing at top
15364 level, outside of any function scope. */
15365static void
15366s390_set_current_function (tree fndecl)
15367{
15368 /* Only change the context if the function changes. This hook is called
15369 several times in the course of compiling a function, and we don't want to
15370 slow things down too much or call target_reinit when it isn't safe. */
15371 if (fndecl == s390_previous_fndecl)
15372 return;
15373
15374 tree old_tree;
15375 if (s390_previous_fndecl == NULL_TREE)
15376 old_tree = target_option_current_node;
15377 else if (DECL_FUNCTION_SPECIFIC_TARGET (s390_previous_fndecl))
15378 old_tree = DECL_FUNCTION_SPECIFIC_TARGET (s390_previous_fndecl);
15379 else
15380 old_tree = target_option_default_node;
15381
15382 if (fndecl == NULL_TREE)
15383 {
15384 if (old_tree != target_option_current_node)
15385 s390_activate_target_options (target_option_current_node);
15386 return;
15387 }
15388
15389 tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
15390 if (new_tree == NULL_TREE)
15391 new_tree = target_option_default_node;
15392
15393 if (old_tree != new_tree)
15394 s390_activate_target_options (new_tree);
15395 s390_previous_fndecl = fndecl;
15396}
15397#endif
15398
a83f0e2c 15399/* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
15400
15401static bool
89da42b6 15402s390_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
a83f0e2c 15403 unsigned int align ATTRIBUTE_UNUSED,
15404 enum by_pieces_operation op ATTRIBUTE_UNUSED,
15405 bool speed_p ATTRIBUTE_UNUSED)
15406{
15407 return (size == 1 || size == 2
15408 || size == 4 || (TARGET_ZARCH && size == 8));
15409}
15410
90f58e2a 15411/* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV hook. */
15412
15413static void
15414s390_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
15415{
07f32359 15416 tree sfpc = s390_builtin_decls[S390_BUILTIN_s390_sfpc];
15417 tree efpc = s390_builtin_decls[S390_BUILTIN_s390_efpc];
90f58e2a 15418 tree call_efpc = build_call_expr (efpc, 0);
9550ce87 15419 tree fenv_var = create_tmp_var_raw (unsigned_type_node);
90f58e2a 15420
15421#define FPC_EXCEPTION_MASK HOST_WIDE_INT_UC (0xf8000000)
15422#define FPC_FLAGS_MASK HOST_WIDE_INT_UC (0x00f80000)
15423#define FPC_DXC_MASK HOST_WIDE_INT_UC (0x0000ff00)
15424#define FPC_EXCEPTION_MASK_SHIFT HOST_WIDE_INT_UC (24)
15425#define FPC_FLAGS_SHIFT HOST_WIDE_INT_UC (16)
15426#define FPC_DXC_SHIFT HOST_WIDE_INT_UC (8)
15427
15428 /* Generates the equivalent of feholdexcept (&fenv_var)
15429
15430 fenv_var = __builtin_s390_efpc ();
15431 __builtin_s390_sfpc (fenv_var & mask) */
15432 tree old_fpc = build2 (MODIFY_EXPR, unsigned_type_node, fenv_var, call_efpc);
15433 tree new_fpc =
15434 build2 (BIT_AND_EXPR, unsigned_type_node, fenv_var,
15435 build_int_cst (unsigned_type_node,
15436 ~(FPC_DXC_MASK | FPC_FLAGS_MASK |
15437 FPC_EXCEPTION_MASK)));
15438 tree set_new_fpc = build_call_expr (sfpc, 1, new_fpc);
15439 *hold = build2 (COMPOUND_EXPR, void_type_node, old_fpc, set_new_fpc);
15440
15441 /* Generates the equivalent of feclearexcept (FE_ALL_EXCEPT)
15442
15443 __builtin_s390_sfpc (__builtin_s390_efpc () & mask) */
15444 new_fpc = build2 (BIT_AND_EXPR, unsigned_type_node, call_efpc,
15445 build_int_cst (unsigned_type_node,
15446 ~(FPC_DXC_MASK | FPC_FLAGS_MASK)));
15447 *clear = build_call_expr (sfpc, 1, new_fpc);
15448
15449 /* Generates the equivalent of feupdateenv (fenv_var)
15450
15451 old_fpc = __builtin_s390_efpc ();
15452 __builtin_s390_sfpc (fenv_var);
15453 __atomic_feraiseexcept ((old_fpc & FPC_FLAGS_MASK) >> FPC_FLAGS_SHIFT); */
15454
9550ce87 15455 old_fpc = create_tmp_var_raw (unsigned_type_node);
90f58e2a 15456 tree store_old_fpc = build2 (MODIFY_EXPR, void_type_node,
15457 old_fpc, call_efpc);
15458
15459 set_new_fpc = build_call_expr (sfpc, 1, fenv_var);
15460
15461 tree raise_old_except = build2 (BIT_AND_EXPR, unsigned_type_node, old_fpc,
15462 build_int_cst (unsigned_type_node,
15463 FPC_FLAGS_MASK));
15464 raise_old_except = build2 (RSHIFT_EXPR, unsigned_type_node, raise_old_except,
15465 build_int_cst (unsigned_type_node,
15466 FPC_FLAGS_SHIFT));
15467 tree atomic_feraiseexcept
15468 = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT);
15469 raise_old_except = build_call_expr (atomic_feraiseexcept,
15470 1, raise_old_except);
15471
15472 *update = build2 (COMPOUND_EXPR, void_type_node,
15473 build2 (COMPOUND_EXPR, void_type_node,
15474 store_old_fpc, set_new_fpc),
15475 raise_old_except);
15476
15477#undef FPC_EXCEPTION_MASK
15478#undef FPC_FLAGS_MASK
15479#undef FPC_DXC_MASK
15480#undef FPC_EXCEPTION_MASK_SHIFT
15481#undef FPC_FLAGS_SHIFT
15482#undef FPC_DXC_SHIFT
15483}
15484
76a4c804 15485/* Return the vector mode to be used for inner mode MODE when doing
15486 vectorization. */
15487static machine_mode
15488s390_preferred_simd_mode (machine_mode mode)
15489{
15490 if (TARGET_VX)
15491 switch (mode)
15492 {
15493 case DFmode:
15494 return V2DFmode;
15495 case DImode:
15496 return V2DImode;
15497 case SImode:
15498 return V4SImode;
15499 case HImode:
15500 return V8HImode;
15501 case QImode:
15502 return V16QImode;
15503 default:;
15504 }
15505 return word_mode;
15506}
15507
15508/* Our hardware does not require vectors to be strictly aligned. */
15509static bool
15510s390_support_vector_misalignment (machine_mode mode ATTRIBUTE_UNUSED,
15511 const_tree type ATTRIBUTE_UNUSED,
15512 int misalignment ATTRIBUTE_UNUSED,
15513 bool is_packed ATTRIBUTE_UNUSED)
15514{
6bb09dc9 15515 if (TARGET_VX)
15516 return true;
15517
15518 return default_builtin_support_vector_misalignment (mode, type, misalignment,
15519 is_packed);
76a4c804 15520}
15521
15522/* The vector ABI requires vector types to be aligned on an 8 byte
15523 boundary (our stack alignment). However, we allow this to be
15524 overriden by the user, while this definitely breaks the ABI. */
15525static HOST_WIDE_INT
15526s390_vector_alignment (const_tree type)
15527{
15528 if (!TARGET_VX_ABI)
15529 return default_vector_alignment (type);
15530
15531 if (TYPE_USER_ALIGN (type))
15532 return TYPE_ALIGN (type);
15533
15534 return MIN (64, tree_to_shwi (TYPE_SIZE (type)));
15535}
15536
14d7e7e6 15537#ifdef HAVE_AS_MACHINE_MACHINEMODE
15538/* Implement TARGET_ASM_FILE_START. */
15539static void
15540s390_asm_file_start (void)
15541{
b904831d 15542 default_file_start ();
14d7e7e6 15543 s390_asm_output_machine_for_arch (asm_out_file);
15544}
15545#endif
15546
6b7cfb9c 15547/* Implement TARGET_ASM_FILE_END. */
15548static void
15549s390_asm_file_end (void)
15550{
15551#ifdef HAVE_AS_GNU_ATTRIBUTE
15552 varpool_node *vnode;
15553 cgraph_node *cnode;
15554
15555 FOR_EACH_VARIABLE (vnode)
15556 if (TREE_PUBLIC (vnode->decl))
15557 s390_check_type_for_vector_abi (TREE_TYPE (vnode->decl), false, false);
15558
15559 FOR_EACH_FUNCTION (cnode)
15560 if (TREE_PUBLIC (cnode->decl))
15561 s390_check_type_for_vector_abi (TREE_TYPE (cnode->decl), false, false);
15562
15563
15564 if (s390_vector_abi != 0)
15565 fprintf (asm_out_file, "\t.gnu_attribute 8, %d\n",
15566 s390_vector_abi);
15567#endif
15568 file_end_indicate_exec_stack ();
c6d481f7 15569
15570 if (flag_split_stack)
15571 file_end_indicate_split_stack ();
6b7cfb9c 15572}
76a4c804 15573
f0c550e7 15574/* Return true if TYPE is a vector bool type. */
15575static inline bool
15576s390_vector_bool_type_p (const_tree type)
15577{
15578 return TYPE_VECTOR_OPAQUE (type);
15579}
15580
15581/* Return the diagnostic message string if the binary operation OP is
15582 not permitted on TYPE1 and TYPE2, NULL otherwise. */
15583static const char*
15584s390_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1, const_tree type2)
15585{
15586 bool bool1_p, bool2_p;
15587 bool plusminus_p;
15588 bool muldiv_p;
15589 bool compare_p;
15590 machine_mode mode1, mode2;
15591
15592 if (!TARGET_ZVECTOR)
15593 return NULL;
15594
15595 if (!VECTOR_TYPE_P (type1) || !VECTOR_TYPE_P (type2))
15596 return NULL;
15597
15598 bool1_p = s390_vector_bool_type_p (type1);
15599 bool2_p = s390_vector_bool_type_p (type2);
15600
15601 /* Mixing signed and unsigned types is forbidden for all
15602 operators. */
15603 if (!bool1_p && !bool2_p
15604 && TYPE_UNSIGNED (type1) != TYPE_UNSIGNED (type2))
d0abd9e0 15605 return N_("types differ in signedness");
f0c550e7 15606
15607 plusminus_p = (op == PLUS_EXPR || op == MINUS_EXPR);
15608 muldiv_p = (op == MULT_EXPR || op == RDIV_EXPR || op == TRUNC_DIV_EXPR
15609 || op == CEIL_DIV_EXPR || op == FLOOR_DIV_EXPR
15610 || op == ROUND_DIV_EXPR);
15611 compare_p = (op == LT_EXPR || op == LE_EXPR || op == GT_EXPR || op == GE_EXPR
15612 || op == EQ_EXPR || op == NE_EXPR);
15613
15614 if (bool1_p && bool2_p && (plusminus_p || muldiv_p))
15615 return N_("binary operator does not support two vector bool operands");
15616
15617 if (bool1_p != bool2_p && (muldiv_p || compare_p))
15618 return N_("binary operator does not support vector bool operand");
15619
15620 mode1 = TYPE_MODE (type1);
15621 mode2 = TYPE_MODE (type2);
15622
15623 if (bool1_p != bool2_p && plusminus_p
15624 && (GET_MODE_CLASS (mode1) == MODE_VECTOR_FLOAT
15625 || GET_MODE_CLASS (mode2) == MODE_VECTOR_FLOAT))
15626 return N_("binary operator does not support mixing vector "
15627 "bool with floating point vector operands");
15628
15629 return NULL;
15630}
15631
1de60655 15632/* Implement TARGET_C_EXCESS_PRECISION.
15633
15634 FIXME: For historical reasons, float_t and double_t are typedef'ed to
15635 double on s390, causing operations on float_t to operate in a higher
15636 precision than is necessary. However, it is not the case that SFmode
15637 operations have implicit excess precision, and we generate more optimal
15638 code if we let the compiler know no implicit extra precision is added.
15639
15640 That means when we are compiling with -fexcess-precision=fast, the value
15641 we set for FLT_EVAL_METHOD will be out of line with the actual precision of
15642 float_t (though they would be correct for -fexcess-precision=standard).
15643
15644 A complete fix would modify glibc to remove the unnecessary typedef
15645 of float_t to double. */
15646
15647static enum flt_eval_method
15648s390_excess_precision (enum excess_precision_type type)
15649{
15650 switch (type)
15651 {
15652 case EXCESS_PRECISION_TYPE_IMPLICIT:
15653 case EXCESS_PRECISION_TYPE_FAST:
15654 /* The fastest type to promote to will always be the native type,
15655 whether that occurs with implicit excess precision or
15656 otherwise. */
15657 return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
15658 case EXCESS_PRECISION_TYPE_STANDARD:
15659 /* Otherwise, when we are in a standards compliant mode, to
15660 ensure consistency with the implementation in glibc, report that
15661 float is evaluated to the range and precision of double. */
15662 return FLT_EVAL_METHOD_PROMOTE_TO_DOUBLE;
15663 default:
15664 gcc_unreachable ();
15665 }
15666 return FLT_EVAL_METHOD_UNPREDICTABLE;
15667}
15668
fff1179b 15669/* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */
15670
15671static unsigned HOST_WIDE_INT
15672s390_asan_shadow_offset (void)
15673{
15674 return TARGET_64BIT ? HOST_WIDE_INT_1U << 52 : HOST_WIDE_INT_UC (0x20000000);
15675}
15676
875862bf 15677/* Initialize GCC target structure. */
f588eb9f 15678
875862bf 15679#undef TARGET_ASM_ALIGNED_HI_OP
15680#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
15681#undef TARGET_ASM_ALIGNED_DI_OP
15682#define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
15683#undef TARGET_ASM_INTEGER
15684#define TARGET_ASM_INTEGER s390_assemble_integer
7346ca58 15685
875862bf 15686#undef TARGET_ASM_OPEN_PAREN
15687#define TARGET_ASM_OPEN_PAREN ""
f588eb9f 15688
875862bf 15689#undef TARGET_ASM_CLOSE_PAREN
15690#define TARGET_ASM_CLOSE_PAREN ""
7346ca58 15691
4c834714 15692#undef TARGET_OPTION_OVERRIDE
15693#define TARGET_OPTION_OVERRIDE s390_option_override
15694
8a23256f 15695#ifdef TARGET_THREAD_SSP_OFFSET
15696#undef TARGET_STACK_PROTECT_GUARD
15697#define TARGET_STACK_PROTECT_GUARD hook_tree_void_null
15698#endif
15699
875862bf 15700#undef TARGET_ENCODE_SECTION_INFO
15701#define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
7346ca58 15702
b5fdc416 15703#undef TARGET_SCALAR_MODE_SUPPORTED_P
15704#define TARGET_SCALAR_MODE_SUPPORTED_P s390_scalar_mode_supported_p
15705
875862bf 15706#ifdef HAVE_AS_TLS
15707#undef TARGET_HAVE_TLS
15708#define TARGET_HAVE_TLS true
15709#endif
15710#undef TARGET_CANNOT_FORCE_CONST_MEM
15711#define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
7346ca58 15712
875862bf 15713#undef TARGET_DELEGITIMIZE_ADDRESS
15714#define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
7346ca58 15715
41e3a0c7 15716#undef TARGET_LEGITIMIZE_ADDRESS
15717#define TARGET_LEGITIMIZE_ADDRESS s390_legitimize_address
15718
875862bf 15719#undef TARGET_RETURN_IN_MEMORY
15720#define TARGET_RETURN_IN_MEMORY s390_return_in_memory
f588eb9f 15721
5ada7a14 15722#undef TARGET_INIT_BUILTINS
15723#define TARGET_INIT_BUILTINS s390_init_builtins
15724#undef TARGET_EXPAND_BUILTIN
15725#define TARGET_EXPAND_BUILTIN s390_expand_builtin
751c914e 15726#undef TARGET_BUILTIN_DECL
15727#define TARGET_BUILTIN_DECL s390_builtin_decl
5ada7a14 15728
1a561788 15729#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
15730#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA s390_output_addr_const_extra
15731
875862bf 15732#undef TARGET_ASM_OUTPUT_MI_THUNK
15733#define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
15734#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
a9f1838b 15735#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
7346ca58 15736
1de60655 15737#undef TARGET_C_EXCESS_PRECISION
15738#define TARGET_C_EXCESS_PRECISION s390_excess_precision
15739
875862bf 15740#undef TARGET_SCHED_ADJUST_PRIORITY
15741#define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
15742#undef TARGET_SCHED_ISSUE_RATE
15743#define TARGET_SCHED_ISSUE_RATE s390_issue_rate
15744#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
15745#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
f588eb9f 15746
8a2a84e3 15747#undef TARGET_SCHED_VARIABLE_ISSUE
15748#define TARGET_SCHED_VARIABLE_ISSUE s390_sched_variable_issue
15749#undef TARGET_SCHED_REORDER
15750#define TARGET_SCHED_REORDER s390_sched_reorder
494d0169 15751#undef TARGET_SCHED_INIT
15752#define TARGET_SCHED_INIT s390_sched_init
8a2a84e3 15753
875862bf 15754#undef TARGET_CANNOT_COPY_INSN_P
15755#define TARGET_CANNOT_COPY_INSN_P s390_cannot_copy_insn_p
15756#undef TARGET_RTX_COSTS
15757#define TARGET_RTX_COSTS s390_rtx_costs
15758#undef TARGET_ADDRESS_COST
15759#define TARGET_ADDRESS_COST s390_address_cost
fa7a995b 15760#undef TARGET_REGISTER_MOVE_COST
15761#define TARGET_REGISTER_MOVE_COST s390_register_move_cost
15762#undef TARGET_MEMORY_MOVE_COST
15763#define TARGET_MEMORY_MOVE_COST s390_memory_move_cost
292e369f 15764#undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
15765#define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
15766 s390_builtin_vectorization_cost
f588eb9f 15767
875862bf 15768#undef TARGET_MACHINE_DEPENDENT_REORG
15769#define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
71597dac 15770
875862bf 15771#undef TARGET_VALID_POINTER_MODE
15772#define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
f588eb9f 15773
875862bf 15774#undef TARGET_BUILD_BUILTIN_VA_LIST
15775#define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
8a58ed0a 15776#undef TARGET_EXPAND_BUILTIN_VA_START
15777#define TARGET_EXPAND_BUILTIN_VA_START s390_va_start
fff1179b 15778#undef TARGET_ASAN_SHADOW_OFFSET
15779#define TARGET_ASAN_SHADOW_OFFSET s390_asan_shadow_offset
875862bf 15780#undef TARGET_GIMPLIFY_VA_ARG_EXPR
15781#define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg
b33c41a1 15782
3b2411a8 15783#undef TARGET_PROMOTE_FUNCTION_MODE
15784#define TARGET_PROMOTE_FUNCTION_MODE s390_promote_function_mode
875862bf 15785#undef TARGET_PASS_BY_REFERENCE
15786#define TARGET_PASS_BY_REFERENCE s390_pass_by_reference
b33c41a1 15787
875862bf 15788#undef TARGET_FUNCTION_OK_FOR_SIBCALL
15789#define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
12bc26aa 15790#undef TARGET_FUNCTION_ARG
15791#define TARGET_FUNCTION_ARG s390_function_arg
15792#undef TARGET_FUNCTION_ARG_ADVANCE
15793#define TARGET_FUNCTION_ARG_ADVANCE s390_function_arg_advance
dc3b3062 15794#undef TARGET_FUNCTION_VALUE
15795#define TARGET_FUNCTION_VALUE s390_function_value
15796#undef TARGET_LIBCALL_VALUE
15797#define TARGET_LIBCALL_VALUE s390_libcall_value
76a4c804 15798#undef TARGET_STRICT_ARGUMENT_NAMING
15799#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
b33c41a1 15800
d44f2f7c 15801#undef TARGET_KEEP_LEAF_WHEN_PROFILED
15802#define TARGET_KEEP_LEAF_WHEN_PROFILED s390_keep_leaf_when_profiled
15803
875862bf 15804#undef TARGET_FIXED_CONDITION_CODE_REGS
15805#define TARGET_FIXED_CONDITION_CODE_REGS s390_fixed_condition_code_regs
b33c41a1 15806
875862bf 15807#undef TARGET_CC_MODES_COMPATIBLE
15808#define TARGET_CC_MODES_COMPATIBLE s390_cc_modes_compatible
b33c41a1 15809
1606e68a 15810#undef TARGET_INVALID_WITHIN_DOLOOP
18282db0 15811#define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_const_rtx_insn_null
e75dabf7 15812
40af64cc 15813#ifdef HAVE_AS_TLS
15814#undef TARGET_ASM_OUTPUT_DWARF_DTPREL
15815#define TARGET_ASM_OUTPUT_DWARF_DTPREL s390_output_dwarf_dtprel
15816#endif
15817
76a4c804 15818#undef TARGET_DWARF_FRAME_REG_MODE
15819#define TARGET_DWARF_FRAME_REG_MODE s390_dwarf_frame_reg_mode
15820
4257b08a 15821#ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
eddcdde1 15822#undef TARGET_MANGLE_TYPE
15823#define TARGET_MANGLE_TYPE s390_mangle_type
4257b08a 15824#endif
15825
36868490 15826#undef TARGET_SCALAR_MODE_SUPPORTED_P
15827#define TARGET_SCALAR_MODE_SUPPORTED_P s390_scalar_mode_supported_p
15828
76a4c804 15829#undef TARGET_VECTOR_MODE_SUPPORTED_P
15830#define TARGET_VECTOR_MODE_SUPPORTED_P s390_vector_mode_supported_p
15831
3359ccfd 15832#undef TARGET_PREFERRED_RELOAD_CLASS
15833#define TARGET_PREFERRED_RELOAD_CLASS s390_preferred_reload_class
15834
328d5423 15835#undef TARGET_SECONDARY_RELOAD
15836#define TARGET_SECONDARY_RELOAD s390_secondary_reload
15837
0ef89dfd 15838#undef TARGET_LIBGCC_CMP_RETURN_MODE
15839#define TARGET_LIBGCC_CMP_RETURN_MODE s390_libgcc_cmp_return_mode
15840
15841#undef TARGET_LIBGCC_SHIFT_COUNT_MODE
15842#define TARGET_LIBGCC_SHIFT_COUNT_MODE s390_libgcc_shift_count_mode
15843
fd50b071 15844#undef TARGET_LEGITIMATE_ADDRESS_P
15845#define TARGET_LEGITIMATE_ADDRESS_P s390_legitimate_address_p
15846
ca316360 15847#undef TARGET_LEGITIMATE_CONSTANT_P
15848#define TARGET_LEGITIMATE_CONSTANT_P s390_legitimate_constant_p
15849
7b1bda1c 15850#undef TARGET_LRA_P
15851#define TARGET_LRA_P s390_lra_p
15852
cd90919d 15853#undef TARGET_CAN_ELIMINATE
15854#define TARGET_CAN_ELIMINATE s390_can_eliminate
15855
b2d7ede1 15856#undef TARGET_CONDITIONAL_REGISTER_USAGE
15857#define TARGET_CONDITIONAL_REGISTER_USAGE s390_conditional_register_usage
15858
9ccaa774 15859#undef TARGET_LOOP_UNROLL_ADJUST
15860#define TARGET_LOOP_UNROLL_ADJUST s390_loop_unroll_adjust
15861
4d946732 15862#undef TARGET_ASM_TRAMPOLINE_TEMPLATE
15863#define TARGET_ASM_TRAMPOLINE_TEMPLATE s390_asm_trampoline_template
15864#undef TARGET_TRAMPOLINE_INIT
15865#define TARGET_TRAMPOLINE_INIT s390_trampoline_init
15866
8805debf 15867/* PR 79421 */
15868#undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
15869#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1
15870
b5fdc416 15871#undef TARGET_UNWIND_WORD_MODE
15872#define TARGET_UNWIND_WORD_MODE s390_unwind_word_mode
15873
d5065e6e 15874#undef TARGET_CANONICALIZE_COMPARISON
15875#define TARGET_CANONICALIZE_COMPARISON s390_canonicalize_comparison
15876
ff4ce128 15877#undef TARGET_HARD_REGNO_SCRATCH_OK
15878#define TARGET_HARD_REGNO_SCRATCH_OK s390_hard_regno_scratch_ok
15879
77bc9912 15880#undef TARGET_ATTRIBUTE_TABLE
15881#define TARGET_ATTRIBUTE_TABLE s390_attribute_table
15882
11762b83 15883#undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
15884#define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_const_tree_true
77bc9912 15885
7a64c761 15886#undef TARGET_SET_UP_BY_PROLOGUE
15887#define TARGET_SET_UP_BY_PROLOGUE s300_set_up_by_prologue
15888
c6d481f7 15889#undef TARGET_EXTRA_LIVE_ON_ENTRY
15890#define TARGET_EXTRA_LIVE_ON_ENTRY s390_live_on_entry
15891
a83f0e2c 15892#undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
15893#define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
15894 s390_use_by_pieces_infrastructure_p
15895
90f58e2a 15896#undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
15897#define TARGET_ATOMIC_ASSIGN_EXPAND_FENV s390_atomic_assign_expand_fenv
15898
76a4c804 15899#undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
15900#define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN s390_invalid_arg_for_unprototyped_fn
15901
15902#undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
15903#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE s390_preferred_simd_mode
15904
15905#undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
15906#define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT s390_support_vector_misalignment
15907
15908#undef TARGET_VECTOR_ALIGNMENT
15909#define TARGET_VECTOR_ALIGNMENT s390_vector_alignment
15910
f0c550e7 15911#undef TARGET_INVALID_BINARY_OP
15912#define TARGET_INVALID_BINARY_OP s390_invalid_binary_op
15913
14d7e7e6 15914#ifdef HAVE_AS_MACHINE_MACHINEMODE
15915#undef TARGET_ASM_FILE_START
15916#define TARGET_ASM_FILE_START s390_asm_file_start
15917#endif
15918
6b7cfb9c 15919#undef TARGET_ASM_FILE_END
15920#define TARGET_ASM_FILE_END s390_asm_file_end
15921
7a0cee35 15922#if S390_USE_TARGET_ATTRIBUTE
15923#undef TARGET_SET_CURRENT_FUNCTION
15924#define TARGET_SET_CURRENT_FUNCTION s390_set_current_function
15925
15926#undef TARGET_OPTION_VALID_ATTRIBUTE_P
15927#define TARGET_OPTION_VALID_ATTRIBUTE_P s390_valid_target_attribute_p
15928#endif
15929
15930#undef TARGET_OPTION_RESTORE
15931#define TARGET_OPTION_RESTORE s390_function_specific_restore
15932
875862bf 15933struct gcc_target targetm = TARGET_INITIALIZER;
f588eb9f 15934
5a5e802f 15935#include "gt-s390.h"