* Merge from mainline
[official-gcc.git] / gcc / config / s390 / s390.c
blobb495d6829fbe2b59ae682d44ca9c53f2ddb19c31
1 /* Subroutines used for code generation on IBM S/390 and zSeries
2 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
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 const int mxbr;
75 /* square root */
76 const int sqxbr; /* cost of square root in TFmode. */
77 const int sqdbr; /* cost of square root in DFmode. */
78 const int sqebr; /* cost of square root in SFmode. */
79 /* multiply and add */
80 const int madbr; /* cost of multiply and add in DFmode. */
81 const int maebr; /* cost of multiply and add in SFmode. */
82 /* division */
83 const int dxbr;
84 const int dxr;
85 const int ddbr;
86 const int ddr;
87 const int debr;
88 const int der;
89 const int dlgr;
90 const int dlr;
91 const int dr;
92 const int dsgfr;
93 const int dsgr;
96 const struct processor_costs *s390_cost;
98 static const
99 struct processor_costs z900_cost =
101 COSTS_N_INSNS (5), /* M */
102 COSTS_N_INSNS (10), /* MGHI */
103 COSTS_N_INSNS (5), /* MH */
104 COSTS_N_INSNS (4), /* MHI */
105 COSTS_N_INSNS (5), /* ML */
106 COSTS_N_INSNS (5), /* MR */
107 COSTS_N_INSNS (4), /* MS */
108 COSTS_N_INSNS (15), /* MSG */
109 COSTS_N_INSNS (7), /* MSGF */
110 COSTS_N_INSNS (7), /* MSGFR */
111 COSTS_N_INSNS (10), /* MSGR */
112 COSTS_N_INSNS (4), /* MSR */
113 COSTS_N_INSNS (7), /* multiplication in DFmode */
114 COSTS_N_INSNS (13), /* MXBR */
115 COSTS_N_INSNS (136), /* SQXBR */
116 COSTS_N_INSNS (44), /* SQDBR */
117 COSTS_N_INSNS (35), /* SQEBR */
118 COSTS_N_INSNS (18), /* MADBR */
119 COSTS_N_INSNS (13), /* MAEBR */
120 COSTS_N_INSNS (134), /* DXBR */
121 COSTS_N_INSNS (135), /* DXR */
122 COSTS_N_INSNS (30), /* DDBR */
123 COSTS_N_INSNS (30), /* DDR */
124 COSTS_N_INSNS (27), /* DEBR */
125 COSTS_N_INSNS (26), /* DER */
126 COSTS_N_INSNS (220), /* DLGR */
127 COSTS_N_INSNS (34), /* DLR */
128 COSTS_N_INSNS (34), /* DR */
129 COSTS_N_INSNS (32), /* DSGFR */
130 COSTS_N_INSNS (32), /* DSGR */
133 static const
134 struct processor_costs z990_cost =
136 COSTS_N_INSNS (4), /* M */
137 COSTS_N_INSNS (2), /* MGHI */
138 COSTS_N_INSNS (2), /* MH */
139 COSTS_N_INSNS (2), /* MHI */
140 COSTS_N_INSNS (4), /* ML */
141 COSTS_N_INSNS (4), /* MR */
142 COSTS_N_INSNS (5), /* MS */
143 COSTS_N_INSNS (6), /* MSG */
144 COSTS_N_INSNS (4), /* MSGF */
145 COSTS_N_INSNS (4), /* MSGFR */
146 COSTS_N_INSNS (4), /* MSGR */
147 COSTS_N_INSNS (4), /* MSR */
148 COSTS_N_INSNS (1), /* multiplication in DFmode */
149 COSTS_N_INSNS (28), /* MXBR */
150 COSTS_N_INSNS (130), /* SQXBR */
151 COSTS_N_INSNS (66), /* SQDBR */
152 COSTS_N_INSNS (38), /* SQEBR */
153 COSTS_N_INSNS (1), /* MADBR */
154 COSTS_N_INSNS (1), /* MAEBR */
155 COSTS_N_INSNS (60), /* DXBR */
156 COSTS_N_INSNS (72), /* DXR */
157 COSTS_N_INSNS (40), /* DDBR */
158 COSTS_N_INSNS (44), /* DDR */
159 COSTS_N_INSNS (26), /* DDBR */
160 COSTS_N_INSNS (28), /* DER */
161 COSTS_N_INSNS (176), /* DLGR */
162 COSTS_N_INSNS (31), /* DLR */
163 COSTS_N_INSNS (31), /* DR */
164 COSTS_N_INSNS (31), /* DSGFR */
165 COSTS_N_INSNS (31), /* DSGR */
168 static const
169 struct processor_costs z9_109_cost =
171 COSTS_N_INSNS (4), /* M */
172 COSTS_N_INSNS (2), /* MGHI */
173 COSTS_N_INSNS (2), /* MH */
174 COSTS_N_INSNS (2), /* MHI */
175 COSTS_N_INSNS (4), /* ML */
176 COSTS_N_INSNS (4), /* MR */
177 COSTS_N_INSNS (5), /* MS */
178 COSTS_N_INSNS (6), /* MSG */
179 COSTS_N_INSNS (4), /* MSGF */
180 COSTS_N_INSNS (4), /* MSGFR */
181 COSTS_N_INSNS (4), /* MSGR */
182 COSTS_N_INSNS (4), /* MSR */
183 COSTS_N_INSNS (1), /* multiplication in DFmode */
184 COSTS_N_INSNS (28), /* MXBR */
185 COSTS_N_INSNS (130), /* SQXBR */
186 COSTS_N_INSNS (66), /* SQDBR */
187 COSTS_N_INSNS (38), /* SQEBR */
188 COSTS_N_INSNS (1), /* MADBR */
189 COSTS_N_INSNS (1), /* MAEBR */
190 COSTS_N_INSNS (60), /* DXBR */
191 COSTS_N_INSNS (72), /* DXR */
192 COSTS_N_INSNS (40), /* DDBR */
193 COSTS_N_INSNS (37), /* DDR */
194 COSTS_N_INSNS (26), /* DDBR */
195 COSTS_N_INSNS (28), /* DER */
196 COSTS_N_INSNS (30), /* DLGR */
197 COSTS_N_INSNS (23), /* DLR */
198 COSTS_N_INSNS (23), /* DR */
199 COSTS_N_INSNS (24), /* DSGFR */
200 COSTS_N_INSNS (24), /* DSGR */
203 extern int reload_completed;
205 /* Save information from a "cmpxx" operation until the branch or scc is
206 emitted. */
207 rtx s390_compare_op0, s390_compare_op1;
209 /* Save the result of a compare_and_swap until the branch or scc is
210 emitted. */
211 rtx s390_compare_emitted = NULL_RTX;
213 /* Structure used to hold the components of a S/390 memory
214 address. A legitimate address on S/390 is of the general
215 form
216 base + index + displacement
217 where any of the components is optional.
219 base and index are registers of the class ADDR_REGS,
220 displacement is an unsigned 12-bit immediate constant. */
222 struct s390_address
224 rtx base;
225 rtx indx;
226 rtx disp;
227 bool pointer;
228 bool literal_pool;
231 /* Which cpu are we tuning for. */
232 enum processor_type s390_tune = PROCESSOR_max;
233 enum processor_flags s390_tune_flags;
234 /* Which instruction set architecture to use. */
235 enum processor_type s390_arch;
236 enum processor_flags s390_arch_flags;
238 HOST_WIDE_INT s390_warn_framesize = 0;
239 HOST_WIDE_INT s390_stack_size = 0;
240 HOST_WIDE_INT s390_stack_guard = 0;
242 /* The following structure is embedded in the machine
243 specific part of struct function. */
245 struct s390_frame_layout GTY (())
247 /* Offset within stack frame. */
248 HOST_WIDE_INT gprs_offset;
249 HOST_WIDE_INT f0_offset;
250 HOST_WIDE_INT f4_offset;
251 HOST_WIDE_INT f8_offset;
252 HOST_WIDE_INT backchain_offset;
254 /* Number of first and last gpr where slots in the register
255 save area are reserved for. */
256 int first_save_gpr_slot;
257 int last_save_gpr_slot;
259 /* Number of first and last gpr to be saved, restored. */
260 int first_save_gpr;
261 int first_restore_gpr;
262 int last_save_gpr;
263 int last_restore_gpr;
265 /* Bits standing for floating point registers. Set, if the
266 respective register has to be saved. Starting with reg 16 (f0)
267 at the rightmost bit.
268 Bit 15 - 8 7 6 5 4 3 2 1 0
269 fpr 15 - 8 7 5 3 1 6 4 2 0
270 reg 31 - 24 23 22 21 20 19 18 17 16 */
271 unsigned int fpr_bitmap;
273 /* Number of floating point registers f8-f15 which must be saved. */
274 int high_fprs;
276 /* Set if return address needs to be saved.
277 This flag is set by s390_return_addr_rtx if it could not use
278 the initial value of r14 and therefore depends on r14 saved
279 to the stack. */
280 bool save_return_addr_p;
282 /* Size of stack frame. */
283 HOST_WIDE_INT frame_size;
286 /* Define the structure for the machine field in struct function. */
288 struct machine_function GTY(())
290 struct s390_frame_layout frame_layout;
292 /* Literal pool base register. */
293 rtx base_reg;
295 /* True if we may need to perform branch splitting. */
296 bool split_branches_pending_p;
298 /* True during final stage of literal pool processing. */
299 bool decomposed_literal_pool_addresses_ok_p;
301 /* Some local-dynamic TLS symbol name. */
302 const char *some_ld_name;
304 bool has_landing_pad_p;
307 /* Few accessor macros for struct cfun->machine->s390_frame_layout. */
309 #define cfun_frame_layout (cfun->machine->frame_layout)
310 #define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)
311 #define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr_slot - \
312 cfun_frame_layout.first_save_gpr_slot + 1) * UNITS_PER_WORD)
313 #define cfun_set_fpr_bit(BITNUM) (cfun->machine->frame_layout.fpr_bitmap |= \
314 (1 << (BITNUM)))
315 #define cfun_fpr_bit_p(BITNUM) (!!(cfun->machine->frame_layout.fpr_bitmap & \
316 (1 << (BITNUM))))
318 /* Number of GPRs and FPRs used for argument passing. */
319 #define GP_ARG_NUM_REG 5
320 #define FP_ARG_NUM_REG (TARGET_64BIT? 4 : 2)
322 /* A couple of shortcuts. */
323 #define CONST_OK_FOR_J(x) \
324 CONST_OK_FOR_CONSTRAINT_P((x), 'J', "J")
325 #define CONST_OK_FOR_K(x) \
326 CONST_OK_FOR_CONSTRAINT_P((x), 'K', "K")
327 #define CONST_OK_FOR_Os(x) \
328 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Os")
329 #define CONST_OK_FOR_Op(x) \
330 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Op")
331 #define CONST_OK_FOR_On(x) \
332 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "On")
334 #define REGNO_PAIR_OK(REGNO, MODE) \
335 (HARD_REGNO_NREGS ((REGNO), (MODE)) == 1 || !((REGNO) & 1))
337 /* Return true if the back end supports mode MODE. */
338 static bool
339 s390_scalar_mode_supported_p (enum machine_mode mode)
341 if (DECIMAL_FLOAT_MODE_P (mode))
342 return true;
343 else
344 return default_scalar_mode_supported_p (mode);
347 /* Set the has_landing_pad_p flag in struct machine_function to VALUE. */
349 void
350 s390_set_has_landing_pad_p (bool value)
352 cfun->machine->has_landing_pad_p = value;
355 /* If two condition code modes are compatible, return a condition code
356 mode which is compatible with both. Otherwise, return
357 VOIDmode. */
359 static enum machine_mode
360 s390_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
362 if (m1 == m2)
363 return m1;
365 switch (m1)
367 case CCZmode:
368 if (m2 == CCUmode || m2 == CCTmode || m2 == CCZ1mode
369 || m2 == CCSmode || m2 == CCSRmode || m2 == CCURmode)
370 return m2;
371 return VOIDmode;
373 case CCSmode:
374 case CCUmode:
375 case CCTmode:
376 case CCSRmode:
377 case CCURmode:
378 case CCZ1mode:
379 if (m2 == CCZmode)
380 return m1;
382 return VOIDmode;
384 default:
385 return VOIDmode;
387 return VOIDmode;
390 /* Return true if SET either doesn't set the CC register, or else
391 the source and destination have matching CC modes and that
392 CC mode is at least as constrained as REQ_MODE. */
394 static bool
395 s390_match_ccmode_set (rtx set, enum machine_mode req_mode)
397 enum machine_mode set_mode;
399 gcc_assert (GET_CODE (set) == SET);
401 if (GET_CODE (SET_DEST (set)) != REG || !CC_REGNO_P (REGNO (SET_DEST (set))))
402 return 1;
404 set_mode = GET_MODE (SET_DEST (set));
405 switch (set_mode)
407 case CCSmode:
408 case CCSRmode:
409 case CCUmode:
410 case CCURmode:
411 case CCLmode:
412 case CCL1mode:
413 case CCL2mode:
414 case CCL3mode:
415 case CCT1mode:
416 case CCT2mode:
417 case CCT3mode:
418 if (req_mode != set_mode)
419 return 0;
420 break;
422 case CCZmode:
423 if (req_mode != CCSmode && req_mode != CCUmode && req_mode != CCTmode
424 && req_mode != CCSRmode && req_mode != CCURmode)
425 return 0;
426 break;
428 case CCAPmode:
429 case CCANmode:
430 if (req_mode != CCAmode)
431 return 0;
432 break;
434 default:
435 gcc_unreachable ();
438 return (GET_MODE (SET_SRC (set)) == set_mode);
441 /* Return true if every SET in INSN that sets the CC register
442 has source and destination with matching CC modes and that
443 CC mode is at least as constrained as REQ_MODE.
444 If REQ_MODE is VOIDmode, always return false. */
446 bool
447 s390_match_ccmode (rtx insn, enum machine_mode req_mode)
449 int i;
451 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
452 if (req_mode == VOIDmode)
453 return false;
455 if (GET_CODE (PATTERN (insn)) == SET)
456 return s390_match_ccmode_set (PATTERN (insn), req_mode);
458 if (GET_CODE (PATTERN (insn)) == PARALLEL)
459 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
461 rtx set = XVECEXP (PATTERN (insn), 0, i);
462 if (GET_CODE (set) == SET)
463 if (!s390_match_ccmode_set (set, req_mode))
464 return false;
467 return true;
470 /* If a test-under-mask instruction can be used to implement
471 (compare (and ... OP1) OP2), return the CC mode required
472 to do that. Otherwise, return VOIDmode.
473 MIXED is true if the instruction can distinguish between
474 CC1 and CC2 for mixed selected bits (TMxx), it is false
475 if the instruction cannot (TM). */
477 enum machine_mode
478 s390_tm_ccmode (rtx op1, rtx op2, bool mixed)
480 int bit0, bit1;
482 /* ??? Fixme: should work on CONST_DOUBLE as well. */
483 if (GET_CODE (op1) != CONST_INT || GET_CODE (op2) != CONST_INT)
484 return VOIDmode;
486 /* Selected bits all zero: CC0.
487 e.g.: int a; if ((a & (16 + 128)) == 0) */
488 if (INTVAL (op2) == 0)
489 return CCTmode;
491 /* Selected bits all one: CC3.
492 e.g.: int a; if ((a & (16 + 128)) == 16 + 128) */
493 if (INTVAL (op2) == INTVAL (op1))
494 return CCT3mode;
496 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. e.g.:
497 int a;
498 if ((a & (16 + 128)) == 16) -> CCT1
499 if ((a & (16 + 128)) == 128) -> CCT2 */
500 if (mixed)
502 bit1 = exact_log2 (INTVAL (op2));
503 bit0 = exact_log2 (INTVAL (op1) ^ INTVAL (op2));
504 if (bit0 != -1 && bit1 != -1)
505 return bit0 > bit1 ? CCT1mode : CCT2mode;
508 return VOIDmode;
511 /* Given a comparison code OP (EQ, NE, etc.) and the operands
512 OP0 and OP1 of a COMPARE, return the mode to be used for the
513 comparison. */
515 enum machine_mode
516 s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
518 switch (code)
520 case EQ:
521 case NE:
522 if ((GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
523 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
524 return CCAPmode;
525 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
526 && CONST_OK_FOR_K (INTVAL (XEXP (op0, 1))))
527 return CCAPmode;
528 if ((GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
529 || GET_CODE (op1) == NEG)
530 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
531 return CCLmode;
533 if (GET_CODE (op0) == AND)
535 /* Check whether we can potentially do it via TM. */
536 enum machine_mode ccmode;
537 ccmode = s390_tm_ccmode (XEXP (op0, 1), op1, 1);
538 if (ccmode != VOIDmode)
540 /* Relax CCTmode to CCZmode to allow fall-back to AND
541 if that turns out to be beneficial. */
542 return ccmode == CCTmode ? CCZmode : ccmode;
546 if (register_operand (op0, HImode)
547 && GET_CODE (op1) == CONST_INT
548 && (INTVAL (op1) == -1 || INTVAL (op1) == 65535))
549 return CCT3mode;
550 if (register_operand (op0, QImode)
551 && GET_CODE (op1) == CONST_INT
552 && (INTVAL (op1) == -1 || INTVAL (op1) == 255))
553 return CCT3mode;
555 return CCZmode;
557 case LE:
558 case LT:
559 case GE:
560 case GT:
561 /* The only overflow condition of NEG and ABS happens when
562 -INT_MAX is used as parameter, which stays negative. So
563 we have an overflow from a positive value to a negative.
564 Using CCAP mode the resulting cc can be used for comparisons. */
565 if ((GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
566 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
567 return CCAPmode;
569 /* If constants are involved in an add instruction it is possible to use
570 the resulting cc for comparisons with zero. Knowing the sign of the
571 constant the overflow behavior gets predictable. e.g.:
572 int a, b; if ((b = a + c) > 0)
573 with c as a constant value: c < 0 -> CCAN and c >= 0 -> CCAP */
574 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
575 && CONST_OK_FOR_K (INTVAL (XEXP (op0, 1))))
577 if (INTVAL (XEXP((op0), 1)) < 0)
578 return CCANmode;
579 else
580 return CCAPmode;
582 /* Fall through. */
583 case UNORDERED:
584 case ORDERED:
585 case UNEQ:
586 case UNLE:
587 case UNLT:
588 case UNGE:
589 case UNGT:
590 case LTGT:
591 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
592 && GET_CODE (op1) != CONST_INT)
593 return CCSRmode;
594 return CCSmode;
596 case LTU:
597 case GEU:
598 if (GET_CODE (op0) == PLUS
599 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
600 return CCL1mode;
602 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
603 && GET_CODE (op1) != CONST_INT)
604 return CCURmode;
605 return CCUmode;
607 case LEU:
608 case GTU:
609 if (GET_CODE (op0) == MINUS
610 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
611 return CCL2mode;
613 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
614 && GET_CODE (op1) != CONST_INT)
615 return CCURmode;
616 return CCUmode;
618 default:
619 gcc_unreachable ();
623 /* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
624 that we can implement more efficiently. */
626 void
627 s390_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
629 /* Convert ZERO_EXTRACT back to AND to enable TM patterns. */
630 if ((*code == EQ || *code == NE)
631 && *op1 == const0_rtx
632 && GET_CODE (*op0) == ZERO_EXTRACT
633 && GET_CODE (XEXP (*op0, 1)) == CONST_INT
634 && GET_CODE (XEXP (*op0, 2)) == CONST_INT
635 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0, 0))))
637 rtx inner = XEXP (*op0, 0);
638 HOST_WIDE_INT modesize = GET_MODE_BITSIZE (GET_MODE (inner));
639 HOST_WIDE_INT len = INTVAL (XEXP (*op0, 1));
640 HOST_WIDE_INT pos = INTVAL (XEXP (*op0, 2));
642 if (len > 0 && len < modesize
643 && pos >= 0 && pos + len <= modesize
644 && modesize <= HOST_BITS_PER_WIDE_INT)
646 unsigned HOST_WIDE_INT block;
647 block = ((unsigned HOST_WIDE_INT) 1 << len) - 1;
648 block <<= modesize - pos - len;
650 *op0 = gen_rtx_AND (GET_MODE (inner), inner,
651 gen_int_mode (block, GET_MODE (inner)));
655 /* Narrow AND of memory against immediate to enable TM. */
656 if ((*code == EQ || *code == NE)
657 && *op1 == const0_rtx
658 && GET_CODE (*op0) == AND
659 && GET_CODE (XEXP (*op0, 1)) == CONST_INT
660 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0, 0))))
662 rtx inner = XEXP (*op0, 0);
663 rtx mask = XEXP (*op0, 1);
665 /* Ignore paradoxical SUBREGs if all extra bits are masked out. */
666 if (GET_CODE (inner) == SUBREG
667 && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (inner)))
668 && (GET_MODE_SIZE (GET_MODE (inner))
669 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner))))
670 && ((INTVAL (mask)
671 & GET_MODE_MASK (GET_MODE (inner))
672 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (inner))))
673 == 0))
674 inner = SUBREG_REG (inner);
676 /* Do not change volatile MEMs. */
677 if (MEM_P (inner) && !MEM_VOLATILE_P (inner))
679 int part = s390_single_part (XEXP (*op0, 1),
680 GET_MODE (inner), QImode, 0);
681 if (part >= 0)
683 mask = gen_int_mode (s390_extract_part (mask, QImode, 0), QImode);
684 inner = adjust_address_nv (inner, QImode, part);
685 *op0 = gen_rtx_AND (QImode, inner, mask);
690 /* Narrow comparisons against 0xffff to HImode if possible. */
691 if ((*code == EQ || *code == NE)
692 && GET_CODE (*op1) == CONST_INT
693 && INTVAL (*op1) == 0xffff
694 && SCALAR_INT_MODE_P (GET_MODE (*op0))
695 && (nonzero_bits (*op0, GET_MODE (*op0))
696 & ~(unsigned HOST_WIDE_INT) 0xffff) == 0)
698 *op0 = gen_lowpart (HImode, *op0);
699 *op1 = constm1_rtx;
703 /* Remove redundant UNSPEC_CMPINT conversions if possible. */
704 if (GET_CODE (*op0) == UNSPEC
705 && XINT (*op0, 1) == UNSPEC_CMPINT
706 && XVECLEN (*op0, 0) == 1
707 && GET_MODE (XVECEXP (*op0, 0, 0)) == CCUmode
708 && GET_CODE (XVECEXP (*op0, 0, 0)) == REG
709 && REGNO (XVECEXP (*op0, 0, 0)) == CC_REGNUM
710 && *op1 == const0_rtx)
712 enum rtx_code new_code = UNKNOWN;
713 switch (*code)
715 case EQ: new_code = EQ; break;
716 case NE: new_code = NE; break;
717 case LT: new_code = GTU; break;
718 case GT: new_code = LTU; break;
719 case LE: new_code = GEU; break;
720 case GE: new_code = LEU; break;
721 default: break;
724 if (new_code != UNKNOWN)
726 *op0 = XVECEXP (*op0, 0, 0);
727 *code = new_code;
731 /* Simplify cascaded EQ, NE with const0_rtx. */
732 if ((*code == NE || *code == EQ)
733 && (GET_CODE (*op0) == EQ || GET_CODE (*op0) == NE)
734 && GET_MODE (*op0) == SImode
735 && GET_MODE (XEXP (*op0, 0)) == CCZ1mode
736 && REG_P (XEXP (*op0, 0))
737 && XEXP (*op0, 1) == const0_rtx
738 && *op1 == const0_rtx)
740 if ((*code == EQ && GET_CODE (*op0) == NE)
741 || (*code == NE && GET_CODE (*op0) == EQ))
742 *code = EQ;
743 else
744 *code = NE;
745 *op0 = XEXP (*op0, 0);
748 /* Prefer register over memory as first operand. */
749 if (MEM_P (*op0) && REG_P (*op1))
751 rtx tem = *op0; *op0 = *op1; *op1 = tem;
752 *code = swap_condition (*code);
756 /* Emit a compare instruction suitable to implement the comparison
757 OP0 CODE OP1. Return the correct condition RTL to be placed in
758 the IF_THEN_ELSE of the conditional branch testing the result. */
761 s390_emit_compare (enum rtx_code code, rtx op0, rtx op1)
763 enum machine_mode mode = s390_select_ccmode (code, op0, op1);
764 rtx ret = NULL_RTX;
766 /* Do not output a redundant compare instruction if a compare_and_swap
767 pattern already computed the result and the machine modes are compatible. */
768 if (s390_compare_emitted
769 && (s390_cc_modes_compatible (GET_MODE (s390_compare_emitted), mode)
770 == GET_MODE (s390_compare_emitted)))
771 ret = gen_rtx_fmt_ee (code, VOIDmode, s390_compare_emitted, const0_rtx);
772 else
774 rtx cc = gen_rtx_REG (mode, CC_REGNUM);
776 emit_insn (gen_rtx_SET (VOIDmode, cc, gen_rtx_COMPARE (mode, op0, op1)));
777 ret = gen_rtx_fmt_ee (code, VOIDmode, cc, const0_rtx);
779 s390_compare_emitted = NULL_RTX;
780 return ret;
783 /* Emit a jump instruction to TARGET. If COND is NULL_RTX, emit an
784 unconditional jump, else a conditional jump under condition COND. */
786 void
787 s390_emit_jump (rtx target, rtx cond)
789 rtx insn;
791 target = gen_rtx_LABEL_REF (VOIDmode, target);
792 if (cond)
793 target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, target, pc_rtx);
795 insn = gen_rtx_SET (VOIDmode, pc_rtx, target);
796 emit_jump_insn (insn);
799 /* Return branch condition mask to implement a branch
800 specified by CODE. Return -1 for invalid comparisons. */
803 s390_branch_condition_mask (rtx code)
805 const int CC0 = 1 << 3;
806 const int CC1 = 1 << 2;
807 const int CC2 = 1 << 1;
808 const int CC3 = 1 << 0;
810 gcc_assert (GET_CODE (XEXP (code, 0)) == REG);
811 gcc_assert (REGNO (XEXP (code, 0)) == CC_REGNUM);
812 gcc_assert (XEXP (code, 1) == const0_rtx);
814 switch (GET_MODE (XEXP (code, 0)))
816 case CCZmode:
817 case CCZ1mode:
818 switch (GET_CODE (code))
820 case EQ: return CC0;
821 case NE: return CC1 | CC2 | CC3;
822 default: return -1;
824 break;
826 case CCT1mode:
827 switch (GET_CODE (code))
829 case EQ: return CC1;
830 case NE: return CC0 | CC2 | CC3;
831 default: return -1;
833 break;
835 case CCT2mode:
836 switch (GET_CODE (code))
838 case EQ: return CC2;
839 case NE: return CC0 | CC1 | CC3;
840 default: return -1;
842 break;
844 case CCT3mode:
845 switch (GET_CODE (code))
847 case EQ: return CC3;
848 case NE: return CC0 | CC1 | CC2;
849 default: return -1;
851 break;
853 case CCLmode:
854 switch (GET_CODE (code))
856 case EQ: return CC0 | CC2;
857 case NE: return CC1 | CC3;
858 default: return -1;
860 break;
862 case CCL1mode:
863 switch (GET_CODE (code))
865 case LTU: return CC2 | CC3; /* carry */
866 case GEU: return CC0 | CC1; /* no carry */
867 default: return -1;
869 break;
871 case CCL2mode:
872 switch (GET_CODE (code))
874 case GTU: return CC0 | CC1; /* borrow */
875 case LEU: return CC2 | CC3; /* no borrow */
876 default: return -1;
878 break;
880 case CCL3mode:
881 switch (GET_CODE (code))
883 case EQ: return CC0 | CC2;
884 case NE: return CC1 | CC3;
885 case LTU: return CC1;
886 case GTU: return CC3;
887 case LEU: return CC1 | CC2;
888 case GEU: return CC2 | CC3;
889 default: return -1;
892 case CCUmode:
893 switch (GET_CODE (code))
895 case EQ: return CC0;
896 case NE: return CC1 | CC2 | CC3;
897 case LTU: return CC1;
898 case GTU: return CC2;
899 case LEU: return CC0 | CC1;
900 case GEU: return CC0 | CC2;
901 default: return -1;
903 break;
905 case CCURmode:
906 switch (GET_CODE (code))
908 case EQ: return CC0;
909 case NE: return CC2 | CC1 | CC3;
910 case LTU: return CC2;
911 case GTU: return CC1;
912 case LEU: return CC0 | CC2;
913 case GEU: return CC0 | CC1;
914 default: return -1;
916 break;
918 case CCAPmode:
919 switch (GET_CODE (code))
921 case EQ: return CC0;
922 case NE: return CC1 | CC2 | CC3;
923 case LT: return CC1 | CC3;
924 case GT: return CC2;
925 case LE: return CC0 | CC1 | CC3;
926 case GE: return CC0 | CC2;
927 default: return -1;
929 break;
931 case CCANmode:
932 switch (GET_CODE (code))
934 case EQ: return CC0;
935 case NE: return CC1 | CC2 | CC3;
936 case LT: return CC1;
937 case GT: return CC2 | CC3;
938 case LE: return CC0 | CC1;
939 case GE: return CC0 | CC2 | CC3;
940 default: return -1;
942 break;
944 case CCSmode:
945 switch (GET_CODE (code))
947 case EQ: return CC0;
948 case NE: return CC1 | CC2 | CC3;
949 case LT: return CC1;
950 case GT: return CC2;
951 case LE: return CC0 | CC1;
952 case GE: return CC0 | CC2;
953 case UNORDERED: return CC3;
954 case ORDERED: return CC0 | CC1 | CC2;
955 case UNEQ: return CC0 | CC3;
956 case UNLT: return CC1 | CC3;
957 case UNGT: return CC2 | CC3;
958 case UNLE: return CC0 | CC1 | CC3;
959 case UNGE: return CC0 | CC2 | CC3;
960 case LTGT: return CC1 | CC2;
961 default: return -1;
963 break;
965 case CCSRmode:
966 switch (GET_CODE (code))
968 case EQ: return CC0;
969 case NE: return CC2 | CC1 | CC3;
970 case LT: return CC2;
971 case GT: return CC1;
972 case LE: return CC0 | CC2;
973 case GE: return CC0 | CC1;
974 case UNORDERED: return CC3;
975 case ORDERED: return CC0 | CC2 | CC1;
976 case UNEQ: return CC0 | CC3;
977 case UNLT: return CC2 | CC3;
978 case UNGT: return CC1 | CC3;
979 case UNLE: return CC0 | CC2 | CC3;
980 case UNGE: return CC0 | CC1 | CC3;
981 case LTGT: return CC2 | CC1;
982 default: return -1;
984 break;
986 default:
987 return -1;
991 /* If INV is false, return assembler mnemonic string to implement
992 a branch specified by CODE. If INV is true, return mnemonic
993 for the corresponding inverted branch. */
995 static const char *
996 s390_branch_condition_mnemonic (rtx code, int inv)
998 static const char *const mnemonic[16] =
1000 NULL, "o", "h", "nle",
1001 "l", "nhe", "lh", "ne",
1002 "e", "nlh", "he", "nl",
1003 "le", "nh", "no", NULL
1006 int mask = s390_branch_condition_mask (code);
1007 gcc_assert (mask >= 0);
1009 if (inv)
1010 mask ^= 15;
1012 gcc_assert (mask >= 1 && mask <= 14);
1014 return mnemonic[mask];
1017 /* Return the part of op which has a value different from def.
1018 The size of the part is determined by mode.
1019 Use this function only if you already know that op really
1020 contains such a part. */
1022 unsigned HOST_WIDE_INT
1023 s390_extract_part (rtx op, enum machine_mode mode, int def)
1025 unsigned HOST_WIDE_INT value = 0;
1026 int max_parts = HOST_BITS_PER_WIDE_INT / GET_MODE_BITSIZE (mode);
1027 int part_bits = GET_MODE_BITSIZE (mode);
1028 unsigned HOST_WIDE_INT part_mask
1029 = ((unsigned HOST_WIDE_INT)1 << part_bits) - 1;
1030 int i;
1032 for (i = 0; i < max_parts; i++)
1034 if (i == 0)
1035 value = (unsigned HOST_WIDE_INT) INTVAL (op);
1036 else
1037 value >>= part_bits;
1039 if ((value & part_mask) != (def & part_mask))
1040 return value & part_mask;
1043 gcc_unreachable ();
1046 /* If OP is an integer constant of mode MODE with exactly one
1047 part of mode PART_MODE unequal to DEF, return the number of that
1048 part. Otherwise, return -1. */
1051 s390_single_part (rtx op,
1052 enum machine_mode mode,
1053 enum machine_mode part_mode,
1054 int def)
1056 unsigned HOST_WIDE_INT value = 0;
1057 int n_parts = GET_MODE_SIZE (mode) / GET_MODE_SIZE (part_mode);
1058 unsigned HOST_WIDE_INT part_mask
1059 = ((unsigned HOST_WIDE_INT)1 << GET_MODE_BITSIZE (part_mode)) - 1;
1060 int i, part = -1;
1062 if (GET_CODE (op) != CONST_INT)
1063 return -1;
1065 for (i = 0; i < n_parts; i++)
1067 if (i == 0)
1068 value = (unsigned HOST_WIDE_INT) INTVAL (op);
1069 else
1070 value >>= GET_MODE_BITSIZE (part_mode);
1072 if ((value & part_mask) != (def & part_mask))
1074 if (part != -1)
1075 return -1;
1076 else
1077 part = i;
1080 return part == -1 ? -1 : n_parts - 1 - part;
1083 /* Check whether we can (and want to) split a double-word
1084 move in mode MODE from SRC to DST into two single-word
1085 moves, moving the subword FIRST_SUBWORD first. */
1087 bool
1088 s390_split_ok_p (rtx dst, rtx src, enum machine_mode mode, int first_subword)
1090 /* Floating point registers cannot be split. */
1091 if (FP_REG_P (src) || FP_REG_P (dst))
1092 return false;
1094 /* We don't need to split if operands are directly accessible. */
1095 if (s_operand (src, mode) || s_operand (dst, mode))
1096 return false;
1098 /* Non-offsettable memory references cannot be split. */
1099 if ((GET_CODE (src) == MEM && !offsettable_memref_p (src))
1100 || (GET_CODE (dst) == MEM && !offsettable_memref_p (dst)))
1101 return false;
1103 /* Moving the first subword must not clobber a register
1104 needed to move the second subword. */
1105 if (register_operand (dst, mode))
1107 rtx subreg = operand_subword (dst, first_subword, 0, mode);
1108 if (reg_overlap_mentioned_p (subreg, src))
1109 return false;
1112 return true;
1115 /* Return true if it can be proven that [MEM1, MEM1 + SIZE]
1116 and [MEM2, MEM2 + SIZE] do overlap and false
1117 otherwise. */
1119 bool
1120 s390_overlap_p (rtx mem1, rtx mem2, HOST_WIDE_INT size)
1122 rtx addr1, addr2, addr_delta;
1123 HOST_WIDE_INT delta;
1125 if (GET_CODE (mem1) != MEM || GET_CODE (mem2) != MEM)
1126 return true;
1128 if (size == 0)
1129 return false;
1131 addr1 = XEXP (mem1, 0);
1132 addr2 = XEXP (mem2, 0);
1134 addr_delta = simplify_binary_operation (MINUS, Pmode, addr2, addr1);
1136 /* This overlapping check is used by peepholes merging memory block operations.
1137 Overlapping operations would otherwise be recognized by the S/390 hardware
1138 and would fall back to a slower implementation. Allowing overlapping
1139 operations would lead to slow code but not to wrong code. Therefore we are
1140 somewhat optimistic if we cannot prove that the memory blocks are
1141 overlapping.
1142 That's why we return false here although this may accept operations on
1143 overlapping memory areas. */
1144 if (!addr_delta || GET_CODE (addr_delta) != CONST_INT)
1145 return false;
1147 delta = INTVAL (addr_delta);
1149 if (delta == 0
1150 || (delta > 0 && delta < size)
1151 || (delta < 0 && -delta < size))
1152 return true;
1154 return false;
1157 /* Check whether the address of memory reference MEM2 equals exactly
1158 the address of memory reference MEM1 plus DELTA. Return true if
1159 we can prove this to be the case, false otherwise. */
1161 bool
1162 s390_offset_p (rtx mem1, rtx mem2, rtx delta)
1164 rtx addr1, addr2, addr_delta;
1166 if (GET_CODE (mem1) != MEM || GET_CODE (mem2) != MEM)
1167 return false;
1169 addr1 = XEXP (mem1, 0);
1170 addr2 = XEXP (mem2, 0);
1172 addr_delta = simplify_binary_operation (MINUS, Pmode, addr2, addr1);
1173 if (!addr_delta || !rtx_equal_p (addr_delta, delta))
1174 return false;
1176 return true;
1179 /* Expand logical operator CODE in mode MODE with operands OPERANDS. */
1181 void
1182 s390_expand_logical_operator (enum rtx_code code, enum machine_mode mode,
1183 rtx *operands)
1185 enum machine_mode wmode = mode;
1186 rtx dst = operands[0];
1187 rtx src1 = operands[1];
1188 rtx src2 = operands[2];
1189 rtx op, clob, tem;
1191 /* If we cannot handle the operation directly, use a temp register. */
1192 if (!s390_logical_operator_ok_p (operands))
1193 dst = gen_reg_rtx (mode);
1195 /* QImode and HImode patterns make sense only if we have a destination
1196 in memory. Otherwise perform the operation in SImode. */
1197 if ((mode == QImode || mode == HImode) && GET_CODE (dst) != MEM)
1198 wmode = SImode;
1200 /* Widen operands if required. */
1201 if (mode != wmode)
1203 if (GET_CODE (dst) == SUBREG
1204 && (tem = simplify_subreg (wmode, dst, mode, 0)) != 0)
1205 dst = tem;
1206 else if (REG_P (dst))
1207 dst = gen_rtx_SUBREG (wmode, dst, 0);
1208 else
1209 dst = gen_reg_rtx (wmode);
1211 if (GET_CODE (src1) == SUBREG
1212 && (tem = simplify_subreg (wmode, src1, mode, 0)) != 0)
1213 src1 = tem;
1214 else if (GET_MODE (src1) != VOIDmode)
1215 src1 = gen_rtx_SUBREG (wmode, force_reg (mode, src1), 0);
1217 if (GET_CODE (src2) == SUBREG
1218 && (tem = simplify_subreg (wmode, src2, mode, 0)) != 0)
1219 src2 = tem;
1220 else if (GET_MODE (src2) != VOIDmode)
1221 src2 = gen_rtx_SUBREG (wmode, force_reg (mode, src2), 0);
1224 /* Emit the instruction. */
1225 op = gen_rtx_SET (VOIDmode, dst, gen_rtx_fmt_ee (code, wmode, src1, src2));
1226 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
1227 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
1229 /* Fix up the destination if needed. */
1230 if (dst != operands[0])
1231 emit_move_insn (operands[0], gen_lowpart (mode, dst));
1234 /* Check whether OPERANDS are OK for a logical operation (AND, IOR, XOR). */
1236 bool
1237 s390_logical_operator_ok_p (rtx *operands)
1239 /* If the destination operand is in memory, it needs to coincide
1240 with one of the source operands. After reload, it has to be
1241 the first source operand. */
1242 if (GET_CODE (operands[0]) == MEM)
1243 return rtx_equal_p (operands[0], operands[1])
1244 || (!reload_completed && rtx_equal_p (operands[0], operands[2]));
1246 return true;
1249 /* Narrow logical operation CODE of memory operand MEMOP with immediate
1250 operand IMMOP to switch from SS to SI type instructions. */
1252 void
1253 s390_narrow_logical_operator (enum rtx_code code, rtx *memop, rtx *immop)
1255 int def = code == AND ? -1 : 0;
1256 HOST_WIDE_INT mask;
1257 int part;
1259 gcc_assert (GET_CODE (*memop) == MEM);
1260 gcc_assert (!MEM_VOLATILE_P (*memop));
1262 mask = s390_extract_part (*immop, QImode, def);
1263 part = s390_single_part (*immop, GET_MODE (*memop), QImode, def);
1264 gcc_assert (part >= 0);
1266 *memop = adjust_address (*memop, QImode, part);
1267 *immop = gen_int_mode (mask, QImode);
1271 /* How to allocate a 'struct machine_function'. */
1273 static struct machine_function *
1274 s390_init_machine_status (void)
1276 return ggc_alloc_cleared (sizeof (struct machine_function));
1279 /* Change optimizations to be performed, depending on the
1280 optimization level.
1282 LEVEL is the optimization level specified; 2 if `-O2' is
1283 specified, 1 if `-O' is specified, and 0 if neither is specified.
1285 SIZE is nonzero if `-Os' is specified and zero otherwise. */
1287 void
1288 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
1290 /* ??? There are apparently still problems with -fcaller-saves. */
1291 flag_caller_saves = 0;
1293 /* By default, always emit DWARF-2 unwind info. This allows debugging
1294 without maintaining a stack frame back-chain. */
1295 flag_asynchronous_unwind_tables = 1;
1297 /* Use MVCLE instructions to decrease code size if requested. */
1298 if (size != 0)
1299 target_flags |= MASK_MVCLE;
1302 /* Return true if ARG is the name of a processor. Set *TYPE and *FLAGS
1303 to the associated processor_type and processor_flags if so. */
1305 static bool
1306 s390_handle_arch_option (const char *arg,
1307 enum processor_type *type,
1308 enum processor_flags *flags)
1310 static struct pta
1312 const char *const name; /* processor name or nickname. */
1313 const enum processor_type processor;
1314 const enum processor_flags flags;
1316 const processor_alias_table[] =
1318 {"g5", PROCESSOR_9672_G5, PF_IEEE_FLOAT},
1319 {"g6", PROCESSOR_9672_G6, PF_IEEE_FLOAT},
1320 {"z900", PROCESSOR_2064_Z900, PF_IEEE_FLOAT | PF_ZARCH},
1321 {"z990", PROCESSOR_2084_Z990, PF_IEEE_FLOAT | PF_ZARCH
1322 | PF_LONG_DISPLACEMENT},
1323 {"z9-109", PROCESSOR_2094_Z9_109, PF_IEEE_FLOAT | PF_ZARCH
1324 | PF_LONG_DISPLACEMENT | PF_EXTIMM},
1326 size_t i;
1328 for (i = 0; i < ARRAY_SIZE (processor_alias_table); i++)
1329 if (strcmp (arg, processor_alias_table[i].name) == 0)
1331 *type = processor_alias_table[i].processor;
1332 *flags = processor_alias_table[i].flags;
1333 return true;
1335 return false;
1338 /* Implement TARGET_HANDLE_OPTION. */
1340 static bool
1341 s390_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
1343 switch (code)
1345 case OPT_march_:
1346 return s390_handle_arch_option (arg, &s390_arch, &s390_arch_flags);
1348 case OPT_mstack_guard_:
1349 if (sscanf (arg, HOST_WIDE_INT_PRINT_DEC, &s390_stack_guard) != 1)
1350 return false;
1351 if (exact_log2 (s390_stack_guard) == -1)
1352 error ("stack guard value must be an exact power of 2");
1353 return true;
1355 case OPT_mstack_size_:
1356 if (sscanf (arg, HOST_WIDE_INT_PRINT_DEC, &s390_stack_size) != 1)
1357 return false;
1358 if (exact_log2 (s390_stack_size) == -1)
1359 error ("stack size must be an exact power of 2");
1360 return true;
1362 case OPT_mtune_:
1363 return s390_handle_arch_option (arg, &s390_tune, &s390_tune_flags);
1365 case OPT_mwarn_framesize_:
1366 return sscanf (arg, HOST_WIDE_INT_PRINT_DEC, &s390_warn_framesize) == 1;
1368 default:
1369 return true;
1373 void
1374 override_options (void)
1376 /* Set up function hooks. */
1377 init_machine_status = s390_init_machine_status;
1379 /* Architecture mode defaults according to ABI. */
1380 if (!(target_flags_explicit & MASK_ZARCH))
1382 if (TARGET_64BIT)
1383 target_flags |= MASK_ZARCH;
1384 else
1385 target_flags &= ~MASK_ZARCH;
1388 /* Determine processor architectural level. */
1389 if (!s390_arch_string)
1391 s390_arch_string = TARGET_ZARCH? "z900" : "g5";
1392 s390_handle_arch_option (s390_arch_string, &s390_arch, &s390_arch_flags);
1395 /* Determine processor to tune for. */
1396 if (s390_tune == PROCESSOR_max)
1398 s390_tune = s390_arch;
1399 s390_tune_flags = s390_arch_flags;
1402 /* Sanity checks. */
1403 if (TARGET_ZARCH && !(s390_arch_flags & PF_ZARCH))
1404 error ("z/Architecture mode not supported on %s", s390_arch_string);
1405 if (TARGET_64BIT && !TARGET_ZARCH)
1406 error ("64-bit ABI not supported in ESA/390 mode");
1408 /* Set processor cost function. */
1409 if (s390_tune == PROCESSOR_2094_Z9_109)
1410 s390_cost = &z9_109_cost;
1411 else if (s390_tune == PROCESSOR_2084_Z990)
1412 s390_cost = &z990_cost;
1413 else
1414 s390_cost = &z900_cost;
1416 if (TARGET_BACKCHAIN && TARGET_PACKED_STACK && TARGET_HARD_FLOAT)
1417 error ("-mbackchain -mpacked-stack -mhard-float are not supported "
1418 "in combination");
1420 if (s390_stack_size)
1422 if (!s390_stack_guard)
1423 error ("-mstack-size implies use of -mstack-guard");
1424 else if (s390_stack_guard >= s390_stack_size)
1425 error ("stack size must be greater than the stack guard value");
1426 else if (s390_stack_size > 1 << 16)
1427 error ("stack size must not be greater than 64k");
1429 else if (s390_stack_guard)
1430 error ("-mstack-guard implies use of -mstack-size");
1432 #ifdef TARGET_DEFAULT_LONG_DOUBLE_128
1433 if (!(target_flags_explicit & MASK_LONG_DOUBLE_128))
1434 target_flags |= MASK_LONG_DOUBLE_128;
1435 #endif
1438 /* Map for smallest class containing reg regno. */
1440 const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
1441 { GENERAL_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1442 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1443 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1444 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1445 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1446 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1447 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1448 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1449 ADDR_REGS, CC_REGS, ADDR_REGS, ADDR_REGS,
1450 ACCESS_REGS, ACCESS_REGS
1453 /* Return attribute type of insn. */
1455 static enum attr_type
1456 s390_safe_attr_type (rtx insn)
1458 if (recog_memoized (insn) >= 0)
1459 return get_attr_type (insn);
1460 else
1461 return TYPE_NONE;
1464 /* Return true if DISP is a valid short displacement. */
1466 static bool
1467 s390_short_displacement (rtx disp)
1469 /* No displacement is OK. */
1470 if (!disp)
1471 return true;
1473 /* Integer displacement in range. */
1474 if (GET_CODE (disp) == CONST_INT)
1475 return INTVAL (disp) >= 0 && INTVAL (disp) < 4096;
1477 /* GOT offset is not OK, the GOT can be large. */
1478 if (GET_CODE (disp) == CONST
1479 && GET_CODE (XEXP (disp, 0)) == UNSPEC
1480 && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOT
1481 || XINT (XEXP (disp, 0), 1) == UNSPEC_GOTNTPOFF))
1482 return false;
1484 /* All other symbolic constants are literal pool references,
1485 which are OK as the literal pool must be small. */
1486 if (GET_CODE (disp) == CONST)
1487 return true;
1489 return false;
1492 /* Decompose a RTL expression ADDR for a memory address into
1493 its components, returned in OUT.
1495 Returns false if ADDR is not a valid memory address, true
1496 otherwise. If OUT is NULL, don't return the components,
1497 but check for validity only.
1499 Note: Only addresses in canonical form are recognized.
1500 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
1501 canonical form so that they will be recognized. */
1503 static int
1504 s390_decompose_address (rtx addr, struct s390_address *out)
1506 HOST_WIDE_INT offset = 0;
1507 rtx base = NULL_RTX;
1508 rtx indx = NULL_RTX;
1509 rtx disp = NULL_RTX;
1510 rtx orig_disp;
1511 bool pointer = false;
1512 bool base_ptr = false;
1513 bool indx_ptr = false;
1514 bool literal_pool = false;
1516 /* We may need to substitute the literal pool base register into the address
1517 below. However, at this point we do not know which register is going to
1518 be used as base, so we substitute the arg pointer register. This is going
1519 to be treated as holding a pointer below -- it shouldn't be used for any
1520 other purpose. */
1521 rtx fake_pool_base = gen_rtx_REG (Pmode, ARG_POINTER_REGNUM);
1523 /* Decompose address into base + index + displacement. */
1525 if (GET_CODE (addr) == REG || GET_CODE (addr) == UNSPEC)
1526 base = addr;
1528 else if (GET_CODE (addr) == PLUS)
1530 rtx op0 = XEXP (addr, 0);
1531 rtx op1 = XEXP (addr, 1);
1532 enum rtx_code code0 = GET_CODE (op0);
1533 enum rtx_code code1 = GET_CODE (op1);
1535 if (code0 == REG || code0 == UNSPEC)
1537 if (code1 == REG || code1 == UNSPEC)
1539 indx = op0; /* index + base */
1540 base = op1;
1543 else
1545 base = op0; /* base + displacement */
1546 disp = op1;
1550 else if (code0 == PLUS)
1552 indx = XEXP (op0, 0); /* index + base + disp */
1553 base = XEXP (op0, 1);
1554 disp = op1;
1557 else
1559 return false;
1563 else
1564 disp = addr; /* displacement */
1566 /* Extract integer part of displacement. */
1567 orig_disp = disp;
1568 if (disp)
1570 if (GET_CODE (disp) == CONST_INT)
1572 offset = INTVAL (disp);
1573 disp = NULL_RTX;
1575 else if (GET_CODE (disp) == CONST
1576 && GET_CODE (XEXP (disp, 0)) == PLUS
1577 && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT)
1579 offset = INTVAL (XEXP (XEXP (disp, 0), 1));
1580 disp = XEXP (XEXP (disp, 0), 0);
1584 /* Strip off CONST here to avoid special case tests later. */
1585 if (disp && GET_CODE (disp) == CONST)
1586 disp = XEXP (disp, 0);
1588 /* We can convert literal pool addresses to
1589 displacements by basing them off the base register. */
1590 if (disp && GET_CODE (disp) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (disp))
1592 /* Either base or index must be free to hold the base register. */
1593 if (!base)
1594 base = fake_pool_base, literal_pool = true;
1595 else if (!indx)
1596 indx = fake_pool_base, literal_pool = true;
1597 else
1598 return false;
1600 /* Mark up the displacement. */
1601 disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp),
1602 UNSPEC_LTREL_OFFSET);
1605 /* Validate base register. */
1606 if (base)
1608 if (GET_CODE (base) == UNSPEC)
1609 switch (XINT (base, 1))
1611 case UNSPEC_LTREF:
1612 if (!disp)
1613 disp = gen_rtx_UNSPEC (Pmode,
1614 gen_rtvec (1, XVECEXP (base, 0, 0)),
1615 UNSPEC_LTREL_OFFSET);
1616 else
1617 return false;
1619 base = XVECEXP (base, 0, 1);
1620 break;
1622 case UNSPEC_LTREL_BASE:
1623 if (XVECLEN (base, 0) == 1)
1624 base = fake_pool_base, literal_pool = true;
1625 else
1626 base = XVECEXP (base, 0, 1);
1627 break;
1629 default:
1630 return false;
1633 if (!REG_P (base)
1634 || (GET_MODE (base) != SImode
1635 && GET_MODE (base) != Pmode))
1636 return false;
1638 if (REGNO (base) == STACK_POINTER_REGNUM
1639 || REGNO (base) == FRAME_POINTER_REGNUM
1640 || ((reload_completed || reload_in_progress)
1641 && frame_pointer_needed
1642 && REGNO (base) == HARD_FRAME_POINTER_REGNUM)
1643 || REGNO (base) == ARG_POINTER_REGNUM
1644 || (flag_pic
1645 && REGNO (base) == PIC_OFFSET_TABLE_REGNUM))
1646 pointer = base_ptr = true;
1648 if ((reload_completed || reload_in_progress)
1649 && base == cfun->machine->base_reg)
1650 pointer = base_ptr = literal_pool = true;
1653 /* Validate index register. */
1654 if (indx)
1656 if (GET_CODE (indx) == UNSPEC)
1657 switch (XINT (indx, 1))
1659 case UNSPEC_LTREF:
1660 if (!disp)
1661 disp = gen_rtx_UNSPEC (Pmode,
1662 gen_rtvec (1, XVECEXP (indx, 0, 0)),
1663 UNSPEC_LTREL_OFFSET);
1664 else
1665 return false;
1667 indx = XVECEXP (indx, 0, 1);
1668 break;
1670 case UNSPEC_LTREL_BASE:
1671 if (XVECLEN (indx, 0) == 1)
1672 indx = fake_pool_base, literal_pool = true;
1673 else
1674 indx = XVECEXP (indx, 0, 1);
1675 break;
1677 default:
1678 return false;
1681 if (!REG_P (indx)
1682 || (GET_MODE (indx) != SImode
1683 && GET_MODE (indx) != Pmode))
1684 return false;
1686 if (REGNO (indx) == STACK_POINTER_REGNUM
1687 || REGNO (indx) == FRAME_POINTER_REGNUM
1688 || ((reload_completed || reload_in_progress)
1689 && frame_pointer_needed
1690 && REGNO (indx) == HARD_FRAME_POINTER_REGNUM)
1691 || REGNO (indx) == ARG_POINTER_REGNUM
1692 || (flag_pic
1693 && REGNO (indx) == PIC_OFFSET_TABLE_REGNUM))
1694 pointer = indx_ptr = true;
1696 if ((reload_completed || reload_in_progress)
1697 && indx == cfun->machine->base_reg)
1698 pointer = indx_ptr = literal_pool = true;
1701 /* Prefer to use pointer as base, not index. */
1702 if (base && indx && !base_ptr
1703 && (indx_ptr || (!REG_POINTER (base) && REG_POINTER (indx))))
1705 rtx tmp = base;
1706 base = indx;
1707 indx = tmp;
1710 /* Validate displacement. */
1711 if (!disp)
1713 /* If virtual registers are involved, the displacement will change later
1714 anyway as the virtual registers get eliminated. This could make a
1715 valid displacement invalid, but it is more likely to make an invalid
1716 displacement valid, because we sometimes access the register save area
1717 via negative offsets to one of those registers.
1718 Thus we don't check the displacement for validity here. If after
1719 elimination the displacement turns out to be invalid after all,
1720 this is fixed up by reload in any case. */
1721 if (base != arg_pointer_rtx
1722 && indx != arg_pointer_rtx
1723 && base != return_address_pointer_rtx
1724 && indx != return_address_pointer_rtx
1725 && base != frame_pointer_rtx
1726 && indx != frame_pointer_rtx
1727 && base != virtual_stack_vars_rtx
1728 && indx != virtual_stack_vars_rtx)
1729 if (!DISP_IN_RANGE (offset))
1730 return false;
1732 else
1734 /* All the special cases are pointers. */
1735 pointer = true;
1737 /* In the small-PIC case, the linker converts @GOT
1738 and @GOTNTPOFF offsets to possible displacements. */
1739 if (GET_CODE (disp) == UNSPEC
1740 && (XINT (disp, 1) == UNSPEC_GOT
1741 || XINT (disp, 1) == UNSPEC_GOTNTPOFF)
1742 && offset == 0
1743 && flag_pic == 1)
1748 /* Accept chunkified literal pool symbol references. */
1749 else if (cfun && cfun->machine
1750 && cfun->machine->decomposed_literal_pool_addresses_ok_p
1751 && GET_CODE (disp) == MINUS
1752 && GET_CODE (XEXP (disp, 0)) == LABEL_REF
1753 && GET_CODE (XEXP (disp, 1)) == LABEL_REF)
1758 /* Accept literal pool references. */
1759 else if (GET_CODE (disp) == UNSPEC
1760 && XINT (disp, 1) == UNSPEC_LTREL_OFFSET)
1762 orig_disp = gen_rtx_CONST (Pmode, disp);
1763 if (offset)
1765 /* If we have an offset, make sure it does not
1766 exceed the size of the constant pool entry. */
1767 rtx sym = XVECEXP (disp, 0, 0);
1768 if (offset >= GET_MODE_SIZE (get_pool_mode (sym)))
1769 return false;
1771 orig_disp = plus_constant (orig_disp, offset);
1775 else
1776 return false;
1779 if (!base && !indx)
1780 pointer = true;
1782 if (out)
1784 out->base = base;
1785 out->indx = indx;
1786 out->disp = orig_disp;
1787 out->pointer = pointer;
1788 out->literal_pool = literal_pool;
1791 return true;
1794 /* Decompose a RTL expression OP for a shift count into its components,
1795 and return the base register in BASE and the offset in OFFSET.
1797 Return true if OP is a valid shift count, false if not. */
1799 bool
1800 s390_decompose_shift_count (rtx op, rtx *base, HOST_WIDE_INT *offset)
1802 HOST_WIDE_INT off = 0;
1804 /* We can have an integer constant, an address register,
1805 or a sum of the two. */
1806 if (GET_CODE (op) == CONST_INT)
1808 off = INTVAL (op);
1809 op = NULL_RTX;
1811 if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
1813 off = INTVAL (XEXP (op, 1));
1814 op = XEXP (op, 0);
1816 while (op && GET_CODE (op) == SUBREG)
1817 op = SUBREG_REG (op);
1819 if (op && GET_CODE (op) != REG)
1820 return false;
1822 if (offset)
1823 *offset = off;
1824 if (base)
1825 *base = op;
1827 return true;
1831 /* Return true if CODE is a valid address without index. */
1833 bool
1834 s390_legitimate_address_without_index_p (rtx op)
1836 struct s390_address addr;
1838 if (!s390_decompose_address (XEXP (op, 0), &addr))
1839 return false;
1840 if (addr.indx)
1841 return false;
1843 return true;
1846 /* Return 1 if OP is a valid operand for a C constraint, 0 else. */
1849 s390_extra_constraint_str (rtx op, int c, const char * str)
1851 struct s390_address addr;
1853 gcc_assert (c == str[0]);
1855 /* Check for offsettable variants of memory constraints. */
1856 if (c == 'A')
1858 /* Only accept non-volatile MEMs. */
1859 if (!MEM_P (op) || MEM_VOLATILE_P (op))
1860 return 0;
1862 if ((reload_completed || reload_in_progress)
1863 ? !offsettable_memref_p (op)
1864 : !offsettable_nonstrict_memref_p (op))
1865 return 0;
1867 c = str[1];
1870 /* Check for non-literal-pool variants of memory constraints. */
1871 else if (c == 'B')
1873 if (GET_CODE (op) != MEM)
1874 return 0;
1875 if (!s390_decompose_address (XEXP (op, 0), &addr))
1876 return 0;
1877 if (addr.literal_pool)
1878 return 0;
1880 c = str[1];
1883 switch (c)
1885 case 'Q':
1886 if (GET_CODE (op) != MEM)
1887 return 0;
1888 if (!s390_decompose_address (XEXP (op, 0), &addr))
1889 return 0;
1890 if (addr.indx)
1891 return 0;
1893 if (TARGET_LONG_DISPLACEMENT)
1895 if (!s390_short_displacement (addr.disp))
1896 return 0;
1898 break;
1900 case 'R':
1901 if (GET_CODE (op) != MEM)
1902 return 0;
1904 if (TARGET_LONG_DISPLACEMENT)
1906 if (!s390_decompose_address (XEXP (op, 0), &addr))
1907 return 0;
1908 if (!s390_short_displacement (addr.disp))
1909 return 0;
1911 break;
1913 case 'S':
1914 if (!TARGET_LONG_DISPLACEMENT)
1915 return 0;
1916 if (GET_CODE (op) != MEM)
1917 return 0;
1918 if (!s390_decompose_address (XEXP (op, 0), &addr))
1919 return 0;
1920 if (addr.indx)
1921 return 0;
1922 if (s390_short_displacement (addr.disp))
1923 return 0;
1924 break;
1926 case 'T':
1927 if (!TARGET_LONG_DISPLACEMENT)
1928 return 0;
1929 if (GET_CODE (op) != MEM)
1930 return 0;
1931 /* Any invalid address here will be fixed up by reload,
1932 so accept it for the most generic constraint. */
1933 if (s390_decompose_address (XEXP (op, 0), &addr)
1934 && s390_short_displacement (addr.disp))
1935 return 0;
1936 break;
1938 case 'U':
1939 if (TARGET_LONG_DISPLACEMENT)
1941 if (!s390_decompose_address (op, &addr))
1942 return 0;
1943 if (!s390_short_displacement (addr.disp))
1944 return 0;
1946 break;
1948 case 'W':
1949 if (!TARGET_LONG_DISPLACEMENT)
1950 return 0;
1951 /* Any invalid address here will be fixed up by reload,
1952 so accept it for the most generic constraint. */
1953 if (s390_decompose_address (op, &addr)
1954 && s390_short_displacement (addr.disp))
1955 return 0;
1956 break;
1958 case 'Y':
1959 /* Simply check for the basic form of a shift count. Reload will
1960 take care of making sure we have a proper base register. */
1961 if (!s390_decompose_shift_count (op, NULL, NULL))
1962 return 0;
1963 break;
1965 default:
1966 return 0;
1969 return 1;
1972 /* Return true if VALUE matches the constraint STR. */
1975 s390_const_double_ok_for_constraint_p (rtx value,
1976 int c,
1977 const char * str)
1979 gcc_assert (c == str[0]);
1981 switch (str[0])
1983 case 'G':
1984 /* The floating point zero constant. */
1985 return (GET_MODE_CLASS (GET_MODE (value)) == MODE_FLOAT
1986 && value == CONST0_RTX (GET_MODE (value)));
1988 default:
1989 return 0;
1993 /* Return true if VALUE matches the constraint STR. */
1996 s390_const_ok_for_constraint_p (HOST_WIDE_INT value,
1997 int c,
1998 const char * str)
2000 enum machine_mode mode, part_mode;
2001 int def;
2002 int part, part_goal;
2004 gcc_assert (c == str[0]);
2006 switch (str[0])
2008 case 'I':
2009 return (unsigned int)value < 256;
2011 case 'J':
2012 return (unsigned int)value < 4096;
2014 case 'K':
2015 return value >= -32768 && value < 32768;
2017 case 'L':
2018 return (TARGET_LONG_DISPLACEMENT ?
2019 (value >= -524288 && value <= 524287)
2020 : (value >= 0 && value <= 4095));
2021 case 'M':
2022 return value == 2147483647;
2024 case 'N':
2025 if (str[1] == 'x')
2026 part_goal = -1;
2027 else
2028 part_goal = str[1] - '0';
2030 switch (str[2])
2032 case 'Q': part_mode = QImode; break;
2033 case 'H': part_mode = HImode; break;
2034 case 'S': part_mode = SImode; break;
2035 default: return 0;
2038 switch (str[3])
2040 case 'H': mode = HImode; break;
2041 case 'S': mode = SImode; break;
2042 case 'D': mode = DImode; break;
2043 default: return 0;
2046 switch (str[4])
2048 case '0': def = 0; break;
2049 case 'F': def = -1; break;
2050 default: return 0;
2053 if (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (part_mode))
2054 return 0;
2056 part = s390_single_part (GEN_INT (value), mode, part_mode, def);
2057 if (part < 0)
2058 return 0;
2059 if (part_goal != -1 && part_goal != part)
2060 return 0;
2062 break;
2064 case 'O':
2065 if (!TARGET_EXTIMM)
2066 return 0;
2068 switch (str[1])
2070 case 's':
2071 return trunc_int_for_mode (value, SImode) == value;
2073 case 'p':
2074 return value == 0
2075 || s390_single_part (GEN_INT (value), DImode, SImode, 0) == 1;
2077 case 'n':
2078 return value == -1
2079 || s390_single_part (GEN_INT (value), DImode, SImode, -1) == 1;
2081 default:
2082 gcc_unreachable ();
2084 break;
2086 case 'P':
2087 return legitimate_reload_constant_p (GEN_INT (value));
2089 default:
2090 return 0;
2093 return 1;
2096 /* Compute a (partial) cost for rtx X. Return true if the complete
2097 cost has been computed, and false if subexpressions should be
2098 scanned. In either case, *TOTAL contains the cost result.
2099 CODE contains GET_CODE (x), OUTER_CODE contains the code
2100 of the superexpression of x. */
2102 static bool
2103 s390_rtx_costs (rtx x, int code, int outer_code, int *total)
2105 switch (code)
2107 case CONST:
2108 case CONST_INT:
2109 case LABEL_REF:
2110 case SYMBOL_REF:
2111 case CONST_DOUBLE:
2112 case MEM:
2113 *total = 0;
2114 return true;
2116 case ASHIFT:
2117 case ASHIFTRT:
2118 case LSHIFTRT:
2119 case ROTATE:
2120 case ROTATERT:
2121 case AND:
2122 case IOR:
2123 case XOR:
2124 case NEG:
2125 case NOT:
2126 *total = COSTS_N_INSNS (1);
2127 return false;
2129 case PLUS:
2130 case MINUS:
2131 /* Check for multiply and add. */
2132 if ((GET_MODE (x) == DFmode || GET_MODE (x) == SFmode)
2133 && GET_CODE (XEXP (x, 0)) == MULT
2134 && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD)
2136 /* This is the multiply and add case. */
2137 if (GET_MODE (x) == DFmode)
2138 *total = s390_cost->madbr;
2139 else
2140 *total = s390_cost->maebr;
2141 *total += rtx_cost (XEXP (XEXP (x, 0), 0), MULT)
2142 + rtx_cost (XEXP (XEXP (x, 0), 1), MULT)
2143 + rtx_cost (XEXP (x, 1), code);
2144 return true; /* Do not do an additional recursive descent. */
2146 *total = COSTS_N_INSNS (1);
2147 return false;
2149 case MULT:
2150 switch (GET_MODE (x))
2152 case SImode:
2154 rtx left = XEXP (x, 0);
2155 rtx right = XEXP (x, 1);
2156 if (GET_CODE (right) == CONST_INT
2157 && CONST_OK_FOR_K (INTVAL (right)))
2158 *total = s390_cost->mhi;
2159 else if (GET_CODE (left) == SIGN_EXTEND)
2160 *total = s390_cost->mh;
2161 else
2162 *total = s390_cost->ms; /* msr, ms, msy */
2163 break;
2165 case DImode:
2167 rtx left = XEXP (x, 0);
2168 rtx right = XEXP (x, 1);
2169 if (TARGET_64BIT)
2171 if (GET_CODE (right) == CONST_INT
2172 && CONST_OK_FOR_K (INTVAL (right)))
2173 *total = s390_cost->mghi;
2174 else if (GET_CODE (left) == SIGN_EXTEND)
2175 *total = s390_cost->msgf;
2176 else
2177 *total = s390_cost->msg; /* msgr, msg */
2179 else /* TARGET_31BIT */
2181 if (GET_CODE (left) == SIGN_EXTEND
2182 && GET_CODE (right) == SIGN_EXTEND)
2183 /* mulsidi case: mr, m */
2184 *total = s390_cost->m;
2185 else if (GET_CODE (left) == ZERO_EXTEND
2186 && GET_CODE (right) == ZERO_EXTEND
2187 && TARGET_CPU_ZARCH)
2188 /* umulsidi case: ml, mlr */
2189 *total = s390_cost->ml;
2190 else
2191 /* Complex calculation is required. */
2192 *total = COSTS_N_INSNS (40);
2194 break;
2196 case SFmode:
2197 case DFmode:
2198 *total = s390_cost->mult_df;
2199 break;
2200 case TFmode:
2201 *total = s390_cost->mxbr;
2202 break;
2203 default:
2204 return false;
2206 return false;
2208 case UDIV:
2209 case UMOD:
2210 if (GET_MODE (x) == TImode) /* 128 bit division */
2211 *total = s390_cost->dlgr;
2212 else if (GET_MODE (x) == DImode)
2214 rtx right = XEXP (x, 1);
2215 if (GET_CODE (right) == ZERO_EXTEND) /* 64 by 32 bit division */
2216 *total = s390_cost->dlr;
2217 else /* 64 by 64 bit division */
2218 *total = s390_cost->dlgr;
2220 else if (GET_MODE (x) == SImode) /* 32 bit division */
2221 *total = s390_cost->dlr;
2222 return false;
2224 case DIV:
2225 case MOD:
2226 if (GET_MODE (x) == DImode)
2228 rtx right = XEXP (x, 1);
2229 if (GET_CODE (right) == ZERO_EXTEND) /* 64 by 32 bit division */
2230 if (TARGET_64BIT)
2231 *total = s390_cost->dsgfr;
2232 else
2233 *total = s390_cost->dr;
2234 else /* 64 by 64 bit division */
2235 *total = s390_cost->dsgr;
2237 else if (GET_MODE (x) == SImode) /* 32 bit division */
2238 *total = s390_cost->dlr;
2239 else if (GET_MODE (x) == SFmode)
2241 if (TARGET_IEEE_FLOAT)
2242 *total = s390_cost->debr;
2243 else /* TARGET_IBM_FLOAT */
2244 *total = s390_cost->der;
2246 else if (GET_MODE (x) == DFmode)
2248 if (TARGET_IEEE_FLOAT)
2249 *total = s390_cost->ddbr;
2250 else /* TARGET_IBM_FLOAT */
2251 *total = s390_cost->ddr;
2253 else if (GET_MODE (x) == TFmode)
2255 if (TARGET_IEEE_FLOAT)
2256 *total = s390_cost->dxbr;
2257 else /* TARGET_IBM_FLOAT */
2258 *total = s390_cost->dxr;
2260 return false;
2262 case SQRT:
2263 if (GET_MODE (x) == SFmode)
2264 *total = s390_cost->sqebr;
2265 else if (GET_MODE (x) == DFmode)
2266 *total = s390_cost->sqdbr;
2267 else /* TFmode */
2268 *total = s390_cost->sqxbr;
2269 return false;
2271 case SIGN_EXTEND:
2272 case ZERO_EXTEND:
2273 if (outer_code == MULT || outer_code == DIV || outer_code == MOD
2274 || outer_code == PLUS || outer_code == MINUS
2275 || outer_code == COMPARE)
2276 *total = 0;
2277 return false;
2279 case COMPARE:
2280 *total = COSTS_N_INSNS (1);
2281 if (GET_CODE (XEXP (x, 0)) == AND
2282 && GET_CODE (XEXP (x, 1)) == CONST_INT
2283 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
2285 rtx op0 = XEXP (XEXP (x, 0), 0);
2286 rtx op1 = XEXP (XEXP (x, 0), 1);
2287 rtx op2 = XEXP (x, 1);
2289 if (memory_operand (op0, GET_MODE (op0))
2290 && s390_tm_ccmode (op1, op2, 0) != VOIDmode)
2291 return true;
2292 if (register_operand (op0, GET_MODE (op0))
2293 && s390_tm_ccmode (op1, op2, 1) != VOIDmode)
2294 return true;
2296 return false;
2298 default:
2299 return false;
2303 /* Return the cost of an address rtx ADDR. */
2305 static int
2306 s390_address_cost (rtx addr)
2308 struct s390_address ad;
2309 if (!s390_decompose_address (addr, &ad))
2310 return 1000;
2312 return ad.indx? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
2315 /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
2316 otherwise return 0. */
2319 tls_symbolic_operand (rtx op)
2321 if (GET_CODE (op) != SYMBOL_REF)
2322 return 0;
2323 return SYMBOL_REF_TLS_MODEL (op);
2326 /* Split DImode access register reference REG (on 64-bit) into its constituent
2327 low and high parts, and store them into LO and HI. Note that gen_lowpart/
2328 gen_highpart cannot be used as they assume all registers are word-sized,
2329 while our access registers have only half that size. */
2331 void
2332 s390_split_access_reg (rtx reg, rtx *lo, rtx *hi)
2334 gcc_assert (TARGET_64BIT);
2335 gcc_assert (ACCESS_REG_P (reg));
2336 gcc_assert (GET_MODE (reg) == DImode);
2337 gcc_assert (!(REGNO (reg) & 1));
2339 *lo = gen_rtx_REG (SImode, REGNO (reg) + 1);
2340 *hi = gen_rtx_REG (SImode, REGNO (reg));
2343 /* Return true if OP contains a symbol reference */
2345 bool
2346 symbolic_reference_mentioned_p (rtx op)
2348 const char *fmt;
2349 int i;
2351 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
2352 return 1;
2354 fmt = GET_RTX_FORMAT (GET_CODE (op));
2355 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
2357 if (fmt[i] == 'E')
2359 int j;
2361 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
2362 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
2363 return 1;
2366 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
2367 return 1;
2370 return 0;
2373 /* Return true if OP contains a reference to a thread-local symbol. */
2375 bool
2376 tls_symbolic_reference_mentioned_p (rtx op)
2378 const char *fmt;
2379 int i;
2381 if (GET_CODE (op) == SYMBOL_REF)
2382 return tls_symbolic_operand (op);
2384 fmt = GET_RTX_FORMAT (GET_CODE (op));
2385 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
2387 if (fmt[i] == 'E')
2389 int j;
2391 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
2392 if (tls_symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
2393 return true;
2396 else if (fmt[i] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op, i)))
2397 return true;
2400 return false;
2404 /* Return true if OP is a legitimate general operand when
2405 generating PIC code. It is given that flag_pic is on
2406 and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2409 legitimate_pic_operand_p (rtx op)
2411 /* Accept all non-symbolic constants. */
2412 if (!SYMBOLIC_CONST (op))
2413 return 1;
2415 /* Reject everything else; must be handled
2416 via emit_symbolic_move. */
2417 return 0;
2420 /* Returns true if the constant value OP is a legitimate general operand.
2421 It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2424 legitimate_constant_p (rtx op)
2426 /* Accept all non-symbolic constants. */
2427 if (!SYMBOLIC_CONST (op))
2428 return 1;
2430 /* Accept immediate LARL operands. */
2431 if (TARGET_CPU_ZARCH && larl_operand (op, VOIDmode))
2432 return 1;
2434 /* Thread-local symbols are never legal constants. This is
2435 so that emit_call knows that computing such addresses
2436 might require a function call. */
2437 if (TLS_SYMBOLIC_CONST (op))
2438 return 0;
2440 /* In the PIC case, symbolic constants must *not* be
2441 forced into the literal pool. We accept them here,
2442 so that they will be handled by emit_symbolic_move. */
2443 if (flag_pic)
2444 return 1;
2446 /* All remaining non-PIC symbolic constants are
2447 forced into the literal pool. */
2448 return 0;
2451 /* Determine if it's legal to put X into the constant pool. This
2452 is not possible if X contains the address of a symbol that is
2453 not constant (TLS) or not known at final link time (PIC). */
2455 static bool
2456 s390_cannot_force_const_mem (rtx x)
2458 switch (GET_CODE (x))
2460 case CONST_INT:
2461 case CONST_DOUBLE:
2462 /* Accept all non-symbolic constants. */
2463 return false;
2465 case LABEL_REF:
2466 /* Labels are OK iff we are non-PIC. */
2467 return flag_pic != 0;
2469 case SYMBOL_REF:
2470 /* 'Naked' TLS symbol references are never OK,
2471 non-TLS symbols are OK iff we are non-PIC. */
2472 if (tls_symbolic_operand (x))
2473 return true;
2474 else
2475 return flag_pic != 0;
2477 case CONST:
2478 return s390_cannot_force_const_mem (XEXP (x, 0));
2479 case PLUS:
2480 case MINUS:
2481 return s390_cannot_force_const_mem (XEXP (x, 0))
2482 || s390_cannot_force_const_mem (XEXP (x, 1));
2484 case UNSPEC:
2485 switch (XINT (x, 1))
2487 /* Only lt-relative or GOT-relative UNSPECs are OK. */
2488 case UNSPEC_LTREL_OFFSET:
2489 case UNSPEC_GOT:
2490 case UNSPEC_GOTOFF:
2491 case UNSPEC_PLTOFF:
2492 case UNSPEC_TLSGD:
2493 case UNSPEC_TLSLDM:
2494 case UNSPEC_NTPOFF:
2495 case UNSPEC_DTPOFF:
2496 case UNSPEC_GOTNTPOFF:
2497 case UNSPEC_INDNTPOFF:
2498 return false;
2500 /* If the literal pool shares the code section, be put
2501 execute template placeholders into the pool as well. */
2502 case UNSPEC_INSN:
2503 return TARGET_CPU_ZARCH;
2505 default:
2506 return true;
2508 break;
2510 default:
2511 gcc_unreachable ();
2515 /* Returns true if the constant value OP is a legitimate general
2516 operand during and after reload. The difference to
2517 legitimate_constant_p is that this function will not accept
2518 a constant that would need to be forced to the literal pool
2519 before it can be used as operand. */
2521 bool
2522 legitimate_reload_constant_p (rtx op)
2524 /* Accept la(y) operands. */
2525 if (GET_CODE (op) == CONST_INT
2526 && DISP_IN_RANGE (INTVAL (op)))
2527 return true;
2529 /* Accept l(g)hi/l(g)fi operands. */
2530 if (GET_CODE (op) == CONST_INT
2531 && (CONST_OK_FOR_K (INTVAL (op)) || CONST_OK_FOR_Os (INTVAL (op))))
2532 return true;
2534 /* Accept lliXX operands. */
2535 if (TARGET_ZARCH
2536 && GET_CODE (op) == CONST_INT
2537 && trunc_int_for_mode (INTVAL (op), word_mode) == INTVAL (op)
2538 && s390_single_part (op, word_mode, HImode, 0) >= 0)
2539 return true;
2541 if (TARGET_EXTIMM
2542 && GET_CODE (op) == CONST_INT
2543 && trunc_int_for_mode (INTVAL (op), word_mode) == INTVAL (op)
2544 && s390_single_part (op, word_mode, SImode, 0) >= 0)
2545 return true;
2547 /* Accept larl operands. */
2548 if (TARGET_CPU_ZARCH
2549 && larl_operand (op, VOIDmode))
2550 return true;
2552 /* Accept lzXX operands. */
2553 if (GET_CODE (op) == CONST_DOUBLE
2554 && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, 'G', "G"))
2555 return true;
2557 /* Accept double-word operands that can be split. */
2558 if (GET_CODE (op) == CONST_INT
2559 && trunc_int_for_mode (INTVAL (op), word_mode) != INTVAL (op))
2561 enum machine_mode dword_mode = word_mode == SImode ? DImode : TImode;
2562 rtx hi = operand_subword (op, 0, 0, dword_mode);
2563 rtx lo = operand_subword (op, 1, 0, dword_mode);
2564 return legitimate_reload_constant_p (hi)
2565 && legitimate_reload_constant_p (lo);
2568 /* Everything else cannot be handled without reload. */
2569 return false;
2572 /* Given an rtx OP being reloaded into a reg required to be in class CLASS,
2573 return the class of reg to actually use. */
2575 enum reg_class
2576 s390_preferred_reload_class (rtx op, enum reg_class class)
2578 switch (GET_CODE (op))
2580 /* Constants we cannot reload must be forced into the
2581 literal pool. */
2583 case CONST_DOUBLE:
2584 case CONST_INT:
2585 if (legitimate_reload_constant_p (op))
2586 return class;
2587 else
2588 return NO_REGS;
2590 /* If a symbolic constant or a PLUS is reloaded,
2591 it is most likely being used as an address, so
2592 prefer ADDR_REGS. If 'class' is not a superset
2593 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
2594 case PLUS:
2595 case LABEL_REF:
2596 case SYMBOL_REF:
2597 case CONST:
2598 if (reg_class_subset_p (ADDR_REGS, class))
2599 return ADDR_REGS;
2600 else
2601 return NO_REGS;
2603 default:
2604 break;
2607 return class;
2610 /* Return the register class of a scratch register needed to
2611 load IN into a register of class CLASS in MODE.
2613 We need a temporary when loading a PLUS expression which
2614 is not a legitimate operand of the LOAD ADDRESS instruction. */
2616 enum reg_class
2617 s390_secondary_input_reload_class (enum reg_class class,
2618 enum machine_mode mode, rtx in)
2620 if (s390_plus_operand (in, mode))
2621 return ADDR_REGS;
2623 if (reg_classes_intersect_p (FP_REGS, class)
2624 && mode == TFmode
2625 && GET_CODE (in) == MEM
2626 && GET_CODE (XEXP (in, 0)) == PLUS
2627 && GET_CODE (XEXP (XEXP (in, 0), 1)) == CONST_INT
2628 && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (in, 0), 1))
2629 + GET_MODE_SIZE (mode) - 1))
2630 return ADDR_REGS;
2632 if (reg_classes_intersect_p (CC_REGS, class))
2633 return GENERAL_REGS;
2635 return NO_REGS;
2638 /* Return the register class of a scratch register needed to
2639 store a register of class CLASS in MODE into OUT:
2641 We need a temporary when storing a double-word to a
2642 non-offsettable memory address. */
2644 enum reg_class
2645 s390_secondary_output_reload_class (enum reg_class class,
2646 enum machine_mode mode, rtx out)
2648 if ((TARGET_64BIT ? (mode == TImode || mode == TFmode)
2649 : (mode == DImode || mode == DFmode))
2650 && reg_classes_intersect_p (GENERAL_REGS, class)
2651 && GET_CODE (out) == MEM
2652 && GET_CODE (XEXP (out, 0)) == PLUS
2653 && GET_CODE (XEXP (XEXP (out, 0), 0)) == PLUS
2654 && GET_CODE (XEXP (XEXP (out, 0), 1)) == CONST_INT
2655 && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (out, 0), 1))
2656 + GET_MODE_SIZE (mode) - 1))
2657 return ADDR_REGS;
2659 if (reg_classes_intersect_p (FP_REGS, class)
2660 && mode == TFmode
2661 && GET_CODE (out) == MEM
2662 && GET_CODE (XEXP (out, 0)) == PLUS
2663 && GET_CODE (XEXP (XEXP (out, 0), 1)) == CONST_INT
2664 && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (out, 0), 1))
2665 + GET_MODE_SIZE (mode) - 1))
2666 return ADDR_REGS;
2668 if (reg_classes_intersect_p (CC_REGS, class))
2669 return GENERAL_REGS;
2671 return NO_REGS;
2674 /* Generate code to load SRC, which is PLUS that is not a
2675 legitimate operand for the LA instruction, into TARGET.
2676 SCRATCH may be used as scratch register. */
2678 void
2679 s390_expand_plus_operand (rtx target, rtx src,
2680 rtx scratch)
2682 rtx sum1, sum2;
2683 struct s390_address ad;
2685 /* src must be a PLUS; get its two operands. */
2686 gcc_assert (GET_CODE (src) == PLUS);
2687 gcc_assert (GET_MODE (src) == Pmode);
2689 /* Check if any of the two operands is already scheduled
2690 for replacement by reload. This can happen e.g. when
2691 float registers occur in an address. */
2692 sum1 = find_replacement (&XEXP (src, 0));
2693 sum2 = find_replacement (&XEXP (src, 1));
2694 src = gen_rtx_PLUS (Pmode, sum1, sum2);
2696 /* If the address is already strictly valid, there's nothing to do. */
2697 if (!s390_decompose_address (src, &ad)
2698 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
2699 || (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx))))
2701 /* Otherwise, one of the operands cannot be an address register;
2702 we reload its value into the scratch register. */
2703 if (true_regnum (sum1) < 1 || true_regnum (sum1) > 15)
2705 emit_move_insn (scratch, sum1);
2706 sum1 = scratch;
2708 if (true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
2710 emit_move_insn (scratch, sum2);
2711 sum2 = scratch;
2714 /* According to the way these invalid addresses are generated
2715 in reload.c, it should never happen (at least on s390) that
2716 *neither* of the PLUS components, after find_replacements
2717 was applied, is an address register. */
2718 if (sum1 == scratch && sum2 == scratch)
2720 debug_rtx (src);
2721 gcc_unreachable ();
2724 src = gen_rtx_PLUS (Pmode, sum1, sum2);
2727 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
2728 is only ever performed on addresses, so we can mark the
2729 sum as legitimate for LA in any case. */
2730 s390_load_address (target, src);
2734 /* Return true if ADDR is a valid memory address.
2735 STRICT specifies whether strict register checking applies. */
2737 bool
2738 legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
2739 rtx addr, int strict)
2741 struct s390_address ad;
2742 if (!s390_decompose_address (addr, &ad))
2743 return false;
2745 if (strict)
2747 if (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
2748 return false;
2750 if (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx)))
2751 return false;
2753 else
2755 if (ad.base
2756 && !(REGNO (ad.base) >= FIRST_PSEUDO_REGISTER
2757 || REGNO_REG_CLASS (REGNO (ad.base)) == ADDR_REGS))
2758 return false;
2760 if (ad.indx
2761 && !(REGNO (ad.indx) >= FIRST_PSEUDO_REGISTER
2762 || REGNO_REG_CLASS (REGNO (ad.indx)) == ADDR_REGS))
2763 return false;
2765 return true;
2768 /* Return true if OP is a valid operand for the LA instruction.
2769 In 31-bit, we need to prove that the result is used as an
2770 address, as LA performs only a 31-bit addition. */
2772 bool
2773 legitimate_la_operand_p (rtx op)
2775 struct s390_address addr;
2776 if (!s390_decompose_address (op, &addr))
2777 return false;
2779 return (TARGET_64BIT || addr.pointer);
2782 /* Return true if it is valid *and* preferable to use LA to
2783 compute the sum of OP1 and OP2. */
2785 bool
2786 preferred_la_operand_p (rtx op1, rtx op2)
2788 struct s390_address addr;
2790 if (op2 != const0_rtx)
2791 op1 = gen_rtx_PLUS (Pmode, op1, op2);
2793 if (!s390_decompose_address (op1, &addr))
2794 return false;
2795 if (addr.base && !REGNO_OK_FOR_BASE_P (REGNO (addr.base)))
2796 return false;
2797 if (addr.indx && !REGNO_OK_FOR_INDEX_P (REGNO (addr.indx)))
2798 return false;
2800 if (!TARGET_64BIT && !addr.pointer)
2801 return false;
2803 if (addr.pointer)
2804 return true;
2806 if ((addr.base && REG_P (addr.base) && REG_POINTER (addr.base))
2807 || (addr.indx && REG_P (addr.indx) && REG_POINTER (addr.indx)))
2808 return true;
2810 return false;
2813 /* Emit a forced load-address operation to load SRC into DST.
2814 This will use the LOAD ADDRESS instruction even in situations
2815 where legitimate_la_operand_p (SRC) returns false. */
2817 void
2818 s390_load_address (rtx dst, rtx src)
2820 if (TARGET_64BIT)
2821 emit_move_insn (dst, src);
2822 else
2823 emit_insn (gen_force_la_31 (dst, src));
2826 /* Return a legitimate reference for ORIG (an address) using the
2827 register REG. If REG is 0, a new pseudo is generated.
2829 There are two types of references that must be handled:
2831 1. Global data references must load the address from the GOT, via
2832 the PIC reg. An insn is emitted to do this load, and the reg is
2833 returned.
2835 2. Static data references, constant pool addresses, and code labels
2836 compute the address as an offset from the GOT, whose base is in
2837 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
2838 differentiate them from global data objects. The returned
2839 address is the PIC reg + an unspec constant.
2841 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2842 reg also appears in the address. */
2845 legitimize_pic_address (rtx orig, rtx reg)
2847 rtx addr = orig;
2848 rtx new = orig;
2849 rtx base;
2851 gcc_assert (!TLS_SYMBOLIC_CONST (addr));
2853 if (GET_CODE (addr) == LABEL_REF
2854 || (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (addr)))
2856 /* This is a local symbol. */
2857 if (TARGET_CPU_ZARCH && larl_operand (addr, VOIDmode))
2859 /* Access local symbols PC-relative via LARL.
2860 This is the same as in the non-PIC case, so it is
2861 handled automatically ... */
2863 else
2865 /* Access local symbols relative to the GOT. */
2867 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2869 if (reload_in_progress || reload_completed)
2870 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2872 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
2873 addr = gen_rtx_CONST (Pmode, addr);
2874 addr = force_const_mem (Pmode, addr);
2875 emit_move_insn (temp, addr);
2877 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2878 if (reg != 0)
2880 s390_load_address (reg, new);
2881 new = reg;
2885 else if (GET_CODE (addr) == SYMBOL_REF)
2887 if (reg == 0)
2888 reg = gen_reg_rtx (Pmode);
2890 if (flag_pic == 1)
2892 /* Assume GOT offset < 4k. This is handled the same way
2893 in both 31- and 64-bit code (@GOT). */
2895 if (reload_in_progress || reload_completed)
2896 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2898 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
2899 new = gen_rtx_CONST (Pmode, new);
2900 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
2901 new = gen_const_mem (Pmode, new);
2902 emit_move_insn (reg, new);
2903 new = reg;
2905 else if (TARGET_CPU_ZARCH)
2907 /* If the GOT offset might be >= 4k, we determine the position
2908 of the GOT entry via a PC-relative LARL (@GOTENT). */
2910 rtx temp = gen_reg_rtx (Pmode);
2912 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTENT);
2913 new = gen_rtx_CONST (Pmode, new);
2914 emit_move_insn (temp, new);
2916 new = gen_const_mem (Pmode, temp);
2917 emit_move_insn (reg, new);
2918 new = reg;
2920 else
2922 /* If the GOT offset might be >= 4k, we have to load it
2923 from the literal pool (@GOT). */
2925 rtx temp = gen_reg_rtx (Pmode);
2927 if (reload_in_progress || reload_completed)
2928 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2930 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
2931 addr = gen_rtx_CONST (Pmode, addr);
2932 addr = force_const_mem (Pmode, addr);
2933 emit_move_insn (temp, addr);
2935 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2936 new = gen_const_mem (Pmode, new);
2937 emit_move_insn (reg, new);
2938 new = reg;
2941 else
2943 if (GET_CODE (addr) == CONST)
2945 addr = XEXP (addr, 0);
2946 if (GET_CODE (addr) == UNSPEC)
2948 gcc_assert (XVECLEN (addr, 0) == 1);
2949 switch (XINT (addr, 1))
2951 /* If someone moved a GOT-relative UNSPEC
2952 out of the literal pool, force them back in. */
2953 case UNSPEC_GOTOFF:
2954 case UNSPEC_PLTOFF:
2955 new = force_const_mem (Pmode, orig);
2956 break;
2958 /* @GOT is OK as is if small. */
2959 case UNSPEC_GOT:
2960 if (flag_pic == 2)
2961 new = force_const_mem (Pmode, orig);
2962 break;
2964 /* @GOTENT is OK as is. */
2965 case UNSPEC_GOTENT:
2966 break;
2968 /* @PLT is OK as is on 64-bit, must be converted to
2969 GOT-relative @PLTOFF on 31-bit. */
2970 case UNSPEC_PLT:
2971 if (!TARGET_CPU_ZARCH)
2973 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2975 if (reload_in_progress || reload_completed)
2976 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2978 addr = XVECEXP (addr, 0, 0);
2979 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
2980 UNSPEC_PLTOFF);
2981 addr = gen_rtx_CONST (Pmode, addr);
2982 addr = force_const_mem (Pmode, addr);
2983 emit_move_insn (temp, addr);
2985 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2986 if (reg != 0)
2988 s390_load_address (reg, new);
2989 new = reg;
2992 break;
2994 /* Everything else cannot happen. */
2995 default:
2996 gcc_unreachable ();
2999 else
3000 gcc_assert (GET_CODE (addr) == PLUS);
3002 if (GET_CODE (addr) == PLUS)
3004 rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
3006 gcc_assert (!TLS_SYMBOLIC_CONST (op0));
3007 gcc_assert (!TLS_SYMBOLIC_CONST (op1));
3009 /* Check first to see if this is a constant offset
3010 from a local symbol reference. */
3011 if ((GET_CODE (op0) == LABEL_REF
3012 || (GET_CODE (op0) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op0)))
3013 && GET_CODE (op1) == CONST_INT)
3015 if (TARGET_CPU_ZARCH && larl_operand (op0, VOIDmode))
3017 if (INTVAL (op1) & 1)
3019 /* LARL can't handle odd offsets, so emit a
3020 pair of LARL and LA. */
3021 rtx temp = reg? reg : gen_reg_rtx (Pmode);
3023 if (!DISP_IN_RANGE (INTVAL (op1)))
3025 int even = INTVAL (op1) - 1;
3026 op0 = gen_rtx_PLUS (Pmode, op0, GEN_INT (even));
3027 op0 = gen_rtx_CONST (Pmode, op0);
3028 op1 = const1_rtx;
3031 emit_move_insn (temp, op0);
3032 new = gen_rtx_PLUS (Pmode, temp, op1);
3034 if (reg != 0)
3036 s390_load_address (reg, new);
3037 new = reg;
3040 else
3042 /* If the offset is even, we can just use LARL.
3043 This will happen automatically. */
3046 else
3048 /* Access local symbols relative to the GOT. */
3050 rtx temp = reg? reg : gen_reg_rtx (Pmode);
3052 if (reload_in_progress || reload_completed)
3053 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
3055 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
3056 UNSPEC_GOTOFF);
3057 addr = gen_rtx_PLUS (Pmode, addr, op1);
3058 addr = gen_rtx_CONST (Pmode, addr);
3059 addr = force_const_mem (Pmode, addr);
3060 emit_move_insn (temp, addr);
3062 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
3063 if (reg != 0)
3065 s390_load_address (reg, new);
3066 new = reg;
3071 /* Now, check whether it is a GOT relative symbol plus offset
3072 that was pulled out of the literal pool. Force it back in. */
3074 else if (GET_CODE (op0) == UNSPEC
3075 && GET_CODE (op1) == CONST_INT
3076 && XINT (op0, 1) == UNSPEC_GOTOFF)
3078 gcc_assert (XVECLEN (op0, 0) == 1);
3080 new = force_const_mem (Pmode, orig);
3083 /* Otherwise, compute the sum. */
3084 else
3086 base = legitimize_pic_address (XEXP (addr, 0), reg);
3087 new = legitimize_pic_address (XEXP (addr, 1),
3088 base == reg ? NULL_RTX : reg);
3089 if (GET_CODE (new) == CONST_INT)
3090 new = plus_constant (base, INTVAL (new));
3091 else
3093 if (GET_CODE (new) == PLUS && CONSTANT_P (XEXP (new, 1)))
3095 base = gen_rtx_PLUS (Pmode, base, XEXP (new, 0));
3096 new = XEXP (new, 1);
3098 new = gen_rtx_PLUS (Pmode, base, new);
3101 if (GET_CODE (new) == CONST)
3102 new = XEXP (new, 0);
3103 new = force_operand (new, 0);
3107 return new;
3110 /* Load the thread pointer into a register. */
3113 s390_get_thread_pointer (void)
3115 rtx tp = gen_reg_rtx (Pmode);
3117 emit_move_insn (tp, gen_rtx_REG (Pmode, TP_REGNUM));
3118 mark_reg_pointer (tp, BITS_PER_WORD);
3120 return tp;
3123 /* Emit a tls call insn. The call target is the SYMBOL_REF stored
3124 in s390_tls_symbol which always refers to __tls_get_offset.
3125 The returned offset is written to RESULT_REG and an USE rtx is
3126 generated for TLS_CALL. */
3128 static GTY(()) rtx s390_tls_symbol;
3130 static void
3131 s390_emit_tls_call_insn (rtx result_reg, rtx tls_call)
3133 rtx insn;
3135 gcc_assert (flag_pic);
3137 if (!s390_tls_symbol)
3138 s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset");
3140 insn = s390_emit_call (s390_tls_symbol, tls_call, result_reg,
3141 gen_rtx_REG (Pmode, RETURN_REGNUM));
3143 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), result_reg);
3144 CONST_OR_PURE_CALL_P (insn) = 1;
3147 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
3148 this (thread-local) address. REG may be used as temporary. */
3150 static rtx
3151 legitimize_tls_address (rtx addr, rtx reg)
3153 rtx new, tls_call, temp, base, r2, insn;
3155 if (GET_CODE (addr) == SYMBOL_REF)
3156 switch (tls_symbolic_operand (addr))
3158 case TLS_MODEL_GLOBAL_DYNAMIC:
3159 start_sequence ();
3160 r2 = gen_rtx_REG (Pmode, 2);
3161 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLSGD);
3162 new = gen_rtx_CONST (Pmode, tls_call);
3163 new = force_const_mem (Pmode, new);
3164 emit_move_insn (r2, new);
3165 s390_emit_tls_call_insn (r2, tls_call);
3166 insn = get_insns ();
3167 end_sequence ();
3169 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
3170 temp = gen_reg_rtx (Pmode);
3171 emit_libcall_block (insn, temp, r2, new);
3173 new = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
3174 if (reg != 0)
3176 s390_load_address (reg, new);
3177 new = reg;
3179 break;
3181 case TLS_MODEL_LOCAL_DYNAMIC:
3182 start_sequence ();
3183 r2 = gen_rtx_REG (Pmode, 2);
3184 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM);
3185 new = gen_rtx_CONST (Pmode, tls_call);
3186 new = force_const_mem (Pmode, new);
3187 emit_move_insn (r2, new);
3188 s390_emit_tls_call_insn (r2, tls_call);
3189 insn = get_insns ();
3190 end_sequence ();
3192 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM_NTPOFF);
3193 temp = gen_reg_rtx (Pmode);
3194 emit_libcall_block (insn, temp, r2, new);
3196 new = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
3197 base = gen_reg_rtx (Pmode);
3198 s390_load_address (base, new);
3200 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_DTPOFF);
3201 new = gen_rtx_CONST (Pmode, new);
3202 new = force_const_mem (Pmode, new);
3203 temp = gen_reg_rtx (Pmode);
3204 emit_move_insn (temp, new);
3206 new = gen_rtx_PLUS (Pmode, base, temp);
3207 if (reg != 0)
3209 s390_load_address (reg, new);
3210 new = reg;
3212 break;
3214 case TLS_MODEL_INITIAL_EXEC:
3215 if (flag_pic == 1)
3217 /* Assume GOT offset < 4k. This is handled the same way
3218 in both 31- and 64-bit code. */
3220 if (reload_in_progress || reload_completed)
3221 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
3223 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
3224 new = gen_rtx_CONST (Pmode, new);
3225 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
3226 new = gen_const_mem (Pmode, new);
3227 temp = gen_reg_rtx (Pmode);
3228 emit_move_insn (temp, new);
3230 else if (TARGET_CPU_ZARCH)
3232 /* If the GOT offset might be >= 4k, we determine the position
3233 of the GOT entry via a PC-relative LARL. */
3235 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
3236 new = gen_rtx_CONST (Pmode, new);
3237 temp = gen_reg_rtx (Pmode);
3238 emit_move_insn (temp, new);
3240 new = gen_const_mem (Pmode, temp);
3241 temp = gen_reg_rtx (Pmode);
3242 emit_move_insn (temp, new);
3244 else if (flag_pic)
3246 /* If the GOT offset might be >= 4k, we have to load it
3247 from the literal pool. */
3249 if (reload_in_progress || reload_completed)
3250 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
3252 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
3253 new = gen_rtx_CONST (Pmode, new);
3254 new = force_const_mem (Pmode, new);
3255 temp = gen_reg_rtx (Pmode);
3256 emit_move_insn (temp, new);
3258 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
3259 new = gen_const_mem (Pmode, new);
3261 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new, addr), UNSPEC_TLS_LOAD);
3262 temp = gen_reg_rtx (Pmode);
3263 emit_insn (gen_rtx_SET (Pmode, temp, new));
3265 else
3267 /* In position-dependent code, load the absolute address of
3268 the GOT entry from the literal pool. */
3270 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
3271 new = gen_rtx_CONST (Pmode, new);
3272 new = force_const_mem (Pmode, new);
3273 temp = gen_reg_rtx (Pmode);
3274 emit_move_insn (temp, new);
3276 new = temp;
3277 new = gen_const_mem (Pmode, new);
3278 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new, addr), UNSPEC_TLS_LOAD);
3279 temp = gen_reg_rtx (Pmode);
3280 emit_insn (gen_rtx_SET (Pmode, temp, new));
3283 new = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
3284 if (reg != 0)
3286 s390_load_address (reg, new);
3287 new = reg;
3289 break;
3291 case TLS_MODEL_LOCAL_EXEC:
3292 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
3293 new = gen_rtx_CONST (Pmode, new);
3294 new = force_const_mem (Pmode, new);
3295 temp = gen_reg_rtx (Pmode);
3296 emit_move_insn (temp, new);
3298 new = gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), temp);
3299 if (reg != 0)
3301 s390_load_address (reg, new);
3302 new = reg;
3304 break;
3306 default:
3307 gcc_unreachable ();
3310 else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == UNSPEC)
3312 switch (XINT (XEXP (addr, 0), 1))
3314 case UNSPEC_INDNTPOFF:
3315 gcc_assert (TARGET_CPU_ZARCH);
3316 new = addr;
3317 break;
3319 default:
3320 gcc_unreachable ();
3324 else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == PLUS
3325 && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
3327 new = XEXP (XEXP (addr, 0), 0);
3328 if (GET_CODE (new) != SYMBOL_REF)
3329 new = gen_rtx_CONST (Pmode, new);
3331 new = legitimize_tls_address (new, reg);
3332 new = plus_constant (new, INTVAL (XEXP (XEXP (addr, 0), 1)));
3333 new = force_operand (new, 0);
3336 else
3337 gcc_unreachable (); /* for now ... */
3339 return new;
3342 /* Emit insns to move operands[1] into operands[0]. */
3344 void
3345 emit_symbolic_move (rtx *operands)
3347 rtx temp = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
3349 if (GET_CODE (operands[0]) == MEM)
3350 operands[1] = force_reg (Pmode, operands[1]);
3351 else if (TLS_SYMBOLIC_CONST (operands[1]))
3352 operands[1] = legitimize_tls_address (operands[1], temp);
3353 else if (flag_pic)
3354 operands[1] = legitimize_pic_address (operands[1], temp);
3357 /* Try machine-dependent ways of modifying an illegitimate address X
3358 to be legitimate. If we find one, return the new, valid address.
3360 OLDX is the address as it was before break_out_memory_refs was called.
3361 In some cases it is useful to look at this to decide what needs to be done.
3363 MODE is the mode of the operand pointed to by X.
3365 When -fpic is used, special handling is needed for symbolic references.
3366 See comments by legitimize_pic_address for details. */
3369 legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
3370 enum machine_mode mode ATTRIBUTE_UNUSED)
3372 rtx constant_term = const0_rtx;
3374 if (TLS_SYMBOLIC_CONST (x))
3376 x = legitimize_tls_address (x, 0);
3378 if (legitimate_address_p (mode, x, FALSE))
3379 return x;
3381 else if (GET_CODE (x) == PLUS
3382 && (TLS_SYMBOLIC_CONST (XEXP (x, 0))
3383 || TLS_SYMBOLIC_CONST (XEXP (x, 1))))
3385 return x;
3387 else if (flag_pic)
3389 if (SYMBOLIC_CONST (x)
3390 || (GET_CODE (x) == PLUS
3391 && (SYMBOLIC_CONST (XEXP (x, 0))
3392 || SYMBOLIC_CONST (XEXP (x, 1)))))
3393 x = legitimize_pic_address (x, 0);
3395 if (legitimate_address_p (mode, x, FALSE))
3396 return x;
3399 x = eliminate_constant_term (x, &constant_term);
3401 /* Optimize loading of large displacements by splitting them
3402 into the multiple of 4K and the rest; this allows the
3403 former to be CSE'd if possible.
3405 Don't do this if the displacement is added to a register
3406 pointing into the stack frame, as the offsets will
3407 change later anyway. */
3409 if (GET_CODE (constant_term) == CONST_INT
3410 && !TARGET_LONG_DISPLACEMENT
3411 && !DISP_IN_RANGE (INTVAL (constant_term))
3412 && !(REG_P (x) && REGNO_PTR_FRAME_P (REGNO (x))))
3414 HOST_WIDE_INT lower = INTVAL (constant_term) & 0xfff;
3415 HOST_WIDE_INT upper = INTVAL (constant_term) ^ lower;
3417 rtx temp = gen_reg_rtx (Pmode);
3418 rtx val = force_operand (GEN_INT (upper), temp);
3419 if (val != temp)
3420 emit_move_insn (temp, val);
3422 x = gen_rtx_PLUS (Pmode, x, temp);
3423 constant_term = GEN_INT (lower);
3426 if (GET_CODE (x) == PLUS)
3428 if (GET_CODE (XEXP (x, 0)) == REG)
3430 rtx temp = gen_reg_rtx (Pmode);
3431 rtx val = force_operand (XEXP (x, 1), temp);
3432 if (val != temp)
3433 emit_move_insn (temp, val);
3435 x = gen_rtx_PLUS (Pmode, XEXP (x, 0), temp);
3438 else if (GET_CODE (XEXP (x, 1)) == REG)
3440 rtx temp = gen_reg_rtx (Pmode);
3441 rtx val = force_operand (XEXP (x, 0), temp);
3442 if (val != temp)
3443 emit_move_insn (temp, val);
3445 x = gen_rtx_PLUS (Pmode, temp, XEXP (x, 1));
3449 if (constant_term != const0_rtx)
3450 x = gen_rtx_PLUS (Pmode, x, constant_term);
3452 return x;
3455 /* Try a machine-dependent way of reloading an illegitimate address AD
3456 operand. If we find one, push the reload and and return the new address.
3458 MODE is the mode of the enclosing MEM. OPNUM is the operand number
3459 and TYPE is the reload type of the current reload. */
3461 rtx
3462 legitimize_reload_address (rtx ad, enum machine_mode mode ATTRIBUTE_UNUSED,
3463 int opnum, int type)
3465 if (!optimize || TARGET_LONG_DISPLACEMENT)
3466 return NULL_RTX;
3468 if (GET_CODE (ad) == PLUS)
3470 rtx tem = simplify_binary_operation (PLUS, Pmode,
3471 XEXP (ad, 0), XEXP (ad, 1));
3472 if (tem)
3473 ad = tem;
3476 if (GET_CODE (ad) == PLUS
3477 && GET_CODE (XEXP (ad, 0)) == REG
3478 && GET_CODE (XEXP (ad, 1)) == CONST_INT
3479 && !DISP_IN_RANGE (INTVAL (XEXP (ad, 1))))
3481 HOST_WIDE_INT lower = INTVAL (XEXP (ad, 1)) & 0xfff;
3482 HOST_WIDE_INT upper = INTVAL (XEXP (ad, 1)) ^ lower;
3483 rtx cst, tem, new;
3485 cst = GEN_INT (upper);
3486 if (!legitimate_reload_constant_p (cst))
3487 cst = force_const_mem (Pmode, cst);
3489 tem = gen_rtx_PLUS (Pmode, XEXP (ad, 0), cst);
3490 new = gen_rtx_PLUS (Pmode, tem, GEN_INT (lower));
3492 push_reload (XEXP (tem, 1), 0, &XEXP (tem, 1), 0,
3493 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3494 opnum, (enum reload_type) type);
3495 return new;
3498 return NULL_RTX;
3501 /* Emit code to move LEN bytes from DST to SRC. */
3503 void
3504 s390_expand_movmem (rtx dst, rtx src, rtx len)
3506 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
3508 if (INTVAL (len) > 0)
3509 emit_insn (gen_movmem_short (dst, src, GEN_INT (INTVAL (len) - 1)));
3512 else if (TARGET_MVCLE)
3514 emit_insn (gen_movmem_long (dst, src, convert_to_mode (Pmode, len, 1)));
3517 else
3519 rtx dst_addr, src_addr, count, blocks, temp;
3520 rtx loop_start_label = gen_label_rtx ();
3521 rtx loop_end_label = gen_label_rtx ();
3522 rtx end_label = gen_label_rtx ();
3523 enum machine_mode mode;
3525 mode = GET_MODE (len);
3526 if (mode == VOIDmode)
3527 mode = Pmode;
3529 dst_addr = gen_reg_rtx (Pmode);
3530 src_addr = gen_reg_rtx (Pmode);
3531 count = gen_reg_rtx (mode);
3532 blocks = gen_reg_rtx (mode);
3534 convert_move (count, len, 1);
3535 emit_cmp_and_jump_insns (count, const0_rtx,
3536 EQ, NULL_RTX, mode, 1, end_label);
3538 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
3539 emit_move_insn (src_addr, force_operand (XEXP (src, 0), NULL_RTX));
3540 dst = change_address (dst, VOIDmode, dst_addr);
3541 src = change_address (src, VOIDmode, src_addr);
3543 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3544 if (temp != count)
3545 emit_move_insn (count, temp);
3547 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
3548 if (temp != blocks)
3549 emit_move_insn (blocks, temp);
3551 emit_cmp_and_jump_insns (blocks, const0_rtx,
3552 EQ, NULL_RTX, mode, 1, loop_end_label);
3554 emit_label (loop_start_label);
3556 emit_insn (gen_movmem_short (dst, src, GEN_INT (255)));
3557 s390_load_address (dst_addr,
3558 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
3559 s390_load_address (src_addr,
3560 gen_rtx_PLUS (Pmode, src_addr, GEN_INT (256)));
3562 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3563 if (temp != blocks)
3564 emit_move_insn (blocks, temp);
3566 emit_cmp_and_jump_insns (blocks, const0_rtx,
3567 EQ, NULL_RTX, mode, 1, loop_end_label);
3569 emit_jump (loop_start_label);
3570 emit_label (loop_end_label);
3572 emit_insn (gen_movmem_short (dst, src,
3573 convert_to_mode (Pmode, count, 1)));
3574 emit_label (end_label);
3578 /* Emit code to set LEN bytes at DST to VAL.
3579 Make use of clrmem if VAL is zero. */
3581 void
3582 s390_expand_setmem (rtx dst, rtx len, rtx val)
3584 gcc_assert (GET_CODE (len) != CONST_INT || INTVAL (len) > 0);
3585 gcc_assert (GET_CODE (val) == CONST_INT || GET_MODE (val) == QImode);
3587 if (GET_CODE (len) == CONST_INT && INTVAL (len) <= 257)
3589 if (val == const0_rtx && INTVAL (len) <= 256)
3590 emit_insn (gen_clrmem_short (dst, GEN_INT (INTVAL (len) - 1)));
3591 else
3593 /* Initialize memory by storing the first byte. */
3594 emit_move_insn (adjust_address (dst, QImode, 0), val);
3596 if (INTVAL (len) > 1)
3598 /* Initiate 1 byte overlap move.
3599 The first byte of DST is propagated through DSTP1.
3600 Prepare a movmem for: DST+1 = DST (length = LEN - 1).
3601 DST is set to size 1 so the rest of the memory location
3602 does not count as source operand. */
3603 rtx dstp1 = adjust_address (dst, VOIDmode, 1);
3604 set_mem_size (dst, const1_rtx);
3606 emit_insn (gen_movmem_short (dstp1, dst,
3607 GEN_INT (INTVAL (len) - 2)));
3612 else if (TARGET_MVCLE)
3614 val = force_not_mem (convert_modes (Pmode, QImode, val, 1));
3615 emit_insn (gen_setmem_long (dst, convert_to_mode (Pmode, len, 1), val));
3618 else
3620 rtx dst_addr, src_addr, count, blocks, temp, dstp1 = NULL_RTX;
3621 rtx loop_start_label = gen_label_rtx ();
3622 rtx loop_end_label = gen_label_rtx ();
3623 rtx end_label = gen_label_rtx ();
3624 enum machine_mode mode;
3626 mode = GET_MODE (len);
3627 if (mode == VOIDmode)
3628 mode = Pmode;
3630 dst_addr = gen_reg_rtx (Pmode);
3631 src_addr = gen_reg_rtx (Pmode);
3632 count = gen_reg_rtx (mode);
3633 blocks = gen_reg_rtx (mode);
3635 convert_move (count, len, 1);
3636 emit_cmp_and_jump_insns (count, const0_rtx,
3637 EQ, NULL_RTX, mode, 1, end_label);
3639 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
3640 dst = change_address (dst, VOIDmode, dst_addr);
3642 if (val == const0_rtx)
3643 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3644 else
3646 dstp1 = adjust_address (dst, VOIDmode, 1);
3647 set_mem_size (dst, const1_rtx);
3649 /* Initialize memory by storing the first byte. */
3650 emit_move_insn (adjust_address (dst, QImode, 0), val);
3652 /* If count is 1 we are done. */
3653 emit_cmp_and_jump_insns (count, const1_rtx,
3654 EQ, NULL_RTX, mode, 1, end_label);
3656 temp = expand_binop (mode, add_optab, count, GEN_INT (-2), count, 1, 0);
3658 if (temp != count)
3659 emit_move_insn (count, temp);
3661 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
3662 if (temp != blocks)
3663 emit_move_insn (blocks, temp);
3665 emit_cmp_and_jump_insns (blocks, const0_rtx,
3666 EQ, NULL_RTX, mode, 1, loop_end_label);
3668 emit_label (loop_start_label);
3670 if (val == const0_rtx)
3671 emit_insn (gen_clrmem_short (dst, GEN_INT (255)));
3672 else
3673 emit_insn (gen_movmem_short (dstp1, dst, GEN_INT (255)));
3674 s390_load_address (dst_addr,
3675 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
3677 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3678 if (temp != blocks)
3679 emit_move_insn (blocks, temp);
3681 emit_cmp_and_jump_insns (blocks, const0_rtx,
3682 EQ, NULL_RTX, mode, 1, loop_end_label);
3684 emit_jump (loop_start_label);
3685 emit_label (loop_end_label);
3687 if (val == const0_rtx)
3688 emit_insn (gen_clrmem_short (dst, convert_to_mode (Pmode, count, 1)));
3689 else
3690 emit_insn (gen_movmem_short (dstp1, dst, convert_to_mode (Pmode, count, 1)));
3691 emit_label (end_label);
3695 /* Emit code to compare LEN bytes at OP0 with those at OP1,
3696 and return the result in TARGET. */
3698 void
3699 s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
3701 rtx ccreg = gen_rtx_REG (CCUmode, CC_REGNUM);
3702 rtx tmp;
3704 /* As the result of CMPINT is inverted compared to what we need,
3705 we have to swap the operands. */
3706 tmp = op0; op0 = op1; op1 = tmp;
3708 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
3710 if (INTVAL (len) > 0)
3712 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (INTVAL (len) - 1)));
3713 emit_insn (gen_cmpint (target, ccreg));
3715 else
3716 emit_move_insn (target, const0_rtx);
3718 else if (TARGET_MVCLE)
3720 emit_insn (gen_cmpmem_long (op0, op1, convert_to_mode (Pmode, len, 1)));
3721 emit_insn (gen_cmpint (target, ccreg));
3723 else
3725 rtx addr0, addr1, count, blocks, temp;
3726 rtx loop_start_label = gen_label_rtx ();
3727 rtx loop_end_label = gen_label_rtx ();
3728 rtx end_label = gen_label_rtx ();
3729 enum machine_mode mode;
3731 mode = GET_MODE (len);
3732 if (mode == VOIDmode)
3733 mode = Pmode;
3735 addr0 = gen_reg_rtx (Pmode);
3736 addr1 = gen_reg_rtx (Pmode);
3737 count = gen_reg_rtx (mode);
3738 blocks = gen_reg_rtx (mode);
3740 convert_move (count, len, 1);
3741 emit_cmp_and_jump_insns (count, const0_rtx,
3742 EQ, NULL_RTX, mode, 1, end_label);
3744 emit_move_insn (addr0, force_operand (XEXP (op0, 0), NULL_RTX));
3745 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
3746 op0 = change_address (op0, VOIDmode, addr0);
3747 op1 = change_address (op1, VOIDmode, addr1);
3749 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3750 if (temp != count)
3751 emit_move_insn (count, temp);
3753 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
3754 if (temp != blocks)
3755 emit_move_insn (blocks, temp);
3757 emit_cmp_and_jump_insns (blocks, const0_rtx,
3758 EQ, NULL_RTX, mode, 1, loop_end_label);
3760 emit_label (loop_start_label);
3762 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (255)));
3763 temp = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
3764 temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
3765 gen_rtx_LABEL_REF (VOIDmode, end_label), pc_rtx);
3766 temp = gen_rtx_SET (VOIDmode, pc_rtx, temp);
3767 emit_jump_insn (temp);
3769 s390_load_address (addr0,
3770 gen_rtx_PLUS (Pmode, addr0, GEN_INT (256)));
3771 s390_load_address (addr1,
3772 gen_rtx_PLUS (Pmode, addr1, GEN_INT (256)));
3774 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3775 if (temp != blocks)
3776 emit_move_insn (blocks, temp);
3778 emit_cmp_and_jump_insns (blocks, const0_rtx,
3779 EQ, NULL_RTX, mode, 1, loop_end_label);
3781 emit_jump (loop_start_label);
3782 emit_label (loop_end_label);
3784 emit_insn (gen_cmpmem_short (op0, op1,
3785 convert_to_mode (Pmode, count, 1)));
3786 emit_label (end_label);
3788 emit_insn (gen_cmpint (target, ccreg));
3793 /* Expand conditional increment or decrement using alc/slb instructions.
3794 Should generate code setting DST to either SRC or SRC + INCREMENT,
3795 depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
3796 Returns true if successful, false otherwise.
3798 That makes it possible to implement some if-constructs without jumps e.g.:
3799 (borrow = CC0 | CC1 and carry = CC2 | CC3)
3800 unsigned int a, b, c;
3801 if (a < b) c++; -> CCU b > a -> CC2; c += carry;
3802 if (a < b) c--; -> CCL3 a - b -> borrow; c -= borrow;
3803 if (a <= b) c++; -> CCL3 b - a -> borrow; c += carry;
3804 if (a <= b) c--; -> CCU a <= b -> borrow; c -= borrow;
3806 Checks for EQ and NE with a nonzero value need an additional xor e.g.:
3807 if (a == b) c++; -> CCL3 a ^= b; 0 - a -> borrow; c += carry;
3808 if (a == b) c--; -> CCU a ^= b; a <= 0 -> CC0 | CC1; c -= borrow;
3809 if (a != b) c++; -> CCU a ^= b; a > 0 -> CC2; c += carry;
3810 if (a != b) c--; -> CCL3 a ^= b; 0 - a -> borrow; c -= borrow; */
3812 bool
3813 s390_expand_addcc (enum rtx_code cmp_code, rtx cmp_op0, rtx cmp_op1,
3814 rtx dst, rtx src, rtx increment)
3816 enum machine_mode cmp_mode;
3817 enum machine_mode cc_mode;
3818 rtx op_res;
3819 rtx insn;
3820 rtvec p;
3821 int ret;
3823 if ((GET_MODE (cmp_op0) == SImode || GET_MODE (cmp_op0) == VOIDmode)
3824 && (GET_MODE (cmp_op1) == SImode || GET_MODE (cmp_op1) == VOIDmode))
3825 cmp_mode = SImode;
3826 else if ((GET_MODE (cmp_op0) == DImode || GET_MODE (cmp_op0) == VOIDmode)
3827 && (GET_MODE (cmp_op1) == DImode || GET_MODE (cmp_op1) == VOIDmode))
3828 cmp_mode = DImode;
3829 else
3830 return false;
3832 /* Try ADD LOGICAL WITH CARRY. */
3833 if (increment == const1_rtx)
3835 /* Determine CC mode to use. */
3836 if (cmp_code == EQ || cmp_code == NE)
3838 if (cmp_op1 != const0_rtx)
3840 cmp_op0 = expand_simple_binop (cmp_mode, XOR, cmp_op0, cmp_op1,
3841 NULL_RTX, 0, OPTAB_WIDEN);
3842 cmp_op1 = const0_rtx;
3845 cmp_code = cmp_code == EQ ? LEU : GTU;
3848 if (cmp_code == LTU || cmp_code == LEU)
3850 rtx tem = cmp_op0;
3851 cmp_op0 = cmp_op1;
3852 cmp_op1 = tem;
3853 cmp_code = swap_condition (cmp_code);
3856 switch (cmp_code)
3858 case GTU:
3859 cc_mode = CCUmode;
3860 break;
3862 case GEU:
3863 cc_mode = CCL3mode;
3864 break;
3866 default:
3867 return false;
3870 /* Emit comparison instruction pattern. */
3871 if (!register_operand (cmp_op0, cmp_mode))
3872 cmp_op0 = force_reg (cmp_mode, cmp_op0);
3874 insn = gen_rtx_SET (VOIDmode, gen_rtx_REG (cc_mode, CC_REGNUM),
3875 gen_rtx_COMPARE (cc_mode, cmp_op0, cmp_op1));
3876 /* We use insn_invalid_p here to add clobbers if required. */
3877 ret = insn_invalid_p (emit_insn (insn));
3878 gcc_assert (!ret);
3880 /* Emit ALC instruction pattern. */
3881 op_res = gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
3882 gen_rtx_REG (cc_mode, CC_REGNUM),
3883 const0_rtx);
3885 if (src != const0_rtx)
3887 if (!register_operand (src, GET_MODE (dst)))
3888 src = force_reg (GET_MODE (dst), src);
3890 src = gen_rtx_PLUS (GET_MODE (dst), src, const0_rtx);
3891 op_res = gen_rtx_PLUS (GET_MODE (dst), src, op_res);
3894 p = rtvec_alloc (2);
3895 RTVEC_ELT (p, 0) =
3896 gen_rtx_SET (VOIDmode, dst, op_res);
3897 RTVEC_ELT (p, 1) =
3898 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
3899 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
3901 return true;
3904 /* Try SUBTRACT LOGICAL WITH BORROW. */
3905 if (increment == constm1_rtx)
3907 /* Determine CC mode to use. */
3908 if (cmp_code == EQ || cmp_code == NE)
3910 if (cmp_op1 != const0_rtx)
3912 cmp_op0 = expand_simple_binop (cmp_mode, XOR, cmp_op0, cmp_op1,
3913 NULL_RTX, 0, OPTAB_WIDEN);
3914 cmp_op1 = const0_rtx;
3917 cmp_code = cmp_code == EQ ? LEU : GTU;
3920 if (cmp_code == GTU || cmp_code == GEU)
3922 rtx tem = cmp_op0;
3923 cmp_op0 = cmp_op1;
3924 cmp_op1 = tem;
3925 cmp_code = swap_condition (cmp_code);
3928 switch (cmp_code)
3930 case LEU:
3931 cc_mode = CCUmode;
3932 break;
3934 case LTU:
3935 cc_mode = CCL3mode;
3936 break;
3938 default:
3939 return false;
3942 /* Emit comparison instruction pattern. */
3943 if (!register_operand (cmp_op0, cmp_mode))
3944 cmp_op0 = force_reg (cmp_mode, cmp_op0);
3946 insn = gen_rtx_SET (VOIDmode, gen_rtx_REG (cc_mode, CC_REGNUM),
3947 gen_rtx_COMPARE (cc_mode, cmp_op0, cmp_op1));
3948 /* We use insn_invalid_p here to add clobbers if required. */
3949 ret = insn_invalid_p (emit_insn (insn));
3950 gcc_assert (!ret);
3952 /* Emit SLB instruction pattern. */
3953 if (!register_operand (src, GET_MODE (dst)))
3954 src = force_reg (GET_MODE (dst), src);
3956 op_res = gen_rtx_MINUS (GET_MODE (dst),
3957 gen_rtx_MINUS (GET_MODE (dst), src, const0_rtx),
3958 gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
3959 gen_rtx_REG (cc_mode, CC_REGNUM),
3960 const0_rtx));
3961 p = rtvec_alloc (2);
3962 RTVEC_ELT (p, 0) =
3963 gen_rtx_SET (VOIDmode, dst, op_res);
3964 RTVEC_ELT (p, 1) =
3965 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
3966 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
3968 return true;
3971 return false;
3974 /* Expand code for the insv template. Return true if successful, false else. */
3976 bool
3977 s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src)
3979 int bitsize = INTVAL (op1);
3980 int bitpos = INTVAL (op2);
3982 /* We need byte alignment. */
3983 if (bitsize % BITS_PER_UNIT)
3984 return false;
3986 if (bitpos == 0
3987 && memory_operand (dest, VOIDmode)
3988 && (register_operand (src, word_mode)
3989 || const_int_operand (src, VOIDmode)))
3991 /* Emit standard pattern if possible. */
3992 enum machine_mode mode = smallest_mode_for_size (bitsize, MODE_INT);
3993 if (GET_MODE_BITSIZE (mode) == bitsize)
3994 emit_move_insn (adjust_address (dest, mode, 0), gen_lowpart (mode, src));
3996 /* (set (ze (mem)) (const_int)). */
3997 else if (const_int_operand (src, VOIDmode))
3999 int size = bitsize / BITS_PER_UNIT;
4000 rtx src_mem = adjust_address (force_const_mem (word_mode, src), BLKmode,
4001 GET_MODE_SIZE (word_mode) - size);
4003 dest = adjust_address (dest, BLKmode, 0);
4004 set_mem_size (dest, GEN_INT (size));
4005 s390_expand_movmem (dest, src_mem, GEN_INT (size));
4008 /* (set (ze (mem)) (reg)). */
4009 else if (register_operand (src, word_mode))
4011 if (bitsize <= GET_MODE_BITSIZE (SImode))
4012 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest, op1,
4013 const0_rtx), src);
4014 else
4016 /* Emit st,stcmh sequence. */
4017 int stcmh_width = bitsize - GET_MODE_BITSIZE (SImode);
4018 int size = stcmh_width / BITS_PER_UNIT;
4020 emit_move_insn (adjust_address (dest, SImode, size),
4021 gen_lowpart (SImode, src));
4022 set_mem_size (dest, GEN_INT (size));
4023 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest, GEN_INT
4024 (stcmh_width), const0_rtx),
4025 gen_rtx_LSHIFTRT (word_mode, src, GEN_INT
4026 (GET_MODE_BITSIZE (SImode))));
4029 else
4030 return false;
4032 return true;
4035 /* (set (ze (reg)) (const_int)). */
4036 if (TARGET_ZARCH
4037 && register_operand (dest, word_mode)
4038 && (bitpos % 16) == 0
4039 && (bitsize % 16) == 0
4040 && const_int_operand (src, VOIDmode))
4042 HOST_WIDE_INT val = INTVAL (src);
4043 int regpos = bitpos + bitsize;
4045 while (regpos > bitpos)
4047 enum machine_mode putmode;
4048 int putsize;
4050 if (TARGET_EXTIMM && (regpos % 32 == 0) && (regpos >= bitpos + 32))
4051 putmode = SImode;
4052 else
4053 putmode = HImode;
4055 putsize = GET_MODE_BITSIZE (putmode);
4056 regpos -= putsize;
4057 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest,
4058 GEN_INT (putsize),
4059 GEN_INT (regpos)),
4060 gen_int_mode (val, putmode));
4061 val >>= putsize;
4063 gcc_assert (regpos == bitpos);
4064 return true;
4067 return false;
4070 /* A subroutine of s390_expand_cs_hqi and s390_expand_atomic which returns a
4071 register that holds VAL of mode MODE shifted by COUNT bits. */
4073 static inline rtx
4074 s390_expand_mask_and_shift (rtx val, enum machine_mode mode, rtx count)
4076 val = expand_simple_binop (SImode, AND, val, GEN_INT (GET_MODE_MASK (mode)),
4077 NULL_RTX, 1, OPTAB_DIRECT);
4078 return expand_simple_binop (SImode, ASHIFT, val, count,
4079 NULL_RTX, 1, OPTAB_DIRECT);
4082 /* Structure to hold the initial parameters for a compare_and_swap operation
4083 in HImode and QImode. */
4085 struct alignment_context
4087 rtx memsi; /* SI aligned memory location. */
4088 rtx shift; /* Bit offset with regard to lsb. */
4089 rtx modemask; /* Mask of the HQImode shifted by SHIFT bits. */
4090 rtx modemaski; /* ~modemask */
4091 bool aligned; /* True if memory is aligned, false else. */
4094 /* A subroutine of s390_expand_cs_hqi and s390_expand_atomic to initialize
4095 structure AC for transparent simplifying, if the memory alignment is known
4096 to be at least 32bit. MEM is the memory location for the actual operation
4097 and MODE its mode. */
4099 static void
4100 init_alignment_context (struct alignment_context *ac, rtx mem,
4101 enum machine_mode mode)
4103 ac->shift = GEN_INT (GET_MODE_SIZE (SImode) - GET_MODE_SIZE (mode));
4104 ac->aligned = (MEM_ALIGN (mem) >= GET_MODE_BITSIZE (SImode));
4106 if (ac->aligned)
4107 ac->memsi = adjust_address (mem, SImode, 0); /* Memory is aligned. */
4108 else
4110 /* Alignment is unknown. */
4111 rtx byteoffset, addr, align;
4113 /* Force the address into a register. */
4114 addr = force_reg (Pmode, XEXP (mem, 0));
4116 /* Align it to SImode. */
4117 align = expand_simple_binop (Pmode, AND, addr,
4118 GEN_INT (-GET_MODE_SIZE (SImode)),
4119 NULL_RTX, 1, OPTAB_DIRECT);
4120 /* Generate MEM. */
4121 ac->memsi = gen_rtx_MEM (SImode, align);
4122 MEM_VOLATILE_P (ac->memsi) = MEM_VOLATILE_P (mem);
4123 set_mem_alias_set (ac->memsi, ALIAS_SET_MEMORY_BARRIER);
4124 set_mem_align (ac->memsi, GET_MODE_BITSIZE (SImode));
4126 /* Calculate shiftcount. */
4127 byteoffset = expand_simple_binop (Pmode, AND, addr,
4128 GEN_INT (GET_MODE_SIZE (SImode) - 1),
4129 NULL_RTX, 1, OPTAB_DIRECT);
4130 /* As we already have some offset, evaluate the remaining distance. */
4131 ac->shift = expand_simple_binop (SImode, MINUS, ac->shift, byteoffset,
4132 NULL_RTX, 1, OPTAB_DIRECT);
4135 /* Shift is the byte count, but we need the bitcount. */
4136 ac->shift = expand_simple_binop (SImode, MULT, ac->shift, GEN_INT (BITS_PER_UNIT),
4137 NULL_RTX, 1, OPTAB_DIRECT);
4138 /* Calculate masks. */
4139 ac->modemask = expand_simple_binop (SImode, ASHIFT,
4140 GEN_INT (GET_MODE_MASK (mode)), ac->shift,
4141 NULL_RTX, 1, OPTAB_DIRECT);
4142 ac->modemaski = expand_simple_unop (SImode, NOT, ac->modemask, NULL_RTX, 1);
4145 /* Expand an atomic compare and swap operation for HImode and QImode. MEM is
4146 the memory location, CMP the old value to compare MEM with and NEW the value
4147 to set if CMP == MEM.
4148 CMP is never in memory for compare_and_swap_cc because
4149 expand_bool_compare_and_swap puts it into a register for later compare. */
4151 void
4152 s390_expand_cs_hqi (enum machine_mode mode, rtx target, rtx mem, rtx cmp, rtx new)
4154 struct alignment_context ac;
4155 rtx cmpv, newv, val, resv, cc;
4156 rtx res = gen_reg_rtx (SImode);
4157 rtx csloop = gen_label_rtx ();
4158 rtx csend = gen_label_rtx ();
4160 gcc_assert (register_operand (target, VOIDmode));
4161 gcc_assert (MEM_P (mem));
4163 init_alignment_context (&ac, mem, mode);
4165 /* Shift the values to the correct bit positions. */
4166 if (!(ac.aligned && MEM_P (cmp)))
4167 cmp = s390_expand_mask_and_shift (cmp, mode, ac.shift);
4168 if (!(ac.aligned && MEM_P (new)))
4169 new = s390_expand_mask_and_shift (new, mode, ac.shift);
4171 /* Load full word. Subsequent loads are performed by CS. */
4172 val = expand_simple_binop (SImode, AND, ac.memsi, ac.modemaski,
4173 NULL_RTX, 1, OPTAB_DIRECT);
4175 /* Start CS loop. */
4176 emit_label (csloop);
4177 /* val = "<mem>00..0<mem>"
4178 * cmp = "00..0<cmp>00..0"
4179 * new = "00..0<new>00..0"
4182 /* Patch cmp and new with val at correct position. */
4183 if (ac.aligned && MEM_P (cmp))
4185 cmpv = force_reg (SImode, val);
4186 store_bit_field (cmpv, GET_MODE_BITSIZE (mode), 0, SImode, cmp);
4188 else
4189 cmpv = force_reg (SImode, expand_simple_binop (SImode, IOR, cmp, val,
4190 NULL_RTX, 1, OPTAB_DIRECT));
4191 if (ac.aligned && MEM_P (new))
4193 newv = force_reg (SImode, val);
4194 store_bit_field (newv, GET_MODE_BITSIZE (mode), 0, SImode, new);
4196 else
4197 newv = force_reg (SImode, expand_simple_binop (SImode, IOR, new, val,
4198 NULL_RTX, 1, OPTAB_DIRECT));
4200 /* Emit compare_and_swap pattern. */
4201 emit_insn (gen_sync_compare_and_swap_ccsi (res, ac.memsi, cmpv, newv));
4203 /* Jump to end if we're done (likely?). */
4204 s390_emit_jump (csend, s390_emit_compare (EQ, cmpv, ac.memsi));
4206 /* Check for changes outside mode. */
4207 resv = expand_simple_binop (SImode, AND, res, ac.modemaski,
4208 NULL_RTX, 1, OPTAB_DIRECT);
4209 cc = s390_emit_compare (NE, resv, val);
4210 emit_move_insn (val, resv);
4211 /* Loop internal if so. */
4212 s390_emit_jump (csloop, cc);
4214 emit_label (csend);
4216 /* Return the correct part of the bitfield. */
4217 convert_move (target, expand_simple_binop (SImode, LSHIFTRT, res, ac.shift,
4218 NULL_RTX, 1, OPTAB_DIRECT), 1);
4221 /* Expand an atomic operation CODE of mode MODE. MEM is the memory location
4222 and VAL the value to play with. If AFTER is true then store the the value
4223 MEM holds after the operation, if AFTER is false then store the value MEM
4224 holds before the operation. If TARGET is zero then discard that value, else
4225 store it to TARGET. */
4227 void
4228 s390_expand_atomic (enum machine_mode mode, enum rtx_code code,
4229 rtx target, rtx mem, rtx val, bool after)
4231 struct alignment_context ac;
4232 rtx cmp;
4233 rtx new = gen_reg_rtx (SImode);
4234 rtx orig = gen_reg_rtx (SImode);
4235 rtx csloop = gen_label_rtx ();
4237 gcc_assert (!target || register_operand (target, VOIDmode));
4238 gcc_assert (MEM_P (mem));
4240 init_alignment_context (&ac, mem, mode);
4242 /* Shift val to the correct bit positions.
4243 Preserve "icm", but prevent "ex icm". */
4244 if (!(ac.aligned && code == SET && MEM_P (val)))
4245 val = s390_expand_mask_and_shift (val, mode, ac.shift);
4247 /* Further preparation insns. */
4248 if (code == PLUS || code == MINUS)
4249 emit_move_insn (orig, val);
4250 else if (code == MULT || code == AND) /* val = "11..1<val>11..1" */
4251 val = expand_simple_binop (SImode, XOR, val, ac.modemaski,
4252 NULL_RTX, 1, OPTAB_DIRECT);
4254 /* Load full word. Subsequent loads are performed by CS. */
4255 cmp = force_reg (SImode, ac.memsi);
4257 /* Start CS loop. */
4258 emit_label (csloop);
4259 emit_move_insn (new, cmp);
4261 /* Patch new with val at correct position. */
4262 switch (code)
4264 case PLUS:
4265 case MINUS:
4266 val = expand_simple_binop (SImode, code, new, orig,
4267 NULL_RTX, 1, OPTAB_DIRECT);
4268 val = expand_simple_binop (SImode, AND, val, ac.modemask,
4269 NULL_RTX, 1, OPTAB_DIRECT);
4270 /* FALLTHRU */
4271 case SET:
4272 if (ac.aligned && MEM_P (val))
4273 store_bit_field (new, GET_MODE_BITSIZE (mode), 0, SImode, val);
4274 else
4276 new = expand_simple_binop (SImode, AND, new, ac.modemaski,
4277 NULL_RTX, 1, OPTAB_DIRECT);
4278 new = expand_simple_binop (SImode, IOR, new, val,
4279 NULL_RTX, 1, OPTAB_DIRECT);
4281 break;
4282 case AND:
4283 case IOR:
4284 case XOR:
4285 new = expand_simple_binop (SImode, code, new, val,
4286 NULL_RTX, 1, OPTAB_DIRECT);
4287 break;
4288 case MULT: /* NAND */
4289 new = expand_simple_binop (SImode, XOR, new, ac.modemask,
4290 NULL_RTX, 1, OPTAB_DIRECT);
4291 new = expand_simple_binop (SImode, AND, new, val,
4292 NULL_RTX, 1, OPTAB_DIRECT);
4293 break;
4294 default:
4295 gcc_unreachable ();
4297 /* Emit compare_and_swap pattern. */
4298 emit_insn (gen_sync_compare_and_swap_ccsi (cmp, ac.memsi, cmp, new));
4300 /* Loop until swapped (unlikely?). */
4301 s390_emit_jump (csloop, gen_rtx_fmt_ee (NE, CCZ1mode,
4302 gen_rtx_REG (CCZ1mode, CC_REGNUM),
4303 const0_rtx));
4305 /* Return the correct part of the bitfield. */
4306 if (target)
4307 convert_move (target, expand_simple_binop (SImode, LSHIFTRT,
4308 after ? new : cmp, ac.shift,
4309 NULL_RTX, 1, OPTAB_DIRECT), 1);
4312 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
4313 We need to emit DTP-relative relocations. */
4315 static void s390_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
4317 static void
4318 s390_output_dwarf_dtprel (FILE *file, int size, rtx x)
4320 switch (size)
4322 case 4:
4323 fputs ("\t.long\t", file);
4324 break;
4325 case 8:
4326 fputs ("\t.quad\t", file);
4327 break;
4328 default:
4329 gcc_unreachable ();
4331 output_addr_const (file, x);
4332 fputs ("@DTPOFF", file);
4335 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
4336 /* Implement TARGET_MANGLE_FUNDAMENTAL_TYPE. */
4338 static const char *
4339 s390_mangle_fundamental_type (tree type)
4341 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
4342 && TARGET_LONG_DOUBLE_128)
4343 return "g";
4345 /* For all other types, use normal C++ mangling. */
4346 return NULL;
4348 #endif
4350 /* In the name of slightly smaller debug output, and to cater to
4351 general assembler lossage, recognize various UNSPEC sequences
4352 and turn them back into a direct symbol reference. */
4354 static rtx
4355 s390_delegitimize_address (rtx orig_x)
4357 rtx x = orig_x, y;
4359 if (GET_CODE (x) != MEM)
4360 return orig_x;
4362 x = XEXP (x, 0);
4363 if (GET_CODE (x) == PLUS
4364 && GET_CODE (XEXP (x, 1)) == CONST
4365 && GET_CODE (XEXP (x, 0)) == REG
4366 && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM)
4368 y = XEXP (XEXP (x, 1), 0);
4369 if (GET_CODE (y) == UNSPEC
4370 && XINT (y, 1) == UNSPEC_GOT)
4371 return XVECEXP (y, 0, 0);
4372 return orig_x;
4375 if (GET_CODE (x) == CONST)
4377 y = XEXP (x, 0);
4378 if (GET_CODE (y) == UNSPEC
4379 && XINT (y, 1) == UNSPEC_GOTENT)
4380 return XVECEXP (y, 0, 0);
4381 return orig_x;
4384 return orig_x;
4387 /* Output operand OP to stdio stream FILE.
4388 OP is an address (register + offset) which is not used to address data;
4389 instead the rightmost bits are interpreted as the value. */
4391 static void
4392 print_shift_count_operand (FILE *file, rtx op)
4394 HOST_WIDE_INT offset = 0;
4396 /* Extract base register and offset. */
4397 if (!s390_decompose_shift_count (op, &base, &offset))
4398 gcc_unreachable ();
4400 op = XEXP (op, 0);
4403 /* We can have an integer constant, an address register,
4404 or a sum of the two. */
4405 if (GET_CODE (op) == CONST_INT)
4407 offset = INTVAL (op);
4408 op = NULL_RTX;
4410 if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
4412 offset = INTVAL (XEXP (op, 1));
4413 op = XEXP (op, 0);
4415 while (op && GET_CODE (op) == SUBREG)
4416 op = SUBREG_REG (op);
4418 /* Sanity check. */
4419 if (op)
4421 gcc_assert (GET_CODE (op) == REG);
4422 gcc_assert (REGNO (op) < FIRST_PSEUDO_REGISTER);
4423 gcc_assert (REGNO_REG_CLASS (REGNO (op)) == ADDR_REGS);
4426 /* Offsets are constricted to twelve bits. */
4427 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset & ((1 << 12) - 1));
4428 if (op)
4429 fprintf (file, "(%s)", reg_names[REGNO (op)]);
4432 /* See 'get_some_local_dynamic_name'. */
4434 static int
4435 get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
4437 rtx x = *px;
4439 if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
4441 x = get_pool_constant (x);
4442 return for_each_rtx (&x, get_some_local_dynamic_name_1, 0);
4445 if (GET_CODE (x) == SYMBOL_REF
4446 && tls_symbolic_operand (x) == TLS_MODEL_LOCAL_DYNAMIC)
4448 cfun->machine->some_ld_name = XSTR (x, 0);
4449 return 1;
4452 return 0;
4455 /* Locate some local-dynamic symbol still in use by this function
4456 so that we can print its name in local-dynamic base patterns. */
4458 static const char *
4459 get_some_local_dynamic_name (void)
4461 rtx insn;
4463 if (cfun->machine->some_ld_name)
4464 return cfun->machine->some_ld_name;
4466 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
4467 if (INSN_P (insn)
4468 && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
4469 return cfun->machine->some_ld_name;
4471 gcc_unreachable ();
4474 /* Output machine-dependent UNSPECs occurring in address constant X
4475 in assembler syntax to stdio stream FILE. Returns true if the
4476 constant X could be recognized, false otherwise. */
4478 bool
4479 s390_output_addr_const_extra (FILE *file, rtx x)
4481 if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 1)
4482 switch (XINT (x, 1))
4484 case UNSPEC_GOTENT:
4485 output_addr_const (file, XVECEXP (x, 0, 0));
4486 fprintf (file, "@GOTENT");
4487 return true;
4488 case UNSPEC_GOT:
4489 output_addr_const (file, XVECEXP (x, 0, 0));
4490 fprintf (file, "@GOT");
4491 return true;
4492 case UNSPEC_GOTOFF:
4493 output_addr_const (file, XVECEXP (x, 0, 0));
4494 fprintf (file, "@GOTOFF");
4495 return true;
4496 case UNSPEC_PLT:
4497 output_addr_const (file, XVECEXP (x, 0, 0));
4498 fprintf (file, "@PLT");
4499 return true;
4500 case UNSPEC_PLTOFF:
4501 output_addr_const (file, XVECEXP (x, 0, 0));
4502 fprintf (file, "@PLTOFF");
4503 return true;
4504 case UNSPEC_TLSGD:
4505 output_addr_const (file, XVECEXP (x, 0, 0));
4506 fprintf (file, "@TLSGD");
4507 return true;
4508 case UNSPEC_TLSLDM:
4509 assemble_name (file, get_some_local_dynamic_name ());
4510 fprintf (file, "@TLSLDM");
4511 return true;
4512 case UNSPEC_DTPOFF:
4513 output_addr_const (file, XVECEXP (x, 0, 0));
4514 fprintf (file, "@DTPOFF");
4515 return true;
4516 case UNSPEC_NTPOFF:
4517 output_addr_const (file, XVECEXP (x, 0, 0));
4518 fprintf (file, "@NTPOFF");
4519 return true;
4520 case UNSPEC_GOTNTPOFF:
4521 output_addr_const (file, XVECEXP (x, 0, 0));
4522 fprintf (file, "@GOTNTPOFF");
4523 return true;
4524 case UNSPEC_INDNTPOFF:
4525 output_addr_const (file, XVECEXP (x, 0, 0));
4526 fprintf (file, "@INDNTPOFF");
4527 return true;
4530 return false;
4533 /* Output address operand ADDR in assembler syntax to
4534 stdio stream FILE. */
4536 void
4537 print_operand_address (FILE *file, rtx addr)
4539 struct s390_address ad;
4541 if (!s390_decompose_address (addr, &ad)
4542 || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
4543 || (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx))))
4544 output_operand_lossage ("cannot decompose address");
4546 if (ad.disp)
4547 output_addr_const (file, ad.disp);
4548 else
4549 fprintf (file, "0");
4551 if (ad.base && ad.indx)
4552 fprintf (file, "(%s,%s)", reg_names[REGNO (ad.indx)],
4553 reg_names[REGNO (ad.base)]);
4554 else if (ad.base)
4555 fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
4558 /* Output operand X in assembler syntax to stdio stream FILE.
4559 CODE specified the format flag. The following format flags
4560 are recognized:
4562 'C': print opcode suffix for branch condition.
4563 'D': print opcode suffix for inverse branch condition.
4564 'J': print tls_load/tls_gdcall/tls_ldcall suffix
4565 'G': print the size of the operand in bytes.
4566 'O': print only the displacement of a memory reference.
4567 'R': print only the base register of a memory reference.
4568 'S': print S-type memory reference (base+displacement).
4569 'N': print the second word of a DImode operand.
4570 'M': print the second word of a TImode operand.
4571 'Y': print shift count operand.
4573 'b': print integer X as if it's an unsigned byte.
4574 'x': print integer X as if it's an unsigned halfword.
4575 'h': print integer X as if it's a signed halfword.
4576 'i': print the first nonzero HImode part of X.
4577 'j': print the first HImode part unequal to -1 of X.
4578 'k': print the first nonzero SImode part of X.
4579 'm': print the first SImode part unequal to -1 of X.
4580 'o': print integer X as if it's an unsigned 32bit word. */
4582 void
4583 print_operand (FILE *file, rtx x, int code)
4585 switch (code)
4587 case 'C':
4588 fprintf (file, s390_branch_condition_mnemonic (x, FALSE));
4589 return;
4591 case 'D':
4592 fprintf (file, s390_branch_condition_mnemonic (x, TRUE));
4593 return;
4595 case 'J':
4596 if (GET_CODE (x) == SYMBOL_REF)
4598 fprintf (file, "%s", ":tls_load:");
4599 output_addr_const (file, x);
4601 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD)
4603 fprintf (file, "%s", ":tls_gdcall:");
4604 output_addr_const (file, XVECEXP (x, 0, 0));
4606 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM)
4608 fprintf (file, "%s", ":tls_ldcall:");
4609 assemble_name (file, get_some_local_dynamic_name ());
4611 else
4612 gcc_unreachable ();
4613 return;
4615 case 'G':
4616 fprintf (file, "%u", GET_MODE_SIZE (GET_MODE (x)));
4617 return;
4619 case 'O':
4621 struct s390_address ad;
4622 int ret;
4624 gcc_assert (GET_CODE (x) == MEM);
4625 ret = s390_decompose_address (XEXP (x, 0), &ad);
4626 gcc_assert (ret);
4627 gcc_assert (!ad.base || REGNO_OK_FOR_BASE_P (REGNO (ad.base)));
4628 gcc_assert (!ad.indx);
4630 if (ad.disp)
4631 output_addr_const (file, ad.disp);
4632 else
4633 fprintf (file, "0");
4635 return;
4637 case 'R':
4639 struct s390_address ad;
4640 int ret;
4642 gcc_assert (GET_CODE (x) == MEM);
4643 ret = s390_decompose_address (XEXP (x, 0), &ad);
4644 gcc_assert (ret);
4645 gcc_assert (!ad.base || REGNO_OK_FOR_BASE_P (REGNO (ad.base)));
4646 gcc_assert (!ad.indx);
4648 if (ad.base)
4649 fprintf (file, "%s", reg_names[REGNO (ad.base)]);
4650 else
4651 fprintf (file, "0");
4653 return;
4655 case 'S':
4657 struct s390_address ad;
4658 int ret;
4660 gcc_assert (GET_CODE (x) == MEM);
4661 ret = s390_decompose_address (XEXP (x, 0), &ad);
4662 gcc_assert (ret);
4663 gcc_assert (!ad.base || REGNO_OK_FOR_BASE_P (REGNO (ad.base)));
4664 gcc_assert (!ad.indx);
4666 if (ad.disp)
4667 output_addr_const (file, ad.disp);
4668 else
4669 fprintf (file, "0");
4671 if (ad.base)
4672 fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
4674 return;
4676 case 'N':
4677 if (GET_CODE (x) == REG)
4678 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
4679 else if (GET_CODE (x) == MEM)
4680 x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 4));
4681 else
4682 gcc_unreachable ();
4683 break;
4685 case 'M':
4686 if (GET_CODE (x) == REG)
4687 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
4688 else if (GET_CODE (x) == MEM)
4689 x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 8));
4690 else
4691 gcc_unreachable ();
4692 break;
4694 case 'Y':
4695 print_shift_count_operand (file, x);
4696 return;
4699 switch (GET_CODE (x))
4701 case REG:
4702 fprintf (file, "%s", reg_names[REGNO (x)]);
4703 break;
4705 case MEM:
4706 output_address (XEXP (x, 0));
4707 break;
4709 case CONST:
4710 case CODE_LABEL:
4711 case LABEL_REF:
4712 case SYMBOL_REF:
4713 output_addr_const (file, x);
4714 break;
4716 case CONST_INT:
4717 if (code == 'b')
4718 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xff);
4719 else if (code == 'x')
4720 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffff);
4721 else if (code == 'h')
4722 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000);
4723 else if (code == 'i')
4724 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4725 s390_extract_part (x, HImode, 0));
4726 else if (code == 'j')
4727 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4728 s390_extract_part (x, HImode, -1));
4729 else if (code == 'k')
4730 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4731 s390_extract_part (x, SImode, 0));
4732 else if (code == 'm')
4733 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4734 s390_extract_part (x, SImode, -1));
4735 else if (code == 'o')
4736 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffffffff);
4737 else
4738 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
4739 break;
4741 case CONST_DOUBLE:
4742 gcc_assert (GET_MODE (x) == VOIDmode);
4743 if (code == 'b')
4744 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xff);
4745 else if (code == 'x')
4746 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xffff);
4747 else if (code == 'h')
4748 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((CONST_DOUBLE_LOW (x) & 0xffff) ^ 0x8000) - 0x8000);
4749 else
4750 gcc_unreachable ();
4751 break;
4753 default:
4754 fatal_insn ("UNKNOWN in print_operand !?", x);
4755 break;
4759 /* Target hook for assembling integer objects. We need to define it
4760 here to work a round a bug in some versions of GAS, which couldn't
4761 handle values smaller than INT_MIN when printed in decimal. */
4763 static bool
4764 s390_assemble_integer (rtx x, unsigned int size, int aligned_p)
4766 if (size == 8 && aligned_p
4767 && GET_CODE (x) == CONST_INT && INTVAL (x) < INT_MIN)
4769 fprintf (asm_out_file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n",
4770 INTVAL (x));
4771 return true;
4773 return default_assemble_integer (x, size, aligned_p);
4776 /* Returns true if register REGNO is used for forming
4777 a memory address in expression X. */
4779 static bool
4780 reg_used_in_mem_p (int regno, rtx x)
4782 enum rtx_code code = GET_CODE (x);
4783 int i, j;
4784 const char *fmt;
4786 if (code == MEM)
4788 if (refers_to_regno_p (regno, regno+1,
4789 XEXP (x, 0), 0))
4790 return true;
4792 else if (code == SET
4793 && GET_CODE (SET_DEST (x)) == PC)
4795 if (refers_to_regno_p (regno, regno+1,
4796 SET_SRC (x), 0))
4797 return true;
4800 fmt = GET_RTX_FORMAT (code);
4801 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4803 if (fmt[i] == 'e'
4804 && reg_used_in_mem_p (regno, XEXP (x, i)))
4805 return true;
4807 else if (fmt[i] == 'E')
4808 for (j = 0; j < XVECLEN (x, i); j++)
4809 if (reg_used_in_mem_p (regno, XVECEXP (x, i, j)))
4810 return true;
4812 return false;
4815 /* Returns true if expression DEP_RTX sets an address register
4816 used by instruction INSN to address memory. */
4818 static bool
4819 addr_generation_dependency_p (rtx dep_rtx, rtx insn)
4821 rtx target, pat;
4823 if (GET_CODE (dep_rtx) == INSN)
4824 dep_rtx = PATTERN (dep_rtx);
4826 if (GET_CODE (dep_rtx) == SET)
4828 target = SET_DEST (dep_rtx);
4829 if (GET_CODE (target) == STRICT_LOW_PART)
4830 target = XEXP (target, 0);
4831 while (GET_CODE (target) == SUBREG)
4832 target = SUBREG_REG (target);
4834 if (GET_CODE (target) == REG)
4836 int regno = REGNO (target);
4838 if (s390_safe_attr_type (insn) == TYPE_LA)
4840 pat = PATTERN (insn);
4841 if (GET_CODE (pat) == PARALLEL)
4843 gcc_assert (XVECLEN (pat, 0) == 2);
4844 pat = XVECEXP (pat, 0, 0);
4846 gcc_assert (GET_CODE (pat) == SET);
4847 return refers_to_regno_p (regno, regno+1, SET_SRC (pat), 0);
4849 else if (get_attr_atype (insn) == ATYPE_AGEN)
4850 return reg_used_in_mem_p (regno, PATTERN (insn));
4853 return false;
4856 /* Return 1, if dep_insn sets register used in insn in the agen unit. */
4859 s390_agen_dep_p (rtx dep_insn, rtx insn)
4861 rtx dep_rtx = PATTERN (dep_insn);
4862 int i;
4864 if (GET_CODE (dep_rtx) == SET
4865 && addr_generation_dependency_p (dep_rtx, insn))
4866 return 1;
4867 else if (GET_CODE (dep_rtx) == PARALLEL)
4869 for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
4871 if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i), insn))
4872 return 1;
4875 return 0;
4878 /* A C statement (sans semicolon) to update the integer scheduling priority
4879 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
4880 reduce the priority to execute INSN later. Do not define this macro if
4881 you do not need to adjust the scheduling priorities of insns.
4883 A STD instruction should be scheduled earlier,
4884 in order to use the bypass. */
4886 static int
4887 s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
4889 if (! INSN_P (insn))
4890 return priority;
4892 if (s390_tune != PROCESSOR_2084_Z990
4893 && s390_tune != PROCESSOR_2094_Z9_109)
4894 return priority;
4896 switch (s390_safe_attr_type (insn))
4898 case TYPE_FSTOREDF:
4899 case TYPE_FSTORESF:
4900 priority = priority << 3;
4901 break;
4902 case TYPE_STORE:
4903 case TYPE_STM:
4904 priority = priority << 1;
4905 break;
4906 default:
4907 break;
4909 return priority;
4912 /* The number of instructions that can be issued per cycle. */
4914 static int
4915 s390_issue_rate (void)
4917 if (s390_tune == PROCESSOR_2084_Z990
4918 || s390_tune == PROCESSOR_2094_Z9_109)
4919 return 3;
4920 return 1;
4923 static int
4924 s390_first_cycle_multipass_dfa_lookahead (void)
4926 return 4;
4930 /* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
4931 Fix up MEMs as required. */
4933 static void
4934 annotate_constant_pool_refs (rtx *x)
4936 int i, j;
4937 const char *fmt;
4939 gcc_assert (GET_CODE (*x) != SYMBOL_REF
4940 || !CONSTANT_POOL_ADDRESS_P (*x));
4942 /* Literal pool references can only occur inside a MEM ... */
4943 if (GET_CODE (*x) == MEM)
4945 rtx memref = XEXP (*x, 0);
4947 if (GET_CODE (memref) == SYMBOL_REF
4948 && CONSTANT_POOL_ADDRESS_P (memref))
4950 rtx base = cfun->machine->base_reg;
4951 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, memref, base),
4952 UNSPEC_LTREF);
4954 *x = replace_equiv_address (*x, addr);
4955 return;
4958 if (GET_CODE (memref) == CONST
4959 && GET_CODE (XEXP (memref, 0)) == PLUS
4960 && GET_CODE (XEXP (XEXP (memref, 0), 1)) == CONST_INT
4961 && GET_CODE (XEXP (XEXP (memref, 0), 0)) == SYMBOL_REF
4962 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (memref, 0), 0)))
4964 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (memref, 0), 1));
4965 rtx sym = XEXP (XEXP (memref, 0), 0);
4966 rtx base = cfun->machine->base_reg;
4967 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, sym, base),
4968 UNSPEC_LTREF);
4970 *x = replace_equiv_address (*x, plus_constant (addr, off));
4971 return;
4975 /* ... or a load-address type pattern. */
4976 if (GET_CODE (*x) == SET)
4978 rtx addrref = SET_SRC (*x);
4980 if (GET_CODE (addrref) == SYMBOL_REF
4981 && CONSTANT_POOL_ADDRESS_P (addrref))
4983 rtx base = cfun->machine->base_reg;
4984 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, addrref, base),
4985 UNSPEC_LTREF);
4987 SET_SRC (*x) = addr;
4988 return;
4991 if (GET_CODE (addrref) == CONST
4992 && GET_CODE (XEXP (addrref, 0)) == PLUS
4993 && GET_CODE (XEXP (XEXP (addrref, 0), 1)) == CONST_INT
4994 && GET_CODE (XEXP (XEXP (addrref, 0), 0)) == SYMBOL_REF
4995 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (addrref, 0), 0)))
4997 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (addrref, 0), 1));
4998 rtx sym = XEXP (XEXP (addrref, 0), 0);
4999 rtx base = cfun->machine->base_reg;
5000 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, sym, base),
5001 UNSPEC_LTREF);
5003 SET_SRC (*x) = plus_constant (addr, off);
5004 return;
5008 /* Annotate LTREL_BASE as well. */
5009 if (GET_CODE (*x) == UNSPEC
5010 && XINT (*x, 1) == UNSPEC_LTREL_BASE)
5012 rtx base = cfun->machine->base_reg;
5013 *x = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, XVECEXP (*x, 0, 0), base),
5014 UNSPEC_LTREL_BASE);
5015 return;
5018 fmt = GET_RTX_FORMAT (GET_CODE (*x));
5019 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
5021 if (fmt[i] == 'e')
5023 annotate_constant_pool_refs (&XEXP (*x, i));
5025 else if (fmt[i] == 'E')
5027 for (j = 0; j < XVECLEN (*x, i); j++)
5028 annotate_constant_pool_refs (&XVECEXP (*x, i, j));
5033 /* Split all branches that exceed the maximum distance.
5034 Returns true if this created a new literal pool entry. */
5036 static int
5037 s390_split_branches (void)
5039 rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
5040 int new_literal = 0, ret;
5041 rtx insn, pat, tmp, target;
5042 rtx *label;
5044 /* We need correct insn addresses. */
5046 shorten_branches (get_insns ());
5048 /* Find all branches that exceed 64KB, and split them. */
5050 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5052 if (GET_CODE (insn) != JUMP_INSN)
5053 continue;
5055 pat = PATTERN (insn);
5056 if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
5057 pat = XVECEXP (pat, 0, 0);
5058 if (GET_CODE (pat) != SET || SET_DEST (pat) != pc_rtx)
5059 continue;
5061 if (GET_CODE (SET_SRC (pat)) == LABEL_REF)
5063 label = &SET_SRC (pat);
5065 else if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE)
5067 if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF)
5068 label = &XEXP (SET_SRC (pat), 1);
5069 else if (GET_CODE (XEXP (SET_SRC (pat), 2)) == LABEL_REF)
5070 label = &XEXP (SET_SRC (pat), 2);
5071 else
5072 continue;
5074 else
5075 continue;
5077 if (get_attr_length (insn) <= 4)
5078 continue;
5080 /* We are going to use the return register as scratch register,
5081 make sure it will be saved/restored by the prologue/epilogue. */
5082 cfun_frame_layout.save_return_addr_p = 1;
5084 if (!flag_pic)
5086 new_literal = 1;
5087 tmp = force_const_mem (Pmode, *label);
5088 tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, tmp), insn);
5089 INSN_ADDRESSES_NEW (tmp, -1);
5090 annotate_constant_pool_refs (&PATTERN (tmp));
5092 target = temp_reg;
5094 else
5096 new_literal = 1;
5097 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, *label),
5098 UNSPEC_LTREL_OFFSET);
5099 target = gen_rtx_CONST (Pmode, target);
5100 target = force_const_mem (Pmode, target);
5101 tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, target), insn);
5102 INSN_ADDRESSES_NEW (tmp, -1);
5103 annotate_constant_pool_refs (&PATTERN (tmp));
5105 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, XEXP (target, 0),
5106 cfun->machine->base_reg),
5107 UNSPEC_LTREL_BASE);
5108 target = gen_rtx_PLUS (Pmode, temp_reg, target);
5111 ret = validate_change (insn, label, target, 0);
5112 gcc_assert (ret);
5115 return new_literal;
5119 /* Find an annotated literal pool symbol referenced in RTX X,
5120 and store it at REF. Will abort if X contains references to
5121 more than one such pool symbol; multiple references to the same
5122 symbol are allowed, however.
5124 The rtx pointed to by REF must be initialized to NULL_RTX
5125 by the caller before calling this routine. */
5127 static void
5128 find_constant_pool_ref (rtx x, rtx *ref)
5130 int i, j;
5131 const char *fmt;
5133 /* Ignore LTREL_BASE references. */
5134 if (GET_CODE (x) == UNSPEC
5135 && XINT (x, 1) == UNSPEC_LTREL_BASE)
5136 return;
5137 /* Likewise POOL_ENTRY insns. */
5138 if (GET_CODE (x) == UNSPEC_VOLATILE
5139 && XINT (x, 1) == UNSPECV_POOL_ENTRY)
5140 return;
5142 gcc_assert (GET_CODE (x) != SYMBOL_REF
5143 || !CONSTANT_POOL_ADDRESS_P (x));
5145 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_LTREF)
5147 rtx sym = XVECEXP (x, 0, 0);
5148 gcc_assert (GET_CODE (sym) == SYMBOL_REF
5149 && CONSTANT_POOL_ADDRESS_P (sym));
5151 if (*ref == NULL_RTX)
5152 *ref = sym;
5153 else
5154 gcc_assert (*ref == sym);
5156 return;
5159 fmt = GET_RTX_FORMAT (GET_CODE (x));
5160 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
5162 if (fmt[i] == 'e')
5164 find_constant_pool_ref (XEXP (x, i), ref);
5166 else if (fmt[i] == 'E')
5168 for (j = 0; j < XVECLEN (x, i); j++)
5169 find_constant_pool_ref (XVECEXP (x, i, j), ref);
5174 /* Replace every reference to the annotated literal pool
5175 symbol REF in X by its base plus OFFSET. */
5177 static void
5178 replace_constant_pool_ref (rtx *x, rtx ref, rtx offset)
5180 int i, j;
5181 const char *fmt;
5183 gcc_assert (*x != ref);
5185 if (GET_CODE (*x) == UNSPEC
5186 && XINT (*x, 1) == UNSPEC_LTREF
5187 && XVECEXP (*x, 0, 0) == ref)
5189 *x = gen_rtx_PLUS (Pmode, XVECEXP (*x, 0, 1), offset);
5190 return;
5193 if (GET_CODE (*x) == PLUS
5194 && GET_CODE (XEXP (*x, 1)) == CONST_INT
5195 && GET_CODE (XEXP (*x, 0)) == UNSPEC
5196 && XINT (XEXP (*x, 0), 1) == UNSPEC_LTREF
5197 && XVECEXP (XEXP (*x, 0), 0, 0) == ref)
5199 rtx addr = gen_rtx_PLUS (Pmode, XVECEXP (XEXP (*x, 0), 0, 1), offset);
5200 *x = plus_constant (addr, INTVAL (XEXP (*x, 1)));
5201 return;
5204 fmt = GET_RTX_FORMAT (GET_CODE (*x));
5205 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
5207 if (fmt[i] == 'e')
5209 replace_constant_pool_ref (&XEXP (*x, i), ref, offset);
5211 else if (fmt[i] == 'E')
5213 for (j = 0; j < XVECLEN (*x, i); j++)
5214 replace_constant_pool_ref (&XVECEXP (*x, i, j), ref, offset);
5219 /* Check whether X contains an UNSPEC_LTREL_BASE.
5220 Return its constant pool symbol if found, NULL_RTX otherwise. */
5222 static rtx
5223 find_ltrel_base (rtx x)
5225 int i, j;
5226 const char *fmt;
5228 if (GET_CODE (x) == UNSPEC
5229 && XINT (x, 1) == UNSPEC_LTREL_BASE)
5230 return XVECEXP (x, 0, 0);
5232 fmt = GET_RTX_FORMAT (GET_CODE (x));
5233 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
5235 if (fmt[i] == 'e')
5237 rtx fnd = find_ltrel_base (XEXP (x, i));
5238 if (fnd)
5239 return fnd;
5241 else if (fmt[i] == 'E')
5243 for (j = 0; j < XVECLEN (x, i); j++)
5245 rtx fnd = find_ltrel_base (XVECEXP (x, i, j));
5246 if (fnd)
5247 return fnd;
5252 return NULL_RTX;
5255 /* Replace any occurrence of UNSPEC_LTREL_BASE in X with its base. */
5257 static void
5258 replace_ltrel_base (rtx *x)
5260 int i, j;
5261 const char *fmt;
5263 if (GET_CODE (*x) == UNSPEC
5264 && XINT (*x, 1) == UNSPEC_LTREL_BASE)
5266 *x = XVECEXP (*x, 0, 1);
5267 return;
5270 fmt = GET_RTX_FORMAT (GET_CODE (*x));
5271 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
5273 if (fmt[i] == 'e')
5275 replace_ltrel_base (&XEXP (*x, i));
5277 else if (fmt[i] == 'E')
5279 for (j = 0; j < XVECLEN (*x, i); j++)
5280 replace_ltrel_base (&XVECEXP (*x, i, j));
5286 /* We keep a list of constants which we have to add to internal
5287 constant tables in the middle of large functions. */
5289 #define NR_C_MODES 11
5290 enum machine_mode constant_modes[NR_C_MODES] =
5292 TFmode, TImode, TDmode,
5293 DFmode, DImode, DDmode,
5294 SFmode, SImode, SDmode,
5295 HImode,
5296 QImode
5299 struct constant
5301 struct constant *next;
5302 rtx value;
5303 rtx label;
5306 struct constant_pool
5308 struct constant_pool *next;
5309 rtx first_insn;
5310 rtx pool_insn;
5311 bitmap insns;
5313 struct constant *constants[NR_C_MODES];
5314 struct constant *execute;
5315 rtx label;
5316 int size;
5319 /* Allocate new constant_pool structure. */
5321 static struct constant_pool *
5322 s390_alloc_pool (void)
5324 struct constant_pool *pool;
5325 int i;
5327 pool = (struct constant_pool *) xmalloc (sizeof *pool);
5328 pool->next = NULL;
5329 for (i = 0; i < NR_C_MODES; i++)
5330 pool->constants[i] = NULL;
5332 pool->execute = NULL;
5333 pool->label = gen_label_rtx ();
5334 pool->first_insn = NULL_RTX;
5335 pool->pool_insn = NULL_RTX;
5336 pool->insns = BITMAP_ALLOC (NULL);
5337 pool->size = 0;
5339 return pool;
5342 /* Create new constant pool covering instructions starting at INSN
5343 and chain it to the end of POOL_LIST. */
5345 static struct constant_pool *
5346 s390_start_pool (struct constant_pool **pool_list, rtx insn)
5348 struct constant_pool *pool, **prev;
5350 pool = s390_alloc_pool ();
5351 pool->first_insn = insn;
5353 for (prev = pool_list; *prev; prev = &(*prev)->next)
5355 *prev = pool;
5357 return pool;
5360 /* End range of instructions covered by POOL at INSN and emit
5361 placeholder insn representing the pool. */
5363 static void
5364 s390_end_pool (struct constant_pool *pool, rtx insn)
5366 rtx pool_size = GEN_INT (pool->size + 8 /* alignment slop */);
5368 if (!insn)
5369 insn = get_last_insn ();
5371 pool->pool_insn = emit_insn_after (gen_pool (pool_size), insn);
5372 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
5375 /* Add INSN to the list of insns covered by POOL. */
5377 static void
5378 s390_add_pool_insn (struct constant_pool *pool, rtx insn)
5380 bitmap_set_bit (pool->insns, INSN_UID (insn));
5383 /* Return pool out of POOL_LIST that covers INSN. */
5385 static struct constant_pool *
5386 s390_find_pool (struct constant_pool *pool_list, rtx insn)
5388 struct constant_pool *pool;
5390 for (pool = pool_list; pool; pool = pool->next)
5391 if (bitmap_bit_p (pool->insns, INSN_UID (insn)))
5392 break;
5394 return pool;
5397 /* Add constant VAL of mode MODE to the constant pool POOL. */
5399 static void
5400 s390_add_constant (struct constant_pool *pool, rtx val, enum machine_mode mode)
5402 struct constant *c;
5403 int i;
5405 for (i = 0; i < NR_C_MODES; i++)
5406 if (constant_modes[i] == mode)
5407 break;
5408 gcc_assert (i != NR_C_MODES);
5410 for (c = pool->constants[i]; c != NULL; c = c->next)
5411 if (rtx_equal_p (val, c->value))
5412 break;
5414 if (c == NULL)
5416 c = (struct constant *) xmalloc (sizeof *c);
5417 c->value = val;
5418 c->label = gen_label_rtx ();
5419 c->next = pool->constants[i];
5420 pool->constants[i] = c;
5421 pool->size += GET_MODE_SIZE (mode);
5425 /* Find constant VAL of mode MODE in the constant pool POOL.
5426 Return an RTX describing the distance from the start of
5427 the pool to the location of the new constant. */
5429 static rtx
5430 s390_find_constant (struct constant_pool *pool, rtx val,
5431 enum machine_mode mode)
5433 struct constant *c;
5434 rtx offset;
5435 int i;
5437 for (i = 0; i < NR_C_MODES; i++)
5438 if (constant_modes[i] == mode)
5439 break;
5440 gcc_assert (i != NR_C_MODES);
5442 for (c = pool->constants[i]; c != NULL; c = c->next)
5443 if (rtx_equal_p (val, c->value))
5444 break;
5446 gcc_assert (c);
5448 offset = gen_rtx_MINUS (Pmode, gen_rtx_LABEL_REF (Pmode, c->label),
5449 gen_rtx_LABEL_REF (Pmode, pool->label));
5450 offset = gen_rtx_CONST (Pmode, offset);
5451 return offset;
5454 /* Check whether INSN is an execute. Return the label_ref to its
5455 execute target template if so, NULL_RTX otherwise. */
5457 static rtx
5458 s390_execute_label (rtx insn)
5460 if (GET_CODE (insn) == INSN
5461 && GET_CODE (PATTERN (insn)) == PARALLEL
5462 && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == UNSPEC
5463 && XINT (XVECEXP (PATTERN (insn), 0, 0), 1) == UNSPEC_EXECUTE)
5464 return XVECEXP (XVECEXP (PATTERN (insn), 0, 0), 0, 2);
5466 return NULL_RTX;
5469 /* Add execute target for INSN to the constant pool POOL. */
5471 static void
5472 s390_add_execute (struct constant_pool *pool, rtx insn)
5474 struct constant *c;
5476 for (c = pool->execute; c != NULL; c = c->next)
5477 if (INSN_UID (insn) == INSN_UID (c->value))
5478 break;
5480 if (c == NULL)
5482 c = (struct constant *) xmalloc (sizeof *c);
5483 c->value = insn;
5484 c->label = gen_label_rtx ();
5485 c->next = pool->execute;
5486 pool->execute = c;
5487 pool->size += 6;
5491 /* Find execute target for INSN in the constant pool POOL.
5492 Return an RTX describing the distance from the start of
5493 the pool to the location of the execute target. */
5495 static rtx
5496 s390_find_execute (struct constant_pool *pool, rtx insn)
5498 struct constant *c;
5499 rtx offset;
5501 for (c = pool->execute; c != NULL; c = c->next)
5502 if (INSN_UID (insn) == INSN_UID (c->value))
5503 break;
5505 gcc_assert (c);
5507 offset = gen_rtx_MINUS (Pmode, gen_rtx_LABEL_REF (Pmode, c->label),
5508 gen_rtx_LABEL_REF (Pmode, pool->label));
5509 offset = gen_rtx_CONST (Pmode, offset);
5510 return offset;
5513 /* For an execute INSN, extract the execute target template. */
5515 static rtx
5516 s390_execute_target (rtx insn)
5518 rtx pattern = PATTERN (insn);
5519 gcc_assert (s390_execute_label (insn));
5521 if (XVECLEN (pattern, 0) == 2)
5523 pattern = copy_rtx (XVECEXP (pattern, 0, 1));
5525 else
5527 rtvec vec = rtvec_alloc (XVECLEN (pattern, 0) - 1);
5528 int i;
5530 for (i = 0; i < XVECLEN (pattern, 0) - 1; i++)
5531 RTVEC_ELT (vec, i) = copy_rtx (XVECEXP (pattern, 0, i + 1));
5533 pattern = gen_rtx_PARALLEL (VOIDmode, vec);
5536 return pattern;
5539 /* Indicate that INSN cannot be duplicated. This is the case for
5540 execute insns that carry a unique label. */
5542 static bool
5543 s390_cannot_copy_insn_p (rtx insn)
5545 rtx label = s390_execute_label (insn);
5546 return label && label != const0_rtx;
5549 /* Dump out the constants in POOL. If REMOTE_LABEL is true,
5550 do not emit the pool base label. */
5552 static void
5553 s390_dump_pool (struct constant_pool *pool, bool remote_label)
5555 struct constant *c;
5556 rtx insn = pool->pool_insn;
5557 int i;
5559 /* Switch to rodata section. */
5560 if (TARGET_CPU_ZARCH)
5562 insn = emit_insn_after (gen_pool_section_start (), insn);
5563 INSN_ADDRESSES_NEW (insn, -1);
5566 /* Ensure minimum pool alignment. */
5567 if (TARGET_CPU_ZARCH)
5568 insn = emit_insn_after (gen_pool_align (GEN_INT (8)), insn);
5569 else
5570 insn = emit_insn_after (gen_pool_align (GEN_INT (4)), insn);
5571 INSN_ADDRESSES_NEW (insn, -1);
5573 /* Emit pool base label. */
5574 if (!remote_label)
5576 insn = emit_label_after (pool->label, insn);
5577 INSN_ADDRESSES_NEW (insn, -1);
5580 /* Dump constants in descending alignment requirement order,
5581 ensuring proper alignment for every constant. */
5582 for (i = 0; i < NR_C_MODES; i++)
5583 for (c = pool->constants[i]; c; c = c->next)
5585 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
5586 rtx value = c->value;
5587 if (GET_CODE (value) == CONST
5588 && GET_CODE (XEXP (value, 0)) == UNSPEC
5589 && XINT (XEXP (value, 0), 1) == UNSPEC_LTREL_OFFSET
5590 && XVECLEN (XEXP (value, 0), 0) == 1)
5592 value = gen_rtx_MINUS (Pmode, XVECEXP (XEXP (value, 0), 0, 0),
5593 gen_rtx_LABEL_REF (VOIDmode, pool->label));
5594 value = gen_rtx_CONST (VOIDmode, value);
5597 insn = emit_label_after (c->label, insn);
5598 INSN_ADDRESSES_NEW (insn, -1);
5600 value = gen_rtx_UNSPEC_VOLATILE (constant_modes[i],
5601 gen_rtvec (1, value),
5602 UNSPECV_POOL_ENTRY);
5603 insn = emit_insn_after (value, insn);
5604 INSN_ADDRESSES_NEW (insn, -1);
5607 /* Ensure minimum alignment for instructions. */
5608 insn = emit_insn_after (gen_pool_align (GEN_INT (2)), insn);
5609 INSN_ADDRESSES_NEW (insn, -1);
5611 /* Output in-pool execute template insns. */
5612 for (c = pool->execute; c; c = c->next)
5614 insn = emit_label_after (c->label, insn);
5615 INSN_ADDRESSES_NEW (insn, -1);
5617 insn = emit_insn_after (s390_execute_target (c->value), insn);
5618 INSN_ADDRESSES_NEW (insn, -1);
5621 /* Switch back to previous section. */
5622 if (TARGET_CPU_ZARCH)
5624 insn = emit_insn_after (gen_pool_section_end (), insn);
5625 INSN_ADDRESSES_NEW (insn, -1);
5628 insn = emit_barrier_after (insn);
5629 INSN_ADDRESSES_NEW (insn, -1);
5631 /* Remove placeholder insn. */
5632 remove_insn (pool->pool_insn);
5635 /* Free all memory used by POOL. */
5637 static void
5638 s390_free_pool (struct constant_pool *pool)
5640 struct constant *c, *next;
5641 int i;
5643 for (i = 0; i < NR_C_MODES; i++)
5644 for (c = pool->constants[i]; c; c = next)
5646 next = c->next;
5647 free (c);
5650 for (c = pool->execute; c; c = next)
5652 next = c->next;
5653 free (c);
5656 BITMAP_FREE (pool->insns);
5657 free (pool);
5661 /* Collect main literal pool. Return NULL on overflow. */
5663 static struct constant_pool *
5664 s390_mainpool_start (void)
5666 struct constant_pool *pool;
5667 rtx insn;
5669 pool = s390_alloc_pool ();
5671 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5673 if (GET_CODE (insn) == INSN
5674 && GET_CODE (PATTERN (insn)) == SET
5675 && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC_VOLATILE
5676 && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPECV_MAIN_POOL)
5678 gcc_assert (!pool->pool_insn);
5679 pool->pool_insn = insn;
5682 if (!TARGET_CPU_ZARCH && s390_execute_label (insn))
5684 s390_add_execute (pool, insn);
5686 else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
5688 rtx pool_ref = NULL_RTX;
5689 find_constant_pool_ref (PATTERN (insn), &pool_ref);
5690 if (pool_ref)
5692 rtx constant = get_pool_constant (pool_ref);
5693 enum machine_mode mode = get_pool_mode (pool_ref);
5694 s390_add_constant (pool, constant, mode);
5699 gcc_assert (pool->pool_insn || pool->size == 0);
5701 if (pool->size >= 4096)
5703 /* We're going to chunkify the pool, so remove the main
5704 pool placeholder insn. */
5705 remove_insn (pool->pool_insn);
5707 s390_free_pool (pool);
5708 pool = NULL;
5711 return pool;
5714 /* POOL holds the main literal pool as collected by s390_mainpool_start.
5715 Modify the current function to output the pool constants as well as
5716 the pool register setup instruction. */
5718 static void
5719 s390_mainpool_finish (struct constant_pool *pool)
5721 rtx base_reg = cfun->machine->base_reg;
5722 rtx insn;
5724 /* If the pool is empty, we're done. */
5725 if (pool->size == 0)
5727 /* We don't actually need a base register after all. */
5728 cfun->machine->base_reg = NULL_RTX;
5730 if (pool->pool_insn)
5731 remove_insn (pool->pool_insn);
5732 s390_free_pool (pool);
5733 return;
5736 /* We need correct insn addresses. */
5737 shorten_branches (get_insns ());
5739 /* On zSeries, we use a LARL to load the pool register. The pool is
5740 located in the .rodata section, so we emit it after the function. */
5741 if (TARGET_CPU_ZARCH)
5743 insn = gen_main_base_64 (base_reg, pool->label);
5744 insn = emit_insn_after (insn, pool->pool_insn);
5745 INSN_ADDRESSES_NEW (insn, -1);
5746 remove_insn (pool->pool_insn);
5748 insn = get_last_insn ();
5749 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
5750 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
5752 s390_dump_pool (pool, 0);
5755 /* On S/390, if the total size of the function's code plus literal pool
5756 does not exceed 4096 bytes, we use BASR to set up a function base
5757 pointer, and emit the literal pool at the end of the function. */
5758 else if (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
5759 + pool->size + 8 /* alignment slop */ < 4096)
5761 insn = gen_main_base_31_small (base_reg, pool->label);
5762 insn = emit_insn_after (insn, pool->pool_insn);
5763 INSN_ADDRESSES_NEW (insn, -1);
5764 remove_insn (pool->pool_insn);
5766 insn = emit_label_after (pool->label, insn);
5767 INSN_ADDRESSES_NEW (insn, -1);
5769 insn = get_last_insn ();
5770 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
5771 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
5773 s390_dump_pool (pool, 1);
5776 /* Otherwise, we emit an inline literal pool and use BASR to branch
5777 over it, setting up the pool register at the same time. */
5778 else
5780 rtx pool_end = gen_label_rtx ();
5782 insn = gen_main_base_31_large (base_reg, pool->label, pool_end);
5783 insn = emit_insn_after (insn, pool->pool_insn);
5784 INSN_ADDRESSES_NEW (insn, -1);
5785 remove_insn (pool->pool_insn);
5787 insn = emit_label_after (pool->label, insn);
5788 INSN_ADDRESSES_NEW (insn, -1);
5790 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
5791 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
5793 insn = emit_label_after (pool_end, pool->pool_insn);
5794 INSN_ADDRESSES_NEW (insn, -1);
5796 s390_dump_pool (pool, 1);
5800 /* Replace all literal pool references. */
5802 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5804 if (INSN_P (insn))
5805 replace_ltrel_base (&PATTERN (insn));
5807 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
5809 rtx addr, pool_ref = NULL_RTX;
5810 find_constant_pool_ref (PATTERN (insn), &pool_ref);
5811 if (pool_ref)
5813 if (s390_execute_label (insn))
5814 addr = s390_find_execute (pool, insn);
5815 else
5816 addr = s390_find_constant (pool, get_pool_constant (pool_ref),
5817 get_pool_mode (pool_ref));
5819 replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
5820 INSN_CODE (insn) = -1;
5826 /* Free the pool. */
5827 s390_free_pool (pool);
5830 /* POOL holds the main literal pool as collected by s390_mainpool_start.
5831 We have decided we cannot use this pool, so revert all changes
5832 to the current function that were done by s390_mainpool_start. */
5833 static void
5834 s390_mainpool_cancel (struct constant_pool *pool)
5836 /* We didn't actually change the instruction stream, so simply
5837 free the pool memory. */
5838 s390_free_pool (pool);
5842 /* Chunkify the literal pool. */
5844 #define S390_POOL_CHUNK_MIN 0xc00
5845 #define S390_POOL_CHUNK_MAX 0xe00
5847 static struct constant_pool *
5848 s390_chunkify_start (void)
5850 struct constant_pool *curr_pool = NULL, *pool_list = NULL;
5851 int extra_size = 0;
5852 bitmap far_labels;
5853 rtx pending_ltrel = NULL_RTX;
5854 rtx insn;
5856 rtx (*gen_reload_base) (rtx, rtx) =
5857 TARGET_CPU_ZARCH? gen_reload_base_64 : gen_reload_base_31;
5860 /* We need correct insn addresses. */
5862 shorten_branches (get_insns ());
5864 /* Scan all insns and move literals to pool chunks. */
5866 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5868 /* Check for pending LTREL_BASE. */
5869 if (INSN_P (insn))
5871 rtx ltrel_base = find_ltrel_base (PATTERN (insn));
5872 if (ltrel_base)
5874 gcc_assert (ltrel_base == pending_ltrel);
5875 pending_ltrel = NULL_RTX;
5879 if (!TARGET_CPU_ZARCH && s390_execute_label (insn))
5881 if (!curr_pool)
5882 curr_pool = s390_start_pool (&pool_list, insn);
5884 s390_add_execute (curr_pool, insn);
5885 s390_add_pool_insn (curr_pool, insn);
5887 else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
5889 rtx pool_ref = NULL_RTX;
5890 find_constant_pool_ref (PATTERN (insn), &pool_ref);
5891 if (pool_ref)
5893 rtx constant = get_pool_constant (pool_ref);
5894 enum machine_mode mode = get_pool_mode (pool_ref);
5896 if (!curr_pool)
5897 curr_pool = s390_start_pool (&pool_list, insn);
5899 s390_add_constant (curr_pool, constant, mode);
5900 s390_add_pool_insn (curr_pool, insn);
5902 /* Don't split the pool chunk between a LTREL_OFFSET load
5903 and the corresponding LTREL_BASE. */
5904 if (GET_CODE (constant) == CONST
5905 && GET_CODE (XEXP (constant, 0)) == UNSPEC
5906 && XINT (XEXP (constant, 0), 1) == UNSPEC_LTREL_OFFSET)
5908 gcc_assert (!pending_ltrel);
5909 pending_ltrel = pool_ref;
5914 if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CODE_LABEL)
5916 if (curr_pool)
5917 s390_add_pool_insn (curr_pool, insn);
5918 /* An LTREL_BASE must follow within the same basic block. */
5919 gcc_assert (!pending_ltrel);
5922 if (!curr_pool
5923 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn)
5924 || INSN_ADDRESSES (INSN_UID (insn)) == -1)
5925 continue;
5927 if (TARGET_CPU_ZARCH)
5929 if (curr_pool->size < S390_POOL_CHUNK_MAX)
5930 continue;
5932 s390_end_pool (curr_pool, NULL_RTX);
5933 curr_pool = NULL;
5935 else
5937 int chunk_size = INSN_ADDRESSES (INSN_UID (insn))
5938 - INSN_ADDRESSES (INSN_UID (curr_pool->first_insn))
5939 + extra_size;
5941 /* We will later have to insert base register reload insns.
5942 Those will have an effect on code size, which we need to
5943 consider here. This calculation makes rather pessimistic
5944 worst-case assumptions. */
5945 if (GET_CODE (insn) == CODE_LABEL)
5946 extra_size += 6;
5948 if (chunk_size < S390_POOL_CHUNK_MIN
5949 && curr_pool->size < S390_POOL_CHUNK_MIN)
5950 continue;
5952 /* Pool chunks can only be inserted after BARRIERs ... */
5953 if (GET_CODE (insn) == BARRIER)
5955 s390_end_pool (curr_pool, insn);
5956 curr_pool = NULL;
5957 extra_size = 0;
5960 /* ... so if we don't find one in time, create one. */
5961 else if ((chunk_size > S390_POOL_CHUNK_MAX
5962 || curr_pool->size > S390_POOL_CHUNK_MAX))
5964 rtx label, jump, barrier;
5966 /* We can insert the barrier only after a 'real' insn. */
5967 if (GET_CODE (insn) != INSN && GET_CODE (insn) != CALL_INSN)
5968 continue;
5969 if (get_attr_length (insn) == 0)
5970 continue;
5972 /* Don't separate LTREL_BASE from the corresponding
5973 LTREL_OFFSET load. */
5974 if (pending_ltrel)
5975 continue;
5977 label = gen_label_rtx ();
5978 jump = emit_jump_insn_after (gen_jump (label), insn);
5979 barrier = emit_barrier_after (jump);
5980 insn = emit_label_after (label, barrier);
5981 JUMP_LABEL (jump) = label;
5982 LABEL_NUSES (label) = 1;
5984 INSN_ADDRESSES_NEW (jump, -1);
5985 INSN_ADDRESSES_NEW (barrier, -1);
5986 INSN_ADDRESSES_NEW (insn, -1);
5988 s390_end_pool (curr_pool, barrier);
5989 curr_pool = NULL;
5990 extra_size = 0;
5995 if (curr_pool)
5996 s390_end_pool (curr_pool, NULL_RTX);
5997 gcc_assert (!pending_ltrel);
5999 /* Find all labels that are branched into
6000 from an insn belonging to a different chunk. */
6002 far_labels = BITMAP_ALLOC (NULL);
6004 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6006 /* Labels marked with LABEL_PRESERVE_P can be target
6007 of non-local jumps, so we have to mark them.
6008 The same holds for named labels.
6010 Don't do that, however, if it is the label before
6011 a jump table. */
6013 if (GET_CODE (insn) == CODE_LABEL
6014 && (LABEL_PRESERVE_P (insn) || LABEL_NAME (insn)))
6016 rtx vec_insn = next_real_insn (insn);
6017 rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
6018 PATTERN (vec_insn) : NULL_RTX;
6019 if (!vec_pat
6020 || !(GET_CODE (vec_pat) == ADDR_VEC
6021 || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
6022 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (insn));
6025 /* If we have a direct jump (conditional or unconditional)
6026 or a casesi jump, check all potential targets. */
6027 else if (GET_CODE (insn) == JUMP_INSN)
6029 rtx pat = PATTERN (insn);
6030 if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
6031 pat = XVECEXP (pat, 0, 0);
6033 if (GET_CODE (pat) == SET)
6035 rtx label = JUMP_LABEL (insn);
6036 if (label)
6038 if (s390_find_pool (pool_list, label)
6039 != s390_find_pool (pool_list, insn))
6040 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
6043 else if (GET_CODE (pat) == PARALLEL
6044 && XVECLEN (pat, 0) == 2
6045 && GET_CODE (XVECEXP (pat, 0, 0)) == SET
6046 && GET_CODE (XVECEXP (pat, 0, 1)) == USE
6047 && GET_CODE (XEXP (XVECEXP (pat, 0, 1), 0)) == LABEL_REF)
6049 /* Find the jump table used by this casesi jump. */
6050 rtx vec_label = XEXP (XEXP (XVECEXP (pat, 0, 1), 0), 0);
6051 rtx vec_insn = next_real_insn (vec_label);
6052 rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
6053 PATTERN (vec_insn) : NULL_RTX;
6054 if (vec_pat
6055 && (GET_CODE (vec_pat) == ADDR_VEC
6056 || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
6058 int i, diff_p = GET_CODE (vec_pat) == ADDR_DIFF_VEC;
6060 for (i = 0; i < XVECLEN (vec_pat, diff_p); i++)
6062 rtx label = XEXP (XVECEXP (vec_pat, diff_p, i), 0);
6064 if (s390_find_pool (pool_list, label)
6065 != s390_find_pool (pool_list, insn))
6066 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
6073 /* Insert base register reload insns before every pool. */
6075 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
6077 rtx new_insn = gen_reload_base (cfun->machine->base_reg,
6078 curr_pool->label);
6079 rtx insn = curr_pool->first_insn;
6080 INSN_ADDRESSES_NEW (emit_insn_before (new_insn, insn), -1);
6083 /* Insert base register reload insns at every far label. */
6085 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6086 if (GET_CODE (insn) == CODE_LABEL
6087 && bitmap_bit_p (far_labels, CODE_LABEL_NUMBER (insn)))
6089 struct constant_pool *pool = s390_find_pool (pool_list, insn);
6090 if (pool)
6092 rtx new_insn = gen_reload_base (cfun->machine->base_reg,
6093 pool->label);
6094 INSN_ADDRESSES_NEW (emit_insn_after (new_insn, insn), -1);
6099 BITMAP_FREE (far_labels);
6102 /* Recompute insn addresses. */
6104 init_insn_lengths ();
6105 shorten_branches (get_insns ());
6107 return pool_list;
6110 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
6111 After we have decided to use this list, finish implementing
6112 all changes to the current function as required. */
6114 static void
6115 s390_chunkify_finish (struct constant_pool *pool_list)
6117 struct constant_pool *curr_pool = NULL;
6118 rtx insn;
6121 /* Replace all literal pool references. */
6123 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6125 if (INSN_P (insn))
6126 replace_ltrel_base (&PATTERN (insn));
6128 curr_pool = s390_find_pool (pool_list, insn);
6129 if (!curr_pool)
6130 continue;
6132 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
6134 rtx addr, pool_ref = NULL_RTX;
6135 find_constant_pool_ref (PATTERN (insn), &pool_ref);
6136 if (pool_ref)
6138 if (s390_execute_label (insn))
6139 addr = s390_find_execute (curr_pool, insn);
6140 else
6141 addr = s390_find_constant (curr_pool,
6142 get_pool_constant (pool_ref),
6143 get_pool_mode (pool_ref));
6145 replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
6146 INSN_CODE (insn) = -1;
6151 /* Dump out all literal pools. */
6153 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
6154 s390_dump_pool (curr_pool, 0);
6156 /* Free pool list. */
6158 while (pool_list)
6160 struct constant_pool *next = pool_list->next;
6161 s390_free_pool (pool_list);
6162 pool_list = next;
6166 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
6167 We have decided we cannot use this list, so revert all changes
6168 to the current function that were done by s390_chunkify_start. */
6170 static void
6171 s390_chunkify_cancel (struct constant_pool *pool_list)
6173 struct constant_pool *curr_pool = NULL;
6174 rtx insn;
6176 /* Remove all pool placeholder insns. */
6178 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
6180 /* Did we insert an extra barrier? Remove it. */
6181 rtx barrier = PREV_INSN (curr_pool->pool_insn);
6182 rtx jump = barrier? PREV_INSN (barrier) : NULL_RTX;
6183 rtx label = NEXT_INSN (curr_pool->pool_insn);
6185 if (jump && GET_CODE (jump) == JUMP_INSN
6186 && barrier && GET_CODE (barrier) == BARRIER
6187 && label && GET_CODE (label) == CODE_LABEL
6188 && GET_CODE (PATTERN (jump)) == SET
6189 && SET_DEST (PATTERN (jump)) == pc_rtx
6190 && GET_CODE (SET_SRC (PATTERN (jump))) == LABEL_REF
6191 && XEXP (SET_SRC (PATTERN (jump)), 0) == label)
6193 remove_insn (jump);
6194 remove_insn (barrier);
6195 remove_insn (label);
6198 remove_insn (curr_pool->pool_insn);
6201 /* Remove all base register reload insns. */
6203 for (insn = get_insns (); insn; )
6205 rtx next_insn = NEXT_INSN (insn);
6207 if (GET_CODE (insn) == INSN
6208 && GET_CODE (PATTERN (insn)) == SET
6209 && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC
6210 && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPEC_RELOAD_BASE)
6211 remove_insn (insn);
6213 insn = next_insn;
6216 /* Free pool list. */
6218 while (pool_list)
6220 struct constant_pool *next = pool_list->next;
6221 s390_free_pool (pool_list);
6222 pool_list = next;
6227 /* Output the constant pool entry EXP in mode MODE with alignment ALIGN. */
6229 void
6230 s390_output_pool_entry (rtx exp, enum machine_mode mode, unsigned int align)
6232 REAL_VALUE_TYPE r;
6234 switch (GET_MODE_CLASS (mode))
6236 case MODE_FLOAT:
6237 case MODE_DECIMAL_FLOAT:
6238 gcc_assert (GET_CODE (exp) == CONST_DOUBLE);
6240 REAL_VALUE_FROM_CONST_DOUBLE (r, exp);
6241 assemble_real (r, mode, align);
6242 break;
6244 case MODE_INT:
6245 assemble_integer (exp, GET_MODE_SIZE (mode), align, 1);
6246 break;
6248 default:
6249 gcc_unreachable ();
6254 /* Return an RTL expression representing the value of the return address
6255 for the frame COUNT steps up from the current frame. FRAME is the
6256 frame pointer of that frame. */
6259 s390_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
6261 int offset;
6262 rtx addr;
6264 /* Without backchain, we fail for all but the current frame. */
6266 if (!TARGET_BACKCHAIN && count > 0)
6267 return NULL_RTX;
6269 /* For the current frame, we need to make sure the initial
6270 value of RETURN_REGNUM is actually saved. */
6272 if (count == 0)
6274 /* On non-z architectures branch splitting could overwrite r14. */
6275 if (TARGET_CPU_ZARCH)
6276 return get_hard_reg_initial_val (Pmode, RETURN_REGNUM);
6277 else
6279 cfun_frame_layout.save_return_addr_p = true;
6280 return gen_rtx_MEM (Pmode, return_address_pointer_rtx);
6284 if (TARGET_PACKED_STACK)
6285 offset = -2 * UNITS_PER_WORD;
6286 else
6287 offset = RETURN_REGNUM * UNITS_PER_WORD;
6289 addr = plus_constant (frame, offset);
6290 addr = memory_address (Pmode, addr);
6291 return gen_rtx_MEM (Pmode, addr);
6294 /* Return an RTL expression representing the back chain stored in
6295 the current stack frame. */
6298 s390_back_chain_rtx (void)
6300 rtx chain;
6302 gcc_assert (TARGET_BACKCHAIN);
6304 if (TARGET_PACKED_STACK)
6305 chain = plus_constant (stack_pointer_rtx,
6306 STACK_POINTER_OFFSET - UNITS_PER_WORD);
6307 else
6308 chain = stack_pointer_rtx;
6310 chain = gen_rtx_MEM (Pmode, chain);
6311 return chain;
6314 /* Find first call clobbered register unused in a function.
6315 This could be used as base register in a leaf function
6316 or for holding the return address before epilogue. */
6318 static int
6319 find_unused_clobbered_reg (void)
6321 int i;
6322 for (i = 0; i < 6; i++)
6323 if (!regs_ever_live[i])
6324 return i;
6325 return 0;
6329 /* Helper function for s390_regs_ever_clobbered. Sets the fields in DATA for all
6330 clobbered hard regs in SETREG. */
6332 static void
6333 s390_reg_clobbered_rtx (rtx setreg, rtx set_insn ATTRIBUTE_UNUSED, void *data)
6335 int *regs_ever_clobbered = (int *)data;
6336 unsigned int i, regno;
6337 enum machine_mode mode = GET_MODE (setreg);
6339 if (GET_CODE (setreg) == SUBREG)
6341 rtx inner = SUBREG_REG (setreg);
6342 if (!GENERAL_REG_P (inner))
6343 return;
6344 regno = subreg_regno (setreg);
6346 else if (GENERAL_REG_P (setreg))
6347 regno = REGNO (setreg);
6348 else
6349 return;
6351 for (i = regno;
6352 i < regno + HARD_REGNO_NREGS (regno, mode);
6353 i++)
6354 regs_ever_clobbered[i] = 1;
6357 /* Walks through all basic blocks of the current function looking
6358 for clobbered hard regs using s390_reg_clobbered_rtx. The fields
6359 of the passed integer array REGS_EVER_CLOBBERED are set to one for
6360 each of those regs. */
6362 static void
6363 s390_regs_ever_clobbered (int *regs_ever_clobbered)
6365 basic_block cur_bb;
6366 rtx cur_insn;
6367 unsigned int i;
6369 memset (regs_ever_clobbered, 0, 16 * sizeof (int));
6371 /* For non-leaf functions we have to consider all call clobbered regs to be
6372 clobbered. */
6373 if (!current_function_is_leaf)
6375 for (i = 0; i < 16; i++)
6376 regs_ever_clobbered[i] = call_really_used_regs[i];
6379 /* Make the "magic" eh_return registers live if necessary. For regs_ever_live
6380 this work is done by liveness analysis (mark_regs_live_at_end).
6381 Special care is needed for functions containing landing pads. Landing pads
6382 may use the eh registers, but the code which sets these registers is not
6383 contained in that function. Hence s390_regs_ever_clobbered is not able to
6384 deal with this automatically. */
6385 if (current_function_calls_eh_return || cfun->machine->has_landing_pad_p)
6386 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM ; i++)
6387 if (current_function_calls_eh_return
6388 || (cfun->machine->has_landing_pad_p
6389 && regs_ever_live [EH_RETURN_DATA_REGNO (i)]))
6390 regs_ever_clobbered[EH_RETURN_DATA_REGNO (i)] = 1;
6392 /* For nonlocal gotos all call-saved registers have to be saved.
6393 This flag is also set for the unwinding code in libgcc.
6394 See expand_builtin_unwind_init. For regs_ever_live this is done by
6395 reload. */
6396 if (current_function_has_nonlocal_label)
6397 for (i = 0; i < 16; i++)
6398 if (!call_really_used_regs[i])
6399 regs_ever_clobbered[i] = 1;
6401 FOR_EACH_BB (cur_bb)
6403 FOR_BB_INSNS (cur_bb, cur_insn)
6405 if (INSN_P (cur_insn))
6406 note_stores (PATTERN (cur_insn),
6407 s390_reg_clobbered_rtx,
6408 regs_ever_clobbered);
6413 /* Determine the frame area which actually has to be accessed
6414 in the function epilogue. The values are stored at the
6415 given pointers AREA_BOTTOM (address of the lowest used stack
6416 address) and AREA_TOP (address of the first item which does
6417 not belong to the stack frame). */
6419 static void
6420 s390_frame_area (int *area_bottom, int *area_top)
6422 int b, t;
6423 int i;
6425 b = INT_MAX;
6426 t = INT_MIN;
6428 if (cfun_frame_layout.first_restore_gpr != -1)
6430 b = (cfun_frame_layout.gprs_offset
6431 + cfun_frame_layout.first_restore_gpr * UNITS_PER_WORD);
6432 t = b + (cfun_frame_layout.last_restore_gpr
6433 - cfun_frame_layout.first_restore_gpr + 1) * UNITS_PER_WORD;
6436 if (TARGET_64BIT && cfun_save_high_fprs_p)
6438 b = MIN (b, cfun_frame_layout.f8_offset);
6439 t = MAX (t, (cfun_frame_layout.f8_offset
6440 + cfun_frame_layout.high_fprs * 8));
6443 if (!TARGET_64BIT)
6444 for (i = 2; i < 4; i++)
6445 if (cfun_fpr_bit_p (i))
6447 b = MIN (b, cfun_frame_layout.f4_offset + (i - 2) * 8);
6448 t = MAX (t, cfun_frame_layout.f4_offset + (i - 1) * 8);
6451 *area_bottom = b;
6452 *area_top = t;
6455 /* Fill cfun->machine with info about register usage of current function.
6456 Return in CLOBBERED_REGS which GPRs are currently considered set. */
6458 static void
6459 s390_register_info (int clobbered_regs[])
6461 int i, j;
6463 /* fprs 8 - 15 are call saved for 64 Bit ABI. */
6464 cfun_frame_layout.fpr_bitmap = 0;
6465 cfun_frame_layout.high_fprs = 0;
6466 if (TARGET_64BIT)
6467 for (i = 24; i < 32; i++)
6468 if (regs_ever_live[i] && !global_regs[i])
6470 cfun_set_fpr_bit (i - 16);
6471 cfun_frame_layout.high_fprs++;
6474 /* Find first and last gpr to be saved. We trust regs_ever_live
6475 data, except that we don't save and restore global registers.
6477 Also, all registers with special meaning to the compiler need
6478 to be handled extra. */
6480 s390_regs_ever_clobbered (clobbered_regs);
6482 for (i = 0; i < 16; i++)
6483 clobbered_regs[i] = clobbered_regs[i] && !global_regs[i] && !fixed_regs[i];
6485 if (frame_pointer_needed)
6486 clobbered_regs[HARD_FRAME_POINTER_REGNUM] = 1;
6488 if (flag_pic)
6489 clobbered_regs[PIC_OFFSET_TABLE_REGNUM]
6490 |= regs_ever_live[PIC_OFFSET_TABLE_REGNUM];
6492 clobbered_regs[BASE_REGNUM]
6493 |= (cfun->machine->base_reg
6494 && REGNO (cfun->machine->base_reg) == BASE_REGNUM);
6496 clobbered_regs[RETURN_REGNUM]
6497 |= (!current_function_is_leaf
6498 || TARGET_TPF_PROFILING
6499 || cfun->machine->split_branches_pending_p
6500 || cfun_frame_layout.save_return_addr_p
6501 || current_function_calls_eh_return
6502 || current_function_stdarg);
6504 clobbered_regs[STACK_POINTER_REGNUM]
6505 |= (!current_function_is_leaf
6506 || TARGET_TPF_PROFILING
6507 || cfun_save_high_fprs_p
6508 || get_frame_size () > 0
6509 || current_function_calls_alloca
6510 || current_function_stdarg);
6512 for (i = 6; i < 16; i++)
6513 if (regs_ever_live[i] || clobbered_regs[i])
6514 break;
6515 for (j = 15; j > i; j--)
6516 if (regs_ever_live[j] || clobbered_regs[j])
6517 break;
6519 if (i == 16)
6521 /* Nothing to save/restore. */
6522 cfun_frame_layout.first_save_gpr_slot = -1;
6523 cfun_frame_layout.last_save_gpr_slot = -1;
6524 cfun_frame_layout.first_save_gpr = -1;
6525 cfun_frame_layout.first_restore_gpr = -1;
6526 cfun_frame_layout.last_save_gpr = -1;
6527 cfun_frame_layout.last_restore_gpr = -1;
6529 else
6531 /* Save slots for gprs from i to j. */
6532 cfun_frame_layout.first_save_gpr_slot = i;
6533 cfun_frame_layout.last_save_gpr_slot = j;
6535 for (i = cfun_frame_layout.first_save_gpr_slot;
6536 i < cfun_frame_layout.last_save_gpr_slot + 1;
6537 i++)
6538 if (clobbered_regs[i])
6539 break;
6541 for (j = cfun_frame_layout.last_save_gpr_slot; j > i; j--)
6542 if (clobbered_regs[j])
6543 break;
6545 if (i == cfun_frame_layout.last_save_gpr_slot + 1)
6547 /* Nothing to save/restore. */
6548 cfun_frame_layout.first_save_gpr = -1;
6549 cfun_frame_layout.first_restore_gpr = -1;
6550 cfun_frame_layout.last_save_gpr = -1;
6551 cfun_frame_layout.last_restore_gpr = -1;
6553 else
6555 /* Save / Restore from gpr i to j. */
6556 cfun_frame_layout.first_save_gpr = i;
6557 cfun_frame_layout.first_restore_gpr = i;
6558 cfun_frame_layout.last_save_gpr = j;
6559 cfun_frame_layout.last_restore_gpr = j;
6563 if (current_function_stdarg)
6565 /* Varargs functions need to save gprs 2 to 6. */
6566 if (cfun->va_list_gpr_size
6567 && current_function_args_info.gprs < GP_ARG_NUM_REG)
6569 int min_gpr = current_function_args_info.gprs;
6570 int max_gpr = min_gpr + cfun->va_list_gpr_size;
6571 if (max_gpr > GP_ARG_NUM_REG)
6572 max_gpr = GP_ARG_NUM_REG;
6574 if (cfun_frame_layout.first_save_gpr == -1
6575 || cfun_frame_layout.first_save_gpr > 2 + min_gpr)
6577 cfun_frame_layout.first_save_gpr = 2 + min_gpr;
6578 cfun_frame_layout.first_save_gpr_slot = 2 + min_gpr;
6581 if (cfun_frame_layout.last_save_gpr == -1
6582 || cfun_frame_layout.last_save_gpr < 2 + max_gpr - 1)
6584 cfun_frame_layout.last_save_gpr = 2 + max_gpr - 1;
6585 cfun_frame_layout.last_save_gpr_slot = 2 + max_gpr - 1;
6589 /* Mark f0, f2 for 31 bit and f0-f4 for 64 bit to be saved. */
6590 if (TARGET_HARD_FLOAT && cfun->va_list_fpr_size
6591 && current_function_args_info.fprs < FP_ARG_NUM_REG)
6593 int min_fpr = current_function_args_info.fprs;
6594 int max_fpr = min_fpr + cfun->va_list_fpr_size;
6595 if (max_fpr > FP_ARG_NUM_REG)
6596 max_fpr = FP_ARG_NUM_REG;
6598 /* ??? This is currently required to ensure proper location
6599 of the fpr save slots within the va_list save area. */
6600 if (TARGET_PACKED_STACK)
6601 min_fpr = 0;
6603 for (i = min_fpr; i < max_fpr; i++)
6604 cfun_set_fpr_bit (i);
6608 if (!TARGET_64BIT)
6609 for (i = 2; i < 4; i++)
6610 if (regs_ever_live[i + 16] && !global_regs[i + 16])
6611 cfun_set_fpr_bit (i);
6614 /* Fill cfun->machine with info about frame of current function. */
6616 static void
6617 s390_frame_info (void)
6619 int i;
6621 cfun_frame_layout.frame_size = get_frame_size ();
6622 if (!TARGET_64BIT && cfun_frame_layout.frame_size > 0x7fff0000)
6623 fatal_error ("total size of local variables exceeds architecture limit");
6625 if (!TARGET_PACKED_STACK)
6627 cfun_frame_layout.backchain_offset = 0;
6628 cfun_frame_layout.f0_offset = 16 * UNITS_PER_WORD;
6629 cfun_frame_layout.f4_offset = cfun_frame_layout.f0_offset + 2 * 8;
6630 cfun_frame_layout.f8_offset = -cfun_frame_layout.high_fprs * 8;
6631 cfun_frame_layout.gprs_offset = (cfun_frame_layout.first_save_gpr_slot
6632 * UNITS_PER_WORD);
6634 else if (TARGET_BACKCHAIN) /* kernel stack layout */
6636 cfun_frame_layout.backchain_offset = (STACK_POINTER_OFFSET
6637 - UNITS_PER_WORD);
6638 cfun_frame_layout.gprs_offset
6639 = (cfun_frame_layout.backchain_offset
6640 - (STACK_POINTER_REGNUM - cfun_frame_layout.first_save_gpr_slot + 1)
6641 * UNITS_PER_WORD);
6643 if (TARGET_64BIT)
6645 cfun_frame_layout.f4_offset
6646 = (cfun_frame_layout.gprs_offset
6647 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6649 cfun_frame_layout.f0_offset
6650 = (cfun_frame_layout.f4_offset
6651 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6653 else
6655 /* On 31 bit we have to care about alignment of the
6656 floating point regs to provide fastest access. */
6657 cfun_frame_layout.f0_offset
6658 = ((cfun_frame_layout.gprs_offset
6659 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1))
6660 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6662 cfun_frame_layout.f4_offset
6663 = (cfun_frame_layout.f0_offset
6664 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6667 else /* no backchain */
6669 cfun_frame_layout.f4_offset
6670 = (STACK_POINTER_OFFSET
6671 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6673 cfun_frame_layout.f0_offset
6674 = (cfun_frame_layout.f4_offset
6675 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6677 cfun_frame_layout.gprs_offset
6678 = cfun_frame_layout.f0_offset - cfun_gprs_save_area_size;
6681 if (current_function_is_leaf
6682 && !TARGET_TPF_PROFILING
6683 && cfun_frame_layout.frame_size == 0
6684 && !cfun_save_high_fprs_p
6685 && !current_function_calls_alloca
6686 && !current_function_stdarg)
6687 return;
6689 if (!TARGET_PACKED_STACK)
6690 cfun_frame_layout.frame_size += (STACK_POINTER_OFFSET
6691 + current_function_outgoing_args_size
6692 + cfun_frame_layout.high_fprs * 8);
6693 else
6695 if (TARGET_BACKCHAIN)
6696 cfun_frame_layout.frame_size += UNITS_PER_WORD;
6698 /* No alignment trouble here because f8-f15 are only saved under
6699 64 bit. */
6700 cfun_frame_layout.f8_offset = (MIN (MIN (cfun_frame_layout.f0_offset,
6701 cfun_frame_layout.f4_offset),
6702 cfun_frame_layout.gprs_offset)
6703 - cfun_frame_layout.high_fprs * 8);
6705 cfun_frame_layout.frame_size += cfun_frame_layout.high_fprs * 8;
6707 for (i = 0; i < 8; i++)
6708 if (cfun_fpr_bit_p (i))
6709 cfun_frame_layout.frame_size += 8;
6711 cfun_frame_layout.frame_size += cfun_gprs_save_area_size;
6713 /* If under 31 bit an odd number of gprs has to be saved we have to adjust
6714 the frame size to sustain 8 byte alignment of stack frames. */
6715 cfun_frame_layout.frame_size = ((cfun_frame_layout.frame_size +
6716 STACK_BOUNDARY / BITS_PER_UNIT - 1)
6717 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
6719 cfun_frame_layout.frame_size += current_function_outgoing_args_size;
6723 /* Generate frame layout. Fills in register and frame data for the current
6724 function in cfun->machine. This routine can be called multiple times;
6725 it will re-do the complete frame layout every time. */
6727 static void
6728 s390_init_frame_layout (void)
6730 HOST_WIDE_INT frame_size;
6731 int base_used;
6732 int clobbered_regs[16];
6734 /* On S/390 machines, we may need to perform branch splitting, which
6735 will require both base and return address register. We have no
6736 choice but to assume we're going to need them until right at the
6737 end of the machine dependent reorg phase. */
6738 if (!TARGET_CPU_ZARCH)
6739 cfun->machine->split_branches_pending_p = true;
6743 frame_size = cfun_frame_layout.frame_size;
6745 /* Try to predict whether we'll need the base register. */
6746 base_used = cfun->machine->split_branches_pending_p
6747 || current_function_uses_const_pool
6748 || (!DISP_IN_RANGE (-frame_size)
6749 && !CONST_OK_FOR_K (-frame_size));
6751 /* Decide which register to use as literal pool base. In small
6752 leaf functions, try to use an unused call-clobbered register
6753 as base register to avoid save/restore overhead. */
6754 if (!base_used)
6755 cfun->machine->base_reg = NULL_RTX;
6756 else if (current_function_is_leaf && !regs_ever_live[5])
6757 cfun->machine->base_reg = gen_rtx_REG (Pmode, 5);
6758 else
6759 cfun->machine->base_reg = gen_rtx_REG (Pmode, BASE_REGNUM);
6761 s390_register_info (clobbered_regs);
6762 s390_frame_info ();
6764 while (frame_size != cfun_frame_layout.frame_size);
6767 /* Update frame layout. Recompute actual register save data based on
6768 current info and update regs_ever_live for the special registers.
6769 May be called multiple times, but may never cause *more* registers
6770 to be saved than s390_init_frame_layout allocated room for. */
6772 static void
6773 s390_update_frame_layout (void)
6775 int clobbered_regs[16];
6777 s390_register_info (clobbered_regs);
6779 regs_ever_live[BASE_REGNUM] = clobbered_regs[BASE_REGNUM];
6780 regs_ever_live[RETURN_REGNUM] = clobbered_regs[RETURN_REGNUM];
6781 regs_ever_live[STACK_POINTER_REGNUM] = clobbered_regs[STACK_POINTER_REGNUM];
6783 if (cfun->machine->base_reg)
6784 regs_ever_live[REGNO (cfun->machine->base_reg)] = 1;
6787 /* Return true if it is legal to put a value with MODE into REGNO. */
6789 bool
6790 s390_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
6792 switch (REGNO_REG_CLASS (regno))
6794 case FP_REGS:
6795 if (REGNO_PAIR_OK (regno, mode))
6797 if (mode == SImode || mode == DImode)
6798 return true;
6800 if (FLOAT_MODE_P (mode) && GET_MODE_CLASS (mode) != MODE_VECTOR_FLOAT)
6801 return true;
6803 break;
6804 case ADDR_REGS:
6805 if (FRAME_REGNO_P (regno) && mode == Pmode)
6806 return true;
6808 /* fallthrough */
6809 case GENERAL_REGS:
6810 if (REGNO_PAIR_OK (regno, mode))
6812 if (TARGET_64BIT
6813 || (mode != TFmode && mode != TCmode && mode != TDmode))
6814 return true;
6816 break;
6817 case CC_REGS:
6818 if (GET_MODE_CLASS (mode) == MODE_CC)
6819 return true;
6820 break;
6821 case ACCESS_REGS:
6822 if (REGNO_PAIR_OK (regno, mode))
6824 if (mode == SImode || mode == Pmode)
6825 return true;
6827 break;
6828 default:
6829 return false;
6832 return false;
6835 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
6837 bool
6838 s390_hard_regno_rename_ok (unsigned int old_reg, unsigned int new_reg)
6840 /* Once we've decided upon a register to use as base register, it must
6841 no longer be used for any other purpose. */
6842 if (cfun->machine->base_reg)
6843 if (REGNO (cfun->machine->base_reg) == old_reg
6844 || REGNO (cfun->machine->base_reg) == new_reg)
6845 return false;
6847 return true;
6850 /* Maximum number of registers to represent a value of mode MODE
6851 in a register of class CLASS. */
6853 bool
6854 s390_class_max_nregs (enum reg_class class, enum machine_mode mode)
6856 switch (class)
6858 case FP_REGS:
6859 if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
6860 return 2 * ((GET_MODE_SIZE (mode) / 2 + 8 - 1) / 8);
6861 else
6862 return (GET_MODE_SIZE (mode) + 8 - 1) / 8;
6863 case ACCESS_REGS:
6864 return (GET_MODE_SIZE (mode) + 4 - 1) / 4;
6865 default:
6866 break;
6868 return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6871 /* Return true if register FROM can be eliminated via register TO. */
6873 bool
6874 s390_can_eliminate (int from, int to)
6876 /* On zSeries machines, we have not marked the base register as fixed.
6877 Instead, we have an elimination rule BASE_REGNUM -> BASE_REGNUM.
6878 If a function requires the base register, we say here that this
6879 elimination cannot be performed. This will cause reload to free
6880 up the base register (as if it were fixed). On the other hand,
6881 if the current function does *not* require the base register, we
6882 say here the elimination succeeds, which in turn allows reload
6883 to allocate the base register for any other purpose. */
6884 if (from == BASE_REGNUM && to == BASE_REGNUM)
6886 if (TARGET_CPU_ZARCH)
6888 s390_init_frame_layout ();
6889 return cfun->machine->base_reg == NULL_RTX;
6892 return false;
6895 /* Everything else must point into the stack frame. */
6896 gcc_assert (to == STACK_POINTER_REGNUM
6897 || to == HARD_FRAME_POINTER_REGNUM);
6899 gcc_assert (from == FRAME_POINTER_REGNUM
6900 || from == ARG_POINTER_REGNUM
6901 || from == RETURN_ADDRESS_POINTER_REGNUM);
6903 /* Make sure we actually saved the return address. */
6904 if (from == RETURN_ADDRESS_POINTER_REGNUM)
6905 if (!current_function_calls_eh_return
6906 && !current_function_stdarg
6907 && !cfun_frame_layout.save_return_addr_p)
6908 return false;
6910 return true;
6913 /* Return offset between register FROM and TO initially after prolog. */
6915 HOST_WIDE_INT
6916 s390_initial_elimination_offset (int from, int to)
6918 HOST_WIDE_INT offset;
6919 int index;
6921 /* ??? Why are we called for non-eliminable pairs? */
6922 if (!s390_can_eliminate (from, to))
6923 return 0;
6925 switch (from)
6927 case FRAME_POINTER_REGNUM:
6928 offset = (get_frame_size()
6929 + STACK_POINTER_OFFSET
6930 + current_function_outgoing_args_size);
6931 break;
6933 case ARG_POINTER_REGNUM:
6934 s390_init_frame_layout ();
6935 offset = cfun_frame_layout.frame_size + STACK_POINTER_OFFSET;
6936 break;
6938 case RETURN_ADDRESS_POINTER_REGNUM:
6939 s390_init_frame_layout ();
6940 index = RETURN_REGNUM - cfun_frame_layout.first_save_gpr_slot;
6941 gcc_assert (index >= 0);
6942 offset = cfun_frame_layout.frame_size + cfun_frame_layout.gprs_offset;
6943 offset += index * UNITS_PER_WORD;
6944 break;
6946 case BASE_REGNUM:
6947 offset = 0;
6948 break;
6950 default:
6951 gcc_unreachable ();
6954 return offset;
6957 /* Emit insn to save fpr REGNUM at offset OFFSET relative
6958 to register BASE. Return generated insn. */
6960 static rtx
6961 save_fpr (rtx base, int offset, int regnum)
6963 rtx addr;
6964 addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
6966 if (regnum >= 16 && regnum <= (16 + FP_ARG_NUM_REG))
6967 set_mem_alias_set (addr, get_varargs_alias_set ());
6968 else
6969 set_mem_alias_set (addr, get_frame_alias_set ());
6971 return emit_move_insn (addr, gen_rtx_REG (DFmode, regnum));
6974 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
6975 to register BASE. Return generated insn. */
6977 static rtx
6978 restore_fpr (rtx base, int offset, int regnum)
6980 rtx addr;
6981 addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
6982 set_mem_alias_set (addr, get_frame_alias_set ());
6984 return emit_move_insn (gen_rtx_REG (DFmode, regnum), addr);
6987 /* Generate insn to save registers FIRST to LAST into
6988 the register save area located at offset OFFSET
6989 relative to register BASE. */
6991 static rtx
6992 save_gprs (rtx base, int offset, int first, int last)
6994 rtx addr, insn, note;
6995 int i;
6997 addr = plus_constant (base, offset);
6998 addr = gen_rtx_MEM (Pmode, addr);
7000 set_mem_alias_set (addr, get_frame_alias_set ());
7002 /* Special-case single register. */
7003 if (first == last)
7005 if (TARGET_64BIT)
7006 insn = gen_movdi (addr, gen_rtx_REG (Pmode, first));
7007 else
7008 insn = gen_movsi (addr, gen_rtx_REG (Pmode, first));
7010 RTX_FRAME_RELATED_P (insn) = 1;
7011 return insn;
7015 insn = gen_store_multiple (addr,
7016 gen_rtx_REG (Pmode, first),
7017 GEN_INT (last - first + 1));
7019 if (first <= 6 && current_function_stdarg)
7020 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
7022 rtx mem = XEXP (XVECEXP (PATTERN (insn), 0, i), 0);
7024 if (first + i <= 6)
7025 set_mem_alias_set (mem, get_varargs_alias_set ());
7028 /* We need to set the FRAME_RELATED flag on all SETs
7029 inside the store-multiple pattern.
7031 However, we must not emit DWARF records for registers 2..5
7032 if they are stored for use by variable arguments ...
7034 ??? Unfortunately, it is not enough to simply not the
7035 FRAME_RELATED flags for those SETs, because the first SET
7036 of the PARALLEL is always treated as if it had the flag
7037 set, even if it does not. Therefore we emit a new pattern
7038 without those registers as REG_FRAME_RELATED_EXPR note. */
7040 if (first >= 6)
7042 rtx pat = PATTERN (insn);
7044 for (i = 0; i < XVECLEN (pat, 0); i++)
7045 if (GET_CODE (XVECEXP (pat, 0, i)) == SET)
7046 RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1;
7048 RTX_FRAME_RELATED_P (insn) = 1;
7050 else if (last >= 6)
7052 addr = plus_constant (base, offset + (6 - first) * UNITS_PER_WORD);
7053 note = gen_store_multiple (gen_rtx_MEM (Pmode, addr),
7054 gen_rtx_REG (Pmode, 6),
7055 GEN_INT (last - 6 + 1));
7056 note = PATTERN (note);
7058 REG_NOTES (insn) =
7059 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
7060 note, REG_NOTES (insn));
7062 for (i = 0; i < XVECLEN (note, 0); i++)
7063 if (GET_CODE (XVECEXP (note, 0, i)) == SET)
7064 RTX_FRAME_RELATED_P (XVECEXP (note, 0, i)) = 1;
7066 RTX_FRAME_RELATED_P (insn) = 1;
7069 return insn;
7072 /* Generate insn to restore registers FIRST to LAST from
7073 the register save area located at offset OFFSET
7074 relative to register BASE. */
7076 static rtx
7077 restore_gprs (rtx base, int offset, int first, int last)
7079 rtx addr, insn;
7081 addr = plus_constant (base, offset);
7082 addr = gen_rtx_MEM (Pmode, addr);
7083 set_mem_alias_set (addr, get_frame_alias_set ());
7085 /* Special-case single register. */
7086 if (first == last)
7088 if (TARGET_64BIT)
7089 insn = gen_movdi (gen_rtx_REG (Pmode, first), addr);
7090 else
7091 insn = gen_movsi (gen_rtx_REG (Pmode, first), addr);
7093 return insn;
7096 insn = gen_load_multiple (gen_rtx_REG (Pmode, first),
7097 addr,
7098 GEN_INT (last - first + 1));
7099 return insn;
7102 /* Return insn sequence to load the GOT register. */
7104 static GTY(()) rtx got_symbol;
7106 s390_load_got (void)
7108 rtx insns;
7110 if (!got_symbol)
7112 got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
7113 SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
7116 start_sequence ();
7118 if (TARGET_CPU_ZARCH)
7120 emit_move_insn (pic_offset_table_rtx, got_symbol);
7122 else
7124 rtx offset;
7126 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got_symbol),
7127 UNSPEC_LTREL_OFFSET);
7128 offset = gen_rtx_CONST (Pmode, offset);
7129 offset = force_const_mem (Pmode, offset);
7131 emit_move_insn (pic_offset_table_rtx, offset);
7133 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (offset, 0)),
7134 UNSPEC_LTREL_BASE);
7135 offset = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, offset);
7137 emit_move_insn (pic_offset_table_rtx, offset);
7140 insns = get_insns ();
7141 end_sequence ();
7142 return insns;
7145 /* Expand the prologue into a bunch of separate insns. */
7147 void
7148 s390_emit_prologue (void)
7150 rtx insn, addr;
7151 rtx temp_reg;
7152 int i;
7153 int offset;
7154 int next_fpr = 0;
7156 /* Complete frame layout. */
7158 s390_update_frame_layout ();
7160 /* Annotate all constant pool references to let the scheduler know
7161 they implicitly use the base register. */
7163 push_topmost_sequence ();
7165 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7166 if (INSN_P (insn))
7167 annotate_constant_pool_refs (&PATTERN (insn));
7169 pop_topmost_sequence ();
7171 /* Choose best register to use for temp use within prologue.
7172 See below for why TPF must use the register 1. */
7174 if (!has_hard_reg_initial_val (Pmode, RETURN_REGNUM)
7175 && !current_function_is_leaf
7176 && !TARGET_TPF_PROFILING)
7177 temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
7178 else
7179 temp_reg = gen_rtx_REG (Pmode, 1);
7181 /* Save call saved gprs. */
7182 if (cfun_frame_layout.first_save_gpr != -1)
7184 insn = save_gprs (stack_pointer_rtx,
7185 cfun_frame_layout.gprs_offset +
7186 UNITS_PER_WORD * (cfun_frame_layout.first_save_gpr
7187 - cfun_frame_layout.first_save_gpr_slot),
7188 cfun_frame_layout.first_save_gpr,
7189 cfun_frame_layout.last_save_gpr);
7190 emit_insn (insn);
7193 /* Dummy insn to mark literal pool slot. */
7195 if (cfun->machine->base_reg)
7196 emit_insn (gen_main_pool (cfun->machine->base_reg));
7198 offset = cfun_frame_layout.f0_offset;
7200 /* Save f0 and f2. */
7201 for (i = 0; i < 2; i++)
7203 if (cfun_fpr_bit_p (i))
7205 save_fpr (stack_pointer_rtx, offset, i + 16);
7206 offset += 8;
7208 else if (!TARGET_PACKED_STACK)
7209 offset += 8;
7212 /* Save f4 and f6. */
7213 offset = cfun_frame_layout.f4_offset;
7214 for (i = 2; i < 4; i++)
7216 if (cfun_fpr_bit_p (i))
7218 insn = save_fpr (stack_pointer_rtx, offset, i + 16);
7219 offset += 8;
7221 /* If f4 and f6 are call clobbered they are saved due to stdargs and
7222 therefore are not frame related. */
7223 if (!call_really_used_regs[i + 16])
7224 RTX_FRAME_RELATED_P (insn) = 1;
7226 else if (!TARGET_PACKED_STACK)
7227 offset += 8;
7230 if (TARGET_PACKED_STACK
7231 && cfun_save_high_fprs_p
7232 && cfun_frame_layout.f8_offset + cfun_frame_layout.high_fprs * 8 > 0)
7234 offset = (cfun_frame_layout.f8_offset
7235 + (cfun_frame_layout.high_fprs - 1) * 8);
7237 for (i = 15; i > 7 && offset >= 0; i--)
7238 if (cfun_fpr_bit_p (i))
7240 insn = save_fpr (stack_pointer_rtx, offset, i + 16);
7242 RTX_FRAME_RELATED_P (insn) = 1;
7243 offset -= 8;
7245 if (offset >= cfun_frame_layout.f8_offset)
7246 next_fpr = i + 16;
7249 if (!TARGET_PACKED_STACK)
7250 next_fpr = cfun_save_high_fprs_p ? 31 : 0;
7252 /* Decrement stack pointer. */
7254 if (cfun_frame_layout.frame_size > 0)
7256 rtx frame_off = GEN_INT (-cfun_frame_layout.frame_size);
7258 if (s390_stack_size)
7260 HOST_WIDE_INT stack_check_mask = ((s390_stack_size - 1)
7261 & ~(s390_stack_guard - 1));
7262 rtx t = gen_rtx_AND (Pmode, stack_pointer_rtx,
7263 GEN_INT (stack_check_mask));
7265 if (TARGET_64BIT)
7266 gen_cmpdi (t, const0_rtx);
7267 else
7268 gen_cmpsi (t, const0_rtx);
7270 emit_insn (gen_conditional_trap (gen_rtx_EQ (CCmode,
7271 gen_rtx_REG (CCmode,
7272 CC_REGNUM),
7273 const0_rtx),
7274 const0_rtx));
7277 if (s390_warn_framesize > 0
7278 && cfun_frame_layout.frame_size >= s390_warn_framesize)
7279 warning (0, "frame size of %qs is " HOST_WIDE_INT_PRINT_DEC " bytes",
7280 current_function_name (), cfun_frame_layout.frame_size);
7282 if (s390_warn_dynamicstack_p && cfun->calls_alloca)
7283 warning (0, "%qs uses dynamic stack allocation", current_function_name ());
7285 /* Save incoming stack pointer into temp reg. */
7286 if (TARGET_BACKCHAIN || next_fpr)
7287 insn = emit_insn (gen_move_insn (temp_reg, stack_pointer_rtx));
7289 /* Subtract frame size from stack pointer. */
7291 if (DISP_IN_RANGE (INTVAL (frame_off)))
7293 insn = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
7294 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
7295 frame_off));
7296 insn = emit_insn (insn);
7298 else
7300 if (!CONST_OK_FOR_K (INTVAL (frame_off)))
7301 frame_off = force_const_mem (Pmode, frame_off);
7303 insn = emit_insn (gen_add2_insn (stack_pointer_rtx, frame_off));
7304 annotate_constant_pool_refs (&PATTERN (insn));
7307 RTX_FRAME_RELATED_P (insn) = 1;
7308 REG_NOTES (insn) =
7309 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
7310 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
7311 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
7312 GEN_INT (-cfun_frame_layout.frame_size))),
7313 REG_NOTES (insn));
7315 /* Set backchain. */
7317 if (TARGET_BACKCHAIN)
7319 if (cfun_frame_layout.backchain_offset)
7320 addr = gen_rtx_MEM (Pmode,
7321 plus_constant (stack_pointer_rtx,
7322 cfun_frame_layout.backchain_offset));
7323 else
7324 addr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
7325 set_mem_alias_set (addr, get_frame_alias_set ());
7326 insn = emit_insn (gen_move_insn (addr, temp_reg));
7329 /* If we support asynchronous exceptions (e.g. for Java),
7330 we need to make sure the backchain pointer is set up
7331 before any possibly trapping memory access. */
7333 if (TARGET_BACKCHAIN && flag_non_call_exceptions)
7335 addr = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
7336 emit_insn (gen_rtx_CLOBBER (VOIDmode, addr));
7340 /* Save fprs 8 - 15 (64 bit ABI). */
7342 if (cfun_save_high_fprs_p && next_fpr)
7344 insn = emit_insn (gen_add2_insn (temp_reg,
7345 GEN_INT (cfun_frame_layout.f8_offset)));
7347 offset = 0;
7349 for (i = 24; i <= next_fpr; i++)
7350 if (cfun_fpr_bit_p (i - 16))
7352 rtx addr = plus_constant (stack_pointer_rtx,
7353 cfun_frame_layout.frame_size
7354 + cfun_frame_layout.f8_offset
7355 + offset);
7357 insn = save_fpr (temp_reg, offset, i);
7358 offset += 8;
7359 RTX_FRAME_RELATED_P (insn) = 1;
7360 REG_NOTES (insn) =
7361 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
7362 gen_rtx_SET (VOIDmode,
7363 gen_rtx_MEM (DFmode, addr),
7364 gen_rtx_REG (DFmode, i)),
7365 REG_NOTES (insn));
7369 /* Set frame pointer, if needed. */
7371 if (frame_pointer_needed)
7373 insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
7374 RTX_FRAME_RELATED_P (insn) = 1;
7377 /* Set up got pointer, if needed. */
7379 if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
7381 rtx insns = s390_load_got ();
7383 for (insn = insns; insn; insn = NEXT_INSN (insn))
7385 annotate_constant_pool_refs (&PATTERN (insn));
7387 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
7388 REG_NOTES (insn));
7391 emit_insn (insns);
7394 if (TARGET_TPF_PROFILING)
7396 /* Generate a BAS instruction to serve as a function
7397 entry intercept to facilitate the use of tracing
7398 algorithms located at the branch target. */
7399 emit_insn (gen_prologue_tpf ());
7401 /* Emit a blockage here so that all code
7402 lies between the profiling mechanisms. */
7403 emit_insn (gen_blockage ());
7407 /* Expand the epilogue into a bunch of separate insns. */
7409 void
7410 s390_emit_epilogue (bool sibcall)
7412 rtx frame_pointer, return_reg;
7413 int area_bottom, area_top, offset = 0;
7414 int next_offset;
7415 rtvec p;
7416 int i;
7418 if (TARGET_TPF_PROFILING)
7421 /* Generate a BAS instruction to serve as a function
7422 entry intercept to facilitate the use of tracing
7423 algorithms located at the branch target. */
7425 /* Emit a blockage here so that all code
7426 lies between the profiling mechanisms. */
7427 emit_insn (gen_blockage ());
7429 emit_insn (gen_epilogue_tpf ());
7432 /* Check whether to use frame or stack pointer for restore. */
7434 frame_pointer = (frame_pointer_needed
7435 ? hard_frame_pointer_rtx : stack_pointer_rtx);
7437 s390_frame_area (&area_bottom, &area_top);
7439 /* Check whether we can access the register save area.
7440 If not, increment the frame pointer as required. */
7442 if (area_top <= area_bottom)
7444 /* Nothing to restore. */
7446 else if (DISP_IN_RANGE (cfun_frame_layout.frame_size + area_bottom)
7447 && DISP_IN_RANGE (cfun_frame_layout.frame_size + area_top - 1))
7449 /* Area is in range. */
7450 offset = cfun_frame_layout.frame_size;
7452 else
7454 rtx insn, frame_off;
7456 offset = area_bottom < 0 ? -area_bottom : 0;
7457 frame_off = GEN_INT (cfun_frame_layout.frame_size - offset);
7459 if (DISP_IN_RANGE (INTVAL (frame_off)))
7461 insn = gen_rtx_SET (VOIDmode, frame_pointer,
7462 gen_rtx_PLUS (Pmode, frame_pointer, frame_off));
7463 insn = emit_insn (insn);
7465 else
7467 if (!CONST_OK_FOR_K (INTVAL (frame_off)))
7468 frame_off = force_const_mem (Pmode, frame_off);
7470 insn = emit_insn (gen_add2_insn (frame_pointer, frame_off));
7471 annotate_constant_pool_refs (&PATTERN (insn));
7475 /* Restore call saved fprs. */
7477 if (TARGET_64BIT)
7479 if (cfun_save_high_fprs_p)
7481 next_offset = cfun_frame_layout.f8_offset;
7482 for (i = 24; i < 32; i++)
7484 if (cfun_fpr_bit_p (i - 16))
7486 restore_fpr (frame_pointer,
7487 offset + next_offset, i);
7488 next_offset += 8;
7494 else
7496 next_offset = cfun_frame_layout.f4_offset;
7497 for (i = 18; i < 20; i++)
7499 if (cfun_fpr_bit_p (i - 16))
7501 restore_fpr (frame_pointer,
7502 offset + next_offset, i);
7503 next_offset += 8;
7505 else if (!TARGET_PACKED_STACK)
7506 next_offset += 8;
7511 /* Return register. */
7513 return_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
7515 /* Restore call saved gprs. */
7517 if (cfun_frame_layout.first_restore_gpr != -1)
7519 rtx insn, addr;
7520 int i;
7522 /* Check for global register and save them
7523 to stack location from where they get restored. */
7525 for (i = cfun_frame_layout.first_restore_gpr;
7526 i <= cfun_frame_layout.last_restore_gpr;
7527 i++)
7529 /* These registers are special and need to be
7530 restored in any case. */
7531 if (i == STACK_POINTER_REGNUM
7532 || i == RETURN_REGNUM
7533 || i == BASE_REGNUM
7534 || (flag_pic && i == (int)PIC_OFFSET_TABLE_REGNUM))
7535 continue;
7537 if (global_regs[i])
7539 addr = plus_constant (frame_pointer,
7540 offset + cfun_frame_layout.gprs_offset
7541 + (i - cfun_frame_layout.first_save_gpr_slot)
7542 * UNITS_PER_WORD);
7543 addr = gen_rtx_MEM (Pmode, addr);
7544 set_mem_alias_set (addr, get_frame_alias_set ());
7545 emit_move_insn (addr, gen_rtx_REG (Pmode, i));
7549 if (! sibcall)
7551 /* Fetch return address from stack before load multiple,
7552 this will do good for scheduling. */
7554 if (cfun_frame_layout.save_return_addr_p
7555 || (cfun_frame_layout.first_restore_gpr < BASE_REGNUM
7556 && cfun_frame_layout.last_restore_gpr > RETURN_REGNUM))
7558 int return_regnum = find_unused_clobbered_reg();
7559 if (!return_regnum)
7560 return_regnum = 4;
7561 return_reg = gen_rtx_REG (Pmode, return_regnum);
7563 addr = plus_constant (frame_pointer,
7564 offset + cfun_frame_layout.gprs_offset
7565 + (RETURN_REGNUM
7566 - cfun_frame_layout.first_save_gpr_slot)
7567 * UNITS_PER_WORD);
7568 addr = gen_rtx_MEM (Pmode, addr);
7569 set_mem_alias_set (addr, get_frame_alias_set ());
7570 emit_move_insn (return_reg, addr);
7574 insn = restore_gprs (frame_pointer,
7575 offset + cfun_frame_layout.gprs_offset
7576 + (cfun_frame_layout.first_restore_gpr
7577 - cfun_frame_layout.first_save_gpr_slot)
7578 * UNITS_PER_WORD,
7579 cfun_frame_layout.first_restore_gpr,
7580 cfun_frame_layout.last_restore_gpr);
7581 emit_insn (insn);
7584 if (! sibcall)
7587 /* Return to caller. */
7589 p = rtvec_alloc (2);
7591 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
7592 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, return_reg);
7593 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
7598 /* Return the size in bytes of a function argument of
7599 type TYPE and/or mode MODE. At least one of TYPE or
7600 MODE must be specified. */
7602 static int
7603 s390_function_arg_size (enum machine_mode mode, tree type)
7605 if (type)
7606 return int_size_in_bytes (type);
7608 /* No type info available for some library calls ... */
7609 if (mode != BLKmode)
7610 return GET_MODE_SIZE (mode);
7612 /* If we have neither type nor mode, abort */
7613 gcc_unreachable ();
7616 /* Return true if a function argument of type TYPE and mode MODE
7617 is to be passed in a floating-point register, if available. */
7619 static bool
7620 s390_function_arg_float (enum machine_mode mode, tree type)
7622 int size = s390_function_arg_size (mode, type);
7623 if (size > 8)
7624 return false;
7626 /* Soft-float changes the ABI: no floating-point registers are used. */
7627 if (TARGET_SOFT_FLOAT)
7628 return false;
7630 /* No type info available for some library calls ... */
7631 if (!type)
7632 return mode == SFmode || mode == DFmode || mode == SDmode || mode == DDmode;
7634 /* The ABI says that record types with a single member are treated
7635 just like that member would be. */
7636 while (TREE_CODE (type) == RECORD_TYPE)
7638 tree field, single = NULL_TREE;
7640 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
7642 if (TREE_CODE (field) != FIELD_DECL)
7643 continue;
7645 if (single == NULL_TREE)
7646 single = TREE_TYPE (field);
7647 else
7648 return false;
7651 if (single == NULL_TREE)
7652 return false;
7653 else
7654 type = single;
7657 return TREE_CODE (type) == REAL_TYPE;
7660 /* Return true if a function argument of type TYPE and mode MODE
7661 is to be passed in an integer register, or a pair of integer
7662 registers, if available. */
7664 static bool
7665 s390_function_arg_integer (enum machine_mode mode, tree type)
7667 int size = s390_function_arg_size (mode, type);
7668 if (size > 8)
7669 return false;
7671 /* No type info available for some library calls ... */
7672 if (!type)
7673 return GET_MODE_CLASS (mode) == MODE_INT
7674 || (TARGET_SOFT_FLOAT && SCALAR_FLOAT_MODE_P (mode));
7676 /* We accept small integral (and similar) types. */
7677 if (INTEGRAL_TYPE_P (type)
7678 || POINTER_TYPE_P (type)
7679 || TREE_CODE (type) == OFFSET_TYPE
7680 || (TARGET_SOFT_FLOAT && TREE_CODE (type) == REAL_TYPE))
7681 return true;
7683 /* We also accept structs of size 1, 2, 4, 8 that are not
7684 passed in floating-point registers. */
7685 if (AGGREGATE_TYPE_P (type)
7686 && exact_log2 (size) >= 0
7687 && !s390_function_arg_float (mode, type))
7688 return true;
7690 return false;
7693 /* Return 1 if a function argument of type TYPE and mode MODE
7694 is to be passed by reference. The ABI specifies that only
7695 structures of size 1, 2, 4, or 8 bytes are passed by value,
7696 all other structures (and complex numbers) are passed by
7697 reference. */
7699 static bool
7700 s390_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
7701 enum machine_mode mode, tree type,
7702 bool named ATTRIBUTE_UNUSED)
7704 int size = s390_function_arg_size (mode, type);
7705 if (size > 8)
7706 return true;
7708 if (type)
7710 if (AGGREGATE_TYPE_P (type) && exact_log2 (size) < 0)
7711 return 1;
7713 if (TREE_CODE (type) == COMPLEX_TYPE
7714 || TREE_CODE (type) == VECTOR_TYPE)
7715 return 1;
7718 return 0;
7721 /* Update the data in CUM to advance over an argument of mode MODE and
7722 data type TYPE. (TYPE is null for libcalls where that information
7723 may not be available.). The boolean NAMED specifies whether the
7724 argument is a named argument (as opposed to an unnamed argument
7725 matching an ellipsis). */
7727 void
7728 s390_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7729 tree type, int named ATTRIBUTE_UNUSED)
7731 if (s390_function_arg_float (mode, type))
7733 cum->fprs += 1;
7735 else if (s390_function_arg_integer (mode, type))
7737 int size = s390_function_arg_size (mode, type);
7738 cum->gprs += ((size + UNITS_PER_WORD-1) / UNITS_PER_WORD);
7740 else
7741 gcc_unreachable ();
7744 /* Define where to put the arguments to a function.
7745 Value is zero to push the argument on the stack,
7746 or a hard register in which to store the argument.
7748 MODE is the argument's machine mode.
7749 TYPE is the data type of the argument (as a tree).
7750 This is null for libcalls where that information may
7751 not be available.
7752 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7753 the preceding args and about the function being called.
7754 NAMED is nonzero if this argument is a named parameter
7755 (otherwise it is an extra parameter matching an ellipsis).
7757 On S/390, we use general purpose registers 2 through 6 to
7758 pass integer, pointer, and certain structure arguments, and
7759 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
7760 to pass floating point arguments. All remaining arguments
7761 are pushed to the stack. */
7764 s390_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
7765 int named ATTRIBUTE_UNUSED)
7767 if (s390_function_arg_float (mode, type))
7769 if (cum->fprs + 1 > FP_ARG_NUM_REG)
7770 return 0;
7771 else
7772 return gen_rtx_REG (mode, cum->fprs + 16);
7774 else if (s390_function_arg_integer (mode, type))
7776 int size = s390_function_arg_size (mode, type);
7777 int n_gprs = (size + UNITS_PER_WORD-1) / UNITS_PER_WORD;
7779 if (cum->gprs + n_gprs > GP_ARG_NUM_REG)
7780 return 0;
7781 else
7782 return gen_rtx_REG (mode, cum->gprs + 2);
7785 /* After the real arguments, expand_call calls us once again
7786 with a void_type_node type. Whatever we return here is
7787 passed as operand 2 to the call expanders.
7789 We don't need this feature ... */
7790 else if (type == void_type_node)
7791 return const0_rtx;
7793 gcc_unreachable ();
7796 /* Return true if return values of type TYPE should be returned
7797 in a memory buffer whose address is passed by the caller as
7798 hidden first argument. */
7800 static bool
7801 s390_return_in_memory (tree type, tree fundecl ATTRIBUTE_UNUSED)
7803 /* We accept small integral (and similar) types. */
7804 if (INTEGRAL_TYPE_P (type)
7805 || POINTER_TYPE_P (type)
7806 || TREE_CODE (type) == OFFSET_TYPE
7807 || TREE_CODE (type) == REAL_TYPE)
7808 return int_size_in_bytes (type) > 8;
7810 /* Aggregates and similar constructs are always returned
7811 in memory. */
7812 if (AGGREGATE_TYPE_P (type)
7813 || TREE_CODE (type) == COMPLEX_TYPE
7814 || TREE_CODE (type) == VECTOR_TYPE)
7815 return true;
7817 /* ??? We get called on all sorts of random stuff from
7818 aggregate_value_p. We can't abort, but it's not clear
7819 what's safe to return. Pretend it's a struct I guess. */
7820 return true;
7823 /* Define where to return a (scalar) value of type TYPE.
7824 If TYPE is null, define where to return a (scalar)
7825 value of mode MODE from a libcall. */
7828 s390_function_value (tree type, enum machine_mode mode)
7830 if (type)
7832 int unsignedp = TYPE_UNSIGNED (type);
7833 mode = promote_mode (type, TYPE_MODE (type), &unsignedp, 1);
7836 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT || SCALAR_FLOAT_MODE_P (mode));
7837 gcc_assert (GET_MODE_SIZE (mode) <= 8);
7839 if (TARGET_HARD_FLOAT && SCALAR_FLOAT_MODE_P (mode))
7840 return gen_rtx_REG (mode, 16);
7841 else
7842 return gen_rtx_REG (mode, 2);
7846 /* Create and return the va_list datatype.
7848 On S/390, va_list is an array type equivalent to
7850 typedef struct __va_list_tag
7852 long __gpr;
7853 long __fpr;
7854 void *__overflow_arg_area;
7855 void *__reg_save_area;
7856 } va_list[1];
7858 where __gpr and __fpr hold the number of general purpose
7859 or floating point arguments used up to now, respectively,
7860 __overflow_arg_area points to the stack location of the
7861 next argument passed on the stack, and __reg_save_area
7862 always points to the start of the register area in the
7863 call frame of the current function. The function prologue
7864 saves all registers used for argument passing into this
7865 area if the function uses variable arguments. */
7867 static tree
7868 s390_build_builtin_va_list (void)
7870 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
7872 record = lang_hooks.types.make_type (RECORD_TYPE);
7874 type_decl =
7875 build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
7877 f_gpr = build_decl (FIELD_DECL, get_identifier ("__gpr"),
7878 long_integer_type_node);
7879 f_fpr = build_decl (FIELD_DECL, get_identifier ("__fpr"),
7880 long_integer_type_node);
7881 f_ovf = build_decl (FIELD_DECL, get_identifier ("__overflow_arg_area"),
7882 ptr_type_node);
7883 f_sav = build_decl (FIELD_DECL, get_identifier ("__reg_save_area"),
7884 ptr_type_node);
7886 va_list_gpr_counter_field = f_gpr;
7887 va_list_fpr_counter_field = f_fpr;
7889 DECL_FIELD_CONTEXT (f_gpr) = record;
7890 DECL_FIELD_CONTEXT (f_fpr) = record;
7891 DECL_FIELD_CONTEXT (f_ovf) = record;
7892 DECL_FIELD_CONTEXT (f_sav) = record;
7894 TREE_CHAIN (record) = type_decl;
7895 TYPE_NAME (record) = type_decl;
7896 TYPE_FIELDS (record) = f_gpr;
7897 TREE_CHAIN (f_gpr) = f_fpr;
7898 TREE_CHAIN (f_fpr) = f_ovf;
7899 TREE_CHAIN (f_ovf) = f_sav;
7901 layout_type (record);
7903 /* The correct type is an array type of one element. */
7904 return build_array_type (record, build_index_type (size_zero_node));
7907 /* Implement va_start by filling the va_list structure VALIST.
7908 STDARG_P is always true, and ignored.
7909 NEXTARG points to the first anonymous stack argument.
7911 The following global variables are used to initialize
7912 the va_list structure:
7914 current_function_args_info:
7915 holds number of gprs and fprs used for named arguments.
7916 current_function_arg_offset_rtx:
7917 holds the offset of the first anonymous stack argument
7918 (relative to the virtual arg pointer). */
7920 void
7921 s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
7923 HOST_WIDE_INT n_gpr, n_fpr;
7924 int off;
7925 tree f_gpr, f_fpr, f_ovf, f_sav;
7926 tree gpr, fpr, ovf, sav, t;
7928 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
7929 f_fpr = TREE_CHAIN (f_gpr);
7930 f_ovf = TREE_CHAIN (f_fpr);
7931 f_sav = TREE_CHAIN (f_ovf);
7933 valist = build_va_arg_indirect_ref (valist);
7934 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
7935 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
7936 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
7937 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
7939 /* Count number of gp and fp argument registers used. */
7941 n_gpr = current_function_args_info.gprs;
7942 n_fpr = current_function_args_info.fprs;
7944 if (cfun->va_list_gpr_size)
7946 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
7947 build_int_cst (NULL_TREE, n_gpr));
7948 TREE_SIDE_EFFECTS (t) = 1;
7949 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7952 if (cfun->va_list_fpr_size)
7954 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
7955 build_int_cst (NULL_TREE, n_fpr));
7956 TREE_SIDE_EFFECTS (t) = 1;
7957 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7960 /* Find the overflow area. */
7961 if (n_gpr + cfun->va_list_gpr_size > GP_ARG_NUM_REG
7962 || n_fpr + cfun->va_list_fpr_size > FP_ARG_NUM_REG)
7964 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
7966 off = INTVAL (current_function_arg_offset_rtx);
7967 off = off < 0 ? 0 : off;
7968 if (TARGET_DEBUG_ARG)
7969 fprintf (stderr, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
7970 (int)n_gpr, (int)n_fpr, off);
7972 t = build2 (PLUS_EXPR, TREE_TYPE (ovf), t, build_int_cst (NULL_TREE, off));
7974 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
7975 TREE_SIDE_EFFECTS (t) = 1;
7976 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7979 /* Find the register save area. */
7980 if ((cfun->va_list_gpr_size && n_gpr < GP_ARG_NUM_REG)
7981 || (cfun->va_list_fpr_size && n_fpr < FP_ARG_NUM_REG))
7983 t = make_tree (TREE_TYPE (sav), return_address_pointer_rtx);
7984 t = build2 (PLUS_EXPR, TREE_TYPE (sav), t,
7985 build_int_cst (NULL_TREE, -RETURN_REGNUM * UNITS_PER_WORD));
7987 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
7988 TREE_SIDE_EFFECTS (t) = 1;
7989 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7993 /* Implement va_arg by updating the va_list structure
7994 VALIST as required to retrieve an argument of type
7995 TYPE, and returning that argument.
7997 Generates code equivalent to:
7999 if (integral value) {
8000 if (size <= 4 && args.gpr < 5 ||
8001 size > 4 && args.gpr < 4 )
8002 ret = args.reg_save_area[args.gpr+8]
8003 else
8004 ret = *args.overflow_arg_area++;
8005 } else if (float value) {
8006 if (args.fgpr < 2)
8007 ret = args.reg_save_area[args.fpr+64]
8008 else
8009 ret = *args.overflow_arg_area++;
8010 } else if (aggregate value) {
8011 if (args.gpr < 5)
8012 ret = *args.reg_save_area[args.gpr]
8013 else
8014 ret = **args.overflow_arg_area++;
8015 } */
8017 static tree
8018 s390_gimplify_va_arg (tree valist, tree type, tree *pre_p,
8019 tree *post_p ATTRIBUTE_UNUSED)
8021 tree f_gpr, f_fpr, f_ovf, f_sav;
8022 tree gpr, fpr, ovf, sav, reg, t, u;
8023 int indirect_p, size, n_reg, sav_ofs, sav_scale, max_reg;
8024 tree lab_false, lab_over, addr;
8026 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8027 f_fpr = TREE_CHAIN (f_gpr);
8028 f_ovf = TREE_CHAIN (f_fpr);
8029 f_sav = TREE_CHAIN (f_ovf);
8031 valist = build_va_arg_indirect_ref (valist);
8032 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8033 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
8034 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
8035 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
8037 size = int_size_in_bytes (type);
8039 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8041 if (TARGET_DEBUG_ARG)
8043 fprintf (stderr, "va_arg: aggregate type");
8044 debug_tree (type);
8047 /* Aggregates are passed by reference. */
8048 indirect_p = 1;
8049 reg = gpr;
8050 n_reg = 1;
8052 /* kernel stack layout on 31 bit: It is assumed here that no padding
8053 will be added by s390_frame_info because for va_args always an even
8054 number of gprs has to be saved r15-r2 = 14 regs. */
8055 sav_ofs = 2 * UNITS_PER_WORD;
8056 sav_scale = UNITS_PER_WORD;
8057 size = UNITS_PER_WORD;
8058 max_reg = GP_ARG_NUM_REG - n_reg;
8060 else if (s390_function_arg_float (TYPE_MODE (type), type))
8062 if (TARGET_DEBUG_ARG)
8064 fprintf (stderr, "va_arg: float type");
8065 debug_tree (type);
8068 /* FP args go in FP registers, if present. */
8069 indirect_p = 0;
8070 reg = fpr;
8071 n_reg = 1;
8072 sav_ofs = 16 * UNITS_PER_WORD;
8073 sav_scale = 8;
8074 max_reg = FP_ARG_NUM_REG - n_reg;
8076 else
8078 if (TARGET_DEBUG_ARG)
8080 fprintf (stderr, "va_arg: other type");
8081 debug_tree (type);
8084 /* Otherwise into GP registers. */
8085 indirect_p = 0;
8086 reg = gpr;
8087 n_reg = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
8089 /* kernel stack layout on 31 bit: It is assumed here that no padding
8090 will be added by s390_frame_info because for va_args always an even
8091 number of gprs has to be saved r15-r2 = 14 regs. */
8092 sav_ofs = 2 * UNITS_PER_WORD;
8094 if (size < UNITS_PER_WORD)
8095 sav_ofs += UNITS_PER_WORD - size;
8097 sav_scale = UNITS_PER_WORD;
8098 max_reg = GP_ARG_NUM_REG - n_reg;
8101 /* Pull the value out of the saved registers ... */
8103 lab_false = create_artificial_label ();
8104 lab_over = create_artificial_label ();
8105 addr = create_tmp_var (ptr_type_node, "addr");
8106 DECL_POINTER_ALIAS_SET (addr) = get_varargs_alias_set ();
8108 t = fold_convert (TREE_TYPE (reg), size_int (max_reg));
8109 t = build2 (GT_EXPR, boolean_type_node, reg, t);
8110 u = build1 (GOTO_EXPR, void_type_node, lab_false);
8111 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
8112 gimplify_and_add (t, pre_p);
8114 t = build2 (PLUS_EXPR, ptr_type_node, sav,
8115 fold_convert (ptr_type_node, size_int (sav_ofs)));
8116 u = build2 (MULT_EXPR, TREE_TYPE (reg), reg,
8117 fold_convert (TREE_TYPE (reg), size_int (sav_scale)));
8118 t = build2 (PLUS_EXPR, ptr_type_node, t, fold_convert (ptr_type_node, u));
8120 t = build2 (MODIFY_EXPR, void_type_node, addr, t);
8121 gimplify_and_add (t, pre_p);
8123 t = build1 (GOTO_EXPR, void_type_node, lab_over);
8124 gimplify_and_add (t, pre_p);
8126 t = build1 (LABEL_EXPR, void_type_node, lab_false);
8127 append_to_statement_list (t, pre_p);
8130 /* ... Otherwise out of the overflow area. */
8132 t = ovf;
8133 if (size < UNITS_PER_WORD)
8134 t = build2 (PLUS_EXPR, ptr_type_node, t,
8135 fold_convert (ptr_type_node, size_int (UNITS_PER_WORD - size)));
8137 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
8139 u = build2 (MODIFY_EXPR, void_type_node, addr, t);
8140 gimplify_and_add (u, pre_p);
8142 t = build2 (PLUS_EXPR, ptr_type_node, t,
8143 fold_convert (ptr_type_node, size_int (size)));
8144 t = build2 (MODIFY_EXPR, ptr_type_node, ovf, t);
8145 gimplify_and_add (t, pre_p);
8147 t = build1 (LABEL_EXPR, void_type_node, lab_over);
8148 append_to_statement_list (t, pre_p);
8151 /* Increment register save count. */
8153 u = build2 (PREINCREMENT_EXPR, TREE_TYPE (reg), reg,
8154 fold_convert (TREE_TYPE (reg), size_int (n_reg)));
8155 gimplify_and_add (u, pre_p);
8157 if (indirect_p)
8159 t = build_pointer_type (build_pointer_type (type));
8160 addr = fold_convert (t, addr);
8161 addr = build_va_arg_indirect_ref (addr);
8163 else
8165 t = build_pointer_type (type);
8166 addr = fold_convert (t, addr);
8169 return build_va_arg_indirect_ref (addr);
8173 /* Builtins. */
8175 enum s390_builtin
8177 S390_BUILTIN_THREAD_POINTER,
8178 S390_BUILTIN_SET_THREAD_POINTER,
8180 S390_BUILTIN_max
8183 static unsigned int const code_for_builtin_64[S390_BUILTIN_max] = {
8184 CODE_FOR_get_tp_64,
8185 CODE_FOR_set_tp_64
8188 static unsigned int const code_for_builtin_31[S390_BUILTIN_max] = {
8189 CODE_FOR_get_tp_31,
8190 CODE_FOR_set_tp_31
8193 static void
8194 s390_init_builtins (void)
8196 tree ftype;
8198 ftype = build_function_type (ptr_type_node, void_list_node);
8199 lang_hooks.builtin_function ("__builtin_thread_pointer", ftype,
8200 S390_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
8201 NULL, NULL_TREE);
8203 ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
8204 lang_hooks.builtin_function ("__builtin_set_thread_pointer", ftype,
8205 S390_BUILTIN_SET_THREAD_POINTER, BUILT_IN_MD,
8206 NULL, NULL_TREE);
8209 /* Expand an expression EXP that calls a built-in function,
8210 with result going to TARGET if that's convenient
8211 (and in mode MODE if that's convenient).
8212 SUBTARGET may be used as the target for computing one of EXP's operands.
8213 IGNORE is nonzero if the value is to be ignored. */
8215 static rtx
8216 s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
8217 enum machine_mode mode ATTRIBUTE_UNUSED,
8218 int ignore ATTRIBUTE_UNUSED)
8220 #define MAX_ARGS 2
8222 unsigned int const *code_for_builtin =
8223 TARGET_64BIT ? code_for_builtin_64 : code_for_builtin_31;
8225 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
8226 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
8227 tree arglist = TREE_OPERAND (exp, 1);
8228 enum insn_code icode;
8229 rtx op[MAX_ARGS], pat;
8230 int arity;
8231 bool nonvoid;
8233 if (fcode >= S390_BUILTIN_max)
8234 internal_error ("bad builtin fcode");
8235 icode = code_for_builtin[fcode];
8236 if (icode == 0)
8237 internal_error ("bad builtin fcode");
8239 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
8241 for (arglist = TREE_OPERAND (exp, 1), arity = 0;
8242 arglist;
8243 arglist = TREE_CHAIN (arglist), arity++)
8245 const struct insn_operand_data *insn_op;
8247 tree arg = TREE_VALUE (arglist);
8248 if (arg == error_mark_node)
8249 return NULL_RTX;
8250 if (arity > MAX_ARGS)
8251 return NULL_RTX;
8253 insn_op = &insn_data[icode].operand[arity + nonvoid];
8255 op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, 0);
8257 if (!(*insn_op->predicate) (op[arity], insn_op->mode))
8258 op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
8261 if (nonvoid)
8263 enum machine_mode tmode = insn_data[icode].operand[0].mode;
8264 if (!target
8265 || GET_MODE (target) != tmode
8266 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
8267 target = gen_reg_rtx (tmode);
8270 switch (arity)
8272 case 0:
8273 pat = GEN_FCN (icode) (target);
8274 break;
8275 case 1:
8276 if (nonvoid)
8277 pat = GEN_FCN (icode) (target, op[0]);
8278 else
8279 pat = GEN_FCN (icode) (op[0]);
8280 break;
8281 case 2:
8282 pat = GEN_FCN (icode) (target, op[0], op[1]);
8283 break;
8284 default:
8285 gcc_unreachable ();
8287 if (!pat)
8288 return NULL_RTX;
8289 emit_insn (pat);
8291 if (nonvoid)
8292 return target;
8293 else
8294 return const0_rtx;
8298 /* Output assembly code for the trampoline template to
8299 stdio stream FILE.
8301 On S/390, we use gpr 1 internally in the trampoline code;
8302 gpr 0 is used to hold the static chain. */
8304 void
8305 s390_trampoline_template (FILE *file)
8307 rtx op[2];
8308 op[0] = gen_rtx_REG (Pmode, 0);
8309 op[1] = gen_rtx_REG (Pmode, 1);
8311 if (TARGET_64BIT)
8313 output_asm_insn ("basr\t%1,0", op);
8314 output_asm_insn ("lmg\t%0,%1,14(%1)", op);
8315 output_asm_insn ("br\t%1", op);
8316 ASM_OUTPUT_SKIP (file, (HOST_WIDE_INT)(TRAMPOLINE_SIZE - 10));
8318 else
8320 output_asm_insn ("basr\t%1,0", op);
8321 output_asm_insn ("lm\t%0,%1,6(%1)", op);
8322 output_asm_insn ("br\t%1", op);
8323 ASM_OUTPUT_SKIP (file, (HOST_WIDE_INT)(TRAMPOLINE_SIZE - 8));
8327 /* Emit RTL insns to initialize the variable parts of a trampoline.
8328 FNADDR is an RTX for the address of the function's pure code.
8329 CXT is an RTX for the static chain value for the function. */
8331 void
8332 s390_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
8334 emit_move_insn (gen_rtx_MEM (Pmode,
8335 memory_address (Pmode,
8336 plus_constant (addr, (TARGET_64BIT ? 16 : 8)))), cxt);
8337 emit_move_insn (gen_rtx_MEM (Pmode,
8338 memory_address (Pmode,
8339 plus_constant (addr, (TARGET_64BIT ? 24 : 12)))), fnaddr);
8342 /* Return rtx for 64-bit constant formed from the 32-bit subwords
8343 LOW and HIGH, independent of the host word size. */
8346 s390_gen_rtx_const_DI (int high, int low)
8348 #if HOST_BITS_PER_WIDE_INT >= 64
8349 HOST_WIDE_INT val;
8350 val = (HOST_WIDE_INT)high;
8351 val <<= 32;
8352 val |= (HOST_WIDE_INT)low;
8354 return GEN_INT (val);
8355 #else
8356 #if HOST_BITS_PER_WIDE_INT >= 32
8357 return immed_double_const ((HOST_WIDE_INT)low, (HOST_WIDE_INT)high, DImode);
8358 #else
8359 gcc_unreachable ();
8360 #endif
8361 #endif
8364 /* Output assembler code to FILE to increment profiler label # LABELNO
8365 for profiling a function entry. */
8367 void
8368 s390_function_profiler (FILE *file, int labelno)
8370 rtx op[7];
8372 char label[128];
8373 ASM_GENERATE_INTERNAL_LABEL (label, "LP", labelno);
8375 fprintf (file, "# function profiler \n");
8377 op[0] = gen_rtx_REG (Pmode, RETURN_REGNUM);
8378 op[1] = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
8379 op[1] = gen_rtx_MEM (Pmode, plus_constant (op[1], UNITS_PER_WORD));
8381 op[2] = gen_rtx_REG (Pmode, 1);
8382 op[3] = gen_rtx_SYMBOL_REF (Pmode, label);
8383 SYMBOL_REF_FLAGS (op[3]) = SYMBOL_FLAG_LOCAL;
8385 op[4] = gen_rtx_SYMBOL_REF (Pmode, "_mcount");
8386 if (flag_pic)
8388 op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), UNSPEC_PLT);
8389 op[4] = gen_rtx_CONST (Pmode, op[4]);
8392 if (TARGET_64BIT)
8394 output_asm_insn ("stg\t%0,%1", op);
8395 output_asm_insn ("larl\t%2,%3", op);
8396 output_asm_insn ("brasl\t%0,%4", op);
8397 output_asm_insn ("lg\t%0,%1", op);
8399 else if (!flag_pic)
8401 op[6] = gen_label_rtx ();
8403 output_asm_insn ("st\t%0,%1", op);
8404 output_asm_insn ("bras\t%2,%l6", op);
8405 output_asm_insn (".long\t%4", op);
8406 output_asm_insn (".long\t%3", op);
8407 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
8408 output_asm_insn ("l\t%0,0(%2)", op);
8409 output_asm_insn ("l\t%2,4(%2)", op);
8410 output_asm_insn ("basr\t%0,%0", op);
8411 output_asm_insn ("l\t%0,%1", op);
8413 else
8415 op[5] = gen_label_rtx ();
8416 op[6] = gen_label_rtx ();
8418 output_asm_insn ("st\t%0,%1", op);
8419 output_asm_insn ("bras\t%2,%l6", op);
8420 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[5]));
8421 output_asm_insn (".long\t%4-%l5", op);
8422 output_asm_insn (".long\t%3-%l5", op);
8423 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
8424 output_asm_insn ("lr\t%0,%2", op);
8425 output_asm_insn ("a\t%0,0(%2)", op);
8426 output_asm_insn ("a\t%2,4(%2)", op);
8427 output_asm_insn ("basr\t%0,%0", op);
8428 output_asm_insn ("l\t%0,%1", op);
8432 /* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
8433 into its SYMBOL_REF_FLAGS. */
8435 static void
8436 s390_encode_section_info (tree decl, rtx rtl, int first)
8438 default_encode_section_info (decl, rtl, first);
8440 /* If a variable has a forced alignment to < 2 bytes, mark it with
8441 SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL operand. */
8442 if (TREE_CODE (decl) == VAR_DECL
8443 && DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) < 16)
8444 SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_ALIGN1;
8447 /* Output thunk to FILE that implements a C++ virtual function call (with
8448 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
8449 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
8450 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
8451 relative to the resulting this pointer. */
8453 static void
8454 s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
8455 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
8456 tree function)
8458 rtx op[10];
8459 int nonlocal = 0;
8461 /* Operand 0 is the target function. */
8462 op[0] = XEXP (DECL_RTL (function), 0);
8463 if (flag_pic && !SYMBOL_REF_LOCAL_P (op[0]))
8465 nonlocal = 1;
8466 op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]),
8467 TARGET_64BIT ? UNSPEC_PLT : UNSPEC_GOT);
8468 op[0] = gen_rtx_CONST (Pmode, op[0]);
8471 /* Operand 1 is the 'this' pointer. */
8472 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
8473 op[1] = gen_rtx_REG (Pmode, 3);
8474 else
8475 op[1] = gen_rtx_REG (Pmode, 2);
8477 /* Operand 2 is the delta. */
8478 op[2] = GEN_INT (delta);
8480 /* Operand 3 is the vcall_offset. */
8481 op[3] = GEN_INT (vcall_offset);
8483 /* Operand 4 is the temporary register. */
8484 op[4] = gen_rtx_REG (Pmode, 1);
8486 /* Operands 5 to 8 can be used as labels. */
8487 op[5] = NULL_RTX;
8488 op[6] = NULL_RTX;
8489 op[7] = NULL_RTX;
8490 op[8] = NULL_RTX;
8492 /* Operand 9 can be used for temporary register. */
8493 op[9] = NULL_RTX;
8495 /* Generate code. */
8496 if (TARGET_64BIT)
8498 /* Setup literal pool pointer if required. */
8499 if ((!DISP_IN_RANGE (delta)
8500 && !CONST_OK_FOR_K (delta)
8501 && !CONST_OK_FOR_Os (delta))
8502 || (!DISP_IN_RANGE (vcall_offset)
8503 && !CONST_OK_FOR_K (vcall_offset)
8504 && !CONST_OK_FOR_Os (vcall_offset)))
8506 op[5] = gen_label_rtx ();
8507 output_asm_insn ("larl\t%4,%5", op);
8510 /* Add DELTA to this pointer. */
8511 if (delta)
8513 if (CONST_OK_FOR_J (delta))
8514 output_asm_insn ("la\t%1,%2(%1)", op);
8515 else if (DISP_IN_RANGE (delta))
8516 output_asm_insn ("lay\t%1,%2(%1)", op);
8517 else if (CONST_OK_FOR_K (delta))
8518 output_asm_insn ("aghi\t%1,%2", op);
8519 else if (CONST_OK_FOR_Os (delta))
8520 output_asm_insn ("agfi\t%1,%2", op);
8521 else
8523 op[6] = gen_label_rtx ();
8524 output_asm_insn ("agf\t%1,%6-%5(%4)", op);
8528 /* Perform vcall adjustment. */
8529 if (vcall_offset)
8531 if (DISP_IN_RANGE (vcall_offset))
8533 output_asm_insn ("lg\t%4,0(%1)", op);
8534 output_asm_insn ("ag\t%1,%3(%4)", op);
8536 else if (CONST_OK_FOR_K (vcall_offset))
8538 output_asm_insn ("lghi\t%4,%3", op);
8539 output_asm_insn ("ag\t%4,0(%1)", op);
8540 output_asm_insn ("ag\t%1,0(%4)", op);
8542 else if (CONST_OK_FOR_Os (vcall_offset))
8544 output_asm_insn ("lgfi\t%4,%3", op);
8545 output_asm_insn ("ag\t%4,0(%1)", op);
8546 output_asm_insn ("ag\t%1,0(%4)", op);
8548 else
8550 op[7] = gen_label_rtx ();
8551 output_asm_insn ("llgf\t%4,%7-%5(%4)", op);
8552 output_asm_insn ("ag\t%4,0(%1)", op);
8553 output_asm_insn ("ag\t%1,0(%4)", op);
8557 /* Jump to target. */
8558 output_asm_insn ("jg\t%0", op);
8560 /* Output literal pool if required. */
8561 if (op[5])
8563 output_asm_insn (".align\t4", op);
8564 targetm.asm_out.internal_label (file, "L",
8565 CODE_LABEL_NUMBER (op[5]));
8567 if (op[6])
8569 targetm.asm_out.internal_label (file, "L",
8570 CODE_LABEL_NUMBER (op[6]));
8571 output_asm_insn (".long\t%2", op);
8573 if (op[7])
8575 targetm.asm_out.internal_label (file, "L",
8576 CODE_LABEL_NUMBER (op[7]));
8577 output_asm_insn (".long\t%3", op);
8580 else
8582 /* Setup base pointer if required. */
8583 if (!vcall_offset
8584 || (!DISP_IN_RANGE (delta)
8585 && !CONST_OK_FOR_K (delta)
8586 && !CONST_OK_FOR_Os (delta))
8587 || (!DISP_IN_RANGE (delta)
8588 && !CONST_OK_FOR_K (vcall_offset)
8589 && !CONST_OK_FOR_Os (vcall_offset)))
8591 op[5] = gen_label_rtx ();
8592 output_asm_insn ("basr\t%4,0", op);
8593 targetm.asm_out.internal_label (file, "L",
8594 CODE_LABEL_NUMBER (op[5]));
8597 /* Add DELTA to this pointer. */
8598 if (delta)
8600 if (CONST_OK_FOR_J (delta))
8601 output_asm_insn ("la\t%1,%2(%1)", op);
8602 else if (DISP_IN_RANGE (delta))
8603 output_asm_insn ("lay\t%1,%2(%1)", op);
8604 else if (CONST_OK_FOR_K (delta))
8605 output_asm_insn ("ahi\t%1,%2", op);
8606 else if (CONST_OK_FOR_Os (delta))
8607 output_asm_insn ("afi\t%1,%2", op);
8608 else
8610 op[6] = gen_label_rtx ();
8611 output_asm_insn ("a\t%1,%6-%5(%4)", op);
8615 /* Perform vcall adjustment. */
8616 if (vcall_offset)
8618 if (CONST_OK_FOR_J (vcall_offset))
8620 output_asm_insn ("l\t%4,0(%1)", op);
8621 output_asm_insn ("a\t%1,%3(%4)", op);
8623 else if (DISP_IN_RANGE (vcall_offset))
8625 output_asm_insn ("l\t%4,0(%1)", op);
8626 output_asm_insn ("ay\t%1,%3(%4)", op);
8628 else if (CONST_OK_FOR_K (vcall_offset))
8630 output_asm_insn ("lhi\t%4,%3", op);
8631 output_asm_insn ("a\t%4,0(%1)", op);
8632 output_asm_insn ("a\t%1,0(%4)", op);
8634 else if (CONST_OK_FOR_Os (vcall_offset))
8636 output_asm_insn ("iilf\t%4,%3", op);
8637 output_asm_insn ("a\t%4,0(%1)", op);
8638 output_asm_insn ("a\t%1,0(%4)", op);
8640 else
8642 op[7] = gen_label_rtx ();
8643 output_asm_insn ("l\t%4,%7-%5(%4)", op);
8644 output_asm_insn ("a\t%4,0(%1)", op);
8645 output_asm_insn ("a\t%1,0(%4)", op);
8648 /* We had to clobber the base pointer register.
8649 Re-setup the base pointer (with a different base). */
8650 op[5] = gen_label_rtx ();
8651 output_asm_insn ("basr\t%4,0", op);
8652 targetm.asm_out.internal_label (file, "L",
8653 CODE_LABEL_NUMBER (op[5]));
8656 /* Jump to target. */
8657 op[8] = gen_label_rtx ();
8659 if (!flag_pic)
8660 output_asm_insn ("l\t%4,%8-%5(%4)", op);
8661 else if (!nonlocal)
8662 output_asm_insn ("a\t%4,%8-%5(%4)", op);
8663 /* We cannot call through .plt, since .plt requires %r12 loaded. */
8664 else if (flag_pic == 1)
8666 output_asm_insn ("a\t%4,%8-%5(%4)", op);
8667 output_asm_insn ("l\t%4,%0(%4)", op);
8669 else if (flag_pic == 2)
8671 op[9] = gen_rtx_REG (Pmode, 0);
8672 output_asm_insn ("l\t%9,%8-4-%5(%4)", op);
8673 output_asm_insn ("a\t%4,%8-%5(%4)", op);
8674 output_asm_insn ("ar\t%4,%9", op);
8675 output_asm_insn ("l\t%4,0(%4)", op);
8678 output_asm_insn ("br\t%4", op);
8680 /* Output literal pool. */
8681 output_asm_insn (".align\t4", op);
8683 if (nonlocal && flag_pic == 2)
8684 output_asm_insn (".long\t%0", op);
8685 if (nonlocal)
8687 op[0] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
8688 SYMBOL_REF_FLAGS (op[0]) = SYMBOL_FLAG_LOCAL;
8691 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[8]));
8692 if (!flag_pic)
8693 output_asm_insn (".long\t%0", op);
8694 else
8695 output_asm_insn (".long\t%0-%5", op);
8697 if (op[6])
8699 targetm.asm_out.internal_label (file, "L",
8700 CODE_LABEL_NUMBER (op[6]));
8701 output_asm_insn (".long\t%2", op);
8703 if (op[7])
8705 targetm.asm_out.internal_label (file, "L",
8706 CODE_LABEL_NUMBER (op[7]));
8707 output_asm_insn (".long\t%3", op);
8712 static bool
8713 s390_valid_pointer_mode (enum machine_mode mode)
8715 return (mode == SImode || (TARGET_64BIT && mode == DImode));
8718 /* Checks whether the given ARGUMENT_LIST would use a caller
8719 saved register. This is used to decide whether sibling call
8720 optimization could be performed on the respective function
8721 call. */
8723 static bool
8724 s390_call_saved_register_used (tree argument_list)
8726 CUMULATIVE_ARGS cum;
8727 tree parameter;
8728 enum machine_mode mode;
8729 tree type;
8730 rtx parm_rtx;
8731 int reg;
8733 INIT_CUMULATIVE_ARGS (cum, NULL, NULL, 0, 0);
8735 while (argument_list)
8737 parameter = TREE_VALUE (argument_list);
8738 argument_list = TREE_CHAIN (argument_list);
8740 gcc_assert (parameter);
8742 /* For an undeclared variable passed as parameter we will get
8743 an ERROR_MARK node here. */
8744 if (TREE_CODE (parameter) == ERROR_MARK)
8745 return true;
8747 type = TREE_TYPE (parameter);
8748 gcc_assert (type);
8750 mode = TYPE_MODE (type);
8751 gcc_assert (mode);
8753 if (pass_by_reference (&cum, mode, type, true))
8755 mode = Pmode;
8756 type = build_pointer_type (type);
8759 parm_rtx = s390_function_arg (&cum, mode, type, 0);
8761 s390_function_arg_advance (&cum, mode, type, 0);
8763 if (parm_rtx && REG_P (parm_rtx))
8765 for (reg = 0;
8766 reg < HARD_REGNO_NREGS (REGNO (parm_rtx), GET_MODE (parm_rtx));
8767 reg++)
8768 if (! call_used_regs[reg + REGNO (parm_rtx)])
8769 return true;
8772 return false;
8775 /* Return true if the given call expression can be
8776 turned into a sibling call.
8777 DECL holds the declaration of the function to be called whereas
8778 EXP is the call expression itself. */
8780 static bool
8781 s390_function_ok_for_sibcall (tree decl, tree exp)
8783 /* The TPF epilogue uses register 1. */
8784 if (TARGET_TPF_PROFILING)
8785 return false;
8787 /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
8788 which would have to be restored before the sibcall. */
8789 if (!TARGET_64BIT && flag_pic && decl && !targetm.binds_local_p (decl))
8790 return false;
8792 /* Register 6 on s390 is available as an argument register but unfortunately
8793 "caller saved". This makes functions needing this register for arguments
8794 not suitable for sibcalls. */
8795 if (TREE_OPERAND (exp, 1)
8796 && s390_call_saved_register_used (TREE_OPERAND (exp, 1)))
8797 return false;
8799 return true;
8802 /* Return the fixed registers used for condition codes. */
8804 static bool
8805 s390_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
8807 *p1 = CC_REGNUM;
8808 *p2 = INVALID_REGNUM;
8810 return true;
8813 /* This function is used by the call expanders of the machine description.
8814 It emits the call insn itself together with the necessary operations
8815 to adjust the target address and returns the emitted insn.
8816 ADDR_LOCATION is the target address rtx
8817 TLS_CALL the location of the thread-local symbol
8818 RESULT_REG the register where the result of the call should be stored
8819 RETADDR_REG the register where the return address should be stored
8820 If this parameter is NULL_RTX the call is considered
8821 to be a sibling call. */
8824 s390_emit_call (rtx addr_location, rtx tls_call, rtx result_reg,
8825 rtx retaddr_reg)
8827 bool plt_call = false;
8828 rtx insn;
8829 rtx call;
8830 rtx clobber;
8831 rtvec vec;
8833 /* Direct function calls need special treatment. */
8834 if (GET_CODE (addr_location) == SYMBOL_REF)
8836 /* When calling a global routine in PIC mode, we must
8837 replace the symbol itself with the PLT stub. */
8838 if (flag_pic && !SYMBOL_REF_LOCAL_P (addr_location))
8840 addr_location = gen_rtx_UNSPEC (Pmode,
8841 gen_rtvec (1, addr_location),
8842 UNSPEC_PLT);
8843 addr_location = gen_rtx_CONST (Pmode, addr_location);
8844 plt_call = true;
8847 /* Unless we can use the bras(l) insn, force the
8848 routine address into a register. */
8849 if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
8851 if (flag_pic)
8852 addr_location = legitimize_pic_address (addr_location, 0);
8853 else
8854 addr_location = force_reg (Pmode, addr_location);
8858 /* If it is already an indirect call or the code above moved the
8859 SYMBOL_REF to somewhere else make sure the address can be found in
8860 register 1. */
8861 if (retaddr_reg == NULL_RTX
8862 && GET_CODE (addr_location) != SYMBOL_REF
8863 && !plt_call)
8865 emit_move_insn (gen_rtx_REG (Pmode, SIBCALL_REGNUM), addr_location);
8866 addr_location = gen_rtx_REG (Pmode, SIBCALL_REGNUM);
8869 addr_location = gen_rtx_MEM (QImode, addr_location);
8870 call = gen_rtx_CALL (VOIDmode, addr_location, const0_rtx);
8872 if (result_reg != NULL_RTX)
8873 call = gen_rtx_SET (VOIDmode, result_reg, call);
8875 if (retaddr_reg != NULL_RTX)
8877 clobber = gen_rtx_CLOBBER (VOIDmode, retaddr_reg);
8879 if (tls_call != NULL_RTX)
8880 vec = gen_rtvec (3, call, clobber,
8881 gen_rtx_USE (VOIDmode, tls_call));
8882 else
8883 vec = gen_rtvec (2, call, clobber);
8885 call = gen_rtx_PARALLEL (VOIDmode, vec);
8888 insn = emit_call_insn (call);
8890 /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
8891 if ((!TARGET_64BIT && plt_call) || tls_call != NULL_RTX)
8893 /* s390_function_ok_for_sibcall should
8894 have denied sibcalls in this case. */
8895 gcc_assert (retaddr_reg != NULL_RTX);
8897 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
8899 return insn;
8902 /* Implement CONDITIONAL_REGISTER_USAGE. */
8904 void
8905 s390_conditional_register_usage (void)
8907 int i;
8909 if (flag_pic)
8911 fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
8912 call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
8914 if (TARGET_CPU_ZARCH)
8916 fixed_regs[BASE_REGNUM] = 0;
8917 call_used_regs[BASE_REGNUM] = 0;
8918 fixed_regs[RETURN_REGNUM] = 0;
8919 call_used_regs[RETURN_REGNUM] = 0;
8921 if (TARGET_64BIT)
8923 for (i = 24; i < 32; i++)
8924 call_used_regs[i] = call_really_used_regs[i] = 0;
8926 else
8928 for (i = 18; i < 20; i++)
8929 call_used_regs[i] = call_really_used_regs[i] = 0;
8932 if (TARGET_SOFT_FLOAT)
8934 for (i = 16; i < 32; i++)
8935 call_used_regs[i] = fixed_regs[i] = 1;
8939 /* Corresponding function to eh_return expander. */
8941 static GTY(()) rtx s390_tpf_eh_return_symbol;
8942 void
8943 s390_emit_tpf_eh_return (rtx target)
8945 rtx insn, reg;
8947 if (!s390_tpf_eh_return_symbol)
8948 s390_tpf_eh_return_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tpf_eh_return");
8950 reg = gen_rtx_REG (Pmode, 2);
8952 emit_move_insn (reg, target);
8953 insn = s390_emit_call (s390_tpf_eh_return_symbol, NULL_RTX, reg,
8954 gen_rtx_REG (Pmode, RETURN_REGNUM));
8955 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
8957 emit_move_insn (EH_RETURN_HANDLER_RTX, reg);
8960 /* Rework the prologue/epilogue to avoid saving/restoring
8961 registers unnecessarily. */
8963 static void
8964 s390_optimize_prologue (void)
8966 rtx insn, new_insn, next_insn;
8968 /* Do a final recompute of the frame-related data. */
8970 s390_update_frame_layout ();
8972 /* If all special registers are in fact used, there's nothing we
8973 can do, so no point in walking the insn list. */
8975 if (cfun_frame_layout.first_save_gpr <= BASE_REGNUM
8976 && cfun_frame_layout.last_save_gpr >= BASE_REGNUM
8977 && (TARGET_CPU_ZARCH
8978 || (cfun_frame_layout.first_save_gpr <= RETURN_REGNUM
8979 && cfun_frame_layout.last_save_gpr >= RETURN_REGNUM)))
8980 return;
8982 /* Search for prologue/epilogue insns and replace them. */
8984 for (insn = get_insns (); insn; insn = next_insn)
8986 int first, last, off;
8987 rtx set, base, offset;
8989 next_insn = NEXT_INSN (insn);
8991 if (GET_CODE (insn) != INSN)
8992 continue;
8994 if (GET_CODE (PATTERN (insn)) == PARALLEL
8995 && store_multiple_operation (PATTERN (insn), VOIDmode))
8997 set = XVECEXP (PATTERN (insn), 0, 0);
8998 first = REGNO (SET_SRC (set));
8999 last = first + XVECLEN (PATTERN (insn), 0) - 1;
9000 offset = const0_rtx;
9001 base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
9002 off = INTVAL (offset);
9004 if (GET_CODE (base) != REG || off < 0)
9005 continue;
9006 if (cfun_frame_layout.first_save_gpr != -1
9007 && (cfun_frame_layout.first_save_gpr < first
9008 || cfun_frame_layout.last_save_gpr > last))
9009 continue;
9010 if (REGNO (base) != STACK_POINTER_REGNUM
9011 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
9012 continue;
9013 if (first > BASE_REGNUM || last < BASE_REGNUM)
9014 continue;
9016 if (cfun_frame_layout.first_save_gpr != -1)
9018 new_insn = save_gprs (base,
9019 off + (cfun_frame_layout.first_save_gpr
9020 - first) * UNITS_PER_WORD,
9021 cfun_frame_layout.first_save_gpr,
9022 cfun_frame_layout.last_save_gpr);
9023 new_insn = emit_insn_before (new_insn, insn);
9024 INSN_ADDRESSES_NEW (new_insn, -1);
9027 remove_insn (insn);
9028 continue;
9031 if (cfun_frame_layout.first_save_gpr == -1
9032 && GET_CODE (PATTERN (insn)) == SET
9033 && GET_CODE (SET_SRC (PATTERN (insn))) == REG
9034 && (REGNO (SET_SRC (PATTERN (insn))) == BASE_REGNUM
9035 || (!TARGET_CPU_ZARCH
9036 && REGNO (SET_SRC (PATTERN (insn))) == RETURN_REGNUM))
9037 && GET_CODE (SET_DEST (PATTERN (insn))) == MEM)
9039 set = PATTERN (insn);
9040 first = REGNO (SET_SRC (set));
9041 offset = const0_rtx;
9042 base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
9043 off = INTVAL (offset);
9045 if (GET_CODE (base) != REG || off < 0)
9046 continue;
9047 if (REGNO (base) != STACK_POINTER_REGNUM
9048 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
9049 continue;
9051 remove_insn (insn);
9052 continue;
9055 if (GET_CODE (PATTERN (insn)) == PARALLEL
9056 && load_multiple_operation (PATTERN (insn), VOIDmode))
9058 set = XVECEXP (PATTERN (insn), 0, 0);
9059 first = REGNO (SET_DEST (set));
9060 last = first + XVECLEN (PATTERN (insn), 0) - 1;
9061 offset = const0_rtx;
9062 base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
9063 off = INTVAL (offset);
9065 if (GET_CODE (base) != REG || off < 0)
9066 continue;
9067 if (cfun_frame_layout.first_restore_gpr != -1
9068 && (cfun_frame_layout.first_restore_gpr < first
9069 || cfun_frame_layout.last_restore_gpr > last))
9070 continue;
9071 if (REGNO (base) != STACK_POINTER_REGNUM
9072 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
9073 continue;
9074 if (first > BASE_REGNUM || last < BASE_REGNUM)
9075 continue;
9077 if (cfun_frame_layout.first_restore_gpr != -1)
9079 new_insn = restore_gprs (base,
9080 off + (cfun_frame_layout.first_restore_gpr
9081 - first) * UNITS_PER_WORD,
9082 cfun_frame_layout.first_restore_gpr,
9083 cfun_frame_layout.last_restore_gpr);
9084 new_insn = emit_insn_before (new_insn, insn);
9085 INSN_ADDRESSES_NEW (new_insn, -1);
9088 remove_insn (insn);
9089 continue;
9092 if (cfun_frame_layout.first_restore_gpr == -1
9093 && GET_CODE (PATTERN (insn)) == SET
9094 && GET_CODE (SET_DEST (PATTERN (insn))) == REG
9095 && (REGNO (SET_DEST (PATTERN (insn))) == BASE_REGNUM
9096 || (!TARGET_CPU_ZARCH
9097 && REGNO (SET_DEST (PATTERN (insn))) == RETURN_REGNUM))
9098 && GET_CODE (SET_SRC (PATTERN (insn))) == MEM)
9100 set = PATTERN (insn);
9101 first = REGNO (SET_DEST (set));
9102 offset = const0_rtx;
9103 base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
9104 off = INTVAL (offset);
9106 if (GET_CODE (base) != REG || off < 0)
9107 continue;
9108 if (REGNO (base) != STACK_POINTER_REGNUM
9109 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
9110 continue;
9112 remove_insn (insn);
9113 continue;
9118 /* Perform machine-dependent processing. */
9120 static void
9121 s390_reorg (void)
9123 bool pool_overflow = false;
9125 /* Make sure all splits have been performed; splits after
9126 machine_dependent_reorg might confuse insn length counts. */
9127 split_all_insns_noflow ();
9129 /* From here on decomposed literal pool addresses must be accepted. */
9130 cfun->machine->decomposed_literal_pool_addresses_ok_p = true;
9132 /* Install the main literal pool and the associated base
9133 register load insns.
9135 In addition, there are two problematic situations we need
9136 to correct:
9138 - the literal pool might be > 4096 bytes in size, so that
9139 some of its elements cannot be directly accessed
9141 - a branch target might be > 64K away from the branch, so that
9142 it is not possible to use a PC-relative instruction.
9144 To fix those, we split the single literal pool into multiple
9145 pool chunks, reloading the pool base register at various
9146 points throughout the function to ensure it always points to
9147 the pool chunk the following code expects, and / or replace
9148 PC-relative branches by absolute branches.
9150 However, the two problems are interdependent: splitting the
9151 literal pool can move a branch further away from its target,
9152 causing the 64K limit to overflow, and on the other hand,
9153 replacing a PC-relative branch by an absolute branch means
9154 we need to put the branch target address into the literal
9155 pool, possibly causing it to overflow.
9157 So, we loop trying to fix up both problems until we manage
9158 to satisfy both conditions at the same time. Note that the
9159 loop is guaranteed to terminate as every pass of the loop
9160 strictly decreases the total number of PC-relative branches
9161 in the function. (This is not completely true as there
9162 might be branch-over-pool insns introduced by chunkify_start.
9163 Those never need to be split however.) */
9165 for (;;)
9167 struct constant_pool *pool = NULL;
9169 /* Collect the literal pool. */
9170 if (!pool_overflow)
9172 pool = s390_mainpool_start ();
9173 if (!pool)
9174 pool_overflow = true;
9177 /* If literal pool overflowed, start to chunkify it. */
9178 if (pool_overflow)
9179 pool = s390_chunkify_start ();
9181 /* Split out-of-range branches. If this has created new
9182 literal pool entries, cancel current chunk list and
9183 recompute it. zSeries machines have large branch
9184 instructions, so we never need to split a branch. */
9185 if (!TARGET_CPU_ZARCH && s390_split_branches ())
9187 if (pool_overflow)
9188 s390_chunkify_cancel (pool);
9189 else
9190 s390_mainpool_cancel (pool);
9192 continue;
9195 /* If we made it up to here, both conditions are satisfied.
9196 Finish up literal pool related changes. */
9197 if (pool_overflow)
9198 s390_chunkify_finish (pool);
9199 else
9200 s390_mainpool_finish (pool);
9202 /* We're done splitting branches. */
9203 cfun->machine->split_branches_pending_p = false;
9204 break;
9207 /* Generate out-of-pool execute target insns. */
9208 if (TARGET_CPU_ZARCH)
9210 rtx insn, label, target;
9212 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
9214 label = s390_execute_label (insn);
9215 if (!label)
9216 continue;
9218 gcc_assert (label != const0_rtx);
9220 target = emit_label (XEXP (label, 0));
9221 INSN_ADDRESSES_NEW (target, -1);
9223 target = emit_insn (s390_execute_target (insn));
9224 INSN_ADDRESSES_NEW (target, -1);
9228 /* Try to optimize prologue and epilogue further. */
9229 s390_optimize_prologue ();
9233 /* Initialize GCC target structure. */
9235 #undef TARGET_ASM_ALIGNED_HI_OP
9236 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
9237 #undef TARGET_ASM_ALIGNED_DI_OP
9238 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
9239 #undef TARGET_ASM_INTEGER
9240 #define TARGET_ASM_INTEGER s390_assemble_integer
9242 #undef TARGET_ASM_OPEN_PAREN
9243 #define TARGET_ASM_OPEN_PAREN ""
9245 #undef TARGET_ASM_CLOSE_PAREN
9246 #define TARGET_ASM_CLOSE_PAREN ""
9248 #undef TARGET_DEFAULT_TARGET_FLAGS
9249 #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD)
9250 #undef TARGET_HANDLE_OPTION
9251 #define TARGET_HANDLE_OPTION s390_handle_option
9253 #undef TARGET_ENCODE_SECTION_INFO
9254 #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
9256 #ifdef HAVE_AS_TLS
9257 #undef TARGET_HAVE_TLS
9258 #define TARGET_HAVE_TLS true
9259 #endif
9260 #undef TARGET_CANNOT_FORCE_CONST_MEM
9261 #define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
9263 #undef TARGET_DELEGITIMIZE_ADDRESS
9264 #define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
9266 #undef TARGET_RETURN_IN_MEMORY
9267 #define TARGET_RETURN_IN_MEMORY s390_return_in_memory
9269 #undef TARGET_INIT_BUILTINS
9270 #define TARGET_INIT_BUILTINS s390_init_builtins
9271 #undef TARGET_EXPAND_BUILTIN
9272 #define TARGET_EXPAND_BUILTIN s390_expand_builtin
9274 #undef TARGET_ASM_OUTPUT_MI_THUNK
9275 #define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
9276 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
9277 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
9279 #undef TARGET_SCHED_ADJUST_PRIORITY
9280 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
9281 #undef TARGET_SCHED_ISSUE_RATE
9282 #define TARGET_SCHED_ISSUE_RATE s390_issue_rate
9283 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
9284 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
9286 #undef TARGET_CANNOT_COPY_INSN_P
9287 #define TARGET_CANNOT_COPY_INSN_P s390_cannot_copy_insn_p
9288 #undef TARGET_RTX_COSTS
9289 #define TARGET_RTX_COSTS s390_rtx_costs
9290 #undef TARGET_ADDRESS_COST
9291 #define TARGET_ADDRESS_COST s390_address_cost
9293 #undef TARGET_MACHINE_DEPENDENT_REORG
9294 #define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
9296 #undef TARGET_VALID_POINTER_MODE
9297 #define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
9299 #undef TARGET_BUILD_BUILTIN_VA_LIST
9300 #define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
9301 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
9302 #define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg
9304 #undef TARGET_PROMOTE_FUNCTION_ARGS
9305 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
9306 #undef TARGET_PROMOTE_FUNCTION_RETURN
9307 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
9308 #undef TARGET_PASS_BY_REFERENCE
9309 #define TARGET_PASS_BY_REFERENCE s390_pass_by_reference
9311 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
9312 #define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
9314 #undef TARGET_FIXED_CONDITION_CODE_REGS
9315 #define TARGET_FIXED_CONDITION_CODE_REGS s390_fixed_condition_code_regs
9317 #undef TARGET_CC_MODES_COMPATIBLE
9318 #define TARGET_CC_MODES_COMPATIBLE s390_cc_modes_compatible
9320 #undef TARGET_INVALID_WITHIN_DOLOOP
9321 #define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_rtx_null
9323 #ifdef HAVE_AS_TLS
9324 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
9325 #define TARGET_ASM_OUTPUT_DWARF_DTPREL s390_output_dwarf_dtprel
9326 #endif
9328 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
9329 #undef TARGET_MANGLE_FUNDAMENTAL_TYPE
9330 #define TARGET_MANGLE_FUNDAMENTAL_TYPE s390_mangle_fundamental_type
9331 #endif
9333 #undef TARGET_SCALAR_MODE_SUPPORTED_P
9334 #define TARGET_SCALAR_MODE_SUPPORTED_P s390_scalar_mode_supported_p
9336 struct gcc_target targetm = TARGET_INITIALIZER;
9338 #include "gt-s390.h"