Merged r158229 through r158464 into branch.
[official-gcc.git] / gcc / config / s390 / s390.c
blobc3820e580123eb19b9ffd3f7f6dc82c1edede06f
1 /* Subroutines used for code generation on IBM S/390 and zSeries
2 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
3 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
4 Contributed by Hartmut Penner (hpenner@de.ibm.com) and
5 Ulrich Weigand (uweigand@de.ibm.com) and
6 Andreas Krebbel (Andreas.Krebbel@de.ibm.com).
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
13 version.
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 for more details.
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "tm_p.h"
31 #include "regs.h"
32 #include "hard-reg-set.h"
33 #include "real.h"
34 #include "insn-config.h"
35 #include "conditions.h"
36 #include "output.h"
37 #include "insn-attr.h"
38 #include "flags.h"
39 #include "except.h"
40 #include "function.h"
41 #include "recog.h"
42 #include "expr.h"
43 #include "reload.h"
44 #include "toplev.h"
45 #include "basic-block.h"
46 #include "integrate.h"
47 #include "ggc.h"
48 #include "target.h"
49 #include "target-def.h"
50 #include "debug.h"
51 #include "langhooks.h"
52 #include "optabs.h"
53 #include "gimple.h"
54 #include "df.h"
55 #include "params.h"
56 #include "cfgloop.h"
59 /* Define the specific costs for a given cpu. */
61 struct processor_costs
63 /* multiplication */
64 const int m; /* cost of an M instruction. */
65 const int mghi; /* cost of an MGHI instruction. */
66 const int mh; /* cost of an MH instruction. */
67 const int mhi; /* cost of an MHI instruction. */
68 const int ml; /* cost of an ML instruction. */
69 const int mr; /* cost of an MR instruction. */
70 const int ms; /* cost of an MS instruction. */
71 const int msg; /* cost of an MSG instruction. */
72 const int msgf; /* cost of an MSGF instruction. */
73 const int msgfr; /* cost of an MSGFR instruction. */
74 const int msgr; /* cost of an MSGR instruction. */
75 const int msr; /* cost of an MSR instruction. */
76 const int mult_df; /* cost of multiplication in DFmode. */
77 const int mxbr;
78 /* square root */
79 const int sqxbr; /* cost of square root in TFmode. */
80 const int sqdbr; /* cost of square root in DFmode. */
81 const int sqebr; /* cost of square root in SFmode. */
82 /* multiply and add */
83 const int madbr; /* cost of multiply and add in DFmode. */
84 const int maebr; /* cost of multiply and add in SFmode. */
85 /* division */
86 const int dxbr;
87 const int ddbr;
88 const int debr;
89 const int dlgr;
90 const int dlr;
91 const int dr;
92 const int dsgfr;
93 const int dsgr;
96 const struct processor_costs *s390_cost;
98 static const
99 struct processor_costs z900_cost =
101 COSTS_N_INSNS (5), /* M */
102 COSTS_N_INSNS (10), /* MGHI */
103 COSTS_N_INSNS (5), /* MH */
104 COSTS_N_INSNS (4), /* MHI */
105 COSTS_N_INSNS (5), /* ML */
106 COSTS_N_INSNS (5), /* MR */
107 COSTS_N_INSNS (4), /* MS */
108 COSTS_N_INSNS (15), /* MSG */
109 COSTS_N_INSNS (7), /* MSGF */
110 COSTS_N_INSNS (7), /* MSGFR */
111 COSTS_N_INSNS (10), /* MSGR */
112 COSTS_N_INSNS (4), /* MSR */
113 COSTS_N_INSNS (7), /* multiplication in DFmode */
114 COSTS_N_INSNS (13), /* MXBR */
115 COSTS_N_INSNS (136), /* SQXBR */
116 COSTS_N_INSNS (44), /* SQDBR */
117 COSTS_N_INSNS (35), /* SQEBR */
118 COSTS_N_INSNS (18), /* MADBR */
119 COSTS_N_INSNS (13), /* MAEBR */
120 COSTS_N_INSNS (134), /* DXBR */
121 COSTS_N_INSNS (30), /* DDBR */
122 COSTS_N_INSNS (27), /* DEBR */
123 COSTS_N_INSNS (220), /* DLGR */
124 COSTS_N_INSNS (34), /* DLR */
125 COSTS_N_INSNS (34), /* DR */
126 COSTS_N_INSNS (32), /* DSGFR */
127 COSTS_N_INSNS (32), /* DSGR */
130 static const
131 struct processor_costs z990_cost =
133 COSTS_N_INSNS (4), /* M */
134 COSTS_N_INSNS (2), /* MGHI */
135 COSTS_N_INSNS (2), /* MH */
136 COSTS_N_INSNS (2), /* MHI */
137 COSTS_N_INSNS (4), /* ML */
138 COSTS_N_INSNS (4), /* MR */
139 COSTS_N_INSNS (5), /* MS */
140 COSTS_N_INSNS (6), /* MSG */
141 COSTS_N_INSNS (4), /* MSGF */
142 COSTS_N_INSNS (4), /* MSGFR */
143 COSTS_N_INSNS (4), /* MSGR */
144 COSTS_N_INSNS (4), /* MSR */
145 COSTS_N_INSNS (1), /* multiplication in DFmode */
146 COSTS_N_INSNS (28), /* MXBR */
147 COSTS_N_INSNS (130), /* SQXBR */
148 COSTS_N_INSNS (66), /* SQDBR */
149 COSTS_N_INSNS (38), /* SQEBR */
150 COSTS_N_INSNS (1), /* MADBR */
151 COSTS_N_INSNS (1), /* MAEBR */
152 COSTS_N_INSNS (60), /* DXBR */
153 COSTS_N_INSNS (40), /* DDBR */
154 COSTS_N_INSNS (26), /* DEBR */
155 COSTS_N_INSNS (176), /* DLGR */
156 COSTS_N_INSNS (31), /* DLR */
157 COSTS_N_INSNS (31), /* DR */
158 COSTS_N_INSNS (31), /* DSGFR */
159 COSTS_N_INSNS (31), /* DSGR */
162 static const
163 struct processor_costs z9_109_cost =
165 COSTS_N_INSNS (4), /* M */
166 COSTS_N_INSNS (2), /* MGHI */
167 COSTS_N_INSNS (2), /* MH */
168 COSTS_N_INSNS (2), /* MHI */
169 COSTS_N_INSNS (4), /* ML */
170 COSTS_N_INSNS (4), /* MR */
171 COSTS_N_INSNS (5), /* MS */
172 COSTS_N_INSNS (6), /* MSG */
173 COSTS_N_INSNS (4), /* MSGF */
174 COSTS_N_INSNS (4), /* MSGFR */
175 COSTS_N_INSNS (4), /* MSGR */
176 COSTS_N_INSNS (4), /* MSR */
177 COSTS_N_INSNS (1), /* multiplication in DFmode */
178 COSTS_N_INSNS (28), /* MXBR */
179 COSTS_N_INSNS (130), /* SQXBR */
180 COSTS_N_INSNS (66), /* SQDBR */
181 COSTS_N_INSNS (38), /* SQEBR */
182 COSTS_N_INSNS (1), /* MADBR */
183 COSTS_N_INSNS (1), /* MAEBR */
184 COSTS_N_INSNS (60), /* DXBR */
185 COSTS_N_INSNS (40), /* DDBR */
186 COSTS_N_INSNS (26), /* DEBR */
187 COSTS_N_INSNS (30), /* DLGR */
188 COSTS_N_INSNS (23), /* DLR */
189 COSTS_N_INSNS (23), /* DR */
190 COSTS_N_INSNS (24), /* DSGFR */
191 COSTS_N_INSNS (24), /* DSGR */
194 static const
195 struct processor_costs z10_cost =
197 COSTS_N_INSNS (10), /* M */
198 COSTS_N_INSNS (10), /* MGHI */
199 COSTS_N_INSNS (10), /* MH */
200 COSTS_N_INSNS (10), /* MHI */
201 COSTS_N_INSNS (10), /* ML */
202 COSTS_N_INSNS (10), /* MR */
203 COSTS_N_INSNS (10), /* MS */
204 COSTS_N_INSNS (10), /* MSG */
205 COSTS_N_INSNS (10), /* MSGF */
206 COSTS_N_INSNS (10), /* MSGFR */
207 COSTS_N_INSNS (10), /* MSGR */
208 COSTS_N_INSNS (10), /* MSR */
209 COSTS_N_INSNS (1) , /* multiplication in DFmode */
210 COSTS_N_INSNS (50), /* MXBR */
211 COSTS_N_INSNS (120), /* SQXBR */
212 COSTS_N_INSNS (52), /* SQDBR */
213 COSTS_N_INSNS (38), /* SQEBR */
214 COSTS_N_INSNS (1), /* MADBR */
215 COSTS_N_INSNS (1), /* MAEBR */
216 COSTS_N_INSNS (111), /* DXBR */
217 COSTS_N_INSNS (39), /* DDBR */
218 COSTS_N_INSNS (32), /* DEBR */
219 COSTS_N_INSNS (160), /* DLGR */
220 COSTS_N_INSNS (71), /* DLR */
221 COSTS_N_INSNS (71), /* DR */
222 COSTS_N_INSNS (71), /* DSGFR */
223 COSTS_N_INSNS (71), /* DSGR */
226 extern int reload_completed;
228 /* Kept up to date using the SCHED_VARIABLE_ISSUE hook. */
229 static rtx last_scheduled_insn;
231 /* Structure used to hold the components of a S/390 memory
232 address. A legitimate address on S/390 is of the general
233 form
234 base + index + displacement
235 where any of the components is optional.
237 base and index are registers of the class ADDR_REGS,
238 displacement is an unsigned 12-bit immediate constant. */
240 struct s390_address
242 rtx base;
243 rtx indx;
244 rtx disp;
245 bool pointer;
246 bool literal_pool;
249 /* Which cpu are we tuning for. */
250 enum processor_type s390_tune = PROCESSOR_max;
251 int s390_tune_flags;
252 /* Which instruction set architecture to use. */
253 enum processor_type s390_arch;
254 int s390_arch_flags;
256 HOST_WIDE_INT s390_warn_framesize = 0;
257 HOST_WIDE_INT s390_stack_size = 0;
258 HOST_WIDE_INT s390_stack_guard = 0;
260 /* The following structure is embedded in the machine
261 specific part of struct function. */
263 struct GTY (()) s390_frame_layout
265 /* Offset within stack frame. */
266 HOST_WIDE_INT gprs_offset;
267 HOST_WIDE_INT f0_offset;
268 HOST_WIDE_INT f4_offset;
269 HOST_WIDE_INT f8_offset;
270 HOST_WIDE_INT backchain_offset;
272 /* Number of first and last gpr where slots in the register
273 save area are reserved for. */
274 int first_save_gpr_slot;
275 int last_save_gpr_slot;
277 /* Number of first and last gpr to be saved, restored. */
278 int first_save_gpr;
279 int first_restore_gpr;
280 int last_save_gpr;
281 int last_restore_gpr;
283 /* Bits standing for floating point registers. Set, if the
284 respective register has to be saved. Starting with reg 16 (f0)
285 at the rightmost bit.
286 Bit 15 - 8 7 6 5 4 3 2 1 0
287 fpr 15 - 8 7 5 3 1 6 4 2 0
288 reg 31 - 24 23 22 21 20 19 18 17 16 */
289 unsigned int fpr_bitmap;
291 /* Number of floating point registers f8-f15 which must be saved. */
292 int high_fprs;
294 /* Set if return address needs to be saved.
295 This flag is set by s390_return_addr_rtx if it could not use
296 the initial value of r14 and therefore depends on r14 saved
297 to the stack. */
298 bool save_return_addr_p;
300 /* Size of stack frame. */
301 HOST_WIDE_INT frame_size;
304 /* Define the structure for the machine field in struct function. */
306 struct GTY(()) machine_function
308 struct s390_frame_layout frame_layout;
310 /* Literal pool base register. */
311 rtx base_reg;
313 /* True if we may need to perform branch splitting. */
314 bool split_branches_pending_p;
316 /* Some local-dynamic TLS symbol name. */
317 const char *some_ld_name;
319 bool has_landing_pad_p;
322 /* Few accessor macros for struct cfun->machine->s390_frame_layout. */
324 #define cfun_frame_layout (cfun->machine->frame_layout)
325 #define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)
326 #define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr_slot - \
327 cfun_frame_layout.first_save_gpr_slot + 1) * UNITS_PER_LONG)
328 #define cfun_set_fpr_bit(BITNUM) (cfun->machine->frame_layout.fpr_bitmap |= \
329 (1 << (BITNUM)))
330 #define cfun_fpr_bit_p(BITNUM) (!!(cfun->machine->frame_layout.fpr_bitmap & \
331 (1 << (BITNUM))))
333 /* Number of GPRs and FPRs used for argument passing. */
334 #define GP_ARG_NUM_REG 5
335 #define FP_ARG_NUM_REG (TARGET_64BIT? 4 : 2)
337 /* A couple of shortcuts. */
338 #define CONST_OK_FOR_J(x) \
339 CONST_OK_FOR_CONSTRAINT_P((x), 'J', "J")
340 #define CONST_OK_FOR_K(x) \
341 CONST_OK_FOR_CONSTRAINT_P((x), 'K', "K")
342 #define CONST_OK_FOR_Os(x) \
343 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Os")
344 #define CONST_OK_FOR_Op(x) \
345 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Op")
346 #define CONST_OK_FOR_On(x) \
347 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "On")
349 #define REGNO_PAIR_OK(REGNO, MODE) \
350 (HARD_REGNO_NREGS ((REGNO), (MODE)) == 1 || !((REGNO) & 1))
352 /* That's the read ahead of the dynamic branch prediction unit in
353 bytes on a z10 CPU. */
354 #define Z10_PREDICT_DISTANCE 384
356 static enum machine_mode
357 s390_libgcc_cmp_return_mode (void)
359 return TARGET_64BIT ? DImode : SImode;
362 static enum machine_mode
363 s390_libgcc_shift_count_mode (void)
365 return TARGET_64BIT ? DImode : SImode;
368 static enum machine_mode
369 s390_unwind_word_mode (void)
371 return TARGET_64BIT ? DImode : SImode;
374 /* Return true if the back end supports mode MODE. */
375 static bool
376 s390_scalar_mode_supported_p (enum machine_mode mode)
378 /* In contrast to the default implementation reject TImode constants on 31bit
379 TARGET_ZARCH for ABI compliance. */
380 if (!TARGET_64BIT && TARGET_ZARCH && mode == TImode)
381 return false;
383 if (DECIMAL_FLOAT_MODE_P (mode))
384 return default_decimal_float_supported_p ();
386 return default_scalar_mode_supported_p (mode);
389 /* Set the has_landing_pad_p flag in struct machine_function to VALUE. */
391 void
392 s390_set_has_landing_pad_p (bool value)
394 cfun->machine->has_landing_pad_p = value;
397 /* If two condition code modes are compatible, return a condition code
398 mode which is compatible with both. Otherwise, return
399 VOIDmode. */
401 static enum machine_mode
402 s390_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
404 if (m1 == m2)
405 return m1;
407 switch (m1)
409 case CCZmode:
410 if (m2 == CCUmode || m2 == CCTmode || m2 == CCZ1mode
411 || m2 == CCSmode || m2 == CCSRmode || m2 == CCURmode)
412 return m2;
413 return VOIDmode;
415 case CCSmode:
416 case CCUmode:
417 case CCTmode:
418 case CCSRmode:
419 case CCURmode:
420 case CCZ1mode:
421 if (m2 == CCZmode)
422 return m1;
424 return VOIDmode;
426 default:
427 return VOIDmode;
429 return VOIDmode;
432 /* Return true if SET either doesn't set the CC register, or else
433 the source and destination have matching CC modes and that
434 CC mode is at least as constrained as REQ_MODE. */
436 static bool
437 s390_match_ccmode_set (rtx set, enum machine_mode req_mode)
439 enum machine_mode set_mode;
441 gcc_assert (GET_CODE (set) == SET);
443 if (GET_CODE (SET_DEST (set)) != REG || !CC_REGNO_P (REGNO (SET_DEST (set))))
444 return 1;
446 set_mode = GET_MODE (SET_DEST (set));
447 switch (set_mode)
449 case CCSmode:
450 case CCSRmode:
451 case CCUmode:
452 case CCURmode:
453 case CCLmode:
454 case CCL1mode:
455 case CCL2mode:
456 case CCL3mode:
457 case CCT1mode:
458 case CCT2mode:
459 case CCT3mode:
460 if (req_mode != set_mode)
461 return 0;
462 break;
464 case CCZmode:
465 if (req_mode != CCSmode && req_mode != CCUmode && req_mode != CCTmode
466 && req_mode != CCSRmode && req_mode != CCURmode)
467 return 0;
468 break;
470 case CCAPmode:
471 case CCANmode:
472 if (req_mode != CCAmode)
473 return 0;
474 break;
476 default:
477 gcc_unreachable ();
480 return (GET_MODE (SET_SRC (set)) == set_mode);
483 /* Return true if every SET in INSN that sets the CC register
484 has source and destination with matching CC modes and that
485 CC mode is at least as constrained as REQ_MODE.
486 If REQ_MODE is VOIDmode, always return false. */
488 bool
489 s390_match_ccmode (rtx insn, enum machine_mode req_mode)
491 int i;
493 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
494 if (req_mode == VOIDmode)
495 return false;
497 if (GET_CODE (PATTERN (insn)) == SET)
498 return s390_match_ccmode_set (PATTERN (insn), req_mode);
500 if (GET_CODE (PATTERN (insn)) == PARALLEL)
501 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
503 rtx set = XVECEXP (PATTERN (insn), 0, i);
504 if (GET_CODE (set) == SET)
505 if (!s390_match_ccmode_set (set, req_mode))
506 return false;
509 return true;
512 /* If a test-under-mask instruction can be used to implement
513 (compare (and ... OP1) OP2), return the CC mode required
514 to do that. Otherwise, return VOIDmode.
515 MIXED is true if the instruction can distinguish between
516 CC1 and CC2 for mixed selected bits (TMxx), it is false
517 if the instruction cannot (TM). */
519 enum machine_mode
520 s390_tm_ccmode (rtx op1, rtx op2, bool mixed)
522 int bit0, bit1;
524 /* ??? Fixme: should work on CONST_DOUBLE as well. */
525 if (GET_CODE (op1) != CONST_INT || GET_CODE (op2) != CONST_INT)
526 return VOIDmode;
528 /* Selected bits all zero: CC0.
529 e.g.: int a; if ((a & (16 + 128)) == 0) */
530 if (INTVAL (op2) == 0)
531 return CCTmode;
533 /* Selected bits all one: CC3.
534 e.g.: int a; if ((a & (16 + 128)) == 16 + 128) */
535 if (INTVAL (op2) == INTVAL (op1))
536 return CCT3mode;
538 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. e.g.:
539 int a;
540 if ((a & (16 + 128)) == 16) -> CCT1
541 if ((a & (16 + 128)) == 128) -> CCT2 */
542 if (mixed)
544 bit1 = exact_log2 (INTVAL (op2));
545 bit0 = exact_log2 (INTVAL (op1) ^ INTVAL (op2));
546 if (bit0 != -1 && bit1 != -1)
547 return bit0 > bit1 ? CCT1mode : CCT2mode;
550 return VOIDmode;
553 /* Given a comparison code OP (EQ, NE, etc.) and the operands
554 OP0 and OP1 of a COMPARE, return the mode to be used for the
555 comparison. */
557 enum machine_mode
558 s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
560 switch (code)
562 case EQ:
563 case NE:
564 if ((GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
565 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
566 return CCAPmode;
567 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
568 && CONST_OK_FOR_K (INTVAL (XEXP (op0, 1))))
569 return CCAPmode;
570 if ((GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
571 || GET_CODE (op1) == NEG)
572 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
573 return CCLmode;
575 if (GET_CODE (op0) == AND)
577 /* Check whether we can potentially do it via TM. */
578 enum machine_mode ccmode;
579 ccmode = s390_tm_ccmode (XEXP (op0, 1), op1, 1);
580 if (ccmode != VOIDmode)
582 /* Relax CCTmode to CCZmode to allow fall-back to AND
583 if that turns out to be beneficial. */
584 return ccmode == CCTmode ? CCZmode : ccmode;
588 if (register_operand (op0, HImode)
589 && GET_CODE (op1) == CONST_INT
590 && (INTVAL (op1) == -1 || INTVAL (op1) == 65535))
591 return CCT3mode;
592 if (register_operand (op0, QImode)
593 && GET_CODE (op1) == CONST_INT
594 && (INTVAL (op1) == -1 || INTVAL (op1) == 255))
595 return CCT3mode;
597 return CCZmode;
599 case LE:
600 case LT:
601 case GE:
602 case GT:
603 /* The only overflow condition of NEG and ABS happens when
604 -INT_MAX is used as parameter, which stays negative. So
605 we have an overflow from a positive value to a negative.
606 Using CCAP mode the resulting cc can be used for comparisons. */
607 if ((GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
608 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
609 return CCAPmode;
611 /* If constants are involved in an add instruction it is possible to use
612 the resulting cc for comparisons with zero. Knowing the sign of the
613 constant the overflow behavior gets predictable. e.g.:
614 int a, b; if ((b = a + c) > 0)
615 with c as a constant value: c < 0 -> CCAN and c >= 0 -> CCAP */
616 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
617 && CONST_OK_FOR_K (INTVAL (XEXP (op0, 1))))
619 if (INTVAL (XEXP((op0), 1)) < 0)
620 return CCANmode;
621 else
622 return CCAPmode;
624 /* Fall through. */
625 case UNORDERED:
626 case ORDERED:
627 case UNEQ:
628 case UNLE:
629 case UNLT:
630 case UNGE:
631 case UNGT:
632 case LTGT:
633 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
634 && GET_CODE (op1) != CONST_INT)
635 return CCSRmode;
636 return CCSmode;
638 case LTU:
639 case GEU:
640 if (GET_CODE (op0) == PLUS
641 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
642 return CCL1mode;
644 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
645 && GET_CODE (op1) != CONST_INT)
646 return CCURmode;
647 return CCUmode;
649 case LEU:
650 case GTU:
651 if (GET_CODE (op0) == MINUS
652 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
653 return CCL2mode;
655 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
656 && GET_CODE (op1) != CONST_INT)
657 return CCURmode;
658 return CCUmode;
660 default:
661 gcc_unreachable ();
665 /* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
666 that we can implement more efficiently. */
668 void
669 s390_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
671 /* Convert ZERO_EXTRACT back to AND to enable TM patterns. */
672 if ((*code == EQ || *code == NE)
673 && *op1 == const0_rtx
674 && GET_CODE (*op0) == ZERO_EXTRACT
675 && GET_CODE (XEXP (*op0, 1)) == CONST_INT
676 && GET_CODE (XEXP (*op0, 2)) == CONST_INT
677 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0, 0))))
679 rtx inner = XEXP (*op0, 0);
680 HOST_WIDE_INT modesize = GET_MODE_BITSIZE (GET_MODE (inner));
681 HOST_WIDE_INT len = INTVAL (XEXP (*op0, 1));
682 HOST_WIDE_INT pos = INTVAL (XEXP (*op0, 2));
684 if (len > 0 && len < modesize
685 && pos >= 0 && pos + len <= modesize
686 && modesize <= HOST_BITS_PER_WIDE_INT)
688 unsigned HOST_WIDE_INT block;
689 block = ((unsigned HOST_WIDE_INT) 1 << len) - 1;
690 block <<= modesize - pos - len;
692 *op0 = gen_rtx_AND (GET_MODE (inner), inner,
693 gen_int_mode (block, GET_MODE (inner)));
697 /* Narrow AND of memory against immediate to enable TM. */
698 if ((*code == EQ || *code == NE)
699 && *op1 == const0_rtx
700 && GET_CODE (*op0) == AND
701 && GET_CODE (XEXP (*op0, 1)) == CONST_INT
702 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0, 0))))
704 rtx inner = XEXP (*op0, 0);
705 rtx mask = XEXP (*op0, 1);
707 /* Ignore paradoxical SUBREGs if all extra bits are masked out. */
708 if (GET_CODE (inner) == SUBREG
709 && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (inner)))
710 && (GET_MODE_SIZE (GET_MODE (inner))
711 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner))))
712 && ((INTVAL (mask)
713 & GET_MODE_MASK (GET_MODE (inner))
714 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (inner))))
715 == 0))
716 inner = SUBREG_REG (inner);
718 /* Do not change volatile MEMs. */
719 if (MEM_P (inner) && !MEM_VOLATILE_P (inner))
721 int part = s390_single_part (XEXP (*op0, 1),
722 GET_MODE (inner), QImode, 0);
723 if (part >= 0)
725 mask = gen_int_mode (s390_extract_part (mask, QImode, 0), QImode);
726 inner = adjust_address_nv (inner, QImode, part);
727 *op0 = gen_rtx_AND (QImode, inner, mask);
732 /* Narrow comparisons against 0xffff to HImode if possible. */
733 if ((*code == EQ || *code == NE)
734 && GET_CODE (*op1) == CONST_INT
735 && INTVAL (*op1) == 0xffff
736 && SCALAR_INT_MODE_P (GET_MODE (*op0))
737 && (nonzero_bits (*op0, GET_MODE (*op0))
738 & ~(unsigned HOST_WIDE_INT) 0xffff) == 0)
740 *op0 = gen_lowpart (HImode, *op0);
741 *op1 = constm1_rtx;
744 /* Remove redundant UNSPEC_CCU_TO_INT conversions if possible. */
745 if (GET_CODE (*op0) == UNSPEC
746 && XINT (*op0, 1) == UNSPEC_CCU_TO_INT
747 && XVECLEN (*op0, 0) == 1
748 && GET_MODE (XVECEXP (*op0, 0, 0)) == CCUmode
749 && GET_CODE (XVECEXP (*op0, 0, 0)) == REG
750 && REGNO (XVECEXP (*op0, 0, 0)) == CC_REGNUM
751 && *op1 == const0_rtx)
753 enum rtx_code new_code = UNKNOWN;
754 switch (*code)
756 case EQ: new_code = EQ; break;
757 case NE: new_code = NE; break;
758 case LT: new_code = GTU; break;
759 case GT: new_code = LTU; break;
760 case LE: new_code = GEU; break;
761 case GE: new_code = LEU; break;
762 default: break;
765 if (new_code != UNKNOWN)
767 *op0 = XVECEXP (*op0, 0, 0);
768 *code = new_code;
772 /* Remove redundant UNSPEC_CCZ_TO_INT conversions if possible. */
773 if (GET_CODE (*op0) == UNSPEC
774 && XINT (*op0, 1) == UNSPEC_CCZ_TO_INT
775 && XVECLEN (*op0, 0) == 1
776 && GET_MODE (XVECEXP (*op0, 0, 0)) == CCZmode
777 && GET_CODE (XVECEXP (*op0, 0, 0)) == REG
778 && REGNO (XVECEXP (*op0, 0, 0)) == CC_REGNUM
779 && *op1 == const0_rtx)
781 enum rtx_code new_code = UNKNOWN;
782 switch (*code)
784 case EQ: new_code = EQ; break;
785 case NE: new_code = NE; break;
786 default: break;
789 if (new_code != UNKNOWN)
791 *op0 = XVECEXP (*op0, 0, 0);
792 *code = new_code;
796 /* Simplify cascaded EQ, NE with const0_rtx. */
797 if ((*code == NE || *code == EQ)
798 && (GET_CODE (*op0) == EQ || GET_CODE (*op0) == NE)
799 && GET_MODE (*op0) == SImode
800 && GET_MODE (XEXP (*op0, 0)) == CCZ1mode
801 && REG_P (XEXP (*op0, 0))
802 && XEXP (*op0, 1) == const0_rtx
803 && *op1 == const0_rtx)
805 if ((*code == EQ && GET_CODE (*op0) == NE)
806 || (*code == NE && GET_CODE (*op0) == EQ))
807 *code = EQ;
808 else
809 *code = NE;
810 *op0 = XEXP (*op0, 0);
813 /* Prefer register over memory as first operand. */
814 if (MEM_P (*op0) && REG_P (*op1))
816 rtx tem = *op0; *op0 = *op1; *op1 = tem;
817 *code = swap_condition (*code);
821 /* Emit a compare instruction suitable to implement the comparison
822 OP0 CODE OP1. Return the correct condition RTL to be placed in
823 the IF_THEN_ELSE of the conditional branch testing the result. */
826 s390_emit_compare (enum rtx_code code, rtx op0, rtx op1)
828 enum machine_mode mode = s390_select_ccmode (code, op0, op1);
829 rtx cc;
831 /* Do not output a redundant compare instruction if a compare_and_swap
832 pattern already computed the result and the machine modes are compatible. */
833 if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
835 gcc_assert (s390_cc_modes_compatible (GET_MODE (op0), mode)
836 == GET_MODE (op0));
837 cc = op0;
839 else
841 cc = gen_rtx_REG (mode, CC_REGNUM);
842 emit_insn (gen_rtx_SET (VOIDmode, cc, gen_rtx_COMPARE (mode, op0, op1)));
845 return gen_rtx_fmt_ee (code, VOIDmode, cc, const0_rtx);
848 /* Emit a SImode compare and swap instruction setting MEM to NEW_RTX if OLD
849 matches CMP.
850 Return the correct condition RTL to be placed in the IF_THEN_ELSE of the
851 conditional branch testing the result. */
853 static rtx
854 s390_emit_compare_and_swap (enum rtx_code code, rtx old, rtx mem, rtx cmp, rtx new_rtx)
856 emit_insn (gen_sync_compare_and_swapsi (old, mem, cmp, new_rtx));
857 return s390_emit_compare (code, gen_rtx_REG (CCZ1mode, CC_REGNUM), const0_rtx);
860 /* Emit a jump instruction to TARGET. If COND is NULL_RTX, emit an
861 unconditional jump, else a conditional jump under condition COND. */
863 void
864 s390_emit_jump (rtx target, rtx cond)
866 rtx insn;
868 target = gen_rtx_LABEL_REF (VOIDmode, target);
869 if (cond)
870 target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, target, pc_rtx);
872 insn = gen_rtx_SET (VOIDmode, pc_rtx, target);
873 emit_jump_insn (insn);
876 /* Return branch condition mask to implement a branch
877 specified by CODE. Return -1 for invalid comparisons. */
880 s390_branch_condition_mask (rtx code)
882 const int CC0 = 1 << 3;
883 const int CC1 = 1 << 2;
884 const int CC2 = 1 << 1;
885 const int CC3 = 1 << 0;
887 gcc_assert (GET_CODE (XEXP (code, 0)) == REG);
888 gcc_assert (REGNO (XEXP (code, 0)) == CC_REGNUM);
889 gcc_assert (XEXP (code, 1) == const0_rtx);
891 switch (GET_MODE (XEXP (code, 0)))
893 case CCZmode:
894 case CCZ1mode:
895 switch (GET_CODE (code))
897 case EQ: return CC0;
898 case NE: return CC1 | CC2 | CC3;
899 default: return -1;
901 break;
903 case CCT1mode:
904 switch (GET_CODE (code))
906 case EQ: return CC1;
907 case NE: return CC0 | CC2 | CC3;
908 default: return -1;
910 break;
912 case CCT2mode:
913 switch (GET_CODE (code))
915 case EQ: return CC2;
916 case NE: return CC0 | CC1 | CC3;
917 default: return -1;
919 break;
921 case CCT3mode:
922 switch (GET_CODE (code))
924 case EQ: return CC3;
925 case NE: return CC0 | CC1 | CC2;
926 default: return -1;
928 break;
930 case CCLmode:
931 switch (GET_CODE (code))
933 case EQ: return CC0 | CC2;
934 case NE: return CC1 | CC3;
935 default: return -1;
937 break;
939 case CCL1mode:
940 switch (GET_CODE (code))
942 case LTU: return CC2 | CC3; /* carry */
943 case GEU: return CC0 | CC1; /* no carry */
944 default: return -1;
946 break;
948 case CCL2mode:
949 switch (GET_CODE (code))
951 case GTU: return CC0 | CC1; /* borrow */
952 case LEU: return CC2 | CC3; /* no borrow */
953 default: return -1;
955 break;
957 case CCL3mode:
958 switch (GET_CODE (code))
960 case EQ: return CC0 | CC2;
961 case NE: return CC1 | CC3;
962 case LTU: return CC1;
963 case GTU: return CC3;
964 case LEU: return CC1 | CC2;
965 case GEU: return CC2 | CC3;
966 default: return -1;
969 case CCUmode:
970 switch (GET_CODE (code))
972 case EQ: return CC0;
973 case NE: return CC1 | CC2 | CC3;
974 case LTU: return CC1;
975 case GTU: return CC2;
976 case LEU: return CC0 | CC1;
977 case GEU: return CC0 | CC2;
978 default: return -1;
980 break;
982 case CCURmode:
983 switch (GET_CODE (code))
985 case EQ: return CC0;
986 case NE: return CC2 | CC1 | CC3;
987 case LTU: return CC2;
988 case GTU: return CC1;
989 case LEU: return CC0 | CC2;
990 case GEU: return CC0 | CC1;
991 default: return -1;
993 break;
995 case CCAPmode:
996 switch (GET_CODE (code))
998 case EQ: return CC0;
999 case NE: return CC1 | CC2 | CC3;
1000 case LT: return CC1 | CC3;
1001 case GT: return CC2;
1002 case LE: return CC0 | CC1 | CC3;
1003 case GE: return CC0 | CC2;
1004 default: return -1;
1006 break;
1008 case CCANmode:
1009 switch (GET_CODE (code))
1011 case EQ: return CC0;
1012 case NE: return CC1 | CC2 | CC3;
1013 case LT: return CC1;
1014 case GT: return CC2 | CC3;
1015 case LE: return CC0 | CC1;
1016 case GE: return CC0 | CC2 | CC3;
1017 default: return -1;
1019 break;
1021 case CCSmode:
1022 switch (GET_CODE (code))
1024 case EQ: return CC0;
1025 case NE: return CC1 | CC2 | CC3;
1026 case LT: return CC1;
1027 case GT: return CC2;
1028 case LE: return CC0 | CC1;
1029 case GE: return CC0 | CC2;
1030 case UNORDERED: return CC3;
1031 case ORDERED: return CC0 | CC1 | CC2;
1032 case UNEQ: return CC0 | CC3;
1033 case UNLT: return CC1 | CC3;
1034 case UNGT: return CC2 | CC3;
1035 case UNLE: return CC0 | CC1 | CC3;
1036 case UNGE: return CC0 | CC2 | CC3;
1037 case LTGT: return CC1 | CC2;
1038 default: return -1;
1040 break;
1042 case CCSRmode:
1043 switch (GET_CODE (code))
1045 case EQ: return CC0;
1046 case NE: return CC2 | CC1 | CC3;
1047 case LT: return CC2;
1048 case GT: return CC1;
1049 case LE: return CC0 | CC2;
1050 case GE: return CC0 | CC1;
1051 case UNORDERED: return CC3;
1052 case ORDERED: return CC0 | CC2 | CC1;
1053 case UNEQ: return CC0 | CC3;
1054 case UNLT: return CC2 | CC3;
1055 case UNGT: return CC1 | CC3;
1056 case UNLE: return CC0 | CC2 | CC3;
1057 case UNGE: return CC0 | CC1 | CC3;
1058 case LTGT: return CC2 | CC1;
1059 default: return -1;
1061 break;
1063 default:
1064 return -1;
1069 /* Return branch condition mask to implement a compare and branch
1070 specified by CODE. Return -1 for invalid comparisons. */
1073 s390_compare_and_branch_condition_mask (rtx code)
1075 const int CC0 = 1 << 3;
1076 const int CC1 = 1 << 2;
1077 const int CC2 = 1 << 1;
1079 switch (GET_CODE (code))
1081 case EQ:
1082 return CC0;
1083 case NE:
1084 return CC1 | CC2;
1085 case LT:
1086 case LTU:
1087 return CC1;
1088 case GT:
1089 case GTU:
1090 return CC2;
1091 case LE:
1092 case LEU:
1093 return CC0 | CC1;
1094 case GE:
1095 case GEU:
1096 return CC0 | CC2;
1097 default:
1098 gcc_unreachable ();
1100 return -1;
1103 /* If INV is false, return assembler mnemonic string to implement
1104 a branch specified by CODE. If INV is true, return mnemonic
1105 for the corresponding inverted branch. */
1107 static const char *
1108 s390_branch_condition_mnemonic (rtx code, int inv)
1110 int mask;
1112 static const char *const mnemonic[16] =
1114 NULL, "o", "h", "nle",
1115 "l", "nhe", "lh", "ne",
1116 "e", "nlh", "he", "nl",
1117 "le", "nh", "no", NULL
1120 if (GET_CODE (XEXP (code, 0)) == REG
1121 && REGNO (XEXP (code, 0)) == CC_REGNUM
1122 && XEXP (code, 1) == const0_rtx)
1123 mask = s390_branch_condition_mask (code);
1124 else
1125 mask = s390_compare_and_branch_condition_mask (code);
1127 gcc_assert (mask >= 0);
1129 if (inv)
1130 mask ^= 15;
1132 gcc_assert (mask >= 1 && mask <= 14);
1134 return mnemonic[mask];
1137 /* Return the part of op which has a value different from def.
1138 The size of the part is determined by mode.
1139 Use this function only if you already know that op really
1140 contains such a part. */
1142 unsigned HOST_WIDE_INT
1143 s390_extract_part (rtx op, enum machine_mode mode, int def)
1145 unsigned HOST_WIDE_INT value = 0;
1146 int max_parts = HOST_BITS_PER_WIDE_INT / GET_MODE_BITSIZE (mode);
1147 int part_bits = GET_MODE_BITSIZE (mode);
1148 unsigned HOST_WIDE_INT part_mask
1149 = ((unsigned HOST_WIDE_INT)1 << part_bits) - 1;
1150 int i;
1152 for (i = 0; i < max_parts; i++)
1154 if (i == 0)
1155 value = (unsigned HOST_WIDE_INT) INTVAL (op);
1156 else
1157 value >>= part_bits;
1159 if ((value & part_mask) != (def & part_mask))
1160 return value & part_mask;
1163 gcc_unreachable ();
1166 /* If OP is an integer constant of mode MODE with exactly one
1167 part of mode PART_MODE unequal to DEF, return the number of that
1168 part. Otherwise, return -1. */
1171 s390_single_part (rtx op,
1172 enum machine_mode mode,
1173 enum machine_mode part_mode,
1174 int def)
1176 unsigned HOST_WIDE_INT value = 0;
1177 int n_parts = GET_MODE_SIZE (mode) / GET_MODE_SIZE (part_mode);
1178 unsigned HOST_WIDE_INT part_mask
1179 = ((unsigned HOST_WIDE_INT)1 << GET_MODE_BITSIZE (part_mode)) - 1;
1180 int i, part = -1;
1182 if (GET_CODE (op) != CONST_INT)
1183 return -1;
1185 for (i = 0; i < n_parts; i++)
1187 if (i == 0)
1188 value = (unsigned HOST_WIDE_INT) INTVAL (op);
1189 else
1190 value >>= GET_MODE_BITSIZE (part_mode);
1192 if ((value & part_mask) != (def & part_mask))
1194 if (part != -1)
1195 return -1;
1196 else
1197 part = i;
1200 return part == -1 ? -1 : n_parts - 1 - part;
1203 /* Return true if IN contains a contiguous bitfield in the lower SIZE
1204 bits and no other bits are set in IN. POS and LENGTH can be used
1205 to obtain the start position and the length of the bitfield.
1207 POS gives the position of the first bit of the bitfield counting
1208 from the lowest order bit starting with zero. In order to use this
1209 value for S/390 instructions this has to be converted to "bits big
1210 endian" style. */
1212 bool
1213 s390_contiguous_bitmask_p (unsigned HOST_WIDE_INT in, int size,
1214 int *pos, int *length)
1216 int tmp_pos = 0;
1217 int tmp_length = 0;
1218 int i;
1219 unsigned HOST_WIDE_INT mask = 1ULL;
1220 bool contiguous = false;
1222 for (i = 0; i < size; mask <<= 1, i++)
1224 if (contiguous)
1226 if (mask & in)
1227 tmp_length++;
1228 else
1229 break;
1231 else
1233 if (mask & in)
1235 contiguous = true;
1236 tmp_length++;
1238 else
1239 tmp_pos++;
1243 if (!tmp_length)
1244 return false;
1246 /* Calculate a mask for all bits beyond the contiguous bits. */
1247 mask = (-1LL & ~(((1ULL << (tmp_length + tmp_pos - 1)) << 1) - 1));
1249 if (mask & in)
1250 return false;
1252 if (tmp_length + tmp_pos - 1 > size)
1253 return false;
1255 if (length)
1256 *length = tmp_length;
1258 if (pos)
1259 *pos = tmp_pos;
1261 return true;
1264 /* Check whether we can (and want to) split a double-word
1265 move in mode MODE from SRC to DST into two single-word
1266 moves, moving the subword FIRST_SUBWORD first. */
1268 bool
1269 s390_split_ok_p (rtx dst, rtx src, enum machine_mode mode, int first_subword)
1271 /* Floating point registers cannot be split. */
1272 if (FP_REG_P (src) || FP_REG_P (dst))
1273 return false;
1275 /* We don't need to split if operands are directly accessible. */
1276 if (s_operand (src, mode) || s_operand (dst, mode))
1277 return false;
1279 /* Non-offsettable memory references cannot be split. */
1280 if ((GET_CODE (src) == MEM && !offsettable_memref_p (src))
1281 || (GET_CODE (dst) == MEM && !offsettable_memref_p (dst)))
1282 return false;
1284 /* Moving the first subword must not clobber a register
1285 needed to move the second subword. */
1286 if (register_operand (dst, mode))
1288 rtx subreg = operand_subword (dst, first_subword, 0, mode);
1289 if (reg_overlap_mentioned_p (subreg, src))
1290 return false;
1293 return true;
1296 /* Return true if it can be proven that [MEM1, MEM1 + SIZE]
1297 and [MEM2, MEM2 + SIZE] do overlap and false
1298 otherwise. */
1300 bool
1301 s390_overlap_p (rtx mem1, rtx mem2, HOST_WIDE_INT size)
1303 rtx addr1, addr2, addr_delta;
1304 HOST_WIDE_INT delta;
1306 if (GET_CODE (mem1) != MEM || GET_CODE (mem2) != MEM)
1307 return true;
1309 if (size == 0)
1310 return false;
1312 addr1 = XEXP (mem1, 0);
1313 addr2 = XEXP (mem2, 0);
1315 addr_delta = simplify_binary_operation (MINUS, Pmode, addr2, addr1);
1317 /* This overlapping check is used by peepholes merging memory block operations.
1318 Overlapping operations would otherwise be recognized by the S/390 hardware
1319 and would fall back to a slower implementation. Allowing overlapping
1320 operations would lead to slow code but not to wrong code. Therefore we are
1321 somewhat optimistic if we cannot prove that the memory blocks are
1322 overlapping.
1323 That's why we return false here although this may accept operations on
1324 overlapping memory areas. */
1325 if (!addr_delta || GET_CODE (addr_delta) != CONST_INT)
1326 return false;
1328 delta = INTVAL (addr_delta);
1330 if (delta == 0
1331 || (delta > 0 && delta < size)
1332 || (delta < 0 && -delta < size))
1333 return true;
1335 return false;
1338 /* Check whether the address of memory reference MEM2 equals exactly
1339 the address of memory reference MEM1 plus DELTA. Return true if
1340 we can prove this to be the case, false otherwise. */
1342 bool
1343 s390_offset_p (rtx mem1, rtx mem2, rtx delta)
1345 rtx addr1, addr2, addr_delta;
1347 if (GET_CODE (mem1) != MEM || GET_CODE (mem2) != MEM)
1348 return false;
1350 addr1 = XEXP (mem1, 0);
1351 addr2 = XEXP (mem2, 0);
1353 addr_delta = simplify_binary_operation (MINUS, Pmode, addr2, addr1);
1354 if (!addr_delta || !rtx_equal_p (addr_delta, delta))
1355 return false;
1357 return true;
1360 /* Expand logical operator CODE in mode MODE with operands OPERANDS. */
1362 void
1363 s390_expand_logical_operator (enum rtx_code code, enum machine_mode mode,
1364 rtx *operands)
1366 enum machine_mode wmode = mode;
1367 rtx dst = operands[0];
1368 rtx src1 = operands[1];
1369 rtx src2 = operands[2];
1370 rtx op, clob, tem;
1372 /* If we cannot handle the operation directly, use a temp register. */
1373 if (!s390_logical_operator_ok_p (operands))
1374 dst = gen_reg_rtx (mode);
1376 /* QImode and HImode patterns make sense only if we have a destination
1377 in memory. Otherwise perform the operation in SImode. */
1378 if ((mode == QImode || mode == HImode) && GET_CODE (dst) != MEM)
1379 wmode = SImode;
1381 /* Widen operands if required. */
1382 if (mode != wmode)
1384 if (GET_CODE (dst) == SUBREG
1385 && (tem = simplify_subreg (wmode, dst, mode, 0)) != 0)
1386 dst = tem;
1387 else if (REG_P (dst))
1388 dst = gen_rtx_SUBREG (wmode, dst, 0);
1389 else
1390 dst = gen_reg_rtx (wmode);
1392 if (GET_CODE (src1) == SUBREG
1393 && (tem = simplify_subreg (wmode, src1, mode, 0)) != 0)
1394 src1 = tem;
1395 else if (GET_MODE (src1) != VOIDmode)
1396 src1 = gen_rtx_SUBREG (wmode, force_reg (mode, src1), 0);
1398 if (GET_CODE (src2) == SUBREG
1399 && (tem = simplify_subreg (wmode, src2, mode, 0)) != 0)
1400 src2 = tem;
1401 else if (GET_MODE (src2) != VOIDmode)
1402 src2 = gen_rtx_SUBREG (wmode, force_reg (mode, src2), 0);
1405 /* Emit the instruction. */
1406 op = gen_rtx_SET (VOIDmode, dst, gen_rtx_fmt_ee (code, wmode, src1, src2));
1407 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
1408 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
1410 /* Fix up the destination if needed. */
1411 if (dst != operands[0])
1412 emit_move_insn (operands[0], gen_lowpart (mode, dst));
1415 /* Check whether OPERANDS are OK for a logical operation (AND, IOR, XOR). */
1417 bool
1418 s390_logical_operator_ok_p (rtx *operands)
1420 /* If the destination operand is in memory, it needs to coincide
1421 with one of the source operands. After reload, it has to be
1422 the first source operand. */
1423 if (GET_CODE (operands[0]) == MEM)
1424 return rtx_equal_p (operands[0], operands[1])
1425 || (!reload_completed && rtx_equal_p (operands[0], operands[2]));
1427 return true;
1430 /* Narrow logical operation CODE of memory operand MEMOP with immediate
1431 operand IMMOP to switch from SS to SI type instructions. */
1433 void
1434 s390_narrow_logical_operator (enum rtx_code code, rtx *memop, rtx *immop)
1436 int def = code == AND ? -1 : 0;
1437 HOST_WIDE_INT mask;
1438 int part;
1440 gcc_assert (GET_CODE (*memop) == MEM);
1441 gcc_assert (!MEM_VOLATILE_P (*memop));
1443 mask = s390_extract_part (*immop, QImode, def);
1444 part = s390_single_part (*immop, GET_MODE (*memop), QImode, def);
1445 gcc_assert (part >= 0);
1447 *memop = adjust_address (*memop, QImode, part);
1448 *immop = gen_int_mode (mask, QImode);
1452 /* How to allocate a 'struct machine_function'. */
1454 static struct machine_function *
1455 s390_init_machine_status (void)
1457 return GGC_CNEW (struct machine_function);
1460 /* Change optimizations to be performed, depending on the
1461 optimization level.
1463 LEVEL is the optimization level specified; 2 if `-O2' is
1464 specified, 1 if `-O' is specified, and 0 if neither is specified.
1466 SIZE is nonzero if `-Os' is specified and zero otherwise. */
1468 void
1469 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
1471 /* ??? There are apparently still problems with -fcaller-saves. */
1472 flag_caller_saves = 0;
1474 /* By default, always emit DWARF-2 unwind info. This allows debugging
1475 without maintaining a stack frame back-chain. */
1476 flag_asynchronous_unwind_tables = 1;
1478 /* Use MVCLE instructions to decrease code size if requested. */
1479 if (size != 0)
1480 target_flags |= MASK_MVCLE;
1483 /* Return true if ARG is the name of a processor. Set *TYPE and *FLAGS
1484 to the associated processor_type and processor_flags if so. */
1486 static bool
1487 s390_handle_arch_option (const char *arg,
1488 enum processor_type *type,
1489 int *flags)
1491 static struct pta
1493 const char *const name; /* processor name or nickname. */
1494 const enum processor_type processor;
1495 const int flags; /* From enum processor_flags. */
1497 const processor_alias_table[] =
1499 {"g5", PROCESSOR_9672_G5, PF_IEEE_FLOAT},
1500 {"g6", PROCESSOR_9672_G6, PF_IEEE_FLOAT},
1501 {"z900", PROCESSOR_2064_Z900, PF_IEEE_FLOAT | PF_ZARCH},
1502 {"z990", PROCESSOR_2084_Z990, PF_IEEE_FLOAT | PF_ZARCH
1503 | PF_LONG_DISPLACEMENT},
1504 {"z9-109", PROCESSOR_2094_Z9_109, PF_IEEE_FLOAT | PF_ZARCH
1505 | PF_LONG_DISPLACEMENT | PF_EXTIMM},
1506 {"z9-ec", PROCESSOR_2094_Z9_109, PF_IEEE_FLOAT | PF_ZARCH
1507 | PF_LONG_DISPLACEMENT | PF_EXTIMM | PF_DFP },
1508 {"z10", PROCESSOR_2097_Z10, PF_IEEE_FLOAT | PF_ZARCH
1509 | PF_LONG_DISPLACEMENT | PF_EXTIMM | PF_DFP | PF_Z10},
1511 size_t i;
1513 for (i = 0; i < ARRAY_SIZE (processor_alias_table); i++)
1514 if (strcmp (arg, processor_alias_table[i].name) == 0)
1516 *type = processor_alias_table[i].processor;
1517 *flags = processor_alias_table[i].flags;
1518 return true;
1520 return false;
1523 /* Implement TARGET_HANDLE_OPTION. */
1525 static bool
1526 s390_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
1528 switch (code)
1530 case OPT_march_:
1531 return s390_handle_arch_option (arg, &s390_arch, &s390_arch_flags);
1533 case OPT_mstack_guard_:
1534 if (sscanf (arg, HOST_WIDE_INT_PRINT_DEC, &s390_stack_guard) != 1)
1535 return false;
1536 if (exact_log2 (s390_stack_guard) == -1)
1537 error ("stack guard value must be an exact power of 2");
1538 return true;
1540 case OPT_mstack_size_:
1541 if (sscanf (arg, HOST_WIDE_INT_PRINT_DEC, &s390_stack_size) != 1)
1542 return false;
1543 if (exact_log2 (s390_stack_size) == -1)
1544 error ("stack size must be an exact power of 2");
1545 return true;
1547 case OPT_mtune_:
1548 return s390_handle_arch_option (arg, &s390_tune, &s390_tune_flags);
1550 case OPT_mwarn_framesize_:
1551 return sscanf (arg, HOST_WIDE_INT_PRINT_DEC, &s390_warn_framesize) == 1;
1553 default:
1554 return true;
1558 void
1559 override_options (void)
1561 /* Set up function hooks. */
1562 init_machine_status = s390_init_machine_status;
1564 /* Architecture mode defaults according to ABI. */
1565 if (!(target_flags_explicit & MASK_ZARCH))
1567 if (TARGET_64BIT)
1568 target_flags |= MASK_ZARCH;
1569 else
1570 target_flags &= ~MASK_ZARCH;
1573 /* Determine processor architectural level. */
1574 if (!s390_arch_string)
1576 s390_arch_string = TARGET_ZARCH? "z900" : "g5";
1577 s390_handle_arch_option (s390_arch_string, &s390_arch, &s390_arch_flags);
1580 /* Determine processor to tune for. */
1581 if (s390_tune == PROCESSOR_max)
1583 s390_tune = s390_arch;
1584 s390_tune_flags = s390_arch_flags;
1587 /* Sanity checks. */
1588 if (TARGET_ZARCH && !TARGET_CPU_ZARCH)
1589 error ("z/Architecture mode not supported on %s", s390_arch_string);
1590 if (TARGET_64BIT && !TARGET_ZARCH)
1591 error ("64-bit ABI not supported in ESA/390 mode");
1593 if (TARGET_HARD_DFP && !TARGET_DFP)
1595 if (target_flags_explicit & MASK_HARD_DFP)
1597 if (!TARGET_CPU_DFP)
1598 error ("Hardware decimal floating point instructions"
1599 " not available on %s", s390_arch_string);
1600 if (!TARGET_ZARCH)
1601 error ("Hardware decimal floating point instructions"
1602 " not available in ESA/390 mode");
1604 else
1605 target_flags &= ~MASK_HARD_DFP;
1608 if ((target_flags_explicit & MASK_SOFT_FLOAT) && TARGET_SOFT_FLOAT)
1610 if ((target_flags_explicit & MASK_HARD_DFP) && TARGET_HARD_DFP)
1611 error ("-mhard-dfp can't be used in conjunction with -msoft-float");
1613 target_flags &= ~MASK_HARD_DFP;
1616 /* Set processor cost function. */
1617 switch (s390_tune)
1619 case PROCESSOR_2084_Z990:
1620 s390_cost = &z990_cost;
1621 break;
1622 case PROCESSOR_2094_Z9_109:
1623 s390_cost = &z9_109_cost;
1624 break;
1625 case PROCESSOR_2097_Z10:
1626 s390_cost = &z10_cost;
1627 break;
1628 default:
1629 s390_cost = &z900_cost;
1632 if (TARGET_BACKCHAIN && TARGET_PACKED_STACK && TARGET_HARD_FLOAT)
1633 error ("-mbackchain -mpacked-stack -mhard-float are not supported "
1634 "in combination");
1636 if (s390_stack_size)
1638 if (s390_stack_guard >= s390_stack_size)
1639 error ("stack size must be greater than the stack guard value");
1640 else if (s390_stack_size > 1 << 16)
1641 error ("stack size must not be greater than 64k");
1643 else if (s390_stack_guard)
1644 error ("-mstack-guard implies use of -mstack-size");
1646 #ifdef TARGET_DEFAULT_LONG_DOUBLE_128
1647 if (!(target_flags_explicit & MASK_LONG_DOUBLE_128))
1648 target_flags |= MASK_LONG_DOUBLE_128;
1649 #endif
1651 if (s390_tune == PROCESSOR_2097_Z10)
1653 if (!PARAM_SET_P (PARAM_MAX_UNROLLED_INSNS))
1654 set_param_value ("max-unrolled-insns", 100);
1655 if (!PARAM_SET_P (PARAM_MAX_UNROLL_TIMES))
1656 set_param_value ("max-unroll-times", 32);
1657 if (!PARAM_SET_P (PARAM_MAX_COMPLETELY_PEELED_INSNS))
1658 set_param_value ("max-completely-peeled-insns", 800);
1659 if (!PARAM_SET_P (PARAM_MAX_COMPLETELY_PEEL_TIMES))
1660 set_param_value ("max-completely-peel-times", 64);
1663 set_param_value ("max-pending-list-length", 256);
1666 /* Map for smallest class containing reg regno. */
1668 const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
1669 { GENERAL_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1670 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1671 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1672 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1673 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1674 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1675 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1676 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1677 ADDR_REGS, CC_REGS, ADDR_REGS, ADDR_REGS,
1678 ACCESS_REGS, ACCESS_REGS
1681 /* Return attribute type of insn. */
1683 static enum attr_type
1684 s390_safe_attr_type (rtx insn)
1686 if (recog_memoized (insn) >= 0)
1687 return get_attr_type (insn);
1688 else
1689 return TYPE_NONE;
1692 /* Return true if DISP is a valid short displacement. */
1694 static bool
1695 s390_short_displacement (rtx disp)
1697 /* No displacement is OK. */
1698 if (!disp)
1699 return true;
1701 /* Without the long displacement facility we don't need to
1702 distingiush between long and short displacement. */
1703 if (!TARGET_LONG_DISPLACEMENT)
1704 return true;
1706 /* Integer displacement in range. */
1707 if (GET_CODE (disp) == CONST_INT)
1708 return INTVAL (disp) >= 0 && INTVAL (disp) < 4096;
1710 /* GOT offset is not OK, the GOT can be large. */
1711 if (GET_CODE (disp) == CONST
1712 && GET_CODE (XEXP (disp, 0)) == UNSPEC
1713 && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOT
1714 || XINT (XEXP (disp, 0), 1) == UNSPEC_GOTNTPOFF))
1715 return false;
1717 /* All other symbolic constants are literal pool references,
1718 which are OK as the literal pool must be small. */
1719 if (GET_CODE (disp) == CONST)
1720 return true;
1722 return false;
1725 /* Decompose a RTL expression ADDR for a memory address into
1726 its components, returned in OUT.
1728 Returns false if ADDR is not a valid memory address, true
1729 otherwise. If OUT is NULL, don't return the components,
1730 but check for validity only.
1732 Note: Only addresses in canonical form are recognized.
1733 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
1734 canonical form so that they will be recognized. */
1736 static int
1737 s390_decompose_address (rtx addr, struct s390_address *out)
1739 HOST_WIDE_INT offset = 0;
1740 rtx base = NULL_RTX;
1741 rtx indx = NULL_RTX;
1742 rtx disp = NULL_RTX;
1743 rtx orig_disp;
1744 bool pointer = false;
1745 bool base_ptr = false;
1746 bool indx_ptr = false;
1747 bool literal_pool = false;
1749 /* We may need to substitute the literal pool base register into the address
1750 below. However, at this point we do not know which register is going to
1751 be used as base, so we substitute the arg pointer register. This is going
1752 to be treated as holding a pointer below -- it shouldn't be used for any
1753 other purpose. */
1754 rtx fake_pool_base = gen_rtx_REG (Pmode, ARG_POINTER_REGNUM);
1756 /* Decompose address into base + index + displacement. */
1758 if (GET_CODE (addr) == REG || GET_CODE (addr) == UNSPEC)
1759 base = addr;
1761 else if (GET_CODE (addr) == PLUS)
1763 rtx op0 = XEXP (addr, 0);
1764 rtx op1 = XEXP (addr, 1);
1765 enum rtx_code code0 = GET_CODE (op0);
1766 enum rtx_code code1 = GET_CODE (op1);
1768 if (code0 == REG || code0 == UNSPEC)
1770 if (code1 == REG || code1 == UNSPEC)
1772 indx = op0; /* index + base */
1773 base = op1;
1776 else
1778 base = op0; /* base + displacement */
1779 disp = op1;
1783 else if (code0 == PLUS)
1785 indx = XEXP (op0, 0); /* index + base + disp */
1786 base = XEXP (op0, 1);
1787 disp = op1;
1790 else
1792 return false;
1796 else
1797 disp = addr; /* displacement */
1799 /* Extract integer part of displacement. */
1800 orig_disp = disp;
1801 if (disp)
1803 if (GET_CODE (disp) == CONST_INT)
1805 offset = INTVAL (disp);
1806 disp = NULL_RTX;
1808 else if (GET_CODE (disp) == CONST
1809 && GET_CODE (XEXP (disp, 0)) == PLUS
1810 && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT)
1812 offset = INTVAL (XEXP (XEXP (disp, 0), 1));
1813 disp = XEXP (XEXP (disp, 0), 0);
1817 /* Strip off CONST here to avoid special case tests later. */
1818 if (disp && GET_CODE (disp) == CONST)
1819 disp = XEXP (disp, 0);
1821 /* We can convert literal pool addresses to
1822 displacements by basing them off the base register. */
1823 if (disp && GET_CODE (disp) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (disp))
1825 /* Either base or index must be free to hold the base register. */
1826 if (!base)
1827 base = fake_pool_base, literal_pool = true;
1828 else if (!indx)
1829 indx = fake_pool_base, literal_pool = true;
1830 else
1831 return false;
1833 /* Mark up the displacement. */
1834 disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp),
1835 UNSPEC_LTREL_OFFSET);
1838 /* Validate base register. */
1839 if (base)
1841 if (GET_CODE (base) == UNSPEC)
1842 switch (XINT (base, 1))
1844 case UNSPEC_LTREF:
1845 if (!disp)
1846 disp = gen_rtx_UNSPEC (Pmode,
1847 gen_rtvec (1, XVECEXP (base, 0, 0)),
1848 UNSPEC_LTREL_OFFSET);
1849 else
1850 return false;
1852 base = XVECEXP (base, 0, 1);
1853 break;
1855 case UNSPEC_LTREL_BASE:
1856 if (XVECLEN (base, 0) == 1)
1857 base = fake_pool_base, literal_pool = true;
1858 else
1859 base = XVECEXP (base, 0, 1);
1860 break;
1862 default:
1863 return false;
1866 if (!REG_P (base)
1867 || (GET_MODE (base) != SImode
1868 && GET_MODE (base) != Pmode))
1869 return false;
1871 if (REGNO (base) == STACK_POINTER_REGNUM
1872 || REGNO (base) == FRAME_POINTER_REGNUM
1873 || ((reload_completed || reload_in_progress)
1874 && frame_pointer_needed
1875 && REGNO (base) == HARD_FRAME_POINTER_REGNUM)
1876 || REGNO (base) == ARG_POINTER_REGNUM
1877 || (flag_pic
1878 && REGNO (base) == PIC_OFFSET_TABLE_REGNUM))
1879 pointer = base_ptr = true;
1881 if ((reload_completed || reload_in_progress)
1882 && base == cfun->machine->base_reg)
1883 pointer = base_ptr = literal_pool = true;
1886 /* Validate index register. */
1887 if (indx)
1889 if (GET_CODE (indx) == UNSPEC)
1890 switch (XINT (indx, 1))
1892 case UNSPEC_LTREF:
1893 if (!disp)
1894 disp = gen_rtx_UNSPEC (Pmode,
1895 gen_rtvec (1, XVECEXP (indx, 0, 0)),
1896 UNSPEC_LTREL_OFFSET);
1897 else
1898 return false;
1900 indx = XVECEXP (indx, 0, 1);
1901 break;
1903 case UNSPEC_LTREL_BASE:
1904 if (XVECLEN (indx, 0) == 1)
1905 indx = fake_pool_base, literal_pool = true;
1906 else
1907 indx = XVECEXP (indx, 0, 1);
1908 break;
1910 default:
1911 return false;
1914 if (!REG_P (indx)
1915 || (GET_MODE (indx) != SImode
1916 && GET_MODE (indx) != Pmode))
1917 return false;
1919 if (REGNO (indx) == STACK_POINTER_REGNUM
1920 || REGNO (indx) == FRAME_POINTER_REGNUM
1921 || ((reload_completed || reload_in_progress)
1922 && frame_pointer_needed
1923 && REGNO (indx) == HARD_FRAME_POINTER_REGNUM)
1924 || REGNO (indx) == ARG_POINTER_REGNUM
1925 || (flag_pic
1926 && REGNO (indx) == PIC_OFFSET_TABLE_REGNUM))
1927 pointer = indx_ptr = true;
1929 if ((reload_completed || reload_in_progress)
1930 && indx == cfun->machine->base_reg)
1931 pointer = indx_ptr = literal_pool = true;
1934 /* Prefer to use pointer as base, not index. */
1935 if (base && indx && !base_ptr
1936 && (indx_ptr || (!REG_POINTER (base) && REG_POINTER (indx))))
1938 rtx tmp = base;
1939 base = indx;
1940 indx = tmp;
1943 /* Validate displacement. */
1944 if (!disp)
1946 /* If virtual registers are involved, the displacement will change later
1947 anyway as the virtual registers get eliminated. This could make a
1948 valid displacement invalid, but it is more likely to make an invalid
1949 displacement valid, because we sometimes access the register save area
1950 via negative offsets to one of those registers.
1951 Thus we don't check the displacement for validity here. If after
1952 elimination the displacement turns out to be invalid after all,
1953 this is fixed up by reload in any case. */
1954 if (base != arg_pointer_rtx
1955 && indx != arg_pointer_rtx
1956 && base != return_address_pointer_rtx
1957 && indx != return_address_pointer_rtx
1958 && base != frame_pointer_rtx
1959 && indx != frame_pointer_rtx
1960 && base != virtual_stack_vars_rtx
1961 && indx != virtual_stack_vars_rtx)
1962 if (!DISP_IN_RANGE (offset))
1963 return false;
1965 else
1967 /* All the special cases are pointers. */
1968 pointer = true;
1970 /* In the small-PIC case, the linker converts @GOT
1971 and @GOTNTPOFF offsets to possible displacements. */
1972 if (GET_CODE (disp) == UNSPEC
1973 && (XINT (disp, 1) == UNSPEC_GOT
1974 || XINT (disp, 1) == UNSPEC_GOTNTPOFF)
1975 && flag_pic == 1)
1980 /* Accept pool label offsets. */
1981 else if (GET_CODE (disp) == UNSPEC
1982 && XINT (disp, 1) == UNSPEC_POOL_OFFSET)
1985 /* Accept literal pool references. */
1986 else if (GET_CODE (disp) == UNSPEC
1987 && XINT (disp, 1) == UNSPEC_LTREL_OFFSET)
1989 orig_disp = gen_rtx_CONST (Pmode, disp);
1990 if (offset)
1992 /* If we have an offset, make sure it does not
1993 exceed the size of the constant pool entry. */
1994 rtx sym = XVECEXP (disp, 0, 0);
1995 if (offset >= GET_MODE_SIZE (get_pool_mode (sym)))
1996 return false;
1998 orig_disp = plus_constant (orig_disp, offset);
2002 else
2003 return false;
2006 if (!base && !indx)
2007 pointer = true;
2009 if (out)
2011 out->base = base;
2012 out->indx = indx;
2013 out->disp = orig_disp;
2014 out->pointer = pointer;
2015 out->literal_pool = literal_pool;
2018 return true;
2021 /* Decompose a RTL expression OP for a shift count into its components,
2022 and return the base register in BASE and the offset in OFFSET.
2024 Return true if OP is a valid shift count, false if not. */
2026 bool
2027 s390_decompose_shift_count (rtx op, rtx *base, HOST_WIDE_INT *offset)
2029 HOST_WIDE_INT off = 0;
2031 /* We can have an integer constant, an address register,
2032 or a sum of the two. */
2033 if (GET_CODE (op) == CONST_INT)
2035 off = INTVAL (op);
2036 op = NULL_RTX;
2038 if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
2040 off = INTVAL (XEXP (op, 1));
2041 op = XEXP (op, 0);
2043 while (op && GET_CODE (op) == SUBREG)
2044 op = SUBREG_REG (op);
2046 if (op && GET_CODE (op) != REG)
2047 return false;
2049 if (offset)
2050 *offset = off;
2051 if (base)
2052 *base = op;
2054 return true;
2058 /* Return true if CODE is a valid address without index. */
2060 bool
2061 s390_legitimate_address_without_index_p (rtx op)
2063 struct s390_address addr;
2065 if (!s390_decompose_address (XEXP (op, 0), &addr))
2066 return false;
2067 if (addr.indx)
2068 return false;
2070 return true;
2074 /* Return true if ADDR is of kind symbol_ref or symbol_ref + const_int
2075 and return these parts in SYMREF and ADDEND. You can pass NULL in
2076 SYMREF and/or ADDEND if you are not interested in these values. */
2078 static bool
2079 s390_symref_operand_p (rtx addr, rtx *symref, HOST_WIDE_INT *addend)
2081 HOST_WIDE_INT tmpaddend = 0;
2083 if (GET_CODE (addr) == CONST)
2084 addr = XEXP (addr, 0);
2086 if (GET_CODE (addr) == PLUS)
2088 if (GET_CODE (XEXP (addr, 0)) == SYMBOL_REF
2089 && CONST_INT_P (XEXP (addr, 1)))
2091 tmpaddend = INTVAL (XEXP (addr, 1));
2092 addr = XEXP (addr, 0);
2094 else
2095 return false;
2097 else
2098 if (GET_CODE (addr) != SYMBOL_REF)
2099 return false;
2101 if (symref)
2102 *symref = addr;
2103 if (addend)
2104 *addend = tmpaddend;
2106 return true;
2110 /* Return true if the address in OP is valid for constraint letter C
2111 if wrapped in a MEM rtx. Set LIT_POOL_OK to true if it literal
2112 pool MEMs should be accepted. Only the Q, R, S, T constraint
2113 letters are allowed for C. */
2115 static int
2116 s390_check_qrst_address (char c, rtx op, bool lit_pool_ok)
2118 struct s390_address addr;
2119 bool decomposed = false;
2121 /* This check makes sure that no symbolic address (except literal
2122 pool references) are accepted by the R or T constraints. */
2123 if (s390_symref_operand_p (op, NULL, NULL))
2125 if (!lit_pool_ok)
2126 return 0;
2127 if (!s390_decompose_address (op, &addr))
2128 return 0;
2129 if (!addr.literal_pool)
2130 return 0;
2131 decomposed = true;
2134 switch (c)
2136 case 'Q': /* no index short displacement */
2137 if (!decomposed && !s390_decompose_address (op, &addr))
2138 return 0;
2139 if (addr.indx)
2140 return 0;
2141 if (!s390_short_displacement (addr.disp))
2142 return 0;
2143 break;
2145 case 'R': /* with index short displacement */
2146 if (TARGET_LONG_DISPLACEMENT)
2148 if (!decomposed && !s390_decompose_address (op, &addr))
2149 return 0;
2150 if (!s390_short_displacement (addr.disp))
2151 return 0;
2153 /* Any invalid address here will be fixed up by reload,
2154 so accept it for the most generic constraint. */
2155 break;
2157 case 'S': /* no index long displacement */
2158 if (!TARGET_LONG_DISPLACEMENT)
2159 return 0;
2160 if (!decomposed && !s390_decompose_address (op, &addr))
2161 return 0;
2162 if (addr.indx)
2163 return 0;
2164 if (s390_short_displacement (addr.disp))
2165 return 0;
2166 break;
2168 case 'T': /* with index long displacement */
2169 if (!TARGET_LONG_DISPLACEMENT)
2170 return 0;
2171 /* Any invalid address here will be fixed up by reload,
2172 so accept it for the most generic constraint. */
2173 if ((decomposed || s390_decompose_address (op, &addr))
2174 && s390_short_displacement (addr.disp))
2175 return 0;
2176 break;
2177 default:
2178 return 0;
2180 return 1;
2184 /* Evaluates constraint strings described by the regular expression
2185 ([A|B|Z](Q|R|S|T))|U|W|Y and returns 1 if OP is a valid operand for
2186 the constraint given in STR, or 0 else. */
2189 s390_mem_constraint (const char *str, rtx op)
2191 char c = str[0];
2193 switch (c)
2195 case 'A':
2196 /* Check for offsettable variants of memory constraints. */
2197 if (!MEM_P (op) || MEM_VOLATILE_P (op))
2198 return 0;
2199 if ((reload_completed || reload_in_progress)
2200 ? !offsettable_memref_p (op) : !offsettable_nonstrict_memref_p (op))
2201 return 0;
2202 return s390_check_qrst_address (str[1], XEXP (op, 0), true);
2203 case 'B':
2204 /* Check for non-literal-pool variants of memory constraints. */
2205 if (!MEM_P (op))
2206 return 0;
2207 return s390_check_qrst_address (str[1], XEXP (op, 0), false);
2208 case 'Q':
2209 case 'R':
2210 case 'S':
2211 case 'T':
2212 if (GET_CODE (op) != MEM)
2213 return 0;
2214 return s390_check_qrst_address (c, XEXP (op, 0), true);
2215 case 'U':
2216 return (s390_check_qrst_address ('Q', op, true)
2217 || s390_check_qrst_address ('R', op, true));
2218 case 'W':
2219 return (s390_check_qrst_address ('S', op, true)
2220 || s390_check_qrst_address ('T', op, true));
2221 case 'Y':
2222 /* Simply check for the basic form of a shift count. Reload will
2223 take care of making sure we have a proper base register. */
2224 if (!s390_decompose_shift_count (op, NULL, NULL))
2225 return 0;
2226 break;
2227 case 'Z':
2228 return s390_check_qrst_address (str[1], op, true);
2229 default:
2230 return 0;
2232 return 1;
2236 /* Evaluates constraint strings starting with letter O. Input
2237 parameter C is the second letter following the "O" in the constraint
2238 string. Returns 1 if VALUE meets the respective constraint and 0
2239 otherwise. */
2242 s390_O_constraint_str (const char c, HOST_WIDE_INT value)
2244 if (!TARGET_EXTIMM)
2245 return 0;
2247 switch (c)
2249 case 's':
2250 return trunc_int_for_mode (value, SImode) == value;
2252 case 'p':
2253 return value == 0
2254 || s390_single_part (GEN_INT (value), DImode, SImode, 0) == 1;
2256 case 'n':
2257 return s390_single_part (GEN_INT (value - 1), DImode, SImode, -1) == 1;
2259 default:
2260 gcc_unreachable ();
2265 /* Evaluates constraint strings starting with letter N. Parameter STR
2266 contains the letters following letter "N" in the constraint string.
2267 Returns true if VALUE matches the constraint. */
2270 s390_N_constraint_str (const char *str, HOST_WIDE_INT value)
2272 enum machine_mode mode, part_mode;
2273 int def;
2274 int part, part_goal;
2277 if (str[0] == 'x')
2278 part_goal = -1;
2279 else
2280 part_goal = str[0] - '0';
2282 switch (str[1])
2284 case 'Q':
2285 part_mode = QImode;
2286 break;
2287 case 'H':
2288 part_mode = HImode;
2289 break;
2290 case 'S':
2291 part_mode = SImode;
2292 break;
2293 default:
2294 return 0;
2297 switch (str[2])
2299 case 'H':
2300 mode = HImode;
2301 break;
2302 case 'S':
2303 mode = SImode;
2304 break;
2305 case 'D':
2306 mode = DImode;
2307 break;
2308 default:
2309 return 0;
2312 switch (str[3])
2314 case '0':
2315 def = 0;
2316 break;
2317 case 'F':
2318 def = -1;
2319 break;
2320 default:
2321 return 0;
2324 if (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (part_mode))
2325 return 0;
2327 part = s390_single_part (GEN_INT (value), mode, part_mode, def);
2328 if (part < 0)
2329 return 0;
2330 if (part_goal != -1 && part_goal != part)
2331 return 0;
2333 return 1;
2337 /* Returns true if the input parameter VALUE is a float zero. */
2340 s390_float_const_zero_p (rtx value)
2342 return (GET_MODE_CLASS (GET_MODE (value)) == MODE_FLOAT
2343 && value == CONST0_RTX (GET_MODE (value)));
2347 /* Compute a (partial) cost for rtx X. Return true if the complete
2348 cost has been computed, and false if subexpressions should be
2349 scanned. In either case, *TOTAL contains the cost result.
2350 CODE contains GET_CODE (x), OUTER_CODE contains the code
2351 of the superexpression of x. */
2353 static bool
2354 s390_rtx_costs (rtx x, int code, int outer_code, int *total,
2355 bool speed ATTRIBUTE_UNUSED)
2357 switch (code)
2359 case CONST:
2360 case CONST_INT:
2361 case LABEL_REF:
2362 case SYMBOL_REF:
2363 case CONST_DOUBLE:
2364 case MEM:
2365 *total = 0;
2366 return true;
2368 case ASHIFT:
2369 case ASHIFTRT:
2370 case LSHIFTRT:
2371 case ROTATE:
2372 case ROTATERT:
2373 case AND:
2374 case IOR:
2375 case XOR:
2376 case NEG:
2377 case NOT:
2378 *total = COSTS_N_INSNS (1);
2379 return false;
2381 case PLUS:
2382 case MINUS:
2383 /* Check for multiply and add. */
2384 if ((GET_MODE (x) == DFmode || GET_MODE (x) == SFmode)
2385 && GET_CODE (XEXP (x, 0)) == MULT
2386 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD)
2388 /* This is the multiply and add case. */
2389 if (GET_MODE (x) == DFmode)
2390 *total = s390_cost->madbr;
2391 else
2392 *total = s390_cost->maebr;
2393 *total += (rtx_cost (XEXP (XEXP (x, 0), 0), MULT, speed)
2394 + rtx_cost (XEXP (XEXP (x, 0), 1), MULT, speed)
2395 + rtx_cost (XEXP (x, 1), (enum rtx_code) code, speed));
2396 return true; /* Do not do an additional recursive descent. */
2398 *total = COSTS_N_INSNS (1);
2399 return false;
2401 case MULT:
2402 switch (GET_MODE (x))
2404 case SImode:
2406 rtx left = XEXP (x, 0);
2407 rtx right = XEXP (x, 1);
2408 if (GET_CODE (right) == CONST_INT
2409 && CONST_OK_FOR_K (INTVAL (right)))
2410 *total = s390_cost->mhi;
2411 else if (GET_CODE (left) == SIGN_EXTEND)
2412 *total = s390_cost->mh;
2413 else
2414 *total = s390_cost->ms; /* msr, ms, msy */
2415 break;
2417 case DImode:
2419 rtx left = XEXP (x, 0);
2420 rtx right = XEXP (x, 1);
2421 if (TARGET_ZARCH)
2423 if (GET_CODE (right) == CONST_INT
2424 && CONST_OK_FOR_K (INTVAL (right)))
2425 *total = s390_cost->mghi;
2426 else if (GET_CODE (left) == SIGN_EXTEND)
2427 *total = s390_cost->msgf;
2428 else
2429 *total = s390_cost->msg; /* msgr, msg */
2431 else /* TARGET_31BIT */
2433 if (GET_CODE (left) == SIGN_EXTEND
2434 && GET_CODE (right) == SIGN_EXTEND)
2435 /* mulsidi case: mr, m */
2436 *total = s390_cost->m;
2437 else if (GET_CODE (left) == ZERO_EXTEND
2438 && GET_CODE (right) == ZERO_EXTEND
2439 && TARGET_CPU_ZARCH)
2440 /* umulsidi case: ml, mlr */
2441 *total = s390_cost->ml;
2442 else
2443 /* Complex calculation is required. */
2444 *total = COSTS_N_INSNS (40);
2446 break;
2448 case SFmode:
2449 case DFmode:
2450 *total = s390_cost->mult_df;
2451 break;
2452 case TFmode:
2453 *total = s390_cost->mxbr;
2454 break;
2455 default:
2456 return false;
2458 return false;
2460 case UDIV:
2461 case UMOD:
2462 if (GET_MODE (x) == TImode) /* 128 bit division */
2463 *total = s390_cost->dlgr;
2464 else if (GET_MODE (x) == DImode)
2466 rtx right = XEXP (x, 1);
2467 if (GET_CODE (right) == ZERO_EXTEND) /* 64 by 32 bit division */
2468 *total = s390_cost->dlr;
2469 else /* 64 by 64 bit division */
2470 *total = s390_cost->dlgr;
2472 else if (GET_MODE (x) == SImode) /* 32 bit division */
2473 *total = s390_cost->dlr;
2474 return false;
2476 case DIV:
2477 case MOD:
2478 if (GET_MODE (x) == DImode)
2480 rtx right = XEXP (x, 1);
2481 if (GET_CODE (right) == ZERO_EXTEND) /* 64 by 32 bit division */
2482 if (TARGET_ZARCH)
2483 *total = s390_cost->dsgfr;
2484 else
2485 *total = s390_cost->dr;
2486 else /* 64 by 64 bit division */
2487 *total = s390_cost->dsgr;
2489 else if (GET_MODE (x) == SImode) /* 32 bit division */
2490 *total = s390_cost->dlr;
2491 else if (GET_MODE (x) == SFmode)
2493 *total = s390_cost->debr;
2495 else if (GET_MODE (x) == DFmode)
2497 *total = s390_cost->ddbr;
2499 else if (GET_MODE (x) == TFmode)
2501 *total = s390_cost->dxbr;
2503 return false;
2505 case SQRT:
2506 if (GET_MODE (x) == SFmode)
2507 *total = s390_cost->sqebr;
2508 else if (GET_MODE (x) == DFmode)
2509 *total = s390_cost->sqdbr;
2510 else /* TFmode */
2511 *total = s390_cost->sqxbr;
2512 return false;
2514 case SIGN_EXTEND:
2515 case ZERO_EXTEND:
2516 if (outer_code == MULT || outer_code == DIV || outer_code == MOD
2517 || outer_code == PLUS || outer_code == MINUS
2518 || outer_code == COMPARE)
2519 *total = 0;
2520 return false;
2522 case COMPARE:
2523 *total = COSTS_N_INSNS (1);
2524 if (GET_CODE (XEXP (x, 0)) == AND
2525 && GET_CODE (XEXP (x, 1)) == CONST_INT
2526 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
2528 rtx op0 = XEXP (XEXP (x, 0), 0);
2529 rtx op1 = XEXP (XEXP (x, 0), 1);
2530 rtx op2 = XEXP (x, 1);
2532 if (memory_operand (op0, GET_MODE (op0))
2533 && s390_tm_ccmode (op1, op2, 0) != VOIDmode)
2534 return true;
2535 if (register_operand (op0, GET_MODE (op0))
2536 && s390_tm_ccmode (op1, op2, 1) != VOIDmode)
2537 return true;
2539 return false;
2541 default:
2542 return false;
2546 /* Return the cost of an address rtx ADDR. */
2548 static int
2549 s390_address_cost (rtx addr, bool speed ATTRIBUTE_UNUSED)
2551 struct s390_address ad;
2552 if (!s390_decompose_address (addr, &ad))
2553 return 1000;
2555 return ad.indx? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
2558 /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
2559 otherwise return 0. */
2562 tls_symbolic_operand (rtx op)
2564 if (GET_CODE (op) != SYMBOL_REF)
2565 return 0;
2566 return SYMBOL_REF_TLS_MODEL (op);
2569 /* Split DImode access register reference REG (on 64-bit) into its constituent
2570 low and high parts, and store them into LO and HI. Note that gen_lowpart/
2571 gen_highpart cannot be used as they assume all registers are word-sized,
2572 while our access registers have only half that size. */
2574 void
2575 s390_split_access_reg (rtx reg, rtx *lo, rtx *hi)
2577 gcc_assert (TARGET_64BIT);
2578 gcc_assert (ACCESS_REG_P (reg));
2579 gcc_assert (GET_MODE (reg) == DImode);
2580 gcc_assert (!(REGNO (reg) & 1));
2582 *lo = gen_rtx_REG (SImode, REGNO (reg) + 1);
2583 *hi = gen_rtx_REG (SImode, REGNO (reg));
2586 /* Return true if OP contains a symbol reference */
2588 bool
2589 symbolic_reference_mentioned_p (rtx op)
2591 const char *fmt;
2592 int i;
2594 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
2595 return 1;
2597 fmt = GET_RTX_FORMAT (GET_CODE (op));
2598 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
2600 if (fmt[i] == 'E')
2602 int j;
2604 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
2605 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
2606 return 1;
2609 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
2610 return 1;
2613 return 0;
2616 /* Return true if OP contains a reference to a thread-local symbol. */
2618 bool
2619 tls_symbolic_reference_mentioned_p (rtx op)
2621 const char *fmt;
2622 int i;
2624 if (GET_CODE (op) == SYMBOL_REF)
2625 return tls_symbolic_operand (op);
2627 fmt = GET_RTX_FORMAT (GET_CODE (op));
2628 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
2630 if (fmt[i] == 'E')
2632 int j;
2634 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
2635 if (tls_symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
2636 return true;
2639 else if (fmt[i] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op, i)))
2640 return true;
2643 return false;
2647 /* Return true if OP is a legitimate general operand when
2648 generating PIC code. It is given that flag_pic is on
2649 and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2652 legitimate_pic_operand_p (rtx op)
2654 /* Accept all non-symbolic constants. */
2655 if (!SYMBOLIC_CONST (op))
2656 return 1;
2658 /* Reject everything else; must be handled
2659 via emit_symbolic_move. */
2660 return 0;
2663 /* Returns true if the constant value OP is a legitimate general operand.
2664 It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2667 legitimate_constant_p (rtx op)
2669 /* Accept all non-symbolic constants. */
2670 if (!SYMBOLIC_CONST (op))
2671 return 1;
2673 /* Accept immediate LARL operands. */
2674 if (TARGET_CPU_ZARCH && larl_operand (op, VOIDmode))
2675 return 1;
2677 /* Thread-local symbols are never legal constants. This is
2678 so that emit_call knows that computing such addresses
2679 might require a function call. */
2680 if (TLS_SYMBOLIC_CONST (op))
2681 return 0;
2683 /* In the PIC case, symbolic constants must *not* be
2684 forced into the literal pool. We accept them here,
2685 so that they will be handled by emit_symbolic_move. */
2686 if (flag_pic)
2687 return 1;
2689 /* All remaining non-PIC symbolic constants are
2690 forced into the literal pool. */
2691 return 0;
2694 /* Determine if it's legal to put X into the constant pool. This
2695 is not possible if X contains the address of a symbol that is
2696 not constant (TLS) or not known at final link time (PIC). */
2698 static bool
2699 s390_cannot_force_const_mem (rtx x)
2701 switch (GET_CODE (x))
2703 case CONST_INT:
2704 case CONST_DOUBLE:
2705 /* Accept all non-symbolic constants. */
2706 return false;
2708 case LABEL_REF:
2709 /* Labels are OK iff we are non-PIC. */
2710 return flag_pic != 0;
2712 case SYMBOL_REF:
2713 /* 'Naked' TLS symbol references are never OK,
2714 non-TLS symbols are OK iff we are non-PIC. */
2715 if (tls_symbolic_operand (x))
2716 return true;
2717 else
2718 return flag_pic != 0;
2720 case CONST:
2721 return s390_cannot_force_const_mem (XEXP (x, 0));
2722 case PLUS:
2723 case MINUS:
2724 return s390_cannot_force_const_mem (XEXP (x, 0))
2725 || s390_cannot_force_const_mem (XEXP (x, 1));
2727 case UNSPEC:
2728 switch (XINT (x, 1))
2730 /* Only lt-relative or GOT-relative UNSPECs are OK. */
2731 case UNSPEC_LTREL_OFFSET:
2732 case UNSPEC_GOT:
2733 case UNSPEC_GOTOFF:
2734 case UNSPEC_PLTOFF:
2735 case UNSPEC_TLSGD:
2736 case UNSPEC_TLSLDM:
2737 case UNSPEC_NTPOFF:
2738 case UNSPEC_DTPOFF:
2739 case UNSPEC_GOTNTPOFF:
2740 case UNSPEC_INDNTPOFF:
2741 return false;
2743 /* If the literal pool shares the code section, be put
2744 execute template placeholders into the pool as well. */
2745 case UNSPEC_INSN:
2746 return TARGET_CPU_ZARCH;
2748 default:
2749 return true;
2751 break;
2753 default:
2754 gcc_unreachable ();
2758 /* Returns true if the constant value OP is a legitimate general
2759 operand during and after reload. The difference to
2760 legitimate_constant_p is that this function will not accept
2761 a constant that would need to be forced to the literal pool
2762 before it can be used as operand. */
2764 bool
2765 legitimate_reload_constant_p (rtx op)
2767 /* Accept la(y) operands. */
2768 if (GET_CODE (op) == CONST_INT
2769 && DISP_IN_RANGE (INTVAL (op)))
2770 return true;
2772 /* Accept l(g)hi/l(g)fi operands. */
2773 if (GET_CODE (op) == CONST_INT
2774 && (CONST_OK_FOR_K (INTVAL (op)) || CONST_OK_FOR_Os (INTVAL (op))))
2775 return true;
2777 /* Accept lliXX operands. */
2778 if (TARGET_ZARCH
2779 && GET_CODE (op) == CONST_INT
2780 && trunc_int_for_mode (INTVAL (op), word_mode) == INTVAL (op)
2781 && s390_single_part (op, word_mode, HImode, 0) >= 0)
2782 return true;
2784 if (TARGET_EXTIMM
2785 && GET_CODE (op) == CONST_INT
2786 && trunc_int_for_mode (INTVAL (op), word_mode) == INTVAL (op)
2787 && s390_single_part (op, word_mode, SImode, 0) >= 0)
2788 return true;
2790 /* Accept larl operands. */
2791 if (TARGET_CPU_ZARCH
2792 && larl_operand (op, VOIDmode))
2793 return true;
2795 /* Accept lzXX operands. */
2796 if (GET_CODE (op) == CONST_DOUBLE
2797 && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, 'G', "G"))
2798 return true;
2800 /* Accept double-word operands that can be split. */
2801 if (GET_CODE (op) == CONST_INT
2802 && trunc_int_for_mode (INTVAL (op), word_mode) != INTVAL (op))
2804 enum machine_mode dword_mode = word_mode == SImode ? DImode : TImode;
2805 rtx hi = operand_subword (op, 0, 0, dword_mode);
2806 rtx lo = operand_subword (op, 1, 0, dword_mode);
2807 return legitimate_reload_constant_p (hi)
2808 && legitimate_reload_constant_p (lo);
2811 /* Everything else cannot be handled without reload. */
2812 return false;
2815 /* Given an rtx OP being reloaded into a reg required to be in class RCLASS,
2816 return the class of reg to actually use. */
2818 enum reg_class
2819 s390_preferred_reload_class (rtx op, enum reg_class rclass)
2821 switch (GET_CODE (op))
2823 /* Constants we cannot reload must be forced into the
2824 literal pool. */
2826 case CONST_DOUBLE:
2827 case CONST_INT:
2828 if (legitimate_reload_constant_p (op))
2829 return rclass;
2830 else
2831 return NO_REGS;
2833 /* If a symbolic constant or a PLUS is reloaded,
2834 it is most likely being used as an address, so
2835 prefer ADDR_REGS. If 'class' is not a superset
2836 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
2837 case PLUS:
2838 case LABEL_REF:
2839 case SYMBOL_REF:
2840 case CONST:
2841 if (reg_class_subset_p (ADDR_REGS, rclass))
2842 return ADDR_REGS;
2843 else
2844 return NO_REGS;
2846 default:
2847 break;
2850 return rclass;
2853 /* Return true if ADDR is SYMBOL_REF + addend with addend being a
2854 multiple of ALIGNMENT and the SYMBOL_REF being naturally
2855 aligned. */
2857 bool
2858 s390_check_symref_alignment (rtx addr, HOST_WIDE_INT alignment)
2860 HOST_WIDE_INT addend;
2861 rtx symref;
2863 if (!s390_symref_operand_p (addr, &symref, &addend))
2864 return false;
2866 return (!SYMBOL_REF_NOT_NATURALLY_ALIGNED_P (symref)
2867 && !(addend & (alignment - 1)));
2870 /* ADDR is moved into REG using larl. If ADDR isn't a valid larl
2871 operand SCRATCH is used to reload the even part of the address and
2872 adding one. */
2874 void
2875 s390_reload_larl_operand (rtx reg, rtx addr, rtx scratch)
2877 HOST_WIDE_INT addend;
2878 rtx symref;
2880 if (!s390_symref_operand_p (addr, &symref, &addend))
2881 gcc_unreachable ();
2883 if (!(addend & 1))
2884 /* Easy case. The addend is even so larl will do fine. */
2885 emit_move_insn (reg, addr);
2886 else
2888 /* We can leave the scratch register untouched if the target
2889 register is a valid base register. */
2890 if (REGNO (reg) < FIRST_PSEUDO_REGISTER
2891 && REGNO_REG_CLASS (REGNO (reg)) == ADDR_REGS)
2892 scratch = reg;
2894 gcc_assert (REGNO (scratch) < FIRST_PSEUDO_REGISTER);
2895 gcc_assert (REGNO_REG_CLASS (REGNO (scratch)) == ADDR_REGS);
2897 if (addend != 1)
2898 emit_move_insn (scratch,
2899 gen_rtx_CONST (Pmode,
2900 gen_rtx_PLUS (Pmode, symref,
2901 GEN_INT (addend - 1))));
2902 else
2903 emit_move_insn (scratch, symref);
2905 /* Increment the address using la in order to avoid clobbering cc. */
2906 emit_move_insn (reg, gen_rtx_PLUS (Pmode, scratch, const1_rtx));
2910 /* Generate what is necessary to move between REG and MEM using
2911 SCRATCH. The direction is given by TOMEM. */
2913 void
2914 s390_reload_symref_address (rtx reg, rtx mem, rtx scratch, bool tomem)
2916 /* Reload might have pulled a constant out of the literal pool.
2917 Force it back in. */
2918 if (CONST_INT_P (mem) || GET_CODE (mem) == CONST_DOUBLE
2919 || GET_CODE (mem) == CONST)
2920 mem = force_const_mem (GET_MODE (reg), mem);
2922 gcc_assert (MEM_P (mem));
2924 /* For a load from memory we can leave the scratch register
2925 untouched if the target register is a valid base register. */
2926 if (!tomem
2927 && REGNO (reg) < FIRST_PSEUDO_REGISTER
2928 && REGNO_REG_CLASS (REGNO (reg)) == ADDR_REGS
2929 && GET_MODE (reg) == GET_MODE (scratch))
2930 scratch = reg;
2932 /* Load address into scratch register. Since we can't have a
2933 secondary reload for a secondary reload we have to cover the case
2934 where larl would need a secondary reload here as well. */
2935 s390_reload_larl_operand (scratch, XEXP (mem, 0), scratch);
2937 /* Now we can use a standard load/store to do the move. */
2938 if (tomem)
2939 emit_move_insn (replace_equiv_address (mem, scratch), reg);
2940 else
2941 emit_move_insn (reg, replace_equiv_address (mem, scratch));
2944 /* Inform reload about cases where moving X with a mode MODE to a register in
2945 RCLASS requires an extra scratch or immediate register. Return the class
2946 needed for the immediate register. */
2948 static enum reg_class
2949 s390_secondary_reload (bool in_p, rtx x, enum reg_class rclass,
2950 enum machine_mode mode, secondary_reload_info *sri)
2952 /* Intermediate register needed. */
2953 if (reg_classes_intersect_p (CC_REGS, rclass))
2954 return GENERAL_REGS;
2956 if (TARGET_Z10)
2958 /* On z10 several optimizer steps may generate larl operands with
2959 an odd addend. */
2960 if (in_p
2961 && s390_symref_operand_p (x, NULL, NULL)
2962 && mode == Pmode
2963 && !s390_check_symref_alignment (x, 2))
2964 sri->icode = ((mode == DImode) ? CODE_FOR_reloaddi_larl_odd_addend_z10
2965 : CODE_FOR_reloadsi_larl_odd_addend_z10);
2967 /* On z10 we need a scratch register when moving QI, TI or floating
2968 point mode values from or to a memory location with a SYMBOL_REF
2969 or if the symref addend of a SI or DI move is not aligned to the
2970 width of the access. */
2971 if (MEM_P (x)
2972 && s390_symref_operand_p (XEXP (x, 0), NULL, NULL)
2973 && (mode == QImode || mode == TImode || FLOAT_MODE_P (mode)
2974 || (!TARGET_ZARCH && mode == DImode)
2975 || ((mode == HImode || mode == SImode || mode == DImode)
2976 && (!s390_check_symref_alignment (XEXP (x, 0),
2977 GET_MODE_SIZE (mode))))))
2979 #define __SECONDARY_RELOAD_CASE(M,m) \
2980 case M##mode: \
2981 if (TARGET_64BIT) \
2982 sri->icode = in_p ? CODE_FOR_reload##m##di_toreg_z10 : \
2983 CODE_FOR_reload##m##di_tomem_z10; \
2984 else \
2985 sri->icode = in_p ? CODE_FOR_reload##m##si_toreg_z10 : \
2986 CODE_FOR_reload##m##si_tomem_z10; \
2987 break;
2989 switch (GET_MODE (x))
2991 __SECONDARY_RELOAD_CASE (QI, qi);
2992 __SECONDARY_RELOAD_CASE (HI, hi);
2993 __SECONDARY_RELOAD_CASE (SI, si);
2994 __SECONDARY_RELOAD_CASE (DI, di);
2995 __SECONDARY_RELOAD_CASE (TI, ti);
2996 __SECONDARY_RELOAD_CASE (SF, sf);
2997 __SECONDARY_RELOAD_CASE (DF, df);
2998 __SECONDARY_RELOAD_CASE (TF, tf);
2999 __SECONDARY_RELOAD_CASE (SD, sd);
3000 __SECONDARY_RELOAD_CASE (DD, dd);
3001 __SECONDARY_RELOAD_CASE (TD, td);
3003 default:
3004 gcc_unreachable ();
3006 #undef __SECONDARY_RELOAD_CASE
3010 /* We need a scratch register when loading a PLUS expression which
3011 is not a legitimate operand of the LOAD ADDRESS instruction. */
3012 if (in_p && s390_plus_operand (x, mode))
3013 sri->icode = (TARGET_64BIT ?
3014 CODE_FOR_reloaddi_plus : CODE_FOR_reloadsi_plus);
3016 /* Performing a multiword move from or to memory we have to make sure the
3017 second chunk in memory is addressable without causing a displacement
3018 overflow. If that would be the case we calculate the address in
3019 a scratch register. */
3020 if (MEM_P (x)
3021 && GET_CODE (XEXP (x, 0)) == PLUS
3022 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
3023 && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (x, 0), 1))
3024 + GET_MODE_SIZE (mode) - 1))
3026 /* For GENERAL_REGS a displacement overflow is no problem if occurring
3027 in a s_operand address since we may fallback to lm/stm. So we only
3028 have to care about overflows in the b+i+d case. */
3029 if ((reg_classes_intersect_p (GENERAL_REGS, rclass)
3030 && s390_class_max_nregs (GENERAL_REGS, mode) > 1
3031 && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS)
3032 /* For FP_REGS no lm/stm is available so this check is triggered
3033 for displacement overflows in b+i+d and b+d like addresses. */
3034 || (reg_classes_intersect_p (FP_REGS, rclass)
3035 && s390_class_max_nregs (FP_REGS, mode) > 1))
3037 if (in_p)
3038 sri->icode = (TARGET_64BIT ?
3039 CODE_FOR_reloaddi_nonoffmem_in :
3040 CODE_FOR_reloadsi_nonoffmem_in);
3041 else
3042 sri->icode = (TARGET_64BIT ?
3043 CODE_FOR_reloaddi_nonoffmem_out :
3044 CODE_FOR_reloadsi_nonoffmem_out);
3048 /* A scratch address register is needed when a symbolic constant is
3049 copied to r0 compiling with -fPIC. In other cases the target
3050 register might be used as temporary (see legitimize_pic_address). */
3051 if (in_p && SYMBOLIC_CONST (x) && flag_pic == 2 && rclass != ADDR_REGS)
3052 sri->icode = (TARGET_64BIT ?
3053 CODE_FOR_reloaddi_PIC_addr :
3054 CODE_FOR_reloadsi_PIC_addr);
3056 /* Either scratch or no register needed. */
3057 return NO_REGS;
3060 /* Generate code to load SRC, which is PLUS that is not a
3061 legitimate operand for the LA instruction, into TARGET.
3062 SCRATCH may be used as scratch register. */
3064 void
3065 s390_expand_plus_operand (rtx target, rtx src,
3066 rtx scratch)
3068 rtx sum1, sum2;
3069 struct s390_address ad;
3071 /* src must be a PLUS; get its two operands. */
3072 gcc_assert (GET_CODE (src) == PLUS);
3073 gcc_assert (GET_MODE (src) == Pmode);
3075 /* Check if any of the two operands is already scheduled
3076 for replacement by reload. This can happen e.g. when
3077 float registers occur in an address. */
3078 sum1 = find_replacement (&XEXP (src, 0));
3079 sum2 = find_replacement (&XEXP (src, 1));
3080 src = gen_rtx_PLUS (Pmode, sum1, sum2);
3082 /* If the address is already strictly valid, there's nothing to do. */
3083 if (!s390_decompose_address (src, &ad)
3084 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
3085 || (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx))))
3087 /* Otherwise, one of the operands cannot be an address register;
3088 we reload its value into the scratch register. */
3089 if (true_regnum (sum1) < 1 || true_regnum (sum1) > 15)
3091 emit_move_insn (scratch, sum1);
3092 sum1 = scratch;
3094 if (true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
3096 emit_move_insn (scratch, sum2);
3097 sum2 = scratch;
3100 /* According to the way these invalid addresses are generated
3101 in reload.c, it should never happen (at least on s390) that
3102 *neither* of the PLUS components, after find_replacements
3103 was applied, is an address register. */
3104 if (sum1 == scratch && sum2 == scratch)
3106 debug_rtx (src);
3107 gcc_unreachable ();
3110 src = gen_rtx_PLUS (Pmode, sum1, sum2);
3113 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
3114 is only ever performed on addresses, so we can mark the
3115 sum as legitimate for LA in any case. */
3116 s390_load_address (target, src);
3120 /* Return true if ADDR is a valid memory address.
3121 STRICT specifies whether strict register checking applies. */
3123 static bool
3124 s390_legitimate_address_p (enum machine_mode mode, rtx addr, bool strict)
3126 struct s390_address ad;
3128 if (TARGET_Z10
3129 && larl_operand (addr, VOIDmode)
3130 && (mode == VOIDmode
3131 || s390_check_symref_alignment (addr, GET_MODE_SIZE (mode))))
3132 return true;
3134 if (!s390_decompose_address (addr, &ad))
3135 return false;
3137 if (strict)
3139 if (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
3140 return false;
3142 if (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx)))
3143 return false;
3145 else
3147 if (ad.base
3148 && !(REGNO (ad.base) >= FIRST_PSEUDO_REGISTER
3149 || REGNO_REG_CLASS (REGNO (ad.base)) == ADDR_REGS))
3150 return false;
3152 if (ad.indx
3153 && !(REGNO (ad.indx) >= FIRST_PSEUDO_REGISTER
3154 || REGNO_REG_CLASS (REGNO (ad.indx)) == ADDR_REGS))
3155 return false;
3157 return true;
3160 /* Return true if OP is a valid operand for the LA instruction.
3161 In 31-bit, we need to prove that the result is used as an
3162 address, as LA performs only a 31-bit addition. */
3164 bool
3165 legitimate_la_operand_p (rtx op)
3167 struct s390_address addr;
3168 if (!s390_decompose_address (op, &addr))
3169 return false;
3171 return (TARGET_64BIT || addr.pointer);
3174 /* Return true if it is valid *and* preferable to use LA to
3175 compute the sum of OP1 and OP2. */
3177 bool
3178 preferred_la_operand_p (rtx op1, rtx op2)
3180 struct s390_address addr;
3182 if (op2 != const0_rtx)
3183 op1 = gen_rtx_PLUS (Pmode, op1, op2);
3185 if (!s390_decompose_address (op1, &addr))
3186 return false;
3187 if (addr.base && !REGNO_OK_FOR_BASE_P (REGNO (addr.base)))
3188 return false;
3189 if (addr.indx && !REGNO_OK_FOR_INDEX_P (REGNO (addr.indx)))
3190 return false;
3192 if (!TARGET_64BIT && !addr.pointer)
3193 return false;
3195 if (addr.pointer)
3196 return true;
3198 if ((addr.base && REG_P (addr.base) && REG_POINTER (addr.base))
3199 || (addr.indx && REG_P (addr.indx) && REG_POINTER (addr.indx)))
3200 return true;
3202 return false;
3205 /* Emit a forced load-address operation to load SRC into DST.
3206 This will use the LOAD ADDRESS instruction even in situations
3207 where legitimate_la_operand_p (SRC) returns false. */
3209 void
3210 s390_load_address (rtx dst, rtx src)
3212 if (TARGET_64BIT)
3213 emit_move_insn (dst, src);
3214 else
3215 emit_insn (gen_force_la_31 (dst, src));
3218 /* Return a legitimate reference for ORIG (an address) using the
3219 register REG. If REG is 0, a new pseudo is generated.
3221 There are two types of references that must be handled:
3223 1. Global data references must load the address from the GOT, via
3224 the PIC reg. An insn is emitted to do this load, and the reg is
3225 returned.
3227 2. Static data references, constant pool addresses, and code labels
3228 compute the address as an offset from the GOT, whose base is in
3229 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
3230 differentiate them from global data objects. The returned
3231 address is the PIC reg + an unspec constant.
3233 TARGET_LEGITIMIZE_ADDRESS_P rejects symbolic references unless the PIC
3234 reg also appears in the address. */
3237 legitimize_pic_address (rtx orig, rtx reg)
3239 rtx addr = orig;
3240 rtx new_rtx = orig;
3241 rtx base;
3243 gcc_assert (!TLS_SYMBOLIC_CONST (addr));
3245 if (GET_CODE (addr) == LABEL_REF
3246 || (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (addr)))
3248 /* This is a local symbol. */
3249 if (TARGET_CPU_ZARCH && larl_operand (addr, VOIDmode))
3251 /* Access local symbols PC-relative via LARL.
3252 This is the same as in the non-PIC case, so it is
3253 handled automatically ... */
3255 else
3257 /* Access local symbols relative to the GOT. */
3259 rtx temp = reg? reg : gen_reg_rtx (Pmode);
3261 if (reload_in_progress || reload_completed)
3262 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
3264 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
3265 addr = gen_rtx_CONST (Pmode, addr);
3266 addr = force_const_mem (Pmode, addr);
3267 emit_move_insn (temp, addr);
3269 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
3270 if (reg != 0)
3272 s390_load_address (reg, new_rtx);
3273 new_rtx = reg;
3277 else if (GET_CODE (addr) == SYMBOL_REF)
3279 if (reg == 0)
3280 reg = gen_reg_rtx (Pmode);
3282 if (flag_pic == 1)
3284 /* Assume GOT offset < 4k. This is handled the same way
3285 in both 31- and 64-bit code (@GOT). */
3287 if (reload_in_progress || reload_completed)
3288 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
3290 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
3291 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
3292 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
3293 new_rtx = gen_const_mem (Pmode, new_rtx);
3294 emit_move_insn (reg, new_rtx);
3295 new_rtx = reg;
3297 else if (TARGET_CPU_ZARCH)
3299 /* If the GOT offset might be >= 4k, we determine the position
3300 of the GOT entry via a PC-relative LARL (@GOTENT). */
3302 rtx temp = reg ? reg : gen_reg_rtx (Pmode);
3304 gcc_assert (REGNO (temp) >= FIRST_PSEUDO_REGISTER
3305 || REGNO_REG_CLASS (REGNO (temp)) == ADDR_REGS);
3307 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTENT);
3308 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
3309 emit_move_insn (temp, new_rtx);
3311 new_rtx = gen_const_mem (Pmode, temp);
3312 emit_move_insn (reg, new_rtx);
3313 new_rtx = reg;
3315 else
3317 /* If the GOT offset might be >= 4k, we have to load it
3318 from the literal pool (@GOT). */
3320 rtx temp = reg ? reg : gen_reg_rtx (Pmode);
3322 gcc_assert (REGNO (temp) >= FIRST_PSEUDO_REGISTER
3323 || REGNO_REG_CLASS (REGNO (temp)) == ADDR_REGS);
3325 if (reload_in_progress || reload_completed)
3326 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
3328 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
3329 addr = gen_rtx_CONST (Pmode, addr);
3330 addr = force_const_mem (Pmode, addr);
3331 emit_move_insn (temp, addr);
3333 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
3334 new_rtx = gen_const_mem (Pmode, new_rtx);
3335 emit_move_insn (reg, new_rtx);
3336 new_rtx = reg;
3339 else
3341 if (GET_CODE (addr) == CONST)
3343 addr = XEXP (addr, 0);
3344 if (GET_CODE (addr) == UNSPEC)
3346 gcc_assert (XVECLEN (addr, 0) == 1);
3347 switch (XINT (addr, 1))
3349 /* If someone moved a GOT-relative UNSPEC
3350 out of the literal pool, force them back in. */
3351 case UNSPEC_GOTOFF:
3352 case UNSPEC_PLTOFF:
3353 new_rtx = force_const_mem (Pmode, orig);
3354 break;
3356 /* @GOT is OK as is if small. */
3357 case UNSPEC_GOT:
3358 if (flag_pic == 2)
3359 new_rtx = force_const_mem (Pmode, orig);
3360 break;
3362 /* @GOTENT is OK as is. */
3363 case UNSPEC_GOTENT:
3364 break;
3366 /* @PLT is OK as is on 64-bit, must be converted to
3367 GOT-relative @PLTOFF on 31-bit. */
3368 case UNSPEC_PLT:
3369 if (!TARGET_CPU_ZARCH)
3371 rtx temp = reg? reg : gen_reg_rtx (Pmode);
3373 if (reload_in_progress || reload_completed)
3374 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
3376 addr = XVECEXP (addr, 0, 0);
3377 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
3378 UNSPEC_PLTOFF);
3379 addr = gen_rtx_CONST (Pmode, addr);
3380 addr = force_const_mem (Pmode, addr);
3381 emit_move_insn (temp, addr);
3383 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
3384 if (reg != 0)
3386 s390_load_address (reg, new_rtx);
3387 new_rtx = reg;
3390 break;
3392 /* Everything else cannot happen. */
3393 default:
3394 gcc_unreachable ();
3397 else
3398 gcc_assert (GET_CODE (addr) == PLUS);
3400 if (GET_CODE (addr) == PLUS)
3402 rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
3404 gcc_assert (!TLS_SYMBOLIC_CONST (op0));
3405 gcc_assert (!TLS_SYMBOLIC_CONST (op1));
3407 /* Check first to see if this is a constant offset
3408 from a local symbol reference. */
3409 if ((GET_CODE (op0) == LABEL_REF
3410 || (GET_CODE (op0) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op0)))
3411 && GET_CODE (op1) == CONST_INT)
3413 if (TARGET_CPU_ZARCH
3414 && larl_operand (op0, VOIDmode)
3415 && INTVAL (op1) < (HOST_WIDE_INT)1 << 31
3416 && INTVAL (op1) >= -((HOST_WIDE_INT)1 << 31))
3418 if (INTVAL (op1) & 1)
3420 /* LARL can't handle odd offsets, so emit a
3421 pair of LARL and LA. */
3422 rtx temp = reg? reg : gen_reg_rtx (Pmode);
3424 if (!DISP_IN_RANGE (INTVAL (op1)))
3426 HOST_WIDE_INT even = INTVAL (op1) - 1;
3427 op0 = gen_rtx_PLUS (Pmode, op0, GEN_INT (even));
3428 op0 = gen_rtx_CONST (Pmode, op0);
3429 op1 = const1_rtx;
3432 emit_move_insn (temp, op0);
3433 new_rtx = gen_rtx_PLUS (Pmode, temp, op1);
3435 if (reg != 0)
3437 s390_load_address (reg, new_rtx);
3438 new_rtx = reg;
3441 else
3443 /* If the offset is even, we can just use LARL.
3444 This will happen automatically. */
3447 else
3449 /* Access local symbols relative to the GOT. */
3451 rtx temp = reg? reg : gen_reg_rtx (Pmode);
3453 if (reload_in_progress || reload_completed)
3454 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
3456 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
3457 UNSPEC_GOTOFF);
3458 addr = gen_rtx_PLUS (Pmode, addr, op1);
3459 addr = gen_rtx_CONST (Pmode, addr);
3460 addr = force_const_mem (Pmode, addr);
3461 emit_move_insn (temp, addr);
3463 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
3464 if (reg != 0)
3466 s390_load_address (reg, new_rtx);
3467 new_rtx = reg;
3472 /* Now, check whether it is a GOT relative symbol plus offset
3473 that was pulled out of the literal pool. Force it back in. */
3475 else if (GET_CODE (op0) == UNSPEC
3476 && GET_CODE (op1) == CONST_INT
3477 && XINT (op0, 1) == UNSPEC_GOTOFF)
3479 gcc_assert (XVECLEN (op0, 0) == 1);
3481 new_rtx = force_const_mem (Pmode, orig);
3484 /* Otherwise, compute the sum. */
3485 else
3487 base = legitimize_pic_address (XEXP (addr, 0), reg);
3488 new_rtx = legitimize_pic_address (XEXP (addr, 1),
3489 base == reg ? NULL_RTX : reg);
3490 if (GET_CODE (new_rtx) == CONST_INT)
3491 new_rtx = plus_constant (base, INTVAL (new_rtx));
3492 else
3494 if (GET_CODE (new_rtx) == PLUS && CONSTANT_P (XEXP (new_rtx, 1)))
3496 base = gen_rtx_PLUS (Pmode, base, XEXP (new_rtx, 0));
3497 new_rtx = XEXP (new_rtx, 1);
3499 new_rtx = gen_rtx_PLUS (Pmode, base, new_rtx);
3502 if (GET_CODE (new_rtx) == CONST)
3503 new_rtx = XEXP (new_rtx, 0);
3504 new_rtx = force_operand (new_rtx, 0);
3508 return new_rtx;
3511 /* Load the thread pointer into a register. */
3514 s390_get_thread_pointer (void)
3516 rtx tp = gen_reg_rtx (Pmode);
3518 emit_move_insn (tp, gen_rtx_REG (Pmode, TP_REGNUM));
3519 mark_reg_pointer (tp, BITS_PER_WORD);
3521 return tp;
3524 /* Emit a tls call insn. The call target is the SYMBOL_REF stored
3525 in s390_tls_symbol which always refers to __tls_get_offset.
3526 The returned offset is written to RESULT_REG and an USE rtx is
3527 generated for TLS_CALL. */
3529 static GTY(()) rtx s390_tls_symbol;
3531 static void
3532 s390_emit_tls_call_insn (rtx result_reg, rtx tls_call)
3534 rtx insn;
3536 gcc_assert (flag_pic);
3538 if (!s390_tls_symbol)
3539 s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset");
3541 insn = s390_emit_call (s390_tls_symbol, tls_call, result_reg,
3542 gen_rtx_REG (Pmode, RETURN_REGNUM));
3544 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), result_reg);
3545 RTL_CONST_CALL_P (insn) = 1;
3548 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
3549 this (thread-local) address. REG may be used as temporary. */
3551 static rtx
3552 legitimize_tls_address (rtx addr, rtx reg)
3554 rtx new_rtx, tls_call, temp, base, r2, insn;
3556 if (GET_CODE (addr) == SYMBOL_REF)
3557 switch (tls_symbolic_operand (addr))
3559 case TLS_MODEL_GLOBAL_DYNAMIC:
3560 start_sequence ();
3561 r2 = gen_rtx_REG (Pmode, 2);
3562 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLSGD);
3563 new_rtx = gen_rtx_CONST (Pmode, tls_call);
3564 new_rtx = force_const_mem (Pmode, new_rtx);
3565 emit_move_insn (r2, new_rtx);
3566 s390_emit_tls_call_insn (r2, tls_call);
3567 insn = get_insns ();
3568 end_sequence ();
3570 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
3571 temp = gen_reg_rtx (Pmode);
3572 emit_libcall_block (insn, temp, r2, new_rtx);
3574 new_rtx = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
3575 if (reg != 0)
3577 s390_load_address (reg, new_rtx);
3578 new_rtx = reg;
3580 break;
3582 case TLS_MODEL_LOCAL_DYNAMIC:
3583 start_sequence ();
3584 r2 = gen_rtx_REG (Pmode, 2);
3585 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM);
3586 new_rtx = gen_rtx_CONST (Pmode, tls_call);
3587 new_rtx = force_const_mem (Pmode, new_rtx);
3588 emit_move_insn (r2, new_rtx);
3589 s390_emit_tls_call_insn (r2, tls_call);
3590 insn = get_insns ();
3591 end_sequence ();
3593 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM_NTPOFF);
3594 temp = gen_reg_rtx (Pmode);
3595 emit_libcall_block (insn, temp, r2, new_rtx);
3597 new_rtx = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
3598 base = gen_reg_rtx (Pmode);
3599 s390_load_address (base, new_rtx);
3601 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_DTPOFF);
3602 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
3603 new_rtx = force_const_mem (Pmode, new_rtx);
3604 temp = gen_reg_rtx (Pmode);
3605 emit_move_insn (temp, new_rtx);
3607 new_rtx = gen_rtx_PLUS (Pmode, base, temp);
3608 if (reg != 0)
3610 s390_load_address (reg, new_rtx);
3611 new_rtx = reg;
3613 break;
3615 case TLS_MODEL_INITIAL_EXEC:
3616 if (flag_pic == 1)
3618 /* Assume GOT offset < 4k. This is handled the same way
3619 in both 31- and 64-bit code. */
3621 if (reload_in_progress || reload_completed)
3622 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
3624 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
3625 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
3626 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
3627 new_rtx = gen_const_mem (Pmode, new_rtx);
3628 temp = gen_reg_rtx (Pmode);
3629 emit_move_insn (temp, new_rtx);
3631 else if (TARGET_CPU_ZARCH)
3633 /* If the GOT offset might be >= 4k, we determine the position
3634 of the GOT entry via a PC-relative LARL. */
3636 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
3637 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
3638 temp = gen_reg_rtx (Pmode);
3639 emit_move_insn (temp, new_rtx);
3641 new_rtx = gen_const_mem (Pmode, temp);
3642 temp = gen_reg_rtx (Pmode);
3643 emit_move_insn (temp, new_rtx);
3645 else if (flag_pic)
3647 /* If the GOT offset might be >= 4k, we have to load it
3648 from the literal pool. */
3650 if (reload_in_progress || reload_completed)
3651 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
3653 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
3654 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
3655 new_rtx = force_const_mem (Pmode, new_rtx);
3656 temp = gen_reg_rtx (Pmode);
3657 emit_move_insn (temp, new_rtx);
3659 new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
3660 new_rtx = gen_const_mem (Pmode, new_rtx);
3662 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new_rtx, addr), UNSPEC_TLS_LOAD);
3663 temp = gen_reg_rtx (Pmode);
3664 emit_insn (gen_rtx_SET (Pmode, temp, new_rtx));
3666 else
3668 /* In position-dependent code, load the absolute address of
3669 the GOT entry from the literal pool. */
3671 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
3672 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
3673 new_rtx = force_const_mem (Pmode, new_rtx);
3674 temp = gen_reg_rtx (Pmode);
3675 emit_move_insn (temp, new_rtx);
3677 new_rtx = temp;
3678 new_rtx = gen_const_mem (Pmode, new_rtx);
3679 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new_rtx, addr), UNSPEC_TLS_LOAD);
3680 temp = gen_reg_rtx (Pmode);
3681 emit_insn (gen_rtx_SET (Pmode, temp, new_rtx));
3684 new_rtx = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
3685 if (reg != 0)
3687 s390_load_address (reg, new_rtx);
3688 new_rtx = reg;
3690 break;
3692 case TLS_MODEL_LOCAL_EXEC:
3693 new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
3694 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
3695 new_rtx = force_const_mem (Pmode, new_rtx);
3696 temp = gen_reg_rtx (Pmode);
3697 emit_move_insn (temp, new_rtx);
3699 new_rtx = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
3700 if (reg != 0)
3702 s390_load_address (reg, new_rtx);
3703 new_rtx = reg;
3705 break;
3707 default:
3708 gcc_unreachable ();
3711 else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == UNSPEC)
3713 switch (XINT (XEXP (addr, 0), 1))
3715 case UNSPEC_INDNTPOFF:
3716 gcc_assert (TARGET_CPU_ZARCH);
3717 new_rtx = addr;
3718 break;
3720 default:
3721 gcc_unreachable ();
3725 else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == PLUS
3726 && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
3728 new_rtx = XEXP (XEXP (addr, 0), 0);
3729 if (GET_CODE (new_rtx) != SYMBOL_REF)
3730 new_rtx = gen_rtx_CONST (Pmode, new_rtx);
3732 new_rtx = legitimize_tls_address (new_rtx, reg);
3733 new_rtx = plus_constant (new_rtx, INTVAL (XEXP (XEXP (addr, 0), 1)));
3734 new_rtx = force_operand (new_rtx, 0);
3737 else
3738 gcc_unreachable (); /* for now ... */
3740 return new_rtx;
3743 /* Emit insns making the address in operands[1] valid for a standard
3744 move to operands[0]. operands[1] is replaced by an address which
3745 should be used instead of the former RTX to emit the move
3746 pattern. */
3748 void
3749 emit_symbolic_move (rtx *operands)
3751 rtx temp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
3753 if (GET_CODE (operands[0]) == MEM)
3754 operands[1] = force_reg (Pmode, operands[1]);
3755 else if (TLS_SYMBOLIC_CONST (operands[1]))
3756 operands[1] = legitimize_tls_address (operands[1], temp);
3757 else if (flag_pic)
3758 operands[1] = legitimize_pic_address (operands[1], temp);
3761 /* Try machine-dependent ways of modifying an illegitimate address X
3762 to be legitimate. If we find one, return the new, valid address.
3764 OLDX is the address as it was before break_out_memory_refs was called.
3765 In some cases it is useful to look at this to decide what needs to be done.
3767 MODE is the mode of the operand pointed to by X.
3769 When -fpic is used, special handling is needed for symbolic references.
3770 See comments by legitimize_pic_address for details. */
3772 static rtx
3773 s390_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
3774 enum machine_mode mode ATTRIBUTE_UNUSED)
3776 rtx constant_term = const0_rtx;
3778 if (TLS_SYMBOLIC_CONST (x))
3780 x = legitimize_tls_address (x, 0);
3782 if (s390_legitimate_address_p (mode, x, FALSE))
3783 return x;
3785 else if (GET_CODE (x) == PLUS
3786 && (TLS_SYMBOLIC_CONST (XEXP (x, 0))
3787 || TLS_SYMBOLIC_CONST (XEXP (x, 1))))
3789 return x;
3791 else if (flag_pic)
3793 if (SYMBOLIC_CONST (x)
3794 || (GET_CODE (x) == PLUS
3795 && (SYMBOLIC_CONST (XEXP (x, 0))
3796 || SYMBOLIC_CONST (XEXP (x, 1)))))
3797 x = legitimize_pic_address (x, 0);
3799 if (s390_legitimate_address_p (mode, x, FALSE))
3800 return x;
3803 x = eliminate_constant_term (x, &constant_term);
3805 /* Optimize loading of large displacements by splitting them
3806 into the multiple of 4K and the rest; this allows the
3807 former to be CSE'd if possible.
3809 Don't do this if the displacement is added to a register
3810 pointing into the stack frame, as the offsets will
3811 change later anyway. */
3813 if (GET_CODE (constant_term) == CONST_INT
3814 && !TARGET_LONG_DISPLACEMENT
3815 && !DISP_IN_RANGE (INTVAL (constant_term))
3816 && !(REG_P (x) && REGNO_PTR_FRAME_P (REGNO (x))))
3818 HOST_WIDE_INT lower = INTVAL (constant_term) & 0xfff;
3819 HOST_WIDE_INT upper = INTVAL (constant_term) ^ lower;
3821 rtx temp = gen_reg_rtx (Pmode);
3822 rtx val = force_operand (GEN_INT (upper), temp);
3823 if (val != temp)
3824 emit_move_insn (temp, val);
3826 x = gen_rtx_PLUS (Pmode, x, temp);
3827 constant_term = GEN_INT (lower);
3830 if (GET_CODE (x) == PLUS)
3832 if (GET_CODE (XEXP (x, 0)) == REG)
3834 rtx temp = gen_reg_rtx (Pmode);
3835 rtx val = force_operand (XEXP (x, 1), temp);
3836 if (val != temp)
3837 emit_move_insn (temp, val);
3839 x = gen_rtx_PLUS (Pmode, XEXP (x, 0), temp);
3842 else if (GET_CODE (XEXP (x, 1)) == REG)
3844 rtx temp = gen_reg_rtx (Pmode);
3845 rtx val = force_operand (XEXP (x, 0), temp);
3846 if (val != temp)
3847 emit_move_insn (temp, val);
3849 x = gen_rtx_PLUS (Pmode, temp, XEXP (x, 1));
3853 if (constant_term != const0_rtx)
3854 x = gen_rtx_PLUS (Pmode, x, constant_term);
3856 return x;
3859 /* Try a machine-dependent way of reloading an illegitimate address AD
3860 operand. If we find one, push the reload and and return the new address.
3862 MODE is the mode of the enclosing MEM. OPNUM is the operand number
3863 and TYPE is the reload type of the current reload. */
3866 legitimize_reload_address (rtx ad, enum machine_mode mode ATTRIBUTE_UNUSED,
3867 int opnum, int type)
3869 if (!optimize || TARGET_LONG_DISPLACEMENT)
3870 return NULL_RTX;
3872 if (GET_CODE (ad) == PLUS)
3874 rtx tem = simplify_binary_operation (PLUS, Pmode,
3875 XEXP (ad, 0), XEXP (ad, 1));
3876 if (tem)
3877 ad = tem;
3880 if (GET_CODE (ad) == PLUS
3881 && GET_CODE (XEXP (ad, 0)) == REG
3882 && GET_CODE (XEXP (ad, 1)) == CONST_INT
3883 && !DISP_IN_RANGE (INTVAL (XEXP (ad, 1))))
3885 HOST_WIDE_INT lower = INTVAL (XEXP (ad, 1)) & 0xfff;
3886 HOST_WIDE_INT upper = INTVAL (XEXP (ad, 1)) ^ lower;
3887 rtx cst, tem, new_rtx;
3889 cst = GEN_INT (upper);
3890 if (!legitimate_reload_constant_p (cst))
3891 cst = force_const_mem (Pmode, cst);
3893 tem = gen_rtx_PLUS (Pmode, XEXP (ad, 0), cst);
3894 new_rtx = gen_rtx_PLUS (Pmode, tem, GEN_INT (lower));
3896 push_reload (XEXP (tem, 1), 0, &XEXP (tem, 1), 0,
3897 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3898 opnum, (enum reload_type) type);
3899 return new_rtx;
3902 return NULL_RTX;
3905 /* Emit code to move LEN bytes from DST to SRC. */
3907 void
3908 s390_expand_movmem (rtx dst, rtx src, rtx len)
3910 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
3912 if (INTVAL (len) > 0)
3913 emit_insn (gen_movmem_short (dst, src, GEN_INT (INTVAL (len) - 1)));
3916 else if (TARGET_MVCLE)
3918 emit_insn (gen_movmem_long (dst, src, convert_to_mode (Pmode, len, 1)));
3921 else
3923 rtx dst_addr, src_addr, count, blocks, temp;
3924 rtx loop_start_label = gen_label_rtx ();
3925 rtx loop_end_label = gen_label_rtx ();
3926 rtx end_label = gen_label_rtx ();
3927 enum machine_mode mode;
3929 mode = GET_MODE (len);
3930 if (mode == VOIDmode)
3931 mode = Pmode;
3933 dst_addr = gen_reg_rtx (Pmode);
3934 src_addr = gen_reg_rtx (Pmode);
3935 count = gen_reg_rtx (mode);
3936 blocks = gen_reg_rtx (mode);
3938 convert_move (count, len, 1);
3939 emit_cmp_and_jump_insns (count, const0_rtx,
3940 EQ, NULL_RTX, mode, 1, end_label);
3942 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
3943 emit_move_insn (src_addr, force_operand (XEXP (src, 0), NULL_RTX));
3944 dst = change_address (dst, VOIDmode, dst_addr);
3945 src = change_address (src, VOIDmode, src_addr);
3947 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1,
3948 OPTAB_DIRECT);
3949 if (temp != count)
3950 emit_move_insn (count, temp);
3952 temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1,
3953 OPTAB_DIRECT);
3954 if (temp != blocks)
3955 emit_move_insn (blocks, temp);
3957 emit_cmp_and_jump_insns (blocks, const0_rtx,
3958 EQ, NULL_RTX, mode, 1, loop_end_label);
3960 emit_label (loop_start_label);
3962 if (TARGET_Z10
3963 && (GET_CODE (len) != CONST_INT || INTVAL (len) > 768))
3965 rtx prefetch;
3967 /* Issue a read prefetch for the +3 cache line. */
3968 prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, src_addr, GEN_INT (768)),
3969 const0_rtx, const0_rtx);
3970 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
3971 emit_insn (prefetch);
3973 /* Issue a write prefetch for the +3 cache line. */
3974 prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (768)),
3975 const1_rtx, const0_rtx);
3976 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
3977 emit_insn (prefetch);
3980 emit_insn (gen_movmem_short (dst, src, GEN_INT (255)));
3981 s390_load_address (dst_addr,
3982 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
3983 s390_load_address (src_addr,
3984 gen_rtx_PLUS (Pmode, src_addr, GEN_INT (256)));
3986 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1,
3987 OPTAB_DIRECT);
3988 if (temp != blocks)
3989 emit_move_insn (blocks, temp);
3991 emit_cmp_and_jump_insns (blocks, const0_rtx,
3992 EQ, NULL_RTX, mode, 1, loop_end_label);
3994 emit_jump (loop_start_label);
3995 emit_label (loop_end_label);
3997 emit_insn (gen_movmem_short (dst, src,
3998 convert_to_mode (Pmode, count, 1)));
3999 emit_label (end_label);
4003 /* Emit code to set LEN bytes at DST to VAL.
4004 Make use of clrmem if VAL is zero. */
4006 void
4007 s390_expand_setmem (rtx dst, rtx len, rtx val)
4009 if (GET_CODE (len) == CONST_INT && INTVAL (len) == 0)
4010 return;
4012 gcc_assert (GET_CODE (val) == CONST_INT || GET_MODE (val) == QImode);
4014 if (GET_CODE (len) == CONST_INT && INTVAL (len) > 0 && INTVAL (len) <= 257)
4016 if (val == const0_rtx && INTVAL (len) <= 256)
4017 emit_insn (gen_clrmem_short (dst, GEN_INT (INTVAL (len) - 1)));
4018 else
4020 /* Initialize memory by storing the first byte. */
4021 emit_move_insn (adjust_address (dst, QImode, 0), val);
4023 if (INTVAL (len) > 1)
4025 /* Initiate 1 byte overlap move.
4026 The first byte of DST is propagated through DSTP1.
4027 Prepare a movmem for: DST+1 = DST (length = LEN - 1).
4028 DST is set to size 1 so the rest of the memory location
4029 does not count as source operand. */
4030 rtx dstp1 = adjust_address (dst, VOIDmode, 1);
4031 set_mem_size (dst, const1_rtx);
4033 emit_insn (gen_movmem_short (dstp1, dst,
4034 GEN_INT (INTVAL (len) - 2)));
4039 else if (TARGET_MVCLE)
4041 val = force_not_mem (convert_modes (Pmode, QImode, val, 1));
4042 emit_insn (gen_setmem_long (dst, convert_to_mode (Pmode, len, 1), val));
4045 else
4047 rtx dst_addr, count, blocks, temp, dstp1 = NULL_RTX;
4048 rtx loop_start_label = gen_label_rtx ();
4049 rtx loop_end_label = gen_label_rtx ();
4050 rtx end_label = gen_label_rtx ();
4051 enum machine_mode mode;
4053 mode = GET_MODE (len);
4054 if (mode == VOIDmode)
4055 mode = Pmode;
4057 dst_addr = gen_reg_rtx (Pmode);
4058 count = gen_reg_rtx (mode);
4059 blocks = gen_reg_rtx (mode);
4061 convert_move (count, len, 1);
4062 emit_cmp_and_jump_insns (count, const0_rtx,
4063 EQ, NULL_RTX, mode, 1, end_label);
4065 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
4066 dst = change_address (dst, VOIDmode, dst_addr);
4068 if (val == const0_rtx)
4069 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1,
4070 OPTAB_DIRECT);
4071 else
4073 dstp1 = adjust_address (dst, VOIDmode, 1);
4074 set_mem_size (dst, const1_rtx);
4076 /* Initialize memory by storing the first byte. */
4077 emit_move_insn (adjust_address (dst, QImode, 0), val);
4079 /* If count is 1 we are done. */
4080 emit_cmp_and_jump_insns (count, const1_rtx,
4081 EQ, NULL_RTX, mode, 1, end_label);
4083 temp = expand_binop (mode, add_optab, count, GEN_INT (-2), count, 1,
4084 OPTAB_DIRECT);
4086 if (temp != count)
4087 emit_move_insn (count, temp);
4089 temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1,
4090 OPTAB_DIRECT);
4091 if (temp != blocks)
4092 emit_move_insn (blocks, temp);
4094 emit_cmp_and_jump_insns (blocks, const0_rtx,
4095 EQ, NULL_RTX, mode, 1, loop_end_label);
4097 emit_label (loop_start_label);
4099 if (TARGET_Z10
4100 && (GET_CODE (len) != CONST_INT || INTVAL (len) > 1024))
4102 /* Issue a write prefetch for the +4 cache line. */
4103 rtx prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, dst_addr,
4104 GEN_INT (1024)),
4105 const1_rtx, const0_rtx);
4106 emit_insn (prefetch);
4107 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
4110 if (val == const0_rtx)
4111 emit_insn (gen_clrmem_short (dst, GEN_INT (255)));
4112 else
4113 emit_insn (gen_movmem_short (dstp1, dst, GEN_INT (255)));
4114 s390_load_address (dst_addr,
4115 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
4117 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1,
4118 OPTAB_DIRECT);
4119 if (temp != blocks)
4120 emit_move_insn (blocks, temp);
4122 emit_cmp_and_jump_insns (blocks, const0_rtx,
4123 EQ, NULL_RTX, mode, 1, loop_end_label);
4125 emit_jump (loop_start_label);
4126 emit_label (loop_end_label);
4128 if (val == const0_rtx)
4129 emit_insn (gen_clrmem_short (dst, convert_to_mode (Pmode, count, 1)));
4130 else
4131 emit_insn (gen_movmem_short (dstp1, dst, convert_to_mode (Pmode, count, 1)));
4132 emit_label (end_label);
4136 /* Emit code to compare LEN bytes at OP0 with those at OP1,
4137 and return the result in TARGET. */
4139 void
4140 s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
4142 rtx ccreg = gen_rtx_REG (CCUmode, CC_REGNUM);
4143 rtx tmp;
4145 /* As the result of CMPINT is inverted compared to what we need,
4146 we have to swap the operands. */
4147 tmp = op0; op0 = op1; op1 = tmp;
4149 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
4151 if (INTVAL (len) > 0)
4153 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (INTVAL (len) - 1)));
4154 emit_insn (gen_cmpint (target, ccreg));
4156 else
4157 emit_move_insn (target, const0_rtx);
4159 else if (TARGET_MVCLE)
4161 emit_insn (gen_cmpmem_long (op0, op1, convert_to_mode (Pmode, len, 1)));
4162 emit_insn (gen_cmpint (target, ccreg));
4164 else
4166 rtx addr0, addr1, count, blocks, temp;
4167 rtx loop_start_label = gen_label_rtx ();
4168 rtx loop_end_label = gen_label_rtx ();
4169 rtx end_label = gen_label_rtx ();
4170 enum machine_mode mode;
4172 mode = GET_MODE (len);
4173 if (mode == VOIDmode)
4174 mode = Pmode;
4176 addr0 = gen_reg_rtx (Pmode);
4177 addr1 = gen_reg_rtx (Pmode);
4178 count = gen_reg_rtx (mode);
4179 blocks = gen_reg_rtx (mode);
4181 convert_move (count, len, 1);
4182 emit_cmp_and_jump_insns (count, const0_rtx,
4183 EQ, NULL_RTX, mode, 1, end_label);
4185 emit_move_insn (addr0, force_operand (XEXP (op0, 0), NULL_RTX));
4186 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
4187 op0 = change_address (op0, VOIDmode, addr0);
4188 op1 = change_address (op1, VOIDmode, addr1);
4190 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1,
4191 OPTAB_DIRECT);
4192 if (temp != count)
4193 emit_move_insn (count, temp);
4195 temp = expand_binop (mode, lshr_optab, count, GEN_INT (8), blocks, 1,
4196 OPTAB_DIRECT);
4197 if (temp != blocks)
4198 emit_move_insn (blocks, temp);
4200 emit_cmp_and_jump_insns (blocks, const0_rtx,
4201 EQ, NULL_RTX, mode, 1, loop_end_label);
4203 emit_label (loop_start_label);
4205 if (TARGET_Z10
4206 && (GET_CODE (len) != CONST_INT || INTVAL (len) > 512))
4208 rtx prefetch;
4210 /* Issue a read prefetch for the +2 cache line of operand 1. */
4211 prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, addr0, GEN_INT (512)),
4212 const0_rtx, const0_rtx);
4213 emit_insn (prefetch);
4214 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
4216 /* Issue a read prefetch for the +2 cache line of operand 2. */
4217 prefetch = gen_prefetch (gen_rtx_PLUS (Pmode, addr1, GEN_INT (512)),
4218 const0_rtx, const0_rtx);
4219 emit_insn (prefetch);
4220 PREFETCH_SCHEDULE_BARRIER_P (prefetch) = true;
4223 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (255)));
4224 temp = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
4225 temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
4226 gen_rtx_LABEL_REF (VOIDmode, end_label), pc_rtx);
4227 temp = gen_rtx_SET (VOIDmode, pc_rtx, temp);
4228 emit_jump_insn (temp);
4230 s390_load_address (addr0,
4231 gen_rtx_PLUS (Pmode, addr0, GEN_INT (256)));
4232 s390_load_address (addr1,
4233 gen_rtx_PLUS (Pmode, addr1, GEN_INT (256)));
4235 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1,
4236 OPTAB_DIRECT);
4237 if (temp != blocks)
4238 emit_move_insn (blocks, temp);
4240 emit_cmp_and_jump_insns (blocks, const0_rtx,
4241 EQ, NULL_RTX, mode, 1, loop_end_label);
4243 emit_jump (loop_start_label);
4244 emit_label (loop_end_label);
4246 emit_insn (gen_cmpmem_short (op0, op1,
4247 convert_to_mode (Pmode, count, 1)));
4248 emit_label (end_label);
4250 emit_insn (gen_cmpint (target, ccreg));
4255 /* Expand conditional increment or decrement using alc/slb instructions.
4256 Should generate code setting DST to either SRC or SRC + INCREMENT,
4257 depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
4258 Returns true if successful, false otherwise.
4260 That makes it possible to implement some if-constructs without jumps e.g.:
4261 (borrow = CC0 | CC1 and carry = CC2 | CC3)
4262 unsigned int a, b, c;
4263 if (a < b) c++; -> CCU b > a -> CC2; c += carry;
4264 if (a < b) c--; -> CCL3 a - b -> borrow; c -= borrow;
4265 if (a <= b) c++; -> CCL3 b - a -> borrow; c += carry;
4266 if (a <= b) c--; -> CCU a <= b -> borrow; c -= borrow;
4268 Checks for EQ and NE with a nonzero value need an additional xor e.g.:
4269 if (a == b) c++; -> CCL3 a ^= b; 0 - a -> borrow; c += carry;
4270 if (a == b) c--; -> CCU a ^= b; a <= 0 -> CC0 | CC1; c -= borrow;
4271 if (a != b) c++; -> CCU a ^= b; a > 0 -> CC2; c += carry;
4272 if (a != b) c--; -> CCL3 a ^= b; 0 - a -> borrow; c -= borrow; */
4274 bool
4275 s390_expand_addcc (enum rtx_code cmp_code, rtx cmp_op0, rtx cmp_op1,
4276 rtx dst, rtx src, rtx increment)
4278 enum machine_mode cmp_mode;
4279 enum machine_mode cc_mode;
4280 rtx op_res;
4281 rtx insn;
4282 rtvec p;
4283 int ret;
4285 if ((GET_MODE (cmp_op0) == SImode || GET_MODE (cmp_op0) == VOIDmode)
4286 && (GET_MODE (cmp_op1) == SImode || GET_MODE (cmp_op1) == VOIDmode))
4287 cmp_mode = SImode;
4288 else if ((GET_MODE (cmp_op0) == DImode || GET_MODE (cmp_op0) == VOIDmode)
4289 && (GET_MODE (cmp_op1) == DImode || GET_MODE (cmp_op1) == VOIDmode))
4290 cmp_mode = DImode;
4291 else
4292 return false;
4294 /* Try ADD LOGICAL WITH CARRY. */
4295 if (increment == const1_rtx)
4297 /* Determine CC mode to use. */
4298 if (cmp_code == EQ || cmp_code == NE)
4300 if (cmp_op1 != const0_rtx)
4302 cmp_op0 = expand_simple_binop (cmp_mode, XOR, cmp_op0, cmp_op1,
4303 NULL_RTX, 0, OPTAB_WIDEN);
4304 cmp_op1 = const0_rtx;
4307 cmp_code = cmp_code == EQ ? LEU : GTU;
4310 if (cmp_code == LTU || cmp_code == LEU)
4312 rtx tem = cmp_op0;
4313 cmp_op0 = cmp_op1;
4314 cmp_op1 = tem;
4315 cmp_code = swap_condition (cmp_code);
4318 switch (cmp_code)
4320 case GTU:
4321 cc_mode = CCUmode;
4322 break;
4324 case GEU:
4325 cc_mode = CCL3mode;
4326 break;
4328 default:
4329 return false;
4332 /* Emit comparison instruction pattern. */
4333 if (!register_operand (cmp_op0, cmp_mode))
4334 cmp_op0 = force_reg (cmp_mode, cmp_op0);
4336 insn = gen_rtx_SET (VOIDmode, gen_rtx_REG (cc_mode, CC_REGNUM),
4337 gen_rtx_COMPARE (cc_mode, cmp_op0, cmp_op1));
4338 /* We use insn_invalid_p here to add clobbers if required. */
4339 ret = insn_invalid_p (emit_insn (insn));
4340 gcc_assert (!ret);
4342 /* Emit ALC instruction pattern. */
4343 op_res = gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
4344 gen_rtx_REG (cc_mode, CC_REGNUM),
4345 const0_rtx);
4347 if (src != const0_rtx)
4349 if (!register_operand (src, GET_MODE (dst)))
4350 src = force_reg (GET_MODE (dst), src);
4352 op_res = gen_rtx_PLUS (GET_MODE (dst), op_res, src);
4353 op_res = gen_rtx_PLUS (GET_MODE (dst), op_res, const0_rtx);
4356 p = rtvec_alloc (2);
4357 RTVEC_ELT (p, 0) =
4358 gen_rtx_SET (VOIDmode, dst, op_res);
4359 RTVEC_ELT (p, 1) =
4360 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
4361 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
4363 return true;
4366 /* Try SUBTRACT LOGICAL WITH BORROW. */
4367 if (increment == constm1_rtx)
4369 /* Determine CC mode to use. */
4370 if (cmp_code == EQ || cmp_code == NE)
4372 if (cmp_op1 != const0_rtx)
4374 cmp_op0 = expand_simple_binop (cmp_mode, XOR, cmp_op0, cmp_op1,
4375 NULL_RTX, 0, OPTAB_WIDEN);
4376 cmp_op1 = const0_rtx;
4379 cmp_code = cmp_code == EQ ? LEU : GTU;
4382 if (cmp_code == GTU || cmp_code == GEU)
4384 rtx tem = cmp_op0;
4385 cmp_op0 = cmp_op1;
4386 cmp_op1 = tem;
4387 cmp_code = swap_condition (cmp_code);
4390 switch (cmp_code)
4392 case LEU:
4393 cc_mode = CCUmode;
4394 break;
4396 case LTU:
4397 cc_mode = CCL3mode;
4398 break;
4400 default:
4401 return false;
4404 /* Emit comparison instruction pattern. */
4405 if (!register_operand (cmp_op0, cmp_mode))
4406 cmp_op0 = force_reg (cmp_mode, cmp_op0);
4408 insn = gen_rtx_SET (VOIDmode, gen_rtx_REG (cc_mode, CC_REGNUM),
4409 gen_rtx_COMPARE (cc_mode, cmp_op0, cmp_op1));
4410 /* We use insn_invalid_p here to add clobbers if required. */
4411 ret = insn_invalid_p (emit_insn (insn));
4412 gcc_assert (!ret);
4414 /* Emit SLB instruction pattern. */
4415 if (!register_operand (src, GET_MODE (dst)))
4416 src = force_reg (GET_MODE (dst), src);
4418 op_res = gen_rtx_MINUS (GET_MODE (dst),
4419 gen_rtx_MINUS (GET_MODE (dst), src, const0_rtx),
4420 gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
4421 gen_rtx_REG (cc_mode, CC_REGNUM),
4422 const0_rtx));
4423 p = rtvec_alloc (2);
4424 RTVEC_ELT (p, 0) =
4425 gen_rtx_SET (VOIDmode, dst, op_res);
4426 RTVEC_ELT (p, 1) =
4427 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
4428 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
4430 return true;
4433 return false;
4436 /* Expand code for the insv template. Return true if successful. */
4438 bool
4439 s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src)
4441 int bitsize = INTVAL (op1);
4442 int bitpos = INTVAL (op2);
4444 /* On z10 we can use the risbg instruction to implement insv. */
4445 if (TARGET_Z10
4446 && ((GET_MODE (dest) == DImode && GET_MODE (src) == DImode)
4447 || (GET_MODE (dest) == SImode && GET_MODE (src) == SImode)))
4449 rtx op;
4450 rtx clobber;
4452 op = gen_rtx_SET (GET_MODE(src),
4453 gen_rtx_ZERO_EXTRACT (GET_MODE (dest), dest, op1, op2),
4454 src);
4455 clobber = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
4456 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clobber)));
4458 return true;
4461 /* We need byte alignment. */
4462 if (bitsize % BITS_PER_UNIT)
4463 return false;
4465 if (bitpos == 0
4466 && memory_operand (dest, VOIDmode)
4467 && (register_operand (src, word_mode)
4468 || const_int_operand (src, VOIDmode)))
4470 /* Emit standard pattern if possible. */
4471 enum machine_mode mode = smallest_mode_for_size (bitsize, MODE_INT);
4472 if (GET_MODE_BITSIZE (mode) == bitsize)
4473 emit_move_insn (adjust_address (dest, mode, 0), gen_lowpart (mode, src));
4475 /* (set (ze (mem)) (const_int)). */
4476 else if (const_int_operand (src, VOIDmode))
4478 int size = bitsize / BITS_PER_UNIT;
4479 rtx src_mem = adjust_address (force_const_mem (word_mode, src), BLKmode,
4480 GET_MODE_SIZE (word_mode) - size);
4482 dest = adjust_address (dest, BLKmode, 0);
4483 set_mem_size (dest, GEN_INT (size));
4484 s390_expand_movmem (dest, src_mem, GEN_INT (size));
4487 /* (set (ze (mem)) (reg)). */
4488 else if (register_operand (src, word_mode))
4490 if (bitsize <= GET_MODE_BITSIZE (SImode))
4491 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest, op1,
4492 const0_rtx), src);
4493 else
4495 /* Emit st,stcmh sequence. */
4496 int stcmh_width = bitsize - GET_MODE_BITSIZE (SImode);
4497 int size = stcmh_width / BITS_PER_UNIT;
4499 emit_move_insn (adjust_address (dest, SImode, size),
4500 gen_lowpart (SImode, src));
4501 set_mem_size (dest, GEN_INT (size));
4502 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest, GEN_INT
4503 (stcmh_width), const0_rtx),
4504 gen_rtx_LSHIFTRT (word_mode, src, GEN_INT
4505 (GET_MODE_BITSIZE (SImode))));
4508 else
4509 return false;
4511 return true;
4514 /* (set (ze (reg)) (const_int)). */
4515 if (TARGET_ZARCH
4516 && register_operand (dest, word_mode)
4517 && (bitpos % 16) == 0
4518 && (bitsize % 16) == 0
4519 && const_int_operand (src, VOIDmode))
4521 HOST_WIDE_INT val = INTVAL (src);
4522 int regpos = bitpos + bitsize;
4524 while (regpos > bitpos)
4526 enum machine_mode putmode;
4527 int putsize;
4529 if (TARGET_EXTIMM && (regpos % 32 == 0) && (regpos >= bitpos + 32))
4530 putmode = SImode;
4531 else
4532 putmode = HImode;
4534 putsize = GET_MODE_BITSIZE (putmode);
4535 regpos -= putsize;
4536 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest,
4537 GEN_INT (putsize),
4538 GEN_INT (regpos)),
4539 gen_int_mode (val, putmode));
4540 val >>= putsize;
4542 gcc_assert (regpos == bitpos);
4543 return true;
4546 return false;
4549 /* A subroutine of s390_expand_cs_hqi and s390_expand_atomic which returns a
4550 register that holds VAL of mode MODE shifted by COUNT bits. */
4552 static inline rtx
4553 s390_expand_mask_and_shift (rtx val, enum machine_mode mode, rtx count)
4555 val = expand_simple_binop (SImode, AND, val, GEN_INT (GET_MODE_MASK (mode)),
4556 NULL_RTX, 1, OPTAB_DIRECT);
4557 return expand_simple_binop (SImode, ASHIFT, val, count,
4558 NULL_RTX, 1, OPTAB_DIRECT);
4561 /* Structure to hold the initial parameters for a compare_and_swap operation
4562 in HImode and QImode. */
4564 struct alignment_context
4566 rtx memsi; /* SI aligned memory location. */
4567 rtx shift; /* Bit offset with regard to lsb. */
4568 rtx modemask; /* Mask of the HQImode shifted by SHIFT bits. */
4569 rtx modemaski; /* ~modemask */
4570 bool aligned; /* True if memory is aligned, false else. */
4573 /* A subroutine of s390_expand_cs_hqi and s390_expand_atomic to initialize
4574 structure AC for transparent simplifying, if the memory alignment is known
4575 to be at least 32bit. MEM is the memory location for the actual operation
4576 and MODE its mode. */
4578 static void
4579 init_alignment_context (struct alignment_context *ac, rtx mem,
4580 enum machine_mode mode)
4582 ac->shift = GEN_INT (GET_MODE_SIZE (SImode) - GET_MODE_SIZE (mode));
4583 ac->aligned = (MEM_ALIGN (mem) >= GET_MODE_BITSIZE (SImode));
4585 if (ac->aligned)
4586 ac->memsi = adjust_address (mem, SImode, 0); /* Memory is aligned. */
4587 else
4589 /* Alignment is unknown. */
4590 rtx byteoffset, addr, align;
4592 /* Force the address into a register. */
4593 addr = force_reg (Pmode, XEXP (mem, 0));
4595 /* Align it to SImode. */
4596 align = expand_simple_binop (Pmode, AND, addr,
4597 GEN_INT (-GET_MODE_SIZE (SImode)),
4598 NULL_RTX, 1, OPTAB_DIRECT);
4599 /* Generate MEM. */
4600 ac->memsi = gen_rtx_MEM (SImode, align);
4601 MEM_VOLATILE_P (ac->memsi) = MEM_VOLATILE_P (mem);
4602 set_mem_alias_set (ac->memsi, ALIAS_SET_MEMORY_BARRIER);
4603 set_mem_align (ac->memsi, GET_MODE_BITSIZE (SImode));
4605 /* Calculate shiftcount. */
4606 byteoffset = expand_simple_binop (Pmode, AND, addr,
4607 GEN_INT (GET_MODE_SIZE (SImode) - 1),
4608 NULL_RTX, 1, OPTAB_DIRECT);
4609 /* As we already have some offset, evaluate the remaining distance. */
4610 ac->shift = expand_simple_binop (SImode, MINUS, ac->shift, byteoffset,
4611 NULL_RTX, 1, OPTAB_DIRECT);
4614 /* Shift is the byte count, but we need the bitcount. */
4615 ac->shift = expand_simple_binop (SImode, MULT, ac->shift, GEN_INT (BITS_PER_UNIT),
4616 NULL_RTX, 1, OPTAB_DIRECT);
4617 /* Calculate masks. */
4618 ac->modemask = expand_simple_binop (SImode, ASHIFT,
4619 GEN_INT (GET_MODE_MASK (mode)), ac->shift,
4620 NULL_RTX, 1, OPTAB_DIRECT);
4621 ac->modemaski = expand_simple_unop (SImode, NOT, ac->modemask, NULL_RTX, 1);
4624 /* Expand an atomic compare and swap operation for HImode and QImode. MEM is
4625 the memory location, CMP the old value to compare MEM with and NEW_RTX the value
4626 to set if CMP == MEM.
4627 CMP is never in memory for compare_and_swap_cc because
4628 expand_bool_compare_and_swap puts it into a register for later compare. */
4630 void
4631 s390_expand_cs_hqi (enum machine_mode mode, rtx target, rtx mem, rtx cmp, rtx new_rtx)
4633 struct alignment_context ac;
4634 rtx cmpv, newv, val, resv, cc;
4635 rtx res = gen_reg_rtx (SImode);
4636 rtx csloop = gen_label_rtx ();
4637 rtx csend = gen_label_rtx ();
4639 gcc_assert (register_operand (target, VOIDmode));
4640 gcc_assert (MEM_P (mem));
4642 init_alignment_context (&ac, mem, mode);
4644 /* Shift the values to the correct bit positions. */
4645 if (!(ac.aligned && MEM_P (cmp)))
4646 cmp = s390_expand_mask_and_shift (cmp, mode, ac.shift);
4647 if (!(ac.aligned && MEM_P (new_rtx)))
4648 new_rtx = s390_expand_mask_and_shift (new_rtx, mode, ac.shift);
4650 /* Load full word. Subsequent loads are performed by CS. */
4651 val = expand_simple_binop (SImode, AND, ac.memsi, ac.modemaski,
4652 NULL_RTX, 1, OPTAB_DIRECT);
4654 /* Start CS loop. */
4655 emit_label (csloop);
4656 /* val = "<mem>00..0<mem>"
4657 * cmp = "00..0<cmp>00..0"
4658 * new = "00..0<new>00..0"
4661 /* Patch cmp and new with val at correct position. */
4662 if (ac.aligned && MEM_P (cmp))
4664 cmpv = force_reg (SImode, val);
4665 store_bit_field (cmpv, GET_MODE_BITSIZE (mode), 0, SImode, cmp);
4667 else
4668 cmpv = force_reg (SImode, expand_simple_binop (SImode, IOR, cmp, val,
4669 NULL_RTX, 1, OPTAB_DIRECT));
4670 if (ac.aligned && MEM_P (new_rtx))
4672 newv = force_reg (SImode, val);
4673 store_bit_field (newv, GET_MODE_BITSIZE (mode), 0, SImode, new_rtx);
4675 else
4676 newv = force_reg (SImode, expand_simple_binop (SImode, IOR, new_rtx, val,
4677 NULL_RTX, 1, OPTAB_DIRECT));
4679 /* Jump to end if we're done (likely?). */
4680 s390_emit_jump (csend, s390_emit_compare_and_swap (EQ, res, ac.memsi,
4681 cmpv, newv));
4683 /* Check for changes outside mode. */
4684 resv = expand_simple_binop (SImode, AND, res, ac.modemaski,
4685 NULL_RTX, 1, OPTAB_DIRECT);
4686 cc = s390_emit_compare (NE, resv, val);
4687 emit_move_insn (val, resv);
4688 /* Loop internal if so. */
4689 s390_emit_jump (csloop, cc);
4691 emit_label (csend);
4693 /* Return the correct part of the bitfield. */
4694 convert_move (target, expand_simple_binop (SImode, LSHIFTRT, res, ac.shift,
4695 NULL_RTX, 1, OPTAB_DIRECT), 1);
4698 /* Expand an atomic operation CODE of mode MODE. MEM is the memory location
4699 and VAL the value to play with. If AFTER is true then store the value
4700 MEM holds after the operation, if AFTER is false then store the value MEM
4701 holds before the operation. If TARGET is zero then discard that value, else
4702 store it to TARGET. */
4704 void
4705 s390_expand_atomic (enum machine_mode mode, enum rtx_code code,
4706 rtx target, rtx mem, rtx val, bool after)
4708 struct alignment_context ac;
4709 rtx cmp;
4710 rtx new_rtx = gen_reg_rtx (SImode);
4711 rtx orig = gen_reg_rtx (SImode);
4712 rtx csloop = gen_label_rtx ();
4714 gcc_assert (!target || register_operand (target, VOIDmode));
4715 gcc_assert (MEM_P (mem));
4717 init_alignment_context (&ac, mem, mode);
4719 /* Shift val to the correct bit positions.
4720 Preserve "icm", but prevent "ex icm". */
4721 if (!(ac.aligned && code == SET && MEM_P (val)))
4722 val = s390_expand_mask_and_shift (val, mode, ac.shift);
4724 /* Further preparation insns. */
4725 if (code == PLUS || code == MINUS)
4726 emit_move_insn (orig, val);
4727 else if (code == MULT || code == AND) /* val = "11..1<val>11..1" */
4728 val = expand_simple_binop (SImode, XOR, val, ac.modemaski,
4729 NULL_RTX, 1, OPTAB_DIRECT);
4731 /* Load full word. Subsequent loads are performed by CS. */
4732 cmp = force_reg (SImode, ac.memsi);
4734 /* Start CS loop. */
4735 emit_label (csloop);
4736 emit_move_insn (new_rtx, cmp);
4738 /* Patch new with val at correct position. */
4739 switch (code)
4741 case PLUS:
4742 case MINUS:
4743 val = expand_simple_binop (SImode, code, new_rtx, orig,
4744 NULL_RTX, 1, OPTAB_DIRECT);
4745 val = expand_simple_binop (SImode, AND, val, ac.modemask,
4746 NULL_RTX, 1, OPTAB_DIRECT);
4747 /* FALLTHRU */
4748 case SET:
4749 if (ac.aligned && MEM_P (val))
4750 store_bit_field (new_rtx, GET_MODE_BITSIZE (mode), 0, SImode, val);
4751 else
4753 new_rtx = expand_simple_binop (SImode, AND, new_rtx, ac.modemaski,
4754 NULL_RTX, 1, OPTAB_DIRECT);
4755 new_rtx = expand_simple_binop (SImode, IOR, new_rtx, val,
4756 NULL_RTX, 1, OPTAB_DIRECT);
4758 break;
4759 case AND:
4760 case IOR:
4761 case XOR:
4762 new_rtx = expand_simple_binop (SImode, code, new_rtx, val,
4763 NULL_RTX, 1, OPTAB_DIRECT);
4764 break;
4765 case MULT: /* NAND */
4766 new_rtx = expand_simple_binop (SImode, AND, new_rtx, val,
4767 NULL_RTX, 1, OPTAB_DIRECT);
4768 new_rtx = expand_simple_binop (SImode, XOR, new_rtx, ac.modemask,
4769 NULL_RTX, 1, OPTAB_DIRECT);
4770 break;
4771 default:
4772 gcc_unreachable ();
4775 s390_emit_jump (csloop, s390_emit_compare_and_swap (NE, cmp,
4776 ac.memsi, cmp, new_rtx));
4778 /* Return the correct part of the bitfield. */
4779 if (target)
4780 convert_move (target, expand_simple_binop (SImode, LSHIFTRT,
4781 after ? new_rtx : cmp, ac.shift,
4782 NULL_RTX, 1, OPTAB_DIRECT), 1);
4785 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
4786 We need to emit DTP-relative relocations. */
4788 static void s390_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
4790 static void
4791 s390_output_dwarf_dtprel (FILE *file, int size, rtx x)
4793 switch (size)
4795 case 4:
4796 fputs ("\t.long\t", file);
4797 break;
4798 case 8:
4799 fputs ("\t.quad\t", file);
4800 break;
4801 default:
4802 gcc_unreachable ();
4804 output_addr_const (file, x);
4805 fputs ("@DTPOFF", file);
4808 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
4809 /* Implement TARGET_MANGLE_TYPE. */
4811 static const char *
4812 s390_mangle_type (const_tree type)
4814 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
4815 && TARGET_LONG_DOUBLE_128)
4816 return "g";
4818 /* For all other types, use normal C++ mangling. */
4819 return NULL;
4821 #endif
4823 /* In the name of slightly smaller debug output, and to cater to
4824 general assembler lossage, recognize various UNSPEC sequences
4825 and turn them back into a direct symbol reference. */
4827 static rtx
4828 s390_delegitimize_address (rtx orig_x)
4830 rtx x, y;
4832 orig_x = delegitimize_mem_from_attrs (orig_x);
4833 x = orig_x;
4834 if (GET_CODE (x) != MEM)
4835 return orig_x;
4837 x = XEXP (x, 0);
4838 if (GET_CODE (x) == PLUS
4839 && GET_CODE (XEXP (x, 1)) == CONST
4840 && GET_CODE (XEXP (x, 0)) == REG
4841 && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM)
4843 y = XEXP (XEXP (x, 1), 0);
4844 if (GET_CODE (y) == UNSPEC
4845 && XINT (y, 1) == UNSPEC_GOT)
4846 return XVECEXP (y, 0, 0);
4847 return orig_x;
4850 if (GET_CODE (x) == CONST)
4852 y = XEXP (x, 0);
4853 if (GET_CODE (y) == UNSPEC
4854 && XINT (y, 1) == UNSPEC_GOTENT)
4855 return XVECEXP (y, 0, 0);
4856 return orig_x;
4859 return orig_x;
4862 /* Output operand OP to stdio stream FILE.
4863 OP is an address (register + offset) which is not used to address data;
4864 instead the rightmost bits are interpreted as the value. */
4866 static void
4867 print_shift_count_operand (FILE *file, rtx op)
4869 HOST_WIDE_INT offset;
4870 rtx base;
4872 /* Extract base register and offset. */
4873 if (!s390_decompose_shift_count (op, &base, &offset))
4874 gcc_unreachable ();
4876 /* Sanity check. */
4877 if (base)
4879 gcc_assert (GET_CODE (base) == REG);
4880 gcc_assert (REGNO (base) < FIRST_PSEUDO_REGISTER);
4881 gcc_assert (REGNO_REG_CLASS (REGNO (base)) == ADDR_REGS);
4884 /* Offsets are constricted to twelve bits. */
4885 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset & ((1 << 12) - 1));
4886 if (base)
4887 fprintf (file, "(%s)", reg_names[REGNO (base)]);
4890 /* See 'get_some_local_dynamic_name'. */
4892 static int
4893 get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
4895 rtx x = *px;
4897 if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
4899 x = get_pool_constant (x);
4900 return for_each_rtx (&x, get_some_local_dynamic_name_1, 0);
4903 if (GET_CODE (x) == SYMBOL_REF
4904 && tls_symbolic_operand (x) == TLS_MODEL_LOCAL_DYNAMIC)
4906 cfun->machine->some_ld_name = XSTR (x, 0);
4907 return 1;
4910 return 0;
4913 /* Locate some local-dynamic symbol still in use by this function
4914 so that we can print its name in local-dynamic base patterns. */
4916 static const char *
4917 get_some_local_dynamic_name (void)
4919 rtx insn;
4921 if (cfun->machine->some_ld_name)
4922 return cfun->machine->some_ld_name;
4924 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
4925 if (INSN_P (insn)
4926 && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
4927 return cfun->machine->some_ld_name;
4929 gcc_unreachable ();
4932 /* Output machine-dependent UNSPECs occurring in address constant X
4933 in assembler syntax to stdio stream FILE. Returns true if the
4934 constant X could be recognized, false otherwise. */
4936 bool
4937 s390_output_addr_const_extra (FILE *file, rtx x)
4939 if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 1)
4940 switch (XINT (x, 1))
4942 case UNSPEC_GOTENT:
4943 output_addr_const (file, XVECEXP (x, 0, 0));
4944 fprintf (file, "@GOTENT");
4945 return true;
4946 case UNSPEC_GOT:
4947 output_addr_const (file, XVECEXP (x, 0, 0));
4948 fprintf (file, "@GOT");
4949 return true;
4950 case UNSPEC_GOTOFF:
4951 output_addr_const (file, XVECEXP (x, 0, 0));
4952 fprintf (file, "@GOTOFF");
4953 return true;
4954 case UNSPEC_PLT:
4955 output_addr_const (file, XVECEXP (x, 0, 0));
4956 fprintf (file, "@PLT");
4957 return true;
4958 case UNSPEC_PLTOFF:
4959 output_addr_const (file, XVECEXP (x, 0, 0));
4960 fprintf (file, "@PLTOFF");
4961 return true;
4962 case UNSPEC_TLSGD:
4963 output_addr_const (file, XVECEXP (x, 0, 0));
4964 fprintf (file, "@TLSGD");
4965 return true;
4966 case UNSPEC_TLSLDM:
4967 assemble_name (file, get_some_local_dynamic_name ());
4968 fprintf (file, "@TLSLDM");
4969 return true;
4970 case UNSPEC_DTPOFF:
4971 output_addr_const (file, XVECEXP (x, 0, 0));
4972 fprintf (file, "@DTPOFF");
4973 return true;
4974 case UNSPEC_NTPOFF:
4975 output_addr_const (file, XVECEXP (x, 0, 0));
4976 fprintf (file, "@NTPOFF");
4977 return true;
4978 case UNSPEC_GOTNTPOFF:
4979 output_addr_const (file, XVECEXP (x, 0, 0));
4980 fprintf (file, "@GOTNTPOFF");
4981 return true;
4982 case UNSPEC_INDNTPOFF:
4983 output_addr_const (file, XVECEXP (x, 0, 0));
4984 fprintf (file, "@INDNTPOFF");
4985 return true;
4988 if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 2)
4989 switch (XINT (x, 1))
4991 case UNSPEC_POOL_OFFSET:
4992 x = gen_rtx_MINUS (GET_MODE (x), XVECEXP (x, 0, 0), XVECEXP (x, 0, 1));
4993 output_addr_const (file, x);
4994 return true;
4996 return false;
4999 /* Output address operand ADDR in assembler syntax to
5000 stdio stream FILE. */
5002 void
5003 print_operand_address (FILE *file, rtx addr)
5005 struct s390_address ad;
5007 if (s390_symref_operand_p (addr, NULL, NULL))
5009 gcc_assert (TARGET_Z10);
5010 output_addr_const (file, addr);
5011 return;
5014 if (!s390_decompose_address (addr, &ad)
5015 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
5016 || (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx))))
5017 output_operand_lossage ("cannot decompose address");
5019 if (ad.disp)
5020 output_addr_const (file, ad.disp);
5021 else
5022 fprintf (file, "0");
5024 if (ad.base && ad.indx)
5025 fprintf (file, "(%s,%s)", reg_names[REGNO (ad.indx)],
5026 reg_names[REGNO (ad.base)]);
5027 else if (ad.base)
5028 fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
5031 /* Output operand X in assembler syntax to stdio stream FILE.
5032 CODE specified the format flag. The following format flags
5033 are recognized:
5035 'C': print opcode suffix for branch condition.
5036 'D': print opcode suffix for inverse branch condition.
5037 'E': print opcode suffix for branch on index instruction.
5038 'J': print tls_load/tls_gdcall/tls_ldcall suffix
5039 'G': print the size of the operand in bytes.
5040 'O': print only the displacement of a memory reference.
5041 'R': print only the base register of a memory reference.
5042 'S': print S-type memory reference (base+displacement).
5043 'N': print the second word of a DImode operand.
5044 'M': print the second word of a TImode operand.
5045 'Y': print shift count operand.
5047 'b': print integer X as if it's an unsigned byte.
5048 'c': print integer X as if it's an signed byte.
5049 'x': print integer X as if it's an unsigned halfword.
5050 'h': print integer X as if it's a signed halfword.
5051 'i': print the first nonzero HImode part of X.
5052 'j': print the first HImode part unequal to -1 of X.
5053 'k': print the first nonzero SImode part of X.
5054 'm': print the first SImode part unequal to -1 of X.
5055 'o': print integer X as if it's an unsigned 32bit word. */
5057 void
5058 print_operand (FILE *file, rtx x, int code)
5060 switch (code)
5062 case 'C':
5063 fprintf (file, s390_branch_condition_mnemonic (x, FALSE));
5064 return;
5066 case 'D':
5067 fprintf (file, s390_branch_condition_mnemonic (x, TRUE));
5068 return;
5070 case 'E':
5071 if (GET_CODE (x) == LE)
5072 fprintf (file, "l");
5073 else if (GET_CODE (x) == GT)
5074 fprintf (file, "h");
5075 else
5076 gcc_unreachable ();
5077 return;
5079 case 'J':
5080 if (GET_CODE (x) == SYMBOL_REF)
5082 fprintf (file, "%s", ":tls_load:");
5083 output_addr_const (file, x);
5085 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD)
5087 fprintf (file, "%s", ":tls_gdcall:");
5088 output_addr_const (file, XVECEXP (x, 0, 0));
5090 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM)
5092 fprintf (file, "%s", ":tls_ldcall:");
5093 assemble_name (file, get_some_local_dynamic_name ());
5095 else
5096 gcc_unreachable ();
5097 return;
5099 case 'G':
5100 fprintf (file, "%u", GET_MODE_SIZE (GET_MODE (x)));
5101 return;
5103 case 'O':
5105 struct s390_address ad;
5106 int ret;
5108 gcc_assert (GET_CODE (x) == MEM);
5109 ret = s390_decompose_address (XEXP (x, 0), &ad);
5110 gcc_assert (ret);
5111 gcc_assert (!ad.base || REGNO_OK_FOR_BASE_P (REGNO (ad.base)));
5112 gcc_assert (!ad.indx);
5114 if (ad.disp)
5115 output_addr_const (file, ad.disp);
5116 else
5117 fprintf (file, "0");
5119 return;
5121 case 'R':
5123 struct s390_address ad;
5124 int ret;
5126 gcc_assert (GET_CODE (x) == MEM);
5127 ret = s390_decompose_address (XEXP (x, 0), &ad);
5128 gcc_assert (ret);
5129 gcc_assert (!ad.base || REGNO_OK_FOR_BASE_P (REGNO (ad.base)));
5130 gcc_assert (!ad.indx);
5132 if (ad.base)
5133 fprintf (file, "%s", reg_names[REGNO (ad.base)]);
5134 else
5135 fprintf (file, "0");
5137 return;
5139 case 'S':
5141 struct s390_address ad;
5142 int ret;
5144 gcc_assert (GET_CODE (x) == MEM);
5145 ret = s390_decompose_address (XEXP (x, 0), &ad);
5146 gcc_assert (ret);
5147 gcc_assert (!ad.base || REGNO_OK_FOR_BASE_P (REGNO (ad.base)));
5148 gcc_assert (!ad.indx);
5150 if (ad.disp)
5151 output_addr_const (file, ad.disp);
5152 else
5153 fprintf (file, "0");
5155 if (ad.base)
5156 fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
5158 return;
5160 case 'N':
5161 if (GET_CODE (x) == REG)
5162 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
5163 else if (GET_CODE (x) == MEM)
5164 x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 4));
5165 else
5166 gcc_unreachable ();
5167 break;
5169 case 'M':
5170 if (GET_CODE (x) == REG)
5171 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
5172 else if (GET_CODE (x) == MEM)
5173 x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 8));
5174 else
5175 gcc_unreachable ();
5176 break;
5178 case 'Y':
5179 print_shift_count_operand (file, x);
5180 return;
5183 switch (GET_CODE (x))
5185 case REG:
5186 fprintf (file, "%s", reg_names[REGNO (x)]);
5187 break;
5189 case MEM:
5190 output_address (XEXP (x, 0));
5191 break;
5193 case CONST:
5194 case CODE_LABEL:
5195 case LABEL_REF:
5196 case SYMBOL_REF:
5197 output_addr_const (file, x);
5198 break;
5200 case CONST_INT:
5201 if (code == 'b')
5202 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xff);
5203 else if (code == 'c')
5204 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xff) ^ 0x80) - 0x80);
5205 else if (code == 'x')
5206 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffff);
5207 else if (code == 'h')
5208 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000);
5209 else if (code == 'i')
5210 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
5211 s390_extract_part (x, HImode, 0));
5212 else if (code == 'j')
5213 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
5214 s390_extract_part (x, HImode, -1));
5215 else if (code == 'k')
5216 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
5217 s390_extract_part (x, SImode, 0));
5218 else if (code == 'm')
5219 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
5220 s390_extract_part (x, SImode, -1));
5221 else if (code == 'o')
5222 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffffffff);
5223 else
5224 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
5225 break;
5227 case CONST_DOUBLE:
5228 gcc_assert (GET_MODE (x) == VOIDmode);
5229 if (code == 'b')
5230 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xff);
5231 else if (code == 'x')
5232 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xffff);
5233 else if (code == 'h')
5234 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((CONST_DOUBLE_LOW (x) & 0xffff) ^ 0x8000) - 0x8000);
5235 else
5236 gcc_unreachable ();
5237 break;
5239 default:
5240 fatal_insn ("UNKNOWN in print_operand !?", x);
5241 break;
5245 /* Target hook for assembling integer objects. We need to define it
5246 here to work a round a bug in some versions of GAS, which couldn't
5247 handle values smaller than INT_MIN when printed in decimal. */
5249 static bool
5250 s390_assemble_integer (rtx x, unsigned int size, int aligned_p)
5252 if (size == 8 && aligned_p
5253 && GET_CODE (x) == CONST_INT && INTVAL (x) < INT_MIN)
5255 fprintf (asm_out_file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n",
5256 INTVAL (x));
5257 return true;
5259 return default_assemble_integer (x, size, aligned_p);
5262 /* Returns true if register REGNO is used for forming
5263 a memory address in expression X. */
5265 static bool
5266 reg_used_in_mem_p (int regno, rtx x)
5268 enum rtx_code code = GET_CODE (x);
5269 int i, j;
5270 const char *fmt;
5272 if (code == MEM)
5274 if (refers_to_regno_p (regno, regno+1,
5275 XEXP (x, 0), 0))
5276 return true;
5278 else if (code == SET
5279 && GET_CODE (SET_DEST (x)) == PC)
5281 if (refers_to_regno_p (regno, regno+1,
5282 SET_SRC (x), 0))
5283 return true;
5286 fmt = GET_RTX_FORMAT (code);
5287 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
5289 if (fmt[i] == 'e'
5290 && reg_used_in_mem_p (regno, XEXP (x, i)))
5291 return true;
5293 else if (fmt[i] == 'E')
5294 for (j = 0; j < XVECLEN (x, i); j++)
5295 if (reg_used_in_mem_p (regno, XVECEXP (x, i, j)))
5296 return true;
5298 return false;
5301 /* Returns true if expression DEP_RTX sets an address register
5302 used by instruction INSN to address memory. */
5304 static bool
5305 addr_generation_dependency_p (rtx dep_rtx, rtx insn)
5307 rtx target, pat;
5309 if (GET_CODE (dep_rtx) == INSN)
5310 dep_rtx = PATTERN (dep_rtx);
5312 if (GET_CODE (dep_rtx) == SET)
5314 target = SET_DEST (dep_rtx);
5315 if (GET_CODE (target) == STRICT_LOW_PART)
5316 target = XEXP (target, 0);
5317 while (GET_CODE (target) == SUBREG)
5318 target = SUBREG_REG (target);
5320 if (GET_CODE (target) == REG)
5322 int regno = REGNO (target);
5324 if (s390_safe_attr_type (insn) == TYPE_LA)
5326 pat = PATTERN (insn);
5327 if (GET_CODE (pat) == PARALLEL)
5329 gcc_assert (XVECLEN (pat, 0) == 2);
5330 pat = XVECEXP (pat, 0, 0);
5332 gcc_assert (GET_CODE (pat) == SET);
5333 return refers_to_regno_p (regno, regno+1, SET_SRC (pat), 0);
5335 else if (get_attr_atype (insn) == ATYPE_AGEN)
5336 return reg_used_in_mem_p (regno, PATTERN (insn));
5339 return false;
5342 /* Return 1, if dep_insn sets register used in insn in the agen unit. */
5345 s390_agen_dep_p (rtx dep_insn, rtx insn)
5347 rtx dep_rtx = PATTERN (dep_insn);
5348 int i;
5350 if (GET_CODE (dep_rtx) == SET
5351 && addr_generation_dependency_p (dep_rtx, insn))
5352 return 1;
5353 else if (GET_CODE (dep_rtx) == PARALLEL)
5355 for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
5357 if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i), insn))
5358 return 1;
5361 return 0;
5365 /* A C statement (sans semicolon) to update the integer scheduling priority
5366 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
5367 reduce the priority to execute INSN later. Do not define this macro if
5368 you do not need to adjust the scheduling priorities of insns.
5370 A STD instruction should be scheduled earlier,
5371 in order to use the bypass. */
5374 static int
5375 s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
5377 if (! INSN_P (insn))
5378 return priority;
5380 if (s390_tune != PROCESSOR_2084_Z990
5381 && s390_tune != PROCESSOR_2094_Z9_109
5382 && s390_tune != PROCESSOR_2097_Z10)
5383 return priority;
5385 switch (s390_safe_attr_type (insn))
5387 case TYPE_FSTOREDF:
5388 case TYPE_FSTORESF:
5389 priority = priority << 3;
5390 break;
5391 case TYPE_STORE:
5392 case TYPE_STM:
5393 priority = priority << 1;
5394 break;
5395 default:
5396 break;
5398 return priority;
5402 /* The number of instructions that can be issued per cycle. */
5404 static int
5405 s390_issue_rate (void)
5407 switch (s390_tune)
5409 case PROCESSOR_2084_Z990:
5410 case PROCESSOR_2094_Z9_109:
5411 return 3;
5412 case PROCESSOR_2097_Z10:
5413 return 2;
5414 default:
5415 return 1;
5419 static int
5420 s390_first_cycle_multipass_dfa_lookahead (void)
5422 return 4;
5425 /* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
5426 Fix up MEMs as required. */
5428 static void
5429 annotate_constant_pool_refs (rtx *x)
5431 int i, j;
5432 const char *fmt;
5434 gcc_assert (GET_CODE (*x) != SYMBOL_REF
5435 || !CONSTANT_POOL_ADDRESS_P (*x));
5437 /* Literal pool references can only occur inside a MEM ... */
5438 if (GET_CODE (*x) == MEM)
5440 rtx memref = XEXP (*x, 0);
5442 if (GET_CODE (memref) == SYMBOL_REF
5443 && CONSTANT_POOL_ADDRESS_P (memref))
5445 rtx base = cfun->machine->base_reg;
5446 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, memref, base),
5447 UNSPEC_LTREF);
5449 *x = replace_equiv_address (*x, addr);
5450 return;
5453 if (GET_CODE (memref) == CONST
5454 && GET_CODE (XEXP (memref, 0)) == PLUS
5455 && GET_CODE (XEXP (XEXP (memref, 0), 1)) == CONST_INT
5456 && GET_CODE (XEXP (XEXP (memref, 0), 0)) == SYMBOL_REF
5457 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (memref, 0), 0)))
5459 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (memref, 0), 1));
5460 rtx sym = XEXP (XEXP (memref, 0), 0);
5461 rtx base = cfun->machine->base_reg;
5462 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, sym, base),
5463 UNSPEC_LTREF);
5465 *x = replace_equiv_address (*x, plus_constant (addr, off));
5466 return;
5470 /* ... or a load-address type pattern. */
5471 if (GET_CODE (*x) == SET)
5473 rtx addrref = SET_SRC (*x);
5475 if (GET_CODE (addrref) == SYMBOL_REF
5476 && CONSTANT_POOL_ADDRESS_P (addrref))
5478 rtx base = cfun->machine->base_reg;
5479 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, addrref, base),
5480 UNSPEC_LTREF);
5482 SET_SRC (*x) = addr;
5483 return;
5486 if (GET_CODE (addrref) == CONST
5487 && GET_CODE (XEXP (addrref, 0)) == PLUS
5488 && GET_CODE (XEXP (XEXP (addrref, 0), 1)) == CONST_INT
5489 && GET_CODE (XEXP (XEXP (addrref, 0), 0)) == SYMBOL_REF
5490 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (addrref, 0), 0)))
5492 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (addrref, 0), 1));
5493 rtx sym = XEXP (XEXP (addrref, 0), 0);
5494 rtx base = cfun->machine->base_reg;
5495 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, sym, base),
5496 UNSPEC_LTREF);
5498 SET_SRC (*x) = plus_constant (addr, off);
5499 return;
5503 /* Annotate LTREL_BASE as well. */
5504 if (GET_CODE (*x) == UNSPEC
5505 && XINT (*x, 1) == UNSPEC_LTREL_BASE)
5507 rtx base = cfun->machine->base_reg;
5508 *x = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, XVECEXP (*x, 0, 0), base),
5509 UNSPEC_LTREL_BASE);
5510 return;
5513 fmt = GET_RTX_FORMAT (GET_CODE (*x));
5514 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
5516 if (fmt[i] == 'e')
5518 annotate_constant_pool_refs (&XEXP (*x, i));
5520 else if (fmt[i] == 'E')
5522 for (j = 0; j < XVECLEN (*x, i); j++)
5523 annotate_constant_pool_refs (&XVECEXP (*x, i, j));
5528 /* Split all branches that exceed the maximum distance.
5529 Returns true if this created a new literal pool entry. */
5531 static int
5532 s390_split_branches (void)
5534 rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
5535 int new_literal = 0, ret;
5536 rtx insn, pat, tmp, target;
5537 rtx *label;
5539 /* We need correct insn addresses. */
5541 shorten_branches (get_insns ());
5543 /* Find all branches that exceed 64KB, and split them. */
5545 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5547 if (GET_CODE (insn) != JUMP_INSN)
5548 continue;
5550 pat = PATTERN (insn);
5551 if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
5552 pat = XVECEXP (pat, 0, 0);
5553 if (GET_CODE (pat) != SET || SET_DEST (pat) != pc_rtx)
5554 continue;
5556 if (GET_CODE (SET_SRC (pat)) == LABEL_REF)
5558 label = &SET_SRC (pat);
5560 else if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE)
5562 if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF)
5563 label = &XEXP (SET_SRC (pat), 1);
5564 else if (GET_CODE (XEXP (SET_SRC (pat), 2)) == LABEL_REF)
5565 label = &XEXP (SET_SRC (pat), 2);
5566 else
5567 continue;
5569 else
5570 continue;
5572 if (get_attr_length (insn) <= 4)
5573 continue;
5575 /* We are going to use the return register as scratch register,
5576 make sure it will be saved/restored by the prologue/epilogue. */
5577 cfun_frame_layout.save_return_addr_p = 1;
5579 if (!flag_pic)
5581 new_literal = 1;
5582 tmp = force_const_mem (Pmode, *label);
5583 tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, tmp), insn);
5584 INSN_ADDRESSES_NEW (tmp, -1);
5585 annotate_constant_pool_refs (&PATTERN (tmp));
5587 target = temp_reg;
5589 else
5591 new_literal = 1;
5592 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, *label),
5593 UNSPEC_LTREL_OFFSET);
5594 target = gen_rtx_CONST (Pmode, target);
5595 target = force_const_mem (Pmode, target);
5596 tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, target), insn);
5597 INSN_ADDRESSES_NEW (tmp, -1);
5598 annotate_constant_pool_refs (&PATTERN (tmp));
5600 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, XEXP (target, 0),
5601 cfun->machine->base_reg),
5602 UNSPEC_LTREL_BASE);
5603 target = gen_rtx_PLUS (Pmode, temp_reg, target);
5606 ret = validate_change (insn, label, target, 0);
5607 gcc_assert (ret);
5610 return new_literal;
5614 /* Find an annotated literal pool symbol referenced in RTX X,
5615 and store it at REF. Will abort if X contains references to
5616 more than one such pool symbol; multiple references to the same
5617 symbol are allowed, however.
5619 The rtx pointed to by REF must be initialized to NULL_RTX
5620 by the caller before calling this routine. */
5622 static void
5623 find_constant_pool_ref (rtx x, rtx *ref)
5625 int i, j;
5626 const char *fmt;
5628 /* Ignore LTREL_BASE references. */
5629 if (GET_CODE (x) == UNSPEC
5630 && XINT (x, 1) == UNSPEC_LTREL_BASE)
5631 return;
5632 /* Likewise POOL_ENTRY insns. */
5633 if (GET_CODE (x) == UNSPEC_VOLATILE
5634 && XINT (x, 1) == UNSPECV_POOL_ENTRY)
5635 return;
5637 gcc_assert (GET_CODE (x) != SYMBOL_REF
5638 || !CONSTANT_POOL_ADDRESS_P (x));
5640 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_LTREF)
5642 rtx sym = XVECEXP (x, 0, 0);
5643 gcc_assert (GET_CODE (sym) == SYMBOL_REF
5644 && CONSTANT_POOL_ADDRESS_P (sym));
5646 if (*ref == NULL_RTX)
5647 *ref = sym;
5648 else
5649 gcc_assert (*ref == sym);
5651 return;
5654 fmt = GET_RTX_FORMAT (GET_CODE (x));
5655 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
5657 if (fmt[i] == 'e')
5659 find_constant_pool_ref (XEXP (x, i), ref);
5661 else if (fmt[i] == 'E')
5663 for (j = 0; j < XVECLEN (x, i); j++)
5664 find_constant_pool_ref (XVECEXP (x, i, j), ref);
5669 /* Replace every reference to the annotated literal pool
5670 symbol REF in X by its base plus OFFSET. */
5672 static void
5673 replace_constant_pool_ref (rtx *x, rtx ref, rtx offset)
5675 int i, j;
5676 const char *fmt;
5678 gcc_assert (*x != ref);
5680 if (GET_CODE (*x) == UNSPEC
5681 && XINT (*x, 1) == UNSPEC_LTREF
5682 && XVECEXP (*x, 0, 0) == ref)
5684 *x = gen_rtx_PLUS (Pmode, XVECEXP (*x, 0, 1), offset);
5685 return;
5688 if (GET_CODE (*x) == PLUS
5689 && GET_CODE (XEXP (*x, 1)) == CONST_INT
5690 && GET_CODE (XEXP (*x, 0)) == UNSPEC
5691 && XINT (XEXP (*x, 0), 1) == UNSPEC_LTREF
5692 && XVECEXP (XEXP (*x, 0), 0, 0) == ref)
5694 rtx addr = gen_rtx_PLUS (Pmode, XVECEXP (XEXP (*x, 0), 0, 1), offset);
5695 *x = plus_constant (addr, INTVAL (XEXP (*x, 1)));
5696 return;
5699 fmt = GET_RTX_FORMAT (GET_CODE (*x));
5700 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
5702 if (fmt[i] == 'e')
5704 replace_constant_pool_ref (&XEXP (*x, i), ref, offset);
5706 else if (fmt[i] == 'E')
5708 for (j = 0; j < XVECLEN (*x, i); j++)
5709 replace_constant_pool_ref (&XVECEXP (*x, i, j), ref, offset);
5714 /* Check whether X contains an UNSPEC_LTREL_BASE.
5715 Return its constant pool symbol if found, NULL_RTX otherwise. */
5717 static rtx
5718 find_ltrel_base (rtx x)
5720 int i, j;
5721 const char *fmt;
5723 if (GET_CODE (x) == UNSPEC
5724 && XINT (x, 1) == UNSPEC_LTREL_BASE)
5725 return XVECEXP (x, 0, 0);
5727 fmt = GET_RTX_FORMAT (GET_CODE (x));
5728 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
5730 if (fmt[i] == 'e')
5732 rtx fnd = find_ltrel_base (XEXP (x, i));
5733 if (fnd)
5734 return fnd;
5736 else if (fmt[i] == 'E')
5738 for (j = 0; j < XVECLEN (x, i); j++)
5740 rtx fnd = find_ltrel_base (XVECEXP (x, i, j));
5741 if (fnd)
5742 return fnd;
5747 return NULL_RTX;
5750 /* Replace any occurrence of UNSPEC_LTREL_BASE in X with its base. */
5752 static void
5753 replace_ltrel_base (rtx *x)
5755 int i, j;
5756 const char *fmt;
5758 if (GET_CODE (*x) == UNSPEC
5759 && XINT (*x, 1) == UNSPEC_LTREL_BASE)
5761 *x = XVECEXP (*x, 0, 1);
5762 return;
5765 fmt = GET_RTX_FORMAT (GET_CODE (*x));
5766 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
5768 if (fmt[i] == 'e')
5770 replace_ltrel_base (&XEXP (*x, i));
5772 else if (fmt[i] == 'E')
5774 for (j = 0; j < XVECLEN (*x, i); j++)
5775 replace_ltrel_base (&XVECEXP (*x, i, j));
5781 /* We keep a list of constants which we have to add to internal
5782 constant tables in the middle of large functions. */
5784 #define NR_C_MODES 11
5785 enum machine_mode constant_modes[NR_C_MODES] =
5787 TFmode, TImode, TDmode,
5788 DFmode, DImode, DDmode,
5789 SFmode, SImode, SDmode,
5790 HImode,
5791 QImode
5794 struct constant
5796 struct constant *next;
5797 rtx value;
5798 rtx label;
5801 struct constant_pool
5803 struct constant_pool *next;
5804 rtx first_insn;
5805 rtx pool_insn;
5806 bitmap insns;
5807 rtx emit_pool_after;
5809 struct constant *constants[NR_C_MODES];
5810 struct constant *execute;
5811 rtx label;
5812 int size;
5815 /* Allocate new constant_pool structure. */
5817 static struct constant_pool *
5818 s390_alloc_pool (void)
5820 struct constant_pool *pool;
5821 int i;
5823 pool = (struct constant_pool *) xmalloc (sizeof *pool);
5824 pool->next = NULL;
5825 for (i = 0; i < NR_C_MODES; i++)
5826 pool->constants[i] = NULL;
5828 pool->execute = NULL;
5829 pool->label = gen_label_rtx ();
5830 pool->first_insn = NULL_RTX;
5831 pool->pool_insn = NULL_RTX;
5832 pool->insns = BITMAP_ALLOC (NULL);
5833 pool->size = 0;
5834 pool->emit_pool_after = NULL_RTX;
5836 return pool;
5839 /* Create new constant pool covering instructions starting at INSN
5840 and chain it to the end of POOL_LIST. */
5842 static struct constant_pool *
5843 s390_start_pool (struct constant_pool **pool_list, rtx insn)
5845 struct constant_pool *pool, **prev;
5847 pool = s390_alloc_pool ();
5848 pool->first_insn = insn;
5850 for (prev = pool_list; *prev; prev = &(*prev)->next)
5852 *prev = pool;
5854 return pool;
5857 /* End range of instructions covered by POOL at INSN and emit
5858 placeholder insn representing the pool. */
5860 static void
5861 s390_end_pool (struct constant_pool *pool, rtx insn)
5863 rtx pool_size = GEN_INT (pool->size + 8 /* alignment slop */);
5865 if (!insn)
5866 insn = get_last_insn ();
5868 pool->pool_insn = emit_insn_after (gen_pool (pool_size), insn);
5869 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
5872 /* Add INSN to the list of insns covered by POOL. */
5874 static void
5875 s390_add_pool_insn (struct constant_pool *pool, rtx insn)
5877 bitmap_set_bit (pool->insns, INSN_UID (insn));
5880 /* Return pool out of POOL_LIST that covers INSN. */
5882 static struct constant_pool *
5883 s390_find_pool (struct constant_pool *pool_list, rtx insn)
5885 struct constant_pool *pool;
5887 for (pool = pool_list; pool; pool = pool->next)
5888 if (bitmap_bit_p (pool->insns, INSN_UID (insn)))
5889 break;
5891 return pool;
5894 /* Add constant VAL of mode MODE to the constant pool POOL. */
5896 static void
5897 s390_add_constant (struct constant_pool *pool, rtx val, enum machine_mode mode)
5899 struct constant *c;
5900 int i;
5902 for (i = 0; i < NR_C_MODES; i++)
5903 if (constant_modes[i] == mode)
5904 break;
5905 gcc_assert (i != NR_C_MODES);
5907 for (c = pool->constants[i]; c != NULL; c = c->next)
5908 if (rtx_equal_p (val, c->value))
5909 break;
5911 if (c == NULL)
5913 c = (struct constant *) xmalloc (sizeof *c);
5914 c->value = val;
5915 c->label = gen_label_rtx ();
5916 c->next = pool->constants[i];
5917 pool->constants[i] = c;
5918 pool->size += GET_MODE_SIZE (mode);
5922 /* Return an rtx that represents the offset of X from the start of
5923 pool POOL. */
5925 static rtx
5926 s390_pool_offset (struct constant_pool *pool, rtx x)
5928 rtx label;
5930 label = gen_rtx_LABEL_REF (GET_MODE (x), pool->label);
5931 x = gen_rtx_UNSPEC (GET_MODE (x), gen_rtvec (2, x, label),
5932 UNSPEC_POOL_OFFSET);
5933 return gen_rtx_CONST (GET_MODE (x), x);
5936 /* Find constant VAL of mode MODE in the constant pool POOL.
5937 Return an RTX describing the distance from the start of
5938 the pool to the location of the new constant. */
5940 static rtx
5941 s390_find_constant (struct constant_pool *pool, rtx val,
5942 enum machine_mode mode)
5944 struct constant *c;
5945 int i;
5947 for (i = 0; i < NR_C_MODES; i++)
5948 if (constant_modes[i] == mode)
5949 break;
5950 gcc_assert (i != NR_C_MODES);
5952 for (c = pool->constants[i]; c != NULL; c = c->next)
5953 if (rtx_equal_p (val, c->value))
5954 break;
5956 gcc_assert (c);
5958 return s390_pool_offset (pool, gen_rtx_LABEL_REF (Pmode, c->label));
5961 /* Check whether INSN is an execute. Return the label_ref to its
5962 execute target template if so, NULL_RTX otherwise. */
5964 static rtx
5965 s390_execute_label (rtx insn)
5967 if (GET_CODE (insn) == INSN
5968 && GET_CODE (PATTERN (insn)) == PARALLEL
5969 && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == UNSPEC
5970 && XINT (XVECEXP (PATTERN (insn), 0, 0), 1) == UNSPEC_EXECUTE)
5971 return XVECEXP (XVECEXP (PATTERN (insn), 0, 0), 0, 2);
5973 return NULL_RTX;
5976 /* Add execute target for INSN to the constant pool POOL. */
5978 static void
5979 s390_add_execute (struct constant_pool *pool, rtx insn)
5981 struct constant *c;
5983 for (c = pool->execute; c != NULL; c = c->next)
5984 if (INSN_UID (insn) == INSN_UID (c->value))
5985 break;
5987 if (c == NULL)
5989 c = (struct constant *) xmalloc (sizeof *c);
5990 c->value = insn;
5991 c->label = gen_label_rtx ();
5992 c->next = pool->execute;
5993 pool->execute = c;
5994 pool->size += 6;
5998 /* Find execute target for INSN in the constant pool POOL.
5999 Return an RTX describing the distance from the start of
6000 the pool to the location of the execute target. */
6002 static rtx
6003 s390_find_execute (struct constant_pool *pool, rtx insn)
6005 struct constant *c;
6007 for (c = pool->execute; c != NULL; c = c->next)
6008 if (INSN_UID (insn) == INSN_UID (c->value))
6009 break;
6011 gcc_assert (c);
6013 return s390_pool_offset (pool, gen_rtx_LABEL_REF (Pmode, c->label));
6016 /* For an execute INSN, extract the execute target template. */
6018 static rtx
6019 s390_execute_target (rtx insn)
6021 rtx pattern = PATTERN (insn);
6022 gcc_assert (s390_execute_label (insn));
6024 if (XVECLEN (pattern, 0) == 2)
6026 pattern = copy_rtx (XVECEXP (pattern, 0, 1));
6028 else
6030 rtvec vec = rtvec_alloc (XVECLEN (pattern, 0) - 1);
6031 int i;
6033 for (i = 0; i < XVECLEN (pattern, 0) - 1; i++)
6034 RTVEC_ELT (vec, i) = copy_rtx (XVECEXP (pattern, 0, i + 1));
6036 pattern = gen_rtx_PARALLEL (VOIDmode, vec);
6039 return pattern;
6042 /* Indicate that INSN cannot be duplicated. This is the case for
6043 execute insns that carry a unique label. */
6045 static bool
6046 s390_cannot_copy_insn_p (rtx insn)
6048 rtx label = s390_execute_label (insn);
6049 return label && label != const0_rtx;
6052 /* Dump out the constants in POOL. If REMOTE_LABEL is true,
6053 do not emit the pool base label. */
6055 static void
6056 s390_dump_pool (struct constant_pool *pool, bool remote_label)
6058 struct constant *c;
6059 rtx insn = pool->pool_insn;
6060 int i;
6062 /* Switch to rodata section. */
6063 if (TARGET_CPU_ZARCH)
6065 insn = emit_insn_after (gen_pool_section_start (), insn);
6066 INSN_ADDRESSES_NEW (insn, -1);
6069 /* Ensure minimum pool alignment. */
6070 if (TARGET_CPU_ZARCH)
6071 insn = emit_insn_after (gen_pool_align (GEN_INT (8)), insn);
6072 else
6073 insn = emit_insn_after (gen_pool_align (GEN_INT (4)), insn);
6074 INSN_ADDRESSES_NEW (insn, -1);
6076 /* Emit pool base label. */
6077 if (!remote_label)
6079 insn = emit_label_after (pool->label, insn);
6080 INSN_ADDRESSES_NEW (insn, -1);
6083 /* Dump constants in descending alignment requirement order,
6084 ensuring proper alignment for every constant. */
6085 for (i = 0; i < NR_C_MODES; i++)
6086 for (c = pool->constants[i]; c; c = c->next)
6088 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
6089 rtx value = copy_rtx (c->value);
6090 if (GET_CODE (value) == CONST
6091 && GET_CODE (XEXP (value, 0)) == UNSPEC
6092 && XINT (XEXP (value, 0), 1) == UNSPEC_LTREL_OFFSET
6093 && XVECLEN (XEXP (value, 0), 0) == 1)
6094 value = s390_pool_offset (pool, XVECEXP (XEXP (value, 0), 0, 0));
6096 insn = emit_label_after (c->label, insn);
6097 INSN_ADDRESSES_NEW (insn, -1);
6099 value = gen_rtx_UNSPEC_VOLATILE (constant_modes[i],
6100 gen_rtvec (1, value),
6101 UNSPECV_POOL_ENTRY);
6102 insn = emit_insn_after (value, insn);
6103 INSN_ADDRESSES_NEW (insn, -1);
6106 /* Ensure minimum alignment for instructions. */
6107 insn = emit_insn_after (gen_pool_align (GEN_INT (2)), insn);
6108 INSN_ADDRESSES_NEW (insn, -1);
6110 /* Output in-pool execute template insns. */
6111 for (c = pool->execute; c; c = c->next)
6113 insn = emit_label_after (c->label, insn);
6114 INSN_ADDRESSES_NEW (insn, -1);
6116 insn = emit_insn_after (s390_execute_target (c->value), insn);
6117 INSN_ADDRESSES_NEW (insn, -1);
6120 /* Switch back to previous section. */
6121 if (TARGET_CPU_ZARCH)
6123 insn = emit_insn_after (gen_pool_section_end (), insn);
6124 INSN_ADDRESSES_NEW (insn, -1);
6127 insn = emit_barrier_after (insn);
6128 INSN_ADDRESSES_NEW (insn, -1);
6130 /* Remove placeholder insn. */
6131 remove_insn (pool->pool_insn);
6134 /* Free all memory used by POOL. */
6136 static void
6137 s390_free_pool (struct constant_pool *pool)
6139 struct constant *c, *next;
6140 int i;
6142 for (i = 0; i < NR_C_MODES; i++)
6143 for (c = pool->constants[i]; c; c = next)
6145 next = c->next;
6146 free (c);
6149 for (c = pool->execute; c; c = next)
6151 next = c->next;
6152 free (c);
6155 BITMAP_FREE (pool->insns);
6156 free (pool);
6160 /* Collect main literal pool. Return NULL on overflow. */
6162 static struct constant_pool *
6163 s390_mainpool_start (void)
6165 struct constant_pool *pool;
6166 rtx insn;
6168 pool = s390_alloc_pool ();
6170 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6172 if (GET_CODE (insn) == INSN
6173 && GET_CODE (PATTERN (insn)) == SET
6174 && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC_VOLATILE
6175 && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPECV_MAIN_POOL)
6177 gcc_assert (!pool->pool_insn);
6178 pool->pool_insn = insn;
6181 if (!TARGET_CPU_ZARCH && s390_execute_label (insn))
6183 s390_add_execute (pool, insn);
6185 else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
6187 rtx pool_ref = NULL_RTX;
6188 find_constant_pool_ref (PATTERN (insn), &pool_ref);
6189 if (pool_ref)
6191 rtx constant = get_pool_constant (pool_ref);
6192 enum machine_mode mode = get_pool_mode (pool_ref);
6193 s390_add_constant (pool, constant, mode);
6197 /* If hot/cold partitioning is enabled we have to make sure that
6198 the literal pool is emitted in the same section where the
6199 initialization of the literal pool base pointer takes place.
6200 emit_pool_after is only used in the non-overflow case on non
6201 Z cpus where we can emit the literal pool at the end of the
6202 function body within the text section. */
6203 if (NOTE_P (insn)
6204 && NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS
6205 && !pool->emit_pool_after)
6206 pool->emit_pool_after = PREV_INSN (insn);
6209 gcc_assert (pool->pool_insn || pool->size == 0);
6211 if (pool->size >= 4096)
6213 /* We're going to chunkify the pool, so remove the main
6214 pool placeholder insn. */
6215 remove_insn (pool->pool_insn);
6217 s390_free_pool (pool);
6218 pool = NULL;
6221 /* If the functions ends with the section where the literal pool
6222 should be emitted set the marker to its end. */
6223 if (pool && !pool->emit_pool_after)
6224 pool->emit_pool_after = get_last_insn ();
6226 return pool;
6229 /* POOL holds the main literal pool as collected by s390_mainpool_start.
6230 Modify the current function to output the pool constants as well as
6231 the pool register setup instruction. */
6233 static void
6234 s390_mainpool_finish (struct constant_pool *pool)
6236 rtx base_reg = cfun->machine->base_reg;
6237 rtx insn;
6239 /* If the pool is empty, we're done. */
6240 if (pool->size == 0)
6242 /* We don't actually need a base register after all. */
6243 cfun->machine->base_reg = NULL_RTX;
6245 if (pool->pool_insn)
6246 remove_insn (pool->pool_insn);
6247 s390_free_pool (pool);
6248 return;
6251 /* We need correct insn addresses. */
6252 shorten_branches (get_insns ());
6254 /* On zSeries, we use a LARL to load the pool register. The pool is
6255 located in the .rodata section, so we emit it after the function. */
6256 if (TARGET_CPU_ZARCH)
6258 insn = gen_main_base_64 (base_reg, pool->label);
6259 insn = emit_insn_after (insn, pool->pool_insn);
6260 INSN_ADDRESSES_NEW (insn, -1);
6261 remove_insn (pool->pool_insn);
6263 insn = get_last_insn ();
6264 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
6265 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
6267 s390_dump_pool (pool, 0);
6270 /* On S/390, if the total size of the function's code plus literal pool
6271 does not exceed 4096 bytes, we use BASR to set up a function base
6272 pointer, and emit the literal pool at the end of the function. */
6273 else if (INSN_ADDRESSES (INSN_UID (pool->emit_pool_after))
6274 + pool->size + 8 /* alignment slop */ < 4096)
6276 insn = gen_main_base_31_small (base_reg, pool->label);
6277 insn = emit_insn_after (insn, pool->pool_insn);
6278 INSN_ADDRESSES_NEW (insn, -1);
6279 remove_insn (pool->pool_insn);
6281 insn = emit_label_after (pool->label, insn);
6282 INSN_ADDRESSES_NEW (insn, -1);
6284 /* emit_pool_after will be set by s390_mainpool_start to the
6285 last insn of the section where the literal pool should be
6286 emitted. */
6287 insn = pool->emit_pool_after;
6289 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
6290 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
6292 s390_dump_pool (pool, 1);
6295 /* Otherwise, we emit an inline literal pool and use BASR to branch
6296 over it, setting up the pool register at the same time. */
6297 else
6299 rtx pool_end = gen_label_rtx ();
6301 insn = gen_main_base_31_large (base_reg, pool->label, pool_end);
6302 insn = emit_insn_after (insn, pool->pool_insn);
6303 INSN_ADDRESSES_NEW (insn, -1);
6304 remove_insn (pool->pool_insn);
6306 insn = emit_label_after (pool->label, insn);
6307 INSN_ADDRESSES_NEW (insn, -1);
6309 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
6310 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
6312 insn = emit_label_after (pool_end, pool->pool_insn);
6313 INSN_ADDRESSES_NEW (insn, -1);
6315 s390_dump_pool (pool, 1);
6319 /* Replace all literal pool references. */
6321 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6323 if (INSN_P (insn))
6324 replace_ltrel_base (&PATTERN (insn));
6326 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
6328 rtx addr, pool_ref = NULL_RTX;
6329 find_constant_pool_ref (PATTERN (insn), &pool_ref);
6330 if (pool_ref)
6332 if (s390_execute_label (insn))
6333 addr = s390_find_execute (pool, insn);
6334 else
6335 addr = s390_find_constant (pool, get_pool_constant (pool_ref),
6336 get_pool_mode (pool_ref));
6338 replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
6339 INSN_CODE (insn) = -1;
6345 /* Free the pool. */
6346 s390_free_pool (pool);
6349 /* POOL holds the main literal pool as collected by s390_mainpool_start.
6350 We have decided we cannot use this pool, so revert all changes
6351 to the current function that were done by s390_mainpool_start. */
6352 static void
6353 s390_mainpool_cancel (struct constant_pool *pool)
6355 /* We didn't actually change the instruction stream, so simply
6356 free the pool memory. */
6357 s390_free_pool (pool);
6361 /* Chunkify the literal pool. */
6363 #define S390_POOL_CHUNK_MIN 0xc00
6364 #define S390_POOL_CHUNK_MAX 0xe00
6366 static struct constant_pool *
6367 s390_chunkify_start (void)
6369 struct constant_pool *curr_pool = NULL, *pool_list = NULL;
6370 int extra_size = 0;
6371 bitmap far_labels;
6372 rtx pending_ltrel = NULL_RTX;
6373 rtx insn;
6375 rtx (*gen_reload_base) (rtx, rtx) =
6376 TARGET_CPU_ZARCH? gen_reload_base_64 : gen_reload_base_31;
6379 /* We need correct insn addresses. */
6381 shorten_branches (get_insns ());
6383 /* Scan all insns and move literals to pool chunks. */
6385 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6387 bool section_switch_p = false;
6389 /* Check for pending LTREL_BASE. */
6390 if (INSN_P (insn))
6392 rtx ltrel_base = find_ltrel_base (PATTERN (insn));
6393 if (ltrel_base)
6395 gcc_assert (ltrel_base == pending_ltrel);
6396 pending_ltrel = NULL_RTX;
6400 if (!TARGET_CPU_ZARCH && s390_execute_label (insn))
6402 if (!curr_pool)
6403 curr_pool = s390_start_pool (&pool_list, insn);
6405 s390_add_execute (curr_pool, insn);
6406 s390_add_pool_insn (curr_pool, insn);
6408 else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
6410 rtx pool_ref = NULL_RTX;
6411 find_constant_pool_ref (PATTERN (insn), &pool_ref);
6412 if (pool_ref)
6414 rtx constant = get_pool_constant (pool_ref);
6415 enum machine_mode mode = get_pool_mode (pool_ref);
6417 if (!curr_pool)
6418 curr_pool = s390_start_pool (&pool_list, insn);
6420 s390_add_constant (curr_pool, constant, mode);
6421 s390_add_pool_insn (curr_pool, insn);
6423 /* Don't split the pool chunk between a LTREL_OFFSET load
6424 and the corresponding LTREL_BASE. */
6425 if (GET_CODE (constant) == CONST
6426 && GET_CODE (XEXP (constant, 0)) == UNSPEC
6427 && XINT (XEXP (constant, 0), 1) == UNSPEC_LTREL_OFFSET)
6429 gcc_assert (!pending_ltrel);
6430 pending_ltrel = pool_ref;
6435 if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CODE_LABEL)
6437 if (curr_pool)
6438 s390_add_pool_insn (curr_pool, insn);
6439 /* An LTREL_BASE must follow within the same basic block. */
6440 gcc_assert (!pending_ltrel);
6443 if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS)
6444 section_switch_p = true;
6446 if (!curr_pool
6447 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn)
6448 || INSN_ADDRESSES (INSN_UID (insn)) == -1)
6449 continue;
6451 if (TARGET_CPU_ZARCH)
6453 if (curr_pool->size < S390_POOL_CHUNK_MAX)
6454 continue;
6456 s390_end_pool (curr_pool, NULL_RTX);
6457 curr_pool = NULL;
6459 else
6461 int chunk_size = INSN_ADDRESSES (INSN_UID (insn))
6462 - INSN_ADDRESSES (INSN_UID (curr_pool->first_insn))
6463 + extra_size;
6465 /* We will later have to insert base register reload insns.
6466 Those will have an effect on code size, which we need to
6467 consider here. This calculation makes rather pessimistic
6468 worst-case assumptions. */
6469 if (GET_CODE (insn) == CODE_LABEL)
6470 extra_size += 6;
6472 if (chunk_size < S390_POOL_CHUNK_MIN
6473 && curr_pool->size < S390_POOL_CHUNK_MIN
6474 && !section_switch_p)
6475 continue;
6477 /* Pool chunks can only be inserted after BARRIERs ... */
6478 if (GET_CODE (insn) == BARRIER)
6480 s390_end_pool (curr_pool, insn);
6481 curr_pool = NULL;
6482 extra_size = 0;
6485 /* ... so if we don't find one in time, create one. */
6486 else if (chunk_size > S390_POOL_CHUNK_MAX
6487 || curr_pool->size > S390_POOL_CHUNK_MAX
6488 || section_switch_p)
6490 rtx label, jump, barrier;
6492 if (!section_switch_p)
6494 /* We can insert the barrier only after a 'real' insn. */
6495 if (GET_CODE (insn) != INSN && GET_CODE (insn) != CALL_INSN)
6496 continue;
6497 if (get_attr_length (insn) == 0)
6498 continue;
6499 /* Don't separate LTREL_BASE from the corresponding
6500 LTREL_OFFSET load. */
6501 if (pending_ltrel)
6502 continue;
6504 else
6506 gcc_assert (!pending_ltrel);
6508 /* The old pool has to end before the section switch
6509 note in order to make it part of the current
6510 section. */
6511 insn = PREV_INSN (insn);
6514 label = gen_label_rtx ();
6515 jump = emit_jump_insn_after (gen_jump (label), insn);
6516 barrier = emit_barrier_after (jump);
6517 insn = emit_label_after (label, barrier);
6518 JUMP_LABEL (jump) = label;
6519 LABEL_NUSES (label) = 1;
6521 INSN_ADDRESSES_NEW (jump, -1);
6522 INSN_ADDRESSES_NEW (barrier, -1);
6523 INSN_ADDRESSES_NEW (insn, -1);
6525 s390_end_pool (curr_pool, barrier);
6526 curr_pool = NULL;
6527 extra_size = 0;
6532 if (curr_pool)
6533 s390_end_pool (curr_pool, NULL_RTX);
6534 gcc_assert (!pending_ltrel);
6536 /* Find all labels that are branched into
6537 from an insn belonging to a different chunk. */
6539 far_labels = BITMAP_ALLOC (NULL);
6541 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6543 /* Labels marked with LABEL_PRESERVE_P can be target
6544 of non-local jumps, so we have to mark them.
6545 The same holds for named labels.
6547 Don't do that, however, if it is the label before
6548 a jump table. */
6550 if (GET_CODE (insn) == CODE_LABEL
6551 && (LABEL_PRESERVE_P (insn) || LABEL_NAME (insn)))
6553 rtx vec_insn = next_real_insn (insn);
6554 rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
6555 PATTERN (vec_insn) : NULL_RTX;
6556 if (!vec_pat
6557 || !(GET_CODE (vec_pat) == ADDR_VEC
6558 || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
6559 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (insn));
6562 /* If we have a direct jump (conditional or unconditional)
6563 or a casesi jump, check all potential targets. */
6564 else if (GET_CODE (insn) == JUMP_INSN)
6566 rtx pat = PATTERN (insn);
6567 if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
6568 pat = XVECEXP (pat, 0, 0);
6570 if (GET_CODE (pat) == SET)
6572 rtx label = JUMP_LABEL (insn);
6573 if (label)
6575 if (s390_find_pool (pool_list, label)
6576 != s390_find_pool (pool_list, insn))
6577 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
6580 else if (GET_CODE (pat) == PARALLEL
6581 && XVECLEN (pat, 0) == 2
6582 && GET_CODE (XVECEXP (pat, 0, 0)) == SET
6583 && GET_CODE (XVECEXP (pat, 0, 1)) == USE
6584 && GET_CODE (XEXP (XVECEXP (pat, 0, 1), 0)) == LABEL_REF)
6586 /* Find the jump table used by this casesi jump. */
6587 rtx vec_label = XEXP (XEXP (XVECEXP (pat, 0, 1), 0), 0);
6588 rtx vec_insn = next_real_insn (vec_label);
6589 rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
6590 PATTERN (vec_insn) : NULL_RTX;
6591 if (vec_pat
6592 && (GET_CODE (vec_pat) == ADDR_VEC
6593 || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
6595 int i, diff_p = GET_CODE (vec_pat) == ADDR_DIFF_VEC;
6597 for (i = 0; i < XVECLEN (vec_pat, diff_p); i++)
6599 rtx label = XEXP (XVECEXP (vec_pat, diff_p, i), 0);
6601 if (s390_find_pool (pool_list, label)
6602 != s390_find_pool (pool_list, insn))
6603 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
6610 /* Insert base register reload insns before every pool. */
6612 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
6614 rtx new_insn = gen_reload_base (cfun->machine->base_reg,
6615 curr_pool->label);
6616 rtx insn = curr_pool->first_insn;
6617 INSN_ADDRESSES_NEW (emit_insn_before (new_insn, insn), -1);
6620 /* Insert base register reload insns at every far label. */
6622 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6623 if (GET_CODE (insn) == CODE_LABEL
6624 && bitmap_bit_p (far_labels, CODE_LABEL_NUMBER (insn)))
6626 struct constant_pool *pool = s390_find_pool (pool_list, insn);
6627 if (pool)
6629 rtx new_insn = gen_reload_base (cfun->machine->base_reg,
6630 pool->label);
6631 INSN_ADDRESSES_NEW (emit_insn_after (new_insn, insn), -1);
6636 BITMAP_FREE (far_labels);
6639 /* Recompute insn addresses. */
6641 init_insn_lengths ();
6642 shorten_branches (get_insns ());
6644 return pool_list;
6647 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
6648 After we have decided to use this list, finish implementing
6649 all changes to the current function as required. */
6651 static void
6652 s390_chunkify_finish (struct constant_pool *pool_list)
6654 struct constant_pool *curr_pool = NULL;
6655 rtx insn;
6658 /* Replace all literal pool references. */
6660 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6662 if (INSN_P (insn))
6663 replace_ltrel_base (&PATTERN (insn));
6665 curr_pool = s390_find_pool (pool_list, insn);
6666 if (!curr_pool)
6667 continue;
6669 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
6671 rtx addr, pool_ref = NULL_RTX;
6672 find_constant_pool_ref (PATTERN (insn), &pool_ref);
6673 if (pool_ref)
6675 if (s390_execute_label (insn))
6676 addr = s390_find_execute (curr_pool, insn);
6677 else
6678 addr = s390_find_constant (curr_pool,
6679 get_pool_constant (pool_ref),
6680 get_pool_mode (pool_ref));
6682 replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
6683 INSN_CODE (insn) = -1;
6688 /* Dump out all literal pools. */
6690 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
6691 s390_dump_pool (curr_pool, 0);
6693 /* Free pool list. */
6695 while (pool_list)
6697 struct constant_pool *next = pool_list->next;
6698 s390_free_pool (pool_list);
6699 pool_list = next;
6703 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
6704 We have decided we cannot use this list, so revert all changes
6705 to the current function that were done by s390_chunkify_start. */
6707 static void
6708 s390_chunkify_cancel (struct constant_pool *pool_list)
6710 struct constant_pool *curr_pool = NULL;
6711 rtx insn;
6713 /* Remove all pool placeholder insns. */
6715 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
6717 /* Did we insert an extra barrier? Remove it. */
6718 rtx barrier = PREV_INSN (curr_pool->pool_insn);
6719 rtx jump = barrier? PREV_INSN (barrier) : NULL_RTX;
6720 rtx label = NEXT_INSN (curr_pool->pool_insn);
6722 if (jump && GET_CODE (jump) == JUMP_INSN
6723 && barrier && GET_CODE (barrier) == BARRIER
6724 && label && GET_CODE (label) == CODE_LABEL
6725 && GET_CODE (PATTERN (jump)) == SET
6726 && SET_DEST (PATTERN (jump)) == pc_rtx
6727 && GET_CODE (SET_SRC (PATTERN (jump))) == LABEL_REF
6728 && XEXP (SET_SRC (PATTERN (jump)), 0) == label)
6730 remove_insn (jump);
6731 remove_insn (barrier);
6732 remove_insn (label);
6735 remove_insn (curr_pool->pool_insn);
6738 /* Remove all base register reload insns. */
6740 for (insn = get_insns (); insn; )
6742 rtx next_insn = NEXT_INSN (insn);
6744 if (GET_CODE (insn) == INSN
6745 && GET_CODE (PATTERN (insn)) == SET
6746 && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC
6747 && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPEC_RELOAD_BASE)
6748 remove_insn (insn);
6750 insn = next_insn;
6753 /* Free pool list. */
6755 while (pool_list)
6757 struct constant_pool *next = pool_list->next;
6758 s390_free_pool (pool_list);
6759 pool_list = next;
6763 /* Output the constant pool entry EXP in mode MODE with alignment ALIGN. */
6765 void
6766 s390_output_pool_entry (rtx exp, enum machine_mode mode, unsigned int align)
6768 REAL_VALUE_TYPE r;
6770 switch (GET_MODE_CLASS (mode))
6772 case MODE_FLOAT:
6773 case MODE_DECIMAL_FLOAT:
6774 gcc_assert (GET_CODE (exp) == CONST_DOUBLE);
6776 REAL_VALUE_FROM_CONST_DOUBLE (r, exp);
6777 assemble_real (r, mode, align);
6778 break;
6780 case MODE_INT:
6781 assemble_integer (exp, GET_MODE_SIZE (mode), align, 1);
6782 mark_symbol_refs_as_used (exp);
6783 break;
6785 default:
6786 gcc_unreachable ();
6791 /* Return an RTL expression representing the value of the return address
6792 for the frame COUNT steps up from the current frame. FRAME is the
6793 frame pointer of that frame. */
6796 s390_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
6798 int offset;
6799 rtx addr;
6801 /* Without backchain, we fail for all but the current frame. */
6803 if (!TARGET_BACKCHAIN && count > 0)
6804 return NULL_RTX;
6806 /* For the current frame, we need to make sure the initial
6807 value of RETURN_REGNUM is actually saved. */
6809 if (count == 0)
6811 /* On non-z architectures branch splitting could overwrite r14. */
6812 if (TARGET_CPU_ZARCH)
6813 return get_hard_reg_initial_val (Pmode, RETURN_REGNUM);
6814 else
6816 cfun_frame_layout.save_return_addr_p = true;
6817 return gen_rtx_MEM (Pmode, return_address_pointer_rtx);
6821 if (TARGET_PACKED_STACK)
6822 offset = -2 * UNITS_PER_LONG;
6823 else
6824 offset = RETURN_REGNUM * UNITS_PER_LONG;
6826 addr = plus_constant (frame, offset);
6827 addr = memory_address (Pmode, addr);
6828 return gen_rtx_MEM (Pmode, addr);
6831 /* Return an RTL expression representing the back chain stored in
6832 the current stack frame. */
6835 s390_back_chain_rtx (void)
6837 rtx chain;
6839 gcc_assert (TARGET_BACKCHAIN);
6841 if (TARGET_PACKED_STACK)
6842 chain = plus_constant (stack_pointer_rtx,
6843 STACK_POINTER_OFFSET - UNITS_PER_LONG);
6844 else
6845 chain = stack_pointer_rtx;
6847 chain = gen_rtx_MEM (Pmode, chain);
6848 return chain;
6851 /* Find first call clobbered register unused in a function.
6852 This could be used as base register in a leaf function
6853 or for holding the return address before epilogue. */
6855 static int
6856 find_unused_clobbered_reg (void)
6858 int i;
6859 for (i = 0; i < 6; i++)
6860 if (!df_regs_ever_live_p (i))
6861 return i;
6862 return 0;
6866 /* Helper function for s390_regs_ever_clobbered. Sets the fields in DATA for all
6867 clobbered hard regs in SETREG. */
6869 static void
6870 s390_reg_clobbered_rtx (rtx setreg, const_rtx set_insn ATTRIBUTE_UNUSED, void *data)
6872 int *regs_ever_clobbered = (int *)data;
6873 unsigned int i, regno;
6874 enum machine_mode mode = GET_MODE (setreg);
6876 if (GET_CODE (setreg) == SUBREG)
6878 rtx inner = SUBREG_REG (setreg);
6879 if (!GENERAL_REG_P (inner))
6880 return;
6881 regno = subreg_regno (setreg);
6883 else if (GENERAL_REG_P (setreg))
6884 regno = REGNO (setreg);
6885 else
6886 return;
6888 for (i = regno;
6889 i < regno + HARD_REGNO_NREGS (regno, mode);
6890 i++)
6891 regs_ever_clobbered[i] = 1;
6894 /* Walks through all basic blocks of the current function looking
6895 for clobbered hard regs using s390_reg_clobbered_rtx. The fields
6896 of the passed integer array REGS_EVER_CLOBBERED are set to one for
6897 each of those regs. */
6899 static void
6900 s390_regs_ever_clobbered (int *regs_ever_clobbered)
6902 basic_block cur_bb;
6903 rtx cur_insn;
6904 unsigned int i;
6906 memset (regs_ever_clobbered, 0, 16 * sizeof (int));
6908 /* For non-leaf functions we have to consider all call clobbered regs to be
6909 clobbered. */
6910 if (!current_function_is_leaf)
6912 for (i = 0; i < 16; i++)
6913 regs_ever_clobbered[i] = call_really_used_regs[i];
6916 /* Make the "magic" eh_return registers live if necessary. For regs_ever_live
6917 this work is done by liveness analysis (mark_regs_live_at_end).
6918 Special care is needed for functions containing landing pads. Landing pads
6919 may use the eh registers, but the code which sets these registers is not
6920 contained in that function. Hence s390_regs_ever_clobbered is not able to
6921 deal with this automatically. */
6922 if (crtl->calls_eh_return || cfun->machine->has_landing_pad_p)
6923 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM ; i++)
6924 if (crtl->calls_eh_return
6925 || (cfun->machine->has_landing_pad_p
6926 && df_regs_ever_live_p (EH_RETURN_DATA_REGNO (i))))
6927 regs_ever_clobbered[EH_RETURN_DATA_REGNO (i)] = 1;
6929 /* For nonlocal gotos all call-saved registers have to be saved.
6930 This flag is also set for the unwinding code in libgcc.
6931 See expand_builtin_unwind_init. For regs_ever_live this is done by
6932 reload. */
6933 if (cfun->has_nonlocal_label)
6934 for (i = 0; i < 16; i++)
6935 if (!call_really_used_regs[i])
6936 regs_ever_clobbered[i] = 1;
6938 FOR_EACH_BB (cur_bb)
6940 FOR_BB_INSNS (cur_bb, cur_insn)
6942 if (INSN_P (cur_insn))
6943 note_stores (PATTERN (cur_insn),
6944 s390_reg_clobbered_rtx,
6945 regs_ever_clobbered);
6950 /* Determine the frame area which actually has to be accessed
6951 in the function epilogue. The values are stored at the
6952 given pointers AREA_BOTTOM (address of the lowest used stack
6953 address) and AREA_TOP (address of the first item which does
6954 not belong to the stack frame). */
6956 static void
6957 s390_frame_area (int *area_bottom, int *area_top)
6959 int b, t;
6960 int i;
6962 b = INT_MAX;
6963 t = INT_MIN;
6965 if (cfun_frame_layout.first_restore_gpr != -1)
6967 b = (cfun_frame_layout.gprs_offset
6968 + cfun_frame_layout.first_restore_gpr * UNITS_PER_LONG);
6969 t = b + (cfun_frame_layout.last_restore_gpr
6970 - cfun_frame_layout.first_restore_gpr + 1) * UNITS_PER_LONG;
6973 if (TARGET_64BIT && cfun_save_high_fprs_p)
6975 b = MIN (b, cfun_frame_layout.f8_offset);
6976 t = MAX (t, (cfun_frame_layout.f8_offset
6977 + cfun_frame_layout.high_fprs * 8));
6980 if (!TARGET_64BIT)
6981 for (i = 2; i < 4; i++)
6982 if (cfun_fpr_bit_p (i))
6984 b = MIN (b, cfun_frame_layout.f4_offset + (i - 2) * 8);
6985 t = MAX (t, cfun_frame_layout.f4_offset + (i - 1) * 8);
6988 *area_bottom = b;
6989 *area_top = t;
6992 /* Fill cfun->machine with info about register usage of current function.
6993 Return in CLOBBERED_REGS which GPRs are currently considered set. */
6995 static void
6996 s390_register_info (int clobbered_regs[])
6998 int i, j;
7000 /* fprs 8 - 15 are call saved for 64 Bit ABI. */
7001 cfun_frame_layout.fpr_bitmap = 0;
7002 cfun_frame_layout.high_fprs = 0;
7003 if (TARGET_64BIT)
7004 for (i = 24; i < 32; i++)
7005 if (df_regs_ever_live_p (i) && !global_regs[i])
7007 cfun_set_fpr_bit (i - 16);
7008 cfun_frame_layout.high_fprs++;
7011 /* Find first and last gpr to be saved. We trust regs_ever_live
7012 data, except that we don't save and restore global registers.
7014 Also, all registers with special meaning to the compiler need
7015 to be handled extra. */
7017 s390_regs_ever_clobbered (clobbered_regs);
7019 for (i = 0; i < 16; i++)
7020 clobbered_regs[i] = clobbered_regs[i] && !global_regs[i] && !fixed_regs[i];
7022 if (frame_pointer_needed)
7023 clobbered_regs[HARD_FRAME_POINTER_REGNUM] = 1;
7025 if (flag_pic)
7026 clobbered_regs[PIC_OFFSET_TABLE_REGNUM]
7027 |= df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM);
7029 clobbered_regs[BASE_REGNUM]
7030 |= (cfun->machine->base_reg
7031 && REGNO (cfun->machine->base_reg) == BASE_REGNUM);
7033 clobbered_regs[RETURN_REGNUM]
7034 |= (!current_function_is_leaf
7035 || TARGET_TPF_PROFILING
7036 || cfun->machine->split_branches_pending_p
7037 || cfun_frame_layout.save_return_addr_p
7038 || crtl->calls_eh_return
7039 || cfun->stdarg);
7041 clobbered_regs[STACK_POINTER_REGNUM]
7042 |= (!current_function_is_leaf
7043 || TARGET_TPF_PROFILING
7044 || cfun_save_high_fprs_p
7045 || get_frame_size () > 0
7046 || cfun->calls_alloca
7047 || cfun->stdarg);
7049 for (i = 6; i < 16; i++)
7050 if (df_regs_ever_live_p (i) || clobbered_regs[i])
7051 break;
7052 for (j = 15; j > i; j--)
7053 if (df_regs_ever_live_p (j) || clobbered_regs[j])
7054 break;
7056 if (i == 16)
7058 /* Nothing to save/restore. */
7059 cfun_frame_layout.first_save_gpr_slot = -1;
7060 cfun_frame_layout.last_save_gpr_slot = -1;
7061 cfun_frame_layout.first_save_gpr = -1;
7062 cfun_frame_layout.first_restore_gpr = -1;
7063 cfun_frame_layout.last_save_gpr = -1;
7064 cfun_frame_layout.last_restore_gpr = -1;
7066 else
7068 /* Save slots for gprs from i to j. */
7069 cfun_frame_layout.first_save_gpr_slot = i;
7070 cfun_frame_layout.last_save_gpr_slot = j;
7072 for (i = cfun_frame_layout.first_save_gpr_slot;
7073 i < cfun_frame_layout.last_save_gpr_slot + 1;
7074 i++)
7075 if (clobbered_regs[i])
7076 break;
7078 for (j = cfun_frame_layout.last_save_gpr_slot; j > i; j--)
7079 if (clobbered_regs[j])
7080 break;
7082 if (i == cfun_frame_layout.last_save_gpr_slot + 1)
7084 /* Nothing to save/restore. */
7085 cfun_frame_layout.first_save_gpr = -1;
7086 cfun_frame_layout.first_restore_gpr = -1;
7087 cfun_frame_layout.last_save_gpr = -1;
7088 cfun_frame_layout.last_restore_gpr = -1;
7090 else
7092 /* Save / Restore from gpr i to j. */
7093 cfun_frame_layout.first_save_gpr = i;
7094 cfun_frame_layout.first_restore_gpr = i;
7095 cfun_frame_layout.last_save_gpr = j;
7096 cfun_frame_layout.last_restore_gpr = j;
7100 if (cfun->stdarg)
7102 /* Varargs functions need to save gprs 2 to 6. */
7103 if (cfun->va_list_gpr_size
7104 && crtl->args.info.gprs < GP_ARG_NUM_REG)
7106 int min_gpr = crtl->args.info.gprs;
7107 int max_gpr = min_gpr + cfun->va_list_gpr_size;
7108 if (max_gpr > GP_ARG_NUM_REG)
7109 max_gpr = GP_ARG_NUM_REG;
7111 if (cfun_frame_layout.first_save_gpr == -1
7112 || cfun_frame_layout.first_save_gpr > 2 + min_gpr)
7114 cfun_frame_layout.first_save_gpr = 2 + min_gpr;
7115 cfun_frame_layout.first_save_gpr_slot = 2 + min_gpr;
7118 if (cfun_frame_layout.last_save_gpr == -1
7119 || cfun_frame_layout.last_save_gpr < 2 + max_gpr - 1)
7121 cfun_frame_layout.last_save_gpr = 2 + max_gpr - 1;
7122 cfun_frame_layout.last_save_gpr_slot = 2 + max_gpr - 1;
7126 /* Mark f0, f2 for 31 bit and f0-f4 for 64 bit to be saved. */
7127 if (TARGET_HARD_FLOAT && cfun->va_list_fpr_size
7128 && crtl->args.info.fprs < FP_ARG_NUM_REG)
7130 int min_fpr = crtl->args.info.fprs;
7131 int max_fpr = min_fpr + cfun->va_list_fpr_size;
7132 if (max_fpr > FP_ARG_NUM_REG)
7133 max_fpr = FP_ARG_NUM_REG;
7135 /* ??? This is currently required to ensure proper location
7136 of the fpr save slots within the va_list save area. */
7137 if (TARGET_PACKED_STACK)
7138 min_fpr = 0;
7140 for (i = min_fpr; i < max_fpr; i++)
7141 cfun_set_fpr_bit (i);
7145 if (!TARGET_64BIT)
7146 for (i = 2; i < 4; i++)
7147 if (df_regs_ever_live_p (i + 16) && !global_regs[i + 16])
7148 cfun_set_fpr_bit (i);
7151 /* Fill cfun->machine with info about frame of current function. */
7153 static void
7154 s390_frame_info (void)
7156 int i;
7158 cfun_frame_layout.frame_size = get_frame_size ();
7159 if (!TARGET_64BIT && cfun_frame_layout.frame_size > 0x7fff0000)
7160 fatal_error ("total size of local variables exceeds architecture limit");
7162 if (!TARGET_PACKED_STACK)
7164 cfun_frame_layout.backchain_offset = 0;
7165 cfun_frame_layout.f0_offset = 16 * UNITS_PER_LONG;
7166 cfun_frame_layout.f4_offset = cfun_frame_layout.f0_offset + 2 * 8;
7167 cfun_frame_layout.f8_offset = -cfun_frame_layout.high_fprs * 8;
7168 cfun_frame_layout.gprs_offset = (cfun_frame_layout.first_save_gpr_slot
7169 * UNITS_PER_LONG);
7171 else if (TARGET_BACKCHAIN) /* kernel stack layout */
7173 cfun_frame_layout.backchain_offset = (STACK_POINTER_OFFSET
7174 - UNITS_PER_LONG);
7175 cfun_frame_layout.gprs_offset
7176 = (cfun_frame_layout.backchain_offset
7177 - (STACK_POINTER_REGNUM - cfun_frame_layout.first_save_gpr_slot + 1)
7178 * UNITS_PER_LONG);
7180 if (TARGET_64BIT)
7182 cfun_frame_layout.f4_offset
7183 = (cfun_frame_layout.gprs_offset
7184 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
7186 cfun_frame_layout.f0_offset
7187 = (cfun_frame_layout.f4_offset
7188 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
7190 else
7192 /* On 31 bit we have to care about alignment of the
7193 floating point regs to provide fastest access. */
7194 cfun_frame_layout.f0_offset
7195 = ((cfun_frame_layout.gprs_offset
7196 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1))
7197 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
7199 cfun_frame_layout.f4_offset
7200 = (cfun_frame_layout.f0_offset
7201 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
7204 else /* no backchain */
7206 cfun_frame_layout.f4_offset
7207 = (STACK_POINTER_OFFSET
7208 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
7210 cfun_frame_layout.f0_offset
7211 = (cfun_frame_layout.f4_offset
7212 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
7214 cfun_frame_layout.gprs_offset
7215 = cfun_frame_layout.f0_offset - cfun_gprs_save_area_size;
7218 if (current_function_is_leaf
7219 && !TARGET_TPF_PROFILING
7220 && cfun_frame_layout.frame_size == 0
7221 && !cfun_save_high_fprs_p
7222 && !cfun->calls_alloca
7223 && !cfun->stdarg)
7224 return;
7226 if (!TARGET_PACKED_STACK)
7227 cfun_frame_layout.frame_size += (STACK_POINTER_OFFSET
7228 + crtl->outgoing_args_size
7229 + cfun_frame_layout.high_fprs * 8);
7230 else
7232 if (TARGET_BACKCHAIN)
7233 cfun_frame_layout.frame_size += UNITS_PER_LONG;
7235 /* No alignment trouble here because f8-f15 are only saved under
7236 64 bit. */
7237 cfun_frame_layout.f8_offset = (MIN (MIN (cfun_frame_layout.f0_offset,
7238 cfun_frame_layout.f4_offset),
7239 cfun_frame_layout.gprs_offset)
7240 - cfun_frame_layout.high_fprs * 8);
7242 cfun_frame_layout.frame_size += cfun_frame_layout.high_fprs * 8;
7244 for (i = 0; i < 8; i++)
7245 if (cfun_fpr_bit_p (i))
7246 cfun_frame_layout.frame_size += 8;
7248 cfun_frame_layout.frame_size += cfun_gprs_save_area_size;
7250 /* If under 31 bit an odd number of gprs has to be saved we have to adjust
7251 the frame size to sustain 8 byte alignment of stack frames. */
7252 cfun_frame_layout.frame_size = ((cfun_frame_layout.frame_size +
7253 STACK_BOUNDARY / BITS_PER_UNIT - 1)
7254 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
7256 cfun_frame_layout.frame_size += crtl->outgoing_args_size;
7260 /* Generate frame layout. Fills in register and frame data for the current
7261 function in cfun->machine. This routine can be called multiple times;
7262 it will re-do the complete frame layout every time. */
7264 static void
7265 s390_init_frame_layout (void)
7267 HOST_WIDE_INT frame_size;
7268 int base_used;
7269 int clobbered_regs[16];
7271 /* On S/390 machines, we may need to perform branch splitting, which
7272 will require both base and return address register. We have no
7273 choice but to assume we're going to need them until right at the
7274 end of the machine dependent reorg phase. */
7275 if (!TARGET_CPU_ZARCH)
7276 cfun->machine->split_branches_pending_p = true;
7280 frame_size = cfun_frame_layout.frame_size;
7282 /* Try to predict whether we'll need the base register. */
7283 base_used = cfun->machine->split_branches_pending_p
7284 || crtl->uses_const_pool
7285 || (!DISP_IN_RANGE (frame_size)
7286 && !CONST_OK_FOR_K (frame_size));
7288 /* Decide which register to use as literal pool base. In small
7289 leaf functions, try to use an unused call-clobbered register
7290 as base register to avoid save/restore overhead. */
7291 if (!base_used)
7292 cfun->machine->base_reg = NULL_RTX;
7293 else if (current_function_is_leaf && !df_regs_ever_live_p (5))
7294 cfun->machine->base_reg = gen_rtx_REG (Pmode, 5);
7295 else
7296 cfun->machine->base_reg = gen_rtx_REG (Pmode, BASE_REGNUM);
7298 s390_register_info (clobbered_regs);
7299 s390_frame_info ();
7301 while (frame_size != cfun_frame_layout.frame_size);
7304 /* Update frame layout. Recompute actual register save data based on
7305 current info and update regs_ever_live for the special registers.
7306 May be called multiple times, but may never cause *more* registers
7307 to be saved than s390_init_frame_layout allocated room for. */
7309 static void
7310 s390_update_frame_layout (void)
7312 int clobbered_regs[16];
7314 s390_register_info (clobbered_regs);
7316 df_set_regs_ever_live (BASE_REGNUM,
7317 clobbered_regs[BASE_REGNUM] ? true : false);
7318 df_set_regs_ever_live (RETURN_REGNUM,
7319 clobbered_regs[RETURN_REGNUM] ? true : false);
7320 df_set_regs_ever_live (STACK_POINTER_REGNUM,
7321 clobbered_regs[STACK_POINTER_REGNUM] ? true : false);
7323 if (cfun->machine->base_reg)
7324 df_set_regs_ever_live (REGNO (cfun->machine->base_reg), true);
7327 /* Return true if it is legal to put a value with MODE into REGNO. */
7329 bool
7330 s390_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
7332 switch (REGNO_REG_CLASS (regno))
7334 case FP_REGS:
7335 if (REGNO_PAIR_OK (regno, mode))
7337 if (mode == SImode || mode == DImode)
7338 return true;
7340 if (FLOAT_MODE_P (mode) && GET_MODE_CLASS (mode) != MODE_VECTOR_FLOAT)
7341 return true;
7343 break;
7344 case ADDR_REGS:
7345 if (FRAME_REGNO_P (regno) && mode == Pmode)
7346 return true;
7348 /* fallthrough */
7349 case GENERAL_REGS:
7350 if (REGNO_PAIR_OK (regno, mode))
7352 if (TARGET_ZARCH
7353 || (mode != TFmode && mode != TCmode && mode != TDmode))
7354 return true;
7356 break;
7357 case CC_REGS:
7358 if (GET_MODE_CLASS (mode) == MODE_CC)
7359 return true;
7360 break;
7361 case ACCESS_REGS:
7362 if (REGNO_PAIR_OK (regno, mode))
7364 if (mode == SImode || mode == Pmode)
7365 return true;
7367 break;
7368 default:
7369 return false;
7372 return false;
7375 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
7377 bool
7378 s390_hard_regno_rename_ok (unsigned int old_reg, unsigned int new_reg)
7380 /* Once we've decided upon a register to use as base register, it must
7381 no longer be used for any other purpose. */
7382 if (cfun->machine->base_reg)
7383 if (REGNO (cfun->machine->base_reg) == old_reg
7384 || REGNO (cfun->machine->base_reg) == new_reg)
7385 return false;
7387 return true;
7390 /* Maximum number of registers to represent a value of mode MODE
7391 in a register of class RCLASS. */
7393 bool
7394 s390_class_max_nregs (enum reg_class rclass, enum machine_mode mode)
7396 switch (rclass)
7398 case FP_REGS:
7399 if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
7400 return 2 * ((GET_MODE_SIZE (mode) / 2 + 8 - 1) / 8);
7401 else
7402 return (GET_MODE_SIZE (mode) + 8 - 1) / 8;
7403 case ACCESS_REGS:
7404 return (GET_MODE_SIZE (mode) + 4 - 1) / 4;
7405 default:
7406 break;
7408 return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
7411 /* Return true if register FROM can be eliminated via register TO. */
7413 static bool
7414 s390_can_eliminate (const int from, const int to)
7416 /* On zSeries machines, we have not marked the base register as fixed.
7417 Instead, we have an elimination rule BASE_REGNUM -> BASE_REGNUM.
7418 If a function requires the base register, we say here that this
7419 elimination cannot be performed. This will cause reload to free
7420 up the base register (as if it were fixed). On the other hand,
7421 if the current function does *not* require the base register, we
7422 say here the elimination succeeds, which in turn allows reload
7423 to allocate the base register for any other purpose. */
7424 if (from == BASE_REGNUM && to == BASE_REGNUM)
7426 if (TARGET_CPU_ZARCH)
7428 s390_init_frame_layout ();
7429 return cfun->machine->base_reg == NULL_RTX;
7432 return false;
7435 /* Everything else must point into the stack frame. */
7436 gcc_assert (to == STACK_POINTER_REGNUM
7437 || to == HARD_FRAME_POINTER_REGNUM);
7439 gcc_assert (from == FRAME_POINTER_REGNUM
7440 || from == ARG_POINTER_REGNUM
7441 || from == RETURN_ADDRESS_POINTER_REGNUM);
7443 /* Make sure we actually saved the return address. */
7444 if (from == RETURN_ADDRESS_POINTER_REGNUM)
7445 if (!crtl->calls_eh_return
7446 && !cfun->stdarg
7447 && !cfun_frame_layout.save_return_addr_p)
7448 return false;
7450 return true;
7453 /* Return offset between register FROM and TO initially after prolog. */
7455 HOST_WIDE_INT
7456 s390_initial_elimination_offset (int from, int to)
7458 HOST_WIDE_INT offset;
7459 int index;
7461 /* ??? Why are we called for non-eliminable pairs? */
7462 if (!s390_can_eliminate (from, to))
7463 return 0;
7465 switch (from)
7467 case FRAME_POINTER_REGNUM:
7468 offset = (get_frame_size()
7469 + STACK_POINTER_OFFSET
7470 + crtl->outgoing_args_size);
7471 break;
7473 case ARG_POINTER_REGNUM:
7474 s390_init_frame_layout ();
7475 offset = cfun_frame_layout.frame_size + STACK_POINTER_OFFSET;
7476 break;
7478 case RETURN_ADDRESS_POINTER_REGNUM:
7479 s390_init_frame_layout ();
7480 index = RETURN_REGNUM - cfun_frame_layout.first_save_gpr_slot;
7481 gcc_assert (index >= 0);
7482 offset = cfun_frame_layout.frame_size + cfun_frame_layout.gprs_offset;
7483 offset += index * UNITS_PER_LONG;
7484 break;
7486 case BASE_REGNUM:
7487 offset = 0;
7488 break;
7490 default:
7491 gcc_unreachable ();
7494 return offset;
7497 /* Emit insn to save fpr REGNUM at offset OFFSET relative
7498 to register BASE. Return generated insn. */
7500 static rtx
7501 save_fpr (rtx base, int offset, int regnum)
7503 rtx addr;
7504 addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
7506 if (regnum >= 16 && regnum <= (16 + FP_ARG_NUM_REG))
7507 set_mem_alias_set (addr, get_varargs_alias_set ());
7508 else
7509 set_mem_alias_set (addr, get_frame_alias_set ());
7511 return emit_move_insn (addr, gen_rtx_REG (DFmode, regnum));
7514 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
7515 to register BASE. Return generated insn. */
7517 static rtx
7518 restore_fpr (rtx base, int offset, int regnum)
7520 rtx addr;
7521 addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
7522 set_mem_alias_set (addr, get_frame_alias_set ());
7524 return emit_move_insn (gen_rtx_REG (DFmode, regnum), addr);
7527 /* Return true if REGNO is a global register, but not one
7528 of the special ones that need to be saved/restored in anyway. */
7530 static inline bool
7531 global_not_special_regno_p (int regno)
7533 return (global_regs[regno]
7534 /* These registers are special and need to be
7535 restored in any case. */
7536 && !(regno == STACK_POINTER_REGNUM
7537 || regno == RETURN_REGNUM
7538 || regno == BASE_REGNUM
7539 || (flag_pic && regno == (int)PIC_OFFSET_TABLE_REGNUM)));
7542 /* Generate insn to save registers FIRST to LAST into
7543 the register save area located at offset OFFSET
7544 relative to register BASE. */
7546 static rtx
7547 save_gprs (rtx base, int offset, int first, int last)
7549 rtx addr, insn, note;
7550 int i;
7552 addr = plus_constant (base, offset);
7553 addr = gen_rtx_MEM (Pmode, addr);
7555 set_mem_alias_set (addr, get_frame_alias_set ());
7557 /* Special-case single register. */
7558 if (first == last)
7560 if (TARGET_64BIT)
7561 insn = gen_movdi (addr, gen_rtx_REG (Pmode, first));
7562 else
7563 insn = gen_movsi (addr, gen_rtx_REG (Pmode, first));
7565 if (!global_not_special_regno_p (first))
7566 RTX_FRAME_RELATED_P (insn) = 1;
7567 return insn;
7571 insn = gen_store_multiple (addr,
7572 gen_rtx_REG (Pmode, first),
7573 GEN_INT (last - first + 1));
7575 if (first <= 6 && cfun->stdarg)
7576 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
7578 rtx mem = XEXP (XVECEXP (PATTERN (insn), 0, i), 0);
7580 if (first + i <= 6)
7581 set_mem_alias_set (mem, get_varargs_alias_set ());
7584 /* We need to set the FRAME_RELATED flag on all SETs
7585 inside the store-multiple pattern.
7587 However, we must not emit DWARF records for registers 2..5
7588 if they are stored for use by variable arguments ...
7590 ??? Unfortunately, it is not enough to simply not the
7591 FRAME_RELATED flags for those SETs, because the first SET
7592 of the PARALLEL is always treated as if it had the flag
7593 set, even if it does not. Therefore we emit a new pattern
7594 without those registers as REG_FRAME_RELATED_EXPR note. */
7596 if (first >= 6 && !global_not_special_regno_p (first))
7598 rtx pat = PATTERN (insn);
7600 for (i = 0; i < XVECLEN (pat, 0); i++)
7601 if (GET_CODE (XVECEXP (pat, 0, i)) == SET
7602 && !global_not_special_regno_p (REGNO (SET_SRC (XVECEXP (pat,
7603 0, i)))))
7604 RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1;
7606 RTX_FRAME_RELATED_P (insn) = 1;
7608 else if (last >= 6)
7610 int start;
7612 for (start = first >= 6 ? first : 6; start <= last; start++)
7613 if (!global_not_special_regno_p (start))
7614 break;
7616 if (start > last)
7617 return insn;
7619 addr = plus_constant (base, offset + (start - first) * UNITS_PER_LONG);
7620 note = gen_store_multiple (gen_rtx_MEM (Pmode, addr),
7621 gen_rtx_REG (Pmode, start),
7622 GEN_INT (last - start + 1));
7623 note = PATTERN (note);
7625 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
7627 for (i = 0; i < XVECLEN (note, 0); i++)
7628 if (GET_CODE (XVECEXP (note, 0, i)) == SET
7629 && !global_not_special_regno_p (REGNO (SET_SRC (XVECEXP (note,
7630 0, i)))))
7631 RTX_FRAME_RELATED_P (XVECEXP (note, 0, i)) = 1;
7633 RTX_FRAME_RELATED_P (insn) = 1;
7636 return insn;
7639 /* Generate insn to restore registers FIRST to LAST from
7640 the register save area located at offset OFFSET
7641 relative to register BASE. */
7643 static rtx
7644 restore_gprs (rtx base, int offset, int first, int last)
7646 rtx addr, insn;
7648 addr = plus_constant (base, offset);
7649 addr = gen_rtx_MEM (Pmode, addr);
7650 set_mem_alias_set (addr, get_frame_alias_set ());
7652 /* Special-case single register. */
7653 if (first == last)
7655 if (TARGET_64BIT)
7656 insn = gen_movdi (gen_rtx_REG (Pmode, first), addr);
7657 else
7658 insn = gen_movsi (gen_rtx_REG (Pmode, first), addr);
7660 return insn;
7663 insn = gen_load_multiple (gen_rtx_REG (Pmode, first),
7664 addr,
7665 GEN_INT (last - first + 1));
7666 return insn;
7669 /* Return insn sequence to load the GOT register. */
7671 static GTY(()) rtx got_symbol;
7673 s390_load_got (void)
7675 rtx insns;
7677 if (!got_symbol)
7679 got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
7680 SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
7683 start_sequence ();
7685 if (TARGET_CPU_ZARCH)
7687 emit_move_insn (pic_offset_table_rtx, got_symbol);
7689 else
7691 rtx offset;
7693 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got_symbol),
7694 UNSPEC_LTREL_OFFSET);
7695 offset = gen_rtx_CONST (Pmode, offset);
7696 offset = force_const_mem (Pmode, offset);
7698 emit_move_insn (pic_offset_table_rtx, offset);
7700 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (offset, 0)),
7701 UNSPEC_LTREL_BASE);
7702 offset = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, offset);
7704 emit_move_insn (pic_offset_table_rtx, offset);
7707 insns = get_insns ();
7708 end_sequence ();
7709 return insns;
7712 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
7713 and the change to the stack pointer. */
7715 static void
7716 s390_emit_stack_tie (void)
7718 rtx mem = gen_frame_mem (BLKmode,
7719 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
7721 emit_insn (gen_stack_tie (mem));
7724 /* Expand the prologue into a bunch of separate insns. */
7726 void
7727 s390_emit_prologue (void)
7729 rtx insn, addr;
7730 rtx temp_reg;
7731 int i;
7732 int offset;
7733 int next_fpr = 0;
7735 /* Complete frame layout. */
7737 s390_update_frame_layout ();
7739 /* Annotate all constant pool references to let the scheduler know
7740 they implicitly use the base register. */
7742 push_topmost_sequence ();
7744 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7745 if (INSN_P (insn))
7747 annotate_constant_pool_refs (&PATTERN (insn));
7748 df_insn_rescan (insn);
7751 pop_topmost_sequence ();
7753 /* Choose best register to use for temp use within prologue.
7754 See below for why TPF must use the register 1. */
7756 if (!has_hard_reg_initial_val (Pmode, RETURN_REGNUM)
7757 && !current_function_is_leaf
7758 && !TARGET_TPF_PROFILING)
7759 temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
7760 else
7761 temp_reg = gen_rtx_REG (Pmode, 1);
7763 /* Save call saved gprs. */
7764 if (cfun_frame_layout.first_save_gpr != -1)
7766 insn = save_gprs (stack_pointer_rtx,
7767 cfun_frame_layout.gprs_offset +
7768 UNITS_PER_LONG * (cfun_frame_layout.first_save_gpr
7769 - cfun_frame_layout.first_save_gpr_slot),
7770 cfun_frame_layout.first_save_gpr,
7771 cfun_frame_layout.last_save_gpr);
7772 emit_insn (insn);
7775 /* Dummy insn to mark literal pool slot. */
7777 if (cfun->machine->base_reg)
7778 emit_insn (gen_main_pool (cfun->machine->base_reg));
7780 offset = cfun_frame_layout.f0_offset;
7782 /* Save f0 and f2. */
7783 for (i = 0; i < 2; i++)
7785 if (cfun_fpr_bit_p (i))
7787 save_fpr (stack_pointer_rtx, offset, i + 16);
7788 offset += 8;
7790 else if (!TARGET_PACKED_STACK)
7791 offset += 8;
7794 /* Save f4 and f6. */
7795 offset = cfun_frame_layout.f4_offset;
7796 for (i = 2; i < 4; i++)
7798 if (cfun_fpr_bit_p (i))
7800 insn = save_fpr (stack_pointer_rtx, offset, i + 16);
7801 offset += 8;
7803 /* If f4 and f6 are call clobbered they are saved due to stdargs and
7804 therefore are not frame related. */
7805 if (!call_really_used_regs[i + 16])
7806 RTX_FRAME_RELATED_P (insn) = 1;
7808 else if (!TARGET_PACKED_STACK)
7809 offset += 8;
7812 if (TARGET_PACKED_STACK
7813 && cfun_save_high_fprs_p
7814 && cfun_frame_layout.f8_offset + cfun_frame_layout.high_fprs * 8 > 0)
7816 offset = (cfun_frame_layout.f8_offset
7817 + (cfun_frame_layout.high_fprs - 1) * 8);
7819 for (i = 15; i > 7 && offset >= 0; i--)
7820 if (cfun_fpr_bit_p (i))
7822 insn = save_fpr (stack_pointer_rtx, offset, i + 16);
7824 RTX_FRAME_RELATED_P (insn) = 1;
7825 offset -= 8;
7827 if (offset >= cfun_frame_layout.f8_offset)
7828 next_fpr = i + 16;
7831 if (!TARGET_PACKED_STACK)
7832 next_fpr = cfun_save_high_fprs_p ? 31 : 0;
7834 /* Decrement stack pointer. */
7836 if (cfun_frame_layout.frame_size > 0)
7838 rtx frame_off = GEN_INT (-cfun_frame_layout.frame_size);
7839 rtx real_frame_off;
7841 if (s390_stack_size)
7843 HOST_WIDE_INT stack_guard;
7845 if (s390_stack_guard)
7846 stack_guard = s390_stack_guard;
7847 else
7849 /* If no value for stack guard is provided the smallest power of 2
7850 larger than the current frame size is chosen. */
7851 stack_guard = 1;
7852 while (stack_guard < cfun_frame_layout.frame_size)
7853 stack_guard <<= 1;
7856 if (cfun_frame_layout.frame_size >= s390_stack_size)
7858 warning (0, "frame size of function %qs is "
7859 HOST_WIDE_INT_PRINT_DEC
7860 " bytes exceeding user provided stack limit of "
7861 HOST_WIDE_INT_PRINT_DEC " bytes. "
7862 "An unconditional trap is added.",
7863 current_function_name(), cfun_frame_layout.frame_size,
7864 s390_stack_size);
7865 emit_insn (gen_trap ());
7867 else
7869 /* stack_guard has to be smaller than s390_stack_size.
7870 Otherwise we would emit an AND with zero which would
7871 not match the test under mask pattern. */
7872 if (stack_guard >= s390_stack_size)
7874 warning (0, "frame size of function %qs is "
7875 HOST_WIDE_INT_PRINT_DEC
7876 " bytes which is more than half the stack size. "
7877 "The dynamic check would not be reliable. "
7878 "No check emitted for this function.",
7879 current_function_name(),
7880 cfun_frame_layout.frame_size);
7882 else
7884 HOST_WIDE_INT stack_check_mask = ((s390_stack_size - 1)
7885 & ~(stack_guard - 1));
7887 rtx t = gen_rtx_AND (Pmode, stack_pointer_rtx,
7888 GEN_INT (stack_check_mask));
7889 if (TARGET_64BIT)
7890 emit_insn (gen_ctrapdi4 (gen_rtx_EQ (VOIDmode,
7891 t, const0_rtx),
7892 t, const0_rtx, const0_rtx));
7893 else
7894 emit_insn (gen_ctrapsi4 (gen_rtx_EQ (VOIDmode,
7895 t, const0_rtx),
7896 t, const0_rtx, const0_rtx));
7901 if (s390_warn_framesize > 0
7902 && cfun_frame_layout.frame_size >= s390_warn_framesize)
7903 warning (0, "frame size of %qs is " HOST_WIDE_INT_PRINT_DEC " bytes",
7904 current_function_name (), cfun_frame_layout.frame_size);
7906 if (s390_warn_dynamicstack_p && cfun->calls_alloca)
7907 warning (0, "%qs uses dynamic stack allocation", current_function_name ());
7909 /* Save incoming stack pointer into temp reg. */
7910 if (TARGET_BACKCHAIN || next_fpr)
7911 insn = emit_insn (gen_move_insn (temp_reg, stack_pointer_rtx));
7913 /* Subtract frame size from stack pointer. */
7915 if (DISP_IN_RANGE (INTVAL (frame_off)))
7917 insn = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
7918 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
7919 frame_off));
7920 insn = emit_insn (insn);
7922 else
7924 if (!CONST_OK_FOR_K (INTVAL (frame_off)))
7925 frame_off = force_const_mem (Pmode, frame_off);
7927 insn = emit_insn (gen_add2_insn (stack_pointer_rtx, frame_off));
7928 annotate_constant_pool_refs (&PATTERN (insn));
7931 RTX_FRAME_RELATED_P (insn) = 1;
7932 real_frame_off = GEN_INT (-cfun_frame_layout.frame_size);
7933 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
7934 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
7935 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
7936 real_frame_off)));
7938 /* Set backchain. */
7940 if (TARGET_BACKCHAIN)
7942 if (cfun_frame_layout.backchain_offset)
7943 addr = gen_rtx_MEM (Pmode,
7944 plus_constant (stack_pointer_rtx,
7945 cfun_frame_layout.backchain_offset));
7946 else
7947 addr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
7948 set_mem_alias_set (addr, get_frame_alias_set ());
7949 insn = emit_insn (gen_move_insn (addr, temp_reg));
7952 /* If we support asynchronous exceptions (e.g. for Java),
7953 we need to make sure the backchain pointer is set up
7954 before any possibly trapping memory access. */
7956 if (TARGET_BACKCHAIN && flag_non_call_exceptions)
7958 addr = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
7959 emit_clobber (addr);
7963 /* Save fprs 8 - 15 (64 bit ABI). */
7965 if (cfun_save_high_fprs_p && next_fpr)
7967 /* If the stack might be accessed through a different register
7968 we have to make sure that the stack pointer decrement is not
7969 moved below the use of the stack slots. */
7970 s390_emit_stack_tie ();
7972 insn = emit_insn (gen_add2_insn (temp_reg,
7973 GEN_INT (cfun_frame_layout.f8_offset)));
7975 offset = 0;
7977 for (i = 24; i <= next_fpr; i++)
7978 if (cfun_fpr_bit_p (i - 16))
7980 rtx addr = plus_constant (stack_pointer_rtx,
7981 cfun_frame_layout.frame_size
7982 + cfun_frame_layout.f8_offset
7983 + offset);
7985 insn = save_fpr (temp_reg, offset, i);
7986 offset += 8;
7987 RTX_FRAME_RELATED_P (insn) = 1;
7988 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
7989 gen_rtx_SET (VOIDmode,
7990 gen_rtx_MEM (DFmode, addr),
7991 gen_rtx_REG (DFmode, i)));
7995 /* Set frame pointer, if needed. */
7997 if (frame_pointer_needed)
7999 insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
8000 RTX_FRAME_RELATED_P (insn) = 1;
8003 /* Set up got pointer, if needed. */
8005 if (flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM))
8007 rtx insns = s390_load_got ();
8009 for (insn = insns; insn; insn = NEXT_INSN (insn))
8010 annotate_constant_pool_refs (&PATTERN (insn));
8012 emit_insn (insns);
8015 if (TARGET_TPF_PROFILING)
8017 /* Generate a BAS instruction to serve as a function
8018 entry intercept to facilitate the use of tracing
8019 algorithms located at the branch target. */
8020 emit_insn (gen_prologue_tpf ());
8022 /* Emit a blockage here so that all code
8023 lies between the profiling mechanisms. */
8024 emit_insn (gen_blockage ());
8028 /* Expand the epilogue into a bunch of separate insns. */
8030 void
8031 s390_emit_epilogue (bool sibcall)
8033 rtx frame_pointer, return_reg, cfa_restores = NULL_RTX;
8034 int area_bottom, area_top, offset = 0;
8035 int next_offset;
8036 rtvec p;
8037 int i;
8039 if (TARGET_TPF_PROFILING)
8042 /* Generate a BAS instruction to serve as a function
8043 entry intercept to facilitate the use of tracing
8044 algorithms located at the branch target. */
8046 /* Emit a blockage here so that all code
8047 lies between the profiling mechanisms. */
8048 emit_insn (gen_blockage ());
8050 emit_insn (gen_epilogue_tpf ());
8053 /* Check whether to use frame or stack pointer for restore. */
8055 frame_pointer = (frame_pointer_needed
8056 ? hard_frame_pointer_rtx : stack_pointer_rtx);
8058 s390_frame_area (&area_bottom, &area_top);
8060 /* Check whether we can access the register save area.
8061 If not, increment the frame pointer as required. */
8063 if (area_top <= area_bottom)
8065 /* Nothing to restore. */
8067 else if (DISP_IN_RANGE (cfun_frame_layout.frame_size + area_bottom)
8068 && DISP_IN_RANGE (cfun_frame_layout.frame_size + area_top - 1))
8070 /* Area is in range. */
8071 offset = cfun_frame_layout.frame_size;
8073 else
8075 rtx insn, frame_off, cfa;
8077 offset = area_bottom < 0 ? -area_bottom : 0;
8078 frame_off = GEN_INT (cfun_frame_layout.frame_size - offset);
8080 cfa = gen_rtx_SET (VOIDmode, frame_pointer,
8081 gen_rtx_PLUS (Pmode, frame_pointer, frame_off));
8082 if (DISP_IN_RANGE (INTVAL (frame_off)))
8084 insn = gen_rtx_SET (VOIDmode, frame_pointer,
8085 gen_rtx_PLUS (Pmode, frame_pointer, frame_off));
8086 insn = emit_insn (insn);
8088 else
8090 if (!CONST_OK_FOR_K (INTVAL (frame_off)))
8091 frame_off = force_const_mem (Pmode, frame_off);
8093 insn = emit_insn (gen_add2_insn (frame_pointer, frame_off));
8094 annotate_constant_pool_refs (&PATTERN (insn));
8096 add_reg_note (insn, REG_CFA_ADJUST_CFA, cfa);
8097 RTX_FRAME_RELATED_P (insn) = 1;
8100 /* Restore call saved fprs. */
8102 if (TARGET_64BIT)
8104 if (cfun_save_high_fprs_p)
8106 next_offset = cfun_frame_layout.f8_offset;
8107 for (i = 24; i < 32; i++)
8109 if (cfun_fpr_bit_p (i - 16))
8111 restore_fpr (frame_pointer,
8112 offset + next_offset, i);
8113 cfa_restores
8114 = alloc_reg_note (REG_CFA_RESTORE,
8115 gen_rtx_REG (DFmode, i), cfa_restores);
8116 next_offset += 8;
8122 else
8124 next_offset = cfun_frame_layout.f4_offset;
8125 for (i = 18; i < 20; i++)
8127 if (cfun_fpr_bit_p (i - 16))
8129 restore_fpr (frame_pointer,
8130 offset + next_offset, i);
8131 cfa_restores
8132 = alloc_reg_note (REG_CFA_RESTORE,
8133 gen_rtx_REG (DFmode, i), cfa_restores);
8134 next_offset += 8;
8136 else if (!TARGET_PACKED_STACK)
8137 next_offset += 8;
8142 /* Return register. */
8144 return_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
8146 /* Restore call saved gprs. */
8148 if (cfun_frame_layout.first_restore_gpr != -1)
8150 rtx insn, addr;
8151 int i;
8153 /* Check for global register and save them
8154 to stack location from where they get restored. */
8156 for (i = cfun_frame_layout.first_restore_gpr;
8157 i <= cfun_frame_layout.last_restore_gpr;
8158 i++)
8160 if (global_not_special_regno_p (i))
8162 addr = plus_constant (frame_pointer,
8163 offset + cfun_frame_layout.gprs_offset
8164 + (i - cfun_frame_layout.first_save_gpr_slot)
8165 * UNITS_PER_LONG);
8166 addr = gen_rtx_MEM (Pmode, addr);
8167 set_mem_alias_set (addr, get_frame_alias_set ());
8168 emit_move_insn (addr, gen_rtx_REG (Pmode, i));
8170 else
8171 cfa_restores
8172 = alloc_reg_note (REG_CFA_RESTORE,
8173 gen_rtx_REG (Pmode, i), cfa_restores);
8176 if (! sibcall)
8178 /* Fetch return address from stack before load multiple,
8179 this will do good for scheduling. */
8181 if (cfun_frame_layout.save_return_addr_p
8182 || (cfun_frame_layout.first_restore_gpr < BASE_REGNUM
8183 && cfun_frame_layout.last_restore_gpr > RETURN_REGNUM))
8185 int return_regnum = find_unused_clobbered_reg();
8186 if (!return_regnum)
8187 return_regnum = 4;
8188 return_reg = gen_rtx_REG (Pmode, return_regnum);
8190 addr = plus_constant (frame_pointer,
8191 offset + cfun_frame_layout.gprs_offset
8192 + (RETURN_REGNUM
8193 - cfun_frame_layout.first_save_gpr_slot)
8194 * UNITS_PER_LONG);
8195 addr = gen_rtx_MEM (Pmode, addr);
8196 set_mem_alias_set (addr, get_frame_alias_set ());
8197 emit_move_insn (return_reg, addr);
8201 insn = restore_gprs (frame_pointer,
8202 offset + cfun_frame_layout.gprs_offset
8203 + (cfun_frame_layout.first_restore_gpr
8204 - cfun_frame_layout.first_save_gpr_slot)
8205 * UNITS_PER_LONG,
8206 cfun_frame_layout.first_restore_gpr,
8207 cfun_frame_layout.last_restore_gpr);
8208 insn = emit_insn (insn);
8209 REG_NOTES (insn) = cfa_restores;
8210 add_reg_note (insn, REG_CFA_DEF_CFA,
8211 plus_constant (stack_pointer_rtx, STACK_POINTER_OFFSET));
8212 RTX_FRAME_RELATED_P (insn) = 1;
8215 if (! sibcall)
8218 /* Return to caller. */
8220 p = rtvec_alloc (2);
8222 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
8223 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, return_reg);
8224 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
8229 /* Return the size in bytes of a function argument of
8230 type TYPE and/or mode MODE. At least one of TYPE or
8231 MODE must be specified. */
8233 static int
8234 s390_function_arg_size (enum machine_mode mode, const_tree type)
8236 if (type)
8237 return int_size_in_bytes (type);
8239 /* No type info available for some library calls ... */
8240 if (mode != BLKmode)
8241 return GET_MODE_SIZE (mode);
8243 /* If we have neither type nor mode, abort */
8244 gcc_unreachable ();
8247 /* Return true if a function argument of type TYPE and mode MODE
8248 is to be passed in a floating-point register, if available. */
8250 static bool
8251 s390_function_arg_float (enum machine_mode mode, tree type)
8253 int size = s390_function_arg_size (mode, type);
8254 if (size > 8)
8255 return false;
8257 /* Soft-float changes the ABI: no floating-point registers are used. */
8258 if (TARGET_SOFT_FLOAT)
8259 return false;
8261 /* No type info available for some library calls ... */
8262 if (!type)
8263 return mode == SFmode || mode == DFmode || mode == SDmode || mode == DDmode;
8265 /* The ABI says that record types with a single member are treated
8266 just like that member would be. */
8267 while (TREE_CODE (type) == RECORD_TYPE)
8269 tree field, single = NULL_TREE;
8271 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
8273 if (TREE_CODE (field) != FIELD_DECL)
8274 continue;
8276 if (single == NULL_TREE)
8277 single = TREE_TYPE (field);
8278 else
8279 return false;
8282 if (single == NULL_TREE)
8283 return false;
8284 else
8285 type = single;
8288 return TREE_CODE (type) == REAL_TYPE;
8291 /* Return true if a function argument of type TYPE and mode MODE
8292 is to be passed in an integer register, or a pair of integer
8293 registers, if available. */
8295 static bool
8296 s390_function_arg_integer (enum machine_mode mode, tree type)
8298 int size = s390_function_arg_size (mode, type);
8299 if (size > 8)
8300 return false;
8302 /* No type info available for some library calls ... */
8303 if (!type)
8304 return GET_MODE_CLASS (mode) == MODE_INT
8305 || (TARGET_SOFT_FLOAT && SCALAR_FLOAT_MODE_P (mode));
8307 /* We accept small integral (and similar) types. */
8308 if (INTEGRAL_TYPE_P (type)
8309 || POINTER_TYPE_P (type)
8310 || TREE_CODE (type) == OFFSET_TYPE
8311 || (TARGET_SOFT_FLOAT && TREE_CODE (type) == REAL_TYPE))
8312 return true;
8314 /* We also accept structs of size 1, 2, 4, 8 that are not
8315 passed in floating-point registers. */
8316 if (AGGREGATE_TYPE_P (type)
8317 && exact_log2 (size) >= 0
8318 && !s390_function_arg_float (mode, type))
8319 return true;
8321 return false;
8324 /* Return 1 if a function argument of type TYPE and mode MODE
8325 is to be passed by reference. The ABI specifies that only
8326 structures of size 1, 2, 4, or 8 bytes are passed by value,
8327 all other structures (and complex numbers) are passed by
8328 reference. */
8330 static bool
8331 s390_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
8332 enum machine_mode mode, const_tree type,
8333 bool named ATTRIBUTE_UNUSED)
8335 int size = s390_function_arg_size (mode, type);
8336 if (size > 8)
8337 return true;
8339 if (type)
8341 if (AGGREGATE_TYPE_P (type) && exact_log2 (size) < 0)
8342 return 1;
8344 if (TREE_CODE (type) == COMPLEX_TYPE
8345 || TREE_CODE (type) == VECTOR_TYPE)
8346 return 1;
8349 return 0;
8352 /* Update the data in CUM to advance over an argument of mode MODE and
8353 data type TYPE. (TYPE is null for libcalls where that information
8354 may not be available.). The boolean NAMED specifies whether the
8355 argument is a named argument (as opposed to an unnamed argument
8356 matching an ellipsis). */
8358 void
8359 s390_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8360 tree type, int named ATTRIBUTE_UNUSED)
8362 if (s390_function_arg_float (mode, type))
8364 cum->fprs += 1;
8366 else if (s390_function_arg_integer (mode, type))
8368 int size = s390_function_arg_size (mode, type);
8369 cum->gprs += ((size + UNITS_PER_LONG - 1) / UNITS_PER_LONG);
8371 else
8372 gcc_unreachable ();
8375 /* Define where to put the arguments to a function.
8376 Value is zero to push the argument on the stack,
8377 or a hard register in which to store the argument.
8379 MODE is the argument's machine mode.
8380 TYPE is the data type of the argument (as a tree).
8381 This is null for libcalls where that information may
8382 not be available.
8383 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8384 the preceding args and about the function being called.
8385 NAMED is nonzero if this argument is a named parameter
8386 (otherwise it is an extra parameter matching an ellipsis).
8388 On S/390, we use general purpose registers 2 through 6 to
8389 pass integer, pointer, and certain structure arguments, and
8390 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
8391 to pass floating point arguments. All remaining arguments
8392 are pushed to the stack. */
8395 s390_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
8396 int named ATTRIBUTE_UNUSED)
8398 if (s390_function_arg_float (mode, type))
8400 if (cum->fprs + 1 > FP_ARG_NUM_REG)
8401 return 0;
8402 else
8403 return gen_rtx_REG (mode, cum->fprs + 16);
8405 else if (s390_function_arg_integer (mode, type))
8407 int size = s390_function_arg_size (mode, type);
8408 int n_gprs = (size + UNITS_PER_LONG - 1) / UNITS_PER_LONG;
8410 if (cum->gprs + n_gprs > GP_ARG_NUM_REG)
8411 return 0;
8412 else if (n_gprs == 1 || UNITS_PER_WORD == UNITS_PER_LONG)
8413 return gen_rtx_REG (mode, cum->gprs + 2);
8414 else if (n_gprs == 2)
8416 rtvec p = rtvec_alloc (2);
8418 RTVEC_ELT (p, 0)
8419 = gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, cum->gprs + 2),
8420 const0_rtx);
8421 RTVEC_ELT (p, 1)
8422 = gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, cum->gprs + 3),
8423 GEN_INT (4));
8425 return gen_rtx_PARALLEL (mode, p);
8429 /* After the real arguments, expand_call calls us once again
8430 with a void_type_node type. Whatever we return here is
8431 passed as operand 2 to the call expanders.
8433 We don't need this feature ... */
8434 else if (type == void_type_node)
8435 return const0_rtx;
8437 gcc_unreachable ();
8440 /* Return true if return values of type TYPE should be returned
8441 in a memory buffer whose address is passed by the caller as
8442 hidden first argument. */
8444 static bool
8445 s390_return_in_memory (const_tree type, const_tree fundecl ATTRIBUTE_UNUSED)
8447 /* We accept small integral (and similar) types. */
8448 if (INTEGRAL_TYPE_P (type)
8449 || POINTER_TYPE_P (type)
8450 || TREE_CODE (type) == OFFSET_TYPE
8451 || TREE_CODE (type) == REAL_TYPE)
8452 return int_size_in_bytes (type) > 8;
8454 /* Aggregates and similar constructs are always returned
8455 in memory. */
8456 if (AGGREGATE_TYPE_P (type)
8457 || TREE_CODE (type) == COMPLEX_TYPE
8458 || TREE_CODE (type) == VECTOR_TYPE)
8459 return true;
8461 /* ??? We get called on all sorts of random stuff from
8462 aggregate_value_p. We can't abort, but it's not clear
8463 what's safe to return. Pretend it's a struct I guess. */
8464 return true;
8467 /* Function arguments and return values are promoted to word size. */
8469 static enum machine_mode
8470 s390_promote_function_mode (const_tree type, enum machine_mode mode,
8471 int *punsignedp,
8472 const_tree fntype ATTRIBUTE_UNUSED,
8473 int for_return ATTRIBUTE_UNUSED)
8475 if (INTEGRAL_MODE_P (mode)
8476 && GET_MODE_SIZE (mode) < UNITS_PER_LONG)
8478 if (POINTER_TYPE_P (type))
8479 *punsignedp = POINTERS_EXTEND_UNSIGNED;
8480 return Pmode;
8483 return mode;
8486 /* Define where to return a (scalar) value of type TYPE.
8487 If TYPE is null, define where to return a (scalar)
8488 value of mode MODE from a libcall. */
8491 s390_function_value (const_tree type, const_tree fn, enum machine_mode mode)
8493 if (type)
8495 int unsignedp = TYPE_UNSIGNED (type);
8496 mode = promote_function_mode (type, TYPE_MODE (type), &unsignedp, fn, 1);
8499 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT || SCALAR_FLOAT_MODE_P (mode));
8500 gcc_assert (GET_MODE_SIZE (mode) <= 8);
8502 if (TARGET_HARD_FLOAT && SCALAR_FLOAT_MODE_P (mode))
8503 return gen_rtx_REG (mode, 16);
8504 else if (GET_MODE_SIZE (mode) <= UNITS_PER_LONG
8505 || UNITS_PER_LONG == UNITS_PER_WORD)
8506 return gen_rtx_REG (mode, 2);
8507 else if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_LONG)
8509 rtvec p = rtvec_alloc (2);
8511 RTVEC_ELT (p, 0)
8512 = gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, 2), const0_rtx);
8513 RTVEC_ELT (p, 1)
8514 = gen_rtx_EXPR_LIST (SImode, gen_rtx_REG (SImode, 3), GEN_INT (4));
8516 return gen_rtx_PARALLEL (mode, p);
8519 gcc_unreachable ();
8523 /* Create and return the va_list datatype.
8525 On S/390, va_list is an array type equivalent to
8527 typedef struct __va_list_tag
8529 long __gpr;
8530 long __fpr;
8531 void *__overflow_arg_area;
8532 void *__reg_save_area;
8533 } va_list[1];
8535 where __gpr and __fpr hold the number of general purpose
8536 or floating point arguments used up to now, respectively,
8537 __overflow_arg_area points to the stack location of the
8538 next argument passed on the stack, and __reg_save_area
8539 always points to the start of the register area in the
8540 call frame of the current function. The function prologue
8541 saves all registers used for argument passing into this
8542 area if the function uses variable arguments. */
8544 static tree
8545 s390_build_builtin_va_list (void)
8547 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
8549 record = lang_hooks.types.make_type (RECORD_TYPE);
8551 type_decl =
8552 build_decl (BUILTINS_LOCATION,
8553 TYPE_DECL, get_identifier ("__va_list_tag"), record);
8555 f_gpr = build_decl (BUILTINS_LOCATION,
8556 FIELD_DECL, get_identifier ("__gpr"),
8557 long_integer_type_node);
8558 f_fpr = build_decl (BUILTINS_LOCATION,
8559 FIELD_DECL, get_identifier ("__fpr"),
8560 long_integer_type_node);
8561 f_ovf = build_decl (BUILTINS_LOCATION,
8562 FIELD_DECL, get_identifier ("__overflow_arg_area"),
8563 ptr_type_node);
8564 f_sav = build_decl (BUILTINS_LOCATION,
8565 FIELD_DECL, get_identifier ("__reg_save_area"),
8566 ptr_type_node);
8568 va_list_gpr_counter_field = f_gpr;
8569 va_list_fpr_counter_field = f_fpr;
8571 DECL_FIELD_CONTEXT (f_gpr) = record;
8572 DECL_FIELD_CONTEXT (f_fpr) = record;
8573 DECL_FIELD_CONTEXT (f_ovf) = record;
8574 DECL_FIELD_CONTEXT (f_sav) = record;
8576 TREE_CHAIN (record) = type_decl;
8577 TYPE_NAME (record) = type_decl;
8578 TYPE_FIELDS (record) = f_gpr;
8579 TREE_CHAIN (f_gpr) = f_fpr;
8580 TREE_CHAIN (f_fpr) = f_ovf;
8581 TREE_CHAIN (f_ovf) = f_sav;
8583 layout_type (record);
8585 /* The correct type is an array type of one element. */
8586 return build_array_type (record, build_index_type (size_zero_node));
8589 /* Implement va_start by filling the va_list structure VALIST.
8590 STDARG_P is always true, and ignored.
8591 NEXTARG points to the first anonymous stack argument.
8593 The following global variables are used to initialize
8594 the va_list structure:
8596 crtl->args.info:
8597 holds number of gprs and fprs used for named arguments.
8598 crtl->args.arg_offset_rtx:
8599 holds the offset of the first anonymous stack argument
8600 (relative to the virtual arg pointer). */
8602 static void
8603 s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
8605 HOST_WIDE_INT n_gpr, n_fpr;
8606 int off;
8607 tree f_gpr, f_fpr, f_ovf, f_sav;
8608 tree gpr, fpr, ovf, sav, t;
8610 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8611 f_fpr = TREE_CHAIN (f_gpr);
8612 f_ovf = TREE_CHAIN (f_fpr);
8613 f_sav = TREE_CHAIN (f_ovf);
8615 valist = build_va_arg_indirect_ref (valist);
8616 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8617 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
8618 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
8619 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
8621 /* Count number of gp and fp argument registers used. */
8623 n_gpr = crtl->args.info.gprs;
8624 n_fpr = crtl->args.info.fprs;
8626 if (cfun->va_list_gpr_size)
8628 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
8629 build_int_cst (NULL_TREE, n_gpr));
8630 TREE_SIDE_EFFECTS (t) = 1;
8631 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8634 if (cfun->va_list_fpr_size)
8636 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
8637 build_int_cst (NULL_TREE, n_fpr));
8638 TREE_SIDE_EFFECTS (t) = 1;
8639 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8642 /* Find the overflow area. */
8643 if (n_gpr + cfun->va_list_gpr_size > GP_ARG_NUM_REG
8644 || n_fpr + cfun->va_list_fpr_size > FP_ARG_NUM_REG)
8646 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
8648 off = INTVAL (crtl->args.arg_offset_rtx);
8649 off = off < 0 ? 0 : off;
8650 if (TARGET_DEBUG_ARG)
8651 fprintf (stderr, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
8652 (int)n_gpr, (int)n_fpr, off);
8654 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t, size_int (off));
8656 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
8657 TREE_SIDE_EFFECTS (t) = 1;
8658 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8661 /* Find the register save area. */
8662 if ((cfun->va_list_gpr_size && n_gpr < GP_ARG_NUM_REG)
8663 || (cfun->va_list_fpr_size && n_fpr < FP_ARG_NUM_REG))
8665 t = make_tree (TREE_TYPE (sav), return_address_pointer_rtx);
8666 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
8667 size_int (-RETURN_REGNUM * UNITS_PER_LONG));
8669 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
8670 TREE_SIDE_EFFECTS (t) = 1;
8671 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8675 /* Implement va_arg by updating the va_list structure
8676 VALIST as required to retrieve an argument of type
8677 TYPE, and returning that argument.
8679 Generates code equivalent to:
8681 if (integral value) {
8682 if (size <= 4 && args.gpr < 5 ||
8683 size > 4 && args.gpr < 4 )
8684 ret = args.reg_save_area[args.gpr+8]
8685 else
8686 ret = *args.overflow_arg_area++;
8687 } else if (float value) {
8688 if (args.fgpr < 2)
8689 ret = args.reg_save_area[args.fpr+64]
8690 else
8691 ret = *args.overflow_arg_area++;
8692 } else if (aggregate value) {
8693 if (args.gpr < 5)
8694 ret = *args.reg_save_area[args.gpr]
8695 else
8696 ret = **args.overflow_arg_area++;
8697 } */
8699 static tree
8700 s390_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
8701 gimple_seq *post_p ATTRIBUTE_UNUSED)
8703 tree f_gpr, f_fpr, f_ovf, f_sav;
8704 tree gpr, fpr, ovf, sav, reg, t, u;
8705 int indirect_p, size, n_reg, sav_ofs, sav_scale, max_reg;
8706 tree lab_false, lab_over, addr;
8708 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8709 f_fpr = TREE_CHAIN (f_gpr);
8710 f_ovf = TREE_CHAIN (f_fpr);
8711 f_sav = TREE_CHAIN (f_ovf);
8713 valist = build_va_arg_indirect_ref (valist);
8714 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8715 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
8716 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
8718 /* The tree for args* cannot be shared between gpr/fpr and ovf since
8719 both appear on a lhs. */
8720 valist = unshare_expr (valist);
8721 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
8723 size = int_size_in_bytes (type);
8725 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8727 if (TARGET_DEBUG_ARG)
8729 fprintf (stderr, "va_arg: aggregate type");
8730 debug_tree (type);
8733 /* Aggregates are passed by reference. */
8734 indirect_p = 1;
8735 reg = gpr;
8736 n_reg = 1;
8738 /* kernel stack layout on 31 bit: It is assumed here that no padding
8739 will be added by s390_frame_info because for va_args always an even
8740 number of gprs has to be saved r15-r2 = 14 regs. */
8741 sav_ofs = 2 * UNITS_PER_LONG;
8742 sav_scale = UNITS_PER_LONG;
8743 size = UNITS_PER_LONG;
8744 max_reg = GP_ARG_NUM_REG - n_reg;
8746 else if (s390_function_arg_float (TYPE_MODE (type), type))
8748 if (TARGET_DEBUG_ARG)
8750 fprintf (stderr, "va_arg: float type");
8751 debug_tree (type);
8754 /* FP args go in FP registers, if present. */
8755 indirect_p = 0;
8756 reg = fpr;
8757 n_reg = 1;
8758 sav_ofs = 16 * UNITS_PER_LONG;
8759 sav_scale = 8;
8760 max_reg = FP_ARG_NUM_REG - n_reg;
8762 else
8764 if (TARGET_DEBUG_ARG)
8766 fprintf (stderr, "va_arg: other type");
8767 debug_tree (type);
8770 /* Otherwise into GP registers. */
8771 indirect_p = 0;
8772 reg = gpr;
8773 n_reg = (size + UNITS_PER_LONG - 1) / UNITS_PER_LONG;
8775 /* kernel stack layout on 31 bit: It is assumed here that no padding
8776 will be added by s390_frame_info because for va_args always an even
8777 number of gprs has to be saved r15-r2 = 14 regs. */
8778 sav_ofs = 2 * UNITS_PER_LONG;
8780 if (size < UNITS_PER_LONG)
8781 sav_ofs += UNITS_PER_LONG - size;
8783 sav_scale = UNITS_PER_LONG;
8784 max_reg = GP_ARG_NUM_REG - n_reg;
8787 /* Pull the value out of the saved registers ... */
8789 lab_false = create_artificial_label (UNKNOWN_LOCATION);
8790 lab_over = create_artificial_label (UNKNOWN_LOCATION);
8791 addr = create_tmp_var (ptr_type_node, "addr");
8793 t = fold_convert (TREE_TYPE (reg), size_int (max_reg));
8794 t = build2 (GT_EXPR, boolean_type_node, reg, t);
8795 u = build1 (GOTO_EXPR, void_type_node, lab_false);
8796 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
8797 gimplify_and_add (t, pre_p);
8799 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav,
8800 size_int (sav_ofs));
8801 u = build2 (MULT_EXPR, TREE_TYPE (reg), reg,
8802 fold_convert (TREE_TYPE (reg), size_int (sav_scale)));
8803 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, fold_convert (sizetype, u));
8805 gimplify_assign (addr, t, pre_p);
8807 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
8809 gimple_seq_add_stmt (pre_p, gimple_build_label (lab_false));
8812 /* ... Otherwise out of the overflow area. */
8814 t = ovf;
8815 if (size < UNITS_PER_LONG)
8816 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t,
8817 size_int (UNITS_PER_LONG - size));
8819 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
8821 gimplify_assign (addr, t, pre_p);
8823 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t,
8824 size_int (size));
8825 gimplify_assign (ovf, t, pre_p);
8827 gimple_seq_add_stmt (pre_p, gimple_build_label (lab_over));
8830 /* Increment register save count. */
8832 u = build2 (PREINCREMENT_EXPR, TREE_TYPE (reg), reg,
8833 fold_convert (TREE_TYPE (reg), size_int (n_reg)));
8834 gimplify_and_add (u, pre_p);
8836 if (indirect_p)
8838 t = build_pointer_type_for_mode (build_pointer_type (type),
8839 ptr_mode, true);
8840 addr = fold_convert (t, addr);
8841 addr = build_va_arg_indirect_ref (addr);
8843 else
8845 t = build_pointer_type_for_mode (type, ptr_mode, true);
8846 addr = fold_convert (t, addr);
8849 return build_va_arg_indirect_ref (addr);
8853 /* Builtins. */
8855 enum s390_builtin
8857 S390_BUILTIN_THREAD_POINTER,
8858 S390_BUILTIN_SET_THREAD_POINTER,
8860 S390_BUILTIN_max
8863 static enum insn_code const code_for_builtin_64[S390_BUILTIN_max] = {
8864 CODE_FOR_get_tp_64,
8865 CODE_FOR_set_tp_64
8868 static enum insn_code const code_for_builtin_31[S390_BUILTIN_max] = {
8869 CODE_FOR_get_tp_31,
8870 CODE_FOR_set_tp_31
8873 static void
8874 s390_init_builtins (void)
8876 tree ftype;
8878 ftype = build_function_type (ptr_type_node, void_list_node);
8879 add_builtin_function ("__builtin_thread_pointer", ftype,
8880 S390_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
8881 NULL, NULL_TREE);
8883 ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
8884 add_builtin_function ("__builtin_set_thread_pointer", ftype,
8885 S390_BUILTIN_SET_THREAD_POINTER, BUILT_IN_MD,
8886 NULL, NULL_TREE);
8889 /* Expand an expression EXP that calls a built-in function,
8890 with result going to TARGET if that's convenient
8891 (and in mode MODE if that's convenient).
8892 SUBTARGET may be used as the target for computing one of EXP's operands.
8893 IGNORE is nonzero if the value is to be ignored. */
8895 static rtx
8896 s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
8897 enum machine_mode mode ATTRIBUTE_UNUSED,
8898 int ignore ATTRIBUTE_UNUSED)
8900 #define MAX_ARGS 2
8902 enum insn_code const *code_for_builtin =
8903 TARGET_64BIT ? code_for_builtin_64 : code_for_builtin_31;
8905 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
8906 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
8907 enum insn_code icode;
8908 rtx op[MAX_ARGS], pat;
8909 int arity;
8910 bool nonvoid;
8911 tree arg;
8912 call_expr_arg_iterator iter;
8914 if (fcode >= S390_BUILTIN_max)
8915 internal_error ("bad builtin fcode");
8916 icode = code_for_builtin[fcode];
8917 if (icode == 0)
8918 internal_error ("bad builtin fcode");
8920 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
8922 arity = 0;
8923 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
8925 const struct insn_operand_data *insn_op;
8927 if (arg == error_mark_node)
8928 return NULL_RTX;
8929 if (arity > MAX_ARGS)
8930 return NULL_RTX;
8932 insn_op = &insn_data[icode].operand[arity + nonvoid];
8934 op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, EXPAND_NORMAL);
8936 if (!(*insn_op->predicate) (op[arity], insn_op->mode))
8937 op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
8938 arity++;
8941 if (nonvoid)
8943 enum machine_mode tmode = insn_data[icode].operand[0].mode;
8944 if (!target
8945 || GET_MODE (target) != tmode
8946 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
8947 target = gen_reg_rtx (tmode);
8950 switch (arity)
8952 case 0:
8953 pat = GEN_FCN (icode) (target);
8954 break;
8955 case 1:
8956 if (nonvoid)
8957 pat = GEN_FCN (icode) (target, op[0]);
8958 else
8959 pat = GEN_FCN (icode) (op[0]);
8960 break;
8961 case 2:
8962 pat = GEN_FCN (icode) (target, op[0], op[1]);
8963 break;
8964 default:
8965 gcc_unreachable ();
8967 if (!pat)
8968 return NULL_RTX;
8969 emit_insn (pat);
8971 if (nonvoid)
8972 return target;
8973 else
8974 return const0_rtx;
8978 /* Output assembly code for the trampoline template to
8979 stdio stream FILE.
8981 On S/390, we use gpr 1 internally in the trampoline code;
8982 gpr 0 is used to hold the static chain. */
8984 static void
8985 s390_asm_trampoline_template (FILE *file)
8987 rtx op[2];
8988 op[0] = gen_rtx_REG (Pmode, 0);
8989 op[1] = gen_rtx_REG (Pmode, 1);
8991 if (TARGET_64BIT)
8993 output_asm_insn ("basr\t%1,0", op);
8994 output_asm_insn ("lmg\t%0,%1,14(%1)", op);
8995 output_asm_insn ("br\t%1", op);
8996 ASM_OUTPUT_SKIP (file, (HOST_WIDE_INT)(TRAMPOLINE_SIZE - 10));
8998 else
9000 output_asm_insn ("basr\t%1,0", op);
9001 output_asm_insn ("lm\t%0,%1,6(%1)", op);
9002 output_asm_insn ("br\t%1", op);
9003 ASM_OUTPUT_SKIP (file, (HOST_WIDE_INT)(TRAMPOLINE_SIZE - 8));
9007 /* Emit RTL insns to initialize the variable parts of a trampoline.
9008 FNADDR is an RTX for the address of the function's pure code.
9009 CXT is an RTX for the static chain value for the function. */
9011 static void
9012 s390_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
9014 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
9015 rtx mem;
9017 emit_block_move (m_tramp, assemble_trampoline_template (),
9018 GEN_INT (2*UNITS_PER_WORD), BLOCK_OP_NORMAL);
9020 mem = adjust_address (m_tramp, Pmode, 2*UNITS_PER_WORD);
9021 emit_move_insn (mem, cxt);
9022 mem = adjust_address (m_tramp, Pmode, 3*UNITS_PER_WORD);
9023 emit_move_insn (mem, fnaddr);
9026 /* Output assembler code to FILE to increment profiler label # LABELNO
9027 for profiling a function entry. */
9029 void
9030 s390_function_profiler (FILE *file, int labelno)
9032 rtx op[7];
9034 char label[128];
9035 ASM_GENERATE_INTERNAL_LABEL (label, "LP", labelno);
9037 fprintf (file, "# function profiler \n");
9039 op[0] = gen_rtx_REG (Pmode, RETURN_REGNUM);
9040 op[1] = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
9041 op[1] = gen_rtx_MEM (Pmode, plus_constant (op[1], UNITS_PER_LONG));
9043 op[2] = gen_rtx_REG (Pmode, 1);
9044 op[3] = gen_rtx_SYMBOL_REF (Pmode, label);
9045 SYMBOL_REF_FLAGS (op[3]) = SYMBOL_FLAG_LOCAL;
9047 op[4] = gen_rtx_SYMBOL_REF (Pmode, "_mcount");
9048 if (flag_pic)
9050 op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), UNSPEC_PLT);
9051 op[4] = gen_rtx_CONST (Pmode, op[4]);
9054 if (TARGET_64BIT)
9056 output_asm_insn ("stg\t%0,%1", op);
9057 output_asm_insn ("larl\t%2,%3", op);
9058 output_asm_insn ("brasl\t%0,%4", op);
9059 output_asm_insn ("lg\t%0,%1", op);
9061 else if (!flag_pic)
9063 op[6] = gen_label_rtx ();
9065 output_asm_insn ("st\t%0,%1", op);
9066 output_asm_insn ("bras\t%2,%l6", op);
9067 output_asm_insn (".long\t%4", op);
9068 output_asm_insn (".long\t%3", op);
9069 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
9070 output_asm_insn ("l\t%0,0(%2)", op);
9071 output_asm_insn ("l\t%2,4(%2)", op);
9072 output_asm_insn ("basr\t%0,%0", op);
9073 output_asm_insn ("l\t%0,%1", op);
9075 else
9077 op[5] = gen_label_rtx ();
9078 op[6] = gen_label_rtx ();
9080 output_asm_insn ("st\t%0,%1", op);
9081 output_asm_insn ("bras\t%2,%l6", op);
9082 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[5]));
9083 output_asm_insn (".long\t%4-%l5", op);
9084 output_asm_insn (".long\t%3-%l5", op);
9085 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
9086 output_asm_insn ("lr\t%0,%2", op);
9087 output_asm_insn ("a\t%0,0(%2)", op);
9088 output_asm_insn ("a\t%2,4(%2)", op);
9089 output_asm_insn ("basr\t%0,%0", op);
9090 output_asm_insn ("l\t%0,%1", op);
9094 /* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
9095 into its SYMBOL_REF_FLAGS. */
9097 static void
9098 s390_encode_section_info (tree decl, rtx rtl, int first)
9100 default_encode_section_info (decl, rtl, first);
9102 if (TREE_CODE (decl) == VAR_DECL)
9104 /* If a variable has a forced alignment to < 2 bytes, mark it
9105 with SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL
9106 operand. */
9107 if (DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) < 16)
9108 SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_ALIGN1;
9109 if (!DECL_SIZE (decl)
9110 || !DECL_ALIGN (decl)
9111 || !host_integerp (DECL_SIZE (decl), 0)
9112 || (DECL_ALIGN (decl) <= 64
9113 && DECL_ALIGN (decl) != tree_low_cst (DECL_SIZE (decl), 0)))
9114 SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_NOT_NATURALLY_ALIGNED;
9117 /* Literal pool references don't have a decl so they are handled
9118 differently here. We rely on the information in the MEM_ALIGN
9119 entry to decide upon natural alignment. */
9120 if (MEM_P (rtl)
9121 && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF
9122 && TREE_CONSTANT_POOL_ADDRESS_P (XEXP (rtl, 0))
9123 && (MEM_ALIGN (rtl) == 0
9124 || GET_MODE_BITSIZE (GET_MODE (rtl)) == 0
9125 || MEM_ALIGN (rtl) < GET_MODE_BITSIZE (GET_MODE (rtl))))
9126 SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_NOT_NATURALLY_ALIGNED;
9129 /* Output thunk to FILE that implements a C++ virtual function call (with
9130 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
9131 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
9132 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
9133 relative to the resulting this pointer. */
9135 static void
9136 s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
9137 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
9138 tree function)
9140 rtx op[10];
9141 int nonlocal = 0;
9143 /* Make sure unwind info is emitted for the thunk if needed. */
9144 final_start_function (emit_barrier (), file, 1);
9146 /* Operand 0 is the target function. */
9147 op[0] = XEXP (DECL_RTL (function), 0);
9148 if (flag_pic && !SYMBOL_REF_LOCAL_P (op[0]))
9150 nonlocal = 1;
9151 op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]),
9152 TARGET_64BIT ? UNSPEC_PLT : UNSPEC_GOT);
9153 op[0] = gen_rtx_CONST (Pmode, op[0]);
9156 /* Operand 1 is the 'this' pointer. */
9157 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
9158 op[1] = gen_rtx_REG (Pmode, 3);
9159 else
9160 op[1] = gen_rtx_REG (Pmode, 2);
9162 /* Operand 2 is the delta. */
9163 op[2] = GEN_INT (delta);
9165 /* Operand 3 is the vcall_offset. */
9166 op[3] = GEN_INT (vcall_offset);
9168 /* Operand 4 is the temporary register. */
9169 op[4] = gen_rtx_REG (Pmode, 1);
9171 /* Operands 5 to 8 can be used as labels. */
9172 op[5] = NULL_RTX;
9173 op[6] = NULL_RTX;
9174 op[7] = NULL_RTX;
9175 op[8] = NULL_RTX;
9177 /* Operand 9 can be used for temporary register. */
9178 op[9] = NULL_RTX;
9180 /* Generate code. */
9181 if (TARGET_64BIT)
9183 /* Setup literal pool pointer if required. */
9184 if ((!DISP_IN_RANGE (delta)
9185 && !CONST_OK_FOR_K (delta)
9186 && !CONST_OK_FOR_Os (delta))
9187 || (!DISP_IN_RANGE (vcall_offset)
9188 && !CONST_OK_FOR_K (vcall_offset)
9189 && !CONST_OK_FOR_Os (vcall_offset)))
9191 op[5] = gen_label_rtx ();
9192 output_asm_insn ("larl\t%4,%5", op);
9195 /* Add DELTA to this pointer. */
9196 if (delta)
9198 if (CONST_OK_FOR_J (delta))
9199 output_asm_insn ("la\t%1,%2(%1)", op);
9200 else if (DISP_IN_RANGE (delta))
9201 output_asm_insn ("lay\t%1,%2(%1)", op);
9202 else if (CONST_OK_FOR_K (delta))
9203 output_asm_insn ("aghi\t%1,%2", op);
9204 else if (CONST_OK_FOR_Os (delta))
9205 output_asm_insn ("agfi\t%1,%2", op);
9206 else
9208 op[6] = gen_label_rtx ();
9209 output_asm_insn ("agf\t%1,%6-%5(%4)", op);
9213 /* Perform vcall adjustment. */
9214 if (vcall_offset)
9216 if (DISP_IN_RANGE (vcall_offset))
9218 output_asm_insn ("lg\t%4,0(%1)", op);
9219 output_asm_insn ("ag\t%1,%3(%4)", op);
9221 else if (CONST_OK_FOR_K (vcall_offset))
9223 output_asm_insn ("lghi\t%4,%3", op);
9224 output_asm_insn ("ag\t%4,0(%1)", op);
9225 output_asm_insn ("ag\t%1,0(%4)", op);
9227 else if (CONST_OK_FOR_Os (vcall_offset))
9229 output_asm_insn ("lgfi\t%4,%3", op);
9230 output_asm_insn ("ag\t%4,0(%1)", op);
9231 output_asm_insn ("ag\t%1,0(%4)", op);
9233 else
9235 op[7] = gen_label_rtx ();
9236 output_asm_insn ("llgf\t%4,%7-%5(%4)", op);
9237 output_asm_insn ("ag\t%4,0(%1)", op);
9238 output_asm_insn ("ag\t%1,0(%4)", op);
9242 /* Jump to target. */
9243 output_asm_insn ("jg\t%0", op);
9245 /* Output literal pool if required. */
9246 if (op[5])
9248 output_asm_insn (".align\t4", op);
9249 targetm.asm_out.internal_label (file, "L",
9250 CODE_LABEL_NUMBER (op[5]));
9252 if (op[6])
9254 targetm.asm_out.internal_label (file, "L",
9255 CODE_LABEL_NUMBER (op[6]));
9256 output_asm_insn (".long\t%2", op);
9258 if (op[7])
9260 targetm.asm_out.internal_label (file, "L",
9261 CODE_LABEL_NUMBER (op[7]));
9262 output_asm_insn (".long\t%3", op);
9265 else
9267 /* Setup base pointer if required. */
9268 if (!vcall_offset
9269 || (!DISP_IN_RANGE (delta)
9270 && !CONST_OK_FOR_K (delta)
9271 && !CONST_OK_FOR_Os (delta))
9272 || (!DISP_IN_RANGE (delta)
9273 && !CONST_OK_FOR_K (vcall_offset)
9274 && !CONST_OK_FOR_Os (vcall_offset)))
9276 op[5] = gen_label_rtx ();
9277 output_asm_insn ("basr\t%4,0", op);
9278 targetm.asm_out.internal_label (file, "L",
9279 CODE_LABEL_NUMBER (op[5]));
9282 /* Add DELTA to this pointer. */
9283 if (delta)
9285 if (CONST_OK_FOR_J (delta))
9286 output_asm_insn ("la\t%1,%2(%1)", op);
9287 else if (DISP_IN_RANGE (delta))
9288 output_asm_insn ("lay\t%1,%2(%1)", op);
9289 else if (CONST_OK_FOR_K (delta))
9290 output_asm_insn ("ahi\t%1,%2", op);
9291 else if (CONST_OK_FOR_Os (delta))
9292 output_asm_insn ("afi\t%1,%2", op);
9293 else
9295 op[6] = gen_label_rtx ();
9296 output_asm_insn ("a\t%1,%6-%5(%4)", op);
9300 /* Perform vcall adjustment. */
9301 if (vcall_offset)
9303 if (CONST_OK_FOR_J (vcall_offset))
9305 output_asm_insn ("l\t%4,0(%1)", op);
9306 output_asm_insn ("a\t%1,%3(%4)", op);
9308 else if (DISP_IN_RANGE (vcall_offset))
9310 output_asm_insn ("l\t%4,0(%1)", op);
9311 output_asm_insn ("ay\t%1,%3(%4)", op);
9313 else if (CONST_OK_FOR_K (vcall_offset))
9315 output_asm_insn ("lhi\t%4,%3", op);
9316 output_asm_insn ("a\t%4,0(%1)", op);
9317 output_asm_insn ("a\t%1,0(%4)", op);
9319 else if (CONST_OK_FOR_Os (vcall_offset))
9321 output_asm_insn ("iilf\t%4,%3", op);
9322 output_asm_insn ("a\t%4,0(%1)", op);
9323 output_asm_insn ("a\t%1,0(%4)", op);
9325 else
9327 op[7] = gen_label_rtx ();
9328 output_asm_insn ("l\t%4,%7-%5(%4)", op);
9329 output_asm_insn ("a\t%4,0(%1)", op);
9330 output_asm_insn ("a\t%1,0(%4)", op);
9333 /* We had to clobber the base pointer register.
9334 Re-setup the base pointer (with a different base). */
9335 op[5] = gen_label_rtx ();
9336 output_asm_insn ("basr\t%4,0", op);
9337 targetm.asm_out.internal_label (file, "L",
9338 CODE_LABEL_NUMBER (op[5]));
9341 /* Jump to target. */
9342 op[8] = gen_label_rtx ();
9344 if (!flag_pic)
9345 output_asm_insn ("l\t%4,%8-%5(%4)", op);
9346 else if (!nonlocal)
9347 output_asm_insn ("a\t%4,%8-%5(%4)", op);
9348 /* We cannot call through .plt, since .plt requires %r12 loaded. */
9349 else if (flag_pic == 1)
9351 output_asm_insn ("a\t%4,%8-%5(%4)", op);
9352 output_asm_insn ("l\t%4,%0(%4)", op);
9354 else if (flag_pic == 2)
9356 op[9] = gen_rtx_REG (Pmode, 0);
9357 output_asm_insn ("l\t%9,%8-4-%5(%4)", op);
9358 output_asm_insn ("a\t%4,%8-%5(%4)", op);
9359 output_asm_insn ("ar\t%4,%9", op);
9360 output_asm_insn ("l\t%4,0(%4)", op);
9363 output_asm_insn ("br\t%4", op);
9365 /* Output literal pool. */
9366 output_asm_insn (".align\t4", op);
9368 if (nonlocal && flag_pic == 2)
9369 output_asm_insn (".long\t%0", op);
9370 if (nonlocal)
9372 op[0] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
9373 SYMBOL_REF_FLAGS (op[0]) = SYMBOL_FLAG_LOCAL;
9376 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[8]));
9377 if (!flag_pic)
9378 output_asm_insn (".long\t%0", op);
9379 else
9380 output_asm_insn (".long\t%0-%5", op);
9382 if (op[6])
9384 targetm.asm_out.internal_label (file, "L",
9385 CODE_LABEL_NUMBER (op[6]));
9386 output_asm_insn (".long\t%2", op);
9388 if (op[7])
9390 targetm.asm_out.internal_label (file, "L",
9391 CODE_LABEL_NUMBER (op[7]));
9392 output_asm_insn (".long\t%3", op);
9395 final_end_function ();
9398 static bool
9399 s390_valid_pointer_mode (enum machine_mode mode)
9401 return (mode == SImode || (TARGET_64BIT && mode == DImode));
9404 /* Checks whether the given CALL_EXPR would use a caller
9405 saved register. This is used to decide whether sibling call
9406 optimization could be performed on the respective function
9407 call. */
9409 static bool
9410 s390_call_saved_register_used (tree call_expr)
9412 CUMULATIVE_ARGS cum;
9413 tree parameter;
9414 enum machine_mode mode;
9415 tree type;
9416 rtx parm_rtx;
9417 int reg, i;
9419 INIT_CUMULATIVE_ARGS (cum, NULL, NULL, 0, 0);
9421 for (i = 0; i < call_expr_nargs (call_expr); i++)
9423 parameter = CALL_EXPR_ARG (call_expr, i);
9424 gcc_assert (parameter);
9426 /* For an undeclared variable passed as parameter we will get
9427 an ERROR_MARK node here. */
9428 if (TREE_CODE (parameter) == ERROR_MARK)
9429 return true;
9431 type = TREE_TYPE (parameter);
9432 gcc_assert (type);
9434 mode = TYPE_MODE (type);
9435 gcc_assert (mode);
9437 if (pass_by_reference (&cum, mode, type, true))
9439 mode = Pmode;
9440 type = build_pointer_type (type);
9443 parm_rtx = s390_function_arg (&cum, mode, type, 0);
9445 s390_function_arg_advance (&cum, mode, type, 0);
9447 if (!parm_rtx)
9448 continue;
9450 if (REG_P (parm_rtx))
9452 for (reg = 0;
9453 reg < HARD_REGNO_NREGS (REGNO (parm_rtx), GET_MODE (parm_rtx));
9454 reg++)
9455 if (!call_used_regs[reg + REGNO (parm_rtx)])
9456 return true;
9459 if (GET_CODE (parm_rtx) == PARALLEL)
9461 int i;
9463 for (i = 0; i < XVECLEN (parm_rtx, 0); i++)
9465 rtx r = XEXP (XVECEXP (parm_rtx, 0, i), 0);
9467 gcc_assert (REG_P (r));
9469 for (reg = 0;
9470 reg < HARD_REGNO_NREGS (REGNO (r), GET_MODE (r));
9471 reg++)
9472 if (!call_used_regs[reg + REGNO (r)])
9473 return true;
9478 return false;
9481 /* Return true if the given call expression can be
9482 turned into a sibling call.
9483 DECL holds the declaration of the function to be called whereas
9484 EXP is the call expression itself. */
9486 static bool
9487 s390_function_ok_for_sibcall (tree decl, tree exp)
9489 /* The TPF epilogue uses register 1. */
9490 if (TARGET_TPF_PROFILING)
9491 return false;
9493 /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
9494 which would have to be restored before the sibcall. */
9495 if (!TARGET_64BIT && flag_pic && decl && !targetm.binds_local_p (decl))
9496 return false;
9498 /* Register 6 on s390 is available as an argument register but unfortunately
9499 "caller saved". This makes functions needing this register for arguments
9500 not suitable for sibcalls. */
9501 return !s390_call_saved_register_used (exp);
9504 /* Return the fixed registers used for condition codes. */
9506 static bool
9507 s390_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
9509 *p1 = CC_REGNUM;
9510 *p2 = INVALID_REGNUM;
9512 return true;
9515 /* This function is used by the call expanders of the machine description.
9516 It emits the call insn itself together with the necessary operations
9517 to adjust the target address and returns the emitted insn.
9518 ADDR_LOCATION is the target address rtx
9519 TLS_CALL the location of the thread-local symbol
9520 RESULT_REG the register where the result of the call should be stored
9521 RETADDR_REG the register where the return address should be stored
9522 If this parameter is NULL_RTX the call is considered
9523 to be a sibling call. */
9526 s390_emit_call (rtx addr_location, rtx tls_call, rtx result_reg,
9527 rtx retaddr_reg)
9529 bool plt_call = false;
9530 rtx insn;
9531 rtx call;
9532 rtx clobber;
9533 rtvec vec;
9535 /* Direct function calls need special treatment. */
9536 if (GET_CODE (addr_location) == SYMBOL_REF)
9538 /* When calling a global routine in PIC mode, we must
9539 replace the symbol itself with the PLT stub. */
9540 if (flag_pic && !SYMBOL_REF_LOCAL_P (addr_location))
9542 addr_location = gen_rtx_UNSPEC (Pmode,
9543 gen_rtvec (1, addr_location),
9544 UNSPEC_PLT);
9545 addr_location = gen_rtx_CONST (Pmode, addr_location);
9546 plt_call = true;
9549 /* Unless we can use the bras(l) insn, force the
9550 routine address into a register. */
9551 if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
9553 if (flag_pic)
9554 addr_location = legitimize_pic_address (addr_location, 0);
9555 else
9556 addr_location = force_reg (Pmode, addr_location);
9560 /* If it is already an indirect call or the code above moved the
9561 SYMBOL_REF to somewhere else make sure the address can be found in
9562 register 1. */
9563 if (retaddr_reg == NULL_RTX
9564 && GET_CODE (addr_location) != SYMBOL_REF
9565 && !plt_call)
9567 emit_move_insn (gen_rtx_REG (Pmode, SIBCALL_REGNUM), addr_location);
9568 addr_location = gen_rtx_REG (Pmode, SIBCALL_REGNUM);
9571 addr_location = gen_rtx_MEM (QImode, addr_location);
9572 call = gen_rtx_CALL (VOIDmode, addr_location, const0_rtx);
9574 if (result_reg != NULL_RTX)
9575 call = gen_rtx_SET (VOIDmode, result_reg, call);
9577 if (retaddr_reg != NULL_RTX)
9579 clobber = gen_rtx_CLOBBER (VOIDmode, retaddr_reg);
9581 if (tls_call != NULL_RTX)
9582 vec = gen_rtvec (3, call, clobber,
9583 gen_rtx_USE (VOIDmode, tls_call));
9584 else
9585 vec = gen_rtvec (2, call, clobber);
9587 call = gen_rtx_PARALLEL (VOIDmode, vec);
9590 insn = emit_call_insn (call);
9592 /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
9593 if ((!TARGET_64BIT && plt_call) || tls_call != NULL_RTX)
9595 /* s390_function_ok_for_sibcall should
9596 have denied sibcalls in this case. */
9597 gcc_assert (retaddr_reg != NULL_RTX);
9599 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
9601 return insn;
9604 /* Implement CONDITIONAL_REGISTER_USAGE. */
9606 void
9607 s390_conditional_register_usage (void)
9609 int i;
9611 if (flag_pic)
9613 fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
9614 call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
9616 if (TARGET_CPU_ZARCH)
9618 fixed_regs[BASE_REGNUM] = 0;
9619 call_used_regs[BASE_REGNUM] = 0;
9620 fixed_regs[RETURN_REGNUM] = 0;
9621 call_used_regs[RETURN_REGNUM] = 0;
9623 if (TARGET_64BIT)
9625 for (i = 24; i < 32; i++)
9626 call_used_regs[i] = call_really_used_regs[i] = 0;
9628 else
9630 for (i = 18; i < 20; i++)
9631 call_used_regs[i] = call_really_used_regs[i] = 0;
9634 if (TARGET_SOFT_FLOAT)
9636 for (i = 16; i < 32; i++)
9637 call_used_regs[i] = fixed_regs[i] = 1;
9641 /* Corresponding function to eh_return expander. */
9643 static GTY(()) rtx s390_tpf_eh_return_symbol;
9644 void
9645 s390_emit_tpf_eh_return (rtx target)
9647 rtx insn, reg;
9649 if (!s390_tpf_eh_return_symbol)
9650 s390_tpf_eh_return_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tpf_eh_return");
9652 reg = gen_rtx_REG (Pmode, 2);
9654 emit_move_insn (reg, target);
9655 insn = s390_emit_call (s390_tpf_eh_return_symbol, NULL_RTX, reg,
9656 gen_rtx_REG (Pmode, RETURN_REGNUM));
9657 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
9659 emit_move_insn (EH_RETURN_HANDLER_RTX, reg);
9662 /* Rework the prologue/epilogue to avoid saving/restoring
9663 registers unnecessarily. */
9665 static void
9666 s390_optimize_prologue (void)
9668 rtx insn, new_insn, next_insn;
9670 /* Do a final recompute of the frame-related data. */
9672 s390_update_frame_layout ();
9674 /* If all special registers are in fact used, there's nothing we
9675 can do, so no point in walking the insn list. */
9677 if (cfun_frame_layout.first_save_gpr <= BASE_REGNUM
9678 && cfun_frame_layout.last_save_gpr >= BASE_REGNUM
9679 && (TARGET_CPU_ZARCH
9680 || (cfun_frame_layout.first_save_gpr <= RETURN_REGNUM
9681 && cfun_frame_layout.last_save_gpr >= RETURN_REGNUM)))
9682 return;
9684 /* Search for prologue/epilogue insns and replace them. */
9686 for (insn = get_insns (); insn; insn = next_insn)
9688 int first, last, off;
9689 rtx set, base, offset;
9691 next_insn = NEXT_INSN (insn);
9693 if (GET_CODE (insn) != INSN)
9694 continue;
9696 if (GET_CODE (PATTERN (insn)) == PARALLEL
9697 && store_multiple_operation (PATTERN (insn), VOIDmode))
9699 set = XVECEXP (PATTERN (insn), 0, 0);
9700 first = REGNO (SET_SRC (set));
9701 last = first + XVECLEN (PATTERN (insn), 0) - 1;
9702 offset = const0_rtx;
9703 base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
9704 off = INTVAL (offset);
9706 if (GET_CODE (base) != REG || off < 0)
9707 continue;
9708 if (cfun_frame_layout.first_save_gpr != -1
9709 && (cfun_frame_layout.first_save_gpr < first
9710 || cfun_frame_layout.last_save_gpr > last))
9711 continue;
9712 if (REGNO (base) != STACK_POINTER_REGNUM
9713 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
9714 continue;
9715 if (first > BASE_REGNUM || last < BASE_REGNUM)
9716 continue;
9718 if (cfun_frame_layout.first_save_gpr != -1)
9720 new_insn = save_gprs (base,
9721 off + (cfun_frame_layout.first_save_gpr
9722 - first) * UNITS_PER_LONG,
9723 cfun_frame_layout.first_save_gpr,
9724 cfun_frame_layout.last_save_gpr);
9725 new_insn = emit_insn_before (new_insn, insn);
9726 INSN_ADDRESSES_NEW (new_insn, -1);
9729 remove_insn (insn);
9730 continue;
9733 if (cfun_frame_layout.first_save_gpr == -1
9734 && GET_CODE (PATTERN (insn)) == SET
9735 && GET_CODE (SET_SRC (PATTERN (insn))) == REG
9736 && (REGNO (SET_SRC (PATTERN (insn))) == BASE_REGNUM
9737 || (!TARGET_CPU_ZARCH
9738 && REGNO (SET_SRC (PATTERN (insn))) == RETURN_REGNUM))
9739 && GET_CODE (SET_DEST (PATTERN (insn))) == MEM)
9741 set = PATTERN (insn);
9742 first = REGNO (SET_SRC (set));
9743 offset = const0_rtx;
9744 base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
9745 off = INTVAL (offset);
9747 if (GET_CODE (base) != REG || off < 0)
9748 continue;
9749 if (REGNO (base) != STACK_POINTER_REGNUM
9750 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
9751 continue;
9753 remove_insn (insn);
9754 continue;
9757 if (GET_CODE (PATTERN (insn)) == PARALLEL
9758 && load_multiple_operation (PATTERN (insn), VOIDmode))
9760 set = XVECEXP (PATTERN (insn), 0, 0);
9761 first = REGNO (SET_DEST (set));
9762 last = first + XVECLEN (PATTERN (insn), 0) - 1;
9763 offset = const0_rtx;
9764 base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
9765 off = INTVAL (offset);
9767 if (GET_CODE (base) != REG || off < 0)
9768 continue;
9769 if (cfun_frame_layout.first_restore_gpr != -1
9770 && (cfun_frame_layout.first_restore_gpr < first
9771 || cfun_frame_layout.last_restore_gpr > last))
9772 continue;
9773 if (REGNO (base) != STACK_POINTER_REGNUM
9774 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
9775 continue;
9776 if (first > BASE_REGNUM || last < BASE_REGNUM)
9777 continue;
9779 if (cfun_frame_layout.first_restore_gpr != -1)
9781 new_insn = restore_gprs (base,
9782 off + (cfun_frame_layout.first_restore_gpr
9783 - first) * UNITS_PER_LONG,
9784 cfun_frame_layout.first_restore_gpr,
9785 cfun_frame_layout.last_restore_gpr);
9786 new_insn = emit_insn_before (new_insn, insn);
9787 INSN_ADDRESSES_NEW (new_insn, -1);
9790 remove_insn (insn);
9791 continue;
9794 if (cfun_frame_layout.first_restore_gpr == -1
9795 && GET_CODE (PATTERN (insn)) == SET
9796 && GET_CODE (SET_DEST (PATTERN (insn))) == REG
9797 && (REGNO (SET_DEST (PATTERN (insn))) == BASE_REGNUM
9798 || (!TARGET_CPU_ZARCH
9799 && REGNO (SET_DEST (PATTERN (insn))) == RETURN_REGNUM))
9800 && GET_CODE (SET_SRC (PATTERN (insn))) == MEM)
9802 set = PATTERN (insn);
9803 first = REGNO (SET_DEST (set));
9804 offset = const0_rtx;
9805 base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
9806 off = INTVAL (offset);
9808 if (GET_CODE (base) != REG || off < 0)
9809 continue;
9810 if (REGNO (base) != STACK_POINTER_REGNUM
9811 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
9812 continue;
9814 remove_insn (insn);
9815 continue;
9820 /* On z10 the dynamic branch prediction must see the backward jump in
9821 a window of 384 bytes. If not it falls back to the static
9822 prediction. This function rearranges the loop backward branch in a
9823 way which makes the static prediction always correct. The function
9824 returns true if it added an instruction. */
9825 static bool
9826 s390_z10_fix_long_loop_prediction (rtx insn)
9828 rtx set = single_set (insn);
9829 rtx code_label, label_ref, new_label;
9830 rtx uncond_jump;
9831 rtx cur_insn;
9832 rtx tmp;
9833 int distance;
9835 /* This will exclude branch on count and branch on index patterns
9836 since these are correctly statically predicted. */
9837 if (!set
9838 || SET_DEST (set) != pc_rtx
9839 || GET_CODE (SET_SRC(set)) != IF_THEN_ELSE)
9840 return false;
9842 label_ref = (GET_CODE (XEXP (SET_SRC (set), 1)) == LABEL_REF ?
9843 XEXP (SET_SRC (set), 1) : XEXP (SET_SRC (set), 2));
9845 gcc_assert (GET_CODE (label_ref) == LABEL_REF);
9847 code_label = XEXP (label_ref, 0);
9849 if (INSN_ADDRESSES (INSN_UID (code_label)) == -1
9850 || INSN_ADDRESSES (INSN_UID (insn)) == -1
9851 || (INSN_ADDRESSES (INSN_UID (insn))
9852 - INSN_ADDRESSES (INSN_UID (code_label)) < Z10_PREDICT_DISTANCE))
9853 return false;
9855 for (distance = 0, cur_insn = PREV_INSN (insn);
9856 distance < Z10_PREDICT_DISTANCE - 6;
9857 distance += get_attr_length (cur_insn), cur_insn = PREV_INSN (cur_insn))
9858 if (!cur_insn || JUMP_P (cur_insn) || LABEL_P (cur_insn))
9859 return false;
9861 new_label = gen_label_rtx ();
9862 uncond_jump = emit_jump_insn_after (
9863 gen_rtx_SET (VOIDmode, pc_rtx,
9864 gen_rtx_LABEL_REF (VOIDmode, code_label)),
9865 insn);
9866 emit_label_after (new_label, uncond_jump);
9868 tmp = XEXP (SET_SRC (set), 1);
9869 XEXP (SET_SRC (set), 1) = XEXP (SET_SRC (set), 2);
9870 XEXP (SET_SRC (set), 2) = tmp;
9871 INSN_CODE (insn) = -1;
9873 XEXP (label_ref, 0) = new_label;
9874 JUMP_LABEL (insn) = new_label;
9875 JUMP_LABEL (uncond_jump) = code_label;
9877 return true;
9880 /* Returns 1 if INSN reads the value of REG for purposes not related
9881 to addressing of memory, and 0 otherwise. */
9882 static int
9883 s390_non_addr_reg_read_p (rtx reg, rtx insn)
9885 return reg_referenced_p (reg, PATTERN (insn))
9886 && !reg_used_in_mem_p (REGNO (reg), PATTERN (insn));
9889 /* Starting from INSN find_cond_jump looks downwards in the insn
9890 stream for a single jump insn which is the last user of the
9891 condition code set in INSN. */
9892 static rtx
9893 find_cond_jump (rtx insn)
9895 for (; insn; insn = NEXT_INSN (insn))
9897 rtx ite, cc;
9899 if (LABEL_P (insn))
9900 break;
9902 if (!JUMP_P (insn))
9904 if (reg_mentioned_p (gen_rtx_REG (CCmode, CC_REGNUM), insn))
9905 break;
9906 continue;
9909 /* This will be triggered by a return. */
9910 if (GET_CODE (PATTERN (insn)) != SET)
9911 break;
9913 gcc_assert (SET_DEST (PATTERN (insn)) == pc_rtx);
9914 ite = SET_SRC (PATTERN (insn));
9916 if (GET_CODE (ite) != IF_THEN_ELSE)
9917 break;
9919 cc = XEXP (XEXP (ite, 0), 0);
9920 if (!REG_P (cc) || !CC_REGNO_P (REGNO (cc)))
9921 break;
9923 if (find_reg_note (insn, REG_DEAD, cc))
9924 return insn;
9925 break;
9928 return NULL_RTX;
9931 /* Swap the condition in COND and the operands in OP0 and OP1 so that
9932 the semantics does not change. If NULL_RTX is passed as COND the
9933 function tries to find the conditional jump starting with INSN. */
9934 static void
9935 s390_swap_cmp (rtx cond, rtx *op0, rtx *op1, rtx insn)
9937 rtx tmp = *op0;
9939 if (cond == NULL_RTX)
9941 rtx jump = find_cond_jump (NEXT_INSN (insn));
9942 jump = jump ? single_set (jump) : NULL_RTX;
9944 if (jump == NULL_RTX)
9945 return;
9947 cond = XEXP (XEXP (jump, 1), 0);
9950 *op0 = *op1;
9951 *op1 = tmp;
9952 PUT_CODE (cond, swap_condition (GET_CODE (cond)));
9955 /* On z10, instructions of the compare-and-branch family have the
9956 property to access the register occurring as second operand with
9957 its bits complemented. If such a compare is grouped with a second
9958 instruction that accesses the same register non-complemented, and
9959 if that register's value is delivered via a bypass, then the
9960 pipeline recycles, thereby causing significant performance decline.
9961 This function locates such situations and exchanges the two
9962 operands of the compare. The function return true whenever it
9963 added an insn. */
9964 static bool
9965 s390_z10_optimize_cmp (rtx insn)
9967 rtx prev_insn, next_insn;
9968 bool insn_added_p = false;
9969 rtx cond, *op0, *op1;
9971 if (GET_CODE (PATTERN (insn)) == PARALLEL)
9973 /* Handle compare and branch and branch on count
9974 instructions. */
9975 rtx pattern = single_set (insn);
9977 if (!pattern
9978 || SET_DEST (pattern) != pc_rtx
9979 || GET_CODE (SET_SRC (pattern)) != IF_THEN_ELSE)
9980 return false;
9982 cond = XEXP (SET_SRC (pattern), 0);
9983 op0 = &XEXP (cond, 0);
9984 op1 = &XEXP (cond, 1);
9986 else if (GET_CODE (PATTERN (insn)) == SET)
9988 rtx src, dest;
9990 /* Handle normal compare instructions. */
9991 src = SET_SRC (PATTERN (insn));
9992 dest = SET_DEST (PATTERN (insn));
9994 if (!REG_P (dest)
9995 || !CC_REGNO_P (REGNO (dest))
9996 || GET_CODE (src) != COMPARE)
9997 return false;
9999 /* s390_swap_cmp will try to find the conditional
10000 jump when passing NULL_RTX as condition. */
10001 cond = NULL_RTX;
10002 op0 = &XEXP (src, 0);
10003 op1 = &XEXP (src, 1);
10005 else
10006 return false;
10008 if (!REG_P (*op0) || !REG_P (*op1))
10009 return false;
10011 if (GET_MODE_CLASS (GET_MODE (*op0)) != MODE_INT)
10012 return false;
10014 /* Swap the COMPARE arguments and its mask if there is a
10015 conflicting access in the previous insn. */
10016 prev_insn = prev_active_insn (insn);
10017 if (prev_insn != NULL_RTX && INSN_P (prev_insn)
10018 && reg_referenced_p (*op1, PATTERN (prev_insn)))
10019 s390_swap_cmp (cond, op0, op1, insn);
10021 /* Check if there is a conflict with the next insn. If there
10022 was no conflict with the previous insn, then swap the
10023 COMPARE arguments and its mask. If we already swapped
10024 the operands, or if swapping them would cause a conflict
10025 with the previous insn, issue a NOP after the COMPARE in
10026 order to separate the two instuctions. */
10027 next_insn = next_active_insn (insn);
10028 if (next_insn != NULL_RTX && INSN_P (next_insn)
10029 && s390_non_addr_reg_read_p (*op1, next_insn))
10031 if (prev_insn != NULL_RTX && INSN_P (prev_insn)
10032 && s390_non_addr_reg_read_p (*op0, prev_insn))
10034 if (REGNO (*op1) == 0)
10035 emit_insn_after (gen_nop1 (), insn);
10036 else
10037 emit_insn_after (gen_nop (), insn);
10038 insn_added_p = true;
10040 else
10041 s390_swap_cmp (cond, op0, op1, insn);
10043 return insn_added_p;
10046 /* Perform machine-dependent processing. */
10048 static void
10049 s390_reorg (void)
10051 bool pool_overflow = false;
10053 /* Make sure all splits have been performed; splits after
10054 machine_dependent_reorg might confuse insn length counts. */
10055 split_all_insns_noflow ();
10057 /* Install the main literal pool and the associated base
10058 register load insns.
10060 In addition, there are two problematic situations we need
10061 to correct:
10063 - the literal pool might be > 4096 bytes in size, so that
10064 some of its elements cannot be directly accessed
10066 - a branch target might be > 64K away from the branch, so that
10067 it is not possible to use a PC-relative instruction.
10069 To fix those, we split the single literal pool into multiple
10070 pool chunks, reloading the pool base register at various
10071 points throughout the function to ensure it always points to
10072 the pool chunk the following code expects, and / or replace
10073 PC-relative branches by absolute branches.
10075 However, the two problems are interdependent: splitting the
10076 literal pool can move a branch further away from its target,
10077 causing the 64K limit to overflow, and on the other hand,
10078 replacing a PC-relative branch by an absolute branch means
10079 we need to put the branch target address into the literal
10080 pool, possibly causing it to overflow.
10082 So, we loop trying to fix up both problems until we manage
10083 to satisfy both conditions at the same time. Note that the
10084 loop is guaranteed to terminate as every pass of the loop
10085 strictly decreases the total number of PC-relative branches
10086 in the function. (This is not completely true as there
10087 might be branch-over-pool insns introduced by chunkify_start.
10088 Those never need to be split however.) */
10090 for (;;)
10092 struct constant_pool *pool = NULL;
10094 /* Collect the literal pool. */
10095 if (!pool_overflow)
10097 pool = s390_mainpool_start ();
10098 if (!pool)
10099 pool_overflow = true;
10102 /* If literal pool overflowed, start to chunkify it. */
10103 if (pool_overflow)
10104 pool = s390_chunkify_start ();
10106 /* Split out-of-range branches. If this has created new
10107 literal pool entries, cancel current chunk list and
10108 recompute it. zSeries machines have large branch
10109 instructions, so we never need to split a branch. */
10110 if (!TARGET_CPU_ZARCH && s390_split_branches ())
10112 if (pool_overflow)
10113 s390_chunkify_cancel (pool);
10114 else
10115 s390_mainpool_cancel (pool);
10117 continue;
10120 /* If we made it up to here, both conditions are satisfied.
10121 Finish up literal pool related changes. */
10122 if (pool_overflow)
10123 s390_chunkify_finish (pool);
10124 else
10125 s390_mainpool_finish (pool);
10127 /* We're done splitting branches. */
10128 cfun->machine->split_branches_pending_p = false;
10129 break;
10132 /* Generate out-of-pool execute target insns. */
10133 if (TARGET_CPU_ZARCH)
10135 rtx insn, label, target;
10137 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
10139 label = s390_execute_label (insn);
10140 if (!label)
10141 continue;
10143 gcc_assert (label != const0_rtx);
10145 target = emit_label (XEXP (label, 0));
10146 INSN_ADDRESSES_NEW (target, -1);
10148 target = emit_insn (s390_execute_target (insn));
10149 INSN_ADDRESSES_NEW (target, -1);
10153 /* Try to optimize prologue and epilogue further. */
10154 s390_optimize_prologue ();
10156 /* Walk over the insns and do some z10 specific changes. */
10157 if (s390_tune == PROCESSOR_2097_Z10)
10159 rtx insn;
10160 bool insn_added_p = false;
10162 /* The insn lengths and addresses have to be up to date for the
10163 following manipulations. */
10164 shorten_branches (get_insns ());
10166 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
10168 if (!INSN_P (insn) || INSN_CODE (insn) <= 0)
10169 continue;
10171 if (JUMP_P (insn))
10172 insn_added_p |= s390_z10_fix_long_loop_prediction (insn);
10174 if (GET_CODE (PATTERN (insn)) == PARALLEL
10175 || GET_CODE (PATTERN (insn)) == SET)
10176 insn_added_p |= s390_z10_optimize_cmp (insn);
10179 /* Adjust branches if we added new instructions. */
10180 if (insn_added_p)
10181 shorten_branches (get_insns ());
10185 /* Return true if INSN is a fp load insn writing register REGNO. */
10186 static inline bool
10187 s390_fpload_toreg (rtx insn, unsigned int regno)
10189 rtx set;
10190 enum attr_type flag = s390_safe_attr_type (insn);
10192 if (flag != TYPE_FLOADSF && flag != TYPE_FLOADDF)
10193 return false;
10195 set = single_set (insn);
10197 if (set == NULL_RTX)
10198 return false;
10200 if (!REG_P (SET_DEST (set)) || !MEM_P (SET_SRC (set)))
10201 return false;
10203 if (REGNO (SET_DEST (set)) != regno)
10204 return false;
10206 return true;
10209 /* This value describes the distance to be avoided between an
10210 aritmetic fp instruction and an fp load writing the same register.
10211 Z10_EARLYLOAD_DISTANCE - 1 as well as Z10_EARLYLOAD_DISTANCE + 1 is
10212 fine but the exact value has to be avoided. Otherwise the FP
10213 pipeline will throw an exception causing a major penalty. */
10214 #define Z10_EARLYLOAD_DISTANCE 7
10216 /* Rearrange the ready list in order to avoid the situation described
10217 for Z10_EARLYLOAD_DISTANCE. A problematic load instruction is
10218 moved to the very end of the ready list. */
10219 static void
10220 s390_z10_prevent_earlyload_conflicts (rtx *ready, int *nready_p)
10222 unsigned int regno;
10223 int nready = *nready_p;
10224 rtx tmp;
10225 int i;
10226 rtx insn;
10227 rtx set;
10228 enum attr_type flag;
10229 int distance;
10231 /* Skip DISTANCE - 1 active insns. */
10232 for (insn = last_scheduled_insn, distance = Z10_EARLYLOAD_DISTANCE - 1;
10233 distance > 0 && insn != NULL_RTX;
10234 distance--, insn = prev_active_insn (insn))
10235 if (CALL_P (insn) || JUMP_P (insn))
10236 return;
10238 if (insn == NULL_RTX)
10239 return;
10241 set = single_set (insn);
10243 if (set == NULL_RTX || !REG_P (SET_DEST (set))
10244 || GET_MODE_CLASS (GET_MODE (SET_DEST (set))) != MODE_FLOAT)
10245 return;
10247 flag = s390_safe_attr_type (insn);
10249 if (flag == TYPE_FLOADSF || flag == TYPE_FLOADDF)
10250 return;
10252 regno = REGNO (SET_DEST (set));
10253 i = nready - 1;
10255 while (!s390_fpload_toreg (ready[i], regno) && i > 0)
10256 i--;
10258 if (!i)
10259 return;
10261 tmp = ready[i];
10262 memmove (&ready[1], &ready[0], sizeof (rtx) * i);
10263 ready[0] = tmp;
10266 /* This function is called via hook TARGET_SCHED_REORDER before
10267 issueing one insn from list READY which contains *NREADYP entries.
10268 For target z10 it reorders load instructions to avoid early load
10269 conflicts in the floating point pipeline */
10270 static int
10271 s390_sched_reorder (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
10272 rtx *ready, int *nreadyp, int clock ATTRIBUTE_UNUSED)
10274 if (s390_tune == PROCESSOR_2097_Z10)
10275 if (reload_completed && *nreadyp > 1)
10276 s390_z10_prevent_earlyload_conflicts (ready, nreadyp);
10278 return s390_issue_rate ();
10281 /* This function is called via hook TARGET_SCHED_VARIABLE_ISSUE after
10282 the scheduler has issued INSN. It stores the last issued insn into
10283 last_scheduled_insn in order to make it available for
10284 s390_sched_reorder. */
10285 static int
10286 s390_sched_variable_issue (FILE *file ATTRIBUTE_UNUSED,
10287 int verbose ATTRIBUTE_UNUSED,
10288 rtx insn, int more)
10290 last_scheduled_insn = insn;
10292 if (GET_CODE (PATTERN (insn)) != USE
10293 && GET_CODE (PATTERN (insn)) != CLOBBER)
10294 return more - 1;
10295 else
10296 return more;
10299 static void
10300 s390_sched_init (FILE *file ATTRIBUTE_UNUSED,
10301 int verbose ATTRIBUTE_UNUSED,
10302 int max_ready ATTRIBUTE_UNUSED)
10304 last_scheduled_insn = NULL_RTX;
10307 /* This function checks the whole of insn X for memory references. The
10308 function always returns zero because the framework it is called
10309 from would stop recursively analyzing the insn upon a return value
10310 other than zero. The real result of this function is updating
10311 counter variable MEM_COUNT. */
10312 static int
10313 check_dpu (rtx *x, unsigned *mem_count)
10315 if (*x != NULL_RTX && MEM_P (*x))
10316 (*mem_count)++;
10317 return 0;
10320 /* This target hook implementation for TARGET_LOOP_UNROLL_ADJUST calculates
10321 a new number struct loop *loop should be unrolled if tuned for the z10
10322 cpu. The loop is analyzed for memory accesses by calling check_dpu for
10323 each rtx of the loop. Depending on the loop_depth and the amount of
10324 memory accesses a new number <=nunroll is returned to improve the
10325 behaviour of the hardware prefetch unit. */
10326 static unsigned
10327 s390_loop_unroll_adjust (unsigned nunroll, struct loop *loop)
10329 basic_block *bbs;
10330 rtx insn;
10331 unsigned i;
10332 unsigned mem_count = 0;
10334 /* Only z10 needs special handling. */
10335 if (s390_tune != PROCESSOR_2097_Z10)
10336 return nunroll;
10338 /* Count the number of memory references within the loop body. */
10339 bbs = get_loop_body (loop);
10340 for (i = 0; i < loop->num_nodes; i++)
10342 for (insn = BB_HEAD (bbs[i]); insn != BB_END (bbs[i]); insn = NEXT_INSN (insn))
10343 if (INSN_P (insn) && INSN_CODE (insn) != -1)
10344 for_each_rtx (&insn, (rtx_function) check_dpu, &mem_count);
10346 free (bbs);
10348 /* Prevent division by zero, and we do not need to adjust nunroll in this case. */
10349 if (mem_count == 0)
10350 return nunroll;
10352 switch (loop_depth(loop))
10354 case 1:
10355 return MIN (nunroll, 28 / mem_count);
10356 case 2:
10357 return MIN (nunroll, 22 / mem_count);
10358 default:
10359 return MIN (nunroll, 16 / mem_count);
10363 /* Initialize GCC target structure. */
10365 #undef TARGET_ASM_ALIGNED_HI_OP
10366 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
10367 #undef TARGET_ASM_ALIGNED_DI_OP
10368 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
10369 #undef TARGET_ASM_INTEGER
10370 #define TARGET_ASM_INTEGER s390_assemble_integer
10372 #undef TARGET_ASM_OPEN_PAREN
10373 #define TARGET_ASM_OPEN_PAREN ""
10375 #undef TARGET_ASM_CLOSE_PAREN
10376 #define TARGET_ASM_CLOSE_PAREN ""
10378 #undef TARGET_DEFAULT_TARGET_FLAGS
10379 #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD)
10381 #undef TARGET_HANDLE_OPTION
10382 #define TARGET_HANDLE_OPTION s390_handle_option
10384 #undef TARGET_ENCODE_SECTION_INFO
10385 #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
10387 #undef TARGET_SCALAR_MODE_SUPPORTED_P
10388 #define TARGET_SCALAR_MODE_SUPPORTED_P s390_scalar_mode_supported_p
10390 #ifdef HAVE_AS_TLS
10391 #undef TARGET_HAVE_TLS
10392 #define TARGET_HAVE_TLS true
10393 #endif
10394 #undef TARGET_CANNOT_FORCE_CONST_MEM
10395 #define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
10397 #undef TARGET_DELEGITIMIZE_ADDRESS
10398 #define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
10400 #undef TARGET_LEGITIMIZE_ADDRESS
10401 #define TARGET_LEGITIMIZE_ADDRESS s390_legitimize_address
10403 #undef TARGET_RETURN_IN_MEMORY
10404 #define TARGET_RETURN_IN_MEMORY s390_return_in_memory
10406 #undef TARGET_INIT_BUILTINS
10407 #define TARGET_INIT_BUILTINS s390_init_builtins
10408 #undef TARGET_EXPAND_BUILTIN
10409 #define TARGET_EXPAND_BUILTIN s390_expand_builtin
10411 #undef TARGET_ASM_OUTPUT_MI_THUNK
10412 #define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
10413 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
10414 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
10416 #undef TARGET_SCHED_ADJUST_PRIORITY
10417 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
10418 #undef TARGET_SCHED_ISSUE_RATE
10419 #define TARGET_SCHED_ISSUE_RATE s390_issue_rate
10420 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
10421 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
10423 #undef TARGET_SCHED_VARIABLE_ISSUE
10424 #define TARGET_SCHED_VARIABLE_ISSUE s390_sched_variable_issue
10425 #undef TARGET_SCHED_REORDER
10426 #define TARGET_SCHED_REORDER s390_sched_reorder
10427 #undef TARGET_SCHED_INIT
10428 #define TARGET_SCHED_INIT s390_sched_init
10430 #undef TARGET_CANNOT_COPY_INSN_P
10431 #define TARGET_CANNOT_COPY_INSN_P s390_cannot_copy_insn_p
10432 #undef TARGET_RTX_COSTS
10433 #define TARGET_RTX_COSTS s390_rtx_costs
10434 #undef TARGET_ADDRESS_COST
10435 #define TARGET_ADDRESS_COST s390_address_cost
10437 #undef TARGET_MACHINE_DEPENDENT_REORG
10438 #define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
10440 #undef TARGET_VALID_POINTER_MODE
10441 #define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
10443 #undef TARGET_BUILD_BUILTIN_VA_LIST
10444 #define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
10445 #undef TARGET_EXPAND_BUILTIN_VA_START
10446 #define TARGET_EXPAND_BUILTIN_VA_START s390_va_start
10447 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
10448 #define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg
10450 #undef TARGET_PROMOTE_FUNCTION_MODE
10451 #define TARGET_PROMOTE_FUNCTION_MODE s390_promote_function_mode
10452 #undef TARGET_PASS_BY_REFERENCE
10453 #define TARGET_PASS_BY_REFERENCE s390_pass_by_reference
10455 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
10456 #define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
10458 #undef TARGET_FIXED_CONDITION_CODE_REGS
10459 #define TARGET_FIXED_CONDITION_CODE_REGS s390_fixed_condition_code_regs
10461 #undef TARGET_CC_MODES_COMPATIBLE
10462 #define TARGET_CC_MODES_COMPATIBLE s390_cc_modes_compatible
10464 #undef TARGET_INVALID_WITHIN_DOLOOP
10465 #define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_const_rtx_null
10467 #ifdef HAVE_AS_TLS
10468 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
10469 #define TARGET_ASM_OUTPUT_DWARF_DTPREL s390_output_dwarf_dtprel
10470 #endif
10472 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
10473 #undef TARGET_MANGLE_TYPE
10474 #define TARGET_MANGLE_TYPE s390_mangle_type
10475 #endif
10477 #undef TARGET_SCALAR_MODE_SUPPORTED_P
10478 #define TARGET_SCALAR_MODE_SUPPORTED_P s390_scalar_mode_supported_p
10480 #undef TARGET_SECONDARY_RELOAD
10481 #define TARGET_SECONDARY_RELOAD s390_secondary_reload
10483 #undef TARGET_LIBGCC_CMP_RETURN_MODE
10484 #define TARGET_LIBGCC_CMP_RETURN_MODE s390_libgcc_cmp_return_mode
10486 #undef TARGET_LIBGCC_SHIFT_COUNT_MODE
10487 #define TARGET_LIBGCC_SHIFT_COUNT_MODE s390_libgcc_shift_count_mode
10489 #undef TARGET_LEGITIMATE_ADDRESS_P
10490 #define TARGET_LEGITIMATE_ADDRESS_P s390_legitimate_address_p
10492 #undef TARGET_CAN_ELIMINATE
10493 #define TARGET_CAN_ELIMINATE s390_can_eliminate
10495 #undef TARGET_LOOP_UNROLL_ADJUST
10496 #define TARGET_LOOP_UNROLL_ADJUST s390_loop_unroll_adjust
10498 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
10499 #define TARGET_ASM_TRAMPOLINE_TEMPLATE s390_asm_trampoline_template
10500 #undef TARGET_TRAMPOLINE_INIT
10501 #define TARGET_TRAMPOLINE_INIT s390_trampoline_init
10503 #undef TARGET_UNWIND_WORD_MODE
10504 #define TARGET_UNWIND_WORD_MODE s390_unwind_word_mode
10506 struct gcc_target targetm = TARGET_INITIALIZER;
10508 #include "gt-s390.h"