1 /* Subroutines used for code generation on IBM S/390 and zSeries
2 Copyright (C) 1999-2013 Free Software Foundation, Inc.
3 Contributed by Hartmut Penner (hpenner@de.ibm.com) and
4 Ulrich Weigand (uweigand@de.ibm.com) and
5 Andreas Krebbel (Andreas.Krebbel@de.ibm.com).
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "tree.h"
29 #include "tm_p.h"
30 #include "regs.h"
31 #include "hard-reg-set.h"
32 #include "insn-config.h"
33 #include "conditions.h"
34 #include "output.h"
35 #include "insn-attr.h"
36 #include "flags.h"
37 #include "except.h"
38 #include "function.h"
39 #include "recog.h"
40 #include "expr.h"
41 #include "reload.h"
42 #include "diagnostic-core.h"
43 #include "basic-block.h"
44 #include "ggc.h"
45 #include "target.h"
46 #include "target-def.h"
47 #include "debug.h"
48 #include "langhooks.h"
49 #include "optabs.h"
50 #include "gimple.h"
51 #include "df.h"
52 #include "params.h"
53 #include "cfgloop.h"
54 #include "opts.h"
55
56 /* Define the specific costs for a given cpu. */
57
58 struct processor_costs
59 {
60 /* multiplication */
61 const int m; /* cost of an M instruction. */
62 const int mghi; /* cost of an MGHI instruction. */
63 const int mh; /* cost of an MH instruction. */
64 const int mhi; /* cost of an MHI instruction. */
65 const int ml; /* cost of an ML instruction. */
66 const int mr; /* cost of an MR instruction. */
67 const int ms; /* cost of an MS instruction. */
68 const int msg; /* cost of an MSG instruction. */
69 const int msgf; /* cost of an MSGF instruction. */
70 const int msgfr; /* cost of an MSGFR instruction. */
71 const int msgr; /* cost of an MSGR instruction. */
72 const int msr; /* cost of an MSR instruction. */
73 const int mult_df; /* cost of multiplication in DFmode. */
74 const int mxbr;
75 /* square root */
76 const int sqxbr; /* cost of square root in TFmode. */
77 const int sqdbr; /* cost of square root in DFmode. */
78 const int sqebr; /* cost of square root in SFmode. */
79 /* multiply and add */
80 const int madbr; /* cost of multiply and add in DFmode. */
81 const int maebr; /* cost of multiply and add in SFmode. */
82 /* division */
83 const int dxbr;
84 const int ddbr;
85 const int debr;
86 const int dlgr;
87 const int dlr;
88 const int dr;
89 const int dsgfr;
90 const int dsgr;
91 };
92
93 const struct processor_costs *s390_cost;
94
95 static const
96 struct processor_costs z900_cost =
97 {
98 COSTS_N_INSNS (5), /* M */
99 COSTS_N_INSNS (10), /* MGHI */
100 COSTS_N_INSNS (5), /* MH */
101 COSTS_N_INSNS (4), /* MHI */
102 COSTS_N_INSNS (5), /* ML */
103 COSTS_N_INSNS (5), /* MR */
104 COSTS_N_INSNS (4), /* MS */
105 COSTS_N_INSNS (15), /* MSG */
106 COSTS_N_INSNS (7), /* MSGF */
107 COSTS_N_INSNS (7), /* MSGFR */
108 COSTS_N_INSNS (10), /* MSGR */
109 COSTS_N_INSNS (4), /* MSR */
110 COSTS_N_INSNS (7), /* multiplication in DFmode */
111 COSTS_N_INSNS (13), /* MXBR */
112 COSTS_N_INSNS (136), /* SQXBR */
113 COSTS_N_INSNS (44), /* SQDBR */
114 COSTS_N_INSNS (35), /* SQEBR */
115 COSTS_N_INSNS (18), /* MADBR */
116 COSTS_N_INSNS (13), /* MAEBR */
117 COSTS_N_INSNS (134), /* DXBR */
118 COSTS_N_INSNS (30), /* DDBR */
119 COSTS_N_INSNS (27), /* DEBR */
120 COSTS_N_INSNS (220), /* DLGR */
121 COSTS_N_INSNS (34), /* DLR */
122 COSTS_N_INSNS (34), /* DR */
123 COSTS_N_INSNS (32), /* DSGFR */
124 COSTS_N_INSNS (32), /* DSGR */
125 };
126
127 static const
128 struct processor_costs z990_cost =
129 {
130 COSTS_N_INSNS (4), /* M */
131 COSTS_N_INSNS (2), /* MGHI */
132 COSTS_N_INSNS (2), /* MH */
133 COSTS_N_INSNS (2), /* MHI */
134 COSTS_N_INSNS (4), /* ML */
135 COSTS_N_INSNS (4), /* MR */
136 COSTS_N_INSNS (5), /* MS */
137 COSTS_N_INSNS (6), /* MSG */
138 COSTS_N_INSNS (4), /* MSGF */
139 COSTS_N_INSNS (4), /* MSGFR */
140 COSTS_N_INSNS (4), /* MSGR */
141 COSTS_N_INSNS (4), /* MSR */
142 COSTS_N_INSNS (1), /* multiplication in DFmode */
143 COSTS_N_INSNS (28), /* MXBR */
144 COSTS_N_INSNS (130), /* SQXBR */
145 COSTS_N_INSNS (66), /* SQDBR */
146 COSTS_N_INSNS (38), /* SQEBR */
147 COSTS_N_INSNS (1), /* MADBR */
148 COSTS_N_INSNS (1), /* MAEBR */
149 COSTS_N_INSNS (60), /* DXBR */
150 COSTS_N_INSNS (40), /* DDBR */
151 COSTS_N_INSNS (26), /* DEBR */
152 COSTS_N_INSNS (176), /* DLGR */
153 COSTS_N_INSNS (31), /* DLR */
154 COSTS_N_INSNS (31), /* DR */
155 COSTS_N_INSNS (31), /* DSGFR */
156 COSTS_N_INSNS (31), /* DSGR */
157 };
158
159 static const
160 struct processor_costs z9_109_cost =
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 */
166 COSTS_N_INSNS (4), /* ML */
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 */
175 COSTS_N_INSNS (28), /* MXBR */
176 COSTS_N_INSNS (130), /* SQXBR */
177 COSTS_N_INSNS (66), /* SQDBR */
178 COSTS_N_INSNS (38), /* SQEBR */
179 COSTS_N_INSNS (1), /* MADBR */
180 COSTS_N_INSNS (1), /* MAEBR */
181 COSTS_N_INSNS (60), /* DXBR */
182 COSTS_N_INSNS (40), /* DDBR */
183 COSTS_N_INSNS (26), /* DEBR */
184 COSTS_N_INSNS (30), /* DLGR */
185 COSTS_N_INSNS (23), /* DLR */
186 COSTS_N_INSNS (23), /* DR */
187 COSTS_N_INSNS (24), /* DSGFR */
188 COSTS_N_INSNS (24), /* DSGR */
189 };
190
191 static const
192 struct processor_costs z10_cost =
193 {
194 COSTS_N_INSNS (10), /* M */
195 COSTS_N_INSNS (10), /* MGHI */
196 COSTS_N_INSNS (10), /* MH */
197 COSTS_N_INSNS (10), /* MHI */
198 COSTS_N_INSNS (10), /* ML */
199 COSTS_N_INSNS (10), /* MR */
200 COSTS_N_INSNS (10), /* MS */
201 COSTS_N_INSNS (10), /* MSG */
202 COSTS_N_INSNS (10), /* MSGF */
203 COSTS_N_INSNS (10), /* MSGFR */
204 COSTS_N_INSNS (10), /* MSGR */
205 COSTS_N_INSNS (10), /* MSR */
206 COSTS_N_INSNS (1) , /* multiplication in DFmode */
207 COSTS_N_INSNS (50), /* MXBR */
208 COSTS_N_INSNS (120), /* SQXBR */
209 COSTS_N_INSNS (52), /* SQDBR */
210 COSTS_N_INSNS (38), /* SQEBR */
211 COSTS_N_INSNS (1), /* MADBR */
212 COSTS_N_INSNS (1), /* MAEBR */
213 COSTS_N_INSNS (111), /* DXBR */
214 COSTS_N_INSNS (39), /* DDBR */
215 COSTS_N_INSNS (32), /* DEBR */
216 COSTS_N_INSNS (160), /* DLGR */
217 COSTS_N_INSNS (71), /* DLR */
218 COSTS_N_INSNS (71), /* DR */
219 COSTS_N_INSNS (71), /* DSGFR */
220 COSTS_N_INSNS (71), /* DSGR */
221 };
222
223 static const
224 struct processor_costs z196_cost =
225 {
226 COSTS_N_INSNS (7), /* M */
227 COSTS_N_INSNS (5), /* MGHI */
228 COSTS_N_INSNS (5), /* MH */
229 COSTS_N_INSNS (5), /* MHI */
230 COSTS_N_INSNS (7), /* ML */
231 COSTS_N_INSNS (7), /* MR */
232 COSTS_N_INSNS (6), /* MS */
233 COSTS_N_INSNS (8), /* MSG */
234 COSTS_N_INSNS (6), /* MSGF */
235 COSTS_N_INSNS (6), /* MSGFR */
236 COSTS_N_INSNS (8), /* MSGR */
237 COSTS_N_INSNS (6), /* MSR */
238 COSTS_N_INSNS (1) , /* multiplication in DFmode */
239 COSTS_N_INSNS (40), /* MXBR B+40 */
240 COSTS_N_INSNS (100), /* SQXBR B+100 */
241 COSTS_N_INSNS (42), /* SQDBR B+42 */
242 COSTS_N_INSNS (28), /* SQEBR B+28 */
243 COSTS_N_INSNS (1), /* MADBR B */
244 COSTS_N_INSNS (1), /* MAEBR B */
245 COSTS_N_INSNS (101), /* DXBR B+101 */
246 COSTS_N_INSNS (29), /* DDBR */
247 COSTS_N_INSNS (22), /* DEBR */
248 COSTS_N_INSNS (160), /* DLGR cracked */
249 COSTS_N_INSNS (160), /* DLR cracked */
250 COSTS_N_INSNS (160), /* DR expanded */
251 COSTS_N_INSNS (160), /* DSGFR cracked */
252 COSTS_N_INSNS (160), /* DSGR cracked */
253 };
254
255 static const
256 struct processor_costs zEC12_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 (131), /* DXBR B+131 */
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
287 extern int reload_completed;
288
289 /* Kept up to date using the SCHED_VARIABLE_ISSUE hook. */
290 static rtx last_scheduled_insn;
291
292 /* Structure used to hold the components of a S/390 memory
293 address. A legitimate address on S/390 is of the general
294 form
295 base + index + displacement
296 where any of the components is optional.
297
298 base and index are registers of the class ADDR_REGS,
299 displacement is an unsigned 12-bit immediate constant. */
300
301 struct s390_address
302 {
303 rtx base;
304 rtx indx;
305 rtx disp;
306 bool pointer;
307 bool literal_pool;
308 };
309
310 /* The following structure is embedded in the machine
311 specific part of struct function. */
312
313 struct GTY (()) s390_frame_layout
314 {
315 /* Offset within stack frame. */
316 HOST_WIDE_INT gprs_offset;
317 HOST_WIDE_INT f0_offset;
318 HOST_WIDE_INT f4_offset;
319 HOST_WIDE_INT f8_offset;
320 HOST_WIDE_INT backchain_offset;
321
322 /* Number of first and last gpr where slots in the register
323 save area are reserved for. */
324 int first_save_gpr_slot;
325 int last_save_gpr_slot;
326
327 /* Number of first and last gpr to be saved, restored. */
328 int first_save_gpr;
329 int first_restore_gpr;
330 int last_save_gpr;
331 int last_restore_gpr;
332
333 /* Bits standing for floating point registers. Set, if the
334 respective register has to be saved. Starting with reg 16 (f0)
335 at the rightmost bit.
336 Bit 15 - 8 7 6 5 4 3 2 1 0
337 fpr 15 - 8 7 5 3 1 6 4 2 0
338 reg 31 - 24 23 22 21 20 19 18 17 16 */
339 unsigned int fpr_bitmap;
340
341 /* Number of floating point registers f8-f15 which must be saved. */
342 int high_fprs;
343
344 /* Set if return address needs to be saved.
345 This flag is set by s390_return_addr_rtx if it could not use
346 the initial value of r14 and therefore depends on r14 saved
347 to the stack. */
348 bool save_return_addr_p;
349
350 /* Size of stack frame. */
351 HOST_WIDE_INT frame_size;
352 };
353
354 /* Define the structure for the machine field in struct function. */
355
356 struct GTY(()) machine_function
357 {
358 struct s390_frame_layout frame_layout;
359
360 /* Literal pool base register. */
361 rtx base_reg;
362
363 /* True if we may need to perform branch splitting. */
364 bool split_branches_pending_p;
365
366 /* Some local-dynamic TLS symbol name. */
367 const char *some_ld_name;
368
369 bool has_landing_pad_p;
370
371 /* True if the current function may contain a tbegin clobbering
372 FPRs. */
373 bool tbegin_p;
374 };
375
376 /* Few accessor macros for struct cfun->machine->s390_frame_layout. */
377
378 #define cfun_frame_layout (cfun->machine->frame_layout)
379 #define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)
380 #define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr_slot - \
381 cfun_frame_layout.first_save_gpr_slot + 1) * UNITS_PER_LONG)
382 #define cfun_set_fpr_bit(BITNUM) (cfun->machine->frame_layout.fpr_bitmap |= \
383 (1 << (BITNUM)))
384 #define cfun_fpr_bit_p(BITNUM) (!!(cfun->machine->frame_layout.fpr_bitmap & \
385 (1 << (BITNUM))))
386
387 /* Number of GPRs and FPRs used for argument passing. */
388 #define GP_ARG_NUM_REG 5
389 #define FP_ARG_NUM_REG (TARGET_64BIT? 4 : 2)
390
391 /* A couple of shortcuts. */
392 #define CONST_OK_FOR_J(x) \
393 CONST_OK_FOR_CONSTRAINT_P((x), 'J', "J")
394 #define CONST_OK_FOR_K(x) \
395 CONST_OK_FOR_CONSTRAINT_P((x), 'K', "K")
396 #define CONST_OK_FOR_Os(x) \
397 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Os")
398 #define CONST_OK_FOR_Op(x) \
399 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Op")
400 #define CONST_OK_FOR_On(x) \
401 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "On")
402
403 #define REGNO_PAIR_OK(REGNO, MODE) \
404 (HARD_REGNO_NREGS ((REGNO), (MODE)) == 1 || !((REGNO) & 1))
405
406 /* That's the read ahead of the dynamic branch prediction unit in
407 bytes on a z10 (or higher) CPU. */
408 #define PREDICT_DISTANCE (TARGET_Z10 ? 384 : 2048)
409
410 static const int s390_hotpatch_hw_max = 1000000;
411 static int s390_hotpatch_hw_before_label = 0;
412 static int s390_hotpatch_hw_after_label = 0;
413
414 /* Check whether the hotpatch attribute is applied to a function and, if it has
415 an argument, the argument is valid. */
416
417 static tree
s390_handle_hotpatch_attribute(tree * node,tree name,tree args,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs)418 s390_handle_hotpatch_attribute (tree *node, tree name, tree args,
419 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
420 {
421 tree expr;
422 tree expr2;
423 int err;
424
425 if (TREE_CODE (*node) != FUNCTION_DECL)
426 {
427 warning (OPT_Wattributes, "%qE attribute only applies to functions",
428 name);
429 *no_add_attrs = true;
430 }
431 if (args != NULL && TREE_CHAIN (args) != NULL)
432 {
433 expr = TREE_VALUE (args);
434 expr2 = TREE_VALUE (TREE_CHAIN (args));
435 }
436 if (args == NULL || TREE_CHAIN (args) == NULL)
437 err = 1;
438 else if (TREE_CODE (expr) != INTEGER_CST
439 || !INTEGRAL_TYPE_P (TREE_TYPE (expr))
440 || TREE_INT_CST_HIGH (expr) != 0
441 || TREE_INT_CST_LOW (expr) > (unsigned int)s390_hotpatch_hw_max)
442 err = 1;
443 else if (TREE_CODE (expr2) != INTEGER_CST
444 || !INTEGRAL_TYPE_P (TREE_TYPE (expr2))
445 || TREE_INT_CST_HIGH (expr2) != 0
446 || TREE_INT_CST_LOW (expr2) > (unsigned int)s390_hotpatch_hw_max)
447 err = 1;
448 else
449 err = 0;
450 if (err)
451 {
452 error ("requested %qE attribute is not a comma separated pair of"
453 " non-negative integer constants or too large (max. %d)", name,
454 s390_hotpatch_hw_max);
455 *no_add_attrs = true;
456 }
457
458 return NULL_TREE;
459 }
460
461 static const struct attribute_spec s390_attribute_table[] = {
462 { "hotpatch", 2, 2, true, false, false, s390_handle_hotpatch_attribute, false
463 },
464 /* End element. */
465 { NULL, 0, 0, false, false, false, NULL, false }
466 };
467
468 /* Return the alignment for LABEL. We default to the -falign-labels
469 value except for the literal pool base label. */
470 int
s390_label_align(rtx label)471 s390_label_align (rtx label)
472 {
473 rtx prev_insn = prev_active_insn (label);
474
475 if (prev_insn == NULL_RTX)
476 goto old;
477
478 prev_insn = single_set (prev_insn);
479
480 if (prev_insn == NULL_RTX)
481 goto old;
482
483 prev_insn = SET_SRC (prev_insn);
484
485 /* Don't align literal pool base labels. */
486 if (GET_CODE (prev_insn) == UNSPEC
487 && XINT (prev_insn, 1) == UNSPEC_MAIN_BASE)
488 return 0;
489
490 old:
491 return align_labels_log;
492 }
493
494 static enum machine_mode
s390_libgcc_cmp_return_mode(void)495 s390_libgcc_cmp_return_mode (void)
496 {
497 return TARGET_64BIT ? DImode : SImode;
498 }
499
500 static enum machine_mode
s390_libgcc_shift_count_mode(void)501 s390_libgcc_shift_count_mode (void)
502 {
503 return TARGET_64BIT ? DImode : SImode;
504 }
505
506 static enum machine_mode
s390_unwind_word_mode(void)507 s390_unwind_word_mode (void)
508 {
509 return TARGET_64BIT ? DImode : SImode;
510 }
511
512 /* Return true if the back end supports mode MODE. */
513 static bool
s390_scalar_mode_supported_p(enum machine_mode mode)514 s390_scalar_mode_supported_p (enum machine_mode mode)
515 {
516 /* In contrast to the default implementation reject TImode constants on 31bit
517 TARGET_ZARCH for ABI compliance. */
518 if (!TARGET_64BIT && TARGET_ZARCH && mode == TImode)
519 return false;
520
521 if (DECIMAL_FLOAT_MODE_P (mode))
522 return default_decimal_float_supported_p ();
523
524 return default_scalar_mode_supported_p (mode);
525 }
526
527 /* Set the has_landing_pad_p flag in struct machine_function to VALUE. */
528
529 void
s390_set_has_landing_pad_p(bool value)530 s390_set_has_landing_pad_p (bool value)
531 {
532 cfun->machine->has_landing_pad_p = value;
533 }
534
535 /* If two condition code modes are compatible, return a condition code
536 mode which is compatible with both. Otherwise, return
537 VOIDmode. */
538
539 static enum machine_mode
s390_cc_modes_compatible(enum machine_mode m1,enum machine_mode m2)540 s390_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
541 {
542 if (m1 == m2)
543 return m1;
544
545 switch (m1)
546 {
547 case CCZmode:
548 if (m2 == CCUmode || m2 == CCTmode || m2 == CCZ1mode
549 || m2 == CCSmode || m2 == CCSRmode || m2 == CCURmode)
550 return m2;
551 return VOIDmode;
552
553 case CCSmode:
554 case CCUmode:
555 case CCTmode:
556 case CCSRmode:
557 case CCURmode:
558 case CCZ1mode:
559 if (m2 == CCZmode)
560 return m1;
561
562 return VOIDmode;
563
564 default:
565 return VOIDmode;
566 }
567 return VOIDmode;
568 }
569
570 /* Return true if SET either doesn't set the CC register, or else
571 the source and destination have matching CC modes and that
572 CC mode is at least as constrained as REQ_MODE. */
573
574 static bool
s390_match_ccmode_set(rtx set,enum machine_mode req_mode)575 s390_match_ccmode_set (rtx set, enum machine_mode req_mode)
576 {
577 enum machine_mode set_mode;
578
579 gcc_assert (GET_CODE (set) == SET);
580
581 if (GET_CODE (SET_DEST (set)) != REG || !CC_REGNO_P (REGNO (SET_DEST (set))))
582 return 1;
583
584 set_mode = GET_MODE (SET_DEST (set));
585 switch (set_mode)
586 {
587 case CCSmode:
588 case CCSRmode:
589 case CCUmode:
590 case CCURmode:
591 case CCLmode:
592 case CCL1mode:
593 case CCL2mode:
594 case CCL3mode:
595 case CCT1mode:
596 case CCT2mode:
597 case CCT3mode:
598 if (req_mode != set_mode)
599 return 0;
600 break;
601
602 case CCZmode:
603 if (req_mode != CCSmode && req_mode != CCUmode && req_mode != CCTmode
604 && req_mode != CCSRmode && req_mode != CCURmode)
605 return 0;
606 break;
607
608 case CCAPmode:
609 case CCANmode:
610 if (req_mode != CCAmode)
611 return 0;
612 break;
613
614 default:
615 gcc_unreachable ();
616 }
617
618 return (GET_MODE (SET_SRC (set)) == set_mode);
619 }
620
621 /* Return true if every SET in INSN that sets the CC register
622 has source and destination with matching CC modes and that
623 CC mode is at least as constrained as REQ_MODE.
624 If REQ_MODE is VOIDmode, always return false. */
625
626 bool
s390_match_ccmode(rtx insn,enum machine_mode req_mode)627 s390_match_ccmode (rtx insn, enum machine_mode req_mode)
628 {
629 int i;
630
631 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
632 if (req_mode == VOIDmode)
633 return false;
634
635 if (GET_CODE (PATTERN (insn)) == SET)
636 return s390_match_ccmode_set (PATTERN (insn), req_mode);
637
638 if (GET_CODE (PATTERN (insn)) == PARALLEL)
639 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
640 {
641 rtx set = XVECEXP (PATTERN (insn), 0, i);
642 if (GET_CODE (set) == SET)
643 if (!s390_match_ccmode_set (set, req_mode))
644 return false;
645 }
646
647 return true;
648 }
649
650 /* If a test-under-mask instruction can be used to implement
651 (compare (and ... OP1) OP2), return the CC mode required
652 to do that. Otherwise, return VOIDmode.
653 MIXED is true if the instruction can distinguish between
654 CC1 and CC2 for mixed selected bits (TMxx), it is false
655 if the instruction cannot (TM). */
656
657 enum machine_mode
s390_tm_ccmode(rtx op1,rtx op2,bool mixed)658 s390_tm_ccmode (rtx op1, rtx op2, bool mixed)
659 {
660 int bit0, bit1;
661
662 /* ??? Fixme: should work on CONST_DOUBLE as well. */
663 if (GET_CODE (op1) != CONST_INT || GET_CODE (op2) != CONST_INT)
664 return VOIDmode;
665
666 /* Selected bits all zero: CC0.
667 e.g.: int a; if ((a & (16 + 128)) == 0) */
668 if (INTVAL (op2) == 0)
669 return CCTmode;
670
671 /* Selected bits all one: CC3.
672 e.g.: int a; if ((a & (16 + 128)) == 16 + 128) */
673 if (INTVAL (op2) == INTVAL (op1))
674 return CCT3mode;
675
676 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. e.g.:
677 int a;
678 if ((a & (16 + 128)) == 16) -> CCT1
679 if ((a & (16 + 128)) == 128) -> CCT2 */
680 if (mixed)
681 {
682 bit1 = exact_log2 (INTVAL (op2));
683 bit0 = exact_log2 (INTVAL (op1) ^ INTVAL (op2));
684 if (bit0 != -1 && bit1 != -1)
685 return bit0 > bit1 ? CCT1mode : CCT2mode;
686 }
687
688 return VOIDmode;
689 }
690
691 /* Given a comparison code OP (EQ, NE, etc.) and the operands
692 OP0 and OP1 of a COMPARE, return the mode to be used for the
693 comparison. */
694
695 enum machine_mode
s390_select_ccmode(enum rtx_code code,rtx op0,rtx op1)696 s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
697 {
698 switch (code)
699 {
700 case EQ:
701 case NE:
702 if ((GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
703 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
704 return CCAPmode;
705 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
706 && CONST_OK_FOR_K (INTVAL (XEXP (op0, 1))))
707 return CCAPmode;
708 if ((GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
709 || GET_CODE (op1) == NEG)
710 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
711 return CCLmode;
712
713 if (GET_CODE (op0) == AND)
714 {
715 /* Check whether we can potentially do it via TM. */
716 enum machine_mode ccmode;
717 ccmode = s390_tm_ccmode (XEXP (op0, 1), op1, 1);
718 if (ccmode != VOIDmode)
719 {
720 /* Relax CCTmode to CCZmode to allow fall-back to AND
721 if that turns out to be beneficial. */
722 return ccmode == CCTmode ? CCZmode : ccmode;
723 }
724 }
725
726 if (register_operand (op0, HImode)
727 && GET_CODE (op1) == CONST_INT
728 && (INTVAL (op1) == -1 || INTVAL (op1) == 65535))
729 return CCT3mode;
730 if (register_operand (op0, QImode)
731 && GET_CODE (op1) == CONST_INT
732 && (INTVAL (op1) == -1 || INTVAL (op1) == 255))
733 return CCT3mode;
734
735 return CCZmode;
736
737 case LE:
738 case LT:
739 case GE:
740 case GT:
741 /* The only overflow condition of NEG and ABS happens when
742 -INT_MAX is used as parameter, which stays negative. So
743 we have an overflow from a positive value to a negative.
744 Using CCAP mode the resulting cc can be used for comparisons. */
745 if ((GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
746 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
747 return CCAPmode;
748
749 /* If constants are involved in an add instruction it is possible to use
750 the resulting cc for comparisons with zero. Knowing the sign of the
751 constant the overflow behavior gets predictable. e.g.:
752 int a, b; if ((b = a + c) > 0)
753 with c as a constant value: c < 0 -> CCAN and c >= 0 -> CCAP */
754 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
755 && (CONST_OK_FOR_K (INTVAL (XEXP (op0, 1)))
756 || (CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0, 1)), 'O', "Os")
757 /* Avoid INT32_MIN on 32 bit. */
758 && (!TARGET_ZARCH || INTVAL (XEXP (op0, 1)) != -0x7fffffff - 1))))
759 {
760 if (INTVAL (XEXP((op0), 1)) < 0)
761 return CCANmode;
762 else
763 return CCAPmode;
764 }
765 /* Fall through. */
766 case UNORDERED:
767 case ORDERED:
768 case UNEQ:
769 case UNLE:
770 case UNLT:
771 case UNGE:
772 case UNGT:
773 case LTGT:
774 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
775 && GET_CODE (op1) != CONST_INT)
776 return CCSRmode;
777 return CCSmode;
778
779 case LTU:
780 case GEU:
781 if (GET_CODE (op0) == PLUS
782 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
783 return CCL1mode;
784
785 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
786 && GET_CODE (op1) != CONST_INT)
787 return CCURmode;
788 return CCUmode;
789
790 case LEU:
791 case GTU:
792 if (GET_CODE (op0) == MINUS
793 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
794 return CCL2mode;
795
796 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
797 && GET_CODE (op1) != CONST_INT)
798 return CCURmode;
799 return CCUmode;
800
801 default:
802 gcc_unreachable ();
803 }
804 }
805
806 /* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
807 that we can implement more efficiently. */
808
809 static void
s390_canonicalize_comparison(int * code,rtx * op0,rtx * op1,bool op0_preserve_value)810 s390_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
811 bool op0_preserve_value)
812 {
813 if (op0_preserve_value)
814 return;
815
816 /* Convert ZERO_EXTRACT back to AND to enable TM patterns. */
817 if ((*code == EQ || *code == NE)
818 && *op1 == const0_rtx
819 && GET_CODE (*op0) == ZERO_EXTRACT
820 && GET_CODE (XEXP (*op0, 1)) == CONST_INT
821 && GET_CODE (XEXP (*op0, 2)) == CONST_INT
822 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0, 0))))
823 {
824 rtx inner = XEXP (*op0, 0);
825 HOST_WIDE_INT modesize = GET_MODE_BITSIZE (GET_MODE (inner));
826 HOST_WIDE_INT len = INTVAL (XEXP (*op0, 1));
827 HOST_WIDE_INT pos = INTVAL (XEXP (*op0, 2));
828
829 if (len > 0 && len < modesize
830 && pos >= 0 && pos + len <= modesize
831 && modesize <= HOST_BITS_PER_WIDE_INT)
832 {
833 unsigned HOST_WIDE_INT block;
834 block = ((unsigned HOST_WIDE_INT) 1 << len) - 1;
835 block <<= modesize - pos - len;
836
837 *op0 = gen_rtx_AND (GET_MODE (inner), inner,
838 gen_int_mode (block, GET_MODE (inner)));
839 }
840 }
841
842 /* Narrow AND of memory against immediate to enable TM. */
843 if ((*code == EQ || *code == NE)
844 && *op1 == const0_rtx
845 && GET_CODE (*op0) == AND
846 && GET_CODE (XEXP (*op0, 1)) == CONST_INT
847 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0, 0))))
848 {
849 rtx inner = XEXP (*op0, 0);
850 rtx mask = XEXP (*op0, 1);
851
852 /* Ignore paradoxical SUBREGs if all extra bits are masked out. */
853 if (GET_CODE (inner) == SUBREG
854 && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (inner)))
855 && (GET_MODE_SIZE (GET_MODE (inner))
856 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner))))
857 && ((INTVAL (mask)
858 & GET_MODE_MASK (GET_MODE (inner))
859 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (inner))))
860 == 0))
861 inner = SUBREG_REG (inner);
862
863 /* Do not change volatile MEMs. */
864 if (MEM_P (inner) && !MEM_VOLATILE_P (inner))
865 {
866 int part = s390_single_part (XEXP (*op0, 1),
867 GET_MODE (inner), QImode, 0);
868 if (part >= 0)
869 {
870 mask = gen_int_mode (s390_extract_part (mask, QImode, 0), QImode);
871 inner = adjust_address_nv (inner, QImode, part);
872 *op0 = gen_rtx_AND (QImode, inner, mask);
873 }
874 }
875 }
876
877 /* Narrow comparisons against 0xffff to HImode if possible. */
878 if ((*code == EQ || *code == NE)
879 && GET_CODE (*op1) == CONST_INT
880 && INTVAL (*op1) == 0xffff
881 && SCALAR_INT_MODE_P (GET_MODE (*op0))
882 && (nonzero_bits (*op0, GET_MODE (*op0))
883 & ~(unsigned HOST_WIDE_INT) 0xffff) == 0)
884 {
885 *op0 = gen_lowpart (HImode, *op0);
886 *op1 = constm1_rtx;
887 }
888
889 /* Remove redundant UNSPEC_STRCMPCC_TO_INT conversions if possible. */
890 if (GET_CODE (*op0) == UNSPEC
891 && XINT (*op0, 1) == UNSPEC_STRCMPCC_TO_INT
892 && XVECLEN (*op0, 0) == 1
893 && GET_MODE (XVECEXP (*op0, 0, 0)) == CCUmode
894 && GET_CODE (XVECEXP (*op0, 0, 0)) == REG
895 && REGNO (XVECEXP (*op0, 0, 0)) == CC_REGNUM
896 && *op1 == const0_rtx)
897 {
898 enum rtx_code new_code = UNKNOWN;
899 switch (*code)
900 {
901 case EQ: new_code = EQ; break;
902 case NE: new_code = NE; break;
903 case LT: new_code = GTU; break;
904 case GT: new_code = LTU; break;
905 case LE: new_code = GEU; break;
906 case GE: new_code = LEU; break;
907 default: break;
908 }
909
910 if (new_code != UNKNOWN)
911 {
912 *op0 = XVECEXP (*op0, 0, 0);
913 *code = new_code;
914 }
915 }
916
917 /* Remove redundant UNSPEC_CC_TO_INT conversions if possible. */
918 if (GET_CODE (*op0) == UNSPEC
919 && XINT (*op0, 1) == UNSPEC_CC_TO_INT
920 && XVECLEN (*op0, 0) == 1
921 && GET_CODE (XVECEXP (*op0, 0, 0)) == REG
922 && REGNO (XVECEXP (*op0, 0, 0)) == CC_REGNUM
923 && CONST_INT_P (*op1))
924 {
925 enum rtx_code new_code = UNKNOWN;
926 switch (GET_MODE (XVECEXP (*op0, 0, 0)))
927 {
928 case CCZmode:
929 case CCRAWmode:
930 switch (*code)
931 {
932 case EQ: new_code = EQ; break;
933 case NE: new_code = NE; break;
934 default: break;
935 }
936 break;
937 default: break;
938 }
939
940 if (new_code != UNKNOWN)
941 {
942 /* For CCRAWmode put the required cc mask into the second
943 operand. */
944 if (GET_MODE (XVECEXP (*op0, 0, 0)) == CCRAWmode
945 && INTVAL (*op1) >= 0 && INTVAL (*op1) <= 3)
946 *op1 = gen_rtx_CONST_INT (VOIDmode, 1 << (3 - INTVAL (*op1)));
947 *op0 = XVECEXP (*op0, 0, 0);
948 *code = new_code;
949 }
950 }
951
952 /* Simplify cascaded EQ, NE with const0_rtx. */
953 if ((*code == NE || *code == EQ)
954 && (GET_CODE (*op0) == EQ || GET_CODE (*op0) == NE)
955 && GET_MODE (*op0) == SImode
956 && GET_MODE (XEXP (*op0, 0)) == CCZ1mode
957 && REG_P (XEXP (*op0, 0))
958 && XEXP (*op0, 1) == const0_rtx
959 && *op1 == const0_rtx)
960 {
961 if ((*code == EQ && GET_CODE (*op0) == NE)
962 || (*code == NE && GET_CODE (*op0) == EQ))
963 *code = EQ;
964 else
965 *code = NE;
966 *op0 = XEXP (*op0, 0);
967 }
968
969 /* Prefer register over memory as first operand. */
970 if (MEM_P (*op0) && REG_P (*op1))
971 {
972 rtx tem = *op0; *op0 = *op1; *op1 = tem;
973 *code = (int)swap_condition ((enum rtx_code)*code);
974 }
975 }
976
977 /* Emit a compare instruction suitable to implement the comparison
978 OP0 CODE OP1. Return the correct condition RTL to be placed in
979 the IF_THEN_ELSE of the conditional branch testing the result. */
980
981 rtx
s390_emit_compare(enum rtx_code code,rtx op0,rtx op1)982 s390_emit_compare (enum rtx_code code, rtx op0, rtx op1)
983 {
984 enum machine_mode mode = s390_select_ccmode (code, op0, op1);
985 rtx cc;
986
987 /* Do not output a redundant compare instruction if a compare_and_swap
988 pattern already computed the result and the machine modes are compatible. */
989 if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
990 {
991 gcc_assert (s390_cc_modes_compatible (GET_MODE (op0), mode)
992 == GET_MODE (op0));
993 cc = op0;
994 }
995 else
996 {
997 cc = gen_rtx_REG (mode, CC_REGNUM);
998 emit_insn (gen_rtx_SET (VOIDmode, cc, gen_rtx_COMPARE (mode, op0, op1)));
999 }
1000
1001 return gen_rtx_fmt_ee (code, VOIDmode, cc, const0_rtx);
1002 }
1003
1004 /* Emit a SImode compare and swap instruction setting MEM to NEW_RTX if OLD
1005 matches CMP.
1006 Return the correct condition RTL to be placed in the IF_THEN_ELSE of the
1007 conditional branch testing the result. */
1008
1009 static rtx
s390_emit_compare_and_swap(enum rtx_code code,rtx old,rtx mem,rtx cmp,rtx new_rtx)1010 s390_emit_compare_and_swap (enum rtx_code code, rtx old, rtx mem,
1011 rtx cmp, rtx new_rtx)
1012 {
1013 emit_insn (gen_atomic_compare_and_swapsi_internal (old, mem, cmp, new_rtx));
1014 return s390_emit_compare (code, gen_rtx_REG (CCZ1mode, CC_REGNUM),
1015 const0_rtx);
1016 }
1017
1018 /* Emit a jump instruction to TARGET and return it. If COND is
1019 NULL_RTX, emit an unconditional jump, else a conditional jump under
1020 condition COND. */
1021
1022 rtx
s390_emit_jump(rtx target,rtx cond)1023 s390_emit_jump (rtx target, rtx cond)
1024 {
1025 rtx insn;
1026
1027 target = gen_rtx_LABEL_REF (VOIDmode, target);
1028 if (cond)
1029 target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, target, pc_rtx);
1030
1031 insn = gen_rtx_SET (VOIDmode, pc_rtx, target);
1032 return emit_jump_insn (insn);
1033 }
1034
1035 /* Return branch condition mask to implement a branch
1036 specified by CODE. Return -1 for invalid comparisons. */
1037
1038 int
s390_branch_condition_mask(rtx code)1039 s390_branch_condition_mask (rtx code)
1040 {
1041 const int CC0 = 1 << 3;
1042 const int CC1 = 1 << 2;
1043 const int CC2 = 1 << 1;
1044 const int CC3 = 1 << 0;
1045
1046 gcc_assert (GET_CODE (XEXP (code, 0)) == REG);
1047 gcc_assert (REGNO (XEXP (code, 0)) == CC_REGNUM);
1048 gcc_assert (XEXP (code, 1) == const0_rtx
1049 || (GET_MODE (XEXP (code, 0)) == CCRAWmode
1050 && CONST_INT_P (XEXP (code, 1))));
1051
1052
1053 switch (GET_MODE (XEXP (code, 0)))
1054 {
1055 case CCZmode:
1056 case CCZ1mode:
1057 switch (GET_CODE (code))
1058 {
1059 case EQ: return CC0;
1060 case NE: return CC1 | CC2 | CC3;
1061 default: return -1;
1062 }
1063 break;
1064
1065 case CCT1mode:
1066 switch (GET_CODE (code))
1067 {
1068 case EQ: return CC1;
1069 case NE: return CC0 | CC2 | CC3;
1070 default: return -1;
1071 }
1072 break;
1073
1074 case CCT2mode:
1075 switch (GET_CODE (code))
1076 {
1077 case EQ: return CC2;
1078 case NE: return CC0 | CC1 | CC3;
1079 default: return -1;
1080 }
1081 break;
1082
1083 case CCT3mode:
1084 switch (GET_CODE (code))
1085 {
1086 case EQ: return CC3;
1087 case NE: return CC0 | CC1 | CC2;
1088 default: return -1;
1089 }
1090 break;
1091
1092 case CCLmode:
1093 switch (GET_CODE (code))
1094 {
1095 case EQ: return CC0 | CC2;
1096 case NE: return CC1 | CC3;
1097 default: return -1;
1098 }
1099 break;
1100
1101 case CCL1mode:
1102 switch (GET_CODE (code))
1103 {
1104 case LTU: return CC2 | CC3; /* carry */
1105 case GEU: return CC0 | CC1; /* no carry */
1106 default: return -1;
1107 }
1108 break;
1109
1110 case CCL2mode:
1111 switch (GET_CODE (code))
1112 {
1113 case GTU: return CC0 | CC1; /* borrow */
1114 case LEU: return CC2 | CC3; /* no borrow */
1115 default: return -1;
1116 }
1117 break;
1118
1119 case CCL3mode:
1120 switch (GET_CODE (code))
1121 {
1122 case EQ: return CC0 | CC2;
1123 case NE: return CC1 | CC3;
1124 case LTU: return CC1;
1125 case GTU: return CC3;
1126 case LEU: return CC1 | CC2;
1127 case GEU: return CC2 | CC3;
1128 default: return -1;
1129 }
1130
1131 case CCUmode:
1132 switch (GET_CODE (code))
1133 {
1134 case EQ: return CC0;
1135 case NE: return CC1 | CC2 | CC3;
1136 case LTU: return CC1;
1137 case GTU: return CC2;
1138 case LEU: return CC0 | CC1;
1139 case GEU: return CC0 | CC2;
1140 default: return -1;
1141 }
1142 break;
1143
1144 case CCURmode:
1145 switch (GET_CODE (code))
1146 {
1147 case EQ: return CC0;
1148 case NE: return CC2 | CC1 | CC3;
1149 case LTU: return CC2;
1150 case GTU: return CC1;
1151 case LEU: return CC0 | CC2;
1152 case GEU: return CC0 | CC1;
1153 default: return -1;
1154 }
1155 break;
1156
1157 case CCAPmode:
1158 switch (GET_CODE (code))
1159 {
1160 case EQ: return CC0;
1161 case NE: return CC1 | CC2 | CC3;
1162 case LT: return CC1 | CC3;
1163 case GT: return CC2;
1164 case LE: return CC0 | CC1 | CC3;
1165 case GE: return CC0 | CC2;
1166 default: return -1;
1167 }
1168 break;
1169
1170 case CCANmode:
1171 switch (GET_CODE (code))
1172 {
1173 case EQ: return CC0;
1174 case NE: return CC1 | CC2 | CC3;
1175 case LT: return CC1;
1176 case GT: return CC2 | CC3;
1177 case LE: return CC0 | CC1;
1178 case GE: return CC0 | CC2 | CC3;
1179 default: return -1;
1180 }
1181 break;
1182
1183 case CCSmode:
1184 switch (GET_CODE (code))
1185 {
1186 case EQ: return CC0;
1187 case NE: return CC1 | CC2 | CC3;
1188 case LT: return CC1;
1189 case GT: return CC2;
1190 case LE: return CC0 | CC1;
1191 case GE: return CC0 | CC2;
1192 case UNORDERED: return CC3;
1193 case ORDERED: return CC0 | CC1 | CC2;
1194 case UNEQ: return CC0 | CC3;
1195 case UNLT: return CC1 | CC3;
1196 case UNGT: return CC2 | CC3;
1197 case UNLE: return CC0 | CC1 | CC3;
1198 case UNGE: return CC0 | CC2 | CC3;
1199 case LTGT: return CC1 | CC2;
1200 default: return -1;
1201 }
1202 break;
1203
1204 case CCSRmode:
1205 switch (GET_CODE (code))
1206 {
1207 case EQ: return CC0;
1208 case NE: return CC2 | CC1 | CC3;
1209 case LT: return CC2;
1210 case GT: return CC1;
1211 case LE: return CC0 | CC2;
1212 case GE: return CC0 | CC1;
1213 case UNORDERED: return CC3;
1214 case ORDERED: return CC0 | CC2 | CC1;
1215 case UNEQ: return CC0 | CC3;
1216 case UNLT: return CC2 | CC3;
1217 case UNGT: return CC1 | CC3;
1218 case UNLE: return CC0 | CC2 | CC3;
1219 case UNGE: return CC0 | CC1 | CC3;
1220 case LTGT: return CC2 | CC1;
1221 default: return -1;
1222 }
1223 break;
1224
1225 case CCRAWmode:
1226 switch (GET_CODE (code))
1227 {
1228 case EQ:
1229 return INTVAL (XEXP (code, 1));
1230 case NE:
1231 return (INTVAL (XEXP (code, 1))) ^ 0xf;
1232 default:
1233 gcc_unreachable ();
1234 }
1235
1236 default:
1237 return -1;
1238 }
1239 }
1240
1241
1242 /* Return branch condition mask to implement a compare and branch
1243 specified by CODE. Return -1 for invalid comparisons. */
1244
1245 int
s390_compare_and_branch_condition_mask(rtx code)1246 s390_compare_and_branch_condition_mask (rtx code)
1247 {
1248 const int CC0 = 1 << 3;
1249 const int CC1 = 1 << 2;
1250 const int CC2 = 1 << 1;
1251
1252 switch (GET_CODE (code))
1253 {
1254 case EQ:
1255 return CC0;
1256 case NE:
1257 return CC1 | CC2;
1258 case LT:
1259 case LTU:
1260 return CC1;
1261 case GT:
1262 case GTU:
1263 return CC2;
1264 case LE:
1265 case LEU:
1266 return CC0 | CC1;
1267 case GE:
1268 case GEU:
1269 return CC0 | CC2;
1270 default:
1271 gcc_unreachable ();
1272 }
1273 return -1;
1274 }
1275
1276 /* If INV is false, return assembler mnemonic string to implement
1277 a branch specified by CODE. If INV is true, return mnemonic
1278 for the corresponding inverted branch. */
1279
1280 static const char *
s390_branch_condition_mnemonic(rtx code,int inv)1281 s390_branch_condition_mnemonic (rtx code, int inv)
1282 {
1283 int mask;
1284
1285 static const char *const mnemonic[16] =
1286 {
1287 NULL, "o", "h", "nle",
1288 "l", "nhe", "lh", "ne",
1289 "e", "nlh", "he", "nl",
1290 "le", "nh", "no", NULL
1291 };
1292
1293 if (GET_CODE (XEXP (code, 0)) == REG
1294 && REGNO (XEXP (code, 0)) == CC_REGNUM
1295 && (XEXP (code, 1) == const0_rtx
1296 || (GET_MODE (XEXP (code, 0)) == CCRAWmode
1297 && CONST_INT_P (XEXP (code, 1)))))
1298 mask = s390_branch_condition_mask (code);
1299 else
1300 mask = s390_compare_and_branch_condition_mask (code);
1301
1302 gcc_assert (mask >= 0);
1303
1304 if (inv)
1305 mask ^= 15;
1306
1307 gcc_assert (mask >= 1 && mask <= 14);
1308
1309 return mnemonic[mask];
1310 }
1311
1312 /* Return the part of op which has a value different from def.
1313 The size of the part is determined by mode.
1314 Use this function only if you already know that op really
1315 contains such a part. */
1316
1317 unsigned HOST_WIDE_INT
s390_extract_part(rtx op,enum machine_mode mode,int def)1318 s390_extract_part (rtx op, enum machine_mode mode, int def)
1319 {
1320 unsigned HOST_WIDE_INT value = 0;
1321 int max_parts = HOST_BITS_PER_WIDE_INT / GET_MODE_BITSIZE (mode);
1322 int part_bits = GET_MODE_BITSIZE (mode);
1323 unsigned HOST_WIDE_INT part_mask
1324 = ((unsigned HOST_WIDE_INT)1 << part_bits) - 1;
1325 int i;
1326
1327 for (i = 0; i < max_parts; i++)
1328 {
1329 if (i == 0)
1330 value = (unsigned HOST_WIDE_INT) INTVAL (op);
1331 else
1332 value >>= part_bits;
1333
1334 if ((value & part_mask) != (def & part_mask))
1335 return value & part_mask;
1336 }
1337
1338 gcc_unreachable ();
1339 }
1340
1341 /* If OP is an integer constant of mode MODE with exactly one
1342 part of mode PART_MODE unequal to DEF, return the number of that
1343 part. Otherwise, return -1. */
1344
1345 int
s390_single_part(rtx op,enum machine_mode mode,enum machine_mode part_mode,int def)1346 s390_single_part (rtx op,
1347 enum machine_mode mode,
1348 enum machine_mode part_mode,
1349 int def)
1350 {
1351 unsigned HOST_WIDE_INT value = 0;
1352 int n_parts = GET_MODE_SIZE (mode) / GET_MODE_SIZE (part_mode);
1353 unsigned HOST_WIDE_INT part_mask
1354 = ((unsigned HOST_WIDE_INT)1 << GET_MODE_BITSIZE (part_mode)) - 1;
1355 int i, part = -1;
1356
1357 if (GET_CODE (op) != CONST_INT)
1358 return -1;
1359
1360 for (i = 0; i < n_parts; i++)
1361 {
1362 if (i == 0)
1363 value = (unsigned HOST_WIDE_INT) INTVAL (op);
1364 else
1365 value >>= GET_MODE_BITSIZE (part_mode);
1366
1367 if ((value & part_mask) != (def & part_mask))
1368 {
1369 if (part != -1)
1370 return -1;
1371 else
1372 part = i;
1373 }
1374 }
1375 return part == -1 ? -1 : n_parts - 1 - part;
1376 }
1377
1378 /* Return true if IN contains a contiguous bitfield in the lower SIZE
1379 bits and no other bits are set in IN. POS and LENGTH can be used
1380 to obtain the start position and the length of the bitfield.
1381
1382 POS gives the position of the first bit of the bitfield counting
1383 from the lowest order bit starting with zero. In order to use this
1384 value for S/390 instructions this has to be converted to "bits big
1385 endian" style. */
1386
1387 bool
s390_contiguous_bitmask_p(unsigned HOST_WIDE_INT in,int size,int * pos,int * length)1388 s390_contiguous_bitmask_p (unsigned HOST_WIDE_INT in, int size,
1389 int *pos, int *length)
1390 {
1391 int tmp_pos = 0;
1392 int tmp_length = 0;
1393 int i;
1394 unsigned HOST_WIDE_INT mask = 1ULL;
1395 bool contiguous = false;
1396
1397 for (i = 0; i < size; mask <<= 1, i++)
1398 {
1399 if (contiguous)
1400 {
1401 if (mask & in)
1402 tmp_length++;
1403 else
1404 break;
1405 }
1406 else
1407 {
1408 if (mask & in)
1409 {
1410 contiguous = true;
1411 tmp_length++;
1412 }
1413 else
1414 tmp_pos++;
1415 }
1416 }
1417
1418 if (!tmp_length)
1419 return false;
1420
1421 /* Calculate a mask for all bits beyond the contiguous bits. */
1422 mask = (-1LL & ~(((1ULL << (tmp_length + tmp_pos - 1)) << 1) - 1));
1423
1424 if (mask & in)
1425 return false;
1426
1427 if (tmp_length + tmp_pos - 1 > size)
1428 return false;
1429
1430 if (length)
1431 *length = tmp_length;
1432
1433 if (pos)
1434 *pos = tmp_pos;
1435
1436 return true;
1437 }
1438
1439 /* Check whether a rotate of ROTL followed by an AND of CONTIG is
1440 equivalent to a shift followed by the AND. In particular, CONTIG
1441 should not overlap the (rotated) bit 0/bit 63 gap. Negative values
1442 for ROTL indicate a rotate to the right. */
1443
1444 bool
s390_extzv_shift_ok(int bitsize,int rotl,unsigned HOST_WIDE_INT contig)1445 s390_extzv_shift_ok (int bitsize, int rotl, unsigned HOST_WIDE_INT contig)
1446 {
1447 int pos, len;
1448 bool ok;
1449
1450 ok = s390_contiguous_bitmask_p (contig, bitsize, &pos, &len);
1451 gcc_assert (ok);
1452
1453 return ((rotl >= 0 && rotl <= pos)
1454 || (rotl < 0 && -rotl <= bitsize - len - pos));
1455 }
1456
1457 /* Check whether we can (and want to) split a double-word
1458 move in mode MODE from SRC to DST into two single-word
1459 moves, moving the subword FIRST_SUBWORD first. */
1460
1461 bool
s390_split_ok_p(rtx dst,rtx src,enum machine_mode mode,int first_subword)1462 s390_split_ok_p (rtx dst, rtx src, enum machine_mode mode, int first_subword)
1463 {
1464 /* Floating point registers cannot be split. */
1465 if (FP_REG_P (src) || FP_REG_P (dst))
1466 return false;
1467
1468 /* We don't need to split if operands are directly accessible. */
1469 if (s_operand (src, mode) || s_operand (dst, mode))
1470 return false;
1471
1472 /* Non-offsettable memory references cannot be split. */
1473 if ((GET_CODE (src) == MEM && !offsettable_memref_p (src))
1474 || (GET_CODE (dst) == MEM && !offsettable_memref_p (dst)))
1475 return false;
1476
1477 /* Moving the first subword must not clobber a register
1478 needed to move the second subword. */
1479 if (register_operand (dst, mode))
1480 {
1481 rtx subreg = operand_subword (dst, first_subword, 0, mode);
1482 if (reg_overlap_mentioned_p (subreg, src))
1483 return false;
1484 }
1485
1486 return true;
1487 }
1488
1489 /* Return true if it can be proven that [MEM1, MEM1 + SIZE]
1490 and [MEM2, MEM2 + SIZE] do overlap and false
1491 otherwise. */
1492
1493 bool
s390_overlap_p(rtx mem1,rtx mem2,HOST_WIDE_INT size)1494 s390_overlap_p (rtx mem1, rtx mem2, HOST_WIDE_INT size)
1495 {
1496 rtx addr1, addr2, addr_delta;
1497 HOST_WIDE_INT delta;
1498
1499 if (GET_CODE (mem1) != MEM || GET_CODE (mem2) != MEM)
1500 return true;
1501
1502 if (size == 0)
1503 return false;
1504
1505 addr1 = XEXP (mem1, 0);
1506 addr2 = XEXP (mem2, 0);
1507
1508 addr_delta = simplify_binary_operation (MINUS, Pmode, addr2, addr1);
1509
1510 /* This overlapping check is used by peepholes merging memory block operations.
1511 Overlapping operations would otherwise be recognized by the S/390 hardware
1512 and would fall back to a slower implementation. Allowing overlapping
1513 operations would lead to slow code but not to wrong code. Therefore we are
1514 somewhat optimistic if we cannot prove that the memory blocks are
1515 overlapping.
1516 That's why we return false here although this may accept operations on
1517 overlapping memory areas. */
1518 if (!addr_delta || GET_CODE (addr_delta) != CONST_INT)
1519 return false;
1520
1521 delta = INTVAL (addr_delta);
1522
1523 if (delta == 0
1524 || (delta > 0 && delta < size)
1525 || (delta < 0 && -delta < size))
1526 return true;
1527
1528 return false;
1529 }
1530
1531 /* Check whether the address of memory reference MEM2 equals exactly
1532 the address of memory reference MEM1 plus DELTA. Return true if
1533 we can prove this to be the case, false otherwise. */
1534
1535 bool
s390_offset_p(rtx mem1,rtx mem2,rtx delta)1536 s390_offset_p (rtx mem1, rtx mem2, rtx delta)
1537 {
1538 rtx addr1, addr2, addr_delta;
1539
1540 if (GET_CODE (mem1) != MEM || GET_CODE (mem2) != MEM)
1541 return false;
1542
1543 addr1 = XEXP (mem1, 0);
1544 addr2 = XEXP (mem2, 0);
1545
1546 addr_delta = simplify_binary_operation (MINUS, Pmode, addr2, addr1);
1547 if (!addr_delta || !rtx_equal_p (addr_delta, delta))
1548 return false;
1549
1550 return true;
1551 }
1552
1553 /* Expand logical operator CODE in mode MODE with operands OPERANDS. */
1554
1555 void
s390_expand_logical_operator(enum rtx_code code,enum machine_mode mode,rtx * operands)1556 s390_expand_logical_operator (enum rtx_code code, enum machine_mode mode,
1557 rtx *operands)
1558 {
1559 enum machine_mode wmode = mode;
1560 rtx dst = operands[0];
1561 rtx src1 = operands[1];
1562 rtx src2 = operands[2];
1563 rtx op, clob, tem;
1564
1565 /* If we cannot handle the operation directly, use a temp register. */
1566 if (!s390_logical_operator_ok_p (operands))
1567 dst = gen_reg_rtx (mode);
1568
1569 /* QImode and HImode patterns make sense only if we have a destination
1570 in memory. Otherwise perform the operation in SImode. */
1571 if ((mode == QImode || mode == HImode) && GET_CODE (dst) != MEM)
1572 wmode = SImode;
1573
1574 /* Widen operands if required. */
1575 if (mode != wmode)
1576 {
1577 if (GET_CODE (dst) == SUBREG
1578 && (tem = simplify_subreg (wmode, dst, mode, 0)) != 0)
1579 dst = tem;
1580 else if (REG_P (dst))
1581 dst = gen_rtx_SUBREG (wmode, dst, 0);
1582 else
1583 dst = gen_reg_rtx (wmode);
1584
1585 if (GET_CODE (src1) == SUBREG
1586 && (tem = simplify_subreg (wmode, src1, mode, 0)) != 0)
1587 src1 = tem;
1588 else if (GET_MODE (src1) != VOIDmode)
1589 src1 = gen_rtx_SUBREG (wmode, force_reg (mode, src1), 0);
1590
1591 if (GET_CODE (src2) == SUBREG
1592 && (tem = simplify_subreg (wmode, src2, mode, 0)) != 0)
1593 src2 = tem;
1594 else if (GET_MODE (src2) != VOIDmode)
1595 src2 = gen_rtx_SUBREG (wmode, force_reg (mode, src2), 0);
1596 }
1597
1598 /* Emit the instruction. */
1599 op = gen_rtx_SET (VOIDmode, dst, gen_rtx_fmt_ee (code, wmode, src1, src2));
1600 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
1601 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
1602
1603 /* Fix up the destination if needed. */
1604 if (dst != operands[0])
1605 emit_move_insn (operands[0], gen_lowpart (mode, dst));
1606 }
1607
1608 /* Check whether OPERANDS are OK for a logical operation (AND, IOR, XOR). */
1609
1610 bool
s390_logical_operator_ok_p(rtx * operands)1611 s390_logical_operator_ok_p (rtx *operands)
1612 {
1613 /* If the destination operand is in memory, it needs to coincide
1614 with one of the source operands. After reload, it has to be
1615 the first source operand. */
1616 if (GET_CODE (operands[0]) == MEM)
1617 return rtx_equal_p (operands[0], operands[1])
1618 || (!reload_completed && rtx_equal_p (operands[0], operands[2]));
1619
1620 return true;
1621 }
1622
1623 /* Narrow logical operation CODE of memory operand MEMOP with immediate
1624 operand IMMOP to switch from SS to SI type instructions. */
1625
1626 void
s390_narrow_logical_operator(enum rtx_code code,rtx * memop,rtx * immop)1627 s390_narrow_logical_operator (enum rtx_code code, rtx *memop, rtx *immop)
1628 {
1629 int def = code == AND ? -1 : 0;
1630 HOST_WIDE_INT mask;
1631 int part;
1632
1633 gcc_assert (GET_CODE (*memop) == MEM);
1634 gcc_assert (!MEM_VOLATILE_P (*memop));
1635
1636 mask = s390_extract_part (*immop, QImode, def);
1637 part = s390_single_part (*immop, GET_MODE (*memop), QImode, def);
1638 gcc_assert (part >= 0);
1639
1640 *memop = adjust_address (*memop, QImode, part);
1641 *immop = gen_int_mode (mask, QImode);
1642 }
1643
1644
1645 /* How to allocate a 'struct machine_function'. */
1646
1647 static struct machine_function *
s390_init_machine_status(void)1648 s390_init_machine_status (void)
1649 {
1650 return ggc_alloc_cleared_machine_function ();
1651 }
1652
1653 static void
s390_option_override(void)1654 s390_option_override (void)
1655 {
1656 unsigned int i;
1657 cl_deferred_option *opt;
1658 vec<cl_deferred_option> *v =
1659 (vec<cl_deferred_option> *) s390_deferred_options;
1660
1661 if (v)
1662 FOR_EACH_VEC_ELT (*v, i, opt)
1663 {
1664 switch (opt->opt_index)
1665 {
1666 case OPT_mhotpatch_:
1667 {
1668 int val1;
1669 int val2;
1670 char s[256];
1671 char *t;
1672
1673 strncpy (s, opt->arg, 256);
1674 s[255] = 0;
1675 t = strchr (s, ',');
1676 if (t != NULL)
1677 {
1678 *t = 0;
1679 t++;
1680 val1 = integral_argument (s);
1681 val2 = integral_argument (t);
1682 }
1683 else
1684 {
1685 val1 = -1;
1686 val2 = -1;
1687 }
1688 if (val1 == -1 || val2 == -1)
1689 {
1690 /* argument is not a plain number */
1691 error ("arguments to %qs should be non-negative integers",
1692 "-mhotpatch=n,m");
1693 break;
1694 }
1695 else if (val1 > s390_hotpatch_hw_max
1696 || val2 > s390_hotpatch_hw_max)
1697 {
1698 error ("argument to %qs is too large (max. %d)",
1699 "-mhotpatch=n,m", s390_hotpatch_hw_max);
1700 break;
1701 }
1702 s390_hotpatch_hw_before_label = val1;
1703 s390_hotpatch_hw_after_label = val2;
1704 break;
1705 }
1706 default:
1707 gcc_unreachable ();
1708 }
1709 }
1710
1711 /* Set up function hooks. */
1712 init_machine_status = s390_init_machine_status;
1713
1714 /* Architecture mode defaults according to ABI. */
1715 if (!(target_flags_explicit & MASK_ZARCH))
1716 {
1717 if (TARGET_64BIT)
1718 target_flags |= MASK_ZARCH;
1719 else
1720 target_flags &= ~MASK_ZARCH;
1721 }
1722
1723 /* Set the march default in case it hasn't been specified on
1724 cmdline. */
1725 if (s390_arch == PROCESSOR_max)
1726 {
1727 s390_arch_string = TARGET_ZARCH? "z900" : "g5";
1728 s390_arch = TARGET_ZARCH ? PROCESSOR_2064_Z900 : PROCESSOR_9672_G5;
1729 s390_arch_flags = processor_flags_table[(int)s390_arch];
1730 }
1731
1732 /* Determine processor to tune for. */
1733 if (s390_tune == PROCESSOR_max)
1734 {
1735 s390_tune = s390_arch;
1736 s390_tune_flags = s390_arch_flags;
1737 }
1738
1739 /* Sanity checks. */
1740 if (TARGET_ZARCH && !TARGET_CPU_ZARCH)
1741 error ("z/Architecture mode not supported on %s", s390_arch_string);
1742 if (TARGET_64BIT && !TARGET_ZARCH)
1743 error ("64-bit ABI not supported in ESA/390 mode");
1744
1745 /* Use hardware DFP if available and not explicitly disabled by
1746 user. E.g. with -m31 -march=z10 -mzarch */
1747 if (!(target_flags_explicit & MASK_HARD_DFP) && TARGET_DFP)
1748 target_flags |= MASK_HARD_DFP;
1749
1750 /* Enable hardware transactions if available and not explicitly
1751 disabled by user. E.g. with -m31 -march=zEC12 -mzarch */
1752 if (!(target_flags_explicit & MASK_OPT_HTM) && TARGET_CPU_HTM && TARGET_ZARCH)
1753 target_flags |= MASK_OPT_HTM;
1754
1755 if (TARGET_HARD_DFP && !TARGET_DFP)
1756 {
1757 if (target_flags_explicit & MASK_HARD_DFP)
1758 {
1759 if (!TARGET_CPU_DFP)
1760 error ("hardware decimal floating point instructions"
1761 " not available on %s", s390_arch_string);
1762 if (!TARGET_ZARCH)
1763 error ("hardware decimal floating point instructions"
1764 " not available in ESA/390 mode");
1765 }
1766 else
1767 target_flags &= ~MASK_HARD_DFP;
1768 }
1769
1770 if ((target_flags_explicit & MASK_SOFT_FLOAT) && TARGET_SOFT_FLOAT)
1771 {
1772 if ((target_flags_explicit & MASK_HARD_DFP) && TARGET_HARD_DFP)
1773 error ("-mhard-dfp can%'t be used in conjunction with -msoft-float");
1774
1775 target_flags &= ~MASK_HARD_DFP;
1776 }
1777
1778 /* Set processor cost function. */
1779 switch (s390_tune)
1780 {
1781 case PROCESSOR_2084_Z990:
1782 s390_cost = &z990_cost;
1783 break;
1784 case PROCESSOR_2094_Z9_109:
1785 s390_cost = &z9_109_cost;
1786 break;
1787 case PROCESSOR_2097_Z10:
1788 s390_cost = &z10_cost;
1789 break;
1790 case PROCESSOR_2817_Z196:
1791 s390_cost = &z196_cost;
1792 break;
1793 case PROCESSOR_2827_ZEC12:
1794 s390_cost = &zEC12_cost;
1795 break;
1796 default:
1797 s390_cost = &z900_cost;
1798 }
1799
1800 if (TARGET_BACKCHAIN && TARGET_PACKED_STACK && TARGET_HARD_FLOAT)
1801 error ("-mbackchain -mpacked-stack -mhard-float are not supported "
1802 "in combination");
1803
1804 if (s390_stack_size)
1805 {
1806 if (s390_stack_guard >= s390_stack_size)
1807 error ("stack size must be greater than the stack guard value");
1808 else if (s390_stack_size > 1 << 16)
1809 error ("stack size must not be greater than 64k");
1810 }
1811 else if (s390_stack_guard)
1812 error ("-mstack-guard implies use of -mstack-size");
1813
1814 #ifdef TARGET_DEFAULT_LONG_DOUBLE_128
1815 if (!(target_flags_explicit & MASK_LONG_DOUBLE_128))
1816 target_flags |= MASK_LONG_DOUBLE_128;
1817 #endif
1818
1819 if (s390_tune == PROCESSOR_2097_Z10
1820 || s390_tune == PROCESSOR_2817_Z196
1821 || s390_tune == PROCESSOR_2827_ZEC12)
1822 {
1823 maybe_set_param_value (PARAM_MAX_UNROLLED_INSNS, 100,
1824 global_options.x_param_values,
1825 global_options_set.x_param_values);
1826 maybe_set_param_value (PARAM_MAX_UNROLL_TIMES, 32,
1827 global_options.x_param_values,
1828 global_options_set.x_param_values);
1829 maybe_set_param_value (PARAM_MAX_COMPLETELY_PEELED_INSNS, 2000,
1830 global_options.x_param_values,
1831 global_options_set.x_param_values);
1832 maybe_set_param_value (PARAM_MAX_COMPLETELY_PEEL_TIMES, 64,
1833 global_options.x_param_values,
1834 global_options_set.x_param_values);
1835 }
1836
1837 maybe_set_param_value (PARAM_MAX_PENDING_LIST_LENGTH, 256,
1838 global_options.x_param_values,
1839 global_options_set.x_param_values);
1840 /* values for loop prefetching */
1841 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE, 256,
1842 global_options.x_param_values,
1843 global_options_set.x_param_values);
1844 maybe_set_param_value (PARAM_L1_CACHE_SIZE, 128,
1845 global_options.x_param_values,
1846 global_options_set.x_param_values);
1847 /* s390 has more than 2 levels and the size is much larger. Since
1848 we are always running virtualized assume that we only get a small
1849 part of the caches above l1. */
1850 maybe_set_param_value (PARAM_L2_CACHE_SIZE, 1500,
1851 global_options.x_param_values,
1852 global_options_set.x_param_values);
1853 maybe_set_param_value (PARAM_PREFETCH_MIN_INSN_TO_MEM_RATIO, 2,
1854 global_options.x_param_values,
1855 global_options_set.x_param_values);
1856 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES, 6,
1857 global_options.x_param_values,
1858 global_options_set.x_param_values);
1859
1860 /* This cannot reside in s390_option_optimization_table since HAVE_prefetch
1861 requires the arch flags to be evaluated already. Since prefetching
1862 is beneficial on s390, we enable it if available. */
1863 if (flag_prefetch_loop_arrays < 0 && HAVE_prefetch && optimize >= 3)
1864 flag_prefetch_loop_arrays = 1;
1865
1866 /* Use the alternative scheduling-pressure algorithm by default. */
1867 maybe_set_param_value (PARAM_SCHED_PRESSURE_ALGORITHM, 2,
1868 global_options.x_param_values,
1869 global_options_set.x_param_values);
1870
1871 if (TARGET_TPF)
1872 {
1873 /* Don't emit DWARF3/4 unless specifically selected. The TPF
1874 debuggers do not yet support DWARF 3/4. */
1875 if (!global_options_set.x_dwarf_strict)
1876 dwarf_strict = 1;
1877 if (!global_options_set.x_dwarf_version)
1878 dwarf_version = 2;
1879 }
1880 }
1881
1882 /* Map for smallest class containing reg regno. */
1883
1884 const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
1885 { GENERAL_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1886 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1887 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1888 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1889 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1890 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1891 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1892 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1893 ADDR_REGS, CC_REGS, ADDR_REGS, ADDR_REGS,
1894 ACCESS_REGS, ACCESS_REGS
1895 };
1896
1897 /* Return attribute type of insn. */
1898
1899 static enum attr_type
s390_safe_attr_type(rtx insn)1900 s390_safe_attr_type (rtx insn)
1901 {
1902 if (recog_memoized (insn) >= 0)
1903 return get_attr_type (insn);
1904 else
1905 return TYPE_NONE;
1906 }
1907
1908 /* Return true if DISP is a valid short displacement. */
1909
1910 static bool
s390_short_displacement(rtx disp)1911 s390_short_displacement (rtx disp)
1912 {
1913 /* No displacement is OK. */
1914 if (!disp)
1915 return true;
1916
1917 /* Without the long displacement facility we don't need to
1918 distingiush between long and short displacement. */
1919 if (!TARGET_LONG_DISPLACEMENT)
1920 return true;
1921
1922 /* Integer displacement in range. */
1923 if (GET_CODE (disp) == CONST_INT)
1924 return INTVAL (disp) >= 0 && INTVAL (disp) < 4096;
1925
1926 /* GOT offset is not OK, the GOT can be large. */
1927 if (GET_CODE (disp) == CONST
1928 && GET_CODE (XEXP (disp, 0)) == UNSPEC
1929 && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOT
1930 || XINT (XEXP (disp, 0), 1) == UNSPEC_GOTNTPOFF))
1931 return false;
1932
1933 /* All other symbolic constants are literal pool references,
1934 which are OK as the literal pool must be small. */
1935 if (GET_CODE (disp) == CONST)
1936 return true;
1937
1938 return false;
1939 }
1940
1941 /* Decompose a RTL expression ADDR for a memory address into
1942 its components, returned in OUT.
1943
1944 Returns false if ADDR is not a valid memory address, true
1945 otherwise. If OUT is NULL, don't return the components,
1946 but check for validity only.
1947
1948 Note: Only addresses in canonical form are recognized.
1949 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
1950 canonical form so that they will be recognized. */
1951
1952 static int
s390_decompose_address(rtx addr,struct s390_address * out)1953 s390_decompose_address (rtx addr, struct s390_address *out)
1954 {
1955 HOST_WIDE_INT offset = 0;
1956 rtx base = NULL_RTX;
1957 rtx indx = NULL_RTX;
1958 rtx disp = NULL_RTX;
1959 rtx orig_disp;
1960 bool pointer = false;
1961 bool base_ptr = false;
1962 bool indx_ptr = false;
1963 bool literal_pool = false;
1964
1965 /* We may need to substitute the literal pool base register into the address
1966 below. However, at this point we do not know which register is going to
1967 be used as base, so we substitute the arg pointer register. This is going
1968 to be treated as holding a pointer below -- it shouldn't be used for any
1969 other purpose. */
1970 rtx fake_pool_base = gen_rtx_REG (Pmode, ARG_POINTER_REGNUM);
1971
1972 /* Decompose address into base + index + displacement. */
1973
1974 if (GET_CODE (addr) == REG || GET_CODE (addr) == UNSPEC)
1975 base = addr;
1976
1977 else if (GET_CODE (addr) == PLUS)
1978 {
1979 rtx op0 = XEXP (addr, 0);
1980 rtx op1 = XEXP (addr, 1);
1981 enum rtx_code code0 = GET_CODE (op0);
1982 enum rtx_code code1 = GET_CODE (op1);
1983
1984 if (code0 == REG || code0 == UNSPEC)
1985 {
1986 if (code1 == REG || code1 == UNSPEC)
1987 {
1988 indx = op0; /* index + base */
1989 base = op1;
1990 }
1991
1992 else
1993 {
1994 base = op0; /* base + displacement */
1995 disp = op1;
1996 }
1997 }
1998
1999 else if (code0 == PLUS)
2000 {
2001 indx = XEXP (op0, 0); /* index + base + disp */
2002 base = XEXP (op0, 1);
2003 disp = op1;
2004 }
2005
2006 else
2007 {
2008 return false;
2009 }
2010 }
2011
2012 else
2013 disp = addr; /* displacement */
2014
2015 /* Extract integer part of displacement. */
2016 orig_disp = disp;
2017 if (disp)
2018 {
2019 if (GET_CODE (disp) == CONST_INT)
2020 {
2021 offset = INTVAL (disp);
2022 disp = NULL_RTX;
2023 }
2024 else if (GET_CODE (disp) == CONST
2025 && GET_CODE (XEXP (disp, 0)) == PLUS
2026 && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT)
2027 {
2028 offset = INTVAL (XEXP (XEXP (disp, 0), 1));
2029 disp = XEXP (XEXP (disp, 0), 0);
2030 }
2031 }
2032
2033 /* Strip off CONST here to avoid special case tests later. */
2034 if (disp && GET_CODE (disp) == CONST)
2035 disp = XEXP (disp, 0);
2036
2037 /* We can convert literal pool addresses to
2038 displacements by basing them off the base register. */
2039 if (disp && GET_CODE (disp) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (disp))
2040 {
2041 /* Either base or index must be free to hold the base register. */
2042 if (!base)
2043 base = fake_pool_base, literal_pool = true;
2044 else if (!indx)
2045 indx = fake_pool_base, literal_pool = true;
2046 else
2047 return false;
2048
2049 /* Mark up the displacement. */
2050 disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp),
2051 UNSPEC_LTREL_OFFSET);
2052 }
2053
2054 /* Validate base register. */
2055 if (base)
2056 {
2057 if (GET_CODE (base) == UNSPEC)
2058 switch (XINT (base, 1))
2059 {
2060 case UNSPEC_LTREF:
2061 if (!disp)
2062 disp = gen_rtx_UNSPEC (Pmode,
2063 gen_rtvec (1, XVECEXP (base, 0, 0)),
2064 UNSPEC_LTREL_OFFSET);
2065 else
2066 return false;
2067
2068 base = XVECEXP (base, 0, 1);
2069 break;
2070
2071 case UNSPEC_LTREL_BASE:
2072 if (XVECLEN (base, 0) == 1)
2073 base = fake_pool_base, literal_pool = true;
2074 else
2075 base = XVECEXP (base, 0, 1);
2076 break;
2077
2078 default:
2079 return false;
2080 }
2081
2082 if (!REG_P (base)
2083 || (GET_MODE (base) != SImode
2084 && GET_MODE (base) != Pmode))
2085 return false;
2086
2087 if (REGNO (base) == STACK_POINTER_REGNUM
2088 || REGNO (base) == FRAME_POINTER_REGNUM
2089 || ((reload_completed || reload_in_progress)
2090 && frame_pointer_needed
2091 && REGNO (base) == HARD_FRAME_POINTER_REGNUM)
2092 || REGNO (base) == ARG_POINTER_REGNUM
2093 || (flag_pic
2094 && REGNO (base) == PIC_OFFSET_TABLE_REGNUM))
2095 pointer = base_ptr = true;
2096
2097 if ((reload_completed || reload_in_progress)
2098 && base == cfun->machine->base_reg)
2099 pointer = base_ptr = literal_pool = true;
2100 }
2101
2102 /* Validate index register. */
2103 if (indx)
2104 {
2105 if (GET_CODE (indx) == UNSPEC)
2106 switch (XINT (indx, 1))
2107 {
2108 case UNSPEC_LTREF:
2109 if (!disp)
2110 disp = gen_rtx_UNSPEC (Pmode,
2111 gen_rtvec (1, XVECEXP (indx, 0, 0)),
2112 UNSPEC_LTREL_OFFSET);
2113 else
2114 return false;
2115
2116 indx = XVECEXP (indx, 0, 1);
2117 break;
2118
2119 case UNSPEC_LTREL_BASE:
2120 if (XVECLEN (indx, 0) == 1)
2121 indx = fake_pool_base, literal_pool = true;
2122 else
2123 indx = XVECEXP (indx, 0, 1);
2124 break;
2125
2126 default:
2127 return false;
2128 }
2129
2130 if (!REG_P (indx)
2131 || (GET_MODE (indx) != SImode
2132 && GET_MODE (indx) != Pmode))
2133 return false;
2134
2135 if (REGNO (indx) == STACK_POINTER_REGNUM
2136 || REGNO (indx) == FRAME_POINTER_REGNUM
2137 || ((reload_completed || reload_in_progress)
2138 && frame_pointer_needed
2139 && REGNO (indx) == HARD_FRAME_POINTER_REGNUM)
2140 || REGNO (indx) == ARG_POINTER_REGNUM
2141 || (flag_pic
2142 && REGNO (indx) == PIC_OFFSET_TABLE_REGNUM))
2143 pointer = indx_ptr = true;
2144
2145 if ((reload_completed || reload_in_progress)
2146 && indx == cfun->machine->base_reg)
2147 pointer = indx_ptr = literal_pool = true;
2148 }
2149
2150 /* Prefer to use pointer as base, not index. */
2151 if (base && indx && !base_ptr
2152 && (indx_ptr || (!REG_POINTER (base) && REG_POINTER (indx))))
2153 {
2154 rtx tmp = base;
2155 base = indx;
2156 indx = tmp;
2157 }
2158
2159 /* Validate displacement. */
2160 if (!disp)
2161 {
2162 /* If virtual registers are involved, the displacement will change later
2163 anyway as the virtual registers get eliminated. This could make a
2164 valid displacement invalid, but it is more likely to make an invalid
2165 displacement valid, because we sometimes access the register save area
2166 via negative offsets to one of those registers.
2167 Thus we don't check the displacement for validity here. If after
2168 elimination the displacement turns out to be invalid after all,
2169 this is fixed up by reload in any case. */
2170 if (base != arg_pointer_rtx
2171 && indx != arg_pointer_rtx
2172 && base != return_address_pointer_rtx
2173 && indx != return_address_pointer_rtx
2174 && base != frame_pointer_rtx
2175 && indx != frame_pointer_rtx
2176 && base != virtual_stack_vars_rtx
2177 && indx != virtual_stack_vars_rtx)
2178 if (!DISP_IN_RANGE (offset))
2179 return false;
2180 }
2181 else
2182 {
2183 /* All the special cases are pointers. */
2184 pointer = true;
2185
2186 /* In the small-PIC case, the linker converts @GOT
2187 and @GOTNTPOFF offsets to possible displacements. */
2188 if (GET_CODE (disp) == UNSPEC
2189 && (XINT (disp, 1) == UNSPEC_GOT
2190 || XINT (disp, 1) == UNSPEC_GOTNTPOFF)
2191 && flag_pic == 1)
2192 {
2193 ;
2194 }
2195
2196 /* Accept pool label offsets. */
2197 else if (GET_CODE (disp) == UNSPEC
2198 && XINT (disp, 1) == UNSPEC_POOL_OFFSET)
2199 ;
2200
2201 /* Accept literal pool references. */
2202 else if (GET_CODE (disp) == UNSPEC
2203 && XINT (disp, 1) == UNSPEC_LTREL_OFFSET)
2204 {
2205 /* In case CSE pulled a non literal pool reference out of
2206 the pool we have to reject the address. This is
2207 especially important when loading the GOT pointer on non
2208 zarch CPUs. In this case the literal pool contains an lt
2209 relative offset to the _GLOBAL_OFFSET_TABLE_ label which
2210 will most likely exceed the displacement. */
2211 if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF
2212 || !CONSTANT_POOL_ADDRESS_P (XVECEXP (disp, 0, 0)))
2213 return false;
2214
2215 orig_disp = gen_rtx_CONST (Pmode, disp);
2216 if (offset)
2217 {
2218 /* If we have an offset, make sure it does not
2219 exceed the size of the constant pool entry. */
2220 rtx sym = XVECEXP (disp, 0, 0);
2221 if (offset >= GET_MODE_SIZE (get_pool_mode (sym)))
2222 return false;
2223
2224 orig_disp = plus_constant (Pmode, orig_disp, offset);
2225 }
2226 }
2227
2228 else
2229 return false;
2230 }
2231
2232 if (!base && !indx)
2233 pointer = true;
2234
2235 if (out)
2236 {
2237 out->base = base;
2238 out->indx = indx;
2239 out->disp = orig_disp;
2240 out->pointer = pointer;
2241 out->literal_pool = literal_pool;
2242 }
2243
2244 return true;
2245 }
2246
2247 /* Decompose a RTL expression OP for a shift count into its components,
2248 and return the base register in BASE and the offset in OFFSET.
2249
2250 Return true if OP is a valid shift count, false if not. */
2251
2252 bool
s390_decompose_shift_count(rtx op,rtx * base,HOST_WIDE_INT * offset)2253 s390_decompose_shift_count (rtx op, rtx *base, HOST_WIDE_INT *offset)
2254 {
2255 HOST_WIDE_INT off = 0;
2256
2257 /* We can have an integer constant, an address register,
2258 or a sum of the two. */
2259 if (GET_CODE (op) == CONST_INT)
2260 {
2261 off = INTVAL (op);
2262 op = NULL_RTX;
2263 }
2264 if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
2265 {
2266 off = INTVAL (XEXP (op, 1));
2267 op = XEXP (op, 0);
2268 }
2269 while (op && GET_CODE (op) == SUBREG)
2270 op = SUBREG_REG (op);
2271
2272 if (op && GET_CODE (op) != REG)
2273 return false;
2274
2275 if (offset)
2276 *offset = off;
2277 if (base)
2278 *base = op;
2279
2280 return true;
2281 }
2282
2283
2284 /* Return true if CODE is a valid address without index. */
2285
2286 bool
s390_legitimate_address_without_index_p(rtx op)2287 s390_legitimate_address_without_index_p (rtx op)
2288 {
2289 struct s390_address addr;
2290
2291 if (!s390_decompose_address (XEXP (op, 0), &addr))
2292 return false;
2293 if (addr.indx)
2294 return false;
2295
2296 return true;
2297 }
2298
2299
2300 /* Return TRUE if ADDR is an operand valid for a load/store relative
2301 instruction. Be aware that the alignment of the operand needs to
2302 be checked separately.
2303 Valid addresses are single references or a sum of a reference and a
2304 constant integer. Return these parts in SYMREF and ADDEND. You can
2305 pass NULL in REF and/or ADDEND if you are not interested in these
2306 values. Literal pool references are *not* considered symbol
2307 references. */
2308
2309 static bool
s390_loadrelative_operand_p(rtx addr,rtx * symref,HOST_WIDE_INT * addend)2310 s390_loadrelative_operand_p (rtx addr, rtx *symref, HOST_WIDE_INT *addend)
2311 {
2312 HOST_WIDE_INT tmpaddend = 0;
2313
2314 if (GET_CODE (addr) == CONST)
2315 addr = XEXP (addr, 0);
2316
2317 if (GET_CODE (addr) == PLUS)
2318 {
2319 if (!CONST_INT_P (XEXP (addr, 1)))
2320 return false;
2321
2322 tmpaddend = INTVAL (XEXP (addr, 1));
2323 addr = XEXP (addr, 0);
2324 }
2325
2326 if ((GET_CODE (addr) == SYMBOL_REF && !CONSTANT_POOL_ADDRESS_P (addr))
2327 || (GET_CODE (addr) == UNSPEC
2328 && (XINT (addr, 1) == UNSPEC_GOTENT
2329 || (TARGET_CPU_ZARCH && XINT (addr, 1) == UNSPEC_PLT))))
2330 {
2331 if (symref)
2332 *symref = addr;
2333 if (addend)
2334 *addend = tmpaddend;
2335
2336 return true;
2337 }
2338 return false;
2339 }
2340
2341 /* Return true if the address in OP is valid for constraint letter C
2342 if wrapped in a MEM rtx. Set LIT_POOL_OK to true if it literal
2343 pool MEMs should be accepted. Only the Q, R, S, T constraint
2344 letters are allowed for C. */
2345
2346 static int
s390_check_qrst_address(char c,rtx op,bool lit_pool_ok)2347 s390_check_qrst_address (char c, rtx op, bool lit_pool_ok)
2348 {
2349 struct s390_address addr;
2350 bool decomposed = false;
2351
2352 /* This check makes sure that no symbolic address (except literal
2353 pool references) are accepted by the R or T constraints. */
2354 if (s390_loadrelative_operand_p (op, NULL, NULL))
2355 return 0;
2356
2357 /* Ensure literal pool references are only accepted if LIT_POOL_OK. */
2358 if (!lit_pool_ok)
2359 {
2360 if (!s390_decompose_address (op, &addr))
2361 return 0;
2362 if (addr.literal_pool)
2363 return 0;
2364 decomposed = true;
2365 }
2366
2367 switch (c)
2368 {
2369 case 'Q': /* no index short displacement */
2370 if (!decomposed && !s390_decompose_address (op, &addr))
2371 return 0;
2372 if (addr.indx)
2373 return 0;
2374 if (!s390_short_displacement (addr.disp))
2375 return 0;
2376 break;
2377
2378 case 'R': /* with index short displacement */
2379 if (TARGET_LONG_DISPLACEMENT)
2380 {
2381 if (!decomposed && !s390_decompose_address (op, &addr))
2382 return 0;
2383 if (!s390_short_displacement (addr.disp))
2384 return 0;
2385 }
2386 /* Any invalid address here will be fixed up by reload,
2387 so accept it for the most generic constraint. */
2388 break;
2389
2390 case 'S': /* no index long displacement */
2391 if (!TARGET_LONG_DISPLACEMENT)
2392 return 0;
2393 if (!decomposed && !s390_decompose_address (op, &addr))
2394 return 0;
2395 if (addr.indx)
2396 return 0;
2397 if (s390_short_displacement (addr.disp))
2398 return 0;
2399 break;
2400
2401 case 'T': /* with index long displacement */
2402 if (!TARGET_LONG_DISPLACEMENT)
2403 return 0;
2404 /* Any invalid address here will be fixed up by reload,
2405 so accept it for the most generic constraint. */
2406 if ((decomposed || s390_decompose_address (op, &addr))
2407 && s390_short_displacement (addr.disp))
2408 return 0;
2409 break;
2410 default:
2411 return 0;
2412 }
2413 return 1;
2414 }
2415
2416
2417 /* Evaluates constraint strings described by the regular expression
2418 ([A|B|Z](Q|R|S|T))|U|W|Y and returns 1 if OP is a valid operand for
2419 the constraint given in STR, or 0 else. */
2420
2421 int
s390_mem_constraint(const char * str,rtx op)2422 s390_mem_constraint (const char *str, rtx op)
2423 {
2424 char c = str[0];
2425
2426 switch (c)
2427 {
2428 case 'A':
2429 /* Check for offsettable variants of memory constraints. */
2430 if (!MEM_P (op) || MEM_VOLATILE_P (op))
2431 return 0;
2432 if ((reload_completed || reload_in_progress)
2433 ? !offsettable_memref_p (op) : !offsettable_nonstrict_memref_p (op))
2434 return 0;
2435 return s390_check_qrst_address (str[1], XEXP (op, 0), true);
2436 case 'B':
2437 /* Check for non-literal-pool variants of memory constraints. */
2438 if (!MEM_P (op))
2439 return 0;
2440 return s390_check_qrst_address (str[1], XEXP (op, 0), false);
2441 case 'Q':
2442 case 'R':
2443 case 'S':
2444 case 'T':
2445 if (GET_CODE (op) != MEM)
2446 return 0;
2447 return s390_check_qrst_address (c, XEXP (op, 0), true);
2448 case 'U':
2449 return (s390_check_qrst_address ('Q', op, true)
2450 || s390_check_qrst_address ('R', op, true));
2451 case 'W':
2452 return (s390_check_qrst_address ('S', op, true)
2453 || s390_check_qrst_address ('T', op, true));
2454 case 'Y':
2455 /* Simply check for the basic form of a shift count. Reload will
2456 take care of making sure we have a proper base register. */
2457 if (!s390_decompose_shift_count (op, NULL, NULL))
2458 return 0;
2459 break;
2460 case 'Z':
2461 return s390_check_qrst_address (str[1], op, true);
2462 default:
2463 return 0;
2464 }
2465 return 1;
2466 }
2467
2468
2469 /* Evaluates constraint strings starting with letter O. Input
2470 parameter C is the second letter following the "O" in the constraint
2471 string. Returns 1 if VALUE meets the respective constraint and 0
2472 otherwise. */
2473
2474 int
s390_O_constraint_str(const char c,HOST_WIDE_INT value)2475 s390_O_constraint_str (const char c, HOST_WIDE_INT value)
2476 {
2477 if (!TARGET_EXTIMM)
2478 return 0;
2479
2480 switch (c)
2481 {
2482 case 's':
2483 return trunc_int_for_mode (value, SImode) == value;
2484
2485 case 'p':
2486 return value == 0
2487 || s390_single_part (GEN_INT (value), DImode, SImode, 0) == 1;
2488
2489 case 'n':
2490 return s390_single_part (GEN_INT (value - 1), DImode, SImode, -1) == 1;
2491
2492 default:
2493 gcc_unreachable ();
2494 }
2495 }
2496
2497
2498 /* Evaluates constraint strings starting with letter N. Parameter STR
2499 contains the letters following letter "N" in the constraint string.
2500 Returns true if VALUE matches the constraint. */
2501
2502 int
s390_N_constraint_str(const char * str,HOST_WIDE_INT value)2503 s390_N_constraint_str (const char *str, HOST_WIDE_INT value)
2504 {
2505 enum machine_mode mode, part_mode;
2506 int def;
2507 int part, part_goal;
2508
2509
2510 if (str[0] == 'x')
2511 part_goal = -1;
2512 else
2513 part_goal = str[0] - '0';
2514
2515 switch (str[1])
2516 {
2517 case 'Q':
2518 part_mode = QImode;
2519 break;
2520 case 'H':
2521 part_mode = HImode;
2522 break;
2523 case 'S':
2524 part_mode = SImode;
2525 break;
2526 default:
2527 return 0;
2528 }
2529
2530 switch (str[2])
2531 {
2532 case 'H':
2533 mode = HImode;
2534 break;
2535 case 'S':
2536 mode = SImode;
2537 break;
2538 case 'D':
2539 mode = DImode;
2540 break;
2541 default:
2542 return 0;
2543 }
2544
2545 switch (str[3])
2546 {
2547 case '0':
2548 def = 0;
2549 break;
2550 case 'F':
2551 def = -1;
2552 break;
2553 default:
2554 return 0;
2555 }
2556
2557 if (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (part_mode))
2558 return 0;
2559
2560 part = s390_single_part (GEN_INT (value), mode, part_mode, def);
2561 if (part < 0)
2562 return 0;
2563 if (part_goal != -1 && part_goal != part)
2564 return 0;
2565
2566 return 1;
2567 }
2568
2569
2570 /* Returns true if the input parameter VALUE is a float zero. */
2571
2572 int
s390_float_const_zero_p(rtx value)2573 s390_float_const_zero_p (rtx value)
2574 {
2575 return (GET_MODE_CLASS (GET_MODE (value)) == MODE_FLOAT
2576 && value == CONST0_RTX (GET_MODE (value)));
2577 }
2578
2579 /* Implement TARGET_REGISTER_MOVE_COST. */
2580
2581 static int
s390_register_move_cost(enum machine_mode mode ATTRIBUTE_UNUSED,reg_class_t from,reg_class_t to)2582 s390_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
2583 reg_class_t from, reg_class_t to)
2584 {
2585 /* On s390, copy between fprs and gprs is expensive. */
2586 if ((reg_classes_intersect_p (from, GENERAL_REGS)
2587 && reg_classes_intersect_p (to, FP_REGS))
2588 || (reg_classes_intersect_p (from, FP_REGS)
2589 && reg_classes_intersect_p (to, GENERAL_REGS)))
2590 return 10;
2591
2592 return 1;
2593 }
2594
2595 /* Implement TARGET_MEMORY_MOVE_COST. */
2596
2597 static int
s390_memory_move_cost(enum machine_mode mode ATTRIBUTE_UNUSED,reg_class_t rclass ATTRIBUTE_UNUSED,bool in ATTRIBUTE_UNUSED)2598 s390_memory_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
2599 reg_class_t rclass ATTRIBUTE_UNUSED,
2600 bool in ATTRIBUTE_UNUSED)
2601 {
2602 return 1;
2603 }
2604
2605 /* Compute a (partial) cost for rtx X. Return true if the complete
2606 cost has been computed, and false if subexpressions should be
2607 scanned. In either case, *TOTAL contains the cost result.
2608 CODE contains GET_CODE (x), OUTER_CODE contains the code
2609 of the superexpression of x. */
2610
2611 static bool
s390_rtx_costs(rtx x,int code,int outer_code,int opno ATTRIBUTE_UNUSED,int * total,bool speed ATTRIBUTE_UNUSED)2612 s390_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
2613 int *total, bool speed ATTRIBUTE_UNUSED)
2614 {
2615 switch (code)
2616 {
2617 case CONST:
2618 case CONST_INT:
2619 case LABEL_REF:
2620 case SYMBOL_REF:
2621 case CONST_DOUBLE:
2622 case MEM:
2623 *total = 0;
2624 return true;
2625
2626 case ASHIFT:
2627 case ASHIFTRT:
2628 case LSHIFTRT:
2629 case ROTATE:
2630 case ROTATERT:
2631 case AND:
2632 case IOR:
2633 case XOR:
2634 case NEG:
2635 case NOT:
2636 *total = COSTS_N_INSNS (1);
2637 return false;
2638
2639 case PLUS:
2640 case MINUS:
2641 *total = COSTS_N_INSNS (1);
2642 return false;
2643
2644 case MULT:
2645 switch (GET_MODE (x))
2646 {
2647 case SImode:
2648 {
2649 rtx left = XEXP (x, 0);
2650 rtx right = XEXP (x, 1);
2651 if (GET_CODE (right) == CONST_INT
2652 && CONST_OK_FOR_K (INTVAL (right)))
2653 *total = s390_cost->mhi;
2654 else if (GET_CODE (left) == SIGN_EXTEND)
2655 *total = s390_cost->mh;
2656 else
2657 *total = s390_cost->ms; /* msr, ms, msy */
2658 break;
2659 }
2660 case DImode:
2661 {
2662 rtx left = XEXP (x, 0);
2663 rtx right = XEXP (x, 1);
2664 if (TARGET_ZARCH)
2665 {
2666 if (GET_CODE (right) == CONST_INT
2667 && CONST_OK_FOR_K (INTVAL (right)))
2668 *total = s390_cost->mghi;
2669 else if (GET_CODE (left) == SIGN_EXTEND)
2670 *total = s390_cost->msgf;
2671 else
2672 *total = s390_cost->msg; /* msgr, msg */
2673 }
2674 else /* TARGET_31BIT */
2675 {
2676 if (GET_CODE (left) == SIGN_EXTEND
2677 && GET_CODE (right) == SIGN_EXTEND)
2678 /* mulsidi case: mr, m */
2679 *total = s390_cost->m;
2680 else if (GET_CODE (left) == ZERO_EXTEND
2681 && GET_CODE (right) == ZERO_EXTEND
2682 && TARGET_CPU_ZARCH)
2683 /* umulsidi case: ml, mlr */
2684 *total = s390_cost->ml;
2685 else
2686 /* Complex calculation is required. */
2687 *total = COSTS_N_INSNS (40);
2688 }
2689 break;
2690 }
2691 case SFmode:
2692 case DFmode:
2693 *total = s390_cost->mult_df;
2694 break;
2695 case TFmode:
2696 *total = s390_cost->mxbr;
2697 break;
2698 default:
2699 return false;
2700 }
2701 return false;
2702
2703 case FMA:
2704 switch (GET_MODE (x))
2705 {
2706 case DFmode:
2707 *total = s390_cost->madbr;
2708 break;
2709 case SFmode:
2710 *total = s390_cost->maebr;
2711 break;
2712 default:
2713 return false;
2714 }
2715 /* Negate in the third argument is free: FMSUB. */
2716 if (GET_CODE (XEXP (x, 2)) == NEG)
2717 {
2718 *total += (rtx_cost (XEXP (x, 0), FMA, 0, speed)
2719 + rtx_cost (XEXP (x, 1), FMA, 1, speed)
2720 + rtx_cost (XEXP (XEXP (x, 2), 0), FMA, 2, speed));
2721 return true;
2722 }
2723 return false;
2724
2725 case UDIV:
2726 case UMOD:
2727 if (GET_MODE (x) == TImode) /* 128 bit division */
2728 *total = s390_cost->dlgr;
2729 else if (GET_MODE (x) == DImode)
2730 {
2731 rtx right = XEXP (x, 1);
2732 if (GET_CODE (right) == ZERO_EXTEND) /* 64 by 32 bit division */
2733 *total = s390_cost->dlr;
2734 else /* 64 by 64 bit division */
2735 *total = s390_cost->dlgr;
2736 }
2737 else if (GET_MODE (x) == SImode) /* 32 bit division */
2738 *total = s390_cost->dlr;
2739 return false;
2740
2741 case DIV:
2742 case MOD:
2743 if (GET_MODE (x) == DImode)
2744 {
2745 rtx right = XEXP (x, 1);
2746 if (GET_CODE (right) == ZERO_EXTEND) /* 64 by 32 bit division */
2747 if (TARGET_ZARCH)
2748 *total = s390_cost->dsgfr;
2749 else
2750 *total = s390_cost->dr;
2751 else /* 64 by 64 bit division */
2752 *total = s390_cost->dsgr;
2753 }
2754 else if (GET_MODE (x) == SImode) /* 32 bit division */
2755 *total = s390_cost->dlr;
2756 else if (GET_MODE (x) == SFmode)
2757 {
2758 *total = s390_cost->debr;
2759 }
2760 else if (GET_MODE (x) == DFmode)
2761 {
2762 *total = s390_cost->ddbr;
2763 }
2764 else if (GET_MODE (x) == TFmode)
2765 {
2766 *total = s390_cost->dxbr;
2767 }
2768 return false;
2769
2770 case SQRT:
2771 if (GET_MODE (x) == SFmode)
2772 *total = s390_cost->sqebr;
2773 else if (GET_MODE (x) == DFmode)
2774 *total = s390_cost->sqdbr;
2775 else /* TFmode */
2776 *total = s390_cost->sqxbr;
2777 return false;
2778
2779 case SIGN_EXTEND:
2780 case ZERO_EXTEND:
2781 if (outer_code == MULT || outer_code == DIV || outer_code == MOD
2782 || outer_code == PLUS || outer_code == MINUS
2783 || outer_code == COMPARE)
2784 *total = 0;
2785 return false;
2786
2787 case COMPARE:
2788 *total = COSTS_N_INSNS (1);
2789 if (GET_CODE (XEXP (x, 0)) == AND
2790 && GET_CODE (XEXP (x, 1)) == CONST_INT
2791 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
2792 {
2793 rtx op0 = XEXP (XEXP (x, 0), 0);
2794 rtx op1 = XEXP (XEXP (x, 0), 1);
2795 rtx op2 = XEXP (x, 1);
2796
2797 if (memory_operand (op0, GET_MODE (op0))
2798 && s390_tm_ccmode (op1, op2, 0) != VOIDmode)
2799 return true;
2800 if (register_operand (op0, GET_MODE (op0))
2801 && s390_tm_ccmode (op1, op2, 1) != VOIDmode)
2802 return true;
2803 }
2804 return false;
2805
2806 default:
2807 return false;
2808 }
2809 }
2810
2811 /* Return the cost of an address rtx ADDR. */
2812
2813 static int
s390_address_cost(rtx addr,enum machine_mode mode ATTRIBUTE_UNUSED,addr_space_t as ATTRIBUTE_UNUSED,bool speed ATTRIBUTE_UNUSED)2814 s390_address_cost (rtx addr, enum machine_mode mode ATTRIBUTE_UNUSED,
2815 addr_space_t as ATTRIBUTE_UNUSED,
2816 bool speed ATTRIBUTE_UNUSED)
2817 {
2818 struct s390_address ad;
2819 if (!s390_decompose_address (addr, &ad))
2820 return 1000;
2821
2822 return ad.indx? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
2823 }
2824
2825 /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
2826 otherwise return 0. */
2827
2828 int
tls_symbolic_operand(rtx op)2829 tls_symbolic_operand (rtx op)
2830 {
2831 if (GET_CODE (op) != SYMBOL_REF)
2832 return 0;
2833 return SYMBOL_REF_TLS_MODEL (op);
2834 }
2835
2836 /* Split DImode access register reference REG (on 64-bit) into its constituent
2837 low and high parts, and store them into LO and HI. Note that gen_lowpart/
2838 gen_highpart cannot be used as they assume all registers are word-sized,
2839 while our access registers have only half that size. */
2840
2841 void
s390_split_access_reg(rtx reg,rtx * lo,rtx * hi)2842 s390_split_access_reg (rtx reg, rtx *lo, rtx *hi)
2843 {
2844 gcc_assert (TARGET_64BIT);
2845 gcc_assert (ACCESS_REG_P (reg));
2846 gcc_assert (GET_MODE (reg) == DImode);
2847 gcc_assert (!(REGNO (reg) & 1));
2848
2849 *lo = gen_rtx_REG (SImode, REGNO (reg) + 1);
2850 *hi = gen_rtx_REG (SImode, REGNO (reg));
2851 }
2852
2853 /* Return true if OP contains a symbol reference */
2854
2855 bool
symbolic_reference_mentioned_p(rtx op)2856 symbolic_reference_mentioned_p (rtx op)
2857 {
2858 const char *fmt;
2859 int i;
2860
2861 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
2862 return 1;
2863
2864 fmt = GET_RTX_FORMAT (GET_CODE (op));
2865 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
2866 {
2867 if (fmt[i] == 'E')
2868 {
2869 int j;
2870
2871 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
2872 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
2873 return 1;
2874 }
2875
2876 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
2877 return 1;
2878 }
2879
2880 return 0;
2881 }
2882
2883 /* Return true if OP contains a reference to a thread-local symbol. */
2884
2885 bool
tls_symbolic_reference_mentioned_p(rtx op)2886 tls_symbolic_reference_mentioned_p (rtx op)
2887 {
2888 const char *fmt;
2889 int i;
2890
2891 if (GET_CODE (op) == SYMBOL_REF)
2892 return tls_symbolic_operand (op);
2893
2894 fmt = GET_RTX_FORMAT (GET_CODE (op));
2895 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
2896 {
2897 if (fmt[i] == 'E')
2898 {
2899 int j;
2900
2901 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
2902 if (tls_symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
2903 return true;
2904 }
2905
2906 else if (fmt[i] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op, i)))
2907 return true;
2908 }
2909
2910 return false;
2911 }
2912
2913
2914 /* Return true if OP is a legitimate general operand when
2915 generating PIC code. It is given that flag_pic is on
2916 and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2917
2918 int
legitimate_pic_operand_p(rtx op)2919 legitimate_pic_operand_p (rtx op)
2920 {
2921 /* Accept all non-symbolic constants. */
2922 if (!SYMBOLIC_CONST (op))
2923 return 1;
2924
2925 /* Reject everything else; must be handled
2926 via emit_symbolic_move. */
2927 return 0;
2928 }
2929
2930 /* Returns true if the constant value OP is a legitimate general operand.
2931 It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2932
2933 static bool
s390_legitimate_constant_p(enum machine_mode mode,rtx op)2934 s390_legitimate_constant_p (enum machine_mode mode, rtx op)
2935 {
2936 /* Accept all non-symbolic constants. */
2937 if (!SYMBOLIC_CONST (op))
2938 return 1;
2939
2940 /* Accept immediate LARL operands. */
2941 if (TARGET_CPU_ZARCH && larl_operand (op, mode))
2942 return 1;
2943
2944 /* Thread-local symbols are never legal constants. This is
2945 so that emit_call knows that computing such addresses
2946 might require a function call. */
2947 if (TLS_SYMBOLIC_CONST (op))
2948 return 0;
2949
2950 /* In the PIC case, symbolic constants must *not* be
2951 forced into the literal pool. We accept them here,
2952 so that they will be handled by emit_symbolic_move. */
2953 if (flag_pic)
2954 return 1;
2955
2956 /* All remaining non-PIC symbolic constants are
2957 forced into the literal pool. */
2958 return 0;
2959 }
2960
2961 /* Determine if it's legal to put X into the constant pool. This
2962 is not possible if X contains the address of a symbol that is
2963 not constant (TLS) or not known at final link time (PIC). */
2964
2965 static bool
s390_cannot_force_const_mem(enum machine_mode mode,rtx x)2966 s390_cannot_force_const_mem (enum machine_mode mode, rtx x)
2967 {
2968 switch (GET_CODE (x))
2969 {
2970 case CONST_INT:
2971 case CONST_DOUBLE:
2972 /* Accept all non-symbolic constants. */
2973 return false;
2974
2975 case LABEL_REF:
2976 /* Labels are OK iff we are non-PIC. */
2977 return flag_pic != 0;
2978
2979 case SYMBOL_REF:
2980 /* 'Naked' TLS symbol references are never OK,
2981 non-TLS symbols are OK iff we are non-PIC. */
2982 if (tls_symbolic_operand (x))
2983 return true;
2984 else
2985 return flag_pic != 0;
2986
2987 case CONST:
2988 return s390_cannot_force_const_mem (mode, XEXP (x, 0));
2989 case PLUS:
2990 case MINUS:
2991 return s390_cannot_force_const_mem (mode, XEXP (x, 0))
2992 || s390_cannot_force_const_mem (mode, XEXP (x, 1));
2993
2994 case UNSPEC:
2995 switch (XINT (x, 1))
2996 {
2997 /* Only lt-relative or GOT-relative UNSPECs are OK. */
2998 case UNSPEC_LTREL_OFFSET:
2999 case UNSPEC_GOT:
3000 case UNSPEC_GOTOFF:
3001 case UNSPEC_PLTOFF:
3002 case UNSPEC_TLSGD:
3003 case UNSPEC_TLSLDM:
3004 case UNSPEC_NTPOFF:
3005 case UNSPEC_DTPOFF:
3006 case UNSPEC_GOTNTPOFF:
3007 case UNSPEC_INDNTPOFF:
3008 return false;
3009
3010 /* If the literal pool shares the code section, be put
3011 execute template placeholders into the pool as well. */
3012 case UNSPEC_INSN:
3013 return TARGET_CPU_ZARCH;
3014
3015 default:
3016 return true;
3017 }
3018 break;
3019
3020 default:
3021 gcc_unreachable ();
3022 }
3023 }
3024
3025 /* Returns true if the constant value OP is a legitimate general
3026 operand during and after reload. The difference to
3027 legitimate_constant_p is that this function will not accept
3028 a constant that would need to be forced to the literal pool
3029 before it can be used as operand.
3030 This function accepts all constants which can be loaded directly
3031 into a GPR. */
3032
3033 bool
legitimate_reload_constant_p(rtx op)3034 legitimate_reload_constant_p (rtx op)
3035 {
3036 /* Accept la(y) operands. */
3037 if (GET_CODE (op) == CONST_INT
3038 && DISP_IN_RANGE (INTVAL (op)))
3039 return true;
3040
3041 /* Accept l(g)hi/l(g)fi operands. */
3042 if (GET_CODE (op) == CONST_INT
3043 && (CONST_OK_FOR_K (INTVAL (op)) || CONST_OK_FOR_Os (INTVAL (op))))
3044 return true;
3045
3046 /* Accept lliXX operands. */
3047 if (TARGET_ZARCH
3048 && GET_CODE (op) == CONST_INT
3049 && trunc_int_for_mode (INTVAL (op), word_mode) == INTVAL (op)
3050 && s390_single_part (op, word_mode, HImode, 0) >= 0)
3051 return true;
3052
3053 if (TARGET_EXTIMM
3054 && GET_CODE (op) == CONST_INT
3055 && trunc_int_for_mode (INTVAL (op), word_mode) == INTVAL (op)
3056 && s390_single_part (op, word_mode, SImode, 0) >= 0)
3057 return true;
3058
3059 /* Accept larl operands. */
3060 if (TARGET_CPU_ZARCH
3061 && larl_operand (op, VOIDmode))
3062 return true;
3063
3064 /* Accept floating-point zero operands that fit into a single GPR. */
3065 if (GET_CODE (op) == CONST_DOUBLE
3066 && s390_float_const_zero_p (op)
3067 && GET_MODE_SIZE (GET_MODE (op)) <= UNITS_PER_WORD)
3068 return true;
3069
3070 /* Accept double-word operands that can be split. */
3071 if (GET_CODE (op) == CONST_INT
3072 && trunc_int_for_mode (INTVAL (op), word_mode) != INTVAL (op))
3073 {
3074 enum machine_mode dword_mode = word_mode == SImode ? DImode : TImode;
3075 rtx hi = operand_subword (op, 0, 0, dword_mode);
3076 rtx lo = operand_subword (op, 1, 0, dword_mode);
3077 return legitimate_reload_constant_p (hi)
3078 && legitimate_reload_constant_p (lo);
3079 }
3080
3081 /* Everything else cannot be handled without reload. */
3082 return false;
3083 }
3084
3085 /* Returns true if the constant value OP is a legitimate fp operand
3086 during and after reload.
3087 This function accepts all constants which can be loaded directly
3088 into an FPR. */
3089
3090 static bool
legitimate_reload_fp_constant_p(rtx op)3091 legitimate_reload_fp_constant_p (rtx op)
3092 {
3093 /* Accept floating-point zero operands if the load zero instruction
3094 can be used. Prior to z196 the load fp zero instruction caused a
3095 performance penalty if the result is used as BFP number. */
3096 if (TARGET_Z196
3097 && GET_CODE (op) == CONST_DOUBLE
3098 && s390_float_const_zero_p (op))
3099 return true;
3100
3101 return false;
3102 }
3103
3104 /* Given an rtx OP being reloaded into a reg required to be in class RCLASS,
3105 return the class of reg to actually use. */
3106
3107 static reg_class_t
s390_preferred_reload_class(rtx op,reg_class_t rclass)3108 s390_preferred_reload_class (rtx op, reg_class_t rclass)
3109 {
3110 switch (GET_CODE (op))
3111 {
3112 /* Constants we cannot reload into general registers
3113 must be forced into the literal pool. */
3114 case CONST_DOUBLE:
3115 case CONST_INT:
3116 if (reg_class_subset_p (GENERAL_REGS, rclass)
3117 && legitimate_reload_constant_p (op))
3118 return GENERAL_REGS;
3119 else if (reg_class_subset_p (ADDR_REGS, rclass)
3120 && legitimate_reload_constant_p (op))
3121 return ADDR_REGS;
3122 else if (reg_class_subset_p (FP_REGS, rclass)
3123 && legitimate_reload_fp_constant_p (op))
3124 return FP_REGS;
3125 return NO_REGS;
3126
3127 /* If a symbolic constant or a PLUS is reloaded,
3128 it is most likely being used as an address, so
3129 prefer ADDR_REGS. If 'class' is not a superset
3130 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
3131 case CONST:
3132 /* Symrefs cannot be pushed into the literal pool with -fPIC
3133 so we *MUST NOT* return NO_REGS for these cases
3134 (s390_cannot_force_const_mem will return true).
3135
3136 On the other hand we MUST return NO_REGS for symrefs with
3137 invalid addend which might have been pushed to the literal
3138 pool (no -fPIC). Usually we would expect them to be
3139 handled via secondary reload but this does not happen if
3140 they are used as literal pool slot replacement in reload
3141 inheritance (see emit_input_reload_insns). */
3142 if (TARGET_CPU_ZARCH
3143 && GET_CODE (XEXP (op, 0)) == PLUS
3144 && GET_CODE (XEXP (XEXP(op, 0), 0)) == SYMBOL_REF
3145 && GET_CODE (XEXP (XEXP(op, 0), 1)) == CONST_INT)
3146 {
3147 if (flag_pic && reg_class_subset_p (ADDR_REGS, rclass))
3148 return ADDR_REGS;
3149 else
3150 return NO_REGS;
3151 }
3152 /* fallthrough */
3153 case LABEL_REF:
3154 case SYMBOL_REF:
3155 if (!legitimate_reload_constant_p (op))
3156 return NO_REGS;
3157 /* fallthrough */
3158 case PLUS:
3159 /* load address will be used. */
3160 if (reg_class_subset_p (ADDR_REGS, rclass))
3161 return ADDR_REGS;
3162 else
3163 return NO_REGS;
3164
3165 default:
3166 break;
3167 }
3168
3169 return rclass;
3170 }
3171
3172 /* Return true if ADDR is SYMBOL_REF + addend with addend being a
3173 multiple of ALIGNMENT and the SYMBOL_REF being naturally
3174 aligned. */
3175
3176 bool
s390_check_symref_alignment(rtx addr,HOST_WIDE_INT alignment)3177 s390_check_symref_alignment (rtx addr, HOST_WIDE_INT alignment)
3178 {
3179 HOST_WIDE_INT addend;
3180 rtx symref;
3181
3182 if (!s390_loadrelative_operand_p (addr, &symref, &addend))
3183 return false;
3184
3185 if (addend & (alignment - 1))
3186 return false;
3187
3188 if (GET_CODE (symref) == SYMBOL_REF
3189 && !SYMBOL_REF_NOT_NATURALLY_ALIGNED_P (symref))
3190 return true;
3191
3192 if (GET_CODE (symref) == UNSPEC
3193 && alignment <= UNITS_PER_LONG)
3194 return true;
3195
3196 return false;
3197 }
3198
3199 /* ADDR is moved into REG using larl. If ADDR isn't a valid larl
3200 operand SCRATCH is used to reload the even part of the address and
3201 adding one. */
3202
3203 void
s390_reload_larl_operand(rtx reg,rtx addr,rtx scratch)3204 s390_reload_larl_operand (rtx reg, rtx addr, rtx scratch)
3205 {
3206 HOST_WIDE_INT addend;
3207 rtx symref;
3208
3209 if (!s390_loadrelative_operand_p (addr, &symref, &addend))
3210 gcc_unreachable ();
3211
3212 if (!(addend & 1))
3213 /* Easy case. The addend is even so larl will do fine. */
3214 emit_move_insn (reg, addr);
3215 else
3216 {
3217 /* We can leave the scratch register untouched if the target
3218 register is a valid base register. */
3219 if (REGNO (reg) < FIRST_PSEUDO_REGISTER
3220 && REGNO_REG_CLASS (REGNO (reg)) == ADDR_REGS)
3221 scratch = reg;
3222
3223 gcc_assert (REGNO (scratch) < FIRST_PSEUDO_REGISTER);
3224 gcc_assert (REGNO_REG_CLASS (REGNO (scratch)) == ADDR_REGS);
3225
3226 if (addend != 1)
3227 emit_move_insn (scratch,
3228 gen_rtx_CONST (Pmode,
3229 gen_rtx_PLUS (Pmode, symref,
3230 GEN_INT (addend - 1))));
3231 else
3232 emit_move_insn (scratch, symref);
3233
3234 /* Increment the address using la in order to avoid clobbering cc. */
3235 s390_load_address (reg, gen_rtx_PLUS (Pmode, scratch, const1_rtx));
3236 }
3237 }
3238
3239 /* Generate what is necessary to move between REG and MEM using
3240 SCRATCH. The direction is given by TOMEM. */
3241
3242 void
s390_reload_symref_address(rtx reg,rtx mem,rtx scratch,bool tomem)3243 s390_reload_symref_address (rtx reg, rtx mem, rtx scratch, bool tomem)
3244 {
3245 /* Reload might have pulled a constant out of the literal pool.
3246 Force it back in. */
3247 if (CONST_INT_P (mem) || GET_CODE (mem) == CONST_DOUBLE
3248 || GET_CODE (mem) == CONST)
3249 mem = force_const_mem (GET_MODE (reg), mem);
3250
3251 gcc_assert (MEM_P (mem));
3252
3253 /* For a load from memory we can leave the scratch register
3254 untouched if the target register is a valid base register. */
3255 if (!tomem
3256 && REGNO (reg) < FIRST_PSEUDO_REGISTER
3257 && REGNO_REG_CLASS (REGNO (reg)) == ADDR_REGS
3258 && GET_MODE (reg) == GET_MODE (scratch))
3259 scratch = reg;
3260
3261 /* Load address into scratch register. Since we can't have a
3262 secondary reload for a secondary reload we have to cover the case
3263 where larl would need a secondary reload here as well. */
3264 s390_reload_larl_operand (scratch, XEXP (mem, 0), scratch);
3265
3266 /* Now we can use a standard load/store to do the move. */
3267 if (tomem)
3268 emit_move_insn (replace_equiv_address (mem, scratch), reg);
3269 else
3270 emit_move_insn (reg, replace_equiv_address (mem, scratch));
3271 }
3272
3273 /* Inform reload about cases where moving X with a mode MODE to a register in
3274 RCLASS requires an extra scratch or immediate register. Return the class
3275 needed for the immediate register. */
3276
3277 static reg_class_t
s390_secondary_reload(bool in_p,rtx x,reg_class_t rclass_i,enum machine_mode mode,secondary_reload_info * sri)3278 s390_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i,
3279 enum machine_mode mode, secondary_reload_info *sri)
3280 {
3281 enum reg_class rclass = (enum reg_class) rclass_i;
3282
3283 /* Intermediate register needed. */
3284 if (reg_classes_intersect_p (CC_REGS, rclass))
3285 return GENERAL_REGS;
3286
3287 if (TARGET_Z10)
3288 {
3289 HOST_WIDE_INT offset;
3290 rtx symref;
3291
3292 /* On z10 several optimizer steps may generate larl operands with
3293 an odd addend. */
3294 if (in_p
3295 && s390_loadrelative_operand_p (x, &symref, &offset)
3296 && mode == Pmode
3297 && !SYMBOL_REF_ALIGN1_P (symref)
3298 && (offset & 1) == 1)
3299 sri->icode = ((mode == DImode) ? CODE_FOR_reloaddi_larl_odd_addend_z10
3300 : CODE_FOR_reloadsi_larl_odd_addend_z10);
3301
3302 /* On z10 we need a scratch register when moving QI, TI or floating
3303 point mode values from or to a memory location with a SYMBOL_REF
3304 or if the symref addend of a SI or DI move is not aligned to the
3305 width of the access. */
3306 if (MEM_P (x)
3307 && s390_loadrelative_operand_p (XEXP (x, 0), NULL, NULL)
3308 && (mode == QImode || mode == TImode || FLOAT_MODE_P (mode)
3309 || (!TARGET_ZARCH && mode == DImode)
3310 || ((mode == HImode || mode == SImode || mode == DImode)
3311 && (!s390_check_symref_alignment (XEXP (x, 0),
3312 GET_MODE_SIZE (mode))))))
3313 {
3314 #define __SECONDARY_RELOAD_CASE(M,m) \
3315 case M##mode: \
3316 if (TARGET_64BIT) \
3317 sri->icode = in_p ? CODE_FOR_reload##m##di_toreg_z10 : \
3318 CODE_FOR_reload##m##di_tomem_z10; \
3319 else \
3320 sri->icode = in_p ? CODE_FOR_reload##m##si_toreg_z10 : \
3321 CODE_FOR_reload##m##si_tomem_z10; \
3322 break;
3323
3324 switch (GET_MODE (x))
3325 {
3326 __SECONDARY_RELOAD_CASE (QI, qi);
3327 __SECONDARY_RELOAD_CASE (HI, hi);
3328 __SECONDARY_RELOAD_CASE (SI, si);
3329 __SECONDARY_RELOAD_CASE (DI, di);
3330 __SECONDARY_RELOAD_CASE (TI, ti);
3331 __SECONDARY_RELOAD_CASE (SF, sf);
3332 __SECONDARY_RELOAD_CASE (DF, df);
3333 __SECONDARY_RELOAD_CASE (TF, tf);
3334 __SECONDARY_RELOAD_CASE (SD, sd);
3335 __SECONDARY_RELOAD_CASE (DD, dd);
3336 __SECONDARY_RELOAD_CASE (TD, td);
3337
3338 default:
3339 gcc_unreachable ();
3340 }
3341 #undef __SECONDARY_RELOAD_CASE
3342 }
3343 }
3344
3345 /* We need a scratch register when loading a PLUS expression which
3346 is not a legitimate operand of the LOAD ADDRESS instruction. */
3347 if (in_p && s390_plus_operand (x, mode))
3348 sri->icode = (TARGET_64BIT ?
3349 CODE_FOR_reloaddi_plus : CODE_FOR_reloadsi_plus);
3350
3351 /* Performing a multiword move from or to memory we have to make sure the
3352 second chunk in memory is addressable without causing a displacement
3353 overflow. If that would be the case we calculate the address in
3354 a scratch register. */
3355 if (MEM_P (x)
3356 && GET_CODE (XEXP (x, 0)) == PLUS
3357 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
3358 && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (x, 0), 1))
3359 + GET_MODE_SIZE (mode) - 1))
3360 {
3361 /* For GENERAL_REGS a displacement overflow is no problem if occurring
3362 in a s_operand address since we may fallback to lm/stm. So we only
3363 have to care about overflows in the b+i+d case. */
3364 if ((reg_classes_intersect_p (GENERAL_REGS, rclass)
3365 && s390_class_max_nregs (GENERAL_REGS, mode) > 1
3366 && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS)
3367 /* For FP_REGS no lm/stm is available so this check is triggered
3368 for displacement overflows in b+i+d and b+d like addresses. */
3369 || (reg_classes_intersect_p (FP_REGS, rclass)
3370 && s390_class_max_nregs (FP_REGS, mode) > 1))
3371 {
3372 if (in_p)
3373 sri->icode = (TARGET_64BIT ?
3374 CODE_FOR_reloaddi_nonoffmem_in :
3375 CODE_FOR_reloadsi_nonoffmem_in);
3376 else
3377 sri->icode = (TARGET_64BIT ?
3378 CODE_FOR_reloaddi_nonoffmem_out :
3379 CODE_FOR_reloadsi_nonoffmem_out);
3380 }
3381 }
3382
3383 /* A scratch address register is needed when a symbolic constant is
3384 copied to r0 compiling with -fPIC. In other cases the target
3385 register might be used as temporary (see legitimize_pic_address). */
3386 if (in_p && SYMBOLIC_CONST (x) && flag_pic == 2 && rclass != ADDR_REGS)
3387 sri->icode = (TARGET_64BIT ?
3388 CODE_FOR_reloaddi_PIC_addr :
3389 CODE_FOR_reloadsi_PIC_addr);
3390
3391 /* Either scratch or no register needed. */
3392 return NO_REGS;
3393 }
3394
3395 /* Generate code to load SRC, which is PLUS that is not a
3396 legitimate operand for the LA instruction, into TARGET.
3397 SCRATCH may be used as scratch register. */
3398
3399 void
s390_expand_plus_operand(rtx target,rtx src,rtx scratch)3400 s390_expand_plus_operand (rtx target, rtx src,
3401 rtx scratch)
3402 {
3403 rtx sum1, sum2;
3404 struct s390_address ad;
3405
3406 /* src must be a PLUS; get its two operands. */
3407 gcc_assert (GET_CODE (src) == PLUS);
3408 gcc_assert (GET_MODE (src) == Pmode);
3409
3410 /* Check if any of the two operands is already scheduled
3411 for replacement by reload. This can happen e.g. when
3412 float registers occur in an address. */
3413 sum1 = find_replacement (&XEXP (src, 0));
3414 sum2 = find_replacement (&XEXP (src, 1));
3415 src = gen_rtx_PLUS (Pmode, sum1, sum2);
3416
3417 /* If the address is already strictly valid, there's nothing to do. */
3418 if (!s390_decompose_address (src, &ad)
3419 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
3420 || (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx))))
3421 {
3422 /* Otherwise, one of the operands cannot be an address register;
3423 we reload its value into the scratch register. */
3424 if (true_regnum (sum1) < 1 || true_regnum (sum1) > 15)
3425 {
3426 emit_move_insn (scratch, sum1);
3427 sum1 = scratch;
3428 }
3429 if (true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
3430 {
3431 emit_move_insn (scratch, sum2);
3432 sum2 = scratch;
3433 }
3434
3435 /* According to the way these invalid addresses are generated
3436 in reload.c, it should never happen (at least on s390) that
3437 *neither* of the PLUS components, after find_replacements
3438 was applied, is an address register. */
3439 if (sum1 == scratch && sum2 == scratch)
3440 {
3441 debug_rtx (src);
3442 gcc_unreachable ();
3443 }
3444
3445 src = gen_rtx_PLUS (Pmode, sum1, sum2);
3446 }
3447
3448 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
3449 is only ever performed on addresses, so we can mark the
3450 sum as legitimate for LA in any case. */
3451 s390_load_address (target, src);
3452 }
3453
3454
3455 /* Return true if ADDR is a valid memory address.
3456 STRICT specifies whether strict register checking applies. */
3457
3458 static bool
s390_legitimate_address_p(enum machine_mode mode,rtx addr,bool strict)3459 s390_legitimate_address_p (enum machine_mode mode, rtx addr, bool strict)
3460 {
3461 struct s390_address ad;
3462
3463 if (TARGET_Z10
3464 && larl_operand (addr, VOIDmode)
3465 && (mode == VOIDmode
3466 || s390_check_symref_alignment (addr, GET_MODE_SIZE (mode))))
3467 return true;
3468
3469 if (!s390_decompose_address (addr, &ad))
3470 return false;
3471
3472 if (strict)
3473 {
3474 if (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
3475 return false;
3476
3477 if (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx)))
3478 return false;
3479 }
3480 else
3481 {
3482 if (ad.base
3483 && !(REGNO (ad.base) >= FIRST_PSEUDO_REGISTER
3484 || REGNO_REG_CLASS (REGNO (ad.base)) == ADDR_REGS))
3485 return false;
3486
3487 if (ad.indx
3488 && !(REGNO (ad.indx) >= FIRST_PSEUDO_REGISTER
3489 || REGNO_REG_CLASS (REGNO (ad.indx)) == ADDR_REGS))
3490 return false;
3491 }
3492 return true;
3493 }
3494
3495 /* Return true if OP is a valid operand for the LA instruction.
3496 In 31-bit, we need to prove that the result is used as an
3497 address, as LA performs only a 31-bit addition. */
3498
3499 bool
legitimate_la_operand_p(rtx op)3500 legitimate_la_operand_p (rtx op)
3501 {
3502 struct s390_address addr;
3503 if (!s390_decompose_address (op, &addr))
3504 return false;
3505
3506 return (TARGET_64BIT || addr.pointer);
3507 }
3508
3509 /* Return true if it is valid *and* preferable to use LA to
3510 compute the sum of OP1 and OP2. */
3511
3512 bool
preferred_la_operand_p(rtx op1,rtx op2)3513 preferred_la_operand_p (rtx op1, rtx op2)
3514 {
3515 struct s390_address addr;
3516
3517 if (op2 != const0_rtx)
3518 op1 = gen_rtx_PLUS (Pmode, op1, op2);
3519
3520 if (!s390_decompose_address (op1, &addr))
3521 return false;
3522 if (addr.base && !REGNO_OK_FOR_BASE_P (REGNO (addr.base)))
3523 return false;
3524 if (addr.indx && !REGNO_OK_FOR_INDEX_P (REGNO (addr.indx)))
3525 return false;
3526
3527 /* Avoid LA instructions with index register on z196; it is
3528 preferable to use regular add instructions when possible.
3529 Starting with zEC12 the la with index register is "uncracked"
3530 again. */
3531 if (addr.indx && s390_tune == PROCESSOR_2817_Z196)
3532 return false;
3533
3534 if (!TARGET_64BIT && !addr.pointer)
3535 return false;
3536
3537 if (addr.pointer)
3538 return true;
3539
3540 if ((addr.base && REG_P (addr.base) && REG_POINTER (addr.base))
3541 || (addr.indx && REG_P (addr.indx) && REG_POINTER (addr.indx)))
3542 return true;
3543
3544 return false;
3545 }
3546
3547 /* Emit a forced load-address operation to load SRC into DST.
3548 This will use the LOAD ADDRESS instruction even in situations
3549 where legitimate_la_operand_p (SRC) returns false. */
3550
3551 void
s390_load_address(rtx dst,rtx src)3552 s390_load_address (rtx dst, rtx src)
3553 {
3554 if (TARGET_64BIT)
3555 emit_move_insn (dst, src);
3556 else
3557 emit_insn (gen_force_la_31 (dst, src));
3558 }
3559
3560 /* Return a legitimate reference for ORIG (an address) using the
3561 register REG. If REG is 0, a new pseudo is generated.
3562
3563 There are two types of references that must be handled:
3564
3565 1. Global data references must load the address from the GOT, via
3566 the PIC reg. An insn is emitted to do this load, and the reg is
3567 returned.
3568
3569 2. Static data references, constant pool addresses, and code labels
3570 compute the address as an offset from the GOT, whose base is in
3571 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
3572 differentiate them from global data objects. The returned
3573 address is the PIC reg + an unspec constant.
3574
3575 TARGET_LEGITIMIZE_ADDRESS_P rejects symbolic references unless the PIC
3576 reg also appears in the address. */
3577
3578 rtx
legitimize_pic_address(rtx orig,rtx reg)3579 legitimize_pic_address (rtx orig, rtx reg)
3580 {
3581 rtx addr = orig;
3582 rtx addend = const0_rtx;
3583 rtx new_rtx = orig;
3584
3585 gcc_assert (!TLS_SYMBOLIC_CONST (addr));
3586
3587 if (GET_CODE (addr) == CONST)
3588 addr = XEXP (addr, 0);
3589
3590 if (GET_CODE (addr) == PLUS)
3591 {
3592 addend = XEXP (addr, 1);
3593 addr = XEXP (addr, 0);
3594 }
3595
3596 if ((GET_CODE (addr) == LABEL_REF
3597 || (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (addr))
3598 || (GET_CODE (addr) == UNSPEC &&
3599 (XINT (addr, 1) == UNSPEC_GOTENT
3600 || (TARGET_CPU_ZARCH && XINT (addr, 1) == UNSPEC_PLT))))
3601 && GET_CODE (addend) == CONST_INT)
3602 {
3603 /* This can be locally addressed. */
3604
3605 /* larl_operand requires UNSPECs to be wrapped in a const rtx. */
3606 rtx const_addr = (GET_CODE (addr) == UNSPEC ?
3607 gen_rtx_CONST (Pmode, addr) : addr);
3608
3609 if (TARGET_CPU_ZARCH
3610 && larl_operand (const_addr, VOIDmode)
3611 && INTVAL (addend) < (HOST_WIDE_INT)1 << 31
3612 && INTVAL (addend) >= -((HOST_WIDE_INT)1 << 31))
3613 {
3614 if (INTVAL (addend) & 1)
3615 {
3616 /* LARL can't handle odd offsets, so emit a pair of LARL
3617 and LA. */
3618 rtx temp = reg? reg : gen_reg_rtx (Pmode);
3619
3620 if (!DISP_IN_RANGE (INTVAL (addend)))
3621 {
3622 HOST_WIDE_INT even = INTVAL (addend) - 1;
3623 addr = gen_rtx_PLUS (Pmode, addr, GEN_INT (even));
3624 addr = gen_rtx_CONST (Pmode, addr);
3625 addend = const1_rtx;
3626 }
3627
3628 emit_move_insn (temp, addr);
3629 new_rtx = gen_rtx_PLUS (Pmode, temp, addend);
3630
3631 if (reg != 0)
3632 {
3633 s390_load_address (reg, new_rtx);
3634 new_rtx = reg;
3635 }
3636 }
3637 else
3638 {
3639 /* If the offset is even, we can just use LARL. This
3640 will happen automatically. */
3641 }
3642 }
3643 else
3644 {
3645 /* No larl - Access local symbols relative to the GOT. */
3646
3647 rtx temp = reg? reg : gen_reg_rtx (Pmode);
3648
3649 if (reload_in_progress || reload_completed)
3650 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
3651
3652 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
3653 if (addend != const0_rtx)
3654 addr = gen_rtx_PLUS (Pmode, addr, addend);
3655 addr = gen_rtx_CONST (Pmode, addr);
3656 addr = force_const_mem (Pmode, addr);
3657 emit_move_insn (temp, addr);
3658
3659 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
3660 if (reg != 0)
3661 {
3662 s390_load_address (reg, new_rtx);
3663 new_rtx = reg;
3664 }
3665 }
3666 }
3667 else if (GET_CODE (addr) == SYMBOL_REF && addend == const0_rtx)
3668 {
3669 /* A non-local symbol reference without addend.
3670
3671 The symbol ref is wrapped into an UNSPEC to make sure the
3672 proper operand modifier (@GOT or @GOTENT) will be emitted.
3673 This will tell the linker to put the symbol into the GOT.
3674
3675 Additionally the code dereferencing the GOT slot is emitted here.
3676
3677 An addend to the symref needs to be added afterwards.
3678 legitimize_pic_address calls itself recursively to handle
3679 that case. So no need to do it here. */
3680
3681 if (reg == 0)
3682 reg = gen_reg_rtx (Pmode);
3683
3684 if (TARGET_Z10)
3685 {
3686 /* Use load relative if possible.
3687 lgrl <target>, sym@GOTENT */
3688 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTENT);
3689 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
3690 new_rtx = gen_const_mem (GET_MODE (reg), new_rtx);
3691
3692 emit_move_insn (reg, new_rtx);
3693 new_rtx = reg;
3694 }
3695 else if (flag_pic == 1)
3696 {
3697 /* Assume GOT offset is a valid displacement operand (< 4k
3698 or < 512k with z990). This is handled the same way in
3699 both 31- and 64-bit code (@GOT).
3700 lg <target>, sym@GOT(r12) */
3701
3702 if (reload_in_progress || reload_completed)
3703 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
3704
3705 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
3706 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
3707 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
3708 new_rtx = gen_const_mem (Pmode, new_rtx);
3709 emit_move_insn (reg, new_rtx);
3710 new_rtx = reg;
3711 }
3712 else if (TARGET_CPU_ZARCH)
3713 {
3714 /* If the GOT offset might be >= 4k, we determine the position
3715 of the GOT entry via a PC-relative LARL (@GOTENT).
3716 larl temp, sym@GOTENT
3717 lg <target>, 0(temp) */
3718
3719 rtx temp = reg ? reg : gen_reg_rtx (Pmode);
3720
3721 gcc_assert (REGNO (temp) >= FIRST_PSEUDO_REGISTER
3722 || REGNO_REG_CLASS (REGNO (temp)) == ADDR_REGS);
3723
3724 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTENT);
3725 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
3726 emit_move_insn (temp, new_rtx);
3727
3728 new_rtx = gen_const_mem (Pmode, temp);
3729 emit_move_insn (reg, new_rtx);
3730
3731 new_rtx = reg;
3732 }
3733 else
3734 {
3735 /* If the GOT offset might be >= 4k, we have to load it
3736 from the literal pool (@GOT).
3737
3738 lg temp, lit-litbase(r13)
3739 lg <target>, 0(temp)
3740 lit: .long sym@GOT */
3741
3742 rtx temp = reg ? reg : gen_reg_rtx (Pmode);
3743
3744 gcc_assert (REGNO (temp) >= FIRST_PSEUDO_REGISTER
3745 || REGNO_REG_CLASS (REGNO (temp)) == ADDR_REGS);
3746
3747 if (reload_in_progress || reload_completed)
3748 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
3749
3750 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
3751 addr = gen_rtx_CONST (Pmode, addr);
3752 addr = force_const_mem (Pmode, addr);
3753 emit_move_insn (temp, addr);
3754
3755 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
3756 new_rtx = gen_const_mem (Pmode, new_rtx);
3757 emit_move_insn (reg, new_rtx);
3758 new_rtx = reg;
3759 }
3760 }
3761 else if (GET_CODE (addr) == UNSPEC && GET_CODE (addend) == CONST_INT)
3762 {
3763 gcc_assert (XVECLEN (addr, 0) == 1);
3764 switch (XINT (addr, 1))
3765 {
3766 /* These address symbols (or PLT slots) relative to the GOT
3767 (not GOT slots!). In general this will exceed the
3768 displacement range so these value belong into the literal
3769 pool. */
3770 case UNSPEC_GOTOFF:
3771 case UNSPEC_PLTOFF:
3772 new_rtx = force_const_mem (Pmode, orig);
3773 break;
3774
3775 /* For -fPIC the GOT size might exceed the displacement
3776 range so make sure the value is in the literal pool. */
3777 case UNSPEC_GOT:
3778 if (flag_pic == 2)
3779 new_rtx = force_const_mem (Pmode, orig);
3780 break;
3781
3782 /* For @GOTENT larl is used. This is handled like local
3783 symbol refs. */
3784 case UNSPEC_GOTENT:
3785 gcc_unreachable ();
3786 break;
3787
3788 /* @PLT is OK as is on 64-bit, must be converted to
3789 GOT-relative @PLTOFF on 31-bit. */
3790 case UNSPEC_PLT:
3791 if (!TARGET_CPU_ZARCH)
3792 {
3793 rtx temp = reg? reg : gen_reg_rtx (Pmode);
3794
3795 if (reload_in_progress || reload_completed)
3796 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
3797
3798 addr = XVECEXP (addr, 0, 0);
3799 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
3800 UNSPEC_PLTOFF);
3801 if (addend != const0_rtx)
3802 addr = gen_rtx_PLUS (Pmode, addr, addend);
3803 addr = gen_rtx_CONST (Pmode, addr);
3804 addr = force_const_mem (Pmode, addr);
3805 emit_move_insn (temp, addr);
3806
3807 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
3808 if (reg != 0)
3809 {
3810 s390_load_address (reg, new_rtx);
3811 new_rtx = reg;
3812 }
3813 }
3814 else
3815 /* On 64 bit larl can be used. This case is handled like
3816 local symbol refs. */
3817 gcc_unreachable ();
3818 break;
3819
3820 /* Everything else cannot happen. */
3821 default:
3822 gcc_unreachable ();
3823 }
3824 }
3825 else if (addend != const0_rtx)
3826 {
3827 /* Otherwise, compute the sum. */
3828
3829 rtx base = legitimize_pic_address (addr, reg);
3830 new_rtx = legitimize_pic_address (addend,
3831 base == reg ? NULL_RTX : reg);
3832 if (GET_CODE (new_rtx) == CONST_INT)
3833 new_rtx = plus_constant (Pmode, base, INTVAL (new_rtx));
3834 else
3835 {
3836 if (GET_CODE (new_rtx) == PLUS && CONSTANT_P (XEXP (new_rtx, 1)))
3837 {
3838 base = gen_rtx_PLUS (Pmode, base, XEXP (new_rtx, 0));
3839 new_rtx = XEXP (new_rtx, 1);
3840 }
3841 new_rtx = gen_rtx_PLUS (Pmode, base, new_rtx);
3842 }
3843
3844 if (GET_CODE (new_rtx) == CONST)
3845 new_rtx = XEXP (new_rtx, 0);
3846 new_rtx = force_operand (new_rtx, 0);
3847 }
3848
3849 return new_rtx;
3850 }
3851
3852 /* Load the thread pointer into a register. */
3853
3854 rtx
s390_get_thread_pointer(void)3855 s390_get_thread_pointer (void)
3856 {
3857 rtx tp = gen_reg_rtx (Pmode);
3858
3859 emit_move_insn (tp, gen_rtx_REG (Pmode, TP_REGNUM));
3860 mark_reg_pointer (tp, BITS_PER_WORD);
3861
3862 return tp;
3863 }
3864
3865 /* Emit a tls call insn. The call target is the SYMBOL_REF stored
3866 in s390_tls_symbol which always refers to __tls_get_offset.
3867 The returned offset is written to RESULT_REG and an USE rtx is
3868 generated for TLS_CALL. */
3869
3870 static GTY(()) rtx s390_tls_symbol;
3871
3872 static void
s390_emit_tls_call_insn(rtx result_reg,rtx tls_call)3873 s390_emit_tls_call_insn (rtx result_reg, rtx tls_call)
3874 {
3875 rtx insn;
3876
3877 if (!flag_pic)
3878 emit_insn (s390_load_got ());
3879
3880 if (!s390_tls_symbol)
3881 s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset");
3882
3883 insn = s390_emit_call (s390_tls_symbol, tls_call, result_reg,
3884 gen_rtx_REG (Pmode, RETURN_REGNUM));
3885
3886 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), result_reg);
3887 RTL_CONST_CALL_P (insn) = 1;
3888 }
3889
3890 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
3891 this (thread-local) address. REG may be used as temporary. */
3892
3893 static rtx
legitimize_tls_address(rtx addr,rtx reg)3894 legitimize_tls_address (rtx addr, rtx reg)
3895 {
3896 rtx new_rtx, tls_call, temp, base, r2, insn;
3897
3898 if (GET_CODE (addr) == SYMBOL_REF)
3899 switch (tls_symbolic_operand (addr))
3900 {
3901 case TLS_MODEL_GLOBAL_DYNAMIC:
3902 start_sequence ();
3903 r2 = gen_rtx_REG (Pmode, 2);
3904 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLSGD);
3905 new_rtx = gen_rtx_CONST (Pmode, tls_call);
3906 new_rtx = force_const_mem (Pmode, new_rtx);
3907 emit_move_insn (r2, new_rtx);
3908 s390_emit_tls_call_insn (r2, tls_call);
3909 insn = get_insns ();
3910 end_sequence ();
3911
3912 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
3913 temp = gen_reg_rtx (Pmode);
3914 emit_libcall_block (insn, temp, r2, new_rtx);
3915
3916 new_rtx = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
3917 if (reg != 0)
3918 {
3919 s390_load_address (reg, new_rtx);
3920 new_rtx = reg;
3921 }
3922 break;
3923
3924 case TLS_MODEL_LOCAL_DYNAMIC:
3925 start_sequence ();
3926 r2 = gen_rtx_REG (Pmode, 2);
3927 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM);
3928 new_rtx = gen_rtx_CONST (Pmode, tls_call);
3929 new_rtx = force_const_mem (Pmode, new_rtx);
3930 emit_move_insn (r2, new_rtx);
3931 s390_emit_tls_call_insn (r2, tls_call);
3932 insn = get_insns ();
3933 end_sequence ();
3934
3935 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM_NTPOFF);
3936 temp = gen_reg_rtx (Pmode);
3937 emit_libcall_block (insn, temp, r2, new_rtx);
3938
3939 new_rtx = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
3940 base = gen_reg_rtx (Pmode);
3941 s390_load_address (base, new_rtx);
3942
3943 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_DTPOFF);
3944 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
3945 new_rtx = force_const_mem (Pmode, new_rtx);
3946 temp = gen_reg_rtx (Pmode);
3947 emit_move_insn (temp, new_rtx);
3948
3949 new_rtx = gen_rtx_PLUS (Pmode, base, temp);
3950 if (reg != 0)
3951 {
3952 s390_load_address (reg, new_rtx);
3953 new_rtx = reg;
3954 }
3955 break;
3956
3957 case TLS_MODEL_INITIAL_EXEC:
3958 if (flag_pic == 1)
3959 {
3960 /* Assume GOT offset < 4k. This is handled the same way
3961 in both 31- and 64-bit code. */
3962
3963 if (reload_in_progress || reload_completed)
3964 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
3965
3966 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
3967 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
3968 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
3969 new_rtx = gen_const_mem (Pmode, new_rtx);
3970 temp = gen_reg_rtx (Pmode);
3971 emit_move_insn (temp, new_rtx);
3972 }
3973 else if (TARGET_CPU_ZARCH)
3974 {
3975 /* If the GOT offset might be >= 4k, we determine the position
3976 of the GOT entry via a PC-relative LARL. */
3977
3978 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
3979 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
3980 temp = gen_reg_rtx (Pmode);
3981 emit_move_insn (temp, new_rtx);
3982
3983 new_rtx = gen_const_mem (Pmode, temp);
3984 temp = gen_reg_rtx (Pmode);
3985 emit_move_insn (temp, new_rtx);
3986 }
3987 else if (flag_pic)
3988 {
3989 /* If the GOT offset might be >= 4k, we have to load it
3990 from the literal pool. */
3991
3992 if (reload_in_progress || reload_completed)
3993 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
3994
3995 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
3996 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
3997 new_rtx = force_const_mem (Pmode, new_rtx);
3998 temp = gen_reg_rtx (Pmode);
3999 emit_move_insn (temp, new_rtx);
4000
4001 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
4002 new_rtx = gen_const_mem (Pmode, new_rtx);
4003
4004 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new_rtx, addr), UNSPEC_TLS_LOAD);
4005 temp = gen_reg_rtx (Pmode);
4006 emit_insn (gen_rtx_SET (Pmode, temp, new_rtx));
4007 }
4008 else
4009 {
4010 /* In position-dependent code, load the absolute address of
4011 the GOT entry from the literal pool. */
4012
4013 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
4014 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
4015 new_rtx = force_const_mem (Pmode, new_rtx);
4016 temp = gen_reg_rtx (Pmode);
4017 emit_move_insn (temp, new_rtx);
4018
4019 new_rtx = temp;
4020 new_rtx = gen_const_mem (Pmode, new_rtx);
4021 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new_rtx, addr), UNSPEC_TLS_LOAD);
4022 temp = gen_reg_rtx (Pmode);
4023 emit_insn (gen_rtx_SET (Pmode, temp, new_rtx));
4024 }
4025
4026 new_rtx = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
4027 if (reg != 0)
4028 {
4029 s390_load_address (reg, new_rtx);
4030 new_rtx = reg;
4031 }
4032 break;
4033
4034 case TLS_MODEL_LOCAL_EXEC:
4035 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
4036 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
4037 new_rtx = force_const_mem (Pmode, new_rtx);
4038 temp = gen_reg_rtx (Pmode);
4039 emit_move_insn (temp, new_rtx);
4040
4041 new_rtx = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
4042 if (reg != 0)
4043 {
4044 s390_load_address (reg, new_rtx);
4045 new_rtx = reg;
4046 }
4047 break;
4048
4049 default:
4050 gcc_unreachable ();
4051 }
4052
4053 else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == UNSPEC)
4054 {
4055 switch (XINT (XEXP (addr, 0), 1))
4056 {
4057 case UNSPEC_INDNTPOFF:
4058 gcc_assert (TARGET_CPU_ZARCH);
4059 new_rtx = addr;
4060 break;
4061
4062 default:
4063 gcc_unreachable ();
4064 }
4065 }
4066
4067 else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == PLUS
4068 && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
4069 {
4070 new_rtx = XEXP (XEXP (addr, 0), 0);
4071 if (GET_CODE (new_rtx) != SYMBOL_REF)
4072 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
4073
4074 new_rtx = legitimize_tls_address (new_rtx, reg);
4075 new_rtx = plus_constant (Pmode, new_rtx,
4076 INTVAL (XEXP (XEXP (addr, 0), 1)));
4077 new_rtx = force_operand (new_rtx, 0);
4078 }
4079
4080 else
4081 gcc_unreachable (); /* for now ... */
4082
4083 return new_rtx;
4084 }
4085
4086 /* Emit insns making the address in operands[1] valid for a standard
4087 move to operands[0]. operands[1] is replaced by an address which
4088 should be used instead of the former RTX to emit the move
4089 pattern. */
4090
4091 void
emit_symbolic_move(rtx * operands)4092 emit_symbolic_move (rtx *operands)
4093 {
4094 rtx temp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
4095
4096 if (GET_CODE (operands[0]) == MEM)
4097 operands[1] = force_reg (Pmode, operands[1]);
4098 else if (TLS_SYMBOLIC_CONST (operands[1]))
4099 operands[1] = legitimize_tls_address (operands[1], temp);
4100 else if (flag_pic)
4101 operands[1] = legitimize_pic_address (operands[1], temp);
4102 }
4103
4104 /* Try machine-dependent ways of modifying an illegitimate address X
4105 to be legitimate. If we find one, return the new, valid address.
4106
4107 OLDX is the address as it was before break_out_memory_refs was called.
4108 In some cases it is useful to look at this to decide what needs to be done.
4109
4110 MODE is the mode of the operand pointed to by X.
4111
4112 When -fpic is used, special handling is needed for symbolic references.
4113 See comments by legitimize_pic_address for details. */
4114
4115 static rtx
s390_legitimize_address(rtx x,rtx oldx ATTRIBUTE_UNUSED,enum machine_mode mode ATTRIBUTE_UNUSED)4116 s390_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
4117 enum machine_mode mode ATTRIBUTE_UNUSED)
4118 {
4119 rtx constant_term = const0_rtx;
4120
4121 if (TLS_SYMBOLIC_CONST (x))
4122 {
4123 x = legitimize_tls_address (x, 0);
4124
4125 if (s390_legitimate_address_p (mode, x, FALSE))
4126 return x;
4127 }
4128 else if (GET_CODE (x) == PLUS
4129 && (TLS_SYMBOLIC_CONST (XEXP (x, 0))
4130 || TLS_SYMBOLIC_CONST (XEXP (x, 1))))
4131 {
4132 return x;
4133 }
4134 else if (flag_pic)
4135 {
4136 if (SYMBOLIC_CONST (x)
4137 || (GET_CODE (x) == PLUS
4138 && (SYMBOLIC_CONST (XEXP (x, 0))
4139 || SYMBOLIC_CONST (XEXP (x, 1)))))
4140 x = legitimize_pic_address (x, 0);
4141
4142 if (s390_legitimate_address_p (mode, x, FALSE))
4143 return x;
4144 }
4145
4146 x = eliminate_constant_term (x, &constant_term);
4147
4148 /* Optimize loading of large displacements by splitting them
4149 into the multiple of 4K and the rest; this allows the
4150 former to be CSE'd if possible.
4151
4152 Don't do this if the displacement is added to a register
4153 pointing into the stack frame, as the offsets will
4154 change later anyway. */
4155
4156 if (GET_CODE (constant_term) == CONST_INT
4157 && !TARGET_LONG_DISPLACEMENT
4158 && !DISP_IN_RANGE (INTVAL (constant_term))
4159 && !(REG_P (x) && REGNO_PTR_FRAME_P (REGNO (x))))
4160 {
4161 HOST_WIDE_INT lower = INTVAL (constant_term) & 0xfff;
4162 HOST_WIDE_INT upper = INTVAL (constant_term) ^ lower;
4163
4164 rtx temp = gen_reg_rtx (Pmode);
4165 rtx val = force_operand (GEN_INT (upper), temp);
4166 if (val != temp)
4167 emit_move_insn (temp, val);
4168
4169 x = gen_rtx_PLUS (Pmode, x, temp);
4170 constant_term = GEN_INT (lower);
4171 }
4172
4173 if (GET_CODE (x) == PLUS)
4174 {
4175 if (GET_CODE (XEXP (x, 0)) == REG)
4176 {
4177 rtx temp = gen_reg_rtx (Pmode);
4178 rtx val = force_operand (XEXP (x, 1), temp);
4179 if (val != temp)
4180 emit_move_insn (temp, val);
4181
4182 x = gen_rtx_PLUS (Pmode, XEXP (x, 0), temp);
4183 }
4184
4185 else if (GET_CODE (XEXP (x, 1)) == REG)
4186 {
4187 rtx temp = gen_reg_rtx (Pmode);
4188 rtx val = force_operand (XEXP (x, 0), temp);
4189 if (val != temp)
4190 emit_move_insn (temp, val);
4191
4192 x = gen_rtx_PLUS (Pmode, temp, XEXP (x, 1));
4193 }
4194 }
4195
4196 if (constant_term != const0_rtx)
4197 x = gen_rtx_PLUS (Pmode, x, constant_term);
4198
4199 return x;
4200 }
4201
4202 /* Try a machine-dependent way of reloading an illegitimate address AD
4203 operand. If we find one, push the reload and return the new address.
4204
4205 MODE is the mode of the enclosing MEM. OPNUM is the operand number
4206 and TYPE is the reload type of the current reload. */
4207
4208 rtx
legitimize_reload_address(rtx ad,enum machine_mode mode ATTRIBUTE_UNUSED,int opnum,int type)4209 legitimize_reload_address (rtx ad, enum machine_mode mode ATTRIBUTE_UNUSED,
4210 int opnum, int type)
4211 {
4212 if (!optimize || TARGET_LONG_DISPLACEMENT)
4213 return NULL_RTX;
4214
4215 if (GET_CODE (ad) == PLUS)
4216 {
4217 rtx tem = simplify_binary_operation (PLUS, Pmode,
4218 XEXP (ad, 0), XEXP (ad, 1));
4219 if (tem)
4220 ad = tem;
4221 }
4222
4223 if (GET_CODE (ad) == PLUS
4224 && GET_CODE (XEXP (ad, 0)) == REG
4225 && GET_CODE (XEXP (ad, 1)) == CONST_INT
4226 && !DISP_IN_RANGE (INTVAL (XEXP (ad, 1))))
4227 {
4228 HOST_WIDE_INT lower = INTVAL (XEXP (ad, 1)) & 0xfff;
4229 HOST_WIDE_INT upper = INTVAL (XEXP (ad, 1)) ^ lower;
4230 rtx cst, tem, new_rtx;
4231
4232 cst = GEN_INT (upper);
4233 if (!legitimate_reload_constant_p (cst))
4234 cst = force_const_mem (Pmode, cst);
4235
4236 tem = gen_rtx_PLUS (Pmode, XEXP (ad, 0), cst);
4237 new_rtx = gen_rtx_PLUS (Pmode, tem, GEN_INT (lower));
4238
4239 push_reload (XEXP (tem, 1), 0, &XEXP (tem, 1), 0,
4240 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
4241 opnum, (enum reload_type) type);
4242 return new_rtx;
4243 }
4244
4245 return NULL_RTX;
4246 }
4247
4248 /* Emit code to move LEN bytes from DST to SRC. */
4249
4250 bool
s390_expand_movmem(rtx dst,rtx src,rtx len)4251 s390_expand_movmem (rtx dst, rtx src, rtx len)
4252 {
4253 /* When tuning for z10 or higher we rely on the Glibc functions to
4254 do the right thing. Only for constant lengths below 64k we will
4255 generate inline code. */
4256 if (s390_tune >= PROCESSOR_2097_Z10
4257 && (GET_CODE (len) != CONST_INT || INTVAL (len) > (1<<16)))
4258 return false;
4259
4260 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
4261 {
4262 if (INTVAL (len) > 0)
4263 emit_insn (gen_movmem_short (dst, src, GEN_INT (INTVAL (len) - 1)));
4264 }
4265
4266 else if (TARGET_MVCLE)
4267 {
4268 emit_insn (gen_movmem_long (dst, src, convert_to_mode (Pmode, len, 1)));
4269 }
4270
4271 else
4272 {
4273 rtx dst_addr, src_addr, count, blocks, temp;
4274 rtx loop_start_label = gen_label_rtx ();
4275 rtx loop_end_label = gen_label_rtx ();
4276 rtx end_label = gen_label_rtx ();
4277 enum machine_mode mode;
4278
4279 mode = GET_MODE (len);
4280 if (mode == VOIDmode)
4281 mode = Pmode;
4282
4283 dst_addr = gen_reg_rtx (Pmode);
4284 src_addr = gen_reg_rtx (Pmode);
4285 count = gen_reg_rtx (mode);
4286 blocks = gen_reg_rtx (mode);
4287
4288 convert_move (count, len, 1);
4289 emit_cmp_and_jump_insns (count, const0_rtx,
4290 EQ, NULL_RTX, mode, 1, end_label);
4291
4292 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
4293 emit_move_insn (src_addr, force_operand (XEXP (src, 0), NULL_RTX));
4294 dst = change_address (dst, VOIDmode, dst_addr);
4295 src = change_address (src, VOIDmode, src_addr);
4296
4297 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1,
4298 OPTAB_DIRECT);
4299 if (temp != count)
4300 emit_move_insn (count, temp);
4301
4302 temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1,
4303 OPTAB_DIRECT);
4304 if (temp != blocks)
4305 emit_move_insn (blocks, temp);
4306
4307 emit_cmp_and_jump_insns (blocks, const0_rtx,
4308 EQ, NULL_RTX, mode, 1, loop_end_label);
4309
4310 emit_label (loop_start_label);
4311
4312 if (TARGET_Z10
4313 && (GET_CODE (len) != CONST_INT || INTVAL (len) > 768))
4314 {
4315 rtx prefetch;
4316
4317 /* Issue a read prefetch for the +3 cache line. */
4318 prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, src_addr, GEN_INT (768)),
4319 const0_rtx, const0_rtx);
4320 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
4321 emit_insn (prefetch);
4322
4323 /* Issue a write prefetch for the +3 cache line. */
4324 prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (768)),
4325 const1_rtx, const0_rtx);
4326 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
4327 emit_insn (prefetch);
4328 }
4329
4330 emit_insn (gen_movmem_short (dst, src, GEN_INT (255)));
4331 s390_load_address (dst_addr,
4332 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
4333 s390_load_address (src_addr,
4334 gen_rtx_PLUS (Pmode, src_addr, GEN_INT (256)));
4335
4336 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1,
4337 OPTAB_DIRECT);
4338 if (temp != blocks)
4339 emit_move_insn (blocks, temp);
4340
4341 emit_cmp_and_jump_insns (blocks, const0_rtx,
4342 EQ, NULL_RTX, mode, 1, loop_end_label);
4343
4344 emit_jump (loop_start_label);
4345 emit_label (loop_end_label);
4346
4347 emit_insn (gen_movmem_short (dst, src,
4348 convert_to_mode (Pmode, count, 1)));
4349 emit_label (end_label);
4350 }
4351 return true;
4352 }
4353
4354 /* Emit code to set LEN bytes at DST to VAL.
4355 Make use of clrmem if VAL is zero. */
4356
4357 void
s390_expand_setmem(rtx dst,rtx len,rtx val)4358 s390_expand_setmem (rtx dst, rtx len, rtx val)
4359 {
4360 if (GET_CODE (len) == CONST_INT && INTVAL (len) == 0)
4361 return;
4362
4363 gcc_assert (GET_CODE (val) == CONST_INT || GET_MODE (val) == QImode);
4364
4365 if (GET_CODE (len) == CONST_INT && INTVAL (len) > 0 && INTVAL (len) <= 257)
4366 {
4367 if (val == const0_rtx && INTVAL (len) <= 256)
4368 emit_insn (gen_clrmem_short (dst, GEN_INT (INTVAL (len) - 1)));
4369 else
4370 {
4371 /* Initialize memory by storing the first byte. */
4372 emit_move_insn (adjust_address (dst, QImode, 0), val);
4373
4374 if (INTVAL (len) > 1)
4375 {
4376 /* Initiate 1 byte overlap move.
4377 The first byte of DST is propagated through DSTP1.
4378 Prepare a movmem for: DST+1 = DST (length = LEN - 1).
4379 DST is set to size 1 so the rest of the memory location
4380 does not count as source operand. */
4381 rtx dstp1 = adjust_address (dst, VOIDmode, 1);
4382 set_mem_size (dst, 1);
4383
4384 emit_insn (gen_movmem_short (dstp1, dst,
4385 GEN_INT (INTVAL (len) - 2)));
4386 }
4387 }
4388 }
4389
4390 else if (TARGET_MVCLE)
4391 {
4392 val = force_not_mem (convert_modes (Pmode, QImode, val, 1));
4393 emit_insn (gen_setmem_long (dst, convert_to_mode (Pmode, len, 1), val));
4394 }
4395
4396 else
4397 {
4398 rtx dst_addr, count, blocks, temp, dstp1 = NULL_RTX;
4399 rtx loop_start_label = gen_label_rtx ();
4400 rtx loop_end_label = gen_label_rtx ();
4401 rtx end_label = gen_label_rtx ();
4402 enum machine_mode mode;
4403
4404 mode = GET_MODE (len);
4405 if (mode == VOIDmode)
4406 mode = Pmode;
4407
4408 dst_addr = gen_reg_rtx (Pmode);
4409 count = gen_reg_rtx (mode);
4410 blocks = gen_reg_rtx (mode);
4411
4412 convert_move (count, len, 1);
4413 emit_cmp_and_jump_insns (count, const0_rtx,
4414 EQ, NULL_RTX, mode, 1, end_label);
4415
4416 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
4417 dst = change_address (dst, VOIDmode, dst_addr);
4418
4419 if (val == const0_rtx)
4420 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1,
4421 OPTAB_DIRECT);
4422 else
4423 {
4424 dstp1 = adjust_address (dst, VOIDmode, 1);
4425 set_mem_size (dst, 1);
4426
4427 /* Initialize memory by storing the first byte. */
4428 emit_move_insn (adjust_address (dst, QImode, 0), val);
4429
4430 /* If count is 1 we are done. */
4431 emit_cmp_and_jump_insns (count, const1_rtx,
4432 EQ, NULL_RTX, mode, 1, end_label);
4433
4434 temp = expand_binop (mode, add_optab, count, GEN_INT (-2), count, 1,
4435 OPTAB_DIRECT);
4436 }
4437 if (temp != count)
4438 emit_move_insn (count, temp);
4439
4440 temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1,
4441 OPTAB_DIRECT);
4442 if (temp != blocks)
4443 emit_move_insn (blocks, temp);
4444
4445 emit_cmp_and_jump_insns (blocks, const0_rtx,
4446 EQ, NULL_RTX, mode, 1, loop_end_label);
4447
4448 emit_label (loop_start_label);
4449
4450 if (TARGET_Z10
4451 && (GET_CODE (len) != CONST_INT || INTVAL (len) > 1024))
4452 {
4453 /* Issue a write prefetch for the +4 cache line. */
4454 rtx prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, dst_addr,
4455 GEN_INT (1024)),
4456 const1_rtx, const0_rtx);
4457 emit_insn (prefetch);
4458 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
4459 }
4460
4461 if (val == const0_rtx)
4462 emit_insn (gen_clrmem_short (dst, GEN_INT (255)));
4463 else
4464 emit_insn (gen_movmem_short (dstp1, dst, GEN_INT (255)));
4465 s390_load_address (dst_addr,
4466 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
4467
4468 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1,
4469 OPTAB_DIRECT);
4470 if (temp != blocks)
4471 emit_move_insn (blocks, temp);
4472
4473 emit_cmp_and_jump_insns (blocks, const0_rtx,
4474 EQ, NULL_RTX, mode, 1, loop_end_label);
4475
4476 emit_jump (loop_start_label);
4477 emit_label (loop_end_label);
4478
4479 if (val == const0_rtx)
4480 emit_insn (gen_clrmem_short (dst, convert_to_mode (Pmode, count, 1)));
4481 else
4482 emit_insn (gen_movmem_short (dstp1, dst, convert_to_mode (Pmode, count, 1)));
4483 emit_label (end_label);
4484 }
4485 }
4486
4487 /* Emit code to compare LEN bytes at OP0 with those at OP1,
4488 and return the result in TARGET. */
4489
4490 bool
s390_expand_cmpmem(rtx target,rtx op0,rtx op1,rtx len)4491 s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
4492 {
4493 rtx ccreg = gen_rtx_REG (CCUmode, CC_REGNUM);
4494 rtx tmp;
4495
4496 /* When tuning for z10 or higher we rely on the Glibc functions to
4497 do the right thing. Only for constant lengths below 64k we will
4498 generate inline code. */
4499 if (s390_tune >= PROCESSOR_2097_Z10
4500 && (GET_CODE (len) != CONST_INT || INTVAL (len) > (1<<16)))
4501 return false;
4502
4503 /* As the result of CMPINT is inverted compared to what we need,
4504 we have to swap the operands. */
4505 tmp = op0; op0 = op1; op1 = tmp;
4506
4507 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
4508 {
4509 if (INTVAL (len) > 0)
4510 {
4511 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (INTVAL (len) - 1)));
4512 emit_insn (gen_cmpint (target, ccreg));
4513 }
4514 else
4515 emit_move_insn (target, const0_rtx);
4516 }
4517 else if (TARGET_MVCLE)
4518 {
4519 emit_insn (gen_cmpmem_long (op0, op1, convert_to_mode (Pmode, len, 1)));
4520 emit_insn (gen_cmpint (target, ccreg));
4521 }
4522 else
4523 {
4524 rtx addr0, addr1, count, blocks, temp;
4525 rtx loop_start_label = gen_label_rtx ();
4526 rtx loop_end_label = gen_label_rtx ();
4527 rtx end_label = gen_label_rtx ();
4528 enum machine_mode mode;
4529
4530 mode = GET_MODE (len);
4531 if (mode == VOIDmode)
4532 mode = Pmode;
4533
4534 addr0 = gen_reg_rtx (Pmode);
4535 addr1 = gen_reg_rtx (Pmode);
4536 count = gen_reg_rtx (mode);
4537 blocks = gen_reg_rtx (mode);
4538
4539 convert_move (count, len, 1);
4540 emit_cmp_and_jump_insns (count, const0_rtx,
4541 EQ, NULL_RTX, mode, 1, end_label);
4542
4543 emit_move_insn (addr0, force_operand (XEXP (op0, 0), NULL_RTX));
4544 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
4545 op0 = change_address (op0, VOIDmode, addr0);
4546 op1 = change_address (op1, VOIDmode, addr1);
4547
4548 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1,
4549 OPTAB_DIRECT);
4550 if (temp != count)
4551 emit_move_insn (count, temp);
4552
4553 temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1,
4554 OPTAB_DIRECT);
4555 if (temp != blocks)
4556 emit_move_insn (blocks, temp);
4557
4558 emit_cmp_and_jump_insns (blocks, const0_rtx,
4559 EQ, NULL_RTX, mode, 1, loop_end_label);
4560
4561 emit_label (loop_start_label);
4562
4563 if (TARGET_Z10
4564 && (GET_CODE (len) != CONST_INT || INTVAL (len) > 512))
4565 {
4566 rtx prefetch;
4567
4568 /* Issue a read prefetch for the +2 cache line of operand 1. */
4569 prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, addr0, GEN_INT (512)),
4570 const0_rtx, const0_rtx);
4571 emit_insn (prefetch);
4572 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
4573
4574 /* Issue a read prefetch for the +2 cache line of operand 2. */
4575 prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, addr1, GEN_INT (512)),
4576 const0_rtx, const0_rtx);
4577 emit_insn (prefetch);
4578 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
4579 }
4580
4581 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (255)));
4582 temp = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
4583 temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
4584 gen_rtx_LABEL_REF (VOIDmode, end_label), pc_rtx);
4585 temp = gen_rtx_SET (VOIDmode, pc_rtx, temp);
4586 emit_jump_insn (temp);
4587
4588 s390_load_address (addr0,
4589 gen_rtx_PLUS (Pmode, addr0, GEN_INT (256)));
4590 s390_load_address (addr1,
4591 gen_rtx_PLUS (Pmode, addr1, GEN_INT (256)));
4592
4593 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1,
4594 OPTAB_DIRECT);
4595 if (temp != blocks)
4596 emit_move_insn (blocks, temp);
4597
4598 emit_cmp_and_jump_insns (blocks, const0_rtx,
4599 EQ, NULL_RTX, mode, 1, loop_end_label);
4600
4601 emit_jump (loop_start_label);
4602 emit_label (loop_end_label);
4603
4604 emit_insn (gen_cmpmem_short (op0, op1,
4605 convert_to_mode (Pmode, count, 1)));
4606 emit_label (end_label);
4607
4608 emit_insn (gen_cmpint (target, ccreg));
4609 }
4610 return true;
4611 }
4612
4613
4614 /* Expand conditional increment or decrement using alc/slb instructions.
4615 Should generate code setting DST to either SRC or SRC + INCREMENT,
4616 depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
4617 Returns true if successful, false otherwise.
4618
4619 That makes it possible to implement some if-constructs without jumps e.g.:
4620 (borrow = CC0 | CC1 and carry = CC2 | CC3)
4621 unsigned int a, b, c;
4622 if (a < b) c++; -> CCU b > a -> CC2; c += carry;
4623 if (a < b) c--; -> CCL3 a - b -> borrow; c -= borrow;
4624 if (a <= b) c++; -> CCL3 b - a -> borrow; c += carry;
4625 if (a <= b) c--; -> CCU a <= b -> borrow; c -= borrow;
4626
4627 Checks for EQ and NE with a nonzero value need an additional xor e.g.:
4628 if (a == b) c++; -> CCL3 a ^= b; 0 - a -> borrow; c += carry;
4629 if (a == b) c--; -> CCU a ^= b; a <= 0 -> CC0 | CC1; c -= borrow;
4630 if (a != b) c++; -> CCU a ^= b; a > 0 -> CC2; c += carry;
4631 if (a != b) c--; -> CCL3 a ^= b; 0 - a -> borrow; c -= borrow; */
4632
4633 bool
s390_expand_addcc(enum rtx_code cmp_code,rtx cmp_op0,rtx cmp_op1,rtx dst,rtx src,rtx increment)4634 s390_expand_addcc (enum rtx_code cmp_code, rtx cmp_op0, rtx cmp_op1,
4635 rtx dst, rtx src, rtx increment)
4636 {
4637 enum machine_mode cmp_mode;
4638 enum machine_mode cc_mode;
4639 rtx op_res;
4640 rtx insn;
4641 rtvec p;
4642 int ret;
4643
4644 if ((GET_MODE (cmp_op0) == SImode || GET_MODE (cmp_op0) == VOIDmode)
4645 && (GET_MODE (cmp_op1) == SImode || GET_MODE (cmp_op1) == VOIDmode))
4646 cmp_mode = SImode;
4647 else if ((GET_MODE (cmp_op0) == DImode || GET_MODE (cmp_op0) == VOIDmode)
4648 && (GET_MODE (cmp_op1) == DImode || GET_MODE (cmp_op1) == VOIDmode))
4649 cmp_mode = DImode;
4650 else
4651 return false;
4652
4653 /* Try ADD LOGICAL WITH CARRY. */
4654 if (increment == const1_rtx)
4655 {
4656 /* Determine CC mode to use. */
4657 if (cmp_code == EQ || cmp_code == NE)
4658 {
4659 if (cmp_op1 != const0_rtx)
4660 {
4661 cmp_op0 = expand_simple_binop (cmp_mode, XOR, cmp_op0, cmp_op1,
4662 NULL_RTX, 0, OPTAB_WIDEN);
4663 cmp_op1 = const0_rtx;
4664 }
4665
4666 cmp_code = cmp_code == EQ ? LEU : GTU;
4667 }
4668
4669 if (cmp_code == LTU || cmp_code == LEU)
4670 {
4671 rtx tem = cmp_op0;
4672 cmp_op0 = cmp_op1;
4673 cmp_op1 = tem;
4674 cmp_code = swap_condition (cmp_code);
4675 }
4676
4677 switch (cmp_code)
4678 {
4679 case GTU:
4680 cc_mode = CCUmode;
4681 break;
4682
4683 case GEU:
4684 cc_mode = CCL3mode;
4685 break;
4686
4687 default:
4688 return false;
4689 }
4690
4691 /* Emit comparison instruction pattern. */
4692 if (!register_operand (cmp_op0, cmp_mode))
4693 cmp_op0 = force_reg (cmp_mode, cmp_op0);
4694
4695 insn = gen_rtx_SET (VOIDmode, gen_rtx_REG (cc_mode, CC_REGNUM),
4696 gen_rtx_COMPARE (cc_mode, cmp_op0, cmp_op1));
4697 /* We use insn_invalid_p here to add clobbers if required. */
4698 ret = insn_invalid_p (emit_insn (insn), false);
4699 gcc_assert (!ret);
4700
4701 /* Emit ALC instruction pattern. */
4702 op_res = gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
4703 gen_rtx_REG (cc_mode, CC_REGNUM),
4704 const0_rtx);
4705
4706 if (src != const0_rtx)
4707 {
4708 if (!register_operand (src, GET_MODE (dst)))
4709 src = force_reg (GET_MODE (dst), src);
4710
4711 op_res = gen_rtx_PLUS (GET_MODE (dst), op_res, src);
4712 op_res = gen_rtx_PLUS (GET_MODE (dst), op_res, const0_rtx);
4713 }
4714
4715 p = rtvec_alloc (2);
4716 RTVEC_ELT (p, 0) =
4717 gen_rtx_SET (VOIDmode, dst, op_res);
4718 RTVEC_ELT (p, 1) =
4719 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
4720 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
4721
4722 return true;
4723 }
4724
4725 /* Try SUBTRACT LOGICAL WITH BORROW. */
4726 if (increment == constm1_rtx)
4727 {
4728 /* Determine CC mode to use. */
4729 if (cmp_code == EQ || cmp_code == NE)
4730 {
4731 if (cmp_op1 != const0_rtx)
4732 {
4733 cmp_op0 = expand_simple_binop (cmp_mode, XOR, cmp_op0, cmp_op1,
4734 NULL_RTX, 0, OPTAB_WIDEN);
4735 cmp_op1 = const0_rtx;
4736 }
4737
4738 cmp_code = cmp_code == EQ ? LEU : GTU;
4739 }
4740
4741 if (cmp_code == GTU || cmp_code == GEU)
4742 {
4743 rtx tem = cmp_op0;
4744 cmp_op0 = cmp_op1;
4745 cmp_op1 = tem;
4746 cmp_code = swap_condition (cmp_code);
4747 }
4748
4749 switch (cmp_code)
4750 {
4751 case LEU:
4752 cc_mode = CCUmode;
4753 break;
4754
4755 case LTU:
4756 cc_mode = CCL3mode;
4757 break;
4758
4759 default:
4760 return false;
4761 }
4762
4763 /* Emit comparison instruction pattern. */
4764 if (!register_operand (cmp_op0, cmp_mode))
4765 cmp_op0 = force_reg (cmp_mode, cmp_op0);
4766
4767 insn = gen_rtx_SET (VOIDmode, gen_rtx_REG (cc_mode, CC_REGNUM),
4768 gen_rtx_COMPARE (cc_mode, cmp_op0, cmp_op1));
4769 /* We use insn_invalid_p here to add clobbers if required. */
4770 ret = insn_invalid_p (emit_insn (insn), false);
4771 gcc_assert (!ret);
4772
4773 /* Emit SLB instruction pattern. */
4774 if (!register_operand (src, GET_MODE (dst)))
4775 src = force_reg (GET_MODE (dst), src);
4776
4777 op_res = gen_rtx_MINUS (GET_MODE (dst),
4778 gen_rtx_MINUS (GET_MODE (dst), src, const0_rtx),
4779 gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
4780 gen_rtx_REG (cc_mode, CC_REGNUM),
4781 const0_rtx));
4782 p = rtvec_alloc (2);
4783 RTVEC_ELT (p, 0) =
4784 gen_rtx_SET (VOIDmode, dst, op_res);
4785 RTVEC_ELT (p, 1) =
4786 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
4787 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
4788
4789 return true;
4790 }
4791
4792 return false;
4793 }
4794
4795 /* Expand code for the insv template. Return true if successful. */
4796
4797 bool
s390_expand_insv(rtx dest,rtx op1,rtx op2,rtx src)4798 s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src)
4799 {
4800 int bitsize = INTVAL (op1);
4801 int bitpos = INTVAL (op2);
4802 enum machine_mode mode = GET_MODE (dest);
4803 enum machine_mode smode;
4804 int smode_bsize, mode_bsize;
4805 rtx op, clobber;
4806
4807 if (bitsize + bitpos > GET_MODE_BITSIZE (mode))
4808 return false;
4809
4810 /* Generate INSERT IMMEDIATE (IILL et al). */
4811 /* (set (ze (reg)) (const_int)). */
4812 if (TARGET_ZARCH
4813 && register_operand (dest, word_mode)
4814 && (bitpos % 16) == 0
4815 && (bitsize % 16) == 0
4816 && const_int_operand (src, VOIDmode))
4817 {
4818 HOST_WIDE_INT val = INTVAL (src);
4819 int regpos = bitpos + bitsize;
4820
4821 while (regpos > bitpos)
4822 {
4823 enum machine_mode putmode;
4824 int putsize;
4825
4826 if (TARGET_EXTIMM && (regpos % 32 == 0) && (regpos >= bitpos + 32))
4827 putmode = SImode;
4828 else
4829 putmode = HImode;
4830
4831 putsize = GET_MODE_BITSIZE (putmode);
4832 regpos -= putsize;
4833 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest,
4834 GEN_INT (putsize),
4835 GEN_INT (regpos)),
4836 gen_int_mode (val, putmode));
4837 val >>= putsize;
4838 }
4839 gcc_assert (regpos == bitpos);
4840 return true;
4841 }
4842
4843 smode = smallest_mode_for_size (bitsize, MODE_INT);
4844 smode_bsize = GET_MODE_BITSIZE (smode);
4845 mode_bsize = GET_MODE_BITSIZE (mode);
4846
4847 /* Generate STORE CHARACTERS UNDER MASK (STCM et al). */
4848 if (bitpos == 0
4849 && (bitsize % BITS_PER_UNIT) == 0
4850 && MEM_P (dest)
4851 && (register_operand (src, word_mode)
4852 || const_int_operand (src, VOIDmode)))
4853 {
4854 /* Emit standard pattern if possible. */
4855 if (smode_bsize == bitsize)
4856 {
4857 emit_move_insn (adjust_address (dest, smode, 0),
4858 gen_lowpart (smode, src));
4859 return true;
4860 }
4861
4862 /* (set (ze (mem)) (const_int)). */
4863 else if (const_int_operand (src, VOIDmode))
4864 {
4865 int size = bitsize / BITS_PER_UNIT;
4866 rtx src_mem = adjust_address (force_const_mem (word_mode, src),
4867 BLKmode,
4868 UNITS_PER_WORD - size);
4869
4870 dest = adjust_address (dest, BLKmode, 0);
4871 set_mem_size (dest, size);
4872 s390_expand_movmem (dest, src_mem, GEN_INT (size));
4873 return true;
4874 }
4875
4876 /* (set (ze (mem)) (reg)). */
4877 else if (register_operand (src, word_mode))
4878 {
4879 if (bitsize <= 32)
4880 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest, op1,
4881 const0_rtx), src);
4882 else
4883 {
4884 /* Emit st,stcmh sequence. */
4885 int stcmh_width = bitsize - 32;
4886 int size = stcmh_width / BITS_PER_UNIT;
4887
4888 emit_move_insn (adjust_address (dest, SImode, size),
4889 gen_lowpart (SImode, src));
4890 set_mem_size (dest, size);
4891 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest,
4892 GEN_INT (stcmh_width),
4893 const0_rtx),
4894 gen_rtx_LSHIFTRT (word_mode, src, GEN_INT (32)));
4895 }
4896 return true;
4897 }
4898 }
4899
4900 /* Generate INSERT CHARACTERS UNDER MASK (IC, ICM et al). */
4901 if ((bitpos % BITS_PER_UNIT) == 0
4902 && (bitsize % BITS_PER_UNIT) == 0
4903 && (bitpos & 32) == ((bitpos + bitsize - 1) & 32)
4904 && MEM_P (src)
4905 && (mode == DImode || mode == SImode)
4906 && register_operand (dest, mode))
4907 {
4908 /* Emit a strict_low_part pattern if possible. */
4909 if (smode_bsize == bitsize && bitpos == mode_bsize - smode_bsize)
4910 {
4911 op = gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (smode, dest));
4912 op = gen_rtx_SET (VOIDmode, op, gen_lowpart (smode, src));
4913 clobber = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
4914 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clobber)));
4915 return true;
4916 }
4917
4918 /* ??? There are more powerful versions of ICM that are not
4919 completely represented in the md file. */
4920 }
4921
4922 /* For z10, generate ROTATE THEN INSERT SELECTED BITS (RISBG et al). */
4923 if (TARGET_Z10 && (mode == DImode || mode == SImode))
4924 {
4925 enum machine_mode mode_s = GET_MODE (src);
4926
4927 if (mode_s == VOIDmode)
4928 {
4929 /* Assume const_int etc already in the proper mode. */
4930 src = force_reg (mode, src);
4931 }
4932 else if (mode_s != mode)
4933 {
4934 gcc_assert (GET_MODE_BITSIZE (mode_s) >= bitsize);
4935 src = force_reg (mode_s, src);
4936 src = gen_lowpart (mode, src);
4937 }
4938
4939 op = gen_rtx_ZERO_EXTRACT (mode, dest, op1, op2),
4940 op = gen_rtx_SET (VOIDmode, op, src);
4941
4942 if (!TARGET_ZEC12)
4943 {
4944 clobber = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
4945 op = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clobber));
4946 }
4947 emit_insn (op);
4948
4949 return true;
4950 }
4951
4952 return false;
4953 }
4954
4955 /* A subroutine of s390_expand_cs_hqi and s390_expand_atomic which returns a
4956 register that holds VAL of mode MODE shifted by COUNT bits. */
4957
4958 static inline rtx
s390_expand_mask_and_shift(rtx val,enum machine_mode mode,rtx count)4959 s390_expand_mask_and_shift (rtx val, enum machine_mode mode, rtx count)
4960 {
4961 val = expand_simple_binop (SImode, AND, val, GEN_INT (GET_MODE_MASK (mode)),
4962 NULL_RTX, 1, OPTAB_DIRECT);
4963 return expand_simple_binop (SImode, ASHIFT, val, count,
4964 NULL_RTX, 1, OPTAB_DIRECT);
4965 }
4966
4967 /* Structure to hold the initial parameters for a compare_and_swap operation
4968 in HImode and QImode. */
4969
4970 struct alignment_context
4971 {
4972 rtx memsi; /* SI aligned memory location. */
4973 rtx shift; /* Bit offset with regard to lsb. */
4974 rtx modemask; /* Mask of the HQImode shifted by SHIFT bits. */
4975 rtx modemaski; /* ~modemask */
4976 bool aligned; /* True if memory is aligned, false else. */
4977 };
4978
4979 /* A subroutine of s390_expand_cs_hqi and s390_expand_atomic to initialize
4980 structure AC for transparent simplifying, if the memory alignment is known
4981 to be at least 32bit. MEM is the memory location for the actual operation
4982 and MODE its mode. */
4983
4984 static void
init_alignment_context(struct alignment_context * ac,rtx mem,enum machine_mode mode)4985 init_alignment_context (struct alignment_context *ac, rtx mem,
4986 enum machine_mode mode)
4987 {
4988 ac->shift = GEN_INT (GET_MODE_SIZE (SImode) - GET_MODE_SIZE (mode));
4989 ac->aligned = (MEM_ALIGN (mem) >= GET_MODE_BITSIZE (SImode));
4990
4991 if (ac->aligned)
4992 ac->memsi = adjust_address (mem, SImode, 0); /* Memory is aligned. */
4993 else
4994 {
4995 /* Alignment is unknown. */
4996 rtx byteoffset, addr, align;
4997
4998 /* Force the address into a register. */
4999 addr = force_reg (Pmode, XEXP (mem, 0));
5000
5001 /* Align it to SImode. */
5002 align = expand_simple_binop (Pmode, AND, addr,
5003 GEN_INT (-GET_MODE_SIZE (SImode)),
5004 NULL_RTX, 1, OPTAB_DIRECT);
5005 /* Generate MEM. */
5006 ac->memsi = gen_rtx_MEM (SImode, align);
5007 MEM_VOLATILE_P (ac->memsi) = MEM_VOLATILE_P (mem);
5008 set_mem_alias_set (ac->memsi, ALIAS_SET_MEMORY_BARRIER);
5009 set_mem_align (ac->memsi, GET_MODE_BITSIZE (SImode));
5010
5011 /* Calculate shiftcount. */
5012 byteoffset = expand_simple_binop (Pmode, AND, addr,
5013 GEN_INT (GET_MODE_SIZE (SImode) - 1),
5014 NULL_RTX, 1, OPTAB_DIRECT);
5015 /* As we already have some offset, evaluate the remaining distance. */
5016 ac->shift = expand_simple_binop (SImode, MINUS, ac->shift, byteoffset,
5017 NULL_RTX, 1, OPTAB_DIRECT);
5018 }
5019
5020 /* Shift is the byte count, but we need the bitcount. */
5021 ac->shift = expand_simple_binop (SImode, ASHIFT, ac->shift, GEN_INT (3),
5022 NULL_RTX, 1, OPTAB_DIRECT);
5023
5024 /* Calculate masks. */
5025 ac->modemask = expand_simple_binop (SImode, ASHIFT,
5026 GEN_INT (GET_MODE_MASK (mode)),
5027 ac->shift, NULL_RTX, 1, OPTAB_DIRECT);
5028 ac->modemaski = expand_simple_unop (SImode, NOT, ac->modemask,
5029 NULL_RTX, 1);
5030 }
5031
5032 /* A subroutine of s390_expand_cs_hqi. Insert INS into VAL. If possible,
5033 use a single insv insn into SEQ2. Otherwise, put prep insns in SEQ1 and
5034 perform the merge in SEQ2. */
5035
5036 static rtx
s390_two_part_insv(struct alignment_context * ac,rtx * seq1,rtx * seq2,enum machine_mode mode,rtx val,rtx ins)5037 s390_two_part_insv (struct alignment_context *ac, rtx *seq1, rtx *seq2,
5038 enum machine_mode mode, rtx val, rtx ins)
5039 {
5040 rtx tmp;
5041
5042 if (ac->aligned)
5043 {
5044 start_sequence ();
5045 tmp = copy_to_mode_reg (SImode, val);
5046 if (s390_expand_insv (tmp, GEN_INT (GET_MODE_BITSIZE (mode)),
5047 const0_rtx, ins))
5048 {
5049 *seq1 = NULL;
5050 *seq2 = get_insns ();
5051 end_sequence ();
5052 return tmp;
5053 }
5054 end_sequence ();
5055 }
5056
5057 /* Failed to use insv. Generate a two part shift and mask. */
5058 start_sequence ();
5059 tmp = s390_expand_mask_and_shift (ins, mode, ac->shift);
5060 *seq1 = get_insns ();
5061 end_sequence ();
5062
5063 start_sequence ();
5064 tmp = expand_simple_binop (SImode, IOR, tmp, val, NULL_RTX, 1, OPTAB_DIRECT);
5065 *seq2 = get_insns ();
5066 end_sequence ();
5067
5068 return tmp;
5069 }
5070
5071 /* Expand an atomic compare and swap operation for HImode and QImode. MEM is
5072 the memory location, CMP the old value to compare MEM with and NEW_RTX the
5073 value to set if CMP == MEM. */
5074
5075 void
s390_expand_cs_hqi(enum machine_mode mode,rtx btarget,rtx vtarget,rtx mem,rtx cmp,rtx new_rtx,bool is_weak)5076 s390_expand_cs_hqi (enum machine_mode mode, rtx btarget, rtx vtarget, rtx mem,
5077 rtx cmp, rtx new_rtx, bool is_weak)
5078 {
5079 struct alignment_context ac;
5080 rtx cmpv, newv, val, cc, seq0, seq1, seq2, seq3;
5081 rtx res = gen_reg_rtx (SImode);
5082 rtx csloop = NULL, csend = NULL;
5083
5084 gcc_assert (MEM_P (mem));
5085
5086 init_alignment_context (&ac, mem, mode);
5087
5088 /* Load full word. Subsequent loads are performed by CS. */
5089 val = expand_simple_binop (SImode, AND, ac.memsi, ac.modemaski,
5090 NULL_RTX, 1, OPTAB_DIRECT);
5091
5092 /* Prepare insertions of cmp and new_rtx into the loaded value. When
5093 possible, we try to use insv to make this happen efficiently. If
5094 that fails we'll generate code both inside and outside the loop. */
5095 cmpv = s390_two_part_insv (&ac, &seq0, &seq2, mode, val, cmp);
5096 newv = s390_two_part_insv (&ac, &seq1, &seq3, mode, val, new_rtx);
5097
5098 if (seq0)
5099 emit_insn (seq0);
5100 if (seq1)
5101 emit_insn (seq1);
5102
5103 /* Start CS loop. */
5104 if (!is_weak)
5105 {
5106 /* Begin assuming success. */
5107 emit_move_insn (btarget, const1_rtx);
5108
5109 csloop = gen_label_rtx ();
5110 csend = gen_label_rtx ();
5111 emit_label (csloop);
5112 }
5113
5114 /* val = "<mem>00..0<mem>"
5115 * cmp = "00..0<cmp>00..0"
5116 * new = "00..0<new>00..0"
5117 */
5118
5119 emit_insn (seq2);
5120 emit_insn (seq3);
5121
5122 cc = s390_emit_compare_and_swap (EQ, res, ac.memsi, cmpv, newv);
5123 if (is_weak)
5124 emit_insn (gen_cstorecc4 (btarget, cc, XEXP (cc, 0), XEXP (cc, 1)));
5125 else
5126 {
5127 rtx tmp;
5128
5129 /* Jump to end if we're done (likely?). */
5130 s390_emit_jump (csend, cc);
5131
5132 /* Check for changes outside mode, and loop internal if so.
5133 Arrange the moves so that the compare is adjacent to the
5134 branch so that we can generate CRJ. */
5135 tmp = copy_to_reg (val);
5136 force_expand_binop (SImode, and_optab, res, ac.modemaski, val,
5137 1, OPTAB_DIRECT);
5138 cc = s390_emit_compare (NE, val, tmp);
5139 s390_emit_jump (csloop, cc);
5140
5141 /* Failed. */
5142 emit_move_insn (btarget, const0_rtx);
5143 emit_label (csend);
5144 }
5145
5146 /* Return the correct part of the bitfield. */
5147 convert_move (vtarget, expand_simple_binop (SImode, LSHIFTRT, res, ac.shift,
5148 NULL_RTX, 1, OPTAB_DIRECT), 1);
5149 }
5150
5151 /* Expand an atomic operation CODE of mode MODE. MEM is the memory location
5152 and VAL the value to play with. If AFTER is true then store the value
5153 MEM holds after the operation, if AFTER is false then store the value MEM
5154 holds before the operation. If TARGET is zero then discard that value, else
5155 store it to TARGET. */
5156
5157 void
s390_expand_atomic(enum machine_mode mode,enum rtx_code code,rtx target,rtx mem,rtx val,bool after)5158 s390_expand_atomic (enum machine_mode mode, enum rtx_code code,
5159 rtx target, rtx mem, rtx val, bool after)
5160 {
5161 struct alignment_context ac;
5162 rtx cmp;
5163 rtx new_rtx = gen_reg_rtx (SImode);
5164 rtx orig = gen_reg_rtx (SImode);
5165 rtx csloop = gen_label_rtx ();
5166
5167 gcc_assert (!target || register_operand (target, VOIDmode));
5168 gcc_assert (MEM_P (mem));
5169
5170 init_alignment_context (&ac, mem, mode);
5171
5172 /* Shift val to the correct bit positions.
5173 Preserve "icm", but prevent "ex icm". */
5174 if (!(ac.aligned && code == SET && MEM_P (val)))
5175 val = s390_expand_mask_and_shift (val, mode, ac.shift);
5176
5177 /* Further preparation insns. */
5178 if (code == PLUS || code == MINUS)
5179 emit_move_insn (orig, val);
5180 else if (code == MULT || code == AND) /* val = "11..1<val>11..1" */
5181 val = expand_simple_binop (SImode, XOR, val, ac.modemaski,
5182 NULL_RTX, 1, OPTAB_DIRECT);
5183
5184 /* Load full word. Subsequent loads are performed by CS. */
5185 cmp = force_reg (SImode, ac.memsi);
5186
5187 /* Start CS loop. */
5188 emit_label (csloop);
5189 emit_move_insn (new_rtx, cmp);
5190
5191 /* Patch new with val at correct position. */
5192 switch (code)
5193 {
5194 case PLUS:
5195 case MINUS:
5196 val = expand_simple_binop (SImode, code, new_rtx, orig,
5197 NULL_RTX, 1, OPTAB_DIRECT);
5198 val = expand_simple_binop (SImode, AND, val, ac.modemask,
5199 NULL_RTX, 1, OPTAB_DIRECT);
5200 /* FALLTHRU */
5201 case SET:
5202 if (ac.aligned && MEM_P (val))
5203 store_bit_field (new_rtx, GET_MODE_BITSIZE (mode), 0,
5204 0, 0, SImode, val);
5205 else
5206 {
5207 new_rtx = expand_simple_binop (SImode, AND, new_rtx, ac.modemaski,
5208 NULL_RTX, 1, OPTAB_DIRECT);
5209 new_rtx = expand_simple_binop (SImode, IOR, new_rtx, val,
5210 NULL_RTX, 1, OPTAB_DIRECT);
5211 }
5212 break;
5213 case AND:
5214 case IOR:
5215 case XOR:
5216 new_rtx = expand_simple_binop (SImode, code, new_rtx, val,
5217 NULL_RTX, 1, OPTAB_DIRECT);
5218 break;
5219 case MULT: /* NAND */
5220 new_rtx = expand_simple_binop (SImode, AND, new_rtx, val,
5221 NULL_RTX, 1, OPTAB_DIRECT);
5222 new_rtx = expand_simple_binop (SImode, XOR, new_rtx, ac.modemask,
5223 NULL_RTX, 1, OPTAB_DIRECT);
5224 break;
5225 default:
5226 gcc_unreachable ();
5227 }
5228
5229 s390_emit_jump (csloop, s390_emit_compare_and_swap (NE, cmp,
5230 ac.memsi, cmp, new_rtx));
5231
5232 /* Return the correct part of the bitfield. */
5233 if (target)
5234 convert_move (target, expand_simple_binop (SImode, LSHIFTRT,
5235 after ? new_rtx : cmp, ac.shift,
5236 NULL_RTX, 1, OPTAB_DIRECT), 1);
5237 }
5238
5239 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5240 We need to emit DTP-relative relocations. */
5241
5242 static void s390_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
5243
5244 static void
s390_output_dwarf_dtprel(FILE * file,int size,rtx x)5245 s390_output_dwarf_dtprel (FILE *file, int size, rtx x)
5246 {
5247 switch (size)
5248 {
5249 case 4:
5250 fputs ("\t.long\t", file);
5251 break;
5252 case 8:
5253 fputs ("\t.quad\t", file);
5254 break;
5255 default:
5256 gcc_unreachable ();
5257 }
5258 output_addr_const (file, x);
5259 fputs ("@DTPOFF", file);
5260 }
5261
5262 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
5263 /* Implement TARGET_MANGLE_TYPE. */
5264
5265 static const char *
s390_mangle_type(const_tree type)5266 s390_mangle_type (const_tree type)
5267 {
5268 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
5269 && TARGET_LONG_DOUBLE_128)
5270 return "g";
5271
5272 /* For all other types, use normal C++ mangling. */
5273 return NULL;
5274 }
5275 #endif
5276
5277 /* In the name of slightly smaller debug output, and to cater to
5278 general assembler lossage, recognize various UNSPEC sequences
5279 and turn them back into a direct symbol reference. */
5280
5281 static rtx
s390_delegitimize_address(rtx orig_x)5282 s390_delegitimize_address (rtx orig_x)
5283 {
5284 rtx x, y;
5285
5286 orig_x = delegitimize_mem_from_attrs (orig_x);
5287 x = orig_x;
5288
5289 /* Extract the symbol ref from:
5290 (plus:SI (reg:SI 12 %r12)
5291 (const:SI (unspec:SI [(symbol_ref/f:SI ("*.LC0"))]
5292 UNSPEC_GOTOFF/PLTOFF)))
5293 and
5294 (plus:SI (reg:SI 12 %r12)
5295 (const:SI (plus:SI (unspec:SI [(symbol_ref:SI ("L"))]
5296 UNSPEC_GOTOFF/PLTOFF)
5297 (const_int 4 [0x4])))) */
5298 if (GET_CODE (x) == PLUS
5299 && REG_P (XEXP (x, 0))
5300 && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM
5301 && GET_CODE (XEXP (x, 1)) == CONST)
5302 {
5303 HOST_WIDE_INT offset = 0;
5304
5305 /* The const operand. */
5306 y = XEXP (XEXP (x, 1), 0);
5307
5308 if (GET_CODE (y) == PLUS
5309 && GET_CODE (XEXP (y, 1)) == CONST_INT)
5310 {
5311 offset = INTVAL (XEXP (y, 1));
5312 y = XEXP (y, 0);
5313 }
5314
5315 if (GET_CODE (y) == UNSPEC
5316 && (XINT (y, 1) == UNSPEC_GOTOFF
5317 || XINT (y, 1) == UNSPEC_PLTOFF))
5318 return plus_constant (Pmode, XVECEXP (y, 0, 0), offset);
5319 }
5320
5321 if (GET_CODE (x) != MEM)
5322 return orig_x;
5323
5324 x = XEXP (x, 0);
5325 if (GET_CODE (x) == PLUS
5326 && GET_CODE (XEXP (x, 1)) == CONST
5327 && GET_CODE (XEXP (x, 0)) == REG
5328 && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM)
5329 {
5330 y = XEXP (XEXP (x, 1), 0);
5331 if (GET_CODE (y) == UNSPEC
5332 && XINT (y, 1) == UNSPEC_GOT)
5333 y = XVECEXP (y, 0, 0);
5334 else
5335 return orig_x;
5336 }
5337 else if (GET_CODE (x) == CONST)
5338 {
5339 /* Extract the symbol ref from:
5340 (mem:QI (const:DI (unspec:DI [(symbol_ref:DI ("foo"))]
5341 UNSPEC_PLT/GOTENT))) */
5342
5343 y = XEXP (x, 0);
5344 if (GET_CODE (y) == UNSPEC
5345 && (XINT (y, 1) == UNSPEC_GOTENT
5346 || XINT (y, 1) == UNSPEC_PLT))
5347 y = XVECEXP (y, 0, 0);
5348 else
5349 return orig_x;
5350 }
5351 else
5352 return orig_x;
5353
5354 if (GET_MODE (orig_x) != Pmode)
5355 {
5356 if (GET_MODE (orig_x) == BLKmode)
5357 return orig_x;
5358 y = lowpart_subreg (GET_MODE (orig_x), y, Pmode);
5359 if (y == NULL_RTX)
5360 return orig_x;
5361 }
5362 return y;
5363 }
5364
5365 /* Output operand OP to stdio stream FILE.
5366 OP is an address (register + offset) which is not used to address data;
5367 instead the rightmost bits are interpreted as the value. */
5368
5369 static void
print_shift_count_operand(FILE * file,rtx op)5370 print_shift_count_operand (FILE *file, rtx op)
5371 {
5372 HOST_WIDE_INT offset;
5373 rtx base;
5374
5375 /* Extract base register and offset. */
5376 if (!s390_decompose_shift_count (op, &base, &offset))
5377 gcc_unreachable ();
5378
5379 /* Sanity check. */
5380 if (base)
5381 {
5382 gcc_assert (GET_CODE (base) == REG);
5383 gcc_assert (REGNO (base) < FIRST_PSEUDO_REGISTER);
5384 gcc_assert (REGNO_REG_CLASS (REGNO (base)) == ADDR_REGS);
5385 }
5386
5387 /* Offsets are constricted to twelve bits. */
5388 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset & ((1 << 12) - 1));
5389 if (base)
5390 fprintf (file, "(%s)", reg_names[REGNO (base)]);
5391 }
5392
5393 /* See 'get_some_local_dynamic_name'. */
5394
5395 static int
get_some_local_dynamic_name_1(rtx * px,void * data ATTRIBUTE_UNUSED)5396 get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
5397 {
5398 rtx x = *px;
5399
5400 if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
5401 {
5402 x = get_pool_constant (x);
5403 return for_each_rtx (&x, get_some_local_dynamic_name_1, 0);
5404 }
5405
5406 if (GET_CODE (x) == SYMBOL_REF
5407 && tls_symbolic_operand (x) == TLS_MODEL_LOCAL_DYNAMIC)
5408 {
5409 cfun->machine->some_ld_name = XSTR (x, 0);
5410 return 1;
5411 }
5412
5413 return 0;
5414 }
5415
5416 /* Locate some local-dynamic symbol still in use by this function
5417 so that we can print its name in local-dynamic base patterns. */
5418
5419 static const char *
get_some_local_dynamic_name(void)5420 get_some_local_dynamic_name (void)
5421 {
5422 rtx insn;
5423
5424 if (cfun->machine->some_ld_name)
5425 return cfun->machine->some_ld_name;
5426
5427 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
5428 if (INSN_P (insn)
5429 && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
5430 return cfun->machine->some_ld_name;
5431
5432 gcc_unreachable ();
5433 }
5434
5435 /* Assigns the number of NOP halfwords to be emitted before and after the
5436 function label to *HW_BEFORE and *HW_AFTER. Both pointers must not be NULL.
5437 If hotpatching is disabled for the function, the values are set to zero.
5438 */
5439
5440 static void
s390_function_num_hotpatch_hw(tree decl,int * hw_before,int * hw_after)5441 s390_function_num_hotpatch_hw (tree decl,
5442 int *hw_before,
5443 int *hw_after)
5444 {
5445 tree attr;
5446
5447 attr = lookup_attribute ("hotpatch", DECL_ATTRIBUTES (decl));
5448
5449 if (attr)
5450 {
5451 tree args = TREE_VALUE (attr);
5452
5453 /* If the hotpatch attribute is present, its values are used even if the
5454 -mhotpatch cmdline option is used. */
5455 *hw_before = TREE_INT_CST_LOW (TREE_VALUE (args));
5456 *hw_after = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (args)));
5457 }
5458 else
5459 {
5460 /* Values specified by the -mhotpatch cmdline option. */
5461 *hw_before = s390_hotpatch_hw_before_label;
5462 *hw_after = s390_hotpatch_hw_after_label;
5463 }
5464 }
5465
5466
5467 /* Write the extra assembler code needed to declare a function properly. */
5468
5469 void
s390_asm_output_function_label(FILE * asm_out_file,const char * fname,tree decl)5470 s390_asm_output_function_label (FILE *asm_out_file, const char *fname,
5471 tree decl)
5472 {
5473 int hw_before, hw_after;
5474
5475 s390_function_num_hotpatch_hw (decl, &hw_before, &hw_after);
5476 if (hw_before > 0)
5477 {
5478 unsigned int function_alignment;
5479 int i;
5480
5481 /* Add trampoline code area before the function label and initialize it
5482 with two-byte NOP instructions. This area can be overwritten with code
5483 that jumps to a patched version of the function. */
5484 asm_fprintf (asm_out_file, "\tnopr\t%%r7"
5485 "\t# pre-label NOPs for hotpatch (%d halfwords)\n",
5486 hw_before);
5487 for (i = 1; i < hw_before; i++)
5488 fputs ("\tnopr\t%r7\n", asm_out_file);
5489
5490 /* Note: The function label must be aligned so that (a) the bytes of the
5491 following NOP do not cross a cacheline boundary, and (b) a jump address
5492 (eight bytes for 64 bit targets, 4 bytes for 32 bit targets) can be
5493 stored directly before the label without crossing a cacheline
5494 boundary. All this is necessary to make sure the trampoline code can
5495 be changed atomically.
5496 This alignment is done automatically using the FOUNCTION_BOUNDARY
5497 macro, but if there are NOPs before the function label, the alignment
5498 is placed before them. So it is necessary to duplicate the alignment
5499 after the NOPs. */
5500 function_alignment = MAX (8, DECL_ALIGN (decl) / BITS_PER_UNIT);
5501 if (! DECL_USER_ALIGN (decl))
5502 function_alignment = MAX (function_alignment,
5503 (unsigned int) align_functions);
5504 fputs ("\t# alignment for hotpatch\n", asm_out_file);
5505 ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (function_alignment));
5506 }
5507
5508 ASM_OUTPUT_LABEL (asm_out_file, fname);
5509 if (hw_after > 0)
5510 asm_fprintf (asm_out_file,
5511 "\t# post-label NOPs for hotpatch (%d halfwords)\n",
5512 hw_after);
5513 }
5514
5515 /* Output machine-dependent UNSPECs occurring in address constant X
5516 in assembler syntax to stdio stream FILE. Returns true if the
5517 constant X could be recognized, false otherwise. */
5518
5519 static bool
s390_output_addr_const_extra(FILE * file,rtx x)5520 s390_output_addr_const_extra (FILE *file, rtx x)
5521 {
5522 if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 1)
5523 switch (XINT (x, 1))
5524 {
5525 case UNSPEC_GOTENT:
5526 output_addr_const (file, XVECEXP (x, 0, 0));
5527 fprintf (file, "@GOTENT");
5528 return true;
5529 case UNSPEC_GOT:
5530 output_addr_const (file, XVECEXP (x, 0, 0));
5531 fprintf (file, "@GOT");
5532 return true;
5533 case UNSPEC_GOTOFF:
5534 output_addr_const (file, XVECEXP (x, 0, 0));
5535 fprintf (file, "@GOTOFF");
5536 return true;
5537 case UNSPEC_PLT:
5538 output_addr_const (file, XVECEXP (x, 0, 0));
5539 fprintf (file, "@PLT");
5540 return true;
5541 case UNSPEC_PLTOFF:
5542 output_addr_const (file, XVECEXP (x, 0, 0));
5543 fprintf (file, "@PLTOFF");
5544 return true;
5545 case UNSPEC_TLSGD:
5546 output_addr_const (file, XVECEXP (x, 0, 0));
5547 fprintf (file, "@TLSGD");
5548 return true;
5549 case UNSPEC_TLSLDM:
5550 assemble_name (file, get_some_local_dynamic_name ());
5551 fprintf (file, "@TLSLDM");
5552 return true;
5553 case UNSPEC_DTPOFF:
5554 output_addr_const (file, XVECEXP (x, 0, 0));
5555 fprintf (file, "@DTPOFF");
5556 return true;
5557 case UNSPEC_NTPOFF:
5558 output_addr_const (file, XVECEXP (x, 0, 0));
5559 fprintf (file, "@NTPOFF");
5560 return true;
5561 case UNSPEC_GOTNTPOFF:
5562 output_addr_const (file, XVECEXP (x, 0, 0));
5563 fprintf (file, "@GOTNTPOFF");
5564 return true;
5565 case UNSPEC_INDNTPOFF:
5566 output_addr_const (file, XVECEXP (x, 0, 0));
5567 fprintf (file, "@INDNTPOFF");
5568 return true;
5569 }
5570
5571 if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 2)
5572 switch (XINT (x, 1))
5573 {
5574 case UNSPEC_POOL_OFFSET:
5575 x = gen_rtx_MINUS (GET_MODE (x), XVECEXP (x, 0, 0), XVECEXP (x, 0, 1));
5576 output_addr_const (file, x);
5577 return true;
5578 }
5579 return false;
5580 }
5581
5582 /* Output address operand ADDR in assembler syntax to
5583 stdio stream FILE. */
5584
5585 void
print_operand_address(FILE * file,rtx addr)5586 print_operand_address (FILE *file, rtx addr)
5587 {
5588 struct s390_address ad;
5589
5590 if (s390_loadrelative_operand_p (addr, NULL, NULL))
5591 {
5592 if (!TARGET_Z10)
5593 {
5594 output_operand_lossage ("symbolic memory references are "
5595 "only supported on z10 or later");
5596 return;
5597 }
5598 output_addr_const (file, addr);
5599 return;
5600 }
5601
5602 if (!s390_decompose_address (addr, &ad)
5603 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
5604 || (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx))))
5605 output_operand_lossage ("cannot decompose address");
5606
5607 if (ad.disp)
5608 output_addr_const (file, ad.disp);
5609 else
5610 fprintf (file, "0");
5611
5612 if (ad.base && ad.indx)
5613 fprintf (file, "(%s,%s)", reg_names[REGNO (ad.indx)],
5614 reg_names[REGNO (ad.base)]);
5615 else if (ad.base)
5616 fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
5617 }
5618
5619 /* Output operand X in assembler syntax to stdio stream FILE.
5620 CODE specified the format flag. The following format flags
5621 are recognized:
5622
5623 'C': print opcode suffix for branch condition.
5624 'D': print opcode suffix for inverse branch condition.
5625 'E': print opcode suffix for branch on index instruction.
5626 'G': print the size of the operand in bytes.
5627 'J': print tls_load/tls_gdcall/tls_ldcall suffix
5628 'M': print the second word of a TImode operand.
5629 'N': print the second word of a DImode operand.
5630 'O': print only the displacement of a memory reference.
5631 'R': print only the base register of a memory reference.
5632 'S': print S-type memory reference (base+displacement).
5633 'Y': print shift count operand.
5634
5635 'b': print integer X as if it's an unsigned byte.
5636 'c': print integer X as if it's an signed byte.
5637 'e': "end" of DImode contiguous bitmask X.
5638 'f': "end" of SImode contiguous bitmask X.
5639 'h': print integer X as if it's a signed halfword.
5640 'i': print the first nonzero HImode part of X.
5641 'j': print the first HImode part unequal to -1 of X.
5642 'k': print the first nonzero SImode part of X.
5643 'm': print the first SImode part unequal to -1 of X.
5644 'o': print integer X as if it's an unsigned 32bit word.
5645 's': "start" of DImode contiguous bitmask X.
5646 't': "start" of SImode contiguous bitmask X.
5647 'x': print integer X as if it's an unsigned halfword.
5648 */
5649
5650 void
print_operand(FILE * file,rtx x,int code)5651 print_operand (FILE *file, rtx x, int code)
5652 {
5653 HOST_WIDE_INT ival;
5654
5655 switch (code)
5656 {
5657 case 'C':
5658 fprintf (file, s390_branch_condition_mnemonic (x, FALSE));
5659 return;
5660
5661 case 'D':
5662 fprintf (file, s390_branch_condition_mnemonic (x, TRUE));
5663 return;
5664
5665 case 'E':
5666 if (GET_CODE (x) == LE)
5667 fprintf (file, "l");
5668 else if (GET_CODE (x) == GT)
5669 fprintf (file, "h");
5670 else
5671 output_operand_lossage ("invalid comparison operator "
5672 "for 'E' output modifier");
5673 return;
5674
5675 case 'J':
5676 if (GET_CODE (x) == SYMBOL_REF)
5677 {
5678 fprintf (file, "%s", ":tls_load:");
5679 output_addr_const (file, x);
5680 }
5681 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD)
5682 {
5683 fprintf (file, "%s", ":tls_gdcall:");
5684 output_addr_const (file, XVECEXP (x, 0, 0));
5685 }
5686 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM)
5687 {
5688 fprintf (file, "%s", ":tls_ldcall:");
5689 assemble_name (file, get_some_local_dynamic_name ());
5690 }
5691 else
5692 output_operand_lossage ("invalid reference for 'J' output modifier");
5693 return;
5694
5695 case 'G':
5696 fprintf (file, "%u", GET_MODE_SIZE (GET_MODE (x)));
5697 return;
5698
5699 case 'O':
5700 {
5701 struct s390_address ad;
5702 int ret;
5703
5704 if (!MEM_P (x))
5705 {
5706 output_operand_lossage ("memory reference expected for "
5707 "'O' output modifier");
5708 return;
5709 }
5710
5711 ret = s390_decompose_address (XEXP (x, 0), &ad);
5712
5713 if (!ret
5714 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
5715 || ad.indx)
5716 {
5717 output_operand_lossage ("invalid address for 'O' output modifier");
5718 return;
5719 }
5720
5721 if (ad.disp)
5722 output_addr_const (file, ad.disp);
5723 else
5724 fprintf (file, "0");
5725 }
5726 return;
5727
5728 case 'R':
5729 {
5730 struct s390_address ad;
5731 int ret;
5732
5733 if (!MEM_P (x))
5734 {
5735 output_operand_lossage ("memory reference expected for "
5736 "'R' output modifier");
5737 return;
5738 }
5739
5740 ret = s390_decompose_address (XEXP (x, 0), &ad);
5741
5742 if (!ret
5743 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
5744 || ad.indx)
5745 {
5746 output_operand_lossage ("invalid address for 'R' output modifier");
5747 return;
5748 }
5749
5750 if (ad.base)
5751 fprintf (file, "%s", reg_names[REGNO (ad.base)]);
5752 else
5753 fprintf (file, "0");
5754 }
5755 return;
5756
5757 case 'S':
5758 {
5759 struct s390_address ad;
5760 int ret;
5761
5762 if (!MEM_P (x))
5763 {
5764 output_operand_lossage ("memory reference expected for "
5765 "'S' output modifier");
5766 return;
5767 }
5768 ret = s390_decompose_address (XEXP (x, 0), &ad);
5769
5770 if (!ret
5771 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
5772 || ad.indx)
5773 {
5774 output_operand_lossage ("invalid address for 'S' output modifier");
5775 return;
5776 }
5777
5778 if (ad.disp)
5779 output_addr_const (file, ad.disp);
5780 else
5781 fprintf (file, "0");
5782
5783 if (ad.base)
5784 fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
5785 }
5786 return;
5787
5788 case 'N':
5789 if (GET_CODE (x) == REG)
5790 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
5791 else if (GET_CODE (x) == MEM)
5792 x = change_address (x, VOIDmode,
5793 plus_constant (Pmode, XEXP (x, 0), 4));
5794 else
5795 output_operand_lossage ("register or memory expression expected "
5796 "for 'N' output modifier");
5797 break;
5798
5799 case 'M':
5800 if (GET_CODE (x) == REG)
5801 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
5802 else if (GET_CODE (x) == MEM)
5803 x = change_address (x, VOIDmode,
5804 plus_constant (Pmode, XEXP (x, 0), 8));
5805 else
5806 output_operand_lossage ("register or memory expression expected "
5807 "for 'M' output modifier");
5808 break;
5809
5810 case 'Y':
5811 print_shift_count_operand (file, x);
5812 return;
5813 }
5814
5815 switch (GET_CODE (x))
5816 {
5817 case REG:
5818 fprintf (file, "%s", reg_names[REGNO (x)]);
5819 break;
5820
5821 case MEM:
5822 output_address (XEXP (x, 0));
5823 break;
5824
5825 case CONST:
5826 case CODE_LABEL:
5827 case LABEL_REF:
5828 case SYMBOL_REF:
5829 output_addr_const (file, x);
5830 break;
5831
5832 case CONST_INT:
5833 ival = INTVAL (x);
5834 switch (code)
5835 {
5836 case 0:
5837 break;
5838 case 'b':
5839 ival &= 0xff;
5840 break;
5841 case 'c':
5842 ival = ((ival & 0xff) ^ 0x80) - 0x80;
5843 break;
5844 case 'x':
5845 ival &= 0xffff;
5846 break;
5847 case 'h':
5848 ival = ((ival & 0xffff) ^ 0x8000) - 0x8000;
5849 break;
5850 case 'i':
5851 ival = s390_extract_part (x, HImode, 0);
5852 break;
5853 case 'j':
5854 ival = s390_extract_part (x, HImode, -1);
5855 break;
5856 case 'k':
5857 ival = s390_extract_part (x, SImode, 0);
5858 break;
5859 case 'm':
5860 ival = s390_extract_part (x, SImode, -1);
5861 break;
5862 case 'o':
5863 ival &= 0xffffffff;
5864 break;
5865 case 'e': case 'f':
5866 case 's': case 't':
5867 {
5868 int pos, len;
5869 bool ok;
5870
5871 len = (code == 's' || code == 'e' ? 64 : 32);
5872 ok = s390_contiguous_bitmask_p (ival, len, &pos, &len);
5873 gcc_assert (ok);
5874 if (code == 's' || code == 't')
5875 ival = 64 - pos - len;
5876 else
5877 ival = 64 - 1 - pos;
5878 }
5879 break;
5880 default:
5881 output_operand_lossage ("invalid constant for output modifier '%c'", code);
5882 }
5883 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival);
5884 break;
5885
5886 case CONST_DOUBLE:
5887 gcc_assert (GET_MODE (x) == VOIDmode);
5888 if (code == 'b')
5889 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xff);
5890 else if (code == 'x')
5891 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xffff);
5892 else if (code == 'h')
5893 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
5894 ((CONST_DOUBLE_LOW (x) & 0xffff) ^ 0x8000) - 0x8000);
5895 else
5896 {
5897 if (code == 0)
5898 output_operand_lossage ("invalid constant - try using "
5899 "an output modifier");
5900 else
5901 output_operand_lossage ("invalid constant for output modifier '%c'",
5902 code);
5903 }
5904 break;
5905
5906 default:
5907 if (code == 0)
5908 output_operand_lossage ("invalid expression - try using "
5909 "an output modifier");
5910 else
5911 output_operand_lossage ("invalid expression for output "
5912 "modifier '%c'", code);
5913 break;
5914 }
5915 }
5916
5917 /* Target hook for assembling integer objects. We need to define it
5918 here to work a round a bug in some versions of GAS, which couldn't
5919 handle values smaller than INT_MIN when printed in decimal. */
5920
5921 static bool
s390_assemble_integer(rtx x,unsigned int size,int aligned_p)5922 s390_assemble_integer (rtx x, unsigned int size, int aligned_p)
5923 {
5924 if (size == 8 && aligned_p
5925 && GET_CODE (x) == CONST_INT && INTVAL (x) < INT_MIN)
5926 {
5927 fprintf (asm_out_file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n",
5928 INTVAL (x));
5929 return true;
5930 }
5931 return default_assemble_integer (x, size, aligned_p);
5932 }
5933
5934 /* Returns true if register REGNO is used for forming
5935 a memory address in expression X. */
5936
5937 static bool
reg_used_in_mem_p(int regno,rtx x)5938 reg_used_in_mem_p (int regno, rtx x)
5939 {
5940 enum rtx_code code = GET_CODE (x);
5941 int i, j;
5942 const char *fmt;
5943
5944 if (code == MEM)
5945 {
5946 if (refers_to_regno_p (regno, regno+1,
5947 XEXP (x, 0), 0))
5948 return true;
5949 }
5950 else if (code == SET
5951 && GET_CODE (SET_DEST (x)) == PC)
5952 {
5953 if (refers_to_regno_p (regno, regno+1,
5954 SET_SRC (x), 0))
5955 return true;
5956 }
5957
5958 fmt = GET_RTX_FORMAT (code);
5959 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
5960 {
5961 if (fmt[i] == 'e'
5962 && reg_used_in_mem_p (regno, XEXP (x, i)))
5963 return true;
5964
5965 else if (fmt[i] == 'E')
5966 for (j = 0; j < XVECLEN (x, i); j++)
5967 if (reg_used_in_mem_p (regno, XVECEXP (x, i, j)))
5968 return true;
5969 }
5970 return false;
5971 }
5972
5973 /* Returns true if expression DEP_RTX sets an address register
5974 used by instruction INSN to address memory. */
5975
5976 static bool
addr_generation_dependency_p(rtx dep_rtx,rtx insn)5977 addr_generation_dependency_p (rtx dep_rtx, rtx insn)
5978 {
5979 rtx target, pat;
5980
5981 if (GET_CODE (dep_rtx) == INSN)
5982 dep_rtx = PATTERN (dep_rtx);
5983
5984 if (GET_CODE (dep_rtx) == SET)
5985 {
5986 target = SET_DEST (dep_rtx);
5987 if (GET_CODE (target) == STRICT_LOW_PART)
5988 target = XEXP (target, 0);
5989 while (GET_CODE (target) == SUBREG)
5990 target = SUBREG_REG (target);
5991
5992 if (GET_CODE (target) == REG)
5993 {
5994 int regno = REGNO (target);
5995
5996 if (s390_safe_attr_type (insn) == TYPE_LA)
5997 {
5998 pat = PATTERN (insn);
5999 if (GET_CODE (pat) == PARALLEL)
6000 {
6001 gcc_assert (XVECLEN (pat, 0) == 2);
6002 pat = XVECEXP (pat, 0, 0);
6003 }
6004 gcc_assert (GET_CODE (pat) == SET);
6005 return refers_to_regno_p (regno, regno+1, SET_SRC (pat), 0);
6006 }
6007 else if (get_attr_atype (insn) == ATYPE_AGEN)
6008 return reg_used_in_mem_p (regno, PATTERN (insn));
6009 }
6010 }
6011 return false;
6012 }
6013
6014 /* Return 1, if dep_insn sets register used in insn in the agen unit. */
6015
6016 int
s390_agen_dep_p(rtx dep_insn,rtx insn)6017 s390_agen_dep_p (rtx dep_insn, rtx insn)
6018 {
6019 rtx dep_rtx = PATTERN (dep_insn);
6020 int i;
6021
6022 if (GET_CODE (dep_rtx) == SET
6023 && addr_generation_dependency_p (dep_rtx, insn))
6024 return 1;
6025 else if (GET_CODE (dep_rtx) == PARALLEL)
6026 {
6027 for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
6028 {
6029 if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i), insn))
6030 return 1;
6031 }
6032 }
6033 return 0;
6034 }
6035
6036
6037 /* A C statement (sans semicolon) to update the integer scheduling priority
6038 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
6039 reduce the priority to execute INSN later. Do not define this macro if
6040 you do not need to adjust the scheduling priorities of insns.
6041
6042 A STD instruction should be scheduled earlier,
6043 in order to use the bypass. */
6044 static int
s390_adjust_priority(rtx insn ATTRIBUTE_UNUSED,int priority)6045 s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
6046 {
6047 if (! INSN_P (insn))
6048 return priority;
6049
6050 if (s390_tune != PROCESSOR_2084_Z990
6051 && s390_tune != PROCESSOR_2094_Z9_109
6052 && s390_tune != PROCESSOR_2097_Z10
6053 && s390_tune != PROCESSOR_2817_Z196
6054 && s390_tune != PROCESSOR_2827_ZEC12)
6055 return priority;
6056
6057 switch (s390_safe_attr_type (insn))
6058 {
6059 case TYPE_FSTOREDF:
6060 case TYPE_FSTORESF:
6061 priority = priority << 3;
6062 break;
6063 case TYPE_STORE:
6064 case TYPE_STM:
6065 priority = priority << 1;
6066 break;
6067 default:
6068 break;
6069 }
6070 return priority;
6071 }
6072
6073
6074 /* The number of instructions that can be issued per cycle. */
6075
6076 static int
s390_issue_rate(void)6077 s390_issue_rate (void)
6078 {
6079 switch (s390_tune)
6080 {
6081 case PROCESSOR_2084_Z990:
6082 case PROCESSOR_2094_Z9_109:
6083 case PROCESSOR_2817_Z196:
6084 return 3;
6085 case PROCESSOR_2097_Z10:
6086 return 2;
6087 /* Starting with EC12 we use the sched_reorder hook to take care
6088 of instruction dispatch constraints. The algorithm only
6089 picks the best instruction and assumes only a single
6090 instruction gets issued per cycle. */
6091 case PROCESSOR_2827_ZEC12:
6092 default:
6093 return 1;
6094 }
6095 }
6096
6097 static int
s390_first_cycle_multipass_dfa_lookahead(void)6098 s390_first_cycle_multipass_dfa_lookahead (void)
6099 {
6100 return 4;
6101 }
6102
6103 /* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
6104 Fix up MEMs as required. */
6105
6106 static void
annotate_constant_pool_refs(rtx * x)6107 annotate_constant_pool_refs (rtx *x)
6108 {
6109 int i, j;
6110 const char *fmt;
6111
6112 gcc_assert (GET_CODE (*x) != SYMBOL_REF
6113 || !CONSTANT_POOL_ADDRESS_P (*x));
6114
6115 /* Literal pool references can only occur inside a MEM ... */
6116 if (GET_CODE (*x) == MEM)
6117 {
6118 rtx memref = XEXP (*x, 0);
6119
6120 if (GET_CODE (memref) == SYMBOL_REF
6121 && CONSTANT_POOL_ADDRESS_P (memref))
6122 {
6123 rtx base = cfun->machine->base_reg;
6124 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, memref, base),
6125 UNSPEC_LTREF);
6126
6127 *x = replace_equiv_address (*x, addr);
6128 return;
6129 }
6130
6131 if (GET_CODE (memref) == CONST
6132 && GET_CODE (XEXP (memref, 0)) == PLUS
6133 && GET_CODE (XEXP (XEXP (memref, 0), 1)) == CONST_INT
6134 && GET_CODE (XEXP (XEXP (memref, 0), 0)) == SYMBOL_REF
6135 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (memref, 0), 0)))
6136 {
6137 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (memref, 0), 1));
6138 rtx sym = XEXP (XEXP (memref, 0), 0);
6139 rtx base = cfun->machine->base_reg;
6140 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, sym, base),
6141 UNSPEC_LTREF);
6142
6143 *x = replace_equiv_address (*x, plus_constant (Pmode, addr, off));
6144 return;
6145 }
6146 }
6147
6148 /* ... or a load-address type pattern. */
6149 if (GET_CODE (*x) == SET)
6150 {
6151 rtx addrref = SET_SRC (*x);
6152
6153 if (GET_CODE (addrref) == SYMBOL_REF
6154 && CONSTANT_POOL_ADDRESS_P (addrref))
6155 {
6156 rtx base = cfun->machine->base_reg;
6157 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, addrref, base),
6158 UNSPEC_LTREF);
6159
6160 SET_SRC (*x) = addr;
6161 return;
6162 }
6163
6164 if (GET_CODE (addrref) == CONST
6165 && GET_CODE (XEXP (addrref, 0)) == PLUS
6166 && GET_CODE (XEXP (XEXP (addrref, 0), 1)) == CONST_INT
6167 && GET_CODE (XEXP (XEXP (addrref, 0), 0)) == SYMBOL_REF
6168 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (addrref, 0), 0)))
6169 {
6170 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (addrref, 0), 1));
6171 rtx sym = XEXP (XEXP (addrref, 0), 0);
6172 rtx base = cfun->machine->base_reg;
6173 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, sym, base),
6174 UNSPEC_LTREF);
6175
6176 SET_SRC (*x) = plus_constant (Pmode, addr, off);
6177 return;
6178 }
6179 }
6180
6181 /* Annotate LTREL_BASE as well. */
6182 if (GET_CODE (*x) == UNSPEC
6183 && XINT (*x, 1) == UNSPEC_LTREL_BASE)
6184 {
6185 rtx base = cfun->machine->base_reg;
6186 *x = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, XVECEXP (*x, 0, 0), base),
6187 UNSPEC_LTREL_BASE);
6188 return;
6189 }
6190
6191 fmt = GET_RTX_FORMAT (GET_CODE (*x));
6192 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
6193 {
6194 if (fmt[i] == 'e')
6195 {
6196 annotate_constant_pool_refs (&XEXP (*x, i));
6197 }
6198 else if (fmt[i] == 'E')
6199 {
6200 for (j = 0; j < XVECLEN (*x, i); j++)
6201 annotate_constant_pool_refs (&XVECEXP (*x, i, j));
6202 }
6203 }
6204 }
6205
6206 /* Split all branches that exceed the maximum distance.
6207 Returns true if this created a new literal pool entry. */
6208
6209 static int
s390_split_branches(void)6210 s390_split_branches (void)
6211 {
6212 rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
6213 int new_literal = 0, ret;
6214 rtx insn, pat, tmp, target;
6215 rtx *label;
6216
6217 /* We need correct insn addresses. */
6218
6219 shorten_branches (get_insns ());
6220
6221 /* Find all branches that exceed 64KB, and split them. */
6222
6223 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6224 {
6225 if (GET_CODE (insn) != JUMP_INSN)
6226 continue;
6227
6228 pat = PATTERN (insn);
6229 if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
6230 pat = XVECEXP (pat, 0, 0);
6231 if (GET_CODE (pat) != SET || SET_DEST (pat) != pc_rtx)
6232 continue;
6233
6234 if (GET_CODE (SET_SRC (pat)) == LABEL_REF)
6235 {
6236 label = &SET_SRC (pat);
6237 }
6238 else if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE)
6239 {
6240 if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF)
6241 label = &XEXP (SET_SRC (pat), 1);
6242 else if (GET_CODE (XEXP (SET_SRC (pat), 2)) == LABEL_REF)
6243 label = &XEXP (SET_SRC (pat), 2);
6244 else
6245 continue;
6246 }
6247 else
6248 continue;
6249
6250 if (get_attr_length (insn) <= 4)
6251 continue;
6252
6253 /* We are going to use the return register as scratch register,
6254 make sure it will be saved/restored by the prologue/epilogue. */
6255 cfun_frame_layout.save_return_addr_p = 1;
6256
6257 if (!flag_pic)
6258 {
6259 new_literal = 1;
6260 tmp = force_const_mem (Pmode, *label);
6261 tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, tmp), insn);
6262 INSN_ADDRESSES_NEW (tmp, -1);
6263 annotate_constant_pool_refs (&PATTERN (tmp));
6264
6265 target = temp_reg;
6266 }
6267 else
6268 {
6269 new_literal = 1;
6270 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, *label),
6271 UNSPEC_LTREL_OFFSET);
6272 target = gen_rtx_CONST (Pmode, target);
6273 target = force_const_mem (Pmode, target);
6274 tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, target), insn);
6275 INSN_ADDRESSES_NEW (tmp, -1);
6276 annotate_constant_pool_refs (&PATTERN (tmp));
6277
6278 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, XEXP (target, 0),
6279 cfun->machine->base_reg),
6280 UNSPEC_LTREL_BASE);
6281 target = gen_rtx_PLUS (Pmode, temp_reg, target);
6282 }
6283
6284 ret = validate_change (insn, label, target, 0);
6285 gcc_assert (ret);
6286 }
6287
6288 return new_literal;
6289 }
6290
6291
6292 /* Find an annotated literal pool symbol referenced in RTX X,
6293 and store it at REF. Will abort if X contains references to
6294 more than one such pool symbol; multiple references to the same
6295 symbol are allowed, however.
6296
6297 The rtx pointed to by REF must be initialized to NULL_RTX
6298 by the caller before calling this routine. */
6299
6300 static void
find_constant_pool_ref(rtx x,rtx * ref)6301 find_constant_pool_ref (rtx x, rtx *ref)
6302 {
6303 int i, j;
6304 const char *fmt;
6305
6306 /* Ignore LTREL_BASE references. */
6307 if (GET_CODE (x) == UNSPEC
6308 && XINT (x, 1) == UNSPEC_LTREL_BASE)
6309 return;
6310 /* Likewise POOL_ENTRY insns. */
6311 if (GET_CODE (x) == UNSPEC_VOLATILE
6312 && XINT (x, 1) == UNSPECV_POOL_ENTRY)
6313 return;
6314
6315 gcc_assert (GET_CODE (x) != SYMBOL_REF
6316 || !CONSTANT_POOL_ADDRESS_P (x));
6317
6318 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_LTREF)
6319 {
6320 rtx sym = XVECEXP (x, 0, 0);
6321 gcc_assert (GET_CODE (sym) == SYMBOL_REF
6322 && CONSTANT_POOL_ADDRESS_P (sym));
6323
6324 if (*ref == NULL_RTX)
6325 *ref = sym;
6326 else
6327 gcc_assert (*ref == sym);
6328
6329 return;
6330 }
6331
6332 fmt = GET_RTX_FORMAT (GET_CODE (x));
6333 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
6334 {
6335 if (fmt[i] == 'e')
6336 {
6337 find_constant_pool_ref (XEXP (x, i), ref);
6338 }
6339 else if (fmt[i] == 'E')
6340 {
6341 for (j = 0; j < XVECLEN (x, i); j++)
6342 find_constant_pool_ref (XVECEXP (x, i, j), ref);
6343 }
6344 }
6345 }
6346
6347 /* Replace every reference to the annotated literal pool
6348 symbol REF in X by its base plus OFFSET. */
6349
6350 static void
replace_constant_pool_ref(rtx * x,rtx ref,rtx offset)6351 replace_constant_pool_ref (rtx *x, rtx ref, rtx offset)
6352 {
6353 int i, j;
6354 const char *fmt;
6355
6356 gcc_assert (*x != ref);
6357
6358 if (GET_CODE (*x) == UNSPEC
6359 && XINT (*x, 1) == UNSPEC_LTREF
6360 && XVECEXP (*x, 0, 0) == ref)
6361 {
6362 *x = gen_rtx_PLUS (Pmode, XVECEXP (*x, 0, 1), offset);
6363 return;
6364 }
6365
6366 if (GET_CODE (*x) == PLUS
6367 && GET_CODE (XEXP (*x, 1)) == CONST_INT
6368 && GET_CODE (XEXP (*x, 0)) == UNSPEC
6369 && XINT (XEXP (*x, 0), 1) == UNSPEC_LTREF
6370 && XVECEXP (XEXP (*x, 0), 0, 0) == ref)
6371 {
6372 rtx addr = gen_rtx_PLUS (Pmode, XVECEXP (XEXP (*x, 0), 0, 1), offset);
6373 *x = plus_constant (Pmode, addr, INTVAL (XEXP (*x, 1)));
6374 return;
6375 }
6376
6377 fmt = GET_RTX_FORMAT (GET_CODE (*x));
6378 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
6379 {
6380 if (fmt[i] == 'e')
6381 {
6382 replace_constant_pool_ref (&XEXP (*x, i), ref, offset);
6383 }
6384 else if (fmt[i] == 'E')
6385 {
6386 for (j = 0; j < XVECLEN (*x, i); j++)
6387 replace_constant_pool_ref (&XVECEXP (*x, i, j), ref, offset);
6388 }
6389 }
6390 }
6391
6392 /* Check whether X contains an UNSPEC_LTREL_BASE.
6393 Return its constant pool symbol if found, NULL_RTX otherwise. */
6394
6395 static rtx
find_ltrel_base(rtx x)6396 find_ltrel_base (rtx x)
6397 {
6398 int i, j;
6399 const char *fmt;
6400
6401 if (GET_CODE (x) == UNSPEC
6402 && XINT (x, 1) == UNSPEC_LTREL_BASE)
6403 return XVECEXP (x, 0, 0);
6404
6405 fmt = GET_RTX_FORMAT (GET_CODE (x));
6406 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
6407 {
6408 if (fmt[i] == 'e')
6409 {
6410 rtx fnd = find_ltrel_base (XEXP (x, i));
6411 if (fnd)
6412 return fnd;
6413 }
6414 else if (fmt[i] == 'E')
6415 {
6416 for (j = 0; j < XVECLEN (x, i); j++)
6417 {
6418 rtx fnd = find_ltrel_base (XVECEXP (x, i, j));
6419 if (fnd)
6420 return fnd;
6421 }
6422 }
6423 }
6424
6425 return NULL_RTX;
6426 }
6427
6428 /* Replace any occurrence of UNSPEC_LTREL_BASE in X with its base. */
6429
6430 static void
replace_ltrel_base(rtx * x)6431 replace_ltrel_base (rtx *x)
6432 {
6433 int i, j;
6434 const char *fmt;
6435
6436 if (GET_CODE (*x) == UNSPEC
6437 && XINT (*x, 1) == UNSPEC_LTREL_BASE)
6438 {
6439 *x = XVECEXP (*x, 0, 1);
6440 return;
6441 }
6442
6443 fmt = GET_RTX_FORMAT (GET_CODE (*x));
6444 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
6445 {
6446 if (fmt[i] == 'e')
6447 {
6448 replace_ltrel_base (&XEXP (*x, i));
6449 }
6450 else if (fmt[i] == 'E')
6451 {
6452 for (j = 0; j < XVECLEN (*x, i); j++)
6453 replace_ltrel_base (&XVECEXP (*x, i, j));
6454 }
6455 }
6456 }
6457
6458
6459 /* We keep a list of constants which we have to add to internal
6460 constant tables in the middle of large functions. */
6461
6462 #define NR_C_MODES 11
6463 enum machine_mode constant_modes[NR_C_MODES] =
6464 {
6465 TFmode, TImode, TDmode,
6466 DFmode, DImode, DDmode,
6467 SFmode, SImode, SDmode,
6468 HImode,
6469 QImode
6470 };
6471
6472 struct constant
6473 {
6474 struct constant *next;
6475 rtx value;
6476 rtx label;
6477 };
6478
6479 struct constant_pool
6480 {
6481 struct constant_pool *next;
6482 rtx first_insn;
6483 rtx pool_insn;
6484 bitmap insns;
6485 rtx emit_pool_after;
6486
6487 struct constant *constants[NR_C_MODES];
6488 struct constant *execute;
6489 rtx label;
6490 int size;
6491 };
6492
6493 /* Allocate new constant_pool structure. */
6494
6495 static struct constant_pool *
s390_alloc_pool(void)6496 s390_alloc_pool (void)
6497 {
6498 struct constant_pool *pool;
6499 int i;
6500
6501 pool = (struct constant_pool *) xmalloc (sizeof *pool);
6502 pool->next = NULL;
6503 for (i = 0; i < NR_C_MODES; i++)
6504 pool->constants[i] = NULL;
6505
6506 pool->execute = NULL;
6507 pool->label = gen_label_rtx ();
6508 pool->first_insn = NULL_RTX;
6509 pool->pool_insn = NULL_RTX;
6510 pool->insns = BITMAP_ALLOC (NULL);
6511 pool->size = 0;
6512 pool->emit_pool_after = NULL_RTX;
6513
6514 return pool;
6515 }
6516
6517 /* Create new constant pool covering instructions starting at INSN
6518 and chain it to the end of POOL_LIST. */
6519
6520 static struct constant_pool *
s390_start_pool(struct constant_pool ** pool_list,rtx insn)6521 s390_start_pool (struct constant_pool **pool_list, rtx insn)
6522 {
6523 struct constant_pool *pool, **prev;
6524
6525 pool = s390_alloc_pool ();
6526 pool->first_insn = insn;
6527
6528 for (prev = pool_list; *prev; prev = &(*prev)->next)
6529 ;
6530 *prev = pool;
6531
6532 return pool;
6533 }
6534
6535 /* End range of instructions covered by POOL at INSN and emit
6536 placeholder insn representing the pool. */
6537
6538 static void
s390_end_pool(struct constant_pool * pool,rtx insn)6539 s390_end_pool (struct constant_pool *pool, rtx insn)
6540 {
6541 rtx pool_size = GEN_INT (pool->size + 8 /* alignment slop */);
6542
6543 if (!insn)
6544 insn = get_last_insn ();
6545
6546 pool->pool_insn = emit_insn_after (gen_pool (pool_size), insn);
6547 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
6548 }
6549
6550 /* Add INSN to the list of insns covered by POOL. */
6551
6552 static void
s390_add_pool_insn(struct constant_pool * pool,rtx insn)6553 s390_add_pool_insn (struct constant_pool *pool, rtx insn)
6554 {
6555 bitmap_set_bit (pool->insns, INSN_UID (insn));
6556 }
6557
6558 /* Return pool out of POOL_LIST that covers INSN. */
6559
6560 static struct constant_pool *
s390_find_pool(struct constant_pool * pool_list,rtx insn)6561 s390_find_pool (struct constant_pool *pool_list, rtx insn)
6562 {
6563 struct constant_pool *pool;
6564
6565 for (pool = pool_list; pool; pool = pool->next)
6566 if (bitmap_bit_p (pool->insns, INSN_UID (insn)))
6567 break;
6568
6569 return pool;
6570 }
6571
6572 /* Add constant VAL of mode MODE to the constant pool POOL. */
6573
6574 static void
s390_add_constant(struct constant_pool * pool,rtx val,enum machine_mode mode)6575 s390_add_constant (struct constant_pool *pool, rtx val, enum machine_mode mode)
6576 {
6577 struct constant *c;
6578 int i;
6579
6580 for (i = 0; i < NR_C_MODES; i++)
6581 if (constant_modes[i] == mode)
6582 break;
6583 gcc_assert (i != NR_C_MODES);
6584
6585 for (c = pool->constants[i]; c != NULL; c = c->next)
6586 if (rtx_equal_p (val, c->value))
6587 break;
6588
6589 if (c == NULL)
6590 {
6591 c = (struct constant *) xmalloc (sizeof *c);
6592 c->value = val;
6593 c->label = gen_label_rtx ();
6594 c->next = pool->constants[i];
6595 pool->constants[i] = c;
6596 pool->size += GET_MODE_SIZE (mode);
6597 }
6598 }
6599
6600 /* Return an rtx that represents the offset of X from the start of
6601 pool POOL. */
6602
6603 static rtx
s390_pool_offset(struct constant_pool * pool,rtx x)6604 s390_pool_offset (struct constant_pool *pool, rtx x)
6605 {
6606 rtx label;
6607
6608 label = gen_rtx_LABEL_REF (GET_MODE (x), pool->label);
6609 x = gen_rtx_UNSPEC (GET_MODE (x), gen_rtvec (2, x, label),
6610 UNSPEC_POOL_OFFSET);
6611 return gen_rtx_CONST (GET_MODE (x), x);
6612 }
6613
6614 /* Find constant VAL of mode MODE in the constant pool POOL.
6615 Return an RTX describing the distance from the start of
6616 the pool to the location of the new constant. */
6617
6618 static rtx
s390_find_constant(struct constant_pool * pool,rtx val,enum machine_mode mode)6619 s390_find_constant (struct constant_pool *pool, rtx val,
6620 enum machine_mode mode)
6621 {
6622 struct constant *c;
6623 int i;
6624
6625 for (i = 0; i < NR_C_MODES; i++)
6626 if (constant_modes[i] == mode)
6627 break;
6628 gcc_assert (i != NR_C_MODES);
6629
6630 for (c = pool->constants[i]; c != NULL; c = c->next)
6631 if (rtx_equal_p (val, c->value))
6632 break;
6633
6634 gcc_assert (c);
6635
6636 return s390_pool_offset (pool, gen_rtx_LABEL_REF (Pmode, c->label));
6637 }
6638
6639 /* Check whether INSN is an execute. Return the label_ref to its
6640 execute target template if so, NULL_RTX otherwise. */
6641
6642 static rtx
s390_execute_label(rtx insn)6643 s390_execute_label (rtx insn)
6644 {
6645 if (GET_CODE (insn) == INSN
6646 && GET_CODE (PATTERN (insn)) == PARALLEL
6647 && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == UNSPEC
6648 && XINT (XVECEXP (PATTERN (insn), 0, 0), 1) == UNSPEC_EXECUTE)
6649 return XVECEXP (XVECEXP (PATTERN (insn), 0, 0), 0, 2);
6650
6651 return NULL_RTX;
6652 }
6653
6654 /* Add execute target for INSN to the constant pool POOL. */
6655
6656 static void
s390_add_execute(struct constant_pool * pool,rtx insn)6657 s390_add_execute (struct constant_pool *pool, rtx insn)
6658 {
6659 struct constant *c;
6660
6661 for (c = pool->execute; c != NULL; c = c->next)
6662 if (INSN_UID (insn) == INSN_UID (c->value))
6663 break;
6664
6665 if (c == NULL)
6666 {
6667 c = (struct constant *) xmalloc (sizeof *c);
6668 c->value = insn;
6669 c->label = gen_label_rtx ();
6670 c->next = pool->execute;
6671 pool->execute = c;
6672 pool->size += 6;
6673 }
6674 }
6675
6676 /* Find execute target for INSN in the constant pool POOL.
6677 Return an RTX describing the distance from the start of
6678 the pool to the location of the execute target. */
6679
6680 static rtx
s390_find_execute(struct constant_pool * pool,rtx insn)6681 s390_find_execute (struct constant_pool *pool, rtx insn)
6682 {
6683 struct constant *c;
6684
6685 for (c = pool->execute; c != NULL; c = c->next)
6686 if (INSN_UID (insn) == INSN_UID (c->value))
6687 break;
6688
6689 gcc_assert (c);
6690
6691 return s390_pool_offset (pool, gen_rtx_LABEL_REF (Pmode, c->label));
6692 }
6693
6694 /* For an execute INSN, extract the execute target template. */
6695
6696 static rtx
s390_execute_target(rtx insn)6697 s390_execute_target (rtx insn)
6698 {
6699 rtx pattern = PATTERN (insn);
6700 gcc_assert (s390_execute_label (insn));
6701
6702 if (XVECLEN (pattern, 0) == 2)
6703 {
6704 pattern = copy_rtx (XVECEXP (pattern, 0, 1));
6705 }
6706 else
6707 {
6708 rtvec vec = rtvec_alloc (XVECLEN (pattern, 0) - 1);
6709 int i;
6710
6711 for (i = 0; i < XVECLEN (pattern, 0) - 1; i++)
6712 RTVEC_ELT (vec, i) = copy_rtx (XVECEXP (pattern, 0, i + 1));
6713
6714 pattern = gen_rtx_PARALLEL (VOIDmode, vec);
6715 }
6716
6717 return pattern;
6718 }
6719
6720 /* Indicate that INSN cannot be duplicated. This is the case for
6721 execute insns that carry a unique label. */
6722
6723 static bool
s390_cannot_copy_insn_p(rtx insn)6724 s390_cannot_copy_insn_p (rtx insn)
6725 {
6726 rtx label = s390_execute_label (insn);
6727 return label && label != const0_rtx;
6728 }
6729
6730 /* Dump out the constants in POOL. If REMOTE_LABEL is true,
6731 do not emit the pool base label. */
6732
6733 static void
s390_dump_pool(struct constant_pool * pool,bool remote_label)6734 s390_dump_pool (struct constant_pool *pool, bool remote_label)
6735 {
6736 struct constant *c;
6737 rtx insn = pool->pool_insn;
6738 int i;
6739
6740 /* Switch to rodata section. */
6741 if (TARGET_CPU_ZARCH)
6742 {
6743 insn = emit_insn_after (gen_pool_section_start (), insn);
6744 INSN_ADDRESSES_NEW (insn, -1);
6745 }
6746
6747 /* Ensure minimum pool alignment. */
6748 if (TARGET_CPU_ZARCH)
6749 insn = emit_insn_after (gen_pool_align (GEN_INT (8)), insn);
6750 else
6751 insn = emit_insn_after (gen_pool_align (GEN_INT (4)), insn);
6752 INSN_ADDRESSES_NEW (insn, -1);
6753
6754 /* Emit pool base label. */
6755 if (!remote_label)
6756 {
6757 insn = emit_label_after (pool->label, insn);
6758 INSN_ADDRESSES_NEW (insn, -1);
6759 }
6760
6761 /* Dump constants in descending alignment requirement order,
6762 ensuring proper alignment for every constant. */
6763 for (i = 0; i < NR_C_MODES; i++)
6764 for (c = pool->constants[i]; c; c = c->next)
6765 {
6766 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
6767 rtx value = copy_rtx (c->value);
6768 if (GET_CODE (value) == CONST
6769 && GET_CODE (XEXP (value, 0)) == UNSPEC
6770 && XINT (XEXP (value, 0), 1) == UNSPEC_LTREL_OFFSET
6771 && XVECLEN (XEXP (value, 0), 0) == 1)
6772 value = s390_pool_offset (pool, XVECEXP (XEXP (value, 0), 0, 0));
6773
6774 insn = emit_label_after (c->label, insn);
6775 INSN_ADDRESSES_NEW (insn, -1);
6776
6777 value = gen_rtx_UNSPEC_VOLATILE (constant_modes[i],
6778 gen_rtvec (1, value),
6779 UNSPECV_POOL_ENTRY);
6780 insn = emit_insn_after (value, insn);
6781 INSN_ADDRESSES_NEW (insn, -1);
6782 }
6783
6784 /* Ensure minimum alignment for instructions. */
6785 insn = emit_insn_after (gen_pool_align (GEN_INT (2)), insn);
6786 INSN_ADDRESSES_NEW (insn, -1);
6787
6788 /* Output in-pool execute template insns. */
6789 for (c = pool->execute; c; c = c->next)
6790 {
6791 insn = emit_label_after (c->label, insn);
6792 INSN_ADDRESSES_NEW (insn, -1);
6793
6794 insn = emit_insn_after (s390_execute_target (c->value), insn);
6795 INSN_ADDRESSES_NEW (insn, -1);
6796 }
6797
6798 /* Switch back to previous section. */
6799 if (TARGET_CPU_ZARCH)
6800 {
6801 insn = emit_insn_after (gen_pool_section_end (), insn);
6802 INSN_ADDRESSES_NEW (insn, -1);
6803 }
6804
6805 insn = emit_barrier_after (insn);
6806 INSN_ADDRESSES_NEW (insn, -1);
6807
6808 /* Remove placeholder insn. */
6809 remove_insn (pool->pool_insn);
6810 }
6811
6812 /* Free all memory used by POOL. */
6813
6814 static void
s390_free_pool(struct constant_pool * pool)6815 s390_free_pool (struct constant_pool *pool)
6816 {
6817 struct constant *c, *next;
6818 int i;
6819
6820 for (i = 0; i < NR_C_MODES; i++)
6821 for (c = pool->constants[i]; c; c = next)
6822 {
6823 next = c->next;
6824 free (c);
6825 }
6826
6827 for (c = pool->execute; c; c = next)
6828 {
6829 next = c->next;
6830 free (c);
6831 }
6832
6833 BITMAP_FREE (pool->insns);
6834 free (pool);
6835 }
6836
6837
6838 /* Collect main literal pool. Return NULL on overflow. */
6839
6840 static struct constant_pool *
s390_mainpool_start(void)6841 s390_mainpool_start (void)
6842 {
6843 struct constant_pool *pool;
6844 rtx insn;
6845
6846 pool = s390_alloc_pool ();
6847
6848 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6849 {
6850 if (GET_CODE (insn) == INSN
6851 && GET_CODE (PATTERN (insn)) == SET
6852 && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC_VOLATILE
6853 && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPECV_MAIN_POOL)
6854 {
6855 gcc_assert (!pool->pool_insn);
6856 pool->pool_insn = insn;
6857 }
6858
6859 if (!TARGET_CPU_ZARCH && s390_execute_label (insn))
6860 {
6861 s390_add_execute (pool, insn);
6862 }
6863 else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
6864 {
6865 rtx pool_ref = NULL_RTX;
6866 find_constant_pool_ref (PATTERN (insn), &pool_ref);
6867 if (pool_ref)
6868 {
6869 rtx constant = get_pool_constant (pool_ref);
6870 enum machine_mode mode = get_pool_mode (pool_ref);
6871 s390_add_constant (pool, constant, mode);
6872 }
6873 }
6874
6875 /* If hot/cold partitioning is enabled we have to make sure that
6876 the literal pool is emitted in the same section where the
6877 initialization of the literal pool base pointer takes place.
6878 emit_pool_after is only used in the non-overflow case on non
6879 Z cpus where we can emit the literal pool at the end of the
6880 function body within the text section. */
6881 if (NOTE_P (insn)
6882 && NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS
6883 && !pool->emit_pool_after)
6884 pool->emit_pool_after = PREV_INSN (insn);
6885 }
6886
6887 gcc_assert (pool->pool_insn || pool->size == 0);
6888
6889 if (pool->size >= 4096)
6890 {
6891 /* We're going to chunkify the pool, so remove the main
6892 pool placeholder insn. */
6893 remove_insn (pool->pool_insn);
6894
6895 s390_free_pool (pool);
6896 pool = NULL;
6897 }
6898
6899 /* If the functions ends with the section where the literal pool
6900 should be emitted set the marker to its end. */
6901 if (pool && !pool->emit_pool_after)
6902 pool->emit_pool_after = get_last_insn ();
6903
6904 return pool;
6905 }
6906
6907 /* POOL holds the main literal pool as collected by s390_mainpool_start.
6908 Modify the current function to output the pool constants as well as
6909 the pool register setup instruction. */
6910
6911 static void
s390_mainpool_finish(struct constant_pool * pool)6912 s390_mainpool_finish (struct constant_pool *pool)
6913 {
6914 rtx base_reg = cfun->machine->base_reg;
6915 rtx insn;
6916
6917 /* If the pool is empty, we're done. */
6918 if (pool->size == 0)
6919 {
6920 /* We don't actually need a base register after all. */
6921 cfun->machine->base_reg = NULL_RTX;
6922
6923 if (pool->pool_insn)
6924 remove_insn (pool->pool_insn);
6925 s390_free_pool (pool);
6926 return;
6927 }
6928
6929 /* We need correct insn addresses. */
6930 shorten_branches (get_insns ());
6931
6932 /* On zSeries, we use a LARL to load the pool register. The pool is
6933 located in the .rodata section, so we emit it after the function. */
6934 if (TARGET_CPU_ZARCH)
6935 {
6936 insn = gen_main_base_64 (base_reg, pool->label);
6937 insn = emit_insn_after (insn, pool->pool_insn);
6938 INSN_ADDRESSES_NEW (insn, -1);
6939 remove_insn (pool->pool_insn);
6940
6941 insn = get_last_insn ();
6942 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
6943 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
6944
6945 s390_dump_pool (pool, 0);
6946 }
6947
6948 /* On S/390, if the total size of the function's code plus literal pool
6949 does not exceed 4096 bytes, we use BASR to set up a function base
6950 pointer, and emit the literal pool at the end of the function. */
6951 else if (INSN_ADDRESSES (INSN_UID (pool->emit_pool_after))
6952 + pool->size + 8 /* alignment slop */ < 4096)
6953 {
6954 insn = gen_main_base_31_small (base_reg, pool->label);
6955 insn = emit_insn_after (insn, pool->pool_insn);
6956 INSN_ADDRESSES_NEW (insn, -1);
6957 remove_insn (pool->pool_insn);
6958
6959 insn = emit_label_after (pool->label, insn);
6960 INSN_ADDRESSES_NEW (insn, -1);
6961
6962 /* emit_pool_after will be set by s390_mainpool_start to the
6963 last insn of the section where the literal pool should be
6964 emitted. */
6965 insn = pool->emit_pool_after;
6966
6967 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
6968 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
6969
6970 s390_dump_pool (pool, 1);
6971 }
6972
6973 /* Otherwise, we emit an inline literal pool and use BASR to branch
6974 over it, setting up the pool register at the same time. */
6975 else
6976 {
6977 rtx pool_end = gen_label_rtx ();
6978
6979 insn = gen_main_base_31_large (base_reg, pool->label, pool_end);
6980 insn = emit_jump_insn_after (insn, pool->pool_insn);
6981 JUMP_LABEL (insn) = pool_end;
6982 INSN_ADDRESSES_NEW (insn, -1);
6983 remove_insn (pool->pool_insn);
6984
6985 insn = emit_label_after (pool->label, insn);
6986 INSN_ADDRESSES_NEW (insn, -1);
6987
6988 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
6989 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
6990
6991 insn = emit_label_after (pool_end, pool->pool_insn);
6992 INSN_ADDRESSES_NEW (insn, -1);
6993
6994 s390_dump_pool (pool, 1);
6995 }
6996
6997
6998 /* Replace all literal pool references. */
6999
7000 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7001 {
7002 if (INSN_P (insn))
7003 replace_ltrel_base (&PATTERN (insn));
7004
7005 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
7006 {
7007 rtx addr, pool_ref = NULL_RTX;
7008 find_constant_pool_ref (PATTERN (insn), &pool_ref);
7009 if (pool_ref)
7010 {
7011 if (s390_execute_label (insn))
7012 addr = s390_find_execute (pool, insn);
7013 else
7014 addr = s390_find_constant (pool, get_pool_constant (pool_ref),
7015 get_pool_mode (pool_ref));
7016
7017 replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
7018 INSN_CODE (insn) = -1;
7019 }
7020 }
7021 }
7022
7023
7024 /* Free the pool. */
7025 s390_free_pool (pool);
7026 }
7027
7028 /* POOL holds the main literal pool as collected by s390_mainpool_start.
7029 We have decided we cannot use this pool, so revert all changes
7030 to the current function that were done by s390_mainpool_start. */
7031 static void
s390_mainpool_cancel(struct constant_pool * pool)7032 s390_mainpool_cancel (struct constant_pool *pool)
7033 {
7034 /* We didn't actually change the instruction stream, so simply
7035 free the pool memory. */
7036 s390_free_pool (pool);
7037 }
7038
7039
7040 /* Chunkify the literal pool. */
7041
7042 #define S390_POOL_CHUNK_MIN 0xc00
7043 #define S390_POOL_CHUNK_MAX 0xe00
7044
7045 static struct constant_pool *
s390_chunkify_start(void)7046 s390_chunkify_start (void)
7047 {
7048 struct constant_pool *curr_pool = NULL, *pool_list = NULL;
7049 int extra_size = 0;
7050 bitmap far_labels;
7051 rtx pending_ltrel = NULL_RTX;
7052 rtx insn;
7053
7054 rtx (*gen_reload_base) (rtx, rtx) =
7055 TARGET_CPU_ZARCH? gen_reload_base_64 : gen_reload_base_31;
7056
7057
7058 /* We need correct insn addresses. */
7059
7060 shorten_branches (get_insns ());
7061
7062 /* Scan all insns and move literals to pool chunks. */
7063
7064 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7065 {
7066 bool section_switch_p = false;
7067
7068 /* Check for pending LTREL_BASE. */
7069 if (INSN_P (insn))
7070 {
7071 rtx ltrel_base = find_ltrel_base (PATTERN (insn));
7072 if (ltrel_base)
7073 {
7074 gcc_assert (ltrel_base == pending_ltrel);
7075 pending_ltrel = NULL_RTX;
7076 }
7077 }
7078
7079 if (!TARGET_CPU_ZARCH && s390_execute_label (insn))
7080 {
7081 if (!curr_pool)
7082 curr_pool = s390_start_pool (&pool_list, insn);
7083
7084 s390_add_execute (curr_pool, insn);
7085 s390_add_pool_insn (curr_pool, insn);
7086 }
7087 else if (GET_CODE (insn) == INSN || CALL_P (insn))
7088 {
7089 rtx pool_ref = NULL_RTX;
7090 find_constant_pool_ref (PATTERN (insn), &pool_ref);
7091 if (pool_ref)
7092 {
7093 rtx constant = get_pool_constant (pool_ref);
7094 enum machine_mode mode = get_pool_mode (pool_ref);
7095
7096 if (!curr_pool)
7097 curr_pool = s390_start_pool (&pool_list, insn);
7098
7099 s390_add_constant (curr_pool, constant, mode);
7100 s390_add_pool_insn (curr_pool, insn);
7101
7102 /* Don't split the pool chunk between a LTREL_OFFSET load
7103 and the corresponding LTREL_BASE. */
7104 if (GET_CODE (constant) == CONST
7105 && GET_CODE (XEXP (constant, 0)) == UNSPEC
7106 && XINT (XEXP (constant, 0), 1) == UNSPEC_LTREL_OFFSET)
7107 {
7108 gcc_assert (!pending_ltrel);
7109 pending_ltrel = pool_ref;
7110 }
7111 }
7112 }
7113
7114 if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CODE_LABEL)
7115 {
7116 if (curr_pool)
7117 s390_add_pool_insn (curr_pool, insn);
7118 /* An LTREL_BASE must follow within the same basic block. */
7119 gcc_assert (!pending_ltrel);
7120 }
7121
7122 if (NOTE_P (insn))
7123 switch (NOTE_KIND (insn))
7124 {
7125 case NOTE_INSN_SWITCH_TEXT_SECTIONS:
7126 section_switch_p = true;
7127 break;
7128 case NOTE_INSN_VAR_LOCATION:
7129 case NOTE_INSN_CALL_ARG_LOCATION:
7130 continue;
7131 default:
7132 break;
7133 }
7134
7135 if (!curr_pool
7136 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn)
7137 || INSN_ADDRESSES (INSN_UID (insn)) == -1)
7138 continue;
7139
7140 if (TARGET_CPU_ZARCH)
7141 {
7142 if (curr_pool->size < S390_POOL_CHUNK_MAX)
7143 continue;
7144
7145 s390_end_pool (curr_pool, NULL_RTX);
7146 curr_pool = NULL;
7147 }
7148 else
7149 {
7150 int chunk_size = INSN_ADDRESSES (INSN_UID (insn))
7151 - INSN_ADDRESSES (INSN_UID (curr_pool->first_insn))
7152 + extra_size;
7153
7154 /* We will later have to insert base register reload insns.
7155 Those will have an effect on code size, which we need to
7156 consider here. This calculation makes rather pessimistic
7157 worst-case assumptions. */
7158 if (GET_CODE (insn) == CODE_LABEL)
7159 extra_size += 6;
7160
7161 if (chunk_size < S390_POOL_CHUNK_MIN
7162 && curr_pool->size < S390_POOL_CHUNK_MIN
7163 && !section_switch_p)
7164 continue;
7165
7166 /* Pool chunks can only be inserted after BARRIERs ... */
7167 if (GET_CODE (insn) == BARRIER)
7168 {
7169 s390_end_pool (curr_pool, insn);
7170 curr_pool = NULL;
7171 extra_size = 0;
7172 }
7173
7174 /* ... so if we don't find one in time, create one. */
7175 else if (chunk_size > S390_POOL_CHUNK_MAX
7176 || curr_pool->size > S390_POOL_CHUNK_MAX
7177 || section_switch_p)
7178 {
7179 rtx label, jump, barrier, next, prev;
7180
7181 if (!section_switch_p)
7182 {
7183 /* We can insert the barrier only after a 'real' insn. */
7184 if (GET_CODE (insn) != INSN && GET_CODE (insn) != CALL_INSN)
7185 continue;
7186 if (get_attr_length (insn) == 0)
7187 continue;
7188 /* Don't separate LTREL_BASE from the corresponding
7189 LTREL_OFFSET load. */
7190 if (pending_ltrel)
7191 continue;
7192 next = insn;
7193 do
7194 {
7195 insn = next;
7196 next = NEXT_INSN (insn);
7197 }
7198 while (next
7199 && NOTE_P (next)
7200 && (NOTE_KIND (next) == NOTE_INSN_VAR_LOCATION
7201 || NOTE_KIND (next) == NOTE_INSN_CALL_ARG_LOCATION));
7202 }
7203 else
7204 {
7205 gcc_assert (!pending_ltrel);
7206
7207 /* The old pool has to end before the section switch
7208 note in order to make it part of the current
7209 section. */
7210 insn = PREV_INSN (insn);
7211 }
7212
7213 label = gen_label_rtx ();
7214 prev = insn;
7215 if (prev && NOTE_P (prev))
7216 prev = prev_nonnote_insn (prev);
7217 if (prev)
7218 jump = emit_jump_insn_after_setloc (gen_jump (label), insn,
7219 INSN_LOCATION (prev));
7220 else
7221 jump = emit_jump_insn_after_noloc (gen_jump (label), insn);
7222 barrier = emit_barrier_after (jump);
7223 insn = emit_label_after (label, barrier);
7224 JUMP_LABEL (jump) = label;
7225 LABEL_NUSES (label) = 1;
7226
7227 INSN_ADDRESSES_NEW (jump, -1);
7228 INSN_ADDRESSES_NEW (barrier, -1);
7229 INSN_ADDRESSES_NEW (insn, -1);
7230
7231 s390_end_pool (curr_pool, barrier);
7232 curr_pool = NULL;
7233 extra_size = 0;
7234 }
7235 }
7236 }
7237
7238 if (curr_pool)
7239 s390_end_pool (curr_pool, NULL_RTX);
7240 gcc_assert (!pending_ltrel);
7241
7242 /* Find all labels that are branched into
7243 from an insn belonging to a different chunk. */
7244
7245 far_labels = BITMAP_ALLOC (NULL);
7246
7247 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7248 {
7249 /* Labels marked with LABEL_PRESERVE_P can be target
7250 of non-local jumps, so we have to mark them.
7251 The same holds for named labels.
7252
7253 Don't do that, however, if it is the label before
7254 a jump table. */
7255
7256 if (GET_CODE (insn) == CODE_LABEL
7257 && (LABEL_PRESERVE_P (insn) || LABEL_NAME (insn)))
7258 {
7259 rtx vec_insn = next_real_insn (insn);
7260 rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
7261 PATTERN (vec_insn) : NULL_RTX;
7262 if (!vec_pat
7263 || !(GET_CODE (vec_pat) == ADDR_VEC
7264 || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
7265 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (insn));
7266 }
7267
7268 /* If we have a direct jump (conditional or unconditional)
7269 or a casesi jump, check all potential targets. */
7270 else if (GET_CODE (insn) == JUMP_INSN)
7271 {
7272 rtx pat = PATTERN (insn);
7273 if (GET_CODE (pat) == PARALLEL
7274 && XVECLEN (pat, 0) == 2
7275 && GET_CODE (XVECEXP (pat, 0, 0)) == SET
7276 && GET_CODE (XVECEXP (pat, 0, 1)) == USE
7277 && GET_CODE (XEXP (XVECEXP (pat, 0, 1), 0)) == LABEL_REF)
7278 {
7279 /* Find the jump table used by this casesi jump. */
7280 rtx vec_label = XEXP (XEXP (XVECEXP (pat, 0, 1), 0), 0);
7281 rtx vec_insn = next_real_insn (vec_label);
7282 rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
7283 PATTERN (vec_insn) : NULL_RTX;
7284 if (vec_pat
7285 && (GET_CODE (vec_pat) == ADDR_VEC
7286 || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
7287 {
7288 int i, diff_p = GET_CODE (vec_pat) == ADDR_DIFF_VEC;
7289
7290 for (i = 0; i < XVECLEN (vec_pat, diff_p); i++)
7291 {
7292 rtx label = XEXP (XVECEXP (vec_pat, diff_p, i), 0);
7293
7294 if (s390_find_pool (pool_list, label)
7295 != s390_find_pool (pool_list, insn))
7296 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
7297 }
7298 }
7299 continue;
7300 }
7301
7302 if (GET_CODE (pat) == PARALLEL)
7303 pat = XVECEXP (pat, 0, 0);
7304
7305 if (GET_CODE (pat) == SET)
7306 {
7307 rtx label = JUMP_LABEL (insn);
7308 if (label)
7309 {
7310 if (s390_find_pool (pool_list, label)
7311 != s390_find_pool (pool_list, insn))
7312 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
7313 }
7314 }
7315 }
7316 }
7317
7318 /* Insert base register reload insns before every pool. */
7319
7320 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
7321 {
7322 rtx new_insn = gen_reload_base (cfun->machine->base_reg,
7323 curr_pool->label);
7324 rtx insn = curr_pool->first_insn;
7325 INSN_ADDRESSES_NEW (emit_insn_before (new_insn, insn), -1);
7326 }
7327
7328 /* Insert base register reload insns at every far label. */
7329
7330 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7331 if (GET_CODE (insn) == CODE_LABEL
7332 && bitmap_bit_p (far_labels, CODE_LABEL_NUMBER (insn)))
7333 {
7334 struct constant_pool *pool = s390_find_pool (pool_list, insn);
7335 if (pool)
7336 {
7337 rtx new_insn = gen_reload_base (cfun->machine->base_reg,
7338 pool->label);
7339 INSN_ADDRESSES_NEW (emit_insn_after (new_insn, insn), -1);
7340 }
7341 }
7342
7343
7344 BITMAP_FREE (far_labels);
7345
7346
7347 /* Recompute insn addresses. */
7348
7349 init_insn_lengths ();
7350 shorten_branches (get_insns ());
7351
7352 return pool_list;
7353 }
7354
7355 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
7356 After we have decided to use this list, finish implementing
7357 all changes to the current function as required. */
7358
7359 static void
s390_chunkify_finish(struct constant_pool * pool_list)7360 s390_chunkify_finish (struct constant_pool *pool_list)
7361 {
7362 struct constant_pool *curr_pool = NULL;
7363 rtx insn;
7364
7365
7366 /* Replace all literal pool references. */
7367
7368 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7369 {
7370 if (INSN_P (insn))
7371 replace_ltrel_base (&PATTERN (insn));
7372
7373 curr_pool = s390_find_pool (pool_list, insn);
7374 if (!curr_pool)
7375 continue;
7376
7377 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
7378 {
7379 rtx addr, pool_ref = NULL_RTX;
7380 find_constant_pool_ref (PATTERN (insn), &pool_ref);
7381 if (pool_ref)
7382 {
7383 if (s390_execute_label (insn))
7384 addr = s390_find_execute (curr_pool, insn);
7385 else
7386 addr = s390_find_constant (curr_pool,
7387 get_pool_constant (pool_ref),
7388 get_pool_mode (pool_ref));
7389
7390 replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
7391 INSN_CODE (insn) = -1;
7392 }
7393 }
7394 }
7395
7396 /* Dump out all literal pools. */
7397
7398 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
7399 s390_dump_pool (curr_pool, 0);
7400
7401 /* Free pool list. */
7402
7403 while (pool_list)
7404 {
7405 struct constant_pool *next = pool_list->next;
7406 s390_free_pool (pool_list);
7407 pool_list = next;
7408 }
7409 }
7410
7411 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
7412 We have decided we cannot use this list, so revert all changes
7413 to the current function that were done by s390_chunkify_start. */
7414
7415 static void
s390_chunkify_cancel(struct constant_pool * pool_list)7416 s390_chunkify_cancel (struct constant_pool *pool_list)
7417 {
7418 struct constant_pool *curr_pool = NULL;
7419 rtx insn;
7420
7421 /* Remove all pool placeholder insns. */
7422
7423 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
7424 {
7425 /* Did we insert an extra barrier? Remove it. */
7426 rtx barrier = PREV_INSN (curr_pool->pool_insn);
7427 rtx jump = barrier? PREV_INSN (barrier) : NULL_RTX;
7428 rtx label = NEXT_INSN (curr_pool->pool_insn);
7429
7430 if (jump && GET_CODE (jump) == JUMP_INSN
7431 && barrier && GET_CODE (barrier) == BARRIER
7432 && label && GET_CODE (label) == CODE_LABEL
7433 && GET_CODE (PATTERN (jump)) == SET
7434 && SET_DEST (PATTERN (jump)) == pc_rtx
7435 && GET_CODE (SET_SRC (PATTERN (jump))) == LABEL_REF
7436 && XEXP (SET_SRC (PATTERN (jump)), 0) == label)
7437 {
7438 remove_insn (jump);
7439 remove_insn (barrier);
7440 remove_insn (label);
7441 }
7442
7443 remove_insn (curr_pool->pool_insn);
7444 }
7445
7446 /* Remove all base register reload insns. */
7447
7448 for (insn = get_insns (); insn; )
7449 {
7450 rtx next_insn = NEXT_INSN (insn);
7451
7452 if (GET_CODE (insn) == INSN
7453 && GET_CODE (PATTERN (insn)) == SET
7454 && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC
7455 && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPEC_RELOAD_BASE)
7456 remove_insn (insn);
7457
7458 insn = next_insn;
7459 }
7460
7461 /* Free pool list. */
7462
7463 while (pool_list)
7464 {
7465 struct constant_pool *next = pool_list->next;
7466 s390_free_pool (pool_list);
7467 pool_list = next;
7468 }
7469 }
7470
7471 /* Output the constant pool entry EXP in mode MODE with alignment ALIGN. */
7472
7473 void
s390_output_pool_entry(rtx exp,enum machine_mode mode,unsigned int align)7474 s390_output_pool_entry (rtx exp, enum machine_mode mode, unsigned int align)
7475 {
7476 REAL_VALUE_TYPE r;
7477
7478 switch (GET_MODE_CLASS (mode))
7479 {
7480 case MODE_FLOAT:
7481 case MODE_DECIMAL_FLOAT:
7482 gcc_assert (GET_CODE (exp) == CONST_DOUBLE);
7483
7484 REAL_VALUE_FROM_CONST_DOUBLE (r, exp);
7485 assemble_real (r, mode, align);
7486 break;
7487
7488 case MODE_INT:
7489 assemble_integer (exp, GET_MODE_SIZE (mode), align, 1);
7490 mark_symbol_refs_as_used (exp);
7491 break;
7492
7493 default:
7494 gcc_unreachable ();
7495 }
7496 }
7497
7498
7499 /* Return an RTL expression representing the value of the return address
7500 for the frame COUNT steps up from the current frame. FRAME is the
7501 frame pointer of that frame. */
7502
7503 rtx
s390_return_addr_rtx(int count,rtx frame ATTRIBUTE_UNUSED)7504 s390_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
7505 {
7506 int offset;
7507 rtx addr;
7508
7509 /* Without backchain, we fail for all but the current frame. */
7510
7511 if (!TARGET_BACKCHAIN && count > 0)
7512 return NULL_RTX;
7513
7514 /* For the current frame, we need to make sure the initial
7515 value of RETURN_REGNUM is actually saved. */
7516
7517 if (count == 0)
7518 {
7519 /* On non-z architectures branch splitting could overwrite r14. */
7520 if (TARGET_CPU_ZARCH)
7521 return get_hard_reg_initial_val (Pmode, RETURN_REGNUM);
7522 else
7523 {
7524 cfun_frame_layout.save_return_addr_p = true;
7525 return gen_rtx_MEM (Pmode, return_address_pointer_rtx);
7526 }
7527 }
7528
7529 if (TARGET_PACKED_STACK)
7530 offset = -2 * UNITS_PER_LONG;
7531 else
7532 offset = RETURN_REGNUM * UNITS_PER_LONG;
7533
7534 addr = plus_constant (Pmode, frame, offset);
7535 addr = memory_address (Pmode, addr);
7536 return gen_rtx_MEM (Pmode, addr);
7537 }
7538
7539 /* Return an RTL expression representing the back chain stored in
7540 the current stack frame. */
7541
7542 rtx
s390_back_chain_rtx(void)7543 s390_back_chain_rtx (void)
7544 {
7545 rtx chain;
7546
7547 gcc_assert (TARGET_BACKCHAIN);
7548
7549 if (TARGET_PACKED_STACK)
7550 chain = plus_constant (Pmode, stack_pointer_rtx,
7551 STACK_POINTER_OFFSET - UNITS_PER_LONG);
7552 else
7553 chain = stack_pointer_rtx;
7554
7555 chain = gen_rtx_MEM (Pmode, chain);
7556 return chain;
7557 }
7558
7559 /* Find first call clobbered register unused in a function.
7560 This could be used as base register in a leaf function
7561 or for holding the return address before epilogue. */
7562
7563 static int
find_unused_clobbered_reg(void)7564 find_unused_clobbered_reg (void)
7565 {
7566 int i;
7567 for (i = 0; i < 6; i++)
7568 if (!df_regs_ever_live_p (i))
7569 return i;
7570 return 0;
7571 }
7572
7573
7574 /* Helper function for s390_regs_ever_clobbered. Sets the fields in DATA for all
7575 clobbered hard regs in SETREG. */
7576
7577 static void
s390_reg_clobbered_rtx(rtx setreg,const_rtx set_insn ATTRIBUTE_UNUSED,void * data)7578 s390_reg_clobbered_rtx (rtx setreg, const_rtx set_insn ATTRIBUTE_UNUSED, void *data)
7579 {
7580 int *regs_ever_clobbered = (int *)data;
7581 unsigned int i, regno;
7582 enum machine_mode mode = GET_MODE (setreg);
7583
7584 if (GET_CODE (setreg) == SUBREG)
7585 {
7586 rtx inner = SUBREG_REG (setreg);
7587 if (!GENERAL_REG_P (inner) && !FP_REG_P (inner))
7588 return;
7589 regno = subreg_regno (setreg);
7590 }
7591 else if (GENERAL_REG_P (setreg) || FP_REG_P (setreg))
7592 regno = REGNO (setreg);
7593 else
7594 return;
7595
7596 for (i = regno;
7597 i < regno + HARD_REGNO_NREGS (regno, mode);
7598 i++)
7599 regs_ever_clobbered[i] = 1;
7600 }
7601
7602 /* Walks through all basic blocks of the current function looking
7603 for clobbered hard regs using s390_reg_clobbered_rtx. The fields
7604 of the passed integer array REGS_EVER_CLOBBERED are set to one for
7605 each of those regs. */
7606
7607 static void
s390_regs_ever_clobbered(int * regs_ever_clobbered)7608 s390_regs_ever_clobbered (int *regs_ever_clobbered)
7609 {
7610 basic_block cur_bb;
7611 rtx cur_insn;
7612 unsigned int i;
7613
7614 memset (regs_ever_clobbered, 0, 32 * sizeof (int));
7615
7616 /* For non-leaf functions we have to consider all call clobbered regs to be
7617 clobbered. */
7618 if (!crtl->is_leaf)
7619 {
7620 for (i = 0; i < 32; i++)
7621 regs_ever_clobbered[i] = call_really_used_regs[i];
7622 }
7623
7624 /* Make the "magic" eh_return registers live if necessary. For regs_ever_live
7625 this work is done by liveness analysis (mark_regs_live_at_end).
7626 Special care is needed for functions containing landing pads. Landing pads
7627 may use the eh registers, but the code which sets these registers is not
7628 contained in that function. Hence s390_regs_ever_clobbered is not able to
7629 deal with this automatically. */
7630 if (crtl->calls_eh_return || cfun->machine->has_landing_pad_p)
7631 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM ; i++)
7632 if (crtl->calls_eh_return
7633 || (cfun->machine->has_landing_pad_p
7634 && df_regs_ever_live_p (EH_RETURN_DATA_REGNO (i))))
7635 regs_ever_clobbered[EH_RETURN_DATA_REGNO (i)] = 1;
7636
7637 /* For nonlocal gotos all call-saved registers have to be saved.
7638 This flag is also set for the unwinding code in libgcc.
7639 See expand_builtin_unwind_init. For regs_ever_live this is done by
7640 reload. */
7641 if (cfun->has_nonlocal_label)
7642 for (i = 0; i < 32; i++)
7643 if (!call_really_used_regs[i])
7644 regs_ever_clobbered[i] = 1;
7645
7646 FOR_EACH_BB (cur_bb)
7647 {
7648 FOR_BB_INSNS (cur_bb, cur_insn)
7649 {
7650 if (INSN_P (cur_insn))
7651 note_stores (PATTERN (cur_insn),
7652 s390_reg_clobbered_rtx,
7653 regs_ever_clobbered);
7654 }
7655 }
7656 }
7657
7658 /* Determine the frame area which actually has to be accessed
7659 in the function epilogue. The values are stored at the
7660 given pointers AREA_BOTTOM (address of the lowest used stack
7661 address) and AREA_TOP (address of the first item which does
7662 not belong to the stack frame). */
7663
7664 static void
s390_frame_area(int * area_bottom,int * area_top)7665 s390_frame_area (int *area_bottom, int *area_top)
7666 {
7667 int b, t;
7668 int i;
7669
7670 b = INT_MAX;
7671 t = INT_MIN;
7672
7673 if (cfun_frame_layout.first_restore_gpr != -1)
7674 {
7675 b = (cfun_frame_layout.gprs_offset
7676 + cfun_frame_layout.first_restore_gpr * UNITS_PER_LONG);
7677 t = b + (cfun_frame_layout.last_restore_gpr
7678 - cfun_frame_layout.first_restore_gpr + 1) * UNITS_PER_LONG;
7679 }
7680
7681 if (TARGET_64BIT && cfun_save_high_fprs_p)
7682 {
7683 b = MIN (b, cfun_frame_layout.f8_offset);
7684 t = MAX (t, (cfun_frame_layout.f8_offset
7685 + cfun_frame_layout.high_fprs * 8));
7686 }
7687
7688 if (!TARGET_64BIT)
7689 for (i = 2; i < 4; i++)
7690 if (cfun_fpr_bit_p (i))
7691 {
7692 b = MIN (b, cfun_frame_layout.f4_offset + (i - 2) * 8);
7693 t = MAX (t, cfun_frame_layout.f4_offset + (i - 1) * 8);
7694 }
7695
7696 *area_bottom = b;
7697 *area_top = t;
7698 }
7699
7700 /* Fill cfun->machine with info about register usage of current function.
7701 Return in CLOBBERED_REGS which GPRs are currently considered set. */
7702
7703 static void
s390_register_info(int clobbered_regs[])7704 s390_register_info (int clobbered_regs[])
7705 {
7706 int i, j;
7707
7708 /* Find first and last gpr to be saved. We trust regs_ever_live
7709 data, except that we don't save and restore global registers.
7710
7711 Also, all registers with special meaning to the compiler need
7712 to be handled extra. */
7713
7714 s390_regs_ever_clobbered (clobbered_regs);
7715
7716 /* fprs 8 - 15 are call saved for 64 Bit ABI. */
7717 if (!epilogue_completed)
7718 {
7719 cfun_frame_layout.fpr_bitmap = 0;
7720 cfun_frame_layout.high_fprs = 0;
7721 for (i = 16; i <= 31; i++)
7722 {
7723 if (call_really_used_regs[i])
7724 continue;
7725 /* During reload we have to use the df_regs_ever_live infos
7726 since reload is marking FPRs used as spill slots there as
7727 live before actually making the code changes. Without
7728 this we fail during elimination offset verification. */
7729 if ((clobbered_regs[i]
7730 || (df_regs_ever_live_p (i)
7731 && (reload_in_progress
7732 || crtl->saves_all_registers)))
7733 && !global_regs[i])
7734 {
7735 cfun_set_fpr_bit (i - 16);
7736 if (i >= 24)
7737 cfun_frame_layout.high_fprs++;
7738 }
7739 }
7740 }
7741
7742 for (i = 0; i < 16; i++)
7743 clobbered_regs[i] = clobbered_regs[i] && !global_regs[i] && !fixed_regs[i];
7744
7745 if (frame_pointer_needed)
7746 clobbered_regs[HARD_FRAME_POINTER_REGNUM] = 1;
7747
7748 if (flag_pic)
7749 clobbered_regs[PIC_OFFSET_TABLE_REGNUM]
7750 |= df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM);
7751
7752 clobbered_regs[BASE_REGNUM]
7753 |= (cfun->machine->base_reg
7754 && REGNO (cfun->machine->base_reg) == BASE_REGNUM);
7755
7756 clobbered_regs[RETURN_REGNUM]
7757 |= (!crtl->is_leaf
7758 || TARGET_TPF_PROFILING
7759 || cfun->machine->split_branches_pending_p
7760 || cfun_frame_layout.save_return_addr_p
7761 || crtl->calls_eh_return
7762 || cfun->stdarg);
7763
7764 clobbered_regs[STACK_POINTER_REGNUM]
7765 |= (!crtl->is_leaf
7766 || TARGET_TPF_PROFILING
7767 || cfun_save_high_fprs_p
7768 || get_frame_size () > 0
7769 || (reload_completed && cfun_frame_layout.frame_size > 0)
7770 || cfun->calls_alloca
7771 || cfun->stdarg);
7772
7773 for (i = 6; i < 16; i++)
7774 if (df_regs_ever_live_p (i) || clobbered_regs[i])
7775 break;
7776 for (j = 15; j > i; j--)
7777 if (df_regs_ever_live_p (j) || clobbered_regs[j])
7778 break;
7779
7780 if (i == 16)
7781 {
7782 /* Nothing to save/restore. */
7783 cfun_frame_layout.first_save_gpr_slot = -1;
7784 cfun_frame_layout.last_save_gpr_slot = -1;
7785 cfun_frame_layout.first_save_gpr = -1;
7786 cfun_frame_layout.first_restore_gpr = -1;
7787 cfun_frame_layout.last_save_gpr = -1;
7788 cfun_frame_layout.last_restore_gpr = -1;
7789 }
7790 else
7791 {
7792 /* Save slots for gprs from i to j. */
7793 cfun_frame_layout.first_save_gpr_slot = i;
7794 cfun_frame_layout.last_save_gpr_slot = j;
7795
7796 for (i = cfun_frame_layout.first_save_gpr_slot;
7797 i < cfun_frame_layout.last_save_gpr_slot + 1;
7798 i++)
7799 if (clobbered_regs[i])
7800 break;
7801
7802 for (j = cfun_frame_layout.last_save_gpr_slot; j > i; j--)
7803 if (clobbered_regs[j])
7804 break;
7805
7806 if (i == cfun_frame_layout.last_save_gpr_slot + 1)
7807 {
7808 /* Nothing to save/restore. */
7809 cfun_frame_layout.first_save_gpr = -1;
7810 cfun_frame_layout.first_restore_gpr = -1;
7811 cfun_frame_layout.last_save_gpr = -1;
7812 cfun_frame_layout.last_restore_gpr = -1;
7813 }
7814 else
7815 {
7816 /* Save / Restore from gpr i to j. */
7817 cfun_frame_layout.first_save_gpr = i;
7818 cfun_frame_layout.first_restore_gpr = i;
7819 cfun_frame_layout.last_save_gpr = j;
7820 cfun_frame_layout.last_restore_gpr = j;
7821 }
7822 }
7823
7824 if (cfun->stdarg)
7825 {
7826 /* Varargs functions need to save gprs 2 to 6. */
7827 if (cfun->va_list_gpr_size
7828 && crtl->args.info.gprs < GP_ARG_NUM_REG)
7829 {
7830 int min_gpr = crtl->args.info.gprs;
7831 int max_gpr = min_gpr + cfun->va_list_gpr_size;
7832 if (max_gpr > GP_ARG_NUM_REG)
7833 max_gpr = GP_ARG_NUM_REG;
7834
7835 if (cfun_frame_layout.first_save_gpr == -1
7836 || cfun_frame_layout.first_save_gpr > 2 + min_gpr)
7837 {
7838 cfun_frame_layout.first_save_gpr = 2 + min_gpr;
7839 cfun_frame_layout.first_save_gpr_slot = 2 + min_gpr;
7840 }
7841
7842 if (cfun_frame_layout.last_save_gpr == -1
7843 || cfun_frame_layout.last_save_gpr < 2 + max_gpr - 1)
7844 {
7845 cfun_frame_layout.last_save_gpr = 2 + max_gpr - 1;
7846 cfun_frame_layout.last_save_gpr_slot = 2 + max_gpr - 1;
7847 }
7848 }
7849
7850 /* Mark f0, f2 for 31 bit and f0-f4 for 64 bit to be saved. */
7851 if (TARGET_HARD_FLOAT && cfun->va_list_fpr_size
7852 && crtl->args.info.fprs < FP_ARG_NUM_REG)
7853 {
7854 int min_fpr = crtl->args.info.fprs;
7855 int max_fpr = min_fpr + cfun->va_list_fpr_size;
7856 if (max_fpr > FP_ARG_NUM_REG)
7857 max_fpr = FP_ARG_NUM_REG;
7858
7859 /* ??? This is currently required to ensure proper location
7860 of the fpr save slots within the va_list save area. */
7861 if (TARGET_PACKED_STACK)
7862 min_fpr = 0;
7863
7864 for (i = min_fpr; i < max_fpr; i++)
7865 cfun_set_fpr_bit (i);
7866 }
7867 }
7868 }
7869
7870 /* Fill cfun->machine with info about frame of current function. */
7871
7872 static void
s390_frame_info(void)7873 s390_frame_info (void)
7874 {
7875 int i;
7876
7877 cfun_frame_layout.frame_size = get_frame_size ();
7878 if (!TARGET_64BIT && cfun_frame_layout.frame_size > 0x7fff0000)
7879 fatal_error ("total size of local variables exceeds architecture limit");
7880
7881 if (!TARGET_PACKED_STACK)
7882 {
7883 cfun_frame_layout.backchain_offset = 0;
7884 cfun_frame_layout.f0_offset = 16 * UNITS_PER_LONG;
7885 cfun_frame_layout.f4_offset = cfun_frame_layout.f0_offset + 2 * 8;
7886 cfun_frame_layout.f8_offset = -cfun_frame_layout.high_fprs * 8;
7887 cfun_frame_layout.gprs_offset = (cfun_frame_layout.first_save_gpr_slot
7888 * UNITS_PER_LONG);
7889 }
7890 else if (TARGET_BACKCHAIN) /* kernel stack layout */
7891 {
7892 cfun_frame_layout.backchain_offset = (STACK_POINTER_OFFSET
7893 - UNITS_PER_LONG);
7894 cfun_frame_layout.gprs_offset
7895 = (cfun_frame_layout.backchain_offset
7896 - (STACK_POINTER_REGNUM - cfun_frame_layout.first_save_gpr_slot + 1)
7897 * UNITS_PER_LONG);
7898
7899 if (TARGET_64BIT)
7900 {
7901 cfun_frame_layout.f4_offset
7902 = (cfun_frame_layout.gprs_offset
7903 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
7904
7905 cfun_frame_layout.f0_offset
7906 = (cfun_frame_layout.f4_offset
7907 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
7908 }
7909 else
7910 {
7911 /* On 31 bit we have to care about alignment of the
7912 floating point regs to provide fastest access. */
7913 cfun_frame_layout.f0_offset
7914 = ((cfun_frame_layout.gprs_offset
7915 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1))
7916 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
7917
7918 cfun_frame_layout.f4_offset
7919 = (cfun_frame_layout.f0_offset
7920 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
7921 }
7922 }
7923 else /* no backchain */
7924 {
7925 cfun_frame_layout.f4_offset
7926 = (STACK_POINTER_OFFSET
7927 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
7928
7929 cfun_frame_layout.f0_offset
7930 = (cfun_frame_layout.f4_offset
7931 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
7932
7933 cfun_frame_layout.gprs_offset
7934 = cfun_frame_layout.f0_offset - cfun_gprs_save_area_size;
7935 }
7936
7937 if (crtl->is_leaf
7938 && !TARGET_TPF_PROFILING
7939 && cfun_frame_layout.frame_size == 0
7940 && !cfun_save_high_fprs_p
7941 && !cfun->calls_alloca
7942 && !cfun->stdarg)
7943 return;
7944
7945 if (!TARGET_PACKED_STACK)
7946 cfun_frame_layout.frame_size += (STACK_POINTER_OFFSET
7947 + crtl->outgoing_args_size
7948 + cfun_frame_layout.high_fprs * 8);
7949 else
7950 {
7951 if (TARGET_BACKCHAIN)
7952 cfun_frame_layout.frame_size += UNITS_PER_LONG;
7953
7954 /* No alignment trouble here because f8-f15 are only saved under
7955 64 bit. */
7956 cfun_frame_layout.f8_offset = (MIN (MIN (cfun_frame_layout.f0_offset,
7957 cfun_frame_layout.f4_offset),
7958 cfun_frame_layout.gprs_offset)
7959 - cfun_frame_layout.high_fprs * 8);
7960
7961 cfun_frame_layout.frame_size += cfun_frame_layout.high_fprs * 8;
7962
7963 for (i = 0; i < 8; i++)
7964 if (cfun_fpr_bit_p (i))
7965 cfun_frame_layout.frame_size += 8;
7966
7967 cfun_frame_layout.frame_size += cfun_gprs_save_area_size;
7968
7969 /* If under 31 bit an odd number of gprs has to be saved we have to adjust
7970 the frame size to sustain 8 byte alignment of stack frames. */
7971 cfun_frame_layout.frame_size = ((cfun_frame_layout.frame_size +
7972 STACK_BOUNDARY / BITS_PER_UNIT - 1)
7973 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
7974
7975 cfun_frame_layout.frame_size += crtl->outgoing_args_size;
7976 }
7977 }
7978
7979 /* Generate frame layout. Fills in register and frame data for the current
7980 function in cfun->machine. This routine can be called multiple times;
7981 it will re-do the complete frame layout every time. */
7982
7983 static void
s390_init_frame_layout(void)7984 s390_init_frame_layout (void)
7985 {
7986 HOST_WIDE_INT frame_size;
7987 int base_used;
7988 int clobbered_regs[32];
7989
7990 /* On S/390 machines, we may need to perform branch splitting, which
7991 will require both base and return address register. We have no
7992 choice but to assume we're going to need them until right at the
7993 end of the machine dependent reorg phase. */
7994 if (!TARGET_CPU_ZARCH)
7995 cfun->machine->split_branches_pending_p = true;
7996
7997 do
7998 {
7999 frame_size = cfun_frame_layout.frame_size;
8000
8001 /* Try to predict whether we'll need the base register. */
8002 base_used = cfun->machine->split_branches_pending_p
8003 || crtl->uses_const_pool
8004 || (!DISP_IN_RANGE (frame_size)
8005 && !CONST_OK_FOR_K (frame_size));
8006
8007 /* Decide which register to use as literal pool base. In small
8008 leaf functions, try to use an unused call-clobbered register
8009 as base register to avoid save/restore overhead. */
8010 if (!base_used)
8011 cfun->machine->base_reg = NULL_RTX;
8012 else if (crtl->is_leaf && !df_regs_ever_live_p (5))
8013 cfun->machine->base_reg = gen_rtx_REG (Pmode, 5);
8014 else
8015 cfun->machine->base_reg = gen_rtx_REG (Pmode, BASE_REGNUM);
8016
8017 s390_register_info (clobbered_regs);
8018 s390_frame_info ();
8019 }
8020 while (frame_size != cfun_frame_layout.frame_size);
8021 }
8022
8023 /* Remove the FPR clobbers from a tbegin insn if it can be proven that
8024 the TX is nonescaping. A transaction is considered escaping if
8025 there is at least one path from tbegin returning CC0 to the
8026 function exit block without an tend.
8027
8028 The check so far has some limitations:
8029 - only single tbegin/tend BBs are supported
8030 - the first cond jump after tbegin must separate the CC0 path from ~CC0
8031 - when CC is copied to a GPR and the CC0 check is done with the GPR
8032 this is not supported
8033 */
8034
8035 static void
s390_optimize_nonescaping_tx(void)8036 s390_optimize_nonescaping_tx (void)
8037 {
8038 const unsigned int CC0 = 1 << 3;
8039 basic_block tbegin_bb = NULL;
8040 basic_block tend_bb = NULL;
8041 basic_block bb;
8042 rtx insn;
8043 bool result = true;
8044 int bb_index;
8045 rtx tbegin_insn = NULL_RTX;
8046
8047 if (!cfun->machine->tbegin_p)
8048 return;
8049
8050 for (bb_index = 0; bb_index < n_basic_blocks; bb_index++)
8051 {
8052 bb = BASIC_BLOCK (bb_index);
8053
8054 if (!bb)
8055 continue;
8056
8057 FOR_BB_INSNS (bb, insn)
8058 {
8059 rtx ite, cc, pat, target;
8060 unsigned HOST_WIDE_INT mask;
8061
8062 if (!INSN_P (insn) || INSN_CODE (insn) <= 0)
8063 continue;
8064
8065 pat = PATTERN (insn);
8066
8067 if (GET_CODE (pat) == PARALLEL)
8068 pat = XVECEXP (pat, 0, 0);
8069
8070 if (GET_CODE (pat) != SET
8071 || GET_CODE (SET_SRC (pat)) != UNSPEC_VOLATILE)
8072 continue;
8073
8074 if (XINT (SET_SRC (pat), 1) == UNSPECV_TBEGIN)
8075 {
8076 rtx tmp;
8077
8078 tbegin_insn = insn;
8079
8080 /* Just return if the tbegin doesn't have clobbers. */
8081 if (GET_CODE (PATTERN (insn)) != PARALLEL)
8082 return;
8083
8084 if (tbegin_bb != NULL)
8085 return;
8086
8087 /* Find the next conditional jump. */
8088 for (tmp = NEXT_INSN (insn);
8089 tmp != NULL_RTX;
8090 tmp = NEXT_INSN (tmp))
8091 {
8092 if (reg_set_p (gen_rtx_REG (CCmode, CC_REGNUM), tmp))
8093 return;
8094 if (!JUMP_P (tmp))
8095 continue;
8096
8097 ite = SET_SRC (PATTERN (tmp));
8098 if (GET_CODE (ite) != IF_THEN_ELSE)
8099 continue;
8100
8101 cc = XEXP (XEXP (ite, 0), 0);
8102 if (!REG_P (cc) || !CC_REGNO_P (REGNO (cc))
8103 || GET_MODE (cc) != CCRAWmode
8104 || GET_CODE (XEXP (XEXP (ite, 0), 1)) != CONST_INT)
8105 return;
8106
8107 if (bb->succs->length () != 2)
8108 return;
8109
8110 mask = INTVAL (XEXP (XEXP (ite, 0), 1));
8111 if (GET_CODE (XEXP (ite, 0)) == NE)
8112 mask ^= 0xf;
8113
8114 if (mask == CC0)
8115 target = XEXP (ite, 1);
8116 else if (mask == (CC0 ^ 0xf))
8117 target = XEXP (ite, 2);
8118 else
8119 return;
8120
8121 {
8122 edge_iterator ei;
8123 edge e1, e2;
8124
8125 ei = ei_start (bb->succs);
8126 e1 = ei_safe_edge (ei);
8127 ei_next (&ei);
8128 e2 = ei_safe_edge (ei);
8129
8130 if (e2->flags & EDGE_FALLTHRU)
8131 {
8132 e2 = e1;
8133 e1 = ei_safe_edge (ei);
8134 }
8135
8136 if (!(e1->flags & EDGE_FALLTHRU))
8137 return;
8138
8139 tbegin_bb = (target == pc_rtx) ? e1->dest : e2->dest;
8140 }
8141 if (tmp == BB_END (bb))
8142 break;
8143 }
8144 }
8145
8146 if (XINT (SET_SRC (pat), 1) == UNSPECV_TEND)
8147 {
8148 if (tend_bb != NULL)
8149 return;
8150 tend_bb = bb;
8151 }
8152 }
8153 }
8154
8155 /* Either we successfully remove the FPR clobbers here or we are not
8156 able to do anything for this TX. Both cases don't qualify for
8157 another look. */
8158 cfun->machine->tbegin_p = false;
8159
8160 if (tbegin_bb == NULL || tend_bb == NULL)
8161 return;
8162
8163 calculate_dominance_info (CDI_POST_DOMINATORS);
8164 result = dominated_by_p (CDI_POST_DOMINATORS, tbegin_bb, tend_bb);
8165 free_dominance_info (CDI_POST_DOMINATORS);
8166
8167 if (!result)
8168 return;
8169
8170 PATTERN (tbegin_insn) = gen_rtx_PARALLEL (VOIDmode,
8171 gen_rtvec (2,
8172 XVECEXP (PATTERN (tbegin_insn), 0, 0),
8173 XVECEXP (PATTERN (tbegin_insn), 0, 1)));
8174 INSN_CODE (tbegin_insn) = -1;
8175 df_insn_rescan (tbegin_insn);
8176
8177 return;
8178 }
8179
8180 /* Update frame layout. Recompute actual register save data based on
8181 current info and update regs_ever_live for the special registers.
8182 May be called multiple times, but may never cause *more* registers
8183 to be saved than s390_init_frame_layout allocated room for. */
8184
8185 static void
s390_update_frame_layout(void)8186 s390_update_frame_layout (void)
8187 {
8188 int clobbered_regs[32];
8189
8190 s390_register_info (clobbered_regs);
8191
8192 df_set_regs_ever_live (BASE_REGNUM,
8193 clobbered_regs[BASE_REGNUM] ? true : false);
8194 df_set_regs_ever_live (RETURN_REGNUM,
8195 clobbered_regs[RETURN_REGNUM] ? true : false);
8196 df_set_regs_ever_live (STACK_POINTER_REGNUM,
8197 clobbered_regs[STACK_POINTER_REGNUM] ? true : false);
8198
8199 if (cfun->machine->base_reg)
8200 df_set_regs_ever_live (REGNO (cfun->machine->base_reg), true);
8201 }
8202
8203 /* Return true if it is legal to put a value with MODE into REGNO. */
8204
8205 bool
s390_hard_regno_mode_ok(unsigned int regno,enum machine_mode mode)8206 s390_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
8207 {
8208 switch (REGNO_REG_CLASS (regno))
8209 {
8210 case FP_REGS:
8211 if (REGNO_PAIR_OK (regno, mode))
8212 {
8213 if (mode == SImode || mode == DImode)
8214 return true;
8215
8216 if (FLOAT_MODE_P (mode) && GET_MODE_CLASS (mode) != MODE_VECTOR_FLOAT)
8217 return true;
8218 }
8219 break;
8220 case ADDR_REGS:
8221 if (FRAME_REGNO_P (regno) && mode == Pmode)
8222 return true;
8223
8224 /* fallthrough */
8225 case GENERAL_REGS:
8226 if (REGNO_PAIR_OK (regno, mode))
8227 {
8228 if (TARGET_ZARCH
8229 || (mode != TFmode && mode != TCmode && mode != TDmode))
8230 return true;
8231 }
8232 break;
8233 case CC_REGS:
8234 if (GET_MODE_CLASS (mode) == MODE_CC)
8235 return true;
8236 break;
8237 case ACCESS_REGS:
8238 if (REGNO_PAIR_OK (regno, mode))
8239 {
8240 if (mode == SImode || mode == Pmode)
8241 return true;
8242 }
8243 break;
8244 default:
8245 return false;
8246 }
8247
8248 return false;
8249 }
8250
8251 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
8252
8253 bool
s390_hard_regno_rename_ok(unsigned int old_reg,unsigned int new_reg)8254 s390_hard_regno_rename_ok (unsigned int old_reg, unsigned int new_reg)
8255 {
8256 /* Once we've decided upon a register to use as base register, it must
8257 no longer be used for any other purpose. */
8258 if (cfun->machine->base_reg)
8259 if (REGNO (cfun->machine->base_reg) == old_reg
8260 || REGNO (cfun->machine->base_reg) == new_reg)
8261 return false;
8262
8263 return true;
8264 }
8265
8266 /* Maximum number of registers to represent a value of mode MODE
8267 in a register of class RCLASS. */
8268
8269 int
s390_class_max_nregs(enum reg_class rclass,enum machine_mode mode)8270 s390_class_max_nregs (enum reg_class rclass, enum machine_mode mode)
8271 {
8272 switch (rclass)
8273 {
8274 case FP_REGS:
8275 if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
8276 return 2 * ((GET_MODE_SIZE (mode) / 2 + 8 - 1) / 8);
8277 else
8278 return (GET_MODE_SIZE (mode) + 8 - 1) / 8;
8279 case ACCESS_REGS:
8280 return (GET_MODE_SIZE (mode) + 4 - 1) / 4;
8281 default:
8282 break;
8283 }
8284 return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
8285 }
8286
8287 /* Return true if register FROM can be eliminated via register TO. */
8288
8289 static bool
s390_can_eliminate(const int from,const int to)8290 s390_can_eliminate (const int from, const int to)
8291 {
8292 /* On zSeries machines, we have not marked the base register as fixed.
8293 Instead, we have an elimination rule BASE_REGNUM -> BASE_REGNUM.
8294 If a function requires the base register, we say here that this
8295 elimination cannot be performed. This will cause reload to free
8296 up the base register (as if it were fixed). On the other hand,
8297 if the current function does *not* require the base register, we
8298 say here the elimination succeeds, which in turn allows reload
8299 to allocate the base register for any other purpose. */
8300 if (from == BASE_REGNUM && to == BASE_REGNUM)
8301 {
8302 if (TARGET_CPU_ZARCH)
8303 {
8304 s390_init_frame_layout ();
8305 return cfun->machine->base_reg == NULL_RTX;
8306 }
8307
8308 return false;
8309 }
8310
8311 /* Everything else must point into the stack frame. */
8312 gcc_assert (to == STACK_POINTER_REGNUM
8313 || to == HARD_FRAME_POINTER_REGNUM);
8314
8315 gcc_assert (from == FRAME_POINTER_REGNUM
8316 || from == ARG_POINTER_REGNUM
8317 || from == RETURN_ADDRESS_POINTER_REGNUM);
8318
8319 /* Make sure we actually saved the return address. */
8320 if (from == RETURN_ADDRESS_POINTER_REGNUM)
8321 if (!crtl->calls_eh_return
8322 && !cfun->stdarg
8323 && !cfun_frame_layout.save_return_addr_p)
8324 return false;
8325
8326 return true;
8327 }
8328
8329 /* Return offset between register FROM and TO initially after prolog. */
8330
8331 HOST_WIDE_INT
s390_initial_elimination_offset(int from,int to)8332 s390_initial_elimination_offset (int from, int to)
8333 {
8334 HOST_WIDE_INT offset;
8335 int index;
8336
8337 /* ??? Why are we called for non-eliminable pairs? */
8338 if (!s390_can_eliminate (from, to))
8339 return 0;
8340
8341 switch (from)
8342 {
8343 case FRAME_POINTER_REGNUM:
8344 offset = (get_frame_size()
8345 + STACK_POINTER_OFFSET
8346 + crtl->outgoing_args_size);
8347 break;
8348
8349 case ARG_POINTER_REGNUM:
8350 s390_init_frame_layout ();
8351 offset = cfun_frame_layout.frame_size + STACK_POINTER_OFFSET;
8352 break;
8353
8354 case RETURN_ADDRESS_POINTER_REGNUM:
8355 s390_init_frame_layout ();
8356 index = RETURN_REGNUM - cfun_frame_layout.first_save_gpr_slot;
8357 gcc_assert (index >= 0);
8358 offset = cfun_frame_layout.frame_size + cfun_frame_layout.gprs_offset;
8359 offset += index * UNITS_PER_LONG;
8360 break;
8361
8362 case BASE_REGNUM:
8363 offset = 0;
8364 break;
8365
8366 default:
8367 gcc_unreachable ();
8368 }
8369
8370 return offset;
8371 }
8372
8373 /* Emit insn to save fpr REGNUM at offset OFFSET relative
8374 to register BASE. Return generated insn. */
8375
8376 static rtx
save_fpr(rtx base,int offset,int regnum)8377 save_fpr (rtx base, int offset, int regnum)
8378 {
8379 rtx addr;
8380 addr = gen_rtx_MEM (DFmode, plus_constant (Pmode, base, offset));
8381
8382 if (regnum >= 16 && regnum <= (16 + FP_ARG_NUM_REG))
8383 set_mem_alias_set (addr, get_varargs_alias_set ());
8384 else
8385 set_mem_alias_set (addr, get_frame_alias_set ());
8386
8387 return emit_move_insn (addr, gen_rtx_REG (DFmode, regnum));
8388 }
8389
8390 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
8391 to register BASE. Return generated insn. */
8392
8393 static rtx
restore_fpr(rtx base,int offset,int regnum)8394 restore_fpr (rtx base, int offset, int regnum)
8395 {
8396 rtx addr;
8397 addr = gen_rtx_MEM (DFmode, plus_constant (Pmode, base, offset));
8398 set_mem_alias_set (addr, get_frame_alias_set ());
8399
8400 return emit_move_insn (gen_rtx_REG (DFmode, regnum), addr);
8401 }
8402
8403 /* Return true if REGNO is a global register, but not one
8404 of the special ones that need to be saved/restored in anyway. */
8405
8406 static inline bool
global_not_special_regno_p(int regno)8407 global_not_special_regno_p (int regno)
8408 {
8409 return (global_regs[regno]
8410 /* These registers are special and need to be
8411 restored in any case. */
8412 && !(regno == STACK_POINTER_REGNUM
8413 || regno == RETURN_REGNUM
8414 || regno == BASE_REGNUM
8415 || (flag_pic && regno == (int)PIC_OFFSET_TABLE_REGNUM)));
8416 }
8417
8418 /* Generate insn to save registers FIRST to LAST into
8419 the register save area located at offset OFFSET
8420 relative to register BASE. */
8421
8422 static rtx
save_gprs(rtx base,int offset,int first,int last)8423 save_gprs (rtx base, int offset, int first, int last)
8424 {
8425 rtx addr, insn, note;
8426 int i;
8427
8428 addr = plus_constant (Pmode, base, offset);
8429 addr = gen_rtx_MEM (Pmode, addr);
8430
8431 set_mem_alias_set (addr, get_frame_alias_set ());
8432
8433 /* Special-case single register. */
8434 if (first == last)
8435 {
8436 if (TARGET_64BIT)
8437 insn = gen_movdi (addr, gen_rtx_REG (Pmode, first));
8438 else
8439 insn = gen_movsi (addr, gen_rtx_REG (Pmode, first));
8440
8441 if (!global_not_special_regno_p (first))
8442 RTX_FRAME_RELATED_P (insn) = 1;
8443 return insn;
8444 }
8445
8446
8447 insn = gen_store_multiple (addr,
8448 gen_rtx_REG (Pmode, first),
8449 GEN_INT (last - first + 1));
8450
8451 if (first <= 6 && cfun->stdarg)
8452 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
8453 {
8454 rtx mem = XEXP (XVECEXP (PATTERN (insn), 0, i), 0);
8455
8456 if (first + i <= 6)
8457 set_mem_alias_set (mem, get_varargs_alias_set ());
8458 }
8459
8460 /* We need to set the FRAME_RELATED flag on all SETs
8461 inside the store-multiple pattern.
8462
8463 However, we must not emit DWARF records for registers 2..5
8464 if they are stored for use by variable arguments ...
8465
8466 ??? Unfortunately, it is not enough to simply not the
8467 FRAME_RELATED flags for those SETs, because the first SET
8468 of the PARALLEL is always treated as if it had the flag
8469 set, even if it does not. Therefore we emit a new pattern
8470 without those registers as REG_FRAME_RELATED_EXPR note. */
8471
8472 if (first >= 6 && !global_not_special_regno_p (first))
8473 {
8474 rtx pat = PATTERN (insn);
8475
8476 for (i = 0; i < XVECLEN (pat, 0); i++)
8477 if (GET_CODE (XVECEXP (pat, 0, i)) == SET
8478 && !global_not_special_regno_p (REGNO (SET_SRC (XVECEXP (pat,
8479 0, i)))))
8480 RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1;
8481
8482 RTX_FRAME_RELATED_P (insn) = 1;
8483 }
8484 else if (last >= 6)
8485 {
8486 int start;
8487
8488 for (start = first >= 6 ? first : 6; start <= last; start++)
8489 if (!global_not_special_regno_p (start))
8490 break;
8491
8492 if (start > last)
8493 return insn;
8494
8495 addr = plus_constant (Pmode, base,
8496 offset + (start - first) * UNITS_PER_LONG);
8497 note = gen_store_multiple (gen_rtx_MEM (Pmode, addr),
8498 gen_rtx_REG (Pmode, start),
8499 GEN_INT (last - start + 1));
8500 note = PATTERN (note);
8501
8502 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
8503
8504 for (i = 0; i < XVECLEN (note, 0); i++)
8505 if (GET_CODE (XVECEXP (note, 0, i)) == SET
8506 && !global_not_special_regno_p (REGNO (SET_SRC (XVECEXP (note,
8507 0, i)))))
8508 RTX_FRAME_RELATED_P (XVECEXP (note, 0, i)) = 1;
8509
8510 RTX_FRAME_RELATED_P (insn) = 1;
8511 }
8512
8513 return insn;
8514 }
8515
8516 /* Generate insn to restore registers FIRST to LAST from
8517 the register save area located at offset OFFSET
8518 relative to register BASE. */
8519
8520 static rtx
restore_gprs(rtx base,int offset,int first,int last)8521 restore_gprs (rtx base, int offset, int first, int last)
8522 {
8523 rtx addr, insn;
8524
8525 addr = plus_constant (Pmode, base, offset);
8526 addr = gen_rtx_MEM (Pmode, addr);
8527 set_mem_alias_set (addr, get_frame_alias_set ());
8528
8529 /* Special-case single register. */
8530 if (first == last)
8531 {
8532 if (TARGET_64BIT)
8533 insn = gen_movdi (gen_rtx_REG (Pmode, first), addr);
8534 else
8535 insn = gen_movsi (gen_rtx_REG (Pmode, first), addr);
8536
8537 return insn;
8538 }
8539
8540 insn = gen_load_multiple (gen_rtx_REG (Pmode, first),
8541 addr,
8542 GEN_INT (last - first + 1));
8543 return insn;
8544 }
8545
8546 /* Return insn sequence to load the GOT register. */
8547
8548 static GTY(()) rtx got_symbol;
8549 rtx
s390_load_got(void)8550 s390_load_got (void)
8551 {
8552 rtx insns;
8553
8554 /* We cannot use pic_offset_table_rtx here since we use this
8555 function also for non-pic if __tls_get_offset is called and in
8556 that case PIC_OFFSET_TABLE_REGNUM as well as pic_offset_table_rtx
8557 aren't usable. */
8558 rtx got_rtx = gen_rtx_REG (Pmode, 12);
8559
8560 if (!got_symbol)
8561 {
8562 got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
8563 SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
8564 }
8565
8566 start_sequence ();
8567
8568 if (TARGET_CPU_ZARCH)
8569 {
8570 emit_move_insn (got_rtx, got_symbol);
8571 }
8572 else
8573 {
8574 rtx offset;
8575
8576 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got_symbol),
8577 UNSPEC_LTREL_OFFSET);
8578 offset = gen_rtx_CONST (Pmode, offset);
8579 offset = force_const_mem (Pmode, offset);
8580
8581 emit_move_insn (got_rtx, offset);
8582
8583 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (offset, 0)),
8584 UNSPEC_LTREL_BASE);
8585 offset = gen_rtx_PLUS (Pmode, got_rtx, offset);
8586
8587 emit_move_insn (got_rtx, offset);
8588 }
8589
8590 insns = get_insns ();
8591 end_sequence ();
8592 return insns;
8593 }
8594
8595 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
8596 and the change to the stack pointer. */
8597
8598 static void
s390_emit_stack_tie(void)8599 s390_emit_stack_tie (void)
8600 {
8601 rtx mem = gen_frame_mem (BLKmode,
8602 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
8603
8604 emit_insn (gen_stack_tie (mem));
8605 }
8606
8607 /* Expand the prologue into a bunch of separate insns. */
8608
8609 void
s390_emit_prologue(void)8610 s390_emit_prologue (void)
8611 {
8612 rtx insn, addr;
8613 rtx temp_reg;
8614 int i;
8615 int offset;
8616 int next_fpr = 0;
8617
8618 /* Try to get rid of the FPR clobbers. */
8619 s390_optimize_nonescaping_tx ();
8620
8621 /* Complete frame layout. */
8622 s390_update_frame_layout ();
8623
8624 /* Annotate all constant pool references to let the scheduler know
8625 they implicitly use the base register. */
8626
8627 push_topmost_sequence ();
8628
8629 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8630 if (INSN_P (insn))
8631 {
8632 annotate_constant_pool_refs (&PATTERN (insn));
8633 df_insn_rescan (insn);
8634 }
8635
8636 pop_topmost_sequence ();
8637
8638 /* Choose best register to use for temp use within prologue.
8639 See below for why TPF must use the register 1. */
8640
8641 if (!has_hard_reg_initial_val (Pmode, RETURN_REGNUM)
8642 && !crtl->is_leaf
8643 && !TARGET_TPF_PROFILING)
8644 temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
8645 else
8646 temp_reg = gen_rtx_REG (Pmode, 1);
8647
8648 /* Save call saved gprs. */
8649 if (cfun_frame_layout.first_save_gpr != -1)
8650 {
8651 insn = save_gprs (stack_pointer_rtx,
8652 cfun_frame_layout.gprs_offset +
8653 UNITS_PER_LONG * (cfun_frame_layout.first_save_gpr
8654 - cfun_frame_layout.first_save_gpr_slot),
8655 cfun_frame_layout.first_save_gpr,
8656 cfun_frame_layout.last_save_gpr);
8657 emit_insn (insn);
8658 }
8659
8660 /* Dummy insn to mark literal pool slot. */
8661
8662 if (cfun->machine->base_reg)
8663 emit_insn (gen_main_pool (cfun->machine->base_reg));
8664
8665 offset = cfun_frame_layout.f0_offset;
8666
8667 /* Save f0 and f2. */
8668 for (i = 0; i < 2; i++)
8669 {
8670 if (cfun_fpr_bit_p (i))
8671 {
8672 save_fpr (stack_pointer_rtx, offset, i + 16);
8673 offset += 8;
8674 }
8675 else if (!TARGET_PACKED_STACK)
8676 offset += 8;
8677 }
8678
8679 /* Save f4 and f6. */
8680 offset = cfun_frame_layout.f4_offset;
8681 for (i = 2; i < 4; i++)
8682 {
8683 if (cfun_fpr_bit_p (i))
8684 {
8685 insn = save_fpr (stack_pointer_rtx, offset, i + 16);
8686 offset += 8;
8687
8688 /* If f4 and f6 are call clobbered they are saved due to stdargs and
8689 therefore are not frame related. */
8690 if (!call_really_used_regs[i + 16])
8691 RTX_FRAME_RELATED_P (insn) = 1;
8692 }
8693 else if (!TARGET_PACKED_STACK)
8694 offset += 8;
8695 }
8696
8697 if (TARGET_PACKED_STACK
8698 && cfun_save_high_fprs_p
8699 && cfun_frame_layout.f8_offset + cfun_frame_layout.high_fprs * 8 > 0)
8700 {
8701 offset = (cfun_frame_layout.f8_offset
8702 + (cfun_frame_layout.high_fprs - 1) * 8);
8703
8704 for (i = 15; i > 7 && offset >= 0; i--)
8705 if (cfun_fpr_bit_p (i))
8706 {
8707 insn = save_fpr (stack_pointer_rtx, offset, i + 16);
8708
8709 RTX_FRAME_RELATED_P (insn) = 1;
8710 offset -= 8;
8711 }
8712 if (offset >= cfun_frame_layout.f8_offset)
8713 next_fpr = i + 16;
8714 }
8715
8716 if (!TARGET_PACKED_STACK)
8717 next_fpr = cfun_save_high_fprs_p ? 31 : 0;
8718
8719 if (flag_stack_usage_info)
8720 current_function_static_stack_size = cfun_frame_layout.frame_size;
8721
8722 /* Decrement stack pointer. */
8723
8724 if (cfun_frame_layout.frame_size > 0)
8725 {
8726 rtx frame_off = GEN_INT (-cfun_frame_layout.frame_size);
8727 rtx real_frame_off;
8728
8729 if (s390_stack_size)
8730 {
8731 HOST_WIDE_INT stack_guard;
8732
8733 if (s390_stack_guard)
8734 stack_guard = s390_stack_guard;
8735 else
8736 {
8737 /* If no value for stack guard is provided the smallest power of 2
8738 larger than the current frame size is chosen. */
8739 stack_guard = 1;
8740 while (stack_guard < cfun_frame_layout.frame_size)
8741 stack_guard <<= 1;
8742 }
8743
8744 if (cfun_frame_layout.frame_size >= s390_stack_size)
8745 {
8746 warning (0, "frame size of function %qs is %wd"
8747 " bytes exceeding user provided stack limit of "
8748 "%d bytes. "
8749 "An unconditional trap is added.",
8750 current_function_name(), cfun_frame_layout.frame_size,
8751 s390_stack_size);
8752 emit_insn (gen_trap ());
8753 }
8754 else
8755 {
8756 /* stack_guard has to be smaller than s390_stack_size.
8757 Otherwise we would emit an AND with zero which would
8758 not match the test under mask pattern. */
8759 if (stack_guard >= s390_stack_size)
8760 {
8761 warning (0, "frame size of function %qs is %wd"
8762 " bytes which is more than half the stack size. "
8763 "The dynamic check would not be reliable. "
8764 "No check emitted for this function.",
8765 current_function_name(),
8766 cfun_frame_layout.frame_size);
8767 }
8768 else
8769 {
8770 HOST_WIDE_INT stack_check_mask = ((s390_stack_size - 1)
8771 & ~(stack_guard - 1));
8772
8773 rtx t = gen_rtx_AND (Pmode, stack_pointer_rtx,
8774 GEN_INT (stack_check_mask));
8775 if (TARGET_64BIT)
8776 emit_insn (gen_ctrapdi4 (gen_rtx_EQ (VOIDmode,
8777 t, const0_rtx),
8778 t, const0_rtx, const0_rtx));
8779 else
8780 emit_insn (gen_ctrapsi4 (gen_rtx_EQ (VOIDmode,
8781 t, const0_rtx),
8782 t, const0_rtx, const0_rtx));
8783 }
8784 }
8785 }
8786
8787 if (s390_warn_framesize > 0
8788 && cfun_frame_layout.frame_size >= s390_warn_framesize)
8789 warning (0, "frame size of %qs is %wd bytes",
8790 current_function_name (), cfun_frame_layout.frame_size);
8791
8792 if (s390_warn_dynamicstack_p && cfun->calls_alloca)
8793 warning (0, "%qs uses dynamic stack allocation", current_function_name ());
8794
8795 /* Save incoming stack pointer into temp reg. */
8796 if (TARGET_BACKCHAIN || next_fpr)
8797 insn = emit_insn (gen_move_insn (temp_reg, stack_pointer_rtx));
8798
8799 /* Subtract frame size from stack pointer. */
8800
8801 if (DISP_IN_RANGE (INTVAL (frame_off)))
8802 {
8803 insn = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
8804 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
8805 frame_off));
8806 insn = emit_insn (insn);
8807 }
8808 else
8809 {
8810 if (!CONST_OK_FOR_K (INTVAL (frame_off)))
8811 frame_off = force_const_mem (Pmode, frame_off);
8812
8813 insn = emit_insn (gen_add2_insn (stack_pointer_rtx, frame_off));
8814 annotate_constant_pool_refs (&PATTERN (insn));
8815 }
8816
8817 RTX_FRAME_RELATED_P (insn) = 1;
8818 real_frame_off = GEN_INT (-cfun_frame_layout.frame_size);
8819 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
8820 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
8821 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
8822 real_frame_off)));
8823
8824 /* Set backchain. */
8825
8826 if (TARGET_BACKCHAIN)
8827 {
8828 if (cfun_frame_layout.backchain_offset)
8829 addr = gen_rtx_MEM (Pmode,
8830 plus_constant (Pmode, stack_pointer_rtx,
8831 cfun_frame_layout.backchain_offset));
8832 else
8833 addr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
8834 set_mem_alias_set (addr, get_frame_alias_set ());
8835 insn = emit_insn (gen_move_insn (addr, temp_reg));
8836 }
8837
8838 /* If we support non-call exceptions (e.g. for Java),
8839 we need to make sure the backchain pointer is set up
8840 before any possibly trapping memory access. */
8841 if (TARGET_BACKCHAIN && cfun->can_throw_non_call_exceptions)
8842 {
8843 addr = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
8844 emit_clobber (addr);
8845 }
8846 }
8847
8848 /* Save fprs 8 - 15 (64 bit ABI). */
8849
8850 if (cfun_save_high_fprs_p && next_fpr)
8851 {
8852 /* If the stack might be accessed through a different register
8853 we have to make sure that the stack pointer decrement is not
8854 moved below the use of the stack slots. */
8855 s390_emit_stack_tie ();
8856
8857 insn = emit_insn (gen_add2_insn (temp_reg,
8858 GEN_INT (cfun_frame_layout.f8_offset)));
8859
8860 offset = 0;
8861
8862 for (i = 24; i <= next_fpr; i++)
8863 if (cfun_fpr_bit_p (i - 16))
8864 {
8865 rtx addr = plus_constant (Pmode, stack_pointer_rtx,
8866 cfun_frame_layout.frame_size
8867 + cfun_frame_layout.f8_offset
8868 + offset);
8869
8870 insn = save_fpr (temp_reg, offset, i);
8871 offset += 8;
8872 RTX_FRAME_RELATED_P (insn) = 1;
8873 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
8874 gen_rtx_SET (VOIDmode,
8875 gen_rtx_MEM (DFmode, addr),
8876 gen_rtx_REG (DFmode, i)));
8877 }
8878 }
8879
8880 /* Set frame pointer, if needed. */
8881
8882 if (frame_pointer_needed)
8883 {
8884 insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
8885 RTX_FRAME_RELATED_P (insn) = 1;
8886 }
8887
8888 /* Set up got pointer, if needed. */
8889
8890 if (flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM))
8891 {
8892 rtx insns = s390_load_got ();
8893
8894 for (insn = insns; insn; insn = NEXT_INSN (insn))
8895 annotate_constant_pool_refs (&PATTERN (insn));
8896
8897 emit_insn (insns);
8898 }
8899
8900 if (TARGET_TPF_PROFILING)
8901 {
8902 /* Generate a BAS instruction to serve as a function
8903 entry intercept to facilitate the use of tracing
8904 algorithms located at the branch target. */
8905 emit_insn (gen_prologue_tpf ());
8906
8907 /* Emit a blockage here so that all code
8908 lies between the profiling mechanisms. */
8909 emit_insn (gen_blockage ());
8910 }
8911 }
8912
8913 /* Expand the epilogue into a bunch of separate insns. */
8914
8915 void
s390_emit_epilogue(bool sibcall)8916 s390_emit_epilogue (bool sibcall)
8917 {
8918 rtx frame_pointer, return_reg, cfa_restores = NULL_RTX;
8919 int area_bottom, area_top, offset = 0;
8920 int next_offset;
8921 rtvec p;
8922 int i;
8923
8924 if (TARGET_TPF_PROFILING)
8925 {
8926
8927 /* Generate a BAS instruction to serve as a function
8928 entry intercept to facilitate the use of tracing
8929 algorithms located at the branch target. */
8930
8931 /* Emit a blockage here so that all code
8932 lies between the profiling mechanisms. */
8933 emit_insn (gen_blockage ());
8934
8935 emit_insn (gen_epilogue_tpf ());
8936 }
8937
8938 /* Check whether to use frame or stack pointer for restore. */
8939
8940 frame_pointer = (frame_pointer_needed
8941 ? hard_frame_pointer_rtx : stack_pointer_rtx);
8942
8943 s390_frame_area (&area_bottom, &area_top);
8944
8945 /* Check whether we can access the register save area.
8946 If not, increment the frame pointer as required. */
8947
8948 if (area_top <= area_bottom)
8949 {
8950 /* Nothing to restore. */
8951 }
8952 else if (DISP_IN_RANGE (cfun_frame_layout.frame_size + area_bottom)
8953 && DISP_IN_RANGE (cfun_frame_layout.frame_size + area_top - 1))
8954 {
8955 /* Area is in range. */
8956 offset = cfun_frame_layout.frame_size;
8957 }
8958 else
8959 {
8960 rtx insn, frame_off, cfa;
8961
8962 offset = area_bottom < 0 ? -area_bottom : 0;
8963 frame_off = GEN_INT (cfun_frame_layout.frame_size - offset);
8964
8965 cfa = gen_rtx_SET (VOIDmode, frame_pointer,
8966 gen_rtx_PLUS (Pmode, frame_pointer, frame_off));
8967 if (DISP_IN_RANGE (INTVAL (frame_off)))
8968 {
8969 insn = gen_rtx_SET (VOIDmode, frame_pointer,
8970 gen_rtx_PLUS (Pmode, frame_pointer, frame_off));
8971 insn = emit_insn (insn);
8972 }
8973 else
8974 {
8975 if (!CONST_OK_FOR_K (INTVAL (frame_off)))
8976 frame_off = force_const_mem (Pmode, frame_off);
8977
8978 insn = emit_insn (gen_add2_insn (frame_pointer, frame_off));
8979 annotate_constant_pool_refs (&PATTERN (insn));
8980 }
8981 add_reg_note (insn, REG_CFA_ADJUST_CFA, cfa);
8982 RTX_FRAME_RELATED_P (insn) = 1;
8983 }
8984
8985 /* Restore call saved fprs. */
8986
8987 if (TARGET_64BIT)
8988 {
8989 if (cfun_save_high_fprs_p)
8990 {
8991 next_offset = cfun_frame_layout.f8_offset;
8992 for (i = 24; i < 32; i++)
8993 {
8994 if (cfun_fpr_bit_p (i - 16))
8995 {
8996 restore_fpr (frame_pointer,
8997 offset + next_offset, i);
8998 cfa_restores
8999 = alloc_reg_note (REG_CFA_RESTORE,
9000 gen_rtx_REG (DFmode, i), cfa_restores);
9001 next_offset += 8;
9002 }
9003 }
9004 }
9005
9006 }
9007 else
9008 {
9009 next_offset = cfun_frame_layout.f4_offset;
9010 for (i = 18; i < 20; i++)
9011 {
9012 if (cfun_fpr_bit_p (i - 16))
9013 {
9014 restore_fpr (frame_pointer,
9015 offset + next_offset, i);
9016 cfa_restores
9017 = alloc_reg_note (REG_CFA_RESTORE,
9018 gen_rtx_REG (DFmode, i), cfa_restores);
9019 next_offset += 8;
9020 }
9021 else if (!TARGET_PACKED_STACK)
9022 next_offset += 8;
9023 }
9024
9025 }
9026
9027 /* Return register. */
9028
9029 return_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
9030
9031 /* Restore call saved gprs. */
9032
9033 if (cfun_frame_layout.first_restore_gpr != -1)
9034 {
9035 rtx insn, addr;
9036 int i;
9037
9038 /* Check for global register and save them
9039 to stack location from where they get restored. */
9040
9041 for (i = cfun_frame_layout.first_restore_gpr;
9042 i <= cfun_frame_layout.last_restore_gpr;
9043 i++)
9044 {
9045 if (global_not_special_regno_p (i))
9046 {
9047 addr = plus_constant (Pmode, frame_pointer,
9048 offset + cfun_frame_layout.gprs_offset
9049 + (i - cfun_frame_layout.first_save_gpr_slot)
9050 * UNITS_PER_LONG);
9051 addr = gen_rtx_MEM (Pmode, addr);
9052 set_mem_alias_set (addr, get_frame_alias_set ());
9053 emit_move_insn (addr, gen_rtx_REG (Pmode, i));
9054 }
9055 else
9056 cfa_restores
9057 = alloc_reg_note (REG_CFA_RESTORE,
9058 gen_rtx_REG (Pmode, i), cfa_restores);
9059 }
9060
9061 if (! sibcall)
9062 {
9063 /* Fetch return address from stack before load multiple,
9064 this will do good for scheduling. */
9065
9066 if (cfun_frame_layout.save_return_addr_p
9067 || (cfun_frame_layout.first_restore_gpr < BASE_REGNUM
9068 && cfun_frame_layout.last_restore_gpr > RETURN_REGNUM))
9069 {
9070 int return_regnum = find_unused_clobbered_reg();
9071 if (!return_regnum)
9072 return_regnum = 4;
9073 return_reg = gen_rtx_REG (Pmode, return_regnum);
9074
9075 addr = plus_constant (Pmode, frame_pointer,
9076 offset + cfun_frame_layout.gprs_offset
9077 + (RETURN_REGNUM
9078 - cfun_frame_layout.first_save_gpr_slot)
9079 * UNITS_PER_LONG);
9080 addr = gen_rtx_MEM (Pmode, addr);
9081 set_mem_alias_set (addr, get_frame_alias_set ());
9082 emit_move_insn (return_reg, addr);
9083 }
9084 }
9085
9086 insn = restore_gprs (frame_pointer,
9087 offset + cfun_frame_layout.gprs_offset
9088 + (cfun_frame_layout.first_restore_gpr
9089 - cfun_frame_layout.first_save_gpr_slot)
9090 * UNITS_PER_LONG,
9091 cfun_frame_layout.first_restore_gpr,
9092 cfun_frame_layout.last_restore_gpr);
9093 insn = emit_insn (insn);
9094 REG_NOTES (insn) = cfa_restores;
9095 add_reg_note (insn, REG_CFA_DEF_CFA,
9096 plus_constant (Pmode, stack_pointer_rtx,
9097 STACK_POINTER_OFFSET));
9098 RTX_FRAME_RELATED_P (insn) = 1;
9099 }
9100
9101 if (! sibcall)
9102 {
9103
9104 /* Return to caller. */
9105
9106 p = rtvec_alloc (2);
9107
9108 RTVEC_ELT (p, 0) = ret_rtx;
9109 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, return_reg);
9110 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
9111 }
9112 }
9113
9114
9115 /* Return the size in bytes of a function argument of
9116 type TYPE and/or mode MODE. At least one of TYPE or
9117 MODE must be specified. */
9118
9119 static int
s390_function_arg_size(enum machine_mode mode,const_tree type)9120 s390_function_arg_size (enum machine_mode mode, const_tree type)
9121 {
9122 if (type)
9123 return int_size_in_bytes (type);
9124
9125 /* No type info available for some library calls ... */
9126 if (mode != BLKmode)
9127 return GET_MODE_SIZE (mode);
9128
9129 /* If we have neither type nor mode, abort */
9130 gcc_unreachable ();
9131 }
9132
9133 /* Return true if a function argument of type TYPE and mode MODE
9134 is to be passed in a floating-point register, if available. */
9135
9136 static bool
s390_function_arg_float(enum machine_mode mode,const_tree type)9137 s390_function_arg_float (enum machine_mode mode, const_tree type)
9138 {
9139 int size = s390_function_arg_size (mode, type);
9140 if (size > 8)
9141 return false;
9142
9143 /* Soft-float changes the ABI: no floating-point registers are used. */
9144 if (TARGET_SOFT_FLOAT)
9145 return false;
9146
9147 /* No type info available for some library calls ... */
9148 if (!type)
9149 return mode == SFmode || mode == DFmode || mode == SDmode || mode == DDmode;
9150
9151 /* The ABI says that record types with a single member are treated
9152 just like that member would be. */
9153 while (TREE_CODE (type) == RECORD_TYPE)
9154 {
9155 tree field, single = NULL_TREE;
9156
9157 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
9158 {
9159 if (TREE_CODE (field) != FIELD_DECL)
9160 continue;
9161
9162 if (single == NULL_TREE)
9163 single = TREE_TYPE (field);
9164 else
9165 return false;
9166 }
9167
9168 if (single == NULL_TREE)
9169 return false;
9170 else
9171 type = single;
9172 }
9173
9174 return TREE_CODE (type) == REAL_TYPE;
9175 }
9176
9177 /* Return true if a function argument of type TYPE and mode MODE
9178 is to be passed in an integer register, or a pair of integer
9179 registers, if available. */
9180
9181 static bool
s390_function_arg_integer(enum machine_mode mode,const_tree type)9182 s390_function_arg_integer (enum machine_mode mode, const_tree type)
9183 {
9184 int size = s390_function_arg_size (mode, type);
9185 if (size > 8)
9186 return false;
9187
9188 /* No type info available for some library calls ... */
9189 if (!type)
9190 return GET_MODE_CLASS (mode) == MODE_INT
9191 || (TARGET_SOFT_FLOAT && SCALAR_FLOAT_MODE_P (mode));
9192
9193 /* We accept small integral (and similar) types. */
9194 if (INTEGRAL_TYPE_P (type)
9195 || POINTER_TYPE_P (type)
9196 || TREE_CODE (type) == NULLPTR_TYPE
9197 || TREE_CODE (type) == OFFSET_TYPE
9198 || (TARGET_SOFT_FLOAT && TREE_CODE (type) == REAL_TYPE))
9199 return true;
9200
9201 /* We also accept structs of size 1, 2, 4, 8 that are not
9202 passed in floating-point registers. */
9203 if (AGGREGATE_TYPE_P (type)
9204 && exact_log2 (size) >= 0
9205 && !s390_function_arg_float (mode, type))
9206 return true;
9207
9208 return false;
9209 }
9210
9211 /* Return 1 if a function argument of type TYPE and mode MODE
9212 is to be passed by reference. The ABI specifies that only
9213 structures of size 1, 2, 4, or 8 bytes are passed by value,
9214 all other structures (and complex numbers) are passed by
9215 reference. */
9216
9217 static bool
s390_pass_by_reference(cumulative_args_t ca ATTRIBUTE_UNUSED,enum machine_mode mode,const_tree type,bool named ATTRIBUTE_UNUSED)9218 s390_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED,
9219 enum machine_mode mode, const_tree type,
9220 bool named ATTRIBUTE_UNUSED)
9221 {
9222 int size = s390_function_arg_size (mode, type);
9223 if (size > 8)
9224 return true;
9225
9226 if (type)
9227 {
9228 if (AGGREGATE_TYPE_P (type) && exact_log2 (size) < 0)
9229 return 1;
9230
9231 if (TREE_CODE (type) == COMPLEX_TYPE
9232 || TREE_CODE (type) == VECTOR_TYPE)
9233 return 1;
9234 }
9235
9236 return 0;
9237 }
9238
9239 /* Update the data in CUM to advance over an argument of mode MODE and
9240 data type TYPE. (TYPE is null for libcalls where that information
9241 may not be available.). The boolean NAMED specifies whether the
9242 argument is a named argument (as opposed to an unnamed argument
9243 matching an ellipsis). */
9244
9245 static void
s390_function_arg_advance(cumulative_args_t cum_v,enum machine_mode mode,const_tree type,bool named ATTRIBUTE_UNUSED)9246 s390_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
9247 const_tree type, bool named ATTRIBUTE_UNUSED)
9248 {
9249 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
9250
9251 if (s390_function_arg_float (mode, type))
9252 {
9253 cum->fprs += 1;
9254 }
9255 else if (s390_function_arg_integer (mode, type))
9256 {
9257 int size = s390_function_arg_size (mode, type);
9258 cum->gprs += ((size + UNITS_PER_LONG - 1) / UNITS_PER_LONG);
9259 }
9260 else
9261 gcc_unreachable ();
9262 }
9263
9264 /* Define where to put the arguments to a function.
9265 Value is zero to push the argument on the stack,
9266 or a hard register in which to store the argument.
9267
9268 MODE is the argument's machine mode.
9269 TYPE is the data type of the argument (as a tree).
9270 This is null for libcalls where that information may
9271 not be available.
9272 CUM is a variable of type CUMULATIVE_ARGS which gives info about
9273 the preceding args and about the function being called.
9274 NAMED is nonzero if this argument is a named parameter
9275 (otherwise it is an extra parameter matching an ellipsis).
9276
9277 On S/390, we use general purpose registers 2 through 6 to
9278 pass integer, pointer, and certain structure arguments, and
9279 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
9280 to pass floating point arguments. All remaining arguments
9281 are pushed to the stack. */
9282
9283 static rtx
s390_function_arg(cumulative_args_t cum_v,enum machine_mode mode,const_tree type,bool named ATTRIBUTE_UNUSED)9284 s390_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
9285 const_tree type, bool named ATTRIBUTE_UNUSED)
9286 {
9287 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
9288
9289 if (s390_function_arg_float (mode, type))
9290 {
9291 if (cum->fprs + 1 > FP_ARG_NUM_REG)
9292 return 0;
9293 else
9294 return gen_rtx_REG (mode, cum->fprs + 16);
9295 }
9296 else if (s390_function_arg_integer (mode, type))
9297 {
9298 int size = s390_function_arg_size (mode, type);
9299 int n_gprs = (size + UNITS_PER_LONG - 1) / UNITS_PER_LONG;
9300
9301 if (cum->gprs + n_gprs > GP_ARG_NUM_REG)
9302 return 0;
9303 else if (n_gprs == 1 || UNITS_PER_WORD == UNITS_PER_LONG)
9304 return gen_rtx_REG (mode, cum->gprs + 2);
9305 else if (n_gprs == 2)
9306 {
9307 rtvec p = rtvec_alloc (2);
9308
9309 RTVEC_ELT (p, 0)
9310 = gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, cum->gprs + 2),
9311 const0_rtx);
9312 RTVEC_ELT (p, 1)
9313 = gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, cum->gprs + 3),
9314 GEN_INT (4));
9315
9316 return gen_rtx_PARALLEL (mode, p);
9317 }
9318 }
9319
9320 /* After the real arguments, expand_call calls us once again
9321 with a void_type_node type. Whatever we return here is
9322 passed as operand 2 to the call expanders.
9323
9324 We don't need this feature ... */
9325 else if (type == void_type_node)
9326 return const0_rtx;
9327
9328 gcc_unreachable ();
9329 }
9330
9331 /* Return true if return values of type TYPE should be returned
9332 in a memory buffer whose address is passed by the caller as
9333 hidden first argument. */
9334
9335 static bool
s390_return_in_memory(const_tree type,const_tree fundecl ATTRIBUTE_UNUSED)9336 s390_return_in_memory (const_tree type, const_tree fundecl ATTRIBUTE_UNUSED)
9337 {
9338 /* We accept small integral (and similar) types. */
9339 if (INTEGRAL_TYPE_P (type)
9340 || POINTER_TYPE_P (type)
9341 || TREE_CODE (type) == OFFSET_TYPE
9342 || TREE_CODE (type) == REAL_TYPE)
9343 return int_size_in_bytes (type) > 8;
9344
9345 /* Aggregates and similar constructs are always returned
9346 in memory. */
9347 if (AGGREGATE_TYPE_P (type)
9348 || TREE_CODE (type) == COMPLEX_TYPE
9349 || TREE_CODE (type) == VECTOR_TYPE)
9350 return true;
9351
9352 /* ??? We get called on all sorts of random stuff from
9353 aggregate_value_p. We can't abort, but it's not clear
9354 what's safe to return. Pretend it's a struct I guess. */
9355 return true;
9356 }
9357
9358 /* Function arguments and return values are promoted to word size. */
9359
9360 static enum machine_mode
s390_promote_function_mode(const_tree type,enum machine_mode mode,int * punsignedp,const_tree fntype ATTRIBUTE_UNUSED,int for_return ATTRIBUTE_UNUSED)9361 s390_promote_function_mode (const_tree type, enum machine_mode mode,
9362 int *punsignedp,
9363 const_tree fntype ATTRIBUTE_UNUSED,
9364 int for_return ATTRIBUTE_UNUSED)
9365 {
9366 if (INTEGRAL_MODE_P (mode)
9367 && GET_MODE_SIZE (mode) < UNITS_PER_LONG)
9368 {
9369 if (type != NULL_TREE && POINTER_TYPE_P (type))
9370 *punsignedp = POINTERS_EXTEND_UNSIGNED;
9371 return Pmode;
9372 }
9373
9374 return mode;
9375 }
9376
9377 /* Define where to return a (scalar) value of type RET_TYPE.
9378 If RET_TYPE is null, define where to return a (scalar)
9379 value of mode MODE from a libcall. */
9380
9381 static rtx
s390_function_and_libcall_value(enum machine_mode mode,const_tree ret_type,const_tree fntype_or_decl,bool outgoing ATTRIBUTE_UNUSED)9382 s390_function_and_libcall_value (enum machine_mode mode,
9383 const_tree ret_type,
9384 const_tree fntype_or_decl,
9385 bool outgoing ATTRIBUTE_UNUSED)
9386 {
9387 /* For normal functions perform the promotion as
9388 promote_function_mode would do. */
9389 if (ret_type)
9390 {
9391 int unsignedp = TYPE_UNSIGNED (ret_type);
9392 mode = promote_function_mode (ret_type, mode, &unsignedp,
9393 fntype_or_decl, 1);
9394 }
9395
9396 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT || SCALAR_FLOAT_MODE_P (mode));
9397 gcc_assert (GET_MODE_SIZE (mode) <= 8);
9398
9399 if (TARGET_HARD_FLOAT && SCALAR_FLOAT_MODE_P (mode))
9400 return gen_rtx_REG (mode, 16);
9401 else if (GET_MODE_SIZE (mode) <= UNITS_PER_LONG
9402 || UNITS_PER_LONG == UNITS_PER_WORD)
9403 return gen_rtx_REG (mode, 2);
9404 else if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_LONG)
9405 {
9406 /* This case is triggered when returning a 64 bit value with
9407 -m31 -mzarch. Although the value would fit into a single
9408 register it has to be forced into a 32 bit register pair in
9409 order to match the ABI. */
9410 rtvec p = rtvec_alloc (2);
9411
9412 RTVEC_ELT (p, 0)
9413 = gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, 2), const0_rtx);
9414 RTVEC_ELT (p, 1)
9415 = gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, 3), GEN_INT (4));
9416
9417 return gen_rtx_PARALLEL (mode, p);
9418 }
9419
9420 gcc_unreachable ();
9421 }
9422
9423 /* Define where to return a scalar return value of type RET_TYPE. */
9424
9425 static rtx
s390_function_value(const_tree ret_type,const_tree fn_decl_or_type,bool outgoing)9426 s390_function_value (const_tree ret_type, const_tree fn_decl_or_type,
9427 bool outgoing)
9428 {
9429 return s390_function_and_libcall_value (TYPE_MODE (ret_type), ret_type,
9430 fn_decl_or_type, outgoing);
9431 }
9432
9433 /* Define where to return a scalar libcall return value of mode
9434 MODE. */
9435
9436 static rtx
s390_libcall_value(enum machine_mode mode,const_rtx fun ATTRIBUTE_UNUSED)9437 s390_libcall_value (enum machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
9438 {
9439 return s390_function_and_libcall_value (mode, NULL_TREE,
9440 NULL_TREE, true);
9441 }
9442
9443
9444 /* Create and return the va_list datatype.
9445
9446 On S/390, va_list is an array type equivalent to
9447
9448 typedef struct __va_list_tag
9449 {
9450 long __gpr;
9451 long __fpr;
9452 void *__overflow_arg_area;
9453 void *__reg_save_area;
9454 } va_list[1];
9455
9456 where __gpr and __fpr hold the number of general purpose
9457 or floating point arguments used up to now, respectively,
9458 __overflow_arg_area points to the stack location of the
9459 next argument passed on the stack, and __reg_save_area
9460 always points to the start of the register area in the
9461 call frame of the current function. The function prologue
9462 saves all registers used for argument passing into this
9463 area if the function uses variable arguments. */
9464
9465 static tree
s390_build_builtin_va_list(void)9466 s390_build_builtin_va_list (void)
9467 {
9468 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
9469
9470 record = lang_hooks.types.make_type (RECORD_TYPE);
9471
9472 type_decl =
9473 build_decl (BUILTINS_LOCATION,
9474 TYPE_DECL, get_identifier ("__va_list_tag"), record);
9475
9476 f_gpr = build_decl (BUILTINS_LOCATION,
9477 FIELD_DECL, get_identifier ("__gpr"),
9478 long_integer_type_node);
9479 f_fpr = build_decl (BUILTINS_LOCATION,
9480 FIELD_DECL, get_identifier ("__fpr"),
9481 long_integer_type_node);
9482 f_ovf = build_decl (BUILTINS_LOCATION,
9483 FIELD_DECL, get_identifier ("__overflow_arg_area"),
9484 ptr_type_node);
9485 f_sav = build_decl (BUILTINS_LOCATION,
9486 FIELD_DECL, get_identifier ("__reg_save_area"),
9487 ptr_type_node);
9488
9489 va_list_gpr_counter_field = f_gpr;
9490 va_list_fpr_counter_field = f_fpr;
9491
9492 DECL_FIELD_CONTEXT (f_gpr) = record;
9493 DECL_FIELD_CONTEXT (f_fpr) = record;
9494 DECL_FIELD_CONTEXT (f_ovf) = record;
9495 DECL_FIELD_CONTEXT (f_sav) = record;
9496
9497 TYPE_STUB_DECL (record) = type_decl;
9498 TYPE_NAME (record) = type_decl;
9499 TYPE_FIELDS (record) = f_gpr;
9500 DECL_CHAIN (f_gpr) = f_fpr;
9501 DECL_CHAIN (f_fpr) = f_ovf;
9502 DECL_CHAIN (f_ovf) = f_sav;
9503
9504 layout_type (record);
9505
9506 /* The correct type is an array type of one element. */
9507 return build_array_type (record, build_index_type (size_zero_node));
9508 }
9509
9510 /* Implement va_start by filling the va_list structure VALIST.
9511 STDARG_P is always true, and ignored.
9512 NEXTARG points to the first anonymous stack argument.
9513
9514 The following global variables are used to initialize
9515 the va_list structure:
9516
9517 crtl->args.info:
9518 holds number of gprs and fprs used for named arguments.
9519 crtl->args.arg_offset_rtx:
9520 holds the offset of the first anonymous stack argument
9521 (relative to the virtual arg pointer). */
9522
9523 static void
s390_va_start(tree valist,rtx nextarg ATTRIBUTE_UNUSED)9524 s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
9525 {
9526 HOST_WIDE_INT n_gpr, n_fpr;
9527 int off;
9528 tree f_gpr, f_fpr, f_ovf, f_sav;
9529 tree gpr, fpr, ovf, sav, t;
9530
9531 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9532 f_fpr = DECL_CHAIN (f_gpr);
9533 f_ovf = DECL_CHAIN (f_fpr);
9534 f_sav = DECL_CHAIN (f_ovf);
9535
9536 valist = build_simple_mem_ref (valist);
9537 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9538 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
9539 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
9540 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
9541
9542 /* Count number of gp and fp argument registers used. */
9543
9544 n_gpr = crtl->args.info.gprs;
9545 n_fpr = crtl->args.info.fprs;
9546
9547 if (cfun->va_list_gpr_size)
9548 {
9549 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9550 build_int_cst (NULL_TREE, n_gpr));
9551 TREE_SIDE_EFFECTS (t) = 1;
9552 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9553 }
9554
9555 if (cfun->va_list_fpr_size)
9556 {
9557 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9558 build_int_cst (NULL_TREE, n_fpr));
9559 TREE_SIDE_EFFECTS (t) = 1;
9560 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9561 }
9562
9563 /* Find the overflow area. */
9564 if (n_gpr + cfun->va_list_gpr_size > GP_ARG_NUM_REG
9565 || n_fpr + cfun->va_list_fpr_size > FP_ARG_NUM_REG)
9566 {
9567 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9568
9569 off = INTVAL (crtl->args.arg_offset_rtx);
9570 off = off < 0 ? 0 : off;
9571 if (TARGET_DEBUG_ARG)
9572 fprintf (stderr, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
9573 (int)n_gpr, (int)n_fpr, off);
9574
9575 t = fold_build_pointer_plus_hwi (t, off);
9576
9577 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9578 TREE_SIDE_EFFECTS (t) = 1;
9579 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9580 }
9581
9582 /* Find the register save area. */
9583 if ((cfun->va_list_gpr_size && n_gpr < GP_ARG_NUM_REG)
9584 || (cfun->va_list_fpr_size && n_fpr < FP_ARG_NUM_REG))
9585 {
9586 t = make_tree (TREE_TYPE (sav), return_address_pointer_rtx);
9587 t = fold_build_pointer_plus_hwi (t, -RETURN_REGNUM * UNITS_PER_LONG);
9588
9589 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9590 TREE_SIDE_EFFECTS (t) = 1;
9591 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9592 }
9593 }
9594
9595 /* Implement va_arg by updating the va_list structure
9596 VALIST as required to retrieve an argument of type
9597 TYPE, and returning that argument.
9598
9599 Generates code equivalent to:
9600
9601 if (integral value) {
9602 if (size <= 4 && args.gpr < 5 ||
9603 size > 4 && args.gpr < 4 )
9604 ret = args.reg_save_area[args.gpr+8]
9605 else
9606 ret = *args.overflow_arg_area++;
9607 } else if (float value) {
9608 if (args.fgpr < 2)
9609 ret = args.reg_save_area[args.fpr+64]
9610 else
9611 ret = *args.overflow_arg_area++;
9612 } else if (aggregate value) {
9613 if (args.gpr < 5)
9614 ret = *args.reg_save_area[args.gpr]
9615 else
9616 ret = **args.overflow_arg_area++;
9617 } */
9618
9619 static tree
s390_gimplify_va_arg(tree valist,tree type,gimple_seq * pre_p,gimple_seq * post_p ATTRIBUTE_UNUSED)9620 s390_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9621 gimple_seq *post_p ATTRIBUTE_UNUSED)
9622 {
9623 tree f_gpr, f_fpr, f_ovf, f_sav;
9624 tree gpr, fpr, ovf, sav, reg, t, u;
9625 int indirect_p, size, n_reg, sav_ofs, sav_scale, max_reg;
9626 tree lab_false, lab_over, addr;
9627
9628 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9629 f_fpr = DECL_CHAIN (f_gpr);
9630 f_ovf = DECL_CHAIN (f_fpr);
9631 f_sav = DECL_CHAIN (f_ovf);
9632
9633 valist = build_va_arg_indirect_ref (valist);
9634 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9635 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
9636 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
9637
9638 /* The tree for args* cannot be shared between gpr/fpr and ovf since
9639 both appear on a lhs. */
9640 valist = unshare_expr (valist);
9641 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
9642
9643 size = int_size_in_bytes (type);
9644
9645 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9646 {
9647 if (TARGET_DEBUG_ARG)
9648 {
9649 fprintf (stderr, "va_arg: aggregate type");
9650 debug_tree (type);
9651 }
9652
9653 /* Aggregates are passed by reference. */
9654 indirect_p = 1;
9655 reg = gpr;
9656 n_reg = 1;
9657
9658 /* kernel stack layout on 31 bit: It is assumed here that no padding
9659 will be added by s390_frame_info because for va_args always an even
9660 number of gprs has to be saved r15-r2 = 14 regs. */
9661 sav_ofs = 2 * UNITS_PER_LONG;
9662 sav_scale = UNITS_PER_LONG;
9663 size = UNITS_PER_LONG;
9664 max_reg = GP_ARG_NUM_REG - n_reg;
9665 }
9666 else if (s390_function_arg_float (TYPE_MODE (type), type))
9667 {
9668 if (TARGET_DEBUG_ARG)
9669 {
9670 fprintf (stderr, "va_arg: float type");
9671 debug_tree (type);
9672 }
9673
9674 /* FP args go in FP registers, if present. */
9675 indirect_p = 0;
9676 reg = fpr;
9677 n_reg = 1;
9678 sav_ofs = 16 * UNITS_PER_LONG;
9679 sav_scale = 8;
9680 max_reg = FP_ARG_NUM_REG - n_reg;
9681 }
9682 else
9683 {
9684 if (TARGET_DEBUG_ARG)
9685 {
9686 fprintf (stderr, "va_arg: other type");
9687 debug_tree (type);
9688 }
9689
9690 /* Otherwise into GP registers. */
9691 indirect_p = 0;
9692 reg = gpr;
9693 n_reg = (size + UNITS_PER_LONG - 1) / UNITS_PER_LONG;
9694
9695 /* kernel stack layout on 31 bit: It is assumed here that no padding
9696 will be added by s390_frame_info because for va_args always an even
9697 number of gprs has to be saved r15-r2 = 14 regs. */
9698 sav_ofs = 2 * UNITS_PER_LONG;
9699
9700 if (size < UNITS_PER_LONG)
9701 sav_ofs += UNITS_PER_LONG - size;
9702
9703 sav_scale = UNITS_PER_LONG;
9704 max_reg = GP_ARG_NUM_REG - n_reg;
9705 }
9706
9707 /* Pull the value out of the saved registers ... */
9708
9709 lab_false = create_artificial_label (UNKNOWN_LOCATION);
9710 lab_over = create_artificial_label (UNKNOWN_LOCATION);
9711 addr = create_tmp_var (ptr_type_node, "addr");
9712
9713 t = fold_convert (TREE_TYPE (reg), size_int (max_reg));
9714 t = build2 (GT_EXPR, boolean_type_node, reg, t);
9715 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9716 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9717 gimplify_and_add (t, pre_p);
9718
9719 t = fold_build_pointer_plus_hwi (sav, sav_ofs);
9720 u = build2 (MULT_EXPR, TREE_TYPE (reg), reg,
9721 fold_convert (TREE_TYPE (reg), size_int (sav_scale)));
9722 t = fold_build_pointer_plus (t, u);
9723
9724 gimplify_assign (addr, t, pre_p);
9725
9726 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9727
9728 gimple_seq_add_stmt (pre_p, gimple_build_label (lab_false));
9729
9730
9731 /* ... Otherwise out of the overflow area. */
9732
9733 t = ovf;
9734 if (size < UNITS_PER_LONG)
9735 t = fold_build_pointer_plus_hwi (t, UNITS_PER_LONG - size);
9736
9737 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9738
9739 gimplify_assign (addr, t, pre_p);
9740
9741 t = fold_build_pointer_plus_hwi (t, size);
9742 gimplify_assign (ovf, t, pre_p);
9743
9744 gimple_seq_add_stmt (pre_p, gimple_build_label (lab_over));
9745
9746
9747 /* Increment register save count. */
9748
9749 u = build2 (PREINCREMENT_EXPR, TREE_TYPE (reg), reg,
9750 fold_convert (TREE_TYPE (reg), size_int (n_reg)));
9751 gimplify_and_add (u, pre_p);
9752
9753 if (indirect_p)
9754 {
9755 t = build_pointer_type_for_mode (build_pointer_type (type),
9756 ptr_mode, true);
9757 addr = fold_convert (t, addr);
9758 addr = build_va_arg_indirect_ref (addr);
9759 }
9760 else
9761 {
9762 t = build_pointer_type_for_mode (type, ptr_mode, true);
9763 addr = fold_convert (t, addr);
9764 }
9765
9766 return build_va_arg_indirect_ref (addr);
9767 }
9768
9769 /* Emit rtl for the tbegin or tbegin_retry (RETRY != NULL_RTX)
9770 expanders.
9771 DEST - Register location where CC will be stored.
9772 TDB - Pointer to a 256 byte area where to store the transaction.
9773 diagnostic block. NULL if TDB is not needed.
9774 RETRY - Retry count value. If non-NULL a retry loop for CC2
9775 is emitted
9776 CLOBBER_FPRS_P - If true clobbers for all FPRs are emitted as part
9777 of the tbegin instruction pattern. */
9778
9779 void
s390_expand_tbegin(rtx dest,rtx tdb,rtx retry,bool clobber_fprs_p)9780 s390_expand_tbegin (rtx dest, rtx tdb, rtx retry, bool clobber_fprs_p)
9781 {
9782 rtx retry_plus_two = gen_reg_rtx (SImode);
9783 rtx retry_reg = gen_reg_rtx (SImode);
9784 rtx retry_label = NULL_RTX;
9785
9786 if (retry != NULL_RTX)
9787 {
9788 emit_move_insn (retry_reg, retry);
9789 emit_insn (gen_addsi3 (retry_plus_two, retry_reg, const2_rtx));
9790 emit_insn (gen_addsi3 (retry_reg, retry_reg, const1_rtx));
9791 retry_label = gen_label_rtx ();
9792 emit_label (retry_label);
9793 }
9794
9795 if (clobber_fprs_p)
9796 emit_insn (gen_tbegin_1 (gen_rtx_CONST_INT (VOIDmode, TBEGIN_MASK), tdb));
9797 else
9798 emit_insn (gen_tbegin_nofloat_1 (gen_rtx_CONST_INT (VOIDmode, TBEGIN_MASK),
9799 tdb));
9800
9801 emit_move_insn (dest, gen_rtx_UNSPEC (SImode,
9802 gen_rtvec (1, gen_rtx_REG (CCRAWmode,
9803 CC_REGNUM)),
9804 UNSPEC_CC_TO_INT));
9805 if (retry != NULL_RTX)
9806 {
9807 const int CC0 = 1 << 3;
9808 const int CC1 = 1 << 2;
9809 const int CC3 = 1 << 0;
9810 rtx jump;
9811 rtx count = gen_reg_rtx (SImode);
9812 rtx leave_label = gen_label_rtx ();
9813
9814 /* Exit for success and permanent failures. */
9815 jump = s390_emit_jump (leave_label,
9816 gen_rtx_EQ (VOIDmode,
9817 gen_rtx_REG (CCRAWmode, CC_REGNUM),
9818 gen_rtx_CONST_INT (VOIDmode, CC0 | CC1 | CC3)));
9819 LABEL_NUSES (leave_label) = 1;
9820
9821 /* CC2 - transient failure. Perform retry with ppa. */
9822 emit_move_insn (count, retry_plus_two);
9823 emit_insn (gen_subsi3 (count, count, retry_reg));
9824 emit_insn (gen_tx_assist (count));
9825 jump = emit_jump_insn (gen_doloop_si64 (retry_label,
9826 retry_reg,
9827 retry_reg));
9828 JUMP_LABEL (jump) = retry_label;
9829 LABEL_NUSES (retry_label) = 1;
9830 emit_label (leave_label);
9831 }
9832 }
9833
9834 /* Builtins. */
9835
9836 enum s390_builtin
9837 {
9838 S390_BUILTIN_TBEGIN,
9839 S390_BUILTIN_TBEGIN_NOFLOAT,
9840 S390_BUILTIN_TBEGIN_RETRY,
9841 S390_BUILTIN_TBEGIN_RETRY_NOFLOAT,
9842 S390_BUILTIN_TBEGINC,
9843 S390_BUILTIN_TEND,
9844 S390_BUILTIN_TABORT,
9845 S390_BUILTIN_NON_TX_STORE,
9846 S390_BUILTIN_TX_NESTING_DEPTH,
9847 S390_BUILTIN_TX_ASSIST,
9848
9849 S390_BUILTIN_max
9850 };
9851
9852 static enum insn_code const code_for_builtin[S390_BUILTIN_max] = {
9853 CODE_FOR_tbegin,
9854 CODE_FOR_tbegin_nofloat,
9855 CODE_FOR_tbegin_retry,
9856 CODE_FOR_tbegin_retry_nofloat,
9857 CODE_FOR_tbeginc,
9858 CODE_FOR_tend,
9859 CODE_FOR_tabort,
9860 CODE_FOR_ntstg,
9861 CODE_FOR_etnd,
9862 CODE_FOR_tx_assist
9863 };
9864
9865 static void
s390_init_builtins(void)9866 s390_init_builtins (void)
9867 {
9868 tree ftype, uint64_type;
9869 tree returns_twice_attr = tree_cons (get_identifier ("returns_twice"),
9870 NULL, NULL);
9871 tree noreturn_attr = tree_cons (get_identifier ("noreturn"), NULL, NULL);
9872
9873 /* void foo (void) */
9874 ftype = build_function_type_list (void_type_node, NULL_TREE);
9875 add_builtin_function ("__builtin_tbeginc", ftype, S390_BUILTIN_TBEGINC,
9876 BUILT_IN_MD, NULL, NULL_TREE);
9877
9878 /* void foo (int) */
9879 ftype = build_function_type_list (void_type_node, integer_type_node,
9880 NULL_TREE);
9881 add_builtin_function ("__builtin_tabort", ftype,
9882 S390_BUILTIN_TABORT, BUILT_IN_MD, NULL, noreturn_attr);
9883 add_builtin_function ("__builtin_tx_assist", ftype,
9884 S390_BUILTIN_TX_ASSIST, BUILT_IN_MD, NULL, NULL_TREE);
9885
9886 /* int foo (void *) */
9887 ftype = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE);
9888 add_builtin_function ("__builtin_tbegin", ftype, S390_BUILTIN_TBEGIN,
9889 BUILT_IN_MD, NULL, returns_twice_attr);
9890 add_builtin_function ("__builtin_tbegin_nofloat", ftype,
9891 S390_BUILTIN_TBEGIN_NOFLOAT,
9892 BUILT_IN_MD, NULL, returns_twice_attr);
9893
9894 /* int foo (void *, int) */
9895 ftype = build_function_type_list (integer_type_node, ptr_type_node,
9896 integer_type_node, NULL_TREE);
9897 add_builtin_function ("__builtin_tbegin_retry", ftype,
9898 S390_BUILTIN_TBEGIN_RETRY,
9899 BUILT_IN_MD,
9900 NULL, returns_twice_attr);
9901 add_builtin_function ("__builtin_tbegin_retry_nofloat", ftype,
9902 S390_BUILTIN_TBEGIN_RETRY_NOFLOAT,
9903 BUILT_IN_MD,
9904 NULL, returns_twice_attr);
9905
9906 /* int foo (void) */
9907 ftype = build_function_type_list (integer_type_node, NULL_TREE);
9908 add_builtin_function ("__builtin_tx_nesting_depth", ftype,
9909 S390_BUILTIN_TX_NESTING_DEPTH,
9910 BUILT_IN_MD, NULL, NULL_TREE);
9911 add_builtin_function ("__builtin_tend", ftype,
9912 S390_BUILTIN_TEND, BUILT_IN_MD, NULL, NULL_TREE);
9913
9914 /* void foo (uint64_t *, uint64_t) */
9915 if (TARGET_64BIT)
9916 uint64_type = long_unsigned_type_node;
9917 else
9918 uint64_type = long_long_unsigned_type_node;
9919
9920 ftype = build_function_type_list (void_type_node,
9921 build_pointer_type (uint64_type),
9922 uint64_type, NULL_TREE);
9923 add_builtin_function ("__builtin_non_tx_store", ftype,
9924 S390_BUILTIN_NON_TX_STORE,
9925 BUILT_IN_MD, NULL, NULL_TREE);
9926 }
9927
9928 /* Expand an expression EXP that calls a built-in function,
9929 with result going to TARGET if that's convenient
9930 (and in mode MODE if that's convenient).
9931 SUBTARGET may be used as the target for computing one of EXP's operands.
9932 IGNORE is nonzero if the value is to be ignored. */
9933
9934 static rtx
s390_expand_builtin(tree exp,rtx target,rtx subtarget ATTRIBUTE_UNUSED,enum machine_mode mode ATTRIBUTE_UNUSED,int ignore ATTRIBUTE_UNUSED)9935 s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
9936 enum machine_mode mode ATTRIBUTE_UNUSED,
9937 int ignore ATTRIBUTE_UNUSED)
9938 {
9939 #define MAX_ARGS 2
9940
9941 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
9942 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
9943 enum insn_code icode;
9944 rtx op[MAX_ARGS], pat;
9945 int arity;
9946 bool nonvoid;
9947 tree arg;
9948 call_expr_arg_iterator iter;
9949
9950 if (fcode >= S390_BUILTIN_max)
9951 internal_error ("bad builtin fcode");
9952 icode = code_for_builtin[fcode];
9953 if (icode == 0)
9954 internal_error ("bad builtin fcode");
9955
9956 if (!TARGET_HTM)
9957 error ("Transactional execution builtins not enabled (-mhtm)\n");
9958
9959 /* Set a flag in the machine specific cfun part in order to support
9960 saving/restoring of FPRs. */
9961 if (fcode == S390_BUILTIN_TBEGIN || fcode == S390_BUILTIN_TBEGIN_RETRY)
9962 cfun->machine->tbegin_p = true;
9963
9964 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
9965
9966 arity = 0;
9967 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
9968 {
9969 const struct insn_operand_data *insn_op;
9970
9971 if (arg == error_mark_node)
9972 return NULL_RTX;
9973 if (arity >= MAX_ARGS)
9974 return NULL_RTX;
9975
9976 insn_op = &insn_data[icode].operand[arity + nonvoid];
9977
9978 op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, EXPAND_NORMAL);
9979
9980 if (!(*insn_op->predicate) (op[arity], insn_op->mode))
9981 {
9982 if (insn_op->predicate == memory_operand)
9983 {
9984 /* Don't move a NULL pointer into a register. Otherwise
9985 we have to rely on combine being able to move it back
9986 in order to get an immediate 0 in the instruction. */
9987 if (op[arity] != const0_rtx)
9988 op[arity] = copy_to_mode_reg (Pmode, op[arity]);
9989 op[arity] = gen_rtx_MEM (insn_op->mode, op[arity]);
9990 }
9991 else
9992 op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
9993 }
9994
9995 arity++;
9996 }
9997
9998 if (nonvoid)
9999 {
10000 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10001 if (!target
10002 || GET_MODE (target) != tmode
10003 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
10004 target = gen_reg_rtx (tmode);
10005 }
10006
10007 switch (arity)
10008 {
10009 case 0:
10010 pat = GEN_FCN (icode) (target);
10011 break;
10012 case 1:
10013 if (nonvoid)
10014 pat = GEN_FCN (icode) (target, op[0]);
10015 else
10016 pat = GEN_FCN (icode) (op[0]);
10017 break;
10018 case 2:
10019 if (nonvoid)
10020 pat = GEN_FCN (icode) (target, op[0], op[1]);
10021 else
10022 pat = GEN_FCN (icode) (op[0], op[1]);
10023 break;
10024 default:
10025 gcc_unreachable ();
10026 }
10027 if (!pat)
10028 return NULL_RTX;
10029 emit_insn (pat);
10030
10031 if (nonvoid)
10032 return target;
10033 else
10034 return const0_rtx;
10035 }
10036
10037
10038 /* Output assembly code for the trampoline template to
10039 stdio stream FILE.
10040
10041 On S/390, we use gpr 1 internally in the trampoline code;
10042 gpr 0 is used to hold the static chain. */
10043
10044 static void
s390_asm_trampoline_template(FILE * file)10045 s390_asm_trampoline_template (FILE *file)
10046 {
10047 rtx op[2];
10048 op[0] = gen_rtx_REG (Pmode, 0);
10049 op[1] = gen_rtx_REG (Pmode, 1);
10050
10051 if (TARGET_64BIT)
10052 {
10053 output_asm_insn ("basr\t%1,0", op); /* 2 byte */
10054 output_asm_insn ("lmg\t%0,%1,14(%1)", op); /* 6 byte */
10055 output_asm_insn ("br\t%1", op); /* 2 byte */
10056 ASM_OUTPUT_SKIP (file, (HOST_WIDE_INT)(TRAMPOLINE_SIZE - 10));
10057 }
10058 else
10059 {
10060 output_asm_insn ("basr\t%1,0", op); /* 2 byte */
10061 output_asm_insn ("lm\t%0,%1,6(%1)", op); /* 4 byte */
10062 output_asm_insn ("br\t%1", op); /* 2 byte */
10063 ASM_OUTPUT_SKIP (file, (HOST_WIDE_INT)(TRAMPOLINE_SIZE - 8));
10064 }
10065 }
10066
10067 /* Emit RTL insns to initialize the variable parts of a trampoline.
10068 FNADDR is an RTX for the address of the function's pure code.
10069 CXT is an RTX for the static chain value for the function. */
10070
10071 static void
s390_trampoline_init(rtx m_tramp,tree fndecl,rtx cxt)10072 s390_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
10073 {
10074 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
10075 rtx mem;
10076
10077 emit_block_move (m_tramp, assemble_trampoline_template (),
10078 GEN_INT (2 * UNITS_PER_LONG), BLOCK_OP_NORMAL);
10079
10080 mem = adjust_address (m_tramp, Pmode, 2 * UNITS_PER_LONG);
10081 emit_move_insn (mem, cxt);
10082 mem = adjust_address (m_tramp, Pmode, 3 * UNITS_PER_LONG);
10083 emit_move_insn (mem, fnaddr);
10084 }
10085
10086 /* Output assembler code to FILE to increment profiler label # LABELNO
10087 for profiling a function entry. */
10088
10089 void
s390_function_profiler(FILE * file,int labelno)10090 s390_function_profiler (FILE *file, int labelno)
10091 {
10092 rtx op[7];
10093
10094 char label[128];
10095 ASM_GENERATE_INTERNAL_LABEL (label, "LP", labelno);
10096
10097 fprintf (file, "# function profiler \n");
10098
10099 op[0] = gen_rtx_REG (Pmode, RETURN_REGNUM);
10100 op[1] = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
10101 op[1] = gen_rtx_MEM (Pmode, plus_constant (Pmode, op[1], UNITS_PER_LONG));
10102
10103 op[2] = gen_rtx_REG (Pmode, 1);
10104 op[3] = gen_rtx_SYMBOL_REF (Pmode, label);
10105 SYMBOL_REF_FLAGS (op[3]) = SYMBOL_FLAG_LOCAL;
10106
10107 op[4] = gen_rtx_SYMBOL_REF (Pmode, "_mcount");
10108 if (flag_pic)
10109 {
10110 op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), UNSPEC_PLT);
10111 op[4] = gen_rtx_CONST (Pmode, op[4]);
10112 }
10113
10114 if (TARGET_64BIT)
10115 {
10116 output_asm_insn ("stg\t%0,%1", op);
10117 output_asm_insn ("larl\t%2,%3", op);
10118 output_asm_insn ("brasl\t%0,%4", op);
10119 output_asm_insn ("lg\t%0,%1", op);
10120 }
10121 else if (!flag_pic)
10122 {
10123 op[6] = gen_label_rtx ();
10124
10125 output_asm_insn ("st\t%0,%1", op);
10126 output_asm_insn ("bras\t%2,%l6", op);
10127 output_asm_insn (".long\t%4", op);
10128 output_asm_insn (".long\t%3", op);
10129 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
10130 output_asm_insn ("l\t%0,0(%2)", op);
10131 output_asm_insn ("l\t%2,4(%2)", op);
10132 output_asm_insn ("basr\t%0,%0", op);
10133 output_asm_insn ("l\t%0,%1", op);
10134 }
10135 else
10136 {
10137 op[5] = gen_label_rtx ();
10138 op[6] = gen_label_rtx ();
10139
10140 output_asm_insn ("st\t%0,%1", op);
10141 output_asm_insn ("bras\t%2,%l6", op);
10142 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[5]));
10143 output_asm_insn (".long\t%4-%l5", op);
10144 output_asm_insn (".long\t%3-%l5", op);
10145 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
10146 output_asm_insn ("lr\t%0,%2", op);
10147 output_asm_insn ("a\t%0,0(%2)", op);
10148 output_asm_insn ("a\t%2,4(%2)", op);
10149 output_asm_insn ("basr\t%0,%0", op);
10150 output_asm_insn ("l\t%0,%1", op);
10151 }
10152 }
10153
10154 /* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
10155 into its SYMBOL_REF_FLAGS. */
10156
10157 static void
s390_encode_section_info(tree decl,rtx rtl,int first)10158 s390_encode_section_info (tree decl, rtx rtl, int first)
10159 {
10160 default_encode_section_info (decl, rtl, first);
10161
10162 if (TREE_CODE (decl) == VAR_DECL)
10163 {
10164 /* If a variable has a forced alignment to < 2 bytes, mark it
10165 with SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL
10166 operand. */
10167 if (DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) < 16)
10168 SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_ALIGN1;
10169 if (!DECL_SIZE (decl)
10170 || !DECL_ALIGN (decl)
10171 || !host_integerp (DECL_SIZE (decl), 0)
10172 || (DECL_ALIGN (decl) <= 64
10173 && DECL_ALIGN (decl) != tree_low_cst (DECL_SIZE (decl), 0)))
10174 SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_NOT_NATURALLY_ALIGNED;
10175 }
10176
10177 /* Literal pool references don't have a decl so they are handled
10178 differently here. We rely on the information in the MEM_ALIGN
10179 entry to decide upon natural alignment. */
10180 if (MEM_P (rtl)
10181 && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF
10182 && TREE_CONSTANT_POOL_ADDRESS_P (XEXP (rtl, 0))
10183 && (MEM_ALIGN (rtl) == 0
10184 || GET_MODE_BITSIZE (GET_MODE (rtl)) == 0
10185 || MEM_ALIGN (rtl) < GET_MODE_BITSIZE (GET_MODE (rtl))))
10186 SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_NOT_NATURALLY_ALIGNED;
10187 }
10188
10189 /* Output thunk to FILE that implements a C++ virtual function call (with
10190 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
10191 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
10192 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
10193 relative to the resulting this pointer. */
10194
10195 static void
s390_output_mi_thunk(FILE * file,tree thunk ATTRIBUTE_UNUSED,HOST_WIDE_INT delta,HOST_WIDE_INT vcall_offset,tree function)10196 s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
10197 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
10198 tree function)
10199 {
10200 rtx op[10];
10201 int nonlocal = 0;
10202
10203 /* Make sure unwind info is emitted for the thunk if needed. */
10204 final_start_function (emit_barrier (), file, 1);
10205
10206 /* Operand 0 is the target function. */
10207 op[0] = XEXP (DECL_RTL (function), 0);
10208 if (flag_pic && !SYMBOL_REF_LOCAL_P (op[0]))
10209 {
10210 nonlocal = 1;
10211 op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]),
10212 TARGET_64BIT ? UNSPEC_PLT : UNSPEC_GOT);
10213 op[0] = gen_rtx_CONST (Pmode, op[0]);
10214 }
10215
10216 /* Operand 1 is the 'this' pointer. */
10217 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
10218 op[1] = gen_rtx_REG (Pmode, 3);
10219 else
10220 op[1] = gen_rtx_REG (Pmode, 2);
10221
10222 /* Operand 2 is the delta. */
10223 op[2] = GEN_INT (delta);
10224
10225 /* Operand 3 is the vcall_offset. */
10226 op[3] = GEN_INT (vcall_offset);
10227
10228 /* Operand 4 is the temporary register. */
10229 op[4] = gen_rtx_REG (Pmode, 1);
10230
10231 /* Operands 5 to 8 can be used as labels. */
10232 op[5] = NULL_RTX;
10233 op[6] = NULL_RTX;
10234 op[7] = NULL_RTX;
10235 op[8] = NULL_RTX;
10236
10237 /* Operand 9 can be used for temporary register. */
10238 op[9] = NULL_RTX;
10239
10240 /* Generate code. */
10241 if (TARGET_64BIT)
10242 {
10243 /* Setup literal pool pointer if required. */
10244 if ((!DISP_IN_RANGE (delta)
10245 && !CONST_OK_FOR_K (delta)
10246 && !CONST_OK_FOR_Os (delta))
10247 || (!DISP_IN_RANGE (vcall_offset)
10248 && !CONST_OK_FOR_K (vcall_offset)
10249 && !CONST_OK_FOR_Os (vcall_offset)))
10250 {
10251 op[5] = gen_label_rtx ();
10252 output_asm_insn ("larl\t%4,%5", op);
10253 }
10254
10255 /* Add DELTA to this pointer. */
10256 if (delta)
10257 {
10258 if (CONST_OK_FOR_J (delta))
10259 output_asm_insn ("la\t%1,%2(%1)", op);
10260 else if (DISP_IN_RANGE (delta))
10261 output_asm_insn ("lay\t%1,%2(%1)", op);
10262 else if (CONST_OK_FOR_K (delta))
10263 output_asm_insn ("aghi\t%1,%2", op);
10264 else if (CONST_OK_FOR_Os (delta))
10265 output_asm_insn ("agfi\t%1,%2", op);
10266 else
10267 {
10268 op[6] = gen_label_rtx ();
10269 output_asm_insn ("agf\t%1,%6-%5(%4)", op);
10270 }
10271 }
10272
10273 /* Perform vcall adjustment. */
10274 if (vcall_offset)
10275 {
10276 if (DISP_IN_RANGE (vcall_offset))
10277 {
10278 output_asm_insn ("lg\t%4,0(%1)", op);
10279 output_asm_insn ("ag\t%1,%3(%4)", op);
10280 }
10281 else if (CONST_OK_FOR_K (vcall_offset))
10282 {
10283 output_asm_insn ("lghi\t%4,%3", op);
10284 output_asm_insn ("ag\t%4,0(%1)", op);
10285 output_asm_insn ("ag\t%1,0(%4)", op);
10286 }
10287 else if (CONST_OK_FOR_Os (vcall_offset))
10288 {
10289 output_asm_insn ("lgfi\t%4,%3", op);
10290 output_asm_insn ("ag\t%4,0(%1)", op);
10291 output_asm_insn ("ag\t%1,0(%4)", op);
10292 }
10293 else
10294 {
10295 op[7] = gen_label_rtx ();
10296 output_asm_insn ("llgf\t%4,%7-%5(%4)", op);
10297 output_asm_insn ("ag\t%4,0(%1)", op);
10298 output_asm_insn ("ag\t%1,0(%4)", op);
10299 }
10300 }
10301
10302 /* Jump to target. */
10303 output_asm_insn ("jg\t%0", op);
10304
10305 /* Output literal pool if required. */
10306 if (op[5])
10307 {
10308 output_asm_insn (".align\t4", op);
10309 targetm.asm_out.internal_label (file, "L",
10310 CODE_LABEL_NUMBER (op[5]));
10311 }
10312 if (op[6])
10313 {
10314 targetm.asm_out.internal_label (file, "L",
10315 CODE_LABEL_NUMBER (op[6]));
10316 output_asm_insn (".long\t%2", op);
10317 }
10318 if (op[7])
10319 {
10320 targetm.asm_out.internal_label (file, "L",
10321 CODE_LABEL_NUMBER (op[7]));
10322 output_asm_insn (".long\t%3", op);
10323 }
10324 }
10325 else
10326 {
10327 /* Setup base pointer if required. */
10328 if (!vcall_offset
10329 || (!DISP_IN_RANGE (delta)
10330 && !CONST_OK_FOR_K (delta)
10331 && !CONST_OK_FOR_Os (delta))
10332 || (!DISP_IN_RANGE (delta)
10333 && !CONST_OK_FOR_K (vcall_offset)
10334 && !CONST_OK_FOR_Os (vcall_offset)))
10335 {
10336 op[5] = gen_label_rtx ();
10337 output_asm_insn ("basr\t%4,0", op);
10338 targetm.asm_out.internal_label (file, "L",
10339 CODE_LABEL_NUMBER (op[5]));
10340 }
10341
10342 /* Add DELTA to this pointer. */
10343 if (delta)
10344 {
10345 if (CONST_OK_FOR_J (delta))
10346 output_asm_insn ("la\t%1,%2(%1)", op);
10347 else if (DISP_IN_RANGE (delta))
10348 output_asm_insn ("lay\t%1,%2(%1)", op);
10349 else if (CONST_OK_FOR_K (delta))
10350 output_asm_insn ("ahi\t%1,%2", op);
10351 else if (CONST_OK_FOR_Os (delta))
10352 output_asm_insn ("afi\t%1,%2", op);
10353 else
10354 {
10355 op[6] = gen_label_rtx ();
10356 output_asm_insn ("a\t%1,%6-%5(%4)", op);
10357 }
10358 }
10359
10360 /* Perform vcall adjustment. */
10361 if (vcall_offset)
10362 {
10363 if (CONST_OK_FOR_J (vcall_offset))
10364 {
10365 output_asm_insn ("l\t%4,0(%1)", op);
10366 output_asm_insn ("a\t%1,%3(%4)", op);
10367 }
10368 else if (DISP_IN_RANGE (vcall_offset))
10369 {
10370 output_asm_insn ("l\t%4,0(%1)", op);
10371 output_asm_insn ("ay\t%1,%3(%4)", op);
10372 }
10373 else if (CONST_OK_FOR_K (vcall_offset))
10374 {
10375 output_asm_insn ("lhi\t%4,%3", op);
10376 output_asm_insn ("a\t%4,0(%1)", op);
10377 output_asm_insn ("a\t%1,0(%4)", op);
10378 }
10379 else if (CONST_OK_FOR_Os (vcall_offset))
10380 {
10381 output_asm_insn ("iilf\t%4,%3", op);
10382 output_asm_insn ("a\t%4,0(%1)", op);
10383 output_asm_insn ("a\t%1,0(%4)", op);
10384 }
10385 else
10386 {
10387 op[7] = gen_label_rtx ();
10388 output_asm_insn ("l\t%4,%7-%5(%4)", op);
10389 output_asm_insn ("a\t%4,0(%1)", op);
10390 output_asm_insn ("a\t%1,0(%4)", op);
10391 }
10392
10393 /* We had to clobber the base pointer register.
10394 Re-setup the base pointer (with a different base). */
10395 op[5] = gen_label_rtx ();
10396 output_asm_insn ("basr\t%4,0", op);
10397 targetm.asm_out.internal_label (file, "L",
10398 CODE_LABEL_NUMBER (op[5]));
10399 }
10400
10401 /* Jump to target. */
10402 op[8] = gen_label_rtx ();
10403
10404 if (!flag_pic)
10405 output_asm_insn ("l\t%4,%8-%5(%4)", op);
10406 else if (!nonlocal)
10407 output_asm_insn ("a\t%4,%8-%5(%4)", op);
10408 /* We cannot call through .plt, since .plt requires %r12 loaded. */
10409 else if (flag_pic == 1)
10410 {
10411 output_asm_insn ("a\t%4,%8-%5(%4)", op);
10412 output_asm_insn ("l\t%4,%0(%4)", op);
10413 }
10414 else if (flag_pic == 2)
10415 {
10416 op[9] = gen_rtx_REG (Pmode, 0);
10417 output_asm_insn ("l\t%9,%8-4-%5(%4)", op);
10418 output_asm_insn ("a\t%4,%8-%5(%4)", op);
10419 output_asm_insn ("ar\t%4,%9", op);
10420 output_asm_insn ("l\t%4,0(%4)", op);
10421 }
10422
10423 output_asm_insn ("br\t%4", op);
10424
10425 /* Output literal pool. */
10426 output_asm_insn (".align\t4", op);
10427
10428 if (nonlocal && flag_pic == 2)
10429 output_asm_insn (".long\t%0", op);
10430 if (nonlocal)
10431 {
10432 op[0] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
10433 SYMBOL_REF_FLAGS (op[0]) = SYMBOL_FLAG_LOCAL;
10434 }
10435
10436 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[8]));
10437 if (!flag_pic)
10438 output_asm_insn (".long\t%0", op);
10439 else
10440 output_asm_insn (".long\t%0-%5", op);
10441
10442 if (op[6])
10443 {
10444 targetm.asm_out.internal_label (file, "L",
10445 CODE_LABEL_NUMBER (op[6]));
10446 output_asm_insn (".long\t%2", op);
10447 }
10448 if (op[7])
10449 {
10450 targetm.asm_out.internal_label (file, "L",
10451 CODE_LABEL_NUMBER (op[7]));
10452 output_asm_insn (".long\t%3", op);
10453 }
10454 }
10455 final_end_function ();
10456 }
10457
10458 static bool
s390_valid_pointer_mode(enum machine_mode mode)10459 s390_valid_pointer_mode (enum machine_mode mode)
10460 {
10461 return (mode == SImode || (TARGET_64BIT && mode == DImode));
10462 }
10463
10464 /* Checks whether the given CALL_EXPR would use a caller
10465 saved register. This is used to decide whether sibling call
10466 optimization could be performed on the respective function
10467 call. */
10468
10469 static bool
s390_call_saved_register_used(tree call_expr)10470 s390_call_saved_register_used (tree call_expr)
10471 {
10472 CUMULATIVE_ARGS cum_v;
10473 cumulative_args_t cum;
10474 tree parameter;
10475 enum machine_mode mode;
10476 tree type;
10477 rtx parm_rtx;
10478 int reg, i;
10479
10480 INIT_CUMULATIVE_ARGS (cum_v, NULL, NULL, 0, 0);
10481 cum = pack_cumulative_args (&cum_v);
10482
10483 for (i = 0; i < call_expr_nargs (call_expr); i++)
10484 {
10485 parameter = CALL_EXPR_ARG (call_expr, i);
10486 gcc_assert (parameter);
10487
10488 /* For an undeclared variable passed as parameter we will get
10489 an ERROR_MARK node here. */
10490 if (TREE_CODE (parameter) == ERROR_MARK)
10491 return true;
10492
10493 type = TREE_TYPE (parameter);
10494 gcc_assert (type);
10495
10496 mode = TYPE_MODE (type);
10497 gcc_assert (mode);
10498
10499 if (pass_by_reference (&cum_v, mode, type, true))
10500 {
10501 mode = Pmode;
10502 type = build_pointer_type (type);
10503 }
10504
10505 parm_rtx = s390_function_arg (cum, mode, type, 0);
10506
10507 s390_function_arg_advance (cum, mode, type, 0);
10508
10509 if (!parm_rtx)
10510 continue;
10511
10512 if (REG_P (parm_rtx))
10513 {
10514 for (reg = 0;
10515 reg < HARD_REGNO_NREGS (REGNO (parm_rtx), GET_MODE (parm_rtx));
10516 reg++)
10517 if (!call_used_regs[reg + REGNO (parm_rtx)])
10518 return true;
10519 }
10520
10521 if (GET_CODE (parm_rtx) == PARALLEL)
10522 {
10523 int i;
10524
10525 for (i = 0; i < XVECLEN (parm_rtx, 0); i++)
10526 {
10527 rtx r = XEXP (XVECEXP (parm_rtx, 0, i), 0);
10528
10529 gcc_assert (REG_P (r));
10530
10531 for (reg = 0;
10532 reg < HARD_REGNO_NREGS (REGNO (r), GET_MODE (r));
10533 reg++)
10534 if (!call_used_regs[reg + REGNO (r)])
10535 return true;
10536 }
10537 }
10538
10539 }
10540 return false;
10541 }
10542
10543 /* Return true if the given call expression can be
10544 turned into a sibling call.
10545 DECL holds the declaration of the function to be called whereas
10546 EXP is the call expression itself. */
10547
10548 static bool
s390_function_ok_for_sibcall(tree decl,tree exp)10549 s390_function_ok_for_sibcall (tree decl, tree exp)
10550 {
10551 /* The TPF epilogue uses register 1. */
10552 if (TARGET_TPF_PROFILING)
10553 return false;
10554
10555 /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
10556 which would have to be restored before the sibcall. */
10557 if (!TARGET_64BIT && flag_pic && decl && !targetm.binds_local_p (decl))
10558 return false;
10559
10560 /* Register 6 on s390 is available as an argument register but unfortunately
10561 "caller saved". This makes functions needing this register for arguments
10562 not suitable for sibcalls. */
10563 return !s390_call_saved_register_used (exp);
10564 }
10565
10566 /* Return the fixed registers used for condition codes. */
10567
10568 static bool
s390_fixed_condition_code_regs(unsigned int * p1,unsigned int * p2)10569 s390_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
10570 {
10571 *p1 = CC_REGNUM;
10572 *p2 = INVALID_REGNUM;
10573
10574 return true;
10575 }
10576
10577 /* This function is used by the call expanders of the machine description.
10578 It emits the call insn itself together with the necessary operations
10579 to adjust the target address and returns the emitted insn.
10580 ADDR_LOCATION is the target address rtx
10581 TLS_CALL the location of the thread-local symbol
10582 RESULT_REG the register where the result of the call should be stored
10583 RETADDR_REG the register where the return address should be stored
10584 If this parameter is NULL_RTX the call is considered
10585 to be a sibling call. */
10586
10587 rtx
s390_emit_call(rtx addr_location,rtx tls_call,rtx result_reg,rtx retaddr_reg)10588 s390_emit_call (rtx addr_location, rtx tls_call, rtx result_reg,
10589 rtx retaddr_reg)
10590 {
10591 bool plt_call = false;
10592 rtx insn;
10593 rtx call;
10594 rtx clobber;
10595 rtvec vec;
10596
10597 /* Direct function calls need special treatment. */
10598 if (GET_CODE (addr_location) == SYMBOL_REF)
10599 {
10600 /* When calling a global routine in PIC mode, we must
10601 replace the symbol itself with the PLT stub. */
10602 if (flag_pic && !SYMBOL_REF_LOCAL_P (addr_location))
10603 {
10604 if (retaddr_reg != NULL_RTX)
10605 {
10606 addr_location = gen_rtx_UNSPEC (Pmode,
10607 gen_rtvec (1, addr_location),
10608 UNSPEC_PLT);
10609 addr_location = gen_rtx_CONST (Pmode, addr_location);
10610 plt_call = true;
10611 }
10612 else
10613 /* For -fpic code the PLT entries might use r12 which is
10614 call-saved. Therefore we cannot do a sibcall when
10615 calling directly using a symbol ref. When reaching
10616 this point we decided (in s390_function_ok_for_sibcall)
10617 to do a sibcall for a function pointer but one of the
10618 optimizers was able to get rid of the function pointer
10619 by propagating the symbol ref into the call. This
10620 optimization is illegal for S/390 so we turn the direct
10621 call into a indirect call again. */
10622 addr_location = force_reg (Pmode, addr_location);
10623 }
10624
10625 /* Unless we can use the bras(l) insn, force the
10626 routine address into a register. */
10627 if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
10628 {
10629 if (flag_pic)
10630 addr_location = legitimize_pic_address (addr_location, 0);
10631 else
10632 addr_location = force_reg (Pmode, addr_location);
10633 }
10634 }
10635
10636 /* If it is already an indirect call or the code above moved the
10637 SYMBOL_REF to somewhere else make sure the address can be found in
10638 register 1. */
10639 if (retaddr_reg == NULL_RTX
10640 && GET_CODE (addr_location) != SYMBOL_REF
10641 && !plt_call)
10642 {
10643 emit_move_insn (gen_rtx_REG (Pmode, SIBCALL_REGNUM), addr_location);
10644 addr_location = gen_rtx_REG (Pmode, SIBCALL_REGNUM);
10645 }
10646
10647 addr_location = gen_rtx_MEM (QImode, addr_location);
10648 call = gen_rtx_CALL (VOIDmode, addr_location, const0_rtx);
10649
10650 if (result_reg != NULL_RTX)
10651 call = gen_rtx_SET (VOIDmode, result_reg, call);
10652
10653 if (retaddr_reg != NULL_RTX)
10654 {
10655 clobber = gen_rtx_CLOBBER (VOIDmode, retaddr_reg);
10656
10657 if (tls_call != NULL_RTX)
10658 vec = gen_rtvec (3, call, clobber,
10659 gen_rtx_USE (VOIDmode, tls_call));
10660 else
10661 vec = gen_rtvec (2, call, clobber);
10662
10663 call = gen_rtx_PARALLEL (VOIDmode, vec);
10664 }
10665
10666 insn = emit_call_insn (call);
10667
10668 /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
10669 if ((!TARGET_64BIT && plt_call) || tls_call != NULL_RTX)
10670 {
10671 /* s390_function_ok_for_sibcall should
10672 have denied sibcalls in this case. */
10673 gcc_assert (retaddr_reg != NULL_RTX);
10674 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), gen_rtx_REG (Pmode, 12));
10675 }
10676 return insn;
10677 }
10678
10679 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
10680
10681 static void
s390_conditional_register_usage(void)10682 s390_conditional_register_usage (void)
10683 {
10684 int i;
10685
10686 if (flag_pic)
10687 {
10688 fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
10689 call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
10690 }
10691 if (TARGET_CPU_ZARCH)
10692 {
10693 fixed_regs[BASE_REGNUM] = 0;
10694 call_used_regs[BASE_REGNUM] = 0;
10695 fixed_regs[RETURN_REGNUM] = 0;
10696 call_used_regs[RETURN_REGNUM] = 0;
10697 }
10698 if (TARGET_64BIT)
10699 {
10700 for (i = 24; i < 32; i++)
10701 call_used_regs[i] = call_really_used_regs[i] = 0;
10702 }
10703 else
10704 {
10705 for (i = 18; i < 20; i++)
10706 call_used_regs[i] = call_really_used_regs[i] = 0;
10707 }
10708
10709 if (TARGET_SOFT_FLOAT)
10710 {
10711 for (i = 16; i < 32; i++)
10712 call_used_regs[i] = fixed_regs[i] = 1;
10713 }
10714 }
10715
10716 /* Corresponding function to eh_return expander. */
10717
10718 static GTY(()) rtx s390_tpf_eh_return_symbol;
10719 void
s390_emit_tpf_eh_return(rtx target)10720 s390_emit_tpf_eh_return (rtx target)
10721 {
10722 rtx insn, reg;
10723
10724 if (!s390_tpf_eh_return_symbol)
10725 s390_tpf_eh_return_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tpf_eh_return");
10726
10727 reg = gen_rtx_REG (Pmode, 2);
10728
10729 emit_move_insn (reg, target);
10730 insn = s390_emit_call (s390_tpf_eh_return_symbol, NULL_RTX, reg,
10731 gen_rtx_REG (Pmode, RETURN_REGNUM));
10732 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
10733
10734 emit_move_insn (EH_RETURN_HANDLER_RTX, reg);
10735 }
10736
10737 /* Rework the prologue/epilogue to avoid saving/restoring
10738 registers unnecessarily. */
10739
10740 static void
s390_optimize_prologue(void)10741 s390_optimize_prologue (void)
10742 {
10743 rtx insn, new_insn, next_insn;
10744
10745 /* Do a final recompute of the frame-related data. */
10746
10747 s390_update_frame_layout ();
10748
10749 /* If all special registers are in fact used, there's nothing we
10750 can do, so no point in walking the insn list. */
10751
10752 if (cfun_frame_layout.first_save_gpr <= BASE_REGNUM
10753 && cfun_frame_layout.last_save_gpr >= BASE_REGNUM
10754 && (TARGET_CPU_ZARCH
10755 || (cfun_frame_layout.first_save_gpr <= RETURN_REGNUM
10756 && cfun_frame_layout.last_save_gpr >= RETURN_REGNUM)))
10757 return;
10758
10759 /* Search for prologue/epilogue insns and replace them. */
10760
10761 for (insn = get_insns (); insn; insn = next_insn)
10762 {
10763 int first, last, off;
10764 rtx set, base, offset;
10765
10766 next_insn = NEXT_INSN (insn);
10767
10768 if (GET_CODE (insn) != INSN)
10769 continue;
10770
10771 if (GET_CODE (PATTERN (insn)) == PARALLEL
10772 && store_multiple_operation (PATTERN (insn), VOIDmode))
10773 {
10774 set = XVECEXP (PATTERN (insn), 0, 0);
10775 first = REGNO (SET_SRC (set));
10776 last = first + XVECLEN (PATTERN (insn), 0) - 1;
10777 offset = const0_rtx;
10778 base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
10779 off = INTVAL (offset);
10780
10781 if (GET_CODE (base) != REG || off < 0)
10782 continue;
10783 if (cfun_frame_layout.first_save_gpr != -1
10784 && (cfun_frame_layout.first_save_gpr < first
10785 || cfun_frame_layout.last_save_gpr > last))
10786 continue;
10787 if (REGNO (base) != STACK_POINTER_REGNUM
10788 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
10789 continue;
10790 if (first > BASE_REGNUM || last < BASE_REGNUM)
10791 continue;
10792
10793 if (cfun_frame_layout.first_save_gpr != -1)
10794 {
10795 new_insn = save_gprs (base,
10796 off + (cfun_frame_layout.first_save_gpr
10797 - first) * UNITS_PER_LONG,
10798 cfun_frame_layout.first_save_gpr,
10799 cfun_frame_layout.last_save_gpr);
10800 new_insn = emit_insn_before (new_insn, insn);
10801 INSN_ADDRESSES_NEW (new_insn, -1);
10802 }
10803
10804 remove_insn (insn);
10805 continue;
10806 }
10807
10808 if (cfun_frame_layout.first_save_gpr == -1
10809 && GET_CODE (PATTERN (insn)) == SET
10810 && GET_CODE (SET_SRC (PATTERN (insn))) == REG
10811 && (REGNO (SET_SRC (PATTERN (insn))) == BASE_REGNUM
10812 || (!TARGET_CPU_ZARCH
10813 && REGNO (SET_SRC (PATTERN (insn))) == RETURN_REGNUM))
10814 && GET_CODE (SET_DEST (PATTERN (insn))) == MEM)
10815 {
10816 set = PATTERN (insn);
10817 first = REGNO (SET_SRC (set));
10818 offset = const0_rtx;
10819 base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
10820 off = INTVAL (offset);
10821
10822 if (GET_CODE (base) != REG || off < 0)
10823 continue;
10824 if (REGNO (base) != STACK_POINTER_REGNUM
10825 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
10826 continue;
10827
10828 remove_insn (insn);
10829 continue;
10830 }
10831
10832 if (GET_CODE (PATTERN (insn)) == PARALLEL
10833 && load_multiple_operation (PATTERN (insn), VOIDmode))
10834 {
10835 set = XVECEXP (PATTERN (insn), 0, 0);
10836 first = REGNO (SET_DEST (set));
10837 last = first + XVECLEN (PATTERN (insn), 0) - 1;
10838 offset = const0_rtx;
10839 base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
10840 off = INTVAL (offset);
10841
10842 if (GET_CODE (base) != REG || off < 0)
10843 continue;
10844 if (cfun_frame_layout.first_restore_gpr != -1
10845 && (cfun_frame_layout.first_restore_gpr < first
10846 || cfun_frame_layout.last_restore_gpr > last))
10847 continue;
10848 if (REGNO (base) != STACK_POINTER_REGNUM
10849 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
10850 continue;
10851 if (first > BASE_REGNUM || last < BASE_REGNUM)
10852 continue;
10853
10854 if (cfun_frame_layout.first_restore_gpr != -1)
10855 {
10856 new_insn = restore_gprs (base,
10857 off + (cfun_frame_layout.first_restore_gpr
10858 - first) * UNITS_PER_LONG,
10859 cfun_frame_layout.first_restore_gpr,
10860 cfun_frame_layout.last_restore_gpr);
10861 new_insn = emit_insn_before (new_insn, insn);
10862 INSN_ADDRESSES_NEW (new_insn, -1);
10863 }
10864
10865 remove_insn (insn);
10866 continue;
10867 }
10868
10869 if (cfun_frame_layout.first_restore_gpr == -1
10870 && GET_CODE (PATTERN (insn)) == SET
10871 && GET_CODE (SET_DEST (PATTERN (insn))) == REG
10872 && (REGNO (SET_DEST (PATTERN (insn))) == BASE_REGNUM
10873 || (!TARGET_CPU_ZARCH
10874 && REGNO (SET_DEST (PATTERN (insn))) == RETURN_REGNUM))
10875 && GET_CODE (SET_SRC (PATTERN (insn))) == MEM)
10876 {
10877 set = PATTERN (insn);
10878 first = REGNO (SET_DEST (set));
10879 offset = const0_rtx;
10880 base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
10881 off = INTVAL (offset);
10882
10883 if (GET_CODE (base) != REG || off < 0)
10884 continue;
10885 if (REGNO (base) != STACK_POINTER_REGNUM
10886 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
10887 continue;
10888
10889 remove_insn (insn);
10890 continue;
10891 }
10892 }
10893 }
10894
10895 /* On z10 and later the dynamic branch prediction must see the
10896 backward jump within a certain windows. If not it falls back to
10897 the static prediction. This function rearranges the loop backward
10898 branch in a way which makes the static prediction always correct.
10899 The function returns true if it added an instruction. */
10900 static bool
s390_fix_long_loop_prediction(rtx insn)10901 s390_fix_long_loop_prediction (rtx insn)
10902 {
10903 rtx set = single_set (insn);
10904 rtx code_label, label_ref, new_label;
10905 rtx uncond_jump;
10906 rtx cur_insn;
10907 rtx tmp;
10908 int distance;
10909
10910 /* This will exclude branch on count and branch on index patterns
10911 since these are correctly statically predicted. */
10912 if (!set
10913 || SET_DEST (set) != pc_rtx
10914 || GET_CODE (SET_SRC(set)) != IF_THEN_ELSE)
10915 return false;
10916
10917 label_ref = (GET_CODE (XEXP (SET_SRC (set), 1)) == LABEL_REF ?
10918 XEXP (SET_SRC (set), 1) : XEXP (SET_SRC (set), 2));
10919
10920 gcc_assert (GET_CODE (label_ref) == LABEL_REF);
10921
10922 code_label = XEXP (label_ref, 0);
10923
10924 if (INSN_ADDRESSES (INSN_UID (code_label)) == -1
10925 || INSN_ADDRESSES (INSN_UID (insn)) == -1
10926 || (INSN_ADDRESSES (INSN_UID (insn))
10927 - INSN_ADDRESSES (INSN_UID (code_label)) < PREDICT_DISTANCE))
10928 return false;
10929
10930 for (distance = 0, cur_insn = PREV_INSN (insn);
10931 distance < PREDICT_DISTANCE - 6;
10932 distance += get_attr_length (cur_insn), cur_insn = PREV_INSN (cur_insn))
10933 if (!cur_insn || JUMP_P (cur_insn) || LABEL_P (cur_insn))
10934 return false;
10935
10936 new_label = gen_label_rtx ();
10937 uncond_jump = emit_jump_insn_after (
10938 gen_rtx_SET (VOIDmode, pc_rtx,
10939 gen_rtx_LABEL_REF (VOIDmode, code_label)),
10940 insn);
10941 emit_label_after (new_label, uncond_jump);
10942
10943 tmp = XEXP (SET_SRC (set), 1);
10944 XEXP (SET_SRC (set), 1) = XEXP (SET_SRC (set), 2);
10945 XEXP (SET_SRC (set), 2) = tmp;
10946 INSN_CODE (insn) = -1;
10947
10948 XEXP (label_ref, 0) = new_label;
10949 JUMP_LABEL (insn) = new_label;
10950 JUMP_LABEL (uncond_jump) = code_label;
10951
10952 return true;
10953 }
10954
10955 /* Returns 1 if INSN reads the value of REG for purposes not related
10956 to addressing of memory, and 0 otherwise. */
10957 static int
s390_non_addr_reg_read_p(rtx reg,rtx insn)10958 s390_non_addr_reg_read_p (rtx reg, rtx insn)
10959 {
10960 return reg_referenced_p (reg, PATTERN (insn))
10961 && !reg_used_in_mem_p (REGNO (reg), PATTERN (insn));
10962 }
10963
10964 /* Starting from INSN find_cond_jump looks downwards in the insn
10965 stream for a single jump insn which is the last user of the
10966 condition code set in INSN. */
10967 static rtx
find_cond_jump(rtx insn)10968 find_cond_jump (rtx insn)
10969 {
10970 for (; insn; insn = NEXT_INSN (insn))
10971 {
10972 rtx ite, cc;
10973
10974 if (LABEL_P (insn))
10975 break;
10976
10977 if (!JUMP_P (insn))
10978 {
10979 if (reg_mentioned_p (gen_rtx_REG (CCmode, CC_REGNUM), insn))
10980 break;
10981 continue;
10982 }
10983
10984 /* This will be triggered by a return. */
10985 if (GET_CODE (PATTERN (insn)) != SET)
10986 break;
10987
10988 gcc_assert (SET_DEST (PATTERN (insn)) == pc_rtx);
10989 ite = SET_SRC (PATTERN (insn));
10990
10991 if (GET_CODE (ite) != IF_THEN_ELSE)
10992 break;
10993
10994 cc = XEXP (XEXP (ite, 0), 0);
10995 if (!REG_P (cc) || !CC_REGNO_P (REGNO (cc)))
10996 break;
10997
10998 if (find_reg_note (insn, REG_DEAD, cc))
10999 return insn;
11000 break;
11001 }
11002
11003 return NULL_RTX;
11004 }
11005
11006 /* Swap the condition in COND and the operands in OP0 and OP1 so that
11007 the semantics does not change. If NULL_RTX is passed as COND the
11008 function tries to find the conditional jump starting with INSN. */
11009 static void
s390_swap_cmp(rtx cond,rtx * op0,rtx * op1,rtx insn)11010 s390_swap_cmp (rtx cond, rtx *op0, rtx *op1, rtx insn)
11011 {
11012 rtx tmp = *op0;
11013
11014 if (cond == NULL_RTX)
11015 {
11016 rtx jump = find_cond_jump (NEXT_INSN (insn));
11017 jump = jump ? single_set (jump) : NULL_RTX;
11018
11019 if (jump == NULL_RTX)
11020 return;
11021
11022 cond = XEXP (XEXP (jump, 1), 0);
11023 }
11024
11025 *op0 = *op1;
11026 *op1 = tmp;
11027 PUT_CODE (cond, swap_condition (GET_CODE (cond)));
11028 }
11029
11030 /* On z10, instructions of the compare-and-branch family have the
11031 property to access the register occurring as second operand with
11032 its bits complemented. If such a compare is grouped with a second
11033 instruction that accesses the same register non-complemented, and
11034 if that register's value is delivered via a bypass, then the
11035 pipeline recycles, thereby causing significant performance decline.
11036 This function locates such situations and exchanges the two
11037 operands of the compare. The function return true whenever it
11038 added an insn. */
11039 static bool
s390_z10_optimize_cmp(rtx insn)11040 s390_z10_optimize_cmp (rtx insn)
11041 {
11042 rtx prev_insn, next_insn;
11043 bool insn_added_p = false;
11044 rtx cond, *op0, *op1;
11045
11046 if (GET_CODE (PATTERN (insn)) == PARALLEL)
11047 {
11048 /* Handle compare and branch and branch on count
11049 instructions. */
11050 rtx pattern = single_set (insn);
11051
11052 if (!pattern
11053 || SET_DEST (pattern) != pc_rtx
11054 || GET_CODE (SET_SRC (pattern)) != IF_THEN_ELSE)
11055 return false;
11056
11057 cond = XEXP (SET_SRC (pattern), 0);
11058 op0 = &XEXP (cond, 0);
11059 op1 = &XEXP (cond, 1);
11060 }
11061 else if (GET_CODE (PATTERN (insn)) == SET)
11062 {
11063 rtx src, dest;
11064
11065 /* Handle normal compare instructions. */
11066 src = SET_SRC (PATTERN (insn));
11067 dest = SET_DEST (PATTERN (insn));
11068
11069 if (!REG_P (dest)
11070 || !CC_REGNO_P (REGNO (dest))
11071 || GET_CODE (src) != COMPARE)
11072 return false;
11073
11074 /* s390_swap_cmp will try to find the conditional
11075 jump when passing NULL_RTX as condition. */
11076 cond = NULL_RTX;
11077 op0 = &XEXP (src, 0);
11078 op1 = &XEXP (src, 1);
11079 }
11080 else
11081 return false;
11082
11083 if (!REG_P (*op0) || !REG_P (*op1))
11084 return false;
11085
11086 if (GET_MODE_CLASS (GET_MODE (*op0)) != MODE_INT)
11087 return false;
11088
11089 /* Swap the COMPARE arguments and its mask if there is a
11090 conflicting access in the previous insn. */
11091 prev_insn = prev_active_insn (insn);
11092 if (prev_insn != NULL_RTX && INSN_P (prev_insn)
11093 && reg_referenced_p (*op1, PATTERN (prev_insn)))
11094 s390_swap_cmp (cond, op0, op1, insn);
11095
11096 /* Check if there is a conflict with the next insn. If there
11097 was no conflict with the previous insn, then swap the
11098 COMPARE arguments and its mask. If we already swapped
11099 the operands, or if swapping them would cause a conflict
11100 with the previous insn, issue a NOP after the COMPARE in
11101 order to separate the two instuctions. */
11102 next_insn = next_active_insn (insn);
11103 if (next_insn != NULL_RTX && INSN_P (next_insn)
11104 && s390_non_addr_reg_read_p (*op1, next_insn))
11105 {
11106 if (prev_insn != NULL_RTX && INSN_P (prev_insn)
11107 && s390_non_addr_reg_read_p (*op0, prev_insn))
11108 {
11109 if (REGNO (*op1) == 0)
11110 emit_insn_after (gen_nop1 (), insn);
11111 else
11112 emit_insn_after (gen_nop (), insn);
11113 insn_added_p = true;
11114 }
11115 else
11116 s390_swap_cmp (cond, op0, op1, insn);
11117 }
11118 return insn_added_p;
11119 }
11120
11121 /* Perform machine-dependent processing. */
11122
11123 static void
s390_reorg(void)11124 s390_reorg (void)
11125 {
11126 bool pool_overflow = false;
11127 int hw_before, hw_after;
11128
11129 /* Make sure all splits have been performed; splits after
11130 machine_dependent_reorg might confuse insn length counts. */
11131 split_all_insns_noflow ();
11132
11133 /* Install the main literal pool and the associated base
11134 register load insns.
11135
11136 In addition, there are two problematic situations we need
11137 to correct:
11138
11139 - the literal pool might be > 4096 bytes in size, so that
11140 some of its elements cannot be directly accessed
11141
11142 - a branch target might be > 64K away from the branch, so that
11143 it is not possible to use a PC-relative instruction.
11144
11145 To fix those, we split the single literal pool into multiple
11146 pool chunks, reloading the pool base register at various
11147 points throughout the function to ensure it always points to
11148 the pool chunk the following code expects, and / or replace
11149 PC-relative branches by absolute branches.
11150
11151 However, the two problems are interdependent: splitting the
11152 literal pool can move a branch further away from its target,
11153 causing the 64K limit to overflow, and on the other hand,
11154 replacing a PC-relative branch by an absolute branch means
11155 we need to put the branch target address into the literal
11156 pool, possibly causing it to overflow.
11157
11158 So, we loop trying to fix up both problems until we manage
11159 to satisfy both conditions at the same time. Note that the
11160 loop is guaranteed to terminate as every pass of the loop
11161 strictly decreases the total number of PC-relative branches
11162 in the function. (This is not completely true as there
11163 might be branch-over-pool insns introduced by chunkify_start.
11164 Those never need to be split however.) */
11165
11166 for (;;)
11167 {
11168 struct constant_pool *pool = NULL;
11169
11170 /* Collect the literal pool. */
11171 if (!pool_overflow)
11172 {
11173 pool = s390_mainpool_start ();
11174 if (!pool)
11175 pool_overflow = true;
11176 }
11177
11178 /* If literal pool overflowed, start to chunkify it. */
11179 if (pool_overflow)
11180 pool = s390_chunkify_start ();
11181
11182 /* Split out-of-range branches. If this has created new
11183 literal pool entries, cancel current chunk list and
11184 recompute it. zSeries machines have large branch
11185 instructions, so we never need to split a branch. */
11186 if (!TARGET_CPU_ZARCH && s390_split_branches ())
11187 {
11188 if (pool_overflow)
11189 s390_chunkify_cancel (pool);
11190 else
11191 s390_mainpool_cancel (pool);
11192
11193 continue;
11194 }
11195
11196 /* If we made it up to here, both conditions are satisfied.
11197 Finish up literal pool related changes. */
11198 if (pool_overflow)
11199 s390_chunkify_finish (pool);
11200 else
11201 s390_mainpool_finish (pool);
11202
11203 /* We're done splitting branches. */
11204 cfun->machine->split_branches_pending_p = false;
11205 break;
11206 }
11207
11208 /* Generate out-of-pool execute target insns. */
11209 if (TARGET_CPU_ZARCH)
11210 {
11211 rtx insn, label, target;
11212
11213 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
11214 {
11215 label = s390_execute_label (insn);
11216 if (!label)
11217 continue;
11218
11219 gcc_assert (label != const0_rtx);
11220
11221 target = emit_label (XEXP (label, 0));
11222 INSN_ADDRESSES_NEW (target, -1);
11223
11224 target = emit_insn (s390_execute_target (insn));
11225 INSN_ADDRESSES_NEW (target, -1);
11226 }
11227 }
11228
11229 /* Try to optimize prologue and epilogue further. */
11230 s390_optimize_prologue ();
11231
11232 /* Walk over the insns and do some >=z10 specific changes. */
11233 if (s390_tune == PROCESSOR_2097_Z10
11234 || s390_tune == PROCESSOR_2817_Z196
11235 || s390_tune == PROCESSOR_2827_ZEC12)
11236 {
11237 rtx insn;
11238 bool insn_added_p = false;
11239
11240 /* The insn lengths and addresses have to be up to date for the
11241 following manipulations. */
11242 shorten_branches (get_insns ());
11243
11244 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
11245 {
11246 if (!INSN_P (insn) || INSN_CODE (insn) <= 0)
11247 continue;
11248
11249 if (JUMP_P (insn))
11250 insn_added_p |= s390_fix_long_loop_prediction (insn);
11251
11252 if ((GET_CODE (PATTERN (insn)) == PARALLEL
11253 || GET_CODE (PATTERN (insn)) == SET)
11254 && s390_tune == PROCESSOR_2097_Z10)
11255 insn_added_p |= s390_z10_optimize_cmp (insn);
11256 }
11257
11258 /* Adjust branches if we added new instructions. */
11259 if (insn_added_p)
11260 shorten_branches (get_insns ());
11261 }
11262
11263 s390_function_num_hotpatch_hw (current_function_decl, &hw_before, &hw_after);
11264 if (hw_after > 0)
11265 {
11266 rtx insn;
11267
11268 /* Insert NOPs for hotpatching. */
11269 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
11270 /* Emit NOPs
11271 1. inside the area covered by debug information to allow setting
11272 breakpoints at the NOPs,
11273 2. before any insn which results in an asm instruction,
11274 3. before in-function labels to avoid jumping to the NOPs, for
11275 example as part of a loop,
11276 4. before any barrier in case the function is completely empty
11277 (__builtin_unreachable ()) and has neither internal labels nor
11278 active insns.
11279 */
11280 if (active_insn_p (insn) || BARRIER_P (insn) || LABEL_P (insn))
11281 break;
11282 /* Output a series of NOPs before the first active insn. */
11283 while (insn && hw_after > 0)
11284 {
11285 if (hw_after >= 3 && TARGET_CPU_ZARCH)
11286 {
11287 emit_insn_before (gen_nop_6_byte (), insn);
11288 hw_after -= 3;
11289 }
11290 else if (hw_after >= 2)
11291 {
11292 emit_insn_before (gen_nop_4_byte (), insn);
11293 hw_after -= 2;
11294 }
11295 else
11296 {
11297 emit_insn_before (gen_nop_2_byte (), insn);
11298 hw_after -= 1;
11299 }
11300 }
11301 }
11302 }
11303
11304 /* Return true if INSN is a fp load insn writing register REGNO. */
11305 static inline bool
s390_fpload_toreg(rtx insn,unsigned int regno)11306 s390_fpload_toreg (rtx insn, unsigned int regno)
11307 {
11308 rtx set;
11309 enum attr_type flag = s390_safe_attr_type (insn);
11310
11311 if (flag != TYPE_FLOADSF && flag != TYPE_FLOADDF)
11312 return false;
11313
11314 set = single_set (insn);
11315
11316 if (set == NULL_RTX)
11317 return false;
11318
11319 if (!REG_P (SET_DEST (set)) || !MEM_P (SET_SRC (set)))
11320 return false;
11321
11322 if (REGNO (SET_DEST (set)) != regno)
11323 return false;
11324
11325 return true;
11326 }
11327
11328 /* This value describes the distance to be avoided between an
11329 aritmetic fp instruction and an fp load writing the same register.
11330 Z10_EARLYLOAD_DISTANCE - 1 as well as Z10_EARLYLOAD_DISTANCE + 1 is
11331 fine but the exact value has to be avoided. Otherwise the FP
11332 pipeline will throw an exception causing a major penalty. */
11333 #define Z10_EARLYLOAD_DISTANCE 7
11334
11335 /* Rearrange the ready list in order to avoid the situation described
11336 for Z10_EARLYLOAD_DISTANCE. A problematic load instruction is
11337 moved to the very end of the ready list. */
11338 static void
s390_z10_prevent_earlyload_conflicts(rtx * ready,int * nready_p)11339 s390_z10_prevent_earlyload_conflicts (rtx *ready, int *nready_p)
11340 {
11341 unsigned int regno;
11342 int nready = *nready_p;
11343 rtx tmp;
11344 int i;
11345 rtx insn;
11346 rtx set;
11347 enum attr_type flag;
11348 int distance;
11349
11350 /* Skip DISTANCE - 1 active insns. */
11351 for (insn = last_scheduled_insn, distance = Z10_EARLYLOAD_DISTANCE - 1;
11352 distance > 0 && insn != NULL_RTX;
11353 distance--, insn = prev_active_insn (insn))
11354 if (CALL_P (insn) || JUMP_P (insn))
11355 return;
11356
11357 if (insn == NULL_RTX)
11358 return;
11359
11360 set = single_set (insn);
11361
11362 if (set == NULL_RTX || !REG_P (SET_DEST (set))
11363 || GET_MODE_CLASS (GET_MODE (SET_DEST (set))) != MODE_FLOAT)
11364 return;
11365
11366 flag = s390_safe_attr_type (insn);
11367
11368 if (flag == TYPE_FLOADSF || flag == TYPE_FLOADDF)
11369 return;
11370
11371 regno = REGNO (SET_DEST (set));
11372 i = nready - 1;
11373
11374 while (!s390_fpload_toreg (ready[i], regno) && i > 0)
11375 i--;
11376
11377 if (!i)
11378 return;
11379
11380 tmp = ready[i];
11381 memmove (&ready[1], &ready[0], sizeof (rtx) * i);
11382 ready[0] = tmp;
11383 }
11384
11385
11386 /* The s390_sched_state variable tracks the state of the current or
11387 the last instruction group.
11388
11389 0,1,2 number of instructions scheduled in the current group
11390 3 the last group is complete - normal insns
11391 4 the last group was a cracked/expanded insn */
11392
11393 static int s390_sched_state;
11394
11395 #define S390_OOO_SCHED_STATE_NORMAL 3
11396 #define S390_OOO_SCHED_STATE_CRACKED 4
11397
11398 #define S390_OOO_SCHED_ATTR_MASK_CRACKED 0x1
11399 #define S390_OOO_SCHED_ATTR_MASK_EXPANDED 0x2
11400 #define S390_OOO_SCHED_ATTR_MASK_ENDGROUP 0x4
11401 #define S390_OOO_SCHED_ATTR_MASK_GROUPALONE 0x8
11402
11403 static unsigned int
s390_get_sched_attrmask(rtx insn)11404 s390_get_sched_attrmask (rtx insn)
11405 {
11406 unsigned int mask = 0;
11407
11408 if (get_attr_ooo_cracked (insn))
11409 mask |= S390_OOO_SCHED_ATTR_MASK_CRACKED;
11410 if (get_attr_ooo_expanded (insn))
11411 mask |= S390_OOO_SCHED_ATTR_MASK_EXPANDED;
11412 if (get_attr_ooo_endgroup (insn))
11413 mask |= S390_OOO_SCHED_ATTR_MASK_ENDGROUP;
11414 if (get_attr_ooo_groupalone (insn))
11415 mask |= S390_OOO_SCHED_ATTR_MASK_GROUPALONE;
11416 return mask;
11417 }
11418
11419 /* Return the scheduling score for INSN. The higher the score the
11420 better. The score is calculated from the OOO scheduling attributes
11421 of INSN and the scheduling state s390_sched_state. */
11422 static int
s390_sched_score(rtx insn)11423 s390_sched_score (rtx insn)
11424 {
11425 unsigned int mask = s390_get_sched_attrmask (insn);
11426 int score = 0;
11427
11428 switch (s390_sched_state)
11429 {
11430 case 0:
11431 /* Try to put insns into the first slot which would otherwise
11432 break a group. */
11433 if ((mask & S390_OOO_SCHED_ATTR_MASK_CRACKED) != 0
11434 || (mask & S390_OOO_SCHED_ATTR_MASK_EXPANDED) != 0)
11435 score += 5;
11436 if ((mask & S390_OOO_SCHED_ATTR_MASK_GROUPALONE) != 0)
11437 score += 10;
11438 case 1:
11439 /* Prefer not cracked insns while trying to put together a
11440 group. */
11441 if ((mask & S390_OOO_SCHED_ATTR_MASK_CRACKED) == 0
11442 && (mask & S390_OOO_SCHED_ATTR_MASK_EXPANDED) == 0
11443 && (mask & S390_OOO_SCHED_ATTR_MASK_GROUPALONE) == 0)
11444 score += 10;
11445 if ((mask & S390_OOO_SCHED_ATTR_MASK_ENDGROUP) == 0)
11446 score += 5;
11447 break;
11448 case 2:
11449 /* Prefer not cracked insns while trying to put together a
11450 group. */
11451 if ((mask & S390_OOO_SCHED_ATTR_MASK_CRACKED) == 0
11452 && (mask & S390_OOO_SCHED_ATTR_MASK_EXPANDED) == 0
11453 && (mask & S390_OOO_SCHED_ATTR_MASK_GROUPALONE) == 0)
11454 score += 10;
11455 /* Prefer endgroup insns in the last slot. */
11456 if ((mask & S390_OOO_SCHED_ATTR_MASK_ENDGROUP) != 0)
11457 score += 10;
11458 break;
11459 case S390_OOO_SCHED_STATE_NORMAL:
11460 /* Prefer not cracked insns if the last was not cracked. */
11461 if ((mask & S390_OOO_SCHED_ATTR_MASK_CRACKED) == 0
11462 && (mask & S390_OOO_SCHED_ATTR_MASK_EXPANDED) == 0)
11463 score += 5;
11464 if ((mask & S390_OOO_SCHED_ATTR_MASK_GROUPALONE) != 0)
11465 score += 10;
11466 break;
11467 case S390_OOO_SCHED_STATE_CRACKED:
11468 /* Try to keep cracked insns together to prevent them from
11469 interrupting groups. */
11470 if ((mask & S390_OOO_SCHED_ATTR_MASK_CRACKED) != 0
11471 || (mask & S390_OOO_SCHED_ATTR_MASK_EXPANDED) != 0)
11472 score += 5;
11473 break;
11474 }
11475 return score;
11476 }
11477
11478 /* This function is called via hook TARGET_SCHED_REORDER before
11479 issueing one insn from list READY which contains *NREADYP entries.
11480 For target z10 it reorders load instructions to avoid early load
11481 conflicts in the floating point pipeline */
11482 static int
s390_sched_reorder(FILE * file,int verbose,rtx * ready,int * nreadyp,int clock ATTRIBUTE_UNUSED)11483 s390_sched_reorder (FILE *file, int verbose,
11484 rtx *ready, int *nreadyp, int clock ATTRIBUTE_UNUSED)
11485 {
11486 if (s390_tune == PROCESSOR_2097_Z10)
11487 if (reload_completed && *nreadyp > 1)
11488 s390_z10_prevent_earlyload_conflicts (ready, nreadyp);
11489
11490 if (s390_tune == PROCESSOR_2827_ZEC12
11491 && reload_completed
11492 && *nreadyp > 1)
11493 {
11494 int i;
11495 int last_index = *nreadyp - 1;
11496 int max_index = -1;
11497 int max_score = -1;
11498 rtx tmp;
11499
11500 /* Just move the insn with the highest score to the top (the
11501 end) of the list. A full sort is not needed since a conflict
11502 in the hazard recognition cannot happen. So the top insn in
11503 the ready list will always be taken. */
11504 for (i = last_index; i >= 0; i--)
11505 {
11506 int score;
11507
11508 if (recog_memoized (ready[i]) < 0)
11509 continue;
11510
11511 score = s390_sched_score (ready[i]);
11512 if (score > max_score)
11513 {
11514 max_score = score;
11515 max_index = i;
11516 }
11517 }
11518
11519 if (max_index != -1)
11520 {
11521 if (max_index != last_index)
11522 {
11523 tmp = ready[max_index];
11524 ready[max_index] = ready[last_index];
11525 ready[last_index] = tmp;
11526
11527 if (verbose > 5)
11528 fprintf (file,
11529 "move insn %d to the top of list\n",
11530 INSN_UID (ready[last_index]));
11531 }
11532 else if (verbose > 5)
11533 fprintf (file,
11534 "best insn %d already on top\n",
11535 INSN_UID (ready[last_index]));
11536 }
11537
11538 if (verbose > 5)
11539 {
11540 fprintf (file, "ready list ooo attributes - sched state: %d\n",
11541 s390_sched_state);
11542
11543 for (i = last_index; i >= 0; i--)
11544 {
11545 if (recog_memoized (ready[i]) < 0)
11546 continue;
11547 fprintf (file, "insn %d score: %d: ", INSN_UID (ready[i]),
11548 s390_sched_score (ready[i]));
11549 #define PRINT_OOO_ATTR(ATTR) fprintf (file, "%s ", get_attr_##ATTR (ready[i]) ? #ATTR : "!" #ATTR);
11550 PRINT_OOO_ATTR (ooo_cracked);
11551 PRINT_OOO_ATTR (ooo_expanded);
11552 PRINT_OOO_ATTR (ooo_endgroup);
11553 PRINT_OOO_ATTR (ooo_groupalone);
11554 #undef PRINT_OOO_ATTR
11555 fprintf (file, "\n");
11556 }
11557 }
11558 }
11559
11560 return s390_issue_rate ();
11561 }
11562
11563
11564 /* This function is called via hook TARGET_SCHED_VARIABLE_ISSUE after
11565 the scheduler has issued INSN. It stores the last issued insn into
11566 last_scheduled_insn in order to make it available for
11567 s390_sched_reorder. */
11568 static int
s390_sched_variable_issue(FILE * file,int verbose,rtx insn,int more)11569 s390_sched_variable_issue (FILE *file, int verbose, rtx insn, int more)
11570 {
11571 last_scheduled_insn = insn;
11572
11573 if (s390_tune == PROCESSOR_2827_ZEC12
11574 && reload_completed
11575 && recog_memoized (insn) >= 0)
11576 {
11577 unsigned int mask = s390_get_sched_attrmask (insn);
11578
11579 if ((mask & S390_OOO_SCHED_ATTR_MASK_CRACKED) != 0
11580 || (mask & S390_OOO_SCHED_ATTR_MASK_EXPANDED) != 0)
11581 s390_sched_state = S390_OOO_SCHED_STATE_CRACKED;
11582 else if ((mask & S390_OOO_SCHED_ATTR_MASK_ENDGROUP) != 0
11583 || (mask & S390_OOO_SCHED_ATTR_MASK_GROUPALONE) != 0)
11584 s390_sched_state = S390_OOO_SCHED_STATE_NORMAL;
11585 else
11586 {
11587 /* Only normal insns are left (mask == 0). */
11588 switch (s390_sched_state)
11589 {
11590 case 0:
11591 case 1:
11592 case 2:
11593 case S390_OOO_SCHED_STATE_NORMAL:
11594 if (s390_sched_state == S390_OOO_SCHED_STATE_NORMAL)
11595 s390_sched_state = 1;
11596 else
11597 s390_sched_state++;
11598
11599 break;
11600 case S390_OOO_SCHED_STATE_CRACKED:
11601 s390_sched_state = S390_OOO_SCHED_STATE_NORMAL;
11602 break;
11603 }
11604 }
11605 if (verbose > 5)
11606 {
11607 fprintf (file, "insn %d: ", INSN_UID (insn));
11608 #define PRINT_OOO_ATTR(ATTR) \
11609 fprintf (file, "%s ", get_attr_##ATTR (insn) ? #ATTR : "");
11610 PRINT_OOO_ATTR (ooo_cracked);
11611 PRINT_OOO_ATTR (ooo_expanded);
11612 PRINT_OOO_ATTR (ooo_endgroup);
11613 PRINT_OOO_ATTR (ooo_groupalone);
11614 #undef PRINT_OOO_ATTR
11615 fprintf (file, "\n");
11616 fprintf (file, "sched state: %d\n", s390_sched_state);
11617 }
11618 }
11619
11620 if (GET_CODE (PATTERN (insn)) != USE
11621 && GET_CODE (PATTERN (insn)) != CLOBBER)
11622 return more - 1;
11623 else
11624 return more;
11625 }
11626
11627 static void
s390_sched_init(FILE * file ATTRIBUTE_UNUSED,int verbose ATTRIBUTE_UNUSED,int max_ready ATTRIBUTE_UNUSED)11628 s390_sched_init (FILE *file ATTRIBUTE_UNUSED,
11629 int verbose ATTRIBUTE_UNUSED,
11630 int max_ready ATTRIBUTE_UNUSED)
11631 {
11632 last_scheduled_insn = NULL_RTX;
11633 s390_sched_state = 0;
11634 }
11635
11636 /* This function checks the whole of insn X for memory references. The
11637 function always returns zero because the framework it is called
11638 from would stop recursively analyzing the insn upon a return value
11639 other than zero. The real result of this function is updating
11640 counter variable MEM_COUNT. */
11641 static int
check_dpu(rtx * x,unsigned * mem_count)11642 check_dpu (rtx *x, unsigned *mem_count)
11643 {
11644 if (*x != NULL_RTX && MEM_P (*x))
11645 (*mem_count)++;
11646 return 0;
11647 }
11648
11649 /* This target hook implementation for TARGET_LOOP_UNROLL_ADJUST calculates
11650 a new number struct loop *loop should be unrolled if tuned for cpus with
11651 a built-in stride prefetcher.
11652 The loop is analyzed for memory accesses by calling check_dpu for
11653 each rtx of the loop. Depending on the loop_depth and the amount of
11654 memory accesses a new number <=nunroll is returned to improve the
11655 behaviour of the hardware prefetch unit. */
11656 static unsigned
s390_loop_unroll_adjust(unsigned nunroll,struct loop * loop)11657 s390_loop_unroll_adjust (unsigned nunroll, struct loop *loop)
11658 {
11659 basic_block *bbs;
11660 rtx insn;
11661 unsigned i;
11662 unsigned mem_count = 0;
11663
11664 if (s390_tune != PROCESSOR_2097_Z10
11665 && s390_tune != PROCESSOR_2817_Z196
11666 && s390_tune != PROCESSOR_2827_ZEC12)
11667 return nunroll;
11668
11669 /* Count the number of memory references within the loop body. */
11670 bbs = get_loop_body (loop);
11671 for (i = 0; i < loop->num_nodes; i++)
11672 {
11673 for (insn = BB_HEAD (bbs[i]); insn != BB_END (bbs[i]); insn = NEXT_INSN (insn))
11674 if (INSN_P (insn) && INSN_CODE (insn) != -1)
11675 for_each_rtx (&insn, (rtx_function) check_dpu, &mem_count);
11676 }
11677 free (bbs);
11678
11679 /* Prevent division by zero, and we do not need to adjust nunroll in this case. */
11680 if (mem_count == 0)
11681 return nunroll;
11682
11683 switch (loop_depth(loop))
11684 {
11685 case 1:
11686 return MIN (nunroll, 28 / mem_count);
11687 case 2:
11688 return MIN (nunroll, 22 / mem_count);
11689 default:
11690 return MIN (nunroll, 16 / mem_count);
11691 }
11692 }
11693
11694 /* Initialize GCC target structure. */
11695
11696 #undef TARGET_ASM_ALIGNED_HI_OP
11697 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
11698 #undef TARGET_ASM_ALIGNED_DI_OP
11699 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
11700 #undef TARGET_ASM_INTEGER
11701 #define TARGET_ASM_INTEGER s390_assemble_integer
11702
11703 #undef TARGET_ASM_OPEN_PAREN
11704 #define TARGET_ASM_OPEN_PAREN ""
11705
11706 #undef TARGET_ASM_CLOSE_PAREN
11707 #define TARGET_ASM_CLOSE_PAREN ""
11708
11709 #undef TARGET_OPTION_OVERRIDE
11710 #define TARGET_OPTION_OVERRIDE s390_option_override
11711
11712 #undef TARGET_ENCODE_SECTION_INFO
11713 #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
11714
11715 #undef TARGET_SCALAR_MODE_SUPPORTED_P
11716 #define TARGET_SCALAR_MODE_SUPPORTED_P s390_scalar_mode_supported_p
11717
11718 #ifdef HAVE_AS_TLS
11719 #undef TARGET_HAVE_TLS
11720 #define TARGET_HAVE_TLS true
11721 #endif
11722 #undef TARGET_CANNOT_FORCE_CONST_MEM
11723 #define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
11724
11725 #undef TARGET_DELEGITIMIZE_ADDRESS
11726 #define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
11727
11728 #undef TARGET_LEGITIMIZE_ADDRESS
11729 #define TARGET_LEGITIMIZE_ADDRESS s390_legitimize_address
11730
11731 #undef TARGET_RETURN_IN_MEMORY
11732 #define TARGET_RETURN_IN_MEMORY s390_return_in_memory
11733
11734 #undef TARGET_INIT_BUILTINS
11735 #define TARGET_INIT_BUILTINS s390_init_builtins
11736 #undef TARGET_EXPAND_BUILTIN
11737 #define TARGET_EXPAND_BUILTIN s390_expand_builtin
11738
11739 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
11740 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA s390_output_addr_const_extra
11741
11742 #undef TARGET_ASM_OUTPUT_MI_THUNK
11743 #define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
11744 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
11745 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
11746
11747 #undef TARGET_SCHED_ADJUST_PRIORITY
11748 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
11749 #undef TARGET_SCHED_ISSUE_RATE
11750 #define TARGET_SCHED_ISSUE_RATE s390_issue_rate
11751 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
11752 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
11753
11754 #undef TARGET_SCHED_VARIABLE_ISSUE
11755 #define TARGET_SCHED_VARIABLE_ISSUE s390_sched_variable_issue
11756 #undef TARGET_SCHED_REORDER
11757 #define TARGET_SCHED_REORDER s390_sched_reorder
11758 #undef TARGET_SCHED_INIT
11759 #define TARGET_SCHED_INIT s390_sched_init
11760
11761 #undef TARGET_CANNOT_COPY_INSN_P
11762 #define TARGET_CANNOT_COPY_INSN_P s390_cannot_copy_insn_p
11763 #undef TARGET_RTX_COSTS
11764 #define TARGET_RTX_COSTS s390_rtx_costs
11765 #undef TARGET_ADDRESS_COST
11766 #define TARGET_ADDRESS_COST s390_address_cost
11767 #undef TARGET_REGISTER_MOVE_COST
11768 #define TARGET_REGISTER_MOVE_COST s390_register_move_cost
11769 #undef TARGET_MEMORY_MOVE_COST
11770 #define TARGET_MEMORY_MOVE_COST s390_memory_move_cost
11771
11772 #undef TARGET_MACHINE_DEPENDENT_REORG
11773 #define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
11774
11775 #undef TARGET_VALID_POINTER_MODE
11776 #define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
11777
11778 #undef TARGET_BUILD_BUILTIN_VA_LIST
11779 #define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
11780 #undef TARGET_EXPAND_BUILTIN_VA_START
11781 #define TARGET_EXPAND_BUILTIN_VA_START s390_va_start
11782 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
11783 #define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg
11784
11785 #undef TARGET_PROMOTE_FUNCTION_MODE
11786 #define TARGET_PROMOTE_FUNCTION_MODE s390_promote_function_mode
11787 #undef TARGET_PASS_BY_REFERENCE
11788 #define TARGET_PASS_BY_REFERENCE s390_pass_by_reference
11789
11790 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
11791 #define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
11792 #undef TARGET_FUNCTION_ARG
11793 #define TARGET_FUNCTION_ARG s390_function_arg
11794 #undef TARGET_FUNCTION_ARG_ADVANCE
11795 #define TARGET_FUNCTION_ARG_ADVANCE s390_function_arg_advance
11796 #undef TARGET_FUNCTION_VALUE
11797 #define TARGET_FUNCTION_VALUE s390_function_value
11798 #undef TARGET_LIBCALL_VALUE
11799 #define TARGET_LIBCALL_VALUE s390_libcall_value
11800
11801 #undef TARGET_FIXED_CONDITION_CODE_REGS
11802 #define TARGET_FIXED_CONDITION_CODE_REGS s390_fixed_condition_code_regs
11803
11804 #undef TARGET_CC_MODES_COMPATIBLE
11805 #define TARGET_CC_MODES_COMPATIBLE s390_cc_modes_compatible
11806
11807 #undef TARGET_INVALID_WITHIN_DOLOOP
11808 #define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_const_rtx_null
11809
11810 #ifdef HAVE_AS_TLS
11811 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
11812 #define TARGET_ASM_OUTPUT_DWARF_DTPREL s390_output_dwarf_dtprel
11813 #endif
11814
11815 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
11816 #undef TARGET_MANGLE_TYPE
11817 #define TARGET_MANGLE_TYPE s390_mangle_type
11818 #endif
11819
11820 #undef TARGET_SCALAR_MODE_SUPPORTED_P
11821 #define TARGET_SCALAR_MODE_SUPPORTED_P s390_scalar_mode_supported_p
11822
11823 #undef TARGET_PREFERRED_RELOAD_CLASS
11824 #define TARGET_PREFERRED_RELOAD_CLASS s390_preferred_reload_class
11825
11826 #undef TARGET_SECONDARY_RELOAD
11827 #define TARGET_SECONDARY_RELOAD s390_secondary_reload
11828
11829 #undef TARGET_LIBGCC_CMP_RETURN_MODE
11830 #define TARGET_LIBGCC_CMP_RETURN_MODE s390_libgcc_cmp_return_mode
11831
11832 #undef TARGET_LIBGCC_SHIFT_COUNT_MODE
11833 #define TARGET_LIBGCC_SHIFT_COUNT_MODE s390_libgcc_shift_count_mode
11834
11835 #undef TARGET_LEGITIMATE_ADDRESS_P
11836 #define TARGET_LEGITIMATE_ADDRESS_P s390_legitimate_address_p
11837
11838 #undef TARGET_LEGITIMATE_CONSTANT_P
11839 #define TARGET_LEGITIMATE_CONSTANT_P s390_legitimate_constant_p
11840
11841 #undef TARGET_CAN_ELIMINATE
11842 #define TARGET_CAN_ELIMINATE s390_can_eliminate
11843
11844 #undef TARGET_CONDITIONAL_REGISTER_USAGE
11845 #define TARGET_CONDITIONAL_REGISTER_USAGE s390_conditional_register_usage
11846
11847 #undef TARGET_LOOP_UNROLL_ADJUST
11848 #define TARGET_LOOP_UNROLL_ADJUST s390_loop_unroll_adjust
11849
11850 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
11851 #define TARGET_ASM_TRAMPOLINE_TEMPLATE s390_asm_trampoline_template
11852 #undef TARGET_TRAMPOLINE_INIT
11853 #define TARGET_TRAMPOLINE_INIT s390_trampoline_init
11854
11855 #undef TARGET_UNWIND_WORD_MODE
11856 #define TARGET_UNWIND_WORD_MODE s390_unwind_word_mode
11857
11858 #undef TARGET_CANONICALIZE_COMPARISON
11859 #define TARGET_CANONICALIZE_COMPARISON s390_canonicalize_comparison
11860
11861 #undef TARGET_ATTRIBUTE_TABLE
11862 #define TARGET_ATTRIBUTE_TABLE s390_attribute_table
11863
11864 #undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
11865 #define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_const_tree_true
11866
11867 struct gcc_target targetm = TARGET_INITIALIZER;
11868
11869 #include "gt-s390.h"
11870