1 /* Subroutines used for code generation on IBM S/390 and zSeries
2 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
3 Free Software Foundation, Inc.
4 Contributed by Hartmut Penner (hpenner@de.ibm.com) and
5 Ulrich Weigand (uweigand@de.ibm.com).
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
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
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
26 #include "coretypes.h"
32 #include "hard-reg-set.h"
34 #include "insn-config.h"
35 #include "conditions.h"
37 #include "insn-attr.h"
45 #include "basic-block.h"
46 #include "integrate.h"
49 #include "target-def.h"
51 #include "langhooks.h"
53 #include "tree-gimple.h"
56 /* Define the specific costs for a given cpu. */
58 struct processor_costs
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. */
75 const int sqdbr
; /* cost of square root in DFmode. */
76 const int sqebr
; /* cost of square root in SFmode. */
77 /* multiply and add */
78 const int madbr
; /* cost of multiply and add in DFmode. */
79 const int maebr
; /* cost of multiply and add in SFmode. */
92 const struct processor_costs
*s390_cost
;
95 struct processor_costs z900_cost
=
97 COSTS_N_INSNS (5), /* M */
98 COSTS_N_INSNS (10), /* MGHI */
99 COSTS_N_INSNS (5), /* MH */
100 COSTS_N_INSNS (4), /* MHI */
101 COSTS_N_INSNS (5), /* ML */
102 COSTS_N_INSNS (5), /* MR */
103 COSTS_N_INSNS (4), /* MS */
104 COSTS_N_INSNS (15), /* MSG */
105 COSTS_N_INSNS (7), /* MSGF */
106 COSTS_N_INSNS (7), /* MSGFR */
107 COSTS_N_INSNS (10), /* MSGR */
108 COSTS_N_INSNS (4), /* MSR */
109 COSTS_N_INSNS (7), /* multiplication in DFmode */
110 COSTS_N_INSNS (44), /* SQDBR */
111 COSTS_N_INSNS (35), /* SQEBR */
112 COSTS_N_INSNS (18), /* MADBR */
113 COSTS_N_INSNS (13), /* MAEBR */
114 COSTS_N_INSNS (30), /* DDBR */
115 COSTS_N_INSNS (30), /* DDR */
116 COSTS_N_INSNS (27), /* DEBR */
117 COSTS_N_INSNS (26), /* DER */
118 COSTS_N_INSNS (220), /* DLGR */
119 COSTS_N_INSNS (34), /* DLR */
120 COSTS_N_INSNS (34), /* DR */
121 COSTS_N_INSNS (32), /* DSGFR */
122 COSTS_N_INSNS (32), /* DSGR */
126 struct processor_costs z990_cost
=
128 COSTS_N_INSNS (4), /* M */
129 COSTS_N_INSNS (2), /* MGHI */
130 COSTS_N_INSNS (2), /* MH */
131 COSTS_N_INSNS (2), /* MHI */
132 COSTS_N_INSNS (4), /* ML */
133 COSTS_N_INSNS (4), /* MR */
134 COSTS_N_INSNS (5), /* MS */
135 COSTS_N_INSNS (6), /* MSG */
136 COSTS_N_INSNS (4), /* MSGF */
137 COSTS_N_INSNS (4), /* MSGFR */
138 COSTS_N_INSNS (4), /* MSGR */
139 COSTS_N_INSNS (4), /* MSR */
140 COSTS_N_INSNS (1), /* multiplication in DFmode */
141 COSTS_N_INSNS (66), /* SQDBR */
142 COSTS_N_INSNS (38), /* SQEBR */
143 COSTS_N_INSNS (1), /* MADBR */
144 COSTS_N_INSNS (1), /* MAEBR */
145 COSTS_N_INSNS (40), /* DDBR */
146 COSTS_N_INSNS (44), /* DDR */
147 COSTS_N_INSNS (26), /* DDBR */
148 COSTS_N_INSNS (28), /* DER */
149 COSTS_N_INSNS (176), /* DLGR */
150 COSTS_N_INSNS (31), /* DLR */
151 COSTS_N_INSNS (31), /* DR */
152 COSTS_N_INSNS (31), /* DSGFR */
153 COSTS_N_INSNS (31), /* DSGR */
157 struct processor_costs z9_109_cost
=
159 COSTS_N_INSNS (4), /* M */
160 COSTS_N_INSNS (2), /* MGHI */
161 COSTS_N_INSNS (2), /* MH */
162 COSTS_N_INSNS (2), /* MHI */
163 COSTS_N_INSNS (4), /* ML */
164 COSTS_N_INSNS (4), /* MR */
165 COSTS_N_INSNS (5), /* MS */
166 COSTS_N_INSNS (6), /* MSG */
167 COSTS_N_INSNS (4), /* MSGF */
168 COSTS_N_INSNS (4), /* MSGFR */
169 COSTS_N_INSNS (4), /* MSGR */
170 COSTS_N_INSNS (4), /* MSR */
171 COSTS_N_INSNS (1), /* multiplication in DFmode */
172 COSTS_N_INSNS (66), /* SQDBR */
173 COSTS_N_INSNS (38), /* SQEBR */
174 COSTS_N_INSNS (1), /* MADBR */
175 COSTS_N_INSNS (1), /* MAEBR */
176 COSTS_N_INSNS (40), /* DDBR */
177 COSTS_N_INSNS (37), /* DDR */
178 COSTS_N_INSNS (26), /* DDBR */
179 COSTS_N_INSNS (28), /* DER */
180 COSTS_N_INSNS (30), /* DLGR */
181 COSTS_N_INSNS (23), /* DLR */
182 COSTS_N_INSNS (23), /* DR */
183 COSTS_N_INSNS (24), /* DSGFR */
184 COSTS_N_INSNS (24), /* DSGR */
187 extern int reload_completed
;
189 /* The alias set for prologue/epilogue register save/restore. */
190 static int s390_sr_alias_set
= 0;
192 /* Save information from a "cmpxx" operation until the branch or scc is
194 rtx s390_compare_op0
, s390_compare_op1
;
196 /* Save the result of a compare_and_swap until the branch or scc is
198 rtx s390_compare_emitted
= NULL_RTX
;
200 /* Structure used to hold the components of a S/390 memory
201 address. A legitimate address on S/390 is of the general
203 base + index + displacement
204 where any of the components is optional.
206 base and index are registers of the class ADDR_REGS,
207 displacement is an unsigned 12-bit immediate constant. */
217 /* Which cpu are we tuning for. */
218 enum processor_type s390_tune
= PROCESSOR_max
;
219 enum processor_flags s390_tune_flags
;
220 /* Which instruction set architecture to use. */
221 enum processor_type s390_arch
;
222 enum processor_flags s390_arch_flags
;
224 HOST_WIDE_INT s390_warn_framesize
= 0;
225 HOST_WIDE_INT s390_stack_size
= 0;
226 HOST_WIDE_INT s390_stack_guard
= 0;
228 /* The following structure is embedded in the machine
229 specific part of struct function. */
231 struct s390_frame_layout
GTY (())
233 /* Offset within stack frame. */
234 HOST_WIDE_INT gprs_offset
;
235 HOST_WIDE_INT f0_offset
;
236 HOST_WIDE_INT f4_offset
;
237 HOST_WIDE_INT f8_offset
;
238 HOST_WIDE_INT backchain_offset
;
240 /* Number of first and last gpr to be saved, restored. */
242 int first_restore_gpr
;
244 int last_restore_gpr
;
246 /* Bits standing for floating point registers. Set, if the
247 respective register has to be saved. Starting with reg 16 (f0)
248 at the rightmost bit.
249 Bit 15 - 8 7 6 5 4 3 2 1 0
250 fpr 15 - 8 7 5 3 1 6 4 2 0
251 reg 31 - 24 23 22 21 20 19 18 17 16 */
252 unsigned int fpr_bitmap
;
254 /* Number of floating point registers f8-f15 which must be saved. */
257 /* Set if return address needs to be saved.
258 This flag is set by s390_return_addr_rtx if it could not use
259 the initial value of r14 and therefore depends on r14 saved
261 bool save_return_addr_p
;
263 /* Size of stack frame. */
264 HOST_WIDE_INT frame_size
;
267 /* Define the structure for the machine field in struct function. */
269 struct machine_function
GTY(())
271 struct s390_frame_layout frame_layout
;
273 /* Literal pool base register. */
276 /* True if we may need to perform branch splitting. */
277 bool split_branches_pending_p
;
279 /* Some local-dynamic TLS symbol name. */
280 const char *some_ld_name
;
282 bool has_landing_pad_p
;
285 /* Few accessor macros for struct cfun->machine->s390_frame_layout. */
287 #define cfun_frame_layout (cfun->machine->frame_layout)
288 #define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)
289 #define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr - \
290 cfun_frame_layout.first_save_gpr + 1) * UNITS_PER_WORD)
291 #define cfun_set_fpr_bit(BITNUM) (cfun->machine->frame_layout.fpr_bitmap |= \
293 #define cfun_fpr_bit_p(BITNUM) (!!(cfun->machine->frame_layout.fpr_bitmap & \
296 /* Number of GPRs and FPRs used for argument passing. */
297 #define GP_ARG_NUM_REG 5
298 #define FP_ARG_NUM_REG (TARGET_64BIT? 4 : 2)
300 /* A couple of shortcuts. */
301 #define CONST_OK_FOR_J(x) \
302 CONST_OK_FOR_CONSTRAINT_P((x), 'J', "J")
303 #define CONST_OK_FOR_K(x) \
304 CONST_OK_FOR_CONSTRAINT_P((x), 'K', "K")
305 #define CONST_OK_FOR_Os(x) \
306 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Os")
307 #define CONST_OK_FOR_Op(x) \
308 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Op")
309 #define CONST_OK_FOR_On(x) \
310 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "On")
312 /* Set the has_landing_pad_p flag in struct machine_function to VALUE. */
315 s390_set_has_landing_pad_p (bool value
)
317 cfun
->machine
->has_landing_pad_p
= value
;
320 /* If two condition code modes are compatible, return a condition code
321 mode which is compatible with both. Otherwise, return
324 static enum machine_mode
325 s390_cc_modes_compatible (enum machine_mode m1
, enum machine_mode m2
)
333 if (m2
== CCUmode
|| m2
== CCTmode
|| m2
== CCZ1mode
334 || m2
== CCSmode
|| m2
== CCSRmode
|| m2
== CCURmode
)
355 /* Return true if SET either doesn't set the CC register, or else
356 the source and destination have matching CC modes and that
357 CC mode is at least as constrained as REQ_MODE. */
360 s390_match_ccmode_set (rtx set
, enum machine_mode req_mode
)
362 enum machine_mode set_mode
;
364 gcc_assert (GET_CODE (set
) == SET
);
366 if (GET_CODE (SET_DEST (set
)) != REG
|| !CC_REGNO_P (REGNO (SET_DEST (set
))))
369 set_mode
= GET_MODE (SET_DEST (set
));
383 if (req_mode
!= set_mode
)
388 if (req_mode
!= CCSmode
&& req_mode
!= CCUmode
&& req_mode
!= CCTmode
389 && req_mode
!= CCSRmode
&& req_mode
!= CCURmode
)
395 if (req_mode
!= CCAmode
)
403 return (GET_MODE (SET_SRC (set
)) == set_mode
);
406 /* Return true if every SET in INSN that sets the CC register
407 has source and destination with matching CC modes and that
408 CC mode is at least as constrained as REQ_MODE.
409 If REQ_MODE is VOIDmode, always return false. */
412 s390_match_ccmode (rtx insn
, enum machine_mode req_mode
)
416 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
417 if (req_mode
== VOIDmode
)
420 if (GET_CODE (PATTERN (insn
)) == SET
)
421 return s390_match_ccmode_set (PATTERN (insn
), req_mode
);
423 if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
424 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
426 rtx set
= XVECEXP (PATTERN (insn
), 0, i
);
427 if (GET_CODE (set
) == SET
)
428 if (!s390_match_ccmode_set (set
, req_mode
))
435 /* If a test-under-mask instruction can be used to implement
436 (compare (and ... OP1) OP2), return the CC mode required
437 to do that. Otherwise, return VOIDmode.
438 MIXED is true if the instruction can distinguish between
439 CC1 and CC2 for mixed selected bits (TMxx), it is false
440 if the instruction cannot (TM). */
443 s390_tm_ccmode (rtx op1
, rtx op2
, bool mixed
)
447 /* ??? Fixme: should work on CONST_DOUBLE as well. */
448 if (GET_CODE (op1
) != CONST_INT
|| GET_CODE (op2
) != CONST_INT
)
451 /* Selected bits all zero: CC0.
452 e.g.: int a; if ((a & (16 + 128)) == 0) */
453 if (INTVAL (op2
) == 0)
456 /* Selected bits all one: CC3.
457 e.g.: int a; if ((a & (16 + 128)) == 16 + 128) */
458 if (INTVAL (op2
) == INTVAL (op1
))
461 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. e.g.:
463 if ((a & (16 + 128)) == 16) -> CCT1
464 if ((a & (16 + 128)) == 128) -> CCT2 */
467 bit1
= exact_log2 (INTVAL (op2
));
468 bit0
= exact_log2 (INTVAL (op1
) ^ INTVAL (op2
));
469 if (bit0
!= -1 && bit1
!= -1)
470 return bit0
> bit1
? CCT1mode
: CCT2mode
;
476 /* Given a comparison code OP (EQ, NE, etc.) and the operands
477 OP0 and OP1 of a COMPARE, return the mode to be used for the
481 s390_select_ccmode (enum rtx_code code
, rtx op0
, rtx op1
)
487 if ((GET_CODE (op0
) == NEG
|| GET_CODE (op0
) == ABS
)
488 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
490 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
491 && CONST_OK_FOR_K (INTVAL (XEXP (op0
, 1))))
493 if ((GET_CODE (op0
) == PLUS
|| GET_CODE (op0
) == MINUS
494 || GET_CODE (op1
) == NEG
)
495 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
498 if (GET_CODE (op0
) == AND
)
500 /* Check whether we can potentially do it via TM. */
501 enum machine_mode ccmode
;
502 ccmode
= s390_tm_ccmode (XEXP (op0
, 1), op1
, 1);
503 if (ccmode
!= VOIDmode
)
505 /* Relax CCTmode to CCZmode to allow fall-back to AND
506 if that turns out to be beneficial. */
507 return ccmode
== CCTmode
? CCZmode
: ccmode
;
511 if (register_operand (op0
, HImode
)
512 && GET_CODE (op1
) == CONST_INT
513 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 65535))
515 if (register_operand (op0
, QImode
)
516 && GET_CODE (op1
) == CONST_INT
517 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 255))
526 /* The only overflow condition of NEG and ABS happens when
527 -INT_MAX is used as parameter, which stays negative. So
528 we have an overflow from a positive value to a negative.
529 Using CCAP mode the resulting cc can be used for comparisons. */
530 if ((GET_CODE (op0
) == NEG
|| GET_CODE (op0
) == ABS
)
531 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
534 /* If constants are involved in an add instruction it is possible to use
535 the resulting cc for comparisons with zero. Knowing the sign of the
536 constant the overflow behavior gets predictable. e.g.:
537 int a, b; if ((b = a + c) > 0)
538 with c as a constant value: c < 0 -> CCAN and c >= 0 -> CCAP */
539 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
540 && CONST_OK_FOR_K (INTVAL (XEXP (op0
, 1))))
542 if (INTVAL (XEXP((op0
), 1)) < 0)
556 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
557 && GET_CODE (op1
) != CONST_INT
)
563 if (GET_CODE (op0
) == PLUS
564 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
567 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
568 && GET_CODE (op1
) != CONST_INT
)
574 if (GET_CODE (op0
) == MINUS
575 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
578 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
579 && GET_CODE (op1
) != CONST_INT
)
588 /* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
589 that we can implement more efficiently. */
592 s390_canonicalize_comparison (enum rtx_code
*code
, rtx
*op0
, rtx
*op1
)
594 /* Convert ZERO_EXTRACT back to AND to enable TM patterns. */
595 if ((*code
== EQ
|| *code
== NE
)
596 && *op1
== const0_rtx
597 && GET_CODE (*op0
) == ZERO_EXTRACT
598 && GET_CODE (XEXP (*op0
, 1)) == CONST_INT
599 && GET_CODE (XEXP (*op0
, 2)) == CONST_INT
600 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0
, 0))))
602 rtx inner
= XEXP (*op0
, 0);
603 HOST_WIDE_INT modesize
= GET_MODE_BITSIZE (GET_MODE (inner
));
604 HOST_WIDE_INT len
= INTVAL (XEXP (*op0
, 1));
605 HOST_WIDE_INT pos
= INTVAL (XEXP (*op0
, 2));
607 if (len
> 0 && len
< modesize
608 && pos
>= 0 && pos
+ len
<= modesize
609 && modesize
<= HOST_BITS_PER_WIDE_INT
)
611 unsigned HOST_WIDE_INT block
;
612 block
= ((unsigned HOST_WIDE_INT
) 1 << len
) - 1;
613 block
<<= modesize
- pos
- len
;
615 *op0
= gen_rtx_AND (GET_MODE (inner
), inner
,
616 gen_int_mode (block
, GET_MODE (inner
)));
620 /* Narrow AND of memory against immediate to enable TM. */
621 if ((*code
== EQ
|| *code
== NE
)
622 && *op1
== const0_rtx
623 && GET_CODE (*op0
) == AND
624 && GET_CODE (XEXP (*op0
, 1)) == CONST_INT
625 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0
, 0))))
627 rtx inner
= XEXP (*op0
, 0);
628 rtx mask
= XEXP (*op0
, 1);
630 /* Ignore paradoxical SUBREGs if all extra bits are masked out. */
631 if (GET_CODE (inner
) == SUBREG
632 && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (inner
)))
633 && (GET_MODE_SIZE (GET_MODE (inner
))
634 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner
))))
636 & GET_MODE_MASK (GET_MODE (inner
))
637 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (inner
))))
639 inner
= SUBREG_REG (inner
);
641 /* Do not change volatile MEMs. */
642 if (MEM_P (inner
) && !MEM_VOLATILE_P (inner
))
644 int part
= s390_single_part (XEXP (*op0
, 1),
645 GET_MODE (inner
), QImode
, 0);
648 mask
= gen_int_mode (s390_extract_part (mask
, QImode
, 0), QImode
);
649 inner
= adjust_address_nv (inner
, QImode
, part
);
650 *op0
= gen_rtx_AND (QImode
, inner
, mask
);
655 /* Narrow comparisons against 0xffff to HImode if possible. */
656 if ((*code
== EQ
|| *code
== NE
)
657 && GET_CODE (*op1
) == CONST_INT
658 && INTVAL (*op1
) == 0xffff
659 && SCALAR_INT_MODE_P (GET_MODE (*op0
))
660 && (nonzero_bits (*op0
, GET_MODE (*op0
))
661 & ~(unsigned HOST_WIDE_INT
) 0xffff) == 0)
663 *op0
= gen_lowpart (HImode
, *op0
);
668 /* Remove redundant UNSPEC_CMPINT conversions if possible. */
669 if (GET_CODE (*op0
) == UNSPEC
670 && XINT (*op0
, 1) == UNSPEC_CMPINT
671 && XVECLEN (*op0
, 0) == 1
672 && GET_MODE (XVECEXP (*op0
, 0, 0)) == CCUmode
673 && GET_CODE (XVECEXP (*op0
, 0, 0)) == REG
674 && REGNO (XVECEXP (*op0
, 0, 0)) == CC_REGNUM
675 && *op1
== const0_rtx
)
677 enum rtx_code new_code
= UNKNOWN
;
680 case EQ
: new_code
= EQ
; break;
681 case NE
: new_code
= NE
; break;
682 case LT
: new_code
= GTU
; break;
683 case GT
: new_code
= LTU
; break;
684 case LE
: new_code
= GEU
; break;
685 case GE
: new_code
= LEU
; break;
689 if (new_code
!= UNKNOWN
)
691 *op0
= XVECEXP (*op0
, 0, 0);
696 /* Simplify cascaded EQ, NE with const0_rtx. */
697 if ((*code
== NE
|| *code
== EQ
)
698 && (GET_CODE (*op0
) == EQ
|| GET_CODE (*op0
) == NE
)
699 && GET_MODE (*op0
) == SImode
700 && GET_MODE (XEXP (*op0
, 0)) == CCZ1mode
701 && REG_P (XEXP (*op0
, 0))
702 && XEXP (*op0
, 1) == const0_rtx
703 && *op1
== const0_rtx
)
705 if ((*code
== EQ
&& GET_CODE (*op0
) == NE
)
706 || (*code
== NE
&& GET_CODE (*op0
) == EQ
))
710 *op0
= XEXP (*op0
, 0);
713 /* Prefer register over memory as first operand. */
714 if (MEM_P (*op0
) && REG_P (*op1
))
716 rtx tem
= *op0
; *op0
= *op1
; *op1
= tem
;
717 *code
= swap_condition (*code
);
721 /* Emit a compare instruction suitable to implement the comparison
722 OP0 CODE OP1. Return the correct condition RTL to be placed in
723 the IF_THEN_ELSE of the conditional branch testing the result. */
726 s390_emit_compare (enum rtx_code code
, rtx op0
, rtx op1
)
728 enum machine_mode mode
= s390_select_ccmode (code
, op0
, op1
);
731 /* Do not output a redundant compare instruction if a compare_and_swap
732 pattern already computed the result and the machine modes are compatible. */
733 if (s390_compare_emitted
734 && (s390_cc_modes_compatible (GET_MODE (s390_compare_emitted
), mode
)
735 == GET_MODE (s390_compare_emitted
)))
736 ret
= gen_rtx_fmt_ee (code
, VOIDmode
, s390_compare_emitted
, const0_rtx
);
739 rtx cc
= gen_rtx_REG (mode
, CC_REGNUM
);
741 emit_insn (gen_rtx_SET (VOIDmode
, cc
, gen_rtx_COMPARE (mode
, op0
, op1
)));
742 ret
= gen_rtx_fmt_ee (code
, VOIDmode
, cc
, const0_rtx
);
744 s390_compare_emitted
= NULL_RTX
;
748 /* Emit a jump instruction to TARGET. If COND is NULL_RTX, emit an
749 unconditional jump, else a conditional jump under condition COND. */
752 s390_emit_jump (rtx target
, rtx cond
)
756 target
= gen_rtx_LABEL_REF (VOIDmode
, target
);
758 target
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, target
, pc_rtx
);
760 insn
= gen_rtx_SET (VOIDmode
, pc_rtx
, target
);
761 emit_jump_insn (insn
);
764 /* Return branch condition mask to implement a branch
765 specified by CODE. Return -1 for invalid comparisons. */
768 s390_branch_condition_mask (rtx code
)
770 const int CC0
= 1 << 3;
771 const int CC1
= 1 << 2;
772 const int CC2
= 1 << 1;
773 const int CC3
= 1 << 0;
775 gcc_assert (GET_CODE (XEXP (code
, 0)) == REG
);
776 gcc_assert (REGNO (XEXP (code
, 0)) == CC_REGNUM
);
777 gcc_assert (XEXP (code
, 1) == const0_rtx
);
779 switch (GET_MODE (XEXP (code
, 0)))
783 switch (GET_CODE (code
))
786 case NE
: return CC1
| CC2
| CC3
;
792 switch (GET_CODE (code
))
795 case NE
: return CC0
| CC2
| CC3
;
801 switch (GET_CODE (code
))
804 case NE
: return CC0
| CC1
| CC3
;
810 switch (GET_CODE (code
))
813 case NE
: return CC0
| CC1
| CC2
;
819 switch (GET_CODE (code
))
821 case EQ
: return CC0
| CC2
;
822 case NE
: return CC1
| CC3
;
828 switch (GET_CODE (code
))
830 case LTU
: return CC2
| CC3
; /* carry */
831 case GEU
: return CC0
| CC1
; /* no carry */
837 switch (GET_CODE (code
))
839 case GTU
: return CC0
| CC1
; /* borrow */
840 case LEU
: return CC2
| CC3
; /* no borrow */
846 switch (GET_CODE (code
))
848 case EQ
: return CC0
| CC2
;
849 case NE
: return CC1
| CC3
;
850 case LTU
: return CC1
;
851 case GTU
: return CC3
;
852 case LEU
: return CC1
| CC2
;
853 case GEU
: return CC2
| CC3
;
858 switch (GET_CODE (code
))
861 case NE
: return CC1
| CC2
| CC3
;
862 case LTU
: return CC1
;
863 case GTU
: return CC2
;
864 case LEU
: return CC0
| CC1
;
865 case GEU
: return CC0
| CC2
;
871 switch (GET_CODE (code
))
874 case NE
: return CC2
| CC1
| CC3
;
875 case LTU
: return CC2
;
876 case GTU
: return CC1
;
877 case LEU
: return CC0
| CC2
;
878 case GEU
: return CC0
| CC1
;
884 switch (GET_CODE (code
))
887 case NE
: return CC1
| CC2
| CC3
;
888 case LT
: return CC1
| CC3
;
890 case LE
: return CC0
| CC1
| CC3
;
891 case GE
: return CC0
| CC2
;
897 switch (GET_CODE (code
))
900 case NE
: return CC1
| CC2
| CC3
;
902 case GT
: return CC2
| CC3
;
903 case LE
: return CC0
| CC1
;
904 case GE
: return CC0
| CC2
| CC3
;
910 switch (GET_CODE (code
))
913 case NE
: return CC1
| CC2
| CC3
;
916 case LE
: return CC0
| CC1
;
917 case GE
: return CC0
| CC2
;
918 case UNORDERED
: return CC3
;
919 case ORDERED
: return CC0
| CC1
| CC2
;
920 case UNEQ
: return CC0
| CC3
;
921 case UNLT
: return CC1
| CC3
;
922 case UNGT
: return CC2
| CC3
;
923 case UNLE
: return CC0
| CC1
| CC3
;
924 case UNGE
: return CC0
| CC2
| CC3
;
925 case LTGT
: return CC1
| CC2
;
931 switch (GET_CODE (code
))
934 case NE
: return CC2
| CC1
| CC3
;
937 case LE
: return CC0
| CC2
;
938 case GE
: return CC0
| CC1
;
939 case UNORDERED
: return CC3
;
940 case ORDERED
: return CC0
| CC2
| CC1
;
941 case UNEQ
: return CC0
| CC3
;
942 case UNLT
: return CC2
| CC3
;
943 case UNGT
: return CC1
| CC3
;
944 case UNLE
: return CC0
| CC2
| CC3
;
945 case UNGE
: return CC0
| CC1
| CC3
;
946 case LTGT
: return CC2
| CC1
;
956 /* If INV is false, return assembler mnemonic string to implement
957 a branch specified by CODE. If INV is true, return mnemonic
958 for the corresponding inverted branch. */
961 s390_branch_condition_mnemonic (rtx code
, int inv
)
963 static const char *const mnemonic
[16] =
965 NULL
, "o", "h", "nle",
966 "l", "nhe", "lh", "ne",
967 "e", "nlh", "he", "nl",
968 "le", "nh", "no", NULL
971 int mask
= s390_branch_condition_mask (code
);
972 gcc_assert (mask
>= 0);
977 gcc_assert (mask
>= 1 && mask
<= 14);
979 return mnemonic
[mask
];
982 /* Return the part of op which has a value different from def.
983 The size of the part is determined by mode.
984 Use this function only if you already know that op really
985 contains such a part. */
987 unsigned HOST_WIDE_INT
988 s390_extract_part (rtx op
, enum machine_mode mode
, int def
)
990 unsigned HOST_WIDE_INT value
= 0;
991 int max_parts
= HOST_BITS_PER_WIDE_INT
/ GET_MODE_BITSIZE (mode
);
992 int part_bits
= GET_MODE_BITSIZE (mode
);
993 unsigned HOST_WIDE_INT part_mask
994 = ((unsigned HOST_WIDE_INT
)1 << part_bits
) - 1;
997 for (i
= 0; i
< max_parts
; i
++)
1000 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
1002 value
>>= part_bits
;
1004 if ((value
& part_mask
) != (def
& part_mask
))
1005 return value
& part_mask
;
1011 /* If OP is an integer constant of mode MODE with exactly one
1012 part of mode PART_MODE unequal to DEF, return the number of that
1013 part. Otherwise, return -1. */
1016 s390_single_part (rtx op
,
1017 enum machine_mode mode
,
1018 enum machine_mode part_mode
,
1021 unsigned HOST_WIDE_INT value
= 0;
1022 int n_parts
= GET_MODE_SIZE (mode
) / GET_MODE_SIZE (part_mode
);
1023 unsigned HOST_WIDE_INT part_mask
1024 = ((unsigned HOST_WIDE_INT
)1 << GET_MODE_BITSIZE (part_mode
)) - 1;
1027 if (GET_CODE (op
) != CONST_INT
)
1030 for (i
= 0; i
< n_parts
; i
++)
1033 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
1035 value
>>= GET_MODE_BITSIZE (part_mode
);
1037 if ((value
& part_mask
) != (def
& part_mask
))
1045 return part
== -1 ? -1 : n_parts
- 1 - part
;
1048 /* Check whether we can (and want to) split a double-word
1049 move in mode MODE from SRC to DST into two single-word
1050 moves, moving the subword FIRST_SUBWORD first. */
1053 s390_split_ok_p (rtx dst
, rtx src
, enum machine_mode mode
, int first_subword
)
1055 /* Floating point registers cannot be split. */
1056 if (FP_REG_P (src
) || FP_REG_P (dst
))
1059 /* We don't need to split if operands are directly accessible. */
1060 if (s_operand (src
, mode
) || s_operand (dst
, mode
))
1063 /* Non-offsettable memory references cannot be split. */
1064 if ((GET_CODE (src
) == MEM
&& !offsettable_memref_p (src
))
1065 || (GET_CODE (dst
) == MEM
&& !offsettable_memref_p (dst
)))
1068 /* Moving the first subword must not clobber a register
1069 needed to move the second subword. */
1070 if (register_operand (dst
, mode
))
1072 rtx subreg
= operand_subword (dst
, first_subword
, 0, mode
);
1073 if (reg_overlap_mentioned_p (subreg
, src
))
1080 /* Check whether the address of memory reference MEM2 equals exactly
1081 the address of memory reference MEM1 plus DELTA. Return true if
1082 we can prove this to be the case, false otherwise. */
1085 s390_offset_p (rtx mem1
, rtx mem2
, rtx delta
)
1087 rtx addr1
, addr2
, addr_delta
;
1089 if (GET_CODE (mem1
) != MEM
|| GET_CODE (mem2
) != MEM
)
1092 addr1
= XEXP (mem1
, 0);
1093 addr2
= XEXP (mem2
, 0);
1095 addr_delta
= simplify_binary_operation (MINUS
, Pmode
, addr2
, addr1
);
1096 if (!addr_delta
|| !rtx_equal_p (addr_delta
, delta
))
1102 /* Expand logical operator CODE in mode MODE with operands OPERANDS. */
1105 s390_expand_logical_operator (enum rtx_code code
, enum machine_mode mode
,
1108 enum machine_mode wmode
= mode
;
1109 rtx dst
= operands
[0];
1110 rtx src1
= operands
[1];
1111 rtx src2
= operands
[2];
1114 /* If we cannot handle the operation directly, use a temp register. */
1115 if (!s390_logical_operator_ok_p (operands
))
1116 dst
= gen_reg_rtx (mode
);
1118 /* QImode and HImode patterns make sense only if we have a destination
1119 in memory. Otherwise perform the operation in SImode. */
1120 if ((mode
== QImode
|| mode
== HImode
) && GET_CODE (dst
) != MEM
)
1123 /* Widen operands if required. */
1126 if (GET_CODE (dst
) == SUBREG
1127 && (tem
= simplify_subreg (wmode
, dst
, mode
, 0)) != 0)
1129 else if (REG_P (dst
))
1130 dst
= gen_rtx_SUBREG (wmode
, dst
, 0);
1132 dst
= gen_reg_rtx (wmode
);
1134 if (GET_CODE (src1
) == SUBREG
1135 && (tem
= simplify_subreg (wmode
, src1
, mode
, 0)) != 0)
1137 else if (GET_MODE (src1
) != VOIDmode
)
1138 src1
= gen_rtx_SUBREG (wmode
, force_reg (mode
, src1
), 0);
1140 if (GET_CODE (src2
) == SUBREG
1141 && (tem
= simplify_subreg (wmode
, src2
, mode
, 0)) != 0)
1143 else if (GET_MODE (src2
) != VOIDmode
)
1144 src2
= gen_rtx_SUBREG (wmode
, force_reg (mode
, src2
), 0);
1147 /* Emit the instruction. */
1148 op
= gen_rtx_SET (VOIDmode
, dst
, gen_rtx_fmt_ee (code
, wmode
, src1
, src2
));
1149 clob
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
1150 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, op
, clob
)));
1152 /* Fix up the destination if needed. */
1153 if (dst
!= operands
[0])
1154 emit_move_insn (operands
[0], gen_lowpart (mode
, dst
));
1157 /* Check whether OPERANDS are OK for a logical operation (AND, IOR, XOR). */
1160 s390_logical_operator_ok_p (rtx
*operands
)
1162 /* If the destination operand is in memory, it needs to coincide
1163 with one of the source operands. After reload, it has to be
1164 the first source operand. */
1165 if (GET_CODE (operands
[0]) == MEM
)
1166 return rtx_equal_p (operands
[0], operands
[1])
1167 || (!reload_completed
&& rtx_equal_p (operands
[0], operands
[2]));
1172 /* Narrow logical operation CODE of memory operand MEMOP with immediate
1173 operand IMMOP to switch from SS to SI type instructions. */
1176 s390_narrow_logical_operator (enum rtx_code code
, rtx
*memop
, rtx
*immop
)
1178 int def
= code
== AND
? -1 : 0;
1182 gcc_assert (GET_CODE (*memop
) == MEM
);
1183 gcc_assert (!MEM_VOLATILE_P (*memop
));
1185 mask
= s390_extract_part (*immop
, QImode
, def
);
1186 part
= s390_single_part (*immop
, GET_MODE (*memop
), QImode
, def
);
1187 gcc_assert (part
>= 0);
1189 *memop
= adjust_address (*memop
, QImode
, part
);
1190 *immop
= gen_int_mode (mask
, QImode
);
1194 /* How to allocate a 'struct machine_function'. */
1196 static struct machine_function
*
1197 s390_init_machine_status (void)
1199 return ggc_alloc_cleared (sizeof (struct machine_function
));
1202 /* Change optimizations to be performed, depending on the
1205 LEVEL is the optimization level specified; 2 if `-O2' is
1206 specified, 1 if `-O' is specified, and 0 if neither is specified.
1208 SIZE is nonzero if `-Os' is specified and zero otherwise. */
1211 optimization_options (int level ATTRIBUTE_UNUSED
, int size ATTRIBUTE_UNUSED
)
1213 /* ??? There are apparently still problems with -fcaller-saves. */
1214 flag_caller_saves
= 0;
1216 /* By default, always emit DWARF-2 unwind info. This allows debugging
1217 without maintaining a stack frame back-chain. */
1218 flag_asynchronous_unwind_tables
= 1;
1220 /* Use MVCLE instructions to decrease code size if requested. */
1222 target_flags
|= MASK_MVCLE
;
1225 /* Return true if ARG is the name of a processor. Set *TYPE and *FLAGS
1226 to the associated processor_type and processor_flags if so. */
1229 s390_handle_arch_option (const char *arg
,
1230 enum processor_type
*type
,
1231 enum processor_flags
*flags
)
1235 const char *const name
; /* processor name or nickname. */
1236 const enum processor_type processor
;
1237 const enum processor_flags flags
;
1239 const processor_alias_table
[] =
1241 {"g5", PROCESSOR_9672_G5
, PF_IEEE_FLOAT
},
1242 {"g6", PROCESSOR_9672_G6
, PF_IEEE_FLOAT
},
1243 {"z900", PROCESSOR_2064_Z900
, PF_IEEE_FLOAT
| PF_ZARCH
},
1244 {"z990", PROCESSOR_2084_Z990
, PF_IEEE_FLOAT
| PF_ZARCH
1245 | PF_LONG_DISPLACEMENT
},
1246 {"z9-109", PROCESSOR_2094_Z9_109
, PF_IEEE_FLOAT
| PF_ZARCH
1247 | PF_LONG_DISPLACEMENT
| PF_EXTIMM
},
1251 for (i
= 0; i
< ARRAY_SIZE (processor_alias_table
); i
++)
1252 if (strcmp (arg
, processor_alias_table
[i
].name
) == 0)
1254 *type
= processor_alias_table
[i
].processor
;
1255 *flags
= processor_alias_table
[i
].flags
;
1261 /* Implement TARGET_HANDLE_OPTION. */
1264 s390_handle_option (size_t code
, const char *arg
, int value ATTRIBUTE_UNUSED
)
1269 return s390_handle_arch_option (arg
, &s390_arch
, &s390_arch_flags
);
1271 case OPT_mstack_guard_
:
1272 if (sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_stack_guard
) != 1)
1274 if (exact_log2 (s390_stack_guard
) == -1)
1275 error ("stack guard value must be an exact power of 2");
1278 case OPT_mstack_size_
:
1279 if (sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_stack_size
) != 1)
1281 if (exact_log2 (s390_stack_size
) == -1)
1282 error ("stack size must be an exact power of 2");
1286 return s390_handle_arch_option (arg
, &s390_tune
, &s390_tune_flags
);
1288 case OPT_mwarn_framesize_
:
1289 return sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_warn_framesize
) == 1;
1297 override_options (void)
1299 /* Acquire a unique set number for our register saves and restores. */
1300 s390_sr_alias_set
= new_alias_set ();
1302 /* Set up function hooks. */
1303 init_machine_status
= s390_init_machine_status
;
1305 /* Architecture mode defaults according to ABI. */
1306 if (!(target_flags_explicit
& MASK_ZARCH
))
1309 target_flags
|= MASK_ZARCH
;
1311 target_flags
&= ~MASK_ZARCH
;
1314 /* Determine processor architectural level. */
1315 if (!s390_arch_string
)
1317 s390_arch_string
= TARGET_ZARCH
? "z900" : "g5";
1318 s390_handle_arch_option (s390_arch_string
, &s390_arch
, &s390_arch_flags
);
1321 /* Determine processor to tune for. */
1322 if (s390_tune
== PROCESSOR_max
)
1324 s390_tune
= s390_arch
;
1325 s390_tune_flags
= s390_arch_flags
;
1328 /* Sanity checks. */
1329 if (TARGET_ZARCH
&& !(s390_arch_flags
& PF_ZARCH
))
1330 error ("z/Architecture mode not supported on %s", s390_arch_string
);
1331 if (TARGET_64BIT
&& !TARGET_ZARCH
)
1332 error ("64-bit ABI not supported in ESA/390 mode");
1334 /* Set processor cost function. */
1335 if (s390_tune
== PROCESSOR_2094_Z9_109
)
1336 s390_cost
= &z9_109_cost
;
1337 else if (s390_tune
== PROCESSOR_2084_Z990
)
1338 s390_cost
= &z990_cost
;
1340 s390_cost
= &z900_cost
;
1342 if (TARGET_BACKCHAIN
&& TARGET_PACKED_STACK
&& TARGET_HARD_FLOAT
)
1343 error ("-mbackchain -mpacked-stack -mhard-float are not supported "
1346 if (s390_stack_size
)
1348 if (!s390_stack_guard
)
1349 error ("-mstack-size implies use of -mstack-guard");
1350 else if (s390_stack_guard
>= s390_stack_size
)
1351 error ("stack size must be greater than the stack guard value");
1353 else if (s390_stack_guard
)
1354 error ("-mstack-guard implies use of -mstack-size");
1357 /* Map for smallest class containing reg regno. */
1359 const enum reg_class regclass_map
[FIRST_PSEUDO_REGISTER
] =
1360 { GENERAL_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1361 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1362 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1363 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1364 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1365 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1366 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1367 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1368 ADDR_REGS
, CC_REGS
, ADDR_REGS
, ADDR_REGS
,
1369 ACCESS_REGS
, ACCESS_REGS
1372 /* Return attribute type of insn. */
1374 static enum attr_type
1375 s390_safe_attr_type (rtx insn
)
1377 if (recog_memoized (insn
) >= 0)
1378 return get_attr_type (insn
);
1383 /* Return true if DISP is a valid short displacement. */
1386 s390_short_displacement (rtx disp
)
1388 /* No displacement is OK. */
1392 /* Integer displacement in range. */
1393 if (GET_CODE (disp
) == CONST_INT
)
1394 return INTVAL (disp
) >= 0 && INTVAL (disp
) < 4096;
1396 /* GOT offset is not OK, the GOT can be large. */
1397 if (GET_CODE (disp
) == CONST
1398 && GET_CODE (XEXP (disp
, 0)) == UNSPEC
1399 && (XINT (XEXP (disp
, 0), 1) == UNSPEC_GOT
1400 || XINT (XEXP (disp
, 0), 1) == UNSPEC_GOTNTPOFF
))
1403 /* All other symbolic constants are literal pool references,
1404 which are OK as the literal pool must be small. */
1405 if (GET_CODE (disp
) == CONST
)
1411 /* Decompose a RTL expression ADDR for a memory address into
1412 its components, returned in OUT.
1414 Returns false if ADDR is not a valid memory address, true
1415 otherwise. If OUT is NULL, don't return the components,
1416 but check for validity only.
1418 Note: Only addresses in canonical form are recognized.
1419 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
1420 canonical form so that they will be recognized. */
1423 s390_decompose_address (rtx addr
, struct s390_address
*out
)
1425 HOST_WIDE_INT offset
= 0;
1426 rtx base
= NULL_RTX
;
1427 rtx indx
= NULL_RTX
;
1428 rtx disp
= NULL_RTX
;
1430 bool pointer
= false;
1431 bool base_ptr
= false;
1432 bool indx_ptr
= false;
1434 /* Decompose address into base + index + displacement. */
1436 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == UNSPEC
)
1439 else if (GET_CODE (addr
) == PLUS
)
1441 rtx op0
= XEXP (addr
, 0);
1442 rtx op1
= XEXP (addr
, 1);
1443 enum rtx_code code0
= GET_CODE (op0
);
1444 enum rtx_code code1
= GET_CODE (op1
);
1446 if (code0
== REG
|| code0
== UNSPEC
)
1448 if (code1
== REG
|| code1
== UNSPEC
)
1450 indx
= op0
; /* index + base */
1456 base
= op0
; /* base + displacement */
1461 else if (code0
== PLUS
)
1463 indx
= XEXP (op0
, 0); /* index + base + disp */
1464 base
= XEXP (op0
, 1);
1475 disp
= addr
; /* displacement */
1477 /* Extract integer part of displacement. */
1481 if (GET_CODE (disp
) == CONST_INT
)
1483 offset
= INTVAL (disp
);
1486 else if (GET_CODE (disp
) == CONST
1487 && GET_CODE (XEXP (disp
, 0)) == PLUS
1488 && GET_CODE (XEXP (XEXP (disp
, 0), 1)) == CONST_INT
)
1490 offset
= INTVAL (XEXP (XEXP (disp
, 0), 1));
1491 disp
= XEXP (XEXP (disp
, 0), 0);
1495 /* Strip off CONST here to avoid special case tests later. */
1496 if (disp
&& GET_CODE (disp
) == CONST
)
1497 disp
= XEXP (disp
, 0);
1499 /* We can convert literal pool addresses to
1500 displacements by basing them off the base register. */
1501 if (disp
&& GET_CODE (disp
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (disp
))
1503 /* Either base or index must be free to hold the base register. */
1505 base
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1507 indx
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1511 /* Mark up the displacement. */
1512 disp
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, disp
),
1513 UNSPEC_LTREL_OFFSET
);
1516 /* Validate base register. */
1519 if (GET_CODE (base
) == UNSPEC
)
1520 switch (XINT (base
, 1))
1524 disp
= gen_rtx_UNSPEC (Pmode
,
1525 gen_rtvec (1, XVECEXP (base
, 0, 0)),
1526 UNSPEC_LTREL_OFFSET
);
1530 base
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1533 case UNSPEC_LTREL_BASE
:
1534 base
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1541 if (GET_CODE (base
) != REG
|| GET_MODE (base
) != Pmode
)
1544 if (REGNO (base
) == BASE_REGNUM
1545 || REGNO (base
) == STACK_POINTER_REGNUM
1546 || REGNO (base
) == FRAME_POINTER_REGNUM
1547 || ((reload_completed
|| reload_in_progress
)
1548 && frame_pointer_needed
1549 && REGNO (base
) == HARD_FRAME_POINTER_REGNUM
)
1550 || REGNO (base
) == ARG_POINTER_REGNUM
1552 && REGNO (base
) == PIC_OFFSET_TABLE_REGNUM
))
1553 pointer
= base_ptr
= true;
1556 /* Validate index register. */
1559 if (GET_CODE (indx
) == UNSPEC
)
1560 switch (XINT (indx
, 1))
1564 disp
= gen_rtx_UNSPEC (Pmode
,
1565 gen_rtvec (1, XVECEXP (indx
, 0, 0)),
1566 UNSPEC_LTREL_OFFSET
);
1570 indx
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1573 case UNSPEC_LTREL_BASE
:
1574 indx
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1581 if (GET_CODE (indx
) != REG
|| GET_MODE (indx
) != Pmode
)
1584 if (REGNO (indx
) == BASE_REGNUM
1585 || REGNO (indx
) == STACK_POINTER_REGNUM
1586 || REGNO (indx
) == FRAME_POINTER_REGNUM
1587 || ((reload_completed
|| reload_in_progress
)
1588 && frame_pointer_needed
1589 && REGNO (indx
) == HARD_FRAME_POINTER_REGNUM
)
1590 || REGNO (indx
) == ARG_POINTER_REGNUM
1592 && REGNO (indx
) == PIC_OFFSET_TABLE_REGNUM
))
1593 pointer
= indx_ptr
= true;
1596 /* Prefer to use pointer as base, not index. */
1597 if (base
&& indx
&& !base_ptr
1598 && (indx_ptr
|| (!REG_POINTER (base
) && REG_POINTER (indx
))))
1605 /* Validate displacement. */
1608 /* If virtual registers are involved, the displacement will change later
1609 anyway as the virtual registers get eliminated. This could make a
1610 valid displacement invalid, but it is more likely to make an invalid
1611 displacement valid, because we sometimes access the register save area
1612 via negative offsets to one of those registers.
1613 Thus we don't check the displacement for validity here. If after
1614 elimination the displacement turns out to be invalid after all,
1615 this is fixed up by reload in any case. */
1616 if (base
!= arg_pointer_rtx
1617 && indx
!= arg_pointer_rtx
1618 && base
!= return_address_pointer_rtx
1619 && indx
!= return_address_pointer_rtx
1620 && base
!= frame_pointer_rtx
1621 && indx
!= frame_pointer_rtx
1622 && base
!= virtual_stack_vars_rtx
1623 && indx
!= virtual_stack_vars_rtx
)
1624 if (!DISP_IN_RANGE (offset
))
1629 /* All the special cases are pointers. */
1632 /* In the small-PIC case, the linker converts @GOT
1633 and @GOTNTPOFF offsets to possible displacements. */
1634 if (GET_CODE (disp
) == UNSPEC
1635 && (XINT (disp
, 1) == UNSPEC_GOT
1636 || XINT (disp
, 1) == UNSPEC_GOTNTPOFF
)
1643 /* Accept chunkified literal pool symbol references. */
1644 else if (GET_CODE (disp
) == MINUS
1645 && GET_CODE (XEXP (disp
, 0)) == LABEL_REF
1646 && GET_CODE (XEXP (disp
, 1)) == LABEL_REF
)
1651 /* Accept literal pool references. */
1652 else if (GET_CODE (disp
) == UNSPEC
1653 && XINT (disp
, 1) == UNSPEC_LTREL_OFFSET
)
1655 orig_disp
= gen_rtx_CONST (Pmode
, disp
);
1658 /* If we have an offset, make sure it does not
1659 exceed the size of the constant pool entry. */
1660 rtx sym
= XVECEXP (disp
, 0, 0);
1661 if (offset
>= GET_MODE_SIZE (get_pool_mode (sym
)))
1664 orig_disp
= plus_constant (orig_disp
, offset
);
1679 out
->disp
= orig_disp
;
1680 out
->pointer
= pointer
;
1686 /* Return true if CODE is a valid address without index. */
1689 s390_legitimate_address_without_index_p (rtx op
)
1691 struct s390_address addr
;
1693 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1701 /* Return 1 if OP is a valid operand for a C constraint, 0 else. */
1704 s390_extra_constraint_str (rtx op
, int c
, const char * str
)
1706 struct s390_address addr
;
1708 gcc_assert (c
== str
[0]);
1710 /* Check for offsettable variants of memory constraints. */
1713 /* Only accept non-volatile MEMs. */
1714 if (!MEM_P (op
) || MEM_VOLATILE_P (op
))
1717 if ((reload_completed
|| reload_in_progress
)
1718 ? !offsettable_memref_p (op
)
1719 : !offsettable_nonstrict_memref_p (op
))
1725 /* Check for non-literal-pool variants of memory constraints. */
1728 if (GET_CODE (op
) != MEM
)
1730 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1732 if (addr
.base
&& REG_P (addr
.base
) && REGNO (addr
.base
) == BASE_REGNUM
)
1734 if (addr
.indx
&& REG_P (addr
.indx
) && REGNO (addr
.indx
) == BASE_REGNUM
)
1743 if (GET_CODE (op
) != MEM
)
1745 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1750 if (TARGET_LONG_DISPLACEMENT
)
1752 if (!s390_short_displacement (addr
.disp
))
1758 if (GET_CODE (op
) != MEM
)
1761 if (TARGET_LONG_DISPLACEMENT
)
1763 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1765 if (!s390_short_displacement (addr
.disp
))
1771 if (!TARGET_LONG_DISPLACEMENT
)
1773 if (GET_CODE (op
) != MEM
)
1775 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1779 if (s390_short_displacement (addr
.disp
))
1784 if (!TARGET_LONG_DISPLACEMENT
)
1786 if (GET_CODE (op
) != MEM
)
1788 /* Any invalid address here will be fixed up by reload,
1789 so accept it for the most generic constraint. */
1790 if (s390_decompose_address (XEXP (op
, 0), &addr
)
1791 && s390_short_displacement (addr
.disp
))
1796 if (TARGET_LONG_DISPLACEMENT
)
1798 if (!s390_decompose_address (op
, &addr
))
1800 if (!s390_short_displacement (addr
.disp
))
1806 if (!TARGET_LONG_DISPLACEMENT
)
1808 /* Any invalid address here will be fixed up by reload,
1809 so accept it for the most generic constraint. */
1810 if (s390_decompose_address (op
, &addr
)
1811 && s390_short_displacement (addr
.disp
))
1816 return shift_count_operand (op
, VOIDmode
);
1825 /* Return true if VALUE matches the constraint STR. */
1828 s390_const_double_ok_for_constraint_p (rtx value
,
1832 gcc_assert (c
== str
[0]);
1837 /* The floating point zero constant. */
1838 return (GET_MODE_CLASS (GET_MODE (value
)) == MODE_FLOAT
1839 && value
== CONST0_RTX (GET_MODE (value
)));
1846 /* Return true if VALUE matches the constraint STR. */
1849 s390_const_ok_for_constraint_p (HOST_WIDE_INT value
,
1853 enum machine_mode mode
, part_mode
;
1855 int part
, part_goal
;
1857 gcc_assert (c
== str
[0]);
1862 return (unsigned int)value
< 256;
1865 return (unsigned int)value
< 4096;
1868 return value
>= -32768 && value
< 32768;
1871 return (TARGET_LONG_DISPLACEMENT
?
1872 (value
>= -524288 && value
<= 524287)
1873 : (value
>= 0 && value
<= 4095));
1875 return value
== 2147483647;
1881 part_goal
= str
[1] - '0';
1885 case 'Q': part_mode
= QImode
; break;
1886 case 'H': part_mode
= HImode
; break;
1887 case 'S': part_mode
= SImode
; break;
1893 case 'H': mode
= HImode
; break;
1894 case 'S': mode
= SImode
; break;
1895 case 'D': mode
= DImode
; break;
1901 case '0': def
= 0; break;
1902 case 'F': def
= -1; break;
1906 if (GET_MODE_SIZE (mode
) <= GET_MODE_SIZE (part_mode
))
1909 part
= s390_single_part (GEN_INT (value
), mode
, part_mode
, def
);
1912 if (part_goal
!= -1 && part_goal
!= part
)
1924 return trunc_int_for_mode (value
, SImode
) == value
;
1928 || s390_single_part (GEN_INT (value
), DImode
, SImode
, 0) == 1;
1932 || s390_single_part (GEN_INT (value
), DImode
, SImode
, -1) == 1;
1940 return legitimate_reload_constant_p (GEN_INT (value
));
1949 /* Compute a (partial) cost for rtx X. Return true if the complete
1950 cost has been computed, and false if subexpressions should be
1951 scanned. In either case, *TOTAL contains the cost result.
1952 CODE contains GET_CODE (x), OUTER_CODE contains the code
1953 of the superexpression of x. */
1956 s390_rtx_costs (rtx x
, int code
, int outer_code
, int *total
)
1979 *total
= COSTS_N_INSNS (1);
1984 /* Check for multiply and add. */
1985 if ((GET_MODE (x
) == DFmode
|| GET_MODE (x
) == SFmode
)
1986 && GET_CODE (XEXP (x
, 0)) == MULT
1987 && TARGET_HARD_FLOAT
&& TARGET_IEEE_FLOAT
&& TARGET_FUSED_MADD
)
1989 /* This is the multiply and add case. */
1990 if (GET_MODE (x
) == DFmode
)
1991 *total
= s390_cost
->madbr
;
1993 *total
= s390_cost
->maebr
;
1994 *total
+= rtx_cost (XEXP (XEXP (x
, 0), 0), MULT
)
1995 + rtx_cost (XEXP (XEXP (x
, 0), 1), MULT
)
1996 + rtx_cost (XEXP (x
, 1), code
);
1997 return true; /* Do not do an additional recursive descent. */
1999 *total
= COSTS_N_INSNS (1);
2003 switch (GET_MODE (x
))
2007 rtx left
= XEXP (x
, 0);
2008 rtx right
= XEXP (x
, 1);
2009 if (GET_CODE (right
) == CONST_INT
2010 && CONST_OK_FOR_K (INTVAL (right
)))
2011 *total
= s390_cost
->mhi
;
2012 else if (GET_CODE (left
) == SIGN_EXTEND
)
2013 *total
= s390_cost
->mh
;
2015 *total
= s390_cost
->ms
; /* msr, ms, msy */
2020 rtx left
= XEXP (x
, 0);
2021 rtx right
= XEXP (x
, 1);
2024 if (GET_CODE (right
) == CONST_INT
2025 && CONST_OK_FOR_K (INTVAL (right
)))
2026 *total
= s390_cost
->mghi
;
2027 else if (GET_CODE (left
) == SIGN_EXTEND
)
2028 *total
= s390_cost
->msgf
;
2030 *total
= s390_cost
->msg
; /* msgr, msg */
2032 else /* TARGET_31BIT */
2034 if (GET_CODE (left
) == SIGN_EXTEND
2035 && GET_CODE (right
) == SIGN_EXTEND
)
2036 /* mulsidi case: mr, m */
2037 *total
= s390_cost
->m
;
2038 else if (GET_CODE (left
) == ZERO_EXTEND
2039 && GET_CODE (right
) == ZERO_EXTEND
2040 && TARGET_CPU_ZARCH
)
2041 /* umulsidi case: ml, mlr */
2042 *total
= s390_cost
->ml
;
2044 /* Complex calculation is required. */
2045 *total
= COSTS_N_INSNS (40);
2051 *total
= s390_cost
->mult_df
;
2060 if (GET_MODE (x
) == TImode
) /* 128 bit division */
2061 *total
= s390_cost
->dlgr
;
2062 else if (GET_MODE (x
) == DImode
)
2064 rtx right
= XEXP (x
, 1);
2065 if (GET_CODE (right
) == ZERO_EXTEND
) /* 64 by 32 bit division */
2066 *total
= s390_cost
->dlr
;
2067 else /* 64 by 64 bit division */
2068 *total
= s390_cost
->dlgr
;
2070 else if (GET_MODE (x
) == SImode
) /* 32 bit division */
2071 *total
= s390_cost
->dlr
;
2076 if (GET_MODE (x
) == DImode
)
2078 rtx right
= XEXP (x
, 1);
2079 if (GET_CODE (right
) == ZERO_EXTEND
) /* 64 by 32 bit division */
2081 *total
= s390_cost
->dsgfr
;
2083 *total
= s390_cost
->dr
;
2084 else /* 64 by 64 bit division */
2085 *total
= s390_cost
->dsgr
;
2087 else if (GET_MODE (x
) == SImode
) /* 32 bit division */
2088 *total
= s390_cost
->dlr
;
2089 else if (GET_MODE (x
) == SFmode
)
2091 if (TARGET_IEEE_FLOAT
)
2092 *total
= s390_cost
->debr
;
2093 else /* TARGET_IBM_FLOAT */
2094 *total
= s390_cost
->der
;
2096 else if (GET_MODE (x
) == DFmode
)
2098 if (TARGET_IEEE_FLOAT
)
2099 *total
= s390_cost
->ddbr
;
2100 else /* TARGET_IBM_FLOAT */
2101 *total
= s390_cost
->ddr
;
2106 if (GET_MODE (x
) == SFmode
)
2107 *total
= s390_cost
->sqebr
;
2109 *total
= s390_cost
->sqdbr
;
2114 if (outer_code
== MULT
|| outer_code
== DIV
|| outer_code
== MOD
2115 || outer_code
== PLUS
|| outer_code
== MINUS
2116 || outer_code
== COMPARE
)
2121 *total
= COSTS_N_INSNS (1);
2122 if (GET_CODE (XEXP (x
, 0)) == AND
2123 && GET_CODE (XEXP (x
, 1)) == CONST_INT
2124 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
)
2126 rtx op0
= XEXP (XEXP (x
, 0), 0);
2127 rtx op1
= XEXP (XEXP (x
, 0), 1);
2128 rtx op2
= XEXP (x
, 1);
2130 if (memory_operand (op0
, GET_MODE (op0
))
2131 && s390_tm_ccmode (op1
, op2
, 0) != VOIDmode
)
2133 if (register_operand (op0
, GET_MODE (op0
))
2134 && s390_tm_ccmode (op1
, op2
, 1) != VOIDmode
)
2144 /* Return the cost of an address rtx ADDR. */
2147 s390_address_cost (rtx addr
)
2149 struct s390_address ad
;
2150 if (!s390_decompose_address (addr
, &ad
))
2153 return ad
.indx
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
2156 /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
2157 otherwise return 0. */
2160 tls_symbolic_operand (rtx op
)
2162 if (GET_CODE (op
) != SYMBOL_REF
)
2164 return SYMBOL_REF_TLS_MODEL (op
);
2167 /* Split DImode access register reference REG (on 64-bit) into its constituent
2168 low and high parts, and store them into LO and HI. Note that gen_lowpart/
2169 gen_highpart cannot be used as they assume all registers are word-sized,
2170 while our access registers have only half that size. */
2173 s390_split_access_reg (rtx reg
, rtx
*lo
, rtx
*hi
)
2175 gcc_assert (TARGET_64BIT
);
2176 gcc_assert (ACCESS_REG_P (reg
));
2177 gcc_assert (GET_MODE (reg
) == DImode
);
2178 gcc_assert (!(REGNO (reg
) & 1));
2180 *lo
= gen_rtx_REG (SImode
, REGNO (reg
) + 1);
2181 *hi
= gen_rtx_REG (SImode
, REGNO (reg
));
2184 /* Return true if OP contains a symbol reference */
2187 symbolic_reference_mentioned_p (rtx op
)
2192 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
2195 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
2196 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
2202 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
2203 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
2207 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
2214 /* Return true if OP contains a reference to a thread-local symbol. */
2217 tls_symbolic_reference_mentioned_p (rtx op
)
2222 if (GET_CODE (op
) == SYMBOL_REF
)
2223 return tls_symbolic_operand (op
);
2225 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
2226 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
2232 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
2233 if (tls_symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
2237 else if (fmt
[i
] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op
, i
)))
2245 /* Return true if OP is a legitimate general operand when
2246 generating PIC code. It is given that flag_pic is on
2247 and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2250 legitimate_pic_operand_p (rtx op
)
2252 /* Accept all non-symbolic constants. */
2253 if (!SYMBOLIC_CONST (op
))
2256 /* Reject everything else; must be handled
2257 via emit_symbolic_move. */
2261 /* Returns true if the constant value OP is a legitimate general operand.
2262 It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2265 legitimate_constant_p (rtx op
)
2267 /* Accept all non-symbolic constants. */
2268 if (!SYMBOLIC_CONST (op
))
2271 /* Accept immediate LARL operands. */
2272 if (TARGET_CPU_ZARCH
&& larl_operand (op
, VOIDmode
))
2275 /* Thread-local symbols are never legal constants. This is
2276 so that emit_call knows that computing such addresses
2277 might require a function call. */
2278 if (TLS_SYMBOLIC_CONST (op
))
2281 /* In the PIC case, symbolic constants must *not* be
2282 forced into the literal pool. We accept them here,
2283 so that they will be handled by emit_symbolic_move. */
2287 /* All remaining non-PIC symbolic constants are
2288 forced into the literal pool. */
2292 /* Determine if it's legal to put X into the constant pool. This
2293 is not possible if X contains the address of a symbol that is
2294 not constant (TLS) or not known at final link time (PIC). */
2297 s390_cannot_force_const_mem (rtx x
)
2299 switch (GET_CODE (x
))
2303 /* Accept all non-symbolic constants. */
2307 /* Labels are OK iff we are non-PIC. */
2308 return flag_pic
!= 0;
2311 /* 'Naked' TLS symbol references are never OK,
2312 non-TLS symbols are OK iff we are non-PIC. */
2313 if (tls_symbolic_operand (x
))
2316 return flag_pic
!= 0;
2319 return s390_cannot_force_const_mem (XEXP (x
, 0));
2322 return s390_cannot_force_const_mem (XEXP (x
, 0))
2323 || s390_cannot_force_const_mem (XEXP (x
, 1));
2326 switch (XINT (x
, 1))
2328 /* Only lt-relative or GOT-relative UNSPECs are OK. */
2329 case UNSPEC_LTREL_OFFSET
:
2337 case UNSPEC_GOTNTPOFF
:
2338 case UNSPEC_INDNTPOFF
:
2341 /* If the literal pool shares the code section, be put
2342 execute template placeholders into the pool as well. */
2344 return TARGET_CPU_ZARCH
;
2356 /* Returns true if the constant value OP is a legitimate general
2357 operand during and after reload. The difference to
2358 legitimate_constant_p is that this function will not accept
2359 a constant that would need to be forced to the literal pool
2360 before it can be used as operand. */
2363 legitimate_reload_constant_p (rtx op
)
2365 /* Accept la(y) operands. */
2366 if (GET_CODE (op
) == CONST_INT
2367 && DISP_IN_RANGE (INTVAL (op
)))
2370 /* Accept l(g)hi/l(g)fi operands. */
2371 if (GET_CODE (op
) == CONST_INT
2372 && (CONST_OK_FOR_K (INTVAL (op
)) || CONST_OK_FOR_Os (INTVAL (op
))))
2375 /* Accept lliXX operands. */
2377 && GET_CODE (op
) == CONST_INT
2378 && trunc_int_for_mode (INTVAL (op
), word_mode
) == INTVAL (op
)
2379 && s390_single_part (op
, word_mode
, HImode
, 0) >= 0)
2383 && GET_CODE (op
) == CONST_INT
2384 && trunc_int_for_mode (INTVAL (op
), word_mode
) == INTVAL (op
)
2385 && s390_single_part (op
, word_mode
, SImode
, 0) >= 0)
2388 /* Accept larl operands. */
2389 if (TARGET_CPU_ZARCH
2390 && larl_operand (op
, VOIDmode
))
2393 /* Accept lzXX operands. */
2394 if (GET_CODE (op
) == CONST_DOUBLE
2395 && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op
, 'G', "G"))
2398 /* Accept double-word operands that can be split. */
2399 if (GET_CODE (op
) == CONST_INT
2400 && trunc_int_for_mode (INTVAL (op
), word_mode
) != INTVAL (op
))
2402 enum machine_mode dword_mode
= word_mode
== SImode
? DImode
: TImode
;
2403 rtx hi
= operand_subword (op
, 0, 0, dword_mode
);
2404 rtx lo
= operand_subword (op
, 1, 0, dword_mode
);
2405 return legitimate_reload_constant_p (hi
)
2406 && legitimate_reload_constant_p (lo
);
2409 /* Everything else cannot be handled without reload. */
2413 /* Given an rtx OP being reloaded into a reg required to be in class CLASS,
2414 return the class of reg to actually use. */
2417 s390_preferred_reload_class (rtx op
, enum reg_class
class)
2419 switch (GET_CODE (op
))
2421 /* Constants we cannot reload must be forced into the
2426 if (legitimate_reload_constant_p (op
))
2431 /* If a symbolic constant or a PLUS is reloaded,
2432 it is most likely being used as an address, so
2433 prefer ADDR_REGS. If 'class' is not a superset
2434 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
2439 if (reg_class_subset_p (ADDR_REGS
, class))
2451 /* Return the register class of a scratch register needed to
2452 load IN into a register of class CLASS in MODE.
2454 We need a temporary when loading a PLUS expression which
2455 is not a legitimate operand of the LOAD ADDRESS instruction. */
2458 s390_secondary_input_reload_class (enum reg_class
class,
2459 enum machine_mode mode
, rtx in
)
2461 if (s390_plus_operand (in
, mode
))
2464 if (reg_classes_intersect_p (CC_REGS
, class))
2465 return GENERAL_REGS
;
2470 /* Return the register class of a scratch register needed to
2471 store a register of class CLASS in MODE into OUT:
2473 We need a temporary when storing a double-word to a
2474 non-offsettable memory address. */
2477 s390_secondary_output_reload_class (enum reg_class
class,
2478 enum machine_mode mode
, rtx out
)
2480 if ((TARGET_64BIT
? mode
== TImode
2481 : (mode
== DImode
|| mode
== DFmode
))
2482 && reg_classes_intersect_p (GENERAL_REGS
, class)
2483 && GET_CODE (out
) == MEM
2484 && GET_CODE (XEXP (out
, 0)) == PLUS
2485 && GET_CODE (XEXP (XEXP (out
, 0), 0)) == PLUS
2486 && GET_CODE (XEXP (XEXP (out
, 0), 1)) == CONST_INT
2487 && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (out
, 0), 1))
2488 + GET_MODE_SIZE (mode
) - 1))
2491 if (reg_classes_intersect_p (CC_REGS
, class))
2492 return GENERAL_REGS
;
2497 /* Generate code to load SRC, which is PLUS that is not a
2498 legitimate operand for the LA instruction, into TARGET.
2499 SCRATCH may be used as scratch register. */
2502 s390_expand_plus_operand (rtx target
, rtx src
,
2506 struct s390_address ad
;
2508 /* src must be a PLUS; get its two operands. */
2509 gcc_assert (GET_CODE (src
) == PLUS
);
2510 gcc_assert (GET_MODE (src
) == Pmode
);
2512 /* Check if any of the two operands is already scheduled
2513 for replacement by reload. This can happen e.g. when
2514 float registers occur in an address. */
2515 sum1
= find_replacement (&XEXP (src
, 0));
2516 sum2
= find_replacement (&XEXP (src
, 1));
2517 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
2519 /* If the address is already strictly valid, there's nothing to do. */
2520 if (!s390_decompose_address (src
, &ad
)
2521 || (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
2522 || (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
)))
2524 /* Otherwise, one of the operands cannot be an address register;
2525 we reload its value into the scratch register. */
2526 if (true_regnum (sum1
) < 1 || true_regnum (sum1
) > 15)
2528 emit_move_insn (scratch
, sum1
);
2531 if (true_regnum (sum2
) < 1 || true_regnum (sum2
) > 15)
2533 emit_move_insn (scratch
, sum2
);
2537 /* According to the way these invalid addresses are generated
2538 in reload.c, it should never happen (at least on s390) that
2539 *neither* of the PLUS components, after find_replacements
2540 was applied, is an address register. */
2541 if (sum1
== scratch
&& sum2
== scratch
)
2547 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
2550 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
2551 is only ever performed on addresses, so we can mark the
2552 sum as legitimate for LA in any case. */
2553 s390_load_address (target
, src
);
2557 /* Return true if ADDR is a valid memory address.
2558 STRICT specifies whether strict register checking applies. */
2561 legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED
,
2562 rtx addr
, int strict
)
2564 struct s390_address ad
;
2565 if (!s390_decompose_address (addr
, &ad
))
2570 if (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
2572 if (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
))
2577 if (ad
.base
&& !REG_OK_FOR_BASE_NONSTRICT_P (ad
.base
))
2579 if (ad
.indx
&& !REG_OK_FOR_INDEX_NONSTRICT_P (ad
.indx
))
2586 /* Return true if OP is a valid operand for the LA instruction.
2587 In 31-bit, we need to prove that the result is used as an
2588 address, as LA performs only a 31-bit addition. */
2591 legitimate_la_operand_p (rtx op
)
2593 struct s390_address addr
;
2594 if (!s390_decompose_address (op
, &addr
))
2597 return (TARGET_64BIT
|| addr
.pointer
);
2600 /* Return true if it is valid *and* preferable to use LA to
2601 compute the sum of OP1 and OP2. */
2604 preferred_la_operand_p (rtx op1
, rtx op2
)
2606 struct s390_address addr
;
2608 if (op2
!= const0_rtx
)
2609 op1
= gen_rtx_PLUS (Pmode
, op1
, op2
);
2611 if (!s390_decompose_address (op1
, &addr
))
2613 if (addr
.base
&& !REG_OK_FOR_BASE_STRICT_P (addr
.base
))
2615 if (addr
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (addr
.indx
))
2618 if (!TARGET_64BIT
&& !addr
.pointer
)
2624 if ((addr
.base
&& REG_P (addr
.base
) && REG_POINTER (addr
.base
))
2625 || (addr
.indx
&& REG_P (addr
.indx
) && REG_POINTER (addr
.indx
)))
2631 /* Emit a forced load-address operation to load SRC into DST.
2632 This will use the LOAD ADDRESS instruction even in situations
2633 where legitimate_la_operand_p (SRC) returns false. */
2636 s390_load_address (rtx dst
, rtx src
)
2639 emit_move_insn (dst
, src
);
2641 emit_insn (gen_force_la_31 (dst
, src
));
2644 /* Return a legitimate reference for ORIG (an address) using the
2645 register REG. If REG is 0, a new pseudo is generated.
2647 There are two types of references that must be handled:
2649 1. Global data references must load the address from the GOT, via
2650 the PIC reg. An insn is emitted to do this load, and the reg is
2653 2. Static data references, constant pool addresses, and code labels
2654 compute the address as an offset from the GOT, whose base is in
2655 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
2656 differentiate them from global data objects. The returned
2657 address is the PIC reg + an unspec constant.
2659 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2660 reg also appears in the address. */
2663 legitimize_pic_address (rtx orig
, rtx reg
)
2669 if (GET_CODE (addr
) == LABEL_REF
2670 || (GET_CODE (addr
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (addr
)))
2672 /* This is a local symbol. */
2673 if (TARGET_CPU_ZARCH
&& larl_operand (addr
, VOIDmode
))
2675 /* Access local symbols PC-relative via LARL.
2676 This is the same as in the non-PIC case, so it is
2677 handled automatically ... */
2681 /* Access local symbols relative to the GOT. */
2683 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2685 if (reload_in_progress
|| reload_completed
)
2686 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2688 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTOFF
);
2689 addr
= gen_rtx_CONST (Pmode
, addr
);
2690 addr
= force_const_mem (Pmode
, addr
);
2691 emit_move_insn (temp
, addr
);
2693 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2696 s390_load_address (reg
, new);
2701 else if (GET_CODE (addr
) == SYMBOL_REF
)
2704 reg
= gen_reg_rtx (Pmode
);
2708 /* Assume GOT offset < 4k. This is handled the same way
2709 in both 31- and 64-bit code (@GOT). */
2711 if (reload_in_progress
|| reload_completed
)
2712 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2714 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
2715 new = gen_rtx_CONST (Pmode
, new);
2716 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new);
2717 new = gen_const_mem (Pmode
, new);
2718 emit_move_insn (reg
, new);
2721 else if (TARGET_CPU_ZARCH
)
2723 /* If the GOT offset might be >= 4k, we determine the position
2724 of the GOT entry via a PC-relative LARL (@GOTENT). */
2726 rtx temp
= gen_reg_rtx (Pmode
);
2728 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTENT
);
2729 new = gen_rtx_CONST (Pmode
, new);
2730 emit_move_insn (temp
, new);
2732 new = gen_const_mem (Pmode
, temp
);
2733 emit_move_insn (reg
, new);
2738 /* If the GOT offset might be >= 4k, we have to load it
2739 from the literal pool (@GOT). */
2741 rtx temp
= gen_reg_rtx (Pmode
);
2743 if (reload_in_progress
|| reload_completed
)
2744 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2746 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
2747 addr
= gen_rtx_CONST (Pmode
, addr
);
2748 addr
= force_const_mem (Pmode
, addr
);
2749 emit_move_insn (temp
, addr
);
2751 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2752 new = gen_const_mem (Pmode
, new);
2753 emit_move_insn (reg
, new);
2759 if (GET_CODE (addr
) == CONST
)
2761 addr
= XEXP (addr
, 0);
2762 if (GET_CODE (addr
) == UNSPEC
)
2764 gcc_assert (XVECLEN (addr
, 0) == 1);
2765 switch (XINT (addr
, 1))
2767 /* If someone moved a GOT-relative UNSPEC
2768 out of the literal pool, force them back in. */
2771 new = force_const_mem (Pmode
, orig
);
2774 /* @GOT is OK as is if small. */
2777 new = force_const_mem (Pmode
, orig
);
2780 /* @GOTENT is OK as is. */
2784 /* @PLT is OK as is on 64-bit, must be converted to
2785 GOT-relative @PLTOFF on 31-bit. */
2787 if (!TARGET_CPU_ZARCH
)
2789 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2791 if (reload_in_progress
|| reload_completed
)
2792 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2794 addr
= XVECEXP (addr
, 0, 0);
2795 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
),
2797 addr
= gen_rtx_CONST (Pmode
, addr
);
2798 addr
= force_const_mem (Pmode
, addr
);
2799 emit_move_insn (temp
, addr
);
2801 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2804 s390_load_address (reg
, new);
2810 /* Everything else cannot happen. */
2816 gcc_assert (GET_CODE (addr
) == PLUS
);
2818 if (GET_CODE (addr
) == PLUS
)
2820 rtx op0
= XEXP (addr
, 0), op1
= XEXP (addr
, 1);
2821 /* Check first to see if this is a constant offset
2822 from a local symbol reference. */
2823 if ((GET_CODE (op0
) == LABEL_REF
2824 || (GET_CODE (op0
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (op0
)))
2825 && GET_CODE (op1
) == CONST_INT
)
2827 if (TARGET_CPU_ZARCH
&& larl_operand (op0
, VOIDmode
))
2829 if (INTVAL (op1
) & 1)
2831 /* LARL can't handle odd offsets, so emit a
2832 pair of LARL and LA. */
2833 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2835 if (!DISP_IN_RANGE (INTVAL (op1
)))
2837 int even
= INTVAL (op1
) - 1;
2838 op0
= gen_rtx_PLUS (Pmode
, op0
, GEN_INT (even
));
2839 op0
= gen_rtx_CONST (Pmode
, op0
);
2843 emit_move_insn (temp
, op0
);
2844 new = gen_rtx_PLUS (Pmode
, temp
, op1
);
2848 s390_load_address (reg
, new);
2854 /* If the offset is even, we can just use LARL.
2855 This will happen automatically. */
2860 /* Access local symbols relative to the GOT. */
2862 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2864 if (reload_in_progress
|| reload_completed
)
2865 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2867 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op0
),
2869 addr
= gen_rtx_PLUS (Pmode
, addr
, op1
);
2870 addr
= gen_rtx_CONST (Pmode
, addr
);
2871 addr
= force_const_mem (Pmode
, addr
);
2872 emit_move_insn (temp
, addr
);
2874 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2877 s390_load_address (reg
, new);
2883 /* Now, check whether it is a GOT relative symbol plus offset
2884 that was pulled out of the literal pool. Force it back in. */
2886 else if (GET_CODE (op0
) == UNSPEC
2887 && GET_CODE (op1
) == CONST_INT
2888 && XINT (op0
, 1) == UNSPEC_GOTOFF
)
2890 gcc_assert (XVECLEN (op0
, 0) == 1);
2892 new = force_const_mem (Pmode
, orig
);
2895 /* Otherwise, compute the sum. */
2898 base
= legitimize_pic_address (XEXP (addr
, 0), reg
);
2899 new = legitimize_pic_address (XEXP (addr
, 1),
2900 base
== reg
? NULL_RTX
: reg
);
2901 if (GET_CODE (new) == CONST_INT
)
2902 new = plus_constant (base
, INTVAL (new));
2905 if (GET_CODE (new) == PLUS
&& CONSTANT_P (XEXP (new, 1)))
2907 base
= gen_rtx_PLUS (Pmode
, base
, XEXP (new, 0));
2908 new = XEXP (new, 1);
2910 new = gen_rtx_PLUS (Pmode
, base
, new);
2913 if (GET_CODE (new) == CONST
)
2914 new = XEXP (new, 0);
2915 new = force_operand (new, 0);
2922 /* Load the thread pointer into a register. */
2925 s390_get_thread_pointer (void)
2927 rtx tp
= gen_reg_rtx (Pmode
);
2929 emit_move_insn (tp
, gen_rtx_REG (Pmode
, TP_REGNUM
));
2930 mark_reg_pointer (tp
, BITS_PER_WORD
);
2935 /* Emit a tls call insn. The call target is the SYMBOL_REF stored
2936 in s390_tls_symbol which always refers to __tls_get_offset.
2937 The returned offset is written to RESULT_REG and an USE rtx is
2938 generated for TLS_CALL. */
2940 static GTY(()) rtx s390_tls_symbol
;
2943 s390_emit_tls_call_insn (rtx result_reg
, rtx tls_call
)
2947 gcc_assert (flag_pic
);
2949 if (!s390_tls_symbol
)
2950 s390_tls_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "__tls_get_offset");
2952 insn
= s390_emit_call (s390_tls_symbol
, tls_call
, result_reg
,
2953 gen_rtx_REG (Pmode
, RETURN_REGNUM
));
2955 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), result_reg
);
2956 CONST_OR_PURE_CALL_P (insn
) = 1;
2959 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
2960 this (thread-local) address. REG may be used as temporary. */
2963 legitimize_tls_address (rtx addr
, rtx reg
)
2965 rtx
new, tls_call
, temp
, base
, r2
, insn
;
2967 if (GET_CODE (addr
) == SYMBOL_REF
)
2968 switch (tls_symbolic_operand (addr
))
2970 case TLS_MODEL_GLOBAL_DYNAMIC
:
2972 r2
= gen_rtx_REG (Pmode
, 2);
2973 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_TLSGD
);
2974 new = gen_rtx_CONST (Pmode
, tls_call
);
2975 new = force_const_mem (Pmode
, new);
2976 emit_move_insn (r2
, new);
2977 s390_emit_tls_call_insn (r2
, tls_call
);
2978 insn
= get_insns ();
2981 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
2982 temp
= gen_reg_rtx (Pmode
);
2983 emit_libcall_block (insn
, temp
, r2
, new);
2985 new = gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
2988 s390_load_address (reg
, new);
2993 case TLS_MODEL_LOCAL_DYNAMIC
:
2995 r2
= gen_rtx_REG (Pmode
, 2);
2996 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM
);
2997 new = gen_rtx_CONST (Pmode
, tls_call
);
2998 new = force_const_mem (Pmode
, new);
2999 emit_move_insn (r2
, new);
3000 s390_emit_tls_call_insn (r2
, tls_call
);
3001 insn
= get_insns ();
3004 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM_NTPOFF
);
3005 temp
= gen_reg_rtx (Pmode
);
3006 emit_libcall_block (insn
, temp
, r2
, new);
3008 new = gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
3009 base
= gen_reg_rtx (Pmode
);
3010 s390_load_address (base
, new);
3012 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_DTPOFF
);
3013 new = gen_rtx_CONST (Pmode
, new);
3014 new = force_const_mem (Pmode
, new);
3015 temp
= gen_reg_rtx (Pmode
);
3016 emit_move_insn (temp
, new);
3018 new = gen_rtx_PLUS (Pmode
, base
, temp
);
3021 s390_load_address (reg
, new);
3026 case TLS_MODEL_INITIAL_EXEC
:
3029 /* Assume GOT offset < 4k. This is handled the same way
3030 in both 31- and 64-bit code. */
3032 if (reload_in_progress
|| reload_completed
)
3033 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
3035 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
3036 new = gen_rtx_CONST (Pmode
, new);
3037 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new);
3038 new = gen_const_mem (Pmode
, new);
3039 temp
= gen_reg_rtx (Pmode
);
3040 emit_move_insn (temp
, new);
3042 else if (TARGET_CPU_ZARCH
)
3044 /* If the GOT offset might be >= 4k, we determine the position
3045 of the GOT entry via a PC-relative LARL. */
3047 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
3048 new = gen_rtx_CONST (Pmode
, new);
3049 temp
= gen_reg_rtx (Pmode
);
3050 emit_move_insn (temp
, new);
3052 new = gen_const_mem (Pmode
, temp
);
3053 temp
= gen_reg_rtx (Pmode
);
3054 emit_move_insn (temp
, new);
3058 /* If the GOT offset might be >= 4k, we have to load it
3059 from the literal pool. */
3061 if (reload_in_progress
|| reload_completed
)
3062 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
3064 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
3065 new = gen_rtx_CONST (Pmode
, new);
3066 new = force_const_mem (Pmode
, new);
3067 temp
= gen_reg_rtx (Pmode
);
3068 emit_move_insn (temp
, new);
3070 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
3071 new = gen_const_mem (Pmode
, new);
3073 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new, addr
), UNSPEC_TLS_LOAD
);
3074 temp
= gen_reg_rtx (Pmode
);
3075 emit_insn (gen_rtx_SET (Pmode
, temp
, new));
3079 /* In position-dependent code, load the absolute address of
3080 the GOT entry from the literal pool. */
3082 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
3083 new = gen_rtx_CONST (Pmode
, new);
3084 new = force_const_mem (Pmode
, new);
3085 temp
= gen_reg_rtx (Pmode
);
3086 emit_move_insn (temp
, new);
3089 new = gen_const_mem (Pmode
, new);
3090 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new, addr
), UNSPEC_TLS_LOAD
);
3091 temp
= gen_reg_rtx (Pmode
);
3092 emit_insn (gen_rtx_SET (Pmode
, temp
, new));
3095 new = gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
3098 s390_load_address (reg
, new);
3103 case TLS_MODEL_LOCAL_EXEC
:
3104 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
3105 new = gen_rtx_CONST (Pmode
, new);
3106 new = force_const_mem (Pmode
, new);
3107 temp
= gen_reg_rtx (Pmode
);
3108 emit_move_insn (temp
, new);
3110 new = gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
3113 s390_load_address (reg
, new);
3122 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == UNSPEC
)
3124 switch (XINT (XEXP (addr
, 0), 1))
3126 case UNSPEC_INDNTPOFF
:
3127 gcc_assert (TARGET_CPU_ZARCH
);
3136 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == PLUS
3137 && GET_CODE (XEXP (XEXP (addr
, 0), 1)) == CONST_INT
)
3139 new = XEXP (XEXP (addr
, 0), 0);
3140 if (GET_CODE (new) != SYMBOL_REF
)
3141 new = gen_rtx_CONST (Pmode
, new);
3143 new = legitimize_tls_address (new, reg
);
3144 new = plus_constant (new, INTVAL (XEXP (XEXP (addr
, 0), 1)));
3145 new = force_operand (new, 0);
3149 gcc_unreachable (); /* for now ... */
3154 /* Emit insns to move operands[1] into operands[0]. */
3157 emit_symbolic_move (rtx
*operands
)
3159 rtx temp
= no_new_pseudos
? operands
[0] : gen_reg_rtx (Pmode
);
3161 if (GET_CODE (operands
[0]) == MEM
)
3162 operands
[1] = force_reg (Pmode
, operands
[1]);
3163 else if (TLS_SYMBOLIC_CONST (operands
[1]))
3164 operands
[1] = legitimize_tls_address (operands
[1], temp
);
3166 operands
[1] = legitimize_pic_address (operands
[1], temp
);
3169 /* Try machine-dependent ways of modifying an illegitimate address X
3170 to be legitimate. If we find one, return the new, valid address.
3172 OLDX is the address as it was before break_out_memory_refs was called.
3173 In some cases it is useful to look at this to decide what needs to be done.
3175 MODE is the mode of the operand pointed to by X.
3177 When -fpic is used, special handling is needed for symbolic references.
3178 See comments by legitimize_pic_address for details. */
3181 legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
3182 enum machine_mode mode ATTRIBUTE_UNUSED
)
3184 rtx constant_term
= const0_rtx
;
3186 if (TLS_SYMBOLIC_CONST (x
))
3188 x
= legitimize_tls_address (x
, 0);
3190 if (legitimate_address_p (mode
, x
, FALSE
))
3195 if (SYMBOLIC_CONST (x
)
3196 || (GET_CODE (x
) == PLUS
3197 && (SYMBOLIC_CONST (XEXP (x
, 0))
3198 || SYMBOLIC_CONST (XEXP (x
, 1)))))
3199 x
= legitimize_pic_address (x
, 0);
3201 if (legitimate_address_p (mode
, x
, FALSE
))
3205 x
= eliminate_constant_term (x
, &constant_term
);
3207 /* Optimize loading of large displacements by splitting them
3208 into the multiple of 4K and the rest; this allows the
3209 former to be CSE'd if possible.
3211 Don't do this if the displacement is added to a register
3212 pointing into the stack frame, as the offsets will
3213 change later anyway. */
3215 if (GET_CODE (constant_term
) == CONST_INT
3216 && !TARGET_LONG_DISPLACEMENT
3217 && !DISP_IN_RANGE (INTVAL (constant_term
))
3218 && !(REG_P (x
) && REGNO_PTR_FRAME_P (REGNO (x
))))
3220 HOST_WIDE_INT lower
= INTVAL (constant_term
) & 0xfff;
3221 HOST_WIDE_INT upper
= INTVAL (constant_term
) ^ lower
;
3223 rtx temp
= gen_reg_rtx (Pmode
);
3224 rtx val
= force_operand (GEN_INT (upper
), temp
);
3226 emit_move_insn (temp
, val
);
3228 x
= gen_rtx_PLUS (Pmode
, x
, temp
);
3229 constant_term
= GEN_INT (lower
);
3232 if (GET_CODE (x
) == PLUS
)
3234 if (GET_CODE (XEXP (x
, 0)) == REG
)
3236 rtx temp
= gen_reg_rtx (Pmode
);
3237 rtx val
= force_operand (XEXP (x
, 1), temp
);
3239 emit_move_insn (temp
, val
);
3241 x
= gen_rtx_PLUS (Pmode
, XEXP (x
, 0), temp
);
3244 else if (GET_CODE (XEXP (x
, 1)) == REG
)
3246 rtx temp
= gen_reg_rtx (Pmode
);
3247 rtx val
= force_operand (XEXP (x
, 0), temp
);
3249 emit_move_insn (temp
, val
);
3251 x
= gen_rtx_PLUS (Pmode
, temp
, XEXP (x
, 1));
3255 if (constant_term
!= const0_rtx
)
3256 x
= gen_rtx_PLUS (Pmode
, x
, constant_term
);
3261 /* Try a machine-dependent way of reloading an illegitimate address AD
3262 operand. If we find one, push the reload and and return the new address.
3264 MODE is the mode of the enclosing MEM. OPNUM is the operand number
3265 and TYPE is the reload type of the current reload. */
3268 legitimize_reload_address (rtx ad
, enum machine_mode mode ATTRIBUTE_UNUSED
,
3269 int opnum
, int type
)
3271 if (!optimize
|| TARGET_LONG_DISPLACEMENT
)
3274 if (GET_CODE (ad
) == PLUS
)
3276 rtx tem
= simplify_binary_operation (PLUS
, Pmode
,
3277 XEXP (ad
, 0), XEXP (ad
, 1));
3282 if (GET_CODE (ad
) == PLUS
3283 && GET_CODE (XEXP (ad
, 0)) == REG
3284 && GET_CODE (XEXP (ad
, 1)) == CONST_INT
3285 && !DISP_IN_RANGE (INTVAL (XEXP (ad
, 1))))
3287 HOST_WIDE_INT lower
= INTVAL (XEXP (ad
, 1)) & 0xfff;
3288 HOST_WIDE_INT upper
= INTVAL (XEXP (ad
, 1)) ^ lower
;
3291 cst
= GEN_INT (upper
);
3292 if (!legitimate_reload_constant_p (cst
))
3293 cst
= force_const_mem (Pmode
, cst
);
3295 tem
= gen_rtx_PLUS (Pmode
, XEXP (ad
, 0), cst
);
3296 new = gen_rtx_PLUS (Pmode
, tem
, GEN_INT (lower
));
3298 push_reload (XEXP (tem
, 1), 0, &XEXP (tem
, 1), 0,
3299 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
3300 opnum
, (enum reload_type
) type
);
3307 /* Emit code to move LEN bytes from DST to SRC. */
3310 s390_expand_movmem (rtx dst
, rtx src
, rtx len
)
3312 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3314 if (INTVAL (len
) > 0)
3315 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (INTVAL (len
) - 1)));
3318 else if (TARGET_MVCLE
)
3320 emit_insn (gen_movmem_long (dst
, src
, convert_to_mode (Pmode
, len
, 1)));
3325 rtx dst_addr
, src_addr
, count
, blocks
, temp
;
3326 rtx loop_start_label
= gen_label_rtx ();
3327 rtx loop_end_label
= gen_label_rtx ();
3328 rtx end_label
= gen_label_rtx ();
3329 enum machine_mode mode
;
3331 mode
= GET_MODE (len
);
3332 if (mode
== VOIDmode
)
3335 dst_addr
= gen_reg_rtx (Pmode
);
3336 src_addr
= gen_reg_rtx (Pmode
);
3337 count
= gen_reg_rtx (mode
);
3338 blocks
= gen_reg_rtx (mode
);
3340 convert_move (count
, len
, 1);
3341 emit_cmp_and_jump_insns (count
, const0_rtx
,
3342 EQ
, NULL_RTX
, mode
, 1, end_label
);
3344 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
3345 emit_move_insn (src_addr
, force_operand (XEXP (src
, 0), NULL_RTX
));
3346 dst
= change_address (dst
, VOIDmode
, dst_addr
);
3347 src
= change_address (src
, VOIDmode
, src_addr
);
3349 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3351 emit_move_insn (count
, temp
);
3353 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3355 emit_move_insn (blocks
, temp
);
3357 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3358 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3360 emit_label (loop_start_label
);
3362 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (255)));
3363 s390_load_address (dst_addr
,
3364 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
3365 s390_load_address (src_addr
,
3366 gen_rtx_PLUS (Pmode
, src_addr
, GEN_INT (256)));
3368 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3370 emit_move_insn (blocks
, temp
);
3372 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3373 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3375 emit_jump (loop_start_label
);
3376 emit_label (loop_end_label
);
3378 emit_insn (gen_movmem_short (dst
, src
,
3379 convert_to_mode (Pmode
, count
, 1)));
3380 emit_label (end_label
);
3384 /* Emit code to set LEN bytes at DST to VAL.
3385 Make use of clrmem if VAL is zero. */
3388 s390_expand_setmem (rtx dst
, rtx len
, rtx val
)
3390 gcc_assert (GET_CODE (len
) != CONST_INT
|| INTVAL (len
) > 0);
3391 gcc_assert (GET_CODE (val
) == CONST_INT
|| GET_MODE (val
) == QImode
);
3393 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) <= 257)
3395 if (val
== const0_rtx
&& INTVAL (len
) <= 256)
3396 emit_insn (gen_clrmem_short (dst
, GEN_INT (INTVAL (len
) - 1)));
3399 /* Initialize memory by storing the first byte. */
3400 emit_move_insn (adjust_address (dst
, QImode
, 0), val
);
3402 if (INTVAL (len
) > 1)
3404 /* Initiate 1 byte overlap move.
3405 The first byte of DST is propagated through DSTP1.
3406 Prepare a movmem for: DST+1 = DST (length = LEN - 1).
3407 DST is set to size 1 so the rest of the memory location
3408 does not count as source operand. */
3409 rtx dstp1
= adjust_address (dst
, VOIDmode
, 1);
3410 set_mem_size (dst
, const1_rtx
);
3412 emit_insn (gen_movmem_short (dstp1
, dst
,
3413 GEN_INT (INTVAL (len
) - 2)));
3418 else if (TARGET_MVCLE
)
3420 val
= force_not_mem (convert_modes (Pmode
, QImode
, val
, 1));
3421 emit_insn (gen_setmem_long (dst
, convert_to_mode (Pmode
, len
, 1), val
));
3426 rtx dst_addr
, src_addr
, count
, blocks
, temp
, dstp1
= NULL_RTX
;
3427 rtx loop_start_label
= gen_label_rtx ();
3428 rtx loop_end_label
= gen_label_rtx ();
3429 rtx end_label
= gen_label_rtx ();
3430 enum machine_mode mode
;
3432 mode
= GET_MODE (len
);
3433 if (mode
== VOIDmode
)
3436 dst_addr
= gen_reg_rtx (Pmode
);
3437 src_addr
= gen_reg_rtx (Pmode
);
3438 count
= gen_reg_rtx (mode
);
3439 blocks
= gen_reg_rtx (mode
);
3441 convert_move (count
, len
, 1);
3442 emit_cmp_and_jump_insns (count
, const0_rtx
,
3443 EQ
, NULL_RTX
, mode
, 1, end_label
);
3445 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
3446 dst
= change_address (dst
, VOIDmode
, dst_addr
);
3448 if (val
== const0_rtx
)
3449 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3452 dstp1
= adjust_address (dst
, VOIDmode
, 1);
3453 set_mem_size (dst
, const1_rtx
);
3455 /* Initialize memory by storing the first byte. */
3456 emit_move_insn (adjust_address (dst
, QImode
, 0), val
);
3458 /* If count is 1 we are done. */
3459 emit_cmp_and_jump_insns (count
, const1_rtx
,
3460 EQ
, NULL_RTX
, mode
, 1, end_label
);
3462 temp
= expand_binop (mode
, add_optab
, count
, GEN_INT (-2), count
, 1, 0);
3465 emit_move_insn (count
, temp
);
3467 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3469 emit_move_insn (blocks
, temp
);
3471 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3472 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3474 emit_label (loop_start_label
);
3476 if (val
== const0_rtx
)
3477 emit_insn (gen_clrmem_short (dst
, GEN_INT (255)));
3479 emit_insn (gen_movmem_short (dstp1
, dst
, GEN_INT (255)));
3480 s390_load_address (dst_addr
,
3481 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
3483 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3485 emit_move_insn (blocks
, temp
);
3487 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3488 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3490 emit_jump (loop_start_label
);
3491 emit_label (loop_end_label
);
3493 if (val
== const0_rtx
)
3494 emit_insn (gen_clrmem_short (dst
, convert_to_mode (Pmode
, count
, 1)));
3496 emit_insn (gen_movmem_short (dstp1
, dst
, convert_to_mode (Pmode
, count
, 1)));
3497 emit_label (end_label
);
3501 /* Emit code to compare LEN bytes at OP0 with those at OP1,
3502 and return the result in TARGET. */
3505 s390_expand_cmpmem (rtx target
, rtx op0
, rtx op1
, rtx len
)
3507 rtx ccreg
= gen_rtx_REG (CCUmode
, CC_REGNUM
);
3510 /* As the result of CMPINT is inverted compared to what we need,
3511 we have to swap the operands. */
3512 tmp
= op0
; op0
= op1
; op1
= tmp
;
3514 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3516 if (INTVAL (len
) > 0)
3518 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (INTVAL (len
) - 1)));
3519 emit_insn (gen_cmpint (target
, ccreg
));
3522 emit_move_insn (target
, const0_rtx
);
3524 else if (TARGET_MVCLE
)
3526 emit_insn (gen_cmpmem_long (op0
, op1
, convert_to_mode (Pmode
, len
, 1)));
3527 emit_insn (gen_cmpint (target
, ccreg
));
3531 rtx addr0
, addr1
, count
, blocks
, temp
;
3532 rtx loop_start_label
= gen_label_rtx ();
3533 rtx loop_end_label
= gen_label_rtx ();
3534 rtx end_label
= gen_label_rtx ();
3535 enum machine_mode mode
;
3537 mode
= GET_MODE (len
);
3538 if (mode
== VOIDmode
)
3541 addr0
= gen_reg_rtx (Pmode
);
3542 addr1
= gen_reg_rtx (Pmode
);
3543 count
= gen_reg_rtx (mode
);
3544 blocks
= gen_reg_rtx (mode
);
3546 convert_move (count
, len
, 1);
3547 emit_cmp_and_jump_insns (count
, const0_rtx
,
3548 EQ
, NULL_RTX
, mode
, 1, end_label
);
3550 emit_move_insn (addr0
, force_operand (XEXP (op0
, 0), NULL_RTX
));
3551 emit_move_insn (addr1
, force_operand (XEXP (op1
, 0), NULL_RTX
));
3552 op0
= change_address (op0
, VOIDmode
, addr0
);
3553 op1
= change_address (op1
, VOIDmode
, addr1
);
3555 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3557 emit_move_insn (count
, temp
);
3559 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3561 emit_move_insn (blocks
, temp
);
3563 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3564 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3566 emit_label (loop_start_label
);
3568 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (255)));
3569 temp
= gen_rtx_NE (VOIDmode
, ccreg
, const0_rtx
);
3570 temp
= gen_rtx_IF_THEN_ELSE (VOIDmode
, temp
,
3571 gen_rtx_LABEL_REF (VOIDmode
, end_label
), pc_rtx
);
3572 temp
= gen_rtx_SET (VOIDmode
, pc_rtx
, temp
);
3573 emit_jump_insn (temp
);
3575 s390_load_address (addr0
,
3576 gen_rtx_PLUS (Pmode
, addr0
, GEN_INT (256)));
3577 s390_load_address (addr1
,
3578 gen_rtx_PLUS (Pmode
, addr1
, GEN_INT (256)));
3580 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3582 emit_move_insn (blocks
, temp
);
3584 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3585 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3587 emit_jump (loop_start_label
);
3588 emit_label (loop_end_label
);
3590 emit_insn (gen_cmpmem_short (op0
, op1
,
3591 convert_to_mode (Pmode
, count
, 1)));
3592 emit_label (end_label
);
3594 emit_insn (gen_cmpint (target
, ccreg
));
3599 /* Expand conditional increment or decrement using alc/slb instructions.
3600 Should generate code setting DST to either SRC or SRC + INCREMENT,
3601 depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
3602 Returns true if successful, false otherwise.
3604 That makes it possible to implement some if-constructs without jumps e.g.:
3605 (borrow = CC0 | CC1 and carry = CC2 | CC3)
3606 unsigned int a, b, c;
3607 if (a < b) c++; -> CCU b > a -> CC2; c += carry;
3608 if (a < b) c--; -> CCL3 a - b -> borrow; c -= borrow;
3609 if (a <= b) c++; -> CCL3 b - a -> borrow; c += carry;
3610 if (a <= b) c--; -> CCU a <= b -> borrow; c -= borrow;
3612 Checks for EQ and NE with a nonzero value need an additional xor e.g.:
3613 if (a == b) c++; -> CCL3 a ^= b; 0 - a -> borrow; c += carry;
3614 if (a == b) c--; -> CCU a ^= b; a <= 0 -> CC0 | CC1; c -= borrow;
3615 if (a != b) c++; -> CCU a ^= b; a > 0 -> CC2; c += carry;
3616 if (a != b) c--; -> CCL3 a ^= b; 0 - a -> borrow; c -= borrow; */
3619 s390_expand_addcc (enum rtx_code cmp_code
, rtx cmp_op0
, rtx cmp_op1
,
3620 rtx dst
, rtx src
, rtx increment
)
3622 enum machine_mode cmp_mode
;
3623 enum machine_mode cc_mode
;
3629 if ((GET_MODE (cmp_op0
) == SImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
3630 && (GET_MODE (cmp_op1
) == SImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
3632 else if ((GET_MODE (cmp_op0
) == DImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
3633 && (GET_MODE (cmp_op1
) == DImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
3638 /* Try ADD LOGICAL WITH CARRY. */
3639 if (increment
== const1_rtx
)
3641 /* Determine CC mode to use. */
3642 if (cmp_code
== EQ
|| cmp_code
== NE
)
3644 if (cmp_op1
!= const0_rtx
)
3646 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
3647 NULL_RTX
, 0, OPTAB_WIDEN
);
3648 cmp_op1
= const0_rtx
;
3651 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
3654 if (cmp_code
== LTU
|| cmp_code
== LEU
)
3659 cmp_code
= swap_condition (cmp_code
);
3676 /* Emit comparison instruction pattern. */
3677 if (!register_operand (cmp_op0
, cmp_mode
))
3678 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
3680 insn
= gen_rtx_SET (VOIDmode
, gen_rtx_REG (cc_mode
, CC_REGNUM
),
3681 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
3682 /* We use insn_invalid_p here to add clobbers if required. */
3683 ret
= insn_invalid_p (emit_insn (insn
));
3686 /* Emit ALC instruction pattern. */
3687 op_res
= gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
3688 gen_rtx_REG (cc_mode
, CC_REGNUM
),
3691 if (src
!= const0_rtx
)
3693 if (!register_operand (src
, GET_MODE (dst
)))
3694 src
= force_reg (GET_MODE (dst
), src
);
3696 src
= gen_rtx_PLUS (GET_MODE (dst
), src
, const0_rtx
);
3697 op_res
= gen_rtx_PLUS (GET_MODE (dst
), src
, op_res
);
3700 p
= rtvec_alloc (2);
3702 gen_rtx_SET (VOIDmode
, dst
, op_res
);
3704 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
3705 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
3710 /* Try SUBTRACT LOGICAL WITH BORROW. */
3711 if (increment
== constm1_rtx
)
3713 /* Determine CC mode to use. */
3714 if (cmp_code
== EQ
|| cmp_code
== NE
)
3716 if (cmp_op1
!= const0_rtx
)
3718 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
3719 NULL_RTX
, 0, OPTAB_WIDEN
);
3720 cmp_op1
= const0_rtx
;
3723 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
3726 if (cmp_code
== GTU
|| cmp_code
== GEU
)
3731 cmp_code
= swap_condition (cmp_code
);
3748 /* Emit comparison instruction pattern. */
3749 if (!register_operand (cmp_op0
, cmp_mode
))
3750 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
3752 insn
= gen_rtx_SET (VOIDmode
, gen_rtx_REG (cc_mode
, CC_REGNUM
),
3753 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
3754 /* We use insn_invalid_p here to add clobbers if required. */
3755 ret
= insn_invalid_p (emit_insn (insn
));
3758 /* Emit SLB instruction pattern. */
3759 if (!register_operand (src
, GET_MODE (dst
)))
3760 src
= force_reg (GET_MODE (dst
), src
);
3762 op_res
= gen_rtx_MINUS (GET_MODE (dst
),
3763 gen_rtx_MINUS (GET_MODE (dst
), src
, const0_rtx
),
3764 gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
3765 gen_rtx_REG (cc_mode
, CC_REGNUM
),
3767 p
= rtvec_alloc (2);
3769 gen_rtx_SET (VOIDmode
, dst
, op_res
);
3771 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
3772 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
3781 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
3782 We need to emit DTP-relative relocations. */
3784 static void s390_output_dwarf_dtprel (FILE *, int, rtx
) ATTRIBUTE_UNUSED
;
3787 s390_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
3792 fputs ("\t.long\t", file
);
3795 fputs ("\t.quad\t", file
);
3800 output_addr_const (file
, x
);
3801 fputs ("@DTPOFF", file
);
3804 /* In the name of slightly smaller debug output, and to cater to
3805 general assembler lossage, recognize various UNSPEC sequences
3806 and turn them back into a direct symbol reference. */
3809 s390_delegitimize_address (rtx orig_x
)
3813 if (GET_CODE (x
) != MEM
)
3817 if (GET_CODE (x
) == PLUS
3818 && GET_CODE (XEXP (x
, 1)) == CONST
3819 && GET_CODE (XEXP (x
, 0)) == REG
3820 && REGNO (XEXP (x
, 0)) == PIC_OFFSET_TABLE_REGNUM
)
3822 y
= XEXP (XEXP (x
, 1), 0);
3823 if (GET_CODE (y
) == UNSPEC
3824 && XINT (y
, 1) == UNSPEC_GOT
)
3825 return XVECEXP (y
, 0, 0);
3829 if (GET_CODE (x
) == CONST
)
3832 if (GET_CODE (y
) == UNSPEC
3833 && XINT (y
, 1) == UNSPEC_GOTENT
)
3834 return XVECEXP (y
, 0, 0);
3841 /* Output operand OP to stdio stream FILE.
3842 OP is an address (register + offset) which is not used to address data;
3843 instead the rightmost bits are interpreted as the value. */
3846 print_shift_count_operand (FILE *file
, rtx op
)
3848 HOST_WIDE_INT offset
= 0;
3850 /* Shift count operands are always truncated to the 6 least significant bits and
3851 the setmem padding byte to the least 8 significant bits. Hence we can drop
3853 if (GET_CODE (op
) == AND
&& GET_CODE (XEXP (op
, 1)) == CONST_INT
)
3855 if ((INTVAL (XEXP (op
, 1)) & 63) != 63)
3861 /* We can have an integer constant, an address register,
3862 or a sum of the two. */
3863 if (GET_CODE (op
) == CONST_INT
)
3865 offset
= INTVAL (op
);
3868 if (op
&& GET_CODE (op
) == PLUS
&& GET_CODE (XEXP (op
, 1)) == CONST_INT
)
3870 offset
= INTVAL (XEXP (op
, 1));
3873 while (op
&& GET_CODE (op
) == SUBREG
)
3874 op
= SUBREG_REG (op
);
3879 gcc_assert (GET_CODE (op
) == REG
);
3880 gcc_assert (REGNO (op
) < FIRST_PSEUDO_REGISTER
);
3881 gcc_assert (REGNO_REG_CLASS (REGNO (op
)) == ADDR_REGS
);
3884 /* Offsets are constricted to twelve bits. */
3885 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
& ((1 << 12) - 1));
3887 fprintf (file
, "(%s)", reg_names
[REGNO (op
)]);
3890 /* See 'get_some_local_dynamic_name'. */
3893 get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
3897 if (GET_CODE (x
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (x
))
3899 x
= get_pool_constant (x
);
3900 return for_each_rtx (&x
, get_some_local_dynamic_name_1
, 0);
3903 if (GET_CODE (x
) == SYMBOL_REF
3904 && tls_symbolic_operand (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
3906 cfun
->machine
->some_ld_name
= XSTR (x
, 0);
3913 /* Locate some local-dynamic symbol still in use by this function
3914 so that we can print its name in local-dynamic base patterns. */
3917 get_some_local_dynamic_name (void)
3921 if (cfun
->machine
->some_ld_name
)
3922 return cfun
->machine
->some_ld_name
;
3924 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
3926 && for_each_rtx (&PATTERN (insn
), get_some_local_dynamic_name_1
, 0))
3927 return cfun
->machine
->some_ld_name
;
3932 /* Output machine-dependent UNSPECs occurring in address constant X
3933 in assembler syntax to stdio stream FILE. Returns true if the
3934 constant X could be recognized, false otherwise. */
3937 s390_output_addr_const_extra (FILE *file
, rtx x
)
3939 if (GET_CODE (x
) == UNSPEC
&& XVECLEN (x
, 0) == 1)
3940 switch (XINT (x
, 1))
3943 output_addr_const (file
, XVECEXP (x
, 0, 0));
3944 fprintf (file
, "@GOTENT");
3947 output_addr_const (file
, XVECEXP (x
, 0, 0));
3948 fprintf (file
, "@GOT");
3951 output_addr_const (file
, XVECEXP (x
, 0, 0));
3952 fprintf (file
, "@GOTOFF");
3955 output_addr_const (file
, XVECEXP (x
, 0, 0));
3956 fprintf (file
, "@PLT");
3959 output_addr_const (file
, XVECEXP (x
, 0, 0));
3960 fprintf (file
, "@PLTOFF");
3963 output_addr_const (file
, XVECEXP (x
, 0, 0));
3964 fprintf (file
, "@TLSGD");
3967 assemble_name (file
, get_some_local_dynamic_name ());
3968 fprintf (file
, "@TLSLDM");
3971 output_addr_const (file
, XVECEXP (x
, 0, 0));
3972 fprintf (file
, "@DTPOFF");
3975 output_addr_const (file
, XVECEXP (x
, 0, 0));
3976 fprintf (file
, "@NTPOFF");
3978 case UNSPEC_GOTNTPOFF
:
3979 output_addr_const (file
, XVECEXP (x
, 0, 0));
3980 fprintf (file
, "@GOTNTPOFF");
3982 case UNSPEC_INDNTPOFF
:
3983 output_addr_const (file
, XVECEXP (x
, 0, 0));
3984 fprintf (file
, "@INDNTPOFF");
3991 /* Output address operand ADDR in assembler syntax to
3992 stdio stream FILE. */
3995 print_operand_address (FILE *file
, rtx addr
)
3997 struct s390_address ad
;
3999 if (!s390_decompose_address (addr
, &ad
)
4000 || (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
4001 || (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
)))
4002 output_operand_lossage ("cannot decompose address");
4005 output_addr_const (file
, ad
.disp
);
4007 fprintf (file
, "0");
4009 if (ad
.base
&& ad
.indx
)
4010 fprintf (file
, "(%s,%s)", reg_names
[REGNO (ad
.indx
)],
4011 reg_names
[REGNO (ad
.base
)]);
4013 fprintf (file
, "(%s)", reg_names
[REGNO (ad
.base
)]);
4016 /* Output operand X in assembler syntax to stdio stream FILE.
4017 CODE specified the format flag. The following format flags
4020 'C': print opcode suffix for branch condition.
4021 'D': print opcode suffix for inverse branch condition.
4022 'J': print tls_load/tls_gdcall/tls_ldcall suffix
4023 'G': print the size of the operand in bytes.
4024 'O': print only the displacement of a memory reference.
4025 'R': print only the base register of a memory reference.
4026 'S': print S-type memory reference (base+displacement).
4027 'N': print the second word of a DImode operand.
4028 'M': print the second word of a TImode operand.
4029 'Y': print shift count operand.
4031 'b': print integer X as if it's an unsigned byte.
4032 'x': print integer X as if it's an unsigned word.
4033 'h': print integer X as if it's a signed word.
4034 'i': print the first nonzero HImode part of X.
4035 'j': print the first HImode part unequal to 0xffff of X. */
4038 print_operand (FILE *file
, rtx x
, int code
)
4043 fprintf (file
, s390_branch_condition_mnemonic (x
, FALSE
));
4047 fprintf (file
, s390_branch_condition_mnemonic (x
, TRUE
));
4051 if (GET_CODE (x
) == SYMBOL_REF
)
4053 fprintf (file
, "%s", ":tls_load:");
4054 output_addr_const (file
, x
);
4056 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSGD
)
4058 fprintf (file
, "%s", ":tls_gdcall:");
4059 output_addr_const (file
, XVECEXP (x
, 0, 0));
4061 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSLDM
)
4063 fprintf (file
, "%s", ":tls_ldcall:");
4064 assemble_name (file
, get_some_local_dynamic_name ());
4071 fprintf (file
, "%u", GET_MODE_SIZE (GET_MODE (x
)));
4076 struct s390_address ad
;
4079 gcc_assert (GET_CODE (x
) == MEM
);
4080 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
4082 gcc_assert (!ad
.base
|| REG_OK_FOR_BASE_STRICT_P (ad
.base
));
4083 gcc_assert (!ad
.indx
);
4086 output_addr_const (file
, ad
.disp
);
4088 fprintf (file
, "0");
4094 struct s390_address ad
;
4097 gcc_assert (GET_CODE (x
) == MEM
);
4098 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
4100 gcc_assert (!ad
.base
|| REG_OK_FOR_BASE_STRICT_P (ad
.base
));
4101 gcc_assert (!ad
.indx
);
4104 fprintf (file
, "%s", reg_names
[REGNO (ad
.base
)]);
4106 fprintf (file
, "0");
4112 struct s390_address ad
;
4115 gcc_assert (GET_CODE (x
) == MEM
);
4116 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
4118 gcc_assert (!ad
.base
|| REG_OK_FOR_BASE_STRICT_P (ad
.base
));
4119 gcc_assert (!ad
.indx
);
4122 output_addr_const (file
, ad
.disp
);
4124 fprintf (file
, "0");
4127 fprintf (file
, "(%s)", reg_names
[REGNO (ad
.base
)]);
4132 if (GET_CODE (x
) == REG
)
4133 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
4134 else if (GET_CODE (x
) == MEM
)
4135 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 4));
4141 if (GET_CODE (x
) == REG
)
4142 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
4143 else if (GET_CODE (x
) == MEM
)
4144 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 8));
4150 print_shift_count_operand (file
, x
);
4154 switch (GET_CODE (x
))
4157 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
4161 output_address (XEXP (x
, 0));
4168 output_addr_const (file
, x
);
4173 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xff);
4174 else if (code
== 'x')
4175 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xffff);
4176 else if (code
== 'h')
4177 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((INTVAL (x
) & 0xffff) ^ 0x8000) - 0x8000);
4178 else if (code
== 'i')
4179 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
4180 s390_extract_part (x
, HImode
, 0));
4181 else if (code
== 'j')
4182 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
4183 s390_extract_part (x
, HImode
, -1));
4184 else if (code
== 'k')
4185 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
4186 s390_extract_part (x
, SImode
, 0));
4187 else if (code
== 'm')
4188 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
4189 s390_extract_part (x
, SImode
, -1));
4190 else if (code
== 'o')
4191 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xffffffff);
4193 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
4197 gcc_assert (GET_MODE (x
) == VOIDmode
);
4199 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xff);
4200 else if (code
== 'x')
4201 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xffff);
4202 else if (code
== 'h')
4203 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((CONST_DOUBLE_LOW (x
) & 0xffff) ^ 0x8000) - 0x8000);
4209 fatal_insn ("UNKNOWN in print_operand !?", x
);
4214 /* Target hook for assembling integer objects. We need to define it
4215 here to work a round a bug in some versions of GAS, which couldn't
4216 handle values smaller than INT_MIN when printed in decimal. */
4219 s390_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
4221 if (size
== 8 && aligned_p
4222 && GET_CODE (x
) == CONST_INT
&& INTVAL (x
) < INT_MIN
)
4224 fprintf (asm_out_file
, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX
"\n",
4228 return default_assemble_integer (x
, size
, aligned_p
);
4231 /* Returns true if register REGNO is used for forming
4232 a memory address in expression X. */
4235 reg_used_in_mem_p (int regno
, rtx x
)
4237 enum rtx_code code
= GET_CODE (x
);
4243 if (refers_to_regno_p (regno
, regno
+1,
4247 else if (code
== SET
4248 && GET_CODE (SET_DEST (x
)) == PC
)
4250 if (refers_to_regno_p (regno
, regno
+1,
4255 fmt
= GET_RTX_FORMAT (code
);
4256 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
4259 && reg_used_in_mem_p (regno
, XEXP (x
, i
)))
4262 else if (fmt
[i
] == 'E')
4263 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
4264 if (reg_used_in_mem_p (regno
, XVECEXP (x
, i
, j
)))
4270 /* Returns true if expression DEP_RTX sets an address register
4271 used by instruction INSN to address memory. */
4274 addr_generation_dependency_p (rtx dep_rtx
, rtx insn
)
4278 if (GET_CODE (dep_rtx
) == INSN
)
4279 dep_rtx
= PATTERN (dep_rtx
);
4281 if (GET_CODE (dep_rtx
) == SET
)
4283 target
= SET_DEST (dep_rtx
);
4284 if (GET_CODE (target
) == STRICT_LOW_PART
)
4285 target
= XEXP (target
, 0);
4286 while (GET_CODE (target
) == SUBREG
)
4287 target
= SUBREG_REG (target
);
4289 if (GET_CODE (target
) == REG
)
4291 int regno
= REGNO (target
);
4293 if (s390_safe_attr_type (insn
) == TYPE_LA
)
4295 pat
= PATTERN (insn
);
4296 if (GET_CODE (pat
) == PARALLEL
)
4298 gcc_assert (XVECLEN (pat
, 0) == 2);
4299 pat
= XVECEXP (pat
, 0, 0);
4301 gcc_assert (GET_CODE (pat
) == SET
);
4302 return refers_to_regno_p (regno
, regno
+1, SET_SRC (pat
), 0);
4304 else if (get_attr_atype (insn
) == ATYPE_AGEN
)
4305 return reg_used_in_mem_p (regno
, PATTERN (insn
));
4311 /* Return 1, if dep_insn sets register used in insn in the agen unit. */
4314 s390_agen_dep_p (rtx dep_insn
, rtx insn
)
4316 rtx dep_rtx
= PATTERN (dep_insn
);
4319 if (GET_CODE (dep_rtx
) == SET
4320 && addr_generation_dependency_p (dep_rtx
, insn
))
4322 else if (GET_CODE (dep_rtx
) == PARALLEL
)
4324 for (i
= 0; i
< XVECLEN (dep_rtx
, 0); i
++)
4326 if (addr_generation_dependency_p (XVECEXP (dep_rtx
, 0, i
), insn
))
4333 /* A C statement (sans semicolon) to update the integer scheduling priority
4334 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
4335 reduce the priority to execute INSN later. Do not define this macro if
4336 you do not need to adjust the scheduling priorities of insns.
4338 A STD instruction should be scheduled earlier,
4339 in order to use the bypass. */
4342 s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
4344 if (! INSN_P (insn
))
4347 if (s390_tune
!= PROCESSOR_2084_Z990
4348 && s390_tune
!= PROCESSOR_2094_Z9_109
)
4351 switch (s390_safe_attr_type (insn
))
4355 priority
= priority
<< 3;
4359 priority
= priority
<< 1;
4367 /* The number of instructions that can be issued per cycle. */
4370 s390_issue_rate (void)
4372 if (s390_tune
== PROCESSOR_2084_Z990
4373 || s390_tune
== PROCESSOR_2094_Z9_109
)
4379 s390_first_cycle_multipass_dfa_lookahead (void)
4385 /* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
4386 Fix up MEMs as required. */
4389 annotate_constant_pool_refs (rtx
*x
)
4394 gcc_assert (GET_CODE (*x
) != SYMBOL_REF
4395 || !CONSTANT_POOL_ADDRESS_P (*x
));
4397 /* Literal pool references can only occur inside a MEM ... */
4398 if (GET_CODE (*x
) == MEM
)
4400 rtx memref
= XEXP (*x
, 0);
4402 if (GET_CODE (memref
) == SYMBOL_REF
4403 && CONSTANT_POOL_ADDRESS_P (memref
))
4405 rtx base
= cfun
->machine
->base_reg
;
4406 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, memref
, base
),
4409 *x
= replace_equiv_address (*x
, addr
);
4413 if (GET_CODE (memref
) == CONST
4414 && GET_CODE (XEXP (memref
, 0)) == PLUS
4415 && GET_CODE (XEXP (XEXP (memref
, 0), 1)) == CONST_INT
4416 && GET_CODE (XEXP (XEXP (memref
, 0), 0)) == SYMBOL_REF
4417 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (memref
, 0), 0)))
4419 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (memref
, 0), 1));
4420 rtx sym
= XEXP (XEXP (memref
, 0), 0);
4421 rtx base
= cfun
->machine
->base_reg
;
4422 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
4425 *x
= replace_equiv_address (*x
, plus_constant (addr
, off
));
4430 /* ... or a load-address type pattern. */
4431 if (GET_CODE (*x
) == SET
)
4433 rtx addrref
= SET_SRC (*x
);
4435 if (GET_CODE (addrref
) == SYMBOL_REF
4436 && CONSTANT_POOL_ADDRESS_P (addrref
))
4438 rtx base
= cfun
->machine
->base_reg
;
4439 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, addrref
, base
),
4442 SET_SRC (*x
) = addr
;
4446 if (GET_CODE (addrref
) == CONST
4447 && GET_CODE (XEXP (addrref
, 0)) == PLUS
4448 && GET_CODE (XEXP (XEXP (addrref
, 0), 1)) == CONST_INT
4449 && GET_CODE (XEXP (XEXP (addrref
, 0), 0)) == SYMBOL_REF
4450 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (addrref
, 0), 0)))
4452 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (addrref
, 0), 1));
4453 rtx sym
= XEXP (XEXP (addrref
, 0), 0);
4454 rtx base
= cfun
->machine
->base_reg
;
4455 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
4458 SET_SRC (*x
) = plus_constant (addr
, off
);
4463 /* Annotate LTREL_BASE as well. */
4464 if (GET_CODE (*x
) == UNSPEC
4465 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
4467 rtx base
= cfun
->machine
->base_reg
;
4468 *x
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XVECEXP (*x
, 0, 0), base
),
4473 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
4474 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
4478 annotate_constant_pool_refs (&XEXP (*x
, i
));
4480 else if (fmt
[i
] == 'E')
4482 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
4483 annotate_constant_pool_refs (&XVECEXP (*x
, i
, j
));
4488 /* Split all branches that exceed the maximum distance.
4489 Returns true if this created a new literal pool entry. */
4492 s390_split_branches (void)
4494 rtx temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
4495 int new_literal
= 0, ret
;
4496 rtx insn
, pat
, tmp
, target
;
4499 /* We need correct insn addresses. */
4501 shorten_branches (get_insns ());
4503 /* Find all branches that exceed 64KB, and split them. */
4505 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
4507 if (GET_CODE (insn
) != JUMP_INSN
)
4510 pat
= PATTERN (insn
);
4511 if (GET_CODE (pat
) == PARALLEL
&& XVECLEN (pat
, 0) > 2)
4512 pat
= XVECEXP (pat
, 0, 0);
4513 if (GET_CODE (pat
) != SET
|| SET_DEST (pat
) != pc_rtx
)
4516 if (GET_CODE (SET_SRC (pat
)) == LABEL_REF
)
4518 label
= &SET_SRC (pat
);
4520 else if (GET_CODE (SET_SRC (pat
)) == IF_THEN_ELSE
)
4522 if (GET_CODE (XEXP (SET_SRC (pat
), 1)) == LABEL_REF
)
4523 label
= &XEXP (SET_SRC (pat
), 1);
4524 else if (GET_CODE (XEXP (SET_SRC (pat
), 2)) == LABEL_REF
)
4525 label
= &XEXP (SET_SRC (pat
), 2);
4532 if (get_attr_length (insn
) <= 4)
4535 /* We are going to use the return register as scratch register,
4536 make sure it will be saved/restored by the prologue/epilogue. */
4537 cfun_frame_layout
.save_return_addr_p
= 1;
4542 tmp
= force_const_mem (Pmode
, *label
);
4543 tmp
= emit_insn_before (gen_rtx_SET (Pmode
, temp_reg
, tmp
), insn
);
4544 INSN_ADDRESSES_NEW (tmp
, -1);
4545 annotate_constant_pool_refs (&PATTERN (tmp
));
4552 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, *label
),
4553 UNSPEC_LTREL_OFFSET
);
4554 target
= gen_rtx_CONST (Pmode
, target
);
4555 target
= force_const_mem (Pmode
, target
);
4556 tmp
= emit_insn_before (gen_rtx_SET (Pmode
, temp_reg
, target
), insn
);
4557 INSN_ADDRESSES_NEW (tmp
, -1);
4558 annotate_constant_pool_refs (&PATTERN (tmp
));
4560 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XEXP (target
, 0),
4561 cfun
->machine
->base_reg
),
4563 target
= gen_rtx_PLUS (Pmode
, temp_reg
, target
);
4566 ret
= validate_change (insn
, label
, target
, 0);
4574 /* Find an annotated literal pool symbol referenced in RTX X,
4575 and store it at REF. Will abort if X contains references to
4576 more than one such pool symbol; multiple references to the same
4577 symbol are allowed, however.
4579 The rtx pointed to by REF must be initialized to NULL_RTX
4580 by the caller before calling this routine. */
4583 find_constant_pool_ref (rtx x
, rtx
*ref
)
4588 /* Ignore LTREL_BASE references. */
4589 if (GET_CODE (x
) == UNSPEC
4590 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
4592 /* Likewise POOL_ENTRY insns. */
4593 if (GET_CODE (x
) == UNSPEC_VOLATILE
4594 && XINT (x
, 1) == UNSPECV_POOL_ENTRY
)
4597 gcc_assert (GET_CODE (x
) != SYMBOL_REF
4598 || !CONSTANT_POOL_ADDRESS_P (x
));
4600 if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_LTREF
)
4602 rtx sym
= XVECEXP (x
, 0, 0);
4603 gcc_assert (GET_CODE (sym
) == SYMBOL_REF
4604 && CONSTANT_POOL_ADDRESS_P (sym
));
4606 if (*ref
== NULL_RTX
)
4609 gcc_assert (*ref
== sym
);
4614 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
4615 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
4619 find_constant_pool_ref (XEXP (x
, i
), ref
);
4621 else if (fmt
[i
] == 'E')
4623 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
4624 find_constant_pool_ref (XVECEXP (x
, i
, j
), ref
);
4629 /* Replace every reference to the annotated literal pool
4630 symbol REF in X by its base plus OFFSET. */
4633 replace_constant_pool_ref (rtx
*x
, rtx ref
, rtx offset
)
4638 gcc_assert (*x
!= ref
);
4640 if (GET_CODE (*x
) == UNSPEC
4641 && XINT (*x
, 1) == UNSPEC_LTREF
4642 && XVECEXP (*x
, 0, 0) == ref
)
4644 *x
= gen_rtx_PLUS (Pmode
, XVECEXP (*x
, 0, 1), offset
);
4648 if (GET_CODE (*x
) == PLUS
4649 && GET_CODE (XEXP (*x
, 1)) == CONST_INT
4650 && GET_CODE (XEXP (*x
, 0)) == UNSPEC
4651 && XINT (XEXP (*x
, 0), 1) == UNSPEC_LTREF
4652 && XVECEXP (XEXP (*x
, 0), 0, 0) == ref
)
4654 rtx addr
= gen_rtx_PLUS (Pmode
, XVECEXP (XEXP (*x
, 0), 0, 1), offset
);
4655 *x
= plus_constant (addr
, INTVAL (XEXP (*x
, 1)));
4659 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
4660 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
4664 replace_constant_pool_ref (&XEXP (*x
, i
), ref
, offset
);
4666 else if (fmt
[i
] == 'E')
4668 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
4669 replace_constant_pool_ref (&XVECEXP (*x
, i
, j
), ref
, offset
);
4674 /* Check whether X contains an UNSPEC_LTREL_BASE.
4675 Return its constant pool symbol if found, NULL_RTX otherwise. */
4678 find_ltrel_base (rtx x
)
4683 if (GET_CODE (x
) == UNSPEC
4684 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
4685 return XVECEXP (x
, 0, 0);
4687 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
4688 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
4692 rtx fnd
= find_ltrel_base (XEXP (x
, i
));
4696 else if (fmt
[i
] == 'E')
4698 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
4700 rtx fnd
= find_ltrel_base (XVECEXP (x
, i
, j
));
4710 /* Replace any occurrence of UNSPEC_LTREL_BASE in X with its base. */
4713 replace_ltrel_base (rtx
*x
)
4718 if (GET_CODE (*x
) == UNSPEC
4719 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
4721 *x
= XVECEXP (*x
, 0, 1);
4725 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
4726 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
4730 replace_ltrel_base (&XEXP (*x
, i
));
4732 else if (fmt
[i
] == 'E')
4734 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
4735 replace_ltrel_base (&XVECEXP (*x
, i
, j
));
4741 /* We keep a list of constants which we have to add to internal
4742 constant tables in the middle of large functions. */
4744 #define NR_C_MODES 7
4745 enum machine_mode constant_modes
[NR_C_MODES
] =
4756 struct constant
*next
;
4761 struct constant_pool
4763 struct constant_pool
*next
;
4768 struct constant
*constants
[NR_C_MODES
];
4769 struct constant
*execute
;
4774 /* Allocate new constant_pool structure. */
4776 static struct constant_pool
*
4777 s390_alloc_pool (void)
4779 struct constant_pool
*pool
;
4782 pool
= (struct constant_pool
*) xmalloc (sizeof *pool
);
4784 for (i
= 0; i
< NR_C_MODES
; i
++)
4785 pool
->constants
[i
] = NULL
;
4787 pool
->execute
= NULL
;
4788 pool
->label
= gen_label_rtx ();
4789 pool
->first_insn
= NULL_RTX
;
4790 pool
->pool_insn
= NULL_RTX
;
4791 pool
->insns
= BITMAP_ALLOC (NULL
);
4797 /* Create new constant pool covering instructions starting at INSN
4798 and chain it to the end of POOL_LIST. */
4800 static struct constant_pool
*
4801 s390_start_pool (struct constant_pool
**pool_list
, rtx insn
)
4803 struct constant_pool
*pool
, **prev
;
4805 pool
= s390_alloc_pool ();
4806 pool
->first_insn
= insn
;
4808 for (prev
= pool_list
; *prev
; prev
= &(*prev
)->next
)
4815 /* End range of instructions covered by POOL at INSN and emit
4816 placeholder insn representing the pool. */
4819 s390_end_pool (struct constant_pool
*pool
, rtx insn
)
4821 rtx pool_size
= GEN_INT (pool
->size
+ 8 /* alignment slop */);
4824 insn
= get_last_insn ();
4826 pool
->pool_insn
= emit_insn_after (gen_pool (pool_size
), insn
);
4827 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
4830 /* Add INSN to the list of insns covered by POOL. */
4833 s390_add_pool_insn (struct constant_pool
*pool
, rtx insn
)
4835 bitmap_set_bit (pool
->insns
, INSN_UID (insn
));
4838 /* Return pool out of POOL_LIST that covers INSN. */
4840 static struct constant_pool
*
4841 s390_find_pool (struct constant_pool
*pool_list
, rtx insn
)
4843 struct constant_pool
*pool
;
4845 for (pool
= pool_list
; pool
; pool
= pool
->next
)
4846 if (bitmap_bit_p (pool
->insns
, INSN_UID (insn
)))
4852 /* Add constant VAL of mode MODE to the constant pool POOL. */
4855 s390_add_constant (struct constant_pool
*pool
, rtx val
, enum machine_mode mode
)
4860 for (i
= 0; i
< NR_C_MODES
; i
++)
4861 if (constant_modes
[i
] == mode
)
4863 gcc_assert (i
!= NR_C_MODES
);
4865 for (c
= pool
->constants
[i
]; c
!= NULL
; c
= c
->next
)
4866 if (rtx_equal_p (val
, c
->value
))
4871 c
= (struct constant
*) xmalloc (sizeof *c
);
4873 c
->label
= gen_label_rtx ();
4874 c
->next
= pool
->constants
[i
];
4875 pool
->constants
[i
] = c
;
4876 pool
->size
+= GET_MODE_SIZE (mode
);
4880 /* Find constant VAL of mode MODE in the constant pool POOL.
4881 Return an RTX describing the distance from the start of
4882 the pool to the location of the new constant. */
4885 s390_find_constant (struct constant_pool
*pool
, rtx val
,
4886 enum machine_mode mode
)
4892 for (i
= 0; i
< NR_C_MODES
; i
++)
4893 if (constant_modes
[i
] == mode
)
4895 gcc_assert (i
!= NR_C_MODES
);
4897 for (c
= pool
->constants
[i
]; c
!= NULL
; c
= c
->next
)
4898 if (rtx_equal_p (val
, c
->value
))
4903 offset
= gen_rtx_MINUS (Pmode
, gen_rtx_LABEL_REF (Pmode
, c
->label
),
4904 gen_rtx_LABEL_REF (Pmode
, pool
->label
));
4905 offset
= gen_rtx_CONST (Pmode
, offset
);
4909 /* Check whether INSN is an execute. Return the label_ref to its
4910 execute target template if so, NULL_RTX otherwise. */
4913 s390_execute_label (rtx insn
)
4915 if (GET_CODE (insn
) == INSN
4916 && GET_CODE (PATTERN (insn
)) == PARALLEL
4917 && GET_CODE (XVECEXP (PATTERN (insn
), 0, 0)) == UNSPEC
4918 && XINT (XVECEXP (PATTERN (insn
), 0, 0), 1) == UNSPEC_EXECUTE
)
4919 return XVECEXP (XVECEXP (PATTERN (insn
), 0, 0), 0, 2);
4924 /* Add execute target for INSN to the constant pool POOL. */
4927 s390_add_execute (struct constant_pool
*pool
, rtx insn
)
4931 for (c
= pool
->execute
; c
!= NULL
; c
= c
->next
)
4932 if (INSN_UID (insn
) == INSN_UID (c
->value
))
4937 c
= (struct constant
*) xmalloc (sizeof *c
);
4939 c
->label
= gen_label_rtx ();
4940 c
->next
= pool
->execute
;
4946 /* Find execute target for INSN in the constant pool POOL.
4947 Return an RTX describing the distance from the start of
4948 the pool to the location of the execute target. */
4951 s390_find_execute (struct constant_pool
*pool
, rtx insn
)
4956 for (c
= pool
->execute
; c
!= NULL
; c
= c
->next
)
4957 if (INSN_UID (insn
) == INSN_UID (c
->value
))
4962 offset
= gen_rtx_MINUS (Pmode
, gen_rtx_LABEL_REF (Pmode
, c
->label
),
4963 gen_rtx_LABEL_REF (Pmode
, pool
->label
));
4964 offset
= gen_rtx_CONST (Pmode
, offset
);
4968 /* For an execute INSN, extract the execute target template. */
4971 s390_execute_target (rtx insn
)
4973 rtx pattern
= PATTERN (insn
);
4974 gcc_assert (s390_execute_label (insn
));
4976 if (XVECLEN (pattern
, 0) == 2)
4978 pattern
= copy_rtx (XVECEXP (pattern
, 0, 1));
4982 rtvec vec
= rtvec_alloc (XVECLEN (pattern
, 0) - 1);
4985 for (i
= 0; i
< XVECLEN (pattern
, 0) - 1; i
++)
4986 RTVEC_ELT (vec
, i
) = copy_rtx (XVECEXP (pattern
, 0, i
+ 1));
4988 pattern
= gen_rtx_PARALLEL (VOIDmode
, vec
);
4994 /* Indicate that INSN cannot be duplicated. This is the case for
4995 execute insns that carry a unique label. */
4998 s390_cannot_copy_insn_p (rtx insn
)
5000 rtx label
= s390_execute_label (insn
);
5001 return label
&& label
!= const0_rtx
;
5004 /* Dump out the constants in POOL. If REMOTE_LABEL is true,
5005 do not emit the pool base label. */
5008 s390_dump_pool (struct constant_pool
*pool
, bool remote_label
)
5011 rtx insn
= pool
->pool_insn
;
5014 /* Switch to rodata section. */
5015 if (TARGET_CPU_ZARCH
)
5017 insn
= emit_insn_after (gen_pool_section_start (), insn
);
5018 INSN_ADDRESSES_NEW (insn
, -1);
5021 /* Ensure minimum pool alignment. */
5022 if (TARGET_CPU_ZARCH
)
5023 insn
= emit_insn_after (gen_pool_align (GEN_INT (8)), insn
);
5025 insn
= emit_insn_after (gen_pool_align (GEN_INT (4)), insn
);
5026 INSN_ADDRESSES_NEW (insn
, -1);
5028 /* Emit pool base label. */
5031 insn
= emit_label_after (pool
->label
, insn
);
5032 INSN_ADDRESSES_NEW (insn
, -1);
5035 /* Dump constants in descending alignment requirement order,
5036 ensuring proper alignment for every constant. */
5037 for (i
= 0; i
< NR_C_MODES
; i
++)
5038 for (c
= pool
->constants
[i
]; c
; c
= c
->next
)
5040 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
5041 rtx value
= c
->value
;
5042 if (GET_CODE (value
) == CONST
5043 && GET_CODE (XEXP (value
, 0)) == UNSPEC
5044 && XINT (XEXP (value
, 0), 1) == UNSPEC_LTREL_OFFSET
5045 && XVECLEN (XEXP (value
, 0), 0) == 1)
5047 value
= gen_rtx_MINUS (Pmode
, XVECEXP (XEXP (value
, 0), 0, 0),
5048 gen_rtx_LABEL_REF (VOIDmode
, pool
->label
));
5049 value
= gen_rtx_CONST (VOIDmode
, value
);
5052 insn
= emit_label_after (c
->label
, insn
);
5053 INSN_ADDRESSES_NEW (insn
, -1);
5055 value
= gen_rtx_UNSPEC_VOLATILE (constant_modes
[i
],
5056 gen_rtvec (1, value
),
5057 UNSPECV_POOL_ENTRY
);
5058 insn
= emit_insn_after (value
, insn
);
5059 INSN_ADDRESSES_NEW (insn
, -1);
5062 /* Ensure minimum alignment for instructions. */
5063 insn
= emit_insn_after (gen_pool_align (GEN_INT (2)), insn
);
5064 INSN_ADDRESSES_NEW (insn
, -1);
5066 /* Output in-pool execute template insns. */
5067 for (c
= pool
->execute
; c
; c
= c
->next
)
5069 insn
= emit_label_after (c
->label
, insn
);
5070 INSN_ADDRESSES_NEW (insn
, -1);
5072 insn
= emit_insn_after (s390_execute_target (c
->value
), insn
);
5073 INSN_ADDRESSES_NEW (insn
, -1);
5076 /* Switch back to previous section. */
5077 if (TARGET_CPU_ZARCH
)
5079 insn
= emit_insn_after (gen_pool_section_end (), insn
);
5080 INSN_ADDRESSES_NEW (insn
, -1);
5083 insn
= emit_barrier_after (insn
);
5084 INSN_ADDRESSES_NEW (insn
, -1);
5086 /* Remove placeholder insn. */
5087 remove_insn (pool
->pool_insn
);
5090 /* Free all memory used by POOL. */
5093 s390_free_pool (struct constant_pool
*pool
)
5095 struct constant
*c
, *next
;
5098 for (i
= 0; i
< NR_C_MODES
; i
++)
5099 for (c
= pool
->constants
[i
]; c
; c
= next
)
5105 for (c
= pool
->execute
; c
; c
= next
)
5111 BITMAP_FREE (pool
->insns
);
5116 /* Collect main literal pool. Return NULL on overflow. */
5118 static struct constant_pool
*
5119 s390_mainpool_start (void)
5121 struct constant_pool
*pool
;
5124 pool
= s390_alloc_pool ();
5126 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5128 if (GET_CODE (insn
) == INSN
5129 && GET_CODE (PATTERN (insn
)) == SET
5130 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC_VOLATILE
5131 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPECV_MAIN_POOL
)
5133 gcc_assert (!pool
->pool_insn
);
5134 pool
->pool_insn
= insn
;
5137 if (!TARGET_CPU_ZARCH
&& s390_execute_label (insn
))
5139 s390_add_execute (pool
, insn
);
5141 else if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5143 rtx pool_ref
= NULL_RTX
;
5144 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5147 rtx constant
= get_pool_constant (pool_ref
);
5148 enum machine_mode mode
= get_pool_mode (pool_ref
);
5149 s390_add_constant (pool
, constant
, mode
);
5154 gcc_assert (pool
->pool_insn
|| pool
->size
== 0);
5156 if (pool
->size
>= 4096)
5158 /* We're going to chunkify the pool, so remove the main
5159 pool placeholder insn. */
5160 remove_insn (pool
->pool_insn
);
5162 s390_free_pool (pool
);
5169 /* POOL holds the main literal pool as collected by s390_mainpool_start.
5170 Modify the current function to output the pool constants as well as
5171 the pool register setup instruction. */
5174 s390_mainpool_finish (struct constant_pool
*pool
)
5176 rtx base_reg
= cfun
->machine
->base_reg
;
5179 /* If the pool is empty, we're done. */
5180 if (pool
->size
== 0)
5182 /* We don't actually need a base register after all. */
5183 cfun
->machine
->base_reg
= NULL_RTX
;
5185 if (pool
->pool_insn
)
5186 remove_insn (pool
->pool_insn
);
5187 s390_free_pool (pool
);
5191 /* We need correct insn addresses. */
5192 shorten_branches (get_insns ());
5194 /* On zSeries, we use a LARL to load the pool register. The pool is
5195 located in the .rodata section, so we emit it after the function. */
5196 if (TARGET_CPU_ZARCH
)
5198 insn
= gen_main_base_64 (base_reg
, pool
->label
);
5199 insn
= emit_insn_after (insn
, pool
->pool_insn
);
5200 INSN_ADDRESSES_NEW (insn
, -1);
5201 remove_insn (pool
->pool_insn
);
5203 insn
= get_last_insn ();
5204 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
5205 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
5207 s390_dump_pool (pool
, 0);
5210 /* On S/390, if the total size of the function's code plus literal pool
5211 does not exceed 4096 bytes, we use BASR to set up a function base
5212 pointer, and emit the literal pool at the end of the function. */
5213 else if (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
5214 + pool
->size
+ 8 /* alignment slop */ < 4096)
5216 insn
= gen_main_base_31_small (base_reg
, pool
->label
);
5217 insn
= emit_insn_after (insn
, pool
->pool_insn
);
5218 INSN_ADDRESSES_NEW (insn
, -1);
5219 remove_insn (pool
->pool_insn
);
5221 insn
= emit_label_after (pool
->label
, insn
);
5222 INSN_ADDRESSES_NEW (insn
, -1);
5224 insn
= get_last_insn ();
5225 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
5226 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
5228 s390_dump_pool (pool
, 1);
5231 /* Otherwise, we emit an inline literal pool and use BASR to branch
5232 over it, setting up the pool register at the same time. */
5235 rtx pool_end
= gen_label_rtx ();
5237 insn
= gen_main_base_31_large (base_reg
, pool
->label
, pool_end
);
5238 insn
= emit_insn_after (insn
, pool
->pool_insn
);
5239 INSN_ADDRESSES_NEW (insn
, -1);
5240 remove_insn (pool
->pool_insn
);
5242 insn
= emit_label_after (pool
->label
, insn
);
5243 INSN_ADDRESSES_NEW (insn
, -1);
5245 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
5246 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
5248 insn
= emit_label_after (pool_end
, pool
->pool_insn
);
5249 INSN_ADDRESSES_NEW (insn
, -1);
5251 s390_dump_pool (pool
, 1);
5255 /* Replace all literal pool references. */
5257 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5260 replace_ltrel_base (&PATTERN (insn
));
5262 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5264 rtx addr
, pool_ref
= NULL_RTX
;
5265 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5268 if (s390_execute_label (insn
))
5269 addr
= s390_find_execute (pool
, insn
);
5271 addr
= s390_find_constant (pool
, get_pool_constant (pool_ref
),
5272 get_pool_mode (pool_ref
));
5274 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
5275 INSN_CODE (insn
) = -1;
5281 /* Free the pool. */
5282 s390_free_pool (pool
);
5285 /* POOL holds the main literal pool as collected by s390_mainpool_start.
5286 We have decided we cannot use this pool, so revert all changes
5287 to the current function that were done by s390_mainpool_start. */
5289 s390_mainpool_cancel (struct constant_pool
*pool
)
5291 /* We didn't actually change the instruction stream, so simply
5292 free the pool memory. */
5293 s390_free_pool (pool
);
5297 /* Chunkify the literal pool. */
5299 #define S390_POOL_CHUNK_MIN 0xc00
5300 #define S390_POOL_CHUNK_MAX 0xe00
5302 static struct constant_pool
*
5303 s390_chunkify_start (void)
5305 struct constant_pool
*curr_pool
= NULL
, *pool_list
= NULL
;
5308 rtx pending_ltrel
= NULL_RTX
;
5311 rtx (*gen_reload_base
) (rtx
, rtx
) =
5312 TARGET_CPU_ZARCH
? gen_reload_base_64
: gen_reload_base_31
;
5315 /* We need correct insn addresses. */
5317 shorten_branches (get_insns ());
5319 /* Scan all insns and move literals to pool chunks. */
5321 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5323 /* Check for pending LTREL_BASE. */
5326 rtx ltrel_base
= find_ltrel_base (PATTERN (insn
));
5329 gcc_assert (ltrel_base
== pending_ltrel
);
5330 pending_ltrel
= NULL_RTX
;
5334 if (!TARGET_CPU_ZARCH
&& s390_execute_label (insn
))
5337 curr_pool
= s390_start_pool (&pool_list
, insn
);
5339 s390_add_execute (curr_pool
, insn
);
5340 s390_add_pool_insn (curr_pool
, insn
);
5342 else if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5344 rtx pool_ref
= NULL_RTX
;
5345 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5348 rtx constant
= get_pool_constant (pool_ref
);
5349 enum machine_mode mode
= get_pool_mode (pool_ref
);
5352 curr_pool
= s390_start_pool (&pool_list
, insn
);
5354 s390_add_constant (curr_pool
, constant
, mode
);
5355 s390_add_pool_insn (curr_pool
, insn
);
5357 /* Don't split the pool chunk between a LTREL_OFFSET load
5358 and the corresponding LTREL_BASE. */
5359 if (GET_CODE (constant
) == CONST
5360 && GET_CODE (XEXP (constant
, 0)) == UNSPEC
5361 && XINT (XEXP (constant
, 0), 1) == UNSPEC_LTREL_OFFSET
)
5363 gcc_assert (!pending_ltrel
);
5364 pending_ltrel
= pool_ref
;
5369 if (GET_CODE (insn
) == JUMP_INSN
|| GET_CODE (insn
) == CODE_LABEL
)
5372 s390_add_pool_insn (curr_pool
, insn
);
5373 /* An LTREL_BASE must follow within the same basic block. */
5374 gcc_assert (!pending_ltrel
);
5378 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn
)
5379 || INSN_ADDRESSES (INSN_UID (insn
)) == -1)
5382 if (TARGET_CPU_ZARCH
)
5384 if (curr_pool
->size
< S390_POOL_CHUNK_MAX
)
5387 s390_end_pool (curr_pool
, NULL_RTX
);
5392 int chunk_size
= INSN_ADDRESSES (INSN_UID (insn
))
5393 - INSN_ADDRESSES (INSN_UID (curr_pool
->first_insn
))
5396 /* We will later have to insert base register reload insns.
5397 Those will have an effect on code size, which we need to
5398 consider here. This calculation makes rather pessimistic
5399 worst-case assumptions. */
5400 if (GET_CODE (insn
) == CODE_LABEL
)
5403 if (chunk_size
< S390_POOL_CHUNK_MIN
5404 && curr_pool
->size
< S390_POOL_CHUNK_MIN
)
5407 /* Pool chunks can only be inserted after BARRIERs ... */
5408 if (GET_CODE (insn
) == BARRIER
)
5410 s390_end_pool (curr_pool
, insn
);
5415 /* ... so if we don't find one in time, create one. */
5416 else if ((chunk_size
> S390_POOL_CHUNK_MAX
5417 || curr_pool
->size
> S390_POOL_CHUNK_MAX
))
5419 rtx label
, jump
, barrier
;
5421 /* We can insert the barrier only after a 'real' insn. */
5422 if (GET_CODE (insn
) != INSN
&& GET_CODE (insn
) != CALL_INSN
)
5424 if (get_attr_length (insn
) == 0)
5427 /* Don't separate LTREL_BASE from the corresponding
5428 LTREL_OFFSET load. */
5432 label
= gen_label_rtx ();
5433 jump
= emit_jump_insn_after (gen_jump (label
), insn
);
5434 barrier
= emit_barrier_after (jump
);
5435 insn
= emit_label_after (label
, barrier
);
5436 JUMP_LABEL (jump
) = label
;
5437 LABEL_NUSES (label
) = 1;
5439 INSN_ADDRESSES_NEW (jump
, -1);
5440 INSN_ADDRESSES_NEW (barrier
, -1);
5441 INSN_ADDRESSES_NEW (insn
, -1);
5443 s390_end_pool (curr_pool
, barrier
);
5451 s390_end_pool (curr_pool
, NULL_RTX
);
5452 gcc_assert (!pending_ltrel
);
5454 /* Find all labels that are branched into
5455 from an insn belonging to a different chunk. */
5457 far_labels
= BITMAP_ALLOC (NULL
);
5459 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5461 /* Labels marked with LABEL_PRESERVE_P can be target
5462 of non-local jumps, so we have to mark them.
5463 The same holds for named labels.
5465 Don't do that, however, if it is the label before
5468 if (GET_CODE (insn
) == CODE_LABEL
5469 && (LABEL_PRESERVE_P (insn
) || LABEL_NAME (insn
)))
5471 rtx vec_insn
= next_real_insn (insn
);
5472 rtx vec_pat
= vec_insn
&& GET_CODE (vec_insn
) == JUMP_INSN
?
5473 PATTERN (vec_insn
) : NULL_RTX
;
5475 || !(GET_CODE (vec_pat
) == ADDR_VEC
5476 || GET_CODE (vec_pat
) == ADDR_DIFF_VEC
))
5477 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (insn
));
5480 /* If we have a direct jump (conditional or unconditional)
5481 or a casesi jump, check all potential targets. */
5482 else if (GET_CODE (insn
) == JUMP_INSN
)
5484 rtx pat
= PATTERN (insn
);
5485 if (GET_CODE (pat
) == PARALLEL
&& XVECLEN (pat
, 0) > 2)
5486 pat
= XVECEXP (pat
, 0, 0);
5488 if (GET_CODE (pat
) == SET
)
5490 rtx label
= JUMP_LABEL (insn
);
5493 if (s390_find_pool (pool_list
, label
)
5494 != s390_find_pool (pool_list
, insn
))
5495 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
5498 else if (GET_CODE (pat
) == PARALLEL
5499 && XVECLEN (pat
, 0) == 2
5500 && GET_CODE (XVECEXP (pat
, 0, 0)) == SET
5501 && GET_CODE (XVECEXP (pat
, 0, 1)) == USE
5502 && GET_CODE (XEXP (XVECEXP (pat
, 0, 1), 0)) == LABEL_REF
)
5504 /* Find the jump table used by this casesi jump. */
5505 rtx vec_label
= XEXP (XEXP (XVECEXP (pat
, 0, 1), 0), 0);
5506 rtx vec_insn
= next_real_insn (vec_label
);
5507 rtx vec_pat
= vec_insn
&& GET_CODE (vec_insn
) == JUMP_INSN
?
5508 PATTERN (vec_insn
) : NULL_RTX
;
5510 && (GET_CODE (vec_pat
) == ADDR_VEC
5511 || GET_CODE (vec_pat
) == ADDR_DIFF_VEC
))
5513 int i
, diff_p
= GET_CODE (vec_pat
) == ADDR_DIFF_VEC
;
5515 for (i
= 0; i
< XVECLEN (vec_pat
, diff_p
); i
++)
5517 rtx label
= XEXP (XVECEXP (vec_pat
, diff_p
, i
), 0);
5519 if (s390_find_pool (pool_list
, label
)
5520 != s390_find_pool (pool_list
, insn
))
5521 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
5528 /* Insert base register reload insns before every pool. */
5530 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
5532 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
5534 rtx insn
= curr_pool
->first_insn
;
5535 INSN_ADDRESSES_NEW (emit_insn_before (new_insn
, insn
), -1);
5538 /* Insert base register reload insns at every far label. */
5540 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5541 if (GET_CODE (insn
) == CODE_LABEL
5542 && bitmap_bit_p (far_labels
, CODE_LABEL_NUMBER (insn
)))
5544 struct constant_pool
*pool
= s390_find_pool (pool_list
, insn
);
5547 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
5549 INSN_ADDRESSES_NEW (emit_insn_after (new_insn
, insn
), -1);
5554 BITMAP_FREE (far_labels
);
5557 /* Recompute insn addresses. */
5559 init_insn_lengths ();
5560 shorten_branches (get_insns ());
5565 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
5566 After we have decided to use this list, finish implementing
5567 all changes to the current function as required. */
5570 s390_chunkify_finish (struct constant_pool
*pool_list
)
5572 struct constant_pool
*curr_pool
= NULL
;
5576 /* Replace all literal pool references. */
5578 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5581 replace_ltrel_base (&PATTERN (insn
));
5583 curr_pool
= s390_find_pool (pool_list
, insn
);
5587 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5589 rtx addr
, pool_ref
= NULL_RTX
;
5590 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5593 if (s390_execute_label (insn
))
5594 addr
= s390_find_execute (curr_pool
, insn
);
5596 addr
= s390_find_constant (curr_pool
,
5597 get_pool_constant (pool_ref
),
5598 get_pool_mode (pool_ref
));
5600 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
5601 INSN_CODE (insn
) = -1;
5606 /* Dump out all literal pools. */
5608 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
5609 s390_dump_pool (curr_pool
, 0);
5611 /* Free pool list. */
5615 struct constant_pool
*next
= pool_list
->next
;
5616 s390_free_pool (pool_list
);
5621 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
5622 We have decided we cannot use this list, so revert all changes
5623 to the current function that were done by s390_chunkify_start. */
5626 s390_chunkify_cancel (struct constant_pool
*pool_list
)
5628 struct constant_pool
*curr_pool
= NULL
;
5631 /* Remove all pool placeholder insns. */
5633 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
5635 /* Did we insert an extra barrier? Remove it. */
5636 rtx barrier
= PREV_INSN (curr_pool
->pool_insn
);
5637 rtx jump
= barrier
? PREV_INSN (barrier
) : NULL_RTX
;
5638 rtx label
= NEXT_INSN (curr_pool
->pool_insn
);
5640 if (jump
&& GET_CODE (jump
) == JUMP_INSN
5641 && barrier
&& GET_CODE (barrier
) == BARRIER
5642 && label
&& GET_CODE (label
) == CODE_LABEL
5643 && GET_CODE (PATTERN (jump
)) == SET
5644 && SET_DEST (PATTERN (jump
)) == pc_rtx
5645 && GET_CODE (SET_SRC (PATTERN (jump
))) == LABEL_REF
5646 && XEXP (SET_SRC (PATTERN (jump
)), 0) == label
)
5649 remove_insn (barrier
);
5650 remove_insn (label
);
5653 remove_insn (curr_pool
->pool_insn
);
5656 /* Remove all base register reload insns. */
5658 for (insn
= get_insns (); insn
; )
5660 rtx next_insn
= NEXT_INSN (insn
);
5662 if (GET_CODE (insn
) == INSN
5663 && GET_CODE (PATTERN (insn
)) == SET
5664 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC
5665 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPEC_RELOAD_BASE
)
5671 /* Free pool list. */
5675 struct constant_pool
*next
= pool_list
->next
;
5676 s390_free_pool (pool_list
);
5682 /* Output the constant pool entry EXP in mode MODE with alignment ALIGN. */
5685 s390_output_pool_entry (rtx exp
, enum machine_mode mode
, unsigned int align
)
5689 switch (GET_MODE_CLASS (mode
))
5692 gcc_assert (GET_CODE (exp
) == CONST_DOUBLE
);
5694 REAL_VALUE_FROM_CONST_DOUBLE (r
, exp
);
5695 assemble_real (r
, mode
, align
);
5699 assemble_integer (exp
, GET_MODE_SIZE (mode
), align
, 1);
5708 /* Return an RTL expression representing the value of the return address
5709 for the frame COUNT steps up from the current frame. FRAME is the
5710 frame pointer of that frame. */
5713 s390_return_addr_rtx (int count
, rtx frame ATTRIBUTE_UNUSED
)
5718 /* Without backchain, we fail for all but the current frame. */
5720 if (!TARGET_BACKCHAIN
&& count
> 0)
5723 /* For the current frame, we need to make sure the initial
5724 value of RETURN_REGNUM is actually saved. */
5728 /* On non-z architectures branch splitting could overwrite r14. */
5729 if (TARGET_CPU_ZARCH
)
5730 return get_hard_reg_initial_val (Pmode
, RETURN_REGNUM
);
5733 cfun_frame_layout
.save_return_addr_p
= true;
5734 return gen_rtx_MEM (Pmode
, return_address_pointer_rtx
);
5738 if (TARGET_PACKED_STACK
)
5739 offset
= -2 * UNITS_PER_WORD
;
5741 offset
= RETURN_REGNUM
* UNITS_PER_WORD
;
5743 addr
= plus_constant (frame
, offset
);
5744 addr
= memory_address (Pmode
, addr
);
5745 return gen_rtx_MEM (Pmode
, addr
);
5748 /* Return an RTL expression representing the back chain stored in
5749 the current stack frame. */
5752 s390_back_chain_rtx (void)
5756 gcc_assert (TARGET_BACKCHAIN
);
5758 if (TARGET_PACKED_STACK
)
5759 chain
= plus_constant (stack_pointer_rtx
,
5760 STACK_POINTER_OFFSET
- UNITS_PER_WORD
);
5762 chain
= stack_pointer_rtx
;
5764 chain
= gen_rtx_MEM (Pmode
, chain
);
5768 /* Find first call clobbered register unused in a function.
5769 This could be used as base register in a leaf function
5770 or for holding the return address before epilogue. */
5773 find_unused_clobbered_reg (void)
5776 for (i
= 0; i
< 6; i
++)
5777 if (!regs_ever_live
[i
])
5783 /* Helper function for s390_regs_ever_clobbered. Sets the fields in DATA for all
5784 clobbered hard regs in SETREG. */
5787 s390_reg_clobbered_rtx (rtx setreg
, rtx set_insn ATTRIBUTE_UNUSED
, void *data
)
5789 int *regs_ever_clobbered
= (int *)data
;
5790 unsigned int i
, regno
;
5791 enum machine_mode mode
= GET_MODE (setreg
);
5793 if (GET_CODE (setreg
) == SUBREG
)
5795 rtx inner
= SUBREG_REG (setreg
);
5796 if (!GENERAL_REG_P (inner
))
5798 regno
= subreg_regno (setreg
);
5800 else if (GENERAL_REG_P (setreg
))
5801 regno
= REGNO (setreg
);
5806 i
< regno
+ HARD_REGNO_NREGS (regno
, mode
);
5808 regs_ever_clobbered
[i
] = 1;
5811 /* Walks through all basic blocks of the current function looking
5812 for clobbered hard regs using s390_reg_clobbered_rtx. The fields
5813 of the passed integer array REGS_EVER_CLOBBERED are set to one for
5814 each of those regs. */
5817 s390_regs_ever_clobbered (int *regs_ever_clobbered
)
5823 memset (regs_ever_clobbered
, 0, 16 * sizeof (int));
5825 /* For non-leaf functions we have to consider all call clobbered regs to be
5827 if (!current_function_is_leaf
)
5829 for (i
= 0; i
< 16; i
++)
5830 regs_ever_clobbered
[i
] = call_really_used_regs
[i
];
5833 /* Make the "magic" eh_return registers live if necessary. For regs_ever_live
5834 this work is done by liveness analysis (mark_regs_live_at_end).
5835 Special care is needed for functions containing landing pads. Landing pads
5836 may use the eh registers, but the code which sets these registers is not
5837 contained in that function. Hence s390_regs_ever_clobbered is not able to
5838 deal with this automatically. */
5839 if (current_function_calls_eh_return
|| cfun
->machine
->has_landing_pad_p
)
5840 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; i
++)
5841 regs_ever_clobbered
[EH_RETURN_DATA_REGNO (i
)] = 1;
5843 /* For nonlocal gotos all call-saved registers have to be saved.
5844 This flag is also set for the unwinding code in libgcc.
5845 See expand_builtin_unwind_init. For regs_ever_live this is done by
5847 if (current_function_has_nonlocal_label
)
5848 for (i
= 0; i
< 16; i
++)
5849 if (!call_really_used_regs
[i
])
5850 regs_ever_clobbered
[i
] = 1;
5852 FOR_EACH_BB (cur_bb
)
5854 FOR_BB_INSNS (cur_bb
, cur_insn
)
5856 if (INSN_P (cur_insn
))
5857 note_stores (PATTERN (cur_insn
),
5858 s390_reg_clobbered_rtx
,
5859 regs_ever_clobbered
);
5864 /* Determine the frame area which actually has to be accessed
5865 in the function epilogue. The values are stored at the
5866 given pointers AREA_BOTTOM (address of the lowest used stack
5867 address) and AREA_TOP (address of the first item which does
5868 not belong to the stack frame). */
5871 s390_frame_area (int *area_bottom
, int *area_top
)
5879 if (cfun_frame_layout
.first_restore_gpr
!= -1)
5881 b
= (cfun_frame_layout
.gprs_offset
5882 + cfun_frame_layout
.first_restore_gpr
* UNITS_PER_WORD
);
5883 t
= b
+ (cfun_frame_layout
.last_restore_gpr
5884 - cfun_frame_layout
.first_restore_gpr
+ 1) * UNITS_PER_WORD
;
5887 if (TARGET_64BIT
&& cfun_save_high_fprs_p
)
5889 b
= MIN (b
, cfun_frame_layout
.f8_offset
);
5890 t
= MAX (t
, (cfun_frame_layout
.f8_offset
5891 + cfun_frame_layout
.high_fprs
* 8));
5895 for (i
= 2; i
< 4; i
++)
5896 if (cfun_fpr_bit_p (i
))
5898 b
= MIN (b
, cfun_frame_layout
.f4_offset
+ (i
- 2) * 8);
5899 t
= MAX (t
, cfun_frame_layout
.f4_offset
+ (i
- 1) * 8);
5906 /* Fill cfun->machine with info about register usage of current function.
5907 Return in CLOBBERED_REGS which GPRs are currently considered set. */
5910 s390_register_info (int clobbered_regs
[])
5914 /* fprs 8 - 15 are call saved for 64 Bit ABI. */
5915 cfun_frame_layout
.fpr_bitmap
= 0;
5916 cfun_frame_layout
.high_fprs
= 0;
5918 for (i
= 24; i
< 32; i
++)
5919 if (regs_ever_live
[i
] && !global_regs
[i
])
5921 cfun_set_fpr_bit (i
- 16);
5922 cfun_frame_layout
.high_fprs
++;
5925 /* Find first and last gpr to be saved. We trust regs_ever_live
5926 data, except that we don't save and restore global registers.
5928 Also, all registers with special meaning to the compiler need
5929 to be handled extra. */
5931 s390_regs_ever_clobbered (clobbered_regs
);
5933 for (i
= 0; i
< 16; i
++)
5934 clobbered_regs
[i
] = clobbered_regs
[i
] && !global_regs
[i
] && !fixed_regs
[i
];
5936 if (frame_pointer_needed
)
5937 clobbered_regs
[HARD_FRAME_POINTER_REGNUM
] = 1;
5940 clobbered_regs
[PIC_OFFSET_TABLE_REGNUM
]
5941 |= regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
];
5943 clobbered_regs
[BASE_REGNUM
]
5944 |= (cfun
->machine
->base_reg
5945 && REGNO (cfun
->machine
->base_reg
) == BASE_REGNUM
);
5947 clobbered_regs
[RETURN_REGNUM
]
5948 |= (!current_function_is_leaf
5949 || TARGET_TPF_PROFILING
5950 || cfun
->machine
->split_branches_pending_p
5951 || cfun_frame_layout
.save_return_addr_p
5952 || current_function_calls_eh_return
5953 || current_function_stdarg
);
5955 clobbered_regs
[STACK_POINTER_REGNUM
]
5956 |= (!current_function_is_leaf
5957 || TARGET_TPF_PROFILING
5958 || cfun_save_high_fprs_p
5959 || get_frame_size () > 0
5960 || current_function_calls_alloca
5961 || current_function_stdarg
);
5963 for (i
= 6; i
< 16; i
++)
5964 if (clobbered_regs
[i
])
5966 for (j
= 15; j
> i
; j
--)
5967 if (clobbered_regs
[j
])
5972 /* Nothing to save/restore. */
5973 cfun_frame_layout
.first_save_gpr
= -1;
5974 cfun_frame_layout
.first_restore_gpr
= -1;
5975 cfun_frame_layout
.last_save_gpr
= -1;
5976 cfun_frame_layout
.last_restore_gpr
= -1;
5980 /* Save / Restore from gpr i to j. */
5981 cfun_frame_layout
.first_save_gpr
= i
;
5982 cfun_frame_layout
.first_restore_gpr
= i
;
5983 cfun_frame_layout
.last_save_gpr
= j
;
5984 cfun_frame_layout
.last_restore_gpr
= j
;
5987 if (current_function_stdarg
)
5989 /* Varargs functions need to save gprs 2 to 6. */
5990 if (cfun
->va_list_gpr_size
5991 && current_function_args_info
.gprs
< GP_ARG_NUM_REG
)
5993 int min_gpr
= current_function_args_info
.gprs
;
5994 int max_gpr
= min_gpr
+ cfun
->va_list_gpr_size
;
5995 if (max_gpr
> GP_ARG_NUM_REG
)
5996 max_gpr
= GP_ARG_NUM_REG
;
5998 if (cfun_frame_layout
.first_save_gpr
== -1
5999 || cfun_frame_layout
.first_save_gpr
> 2 + min_gpr
)
6000 cfun_frame_layout
.first_save_gpr
= 2 + min_gpr
;
6002 if (cfun_frame_layout
.last_save_gpr
== -1
6003 || cfun_frame_layout
.last_save_gpr
< 2 + max_gpr
- 1)
6004 cfun_frame_layout
.last_save_gpr
= 2 + max_gpr
- 1;
6007 /* Mark f0, f2 for 31 bit and f0-f4 for 64 bit to be saved. */
6008 if (TARGET_HARD_FLOAT
&& cfun
->va_list_fpr_size
6009 && current_function_args_info
.fprs
< FP_ARG_NUM_REG
)
6011 int min_fpr
= current_function_args_info
.fprs
;
6012 int max_fpr
= min_fpr
+ cfun
->va_list_fpr_size
;
6013 if (max_fpr
> FP_ARG_NUM_REG
)
6014 max_fpr
= FP_ARG_NUM_REG
;
6016 /* ??? This is currently required to ensure proper location
6017 of the fpr save slots within the va_list save area. */
6018 if (TARGET_PACKED_STACK
)
6021 for (i
= min_fpr
; i
< max_fpr
; i
++)
6022 cfun_set_fpr_bit (i
);
6027 for (i
= 2; i
< 4; i
++)
6028 if (regs_ever_live
[i
+ 16] && !global_regs
[i
+ 16])
6029 cfun_set_fpr_bit (i
);
6032 /* Fill cfun->machine with info about frame of current function. */
6035 s390_frame_info (void)
6039 cfun_frame_layout
.frame_size
= get_frame_size ();
6040 if (!TARGET_64BIT
&& cfun_frame_layout
.frame_size
> 0x7fff0000)
6041 fatal_error ("total size of local variables exceeds architecture limit");
6043 if (!TARGET_PACKED_STACK
)
6045 cfun_frame_layout
.backchain_offset
= 0;
6046 cfun_frame_layout
.f0_offset
= 16 * UNITS_PER_WORD
;
6047 cfun_frame_layout
.f4_offset
= cfun_frame_layout
.f0_offset
+ 2 * 8;
6048 cfun_frame_layout
.f8_offset
= -cfun_frame_layout
.high_fprs
* 8;
6049 cfun_frame_layout
.gprs_offset
= (cfun_frame_layout
.first_save_gpr
6052 else if (TARGET_BACKCHAIN
) /* kernel stack layout */
6054 cfun_frame_layout
.backchain_offset
= (STACK_POINTER_OFFSET
6056 cfun_frame_layout
.gprs_offset
6057 = (cfun_frame_layout
.backchain_offset
6058 - (STACK_POINTER_REGNUM
- cfun_frame_layout
.first_save_gpr
+ 1)
6063 cfun_frame_layout
.f4_offset
6064 = (cfun_frame_layout
.gprs_offset
6065 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6067 cfun_frame_layout
.f0_offset
6068 = (cfun_frame_layout
.f4_offset
6069 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6073 /* On 31 bit we have to care about alignment of the
6074 floating point regs to provide fastest access. */
6075 cfun_frame_layout
.f0_offset
6076 = ((cfun_frame_layout
.gprs_offset
6077 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1))
6078 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6080 cfun_frame_layout
.f4_offset
6081 = (cfun_frame_layout
.f0_offset
6082 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6085 else /* no backchain */
6087 cfun_frame_layout
.f4_offset
6088 = (STACK_POINTER_OFFSET
6089 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6091 cfun_frame_layout
.f0_offset
6092 = (cfun_frame_layout
.f4_offset
6093 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6095 cfun_frame_layout
.gprs_offset
6096 = cfun_frame_layout
.f0_offset
- cfun_gprs_save_area_size
;
6099 if (current_function_is_leaf
6100 && !TARGET_TPF_PROFILING
6101 && cfun_frame_layout
.frame_size
== 0
6102 && !cfun_save_high_fprs_p
6103 && !current_function_calls_alloca
6104 && !current_function_stdarg
)
6107 if (!TARGET_PACKED_STACK
)
6108 cfun_frame_layout
.frame_size
+= (STACK_POINTER_OFFSET
6109 + current_function_outgoing_args_size
6110 + cfun_frame_layout
.high_fprs
* 8);
6113 if (TARGET_BACKCHAIN
)
6114 cfun_frame_layout
.frame_size
+= UNITS_PER_WORD
;
6116 /* No alignment trouble here because f8-f15 are only saved under
6118 cfun_frame_layout
.f8_offset
= (MIN (MIN (cfun_frame_layout
.f0_offset
,
6119 cfun_frame_layout
.f4_offset
),
6120 cfun_frame_layout
.gprs_offset
)
6121 - cfun_frame_layout
.high_fprs
* 8);
6123 cfun_frame_layout
.frame_size
+= cfun_frame_layout
.high_fprs
* 8;
6125 for (i
= 0; i
< 8; i
++)
6126 if (cfun_fpr_bit_p (i
))
6127 cfun_frame_layout
.frame_size
+= 8;
6129 cfun_frame_layout
.frame_size
+= cfun_gprs_save_area_size
;
6131 /* If under 31 bit an odd number of gprs has to be saved we have to adjust
6132 the frame size to sustain 8 byte alignment of stack frames. */
6133 cfun_frame_layout
.frame_size
= ((cfun_frame_layout
.frame_size
+
6134 STACK_BOUNDARY
/ BITS_PER_UNIT
- 1)
6135 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1));
6137 cfun_frame_layout
.frame_size
+= current_function_outgoing_args_size
;
6141 /* Generate frame layout. Fills in register and frame data for the current
6142 function in cfun->machine. This routine can be called multiple times;
6143 it will re-do the complete frame layout every time. */
6146 s390_init_frame_layout (void)
6148 HOST_WIDE_INT frame_size
;
6150 int clobbered_regs
[16];
6152 /* On S/390 machines, we may need to perform branch splitting, which
6153 will require both base and return address register. We have no
6154 choice but to assume we're going to need them until right at the
6155 end of the machine dependent reorg phase. */
6156 if (!TARGET_CPU_ZARCH
)
6157 cfun
->machine
->split_branches_pending_p
= true;
6161 frame_size
= cfun_frame_layout
.frame_size
;
6163 /* Try to predict whether we'll need the base register. */
6164 base_used
= cfun
->machine
->split_branches_pending_p
6165 || current_function_uses_const_pool
6166 || (!DISP_IN_RANGE (-frame_size
)
6167 && !CONST_OK_FOR_K (-frame_size
));
6169 /* Decide which register to use as literal pool base. In small
6170 leaf functions, try to use an unused call-clobbered register
6171 as base register to avoid save/restore overhead. */
6173 cfun
->machine
->base_reg
= NULL_RTX
;
6174 else if (current_function_is_leaf
&& !regs_ever_live
[5])
6175 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, 5);
6177 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
6179 s390_register_info (clobbered_regs
);
6182 while (frame_size
!= cfun_frame_layout
.frame_size
);
6185 /* Update frame layout. Recompute actual register save data based on
6186 current info and update regs_ever_live for the special registers.
6187 May be called multiple times, but may never cause *more* registers
6188 to be saved than s390_init_frame_layout allocated room for. */
6191 s390_update_frame_layout (void)
6193 int clobbered_regs
[16];
6195 s390_register_info (clobbered_regs
);
6197 regs_ever_live
[BASE_REGNUM
] = clobbered_regs
[BASE_REGNUM
];
6198 regs_ever_live
[RETURN_REGNUM
] = clobbered_regs
[RETURN_REGNUM
];
6199 regs_ever_live
[STACK_POINTER_REGNUM
] = clobbered_regs
[STACK_POINTER_REGNUM
];
6201 if (cfun
->machine
->base_reg
)
6202 regs_ever_live
[REGNO (cfun
->machine
->base_reg
)] = 1;
6205 /* Return true if register FROM can be eliminated via register TO. */
6208 s390_can_eliminate (int from
, int to
)
6210 gcc_assert (to
== STACK_POINTER_REGNUM
6211 || to
== HARD_FRAME_POINTER_REGNUM
);
6213 gcc_assert (from
== FRAME_POINTER_REGNUM
6214 || from
== ARG_POINTER_REGNUM
6215 || from
== RETURN_ADDRESS_POINTER_REGNUM
);
6217 /* Make sure we actually saved the return address. */
6218 if (from
== RETURN_ADDRESS_POINTER_REGNUM
)
6219 if (!current_function_calls_eh_return
6220 && !current_function_stdarg
6221 && !cfun_frame_layout
.save_return_addr_p
)
6227 /* Return offset between register FROM and TO initially after prolog. */
6230 s390_initial_elimination_offset (int from
, int to
)
6232 HOST_WIDE_INT offset
;
6235 /* ??? Why are we called for non-eliminable pairs? */
6236 if (!s390_can_eliminate (from
, to
))
6241 case FRAME_POINTER_REGNUM
:
6242 offset
= (get_frame_size()
6243 + STACK_POINTER_OFFSET
6244 + current_function_outgoing_args_size
);
6247 case ARG_POINTER_REGNUM
:
6248 s390_init_frame_layout ();
6249 offset
= cfun_frame_layout
.frame_size
+ STACK_POINTER_OFFSET
;
6252 case RETURN_ADDRESS_POINTER_REGNUM
:
6253 s390_init_frame_layout ();
6254 index
= RETURN_REGNUM
- cfun_frame_layout
.first_save_gpr
;
6255 gcc_assert (index
>= 0);
6256 offset
= cfun_frame_layout
.frame_size
+ cfun_frame_layout
.gprs_offset
;
6257 offset
+= index
* UNITS_PER_WORD
;
6267 /* Emit insn to save fpr REGNUM at offset OFFSET relative
6268 to register BASE. Return generated insn. */
6271 save_fpr (rtx base
, int offset
, int regnum
)
6274 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
6275 set_mem_alias_set (addr
, s390_sr_alias_set
);
6277 return emit_move_insn (addr
, gen_rtx_REG (DFmode
, regnum
));
6280 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
6281 to register BASE. Return generated insn. */
6284 restore_fpr (rtx base
, int offset
, int regnum
)
6287 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
6288 set_mem_alias_set (addr
, s390_sr_alias_set
);
6290 return emit_move_insn (gen_rtx_REG (DFmode
, regnum
), addr
);
6293 /* Generate insn to save registers FIRST to LAST into
6294 the register save area located at offset OFFSET
6295 relative to register BASE. */
6298 save_gprs (rtx base
, int offset
, int first
, int last
)
6300 rtx addr
, insn
, note
;
6303 addr
= plus_constant (base
, offset
);
6304 addr
= gen_rtx_MEM (Pmode
, addr
);
6305 set_mem_alias_set (addr
, s390_sr_alias_set
);
6307 /* Special-case single register. */
6311 insn
= gen_movdi (addr
, gen_rtx_REG (Pmode
, first
));
6313 insn
= gen_movsi (addr
, gen_rtx_REG (Pmode
, first
));
6315 RTX_FRAME_RELATED_P (insn
) = 1;
6320 insn
= gen_store_multiple (addr
,
6321 gen_rtx_REG (Pmode
, first
),
6322 GEN_INT (last
- first
+ 1));
6325 /* We need to set the FRAME_RELATED flag on all SETs
6326 inside the store-multiple pattern.
6328 However, we must not emit DWARF records for registers 2..5
6329 if they are stored for use by variable arguments ...
6331 ??? Unfortunately, it is not enough to simply not the
6332 FRAME_RELATED flags for those SETs, because the first SET
6333 of the PARALLEL is always treated as if it had the flag
6334 set, even if it does not. Therefore we emit a new pattern
6335 without those registers as REG_FRAME_RELATED_EXPR note. */
6339 rtx pat
= PATTERN (insn
);
6341 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
6342 if (GET_CODE (XVECEXP (pat
, 0, i
)) == SET
)
6343 RTX_FRAME_RELATED_P (XVECEXP (pat
, 0, i
)) = 1;
6345 RTX_FRAME_RELATED_P (insn
) = 1;
6349 addr
= plus_constant (base
, offset
+ (6 - first
) * UNITS_PER_WORD
);
6350 note
= gen_store_multiple (gen_rtx_MEM (Pmode
, addr
),
6351 gen_rtx_REG (Pmode
, 6),
6352 GEN_INT (last
- 6 + 1));
6353 note
= PATTERN (note
);
6356 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
6357 note
, REG_NOTES (insn
));
6359 for (i
= 0; i
< XVECLEN (note
, 0); i
++)
6360 if (GET_CODE (XVECEXP (note
, 0, i
)) == SET
)
6361 RTX_FRAME_RELATED_P (XVECEXP (note
, 0, i
)) = 1;
6363 RTX_FRAME_RELATED_P (insn
) = 1;
6369 /* Generate insn to restore registers FIRST to LAST from
6370 the register save area located at offset OFFSET
6371 relative to register BASE. */
6374 restore_gprs (rtx base
, int offset
, int first
, int last
)
6378 addr
= plus_constant (base
, offset
);
6379 addr
= gen_rtx_MEM (Pmode
, addr
);
6380 set_mem_alias_set (addr
, s390_sr_alias_set
);
6382 /* Special-case single register. */
6386 insn
= gen_movdi (gen_rtx_REG (Pmode
, first
), addr
);
6388 insn
= gen_movsi (gen_rtx_REG (Pmode
, first
), addr
);
6393 insn
= gen_load_multiple (gen_rtx_REG (Pmode
, first
),
6395 GEN_INT (last
- first
+ 1));
6399 /* Return insn sequence to load the GOT register. */
6401 static GTY(()) rtx got_symbol
;
6403 s390_load_got (void)
6409 got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
6410 SYMBOL_REF_FLAGS (got_symbol
) = SYMBOL_FLAG_LOCAL
;
6415 if (TARGET_CPU_ZARCH
)
6417 emit_move_insn (pic_offset_table_rtx
, got_symbol
);
6423 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, got_symbol
),
6424 UNSPEC_LTREL_OFFSET
);
6425 offset
= gen_rtx_CONST (Pmode
, offset
);
6426 offset
= force_const_mem (Pmode
, offset
);
6428 emit_move_insn (pic_offset_table_rtx
, offset
);
6430 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, XEXP (offset
, 0)),
6432 offset
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, offset
);
6434 emit_move_insn (pic_offset_table_rtx
, offset
);
6437 insns
= get_insns ();
6442 /* Expand the prologue into a bunch of separate insns. */
6445 s390_emit_prologue (void)
6453 /* Complete frame layout. */
6455 s390_update_frame_layout ();
6457 /* Annotate all constant pool references to let the scheduler know
6458 they implicitly use the base register. */
6460 push_topmost_sequence ();
6462 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6464 annotate_constant_pool_refs (&PATTERN (insn
));
6466 pop_topmost_sequence ();
6468 /* Choose best register to use for temp use within prologue.
6469 See below for why TPF must use the register 1. */
6471 if (!has_hard_reg_initial_val (Pmode
, RETURN_REGNUM
)
6472 && !current_function_is_leaf
6473 && !TARGET_TPF_PROFILING
)
6474 temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
6476 temp_reg
= gen_rtx_REG (Pmode
, 1);
6478 /* Save call saved gprs. */
6479 if (cfun_frame_layout
.first_save_gpr
!= -1)
6481 insn
= save_gprs (stack_pointer_rtx
,
6482 cfun_frame_layout
.gprs_offset
,
6483 cfun_frame_layout
.first_save_gpr
,
6484 cfun_frame_layout
.last_save_gpr
);
6488 /* Dummy insn to mark literal pool slot. */
6490 if (cfun
->machine
->base_reg
)
6491 emit_insn (gen_main_pool (cfun
->machine
->base_reg
));
6493 offset
= cfun_frame_layout
.f0_offset
;
6495 /* Save f0 and f2. */
6496 for (i
= 0; i
< 2; i
++)
6498 if (cfun_fpr_bit_p (i
))
6500 save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
6503 else if (!TARGET_PACKED_STACK
)
6507 /* Save f4 and f6. */
6508 offset
= cfun_frame_layout
.f4_offset
;
6509 for (i
= 2; i
< 4; i
++)
6511 if (cfun_fpr_bit_p (i
))
6513 insn
= save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
6516 /* If f4 and f6 are call clobbered they are saved due to stdargs and
6517 therefore are not frame related. */
6518 if (!call_really_used_regs
[i
+ 16])
6519 RTX_FRAME_RELATED_P (insn
) = 1;
6521 else if (!TARGET_PACKED_STACK
)
6525 if (TARGET_PACKED_STACK
6526 && cfun_save_high_fprs_p
6527 && cfun_frame_layout
.f8_offset
+ cfun_frame_layout
.high_fprs
* 8 > 0)
6529 offset
= (cfun_frame_layout
.f8_offset
6530 + (cfun_frame_layout
.high_fprs
- 1) * 8);
6532 for (i
= 15; i
> 7 && offset
>= 0; i
--)
6533 if (cfun_fpr_bit_p (i
))
6535 insn
= save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
6537 RTX_FRAME_RELATED_P (insn
) = 1;
6540 if (offset
>= cfun_frame_layout
.f8_offset
)
6544 if (!TARGET_PACKED_STACK
)
6545 next_fpr
= cfun_save_high_fprs_p
? 31 : 0;
6547 /* Decrement stack pointer. */
6549 if (cfun_frame_layout
.frame_size
> 0)
6551 rtx frame_off
= GEN_INT (-cfun_frame_layout
.frame_size
);
6553 if (s390_stack_size
)
6555 HOST_WIDE_INT stack_check_mask
= ((s390_stack_size
- 1)
6556 & ~(s390_stack_guard
- 1));
6557 rtx t
= gen_rtx_AND (Pmode
, stack_pointer_rtx
,
6558 GEN_INT (stack_check_mask
));
6561 gen_cmpdi (t
, const0_rtx
);
6563 gen_cmpsi (t
, const0_rtx
);
6565 emit_insn (gen_conditional_trap (gen_rtx_EQ (CCmode
,
6566 gen_rtx_REG (CCmode
,
6572 if (s390_warn_framesize
> 0
6573 && cfun_frame_layout
.frame_size
>= s390_warn_framesize
)
6574 warning (0, "frame size of %qs is " HOST_WIDE_INT_PRINT_DEC
" bytes",
6575 current_function_name (), cfun_frame_layout
.frame_size
);
6577 if (s390_warn_dynamicstack_p
&& cfun
->calls_alloca
)
6578 warning (0, "%qs uses dynamic stack allocation", current_function_name ());
6580 /* Save incoming stack pointer into temp reg. */
6581 if (TARGET_BACKCHAIN
|| next_fpr
)
6582 insn
= emit_insn (gen_move_insn (temp_reg
, stack_pointer_rtx
));
6584 /* Subtract frame size from stack pointer. */
6586 if (DISP_IN_RANGE (INTVAL (frame_off
)))
6588 insn
= gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
6589 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
6591 insn
= emit_insn (insn
);
6595 if (!CONST_OK_FOR_K (INTVAL (frame_off
)))
6596 frame_off
= force_const_mem (Pmode
, frame_off
);
6598 insn
= emit_insn (gen_add2_insn (stack_pointer_rtx
, frame_off
));
6599 annotate_constant_pool_refs (&PATTERN (insn
));
6602 RTX_FRAME_RELATED_P (insn
) = 1;
6604 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
6605 gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
6606 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
6607 GEN_INT (-cfun_frame_layout
.frame_size
))),
6610 /* Set backchain. */
6612 if (TARGET_BACKCHAIN
)
6614 if (cfun_frame_layout
.backchain_offset
)
6615 addr
= gen_rtx_MEM (Pmode
,
6616 plus_constant (stack_pointer_rtx
,
6617 cfun_frame_layout
.backchain_offset
));
6619 addr
= gen_rtx_MEM (Pmode
, stack_pointer_rtx
);
6620 set_mem_alias_set (addr
, s390_sr_alias_set
);
6621 insn
= emit_insn (gen_move_insn (addr
, temp_reg
));
6624 /* If we support asynchronous exceptions (e.g. for Java),
6625 we need to make sure the backchain pointer is set up
6626 before any possibly trapping memory access. */
6628 if (TARGET_BACKCHAIN
&& flag_non_call_exceptions
)
6630 addr
= gen_rtx_MEM (BLKmode
, gen_rtx_SCRATCH (VOIDmode
));
6631 emit_insn (gen_rtx_CLOBBER (VOIDmode
, addr
));
6635 /* Save fprs 8 - 15 (64 bit ABI). */
6637 if (cfun_save_high_fprs_p
&& next_fpr
)
6639 insn
= emit_insn (gen_add2_insn (temp_reg
,
6640 GEN_INT (cfun_frame_layout
.f8_offset
)));
6644 for (i
= 24; i
<= next_fpr
; i
++)
6645 if (cfun_fpr_bit_p (i
- 16))
6647 rtx addr
= plus_constant (stack_pointer_rtx
,
6648 cfun_frame_layout
.frame_size
6649 + cfun_frame_layout
.f8_offset
6652 insn
= save_fpr (temp_reg
, offset
, i
);
6654 RTX_FRAME_RELATED_P (insn
) = 1;
6656 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
6657 gen_rtx_SET (VOIDmode
,
6658 gen_rtx_MEM (DFmode
, addr
),
6659 gen_rtx_REG (DFmode
, i
)),
6664 /* Set frame pointer, if needed. */
6666 if (frame_pointer_needed
)
6668 insn
= emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
);
6669 RTX_FRAME_RELATED_P (insn
) = 1;
6672 /* Set up got pointer, if needed. */
6674 if (flag_pic
&& regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
])
6676 rtx insns
= s390_load_got ();
6678 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
6680 annotate_constant_pool_refs (&PATTERN (insn
));
6682 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD
, NULL_RTX
,
6689 if (TARGET_TPF_PROFILING
)
6691 /* Generate a BAS instruction to serve as a function
6692 entry intercept to facilitate the use of tracing
6693 algorithms located at the branch target. */
6694 emit_insn (gen_prologue_tpf ());
6696 /* Emit a blockage here so that all code
6697 lies between the profiling mechanisms. */
6698 emit_insn (gen_blockage ());
6702 /* Expand the epilogue into a bunch of separate insns. */
6705 s390_emit_epilogue (bool sibcall
)
6707 rtx frame_pointer
, return_reg
;
6708 int area_bottom
, area_top
, offset
= 0;
6713 if (TARGET_TPF_PROFILING
)
6716 /* Generate a BAS instruction to serve as a function
6717 entry intercept to facilitate the use of tracing
6718 algorithms located at the branch target. */
6720 /* Emit a blockage here so that all code
6721 lies between the profiling mechanisms. */
6722 emit_insn (gen_blockage ());
6724 emit_insn (gen_epilogue_tpf ());
6727 /* Check whether to use frame or stack pointer for restore. */
6729 frame_pointer
= (frame_pointer_needed
6730 ? hard_frame_pointer_rtx
: stack_pointer_rtx
);
6732 s390_frame_area (&area_bottom
, &area_top
);
6734 /* Check whether we can access the register save area.
6735 If not, increment the frame pointer as required. */
6737 if (area_top
<= area_bottom
)
6739 /* Nothing to restore. */
6741 else if (DISP_IN_RANGE (cfun_frame_layout
.frame_size
+ area_bottom
)
6742 && DISP_IN_RANGE (cfun_frame_layout
.frame_size
+ area_top
- 1))
6744 /* Area is in range. */
6745 offset
= cfun_frame_layout
.frame_size
;
6749 rtx insn
, frame_off
;
6751 offset
= area_bottom
< 0 ? -area_bottom
: 0;
6752 frame_off
= GEN_INT (cfun_frame_layout
.frame_size
- offset
);
6754 if (DISP_IN_RANGE (INTVAL (frame_off
)))
6756 insn
= gen_rtx_SET (VOIDmode
, frame_pointer
,
6757 gen_rtx_PLUS (Pmode
, frame_pointer
, frame_off
));
6758 insn
= emit_insn (insn
);
6762 if (!CONST_OK_FOR_K (INTVAL (frame_off
)))
6763 frame_off
= force_const_mem (Pmode
, frame_off
);
6765 insn
= emit_insn (gen_add2_insn (frame_pointer
, frame_off
));
6766 annotate_constant_pool_refs (&PATTERN (insn
));
6770 /* Restore call saved fprs. */
6774 if (cfun_save_high_fprs_p
)
6776 next_offset
= cfun_frame_layout
.f8_offset
;
6777 for (i
= 24; i
< 32; i
++)
6779 if (cfun_fpr_bit_p (i
- 16))
6781 restore_fpr (frame_pointer
,
6782 offset
+ next_offset
, i
);
6791 next_offset
= cfun_frame_layout
.f4_offset
;
6792 for (i
= 18; i
< 20; i
++)
6794 if (cfun_fpr_bit_p (i
- 16))
6796 restore_fpr (frame_pointer
,
6797 offset
+ next_offset
, i
);
6800 else if (!TARGET_PACKED_STACK
)
6806 /* Return register. */
6808 return_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
6810 /* Restore call saved gprs. */
6812 if (cfun_frame_layout
.first_restore_gpr
!= -1)
6817 /* Check for global register and save them
6818 to stack location from where they get restored. */
6820 for (i
= cfun_frame_layout
.first_restore_gpr
;
6821 i
<= cfun_frame_layout
.last_restore_gpr
;
6824 /* These registers are special and need to be
6825 restored in any case. */
6826 if (i
== STACK_POINTER_REGNUM
6827 || i
== RETURN_REGNUM
6829 || (flag_pic
&& i
== (int)PIC_OFFSET_TABLE_REGNUM
))
6834 addr
= plus_constant (frame_pointer
,
6835 offset
+ cfun_frame_layout
.gprs_offset
6836 + (i
- cfun_frame_layout
.first_save_gpr
)
6838 addr
= gen_rtx_MEM (Pmode
, addr
);
6839 set_mem_alias_set (addr
, s390_sr_alias_set
);
6840 emit_move_insn (addr
, gen_rtx_REG (Pmode
, i
));
6846 /* Fetch return address from stack before load multiple,
6847 this will do good for scheduling. */
6849 if (cfun_frame_layout
.save_return_addr_p
6850 || (cfun_frame_layout
.first_restore_gpr
< BASE_REGNUM
6851 && cfun_frame_layout
.last_restore_gpr
> RETURN_REGNUM
))
6853 int return_regnum
= find_unused_clobbered_reg();
6856 return_reg
= gen_rtx_REG (Pmode
, return_regnum
);
6858 addr
= plus_constant (frame_pointer
,
6859 offset
+ cfun_frame_layout
.gprs_offset
6861 - cfun_frame_layout
.first_save_gpr
)
6863 addr
= gen_rtx_MEM (Pmode
, addr
);
6864 set_mem_alias_set (addr
, s390_sr_alias_set
);
6865 emit_move_insn (return_reg
, addr
);
6869 insn
= restore_gprs (frame_pointer
,
6870 offset
+ cfun_frame_layout
.gprs_offset
6871 + (cfun_frame_layout
.first_restore_gpr
6872 - cfun_frame_layout
.first_save_gpr
)
6874 cfun_frame_layout
.first_restore_gpr
,
6875 cfun_frame_layout
.last_restore_gpr
);
6882 /* Return to caller. */
6884 p
= rtvec_alloc (2);
6886 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
6887 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
, return_reg
);
6888 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
6893 /* Return the size in bytes of a function argument of
6894 type TYPE and/or mode MODE. At least one of TYPE or
6895 MODE must be specified. */
6898 s390_function_arg_size (enum machine_mode mode
, tree type
)
6901 return int_size_in_bytes (type
);
6903 /* No type info available for some library calls ... */
6904 if (mode
!= BLKmode
)
6905 return GET_MODE_SIZE (mode
);
6907 /* If we have neither type nor mode, abort */
6911 /* Return true if a function argument of type TYPE and mode MODE
6912 is to be passed in a floating-point register, if available. */
6915 s390_function_arg_float (enum machine_mode mode
, tree type
)
6917 int size
= s390_function_arg_size (mode
, type
);
6921 /* Soft-float changes the ABI: no floating-point registers are used. */
6922 if (TARGET_SOFT_FLOAT
)
6925 /* No type info available for some library calls ... */
6927 return mode
== SFmode
|| mode
== DFmode
;
6929 /* The ABI says that record types with a single member are treated
6930 just like that member would be. */
6931 while (TREE_CODE (type
) == RECORD_TYPE
)
6933 tree field
, single
= NULL_TREE
;
6935 for (field
= TYPE_FIELDS (type
); field
; field
= TREE_CHAIN (field
))
6937 if (TREE_CODE (field
) != FIELD_DECL
)
6940 if (single
== NULL_TREE
)
6941 single
= TREE_TYPE (field
);
6946 if (single
== NULL_TREE
)
6952 return TREE_CODE (type
) == REAL_TYPE
;
6955 /* Return true if a function argument of type TYPE and mode MODE
6956 is to be passed in an integer register, or a pair of integer
6957 registers, if available. */
6960 s390_function_arg_integer (enum machine_mode mode
, tree type
)
6962 int size
= s390_function_arg_size (mode
, type
);
6966 /* No type info available for some library calls ... */
6968 return GET_MODE_CLASS (mode
) == MODE_INT
6969 || (TARGET_SOFT_FLOAT
&& GET_MODE_CLASS (mode
) == MODE_FLOAT
);
6971 /* We accept small integral (and similar) types. */
6972 if (INTEGRAL_TYPE_P (type
)
6973 || POINTER_TYPE_P (type
)
6974 || TREE_CODE (type
) == OFFSET_TYPE
6975 || (TARGET_SOFT_FLOAT
&& TREE_CODE (type
) == REAL_TYPE
))
6978 /* We also accept structs of size 1, 2, 4, 8 that are not
6979 passed in floating-point registers. */
6980 if (AGGREGATE_TYPE_P (type
)
6981 && exact_log2 (size
) >= 0
6982 && !s390_function_arg_float (mode
, type
))
6988 /* Return 1 if a function argument of type TYPE and mode MODE
6989 is to be passed by reference. The ABI specifies that only
6990 structures of size 1, 2, 4, or 8 bytes are passed by value,
6991 all other structures (and complex numbers) are passed by
6995 s390_pass_by_reference (CUMULATIVE_ARGS
*ca ATTRIBUTE_UNUSED
,
6996 enum machine_mode mode
, tree type
,
6997 bool named ATTRIBUTE_UNUSED
)
6999 int size
= s390_function_arg_size (mode
, type
);
7005 if (AGGREGATE_TYPE_P (type
) && exact_log2 (size
) < 0)
7008 if (TREE_CODE (type
) == COMPLEX_TYPE
7009 || TREE_CODE (type
) == VECTOR_TYPE
)
7016 /* Update the data in CUM to advance over an argument of mode MODE and
7017 data type TYPE. (TYPE is null for libcalls where that information
7018 may not be available.). The boolean NAMED specifies whether the
7019 argument is a named argument (as opposed to an unnamed argument
7020 matching an ellipsis). */
7023 s390_function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
7024 tree type
, int named ATTRIBUTE_UNUSED
)
7026 if (s390_function_arg_float (mode
, type
))
7030 else if (s390_function_arg_integer (mode
, type
))
7032 int size
= s390_function_arg_size (mode
, type
);
7033 cum
->gprs
+= ((size
+ UNITS_PER_WORD
-1) / UNITS_PER_WORD
);
7039 /* Define where to put the arguments to a function.
7040 Value is zero to push the argument on the stack,
7041 or a hard register in which to store the argument.
7043 MODE is the argument's machine mode.
7044 TYPE is the data type of the argument (as a tree).
7045 This is null for libcalls where that information may
7047 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7048 the preceding args and about the function being called.
7049 NAMED is nonzero if this argument is a named parameter
7050 (otherwise it is an extra parameter matching an ellipsis).
7052 On S/390, we use general purpose registers 2 through 6 to
7053 pass integer, pointer, and certain structure arguments, and
7054 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
7055 to pass floating point arguments. All remaining arguments
7056 are pushed to the stack. */
7059 s390_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
, tree type
,
7060 int named ATTRIBUTE_UNUSED
)
7062 if (s390_function_arg_float (mode
, type
))
7064 if (cum
->fprs
+ 1 > FP_ARG_NUM_REG
)
7067 return gen_rtx_REG (mode
, cum
->fprs
+ 16);
7069 else if (s390_function_arg_integer (mode
, type
))
7071 int size
= s390_function_arg_size (mode
, type
);
7072 int n_gprs
= (size
+ UNITS_PER_WORD
-1) / UNITS_PER_WORD
;
7074 if (cum
->gprs
+ n_gprs
> GP_ARG_NUM_REG
)
7077 return gen_rtx_REG (mode
, cum
->gprs
+ 2);
7080 /* After the real arguments, expand_call calls us once again
7081 with a void_type_node type. Whatever we return here is
7082 passed as operand 2 to the call expanders.
7084 We don't need this feature ... */
7085 else if (type
== void_type_node
)
7091 /* Return true if return values of type TYPE should be returned
7092 in a memory buffer whose address is passed by the caller as
7093 hidden first argument. */
7096 s390_return_in_memory (tree type
, tree fundecl ATTRIBUTE_UNUSED
)
7098 /* We accept small integral (and similar) types. */
7099 if (INTEGRAL_TYPE_P (type
)
7100 || POINTER_TYPE_P (type
)
7101 || TREE_CODE (type
) == OFFSET_TYPE
7102 || TREE_CODE (type
) == REAL_TYPE
)
7103 return int_size_in_bytes (type
) > 8;
7105 /* Aggregates and similar constructs are always returned
7107 if (AGGREGATE_TYPE_P (type
)
7108 || TREE_CODE (type
) == COMPLEX_TYPE
7109 || TREE_CODE (type
) == VECTOR_TYPE
)
7112 /* ??? We get called on all sorts of random stuff from
7113 aggregate_value_p. We can't abort, but it's not clear
7114 what's safe to return. Pretend it's a struct I guess. */
7118 /* Define where to return a (scalar) value of type TYPE.
7119 If TYPE is null, define where to return a (scalar)
7120 value of mode MODE from a libcall. */
7123 s390_function_value (tree type
, enum machine_mode mode
)
7127 int unsignedp
= TYPE_UNSIGNED (type
);
7128 mode
= promote_mode (type
, TYPE_MODE (type
), &unsignedp
, 1);
7131 gcc_assert (GET_MODE_CLASS (mode
) == MODE_INT
7132 || GET_MODE_CLASS (mode
) == MODE_FLOAT
);
7133 gcc_assert (GET_MODE_SIZE (mode
) <= 8);
7135 if (TARGET_HARD_FLOAT
&& GET_MODE_CLASS (mode
) == MODE_FLOAT
)
7136 return gen_rtx_REG (mode
, 16);
7138 return gen_rtx_REG (mode
, 2);
7142 /* Create and return the va_list datatype.
7144 On S/390, va_list is an array type equivalent to
7146 typedef struct __va_list_tag
7150 void *__overflow_arg_area;
7151 void *__reg_save_area;
7154 where __gpr and __fpr hold the number of general purpose
7155 or floating point arguments used up to now, respectively,
7156 __overflow_arg_area points to the stack location of the
7157 next argument passed on the stack, and __reg_save_area
7158 always points to the start of the register area in the
7159 call frame of the current function. The function prologue
7160 saves all registers used for argument passing into this
7161 area if the function uses variable arguments. */
7164 s390_build_builtin_va_list (void)
7166 tree f_gpr
, f_fpr
, f_ovf
, f_sav
, record
, type_decl
;
7168 record
= lang_hooks
.types
.make_type (RECORD_TYPE
);
7171 build_decl (TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
7173 f_gpr
= build_decl (FIELD_DECL
, get_identifier ("__gpr"),
7174 long_integer_type_node
);
7175 f_fpr
= build_decl (FIELD_DECL
, get_identifier ("__fpr"),
7176 long_integer_type_node
);
7177 f_ovf
= build_decl (FIELD_DECL
, get_identifier ("__overflow_arg_area"),
7179 f_sav
= build_decl (FIELD_DECL
, get_identifier ("__reg_save_area"),
7182 va_list_gpr_counter_field
= f_gpr
;
7183 va_list_fpr_counter_field
= f_fpr
;
7185 DECL_FIELD_CONTEXT (f_gpr
) = record
;
7186 DECL_FIELD_CONTEXT (f_fpr
) = record
;
7187 DECL_FIELD_CONTEXT (f_ovf
) = record
;
7188 DECL_FIELD_CONTEXT (f_sav
) = record
;
7190 TREE_CHAIN (record
) = type_decl
;
7191 TYPE_NAME (record
) = type_decl
;
7192 TYPE_FIELDS (record
) = f_gpr
;
7193 TREE_CHAIN (f_gpr
) = f_fpr
;
7194 TREE_CHAIN (f_fpr
) = f_ovf
;
7195 TREE_CHAIN (f_ovf
) = f_sav
;
7197 layout_type (record
);
7199 /* The correct type is an array type of one element. */
7200 return build_array_type (record
, build_index_type (size_zero_node
));
7203 /* Implement va_start by filling the va_list structure VALIST.
7204 STDARG_P is always true, and ignored.
7205 NEXTARG points to the first anonymous stack argument.
7207 The following global variables are used to initialize
7208 the va_list structure:
7210 current_function_args_info:
7211 holds number of gprs and fprs used for named arguments.
7212 current_function_arg_offset_rtx:
7213 holds the offset of the first anonymous stack argument
7214 (relative to the virtual arg pointer). */
7217 s390_va_start (tree valist
, rtx nextarg ATTRIBUTE_UNUSED
)
7219 HOST_WIDE_INT n_gpr
, n_fpr
;
7221 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
7222 tree gpr
, fpr
, ovf
, sav
, t
;
7224 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
7225 f_fpr
= TREE_CHAIN (f_gpr
);
7226 f_ovf
= TREE_CHAIN (f_fpr
);
7227 f_sav
= TREE_CHAIN (f_ovf
);
7229 valist
= build_va_arg_indirect_ref (valist
);
7230 gpr
= build (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
7231 fpr
= build (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
7232 ovf
= build (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
7233 sav
= build (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
7235 /* Count number of gp and fp argument registers used. */
7237 n_gpr
= current_function_args_info
.gprs
;
7238 n_fpr
= current_function_args_info
.fprs
;
7240 if (cfun
->va_list_gpr_size
)
7242 t
= build (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
,
7243 build_int_cst (NULL_TREE
, n_gpr
));
7244 TREE_SIDE_EFFECTS (t
) = 1;
7245 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7248 if (cfun
->va_list_fpr_size
)
7250 t
= build (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
,
7251 build_int_cst (NULL_TREE
, n_fpr
));
7252 TREE_SIDE_EFFECTS (t
) = 1;
7253 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7256 /* Find the overflow area. */
7257 if (n_gpr
+ cfun
->va_list_gpr_size
> GP_ARG_NUM_REG
7258 || n_fpr
+ cfun
->va_list_fpr_size
> FP_ARG_NUM_REG
)
7260 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
7262 off
= INTVAL (current_function_arg_offset_rtx
);
7263 off
= off
< 0 ? 0 : off
;
7264 if (TARGET_DEBUG_ARG
)
7265 fprintf (stderr
, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
7266 (int)n_gpr
, (int)n_fpr
, off
);
7268 t
= build (PLUS_EXPR
, TREE_TYPE (ovf
), t
, build_int_cst (NULL_TREE
, off
));
7270 t
= build (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
7271 TREE_SIDE_EFFECTS (t
) = 1;
7272 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7275 /* Find the register save area. */
7276 if ((cfun
->va_list_gpr_size
&& n_gpr
< GP_ARG_NUM_REG
)
7277 || (cfun
->va_list_fpr_size
&& n_fpr
< FP_ARG_NUM_REG
))
7279 t
= make_tree (TREE_TYPE (sav
), return_address_pointer_rtx
);
7280 t
= build (PLUS_EXPR
, TREE_TYPE (sav
), t
,
7281 build_int_cst (NULL_TREE
, -RETURN_REGNUM
* UNITS_PER_WORD
));
7283 t
= build (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
7284 TREE_SIDE_EFFECTS (t
) = 1;
7285 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7289 /* Implement va_arg by updating the va_list structure
7290 VALIST as required to retrieve an argument of type
7291 TYPE, and returning that argument.
7293 Generates code equivalent to:
7295 if (integral value) {
7296 if (size <= 4 && args.gpr < 5 ||
7297 size > 4 && args.gpr < 4 )
7298 ret = args.reg_save_area[args.gpr+8]
7300 ret = *args.overflow_arg_area++;
7301 } else if (float value) {
7303 ret = args.reg_save_area[args.fpr+64]
7305 ret = *args.overflow_arg_area++;
7306 } else if (aggregate value) {
7308 ret = *args.reg_save_area[args.gpr]
7310 ret = **args.overflow_arg_area++;
7314 s390_gimplify_va_arg (tree valist
, tree type
, tree
*pre_p
,
7315 tree
*post_p ATTRIBUTE_UNUSED
)
7317 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
7318 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
7319 int indirect_p
, size
, n_reg
, sav_ofs
, sav_scale
, max_reg
;
7320 tree lab_false
, lab_over
, addr
;
7322 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
7323 f_fpr
= TREE_CHAIN (f_gpr
);
7324 f_ovf
= TREE_CHAIN (f_fpr
);
7325 f_sav
= TREE_CHAIN (f_ovf
);
7327 valist
= build_va_arg_indirect_ref (valist
);
7328 gpr
= build (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
7329 fpr
= build (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
7330 ovf
= build (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
7331 sav
= build (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
7333 size
= int_size_in_bytes (type
);
7335 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
7337 if (TARGET_DEBUG_ARG
)
7339 fprintf (stderr
, "va_arg: aggregate type");
7343 /* Aggregates are passed by reference. */
7348 /* kernel stack layout on 31 bit: It is assumed here that no padding
7349 will be added by s390_frame_info because for va_args always an even
7350 number of gprs has to be saved r15-r2 = 14 regs. */
7351 sav_ofs
= 2 * UNITS_PER_WORD
;
7352 sav_scale
= UNITS_PER_WORD
;
7353 size
= UNITS_PER_WORD
;
7354 max_reg
= GP_ARG_NUM_REG
- n_reg
;
7356 else if (s390_function_arg_float (TYPE_MODE (type
), type
))
7358 if (TARGET_DEBUG_ARG
)
7360 fprintf (stderr
, "va_arg: float type");
7364 /* FP args go in FP registers, if present. */
7368 sav_ofs
= 16 * UNITS_PER_WORD
;
7370 max_reg
= FP_ARG_NUM_REG
- n_reg
;
7374 if (TARGET_DEBUG_ARG
)
7376 fprintf (stderr
, "va_arg: other type");
7380 /* Otherwise into GP registers. */
7383 n_reg
= (size
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
7385 /* kernel stack layout on 31 bit: It is assumed here that no padding
7386 will be added by s390_frame_info because for va_args always an even
7387 number of gprs has to be saved r15-r2 = 14 regs. */
7388 sav_ofs
= 2 * UNITS_PER_WORD
;
7390 if (size
< UNITS_PER_WORD
)
7391 sav_ofs
+= UNITS_PER_WORD
- size
;
7393 sav_scale
= UNITS_PER_WORD
;
7394 max_reg
= GP_ARG_NUM_REG
- n_reg
;
7397 /* Pull the value out of the saved registers ... */
7399 lab_false
= create_artificial_label ();
7400 lab_over
= create_artificial_label ();
7401 addr
= create_tmp_var (ptr_type_node
, "addr");
7402 DECL_POINTER_ALIAS_SET (addr
) = s390_sr_alias_set
;
7404 t
= fold_convert (TREE_TYPE (reg
), size_int (max_reg
));
7405 t
= build2 (GT_EXPR
, boolean_type_node
, reg
, t
);
7406 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
7407 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
7408 gimplify_and_add (t
, pre_p
);
7410 t
= build2 (PLUS_EXPR
, ptr_type_node
, sav
,
7411 fold_convert (ptr_type_node
, size_int (sav_ofs
)));
7412 u
= build2 (MULT_EXPR
, TREE_TYPE (reg
), reg
,
7413 fold_convert (TREE_TYPE (reg
), size_int (sav_scale
)));
7414 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
, fold_convert (ptr_type_node
, u
));
7416 t
= build2 (MODIFY_EXPR
, void_type_node
, addr
, t
);
7417 gimplify_and_add (t
, pre_p
);
7419 t
= build1 (GOTO_EXPR
, void_type_node
, lab_over
);
7420 gimplify_and_add (t
, pre_p
);
7422 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false
);
7423 append_to_statement_list (t
, pre_p
);
7426 /* ... Otherwise out of the overflow area. */
7429 if (size
< UNITS_PER_WORD
)
7430 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
,
7431 fold_convert (ptr_type_node
, size_int (UNITS_PER_WORD
- size
)));
7433 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
7435 u
= build2 (MODIFY_EXPR
, void_type_node
, addr
, t
);
7436 gimplify_and_add (u
, pre_p
);
7438 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
,
7439 fold_convert (ptr_type_node
, size_int (size
)));
7440 t
= build2 (MODIFY_EXPR
, ptr_type_node
, ovf
, t
);
7441 gimplify_and_add (t
, pre_p
);
7443 t
= build1 (LABEL_EXPR
, void_type_node
, lab_over
);
7444 append_to_statement_list (t
, pre_p
);
7447 /* Increment register save count. */
7449 u
= build2 (PREINCREMENT_EXPR
, TREE_TYPE (reg
), reg
,
7450 fold_convert (TREE_TYPE (reg
), size_int (n_reg
)));
7451 gimplify_and_add (u
, pre_p
);
7455 t
= build_pointer_type (build_pointer_type (type
));
7456 addr
= fold_convert (t
, addr
);
7457 addr
= build_va_arg_indirect_ref (addr
);
7461 t
= build_pointer_type (type
);
7462 addr
= fold_convert (t
, addr
);
7465 return build_va_arg_indirect_ref (addr
);
7473 S390_BUILTIN_THREAD_POINTER
,
7474 S390_BUILTIN_SET_THREAD_POINTER
,
7479 static unsigned int const code_for_builtin_64
[S390_BUILTIN_max
] = {
7484 static unsigned int const code_for_builtin_31
[S390_BUILTIN_max
] = {
7490 s390_init_builtins (void)
7494 ftype
= build_function_type (ptr_type_node
, void_list_node
);
7495 lang_hooks
.builtin_function ("__builtin_thread_pointer", ftype
,
7496 S390_BUILTIN_THREAD_POINTER
, BUILT_IN_MD
,
7499 ftype
= build_function_type_list (void_type_node
, ptr_type_node
, NULL_TREE
);
7500 lang_hooks
.builtin_function ("__builtin_set_thread_pointer", ftype
,
7501 S390_BUILTIN_SET_THREAD_POINTER
, BUILT_IN_MD
,
7505 /* Expand an expression EXP that calls a built-in function,
7506 with result going to TARGET if that's convenient
7507 (and in mode MODE if that's convenient).
7508 SUBTARGET may be used as the target for computing one of EXP's operands.
7509 IGNORE is nonzero if the value is to be ignored. */
7512 s390_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
7513 enum machine_mode mode ATTRIBUTE_UNUSED
,
7514 int ignore ATTRIBUTE_UNUSED
)
7518 unsigned int const *code_for_builtin
=
7519 TARGET_64BIT
? code_for_builtin_64
: code_for_builtin_31
;
7521 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
7522 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7523 tree arglist
= TREE_OPERAND (exp
, 1);
7524 enum insn_code icode
;
7525 rtx op
[MAX_ARGS
], pat
;
7529 if (fcode
>= S390_BUILTIN_max
)
7530 internal_error ("bad builtin fcode");
7531 icode
= code_for_builtin
[fcode
];
7533 internal_error ("bad builtin fcode");
7535 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
7537 for (arglist
= TREE_OPERAND (exp
, 1), arity
= 0;
7539 arglist
= TREE_CHAIN (arglist
), arity
++)
7541 const struct insn_operand_data
*insn_op
;
7543 tree arg
= TREE_VALUE (arglist
);
7544 if (arg
== error_mark_node
)
7546 if (arity
> MAX_ARGS
)
7549 insn_op
= &insn_data
[icode
].operand
[arity
+ nonvoid
];
7551 op
[arity
] = expand_expr (arg
, NULL_RTX
, insn_op
->mode
, 0);
7553 if (!(*insn_op
->predicate
) (op
[arity
], insn_op
->mode
))
7554 op
[arity
] = copy_to_mode_reg (insn_op
->mode
, op
[arity
]);
7559 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7561 || GET_MODE (target
) != tmode
7562 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7563 target
= gen_reg_rtx (tmode
);
7569 pat
= GEN_FCN (icode
) (target
);
7573 pat
= GEN_FCN (icode
) (target
, op
[0]);
7575 pat
= GEN_FCN (icode
) (op
[0]);
7578 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
7594 /* Output assembly code for the trampoline template to
7597 On S/390, we use gpr 1 internally in the trampoline code;
7598 gpr 0 is used to hold the static chain. */
7601 s390_trampoline_template (FILE *file
)
7604 op
[0] = gen_rtx_REG (Pmode
, 0);
7605 op
[1] = gen_rtx_REG (Pmode
, 1);
7609 output_asm_insn ("basr\t%1,0", op
);
7610 output_asm_insn ("lmg\t%0,%1,14(%1)", op
);
7611 output_asm_insn ("br\t%1", op
);
7612 ASM_OUTPUT_SKIP (file
, (HOST_WIDE_INT
)(TRAMPOLINE_SIZE
- 10));
7616 output_asm_insn ("basr\t%1,0", op
);
7617 output_asm_insn ("lm\t%0,%1,6(%1)", op
);
7618 output_asm_insn ("br\t%1", op
);
7619 ASM_OUTPUT_SKIP (file
, (HOST_WIDE_INT
)(TRAMPOLINE_SIZE
- 8));
7623 /* Emit RTL insns to initialize the variable parts of a trampoline.
7624 FNADDR is an RTX for the address of the function's pure code.
7625 CXT is an RTX for the static chain value for the function. */
7628 s390_initialize_trampoline (rtx addr
, rtx fnaddr
, rtx cxt
)
7630 emit_move_insn (gen_rtx_MEM (Pmode
,
7631 memory_address (Pmode
,
7632 plus_constant (addr
, (TARGET_64BIT
? 16 : 8)))), cxt
);
7633 emit_move_insn (gen_rtx_MEM (Pmode
,
7634 memory_address (Pmode
,
7635 plus_constant (addr
, (TARGET_64BIT
? 24 : 12)))), fnaddr
);
7638 /* Return rtx for 64-bit constant formed from the 32-bit subwords
7639 LOW and HIGH, independent of the host word size. */
7642 s390_gen_rtx_const_DI (int high
, int low
)
7644 #if HOST_BITS_PER_WIDE_INT >= 64
7646 val
= (HOST_WIDE_INT
)high
;
7648 val
|= (HOST_WIDE_INT
)low
;
7650 return GEN_INT (val
);
7652 #if HOST_BITS_PER_WIDE_INT >= 32
7653 return immed_double_const ((HOST_WIDE_INT
)low
, (HOST_WIDE_INT
)high
, DImode
);
7660 /* Output assembler code to FILE to increment profiler label # LABELNO
7661 for profiling a function entry. */
7664 s390_function_profiler (FILE *file
, int labelno
)
7669 ASM_GENERATE_INTERNAL_LABEL (label
, "LP", labelno
);
7671 fprintf (file
, "# function profiler \n");
7673 op
[0] = gen_rtx_REG (Pmode
, RETURN_REGNUM
);
7674 op
[1] = gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
7675 op
[1] = gen_rtx_MEM (Pmode
, plus_constant (op
[1], UNITS_PER_WORD
));
7677 op
[2] = gen_rtx_REG (Pmode
, 1);
7678 op
[3] = gen_rtx_SYMBOL_REF (Pmode
, label
);
7679 SYMBOL_REF_FLAGS (op
[3]) = SYMBOL_FLAG_LOCAL
;
7681 op
[4] = gen_rtx_SYMBOL_REF (Pmode
, "_mcount");
7684 op
[4] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[4]), UNSPEC_PLT
);
7685 op
[4] = gen_rtx_CONST (Pmode
, op
[4]);
7690 output_asm_insn ("stg\t%0,%1", op
);
7691 output_asm_insn ("larl\t%2,%3", op
);
7692 output_asm_insn ("brasl\t%0,%4", op
);
7693 output_asm_insn ("lg\t%0,%1", op
);
7697 op
[6] = gen_label_rtx ();
7699 output_asm_insn ("st\t%0,%1", op
);
7700 output_asm_insn ("bras\t%2,%l6", op
);
7701 output_asm_insn (".long\t%4", op
);
7702 output_asm_insn (".long\t%3", op
);
7703 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
7704 output_asm_insn ("l\t%0,0(%2)", op
);
7705 output_asm_insn ("l\t%2,4(%2)", op
);
7706 output_asm_insn ("basr\t%0,%0", op
);
7707 output_asm_insn ("l\t%0,%1", op
);
7711 op
[5] = gen_label_rtx ();
7712 op
[6] = gen_label_rtx ();
7714 output_asm_insn ("st\t%0,%1", op
);
7715 output_asm_insn ("bras\t%2,%l6", op
);
7716 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[5]));
7717 output_asm_insn (".long\t%4-%l5", op
);
7718 output_asm_insn (".long\t%3-%l5", op
);
7719 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
7720 output_asm_insn ("lr\t%0,%2", op
);
7721 output_asm_insn ("a\t%0,0(%2)", op
);
7722 output_asm_insn ("a\t%2,4(%2)", op
);
7723 output_asm_insn ("basr\t%0,%0", op
);
7724 output_asm_insn ("l\t%0,%1", op
);
7728 /* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
7729 into its SYMBOL_REF_FLAGS. */
7732 s390_encode_section_info (tree decl
, rtx rtl
, int first
)
7734 default_encode_section_info (decl
, rtl
, first
);
7736 /* If a variable has a forced alignment to < 2 bytes, mark it with
7737 SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL operand. */
7738 if (TREE_CODE (decl
) == VAR_DECL
7739 && DECL_USER_ALIGN (decl
) && DECL_ALIGN (decl
) < 16)
7740 SYMBOL_REF_FLAGS (XEXP (rtl
, 0)) |= SYMBOL_FLAG_ALIGN1
;
7743 /* Output thunk to FILE that implements a C++ virtual function call (with
7744 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
7745 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
7746 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
7747 relative to the resulting this pointer. */
7750 s390_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
7751 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
7757 /* Operand 0 is the target function. */
7758 op
[0] = XEXP (DECL_RTL (function
), 0);
7759 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (op
[0]))
7762 op
[0] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[0]),
7763 TARGET_64BIT
? UNSPEC_PLT
: UNSPEC_GOT
);
7764 op
[0] = gen_rtx_CONST (Pmode
, op
[0]);
7767 /* Operand 1 is the 'this' pointer. */
7768 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
7769 op
[1] = gen_rtx_REG (Pmode
, 3);
7771 op
[1] = gen_rtx_REG (Pmode
, 2);
7773 /* Operand 2 is the delta. */
7774 op
[2] = GEN_INT (delta
);
7776 /* Operand 3 is the vcall_offset. */
7777 op
[3] = GEN_INT (vcall_offset
);
7779 /* Operand 4 is the temporary register. */
7780 op
[4] = gen_rtx_REG (Pmode
, 1);
7782 /* Operands 5 to 8 can be used as labels. */
7788 /* Operand 9 can be used for temporary register. */
7791 /* Generate code. */
7794 /* Setup literal pool pointer if required. */
7795 if ((!DISP_IN_RANGE (delta
)
7796 && !CONST_OK_FOR_K (delta
)
7797 && !CONST_OK_FOR_Os (delta
))
7798 || (!DISP_IN_RANGE (vcall_offset
)
7799 && !CONST_OK_FOR_K (vcall_offset
)
7800 && !CONST_OK_FOR_Os (vcall_offset
)))
7802 op
[5] = gen_label_rtx ();
7803 output_asm_insn ("larl\t%4,%5", op
);
7806 /* Add DELTA to this pointer. */
7809 if (CONST_OK_FOR_J (delta
))
7810 output_asm_insn ("la\t%1,%2(%1)", op
);
7811 else if (DISP_IN_RANGE (delta
))
7812 output_asm_insn ("lay\t%1,%2(%1)", op
);
7813 else if (CONST_OK_FOR_K (delta
))
7814 output_asm_insn ("aghi\t%1,%2", op
);
7815 else if (CONST_OK_FOR_Os (delta
))
7816 output_asm_insn ("agfi\t%1,%2", op
);
7819 op
[6] = gen_label_rtx ();
7820 output_asm_insn ("agf\t%1,%6-%5(%4)", op
);
7824 /* Perform vcall adjustment. */
7827 if (DISP_IN_RANGE (vcall_offset
))
7829 output_asm_insn ("lg\t%4,0(%1)", op
);
7830 output_asm_insn ("ag\t%1,%3(%4)", op
);
7832 else if (CONST_OK_FOR_K (vcall_offset
))
7834 output_asm_insn ("lghi\t%4,%3", op
);
7835 output_asm_insn ("ag\t%4,0(%1)", op
);
7836 output_asm_insn ("ag\t%1,0(%4)", op
);
7838 else if (CONST_OK_FOR_Os (vcall_offset
))
7840 output_asm_insn ("lgfi\t%4,%3", op
);
7841 output_asm_insn ("ag\t%4,0(%1)", op
);
7842 output_asm_insn ("ag\t%1,0(%4)", op
);
7846 op
[7] = gen_label_rtx ();
7847 output_asm_insn ("llgf\t%4,%7-%5(%4)", op
);
7848 output_asm_insn ("ag\t%4,0(%1)", op
);
7849 output_asm_insn ("ag\t%1,0(%4)", op
);
7853 /* Jump to target. */
7854 output_asm_insn ("jg\t%0", op
);
7856 /* Output literal pool if required. */
7859 output_asm_insn (".align\t4", op
);
7860 targetm
.asm_out
.internal_label (file
, "L",
7861 CODE_LABEL_NUMBER (op
[5]));
7865 targetm
.asm_out
.internal_label (file
, "L",
7866 CODE_LABEL_NUMBER (op
[6]));
7867 output_asm_insn (".long\t%2", op
);
7871 targetm
.asm_out
.internal_label (file
, "L",
7872 CODE_LABEL_NUMBER (op
[7]));
7873 output_asm_insn (".long\t%3", op
);
7878 /* Setup base pointer if required. */
7880 || (!DISP_IN_RANGE (delta
)
7881 && !CONST_OK_FOR_K (delta
)
7882 && !CONST_OK_FOR_Os (delta
))
7883 || (!DISP_IN_RANGE (delta
)
7884 && !CONST_OK_FOR_K (vcall_offset
)
7885 && !CONST_OK_FOR_Os (vcall_offset
)))
7887 op
[5] = gen_label_rtx ();
7888 output_asm_insn ("basr\t%4,0", op
);
7889 targetm
.asm_out
.internal_label (file
, "L",
7890 CODE_LABEL_NUMBER (op
[5]));
7893 /* Add DELTA to this pointer. */
7896 if (CONST_OK_FOR_J (delta
))
7897 output_asm_insn ("la\t%1,%2(%1)", op
);
7898 else if (DISP_IN_RANGE (delta
))
7899 output_asm_insn ("lay\t%1,%2(%1)", op
);
7900 else if (CONST_OK_FOR_K (delta
))
7901 output_asm_insn ("ahi\t%1,%2", op
);
7902 else if (CONST_OK_FOR_Os (delta
))
7903 output_asm_insn ("afi\t%1,%2", op
);
7906 op
[6] = gen_label_rtx ();
7907 output_asm_insn ("a\t%1,%6-%5(%4)", op
);
7911 /* Perform vcall adjustment. */
7914 if (CONST_OK_FOR_J (vcall_offset
))
7916 output_asm_insn ("l\t%4,0(%1)", op
);
7917 output_asm_insn ("a\t%1,%3(%4)", op
);
7919 else if (DISP_IN_RANGE (vcall_offset
))
7921 output_asm_insn ("l\t%4,0(%1)", op
);
7922 output_asm_insn ("ay\t%1,%3(%4)", op
);
7924 else if (CONST_OK_FOR_K (vcall_offset
))
7926 output_asm_insn ("lhi\t%4,%3", op
);
7927 output_asm_insn ("a\t%4,0(%1)", op
);
7928 output_asm_insn ("a\t%1,0(%4)", op
);
7930 else if (CONST_OK_FOR_Os (vcall_offset
))
7932 output_asm_insn ("iilf\t%4,%3", op
);
7933 output_asm_insn ("a\t%4,0(%1)", op
);
7934 output_asm_insn ("a\t%1,0(%4)", op
);
7938 op
[7] = gen_label_rtx ();
7939 output_asm_insn ("l\t%4,%7-%5(%4)", op
);
7940 output_asm_insn ("a\t%4,0(%1)", op
);
7941 output_asm_insn ("a\t%1,0(%4)", op
);
7944 /* We had to clobber the base pointer register.
7945 Re-setup the base pointer (with a different base). */
7946 op
[5] = gen_label_rtx ();
7947 output_asm_insn ("basr\t%4,0", op
);
7948 targetm
.asm_out
.internal_label (file
, "L",
7949 CODE_LABEL_NUMBER (op
[5]));
7952 /* Jump to target. */
7953 op
[8] = gen_label_rtx ();
7956 output_asm_insn ("l\t%4,%8-%5(%4)", op
);
7958 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
7959 /* We cannot call through .plt, since .plt requires %r12 loaded. */
7960 else if (flag_pic
== 1)
7962 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
7963 output_asm_insn ("l\t%4,%0(%4)", op
);
7965 else if (flag_pic
== 2)
7967 op
[9] = gen_rtx_REG (Pmode
, 0);
7968 output_asm_insn ("l\t%9,%8-4-%5(%4)", op
);
7969 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
7970 output_asm_insn ("ar\t%4,%9", op
);
7971 output_asm_insn ("l\t%4,0(%4)", op
);
7974 output_asm_insn ("br\t%4", op
);
7976 /* Output literal pool. */
7977 output_asm_insn (".align\t4", op
);
7979 if (nonlocal
&& flag_pic
== 2)
7980 output_asm_insn (".long\t%0", op
);
7983 op
[0] = gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
7984 SYMBOL_REF_FLAGS (op
[0]) = SYMBOL_FLAG_LOCAL
;
7987 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[8]));
7989 output_asm_insn (".long\t%0", op
);
7991 output_asm_insn (".long\t%0-%5", op
);
7995 targetm
.asm_out
.internal_label (file
, "L",
7996 CODE_LABEL_NUMBER (op
[6]));
7997 output_asm_insn (".long\t%2", op
);
8001 targetm
.asm_out
.internal_label (file
, "L",
8002 CODE_LABEL_NUMBER (op
[7]));
8003 output_asm_insn (".long\t%3", op
);
8009 s390_valid_pointer_mode (enum machine_mode mode
)
8011 return (mode
== SImode
|| (TARGET_64BIT
&& mode
== DImode
));
8014 /* Checks whether the given ARGUMENT_LIST would use a caller
8015 saved register. This is used to decide whether sibling call
8016 optimization could be performed on the respective function
8020 s390_call_saved_register_used (tree argument_list
)
8022 CUMULATIVE_ARGS cum
;
8024 enum machine_mode mode
;
8029 INIT_CUMULATIVE_ARGS (cum
, NULL
, NULL
, 0, 0);
8031 while (argument_list
)
8033 parameter
= TREE_VALUE (argument_list
);
8034 argument_list
= TREE_CHAIN (argument_list
);
8036 gcc_assert (parameter
);
8038 /* For an undeclared variable passed as parameter we will get
8039 an ERROR_MARK node here. */
8040 if (TREE_CODE (parameter
) == ERROR_MARK
)
8043 type
= TREE_TYPE (parameter
);
8046 mode
= TYPE_MODE (type
);
8049 if (pass_by_reference (&cum
, mode
, type
, true))
8052 type
= build_pointer_type (type
);
8055 parm_rtx
= s390_function_arg (&cum
, mode
, type
, 0);
8057 s390_function_arg_advance (&cum
, mode
, type
, 0);
8059 if (parm_rtx
&& REG_P (parm_rtx
))
8062 reg
< HARD_REGNO_NREGS (REGNO (parm_rtx
), GET_MODE (parm_rtx
));
8064 if (! call_used_regs
[reg
+ REGNO (parm_rtx
)])
8071 /* Return true if the given call expression can be
8072 turned into a sibling call.
8073 DECL holds the declaration of the function to be called whereas
8074 EXP is the call expression itself. */
8077 s390_function_ok_for_sibcall (tree decl
, tree exp
)
8079 /* The TPF epilogue uses register 1. */
8080 if (TARGET_TPF_PROFILING
)
8083 /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
8084 which would have to be restored before the sibcall. */
8085 if (!TARGET_64BIT
&& flag_pic
&& decl
&& TREE_PUBLIC (decl
))
8088 /* Register 6 on s390 is available as an argument register but unfortunately
8089 "caller saved". This makes functions needing this register for arguments
8090 not suitable for sibcalls. */
8091 if (TREE_OPERAND (exp
, 1)
8092 && s390_call_saved_register_used (TREE_OPERAND (exp
, 1)))
8098 /* Return the fixed registers used for condition codes. */
8101 s390_fixed_condition_code_regs (unsigned int *p1
, unsigned int *p2
)
8104 *p2
= INVALID_REGNUM
;
8109 /* This function is used by the call expanders of the machine description.
8110 It emits the call insn itself together with the necessary operations
8111 to adjust the target address and returns the emitted insn.
8112 ADDR_LOCATION is the target address rtx
8113 TLS_CALL the location of the thread-local symbol
8114 RESULT_REG the register where the result of the call should be stored
8115 RETADDR_REG the register where the return address should be stored
8116 If this parameter is NULL_RTX the call is considered
8117 to be a sibling call. */
8120 s390_emit_call (rtx addr_location
, rtx tls_call
, rtx result_reg
,
8123 bool plt_call
= false;
8129 /* Direct function calls need special treatment. */
8130 if (GET_CODE (addr_location
) == SYMBOL_REF
)
8132 /* When calling a global routine in PIC mode, we must
8133 replace the symbol itself with the PLT stub. */
8134 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (addr_location
))
8136 addr_location
= gen_rtx_UNSPEC (Pmode
,
8137 gen_rtvec (1, addr_location
),
8139 addr_location
= gen_rtx_CONST (Pmode
, addr_location
);
8143 /* Unless we can use the bras(l) insn, force the
8144 routine address into a register. */
8145 if (!TARGET_SMALL_EXEC
&& !TARGET_CPU_ZARCH
)
8148 addr_location
= legitimize_pic_address (addr_location
, 0);
8150 addr_location
= force_reg (Pmode
, addr_location
);
8154 /* If it is already an indirect call or the code above moved the
8155 SYMBOL_REF to somewhere else make sure the address can be found in
8157 if (retaddr_reg
== NULL_RTX
8158 && GET_CODE (addr_location
) != SYMBOL_REF
8161 emit_move_insn (gen_rtx_REG (Pmode
, SIBCALL_REGNUM
), addr_location
);
8162 addr_location
= gen_rtx_REG (Pmode
, SIBCALL_REGNUM
);
8165 addr_location
= gen_rtx_MEM (QImode
, addr_location
);
8166 call
= gen_rtx_CALL (VOIDmode
, addr_location
, const0_rtx
);
8168 if (result_reg
!= NULL_RTX
)
8169 call
= gen_rtx_SET (VOIDmode
, result_reg
, call
);
8171 if (retaddr_reg
!= NULL_RTX
)
8173 clobber
= gen_rtx_CLOBBER (VOIDmode
, retaddr_reg
);
8175 if (tls_call
!= NULL_RTX
)
8176 vec
= gen_rtvec (3, call
, clobber
,
8177 gen_rtx_USE (VOIDmode
, tls_call
));
8179 vec
= gen_rtvec (2, call
, clobber
);
8181 call
= gen_rtx_PARALLEL (VOIDmode
, vec
);
8184 insn
= emit_call_insn (call
);
8186 /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
8187 if ((!TARGET_64BIT
&& plt_call
) || tls_call
!= NULL_RTX
)
8189 /* s390_function_ok_for_sibcall should
8190 have denied sibcalls in this case. */
8191 gcc_assert (retaddr_reg
!= NULL_RTX
);
8193 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), pic_offset_table_rtx
);
8198 /* Implement CONDITIONAL_REGISTER_USAGE. */
8201 s390_conditional_register_usage (void)
8207 fixed_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
8208 call_used_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
8210 if (TARGET_CPU_ZARCH
)
8212 fixed_regs
[RETURN_REGNUM
] = 0;
8213 call_used_regs
[RETURN_REGNUM
] = 0;
8217 for (i
= 24; i
< 32; i
++)
8218 call_used_regs
[i
] = call_really_used_regs
[i
] = 0;
8222 for (i
= 18; i
< 20; i
++)
8223 call_used_regs
[i
] = call_really_used_regs
[i
] = 0;
8226 if (TARGET_SOFT_FLOAT
)
8228 for (i
= 16; i
< 32; i
++)
8229 call_used_regs
[i
] = fixed_regs
[i
] = 1;
8233 /* Corresponding function to eh_return expander. */
8235 static GTY(()) rtx s390_tpf_eh_return_symbol
;
8237 s390_emit_tpf_eh_return (rtx target
)
8241 if (!s390_tpf_eh_return_symbol
)
8242 s390_tpf_eh_return_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "__tpf_eh_return");
8244 reg
= gen_rtx_REG (Pmode
, 2);
8246 emit_move_insn (reg
, target
);
8247 insn
= s390_emit_call (s390_tpf_eh_return_symbol
, NULL_RTX
, reg
,
8248 gen_rtx_REG (Pmode
, RETURN_REGNUM
));
8249 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), reg
);
8251 emit_move_insn (EH_RETURN_HANDLER_RTX
, reg
);
8254 /* Rework the prologue/epilogue to avoid saving/restoring
8255 registers unnecessarily. */
8258 s390_optimize_prologue (void)
8260 rtx insn
, new_insn
, next_insn
;
8262 /* Do a final recompute of the frame-related data. */
8264 s390_update_frame_layout ();
8266 /* If all special registers are in fact used, there's nothing we
8267 can do, so no point in walking the insn list. */
8269 if (cfun_frame_layout
.first_save_gpr
<= BASE_REGNUM
8270 && cfun_frame_layout
.last_save_gpr
>= BASE_REGNUM
8271 && (TARGET_CPU_ZARCH
8272 || (cfun_frame_layout
.first_save_gpr
<= RETURN_REGNUM
8273 && cfun_frame_layout
.last_save_gpr
>= RETURN_REGNUM
)))
8276 /* Search for prologue/epilogue insns and replace them. */
8278 for (insn
= get_insns (); insn
; insn
= next_insn
)
8280 int first
, last
, off
;
8281 rtx set
, base
, offset
;
8283 next_insn
= NEXT_INSN (insn
);
8285 if (GET_CODE (insn
) != INSN
)
8288 if (GET_CODE (PATTERN (insn
)) == PARALLEL
8289 && store_multiple_operation (PATTERN (insn
), VOIDmode
))
8291 set
= XVECEXP (PATTERN (insn
), 0, 0);
8292 first
= REGNO (SET_SRC (set
));
8293 last
= first
+ XVECLEN (PATTERN (insn
), 0) - 1;
8294 offset
= const0_rtx
;
8295 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
8296 off
= INTVAL (offset
);
8298 if (GET_CODE (base
) != REG
|| off
< 0)
8300 if (cfun_frame_layout
.first_save_gpr
!= -1
8301 && (cfun_frame_layout
.first_save_gpr
< first
8302 || cfun_frame_layout
.last_save_gpr
> last
))
8304 if (REGNO (base
) != STACK_POINTER_REGNUM
8305 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
8307 if (first
> BASE_REGNUM
|| last
< BASE_REGNUM
)
8310 if (cfun_frame_layout
.first_save_gpr
!= -1)
8312 new_insn
= save_gprs (base
,
8313 off
+ (cfun_frame_layout
.first_save_gpr
8314 - first
) * UNITS_PER_WORD
,
8315 cfun_frame_layout
.first_save_gpr
,
8316 cfun_frame_layout
.last_save_gpr
);
8317 new_insn
= emit_insn_before (new_insn
, insn
);
8318 INSN_ADDRESSES_NEW (new_insn
, -1);
8325 if (cfun_frame_layout
.first_save_gpr
== -1
8326 && GET_CODE (PATTERN (insn
)) == SET
8327 && GET_CODE (SET_SRC (PATTERN (insn
))) == REG
8328 && (REGNO (SET_SRC (PATTERN (insn
))) == BASE_REGNUM
8329 || (!TARGET_CPU_ZARCH
8330 && REGNO (SET_SRC (PATTERN (insn
))) == RETURN_REGNUM
))
8331 && GET_CODE (SET_DEST (PATTERN (insn
))) == MEM
)
8333 set
= PATTERN (insn
);
8334 first
= REGNO (SET_SRC (set
));
8335 offset
= const0_rtx
;
8336 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
8337 off
= INTVAL (offset
);
8339 if (GET_CODE (base
) != REG
|| off
< 0)
8341 if (REGNO (base
) != STACK_POINTER_REGNUM
8342 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
8349 if (GET_CODE (PATTERN (insn
)) == PARALLEL
8350 && load_multiple_operation (PATTERN (insn
), VOIDmode
))
8352 set
= XVECEXP (PATTERN (insn
), 0, 0);
8353 first
= REGNO (SET_DEST (set
));
8354 last
= first
+ XVECLEN (PATTERN (insn
), 0) - 1;
8355 offset
= const0_rtx
;
8356 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
8357 off
= INTVAL (offset
);
8359 if (GET_CODE (base
) != REG
|| off
< 0)
8361 if (cfun_frame_layout
.first_restore_gpr
!= -1
8362 && (cfun_frame_layout
.first_restore_gpr
< first
8363 || cfun_frame_layout
.last_restore_gpr
> last
))
8365 if (REGNO (base
) != STACK_POINTER_REGNUM
8366 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
8368 if (first
> BASE_REGNUM
|| last
< BASE_REGNUM
)
8371 if (cfun_frame_layout
.first_restore_gpr
!= -1)
8373 new_insn
= restore_gprs (base
,
8374 off
+ (cfun_frame_layout
.first_restore_gpr
8375 - first
) * UNITS_PER_WORD
,
8376 cfun_frame_layout
.first_restore_gpr
,
8377 cfun_frame_layout
.last_restore_gpr
);
8378 new_insn
= emit_insn_before (new_insn
, insn
);
8379 INSN_ADDRESSES_NEW (new_insn
, -1);
8386 if (cfun_frame_layout
.first_restore_gpr
== -1
8387 && GET_CODE (PATTERN (insn
)) == SET
8388 && GET_CODE (SET_DEST (PATTERN (insn
))) == REG
8389 && (REGNO (SET_DEST (PATTERN (insn
))) == BASE_REGNUM
8390 || (!TARGET_CPU_ZARCH
8391 && REGNO (SET_DEST (PATTERN (insn
))) == RETURN_REGNUM
))
8392 && GET_CODE (SET_SRC (PATTERN (insn
))) == MEM
)
8394 set
= PATTERN (insn
);
8395 first
= REGNO (SET_DEST (set
));
8396 offset
= const0_rtx
;
8397 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
8398 off
= INTVAL (offset
);
8400 if (GET_CODE (base
) != REG
|| off
< 0)
8402 if (REGNO (base
) != STACK_POINTER_REGNUM
8403 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
8412 /* Perform machine-dependent processing. */
8417 bool pool_overflow
= false;
8419 /* Make sure all splits have been performed; splits after
8420 machine_dependent_reorg might confuse insn length counts. */
8421 split_all_insns_noflow ();
8424 /* Install the main literal pool and the associated base
8425 register load insns.
8427 In addition, there are two problematic situations we need
8430 - the literal pool might be > 4096 bytes in size, so that
8431 some of its elements cannot be directly accessed
8433 - a branch target might be > 64K away from the branch, so that
8434 it is not possible to use a PC-relative instruction.
8436 To fix those, we split the single literal pool into multiple
8437 pool chunks, reloading the pool base register at various
8438 points throughout the function to ensure it always points to
8439 the pool chunk the following code expects, and / or replace
8440 PC-relative branches by absolute branches.
8442 However, the two problems are interdependent: splitting the
8443 literal pool can move a branch further away from its target,
8444 causing the 64K limit to overflow, and on the other hand,
8445 replacing a PC-relative branch by an absolute branch means
8446 we need to put the branch target address into the literal
8447 pool, possibly causing it to overflow.
8449 So, we loop trying to fix up both problems until we manage
8450 to satisfy both conditions at the same time. Note that the
8451 loop is guaranteed to terminate as every pass of the loop
8452 strictly decreases the total number of PC-relative branches
8453 in the function. (This is not completely true as there
8454 might be branch-over-pool insns introduced by chunkify_start.
8455 Those never need to be split however.) */
8459 struct constant_pool
*pool
= NULL
;
8461 /* Collect the literal pool. */
8464 pool
= s390_mainpool_start ();
8466 pool_overflow
= true;
8469 /* If literal pool overflowed, start to chunkify it. */
8471 pool
= s390_chunkify_start ();
8473 /* Split out-of-range branches. If this has created new
8474 literal pool entries, cancel current chunk list and
8475 recompute it. zSeries machines have large branch
8476 instructions, so we never need to split a branch. */
8477 if (!TARGET_CPU_ZARCH
&& s390_split_branches ())
8480 s390_chunkify_cancel (pool
);
8482 s390_mainpool_cancel (pool
);
8487 /* If we made it up to here, both conditions are satisfied.
8488 Finish up literal pool related changes. */
8490 s390_chunkify_finish (pool
);
8492 s390_mainpool_finish (pool
);
8494 /* We're done splitting branches. */
8495 cfun
->machine
->split_branches_pending_p
= false;
8499 /* Generate out-of-pool execute target insns. */
8500 if (TARGET_CPU_ZARCH
)
8502 rtx insn
, label
, target
;
8504 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
8506 label
= s390_execute_label (insn
);
8510 gcc_assert (label
!= const0_rtx
);
8512 target
= emit_label (XEXP (label
, 0));
8513 INSN_ADDRESSES_NEW (target
, -1);
8515 target
= emit_insn (s390_execute_target (insn
));
8516 INSN_ADDRESSES_NEW (target
, -1);
8520 /* Try to optimize prologue and epilogue further. */
8521 s390_optimize_prologue ();
8525 /* Initialize GCC target structure. */
8527 #undef TARGET_ASM_ALIGNED_HI_OP
8528 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
8529 #undef TARGET_ASM_ALIGNED_DI_OP
8530 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
8531 #undef TARGET_ASM_INTEGER
8532 #define TARGET_ASM_INTEGER s390_assemble_integer
8534 #undef TARGET_ASM_OPEN_PAREN
8535 #define TARGET_ASM_OPEN_PAREN ""
8537 #undef TARGET_ASM_CLOSE_PAREN
8538 #define TARGET_ASM_CLOSE_PAREN ""
8540 #undef TARGET_DEFAULT_TARGET_FLAGS
8541 #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD)
8542 #undef TARGET_HANDLE_OPTION
8543 #define TARGET_HANDLE_OPTION s390_handle_option
8545 #undef TARGET_ENCODE_SECTION_INFO
8546 #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
8549 #undef TARGET_HAVE_TLS
8550 #define TARGET_HAVE_TLS true
8552 #undef TARGET_CANNOT_FORCE_CONST_MEM
8553 #define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
8555 #undef TARGET_DELEGITIMIZE_ADDRESS
8556 #define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
8558 #undef TARGET_RETURN_IN_MEMORY
8559 #define TARGET_RETURN_IN_MEMORY s390_return_in_memory
8561 #undef TARGET_INIT_BUILTINS
8562 #define TARGET_INIT_BUILTINS s390_init_builtins
8563 #undef TARGET_EXPAND_BUILTIN
8564 #define TARGET_EXPAND_BUILTIN s390_expand_builtin
8566 #undef TARGET_ASM_OUTPUT_MI_THUNK
8567 #define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
8568 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
8569 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
8571 #undef TARGET_SCHED_ADJUST_PRIORITY
8572 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
8573 #undef TARGET_SCHED_ISSUE_RATE
8574 #define TARGET_SCHED_ISSUE_RATE s390_issue_rate
8575 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
8576 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
8578 #undef TARGET_CANNOT_COPY_INSN_P
8579 #define TARGET_CANNOT_COPY_INSN_P s390_cannot_copy_insn_p
8580 #undef TARGET_RTX_COSTS
8581 #define TARGET_RTX_COSTS s390_rtx_costs
8582 #undef TARGET_ADDRESS_COST
8583 #define TARGET_ADDRESS_COST s390_address_cost
8585 #undef TARGET_MACHINE_DEPENDENT_REORG
8586 #define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
8588 #undef TARGET_VALID_POINTER_MODE
8589 #define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
8591 #undef TARGET_BUILD_BUILTIN_VA_LIST
8592 #define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
8593 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
8594 #define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg
8596 #undef TARGET_PROMOTE_FUNCTION_ARGS
8597 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
8598 #undef TARGET_PROMOTE_FUNCTION_RETURN
8599 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
8600 #undef TARGET_PASS_BY_REFERENCE
8601 #define TARGET_PASS_BY_REFERENCE s390_pass_by_reference
8603 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
8604 #define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
8606 #undef TARGET_FIXED_CONDITION_CODE_REGS
8607 #define TARGET_FIXED_CONDITION_CODE_REGS s390_fixed_condition_code_regs
8609 #undef TARGET_CC_MODES_COMPATIBLE
8610 #define TARGET_CC_MODES_COMPATIBLE s390_cc_modes_compatible
8612 #undef TARGET_INVALID_WITHIN_DOLOOP
8613 #define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_rtx_null
8616 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
8617 #define TARGET_ASM_OUTPUT_DWARF_DTPREL s390_output_dwarf_dtprel
8620 struct gcc_target targetm
= TARGET_INITIALIZER
;
8622 #include "gt-s390.h"