2005-06-29 Andreas Krebbel <krebbel1@de.ibm.com>
[official-gcc.git] / gcc / config / s390 / s390.c
blob1dfefc5369c03f161ec140140b66268ecfacbded
1 /* Subroutines used for code generation on IBM S/390 and zSeries
2 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
3 Free Software Foundation, Inc.
4 Contributed by Hartmut Penner (hpenner@de.ibm.com) and
5 Ulrich Weigand (uweigand@de.ibm.com).
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
12 version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to the Free
21 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
22 02110-1301, USA. */
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 "tree-gimple.h"
56 /* Define the specific costs for a given cpu. */
58 struct processor_costs
60 /* multiplication */
61 const int m; /* cost of an M instruction. */
62 const int mghi; /* cost of an MGHI instruction. */
63 const int mh; /* cost of an MH instruction. */
64 const int mhi; /* cost of an MHI instruction. */
65 const int ml; /* cost of an ML instruction. */
66 const int mr; /* cost of an MR instruction. */
67 const int ms; /* cost of an MS instruction. */
68 const int msg; /* cost of an MSG instruction. */
69 const int msgf; /* cost of an MSGF instruction. */
70 const int msgfr; /* cost of an MSGFR instruction. */
71 const int msgr; /* cost of an MSGR instruction. */
72 const int msr; /* cost of an MSR instruction. */
73 const int mult_df; /* cost of multiplication in DFmode. */
74 /* square root */
75 const int sqdbr; /* cost of square root in DFmode. */
76 const int sqebr; /* cost of square root in SFmode. */
77 /* multiply and add */
78 const int madbr; /* cost of multiply and add in DFmode. */
79 const int maebr; /* cost of multiply and add in SFmode. */
80 /* division */
81 const int ddbr;
82 const int ddr;
83 const int debr;
84 const int der;
85 const int dlgr;
86 const int dlr;
87 const int dr;
88 const int dsgfr;
89 const int dsgr;
92 const struct processor_costs *s390_cost;
94 static const
95 struct processor_costs z900_cost =
97 COSTS_N_INSNS (5), /* M */
98 COSTS_N_INSNS (10), /* MGHI */
99 COSTS_N_INSNS (5), /* MH */
100 COSTS_N_INSNS (4), /* MHI */
101 COSTS_N_INSNS (5), /* ML */
102 COSTS_N_INSNS (5), /* MR */
103 COSTS_N_INSNS (4), /* MS */
104 COSTS_N_INSNS (15), /* MSG */
105 COSTS_N_INSNS (7), /* MSGF */
106 COSTS_N_INSNS (7), /* MSGFR */
107 COSTS_N_INSNS (10), /* MSGR */
108 COSTS_N_INSNS (4), /* MSR */
109 COSTS_N_INSNS (7), /* multiplication in DFmode */
110 COSTS_N_INSNS (44), /* SQDBR */
111 COSTS_N_INSNS (35), /* SQEBR */
112 COSTS_N_INSNS (18), /* MADBR */
113 COSTS_N_INSNS (13), /* MAEBR */
114 COSTS_N_INSNS (30), /* DDBR */
115 COSTS_N_INSNS (30), /* DDR */
116 COSTS_N_INSNS (27), /* DEBR */
117 COSTS_N_INSNS (26), /* DER */
118 COSTS_N_INSNS (220), /* DLGR */
119 COSTS_N_INSNS (34), /* DLR */
120 COSTS_N_INSNS (34), /* DR */
121 COSTS_N_INSNS (32), /* DSGFR */
122 COSTS_N_INSNS (32), /* DSGR */
125 static const
126 struct processor_costs z990_cost =
128 COSTS_N_INSNS (4), /* M */
129 COSTS_N_INSNS (2), /* MGHI */
130 COSTS_N_INSNS (2), /* MH */
131 COSTS_N_INSNS (2), /* MHI */
132 COSTS_N_INSNS (4), /* ML */
133 COSTS_N_INSNS (4), /* MR */
134 COSTS_N_INSNS (5), /* MS */
135 COSTS_N_INSNS (6), /* MSG */
136 COSTS_N_INSNS (4), /* MSGF */
137 COSTS_N_INSNS (4), /* MSGFR */
138 COSTS_N_INSNS (4), /* MSGR */
139 COSTS_N_INSNS (4), /* MSR */
140 COSTS_N_INSNS (1), /* multiplication in DFmode */
141 COSTS_N_INSNS (66), /* SQDBR */
142 COSTS_N_INSNS (38), /* SQEBR */
143 COSTS_N_INSNS (1), /* MADBR */
144 COSTS_N_INSNS (1), /* MAEBR */
145 COSTS_N_INSNS (40), /* DDBR */
146 COSTS_N_INSNS (44), /* DDR */
147 COSTS_N_INSNS (26), /* DDBR */
148 COSTS_N_INSNS (28), /* DER */
149 COSTS_N_INSNS (176), /* DLGR */
150 COSTS_N_INSNS (31), /* DLR */
151 COSTS_N_INSNS (31), /* DR */
152 COSTS_N_INSNS (31), /* DSGFR */
153 COSTS_N_INSNS (31), /* DSGR */
157 extern int reload_completed;
159 /* The alias set for prologue/epilogue register save/restore. */
160 static int s390_sr_alias_set = 0;
162 /* Save information from a "cmpxx" operation until the branch or scc is
163 emitted. */
164 rtx s390_compare_op0, s390_compare_op1;
166 /* Save the result of a compare_and_swap until the branch or scc is
167 emitted. */
168 rtx s390_compare_emitted = NULL_RTX;
170 /* Structure used to hold the components of a S/390 memory
171 address. A legitimate address on S/390 is of the general
172 form
173 base + index + displacement
174 where any of the components is optional.
176 base and index are registers of the class ADDR_REGS,
177 displacement is an unsigned 12-bit immediate constant. */
179 struct s390_address
181 rtx base;
182 rtx indx;
183 rtx disp;
184 bool pointer;
187 /* Which cpu are we tuning for. */
188 enum processor_type s390_tune = PROCESSOR_max;
189 enum processor_flags s390_tune_flags;
190 /* Which instruction set architecture to use. */
191 enum processor_type s390_arch;
192 enum processor_flags s390_arch_flags;
194 HOST_WIDE_INT s390_warn_framesize = 0;
195 HOST_WIDE_INT s390_stack_size = 0;
196 HOST_WIDE_INT s390_stack_guard = 0;
198 /* The following structure is embedded in the machine
199 specific part of struct function. */
201 struct s390_frame_layout GTY (())
203 /* Offset within stack frame. */
204 HOST_WIDE_INT gprs_offset;
205 HOST_WIDE_INT f0_offset;
206 HOST_WIDE_INT f4_offset;
207 HOST_WIDE_INT f8_offset;
208 HOST_WIDE_INT backchain_offset;
210 /* Number of first and last gpr to be saved, restored. */
211 int first_save_gpr;
212 int first_restore_gpr;
213 int last_save_gpr;
214 int last_restore_gpr;
216 /* Bits standing for floating point registers. Set, if the
217 respective register has to be saved. Starting with reg 16 (f0)
218 at the rightmost bit.
219 Bit 15 - 8 7 6 5 4 3 2 1 0
220 fpr 15 - 8 7 5 3 1 6 4 2 0
221 reg 31 - 24 23 22 21 20 19 18 17 16 */
222 unsigned int fpr_bitmap;
224 /* Number of floating point registers f8-f15 which must be saved. */
225 int high_fprs;
227 /* Set if return address needs to be saved. */
228 bool save_return_addr_p;
230 /* Size of stack frame. */
231 HOST_WIDE_INT frame_size;
234 /* Define the structure for the machine field in struct function. */
236 struct machine_function GTY(())
238 struct s390_frame_layout frame_layout;
240 /* Literal pool base register. */
241 rtx base_reg;
243 /* True if we may need to perform branch splitting. */
244 bool split_branches_pending_p;
246 /* Some local-dynamic TLS symbol name. */
247 const char *some_ld_name;
249 bool has_landing_pad_p;
252 /* Few accessor macros for struct cfun->machine->s390_frame_layout. */
254 #define cfun_frame_layout (cfun->machine->frame_layout)
255 #define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)
256 #define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr - \
257 cfun_frame_layout.first_save_gpr + 1) * UNITS_PER_WORD)
258 #define cfun_set_fpr_bit(BITNUM) (cfun->machine->frame_layout.fpr_bitmap |= \
259 (1 << (BITNUM)))
260 #define cfun_fpr_bit_p(BITNUM) (!!(cfun->machine->frame_layout.fpr_bitmap & \
261 (1 << (BITNUM))))
263 /* Number of GPRs and FPRs used for argument passing. */
264 #define GP_ARG_NUM_REG 5
265 #define FP_ARG_NUM_REG (TARGET_64BIT? 4 : 2)
267 /* Set the has_landing_pad_p flag in struct machine_function to VALUE. */
269 void
270 s390_set_has_landing_pad_p (bool value)
272 cfun->machine->has_landing_pad_p = value;
275 /* Return true if SET either doesn't set the CC register, or else
276 the source and destination have matching CC modes and that
277 CC mode is at least as constrained as REQ_MODE. */
279 static bool
280 s390_match_ccmode_set (rtx set, enum machine_mode req_mode)
282 enum machine_mode set_mode;
284 gcc_assert (GET_CODE (set) == SET);
286 if (GET_CODE (SET_DEST (set)) != REG || !CC_REGNO_P (REGNO (SET_DEST (set))))
287 return 1;
289 set_mode = GET_MODE (SET_DEST (set));
290 switch (set_mode)
292 case CCSmode:
293 case CCSRmode:
294 case CCUmode:
295 case CCURmode:
296 case CCLmode:
297 case CCL1mode:
298 case CCL2mode:
299 case CCL3mode:
300 case CCT1mode:
301 case CCT2mode:
302 case CCT3mode:
303 if (req_mode != set_mode)
304 return 0;
305 break;
307 case CCZmode:
308 if (req_mode != CCSmode && req_mode != CCUmode && req_mode != CCTmode
309 && req_mode != CCSRmode && req_mode != CCURmode)
310 return 0;
311 break;
313 case CCAPmode:
314 case CCANmode:
315 if (req_mode != CCAmode)
316 return 0;
317 break;
319 default:
320 gcc_unreachable ();
323 return (GET_MODE (SET_SRC (set)) == set_mode);
326 /* Return true if every SET in INSN that sets the CC register
327 has source and destination with matching CC modes and that
328 CC mode is at least as constrained as REQ_MODE.
329 If REQ_MODE is VOIDmode, always return false. */
331 bool
332 s390_match_ccmode (rtx insn, enum machine_mode req_mode)
334 int i;
336 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
337 if (req_mode == VOIDmode)
338 return false;
340 if (GET_CODE (PATTERN (insn)) == SET)
341 return s390_match_ccmode_set (PATTERN (insn), req_mode);
343 if (GET_CODE (PATTERN (insn)) == PARALLEL)
344 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
346 rtx set = XVECEXP (PATTERN (insn), 0, i);
347 if (GET_CODE (set) == SET)
348 if (!s390_match_ccmode_set (set, req_mode))
349 return false;
352 return true;
355 /* If a test-under-mask instruction can be used to implement
356 (compare (and ... OP1) OP2), return the CC mode required
357 to do that. Otherwise, return VOIDmode.
358 MIXED is true if the instruction can distinguish between
359 CC1 and CC2 for mixed selected bits (TMxx), it is false
360 if the instruction cannot (TM). */
362 enum machine_mode
363 s390_tm_ccmode (rtx op1, rtx op2, bool mixed)
365 int bit0, bit1;
367 /* ??? Fixme: should work on CONST_DOUBLE as well. */
368 if (GET_CODE (op1) != CONST_INT || GET_CODE (op2) != CONST_INT)
369 return VOIDmode;
371 /* Selected bits all zero: CC0.
372 e.g.: int a; if ((a & (16 + 128)) == 0) */
373 if (INTVAL (op2) == 0)
374 return CCTmode;
376 /* Selected bits all one: CC3.
377 e.g.: int a; if ((a & (16 + 128)) == 16 + 128) */
378 if (INTVAL (op2) == INTVAL (op1))
379 return CCT3mode;
381 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. e.g.:
382 int a;
383 if ((a & (16 + 128)) == 16) -> CCT1
384 if ((a & (16 + 128)) == 128) -> CCT2 */
385 if (mixed)
387 bit1 = exact_log2 (INTVAL (op2));
388 bit0 = exact_log2 (INTVAL (op1) ^ INTVAL (op2));
389 if (bit0 != -1 && bit1 != -1)
390 return bit0 > bit1 ? CCT1mode : CCT2mode;
393 return VOIDmode;
396 /* Given a comparison code OP (EQ, NE, etc.) and the operands
397 OP0 and OP1 of a COMPARE, return the mode to be used for the
398 comparison. */
400 enum machine_mode
401 s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
403 switch (code)
405 case EQ:
406 case NE:
407 if ((GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
408 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
409 return CCAPmode;
410 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
411 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0, 1)), 'K', "K"))
412 return CCAPmode;
413 if ((GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
414 || GET_CODE (op1) == NEG)
415 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
416 return CCLmode;
418 if (GET_CODE (op0) == AND)
420 /* Check whether we can potentially do it via TM. */
421 enum machine_mode ccmode;
422 ccmode = s390_tm_ccmode (XEXP (op0, 1), op1, 1);
423 if (ccmode != VOIDmode)
425 /* Relax CCTmode to CCZmode to allow fall-back to AND
426 if that turns out to be beneficial. */
427 return ccmode == CCTmode ? CCZmode : ccmode;
431 if (register_operand (op0, HImode)
432 && GET_CODE (op1) == CONST_INT
433 && (INTVAL (op1) == -1 || INTVAL (op1) == 65535))
434 return CCT3mode;
435 if (register_operand (op0, QImode)
436 && GET_CODE (op1) == CONST_INT
437 && (INTVAL (op1) == -1 || INTVAL (op1) == 255))
438 return CCT3mode;
440 return CCZmode;
442 case LE:
443 case LT:
444 case GE:
445 case GT:
446 /* The only overflow condition of NEG and ABS happens when
447 -INT_MAX is used as parameter, which stays negative. So
448 we have an overflow from a positive value to a negative.
449 Using CCAP mode the resulting cc can be used for comparisons. */
450 if ((GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
451 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
452 return CCAPmode;
454 /* If constants are involved in an add instruction it is possible to use
455 the resulting cc for comparisons with zero. Knowing the sign of the
456 constant the overflow behavior gets predictable. e.g.:
457 int a, b; if ((b = a + c) > 0)
458 with c as a constant value: c < 0 -> CCAN and c >= 0 -> CCAP */
459 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
460 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0, 1)), 'K', "K"))
462 if (INTVAL (XEXP((op0), 1)) < 0)
463 return CCANmode;
464 else
465 return CCAPmode;
467 /* Fall through. */
468 case UNORDERED:
469 case ORDERED:
470 case UNEQ:
471 case UNLE:
472 case UNLT:
473 case UNGE:
474 case UNGT:
475 case LTGT:
476 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
477 && GET_CODE (op1) != CONST_INT)
478 return CCSRmode;
479 return CCSmode;
481 case LTU:
482 case GEU:
483 if (GET_CODE (op0) == PLUS
484 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
485 return CCL1mode;
487 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
488 && GET_CODE (op1) != CONST_INT)
489 return CCURmode;
490 return CCUmode;
492 case LEU:
493 case GTU:
494 if (GET_CODE (op0) == MINUS
495 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
496 return CCL2mode;
498 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
499 && GET_CODE (op1) != CONST_INT)
500 return CCURmode;
501 return CCUmode;
503 default:
504 gcc_unreachable ();
508 /* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
509 that we can implement more efficiently. */
511 void
512 s390_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
514 /* Convert ZERO_EXTRACT back to AND to enable TM patterns. */
515 if ((*code == EQ || *code == NE)
516 && *op1 == const0_rtx
517 && GET_CODE (*op0) == ZERO_EXTRACT
518 && GET_CODE (XEXP (*op0, 1)) == CONST_INT
519 && GET_CODE (XEXP (*op0, 2)) == CONST_INT
520 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0, 0))))
522 rtx inner = XEXP (*op0, 0);
523 HOST_WIDE_INT modesize = GET_MODE_BITSIZE (GET_MODE (inner));
524 HOST_WIDE_INT len = INTVAL (XEXP (*op0, 1));
525 HOST_WIDE_INT pos = INTVAL (XEXP (*op0, 2));
527 if (len > 0 && len < modesize
528 && pos >= 0 && pos + len <= modesize
529 && modesize <= HOST_BITS_PER_WIDE_INT)
531 unsigned HOST_WIDE_INT block;
532 block = ((unsigned HOST_WIDE_INT) 1 << len) - 1;
533 block <<= modesize - pos - len;
535 *op0 = gen_rtx_AND (GET_MODE (inner), inner,
536 gen_int_mode (block, GET_MODE (inner)));
540 /* Narrow AND of memory against immediate to enable TM. */
541 if ((*code == EQ || *code == NE)
542 && *op1 == const0_rtx
543 && GET_CODE (*op0) == AND
544 && GET_CODE (XEXP (*op0, 1)) == CONST_INT
545 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0, 0))))
547 rtx inner = XEXP (*op0, 0);
548 rtx mask = XEXP (*op0, 1);
550 /* Ignore paradoxical SUBREGs if all extra bits are masked out. */
551 if (GET_CODE (inner) == SUBREG
552 && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (inner)))
553 && (GET_MODE_SIZE (GET_MODE (inner))
554 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner))))
555 && ((INTVAL (mask)
556 & GET_MODE_MASK (GET_MODE (inner))
557 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (inner))))
558 == 0))
559 inner = SUBREG_REG (inner);
561 /* Do not change volatile MEMs. */
562 if (MEM_P (inner) && !MEM_VOLATILE_P (inner))
564 int part = s390_single_part (XEXP (*op0, 1),
565 GET_MODE (inner), QImode, 0);
566 if (part >= 0)
568 mask = gen_int_mode (s390_extract_part (mask, QImode, 0), QImode);
569 inner = adjust_address_nv (inner, QImode, part);
570 *op0 = gen_rtx_AND (QImode, inner, mask);
575 /* Narrow comparisons against 0xffff to HImode if possible. */
576 if ((*code == EQ || *code == NE)
577 && GET_CODE (*op1) == CONST_INT
578 && INTVAL (*op1) == 0xffff
579 && SCALAR_INT_MODE_P (GET_MODE (*op0))
580 && (nonzero_bits (*op0, GET_MODE (*op0))
581 & ~(unsigned HOST_WIDE_INT) 0xffff) == 0)
583 *op0 = gen_lowpart (HImode, *op0);
584 *op1 = constm1_rtx;
588 /* Remove redundant UNSPEC_CMPINT conversions if possible. */
589 if (GET_CODE (*op0) == UNSPEC
590 && XINT (*op0, 1) == UNSPEC_CMPINT
591 && XVECLEN (*op0, 0) == 1
592 && GET_MODE (XVECEXP (*op0, 0, 0)) == CCUmode
593 && GET_CODE (XVECEXP (*op0, 0, 0)) == REG
594 && REGNO (XVECEXP (*op0, 0, 0)) == CC_REGNUM
595 && *op1 == const0_rtx)
597 enum rtx_code new_code = UNKNOWN;
598 switch (*code)
600 case EQ: new_code = EQ; break;
601 case NE: new_code = NE; break;
602 case LT: new_code = GTU; break;
603 case GT: new_code = LTU; break;
604 case LE: new_code = GEU; break;
605 case GE: new_code = LEU; break;
606 default: break;
609 if (new_code != UNKNOWN)
611 *op0 = XVECEXP (*op0, 0, 0);
612 *code = new_code;
617 /* Emit a compare instruction suitable to implement the comparison
618 OP0 CODE OP1. Return the correct condition RTL to be placed in
619 the IF_THEN_ELSE of the conditional branch testing the result. */
622 s390_emit_compare (enum rtx_code code, rtx op0, rtx op1)
624 enum machine_mode mode = s390_select_ccmode (code, op0, op1);
625 rtx ret = NULL_RTX;
627 /* Do not output a redundant compare instruction if a compare_and_swap
628 pattern already computed the result and the machine modes match. */
629 if (s390_compare_emitted && GET_MODE (s390_compare_emitted) == mode)
630 ret = gen_rtx_fmt_ee (code, VOIDmode, s390_compare_emitted, const0_rtx);
631 else
633 rtx cc = gen_rtx_REG (mode, CC_REGNUM);
635 emit_insn (gen_rtx_SET (VOIDmode, cc, gen_rtx_COMPARE (mode, op0, op1)));
636 ret = gen_rtx_fmt_ee (code, VOIDmode, cc, const0_rtx);
638 s390_compare_emitted = NULL_RTX;
639 return ret;
642 /* Emit a jump instruction to TARGET. If COND is NULL_RTX, emit an
643 unconditional jump, else a conditional jump under condition COND. */
645 void
646 s390_emit_jump (rtx target, rtx cond)
648 rtx insn;
650 target = gen_rtx_LABEL_REF (VOIDmode, target);
651 if (cond)
652 target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, target, pc_rtx);
654 insn = gen_rtx_SET (VOIDmode, pc_rtx, target);
655 emit_jump_insn (insn);
658 /* Return branch condition mask to implement a branch
659 specified by CODE. Return -1 for invalid comparisons. */
662 s390_branch_condition_mask (rtx code)
664 const int CC0 = 1 << 3;
665 const int CC1 = 1 << 2;
666 const int CC2 = 1 << 1;
667 const int CC3 = 1 << 0;
669 gcc_assert (GET_CODE (XEXP (code, 0)) == REG);
670 gcc_assert (REGNO (XEXP (code, 0)) == CC_REGNUM);
671 gcc_assert (XEXP (code, 1) == const0_rtx);
673 switch (GET_MODE (XEXP (code, 0)))
675 case CCZmode:
676 switch (GET_CODE (code))
678 case EQ: return CC0;
679 case NE: return CC1 | CC2 | CC3;
680 default: return -1;
682 break;
684 case CCT1mode:
685 switch (GET_CODE (code))
687 case EQ: return CC1;
688 case NE: return CC0 | CC2 | CC3;
689 default: return -1;
691 break;
693 case CCT2mode:
694 switch (GET_CODE (code))
696 case EQ: return CC2;
697 case NE: return CC0 | CC1 | CC3;
698 default: return -1;
700 break;
702 case CCT3mode:
703 switch (GET_CODE (code))
705 case EQ: return CC3;
706 case NE: return CC0 | CC1 | CC2;
707 default: return -1;
709 break;
711 case CCLmode:
712 switch (GET_CODE (code))
714 case EQ: return CC0 | CC2;
715 case NE: return CC1 | CC3;
716 default: return -1;
718 break;
720 case CCL1mode:
721 switch (GET_CODE (code))
723 case LTU: return CC2 | CC3; /* carry */
724 case GEU: return CC0 | CC1; /* no carry */
725 default: return -1;
727 break;
729 case CCL2mode:
730 switch (GET_CODE (code))
732 case GTU: return CC0 | CC1; /* borrow */
733 case LEU: return CC2 | CC3; /* no borrow */
734 default: return -1;
736 break;
738 case CCL3mode:
739 switch (GET_CODE (code))
741 case EQ: return CC0 | CC2;
742 case NE: return CC1 | CC3;
743 case LTU: return CC1;
744 case GTU: return CC3;
745 case LEU: return CC1 | CC2;
746 case GEU: return CC2 | CC3;
747 default: return -1;
750 case CCUmode:
751 switch (GET_CODE (code))
753 case EQ: return CC0;
754 case NE: return CC1 | CC2 | CC3;
755 case LTU: return CC1;
756 case GTU: return CC2;
757 case LEU: return CC0 | CC1;
758 case GEU: return CC0 | CC2;
759 default: return -1;
761 break;
763 case CCURmode:
764 switch (GET_CODE (code))
766 case EQ: return CC0;
767 case NE: return CC2 | CC1 | CC3;
768 case LTU: return CC2;
769 case GTU: return CC1;
770 case LEU: return CC0 | CC2;
771 case GEU: return CC0 | CC1;
772 default: return -1;
774 break;
776 case CCAPmode:
777 switch (GET_CODE (code))
779 case EQ: return CC0;
780 case NE: return CC1 | CC2 | CC3;
781 case LT: return CC1 | CC3;
782 case GT: return CC2;
783 case LE: return CC0 | CC1 | CC3;
784 case GE: return CC0 | CC2;
785 default: return -1;
787 break;
789 case CCANmode:
790 switch (GET_CODE (code))
792 case EQ: return CC0;
793 case NE: return CC1 | CC2 | CC3;
794 case LT: return CC1;
795 case GT: return CC2 | CC3;
796 case LE: return CC0 | CC1;
797 case GE: return CC0 | CC2 | CC3;
798 default: return -1;
800 break;
802 case CCSmode:
803 switch (GET_CODE (code))
805 case EQ: return CC0;
806 case NE: return CC1 | CC2 | CC3;
807 case LT: return CC1;
808 case GT: return CC2;
809 case LE: return CC0 | CC1;
810 case GE: return CC0 | CC2;
811 case UNORDERED: return CC3;
812 case ORDERED: return CC0 | CC1 | CC2;
813 case UNEQ: return CC0 | CC3;
814 case UNLT: return CC1 | CC3;
815 case UNGT: return CC2 | CC3;
816 case UNLE: return CC0 | CC1 | CC3;
817 case UNGE: return CC0 | CC2 | CC3;
818 case LTGT: return CC1 | CC2;
819 default: return -1;
821 break;
823 case CCSRmode:
824 switch (GET_CODE (code))
826 case EQ: return CC0;
827 case NE: return CC2 | CC1 | CC3;
828 case LT: return CC2;
829 case GT: return CC1;
830 case LE: return CC0 | CC2;
831 case GE: return CC0 | CC1;
832 case UNORDERED: return CC3;
833 case ORDERED: return CC0 | CC2 | CC1;
834 case UNEQ: return CC0 | CC3;
835 case UNLT: return CC2 | CC3;
836 case UNGT: return CC1 | CC3;
837 case UNLE: return CC0 | CC2 | CC3;
838 case UNGE: return CC0 | CC1 | CC3;
839 case LTGT: return CC2 | CC1;
840 default: return -1;
842 break;
844 default:
845 return -1;
849 /* If INV is false, return assembler mnemonic string to implement
850 a branch specified by CODE. If INV is true, return mnemonic
851 for the corresponding inverted branch. */
853 static const char *
854 s390_branch_condition_mnemonic (rtx code, int inv)
856 static const char *const mnemonic[16] =
858 NULL, "o", "h", "nle",
859 "l", "nhe", "lh", "ne",
860 "e", "nlh", "he", "nl",
861 "le", "nh", "no", NULL
864 int mask = s390_branch_condition_mask (code);
865 gcc_assert (mask >= 0);
867 if (inv)
868 mask ^= 15;
870 gcc_assert (mask >= 1 && mask <= 14);
872 return mnemonic[mask];
875 /* Return the part of op which has a value different from def.
876 The size of the part is determined by mode.
877 Use this function only if you already know that op really
878 contains such a part. */
880 unsigned HOST_WIDE_INT
881 s390_extract_part (rtx op, enum machine_mode mode, int def)
883 unsigned HOST_WIDE_INT value = 0;
884 int max_parts = HOST_BITS_PER_WIDE_INT / GET_MODE_BITSIZE (mode);
885 int part_bits = GET_MODE_BITSIZE (mode);
886 unsigned HOST_WIDE_INT part_mask = (1 << part_bits) - 1;
887 int i;
889 for (i = 0; i < max_parts; i++)
891 if (i == 0)
892 value = (unsigned HOST_WIDE_INT) INTVAL (op);
893 else
894 value >>= part_bits;
896 if ((value & part_mask) != (def & part_mask))
897 return value & part_mask;
900 gcc_unreachable ();
903 /* If OP is an integer constant of mode MODE with exactly one
904 part of mode PART_MODE unequal to DEF, return the number of that
905 part. Otherwise, return -1. */
908 s390_single_part (rtx op,
909 enum machine_mode mode,
910 enum machine_mode part_mode,
911 int def)
913 unsigned HOST_WIDE_INT value = 0;
914 int n_parts = GET_MODE_SIZE (mode) / GET_MODE_SIZE (part_mode);
915 unsigned HOST_WIDE_INT part_mask = (1 << GET_MODE_BITSIZE (part_mode)) - 1;
916 int i, part = -1;
918 if (GET_CODE (op) != CONST_INT)
919 return -1;
921 for (i = 0; i < n_parts; i++)
923 if (i == 0)
924 value = (unsigned HOST_WIDE_INT) INTVAL (op);
925 else
926 value >>= GET_MODE_BITSIZE (part_mode);
928 if ((value & part_mask) != (def & part_mask))
930 if (part != -1)
931 return -1;
932 else
933 part = i;
936 return part == -1 ? -1 : n_parts - 1 - part;
939 /* Check whether we can (and want to) split a double-word
940 move in mode MODE from SRC to DST into two single-word
941 moves, moving the subword FIRST_SUBWORD first. */
943 bool
944 s390_split_ok_p (rtx dst, rtx src, enum machine_mode mode, int first_subword)
946 /* Floating point registers cannot be split. */
947 if (FP_REG_P (src) || FP_REG_P (dst))
948 return false;
950 /* We don't need to split if operands are directly accessible. */
951 if (s_operand (src, mode) || s_operand (dst, mode))
952 return false;
954 /* Non-offsettable memory references cannot be split. */
955 if ((GET_CODE (src) == MEM && !offsettable_memref_p (src))
956 || (GET_CODE (dst) == MEM && !offsettable_memref_p (dst)))
957 return false;
959 /* Moving the first subword must not clobber a register
960 needed to move the second subword. */
961 if (register_operand (dst, mode))
963 rtx subreg = operand_subword (dst, first_subword, 0, mode);
964 if (reg_overlap_mentioned_p (subreg, src))
965 return false;
968 return true;
971 /* Check whether the address of memory reference MEM2 equals exactly
972 the address of memory reference MEM1 plus DELTA. Return true if
973 we can prove this to be the case, false otherwise. */
975 bool
976 s390_offset_p (rtx mem1, rtx mem2, rtx delta)
978 rtx addr1, addr2, addr_delta;
980 if (GET_CODE (mem1) != MEM || GET_CODE (mem2) != MEM)
981 return false;
983 addr1 = XEXP (mem1, 0);
984 addr2 = XEXP (mem2, 0);
986 addr_delta = simplify_binary_operation (MINUS, Pmode, addr2, addr1);
987 if (!addr_delta || !rtx_equal_p (addr_delta, delta))
988 return false;
990 return true;
993 /* Expand logical operator CODE in mode MODE with operands OPERANDS. */
995 void
996 s390_expand_logical_operator (enum rtx_code code, enum machine_mode mode,
997 rtx *operands)
999 enum machine_mode wmode = mode;
1000 rtx dst = operands[0];
1001 rtx src1 = operands[1];
1002 rtx src2 = operands[2];
1003 rtx op, clob, tem;
1005 /* If we cannot handle the operation directly, use a temp register. */
1006 if (!s390_logical_operator_ok_p (operands))
1007 dst = gen_reg_rtx (mode);
1009 /* QImode and HImode patterns make sense only if we have a destination
1010 in memory. Otherwise perform the operation in SImode. */
1011 if ((mode == QImode || mode == HImode) && GET_CODE (dst) != MEM)
1012 wmode = SImode;
1014 /* Widen operands if required. */
1015 if (mode != wmode)
1017 if (GET_CODE (dst) == SUBREG
1018 && (tem = simplify_subreg (wmode, dst, mode, 0)) != 0)
1019 dst = tem;
1020 else if (REG_P (dst))
1021 dst = gen_rtx_SUBREG (wmode, dst, 0);
1022 else
1023 dst = gen_reg_rtx (wmode);
1025 if (GET_CODE (src1) == SUBREG
1026 && (tem = simplify_subreg (wmode, src1, mode, 0)) != 0)
1027 src1 = tem;
1028 else if (GET_MODE (src1) != VOIDmode)
1029 src1 = gen_rtx_SUBREG (wmode, force_reg (mode, src1), 0);
1031 if (GET_CODE (src2) == SUBREG
1032 && (tem = simplify_subreg (wmode, src2, mode, 0)) != 0)
1033 src2 = tem;
1034 else if (GET_MODE (src2) != VOIDmode)
1035 src2 = gen_rtx_SUBREG (wmode, force_reg (mode, src2), 0);
1038 /* Emit the instruction. */
1039 op = gen_rtx_SET (VOIDmode, dst, gen_rtx_fmt_ee (code, wmode, src1, src2));
1040 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
1041 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
1043 /* Fix up the destination if needed. */
1044 if (dst != operands[0])
1045 emit_move_insn (operands[0], gen_lowpart (mode, dst));
1048 /* Check whether OPERANDS are OK for a logical operation (AND, IOR, XOR). */
1050 bool
1051 s390_logical_operator_ok_p (rtx *operands)
1053 /* If the destination operand is in memory, it needs to coincide
1054 with one of the source operands. After reload, it has to be
1055 the first source operand. */
1056 if (GET_CODE (operands[0]) == MEM)
1057 return rtx_equal_p (operands[0], operands[1])
1058 || (!reload_completed && rtx_equal_p (operands[0], operands[2]));
1060 return true;
1063 /* Narrow logical operation CODE of memory operand MEMOP with immediate
1064 operand IMMOP to switch from SS to SI type instructions. */
1066 void
1067 s390_narrow_logical_operator (enum rtx_code code, rtx *memop, rtx *immop)
1069 int def = code == AND ? -1 : 0;
1070 HOST_WIDE_INT mask;
1071 int part;
1073 gcc_assert (GET_CODE (*memop) == MEM);
1074 gcc_assert (!MEM_VOLATILE_P (*memop));
1076 mask = s390_extract_part (*immop, QImode, def);
1077 part = s390_single_part (*immop, GET_MODE (*memop), QImode, def);
1078 gcc_assert (part >= 0);
1080 *memop = adjust_address (*memop, QImode, part);
1081 *immop = gen_int_mode (mask, QImode);
1085 /* How to allocate a 'struct machine_function'. */
1087 static struct machine_function *
1088 s390_init_machine_status (void)
1090 return ggc_alloc_cleared (sizeof (struct machine_function));
1093 /* Change optimizations to be performed, depending on the
1094 optimization level.
1096 LEVEL is the optimization level specified; 2 if `-O2' is
1097 specified, 1 if `-O' is specified, and 0 if neither is specified.
1099 SIZE is nonzero if `-Os' is specified and zero otherwise. */
1101 void
1102 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
1104 /* ??? There are apparently still problems with -fcaller-saves. */
1105 flag_caller_saves = 0;
1107 /* By default, always emit DWARF-2 unwind info. This allows debugging
1108 without maintaining a stack frame back-chain. */
1109 flag_asynchronous_unwind_tables = 1;
1112 /* Return true if ARG is the name of a processor. Set *TYPE and *FLAGS
1113 to the associated processor_type and processor_flags if so. */
1115 static bool
1116 s390_handle_arch_option (const char *arg,
1117 enum processor_type *type,
1118 enum processor_flags *flags)
1120 static struct pta
1122 const char *const name; /* processor name or nickname. */
1123 const enum processor_type processor;
1124 const enum processor_flags flags;
1126 const processor_alias_table[] =
1128 {"g5", PROCESSOR_9672_G5, PF_IEEE_FLOAT},
1129 {"g6", PROCESSOR_9672_G6, PF_IEEE_FLOAT},
1130 {"z900", PROCESSOR_2064_Z900, PF_IEEE_FLOAT | PF_ZARCH},
1131 {"z990", PROCESSOR_2084_Z990, PF_IEEE_FLOAT | PF_ZARCH
1132 | PF_LONG_DISPLACEMENT},
1134 size_t i;
1136 for (i = 0; i < ARRAY_SIZE (processor_alias_table); i++)
1137 if (strcmp (arg, processor_alias_table[i].name) == 0)
1139 *type = processor_alias_table[i].processor;
1140 *flags = processor_alias_table[i].flags;
1141 return true;
1143 return false;
1146 /* Implement TARGET_HANDLE_OPTION. */
1148 static bool
1149 s390_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
1151 switch (code)
1153 case OPT_march_:
1154 return s390_handle_arch_option (arg, &s390_arch, &s390_arch_flags);
1156 case OPT_mstack_guard_:
1157 if (sscanf (arg, HOST_WIDE_INT_PRINT_DEC, &s390_stack_guard) != 1)
1158 return false;
1159 if (exact_log2 (s390_stack_guard) == -1)
1160 error ("stack guard value must be an exact power of 2");
1161 return true;
1163 case OPT_mstack_size_:
1164 if (sscanf (arg, HOST_WIDE_INT_PRINT_DEC, &s390_stack_size) != 1)
1165 return false;
1166 if (exact_log2 (s390_stack_size) == -1)
1167 error ("stack size must be an exact power of 2");
1168 return true;
1170 case OPT_mtune_:
1171 return s390_handle_arch_option (arg, &s390_tune, &s390_tune_flags);
1173 case OPT_mwarn_framesize_:
1174 return sscanf (arg, HOST_WIDE_INT_PRINT_DEC, &s390_warn_framesize) == 1;
1176 default:
1177 return true;
1181 void
1182 override_options (void)
1184 /* Acquire a unique set number for our register saves and restores. */
1185 s390_sr_alias_set = new_alias_set ();
1187 /* Set up function hooks. */
1188 init_machine_status = s390_init_machine_status;
1190 /* Architecture mode defaults according to ABI. */
1191 if (!(target_flags_explicit & MASK_ZARCH))
1193 if (TARGET_64BIT)
1194 target_flags |= MASK_ZARCH;
1195 else
1196 target_flags &= ~MASK_ZARCH;
1199 /* Determine processor architectural level. */
1200 if (!s390_arch_string)
1202 s390_arch_string = TARGET_ZARCH? "z900" : "g5";
1203 s390_handle_arch_option (s390_arch_string, &s390_arch, &s390_arch_flags);
1206 /* Determine processor to tune for. */
1207 if (s390_tune == PROCESSOR_max)
1209 s390_tune = s390_arch;
1210 s390_tune_flags = s390_arch_flags;
1213 /* Sanity checks. */
1214 if (TARGET_ZARCH && !(s390_arch_flags & PF_ZARCH))
1215 error ("z/Architecture mode not supported on %s.", s390_arch_string);
1216 if (TARGET_64BIT && !TARGET_ZARCH)
1217 error ("64-bit ABI not supported in ESA/390 mode.");
1220 /* Set processor cost function. */
1221 if (s390_tune == PROCESSOR_2084_Z990)
1222 s390_cost = &z990_cost;
1223 else
1224 s390_cost = &z900_cost;
1227 if (TARGET_BACKCHAIN && TARGET_PACKED_STACK && TARGET_HARD_FLOAT)
1228 error ("-mbackchain -mpacked-stack -mhard-float are not supported "
1229 "in combination.");
1231 if (s390_stack_size)
1233 if (!s390_stack_guard)
1234 error ("-mstack-size implies use of -mstack-guard");
1235 else if (s390_stack_guard >= s390_stack_size)
1236 error ("stack size must be greater than the stack guard value");
1238 else if (s390_stack_guard)
1239 error ("-mstack-guard implies use of -mstack-size");
1242 /* Map for smallest class containing reg regno. */
1244 const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
1245 { GENERAL_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1246 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1247 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1248 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1249 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1250 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1251 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1252 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1253 ADDR_REGS, CC_REGS, ADDR_REGS, ADDR_REGS,
1254 ACCESS_REGS, ACCESS_REGS
1257 /* Return attribute type of insn. */
1259 static enum attr_type
1260 s390_safe_attr_type (rtx insn)
1262 if (recog_memoized (insn) >= 0)
1263 return get_attr_type (insn);
1264 else
1265 return TYPE_NONE;
1268 /* Return true if DISP is a valid short displacement. */
1270 static bool
1271 s390_short_displacement (rtx disp)
1273 /* No displacement is OK. */
1274 if (!disp)
1275 return true;
1277 /* Integer displacement in range. */
1278 if (GET_CODE (disp) == CONST_INT)
1279 return INTVAL (disp) >= 0 && INTVAL (disp) < 4096;
1281 /* GOT offset is not OK, the GOT can be large. */
1282 if (GET_CODE (disp) == CONST
1283 && GET_CODE (XEXP (disp, 0)) == UNSPEC
1284 && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOT
1285 || XINT (XEXP (disp, 0), 1) == UNSPEC_GOTNTPOFF))
1286 return false;
1288 /* All other symbolic constants are literal pool references,
1289 which are OK as the literal pool must be small. */
1290 if (GET_CODE (disp) == CONST)
1291 return true;
1293 return false;
1296 /* Decompose a RTL expression ADDR for a memory address into
1297 its components, returned in OUT.
1299 Returns false if ADDR is not a valid memory address, true
1300 otherwise. If OUT is NULL, don't return the components,
1301 but check for validity only.
1303 Note: Only addresses in canonical form are recognized.
1304 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
1305 canonical form so that they will be recognized. */
1307 static int
1308 s390_decompose_address (rtx addr, struct s390_address *out)
1310 HOST_WIDE_INT offset = 0;
1311 rtx base = NULL_RTX;
1312 rtx indx = NULL_RTX;
1313 rtx disp = NULL_RTX;
1314 rtx orig_disp;
1315 bool pointer = false;
1316 bool base_ptr = false;
1317 bool indx_ptr = false;
1319 /* Decompose address into base + index + displacement. */
1321 if (GET_CODE (addr) == REG || GET_CODE (addr) == UNSPEC)
1322 base = addr;
1324 else if (GET_CODE (addr) == PLUS)
1326 rtx op0 = XEXP (addr, 0);
1327 rtx op1 = XEXP (addr, 1);
1328 enum rtx_code code0 = GET_CODE (op0);
1329 enum rtx_code code1 = GET_CODE (op1);
1331 if (code0 == REG || code0 == UNSPEC)
1333 if (code1 == REG || code1 == UNSPEC)
1335 indx = op0; /* index + base */
1336 base = op1;
1339 else
1341 base = op0; /* base + displacement */
1342 disp = op1;
1346 else if (code0 == PLUS)
1348 indx = XEXP (op0, 0); /* index + base + disp */
1349 base = XEXP (op0, 1);
1350 disp = op1;
1353 else
1355 return false;
1359 else
1360 disp = addr; /* displacement */
1362 /* Extract integer part of displacement. */
1363 orig_disp = disp;
1364 if (disp)
1366 if (GET_CODE (disp) == CONST_INT)
1368 offset = INTVAL (disp);
1369 disp = NULL_RTX;
1371 else if (GET_CODE (disp) == CONST
1372 && GET_CODE (XEXP (disp, 0)) == PLUS
1373 && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT)
1375 offset = INTVAL (XEXP (XEXP (disp, 0), 1));
1376 disp = XEXP (XEXP (disp, 0), 0);
1380 /* Strip off CONST here to avoid special case tests later. */
1381 if (disp && GET_CODE (disp) == CONST)
1382 disp = XEXP (disp, 0);
1384 /* We can convert literal pool addresses to
1385 displacements by basing them off the base register. */
1386 if (disp && GET_CODE (disp) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (disp))
1388 /* Either base or index must be free to hold the base register. */
1389 if (!base)
1390 base = gen_rtx_REG (Pmode, BASE_REGNUM);
1391 else if (!indx)
1392 indx = gen_rtx_REG (Pmode, BASE_REGNUM);
1393 else
1394 return false;
1396 /* Mark up the displacement. */
1397 disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp),
1398 UNSPEC_LTREL_OFFSET);
1401 /* Validate base register. */
1402 if (base)
1404 if (GET_CODE (base) == UNSPEC)
1405 switch (XINT (base, 1))
1407 case UNSPEC_LTREF:
1408 if (!disp)
1409 disp = gen_rtx_UNSPEC (Pmode,
1410 gen_rtvec (1, XVECEXP (base, 0, 0)),
1411 UNSPEC_LTREL_OFFSET);
1412 else
1413 return false;
1415 base = gen_rtx_REG (Pmode, BASE_REGNUM);
1416 break;
1418 case UNSPEC_LTREL_BASE:
1419 base = gen_rtx_REG (Pmode, BASE_REGNUM);
1420 break;
1422 default:
1423 return false;
1426 if (GET_CODE (base) != REG || GET_MODE (base) != Pmode)
1427 return false;
1429 if (REGNO (base) == BASE_REGNUM
1430 || REGNO (base) == STACK_POINTER_REGNUM
1431 || REGNO (base) == FRAME_POINTER_REGNUM
1432 || ((reload_completed || reload_in_progress)
1433 && frame_pointer_needed
1434 && REGNO (base) == HARD_FRAME_POINTER_REGNUM)
1435 || REGNO (base) == ARG_POINTER_REGNUM
1436 || (flag_pic
1437 && REGNO (base) == PIC_OFFSET_TABLE_REGNUM))
1438 pointer = base_ptr = true;
1441 /* Validate index register. */
1442 if (indx)
1444 if (GET_CODE (indx) == UNSPEC)
1445 switch (XINT (indx, 1))
1447 case UNSPEC_LTREF:
1448 if (!disp)
1449 disp = gen_rtx_UNSPEC (Pmode,
1450 gen_rtvec (1, XVECEXP (indx, 0, 0)),
1451 UNSPEC_LTREL_OFFSET);
1452 else
1453 return false;
1455 indx = gen_rtx_REG (Pmode, BASE_REGNUM);
1456 break;
1458 case UNSPEC_LTREL_BASE:
1459 indx = gen_rtx_REG (Pmode, BASE_REGNUM);
1460 break;
1462 default:
1463 return false;
1466 if (GET_CODE (indx) != REG || GET_MODE (indx) != Pmode)
1467 return false;
1469 if (REGNO (indx) == BASE_REGNUM
1470 || REGNO (indx) == STACK_POINTER_REGNUM
1471 || REGNO (indx) == FRAME_POINTER_REGNUM
1472 || ((reload_completed || reload_in_progress)
1473 && frame_pointer_needed
1474 && REGNO (indx) == HARD_FRAME_POINTER_REGNUM)
1475 || REGNO (indx) == ARG_POINTER_REGNUM
1476 || (flag_pic
1477 && REGNO (indx) == PIC_OFFSET_TABLE_REGNUM))
1478 pointer = indx_ptr = true;
1481 /* Prefer to use pointer as base, not index. */
1482 if (base && indx && !base_ptr
1483 && (indx_ptr || (!REG_POINTER (base) && REG_POINTER (indx))))
1485 rtx tmp = base;
1486 base = indx;
1487 indx = tmp;
1490 /* Validate displacement. */
1491 if (!disp)
1493 /* If virtual registers are involved, the displacement will change later
1494 anyway as the virtual registers get eliminated. This could make a
1495 valid displacement invalid, but it is more likely to make an invalid
1496 displacement valid, because we sometimes access the register save area
1497 via negative offsets to one of those registers.
1498 Thus we don't check the displacement for validity here. If after
1499 elimination the displacement turns out to be invalid after all,
1500 this is fixed up by reload in any case. */
1501 if (base != arg_pointer_rtx
1502 && indx != arg_pointer_rtx
1503 && base != return_address_pointer_rtx
1504 && indx != return_address_pointer_rtx
1505 && base != frame_pointer_rtx
1506 && indx != frame_pointer_rtx
1507 && base != virtual_stack_vars_rtx
1508 && indx != virtual_stack_vars_rtx)
1509 if (!DISP_IN_RANGE (offset))
1510 return false;
1512 else
1514 /* All the special cases are pointers. */
1515 pointer = true;
1517 /* In the small-PIC case, the linker converts @GOT
1518 and @GOTNTPOFF offsets to possible displacements. */
1519 if (GET_CODE (disp) == UNSPEC
1520 && (XINT (disp, 1) == UNSPEC_GOT
1521 || XINT (disp, 1) == UNSPEC_GOTNTPOFF)
1522 && offset == 0
1523 && flag_pic == 1)
1528 /* Accept chunkified literal pool symbol references. */
1529 else if (GET_CODE (disp) == MINUS
1530 && GET_CODE (XEXP (disp, 0)) == LABEL_REF
1531 && GET_CODE (XEXP (disp, 1)) == LABEL_REF)
1536 /* Accept literal pool references. */
1537 else if (GET_CODE (disp) == UNSPEC
1538 && XINT (disp, 1) == UNSPEC_LTREL_OFFSET)
1540 orig_disp = gen_rtx_CONST (Pmode, disp);
1541 if (offset)
1543 /* If we have an offset, make sure it does not
1544 exceed the size of the constant pool entry. */
1545 rtx sym = XVECEXP (disp, 0, 0);
1546 if (offset >= GET_MODE_SIZE (get_pool_mode (sym)))
1547 return false;
1549 orig_disp = plus_constant (orig_disp, offset);
1553 else
1554 return false;
1557 if (!base && !indx)
1558 pointer = true;
1560 if (out)
1562 out->base = base;
1563 out->indx = indx;
1564 out->disp = orig_disp;
1565 out->pointer = pointer;
1568 return true;
1571 /* Return true if CODE is a valid address without index. */
1573 bool
1574 s390_legitimate_address_without_index_p (rtx op)
1576 struct s390_address addr;
1578 if (!s390_decompose_address (XEXP (op, 0), &addr))
1579 return false;
1580 if (addr.indx)
1581 return false;
1583 return true;
1586 /* Return 1 if OP is a valid operand for a C constraint, 0 else. */
1589 s390_extra_constraint_str (rtx op, int c, const char * str)
1591 struct s390_address addr;
1593 gcc_assert (c == str[0]);
1595 /* Check for offsettable variants of memory constraints. */
1596 if (c == 'A')
1598 /* Only accept non-volatile MEMs. */
1599 if (!MEM_P (op) || MEM_VOLATILE_P (op))
1600 return 0;
1602 if ((reload_completed || reload_in_progress)
1603 ? !offsettable_memref_p (op)
1604 : !offsettable_nonstrict_memref_p (op))
1605 return 0;
1607 c = str[1];
1610 /* Check for non-literal-pool variants of memory constraints. */
1611 else if (c == 'B')
1613 if (GET_CODE (op) != MEM)
1614 return 0;
1615 if (!s390_decompose_address (XEXP (op, 0), &addr))
1616 return 0;
1617 if (addr.base && REG_P (addr.base) && REGNO (addr.base) == BASE_REGNUM)
1618 return 0;
1619 if (addr.indx && REG_P (addr.indx) && REGNO (addr.indx) == BASE_REGNUM)
1620 return 0;
1622 c = str[1];
1625 switch (c)
1627 case 'Q':
1628 if (GET_CODE (op) != MEM)
1629 return 0;
1630 if (!s390_decompose_address (XEXP (op, 0), &addr))
1631 return 0;
1632 if (addr.indx)
1633 return 0;
1635 if (TARGET_LONG_DISPLACEMENT)
1637 if (!s390_short_displacement (addr.disp))
1638 return 0;
1640 break;
1642 case 'R':
1643 if (GET_CODE (op) != MEM)
1644 return 0;
1646 if (TARGET_LONG_DISPLACEMENT)
1648 if (!s390_decompose_address (XEXP (op, 0), &addr))
1649 return 0;
1650 if (!s390_short_displacement (addr.disp))
1651 return 0;
1653 break;
1655 case 'S':
1656 if (!TARGET_LONG_DISPLACEMENT)
1657 return 0;
1658 if (GET_CODE (op) != MEM)
1659 return 0;
1660 if (!s390_decompose_address (XEXP (op, 0), &addr))
1661 return 0;
1662 if (addr.indx)
1663 return 0;
1664 if (s390_short_displacement (addr.disp))
1665 return 0;
1666 break;
1668 case 'T':
1669 if (!TARGET_LONG_DISPLACEMENT)
1670 return 0;
1671 if (GET_CODE (op) != MEM)
1672 return 0;
1673 /* Any invalid address here will be fixed up by reload,
1674 so accept it for the most generic constraint. */
1675 if (s390_decompose_address (XEXP (op, 0), &addr)
1676 && s390_short_displacement (addr.disp))
1677 return 0;
1678 break;
1680 case 'U':
1681 if (TARGET_LONG_DISPLACEMENT)
1683 if (!s390_decompose_address (op, &addr))
1684 return 0;
1685 if (!s390_short_displacement (addr.disp))
1686 return 0;
1688 break;
1690 case 'W':
1691 if (!TARGET_LONG_DISPLACEMENT)
1692 return 0;
1693 /* Any invalid address here will be fixed up by reload,
1694 so accept it for the most generic constraint. */
1695 if (s390_decompose_address (op, &addr)
1696 && s390_short_displacement (addr.disp))
1697 return 0;
1698 break;
1700 case 'Y':
1701 return shift_count_operand (op, VOIDmode);
1703 default:
1704 return 0;
1707 return 1;
1710 /* Return true if VALUE matches the constraint STR. */
1713 s390_const_double_ok_for_constraint_p (rtx value,
1714 int c,
1715 const char * str)
1717 gcc_assert (c == str[0]);
1719 switch (str[0])
1721 case 'G':
1722 /* The floating point zero constant. */
1723 return (GET_MODE_CLASS (GET_MODE (value)) == MODE_FLOAT
1724 && value == CONST0_RTX (GET_MODE (value)));
1726 default:
1727 return 0;
1731 /* Return true if VALUE matches the constraint STR. */
1734 s390_const_ok_for_constraint_p (HOST_WIDE_INT value,
1735 int c,
1736 const char * str)
1738 enum machine_mode mode, part_mode;
1739 int def;
1740 int part, part_goal;
1742 gcc_assert (c == str[0]);
1744 switch (str[0])
1746 case 'I':
1747 return (unsigned int)value < 256;
1749 case 'J':
1750 return (unsigned int)value < 4096;
1752 case 'K':
1753 return value >= -32768 && value < 32768;
1755 case 'L':
1756 return (TARGET_LONG_DISPLACEMENT ?
1757 (value >= -524288 && value <= 524287)
1758 : (value >= 0 && value <= 4095));
1759 case 'M':
1760 return value == 2147483647;
1762 case 'N':
1763 if (str[1] == 'x')
1764 part_goal = -1;
1765 else
1766 part_goal = str[1] - '0';
1768 switch (str[2])
1770 case 'H': part_mode = HImode; break;
1771 case 'Q': part_mode = QImode; break;
1772 default: return 0;
1775 switch (str[3])
1777 case 'H': mode = HImode; break;
1778 case 'S': mode = SImode; break;
1779 case 'D': mode = DImode; break;
1780 default: return 0;
1783 switch (str[4])
1785 case '0': def = 0; break;
1786 case 'F': def = -1; break;
1787 default: return 0;
1790 if (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (part_mode))
1791 return 0;
1793 part = s390_single_part (GEN_INT (value), mode, part_mode, def);
1794 if (part < 0)
1795 return 0;
1796 if (part_goal != -1 && part_goal != part)
1797 return 0;
1799 break;
1801 default:
1802 return 0;
1805 return 1;
1808 /* Compute a (partial) cost for rtx X. Return true if the complete
1809 cost has been computed, and false if subexpressions should be
1810 scanned. In either case, *TOTAL contains the cost result.
1811 CODE contains GET_CODE (x), OUTER_CODE contains the code
1812 of the superexpression of x. */
1814 static bool
1815 s390_rtx_costs (rtx x, int code, int outer_code, int *total)
1817 switch (code)
1819 case CONST:
1820 case CONST_INT:
1821 case LABEL_REF:
1822 case SYMBOL_REF:
1823 case CONST_DOUBLE:
1824 case MEM:
1825 *total = 0;
1826 return true;
1828 case ASHIFT:
1829 case ASHIFTRT:
1830 case LSHIFTRT:
1831 case ROTATE:
1832 case ROTATERT:
1833 case AND:
1834 case IOR:
1835 case XOR:
1836 case NEG:
1837 case NOT:
1838 *total = COSTS_N_INSNS (1);
1839 return false;
1841 case PLUS:
1842 case MINUS:
1843 /* Check for multiply and add. */
1844 if ((GET_MODE (x) == DFmode || GET_MODE (x) == SFmode)
1845 && GET_CODE (XEXP (x, 0)) == MULT
1846 && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD)
1848 /* This is the multiply and add case. */
1849 if (GET_MODE (x) == DFmode)
1850 *total = s390_cost->madbr;
1851 else
1852 *total = s390_cost->maebr;
1853 *total += rtx_cost (XEXP (XEXP (x, 0), 0), MULT)
1854 + rtx_cost (XEXP (XEXP (x, 0), 1), MULT)
1855 + rtx_cost (XEXP (x, 1), code);
1856 return true; /* Do not do an additional recursive descent. */
1858 *total = COSTS_N_INSNS (1);
1859 return false;
1861 case MULT:
1862 switch (GET_MODE (x))
1864 case SImode:
1866 rtx left = XEXP (x, 0);
1867 rtx right = XEXP (x, 1);
1868 if (GET_CODE (right) == CONST_INT
1869 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (right), 'K', "K"))
1870 *total = s390_cost->mhi;
1871 else if (GET_CODE (left) == SIGN_EXTEND)
1872 *total = s390_cost->mh;
1873 else
1874 *total = s390_cost->ms; /* msr, ms, msy */
1875 break;
1877 case DImode:
1879 rtx left = XEXP (x, 0);
1880 rtx right = XEXP (x, 1);
1881 if (TARGET_64BIT)
1883 if (GET_CODE (right) == CONST_INT
1884 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (right), 'K', "K"))
1885 *total = s390_cost->mghi;
1886 else if (GET_CODE (left) == SIGN_EXTEND)
1887 *total = s390_cost->msgf;
1888 else
1889 *total = s390_cost->msg; /* msgr, msg */
1891 else /* TARGET_31BIT */
1893 if (GET_CODE (left) == SIGN_EXTEND
1894 && GET_CODE (right) == SIGN_EXTEND)
1895 /* mulsidi case: mr, m */
1896 *total = s390_cost->m;
1897 else if (GET_CODE (left) == ZERO_EXTEND
1898 && GET_CODE (right) == ZERO_EXTEND
1899 && TARGET_CPU_ZARCH)
1900 /* umulsidi case: ml, mlr */
1901 *total = s390_cost->ml;
1902 else
1903 /* Complex calculation is required. */
1904 *total = COSTS_N_INSNS (40);
1906 break;
1908 case SFmode:
1909 case DFmode:
1910 *total = s390_cost->mult_df;
1911 break;
1912 default:
1913 return false;
1915 return false;
1917 case UDIV:
1918 case UMOD:
1919 if (GET_MODE (x) == TImode) /* 128 bit division */
1920 *total = s390_cost->dlgr;
1921 else if (GET_MODE (x) == DImode)
1923 rtx right = XEXP (x, 1);
1924 if (GET_CODE (right) == ZERO_EXTEND) /* 64 by 32 bit division */
1925 *total = s390_cost->dlr;
1926 else /* 64 by 64 bit division */
1927 *total = s390_cost->dlgr;
1929 else if (GET_MODE (x) == SImode) /* 32 bit division */
1930 *total = s390_cost->dlr;
1931 return false;
1933 case DIV:
1934 case MOD:
1935 if (GET_MODE (x) == DImode)
1937 rtx right = XEXP (x, 1);
1938 if (GET_CODE (right) == ZERO_EXTEND) /* 64 by 32 bit division */
1939 if (TARGET_64BIT)
1940 *total = s390_cost->dsgfr;
1941 else
1942 *total = s390_cost->dr;
1943 else /* 64 by 64 bit division */
1944 *total = s390_cost->dsgr;
1946 else if (GET_MODE (x) == SImode) /* 32 bit division */
1947 *total = s390_cost->dlr;
1948 else if (GET_MODE (x) == SFmode)
1950 if (TARGET_IEEE_FLOAT)
1951 *total = s390_cost->debr;
1952 else /* TARGET_IBM_FLOAT */
1953 *total = s390_cost->der;
1955 else if (GET_MODE (x) == DFmode)
1957 if (TARGET_IEEE_FLOAT)
1958 *total = s390_cost->ddbr;
1959 else /* TARGET_IBM_FLOAT */
1960 *total = s390_cost->ddr;
1962 return false;
1964 case SQRT:
1965 if (GET_MODE (x) == SFmode)
1966 *total = s390_cost->sqebr;
1967 else /* DFmode */
1968 *total = s390_cost->sqdbr;
1969 return false;
1971 case SIGN_EXTEND:
1972 case ZERO_EXTEND:
1973 if (outer_code == MULT || outer_code == DIV || outer_code == MOD
1974 || outer_code == PLUS || outer_code == MINUS
1975 || outer_code == COMPARE)
1976 *total = 0;
1977 return false;
1979 case COMPARE:
1980 *total = COSTS_N_INSNS (1);
1981 if (GET_CODE (XEXP (x, 0)) == AND
1982 && GET_CODE (XEXP (x, 1)) == CONST_INT
1983 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
1985 rtx op0 = XEXP (XEXP (x, 0), 0);
1986 rtx op1 = XEXP (XEXP (x, 0), 1);
1987 rtx op2 = XEXP (x, 1);
1989 if (memory_operand (op0, GET_MODE (op0))
1990 && s390_tm_ccmode (op1, op2, 0) != VOIDmode)
1991 return true;
1992 if (register_operand (op0, GET_MODE (op0))
1993 && s390_tm_ccmode (op1, op2, 1) != VOIDmode)
1994 return true;
1996 return false;
1998 default:
1999 return false;
2003 /* Return the cost of an address rtx ADDR. */
2005 static int
2006 s390_address_cost (rtx addr)
2008 struct s390_address ad;
2009 if (!s390_decompose_address (addr, &ad))
2010 return 1000;
2012 return ad.indx? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
2015 /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
2016 otherwise return 0. */
2019 tls_symbolic_operand (rtx op)
2021 if (GET_CODE (op) != SYMBOL_REF)
2022 return 0;
2023 return SYMBOL_REF_TLS_MODEL (op);
2026 /* Split DImode access register reference REG (on 64-bit) into its constituent
2027 low and high parts, and store them into LO and HI. Note that gen_lowpart/
2028 gen_highpart cannot be used as they assume all registers are word-sized,
2029 while our access registers have only half that size. */
2031 void
2032 s390_split_access_reg (rtx reg, rtx *lo, rtx *hi)
2034 gcc_assert (TARGET_64BIT);
2035 gcc_assert (ACCESS_REG_P (reg));
2036 gcc_assert (GET_MODE (reg) == DImode);
2037 gcc_assert (!(REGNO (reg) & 1));
2039 *lo = gen_rtx_REG (SImode, REGNO (reg) + 1);
2040 *hi = gen_rtx_REG (SImode, REGNO (reg));
2043 /* Return true if OP contains a symbol reference */
2045 bool
2046 symbolic_reference_mentioned_p (rtx op)
2048 const char *fmt;
2049 int i;
2051 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
2052 return 1;
2054 fmt = GET_RTX_FORMAT (GET_CODE (op));
2055 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
2057 if (fmt[i] == 'E')
2059 int j;
2061 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
2062 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
2063 return 1;
2066 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
2067 return 1;
2070 return 0;
2073 /* Return true if OP contains a reference to a thread-local symbol. */
2075 bool
2076 tls_symbolic_reference_mentioned_p (rtx op)
2078 const char *fmt;
2079 int i;
2081 if (GET_CODE (op) == SYMBOL_REF)
2082 return tls_symbolic_operand (op);
2084 fmt = GET_RTX_FORMAT (GET_CODE (op));
2085 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
2087 if (fmt[i] == 'E')
2089 int j;
2091 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
2092 if (tls_symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
2093 return true;
2096 else if (fmt[i] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op, i)))
2097 return true;
2100 return false;
2104 /* Return true if OP is a legitimate general operand when
2105 generating PIC code. It is given that flag_pic is on
2106 and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2109 legitimate_pic_operand_p (rtx op)
2111 /* Accept all non-symbolic constants. */
2112 if (!SYMBOLIC_CONST (op))
2113 return 1;
2115 /* Reject everything else; must be handled
2116 via emit_symbolic_move. */
2117 return 0;
2120 /* Returns true if the constant value OP is a legitimate general operand.
2121 It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2124 legitimate_constant_p (rtx op)
2126 /* Accept all non-symbolic constants. */
2127 if (!SYMBOLIC_CONST (op))
2128 return 1;
2130 /* Accept immediate LARL operands. */
2131 if (TARGET_CPU_ZARCH && larl_operand (op, VOIDmode))
2132 return 1;
2134 /* Thread-local symbols are never legal constants. This is
2135 so that emit_call knows that computing such addresses
2136 might require a function call. */
2137 if (TLS_SYMBOLIC_CONST (op))
2138 return 0;
2140 /* In the PIC case, symbolic constants must *not* be
2141 forced into the literal pool. We accept them here,
2142 so that they will be handled by emit_symbolic_move. */
2143 if (flag_pic)
2144 return 1;
2146 /* All remaining non-PIC symbolic constants are
2147 forced into the literal pool. */
2148 return 0;
2151 /* Determine if it's legal to put X into the constant pool. This
2152 is not possible if X contains the address of a symbol that is
2153 not constant (TLS) or not known at final link time (PIC). */
2155 static bool
2156 s390_cannot_force_const_mem (rtx x)
2158 switch (GET_CODE (x))
2160 case CONST_INT:
2161 case CONST_DOUBLE:
2162 /* Accept all non-symbolic constants. */
2163 return false;
2165 case LABEL_REF:
2166 /* Labels are OK iff we are non-PIC. */
2167 return flag_pic != 0;
2169 case SYMBOL_REF:
2170 /* 'Naked' TLS symbol references are never OK,
2171 non-TLS symbols are OK iff we are non-PIC. */
2172 if (tls_symbolic_operand (x))
2173 return true;
2174 else
2175 return flag_pic != 0;
2177 case CONST:
2178 return s390_cannot_force_const_mem (XEXP (x, 0));
2179 case PLUS:
2180 case MINUS:
2181 return s390_cannot_force_const_mem (XEXP (x, 0))
2182 || s390_cannot_force_const_mem (XEXP (x, 1));
2184 case UNSPEC:
2185 switch (XINT (x, 1))
2187 /* Only lt-relative or GOT-relative UNSPECs are OK. */
2188 case UNSPEC_LTREL_OFFSET:
2189 case UNSPEC_GOT:
2190 case UNSPEC_GOTOFF:
2191 case UNSPEC_PLTOFF:
2192 case UNSPEC_TLSGD:
2193 case UNSPEC_TLSLDM:
2194 case UNSPEC_NTPOFF:
2195 case UNSPEC_DTPOFF:
2196 case UNSPEC_GOTNTPOFF:
2197 case UNSPEC_INDNTPOFF:
2198 return false;
2200 /* If the literal pool shares the code section, be put
2201 execute template placeholders into the pool as well. */
2202 case UNSPEC_INSN:
2203 return TARGET_CPU_ZARCH;
2205 default:
2206 return true;
2208 break;
2210 default:
2211 gcc_unreachable ();
2215 /* Returns true if the constant value OP is a legitimate general
2216 operand during and after reload. The difference to
2217 legitimate_constant_p is that this function will not accept
2218 a constant that would need to be forced to the literal pool
2219 before it can be used as operand. */
2221 bool
2222 legitimate_reload_constant_p (rtx op)
2224 /* Accept la(y) operands. */
2225 if (GET_CODE (op) == CONST_INT
2226 && DISP_IN_RANGE (INTVAL (op)))
2227 return true;
2229 /* Accept l(g)hi operands. */
2230 if (GET_CODE (op) == CONST_INT
2231 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'K', "K"))
2232 return true;
2234 /* Accept lliXX operands. */
2235 if (TARGET_ZARCH
2236 && s390_single_part (op, DImode, HImode, 0) >= 0)
2237 return true;
2239 /* Accept larl operands. */
2240 if (TARGET_CPU_ZARCH
2241 && larl_operand (op, VOIDmode))
2242 return true;
2244 /* Accept lzXX operands. */
2245 if (GET_CODE (op) == CONST_DOUBLE
2246 && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, 'G', "G"))
2247 return true;
2249 /* Everything else cannot be handled without reload. */
2250 return false;
2253 /* Given an rtx OP being reloaded into a reg required to be in class CLASS,
2254 return the class of reg to actually use. */
2256 enum reg_class
2257 s390_preferred_reload_class (rtx op, enum reg_class class)
2259 switch (GET_CODE (op))
2261 /* Constants we cannot reload must be forced into the
2262 literal pool. */
2264 case CONST_DOUBLE:
2265 case CONST_INT:
2266 if (legitimate_reload_constant_p (op))
2267 return class;
2268 else
2269 return NO_REGS;
2271 /* If a symbolic constant or a PLUS is reloaded,
2272 it is most likely being used as an address, so
2273 prefer ADDR_REGS. If 'class' is not a superset
2274 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
2275 case PLUS:
2276 case LABEL_REF:
2277 case SYMBOL_REF:
2278 case CONST:
2279 if (reg_class_subset_p (ADDR_REGS, class))
2280 return ADDR_REGS;
2281 else
2282 return NO_REGS;
2284 default:
2285 break;
2288 return class;
2291 /* Return the register class of a scratch register needed to
2292 load IN into a register of class CLASS in MODE.
2294 We need a temporary when loading a PLUS expression which
2295 is not a legitimate operand of the LOAD ADDRESS instruction. */
2297 enum reg_class
2298 s390_secondary_input_reload_class (enum reg_class class,
2299 enum machine_mode mode, rtx in)
2301 if (s390_plus_operand (in, mode))
2302 return ADDR_REGS;
2304 if (reg_classes_intersect_p (CC_REGS, class))
2305 return GENERAL_REGS;
2307 return NO_REGS;
2310 /* Return the register class of a scratch register needed to
2311 store a register of class CLASS in MODE into OUT:
2313 We need a temporary when storing a double-word to a
2314 non-offsettable memory address. */
2316 enum reg_class
2317 s390_secondary_output_reload_class (enum reg_class class,
2318 enum machine_mode mode, rtx out)
2320 if ((TARGET_64BIT ? mode == TImode
2321 : (mode == DImode || mode == DFmode))
2322 && reg_classes_intersect_p (GENERAL_REGS, class)
2323 && GET_CODE (out) == MEM
2324 && GET_CODE (XEXP (out, 0)) == PLUS
2325 && GET_CODE (XEXP (XEXP (out, 0), 0)) == PLUS
2326 && GET_CODE (XEXP (XEXP (out, 0), 1)) == CONST_INT
2327 && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (out, 0), 1))
2328 + GET_MODE_SIZE (mode) - 1))
2329 return ADDR_REGS;
2331 if (reg_classes_intersect_p (CC_REGS, class))
2332 return GENERAL_REGS;
2334 return NO_REGS;
2337 /* Generate code to load SRC, which is PLUS that is not a
2338 legitimate operand for the LA instruction, into TARGET.
2339 SCRATCH may be used as scratch register. */
2341 void
2342 s390_expand_plus_operand (rtx target, rtx src,
2343 rtx scratch)
2345 rtx sum1, sum2;
2346 struct s390_address ad;
2348 /* src must be a PLUS; get its two operands. */
2349 gcc_assert (GET_CODE (src) == PLUS);
2350 gcc_assert (GET_MODE (src) == Pmode);
2352 /* Check if any of the two operands is already scheduled
2353 for replacement by reload. This can happen e.g. when
2354 float registers occur in an address. */
2355 sum1 = find_replacement (&XEXP (src, 0));
2356 sum2 = find_replacement (&XEXP (src, 1));
2357 src = gen_rtx_PLUS (Pmode, sum1, sum2);
2359 /* If the address is already strictly valid, there's nothing to do. */
2360 if (!s390_decompose_address (src, &ad)
2361 || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
2362 || (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
2364 /* Otherwise, one of the operands cannot be an address register;
2365 we reload its value into the scratch register. */
2366 if (true_regnum (sum1) < 1 || true_regnum (sum1) > 15)
2368 emit_move_insn (scratch, sum1);
2369 sum1 = scratch;
2371 if (true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
2373 emit_move_insn (scratch, sum2);
2374 sum2 = scratch;
2377 /* According to the way these invalid addresses are generated
2378 in reload.c, it should never happen (at least on s390) that
2379 *neither* of the PLUS components, after find_replacements
2380 was applied, is an address register. */
2381 if (sum1 == scratch && sum2 == scratch)
2383 debug_rtx (src);
2384 gcc_unreachable ();
2387 src = gen_rtx_PLUS (Pmode, sum1, sum2);
2390 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
2391 is only ever performed on addresses, so we can mark the
2392 sum as legitimate for LA in any case. */
2393 s390_load_address (target, src);
2397 /* Return true if ADDR is a valid memory address.
2398 STRICT specifies whether strict register checking applies. */
2400 bool
2401 legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
2402 rtx addr, int strict)
2404 struct s390_address ad;
2405 if (!s390_decompose_address (addr, &ad))
2406 return false;
2408 if (strict)
2410 if (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
2411 return false;
2412 if (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx))
2413 return false;
2415 else
2417 if (ad.base && !REG_OK_FOR_BASE_NONSTRICT_P (ad.base))
2418 return false;
2419 if (ad.indx && !REG_OK_FOR_INDEX_NONSTRICT_P (ad.indx))
2420 return false;
2423 return true;
2426 /* Return true if OP is a valid operand for the LA instruction.
2427 In 31-bit, we need to prove that the result is used as an
2428 address, as LA performs only a 31-bit addition. */
2430 bool
2431 legitimate_la_operand_p (rtx op)
2433 struct s390_address addr;
2434 if (!s390_decompose_address (op, &addr))
2435 return false;
2437 return (TARGET_64BIT || addr.pointer);
2440 /* Return true if it is valid *and* preferable to use LA to
2441 compute the sum of OP1 and OP2. */
2443 bool
2444 preferred_la_operand_p (rtx op1, rtx op2)
2446 struct s390_address addr;
2448 if (op2 != const0_rtx)
2449 op1 = gen_rtx_PLUS (Pmode, op1, op2);
2451 if (!s390_decompose_address (op1, &addr))
2452 return false;
2453 if (addr.base && !REG_OK_FOR_BASE_STRICT_P (addr.base))
2454 return false;
2455 if (addr.indx && !REG_OK_FOR_INDEX_STRICT_P (addr.indx))
2456 return false;
2458 if (!TARGET_64BIT && !addr.pointer)
2459 return false;
2461 if (addr.pointer)
2462 return true;
2464 if ((addr.base && REG_P (addr.base) && REG_POINTER (addr.base))
2465 || (addr.indx && REG_P (addr.indx) && REG_POINTER (addr.indx)))
2466 return true;
2468 return false;
2471 /* Emit a forced load-address operation to load SRC into DST.
2472 This will use the LOAD ADDRESS instruction even in situations
2473 where legitimate_la_operand_p (SRC) returns false. */
2475 void
2476 s390_load_address (rtx dst, rtx src)
2478 if (TARGET_64BIT)
2479 emit_move_insn (dst, src);
2480 else
2481 emit_insn (gen_force_la_31 (dst, src));
2484 /* Return a legitimate reference for ORIG (an address) using the
2485 register REG. If REG is 0, a new pseudo is generated.
2487 There are two types of references that must be handled:
2489 1. Global data references must load the address from the GOT, via
2490 the PIC reg. An insn is emitted to do this load, and the reg is
2491 returned.
2493 2. Static data references, constant pool addresses, and code labels
2494 compute the address as an offset from the GOT, whose base is in
2495 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
2496 differentiate them from global data objects. The returned
2497 address is the PIC reg + an unspec constant.
2499 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2500 reg also appears in the address. */
2503 legitimize_pic_address (rtx orig, rtx reg)
2505 rtx addr = orig;
2506 rtx new = orig;
2507 rtx base;
2509 if (GET_CODE (addr) == LABEL_REF
2510 || (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (addr)))
2512 /* This is a local symbol. */
2513 if (TARGET_CPU_ZARCH && larl_operand (addr, VOIDmode))
2515 /* Access local symbols PC-relative via LARL.
2516 This is the same as in the non-PIC case, so it is
2517 handled automatically ... */
2519 else
2521 /* Access local symbols relative to the GOT. */
2523 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2525 if (reload_in_progress || reload_completed)
2526 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2528 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
2529 addr = gen_rtx_CONST (Pmode, addr);
2530 addr = force_const_mem (Pmode, addr);
2531 emit_move_insn (temp, addr);
2533 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2534 if (reg != 0)
2536 s390_load_address (reg, new);
2537 new = reg;
2541 else if (GET_CODE (addr) == SYMBOL_REF)
2543 if (reg == 0)
2544 reg = gen_reg_rtx (Pmode);
2546 if (flag_pic == 1)
2548 /* Assume GOT offset < 4k. This is handled the same way
2549 in both 31- and 64-bit code (@GOT). */
2551 if (reload_in_progress || reload_completed)
2552 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2554 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
2555 new = gen_rtx_CONST (Pmode, new);
2556 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
2557 new = gen_const_mem (Pmode, new);
2558 emit_move_insn (reg, new);
2559 new = reg;
2561 else if (TARGET_CPU_ZARCH)
2563 /* If the GOT offset might be >= 4k, we determine the position
2564 of the GOT entry via a PC-relative LARL (@GOTENT). */
2566 rtx temp = gen_reg_rtx (Pmode);
2568 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTENT);
2569 new = gen_rtx_CONST (Pmode, new);
2570 emit_move_insn (temp, new);
2572 new = gen_const_mem (Pmode, temp);
2573 emit_move_insn (reg, new);
2574 new = reg;
2576 else
2578 /* If the GOT offset might be >= 4k, we have to load it
2579 from the literal pool (@GOT). */
2581 rtx temp = gen_reg_rtx (Pmode);
2583 if (reload_in_progress || reload_completed)
2584 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2586 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
2587 addr = gen_rtx_CONST (Pmode, addr);
2588 addr = force_const_mem (Pmode, addr);
2589 emit_move_insn (temp, addr);
2591 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2592 new = gen_const_mem (Pmode, new);
2593 emit_move_insn (reg, new);
2594 new = reg;
2597 else
2599 if (GET_CODE (addr) == CONST)
2601 addr = XEXP (addr, 0);
2602 if (GET_CODE (addr) == UNSPEC)
2604 gcc_assert (XVECLEN (addr, 0) == 1);
2605 switch (XINT (addr, 1))
2607 /* If someone moved a GOT-relative UNSPEC
2608 out of the literal pool, force them back in. */
2609 case UNSPEC_GOTOFF:
2610 case UNSPEC_PLTOFF:
2611 new = force_const_mem (Pmode, orig);
2612 break;
2614 /* @GOT is OK as is if small. */
2615 case UNSPEC_GOT:
2616 if (flag_pic == 2)
2617 new = force_const_mem (Pmode, orig);
2618 break;
2620 /* @GOTENT is OK as is. */
2621 case UNSPEC_GOTENT:
2622 break;
2624 /* @PLT is OK as is on 64-bit, must be converted to
2625 GOT-relative @PLTOFF on 31-bit. */
2626 case UNSPEC_PLT:
2627 if (!TARGET_CPU_ZARCH)
2629 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2631 if (reload_in_progress || reload_completed)
2632 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2634 addr = XVECEXP (addr, 0, 0);
2635 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
2636 UNSPEC_PLTOFF);
2637 addr = gen_rtx_CONST (Pmode, addr);
2638 addr = force_const_mem (Pmode, addr);
2639 emit_move_insn (temp, addr);
2641 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2642 if (reg != 0)
2644 s390_load_address (reg, new);
2645 new = reg;
2648 break;
2650 /* Everything else cannot happen. */
2651 default:
2652 gcc_unreachable ();
2655 else
2656 gcc_assert (GET_CODE (addr) == PLUS);
2658 if (GET_CODE (addr) == PLUS)
2660 rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
2661 /* Check first to see if this is a constant offset
2662 from a local symbol reference. */
2663 if ((GET_CODE (op0) == LABEL_REF
2664 || (GET_CODE (op0) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op0)))
2665 && GET_CODE (op1) == CONST_INT)
2667 if (TARGET_CPU_ZARCH && larl_operand (op0, VOIDmode))
2669 if (INTVAL (op1) & 1)
2671 /* LARL can't handle odd offsets, so emit a
2672 pair of LARL and LA. */
2673 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2675 if (!DISP_IN_RANGE (INTVAL (op1)))
2677 int even = INTVAL (op1) - 1;
2678 op0 = gen_rtx_PLUS (Pmode, op0, GEN_INT (even));
2679 op0 = gen_rtx_CONST (Pmode, op0);
2680 op1 = const1_rtx;
2683 emit_move_insn (temp, op0);
2684 new = gen_rtx_PLUS (Pmode, temp, op1);
2686 if (reg != 0)
2688 s390_load_address (reg, new);
2689 new = reg;
2692 else
2694 /* If the offset is even, we can just use LARL.
2695 This will happen automatically. */
2698 else
2700 /* Access local symbols relative to the GOT. */
2702 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2704 if (reload_in_progress || reload_completed)
2705 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2707 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
2708 UNSPEC_GOTOFF);
2709 addr = gen_rtx_PLUS (Pmode, addr, op1);
2710 addr = gen_rtx_CONST (Pmode, addr);
2711 addr = force_const_mem (Pmode, addr);
2712 emit_move_insn (temp, addr);
2714 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2715 if (reg != 0)
2717 s390_load_address (reg, new);
2718 new = reg;
2723 /* Now, check whether it is a GOT relative symbol plus offset
2724 that was pulled out of the literal pool. Force it back in. */
2726 else if (GET_CODE (op0) == UNSPEC
2727 && GET_CODE (op1) == CONST_INT
2728 && XINT (op0, 1) == UNSPEC_GOTOFF)
2730 gcc_assert (XVECLEN (op0, 0) == 1);
2732 new = force_const_mem (Pmode, orig);
2735 /* Otherwise, compute the sum. */
2736 else
2738 base = legitimize_pic_address (XEXP (addr, 0), reg);
2739 new = legitimize_pic_address (XEXP (addr, 1),
2740 base == reg ? NULL_RTX : reg);
2741 if (GET_CODE (new) == CONST_INT)
2742 new = plus_constant (base, INTVAL (new));
2743 else
2745 if (GET_CODE (new) == PLUS && CONSTANT_P (XEXP (new, 1)))
2747 base = gen_rtx_PLUS (Pmode, base, XEXP (new, 0));
2748 new = XEXP (new, 1);
2750 new = gen_rtx_PLUS (Pmode, base, new);
2753 if (GET_CODE (new) == CONST)
2754 new = XEXP (new, 0);
2755 new = force_operand (new, 0);
2759 return new;
2762 /* Load the thread pointer into a register. */
2764 static rtx
2765 get_thread_pointer (void)
2767 rtx tp = gen_reg_rtx (Pmode);
2769 emit_move_insn (tp, gen_rtx_REG (Pmode, TP_REGNUM));
2770 mark_reg_pointer (tp, BITS_PER_WORD);
2772 return tp;
2775 /* Emit a tls call insn. The call target is the SYMBOL_REF stored
2776 in s390_tls_symbol which always refers to __tls_get_offset.
2777 The returned offset is written to RESULT_REG and an USE rtx is
2778 generated for TLS_CALL. */
2780 static GTY(()) rtx s390_tls_symbol;
2782 static void
2783 s390_emit_tls_call_insn (rtx result_reg, rtx tls_call)
2785 rtx insn;
2787 gcc_assert (flag_pic);
2789 if (!s390_tls_symbol)
2790 s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset");
2792 insn = s390_emit_call (s390_tls_symbol, tls_call, result_reg,
2793 gen_rtx_REG (Pmode, RETURN_REGNUM));
2795 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), result_reg);
2796 CONST_OR_PURE_CALL_P (insn) = 1;
2799 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
2800 this (thread-local) address. REG may be used as temporary. */
2802 static rtx
2803 legitimize_tls_address (rtx addr, rtx reg)
2805 rtx new, tls_call, temp, base, r2, insn;
2807 if (GET_CODE (addr) == SYMBOL_REF)
2808 switch (tls_symbolic_operand (addr))
2810 case TLS_MODEL_GLOBAL_DYNAMIC:
2811 start_sequence ();
2812 r2 = gen_rtx_REG (Pmode, 2);
2813 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLSGD);
2814 new = gen_rtx_CONST (Pmode, tls_call);
2815 new = force_const_mem (Pmode, new);
2816 emit_move_insn (r2, new);
2817 s390_emit_tls_call_insn (r2, tls_call);
2818 insn = get_insns ();
2819 end_sequence ();
2821 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
2822 temp = gen_reg_rtx (Pmode);
2823 emit_libcall_block (insn, temp, r2, new);
2825 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2826 if (reg != 0)
2828 s390_load_address (reg, new);
2829 new = reg;
2831 break;
2833 case TLS_MODEL_LOCAL_DYNAMIC:
2834 start_sequence ();
2835 r2 = gen_rtx_REG (Pmode, 2);
2836 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM);
2837 new = gen_rtx_CONST (Pmode, tls_call);
2838 new = force_const_mem (Pmode, new);
2839 emit_move_insn (r2, new);
2840 s390_emit_tls_call_insn (r2, tls_call);
2841 insn = get_insns ();
2842 end_sequence ();
2844 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM_NTPOFF);
2845 temp = gen_reg_rtx (Pmode);
2846 emit_libcall_block (insn, temp, r2, new);
2848 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2849 base = gen_reg_rtx (Pmode);
2850 s390_load_address (base, new);
2852 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_DTPOFF);
2853 new = gen_rtx_CONST (Pmode, new);
2854 new = force_const_mem (Pmode, new);
2855 temp = gen_reg_rtx (Pmode);
2856 emit_move_insn (temp, new);
2858 new = gen_rtx_PLUS (Pmode, base, temp);
2859 if (reg != 0)
2861 s390_load_address (reg, new);
2862 new = reg;
2864 break;
2866 case TLS_MODEL_INITIAL_EXEC:
2867 if (flag_pic == 1)
2869 /* Assume GOT offset < 4k. This is handled the same way
2870 in both 31- and 64-bit code. */
2872 if (reload_in_progress || reload_completed)
2873 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2875 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
2876 new = gen_rtx_CONST (Pmode, new);
2877 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
2878 new = gen_const_mem (Pmode, new);
2879 temp = gen_reg_rtx (Pmode);
2880 emit_move_insn (temp, new);
2882 else if (TARGET_CPU_ZARCH)
2884 /* If the GOT offset might be >= 4k, we determine the position
2885 of the GOT entry via a PC-relative LARL. */
2887 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
2888 new = gen_rtx_CONST (Pmode, new);
2889 temp = gen_reg_rtx (Pmode);
2890 emit_move_insn (temp, new);
2892 new = gen_const_mem (Pmode, temp);
2893 temp = gen_reg_rtx (Pmode);
2894 emit_move_insn (temp, new);
2896 else if (flag_pic)
2898 /* If the GOT offset might be >= 4k, we have to load it
2899 from the literal pool. */
2901 if (reload_in_progress || reload_completed)
2902 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2904 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
2905 new = gen_rtx_CONST (Pmode, new);
2906 new = force_const_mem (Pmode, new);
2907 temp = gen_reg_rtx (Pmode);
2908 emit_move_insn (temp, new);
2910 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2911 new = gen_const_mem (Pmode, new);
2913 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new, addr), UNSPEC_TLS_LOAD);
2914 temp = gen_reg_rtx (Pmode);
2915 emit_insn (gen_rtx_SET (Pmode, temp, new));
2917 else
2919 /* In position-dependent code, load the absolute address of
2920 the GOT entry from the literal pool. */
2922 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
2923 new = gen_rtx_CONST (Pmode, new);
2924 new = force_const_mem (Pmode, new);
2925 temp = gen_reg_rtx (Pmode);
2926 emit_move_insn (temp, new);
2928 new = temp;
2929 new = gen_const_mem (Pmode, new);
2930 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new, addr), UNSPEC_TLS_LOAD);
2931 temp = gen_reg_rtx (Pmode);
2932 emit_insn (gen_rtx_SET (Pmode, temp, new));
2935 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2936 if (reg != 0)
2938 s390_load_address (reg, new);
2939 new = reg;
2941 break;
2943 case TLS_MODEL_LOCAL_EXEC:
2944 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
2945 new = gen_rtx_CONST (Pmode, new);
2946 new = force_const_mem (Pmode, new);
2947 temp = gen_reg_rtx (Pmode);
2948 emit_move_insn (temp, new);
2950 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2951 if (reg != 0)
2953 s390_load_address (reg, new);
2954 new = reg;
2956 break;
2958 default:
2959 gcc_unreachable ();
2962 else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == UNSPEC)
2964 switch (XINT (XEXP (addr, 0), 1))
2966 case UNSPEC_INDNTPOFF:
2967 gcc_assert (TARGET_CPU_ZARCH);
2968 new = addr;
2969 break;
2971 default:
2972 gcc_unreachable ();
2976 else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == PLUS
2977 && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
2979 new = XEXP (XEXP (addr, 0), 0);
2980 if (GET_CODE (new) != SYMBOL_REF)
2981 new = gen_rtx_CONST (Pmode, new);
2983 new = legitimize_tls_address (new, reg);
2984 new = plus_constant (new, INTVAL (XEXP (XEXP (addr, 0), 1)));
2985 new = force_operand (new, 0);
2988 else
2989 gcc_unreachable (); /* for now ... */
2991 return new;
2994 /* Emit insns to move operands[1] into operands[0]. */
2996 void
2997 emit_symbolic_move (rtx *operands)
2999 rtx temp = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
3001 if (GET_CODE (operands[0]) == MEM)
3002 operands[1] = force_reg (Pmode, operands[1]);
3003 else if (TLS_SYMBOLIC_CONST (operands[1]))
3004 operands[1] = legitimize_tls_address (operands[1], temp);
3005 else if (flag_pic)
3006 operands[1] = legitimize_pic_address (operands[1], temp);
3009 /* Try machine-dependent ways of modifying an illegitimate address X
3010 to be legitimate. If we find one, return the new, valid address.
3012 OLDX is the address as it was before break_out_memory_refs was called.
3013 In some cases it is useful to look at this to decide what needs to be done.
3015 MODE is the mode of the operand pointed to by X.
3017 When -fpic is used, special handling is needed for symbolic references.
3018 See comments by legitimize_pic_address for details. */
3021 legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
3022 enum machine_mode mode ATTRIBUTE_UNUSED)
3024 rtx constant_term = const0_rtx;
3026 if (TLS_SYMBOLIC_CONST (x))
3028 x = legitimize_tls_address (x, 0);
3030 if (legitimate_address_p (mode, x, FALSE))
3031 return x;
3033 else if (flag_pic)
3035 if (SYMBOLIC_CONST (x)
3036 || (GET_CODE (x) == PLUS
3037 && (SYMBOLIC_CONST (XEXP (x, 0))
3038 || SYMBOLIC_CONST (XEXP (x, 1)))))
3039 x = legitimize_pic_address (x, 0);
3041 if (legitimate_address_p (mode, x, FALSE))
3042 return x;
3045 x = eliminate_constant_term (x, &constant_term);
3047 /* Optimize loading of large displacements by splitting them
3048 into the multiple of 4K and the rest; this allows the
3049 former to be CSE'd if possible.
3051 Don't do this if the displacement is added to a register
3052 pointing into the stack frame, as the offsets will
3053 change later anyway. */
3055 if (GET_CODE (constant_term) == CONST_INT
3056 && !TARGET_LONG_DISPLACEMENT
3057 && !DISP_IN_RANGE (INTVAL (constant_term))
3058 && !(REG_P (x) && REGNO_PTR_FRAME_P (REGNO (x))))
3060 HOST_WIDE_INT lower = INTVAL (constant_term) & 0xfff;
3061 HOST_WIDE_INT upper = INTVAL (constant_term) ^ lower;
3063 rtx temp = gen_reg_rtx (Pmode);
3064 rtx val = force_operand (GEN_INT (upper), temp);
3065 if (val != temp)
3066 emit_move_insn (temp, val);
3068 x = gen_rtx_PLUS (Pmode, x, temp);
3069 constant_term = GEN_INT (lower);
3072 if (GET_CODE (x) == PLUS)
3074 if (GET_CODE (XEXP (x, 0)) == REG)
3076 rtx temp = gen_reg_rtx (Pmode);
3077 rtx val = force_operand (XEXP (x, 1), temp);
3078 if (val != temp)
3079 emit_move_insn (temp, val);
3081 x = gen_rtx_PLUS (Pmode, XEXP (x, 0), temp);
3084 else if (GET_CODE (XEXP (x, 1)) == REG)
3086 rtx temp = gen_reg_rtx (Pmode);
3087 rtx val = force_operand (XEXP (x, 0), temp);
3088 if (val != temp)
3089 emit_move_insn (temp, val);
3091 x = gen_rtx_PLUS (Pmode, temp, XEXP (x, 1));
3095 if (constant_term != const0_rtx)
3096 x = gen_rtx_PLUS (Pmode, x, constant_term);
3098 return x;
3101 /* Try a machine-dependent way of reloading an illegitimate address AD
3102 operand. If we find one, push the reload and and return the new address.
3104 MODE is the mode of the enclosing MEM. OPNUM is the operand number
3105 and TYPE is the reload type of the current reload. */
3107 rtx
3108 legitimize_reload_address (rtx ad, enum machine_mode mode ATTRIBUTE_UNUSED,
3109 int opnum, int type)
3111 if (!optimize || TARGET_LONG_DISPLACEMENT)
3112 return NULL_RTX;
3114 if (GET_CODE (ad) == PLUS)
3116 rtx tem = simplify_binary_operation (PLUS, Pmode,
3117 XEXP (ad, 0), XEXP (ad, 1));
3118 if (tem)
3119 ad = tem;
3122 if (GET_CODE (ad) == PLUS
3123 && GET_CODE (XEXP (ad, 0)) == REG
3124 && GET_CODE (XEXP (ad, 1)) == CONST_INT
3125 && !DISP_IN_RANGE (INTVAL (XEXP (ad, 1))))
3127 HOST_WIDE_INT lower = INTVAL (XEXP (ad, 1)) & 0xfff;
3128 HOST_WIDE_INT upper = INTVAL (XEXP (ad, 1)) ^ lower;
3129 rtx cst, tem, new;
3131 cst = GEN_INT (upper);
3132 if (!legitimate_reload_constant_p (cst))
3133 cst = force_const_mem (Pmode, cst);
3135 tem = gen_rtx_PLUS (Pmode, XEXP (ad, 0), cst);
3136 new = gen_rtx_PLUS (Pmode, tem, GEN_INT (lower));
3138 push_reload (XEXP (tem, 1), 0, &XEXP (tem, 1), 0,
3139 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3140 opnum, (enum reload_type) type);
3141 return new;
3144 return NULL_RTX;
3147 /* Emit code to move LEN bytes from DST to SRC. */
3149 void
3150 s390_expand_movmem (rtx dst, rtx src, rtx len)
3152 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
3154 if (INTVAL (len) > 0)
3155 emit_insn (gen_movmem_short (dst, src, GEN_INT (INTVAL (len) - 1)));
3158 else if (TARGET_MVCLE)
3160 emit_insn (gen_movmem_long (dst, src, convert_to_mode (Pmode, len, 1)));
3163 else
3165 rtx dst_addr, src_addr, count, blocks, temp;
3166 rtx loop_start_label = gen_label_rtx ();
3167 rtx loop_end_label = gen_label_rtx ();
3168 rtx end_label = gen_label_rtx ();
3169 enum machine_mode mode;
3171 mode = GET_MODE (len);
3172 if (mode == VOIDmode)
3173 mode = Pmode;
3175 dst_addr = gen_reg_rtx (Pmode);
3176 src_addr = gen_reg_rtx (Pmode);
3177 count = gen_reg_rtx (mode);
3178 blocks = gen_reg_rtx (mode);
3180 convert_move (count, len, 1);
3181 emit_cmp_and_jump_insns (count, const0_rtx,
3182 EQ, NULL_RTX, mode, 1, end_label);
3184 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
3185 emit_move_insn (src_addr, force_operand (XEXP (src, 0), NULL_RTX));
3186 dst = change_address (dst, VOIDmode, dst_addr);
3187 src = change_address (src, VOIDmode, src_addr);
3189 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3190 if (temp != count)
3191 emit_move_insn (count, temp);
3193 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
3194 if (temp != blocks)
3195 emit_move_insn (blocks, temp);
3197 emit_cmp_and_jump_insns (blocks, const0_rtx,
3198 EQ, NULL_RTX, mode, 1, loop_end_label);
3200 emit_label (loop_start_label);
3202 emit_insn (gen_movmem_short (dst, src, GEN_INT (255)));
3203 s390_load_address (dst_addr,
3204 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
3205 s390_load_address (src_addr,
3206 gen_rtx_PLUS (Pmode, src_addr, GEN_INT (256)));
3208 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3209 if (temp != blocks)
3210 emit_move_insn (blocks, temp);
3212 emit_cmp_and_jump_insns (blocks, const0_rtx,
3213 EQ, NULL_RTX, mode, 1, loop_end_label);
3215 emit_jump (loop_start_label);
3216 emit_label (loop_end_label);
3218 emit_insn (gen_movmem_short (dst, src,
3219 convert_to_mode (Pmode, count, 1)));
3220 emit_label (end_label);
3224 /* Emit code to clear LEN bytes at DST. */
3226 void
3227 s390_expand_clrmem (rtx dst, rtx len)
3229 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
3231 if (INTVAL (len) > 0)
3232 emit_insn (gen_clrmem_short (dst, GEN_INT (INTVAL (len) - 1)));
3235 else if (TARGET_MVCLE)
3237 emit_insn (gen_clrmem_long (dst, convert_to_mode (Pmode, len, 1)));
3240 else
3242 rtx dst_addr, src_addr, count, blocks, temp;
3243 rtx loop_start_label = gen_label_rtx ();
3244 rtx loop_end_label = gen_label_rtx ();
3245 rtx end_label = gen_label_rtx ();
3246 enum machine_mode mode;
3248 mode = GET_MODE (len);
3249 if (mode == VOIDmode)
3250 mode = Pmode;
3252 dst_addr = gen_reg_rtx (Pmode);
3253 src_addr = gen_reg_rtx (Pmode);
3254 count = gen_reg_rtx (mode);
3255 blocks = gen_reg_rtx (mode);
3257 convert_move (count, len, 1);
3258 emit_cmp_and_jump_insns (count, const0_rtx,
3259 EQ, NULL_RTX, mode, 1, end_label);
3261 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
3262 dst = change_address (dst, VOIDmode, dst_addr);
3264 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3265 if (temp != count)
3266 emit_move_insn (count, temp);
3268 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
3269 if (temp != blocks)
3270 emit_move_insn (blocks, temp);
3272 emit_cmp_and_jump_insns (blocks, const0_rtx,
3273 EQ, NULL_RTX, mode, 1, loop_end_label);
3275 emit_label (loop_start_label);
3277 emit_insn (gen_clrmem_short (dst, GEN_INT (255)));
3278 s390_load_address (dst_addr,
3279 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
3281 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3282 if (temp != blocks)
3283 emit_move_insn (blocks, temp);
3285 emit_cmp_and_jump_insns (blocks, const0_rtx,
3286 EQ, NULL_RTX, mode, 1, loop_end_label);
3288 emit_jump (loop_start_label);
3289 emit_label (loop_end_label);
3291 emit_insn (gen_clrmem_short (dst, convert_to_mode (Pmode, count, 1)));
3292 emit_label (end_label);
3296 /* Emit code to compare LEN bytes at OP0 with those at OP1,
3297 and return the result in TARGET. */
3299 void
3300 s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
3302 rtx ccreg = gen_rtx_REG (CCUmode, CC_REGNUM);
3303 rtx tmp;
3305 /* As the result of CMPINT is inverted compared to what we need,
3306 we have to swap the operands. */
3307 tmp = op0; op0 = op1; op1 = tmp;
3309 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
3311 if (INTVAL (len) > 0)
3313 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (INTVAL (len) - 1)));
3314 emit_insn (gen_cmpint (target, ccreg));
3316 else
3317 emit_move_insn (target, const0_rtx);
3319 else if (TARGET_MVCLE)
3321 emit_insn (gen_cmpmem_long (op0, op1, convert_to_mode (Pmode, len, 1)));
3322 emit_insn (gen_cmpint (target, ccreg));
3324 else
3326 rtx addr0, addr1, count, blocks, temp;
3327 rtx loop_start_label = gen_label_rtx ();
3328 rtx loop_end_label = gen_label_rtx ();
3329 rtx end_label = gen_label_rtx ();
3330 enum machine_mode mode;
3332 mode = GET_MODE (len);
3333 if (mode == VOIDmode)
3334 mode = Pmode;
3336 addr0 = gen_reg_rtx (Pmode);
3337 addr1 = gen_reg_rtx (Pmode);
3338 count = gen_reg_rtx (mode);
3339 blocks = gen_reg_rtx (mode);
3341 convert_move (count, len, 1);
3342 emit_cmp_and_jump_insns (count, const0_rtx,
3343 EQ, NULL_RTX, mode, 1, end_label);
3345 emit_move_insn (addr0, force_operand (XEXP (op0, 0), NULL_RTX));
3346 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
3347 op0 = change_address (op0, VOIDmode, addr0);
3348 op1 = change_address (op1, VOIDmode, addr1);
3350 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3351 if (temp != count)
3352 emit_move_insn (count, temp);
3354 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
3355 if (temp != blocks)
3356 emit_move_insn (blocks, temp);
3358 emit_cmp_and_jump_insns (blocks, const0_rtx,
3359 EQ, NULL_RTX, mode, 1, loop_end_label);
3361 emit_label (loop_start_label);
3363 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (255)));
3364 temp = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
3365 temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
3366 gen_rtx_LABEL_REF (VOIDmode, end_label), pc_rtx);
3367 temp = gen_rtx_SET (VOIDmode, pc_rtx, temp);
3368 emit_jump_insn (temp);
3370 s390_load_address (addr0,
3371 gen_rtx_PLUS (Pmode, addr0, GEN_INT (256)));
3372 s390_load_address (addr1,
3373 gen_rtx_PLUS (Pmode, addr1, GEN_INT (256)));
3375 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3376 if (temp != blocks)
3377 emit_move_insn (blocks, temp);
3379 emit_cmp_and_jump_insns (blocks, const0_rtx,
3380 EQ, NULL_RTX, mode, 1, loop_end_label);
3382 emit_jump (loop_start_label);
3383 emit_label (loop_end_label);
3385 emit_insn (gen_cmpmem_short (op0, op1,
3386 convert_to_mode (Pmode, count, 1)));
3387 emit_label (end_label);
3389 emit_insn (gen_cmpint (target, ccreg));
3394 /* Expand conditional increment or decrement using alc/slb instructions.
3395 Should generate code setting DST to either SRC or SRC + INCREMENT,
3396 depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
3397 Returns true if successful, false otherwise.
3399 That makes it possible to implement some if-constructs without jumps e.g.:
3400 (borrow = CC0 | CC1 and carry = CC2 | CC3)
3401 unsigned int a, b, c;
3402 if (a < b) c++; -> CCU b > a -> CC2; c += carry;
3403 if (a < b) c--; -> CCL3 a - b -> borrow; c -= borrow;
3404 if (a <= b) c++; -> CCL3 b - a -> borrow; c += carry;
3405 if (a <= b) c--; -> CCU a <= b -> borrow; c -= borrow;
3407 Checks for EQ and NE with a nonzero value need an additional xor e.g.:
3408 if (a == b) c++; -> CCL3 a ^= b; 0 - a -> borrow; c += carry;
3409 if (a == b) c--; -> CCU a ^= b; a <= 0 -> CC0 | CC1; c -= borrow;
3410 if (a != b) c++; -> CCU a ^= b; a > 0 -> CC2; c += carry;
3411 if (a != b) c--; -> CCL3 a ^= b; 0 - a -> borrow; c -= borrow; */
3413 bool
3414 s390_expand_addcc (enum rtx_code cmp_code, rtx cmp_op0, rtx cmp_op1,
3415 rtx dst, rtx src, rtx increment)
3417 enum machine_mode cmp_mode;
3418 enum machine_mode cc_mode;
3419 rtx op_res;
3420 rtx insn;
3421 rtvec p;
3422 int ret;
3424 if ((GET_MODE (cmp_op0) == SImode || GET_MODE (cmp_op0) == VOIDmode)
3425 && (GET_MODE (cmp_op1) == SImode || GET_MODE (cmp_op1) == VOIDmode))
3426 cmp_mode = SImode;
3427 else if ((GET_MODE (cmp_op0) == DImode || GET_MODE (cmp_op0) == VOIDmode)
3428 && (GET_MODE (cmp_op1) == DImode || GET_MODE (cmp_op1) == VOIDmode))
3429 cmp_mode = DImode;
3430 else
3431 return false;
3433 /* Try ADD LOGICAL WITH CARRY. */
3434 if (increment == const1_rtx)
3436 /* Determine CC mode to use. */
3437 if (cmp_code == EQ || cmp_code == NE)
3439 if (cmp_op1 != const0_rtx)
3441 cmp_op0 = expand_simple_binop (cmp_mode, XOR, cmp_op0, cmp_op1,
3442 NULL_RTX, 0, OPTAB_WIDEN);
3443 cmp_op1 = const0_rtx;
3446 cmp_code = cmp_code == EQ ? LEU : GTU;
3449 if (cmp_code == LTU || cmp_code == LEU)
3451 rtx tem = cmp_op0;
3452 cmp_op0 = cmp_op1;
3453 cmp_op1 = tem;
3454 cmp_code = swap_condition (cmp_code);
3457 switch (cmp_code)
3459 case GTU:
3460 cc_mode = CCUmode;
3461 break;
3463 case GEU:
3464 cc_mode = CCL3mode;
3465 break;
3467 default:
3468 return false;
3471 /* Emit comparison instruction pattern. */
3472 if (!register_operand (cmp_op0, cmp_mode))
3473 cmp_op0 = force_reg (cmp_mode, cmp_op0);
3475 insn = gen_rtx_SET (VOIDmode, gen_rtx_REG (cc_mode, CC_REGNUM),
3476 gen_rtx_COMPARE (cc_mode, cmp_op0, cmp_op1));
3477 /* We use insn_invalid_p here to add clobbers if required. */
3478 ret = insn_invalid_p (emit_insn (insn));
3479 gcc_assert (!ret);
3481 /* Emit ALC instruction pattern. */
3482 op_res = gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
3483 gen_rtx_REG (cc_mode, CC_REGNUM),
3484 const0_rtx);
3486 if (src != const0_rtx)
3488 if (!register_operand (src, GET_MODE (dst)))
3489 src = force_reg (GET_MODE (dst), src);
3491 src = gen_rtx_PLUS (GET_MODE (dst), src, const0_rtx);
3492 op_res = gen_rtx_PLUS (GET_MODE (dst), src, op_res);
3495 p = rtvec_alloc (2);
3496 RTVEC_ELT (p, 0) =
3497 gen_rtx_SET (VOIDmode, dst, op_res);
3498 RTVEC_ELT (p, 1) =
3499 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
3500 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
3502 return true;
3505 /* Try SUBTRACT LOGICAL WITH BORROW. */
3506 if (increment == constm1_rtx)
3508 /* Determine CC mode to use. */
3509 if (cmp_code == EQ || cmp_code == NE)
3511 if (cmp_op1 != const0_rtx)
3513 cmp_op0 = expand_simple_binop (cmp_mode, XOR, cmp_op0, cmp_op1,
3514 NULL_RTX, 0, OPTAB_WIDEN);
3515 cmp_op1 = const0_rtx;
3518 cmp_code = cmp_code == EQ ? LEU : GTU;
3521 if (cmp_code == GTU || cmp_code == GEU)
3523 rtx tem = cmp_op0;
3524 cmp_op0 = cmp_op1;
3525 cmp_op1 = tem;
3526 cmp_code = swap_condition (cmp_code);
3529 switch (cmp_code)
3531 case LEU:
3532 cc_mode = CCUmode;
3533 break;
3535 case LTU:
3536 cc_mode = CCL3mode;
3537 break;
3539 default:
3540 return false;
3543 /* Emit comparison instruction pattern. */
3544 if (!register_operand (cmp_op0, cmp_mode))
3545 cmp_op0 = force_reg (cmp_mode, cmp_op0);
3547 insn = gen_rtx_SET (VOIDmode, gen_rtx_REG (cc_mode, CC_REGNUM),
3548 gen_rtx_COMPARE (cc_mode, cmp_op0, cmp_op1));
3549 /* We use insn_invalid_p here to add clobbers if required. */
3550 ret = insn_invalid_p (emit_insn (insn));
3551 gcc_assert (!ret);
3553 /* Emit SLB instruction pattern. */
3554 if (!register_operand (src, GET_MODE (dst)))
3555 src = force_reg (GET_MODE (dst), src);
3557 op_res = gen_rtx_MINUS (GET_MODE (dst),
3558 gen_rtx_MINUS (GET_MODE (dst), src, const0_rtx),
3559 gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
3560 gen_rtx_REG (cc_mode, CC_REGNUM),
3561 const0_rtx));
3562 p = rtvec_alloc (2);
3563 RTVEC_ELT (p, 0) =
3564 gen_rtx_SET (VOIDmode, dst, op_res);
3565 RTVEC_ELT (p, 1) =
3566 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
3567 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
3569 return true;
3572 return false;
3576 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
3577 We need to emit DTP-relative relocations. */
3579 static void s390_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
3581 static void
3582 s390_output_dwarf_dtprel (FILE *file, int size, rtx x)
3584 switch (size)
3586 case 4:
3587 fputs ("\t.long\t", file);
3588 break;
3589 case 8:
3590 fputs ("\t.quad\t", file);
3591 break;
3592 default:
3593 gcc_unreachable ();
3595 output_addr_const (file, x);
3596 fputs ("@DTPOFF", file);
3599 /* In the name of slightly smaller debug output, and to cater to
3600 general assembler lossage, recognize various UNSPEC sequences
3601 and turn them back into a direct symbol reference. */
3603 static rtx
3604 s390_delegitimize_address (rtx orig_x)
3606 rtx x = orig_x, y;
3608 if (GET_CODE (x) != MEM)
3609 return orig_x;
3611 x = XEXP (x, 0);
3612 if (GET_CODE (x) == PLUS
3613 && GET_CODE (XEXP (x, 1)) == CONST
3614 && GET_CODE (XEXP (x, 0)) == REG
3615 && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM)
3617 y = XEXP (XEXP (x, 1), 0);
3618 if (GET_CODE (y) == UNSPEC
3619 && XINT (y, 1) == UNSPEC_GOT)
3620 return XVECEXP (y, 0, 0);
3621 return orig_x;
3624 if (GET_CODE (x) == CONST)
3626 y = XEXP (x, 0);
3627 if (GET_CODE (y) == UNSPEC
3628 && XINT (y, 1) == UNSPEC_GOTENT)
3629 return XVECEXP (y, 0, 0);
3630 return orig_x;
3633 return orig_x;
3636 /* Output shift count operand OP to stdio stream FILE. */
3638 static void
3639 print_shift_count_operand (FILE *file, rtx op)
3641 HOST_WIDE_INT offset = 0;
3643 /* We can have an integer constant, an address register,
3644 or a sum of the two. */
3645 if (GET_CODE (op) == CONST_INT)
3647 offset = INTVAL (op);
3648 op = NULL_RTX;
3650 if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
3652 offset = INTVAL (XEXP (op, 1));
3653 op = XEXP (op, 0);
3655 while (op && GET_CODE (op) == SUBREG)
3656 op = SUBREG_REG (op);
3658 /* Sanity check. */
3659 if (op)
3661 gcc_assert (GET_CODE (op) == REG);
3662 gcc_assert (REGNO (op) < FIRST_PSEUDO_REGISTER);
3663 gcc_assert (REGNO_REG_CLASS (REGNO (op)) == ADDR_REGS);
3666 /* Shift counts are truncated to the low six bits anyway. */
3667 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset & 63);
3668 if (op)
3669 fprintf (file, "(%s)", reg_names[REGNO (op)]);
3672 /* See 'get_some_local_dynamic_name'. */
3674 static int
3675 get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
3677 rtx x = *px;
3679 if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
3681 x = get_pool_constant (x);
3682 return for_each_rtx (&x, get_some_local_dynamic_name_1, 0);
3685 if (GET_CODE (x) == SYMBOL_REF
3686 && tls_symbolic_operand (x) == TLS_MODEL_LOCAL_DYNAMIC)
3688 cfun->machine->some_ld_name = XSTR (x, 0);
3689 return 1;
3692 return 0;
3695 /* Locate some local-dynamic symbol still in use by this function
3696 so that we can print its name in local-dynamic base patterns. */
3698 static const char *
3699 get_some_local_dynamic_name (void)
3701 rtx insn;
3703 if (cfun->machine->some_ld_name)
3704 return cfun->machine->some_ld_name;
3706 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
3707 if (INSN_P (insn)
3708 && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
3709 return cfun->machine->some_ld_name;
3711 gcc_unreachable ();
3714 /* Output machine-dependent UNSPECs occurring in address constant X
3715 in assembler syntax to stdio stream FILE. Returns true if the
3716 constant X could be recognized, false otherwise. */
3718 bool
3719 s390_output_addr_const_extra (FILE *file, rtx x)
3721 if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 1)
3722 switch (XINT (x, 1))
3724 case UNSPEC_GOTENT:
3725 output_addr_const (file, XVECEXP (x, 0, 0));
3726 fprintf (file, "@GOTENT");
3727 return true;
3728 case UNSPEC_GOT:
3729 output_addr_const (file, XVECEXP (x, 0, 0));
3730 fprintf (file, "@GOT");
3731 return true;
3732 case UNSPEC_GOTOFF:
3733 output_addr_const (file, XVECEXP (x, 0, 0));
3734 fprintf (file, "@GOTOFF");
3735 return true;
3736 case UNSPEC_PLT:
3737 output_addr_const (file, XVECEXP (x, 0, 0));
3738 fprintf (file, "@PLT");
3739 return true;
3740 case UNSPEC_PLTOFF:
3741 output_addr_const (file, XVECEXP (x, 0, 0));
3742 fprintf (file, "@PLTOFF");
3743 return true;
3744 case UNSPEC_TLSGD:
3745 output_addr_const (file, XVECEXP (x, 0, 0));
3746 fprintf (file, "@TLSGD");
3747 return true;
3748 case UNSPEC_TLSLDM:
3749 assemble_name (file, get_some_local_dynamic_name ());
3750 fprintf (file, "@TLSLDM");
3751 return true;
3752 case UNSPEC_DTPOFF:
3753 output_addr_const (file, XVECEXP (x, 0, 0));
3754 fprintf (file, "@DTPOFF");
3755 return true;
3756 case UNSPEC_NTPOFF:
3757 output_addr_const (file, XVECEXP (x, 0, 0));
3758 fprintf (file, "@NTPOFF");
3759 return true;
3760 case UNSPEC_GOTNTPOFF:
3761 output_addr_const (file, XVECEXP (x, 0, 0));
3762 fprintf (file, "@GOTNTPOFF");
3763 return true;
3764 case UNSPEC_INDNTPOFF:
3765 output_addr_const (file, XVECEXP (x, 0, 0));
3766 fprintf (file, "@INDNTPOFF");
3767 return true;
3770 return false;
3773 /* Output address operand ADDR in assembler syntax to
3774 stdio stream FILE. */
3776 void
3777 print_operand_address (FILE *file, rtx addr)
3779 struct s390_address ad;
3781 if (!s390_decompose_address (addr, &ad)
3782 || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
3783 || (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
3784 output_operand_lossage ("Cannot decompose address.");
3786 if (ad.disp)
3787 output_addr_const (file, ad.disp);
3788 else
3789 fprintf (file, "0");
3791 if (ad.base && ad.indx)
3792 fprintf (file, "(%s,%s)", reg_names[REGNO (ad.indx)],
3793 reg_names[REGNO (ad.base)]);
3794 else if (ad.base)
3795 fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
3798 /* Output operand X in assembler syntax to stdio stream FILE.
3799 CODE specified the format flag. The following format flags
3800 are recognized:
3802 'C': print opcode suffix for branch condition.
3803 'D': print opcode suffix for inverse branch condition.
3804 'J': print tls_load/tls_gdcall/tls_ldcall suffix
3805 'O': print only the displacement of a memory reference.
3806 'R': print only the base register of a memory reference.
3807 'S': print S-type memory reference (base+displacement).
3808 'N': print the second word of a DImode operand.
3809 'M': print the second word of a TImode operand.
3810 'Y': print shift count operand.
3812 'b': print integer X as if it's an unsigned byte.
3813 'x': print integer X as if it's an unsigned word.
3814 'h': print integer X as if it's a signed word.
3815 'i': print the first nonzero HImode part of X.
3816 'j': print the first HImode part unequal to 0xffff of X. */
3818 void
3819 print_operand (FILE *file, rtx x, int code)
3821 switch (code)
3823 case 'C':
3824 fprintf (file, s390_branch_condition_mnemonic (x, FALSE));
3825 return;
3827 case 'D':
3828 fprintf (file, s390_branch_condition_mnemonic (x, TRUE));
3829 return;
3831 case 'J':
3832 if (GET_CODE (x) == SYMBOL_REF)
3834 fprintf (file, "%s", ":tls_load:");
3835 output_addr_const (file, x);
3837 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD)
3839 fprintf (file, "%s", ":tls_gdcall:");
3840 output_addr_const (file, XVECEXP (x, 0, 0));
3842 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM)
3844 fprintf (file, "%s", ":tls_ldcall:");
3845 assemble_name (file, get_some_local_dynamic_name ());
3847 else
3848 gcc_unreachable ();
3849 return;
3851 case 'O':
3853 struct s390_address ad;
3854 int ret;
3856 gcc_assert (GET_CODE (x) == MEM);
3857 ret = s390_decompose_address (XEXP (x, 0), &ad);
3858 gcc_assert (ret);
3859 gcc_assert (!ad.base || REG_OK_FOR_BASE_STRICT_P (ad.base));
3860 gcc_assert (!ad.indx);
3862 if (ad.disp)
3863 output_addr_const (file, ad.disp);
3864 else
3865 fprintf (file, "0");
3867 return;
3869 case 'R':
3871 struct s390_address ad;
3872 int ret;
3874 gcc_assert (GET_CODE (x) == MEM);
3875 ret = s390_decompose_address (XEXP (x, 0), &ad);
3876 gcc_assert (ret);
3877 gcc_assert (!ad.base || REG_OK_FOR_BASE_STRICT_P (ad.base));
3878 gcc_assert (!ad.indx);
3880 if (ad.base)
3881 fprintf (file, "%s", reg_names[REGNO (ad.base)]);
3882 else
3883 fprintf (file, "0");
3885 return;
3887 case 'S':
3889 struct s390_address ad;
3890 int ret;
3892 gcc_assert (GET_CODE (x) == MEM);
3893 ret = s390_decompose_address (XEXP (x, 0), &ad);
3894 gcc_assert (ret);
3895 gcc_assert (!ad.base || REG_OK_FOR_BASE_STRICT_P (ad.base));
3896 gcc_assert (!ad.indx);
3898 if (ad.disp)
3899 output_addr_const (file, ad.disp);
3900 else
3901 fprintf (file, "0");
3903 if (ad.base)
3904 fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
3906 return;
3908 case 'N':
3909 if (GET_CODE (x) == REG)
3910 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
3911 else if (GET_CODE (x) == MEM)
3912 x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 4));
3913 else
3914 gcc_unreachable ();
3915 break;
3917 case 'M':
3918 if (GET_CODE (x) == REG)
3919 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
3920 else if (GET_CODE (x) == MEM)
3921 x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 8));
3922 else
3923 gcc_unreachable ();
3924 break;
3926 case 'Y':
3927 print_shift_count_operand (file, x);
3928 return;
3931 switch (GET_CODE (x))
3933 case REG:
3934 fprintf (file, "%s", reg_names[REGNO (x)]);
3935 break;
3937 case MEM:
3938 output_address (XEXP (x, 0));
3939 break;
3941 case CONST:
3942 case CODE_LABEL:
3943 case LABEL_REF:
3944 case SYMBOL_REF:
3945 output_addr_const (file, x);
3946 break;
3948 case CONST_INT:
3949 if (code == 'b')
3950 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xff);
3951 else if (code == 'x')
3952 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffff);
3953 else if (code == 'h')
3954 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000);
3955 else if (code == 'i')
3956 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3957 s390_extract_part (x, HImode, 0));
3958 else if (code == 'j')
3959 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3960 s390_extract_part (x, HImode, -1));
3961 else
3962 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
3963 break;
3965 case CONST_DOUBLE:
3966 gcc_assert (GET_MODE (x) == VOIDmode);
3967 if (code == 'b')
3968 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xff);
3969 else if (code == 'x')
3970 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xffff);
3971 else if (code == 'h')
3972 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((CONST_DOUBLE_LOW (x) & 0xffff) ^ 0x8000) - 0x8000);
3973 else
3974 gcc_unreachable ();
3975 break;
3977 default:
3978 fatal_insn ("UNKNOWN in print_operand !?", x);
3979 break;
3983 /* Target hook for assembling integer objects. We need to define it
3984 here to work a round a bug in some versions of GAS, which couldn't
3985 handle values smaller than INT_MIN when printed in decimal. */
3987 static bool
3988 s390_assemble_integer (rtx x, unsigned int size, int aligned_p)
3990 if (size == 8 && aligned_p
3991 && GET_CODE (x) == CONST_INT && INTVAL (x) < INT_MIN)
3993 fprintf (asm_out_file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n",
3994 INTVAL (x));
3995 return true;
3997 return default_assemble_integer (x, size, aligned_p);
4000 /* Returns true if register REGNO is used for forming
4001 a memory address in expression X. */
4003 static bool
4004 reg_used_in_mem_p (int regno, rtx x)
4006 enum rtx_code code = GET_CODE (x);
4007 int i, j;
4008 const char *fmt;
4010 if (code == MEM)
4012 if (refers_to_regno_p (regno, regno+1,
4013 XEXP (x, 0), 0))
4014 return true;
4016 else if (code == SET
4017 && GET_CODE (SET_DEST (x)) == PC)
4019 if (refers_to_regno_p (regno, regno+1,
4020 SET_SRC (x), 0))
4021 return true;
4024 fmt = GET_RTX_FORMAT (code);
4025 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4027 if (fmt[i] == 'e'
4028 && reg_used_in_mem_p (regno, XEXP (x, i)))
4029 return true;
4031 else if (fmt[i] == 'E')
4032 for (j = 0; j < XVECLEN (x, i); j++)
4033 if (reg_used_in_mem_p (regno, XVECEXP (x, i, j)))
4034 return true;
4036 return false;
4039 /* Returns true if expression DEP_RTX sets an address register
4040 used by instruction INSN to address memory. */
4042 static bool
4043 addr_generation_dependency_p (rtx dep_rtx, rtx insn)
4045 rtx target, pat;
4047 if (GET_CODE (dep_rtx) == INSN)
4048 dep_rtx = PATTERN (dep_rtx);
4050 if (GET_CODE (dep_rtx) == SET)
4052 target = SET_DEST (dep_rtx);
4053 if (GET_CODE (target) == STRICT_LOW_PART)
4054 target = XEXP (target, 0);
4055 while (GET_CODE (target) == SUBREG)
4056 target = SUBREG_REG (target);
4058 if (GET_CODE (target) == REG)
4060 int regno = REGNO (target);
4062 if (s390_safe_attr_type (insn) == TYPE_LA)
4064 pat = PATTERN (insn);
4065 if (GET_CODE (pat) == PARALLEL)
4067 gcc_assert (XVECLEN (pat, 0) == 2);
4068 pat = XVECEXP (pat, 0, 0);
4070 gcc_assert (GET_CODE (pat) == SET);
4071 return refers_to_regno_p (regno, regno+1, SET_SRC (pat), 0);
4073 else if (get_attr_atype (insn) == ATYPE_AGEN)
4074 return reg_used_in_mem_p (regno, PATTERN (insn));
4077 return false;
4080 /* Return 1, if dep_insn sets register used in insn in the agen unit. */
4083 s390_agen_dep_p (rtx dep_insn, rtx insn)
4085 rtx dep_rtx = PATTERN (dep_insn);
4086 int i;
4088 if (GET_CODE (dep_rtx) == SET
4089 && addr_generation_dependency_p (dep_rtx, insn))
4090 return 1;
4091 else if (GET_CODE (dep_rtx) == PARALLEL)
4093 for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
4095 if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i), insn))
4096 return 1;
4099 return 0;
4102 /* A C statement (sans semicolon) to update the integer scheduling priority
4103 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
4104 reduce the priority to execute INSN later. Do not define this macro if
4105 you do not need to adjust the scheduling priorities of insns.
4107 A STD instruction should be scheduled earlier,
4108 in order to use the bypass. */
4110 static int
4111 s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
4113 if (! INSN_P (insn))
4114 return priority;
4116 if (s390_tune != PROCESSOR_2084_Z990)
4117 return priority;
4119 switch (s390_safe_attr_type (insn))
4121 case TYPE_FSTOREDF:
4122 case TYPE_FSTORESF:
4123 priority = priority << 3;
4124 break;
4125 case TYPE_STORE:
4126 case TYPE_STM:
4127 priority = priority << 1;
4128 break;
4129 default:
4130 break;
4132 return priority;
4135 /* The number of instructions that can be issued per cycle. */
4137 static int
4138 s390_issue_rate (void)
4140 if (s390_tune == PROCESSOR_2084_Z990)
4141 return 3;
4142 return 1;
4145 static int
4146 s390_first_cycle_multipass_dfa_lookahead (void)
4148 return 4;
4152 /* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
4153 Fix up MEMs as required. */
4155 static void
4156 annotate_constant_pool_refs (rtx *x)
4158 int i, j;
4159 const char *fmt;
4161 gcc_assert (GET_CODE (*x) != SYMBOL_REF
4162 || !CONSTANT_POOL_ADDRESS_P (*x));
4164 /* Literal pool references can only occur inside a MEM ... */
4165 if (GET_CODE (*x) == MEM)
4167 rtx memref = XEXP (*x, 0);
4169 if (GET_CODE (memref) == SYMBOL_REF
4170 && CONSTANT_POOL_ADDRESS_P (memref))
4172 rtx base = cfun->machine->base_reg;
4173 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, memref, base),
4174 UNSPEC_LTREF);
4176 *x = replace_equiv_address (*x, addr);
4177 return;
4180 if (GET_CODE (memref) == CONST
4181 && GET_CODE (XEXP (memref, 0)) == PLUS
4182 && GET_CODE (XEXP (XEXP (memref, 0), 1)) == CONST_INT
4183 && GET_CODE (XEXP (XEXP (memref, 0), 0)) == SYMBOL_REF
4184 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (memref, 0), 0)))
4186 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (memref, 0), 1));
4187 rtx sym = XEXP (XEXP (memref, 0), 0);
4188 rtx base = cfun->machine->base_reg;
4189 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, sym, base),
4190 UNSPEC_LTREF);
4192 *x = replace_equiv_address (*x, plus_constant (addr, off));
4193 return;
4197 /* ... or a load-address type pattern. */
4198 if (GET_CODE (*x) == SET)
4200 rtx addrref = SET_SRC (*x);
4202 if (GET_CODE (addrref) == SYMBOL_REF
4203 && CONSTANT_POOL_ADDRESS_P (addrref))
4205 rtx base = cfun->machine->base_reg;
4206 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, addrref, base),
4207 UNSPEC_LTREF);
4209 SET_SRC (*x) = addr;
4210 return;
4213 if (GET_CODE (addrref) == CONST
4214 && GET_CODE (XEXP (addrref, 0)) == PLUS
4215 && GET_CODE (XEXP (XEXP (addrref, 0), 1)) == CONST_INT
4216 && GET_CODE (XEXP (XEXP (addrref, 0), 0)) == SYMBOL_REF
4217 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (addrref, 0), 0)))
4219 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (addrref, 0), 1));
4220 rtx sym = XEXP (XEXP (addrref, 0), 0);
4221 rtx base = cfun->machine->base_reg;
4222 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, sym, base),
4223 UNSPEC_LTREF);
4225 SET_SRC (*x) = plus_constant (addr, off);
4226 return;
4230 /* Annotate LTREL_BASE as well. */
4231 if (GET_CODE (*x) == UNSPEC
4232 && XINT (*x, 1) == UNSPEC_LTREL_BASE)
4234 rtx base = cfun->machine->base_reg;
4235 *x = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, XVECEXP (*x, 0, 0), base),
4236 UNSPEC_LTREL_BASE);
4237 return;
4240 fmt = GET_RTX_FORMAT (GET_CODE (*x));
4241 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
4243 if (fmt[i] == 'e')
4245 annotate_constant_pool_refs (&XEXP (*x, i));
4247 else if (fmt[i] == 'E')
4249 for (j = 0; j < XVECLEN (*x, i); j++)
4250 annotate_constant_pool_refs (&XVECEXP (*x, i, j));
4255 /* Split all branches that exceed the maximum distance.
4256 Returns true if this created a new literal pool entry. */
4258 static int
4259 s390_split_branches (void)
4261 rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
4262 int new_literal = 0, ret;
4263 rtx insn, pat, tmp, target;
4264 rtx *label;
4266 /* We need correct insn addresses. */
4268 shorten_branches (get_insns ());
4270 /* Find all branches that exceed 64KB, and split them. */
4272 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4274 if (GET_CODE (insn) != JUMP_INSN)
4275 continue;
4277 pat = PATTERN (insn);
4278 if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
4279 pat = XVECEXP (pat, 0, 0);
4280 if (GET_CODE (pat) != SET || SET_DEST (pat) != pc_rtx)
4281 continue;
4283 if (GET_CODE (SET_SRC (pat)) == LABEL_REF)
4285 label = &SET_SRC (pat);
4287 else if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE)
4289 if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF)
4290 label = &XEXP (SET_SRC (pat), 1);
4291 else if (GET_CODE (XEXP (SET_SRC (pat), 2)) == LABEL_REF)
4292 label = &XEXP (SET_SRC (pat), 2);
4293 else
4294 continue;
4296 else
4297 continue;
4299 if (get_attr_length (insn) <= 4)
4300 continue;
4302 /* We are going to use the return register as scratch register,
4303 make sure it will be saved/restored by the prologue/epilogue. */
4304 cfun_frame_layout.save_return_addr_p = 1;
4306 if (!flag_pic)
4308 new_literal = 1;
4309 tmp = force_const_mem (Pmode, *label);
4310 tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, tmp), insn);
4311 INSN_ADDRESSES_NEW (tmp, -1);
4312 annotate_constant_pool_refs (&PATTERN (tmp));
4314 target = temp_reg;
4316 else
4318 new_literal = 1;
4319 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, *label),
4320 UNSPEC_LTREL_OFFSET);
4321 target = gen_rtx_CONST (Pmode, target);
4322 target = force_const_mem (Pmode, target);
4323 tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, target), insn);
4324 INSN_ADDRESSES_NEW (tmp, -1);
4325 annotate_constant_pool_refs (&PATTERN (tmp));
4327 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, XEXP (target, 0),
4328 cfun->machine->base_reg),
4329 UNSPEC_LTREL_BASE);
4330 target = gen_rtx_PLUS (Pmode, temp_reg, target);
4333 ret = validate_change (insn, label, target, 0);
4334 gcc_assert (ret);
4337 return new_literal;
4341 /* Find an annotated literal pool symbol referenced in RTX X,
4342 and store it at REF. Will abort if X contains references to
4343 more than one such pool symbol; multiple references to the same
4344 symbol are allowed, however.
4346 The rtx pointed to by REF must be initialized to NULL_RTX
4347 by the caller before calling this routine. */
4349 static void
4350 find_constant_pool_ref (rtx x, rtx *ref)
4352 int i, j;
4353 const char *fmt;
4355 /* Ignore LTREL_BASE references. */
4356 if (GET_CODE (x) == UNSPEC
4357 && XINT (x, 1) == UNSPEC_LTREL_BASE)
4358 return;
4359 /* Likewise POOL_ENTRY insns. */
4360 if (GET_CODE (x) == UNSPEC_VOLATILE
4361 && XINT (x, 1) == UNSPECV_POOL_ENTRY)
4362 return;
4364 gcc_assert (GET_CODE (x) != SYMBOL_REF
4365 || !CONSTANT_POOL_ADDRESS_P (x));
4367 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_LTREF)
4369 rtx sym = XVECEXP (x, 0, 0);
4370 gcc_assert (GET_CODE (sym) == SYMBOL_REF
4371 && CONSTANT_POOL_ADDRESS_P (sym));
4373 if (*ref == NULL_RTX)
4374 *ref = sym;
4375 else
4376 gcc_assert (*ref == sym);
4378 return;
4381 fmt = GET_RTX_FORMAT (GET_CODE (x));
4382 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4384 if (fmt[i] == 'e')
4386 find_constant_pool_ref (XEXP (x, i), ref);
4388 else if (fmt[i] == 'E')
4390 for (j = 0; j < XVECLEN (x, i); j++)
4391 find_constant_pool_ref (XVECEXP (x, i, j), ref);
4396 /* Replace every reference to the annotated literal pool
4397 symbol REF in X by its base plus OFFSET. */
4399 static void
4400 replace_constant_pool_ref (rtx *x, rtx ref, rtx offset)
4402 int i, j;
4403 const char *fmt;
4405 gcc_assert (*x != ref);
4407 if (GET_CODE (*x) == UNSPEC
4408 && XINT (*x, 1) == UNSPEC_LTREF
4409 && XVECEXP (*x, 0, 0) == ref)
4411 *x = gen_rtx_PLUS (Pmode, XVECEXP (*x, 0, 1), offset);
4412 return;
4415 if (GET_CODE (*x) == PLUS
4416 && GET_CODE (XEXP (*x, 1)) == CONST_INT
4417 && GET_CODE (XEXP (*x, 0)) == UNSPEC
4418 && XINT (XEXP (*x, 0), 1) == UNSPEC_LTREF
4419 && XVECEXP (XEXP (*x, 0), 0, 0) == ref)
4421 rtx addr = gen_rtx_PLUS (Pmode, XVECEXP (XEXP (*x, 0), 0, 1), offset);
4422 *x = plus_constant (addr, INTVAL (XEXP (*x, 1)));
4423 return;
4426 fmt = GET_RTX_FORMAT (GET_CODE (*x));
4427 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
4429 if (fmt[i] == 'e')
4431 replace_constant_pool_ref (&XEXP (*x, i), ref, offset);
4433 else if (fmt[i] == 'E')
4435 for (j = 0; j < XVECLEN (*x, i); j++)
4436 replace_constant_pool_ref (&XVECEXP (*x, i, j), ref, offset);
4441 /* Check whether X contains an UNSPEC_LTREL_BASE.
4442 Return its constant pool symbol if found, NULL_RTX otherwise. */
4444 static rtx
4445 find_ltrel_base (rtx x)
4447 int i, j;
4448 const char *fmt;
4450 if (GET_CODE (x) == UNSPEC
4451 && XINT (x, 1) == UNSPEC_LTREL_BASE)
4452 return XVECEXP (x, 0, 0);
4454 fmt = GET_RTX_FORMAT (GET_CODE (x));
4455 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4457 if (fmt[i] == 'e')
4459 rtx fnd = find_ltrel_base (XEXP (x, i));
4460 if (fnd)
4461 return fnd;
4463 else if (fmt[i] == 'E')
4465 for (j = 0; j < XVECLEN (x, i); j++)
4467 rtx fnd = find_ltrel_base (XVECEXP (x, i, j));
4468 if (fnd)
4469 return fnd;
4474 return NULL_RTX;
4477 /* Replace any occurrence of UNSPEC_LTREL_BASE in X with its base. */
4479 static void
4480 replace_ltrel_base (rtx *x)
4482 int i, j;
4483 const char *fmt;
4485 if (GET_CODE (*x) == UNSPEC
4486 && XINT (*x, 1) == UNSPEC_LTREL_BASE)
4488 *x = XVECEXP (*x, 0, 1);
4489 return;
4492 fmt = GET_RTX_FORMAT (GET_CODE (*x));
4493 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
4495 if (fmt[i] == 'e')
4497 replace_ltrel_base (&XEXP (*x, i));
4499 else if (fmt[i] == 'E')
4501 for (j = 0; j < XVECLEN (*x, i); j++)
4502 replace_ltrel_base (&XVECEXP (*x, i, j));
4508 /* We keep a list of constants which we have to add to internal
4509 constant tables in the middle of large functions. */
4511 #define NR_C_MODES 7
4512 enum machine_mode constant_modes[NR_C_MODES] =
4514 TImode,
4515 DFmode, DImode,
4516 SFmode, SImode,
4517 HImode,
4518 QImode
4521 struct constant
4523 struct constant *next;
4524 rtx value;
4525 rtx label;
4528 struct constant_pool
4530 struct constant_pool *next;
4531 rtx first_insn;
4532 rtx pool_insn;
4533 bitmap insns;
4535 struct constant *constants[NR_C_MODES];
4536 struct constant *execute;
4537 rtx label;
4538 int size;
4541 /* Allocate new constant_pool structure. */
4543 static struct constant_pool *
4544 s390_alloc_pool (void)
4546 struct constant_pool *pool;
4547 int i;
4549 pool = (struct constant_pool *) xmalloc (sizeof *pool);
4550 pool->next = NULL;
4551 for (i = 0; i < NR_C_MODES; i++)
4552 pool->constants[i] = NULL;
4554 pool->execute = NULL;
4555 pool->label = gen_label_rtx ();
4556 pool->first_insn = NULL_RTX;
4557 pool->pool_insn = NULL_RTX;
4558 pool->insns = BITMAP_ALLOC (NULL);
4559 pool->size = 0;
4561 return pool;
4564 /* Create new constant pool covering instructions starting at INSN
4565 and chain it to the end of POOL_LIST. */
4567 static struct constant_pool *
4568 s390_start_pool (struct constant_pool **pool_list, rtx insn)
4570 struct constant_pool *pool, **prev;
4572 pool = s390_alloc_pool ();
4573 pool->first_insn = insn;
4575 for (prev = pool_list; *prev; prev = &(*prev)->next)
4577 *prev = pool;
4579 return pool;
4582 /* End range of instructions covered by POOL at INSN and emit
4583 placeholder insn representing the pool. */
4585 static void
4586 s390_end_pool (struct constant_pool *pool, rtx insn)
4588 rtx pool_size = GEN_INT (pool->size + 8 /* alignment slop */);
4590 if (!insn)
4591 insn = get_last_insn ();
4593 pool->pool_insn = emit_insn_after (gen_pool (pool_size), insn);
4594 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
4597 /* Add INSN to the list of insns covered by POOL. */
4599 static void
4600 s390_add_pool_insn (struct constant_pool *pool, rtx insn)
4602 bitmap_set_bit (pool->insns, INSN_UID (insn));
4605 /* Return pool out of POOL_LIST that covers INSN. */
4607 static struct constant_pool *
4608 s390_find_pool (struct constant_pool *pool_list, rtx insn)
4610 struct constant_pool *pool;
4612 for (pool = pool_list; pool; pool = pool->next)
4613 if (bitmap_bit_p (pool->insns, INSN_UID (insn)))
4614 break;
4616 return pool;
4619 /* Add constant VAL of mode MODE to the constant pool POOL. */
4621 static void
4622 s390_add_constant (struct constant_pool *pool, rtx val, enum machine_mode mode)
4624 struct constant *c;
4625 int i;
4627 for (i = 0; i < NR_C_MODES; i++)
4628 if (constant_modes[i] == mode)
4629 break;
4630 gcc_assert (i != NR_C_MODES);
4632 for (c = pool->constants[i]; c != NULL; c = c->next)
4633 if (rtx_equal_p (val, c->value))
4634 break;
4636 if (c == NULL)
4638 c = (struct constant *) xmalloc (sizeof *c);
4639 c->value = val;
4640 c->label = gen_label_rtx ();
4641 c->next = pool->constants[i];
4642 pool->constants[i] = c;
4643 pool->size += GET_MODE_SIZE (mode);
4647 /* Find constant VAL of mode MODE in the constant pool POOL.
4648 Return an RTX describing the distance from the start of
4649 the pool to the location of the new constant. */
4651 static rtx
4652 s390_find_constant (struct constant_pool *pool, rtx val,
4653 enum machine_mode mode)
4655 struct constant *c;
4656 rtx offset;
4657 int i;
4659 for (i = 0; i < NR_C_MODES; i++)
4660 if (constant_modes[i] == mode)
4661 break;
4662 gcc_assert (i != NR_C_MODES);
4664 for (c = pool->constants[i]; c != NULL; c = c->next)
4665 if (rtx_equal_p (val, c->value))
4666 break;
4668 gcc_assert (c);
4670 offset = gen_rtx_MINUS (Pmode, gen_rtx_LABEL_REF (Pmode, c->label),
4671 gen_rtx_LABEL_REF (Pmode, pool->label));
4672 offset = gen_rtx_CONST (Pmode, offset);
4673 return offset;
4676 /* Check whether INSN is an execute. Return the label_ref to its
4677 execute target template if so, NULL_RTX otherwise. */
4679 static rtx
4680 s390_execute_label (rtx insn)
4682 if (GET_CODE (insn) == INSN
4683 && GET_CODE (PATTERN (insn)) == PARALLEL
4684 && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == UNSPEC
4685 && XINT (XVECEXP (PATTERN (insn), 0, 0), 1) == UNSPEC_EXECUTE)
4686 return XVECEXP (XVECEXP (PATTERN (insn), 0, 0), 0, 2);
4688 return NULL_RTX;
4691 /* Add execute target for INSN to the constant pool POOL. */
4693 static void
4694 s390_add_execute (struct constant_pool *pool, rtx insn)
4696 struct constant *c;
4698 for (c = pool->execute; c != NULL; c = c->next)
4699 if (INSN_UID (insn) == INSN_UID (c->value))
4700 break;
4702 if (c == NULL)
4704 c = (struct constant *) xmalloc (sizeof *c);
4705 c->value = insn;
4706 c->label = gen_label_rtx ();
4707 c->next = pool->execute;
4708 pool->execute = c;
4709 pool->size += 6;
4713 /* Find execute target for INSN in the constant pool POOL.
4714 Return an RTX describing the distance from the start of
4715 the pool to the location of the execute target. */
4717 static rtx
4718 s390_find_execute (struct constant_pool *pool, rtx insn)
4720 struct constant *c;
4721 rtx offset;
4723 for (c = pool->execute; c != NULL; c = c->next)
4724 if (INSN_UID (insn) == INSN_UID (c->value))
4725 break;
4727 gcc_assert (c);
4729 offset = gen_rtx_MINUS (Pmode, gen_rtx_LABEL_REF (Pmode, c->label),
4730 gen_rtx_LABEL_REF (Pmode, pool->label));
4731 offset = gen_rtx_CONST (Pmode, offset);
4732 return offset;
4735 /* For an execute INSN, extract the execute target template. */
4737 static rtx
4738 s390_execute_target (rtx insn)
4740 rtx pattern = PATTERN (insn);
4741 gcc_assert (s390_execute_label (insn));
4743 if (XVECLEN (pattern, 0) == 2)
4745 pattern = copy_rtx (XVECEXP (pattern, 0, 1));
4747 else
4749 rtvec vec = rtvec_alloc (XVECLEN (pattern, 0) - 1);
4750 int i;
4752 for (i = 0; i < XVECLEN (pattern, 0) - 1; i++)
4753 RTVEC_ELT (vec, i) = copy_rtx (XVECEXP (pattern, 0, i + 1));
4755 pattern = gen_rtx_PARALLEL (VOIDmode, vec);
4758 return pattern;
4761 /* Indicate that INSN cannot be duplicated. This is the case for
4762 execute insns that carry a unique label. */
4764 static bool
4765 s390_cannot_copy_insn_p (rtx insn)
4767 rtx label = s390_execute_label (insn);
4768 return label && label != const0_rtx;
4771 /* Dump out the constants in POOL. If REMOTE_LABEL is true,
4772 do not emit the pool base label. */
4774 static void
4775 s390_dump_pool (struct constant_pool *pool, bool remote_label)
4777 struct constant *c;
4778 rtx insn = pool->pool_insn;
4779 int i;
4781 /* Switch to rodata section. */
4782 if (TARGET_CPU_ZARCH)
4784 insn = emit_insn_after (gen_pool_section_start (), insn);
4785 INSN_ADDRESSES_NEW (insn, -1);
4788 /* Ensure minimum pool alignment. */
4789 if (TARGET_CPU_ZARCH)
4790 insn = emit_insn_after (gen_pool_align (GEN_INT (8)), insn);
4791 else
4792 insn = emit_insn_after (gen_pool_align (GEN_INT (4)), insn);
4793 INSN_ADDRESSES_NEW (insn, -1);
4795 /* Emit pool base label. */
4796 if (!remote_label)
4798 insn = emit_label_after (pool->label, insn);
4799 INSN_ADDRESSES_NEW (insn, -1);
4802 /* Dump constants in descending alignment requirement order,
4803 ensuring proper alignment for every constant. */
4804 for (i = 0; i < NR_C_MODES; i++)
4805 for (c = pool->constants[i]; c; c = c->next)
4807 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
4808 rtx value = c->value;
4809 if (GET_CODE (value) == CONST
4810 && GET_CODE (XEXP (value, 0)) == UNSPEC
4811 && XINT (XEXP (value, 0), 1) == UNSPEC_LTREL_OFFSET
4812 && XVECLEN (XEXP (value, 0), 0) == 1)
4814 value = gen_rtx_MINUS (Pmode, XVECEXP (XEXP (value, 0), 0, 0),
4815 gen_rtx_LABEL_REF (VOIDmode, pool->label));
4816 value = gen_rtx_CONST (VOIDmode, value);
4819 insn = emit_label_after (c->label, insn);
4820 INSN_ADDRESSES_NEW (insn, -1);
4822 value = gen_rtx_UNSPEC_VOLATILE (constant_modes[i],
4823 gen_rtvec (1, value),
4824 UNSPECV_POOL_ENTRY);
4825 insn = emit_insn_after (value, insn);
4826 INSN_ADDRESSES_NEW (insn, -1);
4829 /* Ensure minimum alignment for instructions. */
4830 insn = emit_insn_after (gen_pool_align (GEN_INT (2)), insn);
4831 INSN_ADDRESSES_NEW (insn, -1);
4833 /* Output in-pool execute template insns. */
4834 for (c = pool->execute; c; c = c->next)
4836 insn = emit_label_after (c->label, insn);
4837 INSN_ADDRESSES_NEW (insn, -1);
4839 insn = emit_insn_after (s390_execute_target (c->value), insn);
4840 INSN_ADDRESSES_NEW (insn, -1);
4843 /* Switch back to previous section. */
4844 if (TARGET_CPU_ZARCH)
4846 insn = emit_insn_after (gen_pool_section_end (), insn);
4847 INSN_ADDRESSES_NEW (insn, -1);
4850 insn = emit_barrier_after (insn);
4851 INSN_ADDRESSES_NEW (insn, -1);
4853 /* Remove placeholder insn. */
4854 remove_insn (pool->pool_insn);
4857 /* Free all memory used by POOL. */
4859 static void
4860 s390_free_pool (struct constant_pool *pool)
4862 struct constant *c, *next;
4863 int i;
4865 for (i = 0; i < NR_C_MODES; i++)
4866 for (c = pool->constants[i]; c; c = next)
4868 next = c->next;
4869 free (c);
4872 for (c = pool->execute; c; c = next)
4874 next = c->next;
4875 free (c);
4878 BITMAP_FREE (pool->insns);
4879 free (pool);
4883 /* Collect main literal pool. Return NULL on overflow. */
4885 static struct constant_pool *
4886 s390_mainpool_start (void)
4888 struct constant_pool *pool;
4889 rtx insn;
4891 pool = s390_alloc_pool ();
4893 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4895 if (GET_CODE (insn) == INSN
4896 && GET_CODE (PATTERN (insn)) == SET
4897 && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC_VOLATILE
4898 && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPECV_MAIN_POOL)
4900 gcc_assert (!pool->pool_insn);
4901 pool->pool_insn = insn;
4904 if (!TARGET_CPU_ZARCH && s390_execute_label (insn))
4906 s390_add_execute (pool, insn);
4908 else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
4910 rtx pool_ref = NULL_RTX;
4911 find_constant_pool_ref (PATTERN (insn), &pool_ref);
4912 if (pool_ref)
4914 rtx constant = get_pool_constant (pool_ref);
4915 enum machine_mode mode = get_pool_mode (pool_ref);
4916 s390_add_constant (pool, constant, mode);
4921 gcc_assert (pool->pool_insn || pool->size == 0);
4923 if (pool->size >= 4096)
4925 /* We're going to chunkify the pool, so remove the main
4926 pool placeholder insn. */
4927 remove_insn (pool->pool_insn);
4929 s390_free_pool (pool);
4930 pool = NULL;
4933 return pool;
4936 /* POOL holds the main literal pool as collected by s390_mainpool_start.
4937 Modify the current function to output the pool constants as well as
4938 the pool register setup instruction. */
4940 static void
4941 s390_mainpool_finish (struct constant_pool *pool)
4943 rtx base_reg = cfun->machine->base_reg;
4944 rtx insn;
4946 /* If the pool is empty, we're done. */
4947 if (pool->size == 0)
4949 /* We don't actually need a base register after all. */
4950 cfun->machine->base_reg = NULL_RTX;
4952 if (pool->pool_insn)
4953 remove_insn (pool->pool_insn);
4954 s390_free_pool (pool);
4955 return;
4958 /* We need correct insn addresses. */
4959 shorten_branches (get_insns ());
4961 /* On zSeries, we use a LARL to load the pool register. The pool is
4962 located in the .rodata section, so we emit it after the function. */
4963 if (TARGET_CPU_ZARCH)
4965 insn = gen_main_base_64 (base_reg, pool->label);
4966 insn = emit_insn_after (insn, pool->pool_insn);
4967 INSN_ADDRESSES_NEW (insn, -1);
4968 remove_insn (pool->pool_insn);
4970 insn = get_last_insn ();
4971 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
4972 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
4974 s390_dump_pool (pool, 0);
4977 /* On S/390, if the total size of the function's code plus literal pool
4978 does not exceed 4096 bytes, we use BASR to set up a function base
4979 pointer, and emit the literal pool at the end of the function. */
4980 else if (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
4981 + pool->size + 8 /* alignment slop */ < 4096)
4983 insn = gen_main_base_31_small (base_reg, pool->label);
4984 insn = emit_insn_after (insn, pool->pool_insn);
4985 INSN_ADDRESSES_NEW (insn, -1);
4986 remove_insn (pool->pool_insn);
4988 insn = emit_label_after (pool->label, insn);
4989 INSN_ADDRESSES_NEW (insn, -1);
4991 insn = get_last_insn ();
4992 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
4993 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
4995 s390_dump_pool (pool, 1);
4998 /* Otherwise, we emit an inline literal pool and use BASR to branch
4999 over it, setting up the pool register at the same time. */
5000 else
5002 rtx pool_end = gen_label_rtx ();
5004 insn = gen_main_base_31_large (base_reg, pool->label, pool_end);
5005 insn = emit_insn_after (insn, pool->pool_insn);
5006 INSN_ADDRESSES_NEW (insn, -1);
5007 remove_insn (pool->pool_insn);
5009 insn = emit_label_after (pool->label, insn);
5010 INSN_ADDRESSES_NEW (insn, -1);
5012 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
5013 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
5015 insn = emit_label_after (pool_end, pool->pool_insn);
5016 INSN_ADDRESSES_NEW (insn, -1);
5018 s390_dump_pool (pool, 1);
5022 /* Replace all literal pool references. */
5024 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5026 if (INSN_P (insn))
5027 replace_ltrel_base (&PATTERN (insn));
5029 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
5031 rtx addr, pool_ref = NULL_RTX;
5032 find_constant_pool_ref (PATTERN (insn), &pool_ref);
5033 if (pool_ref)
5035 if (s390_execute_label (insn))
5036 addr = s390_find_execute (pool, insn);
5037 else
5038 addr = s390_find_constant (pool, get_pool_constant (pool_ref),
5039 get_pool_mode (pool_ref));
5041 replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
5042 INSN_CODE (insn) = -1;
5048 /* Free the pool. */
5049 s390_free_pool (pool);
5052 /* POOL holds the main literal pool as collected by s390_mainpool_start.
5053 We have decided we cannot use this pool, so revert all changes
5054 to the current function that were done by s390_mainpool_start. */
5055 static void
5056 s390_mainpool_cancel (struct constant_pool *pool)
5058 /* We didn't actually change the instruction stream, so simply
5059 free the pool memory. */
5060 s390_free_pool (pool);
5064 /* Chunkify the literal pool. */
5066 #define S390_POOL_CHUNK_MIN 0xc00
5067 #define S390_POOL_CHUNK_MAX 0xe00
5069 static struct constant_pool *
5070 s390_chunkify_start (void)
5072 struct constant_pool *curr_pool = NULL, *pool_list = NULL;
5073 int extra_size = 0;
5074 bitmap far_labels;
5075 rtx pending_ltrel = NULL_RTX;
5076 rtx insn;
5078 rtx (*gen_reload_base) (rtx, rtx) =
5079 TARGET_CPU_ZARCH? gen_reload_base_64 : gen_reload_base_31;
5082 /* We need correct insn addresses. */
5084 shorten_branches (get_insns ());
5086 /* Scan all insns and move literals to pool chunks. */
5088 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5090 /* Check for pending LTREL_BASE. */
5091 if (INSN_P (insn))
5093 rtx ltrel_base = find_ltrel_base (PATTERN (insn));
5094 if (ltrel_base)
5096 gcc_assert (ltrel_base == pending_ltrel);
5097 pending_ltrel = NULL_RTX;
5101 if (!TARGET_CPU_ZARCH && s390_execute_label (insn))
5103 if (!curr_pool)
5104 curr_pool = s390_start_pool (&pool_list, insn);
5106 s390_add_execute (curr_pool, insn);
5107 s390_add_pool_insn (curr_pool, insn);
5109 else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
5111 rtx pool_ref = NULL_RTX;
5112 find_constant_pool_ref (PATTERN (insn), &pool_ref);
5113 if (pool_ref)
5115 rtx constant = get_pool_constant (pool_ref);
5116 enum machine_mode mode = get_pool_mode (pool_ref);
5118 if (!curr_pool)
5119 curr_pool = s390_start_pool (&pool_list, insn);
5121 s390_add_constant (curr_pool, constant, mode);
5122 s390_add_pool_insn (curr_pool, insn);
5124 /* Don't split the pool chunk between a LTREL_OFFSET load
5125 and the corresponding LTREL_BASE. */
5126 if (GET_CODE (constant) == CONST
5127 && GET_CODE (XEXP (constant, 0)) == UNSPEC
5128 && XINT (XEXP (constant, 0), 1) == UNSPEC_LTREL_OFFSET)
5130 gcc_assert (!pending_ltrel);
5131 pending_ltrel = pool_ref;
5136 if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CODE_LABEL)
5138 if (curr_pool)
5139 s390_add_pool_insn (curr_pool, insn);
5140 /* An LTREL_BASE must follow within the same basic block. */
5141 gcc_assert (!pending_ltrel);
5144 if (!curr_pool
5145 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn)
5146 || INSN_ADDRESSES (INSN_UID (insn)) == -1)
5147 continue;
5149 if (TARGET_CPU_ZARCH)
5151 if (curr_pool->size < S390_POOL_CHUNK_MAX)
5152 continue;
5154 s390_end_pool (curr_pool, NULL_RTX);
5155 curr_pool = NULL;
5157 else
5159 int chunk_size = INSN_ADDRESSES (INSN_UID (insn))
5160 - INSN_ADDRESSES (INSN_UID (curr_pool->first_insn))
5161 + extra_size;
5163 /* We will later have to insert base register reload insns.
5164 Those will have an effect on code size, which we need to
5165 consider here. This calculation makes rather pessimistic
5166 worst-case assumptions. */
5167 if (GET_CODE (insn) == CODE_LABEL)
5168 extra_size += 6;
5170 if (chunk_size < S390_POOL_CHUNK_MIN
5171 && curr_pool->size < S390_POOL_CHUNK_MIN)
5172 continue;
5174 /* Pool chunks can only be inserted after BARRIERs ... */
5175 if (GET_CODE (insn) == BARRIER)
5177 s390_end_pool (curr_pool, insn);
5178 curr_pool = NULL;
5179 extra_size = 0;
5182 /* ... so if we don't find one in time, create one. */
5183 else if ((chunk_size > S390_POOL_CHUNK_MAX
5184 || curr_pool->size > S390_POOL_CHUNK_MAX))
5186 rtx label, jump, barrier;
5188 /* We can insert the barrier only after a 'real' insn. */
5189 if (GET_CODE (insn) != INSN && GET_CODE (insn) != CALL_INSN)
5190 continue;
5191 if (get_attr_length (insn) == 0)
5192 continue;
5194 /* Don't separate LTREL_BASE from the corresponding
5195 LTREL_OFFSET load. */
5196 if (pending_ltrel)
5197 continue;
5199 label = gen_label_rtx ();
5200 jump = emit_jump_insn_after (gen_jump (label), insn);
5201 barrier = emit_barrier_after (jump);
5202 insn = emit_label_after (label, barrier);
5203 JUMP_LABEL (jump) = label;
5204 LABEL_NUSES (label) = 1;
5206 INSN_ADDRESSES_NEW (jump, -1);
5207 INSN_ADDRESSES_NEW (barrier, -1);
5208 INSN_ADDRESSES_NEW (insn, -1);
5210 s390_end_pool (curr_pool, barrier);
5211 curr_pool = NULL;
5212 extra_size = 0;
5217 if (curr_pool)
5218 s390_end_pool (curr_pool, NULL_RTX);
5219 gcc_assert (!pending_ltrel);
5221 /* Find all labels that are branched into
5222 from an insn belonging to a different chunk. */
5224 far_labels = BITMAP_ALLOC (NULL);
5226 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5228 /* Labels marked with LABEL_PRESERVE_P can be target
5229 of non-local jumps, so we have to mark them.
5230 The same holds for named labels.
5232 Don't do that, however, if it is the label before
5233 a jump table. */
5235 if (GET_CODE (insn) == CODE_LABEL
5236 && (LABEL_PRESERVE_P (insn) || LABEL_NAME (insn)))
5238 rtx vec_insn = next_real_insn (insn);
5239 rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
5240 PATTERN (vec_insn) : NULL_RTX;
5241 if (!vec_pat
5242 || !(GET_CODE (vec_pat) == ADDR_VEC
5243 || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
5244 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (insn));
5247 /* If we have a direct jump (conditional or unconditional)
5248 or a casesi jump, check all potential targets. */
5249 else if (GET_CODE (insn) == JUMP_INSN)
5251 rtx pat = PATTERN (insn);
5252 if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
5253 pat = XVECEXP (pat, 0, 0);
5255 if (GET_CODE (pat) == SET)
5257 rtx label = JUMP_LABEL (insn);
5258 if (label)
5260 if (s390_find_pool (pool_list, label)
5261 != s390_find_pool (pool_list, insn))
5262 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
5265 else if (GET_CODE (pat) == PARALLEL
5266 && XVECLEN (pat, 0) == 2
5267 && GET_CODE (XVECEXP (pat, 0, 0)) == SET
5268 && GET_CODE (XVECEXP (pat, 0, 1)) == USE
5269 && GET_CODE (XEXP (XVECEXP (pat, 0, 1), 0)) == LABEL_REF)
5271 /* Find the jump table used by this casesi jump. */
5272 rtx vec_label = XEXP (XEXP (XVECEXP (pat, 0, 1), 0), 0);
5273 rtx vec_insn = next_real_insn (vec_label);
5274 rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
5275 PATTERN (vec_insn) : NULL_RTX;
5276 if (vec_pat
5277 && (GET_CODE (vec_pat) == ADDR_VEC
5278 || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
5280 int i, diff_p = GET_CODE (vec_pat) == ADDR_DIFF_VEC;
5282 for (i = 0; i < XVECLEN (vec_pat, diff_p); i++)
5284 rtx label = XEXP (XVECEXP (vec_pat, diff_p, i), 0);
5286 if (s390_find_pool (pool_list, label)
5287 != s390_find_pool (pool_list, insn))
5288 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
5295 /* Insert base register reload insns before every pool. */
5297 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
5299 rtx new_insn = gen_reload_base (cfun->machine->base_reg,
5300 curr_pool->label);
5301 rtx insn = curr_pool->first_insn;
5302 INSN_ADDRESSES_NEW (emit_insn_before (new_insn, insn), -1);
5305 /* Insert base register reload insns at every far label. */
5307 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5308 if (GET_CODE (insn) == CODE_LABEL
5309 && bitmap_bit_p (far_labels, CODE_LABEL_NUMBER (insn)))
5311 struct constant_pool *pool = s390_find_pool (pool_list, insn);
5312 if (pool)
5314 rtx new_insn = gen_reload_base (cfun->machine->base_reg,
5315 pool->label);
5316 INSN_ADDRESSES_NEW (emit_insn_after (new_insn, insn), -1);
5321 BITMAP_FREE (far_labels);
5324 /* Recompute insn addresses. */
5326 init_insn_lengths ();
5327 shorten_branches (get_insns ());
5329 return pool_list;
5332 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
5333 After we have decided to use this list, finish implementing
5334 all changes to the current function as required. */
5336 static void
5337 s390_chunkify_finish (struct constant_pool *pool_list)
5339 struct constant_pool *curr_pool = NULL;
5340 rtx insn;
5343 /* Replace all literal pool references. */
5345 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5347 if (INSN_P (insn))
5348 replace_ltrel_base (&PATTERN (insn));
5350 curr_pool = s390_find_pool (pool_list, insn);
5351 if (!curr_pool)
5352 continue;
5354 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
5356 rtx addr, pool_ref = NULL_RTX;
5357 find_constant_pool_ref (PATTERN (insn), &pool_ref);
5358 if (pool_ref)
5360 if (s390_execute_label (insn))
5361 addr = s390_find_execute (curr_pool, insn);
5362 else
5363 addr = s390_find_constant (curr_pool,
5364 get_pool_constant (pool_ref),
5365 get_pool_mode (pool_ref));
5367 replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
5368 INSN_CODE (insn) = -1;
5373 /* Dump out all literal pools. */
5375 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
5376 s390_dump_pool (curr_pool, 0);
5378 /* Free pool list. */
5380 while (pool_list)
5382 struct constant_pool *next = pool_list->next;
5383 s390_free_pool (pool_list);
5384 pool_list = next;
5388 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
5389 We have decided we cannot use this list, so revert all changes
5390 to the current function that were done by s390_chunkify_start. */
5392 static void
5393 s390_chunkify_cancel (struct constant_pool *pool_list)
5395 struct constant_pool *curr_pool = NULL;
5396 rtx insn;
5398 /* Remove all pool placeholder insns. */
5400 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
5402 /* Did we insert an extra barrier? Remove it. */
5403 rtx barrier = PREV_INSN (curr_pool->pool_insn);
5404 rtx jump = barrier? PREV_INSN (barrier) : NULL_RTX;
5405 rtx label = NEXT_INSN (curr_pool->pool_insn);
5407 if (jump && GET_CODE (jump) == JUMP_INSN
5408 && barrier && GET_CODE (barrier) == BARRIER
5409 && label && GET_CODE (label) == CODE_LABEL
5410 && GET_CODE (PATTERN (jump)) == SET
5411 && SET_DEST (PATTERN (jump)) == pc_rtx
5412 && GET_CODE (SET_SRC (PATTERN (jump))) == LABEL_REF
5413 && XEXP (SET_SRC (PATTERN (jump)), 0) == label)
5415 remove_insn (jump);
5416 remove_insn (barrier);
5417 remove_insn (label);
5420 remove_insn (curr_pool->pool_insn);
5423 /* Remove all base register reload insns. */
5425 for (insn = get_insns (); insn; )
5427 rtx next_insn = NEXT_INSN (insn);
5429 if (GET_CODE (insn) == INSN
5430 && GET_CODE (PATTERN (insn)) == SET
5431 && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC
5432 && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPEC_RELOAD_BASE)
5433 remove_insn (insn);
5435 insn = next_insn;
5438 /* Free pool list. */
5440 while (pool_list)
5442 struct constant_pool *next = pool_list->next;
5443 s390_free_pool (pool_list);
5444 pool_list = next;
5449 /* Output the constant pool entry EXP in mode MODE with alignment ALIGN. */
5451 void
5452 s390_output_pool_entry (rtx exp, enum machine_mode mode, unsigned int align)
5454 REAL_VALUE_TYPE r;
5456 switch (GET_MODE_CLASS (mode))
5458 case MODE_FLOAT:
5459 gcc_assert (GET_CODE (exp) == CONST_DOUBLE);
5461 REAL_VALUE_FROM_CONST_DOUBLE (r, exp);
5462 assemble_real (r, mode, align);
5463 break;
5465 case MODE_INT:
5466 assemble_integer (exp, GET_MODE_SIZE (mode), align, 1);
5467 break;
5469 default:
5470 gcc_unreachable ();
5475 /* Return an RTL expression representing the value of the return address
5476 for the frame COUNT steps up from the current frame. FRAME is the
5477 frame pointer of that frame. */
5480 s390_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
5482 int offset;
5483 rtx addr;
5485 /* Without backchain, we fail for all but the current frame. */
5487 if (!TARGET_BACKCHAIN && count > 0)
5488 return NULL_RTX;
5490 /* For the current frame, we need to make sure the initial
5491 value of RETURN_REGNUM is actually saved. */
5493 if (count == 0)
5495 /* On non-z architectures branch splitting could overwrite r14. */
5496 if (TARGET_CPU_ZARCH)
5497 return get_hard_reg_initial_val (Pmode, RETURN_REGNUM);
5498 else
5500 cfun_frame_layout.save_return_addr_p = true;
5501 return gen_rtx_MEM (Pmode, return_address_pointer_rtx);
5505 if (TARGET_PACKED_STACK)
5506 offset = -2 * UNITS_PER_WORD;
5507 else
5508 offset = RETURN_REGNUM * UNITS_PER_WORD;
5510 addr = plus_constant (frame, offset);
5511 addr = memory_address (Pmode, addr);
5512 return gen_rtx_MEM (Pmode, addr);
5515 /* Return an RTL expression representing the back chain stored in
5516 the current stack frame. */
5519 s390_back_chain_rtx (void)
5521 rtx chain;
5523 gcc_assert (TARGET_BACKCHAIN);
5525 if (TARGET_PACKED_STACK)
5526 chain = plus_constant (stack_pointer_rtx,
5527 STACK_POINTER_OFFSET - UNITS_PER_WORD);
5528 else
5529 chain = stack_pointer_rtx;
5531 chain = gen_rtx_MEM (Pmode, chain);
5532 return chain;
5535 /* Find first call clobbered register unused in a function.
5536 This could be used as base register in a leaf function
5537 or for holding the return address before epilogue. */
5539 static int
5540 find_unused_clobbered_reg (void)
5542 int i;
5543 for (i = 0; i < 6; i++)
5544 if (!regs_ever_live[i])
5545 return i;
5546 return 0;
5550 /* Helper function for s390_regs_ever_clobbered. Sets the fields in DATA for all
5551 clobbered hard regs in SETREG. */
5553 static void
5554 s390_reg_clobbered_rtx (rtx setreg, rtx set_insn ATTRIBUTE_UNUSED, void *data)
5556 int *regs_ever_clobbered = (int *)data;
5557 unsigned int i, regno;
5558 enum machine_mode mode = GET_MODE (setreg);
5560 if (GET_CODE (setreg) == SUBREG)
5562 rtx inner = SUBREG_REG (setreg);
5563 if (!GENERAL_REG_P (inner))
5564 return;
5565 regno = subreg_regno (setreg);
5567 else if (GENERAL_REG_P (setreg))
5568 regno = REGNO (setreg);
5569 else
5570 return;
5572 for (i = regno;
5573 i < regno + HARD_REGNO_NREGS (regno, mode);
5574 i++)
5575 regs_ever_clobbered[i] = 1;
5578 /* Walks through all basic blocks of the current function looking
5579 for clobbered hard regs using s390_reg_clobbered_rtx. The fields
5580 of the passed integer array REGS_EVER_CLOBBERED are set to one for
5581 each of those regs. */
5583 static void
5584 s390_regs_ever_clobbered (int *regs_ever_clobbered)
5586 basic_block cur_bb;
5587 rtx cur_insn;
5588 unsigned int i;
5590 memset (regs_ever_clobbered, 0, 16 * sizeof (int));
5592 /* For non-leaf functions we have to consider all call clobbered regs to be
5593 clobbered. */
5594 if (!current_function_is_leaf)
5596 for (i = 0; i < 16; i++)
5597 regs_ever_clobbered[i] = call_really_used_regs[i];
5600 /* Make the "magic" eh_return registers live if necessary. For regs_ever_live
5601 this work is done by liveness analysis (mark_regs_live_at_end).
5602 Special care is needed for functions containing landing pads. Landing pads
5603 may use the eh registers, but the code which sets these registers is not
5604 contained in that function. Hence s390_regs_ever_clobbered is not able to
5605 deal with this automatically. */
5606 if (current_function_calls_eh_return || cfun->machine->has_landing_pad_p)
5607 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM ; i++)
5608 regs_ever_clobbered[EH_RETURN_DATA_REGNO (i)] = 1;
5610 /* For nonlocal gotos all call-saved registers have to be saved.
5611 This flag is also set for the unwinding code in libgcc.
5612 See expand_builtin_unwind_init. For regs_ever_live this is done by
5613 reload. */
5614 if (current_function_has_nonlocal_label)
5615 for (i = 0; i < 16; i++)
5616 if (!call_really_used_regs[i])
5617 regs_ever_clobbered[i] = 1;
5619 FOR_EACH_BB (cur_bb)
5621 FOR_BB_INSNS (cur_bb, cur_insn)
5623 if (INSN_P (cur_insn))
5624 note_stores (PATTERN (cur_insn),
5625 s390_reg_clobbered_rtx,
5626 regs_ever_clobbered);
5631 /* Determine the frame area which actually has to be accessed
5632 in the function epilogue. The values are stored at the
5633 given pointers AREA_BOTTOM (address of the lowest used stack
5634 address) and AREA_TOP (address of the first item which does
5635 not belong to the stack frame). */
5637 static void
5638 s390_frame_area (int *area_bottom, int *area_top)
5640 int b, t;
5641 int i;
5643 b = INT_MAX;
5644 t = INT_MIN;
5646 if (cfun_frame_layout.first_restore_gpr != -1)
5648 b = (cfun_frame_layout.gprs_offset
5649 + cfun_frame_layout.first_restore_gpr * UNITS_PER_WORD);
5650 t = b + (cfun_frame_layout.last_restore_gpr
5651 - cfun_frame_layout.first_restore_gpr + 1) * UNITS_PER_WORD;
5654 if (TARGET_64BIT && cfun_save_high_fprs_p)
5656 b = MIN (b, cfun_frame_layout.f8_offset);
5657 t = MAX (t, (cfun_frame_layout.f8_offset
5658 + cfun_frame_layout.high_fprs * 8));
5661 if (!TARGET_64BIT)
5662 for (i = 2; i < 4; i++)
5663 if (cfun_fpr_bit_p (i))
5665 b = MIN (b, cfun_frame_layout.f4_offset + (i - 2) * 8);
5666 t = MAX (t, cfun_frame_layout.f4_offset + (i - 1) * 8);
5669 *area_bottom = b;
5670 *area_top = t;
5673 /* Fill cfun->machine with info about register usage of current function.
5674 Return in CLOBBERED_REGS which GPRs are currently considered set. */
5676 static void
5677 s390_register_info (int clobbered_regs[])
5679 int i, j;
5681 /* fprs 8 - 15 are call saved for 64 Bit ABI. */
5682 cfun_frame_layout.fpr_bitmap = 0;
5683 cfun_frame_layout.high_fprs = 0;
5684 if (TARGET_64BIT)
5685 for (i = 24; i < 32; i++)
5686 if (regs_ever_live[i] && !global_regs[i])
5688 cfun_set_fpr_bit (i - 16);
5689 cfun_frame_layout.high_fprs++;
5692 /* Find first and last gpr to be saved. We trust regs_ever_live
5693 data, except that we don't save and restore global registers.
5695 Also, all registers with special meaning to the compiler need
5696 to be handled extra. */
5698 s390_regs_ever_clobbered (clobbered_regs);
5700 for (i = 0; i < 16; i++)
5701 clobbered_regs[i] = clobbered_regs[i] && !global_regs[i];
5703 if (frame_pointer_needed)
5704 clobbered_regs[HARD_FRAME_POINTER_REGNUM] = 1;
5706 if (flag_pic)
5707 clobbered_regs[PIC_OFFSET_TABLE_REGNUM]
5708 = regs_ever_live[PIC_OFFSET_TABLE_REGNUM];
5710 clobbered_regs[BASE_REGNUM]
5711 = cfun->machine->base_reg
5712 && REGNO (cfun->machine->base_reg) == BASE_REGNUM;
5714 clobbered_regs[RETURN_REGNUM]
5715 = cfun->machine->split_branches_pending_p
5716 || cfun_frame_layout.save_return_addr_p;
5718 clobbered_regs[STACK_POINTER_REGNUM]
5719 = !current_function_is_leaf
5720 || TARGET_TPF_PROFILING
5721 || cfun_save_high_fprs_p
5722 || get_frame_size () > 0
5723 || current_function_calls_alloca
5724 || current_function_stdarg;
5726 for (i = 6; i < 16; i++)
5727 if (clobbered_regs[i])
5728 break;
5729 for (j = 15; j > i; j--)
5730 if (clobbered_regs[j])
5731 break;
5733 if (i == 16)
5735 /* Nothing to save/restore. */
5736 cfun_frame_layout.first_save_gpr = -1;
5737 cfun_frame_layout.first_restore_gpr = -1;
5738 cfun_frame_layout.last_save_gpr = -1;
5739 cfun_frame_layout.last_restore_gpr = -1;
5741 else
5743 /* Save / Restore from gpr i to j. */
5744 cfun_frame_layout.first_save_gpr = i;
5745 cfun_frame_layout.first_restore_gpr = i;
5746 cfun_frame_layout.last_save_gpr = j;
5747 cfun_frame_layout.last_restore_gpr = j;
5750 if (current_function_stdarg)
5752 /* Varargs functions need to save gprs 2 to 6. */
5753 if (cfun->va_list_gpr_size
5754 && current_function_args_info.gprs < GP_ARG_NUM_REG)
5756 int min_gpr = current_function_args_info.gprs;
5757 int max_gpr = min_gpr + cfun->va_list_gpr_size;
5758 if (max_gpr > GP_ARG_NUM_REG)
5759 max_gpr = GP_ARG_NUM_REG;
5761 if (cfun_frame_layout.first_save_gpr == -1
5762 || cfun_frame_layout.first_save_gpr > 2 + min_gpr)
5763 cfun_frame_layout.first_save_gpr = 2 + min_gpr;
5765 if (cfun_frame_layout.last_save_gpr == -1
5766 || cfun_frame_layout.last_save_gpr < 2 + max_gpr - 1)
5767 cfun_frame_layout.last_save_gpr = 2 + max_gpr - 1;
5770 /* Mark f0, f2 for 31 bit and f0-f4 for 64 bit to be saved. */
5771 if (TARGET_HARD_FLOAT && cfun->va_list_fpr_size
5772 && current_function_args_info.fprs < FP_ARG_NUM_REG)
5774 int min_fpr = current_function_args_info.fprs;
5775 int max_fpr = min_fpr + cfun->va_list_fpr_size;
5776 if (max_fpr > FP_ARG_NUM_REG)
5777 max_fpr = FP_ARG_NUM_REG;
5779 /* ??? This is currently required to ensure proper location
5780 of the fpr save slots within the va_list save area. */
5781 if (TARGET_PACKED_STACK)
5782 min_fpr = 0;
5784 for (i = min_fpr; i < max_fpr; i++)
5785 cfun_set_fpr_bit (i);
5789 if (!TARGET_64BIT)
5790 for (i = 2; i < 4; i++)
5791 if (regs_ever_live[i + 16] && !global_regs[i + 16])
5792 cfun_set_fpr_bit (i);
5795 /* Fill cfun->machine with info about frame of current function. */
5797 static void
5798 s390_frame_info (void)
5800 int i;
5802 cfun_frame_layout.frame_size = get_frame_size ();
5803 if (!TARGET_64BIT && cfun_frame_layout.frame_size > 0x7fff0000)
5804 fatal_error ("Total size of local variables exceeds architecture limit.");
5806 if (!TARGET_PACKED_STACK)
5808 cfun_frame_layout.backchain_offset = 0;
5809 cfun_frame_layout.f0_offset = 16 * UNITS_PER_WORD;
5810 cfun_frame_layout.f4_offset = cfun_frame_layout.f0_offset + 2 * 8;
5811 cfun_frame_layout.f8_offset = -cfun_frame_layout.high_fprs * 8;
5812 cfun_frame_layout.gprs_offset = (cfun_frame_layout.first_save_gpr
5813 * UNITS_PER_WORD);
5815 else if (TARGET_BACKCHAIN) /* kernel stack layout */
5817 cfun_frame_layout.backchain_offset = (STACK_POINTER_OFFSET
5818 - UNITS_PER_WORD);
5819 cfun_frame_layout.gprs_offset
5820 = (cfun_frame_layout.backchain_offset
5821 - (STACK_POINTER_REGNUM - cfun_frame_layout.first_save_gpr + 1)
5822 * UNITS_PER_WORD);
5824 if (TARGET_64BIT)
5826 cfun_frame_layout.f4_offset
5827 = (cfun_frame_layout.gprs_offset
5828 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
5830 cfun_frame_layout.f0_offset
5831 = (cfun_frame_layout.f4_offset
5832 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
5834 else
5836 /* On 31 bit we have to care about alignment of the
5837 floating point regs to provide fastest access. */
5838 cfun_frame_layout.f0_offset
5839 = ((cfun_frame_layout.gprs_offset
5840 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1))
5841 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
5843 cfun_frame_layout.f4_offset
5844 = (cfun_frame_layout.f0_offset
5845 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
5848 else /* no backchain */
5850 cfun_frame_layout.f4_offset
5851 = (STACK_POINTER_OFFSET
5852 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
5854 cfun_frame_layout.f0_offset
5855 = (cfun_frame_layout.f4_offset
5856 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
5858 cfun_frame_layout.gprs_offset
5859 = cfun_frame_layout.f0_offset - cfun_gprs_save_area_size;
5862 if (current_function_is_leaf
5863 && !TARGET_TPF_PROFILING
5864 && cfun_frame_layout.frame_size == 0
5865 && !cfun_save_high_fprs_p
5866 && !current_function_calls_alloca
5867 && !current_function_stdarg)
5868 return;
5870 if (!TARGET_PACKED_STACK)
5871 cfun_frame_layout.frame_size += (STACK_POINTER_OFFSET
5872 + current_function_outgoing_args_size
5873 + cfun_frame_layout.high_fprs * 8);
5874 else
5876 if (TARGET_BACKCHAIN)
5877 cfun_frame_layout.frame_size += UNITS_PER_WORD;
5879 /* No alignment trouble here because f8-f15 are only saved under
5880 64 bit. */
5881 cfun_frame_layout.f8_offset = (MIN (MIN (cfun_frame_layout.f0_offset,
5882 cfun_frame_layout.f4_offset),
5883 cfun_frame_layout.gprs_offset)
5884 - cfun_frame_layout.high_fprs * 8);
5886 cfun_frame_layout.frame_size += cfun_frame_layout.high_fprs * 8;
5888 for (i = 0; i < 8; i++)
5889 if (cfun_fpr_bit_p (i))
5890 cfun_frame_layout.frame_size += 8;
5892 cfun_frame_layout.frame_size += cfun_gprs_save_area_size;
5894 /* If under 31 bit an odd number of gprs has to be saved we have to adjust
5895 the frame size to sustain 8 byte alignment of stack frames. */
5896 cfun_frame_layout.frame_size = ((cfun_frame_layout.frame_size +
5897 STACK_BOUNDARY / BITS_PER_UNIT - 1)
5898 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
5900 cfun_frame_layout.frame_size += current_function_outgoing_args_size;
5904 /* Generate frame layout. Fills in register and frame data for the current
5905 function in cfun->machine. This routine can be called multiple times;
5906 it will re-do the complete frame layout every time. */
5908 static void
5909 s390_init_frame_layout (void)
5911 HOST_WIDE_INT frame_size;
5912 int base_used;
5913 int clobbered_regs[16];
5915 /* If return address register is explicitly used, we need to save it. */
5916 s390_regs_ever_clobbered (clobbered_regs);
5918 if (clobbered_regs[RETURN_REGNUM]
5919 || !current_function_is_leaf
5920 || TARGET_TPF_PROFILING
5921 || current_function_stdarg
5922 || current_function_calls_eh_return)
5923 cfun_frame_layout.save_return_addr_p = true;
5925 /* On S/390 machines, we may need to perform branch splitting, which
5926 will require both base and return address register. We have no
5927 choice but to assume we're going to need them until right at the
5928 end of the machine dependent reorg phase. */
5929 if (!TARGET_CPU_ZARCH)
5930 cfun->machine->split_branches_pending_p = true;
5934 frame_size = cfun_frame_layout.frame_size;
5936 /* Try to predict whether we'll need the base register. */
5937 base_used = cfun->machine->split_branches_pending_p
5938 || current_function_uses_const_pool
5939 || (!DISP_IN_RANGE (-frame_size)
5940 && !CONST_OK_FOR_CONSTRAINT_P (-frame_size, 'K', "K"));
5942 /* Decide which register to use as literal pool base. In small
5943 leaf functions, try to use an unused call-clobbered register
5944 as base register to avoid save/restore overhead. */
5945 if (!base_used)
5946 cfun->machine->base_reg = NULL_RTX;
5947 else if (current_function_is_leaf && !regs_ever_live[5])
5948 cfun->machine->base_reg = gen_rtx_REG (Pmode, 5);
5949 else
5950 cfun->machine->base_reg = gen_rtx_REG (Pmode, BASE_REGNUM);
5952 s390_register_info (clobbered_regs);
5953 s390_frame_info ();
5955 while (frame_size != cfun_frame_layout.frame_size);
5958 /* Update frame layout. Recompute actual register save data based on
5959 current info and update regs_ever_live for the special registers.
5960 May be called multiple times, but may never cause *more* registers
5961 to be saved than s390_init_frame_layout allocated room for. */
5963 static void
5964 s390_update_frame_layout (void)
5966 int clobbered_regs[16];
5968 s390_register_info (clobbered_regs);
5970 regs_ever_live[BASE_REGNUM] = clobbered_regs[BASE_REGNUM];
5971 regs_ever_live[RETURN_REGNUM] = clobbered_regs[RETURN_REGNUM];
5972 regs_ever_live[STACK_POINTER_REGNUM] = clobbered_regs[STACK_POINTER_REGNUM];
5974 if (cfun->machine->base_reg)
5975 regs_ever_live[REGNO (cfun->machine->base_reg)] = 1;
5978 /* Return true if register FROM can be eliminated via register TO. */
5980 bool
5981 s390_can_eliminate (int from, int to)
5983 gcc_assert (to == STACK_POINTER_REGNUM
5984 || to == HARD_FRAME_POINTER_REGNUM);
5986 gcc_assert (from == FRAME_POINTER_REGNUM
5987 || from == ARG_POINTER_REGNUM
5988 || from == RETURN_ADDRESS_POINTER_REGNUM);
5990 /* Make sure we actually saved the return address. */
5991 if (from == RETURN_ADDRESS_POINTER_REGNUM)
5992 if (!current_function_calls_eh_return
5993 && !current_function_stdarg
5994 && !cfun_frame_layout.save_return_addr_p)
5995 return false;
5997 return true;
6000 /* Return offset between register FROM and TO initially after prolog. */
6002 HOST_WIDE_INT
6003 s390_initial_elimination_offset (int from, int to)
6005 HOST_WIDE_INT offset;
6006 int index;
6008 /* ??? Why are we called for non-eliminable pairs? */
6009 if (!s390_can_eliminate (from, to))
6010 return 0;
6012 switch (from)
6014 case FRAME_POINTER_REGNUM:
6015 offset = (get_frame_size()
6016 + STACK_POINTER_OFFSET
6017 + current_function_outgoing_args_size);
6018 break;
6020 case ARG_POINTER_REGNUM:
6021 s390_init_frame_layout ();
6022 offset = cfun_frame_layout.frame_size + STACK_POINTER_OFFSET;
6023 break;
6025 case RETURN_ADDRESS_POINTER_REGNUM:
6026 s390_init_frame_layout ();
6027 index = RETURN_REGNUM - cfun_frame_layout.first_save_gpr;
6028 gcc_assert (index >= 0);
6029 offset = cfun_frame_layout.frame_size + cfun_frame_layout.gprs_offset;
6030 offset += index * UNITS_PER_WORD;
6031 break;
6033 default:
6034 gcc_unreachable ();
6037 return offset;
6040 /* Emit insn to save fpr REGNUM at offset OFFSET relative
6041 to register BASE. Return generated insn. */
6043 static rtx
6044 save_fpr (rtx base, int offset, int regnum)
6046 rtx addr;
6047 addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
6048 set_mem_alias_set (addr, s390_sr_alias_set);
6050 return emit_move_insn (addr, gen_rtx_REG (DFmode, regnum));
6053 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
6054 to register BASE. Return generated insn. */
6056 static rtx
6057 restore_fpr (rtx base, int offset, int regnum)
6059 rtx addr;
6060 addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
6061 set_mem_alias_set (addr, s390_sr_alias_set);
6063 return emit_move_insn (gen_rtx_REG (DFmode, regnum), addr);
6066 /* Generate insn to save registers FIRST to LAST into
6067 the register save area located at offset OFFSET
6068 relative to register BASE. */
6070 static rtx
6071 save_gprs (rtx base, int offset, int first, int last)
6073 rtx addr, insn, note;
6074 int i;
6076 addr = plus_constant (base, offset);
6077 addr = gen_rtx_MEM (Pmode, addr);
6078 set_mem_alias_set (addr, s390_sr_alias_set);
6080 /* Special-case single register. */
6081 if (first == last)
6083 if (TARGET_64BIT)
6084 insn = gen_movdi (addr, gen_rtx_REG (Pmode, first));
6085 else
6086 insn = gen_movsi (addr, gen_rtx_REG (Pmode, first));
6088 RTX_FRAME_RELATED_P (insn) = 1;
6089 return insn;
6093 insn = gen_store_multiple (addr,
6094 gen_rtx_REG (Pmode, first),
6095 GEN_INT (last - first + 1));
6098 /* We need to set the FRAME_RELATED flag on all SETs
6099 inside the store-multiple pattern.
6101 However, we must not emit DWARF records for registers 2..5
6102 if they are stored for use by variable arguments ...
6104 ??? Unfortunately, it is not enough to simply not the the
6105 FRAME_RELATED flags for those SETs, because the first SET
6106 of the PARALLEL is always treated as if it had the flag
6107 set, even if it does not. Therefore we emit a new pattern
6108 without those registers as REG_FRAME_RELATED_EXPR note. */
6110 if (first >= 6)
6112 rtx pat = PATTERN (insn);
6114 for (i = 0; i < XVECLEN (pat, 0); i++)
6115 if (GET_CODE (XVECEXP (pat, 0, i)) == SET)
6116 RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1;
6118 RTX_FRAME_RELATED_P (insn) = 1;
6120 else if (last >= 6)
6122 addr = plus_constant (base, offset + (6 - first) * UNITS_PER_WORD);
6123 note = gen_store_multiple (gen_rtx_MEM (Pmode, addr),
6124 gen_rtx_REG (Pmode, 6),
6125 GEN_INT (last - 6 + 1));
6126 note = PATTERN (note);
6128 REG_NOTES (insn) =
6129 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
6130 note, REG_NOTES (insn));
6132 for (i = 0; i < XVECLEN (note, 0); i++)
6133 if (GET_CODE (XVECEXP (note, 0, i)) == SET)
6134 RTX_FRAME_RELATED_P (XVECEXP (note, 0, i)) = 1;
6136 RTX_FRAME_RELATED_P (insn) = 1;
6139 return insn;
6142 /* Generate insn to restore registers FIRST to LAST from
6143 the register save area located at offset OFFSET
6144 relative to register BASE. */
6146 static rtx
6147 restore_gprs (rtx base, int offset, int first, int last)
6149 rtx addr, insn;
6151 addr = plus_constant (base, offset);
6152 addr = gen_rtx_MEM (Pmode, addr);
6153 set_mem_alias_set (addr, s390_sr_alias_set);
6155 /* Special-case single register. */
6156 if (first == last)
6158 if (TARGET_64BIT)
6159 insn = gen_movdi (gen_rtx_REG (Pmode, first), addr);
6160 else
6161 insn = gen_movsi (gen_rtx_REG (Pmode, first), addr);
6163 return insn;
6166 insn = gen_load_multiple (gen_rtx_REG (Pmode, first),
6167 addr,
6168 GEN_INT (last - first + 1));
6169 return insn;
6172 /* Return insn sequence to load the GOT register. */
6174 static GTY(()) rtx got_symbol;
6176 s390_load_got (void)
6178 rtx insns;
6180 if (!got_symbol)
6182 got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6183 SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
6186 start_sequence ();
6188 if (TARGET_CPU_ZARCH)
6190 emit_move_insn (pic_offset_table_rtx, got_symbol);
6192 else
6194 rtx offset;
6196 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got_symbol),
6197 UNSPEC_LTREL_OFFSET);
6198 offset = gen_rtx_CONST (Pmode, offset);
6199 offset = force_const_mem (Pmode, offset);
6201 emit_move_insn (pic_offset_table_rtx, offset);
6203 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (offset, 0)),
6204 UNSPEC_LTREL_BASE);
6205 offset = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, offset);
6207 emit_move_insn (pic_offset_table_rtx, offset);
6210 insns = get_insns ();
6211 end_sequence ();
6212 return insns;
6215 /* Expand the prologue into a bunch of separate insns. */
6217 void
6218 s390_emit_prologue (void)
6220 rtx insn, addr;
6221 rtx temp_reg;
6222 int i;
6223 int offset;
6224 int next_fpr = 0;
6226 /* Complete frame layout. */
6228 s390_update_frame_layout ();
6230 /* Annotate all constant pool references to let the scheduler know
6231 they implicitly use the base register. */
6233 push_topmost_sequence ();
6235 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6236 if (INSN_P (insn))
6237 annotate_constant_pool_refs (&PATTERN (insn));
6239 pop_topmost_sequence ();
6241 /* Choose best register to use for temp use within prologue.
6242 See below for why TPF must use the register 1. */
6244 if (!has_hard_reg_initial_val (Pmode, RETURN_REGNUM)
6245 && !current_function_is_leaf
6246 && !TARGET_TPF_PROFILING)
6247 temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
6248 else
6249 temp_reg = gen_rtx_REG (Pmode, 1);
6251 /* Save call saved gprs. */
6252 if (cfun_frame_layout.first_save_gpr != -1)
6254 insn = save_gprs (stack_pointer_rtx,
6255 cfun_frame_layout.gprs_offset,
6256 cfun_frame_layout.first_save_gpr,
6257 cfun_frame_layout.last_save_gpr);
6258 emit_insn (insn);
6261 /* Dummy insn to mark literal pool slot. */
6263 if (cfun->machine->base_reg)
6264 emit_insn (gen_main_pool (cfun->machine->base_reg));
6266 offset = cfun_frame_layout.f0_offset;
6268 /* Save f0 and f2. */
6269 for (i = 0; i < 2; i++)
6271 if (cfun_fpr_bit_p (i))
6273 save_fpr (stack_pointer_rtx, offset, i + 16);
6274 offset += 8;
6276 else if (!TARGET_PACKED_STACK)
6277 offset += 8;
6280 /* Save f4 and f6. */
6281 offset = cfun_frame_layout.f4_offset;
6282 for (i = 2; i < 4; i++)
6284 if (cfun_fpr_bit_p (i))
6286 insn = save_fpr (stack_pointer_rtx, offset, i + 16);
6287 offset += 8;
6289 /* If f4 and f6 are call clobbered they are saved due to stdargs and
6290 therefore are not frame related. */
6291 if (!call_really_used_regs[i + 16])
6292 RTX_FRAME_RELATED_P (insn) = 1;
6294 else if (!TARGET_PACKED_STACK)
6295 offset += 8;
6298 if (TARGET_PACKED_STACK
6299 && cfun_save_high_fprs_p
6300 && cfun_frame_layout.f8_offset + cfun_frame_layout.high_fprs * 8 > 0)
6302 offset = (cfun_frame_layout.f8_offset
6303 + (cfun_frame_layout.high_fprs - 1) * 8);
6305 for (i = 15; i > 7 && offset >= 0; i--)
6306 if (cfun_fpr_bit_p (i))
6308 insn = save_fpr (stack_pointer_rtx, offset, i + 16);
6310 RTX_FRAME_RELATED_P (insn) = 1;
6311 offset -= 8;
6313 if (offset >= cfun_frame_layout.f8_offset)
6314 next_fpr = i + 16;
6317 if (!TARGET_PACKED_STACK)
6318 next_fpr = cfun_save_high_fprs_p ? 31 : 0;
6320 /* Decrement stack pointer. */
6322 if (cfun_frame_layout.frame_size > 0)
6324 rtx frame_off = GEN_INT (-cfun_frame_layout.frame_size);
6326 if (s390_stack_size)
6328 HOST_WIDE_INT stack_check_mask = ((s390_stack_size - 1)
6329 & ~(s390_stack_guard - 1));
6330 rtx t = gen_rtx_AND (Pmode, stack_pointer_rtx,
6331 GEN_INT (stack_check_mask));
6333 if (TARGET_64BIT)
6334 gen_cmpdi (t, const0_rtx);
6335 else
6336 gen_cmpsi (t, const0_rtx);
6338 emit_insn (gen_conditional_trap (gen_rtx_EQ (CCmode,
6339 gen_rtx_REG (CCmode,
6340 CC_REGNUM),
6341 const0_rtx),
6342 const0_rtx));
6345 if (s390_warn_framesize > 0
6346 && cfun_frame_layout.frame_size >= s390_warn_framesize)
6347 warning (0, "frame size of %qs is " HOST_WIDE_INT_PRINT_DEC " bytes",
6348 current_function_name (), cfun_frame_layout.frame_size);
6350 if (s390_warn_dynamicstack_p && cfun->calls_alloca)
6351 warning (0, "%qs uses dynamic stack allocation", current_function_name ());
6353 /* Save incoming stack pointer into temp reg. */
6354 if (TARGET_BACKCHAIN || next_fpr)
6355 insn = emit_insn (gen_move_insn (temp_reg, stack_pointer_rtx));
6357 /* Subtract frame size from stack pointer. */
6359 if (DISP_IN_RANGE (INTVAL (frame_off)))
6361 insn = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
6362 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
6363 frame_off));
6364 insn = emit_insn (insn);
6366 else
6368 if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off), 'K', "K"))
6369 frame_off = force_const_mem (Pmode, frame_off);
6371 insn = emit_insn (gen_add2_insn (stack_pointer_rtx, frame_off));
6372 annotate_constant_pool_refs (&PATTERN (insn));
6375 RTX_FRAME_RELATED_P (insn) = 1;
6376 REG_NOTES (insn) =
6377 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
6378 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
6379 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
6380 GEN_INT (-cfun_frame_layout.frame_size))),
6381 REG_NOTES (insn));
6383 /* Set backchain. */
6385 if (TARGET_BACKCHAIN)
6387 if (cfun_frame_layout.backchain_offset)
6388 addr = gen_rtx_MEM (Pmode,
6389 plus_constant (stack_pointer_rtx,
6390 cfun_frame_layout.backchain_offset));
6391 else
6392 addr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
6393 set_mem_alias_set (addr, s390_sr_alias_set);
6394 insn = emit_insn (gen_move_insn (addr, temp_reg));
6397 /* If we support asynchronous exceptions (e.g. for Java),
6398 we need to make sure the backchain pointer is set up
6399 before any possibly trapping memory access. */
6401 if (TARGET_BACKCHAIN && flag_non_call_exceptions)
6403 addr = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
6404 emit_insn (gen_rtx_CLOBBER (VOIDmode, addr));
6408 /* Save fprs 8 - 15 (64 bit ABI). */
6410 if (cfun_save_high_fprs_p && next_fpr)
6412 insn = emit_insn (gen_add2_insn (temp_reg,
6413 GEN_INT (cfun_frame_layout.f8_offset)));
6415 offset = 0;
6417 for (i = 24; i <= next_fpr; i++)
6418 if (cfun_fpr_bit_p (i - 16))
6420 rtx addr = plus_constant (stack_pointer_rtx,
6421 cfun_frame_layout.frame_size
6422 + cfun_frame_layout.f8_offset
6423 + offset);
6425 insn = save_fpr (temp_reg, offset, i);
6426 offset += 8;
6427 RTX_FRAME_RELATED_P (insn) = 1;
6428 REG_NOTES (insn) =
6429 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
6430 gen_rtx_SET (VOIDmode,
6431 gen_rtx_MEM (DFmode, addr),
6432 gen_rtx_REG (DFmode, i)),
6433 REG_NOTES (insn));
6437 /* Set frame pointer, if needed. */
6439 if (frame_pointer_needed)
6441 insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
6442 RTX_FRAME_RELATED_P (insn) = 1;
6445 /* Set up got pointer, if needed. */
6447 if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
6449 rtx insns = s390_load_got ();
6451 for (insn = insns; insn; insn = NEXT_INSN (insn))
6453 annotate_constant_pool_refs (&PATTERN (insn));
6455 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
6456 REG_NOTES (insn));
6459 emit_insn (insns);
6462 if (TARGET_TPF_PROFILING)
6464 /* Generate a BAS instruction to serve as a function
6465 entry intercept to facilitate the use of tracing
6466 algorithms located at the branch target. */
6467 emit_insn (gen_prologue_tpf ());
6469 /* Emit a blockage here so that all code
6470 lies between the profiling mechanisms. */
6471 emit_insn (gen_blockage ());
6475 /* Expand the epilogue into a bunch of separate insns. */
6477 void
6478 s390_emit_epilogue (bool sibcall)
6480 rtx frame_pointer, return_reg;
6481 int area_bottom, area_top, offset = 0;
6482 int next_offset;
6483 rtvec p;
6484 int i;
6486 if (TARGET_TPF_PROFILING)
6489 /* Generate a BAS instruction to serve as a function
6490 entry intercept to facilitate the use of tracing
6491 algorithms located at the branch target. */
6493 /* Emit a blockage here so that all code
6494 lies between the profiling mechanisms. */
6495 emit_insn (gen_blockage ());
6497 emit_insn (gen_epilogue_tpf ());
6500 /* Check whether to use frame or stack pointer for restore. */
6502 frame_pointer = (frame_pointer_needed
6503 ? hard_frame_pointer_rtx : stack_pointer_rtx);
6505 s390_frame_area (&area_bottom, &area_top);
6507 /* Check whether we can access the register save area.
6508 If not, increment the frame pointer as required. */
6510 if (area_top <= area_bottom)
6512 /* Nothing to restore. */
6514 else if (DISP_IN_RANGE (cfun_frame_layout.frame_size + area_bottom)
6515 && DISP_IN_RANGE (cfun_frame_layout.frame_size + area_top - 1))
6517 /* Area is in range. */
6518 offset = cfun_frame_layout.frame_size;
6520 else
6522 rtx insn, frame_off;
6524 offset = area_bottom < 0 ? -area_bottom : 0;
6525 frame_off = GEN_INT (cfun_frame_layout.frame_size - offset);
6527 if (DISP_IN_RANGE (INTVAL (frame_off)))
6529 insn = gen_rtx_SET (VOIDmode, frame_pointer,
6530 gen_rtx_PLUS (Pmode, frame_pointer, frame_off));
6531 insn = emit_insn (insn);
6533 else
6535 if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off), 'K', "K"))
6536 frame_off = force_const_mem (Pmode, frame_off);
6538 insn = emit_insn (gen_add2_insn (frame_pointer, frame_off));
6539 annotate_constant_pool_refs (&PATTERN (insn));
6543 /* Restore call saved fprs. */
6545 if (TARGET_64BIT)
6547 if (cfun_save_high_fprs_p)
6549 next_offset = cfun_frame_layout.f8_offset;
6550 for (i = 24; i < 32; i++)
6552 if (cfun_fpr_bit_p (i - 16))
6554 restore_fpr (frame_pointer,
6555 offset + next_offset, i);
6556 next_offset += 8;
6562 else
6564 next_offset = cfun_frame_layout.f4_offset;
6565 for (i = 18; i < 20; i++)
6567 if (cfun_fpr_bit_p (i - 16))
6569 restore_fpr (frame_pointer,
6570 offset + next_offset, i);
6571 next_offset += 8;
6573 else if (!TARGET_PACKED_STACK)
6574 next_offset += 8;
6579 /* Return register. */
6581 return_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
6583 /* Restore call saved gprs. */
6585 if (cfun_frame_layout.first_restore_gpr != -1)
6587 rtx insn, addr;
6588 int i;
6590 /* Check for global register and save them
6591 to stack location from where they get restored. */
6593 for (i = cfun_frame_layout.first_restore_gpr;
6594 i <= cfun_frame_layout.last_restore_gpr;
6595 i++)
6597 /* These registers are special and need to be
6598 restored in any case. */
6599 if (i == STACK_POINTER_REGNUM
6600 || i == RETURN_REGNUM
6601 || i == BASE_REGNUM
6602 || (flag_pic && i == (int)PIC_OFFSET_TABLE_REGNUM))
6603 continue;
6605 if (global_regs[i])
6607 addr = plus_constant (frame_pointer,
6608 offset + cfun_frame_layout.gprs_offset
6609 + (i - cfun_frame_layout.first_save_gpr)
6610 * UNITS_PER_WORD);
6611 addr = gen_rtx_MEM (Pmode, addr);
6612 set_mem_alias_set (addr, s390_sr_alias_set);
6613 emit_move_insn (addr, gen_rtx_REG (Pmode, i));
6617 if (! sibcall)
6619 /* Fetch return address from stack before load multiple,
6620 this will do good for scheduling. */
6622 if (cfun_frame_layout.save_return_addr_p
6623 || (cfun_frame_layout.first_restore_gpr < BASE_REGNUM
6624 && cfun_frame_layout.last_restore_gpr > RETURN_REGNUM))
6626 int return_regnum = find_unused_clobbered_reg();
6627 if (!return_regnum)
6628 return_regnum = 4;
6629 return_reg = gen_rtx_REG (Pmode, return_regnum);
6631 addr = plus_constant (frame_pointer,
6632 offset + cfun_frame_layout.gprs_offset
6633 + (RETURN_REGNUM
6634 - cfun_frame_layout.first_save_gpr)
6635 * UNITS_PER_WORD);
6636 addr = gen_rtx_MEM (Pmode, addr);
6637 set_mem_alias_set (addr, s390_sr_alias_set);
6638 emit_move_insn (return_reg, addr);
6642 insn = restore_gprs (frame_pointer,
6643 offset + cfun_frame_layout.gprs_offset
6644 + (cfun_frame_layout.first_restore_gpr
6645 - cfun_frame_layout.first_save_gpr)
6646 * UNITS_PER_WORD,
6647 cfun_frame_layout.first_restore_gpr,
6648 cfun_frame_layout.last_restore_gpr);
6649 emit_insn (insn);
6652 if (! sibcall)
6655 /* Return to caller. */
6657 p = rtvec_alloc (2);
6659 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
6660 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, return_reg);
6661 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
6666 /* Return the size in bytes of a function argument of
6667 type TYPE and/or mode MODE. At least one of TYPE or
6668 MODE must be specified. */
6670 static int
6671 s390_function_arg_size (enum machine_mode mode, tree type)
6673 if (type)
6674 return int_size_in_bytes (type);
6676 /* No type info available for some library calls ... */
6677 if (mode != BLKmode)
6678 return GET_MODE_SIZE (mode);
6680 /* If we have neither type nor mode, abort */
6681 gcc_unreachable ();
6684 /* Return true if a function argument of type TYPE and mode MODE
6685 is to be passed in a floating-point register, if available. */
6687 static bool
6688 s390_function_arg_float (enum machine_mode mode, tree type)
6690 int size = s390_function_arg_size (mode, type);
6691 if (size > 8)
6692 return false;
6694 /* Soft-float changes the ABI: no floating-point registers are used. */
6695 if (TARGET_SOFT_FLOAT)
6696 return false;
6698 /* No type info available for some library calls ... */
6699 if (!type)
6700 return mode == SFmode || mode == DFmode;
6702 /* The ABI says that record types with a single member are treated
6703 just like that member would be. */
6704 while (TREE_CODE (type) == RECORD_TYPE)
6706 tree field, single = NULL_TREE;
6708 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
6710 if (TREE_CODE (field) != FIELD_DECL)
6711 continue;
6713 if (single == NULL_TREE)
6714 single = TREE_TYPE (field);
6715 else
6716 return false;
6719 if (single == NULL_TREE)
6720 return false;
6721 else
6722 type = single;
6725 return TREE_CODE (type) == REAL_TYPE;
6728 /* Return true if a function argument of type TYPE and mode MODE
6729 is to be passed in an integer register, or a pair of integer
6730 registers, if available. */
6732 static bool
6733 s390_function_arg_integer (enum machine_mode mode, tree type)
6735 int size = s390_function_arg_size (mode, type);
6736 if (size > 8)
6737 return false;
6739 /* No type info available for some library calls ... */
6740 if (!type)
6741 return GET_MODE_CLASS (mode) == MODE_INT
6742 || (TARGET_SOFT_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT);
6744 /* We accept small integral (and similar) types. */
6745 if (INTEGRAL_TYPE_P (type)
6746 || POINTER_TYPE_P (type)
6747 || TREE_CODE (type) == OFFSET_TYPE
6748 || (TARGET_SOFT_FLOAT && TREE_CODE (type) == REAL_TYPE))
6749 return true;
6751 /* We also accept structs of size 1, 2, 4, 8 that are not
6752 passed in floating-point registers. */
6753 if (AGGREGATE_TYPE_P (type)
6754 && exact_log2 (size) >= 0
6755 && !s390_function_arg_float (mode, type))
6756 return true;
6758 return false;
6761 /* Return 1 if a function argument of type TYPE and mode MODE
6762 is to be passed by reference. The ABI specifies that only
6763 structures of size 1, 2, 4, or 8 bytes are passed by value,
6764 all other structures (and complex numbers) are passed by
6765 reference. */
6767 static bool
6768 s390_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
6769 enum machine_mode mode, tree type,
6770 bool named ATTRIBUTE_UNUSED)
6772 int size = s390_function_arg_size (mode, type);
6773 if (size > 8)
6774 return true;
6776 if (type)
6778 if (AGGREGATE_TYPE_P (type) && exact_log2 (size) < 0)
6779 return 1;
6781 if (TREE_CODE (type) == COMPLEX_TYPE
6782 || TREE_CODE (type) == VECTOR_TYPE)
6783 return 1;
6786 return 0;
6789 /* Update the data in CUM to advance over an argument of mode MODE and
6790 data type TYPE. (TYPE is null for libcalls where that information
6791 may not be available.). The boolean NAMED specifies whether the
6792 argument is a named argument (as opposed to an unnamed argument
6793 matching an ellipsis). */
6795 void
6796 s390_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
6797 tree type, int named ATTRIBUTE_UNUSED)
6799 if (s390_function_arg_float (mode, type))
6801 cum->fprs += 1;
6803 else if (s390_function_arg_integer (mode, type))
6805 int size = s390_function_arg_size (mode, type);
6806 cum->gprs += ((size + UNITS_PER_WORD-1) / UNITS_PER_WORD);
6808 else
6809 gcc_unreachable ();
6812 /* Define where to put the arguments to a function.
6813 Value is zero to push the argument on the stack,
6814 or a hard register in which to store the argument.
6816 MODE is the argument's machine mode.
6817 TYPE is the data type of the argument (as a tree).
6818 This is null for libcalls where that information may
6819 not be available.
6820 CUM is a variable of type CUMULATIVE_ARGS which gives info about
6821 the preceding args and about the function being called.
6822 NAMED is nonzero if this argument is a named parameter
6823 (otherwise it is an extra parameter matching an ellipsis).
6825 On S/390, we use general purpose registers 2 through 6 to
6826 pass integer, pointer, and certain structure arguments, and
6827 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
6828 to pass floating point arguments. All remaining arguments
6829 are pushed to the stack. */
6832 s390_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
6833 int named ATTRIBUTE_UNUSED)
6835 if (s390_function_arg_float (mode, type))
6837 if (cum->fprs + 1 > FP_ARG_NUM_REG)
6838 return 0;
6839 else
6840 return gen_rtx_REG (mode, cum->fprs + 16);
6842 else if (s390_function_arg_integer (mode, type))
6844 int size = s390_function_arg_size (mode, type);
6845 int n_gprs = (size + UNITS_PER_WORD-1) / UNITS_PER_WORD;
6847 if (cum->gprs + n_gprs > GP_ARG_NUM_REG)
6848 return 0;
6849 else
6850 return gen_rtx_REG (mode, cum->gprs + 2);
6853 /* After the real arguments, expand_call calls us once again
6854 with a void_type_node type. Whatever we return here is
6855 passed as operand 2 to the call expanders.
6857 We don't need this feature ... */
6858 else if (type == void_type_node)
6859 return const0_rtx;
6861 gcc_unreachable ();
6864 /* Return true if return values of type TYPE should be returned
6865 in a memory buffer whose address is passed by the caller as
6866 hidden first argument. */
6868 static bool
6869 s390_return_in_memory (tree type, tree fundecl ATTRIBUTE_UNUSED)
6871 /* We accept small integral (and similar) types. */
6872 if (INTEGRAL_TYPE_P (type)
6873 || POINTER_TYPE_P (type)
6874 || TREE_CODE (type) == OFFSET_TYPE
6875 || TREE_CODE (type) == REAL_TYPE)
6876 return int_size_in_bytes (type) > 8;
6878 /* Aggregates and similar constructs are always returned
6879 in memory. */
6880 if (AGGREGATE_TYPE_P (type)
6881 || TREE_CODE (type) == COMPLEX_TYPE
6882 || TREE_CODE (type) == VECTOR_TYPE)
6883 return true;
6885 /* ??? We get called on all sorts of random stuff from
6886 aggregate_value_p. We can't abort, but it's not clear
6887 what's safe to return. Pretend it's a struct I guess. */
6888 return true;
6891 /* Define where to return a (scalar) value of type TYPE.
6892 If TYPE is null, define where to return a (scalar)
6893 value of mode MODE from a libcall. */
6896 s390_function_value (tree type, enum machine_mode mode)
6898 if (type)
6900 int unsignedp = TYPE_UNSIGNED (type);
6901 mode = promote_mode (type, TYPE_MODE (type), &unsignedp, 1);
6904 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT
6905 || GET_MODE_CLASS (mode) == MODE_FLOAT);
6906 gcc_assert (GET_MODE_SIZE (mode) <= 8);
6908 if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT)
6909 return gen_rtx_REG (mode, 16);
6910 else
6911 return gen_rtx_REG (mode, 2);
6915 /* Create and return the va_list datatype.
6917 On S/390, va_list is an array type equivalent to
6919 typedef struct __va_list_tag
6921 long __gpr;
6922 long __fpr;
6923 void *__overflow_arg_area;
6924 void *__reg_save_area;
6925 } va_list[1];
6927 where __gpr and __fpr hold the number of general purpose
6928 or floating point arguments used up to now, respectively,
6929 __overflow_arg_area points to the stack location of the
6930 next argument passed on the stack, and __reg_save_area
6931 always points to the start of the register area in the
6932 call frame of the current function. The function prologue
6933 saves all registers used for argument passing into this
6934 area if the function uses variable arguments. */
6936 static tree
6937 s390_build_builtin_va_list (void)
6939 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
6941 record = lang_hooks.types.make_type (RECORD_TYPE);
6943 type_decl =
6944 build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
6946 f_gpr = build_decl (FIELD_DECL, get_identifier ("__gpr"),
6947 long_integer_type_node);
6948 f_fpr = build_decl (FIELD_DECL, get_identifier ("__fpr"),
6949 long_integer_type_node);
6950 f_ovf = build_decl (FIELD_DECL, get_identifier ("__overflow_arg_area"),
6951 ptr_type_node);
6952 f_sav = build_decl (FIELD_DECL, get_identifier ("__reg_save_area"),
6953 ptr_type_node);
6955 va_list_gpr_counter_field = f_gpr;
6956 va_list_fpr_counter_field = f_fpr;
6958 DECL_FIELD_CONTEXT (f_gpr) = record;
6959 DECL_FIELD_CONTEXT (f_fpr) = record;
6960 DECL_FIELD_CONTEXT (f_ovf) = record;
6961 DECL_FIELD_CONTEXT (f_sav) = record;
6963 TREE_CHAIN (record) = type_decl;
6964 TYPE_NAME (record) = type_decl;
6965 TYPE_FIELDS (record) = f_gpr;
6966 TREE_CHAIN (f_gpr) = f_fpr;
6967 TREE_CHAIN (f_fpr) = f_ovf;
6968 TREE_CHAIN (f_ovf) = f_sav;
6970 layout_type (record);
6972 /* The correct type is an array type of one element. */
6973 return build_array_type (record, build_index_type (size_zero_node));
6976 /* Implement va_start by filling the va_list structure VALIST.
6977 STDARG_P is always true, and ignored.
6978 NEXTARG points to the first anonymous stack argument.
6980 The following global variables are used to initialize
6981 the va_list structure:
6983 current_function_args_info:
6984 holds number of gprs and fprs used for named arguments.
6985 current_function_arg_offset_rtx:
6986 holds the offset of the first anonymous stack argument
6987 (relative to the virtual arg pointer). */
6989 void
6990 s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
6992 HOST_WIDE_INT n_gpr, n_fpr;
6993 int off;
6994 tree f_gpr, f_fpr, f_ovf, f_sav;
6995 tree gpr, fpr, ovf, sav, t;
6997 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
6998 f_fpr = TREE_CHAIN (f_gpr);
6999 f_ovf = TREE_CHAIN (f_fpr);
7000 f_sav = TREE_CHAIN (f_ovf);
7002 valist = build_va_arg_indirect_ref (valist);
7003 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
7004 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
7005 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
7006 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
7008 /* Count number of gp and fp argument registers used. */
7010 n_gpr = current_function_args_info.gprs;
7011 n_fpr = current_function_args_info.fprs;
7013 if (cfun->va_list_gpr_size)
7015 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
7016 build_int_cst (NULL_TREE, n_gpr));
7017 TREE_SIDE_EFFECTS (t) = 1;
7018 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7021 if (cfun->va_list_fpr_size)
7023 t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
7024 build_int_cst (NULL_TREE, n_fpr));
7025 TREE_SIDE_EFFECTS (t) = 1;
7026 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7029 /* Find the overflow area. */
7030 if (n_gpr + cfun->va_list_gpr_size > GP_ARG_NUM_REG
7031 || n_fpr + cfun->va_list_fpr_size > FP_ARG_NUM_REG)
7033 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
7035 off = INTVAL (current_function_arg_offset_rtx);
7036 off = off < 0 ? 0 : off;
7037 if (TARGET_DEBUG_ARG)
7038 fprintf (stderr, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
7039 (int)n_gpr, (int)n_fpr, off);
7041 t = build (PLUS_EXPR, TREE_TYPE (ovf), t, build_int_cst (NULL_TREE, off));
7043 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
7044 TREE_SIDE_EFFECTS (t) = 1;
7045 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7048 /* Find the register save area. */
7049 if ((cfun->va_list_gpr_size && n_gpr < GP_ARG_NUM_REG)
7050 || (cfun->va_list_fpr_size && n_fpr < FP_ARG_NUM_REG))
7052 t = make_tree (TREE_TYPE (sav), return_address_pointer_rtx);
7053 t = build (PLUS_EXPR, TREE_TYPE (sav), t,
7054 build_int_cst (NULL_TREE, -RETURN_REGNUM * UNITS_PER_WORD));
7056 t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
7057 TREE_SIDE_EFFECTS (t) = 1;
7058 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7062 /* Implement va_arg by updating the va_list structure
7063 VALIST as required to retrieve an argument of type
7064 TYPE, and returning that argument.
7066 Generates code equivalent to:
7068 if (integral value) {
7069 if (size <= 4 && args.gpr < 5 ||
7070 size > 4 && args.gpr < 4 )
7071 ret = args.reg_save_area[args.gpr+8]
7072 else
7073 ret = *args.overflow_arg_area++;
7074 } else if (float value) {
7075 if (args.fgpr < 2)
7076 ret = args.reg_save_area[args.fpr+64]
7077 else
7078 ret = *args.overflow_arg_area++;
7079 } else if (aggregate value) {
7080 if (args.gpr < 5)
7081 ret = *args.reg_save_area[args.gpr]
7082 else
7083 ret = **args.overflow_arg_area++;
7084 } */
7086 static tree
7087 s390_gimplify_va_arg (tree valist, tree type, tree *pre_p,
7088 tree *post_p ATTRIBUTE_UNUSED)
7090 tree f_gpr, f_fpr, f_ovf, f_sav;
7091 tree gpr, fpr, ovf, sav, reg, t, u;
7092 int indirect_p, size, n_reg, sav_ofs, sav_scale, max_reg;
7093 tree lab_false, lab_over, addr;
7095 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
7096 f_fpr = TREE_CHAIN (f_gpr);
7097 f_ovf = TREE_CHAIN (f_fpr);
7098 f_sav = TREE_CHAIN (f_ovf);
7100 valist = build_va_arg_indirect_ref (valist);
7101 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
7102 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
7103 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
7104 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
7106 size = int_size_in_bytes (type);
7108 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
7110 if (TARGET_DEBUG_ARG)
7112 fprintf (stderr, "va_arg: aggregate type");
7113 debug_tree (type);
7116 /* Aggregates are passed by reference. */
7117 indirect_p = 1;
7118 reg = gpr;
7119 n_reg = 1;
7121 /* kernel stack layout on 31 bit: It is assumed here that no padding
7122 will be added by s390_frame_info because for va_args always an even
7123 number of gprs has to be saved r15-r2 = 14 regs. */
7124 sav_ofs = 2 * UNITS_PER_WORD;
7125 sav_scale = UNITS_PER_WORD;
7126 size = UNITS_PER_WORD;
7127 max_reg = GP_ARG_NUM_REG - n_reg;
7129 else if (s390_function_arg_float (TYPE_MODE (type), type))
7131 if (TARGET_DEBUG_ARG)
7133 fprintf (stderr, "va_arg: float type");
7134 debug_tree (type);
7137 /* FP args go in FP registers, if present. */
7138 indirect_p = 0;
7139 reg = fpr;
7140 n_reg = 1;
7141 sav_ofs = 16 * UNITS_PER_WORD;
7142 sav_scale = 8;
7143 max_reg = FP_ARG_NUM_REG - n_reg;
7145 else
7147 if (TARGET_DEBUG_ARG)
7149 fprintf (stderr, "va_arg: other type");
7150 debug_tree (type);
7153 /* Otherwise into GP registers. */
7154 indirect_p = 0;
7155 reg = gpr;
7156 n_reg = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
7158 /* kernel stack layout on 31 bit: It is assumed here that no padding
7159 will be added by s390_frame_info because for va_args always an even
7160 number of gprs has to be saved r15-r2 = 14 regs. */
7161 sav_ofs = 2 * UNITS_PER_WORD;
7163 if (size < UNITS_PER_WORD)
7164 sav_ofs += UNITS_PER_WORD - size;
7166 sav_scale = UNITS_PER_WORD;
7167 max_reg = GP_ARG_NUM_REG - n_reg;
7170 /* Pull the value out of the saved registers ... */
7172 lab_false = create_artificial_label ();
7173 lab_over = create_artificial_label ();
7174 addr = create_tmp_var (ptr_type_node, "addr");
7175 DECL_POINTER_ALIAS_SET (addr) = s390_sr_alias_set;
7177 t = fold_convert (TREE_TYPE (reg), size_int (max_reg));
7178 t = build2 (GT_EXPR, boolean_type_node, reg, t);
7179 u = build1 (GOTO_EXPR, void_type_node, lab_false);
7180 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
7181 gimplify_and_add (t, pre_p);
7183 t = build2 (PLUS_EXPR, ptr_type_node, sav,
7184 fold_convert (ptr_type_node, size_int (sav_ofs)));
7185 u = build2 (MULT_EXPR, TREE_TYPE (reg), reg,
7186 fold_convert (TREE_TYPE (reg), size_int (sav_scale)));
7187 t = build2 (PLUS_EXPR, ptr_type_node, t, fold_convert (ptr_type_node, u));
7189 t = build2 (MODIFY_EXPR, void_type_node, addr, t);
7190 gimplify_and_add (t, pre_p);
7192 t = build1 (GOTO_EXPR, void_type_node, lab_over);
7193 gimplify_and_add (t, pre_p);
7195 t = build1 (LABEL_EXPR, void_type_node, lab_false);
7196 append_to_statement_list (t, pre_p);
7199 /* ... Otherwise out of the overflow area. */
7201 t = ovf;
7202 if (size < UNITS_PER_WORD)
7203 t = build2 (PLUS_EXPR, ptr_type_node, t,
7204 fold_convert (ptr_type_node, size_int (UNITS_PER_WORD - size)));
7206 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
7208 u = build2 (MODIFY_EXPR, void_type_node, addr, t);
7209 gimplify_and_add (u, pre_p);
7211 t = build2 (PLUS_EXPR, ptr_type_node, t,
7212 fold_convert (ptr_type_node, size_int (size)));
7213 t = build2 (MODIFY_EXPR, ptr_type_node, ovf, t);
7214 gimplify_and_add (t, pre_p);
7216 t = build1 (LABEL_EXPR, void_type_node, lab_over);
7217 append_to_statement_list (t, pre_p);
7220 /* Increment register save count. */
7222 u = build2 (PREINCREMENT_EXPR, TREE_TYPE (reg), reg,
7223 fold_convert (TREE_TYPE (reg), size_int (n_reg)));
7224 gimplify_and_add (u, pre_p);
7226 if (indirect_p)
7228 t = build_pointer_type (build_pointer_type (type));
7229 addr = fold_convert (t, addr);
7230 addr = build_va_arg_indirect_ref (addr);
7232 else
7234 t = build_pointer_type (type);
7235 addr = fold_convert (t, addr);
7238 return build_va_arg_indirect_ref (addr);
7242 /* Builtins. */
7244 enum s390_builtin
7246 S390_BUILTIN_THREAD_POINTER,
7247 S390_BUILTIN_SET_THREAD_POINTER,
7249 S390_BUILTIN_max
7252 static unsigned int const code_for_builtin_64[S390_BUILTIN_max] = {
7253 CODE_FOR_get_tp_64,
7254 CODE_FOR_set_tp_64
7257 static unsigned int const code_for_builtin_31[S390_BUILTIN_max] = {
7258 CODE_FOR_get_tp_31,
7259 CODE_FOR_set_tp_31
7262 static void
7263 s390_init_builtins (void)
7265 tree ftype;
7267 ftype = build_function_type (ptr_type_node, void_list_node);
7268 lang_hooks.builtin_function ("__builtin_thread_pointer", ftype,
7269 S390_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
7270 NULL, NULL_TREE);
7272 ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
7273 lang_hooks.builtin_function ("__builtin_set_thread_pointer", ftype,
7274 S390_BUILTIN_SET_THREAD_POINTER, BUILT_IN_MD,
7275 NULL, NULL_TREE);
7278 /* Expand an expression EXP that calls a built-in function,
7279 with result going to TARGET if that's convenient
7280 (and in mode MODE if that's convenient).
7281 SUBTARGET may be used as the target for computing one of EXP's operands.
7282 IGNORE is nonzero if the value is to be ignored. */
7284 static rtx
7285 s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
7286 enum machine_mode mode ATTRIBUTE_UNUSED,
7287 int ignore ATTRIBUTE_UNUSED)
7289 #define MAX_ARGS 2
7291 unsigned int const *code_for_builtin =
7292 TARGET_64BIT ? code_for_builtin_64 : code_for_builtin_31;
7294 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7295 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7296 tree arglist = TREE_OPERAND (exp, 1);
7297 enum insn_code icode;
7298 rtx op[MAX_ARGS], pat;
7299 int arity;
7300 bool nonvoid;
7302 if (fcode >= S390_BUILTIN_max)
7303 internal_error ("bad builtin fcode");
7304 icode = code_for_builtin[fcode];
7305 if (icode == 0)
7306 internal_error ("bad builtin fcode");
7308 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
7310 for (arglist = TREE_OPERAND (exp, 1), arity = 0;
7311 arglist;
7312 arglist = TREE_CHAIN (arglist), arity++)
7314 const struct insn_operand_data *insn_op;
7316 tree arg = TREE_VALUE (arglist);
7317 if (arg == error_mark_node)
7318 return NULL_RTX;
7319 if (arity > MAX_ARGS)
7320 return NULL_RTX;
7322 insn_op = &insn_data[icode].operand[arity + nonvoid];
7324 op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, 0);
7326 if (!(*insn_op->predicate) (op[arity], insn_op->mode))
7327 op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
7330 if (nonvoid)
7332 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7333 if (!target
7334 || GET_MODE (target) != tmode
7335 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
7336 target = gen_reg_rtx (tmode);
7339 switch (arity)
7341 case 0:
7342 pat = GEN_FCN (icode) (target);
7343 break;
7344 case 1:
7345 if (nonvoid)
7346 pat = GEN_FCN (icode) (target, op[0]);
7347 else
7348 pat = GEN_FCN (icode) (op[0]);
7349 break;
7350 case 2:
7351 pat = GEN_FCN (icode) (target, op[0], op[1]);
7352 break;
7353 default:
7354 gcc_unreachable ();
7356 if (!pat)
7357 return NULL_RTX;
7358 emit_insn (pat);
7360 if (nonvoid)
7361 return target;
7362 else
7363 return const0_rtx;
7367 /* Output assembly code for the trampoline template to
7368 stdio stream FILE.
7370 On S/390, we use gpr 1 internally in the trampoline code;
7371 gpr 0 is used to hold the static chain. */
7373 void
7374 s390_trampoline_template (FILE *file)
7376 rtx op[2];
7377 op[0] = gen_rtx_REG (Pmode, 0);
7378 op[1] = gen_rtx_REG (Pmode, 1);
7380 if (TARGET_64BIT)
7382 output_asm_insn ("basr\t%1,0", op);
7383 output_asm_insn ("lmg\t%0,%1,14(%1)", op);
7384 output_asm_insn ("br\t%1", op);
7385 ASM_OUTPUT_SKIP (file, (HOST_WIDE_INT)(TRAMPOLINE_SIZE - 10));
7387 else
7389 output_asm_insn ("basr\t%1,0", op);
7390 output_asm_insn ("lm\t%0,%1,6(%1)", op);
7391 output_asm_insn ("br\t%1", op);
7392 ASM_OUTPUT_SKIP (file, (HOST_WIDE_INT)(TRAMPOLINE_SIZE - 8));
7396 /* Emit RTL insns to initialize the variable parts of a trampoline.
7397 FNADDR is an RTX for the address of the function's pure code.
7398 CXT is an RTX for the static chain value for the function. */
7400 void
7401 s390_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
7403 emit_move_insn (gen_rtx_MEM (Pmode,
7404 memory_address (Pmode,
7405 plus_constant (addr, (TARGET_64BIT ? 16 : 8)))), cxt);
7406 emit_move_insn (gen_rtx_MEM (Pmode,
7407 memory_address (Pmode,
7408 plus_constant (addr, (TARGET_64BIT ? 24 : 12)))), fnaddr);
7411 /* Return rtx for 64-bit constant formed from the 32-bit subwords
7412 LOW and HIGH, independent of the host word size. */
7415 s390_gen_rtx_const_DI (int high, int low)
7417 #if HOST_BITS_PER_WIDE_INT >= 64
7418 HOST_WIDE_INT val;
7419 val = (HOST_WIDE_INT)high;
7420 val <<= 32;
7421 val |= (HOST_WIDE_INT)low;
7423 return GEN_INT (val);
7424 #else
7425 #if HOST_BITS_PER_WIDE_INT >= 32
7426 return immed_double_const ((HOST_WIDE_INT)low, (HOST_WIDE_INT)high, DImode);
7427 #else
7428 gcc_unreachable ();
7429 #endif
7430 #endif
7433 /* Output assembler code to FILE to increment profiler label # LABELNO
7434 for profiling a function entry. */
7436 void
7437 s390_function_profiler (FILE *file, int labelno)
7439 rtx op[7];
7441 char label[128];
7442 ASM_GENERATE_INTERNAL_LABEL (label, "LP", labelno);
7444 fprintf (file, "# function profiler \n");
7446 op[0] = gen_rtx_REG (Pmode, RETURN_REGNUM);
7447 op[1] = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
7448 op[1] = gen_rtx_MEM (Pmode, plus_constant (op[1], UNITS_PER_WORD));
7450 op[2] = gen_rtx_REG (Pmode, 1);
7451 op[3] = gen_rtx_SYMBOL_REF (Pmode, label);
7452 SYMBOL_REF_FLAGS (op[3]) = SYMBOL_FLAG_LOCAL;
7454 op[4] = gen_rtx_SYMBOL_REF (Pmode, "_mcount");
7455 if (flag_pic)
7457 op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), UNSPEC_PLT);
7458 op[4] = gen_rtx_CONST (Pmode, op[4]);
7461 if (TARGET_64BIT)
7463 output_asm_insn ("stg\t%0,%1", op);
7464 output_asm_insn ("larl\t%2,%3", op);
7465 output_asm_insn ("brasl\t%0,%4", op);
7466 output_asm_insn ("lg\t%0,%1", op);
7468 else if (!flag_pic)
7470 op[6] = gen_label_rtx ();
7472 output_asm_insn ("st\t%0,%1", op);
7473 output_asm_insn ("bras\t%2,%l6", op);
7474 output_asm_insn (".long\t%4", op);
7475 output_asm_insn (".long\t%3", op);
7476 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
7477 output_asm_insn ("l\t%0,0(%2)", op);
7478 output_asm_insn ("l\t%2,4(%2)", op);
7479 output_asm_insn ("basr\t%0,%0", op);
7480 output_asm_insn ("l\t%0,%1", op);
7482 else
7484 op[5] = gen_label_rtx ();
7485 op[6] = gen_label_rtx ();
7487 output_asm_insn ("st\t%0,%1", op);
7488 output_asm_insn ("bras\t%2,%l6", op);
7489 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[5]));
7490 output_asm_insn (".long\t%4-%l5", op);
7491 output_asm_insn (".long\t%3-%l5", op);
7492 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
7493 output_asm_insn ("lr\t%0,%2", op);
7494 output_asm_insn ("a\t%0,0(%2)", op);
7495 output_asm_insn ("a\t%2,4(%2)", op);
7496 output_asm_insn ("basr\t%0,%0", op);
7497 output_asm_insn ("l\t%0,%1", op);
7501 /* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
7502 into its SYMBOL_REF_FLAGS. */
7504 static void
7505 s390_encode_section_info (tree decl, rtx rtl, int first)
7507 default_encode_section_info (decl, rtl, first);
7509 /* If a variable has a forced alignment to < 2 bytes, mark it with
7510 SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL operand. */
7511 if (TREE_CODE (decl) == VAR_DECL
7512 && DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) < 16)
7513 SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_ALIGN1;
7516 /* Output thunk to FILE that implements a C++ virtual function call (with
7517 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
7518 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
7519 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
7520 relative to the resulting this pointer. */
7522 static void
7523 s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
7524 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
7525 tree function)
7527 rtx op[10];
7528 int nonlocal = 0;
7530 /* Operand 0 is the target function. */
7531 op[0] = XEXP (DECL_RTL (function), 0);
7532 if (flag_pic && !SYMBOL_REF_LOCAL_P (op[0]))
7534 nonlocal = 1;
7535 op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]),
7536 TARGET_64BIT ? UNSPEC_PLT : UNSPEC_GOT);
7537 op[0] = gen_rtx_CONST (Pmode, op[0]);
7540 /* Operand 1 is the 'this' pointer. */
7541 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
7542 op[1] = gen_rtx_REG (Pmode, 3);
7543 else
7544 op[1] = gen_rtx_REG (Pmode, 2);
7546 /* Operand 2 is the delta. */
7547 op[2] = GEN_INT (delta);
7549 /* Operand 3 is the vcall_offset. */
7550 op[3] = GEN_INT (vcall_offset);
7552 /* Operand 4 is the temporary register. */
7553 op[4] = gen_rtx_REG (Pmode, 1);
7555 /* Operands 5 to 8 can be used as labels. */
7556 op[5] = NULL_RTX;
7557 op[6] = NULL_RTX;
7558 op[7] = NULL_RTX;
7559 op[8] = NULL_RTX;
7561 /* Operand 9 can be used for temporary register. */
7562 op[9] = NULL_RTX;
7564 /* Generate code. */
7565 if (TARGET_64BIT)
7567 /* Setup literal pool pointer if required. */
7568 if ((!DISP_IN_RANGE (delta)
7569 && !CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
7570 || (!DISP_IN_RANGE (vcall_offset)
7571 && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K")))
7573 op[5] = gen_label_rtx ();
7574 output_asm_insn ("larl\t%4,%5", op);
7577 /* Add DELTA to this pointer. */
7578 if (delta)
7580 if (CONST_OK_FOR_CONSTRAINT_P (delta, 'J', "J"))
7581 output_asm_insn ("la\t%1,%2(%1)", op);
7582 else if (DISP_IN_RANGE (delta))
7583 output_asm_insn ("lay\t%1,%2(%1)", op);
7584 else if (CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
7585 output_asm_insn ("aghi\t%1,%2", op);
7586 else
7588 op[6] = gen_label_rtx ();
7589 output_asm_insn ("agf\t%1,%6-%5(%4)", op);
7593 /* Perform vcall adjustment. */
7594 if (vcall_offset)
7596 if (DISP_IN_RANGE (vcall_offset))
7598 output_asm_insn ("lg\t%4,0(%1)", op);
7599 output_asm_insn ("ag\t%1,%3(%4)", op);
7601 else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K"))
7603 output_asm_insn ("lghi\t%4,%3", op);
7604 output_asm_insn ("ag\t%4,0(%1)", op);
7605 output_asm_insn ("ag\t%1,0(%4)", op);
7607 else
7609 op[7] = gen_label_rtx ();
7610 output_asm_insn ("llgf\t%4,%7-%5(%4)", op);
7611 output_asm_insn ("ag\t%4,0(%1)", op);
7612 output_asm_insn ("ag\t%1,0(%4)", op);
7616 /* Jump to target. */
7617 output_asm_insn ("jg\t%0", op);
7619 /* Output literal pool if required. */
7620 if (op[5])
7622 output_asm_insn (".align\t4", op);
7623 targetm.asm_out.internal_label (file, "L",
7624 CODE_LABEL_NUMBER (op[5]));
7626 if (op[6])
7628 targetm.asm_out.internal_label (file, "L",
7629 CODE_LABEL_NUMBER (op[6]));
7630 output_asm_insn (".long\t%2", op);
7632 if (op[7])
7634 targetm.asm_out.internal_label (file, "L",
7635 CODE_LABEL_NUMBER (op[7]));
7636 output_asm_insn (".long\t%3", op);
7639 else
7641 /* Setup base pointer if required. */
7642 if (!vcall_offset
7643 || (!DISP_IN_RANGE (delta)
7644 && !CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
7645 || (!DISP_IN_RANGE (delta)
7646 && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K")))
7648 op[5] = gen_label_rtx ();
7649 output_asm_insn ("basr\t%4,0", op);
7650 targetm.asm_out.internal_label (file, "L",
7651 CODE_LABEL_NUMBER (op[5]));
7654 /* Add DELTA to this pointer. */
7655 if (delta)
7657 if (CONST_OK_FOR_CONSTRAINT_P (delta, 'J', "J"))
7658 output_asm_insn ("la\t%1,%2(%1)", op);
7659 else if (DISP_IN_RANGE (delta))
7660 output_asm_insn ("lay\t%1,%2(%1)", op);
7661 else if (CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
7662 output_asm_insn ("ahi\t%1,%2", op);
7663 else
7665 op[6] = gen_label_rtx ();
7666 output_asm_insn ("a\t%1,%6-%5(%4)", op);
7670 /* Perform vcall adjustment. */
7671 if (vcall_offset)
7673 if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'J', "J"))
7675 output_asm_insn ("lg\t%4,0(%1)", op);
7676 output_asm_insn ("a\t%1,%3(%4)", op);
7678 else if (DISP_IN_RANGE (vcall_offset))
7680 output_asm_insn ("lg\t%4,0(%1)", op);
7681 output_asm_insn ("ay\t%1,%3(%4)", op);
7683 else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K"))
7685 output_asm_insn ("lhi\t%4,%3", op);
7686 output_asm_insn ("a\t%4,0(%1)", op);
7687 output_asm_insn ("a\t%1,0(%4)", op);
7689 else
7691 op[7] = gen_label_rtx ();
7692 output_asm_insn ("l\t%4,%7-%5(%4)", op);
7693 output_asm_insn ("a\t%4,0(%1)", op);
7694 output_asm_insn ("a\t%1,0(%4)", op);
7697 /* We had to clobber the base pointer register.
7698 Re-setup the base pointer (with a different base). */
7699 op[5] = gen_label_rtx ();
7700 output_asm_insn ("basr\t%4,0", op);
7701 targetm.asm_out.internal_label (file, "L",
7702 CODE_LABEL_NUMBER (op[5]));
7705 /* Jump to target. */
7706 op[8] = gen_label_rtx ();
7708 if (!flag_pic)
7709 output_asm_insn ("l\t%4,%8-%5(%4)", op);
7710 else if (!nonlocal)
7711 output_asm_insn ("a\t%4,%8-%5(%4)", op);
7712 /* We cannot call through .plt, since .plt requires %r12 loaded. */
7713 else if (flag_pic == 1)
7715 output_asm_insn ("a\t%4,%8-%5(%4)", op);
7716 output_asm_insn ("l\t%4,%0(%4)", op);
7718 else if (flag_pic == 2)
7720 op[9] = gen_rtx_REG (Pmode, 0);
7721 output_asm_insn ("l\t%9,%8-4-%5(%4)", op);
7722 output_asm_insn ("a\t%4,%8-%5(%4)", op);
7723 output_asm_insn ("ar\t%4,%9", op);
7724 output_asm_insn ("l\t%4,0(%4)", op);
7727 output_asm_insn ("br\t%4", op);
7729 /* Output literal pool. */
7730 output_asm_insn (".align\t4", op);
7732 if (nonlocal && flag_pic == 2)
7733 output_asm_insn (".long\t%0", op);
7734 if (nonlocal)
7736 op[0] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
7737 SYMBOL_REF_FLAGS (op[0]) = SYMBOL_FLAG_LOCAL;
7740 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[8]));
7741 if (!flag_pic)
7742 output_asm_insn (".long\t%0", op);
7743 else
7744 output_asm_insn (".long\t%0-%5", op);
7746 if (op[6])
7748 targetm.asm_out.internal_label (file, "L",
7749 CODE_LABEL_NUMBER (op[6]));
7750 output_asm_insn (".long\t%2", op);
7752 if (op[7])
7754 targetm.asm_out.internal_label (file, "L",
7755 CODE_LABEL_NUMBER (op[7]));
7756 output_asm_insn (".long\t%3", op);
7761 static bool
7762 s390_valid_pointer_mode (enum machine_mode mode)
7764 return (mode == SImode || (TARGET_64BIT && mode == DImode));
7767 /* Checks whether the given ARGUMENT_LIST would use a caller
7768 saved register. This is used to decide whether sibling call
7769 optimization could be performed on the respective function
7770 call. */
7772 static bool
7773 s390_call_saved_register_used (tree argument_list)
7775 CUMULATIVE_ARGS cum;
7776 tree parameter;
7777 enum machine_mode mode;
7778 tree type;
7779 rtx parm_rtx;
7780 int reg;
7782 INIT_CUMULATIVE_ARGS (cum, NULL, NULL, 0, 0);
7784 while (argument_list)
7786 parameter = TREE_VALUE (argument_list);
7787 argument_list = TREE_CHAIN (argument_list);
7789 gcc_assert (parameter);
7791 /* For an undeclared variable passed as parameter we will get
7792 an ERROR_MARK node here. */
7793 if (TREE_CODE (parameter) == ERROR_MARK)
7794 return true;
7796 type = TREE_TYPE (parameter);
7797 gcc_assert (type);
7799 mode = TYPE_MODE (type);
7800 gcc_assert (mode);
7802 if (pass_by_reference (&cum, mode, type, true))
7804 mode = Pmode;
7805 type = build_pointer_type (type);
7808 parm_rtx = s390_function_arg (&cum, mode, type, 0);
7810 s390_function_arg_advance (&cum, mode, type, 0);
7812 if (parm_rtx && REG_P (parm_rtx))
7814 for (reg = 0;
7815 reg < HARD_REGNO_NREGS (REGNO (parm_rtx), GET_MODE (parm_rtx));
7816 reg++)
7817 if (! call_used_regs[reg + REGNO (parm_rtx)])
7818 return true;
7821 return false;
7824 /* Return true if the given call expression can be
7825 turned into a sibling call.
7826 DECL holds the declaration of the function to be called whereas
7827 EXP is the call expression itself. */
7829 static bool
7830 s390_function_ok_for_sibcall (tree decl, tree exp)
7832 /* The TPF epilogue uses register 1. */
7833 if (TARGET_TPF_PROFILING)
7834 return false;
7836 /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
7837 which would have to be restored before the sibcall. */
7838 if (!TARGET_64BIT && flag_pic && decl && TREE_PUBLIC (decl))
7839 return false;
7841 /* Register 6 on s390 is available as an argument register but unfortunately
7842 "caller saved". This makes functions needing this register for arguments
7843 not suitable for sibcalls. */
7844 if (TREE_OPERAND (exp, 1)
7845 && s390_call_saved_register_used (TREE_OPERAND (exp, 1)))
7846 return false;
7848 return true;
7851 /* Return the fixed registers used for condition codes. */
7853 static bool
7854 s390_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
7856 *p1 = CC_REGNUM;
7857 *p2 = INVALID_REGNUM;
7859 return true;
7862 /* If two condition code modes are compatible, return a condition code
7863 mode which is compatible with both. Otherwise, return
7864 VOIDmode. */
7866 static enum machine_mode
7867 s390_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
7869 if (m1 == m2)
7870 return m1;
7872 switch (m1)
7874 case CCZmode:
7875 if (m2 == CCUmode || m2 == CCTmode
7876 || m2 == CCSmode || m2 == CCSRmode || m2 == CCURmode)
7877 return m2;
7878 return VOIDmode;
7880 case CCSmode:
7881 case CCUmode:
7882 case CCTmode:
7883 case CCSRmode:
7884 case CCURmode:
7885 if (m2 == CCZmode)
7886 return m1;
7888 return VOIDmode;
7890 default:
7891 return VOIDmode;
7893 return VOIDmode;
7896 /* This function is used by the call expanders of the machine description.
7897 It emits the call insn itself together with the necessary operations
7898 to adjust the target address and returns the emitted insn.
7899 ADDR_LOCATION is the target address rtx
7900 TLS_CALL the location of the thread-local symbol
7901 RESULT_REG the register where the result of the call should be stored
7902 RETADDR_REG the register where the return address should be stored
7903 If this parameter is NULL_RTX the call is considered
7904 to be a sibling call. */
7907 s390_emit_call (rtx addr_location, rtx tls_call, rtx result_reg,
7908 rtx retaddr_reg)
7910 bool plt_call = false;
7911 rtx insn;
7912 rtx call;
7913 rtx clobber;
7914 rtvec vec;
7916 /* Direct function calls need special treatment. */
7917 if (GET_CODE (addr_location) == SYMBOL_REF)
7919 /* When calling a global routine in PIC mode, we must
7920 replace the symbol itself with the PLT stub. */
7921 if (flag_pic && !SYMBOL_REF_LOCAL_P (addr_location))
7923 addr_location = gen_rtx_UNSPEC (Pmode,
7924 gen_rtvec (1, addr_location),
7925 UNSPEC_PLT);
7926 addr_location = gen_rtx_CONST (Pmode, addr_location);
7927 plt_call = true;
7930 /* Unless we can use the bras(l) insn, force the
7931 routine address into a register. */
7932 if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
7934 if (flag_pic)
7935 addr_location = legitimize_pic_address (addr_location, 0);
7936 else
7937 addr_location = force_reg (Pmode, addr_location);
7941 /* If it is already an indirect call or the code above moved the
7942 SYMBOL_REF to somewhere else make sure the address can be found in
7943 register 1. */
7944 if (retaddr_reg == NULL_RTX
7945 && GET_CODE (addr_location) != SYMBOL_REF
7946 && !plt_call)
7948 emit_move_insn (gen_rtx_REG (Pmode, SIBCALL_REGNUM), addr_location);
7949 addr_location = gen_rtx_REG (Pmode, SIBCALL_REGNUM);
7952 addr_location = gen_rtx_MEM (QImode, addr_location);
7953 call = gen_rtx_CALL (VOIDmode, addr_location, const0_rtx);
7955 if (result_reg != NULL_RTX)
7956 call = gen_rtx_SET (VOIDmode, result_reg, call);
7958 if (retaddr_reg != NULL_RTX)
7960 clobber = gen_rtx_CLOBBER (VOIDmode, retaddr_reg);
7962 if (tls_call != NULL_RTX)
7963 vec = gen_rtvec (3, call, clobber,
7964 gen_rtx_USE (VOIDmode, tls_call));
7965 else
7966 vec = gen_rtvec (2, call, clobber);
7968 call = gen_rtx_PARALLEL (VOIDmode, vec);
7971 insn = emit_call_insn (call);
7973 /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
7974 if ((!TARGET_64BIT && plt_call) || tls_call != NULL_RTX)
7976 /* s390_function_ok_for_sibcall should
7977 have denied sibcalls in this case. */
7978 gcc_assert (retaddr_reg != NULL_RTX);
7980 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
7982 return insn;
7985 /* Implement CONDITIONAL_REGISTER_USAGE. */
7987 void
7988 s390_conditional_register_usage (void)
7990 int i;
7992 if (flag_pic)
7994 fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
7995 call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
7997 if (TARGET_CPU_ZARCH)
7999 fixed_regs[RETURN_REGNUM] = 0;
8000 call_used_regs[RETURN_REGNUM] = 0;
8002 if (TARGET_64BIT)
8004 for (i = 24; i < 32; i++)
8005 call_used_regs[i] = call_really_used_regs[i] = 0;
8007 else
8009 for (i = 18; i < 20; i++)
8010 call_used_regs[i] = call_really_used_regs[i] = 0;
8013 if (TARGET_SOFT_FLOAT)
8015 for (i = 16; i < 32; i++)
8016 call_used_regs[i] = fixed_regs[i] = 1;
8020 /* Corresponding function to eh_return expander. */
8022 static GTY(()) rtx s390_tpf_eh_return_symbol;
8023 void
8024 s390_emit_tpf_eh_return (rtx target)
8026 rtx insn, reg;
8028 if (!s390_tpf_eh_return_symbol)
8029 s390_tpf_eh_return_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tpf_eh_return");
8031 reg = gen_rtx_REG (Pmode, 2);
8033 emit_move_insn (reg, target);
8034 insn = s390_emit_call (s390_tpf_eh_return_symbol, NULL_RTX, reg,
8035 gen_rtx_REG (Pmode, RETURN_REGNUM));
8036 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
8038 emit_move_insn (EH_RETURN_HANDLER_RTX, reg);
8041 /* Rework the prologue/epilogue to avoid saving/restoring
8042 registers unnecessarily. */
8044 static void
8045 s390_optimize_prologue (void)
8047 rtx insn, new_insn, next_insn;
8049 /* Do a final recompute of the frame-related data. */
8051 s390_update_frame_layout ();
8053 /* If all special registers are in fact used, there's nothing we
8054 can do, so no point in walking the insn list. */
8056 if (cfun_frame_layout.first_save_gpr <= BASE_REGNUM
8057 && cfun_frame_layout.last_save_gpr >= BASE_REGNUM
8058 && (TARGET_CPU_ZARCH
8059 || (cfun_frame_layout.first_save_gpr <= RETURN_REGNUM
8060 && cfun_frame_layout.last_save_gpr >= RETURN_REGNUM)))
8061 return;
8063 /* Search for prologue/epilogue insns and replace them. */
8065 for (insn = get_insns (); insn; insn = next_insn)
8067 int first, last, off;
8068 rtx set, base, offset;
8070 next_insn = NEXT_INSN (insn);
8072 if (GET_CODE (insn) != INSN)
8073 continue;
8075 if (GET_CODE (PATTERN (insn)) == PARALLEL
8076 && store_multiple_operation (PATTERN (insn), VOIDmode))
8078 set = XVECEXP (PATTERN (insn), 0, 0);
8079 first = REGNO (SET_SRC (set));
8080 last = first + XVECLEN (PATTERN (insn), 0) - 1;
8081 offset = const0_rtx;
8082 base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
8083 off = INTVAL (offset);
8085 if (GET_CODE (base) != REG || off < 0)
8086 continue;
8087 if (cfun_frame_layout.first_save_gpr != -1
8088 && (cfun_frame_layout.first_save_gpr < first
8089 || cfun_frame_layout.last_save_gpr > last))
8090 continue;
8091 if (REGNO (base) != STACK_POINTER_REGNUM
8092 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
8093 continue;
8094 if (first > BASE_REGNUM || last < BASE_REGNUM)
8095 continue;
8097 if (cfun_frame_layout.first_save_gpr != -1)
8099 new_insn = save_gprs (base,
8100 off + (cfun_frame_layout.first_save_gpr
8101 - first) * UNITS_PER_WORD,
8102 cfun_frame_layout.first_save_gpr,
8103 cfun_frame_layout.last_save_gpr);
8104 new_insn = emit_insn_before (new_insn, insn);
8105 INSN_ADDRESSES_NEW (new_insn, -1);
8108 remove_insn (insn);
8109 continue;
8112 if (cfun_frame_layout.first_save_gpr == -1
8113 && GET_CODE (PATTERN (insn)) == SET
8114 && GET_CODE (SET_SRC (PATTERN (insn))) == REG
8115 && (REGNO (SET_SRC (PATTERN (insn))) == BASE_REGNUM
8116 || (!TARGET_CPU_ZARCH
8117 && REGNO (SET_SRC (PATTERN (insn))) == RETURN_REGNUM))
8118 && GET_CODE (SET_DEST (PATTERN (insn))) == MEM)
8120 set = PATTERN (insn);
8121 first = REGNO (SET_SRC (set));
8122 offset = const0_rtx;
8123 base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
8124 off = INTVAL (offset);
8126 if (GET_CODE (base) != REG || off < 0)
8127 continue;
8128 if (REGNO (base) != STACK_POINTER_REGNUM
8129 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
8130 continue;
8132 remove_insn (insn);
8133 continue;
8136 if (GET_CODE (PATTERN (insn)) == PARALLEL
8137 && load_multiple_operation (PATTERN (insn), VOIDmode))
8139 set = XVECEXP (PATTERN (insn), 0, 0);
8140 first = REGNO (SET_DEST (set));
8141 last = first + XVECLEN (PATTERN (insn), 0) - 1;
8142 offset = const0_rtx;
8143 base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
8144 off = INTVAL (offset);
8146 if (GET_CODE (base) != REG || off < 0)
8147 continue;
8148 if (cfun_frame_layout.first_restore_gpr != -1
8149 && (cfun_frame_layout.first_restore_gpr < first
8150 || cfun_frame_layout.last_restore_gpr > last))
8151 continue;
8152 if (REGNO (base) != STACK_POINTER_REGNUM
8153 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
8154 continue;
8155 if (first > BASE_REGNUM || last < BASE_REGNUM)
8156 continue;
8158 if (cfun_frame_layout.first_restore_gpr != -1)
8160 new_insn = restore_gprs (base,
8161 off + (cfun_frame_layout.first_restore_gpr
8162 - first) * UNITS_PER_WORD,
8163 cfun_frame_layout.first_restore_gpr,
8164 cfun_frame_layout.last_restore_gpr);
8165 new_insn = emit_insn_before (new_insn, insn);
8166 INSN_ADDRESSES_NEW (new_insn, -1);
8169 remove_insn (insn);
8170 continue;
8173 if (cfun_frame_layout.first_restore_gpr == -1
8174 && GET_CODE (PATTERN (insn)) == SET
8175 && GET_CODE (SET_DEST (PATTERN (insn))) == REG
8176 && (REGNO (SET_DEST (PATTERN (insn))) == BASE_REGNUM
8177 || (!TARGET_CPU_ZARCH
8178 && REGNO (SET_DEST (PATTERN (insn))) == RETURN_REGNUM))
8179 && GET_CODE (SET_SRC (PATTERN (insn))) == MEM)
8181 set = PATTERN (insn);
8182 first = REGNO (SET_DEST (set));
8183 offset = const0_rtx;
8184 base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
8185 off = INTVAL (offset);
8187 if (GET_CODE (base) != REG || off < 0)
8188 continue;
8189 if (REGNO (base) != STACK_POINTER_REGNUM
8190 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
8191 continue;
8193 remove_insn (insn);
8194 continue;
8199 /* Perform machine-dependent processing. */
8201 static void
8202 s390_reorg (void)
8204 bool pool_overflow = false;
8206 /* Make sure all splits have been performed; splits after
8207 machine_dependent_reorg might confuse insn length counts. */
8208 split_all_insns_noflow ();
8211 /* Install the main literal pool and the associated base
8212 register load insns.
8214 In addition, there are two problematic situations we need
8215 to correct:
8217 - the literal pool might be > 4096 bytes in size, so that
8218 some of its elements cannot be directly accessed
8220 - a branch target might be > 64K away from the branch, so that
8221 it is not possible to use a PC-relative instruction.
8223 To fix those, we split the single literal pool into multiple
8224 pool chunks, reloading the pool base register at various
8225 points throughout the function to ensure it always points to
8226 the pool chunk the following code expects, and / or replace
8227 PC-relative branches by absolute branches.
8229 However, the two problems are interdependent: splitting the
8230 literal pool can move a branch further away from its target,
8231 causing the 64K limit to overflow, and on the other hand,
8232 replacing a PC-relative branch by an absolute branch means
8233 we need to put the branch target address into the literal
8234 pool, possibly causing it to overflow.
8236 So, we loop trying to fix up both problems until we manage
8237 to satisfy both conditions at the same time. Note that the
8238 loop is guaranteed to terminate as every pass of the loop
8239 strictly decreases the total number of PC-relative branches
8240 in the function. (This is not completely true as there
8241 might be branch-over-pool insns introduced by chunkify_start.
8242 Those never need to be split however.) */
8244 for (;;)
8246 struct constant_pool *pool = NULL;
8248 /* Collect the literal pool. */
8249 if (!pool_overflow)
8251 pool = s390_mainpool_start ();
8252 if (!pool)
8253 pool_overflow = true;
8256 /* If literal pool overflowed, start to chunkify it. */
8257 if (pool_overflow)
8258 pool = s390_chunkify_start ();
8260 /* Split out-of-range branches. If this has created new
8261 literal pool entries, cancel current chunk list and
8262 recompute it. zSeries machines have large branch
8263 instructions, so we never need to split a branch. */
8264 if (!TARGET_CPU_ZARCH && s390_split_branches ())
8266 if (pool_overflow)
8267 s390_chunkify_cancel (pool);
8268 else
8269 s390_mainpool_cancel (pool);
8271 continue;
8274 /* If we made it up to here, both conditions are satisfied.
8275 Finish up literal pool related changes. */
8276 if (pool_overflow)
8277 s390_chunkify_finish (pool);
8278 else
8279 s390_mainpool_finish (pool);
8281 /* We're done splitting branches. */
8282 cfun->machine->split_branches_pending_p = false;
8283 break;
8286 /* Generate out-of-pool execute target insns. */
8287 if (TARGET_CPU_ZARCH)
8289 rtx insn, label, target;
8291 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8293 label = s390_execute_label (insn);
8294 if (!label)
8295 continue;
8297 gcc_assert (label != const0_rtx);
8299 target = emit_label (XEXP (label, 0));
8300 INSN_ADDRESSES_NEW (target, -1);
8302 target = emit_insn (s390_execute_target (insn));
8303 INSN_ADDRESSES_NEW (target, -1);
8307 /* Try to optimize prologue and epilogue further. */
8308 s390_optimize_prologue ();
8312 /* Initialize GCC target structure. */
8314 #undef TARGET_ASM_ALIGNED_HI_OP
8315 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
8316 #undef TARGET_ASM_ALIGNED_DI_OP
8317 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
8318 #undef TARGET_ASM_INTEGER
8319 #define TARGET_ASM_INTEGER s390_assemble_integer
8321 #undef TARGET_ASM_OPEN_PAREN
8322 #define TARGET_ASM_OPEN_PAREN ""
8324 #undef TARGET_ASM_CLOSE_PAREN
8325 #define TARGET_ASM_CLOSE_PAREN ""
8327 #undef TARGET_DEFAULT_TARGET_FLAGS
8328 #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD)
8329 #undef TARGET_HANDLE_OPTION
8330 #define TARGET_HANDLE_OPTION s390_handle_option
8332 #undef TARGET_ENCODE_SECTION_INFO
8333 #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
8335 #ifdef HAVE_AS_TLS
8336 #undef TARGET_HAVE_TLS
8337 #define TARGET_HAVE_TLS true
8338 #endif
8339 #undef TARGET_CANNOT_FORCE_CONST_MEM
8340 #define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
8342 #undef TARGET_DELEGITIMIZE_ADDRESS
8343 #define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
8345 #undef TARGET_RETURN_IN_MEMORY
8346 #define TARGET_RETURN_IN_MEMORY s390_return_in_memory
8348 #undef TARGET_INIT_BUILTINS
8349 #define TARGET_INIT_BUILTINS s390_init_builtins
8350 #undef TARGET_EXPAND_BUILTIN
8351 #define TARGET_EXPAND_BUILTIN s390_expand_builtin
8353 #undef TARGET_ASM_OUTPUT_MI_THUNK
8354 #define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
8355 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
8356 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
8358 #undef TARGET_SCHED_ADJUST_PRIORITY
8359 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
8360 #undef TARGET_SCHED_ISSUE_RATE
8361 #define TARGET_SCHED_ISSUE_RATE s390_issue_rate
8362 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
8363 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
8365 #undef TARGET_CANNOT_COPY_INSN_P
8366 #define TARGET_CANNOT_COPY_INSN_P s390_cannot_copy_insn_p
8367 #undef TARGET_RTX_COSTS
8368 #define TARGET_RTX_COSTS s390_rtx_costs
8369 #undef TARGET_ADDRESS_COST
8370 #define TARGET_ADDRESS_COST s390_address_cost
8372 #undef TARGET_MACHINE_DEPENDENT_REORG
8373 #define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
8375 #undef TARGET_VALID_POINTER_MODE
8376 #define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
8378 #undef TARGET_BUILD_BUILTIN_VA_LIST
8379 #define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
8380 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
8381 #define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg
8383 #undef TARGET_PROMOTE_FUNCTION_ARGS
8384 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
8385 #undef TARGET_PROMOTE_FUNCTION_RETURN
8386 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
8387 #undef TARGET_PASS_BY_REFERENCE
8388 #define TARGET_PASS_BY_REFERENCE s390_pass_by_reference
8390 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
8391 #define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
8393 #undef TARGET_FIXED_CONDITION_CODE_REGS
8394 #define TARGET_FIXED_CONDITION_CODE_REGS s390_fixed_condition_code_regs
8396 #undef TARGET_CC_MODES_COMPATIBLE
8397 #define TARGET_CC_MODES_COMPATIBLE s390_cc_modes_compatible
8399 #undef TARGET_INVALID_WITHIN_DOLOOP
8400 #define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_rtx_null
8402 #ifdef HAVE_AS_TLS
8403 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
8404 #define TARGET_ASM_OUTPUT_DWARF_DTPREL s390_output_dwarf_dtprel
8405 #endif
8407 struct gcc_target targetm = TARGET_INITIALIZER;
8409 #include "gt-s390.h"