]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/s390/s390.c
Fix numerous typos in comments
[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"
38#include "expmed.h"
39#include "optabs.h"
40#include "regs.h"
41#include "emit-rtl.h"
42#include "recog.h"
43#include "cgraph.h"
44#include "diagnostic-core.h"
7a0cee35 45#include "diagnostic.h"
b20a8bb4 46#include "alias.h"
b20a8bb4 47#include "fold-const.h"
9ed99284 48#include "print-tree.h"
9ed99284 49#include "stor-layout.h"
50#include "varasm.h"
51#include "calls.h"
4673c1a0 52#include "conditions.h"
53#include "output.h"
54#include "insn-attr.h"
55#include "flags.h"
56#include "except.h"
d53441c8 57#include "dojump.h"
58#include "explow.h"
d53441c8 59#include "stmt.h"
4673c1a0 60#include "expr.h"
c10847b9 61#include "reload.h"
94ea8568 62#include "cfgrtl.h"
63#include "cfganal.h"
64#include "lcm.h"
65#include "cfgbuild.h"
66#include "cfgcleanup.h"
7baa5366 67#include "debug.h"
a1f71e15 68#include "langhooks.h"
bc61cadb 69#include "internal-fn.h"
70#include "gimple-fold.h"
71#include "tree-eh.h"
a8783bee 72#include "gimplify.h"
c0717306 73#include "params.h"
fba5dd52 74#include "opts.h"
0b8be04c 75#include "tree-pass.h"
76#include "context.h"
f7715905 77#include "builtins.h"
15e472ec 78#include "rtl-iter.h"
76a4c804 79#include "intl.h"
80fc7f56 80#include "tm-constrs.h"
4673c1a0 81
0c71fb4f 82/* This file should be included last. */
4b498588 83#include "target-def.h"
84
7a0cee35 85/* Remember the last target of s390_set_current_function. */
86static GTY(()) tree s390_previous_fndecl;
87
18925d38 88/* Define the specific costs for a given cpu. */
89
ffead1ca 90struct processor_costs
18925d38 91{
260075cc 92 /* multiplication */
18925d38 93 const int m; /* cost of an M instruction. */
94 const int mghi; /* cost of an MGHI instruction. */
95 const int mh; /* cost of an MH instruction. */
96 const int mhi; /* cost of an MHI instruction. */
9cd3f3e6 97 const int ml; /* cost of an ML instruction. */
18925d38 98 const int mr; /* cost of an MR instruction. */
99 const int ms; /* cost of an MS instruction. */
100 const int msg; /* cost of an MSG instruction. */
101 const int msgf; /* cost of an MSGF instruction. */
102 const int msgfr; /* cost of an MSGFR instruction. */
103 const int msgr; /* cost of an MSGR instruction. */
104 const int msr; /* cost of an MSR instruction. */
105 const int mult_df; /* cost of multiplication in DFmode. */
429f9fdb 106 const int mxbr;
260075cc 107 /* square root */
429f9fdb 108 const int sqxbr; /* cost of square root in TFmode. */
9cd3f3e6 109 const int sqdbr; /* cost of square root in DFmode. */
110 const int sqebr; /* cost of square root in SFmode. */
260075cc 111 /* multiply and add */
d95e38cf 112 const int madbr; /* cost of multiply and add in DFmode. */
113 const int maebr; /* cost of multiply and add in SFmode. */
260075cc 114 /* division */
429f9fdb 115 const int dxbr;
260075cc 116 const int ddbr;
260075cc 117 const int debr;
3f074425 118 const int dlgr;
119 const int dlr;
120 const int dr;
121 const int dsgfr;
122 const int dsgr;
18925d38 123};
124
7a0cee35 125#define s390_cost ((const struct processor_costs *)(s390_cost_pointer))
18925d38 126
127static const
ffead1ca 128struct processor_costs z900_cost =
18925d38 129{
130 COSTS_N_INSNS (5), /* M */
131 COSTS_N_INSNS (10), /* MGHI */
132 COSTS_N_INSNS (5), /* MH */
133 COSTS_N_INSNS (4), /* MHI */
9cd3f3e6 134 COSTS_N_INSNS (5), /* ML */
18925d38 135 COSTS_N_INSNS (5), /* MR */
136 COSTS_N_INSNS (4), /* MS */
137 COSTS_N_INSNS (15), /* MSG */
138 COSTS_N_INSNS (7), /* MSGF */
139 COSTS_N_INSNS (7), /* MSGFR */
140 COSTS_N_INSNS (10), /* MSGR */
141 COSTS_N_INSNS (4), /* MSR */
142 COSTS_N_INSNS (7), /* multiplication in DFmode */
429f9fdb 143 COSTS_N_INSNS (13), /* MXBR */
144 COSTS_N_INSNS (136), /* SQXBR */
9cd3f3e6 145 COSTS_N_INSNS (44), /* SQDBR */
146 COSTS_N_INSNS (35), /* SQEBR */
d95e38cf 147 COSTS_N_INSNS (18), /* MADBR */
148 COSTS_N_INSNS (13), /* MAEBR */
429f9fdb 149 COSTS_N_INSNS (134), /* DXBR */
260075cc 150 COSTS_N_INSNS (30), /* DDBR */
260075cc 151 COSTS_N_INSNS (27), /* DEBR */
3f074425 152 COSTS_N_INSNS (220), /* DLGR */
153 COSTS_N_INSNS (34), /* DLR */
154 COSTS_N_INSNS (34), /* DR */
155 COSTS_N_INSNS (32), /* DSGFR */
156 COSTS_N_INSNS (32), /* DSGR */
18925d38 157};
158
159static const
ffead1ca 160struct processor_costs z990_cost =
18925d38 161{
162 COSTS_N_INSNS (4), /* M */
163 COSTS_N_INSNS (2), /* MGHI */
164 COSTS_N_INSNS (2), /* MH */
165 COSTS_N_INSNS (2), /* MHI */
9cd3f3e6 166 COSTS_N_INSNS (4), /* ML */
18925d38 167 COSTS_N_INSNS (4), /* MR */
168 COSTS_N_INSNS (5), /* MS */
169 COSTS_N_INSNS (6), /* MSG */
170 COSTS_N_INSNS (4), /* MSGF */
171 COSTS_N_INSNS (4), /* MSGFR */
172 COSTS_N_INSNS (4), /* MSGR */
173 COSTS_N_INSNS (4), /* MSR */
174 COSTS_N_INSNS (1), /* multiplication in DFmode */
429f9fdb 175 COSTS_N_INSNS (28), /* MXBR */
176 COSTS_N_INSNS (130), /* SQXBR */
9cd3f3e6 177 COSTS_N_INSNS (66), /* SQDBR */
178 COSTS_N_INSNS (38), /* SQEBR */
d95e38cf 179 COSTS_N_INSNS (1), /* MADBR */
180 COSTS_N_INSNS (1), /* MAEBR */
429f9fdb 181 COSTS_N_INSNS (60), /* DXBR */
260075cc 182 COSTS_N_INSNS (40), /* DDBR */
095798e3 183 COSTS_N_INSNS (26), /* DEBR */
3f074425 184 COSTS_N_INSNS (176), /* DLGR */
185 COSTS_N_INSNS (31), /* DLR */
186 COSTS_N_INSNS (31), /* DR */
187 COSTS_N_INSNS (31), /* DSGFR */
188 COSTS_N_INSNS (31), /* DSGR */
18925d38 189};
190
163277cf 191static const
ffead1ca 192struct processor_costs z9_109_cost =
163277cf 193{
194 COSTS_N_INSNS (4), /* M */
195 COSTS_N_INSNS (2), /* MGHI */
196 COSTS_N_INSNS (2), /* MH */
197 COSTS_N_INSNS (2), /* MHI */
198 COSTS_N_INSNS (4), /* ML */
199 COSTS_N_INSNS (4), /* MR */
200 COSTS_N_INSNS (5), /* MS */
201 COSTS_N_INSNS (6), /* MSG */
202 COSTS_N_INSNS (4), /* MSGF */
203 COSTS_N_INSNS (4), /* MSGFR */
204 COSTS_N_INSNS (4), /* MSGR */
205 COSTS_N_INSNS (4), /* MSR */
206 COSTS_N_INSNS (1), /* multiplication in DFmode */
429f9fdb 207 COSTS_N_INSNS (28), /* MXBR */
208 COSTS_N_INSNS (130), /* SQXBR */
163277cf 209 COSTS_N_INSNS (66), /* SQDBR */
210 COSTS_N_INSNS (38), /* SQEBR */
211 COSTS_N_INSNS (1), /* MADBR */
212 COSTS_N_INSNS (1), /* MAEBR */
429f9fdb 213 COSTS_N_INSNS (60), /* DXBR */
163277cf 214 COSTS_N_INSNS (40), /* DDBR */
095798e3 215 COSTS_N_INSNS (26), /* DEBR */
163277cf 216 COSTS_N_INSNS (30), /* DLGR */
217 COSTS_N_INSNS (23), /* DLR */
218 COSTS_N_INSNS (23), /* DR */
219 COSTS_N_INSNS (24), /* DSGFR */
220 COSTS_N_INSNS (24), /* DSGR */
221};
18925d38 222
a850370e 223static const
224struct processor_costs z10_cost =
225{
510c2327 226 COSTS_N_INSNS (10), /* M */
227 COSTS_N_INSNS (10), /* MGHI */
228 COSTS_N_INSNS (10), /* MH */
229 COSTS_N_INSNS (10), /* MHI */
230 COSTS_N_INSNS (10), /* ML */
231 COSTS_N_INSNS (10), /* MR */
232 COSTS_N_INSNS (10), /* MS */
233 COSTS_N_INSNS (10), /* MSG */
234 COSTS_N_INSNS (10), /* MSGF */
235 COSTS_N_INSNS (10), /* MSGFR */
236 COSTS_N_INSNS (10), /* MSGR */
237 COSTS_N_INSNS (10), /* MSR */
b0eacf26 238 COSTS_N_INSNS (1) , /* multiplication in DFmode */
510c2327 239 COSTS_N_INSNS (50), /* MXBR */
240 COSTS_N_INSNS (120), /* SQXBR */
241 COSTS_N_INSNS (52), /* SQDBR */
a850370e 242 COSTS_N_INSNS (38), /* SQEBR */
b0eacf26 243 COSTS_N_INSNS (1), /* MADBR */
244 COSTS_N_INSNS (1), /* MAEBR */
510c2327 245 COSTS_N_INSNS (111), /* DXBR */
246 COSTS_N_INSNS (39), /* DDBR */
247 COSTS_N_INSNS (32), /* DEBR */
248 COSTS_N_INSNS (160), /* DLGR */
249 COSTS_N_INSNS (71), /* DLR */
250 COSTS_N_INSNS (71), /* DR */
251 COSTS_N_INSNS (71), /* DSGFR */
252 COSTS_N_INSNS (71), /* DSGR */
a850370e 253};
254
33d033da 255static const
256struct processor_costs z196_cost =
257{
258 COSTS_N_INSNS (7), /* M */
259 COSTS_N_INSNS (5), /* MGHI */
260 COSTS_N_INSNS (5), /* MH */
261 COSTS_N_INSNS (5), /* MHI */
262 COSTS_N_INSNS (7), /* ML */
263 COSTS_N_INSNS (7), /* MR */
264 COSTS_N_INSNS (6), /* MS */
265 COSTS_N_INSNS (8), /* MSG */
266 COSTS_N_INSNS (6), /* MSGF */
267 COSTS_N_INSNS (6), /* MSGFR */
268 COSTS_N_INSNS (8), /* MSGR */
269 COSTS_N_INSNS (6), /* MSR */
270 COSTS_N_INSNS (1) , /* multiplication in DFmode */
271 COSTS_N_INSNS (40), /* MXBR B+40 */
272 COSTS_N_INSNS (100), /* SQXBR B+100 */
273 COSTS_N_INSNS (42), /* SQDBR B+42 */
274 COSTS_N_INSNS (28), /* SQEBR B+28 */
275 COSTS_N_INSNS (1), /* MADBR B */
276 COSTS_N_INSNS (1), /* MAEBR B */
277 COSTS_N_INSNS (101), /* DXBR B+101 */
278 COSTS_N_INSNS (29), /* DDBR */
279 COSTS_N_INSNS (22), /* DEBR */
280 COSTS_N_INSNS (160), /* DLGR cracked */
281 COSTS_N_INSNS (160), /* DLR cracked */
282 COSTS_N_INSNS (160), /* DR expanded */
283 COSTS_N_INSNS (160), /* DSGFR cracked */
284 COSTS_N_INSNS (160), /* DSGR cracked */
285};
286
81769881 287static const
288struct processor_costs zEC12_cost =
289{
290 COSTS_N_INSNS (7), /* M */
291 COSTS_N_INSNS (5), /* MGHI */
292 COSTS_N_INSNS (5), /* MH */
293 COSTS_N_INSNS (5), /* MHI */
294 COSTS_N_INSNS (7), /* ML */
295 COSTS_N_INSNS (7), /* MR */
296 COSTS_N_INSNS (6), /* MS */
297 COSTS_N_INSNS (8), /* MSG */
298 COSTS_N_INSNS (6), /* MSGF */
299 COSTS_N_INSNS (6), /* MSGFR */
300 COSTS_N_INSNS (8), /* MSGR */
301 COSTS_N_INSNS (6), /* MSR */
302 COSTS_N_INSNS (1) , /* multiplication in DFmode */
303 COSTS_N_INSNS (40), /* MXBR B+40 */
304 COSTS_N_INSNS (100), /* SQXBR B+100 */
305 COSTS_N_INSNS (42), /* SQDBR B+42 */
306 COSTS_N_INSNS (28), /* SQEBR B+28 */
307 COSTS_N_INSNS (1), /* MADBR B */
308 COSTS_N_INSNS (1), /* MAEBR B */
309 COSTS_N_INSNS (131), /* DXBR B+131 */
310 COSTS_N_INSNS (29), /* DDBR */
311 COSTS_N_INSNS (22), /* DEBR */
312 COSTS_N_INSNS (160), /* DLGR cracked */
313 COSTS_N_INSNS (160), /* DLR cracked */
314 COSTS_N_INSNS (160), /* DR expanded */
315 COSTS_N_INSNS (160), /* DSGFR cracked */
316 COSTS_N_INSNS (160), /* DSGR cracked */
317};
318
7a0cee35 319static struct
320{
321 const char *const name;
322 const enum processor_type processor;
323 const struct processor_costs *cost;
324}
325const processor_table[] =
326{
327 { "g5", PROCESSOR_9672_G5, &z900_cost },
328 { "g6", PROCESSOR_9672_G6, &z900_cost },
329 { "z900", PROCESSOR_2064_Z900, &z900_cost },
330 { "z990", PROCESSOR_2084_Z990, &z990_cost },
331 { "z9-109", PROCESSOR_2094_Z9_109, &z9_109_cost },
332 { "z9-ec", PROCESSOR_2094_Z9_EC, &z9_109_cost },
333 { "z10", PROCESSOR_2097_Z10, &z10_cost },
334 { "z196", PROCESSOR_2817_Z196, &z196_cost },
335 { "zEC12", PROCESSOR_2827_ZEC12, &zEC12_cost },
336 { "z13", PROCESSOR_2964_Z13, &zEC12_cost },
c9213ca0 337 { "arch12", PROCESSOR_ARCH12, &zEC12_cost },
7a0cee35 338 { "native", PROCESSOR_NATIVE, NULL }
339};
340
4673c1a0 341extern int reload_completed;
342
8a2a84e3 343/* Kept up to date using the SCHED_VARIABLE_ISSUE hook. */
93e0956b 344static rtx_insn *last_scheduled_insn;
0cb69051 345#define MAX_SCHED_UNITS 3
346static int last_scheduled_unit_distance[MAX_SCHED_UNITS];
347
348/* The maximum score added for an instruction whose unit hasn't been
349 in use for MAX_SCHED_MIX_DISTANCE steps. Increase this value to
350 give instruction mix scheduling more priority over instruction
351 grouping. */
352#define MAX_SCHED_MIX_SCORE 8
353
354/* The maximum distance up to which individual scores will be
355 calculated. Everything beyond this gives MAX_SCHED_MIX_SCORE.
356 Increase this with the OOO windows size of the machine. */
357#define MAX_SCHED_MIX_DISTANCE 100
8a2a84e3 358
56769981 359/* Structure used to hold the components of a S/390 memory
360 address. A legitimate address on S/390 is of the general
361 form
362 base + index + displacement
363 where any of the components is optional.
364
365 base and index are registers of the class ADDR_REGS,
366 displacement is an unsigned 12-bit immediate constant. */
4673c1a0 367
368struct s390_address
369{
370 rtx base;
371 rtx indx;
372 rtx disp;
e5537457 373 bool pointer;
05b58257 374 bool literal_pool;
4673c1a0 375};
376
ffead1ca 377/* The following structure is embedded in the machine
67928721 378 specific part of struct function. */
379
fb1e4f4a 380struct GTY (()) s390_frame_layout
67928721 381{
382 /* Offset within stack frame. */
383 HOST_WIDE_INT gprs_offset;
384 HOST_WIDE_INT f0_offset;
385 HOST_WIDE_INT f4_offset;
386 HOST_WIDE_INT f8_offset;
387 HOST_WIDE_INT backchain_offset;
5214e6ae 388
389 /* Number of first and last gpr where slots in the register
390 save area are reserved for. */
391 int first_save_gpr_slot;
392 int last_save_gpr_slot;
393
ff4ce128 394 /* Location (FP register number) where GPRs (r0-r15) should
395 be saved to.
396 0 - does not need to be saved at all
397 -1 - stack slot */
1d3cea74 398#define SAVE_SLOT_NONE 0
399#define SAVE_SLOT_STACK -1
ff4ce128 400 signed char gpr_save_slots[16];
401
5a5e802f 402 /* Number of first and last gpr to be saved, restored. */
8b4a4127 403 int first_save_gpr;
404 int first_restore_gpr;
405 int last_save_gpr;
beee1f75 406 int last_restore_gpr;
8b4a4127 407
ffead1ca 408 /* Bits standing for floating point registers. Set, if the
409 respective register has to be saved. Starting with reg 16 (f0)
67928721 410 at the rightmost bit.
6a2469fe 411 Bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
412 fpr 15 13 11 9 14 12 10 8 7 5 3 1 6 4 2 0
413 reg 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 */
67928721 414 unsigned int fpr_bitmap;
415
416 /* Number of floating point registers f8-f15 which must be saved. */
417 int high_fprs;
418
9bee2845 419 /* Set if return address needs to be saved.
420 This flag is set by s390_return_addr_rtx if it could not use
421 the initial value of r14 and therefore depends on r14 saved
422 to the stack. */
67928721 423 bool save_return_addr_p;
424
5a5e802f 425 /* Size of stack frame. */
8b4a4127 426 HOST_WIDE_INT frame_size;
67928721 427};
428
429/* Define the structure for the machine field in struct function. */
430
fb1e4f4a 431struct GTY(()) machine_function
67928721 432{
433 struct s390_frame_layout frame_layout;
be00aaa8 434
20074f87 435 /* Literal pool base register. */
436 rtx base_reg;
437
4fed3f99 438 /* True if we may need to perform branch splitting. */
439 bool split_branches_pending_p;
440
1e639cb0 441 bool has_landing_pad_p;
5ada7a14 442
443 /* True if the current function may contain a tbegin clobbering
444 FPRs. */
445 bool tbegin_p;
c6d481f7 446
447 /* For -fsplit-stack support: A stack local which holds a pointer to
448 the stack arguments for a function with a variable number of
449 arguments. This is set at the start of the function and is used
450 to initialize the overflow_arg_area field of the va_list
451 structure. */
452 rtx split_stack_varargs_pointer;
8b4a4127 453};
454
67928721 455/* Few accessor macros for struct cfun->machine->s390_frame_layout. */
456
457#define cfun_frame_layout (cfun->machine->frame_layout)
458#define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)
ff4ce128 459#define cfun_save_arg_fprs_p (!!(TARGET_64BIT \
460 ? cfun_frame_layout.fpr_bitmap & 0x0f \
461 : cfun_frame_layout.fpr_bitmap & 0x03))
462#define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr_slot - \
b5fdc416 463 cfun_frame_layout.first_save_gpr_slot + 1) * UNITS_PER_LONG)
29439367 464#define cfun_set_fpr_save(REGNO) (cfun->machine->frame_layout.fpr_bitmap |= \
6a2469fe 465 (1 << (REGNO - FPR0_REGNUM)))
29439367 466#define cfun_fpr_save_p(REGNO) (!!(cfun->machine->frame_layout.fpr_bitmap & \
6a2469fe 467 (1 << (REGNO - FPR0_REGNUM))))
ff4ce128 468#define cfun_gpr_save_slot(REGNO) \
469 cfun->machine->frame_layout.gpr_save_slots[REGNO]
67928721 470
6902d973 471/* Number of GPRs and FPRs used for argument passing. */
472#define GP_ARG_NUM_REG 5
473#define FP_ARG_NUM_REG (TARGET_64BIT? 4 : 2)
76a4c804 474#define VEC_ARG_NUM_REG 8
6902d973 475
cb888f33 476/* A couple of shortcuts. */
477#define CONST_OK_FOR_J(x) \
478 CONST_OK_FOR_CONSTRAINT_P((x), 'J', "J")
479#define CONST_OK_FOR_K(x) \
480 CONST_OK_FOR_CONSTRAINT_P((x), 'K', "K")
163277cf 481#define CONST_OK_FOR_Os(x) \
482 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Os")
483#define CONST_OK_FOR_Op(x) \
484 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Op")
485#define CONST_OK_FOR_On(x) \
486 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "On")
cb888f33 487
8f1128bb 488#define REGNO_PAIR_OK(REGNO, MODE) \
489 (HARD_REGNO_NREGS ((REGNO), (MODE)) == 1 || !((REGNO) & 1))
490
73df8a45 491/* That's the read ahead of the dynamic branch prediction unit in
33d033da 492 bytes on a z10 (or higher) CPU. */
493#define PREDICT_DISTANCE (TARGET_Z10 ? 384 : 2048)
73df8a45 494
07f32359 495
6b7cfb9c 496/* Indicate which ABI has been used for passing vector args.
497 0 - no vector type arguments have been passed where the ABI is relevant
498 1 - the old ABI has been used
499 2 - a vector type argument has been passed either in a vector register
500 or on the stack by value */
501static int s390_vector_abi = 0;
502
503/* Set the vector ABI marker if TYPE is subject to the vector ABI
504 switch. The vector ABI affects only vector data types. There are
505 two aspects of the vector ABI relevant here:
506
507 1. vectors >= 16 bytes have an alignment of 8 bytes with the new
508 ABI and natural alignment with the old.
509
510 2. vector <= 16 bytes are passed in VRs or by value on the stack
511 with the new ABI but by reference on the stack with the old.
512
513 If ARG_P is true TYPE is used for a function argument or return
514 value. The ABI marker then is set for all vector data types. If
515 ARG_P is false only type 1 vectors are being checked. */
516
517static void
518s390_check_type_for_vector_abi (const_tree type, bool arg_p, bool in_struct_p)
519{
520 static hash_set<const_tree> visited_types_hash;
521
522 if (s390_vector_abi)
523 return;
524
525 if (type == NULL_TREE || TREE_CODE (type) == ERROR_MARK)
526 return;
527
528 if (visited_types_hash.contains (type))
529 return;
530
531 visited_types_hash.add (type);
532
533 if (VECTOR_TYPE_P (type))
534 {
535 int type_size = int_size_in_bytes (type);
536
537 /* Outside arguments only the alignment is changing and this
538 only happens for vector types >= 16 bytes. */
539 if (!arg_p && type_size < 16)
540 return;
541
542 /* In arguments vector types > 16 are passed as before (GCC
543 never enforced the bigger alignment for arguments which was
544 required by the old vector ABI). However, it might still be
545 ABI relevant due to the changed alignment if it is a struct
546 member. */
547 if (arg_p && type_size > 16 && !in_struct_p)
548 return;
549
550 s390_vector_abi = TARGET_VX_ABI ? 2 : 1;
551 }
552 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
553 {
554 /* ARRAY_TYPE: Since with neither of the ABIs we have more than
555 natural alignment there will never be ABI dependent padding
556 in an array type. That's why we do not set in_struct_p to
557 true here. */
558 s390_check_type_for_vector_abi (TREE_TYPE (type), arg_p, in_struct_p);
559 }
560 else if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE)
561 {
562 tree arg_chain;
563
564 /* Check the return type. */
565 s390_check_type_for_vector_abi (TREE_TYPE (type), true, false);
566
567 for (arg_chain = TYPE_ARG_TYPES (type);
568 arg_chain;
569 arg_chain = TREE_CHAIN (arg_chain))
570 s390_check_type_for_vector_abi (TREE_VALUE (arg_chain), true, false);
571 }
572 else if (RECORD_OR_UNION_TYPE_P (type))
573 {
574 tree field;
575
576 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
577 {
578 if (TREE_CODE (field) != FIELD_DECL)
579 continue;
580
581 s390_check_type_for_vector_abi (TREE_TYPE (field), arg_p, true);
582 }
583 }
584}
585
586
07f32359 587/* System z builtins. */
588
589#include "s390-builtins.h"
590
a8aefbef 591const unsigned int bflags_builtin[S390_BUILTIN_MAX + 1] =
07f32359 592 {
593#undef B_DEF
594#undef OB_DEF
595#undef OB_DEF_VAR
a8aefbef 596#define B_DEF(NAME, PATTERN, ATTRS, BFLAGS, ...) BFLAGS,
07f32359 597#define OB_DEF(...)
598#define OB_DEF_VAR(...)
599#include "s390-builtins.def"
600 0
601 };
602
a8aefbef 603const unsigned int opflags_builtin[S390_BUILTIN_MAX + 1] =
604 {
605#undef B_DEF
606#undef OB_DEF
607#undef OB_DEF_VAR
608#define B_DEF(NAME, PATTERN, ATTRS, BFLAGS, OPFLAGS, ...) OPFLAGS,
609#define OB_DEF(...)
610#define OB_DEF_VAR(...)
611#include "s390-builtins.def"
612 0
613 };
614
615const unsigned int bflags_overloaded_builtin[S390_OVERLOADED_BUILTIN_MAX + 1] =
616 {
617#undef B_DEF
618#undef OB_DEF
619#undef OB_DEF_VAR
620#define B_DEF(...)
621#define OB_DEF(NAME, FIRST_VAR_NAME, LAST_VAR_NAME, BFLAGS, ...) BFLAGS,
622#define OB_DEF_VAR(...)
623#include "s390-builtins.def"
624 0
625 };
626
063ed3cf 627const unsigned int
628bflags_overloaded_builtin_var[S390_OVERLOADED_BUILTIN_VAR_MAX + 1] =
629 {
630#undef B_DEF
631#undef OB_DEF
632#undef OB_DEF_VAR
633#define B_DEF(...)
634#define OB_DEF(...)
635#define OB_DEF_VAR(NAME, PATTERN, FLAGS, OPFLAGS, FNTYPE) FLAGS,
636#include "s390-builtins.def"
637 0
638 };
639
a8aefbef 640const unsigned int
641opflags_overloaded_builtin_var[S390_OVERLOADED_BUILTIN_VAR_MAX + 1] =
07f32359 642 {
643#undef B_DEF
644#undef OB_DEF
645#undef OB_DEF_VAR
646#define B_DEF(...)
647#define OB_DEF(...)
063ed3cf 648#define OB_DEF_VAR(NAME, PATTERN, FLAGS, OPFLAGS, FNTYPE) OPFLAGS,
07f32359 649#include "s390-builtins.def"
650 0
651 };
652
653tree s390_builtin_types[BT_MAX];
654tree s390_builtin_fn_types[BT_FN_MAX];
655tree s390_builtin_decls[S390_BUILTIN_MAX +
656 S390_OVERLOADED_BUILTIN_MAX +
657 S390_OVERLOADED_BUILTIN_VAR_MAX];
658
659static enum insn_code const code_for_builtin[S390_BUILTIN_MAX + 1] = {
660#undef B_DEF
661#undef OB_DEF
662#undef OB_DEF_VAR
663#define B_DEF(NAME, PATTERN, ...) CODE_FOR_##PATTERN,
664#define OB_DEF(...)
665#define OB_DEF_VAR(...)
666
667#include "s390-builtins.def"
668 CODE_FOR_nothing
669};
670
671static void
672s390_init_builtins (void)
673{
674 /* These definitions are being used in s390-builtins.def. */
675 tree returns_twice_attr = tree_cons (get_identifier ("returns_twice"),
676 NULL, NULL);
677 tree noreturn_attr = tree_cons (get_identifier ("noreturn"), NULL, NULL);
678 tree c_uint64_type_node;
679
680 /* The uint64_type_node from tree.c is not compatible to the C99
681 uint64_t data type. What we want is c_uint64_type_node from
682 c-common.c. But since backend code is not supposed to interface
683 with the frontend we recreate it here. */
684 if (TARGET_64BIT)
685 c_uint64_type_node = long_unsigned_type_node;
686 else
687 c_uint64_type_node = long_long_unsigned_type_node;
688
689#undef DEF_TYPE
f9378734 690#define DEF_TYPE(INDEX, NODE, CONST_P) \
7a0cee35 691 if (s390_builtin_types[INDEX] == NULL) \
a8aefbef 692 s390_builtin_types[INDEX] = (!CONST_P) ? \
693 (NODE) : build_type_variant ((NODE), 1, 0);
07f32359 694
695#undef DEF_POINTER_TYPE
f9378734 696#define DEF_POINTER_TYPE(INDEX, INDEX_BASE) \
7a0cee35 697 if (s390_builtin_types[INDEX] == NULL) \
a8aefbef 698 s390_builtin_types[INDEX] = \
699 build_pointer_type (s390_builtin_types[INDEX_BASE]);
07f32359 700
701#undef DEF_DISTINCT_TYPE
f9378734 702#define DEF_DISTINCT_TYPE(INDEX, INDEX_BASE) \
7a0cee35 703 if (s390_builtin_types[INDEX] == NULL) \
a8aefbef 704 s390_builtin_types[INDEX] = \
705 build_distinct_type_copy (s390_builtin_types[INDEX_BASE]);
07f32359 706
707#undef DEF_VECTOR_TYPE
f9378734 708#define DEF_VECTOR_TYPE(INDEX, INDEX_BASE, ELEMENTS) \
7a0cee35 709 if (s390_builtin_types[INDEX] == NULL) \
a8aefbef 710 s390_builtin_types[INDEX] = \
711 build_vector_type (s390_builtin_types[INDEX_BASE], ELEMENTS);
07f32359 712
713#undef DEF_OPAQUE_VECTOR_TYPE
f9378734 714#define DEF_OPAQUE_VECTOR_TYPE(INDEX, INDEX_BASE, ELEMENTS) \
7a0cee35 715 if (s390_builtin_types[INDEX] == NULL) \
a8aefbef 716 s390_builtin_types[INDEX] = \
717 build_opaque_vector_type (s390_builtin_types[INDEX_BASE], ELEMENTS);
07f32359 718
719#undef DEF_FN_TYPE
f9378734 720#define DEF_FN_TYPE(INDEX, args...) \
7a0cee35 721 if (s390_builtin_fn_types[INDEX] == NULL) \
a8aefbef 722 s390_builtin_fn_types[INDEX] = \
7a0cee35 723 build_function_type_list (args, NULL_TREE);
07f32359 724#undef DEF_OV_TYPE
725#define DEF_OV_TYPE(...)
726#include "s390-builtin-types.def"
727
728#undef B_DEF
a8aefbef 729#define B_DEF(NAME, PATTERN, ATTRS, BFLAGS, OPFLAGS, FNTYPE) \
7a0cee35 730 if (s390_builtin_decls[S390_BUILTIN_##NAME] == NULL) \
a8aefbef 731 s390_builtin_decls[S390_BUILTIN_##NAME] = \
732 add_builtin_function ("__builtin_" #NAME, \
733 s390_builtin_fn_types[FNTYPE], \
734 S390_BUILTIN_##NAME, \
735 BUILT_IN_MD, \
736 NULL, \
737 ATTRS);
07f32359 738#undef OB_DEF
a8aefbef 739#define OB_DEF(NAME, FIRST_VAR_NAME, LAST_VAR_NAME, BFLAGS, FNTYPE) \
7a0cee35 740 if (s390_builtin_decls[S390_OVERLOADED_BUILTIN_##NAME + S390_BUILTIN_MAX] \
741 == NULL) \
a8aefbef 742 s390_builtin_decls[S390_OVERLOADED_BUILTIN_##NAME + S390_BUILTIN_MAX] = \
743 add_builtin_function ("__builtin_" #NAME, \
744 s390_builtin_fn_types[FNTYPE], \
745 S390_OVERLOADED_BUILTIN_##NAME + S390_BUILTIN_MAX, \
746 BUILT_IN_MD, \
747 NULL, \
748 0);
07f32359 749#undef OB_DEF_VAR
750#define OB_DEF_VAR(...)
751#include "s390-builtins.def"
752
753}
754
755/* Return true if ARG is appropriate as argument number ARGNUM of
756 builtin DECL. The operand flags from s390-builtins.def have to
757 passed as OP_FLAGS. */
758bool
759s390_const_operand_ok (tree arg, int argnum, int op_flags, tree decl)
760{
761 if (O_UIMM_P (op_flags))
762 {
763 int bitwidths[] = { 1, 2, 3, 4, 5, 8, 12, 16, 32 };
764 int bitwidth = bitwidths[op_flags - O_U1];
765
766 if (!tree_fits_uhwi_p (arg)
b422d8c0 767 || tree_to_uhwi (arg) > (HOST_WIDE_INT_1U << bitwidth) - 1)
07f32359 768 {
769 error("constant argument %d for builtin %qF is out of range (0.."
770 HOST_WIDE_INT_PRINT_UNSIGNED ")",
771 argnum, decl,
b422d8c0 772 (HOST_WIDE_INT_1U << bitwidth) - 1);
07f32359 773 return false;
774 }
775 }
776
777 if (O_SIMM_P (op_flags))
778 {
779 int bitwidths[] = { 2, 3, 4, 5, 8, 12, 16, 32 };
780 int bitwidth = bitwidths[op_flags - O_S2];
781
782 if (!tree_fits_shwi_p (arg)
b422d8c0 783 || tree_to_shwi (arg) < -(HOST_WIDE_INT_1 << (bitwidth - 1))
784 || tree_to_shwi (arg) > ((HOST_WIDE_INT_1 << (bitwidth - 1)) - 1))
07f32359 785 {
786 error("constant argument %d for builtin %qF is out of range ("
787 HOST_WIDE_INT_PRINT_DEC ".."
788 HOST_WIDE_INT_PRINT_DEC ")",
789 argnum, decl,
b422d8c0 790 -(HOST_WIDE_INT_1 << (bitwidth - 1)),
791 (HOST_WIDE_INT_1 << (bitwidth - 1)) - 1);
07f32359 792 return false;
793 }
794 }
795 return true;
796}
797
798/* Expand an expression EXP that calls a built-in function,
799 with result going to TARGET if that's convenient
800 (and in mode MODE if that's convenient).
801 SUBTARGET may be used as the target for computing one of EXP's operands.
802 IGNORE is nonzero if the value is to be ignored. */
803
804static rtx
805s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
806 machine_mode mode ATTRIBUTE_UNUSED,
807 int ignore ATTRIBUTE_UNUSED)
808{
674b3578 809#define MAX_ARGS 6
07f32359 810
811 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
812 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
813 enum insn_code icode;
814 rtx op[MAX_ARGS], pat;
815 int arity;
816 bool nonvoid;
817 tree arg;
818 call_expr_arg_iterator iter;
a8aefbef 819 unsigned int all_op_flags = opflags_for_builtin (fcode);
07f32359 820 machine_mode last_vec_mode = VOIDmode;
821
822 if (TARGET_DEBUG_ARG)
823 {
824 fprintf (stderr,
7a0cee35 825 "s390_expand_builtin, code = %4d, %s, bflags = 0x%x\n",
826 (int)fcode, IDENTIFIER_POINTER (DECL_NAME (fndecl)),
827 bflags_for_builtin (fcode));
07f32359 828 }
829
7a0cee35 830 if (S390_USE_TARGET_ATTRIBUTE)
831 {
832 unsigned int bflags;
833
834 bflags = bflags_for_builtin (fcode);
835 if ((bflags & B_HTM) && !TARGET_HTM)
836 {
19abb0ad 837 error ("builtin %qF is not supported without -mhtm "
7a0cee35 838 "(default with -march=zEC12 and higher).", fndecl);
839 return const0_rtx;
840 }
c9213ca0 841 if (((bflags & B_VX) || (bflags & B_VXE)) && !TARGET_VX)
7a0cee35 842 {
063ed3cf 843 error ("builtin %qF requires -mvx "
7a0cee35 844 "(default with -march=z13 and higher).", fndecl);
845 return const0_rtx;
846 }
c9213ca0 847
848 if ((bflags & B_VXE) && !TARGET_VXE)
849 {
850 error ("Builtin %qF requires arch12 or higher.", fndecl);
851 return const0_rtx;
852 }
7a0cee35 853 }
07f32359 854 if (fcode >= S390_OVERLOADED_BUILTIN_VAR_OFFSET
855 && fcode < S390_ALL_BUILTIN_MAX)
856 {
857 gcc_unreachable ();
858 }
859 else if (fcode < S390_OVERLOADED_BUILTIN_OFFSET)
860 {
861 icode = code_for_builtin[fcode];
862 /* Set a flag in the machine specific cfun part in order to support
863 saving/restoring of FPRs. */
864 if (fcode == S390_BUILTIN_tbegin || fcode == S390_BUILTIN_tbegin_retry)
865 cfun->machine->tbegin_p = true;
866 }
867 else if (fcode < S390_OVERLOADED_BUILTIN_VAR_OFFSET)
868 {
19abb0ad 869 error ("unresolved overloaded builtin");
07f32359 870 return const0_rtx;
871 }
872 else
873 internal_error ("bad builtin fcode");
874
875 if (icode == 0)
876 internal_error ("bad builtin icode");
877
878 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
879
880 if (nonvoid)
881 {
882 machine_mode tmode = insn_data[icode].operand[0].mode;
883 if (!target
884 || GET_MODE (target) != tmode
885 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
886 target = gen_reg_rtx (tmode);
887
888 /* There are builtins (e.g. vec_promote) with no vector
889 arguments but an element selector. So we have to also look
890 at the vector return type when emitting the modulo
891 operation. */
892 if (VECTOR_MODE_P (insn_data[icode].operand[0].mode))
893 last_vec_mode = insn_data[icode].operand[0].mode;
894 }
895
896 arity = 0;
897 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
898 {
b0c401ca 899 rtx tmp_rtx;
07f32359 900 const struct insn_operand_data *insn_op;
901 unsigned int op_flags = all_op_flags & ((1 << O_SHIFT) - 1);
902
903 all_op_flags = all_op_flags >> O_SHIFT;
904
905 if (arg == error_mark_node)
906 return NULL_RTX;
907 if (arity >= MAX_ARGS)
908 return NULL_RTX;
909
910 if (O_IMM_P (op_flags)
911 && TREE_CODE (arg) != INTEGER_CST)
912 {
913 error ("constant value required for builtin %qF argument %d",
914 fndecl, arity + 1);
915 return const0_rtx;
916 }
917
918 if (!s390_const_operand_ok (arg, arity + 1, op_flags, fndecl))
919 return const0_rtx;
920
921 insn_op = &insn_data[icode].operand[arity + nonvoid];
922 op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, EXPAND_NORMAL);
923
0570ddf1 924 /* expand_expr truncates constants to the target mode only if it
925 is "convenient". However, our checks below rely on this
926 being done. */
927 if (CONST_INT_P (op[arity])
928 && SCALAR_INT_MODE_P (insn_op->mode)
929 && GET_MODE (op[arity]) != insn_op->mode)
930 op[arity] = GEN_INT (trunc_int_for_mode (INTVAL (op[arity]),
931 insn_op->mode));
932
07f32359 933 /* Wrap the expanded RTX for pointer types into a MEM expr with
934 the proper mode. This allows us to use e.g. (match_operand
935 "memory_operand"..) in the insn patterns instead of (mem
936 (match_operand "address_operand)). This is helpful for
937 patterns not just accepting MEMs. */
938 if (POINTER_TYPE_P (TREE_TYPE (arg))
939 && insn_op->predicate != address_operand)
940 op[arity] = gen_rtx_MEM (insn_op->mode, op[arity]);
941
942 /* Expand the module operation required on element selectors. */
943 if (op_flags == O_ELEM)
944 {
945 gcc_assert (last_vec_mode != VOIDmode);
946 op[arity] = simplify_expand_binop (SImode, code_to_optab (AND),
947 op[arity],
948 GEN_INT (GET_MODE_NUNITS (last_vec_mode) - 1),
949 NULL_RTX, 1, OPTAB_DIRECT);
950 }
951
952 /* Record the vector mode used for an element selector. This assumes:
953 1. There is no builtin with two different vector modes and an element selector
954 2. The element selector comes after the vector type it is referring to.
955 This currently the true for all the builtins but FIXME we
956 should better check for that. */
957 if (VECTOR_MODE_P (insn_op->mode))
958 last_vec_mode = insn_op->mode;
959
960 if (insn_op->predicate (op[arity], insn_op->mode))
961 {
962 arity++;
963 continue;
964 }
965
966 if (MEM_P (op[arity])
967 && insn_op->predicate == memory_operand
968 && (GET_MODE (XEXP (op[arity], 0)) == Pmode
969 || GET_MODE (XEXP (op[arity], 0)) == VOIDmode))
970 {
971 op[arity] = replace_equiv_address (op[arity],
972 copy_to_mode_reg (Pmode,
973 XEXP (op[arity], 0)));
974 }
b0c401ca 975 /* Some of the builtins require different modes/types than the
976 pattern in order to implement a specific API. Instead of
977 adding many expanders which do the mode change we do it here.
978 E.g. s390_vec_add_u128 required to have vector unsigned char
979 arguments is mapped to addti3. */
980 else if (insn_op->mode != VOIDmode
981 && GET_MODE (op[arity]) != VOIDmode
982 && GET_MODE (op[arity]) != insn_op->mode
983 && ((tmp_rtx = simplify_gen_subreg (insn_op->mode, op[arity],
984 GET_MODE (op[arity]), 0))
985 != NULL_RTX))
986 {
987 op[arity] = tmp_rtx;
988 }
07f32359 989 else if (GET_MODE (op[arity]) == insn_op->mode
990 || GET_MODE (op[arity]) == VOIDmode
991 || (insn_op->predicate == address_operand
992 && GET_MODE (op[arity]) == Pmode))
993 {
994 /* An address_operand usually has VOIDmode in the expander
995 so we cannot use this. */
996 machine_mode target_mode =
997 (insn_op->predicate == address_operand
998 ? Pmode : insn_op->mode);
999 op[arity] = copy_to_mode_reg (target_mode, op[arity]);
1000 }
1001
1002 if (!insn_op->predicate (op[arity], insn_op->mode))
1003 {
19abb0ad 1004 error ("invalid argument %d for builtin %qF", arity + 1, fndecl);
07f32359 1005 return const0_rtx;
1006 }
1007 arity++;
1008 }
1009
07f32359 1010 switch (arity)
1011 {
1012 case 0:
1013 pat = GEN_FCN (icode) (target);
1014 break;
1015 case 1:
1016 if (nonvoid)
1017 pat = GEN_FCN (icode) (target, op[0]);
1018 else
1019 pat = GEN_FCN (icode) (op[0]);
1020 break;
1021 case 2:
1022 if (nonvoid)
1023 pat = GEN_FCN (icode) (target, op[0], op[1]);
1024 else
1025 pat = GEN_FCN (icode) (op[0], op[1]);
1026 break;
1027 case 3:
1028 if (nonvoid)
1029 pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
1030 else
1031 pat = GEN_FCN (icode) (op[0], op[1], op[2]);
1032 break;
1033 case 4:
1034 if (nonvoid)
1035 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
1036 else
1037 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
1038 break;
1039 case 5:
1040 if (nonvoid)
1041 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3], op[4]);
1042 else
1043 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4]);
1044 break;
1045 case 6:
1046 if (nonvoid)
1047 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3], op[4], op[5]);
1048 else
1049 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5]);
1050 break;
1051 default:
1052 gcc_unreachable ();
1053 }
1054 if (!pat)
1055 return NULL_RTX;
1056 emit_insn (pat);
1057
1058 if (nonvoid)
1059 return target;
1060 else
1061 return const0_rtx;
1062}
1063
1064
11762b83 1065static const int s390_hotpatch_hw_max = 1000000;
1066static int s390_hotpatch_hw_before_label = 0;
1067static int s390_hotpatch_hw_after_label = 0;
77bc9912 1068
1069/* Check whether the hotpatch attribute is applied to a function and, if it has
1070 an argument, the argument is valid. */
1071
1072static tree
1073s390_handle_hotpatch_attribute (tree *node, tree name, tree args,
1074 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
1075{
11762b83 1076 tree expr;
1077 tree expr2;
1078 int err;
1079
77bc9912 1080 if (TREE_CODE (*node) != FUNCTION_DECL)
1081 {
1082 warning (OPT_Wattributes, "%qE attribute only applies to functions",
1083 name);
1084 *no_add_attrs = true;
1085 }
11762b83 1086 if (args != NULL && TREE_CHAIN (args) != NULL)
1087 {
1088 expr = TREE_VALUE (args);
1089 expr2 = TREE_VALUE (TREE_CHAIN (args));
1090 }
1091 if (args == NULL || TREE_CHAIN (args) == NULL)
1092 err = 1;
1093 else if (TREE_CODE (expr) != INTEGER_CST
1094 || !INTEGRAL_TYPE_P (TREE_TYPE (expr))
1095 || wi::gtu_p (expr, s390_hotpatch_hw_max))
1096 err = 1;
1097 else if (TREE_CODE (expr2) != INTEGER_CST
1098 || !INTEGRAL_TYPE_P (TREE_TYPE (expr2))
1099 || wi::gtu_p (expr2, s390_hotpatch_hw_max))
1100 err = 1;
1101 else
1102 err = 0;
1103 if (err)
77bc9912 1104 {
11762b83 1105 error ("requested %qE attribute is not a comma separated pair of"
1106 " non-negative integer constants or too large (max. %d)", name,
1107 s390_hotpatch_hw_max);
1108 *no_add_attrs = true;
77bc9912 1109 }
1110
1111 return NULL_TREE;
1112}
1113
07f32359 1114/* Expand the s390_vector_bool type attribute. */
1115
1116static tree
1117s390_handle_vectorbool_attribute (tree *node, tree name ATTRIBUTE_UNUSED,
1118 tree args ATTRIBUTE_UNUSED,
1119 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
1120{
1121 tree type = *node, result = NULL_TREE;
1122 machine_mode mode;
1123
1124 while (POINTER_TYPE_P (type)
1125 || TREE_CODE (type) == FUNCTION_TYPE
1126 || TREE_CODE (type) == METHOD_TYPE
1127 || TREE_CODE (type) == ARRAY_TYPE)
1128 type = TREE_TYPE (type);
1129
1130 mode = TYPE_MODE (type);
1131 switch (mode)
1132 {
1133 case DImode: case V2DImode: result = s390_builtin_types[BT_BV2DI]; break;
1134 case SImode: case V4SImode: result = s390_builtin_types[BT_BV4SI]; break;
1135 case HImode: case V8HImode: result = s390_builtin_types[BT_BV8HI]; break;
1136 case QImode: case V16QImode: result = s390_builtin_types[BT_BV16QI];
1137 default: break;
1138 }
1139
1140 *no_add_attrs = true; /* No need to hang on to the attribute. */
1141
1142 if (result)
1143 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
1144
1145 return NULL_TREE;
1146}
1147
77bc9912 1148static const struct attribute_spec s390_attribute_table[] = {
07f32359 1149 { "hotpatch", 2, 2, true, false, false, s390_handle_hotpatch_attribute, false },
1150 { "s390_vector_bool", 0, 0, false, true, false, s390_handle_vectorbool_attribute, true },
77bc9912 1151 /* End element. */
1152 { NULL, 0, 0, false, false, false, NULL, false }
1153};
1154
6d0afa28 1155/* Return the alignment for LABEL. We default to the -falign-labels
1156 value except for the literal pool base label. */
1157int
56d95ea5 1158s390_label_align (rtx_insn *label)
6d0afa28 1159{
50fc2d35 1160 rtx_insn *prev_insn = prev_active_insn (label);
1161 rtx set, src;
6d0afa28 1162
1163 if (prev_insn == NULL_RTX)
1164 goto old;
1165
50fc2d35 1166 set = single_set (prev_insn);
6d0afa28 1167
50fc2d35 1168 if (set == NULL_RTX)
6d0afa28 1169 goto old;
1170
50fc2d35 1171 src = SET_SRC (set);
6d0afa28 1172
1173 /* Don't align literal pool base labels. */
50fc2d35 1174 if (GET_CODE (src) == UNSPEC
1175 && XINT (src, 1) == UNSPEC_MAIN_BASE)
6d0afa28 1176 return 0;
1177
1178 old:
1179 return align_labels_log;
1180}
1181
3754d046 1182static machine_mode
0ef89dfd 1183s390_libgcc_cmp_return_mode (void)
1184{
1185 return TARGET_64BIT ? DImode : SImode;
1186}
1187
3754d046 1188static machine_mode
0ef89dfd 1189s390_libgcc_shift_count_mode (void)
1190{
1191 return TARGET_64BIT ? DImode : SImode;
1192}
1193
3754d046 1194static machine_mode
b5fdc416 1195s390_unwind_word_mode (void)
1196{
1197 return TARGET_64BIT ? DImode : SImode;
1198}
1199
36868490 1200/* Return true if the back end supports mode MODE. */
1201static bool
3754d046 1202s390_scalar_mode_supported_p (machine_mode mode)
36868490 1203{
b5fdc416 1204 /* In contrast to the default implementation reject TImode constants on 31bit
1205 TARGET_ZARCH for ABI compliance. */
1206 if (!TARGET_64BIT && TARGET_ZARCH && mode == TImode)
1207 return false;
1208
36868490 1209 if (DECIMAL_FLOAT_MODE_P (mode))
8e72d11d 1210 return default_decimal_float_supported_p ();
b5fdc416 1211
1212 return default_scalar_mode_supported_p (mode);
36868490 1213}
1214
76a4c804 1215/* Return true if the back end supports vector mode MODE. */
1216static bool
1217s390_vector_mode_supported_p (machine_mode mode)
1218{
1219 machine_mode inner;
1220
1221 if (!VECTOR_MODE_P (mode)
1222 || !TARGET_VX
1223 || GET_MODE_SIZE (mode) > 16)
1224 return false;
1225
1226 inner = GET_MODE_INNER (mode);
1227
1228 switch (inner)
1229 {
1230 case QImode:
1231 case HImode:
1232 case SImode:
1233 case DImode:
1234 case TImode:
1235 case SFmode:
1236 case DFmode:
1237 case TFmode:
1238 return true;
1239 default:
1240 return false;
1241 }
1242}
1243
1e639cb0 1244/* Set the has_landing_pad_p flag in struct machine_function to VALUE. */
1245
1246void
1247s390_set_has_landing_pad_p (bool value)
1248{
1249 cfun->machine->has_landing_pad_p = value;
1250}
6902d973 1251
9c93d843 1252/* If two condition code modes are compatible, return a condition code
1253 mode which is compatible with both. Otherwise, return
1254 VOIDmode. */
1255
3754d046 1256static machine_mode
1257s390_cc_modes_compatible (machine_mode m1, machine_mode m2)
9c93d843 1258{
1259 if (m1 == m2)
1260 return m1;
1261
1262 switch (m1)
1263 {
1264 case CCZmode:
1265 if (m2 == CCUmode || m2 == CCTmode || m2 == CCZ1mode
1266 || m2 == CCSmode || m2 == CCSRmode || m2 == CCURmode)
1267 return m2;
1268 return VOIDmode;
1269
1270 case CCSmode:
1271 case CCUmode:
1272 case CCTmode:
1273 case CCSRmode:
1274 case CCURmode:
1275 case CCZ1mode:
1276 if (m2 == CCZmode)
1277 return m1;
ffead1ca 1278
9c93d843 1279 return VOIDmode;
1280
1281 default:
1282 return VOIDmode;
1283 }
1284 return VOIDmode;
1285}
1286
56769981 1287/* Return true if SET either doesn't set the CC register, or else
f81e845f 1288 the source and destination have matching CC modes and that
56769981 1289 CC mode is at least as constrained as REQ_MODE. */
f81e845f 1290
e5537457 1291static bool
3754d046 1292s390_match_ccmode_set (rtx set, machine_mode req_mode)
4673c1a0 1293{
3754d046 1294 machine_mode set_mode;
4673c1a0 1295
32eda510 1296 gcc_assert (GET_CODE (set) == SET);
4673c1a0 1297
abc57c35 1298 /* These modes are supposed to be used only in CC consumer
1299 patterns. */
1300 gcc_assert (req_mode != CCVIALLmode && req_mode != CCVIANYmode
1301 && req_mode != CCVFALLmode && req_mode != CCVFANYmode);
1302
4673c1a0 1303 if (GET_CODE (SET_DEST (set)) != REG || !CC_REGNO_P (REGNO (SET_DEST (set))))
1304 return 1;
1305
1306 set_mode = GET_MODE (SET_DEST (set));
1307 switch (set_mode)
1308 {
4673c1a0 1309 case CCSmode:
c6821d1c 1310 case CCSRmode:
4673c1a0 1311 case CCUmode:
c6821d1c 1312 case CCURmode:
2eb8fe23 1313 case CCLmode:
c6821d1c 1314 case CCL1mode:
1315 case CCL2mode:
3b699fc7 1316 case CCL3mode:
c6821d1c 1317 case CCT1mode:
1318 case CCT2mode:
1319 case CCT3mode:
26233f43 1320 case CCVEQmode:
abc57c35 1321 case CCVIHmode:
1322 case CCVIHUmode:
26233f43 1323 case CCVFHmode:
1324 case CCVFHEmode:
c6821d1c 1325 if (req_mode != set_mode)
2eb8fe23 1326 return 0;
1327 break;
c6821d1c 1328
4673c1a0 1329 case CCZmode:
c6821d1c 1330 if (req_mode != CCSmode && req_mode != CCUmode && req_mode != CCTmode
1331 && req_mode != CCSRmode && req_mode != CCURmode)
4673c1a0 1332 return 0;
1333 break;
3c482144 1334
1335 case CCAPmode:
1336 case CCANmode:
1337 if (req_mode != CCAmode)
1338 return 0;
1339 break;
f81e845f 1340
4673c1a0 1341 default:
32eda510 1342 gcc_unreachable ();
4673c1a0 1343 }
f81e845f 1344
4673c1a0 1345 return (GET_MODE (SET_SRC (set)) == set_mode);
1346}
1347
f81e845f 1348/* Return true if every SET in INSN that sets the CC register
1349 has source and destination with matching CC modes and that
1350 CC mode is at least as constrained as REQ_MODE.
c6821d1c 1351 If REQ_MODE is VOIDmode, always return false. */
f81e845f 1352
e5537457 1353bool
3754d046 1354s390_match_ccmode (rtx_insn *insn, machine_mode req_mode)
4673c1a0 1355{
1356 int i;
1357
c6821d1c 1358 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
1359 if (req_mode == VOIDmode)
e5537457 1360 return false;
c6821d1c 1361
4673c1a0 1362 if (GET_CODE (PATTERN (insn)) == SET)
1363 return s390_match_ccmode_set (PATTERN (insn), req_mode);
1364
1365 if (GET_CODE (PATTERN (insn)) == PARALLEL)
1366 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
1367 {
1368 rtx set = XVECEXP (PATTERN (insn), 0, i);
1369 if (GET_CODE (set) == SET)
1370 if (!s390_match_ccmode_set (set, req_mode))
e5537457 1371 return false;
4673c1a0 1372 }
1373
e5537457 1374 return true;
4673c1a0 1375}
1376
f81e845f 1377/* If a test-under-mask instruction can be used to implement
c6821d1c 1378 (compare (and ... OP1) OP2), return the CC mode required
f81e845f 1379 to do that. Otherwise, return VOIDmode.
c6821d1c 1380 MIXED is true if the instruction can distinguish between
1381 CC1 and CC2 for mixed selected bits (TMxx), it is false
1382 if the instruction cannot (TM). */
1383
3754d046 1384machine_mode
e5537457 1385s390_tm_ccmode (rtx op1, rtx op2, bool mixed)
c6821d1c 1386{
1387 int bit0, bit1;
1388
ba0e61d6 1389 /* ??? Fixme: should work on CONST_WIDE_INT as well. */
c6821d1c 1390 if (GET_CODE (op1) != CONST_INT || GET_CODE (op2) != CONST_INT)
1391 return VOIDmode;
1392
eeba5f25 1393 /* Selected bits all zero: CC0.
1394 e.g.: int a; if ((a & (16 + 128)) == 0) */
c6821d1c 1395 if (INTVAL (op2) == 0)
1396 return CCTmode;
1397
ffead1ca 1398 /* Selected bits all one: CC3.
eeba5f25 1399 e.g.: int a; if ((a & (16 + 128)) == 16 + 128) */
c6821d1c 1400 if (INTVAL (op2) == INTVAL (op1))
1401 return CCT3mode;
1402
eeba5f25 1403 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. e.g.:
1404 int a;
1405 if ((a & (16 + 128)) == 16) -> CCT1
1406 if ((a & (16 + 128)) == 128) -> CCT2 */
c6821d1c 1407 if (mixed)
1408 {
1409 bit1 = exact_log2 (INTVAL (op2));
1410 bit0 = exact_log2 (INTVAL (op1) ^ INTVAL (op2));
1411 if (bit0 != -1 && bit1 != -1)
1412 return bit0 > bit1 ? CCT1mode : CCT2mode;
1413 }
1414
1415 return VOIDmode;
1416}
1417
f81e845f 1418/* Given a comparison code OP (EQ, NE, etc.) and the operands
1419 OP0 and OP1 of a COMPARE, return the mode to be used for the
2eb8fe23 1420 comparison. */
1421
3754d046 1422machine_mode
b40da9a7 1423s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
2eb8fe23 1424{
1425 switch (code)
1426 {
1427 case EQ:
1428 case NE:
9be33ca2 1429 if ((GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
1430 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
1431 return CCAPmode;
3c482144 1432 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
cb888f33 1433 && CONST_OK_FOR_K (INTVAL (XEXP (op0, 1))))
3c482144 1434 return CCAPmode;
e9fd5349 1435 if ((GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
1436 || GET_CODE (op1) == NEG)
1437 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
2eb8fe23 1438 return CCLmode;
1439
c6821d1c 1440 if (GET_CODE (op0) == AND)
1441 {
1442 /* Check whether we can potentially do it via TM. */
3754d046 1443 machine_mode ccmode;
c6821d1c 1444 ccmode = s390_tm_ccmode (XEXP (op0, 1), op1, 1);
1445 if (ccmode != VOIDmode)
1446 {
1447 /* Relax CCTmode to CCZmode to allow fall-back to AND
1448 if that turns out to be beneficial. */
1449 return ccmode == CCTmode ? CCZmode : ccmode;
1450 }
1451 }
1452
f81e845f 1453 if (register_operand (op0, HImode)
c6821d1c 1454 && GET_CODE (op1) == CONST_INT
1455 && (INTVAL (op1) == -1 || INTVAL (op1) == 65535))
1456 return CCT3mode;
f81e845f 1457 if (register_operand (op0, QImode)
c6821d1c 1458 && GET_CODE (op1) == CONST_INT
1459 && (INTVAL (op1) == -1 || INTVAL (op1) == 255))
1460 return CCT3mode;
1461
2eb8fe23 1462 return CCZmode;
1463
1464 case LE:
1465 case LT:
1466 case GE:
1467 case GT:
eeba5f25 1468 /* The only overflow condition of NEG and ABS happens when
1469 -INT_MAX is used as parameter, which stays negative. So
ffead1ca 1470 we have an overflow from a positive value to a negative.
eeba5f25 1471 Using CCAP mode the resulting cc can be used for comparisons. */
9be33ca2 1472 if ((GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
1473 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
1474 return CCAPmode;
eeba5f25 1475
1476 /* If constants are involved in an add instruction it is possible to use
1477 the resulting cc for comparisons with zero. Knowing the sign of the
0975351b 1478 constant the overflow behavior gets predictable. e.g.:
ffead1ca 1479 int a, b; if ((b = a + c) > 0)
eeba5f25 1480 with c as a constant value: c < 0 -> CCAN and c >= 0 -> CCAP */
9be33ca2 1481 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
ea14438e 1482 && (CONST_OK_FOR_K (INTVAL (XEXP (op0, 1)))
1483 || (CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0, 1)), 'O', "Os")
1484 /* Avoid INT32_MIN on 32 bit. */
1485 && (!TARGET_ZARCH || INTVAL (XEXP (op0, 1)) != -0x7fffffff - 1))))
9be33ca2 1486 {
1487 if (INTVAL (XEXP((op0), 1)) < 0)
1488 return CCANmode;
1489 else
1490 return CCAPmode;
1491 }
1492 /* Fall through. */
2eb8fe23 1493 case UNORDERED:
1494 case ORDERED:
1495 case UNEQ:
1496 case UNLE:
1497 case UNLT:
1498 case UNGE:
1499 case UNGT:
1500 case LTGT:
c6821d1c 1501 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
1502 && GET_CODE (op1) != CONST_INT)
1503 return CCSRmode;
2eb8fe23 1504 return CCSmode;
1505
2eb8fe23 1506 case LTU:
1507 case GEU:
e9fd5349 1508 if (GET_CODE (op0) == PLUS
1509 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
c6821d1c 1510 return CCL1mode;
1511
1512 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
1513 && GET_CODE (op1) != CONST_INT)
1514 return CCURmode;
1515 return CCUmode;
1516
1517 case LEU:
2eb8fe23 1518 case GTU:
e9fd5349 1519 if (GET_CODE (op0) == MINUS
1520 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
c6821d1c 1521 return CCL2mode;
1522
1523 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
1524 && GET_CODE (op1) != CONST_INT)
1525 return CCURmode;
2eb8fe23 1526 return CCUmode;
1527
1528 default:
32eda510 1529 gcc_unreachable ();
2eb8fe23 1530 }
1531}
1532
ebe32bb0 1533/* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
1534 that we can implement more efficiently. */
1535
d5065e6e 1536static void
1537s390_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
1538 bool op0_preserve_value)
ebe32bb0 1539{
d5065e6e 1540 if (op0_preserve_value)
1541 return;
1542
ebe32bb0 1543 /* Convert ZERO_EXTRACT back to AND to enable TM patterns. */
1544 if ((*code == EQ || *code == NE)
1545 && *op1 == const0_rtx
1546 && GET_CODE (*op0) == ZERO_EXTRACT
1547 && GET_CODE (XEXP (*op0, 1)) == CONST_INT
1548 && GET_CODE (XEXP (*op0, 2)) == CONST_INT
1549 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0, 0))))
1550 {
1551 rtx inner = XEXP (*op0, 0);
1552 HOST_WIDE_INT modesize = GET_MODE_BITSIZE (GET_MODE (inner));
1553 HOST_WIDE_INT len = INTVAL (XEXP (*op0, 1));
1554 HOST_WIDE_INT pos = INTVAL (XEXP (*op0, 2));
1555
1556 if (len > 0 && len < modesize
1557 && pos >= 0 && pos + len <= modesize
1558 && modesize <= HOST_BITS_PER_WIDE_INT)
1559 {
1560 unsigned HOST_WIDE_INT block;
b422d8c0 1561 block = (HOST_WIDE_INT_1U << len) - 1;
ebe32bb0 1562 block <<= modesize - pos - len;
1563
1564 *op0 = gen_rtx_AND (GET_MODE (inner), inner,
1565 gen_int_mode (block, GET_MODE (inner)));
1566 }
1567 }
1568
1569 /* Narrow AND of memory against immediate to enable TM. */
1570 if ((*code == EQ || *code == NE)
1571 && *op1 == const0_rtx
1572 && GET_CODE (*op0) == AND
1573 && GET_CODE (XEXP (*op0, 1)) == CONST_INT
1574 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0, 0))))
1575 {
1576 rtx inner = XEXP (*op0, 0);
1577 rtx mask = XEXP (*op0, 1);
1578
1579 /* Ignore paradoxical SUBREGs if all extra bits are masked out. */
1580 if (GET_CODE (inner) == SUBREG
1581 && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (inner)))
1582 && (GET_MODE_SIZE (GET_MODE (inner))
1583 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner))))
1584 && ((INTVAL (mask)
1585 & GET_MODE_MASK (GET_MODE (inner))
1586 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (inner))))
1587 == 0))
1588 inner = SUBREG_REG (inner);
1589
1590 /* Do not change volatile MEMs. */
1591 if (MEM_P (inner) && !MEM_VOLATILE_P (inner))
1592 {
1593 int part = s390_single_part (XEXP (*op0, 1),
1594 GET_MODE (inner), QImode, 0);
1595 if (part >= 0)
1596 {
1597 mask = gen_int_mode (s390_extract_part (mask, QImode, 0), QImode);
1598 inner = adjust_address_nv (inner, QImode, part);
1599 *op0 = gen_rtx_AND (QImode, inner, mask);
1600 }
1601 }
1602 }
1603
1604 /* Narrow comparisons against 0xffff to HImode if possible. */
ebe32bb0 1605 if ((*code == EQ || *code == NE)
1606 && GET_CODE (*op1) == CONST_INT
1607 && INTVAL (*op1) == 0xffff
1608 && SCALAR_INT_MODE_P (GET_MODE (*op0))
ffead1ca 1609 && (nonzero_bits (*op0, GET_MODE (*op0))
b422d8c0 1610 & ~HOST_WIDE_INT_UC (0xffff)) == 0)
ebe32bb0 1611 {
1612 *op0 = gen_lowpart (HImode, *op0);
1613 *op1 = constm1_rtx;
1614 }
80b53886 1615
5ada7a14 1616 /* Remove redundant UNSPEC_STRCMPCC_TO_INT conversions if possible. */
80b53886 1617 if (GET_CODE (*op0) == UNSPEC
5ada7a14 1618 && XINT (*op0, 1) == UNSPEC_STRCMPCC_TO_INT
80b53886 1619 && XVECLEN (*op0, 0) == 1
1620 && GET_MODE (XVECEXP (*op0, 0, 0)) == CCUmode
1621 && GET_CODE (XVECEXP (*op0, 0, 0)) == REG
1622 && REGNO (XVECEXP (*op0, 0, 0)) == CC_REGNUM
1623 && *op1 == const0_rtx)
1624 {
1625 enum rtx_code new_code = UNKNOWN;
1626 switch (*code)
1627 {
1628 case EQ: new_code = EQ; break;
1629 case NE: new_code = NE; break;
dd16a4bd 1630 case LT: new_code = GTU; break;
1631 case GT: new_code = LTU; break;
1632 case LE: new_code = GEU; break;
1633 case GE: new_code = LEU; break;
80b53886 1634 default: break;
1635 }
1636
1637 if (new_code != UNKNOWN)
1638 {
1639 *op0 = XVECEXP (*op0, 0, 0);
1640 *code = new_code;
1641 }
1642 }
9c93d843 1643
5ada7a14 1644 /* Remove redundant UNSPEC_CC_TO_INT conversions if possible. */
27784c70 1645 if (GET_CODE (*op0) == UNSPEC
5ada7a14 1646 && XINT (*op0, 1) == UNSPEC_CC_TO_INT
27784c70 1647 && XVECLEN (*op0, 0) == 1
27784c70 1648 && GET_CODE (XVECEXP (*op0, 0, 0)) == REG
1649 && REGNO (XVECEXP (*op0, 0, 0)) == CC_REGNUM
5ada7a14 1650 && CONST_INT_P (*op1))
27784c70 1651 {
1652 enum rtx_code new_code = UNKNOWN;
5ada7a14 1653 switch (GET_MODE (XVECEXP (*op0, 0, 0)))
27784c70 1654 {
5ada7a14 1655 case CCZmode:
1656 case CCRAWmode:
1657 switch (*code)
1658 {
1659 case EQ: new_code = EQ; break;
1660 case NE: new_code = NE; break;
1661 default: break;
1662 }
1663 break;
1664 default: break;
27784c70 1665 }
1666
1667 if (new_code != UNKNOWN)
1668 {
5ada7a14 1669 /* For CCRAWmode put the required cc mask into the second
1670 operand. */
91dfd73e 1671 if (GET_MODE (XVECEXP (*op0, 0, 0)) == CCRAWmode
1672 && INTVAL (*op1) >= 0 && INTVAL (*op1) <= 3)
5ada7a14 1673 *op1 = gen_rtx_CONST_INT (VOIDmode, 1 << (3 - INTVAL (*op1)));
27784c70 1674 *op0 = XVECEXP (*op0, 0, 0);
1675 *code = new_code;
1676 }
1677 }
1678
9c93d843 1679 /* Simplify cascaded EQ, NE with const0_rtx. */
1680 if ((*code == NE || *code == EQ)
1681 && (GET_CODE (*op0) == EQ || GET_CODE (*op0) == NE)
1682 && GET_MODE (*op0) == SImode
1683 && GET_MODE (XEXP (*op0, 0)) == CCZ1mode
1684 && REG_P (XEXP (*op0, 0))
1685 && XEXP (*op0, 1) == const0_rtx
1686 && *op1 == const0_rtx)
1687 {
1688 if ((*code == EQ && GET_CODE (*op0) == NE)
1689 || (*code == NE && GET_CODE (*op0) == EQ))
1690 *code = EQ;
1691 else
1692 *code = NE;
1693 *op0 = XEXP (*op0, 0);
1694 }
a0631a8a 1695
1696 /* Prefer register over memory as first operand. */
1697 if (MEM_P (*op0) && REG_P (*op1))
1698 {
1699 rtx tem = *op0; *op0 = *op1; *op1 = tem;
d5065e6e 1700 *code = (int)swap_condition ((enum rtx_code)*code);
a0631a8a 1701 }
26233f43 1702
e17ed6ec 1703 /* A comparison result is compared against zero. Replace it with
1704 the (perhaps inverted) original comparison.
1705 This probably should be done by simplify_relational_operation. */
1706 if ((*code == EQ || *code == NE)
1707 && *op1 == const0_rtx
1708 && COMPARISON_P (*op0)
1709 && CC_REG_P (XEXP (*op0, 0)))
1710 {
1711 enum rtx_code new_code;
1712
1713 if (*code == EQ)
1714 new_code = reversed_comparison_code_parts (GET_CODE (*op0),
1715 XEXP (*op0, 0),
1716 XEXP (*op1, 0), NULL);
1717 else
1718 new_code = GET_CODE (*op0);
1719
1720 if (new_code != UNKNOWN)
1721 {
1722 *code = new_code;
1723 *op1 = XEXP (*op0, 1);
1724 *op0 = XEXP (*op0, 0);
1725 }
1726 }
ebe32bb0 1727}
1728
26233f43 1729
0d656e8b 1730/* Emit a compare instruction suitable to implement the comparison
1731 OP0 CODE OP1. Return the correct condition RTL to be placed in
1732 the IF_THEN_ELSE of the conditional branch testing the result. */
1733
1734rtx
1735s390_emit_compare (enum rtx_code code, rtx op0, rtx op1)
1736{
3754d046 1737 machine_mode mode = s390_select_ccmode (code, op0, op1);
8e58aded 1738 rtx cc;
0d656e8b 1739
29c098f6 1740 if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
8e58aded 1741 {
26233f43 1742 /* Do not output a redundant compare instruction if a
1743 compare_and_swap pattern already computed the result and the
1744 machine modes are compatible. */
8e58aded 1745 gcc_assert (s390_cc_modes_compatible (GET_MODE (op0), mode)
1746 == GET_MODE (op0));
1747 cc = op0;
1748 }
891e3096 1749 else
1750 {
8e58aded 1751 cc = gen_rtx_REG (mode, CC_REGNUM);
d1f9b275 1752 emit_insn (gen_rtx_SET (cc, gen_rtx_COMPARE (mode, op0, op1)));
891e3096 1753 }
8e58aded 1754
ffead1ca 1755 return gen_rtx_fmt_ee (code, VOIDmode, cc, const0_rtx);
0d656e8b 1756}
1757
8deb3959 1758/* Emit a SImode compare and swap instruction setting MEM to NEW_RTX if OLD
db1f11e3 1759 matches CMP.
1760 Return the correct condition RTL to be placed in the IF_THEN_ELSE of the
1761 conditional branch testing the result. */
1762
1763static rtx
8c753480 1764s390_emit_compare_and_swap (enum rtx_code code, rtx old, rtx mem,
1765 rtx cmp, rtx new_rtx)
db1f11e3 1766{
8c753480 1767 emit_insn (gen_atomic_compare_and_swapsi_internal (old, mem, cmp, new_rtx));
1768 return s390_emit_compare (code, gen_rtx_REG (CCZ1mode, CC_REGNUM),
1769 const0_rtx);
db1f11e3 1770}
1771
5ada7a14 1772/* Emit a jump instruction to TARGET and return it. If COND is
1773 NULL_RTX, emit an unconditional jump, else a conditional jump under
1774 condition COND. */
0d656e8b 1775
93e0956b 1776rtx_insn *
0d656e8b 1777s390_emit_jump (rtx target, rtx cond)
1778{
1779 rtx insn;
1780
1781 target = gen_rtx_LABEL_REF (VOIDmode, target);
1782 if (cond)
1783 target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, target, pc_rtx);
1784
d1f9b275 1785 insn = gen_rtx_SET (pc_rtx, target);
5ada7a14 1786 return emit_jump_insn (insn);
0d656e8b 1787}
1788
f81e845f 1789/* Return branch condition mask to implement a branch
80b53886 1790 specified by CODE. Return -1 for invalid comparisons. */
2eb8fe23 1791
8cc5de33 1792int
b40da9a7 1793s390_branch_condition_mask (rtx code)
f81e845f 1794{
2eb8fe23 1795 const int CC0 = 1 << 3;
1796 const int CC1 = 1 << 2;
1797 const int CC2 = 1 << 1;
1798 const int CC3 = 1 << 0;
1799
32eda510 1800 gcc_assert (GET_CODE (XEXP (code, 0)) == REG);
1801 gcc_assert (REGNO (XEXP (code, 0)) == CC_REGNUM);
5ada7a14 1802 gcc_assert (XEXP (code, 1) == const0_rtx
1803 || (GET_MODE (XEXP (code, 0)) == CCRAWmode
1804 && CONST_INT_P (XEXP (code, 1))));
1805
2eb8fe23 1806
1807 switch (GET_MODE (XEXP (code, 0)))
1808 {
1809 case CCZmode:
9c93d843 1810 case CCZ1mode:
2eb8fe23 1811 switch (GET_CODE (code))
1812 {
1813 case EQ: return CC0;
1814 case NE: return CC1 | CC2 | CC3;
80b53886 1815 default: return -1;
2eb8fe23 1816 }
1817 break;
1818
c6821d1c 1819 case CCT1mode:
1820 switch (GET_CODE (code))
1821 {
1822 case EQ: return CC1;
1823 case NE: return CC0 | CC2 | CC3;
80b53886 1824 default: return -1;
c6821d1c 1825 }
1826 break;
1827
1828 case CCT2mode:
1829 switch (GET_CODE (code))
1830 {
1831 case EQ: return CC2;
1832 case NE: return CC0 | CC1 | CC3;
80b53886 1833 default: return -1;
c6821d1c 1834 }
1835 break;
1836
1837 case CCT3mode:
1838 switch (GET_CODE (code))
1839 {
1840 case EQ: return CC3;
1841 case NE: return CC0 | CC1 | CC2;
80b53886 1842 default: return -1;
c6821d1c 1843 }
1844 break;
1845
2eb8fe23 1846 case CCLmode:
1847 switch (GET_CODE (code))
1848 {
1849 case EQ: return CC0 | CC2;
1850 case NE: return CC1 | CC3;
80b53886 1851 default: return -1;
c6821d1c 1852 }
1853 break;
1854
1855 case CCL1mode:
1856 switch (GET_CODE (code))
1857 {
1858 case LTU: return CC2 | CC3; /* carry */
1859 case GEU: return CC0 | CC1; /* no carry */
80b53886 1860 default: return -1;
c6821d1c 1861 }
1862 break;
1863
1864 case CCL2mode:
1865 switch (GET_CODE (code))
1866 {
1867 case GTU: return CC0 | CC1; /* borrow */
1868 case LEU: return CC2 | CC3; /* no borrow */
80b53886 1869 default: return -1;
2eb8fe23 1870 }
1871 break;
1872
3b699fc7 1873 case CCL3mode:
1874 switch (GET_CODE (code))
1875 {
1876 case EQ: return CC0 | CC2;
1877 case NE: return CC1 | CC3;
1878 case LTU: return CC1;
1879 case GTU: return CC3;
1880 case LEU: return CC1 | CC2;
1881 case GEU: return CC2 | CC3;
80b53886 1882 default: return -1;
3b699fc7 1883 }
1884
2eb8fe23 1885 case CCUmode:
1886 switch (GET_CODE (code))
1887 {
1888 case EQ: return CC0;
1889 case NE: return CC1 | CC2 | CC3;
1890 case LTU: return CC1;
1891 case GTU: return CC2;
1892 case LEU: return CC0 | CC1;
1893 case GEU: return CC0 | CC2;
80b53886 1894 default: return -1;
2eb8fe23 1895 }
1896 break;
1897
c6821d1c 1898 case CCURmode:
1899 switch (GET_CODE (code))
1900 {
1901 case EQ: return CC0;
1902 case NE: return CC2 | CC1 | CC3;
1903 case LTU: return CC2;
1904 case GTU: return CC1;
1905 case LEU: return CC0 | CC2;
1906 case GEU: return CC0 | CC1;
80b53886 1907 default: return -1;
c6821d1c 1908 }
1909 break;
1910
3c482144 1911 case CCAPmode:
1912 switch (GET_CODE (code))
1913 {
1914 case EQ: return CC0;
1915 case NE: return CC1 | CC2 | CC3;
1916 case LT: return CC1 | CC3;
1917 case GT: return CC2;
1918 case LE: return CC0 | CC1 | CC3;
1919 case GE: return CC0 | CC2;
80b53886 1920 default: return -1;
3c482144 1921 }
1922 break;
1923
1924 case CCANmode:
1925 switch (GET_CODE (code))
1926 {
1927 case EQ: return CC0;
1928 case NE: return CC1 | CC2 | CC3;
1929 case LT: return CC1;
1930 case GT: return CC2 | CC3;
1931 case LE: return CC0 | CC1;
1932 case GE: return CC0 | CC2 | CC3;
80b53886 1933 default: return -1;
3c482144 1934 }
1935 break;
1936
2eb8fe23 1937 case CCSmode:
1938 switch (GET_CODE (code))
1939 {
1940 case EQ: return CC0;
1941 case NE: return CC1 | CC2 | CC3;
1942 case LT: return CC1;
1943 case GT: return CC2;
1944 case LE: return CC0 | CC1;
1945 case GE: return CC0 | CC2;
1946 case UNORDERED: return CC3;
1947 case ORDERED: return CC0 | CC1 | CC2;
1948 case UNEQ: return CC0 | CC3;
1949 case UNLT: return CC1 | CC3;
1950 case UNGT: return CC2 | CC3;
1951 case UNLE: return CC0 | CC1 | CC3;
1952 case UNGE: return CC0 | CC2 | CC3;
1953 case LTGT: return CC1 | CC2;
80b53886 1954 default: return -1;
2eb8fe23 1955 }
c6821d1c 1956 break;
1957
1958 case CCSRmode:
1959 switch (GET_CODE (code))
1960 {
1961 case EQ: return CC0;
1962 case NE: return CC2 | CC1 | CC3;
1963 case LT: return CC2;
1964 case GT: return CC1;
1965 case LE: return CC0 | CC2;
1966 case GE: return CC0 | CC1;
1967 case UNORDERED: return CC3;
1968 case ORDERED: return CC0 | CC2 | CC1;
1969 case UNEQ: return CC0 | CC3;
1970 case UNLT: return CC2 | CC3;
1971 case UNGT: return CC1 | CC3;
1972 case UNLE: return CC0 | CC2 | CC3;
1973 case UNGE: return CC0 | CC1 | CC3;
1974 case LTGT: return CC2 | CC1;
80b53886 1975 default: return -1;
c6821d1c 1976 }
1977 break;
2eb8fe23 1978
26233f43 1979 /* Vector comparison modes. */
abc57c35 1980 /* CC2 will never be set. It however is part of the negated
1981 masks. */
1982 case CCVIALLmode:
26233f43 1983 switch (GET_CODE (code))
1984 {
abc57c35 1985 case EQ:
1986 case GTU:
1987 case GT:
1988 case GE: return CC0;
1989 /* The inverted modes are in fact *any* modes. */
1990 case NE:
1991 case LEU:
1992 case LE:
1993 case LT: return CC3 | CC1 | CC2;
26233f43 1994 default: return -1;
1995 }
07f32359 1996
abc57c35 1997 case CCVIANYmode:
07f32359 1998 switch (GET_CODE (code))
1999 {
abc57c35 2000 case EQ:
2001 case GTU:
2002 case GT:
2003 case GE: return CC0 | CC1;
2004 /* The inverted modes are in fact *all* modes. */
2005 case NE:
2006 case LEU:
2007 case LE:
2008 case LT: return CC3 | CC2;
07f32359 2009 default: return -1;
2010 }
abc57c35 2011 case CCVFALLmode:
26233f43 2012 switch (GET_CODE (code))
2013 {
abc57c35 2014 case EQ:
2015 case GT:
26233f43 2016 case GE: return CC0;
abc57c35 2017 /* The inverted modes are in fact *any* modes. */
2018 case NE:
2019 case UNLE:
2020 case UNLT: return CC3 | CC1 | CC2;
26233f43 2021 default: return -1;
2022 }
07f32359 2023
abc57c35 2024 case CCVFANYmode:
07f32359 2025 switch (GET_CODE (code))
2026 {
abc57c35 2027 case EQ:
2028 case GT:
07f32359 2029 case GE: return CC0 | CC1;
abc57c35 2030 /* The inverted modes are in fact *all* modes. */
2031 case NE:
2032 case UNLE:
2033 case UNLT: return CC3 | CC2;
07f32359 2034 default: return -1;
2035 }
2036
5ada7a14 2037 case CCRAWmode:
2038 switch (GET_CODE (code))
2039 {
2040 case EQ:
2041 return INTVAL (XEXP (code, 1));
2042 case NE:
2043 return (INTVAL (XEXP (code, 1))) ^ 0xf;
2044 default:
2045 gcc_unreachable ();
2046 }
2047
2eb8fe23 2048 default:
80b53886 2049 return -1;
2eb8fe23 2050 }
2051}
2052
e68d6a13 2053
2054/* Return branch condition mask to implement a compare and branch
2055 specified by CODE. Return -1 for invalid comparisons. */
2056
2057int
2058s390_compare_and_branch_condition_mask (rtx code)
2059{
2060 const int CC0 = 1 << 3;
2061 const int CC1 = 1 << 2;
2062 const int CC2 = 1 << 1;
2063
2064 switch (GET_CODE (code))
2065 {
2066 case EQ:
2067 return CC0;
2068 case NE:
2069 return CC1 | CC2;
2070 case LT:
2071 case LTU:
2072 return CC1;
2073 case GT:
2074 case GTU:
2075 return CC2;
2076 case LE:
2077 case LEU:
2078 return CC0 | CC1;
2079 case GE:
2080 case GEU:
2081 return CC0 | CC2;
2082 default:
2083 gcc_unreachable ();
2084 }
2085 return -1;
2086}
2087
f81e845f 2088/* If INV is false, return assembler mnemonic string to implement
2089 a branch specified by CODE. If INV is true, return mnemonic
2eb8fe23 2090 for the corresponding inverted branch. */
2091
2092static const char *
b40da9a7 2093s390_branch_condition_mnemonic (rtx code, int inv)
2eb8fe23 2094{
e68d6a13 2095 int mask;
2096
c8834c5f 2097 static const char *const mnemonic[16] =
2eb8fe23 2098 {
2099 NULL, "o", "h", "nle",
2100 "l", "nhe", "lh", "ne",
2101 "e", "nlh", "he", "nl",
2102 "le", "nh", "no", NULL
2103 };
2104
e68d6a13 2105 if (GET_CODE (XEXP (code, 0)) == REG
2106 && REGNO (XEXP (code, 0)) == CC_REGNUM
5ada7a14 2107 && (XEXP (code, 1) == const0_rtx
2108 || (GET_MODE (XEXP (code, 0)) == CCRAWmode
2109 && CONST_INT_P (XEXP (code, 1)))))
e68d6a13 2110 mask = s390_branch_condition_mask (code);
2111 else
2112 mask = s390_compare_and_branch_condition_mask (code);
2113
80b53886 2114 gcc_assert (mask >= 0);
2eb8fe23 2115
2116 if (inv)
2117 mask ^= 15;
2118
32eda510 2119 gcc_assert (mask >= 1 && mask <= 14);
2eb8fe23 2120
2121 return mnemonic[mask];
2122}
2123
64a1078f 2124/* Return the part of op which has a value different from def.
2125 The size of the part is determined by mode.
f588eb9f 2126 Use this function only if you already know that op really
64a1078f 2127 contains such a part. */
8b4a4127 2128
64a1078f 2129unsigned HOST_WIDE_INT
3754d046 2130s390_extract_part (rtx op, machine_mode mode, int def)
8b4a4127 2131{
64a1078f 2132 unsigned HOST_WIDE_INT value = 0;
2133 int max_parts = HOST_BITS_PER_WIDE_INT / GET_MODE_BITSIZE (mode);
2134 int part_bits = GET_MODE_BITSIZE (mode);
b422d8c0 2135 unsigned HOST_WIDE_INT part_mask = (HOST_WIDE_INT_1U << part_bits) - 1;
64a1078f 2136 int i;
f588eb9f 2137
64a1078f 2138 for (i = 0; i < max_parts; i++)
8b4a4127 2139 {
64a1078f 2140 if (i == 0)
b422d8c0 2141 value = UINTVAL (op);
8b4a4127 2142 else
64a1078f 2143 value >>= part_bits;
f588eb9f 2144
64a1078f 2145 if ((value & part_mask) != (def & part_mask))
2146 return value & part_mask;
8b4a4127 2147 }
f588eb9f 2148
32eda510 2149 gcc_unreachable ();
8b4a4127 2150}
2151
2152/* If OP is an integer constant of mode MODE with exactly one
64a1078f 2153 part of mode PART_MODE unequal to DEF, return the number of that
2154 part. Otherwise, return -1. */
8b4a4127 2155
2156int
f588eb9f 2157s390_single_part (rtx op,
3754d046 2158 machine_mode mode,
2159 machine_mode part_mode,
64a1078f 2160 int def)
2161{
2162 unsigned HOST_WIDE_INT value = 0;
2163 int n_parts = GET_MODE_SIZE (mode) / GET_MODE_SIZE (part_mode);
0451e449 2164 unsigned HOST_WIDE_INT part_mask
b422d8c0 2165 = (HOST_WIDE_INT_1U << GET_MODE_BITSIZE (part_mode)) - 1;
64a1078f 2166 int i, part = -1;
2167
2168 if (GET_CODE (op) != CONST_INT)
2169 return -1;
f588eb9f 2170
64a1078f 2171 for (i = 0; i < n_parts; i++)
2172 {
2173 if (i == 0)
b422d8c0 2174 value = UINTVAL (op);
8b4a4127 2175 else
64a1078f 2176 value >>= GET_MODE_BITSIZE (part_mode);
f588eb9f 2177
64a1078f 2178 if ((value & part_mask) != (def & part_mask))
2179 {
2180 if (part != -1)
2181 return -1;
2182 else
2183 part = i;
2184 }
8b4a4127 2185 }
64a1078f 2186 return part == -1 ? -1 : n_parts - 1 - part;
8b4a4127 2187}
2188
e68d6a13 2189/* Return true if IN contains a contiguous bitfield in the lower SIZE
e64f5133 2190 bits and no other bits are set in (the lower SIZE bits of) IN.
e68d6a13 2191
e64f5133 2192 PSTART and PEND can be used to obtain the start and end
2193 position (inclusive) of the bitfield relative to 64
2194 bits. *PSTART / *PEND gives the position of the first/last bit
2195 of the bitfield counting from the highest order bit starting
2196 with zero. */
e68d6a13 2197
2198bool
e64f5133 2199s390_contiguous_bitmask_nowrap_p (unsigned HOST_WIDE_INT in, int size,
2200 int *pstart, int *pend)
e68d6a13 2201{
e64f5133 2202 int start;
2203 int end = -1;
b422d8c0 2204 int lowbit = HOST_BITS_PER_WIDE_INT - 1;
2205 int highbit = HOST_BITS_PER_WIDE_INT - size;
2206 unsigned HOST_WIDE_INT bitmask = HOST_WIDE_INT_1U;
e64f5133 2207
2208 gcc_assert (!!pstart == !!pend);
2209 for (start = lowbit; start >= highbit; bitmask <<= 1, start--)
2210 if (end == -1)
2211 {
2212 /* Look for the rightmost bit of a contiguous range of ones. */
2213 if (bitmask & in)
2214 /* Found it. */
2215 end = start;
2216 }
2217 else
2218 {
2219 /* Look for the firt zero bit after the range of ones. */
2220 if (! (bitmask & in))
2221 /* Found it. */
2222 break;
2223 }
2224 /* We're one past the last one-bit. */
2225 start++;
e68d6a13 2226
e64f5133 2227 if (end == -1)
2228 /* No one bits found. */
2229 return false;
2230
2231 if (start > highbit)
e68d6a13 2232 {
e64f5133 2233 unsigned HOST_WIDE_INT mask;
2234
2235 /* Calculate a mask for all bits beyond the contiguous bits. */
b422d8c0 2236 mask = ((~HOST_WIDE_INT_0U >> highbit)
2237 & (~HOST_WIDE_INT_0U << (lowbit - start + 1)));
e64f5133 2238 if (mask & in)
2239 /* There are more bits set beyond the first range of one bits. */
2240 return false;
e68d6a13 2241 }
2242
e64f5133 2243 if (pstart)
2244 {
2245 *pstart = start;
2246 *pend = end;
2247 }
e68d6a13 2248
e64f5133 2249 return true;
2250}
e68d6a13 2251
e64f5133 2252/* Same as s390_contiguous_bitmask_nowrap_p but also returns true
2253 if ~IN contains a contiguous bitfield. In that case, *END is <
2254 *START.
76a4c804 2255
e64f5133 2256 If WRAP_P is true, a bitmask that wraps around is also tested.
2257 When a wraparoud occurs *START is greater than *END (in
2258 non-null pointers), and the uppermost (64 - SIZE) bits are thus
2259 part of the range. If WRAP_P is false, no wraparound is
2260 tested. */
e68d6a13 2261
e64f5133 2262bool
2263s390_contiguous_bitmask_p (unsigned HOST_WIDE_INT in, bool wrap_p,
2264 int size, int *start, int *end)
2265{
b422d8c0 2266 int bs = HOST_BITS_PER_WIDE_INT;
e64f5133 2267 bool b;
2268
2269 gcc_assert (!!start == !!end);
b422d8c0 2270 if ((in & ((~HOST_WIDE_INT_0U) >> (bs - size))) == 0)
e64f5133 2271 /* This cannot be expressed as a contiguous bitmask. Exit early because
2272 the second call of s390_contiguous_bitmask_nowrap_p would accept this as
2273 a valid bitmask. */
e68d6a13 2274 return false;
e64f5133 2275 b = s390_contiguous_bitmask_nowrap_p (in, size, start, end);
2276 if (b)
2277 return true;
2278 if (! wrap_p)
2279 return false;
2280 b = s390_contiguous_bitmask_nowrap_p (~in, size, start, end);
2281 if (b && start)
2282 {
2283 int s = *start;
2284 int e = *end;
e68d6a13 2285
e64f5133 2286 gcc_assert (s >= 1);
2287 *start = ((e + 1) & (bs - 1));
2288 *end = ((s - 1 + bs) & (bs - 1));
2289 }
e68d6a13 2290
e64f5133 2291 return b;
e68d6a13 2292}
2293
76a4c804 2294/* Return true if OP contains the same contiguous bitfield in *all*
2295 its elements. START and END can be used to obtain the start and
2296 end position of the bitfield.
2297
2298 START/STOP give the position of the first/last bit of the bitfield
2299 counting from the lowest order bit starting with zero. In order to
2300 use these values for S/390 instructions this has to be converted to
2301 "bits big endian" style. */
2302
2303bool
2304s390_contiguous_bitmask_vector_p (rtx op, int *start, int *end)
2305{
2306 unsigned HOST_WIDE_INT mask;
e64f5133 2307 int size;
62fdb8e4 2308 rtx elt;
e64f5133 2309 bool b;
76a4c804 2310
e64f5133 2311 gcc_assert (!!start == !!end);
62fdb8e4 2312 if (!const_vec_duplicate_p (op, &elt)
2313 || !CONST_INT_P (elt))
76a4c804 2314 return false;
2315
76a4c804 2316 size = GET_MODE_UNIT_BITSIZE (GET_MODE (op));
f81e57c4 2317
2318 /* We cannot deal with V1TI/V1TF. This would require a vgmq. */
2319 if (size > 64)
2320 return false;
2321
62fdb8e4 2322 mask = UINTVAL (elt);
e64f5133 2323
2324 b = s390_contiguous_bitmask_p (mask, true, size, start, end);
2325 if (b)
76a4c804 2326 {
e64f5133 2327 if (start)
2328 {
b422d8c0 2329 *start -= (HOST_BITS_PER_WIDE_INT - size);
2330 *end -= (HOST_BITS_PER_WIDE_INT - size);
e64f5133 2331 }
76a4c804 2332 return true;
2333 }
e64f5133 2334 else
2335 return false;
76a4c804 2336}
2337
2338/* Return true if C consists only of byte chunks being either 0 or
2339 0xff. If MASK is !=NULL a byte mask is generated which is
2340 appropriate for the vector generate byte mask instruction. */
2341
2342bool
2343s390_bytemask_vector_p (rtx op, unsigned *mask)
2344{
2345 int i;
2346 unsigned tmp_mask = 0;
2347 int nunit, unit_size;
2348
2349 if (!VECTOR_MODE_P (GET_MODE (op))
2350 || GET_CODE (op) != CONST_VECTOR
2351 || !CONST_INT_P (XVECEXP (op, 0, 0)))
2352 return false;
2353
2354 nunit = GET_MODE_NUNITS (GET_MODE (op));
2355 unit_size = GET_MODE_UNIT_SIZE (GET_MODE (op));
2356
2357 for (i = 0; i < nunit; i++)
2358 {
2359 unsigned HOST_WIDE_INT c;
2360 int j;
2361
2362 if (!CONST_INT_P (XVECEXP (op, 0, i)))
2363 return false;
2364
2365 c = UINTVAL (XVECEXP (op, 0, i));
2366 for (j = 0; j < unit_size; j++)
2367 {
2368 if ((c & 0xff) != 0 && (c & 0xff) != 0xff)
2369 return false;
2370 tmp_mask |= (c & 1) << ((nunit - 1 - i) * unit_size + j);
2371 c = c >> BITS_PER_UNIT;
2372 }
2373 }
2374
2375 if (mask != NULL)
2376 *mask = tmp_mask;
2377
2378 return true;
2379}
2380
6bc28655 2381/* Check whether a rotate of ROTL followed by an AND of CONTIG is
2382 equivalent to a shift followed by the AND. In particular, CONTIG
2383 should not overlap the (rotated) bit 0/bit 63 gap. Negative values
2384 for ROTL indicate a rotate to the right. */
2385
2386bool
2387s390_extzv_shift_ok (int bitsize, int rotl, unsigned HOST_WIDE_INT contig)
2388{
e64f5133 2389 int start, end;
6bc28655 2390 bool ok;
2391
e64f5133 2392 ok = s390_contiguous_bitmask_nowrap_p (contig, bitsize, &start, &end);
6bc28655 2393 gcc_assert (ok);
2394
e64f5133 2395 if (rotl >= 0)
2396 return (64 - end >= rotl);
2397 else
2398 {
2399 /* Translate "- rotate right" in BITSIZE mode to "rotate left" in
2400 DIMode. */
2401 rotl = -rotl + (64 - bitsize);
2402 return (start >= rotl);
2403 }
6bc28655 2404}
2405
f81e845f 2406/* Check whether we can (and want to) split a double-word
2407 move in mode MODE from SRC to DST into two single-word
66795431 2408 moves, moving the subword FIRST_SUBWORD first. */
2409
2410bool
3754d046 2411s390_split_ok_p (rtx dst, rtx src, machine_mode mode, int first_subword)
66795431 2412{
76a4c804 2413 /* Floating point and vector registers cannot be split. */
2414 if (FP_REG_P (src) || FP_REG_P (dst) || VECTOR_REG_P (src) || VECTOR_REG_P (dst))
66795431 2415 return false;
2416
66795431 2417 /* Non-offsettable memory references cannot be split. */
2418 if ((GET_CODE (src) == MEM && !offsettable_memref_p (src))
2419 || (GET_CODE (dst) == MEM && !offsettable_memref_p (dst)))
2420 return false;
2421
2422 /* Moving the first subword must not clobber a register
2423 needed to move the second subword. */
2424 if (register_operand (dst, mode))
2425 {
2426 rtx subreg = operand_subword (dst, first_subword, 0, mode);
2427 if (reg_overlap_mentioned_p (subreg, src))
2428 return false;
2429 }
2430
2431 return true;
2432}
2433
74bdf297 2434/* Return true if it can be proven that [MEM1, MEM1 + SIZE]
2435 and [MEM2, MEM2 + SIZE] do overlap and false
2436 otherwise. */
2437
2438bool
2439s390_overlap_p (rtx mem1, rtx mem2, HOST_WIDE_INT size)
2440{
2441 rtx addr1, addr2, addr_delta;
2442 HOST_WIDE_INT delta;
2443
2444 if (GET_CODE (mem1) != MEM || GET_CODE (mem2) != MEM)
2445 return true;
2446
2447 if (size == 0)
2448 return false;
2449
2450 addr1 = XEXP (mem1, 0);
2451 addr2 = XEXP (mem2, 0);
2452
2453 addr_delta = simplify_binary_operation (MINUS, Pmode, addr2, addr1);
2454
2455 /* This overlapping check is used by peepholes merging memory block operations.
2456 Overlapping operations would otherwise be recognized by the S/390 hardware
ffead1ca 2457 and would fall back to a slower implementation. Allowing overlapping
74bdf297 2458 operations would lead to slow code but not to wrong code. Therefore we are
ffead1ca 2459 somewhat optimistic if we cannot prove that the memory blocks are
74bdf297 2460 overlapping.
2461 That's why we return false here although this may accept operations on
2462 overlapping memory areas. */
2463 if (!addr_delta || GET_CODE (addr_delta) != CONST_INT)
2464 return false;
2465
2466 delta = INTVAL (addr_delta);
2467
2468 if (delta == 0
2469 || (delta > 0 && delta < size)
2470 || (delta < 0 && -delta < size))
2471 return true;
2472
2473 return false;
2474}
2475
9dffd3ff 2476/* Check whether the address of memory reference MEM2 equals exactly
2477 the address of memory reference MEM1 plus DELTA. Return true if
2478 we can prove this to be the case, false otherwise. */
2479
2480bool
2481s390_offset_p (rtx mem1, rtx mem2, rtx delta)
2482{
2483 rtx addr1, addr2, addr_delta;
2484
2485 if (GET_CODE (mem1) != MEM || GET_CODE (mem2) != MEM)
2486 return false;
2487
2488 addr1 = XEXP (mem1, 0);
2489 addr2 = XEXP (mem2, 0);
2490
2491 addr_delta = simplify_binary_operation (MINUS, Pmode, addr2, addr1);
2492 if (!addr_delta || !rtx_equal_p (addr_delta, delta))
2493 return false;
2494
2495 return true;
2496}
2497
3e247a31 2498/* Expand logical operator CODE in mode MODE with operands OPERANDS. */
2499
2500void
3754d046 2501s390_expand_logical_operator (enum rtx_code code, machine_mode mode,
3e247a31 2502 rtx *operands)
2503{
3754d046 2504 machine_mode wmode = mode;
3e247a31 2505 rtx dst = operands[0];
2506 rtx src1 = operands[1];
2507 rtx src2 = operands[2];
2508 rtx op, clob, tem;
2509
2510 /* If we cannot handle the operation directly, use a temp register. */
2511 if (!s390_logical_operator_ok_p (operands))
2512 dst = gen_reg_rtx (mode);
2513
2514 /* QImode and HImode patterns make sense only if we have a destination
2515 in memory. Otherwise perform the operation in SImode. */
2516 if ((mode == QImode || mode == HImode) && GET_CODE (dst) != MEM)
2517 wmode = SImode;
2518
2519 /* Widen operands if required. */
2520 if (mode != wmode)
2521 {
2522 if (GET_CODE (dst) == SUBREG
2523 && (tem = simplify_subreg (wmode, dst, mode, 0)) != 0)
2524 dst = tem;
2525 else if (REG_P (dst))
2526 dst = gen_rtx_SUBREG (wmode, dst, 0);
2527 else
2528 dst = gen_reg_rtx (wmode);
2529
2530 if (GET_CODE (src1) == SUBREG
2531 && (tem = simplify_subreg (wmode, src1, mode, 0)) != 0)
2532 src1 = tem;
2533 else if (GET_MODE (src1) != VOIDmode)
2534 src1 = gen_rtx_SUBREG (wmode, force_reg (mode, src1), 0);
2535
2536 if (GET_CODE (src2) == SUBREG
2537 && (tem = simplify_subreg (wmode, src2, mode, 0)) != 0)
2538 src2 = tem;
2539 else if (GET_MODE (src2) != VOIDmode)
2540 src2 = gen_rtx_SUBREG (wmode, force_reg (mode, src2), 0);
2541 }
2542
2543 /* Emit the instruction. */
d1f9b275 2544 op = gen_rtx_SET (dst, gen_rtx_fmt_ee (code, wmode, src1, src2));
3e247a31 2545 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
2546 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
2547
2548 /* Fix up the destination if needed. */
2549 if (dst != operands[0])
2550 emit_move_insn (operands[0], gen_lowpart (mode, dst));
2551}
2552
2553/* Check whether OPERANDS are OK for a logical operation (AND, IOR, XOR). */
2554
2555bool
2556s390_logical_operator_ok_p (rtx *operands)
2557{
2558 /* If the destination operand is in memory, it needs to coincide
2559 with one of the source operands. After reload, it has to be
2560 the first source operand. */
2561 if (GET_CODE (operands[0]) == MEM)
2562 return rtx_equal_p (operands[0], operands[1])
2563 || (!reload_completed && rtx_equal_p (operands[0], operands[2]));
2564
2565 return true;
2566}
2567
3f56e755 2568/* Narrow logical operation CODE of memory operand MEMOP with immediate
2569 operand IMMOP to switch from SS to SI type instructions. */
2570
2571void
2572s390_narrow_logical_operator (enum rtx_code code, rtx *memop, rtx *immop)
2573{
2574 int def = code == AND ? -1 : 0;
2575 HOST_WIDE_INT mask;
2576 int part;
2577
2578 gcc_assert (GET_CODE (*memop) == MEM);
2579 gcc_assert (!MEM_VOLATILE_P (*memop));
2580
2581 mask = s390_extract_part (*immop, QImode, def);
2582 part = s390_single_part (*immop, GET_MODE (*memop), QImode, def);
2583 gcc_assert (part >= 0);
2584
2585 *memop = adjust_address (*memop, QImode, part);
2586 *immop = gen_int_mode (mask, QImode);
2587}
2588
2eb8fe23 2589
875862bf 2590/* How to allocate a 'struct machine_function'. */
2591
2592static struct machine_function *
2593s390_init_machine_status (void)
2594{
25a27413 2595 return ggc_cleared_alloc<machine_function> ();
875862bf 2596}
2597
4673c1a0 2598/* Map for smallest class containing reg regno. */
2599
c8834c5f 2600const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
76a4c804 2601{ GENERAL_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS, /* 0 */
2602 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS, /* 4 */
2603 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS, /* 8 */
2604 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS, /* 12 */
2605 FP_REGS, FP_REGS, FP_REGS, FP_REGS, /* 16 */
2606 FP_REGS, FP_REGS, FP_REGS, FP_REGS, /* 20 */
2607 FP_REGS, FP_REGS, FP_REGS, FP_REGS, /* 24 */
2608 FP_REGS, FP_REGS, FP_REGS, FP_REGS, /* 28 */
2609 ADDR_REGS, CC_REGS, ADDR_REGS, ADDR_REGS, /* 32 */
2610 ACCESS_REGS, ACCESS_REGS, VEC_REGS, VEC_REGS, /* 36 */
2611 VEC_REGS, VEC_REGS, VEC_REGS, VEC_REGS, /* 40 */
2612 VEC_REGS, VEC_REGS, VEC_REGS, VEC_REGS, /* 44 */
2613 VEC_REGS, VEC_REGS, VEC_REGS, VEC_REGS, /* 48 */
2614 VEC_REGS, VEC_REGS /* 52 */
4673c1a0 2615};
2616
71343e6b 2617/* Return attribute type of insn. */
2618
2619static enum attr_type
ed3e6e5d 2620s390_safe_attr_type (rtx_insn *insn)
71343e6b 2621{
2622 if (recog_memoized (insn) >= 0)
2623 return get_attr_type (insn);
2624 else
2625 return TYPE_NONE;
2626}
4673c1a0 2627
51aa1e9c 2628/* Return true if DISP is a valid short displacement. */
2629
e5537457 2630static bool
b40da9a7 2631s390_short_displacement (rtx disp)
51aa1e9c 2632{
2633 /* No displacement is OK. */
2634 if (!disp)
e5537457 2635 return true;
51aa1e9c 2636
a7b49046 2637 /* Without the long displacement facility we don't need to
2638 distingiush between long and short displacement. */
2639 if (!TARGET_LONG_DISPLACEMENT)
2640 return true;
2641
51aa1e9c 2642 /* Integer displacement in range. */
2643 if (GET_CODE (disp) == CONST_INT)
2644 return INTVAL (disp) >= 0 && INTVAL (disp) < 4096;
2645
2646 /* GOT offset is not OK, the GOT can be large. */
2647 if (GET_CODE (disp) == CONST
2648 && GET_CODE (XEXP (disp, 0)) == UNSPEC
a6e4e903 2649 && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOT
2650 || XINT (XEXP (disp, 0), 1) == UNSPEC_GOTNTPOFF))
e5537457 2651 return false;
51aa1e9c 2652
2653 /* All other symbolic constants are literal pool references,
2654 which are OK as the literal pool must be small. */
2655 if (GET_CODE (disp) == CONST)
e5537457 2656 return true;
51aa1e9c 2657
e5537457 2658 return false;
51aa1e9c 2659}
2660
875862bf 2661/* Decompose a RTL expression ADDR for a memory address into
2662 its components, returned in OUT.
a5004c3d 2663
e5537457 2664 Returns false if ADDR is not a valid memory address, true
875862bf 2665 otherwise. If OUT is NULL, don't return the components,
2666 but check for validity only.
a5004c3d 2667
875862bf 2668 Note: Only addresses in canonical form are recognized.
2669 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
2670 canonical form so that they will be recognized. */
64a1078f 2671
875862bf 2672static int
edd89d66 2673s390_decompose_address (rtx addr, struct s390_address *out)
875862bf 2674{
2675 HOST_WIDE_INT offset = 0;
2676 rtx base = NULL_RTX;
2677 rtx indx = NULL_RTX;
2678 rtx disp = NULL_RTX;
2679 rtx orig_disp;
e5537457 2680 bool pointer = false;
2681 bool base_ptr = false;
2682 bool indx_ptr = false;
05b58257 2683 bool literal_pool = false;
2684
2685 /* We may need to substitute the literal pool base register into the address
2686 below. However, at this point we do not know which register is going to
2687 be used as base, so we substitute the arg pointer register. This is going
2688 to be treated as holding a pointer below -- it shouldn't be used for any
2689 other purpose. */
2690 rtx fake_pool_base = gen_rtx_REG (Pmode, ARG_POINTER_REGNUM);
3f56e755 2691
875862bf 2692 /* Decompose address into base + index + displacement. */
3f56e755 2693
875862bf 2694 if (GET_CODE (addr) == REG || GET_CODE (addr) == UNSPEC)
2695 base = addr;
3f56e755 2696
875862bf 2697 else if (GET_CODE (addr) == PLUS)
6b1c8423 2698 {
875862bf 2699 rtx op0 = XEXP (addr, 0);
2700 rtx op1 = XEXP (addr, 1);
2701 enum rtx_code code0 = GET_CODE (op0);
2702 enum rtx_code code1 = GET_CODE (op1);
6b1c8423 2703
875862bf 2704 if (code0 == REG || code0 == UNSPEC)
2705 {
2706 if (code1 == REG || code1 == UNSPEC)
2707 {
2708 indx = op0; /* index + base */
2709 base = op1;
2710 }
6b1c8423 2711
875862bf 2712 else
2713 {
2714 base = op0; /* base + displacement */
2715 disp = op1;
2716 }
2717 }
a5004c3d 2718
875862bf 2719 else if (code0 == PLUS)
51aa1e9c 2720 {
875862bf 2721 indx = XEXP (op0, 0); /* index + base + disp */
2722 base = XEXP (op0, 1);
2723 disp = op1;
51aa1e9c 2724 }
51aa1e9c 2725
875862bf 2726 else
51aa1e9c 2727 {
e5537457 2728 return false;
51aa1e9c 2729 }
875862bf 2730 }
51aa1e9c 2731
875862bf 2732 else
2733 disp = addr; /* displacement */
51aa1e9c 2734
875862bf 2735 /* Extract integer part of displacement. */
2736 orig_disp = disp;
2737 if (disp)
2738 {
2739 if (GET_CODE (disp) == CONST_INT)
51aa1e9c 2740 {
875862bf 2741 offset = INTVAL (disp);
2742 disp = NULL_RTX;
51aa1e9c 2743 }
875862bf 2744 else if (GET_CODE (disp) == CONST
2745 && GET_CODE (XEXP (disp, 0)) == PLUS
2746 && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT)
2747 {
2748 offset = INTVAL (XEXP (XEXP (disp, 0), 1));
2749 disp = XEXP (XEXP (disp, 0), 0);
2750 }
2751 }
51aa1e9c 2752
875862bf 2753 /* Strip off CONST here to avoid special case tests later. */
2754 if (disp && GET_CODE (disp) == CONST)
2755 disp = XEXP (disp, 0);
63ebd742 2756
875862bf 2757 /* We can convert literal pool addresses to
2758 displacements by basing them off the base register. */
2759 if (disp && GET_CODE (disp) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (disp))
2760 {
58ad9b54 2761 if (base || indx)
2762 return false;
2763
2764 base = fake_pool_base, literal_pool = true;
875862bf 2765
2766 /* Mark up the displacement. */
2767 disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp),
2768 UNSPEC_LTREL_OFFSET);
51aa1e9c 2769 }
a5004c3d 2770
875862bf 2771 /* Validate base register. */
2772 if (base)
2773 {
2774 if (GET_CODE (base) == UNSPEC)
2775 switch (XINT (base, 1))
2776 {
2777 case UNSPEC_LTREF:
2778 if (!disp)
ffead1ca 2779 disp = gen_rtx_UNSPEC (Pmode,
875862bf 2780 gen_rtvec (1, XVECEXP (base, 0, 0)),
2781 UNSPEC_LTREL_OFFSET);
2782 else
e5537457 2783 return false;
a5004c3d 2784
05b58257 2785 base = XVECEXP (base, 0, 1);
875862bf 2786 break;
64a1078f 2787
875862bf 2788 case UNSPEC_LTREL_BASE:
05b58257 2789 if (XVECLEN (base, 0) == 1)
2790 base = fake_pool_base, literal_pool = true;
2791 else
2792 base = XVECEXP (base, 0, 1);
875862bf 2793 break;
64a1078f 2794
875862bf 2795 default:
e5537457 2796 return false;
875862bf 2797 }
64a1078f 2798
a25e52e9 2799 if (!REG_P (base) || GET_MODE (base) != Pmode)
e5537457 2800 return false;
875862bf 2801
05b58257 2802 if (REGNO (base) == STACK_POINTER_REGNUM
875862bf 2803 || REGNO (base) == FRAME_POINTER_REGNUM
2804 || ((reload_completed || reload_in_progress)
2805 && frame_pointer_needed
2806 && REGNO (base) == HARD_FRAME_POINTER_REGNUM)
2807 || REGNO (base) == ARG_POINTER_REGNUM
2808 || (flag_pic
2809 && REGNO (base) == PIC_OFFSET_TABLE_REGNUM))
e5537457 2810 pointer = base_ptr = true;
05b58257 2811
2812 if ((reload_completed || reload_in_progress)
2813 && base == cfun->machine->base_reg)
2814 pointer = base_ptr = literal_pool = true;
875862bf 2815 }
2816
2817 /* Validate index register. */
2818 if (indx)
64a1078f 2819 {
875862bf 2820 if (GET_CODE (indx) == UNSPEC)
2821 switch (XINT (indx, 1))
2822 {
2823 case UNSPEC_LTREF:
2824 if (!disp)
ffead1ca 2825 disp = gen_rtx_UNSPEC (Pmode,
875862bf 2826 gen_rtvec (1, XVECEXP (indx, 0, 0)),
2827 UNSPEC_LTREL_OFFSET);
2828 else
e5537457 2829 return false;
64a1078f 2830
05b58257 2831 indx = XVECEXP (indx, 0, 1);
875862bf 2832 break;
64a1078f 2833
875862bf 2834 case UNSPEC_LTREL_BASE:
05b58257 2835 if (XVECLEN (indx, 0) == 1)
2836 indx = fake_pool_base, literal_pool = true;
2837 else
2838 indx = XVECEXP (indx, 0, 1);
875862bf 2839 break;
64a1078f 2840
875862bf 2841 default:
e5537457 2842 return false;
875862bf 2843 }
64a1078f 2844
a25e52e9 2845 if (!REG_P (indx) || GET_MODE (indx) != Pmode)
e5537457 2846 return false;
64a1078f 2847
05b58257 2848 if (REGNO (indx) == STACK_POINTER_REGNUM
875862bf 2849 || REGNO (indx) == FRAME_POINTER_REGNUM
2850 || ((reload_completed || reload_in_progress)
2851 && frame_pointer_needed
2852 && REGNO (indx) == HARD_FRAME_POINTER_REGNUM)
2853 || REGNO (indx) == ARG_POINTER_REGNUM
2854 || (flag_pic
2855 && REGNO (indx) == PIC_OFFSET_TABLE_REGNUM))
e5537457 2856 pointer = indx_ptr = true;
05b58257 2857
2858 if ((reload_completed || reload_in_progress)
2859 && indx == cfun->machine->base_reg)
2860 pointer = indx_ptr = literal_pool = true;
875862bf 2861 }
f588eb9f 2862
875862bf 2863 /* Prefer to use pointer as base, not index. */
2864 if (base && indx && !base_ptr
2865 && (indx_ptr || (!REG_POINTER (base) && REG_POINTER (indx))))
2866 {
2867 rtx tmp = base;
2868 base = indx;
2869 indx = tmp;
2870 }
64a1078f 2871
875862bf 2872 /* Validate displacement. */
2873 if (!disp)
2874 {
ffead1ca 2875 /* If virtual registers are involved, the displacement will change later
2876 anyway as the virtual registers get eliminated. This could make a
2877 valid displacement invalid, but it is more likely to make an invalid
2878 displacement valid, because we sometimes access the register save area
119114cb 2879 via negative offsets to one of those registers.
875862bf 2880 Thus we don't check the displacement for validity here. If after
2881 elimination the displacement turns out to be invalid after all,
2882 this is fixed up by reload in any case. */
7b1bda1c 2883 /* LRA maintains always displacements up to date and we need to
2884 know the displacement is right during all LRA not only at the
2885 final elimination. */
2886 if (lra_in_progress
2887 || (base != arg_pointer_rtx
2888 && indx != arg_pointer_rtx
2889 && base != return_address_pointer_rtx
2890 && indx != return_address_pointer_rtx
2891 && base != frame_pointer_rtx
2892 && indx != frame_pointer_rtx
2893 && base != virtual_stack_vars_rtx
2894 && indx != virtual_stack_vars_rtx))
875862bf 2895 if (!DISP_IN_RANGE (offset))
e5537457 2896 return false;
875862bf 2897 }
2898 else
2899 {
2900 /* All the special cases are pointers. */
e5537457 2901 pointer = true;
64a1078f 2902
875862bf 2903 /* In the small-PIC case, the linker converts @GOT
2904 and @GOTNTPOFF offsets to possible displacements. */
2905 if (GET_CODE (disp) == UNSPEC
2906 && (XINT (disp, 1) == UNSPEC_GOT
2907 || XINT (disp, 1) == UNSPEC_GOTNTPOFF)
875862bf 2908 && flag_pic == 1)
2909 {
2910 ;
2911 }
64a1078f 2912
1ed7a160 2913 /* Accept pool label offsets. */
2914 else if (GET_CODE (disp) == UNSPEC
2915 && XINT (disp, 1) == UNSPEC_POOL_OFFSET)
2916 ;
64a1078f 2917
875862bf 2918 /* Accept literal pool references. */
2919 else if (GET_CODE (disp) == UNSPEC
2920 && XINT (disp, 1) == UNSPEC_LTREL_OFFSET)
2921 {
cf8ffe7d 2922 /* In case CSE pulled a non literal pool reference out of
2923 the pool we have to reject the address. This is
2924 especially important when loading the GOT pointer on non
2925 zarch CPUs. In this case the literal pool contains an lt
2926 relative offset to the _GLOBAL_OFFSET_TABLE_ label which
2927 will most likely exceed the displacement. */
2928 if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF
2929 || !CONSTANT_POOL_ADDRESS_P (XVECEXP (disp, 0, 0)))
2930 return false;
2931
875862bf 2932 orig_disp = gen_rtx_CONST (Pmode, disp);
2933 if (offset)
2934 {
2935 /* If we have an offset, make sure it does not
2936 exceed the size of the constant pool entry. */
2937 rtx sym = XVECEXP (disp, 0, 0);
2938 if (offset >= GET_MODE_SIZE (get_pool_mode (sym)))
e5537457 2939 return false;
64a1078f 2940
29c05e22 2941 orig_disp = plus_constant (Pmode, orig_disp, offset);
875862bf 2942 }
2943 }
2944
2945 else
e5537457 2946 return false;
64a1078f 2947 }
2948
875862bf 2949 if (!base && !indx)
e5537457 2950 pointer = true;
875862bf 2951
2952 if (out)
2953 {
2954 out->base = base;
2955 out->indx = indx;
2956 out->disp = orig_disp;
2957 out->pointer = pointer;
05b58257 2958 out->literal_pool = literal_pool;
875862bf 2959 }
2960
e5537457 2961 return true;
64a1078f 2962}
2963
2be7449b 2964/* Decompose a RTL expression OP for an address style operand into its
2965 components, and return the base register in BASE and the offset in
2966 OFFSET. While OP looks like an address it is never supposed to be
2967 used as such.
6d6be381 2968
2be7449b 2969 Return true if OP is a valid address operand, false if not. */
6d6be381 2970
2971bool
2be7449b 2972s390_decompose_addrstyle_without_index (rtx op, rtx *base,
2973 HOST_WIDE_INT *offset)
6d6be381 2974{
6191f2a0 2975 rtx off = NULL_RTX;
6d6be381 2976
6d6be381 2977 /* We can have an integer constant, an address register,
2978 or a sum of the two. */
6191f2a0 2979 if (CONST_SCALAR_INT_P (op))
6d6be381 2980 {
6191f2a0 2981 off = op;
6d6be381 2982 op = NULL_RTX;
2983 }
6191f2a0 2984 if (op && GET_CODE (op) == PLUS && CONST_SCALAR_INT_P (XEXP (op, 1)))
6d6be381 2985 {
6191f2a0 2986 off = XEXP (op, 1);
6d6be381 2987 op = XEXP (op, 0);
2988 }
2989 while (op && GET_CODE (op) == SUBREG)
2990 op = SUBREG_REG (op);
2991
2992 if (op && GET_CODE (op) != REG)
2993 return false;
2994
2995 if (offset)
6191f2a0 2996 {
2997 if (off == NULL_RTX)
2998 *offset = 0;
2999 else if (CONST_INT_P (off))
3000 *offset = INTVAL (off);
3001 else if (CONST_WIDE_INT_P (off))
3002 /* The offset will anyway be cut down to 12 bits so take just
3003 the lowest order chunk of the wide int. */
3004 *offset = CONST_WIDE_INT_ELT (off, 0);
3005 else
3006 gcc_unreachable ();
3007 }
6d6be381 3008 if (base)
3009 *base = op;
3010
3011 return true;
3012}
3013
3014
875862bf 3015/* Return true if CODE is a valid address without index. */
fab7adbf 3016
875862bf 3017bool
3018s390_legitimate_address_without_index_p (rtx op)
3019{
3020 struct s390_address addr;
3021
3022 if (!s390_decompose_address (XEXP (op, 0), &addr))
3023 return false;
3024 if (addr.indx)
3025 return false;
3026
3027 return true;
3028}
3029
59bc01b3 3030
2a672556 3031/* Return TRUE if ADDR is an operand valid for a load/store relative
3032 instruction. Be aware that the alignment of the operand needs to
3033 be checked separately.
3034 Valid addresses are single references or a sum of a reference and a
3035 constant integer. Return these parts in SYMREF and ADDEND. You can
3036 pass NULL in REF and/or ADDEND if you are not interested in these
3037 values. Literal pool references are *not* considered symbol
3038 references. */
875862bf 3039
a7b49046 3040static bool
2a672556 3041s390_loadrelative_operand_p (rtx addr, rtx *symref, HOST_WIDE_INT *addend)
875862bf 3042{
a7b49046 3043 HOST_WIDE_INT tmpaddend = 0;
875862bf 3044
a7b49046 3045 if (GET_CODE (addr) == CONST)
3046 addr = XEXP (addr, 0);
3047
3048 if (GET_CODE (addr) == PLUS)
875862bf 3049 {
2a672556 3050 if (!CONST_INT_P (XEXP (addr, 1)))
a7b49046 3051 return false;
875862bf 3052
2a672556 3053 tmpaddend = INTVAL (XEXP (addr, 1));
3054 addr = XEXP (addr, 0);
3055 }
62cb5855 3056
2a672556 3057 if ((GET_CODE (addr) == SYMBOL_REF && !CONSTANT_POOL_ADDRESS_P (addr))
3058 || (GET_CODE (addr) == UNSPEC
3059 && (XINT (addr, 1) == UNSPEC_GOTENT
3060 || (TARGET_CPU_ZARCH && XINT (addr, 1) == UNSPEC_PLT))))
3061 {
3062 if (symref)
3063 *symref = addr;
3064 if (addend)
3065 *addend = tmpaddend;
62cb5855 3066
2a672556 3067 return true;
3068 }
3069 return false;
62cb5855 3070}
a7b49046 3071
3072/* Return true if the address in OP is valid for constraint letter C
3073 if wrapped in a MEM rtx. Set LIT_POOL_OK to true if it literal
3074 pool MEMs should be accepted. Only the Q, R, S, T constraint
3075 letters are allowed for C. */
875862bf 3076
a7b49046 3077static int
3078s390_check_qrst_address (char c, rtx op, bool lit_pool_ok)
3079{
3080 struct s390_address addr;
3081 bool decomposed = false;
3082
3083 /* This check makes sure that no symbolic address (except literal
3084 pool references) are accepted by the R or T constraints. */
2a672556 3085 if (s390_loadrelative_operand_p (op, NULL, NULL))
f3959569 3086 return 0;
3087
3088 /* Ensure literal pool references are only accepted if LIT_POOL_OK. */
3089 if (!lit_pool_ok)
875862bf 3090 {
a7b49046 3091 if (!s390_decompose_address (op, &addr))
875862bf 3092 return 0;
f3959569 3093 if (addr.literal_pool)
875862bf 3094 return 0;
a7b49046 3095 decomposed = true;
875862bf 3096 }
3097
7396c35d 3098 /* With reload, we sometimes get intermediate address forms that are
3099 actually invalid as-is, but we need to accept them in the most
3100 generic cases below ('R' or 'T'), since reload will in fact fix
3101 them up. LRA behaves differently here; we never see such forms,
3102 but on the other hand, we need to strictly reject every invalid
3103 address form. Perform this check right up front. */
3104 if (lra_in_progress)
3105 {
3106 if (!decomposed && !s390_decompose_address (op, &addr))
3107 return 0;
3108 decomposed = true;
3109 }
3110
875862bf 3111 switch (c)
3112 {
a7b49046 3113 case 'Q': /* no index short displacement */
3114 if (!decomposed && !s390_decompose_address (op, &addr))
875862bf 3115 return 0;
3116 if (addr.indx)
3117 return 0;
a7b49046 3118 if (!s390_short_displacement (addr.disp))
875862bf 3119 return 0;
a7b49046 3120 break;
875862bf 3121
a7b49046 3122 case 'R': /* with index short displacement */
875862bf 3123 if (TARGET_LONG_DISPLACEMENT)
3124 {
a7b49046 3125 if (!decomposed && !s390_decompose_address (op, &addr))
875862bf 3126 return 0;
3127 if (!s390_short_displacement (addr.disp))
3128 return 0;
3129 }
a7b49046 3130 /* Any invalid address here will be fixed up by reload,
3131 so accept it for the most generic constraint. */
875862bf 3132 break;
3133
a7b49046 3134 case 'S': /* no index long displacement */
a7b49046 3135 if (!decomposed && !s390_decompose_address (op, &addr))
875862bf 3136 return 0;
3137 if (addr.indx)
3138 return 0;
875862bf 3139 break;
3140
a7b49046 3141 case 'T': /* with index long displacement */
a7b49046 3142 /* Any invalid address here will be fixed up by reload,
3143 so accept it for the most generic constraint. */
875862bf 3144 break;
7396c35d 3145
a7b49046 3146 default:
3147 return 0;
3148 }
3149 return 1;
3150}
875862bf 3151
875862bf 3152
a7b49046 3153/* Evaluates constraint strings described by the regular expression
7396c35d 3154 ([A|B|Z](Q|R|S|T))|Y and returns 1 if OP is a valid operand for
a7b49046 3155 the constraint given in STR, or 0 else. */
3156
3157int
3158s390_mem_constraint (const char *str, rtx op)
3159{
3160 char c = str[0];
3161
3162 switch (c)
3163 {
3164 case 'A':
3165 /* Check for offsettable variants of memory constraints. */
3166 if (!MEM_P (op) || MEM_VOLATILE_P (op))
875862bf 3167 return 0;
a7b49046 3168 if ((reload_completed || reload_in_progress)
3169 ? !offsettable_memref_p (op) : !offsettable_nonstrict_memref_p (op))
e68d6a13 3170 return 0;
a7b49046 3171 return s390_check_qrst_address (str[1], XEXP (op, 0), true);
3172 case 'B':
3173 /* Check for non-literal-pool variants of memory constraints. */
3174 if (!MEM_P (op))
875862bf 3175 return 0;
a7b49046 3176 return s390_check_qrst_address (str[1], XEXP (op, 0), false);
3177 case 'Q':
3178 case 'R':
3179 case 'S':
3180 case 'T':
3181 if (GET_CODE (op) != MEM)
3182 return 0;
3183 return s390_check_qrst_address (c, XEXP (op, 0), true);
875862bf 3184 case 'Y':
6d6be381 3185 /* Simply check for the basic form of a shift count. Reload will
3186 take care of making sure we have a proper base register. */
2be7449b 3187 if (!s390_decompose_addrstyle_without_index (op, NULL, NULL))
6d6be381 3188 return 0;
3189 break;
a7b49046 3190 case 'Z':
3191 return s390_check_qrst_address (str[1], op, true);
875862bf 3192 default:
3193 return 0;
3194 }
875862bf 3195 return 1;
3196}
3197
59bc01b3 3198
59bc01b3 3199/* Evaluates constraint strings starting with letter O. Input
3200 parameter C is the second letter following the "O" in the constraint
3201 string. Returns 1 if VALUE meets the respective constraint and 0
3202 otherwise. */
875862bf 3203
e863b008 3204int
59bc01b3 3205s390_O_constraint_str (const char c, HOST_WIDE_INT value)
e863b008 3206{
59bc01b3 3207 if (!TARGET_EXTIMM)
3208 return 0;
e863b008 3209
59bc01b3 3210 switch (c)
e863b008 3211 {
59bc01b3 3212 case 's':
3213 return trunc_int_for_mode (value, SImode) == value;
3214
3215 case 'p':
3216 return value == 0
3217 || s390_single_part (GEN_INT (value), DImode, SImode, 0) == 1;
3218
3219 case 'n':
29847ec4 3220 return s390_single_part (GEN_INT (value - 1), DImode, SImode, -1) == 1;
59bc01b3 3221
e863b008 3222 default:
59bc01b3 3223 gcc_unreachable ();
e863b008 3224 }
3225}
3226
59bc01b3 3227
3228/* Evaluates constraint strings starting with letter N. Parameter STR
3229 contains the letters following letter "N" in the constraint string.
3230 Returns true if VALUE matches the constraint. */
e863b008 3231
875862bf 3232int
59bc01b3 3233s390_N_constraint_str (const char *str, HOST_WIDE_INT value)
875862bf 3234{
3754d046 3235 machine_mode mode, part_mode;
875862bf 3236 int def;
3237 int part, part_goal;
3238
875862bf 3239
59bc01b3 3240 if (str[0] == 'x')
3241 part_goal = -1;
3242 else
3243 part_goal = str[0] - '0';
875862bf 3244
59bc01b3 3245 switch (str[1])
3246 {
3247 case 'Q':
3248 part_mode = QImode;
875862bf 3249 break;
59bc01b3 3250 case 'H':
3251 part_mode = HImode;
163277cf 3252 break;
59bc01b3 3253 case 'S':
3254 part_mode = SImode;
3255 break;
3256 default:
3257 return 0;
3258 }
163277cf 3259
59bc01b3 3260 switch (str[2])
3261 {
3262 case 'H':
3263 mode = HImode;
3264 break;
3265 case 'S':
3266 mode = SImode;
3267 break;
3268 case 'D':
3269 mode = DImode;
3270 break;
3271 default:
3272 return 0;
3273 }
53239c89 3274
59bc01b3 3275 switch (str[3])
3276 {
3277 case '0':
3278 def = 0;
3279 break;
3280 case 'F':
3281 def = -1;
3282 break;
875862bf 3283 default:
3284 return 0;
3285 }
3286
59bc01b3 3287 if (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (part_mode))
3288 return 0;
3289
3290 part = s390_single_part (GEN_INT (value), mode, part_mode, def);
3291 if (part < 0)
3292 return 0;
3293 if (part_goal != -1 && part_goal != part)
3294 return 0;
3295
875862bf 3296 return 1;
3297}
3298
59bc01b3 3299
3300/* Returns true if the input parameter VALUE is a float zero. */
3301
3302int
3303s390_float_const_zero_p (rtx value)
3304{
3305 return (GET_MODE_CLASS (GET_MODE (value)) == MODE_FLOAT
3306 && value == CONST0_RTX (GET_MODE (value)));
3307}
3308
fa7a995b 3309/* Implement TARGET_REGISTER_MOVE_COST. */
3310
3311static int
5fe5762e 3312s390_register_move_cost (machine_mode mode,
fa7a995b 3313 reg_class_t from, reg_class_t to)
3314{
5fe5762e 3315 /* On s390, copy between fprs and gprs is expensive. */
3316
3317 /* It becomes somewhat faster having ldgr/lgdr. */
3318 if (TARGET_Z10 && GET_MODE_SIZE (mode) == 8)
3319 {
3320 /* ldgr is single cycle. */
3321 if (reg_classes_intersect_p (from, GENERAL_REGS)
3322 && reg_classes_intersect_p (to, FP_REGS))
3323 return 1;
3324 /* lgdr needs 3 cycles. */
3325 if (reg_classes_intersect_p (to, GENERAL_REGS)
3326 && reg_classes_intersect_p (from, FP_REGS))
3327 return 3;
3328 }
3329
3330 /* Otherwise copying is done via memory. */
3331 if ((reg_classes_intersect_p (from, GENERAL_REGS)
3332 && reg_classes_intersect_p (to, FP_REGS))
3333 || (reg_classes_intersect_p (from, FP_REGS)
3334 && reg_classes_intersect_p (to, GENERAL_REGS)))
fa7a995b 3335 return 10;
3336
3337 return 1;
3338}
3339
3340/* Implement TARGET_MEMORY_MOVE_COST. */
3341
3342static int
3754d046 3343s390_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
fa7a995b 3344 reg_class_t rclass ATTRIBUTE_UNUSED,
3345 bool in ATTRIBUTE_UNUSED)
3346{
9a071c9f 3347 return 2;
fa7a995b 3348}
59bc01b3 3349
875862bf 3350/* Compute a (partial) cost for rtx X. Return true if the complete
3351 cost has been computed, and false if subexpressions should be
016d030e 3352 scanned. In either case, *TOTAL contains the cost result. The
3353 initial value of *TOTAL is the default value computed by
3354 rtx_cost. It may be left unmodified. OUTER_CODE contains the
3355 code of the superexpression of x. */
875862bf 3356
3357static bool
5ae4887d 3358s390_rtx_costs (rtx x, machine_mode mode, int outer_code,
3359 int opno ATTRIBUTE_UNUSED,
20d892d1 3360 int *total, bool speed ATTRIBUTE_UNUSED)
fab7adbf 3361{
5ae4887d 3362 int code = GET_CODE (x);
fab7adbf 3363 switch (code)
3364 {
3365 case CONST:
fab7adbf 3366 case CONST_INT:
fab7adbf 3367 case LABEL_REF:
3368 case SYMBOL_REF:
3369 case CONST_DOUBLE:
ba0e61d6 3370 case CONST_WIDE_INT:
3f074425 3371 case MEM:
fab7adbf 3372 *total = 0;
3373 return true;
3374
02a8efd2 3375 case IOR:
3376 /* risbg */
3377 if (GET_CODE (XEXP (x, 0)) == AND
3378 && GET_CODE (XEXP (x, 1)) == ASHIFT
3379 && REG_P (XEXP (XEXP (x, 0), 0))
3380 && REG_P (XEXP (XEXP (x, 1), 0))
3381 && CONST_INT_P (XEXP (XEXP (x, 0), 1))
3382 && CONST_INT_P (XEXP (XEXP (x, 1), 1))
3383 && (UINTVAL (XEXP (XEXP (x, 0), 1)) ==
b422d8c0 3384 (HOST_WIDE_INT_1U << UINTVAL (XEXP (XEXP (x, 1), 1))) - 1))
02a8efd2 3385 {
3386 *total = COSTS_N_INSNS (2);
3387 return true;
3388 }
0f57593c 3389
3390 /* ~AND on a 128 bit mode. This can be done using a vector
3391 instruction. */
3392 if (TARGET_VXE
3393 && GET_CODE (XEXP (x, 0)) == NOT
3394 && GET_CODE (XEXP (x, 1)) == NOT
3395 && REG_P (XEXP (XEXP (x, 0), 0))
3396 && REG_P (XEXP (XEXP (x, 1), 0))
3397 && GET_MODE_SIZE (GET_MODE (XEXP (XEXP (x, 0), 0))) == 16
3398 && s390_hard_regno_mode_ok (VR0_REGNUM,
3399 GET_MODE (XEXP (XEXP (x, 0), 0))))
3400 {
3401 *total = COSTS_N_INSNS (1);
3402 return true;
3403 }
0903985d 3404 /* fallthrough */
fab7adbf 3405 case ASHIFT:
3406 case ASHIFTRT:
3407 case LSHIFTRT:
18925d38 3408 case ROTATE:
3409 case ROTATERT:
fab7adbf 3410 case AND:
fab7adbf 3411 case XOR:
fab7adbf 3412 case NEG:
3413 case NOT:
3414 *total = COSTS_N_INSNS (1);
18925d38 3415 return false;
fab7adbf 3416
9cd3f3e6 3417 case PLUS:
3418 case MINUS:
9cd3f3e6 3419 *total = COSTS_N_INSNS (1);
3420 return false;
3421
ffead1ca 3422 case MULT:
5ae4887d 3423 switch (mode)
18925d38 3424 {
3425 case SImode:
9cd3f3e6 3426 {
18925d38 3427 rtx left = XEXP (x, 0);
3428 rtx right = XEXP (x, 1);
3429 if (GET_CODE (right) == CONST_INT
cb888f33 3430 && CONST_OK_FOR_K (INTVAL (right)))
18925d38 3431 *total = s390_cost->mhi;
3432 else if (GET_CODE (left) == SIGN_EXTEND)
3433 *total = s390_cost->mh;
3434 else
3435 *total = s390_cost->ms; /* msr, ms, msy */
3436 break;
3437 }
3438 case DImode:
3439 {
3440 rtx left = XEXP (x, 0);
3441 rtx right = XEXP (x, 1);
b5fdc416 3442 if (TARGET_ZARCH)
18925d38 3443 {
3444 if (GET_CODE (right) == CONST_INT
cb888f33 3445 && CONST_OK_FOR_K (INTVAL (right)))
18925d38 3446 *total = s390_cost->mghi;
3447 else if (GET_CODE (left) == SIGN_EXTEND)
3448 *total = s390_cost->msgf;
3449 else
3450 *total = s390_cost->msg; /* msgr, msg */
3451 }
3452 else /* TARGET_31BIT */
3453 {
3454 if (GET_CODE (left) == SIGN_EXTEND
3455 && GET_CODE (right) == SIGN_EXTEND)
3456 /* mulsidi case: mr, m */
3457 *total = s390_cost->m;
9cd3f3e6 3458 else if (GET_CODE (left) == ZERO_EXTEND
3459 && GET_CODE (right) == ZERO_EXTEND
3460 && TARGET_CPU_ZARCH)
3461 /* umulsidi case: ml, mlr */
3462 *total = s390_cost->ml;
18925d38 3463 else
3464 /* Complex calculation is required. */
3465 *total = COSTS_N_INSNS (40);
3466 }
3467 break;
3468 }
3469 case SFmode:
3470 case DFmode:
3471 *total = s390_cost->mult_df;
3472 break;
429f9fdb 3473 case TFmode:
3474 *total = s390_cost->mxbr;
3475 break;
18925d38 3476 default:
3477 return false;
3478 }
3479 return false;
fab7adbf 3480
81470015 3481 case FMA:
5ae4887d 3482 switch (mode)
81470015 3483 {
3484 case DFmode:
3485 *total = s390_cost->madbr;
3486 break;
3487 case SFmode:
3488 *total = s390_cost->maebr;
3489 break;
3490 default:
3491 return false;
3492 }
3493 /* Negate in the third argument is free: FMSUB. */
3494 if (GET_CODE (XEXP (x, 2)) == NEG)
3495 {
5ae4887d 3496 *total += (rtx_cost (XEXP (x, 0), mode, FMA, 0, speed)
3497 + rtx_cost (XEXP (x, 1), mode, FMA, 1, speed)
3498 + rtx_cost (XEXP (XEXP (x, 2), 0), mode, FMA, 2, speed));
81470015 3499 return true;
3500 }
3501 return false;
3502
3f074425 3503 case UDIV:
3504 case UMOD:
5ae4887d 3505 if (mode == TImode) /* 128 bit division */
3f074425 3506 *total = s390_cost->dlgr;
5ae4887d 3507 else if (mode == DImode)
3f074425 3508 {
3509 rtx right = XEXP (x, 1);
3510 if (GET_CODE (right) == ZERO_EXTEND) /* 64 by 32 bit division */
3511 *total = s390_cost->dlr;
3512 else /* 64 by 64 bit division */
3513 *total = s390_cost->dlgr;
3514 }
5ae4887d 3515 else if (mode == SImode) /* 32 bit division */
3f074425 3516 *total = s390_cost->dlr;
3517 return false;
3518
fab7adbf 3519 case DIV:
3f074425 3520 case MOD:
5ae4887d 3521 if (mode == DImode)
3f074425 3522 {
3523 rtx right = XEXP (x, 1);
3524 if (GET_CODE (right) == ZERO_EXTEND) /* 64 by 32 bit division */
b5fdc416 3525 if (TARGET_ZARCH)
3f074425 3526 *total = s390_cost->dsgfr;
3527 else
3528 *total = s390_cost->dr;
3529 else /* 64 by 64 bit division */
3530 *total = s390_cost->dsgr;
3531 }
5ae4887d 3532 else if (mode == SImode) /* 32 bit division */
3f074425 3533 *total = s390_cost->dlr;
5ae4887d 3534 else if (mode == SFmode)
260075cc 3535 {
095798e3 3536 *total = s390_cost->debr;
260075cc 3537 }
5ae4887d 3538 else if (mode == DFmode)
260075cc 3539 {
095798e3 3540 *total = s390_cost->ddbr;
260075cc 3541 }
5ae4887d 3542 else if (mode == TFmode)
429f9fdb 3543 {
095798e3 3544 *total = s390_cost->dxbr;
429f9fdb 3545 }
18925d38 3546 return false;
3547
9cd3f3e6 3548 case SQRT:
5ae4887d 3549 if (mode == SFmode)
9cd3f3e6 3550 *total = s390_cost->sqebr;
5ae4887d 3551 else if (mode == DFmode)
9cd3f3e6 3552 *total = s390_cost->sqdbr;
429f9fdb 3553 else /* TFmode */
3554 *total = s390_cost->sqxbr;
9cd3f3e6 3555 return false;
3556
18925d38 3557 case SIGN_EXTEND:
9cd3f3e6 3558 case ZERO_EXTEND:
3f074425 3559 if (outer_code == MULT || outer_code == DIV || outer_code == MOD
3560 || outer_code == PLUS || outer_code == MINUS
3561 || outer_code == COMPARE)
18925d38 3562 *total = 0;
3563 return false;
fab7adbf 3564
3f074425 3565 case COMPARE:
3566 *total = COSTS_N_INSNS (1);
3567 if (GET_CODE (XEXP (x, 0)) == AND
3568 && GET_CODE (XEXP (x, 1)) == CONST_INT
3569 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
3570 {
3571 rtx op0 = XEXP (XEXP (x, 0), 0);
3572 rtx op1 = XEXP (XEXP (x, 0), 1);
3573 rtx op2 = XEXP (x, 1);
3574
3575 if (memory_operand (op0, GET_MODE (op0))
3576 && s390_tm_ccmode (op1, op2, 0) != VOIDmode)
3577 return true;
3578 if (register_operand (op0, GET_MODE (op0))
3579 && s390_tm_ccmode (op1, op2, 1) != VOIDmode)
3580 return true;
3581 }
3582 return false;
3583
fab7adbf 3584 default:
3585 return false;
3586 }
3587}
3588
ee9c19ee 3589/* Return the cost of an address rtx ADDR. */
3590
ec0457a8 3591static int
3754d046 3592s390_address_cost (rtx addr, machine_mode mode ATTRIBUTE_UNUSED,
d9c5e5f4 3593 addr_space_t as ATTRIBUTE_UNUSED,
3594 bool speed ATTRIBUTE_UNUSED)
ee9c19ee 3595{
3596 struct s390_address ad;
3597 if (!s390_decompose_address (addr, &ad))
3598 return 1000;
3599
3600 return ad.indx? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
3601}
3602
292e369f 3603/* Implement targetm.vectorize.builtin_vectorization_cost. */
3604static int
3605s390_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3606 tree vectype,
3607 int misalign ATTRIBUTE_UNUSED)
3608{
3609 switch (type_of_cost)
3610 {
3611 case scalar_stmt:
3612 case scalar_load:
3613 case scalar_store:
3614 case vector_stmt:
3615 case vector_load:
3616 case vector_store:
3617 case vec_to_scalar:
3618 case scalar_to_vec:
3619 case cond_branch_not_taken:
3620 case vec_perm:
3621 case vec_promote_demote:
3622 case unaligned_load:
3623 case unaligned_store:
3624 return 1;
3625
3626 case cond_branch_taken:
3627 return 3;
3628
3629 case vec_construct:
3630 return TYPE_VECTOR_SUBPARTS (vectype) - 1;
3631
3632 default:
3633 gcc_unreachable ();
3634 }
3635}
3636
be00aaa8 3637/* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
3638 otherwise return 0. */
3639
3640int
edd89d66 3641tls_symbolic_operand (rtx op)
be00aaa8 3642{
be00aaa8 3643 if (GET_CODE (op) != SYMBOL_REF)
3644 return 0;
a3e33162 3645 return SYMBOL_REF_TLS_MODEL (op);
be00aaa8 3646}
4673c1a0 3647\f
923cf36d 3648/* Split DImode access register reference REG (on 64-bit) into its constituent
3649 low and high parts, and store them into LO and HI. Note that gen_lowpart/
3650 gen_highpart cannot be used as they assume all registers are word-sized,
3651 while our access registers have only half that size. */
3652
3653void
3654s390_split_access_reg (rtx reg, rtx *lo, rtx *hi)
3655{
3656 gcc_assert (TARGET_64BIT);
3657 gcc_assert (ACCESS_REG_P (reg));
3658 gcc_assert (GET_MODE (reg) == DImode);
3659 gcc_assert (!(REGNO (reg) & 1));
3660
3661 *lo = gen_rtx_REG (SImode, REGNO (reg) + 1);
3662 *hi = gen_rtx_REG (SImode, REGNO (reg));
3663}
4673c1a0 3664
56769981 3665/* Return true if OP contains a symbol reference */
4673c1a0 3666
e5537457 3667bool
b40da9a7 3668symbolic_reference_mentioned_p (rtx op)
4673c1a0 3669{
edd89d66 3670 const char *fmt;
3671 int i;
4673c1a0 3672
3673 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
3674 return 1;
3675
3676 fmt = GET_RTX_FORMAT (GET_CODE (op));
3677 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
3678 {
3679 if (fmt[i] == 'E')
3680 {
edd89d66 3681 int j;
4673c1a0 3682
3683 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
3684 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
3685 return 1;
3686 }
3687
3688 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
3689 return 1;
3690 }
3691
3692 return 0;
3693}
3694
be00aaa8 3695/* Return true if OP contains a reference to a thread-local symbol. */
3696
e5537457 3697bool
b40da9a7 3698tls_symbolic_reference_mentioned_p (rtx op)
be00aaa8 3699{
edd89d66 3700 const char *fmt;
3701 int i;
be00aaa8 3702
3703 if (GET_CODE (op) == SYMBOL_REF)
3704 return tls_symbolic_operand (op);
3705
3706 fmt = GET_RTX_FORMAT (GET_CODE (op));
3707 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
3708 {
3709 if (fmt[i] == 'E')
3710 {
edd89d66 3711 int j;
be00aaa8 3712
3713 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
3714 if (tls_symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
e5537457 3715 return true;
be00aaa8 3716 }
3717
3718 else if (fmt[i] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op, i)))
e5537457 3719 return true;
be00aaa8 3720 }
3721
e5537457 3722 return false;
be00aaa8 3723}
3724
4673c1a0 3725
f81e845f 3726/* Return true if OP is a legitimate general operand when
3727 generating PIC code. It is given that flag_pic is on
ba0e61d6 3728 and that OP satisfies CONSTANT_P. */
56769981 3729
4673c1a0 3730int
edd89d66 3731legitimate_pic_operand_p (rtx op)
4673c1a0 3732{
8b4a4127 3733 /* Accept all non-symbolic constants. */
4673c1a0 3734 if (!SYMBOLIC_CONST (op))
3735 return 1;
3736
f81e845f 3737 /* Reject everything else; must be handled
be00aaa8 3738 via emit_symbolic_move. */
4673c1a0 3739 return 0;
3740}
3741
56769981 3742/* Returns true if the constant value OP is a legitimate general operand.
ba0e61d6 3743 It is given that OP satisfies CONSTANT_P. */
56769981 3744
ca316360 3745static bool
3754d046 3746s390_legitimate_constant_p (machine_mode mode, rtx op)
4673c1a0 3747{
abf3beed 3748 if (TARGET_VX && VECTOR_MODE_P (mode) && GET_CODE (op) == CONST_VECTOR)
76a4c804 3749 {
3750 if (GET_MODE_SIZE (mode) != 16)
3751 return 0;
3752
80fc7f56 3753 if (!satisfies_constraint_j00 (op)
3754 && !satisfies_constraint_jm1 (op)
3755 && !satisfies_constraint_jKK (op)
3756 && !satisfies_constraint_jxx (op)
3757 && !satisfies_constraint_jyy (op))
76a4c804 3758 return 0;
3759 }
3760
8b4a4127 3761 /* Accept all non-symbolic constants. */
4673c1a0 3762 if (!SYMBOLIC_CONST (op))
3763 return 1;
3764
be00aaa8 3765 /* Accept immediate LARL operands. */
ca316360 3766 if (TARGET_CPU_ZARCH && larl_operand (op, mode))
be00aaa8 3767 return 1;
3768
3769 /* Thread-local symbols are never legal constants. This is
3770 so that emit_call knows that computing such addresses
3771 might require a function call. */
3772 if (TLS_SYMBOLIC_CONST (op))
3773 return 0;
3774
4673c1a0 3775 /* In the PIC case, symbolic constants must *not* be
3776 forced into the literal pool. We accept them here,
be00aaa8 3777 so that they will be handled by emit_symbolic_move. */
4673c1a0 3778 if (flag_pic)
3779 return 1;
3780
4673c1a0 3781 /* All remaining non-PIC symbolic constants are
3782 forced into the literal pool. */
3783 return 0;
3784}
3785
be00aaa8 3786/* Determine if it's legal to put X into the constant pool. This
3787 is not possible if X contains the address of a symbol that is
3788 not constant (TLS) or not known at final link time (PIC). */
3789
3790static bool
3754d046 3791s390_cannot_force_const_mem (machine_mode mode, rtx x)
be00aaa8 3792{
3793 switch (GET_CODE (x))
3794 {
3795 case CONST_INT:
3796 case CONST_DOUBLE:
ba0e61d6 3797 case CONST_WIDE_INT:
76a4c804 3798 case CONST_VECTOR:
be00aaa8 3799 /* Accept all non-symbolic constants. */
3800 return false;
3801
3802 case LABEL_REF:
3803 /* Labels are OK iff we are non-PIC. */
3804 return flag_pic != 0;
3805
3806 case SYMBOL_REF:
3807 /* 'Naked' TLS symbol references are never OK,
3808 non-TLS symbols are OK iff we are non-PIC. */
3809 if (tls_symbolic_operand (x))
3810 return true;
3811 else
3812 return flag_pic != 0;
3813
3814 case CONST:
7d7d7bd2 3815 return s390_cannot_force_const_mem (mode, XEXP (x, 0));
be00aaa8 3816 case PLUS:
3817 case MINUS:
7d7d7bd2 3818 return s390_cannot_force_const_mem (mode, XEXP (x, 0))
3819 || s390_cannot_force_const_mem (mode, XEXP (x, 1));
be00aaa8 3820
3821 case UNSPEC:
3822 switch (XINT (x, 1))
3823 {
3824 /* Only lt-relative or GOT-relative UNSPECs are OK. */
12ef3745 3825 case UNSPEC_LTREL_OFFSET:
3826 case UNSPEC_GOT:
3827 case UNSPEC_GOTOFF:
3828 case UNSPEC_PLTOFF:
be00aaa8 3829 case UNSPEC_TLSGD:
3830 case UNSPEC_TLSLDM:
3831 case UNSPEC_NTPOFF:
3832 case UNSPEC_DTPOFF:
3833 case UNSPEC_GOTNTPOFF:
3834 case UNSPEC_INDNTPOFF:
3835 return false;
3836
d345b493 3837 /* If the literal pool shares the code section, be put
3838 execute template placeholders into the pool as well. */
3839 case UNSPEC_INSN:
3840 return TARGET_CPU_ZARCH;
3841
be00aaa8 3842 default:
3843 return true;
3844 }
3845 break;
3846
3847 default:
32eda510 3848 gcc_unreachable ();
be00aaa8 3849 }
3850}
3851
8b4a4127 3852/* Returns true if the constant value OP is a legitimate general
f81e845f 3853 operand during and after reload. The difference to
8b4a4127 3854 legitimate_constant_p is that this function will not accept
3855 a constant that would need to be forced to the literal pool
33d033da 3856 before it can be used as operand.
3857 This function accepts all constants which can be loaded directly
3858 into a GPR. */
8b4a4127 3859
e5537457 3860bool
edd89d66 3861legitimate_reload_constant_p (rtx op)
8b4a4127 3862{
51aa1e9c 3863 /* Accept la(y) operands. */
f81e845f 3864 if (GET_CODE (op) == CONST_INT
51aa1e9c 3865 && DISP_IN_RANGE (INTVAL (op)))
e5537457 3866 return true;
51aa1e9c 3867
163277cf 3868 /* Accept l(g)hi/l(g)fi operands. */
8b4a4127 3869 if (GET_CODE (op) == CONST_INT
163277cf 3870 && (CONST_OK_FOR_K (INTVAL (op)) || CONST_OK_FOR_Os (INTVAL (op))))
e5537457 3871 return true;
8b4a4127 3872
3873 /* Accept lliXX operands. */
dafc8d45 3874 if (TARGET_ZARCH
53239c89 3875 && GET_CODE (op) == CONST_INT
3876 && trunc_int_for_mode (INTVAL (op), word_mode) == INTVAL (op)
3877 && s390_single_part (op, word_mode, HImode, 0) >= 0)
e5537457 3878 return true;
8b4a4127 3879
163277cf 3880 if (TARGET_EXTIMM
3881 && GET_CODE (op) == CONST_INT
3882 && trunc_int_for_mode (INTVAL (op), word_mode) == INTVAL (op)
3883 && s390_single_part (op, word_mode, SImode, 0) >= 0)
3884 return true;
3885
8b4a4127 3886 /* Accept larl operands. */
dafc8d45 3887 if (TARGET_CPU_ZARCH
8b4a4127 3888 && larl_operand (op, VOIDmode))
e5537457 3889 return true;
8b4a4127 3890
70037005 3891 /* Accept floating-point zero operands that fit into a single GPR. */
3892 if (GET_CODE (op) == CONST_DOUBLE
3893 && s390_float_const_zero_p (op)
3894 && GET_MODE_SIZE (GET_MODE (op)) <= UNITS_PER_WORD)
3895 return true;
3896
53239c89 3897 /* Accept double-word operands that can be split. */
ba0e61d6 3898 if (GET_CODE (op) == CONST_WIDE_INT
3899 || (GET_CODE (op) == CONST_INT
3900 && trunc_int_for_mode (INTVAL (op), word_mode) != INTVAL (op)))
53239c89 3901 {
3754d046 3902 machine_mode dword_mode = word_mode == SImode ? DImode : TImode;
53239c89 3903 rtx hi = operand_subword (op, 0, 0, dword_mode);
3904 rtx lo = operand_subword (op, 1, 0, dword_mode);
3905 return legitimate_reload_constant_p (hi)
3906 && legitimate_reload_constant_p (lo);
3907 }
3908
8b4a4127 3909 /* Everything else cannot be handled without reload. */
e5537457 3910 return false;
8b4a4127 3911}
3912
33d033da 3913/* Returns true if the constant value OP is a legitimate fp operand
3914 during and after reload.
3915 This function accepts all constants which can be loaded directly
3916 into an FPR. */
3917
3918static bool
3919legitimate_reload_fp_constant_p (rtx op)
3920{
3921 /* Accept floating-point zero operands if the load zero instruction
81769881 3922 can be used. Prior to z196 the load fp zero instruction caused a
3923 performance penalty if the result is used as BFP number. */
33d033da 3924 if (TARGET_Z196
3925 && GET_CODE (op) == CONST_DOUBLE
3926 && s390_float_const_zero_p (op))
3927 return true;
3928
3929 return false;
3930}
3931
76a4c804 3932/* Returns true if the constant value OP is a legitimate vector operand
3933 during and after reload.
3934 This function accepts all constants which can be loaded directly
3935 into an VR. */
3936
3937static bool
3938legitimate_reload_vector_constant_p (rtx op)
3939{
76a4c804 3940 if (TARGET_VX && GET_MODE_SIZE (GET_MODE (op)) == 16
80fc7f56 3941 && (satisfies_constraint_j00 (op)
3942 || satisfies_constraint_jm1 (op)
3943 || satisfies_constraint_jKK (op)
3944 || satisfies_constraint_jxx (op)
3945 || satisfies_constraint_jyy (op)))
76a4c804 3946 return true;
3947
3948 return false;
3949}
3950
8deb3959 3951/* Given an rtx OP being reloaded into a reg required to be in class RCLASS,
8b4a4127 3952 return the class of reg to actually use. */
3953
3359ccfd 3954static reg_class_t
3955s390_preferred_reload_class (rtx op, reg_class_t rclass)
8b4a4127 3956{
8b4a4127 3957 switch (GET_CODE (op))
3958 {
70037005 3959 /* Constants we cannot reload into general registers
3960 must be forced into the literal pool. */
76a4c804 3961 case CONST_VECTOR:
8b4a4127 3962 case CONST_DOUBLE:
3963 case CONST_INT:
ba0e61d6 3964 case CONST_WIDE_INT:
70037005 3965 if (reg_class_subset_p (GENERAL_REGS, rclass)
3966 && legitimate_reload_constant_p (op))
3967 return GENERAL_REGS;
3968 else if (reg_class_subset_p (ADDR_REGS, rclass)
3969 && legitimate_reload_constant_p (op))
3970 return ADDR_REGS;
33d033da 3971 else if (reg_class_subset_p (FP_REGS, rclass)
3972 && legitimate_reload_fp_constant_p (op))
3973 return FP_REGS;
76a4c804 3974 else if (reg_class_subset_p (VEC_REGS, rclass)
3975 && legitimate_reload_vector_constant_p (op))
3976 return VEC_REGS;
3977
33d033da 3978 return NO_REGS;
8b4a4127 3979
3980 /* If a symbolic constant or a PLUS is reloaded,
0b300c86 3981 it is most likely being used as an address, so
3982 prefer ADDR_REGS. If 'class' is not a superset
3983 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
de47476b 3984 case CONST:
37c55f71 3985 /* Symrefs cannot be pushed into the literal pool with -fPIC
3986 so we *MUST NOT* return NO_REGS for these cases
3987 (s390_cannot_force_const_mem will return true).
3988
3989 On the other hand we MUST return NO_REGS for symrefs with
3990 invalid addend which might have been pushed to the literal
3991 pool (no -fPIC). Usually we would expect them to be
3992 handled via secondary reload but this does not happen if
3993 they are used as literal pool slot replacement in reload
3994 inheritance (see emit_input_reload_insns). */
de47476b 3995 if (TARGET_CPU_ZARCH
3996 && GET_CODE (XEXP (op, 0)) == PLUS
3997 && GET_CODE (XEXP (XEXP(op, 0), 0)) == SYMBOL_REF
3998 && GET_CODE (XEXP (XEXP(op, 0), 1)) == CONST_INT)
3999 {
37c55f71 4000 if (flag_pic && reg_class_subset_p (ADDR_REGS, rclass))
de47476b 4001 return ADDR_REGS;
4002 else
4003 return NO_REGS;
4004 }
4005 /* fallthrough */
8b4a4127 4006 case LABEL_REF:
4007 case SYMBOL_REF:
08d88e72 4008 if (!legitimate_reload_constant_p (op))
4009 return NO_REGS;
4010 /* fallthrough */
4011 case PLUS:
4012 /* load address will be used. */
8deb3959 4013 if (reg_class_subset_p (ADDR_REGS, rclass))
08d88e72 4014 return ADDR_REGS;
0b300c86 4015 else
4016 return NO_REGS;
8b4a4127 4017
4018 default:
4019 break;
4020 }
4021
8deb3959 4022 return rclass;
8b4a4127 4023}
4673c1a0 4024
e68d6a13 4025/* Return true if ADDR is SYMBOL_REF + addend with addend being a
4026 multiple of ALIGNMENT and the SYMBOL_REF being naturally
4027 aligned. */
4028
4029bool
4030s390_check_symref_alignment (rtx addr, HOST_WIDE_INT alignment)
4031{
4032 HOST_WIDE_INT addend;
4033 rtx symref;
4034
78affa36 4035 /* The "required alignment" might be 0 (e.g. for certain structs
4036 accessed via BLKmode). Early abort in this case, as well as when
4037 an alignment > 8 is required. */
4038 if (alignment < 2 || alignment > 8)
4039 return false;
4040
2a672556 4041 if (!s390_loadrelative_operand_p (addr, &symref, &addend))
4042 return false;
62cb5855 4043
2a672556 4044 if (addend & (alignment - 1))
e68d6a13 4045 return false;
4046
78affa36 4047 if (GET_CODE (symref) == SYMBOL_REF)
4048 {
4049 /* We have load-relative instructions for 2-byte, 4-byte, and
4050 8-byte alignment so allow only these. */
4051 switch (alignment)
4052 {
4053 case 8: return !SYMBOL_FLAG_NOTALIGN8_P (symref);
4054 case 4: return !SYMBOL_FLAG_NOTALIGN4_P (symref);
4055 case 2: return !SYMBOL_FLAG_NOTALIGN2_P (symref);
4056 default: return false;
4057 }
4058 }
2a672556 4059
4060 if (GET_CODE (symref) == UNSPEC
4061 && alignment <= UNITS_PER_LONG)
4062 return true;
4063
4064 return false;
e68d6a13 4065}
4066
4067/* ADDR is moved into REG using larl. If ADDR isn't a valid larl
4068 operand SCRATCH is used to reload the even part of the address and
4069 adding one. */
4070
4071void
4072s390_reload_larl_operand (rtx reg, rtx addr, rtx scratch)
4073{
4074 HOST_WIDE_INT addend;
4075 rtx symref;
4076
2a672556 4077 if (!s390_loadrelative_operand_p (addr, &symref, &addend))
e68d6a13 4078 gcc_unreachable ();
4079
4080 if (!(addend & 1))
4081 /* Easy case. The addend is even so larl will do fine. */
4082 emit_move_insn (reg, addr);
4083 else
4084 {
4085 /* We can leave the scratch register untouched if the target
4086 register is a valid base register. */
4087 if (REGNO (reg) < FIRST_PSEUDO_REGISTER
4088 && REGNO_REG_CLASS (REGNO (reg)) == ADDR_REGS)
4089 scratch = reg;
4090
4091 gcc_assert (REGNO (scratch) < FIRST_PSEUDO_REGISTER);
4092 gcc_assert (REGNO_REG_CLASS (REGNO (scratch)) == ADDR_REGS);
4093
4094 if (addend != 1)
4095 emit_move_insn (scratch,
4096 gen_rtx_CONST (Pmode,
4097 gen_rtx_PLUS (Pmode, symref,
4098 GEN_INT (addend - 1))));
4099 else
4100 emit_move_insn (scratch, symref);
4101
4102 /* Increment the address using la in order to avoid clobbering cc. */
de47476b 4103 s390_load_address (reg, gen_rtx_PLUS (Pmode, scratch, const1_rtx));
e68d6a13 4104 }
4105}
4106
4107/* Generate what is necessary to move between REG and MEM using
4108 SCRATCH. The direction is given by TOMEM. */
4109
4110void
4111s390_reload_symref_address (rtx reg, rtx mem, rtx scratch, bool tomem)
4112{
4113 /* Reload might have pulled a constant out of the literal pool.
4114 Force it back in. */
4115 if (CONST_INT_P (mem) || GET_CODE (mem) == CONST_DOUBLE
ba0e61d6 4116 || GET_CODE (mem) == CONST_WIDE_INT
76a4c804 4117 || GET_CODE (mem) == CONST_VECTOR
e68d6a13 4118 || GET_CODE (mem) == CONST)
4119 mem = force_const_mem (GET_MODE (reg), mem);
4120
4121 gcc_assert (MEM_P (mem));
4122
4123 /* For a load from memory we can leave the scratch register
4124 untouched if the target register is a valid base register. */
4125 if (!tomem
4126 && REGNO (reg) < FIRST_PSEUDO_REGISTER
4127 && REGNO_REG_CLASS (REGNO (reg)) == ADDR_REGS
4128 && GET_MODE (reg) == GET_MODE (scratch))
4129 scratch = reg;
4130
4131 /* Load address into scratch register. Since we can't have a
4132 secondary reload for a secondary reload we have to cover the case
4133 where larl would need a secondary reload here as well. */
4134 s390_reload_larl_operand (scratch, XEXP (mem, 0), scratch);
4135
4136 /* Now we can use a standard load/store to do the move. */
4137 if (tomem)
4138 emit_move_insn (replace_equiv_address (mem, scratch), reg);
4139 else
4140 emit_move_insn (reg, replace_equiv_address (mem, scratch));
4141}
4142
328d5423 4143/* Inform reload about cases where moving X with a mode MODE to a register in
8deb3959 4144 RCLASS requires an extra scratch or immediate register. Return the class
328d5423 4145 needed for the immediate register. */
429f9fdb 4146
964229b7 4147static reg_class_t
4148s390_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i,
3754d046 4149 machine_mode mode, secondary_reload_info *sri)
328d5423 4150{
964229b7 4151 enum reg_class rclass = (enum reg_class) rclass_i;
4152
328d5423 4153 /* Intermediate register needed. */
8deb3959 4154 if (reg_classes_intersect_p (CC_REGS, rclass))
bcbf02a5 4155 return GENERAL_REGS;
4156
76a4c804 4157 if (TARGET_VX)
4158 {
4159 /* The vst/vl vector move instructions allow only for short
4160 displacements. */
4161 if (MEM_P (x)
4162 && GET_CODE (XEXP (x, 0)) == PLUS
4163 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
4164 && !SHORT_DISP_IN_RANGE(INTVAL (XEXP (XEXP (x, 0), 1)))
4165 && reg_class_subset_p (rclass, VEC_REGS)
4166 && (!reg_class_subset_p (rclass, FP_REGS)
4167 || (GET_MODE_SIZE (mode) > 8
4168 && s390_class_max_nregs (FP_REGS, mode) == 1)))
4169 {
4170 if (in_p)
4171 sri->icode = (TARGET_64BIT ?
4172 CODE_FOR_reloaddi_la_in :
4173 CODE_FOR_reloadsi_la_in);
4174 else
4175 sri->icode = (TARGET_64BIT ?
4176 CODE_FOR_reloaddi_la_out :
4177 CODE_FOR_reloadsi_la_out);
4178 }
4179 }
4180
e68d6a13 4181 if (TARGET_Z10)
4182 {
08d88e72 4183 HOST_WIDE_INT offset;
4184 rtx symref;
4185
e68d6a13 4186 /* On z10 several optimizer steps may generate larl operands with
4187 an odd addend. */
4188 if (in_p
2a672556 4189 && s390_loadrelative_operand_p (x, &symref, &offset)
e68d6a13 4190 && mode == Pmode
78affa36 4191 && !SYMBOL_FLAG_NOTALIGN2_P (symref)
08d88e72 4192 && (offset & 1) == 1)
e68d6a13 4193 sri->icode = ((mode == DImode) ? CODE_FOR_reloaddi_larl_odd_addend_z10
4194 : CODE_FOR_reloadsi_larl_odd_addend_z10);
4195
ddb92daa 4196 /* Handle all the (mem (symref)) accesses we cannot use the z10
4197 instructions for. */
e68d6a13 4198 if (MEM_P (x)
2a672556 4199 && s390_loadrelative_operand_p (XEXP (x, 0), NULL, NULL)
ddb92daa 4200 && (mode == QImode
a1142483 4201 || !reg_class_subset_p (rclass, GENERAL_REGS)
ddb92daa 4202 || GET_MODE_SIZE (mode) > UNITS_PER_WORD
4203 || !s390_check_symref_alignment (XEXP (x, 0),
4204 GET_MODE_SIZE (mode))))
e68d6a13 4205 {
4206#define __SECONDARY_RELOAD_CASE(M,m) \
4207 case M##mode: \
4208 if (TARGET_64BIT) \
4209 sri->icode = in_p ? CODE_FOR_reload##m##di_toreg_z10 : \
4210 CODE_FOR_reload##m##di_tomem_z10; \
4211 else \
4212 sri->icode = in_p ? CODE_FOR_reload##m##si_toreg_z10 : \
4213 CODE_FOR_reload##m##si_tomem_z10; \
4214 break;
4215
4216 switch (GET_MODE (x))
4217 {
4218 __SECONDARY_RELOAD_CASE (QI, qi);
4219 __SECONDARY_RELOAD_CASE (HI, hi);
4220 __SECONDARY_RELOAD_CASE (SI, si);
4221 __SECONDARY_RELOAD_CASE (DI, di);
4222 __SECONDARY_RELOAD_CASE (TI, ti);
4223 __SECONDARY_RELOAD_CASE (SF, sf);
4224 __SECONDARY_RELOAD_CASE (DF, df);
4225 __SECONDARY_RELOAD_CASE (TF, tf);
4226 __SECONDARY_RELOAD_CASE (SD, sd);
4227 __SECONDARY_RELOAD_CASE (DD, dd);
4228 __SECONDARY_RELOAD_CASE (TD, td);
76a4c804 4229 __SECONDARY_RELOAD_CASE (V1QI, v1qi);
4230 __SECONDARY_RELOAD_CASE (V2QI, v2qi);
4231 __SECONDARY_RELOAD_CASE (V4QI, v4qi);
4232 __SECONDARY_RELOAD_CASE (V8QI, v8qi);
4233 __SECONDARY_RELOAD_CASE (V16QI, v16qi);
4234 __SECONDARY_RELOAD_CASE (V1HI, v1hi);
4235 __SECONDARY_RELOAD_CASE (V2HI, v2hi);
4236 __SECONDARY_RELOAD_CASE (V4HI, v4hi);
4237 __SECONDARY_RELOAD_CASE (V8HI, v8hi);
4238 __SECONDARY_RELOAD_CASE (V1SI, v1si);
4239 __SECONDARY_RELOAD_CASE (V2SI, v2si);
4240 __SECONDARY_RELOAD_CASE (V4SI, v4si);
4241 __SECONDARY_RELOAD_CASE (V1DI, v1di);
4242 __SECONDARY_RELOAD_CASE (V2DI, v2di);
4243 __SECONDARY_RELOAD_CASE (V1TI, v1ti);
4244 __SECONDARY_RELOAD_CASE (V1SF, v1sf);
4245 __SECONDARY_RELOAD_CASE (V2SF, v2sf);
4246 __SECONDARY_RELOAD_CASE (V4SF, v4sf);
4247 __SECONDARY_RELOAD_CASE (V1DF, v1df);
4248 __SECONDARY_RELOAD_CASE (V2DF, v2df);
4249 __SECONDARY_RELOAD_CASE (V1TF, v1tf);
e68d6a13 4250 default:
4251 gcc_unreachable ();
4252 }
4253#undef __SECONDARY_RELOAD_CASE
4254 }
4255 }
4256
328d5423 4257 /* We need a scratch register when loading a PLUS expression which
4258 is not a legitimate operand of the LOAD ADDRESS instruction. */
7b1bda1c 4259 /* LRA can deal with transformation of plus op very well -- so we
4260 don't need to prompt LRA in this case. */
4261 if (! lra_in_progress && in_p && s390_plus_operand (x, mode))
328d5423 4262 sri->icode = (TARGET_64BIT ?
4263 CODE_FOR_reloaddi_plus : CODE_FOR_reloadsi_plus);
4264
efec32e0 4265 /* Performing a multiword move from or to memory we have to make sure the
328d5423 4266 second chunk in memory is addressable without causing a displacement
4267 overflow. If that would be the case we calculate the address in
4268 a scratch register. */
4269 if (MEM_P (x)
4270 && GET_CODE (XEXP (x, 0)) == PLUS
4271 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
4272 && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (x, 0), 1))
6938bdf8 4273 + GET_MODE_SIZE (mode) - 1))
328d5423 4274 {
efec32e0 4275 /* For GENERAL_REGS a displacement overflow is no problem if occurring
328d5423 4276 in a s_operand address since we may fallback to lm/stm. So we only
4277 have to care about overflows in the b+i+d case. */
8deb3959 4278 if ((reg_classes_intersect_p (GENERAL_REGS, rclass)
328d5423 4279 && s390_class_max_nregs (GENERAL_REGS, mode) > 1
4280 && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS)
4281 /* For FP_REGS no lm/stm is available so this check is triggered
4282 for displacement overflows in b+i+d and b+d like addresses. */
8deb3959 4283 || (reg_classes_intersect_p (FP_REGS, rclass)
328d5423 4284 && s390_class_max_nregs (FP_REGS, mode) > 1))
4285 {
4286 if (in_p)
4287 sri->icode = (TARGET_64BIT ?
76a4c804 4288 CODE_FOR_reloaddi_la_in :
4289 CODE_FOR_reloadsi_la_in);
328d5423 4290 else
4291 sri->icode = (TARGET_64BIT ?
76a4c804 4292 CODE_FOR_reloaddi_la_out :
4293 CODE_FOR_reloadsi_la_out);
328d5423 4294 }
4295 }
bcbf02a5 4296
08b5e262 4297 /* A scratch address register is needed when a symbolic constant is
4298 copied to r0 compiling with -fPIC. In other cases the target
4299 register might be used as temporary (see legitimize_pic_address). */
8deb3959 4300 if (in_p && SYMBOLIC_CONST (x) && flag_pic == 2 && rclass != ADDR_REGS)
08b5e262 4301 sri->icode = (TARGET_64BIT ?
4302 CODE_FOR_reloaddi_PIC_addr :
4303 CODE_FOR_reloadsi_PIC_addr);
4304
328d5423 4305 /* Either scratch or no register needed. */
66795431 4306 return NO_REGS;
4307}
4308
64f977d6 4309/* Generate code to load SRC, which is PLUS that is not a
4310 legitimate operand for the LA instruction, into TARGET.
4311 SCRATCH may be used as scratch register. */
4312
4313void
edd89d66 4314s390_expand_plus_operand (rtx target, rtx src,
4315 rtx scratch)
64f977d6 4316{
e7f0624a 4317 rtx sum1, sum2;
8ba34dcd 4318 struct s390_address ad;
dc4951d9 4319
dc4951d9 4320 /* src must be a PLUS; get its two operands. */
32eda510 4321 gcc_assert (GET_CODE (src) == PLUS);
4322 gcc_assert (GET_MODE (src) == Pmode);
64f977d6 4323
c10847b9 4324 /* Check if any of the two operands is already scheduled
4325 for replacement by reload. This can happen e.g. when
4326 float registers occur in an address. */
4327 sum1 = find_replacement (&XEXP (src, 0));
4328 sum2 = find_replacement (&XEXP (src, 1));
a5004c3d 4329 src = gen_rtx_PLUS (Pmode, sum1, sum2);
a5004c3d 4330
e7f0624a 4331 /* If the address is already strictly valid, there's nothing to do. */
4332 if (!s390_decompose_address (src, &ad)
1e280623 4333 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
4334 || (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx))))
64f977d6 4335 {
e7f0624a 4336 /* Otherwise, one of the operands cannot be an address register;
4337 we reload its value into the scratch register. */
4338 if (true_regnum (sum1) < 1 || true_regnum (sum1) > 15)
4339 {
4340 emit_move_insn (scratch, sum1);
4341 sum1 = scratch;
4342 }
4343 if (true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
4344 {
4345 emit_move_insn (scratch, sum2);
4346 sum2 = scratch;
4347 }
64f977d6 4348
e7f0624a 4349 /* According to the way these invalid addresses are generated
4350 in reload.c, it should never happen (at least on s390) that
4351 *neither* of the PLUS components, after find_replacements
4352 was applied, is an address register. */
4353 if (sum1 == scratch && sum2 == scratch)
4354 {
4355 debug_rtx (src);
32eda510 4356 gcc_unreachable ();
e7f0624a 4357 }
64f977d6 4358
e7f0624a 4359 src = gen_rtx_PLUS (Pmode, sum1, sum2);
64f977d6 4360 }
4361
4362 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
4363 is only ever performed on addresses, so we can mark the
4364 sum as legitimate for LA in any case. */
4fbc4db5 4365 s390_load_address (target, src);
64f977d6 4366}
4367
4368
e5537457 4369/* Return true if ADDR is a valid memory address.
875862bf 4370 STRICT specifies whether strict register checking applies. */
4673c1a0 4371
fd50b071 4372static bool
3754d046 4373s390_legitimate_address_p (machine_mode mode, rtx addr, bool strict)
4673c1a0 4374{
875862bf 4375 struct s390_address ad;
e68d6a13 4376
4377 if (TARGET_Z10
4378 && larl_operand (addr, VOIDmode)
4379 && (mode == VOIDmode
4380 || s390_check_symref_alignment (addr, GET_MODE_SIZE (mode))))
4381 return true;
4382
875862bf 4383 if (!s390_decompose_address (addr, &ad))
e5537457 4384 return false;
8ba34dcd 4385
4386 if (strict)
4387 {
1e280623 4388 if (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
e5537457 4389 return false;
1e280623 4390
4391 if (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx)))
e5537457 4392 return false;
8ba34dcd 4393 }
4394 else
4395 {
ffead1ca 4396 if (ad.base
1e280623 4397 && !(REGNO (ad.base) >= FIRST_PSEUDO_REGISTER
4398 || REGNO_REG_CLASS (REGNO (ad.base)) == ADDR_REGS))
e5537457 4399 return false;
ffead1ca 4400
1e280623 4401 if (ad.indx
4402 && !(REGNO (ad.indx) >= FIRST_PSEUDO_REGISTER
4403 || REGNO_REG_CLASS (REGNO (ad.indx)) == ADDR_REGS))
4404 return false;
8ba34dcd 4405 }
e5537457 4406 return true;
4673c1a0 4407}
4408
e5537457 4409/* Return true if OP is a valid operand for the LA instruction.
2eb8fe23 4410 In 31-bit, we need to prove that the result is used as an
4411 address, as LA performs only a 31-bit addition. */
4412
e5537457 4413bool
edd89d66 4414legitimate_la_operand_p (rtx op)
2eb8fe23 4415{
4416 struct s390_address addr;
8ba34dcd 4417 if (!s390_decompose_address (op, &addr))
e5537457 4418 return false;
2eb8fe23 4419
e5537457 4420 return (TARGET_64BIT || addr.pointer);
64f977d6 4421}
2eb8fe23 4422
e5537457 4423/* Return true if it is valid *and* preferable to use LA to
c6061690 4424 compute the sum of OP1 and OP2. */
f81e845f 4425
e5537457 4426bool
c6061690 4427preferred_la_operand_p (rtx op1, rtx op2)
a40b2054 4428{
4429 struct s390_address addr;
c6061690 4430
4431 if (op2 != const0_rtx)
4432 op1 = gen_rtx_PLUS (Pmode, op1, op2);
4433
4434 if (!s390_decompose_address (op1, &addr))
e5537457 4435 return false;
1e280623 4436 if (addr.base && !REGNO_OK_FOR_BASE_P (REGNO (addr.base)))
e5537457 4437 return false;
1e280623 4438 if (addr.indx && !REGNO_OK_FOR_INDEX_P (REGNO (addr.indx)))
e5537457 4439 return false;
a40b2054 4440
33d033da 4441 /* Avoid LA instructions with index register on z196; it is
81769881 4442 preferable to use regular add instructions when possible.
4443 Starting with zEC12 the la with index register is "uncracked"
4444 again. */
33d033da 4445 if (addr.indx && s390_tune == PROCESSOR_2817_Z196)
4446 return false;
4447
a40b2054 4448 if (!TARGET_64BIT && !addr.pointer)
e5537457 4449 return false;
a40b2054 4450
4451 if (addr.pointer)
e5537457 4452 return true;
a40b2054 4453
ec3b9583 4454 if ((addr.base && REG_P (addr.base) && REG_POINTER (addr.base))
4455 || (addr.indx && REG_P (addr.indx) && REG_POINTER (addr.indx)))
e5537457 4456 return true;
a40b2054 4457
e5537457 4458 return false;
a40b2054 4459}
4460
4fbc4db5 4461/* Emit a forced load-address operation to load SRC into DST.
4462 This will use the LOAD ADDRESS instruction even in situations
4463 where legitimate_la_operand_p (SRC) returns false. */
2eb8fe23 4464
4fbc4db5 4465void
b40da9a7 4466s390_load_address (rtx dst, rtx src)
64f977d6 4467{
4fbc4db5 4468 if (TARGET_64BIT)
4469 emit_move_insn (dst, src);
4470 else
4471 emit_insn (gen_force_la_31 (dst, src));
2eb8fe23 4472}
4473
4673c1a0 4474/* Return a legitimate reference for ORIG (an address) using the
4475 register REG. If REG is 0, a new pseudo is generated.
4476
4477 There are two types of references that must be handled:
4478
4479 1. Global data references must load the address from the GOT, via
4480 the PIC reg. An insn is emitted to do this load, and the reg is
4481 returned.
4482
4483 2. Static data references, constant pool addresses, and code labels
4484 compute the address as an offset from the GOT, whose base is in
a3e33162 4485 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
4673c1a0 4486 differentiate them from global data objects. The returned
4487 address is the PIC reg + an unspec constant.
4488
bc409cb4 4489 TARGET_LEGITIMIZE_ADDRESS_P rejects symbolic references unless the PIC
4673c1a0 4490 reg also appears in the address. */
4491
4492rtx
b40da9a7 4493legitimize_pic_address (rtx orig, rtx reg)
4673c1a0 4494{
4495 rtx addr = orig;
2a672556 4496 rtx addend = const0_rtx;
8deb3959 4497 rtx new_rtx = orig;
4673c1a0 4498
1ed004b7 4499 gcc_assert (!TLS_SYMBOLIC_CONST (addr));
4500
2a672556 4501 if (GET_CODE (addr) == CONST)
4502 addr = XEXP (addr, 0);
4503
4504 if (GET_CODE (addr) == PLUS)
4673c1a0 4505 {
2a672556 4506 addend = XEXP (addr, 1);
4507 addr = XEXP (addr, 0);
4508 }
4509
4510 if ((GET_CODE (addr) == LABEL_REF
4511 || (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (addr))
4512 || (GET_CODE (addr) == UNSPEC &&
4513 (XINT (addr, 1) == UNSPEC_GOTENT
4514 || (TARGET_CPU_ZARCH && XINT (addr, 1) == UNSPEC_PLT))))
4515 && GET_CODE (addend) == CONST_INT)
4516 {
4517 /* This can be locally addressed. */
4518
4519 /* larl_operand requires UNSPECs to be wrapped in a const rtx. */
4520 rtx const_addr = (GET_CODE (addr) == UNSPEC ?
4521 gen_rtx_CONST (Pmode, addr) : addr);
4522
4523 if (TARGET_CPU_ZARCH
4524 && larl_operand (const_addr, VOIDmode)
b422d8c0 4525 && INTVAL (addend) < HOST_WIDE_INT_1 << 31
4526 && INTVAL (addend) >= -(HOST_WIDE_INT_1 << 31))
2a672556 4527 {
4528 if (INTVAL (addend) & 1)
4529 {
4530 /* LARL can't handle odd offsets, so emit a pair of LARL
4531 and LA. */
4532 rtx temp = reg? reg : gen_reg_rtx (Pmode);
4533
4534 if (!DISP_IN_RANGE (INTVAL (addend)))
4535 {
4536 HOST_WIDE_INT even = INTVAL (addend) - 1;
4537 addr = gen_rtx_PLUS (Pmode, addr, GEN_INT (even));
4538 addr = gen_rtx_CONST (Pmode, addr);
4539 addend = const1_rtx;
4540 }
4541
4542 emit_move_insn (temp, addr);
4543 new_rtx = gen_rtx_PLUS (Pmode, temp, addend);
4544
4545 if (reg != 0)
4546 {
4547 s390_load_address (reg, new_rtx);
4548 new_rtx = reg;
4549 }
4550 }
4551 else
4552 {
4553 /* If the offset is even, we can just use LARL. This
4554 will happen automatically. */
4555 }
4556 }
4673c1a0 4557 else
2a672556 4558 {
4559 /* No larl - Access local symbols relative to the GOT. */
4673c1a0 4560
2a672556 4561 rtx temp = reg? reg : gen_reg_rtx (Pmode);
4673c1a0 4562
12ef3745 4563 if (reload_in_progress || reload_completed)
3072d30e 4564 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
12ef3745 4565
2a672556 4566 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
4567 if (addend != const0_rtx)
4568 addr = gen_rtx_PLUS (Pmode, addr, addend);
4569 addr = gen_rtx_CONST (Pmode, addr);
4570 addr = force_const_mem (Pmode, addr);
4673c1a0 4571 emit_move_insn (temp, addr);
4572
2a672556 4573 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
4574 if (reg != 0)
4575 {
4576 s390_load_address (reg, new_rtx);
4577 new_rtx = reg;
4578 }
4579 }
4673c1a0 4580 }
2a672556 4581 else if (GET_CODE (addr) == SYMBOL_REF && addend == const0_rtx)
4673c1a0 4582 {
2a672556 4583 /* A non-local symbol reference without addend.
4584
4585 The symbol ref is wrapped into an UNSPEC to make sure the
4586 proper operand modifier (@GOT or @GOTENT) will be emitted.
4587 This will tell the linker to put the symbol into the GOT.
4588
4589 Additionally the code dereferencing the GOT slot is emitted here.
4590
4591 An addend to the symref needs to be added afterwards.
4592 legitimize_pic_address calls itself recursively to handle
4593 that case. So no need to do it here. */
4594
4673c1a0 4595 if (reg == 0)
4596 reg = gen_reg_rtx (Pmode);
4597
2a672556 4598 if (TARGET_Z10)
4599 {
4600 /* Use load relative if possible.
4601 lgrl <target>, sym@GOTENT */
4602 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTENT);
4603 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
4604 new_rtx = gen_const_mem (GET_MODE (reg), new_rtx);
4605
4606 emit_move_insn (reg, new_rtx);
4607 new_rtx = reg;
4608 }
4609 else if (flag_pic == 1)
4673c1a0 4610 {
2a672556 4611 /* Assume GOT offset is a valid displacement operand (< 4k
4612 or < 512k with z990). This is handled the same way in
4613 both 31- and 64-bit code (@GOT).
4614 lg <target>, sym@GOT(r12) */
4673c1a0 4615
9a2a66ae 4616 if (reload_in_progress || reload_completed)
3072d30e 4617 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
4673c1a0 4618
8deb3959 4619 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
4620 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
4621 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
4622 new_rtx = gen_const_mem (Pmode, new_rtx);
4623 emit_move_insn (reg, new_rtx);
4624 new_rtx = reg;
4673c1a0 4625 }
dafc8d45 4626 else if (TARGET_CPU_ZARCH)
4673c1a0 4627 {
4628 /* If the GOT offset might be >= 4k, we determine the position
2a672556 4629 of the GOT entry via a PC-relative LARL (@GOTENT).
4630 larl temp, sym@GOTENT
4631 lg <target>, 0(temp) */
4673c1a0 4632
08b5e262 4633 rtx temp = reg ? reg : gen_reg_rtx (Pmode);
4634
4635 gcc_assert (REGNO (temp) >= FIRST_PSEUDO_REGISTER
4636 || REGNO_REG_CLASS (REGNO (temp)) == ADDR_REGS);
4673c1a0 4637
8deb3959 4638 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTENT);
4639 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
2a672556 4640 emit_move_insn (temp, new_rtx);
4673c1a0 4641
2a672556 4642 new_rtx = gen_const_mem (Pmode, temp);
8deb3959 4643 emit_move_insn (reg, new_rtx);
2a672556 4644
8deb3959 4645 new_rtx = reg;
4673c1a0 4646 }
4647 else
4648 {
f81e845f 4649 /* If the GOT offset might be >= 4k, we have to load it
2a672556 4650 from the literal pool (@GOT).
4651
4652 lg temp, lit-litbase(r13)
4653 lg <target>, 0(temp)
4654 lit: .long sym@GOT */
4673c1a0 4655
08b5e262 4656 rtx temp = reg ? reg : gen_reg_rtx (Pmode);
4657
4658 gcc_assert (REGNO (temp) >= FIRST_PSEUDO_REGISTER
4659 || REGNO_REG_CLASS (REGNO (temp)) == ADDR_REGS);
4673c1a0 4660
9a2a66ae 4661 if (reload_in_progress || reload_completed)
3072d30e 4662 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
4673c1a0 4663
12ef3745 4664 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
525d1294 4665 addr = gen_rtx_CONST (Pmode, addr);
4666 addr = force_const_mem (Pmode, addr);
4673c1a0 4667 emit_move_insn (temp, addr);
4668
8deb3959 4669 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
4670 new_rtx = gen_const_mem (Pmode, new_rtx);
4671 emit_move_insn (reg, new_rtx);
4672 new_rtx = reg;
4673c1a0 4673 }
f81e845f 4674 }
2a672556 4675 else if (GET_CODE (addr) == UNSPEC && GET_CODE (addend) == CONST_INT)
4673c1a0 4676 {
2a672556 4677 gcc_assert (XVECLEN (addr, 0) == 1);
4678 switch (XINT (addr, 1))
4673c1a0 4679 {
2a672556 4680 /* These address symbols (or PLT slots) relative to the GOT
4681 (not GOT slots!). In general this will exceed the
4682 displacement range so these value belong into the literal
4683 pool. */
4684 case UNSPEC_GOTOFF:
4685 case UNSPEC_PLTOFF:
4686 new_rtx = force_const_mem (Pmode, orig);
4687 break;
4673c1a0 4688
2a672556 4689 /* For -fPIC the GOT size might exceed the displacement
4690 range so make sure the value is in the literal pool. */
4691 case UNSPEC_GOT:
4692 if (flag_pic == 2)
4693 new_rtx = force_const_mem (Pmode, orig);
4694 break;
4673c1a0 4695
2a672556 4696 /* For @GOTENT larl is used. This is handled like local
4697 symbol refs. */
4698 case UNSPEC_GOTENT:
4699 gcc_unreachable ();
4700 break;
4673c1a0 4701
2a672556 4702 /* @PLT is OK as is on 64-bit, must be converted to
4703 GOT-relative @PLTOFF on 31-bit. */
4704 case UNSPEC_PLT:
4705 if (!TARGET_CPU_ZARCH)
4673c1a0 4706 {
2a672556 4707 rtx temp = reg? reg : gen_reg_rtx (Pmode);
4708
4709 if (reload_in_progress || reload_completed)
4710 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
4711
4712 addr = XVECEXP (addr, 0, 0);
4713 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
4714 UNSPEC_PLTOFF);
4715 if (addend != const0_rtx)
4716 addr = gen_rtx_PLUS (Pmode, addr, addend);
4717 addr = gen_rtx_CONST (Pmode, addr);
4718 addr = force_const_mem (Pmode, addr);
4719 emit_move_insn (temp, addr);
4720
4721 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
4722 if (reg != 0)
4673c1a0 4723 {
2a672556 4724 s390_load_address (reg, new_rtx);
4725 new_rtx = reg;
4673c1a0 4726 }
2a672556 4727 }
4728 else
4729 /* On 64 bit larl can be used. This case is handled like
4730 local symbol refs. */
4731 gcc_unreachable ();
4732 break;
4733
4734 /* Everything else cannot happen. */
4735 default:
4736 gcc_unreachable ();
4737 }
4738 }
4739 else if (addend != const0_rtx)
4740 {
4741 /* Otherwise, compute the sum. */
4673c1a0 4742
2a672556 4743 rtx base = legitimize_pic_address (addr, reg);
4744 new_rtx = legitimize_pic_address (addend,
4745 base == reg ? NULL_RTX : reg);
4746 if (GET_CODE (new_rtx) == CONST_INT)
4747 new_rtx = plus_constant (Pmode, base, INTVAL (new_rtx));
4748 else
4749 {
4750 if (GET_CODE (new_rtx) == PLUS && CONSTANT_P (XEXP (new_rtx, 1)))
4751 {
4752 base = gen_rtx_PLUS (Pmode, base, XEXP (new_rtx, 0));
4753 new_rtx = XEXP (new_rtx, 1);
4673c1a0 4754 }
2a672556 4755 new_rtx = gen_rtx_PLUS (Pmode, base, new_rtx);
4673c1a0 4756 }
2a672556 4757
4758 if (GET_CODE (new_rtx) == CONST)
4759 new_rtx = XEXP (new_rtx, 0);
4760 new_rtx = force_operand (new_rtx, 0);
4673c1a0 4761 }
2a672556 4762
8deb3959 4763 return new_rtx;
4673c1a0 4764}
4765
be00aaa8 4766/* Load the thread pointer into a register. */
4767
cc87d0c5 4768rtx
4769s390_get_thread_pointer (void)
be00aaa8 4770{
923cf36d 4771 rtx tp = gen_reg_rtx (Pmode);
be00aaa8 4772
923cf36d 4773 emit_move_insn (tp, gen_rtx_REG (Pmode, TP_REGNUM));
be00aaa8 4774 mark_reg_pointer (tp, BITS_PER_WORD);
4775
4776 return tp;
4777}
4778
7346ca58 4779/* Emit a tls call insn. The call target is the SYMBOL_REF stored
4780 in s390_tls_symbol which always refers to __tls_get_offset.
4781 The returned offset is written to RESULT_REG and an USE rtx is
4782 generated for TLS_CALL. */
be00aaa8 4783
4784static GTY(()) rtx s390_tls_symbol;
7346ca58 4785
4786static void
4787s390_emit_tls_call_insn (rtx result_reg, rtx tls_call)
be00aaa8 4788{
7346ca58 4789 rtx insn;
f588eb9f 4790
c60a7572 4791 if (!flag_pic)
4792 emit_insn (s390_load_got ());
7346ca58 4793
be00aaa8 4794 if (!s390_tls_symbol)
4795 s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset");
4796
f588eb9f 4797 insn = s390_emit_call (s390_tls_symbol, tls_call, result_reg,
4798 gen_rtx_REG (Pmode, RETURN_REGNUM));
7346ca58 4799
4800 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), result_reg);
9c2a0c05 4801 RTL_CONST_CALL_P (insn) = 1;
be00aaa8 4802}
4803
4804/* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
4805 this (thread-local) address. REG may be used as temporary. */
4806
4807static rtx
b40da9a7 4808legitimize_tls_address (rtx addr, rtx reg)
be00aaa8 4809{
db7dd023 4810 rtx new_rtx, tls_call, temp, base, r2;
4811 rtx_insn *insn;
be00aaa8 4812
4813 if (GET_CODE (addr) == SYMBOL_REF)
4814 switch (tls_symbolic_operand (addr))
4815 {
4816 case TLS_MODEL_GLOBAL_DYNAMIC:
4817 start_sequence ();
4818 r2 = gen_rtx_REG (Pmode, 2);
4819 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLSGD);
8deb3959 4820 new_rtx = gen_rtx_CONST (Pmode, tls_call);
4821 new_rtx = force_const_mem (Pmode, new_rtx);
4822 emit_move_insn (r2, new_rtx);
7346ca58 4823 s390_emit_tls_call_insn (r2, tls_call);
be00aaa8 4824 insn = get_insns ();
4825 end_sequence ();
4826
8deb3959 4827 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
be00aaa8 4828 temp = gen_reg_rtx (Pmode);
8deb3959 4829 emit_libcall_block (insn, temp, r2, new_rtx);
be00aaa8 4830
8deb3959 4831 new_rtx = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
be00aaa8 4832 if (reg != 0)
4833 {
8deb3959 4834 s390_load_address (reg, new_rtx);
4835 new_rtx = reg;
be00aaa8 4836 }
4837 break;
4838
4839 case TLS_MODEL_LOCAL_DYNAMIC:
4840 start_sequence ();
4841 r2 = gen_rtx_REG (Pmode, 2);
4842 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM);
8deb3959 4843 new_rtx = gen_rtx_CONST (Pmode, tls_call);
4844 new_rtx = force_const_mem (Pmode, new_rtx);
4845 emit_move_insn (r2, new_rtx);
7346ca58 4846 s390_emit_tls_call_insn (r2, tls_call);
be00aaa8 4847 insn = get_insns ();
4848 end_sequence ();
4849
8deb3959 4850 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM_NTPOFF);
be00aaa8 4851 temp = gen_reg_rtx (Pmode);
8deb3959 4852 emit_libcall_block (insn, temp, r2, new_rtx);
be00aaa8 4853
8deb3959 4854 new_rtx = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
be00aaa8 4855 base = gen_reg_rtx (Pmode);
8deb3959 4856 s390_load_address (base, new_rtx);
be00aaa8 4857
8deb3959 4858 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_DTPOFF);
4859 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
4860 new_rtx = force_const_mem (Pmode, new_rtx);
be00aaa8 4861 temp = gen_reg_rtx (Pmode);
8deb3959 4862 emit_move_insn (temp, new_rtx);
be00aaa8 4863
8deb3959 4864 new_rtx = gen_rtx_PLUS (Pmode, base, temp);
be00aaa8 4865 if (reg != 0)
4866 {
8deb3959 4867 s390_load_address (reg, new_rtx);
4868 new_rtx = reg;
be00aaa8 4869 }
4870 break;
4871
4872 case TLS_MODEL_INITIAL_EXEC:
4873 if (flag_pic == 1)
4874 {
4875 /* Assume GOT offset < 4k. This is handled the same way
4876 in both 31- and 64-bit code. */
4877
4878 if (reload_in_progress || reload_completed)
3072d30e 4879 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
be00aaa8 4880
8deb3959 4881 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
4882 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
4883 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
4884 new_rtx = gen_const_mem (Pmode, new_rtx);
be00aaa8 4885 temp = gen_reg_rtx (Pmode);
8deb3959 4886 emit_move_insn (temp, new_rtx);
be00aaa8 4887 }
dafc8d45 4888 else if (TARGET_CPU_ZARCH)
be00aaa8 4889 {
4890 /* If the GOT offset might be >= 4k, we determine the position
4891 of the GOT entry via a PC-relative LARL. */
4892
8deb3959 4893 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
4894 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
be00aaa8 4895 temp = gen_reg_rtx (Pmode);
8deb3959 4896 emit_move_insn (temp, new_rtx);
be00aaa8 4897
8deb3959 4898 new_rtx = gen_const_mem (Pmode, temp);
be00aaa8 4899 temp = gen_reg_rtx (Pmode);
8deb3959 4900 emit_move_insn (temp, new_rtx);
be00aaa8 4901 }
4902 else if (flag_pic)
4903 {
f81e845f 4904 /* If the GOT offset might be >= 4k, we have to load it
be00aaa8 4905 from the literal pool. */
4906
4907 if (reload_in_progress || reload_completed)
3072d30e 4908 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
be00aaa8 4909
8deb3959 4910 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
4911 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
4912 new_rtx = force_const_mem (Pmode, new_rtx);
be00aaa8 4913 temp = gen_reg_rtx (Pmode);
8deb3959 4914 emit_move_insn (temp, new_rtx);
be00aaa8 4915
8deb3959 4916 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
4917 new_rtx = gen_const_mem (Pmode, new_rtx);
be00aaa8 4918
8deb3959 4919 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new_rtx, addr), UNSPEC_TLS_LOAD);
be00aaa8 4920 temp = gen_reg_rtx (Pmode);
d1f9b275 4921 emit_insn (gen_rtx_SET (temp, new_rtx));
be00aaa8 4922 }
4923 else
4924 {
4925 /* In position-dependent code, load the absolute address of
4926 the GOT entry from the literal pool. */
4927
8deb3959 4928 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
4929 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
4930 new_rtx = force_const_mem (Pmode, new_rtx);
be00aaa8 4931 temp = gen_reg_rtx (Pmode);
8deb3959 4932 emit_move_insn (temp, new_rtx);
be00aaa8 4933
8deb3959 4934 new_rtx = temp;
4935 new_rtx = gen_const_mem (Pmode, new_rtx);
4936 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new_rtx, addr), UNSPEC_TLS_LOAD);
be00aaa8 4937 temp = gen_reg_rtx (Pmode);
d1f9b275 4938 emit_insn (gen_rtx_SET (temp, new_rtx));
be00aaa8 4939 }
4940
8deb3959 4941 new_rtx = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
be00aaa8 4942 if (reg != 0)
4943 {
8deb3959 4944 s390_load_address (reg, new_rtx);
4945 new_rtx = reg;
be00aaa8 4946 }
4947 break;
4948
4949 case TLS_MODEL_LOCAL_EXEC:
8deb3959 4950 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
4951 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
4952 new_rtx = force_const_mem (Pmode, new_rtx);
be00aaa8 4953 temp = gen_reg_rtx (Pmode);
8deb3959 4954 emit_move_insn (temp, new_rtx);
be00aaa8 4955
8deb3959 4956 new_rtx = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
be00aaa8 4957 if (reg != 0)
4958 {
8deb3959 4959 s390_load_address (reg, new_rtx);
4960 new_rtx = reg;
be00aaa8 4961 }
4962 break;
4963
4964 default:
32eda510 4965 gcc_unreachable ();
be00aaa8 4966 }
4967
4968 else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == UNSPEC)
4969 {
4970 switch (XINT (XEXP (addr, 0), 1))
4971 {
4972 case UNSPEC_INDNTPOFF:
32eda510 4973 gcc_assert (TARGET_CPU_ZARCH);
8deb3959 4974 new_rtx = addr;
be00aaa8 4975 break;
4976
4977 default:
32eda510 4978 gcc_unreachable ();
be00aaa8 4979 }
4980 }
4981
b7ace65c 4982 else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == PLUS
4983 && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
4984 {
8deb3959 4985 new_rtx = XEXP (XEXP (addr, 0), 0);
4986 if (GET_CODE (new_rtx) != SYMBOL_REF)
4987 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
b7ace65c 4988
8deb3959 4989 new_rtx = legitimize_tls_address (new_rtx, reg);
29c05e22 4990 new_rtx = plus_constant (Pmode, new_rtx,
4991 INTVAL (XEXP (XEXP (addr, 0), 1)));
8deb3959 4992 new_rtx = force_operand (new_rtx, 0);
b7ace65c 4993 }
4994
be00aaa8 4995 else
32eda510 4996 gcc_unreachable (); /* for now ... */
be00aaa8 4997
8deb3959 4998 return new_rtx;
be00aaa8 4999}
5000
08b5e262 5001/* Emit insns making the address in operands[1] valid for a standard
5002 move to operands[0]. operands[1] is replaced by an address which
5003 should be used instead of the former RTX to emit the move
5004 pattern. */
4673c1a0 5005
5006void
b40da9a7 5007emit_symbolic_move (rtx *operands)
4673c1a0 5008{
e1ba4a27 5009 rtx temp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
4673c1a0 5010
be00aaa8 5011 if (GET_CODE (operands[0]) == MEM)
4673c1a0 5012 operands[1] = force_reg (Pmode, operands[1]);
be00aaa8 5013 else if (TLS_SYMBOLIC_CONST (operands[1]))
5014 operands[1] = legitimize_tls_address (operands[1], temp);
5015 else if (flag_pic)
4673c1a0 5016 operands[1] = legitimize_pic_address (operands[1], temp);
5017}
5018
56769981 5019/* Try machine-dependent ways of modifying an illegitimate address X
4673c1a0 5020 to be legitimate. If we find one, return the new, valid address.
4673c1a0 5021
5022 OLDX is the address as it was before break_out_memory_refs was called.
5023 In some cases it is useful to look at this to decide what needs to be done.
5024
56769981 5025 MODE is the mode of the operand pointed to by X.
4673c1a0 5026
5027 When -fpic is used, special handling is needed for symbolic references.
5028 See comments by legitimize_pic_address for details. */
5029
41e3a0c7 5030static rtx
5031s390_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
3754d046 5032 machine_mode mode ATTRIBUTE_UNUSED)
4673c1a0 5033{
2eb8fe23 5034 rtx constant_term = const0_rtx;
4673c1a0 5035
be00aaa8 5036 if (TLS_SYMBOLIC_CONST (x))
5037 {
5038 x = legitimize_tls_address (x, 0);
5039
fd50b071 5040 if (s390_legitimate_address_p (mode, x, FALSE))
be00aaa8 5041 return x;
5042 }
1ed004b7 5043 else if (GET_CODE (x) == PLUS
ffead1ca 5044 && (TLS_SYMBOLIC_CONST (XEXP (x, 0))
1ed004b7 5045 || TLS_SYMBOLIC_CONST (XEXP (x, 1))))
5046 {
5047 return x;
5048 }
be00aaa8 5049 else if (flag_pic)
4673c1a0 5050 {
2eb8fe23 5051 if (SYMBOLIC_CONST (x)
f81e845f 5052 || (GET_CODE (x) == PLUS
5053 && (SYMBOLIC_CONST (XEXP (x, 0))
2eb8fe23 5054 || SYMBOLIC_CONST (XEXP (x, 1)))))
5055 x = legitimize_pic_address (x, 0);
5056
fd50b071 5057 if (s390_legitimate_address_p (mode, x, FALSE))
2eb8fe23 5058 return x;
4673c1a0 5059 }
4673c1a0 5060
2eb8fe23 5061 x = eliminate_constant_term (x, &constant_term);
56769981 5062
de84f805 5063 /* Optimize loading of large displacements by splitting them
5064 into the multiple of 4K and the rest; this allows the
f81e845f 5065 former to be CSE'd if possible.
de84f805 5066
5067 Don't do this if the displacement is added to a register
5068 pointing into the stack frame, as the offsets will
5069 change later anyway. */
5070
5071 if (GET_CODE (constant_term) == CONST_INT
51aa1e9c 5072 && !TARGET_LONG_DISPLACEMENT
5073 && !DISP_IN_RANGE (INTVAL (constant_term))
de84f805 5074 && !(REG_P (x) && REGNO_PTR_FRAME_P (REGNO (x))))
5075 {
5076 HOST_WIDE_INT lower = INTVAL (constant_term) & 0xfff;
5077 HOST_WIDE_INT upper = INTVAL (constant_term) ^ lower;
5078
5079 rtx temp = gen_reg_rtx (Pmode);
5080 rtx val = force_operand (GEN_INT (upper), temp);
5081 if (val != temp)
5082 emit_move_insn (temp, val);
5083
5084 x = gen_rtx_PLUS (Pmode, x, temp);
5085 constant_term = GEN_INT (lower);
5086 }
5087
2eb8fe23 5088 if (GET_CODE (x) == PLUS)
4673c1a0 5089 {
2eb8fe23 5090 if (GET_CODE (XEXP (x, 0)) == REG)
5091 {
edd89d66 5092 rtx temp = gen_reg_rtx (Pmode);
5093 rtx val = force_operand (XEXP (x, 1), temp);
2eb8fe23 5094 if (val != temp)
5095 emit_move_insn (temp, val);
5096
5097 x = gen_rtx_PLUS (Pmode, XEXP (x, 0), temp);
5098 }
5099
5100 else if (GET_CODE (XEXP (x, 1)) == REG)
5101 {
edd89d66 5102 rtx temp = gen_reg_rtx (Pmode);
5103 rtx val = force_operand (XEXP (x, 0), temp);
2eb8fe23 5104 if (val != temp)
5105 emit_move_insn (temp, val);
5106
5107 x = gen_rtx_PLUS (Pmode, temp, XEXP (x, 1));
5108 }
4673c1a0 5109 }
2eb8fe23 5110
5111 if (constant_term != const0_rtx)
5112 x = gen_rtx_PLUS (Pmode, x, constant_term);
5113
5114 return x;
4673c1a0 5115}
5116
e4542435 5117/* Try a machine-dependent way of reloading an illegitimate address AD
851d9296 5118 operand. If we find one, push the reload and return the new address.
e4542435 5119
5120 MODE is the mode of the enclosing MEM. OPNUM is the operand number
5121 and TYPE is the reload type of the current reload. */
5122
ffead1ca 5123rtx
3754d046 5124legitimize_reload_address (rtx ad, machine_mode mode ATTRIBUTE_UNUSED,
e4542435 5125 int opnum, int type)
5126{
5127 if (!optimize || TARGET_LONG_DISPLACEMENT)
5128 return NULL_RTX;
5129
5130 if (GET_CODE (ad) == PLUS)
5131 {
5132 rtx tem = simplify_binary_operation (PLUS, Pmode,
5133 XEXP (ad, 0), XEXP (ad, 1));
5134 if (tem)
5135 ad = tem;
5136 }
5137
5138 if (GET_CODE (ad) == PLUS
5139 && GET_CODE (XEXP (ad, 0)) == REG
5140 && GET_CODE (XEXP (ad, 1)) == CONST_INT
5141 && !DISP_IN_RANGE (INTVAL (XEXP (ad, 1))))
5142 {
5143 HOST_WIDE_INT lower = INTVAL (XEXP (ad, 1)) & 0xfff;
5144 HOST_WIDE_INT upper = INTVAL (XEXP (ad, 1)) ^ lower;
8deb3959 5145 rtx cst, tem, new_rtx;
e4542435 5146
5147 cst = GEN_INT (upper);
5148 if (!legitimate_reload_constant_p (cst))
5149 cst = force_const_mem (Pmode, cst);
5150
5151 tem = gen_rtx_PLUS (Pmode, XEXP (ad, 0), cst);
8deb3959 5152 new_rtx = gen_rtx_PLUS (Pmode, tem, GEN_INT (lower));
e4542435 5153
5154 push_reload (XEXP (tem, 1), 0, &XEXP (tem, 1), 0,
ffead1ca 5155 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
e4542435 5156 opnum, (enum reload_type) type);
8deb3959 5157 return new_rtx;
e4542435 5158 }
5159
5160 return NULL_RTX;
5161}
5162
4fbc4db5 5163/* Emit code to move LEN bytes from DST to SRC. */
5164
daa87e5a 5165bool
008c057d 5166s390_expand_movmem (rtx dst, rtx src, rtx len)
4fbc4db5 5167{
daa87e5a 5168 /* When tuning for z10 or higher we rely on the Glibc functions to
5169 do the right thing. Only for constant lengths below 64k we will
5170 generate inline code. */
5171 if (s390_tune >= PROCESSOR_2097_Z10
5172 && (GET_CODE (len) != CONST_INT || INTVAL (len) > (1<<16)))
5173 return false;
5174
d044af2a 5175 /* Expand memcpy for constant length operands without a loop if it
5176 is shorter that way.
5177
5178 With a constant length argument a
5179 memcpy loop (without pfd) is 36 bytes -> 6 * mvc */
5180 if (GET_CODE (len) == CONST_INT
5181 && INTVAL (len) >= 0
5182 && INTVAL (len) <= 256 * 6
5183 && (!TARGET_MVCLE || INTVAL (len) <= 256))
4fbc4db5 5184 {
d044af2a 5185 HOST_WIDE_INT o, l;
5186
5187 for (l = INTVAL (len), o = 0; l > 0; l -= 256, o += 256)
5188 {
5189 rtx newdst = adjust_address (dst, BLKmode, o);
5190 rtx newsrc = adjust_address (src, BLKmode, o);
5191 emit_insn (gen_movmem_short (newdst, newsrc,
5192 GEN_INT (l > 256 ? 255 : l - 1)));
5193 }
4fbc4db5 5194 }
5195
5196 else if (TARGET_MVCLE)
5197 {
008c057d 5198 emit_insn (gen_movmem_long (dst, src, convert_to_mode (Pmode, len, 1)));
4fbc4db5 5199 }
5200
5201 else
5202 {
5203 rtx dst_addr, src_addr, count, blocks, temp;
79f6a8ed 5204 rtx_code_label *loop_start_label = gen_label_rtx ();
5205 rtx_code_label *loop_end_label = gen_label_rtx ();
5206 rtx_code_label *end_label = gen_label_rtx ();
3754d046 5207 machine_mode mode;
4fbc4db5 5208
5209 mode = GET_MODE (len);
5210 if (mode == VOIDmode)
31838f66 5211 mode = Pmode;
4fbc4db5 5212
4fbc4db5 5213 dst_addr = gen_reg_rtx (Pmode);
5214 src_addr = gen_reg_rtx (Pmode);
5215 count = gen_reg_rtx (mode);
5216 blocks = gen_reg_rtx (mode);
5217
5218 convert_move (count, len, 1);
f81e845f 5219 emit_cmp_and_jump_insns (count, const0_rtx,
4fbc4db5 5220 EQ, NULL_RTX, mode, 1, end_label);
5221
5222 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
5223 emit_move_insn (src_addr, force_operand (XEXP (src, 0), NULL_RTX));
5224 dst = change_address (dst, VOIDmode, dst_addr);
5225 src = change_address (src, VOIDmode, src_addr);
f81e845f 5226
b9c74b4d 5227 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1,
5228 OPTAB_DIRECT);
4fbc4db5 5229 if (temp != count)
5230 emit_move_insn (count, temp);
5231
b9c74b4d 5232 temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1,
5233 OPTAB_DIRECT);
4fbc4db5 5234 if (temp != blocks)
5235 emit_move_insn (blocks, temp);
5236
4ee9c684 5237 emit_cmp_and_jump_insns (blocks, const0_rtx,
5238 EQ, NULL_RTX, mode, 1, loop_end_label);
7746964e 5239
5240 emit_label (loop_start_label);
4fbc4db5 5241
d5de7805 5242 if (TARGET_Z10
5243 && (GET_CODE (len) != CONST_INT || INTVAL (len) > 768))
5244 {
5245 rtx prefetch;
5246
5247 /* Issue a read prefetch for the +3 cache line. */
5248 prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, src_addr, GEN_INT (768)),
5249 const0_rtx, const0_rtx);
5250 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
5251 emit_insn (prefetch);
5252
5253 /* Issue a write prefetch for the +3 cache line. */
5254 prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (768)),
5255 const1_rtx, const0_rtx);
5256 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
5257 emit_insn (prefetch);
5258 }
5259
008c057d 5260 emit_insn (gen_movmem_short (dst, src, GEN_INT (255)));
f81e845f 5261 s390_load_address (dst_addr,
4fbc4db5 5262 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
f81e845f 5263 s390_load_address (src_addr,
4fbc4db5 5264 gen_rtx_PLUS (Pmode, src_addr, GEN_INT (256)));
f81e845f 5265
b9c74b4d 5266 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1,
5267 OPTAB_DIRECT);
4fbc4db5 5268 if (temp != blocks)
5269 emit_move_insn (blocks, temp);
5270
4ee9c684 5271 emit_cmp_and_jump_insns (blocks, const0_rtx,
5272 EQ, NULL_RTX, mode, 1, loop_end_label);
7746964e 5273
5274 emit_jump (loop_start_label);
4ee9c684 5275 emit_label (loop_end_label);
4fbc4db5 5276
008c057d 5277 emit_insn (gen_movmem_short (dst, src,
31838f66 5278 convert_to_mode (Pmode, count, 1)));
4fbc4db5 5279 emit_label (end_label);
5280 }
daa87e5a 5281 return true;
4fbc4db5 5282}
5283
805a133b 5284/* Emit code to set LEN bytes at DST to VAL.
5285 Make use of clrmem if VAL is zero. */
4fbc4db5 5286
5287void
805a133b 5288s390_expand_setmem (rtx dst, rtx len, rtx val)
4fbc4db5 5289{
4b6f12fb 5290 const int very_unlikely = REG_BR_PROB_BASE / 100 - 1;
5291
2b1d59f5 5292 if (GET_CODE (len) == CONST_INT && INTVAL (len) <= 0)
1ed6fd08 5293 return;
5294
805a133b 5295 gcc_assert (GET_CODE (val) == CONST_INT || GET_MODE (val) == QImode);
ffead1ca 5296
2b1d59f5 5297 /* Expand setmem/clrmem for a constant length operand without a
5298 loop if it will be shorter that way.
5299 With a constant length and without pfd argument a
5300 clrmem loop is 32 bytes -> 5.3 * xc
5301 setmem loop is 36 bytes -> 3.6 * (mvi/stc + mvc) */
5302 if (GET_CODE (len) == CONST_INT
5303 && ((INTVAL (len) <= 256 * 5 && val == const0_rtx)
5304 || INTVAL (len) <= 257 * 3)
5305 && (!TARGET_MVCLE || INTVAL (len) <= 256))
4fbc4db5 5306 {
2b1d59f5 5307 HOST_WIDE_INT o, l;
ffead1ca 5308
2b1d59f5 5309 if (val == const0_rtx)
5310 /* clrmem: emit 256 byte blockwise XCs. */
5311 for (l = INTVAL (len), o = 0; l > 0; l -= 256, o += 256)
5312 {
5313 rtx newdst = adjust_address (dst, BLKmode, o);
5314 emit_insn (gen_clrmem_short (newdst,
5315 GEN_INT (l > 256 ? 255 : l - 1)));
5316 }
5317 else
5318 /* setmem: emit 1(mvi) + 256(mvc) byte blockwise memsets by
5319 setting first byte to val and using a 256 byte mvc with one
5320 byte overlap to propagate the byte. */
5321 for (l = INTVAL (len), o = 0; l > 0; l -= 257, o += 257)
5322 {
5323 rtx newdst = adjust_address (dst, BLKmode, o);
5324 emit_move_insn (adjust_address (dst, QImode, o), val);
5325 if (l > 1)
5326 {
5327 rtx newdstp1 = adjust_address (dst, BLKmode, o + 1);
5328 emit_insn (gen_movmem_short (newdstp1, newdst,
5329 GEN_INT (l > 257 ? 255 : l - 2)));
5330 }
5331 }
4fbc4db5 5332 }
5333
5334 else if (TARGET_MVCLE)
5335 {
805a133b 5336 val = force_not_mem (convert_modes (Pmode, QImode, val, 1));
00091884 5337 if (TARGET_64BIT)
5338 emit_insn (gen_setmem_long_di (dst, convert_to_mode (Pmode, len, 1),
5339 val));
5340 else
5341 emit_insn (gen_setmem_long_si (dst, convert_to_mode (Pmode, len, 1),
5342 val));
4fbc4db5 5343 }
5344
5345 else
5346 {
b5fdc416 5347 rtx dst_addr, count, blocks, temp, dstp1 = NULL_RTX;
79f6a8ed 5348 rtx_code_label *loop_start_label = gen_label_rtx ();
4b6f12fb 5349 rtx_code_label *onebyte_end_label = gen_label_rtx ();
5350 rtx_code_label *zerobyte_end_label = gen_label_rtx ();
5351 rtx_code_label *restbyte_end_label = gen_label_rtx ();
3754d046 5352 machine_mode mode;
4fbc4db5 5353
5354 mode = GET_MODE (len);
5355 if (mode == VOIDmode)
4b6f12fb 5356 mode = Pmode;
4fbc4db5 5357
4fbc4db5 5358 dst_addr = gen_reg_rtx (Pmode);
4fbc4db5 5359 count = gen_reg_rtx (mode);
5360 blocks = gen_reg_rtx (mode);
5361
5362 convert_move (count, len, 1);
f81e845f 5363 emit_cmp_and_jump_insns (count, const0_rtx,
4b6f12fb 5364 EQ, NULL_RTX, mode, 1, zerobyte_end_label,
5365 very_unlikely);
4fbc4db5 5366
4b6f12fb 5367 /* We need to make a copy of the target address since memset is
5368 supposed to return it unmodified. We have to make it here
5369 already since the new reg is used at onebyte_end_label. */
4fbc4db5 5370 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
5371 dst = change_address (dst, VOIDmode, dst_addr);
f81e845f 5372
4b6f12fb 5373 if (val != const0_rtx)
805a133b 5374 {
4b6f12fb 5375 /* When using the overlapping mvc the original target
5376 address is only accessed as single byte entity (even by
5377 the mvc reading this value). */
5b2a69fa 5378 set_mem_size (dst, 1);
4b6f12fb 5379 dstp1 = adjust_address (dst, VOIDmode, 1);
5380 emit_cmp_and_jump_insns (count,
5381 const1_rtx, EQ, NULL_RTX, mode, 1,
5382 onebyte_end_label, very_unlikely);
805a133b 5383 }
4b6f12fb 5384
5385 /* There is one unconditional (mvi+mvc)/xc after the loop
5386 dealing with the rest of the bytes, subtracting two (mvi+mvc)
5387 or one (xc) here leaves this number of bytes to be handled by
5388 it. */
5389 temp = expand_binop (mode, add_optab, count,
5390 val == const0_rtx ? constm1_rtx : GEN_INT (-2),
5391 count, 1, OPTAB_DIRECT);
4fbc4db5 5392 if (temp != count)
4b6f12fb 5393 emit_move_insn (count, temp);
4fbc4db5 5394
b9c74b4d 5395 temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1,
5396 OPTAB_DIRECT);
4fbc4db5 5397 if (temp != blocks)
4b6f12fb 5398 emit_move_insn (blocks, temp);
4fbc4db5 5399
4ee9c684 5400 emit_cmp_and_jump_insns (blocks, const0_rtx,
4b6f12fb 5401 EQ, NULL_RTX, mode, 1, restbyte_end_label);
5402
5403 emit_jump (loop_start_label);
5404
5405 if (val != const0_rtx)
5406 {
5407 /* The 1 byte != 0 special case. Not handled efficiently
5408 since we require two jumps for that. However, this
5409 should be very rare. */
5410 emit_label (onebyte_end_label);
5411 emit_move_insn (adjust_address (dst, QImode, 0), val);
5412 emit_jump (zerobyte_end_label);
5413 }
7746964e 5414
5415 emit_label (loop_start_label);
4fbc4db5 5416
d5de7805 5417 if (TARGET_Z10
5418 && (GET_CODE (len) != CONST_INT || INTVAL (len) > 1024))
5419 {
5420 /* Issue a write prefetch for the +4 cache line. */
5421 rtx prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, dst_addr,
5422 GEN_INT (1024)),
5423 const1_rtx, const0_rtx);
5424 emit_insn (prefetch);
5425 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
5426 }
5427
805a133b 5428 if (val == const0_rtx)
5429 emit_insn (gen_clrmem_short (dst, GEN_INT (255)));
5430 else
4b6f12fb 5431 {
5432 /* Set the first byte in the block to the value and use an
5433 overlapping mvc for the block. */
5434 emit_move_insn (adjust_address (dst, QImode, 0), val);
5435 emit_insn (gen_movmem_short (dstp1, dst, GEN_INT (254)));
5436 }
f81e845f 5437 s390_load_address (dst_addr,
4fbc4db5 5438 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
f81e845f 5439
b9c74b4d 5440 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1,
5441 OPTAB_DIRECT);
4fbc4db5 5442 if (temp != blocks)
4b6f12fb 5443 emit_move_insn (blocks, temp);
4fbc4db5 5444
4ee9c684 5445 emit_cmp_and_jump_insns (blocks, const0_rtx,
4b6f12fb 5446 NE, NULL_RTX, mode, 1, loop_start_label);
7746964e 5447
4b6f12fb 5448 emit_label (restbyte_end_label);
4fbc4db5 5449
805a133b 5450 if (val == const0_rtx)
4b6f12fb 5451 emit_insn (gen_clrmem_short (dst, convert_to_mode (Pmode, count, 1)));
805a133b 5452 else
4b6f12fb 5453 {
5454 /* Set the first byte in the block to the value and use an
5455 overlapping mvc for the block. */
5456 emit_move_insn (adjust_address (dst, QImode, 0), val);
5457 /* execute only uses the lowest 8 bits of count that's
5458 exactly what we need here. */
5459 emit_insn (gen_movmem_short (dstp1, dst,
5460 convert_to_mode (Pmode, count, 1)));
5461 }
5462
5463 emit_label (zerobyte_end_label);
4fbc4db5 5464 }
5465}
5466
5467/* Emit code to compare LEN bytes at OP0 with those at OP1,
5468 and return the result in TARGET. */
5469
daa87e5a 5470bool
b40da9a7 5471s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
4fbc4db5 5472{
80b53886 5473 rtx ccreg = gen_rtx_REG (CCUmode, CC_REGNUM);
dd16a4bd 5474 rtx tmp;
5475
daa87e5a 5476 /* When tuning for z10 or higher we rely on the Glibc functions to
5477 do the right thing. Only for constant lengths below 64k we will
5478 generate inline code. */
5479 if (s390_tune >= PROCESSOR_2097_Z10
5480 && (GET_CODE (len) != CONST_INT || INTVAL (len) > (1<<16)))
5481 return false;
5482
dd16a4bd 5483 /* As the result of CMPINT is inverted compared to what we need,
5484 we have to swap the operands. */
5485 tmp = op0; op0 = op1; op1 = tmp;
4fbc4db5 5486
4fbc4db5 5487 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
5488 {
5489 if (INTVAL (len) > 0)
5490 {
31838f66 5491 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (INTVAL (len) - 1)));
dd16a4bd 5492 emit_insn (gen_cmpint (target, ccreg));
4fbc4db5 5493 }
5494 else
5495 emit_move_insn (target, const0_rtx);
5496 }
bcbf02a5 5497 else if (TARGET_MVCLE)
4fbc4db5 5498 {
31838f66 5499 emit_insn (gen_cmpmem_long (op0, op1, convert_to_mode (Pmode, len, 1)));
dd16a4bd 5500 emit_insn (gen_cmpint (target, ccreg));
4fbc4db5 5501 }
4fbc4db5 5502 else
5503 {
5504 rtx addr0, addr1, count, blocks, temp;
79f6a8ed 5505 rtx_code_label *loop_start_label = gen_label_rtx ();
5506 rtx_code_label *loop_end_label = gen_label_rtx ();
5507 rtx_code_label *end_label = gen_label_rtx ();
3754d046 5508 machine_mode mode;
4fbc4db5 5509
5510 mode = GET_MODE (len);
5511 if (mode == VOIDmode)
31838f66 5512 mode = Pmode;
4fbc4db5 5513
4fbc4db5 5514 addr0 = gen_reg_rtx (Pmode);
5515 addr1 = gen_reg_rtx (Pmode);
5516 count = gen_reg_rtx (mode);
5517 blocks = gen_reg_rtx (mode);
5518
5519 convert_move (count, len, 1);
f81e845f 5520 emit_cmp_and_jump_insns (count, const0_rtx,
4fbc4db5 5521 EQ, NULL_RTX, mode, 1, end_label);
5522
5523 emit_move_insn (addr0, force_operand (XEXP (op0, 0), NULL_RTX));
5524 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
5525 op0 = change_address (op0, VOIDmode, addr0);
5526 op1 = change_address (op1, VOIDmode, addr1);
f81e845f 5527
b9c74b4d 5528 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1,
5529 OPTAB_DIRECT);
4fbc4db5 5530 if (temp != count)
5531 emit_move_insn (count, temp);
5532
b9c74b4d 5533 temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1,
5534 OPTAB_DIRECT);
4fbc4db5 5535 if (temp != blocks)
5536 emit_move_insn (blocks, temp);
5537
4ee9c684 5538 emit_cmp_and_jump_insns (blocks, const0_rtx,
5539 EQ, NULL_RTX, mode, 1, loop_end_label);
7746964e 5540
5541 emit_label (loop_start_label);
4fbc4db5 5542
d5de7805 5543 if (TARGET_Z10
5544 && (GET_CODE (len) != CONST_INT || INTVAL (len) > 512))
5545 {
5546 rtx prefetch;
5547
5548 /* Issue a read prefetch for the +2 cache line of operand 1. */
5549 prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, addr0, GEN_INT (512)),
5550 const0_rtx, const0_rtx);
5551 emit_insn (prefetch);
5552 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
5553
5554 /* Issue a read prefetch for the +2 cache line of operand 2. */
5555 prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, addr1, GEN_INT (512)),
5556 const0_rtx, const0_rtx);
5557 emit_insn (prefetch);
5558 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
5559 }
5560
31838f66 5561 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (255)));
80b53886 5562 temp = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
f81e845f 5563 temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
4fbc4db5 5564 gen_rtx_LABEL_REF (VOIDmode, end_label), pc_rtx);
d1f9b275 5565 temp = gen_rtx_SET (pc_rtx, temp);
4fbc4db5 5566 emit_jump_insn (temp);
5567
f81e845f 5568 s390_load_address (addr0,
4fbc4db5 5569 gen_rtx_PLUS (Pmode, addr0, GEN_INT (256)));
f81e845f 5570 s390_load_address (addr1,
4fbc4db5 5571 gen_rtx_PLUS (Pmode, addr1, GEN_INT (256)));
f81e845f 5572
b9c74b4d 5573 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1,
5574 OPTAB_DIRECT);
4fbc4db5 5575 if (temp != blocks)
5576 emit_move_insn (blocks, temp);
5577
4ee9c684 5578 emit_cmp_and_jump_insns (blocks, const0_rtx,
5579 EQ, NULL_RTX, mode, 1, loop_end_label);
7746964e 5580
5581 emit_jump (loop_start_label);
4ee9c684 5582 emit_label (loop_end_label);
4fbc4db5 5583
f588eb9f 5584 emit_insn (gen_cmpmem_short (op0, op1,
31838f66 5585 convert_to_mode (Pmode, count, 1)));
4fbc4db5 5586 emit_label (end_label);
5587
dd16a4bd 5588 emit_insn (gen_cmpint (target, ccreg));
4fbc4db5 5589 }
daa87e5a 5590 return true;
4fbc4db5 5591}
5592
76a4c804 5593/* Emit a conditional jump to LABEL for condition code mask MASK using
5594 comparsion operator COMPARISON. Return the emitted jump insn. */
5595
26cd1198 5596static rtx_insn *
76a4c804 5597s390_emit_ccraw_jump (HOST_WIDE_INT mask, enum rtx_code comparison, rtx label)
5598{
5599 rtx temp;
5600
5601 gcc_assert (comparison == EQ || comparison == NE);
5602 gcc_assert (mask > 0 && mask < 15);
5603
5604 temp = gen_rtx_fmt_ee (comparison, VOIDmode,
5605 gen_rtx_REG (CCRAWmode, CC_REGNUM), GEN_INT (mask));
5606 temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
5607 gen_rtx_LABEL_REF (VOIDmode, label), pc_rtx);
5608 temp = gen_rtx_SET (pc_rtx, temp);
5609 return emit_jump_insn (temp);
5610}
5611
5612/* Emit the instructions to implement strlen of STRING and store the
5613 result in TARGET. The string has the known ALIGNMENT. This
5614 version uses vector instructions and is therefore not appropriate
5615 for targets prior to z13. */
5616
5617void
5618s390_expand_vec_strlen (rtx target, rtx string, rtx alignment)
5619{
5620 int very_unlikely = REG_BR_PROB_BASE / 100 - 1;
5621 int very_likely = REG_BR_PROB_BASE - 1;
5622 rtx highest_index_to_load_reg = gen_reg_rtx (Pmode);
5623 rtx str_reg = gen_reg_rtx (V16QImode);
5624 rtx str_addr_base_reg = gen_reg_rtx (Pmode);
5625 rtx str_idx_reg = gen_reg_rtx (Pmode);
5626 rtx result_reg = gen_reg_rtx (V16QImode);
5627 rtx is_aligned_label = gen_label_rtx ();
5628 rtx into_loop_label = NULL_RTX;
5629 rtx loop_start_label = gen_label_rtx ();
5630 rtx temp;
5631 rtx len = gen_reg_rtx (QImode);
5632 rtx cond;
5633
5634 s390_load_address (str_addr_base_reg, XEXP (string, 0));
5635 emit_move_insn (str_idx_reg, const0_rtx);
5636
5637 if (INTVAL (alignment) < 16)
5638 {
5639 /* Check whether the address happens to be aligned properly so
5640 jump directly to the aligned loop. */
5641 emit_cmp_and_jump_insns (gen_rtx_AND (Pmode,
5642 str_addr_base_reg, GEN_INT (15)),
5643 const0_rtx, EQ, NULL_RTX,
5644 Pmode, 1, is_aligned_label);
5645
5646 temp = gen_reg_rtx (Pmode);
5647 temp = expand_binop (Pmode, and_optab, str_addr_base_reg,
5648 GEN_INT (15), temp, 1, OPTAB_DIRECT);
5649 gcc_assert (REG_P (temp));
5650 highest_index_to_load_reg =
5651 expand_binop (Pmode, sub_optab, GEN_INT (15), temp,
5652 highest_index_to_load_reg, 1, OPTAB_DIRECT);
5653 gcc_assert (REG_P (highest_index_to_load_reg));
5654 emit_insn (gen_vllv16qi (str_reg,
5655 convert_to_mode (SImode, highest_index_to_load_reg, 1),
5656 gen_rtx_MEM (BLKmode, str_addr_base_reg)));
5657
5658 into_loop_label = gen_label_rtx ();
5659 s390_emit_jump (into_loop_label, NULL_RTX);
5660 emit_barrier ();
5661 }
5662
5663 emit_label (is_aligned_label);
5664 LABEL_NUSES (is_aligned_label) = INTVAL (alignment) < 16 ? 2 : 1;
5665
5666 /* Reaching this point we are only performing 16 bytes aligned
5667 loads. */
5668 emit_move_insn (highest_index_to_load_reg, GEN_INT (15));
5669
5670 emit_label (loop_start_label);
5671 LABEL_NUSES (loop_start_label) = 1;
5672
5673 /* Load 16 bytes of the string into VR. */
5674 emit_move_insn (str_reg,
5675 gen_rtx_MEM (V16QImode,
5676 gen_rtx_PLUS (Pmode, str_idx_reg,
5677 str_addr_base_reg)));
5678 if (into_loop_label != NULL_RTX)
5679 {
5680 emit_label (into_loop_label);
5681 LABEL_NUSES (into_loop_label) = 1;
5682 }
5683
5684 /* Increment string index by 16 bytes. */
5685 expand_binop (Pmode, add_optab, str_idx_reg, GEN_INT (16),
5686 str_idx_reg, 1, OPTAB_DIRECT);
5687
5688 emit_insn (gen_vec_vfenesv16qi (result_reg, str_reg, str_reg,
5689 GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS)));
5690
5691 add_int_reg_note (s390_emit_ccraw_jump (8, NE, loop_start_label),
5692 REG_BR_PROB, very_likely);
5693 emit_insn (gen_vec_extractv16qi (len, result_reg, GEN_INT (7)));
5694
5695 /* If the string pointer wasn't aligned we have loaded less then 16
5696 bytes and the remaining bytes got filled with zeros (by vll).
5697 Now we have to check whether the resulting index lies within the
5698 bytes actually part of the string. */
5699
5700 cond = s390_emit_compare (GT, convert_to_mode (Pmode, len, 1),
5701 highest_index_to_load_reg);
5702 s390_load_address (highest_index_to_load_reg,
5703 gen_rtx_PLUS (Pmode, highest_index_to_load_reg,
5704 const1_rtx));
5705 if (TARGET_64BIT)
5706 emit_insn (gen_movdicc (str_idx_reg, cond,
5707 highest_index_to_load_reg, str_idx_reg));
5708 else
5709 emit_insn (gen_movsicc (str_idx_reg, cond,
5710 highest_index_to_load_reg, str_idx_reg));
5711
5712 add_int_reg_note (s390_emit_jump (is_aligned_label, cond), REG_BR_PROB,
5713 very_unlikely);
5714
5715 expand_binop (Pmode, add_optab, str_idx_reg,
5716 GEN_INT (-16), str_idx_reg, 1, OPTAB_DIRECT);
5717 /* FIXME: len is already zero extended - so avoid the llgcr emitted
5718 here. */
5719 temp = expand_binop (Pmode, add_optab, str_idx_reg,
5720 convert_to_mode (Pmode, len, 1),
5721 target, 1, OPTAB_DIRECT);
5722 if (temp != target)
5723 emit_move_insn (target, temp);
5724}
3b699fc7 5725
664ff6a0 5726void
5727s390_expand_vec_movstr (rtx result, rtx dst, rtx src)
5728{
5729 int very_unlikely = REG_BR_PROB_BASE / 100 - 1;
5730 rtx temp = gen_reg_rtx (Pmode);
5731 rtx src_addr = XEXP (src, 0);
5732 rtx dst_addr = XEXP (dst, 0);
5733 rtx src_addr_reg = gen_reg_rtx (Pmode);
5734 rtx dst_addr_reg = gen_reg_rtx (Pmode);
5735 rtx offset = gen_reg_rtx (Pmode);
5736 rtx vsrc = gen_reg_rtx (V16QImode);
5737 rtx vpos = gen_reg_rtx (V16QImode);
5738 rtx loadlen = gen_reg_rtx (SImode);
5739 rtx gpos_qi = gen_reg_rtx(QImode);
5740 rtx gpos = gen_reg_rtx (SImode);
5741 rtx done_label = gen_label_rtx ();
5742 rtx loop_label = gen_label_rtx ();
5743 rtx exit_label = gen_label_rtx ();
5744 rtx full_label = gen_label_rtx ();
5745
5746 /* Perform a quick check for string ending on the first up to 16
5747 bytes and exit early if successful. */
5748
5749 emit_insn (gen_vlbb (vsrc, src, GEN_INT (6)));
5750 emit_insn (gen_lcbb (loadlen, src_addr, GEN_INT (6)));
5751 emit_insn (gen_vfenezv16qi (vpos, vsrc, vsrc));
5752 emit_insn (gen_vec_extractv16qi (gpos_qi, vpos, GEN_INT (7)));
5753 emit_move_insn (gpos, gen_rtx_SUBREG (SImode, gpos_qi, 0));
5754 /* gpos is the byte index if a zero was found and 16 otherwise.
5755 So if it is lower than the loaded bytes we have a hit. */
5756 emit_cmp_and_jump_insns (gpos, loadlen, GE, NULL_RTX, SImode, 1,
5757 full_label);
5758 emit_insn (gen_vstlv16qi (vsrc, gpos, dst));
5759
5760 force_expand_binop (Pmode, add_optab, dst_addr, gpos, result,
5761 1, OPTAB_DIRECT);
5762 emit_jump (exit_label);
5763 emit_barrier ();
5764
5765 emit_label (full_label);
5766 LABEL_NUSES (full_label) = 1;
5767
5768 /* Calculate `offset' so that src + offset points to the last byte
5769 before 16 byte alignment. */
5770
5771 /* temp = src_addr & 0xf */
5772 force_expand_binop (Pmode, and_optab, src_addr, GEN_INT (15), temp,
5773 1, OPTAB_DIRECT);
5774
5775 /* offset = 0xf - temp */
5776 emit_move_insn (offset, GEN_INT (15));
5777 force_expand_binop (Pmode, sub_optab, offset, temp, offset,
5778 1, OPTAB_DIRECT);
5779
5780 /* Store `offset' bytes in the dstination string. The quick check
5781 has loaded at least `offset' bytes into vsrc. */
5782
5783 emit_insn (gen_vstlv16qi (vsrc, gen_lowpart (SImode, offset), dst));
5784
5785 /* Advance to the next byte to be loaded. */
5786 force_expand_binop (Pmode, add_optab, offset, const1_rtx, offset,
5787 1, OPTAB_DIRECT);
5788
5789 /* Make sure the addresses are single regs which can be used as a
5790 base. */
5791 emit_move_insn (src_addr_reg, src_addr);
5792 emit_move_insn (dst_addr_reg, dst_addr);
5793
5794 /* MAIN LOOP */
5795
5796 emit_label (loop_label);
5797 LABEL_NUSES (loop_label) = 1;
5798
5799 emit_move_insn (vsrc,
5800 gen_rtx_MEM (V16QImode,
5801 gen_rtx_PLUS (Pmode, src_addr_reg, offset)));
5802
5803 emit_insn (gen_vec_vfenesv16qi (vpos, vsrc, vsrc,
5804 GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS)));
5805 add_int_reg_note (s390_emit_ccraw_jump (8, EQ, done_label),
5806 REG_BR_PROB, very_unlikely);
5807
5808 emit_move_insn (gen_rtx_MEM (V16QImode,
5809 gen_rtx_PLUS (Pmode, dst_addr_reg, offset)),
5810 vsrc);
5811 /* offset += 16 */
5812 force_expand_binop (Pmode, add_optab, offset, GEN_INT (16),
5813 offset, 1, OPTAB_DIRECT);
5814
5815 emit_jump (loop_label);
5816 emit_barrier ();
5817
5818 /* REGULAR EXIT */
5819
5820 /* We are done. Add the offset of the zero character to the dst_addr
5821 pointer to get the result. */
5822
5823 emit_label (done_label);
5824 LABEL_NUSES (done_label) = 1;
5825
5826 force_expand_binop (Pmode, add_optab, dst_addr_reg, offset, dst_addr_reg,
5827 1, OPTAB_DIRECT);
5828
5829 emit_insn (gen_vec_extractv16qi (gpos_qi, vpos, GEN_INT (7)));
5830 emit_move_insn (gpos, gen_rtx_SUBREG (SImode, gpos_qi, 0));
5831
5832 emit_insn (gen_vstlv16qi (vsrc, gpos, gen_rtx_MEM (BLKmode, dst_addr_reg)));
5833
5834 force_expand_binop (Pmode, add_optab, dst_addr_reg, gpos, result,
5835 1, OPTAB_DIRECT);
5836
5837 /* EARLY EXIT */
5838
5839 emit_label (exit_label);
5840 LABEL_NUSES (exit_label) = 1;
5841}
5842
5843
3b699fc7 5844/* Expand conditional increment or decrement using alc/slb instructions.
5845 Should generate code setting DST to either SRC or SRC + INCREMENT,
5846 depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
eeba5f25 5847 Returns true if successful, false otherwise.
5848
5849 That makes it possible to implement some if-constructs without jumps e.g.:
5850 (borrow = CC0 | CC1 and carry = CC2 | CC3)
5851 unsigned int a, b, c;
5852 if (a < b) c++; -> CCU b > a -> CC2; c += carry;
5853 if (a < b) c--; -> CCL3 a - b -> borrow; c -= borrow;
5854 if (a <= b) c++; -> CCL3 b - a -> borrow; c += carry;
5855 if (a <= b) c--; -> CCU a <= b -> borrow; c -= borrow;
5856
5857 Checks for EQ and NE with a nonzero value need an additional xor e.g.:
5858 if (a == b) c++; -> CCL3 a ^= b; 0 - a -> borrow; c += carry;
5859 if (a == b) c--; -> CCU a ^= b; a <= 0 -> CC0 | CC1; c -= borrow;
5860 if (a != b) c++; -> CCU a ^= b; a > 0 -> CC2; c += carry;
5861 if (a != b) c--; -> CCL3 a ^= b; 0 - a -> borrow; c -= borrow; */
3b699fc7 5862
5863bool
5864s390_expand_addcc (enum rtx_code cmp_code, rtx cmp_op0, rtx cmp_op1,
5865 rtx dst, rtx src, rtx increment)
5866{
3754d046 5867 machine_mode cmp_mode;
5868 machine_mode cc_mode;
3b699fc7 5869 rtx op_res;
5870 rtx insn;
5871 rtvec p;
32eda510 5872 int ret;
3b699fc7 5873
5874 if ((GET_MODE (cmp_op0) == SImode || GET_MODE (cmp_op0) == VOIDmode)
5875 && (GET_MODE (cmp_op1) == SImode || GET_MODE (cmp_op1) == VOIDmode))
5876 cmp_mode = SImode;
5877 else if ((GET_MODE (cmp_op0) == DImode || GET_MODE (cmp_op0) == VOIDmode)
5878 && (GET_MODE (cmp_op1) == DImode || GET_MODE (cmp_op1) == VOIDmode))
5879 cmp_mode = DImode;
5880 else
5881 return false;
5882
5883 /* Try ADD LOGICAL WITH CARRY. */
5884 if (increment == const1_rtx)
5885 {
5886 /* Determine CC mode to use. */
5887 if (cmp_code == EQ || cmp_code == NE)
5888 {
5889 if (cmp_op1 != const0_rtx)
5890 {
5891 cmp_op0 = expand_simple_binop (cmp_mode, XOR, cmp_op0, cmp_op1,
5892 NULL_RTX, 0, OPTAB_WIDEN);
5893 cmp_op1 = const0_rtx;
5894 }
5895
5896 cmp_code = cmp_code == EQ ? LEU : GTU;
5897 }
5898
5899 if (cmp_code == LTU || cmp_code == LEU)
5900 {
5901 rtx tem = cmp_op0;
5902 cmp_op0 = cmp_op1;
5903 cmp_op1 = tem;
5904 cmp_code = swap_condition (cmp_code);
5905 }
5906
5907 switch (cmp_code)
5908 {
5909 case GTU:
5910 cc_mode = CCUmode;
5911 break;
5912
5913 case GEU:
5914 cc_mode = CCL3mode;
5915 break;
5916
5917 default:
5918 return false;
5919 }
5920
5921 /* Emit comparison instruction pattern. */
5922 if (!register_operand (cmp_op0, cmp_mode))
5923 cmp_op0 = force_reg (cmp_mode, cmp_op0);
5924
d1f9b275 5925 insn = gen_rtx_SET (gen_rtx_REG (cc_mode, CC_REGNUM),
3b699fc7 5926 gen_rtx_COMPARE (cc_mode, cmp_op0, cmp_op1));
5927 /* We use insn_invalid_p here to add clobbers if required. */
dae9d0e7 5928 ret = insn_invalid_p (emit_insn (insn), false);
32eda510 5929 gcc_assert (!ret);
3b699fc7 5930
5931 /* Emit ALC instruction pattern. */
5932 op_res = gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
5933 gen_rtx_REG (cc_mode, CC_REGNUM),
5934 const0_rtx);
5935
5936 if (src != const0_rtx)
5937 {
5938 if (!register_operand (src, GET_MODE (dst)))
5939 src = force_reg (GET_MODE (dst), src);
5940
6f4afa7e 5941 op_res = gen_rtx_PLUS (GET_MODE (dst), op_res, src);
5942 op_res = gen_rtx_PLUS (GET_MODE (dst), op_res, const0_rtx);
3b699fc7 5943 }
5944
5945 p = rtvec_alloc (2);
ffead1ca 5946 RTVEC_ELT (p, 0) =
d1f9b275 5947 gen_rtx_SET (dst, op_res);
ffead1ca 5948 RTVEC_ELT (p, 1) =
3b699fc7 5949 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
5950 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
5951
5952 return true;
5953 }
5954
5955 /* Try SUBTRACT LOGICAL WITH BORROW. */
5956 if (increment == constm1_rtx)
5957 {
5958 /* Determine CC mode to use. */
5959 if (cmp_code == EQ || cmp_code == NE)
5960 {
5961 if (cmp_op1 != const0_rtx)
5962 {
5963 cmp_op0 = expand_simple_binop (cmp_mode, XOR, cmp_op0, cmp_op1,
5964 NULL_RTX, 0, OPTAB_WIDEN);
5965 cmp_op1 = const0_rtx;
5966 }
5967
5968 cmp_code = cmp_code == EQ ? LEU : GTU;
5969 }
5970
5971 if (cmp_code == GTU || cmp_code == GEU)
5972 {
5973 rtx tem = cmp_op0;
5974 cmp_op0 = cmp_op1;
5975 cmp_op1 = tem;
5976 cmp_code = swap_condition (cmp_code);
5977 }
5978
5979 switch (cmp_code)
5980 {
5981 case LEU:
5982 cc_mode = CCUmode;
5983 break;
5984
5985 case LTU:
5986 cc_mode = CCL3mode;
5987 break;
5988
5989 default:
5990 return false;
5991 }
5992
5993 /* Emit comparison instruction pattern. */
5994 if (!register_operand (cmp_op0, cmp_mode))
5995 cmp_op0 = force_reg (cmp_mode, cmp_op0);
5996
d1f9b275 5997 insn = gen_rtx_SET (gen_rtx_REG (cc_mode, CC_REGNUM),
3b699fc7 5998 gen_rtx_COMPARE (cc_mode, cmp_op0, cmp_op1));
5999 /* We use insn_invalid_p here to add clobbers if required. */
dae9d0e7 6000 ret = insn_invalid_p (emit_insn (insn), false);
32eda510 6001 gcc_assert (!ret);
3b699fc7 6002
6003 /* Emit SLB instruction pattern. */
6004 if (!register_operand (src, GET_MODE (dst)))
6005 src = force_reg (GET_MODE (dst), src);
6006
ffead1ca 6007 op_res = gen_rtx_MINUS (GET_MODE (dst),
6008 gen_rtx_MINUS (GET_MODE (dst), src, const0_rtx),
6009 gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
6010 gen_rtx_REG (cc_mode, CC_REGNUM),
3b699fc7 6011 const0_rtx));
6012 p = rtvec_alloc (2);
ffead1ca 6013 RTVEC_ELT (p, 0) =
d1f9b275 6014 gen_rtx_SET (dst, op_res);
ffead1ca 6015 RTVEC_ELT (p, 1) =
3b699fc7 6016 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
6017 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
6018
6019 return true;
6020 }
6021
6022 return false;
6023}
6024
e68d6a13 6025/* Expand code for the insv template. Return true if successful. */
0349cc73 6026
e68d6a13 6027bool
0349cc73 6028s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src)
6029{
6030 int bitsize = INTVAL (op1);
6031 int bitpos = INTVAL (op2);
3754d046 6032 machine_mode mode = GET_MODE (dest);
6033 machine_mode smode;
8c753480 6034 int smode_bsize, mode_bsize;
6035 rtx op, clobber;
0349cc73 6036
0bc377b9 6037 if (bitsize + bitpos > GET_MODE_BITSIZE (mode))
31efd1ec 6038 return false;
6039
8c753480 6040 /* Generate INSERT IMMEDIATE (IILL et al). */
6041 /* (set (ze (reg)) (const_int)). */
6042 if (TARGET_ZARCH
6043 && register_operand (dest, word_mode)
6044 && (bitpos % 16) == 0
6045 && (bitsize % 16) == 0
6046 && const_int_operand (src, VOIDmode))
e68d6a13 6047 {
8c753480 6048 HOST_WIDE_INT val = INTVAL (src);
6049 int regpos = bitpos + bitsize;
e68d6a13 6050
8c753480 6051 while (regpos > bitpos)
6052 {
3754d046 6053 machine_mode putmode;
8c753480 6054 int putsize;
6055
6056 if (TARGET_EXTIMM && (regpos % 32 == 0) && (regpos >= bitpos + 32))
6057 putmode = SImode;
6058 else
6059 putmode = HImode;
e68d6a13 6060
8c753480 6061 putsize = GET_MODE_BITSIZE (putmode);
6062 regpos -= putsize;
6063 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest,
6064 GEN_INT (putsize),
6065 GEN_INT (regpos)),
6066 gen_int_mode (val, putmode));
6067 val >>= putsize;
6068 }
6069 gcc_assert (regpos == bitpos);
e68d6a13 6070 return true;
6071 }
6072
8c753480 6073 smode = smallest_mode_for_size (bitsize, MODE_INT);
6074 smode_bsize = GET_MODE_BITSIZE (smode);
6075 mode_bsize = GET_MODE_BITSIZE (mode);
0349cc73 6076
8c753480 6077 /* Generate STORE CHARACTERS UNDER MASK (STCM et al). */
0349cc73 6078 if (bitpos == 0
8c753480 6079 && (bitsize % BITS_PER_UNIT) == 0
6080 && MEM_P (dest)
0349cc73 6081 && (register_operand (src, word_mode)
6082 || const_int_operand (src, VOIDmode)))
6083 {
6084 /* Emit standard pattern if possible. */
8c753480 6085 if (smode_bsize == bitsize)
6086 {
6087 emit_move_insn (adjust_address (dest, smode, 0),
6088 gen_lowpart (smode, src));
6089 return true;
6090 }
0349cc73 6091
6092 /* (set (ze (mem)) (const_int)). */
6093 else if (const_int_operand (src, VOIDmode))
6094 {
6095 int size = bitsize / BITS_PER_UNIT;
8c753480 6096 rtx src_mem = adjust_address (force_const_mem (word_mode, src),
6097 BLKmode,
6098 UNITS_PER_WORD - size);
0349cc73 6099
6100 dest = adjust_address (dest, BLKmode, 0);
5b2a69fa 6101 set_mem_size (dest, size);
0349cc73 6102 s390_expand_movmem (dest, src_mem, GEN_INT (size));
8c753480 6103 return true;
0349cc73 6104 }
ffead1ca 6105
0349cc73 6106 /* (set (ze (mem)) (reg)). */
6107 else if (register_operand (src, word_mode))
6108 {
8c753480 6109 if (bitsize <= 32)
0349cc73 6110 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest, op1,
6111 const0_rtx), src);
6112 else
6113 {
6114 /* Emit st,stcmh sequence. */
8c753480 6115 int stcmh_width = bitsize - 32;
0349cc73 6116 int size = stcmh_width / BITS_PER_UNIT;
6117
ffead1ca 6118 emit_move_insn (adjust_address (dest, SImode, size),
0349cc73 6119 gen_lowpart (SImode, src));
5b2a69fa 6120 set_mem_size (dest, size);
8c753480 6121 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest,
6122 GEN_INT (stcmh_width),
6123 const0_rtx),
6124 gen_rtx_LSHIFTRT (word_mode, src, GEN_INT (32)));
0349cc73 6125 }
8c753480 6126 return true;
0349cc73 6127 }
8c753480 6128 }
0349cc73 6129
8c753480 6130 /* Generate INSERT CHARACTERS UNDER MASK (IC, ICM et al). */
6131 if ((bitpos % BITS_PER_UNIT) == 0
6132 && (bitsize % BITS_PER_UNIT) == 0
6133 && (bitpos & 32) == ((bitpos + bitsize - 1) & 32)
6134 && MEM_P (src)
6135 && (mode == DImode || mode == SImode)
6136 && register_operand (dest, mode))
6137 {
6138 /* Emit a strict_low_part pattern if possible. */
6139 if (smode_bsize == bitsize && bitpos == mode_bsize - smode_bsize)
6140 {
6141 op = gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (smode, dest));
d1f9b275 6142 op = gen_rtx_SET (op, gen_lowpart (smode, src));
8c753480 6143 clobber = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
6144 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clobber)));
6145 return true;
6146 }
6147
6148 /* ??? There are more powerful versions of ICM that are not
6149 completely represented in the md file. */
0349cc73 6150 }
6151
8c753480 6152 /* For z10, generate ROTATE THEN INSERT SELECTED BITS (RISBG et al). */
6153 if (TARGET_Z10 && (mode == DImode || mode == SImode))
0349cc73 6154 {
3754d046 6155 machine_mode mode_s = GET_MODE (src);
0349cc73 6156
678c417b 6157 if (CONSTANT_P (src))
0349cc73 6158 {
02a8efd2 6159 /* For constant zero values the representation with AND
6160 appears to be folded in more situations than the (set
6161 (zero_extract) ...).
6162 We only do this when the start and end of the bitfield
6163 remain in the same SImode chunk. That way nihf or nilf
6164 can be used.
6165 The AND patterns might still generate a risbg for this. */
6166 if (src == const0_rtx && bitpos / 32 == (bitpos + bitsize - 1) / 32)
6167 return false;
6168 else
6169 src = force_reg (mode, src);
8c753480 6170 }
6171 else if (mode_s != mode)
6172 {
6173 gcc_assert (GET_MODE_BITSIZE (mode_s) >= bitsize);
6174 src = force_reg (mode_s, src);
6175 src = gen_lowpart (mode, src);
6176 }
0349cc73 6177
99274008 6178 op = gen_rtx_ZERO_EXTRACT (mode, dest, op1, op2),
d1f9b275 6179 op = gen_rtx_SET (op, src);
81769881 6180
6181 if (!TARGET_ZEC12)
6182 {
6183 clobber = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
6184 op = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clobber));
6185 }
6186 emit_insn (op);
0349cc73 6187
0349cc73 6188 return true;
6189 }
6190
6191 return false;
6192}
3b699fc7 6193
7cc66daf 6194/* A subroutine of s390_expand_cs_hqi and s390_expand_atomic which returns a
6195 register that holds VAL of mode MODE shifted by COUNT bits. */
182f815e 6196
6197static inline rtx
3754d046 6198s390_expand_mask_and_shift (rtx val, machine_mode mode, rtx count)
182f815e 6199{
6200 val = expand_simple_binop (SImode, AND, val, GEN_INT (GET_MODE_MASK (mode)),
6201 NULL_RTX, 1, OPTAB_DIRECT);
ffead1ca 6202 return expand_simple_binop (SImode, ASHIFT, val, count,
182f815e 6203 NULL_RTX, 1, OPTAB_DIRECT);
6204}
6205
76a4c804 6206/* Generate a vector comparison COND of CMP_OP1 and CMP_OP2 and store
6207 the result in TARGET. */
6208
6209void
6210s390_expand_vec_compare (rtx target, enum rtx_code cond,
6211 rtx cmp_op1, rtx cmp_op2)
6212{
6213 machine_mode mode = GET_MODE (target);
6214 bool neg_p = false, swap_p = false;
6215 rtx tmp;
6216
80912819 6217 if (GET_MODE_CLASS (GET_MODE (cmp_op1)) == MODE_VECTOR_FLOAT)
76a4c804 6218 {
6219 switch (cond)
6220 {
6221 /* NE a != b -> !(a == b) */
6222 case NE: cond = EQ; neg_p = true; break;
6223 /* UNGT a u> b -> !(b >= a) */
6224 case UNGT: cond = GE; neg_p = true; swap_p = true; break;
6225 /* UNGE a u>= b -> !(b > a) */
6226 case UNGE: cond = GT; neg_p = true; swap_p = true; break;
6227 /* LE: a <= b -> b >= a */
6228 case LE: cond = GE; swap_p = true; break;
6229 /* UNLE: a u<= b -> !(a > b) */
6230 case UNLE: cond = GT; neg_p = true; break;
6231 /* LT: a < b -> b > a */
6232 case LT: cond = GT; swap_p = true; break;
6233 /* UNLT: a u< b -> !(a >= b) */
6234 case UNLT: cond = GE; neg_p = true; break;
6235 case UNEQ:
6236 emit_insn (gen_vec_cmpuneqv2df (target, cmp_op1, cmp_op2));
6237 return;
6238 case LTGT:
6239 emit_insn (gen_vec_cmpltgtv2df (target, cmp_op1, cmp_op2));
6240 return;
6241 case ORDERED:
6242 emit_insn (gen_vec_orderedv2df (target, cmp_op1, cmp_op2));
6243 return;
6244 case UNORDERED:
6245 emit_insn (gen_vec_unorderedv2df (target, cmp_op1, cmp_op2));
6246 return;
6247 default: break;
6248 }
6249 }
6250 else
6251 {
6252 switch (cond)
6253 {
6254 /* NE: a != b -> !(a == b) */
6255 case NE: cond = EQ; neg_p = true; break;
6256 /* GE: a >= b -> !(b > a) */
6257 case GE: cond = GT; neg_p = true; swap_p = true; break;
6258 /* GEU: a >= b -> !(b > a) */
6259 case GEU: cond = GTU; neg_p = true; swap_p = true; break;
6260 /* LE: a <= b -> !(a > b) */
6261 case LE: cond = GT; neg_p = true; break;
6262 /* LEU: a <= b -> !(a > b) */
6263 case LEU: cond = GTU; neg_p = true; break;
6264 /* LT: a < b -> b > a */
6265 case LT: cond = GT; swap_p = true; break;
6266 /* LTU: a < b -> b > a */
6267 case LTU: cond = GTU; swap_p = true; break;
6268 default: break;
6269 }
6270 }
6271
6272 if (swap_p)
6273 {
6274 tmp = cmp_op1; cmp_op1 = cmp_op2; cmp_op2 = tmp;
6275 }
6276
6277 emit_insn (gen_rtx_SET (target, gen_rtx_fmt_ee (cond,
6278 mode,
6279 cmp_op1, cmp_op2)));
6280 if (neg_p)
6281 emit_insn (gen_rtx_SET (target, gen_rtx_NOT (mode, target)));
6282}
6283
07f32359 6284/* Expand the comparison CODE of CMP1 and CMP2 and copy 1 or 0 into
6285 TARGET if either all (ALL_P is true) or any (ALL_P is false) of the
abc57c35 6286 elements in CMP1 and CMP2 fulfill the comparison.
6287 This function is only used to emit patterns for the vx builtins and
6288 therefore only handles comparison codes required by the
6289 builtins. */
07f32359 6290void
6291s390_expand_vec_compare_cc (rtx target, enum rtx_code code,
6292 rtx cmp1, rtx cmp2, bool all_p)
6293{
abc57c35 6294 machine_mode cc_producer_mode, cc_consumer_mode, scratch_mode;
07f32359 6295 rtx tmp_reg = gen_reg_rtx (SImode);
6296 bool swap_p = false;
6297
6298 if (GET_MODE_CLASS (GET_MODE (cmp1)) == MODE_VECTOR_INT)
6299 {
6300 switch (code)
6301 {
abc57c35 6302 case EQ:
6303 case NE:
6304 cc_producer_mode = CCVEQmode;
6305 break;
6306 case GE:
6307 case LT:
6308 code = swap_condition (code);
6309 swap_p = true;
6310 /* fallthrough */
6311 case GT:
6312 case LE:
6313 cc_producer_mode = CCVIHmode;
6314 break;
6315 case GEU:
6316 case LTU:
6317 code = swap_condition (code);
6318 swap_p = true;
6319 /* fallthrough */
6320 case GTU:
6321 case LEU:
6322 cc_producer_mode = CCVIHUmode;
6323 break;
6324 default:
6325 gcc_unreachable ();
07f32359 6326 }
abc57c35 6327
07f32359 6328 scratch_mode = GET_MODE (cmp1);
abc57c35 6329 /* These codes represent inverted CC interpretations. Inverting
6330 an ALL CC mode results in an ANY CC mode and the other way
6331 around. Invert the all_p flag here to compensate for
6332 that. */
6333 if (code == NE || code == LE || code == LEU)
6334 all_p = !all_p;
6335
6336 cc_consumer_mode = all_p ? CCVIALLmode : CCVIANYmode;
07f32359 6337 }
abc57c35 6338 else if (GET_MODE_CLASS (GET_MODE (cmp1)) == MODE_VECTOR_FLOAT)
07f32359 6339 {
abc57c35 6340 bool inv_p = false;
6341
07f32359 6342 switch (code)
6343 {
abc57c35 6344 case EQ: cc_producer_mode = CCVEQmode; break;
6345 case NE: cc_producer_mode = CCVEQmode; inv_p = true; break;
6346 case GT: cc_producer_mode = CCVFHmode; break;
6347 case GE: cc_producer_mode = CCVFHEmode; break;
6348 case UNLE: cc_producer_mode = CCVFHmode; inv_p = true; break;
6349 case UNLT: cc_producer_mode = CCVFHEmode; inv_p = true; break;
6350 case LT: cc_producer_mode = CCVFHmode; code = GT; swap_p = true; break;
6351 case LE: cc_producer_mode = CCVFHEmode; code = GE; swap_p = true; break;
07f32359 6352 default: gcc_unreachable ();
6353 }
abc57c35 6354 scratch_mode = mode_for_vector (
6355 int_mode_for_mode (GET_MODE_INNER (GET_MODE (cmp1))),
6356 GET_MODE_NUNITS (GET_MODE (cmp1)));
6357 gcc_assert (scratch_mode != BLKmode);
6358
6359 if (inv_p)
6360 all_p = !all_p;
6361
6362 cc_consumer_mode = all_p ? CCVFALLmode : CCVFANYmode;
07f32359 6363 }
6364 else
6365 gcc_unreachable ();
6366
07f32359 6367 if (swap_p)
6368 {
6369 rtx tmp = cmp2;
6370 cmp2 = cmp1;
6371 cmp1 = tmp;
6372 }
6373
6374 emit_insn (gen_rtx_PARALLEL (VOIDmode,
6375 gen_rtvec (2, gen_rtx_SET (
abc57c35 6376 gen_rtx_REG (cc_producer_mode, CC_REGNUM),
6377 gen_rtx_COMPARE (cc_producer_mode, cmp1, cmp2)),
07f32359 6378 gen_rtx_CLOBBER (VOIDmode,
6379 gen_rtx_SCRATCH (scratch_mode)))));
6380 emit_move_insn (target, const0_rtx);
6381 emit_move_insn (tmp_reg, const1_rtx);
6382
6383 emit_move_insn (target,
6384 gen_rtx_IF_THEN_ELSE (SImode,
abc57c35 6385 gen_rtx_fmt_ee (code, VOIDmode,
6386 gen_rtx_REG (cc_consumer_mode, CC_REGNUM),
07f32359 6387 const0_rtx),
abc57c35 6388 tmp_reg, target));
07f32359 6389}
6390
e17ed6ec 6391/* Invert the comparison CODE applied to a CC mode. This is only safe
6392 if we know whether there result was created by a floating point
6393 compare or not. For the CCV modes this is encoded as part of the
6394 mode. */
6395enum rtx_code
6396s390_reverse_condition (machine_mode mode, enum rtx_code code)
6397{
6398 /* Reversal of FP compares takes care -- an ordered compare
6399 becomes an unordered compare and vice versa. */
6400 if (mode == CCVFALLmode || mode == CCVFANYmode)
6401 return reverse_condition_maybe_unordered (code);
6402 else if (mode == CCVIALLmode || mode == CCVIANYmode)
6403 return reverse_condition (code);
6404 else
6405 gcc_unreachable ();
6406}
6407
76a4c804 6408/* Generate a vector comparison expression loading either elements of
6409 THEN or ELS into TARGET depending on the comparison COND of CMP_OP1
6410 and CMP_OP2. */
6411
6412void
6413s390_expand_vcond (rtx target, rtx then, rtx els,
6414 enum rtx_code cond, rtx cmp_op1, rtx cmp_op2)
6415{
6416 rtx tmp;
6417 machine_mode result_mode;
6418 rtx result_target;
6419
651e0407 6420 machine_mode target_mode = GET_MODE (target);
6421 machine_mode cmp_mode = GET_MODE (cmp_op1);
6422 rtx op = (cond == LT) ? els : then;
6423
6424 /* Try to optimize x < 0 ? -1 : 0 into (signed) x >> 31
6425 and x < 0 ? 1 : 0 into (unsigned) x >> 31. Likewise
6426 for short and byte (x >> 15 and x >> 7 respectively). */
6427 if ((cond == LT || cond == GE)
6428 && target_mode == cmp_mode
6429 && cmp_op2 == CONST0_RTX (cmp_mode)
6430 && op == CONST0_RTX (target_mode)
6431 && s390_vector_mode_supported_p (target_mode)
6432 && GET_MODE_CLASS (target_mode) == MODE_VECTOR_INT)
6433 {
6434 rtx negop = (cond == LT) ? then : els;
6435
6436 int shift = GET_MODE_BITSIZE (GET_MODE_INNER (target_mode)) - 1;
6437
6438 /* if x < 0 ? 1 : 0 or if x >= 0 ? 0 : 1 */
6439 if (negop == CONST1_RTX (target_mode))
6440 {
6441 rtx res = expand_simple_binop (cmp_mode, LSHIFTRT, cmp_op1,
6442 GEN_INT (shift), target,
6443 1, OPTAB_DIRECT);
6444 if (res != target)
6445 emit_move_insn (target, res);
6446 return;
6447 }
6448
6449 /* if x < 0 ? -1 : 0 or if x >= 0 ? 0 : -1 */
a991c8aa 6450 else if (all_ones_operand (negop, target_mode))
651e0407 6451 {
6452 rtx res = expand_simple_binop (cmp_mode, ASHIFTRT, cmp_op1,
6453 GEN_INT (shift), target,
6454 0, OPTAB_DIRECT);
6455 if (res != target)
6456 emit_move_insn (target, res);
6457 return;
6458 }
6459 }
6460
76a4c804 6461 /* We always use an integral type vector to hold the comparison
6462 result. */
80912819 6463 result_mode = mode_for_vector (int_mode_for_mode (GET_MODE_INNER (cmp_mode)),
6464 GET_MODE_NUNITS (cmp_mode));
76a4c804 6465 result_target = gen_reg_rtx (result_mode);
6466
651e0407 6467 /* We allow vector immediates as comparison operands that
6468 can be handled by the optimization above but not by the
6469 following code. Hence, force them into registers here. */
76a4c804 6470 if (!REG_P (cmp_op1))
b088ff4b 6471 cmp_op1 = force_reg (GET_MODE (cmp_op1), cmp_op1);
76a4c804 6472
6473 if (!REG_P (cmp_op2))
b088ff4b 6474 cmp_op2 = force_reg (GET_MODE (cmp_op2), cmp_op2);
76a4c804 6475
6476 s390_expand_vec_compare (result_target, cond,
6477 cmp_op1, cmp_op2);
6478
6479 /* If the results are supposed to be either -1 or 0 we are done
6480 since this is what our compare instructions generate anyway. */
a991c8aa 6481 if (all_ones_operand (then, GET_MODE (then))
76a4c804 6482 && const0_operand (els, GET_MODE (els)))
6483 {
651e0407 6484 emit_move_insn (target, gen_rtx_SUBREG (target_mode,
76a4c804 6485 result_target, 0));
6486 return;
6487 }
6488
6489 /* Otherwise we will do a vsel afterwards. */
6490 /* This gets triggered e.g.
6491 with gcc.c-torture/compile/pr53410-1.c */
6492 if (!REG_P (then))
651e0407 6493 then = force_reg (target_mode, then);
76a4c804 6494
6495 if (!REG_P (els))
651e0407 6496 els = force_reg (target_mode, els);
76a4c804 6497
6498 tmp = gen_rtx_fmt_ee (EQ, VOIDmode,
6499 result_target,
6500 CONST0_RTX (result_mode));
6501
6502 /* We compared the result against zero above so we have to swap then
6503 and els here. */
651e0407 6504 tmp = gen_rtx_IF_THEN_ELSE (target_mode, tmp, els, then);
76a4c804 6505
651e0407 6506 gcc_assert (target_mode == GET_MODE (then));
76a4c804 6507 emit_insn (gen_rtx_SET (target, tmp));
6508}
6509
6510/* Emit the RTX necessary to initialize the vector TARGET with values
6511 in VALS. */
6512void
6513s390_expand_vec_init (rtx target, rtx vals)
6514{
6515 machine_mode mode = GET_MODE (target);
6516 machine_mode inner_mode = GET_MODE_INNER (mode);
6517 int n_elts = GET_MODE_NUNITS (mode);
6518 bool all_same = true, all_regs = true, all_const_int = true;
6519 rtx x;
6520 int i;
6521
6522 for (i = 0; i < n_elts; ++i)
6523 {
6524 x = XVECEXP (vals, 0, i);
6525
6526 if (!CONST_INT_P (x))
6527 all_const_int = false;
6528
6529 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
6530 all_same = false;
6531
6532 if (!REG_P (x))
6533 all_regs = false;
6534 }
6535
6536 /* Use vector gen mask or vector gen byte mask if possible. */
6537 if (all_same && all_const_int
6538 && (XVECEXP (vals, 0, 0) == const0_rtx
6539 || s390_contiguous_bitmask_vector_p (XVECEXP (vals, 0, 0),
6540 NULL, NULL)
6541 || s390_bytemask_vector_p (XVECEXP (vals, 0, 0), NULL)))
6542 {
6543 emit_insn (gen_rtx_SET (target,
6544 gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0))));
6545 return;
6546 }
6547
6548 if (all_same)
6549 {
6550 emit_insn (gen_rtx_SET (target,
6551 gen_rtx_VEC_DUPLICATE (mode,
6552 XVECEXP (vals, 0, 0))));
6553 return;
6554 }
6555
f413810a 6556 if (all_regs
6557 && REG_P (target)
6558 && n_elts == 2
6559 && GET_MODE_SIZE (inner_mode) == 8)
76a4c804 6560 {
6561 /* Use vector load pair. */
6562 emit_insn (gen_rtx_SET (target,
6563 gen_rtx_VEC_CONCAT (mode,
6564 XVECEXP (vals, 0, 0),
6565 XVECEXP (vals, 0, 1))));
6566 return;
6567 }
bd97b7d0 6568
6569 /* Use vector load logical element and zero. */
6570 if (TARGET_VXE && (mode == V4SImode || mode == V4SFmode))
6571 {
6572 bool found = true;
6573
6574 x = XVECEXP (vals, 0, 0);
6575 if (memory_operand (x, inner_mode))
6576 {
6577 for (i = 1; i < n_elts; ++i)
6578 found = found && XVECEXP (vals, 0, i) == const0_rtx;
6579
6580 if (found)
6581 {
6582 machine_mode half_mode = (inner_mode == SFmode
6583 ? V2SFmode : V2SImode);
6584 emit_insn (gen_rtx_SET (target,
6585 gen_rtx_VEC_CONCAT (mode,
6586 gen_rtx_VEC_CONCAT (half_mode,
6587 x,
6588 const0_rtx),
6589 gen_rtx_VEC_CONCAT (half_mode,
6590 const0_rtx,
6591 const0_rtx))));
6592 return;
6593 }
6594 }
6595 }
76a4c804 6596
6597 /* We are about to set the vector elements one by one. Zero out the
6598 full register first in order to help the data flow framework to
6599 detect it as full VR set. */
6600 emit_insn (gen_rtx_SET (target, CONST0_RTX (mode)));
6601
6602 /* Unfortunately the vec_init expander is not allowed to fail. So
6603 we have to implement the fallback ourselves. */
6604 for (i = 0; i < n_elts; i++)
4ba2579e 6605 {
6606 rtx elem = XVECEXP (vals, 0, i);
6607 if (!general_operand (elem, GET_MODE (elem)))
6608 elem = force_reg (inner_mode, elem);
6609
6610 emit_insn (gen_rtx_SET (target,
6611 gen_rtx_UNSPEC (mode,
6612 gen_rtvec (3, elem,
6613 GEN_INT (i), target),
6614 UNSPEC_VEC_SET)));
6615 }
76a4c804 6616}
6617
182f815e 6618/* Structure to hold the initial parameters for a compare_and_swap operation
ffead1ca 6619 in HImode and QImode. */
182f815e 6620
6621struct alignment_context
6622{
ffead1ca 6623 rtx memsi; /* SI aligned memory location. */
182f815e 6624 rtx shift; /* Bit offset with regard to lsb. */
6625 rtx modemask; /* Mask of the HQImode shifted by SHIFT bits. */
6626 rtx modemaski; /* ~modemask */
191ec5a2 6627 bool aligned; /* True if memory is aligned, false else. */
182f815e 6628};
6629
7cc66daf 6630/* A subroutine of s390_expand_cs_hqi and s390_expand_atomic to initialize
6631 structure AC for transparent simplifying, if the memory alignment is known
6632 to be at least 32bit. MEM is the memory location for the actual operation
6633 and MODE its mode. */
182f815e 6634
6635static void
6636init_alignment_context (struct alignment_context *ac, rtx mem,
3754d046 6637 machine_mode mode)
182f815e 6638{
6639 ac->shift = GEN_INT (GET_MODE_SIZE (SImode) - GET_MODE_SIZE (mode));
6640 ac->aligned = (MEM_ALIGN (mem) >= GET_MODE_BITSIZE (SImode));
6641
6642 if (ac->aligned)
6643 ac->memsi = adjust_address (mem, SImode, 0); /* Memory is aligned. */
6644 else
6645 {
6646 /* Alignment is unknown. */
6647 rtx byteoffset, addr, align;
6648
6649 /* Force the address into a register. */
6650 addr = force_reg (Pmode, XEXP (mem, 0));
6651
6652 /* Align it to SImode. */
6653 align = expand_simple_binop (Pmode, AND, addr,
6654 GEN_INT (-GET_MODE_SIZE (SImode)),
6655 NULL_RTX, 1, OPTAB_DIRECT);
6656 /* Generate MEM. */
6657 ac->memsi = gen_rtx_MEM (SImode, align);
6658 MEM_VOLATILE_P (ac->memsi) = MEM_VOLATILE_P (mem);
bd1da572 6659 set_mem_alias_set (ac->memsi, ALIAS_SET_MEMORY_BARRIER);
182f815e 6660 set_mem_align (ac->memsi, GET_MODE_BITSIZE (SImode));
6661
6662 /* Calculate shiftcount. */
6663 byteoffset = expand_simple_binop (Pmode, AND, addr,
6664 GEN_INT (GET_MODE_SIZE (SImode) - 1),
6665 NULL_RTX, 1, OPTAB_DIRECT);
6666 /* As we already have some offset, evaluate the remaining distance. */
6667 ac->shift = expand_simple_binop (SImode, MINUS, ac->shift, byteoffset,
6668 NULL_RTX, 1, OPTAB_DIRECT);
182f815e 6669 }
8c753480 6670
182f815e 6671 /* Shift is the byte count, but we need the bitcount. */
8c753480 6672 ac->shift = expand_simple_binop (SImode, ASHIFT, ac->shift, GEN_INT (3),
6673 NULL_RTX, 1, OPTAB_DIRECT);
6674
182f815e 6675 /* Calculate masks. */
ffead1ca 6676 ac->modemask = expand_simple_binop (SImode, ASHIFT,
8c753480 6677 GEN_INT (GET_MODE_MASK (mode)),
6678 ac->shift, NULL_RTX, 1, OPTAB_DIRECT);
6679 ac->modemaski = expand_simple_unop (SImode, NOT, ac->modemask,
6680 NULL_RTX, 1);
6681}
6682
6683/* A subroutine of s390_expand_cs_hqi. Insert INS into VAL. If possible,
6684 use a single insv insn into SEQ2. Otherwise, put prep insns in SEQ1 and
6685 perform the merge in SEQ2. */
6686
6687static rtx
6688s390_two_part_insv (struct alignment_context *ac, rtx *seq1, rtx *seq2,
3754d046 6689 machine_mode mode, rtx val, rtx ins)
8c753480 6690{
6691 rtx tmp;
6692
6693 if (ac->aligned)
6694 {
6695 start_sequence ();
6696 tmp = copy_to_mode_reg (SImode, val);
6697 if (s390_expand_insv (tmp, GEN_INT (GET_MODE_BITSIZE (mode)),
6698 const0_rtx, ins))
6699 {
6700 *seq1 = NULL;
6701 *seq2 = get_insns ();
6702 end_sequence ();
6703 return tmp;
6704 }
6705 end_sequence ();
6706 }
6707
6708 /* Failed to use insv. Generate a two part shift and mask. */
6709 start_sequence ();
6710 tmp = s390_expand_mask_and_shift (ins, mode, ac->shift);
6711 *seq1 = get_insns ();
6712 end_sequence ();
6713
6714 start_sequence ();
6715 tmp = expand_simple_binop (SImode, IOR, tmp, val, NULL_RTX, 1, OPTAB_DIRECT);
6716 *seq2 = get_insns ();
6717 end_sequence ();
6718
6719 return tmp;
182f815e 6720}
6721
6722/* Expand an atomic compare and swap operation for HImode and QImode. MEM is
8c753480 6723 the memory location, CMP the old value to compare MEM with and NEW_RTX the
6724 value to set if CMP == MEM. */
182f815e 6725
6726void
3754d046 6727s390_expand_cs_hqi (machine_mode mode, rtx btarget, rtx vtarget, rtx mem,
8c753480 6728 rtx cmp, rtx new_rtx, bool is_weak)
182f815e 6729{
6730 struct alignment_context ac;
77e58889 6731 rtx cmpv, newv, val, cc, seq0, seq1, seq2, seq3;
182f815e 6732 rtx res = gen_reg_rtx (SImode);
79f6a8ed 6733 rtx_code_label *csloop = NULL, *csend = NULL;
182f815e 6734
182f815e 6735 gcc_assert (MEM_P (mem));
6736
6737 init_alignment_context (&ac, mem, mode);
6738
182f815e 6739 /* Load full word. Subsequent loads are performed by CS. */
6740 val = expand_simple_binop (SImode, AND, ac.memsi, ac.modemaski,
6741 NULL_RTX, 1, OPTAB_DIRECT);
6742
8c753480 6743 /* Prepare insertions of cmp and new_rtx into the loaded value. When
6744 possible, we try to use insv to make this happen efficiently. If
6745 that fails we'll generate code both inside and outside the loop. */
6746 cmpv = s390_two_part_insv (&ac, &seq0, &seq2, mode, val, cmp);
6747 newv = s390_two_part_insv (&ac, &seq1, &seq3, mode, val, new_rtx);
6748
6749 if (seq0)
6750 emit_insn (seq0);
6751 if (seq1)
6752 emit_insn (seq1);
6753
182f815e 6754 /* Start CS loop. */
8c753480 6755 if (!is_weak)
6756 {
6757 /* Begin assuming success. */
6758 emit_move_insn (btarget, const1_rtx);
6759
6760 csloop = gen_label_rtx ();
6761 csend = gen_label_rtx ();
6762 emit_label (csloop);
6763 }
6764
ffead1ca 6765 /* val = "<mem>00..0<mem>"
182f815e 6766 * cmp = "00..0<cmp>00..0"
ffead1ca 6767 * new = "00..0<new>00..0"
182f815e 6768 */
6769
8c753480 6770 emit_insn (seq2);
6771 emit_insn (seq3);
6772
6773 cc = s390_emit_compare_and_swap (EQ, res, ac.memsi, cmpv, newv);
6774 if (is_weak)
6775 emit_insn (gen_cstorecc4 (btarget, cc, XEXP (cc, 0), XEXP (cc, 1)));
182f815e 6776 else
182f815e 6777 {
77e58889 6778 rtx tmp;
6779
8c753480 6780 /* Jump to end if we're done (likely?). */
6781 s390_emit_jump (csend, cc);
6782
77e58889 6783 /* Check for changes outside mode, and loop internal if so.
6784 Arrange the moves so that the compare is adjacent to the
6785 branch so that we can generate CRJ. */
6786 tmp = copy_to_reg (val);
6787 force_expand_binop (SImode, and_optab, res, ac.modemaski, val,
6788 1, OPTAB_DIRECT);
6789 cc = s390_emit_compare (NE, val, tmp);
8c753480 6790 s390_emit_jump (csloop, cc);
6791
6792 /* Failed. */
6793 emit_move_insn (btarget, const0_rtx);
6794 emit_label (csend);
182f815e 6795 }
ffead1ca 6796
182f815e 6797 /* Return the correct part of the bitfield. */
8c753480 6798 convert_move (vtarget, expand_simple_binop (SImode, LSHIFTRT, res, ac.shift,
6799 NULL_RTX, 1, OPTAB_DIRECT), 1);
182f815e 6800}
6801
7cc66daf 6802/* Expand an atomic operation CODE of mode MODE. MEM is the memory location
85694bac 6803 and VAL the value to play with. If AFTER is true then store the value
7cc66daf 6804 MEM holds after the operation, if AFTER is false then store the value MEM
6805 holds before the operation. If TARGET is zero then discard that value, else
6806 store it to TARGET. */
6807
6808void
3754d046 6809s390_expand_atomic (machine_mode mode, enum rtx_code code,
7cc66daf 6810 rtx target, rtx mem, rtx val, bool after)
6811{
6812 struct alignment_context ac;
6813 rtx cmp;
8deb3959 6814 rtx new_rtx = gen_reg_rtx (SImode);
7cc66daf 6815 rtx orig = gen_reg_rtx (SImode);
79f6a8ed 6816 rtx_code_label *csloop = gen_label_rtx ();
7cc66daf 6817
6818 gcc_assert (!target || register_operand (target, VOIDmode));
6819 gcc_assert (MEM_P (mem));
6820
6821 init_alignment_context (&ac, mem, mode);
6822
6823 /* Shift val to the correct bit positions.
6824 Preserve "icm", but prevent "ex icm". */
6825 if (!(ac.aligned && code == SET && MEM_P (val)))
6826 val = s390_expand_mask_and_shift (val, mode, ac.shift);
6827
6828 /* Further preparation insns. */
6829 if (code == PLUS || code == MINUS)
6830 emit_move_insn (orig, val);
6831 else if (code == MULT || code == AND) /* val = "11..1<val>11..1" */
6832 val = expand_simple_binop (SImode, XOR, val, ac.modemaski,
6833 NULL_RTX, 1, OPTAB_DIRECT);
6834
6835 /* Load full word. Subsequent loads are performed by CS. */
6836 cmp = force_reg (SImode, ac.memsi);
6837
6838 /* Start CS loop. */
6839 emit_label (csloop);
8deb3959 6840 emit_move_insn (new_rtx, cmp);
7cc66daf 6841
6842 /* Patch new with val at correct position. */
6843 switch (code)
6844 {
6845 case PLUS:
6846 case MINUS:
8deb3959 6847 val = expand_simple_binop (SImode, code, new_rtx, orig,
7cc66daf 6848 NULL_RTX, 1, OPTAB_DIRECT);
6849 val = expand_simple_binop (SImode, AND, val, ac.modemask,
6850 NULL_RTX, 1, OPTAB_DIRECT);
6851 /* FALLTHRU */
ffead1ca 6852 case SET:
7cc66daf 6853 if (ac.aligned && MEM_P (val))
b634c730 6854 store_bit_field (new_rtx, GET_MODE_BITSIZE (mode), 0,
292237f3 6855 0, 0, SImode, val, false);
7cc66daf 6856 else
6857 {
8deb3959 6858 new_rtx = expand_simple_binop (SImode, AND, new_rtx, ac.modemaski,
7cc66daf 6859 NULL_RTX, 1, OPTAB_DIRECT);
8deb3959 6860 new_rtx = expand_simple_binop (SImode, IOR, new_rtx, val,
7cc66daf 6861 NULL_RTX, 1, OPTAB_DIRECT);
6862 }
6863 break;
6864 case AND:
6865 case IOR:
6866 case XOR:
8deb3959 6867 new_rtx = expand_simple_binop (SImode, code, new_rtx, val,
7cc66daf 6868 NULL_RTX, 1, OPTAB_DIRECT);
6869 break;
6870 case MULT: /* NAND */
8deb3959 6871 new_rtx = expand_simple_binop (SImode, AND, new_rtx, val,
7cc66daf 6872 NULL_RTX, 1, OPTAB_DIRECT);
636c17b8 6873 new_rtx = expand_simple_binop (SImode, XOR, new_rtx, ac.modemask,
6874 NULL_RTX, 1, OPTAB_DIRECT);
7cc66daf 6875 break;
6876 default:
6877 gcc_unreachable ();
6878 }
7cc66daf 6879
db1f11e3 6880 s390_emit_jump (csloop, s390_emit_compare_and_swap (NE, cmp,
8deb3959 6881 ac.memsi, cmp, new_rtx));
7cc66daf 6882
6883 /* Return the correct part of the bitfield. */
6884 if (target)
6885 convert_move (target, expand_simple_binop (SImode, LSHIFTRT,
8deb3959 6886 after ? new_rtx : cmp, ac.shift,
7cc66daf 6887 NULL_RTX, 1, OPTAB_DIRECT), 1);
6888}
6889
40af64cc 6890/* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
03c118d5 6891 We need to emit DTP-relative relocations. */
6892
40af64cc 6893static void s390_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
6894
6895static void
b40da9a7 6896s390_output_dwarf_dtprel (FILE *file, int size, rtx x)
03c118d5 6897{
6898 switch (size)
6899 {
6900 case 4:
6901 fputs ("\t.long\t", file);
6902 break;
6903 case 8:
6904 fputs ("\t.quad\t", file);
6905 break;
6906 default:
32eda510 6907 gcc_unreachable ();
03c118d5 6908 }
6909 output_addr_const (file, x);
6910 fputs ("@DTPOFF", file);
6911}
6912
76a4c804 6913/* Return the proper mode for REGNO being represented in the dwarf
6914 unwind table. */
6915machine_mode
6916s390_dwarf_frame_reg_mode (int regno)
6917{
6918 machine_mode save_mode = default_dwarf_frame_reg_mode (regno);
6919
52de7525 6920 /* Make sure not to return DImode for any GPR with -m31 -mzarch. */
6921 if (GENERAL_REGNO_P (regno))
6922 save_mode = Pmode;
6923
76a4c804 6924 /* The rightmost 64 bits of vector registers are call-clobbered. */
6925 if (GET_MODE_SIZE (save_mode) > 8)
6926 save_mode = DImode;
6927
6928 return save_mode;
6929}
6930
4257b08a 6931#ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
eddcdde1 6932/* Implement TARGET_MANGLE_TYPE. */
4257b08a 6933
6934static const char *
a9f1838b 6935s390_mangle_type (const_tree type)
4257b08a 6936{
07f32359 6937 type = TYPE_MAIN_VARIANT (type);
6938
6939 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
6940 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
6941 return NULL;
6942
6943 if (type == s390_builtin_types[BT_BV16QI]) return "U6__boolc";
6944 if (type == s390_builtin_types[BT_BV8HI]) return "U6__bools";
6945 if (type == s390_builtin_types[BT_BV4SI]) return "U6__booli";
6946 if (type == s390_builtin_types[BT_BV2DI]) return "U6__booll";
6947
4257b08a 6948 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
6949 && TARGET_LONG_DOUBLE_128)
6950 return "g";
6951
6952 /* For all other types, use normal C++ mangling. */
6953 return NULL;
6954}
6955#endif
6956
e93986bb 6957/* In the name of slightly smaller debug output, and to cater to
06b27565 6958 general assembler lossage, recognize various UNSPEC sequences
e93986bb 6959 and turn them back into a direct symbol reference. */
6960
07576557 6961static rtx
b40da9a7 6962s390_delegitimize_address (rtx orig_x)
e93986bb 6963{
3b6b647c 6964 rtx x, y;
e93986bb 6965
3b6b647c 6966 orig_x = delegitimize_mem_from_attrs (orig_x);
6967 x = orig_x;
4796d433 6968
6969 /* Extract the symbol ref from:
6970 (plus:SI (reg:SI 12 %r12)
6971 (const:SI (unspec:SI [(symbol_ref/f:SI ("*.LC0"))]
2b2b857a 6972 UNSPEC_GOTOFF/PLTOFF)))
6973 and
6974 (plus:SI (reg:SI 12 %r12)
6975 (const:SI (plus:SI (unspec:SI [(symbol_ref:SI ("L"))]
6976 UNSPEC_GOTOFF/PLTOFF)
6977 (const_int 4 [0x4])))) */
4796d433 6978 if (GET_CODE (x) == PLUS
6979 && REG_P (XEXP (x, 0))
6980 && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM
6981 && GET_CODE (XEXP (x, 1)) == CONST)
6982 {
b6382e93 6983 HOST_WIDE_INT offset = 0;
6984
4796d433 6985 /* The const operand. */
6986 y = XEXP (XEXP (x, 1), 0);
2b2b857a 6987
6988 if (GET_CODE (y) == PLUS
6989 && GET_CODE (XEXP (y, 1)) == CONST_INT)
b6382e93 6990 {
6991 offset = INTVAL (XEXP (y, 1));
6992 y = XEXP (y, 0);
6993 }
2b2b857a 6994
4796d433 6995 if (GET_CODE (y) == UNSPEC
2b2b857a 6996 && (XINT (y, 1) == UNSPEC_GOTOFF
6997 || XINT (y, 1) == UNSPEC_PLTOFF))
29c05e22 6998 return plus_constant (Pmode, XVECEXP (y, 0, 0), offset);
4796d433 6999 }
7000
e93986bb 7001 if (GET_CODE (x) != MEM)
7002 return orig_x;
7003
7004 x = XEXP (x, 0);
7005 if (GET_CODE (x) == PLUS
7006 && GET_CODE (XEXP (x, 1)) == CONST
7007 && GET_CODE (XEXP (x, 0)) == REG
7008 && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM)
7009 {
7010 y = XEXP (XEXP (x, 1), 0);
7011 if (GET_CODE (y) == UNSPEC
12ef3745 7012 && XINT (y, 1) == UNSPEC_GOT)
54cb44a3 7013 y = XVECEXP (y, 0, 0);
7014 else
7015 return orig_x;
e93986bb 7016 }
54cb44a3 7017 else if (GET_CODE (x) == CONST)
e93986bb 7018 {
2b2b857a 7019 /* Extract the symbol ref from:
7020 (mem:QI (const:DI (unspec:DI [(symbol_ref:DI ("foo"))]
7021 UNSPEC_PLT/GOTENT))) */
7022
e93986bb 7023 y = XEXP (x, 0);
7024 if (GET_CODE (y) == UNSPEC
2b2b857a 7025 && (XINT (y, 1) == UNSPEC_GOTENT
7026 || XINT (y, 1) == UNSPEC_PLT))
54cb44a3 7027 y = XVECEXP (y, 0, 0);
7028 else
7029 return orig_x;
e93986bb 7030 }
54cb44a3 7031 else
7032 return orig_x;
e93986bb 7033
54cb44a3 7034 if (GET_MODE (orig_x) != Pmode)
7035 {
2b03de53 7036 if (GET_MODE (orig_x) == BLKmode)
7037 return orig_x;
54cb44a3 7038 y = lowpart_subreg (GET_MODE (orig_x), y, Pmode);
7039 if (y == NULL_RTX)
7040 return orig_x;
7041 }
7042 return y;
e93986bb 7043}
2eb8fe23 7044
805a133b 7045/* Output operand OP to stdio stream FILE.
7046 OP is an address (register + offset) which is not used to address data;
7047 instead the rightmost bits are interpreted as the value. */
63ebd742 7048
7049static void
2be7449b 7050print_addrstyle_operand (FILE *file, rtx op)
63ebd742 7051{
6d6be381 7052 HOST_WIDE_INT offset;
7053 rtx base;
9a09ba70 7054
6d6be381 7055 /* Extract base register and offset. */
2be7449b 7056 if (!s390_decompose_addrstyle_without_index (op, &base, &offset))
6d6be381 7057 gcc_unreachable ();
63ebd742 7058
7059 /* Sanity check. */
6d6be381 7060 if (base)
32eda510 7061 {
6d6be381 7062 gcc_assert (GET_CODE (base) == REG);
7063 gcc_assert (REGNO (base) < FIRST_PSEUDO_REGISTER);
7064 gcc_assert (REGNO_REG_CLASS (REGNO (base)) == ADDR_REGS);
32eda510 7065 }
63ebd742 7066
805a133b 7067 /* Offsets are constricted to twelve bits. */
7068 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset & ((1 << 12) - 1));
6d6be381 7069 if (base)
7070 fprintf (file, "(%s)", reg_names[REGNO (base)]);
63ebd742 7071}
7072
06877232 7073/* Assigns the number of NOP halfwords to be emitted before and after the
7074 function label to *HW_BEFORE and *HW_AFTER. Both pointers must not be NULL.
7075 If hotpatching is disabled for the function, the values are set to zero.
7076*/
77bc9912 7077
06877232 7078static void
11762b83 7079s390_function_num_hotpatch_hw (tree decl,
7080 int *hw_before,
7081 int *hw_after)
77bc9912 7082{
7083 tree attr;
7084
11762b83 7085 attr = lookup_attribute ("hotpatch", DECL_ATTRIBUTES (decl));
7086
7087 /* Handle the arguments of the hotpatch attribute. The values
7088 specified via attribute might override the cmdline argument
7089 values. */
7090 if (attr)
77bc9912 7091 {
11762b83 7092 tree args = TREE_VALUE (attr);
7093
7094 *hw_before = TREE_INT_CST_LOW (TREE_VALUE (args));
7095 *hw_after = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (args)));
77bc9912 7096 }
11762b83 7097 else
77bc9912 7098 {
11762b83 7099 /* Use the values specified by the cmdline arguments. */
7100 *hw_before = s390_hotpatch_hw_before_label;
7101 *hw_after = s390_hotpatch_hw_after_label;
77bc9912 7102 }
77bc9912 7103}
7104
7a0cee35 7105/* Write the current .machine and .machinemode specification to the assembler
7106 file. */
7107
14d7e7e6 7108#ifdef HAVE_AS_MACHINE_MACHINEMODE
7a0cee35 7109static void
7110s390_asm_output_machine_for_arch (FILE *asm_out_file)
7111{
7112 fprintf (asm_out_file, "\t.machinemode %s\n",
7113 (TARGET_ZARCH) ? "zarch" : "esa");
7114 fprintf (asm_out_file, "\t.machine \"%s", processor_table[s390_arch].name);
7115 if (S390_USE_ARCHITECTURE_MODIFIERS)
7116 {
7117 int cpu_flags;
7118
7119 cpu_flags = processor_flags_table[(int) s390_arch];
7120 if (TARGET_HTM && !(cpu_flags & PF_TX))
7121 fprintf (asm_out_file, "+htm");
7122 else if (!TARGET_HTM && (cpu_flags & PF_TX))
7123 fprintf (asm_out_file, "+nohtm");
7124 if (TARGET_VX && !(cpu_flags & PF_VX))
7125 fprintf (asm_out_file, "+vx");
7126 else if (!TARGET_VX && (cpu_flags & PF_VX))
7127 fprintf (asm_out_file, "+novx");
7128 }
7129 fprintf (asm_out_file, "\"\n");
7130}
7131
7132/* Write an extra function header before the very start of the function. */
7133
7134void
7135s390_asm_output_function_prefix (FILE *asm_out_file,
7136 const char *fnname ATTRIBUTE_UNUSED)
7137{
7138 if (DECL_FUNCTION_SPECIFIC_TARGET (current_function_decl) == NULL)
7139 return;
7140 /* Since only the function specific options are saved but not the indications
7141 which options are set, it's too much work here to figure out which options
7142 have actually changed. Thus, generate .machine and .machinemode whenever a
7143 function has the target attribute or pragma. */
7144 fprintf (asm_out_file, "\t.machinemode push\n");
7145 fprintf (asm_out_file, "\t.machine push\n");
7146 s390_asm_output_machine_for_arch (asm_out_file);
7147}
7148
7149/* Write an extra function footer after the very end of the function. */
7150
7151void
7152s390_asm_declare_function_size (FILE *asm_out_file,
0491d54f 7153 const char *fnname, tree decl)
7a0cee35 7154{
0491d54f 7155 if (!flag_inhibit_size_directive)
7156 ASM_OUTPUT_MEASURED_SIZE (asm_out_file, fnname);
7a0cee35 7157 if (DECL_FUNCTION_SPECIFIC_TARGET (decl) == NULL)
7158 return;
7159 fprintf (asm_out_file, "\t.machine pop\n");
7160 fprintf (asm_out_file, "\t.machinemode pop\n");
7161}
7162#endif
7163
77bc9912 7164/* Write the extra assembler code needed to declare a function properly. */
7165
7166void
7167s390_asm_output_function_label (FILE *asm_out_file, const char *fname,
7168 tree decl)
7169{
11762b83 7170 int hw_before, hw_after;
77bc9912 7171
06877232 7172 s390_function_num_hotpatch_hw (decl, &hw_before, &hw_after);
7173 if (hw_before > 0)
77bc9912 7174 {
f4252e72 7175 unsigned int function_alignment;
77bc9912 7176 int i;
7177
7178 /* Add a trampoline code area before the function label and initialize it
7179 with two-byte nop instructions. This area can be overwritten with code
7180 that jumps to a patched version of the function. */
2a4536cc 7181 asm_fprintf (asm_out_file, "\tnopr\t%%r0"
06877232 7182 "\t# pre-label NOPs for hotpatch (%d halfwords)\n",
7183 hw_before);
7184 for (i = 1; i < hw_before; i++)
2a4536cc 7185 fputs ("\tnopr\t%r0\n", asm_out_file);
06877232 7186
77bc9912 7187 /* Note: The function label must be aligned so that (a) the bytes of the
7188 following nop do not cross a cacheline boundary, and (b) a jump address
7189 (eight bytes for 64 bit targets, 4 bytes for 32 bit targets) can be
7190 stored directly before the label without crossing a cacheline
7191 boundary. All this is necessary to make sure the trampoline code can
06877232 7192 be changed atomically.
7193 This alignment is done automatically using the FOUNCTION_BOUNDARY, but
7194 if there are NOPs before the function label, the alignment is placed
7195 before them. So it is necessary to duplicate the alignment after the
7196 NOPs. */
f4252e72 7197 function_alignment = MAX (8, DECL_ALIGN (decl) / BITS_PER_UNIT);
7198 if (! DECL_USER_ALIGN (decl))
7199 function_alignment = MAX (function_alignment,
7200 (unsigned int) align_functions);
06877232 7201 fputs ("\t# alignment for hotpatch\n", asm_out_file);
f4252e72 7202 ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (function_alignment));
77bc9912 7203 }
7204
7a0cee35 7205 if (S390_USE_TARGET_ATTRIBUTE && TARGET_DEBUG_ARG)
7206 {
7207 asm_fprintf (asm_out_file, "\t# fn:%s ar%d\n", fname, s390_arch);
7208 asm_fprintf (asm_out_file, "\t# fn:%s tu%d\n", fname, s390_tune);
7209 asm_fprintf (asm_out_file, "\t# fn:%s sg%d\n", fname, s390_stack_guard);
7210 asm_fprintf (asm_out_file, "\t# fn:%s ss%d\n", fname, s390_stack_size);
7211 asm_fprintf (asm_out_file, "\t# fn:%s bc%d\n", fname, s390_branch_cost);
7212 asm_fprintf (asm_out_file, "\t# fn:%s wf%d\n", fname,
7213 s390_warn_framesize);
7214 asm_fprintf (asm_out_file, "\t# fn:%s ba%d\n", fname, TARGET_BACKCHAIN);
7215 asm_fprintf (asm_out_file, "\t# fn:%s hd%d\n", fname, TARGET_HARD_DFP);
7216 asm_fprintf (asm_out_file, "\t# fn:%s hf%d\n", fname, !TARGET_SOFT_FLOAT);
7217 asm_fprintf (asm_out_file, "\t# fn:%s ht%d\n", fname, TARGET_OPT_HTM);
7218 asm_fprintf (asm_out_file, "\t# fn:%s vx%d\n", fname, TARGET_OPT_VX);
7219 asm_fprintf (asm_out_file, "\t# fn:%s ps%d\n", fname,
7220 TARGET_PACKED_STACK);
7221 asm_fprintf (asm_out_file, "\t# fn:%s se%d\n", fname, TARGET_SMALL_EXEC);
7222 asm_fprintf (asm_out_file, "\t# fn:%s mv%d\n", fname, TARGET_MVCLE);
7223 asm_fprintf (asm_out_file, "\t# fn:%s zv%d\n", fname, TARGET_ZVECTOR);
7224 asm_fprintf (asm_out_file, "\t# fn:%s wd%d\n", fname,
7225 s390_warn_dynamicstack_p);
7226 }
77bc9912 7227 ASM_OUTPUT_LABEL (asm_out_file, fname);
06877232 7228 if (hw_after > 0)
7229 asm_fprintf (asm_out_file,
7230 "\t# post-label NOPs for hotpatch (%d halfwords)\n",
7231 hw_after);
77bc9912 7232}
7233
f588eb9f 7234/* Output machine-dependent UNSPECs occurring in address constant X
74d2529d 7235 in assembler syntax to stdio stream FILE. Returns true if the
7236 constant X could be recognized, false otherwise. */
4673c1a0 7237
1a561788 7238static bool
74d2529d 7239s390_output_addr_const_extra (FILE *file, rtx x)
4673c1a0 7240{
74d2529d 7241 if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 1)
7242 switch (XINT (x, 1))
7243 {
7244 case UNSPEC_GOTENT:
7245 output_addr_const (file, XVECEXP (x, 0, 0));
7246 fprintf (file, "@GOTENT");
7247 return true;
7248 case UNSPEC_GOT:
7249 output_addr_const (file, XVECEXP (x, 0, 0));
7250 fprintf (file, "@GOT");
7251 return true;
7252 case UNSPEC_GOTOFF:
7253 output_addr_const (file, XVECEXP (x, 0, 0));
7254 fprintf (file, "@GOTOFF");
7255 return true;
7256 case UNSPEC_PLT:
7257 output_addr_const (file, XVECEXP (x, 0, 0));
7258 fprintf (file, "@PLT");
7259 return true;
7260 case UNSPEC_PLTOFF:
7261 output_addr_const (file, XVECEXP (x, 0, 0));
7262 fprintf (file, "@PLTOFF");
7263 return true;
7264 case UNSPEC_TLSGD:
7265 output_addr_const (file, XVECEXP (x, 0, 0));
7266 fprintf (file, "@TLSGD");
7267 return true;
7268 case UNSPEC_TLSLDM:
7269 assemble_name (file, get_some_local_dynamic_name ());
7270 fprintf (file, "@TLSLDM");
7271 return true;
7272 case UNSPEC_DTPOFF:
7273 output_addr_const (file, XVECEXP (x, 0, 0));
7274 fprintf (file, "@DTPOFF");
7275 return true;
7276 case UNSPEC_NTPOFF:
7277 output_addr_const (file, XVECEXP (x, 0, 0));
7278 fprintf (file, "@NTPOFF");
7279 return true;
7280 case UNSPEC_GOTNTPOFF:
7281 output_addr_const (file, XVECEXP (x, 0, 0));
7282 fprintf (file, "@GOTNTPOFF");
7283 return true;
7284 case UNSPEC_INDNTPOFF:
7285 output_addr_const (file, XVECEXP (x, 0, 0));
7286 fprintf (file, "@INDNTPOFF");
7287 return true;
7288 }
4673c1a0 7289
1ed7a160 7290 if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 2)
7291 switch (XINT (x, 1))
7292 {
7293 case UNSPEC_POOL_OFFSET:
7294 x = gen_rtx_MINUS (GET_MODE (x), XVECEXP (x, 0, 0), XVECEXP (x, 0, 1));
7295 output_addr_const (file, x);
7296 return true;
7297 }
74d2529d 7298 return false;
4673c1a0 7299}
7300
f81e845f 7301/* Output address operand ADDR in assembler syntax to
56769981 7302 stdio stream FILE. */
4673c1a0 7303
7304void
b40da9a7 7305print_operand_address (FILE *file, rtx addr)
4673c1a0 7306{
7307 struct s390_address ad;
883b2519 7308 memset (&ad, 0, sizeof (s390_address));
4673c1a0 7309
2a672556 7310 if (s390_loadrelative_operand_p (addr, NULL, NULL))
e68d6a13 7311 {
53b9033c 7312 if (!TARGET_Z10)
7313 {
902602ef 7314 output_operand_lossage ("symbolic memory references are "
7315 "only supported on z10 or later");
53b9033c 7316 return;
7317 }
e68d6a13 7318 output_addr_const (file, addr);
7319 return;
7320 }
7321
8ba34dcd 7322 if (!s390_decompose_address (addr, &ad)
1e280623 7323 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
7324 || (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx))))
3284a242 7325 output_operand_lossage ("cannot decompose address");
f81e845f 7326
4673c1a0 7327 if (ad.disp)
74d2529d 7328 output_addr_const (file, ad.disp);
4673c1a0 7329 else
7330 fprintf (file, "0");
7331
7332 if (ad.base && ad.indx)
7333 fprintf (file, "(%s,%s)", reg_names[REGNO (ad.indx)],
7334 reg_names[REGNO (ad.base)]);
7335 else if (ad.base)
7336 fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
7337}
7338
f81e845f 7339/* Output operand X in assembler syntax to stdio stream FILE.
7340 CODE specified the format flag. The following format flags
56769981 7341 are recognized:
7342
7343 'C': print opcode suffix for branch condition.
7344 'D': print opcode suffix for inverse branch condition.
f1443d23 7345 'E': print opcode suffix for branch on index instruction.
cc87d0c5 7346 'G': print the size of the operand in bytes.
0d46035f 7347 'J': print tls_load/tls_gdcall/tls_ldcall suffix
7348 'M': print the second word of a TImode operand.
7349 'N': print the second word of a DImode operand.
76a4c804 7350 'O': print only the displacement of a memory reference or address.
7351 'R': print only the base register of a memory reference or address.
0574acbe 7352 'S': print S-type memory reference (base+displacement).
2be7449b 7353 'Y': print address style operand without index (e.g. shift count or setmem
7354 operand).
56769981 7355
45981c0a 7356 'b': print integer X as if it's an unsigned byte.
e68d6a13 7357 'c': print integer X as if it's an signed byte.
76a4c804 7358 'e': "end" contiguous bitmask X in either DImode or vector inner mode.
7359 'f': "end" contiguous bitmask X in SImode.
b9059d39 7360 'h': print integer X as if it's a signed halfword.
64a1078f 7361 'i': print the first nonzero HImode part of X.
b9059d39 7362 'j': print the first HImode part unequal to -1 of X.
7363 'k': print the first nonzero SImode part of X.
7364 'm': print the first SImode part unequal to -1 of X.
0d46035f 7365 'o': print integer X as if it's an unsigned 32bit word.
76a4c804 7366 's': "start" of contiguous bitmask X in either DImode or vector inner mode.
7367 't': CONST_INT: "start" of contiguous bitmask X in SImode.
7368 CONST_VECTOR: Generate a bitmask for vgbm instruction.
0d46035f 7369 'x': print integer X as if it's an unsigned halfword.
76a4c804 7370 'v': print register number as vector register (v1 instead of f1).
0d46035f 7371*/
4673c1a0 7372
7373void
b40da9a7 7374print_operand (FILE *file, rtx x, int code)
4673c1a0 7375{
0d46035f 7376 HOST_WIDE_INT ival;
7377
4673c1a0 7378 switch (code)
7379 {
7380 case 'C':
2eb8fe23 7381 fprintf (file, s390_branch_condition_mnemonic (x, FALSE));
4673c1a0 7382 return;
7383
7384 case 'D':
2eb8fe23 7385 fprintf (file, s390_branch_condition_mnemonic (x, TRUE));
4673c1a0 7386 return;
7387
f1443d23 7388 case 'E':
7389 if (GET_CODE (x) == LE)
7390 fprintf (file, "l");
7391 else if (GET_CODE (x) == GT)
7392 fprintf (file, "h");
7393 else
902602ef 7394 output_operand_lossage ("invalid comparison operator "
7395 "for 'E' output modifier");
f1443d23 7396 return;
7397
be00aaa8 7398 case 'J':
7399 if (GET_CODE (x) == SYMBOL_REF)
7400 {
7401 fprintf (file, "%s", ":tls_load:");
7402 output_addr_const (file, x);
7403 }
7404 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD)
7405 {
7406 fprintf (file, "%s", ":tls_gdcall:");
7407 output_addr_const (file, XVECEXP (x, 0, 0));
7408 }
7409 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM)
7410 {
7411 fprintf (file, "%s", ":tls_ldcall:");
3677652f 7412 const char *name = get_some_local_dynamic_name ();
7413 gcc_assert (name);
7414 assemble_name (file, name);
be00aaa8 7415 }
7416 else
902602ef 7417 output_operand_lossage ("invalid reference for 'J' output modifier");
be00aaa8 7418 return;
7419
cc87d0c5 7420 case 'G':
7421 fprintf (file, "%u", GET_MODE_SIZE (GET_MODE (x)));
7422 return;
7423
4673c1a0 7424 case 'O':
7425 {
7426 struct s390_address ad;
32eda510 7427 int ret;
4673c1a0 7428
76a4c804 7429 ret = s390_decompose_address (MEM_P (x) ? XEXP (x, 0) : x, &ad);
53b9033c 7430
7431 if (!ret
7432 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
7433 || ad.indx)
7434 {
902602ef 7435 output_operand_lossage ("invalid address for 'O' output modifier");
53b9033c 7436 return;
7437 }
4673c1a0 7438
7439 if (ad.disp)
74d2529d 7440 output_addr_const (file, ad.disp);
4673c1a0 7441 else
7442 fprintf (file, "0");
7443 }
7444 return;
7445
7446 case 'R':
7447 {
7448 struct s390_address ad;
32eda510 7449 int ret;
4673c1a0 7450
76a4c804 7451 ret = s390_decompose_address (MEM_P (x) ? XEXP (x, 0) : x, &ad);
53b9033c 7452
7453 if (!ret
7454 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
7455 || ad.indx)
7456 {
902602ef 7457 output_operand_lossage ("invalid address for 'R' output modifier");
53b9033c 7458 return;
7459 }
4673c1a0 7460
7461 if (ad.base)
7462 fprintf (file, "%s", reg_names[REGNO (ad.base)]);
7463 else
7464 fprintf (file, "0");
7465 }
7466 return;
7467
0574acbe 7468 case 'S':
7469 {
7470 struct s390_address ad;
32eda510 7471 int ret;
0574acbe 7472
53b9033c 7473 if (!MEM_P (x))
7474 {
902602ef 7475 output_operand_lossage ("memory reference expected for "
7476 "'S' output modifier");
53b9033c 7477 return;
7478 }
32eda510 7479 ret = s390_decompose_address (XEXP (x, 0), &ad);
53b9033c 7480
7481 if (!ret
7482 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
7483 || ad.indx)
7484 {
902602ef 7485 output_operand_lossage ("invalid address for 'S' output modifier");
53b9033c 7486 return;
7487 }
0574acbe 7488
7489 if (ad.disp)
7490 output_addr_const (file, ad.disp);
7491 else
7492 fprintf (file, "0");
7493
7494 if (ad.base)
7495 fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
7496 }
7497 return;
7498
4673c1a0 7499 case 'N':
7500 if (GET_CODE (x) == REG)
7501 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
7502 else if (GET_CODE (x) == MEM)
29c05e22 7503 x = change_address (x, VOIDmode,
7504 plus_constant (Pmode, XEXP (x, 0), 4));
4673c1a0 7505 else
902602ef 7506 output_operand_lossage ("register or memory expression expected "
7507 "for 'N' output modifier");
4673c1a0 7508 break;
7509
7510 case 'M':
7511 if (GET_CODE (x) == REG)
7512 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
7513 else if (GET_CODE (x) == MEM)
29c05e22 7514 x = change_address (x, VOIDmode,
7515 plus_constant (Pmode, XEXP (x, 0), 8));
4673c1a0 7516 else
902602ef 7517 output_operand_lossage ("register or memory expression expected "
7518 "for 'M' output modifier");
4673c1a0 7519 break;
63ebd742 7520
7521 case 'Y':
2be7449b 7522 print_addrstyle_operand (file, x);
63ebd742 7523 return;
4673c1a0 7524 }
7525
7526 switch (GET_CODE (x))
7527 {
7528 case REG:
76a4c804 7529 /* Print FP regs as fx instead of vx when they are accessed
7530 through non-vector mode. */
7531 if (code == 'v'
7532 || VECTOR_NOFP_REG_P (x)
7533 || (FP_REG_P (x) && VECTOR_MODE_P (GET_MODE (x)))
7534 || (VECTOR_REG_P (x)
7535 && (GET_MODE_SIZE (GET_MODE (x)) /
7536 s390_class_max_nregs (FP_REGS, GET_MODE (x))) > 8))
7537 fprintf (file, "%%v%s", reg_names[REGNO (x)] + 2);
7538 else
7539 fprintf (file, "%s", reg_names[REGNO (x)]);
4673c1a0 7540 break;
7541
7542 case MEM:
3c047fe9 7543 output_address (GET_MODE (x), XEXP (x, 0));
4673c1a0 7544 break;
7545
7546 case CONST:
7547 case CODE_LABEL:
7548 case LABEL_REF:
7549 case SYMBOL_REF:
74d2529d 7550 output_addr_const (file, x);
4673c1a0 7551 break;
7552
7553 case CONST_INT:
0d46035f 7554 ival = INTVAL (x);
7555 switch (code)
7556 {
7557 case 0:
7558 break;
7559 case 'b':
7560 ival &= 0xff;
7561 break;
7562 case 'c':
7563 ival = ((ival & 0xff) ^ 0x80) - 0x80;
7564 break;
7565 case 'x':
7566 ival &= 0xffff;
7567 break;
7568 case 'h':
7569 ival = ((ival & 0xffff) ^ 0x8000) - 0x8000;
7570 break;
7571 case 'i':
7572 ival = s390_extract_part (x, HImode, 0);
7573 break;
7574 case 'j':
7575 ival = s390_extract_part (x, HImode, -1);
7576 break;
7577 case 'k':
7578 ival = s390_extract_part (x, SImode, 0);
7579 break;
7580 case 'm':
7581 ival = s390_extract_part (x, SImode, -1);
7582 break;
7583 case 'o':
7584 ival &= 0xffffffff;
7585 break;
7586 case 'e': case 'f':
7587 case 's': case 't':
7588 {
e64f5133 7589 int start, end;
7590 int len;
0d46035f 7591 bool ok;
7592
7593 len = (code == 's' || code == 'e' ? 64 : 32);
e64f5133 7594 ok = s390_contiguous_bitmask_p (ival, true, len, &start, &end);
0d46035f 7595 gcc_assert (ok);
7596 if (code == 's' || code == 't')
e64f5133 7597 ival = start;
0d46035f 7598 else
e64f5133 7599 ival = end;
0d46035f 7600 }
7601 break;
7602 default:
7603 output_operand_lossage ("invalid constant for output modifier '%c'", code);
7604 }
7605 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival);
8b4a4127 7606 break;
7607
ba0e61d6 7608 case CONST_WIDE_INT:
8b4a4127 7609 if (code == 'b')
ba0e61d6 7610 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
7611 CONST_WIDE_INT_ELT (x, 0) & 0xff);
4673c1a0 7612 else if (code == 'x')
ba0e61d6 7613 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
7614 CONST_WIDE_INT_ELT (x, 0) & 0xffff);
4673c1a0 7615 else if (code == 'h')
902602ef 7616 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
ba0e61d6 7617 ((CONST_WIDE_INT_ELT (x, 0) & 0xffff) ^ 0x8000) - 0x8000);
4673c1a0 7618 else
53b9033c 7619 {
7620 if (code == 0)
902602ef 7621 output_operand_lossage ("invalid constant - try using "
7622 "an output modifier");
53b9033c 7623 else
902602ef 7624 output_operand_lossage ("invalid constant for output modifier '%c'",
7625 code);
53b9033c 7626 }
4673c1a0 7627 break;
76a4c804 7628 case CONST_VECTOR:
7629 switch (code)
7630 {
80fc7f56 7631 case 'h':
7632 gcc_assert (const_vec_duplicate_p (x));
7633 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
7634 ((INTVAL (XVECEXP (x, 0, 0)) & 0xffff) ^ 0x8000) - 0x8000);
7635 break;
76a4c804 7636 case 'e':
7637 case 's':
7638 {
e64f5133 7639 int start, end;
76a4c804 7640 bool ok;
7641
e64f5133 7642 ok = s390_contiguous_bitmask_vector_p (x, &start, &end);
76a4c804 7643 gcc_assert (ok);
e64f5133 7644 ival = (code == 's') ? start : end;
76a4c804 7645 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival);
7646 }
7647 break;
7648 case 't':
7649 {
7650 unsigned mask;
7651 bool ok = s390_bytemask_vector_p (x, &mask);
7652 gcc_assert (ok);
7653 fprintf (file, "%u", mask);
7654 }
7655 break;
7656
7657 default:
7658 output_operand_lossage ("invalid constant vector for output "
7659 "modifier '%c'", code);
7660 }
7661 break;
4673c1a0 7662
7663 default:
53b9033c 7664 if (code == 0)
902602ef 7665 output_operand_lossage ("invalid expression - try using "
7666 "an output modifier");
53b9033c 7667 else
902602ef 7668 output_operand_lossage ("invalid expression for output "
7669 "modifier '%c'", code);
4673c1a0 7670 break;
7671 }
7672}
7673
58356836 7674/* Target hook for assembling integer objects. We need to define it
7675 here to work a round a bug in some versions of GAS, which couldn't
7676 handle values smaller than INT_MIN when printed in decimal. */
7677
7678static bool
b40da9a7 7679s390_assemble_integer (rtx x, unsigned int size, int aligned_p)
58356836 7680{
7681 if (size == 8 && aligned_p
7682 && GET_CODE (x) == CONST_INT && INTVAL (x) < INT_MIN)
7683 {
4840a03a 7684 fprintf (asm_out_file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n",
7685 INTVAL (x));
58356836 7686 return true;
7687 }
7688 return default_assemble_integer (x, size, aligned_p);
7689}
7690
f81e845f 7691/* Returns true if register REGNO is used for forming
56769981 7692 a memory address in expression X. */
4673c1a0 7693
e5537457 7694static bool
b40da9a7 7695reg_used_in_mem_p (int regno, rtx x)
4673c1a0 7696{
7697 enum rtx_code code = GET_CODE (x);
7698 int i, j;
7699 const char *fmt;
f81e845f 7700
4673c1a0 7701 if (code == MEM)
7702 {
2ec77a7c 7703 if (refers_to_regno_p (regno, XEXP (x, 0)))
e5537457 7704 return true;
4673c1a0 7705 }
f81e845f 7706 else if (code == SET
8b4a4127 7707 && GET_CODE (SET_DEST (x)) == PC)
7708 {
2ec77a7c 7709 if (refers_to_regno_p (regno, SET_SRC (x)))
e5537457 7710 return true;
8b4a4127 7711 }
4673c1a0 7712
7713 fmt = GET_RTX_FORMAT (code);
7714 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
7715 {
7716 if (fmt[i] == 'e'
7717 && reg_used_in_mem_p (regno, XEXP (x, i)))
e5537457 7718 return true;
f81e845f 7719
4673c1a0 7720 else if (fmt[i] == 'E')
7721 for (j = 0; j < XVECLEN (x, i); j++)
7722 if (reg_used_in_mem_p (regno, XVECEXP (x, i, j)))
e5537457 7723 return true;
4673c1a0 7724 }
e5537457 7725 return false;
4673c1a0 7726}
7727
0c034860 7728/* Returns true if expression DEP_RTX sets an address register
56769981 7729 used by instruction INSN to address memory. */
4673c1a0 7730
e5537457 7731static bool
ed3e6e5d 7732addr_generation_dependency_p (rtx dep_rtx, rtx_insn *insn)
4673c1a0 7733{
8b4a4127 7734 rtx target, pat;
4673c1a0 7735
aa90bb35 7736 if (NONJUMP_INSN_P (dep_rtx))
77985f1a 7737 dep_rtx = PATTERN (dep_rtx);
71343e6b 7738
4673c1a0 7739 if (GET_CODE (dep_rtx) == SET)
7740 {
7741 target = SET_DEST (dep_rtx);
147b6a2d 7742 if (GET_CODE (target) == STRICT_LOW_PART)
7743 target = XEXP (target, 0);
7744 while (GET_CODE (target) == SUBREG)
7745 target = SUBREG_REG (target);
7746
4673c1a0 7747 if (GET_CODE (target) == REG)
7748 {
7749 int regno = REGNO (target);
7750
71343e6b 7751 if (s390_safe_attr_type (insn) == TYPE_LA)
8b4a4127 7752 {
7753 pat = PATTERN (insn);
7754 if (GET_CODE (pat) == PARALLEL)
7755 {
32eda510 7756 gcc_assert (XVECLEN (pat, 0) == 2);
8b4a4127 7757 pat = XVECEXP (pat, 0, 0);
7758 }
32eda510 7759 gcc_assert (GET_CODE (pat) == SET);
2ec77a7c 7760 return refers_to_regno_p (regno, SET_SRC (pat));
8b4a4127 7761 }
71343e6b 7762 else if (get_attr_atype (insn) == ATYPE_AGEN)
8b4a4127 7763 return reg_used_in_mem_p (regno, PATTERN (insn));
7764 }
4673c1a0 7765 }
e5537457 7766 return false;
4673c1a0 7767}
7768
71343e6b 7769/* Return 1, if dep_insn sets register used in insn in the agen unit. */
7770
f81e845f 7771int
ed3e6e5d 7772s390_agen_dep_p (rtx_insn *dep_insn, rtx_insn *insn)
f81e845f 7773{
71343e6b 7774 rtx dep_rtx = PATTERN (dep_insn);
7775 int i;
f81e845f 7776
7777 if (GET_CODE (dep_rtx) == SET
71343e6b 7778 && addr_generation_dependency_p (dep_rtx, insn))
7779 return 1;
7780 else if (GET_CODE (dep_rtx) == PARALLEL)
7781 {
7782 for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
7783 {
7784 if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i), insn))
7785 return 1;
7786 }
7787 }
7788 return 0;
7789}
7790
510c2327 7791
e51ae8ff 7792/* A C statement (sans semicolon) to update the integer scheduling priority
7793 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
7794 reduce the priority to execute INSN later. Do not define this macro if
f81e845f 7795 you do not need to adjust the scheduling priorities of insns.
e51ae8ff 7796
f81e845f 7797 A STD instruction should be scheduled earlier,
e51ae8ff 7798 in order to use the bypass. */
e51ae8ff 7799static int
18282db0 7800s390_adjust_priority (rtx_insn *insn, int priority)
e51ae8ff 7801{
7802 if (! INSN_P (insn))
7803 return priority;
7804
9aae2901 7805 if (s390_tune <= PROCESSOR_2064_Z900)
e51ae8ff 7806 return priority;
7807
7808 switch (s390_safe_attr_type (insn))
7809 {
11f88fec 7810 case TYPE_FSTOREDF:
7811 case TYPE_FSTORESF:
e51ae8ff 7812 priority = priority << 3;
7813 break;
7814 case TYPE_STORE:
76dbb8df 7815 case TYPE_STM:
e51ae8ff 7816 priority = priority << 1;
7817 break;
7818 default:
7819 break;
7820 }
7821 return priority;
7822}
369293ed 7823
b0eacf26 7824
71343e6b 7825/* The number of instructions that can be issued per cycle. */
369293ed 7826
71343e6b 7827static int
b40da9a7 7828s390_issue_rate (void)
71343e6b 7829{
a850370e 7830 switch (s390_tune)
7831 {
7832 case PROCESSOR_2084_Z990:
7833 case PROCESSOR_2094_Z9_109:
9aae2901 7834 case PROCESSOR_2094_Z9_EC:
33d033da 7835 case PROCESSOR_2817_Z196:
a850370e 7836 return 3;
7837 case PROCESSOR_2097_Z10:
7838 return 2;
117d67d0 7839 case PROCESSOR_9672_G5:
7840 case PROCESSOR_9672_G6:
7841 case PROCESSOR_2064_Z900:
5ed1f72b 7842 /* Starting with EC12 we use the sched_reorder hook to take care
7843 of instruction dispatch constraints. The algorithm only
7844 picks the best instruction and assumes only a single
7845 instruction gets issued per cycle. */
7846 case PROCESSOR_2827_ZEC12:
117d67d0 7847 case PROCESSOR_2964_Z13:
c9213ca0 7848 case PROCESSOR_ARCH12:
a850370e 7849 default:
7850 return 1;
7851 }
71343e6b 7852}
369293ed 7853
e51ae8ff 7854static int
b40da9a7 7855s390_first_cycle_multipass_dfa_lookahead (void)
e51ae8ff 7856{
a65ea517 7857 return 4;
e51ae8ff 7858}
7859
20074f87 7860/* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
7861 Fix up MEMs as required. */
7862
7863static void
7864annotate_constant_pool_refs (rtx *x)
7865{
7866 int i, j;
7867 const char *fmt;
7868
32eda510 7869 gcc_assert (GET_CODE (*x) != SYMBOL_REF
7870 || !CONSTANT_POOL_ADDRESS_P (*x));
20074f87 7871
7872 /* Literal pool references can only occur inside a MEM ... */
7873 if (GET_CODE (*x) == MEM)
7874 {
7875 rtx memref = XEXP (*x, 0);
7876
7877 if (GET_CODE (memref) == SYMBOL_REF
7878 && CONSTANT_POOL_ADDRESS_P (memref))
7879 {
7880 rtx base = cfun->machine->base_reg;
7881 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, memref, base),
7882 UNSPEC_LTREF);
7883
7884 *x = replace_equiv_address (*x, addr);
7885 return;
7886 }
7887
7888 if (GET_CODE (memref) == CONST
7889 && GET_CODE (XEXP (memref, 0)) == PLUS
7890 && GET_CODE (XEXP (XEXP (memref, 0), 1)) == CONST_INT
7891 && GET_CODE (XEXP (XEXP (memref, 0), 0)) == SYMBOL_REF
7892 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (memref, 0), 0)))
7893 {
7894 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (memref, 0), 1));
7895 rtx sym = XEXP (XEXP (memref, 0), 0);
7896 rtx base = cfun->machine->base_reg;
7897 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, sym, base),
7898 UNSPEC_LTREF);
7899
29c05e22 7900 *x = replace_equiv_address (*x, plus_constant (Pmode, addr, off));
20074f87 7901 return;
7902 }
7903 }
7904
7905 /* ... or a load-address type pattern. */
7906 if (GET_CODE (*x) == SET)
7907 {
7908 rtx addrref = SET_SRC (*x);
7909
7910 if (GET_CODE (addrref) == SYMBOL_REF
7911 && CONSTANT_POOL_ADDRESS_P (addrref))
7912 {
7913 rtx base = cfun->machine->base_reg;
7914 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, addrref, base),
7915 UNSPEC_LTREF);
7916
7917 SET_SRC (*x) = addr;
7918 return;
7919 }
7920
7921 if (GET_CODE (addrref) == CONST
7922 && GET_CODE (XEXP (addrref, 0)) == PLUS
7923 && GET_CODE (XEXP (XEXP (addrref, 0), 1)) == CONST_INT
7924 && GET_CODE (XEXP (XEXP (addrref, 0), 0)) == SYMBOL_REF
7925 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (addrref, 0), 0)))
7926 {
7927 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (addrref, 0), 1));
7928 rtx sym = XEXP (XEXP (addrref, 0), 0);
7929 rtx base = cfun->machine->base_reg;
7930 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, sym, base),
7931 UNSPEC_LTREF);
7932
29c05e22 7933 SET_SRC (*x) = plus_constant (Pmode, addr, off);
20074f87 7934 return;
7935 }
7936 }
7937
7938 /* Annotate LTREL_BASE as well. */
7939 if (GET_CODE (*x) == UNSPEC
7940 && XINT (*x, 1) == UNSPEC_LTREL_BASE)
7941 {
7942 rtx base = cfun->machine->base_reg;
7943 *x = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, XVECEXP (*x, 0, 0), base),
7944 UNSPEC_LTREL_BASE);
7945 return;
7946 }
7947
7948 fmt = GET_RTX_FORMAT (GET_CODE (*x));
7949 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
7950 {
7951 if (fmt[i] == 'e')
7952 {
7953 annotate_constant_pool_refs (&XEXP (*x, i));
7954 }
7955 else if (fmt[i] == 'E')
7956 {
7957 for (j = 0; j < XVECLEN (*x, i); j++)
7958 annotate_constant_pool_refs (&XVECEXP (*x, i, j));
7959 }
7960 }
7961}
7962
875862bf 7963/* Split all branches that exceed the maximum distance.
7964 Returns true if this created a new literal pool entry. */
7965
7966static int
7967s390_split_branches (void)
7968{
7969 rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
32eda510 7970 int new_literal = 0, ret;
93e0956b 7971 rtx_insn *insn;
ed7591be 7972 rtx pat, target;
875862bf 7973 rtx *label;
7974
7975 /* We need correct insn addresses. */
7976
7977 shorten_branches (get_insns ());
7978
7979 /* Find all branches that exceed 64KB, and split them. */
7980
7981 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7982 {
245402e7 7983 if (! JUMP_P (insn) || tablejump_p (insn, NULL, NULL))
875862bf 7984 continue;
7985
7986 pat = PATTERN (insn);
245402e7 7987 if (GET_CODE (pat) == PARALLEL)
875862bf 7988 pat = XVECEXP (pat, 0, 0);
7989 if (GET_CODE (pat) != SET || SET_DEST (pat) != pc_rtx)
7990 continue;
7991
7992 if (GET_CODE (SET_SRC (pat)) == LABEL_REF)
7993 {
7994 label = &SET_SRC (pat);
7995 }
7996 else if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE)
7997 {
7998 if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF)
7999 label = &XEXP (SET_SRC (pat), 1);
8000 else if (GET_CODE (XEXP (SET_SRC (pat), 2)) == LABEL_REF)
8001 label = &XEXP (SET_SRC (pat), 2);
8002 else
8003 continue;
8004 }
8005 else
8006 continue;
8007
8008 if (get_attr_length (insn) <= 4)
8009 continue;
8010
77beec48 8011 /* We are going to use the return register as scratch register,
8012 make sure it will be saved/restored by the prologue/epilogue. */
8013 cfun_frame_layout.save_return_addr_p = 1;
8014
875862bf 8015 if (!flag_pic)
8016 {
8017 new_literal = 1;
ed7591be 8018 rtx mem = force_const_mem (Pmode, *label);
d1f9b275 8019 rtx_insn *set_insn = emit_insn_before (gen_rtx_SET (temp_reg, mem),
8020 insn);
ed7591be 8021 INSN_ADDRESSES_NEW (set_insn, -1);
8022 annotate_constant_pool_refs (&PATTERN (set_insn));
875862bf 8023
8024 target = temp_reg;
8025 }
8026 else
8027 {
8028 new_literal = 1;
8029 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, *label),
8030 UNSPEC_LTREL_OFFSET);
8031 target = gen_rtx_CONST (Pmode, target);
8032 target = force_const_mem (Pmode, target);
d1f9b275 8033 rtx_insn *set_insn = emit_insn_before (gen_rtx_SET (temp_reg, target),
8034 insn);
ed7591be 8035 INSN_ADDRESSES_NEW (set_insn, -1);
8036 annotate_constant_pool_refs (&PATTERN (set_insn));
875862bf 8037
8038 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, XEXP (target, 0),
8039 cfun->machine->base_reg),
8040 UNSPEC_LTREL_BASE);
8041 target = gen_rtx_PLUS (Pmode, temp_reg, target);
8042 }
8043
32eda510 8044 ret = validate_change (insn, label, target, 0);
8045 gcc_assert (ret);
875862bf 8046 }
8047
8048 return new_literal;
8049}
8050
0756cebb 8051
ffead1ca 8052/* Find an annotated literal pool symbol referenced in RTX X,
8053 and store it at REF. Will abort if X contains references to
20074f87 8054 more than one such pool symbol; multiple references to the same
8055 symbol are allowed, however.
0756cebb 8056
f81e845f 8057 The rtx pointed to by REF must be initialized to NULL_RTX
0756cebb 8058 by the caller before calling this routine. */
8059
8060static void
b40da9a7 8061find_constant_pool_ref (rtx x, rtx *ref)
0756cebb 8062{
8063 int i, j;
8064 const char *fmt;
8065
12ef3745 8066 /* Ignore LTREL_BASE references. */
8067 if (GET_CODE (x) == UNSPEC
8068 && XINT (x, 1) == UNSPEC_LTREL_BASE)
8069 return;
c2c1332a 8070 /* Likewise POOL_ENTRY insns. */
8071 if (GET_CODE (x) == UNSPEC_VOLATILE
8072 && XINT (x, 1) == UNSPECV_POOL_ENTRY)
8073 return;
12ef3745 8074
32eda510 8075 gcc_assert (GET_CODE (x) != SYMBOL_REF
8076 || !CONSTANT_POOL_ADDRESS_P (x));
20074f87 8077
8078 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_LTREF)
0756cebb 8079 {
20074f87 8080 rtx sym = XVECEXP (x, 0, 0);
32eda510 8081 gcc_assert (GET_CODE (sym) == SYMBOL_REF
8082 && CONSTANT_POOL_ADDRESS_P (sym));
20074f87 8083
0756cebb 8084 if (*ref == NULL_RTX)
20074f87 8085 *ref = sym;
ffead1ca 8086 else
32eda510 8087 gcc_assert (*ref == sym);
20074f87 8088
8089 return;
0756cebb 8090 }
8091
8092 fmt = GET_RTX_FORMAT (GET_CODE (x));
8093 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
8094 {
8095 if (fmt[i] == 'e')
8096 {
8097 find_constant_pool_ref (XEXP (x, i), ref);
8098 }
8099 else if (fmt[i] == 'E')
8100 {
8101 for (j = 0; j < XVECLEN (x, i); j++)
8102 find_constant_pool_ref (XVECEXP (x, i, j), ref);
8103 }
8104 }
8105}
8106
ffead1ca 8107/* Replace every reference to the annotated literal pool
20074f87 8108 symbol REF in X by its base plus OFFSET. */
0756cebb 8109
8110static void
20074f87 8111replace_constant_pool_ref (rtx *x, rtx ref, rtx offset)
0756cebb 8112{
8113 int i, j;
8114 const char *fmt;
8115
32eda510 8116 gcc_assert (*x != ref);
0756cebb 8117
20074f87 8118 if (GET_CODE (*x) == UNSPEC
8119 && XINT (*x, 1) == UNSPEC_LTREF
8120 && XVECEXP (*x, 0, 0) == ref)
0756cebb 8121 {
20074f87 8122 *x = gen_rtx_PLUS (Pmode, XVECEXP (*x, 0, 1), offset);
8123 return;
0756cebb 8124 }
8125
20074f87 8126 if (GET_CODE (*x) == PLUS
8127 && GET_CODE (XEXP (*x, 1)) == CONST_INT
8128 && GET_CODE (XEXP (*x, 0)) == UNSPEC
8129 && XINT (XEXP (*x, 0), 1) == UNSPEC_LTREF
8130 && XVECEXP (XEXP (*x, 0), 0, 0) == ref)
0756cebb 8131 {
20074f87 8132 rtx addr = gen_rtx_PLUS (Pmode, XVECEXP (XEXP (*x, 0), 0, 1), offset);
29c05e22 8133 *x = plus_constant (Pmode, addr, INTVAL (XEXP (*x, 1)));
20074f87 8134 return;
0756cebb 8135 }
8136
8137 fmt = GET_RTX_FORMAT (GET_CODE (*x));
8138 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
8139 {
8140 if (fmt[i] == 'e')
8141 {
20074f87 8142 replace_constant_pool_ref (&XEXP (*x, i), ref, offset);
0756cebb 8143 }
8144 else if (fmt[i] == 'E')
8145 {
8146 for (j = 0; j < XVECLEN (*x, i); j++)
20074f87 8147 replace_constant_pool_ref (&XVECEXP (*x, i, j), ref, offset);
0756cebb 8148 }
8149 }
8150}
8151
f81e845f 8152/* Check whether X contains an UNSPEC_LTREL_BASE.
12ef3745 8153 Return its constant pool symbol if found, NULL_RTX otherwise. */
96be3ab6 8154
12ef3745 8155static rtx
b40da9a7 8156find_ltrel_base (rtx x)
96be3ab6 8157{
96be3ab6 8158 int i, j;
8159 const char *fmt;
8160
12ef3745 8161 if (GET_CODE (x) == UNSPEC
8162 && XINT (x, 1) == UNSPEC_LTREL_BASE)
8163 return XVECEXP (x, 0, 0);
96be3ab6 8164
8165 fmt = GET_RTX_FORMAT (GET_CODE (x));
8166 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
8167 {
8168 if (fmt[i] == 'e')
8169 {
12ef3745 8170 rtx fnd = find_ltrel_base (XEXP (x, i));
8171 if (fnd)
8172 return fnd;
96be3ab6 8173 }
8174 else if (fmt[i] == 'E')
8175 {
8176 for (j = 0; j < XVECLEN (x, i); j++)
12ef3745 8177 {
8178 rtx fnd = find_ltrel_base (XVECEXP (x, i, j));
8179 if (fnd)
8180 return fnd;
8181 }
96be3ab6 8182 }
8183 }
8184
12ef3745 8185 return NULL_RTX;
96be3ab6 8186}
8187
20074f87 8188/* Replace any occurrence of UNSPEC_LTREL_BASE in X with its base. */
96be3ab6 8189
8190static void
20074f87 8191replace_ltrel_base (rtx *x)
96be3ab6 8192{
12ef3745 8193 int i, j;
96be3ab6 8194 const char *fmt;
8195
12ef3745 8196 if (GET_CODE (*x) == UNSPEC
8197 && XINT (*x, 1) == UNSPEC_LTREL_BASE)
96be3ab6 8198 {
20074f87 8199 *x = XVECEXP (*x, 0, 1);
12ef3745 8200 return;
96be3ab6 8201 }
8202
8203 fmt = GET_RTX_FORMAT (GET_CODE (*x));
8204 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
8205 {
8206 if (fmt[i] == 'e')
8207 {
20074f87 8208 replace_ltrel_base (&XEXP (*x, i));
96be3ab6 8209 }
8210 else if (fmt[i] == 'E')
8211 {
8212 for (j = 0; j < XVECLEN (*x, i); j++)
20074f87 8213 replace_ltrel_base (&XVECEXP (*x, i, j));
96be3ab6 8214 }
8215 }
8216}
8217
8218
12ef3745 8219/* We keep a list of constants which we have to add to internal
0756cebb 8220 constant tables in the middle of large functions. */
8221
02b901ef 8222#define NR_C_MODES 32
3754d046 8223machine_mode constant_modes[NR_C_MODES] =
0756cebb 8224{
36868490 8225 TFmode, TImode, TDmode,
02b901ef 8226 V16QImode, V8HImode, V4SImode, V2DImode, V1TImode,
8227 V4SFmode, V2DFmode, V1TFmode,
36868490 8228 DFmode, DImode, DDmode,
76a4c804 8229 V8QImode, V4HImode, V2SImode, V1DImode, V2SFmode, V1DFmode,
36868490 8230 SFmode, SImode, SDmode,
76a4c804 8231 V4QImode, V2HImode, V1SImode, V1SFmode,
0756cebb 8232 HImode,
76a4c804 8233 V2QImode, V1HImode,
8234 QImode,
8235 V1QImode
0756cebb 8236};
8237
0756cebb 8238struct constant
8239{
8240 struct constant *next;
8241 rtx value;
93e0956b 8242 rtx_code_label *label;
0756cebb 8243};
8244
8245struct constant_pool
8246{
8247 struct constant_pool *next;
93e0956b 8248 rtx_insn *first_insn;
8249 rtx_insn *pool_insn;
96be3ab6 8250 bitmap insns;
93e0956b 8251 rtx_insn *emit_pool_after;
0756cebb 8252
8253 struct constant *constants[NR_C_MODES];
d345b493 8254 struct constant *execute;
93e0956b 8255 rtx_code_label *label;
0756cebb 8256 int size;
8257};
8258
875862bf 8259/* Allocate new constant_pool structure. */
8260
8261static struct constant_pool *
8262s390_alloc_pool (void)
8263{
8264 struct constant_pool *pool;
8265 int i;
8266
8267 pool = (struct constant_pool *) xmalloc (sizeof *pool);
8268 pool->next = NULL;
8269 for (i = 0; i < NR_C_MODES; i++)
8270 pool->constants[i] = NULL;
8271
8272 pool->execute = NULL;
8273 pool->label = gen_label_rtx ();
93e0956b 8274 pool->first_insn = NULL;
8275 pool->pool_insn = NULL;
875862bf 8276 pool->insns = BITMAP_ALLOC (NULL);
8277 pool->size = 0;
93e0956b 8278 pool->emit_pool_after = NULL;
875862bf 8279
8280 return pool;
8281}
0756cebb 8282
8283/* Create new constant pool covering instructions starting at INSN
8284 and chain it to the end of POOL_LIST. */
8285
8286static struct constant_pool *
93e0956b 8287s390_start_pool (struct constant_pool **pool_list, rtx_insn *insn)
0756cebb 8288{
8289 struct constant_pool *pool, **prev;
0756cebb 8290
c2c1332a 8291 pool = s390_alloc_pool ();
0756cebb 8292 pool->first_insn = insn;
96be3ab6 8293
0756cebb 8294 for (prev = pool_list; *prev; prev = &(*prev)->next)
8295 ;
8296 *prev = pool;
8297
8298 return pool;
8299}
8300
96be3ab6 8301/* End range of instructions covered by POOL at INSN and emit
8302 placeholder insn representing the pool. */
0756cebb 8303
8304static void
93e0956b 8305s390_end_pool (struct constant_pool *pool, rtx_insn *insn)
0756cebb 8306{
96be3ab6 8307 rtx pool_size = GEN_INT (pool->size + 8 /* alignment slop */);
8308
8309 if (!insn)
8310 insn = get_last_insn ();
8311
8312 pool->pool_insn = emit_insn_after (gen_pool (pool_size), insn);
8313 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
8314}
8315
8316/* Add INSN to the list of insns covered by POOL. */
8317
8318static void
b40da9a7 8319s390_add_pool_insn (struct constant_pool *pool, rtx insn)
96be3ab6 8320{
8321 bitmap_set_bit (pool->insns, INSN_UID (insn));
0756cebb 8322}
8323
8324/* Return pool out of POOL_LIST that covers INSN. */
8325
8326static struct constant_pool *
b40da9a7 8327s390_find_pool (struct constant_pool *pool_list, rtx insn)
0756cebb 8328{
0756cebb 8329 struct constant_pool *pool;
8330
0756cebb 8331 for (pool = pool_list; pool; pool = pool->next)
96be3ab6 8332 if (bitmap_bit_p (pool->insns, INSN_UID (insn)))
0756cebb 8333 break;
8334
8335 return pool;
8336}
8337
96be3ab6 8338/* Add constant VAL of mode MODE to the constant pool POOL. */
0756cebb 8339
96be3ab6 8340static void
3754d046 8341s390_add_constant (struct constant_pool *pool, rtx val, machine_mode mode)
0756cebb 8342{
8343 struct constant *c;
0756cebb 8344 int i;
8345
8346 for (i = 0; i < NR_C_MODES; i++)
8347 if (constant_modes[i] == mode)
8348 break;
32eda510 8349 gcc_assert (i != NR_C_MODES);
0756cebb 8350
8351 for (c = pool->constants[i]; c != NULL; c = c->next)
8352 if (rtx_equal_p (val, c->value))
8353 break;
8354
8355 if (c == NULL)
8356 {
8357 c = (struct constant *) xmalloc (sizeof *c);
8358 c->value = val;
8359 c->label = gen_label_rtx ();
8360 c->next = pool->constants[i];
8361 pool->constants[i] = c;
8362 pool->size += GET_MODE_SIZE (mode);
8363 }
96be3ab6 8364}
0756cebb 8365
1ed7a160 8366/* Return an rtx that represents the offset of X from the start of
8367 pool POOL. */
8368
8369static rtx
8370s390_pool_offset (struct constant_pool *pool, rtx x)
8371{
8372 rtx label;
8373
8374 label = gen_rtx_LABEL_REF (GET_MODE (x), pool->label);
8375 x = gen_rtx_UNSPEC (GET_MODE (x), gen_rtvec (2, x, label),
8376 UNSPEC_POOL_OFFSET);
8377 return gen_rtx_CONST (GET_MODE (x), x);
8378}
8379
96be3ab6 8380/* Find constant VAL of mode MODE in the constant pool POOL.
8381 Return an RTX describing the distance from the start of
8382 the pool to the location of the new constant. */
f81e845f 8383
96be3ab6 8384static rtx
b40da9a7 8385s390_find_constant (struct constant_pool *pool, rtx val,
3754d046 8386 machine_mode mode)
96be3ab6 8387{
8388 struct constant *c;
96be3ab6 8389 int i;
f81e845f 8390
96be3ab6 8391 for (i = 0; i < NR_C_MODES; i++)
8392 if (constant_modes[i] == mode)
8393 break;
32eda510 8394 gcc_assert (i != NR_C_MODES);
f81e845f 8395
96be3ab6 8396 for (c = pool->constants[i]; c != NULL; c = c->next)
8397 if (rtx_equal_p (val, c->value))
8398 break;
f81e845f 8399
32eda510 8400 gcc_assert (c);
f81e845f 8401
1ed7a160 8402 return s390_pool_offset (pool, gen_rtx_LABEL_REF (Pmode, c->label));
0756cebb 8403}
8404
875862bf 8405/* Check whether INSN is an execute. Return the label_ref to its
8406 execute target template if so, NULL_RTX otherwise. */
8407
8408static rtx
8409s390_execute_label (rtx insn)
8410{
aa90bb35 8411 if (NONJUMP_INSN_P (insn)
875862bf 8412 && GET_CODE (PATTERN (insn)) == PARALLEL
8413 && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == UNSPEC
8414 && XINT (XVECEXP (PATTERN (insn), 0, 0), 1) == UNSPEC_EXECUTE)
8415 return XVECEXP (XVECEXP (PATTERN (insn), 0, 0), 0, 2);
8416
8417 return NULL_RTX;
8418}
8419
d345b493 8420/* Add execute target for INSN to the constant pool POOL. */
8421
8422static void
8423s390_add_execute (struct constant_pool *pool, rtx insn)
8424{
8425 struct constant *c;
8426
8427 for (c = pool->execute; c != NULL; c = c->next)
8428 if (INSN_UID (insn) == INSN_UID (c->value))
8429 break;
8430
8431 if (c == NULL)
8432 {
d345b493 8433 c = (struct constant *) xmalloc (sizeof *c);
8434 c->value = insn;
babfdedf 8435 c->label = gen_label_rtx ();
d345b493 8436 c->next = pool->execute;
8437 pool->execute = c;
babfdedf 8438 pool->size += 6;
d345b493 8439 }
8440}
8441
8442/* Find execute target for INSN in the constant pool POOL.
8443 Return an RTX describing the distance from the start of
8444 the pool to the location of the execute target. */
8445
8446static rtx
8447s390_find_execute (struct constant_pool *pool, rtx insn)
8448{
8449 struct constant *c;
d345b493 8450
8451 for (c = pool->execute; c != NULL; c = c->next)
8452 if (INSN_UID (insn) == INSN_UID (c->value))
8453 break;
8454
32eda510 8455 gcc_assert (c);
d345b493 8456
1ed7a160 8457 return s390_pool_offset (pool, gen_rtx_LABEL_REF (Pmode, c->label));
d345b493 8458}
8459
875862bf 8460/* For an execute INSN, extract the execute target template. */
d345b493 8461
8462static rtx
875862bf 8463s390_execute_target (rtx insn)
d345b493 8464{
875862bf 8465 rtx pattern = PATTERN (insn);
8466 gcc_assert (s390_execute_label (insn));
d345b493 8467
8468 if (XVECLEN (pattern, 0) == 2)
8469 {
8470 pattern = copy_rtx (XVECEXP (pattern, 0, 1));
8471 }
8472 else
8473 {
8474 rtvec vec = rtvec_alloc (XVECLEN (pattern, 0) - 1);
8475 int i;
8476
8477 for (i = 0; i < XVECLEN (pattern, 0) - 1; i++)
8478 RTVEC_ELT (vec, i) = copy_rtx (XVECEXP (pattern, 0, i + 1));
8479
8480 pattern = gen_rtx_PARALLEL (VOIDmode, vec);
8481 }
8482
8483 return pattern;
8484}
8485
8486/* Indicate that INSN cannot be duplicated. This is the case for
8487 execute insns that carry a unique label. */
8488
8489static bool
18282db0 8490s390_cannot_copy_insn_p (rtx_insn *insn)
d345b493 8491{
8492 rtx label = s390_execute_label (insn);
8493 return label && label != const0_rtx;
8494}
8495
c2c1332a 8496/* Dump out the constants in POOL. If REMOTE_LABEL is true,
8497 do not emit the pool base label. */
0756cebb 8498
d345b493 8499static void
c2c1332a 8500s390_dump_pool (struct constant_pool *pool, bool remote_label)
0756cebb 8501{
8502 struct constant *c;
93e0956b 8503 rtx_insn *insn = pool->pool_insn;
0756cebb 8504 int i;
8505
d345b493 8506 /* Switch to rodata section. */
8507 if (TARGET_CPU_ZARCH)
8508 {
8509 insn = emit_insn_after (gen_pool_section_start (), insn);
8510 INSN_ADDRESSES_NEW (insn, -1);
8511 }
8512
8513 /* Ensure minimum pool alignment. */
dafc8d45 8514 if (TARGET_CPU_ZARCH)
d345b493 8515 insn = emit_insn_after (gen_pool_align (GEN_INT (8)), insn);
0756cebb 8516 else
d345b493 8517 insn = emit_insn_after (gen_pool_align (GEN_INT (4)), insn);
0756cebb 8518 INSN_ADDRESSES_NEW (insn, -1);
8519
d345b493 8520 /* Emit pool base label. */
c2c1332a 8521 if (!remote_label)
8522 {
8523 insn = emit_label_after (pool->label, insn);
8524 INSN_ADDRESSES_NEW (insn, -1);
8525 }
0756cebb 8526
8527 /* Dump constants in descending alignment requirement order,
8528 ensuring proper alignment for every constant. */
8529 for (i = 0; i < NR_C_MODES; i++)
8530 for (c = pool->constants[i]; c; c = c->next)
8531 {
12ef3745 8532 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
b2ed6df1 8533 rtx value = copy_rtx (c->value);
96be3ab6 8534 if (GET_CODE (value) == CONST
8535 && GET_CODE (XEXP (value, 0)) == UNSPEC
12ef3745 8536 && XINT (XEXP (value, 0), 1) == UNSPEC_LTREL_OFFSET
96be3ab6 8537 && XVECLEN (XEXP (value, 0), 0) == 1)
1ed7a160 8538 value = s390_pool_offset (pool, XVECEXP (XEXP (value, 0), 0, 0));
96be3ab6 8539
0756cebb 8540 insn = emit_label_after (c->label, insn);
8541 INSN_ADDRESSES_NEW (insn, -1);
df82fb76 8542
f588eb9f 8543 value = gen_rtx_UNSPEC_VOLATILE (constant_modes[i],
df82fb76 8544 gen_rtvec (1, value),
8545 UNSPECV_POOL_ENTRY);
8546 insn = emit_insn_after (value, insn);
0756cebb 8547 INSN_ADDRESSES_NEW (insn, -1);
8548 }
8549
d345b493 8550 /* Ensure minimum alignment for instructions. */
8551 insn = emit_insn_after (gen_pool_align (GEN_INT (2)), insn);
0756cebb 8552 INSN_ADDRESSES_NEW (insn, -1);
8553
d345b493 8554 /* Output in-pool execute template insns. */
8555 for (c = pool->execute; c; c = c->next)
8556 {
d345b493 8557 insn = emit_label_after (c->label, insn);
8558 INSN_ADDRESSES_NEW (insn, -1);
8559
8560 insn = emit_insn_after (s390_execute_target (c->value), insn);
8561 INSN_ADDRESSES_NEW (insn, -1);
8562 }
8563
8564 /* Switch back to previous section. */
8565 if (TARGET_CPU_ZARCH)
8566 {
8567 insn = emit_insn_after (gen_pool_section_end (), insn);
8568 INSN_ADDRESSES_NEW (insn, -1);
8569 }
8570
0756cebb 8571 insn = emit_barrier_after (insn);
8572 INSN_ADDRESSES_NEW (insn, -1);
8573
96be3ab6 8574 /* Remove placeholder insn. */
8575 remove_insn (pool->pool_insn);
d345b493 8576}
8577
0756cebb 8578/* Free all memory used by POOL. */
8579
8580static void
b40da9a7 8581s390_free_pool (struct constant_pool *pool)
0756cebb 8582{
d345b493 8583 struct constant *c, *next;
0756cebb 8584 int i;
8585
8586 for (i = 0; i < NR_C_MODES; i++)
d345b493 8587 for (c = pool->constants[i]; c; c = next)
8588 {
8589 next = c->next;
8590 free (c);
8591 }
8592
8593 for (c = pool->execute; c; c = next)
0756cebb 8594 {
d345b493 8595 next = c->next;
8596 free (c);
0756cebb 8597 }
8598
4d6e8511 8599 BITMAP_FREE (pool->insns);
0756cebb 8600 free (pool);
f81e845f 8601}
0756cebb 8602
0756cebb 8603
c2c1332a 8604/* Collect main literal pool. Return NULL on overflow. */
8605
8606static struct constant_pool *
8607s390_mainpool_start (void)
8608{
8609 struct constant_pool *pool;
93e0956b 8610 rtx_insn *insn;
c2c1332a 8611
8612 pool = s390_alloc_pool ();
8613
8614 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8615 {
aa90bb35 8616 if (NONJUMP_INSN_P (insn)
20074f87 8617 && GET_CODE (PATTERN (insn)) == SET
8618 && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC_VOLATILE
8619 && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPECV_MAIN_POOL)
c2c1332a 8620 {
7a64c761 8621 /* There might be two main_pool instructions if base_reg
8622 is call-clobbered; one for shrink-wrapped code and one
8623 for the rest. We want to keep the first. */
8624 if (pool->pool_insn)
8625 {
8626 insn = PREV_INSN (insn);
8627 delete_insn (NEXT_INSN (insn));
8628 continue;
8629 }
c2c1332a 8630 pool->pool_insn = insn;
8631 }
8632
babfdedf 8633 if (!TARGET_CPU_ZARCH && s390_execute_label (insn))
d345b493 8634 {
8635 s390_add_execute (pool, insn);
8636 }
aa90bb35 8637 else if (NONJUMP_INSN_P (insn) || CALL_P (insn))
c2c1332a 8638 {
8639 rtx pool_ref = NULL_RTX;
8640 find_constant_pool_ref (PATTERN (insn), &pool_ref);
8641 if (pool_ref)
8642 {
8643 rtx constant = get_pool_constant (pool_ref);
3754d046 8644 machine_mode mode = get_pool_mode (pool_ref);
c2c1332a 8645 s390_add_constant (pool, constant, mode);
8646 }
8647 }
86428198 8648
8649 /* If hot/cold partitioning is enabled we have to make sure that
8650 the literal pool is emitted in the same section where the
8651 initialization of the literal pool base pointer takes place.
8652 emit_pool_after is only used in the non-overflow case on non
8653 Z cpus where we can emit the literal pool at the end of the
8654 function body within the text section. */
8655 if (NOTE_P (insn)
7338c728 8656 && NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS
8657 && !pool->emit_pool_after)
8658 pool->emit_pool_after = PREV_INSN (insn);
c2c1332a 8659 }
8660
32eda510 8661 gcc_assert (pool->pool_insn || pool->size == 0);
c2c1332a 8662
8663 if (pool->size >= 4096)
8664 {
7de9f7aa 8665 /* We're going to chunkify the pool, so remove the main
8666 pool placeholder insn. */
8667 remove_insn (pool->pool_insn);
8668
c2c1332a 8669 s390_free_pool (pool);
8670 pool = NULL;
8671 }
8672
86428198 8673 /* If the functions ends with the section where the literal pool
8674 should be emitted set the marker to its end. */
7338c728 8675 if (pool && !pool->emit_pool_after)
86428198 8676 pool->emit_pool_after = get_last_insn ();
8677
c2c1332a 8678 return pool;
8679}
8680
8681/* POOL holds the main literal pool as collected by s390_mainpool_start.
8682 Modify the current function to output the pool constants as well as
20074f87 8683 the pool register setup instruction. */
c2c1332a 8684
8685static void
20074f87 8686s390_mainpool_finish (struct constant_pool *pool)
c2c1332a 8687{
4fed3f99 8688 rtx base_reg = cfun->machine->base_reg;
c2c1332a 8689
8690 /* If the pool is empty, we're done. */
8691 if (pool->size == 0)
8692 {
4fed3f99 8693 /* We don't actually need a base register after all. */
8694 cfun->machine->base_reg = NULL_RTX;
8695
8696 if (pool->pool_insn)
8697 remove_insn (pool->pool_insn);
c2c1332a 8698 s390_free_pool (pool);
8699 return;
8700 }
8701
8702 /* We need correct insn addresses. */
8703 shorten_branches (get_insns ());
8704
dafc8d45 8705 /* On zSeries, we use a LARL to load the pool register. The pool is
c2c1332a 8706 located in the .rodata section, so we emit it after the function. */
dafc8d45 8707 if (TARGET_CPU_ZARCH)
c2c1332a 8708 {
ed7591be 8709 rtx set = gen_main_base_64 (base_reg, pool->label);
8710 rtx_insn *insn = emit_insn_after (set, pool->pool_insn);
c2c1332a 8711 INSN_ADDRESSES_NEW (insn, -1);
8712 remove_insn (pool->pool_insn);
f588eb9f 8713
8714 insn = get_last_insn ();
c2c1332a 8715 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
8716 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
8717
8718 s390_dump_pool (pool, 0);
8719 }
8720
dafc8d45 8721 /* On S/390, if the total size of the function's code plus literal pool
c2c1332a 8722 does not exceed 4096 bytes, we use BASR to set up a function base
8723 pointer, and emit the literal pool at the end of the function. */
86428198 8724 else if (INSN_ADDRESSES (INSN_UID (pool->emit_pool_after))
c2c1332a 8725 + pool->size + 8 /* alignment slop */ < 4096)
8726 {
ed7591be 8727 rtx set = gen_main_base_31_small (base_reg, pool->label);
8728 rtx_insn *insn = emit_insn_after (set, pool->pool_insn);
c2c1332a 8729 INSN_ADDRESSES_NEW (insn, -1);
8730 remove_insn (pool->pool_insn);
8731
8732 insn = emit_label_after (pool->label, insn);
8733 INSN_ADDRESSES_NEW (insn, -1);
8734
86428198 8735 /* emit_pool_after will be set by s390_mainpool_start to the
8736 last insn of the section where the literal pool should be
8737 emitted. */
8738 insn = pool->emit_pool_after;
8739
c2c1332a 8740 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
8741 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
8742
8743 s390_dump_pool (pool, 1);
8744 }
8745
8746 /* Otherwise, we emit an inline literal pool and use BASR to branch
8747 over it, setting up the pool register at the same time. */
8748 else
8749 {
ed7591be 8750 rtx_code_label *pool_end = gen_label_rtx ();
c2c1332a 8751
ed7591be 8752 rtx pat = gen_main_base_31_large (base_reg, pool->label, pool_end);
8753 rtx_insn *insn = emit_jump_insn_after (pat, pool->pool_insn);
12f0f6d7 8754 JUMP_LABEL (insn) = pool_end;
c2c1332a 8755 INSN_ADDRESSES_NEW (insn, -1);
8756 remove_insn (pool->pool_insn);
8757
8758 insn = emit_label_after (pool->label, insn);
8759 INSN_ADDRESSES_NEW (insn, -1);
8760
8761 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
8762 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
8763
8764 insn = emit_label_after (pool_end, pool->pool_insn);
8765 INSN_ADDRESSES_NEW (insn, -1);
8766
8767 s390_dump_pool (pool, 1);
8768 }
8769
8770
8771 /* Replace all literal pool references. */
8772
91a55c11 8773 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
c2c1332a 8774 {
8775 if (INSN_P (insn))
20074f87 8776 replace_ltrel_base (&PATTERN (insn));
c2c1332a 8777
aa90bb35 8778 if (NONJUMP_INSN_P (insn) || CALL_P (insn))
c2c1332a 8779 {
8780 rtx addr, pool_ref = NULL_RTX;
8781 find_constant_pool_ref (PATTERN (insn), &pool_ref);
8782 if (pool_ref)
8783 {
d345b493 8784 if (s390_execute_label (insn))
8785 addr = s390_find_execute (pool, insn);
8786 else
8787 addr = s390_find_constant (pool, get_pool_constant (pool_ref),
8788 get_pool_mode (pool_ref));
8789
c2c1332a 8790 replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
8791 INSN_CODE (insn) = -1;
8792 }
8793 }
8794 }
8795
8796
8797 /* Free the pool. */
8798 s390_free_pool (pool);
8799}
8800
8801/* POOL holds the main literal pool as collected by s390_mainpool_start.
8802 We have decided we cannot use this pool, so revert all changes
8803 to the current function that were done by s390_mainpool_start. */
8804static void
8805s390_mainpool_cancel (struct constant_pool *pool)
8806{
8807 /* We didn't actually change the instruction stream, so simply
8808 free the pool memory. */
8809 s390_free_pool (pool);
8810}
8811
8812
20074f87 8813/* Chunkify the literal pool. */
4673c1a0 8814
0756cebb 8815#define S390_POOL_CHUNK_MIN 0xc00
8816#define S390_POOL_CHUNK_MAX 0xe00
8817
f81e845f 8818static struct constant_pool *
20074f87 8819s390_chunkify_start (void)
4673c1a0 8820{
0756cebb 8821 struct constant_pool *curr_pool = NULL, *pool_list = NULL;
8822 int extra_size = 0;
8823 bitmap far_labels;
12ef3745 8824 rtx pending_ltrel = NULL_RTX;
93e0956b 8825 rtx_insn *insn;
4673c1a0 8826
b40da9a7 8827 rtx (*gen_reload_base) (rtx, rtx) =
dafc8d45 8828 TARGET_CPU_ZARCH? gen_reload_base_64 : gen_reload_base_31;
96be3ab6 8829
8830
9a2a66ae 8831 /* We need correct insn addresses. */
8832
8833 shorten_branches (get_insns ());
8834
12ef3745 8835 /* Scan all insns and move literals to pool chunks. */
479ca6e8 8836
479ca6e8 8837 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4673c1a0 8838 {
86428198 8839 bool section_switch_p = false;
8840
12ef3745 8841 /* Check for pending LTREL_BASE. */
8842 if (INSN_P (insn))
8843 {
8844 rtx ltrel_base = find_ltrel_base (PATTERN (insn));
8845 if (ltrel_base)
8846 {
32eda510 8847 gcc_assert (ltrel_base == pending_ltrel);
8848 pending_ltrel = NULL_RTX;
12ef3745 8849 }
8850 }
8851
babfdedf 8852 if (!TARGET_CPU_ZARCH && s390_execute_label (insn))
d345b493 8853 {
8854 if (!curr_pool)
8855 curr_pool = s390_start_pool (&pool_list, insn);
8856
8857 s390_add_execute (curr_pool, insn);
8858 s390_add_pool_insn (curr_pool, insn);
8859 }
aa90bb35 8860 else if (NONJUMP_INSN_P (insn) || CALL_P (insn))
0756cebb 8861 {
96be3ab6 8862 rtx pool_ref = NULL_RTX;
0756cebb 8863 find_constant_pool_ref (PATTERN (insn), &pool_ref);
8864 if (pool_ref)
8865 {
12ef3745 8866 rtx constant = get_pool_constant (pool_ref);
3754d046 8867 machine_mode mode = get_pool_mode (pool_ref);
12ef3745 8868
0756cebb 8869 if (!curr_pool)
8870 curr_pool = s390_start_pool (&pool_list, insn);
8871
12ef3745 8872 s390_add_constant (curr_pool, constant, mode);
96be3ab6 8873 s390_add_pool_insn (curr_pool, insn);
96be3ab6 8874
12ef3745 8875 /* Don't split the pool chunk between a LTREL_OFFSET load
8876 and the corresponding LTREL_BASE. */
8877 if (GET_CODE (constant) == CONST
8878 && GET_CODE (XEXP (constant, 0)) == UNSPEC
8879 && XINT (XEXP (constant, 0), 1) == UNSPEC_LTREL_OFFSET)
8880 {
32eda510 8881 gcc_assert (!pending_ltrel);
12ef3745 8882 pending_ltrel = pool_ref;
8883 }
0756cebb 8884 }
8885 }
8886
91f71fa3 8887 if (JUMP_P (insn) || JUMP_TABLE_DATA_P (insn) || LABEL_P (insn))
12ef3745 8888 {
8889 if (curr_pool)
8890 s390_add_pool_insn (curr_pool, insn);
8891 /* An LTREL_BASE must follow within the same basic block. */
32eda510 8892 gcc_assert (!pending_ltrel);
12ef3745 8893 }
96be3ab6 8894
414bc417 8895 if (NOTE_P (insn))
8896 switch (NOTE_KIND (insn))
8897 {
8898 case NOTE_INSN_SWITCH_TEXT_SECTIONS:
8899 section_switch_p = true;
8900 break;
8901 case NOTE_INSN_VAR_LOCATION:
8902 case NOTE_INSN_CALL_ARG_LOCATION:
8903 continue;
8904 default:
8905 break;
8906 }
86428198 8907
f81e845f 8908 if (!curr_pool
0756cebb 8909 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn)
8910 || INSN_ADDRESSES (INSN_UID (insn)) == -1)
4673c1a0 8911 continue;
479ca6e8 8912
dafc8d45 8913 if (TARGET_CPU_ZARCH)
4673c1a0 8914 {
0756cebb 8915 if (curr_pool->size < S390_POOL_CHUNK_MAX)
8916 continue;
479ca6e8 8917
93e0956b 8918 s390_end_pool (curr_pool, NULL);
0756cebb 8919 curr_pool = NULL;
8920 }
8921 else
4673c1a0 8922 {
0756cebb 8923 int chunk_size = INSN_ADDRESSES (INSN_UID (insn))
b40da9a7 8924 - INSN_ADDRESSES (INSN_UID (curr_pool->first_insn))
0756cebb 8925 + extra_size;
8926
8927 /* We will later have to insert base register reload insns.
8928 Those will have an effect on code size, which we need to
8929 consider here. This calculation makes rather pessimistic
8930 worst-case assumptions. */
aa90bb35 8931 if (LABEL_P (insn))
0756cebb 8932 extra_size += 6;
0756cebb 8933
8934 if (chunk_size < S390_POOL_CHUNK_MIN
86428198 8935 && curr_pool->size < S390_POOL_CHUNK_MIN
8936 && !section_switch_p)
0756cebb 8937 continue;
8938
8939 /* Pool chunks can only be inserted after BARRIERs ... */
aa90bb35 8940 if (BARRIER_P (insn))
0756cebb 8941 {
8942 s390_end_pool (curr_pool, insn);
8943 curr_pool = NULL;
8944 extra_size = 0;
8945 }
8946
8947 /* ... so if we don't find one in time, create one. */
86428198 8948 else if (chunk_size > S390_POOL_CHUNK_MAX
8949 || curr_pool->size > S390_POOL_CHUNK_MAX
8950 || section_switch_p)
0756cebb 8951 {
93e0956b 8952 rtx_insn *label, *jump, *barrier, *next, *prev;
0756cebb 8953
86428198 8954 if (!section_switch_p)
8955 {
8956 /* We can insert the barrier only after a 'real' insn. */
aa90bb35 8957 if (! NONJUMP_INSN_P (insn) && ! CALL_P (insn))
86428198 8958 continue;
8959 if (get_attr_length (insn) == 0)
8960 continue;
8961 /* Don't separate LTREL_BASE from the corresponding
414bc417 8962 LTREL_OFFSET load. */
86428198 8963 if (pending_ltrel)
8964 continue;
414bc417 8965 next = insn;
8966 do
8967 {
8968 insn = next;
8969 next = NEXT_INSN (insn);
8970 }
8971 while (next
8972 && NOTE_P (next)
8973 && (NOTE_KIND (next) == NOTE_INSN_VAR_LOCATION
8974 || NOTE_KIND (next) == NOTE_INSN_CALL_ARG_LOCATION));
86428198 8975 }
8976 else
8977 {
8978 gcc_assert (!pending_ltrel);
8979
8980 /* The old pool has to end before the section switch
8981 note in order to make it part of the current
8982 section. */
8983 insn = PREV_INSN (insn);
8984 }
96be3ab6 8985
b40da9a7 8986 label = gen_label_rtx ();
414bc417 8987 prev = insn;
8988 if (prev && NOTE_P (prev))
8989 prev = prev_nonnote_insn (prev);
8990 if (prev)
8991 jump = emit_jump_insn_after_setloc (gen_jump (label), insn,
d53c050c 8992 INSN_LOCATION (prev));
414bc417 8993 else
8994 jump = emit_jump_insn_after_noloc (gen_jump (label), insn);
0756cebb 8995 barrier = emit_barrier_after (jump);
8996 insn = emit_label_after (label, barrier);
8997 JUMP_LABEL (jump) = label;
8998 LABEL_NUSES (label) = 1;
8999
96be3ab6 9000 INSN_ADDRESSES_NEW (jump, -1);
9001 INSN_ADDRESSES_NEW (barrier, -1);
0756cebb 9002 INSN_ADDRESSES_NEW (insn, -1);
9003
9004 s390_end_pool (curr_pool, barrier);
9005 curr_pool = NULL;
9006 extra_size = 0;
9007 }
479ca6e8 9008 }
4673c1a0 9009 }
9fa6d5d9 9010
96be3ab6 9011 if (curr_pool)
93e0956b 9012 s390_end_pool (curr_pool, NULL);
32eda510 9013 gcc_assert (!pending_ltrel);
0756cebb 9014
f81e845f 9015 /* Find all labels that are branched into
479ca6e8 9016 from an insn belonging to a different chunk. */
9fa6d5d9 9017
4d6e8511 9018 far_labels = BITMAP_ALLOC (NULL);
a8ef833a 9019
479ca6e8 9020 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4673c1a0 9021 {
c86d86ff 9022 rtx_jump_table_data *table;
245402e7 9023
0756cebb 9024 /* Labels marked with LABEL_PRESERVE_P can be target
9025 of non-local jumps, so we have to mark them.
9026 The same holds for named labels.
9027
9028 Don't do that, however, if it is the label before
9029 a jump table. */
9030
aa90bb35 9031 if (LABEL_P (insn)
0756cebb 9032 && (LABEL_PRESERVE_P (insn) || LABEL_NAME (insn)))
9033 {
93e0956b 9034 rtx_insn *vec_insn = NEXT_INSN (insn);
77985f1a 9035 if (! vec_insn || ! JUMP_TABLE_DATA_P (vec_insn))
0756cebb 9036 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (insn));
9037 }
245402e7 9038 /* Check potential targets in a table jump (casesi_jump). */
9039 else if (tablejump_p (insn, NULL, &table))
9040 {
9041 rtx vec_pat = PATTERN (table);
9042 int i, diff_p = GET_CODE (vec_pat) == ADDR_DIFF_VEC;
9043
9044 for (i = 0; i < XVECLEN (vec_pat, diff_p); i++)
9045 {
9046 rtx label = XEXP (XVECEXP (vec_pat, diff_p, i), 0);
0756cebb 9047
245402e7 9048 if (s390_find_pool (pool_list, label)
9049 != s390_find_pool (pool_list, insn))
9050 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
9051 }
9052 }
9053 /* If we have a direct jump (conditional or unconditional),
9054 check all potential targets. */
aa90bb35 9055 else if (JUMP_P (insn))
479ca6e8 9056 {
245402e7 9057 rtx pat = PATTERN (insn);
0cd9a9a9 9058
245402e7 9059 if (GET_CODE (pat) == PARALLEL)
3c482144 9060 pat = XVECEXP (pat, 0, 0);
9061
245402e7 9062 if (GET_CODE (pat) == SET)
9063 {
96be3ab6 9064 rtx label = JUMP_LABEL (insn);
7a64c761 9065 if (label && !ANY_RETURN_P (label))
479ca6e8 9066 {
245402e7 9067 if (s390_find_pool (pool_list, label)
0756cebb 9068 != s390_find_pool (pool_list, insn))
9069 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
479ca6e8 9070 }
0756cebb 9071 }
245402e7 9072 }
4673c1a0 9073 }
9fa6d5d9 9074
0756cebb 9075 /* Insert base register reload insns before every pool. */
9076
9077 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
96be3ab6 9078 {
ffead1ca 9079 rtx new_insn = gen_reload_base (cfun->machine->base_reg,
20074f87 9080 curr_pool->label);
93e0956b 9081 rtx_insn *insn = curr_pool->first_insn;
96be3ab6 9082 INSN_ADDRESSES_NEW (emit_insn_before (new_insn, insn), -1);
9083 }
0756cebb 9084
9085 /* Insert base register reload insns at every far label. */
479ca6e8 9086
479ca6e8 9087 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
aa90bb35 9088 if (LABEL_P (insn)
0756cebb 9089 && bitmap_bit_p (far_labels, CODE_LABEL_NUMBER (insn)))
9090 {
9091 struct constant_pool *pool = s390_find_pool (pool_list, insn);
9092 if (pool)
9093 {
ffead1ca 9094 rtx new_insn = gen_reload_base (cfun->machine->base_reg,
20074f87 9095 pool->label);
96be3ab6 9096 INSN_ADDRESSES_NEW (emit_insn_after (new_insn, insn), -1);
0756cebb 9097 }
9098 }
9099
96be3ab6 9100
4d6e8511 9101 BITMAP_FREE (far_labels);
479ca6e8 9102
479ca6e8 9103
9104 /* Recompute insn addresses. */
9105
9106 init_insn_lengths ();
9107 shorten_branches (get_insns ());
4673c1a0 9108
96be3ab6 9109 return pool_list;
9110}
4673c1a0 9111
96be3ab6 9112/* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
f81e845f 9113 After we have decided to use this list, finish implementing
20074f87 9114 all changes to the current function as required. */
f81e845f 9115
96be3ab6 9116static void
20074f87 9117s390_chunkify_finish (struct constant_pool *pool_list)
96be3ab6 9118{
96be3ab6 9119 struct constant_pool *curr_pool = NULL;
93e0956b 9120 rtx_insn *insn;
f81e845f 9121
9122
96be3ab6 9123 /* Replace all literal pool references. */
9124
f81e845f 9125 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
96be3ab6 9126 {
12ef3745 9127 if (INSN_P (insn))
20074f87 9128 replace_ltrel_base (&PATTERN (insn));
12ef3745 9129
96be3ab6 9130 curr_pool = s390_find_pool (pool_list, insn);
9131 if (!curr_pool)
9132 continue;
9133
aa90bb35 9134 if (NONJUMP_INSN_P (insn) || CALL_P (insn))
96be3ab6 9135 {
9136 rtx addr, pool_ref = NULL_RTX;
9137 find_constant_pool_ref (PATTERN (insn), &pool_ref);
9138 if (pool_ref)
9139 {
d345b493 9140 if (s390_execute_label (insn))
9141 addr = s390_find_execute (curr_pool, insn);
9142 else
9143 addr = s390_find_constant (curr_pool,
9144 get_pool_constant (pool_ref),
9145 get_pool_mode (pool_ref));
9146
96be3ab6 9147 replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
9148 INSN_CODE (insn) = -1;
9149 }
96be3ab6 9150 }
9151 }
9152
9153 /* Dump out all literal pools. */
f81e845f 9154
96be3ab6 9155 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
c2c1332a 9156 s390_dump_pool (curr_pool, 0);
f81e845f 9157
96be3ab6 9158 /* Free pool list. */
9159
9160 while (pool_list)
9161 {
9162 struct constant_pool *next = pool_list->next;
9163 s390_free_pool (pool_list);
9164 pool_list = next;
9165 }
9166}
9167
9168/* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
9169 We have decided we cannot use this list, so revert all changes
9170 to the current function that were done by s390_chunkify_start. */
f81e845f 9171
96be3ab6 9172static void
b40da9a7 9173s390_chunkify_cancel (struct constant_pool *pool_list)
96be3ab6 9174{
9175 struct constant_pool *curr_pool = NULL;
93e0956b 9176 rtx_insn *insn;
96be3ab6 9177
9178 /* Remove all pool placeholder insns. */
9179
9180 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
9181 {
9182 /* Did we insert an extra barrier? Remove it. */
93e0956b 9183 rtx_insn *barrier = PREV_INSN (curr_pool->pool_insn);
9184 rtx_insn *jump = barrier? PREV_INSN (barrier) : NULL;
9185 rtx_insn *label = NEXT_INSN (curr_pool->pool_insn);
96be3ab6 9186
aa90bb35 9187 if (jump && JUMP_P (jump)
9188 && barrier && BARRIER_P (barrier)
9189 && label && LABEL_P (label)
96be3ab6 9190 && GET_CODE (PATTERN (jump)) == SET
9191 && SET_DEST (PATTERN (jump)) == pc_rtx
9192 && GET_CODE (SET_SRC (PATTERN (jump))) == LABEL_REF
9193 && XEXP (SET_SRC (PATTERN (jump)), 0) == label)
9194 {
9195 remove_insn (jump);
9196 remove_insn (barrier);
9197 remove_insn (label);
0756cebb 9198 }
4673c1a0 9199
96be3ab6 9200 remove_insn (curr_pool->pool_insn);
9201 }
9202
12ef3745 9203 /* Remove all base register reload insns. */
96be3ab6 9204
9205 for (insn = get_insns (); insn; )
9206 {
93e0956b 9207 rtx_insn *next_insn = NEXT_INSN (insn);
96be3ab6 9208
aa90bb35 9209 if (NONJUMP_INSN_P (insn)
96be3ab6 9210 && GET_CODE (PATTERN (insn)) == SET
9211 && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC
12ef3745 9212 && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPEC_RELOAD_BASE)
96be3ab6 9213 remove_insn (insn);
4673c1a0 9214
96be3ab6 9215 insn = next_insn;
9216 }
9217
9218 /* Free pool list. */
4673c1a0 9219
0756cebb 9220 while (pool_list)
4673c1a0 9221 {
0756cebb 9222 struct constant_pool *next = pool_list->next;
9223 s390_free_pool (pool_list);
9224 pool_list = next;
4673c1a0 9225 }
4673c1a0 9226}
9227
74d2529d 9228/* Output the constant pool entry EXP in mode MODE with alignment ALIGN. */
df82fb76 9229
9230void
3754d046 9231s390_output_pool_entry (rtx exp, machine_mode mode, unsigned int align)
df82fb76 9232{
df82fb76 9233 switch (GET_MODE_CLASS (mode))
9234 {
9235 case MODE_FLOAT:
36868490 9236 case MODE_DECIMAL_FLOAT:
32eda510 9237 gcc_assert (GET_CODE (exp) == CONST_DOUBLE);
df82fb76 9238
945f7b03 9239 assemble_real (*CONST_DOUBLE_REAL_VALUE (exp), mode, align);
df82fb76 9240 break;
9241
9242 case MODE_INT:
74d2529d 9243 assemble_integer (exp, GET_MODE_SIZE (mode), align, 1);
af2a449c 9244 mark_symbol_refs_as_used (exp);
df82fb76 9245 break;
9246
76a4c804 9247 case MODE_VECTOR_INT:
9248 case MODE_VECTOR_FLOAT:
9249 {
9250 int i;
9251 machine_mode inner_mode;
9252 gcc_assert (GET_CODE (exp) == CONST_VECTOR);
9253
9254 inner_mode = GET_MODE_INNER (GET_MODE (exp));
9255 for (i = 0; i < XVECLEN (exp, 0); i++)
9256 s390_output_pool_entry (XVECEXP (exp, 0, i),
9257 inner_mode,
9258 i == 0
9259 ? align
9260 : GET_MODE_BITSIZE (inner_mode));
9261 }
9262 break;
9263
df82fb76 9264 default:
32eda510 9265 gcc_unreachable ();
df82fb76 9266 }
9267}
9268
9269
875862bf 9270/* Return an RTL expression representing the value of the return address
9271 for the frame COUNT steps up from the current frame. FRAME is the
9272 frame pointer of that frame. */
0756cebb 9273
875862bf 9274rtx
9275s390_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
0756cebb 9276{
875862bf 9277 int offset;
9278 rtx addr;
96be3ab6 9279
875862bf 9280 /* Without backchain, we fail for all but the current frame. */
9a2a66ae 9281
875862bf 9282 if (!TARGET_BACKCHAIN && count > 0)
9283 return NULL_RTX;
9a2a66ae 9284
875862bf 9285 /* For the current frame, we need to make sure the initial
9286 value of RETURN_REGNUM is actually saved. */
9a2a66ae 9287
875862bf 9288 if (count == 0)
9a2a66ae 9289 {
1e639cb0 9290 /* On non-z architectures branch splitting could overwrite r14. */
9291 if (TARGET_CPU_ZARCH)
9292 return get_hard_reg_initial_val (Pmode, RETURN_REGNUM);
9293 else
9294 {
9295 cfun_frame_layout.save_return_addr_p = true;
9296 return gen_rtx_MEM (Pmode, return_address_pointer_rtx);
9297 }
875862bf 9298 }
9a2a66ae 9299
875862bf 9300 if (TARGET_PACKED_STACK)
b5fdc416 9301 offset = -2 * UNITS_PER_LONG;
875862bf 9302 else
b5fdc416 9303 offset = RETURN_REGNUM * UNITS_PER_LONG;
9a2a66ae 9304
29c05e22 9305 addr = plus_constant (Pmode, frame, offset);
875862bf 9306 addr = memory_address (Pmode, addr);
9307 return gen_rtx_MEM (Pmode, addr);
9308}
9a2a66ae 9309
875862bf 9310/* Return an RTL expression representing the back chain stored in
9311 the current stack frame. */
5fe74ca1 9312
875862bf 9313rtx
9314s390_back_chain_rtx (void)
9315{
9316 rtx chain;
5fe74ca1 9317
875862bf 9318 gcc_assert (TARGET_BACKCHAIN);
5fe74ca1 9319
875862bf 9320 if (TARGET_PACKED_STACK)
29c05e22 9321 chain = plus_constant (Pmode, stack_pointer_rtx,
b5fdc416 9322 STACK_POINTER_OFFSET - UNITS_PER_LONG);
875862bf 9323 else
9324 chain = stack_pointer_rtx;
5fe74ca1 9325
875862bf 9326 chain = gen_rtx_MEM (Pmode, chain);
9327 return chain;
9328}
9a2a66ae 9329
875862bf 9330/* Find first call clobbered register unused in a function.
9331 This could be used as base register in a leaf function
9332 or for holding the return address before epilogue. */
9a2a66ae 9333
875862bf 9334static int
9335find_unused_clobbered_reg (void)
9336{
9337 int i;
9338 for (i = 0; i < 6; i++)
3072d30e 9339 if (!df_regs_ever_live_p (i))
875862bf 9340 return i;
9341 return 0;
9342}
9a2a66ae 9343
1e639cb0 9344
ffead1ca 9345/* Helper function for s390_regs_ever_clobbered. Sets the fields in DATA for all
1e639cb0 9346 clobbered hard regs in SETREG. */
9347
9348static void
81a410b1 9349s390_reg_clobbered_rtx (rtx setreg, const_rtx set_insn ATTRIBUTE_UNUSED, void *data)
1e639cb0 9350{
ff4ce128 9351 char *regs_ever_clobbered = (char *)data;
1e639cb0 9352 unsigned int i, regno;
3754d046 9353 machine_mode mode = GET_MODE (setreg);
1e639cb0 9354
9355 if (GET_CODE (setreg) == SUBREG)
9356 {
9357 rtx inner = SUBREG_REG (setreg);
5ada7a14 9358 if (!GENERAL_REG_P (inner) && !FP_REG_P (inner))
1e639cb0 9359 return;
9360 regno = subreg_regno (setreg);
9361 }
5ada7a14 9362 else if (GENERAL_REG_P (setreg) || FP_REG_P (setreg))
1e639cb0 9363 regno = REGNO (setreg);
9364 else
9365 return;
9366
9367 for (i = regno;
9368 i < regno + HARD_REGNO_NREGS (regno, mode);
9369 i++)
9370 regs_ever_clobbered[i] = 1;
9371}
9372
9373/* Walks through all basic blocks of the current function looking
9374 for clobbered hard regs using s390_reg_clobbered_rtx. The fields
9375 of the passed integer array REGS_EVER_CLOBBERED are set to one for
9376 each of those regs. */
9377
9378static void
ff4ce128 9379s390_regs_ever_clobbered (char regs_ever_clobbered[])
1e639cb0 9380{
9381 basic_block cur_bb;
93e0956b 9382 rtx_insn *cur_insn;
1e639cb0 9383 unsigned int i;
9384
ff4ce128 9385 memset (regs_ever_clobbered, 0, 32);
1e639cb0 9386
9387 /* For non-leaf functions we have to consider all call clobbered regs to be
9388 clobbered. */
d5bf7b64 9389 if (!crtl->is_leaf)
1e639cb0 9390 {
5ada7a14 9391 for (i = 0; i < 32; i++)
1e639cb0 9392 regs_ever_clobbered[i] = call_really_used_regs[i];
9393 }
9394
9395 /* Make the "magic" eh_return registers live if necessary. For regs_ever_live
9396 this work is done by liveness analysis (mark_regs_live_at_end).
9397 Special care is needed for functions containing landing pads. Landing pads
9398 may use the eh registers, but the code which sets these registers is not
9399 contained in that function. Hence s390_regs_ever_clobbered is not able to
9400 deal with this automatically. */
18d50ae6 9401 if (crtl->calls_eh_return || cfun->machine->has_landing_pad_p)
1e639cb0 9402 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM ; i++)
ffead1ca 9403 if (crtl->calls_eh_return
9404 || (cfun->machine->has_landing_pad_p
3072d30e 9405 && df_regs_ever_live_p (EH_RETURN_DATA_REGNO (i))))
220be973 9406 regs_ever_clobbered[EH_RETURN_DATA_REGNO (i)] = 1;
1e639cb0 9407
9408 /* For nonlocal gotos all call-saved registers have to be saved.
9409 This flag is also set for the unwinding code in libgcc.
9410 See expand_builtin_unwind_init. For regs_ever_live this is done by
9411 reload. */
ff4ce128 9412 if (crtl->saves_all_registers)
5ada7a14 9413 for (i = 0; i < 32; i++)
1e639cb0 9414 if (!call_really_used_regs[i])
9415 regs_ever_clobbered[i] = 1;
9416
fc00614f 9417 FOR_EACH_BB_FN (cur_bb, cfun)
1e639cb0 9418 {
9419 FOR_BB_INSNS (cur_bb, cur_insn)
9420 {
ff4ce128 9421 rtx pat;
9422
9423 if (!INSN_P (cur_insn))
9424 continue;
9425
9426 pat = PATTERN (cur_insn);
9427
9428 /* Ignore GPR restore insns. */
9429 if (epilogue_completed && RTX_FRAME_RELATED_P (cur_insn))
9430 {
9431 if (GET_CODE (pat) == SET
9432 && GENERAL_REG_P (SET_DEST (pat)))
9433 {
9434 /* lgdr */
9435 if (GET_MODE (SET_SRC (pat)) == DImode
9436 && FP_REG_P (SET_SRC (pat)))
9437 continue;
9438
9439 /* l / lg */
9440 if (GET_CODE (SET_SRC (pat)) == MEM)
9441 continue;
9442 }
9443
9444 /* lm / lmg */
9445 if (GET_CODE (pat) == PARALLEL
9446 && load_multiple_operation (pat, VOIDmode))
9447 continue;
9448 }
9449
9450 note_stores (pat,
9451 s390_reg_clobbered_rtx,
9452 regs_ever_clobbered);
1e639cb0 9453 }
9454 }
9455}
9456
ffead1ca 9457/* Determine the frame area which actually has to be accessed
9458 in the function epilogue. The values are stored at the
875862bf 9459 given pointers AREA_BOTTOM (address of the lowest used stack
ffead1ca 9460 address) and AREA_TOP (address of the first item which does
875862bf 9461 not belong to the stack frame). */
5fe74ca1 9462
875862bf 9463static void
9464s390_frame_area (int *area_bottom, int *area_top)
9465{
9466 int b, t;
5fe74ca1 9467
875862bf 9468 b = INT_MAX;
9469 t = INT_MIN;
67928721 9470
9471 if (cfun_frame_layout.first_restore_gpr != -1)
9472 {
9473 b = (cfun_frame_layout.gprs_offset
b5fdc416 9474 + cfun_frame_layout.first_restore_gpr * UNITS_PER_LONG);
67928721 9475 t = b + (cfun_frame_layout.last_restore_gpr
b5fdc416 9476 - cfun_frame_layout.first_restore_gpr + 1) * UNITS_PER_LONG;
67928721 9477 }
9478
9479 if (TARGET_64BIT && cfun_save_high_fprs_p)
9480 {
9481 b = MIN (b, cfun_frame_layout.f8_offset);
9482 t = MAX (t, (cfun_frame_layout.f8_offset
9483 + cfun_frame_layout.high_fprs * 8));
9484 }
9485
9486 if (!TARGET_64BIT)
29439367 9487 {
6a2469fe 9488 if (cfun_fpr_save_p (FPR4_REGNUM))
67928721 9489 {
29439367 9490 b = MIN (b, cfun_frame_layout.f4_offset);
9491 t = MAX (t, cfun_frame_layout.f4_offset + 8);
67928721 9492 }
6a2469fe 9493 if (cfun_fpr_save_p (FPR6_REGNUM))
29439367 9494 {
9495 b = MIN (b, cfun_frame_layout.f4_offset + 8);
9496 t = MAX (t, cfun_frame_layout.f4_offset + 16);
9497 }
9498 }
67928721 9499 *area_bottom = b;
9500 *area_top = t;
9501}
ff4ce128 9502/* Update gpr_save_slots in the frame layout trying to make use of
9503 FPRs as GPR save slots.
9504 This is a helper routine of s390_register_info. */
8b4a4127 9505
9506static void
ff4ce128 9507s390_register_info_gprtofpr ()
8b4a4127 9508{
ff4ce128 9509 int save_reg_slot = FPR0_REGNUM;
8b4a4127 9510 int i, j;
8b4a4127 9511
ff4ce128 9512 if (!TARGET_Z10 || !TARGET_HARD_FLOAT || !crtl->is_leaf)
9513 return;
1e639cb0 9514
ff4ce128 9515 for (i = 15; i >= 6; i--)
5ada7a14 9516 {
1d3cea74 9517 if (cfun_gpr_save_slot (i) == SAVE_SLOT_NONE)
ff4ce128 9518 continue;
68bc0408 9519
ff4ce128 9520 /* Advance to the next FP register which can be used as a
9521 GPR save slot. */
9522 while ((!call_really_used_regs[save_reg_slot]
9523 || df_regs_ever_live_p (save_reg_slot)
9524 || cfun_fpr_save_p (save_reg_slot))
9525 && FP_REGNO_P (save_reg_slot))
9526 save_reg_slot++;
9527 if (!FP_REGNO_P (save_reg_slot))
9528 {
9529 /* We only want to use ldgr/lgdr if we can get rid of
9530 stm/lm entirely. So undo the gpr slot allocation in
9531 case we ran out of FPR save slots. */
9532 for (j = 6; j <= 15; j++)
9533 if (FP_REGNO_P (cfun_gpr_save_slot (j)))
1d3cea74 9534 cfun_gpr_save_slot (j) = SAVE_SLOT_STACK;
ff4ce128 9535 break;
68bc0408 9536 }
ff4ce128 9537 cfun_gpr_save_slot (i) = save_reg_slot++;
5ada7a14 9538 }
ff4ce128 9539}
5ada7a14 9540
ff4ce128 9541/* Set the bits in fpr_bitmap for FPRs which need to be saved due to
9542 stdarg.
9543 This is a helper routine for s390_register_info. */
1e639cb0 9544
ff4ce128 9545static void
9546s390_register_info_stdarg_fpr ()
9547{
9548 int i;
9549 int min_fpr;
9550 int max_fpr;
9551
9552 /* Save the FP argument regs for stdarg. f0, f2 for 31 bit and
9553 f0-f4 for 64 bit. */
9554 if (!cfun->stdarg
9555 || !TARGET_HARD_FLOAT
9556 || !cfun->va_list_fpr_size
9557 || crtl->args.info.fprs >= FP_ARG_NUM_REG)
9558 return;
9559
9560 min_fpr = crtl->args.info.fprs;
1d3cea74 9561 max_fpr = min_fpr + cfun->va_list_fpr_size - 1;
9562 if (max_fpr >= FP_ARG_NUM_REG)
9563 max_fpr = FP_ARG_NUM_REG - 1;
ff4ce128 9564
1d3cea74 9565 /* FPR argument regs start at f0. */
9566 min_fpr += FPR0_REGNUM;
9567 max_fpr += FPR0_REGNUM;
9568
9569 for (i = min_fpr; i <= max_fpr; i++)
9570 cfun_set_fpr_save (i);
ff4ce128 9571}
9572
9573/* Reserve the GPR save slots for GPRs which need to be saved due to
9574 stdarg.
9575 This is a helper routine for s390_register_info. */
9576
9577static void
9578s390_register_info_stdarg_gpr ()
9579{
9580 int i;
9581 int min_gpr;
9582 int max_gpr;
9583
9584 if (!cfun->stdarg
9585 || !cfun->va_list_gpr_size
9586 || crtl->args.info.gprs >= GP_ARG_NUM_REG)
9587 return;
9588
9589 min_gpr = crtl->args.info.gprs;
1d3cea74 9590 max_gpr = min_gpr + cfun->va_list_gpr_size - 1;
9591 if (max_gpr >= GP_ARG_NUM_REG)
9592 max_gpr = GP_ARG_NUM_REG - 1;
9593
9594 /* GPR argument regs start at r2. */
9595 min_gpr += GPR2_REGNUM;
9596 max_gpr += GPR2_REGNUM;
9597
9598 /* If r6 was supposed to be saved into an FPR and now needs to go to
9599 the stack for vararg we have to adjust the restore range to make
9600 sure that the restore is done from stack as well. */
9601 if (FP_REGNO_P (cfun_gpr_save_slot (GPR6_REGNUM))
9602 && min_gpr <= GPR6_REGNUM
9603 && max_gpr >= GPR6_REGNUM)
9604 {
9605 if (cfun_frame_layout.first_restore_gpr == -1
9606 || cfun_frame_layout.first_restore_gpr > GPR6_REGNUM)
9607 cfun_frame_layout.first_restore_gpr = GPR6_REGNUM;
9608 if (cfun_frame_layout.last_restore_gpr == -1
9609 || cfun_frame_layout.last_restore_gpr < GPR6_REGNUM)
9610 cfun_frame_layout.last_restore_gpr = GPR6_REGNUM;
9611 }
9612
9613 if (cfun_frame_layout.first_save_gpr == -1
9614 || cfun_frame_layout.first_save_gpr > min_gpr)
9615 cfun_frame_layout.first_save_gpr = min_gpr;
9616
9617 if (cfun_frame_layout.last_save_gpr == -1
9618 || cfun_frame_layout.last_save_gpr < max_gpr)
9619 cfun_frame_layout.last_save_gpr = max_gpr;
9620
9621 for (i = min_gpr; i <= max_gpr; i++)
9622 cfun_gpr_save_slot (i) = SAVE_SLOT_STACK;
9623}
9624
9625/* Calculate the save and restore ranges for stm(g) and lm(g) in the
9626 prologue and epilogue. */
ff4ce128 9627
1d3cea74 9628static void
9629s390_register_info_set_ranges ()
9630{
9631 int i, j;
9632
9633 /* Find the first and the last save slot supposed to use the stack
9634 to set the restore range.
9635 Vararg regs might be marked as save to stack but only the
9636 call-saved regs really need restoring (i.e. r6). This code
9637 assumes that the vararg regs have not yet been recorded in
9638 cfun_gpr_save_slot. */
9639 for (i = 0; i < 16 && cfun_gpr_save_slot (i) != SAVE_SLOT_STACK; i++);
9640 for (j = 15; j > i && cfun_gpr_save_slot (j) != SAVE_SLOT_STACK; j--);
9641 cfun_frame_layout.first_restore_gpr = (i == 16) ? -1 : i;
9642 cfun_frame_layout.last_restore_gpr = (i == 16) ? -1 : j;
1d3cea74 9643 cfun_frame_layout.first_save_gpr = (i == 16) ? -1 : i;
9644 cfun_frame_layout.last_save_gpr = (i == 16) ? -1 : j;
ff4ce128 9645}
9646
9647/* The GPR and FPR save slots in cfun->machine->frame_layout are set
9648 for registers which need to be saved in function prologue.
9649 This function can be used until the insns emitted for save/restore
9650 of the regs are visible in the RTL stream. */
9651
9652static void
9653s390_register_info ()
9654{
1d3cea74 9655 int i;
ff4ce128 9656 char clobbered_regs[32];
9657
9658 gcc_assert (!epilogue_completed);
9659
9660 if (reload_completed)
9661 /* After reload we rely on our own routine to determine which
9662 registers need saving. */
9663 s390_regs_ever_clobbered (clobbered_regs);
9664 else
9665 /* During reload we use regs_ever_live as a base since reload
9666 does changes in there which we otherwise would not be aware
9667 of. */
9668 for (i = 0; i < 32; i++)
9669 clobbered_regs[i] = df_regs_ever_live_p (i);
9670
9671 for (i = 0; i < 32; i++)
9672 clobbered_regs[i] = clobbered_regs[i] && !global_regs[i];
9673
9674 /* Mark the call-saved FPRs which need to be saved.
9675 This needs to be done before checking the special GPRs since the
9676 stack pointer usage depends on whether high FPRs have to be saved
9677 or not. */
9678 cfun_frame_layout.fpr_bitmap = 0;
9679 cfun_frame_layout.high_fprs = 0;
9680 for (i = FPR0_REGNUM; i <= FPR15_REGNUM; i++)
9681 if (clobbered_regs[i] && !call_really_used_regs[i])
9682 {
9683 cfun_set_fpr_save (i);
9684 if (i >= FPR8_REGNUM)
9685 cfun_frame_layout.high_fprs++;
9686 }
9a2a66ae 9687
c6d481f7 9688 /* Register 12 is used for GOT address, but also as temp in prologue
9689 for split-stack stdarg functions (unless r14 is available). */
9690 clobbered_regs[12]
9691 |= ((flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM))
9692 || (flag_split_stack && cfun->stdarg
9693 && (crtl->is_leaf || TARGET_TPF_PROFILING
9694 || has_hard_reg_initial_val (Pmode, RETURN_REGNUM))));
4fed3f99 9695
ffead1ca 9696 clobbered_regs[BASE_REGNUM]
77beec48 9697 |= (cfun->machine->base_reg
ff4ce128 9698 && REGNO (cfun->machine->base_reg) == BASE_REGNUM);
4fed3f99 9699
ff4ce128 9700 clobbered_regs[HARD_FRAME_POINTER_REGNUM]
9701 |= !!frame_pointer_needed;
9702
9703 /* On pre z900 machines this might take until machine dependent
9704 reorg to decide.
9705 save_return_addr_p will only be set on non-zarch machines so
9706 there is no risk that r14 goes into an FPR instead of a stack
9707 slot. */
1e639cb0 9708 clobbered_regs[RETURN_REGNUM]
d5bf7b64 9709 |= (!crtl->is_leaf
9bee2845 9710 || TARGET_TPF_PROFILING
77beec48 9711 || cfun->machine->split_branches_pending_p
9712 || cfun_frame_layout.save_return_addr_p
ff4ce128 9713 || crtl->calls_eh_return);
4fed3f99 9714
1e639cb0 9715 clobbered_regs[STACK_POINTER_REGNUM]
d5bf7b64 9716 |= (!crtl->is_leaf
77beec48 9717 || TARGET_TPF_PROFILING
9718 || cfun_save_high_fprs_p
9719 || get_frame_size () > 0
68bc0408 9720 || (reload_completed && cfun_frame_layout.frame_size > 0)
ff4ce128 9721 || cfun->calls_alloca);
9722
1d3cea74 9723 memset (cfun_frame_layout.gpr_save_slots, SAVE_SLOT_NONE, 16);
1e639cb0 9724
beee1f75 9725 for (i = 6; i < 16; i++)
ff4ce128 9726 if (clobbered_regs[i])
1d3cea74 9727 cfun_gpr_save_slot (i) = SAVE_SLOT_STACK;
9a2a66ae 9728
ff4ce128 9729 s390_register_info_stdarg_fpr ();
9730 s390_register_info_gprtofpr ();
1d3cea74 9731 s390_register_info_set_ranges ();
ff4ce128 9732 /* stdarg functions might need to save GPRs 2 to 6. This might
1d3cea74 9733 override the GPR->FPR save decision made by
9734 s390_register_info_gprtofpr for r6 since vararg regs must go to
9735 the stack. */
ff4ce128 9736 s390_register_info_stdarg_gpr ();
ff4ce128 9737}
9a2a66ae 9738
ff4ce128 9739/* This function is called by s390_optimize_prologue in order to get
9740 rid of unnecessary GPR save/restore instructions. The register info
9741 for the GPRs is re-computed and the ranges are re-calculated. */
6902d973 9742
ff4ce128 9743static void
9744s390_optimize_register_info ()
9745{
9746 char clobbered_regs[32];
1d3cea74 9747 int i;
6902d973 9748
ff4ce128 9749 gcc_assert (epilogue_completed);
9750 gcc_assert (!cfun->machine->split_branches_pending_p);
beee1f75 9751
ff4ce128 9752 s390_regs_ever_clobbered (clobbered_regs);
6902d973 9753
ff4ce128 9754 for (i = 0; i < 32; i++)
9755 clobbered_regs[i] = clobbered_regs[i] && !global_regs[i];
6902d973 9756
ff4ce128 9757 /* There is still special treatment needed for cases invisible to
9758 s390_regs_ever_clobbered. */
9759 clobbered_regs[RETURN_REGNUM]
9760 |= (TARGET_TPF_PROFILING
9761 /* When expanding builtin_return_addr in ESA mode we do not
9762 know whether r14 will later be needed as scratch reg when
9763 doing branch splitting. So the builtin always accesses the
9764 r14 save slot and we need to stick to the save/restore
9765 decision for r14 even if it turns out that it didn't get
9766 clobbered. */
9767 || cfun_frame_layout.save_return_addr_p
9768 || crtl->calls_eh_return);
9769
1d3cea74 9770 memset (cfun_frame_layout.gpr_save_slots, SAVE_SLOT_NONE, 6);
ff4ce128 9771
9772 for (i = 6; i < 16; i++)
9773 if (!clobbered_regs[i])
1d3cea74 9774 cfun_gpr_save_slot (i) = SAVE_SLOT_NONE;
ff4ce128 9775
1d3cea74 9776 s390_register_info_set_ranges ();
ff4ce128 9777 s390_register_info_stdarg_gpr ();
67928721 9778}
9779
4fed3f99 9780/* Fill cfun->machine with info about frame of current function. */
67928721 9781
9782static void
4fed3f99 9783s390_frame_info (void)
67928721 9784{
62eb9236 9785 HOST_WIDE_INT lowest_offset;
67928721 9786
ff4ce128 9787 cfun_frame_layout.first_save_gpr_slot = cfun_frame_layout.first_save_gpr;
9788 cfun_frame_layout.last_save_gpr_slot = cfun_frame_layout.last_save_gpr;
9789
9790 /* The va_arg builtin uses a constant distance of 16 *
9791 UNITS_PER_LONG (r0-r15) to reach the FPRs from the reg_save_area
9792 pointer. So even if we are going to save the stack pointer in an
9793 FPR we need the stack space in order to keep the offsets
9794 correct. */
9795 if (cfun->stdarg && cfun_save_arg_fprs_p)
9796 {
9797 cfun_frame_layout.last_save_gpr_slot = STACK_POINTER_REGNUM;
9798
9799 if (cfun_frame_layout.first_save_gpr_slot == -1)
9800 cfun_frame_layout.first_save_gpr_slot = STACK_POINTER_REGNUM;
9801 }
9802
67928721 9803 cfun_frame_layout.frame_size = get_frame_size ();
67928721 9804 if (!TARGET_64BIT && cfun_frame_layout.frame_size > 0x7fff0000)
c05be867 9805 fatal_error (input_location,
9806 "total size of local variables exceeds architecture limit");
ffead1ca 9807
646a946e 9808 if (!TARGET_PACKED_STACK)
67928721 9809 {
62eb9236 9810 /* Fixed stack layout. */
67928721 9811 cfun_frame_layout.backchain_offset = 0;
b5fdc416 9812 cfun_frame_layout.f0_offset = 16 * UNITS_PER_LONG;
67928721 9813 cfun_frame_layout.f4_offset = cfun_frame_layout.f0_offset + 2 * 8;
9814 cfun_frame_layout.f8_offset = -cfun_frame_layout.high_fprs * 8;
5214e6ae 9815 cfun_frame_layout.gprs_offset = (cfun_frame_layout.first_save_gpr_slot
b5fdc416 9816 * UNITS_PER_LONG);
67928721 9817 }
62eb9236 9818 else if (TARGET_BACKCHAIN)
67928721 9819 {
62eb9236 9820 /* Kernel stack layout - packed stack, backchain, no float */
9821 gcc_assert (TARGET_SOFT_FLOAT);
67928721 9822 cfun_frame_layout.backchain_offset = (STACK_POINTER_OFFSET
b5fdc416 9823 - UNITS_PER_LONG);
62eb9236 9824
9825 /* The distance between the backchain and the return address
9826 save slot must not change. So we always need a slot for the
9827 stack pointer which resides in between. */
9828 cfun_frame_layout.last_save_gpr_slot = STACK_POINTER_REGNUM;
9829
ffead1ca 9830 cfun_frame_layout.gprs_offset
62eb9236 9831 = cfun_frame_layout.backchain_offset - cfun_gprs_save_area_size;
ffead1ca 9832
62eb9236 9833 /* FPRs will not be saved. Nevertheless pick sane values to
9834 keep area calculations valid. */
9835 cfun_frame_layout.f0_offset =
9836 cfun_frame_layout.f4_offset =
9837 cfun_frame_layout.f8_offset = cfun_frame_layout.gprs_offset;
67928721 9838 }
62eb9236 9839 else
67928721 9840 {
031bdf83 9841 int num_fprs;
9842
62eb9236 9843 /* Packed stack layout without backchain. */
ffead1ca 9844
031bdf83 9845 /* With stdarg FPRs need their dedicated slots. */
9846 num_fprs = (TARGET_64BIT && cfun->stdarg ? 2
9847 : (cfun_fpr_save_p (FPR4_REGNUM) +
9848 cfun_fpr_save_p (FPR6_REGNUM)));
9849 cfun_frame_layout.f4_offset = STACK_POINTER_OFFSET - 8 * num_fprs;
9850
9851 num_fprs = (cfun->stdarg ? 2
9852 : (cfun_fpr_save_p (FPR0_REGNUM)
9853 + cfun_fpr_save_p (FPR2_REGNUM)));
9854 cfun_frame_layout.f0_offset = cfun_frame_layout.f4_offset - 8 * num_fprs;
ffead1ca 9855
9856 cfun_frame_layout.gprs_offset
67928721 9857 = cfun_frame_layout.f0_offset - cfun_gprs_save_area_size;
62eb9236 9858
9859 cfun_frame_layout.f8_offset = (cfun_frame_layout.gprs_offset
9860 - cfun_frame_layout.high_fprs * 8);
67928721 9861 }
9862
62eb9236 9863 if (cfun_save_high_fprs_p)
9864 cfun_frame_layout.frame_size += cfun_frame_layout.high_fprs * 8;
9865
9866 if (!crtl->is_leaf)
9867 cfun_frame_layout.frame_size += crtl->outgoing_args_size;
9868
9869 /* In the following cases we have to allocate a STACK_POINTER_OFFSET
9870 sized area at the bottom of the stack. This is required also for
9871 leaf functions. When GCC generates a local stack reference it
9872 will always add STACK_POINTER_OFFSET to all these references. */
d5bf7b64 9873 if (crtl->is_leaf
67928721 9874 && !TARGET_TPF_PROFILING
9875 && cfun_frame_layout.frame_size == 0
ff4ce128 9876 && !cfun->calls_alloca)
67928721 9877 return;
9878
62eb9236 9879 /* Calculate the number of bytes we have used in our own register
9880 save area. With the packed stack layout we can re-use the
9881 remaining bytes for normal stack elements. */
67928721 9882
62eb9236 9883 if (TARGET_PACKED_STACK)
9884 lowest_offset = MIN (MIN (cfun_frame_layout.f0_offset,
9885 cfun_frame_layout.f4_offset),
9886 cfun_frame_layout.gprs_offset);
9887 else
9888 lowest_offset = 0;
ffead1ca 9889
62eb9236 9890 if (TARGET_BACKCHAIN)
9891 lowest_offset = MIN (lowest_offset, cfun_frame_layout.backchain_offset);
ffead1ca 9892
62eb9236 9893 cfun_frame_layout.frame_size += STACK_POINTER_OFFSET - lowest_offset;
67928721 9894
62eb9236 9895 /* If under 31 bit an odd number of gprs has to be saved we have to
9896 adjust the frame size to sustain 8 byte alignment of stack
9897 frames. */
9898 cfun_frame_layout.frame_size = ((cfun_frame_layout.frame_size +
9899 STACK_BOUNDARY / BITS_PER_UNIT - 1)
9900 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
8b4a4127 9901}
9902
4fed3f99 9903/* Generate frame layout. Fills in register and frame data for the current
9904 function in cfun->machine. This routine can be called multiple times;
9905 it will re-do the complete frame layout every time. */
8b4a4127 9906
4fed3f99 9907static void
9908s390_init_frame_layout (void)
4673c1a0 9909{
4fed3f99 9910 HOST_WIDE_INT frame_size;
9911 int base_used;
ff4ce128 9912
b85ca4c8 9913 /* After LRA the frame layout is supposed to be read-only and should
9914 not be re-computed. */
9915 if (reload_completed)
9916 return;
beee1f75 9917
4fed3f99 9918 /* On S/390 machines, we may need to perform branch splitting, which
9919 will require both base and return address register. We have no
9920 choice but to assume we're going to need them until right at the
9921 end of the machine dependent reorg phase. */
9922 if (!TARGET_CPU_ZARCH)
9923 cfun->machine->split_branches_pending_p = true;
9924
9925 do
9926 {
9927 frame_size = cfun_frame_layout.frame_size;
9928
9929 /* Try to predict whether we'll need the base register. */
9930 base_used = cfun->machine->split_branches_pending_p
18d50ae6 9931 || crtl->uses_const_pool
3ea2a559 9932 || (!DISP_IN_RANGE (frame_size)
9933 && !CONST_OK_FOR_K (frame_size));
4fed3f99 9934
9935 /* Decide which register to use as literal pool base. In small
9936 leaf functions, try to use an unused call-clobbered register
9937 as base register to avoid save/restore overhead. */
9938 if (!base_used)
9939 cfun->machine->base_reg = NULL_RTX;
4fed3f99 9940 else
fee9fc9f 9941 {
9942 int br = 0;
9943
9944 if (crtl->is_leaf)
9945 /* Prefer r5 (most likely to be free). */
9946 for (br = 5; br >= 2 && df_regs_ever_live_p (br); br--)
9947 ;
9948 cfun->machine->base_reg =
009c4697 9949 gen_rtx_REG (Pmode, (br >= 2) ? br : BASE_REGNUM);
fee9fc9f 9950 }
67928721 9951
ff4ce128 9952 s390_register_info ();
4fed3f99 9953 s390_frame_info ();
9954 }
9955 while (frame_size != cfun_frame_layout.frame_size);
4673c1a0 9956}
9957
5ada7a14 9958/* Remove the FPR clobbers from a tbegin insn if it can be proven that
9959 the TX is nonescaping. A transaction is considered escaping if
9960 there is at least one path from tbegin returning CC0 to the
9961 function exit block without an tend.
9962
9963 The check so far has some limitations:
9964 - only single tbegin/tend BBs are supported
9965 - the first cond jump after tbegin must separate the CC0 path from ~CC0
9966 - when CC is copied to a GPR and the CC0 check is done with the GPR
9967 this is not supported
9968*/
9969
9970static void
9971s390_optimize_nonescaping_tx (void)
9972{
9973 const unsigned int CC0 = 1 << 3;
9974 basic_block tbegin_bb = NULL;
9975 basic_block tend_bb = NULL;
9976 basic_block bb;
93e0956b 9977 rtx_insn *insn;
5ada7a14 9978 bool result = true;
9979 int bb_index;
93e0956b 9980 rtx_insn *tbegin_insn = NULL;
5ada7a14 9981
9982 if (!cfun->machine->tbegin_p)
9983 return;
9984
a28770e1 9985 for (bb_index = 0; bb_index < n_basic_blocks_for_fn (cfun); bb_index++)
5ada7a14 9986 {
f5a6b05f 9987 bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
5ada7a14 9988
91dfd73e 9989 if (!bb)
9990 continue;
9991
5ada7a14 9992 FOR_BB_INSNS (bb, insn)
9993 {
9994 rtx ite, cc, pat, target;
9995 unsigned HOST_WIDE_INT mask;
9996
9997 if (!INSN_P (insn) || INSN_CODE (insn) <= 0)
9998 continue;
9999
10000 pat = PATTERN (insn);
10001
10002 if (GET_CODE (pat) == PARALLEL)
10003 pat = XVECEXP (pat, 0, 0);
10004
10005 if (GET_CODE (pat) != SET
10006 || GET_CODE (SET_SRC (pat)) != UNSPEC_VOLATILE)
10007 continue;
10008
10009 if (XINT (SET_SRC (pat), 1) == UNSPECV_TBEGIN)
10010 {
91a55c11 10011 rtx_insn *tmp;
5ada7a14 10012
10013 tbegin_insn = insn;
10014
10015 /* Just return if the tbegin doesn't have clobbers. */
10016 if (GET_CODE (PATTERN (insn)) != PARALLEL)
10017 return;
10018
10019 if (tbegin_bb != NULL)
10020 return;
10021
10022 /* Find the next conditional jump. */
10023 for (tmp = NEXT_INSN (insn);
10024 tmp != NULL_RTX;
10025 tmp = NEXT_INSN (tmp))
10026 {
10027 if (reg_set_p (gen_rtx_REG (CCmode, CC_REGNUM), tmp))
10028 return;
10029 if (!JUMP_P (tmp))
10030 continue;
10031
10032 ite = SET_SRC (PATTERN (tmp));
10033 if (GET_CODE (ite) != IF_THEN_ELSE)
10034 continue;
10035
10036 cc = XEXP (XEXP (ite, 0), 0);
10037 if (!REG_P (cc) || !CC_REGNO_P (REGNO (cc))
10038 || GET_MODE (cc) != CCRAWmode
10039 || GET_CODE (XEXP (XEXP (ite, 0), 1)) != CONST_INT)
10040 return;
10041
10042 if (bb->succs->length () != 2)
10043 return;
10044
10045 mask = INTVAL (XEXP (XEXP (ite, 0), 1));
10046 if (GET_CODE (XEXP (ite, 0)) == NE)
10047 mask ^= 0xf;
10048
10049 if (mask == CC0)
10050 target = XEXP (ite, 1);
10051 else if (mask == (CC0 ^ 0xf))
10052 target = XEXP (ite, 2);
10053 else
10054 return;
10055
10056 {
10057 edge_iterator ei;
10058 edge e1, e2;
10059
10060 ei = ei_start (bb->succs);
10061 e1 = ei_safe_edge (ei);
10062 ei_next (&ei);
10063 e2 = ei_safe_edge (ei);
10064
10065 if (e2->flags & EDGE_FALLTHRU)
10066 {
10067 e2 = e1;
10068 e1 = ei_safe_edge (ei);
10069 }
10070
10071 if (!(e1->flags & EDGE_FALLTHRU))
10072 return;
10073
10074 tbegin_bb = (target == pc_rtx) ? e1->dest : e2->dest;
10075 }
10076 if (tmp == BB_END (bb))
10077 break;
10078 }
10079 }
10080
10081 if (XINT (SET_SRC (pat), 1) == UNSPECV_TEND)
10082 {
10083 if (tend_bb != NULL)
10084 return;
10085 tend_bb = bb;
10086 }
10087 }
10088 }
10089
10090 /* Either we successfully remove the FPR clobbers here or we are not
10091 able to do anything for this TX. Both cases don't qualify for
10092 another look. */
10093 cfun->machine->tbegin_p = false;
10094
10095 if (tbegin_bb == NULL || tend_bb == NULL)
10096 return;
10097
10098 calculate_dominance_info (CDI_POST_DOMINATORS);
10099 result = dominated_by_p (CDI_POST_DOMINATORS, tbegin_bb, tend_bb);
10100 free_dominance_info (CDI_POST_DOMINATORS);
10101
10102 if (!result)
10103 return;
10104
91dfd73e 10105 PATTERN (tbegin_insn) = gen_rtx_PARALLEL (VOIDmode,
10106 gen_rtvec (2,
10107 XVECEXP (PATTERN (tbegin_insn), 0, 0),
10108 XVECEXP (PATTERN (tbegin_insn), 0, 1)));
5ada7a14 10109 INSN_CODE (tbegin_insn) = -1;
10110 df_insn_rescan (tbegin_insn);
10111
10112 return;
10113}
10114
8f1128bb 10115/* Return true if it is legal to put a value with MODE into REGNO. */
10116
10117bool
3754d046 10118s390_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
8f1128bb 10119{
76a4c804 10120 if (!TARGET_VX && VECTOR_NOFP_REGNO_P (regno))
10121 return false;
10122
8f1128bb 10123 switch (REGNO_REG_CLASS (regno))
10124 {
76a4c804 10125 case VEC_REGS:
10126 return ((GET_MODE_CLASS (mode) == MODE_INT
10127 && s390_class_max_nregs (VEC_REGS, mode) == 1)
10128 || mode == DFmode
80912819 10129 || (TARGET_VXE && mode == SFmode)
76a4c804 10130 || s390_vector_mode_supported_p (mode));
10131 break;
8f1128bb 10132 case FP_REGS:
76a4c804 10133 if (TARGET_VX
10134 && ((GET_MODE_CLASS (mode) == MODE_INT
10135 && s390_class_max_nregs (FP_REGS, mode) == 1)
10136 || mode == DFmode
10137 || s390_vector_mode_supported_p (mode)))
10138 return true;
10139
8f1128bb 10140 if (REGNO_PAIR_OK (regno, mode))
10141 {
10142 if (mode == SImode || mode == DImode)
10143 return true;
10144
10145 if (FLOAT_MODE_P (mode) && GET_MODE_CLASS (mode) != MODE_VECTOR_FLOAT)
10146 return true;
10147 }
10148 break;
10149 case ADDR_REGS:
10150 if (FRAME_REGNO_P (regno) && mode == Pmode)
10151 return true;
10152
10153 /* fallthrough */
10154 case GENERAL_REGS:
10155 if (REGNO_PAIR_OK (regno, mode))
10156 {
b5fdc416 10157 if (TARGET_ZARCH
36868490 10158 || (mode != TFmode && mode != TCmode && mode != TDmode))
8f1128bb 10159 return true;
ffead1ca 10160 }
8f1128bb 10161 break;
10162 case CC_REGS:
10163 if (GET_MODE_CLASS (mode) == MODE_CC)
10164 return true;
10165 break;
10166 case ACCESS_REGS:
10167 if (REGNO_PAIR_OK (regno, mode))
10168 {
10169 if (mode == SImode || mode == Pmode)
10170 return true;
10171 }
10172 break;
10173 default:
10174 return false;
10175 }
ffead1ca 10176
8f1128bb 10177 return false;
10178}
10179
d1a5573e 10180/* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
10181
10182bool
10183s390_hard_regno_rename_ok (unsigned int old_reg, unsigned int new_reg)
10184{
10185 /* Once we've decided upon a register to use as base register, it must
10186 no longer be used for any other purpose. */
10187 if (cfun->machine->base_reg)
10188 if (REGNO (cfun->machine->base_reg) == old_reg
10189 || REGNO (cfun->machine->base_reg) == new_reg)
10190 return false;
10191
ff4ce128 10192 /* Prevent regrename from using call-saved regs which haven't
10193 actually been saved. This is necessary since regrename assumes
10194 the backend save/restore decisions are based on
10195 df_regs_ever_live. Since we have our own routine we have to tell
10196 regrename manually about it. */
10197 if (GENERAL_REGNO_P (new_reg)
10198 && !call_really_used_regs[new_reg]
1d3cea74 10199 && cfun_gpr_save_slot (new_reg) == SAVE_SLOT_NONE)
ff4ce128 10200 return false;
10201
10202 return true;
10203}
10204
10205/* Return nonzero if register REGNO can be used as a scratch register
10206 in peephole2. */
10207
10208static bool
10209s390_hard_regno_scratch_ok (unsigned int regno)
10210{
10211 /* See s390_hard_regno_rename_ok. */
10212 if (GENERAL_REGNO_P (regno)
10213 && !call_really_used_regs[regno]
1d3cea74 10214 && cfun_gpr_save_slot (regno) == SAVE_SLOT_NONE)
ff4ce128 10215 return false;
10216
d1a5573e 10217 return true;
10218}
10219
8f1128bb 10220/* Maximum number of registers to represent a value of mode MODE
8deb3959 10221 in a register of class RCLASS. */
8f1128bb 10222
6c2d82ab 10223int
3754d046 10224s390_class_max_nregs (enum reg_class rclass, machine_mode mode)
8f1128bb 10225{
76a4c804 10226 int reg_size;
10227 bool reg_pair_required_p = false;
10228
8deb3959 10229 switch (rclass)
8f1128bb 10230 {
10231 case FP_REGS:
76a4c804 10232 case VEC_REGS:
10233 reg_size = TARGET_VX ? 16 : 8;
10234
10235 /* TF and TD modes would fit into a VR but we put them into a
10236 register pair since we do not have 128bit FP instructions on
10237 full VRs. */
10238 if (TARGET_VX
10239 && SCALAR_FLOAT_MODE_P (mode)
10240 && GET_MODE_SIZE (mode) >= 16)
10241 reg_pair_required_p = true;
10242
10243 /* Even if complex types would fit into a single FPR/VR we force
10244 them into a register pair to deal with the parts more easily.
10245 (FIXME: What about complex ints?) */
8f1128bb 10246 if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
76a4c804 10247 reg_pair_required_p = true;
10248 break;
8f1128bb 10249 case ACCESS_REGS:
76a4c804 10250 reg_size = 4;
10251 break;
8f1128bb 10252 default:
76a4c804 10253 reg_size = UNITS_PER_WORD;
8f1128bb 10254 break;
10255 }
76a4c804 10256
10257 if (reg_pair_required_p)
10258 return 2 * ((GET_MODE_SIZE (mode) / 2 + reg_size - 1) / reg_size);
10259
10260 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
10261}
10262
10263/* Return TRUE if changing mode from FROM to TO should not be allowed
10264 for register class CLASS. */
10265
10266int
10267s390_cannot_change_mode_class (machine_mode from_mode,
10268 machine_mode to_mode,
10269 enum reg_class rclass)
10270{
10271 machine_mode small_mode;
10272 machine_mode big_mode;
10273
80912819 10274 /* V1TF and TF have different representations in vector
10275 registers. */
10276 if (reg_classes_intersect_p (VEC_REGS, rclass)
10277 && ((from_mode == V1TFmode && to_mode == TFmode)
10278 || (from_mode == TFmode && to_mode == V1TFmode)))
10279 return 1;
10280
76a4c804 10281 if (GET_MODE_SIZE (from_mode) == GET_MODE_SIZE (to_mode))
10282 return 0;
10283
10284 if (GET_MODE_SIZE (from_mode) < GET_MODE_SIZE (to_mode))
10285 {
10286 small_mode = from_mode;
10287 big_mode = to_mode;
10288 }
10289 else
10290 {
10291 small_mode = to_mode;
10292 big_mode = from_mode;
10293 }
10294
10295 /* Values residing in VRs are little-endian style. All modes are
10296 placed left-aligned in an VR. This means that we cannot allow
10297 switching between modes with differing sizes. Also if the vector
10298 facility is available we still place TFmode values in VR register
10299 pairs, since the only instructions we have operating on TFmodes
10300 only deal with register pairs. Therefore we have to allow DFmode
10301 subregs of TFmodes to enable the TFmode splitters. */
10302 if (reg_classes_intersect_p (VEC_REGS, rclass)
10303 && (GET_MODE_SIZE (small_mode) < 8
10304 || s390_class_max_nregs (VEC_REGS, big_mode) == 1))
10305 return 1;
10306
10307 /* Likewise for access registers, since they have only half the
10308 word size on 64-bit. */
10309 if (reg_classes_intersect_p (ACCESS_REGS, rclass))
10310 return 1;
10311
10312 return 0;
8f1128bb 10313}
10314
7b1bda1c 10315/* Return true if we use LRA instead of reload pass. */
10316static bool
10317s390_lra_p (void)
10318{
10319 return s390_lra_flag;
10320}
10321
4fed3f99 10322/* Return true if register FROM can be eliminated via register TO. */
10323
cd90919d 10324static bool
10325s390_can_eliminate (const int from, const int to)
4fed3f99 10326{
d1a5573e 10327 /* On zSeries machines, we have not marked the base register as fixed.
10328 Instead, we have an elimination rule BASE_REGNUM -> BASE_REGNUM.
10329 If a function requires the base register, we say here that this
10330 elimination cannot be performed. This will cause reload to free
10331 up the base register (as if it were fixed). On the other hand,
10332 if the current function does *not* require the base register, we
10333 say here the elimination succeeds, which in turn allows reload
10334 to allocate the base register for any other purpose. */
10335 if (from == BASE_REGNUM && to == BASE_REGNUM)
10336 {
10337 if (TARGET_CPU_ZARCH)
10338 {
10339 s390_init_frame_layout ();
10340 return cfun->machine->base_reg == NULL_RTX;
10341 }
10342
10343 return false;
10344 }
10345
10346 /* Everything else must point into the stack frame. */
4fed3f99 10347 gcc_assert (to == STACK_POINTER_REGNUM
10348 || to == HARD_FRAME_POINTER_REGNUM);
10349
10350 gcc_assert (from == FRAME_POINTER_REGNUM
10351 || from == ARG_POINTER_REGNUM
10352 || from == RETURN_ADDRESS_POINTER_REGNUM);
10353
10354 /* Make sure we actually saved the return address. */
10355 if (from == RETURN_ADDRESS_POINTER_REGNUM)
18d50ae6 10356 if (!crtl->calls_eh_return
10357 && !cfun->stdarg
4fed3f99 10358 && !cfun_frame_layout.save_return_addr_p)
10359 return false;
10360
10361 return true;
10362}
10363
10364/* Return offset between register FROM and TO initially after prolog. */
7cbfc974 10365
10366HOST_WIDE_INT
4fed3f99 10367s390_initial_elimination_offset (int from, int to)
7cbfc974 10368{
4fed3f99 10369 HOST_WIDE_INT offset;
7cbfc974 10370
4fed3f99 10371 /* ??? Why are we called for non-eliminable pairs? */
10372 if (!s390_can_eliminate (from, to))
10373 return 0;
10374
10375 switch (from)
10376 {
10377 case FRAME_POINTER_REGNUM:
ffead1ca 10378 offset = (get_frame_size()
119114cb 10379 + STACK_POINTER_OFFSET
abe32cce 10380 + crtl->outgoing_args_size);
4fed3f99 10381 break;
67928721 10382
4fed3f99 10383 case ARG_POINTER_REGNUM:
10384 s390_init_frame_layout ();
10385 offset = cfun_frame_layout.frame_size + STACK_POINTER_OFFSET;
10386 break;
10387
10388 case RETURN_ADDRESS_POINTER_REGNUM:
10389 s390_init_frame_layout ();
ff4ce128 10390
10391 if (cfun_frame_layout.first_save_gpr_slot == -1)
10392 {
10393 /* If it turns out that for stdarg nothing went into the reg
10394 save area we also do not need the return address
10395 pointer. */
10396 if (cfun->stdarg && !cfun_save_arg_fprs_p)
10397 return 0;
10398
10399 gcc_unreachable ();
10400 }
10401
10402 /* In order to make the following work it is not necessary for
10403 r14 to have a save slot. It is sufficient if one other GPR
10404 got one. Since the GPRs are always stored without gaps we
10405 are able to calculate where the r14 save slot would
10406 reside. */
10407 offset = (cfun_frame_layout.frame_size + cfun_frame_layout.gprs_offset +
10408 (RETURN_REGNUM - cfun_frame_layout.first_save_gpr_slot) *
10409 UNITS_PER_LONG);
4fed3f99 10410 break;
10411
d1a5573e 10412 case BASE_REGNUM:
10413 offset = 0;
10414 break;
10415
4fed3f99 10416 default:
10417 gcc_unreachable ();
10418 }
10419
10420 return offset;
7cbfc974 10421}
10422
8b4a4127 10423/* Emit insn to save fpr REGNUM at offset OFFSET relative
f81e845f 10424 to register BASE. Return generated insn. */
56769981 10425
4673c1a0 10426static rtx
b40da9a7 10427save_fpr (rtx base, int offset, int regnum)
4673c1a0 10428{
8b4a4127 10429 rtx addr;
29c05e22 10430 addr = gen_rtx_MEM (DFmode, plus_constant (Pmode, base, offset));
ce1d5a67 10431
10432 if (regnum >= 16 && regnum <= (16 + FP_ARG_NUM_REG))
10433 set_mem_alias_set (addr, get_varargs_alias_set ());
10434 else
10435 set_mem_alias_set (addr, get_frame_alias_set ());
4673c1a0 10436
8b4a4127 10437 return emit_move_insn (addr, gen_rtx_REG (DFmode, regnum));
10438}
4673c1a0 10439
8b4a4127 10440/* Emit insn to restore fpr REGNUM from offset OFFSET relative
f81e845f 10441 to register BASE. Return generated insn. */
4673c1a0 10442
8b4a4127 10443static rtx
b40da9a7 10444restore_fpr (rtx base, int offset, int regnum)
8b4a4127 10445{
10446 rtx addr;
29c05e22 10447 addr = gen_rtx_MEM (DFmode, plus_constant (Pmode, base, offset));
ce1d5a67 10448 set_mem_alias_set (addr, get_frame_alias_set ());
4673c1a0 10449
8b4a4127 10450 return emit_move_insn (gen_rtx_REG (DFmode, regnum), addr);
4673c1a0 10451}
10452
a3cd0f6a 10453/* Return true if REGNO is a global register, but not one
10454 of the special ones that need to be saved/restored in anyway. */
10455
10456static inline bool
10457global_not_special_regno_p (int regno)
10458{
10459 return (global_regs[regno]
10460 /* These registers are special and need to be
10461 restored in any case. */
10462 && !(regno == STACK_POINTER_REGNUM
10463 || regno == RETURN_REGNUM
10464 || regno == BASE_REGNUM
10465 || (flag_pic && regno == (int)PIC_OFFSET_TABLE_REGNUM)));
10466}
10467
9a2a66ae 10468/* Generate insn to save registers FIRST to LAST into
f81e845f 10469 the register save area located at offset OFFSET
9a2a66ae 10470 relative to register BASE. */
4673c1a0 10471
9a2a66ae 10472static rtx
b40da9a7 10473save_gprs (rtx base, int offset, int first, int last)
4673c1a0 10474{
9a2a66ae 10475 rtx addr, insn, note;
10476 int i;
10477
29c05e22 10478 addr = plus_constant (Pmode, base, offset);
9a2a66ae 10479 addr = gen_rtx_MEM (Pmode, addr);
ce1d5a67 10480
10481 set_mem_alias_set (addr, get_frame_alias_set ());
9a2a66ae 10482
10483 /* Special-case single register. */
10484 if (first == last)
10485 {
10486 if (TARGET_64BIT)
10487 insn = gen_movdi (addr, gen_rtx_REG (Pmode, first));
10488 else
10489 insn = gen_movsi (addr, gen_rtx_REG (Pmode, first));
10490
a3cd0f6a 10491 if (!global_not_special_regno_p (first))
10492 RTX_FRAME_RELATED_P (insn) = 1;
9a2a66ae 10493 return insn;
10494 }
10495
10496
10497 insn = gen_store_multiple (addr,
10498 gen_rtx_REG (Pmode, first),
10499 GEN_INT (last - first + 1));
10500
18d50ae6 10501 if (first <= 6 && cfun->stdarg)
ce1d5a67 10502 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
10503 {
10504 rtx mem = XEXP (XVECEXP (PATTERN (insn), 0, i), 0);
ffead1ca 10505
ce1d5a67 10506 if (first + i <= 6)
10507 set_mem_alias_set (mem, get_varargs_alias_set ());
10508 }
9a2a66ae 10509
10510 /* We need to set the FRAME_RELATED flag on all SETs
10511 inside the store-multiple pattern.
10512
10513 However, we must not emit DWARF records for registers 2..5
f81e845f 10514 if they are stored for use by variable arguments ...
9a2a66ae 10515
3ce7ff97 10516 ??? Unfortunately, it is not enough to simply not the
9a2a66ae 10517 FRAME_RELATED flags for those SETs, because the first SET
10518 of the PARALLEL is always treated as if it had the flag
10519 set, even if it does not. Therefore we emit a new pattern
10520 without those registers as REG_FRAME_RELATED_EXPR note. */
10521
a3cd0f6a 10522 if (first >= 6 && !global_not_special_regno_p (first))
9a2a66ae 10523 {
10524 rtx pat = PATTERN (insn);
10525
10526 for (i = 0; i < XVECLEN (pat, 0); i++)
a3cd0f6a 10527 if (GET_CODE (XVECEXP (pat, 0, i)) == SET
10528 && !global_not_special_regno_p (REGNO (SET_SRC (XVECEXP (pat,
10529 0, i)))))
9a2a66ae 10530 RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1;
10531
10532 RTX_FRAME_RELATED_P (insn) = 1;
10533 }
10534 else if (last >= 6)
10535 {
a3cd0f6a 10536 int start;
10537
10538 for (start = first >= 6 ? first : 6; start <= last; start++)
10539 if (!global_not_special_regno_p (start))
10540 break;
10541
10542 if (start > last)
10543 return insn;
10544
29c05e22 10545 addr = plus_constant (Pmode, base,
10546 offset + (start - first) * UNITS_PER_LONG);
ff4ce128 10547
10548 if (start == last)
10549 {
10550 if (TARGET_64BIT)
10551 note = gen_movdi (gen_rtx_MEM (Pmode, addr),
10552 gen_rtx_REG (Pmode, start));
10553 else
10554 note = gen_movsi (gen_rtx_MEM (Pmode, addr),
10555 gen_rtx_REG (Pmode, start));
10556 note = PATTERN (note);
10557
10558 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
10559 RTX_FRAME_RELATED_P (insn) = 1;
10560
10561 return insn;
10562 }
10563
f81e845f 10564 note = gen_store_multiple (gen_rtx_MEM (Pmode, addr),
a3cd0f6a 10565 gen_rtx_REG (Pmode, start),
10566 GEN_INT (last - start + 1));
9a2a66ae 10567 note = PATTERN (note);
10568
b9c74b4d 10569 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
9a2a66ae 10570
10571 for (i = 0; i < XVECLEN (note, 0); i++)
a3cd0f6a 10572 if (GET_CODE (XVECEXP (note, 0, i)) == SET
10573 && !global_not_special_regno_p (REGNO (SET_SRC (XVECEXP (note,
10574 0, i)))))
9a2a66ae 10575 RTX_FRAME_RELATED_P (XVECEXP (note, 0, i)) = 1;
10576
10577 RTX_FRAME_RELATED_P (insn) = 1;
10578 }
10579
10580 return insn;
8b4a4127 10581}
4673c1a0 10582
9a2a66ae 10583/* Generate insn to restore registers FIRST to LAST from
f81e845f 10584 the register save area located at offset OFFSET
9a2a66ae 10585 relative to register BASE. */
4673c1a0 10586
9a2a66ae 10587static rtx
b40da9a7 10588restore_gprs (rtx base, int offset, int first, int last)
8b4a4127 10589{
9a2a66ae 10590 rtx addr, insn;
10591
29c05e22 10592 addr = plus_constant (Pmode, base, offset);
9a2a66ae 10593 addr = gen_rtx_MEM (Pmode, addr);
ce1d5a67 10594 set_mem_alias_set (addr, get_frame_alias_set ());
9a2a66ae 10595
10596 /* Special-case single register. */
10597 if (first == last)
10598 {
10599 if (TARGET_64BIT)
10600 insn = gen_movdi (gen_rtx_REG (Pmode, first), addr);
10601 else
10602 insn = gen_movsi (gen_rtx_REG (Pmode, first), addr);
10603
ff4ce128 10604 RTX_FRAME_RELATED_P (insn) = 1;
9a2a66ae 10605 return insn;
10606 }
10607
10608 insn = gen_load_multiple (gen_rtx_REG (Pmode, first),
10609 addr,
10610 GEN_INT (last - first + 1));
ff4ce128 10611 RTX_FRAME_RELATED_P (insn) = 1;
9a2a66ae 10612 return insn;
8b4a4127 10613}
4673c1a0 10614
20074f87 10615/* Return insn sequence to load the GOT register. */
12ef3745 10616
10617static GTY(()) rtx got_symbol;
93e0956b 10618rtx_insn *
20074f87 10619s390_load_got (void)
12ef3745 10620{
93e0956b 10621 rtx_insn *insns;
20074f87 10622
c60a7572 10623 /* We cannot use pic_offset_table_rtx here since we use this
10624 function also for non-pic if __tls_get_offset is called and in
10625 that case PIC_OFFSET_TABLE_REGNUM as well as pic_offset_table_rtx
10626 aren't usable. */
10627 rtx got_rtx = gen_rtx_REG (Pmode, 12);
10628
12ef3745 10629 if (!got_symbol)
10630 {
10631 got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
10632 SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
10633 }
10634
20074f87 10635 start_sequence ();
10636
dafc8d45 10637 if (TARGET_CPU_ZARCH)
12ef3745 10638 {
c60a7572 10639 emit_move_insn (got_rtx, got_symbol);
12ef3745 10640 }
10641 else
10642 {
20074f87 10643 rtx offset;
12ef3745 10644
f81e845f 10645 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got_symbol),
12ef3745 10646 UNSPEC_LTREL_OFFSET);
10647 offset = gen_rtx_CONST (Pmode, offset);
10648 offset = force_const_mem (Pmode, offset);
10649
c60a7572 10650 emit_move_insn (got_rtx, offset);
12ef3745 10651
f81e845f 10652 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (offset, 0)),
12ef3745 10653 UNSPEC_LTREL_BASE);
c60a7572 10654 offset = gen_rtx_PLUS (Pmode, got_rtx, offset);
12ef3745 10655
c60a7572 10656 emit_move_insn (got_rtx, offset);
12ef3745 10657 }
20074f87 10658
10659 insns = get_insns ();
10660 end_sequence ();
10661 return insns;
12ef3745 10662}
10663
062c49fd 10664/* This ties together stack memory (MEM with an alias set of frame_alias_set)
10665 and the change to the stack pointer. */
10666
10667static void
10668s390_emit_stack_tie (void)
10669{
10670 rtx mem = gen_frame_mem (BLKmode,
10671 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
10672
10673 emit_insn (gen_stack_tie (mem));
10674}
10675
ff4ce128 10676/* Copy GPRS into FPR save slots. */
10677
10678static void
10679s390_save_gprs_to_fprs (void)
10680{
10681 int i;
10682
10683 if (!TARGET_Z10 || !TARGET_HARD_FLOAT || !crtl->is_leaf)
10684 return;
10685
10686 for (i = 6; i < 16; i++)
10687 {
10688 if (FP_REGNO_P (cfun_gpr_save_slot (i)))
10689 {
93e0956b 10690 rtx_insn *insn =
ff4ce128 10691 emit_move_insn (gen_rtx_REG (DImode, cfun_gpr_save_slot (i)),
10692 gen_rtx_REG (DImode, i));
10693 RTX_FRAME_RELATED_P (insn) = 1;
c5dad799 10694 /* This prevents dwarf2cfi from interpreting the set. Doing
10695 so it might emit def_cfa_register infos setting an FPR as
10696 new CFA. */
9e165059 10697 add_reg_note (insn, REG_CFA_REGISTER, copy_rtx (PATTERN (insn)));
ff4ce128 10698 }
10699 }
10700}
10701
10702/* Restore GPRs from FPR save slots. */
10703
10704static void
10705s390_restore_gprs_from_fprs (void)
10706{
10707 int i;
10708
10709 if (!TARGET_Z10 || !TARGET_HARD_FLOAT || !crtl->is_leaf)
10710 return;
10711
10712 for (i = 6; i < 16; i++)
10713 {
54530437 10714 rtx_insn *insn;
10715
10716 if (!FP_REGNO_P (cfun_gpr_save_slot (i)))
10717 continue;
10718
10719 rtx fpr = gen_rtx_REG (DImode, cfun_gpr_save_slot (i));
10720
10721 if (i == STACK_POINTER_REGNUM)
10722 insn = emit_insn (gen_stack_restore_from_fpr (fpr));
10723 else
10724 insn = emit_move_insn (gen_rtx_REG (DImode, i), fpr);
10725
10726 df_set_regs_ever_live (i, true);
10727 add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (DImode, i));
10728 if (i == STACK_POINTER_REGNUM)
10729 add_reg_note (insn, REG_CFA_DEF_CFA,
10730 plus_constant (Pmode, stack_pointer_rtx,
10731 STACK_POINTER_OFFSET));
10732 RTX_FRAME_RELATED_P (insn) = 1;
ff4ce128 10733 }
10734}
10735
4673c1a0 10736
0b8be04c 10737/* A pass run immediately before shrink-wrapping and prologue and epilogue
10738 generation. */
10739
0b8be04c 10740namespace {
10741
10742const pass_data pass_data_s390_early_mach =
10743{
10744 RTL_PASS, /* type */
10745 "early_mach", /* name */
10746 OPTGROUP_NONE, /* optinfo_flags */
0b8be04c 10747 TV_MACH_DEP, /* tv_id */
10748 0, /* properties_required */
10749 0, /* properties_provided */
10750 0, /* properties_destroyed */
10751 0, /* todo_flags_start */
8b88439e 10752 ( TODO_df_verify | TODO_df_finish ), /* todo_flags_finish */
0b8be04c 10753};
20074f87 10754
0b8be04c 10755class pass_s390_early_mach : public rtl_opt_pass
10756{
10757public:
10758 pass_s390_early_mach (gcc::context *ctxt)
10759 : rtl_opt_pass (pass_data_s390_early_mach, ctxt)
10760 {}
10761
10762 /* opt_pass methods: */
65b0537f 10763 virtual unsigned int execute (function *);
0b8be04c 10764
10765}; // class pass_s390_early_mach
10766
65b0537f 10767unsigned int
10768pass_s390_early_mach::execute (function *fun)
10769{
93e0956b 10770 rtx_insn *insn;
65b0537f 10771
10772 /* Try to get rid of the FPR clobbers. */
10773 s390_optimize_nonescaping_tx ();
10774
10775 /* Re-compute register info. */
10776 s390_register_info ();
10777
10778 /* If we're using a base register, ensure that it is always valid for
10779 the first non-prologue instruction. */
10780 if (fun->machine->base_reg)
10781 emit_insn_at_entry (gen_main_pool (fun->machine->base_reg));
10782
10783 /* Annotate all constant pool references to let the scheduler know
10784 they implicitly use the base register. */
10785 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
10786 if (INSN_P (insn))
10787 {
10788 annotate_constant_pool_refs (&PATTERN (insn));
10789 df_insn_rescan (insn);
10790 }
10791 return 0;
10792}
10793
0b8be04c 10794} // anon namespace
10795
10796/* Expand the prologue into a bunch of separate insns. */
10797
10798void
10799s390_emit_prologue (void)
10800{
10801 rtx insn, addr;
10802 rtx temp_reg;
10803 int i;
10804 int offset;
10805 int next_fpr = 0;
20074f87 10806
f81e845f 10807 /* Choose best register to use for temp use within prologue.
c6d481f7 10808 TPF with profiling must avoid the register 14 - the tracing function
10809 needs the original contents of r14 to be preserved. */
f81e845f 10810
ffead1ca 10811 if (!has_hard_reg_initial_val (Pmode, RETURN_REGNUM)
d5bf7b64 10812 && !crtl->is_leaf
1e639cb0 10813 && !TARGET_TPF_PROFILING)
8b4a4127 10814 temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
c6d481f7 10815 else if (flag_split_stack && cfun->stdarg)
10816 temp_reg = gen_rtx_REG (Pmode, 12);
4673c1a0 10817 else
8b4a4127 10818 temp_reg = gen_rtx_REG (Pmode, 1);
4673c1a0 10819
ff4ce128 10820 s390_save_gprs_to_fprs ();
10821
8b4a4127 10822 /* Save call saved gprs. */
67928721 10823 if (cfun_frame_layout.first_save_gpr != -1)
4ac7fd98 10824 {
ffead1ca 10825 insn = save_gprs (stack_pointer_rtx,
10826 cfun_frame_layout.gprs_offset +
b5fdc416 10827 UNITS_PER_LONG * (cfun_frame_layout.first_save_gpr
5214e6ae 10828 - cfun_frame_layout.first_save_gpr_slot),
ffead1ca 10829 cfun_frame_layout.first_save_gpr,
4ac7fd98 10830 cfun_frame_layout.last_save_gpr);
10831 emit_insn (insn);
10832 }
8b4a4127 10833
c2c1332a 10834 /* Dummy insn to mark literal pool slot. */
f81e845f 10835
4fed3f99 10836 if (cfun->machine->base_reg)
10837 emit_insn (gen_main_pool (cfun->machine->base_reg));
f81e845f 10838
67928721 10839 offset = cfun_frame_layout.f0_offset;
8b4a4127 10840
67928721 10841 /* Save f0 and f2. */
6a2469fe 10842 for (i = FPR0_REGNUM; i <= FPR0_REGNUM + 1; i++)
67928721 10843 {
29439367 10844 if (cfun_fpr_save_p (i))
67928721 10845 {
29439367 10846 save_fpr (stack_pointer_rtx, offset, i);
67928721 10847 offset += 8;
10848 }
031bdf83 10849 else if (!TARGET_PACKED_STACK || cfun->stdarg)
10850 offset += 8;
67928721 10851 }
4673c1a0 10852
67928721 10853 /* Save f4 and f6. */
10854 offset = cfun_frame_layout.f4_offset;
6a2469fe 10855 for (i = FPR4_REGNUM; i <= FPR4_REGNUM + 1; i++)
67928721 10856 {
29439367 10857 if (cfun_fpr_save_p (i))
8b4a4127 10858 {
29439367 10859 insn = save_fpr (stack_pointer_rtx, offset, i);
67928721 10860 offset += 8;
10861
031bdf83 10862 /* If f4 and f6 are call clobbered they are saved due to
10863 stdargs and therefore are not frame related. */
29439367 10864 if (!call_really_used_regs[i])
67928721 10865 RTX_FRAME_RELATED_P (insn) = 1;
8b4a4127 10866 }
031bdf83 10867 else if (!TARGET_PACKED_STACK || call_really_used_regs[i])
67928721 10868 offset += 8;
10869 }
10870
646a946e 10871 if (TARGET_PACKED_STACK
67928721 10872 && cfun_save_high_fprs_p
10873 && cfun_frame_layout.f8_offset + cfun_frame_layout.high_fprs * 8 > 0)
10874 {
10875 offset = (cfun_frame_layout.f8_offset
10876 + (cfun_frame_layout.high_fprs - 1) * 8);
10877
6a2469fe 10878 for (i = FPR15_REGNUM; i >= FPR8_REGNUM && offset >= 0; i--)
29439367 10879 if (cfun_fpr_save_p (i))
67928721 10880 {
29439367 10881 insn = save_fpr (stack_pointer_rtx, offset, i);
ffead1ca 10882
67928721 10883 RTX_FRAME_RELATED_P (insn) = 1;
10884 offset -= 8;
10885 }
10886 if (offset >= cfun_frame_layout.f8_offset)
29439367 10887 next_fpr = i;
67928721 10888 }
ffead1ca 10889
646a946e 10890 if (!TARGET_PACKED_STACK)
6a2469fe 10891 next_fpr = cfun_save_high_fprs_p ? FPR15_REGNUM : 0;
4673c1a0 10892
8c0dd614 10893 if (flag_stack_usage_info)
7810b579 10894 current_function_static_stack_size = cfun_frame_layout.frame_size;
10895
8b4a4127 10896 /* Decrement stack pointer. */
4673c1a0 10897
67928721 10898 if (cfun_frame_layout.frame_size > 0)
8b4a4127 10899 {
67928721 10900 rtx frame_off = GEN_INT (-cfun_frame_layout.frame_size);
b9c74b4d 10901 rtx real_frame_off;
4673c1a0 10902
cbb300e8 10903 if (s390_stack_size)
10904 {
00d233e6 10905 HOST_WIDE_INT stack_guard;
cbb300e8 10906
00d233e6 10907 if (s390_stack_guard)
10908 stack_guard = s390_stack_guard;
cbb300e8 10909 else
00d233e6 10910 {
10911 /* If no value for stack guard is provided the smallest power of 2
10912 larger than the current frame size is chosen. */
10913 stack_guard = 1;
10914 while (stack_guard < cfun_frame_layout.frame_size)
10915 stack_guard <<= 1;
10916 }
cbb300e8 10917
00d233e6 10918 if (cfun_frame_layout.frame_size >= s390_stack_size)
10919 {
8ad6fff9 10920 warning (0, "frame size of function %qs is %wd"
00d233e6 10921 " bytes exceeding user provided stack limit of "
8ad6fff9 10922 "%d bytes. "
00d233e6 10923 "An unconditional trap is added.",
10924 current_function_name(), cfun_frame_layout.frame_size,
10925 s390_stack_size);
10926 emit_insn (gen_trap ());
482869e7 10927 emit_barrier ();
00d233e6 10928 }
10929 else
10930 {
b437383e 10931 /* stack_guard has to be smaller than s390_stack_size.
10932 Otherwise we would emit an AND with zero which would
10933 not match the test under mask pattern. */
10934 if (stack_guard >= s390_stack_size)
10935 {
7fe62d25 10936 warning (0, "frame size of function %qs is %wd"
b437383e 10937 " bytes which is more than half the stack size. "
10938 "The dynamic check would not be reliable. "
10939 "No check emitted for this function.",
10940 current_function_name(),
10941 cfun_frame_layout.frame_size);
10942 }
00d233e6 10943 else
b437383e 10944 {
10945 HOST_WIDE_INT stack_check_mask = ((s390_stack_size - 1)
10946 & ~(stack_guard - 1));
10947
10948 rtx t = gen_rtx_AND (Pmode, stack_pointer_rtx,
10949 GEN_INT (stack_check_mask));
10950 if (TARGET_64BIT)
10951 emit_insn (gen_ctrapdi4 (gen_rtx_EQ (VOIDmode,
10952 t, const0_rtx),
10953 t, const0_rtx, const0_rtx));
10954 else
10955 emit_insn (gen_ctrapsi4 (gen_rtx_EQ (VOIDmode,
10956 t, const0_rtx),
10957 t, const0_rtx, const0_rtx));
10958 }
00d233e6 10959 }
cbb300e8 10960 }
10961
ffead1ca 10962 if (s390_warn_framesize > 0
cbb300e8 10963 && cfun_frame_layout.frame_size >= s390_warn_framesize)
7fe62d25 10964 warning (0, "frame size of %qs is %wd bytes",
cbb300e8 10965 current_function_name (), cfun_frame_layout.frame_size);
10966
10967 if (s390_warn_dynamicstack_p && cfun->calls_alloca)
c3ceba8e 10968 warning (0, "%qs uses dynamic stack allocation", current_function_name ());
cbb300e8 10969
8b4a4127 10970 /* Save incoming stack pointer into temp reg. */
e5c64bfc 10971 if (TARGET_BACKCHAIN || next_fpr)
67928721 10972 insn = emit_insn (gen_move_insn (temp_reg, stack_pointer_rtx));
f81e845f 10973
1fc184ee 10974 /* Subtract frame size from stack pointer. */
8b4a4127 10975
51aa1e9c 10976 if (DISP_IN_RANGE (INTVAL (frame_off)))
10977 {
d1f9b275 10978 insn = gen_rtx_SET (stack_pointer_rtx,
ffead1ca 10979 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
b40da9a7 10980 frame_off));
51aa1e9c 10981 insn = emit_insn (insn);
10982 }
10983 else
10984 {
cb888f33 10985 if (!CONST_OK_FOR_K (INTVAL (frame_off)))
51aa1e9c 10986 frame_off = force_const_mem (Pmode, frame_off);
10987
10988 insn = emit_insn (gen_add2_insn (stack_pointer_rtx, frame_off));
20074f87 10989 annotate_constant_pool_refs (&PATTERN (insn));
51aa1e9c 10990 }
8b4a4127 10991
8b4a4127 10992 RTX_FRAME_RELATED_P (insn) = 1;
b9c74b4d 10993 real_frame_off = GEN_INT (-cfun_frame_layout.frame_size);
10994 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
d1f9b275 10995 gen_rtx_SET (stack_pointer_rtx,
b9c74b4d 10996 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
10997 real_frame_off)));
8b4a4127 10998
10999 /* Set backchain. */
f81e845f 11000
e5c64bfc 11001 if (TARGET_BACKCHAIN)
4673c1a0 11002 {
67928721 11003 if (cfun_frame_layout.backchain_offset)
ffead1ca 11004 addr = gen_rtx_MEM (Pmode,
29c05e22 11005 plus_constant (Pmode, stack_pointer_rtx,
67928721 11006 cfun_frame_layout.backchain_offset));
11007 else
ffead1ca 11008 addr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
ce1d5a67 11009 set_mem_alias_set (addr, get_frame_alias_set ());
8b4a4127 11010 insn = emit_insn (gen_move_insn (addr, temp_reg));
4673c1a0 11011 }
90524d70 11012
cbeb677e 11013 /* If we support non-call exceptions (e.g. for Java),
90524d70 11014 we need to make sure the backchain pointer is set up
11015 before any possibly trapping memory access. */
cbeb677e 11016 if (TARGET_BACKCHAIN && cfun->can_throw_non_call_exceptions)
90524d70 11017 {
11018 addr = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
18b42941 11019 emit_clobber (addr);
90524d70 11020 }
8b4a4127 11021 }
4673c1a0 11022
8b4a4127 11023 /* Save fprs 8 - 15 (64 bit ABI). */
f81e845f 11024
67928721 11025 if (cfun_save_high_fprs_p && next_fpr)
8b4a4127 11026 {
062c49fd 11027 /* If the stack might be accessed through a different register
11028 we have to make sure that the stack pointer decrement is not
11029 moved below the use of the stack slots. */
11030 s390_emit_stack_tie ();
11031
ffead1ca 11032 insn = emit_insn (gen_add2_insn (temp_reg,
67928721 11033 GEN_INT (cfun_frame_layout.f8_offset)));
11034
11035 offset = 0;
4673c1a0 11036
6a2469fe 11037 for (i = FPR8_REGNUM; i <= next_fpr; i++)
29439367 11038 if (cfun_fpr_save_p (i))
8b4a4127 11039 {
29c05e22 11040 rtx addr = plus_constant (Pmode, stack_pointer_rtx,
67928721 11041 cfun_frame_layout.frame_size
11042 + cfun_frame_layout.f8_offset
11043 + offset);
ffead1ca 11044
67928721 11045 insn = save_fpr (temp_reg, offset, i);
11046 offset += 8;
8b4a4127 11047 RTX_FRAME_RELATED_P (insn) = 1;
b9c74b4d 11048 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
d1f9b275 11049 gen_rtx_SET (gen_rtx_MEM (DFmode, addr),
b9c74b4d 11050 gen_rtx_REG (DFmode, i)));
8b4a4127 11051 }
11052 }
f81e845f 11053
8b4a4127 11054 /* Set frame pointer, if needed. */
f81e845f 11055
5a5e802f 11056 if (frame_pointer_needed)
8b4a4127 11057 {
11058 insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
11059 RTX_FRAME_RELATED_P (insn) = 1;
11060 }
4673c1a0 11061
8b4a4127 11062 /* Set up got pointer, if needed. */
f81e845f 11063
3072d30e 11064 if (flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM))
20074f87 11065 {
93e0956b 11066 rtx_insn *insns = s390_load_got ();
20074f87 11067
91a55c11 11068 for (rtx_insn *insn = insns; insn; insn = NEXT_INSN (insn))
3072d30e 11069 annotate_constant_pool_refs (&PATTERN (insn));
20074f87 11070
11071 emit_insn (insns);
11072 }
f81e845f 11073
de253666 11074 if (TARGET_TPF_PROFILING)
f81e845f 11075 {
11076 /* Generate a BAS instruction to serve as a function
11077 entry intercept to facilitate the use of tracing
346fecd5 11078 algorithms located at the branch target. */
11079 emit_insn (gen_prologue_tpf ());
f81e845f 11080
11081 /* Emit a blockage here so that all code
11082 lies between the profiling mechanisms. */
11083 emit_insn (gen_blockage ());
11084 }
8b4a4127 11085}
4673c1a0 11086
d2833c15 11087/* Expand the epilogue into a bunch of separate insns. */
4673c1a0 11088
8b4a4127 11089void
7346ca58 11090s390_emit_epilogue (bool sibcall)
8b4a4127 11091{
a3cd0f6a 11092 rtx frame_pointer, return_reg, cfa_restores = NULL_RTX;
abd8f04d 11093 int area_bottom, area_top, offset = 0;
67928721 11094 int next_offset;
8b4a4127 11095 rtvec p;
78c2b526 11096 int i;
4673c1a0 11097
de253666 11098 if (TARGET_TPF_PROFILING)
f81e845f 11099 {
11100
11101 /* Generate a BAS instruction to serve as a function
11102 entry intercept to facilitate the use of tracing
346fecd5 11103 algorithms located at the branch target. */
f81e845f 11104
f81e845f 11105 /* Emit a blockage here so that all code
11106 lies between the profiling mechanisms. */
11107 emit_insn (gen_blockage ());
11108
346fecd5 11109 emit_insn (gen_epilogue_tpf ());
f81e845f 11110 }
11111
8b4a4127 11112 /* Check whether to use frame or stack pointer for restore. */
4673c1a0 11113
ffead1ca 11114 frame_pointer = (frame_pointer_needed
67928721 11115 ? hard_frame_pointer_rtx : stack_pointer_rtx);
4673c1a0 11116
67928721 11117 s390_frame_area (&area_bottom, &area_top);
4673c1a0 11118
f81e845f 11119 /* Check whether we can access the register save area.
8b4a4127 11120 If not, increment the frame pointer as required. */
4673c1a0 11121
8b4a4127 11122 if (area_top <= area_bottom)
11123 {
11124 /* Nothing to restore. */
11125 }
67928721 11126 else if (DISP_IN_RANGE (cfun_frame_layout.frame_size + area_bottom)
11127 && DISP_IN_RANGE (cfun_frame_layout.frame_size + area_top - 1))
8b4a4127 11128 {
11129 /* Area is in range. */
67928721 11130 offset = cfun_frame_layout.frame_size;
8b4a4127 11131 }
11132 else
11133 {
a3cd0f6a 11134 rtx insn, frame_off, cfa;
4673c1a0 11135
f81e845f 11136 offset = area_bottom < 0 ? -area_bottom : 0;
67928721 11137 frame_off = GEN_INT (cfun_frame_layout.frame_size - offset);
4673c1a0 11138
d1f9b275 11139 cfa = gen_rtx_SET (frame_pointer,
a3cd0f6a 11140 gen_rtx_PLUS (Pmode, frame_pointer, frame_off));
51aa1e9c 11141 if (DISP_IN_RANGE (INTVAL (frame_off)))
11142 {
d1f9b275 11143 insn = gen_rtx_SET (frame_pointer,
51aa1e9c 11144 gen_rtx_PLUS (Pmode, frame_pointer, frame_off));
11145 insn = emit_insn (insn);
11146 }
11147 else
11148 {
cb888f33 11149 if (!CONST_OK_FOR_K (INTVAL (frame_off)))
51aa1e9c 11150 frame_off = force_const_mem (Pmode, frame_off);
4673c1a0 11151
51aa1e9c 11152 insn = emit_insn (gen_add2_insn (frame_pointer, frame_off));
20074f87 11153 annotate_constant_pool_refs (&PATTERN (insn));
51aa1e9c 11154 }
a3cd0f6a 11155 add_reg_note (insn, REG_CFA_ADJUST_CFA, cfa);
11156 RTX_FRAME_RELATED_P (insn) = 1;
8b4a4127 11157 }
4673c1a0 11158
8b4a4127 11159 /* Restore call saved fprs. */
11160
11161 if (TARGET_64BIT)
4673c1a0 11162 {
67928721 11163 if (cfun_save_high_fprs_p)
11164 {
11165 next_offset = cfun_frame_layout.f8_offset;
6a2469fe 11166 for (i = FPR8_REGNUM; i <= FPR15_REGNUM; i++)
67928721 11167 {
29439367 11168 if (cfun_fpr_save_p (i))
67928721 11169 {
11170 restore_fpr (frame_pointer,
11171 offset + next_offset, i);
a3cd0f6a 11172 cfa_restores
11173 = alloc_reg_note (REG_CFA_RESTORE,
11174 gen_rtx_REG (DFmode, i), cfa_restores);
67928721 11175 next_offset += 8;
11176 }
11177 }
11178 }
ffead1ca 11179
4673c1a0 11180 }
11181 else
11182 {
67928721 11183 next_offset = cfun_frame_layout.f4_offset;
29439367 11184 /* f4, f6 */
6a2469fe 11185 for (i = FPR4_REGNUM; i <= FPR4_REGNUM + 1; i++)
67928721 11186 {
29439367 11187 if (cfun_fpr_save_p (i))
67928721 11188 {
11189 restore_fpr (frame_pointer,
11190 offset + next_offset, i);
a3cd0f6a 11191 cfa_restores
11192 = alloc_reg_note (REG_CFA_RESTORE,
11193 gen_rtx_REG (DFmode, i), cfa_restores);
67928721 11194 next_offset += 8;
11195 }
646a946e 11196 else if (!TARGET_PACKED_STACK)
67928721 11197 next_offset += 8;
11198 }
ffead1ca 11199
8b4a4127 11200 }
4673c1a0 11201
8b4a4127 11202 /* Return register. */
11203
f81e845f 11204 return_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
8b4a4127 11205
11206 /* Restore call saved gprs. */
11207
67928721 11208 if (cfun_frame_layout.first_restore_gpr != -1)
8b4a4127 11209 {
9a2a66ae 11210 rtx insn, addr;
43935856 11211 int i;
11212
f81e845f 11213 /* Check for global register and save them
43935856 11214 to stack location from where they get restored. */
11215
67928721 11216 for (i = cfun_frame_layout.first_restore_gpr;
11217 i <= cfun_frame_layout.last_restore_gpr;
43935856 11218 i++)
11219 {
a3cd0f6a 11220 if (global_not_special_regno_p (i))
43935856 11221 {
29c05e22 11222 addr = plus_constant (Pmode, frame_pointer,
ffead1ca 11223 offset + cfun_frame_layout.gprs_offset
5214e6ae 11224 + (i - cfun_frame_layout.first_save_gpr_slot)
b5fdc416 11225 * UNITS_PER_LONG);
43935856 11226 addr = gen_rtx_MEM (Pmode, addr);
ce1d5a67 11227 set_mem_alias_set (addr, get_frame_alias_set ());
43935856 11228 emit_move_insn (addr, gen_rtx_REG (Pmode, i));
f81e845f 11229 }
a3cd0f6a 11230 else
11231 cfa_restores
11232 = alloc_reg_note (REG_CFA_RESTORE,
11233 gen_rtx_REG (Pmode, i), cfa_restores);
43935856 11234 }
8b4a4127 11235
7346ca58 11236 if (! sibcall)
4673c1a0 11237 {
7346ca58 11238 /* Fetch return address from stack before load multiple,
d7c99e1a 11239 this will do good for scheduling.
11240
11241 Only do this if we already decided that r14 needs to be
11242 saved to a stack slot. (And not just because r14 happens to
11243 be in between two GPRs which need saving.) Otherwise it
11244 would be difficult to take that decision back in
11245 s390_optimize_prologue. */
1d3cea74 11246 if (cfun_gpr_save_slot (RETURN_REGNUM) == SAVE_SLOT_STACK)
7346ca58 11247 {
11248 int return_regnum = find_unused_clobbered_reg();
11249 if (!return_regnum)
11250 return_regnum = 4;
11251 return_reg = gen_rtx_REG (Pmode, return_regnum);
f588eb9f 11252
29c05e22 11253 addr = plus_constant (Pmode, frame_pointer,
67928721 11254 offset + cfun_frame_layout.gprs_offset
ffead1ca 11255 + (RETURN_REGNUM
5214e6ae 11256 - cfun_frame_layout.first_save_gpr_slot)
b5fdc416 11257 * UNITS_PER_LONG);
7346ca58 11258 addr = gen_rtx_MEM (Pmode, addr);
ce1d5a67 11259 set_mem_alias_set (addr, get_frame_alias_set ());
7346ca58 11260 emit_move_insn (return_reg, addr);
d7c99e1a 11261
11262 /* Once we did that optimization we have to make sure
11263 s390_optimize_prologue does not try to remove the
11264 store of r14 since we will not be able to find the
11265 load issued here. */
11266 cfun_frame_layout.save_return_addr_p = true;
7346ca58 11267 }
4673c1a0 11268 }
8b4a4127 11269
67928721 11270 insn = restore_gprs (frame_pointer,
11271 offset + cfun_frame_layout.gprs_offset
ffead1ca 11272 + (cfun_frame_layout.first_restore_gpr
5214e6ae 11273 - cfun_frame_layout.first_save_gpr_slot)
b5fdc416 11274 * UNITS_PER_LONG,
67928721 11275 cfun_frame_layout.first_restore_gpr,
11276 cfun_frame_layout.last_restore_gpr);
a3cd0f6a 11277 insn = emit_insn (insn);
11278 REG_NOTES (insn) = cfa_restores;
11279 add_reg_note (insn, REG_CFA_DEF_CFA,
29c05e22 11280 plus_constant (Pmode, stack_pointer_rtx,
11281 STACK_POINTER_OFFSET));
a3cd0f6a 11282 RTX_FRAME_RELATED_P (insn) = 1;
8b4a4127 11283 }
4673c1a0 11284
ff4ce128 11285 s390_restore_gprs_from_fprs ();
11286
7346ca58 11287 if (! sibcall)
11288 {
f81e845f 11289
7346ca58 11290 /* Return to caller. */
f588eb9f 11291
7346ca58 11292 p = rtvec_alloc (2);
f588eb9f 11293
1a860023 11294 RTVEC_ELT (p, 0) = ret_rtx;
7346ca58 11295 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, return_reg);
11296 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
11297 }
4673c1a0 11298}
11299
7a64c761 11300/* Implement TARGET_SET_UP_BY_PROLOGUE. */
11301
11302static void
11303s300_set_up_by_prologue (hard_reg_set_container *regs)
11304{
11305 if (cfun->machine->base_reg
11306 && !call_really_used_regs[REGNO (cfun->machine->base_reg)])
11307 SET_HARD_REG_BIT (regs->set, REGNO (cfun->machine->base_reg));
11308}
11309
c6d481f7 11310/* -fsplit-stack support. */
11311
11312/* A SYMBOL_REF for __morestack. */
11313static GTY(()) rtx morestack_ref;
11314
11315/* When using -fsplit-stack, the allocation routines set a field in
11316 the TCB to the bottom of the stack plus this much space, measured
11317 in bytes. */
11318
11319#define SPLIT_STACK_AVAILABLE 1024
11320
11321/* Emit -fsplit-stack prologue, which goes before the regular function
11322 prologue. */
11323
11324void
11325s390_expand_split_stack_prologue (void)
11326{
11327 rtx r1, guard, cc = NULL;
11328 rtx_insn *insn;
11329 /* Offset from thread pointer to __private_ss. */
11330 int psso = TARGET_64BIT ? 0x38 : 0x20;
11331 /* Pointer size in bytes. */
11332 /* Frame size and argument size - the two parameters to __morestack. */
11333 HOST_WIDE_INT frame_size = cfun_frame_layout.frame_size;
11334 /* Align argument size to 8 bytes - simplifies __morestack code. */
11335 HOST_WIDE_INT args_size = crtl->args.size >= 0
11336 ? ((crtl->args.size + 7) & ~7)
11337 : 0;
11338 /* Label to be called by __morestack. */
11339 rtx_code_label *call_done = NULL;
11340 rtx_code_label *parm_base = NULL;
11341 rtx tmp;
11342
11343 gcc_assert (flag_split_stack && reload_completed);
11344 if (!TARGET_CPU_ZARCH)
11345 {
11346 sorry ("CPUs older than z900 are not supported for -fsplit-stack");
11347 return;
11348 }
11349
11350 r1 = gen_rtx_REG (Pmode, 1);
11351
11352 /* If no stack frame will be allocated, don't do anything. */
11353 if (!frame_size)
11354 {
11355 if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
11356 {
11357 /* If va_start is used, just use r15. */
11358 emit_move_insn (r1,
11359 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
11360 GEN_INT (STACK_POINTER_OFFSET)));
11361
11362 }
11363 return;
11364 }
11365
11366 if (morestack_ref == NULL_RTX)
11367 {
11368 morestack_ref = gen_rtx_SYMBOL_REF (Pmode, "__morestack");
11369 SYMBOL_REF_FLAGS (morestack_ref) |= (SYMBOL_FLAG_LOCAL
11370 | SYMBOL_FLAG_FUNCTION);
11371 }
11372
11373 if (CONST_OK_FOR_K (frame_size) || CONST_OK_FOR_Op (frame_size))
11374 {
11375 /* If frame_size will fit in an add instruction, do a stack space
11376 check, and only call __morestack if there's not enough space. */
11377
11378 /* Get thread pointer. r1 is the only register we can always destroy - r0
11379 could contain a static chain (and cannot be used to address memory
11380 anyway), r2-r6 can contain parameters, and r6-r15 are callee-saved. */
11381 emit_move_insn (r1, gen_rtx_REG (Pmode, TP_REGNUM));
11382 /* Aim at __private_ss. */
11383 guard = gen_rtx_MEM (Pmode, plus_constant (Pmode, r1, psso));
11384
11385 /* If less that 1kiB used, skip addition and compare directly with
11386 __private_ss. */
11387 if (frame_size > SPLIT_STACK_AVAILABLE)
11388 {
11389 emit_move_insn (r1, guard);
11390 if (TARGET_64BIT)
11391 emit_insn (gen_adddi3 (r1, r1, GEN_INT (frame_size)));
11392 else
11393 emit_insn (gen_addsi3 (r1, r1, GEN_INT (frame_size)));
11394 guard = r1;
11395 }
11396
11397 /* Compare the (maybe adjusted) guard with the stack pointer. */
11398 cc = s390_emit_compare (LT, stack_pointer_rtx, guard);
11399 }
11400
11401 call_done = gen_label_rtx ();
11402 parm_base = gen_label_rtx ();
11403
11404 /* Emit the parameter block. */
11405 tmp = gen_split_stack_data (parm_base, call_done,
11406 GEN_INT (frame_size),
11407 GEN_INT (args_size));
11408 insn = emit_insn (tmp);
11409 add_reg_note (insn, REG_LABEL_OPERAND, call_done);
11410 LABEL_NUSES (call_done)++;
11411 add_reg_note (insn, REG_LABEL_OPERAND, parm_base);
11412 LABEL_NUSES (parm_base)++;
11413
11414 /* %r1 = litbase. */
11415 insn = emit_move_insn (r1, gen_rtx_LABEL_REF (VOIDmode, parm_base));
11416 add_reg_note (insn, REG_LABEL_OPERAND, parm_base);
11417 LABEL_NUSES (parm_base)++;
11418
11419 /* Now, we need to call __morestack. It has very special calling
11420 conventions: it preserves param/return/static chain registers for
11421 calling main function body, and looks for its own parameters at %r1. */
11422
11423 if (cc != NULL)
11424 {
11425 tmp = gen_split_stack_cond_call (morestack_ref, cc, call_done);
11426
11427 insn = emit_jump_insn (tmp);
11428 JUMP_LABEL (insn) = call_done;
11429 LABEL_NUSES (call_done)++;
11430
11431 /* Mark the jump as very unlikely to be taken. */
11432 add_int_reg_note (insn, REG_BR_PROB, REG_BR_PROB_BASE / 100);
11433
11434 if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
11435 {
11436 /* If va_start is used, and __morestack was not called, just use
11437 r15. */
11438 emit_move_insn (r1,
11439 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
11440 GEN_INT (STACK_POINTER_OFFSET)));
11441 }
11442 }
11443 else
11444 {
11445 tmp = gen_split_stack_call (morestack_ref, call_done);
11446 insn = emit_jump_insn (tmp);
11447 JUMP_LABEL (insn) = call_done;
11448 LABEL_NUSES (call_done)++;
11449 emit_barrier ();
11450 }
11451
11452 /* __morestack will call us here. */
11453
11454 emit_label (call_done);
11455}
11456
11457/* We may have to tell the dataflow pass that the split stack prologue
11458 is initializing a register. */
11459
11460static void
11461s390_live_on_entry (bitmap regs)
11462{
11463 if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
11464 {
11465 gcc_assert (flag_split_stack);
11466 bitmap_set_bit (regs, 1);
11467 }
11468}
11469
7a64c761 11470/* Return true if the function can use simple_return to return outside
11471 of a shrink-wrapped region. At present shrink-wrapping is supported
11472 in all cases. */
11473
11474bool
11475s390_can_use_simple_return_insn (void)
11476{
11477 return true;
11478}
11479
11480/* Return true if the epilogue is guaranteed to contain only a return
11481 instruction and if a direct return can therefore be used instead.
11482 One of the main advantages of using direct return instructions
11483 is that we can then use conditional returns. */
11484
11485bool
11486s390_can_use_return_insn (void)
11487{
11488 int i;
11489
11490 if (!reload_completed)
11491 return false;
11492
11493 if (crtl->profile)
11494 return false;
11495
11496 if (TARGET_TPF_PROFILING)
11497 return false;
11498
11499 for (i = 0; i < 16; i++)
1d3cea74 11500 if (cfun_gpr_save_slot (i) != SAVE_SLOT_NONE)
7a64c761 11501 return false;
11502
06fa0630 11503 /* For 31 bit this is not covered by the frame_size check below
11504 since f4, f6 are saved in the register save area without needing
11505 additional stack space. */
11506 if (!TARGET_64BIT
11507 && (cfun_fpr_save_p (FPR4_REGNUM) || cfun_fpr_save_p (FPR6_REGNUM)))
11508 return false;
11509
7a64c761 11510 if (cfun->machine->base_reg
11511 && !call_really_used_regs[REGNO (cfun->machine->base_reg)])
11512 return false;
11513
11514 return cfun_frame_layout.frame_size == 0;
11515}
4673c1a0 11516
76a4c804 11517/* The VX ABI differs for vararg functions. Therefore we need the
11518 prototype of the callee to be available when passing vector type
11519 values. */
11520static const char *
11521s390_invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
11522{
11523 return ((TARGET_VX_ABI
11524 && typelist == 0
11525 && VECTOR_TYPE_P (TREE_TYPE (val))
11526 && (funcdecl == NULL_TREE
11527 || (TREE_CODE (funcdecl) == FUNCTION_DECL
11528 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
19abb0ad 11529 ? N_("vector argument passed to unprototyped function")
76a4c804 11530 : NULL);
11531}
11532
11533
f81e845f 11534/* Return the size in bytes of a function argument of
56769981 11535 type TYPE and/or mode MODE. At least one of TYPE or
11536 MODE must be specified. */
4673c1a0 11537
11538static int
3754d046 11539s390_function_arg_size (machine_mode mode, const_tree type)
4673c1a0 11540{
11541 if (type)
11542 return int_size_in_bytes (type);
11543
0c034860 11544 /* No type info available for some library calls ... */
4673c1a0 11545 if (mode != BLKmode)
11546 return GET_MODE_SIZE (mode);
11547
11548 /* If we have neither type nor mode, abort */
32eda510 11549 gcc_unreachable ();
4673c1a0 11550}
11551
76a4c804 11552/* Return true if a function argument of type TYPE and mode MODE
11553 is to be passed in a vector register, if available. */
11554
11555bool
11556s390_function_arg_vector (machine_mode mode, const_tree type)
11557{
11558 if (!TARGET_VX_ABI)
11559 return false;
11560
11561 if (s390_function_arg_size (mode, type) > 16)
11562 return false;
11563
11564 /* No type info available for some library calls ... */
11565 if (!type)
11566 return VECTOR_MODE_P (mode);
11567
11568 /* The ABI says that record types with a single member are treated
11569 just like that member would be. */
11570 while (TREE_CODE (type) == RECORD_TYPE)
11571 {
11572 tree field, single = NULL_TREE;
11573
11574 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
11575 {
11576 if (TREE_CODE (field) != FIELD_DECL)
11577 continue;
11578
11579 if (single == NULL_TREE)
11580 single = TREE_TYPE (field);
11581 else
11582 return false;
11583 }
11584
11585 if (single == NULL_TREE)
11586 return false;
11587 else
11588 {
11589 /* If the field declaration adds extra byte due to
11590 e.g. padding this is not accepted as vector type. */
11591 if (int_size_in_bytes (single) <= 0
11592 || int_size_in_bytes (single) != int_size_in_bytes (type))
11593 return false;
11594 type = single;
11595 }
11596 }
11597
11598 return VECTOR_TYPE_P (type);
11599}
11600
59652f3f 11601/* Return true if a function argument of type TYPE and mode MODE
11602 is to be passed in a floating-point register, if available. */
11603
11604static bool
3754d046 11605s390_function_arg_float (machine_mode mode, const_tree type)
59652f3f 11606{
76a4c804 11607 if (s390_function_arg_size (mode, type) > 8)
201e502c 11608 return false;
11609
59652f3f 11610 /* Soft-float changes the ABI: no floating-point registers are used. */
11611 if (TARGET_SOFT_FLOAT)
11612 return false;
11613
11614 /* No type info available for some library calls ... */
11615 if (!type)
36868490 11616 return mode == SFmode || mode == DFmode || mode == SDmode || mode == DDmode;
59652f3f 11617
11618 /* The ABI says that record types with a single member are treated
11619 just like that member would be. */
11620 while (TREE_CODE (type) == RECORD_TYPE)
11621 {
11622 tree field, single = NULL_TREE;
11623
1767a056 11624 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
59652f3f 11625 {
11626 if (TREE_CODE (field) != FIELD_DECL)
11627 continue;
11628
11629 if (single == NULL_TREE)
11630 single = TREE_TYPE (field);
11631 else
11632 return false;
11633 }
11634
11635 if (single == NULL_TREE)
11636 return false;
11637 else
11638 type = single;
11639 }
11640
11641 return TREE_CODE (type) == REAL_TYPE;
11642}
11643
201e502c 11644/* Return true if a function argument of type TYPE and mode MODE
11645 is to be passed in an integer register, or a pair of integer
11646 registers, if available. */
11647
11648static bool
3754d046 11649s390_function_arg_integer (machine_mode mode, const_tree type)
201e502c 11650{
11651 int size = s390_function_arg_size (mode, type);
11652 if (size > 8)
11653 return false;
11654
11655 /* No type info available for some library calls ... */
11656 if (!type)
11657 return GET_MODE_CLASS (mode) == MODE_INT
36868490 11658 || (TARGET_SOFT_FLOAT && SCALAR_FLOAT_MODE_P (mode));
201e502c 11659
11660 /* We accept small integral (and similar) types. */
11661 if (INTEGRAL_TYPE_P (type)
f588eb9f 11662 || POINTER_TYPE_P (type)
bd3e12e5 11663 || TREE_CODE (type) == NULLPTR_TYPE
201e502c 11664 || TREE_CODE (type) == OFFSET_TYPE
11665 || (TARGET_SOFT_FLOAT && TREE_CODE (type) == REAL_TYPE))
11666 return true;
11667
11668 /* We also accept structs of size 1, 2, 4, 8 that are not
f588eb9f 11669 passed in floating-point registers. */
201e502c 11670 if (AGGREGATE_TYPE_P (type)
11671 && exact_log2 (size) >= 0
11672 && !s390_function_arg_float (mode, type))
11673 return true;
11674
11675 return false;
11676}
11677
56769981 11678/* Return 1 if a function argument of type TYPE and mode MODE
11679 is to be passed by reference. The ABI specifies that only
11680 structures of size 1, 2, 4, or 8 bytes are passed by value,
11681 all other structures (and complex numbers) are passed by
11682 reference. */
11683
b981d932 11684static bool
39cba157 11685s390_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED,
3754d046 11686 machine_mode mode, const_tree type,
b981d932 11687 bool named ATTRIBUTE_UNUSED)
4673c1a0 11688{
11689 int size = s390_function_arg_size (mode, type);
76a4c804 11690
11691 if (s390_function_arg_vector (mode, type))
11692 return false;
11693
201e502c 11694 if (size > 8)
11695 return true;
4673c1a0 11696
11697 if (type)
11698 {
201e502c 11699 if (AGGREGATE_TYPE_P (type) && exact_log2 (size) < 0)
76a4c804 11700 return true;
4673c1a0 11701
201e502c 11702 if (TREE_CODE (type) == COMPLEX_TYPE
11703 || TREE_CODE (type) == VECTOR_TYPE)
76a4c804 11704 return true;
4673c1a0 11705 }
f81e845f 11706
76a4c804 11707 return false;
4673c1a0 11708}
11709
11710/* Update the data in CUM to advance over an argument of mode MODE and
11711 data type TYPE. (TYPE is null for libcalls where that information
56769981 11712 may not be available.). The boolean NAMED specifies whether the
11713 argument is a named argument (as opposed to an unnamed argument
11714 matching an ellipsis). */
4673c1a0 11715
12bc26aa 11716static void
3754d046 11717s390_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
76a4c804 11718 const_tree type, bool named)
4673c1a0 11719{
39cba157 11720 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
11721
76a4c804 11722 if (s390_function_arg_vector (mode, type))
11723 {
11724 /* We are called for unnamed vector stdarg arguments which are
11725 passed on the stack. In this case this hook does not have to
11726 do anything since stack arguments are tracked by common
11727 code. */
11728 if (!named)
11729 return;
11730 cum->vrs += 1;
11731 }
11732 else if (s390_function_arg_float (mode, type))
4673c1a0 11733 {
59652f3f 11734 cum->fprs += 1;
4673c1a0 11735 }
201e502c 11736 else if (s390_function_arg_integer (mode, type))
4673c1a0 11737 {
11738 int size = s390_function_arg_size (mode, type);
b5fdc416 11739 cum->gprs += ((size + UNITS_PER_LONG - 1) / UNITS_PER_LONG);
4673c1a0 11740 }
201e502c 11741 else
32eda510 11742 gcc_unreachable ();
4673c1a0 11743}
11744
56769981 11745/* Define where to put the arguments to a function.
11746 Value is zero to push the argument on the stack,
11747 or a hard register in which to store the argument.
11748
11749 MODE is the argument's machine mode.
11750 TYPE is the data type of the argument (as a tree).
11751 This is null for libcalls where that information may
11752 not be available.
11753 CUM is a variable of type CUMULATIVE_ARGS which gives info about
11754 the preceding args and about the function being called.
11755 NAMED is nonzero if this argument is a named parameter
f81e845f 11756 (otherwise it is an extra parameter matching an ellipsis).
56769981 11757
11758 On S/390, we use general purpose registers 2 through 6 to
11759 pass integer, pointer, and certain structure arguments, and
11760 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
11761 to pass floating point arguments. All remaining arguments
11762 are pushed to the stack. */
4673c1a0 11763
12bc26aa 11764static rtx
3754d046 11765s390_function_arg (cumulative_args_t cum_v, machine_mode mode,
76a4c804 11766 const_tree type, bool named)
4673c1a0 11767{
39cba157 11768 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
11769
6b7cfb9c 11770 if (!named)
11771 s390_check_type_for_vector_abi (type, true, false);
76a4c804 11772
11773 if (s390_function_arg_vector (mode, type))
11774 {
11775 /* Vector arguments being part of the ellipsis are passed on the
11776 stack. */
11777 if (!named || (cum->vrs + 1 > VEC_ARG_NUM_REG))
11778 return NULL_RTX;
11779
11780 return gen_rtx_REG (mode, cum->vrs + FIRST_VEC_ARG_REGNO);
11781 }
11782 else if (s390_function_arg_float (mode, type))
4673c1a0 11783 {
6902d973 11784 if (cum->fprs + 1 > FP_ARG_NUM_REG)
76a4c804 11785 return NULL_RTX;
4673c1a0 11786 else
1a83b3ff 11787 return gen_rtx_REG (mode, cum->fprs + 16);
4673c1a0 11788 }
201e502c 11789 else if (s390_function_arg_integer (mode, type))
4673c1a0 11790 {
11791 int size = s390_function_arg_size (mode, type);
b5fdc416 11792 int n_gprs = (size + UNITS_PER_LONG - 1) / UNITS_PER_LONG;
4673c1a0 11793
6902d973 11794 if (cum->gprs + n_gprs > GP_ARG_NUM_REG)
76a4c804 11795 return NULL_RTX;
b5fdc416 11796 else if (n_gprs == 1 || UNITS_PER_WORD == UNITS_PER_LONG)
1a83b3ff 11797 return gen_rtx_REG (mode, cum->gprs + 2);
b5fdc416 11798 else if (n_gprs == 2)
11799 {
11800 rtvec p = rtvec_alloc (2);
11801
11802 RTVEC_ELT (p, 0)
11803 = gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, cum->gprs + 2),
11804 const0_rtx);
11805 RTVEC_ELT (p, 1)
11806 = gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, cum->gprs + 3),
11807 GEN_INT (4));
11808
11809 return gen_rtx_PARALLEL (mode, p);
11810 }
4673c1a0 11811 }
201e502c 11812
11813 /* After the real arguments, expand_call calls us once again
11814 with a void_type_node type. Whatever we return here is
11815 passed as operand 2 to the call expanders.
11816
11817 We don't need this feature ... */
11818 else if (type == void_type_node)
11819 return const0_rtx;
11820
32eda510 11821 gcc_unreachable ();
201e502c 11822}
11823
11824/* Return true if return values of type TYPE should be returned
11825 in a memory buffer whose address is passed by the caller as
11826 hidden first argument. */
11827
11828static bool
fb80456a 11829s390_return_in_memory (const_tree type, const_tree fundecl ATTRIBUTE_UNUSED)
201e502c 11830{
11831 /* We accept small integral (and similar) types. */
11832 if (INTEGRAL_TYPE_P (type)
f588eb9f 11833 || POINTER_TYPE_P (type)
201e502c 11834 || TREE_CODE (type) == OFFSET_TYPE
11835 || TREE_CODE (type) == REAL_TYPE)
11836 return int_size_in_bytes (type) > 8;
11837
76a4c804 11838 /* vector types which fit into a VR. */
11839 if (TARGET_VX_ABI
11840 && VECTOR_TYPE_P (type)
11841 && int_size_in_bytes (type) <= 16)
11842 return false;
11843
201e502c 11844 /* Aggregates and similar constructs are always returned
11845 in memory. */
11846 if (AGGREGATE_TYPE_P (type)
11847 || TREE_CODE (type) == COMPLEX_TYPE
76a4c804 11848 || VECTOR_TYPE_P (type))
201e502c 11849 return true;
11850
11851 /* ??? We get called on all sorts of random stuff from
11852 aggregate_value_p. We can't abort, but it's not clear
11853 what's safe to return. Pretend it's a struct I guess. */
11854 return true;
11855}
11856
3b2411a8 11857/* Function arguments and return values are promoted to word size. */
11858
3754d046 11859static machine_mode
11860s390_promote_function_mode (const_tree type, machine_mode mode,
3b2411a8 11861 int *punsignedp,
11862 const_tree fntype ATTRIBUTE_UNUSED,
11863 int for_return ATTRIBUTE_UNUSED)
11864{
11865 if (INTEGRAL_MODE_P (mode)
b5fdc416 11866 && GET_MODE_SIZE (mode) < UNITS_PER_LONG)
3b2411a8 11867 {
adaf4ef0 11868 if (type != NULL_TREE && POINTER_TYPE_P (type))
3b2411a8 11869 *punsignedp = POINTERS_EXTEND_UNSIGNED;
11870 return Pmode;
11871 }
11872
11873 return mode;
11874}
11875
dc3b3062 11876/* Define where to return a (scalar) value of type RET_TYPE.
11877 If RET_TYPE is null, define where to return a (scalar)
201e502c 11878 value of mode MODE from a libcall. */
11879
dc3b3062 11880static rtx
3754d046 11881s390_function_and_libcall_value (machine_mode mode,
dc3b3062 11882 const_tree ret_type,
11883 const_tree fntype_or_decl,
11884 bool outgoing ATTRIBUTE_UNUSED)
201e502c 11885{
76a4c804 11886 /* For vector return types it is important to use the RET_TYPE
11887 argument whenever available since the middle-end might have
11888 changed the mode to a scalar mode. */
11889 bool vector_ret_type_p = ((ret_type && VECTOR_TYPE_P (ret_type))
11890 || (!ret_type && VECTOR_MODE_P (mode)));
11891
dc3b3062 11892 /* For normal functions perform the promotion as
11893 promote_function_mode would do. */
11894 if (ret_type)
201e502c 11895 {
dc3b3062 11896 int unsignedp = TYPE_UNSIGNED (ret_type);
11897 mode = promote_function_mode (ret_type, mode, &unsignedp,
11898 fntype_or_decl, 1);
201e502c 11899 }
11900
76a4c804 11901 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT
11902 || SCALAR_FLOAT_MODE_P (mode)
11903 || (TARGET_VX_ABI && vector_ret_type_p));
11904 gcc_assert (GET_MODE_SIZE (mode) <= (TARGET_VX_ABI ? 16 : 8));
201e502c 11905
76a4c804 11906 if (TARGET_VX_ABI && vector_ret_type_p)
11907 return gen_rtx_REG (mode, FIRST_VEC_ARG_REGNO);
11908 else if (TARGET_HARD_FLOAT && SCALAR_FLOAT_MODE_P (mode))
201e502c 11909 return gen_rtx_REG (mode, 16);
b5fdc416 11910 else if (GET_MODE_SIZE (mode) <= UNITS_PER_LONG
11911 || UNITS_PER_LONG == UNITS_PER_WORD)
201e502c 11912 return gen_rtx_REG (mode, 2);
b5fdc416 11913 else if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_LONG)
11914 {
dc3b3062 11915 /* This case is triggered when returning a 64 bit value with
11916 -m31 -mzarch. Although the value would fit into a single
11917 register it has to be forced into a 32 bit register pair in
11918 order to match the ABI. */
b5fdc416 11919 rtvec p = rtvec_alloc (2);
11920
11921 RTVEC_ELT (p, 0)
11922 = gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, 2), const0_rtx);
11923 RTVEC_ELT (p, 1)
11924 = gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, 3), GEN_INT (4));
11925
11926 return gen_rtx_PARALLEL (mode, p);
11927 }
11928
11929 gcc_unreachable ();
4673c1a0 11930}
11931
dc3b3062 11932/* Define where to return a scalar return value of type RET_TYPE. */
11933
11934static rtx
11935s390_function_value (const_tree ret_type, const_tree fn_decl_or_type,
11936 bool outgoing)
11937{
11938 return s390_function_and_libcall_value (TYPE_MODE (ret_type), ret_type,
11939 fn_decl_or_type, outgoing);
11940}
11941
11942/* Define where to return a scalar libcall return value of mode
11943 MODE. */
11944
11945static rtx
3754d046 11946s390_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
dc3b3062 11947{
11948 return s390_function_and_libcall_value (mode, NULL_TREE,
11949 NULL_TREE, true);
11950}
11951
4673c1a0 11952
56769981 11953/* Create and return the va_list datatype.
11954
11955 On S/390, va_list is an array type equivalent to
11956
11957 typedef struct __va_list_tag
11958 {
11959 long __gpr;
11960 long __fpr;
11961 void *__overflow_arg_area;
11962 void *__reg_save_area;
56769981 11963 } va_list[1];
11964
11965 where __gpr and __fpr hold the number of general purpose
11966 or floating point arguments used up to now, respectively,
f81e845f 11967 __overflow_arg_area points to the stack location of the
56769981 11968 next argument passed on the stack, and __reg_save_area
11969 always points to the start of the register area in the
11970 call frame of the current function. The function prologue
11971 saves all registers used for argument passing into this
11972 area if the function uses variable arguments. */
4673c1a0 11973
2e15d750 11974static tree
11975s390_build_builtin_va_list (void)
4673c1a0 11976{
11977 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
11978
5ebb663d 11979 record = lang_hooks.types.make_type (RECORD_TYPE);
4673c1a0 11980
11981 type_decl =
54e46243 11982 build_decl (BUILTINS_LOCATION,
11983 TYPE_DECL, get_identifier ("__va_list_tag"), record);
4673c1a0 11984
54e46243 11985 f_gpr = build_decl (BUILTINS_LOCATION,
11986 FIELD_DECL, get_identifier ("__gpr"),
4673c1a0 11987 long_integer_type_node);
54e46243 11988 f_fpr = build_decl (BUILTINS_LOCATION,
11989 FIELD_DECL, get_identifier ("__fpr"),
4673c1a0 11990 long_integer_type_node);
54e46243 11991 f_ovf = build_decl (BUILTINS_LOCATION,
11992 FIELD_DECL, get_identifier ("__overflow_arg_area"),
4673c1a0 11993 ptr_type_node);
54e46243 11994 f_sav = build_decl (BUILTINS_LOCATION,
11995 FIELD_DECL, get_identifier ("__reg_save_area"),
4673c1a0 11996 ptr_type_node);
11997
6902d973 11998 va_list_gpr_counter_field = f_gpr;
11999 va_list_fpr_counter_field = f_fpr;
12000
4673c1a0 12001 DECL_FIELD_CONTEXT (f_gpr) = record;
12002 DECL_FIELD_CONTEXT (f_fpr) = record;
12003 DECL_FIELD_CONTEXT (f_ovf) = record;
12004 DECL_FIELD_CONTEXT (f_sav) = record;
12005
bc907808 12006 TYPE_STUB_DECL (record) = type_decl;
4673c1a0 12007 TYPE_NAME (record) = type_decl;
12008 TYPE_FIELDS (record) = f_gpr;
1767a056 12009 DECL_CHAIN (f_gpr) = f_fpr;
12010 DECL_CHAIN (f_fpr) = f_ovf;
12011 DECL_CHAIN (f_ovf) = f_sav;
4673c1a0 12012
12013 layout_type (record);
12014
12015 /* The correct type is an array type of one element. */
12016 return build_array_type (record, build_index_type (size_zero_node));
12017}
12018
56769981 12019/* Implement va_start by filling the va_list structure VALIST.
7ccc713a 12020 STDARG_P is always true, and ignored.
12021 NEXTARG points to the first anonymous stack argument.
56769981 12022
8ef587dc 12023 The following global variables are used to initialize
56769981 12024 the va_list structure:
12025
abe32cce 12026 crtl->args.info:
56769981 12027 holds number of gprs and fprs used for named arguments.
abe32cce 12028 crtl->args.arg_offset_rtx:
56769981 12029 holds the offset of the first anonymous stack argument
12030 (relative to the virtual arg pointer). */
4673c1a0 12031
8a58ed0a 12032static void
b40da9a7 12033s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
4673c1a0 12034{
12035 HOST_WIDE_INT n_gpr, n_fpr;
12036 int off;
12037 tree f_gpr, f_fpr, f_ovf, f_sav;
12038 tree gpr, fpr, ovf, sav, t;
12039
12040 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
1767a056 12041 f_fpr = DECL_CHAIN (f_gpr);
12042 f_ovf = DECL_CHAIN (f_fpr);
12043 f_sav = DECL_CHAIN (f_ovf);
4673c1a0 12044
170efcd4 12045 valist = build_simple_mem_ref (valist);
ed03eadb 12046 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
12047 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
12048 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
12049 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
4673c1a0 12050
12051 /* Count number of gp and fp argument registers used. */
12052
abe32cce 12053 n_gpr = crtl->args.info.gprs;
12054 n_fpr = crtl->args.info.fprs;
4673c1a0 12055
6902d973 12056 if (cfun->va_list_gpr_size)
12057 {
75a70cf9 12058 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
12059 build_int_cst (NULL_TREE, n_gpr));
6902d973 12060 TREE_SIDE_EFFECTS (t) = 1;
12061 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
12062 }
4673c1a0 12063
6902d973 12064 if (cfun->va_list_fpr_size)
12065 {
75a70cf9 12066 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
ed03eadb 12067 build_int_cst (NULL_TREE, n_fpr));
6902d973 12068 TREE_SIDE_EFFECTS (t) = 1;
12069 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
12070 }
4673c1a0 12071
c6d481f7 12072 if (flag_split_stack
12073 && (lookup_attribute ("no_split_stack", DECL_ATTRIBUTES (cfun->decl))
12074 == NULL)
12075 && cfun->machine->split_stack_varargs_pointer == NULL_RTX)
12076 {
12077 rtx reg;
12078 rtx_insn *seq;
12079
12080 reg = gen_reg_rtx (Pmode);
12081 cfun->machine->split_stack_varargs_pointer = reg;
12082
12083 start_sequence ();
12084 emit_move_insn (reg, gen_rtx_REG (Pmode, 1));
12085 seq = get_insns ();
12086 end_sequence ();
12087
12088 push_topmost_sequence ();
12089 emit_insn_after (seq, entry_of_function ());
12090 pop_topmost_sequence ();
12091 }
12092
76a4c804 12093 /* Find the overflow area.
12094 FIXME: This currently is too pessimistic when the vector ABI is
12095 enabled. In that case we *always* set up the overflow area
12096 pointer. */
6902d973 12097 if (n_gpr + cfun->va_list_gpr_size > GP_ARG_NUM_REG
76a4c804 12098 || n_fpr + cfun->va_list_fpr_size > FP_ARG_NUM_REG
12099 || TARGET_VX_ABI)
6902d973 12100 {
c6d481f7 12101 if (cfun->machine->split_stack_varargs_pointer == NULL_RTX)
12102 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
12103 else
12104 t = make_tree (TREE_TYPE (ovf), cfun->machine->split_stack_varargs_pointer);
4673c1a0 12105
abe32cce 12106 off = INTVAL (crtl->args.arg_offset_rtx);
6902d973 12107 off = off < 0 ? 0 : off;
12108 if (TARGET_DEBUG_ARG)
12109 fprintf (stderr, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
12110 (int)n_gpr, (int)n_fpr, off);
4673c1a0 12111
2cc66f2a 12112 t = fold_build_pointer_plus_hwi (t, off);
4673c1a0 12113
75a70cf9 12114 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
6902d973 12115 TREE_SIDE_EFFECTS (t) = 1;
12116 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
12117 }
4673c1a0 12118
12119 /* Find the register save area. */
6902d973 12120 if ((cfun->va_list_gpr_size && n_gpr < GP_ARG_NUM_REG)
12121 || (cfun->va_list_fpr_size && n_fpr < FP_ARG_NUM_REG))
12122 {
12123 t = make_tree (TREE_TYPE (sav), return_address_pointer_rtx);
2cc66f2a 12124 t = fold_build_pointer_plus_hwi (t, -RETURN_REGNUM * UNITS_PER_LONG);
ffead1ca 12125
75a70cf9 12126 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
6902d973 12127 TREE_SIDE_EFFECTS (t) = 1;
12128 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
12129 }
4673c1a0 12130}
12131
f81e845f 12132/* Implement va_arg by updating the va_list structure
56769981 12133 VALIST as required to retrieve an argument of type
f81e845f 12134 TYPE, and returning that argument.
12135
56769981 12136 Generates code equivalent to:
f81e845f 12137
4673c1a0 12138 if (integral value) {
12139 if (size <= 4 && args.gpr < 5 ||
f81e845f 12140 size > 4 && args.gpr < 4 )
4673c1a0 12141 ret = args.reg_save_area[args.gpr+8]
12142 else
12143 ret = *args.overflow_arg_area++;
76a4c804 12144 } else if (vector value) {
12145 ret = *args.overflow_arg_area;
12146 args.overflow_arg_area += size / 8;
4673c1a0 12147 } else if (float value) {
12148 if (args.fgpr < 2)
12149 ret = args.reg_save_area[args.fpr+64]
12150 else
12151 ret = *args.overflow_arg_area++;
12152 } else if (aggregate value) {
12153 if (args.gpr < 5)
12154 ret = *args.reg_save_area[args.gpr]
12155 else
12156 ret = **args.overflow_arg_area++;
12157 } */
12158
875862bf 12159static tree
ffead1ca 12160s390_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
75a70cf9 12161 gimple_seq *post_p ATTRIBUTE_UNUSED)
4673c1a0 12162{
12163 tree f_gpr, f_fpr, f_ovf, f_sav;
12164 tree gpr, fpr, ovf, sav, reg, t, u;
12165 int indirect_p, size, n_reg, sav_ofs, sav_scale, max_reg;
883b2519 12166 tree lab_false, lab_over = NULL_TREE;
76a4c804 12167 tree addr = create_tmp_var (ptr_type_node, "addr");
12168 bool left_align_p; /* How a value < UNITS_PER_LONG is aligned within
12169 a stack slot. */
4673c1a0 12170
12171 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
1767a056 12172 f_fpr = DECL_CHAIN (f_gpr);
12173 f_ovf = DECL_CHAIN (f_fpr);
12174 f_sav = DECL_CHAIN (f_ovf);
4673c1a0 12175
ed03eadb 12176 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
12177 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
ed03eadb 12178 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
4673c1a0 12179
75a70cf9 12180 /* The tree for args* cannot be shared between gpr/fpr and ovf since
12181 both appear on a lhs. */
12182 valist = unshare_expr (valist);
12183 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
12184
4673c1a0 12185 size = int_size_in_bytes (type);
12186
6b7cfb9c 12187 s390_check_type_for_vector_abi (type, true, false);
12188
b981d932 12189 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
4673c1a0 12190 {
12191 if (TARGET_DEBUG_ARG)
12192 {
12193 fprintf (stderr, "va_arg: aggregate type");
12194 debug_tree (type);
12195 }
12196
12197 /* Aggregates are passed by reference. */
12198 indirect_p = 1;
12199 reg = gpr;
12200 n_reg = 1;
99e8a714 12201
646a946e 12202 /* kernel stack layout on 31 bit: It is assumed here that no padding
99e8a714 12203 will be added by s390_frame_info because for va_args always an even
12204 number of gprs has to be saved r15-r2 = 14 regs. */
b5fdc416 12205 sav_ofs = 2 * UNITS_PER_LONG;
12206 sav_scale = UNITS_PER_LONG;
12207 size = UNITS_PER_LONG;
6902d973 12208 max_reg = GP_ARG_NUM_REG - n_reg;
76a4c804 12209 left_align_p = false;
12210 }
12211 else if (s390_function_arg_vector (TYPE_MODE (type), type))
12212 {
12213 if (TARGET_DEBUG_ARG)
12214 {
12215 fprintf (stderr, "va_arg: vector type");
12216 debug_tree (type);
12217 }
12218
12219 indirect_p = 0;
12220 reg = NULL_TREE;
12221 n_reg = 0;
12222 sav_ofs = 0;
12223 sav_scale = 8;
12224 max_reg = 0;
12225 left_align_p = true;
4673c1a0 12226 }
59652f3f 12227 else if (s390_function_arg_float (TYPE_MODE (type), type))
4673c1a0 12228 {
12229 if (TARGET_DEBUG_ARG)
12230 {
12231 fprintf (stderr, "va_arg: float type");
12232 debug_tree (type);
12233 }
12234
12235 /* FP args go in FP registers, if present. */
12236 indirect_p = 0;
12237 reg = fpr;
12238 n_reg = 1;
b5fdc416 12239 sav_ofs = 16 * UNITS_PER_LONG;
4673c1a0 12240 sav_scale = 8;
6902d973 12241 max_reg = FP_ARG_NUM_REG - n_reg;
76a4c804 12242 left_align_p = false;
4673c1a0 12243 }
12244 else
12245 {
12246 if (TARGET_DEBUG_ARG)
12247 {
12248 fprintf (stderr, "va_arg: other type");
12249 debug_tree (type);
12250 }
12251
12252 /* Otherwise into GP registers. */
12253 indirect_p = 0;
12254 reg = gpr;
b5fdc416 12255 n_reg = (size + UNITS_PER_LONG - 1) / UNITS_PER_LONG;
99e8a714 12256
646a946e 12257 /* kernel stack layout on 31 bit: It is assumed here that no padding
12258 will be added by s390_frame_info because for va_args always an even
12259 number of gprs has to be saved r15-r2 = 14 regs. */
b5fdc416 12260 sav_ofs = 2 * UNITS_PER_LONG;
f81e845f 12261
b5fdc416 12262 if (size < UNITS_PER_LONG)
12263 sav_ofs += UNITS_PER_LONG - size;
4673c1a0 12264
b5fdc416 12265 sav_scale = UNITS_PER_LONG;
6902d973 12266 max_reg = GP_ARG_NUM_REG - n_reg;
76a4c804 12267 left_align_p = false;
4673c1a0 12268 }
12269
12270 /* Pull the value out of the saved registers ... */
12271
76a4c804 12272 if (reg != NULL_TREE)
12273 {
12274 /*
12275 if (reg > ((typeof (reg))max_reg))
12276 goto lab_false;
4673c1a0 12277
76a4c804 12278 addr = sav + sav_ofs + reg * save_scale;
4673c1a0 12279
76a4c804 12280 goto lab_over;
4673c1a0 12281
76a4c804 12282 lab_false:
12283 */
12284
12285 lab_false = create_artificial_label (UNKNOWN_LOCATION);
12286 lab_over = create_artificial_label (UNKNOWN_LOCATION);
12287
12288 t = fold_convert (TREE_TYPE (reg), size_int (max_reg));
12289 t = build2 (GT_EXPR, boolean_type_node, reg, t);
12290 u = build1 (GOTO_EXPR, void_type_node, lab_false);
12291 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
12292 gimplify_and_add (t, pre_p);
4673c1a0 12293
76a4c804 12294 t = fold_build_pointer_plus_hwi (sav, sav_ofs);
12295 u = build2 (MULT_EXPR, TREE_TYPE (reg), reg,
12296 fold_convert (TREE_TYPE (reg), size_int (sav_scale)));
12297 t = fold_build_pointer_plus (t, u);
4673c1a0 12298
76a4c804 12299 gimplify_assign (addr, t, pre_p);
4673c1a0 12300
76a4c804 12301 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
12302
12303 gimple_seq_add_stmt (pre_p, gimple_build_label (lab_false));
12304 }
4673c1a0 12305
12306 /* ... Otherwise out of the overflow area. */
12307
875862bf 12308 t = ovf;
76a4c804 12309 if (size < UNITS_PER_LONG && !left_align_p)
2cc66f2a 12310 t = fold_build_pointer_plus_hwi (t, UNITS_PER_LONG - size);
875862bf 12311
12312 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
12313
75a70cf9 12314 gimplify_assign (addr, t, pre_p);
875862bf 12315
76a4c804 12316 if (size < UNITS_PER_LONG && left_align_p)
12317 t = fold_build_pointer_plus_hwi (t, UNITS_PER_LONG);
12318 else
12319 t = fold_build_pointer_plus_hwi (t, size);
12320
75a70cf9 12321 gimplify_assign (ovf, t, pre_p);
875862bf 12322
76a4c804 12323 if (reg != NULL_TREE)
12324 gimple_seq_add_stmt (pre_p, gimple_build_label (lab_over));
875862bf 12325
12326
12327 /* Increment register save count. */
12328
76a4c804 12329 if (n_reg > 0)
12330 {
12331 u = build2 (PREINCREMENT_EXPR, TREE_TYPE (reg), reg,
12332 fold_convert (TREE_TYPE (reg), size_int (n_reg)));
12333 gimplify_and_add (u, pre_p);
12334 }
875862bf 12335
12336 if (indirect_p)
12337 {
8115f0af 12338 t = build_pointer_type_for_mode (build_pointer_type (type),
12339 ptr_mode, true);
875862bf 12340 addr = fold_convert (t, addr);
12341 addr = build_va_arg_indirect_ref (addr);
12342 }
12343 else
12344 {
8115f0af 12345 t = build_pointer_type_for_mode (type, ptr_mode, true);
875862bf 12346 addr = fold_convert (t, addr);
12347 }
12348
12349 return build_va_arg_indirect_ref (addr);
12350}
12351
5ada7a14 12352/* Emit rtl for the tbegin or tbegin_retry (RETRY != NULL_RTX)
12353 expanders.
12354 DEST - Register location where CC will be stored.
12355 TDB - Pointer to a 256 byte area where to store the transaction.
12356 diagnostic block. NULL if TDB is not needed.
12357 RETRY - Retry count value. If non-NULL a retry loop for CC2
12358 is emitted
12359 CLOBBER_FPRS_P - If true clobbers for all FPRs are emitted as part
12360 of the tbegin instruction pattern. */
12361
12362void
12363s390_expand_tbegin (rtx dest, rtx tdb, rtx retry, bool clobber_fprs_p)
12364{
91dfd73e 12365 rtx retry_plus_two = gen_reg_rtx (SImode);
5ada7a14 12366 rtx retry_reg = gen_reg_rtx (SImode);
79f6a8ed 12367 rtx_code_label *retry_label = NULL;
5ada7a14 12368
12369 if (retry != NULL_RTX)
12370 {
12371 emit_move_insn (retry_reg, retry);
91dfd73e 12372 emit_insn (gen_addsi3 (retry_plus_two, retry_reg, const2_rtx));
12373 emit_insn (gen_addsi3 (retry_reg, retry_reg, const1_rtx));
5ada7a14 12374 retry_label = gen_label_rtx ();
12375 emit_label (retry_label);
12376 }
12377
12378 if (clobber_fprs_p)
044a78dc 12379 {
12380 if (TARGET_VX)
12381 emit_insn (gen_tbegin_1_z13 (gen_rtx_CONST_INT (VOIDmode, TBEGIN_MASK),
12382 tdb));
12383 else
12384 emit_insn (gen_tbegin_1 (gen_rtx_CONST_INT (VOIDmode, TBEGIN_MASK),
12385 tdb));
12386 }
5ada7a14 12387 else
91dfd73e 12388 emit_insn (gen_tbegin_nofloat_1 (gen_rtx_CONST_INT (VOIDmode, TBEGIN_MASK),
12389 tdb));
5ada7a14 12390
91dfd73e 12391 emit_move_insn (dest, gen_rtx_UNSPEC (SImode,
12392 gen_rtvec (1, gen_rtx_REG (CCRAWmode,
12393 CC_REGNUM)),
12394 UNSPEC_CC_TO_INT));
5ada7a14 12395 if (retry != NULL_RTX)
12396 {
d089210f 12397 const int CC0 = 1 << 3;
12398 const int CC1 = 1 << 2;
12399 const int CC3 = 1 << 0;
12400 rtx jump;
5ada7a14 12401 rtx count = gen_reg_rtx (SImode);
93e0956b 12402 rtx_code_label *leave_label = gen_label_rtx ();
d089210f 12403
12404 /* Exit for success and permanent failures. */
5ada7a14 12405 jump = s390_emit_jump (leave_label,
12406 gen_rtx_EQ (VOIDmode,
12407 gen_rtx_REG (CCRAWmode, CC_REGNUM),
d089210f 12408 gen_rtx_CONST_INT (VOIDmode, CC0 | CC1 | CC3)));
12409 LABEL_NUSES (leave_label) = 1;
5ada7a14 12410
12411 /* CC2 - transient failure. Perform retry with ppa. */
91dfd73e 12412 emit_move_insn (count, retry_plus_two);
5ada7a14 12413 emit_insn (gen_subsi3 (count, count, retry_reg));
12414 emit_insn (gen_tx_assist (count));
12415 jump = emit_jump_insn (gen_doloop_si64 (retry_label,
12416 retry_reg,
12417 retry_reg));
12418 JUMP_LABEL (jump) = retry_label;
12419 LABEL_NUSES (retry_label) = 1;
d089210f 12420 emit_label (leave_label);
5ada7a14 12421 }
5ada7a14 12422}
12423
5ada7a14 12424
751c914e 12425/* Return the decl for the target specific builtin with the function
12426 code FCODE. */
12427
12428static tree
12429s390_builtin_decl (unsigned fcode, bool initialized_p ATTRIBUTE_UNUSED)
12430{
12431 if (fcode >= S390_BUILTIN_MAX)
12432 return error_mark_node;
12433
12434 return s390_builtin_decls[fcode];
12435}
12436
d44f2f7c 12437/* We call mcount before the function prologue. So a profiled leaf
12438 function should stay a leaf function. */
12439
12440static bool
12441s390_keep_leaf_when_profiled ()
12442{
12443 return true;
12444}
5ada7a14 12445
875862bf 12446/* Output assembly code for the trampoline template to
12447 stdio stream FILE.
12448
12449 On S/390, we use gpr 1 internally in the trampoline code;
12450 gpr 0 is used to hold the static chain. */
12451
4d946732 12452static void
12453s390_asm_trampoline_template (FILE *file)
875862bf 12454{
12455 rtx op[2];
12456 op[0] = gen_rtx_REG (Pmode, 0);
12457 op[1] = gen_rtx_REG (Pmode, 1);
12458
12459 if (TARGET_64BIT)
12460 {
29335855 12461 output_asm_insn ("basr\t%1,0", op); /* 2 byte */
12462 output_asm_insn ("lmg\t%0,%1,14(%1)", op); /* 6 byte */
12463 output_asm_insn ("br\t%1", op); /* 2 byte */
875862bf 12464 ASM_OUTPUT_SKIP (file, (HOST_WIDE_INT)(TRAMPOLINE_SIZE - 10));
12465 }
12466 else
12467 {
29335855 12468 output_asm_insn ("basr\t%1,0", op); /* 2 byte */
12469 output_asm_insn ("lm\t%0,%1,6(%1)", op); /* 4 byte */
12470 output_asm_insn ("br\t%1", op); /* 2 byte */
875862bf 12471 ASM_OUTPUT_SKIP (file, (HOST_WIDE_INT)(TRAMPOLINE_SIZE - 8));
12472 }
12473}
12474
12475/* Emit RTL insns to initialize the variable parts of a trampoline.
12476 FNADDR is an RTX for the address of the function's pure code.
12477 CXT is an RTX for the static chain value for the function. */
12478
4d946732 12479static void
12480s390_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
875862bf 12481{
4d946732 12482 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
12483 rtx mem;
8a2a84e3 12484
4d946732 12485 emit_block_move (m_tramp, assemble_trampoline_template (),
29335855 12486 GEN_INT (2 * UNITS_PER_LONG), BLOCK_OP_NORMAL);
4d946732 12487
29335855 12488 mem = adjust_address (m_tramp, Pmode, 2 * UNITS_PER_LONG);
4d946732 12489 emit_move_insn (mem, cxt);
29335855 12490 mem = adjust_address (m_tramp, Pmode, 3 * UNITS_PER_LONG);
4d946732 12491 emit_move_insn (mem, fnaddr);
875862bf 12492}
12493
875862bf 12494/* Output assembler code to FILE to increment profiler label # LABELNO
12495 for profiling a function entry. */
12496
12497void
12498s390_function_profiler (FILE *file, int labelno)
12499{
12500 rtx op[7];
12501
12502 char label[128];
12503 ASM_GENERATE_INTERNAL_LABEL (label, "LP", labelno);
12504
12505 fprintf (file, "# function profiler \n");
12506
12507 op[0] = gen_rtx_REG (Pmode, RETURN_REGNUM);
12508 op[1] = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
29c05e22 12509 op[1] = gen_rtx_MEM (Pmode, plus_constant (Pmode, op[1], UNITS_PER_LONG));
875862bf 12510
12511 op[2] = gen_rtx_REG (Pmode, 1);
12512 op[3] = gen_rtx_SYMBOL_REF (Pmode, label);
12513 SYMBOL_REF_FLAGS (op[3]) = SYMBOL_FLAG_LOCAL;
12514
12515 op[4] = gen_rtx_SYMBOL_REF (Pmode, "_mcount");
12516 if (flag_pic)
12517 {
12518 op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), UNSPEC_PLT);
12519 op[4] = gen_rtx_CONST (Pmode, op[4]);
12520 }
12521
12522 if (TARGET_64BIT)
12523 {
12524 output_asm_insn ("stg\t%0,%1", op);
12525 output_asm_insn ("larl\t%2,%3", op);
12526 output_asm_insn ("brasl\t%0,%4", op);
12527 output_asm_insn ("lg\t%0,%1", op);
12528 }
4bc40d24 12529 else if (TARGET_CPU_ZARCH)
12530 {
12531 output_asm_insn ("st\t%0,%1", op);
12532 output_asm_insn ("larl\t%2,%3", op);
12533 output_asm_insn ("brasl\t%0,%4", op);
12534 output_asm_insn ("l\t%0,%1", op);
12535 }
875862bf 12536 else if (!flag_pic)
12537 {
12538 op[6] = gen_label_rtx ();
12539
12540 output_asm_insn ("st\t%0,%1", op);
12541 output_asm_insn ("bras\t%2,%l6", op);
12542 output_asm_insn (".long\t%4", op);
12543 output_asm_insn (".long\t%3", op);
12544 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
12545 output_asm_insn ("l\t%0,0(%2)", op);
12546 output_asm_insn ("l\t%2,4(%2)", op);
12547 output_asm_insn ("basr\t%0,%0", op);
12548 output_asm_insn ("l\t%0,%1", op);
12549 }
12550 else
12551 {
12552 op[5] = gen_label_rtx ();
12553 op[6] = gen_label_rtx ();
12554
12555 output_asm_insn ("st\t%0,%1", op);
12556 output_asm_insn ("bras\t%2,%l6", op);
12557 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[5]));
12558 output_asm_insn (".long\t%4-%l5", op);
12559 output_asm_insn (".long\t%3-%l5", op);
12560 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
12561 output_asm_insn ("lr\t%0,%2", op);
12562 output_asm_insn ("a\t%0,0(%2)", op);
12563 output_asm_insn ("a\t%2,4(%2)", op);
12564 output_asm_insn ("basr\t%0,%0", op);
12565 output_asm_insn ("l\t%0,%1", op);
12566 }
12567}
12568
12569/* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
12570 into its SYMBOL_REF_FLAGS. */
12571
12572static void
12573s390_encode_section_info (tree decl, rtx rtl, int first)
12574{
12575 default_encode_section_info (decl, rtl, first);
12576
e68d6a13 12577 if (TREE_CODE (decl) == VAR_DECL)
12578 {
78affa36 12579 /* Store the alignment to be able to check if we can use
12580 a larl/load-relative instruction. We only handle the cases
ea283725 12581 that can go wrong (i.e. no FUNC_DECLs). */
09d899d1 12582 if (DECL_ALIGN (decl) == 0 || DECL_ALIGN (decl) % 16)
78affa36 12583 SYMBOL_FLAG_SET_NOTALIGN2 (XEXP (rtl, 0));
ea283725 12584 else if (DECL_ALIGN (decl) % 32)
12585 SYMBOL_FLAG_SET_NOTALIGN4 (XEXP (rtl, 0));
12586 else if (DECL_ALIGN (decl) % 64)
12587 SYMBOL_FLAG_SET_NOTALIGN8 (XEXP (rtl, 0));
e68d6a13 12588 }
12589
12590 /* Literal pool references don't have a decl so they are handled
12591 differently here. We rely on the information in the MEM_ALIGN
78affa36 12592 entry to decide upon the alignment. */
e68d6a13 12593 if (MEM_P (rtl)
12594 && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF
ea283725 12595 && TREE_CONSTANT_POOL_ADDRESS_P (XEXP (rtl, 0)))
78affa36 12596 {
09d899d1 12597 if (MEM_ALIGN (rtl) == 0 || MEM_ALIGN (rtl) % 16)
78affa36 12598 SYMBOL_FLAG_SET_NOTALIGN2 (XEXP (rtl, 0));
ea283725 12599 else if (MEM_ALIGN (rtl) % 32)
12600 SYMBOL_FLAG_SET_NOTALIGN4 (XEXP (rtl, 0));
12601 else if (MEM_ALIGN (rtl) % 64)
12602 SYMBOL_FLAG_SET_NOTALIGN8 (XEXP (rtl, 0));
78affa36 12603 }
875862bf 12604}
12605
12606/* Output thunk to FILE that implements a C++ virtual function call (with
12607 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
12608 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
12609 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
12610 relative to the resulting this pointer. */
12611
12612static void
12613s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
12614 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
12615 tree function)
12616{
12617 rtx op[10];
12618 int nonlocal = 0;
12619
21a38800 12620 /* Make sure unwind info is emitted for the thunk if needed. */
12621 final_start_function (emit_barrier (), file, 1);
12622
875862bf 12623 /* Operand 0 is the target function. */
12624 op[0] = XEXP (DECL_RTL (function), 0);
12625 if (flag_pic && !SYMBOL_REF_LOCAL_P (op[0]))
12626 {
12627 nonlocal = 1;
12628 op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]),
12629 TARGET_64BIT ? UNSPEC_PLT : UNSPEC_GOT);
12630 op[0] = gen_rtx_CONST (Pmode, op[0]);
12631 }
12632
12633 /* Operand 1 is the 'this' pointer. */
12634 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
12635 op[1] = gen_rtx_REG (Pmode, 3);
12636 else
12637 op[1] = gen_rtx_REG (Pmode, 2);
12638
12639 /* Operand 2 is the delta. */
12640 op[2] = GEN_INT (delta);
12641
12642 /* Operand 3 is the vcall_offset. */
12643 op[3] = GEN_INT (vcall_offset);
12644
12645 /* Operand 4 is the temporary register. */
12646 op[4] = gen_rtx_REG (Pmode, 1);
12647
12648 /* Operands 5 to 8 can be used as labels. */
12649 op[5] = NULL_RTX;
12650 op[6] = NULL_RTX;
12651 op[7] = NULL_RTX;
12652 op[8] = NULL_RTX;
12653
12654 /* Operand 9 can be used for temporary register. */
12655 op[9] = NULL_RTX;
12656
12657 /* Generate code. */
12658 if (TARGET_64BIT)
12659 {
12660 /* Setup literal pool pointer if required. */
12661 if ((!DISP_IN_RANGE (delta)
163277cf 12662 && !CONST_OK_FOR_K (delta)
12663 && !CONST_OK_FOR_Os (delta))
875862bf 12664 || (!DISP_IN_RANGE (vcall_offset)
163277cf 12665 && !CONST_OK_FOR_K (vcall_offset)
12666 && !CONST_OK_FOR_Os (vcall_offset)))
875862bf 12667 {
12668 op[5] = gen_label_rtx ();
12669 output_asm_insn ("larl\t%4,%5", op);
12670 }
12671
12672 /* Add DELTA to this pointer. */
12673 if (delta)
12674 {
cb888f33 12675 if (CONST_OK_FOR_J (delta))
875862bf 12676 output_asm_insn ("la\t%1,%2(%1)", op);
12677 else if (DISP_IN_RANGE (delta))
12678 output_asm_insn ("lay\t%1,%2(%1)", op);
cb888f33 12679 else if (CONST_OK_FOR_K (delta))
875862bf 12680 output_asm_insn ("aghi\t%1,%2", op);
163277cf 12681 else if (CONST_OK_FOR_Os (delta))
12682 output_asm_insn ("agfi\t%1,%2", op);
875862bf 12683 else
12684 {
12685 op[6] = gen_label_rtx ();
12686 output_asm_insn ("agf\t%1,%6-%5(%4)", op);
12687 }
12688 }
12689
12690 /* Perform vcall adjustment. */
12691 if (vcall_offset)
12692 {
12693 if (DISP_IN_RANGE (vcall_offset))
12694 {
12695 output_asm_insn ("lg\t%4,0(%1)", op);
12696 output_asm_insn ("ag\t%1,%3(%4)", op);
12697 }
cb888f33 12698 else if (CONST_OK_FOR_K (vcall_offset))
875862bf 12699 {
12700 output_asm_insn ("lghi\t%4,%3", op);
12701 output_asm_insn ("ag\t%4,0(%1)", op);
12702 output_asm_insn ("ag\t%1,0(%4)", op);
12703 }
163277cf 12704 else if (CONST_OK_FOR_Os (vcall_offset))
12705 {
12706 output_asm_insn ("lgfi\t%4,%3", op);
12707 output_asm_insn ("ag\t%4,0(%1)", op);
12708 output_asm_insn ("ag\t%1,0(%4)", op);
12709 }
875862bf 12710 else
12711 {
12712 op[7] = gen_label_rtx ();
12713 output_asm_insn ("llgf\t%4,%7-%5(%4)", op);
12714 output_asm_insn ("ag\t%4,0(%1)", op);
12715 output_asm_insn ("ag\t%1,0(%4)", op);
12716 }
12717 }
12718
12719 /* Jump to target. */
12720 output_asm_insn ("jg\t%0", op);
12721
12722 /* Output literal pool if required. */
12723 if (op[5])
12724 {
12725 output_asm_insn (".align\t4", op);
12726 targetm.asm_out.internal_label (file, "L",
12727 CODE_LABEL_NUMBER (op[5]));
12728 }
12729 if (op[6])
12730 {
12731 targetm.asm_out.internal_label (file, "L",
12732 CODE_LABEL_NUMBER (op[6]));
12733 output_asm_insn (".long\t%2", op);
12734 }
12735 if (op[7])
12736 {
12737 targetm.asm_out.internal_label (file, "L",
12738 CODE_LABEL_NUMBER (op[7]));
12739 output_asm_insn (".long\t%3", op);
12740 }
12741 }
12742 else
12743 {
12744 /* Setup base pointer if required. */
12745 if (!vcall_offset
12746 || (!DISP_IN_RANGE (delta)
163277cf 12747 && !CONST_OK_FOR_K (delta)
12748 && !CONST_OK_FOR_Os (delta))
875862bf 12749 || (!DISP_IN_RANGE (delta)
163277cf 12750 && !CONST_OK_FOR_K (vcall_offset)
12751 && !CONST_OK_FOR_Os (vcall_offset)))
875862bf 12752 {
12753 op[5] = gen_label_rtx ();
12754 output_asm_insn ("basr\t%4,0", op);
12755 targetm.asm_out.internal_label (file, "L",
12756 CODE_LABEL_NUMBER (op[5]));
12757 }
12758
12759 /* Add DELTA to this pointer. */
12760 if (delta)
12761 {
cb888f33 12762 if (CONST_OK_FOR_J (delta))
875862bf 12763 output_asm_insn ("la\t%1,%2(%1)", op);
12764 else if (DISP_IN_RANGE (delta))
12765 output_asm_insn ("lay\t%1,%2(%1)", op);
cb888f33 12766 else if (CONST_OK_FOR_K (delta))
875862bf 12767 output_asm_insn ("ahi\t%1,%2", op);
163277cf 12768 else if (CONST_OK_FOR_Os (delta))
12769 output_asm_insn ("afi\t%1,%2", op);
875862bf 12770 else
12771 {
12772 op[6] = gen_label_rtx ();
12773 output_asm_insn ("a\t%1,%6-%5(%4)", op);
12774 }
12775 }
12776
12777 /* Perform vcall adjustment. */
12778 if (vcall_offset)
12779 {
cb888f33 12780 if (CONST_OK_FOR_J (vcall_offset))
875862bf 12781 {
0451e449 12782 output_asm_insn ("l\t%4,0(%1)", op);
875862bf 12783 output_asm_insn ("a\t%1,%3(%4)", op);
12784 }
12785 else if (DISP_IN_RANGE (vcall_offset))
12786 {
0451e449 12787 output_asm_insn ("l\t%4,0(%1)", op);
875862bf 12788 output_asm_insn ("ay\t%1,%3(%4)", op);
12789 }
cb888f33 12790 else if (CONST_OK_FOR_K (vcall_offset))
875862bf 12791 {
12792 output_asm_insn ("lhi\t%4,%3", op);
12793 output_asm_insn ("a\t%4,0(%1)", op);
12794 output_asm_insn ("a\t%1,0(%4)", op);
12795 }
163277cf 12796 else if (CONST_OK_FOR_Os (vcall_offset))
12797 {
12798 output_asm_insn ("iilf\t%4,%3", op);
12799 output_asm_insn ("a\t%4,0(%1)", op);
12800 output_asm_insn ("a\t%1,0(%4)", op);
12801 }
875862bf 12802 else
12803 {
12804 op[7] = gen_label_rtx ();
12805 output_asm_insn ("l\t%4,%7-%5(%4)", op);
12806 output_asm_insn ("a\t%4,0(%1)", op);
12807 output_asm_insn ("a\t%1,0(%4)", op);
12808 }
4673c1a0 12809
875862bf 12810 /* We had to clobber the base pointer register.
12811 Re-setup the base pointer (with a different base). */
12812 op[5] = gen_label_rtx ();
12813 output_asm_insn ("basr\t%4,0", op);
12814 targetm.asm_out.internal_label (file, "L",
12815 CODE_LABEL_NUMBER (op[5]));
12816 }
4673c1a0 12817
875862bf 12818 /* Jump to target. */
12819 op[8] = gen_label_rtx ();
4673c1a0 12820
875862bf 12821 if (!flag_pic)
12822 output_asm_insn ("l\t%4,%8-%5(%4)", op);
12823 else if (!nonlocal)
12824 output_asm_insn ("a\t%4,%8-%5(%4)", op);
12825 /* We cannot call through .plt, since .plt requires %r12 loaded. */
12826 else if (flag_pic == 1)
12827 {
12828 output_asm_insn ("a\t%4,%8-%5(%4)", op);
12829 output_asm_insn ("l\t%4,%0(%4)", op);
12830 }
12831 else if (flag_pic == 2)
12832 {
12833 op[9] = gen_rtx_REG (Pmode, 0);
12834 output_asm_insn ("l\t%9,%8-4-%5(%4)", op);
12835 output_asm_insn ("a\t%4,%8-%5(%4)", op);
12836 output_asm_insn ("ar\t%4,%9", op);
12837 output_asm_insn ("l\t%4,0(%4)", op);
12838 }
4673c1a0 12839
875862bf 12840 output_asm_insn ("br\t%4", op);
4673c1a0 12841
875862bf 12842 /* Output literal pool. */
12843 output_asm_insn (".align\t4", op);
4673c1a0 12844
875862bf 12845 if (nonlocal && flag_pic == 2)
12846 output_asm_insn (".long\t%0", op);
12847 if (nonlocal)
12848 {
12849 op[0] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
12850 SYMBOL_REF_FLAGS (op[0]) = SYMBOL_FLAG_LOCAL;
12851 }
d93e0d9f 12852
875862bf 12853 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[8]));
12854 if (!flag_pic)
12855 output_asm_insn (".long\t%0", op);
12856 else
12857 output_asm_insn (".long\t%0-%5", op);
4673c1a0 12858
875862bf 12859 if (op[6])
12860 {
12861 targetm.asm_out.internal_label (file, "L",
12862 CODE_LABEL_NUMBER (op[6]));
12863 output_asm_insn (".long\t%2", op);
12864 }
12865 if (op[7])
12866 {
12867 targetm.asm_out.internal_label (file, "L",
12868 CODE_LABEL_NUMBER (op[7]));
12869 output_asm_insn (".long\t%3", op);
12870 }
4673c1a0 12871 }
21a38800 12872 final_end_function ();
4673c1a0 12873}
12874
875862bf 12875static bool
3754d046 12876s390_valid_pointer_mode (machine_mode mode)
875862bf 12877{
12878 return (mode == SImode || (TARGET_64BIT && mode == DImode));
12879}
56769981 12880
347301d6 12881/* Checks whether the given CALL_EXPR would use a caller
875862bf 12882 saved register. This is used to decide whether sibling call
12883 optimization could be performed on the respective function
12884 call. */
be00aaa8 12885
875862bf 12886static bool
347301d6 12887s390_call_saved_register_used (tree call_expr)
be00aaa8 12888{
39cba157 12889 CUMULATIVE_ARGS cum_v;
12890 cumulative_args_t cum;
875862bf 12891 tree parameter;
3754d046 12892 machine_mode mode;
875862bf 12893 tree type;
12894 rtx parm_rtx;
347301d6 12895 int reg, i;
be00aaa8 12896
39cba157 12897 INIT_CUMULATIVE_ARGS (cum_v, NULL, NULL, 0, 0);
12898 cum = pack_cumulative_args (&cum_v);
be00aaa8 12899
347301d6 12900 for (i = 0; i < call_expr_nargs (call_expr); i++)
875862bf 12901 {
347301d6 12902 parameter = CALL_EXPR_ARG (call_expr, i);
32eda510 12903 gcc_assert (parameter);
be00aaa8 12904
875862bf 12905 /* For an undeclared variable passed as parameter we will get
12906 an ERROR_MARK node here. */
12907 if (TREE_CODE (parameter) == ERROR_MARK)
12908 return true;
be00aaa8 12909
32eda510 12910 type = TREE_TYPE (parameter);
12911 gcc_assert (type);
be00aaa8 12912
32eda510 12913 mode = TYPE_MODE (type);
12914 gcc_assert (mode);
be00aaa8 12915
76a4c804 12916 /* We assume that in the target function all parameters are
12917 named. This only has an impact on vector argument register
12918 usage none of which is call-saved. */
39cba157 12919 if (pass_by_reference (&cum_v, mode, type, true))
875862bf 12920 {
12921 mode = Pmode;
12922 type = build_pointer_type (type);
12923 }
be00aaa8 12924
76a4c804 12925 parm_rtx = s390_function_arg (cum, mode, type, true);
be00aaa8 12926
76a4c804 12927 s390_function_arg_advance (cum, mode, type, true);
be00aaa8 12928
b5fdc416 12929 if (!parm_rtx)
12930 continue;
12931
12932 if (REG_P (parm_rtx))
12933 {
cc6a115b 12934 for (reg = 0;
12935 reg < HARD_REGNO_NREGS (REGNO (parm_rtx), GET_MODE (parm_rtx));
12936 reg++)
b5fdc416 12937 if (!call_used_regs[reg + REGNO (parm_rtx)])
12938 return true;
12939 }
12940
12941 if (GET_CODE (parm_rtx) == PARALLEL)
875862bf 12942 {
b5fdc416 12943 int i;
cc6a115b 12944
b5fdc416 12945 for (i = 0; i < XVECLEN (parm_rtx, 0); i++)
12946 {
12947 rtx r = XEXP (XVECEXP (parm_rtx, 0, i), 0);
b5fdc416 12948
12949 gcc_assert (REG_P (r));
12950
cc6a115b 12951 for (reg = 0;
12952 reg < HARD_REGNO_NREGS (REGNO (r), GET_MODE (r));
12953 reg++)
b5fdc416 12954 if (!call_used_regs[reg + REGNO (r)])
12955 return true;
12956 }
875862bf 12957 }
b5fdc416 12958
875862bf 12959 }
12960 return false;
12961}
be00aaa8 12962
875862bf 12963/* Return true if the given call expression can be
12964 turned into a sibling call.
12965 DECL holds the declaration of the function to be called whereas
12966 EXP is the call expression itself. */
be00aaa8 12967
875862bf 12968static bool
12969s390_function_ok_for_sibcall (tree decl, tree exp)
12970{
12971 /* The TPF epilogue uses register 1. */
12972 if (TARGET_TPF_PROFILING)
12973 return false;
be00aaa8 12974
875862bf 12975 /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
12976 which would have to be restored before the sibcall. */
a47b0dc3 12977 if (!TARGET_64BIT && flag_pic && decl && !targetm.binds_local_p (decl))
875862bf 12978 return false;
be00aaa8 12979
875862bf 12980 /* Register 6 on s390 is available as an argument register but unfortunately
12981 "caller saved". This makes functions needing this register for arguments
12982 not suitable for sibcalls. */
347301d6 12983 return !s390_call_saved_register_used (exp);
875862bf 12984}
be00aaa8 12985
875862bf 12986/* Return the fixed registers used for condition codes. */
be00aaa8 12987
875862bf 12988static bool
12989s390_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
12990{
12991 *p1 = CC_REGNUM;
12992 *p2 = INVALID_REGNUM;
ffead1ca 12993
875862bf 12994 return true;
12995}
be00aaa8 12996
875862bf 12997/* This function is used by the call expanders of the machine description.
12998 It emits the call insn itself together with the necessary operations
12999 to adjust the target address and returns the emitted insn.
13000 ADDR_LOCATION is the target address rtx
13001 TLS_CALL the location of the thread-local symbol
13002 RESULT_REG the register where the result of the call should be stored
13003 RETADDR_REG the register where the return address should be stored
13004 If this parameter is NULL_RTX the call is considered
13005 to be a sibling call. */
be00aaa8 13006
93e0956b 13007rtx_insn *
875862bf 13008s390_emit_call (rtx addr_location, rtx tls_call, rtx result_reg,
13009 rtx retaddr_reg)
4673c1a0 13010{
875862bf 13011 bool plt_call = false;
93e0956b 13012 rtx_insn *insn;
875862bf 13013 rtx call;
13014 rtx clobber;
13015 rtvec vec;
4a1c604e 13016
875862bf 13017 /* Direct function calls need special treatment. */
13018 if (GET_CODE (addr_location) == SYMBOL_REF)
4673c1a0 13019 {
875862bf 13020 /* When calling a global routine in PIC mode, we must
13021 replace the symbol itself with the PLT stub. */
13022 if (flag_pic && !SYMBOL_REF_LOCAL_P (addr_location))
13023 {
aa5b4778 13024 if (TARGET_64BIT || retaddr_reg != NULL_RTX)
9c7185f7 13025 {
13026 addr_location = gen_rtx_UNSPEC (Pmode,
13027 gen_rtvec (1, addr_location),
13028 UNSPEC_PLT);
13029 addr_location = gen_rtx_CONST (Pmode, addr_location);
13030 plt_call = true;
13031 }
13032 else
13033 /* For -fpic code the PLT entries might use r12 which is
13034 call-saved. Therefore we cannot do a sibcall when
13035 calling directly using a symbol ref. When reaching
13036 this point we decided (in s390_function_ok_for_sibcall)
13037 to do a sibcall for a function pointer but one of the
13038 optimizers was able to get rid of the function pointer
13039 by propagating the symbol ref into the call. This
13040 optimization is illegal for S/390 so we turn the direct
13041 call into a indirect call again. */
13042 addr_location = force_reg (Pmode, addr_location);
875862bf 13043 }
13044
13045 /* Unless we can use the bras(l) insn, force the
13046 routine address into a register. */
13047 if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
13048 {
13049 if (flag_pic)
13050 addr_location = legitimize_pic_address (addr_location, 0);
13051 else
13052 addr_location = force_reg (Pmode, addr_location);
13053 }
4673c1a0 13054 }
875862bf 13055
13056 /* If it is already an indirect call or the code above moved the
13057 SYMBOL_REF to somewhere else make sure the address can be found in
13058 register 1. */
13059 if (retaddr_reg == NULL_RTX
13060 && GET_CODE (addr_location) != SYMBOL_REF
13061 && !plt_call)
4673c1a0 13062 {
875862bf 13063 emit_move_insn (gen_rtx_REG (Pmode, SIBCALL_REGNUM), addr_location);
13064 addr_location = gen_rtx_REG (Pmode, SIBCALL_REGNUM);
4673c1a0 13065 }
4673c1a0 13066
875862bf 13067 addr_location = gen_rtx_MEM (QImode, addr_location);
13068 call = gen_rtx_CALL (VOIDmode, addr_location, const0_rtx);
8b4a4127 13069
875862bf 13070 if (result_reg != NULL_RTX)
d1f9b275 13071 call = gen_rtx_SET (result_reg, call);
8b4a4127 13072
875862bf 13073 if (retaddr_reg != NULL_RTX)
13074 {
13075 clobber = gen_rtx_CLOBBER (VOIDmode, retaddr_reg);
f81e845f 13076
875862bf 13077 if (tls_call != NULL_RTX)
13078 vec = gen_rtvec (3, call, clobber,
13079 gen_rtx_USE (VOIDmode, tls_call));
13080 else
13081 vec = gen_rtvec (2, call, clobber);
8b4a4127 13082
875862bf 13083 call = gen_rtx_PARALLEL (VOIDmode, vec);
13084 }
8b4a4127 13085
875862bf 13086 insn = emit_call_insn (call);
8b4a4127 13087
875862bf 13088 /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
13089 if ((!TARGET_64BIT && plt_call) || tls_call != NULL_RTX)
13090 {
13091 /* s390_function_ok_for_sibcall should
13092 have denied sibcalls in this case. */
32eda510 13093 gcc_assert (retaddr_reg != NULL_RTX);
c60a7572 13094 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), gen_rtx_REG (Pmode, 12));
875862bf 13095 }
13096 return insn;
13097}
8b4a4127 13098
b2d7ede1 13099/* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
8b4a4127 13100
b2d7ede1 13101static void
875862bf 13102s390_conditional_register_usage (void)
13103{
13104 int i;
8b4a4127 13105
8b4a4127 13106 if (flag_pic)
13107 {
875862bf 13108 fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
13109 call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
8b4a4127 13110 }
875862bf 13111 if (TARGET_CPU_ZARCH)
8b4a4127 13112 {
d1a5573e 13113 fixed_regs[BASE_REGNUM] = 0;
13114 call_used_regs[BASE_REGNUM] = 0;
875862bf 13115 fixed_regs[RETURN_REGNUM] = 0;
13116 call_used_regs[RETURN_REGNUM] = 0;
8b4a4127 13117 }
875862bf 13118 if (TARGET_64BIT)
8b4a4127 13119 {
6a2469fe 13120 for (i = FPR8_REGNUM; i <= FPR15_REGNUM; i++)
875862bf 13121 call_used_regs[i] = call_really_used_regs[i] = 0;
8b4a4127 13122 }
13123 else
13124 {
6a2469fe 13125 call_used_regs[FPR4_REGNUM] = call_really_used_regs[FPR4_REGNUM] = 0;
13126 call_used_regs[FPR6_REGNUM] = call_really_used_regs[FPR6_REGNUM] = 0;
875862bf 13127 }
8b4a4127 13128
875862bf 13129 if (TARGET_SOFT_FLOAT)
13130 {
6a2469fe 13131 for (i = FPR0_REGNUM; i <= FPR15_REGNUM; i++)
875862bf 13132 call_used_regs[i] = fixed_regs[i] = 1;
8b4a4127 13133 }
76a4c804 13134
13135 /* Disable v16 - v31 for non-vector target. */
13136 if (!TARGET_VX)
13137 {
13138 for (i = VR16_REGNUM; i <= VR31_REGNUM; i++)
13139 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
13140 }
8b4a4127 13141}
13142
875862bf 13143/* Corresponding function to eh_return expander. */
7811991d 13144
875862bf 13145static GTY(()) rtx s390_tpf_eh_return_symbol;
13146void
13147s390_emit_tpf_eh_return (rtx target)
7811991d 13148{
93e0956b 13149 rtx_insn *insn;
13150 rtx reg, orig_ra;
525d1294 13151
875862bf 13152 if (!s390_tpf_eh_return_symbol)
13153 s390_tpf_eh_return_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tpf_eh_return");
13154
13155 reg = gen_rtx_REG (Pmode, 2);
bcd3133e 13156 orig_ra = gen_rtx_REG (Pmode, 3);
875862bf 13157
13158 emit_move_insn (reg, target);
bcd3133e 13159 emit_move_insn (orig_ra, get_hard_reg_initial_val (Pmode, RETURN_REGNUM));
875862bf 13160 insn = s390_emit_call (s390_tpf_eh_return_symbol, NULL_RTX, reg,
13161 gen_rtx_REG (Pmode, RETURN_REGNUM));
13162 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
bcd3133e 13163 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), orig_ra);
875862bf 13164
13165 emit_move_insn (EH_RETURN_HANDLER_RTX, reg);
be00aaa8 13166}
13167
875862bf 13168/* Rework the prologue/epilogue to avoid saving/restoring
13169 registers unnecessarily. */
c20f8a1d 13170
6988553d 13171static void
875862bf 13172s390_optimize_prologue (void)
c6933ba6 13173{
93e0956b 13174 rtx_insn *insn, *new_insn, *next_insn;
c20f8a1d 13175
875862bf 13176 /* Do a final recompute of the frame-related data. */
ff4ce128 13177 s390_optimize_register_info ();
c20f8a1d 13178
875862bf 13179 /* If all special registers are in fact used, there's nothing we
13180 can do, so no point in walking the insn list. */
c20f8a1d 13181
ffead1ca 13182 if (cfun_frame_layout.first_save_gpr <= BASE_REGNUM
875862bf 13183 && cfun_frame_layout.last_save_gpr >= BASE_REGNUM
ffead1ca 13184 && (TARGET_CPU_ZARCH
13185 || (cfun_frame_layout.first_save_gpr <= RETURN_REGNUM
875862bf 13186 && cfun_frame_layout.last_save_gpr >= RETURN_REGNUM)))
13187 return;
c20f8a1d 13188
875862bf 13189 /* Search for prologue/epilogue insns and replace them. */
c20f8a1d 13190
875862bf 13191 for (insn = get_insns (); insn; insn = next_insn)
13192 {
13193 int first, last, off;
13194 rtx set, base, offset;
ff4ce128 13195 rtx pat;
c20f8a1d 13196
875862bf 13197 next_insn = NEXT_INSN (insn);
d7bec695 13198
ff4ce128 13199 if (! NONJUMP_INSN_P (insn) || ! RTX_FRAME_RELATED_P (insn))
875862bf 13200 continue;
c20f8a1d 13201
ff4ce128 13202 pat = PATTERN (insn);
13203
13204 /* Remove ldgr/lgdr instructions used for saving and restore
13205 GPRs if possible. */
54530437 13206 if (TARGET_Z10)
13207 {
13208 rtx tmp_pat = pat;
ff4ce128 13209
54530437 13210 if (INSN_CODE (insn) == CODE_FOR_stack_restore_from_fpr)
13211 tmp_pat = XVECEXP (pat, 0, 0);
ff4ce128 13212
54530437 13213 if (GET_CODE (tmp_pat) == SET
13214 && GET_MODE (SET_SRC (tmp_pat)) == DImode
13215 && REG_P (SET_SRC (tmp_pat))
13216 && REG_P (SET_DEST (tmp_pat)))
13217 {
13218 int src_regno = REGNO (SET_SRC (tmp_pat));
13219 int dest_regno = REGNO (SET_DEST (tmp_pat));
13220 int gpr_regno;
13221 int fpr_regno;
13222
13223 if (!((GENERAL_REGNO_P (src_regno)
13224 && FP_REGNO_P (dest_regno))
13225 || (FP_REGNO_P (src_regno)
13226 && GENERAL_REGNO_P (dest_regno))))
13227 continue;
ff4ce128 13228
54530437 13229 gpr_regno = GENERAL_REGNO_P (src_regno) ? src_regno : dest_regno;
13230 fpr_regno = FP_REGNO_P (src_regno) ? src_regno : dest_regno;
ff4ce128 13231
54530437 13232 /* GPR must be call-saved, FPR must be call-clobbered. */
13233 if (!call_really_used_regs[fpr_regno]
13234 || call_really_used_regs[gpr_regno])
13235 continue;
13236
13237 /* It must not happen that what we once saved in an FPR now
13238 needs a stack slot. */
13239 gcc_assert (cfun_gpr_save_slot (gpr_regno) != SAVE_SLOT_STACK);
13240
13241 if (cfun_gpr_save_slot (gpr_regno) == SAVE_SLOT_NONE)
13242 {
13243 remove_insn (insn);
13244 continue;
13245 }
ff4ce128 13246 }
13247 }
13248
13249 if (GET_CODE (pat) == PARALLEL
13250 && store_multiple_operation (pat, VOIDmode))
c20f8a1d 13251 {
ff4ce128 13252 set = XVECEXP (pat, 0, 0);
875862bf 13253 first = REGNO (SET_SRC (set));
ff4ce128 13254 last = first + XVECLEN (pat, 0) - 1;
875862bf 13255 offset = const0_rtx;
13256 base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
13257 off = INTVAL (offset);
c20f8a1d 13258
875862bf 13259 if (GET_CODE (base) != REG || off < 0)
13260 continue;
43944aa4 13261 if (cfun_frame_layout.first_save_gpr != -1
13262 && (cfun_frame_layout.first_save_gpr < first
13263 || cfun_frame_layout.last_save_gpr > last))
13264 continue;
875862bf 13265 if (REGNO (base) != STACK_POINTER_REGNUM
13266 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
13267 continue;
13268 if (first > BASE_REGNUM || last < BASE_REGNUM)
13269 continue;
13270
13271 if (cfun_frame_layout.first_save_gpr != -1)
c20f8a1d 13272 {
93e0956b 13273 rtx s_pat = save_gprs (base,
875862bf 13274 off + (cfun_frame_layout.first_save_gpr
b5fdc416 13275 - first) * UNITS_PER_LONG,
875862bf 13276 cfun_frame_layout.first_save_gpr,
13277 cfun_frame_layout.last_save_gpr);
93e0956b 13278 new_insn = emit_insn_before (s_pat, insn);
875862bf 13279 INSN_ADDRESSES_NEW (new_insn, -1);
c20f8a1d 13280 }
c20f8a1d 13281
875862bf 13282 remove_insn (insn);
13283 continue;
c20f8a1d 13284 }
13285
43944aa4 13286 if (cfun_frame_layout.first_save_gpr == -1
ff4ce128 13287 && GET_CODE (pat) == SET
13288 && GENERAL_REG_P (SET_SRC (pat))
13289 && GET_CODE (SET_DEST (pat)) == MEM)
c20f8a1d 13290 {
ff4ce128 13291 set = pat;
875862bf 13292 first = REGNO (SET_SRC (set));
13293 offset = const0_rtx;
13294 base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
13295 off = INTVAL (offset);
c20f8a1d 13296
875862bf 13297 if (GET_CODE (base) != REG || off < 0)
13298 continue;
13299 if (REGNO (base) != STACK_POINTER_REGNUM
13300 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
13301 continue;
c20f8a1d 13302
875862bf 13303 remove_insn (insn);
13304 continue;
c20f8a1d 13305 }
13306
ff4ce128 13307 if (GET_CODE (pat) == PARALLEL
13308 && load_multiple_operation (pat, VOIDmode))
d7bec695 13309 {
ff4ce128 13310 set = XVECEXP (pat, 0, 0);
875862bf 13311 first = REGNO (SET_DEST (set));
ff4ce128 13312 last = first + XVECLEN (pat, 0) - 1;
875862bf 13313 offset = const0_rtx;
13314 base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
13315 off = INTVAL (offset);
d7bec695 13316
875862bf 13317 if (GET_CODE (base) != REG || off < 0)
13318 continue;
ff4ce128 13319
43944aa4 13320 if (cfun_frame_layout.first_restore_gpr != -1
13321 && (cfun_frame_layout.first_restore_gpr < first
13322 || cfun_frame_layout.last_restore_gpr > last))
13323 continue;
875862bf 13324 if (REGNO (base) != STACK_POINTER_REGNUM
13325 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
13326 continue;
13327 if (first > BASE_REGNUM || last < BASE_REGNUM)
13328 continue;
c20f8a1d 13329
875862bf 13330 if (cfun_frame_layout.first_restore_gpr != -1)
13331 {
93e0956b 13332 rtx rpat = restore_gprs (base,
875862bf 13333 off + (cfun_frame_layout.first_restore_gpr
b5fdc416 13334 - first) * UNITS_PER_LONG,
875862bf 13335 cfun_frame_layout.first_restore_gpr,
13336 cfun_frame_layout.last_restore_gpr);
8240ec0e 13337
13338 /* Remove REG_CFA_RESTOREs for registers that we no
13339 longer need to save. */
93e0956b 13340 REG_NOTES (rpat) = REG_NOTES (insn);
13341 for (rtx *ptr = &REG_NOTES (rpat); *ptr; )
8240ec0e 13342 if (REG_NOTE_KIND (*ptr) == REG_CFA_RESTORE
13343 && ((int) REGNO (XEXP (*ptr, 0))
13344 < cfun_frame_layout.first_restore_gpr))
13345 *ptr = XEXP (*ptr, 1);
13346 else
13347 ptr = &XEXP (*ptr, 1);
93e0956b 13348 new_insn = emit_insn_before (rpat, insn);
8240ec0e 13349 RTX_FRAME_RELATED_P (new_insn) = 1;
875862bf 13350 INSN_ADDRESSES_NEW (new_insn, -1);
13351 }
d7bec695 13352
875862bf 13353 remove_insn (insn);
13354 continue;
d7bec695 13355 }
13356
43944aa4 13357 if (cfun_frame_layout.first_restore_gpr == -1
ff4ce128 13358 && GET_CODE (pat) == SET
13359 && GENERAL_REG_P (SET_DEST (pat))
13360 && GET_CODE (SET_SRC (pat)) == MEM)
c20f8a1d 13361 {
ff4ce128 13362 set = pat;
875862bf 13363 first = REGNO (SET_DEST (set));
13364 offset = const0_rtx;
13365 base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
13366 off = INTVAL (offset);
f81e845f 13367
875862bf 13368 if (GET_CODE (base) != REG || off < 0)
13369 continue;
ff4ce128 13370
875862bf 13371 if (REGNO (base) != STACK_POINTER_REGNUM
13372 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
13373 continue;
5a5e802f 13374
875862bf 13375 remove_insn (insn);
13376 continue;
13377 }
13378 }
5a5e802f 13379}
13380
33d033da 13381/* On z10 and later the dynamic branch prediction must see the
13382 backward jump within a certain windows. If not it falls back to
13383 the static prediction. This function rearranges the loop backward
13384 branch in a way which makes the static prediction always correct.
13385 The function returns true if it added an instruction. */
73df8a45 13386static bool
93e0956b 13387s390_fix_long_loop_prediction (rtx_insn *insn)
73df8a45 13388{
13389 rtx set = single_set (insn);
db7dd023 13390 rtx code_label, label_ref;
158a522b 13391 rtx_insn *uncond_jump;
93e0956b 13392 rtx_insn *cur_insn;
73df8a45 13393 rtx tmp;
13394 int distance;
13395
13396 /* This will exclude branch on count and branch on index patterns
13397 since these are correctly statically predicted. */
13398 if (!set
13399 || SET_DEST (set) != pc_rtx
13400 || GET_CODE (SET_SRC(set)) != IF_THEN_ELSE)
13401 return false;
13402
7a64c761 13403 /* Skip conditional returns. */
13404 if (ANY_RETURN_P (XEXP (SET_SRC (set), 1))
13405 && XEXP (SET_SRC (set), 2) == pc_rtx)
13406 return false;
13407
73df8a45 13408 label_ref = (GET_CODE (XEXP (SET_SRC (set), 1)) == LABEL_REF ?
13409 XEXP (SET_SRC (set), 1) : XEXP (SET_SRC (set), 2));
13410
13411 gcc_assert (GET_CODE (label_ref) == LABEL_REF);
13412
13413 code_label = XEXP (label_ref, 0);
13414
13415 if (INSN_ADDRESSES (INSN_UID (code_label)) == -1
13416 || INSN_ADDRESSES (INSN_UID (insn)) == -1
13417 || (INSN_ADDRESSES (INSN_UID (insn))
33d033da 13418 - INSN_ADDRESSES (INSN_UID (code_label)) < PREDICT_DISTANCE))
73df8a45 13419 return false;
13420
13421 for (distance = 0, cur_insn = PREV_INSN (insn);
33d033da 13422 distance < PREDICT_DISTANCE - 6;
73df8a45 13423 distance += get_attr_length (cur_insn), cur_insn = PREV_INSN (cur_insn))
13424 if (!cur_insn || JUMP_P (cur_insn) || LABEL_P (cur_insn))
13425 return false;
13426
db7dd023 13427 rtx_code_label *new_label = gen_label_rtx ();
73df8a45 13428 uncond_jump = emit_jump_insn_after (
d1f9b275 13429 gen_rtx_SET (pc_rtx,
73df8a45 13430 gen_rtx_LABEL_REF (VOIDmode, code_label)),
13431 insn);
13432 emit_label_after (new_label, uncond_jump);
13433
13434 tmp = XEXP (SET_SRC (set), 1);
13435 XEXP (SET_SRC (set), 1) = XEXP (SET_SRC (set), 2);
13436 XEXP (SET_SRC (set), 2) = tmp;
13437 INSN_CODE (insn) = -1;
13438
13439 XEXP (label_ref, 0) = new_label;
13440 JUMP_LABEL (insn) = new_label;
13441 JUMP_LABEL (uncond_jump) = code_label;
13442
13443 return true;
13444}
13445
3b14a2e6 13446/* Returns 1 if INSN reads the value of REG for purposes not related
13447 to addressing of memory, and 0 otherwise. */
13448static int
93e0956b 13449s390_non_addr_reg_read_p (rtx reg, rtx_insn *insn)
3b14a2e6 13450{
13451 return reg_referenced_p (reg, PATTERN (insn))
13452 && !reg_used_in_mem_p (REGNO (reg), PATTERN (insn));
13453}
13454
512d9edf 13455/* Starting from INSN find_cond_jump looks downwards in the insn
13456 stream for a single jump insn which is the last user of the
13457 condition code set in INSN. */
93e0956b 13458static rtx_insn *
13459find_cond_jump (rtx_insn *insn)
512d9edf 13460{
13461 for (; insn; insn = NEXT_INSN (insn))
13462 {
13463 rtx ite, cc;
13464
13465 if (LABEL_P (insn))
13466 break;
13467
13468 if (!JUMP_P (insn))
13469 {
13470 if (reg_mentioned_p (gen_rtx_REG (CCmode, CC_REGNUM), insn))
13471 break;
13472 continue;
13473 }
13474
13475 /* This will be triggered by a return. */
13476 if (GET_CODE (PATTERN (insn)) != SET)
13477 break;
13478
13479 gcc_assert (SET_DEST (PATTERN (insn)) == pc_rtx);
13480 ite = SET_SRC (PATTERN (insn));
13481
13482 if (GET_CODE (ite) != IF_THEN_ELSE)
13483 break;
13484
13485 cc = XEXP (XEXP (ite, 0), 0);
13486 if (!REG_P (cc) || !CC_REGNO_P (REGNO (cc)))
13487 break;
13488
13489 if (find_reg_note (insn, REG_DEAD, cc))
13490 return insn;
13491 break;
13492 }
13493
93e0956b 13494 return NULL;
512d9edf 13495}
13496
13497/* Swap the condition in COND and the operands in OP0 and OP1 so that
13498 the semantics does not change. If NULL_RTX is passed as COND the
13499 function tries to find the conditional jump starting with INSN. */
13500static void
93e0956b 13501s390_swap_cmp (rtx cond, rtx *op0, rtx *op1, rtx_insn *insn)
512d9edf 13502{
13503 rtx tmp = *op0;
13504
13505 if (cond == NULL_RTX)
13506 {
50fc2d35 13507 rtx_insn *jump = find_cond_jump (NEXT_INSN (insn));
13508 rtx set = jump ? single_set (jump) : NULL_RTX;
512d9edf 13509
50fc2d35 13510 if (set == NULL_RTX)
512d9edf 13511 return;
13512
50fc2d35 13513 cond = XEXP (SET_SRC (set), 0);
512d9edf 13514 }
13515
13516 *op0 = *op1;
13517 *op1 = tmp;
13518 PUT_CODE (cond, swap_condition (GET_CODE (cond)));
13519}
3b14a2e6 13520
13521/* On z10, instructions of the compare-and-branch family have the
13522 property to access the register occurring as second operand with
13523 its bits complemented. If such a compare is grouped with a second
13524 instruction that accesses the same register non-complemented, and
13525 if that register's value is delivered via a bypass, then the
13526 pipeline recycles, thereby causing significant performance decline.
13527 This function locates such situations and exchanges the two
73df8a45 13528 operands of the compare. The function return true whenever it
13529 added an insn. */
13530static bool
93e0956b 13531s390_z10_optimize_cmp (rtx_insn *insn)
3b14a2e6 13532{
93e0956b 13533 rtx_insn *prev_insn, *next_insn;
73df8a45 13534 bool insn_added_p = false;
13535 rtx cond, *op0, *op1;
3b14a2e6 13536
73df8a45 13537 if (GET_CODE (PATTERN (insn)) == PARALLEL)
3b14a2e6 13538 {
73df8a45 13539 /* Handle compare and branch and branch on count
13540 instructions. */
13541 rtx pattern = single_set (insn);
512d9edf 13542
73df8a45 13543 if (!pattern
13544 || SET_DEST (pattern) != pc_rtx
13545 || GET_CODE (SET_SRC (pattern)) != IF_THEN_ELSE)
13546 return false;
3b14a2e6 13547
73df8a45 13548 cond = XEXP (SET_SRC (pattern), 0);
13549 op0 = &XEXP (cond, 0);
13550 op1 = &XEXP (cond, 1);
13551 }
13552 else if (GET_CODE (PATTERN (insn)) == SET)
13553 {
13554 rtx src, dest;
3b14a2e6 13555
73df8a45 13556 /* Handle normal compare instructions. */
13557 src = SET_SRC (PATTERN (insn));
13558 dest = SET_DEST (PATTERN (insn));
512d9edf 13559
73df8a45 13560 if (!REG_P (dest)
13561 || !CC_REGNO_P (REGNO (dest))
13562 || GET_CODE (src) != COMPARE)
13563 return false;
512d9edf 13564
73df8a45 13565 /* s390_swap_cmp will try to find the conditional
13566 jump when passing NULL_RTX as condition. */
13567 cond = NULL_RTX;
13568 op0 = &XEXP (src, 0);
13569 op1 = &XEXP (src, 1);
13570 }
13571 else
13572 return false;
512d9edf 13573
73df8a45 13574 if (!REG_P (*op0) || !REG_P (*op1))
13575 return false;
512d9edf 13576
cc6056e1 13577 if (GET_MODE_CLASS (GET_MODE (*op0)) != MODE_INT)
13578 return false;
13579
73df8a45 13580 /* Swap the COMPARE arguments and its mask if there is a
13581 conflicting access in the previous insn. */
bc1c8bc5 13582 prev_insn = prev_active_insn (insn);
73df8a45 13583 if (prev_insn != NULL_RTX && INSN_P (prev_insn)
13584 && reg_referenced_p (*op1, PATTERN (prev_insn)))
13585 s390_swap_cmp (cond, op0, op1, insn);
13586
13587 /* Check if there is a conflict with the next insn. If there
13588 was no conflict with the previous insn, then swap the
13589 COMPARE arguments and its mask. If we already swapped
13590 the operands, or if swapping them would cause a conflict
13591 with the previous insn, issue a NOP after the COMPARE in
13592 order to separate the two instuctions. */
bc1c8bc5 13593 next_insn = next_active_insn (insn);
73df8a45 13594 if (next_insn != NULL_RTX && INSN_P (next_insn)
13595 && s390_non_addr_reg_read_p (*op1, next_insn))
13596 {
512d9edf 13597 if (prev_insn != NULL_RTX && INSN_P (prev_insn)
73df8a45 13598 && s390_non_addr_reg_read_p (*op0, prev_insn))
512d9edf 13599 {
73df8a45 13600 if (REGNO (*op1) == 0)
13601 emit_insn_after (gen_nop1 (), insn);
512d9edf 13602 else
73df8a45 13603 emit_insn_after (gen_nop (), insn);
13604 insn_added_p = true;
3b14a2e6 13605 }
73df8a45 13606 else
13607 s390_swap_cmp (cond, op0, op1, insn);
3b14a2e6 13608 }
73df8a45 13609 return insn_added_p;
3b14a2e6 13610}
13611
987860a9 13612/* Number of INSNs to be scanned backward in the last BB of the loop
13613 and forward in the first BB of the loop. This usually should be a
13614 bit more than the number of INSNs which could go into one
13615 group. */
13616#define S390_OSC_SCAN_INSN_NUM 5
13617
13618/* Scan LOOP for static OSC collisions and return true if a osc_break
13619 should be issued for this loop. */
13620static bool
13621s390_adjust_loop_scan_osc (struct loop* loop)
13622
13623{
13624 HARD_REG_SET modregs, newregs;
13625 rtx_insn *insn, *store_insn = NULL;
13626 rtx set;
13627 struct s390_address addr_store, addr_load;
13628 subrtx_iterator::array_type array;
13629 int insn_count;
13630
13631 CLEAR_HARD_REG_SET (modregs);
13632
13633 insn_count = 0;
13634 FOR_BB_INSNS_REVERSE (loop->latch, insn)
13635 {
13636 if (!INSN_P (insn) || INSN_CODE (insn) <= 0)
13637 continue;
13638
13639 insn_count++;
13640 if (insn_count > S390_OSC_SCAN_INSN_NUM)
13641 return false;
13642
13643 find_all_hard_reg_sets (insn, &newregs, true);
13644 IOR_HARD_REG_SET (modregs, newregs);
13645
13646 set = single_set (insn);
13647 if (!set)
13648 continue;
13649
13650 if (MEM_P (SET_DEST (set))
13651 && s390_decompose_address (XEXP (SET_DEST (set), 0), &addr_store))
13652 {
13653 store_insn = insn;
13654 break;
13655 }
13656 }
13657
13658 if (store_insn == NULL_RTX)
13659 return false;
13660
13661 insn_count = 0;
13662 FOR_BB_INSNS (loop->header, insn)
13663 {
13664 if (!INSN_P (insn) || INSN_CODE (insn) <= 0)
13665 continue;
13666
13667 if (insn == store_insn)
13668 return false;
13669
13670 insn_count++;
13671 if (insn_count > S390_OSC_SCAN_INSN_NUM)
13672 return false;
13673
13674 find_all_hard_reg_sets (insn, &newregs, true);
13675 IOR_HARD_REG_SET (modregs, newregs);
13676
13677 set = single_set (insn);
13678 if (!set)
13679 continue;
13680
13681 /* An intermediate store disrupts static OSC checking
13682 anyway. */
13683 if (MEM_P (SET_DEST (set))
13684 && s390_decompose_address (XEXP (SET_DEST (set), 0), NULL))
13685 return false;
13686
13687 FOR_EACH_SUBRTX (iter, array, SET_SRC (set), NONCONST)
13688 if (MEM_P (*iter)
13689 && s390_decompose_address (XEXP (*iter, 0), &addr_load)
13690 && rtx_equal_p (addr_load.base, addr_store.base)
13691 && rtx_equal_p (addr_load.indx, addr_store.indx)
13692 && rtx_equal_p (addr_load.disp, addr_store.disp))
13693 {
13694 if ((addr_load.base != NULL_RTX
13695 && TEST_HARD_REG_BIT (modregs, REGNO (addr_load.base)))
13696 || (addr_load.indx != NULL_RTX
13697 && TEST_HARD_REG_BIT (modregs, REGNO (addr_load.indx))))
13698 return true;
13699 }
13700 }
13701 return false;
13702}
13703
13704/* Look for adjustments which can be done on simple innermost
13705 loops. */
13706static void
13707s390_adjust_loops ()
13708{
13709 struct loop *loop = NULL;
13710
13711 df_analyze ();
13712 compute_bb_for_insn ();
13713
13714 /* Find the loops. */
13715 loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
13716
13717 FOR_EACH_LOOP (loop, LI_ONLY_INNERMOST)
13718 {
13719 if (dump_file)
13720 {
13721 flow_loop_dump (loop, dump_file, NULL, 0);
13722 fprintf (dump_file, ";; OSC loop scan Loop: ");
13723 }
13724 if (loop->latch == NULL
13725 || pc_set (BB_END (loop->latch)) == NULL_RTX
13726 || !s390_adjust_loop_scan_osc (loop))
13727 {
13728 if (dump_file)
13729 {
13730 if (loop->latch == NULL)
13731 fprintf (dump_file, " muliple backward jumps\n");
13732 else
13733 {
13734 fprintf (dump_file, " header insn: %d latch insn: %d ",
13735 INSN_UID (BB_HEAD (loop->header)),
13736 INSN_UID (BB_END (loop->latch)));
13737 if (pc_set (BB_END (loop->latch)) == NULL_RTX)
13738 fprintf (dump_file, " loop does not end with jump\n");
13739 else
13740 fprintf (dump_file, " not instrumented\n");
13741 }
13742 }
13743 }
13744 else
13745 {
13746 rtx_insn *new_insn;
13747
13748 if (dump_file)
13749 fprintf (dump_file, " adding OSC break insn: ");
13750 new_insn = emit_insn_before (gen_osc_break (),
13751 BB_END (loop->latch));
13752 INSN_ADDRESSES_NEW (new_insn, -1);
13753 }
13754 }
13755
13756 loop_optimizer_finalize ();
13757
13758 df_finish_pass (false);
13759}
13760
875862bf 13761/* Perform machine-dependent processing. */
7346ca58 13762
875862bf 13763static void
13764s390_reorg (void)
7346ca58 13765{
875862bf 13766 bool pool_overflow = false;
f4252e72 13767 int hw_before, hw_after;
7346ca58 13768
987860a9 13769 if (s390_tune == PROCESSOR_2964_Z13)
13770 s390_adjust_loops ();
13771
875862bf 13772 /* Make sure all splits have been performed; splits after
13773 machine_dependent_reorg might confuse insn length counts. */
13774 split_all_insns_noflow ();
f588eb9f 13775
875862bf 13776 /* Install the main literal pool and the associated base
13777 register load insns.
f588eb9f 13778
875862bf 13779 In addition, there are two problematic situations we need
13780 to correct:
7346ca58 13781
875862bf 13782 - the literal pool might be > 4096 bytes in size, so that
13783 some of its elements cannot be directly accessed
7346ca58 13784
875862bf 13785 - a branch target might be > 64K away from the branch, so that
13786 it is not possible to use a PC-relative instruction.
7346ca58 13787
875862bf 13788 To fix those, we split the single literal pool into multiple
13789 pool chunks, reloading the pool base register at various
13790 points throughout the function to ensure it always points to
13791 the pool chunk the following code expects, and / or replace
13792 PC-relative branches by absolute branches.
7346ca58 13793
875862bf 13794 However, the two problems are interdependent: splitting the
13795 literal pool can move a branch further away from its target,
13796 causing the 64K limit to overflow, and on the other hand,
13797 replacing a PC-relative branch by an absolute branch means
13798 we need to put the branch target address into the literal
13799 pool, possibly causing it to overflow.
44a61e21 13800
875862bf 13801 So, we loop trying to fix up both problems until we manage
13802 to satisfy both conditions at the same time. Note that the
13803 loop is guaranteed to terminate as every pass of the loop
13804 strictly decreases the total number of PC-relative branches
13805 in the function. (This is not completely true as there
13806 might be branch-over-pool insns introduced by chunkify_start.
13807 Those never need to be split however.) */
44a61e21 13808
875862bf 13809 for (;;)
13810 {
13811 struct constant_pool *pool = NULL;
80aaaa56 13812
875862bf 13813 /* Collect the literal pool. */
13814 if (!pool_overflow)
13815 {
13816 pool = s390_mainpool_start ();
13817 if (!pool)
13818 pool_overflow = true;
13819 }
80aaaa56 13820
875862bf 13821 /* If literal pool overflowed, start to chunkify it. */
13822 if (pool_overflow)
13823 pool = s390_chunkify_start ();
80aaaa56 13824
875862bf 13825 /* Split out-of-range branches. If this has created new
13826 literal pool entries, cancel current chunk list and
13827 recompute it. zSeries machines have large branch
13828 instructions, so we never need to split a branch. */
13829 if (!TARGET_CPU_ZARCH && s390_split_branches ())
13830 {
13831 if (pool_overflow)
13832 s390_chunkify_cancel (pool);
13833 else
13834 s390_mainpool_cancel (pool);
80aaaa56 13835
875862bf 13836 continue;
13837 }
13838
13839 /* If we made it up to here, both conditions are satisfied.
13840 Finish up literal pool related changes. */
13841 if (pool_overflow)
13842 s390_chunkify_finish (pool);
13843 else
13844 s390_mainpool_finish (pool);
13845
13846 /* We're done splitting branches. */
13847 cfun->machine->split_branches_pending_p = false;
13848 break;
80aaaa56 13849 }
80aaaa56 13850
babfdedf 13851 /* Generate out-of-pool execute target insns. */
13852 if (TARGET_CPU_ZARCH)
13853 {
93e0956b 13854 rtx_insn *insn, *target;
13855 rtx label;
babfdedf 13856
13857 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
13858 {
13859 label = s390_execute_label (insn);
13860 if (!label)
13861 continue;
13862
13863 gcc_assert (label != const0_rtx);
13864
13865 target = emit_label (XEXP (label, 0));
13866 INSN_ADDRESSES_NEW (target, -1);
13867
13868 target = emit_insn (s390_execute_target (insn));
13869 INSN_ADDRESSES_NEW (target, -1);
13870 }
13871 }
13872
13873 /* Try to optimize prologue and epilogue further. */
875862bf 13874 s390_optimize_prologue ();
3b14a2e6 13875
33d033da 13876 /* Walk over the insns and do some >=z10 specific changes. */
117d67d0 13877 if (s390_tune >= PROCESSOR_2097_Z10)
73df8a45 13878 {
93e0956b 13879 rtx_insn *insn;
73df8a45 13880 bool insn_added_p = false;
13881
13882 /* The insn lengths and addresses have to be up to date for the
13883 following manipulations. */
13884 shorten_branches (get_insns ());
13885
13886 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
13887 {
13888 if (!INSN_P (insn) || INSN_CODE (insn) <= 0)
13889 continue;
13890
13891 if (JUMP_P (insn))
33d033da 13892 insn_added_p |= s390_fix_long_loop_prediction (insn);
73df8a45 13893
33d033da 13894 if ((GET_CODE (PATTERN (insn)) == PARALLEL
13895 || GET_CODE (PATTERN (insn)) == SET)
13896 && s390_tune == PROCESSOR_2097_Z10)
73df8a45 13897 insn_added_p |= s390_z10_optimize_cmp (insn);
13898 }
13899
13900 /* Adjust branches if we added new instructions. */
13901 if (insn_added_p)
13902 shorten_branches (get_insns ());
13903 }
f4252e72 13904
13905 s390_function_num_hotpatch_hw (current_function_decl, &hw_before, &hw_after);
13906 if (hw_after > 0)
13907 {
13908 rtx_insn *insn;
13909
06877232 13910 /* Insert NOPs for hotpatching. */
f4252e72 13911 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8ae6e291 13912 /* Emit NOPs
13913 1. inside the area covered by debug information to allow setting
13914 breakpoints at the NOPs,
13915 2. before any insn which results in an asm instruction,
13916 3. before in-function labels to avoid jumping to the NOPs, for
13917 example as part of a loop,
13918 4. before any barrier in case the function is completely empty
13919 (__builtin_unreachable ()) and has neither internal labels nor
13920 active insns.
13921 */
13922 if (active_insn_p (insn) || BARRIER_P (insn) || LABEL_P (insn))
13923 break;
13924 /* Output a series of NOPs before the first active insn. */
13925 while (insn && hw_after > 0)
f4252e72 13926 {
13927 if (hw_after >= 3 && TARGET_CPU_ZARCH)
13928 {
8ae6e291 13929 emit_insn_before (gen_nop_6_byte (), insn);
f4252e72 13930 hw_after -= 3;
13931 }
13932 else if (hw_after >= 2)
13933 {
8ae6e291 13934 emit_insn_before (gen_nop_4_byte (), insn);
f4252e72 13935 hw_after -= 2;
13936 }
13937 else
13938 {
8ae6e291 13939 emit_insn_before (gen_nop_2_byte (), insn);
f4252e72 13940 hw_after -= 1;
13941 }
13942 }
f4252e72 13943 }
875862bf 13944}
7346ca58 13945
8a2a84e3 13946/* Return true if INSN is a fp load insn writing register REGNO. */
13947static inline bool
ed3e6e5d 13948s390_fpload_toreg (rtx_insn *insn, unsigned int regno)
8a2a84e3 13949{
13950 rtx set;
13951 enum attr_type flag = s390_safe_attr_type (insn);
13952
13953 if (flag != TYPE_FLOADSF && flag != TYPE_FLOADDF)
13954 return false;
13955
13956 set = single_set (insn);
13957
13958 if (set == NULL_RTX)
13959 return false;
13960
13961 if (!REG_P (SET_DEST (set)) || !MEM_P (SET_SRC (set)))
13962 return false;
13963
13964 if (REGNO (SET_DEST (set)) != regno)
13965 return false;
13966
13967 return true;
13968}
13969
13970/* This value describes the distance to be avoided between an
2fbe7a32 13971 arithmetic fp instruction and an fp load writing the same register.
8a2a84e3 13972 Z10_EARLYLOAD_DISTANCE - 1 as well as Z10_EARLYLOAD_DISTANCE + 1 is
13973 fine but the exact value has to be avoided. Otherwise the FP
13974 pipeline will throw an exception causing a major penalty. */
13975#define Z10_EARLYLOAD_DISTANCE 7
13976
13977/* Rearrange the ready list in order to avoid the situation described
13978 for Z10_EARLYLOAD_DISTANCE. A problematic load instruction is
13979 moved to the very end of the ready list. */
13980static void
b24ef467 13981s390_z10_prevent_earlyload_conflicts (rtx_insn **ready, int *nready_p)
8a2a84e3 13982{
13983 unsigned int regno;
13984 int nready = *nready_p;
b24ef467 13985 rtx_insn *tmp;
8a2a84e3 13986 int i;
93e0956b 13987 rtx_insn *insn;
8a2a84e3 13988 rtx set;
13989 enum attr_type flag;
13990 int distance;
13991
13992 /* Skip DISTANCE - 1 active insns. */
13993 for (insn = last_scheduled_insn, distance = Z10_EARLYLOAD_DISTANCE - 1;
13994 distance > 0 && insn != NULL_RTX;
13995 distance--, insn = prev_active_insn (insn))
13996 if (CALL_P (insn) || JUMP_P (insn))
13997 return;
13998
13999 if (insn == NULL_RTX)
14000 return;
14001
14002 set = single_set (insn);
14003
14004 if (set == NULL_RTX || !REG_P (SET_DEST (set))
14005 || GET_MODE_CLASS (GET_MODE (SET_DEST (set))) != MODE_FLOAT)
14006 return;
14007
14008 flag = s390_safe_attr_type (insn);
14009
14010 if (flag == TYPE_FLOADSF || flag == TYPE_FLOADDF)
14011 return;
14012
14013 regno = REGNO (SET_DEST (set));
14014 i = nready - 1;
14015
14016 while (!s390_fpload_toreg (ready[i], regno) && i > 0)
14017 i--;
14018
14019 if (!i)
14020 return;
14021
14022 tmp = ready[i];
b24ef467 14023 memmove (&ready[1], &ready[0], sizeof (rtx_insn *) * i);
8a2a84e3 14024 ready[0] = tmp;
14025}
14026
81769881 14027
14028/* The s390_sched_state variable tracks the state of the current or
14029 the last instruction group.
14030
14031 0,1,2 number of instructions scheduled in the current group
14032 3 the last group is complete - normal insns
14033 4 the last group was a cracked/expanded insn */
14034
14035static int s390_sched_state;
14036
0cb69051 14037#define S390_SCHED_STATE_NORMAL 3
14038#define S390_SCHED_STATE_CRACKED 4
81769881 14039
0cb69051 14040#define S390_SCHED_ATTR_MASK_CRACKED 0x1
14041#define S390_SCHED_ATTR_MASK_EXPANDED 0x2
14042#define S390_SCHED_ATTR_MASK_ENDGROUP 0x4
14043#define S390_SCHED_ATTR_MASK_GROUPALONE 0x8
81769881 14044
14045static unsigned int
d3ffa7b4 14046s390_get_sched_attrmask (rtx_insn *insn)
81769881 14047{
14048 unsigned int mask = 0;
14049
0cb69051 14050 switch (s390_tune)
14051 {
14052 case PROCESSOR_2827_ZEC12:
14053 if (get_attr_zEC12_cracked (insn))
14054 mask |= S390_SCHED_ATTR_MASK_CRACKED;
14055 if (get_attr_zEC12_expanded (insn))
14056 mask |= S390_SCHED_ATTR_MASK_EXPANDED;
14057 if (get_attr_zEC12_endgroup (insn))
14058 mask |= S390_SCHED_ATTR_MASK_ENDGROUP;
14059 if (get_attr_zEC12_groupalone (insn))
14060 mask |= S390_SCHED_ATTR_MASK_GROUPALONE;
14061 break;
14062 case PROCESSOR_2964_Z13:
c9213ca0 14063 case PROCESSOR_ARCH12:
0cb69051 14064 if (get_attr_z13_cracked (insn))
14065 mask |= S390_SCHED_ATTR_MASK_CRACKED;
14066 if (get_attr_z13_expanded (insn))
14067 mask |= S390_SCHED_ATTR_MASK_EXPANDED;
14068 if (get_attr_z13_endgroup (insn))
14069 mask |= S390_SCHED_ATTR_MASK_ENDGROUP;
14070 if (get_attr_z13_groupalone (insn))
14071 mask |= S390_SCHED_ATTR_MASK_GROUPALONE;
14072 break;
14073 default:
14074 gcc_unreachable ();
14075 }
14076 return mask;
14077}
14078
14079static unsigned int
14080s390_get_unit_mask (rtx_insn *insn, int *units)
14081{
14082 unsigned int mask = 0;
14083
14084 switch (s390_tune)
14085 {
14086 case PROCESSOR_2964_Z13:
c9213ca0 14087 case PROCESSOR_ARCH12:
0cb69051 14088 *units = 3;
14089 if (get_attr_z13_unit_lsu (insn))
14090 mask |= 1 << 0;
14091 if (get_attr_z13_unit_fxu (insn))
14092 mask |= 1 << 1;
14093 if (get_attr_z13_unit_vfu (insn))
14094 mask |= 1 << 2;
14095 break;
14096 default:
14097 gcc_unreachable ();
14098 }
81769881 14099 return mask;
14100}
14101
14102/* Return the scheduling score for INSN. The higher the score the
14103 better. The score is calculated from the OOO scheduling attributes
14104 of INSN and the scheduling state s390_sched_state. */
14105static int
d3ffa7b4 14106s390_sched_score (rtx_insn *insn)
81769881 14107{
14108 unsigned int mask = s390_get_sched_attrmask (insn);
14109 int score = 0;
14110
14111 switch (s390_sched_state)
14112 {
14113 case 0:
14114 /* Try to put insns into the first slot which would otherwise
14115 break a group. */
0cb69051 14116 if ((mask & S390_SCHED_ATTR_MASK_CRACKED) != 0
14117 || (mask & S390_SCHED_ATTR_MASK_EXPANDED) != 0)
81769881 14118 score += 5;
0cb69051 14119 if ((mask & S390_SCHED_ATTR_MASK_GROUPALONE) != 0)
81769881 14120 score += 10;
0903985d 14121 /* fallthrough */
81769881 14122 case 1:
14123 /* Prefer not cracked insns while trying to put together a
14124 group. */
0cb69051 14125 if ((mask & S390_SCHED_ATTR_MASK_CRACKED) == 0
14126 && (mask & S390_SCHED_ATTR_MASK_EXPANDED) == 0
14127 && (mask & S390_SCHED_ATTR_MASK_GROUPALONE) == 0)
81769881 14128 score += 10;
0cb69051 14129 if ((mask & S390_SCHED_ATTR_MASK_ENDGROUP) == 0)
81769881 14130 score += 5;
14131 break;
14132 case 2:
14133 /* Prefer not cracked insns while trying to put together a
14134 group. */
0cb69051 14135 if ((mask & S390_SCHED_ATTR_MASK_CRACKED) == 0
14136 && (mask & S390_SCHED_ATTR_MASK_EXPANDED) == 0
14137 && (mask & S390_SCHED_ATTR_MASK_GROUPALONE) == 0)
81769881 14138 score += 10;
14139 /* Prefer endgroup insns in the last slot. */
0cb69051 14140 if ((mask & S390_SCHED_ATTR_MASK_ENDGROUP) != 0)
81769881 14141 score += 10;
14142 break;
0cb69051 14143 case S390_SCHED_STATE_NORMAL:
81769881 14144 /* Prefer not cracked insns if the last was not cracked. */
0cb69051 14145 if ((mask & S390_SCHED_ATTR_MASK_CRACKED) == 0
14146 && (mask & S390_SCHED_ATTR_MASK_EXPANDED) == 0)
81769881 14147 score += 5;
0cb69051 14148 if ((mask & S390_SCHED_ATTR_MASK_GROUPALONE) != 0)
81769881 14149 score += 10;
14150 break;
0cb69051 14151 case S390_SCHED_STATE_CRACKED:
81769881 14152 /* Try to keep cracked insns together to prevent them from
14153 interrupting groups. */
0cb69051 14154 if ((mask & S390_SCHED_ATTR_MASK_CRACKED) != 0
14155 || (mask & S390_SCHED_ATTR_MASK_EXPANDED) != 0)
81769881 14156 score += 5;
14157 break;
14158 }
0cb69051 14159
c9213ca0 14160 if (s390_tune >= PROCESSOR_2964_Z13)
0cb69051 14161 {
14162 int units, i;
14163 unsigned unit_mask, m = 1;
14164
14165 unit_mask = s390_get_unit_mask (insn, &units);
14166 gcc_assert (units <= MAX_SCHED_UNITS);
14167
14168 /* Add a score in range 0..MAX_SCHED_MIX_SCORE depending on how long
14169 ago the last insn of this unit type got scheduled. This is
14170 supposed to help providing a proper instruction mix to the
14171 CPU. */
14172 for (i = 0; i < units; i++, m <<= 1)
14173 if (m & unit_mask)
14174 score += (last_scheduled_unit_distance[i] * MAX_SCHED_MIX_SCORE /
14175 MAX_SCHED_MIX_DISTANCE);
14176 }
81769881 14177 return score;
14178}
14179
8a2a84e3 14180/* This function is called via hook TARGET_SCHED_REORDER before
4246a5c7 14181 issuing one insn from list READY which contains *NREADYP entries.
8a2a84e3 14182 For target z10 it reorders load instructions to avoid early load
14183 conflicts in the floating point pipeline */
14184static int
81769881 14185s390_sched_reorder (FILE *file, int verbose,
b24ef467 14186 rtx_insn **ready, int *nreadyp, int clock ATTRIBUTE_UNUSED)
8a2a84e3 14187{
117d67d0 14188 if (s390_tune == PROCESSOR_2097_Z10
14189 && reload_completed
14190 && *nreadyp > 1)
14191 s390_z10_prevent_earlyload_conflicts (ready, nreadyp);
8a2a84e3 14192
117d67d0 14193 if (s390_tune >= PROCESSOR_2827_ZEC12
81769881 14194 && reload_completed
14195 && *nreadyp > 1)
14196 {
14197 int i;
14198 int last_index = *nreadyp - 1;
14199 int max_index = -1;
14200 int max_score = -1;
b24ef467 14201 rtx_insn *tmp;
81769881 14202
14203 /* Just move the insn with the highest score to the top (the
14204 end) of the list. A full sort is not needed since a conflict
14205 in the hazard recognition cannot happen. So the top insn in
14206 the ready list will always be taken. */
14207 for (i = last_index; i >= 0; i--)
14208 {
14209 int score;
14210
14211 if (recog_memoized (ready[i]) < 0)
14212 continue;
14213
14214 score = s390_sched_score (ready[i]);
14215 if (score > max_score)
14216 {
14217 max_score = score;
14218 max_index = i;
14219 }
14220 }
14221
14222 if (max_index != -1)
14223 {
14224 if (max_index != last_index)
14225 {
14226 tmp = ready[max_index];
14227 ready[max_index] = ready[last_index];
14228 ready[last_index] = tmp;
14229
14230 if (verbose > 5)
14231 fprintf (file,
0cb69051 14232 ";;\t\tBACKEND: move insn %d to the top of list\n",
81769881 14233 INSN_UID (ready[last_index]));
14234 }
14235 else if (verbose > 5)
14236 fprintf (file,
0cb69051 14237 ";;\t\tBACKEND: best insn %d already on top\n",
81769881 14238 INSN_UID (ready[last_index]));
14239 }
14240
14241 if (verbose > 5)
14242 {
14243 fprintf (file, "ready list ooo attributes - sched state: %d\n",
14244 s390_sched_state);
14245
14246 for (i = last_index; i >= 0; i--)
14247 {
0cb69051 14248 unsigned int sched_mask;
14249 rtx_insn *insn = ready[i];
14250
14251 if (recog_memoized (insn) < 0)
81769881 14252 continue;
0cb69051 14253
14254 sched_mask = s390_get_sched_attrmask (insn);
14255 fprintf (file, ";;\t\tBACKEND: insn %d score: %d: ",
14256 INSN_UID (insn),
14257 s390_sched_score (insn));
14258#define PRINT_SCHED_ATTR(M, ATTR) fprintf (file, "%s ",\
14259 ((M) & sched_mask) ? #ATTR : "");
14260 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_CRACKED, cracked);
14261 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_EXPANDED, expanded);
14262 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_ENDGROUP, endgroup);
14263 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_GROUPALONE, groupalone);
14264#undef PRINT_SCHED_ATTR
c9213ca0 14265 if (s390_tune >= PROCESSOR_2964_Z13)
0cb69051 14266 {
14267 unsigned int unit_mask, m = 1;
14268 int units, j;
14269
14270 unit_mask = s390_get_unit_mask (insn, &units);
14271 fprintf (file, "(units:");
14272 for (j = 0; j < units; j++, m <<= 1)
14273 if (m & unit_mask)
14274 fprintf (file, " u%d", j);
14275 fprintf (file, ")");
14276 }
81769881 14277 fprintf (file, "\n");
14278 }
14279 }
14280 }
14281
8a2a84e3 14282 return s390_issue_rate ();
14283}
14284
81769881 14285
8a2a84e3 14286/* This function is called via hook TARGET_SCHED_VARIABLE_ISSUE after
14287 the scheduler has issued INSN. It stores the last issued insn into
14288 last_scheduled_insn in order to make it available for
14289 s390_sched_reorder. */
14290static int
18282db0 14291s390_sched_variable_issue (FILE *file, int verbose, rtx_insn *insn, int more)
8a2a84e3 14292{
14293 last_scheduled_insn = insn;
14294
117d67d0 14295 if (s390_tune >= PROCESSOR_2827_ZEC12
81769881 14296 && reload_completed
14297 && recog_memoized (insn) >= 0)
14298 {
14299 unsigned int mask = s390_get_sched_attrmask (insn);
14300
0cb69051 14301 if ((mask & S390_SCHED_ATTR_MASK_CRACKED) != 0
14302 || (mask & S390_SCHED_ATTR_MASK_EXPANDED) != 0)
14303 s390_sched_state = S390_SCHED_STATE_CRACKED;
14304 else if ((mask & S390_SCHED_ATTR_MASK_ENDGROUP) != 0
14305 || (mask & S390_SCHED_ATTR_MASK_GROUPALONE) != 0)
14306 s390_sched_state = S390_SCHED_STATE_NORMAL;
81769881 14307 else
14308 {
14309 /* Only normal insns are left (mask == 0). */
14310 switch (s390_sched_state)
14311 {
14312 case 0:
14313 case 1:
14314 case 2:
0cb69051 14315 case S390_SCHED_STATE_NORMAL:
14316 if (s390_sched_state == S390_SCHED_STATE_NORMAL)
81769881 14317 s390_sched_state = 1;
14318 else
14319 s390_sched_state++;
14320
14321 break;
0cb69051 14322 case S390_SCHED_STATE_CRACKED:
14323 s390_sched_state = S390_SCHED_STATE_NORMAL;
81769881 14324 break;
14325 }
14326 }
0cb69051 14327
c9213ca0 14328 if (s390_tune >= PROCESSOR_2964_Z13)
0cb69051 14329 {
14330 int units, i;
14331 unsigned unit_mask, m = 1;
14332
14333 unit_mask = s390_get_unit_mask (insn, &units);
14334 gcc_assert (units <= MAX_SCHED_UNITS);
14335
14336 for (i = 0; i < units; i++, m <<= 1)
14337 if (m & unit_mask)
14338 last_scheduled_unit_distance[i] = 0;
14339 else if (last_scheduled_unit_distance[i] < MAX_SCHED_MIX_DISTANCE)
14340 last_scheduled_unit_distance[i]++;
14341 }
14342
81769881 14343 if (verbose > 5)
14344 {
0cb69051 14345 unsigned int sched_mask;
14346
14347 sched_mask = s390_get_sched_attrmask (insn);
14348
14349 fprintf (file, ";;\t\tBACKEND: insn %d: ", INSN_UID (insn));
14350#define PRINT_SCHED_ATTR(M, ATTR) fprintf (file, "%s ", ((M) & sched_mask) ? #ATTR : "");
14351 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_CRACKED, cracked);
14352 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_EXPANDED, expanded);
14353 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_ENDGROUP, endgroup);
14354 PRINT_SCHED_ATTR (S390_SCHED_ATTR_MASK_GROUPALONE, groupalone);
14355#undef PRINT_SCHED_ATTR
14356
c9213ca0 14357 if (s390_tune >= PROCESSOR_2964_Z13)
0cb69051 14358 {
14359 unsigned int unit_mask, m = 1;
14360 int units, j;
14361
14362 unit_mask = s390_get_unit_mask (insn, &units);
14363 fprintf (file, "(units:");
14364 for (j = 0; j < units; j++, m <<= 1)
14365 if (m & unit_mask)
14366 fprintf (file, " %d", j);
14367 fprintf (file, ")");
14368 }
14369 fprintf (file, " sched state: %d\n", s390_sched_state);
14370
c9213ca0 14371 if (s390_tune >= PROCESSOR_2964_Z13)
0cb69051 14372 {
14373 int units, j;
14374
14375 s390_get_unit_mask (insn, &units);
14376
14377 fprintf (file, ";;\t\tBACKEND: units unused for: ");
14378 for (j = 0; j < units; j++)
14379 fprintf (file, "%d:%d ", j, last_scheduled_unit_distance[j]);
14380 fprintf (file, "\n");
14381 }
81769881 14382 }
14383 }
14384
8a2a84e3 14385 if (GET_CODE (PATTERN (insn)) != USE
14386 && GET_CODE (PATTERN (insn)) != CLOBBER)
14387 return more - 1;
14388 else
14389 return more;
14390}
7346ca58 14391
494d0169 14392static void
14393s390_sched_init (FILE *file ATTRIBUTE_UNUSED,
14394 int verbose ATTRIBUTE_UNUSED,
14395 int max_ready ATTRIBUTE_UNUSED)
14396{
93e0956b 14397 last_scheduled_insn = NULL;
0cb69051 14398 memset (last_scheduled_unit_distance, 0, MAX_SCHED_UNITS * sizeof (int));
81769881 14399 s390_sched_state = 0;
494d0169 14400}
14401
9ccaa774 14402/* This target hook implementation for TARGET_LOOP_UNROLL_ADJUST calculates
33d033da 14403 a new number struct loop *loop should be unrolled if tuned for cpus with
14404 a built-in stride prefetcher.
14405 The loop is analyzed for memory accesses by calling check_dpu for
9ccaa774 14406 each rtx of the loop. Depending on the loop_depth and the amount of
14407 memory accesses a new number <=nunroll is returned to improve the
67cf9b55 14408 behavior of the hardware prefetch unit. */
9ccaa774 14409static unsigned
14410s390_loop_unroll_adjust (unsigned nunroll, struct loop *loop)
14411{
14412 basic_block *bbs;
93e0956b 14413 rtx_insn *insn;
9ccaa774 14414 unsigned i;
14415 unsigned mem_count = 0;
14416
117d67d0 14417 if (s390_tune < PROCESSOR_2097_Z10)
9ccaa774 14418 return nunroll;
14419
14420 /* Count the number of memory references within the loop body. */
14421 bbs = get_loop_body (loop);
15e472ec 14422 subrtx_iterator::array_type array;
9ccaa774 14423 for (i = 0; i < loop->num_nodes; i++)
15e472ec 14424 FOR_BB_INSNS (bbs[i], insn)
14425 if (INSN_P (insn) && INSN_CODE (insn) != -1)
14426 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
14427 if (MEM_P (*iter))
14428 mem_count += 1;
9ccaa774 14429 free (bbs);
14430
14431 /* Prevent division by zero, and we do not need to adjust nunroll in this case. */
14432 if (mem_count == 0)
14433 return nunroll;
14434
14435 switch (loop_depth(loop))
14436 {
14437 case 1:
14438 return MIN (nunroll, 28 / mem_count);
14439 case 2:
14440 return MIN (nunroll, 22 / mem_count);
14441 default:
14442 return MIN (nunroll, 16 / mem_count);
14443 }
14444}
14445
7a0cee35 14446/* Restore the current options. This is a hook function and also called
14447 internally. */
14448
0b8be04c 14449static void
7a0cee35 14450s390_function_specific_restore (struct gcc_options *opts,
14451 struct cl_target_option *ptr ATTRIBUTE_UNUSED)
0b8be04c 14452{
7a0cee35 14453 opts->x_s390_cost_pointer = (long)processor_table[opts->x_s390_tune].cost;
14454}
0b8be04c 14455
7a0cee35 14456static void
3bd8520f 14457s390_option_override_internal (bool main_args_p,
14458 struct gcc_options *opts,
7a0cee35 14459 const struct gcc_options *opts_set)
14460{
3bd8520f 14461 const char *prefix;
14462 const char *suffix;
14463
14464 /* Set up prefix/suffix so the error messages refer to either the command
14465 line argument, or the attribute(target). */
14466 if (main_args_p)
14467 {
14468 prefix = "-m";
14469 suffix = "";
14470 }
14471 else
14472 {
14473 prefix = "option(\"";
14474 suffix = "\")";
14475 }
14476
14477
0b8be04c 14478 /* Architecture mode defaults according to ABI. */
7a0cee35 14479 if (!(opts_set->x_target_flags & MASK_ZARCH))
0b8be04c 14480 {
14481 if (TARGET_64BIT)
7a0cee35 14482 opts->x_target_flags |= MASK_ZARCH;
0b8be04c 14483 else
7a0cee35 14484 opts->x_target_flags &= ~MASK_ZARCH;
0b8be04c 14485 }
14486
7a0cee35 14487 /* Set the march default in case it hasn't been specified on cmdline. */
14488 if (!opts_set->x_s390_arch)
3bd8520f 14489 opts->x_s390_arch = PROCESSOR_2064_Z900;
14490 else if (opts->x_s390_arch == PROCESSOR_9672_G5
14491 || opts->x_s390_arch == PROCESSOR_9672_G6)
14492 warning (OPT_Wdeprecated, "%sarch=%s%s is deprecated and will be removed "
14493 "in future releases; use at least %sarch=z900%s",
14494 prefix, opts->x_s390_arch == PROCESSOR_9672_G5 ? "g5" : "g6",
14495 suffix, prefix, suffix);
14496
7a0cee35 14497 opts->x_s390_arch_flags = processor_flags_table[(int) opts->x_s390_arch];
0b8be04c 14498
14499 /* Determine processor to tune for. */
7a0cee35 14500 if (!opts_set->x_s390_tune)
14501 opts->x_s390_tune = opts->x_s390_arch;
3bd8520f 14502 else if (opts->x_s390_tune == PROCESSOR_9672_G5
14503 || opts->x_s390_tune == PROCESSOR_9672_G6)
14504 warning (OPT_Wdeprecated, "%stune=%s%s is deprecated and will be removed "
14505 "in future releases; use at least %stune=z900%s",
14506 prefix, opts->x_s390_tune == PROCESSOR_9672_G5 ? "g5" : "g6",
14507 suffix, prefix, suffix);
14508
7a0cee35 14509 opts->x_s390_tune_flags = processor_flags_table[opts->x_s390_tune];
0b8be04c 14510
14511 /* Sanity checks. */
7a0cee35 14512 if (opts->x_s390_arch == PROCESSOR_NATIVE
14513 || opts->x_s390_tune == PROCESSOR_NATIVE)
db249f37 14514 gcc_unreachable ();
7a0cee35 14515 if (TARGET_ZARCH_P (opts->x_target_flags) && !TARGET_CPU_ZARCH_P (opts))
14516 error ("z/Architecture mode not supported on %s",
14517 processor_table[(int)opts->x_s390_arch].name);
14518 if (TARGET_64BIT && !TARGET_ZARCH_P (opts->x_target_flags))
0b8be04c 14519 error ("64-bit ABI not supported in ESA/390 mode");
14520
0b8be04c 14521 /* Enable hardware transactions if available and not explicitly
14522 disabled by user. E.g. with -m31 -march=zEC12 -mzarch */
7a0cee35 14523 if (!TARGET_OPT_HTM_P (opts_set->x_target_flags))
14524 {
14525 if (TARGET_CPU_HTM_P (opts) && TARGET_ZARCH_P (opts->x_target_flags))
14526 opts->x_target_flags |= MASK_OPT_HTM;
14527 else
14528 opts->x_target_flags &= ~MASK_OPT_HTM;
14529 }
0b8be04c 14530
7a0cee35 14531 if (TARGET_OPT_VX_P (opts_set->x_target_flags))
cc79fcc9 14532 {
7a0cee35 14533 if (TARGET_OPT_VX_P (opts->x_target_flags))
cc79fcc9 14534 {
7a0cee35 14535 if (!TARGET_CPU_VX_P (opts))
cc79fcc9 14536 error ("hardware vector support not available on %s",
7a0cee35 14537 processor_table[(int)opts->x_s390_arch].name);
14538 if (TARGET_SOFT_FLOAT_P (opts->x_target_flags))
cc79fcc9 14539 error ("hardware vector support not available with -msoft-float");
14540 }
14541 }
7a0cee35 14542 else
14543 {
14544 if (TARGET_CPU_VX_P (opts))
14545 /* Enable vector support if available and not explicitly disabled
14546 by user. E.g. with -m31 -march=z13 -mzarch */
14547 opts->x_target_flags |= MASK_OPT_VX;
14548 else
14549 opts->x_target_flags &= ~MASK_OPT_VX;
14550 }
cc79fcc9 14551
7a0cee35 14552 /* Use hardware DFP if available and not explicitly disabled by
14553 user. E.g. with -m31 -march=z10 -mzarch */
14554 if (!TARGET_HARD_DFP_P (opts_set->x_target_flags))
14555 {
14556 if (TARGET_DFP_P (opts))
14557 opts->x_target_flags |= MASK_HARD_DFP;
14558 else
14559 opts->x_target_flags &= ~MASK_HARD_DFP;
14560 }
14561
14562 if (TARGET_HARD_DFP_P (opts->x_target_flags) && !TARGET_DFP_P (opts))
0b8be04c 14563 {
7a0cee35 14564 if (TARGET_HARD_DFP_P (opts_set->x_target_flags))
0b8be04c 14565 {
7a0cee35 14566 if (!TARGET_CPU_DFP_P (opts))
0b8be04c 14567 error ("hardware decimal floating point instructions"
7a0cee35 14568 " not available on %s",
14569 processor_table[(int)opts->x_s390_arch].name);
14570 if (!TARGET_ZARCH_P (opts->x_target_flags))
0b8be04c 14571 error ("hardware decimal floating point instructions"
14572 " not available in ESA/390 mode");
14573 }
14574 else
7a0cee35 14575 opts->x_target_flags &= ~MASK_HARD_DFP;
0b8be04c 14576 }
14577
7a0cee35 14578 if (TARGET_SOFT_FLOAT_P (opts_set->x_target_flags)
14579 && TARGET_SOFT_FLOAT_P (opts->x_target_flags))
0b8be04c 14580 {
7a0cee35 14581 if (TARGET_HARD_DFP_P (opts_set->x_target_flags)
14582 && TARGET_HARD_DFP_P (opts->x_target_flags))
0b8be04c 14583 error ("-mhard-dfp can%'t be used in conjunction with -msoft-float");
14584
7a0cee35 14585 opts->x_target_flags &= ~MASK_HARD_DFP;
0b8be04c 14586 }
14587
7a0cee35 14588 if (TARGET_BACKCHAIN_P (opts->x_target_flags)
14589 && TARGET_PACKED_STACK_P (opts->x_target_flags)
14590 && TARGET_HARD_FLOAT_P (opts->x_target_flags))
0b8be04c 14591 error ("-mbackchain -mpacked-stack -mhard-float are not supported "
14592 "in combination");
14593
7a0cee35 14594 if (opts->x_s390_stack_size)
0b8be04c 14595 {
7a0cee35 14596 if (opts->x_s390_stack_guard >= opts->x_s390_stack_size)
0b8be04c 14597 error ("stack size must be greater than the stack guard value");
7a0cee35 14598 else if (opts->x_s390_stack_size > 1 << 16)
0b8be04c 14599 error ("stack size must not be greater than 64k");
14600 }
7a0cee35 14601 else if (opts->x_s390_stack_guard)
0b8be04c 14602 error ("-mstack-guard implies use of -mstack-size");
14603
14604#ifdef TARGET_DEFAULT_LONG_DOUBLE_128
7a0cee35 14605 if (!TARGET_LONG_DOUBLE_128_P (opts_set->x_target_flags))
14606 opts->x_target_flags |= MASK_LONG_DOUBLE_128;
0b8be04c 14607#endif
14608
7a0cee35 14609 if (opts->x_s390_tune >= PROCESSOR_2097_Z10)
0b8be04c 14610 {
14611 maybe_set_param_value (PARAM_MAX_UNROLLED_INSNS, 100,
7a0cee35 14612 opts->x_param_values,
14613 opts_set->x_param_values);
0b8be04c 14614 maybe_set_param_value (PARAM_MAX_UNROLL_TIMES, 32,
7a0cee35 14615 opts->x_param_values,
14616 opts_set->x_param_values);
0b8be04c 14617 maybe_set_param_value (PARAM_MAX_COMPLETELY_PEELED_INSNS, 2000,
7a0cee35 14618 opts->x_param_values,
14619 opts_set->x_param_values);
0b8be04c 14620 maybe_set_param_value (PARAM_MAX_COMPLETELY_PEEL_TIMES, 64,
7a0cee35 14621 opts->x_param_values,
14622 opts_set->x_param_values);
0b8be04c 14623 }
14624
14625 maybe_set_param_value (PARAM_MAX_PENDING_LIST_LENGTH, 256,
7a0cee35 14626 opts->x_param_values,
14627 opts_set->x_param_values);
0b8be04c 14628 /* values for loop prefetching */
14629 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE, 256,
7a0cee35 14630 opts->x_param_values,
14631 opts_set->x_param_values);
0b8be04c 14632 maybe_set_param_value (PARAM_L1_CACHE_SIZE, 128,
7a0cee35 14633 opts->x_param_values,
14634 opts_set->x_param_values);
0b8be04c 14635 /* s390 has more than 2 levels and the size is much larger. Since
14636 we are always running virtualized assume that we only get a small
14637 part of the caches above l1. */
14638 maybe_set_param_value (PARAM_L2_CACHE_SIZE, 1500,
7a0cee35 14639 opts->x_param_values,
14640 opts_set->x_param_values);
0b8be04c 14641 maybe_set_param_value (PARAM_PREFETCH_MIN_INSN_TO_MEM_RATIO, 2,
7a0cee35 14642 opts->x_param_values,
14643 opts_set->x_param_values);
0b8be04c 14644 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES, 6,
7a0cee35 14645 opts->x_param_values,
14646 opts_set->x_param_values);
14647
14648 /* Use the alternative scheduling-pressure algorithm by default. */
14649 maybe_set_param_value (PARAM_SCHED_PRESSURE_ALGORITHM, 2,
14650 opts->x_param_values,
14651 opts_set->x_param_values);
14652
e328d74f 14653 maybe_set_param_value (PARAM_MIN_VECT_LOOP_BOUND, 2,
14654 opts->x_param_values,
14655 opts_set->x_param_values);
14656
7a0cee35 14657 /* Call target specific restore function to do post-init work. At the moment,
14658 this just sets opts->x_s390_cost_pointer. */
14659 s390_function_specific_restore (opts, NULL);
14660}
14661
14662static void
14663s390_option_override (void)
14664{
14665 unsigned int i;
14666 cl_deferred_option *opt;
14667 vec<cl_deferred_option> *v =
14668 (vec<cl_deferred_option> *) s390_deferred_options;
14669
14670 if (v)
14671 FOR_EACH_VEC_ELT (*v, i, opt)
14672 {
14673 switch (opt->opt_index)
14674 {
14675 case OPT_mhotpatch_:
14676 {
14677 int val1;
14678 int val2;
14679 char s[256];
14680 char *t;
14681
14682 strncpy (s, opt->arg, 256);
14683 s[255] = 0;
14684 t = strchr (s, ',');
14685 if (t != NULL)
14686 {
14687 *t = 0;
14688 t++;
14689 val1 = integral_argument (s);
14690 val2 = integral_argument (t);
14691 }
14692 else
14693 {
14694 val1 = -1;
14695 val2 = -1;
14696 }
14697 if (val1 == -1 || val2 == -1)
14698 {
14699 /* argument is not a plain number */
14700 error ("arguments to %qs should be non-negative integers",
14701 "-mhotpatch=n,m");
14702 break;
14703 }
14704 else if (val1 > s390_hotpatch_hw_max
14705 || val2 > s390_hotpatch_hw_max)
14706 {
14707 error ("argument to %qs is too large (max. %d)",
14708 "-mhotpatch=n,m", s390_hotpatch_hw_max);
14709 break;
14710 }
14711 s390_hotpatch_hw_before_label = val1;
14712 s390_hotpatch_hw_after_label = val2;
14713 break;
14714 }
14715 default:
14716 gcc_unreachable ();
14717 }
14718 }
14719
14720 /* Set up function hooks. */
14721 init_machine_status = s390_init_machine_status;
14722
3bd8520f 14723 s390_option_override_internal (true, &global_options, &global_options_set);
7a0cee35 14724
14725 /* Save the initial options in case the user does function specific
14726 options. */
14727 target_option_default_node = build_target_option_node (&global_options);
14728 target_option_current_node = target_option_default_node;
0b8be04c 14729
14730 /* This cannot reside in s390_option_optimization_table since HAVE_prefetch
14731 requires the arch flags to be evaluated already. Since prefetching
14732 is beneficial on s390, we enable it if available. */
14733 if (flag_prefetch_loop_arrays < 0 && HAVE_prefetch && optimize >= 3)
14734 flag_prefetch_loop_arrays = 1;
14735
0b8be04c 14736 if (TARGET_TPF)
14737 {
14738 /* Don't emit DWARF3/4 unless specifically selected. The TPF
14739 debuggers do not yet support DWARF 3/4. */
14740 if (!global_options_set.x_dwarf_strict)
14741 dwarf_strict = 1;
14742 if (!global_options_set.x_dwarf_version)
14743 dwarf_version = 2;
14744 }
14745
14746 /* Register a target-specific optimization-and-lowering pass
14747 to run immediately before prologue and epilogue generation.
14748
14749 Registering the pass must be done at start up. It's
14750 convenient to do it here. */
14751 opt_pass *new_pass = new pass_s390_early_mach (g);
14752 struct register_pass_info insert_pass_s390_early_mach =
14753 {
14754 new_pass, /* pass */
14755 "pro_and_epilogue", /* reference_pass_name */
14756 1, /* ref_pass_instance_number */
14757 PASS_POS_INSERT_BEFORE /* po_op */
14758 };
14759 register_pass (&insert_pass_s390_early_mach);
14760}
14761
7a0cee35 14762#if S390_USE_TARGET_ATTRIBUTE
14763/* Inner function to process the attribute((target(...))), take an argument and
14764 set the current options from the argument. If we have a list, recursively go
14765 over the list. */
14766
14767static bool
14768s390_valid_target_attribute_inner_p (tree args,
14769 struct gcc_options *opts,
14770 struct gcc_options *new_opts_set,
14771 bool force_pragma)
14772{
14773 char *next_optstr;
14774 bool ret = true;
14775
14776#define S390_ATTRIB(S,O,A) { S, sizeof (S)-1, O, A, 0 }
14777#define S390_PRAGMA(S,O,A) { S, sizeof (S)-1, O, A, 1 }
14778 static const struct
14779 {
14780 const char *string;
14781 size_t len;
14782 int opt;
14783 int has_arg;
14784 int only_as_pragma;
14785 } attrs[] = {
14786 /* enum options */
14787 S390_ATTRIB ("arch=", OPT_march_, 1),
14788 S390_ATTRIB ("tune=", OPT_mtune_, 1),
14789 /* uinteger options */
14790 S390_ATTRIB ("stack-guard=", OPT_mstack_guard_, 1),
14791 S390_ATTRIB ("stack-size=", OPT_mstack_size_, 1),
14792 S390_ATTRIB ("branch-cost=", OPT_mbranch_cost_, 1),
14793 S390_ATTRIB ("warn-framesize=", OPT_mwarn_framesize_, 1),
14794 /* flag options */
14795 S390_ATTRIB ("backchain", OPT_mbackchain, 0),
14796 S390_ATTRIB ("hard-dfp", OPT_mhard_dfp, 0),
14797 S390_ATTRIB ("hard-float", OPT_mhard_float, 0),
14798 S390_ATTRIB ("htm", OPT_mhtm, 0),
14799 S390_ATTRIB ("vx", OPT_mvx, 0),
14800 S390_ATTRIB ("packed-stack", OPT_mpacked_stack, 0),
14801 S390_ATTRIB ("small-exec", OPT_msmall_exec, 0),
14802 S390_ATTRIB ("soft-float", OPT_msoft_float, 0),
14803 S390_ATTRIB ("mvcle", OPT_mmvcle, 0),
14804 S390_PRAGMA ("zvector", OPT_mzvector, 0),
14805 /* boolean options */
14806 S390_ATTRIB ("warn-dynamicstack", OPT_mwarn_dynamicstack, 0),
14807 };
14808#undef S390_ATTRIB
14809#undef S390_PRAGMA
14810
14811 /* If this is a list, recurse to get the options. */
14812 if (TREE_CODE (args) == TREE_LIST)
14813 {
14814 bool ret = true;
14815 int num_pragma_values;
14816 int i;
14817
14818 /* Note: attribs.c:decl_attributes prepends the values from
14819 current_target_pragma to the list of target attributes. To determine
14820 whether we're looking at a value of the attribute or the pragma we
14821 assume that the first [list_length (current_target_pragma)] values in
14822 the list are the values from the pragma. */
14823 num_pragma_values = (!force_pragma && current_target_pragma != NULL)
14824 ? list_length (current_target_pragma) : 0;
14825 for (i = 0; args; args = TREE_CHAIN (args), i++)
14826 {
14827 bool is_pragma;
14828
14829 is_pragma = (force_pragma || i < num_pragma_values);
14830 if (TREE_VALUE (args)
14831 && !s390_valid_target_attribute_inner_p (TREE_VALUE (args),
14832 opts, new_opts_set,
14833 is_pragma))
14834 {
14835 ret = false;
14836 }
14837 }
14838 return ret;
14839 }
14840
14841 else if (TREE_CODE (args) != STRING_CST)
14842 {
14843 error ("attribute %<target%> argument not a string");
14844 return false;
14845 }
14846
14847 /* Handle multiple arguments separated by commas. */
14848 next_optstr = ASTRDUP (TREE_STRING_POINTER (args));
14849
14850 while (next_optstr && *next_optstr != '\0')
14851 {
14852 char *p = next_optstr;
14853 char *orig_p = p;
14854 char *comma = strchr (next_optstr, ',');
14855 size_t len, opt_len;
14856 int opt;
14857 bool opt_set_p;
14858 char ch;
14859 unsigned i;
14860 int mask = 0;
14861 enum cl_var_type var_type;
14862 bool found;
14863
14864 if (comma)
14865 {
14866 *comma = '\0';
14867 len = comma - next_optstr;
14868 next_optstr = comma + 1;
14869 }
14870 else
14871 {
14872 len = strlen (p);
14873 next_optstr = NULL;
14874 }
14875
14876 /* Recognize no-xxx. */
14877 if (len > 3 && p[0] == 'n' && p[1] == 'o' && p[2] == '-')
14878 {
14879 opt_set_p = false;
14880 p += 3;
14881 len -= 3;
14882 }
14883 else
14884 opt_set_p = true;
14885
14886 /* Find the option. */
14887 ch = *p;
14888 found = false;
14889 for (i = 0; i < ARRAY_SIZE (attrs); i++)
14890 {
14891 opt_len = attrs[i].len;
14892 if (ch == attrs[i].string[0]
14893 && ((attrs[i].has_arg) ? len > opt_len : len == opt_len)
14894 && memcmp (p, attrs[i].string, opt_len) == 0)
14895 {
14896 opt = attrs[i].opt;
14897 if (!opt_set_p && cl_options[opt].cl_reject_negative)
14898 continue;
14899 mask = cl_options[opt].var_value;
14900 var_type = cl_options[opt].var_type;
14901 found = true;
14902 break;
14903 }
14904 }
14905
14906 /* Process the option. */
14907 if (!found)
14908 {
14909 error ("attribute(target(\"%s\")) is unknown", orig_p);
14910 return false;
14911 }
14912 else if (attrs[i].only_as_pragma && !force_pragma)
14913 {
14914 /* Value is not allowed for the target attribute. */
19abb0ad 14915 error ("value %qs is not supported by attribute %<target%>",
7a0cee35 14916 attrs[i].string);
14917 return false;
14918 }
14919
14920 else if (var_type == CLVC_BIT_SET || var_type == CLVC_BIT_CLEAR)
14921 {
14922 if (var_type == CLVC_BIT_CLEAR)
14923 opt_set_p = !opt_set_p;
14924
14925 if (opt_set_p)
14926 opts->x_target_flags |= mask;
14927 else
14928 opts->x_target_flags &= ~mask;
14929 new_opts_set->x_target_flags |= mask;
14930 }
14931
14932 else if (cl_options[opt].var_type == CLVC_BOOLEAN)
14933 {
14934 int value;
14935
14936 if (cl_options[opt].cl_uinteger)
14937 {
14938 /* Unsigned integer argument. Code based on the function
14939 decode_cmdline_option () in opts-common.c. */
14940 value = integral_argument (p + opt_len);
14941 }
14942 else
14943 value = (opt_set_p) ? 1 : 0;
14944
14945 if (value != -1)
14946 {
14947 struct cl_decoded_option decoded;
14948
14949 /* Value range check; only implemented for numeric and boolean
14950 options at the moment. */
14951 generate_option (opt, NULL, value, CL_TARGET, &decoded);
14952 s390_handle_option (opts, new_opts_set, &decoded, input_location);
14953 set_option (opts, new_opts_set, opt, value,
14954 p + opt_len, DK_UNSPECIFIED, input_location,
14955 global_dc);
14956 }
14957 else
14958 {
14959 error ("attribute(target(\"%s\")) is unknown", orig_p);
14960 ret = false;
14961 }
14962 }
14963
14964 else if (cl_options[opt].var_type == CLVC_ENUM)
14965 {
14966 bool arg_ok;
14967 int value;
14968
14969 arg_ok = opt_enum_arg_to_value (opt, p + opt_len, &value, CL_TARGET);
14970 if (arg_ok)
14971 set_option (opts, new_opts_set, opt, value,
14972 p + opt_len, DK_UNSPECIFIED, input_location,
14973 global_dc);
14974 else
14975 {
14976 error ("attribute(target(\"%s\")) is unknown", orig_p);
14977 ret = false;
14978 }
14979 }
14980
14981 else
14982 gcc_unreachable ();
14983 }
14984 return ret;
14985}
14986
14987/* Return a TARGET_OPTION_NODE tree of the target options listed or NULL. */
14988
14989tree
14990s390_valid_target_attribute_tree (tree args,
14991 struct gcc_options *opts,
14992 const struct gcc_options *opts_set,
14993 bool force_pragma)
14994{
14995 tree t = NULL_TREE;
14996 struct gcc_options new_opts_set;
14997
14998 memset (&new_opts_set, 0, sizeof (new_opts_set));
14999
15000 /* Process each of the options on the chain. */
15001 if (! s390_valid_target_attribute_inner_p (args, opts, &new_opts_set,
15002 force_pragma))
15003 return error_mark_node;
15004
15005 /* If some option was set (even if it has not changed), rerun
15006 s390_option_override_internal, and then save the options away. */
15007 if (new_opts_set.x_target_flags
15008 || new_opts_set.x_s390_arch
15009 || new_opts_set.x_s390_tune
15010 || new_opts_set.x_s390_stack_guard
15011 || new_opts_set.x_s390_stack_size
15012 || new_opts_set.x_s390_branch_cost
15013 || new_opts_set.x_s390_warn_framesize
15014 || new_opts_set.x_s390_warn_dynamicstack_p)
15015 {
15016 const unsigned char *src = (const unsigned char *)opts_set;
15017 unsigned char *dest = (unsigned char *)&new_opts_set;
15018 unsigned int i;
15019
15020 /* Merge the original option flags into the new ones. */
15021 for (i = 0; i < sizeof(*opts_set); i++)
15022 dest[i] |= src[i];
15023
15024 /* Do any overrides, such as arch=xxx, or tune=xxx support. */
3bd8520f 15025 s390_option_override_internal (false, opts, &new_opts_set);
7a0cee35 15026 /* Save the current options unless we are validating options for
15027 #pragma. */
15028 t = build_target_option_node (opts);
15029 }
15030 return t;
15031}
15032
15033/* Hook to validate attribute((target("string"))). */
15034
15035static bool
15036s390_valid_target_attribute_p (tree fndecl,
15037 tree ARG_UNUSED (name),
15038 tree args,
15039 int ARG_UNUSED (flags))
15040{
15041 struct gcc_options func_options;
15042 tree new_target, new_optimize;
15043 bool ret = true;
15044
15045 /* attribute((target("default"))) does nothing, beyond
15046 affecting multi-versioning. */
15047 if (TREE_VALUE (args)
15048 && TREE_CODE (TREE_VALUE (args)) == STRING_CST
15049 && TREE_CHAIN (args) == NULL_TREE
15050 && strcmp (TREE_STRING_POINTER (TREE_VALUE (args)), "default") == 0)
15051 return true;
15052
15053 tree old_optimize = build_optimization_node (&global_options);
15054
15055 /* Get the optimization options of the current function. */
15056 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
15057
15058 if (!func_optimize)
15059 func_optimize = old_optimize;
15060
15061 /* Init func_options. */
15062 memset (&func_options, 0, sizeof (func_options));
15063 init_options_struct (&func_options, NULL);
15064 lang_hooks.init_options_struct (&func_options);
15065
15066 cl_optimization_restore (&func_options, TREE_OPTIMIZATION (func_optimize));
15067
15068 /* Initialize func_options to the default before its target options can
15069 be set. */
15070 cl_target_option_restore (&func_options,
15071 TREE_TARGET_OPTION (target_option_default_node));
15072
15073 new_target = s390_valid_target_attribute_tree (args, &func_options,
15074 &global_options_set,
15075 (args ==
15076 current_target_pragma));
15077 new_optimize = build_optimization_node (&func_options);
15078 if (new_target == error_mark_node)
15079 ret = false;
15080 else if (fndecl && new_target)
15081 {
15082 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
15083 if (old_optimize != new_optimize)
15084 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
15085 }
15086 return ret;
15087}
15088
15089/* Restore targets globals from NEW_TREE and invalidate s390_previous_fndecl
15090 cache. */
15091
15092void
15093s390_activate_target_options (tree new_tree)
15094{
15095 cl_target_option_restore (&global_options, TREE_TARGET_OPTION (new_tree));
15096 if (TREE_TARGET_GLOBALS (new_tree))
15097 restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
15098 else if (new_tree == target_option_default_node)
15099 restore_target_globals (&default_target_globals);
15100 else
15101 TREE_TARGET_GLOBALS (new_tree) = save_target_globals_default_opts ();
15102 s390_previous_fndecl = NULL_TREE;
15103}
15104
15105/* Establish appropriate back-end context for processing the function
15106 FNDECL. The argument might be NULL to indicate processing at top
15107 level, outside of any function scope. */
15108static void
15109s390_set_current_function (tree fndecl)
15110{
15111 /* Only change the context if the function changes. This hook is called
15112 several times in the course of compiling a function, and we don't want to
15113 slow things down too much or call target_reinit when it isn't safe. */
15114 if (fndecl == s390_previous_fndecl)
15115 return;
15116
15117 tree old_tree;
15118 if (s390_previous_fndecl == NULL_TREE)
15119 old_tree = target_option_current_node;
15120 else if (DECL_FUNCTION_SPECIFIC_TARGET (s390_previous_fndecl))
15121 old_tree = DECL_FUNCTION_SPECIFIC_TARGET (s390_previous_fndecl);
15122 else
15123 old_tree = target_option_default_node;
15124
15125 if (fndecl == NULL_TREE)
15126 {
15127 if (old_tree != target_option_current_node)
15128 s390_activate_target_options (target_option_current_node);
15129 return;
15130 }
15131
15132 tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
15133 if (new_tree == NULL_TREE)
15134 new_tree = target_option_default_node;
15135
15136 if (old_tree != new_tree)
15137 s390_activate_target_options (new_tree);
15138 s390_previous_fndecl = fndecl;
15139}
15140#endif
15141
a83f0e2c 15142/* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
15143
15144static bool
89da42b6 15145s390_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
a83f0e2c 15146 unsigned int align ATTRIBUTE_UNUSED,
15147 enum by_pieces_operation op ATTRIBUTE_UNUSED,
15148 bool speed_p ATTRIBUTE_UNUSED)
15149{
15150 return (size == 1 || size == 2
15151 || size == 4 || (TARGET_ZARCH && size == 8));
15152}
15153
90f58e2a 15154/* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV hook. */
15155
15156static void
15157s390_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
15158{
07f32359 15159 tree sfpc = s390_builtin_decls[S390_BUILTIN_s390_sfpc];
15160 tree efpc = s390_builtin_decls[S390_BUILTIN_s390_efpc];
90f58e2a 15161 tree call_efpc = build_call_expr (efpc, 0);
9550ce87 15162 tree fenv_var = create_tmp_var_raw (unsigned_type_node);
90f58e2a 15163
15164#define FPC_EXCEPTION_MASK HOST_WIDE_INT_UC (0xf8000000)
15165#define FPC_FLAGS_MASK HOST_WIDE_INT_UC (0x00f80000)
15166#define FPC_DXC_MASK HOST_WIDE_INT_UC (0x0000ff00)
15167#define FPC_EXCEPTION_MASK_SHIFT HOST_WIDE_INT_UC (24)
15168#define FPC_FLAGS_SHIFT HOST_WIDE_INT_UC (16)
15169#define FPC_DXC_SHIFT HOST_WIDE_INT_UC (8)
15170
15171 /* Generates the equivalent of feholdexcept (&fenv_var)
15172
15173 fenv_var = __builtin_s390_efpc ();
15174 __builtin_s390_sfpc (fenv_var & mask) */
15175 tree old_fpc = build2 (MODIFY_EXPR, unsigned_type_node, fenv_var, call_efpc);
15176 tree new_fpc =
15177 build2 (BIT_AND_EXPR, unsigned_type_node, fenv_var,
15178 build_int_cst (unsigned_type_node,
15179 ~(FPC_DXC_MASK | FPC_FLAGS_MASK |
15180 FPC_EXCEPTION_MASK)));
15181 tree set_new_fpc = build_call_expr (sfpc, 1, new_fpc);
15182 *hold = build2 (COMPOUND_EXPR, void_type_node, old_fpc, set_new_fpc);
15183
15184 /* Generates the equivalent of feclearexcept (FE_ALL_EXCEPT)
15185
15186 __builtin_s390_sfpc (__builtin_s390_efpc () & mask) */
15187 new_fpc = build2 (BIT_AND_EXPR, unsigned_type_node, call_efpc,
15188 build_int_cst (unsigned_type_node,
15189 ~(FPC_DXC_MASK | FPC_FLAGS_MASK)));
15190 *clear = build_call_expr (sfpc, 1, new_fpc);
15191
15192 /* Generates the equivalent of feupdateenv (fenv_var)
15193
15194 old_fpc = __builtin_s390_efpc ();
15195 __builtin_s390_sfpc (fenv_var);
15196 __atomic_feraiseexcept ((old_fpc & FPC_FLAGS_MASK) >> FPC_FLAGS_SHIFT); */
15197
9550ce87 15198 old_fpc = create_tmp_var_raw (unsigned_type_node);
90f58e2a 15199 tree store_old_fpc = build2 (MODIFY_EXPR, void_type_node,
15200 old_fpc, call_efpc);
15201
15202 set_new_fpc = build_call_expr (sfpc, 1, fenv_var);
15203
15204 tree raise_old_except = build2 (BIT_AND_EXPR, unsigned_type_node, old_fpc,
15205 build_int_cst (unsigned_type_node,
15206 FPC_FLAGS_MASK));
15207 raise_old_except = build2 (RSHIFT_EXPR, unsigned_type_node, raise_old_except,
15208 build_int_cst (unsigned_type_node,
15209 FPC_FLAGS_SHIFT));
15210 tree atomic_feraiseexcept
15211 = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT);
15212 raise_old_except = build_call_expr (atomic_feraiseexcept,
15213 1, raise_old_except);
15214
15215 *update = build2 (COMPOUND_EXPR, void_type_node,
15216 build2 (COMPOUND_EXPR, void_type_node,
15217 store_old_fpc, set_new_fpc),
15218 raise_old_except);
15219
15220#undef FPC_EXCEPTION_MASK
15221#undef FPC_FLAGS_MASK
15222#undef FPC_DXC_MASK
15223#undef FPC_EXCEPTION_MASK_SHIFT
15224#undef FPC_FLAGS_SHIFT
15225#undef FPC_DXC_SHIFT
15226}
15227
76a4c804 15228/* Return the vector mode to be used for inner mode MODE when doing
15229 vectorization. */
15230static machine_mode
15231s390_preferred_simd_mode (machine_mode mode)
15232{
15233 if (TARGET_VX)
15234 switch (mode)
15235 {
15236 case DFmode:
15237 return V2DFmode;
15238 case DImode:
15239 return V2DImode;
15240 case SImode:
15241 return V4SImode;
15242 case HImode:
15243 return V8HImode;
15244 case QImode:
15245 return V16QImode;
15246 default:;
15247 }
15248 return word_mode;
15249}
15250
15251/* Our hardware does not require vectors to be strictly aligned. */
15252static bool
15253s390_support_vector_misalignment (machine_mode mode ATTRIBUTE_UNUSED,
15254 const_tree type ATTRIBUTE_UNUSED,
15255 int misalignment ATTRIBUTE_UNUSED,
15256 bool is_packed ATTRIBUTE_UNUSED)
15257{
6bb09dc9 15258 if (TARGET_VX)
15259 return true;
15260
15261 return default_builtin_support_vector_misalignment (mode, type, misalignment,
15262 is_packed);
76a4c804 15263}
15264
15265/* The vector ABI requires vector types to be aligned on an 8 byte
15266 boundary (our stack alignment). However, we allow this to be
15267 overriden by the user, while this definitely breaks the ABI. */
15268static HOST_WIDE_INT
15269s390_vector_alignment (const_tree type)
15270{
15271 if (!TARGET_VX_ABI)
15272 return default_vector_alignment (type);
15273
15274 if (TYPE_USER_ALIGN (type))
15275 return TYPE_ALIGN (type);
15276
15277 return MIN (64, tree_to_shwi (TYPE_SIZE (type)));
15278}
15279
14d7e7e6 15280#ifdef HAVE_AS_MACHINE_MACHINEMODE
15281/* Implement TARGET_ASM_FILE_START. */
15282static void
15283s390_asm_file_start (void)
15284{
b904831d 15285 default_file_start ();
14d7e7e6 15286 s390_asm_output_machine_for_arch (asm_out_file);
15287}
15288#endif
15289
6b7cfb9c 15290/* Implement TARGET_ASM_FILE_END. */
15291static void
15292s390_asm_file_end (void)
15293{
15294#ifdef HAVE_AS_GNU_ATTRIBUTE
15295 varpool_node *vnode;
15296 cgraph_node *cnode;
15297
15298 FOR_EACH_VARIABLE (vnode)
15299 if (TREE_PUBLIC (vnode->decl))
15300 s390_check_type_for_vector_abi (TREE_TYPE (vnode->decl), false, false);
15301
15302 FOR_EACH_FUNCTION (cnode)
15303 if (TREE_PUBLIC (cnode->decl))
15304 s390_check_type_for_vector_abi (TREE_TYPE (cnode->decl), false, false);
15305
15306
15307 if (s390_vector_abi != 0)
15308 fprintf (asm_out_file, "\t.gnu_attribute 8, %d\n",
15309 s390_vector_abi);
15310#endif
15311 file_end_indicate_exec_stack ();
c6d481f7 15312
15313 if (flag_split_stack)
15314 file_end_indicate_split_stack ();
6b7cfb9c 15315}
76a4c804 15316
f0c550e7 15317/* Return true if TYPE is a vector bool type. */
15318static inline bool
15319s390_vector_bool_type_p (const_tree type)
15320{
15321 return TYPE_VECTOR_OPAQUE (type);
15322}
15323
15324/* Return the diagnostic message string if the binary operation OP is
15325 not permitted on TYPE1 and TYPE2, NULL otherwise. */
15326static const char*
15327s390_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1, const_tree type2)
15328{
15329 bool bool1_p, bool2_p;
15330 bool plusminus_p;
15331 bool muldiv_p;
15332 bool compare_p;
15333 machine_mode mode1, mode2;
15334
15335 if (!TARGET_ZVECTOR)
15336 return NULL;
15337
15338 if (!VECTOR_TYPE_P (type1) || !VECTOR_TYPE_P (type2))
15339 return NULL;
15340
15341 bool1_p = s390_vector_bool_type_p (type1);
15342 bool2_p = s390_vector_bool_type_p (type2);
15343
15344 /* Mixing signed and unsigned types is forbidden for all
15345 operators. */
15346 if (!bool1_p && !bool2_p
15347 && TYPE_UNSIGNED (type1) != TYPE_UNSIGNED (type2))
d0abd9e0 15348 return N_("types differ in signedness");
f0c550e7 15349
15350 plusminus_p = (op == PLUS_EXPR || op == MINUS_EXPR);
15351 muldiv_p = (op == MULT_EXPR || op == RDIV_EXPR || op == TRUNC_DIV_EXPR
15352 || op == CEIL_DIV_EXPR || op == FLOOR_DIV_EXPR
15353 || op == ROUND_DIV_EXPR);
15354 compare_p = (op == LT_EXPR || op == LE_EXPR || op == GT_EXPR || op == GE_EXPR
15355 || op == EQ_EXPR || op == NE_EXPR);
15356
15357 if (bool1_p && bool2_p && (plusminus_p || muldiv_p))
15358 return N_("binary operator does not support two vector bool operands");
15359
15360 if (bool1_p != bool2_p && (muldiv_p || compare_p))
15361 return N_("binary operator does not support vector bool operand");
15362
15363 mode1 = TYPE_MODE (type1);
15364 mode2 = TYPE_MODE (type2);
15365
15366 if (bool1_p != bool2_p && plusminus_p
15367 && (GET_MODE_CLASS (mode1) == MODE_VECTOR_FLOAT
15368 || GET_MODE_CLASS (mode2) == MODE_VECTOR_FLOAT))
15369 return N_("binary operator does not support mixing vector "
15370 "bool with floating point vector operands");
15371
15372 return NULL;
15373}
15374
1de60655 15375/* Implement TARGET_C_EXCESS_PRECISION.
15376
15377 FIXME: For historical reasons, float_t and double_t are typedef'ed to
15378 double on s390, causing operations on float_t to operate in a higher
15379 precision than is necessary. However, it is not the case that SFmode
15380 operations have implicit excess precision, and we generate more optimal
15381 code if we let the compiler know no implicit extra precision is added.
15382
15383 That means when we are compiling with -fexcess-precision=fast, the value
15384 we set for FLT_EVAL_METHOD will be out of line with the actual precision of
15385 float_t (though they would be correct for -fexcess-precision=standard).
15386
15387 A complete fix would modify glibc to remove the unnecessary typedef
15388 of float_t to double. */
15389
15390static enum flt_eval_method
15391s390_excess_precision (enum excess_precision_type type)
15392{
15393 switch (type)
15394 {
15395 case EXCESS_PRECISION_TYPE_IMPLICIT:
15396 case EXCESS_PRECISION_TYPE_FAST:
15397 /* The fastest type to promote to will always be the native type,
15398 whether that occurs with implicit excess precision or
15399 otherwise. */
15400 return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
15401 case EXCESS_PRECISION_TYPE_STANDARD:
15402 /* Otherwise, when we are in a standards compliant mode, to
15403 ensure consistency with the implementation in glibc, report that
15404 float is evaluated to the range and precision of double. */
15405 return FLT_EVAL_METHOD_PROMOTE_TO_DOUBLE;
15406 default:
15407 gcc_unreachable ();
15408 }
15409 return FLT_EVAL_METHOD_UNPREDICTABLE;
15410}
15411
fff1179b 15412/* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */
15413
15414static unsigned HOST_WIDE_INT
15415s390_asan_shadow_offset (void)
15416{
15417 return TARGET_64BIT ? HOST_WIDE_INT_1U << 52 : HOST_WIDE_INT_UC (0x20000000);
15418}
15419
875862bf 15420/* Initialize GCC target structure. */
f588eb9f 15421
875862bf 15422#undef TARGET_ASM_ALIGNED_HI_OP
15423#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
15424#undef TARGET_ASM_ALIGNED_DI_OP
15425#define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
15426#undef TARGET_ASM_INTEGER
15427#define TARGET_ASM_INTEGER s390_assemble_integer
7346ca58 15428
875862bf 15429#undef TARGET_ASM_OPEN_PAREN
15430#define TARGET_ASM_OPEN_PAREN ""
f588eb9f 15431
875862bf 15432#undef TARGET_ASM_CLOSE_PAREN
15433#define TARGET_ASM_CLOSE_PAREN ""
7346ca58 15434
4c834714 15435#undef TARGET_OPTION_OVERRIDE
15436#define TARGET_OPTION_OVERRIDE s390_option_override
15437
8a23256f 15438#ifdef TARGET_THREAD_SSP_OFFSET
15439#undef TARGET_STACK_PROTECT_GUARD
15440#define TARGET_STACK_PROTECT_GUARD hook_tree_void_null
15441#endif
15442
875862bf 15443#undef TARGET_ENCODE_SECTION_INFO
15444#define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
7346ca58 15445
b5fdc416 15446#undef TARGET_SCALAR_MODE_SUPPORTED_P
15447#define TARGET_SCALAR_MODE_SUPPORTED_P s390_scalar_mode_supported_p
15448
875862bf 15449#ifdef HAVE_AS_TLS
15450#undef TARGET_HAVE_TLS
15451#define TARGET_HAVE_TLS true
15452#endif
15453#undef TARGET_CANNOT_FORCE_CONST_MEM
15454#define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
7346ca58 15455
875862bf 15456#undef TARGET_DELEGITIMIZE_ADDRESS
15457#define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
7346ca58 15458
41e3a0c7 15459#undef TARGET_LEGITIMIZE_ADDRESS
15460#define TARGET_LEGITIMIZE_ADDRESS s390_legitimize_address
15461
875862bf 15462#undef TARGET_RETURN_IN_MEMORY
15463#define TARGET_RETURN_IN_MEMORY s390_return_in_memory
f588eb9f 15464
5ada7a14 15465#undef TARGET_INIT_BUILTINS
15466#define TARGET_INIT_BUILTINS s390_init_builtins
15467#undef TARGET_EXPAND_BUILTIN
15468#define TARGET_EXPAND_BUILTIN s390_expand_builtin
751c914e 15469#undef TARGET_BUILTIN_DECL
15470#define TARGET_BUILTIN_DECL s390_builtin_decl
5ada7a14 15471
1a561788 15472#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
15473#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA s390_output_addr_const_extra
15474
875862bf 15475#undef TARGET_ASM_OUTPUT_MI_THUNK
15476#define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
15477#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
a9f1838b 15478#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
7346ca58 15479
1de60655 15480#undef TARGET_C_EXCESS_PRECISION
15481#define TARGET_C_EXCESS_PRECISION s390_excess_precision
15482
875862bf 15483#undef TARGET_SCHED_ADJUST_PRIORITY
15484#define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
15485#undef TARGET_SCHED_ISSUE_RATE
15486#define TARGET_SCHED_ISSUE_RATE s390_issue_rate
15487#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
15488#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
f588eb9f 15489
8a2a84e3 15490#undef TARGET_SCHED_VARIABLE_ISSUE
15491#define TARGET_SCHED_VARIABLE_ISSUE s390_sched_variable_issue
15492#undef TARGET_SCHED_REORDER
15493#define TARGET_SCHED_REORDER s390_sched_reorder
494d0169 15494#undef TARGET_SCHED_INIT
15495#define TARGET_SCHED_INIT s390_sched_init
8a2a84e3 15496
875862bf 15497#undef TARGET_CANNOT_COPY_INSN_P
15498#define TARGET_CANNOT_COPY_INSN_P s390_cannot_copy_insn_p
15499#undef TARGET_RTX_COSTS
15500#define TARGET_RTX_COSTS s390_rtx_costs
15501#undef TARGET_ADDRESS_COST
15502#define TARGET_ADDRESS_COST s390_address_cost
fa7a995b 15503#undef TARGET_REGISTER_MOVE_COST
15504#define TARGET_REGISTER_MOVE_COST s390_register_move_cost
15505#undef TARGET_MEMORY_MOVE_COST
15506#define TARGET_MEMORY_MOVE_COST s390_memory_move_cost
292e369f 15507#undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
15508#define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
15509 s390_builtin_vectorization_cost
f588eb9f 15510
875862bf 15511#undef TARGET_MACHINE_DEPENDENT_REORG
15512#define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
71597dac 15513
875862bf 15514#undef TARGET_VALID_POINTER_MODE
15515#define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
f588eb9f 15516
875862bf 15517#undef TARGET_BUILD_BUILTIN_VA_LIST
15518#define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
8a58ed0a 15519#undef TARGET_EXPAND_BUILTIN_VA_START
15520#define TARGET_EXPAND_BUILTIN_VA_START s390_va_start
fff1179b 15521#undef TARGET_ASAN_SHADOW_OFFSET
15522#define TARGET_ASAN_SHADOW_OFFSET s390_asan_shadow_offset
875862bf 15523#undef TARGET_GIMPLIFY_VA_ARG_EXPR
15524#define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg
b33c41a1 15525
3b2411a8 15526#undef TARGET_PROMOTE_FUNCTION_MODE
15527#define TARGET_PROMOTE_FUNCTION_MODE s390_promote_function_mode
875862bf 15528#undef TARGET_PASS_BY_REFERENCE
15529#define TARGET_PASS_BY_REFERENCE s390_pass_by_reference
b33c41a1 15530
875862bf 15531#undef TARGET_FUNCTION_OK_FOR_SIBCALL
15532#define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
12bc26aa 15533#undef TARGET_FUNCTION_ARG
15534#define TARGET_FUNCTION_ARG s390_function_arg
15535#undef TARGET_FUNCTION_ARG_ADVANCE
15536#define TARGET_FUNCTION_ARG_ADVANCE s390_function_arg_advance
dc3b3062 15537#undef TARGET_FUNCTION_VALUE
15538#define TARGET_FUNCTION_VALUE s390_function_value
15539#undef TARGET_LIBCALL_VALUE
15540#define TARGET_LIBCALL_VALUE s390_libcall_value
76a4c804 15541#undef TARGET_STRICT_ARGUMENT_NAMING
15542#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
b33c41a1 15543
d44f2f7c 15544#undef TARGET_KEEP_LEAF_WHEN_PROFILED
15545#define TARGET_KEEP_LEAF_WHEN_PROFILED s390_keep_leaf_when_profiled
15546
875862bf 15547#undef TARGET_FIXED_CONDITION_CODE_REGS
15548#define TARGET_FIXED_CONDITION_CODE_REGS s390_fixed_condition_code_regs
b33c41a1 15549
875862bf 15550#undef TARGET_CC_MODES_COMPATIBLE
15551#define TARGET_CC_MODES_COMPATIBLE s390_cc_modes_compatible
b33c41a1 15552
1606e68a 15553#undef TARGET_INVALID_WITHIN_DOLOOP
18282db0 15554#define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_const_rtx_insn_null
e75dabf7 15555
40af64cc 15556#ifdef HAVE_AS_TLS
15557#undef TARGET_ASM_OUTPUT_DWARF_DTPREL
15558#define TARGET_ASM_OUTPUT_DWARF_DTPREL s390_output_dwarf_dtprel
15559#endif
15560
76a4c804 15561#undef TARGET_DWARF_FRAME_REG_MODE
15562#define TARGET_DWARF_FRAME_REG_MODE s390_dwarf_frame_reg_mode
15563
4257b08a 15564#ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
eddcdde1 15565#undef TARGET_MANGLE_TYPE
15566#define TARGET_MANGLE_TYPE s390_mangle_type
4257b08a 15567#endif
15568
36868490 15569#undef TARGET_SCALAR_MODE_SUPPORTED_P
15570#define TARGET_SCALAR_MODE_SUPPORTED_P s390_scalar_mode_supported_p
15571
76a4c804 15572#undef TARGET_VECTOR_MODE_SUPPORTED_P
15573#define TARGET_VECTOR_MODE_SUPPORTED_P s390_vector_mode_supported_p
15574
3359ccfd 15575#undef TARGET_PREFERRED_RELOAD_CLASS
15576#define TARGET_PREFERRED_RELOAD_CLASS s390_preferred_reload_class
15577
328d5423 15578#undef TARGET_SECONDARY_RELOAD
15579#define TARGET_SECONDARY_RELOAD s390_secondary_reload
15580
0ef89dfd 15581#undef TARGET_LIBGCC_CMP_RETURN_MODE
15582#define TARGET_LIBGCC_CMP_RETURN_MODE s390_libgcc_cmp_return_mode
15583
15584#undef TARGET_LIBGCC_SHIFT_COUNT_MODE
15585#define TARGET_LIBGCC_SHIFT_COUNT_MODE s390_libgcc_shift_count_mode
15586
fd50b071 15587#undef TARGET_LEGITIMATE_ADDRESS_P
15588#define TARGET_LEGITIMATE_ADDRESS_P s390_legitimate_address_p
15589
ca316360 15590#undef TARGET_LEGITIMATE_CONSTANT_P
15591#define TARGET_LEGITIMATE_CONSTANT_P s390_legitimate_constant_p
15592
7b1bda1c 15593#undef TARGET_LRA_P
15594#define TARGET_LRA_P s390_lra_p
15595
cd90919d 15596#undef TARGET_CAN_ELIMINATE
15597#define TARGET_CAN_ELIMINATE s390_can_eliminate
15598
b2d7ede1 15599#undef TARGET_CONDITIONAL_REGISTER_USAGE
15600#define TARGET_CONDITIONAL_REGISTER_USAGE s390_conditional_register_usage
15601
9ccaa774 15602#undef TARGET_LOOP_UNROLL_ADJUST
15603#define TARGET_LOOP_UNROLL_ADJUST s390_loop_unroll_adjust
15604
4d946732 15605#undef TARGET_ASM_TRAMPOLINE_TEMPLATE
15606#define TARGET_ASM_TRAMPOLINE_TEMPLATE s390_asm_trampoline_template
15607#undef TARGET_TRAMPOLINE_INIT
15608#define TARGET_TRAMPOLINE_INIT s390_trampoline_init
15609
8805debf 15610/* PR 79421 */
15611#undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
15612#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1
15613
b5fdc416 15614#undef TARGET_UNWIND_WORD_MODE
15615#define TARGET_UNWIND_WORD_MODE s390_unwind_word_mode
15616
d5065e6e 15617#undef TARGET_CANONICALIZE_COMPARISON
15618#define TARGET_CANONICALIZE_COMPARISON s390_canonicalize_comparison
15619
ff4ce128 15620#undef TARGET_HARD_REGNO_SCRATCH_OK
15621#define TARGET_HARD_REGNO_SCRATCH_OK s390_hard_regno_scratch_ok
15622
77bc9912 15623#undef TARGET_ATTRIBUTE_TABLE
15624#define TARGET_ATTRIBUTE_TABLE s390_attribute_table
15625
11762b83 15626#undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
15627#define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_const_tree_true
77bc9912 15628
7a64c761 15629#undef TARGET_SET_UP_BY_PROLOGUE
15630#define TARGET_SET_UP_BY_PROLOGUE s300_set_up_by_prologue
15631
c6d481f7 15632#undef TARGET_EXTRA_LIVE_ON_ENTRY
15633#define TARGET_EXTRA_LIVE_ON_ENTRY s390_live_on_entry
15634
a83f0e2c 15635#undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
15636#define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
15637 s390_use_by_pieces_infrastructure_p
15638
90f58e2a 15639#undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
15640#define TARGET_ATOMIC_ASSIGN_EXPAND_FENV s390_atomic_assign_expand_fenv
15641
76a4c804 15642#undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
15643#define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN s390_invalid_arg_for_unprototyped_fn
15644
15645#undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
15646#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE s390_preferred_simd_mode
15647
15648#undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
15649#define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT s390_support_vector_misalignment
15650
15651#undef TARGET_VECTOR_ALIGNMENT
15652#define TARGET_VECTOR_ALIGNMENT s390_vector_alignment
15653
f0c550e7 15654#undef TARGET_INVALID_BINARY_OP
15655#define TARGET_INVALID_BINARY_OP s390_invalid_binary_op
15656
14d7e7e6 15657#ifdef HAVE_AS_MACHINE_MACHINEMODE
15658#undef TARGET_ASM_FILE_START
15659#define TARGET_ASM_FILE_START s390_asm_file_start
15660#endif
15661
6b7cfb9c 15662#undef TARGET_ASM_FILE_END
15663#define TARGET_ASM_FILE_END s390_asm_file_end
15664
7a0cee35 15665#if S390_USE_TARGET_ATTRIBUTE
15666#undef TARGET_SET_CURRENT_FUNCTION
15667#define TARGET_SET_CURRENT_FUNCTION s390_set_current_function
15668
15669#undef TARGET_OPTION_VALID_ATTRIBUTE_P
15670#define TARGET_OPTION_VALID_ATTRIBUTE_P s390_valid_target_attribute_p
15671#endif
15672
15673#undef TARGET_OPTION_RESTORE
15674#define TARGET_OPTION_RESTORE s390_function_specific_restore
15675
875862bf 15676struct gcc_target targetm = TARGET_INITIALIZER;
f588eb9f 15677
5a5e802f 15678#include "gt-s390.h"