1 /* Subroutines used for code generation on IBM S/390 and zSeries
2 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
3 Free Software Foundation, Inc.
4 Contributed by Hartmut Penner (hpenner@de.ibm.com) and
5 Ulrich Weigand (uweigand@de.ibm.com).
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
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. */
76 const int sqxbr
; /* cost of square root in TFmode. */
77 const int sqdbr
; /* cost of square root in DFmode. */
78 const int sqebr
; /* cost of square root in SFmode. */
79 /* multiply and add */
80 const int madbr
; /* cost of multiply and add in DFmode. */
81 const int maebr
; /* cost of multiply and add in SFmode. */
96 const struct processor_costs
*s390_cost
;
99 struct processor_costs z900_cost
=
101 COSTS_N_INSNS (5), /* M */
102 COSTS_N_INSNS (10), /* MGHI */
103 COSTS_N_INSNS (5), /* MH */
104 COSTS_N_INSNS (4), /* MHI */
105 COSTS_N_INSNS (5), /* ML */
106 COSTS_N_INSNS (5), /* MR */
107 COSTS_N_INSNS (4), /* MS */
108 COSTS_N_INSNS (15), /* MSG */
109 COSTS_N_INSNS (7), /* MSGF */
110 COSTS_N_INSNS (7), /* MSGFR */
111 COSTS_N_INSNS (10), /* MSGR */
112 COSTS_N_INSNS (4), /* MSR */
113 COSTS_N_INSNS (7), /* multiplication in DFmode */
114 COSTS_N_INSNS (13), /* MXBR */
115 COSTS_N_INSNS (136), /* SQXBR */
116 COSTS_N_INSNS (44), /* SQDBR */
117 COSTS_N_INSNS (35), /* SQEBR */
118 COSTS_N_INSNS (18), /* MADBR */
119 COSTS_N_INSNS (13), /* MAEBR */
120 COSTS_N_INSNS (134), /* DXBR */
121 COSTS_N_INSNS (135), /* DXR */
122 COSTS_N_INSNS (30), /* DDBR */
123 COSTS_N_INSNS (30), /* DDR */
124 COSTS_N_INSNS (27), /* DEBR */
125 COSTS_N_INSNS (26), /* DER */
126 COSTS_N_INSNS (220), /* DLGR */
127 COSTS_N_INSNS (34), /* DLR */
128 COSTS_N_INSNS (34), /* DR */
129 COSTS_N_INSNS (32), /* DSGFR */
130 COSTS_N_INSNS (32), /* DSGR */
134 struct processor_costs z990_cost
=
136 COSTS_N_INSNS (4), /* M */
137 COSTS_N_INSNS (2), /* MGHI */
138 COSTS_N_INSNS (2), /* MH */
139 COSTS_N_INSNS (2), /* MHI */
140 COSTS_N_INSNS (4), /* ML */
141 COSTS_N_INSNS (4), /* MR */
142 COSTS_N_INSNS (5), /* MS */
143 COSTS_N_INSNS (6), /* MSG */
144 COSTS_N_INSNS (4), /* MSGF */
145 COSTS_N_INSNS (4), /* MSGFR */
146 COSTS_N_INSNS (4), /* MSGR */
147 COSTS_N_INSNS (4), /* MSR */
148 COSTS_N_INSNS (1), /* multiplication in DFmode */
149 COSTS_N_INSNS (28), /* MXBR */
150 COSTS_N_INSNS (130), /* SQXBR */
151 COSTS_N_INSNS (66), /* SQDBR */
152 COSTS_N_INSNS (38), /* SQEBR */
153 COSTS_N_INSNS (1), /* MADBR */
154 COSTS_N_INSNS (1), /* MAEBR */
155 COSTS_N_INSNS (60), /* DXBR */
156 COSTS_N_INSNS (72), /* DXR */
157 COSTS_N_INSNS (40), /* DDBR */
158 COSTS_N_INSNS (44), /* DDR */
159 COSTS_N_INSNS (26), /* DDBR */
160 COSTS_N_INSNS (28), /* DER */
161 COSTS_N_INSNS (176), /* DLGR */
162 COSTS_N_INSNS (31), /* DLR */
163 COSTS_N_INSNS (31), /* DR */
164 COSTS_N_INSNS (31), /* DSGFR */
165 COSTS_N_INSNS (31), /* DSGR */
169 struct processor_costs z9_109_cost
=
171 COSTS_N_INSNS (4), /* M */
172 COSTS_N_INSNS (2), /* MGHI */
173 COSTS_N_INSNS (2), /* MH */
174 COSTS_N_INSNS (2), /* MHI */
175 COSTS_N_INSNS (4), /* ML */
176 COSTS_N_INSNS (4), /* MR */
177 COSTS_N_INSNS (5), /* MS */
178 COSTS_N_INSNS (6), /* MSG */
179 COSTS_N_INSNS (4), /* MSGF */
180 COSTS_N_INSNS (4), /* MSGFR */
181 COSTS_N_INSNS (4), /* MSGR */
182 COSTS_N_INSNS (4), /* MSR */
183 COSTS_N_INSNS (1), /* multiplication in DFmode */
184 COSTS_N_INSNS (28), /* MXBR */
185 COSTS_N_INSNS (130), /* SQXBR */
186 COSTS_N_INSNS (66), /* SQDBR */
187 COSTS_N_INSNS (38), /* SQEBR */
188 COSTS_N_INSNS (1), /* MADBR */
189 COSTS_N_INSNS (1), /* MAEBR */
190 COSTS_N_INSNS (60), /* DXBR */
191 COSTS_N_INSNS (72), /* DXR */
192 COSTS_N_INSNS (40), /* DDBR */
193 COSTS_N_INSNS (37), /* DDR */
194 COSTS_N_INSNS (26), /* DDBR */
195 COSTS_N_INSNS (28), /* DER */
196 COSTS_N_INSNS (30), /* DLGR */
197 COSTS_N_INSNS (23), /* DLR */
198 COSTS_N_INSNS (23), /* DR */
199 COSTS_N_INSNS (24), /* DSGFR */
200 COSTS_N_INSNS (24), /* DSGR */
203 extern int reload_completed
;
205 /* Save information from a "cmpxx" operation until the branch or scc is
207 rtx s390_compare_op0
, s390_compare_op1
;
209 /* Save the result of a compare_and_swap until the branch or scc is
211 rtx s390_compare_emitted
= NULL_RTX
;
213 /* Structure used to hold the components of a S/390 memory
214 address. A legitimate address on S/390 is of the general
216 base + index + displacement
217 where any of the components is optional.
219 base and index are registers of the class ADDR_REGS,
220 displacement is an unsigned 12-bit immediate constant. */
231 /* Which cpu are we tuning for. */
232 enum processor_type s390_tune
= PROCESSOR_max
;
233 enum processor_flags s390_tune_flags
;
234 /* Which instruction set architecture to use. */
235 enum processor_type s390_arch
;
236 enum processor_flags s390_arch_flags
;
238 HOST_WIDE_INT s390_warn_framesize
= 0;
239 HOST_WIDE_INT s390_stack_size
= 0;
240 HOST_WIDE_INT s390_stack_guard
= 0;
242 /* The following structure is embedded in the machine
243 specific part of struct function. */
245 struct s390_frame_layout
GTY (())
247 /* Offset within stack frame. */
248 HOST_WIDE_INT gprs_offset
;
249 HOST_WIDE_INT f0_offset
;
250 HOST_WIDE_INT f4_offset
;
251 HOST_WIDE_INT f8_offset
;
252 HOST_WIDE_INT backchain_offset
;
254 /* Number of first and last gpr where slots in the register
255 save area are reserved for. */
256 int first_save_gpr_slot
;
257 int last_save_gpr_slot
;
259 /* Number of first and last gpr to be saved, restored. */
261 int first_restore_gpr
;
263 int last_restore_gpr
;
265 /* Bits standing for floating point registers. Set, if the
266 respective register has to be saved. Starting with reg 16 (f0)
267 at the rightmost bit.
268 Bit 15 - 8 7 6 5 4 3 2 1 0
269 fpr 15 - 8 7 5 3 1 6 4 2 0
270 reg 31 - 24 23 22 21 20 19 18 17 16 */
271 unsigned int fpr_bitmap
;
273 /* Number of floating point registers f8-f15 which must be saved. */
276 /* Set if return address needs to be saved.
277 This flag is set by s390_return_addr_rtx if it could not use
278 the initial value of r14 and therefore depends on r14 saved
280 bool save_return_addr_p
;
282 /* Size of stack frame. */
283 HOST_WIDE_INT frame_size
;
286 /* Define the structure for the machine field in struct function. */
288 struct machine_function
GTY(())
290 struct s390_frame_layout frame_layout
;
292 /* Literal pool base register. */
295 /* True if we may need to perform branch splitting. */
296 bool split_branches_pending_p
;
298 /* True during final stage of literal pool processing. */
299 bool decomposed_literal_pool_addresses_ok_p
;
301 /* Some local-dynamic TLS symbol name. */
302 const char *some_ld_name
;
304 bool has_landing_pad_p
;
307 /* Few accessor macros for struct cfun->machine->s390_frame_layout. */
309 #define cfun_frame_layout (cfun->machine->frame_layout)
310 #define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)
311 #define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr_slot - \
312 cfun_frame_layout.first_save_gpr_slot + 1) * UNITS_PER_WORD)
313 #define cfun_set_fpr_bit(BITNUM) (cfun->machine->frame_layout.fpr_bitmap |= \
315 #define cfun_fpr_bit_p(BITNUM) (!!(cfun->machine->frame_layout.fpr_bitmap & \
318 /* Number of GPRs and FPRs used for argument passing. */
319 #define GP_ARG_NUM_REG 5
320 #define FP_ARG_NUM_REG (TARGET_64BIT? 4 : 2)
322 /* A couple of shortcuts. */
323 #define CONST_OK_FOR_J(x) \
324 CONST_OK_FOR_CONSTRAINT_P((x), 'J', "J")
325 #define CONST_OK_FOR_K(x) \
326 CONST_OK_FOR_CONSTRAINT_P((x), 'K', "K")
327 #define CONST_OK_FOR_Os(x) \
328 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Os")
329 #define CONST_OK_FOR_Op(x) \
330 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Op")
331 #define CONST_OK_FOR_On(x) \
332 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "On")
334 #define REGNO_PAIR_OK(REGNO, MODE) \
335 (HARD_REGNO_NREGS ((REGNO), (MODE)) == 1 || !((REGNO) & 1))
337 /* Return true if the back end supports mode MODE. */
339 s390_scalar_mode_supported_p (enum machine_mode mode
)
341 if (DECIMAL_FLOAT_MODE_P (mode
))
344 return default_scalar_mode_supported_p (mode
);
347 /* Set the has_landing_pad_p flag in struct machine_function to VALUE. */
350 s390_set_has_landing_pad_p (bool value
)
352 cfun
->machine
->has_landing_pad_p
= value
;
355 /* If two condition code modes are compatible, return a condition code
356 mode which is compatible with both. Otherwise, return
359 static enum machine_mode
360 s390_cc_modes_compatible (enum machine_mode m1
, enum machine_mode m2
)
368 if (m2
== CCUmode
|| m2
== CCTmode
|| m2
== CCZ1mode
369 || m2
== CCSmode
|| m2
== CCSRmode
|| m2
== CCURmode
)
390 /* Return true if SET either doesn't set the CC register, or else
391 the source and destination have matching CC modes and that
392 CC mode is at least as constrained as REQ_MODE. */
395 s390_match_ccmode_set (rtx set
, enum machine_mode req_mode
)
397 enum machine_mode set_mode
;
399 gcc_assert (GET_CODE (set
) == SET
);
401 if (GET_CODE (SET_DEST (set
)) != REG
|| !CC_REGNO_P (REGNO (SET_DEST (set
))))
404 set_mode
= GET_MODE (SET_DEST (set
));
418 if (req_mode
!= set_mode
)
423 if (req_mode
!= CCSmode
&& req_mode
!= CCUmode
&& req_mode
!= CCTmode
424 && req_mode
!= CCSRmode
&& req_mode
!= CCURmode
)
430 if (req_mode
!= CCAmode
)
438 return (GET_MODE (SET_SRC (set
)) == set_mode
);
441 /* Return true if every SET in INSN that sets the CC register
442 has source and destination with matching CC modes and that
443 CC mode is at least as constrained as REQ_MODE.
444 If REQ_MODE is VOIDmode, always return false. */
447 s390_match_ccmode (rtx insn
, enum machine_mode req_mode
)
451 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
452 if (req_mode
== VOIDmode
)
455 if (GET_CODE (PATTERN (insn
)) == SET
)
456 return s390_match_ccmode_set (PATTERN (insn
), req_mode
);
458 if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
459 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
461 rtx set
= XVECEXP (PATTERN (insn
), 0, i
);
462 if (GET_CODE (set
) == SET
)
463 if (!s390_match_ccmode_set (set
, req_mode
))
470 /* If a test-under-mask instruction can be used to implement
471 (compare (and ... OP1) OP2), return the CC mode required
472 to do that. Otherwise, return VOIDmode.
473 MIXED is true if the instruction can distinguish between
474 CC1 and CC2 for mixed selected bits (TMxx), it is false
475 if the instruction cannot (TM). */
478 s390_tm_ccmode (rtx op1
, rtx op2
, bool mixed
)
482 /* ??? Fixme: should work on CONST_DOUBLE as well. */
483 if (GET_CODE (op1
) != CONST_INT
|| GET_CODE (op2
) != CONST_INT
)
486 /* Selected bits all zero: CC0.
487 e.g.: int a; if ((a & (16 + 128)) == 0) */
488 if (INTVAL (op2
) == 0)
491 /* Selected bits all one: CC3.
492 e.g.: int a; if ((a & (16 + 128)) == 16 + 128) */
493 if (INTVAL (op2
) == INTVAL (op1
))
496 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. e.g.:
498 if ((a & (16 + 128)) == 16) -> CCT1
499 if ((a & (16 + 128)) == 128) -> CCT2 */
502 bit1
= exact_log2 (INTVAL (op2
));
503 bit0
= exact_log2 (INTVAL (op1
) ^ INTVAL (op2
));
504 if (bit0
!= -1 && bit1
!= -1)
505 return bit0
> bit1
? CCT1mode
: CCT2mode
;
511 /* Given a comparison code OP (EQ, NE, etc.) and the operands
512 OP0 and OP1 of a COMPARE, return the mode to be used for the
516 s390_select_ccmode (enum rtx_code code
, rtx op0
, rtx op1
)
522 if ((GET_CODE (op0
) == NEG
|| GET_CODE (op0
) == ABS
)
523 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
525 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
526 && CONST_OK_FOR_K (INTVAL (XEXP (op0
, 1))))
528 if ((GET_CODE (op0
) == PLUS
|| GET_CODE (op0
) == MINUS
529 || GET_CODE (op1
) == NEG
)
530 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
533 if (GET_CODE (op0
) == AND
)
535 /* Check whether we can potentially do it via TM. */
536 enum machine_mode ccmode
;
537 ccmode
= s390_tm_ccmode (XEXP (op0
, 1), op1
, 1);
538 if (ccmode
!= VOIDmode
)
540 /* Relax CCTmode to CCZmode to allow fall-back to AND
541 if that turns out to be beneficial. */
542 return ccmode
== CCTmode
? CCZmode
: ccmode
;
546 if (register_operand (op0
, HImode
)
547 && GET_CODE (op1
) == CONST_INT
548 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 65535))
550 if (register_operand (op0
, QImode
)
551 && GET_CODE (op1
) == CONST_INT
552 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 255))
561 /* The only overflow condition of NEG and ABS happens when
562 -INT_MAX is used as parameter, which stays negative. So
563 we have an overflow from a positive value to a negative.
564 Using CCAP mode the resulting cc can be used for comparisons. */
565 if ((GET_CODE (op0
) == NEG
|| GET_CODE (op0
) == ABS
)
566 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
569 /* If constants are involved in an add instruction it is possible to use
570 the resulting cc for comparisons with zero. Knowing the sign of the
571 constant the overflow behavior gets predictable. e.g.:
572 int a, b; if ((b = a + c) > 0)
573 with c as a constant value: c < 0 -> CCAN and c >= 0 -> CCAP */
574 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
575 && CONST_OK_FOR_K (INTVAL (XEXP (op0
, 1))))
577 if (INTVAL (XEXP((op0
), 1)) < 0)
591 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
592 && GET_CODE (op1
) != CONST_INT
)
598 if (GET_CODE (op0
) == PLUS
599 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
602 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
603 && GET_CODE (op1
) != CONST_INT
)
609 if (GET_CODE (op0
) == MINUS
610 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
613 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
614 && GET_CODE (op1
) != CONST_INT
)
623 /* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
624 that we can implement more efficiently. */
627 s390_canonicalize_comparison (enum rtx_code
*code
, rtx
*op0
, rtx
*op1
)
629 /* Convert ZERO_EXTRACT back to AND to enable TM patterns. */
630 if ((*code
== EQ
|| *code
== NE
)
631 && *op1
== const0_rtx
632 && GET_CODE (*op0
) == ZERO_EXTRACT
633 && GET_CODE (XEXP (*op0
, 1)) == CONST_INT
634 && GET_CODE (XEXP (*op0
, 2)) == CONST_INT
635 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0
, 0))))
637 rtx inner
= XEXP (*op0
, 0);
638 HOST_WIDE_INT modesize
= GET_MODE_BITSIZE (GET_MODE (inner
));
639 HOST_WIDE_INT len
= INTVAL (XEXP (*op0
, 1));
640 HOST_WIDE_INT pos
= INTVAL (XEXP (*op0
, 2));
642 if (len
> 0 && len
< modesize
643 && pos
>= 0 && pos
+ len
<= modesize
644 && modesize
<= HOST_BITS_PER_WIDE_INT
)
646 unsigned HOST_WIDE_INT block
;
647 block
= ((unsigned HOST_WIDE_INT
) 1 << len
) - 1;
648 block
<<= modesize
- pos
- len
;
650 *op0
= gen_rtx_AND (GET_MODE (inner
), inner
,
651 gen_int_mode (block
, GET_MODE (inner
)));
655 /* Narrow AND of memory against immediate to enable TM. */
656 if ((*code
== EQ
|| *code
== NE
)
657 && *op1
== const0_rtx
658 && GET_CODE (*op0
) == AND
659 && GET_CODE (XEXP (*op0
, 1)) == CONST_INT
660 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0
, 0))))
662 rtx inner
= XEXP (*op0
, 0);
663 rtx mask
= XEXP (*op0
, 1);
665 /* Ignore paradoxical SUBREGs if all extra bits are masked out. */
666 if (GET_CODE (inner
) == SUBREG
667 && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (inner
)))
668 && (GET_MODE_SIZE (GET_MODE (inner
))
669 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner
))))
671 & GET_MODE_MASK (GET_MODE (inner
))
672 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (inner
))))
674 inner
= SUBREG_REG (inner
);
676 /* Do not change volatile MEMs. */
677 if (MEM_P (inner
) && !MEM_VOLATILE_P (inner
))
679 int part
= s390_single_part (XEXP (*op0
, 1),
680 GET_MODE (inner
), QImode
, 0);
683 mask
= gen_int_mode (s390_extract_part (mask
, QImode
, 0), QImode
);
684 inner
= adjust_address_nv (inner
, QImode
, part
);
685 *op0
= gen_rtx_AND (QImode
, inner
, mask
);
690 /* Narrow comparisons against 0xffff to HImode if possible. */
691 if ((*code
== EQ
|| *code
== NE
)
692 && GET_CODE (*op1
) == CONST_INT
693 && INTVAL (*op1
) == 0xffff
694 && SCALAR_INT_MODE_P (GET_MODE (*op0
))
695 && (nonzero_bits (*op0
, GET_MODE (*op0
))
696 & ~(unsigned HOST_WIDE_INT
) 0xffff) == 0)
698 *op0
= gen_lowpart (HImode
, *op0
);
703 /* Remove redundant UNSPEC_CMPINT conversions if possible. */
704 if (GET_CODE (*op0
) == UNSPEC
705 && XINT (*op0
, 1) == UNSPEC_CMPINT
706 && XVECLEN (*op0
, 0) == 1
707 && GET_MODE (XVECEXP (*op0
, 0, 0)) == CCUmode
708 && GET_CODE (XVECEXP (*op0
, 0, 0)) == REG
709 && REGNO (XVECEXP (*op0
, 0, 0)) == CC_REGNUM
710 && *op1
== const0_rtx
)
712 enum rtx_code new_code
= UNKNOWN
;
715 case EQ
: new_code
= EQ
; break;
716 case NE
: new_code
= NE
; break;
717 case LT
: new_code
= GTU
; break;
718 case GT
: new_code
= LTU
; break;
719 case LE
: new_code
= GEU
; break;
720 case GE
: new_code
= LEU
; break;
724 if (new_code
!= UNKNOWN
)
726 *op0
= XVECEXP (*op0
, 0, 0);
731 /* Simplify cascaded EQ, NE with const0_rtx. */
732 if ((*code
== NE
|| *code
== EQ
)
733 && (GET_CODE (*op0
) == EQ
|| GET_CODE (*op0
) == NE
)
734 && GET_MODE (*op0
) == SImode
735 && GET_MODE (XEXP (*op0
, 0)) == CCZ1mode
736 && REG_P (XEXP (*op0
, 0))
737 && XEXP (*op0
, 1) == const0_rtx
738 && *op1
== const0_rtx
)
740 if ((*code
== EQ
&& GET_CODE (*op0
) == NE
)
741 || (*code
== NE
&& GET_CODE (*op0
) == EQ
))
745 *op0
= XEXP (*op0
, 0);
748 /* Prefer register over memory as first operand. */
749 if (MEM_P (*op0
) && REG_P (*op1
))
751 rtx tem
= *op0
; *op0
= *op1
; *op1
= tem
;
752 *code
= swap_condition (*code
);
756 /* Emit a compare instruction suitable to implement the comparison
757 OP0 CODE OP1. Return the correct condition RTL to be placed in
758 the IF_THEN_ELSE of the conditional branch testing the result. */
761 s390_emit_compare (enum rtx_code code
, rtx op0
, rtx op1
)
763 enum machine_mode mode
= s390_select_ccmode (code
, op0
, op1
);
766 /* Do not output a redundant compare instruction if a compare_and_swap
767 pattern already computed the result and the machine modes are compatible. */
768 if (s390_compare_emitted
769 && (s390_cc_modes_compatible (GET_MODE (s390_compare_emitted
), mode
)
770 == GET_MODE (s390_compare_emitted
)))
771 ret
= gen_rtx_fmt_ee (code
, VOIDmode
, s390_compare_emitted
, const0_rtx
);
774 rtx cc
= gen_rtx_REG (mode
, CC_REGNUM
);
776 emit_insn (gen_rtx_SET (VOIDmode
, cc
, gen_rtx_COMPARE (mode
, op0
, op1
)));
777 ret
= gen_rtx_fmt_ee (code
, VOIDmode
, cc
, const0_rtx
);
779 s390_compare_emitted
= NULL_RTX
;
783 /* Emit a SImode compare and swap instruction setting MEM to NEW if OLD
785 Return the correct condition RTL to be placed in the IF_THEN_ELSE of the
786 conditional branch testing the result. */
789 s390_emit_compare_and_swap (enum rtx_code code
, rtx old
, rtx mem
, rtx cmp
, rtx
new)
793 emit_insn (gen_sync_compare_and_swap_ccsi (old
, mem
, cmp
, new));
794 ret
= gen_rtx_fmt_ee (code
, VOIDmode
, s390_compare_emitted
, const0_rtx
);
796 s390_compare_emitted
= NULL_RTX
;
801 /* Emit a jump instruction to TARGET. If COND is NULL_RTX, emit an
802 unconditional jump, else a conditional jump under condition COND. */
805 s390_emit_jump (rtx target
, rtx cond
)
809 target
= gen_rtx_LABEL_REF (VOIDmode
, target
);
811 target
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, target
, pc_rtx
);
813 insn
= gen_rtx_SET (VOIDmode
, pc_rtx
, target
);
814 emit_jump_insn (insn
);
817 /* Return branch condition mask to implement a branch
818 specified by CODE. Return -1 for invalid comparisons. */
821 s390_branch_condition_mask (rtx code
)
823 const int CC0
= 1 << 3;
824 const int CC1
= 1 << 2;
825 const int CC2
= 1 << 1;
826 const int CC3
= 1 << 0;
828 gcc_assert (GET_CODE (XEXP (code
, 0)) == REG
);
829 gcc_assert (REGNO (XEXP (code
, 0)) == CC_REGNUM
);
830 gcc_assert (XEXP (code
, 1) == const0_rtx
);
832 switch (GET_MODE (XEXP (code
, 0)))
836 switch (GET_CODE (code
))
839 case NE
: return CC1
| CC2
| CC3
;
845 switch (GET_CODE (code
))
848 case NE
: return CC0
| CC2
| CC3
;
854 switch (GET_CODE (code
))
857 case NE
: return CC0
| CC1
| CC3
;
863 switch (GET_CODE (code
))
866 case NE
: return CC0
| CC1
| CC2
;
872 switch (GET_CODE (code
))
874 case EQ
: return CC0
| CC2
;
875 case NE
: return CC1
| CC3
;
881 switch (GET_CODE (code
))
883 case LTU
: return CC2
| CC3
; /* carry */
884 case GEU
: return CC0
| CC1
; /* no carry */
890 switch (GET_CODE (code
))
892 case GTU
: return CC0
| CC1
; /* borrow */
893 case LEU
: return CC2
| CC3
; /* no borrow */
899 switch (GET_CODE (code
))
901 case EQ
: return CC0
| CC2
;
902 case NE
: return CC1
| CC3
;
903 case LTU
: return CC1
;
904 case GTU
: return CC3
;
905 case LEU
: return CC1
| CC2
;
906 case GEU
: return CC2
| CC3
;
911 switch (GET_CODE (code
))
914 case NE
: return CC1
| CC2
| CC3
;
915 case LTU
: return CC1
;
916 case GTU
: return CC2
;
917 case LEU
: return CC0
| CC1
;
918 case GEU
: return CC0
| CC2
;
924 switch (GET_CODE (code
))
927 case NE
: return CC2
| CC1
| CC3
;
928 case LTU
: return CC2
;
929 case GTU
: return CC1
;
930 case LEU
: return CC0
| CC2
;
931 case GEU
: return CC0
| CC1
;
937 switch (GET_CODE (code
))
940 case NE
: return CC1
| CC2
| CC3
;
941 case LT
: return CC1
| CC3
;
943 case LE
: return CC0
| CC1
| CC3
;
944 case GE
: return CC0
| CC2
;
950 switch (GET_CODE (code
))
953 case NE
: return CC1
| CC2
| CC3
;
955 case GT
: return CC2
| CC3
;
956 case LE
: return CC0
| CC1
;
957 case GE
: return CC0
| CC2
| CC3
;
963 switch (GET_CODE (code
))
966 case NE
: return CC1
| CC2
| CC3
;
969 case LE
: return CC0
| CC1
;
970 case GE
: return CC0
| CC2
;
971 case UNORDERED
: return CC3
;
972 case ORDERED
: return CC0
| CC1
| CC2
;
973 case UNEQ
: return CC0
| CC3
;
974 case UNLT
: return CC1
| CC3
;
975 case UNGT
: return CC2
| CC3
;
976 case UNLE
: return CC0
| CC1
| CC3
;
977 case UNGE
: return CC0
| CC2
| CC3
;
978 case LTGT
: return CC1
| CC2
;
984 switch (GET_CODE (code
))
987 case NE
: return CC2
| CC1
| CC3
;
990 case LE
: return CC0
| CC2
;
991 case GE
: return CC0
| CC1
;
992 case UNORDERED
: return CC3
;
993 case ORDERED
: return CC0
| CC2
| CC1
;
994 case UNEQ
: return CC0
| CC3
;
995 case UNLT
: return CC2
| CC3
;
996 case UNGT
: return CC1
| CC3
;
997 case UNLE
: return CC0
| CC2
| CC3
;
998 case UNGE
: return CC0
| CC1
| CC3
;
999 case LTGT
: return CC2
| CC1
;
1009 /* If INV is false, return assembler mnemonic string to implement
1010 a branch specified by CODE. If INV is true, return mnemonic
1011 for the corresponding inverted branch. */
1014 s390_branch_condition_mnemonic (rtx code
, int inv
)
1016 static const char *const mnemonic
[16] =
1018 NULL
, "o", "h", "nle",
1019 "l", "nhe", "lh", "ne",
1020 "e", "nlh", "he", "nl",
1021 "le", "nh", "no", NULL
1024 int mask
= s390_branch_condition_mask (code
);
1025 gcc_assert (mask
>= 0);
1030 gcc_assert (mask
>= 1 && mask
<= 14);
1032 return mnemonic
[mask
];
1035 /* Return the part of op which has a value different from def.
1036 The size of the part is determined by mode.
1037 Use this function only if you already know that op really
1038 contains such a part. */
1040 unsigned HOST_WIDE_INT
1041 s390_extract_part (rtx op
, enum machine_mode mode
, int def
)
1043 unsigned HOST_WIDE_INT value
= 0;
1044 int max_parts
= HOST_BITS_PER_WIDE_INT
/ GET_MODE_BITSIZE (mode
);
1045 int part_bits
= GET_MODE_BITSIZE (mode
);
1046 unsigned HOST_WIDE_INT part_mask
1047 = ((unsigned HOST_WIDE_INT
)1 << part_bits
) - 1;
1050 for (i
= 0; i
< max_parts
; i
++)
1053 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
1055 value
>>= part_bits
;
1057 if ((value
& part_mask
) != (def
& part_mask
))
1058 return value
& part_mask
;
1064 /* If OP is an integer constant of mode MODE with exactly one
1065 part of mode PART_MODE unequal to DEF, return the number of that
1066 part. Otherwise, return -1. */
1069 s390_single_part (rtx op
,
1070 enum machine_mode mode
,
1071 enum machine_mode part_mode
,
1074 unsigned HOST_WIDE_INT value
= 0;
1075 int n_parts
= GET_MODE_SIZE (mode
) / GET_MODE_SIZE (part_mode
);
1076 unsigned HOST_WIDE_INT part_mask
1077 = ((unsigned HOST_WIDE_INT
)1 << GET_MODE_BITSIZE (part_mode
)) - 1;
1080 if (GET_CODE (op
) != CONST_INT
)
1083 for (i
= 0; i
< n_parts
; i
++)
1086 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
1088 value
>>= GET_MODE_BITSIZE (part_mode
);
1090 if ((value
& part_mask
) != (def
& part_mask
))
1098 return part
== -1 ? -1 : n_parts
- 1 - part
;
1101 /* Check whether we can (and want to) split a double-word
1102 move in mode MODE from SRC to DST into two single-word
1103 moves, moving the subword FIRST_SUBWORD first. */
1106 s390_split_ok_p (rtx dst
, rtx src
, enum machine_mode mode
, int first_subword
)
1108 /* Floating point registers cannot be split. */
1109 if (FP_REG_P (src
) || FP_REG_P (dst
))
1112 /* We don't need to split if operands are directly accessible. */
1113 if (s_operand (src
, mode
) || s_operand (dst
, mode
))
1116 /* Non-offsettable memory references cannot be split. */
1117 if ((GET_CODE (src
) == MEM
&& !offsettable_memref_p (src
))
1118 || (GET_CODE (dst
) == MEM
&& !offsettable_memref_p (dst
)))
1121 /* Moving the first subword must not clobber a register
1122 needed to move the second subword. */
1123 if (register_operand (dst
, mode
))
1125 rtx subreg
= operand_subword (dst
, first_subword
, 0, mode
);
1126 if (reg_overlap_mentioned_p (subreg
, src
))
1133 /* Return true if it can be proven that [MEM1, MEM1 + SIZE]
1134 and [MEM2, MEM2 + SIZE] do overlap and false
1138 s390_overlap_p (rtx mem1
, rtx mem2
, HOST_WIDE_INT size
)
1140 rtx addr1
, addr2
, addr_delta
;
1141 HOST_WIDE_INT delta
;
1143 if (GET_CODE (mem1
) != MEM
|| GET_CODE (mem2
) != MEM
)
1149 addr1
= XEXP (mem1
, 0);
1150 addr2
= XEXP (mem2
, 0);
1152 addr_delta
= simplify_binary_operation (MINUS
, Pmode
, addr2
, addr1
);
1154 /* This overlapping check is used by peepholes merging memory block operations.
1155 Overlapping operations would otherwise be recognized by the S/390 hardware
1156 and would fall back to a slower implementation. Allowing overlapping
1157 operations would lead to slow code but not to wrong code. Therefore we are
1158 somewhat optimistic if we cannot prove that the memory blocks are
1160 That's why we return false here although this may accept operations on
1161 overlapping memory areas. */
1162 if (!addr_delta
|| GET_CODE (addr_delta
) != CONST_INT
)
1165 delta
= INTVAL (addr_delta
);
1168 || (delta
> 0 && delta
< size
)
1169 || (delta
< 0 && -delta
< size
))
1175 /* Check whether the address of memory reference MEM2 equals exactly
1176 the address of memory reference MEM1 plus DELTA. Return true if
1177 we can prove this to be the case, false otherwise. */
1180 s390_offset_p (rtx mem1
, rtx mem2
, rtx delta
)
1182 rtx addr1
, addr2
, addr_delta
;
1184 if (GET_CODE (mem1
) != MEM
|| GET_CODE (mem2
) != MEM
)
1187 addr1
= XEXP (mem1
, 0);
1188 addr2
= XEXP (mem2
, 0);
1190 addr_delta
= simplify_binary_operation (MINUS
, Pmode
, addr2
, addr1
);
1191 if (!addr_delta
|| !rtx_equal_p (addr_delta
, delta
))
1197 /* Expand logical operator CODE in mode MODE with operands OPERANDS. */
1200 s390_expand_logical_operator (enum rtx_code code
, enum machine_mode mode
,
1203 enum machine_mode wmode
= mode
;
1204 rtx dst
= operands
[0];
1205 rtx src1
= operands
[1];
1206 rtx src2
= operands
[2];
1209 /* If we cannot handle the operation directly, use a temp register. */
1210 if (!s390_logical_operator_ok_p (operands
))
1211 dst
= gen_reg_rtx (mode
);
1213 /* QImode and HImode patterns make sense only if we have a destination
1214 in memory. Otherwise perform the operation in SImode. */
1215 if ((mode
== QImode
|| mode
== HImode
) && GET_CODE (dst
) != MEM
)
1218 /* Widen operands if required. */
1221 if (GET_CODE (dst
) == SUBREG
1222 && (tem
= simplify_subreg (wmode
, dst
, mode
, 0)) != 0)
1224 else if (REG_P (dst
))
1225 dst
= gen_rtx_SUBREG (wmode
, dst
, 0);
1227 dst
= gen_reg_rtx (wmode
);
1229 if (GET_CODE (src1
) == SUBREG
1230 && (tem
= simplify_subreg (wmode
, src1
, mode
, 0)) != 0)
1232 else if (GET_MODE (src1
) != VOIDmode
)
1233 src1
= gen_rtx_SUBREG (wmode
, force_reg (mode
, src1
), 0);
1235 if (GET_CODE (src2
) == SUBREG
1236 && (tem
= simplify_subreg (wmode
, src2
, mode
, 0)) != 0)
1238 else if (GET_MODE (src2
) != VOIDmode
)
1239 src2
= gen_rtx_SUBREG (wmode
, force_reg (mode
, src2
), 0);
1242 /* Emit the instruction. */
1243 op
= gen_rtx_SET (VOIDmode
, dst
, gen_rtx_fmt_ee (code
, wmode
, src1
, src2
));
1244 clob
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
1245 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, op
, clob
)));
1247 /* Fix up the destination if needed. */
1248 if (dst
!= operands
[0])
1249 emit_move_insn (operands
[0], gen_lowpart (mode
, dst
));
1252 /* Check whether OPERANDS are OK for a logical operation (AND, IOR, XOR). */
1255 s390_logical_operator_ok_p (rtx
*operands
)
1257 /* If the destination operand is in memory, it needs to coincide
1258 with one of the source operands. After reload, it has to be
1259 the first source operand. */
1260 if (GET_CODE (operands
[0]) == MEM
)
1261 return rtx_equal_p (operands
[0], operands
[1])
1262 || (!reload_completed
&& rtx_equal_p (operands
[0], operands
[2]));
1267 /* Narrow logical operation CODE of memory operand MEMOP with immediate
1268 operand IMMOP to switch from SS to SI type instructions. */
1271 s390_narrow_logical_operator (enum rtx_code code
, rtx
*memop
, rtx
*immop
)
1273 int def
= code
== AND
? -1 : 0;
1277 gcc_assert (GET_CODE (*memop
) == MEM
);
1278 gcc_assert (!MEM_VOLATILE_P (*memop
));
1280 mask
= s390_extract_part (*immop
, QImode
, def
);
1281 part
= s390_single_part (*immop
, GET_MODE (*memop
), QImode
, def
);
1282 gcc_assert (part
>= 0);
1284 *memop
= adjust_address (*memop
, QImode
, part
);
1285 *immop
= gen_int_mode (mask
, QImode
);
1289 /* How to allocate a 'struct machine_function'. */
1291 static struct machine_function
*
1292 s390_init_machine_status (void)
1294 return ggc_alloc_cleared (sizeof (struct machine_function
));
1297 /* Change optimizations to be performed, depending on the
1300 LEVEL is the optimization level specified; 2 if `-O2' is
1301 specified, 1 if `-O' is specified, and 0 if neither is specified.
1303 SIZE is nonzero if `-Os' is specified and zero otherwise. */
1306 optimization_options (int level ATTRIBUTE_UNUSED
, int size ATTRIBUTE_UNUSED
)
1308 /* ??? There are apparently still problems with -fcaller-saves. */
1309 flag_caller_saves
= 0;
1311 /* By default, always emit DWARF-2 unwind info. This allows debugging
1312 without maintaining a stack frame back-chain. */
1313 flag_asynchronous_unwind_tables
= 1;
1315 /* Use MVCLE instructions to decrease code size if requested. */
1317 target_flags
|= MASK_MVCLE
;
1320 /* Return true if ARG is the name of a processor. Set *TYPE and *FLAGS
1321 to the associated processor_type and processor_flags if so. */
1324 s390_handle_arch_option (const char *arg
,
1325 enum processor_type
*type
,
1326 enum processor_flags
*flags
)
1330 const char *const name
; /* processor name or nickname. */
1331 const enum processor_type processor
;
1332 const enum processor_flags flags
;
1334 const processor_alias_table
[] =
1336 {"g5", PROCESSOR_9672_G5
, PF_IEEE_FLOAT
},
1337 {"g6", PROCESSOR_9672_G6
, PF_IEEE_FLOAT
},
1338 {"z900", PROCESSOR_2064_Z900
, PF_IEEE_FLOAT
| PF_ZARCH
},
1339 {"z990", PROCESSOR_2084_Z990
, PF_IEEE_FLOAT
| PF_ZARCH
1340 | PF_LONG_DISPLACEMENT
},
1341 {"z9-109", PROCESSOR_2094_Z9_109
, PF_IEEE_FLOAT
| PF_ZARCH
1342 | PF_LONG_DISPLACEMENT
| PF_EXTIMM
},
1346 for (i
= 0; i
< ARRAY_SIZE (processor_alias_table
); i
++)
1347 if (strcmp (arg
, processor_alias_table
[i
].name
) == 0)
1349 *type
= processor_alias_table
[i
].processor
;
1350 *flags
= processor_alias_table
[i
].flags
;
1356 /* Implement TARGET_HANDLE_OPTION. */
1359 s390_handle_option (size_t code
, const char *arg
, int value ATTRIBUTE_UNUSED
)
1364 return s390_handle_arch_option (arg
, &s390_arch
, &s390_arch_flags
);
1366 case OPT_mstack_guard_
:
1367 if (sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_stack_guard
) != 1)
1369 if (exact_log2 (s390_stack_guard
) == -1)
1370 error ("stack guard value must be an exact power of 2");
1373 case OPT_mstack_size_
:
1374 if (sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_stack_size
) != 1)
1376 if (exact_log2 (s390_stack_size
) == -1)
1377 error ("stack size must be an exact power of 2");
1381 return s390_handle_arch_option (arg
, &s390_tune
, &s390_tune_flags
);
1383 case OPT_mwarn_framesize_
:
1384 return sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_warn_framesize
) == 1;
1392 override_options (void)
1394 /* Set up function hooks. */
1395 init_machine_status
= s390_init_machine_status
;
1397 /* Architecture mode defaults according to ABI. */
1398 if (!(target_flags_explicit
& MASK_ZARCH
))
1401 target_flags
|= MASK_ZARCH
;
1403 target_flags
&= ~MASK_ZARCH
;
1406 /* Determine processor architectural level. */
1407 if (!s390_arch_string
)
1409 s390_arch_string
= TARGET_ZARCH
? "z900" : "g5";
1410 s390_handle_arch_option (s390_arch_string
, &s390_arch
, &s390_arch_flags
);
1413 /* Determine processor to tune for. */
1414 if (s390_tune
== PROCESSOR_max
)
1416 s390_tune
= s390_arch
;
1417 s390_tune_flags
= s390_arch_flags
;
1420 /* Sanity checks. */
1421 if (TARGET_ZARCH
&& !(s390_arch_flags
& PF_ZARCH
))
1422 error ("z/Architecture mode not supported on %s", s390_arch_string
);
1423 if (TARGET_64BIT
&& !TARGET_ZARCH
)
1424 error ("64-bit ABI not supported in ESA/390 mode");
1426 /* Set processor cost function. */
1427 if (s390_tune
== PROCESSOR_2094_Z9_109
)
1428 s390_cost
= &z9_109_cost
;
1429 else if (s390_tune
== PROCESSOR_2084_Z990
)
1430 s390_cost
= &z990_cost
;
1432 s390_cost
= &z900_cost
;
1434 if (TARGET_BACKCHAIN
&& TARGET_PACKED_STACK
&& TARGET_HARD_FLOAT
)
1435 error ("-mbackchain -mpacked-stack -mhard-float are not supported "
1438 if (s390_stack_size
)
1440 if (s390_stack_guard
>= s390_stack_size
)
1441 error ("stack size must be greater than the stack guard value");
1442 else if (s390_stack_size
> 1 << 16)
1443 error ("stack size must not be greater than 64k");
1445 else if (s390_stack_guard
)
1446 error ("-mstack-guard implies use of -mstack-size");
1448 #ifdef TARGET_DEFAULT_LONG_DOUBLE_128
1449 if (!(target_flags_explicit
& MASK_LONG_DOUBLE_128
))
1450 target_flags
|= MASK_LONG_DOUBLE_128
;
1454 /* Map for smallest class containing reg regno. */
1456 const enum reg_class regclass_map
[FIRST_PSEUDO_REGISTER
] =
1457 { GENERAL_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1458 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1459 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1460 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1461 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1462 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1463 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1464 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1465 ADDR_REGS
, CC_REGS
, ADDR_REGS
, ADDR_REGS
,
1466 ACCESS_REGS
, ACCESS_REGS
1469 /* Return attribute type of insn. */
1471 static enum attr_type
1472 s390_safe_attr_type (rtx insn
)
1474 if (recog_memoized (insn
) >= 0)
1475 return get_attr_type (insn
);
1480 /* Return true if DISP is a valid short displacement. */
1483 s390_short_displacement (rtx disp
)
1485 /* No displacement is OK. */
1489 /* Integer displacement in range. */
1490 if (GET_CODE (disp
) == CONST_INT
)
1491 return INTVAL (disp
) >= 0 && INTVAL (disp
) < 4096;
1493 /* GOT offset is not OK, the GOT can be large. */
1494 if (GET_CODE (disp
) == CONST
1495 && GET_CODE (XEXP (disp
, 0)) == UNSPEC
1496 && (XINT (XEXP (disp
, 0), 1) == UNSPEC_GOT
1497 || XINT (XEXP (disp
, 0), 1) == UNSPEC_GOTNTPOFF
))
1500 /* All other symbolic constants are literal pool references,
1501 which are OK as the literal pool must be small. */
1502 if (GET_CODE (disp
) == CONST
)
1508 /* Decompose a RTL expression ADDR for a memory address into
1509 its components, returned in OUT.
1511 Returns false if ADDR is not a valid memory address, true
1512 otherwise. If OUT is NULL, don't return the components,
1513 but check for validity only.
1515 Note: Only addresses in canonical form are recognized.
1516 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
1517 canonical form so that they will be recognized. */
1520 s390_decompose_address (rtx addr
, struct s390_address
*out
)
1522 HOST_WIDE_INT offset
= 0;
1523 rtx base
= NULL_RTX
;
1524 rtx indx
= NULL_RTX
;
1525 rtx disp
= NULL_RTX
;
1527 bool pointer
= false;
1528 bool base_ptr
= false;
1529 bool indx_ptr
= false;
1530 bool literal_pool
= false;
1532 /* We may need to substitute the literal pool base register into the address
1533 below. However, at this point we do not know which register is going to
1534 be used as base, so we substitute the arg pointer register. This is going
1535 to be treated as holding a pointer below -- it shouldn't be used for any
1537 rtx fake_pool_base
= gen_rtx_REG (Pmode
, ARG_POINTER_REGNUM
);
1539 /* Decompose address into base + index + displacement. */
1541 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == UNSPEC
)
1544 else if (GET_CODE (addr
) == PLUS
)
1546 rtx op0
= XEXP (addr
, 0);
1547 rtx op1
= XEXP (addr
, 1);
1548 enum rtx_code code0
= GET_CODE (op0
);
1549 enum rtx_code code1
= GET_CODE (op1
);
1551 if (code0
== REG
|| code0
== UNSPEC
)
1553 if (code1
== REG
|| code1
== UNSPEC
)
1555 indx
= op0
; /* index + base */
1561 base
= op0
; /* base + displacement */
1566 else if (code0
== PLUS
)
1568 indx
= XEXP (op0
, 0); /* index + base + disp */
1569 base
= XEXP (op0
, 1);
1580 disp
= addr
; /* displacement */
1582 /* Extract integer part of displacement. */
1586 if (GET_CODE (disp
) == CONST_INT
)
1588 offset
= INTVAL (disp
);
1591 else if (GET_CODE (disp
) == CONST
1592 && GET_CODE (XEXP (disp
, 0)) == PLUS
1593 && GET_CODE (XEXP (XEXP (disp
, 0), 1)) == CONST_INT
)
1595 offset
= INTVAL (XEXP (XEXP (disp
, 0), 1));
1596 disp
= XEXP (XEXP (disp
, 0), 0);
1600 /* Strip off CONST here to avoid special case tests later. */
1601 if (disp
&& GET_CODE (disp
) == CONST
)
1602 disp
= XEXP (disp
, 0);
1604 /* We can convert literal pool addresses to
1605 displacements by basing them off the base register. */
1606 if (disp
&& GET_CODE (disp
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (disp
))
1608 /* Either base or index must be free to hold the base register. */
1610 base
= fake_pool_base
, literal_pool
= true;
1612 indx
= fake_pool_base
, literal_pool
= true;
1616 /* Mark up the displacement. */
1617 disp
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, disp
),
1618 UNSPEC_LTREL_OFFSET
);
1621 /* Validate base register. */
1624 if (GET_CODE (base
) == UNSPEC
)
1625 switch (XINT (base
, 1))
1629 disp
= gen_rtx_UNSPEC (Pmode
,
1630 gen_rtvec (1, XVECEXP (base
, 0, 0)),
1631 UNSPEC_LTREL_OFFSET
);
1635 base
= XVECEXP (base
, 0, 1);
1638 case UNSPEC_LTREL_BASE
:
1639 if (XVECLEN (base
, 0) == 1)
1640 base
= fake_pool_base
, literal_pool
= true;
1642 base
= XVECEXP (base
, 0, 1);
1650 || (GET_MODE (base
) != SImode
1651 && GET_MODE (base
) != Pmode
))
1654 if (REGNO (base
) == STACK_POINTER_REGNUM
1655 || REGNO (base
) == FRAME_POINTER_REGNUM
1656 || ((reload_completed
|| reload_in_progress
)
1657 && frame_pointer_needed
1658 && REGNO (base
) == HARD_FRAME_POINTER_REGNUM
)
1659 || REGNO (base
) == ARG_POINTER_REGNUM
1661 && REGNO (base
) == PIC_OFFSET_TABLE_REGNUM
))
1662 pointer
= base_ptr
= true;
1664 if ((reload_completed
|| reload_in_progress
)
1665 && base
== cfun
->machine
->base_reg
)
1666 pointer
= base_ptr
= literal_pool
= true;
1669 /* Validate index register. */
1672 if (GET_CODE (indx
) == UNSPEC
)
1673 switch (XINT (indx
, 1))
1677 disp
= gen_rtx_UNSPEC (Pmode
,
1678 gen_rtvec (1, XVECEXP (indx
, 0, 0)),
1679 UNSPEC_LTREL_OFFSET
);
1683 indx
= XVECEXP (indx
, 0, 1);
1686 case UNSPEC_LTREL_BASE
:
1687 if (XVECLEN (indx
, 0) == 1)
1688 indx
= fake_pool_base
, literal_pool
= true;
1690 indx
= XVECEXP (indx
, 0, 1);
1698 || (GET_MODE (indx
) != SImode
1699 && GET_MODE (indx
) != Pmode
))
1702 if (REGNO (indx
) == STACK_POINTER_REGNUM
1703 || REGNO (indx
) == FRAME_POINTER_REGNUM
1704 || ((reload_completed
|| reload_in_progress
)
1705 && frame_pointer_needed
1706 && REGNO (indx
) == HARD_FRAME_POINTER_REGNUM
)
1707 || REGNO (indx
) == ARG_POINTER_REGNUM
1709 && REGNO (indx
) == PIC_OFFSET_TABLE_REGNUM
))
1710 pointer
= indx_ptr
= true;
1712 if ((reload_completed
|| reload_in_progress
)
1713 && indx
== cfun
->machine
->base_reg
)
1714 pointer
= indx_ptr
= literal_pool
= true;
1717 /* Prefer to use pointer as base, not index. */
1718 if (base
&& indx
&& !base_ptr
1719 && (indx_ptr
|| (!REG_POINTER (base
) && REG_POINTER (indx
))))
1726 /* Validate displacement. */
1729 /* If virtual registers are involved, the displacement will change later
1730 anyway as the virtual registers get eliminated. This could make a
1731 valid displacement invalid, but it is more likely to make an invalid
1732 displacement valid, because we sometimes access the register save area
1733 via negative offsets to one of those registers.
1734 Thus we don't check the displacement for validity here. If after
1735 elimination the displacement turns out to be invalid after all,
1736 this is fixed up by reload in any case. */
1737 if (base
!= arg_pointer_rtx
1738 && indx
!= arg_pointer_rtx
1739 && base
!= return_address_pointer_rtx
1740 && indx
!= return_address_pointer_rtx
1741 && base
!= frame_pointer_rtx
1742 && indx
!= frame_pointer_rtx
1743 && base
!= virtual_stack_vars_rtx
1744 && indx
!= virtual_stack_vars_rtx
)
1745 if (!DISP_IN_RANGE (offset
))
1750 /* All the special cases are pointers. */
1753 /* In the small-PIC case, the linker converts @GOT
1754 and @GOTNTPOFF offsets to possible displacements. */
1755 if (GET_CODE (disp
) == UNSPEC
1756 && (XINT (disp
, 1) == UNSPEC_GOT
1757 || XINT (disp
, 1) == UNSPEC_GOTNTPOFF
)
1763 /* Accept chunkified literal pool symbol references. */
1764 else if (cfun
&& cfun
->machine
1765 && cfun
->machine
->decomposed_literal_pool_addresses_ok_p
1766 && GET_CODE (disp
) == MINUS
1767 && GET_CODE (XEXP (disp
, 0)) == LABEL_REF
1768 && GET_CODE (XEXP (disp
, 1)) == LABEL_REF
)
1773 /* Accept literal pool references. */
1774 else if (GET_CODE (disp
) == UNSPEC
1775 && XINT (disp
, 1) == UNSPEC_LTREL_OFFSET
)
1777 orig_disp
= gen_rtx_CONST (Pmode
, disp
);
1780 /* If we have an offset, make sure it does not
1781 exceed the size of the constant pool entry. */
1782 rtx sym
= XVECEXP (disp
, 0, 0);
1783 if (offset
>= GET_MODE_SIZE (get_pool_mode (sym
)))
1786 orig_disp
= plus_constant (orig_disp
, offset
);
1801 out
->disp
= orig_disp
;
1802 out
->pointer
= pointer
;
1803 out
->literal_pool
= literal_pool
;
1809 /* Decompose a RTL expression OP for a shift count into its components,
1810 and return the base register in BASE and the offset in OFFSET.
1812 Return true if OP is a valid shift count, false if not. */
1815 s390_decompose_shift_count (rtx op
, rtx
*base
, HOST_WIDE_INT
*offset
)
1817 HOST_WIDE_INT off
= 0;
1819 /* We can have an integer constant, an address register,
1820 or a sum of the two. */
1821 if (GET_CODE (op
) == CONST_INT
)
1826 if (op
&& GET_CODE (op
) == PLUS
&& GET_CODE (XEXP (op
, 1)) == CONST_INT
)
1828 off
= INTVAL (XEXP (op
, 1));
1831 while (op
&& GET_CODE (op
) == SUBREG
)
1832 op
= SUBREG_REG (op
);
1834 if (op
&& GET_CODE (op
) != REG
)
1846 /* Return true if CODE is a valid address without index. */
1849 s390_legitimate_address_without_index_p (rtx op
)
1851 struct s390_address addr
;
1853 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1862 /* Evaluates constraint strings described by the regular expression
1863 ([A|B](Q|R|S|T))|U|W and returns 1 if OP is a valid operand for the
1864 constraint given in STR, or 0 else. */
1867 s390_mem_constraint (const char *str
, rtx op
)
1869 struct s390_address addr
;
1872 /* Check for offsettable variants of memory constraints. */
1875 /* Only accept non-volatile MEMs. */
1876 if (!MEM_P (op
) || MEM_VOLATILE_P (op
))
1879 if ((reload_completed
|| reload_in_progress
)
1880 ? !offsettable_memref_p (op
) : !offsettable_nonstrict_memref_p (op
))
1886 /* Check for non-literal-pool variants of memory constraints. */
1889 if (GET_CODE (op
) != MEM
)
1891 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1893 if (addr
.literal_pool
)
1902 if (GET_CODE (op
) != MEM
)
1904 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1909 if (TARGET_LONG_DISPLACEMENT
)
1911 if (!s390_short_displacement (addr
.disp
))
1917 if (GET_CODE (op
) != MEM
)
1920 if (TARGET_LONG_DISPLACEMENT
)
1922 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1924 if (!s390_short_displacement (addr
.disp
))
1930 if (!TARGET_LONG_DISPLACEMENT
)
1932 if (GET_CODE (op
) != MEM
)
1934 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1938 if (s390_short_displacement (addr
.disp
))
1943 if (!TARGET_LONG_DISPLACEMENT
)
1945 if (GET_CODE (op
) != MEM
)
1947 /* Any invalid address here will be fixed up by reload,
1948 so accept it for the most generic constraint. */
1949 if (s390_decompose_address (XEXP (op
, 0), &addr
)
1950 && s390_short_displacement (addr
.disp
))
1955 if (TARGET_LONG_DISPLACEMENT
)
1957 if (!s390_decompose_address (op
, &addr
))
1959 if (!s390_short_displacement (addr
.disp
))
1965 if (!TARGET_LONG_DISPLACEMENT
)
1967 /* Any invalid address here will be fixed up by reload,
1968 so accept it for the most generic constraint. */
1969 if (s390_decompose_address (op
, &addr
)
1970 && s390_short_displacement (addr
.disp
))
1975 /* Simply check for the basic form of a shift count. Reload will
1976 take care of making sure we have a proper base register. */
1977 if (!s390_decompose_shift_count (op
, NULL
, NULL
))
1990 /* Evaluates constraint strings starting with letter O. Input
1991 parameter C is the second letter following the "O" in the constraint
1992 string. Returns 1 if VALUE meets the respective constraint and 0
1996 s390_O_constraint_str (const char c
, HOST_WIDE_INT value
)
2004 return trunc_int_for_mode (value
, SImode
) == value
;
2008 || s390_single_part (GEN_INT (value
), DImode
, SImode
, 0) == 1;
2012 || s390_single_part (GEN_INT (value
), DImode
, SImode
, -1) == 1;
2020 /* Evaluates constraint strings starting with letter N. Parameter STR
2021 contains the letters following letter "N" in the constraint string.
2022 Returns true if VALUE matches the constraint. */
2025 s390_N_constraint_str (const char *str
, HOST_WIDE_INT value
)
2027 enum machine_mode mode
, part_mode
;
2029 int part
, part_goal
;
2035 part_goal
= str
[0] - '0';
2079 if (GET_MODE_SIZE (mode
) <= GET_MODE_SIZE (part_mode
))
2082 part
= s390_single_part (GEN_INT (value
), mode
, part_mode
, def
);
2085 if (part_goal
!= -1 && part_goal
!= part
)
2092 /* Returns true if the input parameter VALUE is a float zero. */
2095 s390_float_const_zero_p (rtx value
)
2097 return (GET_MODE_CLASS (GET_MODE (value
)) == MODE_FLOAT
2098 && value
== CONST0_RTX (GET_MODE (value
)));
2102 /* Compute a (partial) cost for rtx X. Return true if the complete
2103 cost has been computed, and false if subexpressions should be
2104 scanned. In either case, *TOTAL contains the cost result.
2105 CODE contains GET_CODE (x), OUTER_CODE contains the code
2106 of the superexpression of x. */
2109 s390_rtx_costs (rtx x
, int code
, int outer_code
, int *total
)
2132 *total
= COSTS_N_INSNS (1);
2137 /* Check for multiply and add. */
2138 if ((GET_MODE (x
) == DFmode
|| GET_MODE (x
) == SFmode
)
2139 && GET_CODE (XEXP (x
, 0)) == MULT
2140 && TARGET_HARD_FLOAT
&& TARGET_IEEE_FLOAT
&& TARGET_FUSED_MADD
)
2142 /* This is the multiply and add case. */
2143 if (GET_MODE (x
) == DFmode
)
2144 *total
= s390_cost
->madbr
;
2146 *total
= s390_cost
->maebr
;
2147 *total
+= rtx_cost (XEXP (XEXP (x
, 0), 0), MULT
)
2148 + rtx_cost (XEXP (XEXP (x
, 0), 1), MULT
)
2149 + rtx_cost (XEXP (x
, 1), code
);
2150 return true; /* Do not do an additional recursive descent. */
2152 *total
= COSTS_N_INSNS (1);
2156 switch (GET_MODE (x
))
2160 rtx left
= XEXP (x
, 0);
2161 rtx right
= XEXP (x
, 1);
2162 if (GET_CODE (right
) == CONST_INT
2163 && CONST_OK_FOR_K (INTVAL (right
)))
2164 *total
= s390_cost
->mhi
;
2165 else if (GET_CODE (left
) == SIGN_EXTEND
)
2166 *total
= s390_cost
->mh
;
2168 *total
= s390_cost
->ms
; /* msr, ms, msy */
2173 rtx left
= XEXP (x
, 0);
2174 rtx right
= XEXP (x
, 1);
2177 if (GET_CODE (right
) == CONST_INT
2178 && CONST_OK_FOR_K (INTVAL (right
)))
2179 *total
= s390_cost
->mghi
;
2180 else if (GET_CODE (left
) == SIGN_EXTEND
)
2181 *total
= s390_cost
->msgf
;
2183 *total
= s390_cost
->msg
; /* msgr, msg */
2185 else /* TARGET_31BIT */
2187 if (GET_CODE (left
) == SIGN_EXTEND
2188 && GET_CODE (right
) == SIGN_EXTEND
)
2189 /* mulsidi case: mr, m */
2190 *total
= s390_cost
->m
;
2191 else if (GET_CODE (left
) == ZERO_EXTEND
2192 && GET_CODE (right
) == ZERO_EXTEND
2193 && TARGET_CPU_ZARCH
)
2194 /* umulsidi case: ml, mlr */
2195 *total
= s390_cost
->ml
;
2197 /* Complex calculation is required. */
2198 *total
= COSTS_N_INSNS (40);
2204 *total
= s390_cost
->mult_df
;
2207 *total
= s390_cost
->mxbr
;
2216 if (GET_MODE (x
) == TImode
) /* 128 bit division */
2217 *total
= s390_cost
->dlgr
;
2218 else if (GET_MODE (x
) == DImode
)
2220 rtx right
= XEXP (x
, 1);
2221 if (GET_CODE (right
) == ZERO_EXTEND
) /* 64 by 32 bit division */
2222 *total
= s390_cost
->dlr
;
2223 else /* 64 by 64 bit division */
2224 *total
= s390_cost
->dlgr
;
2226 else if (GET_MODE (x
) == SImode
) /* 32 bit division */
2227 *total
= s390_cost
->dlr
;
2232 if (GET_MODE (x
) == DImode
)
2234 rtx right
= XEXP (x
, 1);
2235 if (GET_CODE (right
) == ZERO_EXTEND
) /* 64 by 32 bit division */
2237 *total
= s390_cost
->dsgfr
;
2239 *total
= s390_cost
->dr
;
2240 else /* 64 by 64 bit division */
2241 *total
= s390_cost
->dsgr
;
2243 else if (GET_MODE (x
) == SImode
) /* 32 bit division */
2244 *total
= s390_cost
->dlr
;
2245 else if (GET_MODE (x
) == SFmode
)
2247 if (TARGET_IEEE_FLOAT
)
2248 *total
= s390_cost
->debr
;
2249 else /* TARGET_IBM_FLOAT */
2250 *total
= s390_cost
->der
;
2252 else if (GET_MODE (x
) == DFmode
)
2254 if (TARGET_IEEE_FLOAT
)
2255 *total
= s390_cost
->ddbr
;
2256 else /* TARGET_IBM_FLOAT */
2257 *total
= s390_cost
->ddr
;
2259 else if (GET_MODE (x
) == TFmode
)
2261 if (TARGET_IEEE_FLOAT
)
2262 *total
= s390_cost
->dxbr
;
2263 else /* TARGET_IBM_FLOAT */
2264 *total
= s390_cost
->dxr
;
2269 if (GET_MODE (x
) == SFmode
)
2270 *total
= s390_cost
->sqebr
;
2271 else if (GET_MODE (x
) == DFmode
)
2272 *total
= s390_cost
->sqdbr
;
2274 *total
= s390_cost
->sqxbr
;
2279 if (outer_code
== MULT
|| outer_code
== DIV
|| outer_code
== MOD
2280 || outer_code
== PLUS
|| outer_code
== MINUS
2281 || outer_code
== COMPARE
)
2286 *total
= COSTS_N_INSNS (1);
2287 if (GET_CODE (XEXP (x
, 0)) == AND
2288 && GET_CODE (XEXP (x
, 1)) == CONST_INT
2289 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
)
2291 rtx op0
= XEXP (XEXP (x
, 0), 0);
2292 rtx op1
= XEXP (XEXP (x
, 0), 1);
2293 rtx op2
= XEXP (x
, 1);
2295 if (memory_operand (op0
, GET_MODE (op0
))
2296 && s390_tm_ccmode (op1
, op2
, 0) != VOIDmode
)
2298 if (register_operand (op0
, GET_MODE (op0
))
2299 && s390_tm_ccmode (op1
, op2
, 1) != VOIDmode
)
2309 /* Return the cost of an address rtx ADDR. */
2312 s390_address_cost (rtx addr
)
2314 struct s390_address ad
;
2315 if (!s390_decompose_address (addr
, &ad
))
2318 return ad
.indx
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
2321 /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
2322 otherwise return 0. */
2325 tls_symbolic_operand (rtx op
)
2327 if (GET_CODE (op
) != SYMBOL_REF
)
2329 return SYMBOL_REF_TLS_MODEL (op
);
2332 /* Split DImode access register reference REG (on 64-bit) into its constituent
2333 low and high parts, and store them into LO and HI. Note that gen_lowpart/
2334 gen_highpart cannot be used as they assume all registers are word-sized,
2335 while our access registers have only half that size. */
2338 s390_split_access_reg (rtx reg
, rtx
*lo
, rtx
*hi
)
2340 gcc_assert (TARGET_64BIT
);
2341 gcc_assert (ACCESS_REG_P (reg
));
2342 gcc_assert (GET_MODE (reg
) == DImode
);
2343 gcc_assert (!(REGNO (reg
) & 1));
2345 *lo
= gen_rtx_REG (SImode
, REGNO (reg
) + 1);
2346 *hi
= gen_rtx_REG (SImode
, REGNO (reg
));
2349 /* Return true if OP contains a symbol reference */
2352 symbolic_reference_mentioned_p (rtx op
)
2357 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
2360 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
2361 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
2367 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
2368 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
2372 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
2379 /* Return true if OP contains a reference to a thread-local symbol. */
2382 tls_symbolic_reference_mentioned_p (rtx op
)
2387 if (GET_CODE (op
) == SYMBOL_REF
)
2388 return tls_symbolic_operand (op
);
2390 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
2391 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
2397 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
2398 if (tls_symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
2402 else if (fmt
[i
] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op
, i
)))
2410 /* Return true if OP is a legitimate general operand when
2411 generating PIC code. It is given that flag_pic is on
2412 and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2415 legitimate_pic_operand_p (rtx op
)
2417 /* Accept all non-symbolic constants. */
2418 if (!SYMBOLIC_CONST (op
))
2421 /* Reject everything else; must be handled
2422 via emit_symbolic_move. */
2426 /* Returns true if the constant value OP is a legitimate general operand.
2427 It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2430 legitimate_constant_p (rtx op
)
2432 /* Accept all non-symbolic constants. */
2433 if (!SYMBOLIC_CONST (op
))
2436 /* Accept immediate LARL operands. */
2437 if (TARGET_CPU_ZARCH
&& larl_operand (op
, VOIDmode
))
2440 /* Thread-local symbols are never legal constants. This is
2441 so that emit_call knows that computing such addresses
2442 might require a function call. */
2443 if (TLS_SYMBOLIC_CONST (op
))
2446 /* In the PIC case, symbolic constants must *not* be
2447 forced into the literal pool. We accept them here,
2448 so that they will be handled by emit_symbolic_move. */
2452 /* All remaining non-PIC symbolic constants are
2453 forced into the literal pool. */
2457 /* Determine if it's legal to put X into the constant pool. This
2458 is not possible if X contains the address of a symbol that is
2459 not constant (TLS) or not known at final link time (PIC). */
2462 s390_cannot_force_const_mem (rtx x
)
2464 switch (GET_CODE (x
))
2468 /* Accept all non-symbolic constants. */
2472 /* Labels are OK iff we are non-PIC. */
2473 return flag_pic
!= 0;
2476 /* 'Naked' TLS symbol references are never OK,
2477 non-TLS symbols are OK iff we are non-PIC. */
2478 if (tls_symbolic_operand (x
))
2481 return flag_pic
!= 0;
2484 return s390_cannot_force_const_mem (XEXP (x
, 0));
2487 return s390_cannot_force_const_mem (XEXP (x
, 0))
2488 || s390_cannot_force_const_mem (XEXP (x
, 1));
2491 switch (XINT (x
, 1))
2493 /* Only lt-relative or GOT-relative UNSPECs are OK. */
2494 case UNSPEC_LTREL_OFFSET
:
2502 case UNSPEC_GOTNTPOFF
:
2503 case UNSPEC_INDNTPOFF
:
2506 /* If the literal pool shares the code section, be put
2507 execute template placeholders into the pool as well. */
2509 return TARGET_CPU_ZARCH
;
2521 /* Returns true if the constant value OP is a legitimate general
2522 operand during and after reload. The difference to
2523 legitimate_constant_p is that this function will not accept
2524 a constant that would need to be forced to the literal pool
2525 before it can be used as operand. */
2528 legitimate_reload_constant_p (rtx op
)
2530 /* Accept la(y) operands. */
2531 if (GET_CODE (op
) == CONST_INT
2532 && DISP_IN_RANGE (INTVAL (op
)))
2535 /* Accept l(g)hi/l(g)fi operands. */
2536 if (GET_CODE (op
) == CONST_INT
2537 && (CONST_OK_FOR_K (INTVAL (op
)) || CONST_OK_FOR_Os (INTVAL (op
))))
2540 /* Accept lliXX operands. */
2542 && GET_CODE (op
) == CONST_INT
2543 && trunc_int_for_mode (INTVAL (op
), word_mode
) == INTVAL (op
)
2544 && s390_single_part (op
, word_mode
, HImode
, 0) >= 0)
2548 && GET_CODE (op
) == CONST_INT
2549 && trunc_int_for_mode (INTVAL (op
), word_mode
) == INTVAL (op
)
2550 && s390_single_part (op
, word_mode
, SImode
, 0) >= 0)
2553 /* Accept larl operands. */
2554 if (TARGET_CPU_ZARCH
2555 && larl_operand (op
, VOIDmode
))
2558 /* Accept lzXX operands. */
2559 if (GET_CODE (op
) == CONST_DOUBLE
2560 && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op
, 'G', "G"))
2563 /* Accept double-word operands that can be split. */
2564 if (GET_CODE (op
) == CONST_INT
2565 && trunc_int_for_mode (INTVAL (op
), word_mode
) != INTVAL (op
))
2567 enum machine_mode dword_mode
= word_mode
== SImode
? DImode
: TImode
;
2568 rtx hi
= operand_subword (op
, 0, 0, dword_mode
);
2569 rtx lo
= operand_subword (op
, 1, 0, dword_mode
);
2570 return legitimate_reload_constant_p (hi
)
2571 && legitimate_reload_constant_p (lo
);
2574 /* Everything else cannot be handled without reload. */
2578 /* Given an rtx OP being reloaded into a reg required to be in class CLASS,
2579 return the class of reg to actually use. */
2582 s390_preferred_reload_class (rtx op
, enum reg_class
class)
2584 switch (GET_CODE (op
))
2586 /* Constants we cannot reload must be forced into the
2591 if (legitimate_reload_constant_p (op
))
2596 /* If a symbolic constant or a PLUS is reloaded,
2597 it is most likely being used as an address, so
2598 prefer ADDR_REGS. If 'class' is not a superset
2599 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
2604 if (reg_class_subset_p (ADDR_REGS
, class))
2616 /* Return the register class of a scratch register needed to
2617 load IN into a register of class CLASS in MODE.
2619 We need a temporary when loading a PLUS expression which
2620 is not a legitimate operand of the LOAD ADDRESS instruction. */
2623 s390_secondary_input_reload_class (enum reg_class
class,
2624 enum machine_mode mode
, rtx in
)
2626 if (s390_plus_operand (in
, mode
))
2629 if (reg_classes_intersect_p (FP_REGS
, class)
2631 && GET_CODE (in
) == MEM
2632 && GET_CODE (XEXP (in
, 0)) == PLUS
2633 && GET_CODE (XEXP (XEXP (in
, 0), 1)) == CONST_INT
2634 && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (in
, 0), 1))
2635 + GET_MODE_SIZE (mode
) - 1))
2638 if (reg_classes_intersect_p (CC_REGS
, class))
2639 return GENERAL_REGS
;
2644 /* Return the register class of a scratch register needed to
2645 store a register of class CLASS in MODE into OUT:
2647 We need a temporary when storing a double-word to a
2648 non-offsettable memory address. */
2651 s390_secondary_output_reload_class (enum reg_class
class,
2652 enum machine_mode mode
, rtx out
)
2654 if ((TARGET_64BIT
? (mode
== TImode
|| mode
== TFmode
)
2655 : (mode
== DImode
|| mode
== DFmode
))
2656 && reg_classes_intersect_p (GENERAL_REGS
, class)
2657 && GET_CODE (out
) == MEM
2658 && GET_CODE (XEXP (out
, 0)) == PLUS
2659 && GET_CODE (XEXP (XEXP (out
, 0), 0)) == PLUS
2660 && GET_CODE (XEXP (XEXP (out
, 0), 1)) == CONST_INT
2661 && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (out
, 0), 1))
2662 + GET_MODE_SIZE (mode
) - 1))
2665 if (reg_classes_intersect_p (FP_REGS
, class)
2667 && GET_CODE (out
) == MEM
2668 && GET_CODE (XEXP (out
, 0)) == PLUS
2669 && GET_CODE (XEXP (XEXP (out
, 0), 1)) == CONST_INT
2670 && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (out
, 0), 1))
2671 + GET_MODE_SIZE (mode
) - 1))
2674 if (reg_classes_intersect_p (CC_REGS
, class))
2675 return GENERAL_REGS
;
2680 /* Generate code to load SRC, which is PLUS that is not a
2681 legitimate operand for the LA instruction, into TARGET.
2682 SCRATCH may be used as scratch register. */
2685 s390_expand_plus_operand (rtx target
, rtx src
,
2689 struct s390_address ad
;
2691 /* src must be a PLUS; get its two operands. */
2692 gcc_assert (GET_CODE (src
) == PLUS
);
2693 gcc_assert (GET_MODE (src
) == Pmode
);
2695 /* Check if any of the two operands is already scheduled
2696 for replacement by reload. This can happen e.g. when
2697 float registers occur in an address. */
2698 sum1
= find_replacement (&XEXP (src
, 0));
2699 sum2
= find_replacement (&XEXP (src
, 1));
2700 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
2702 /* If the address is already strictly valid, there's nothing to do. */
2703 if (!s390_decompose_address (src
, &ad
)
2704 || (ad
.base
&& !REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)))
2705 || (ad
.indx
&& !REGNO_OK_FOR_INDEX_P (REGNO (ad
.indx
))))
2707 /* Otherwise, one of the operands cannot be an address register;
2708 we reload its value into the scratch register. */
2709 if (true_regnum (sum1
) < 1 || true_regnum (sum1
) > 15)
2711 emit_move_insn (scratch
, sum1
);
2714 if (true_regnum (sum2
) < 1 || true_regnum (sum2
) > 15)
2716 emit_move_insn (scratch
, sum2
);
2720 /* According to the way these invalid addresses are generated
2721 in reload.c, it should never happen (at least on s390) that
2722 *neither* of the PLUS components, after find_replacements
2723 was applied, is an address register. */
2724 if (sum1
== scratch
&& sum2
== scratch
)
2730 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
2733 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
2734 is only ever performed on addresses, so we can mark the
2735 sum as legitimate for LA in any case. */
2736 s390_load_address (target
, src
);
2740 /* Return true if ADDR is a valid memory address.
2741 STRICT specifies whether strict register checking applies. */
2744 legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED
,
2745 rtx addr
, int strict
)
2747 struct s390_address ad
;
2748 if (!s390_decompose_address (addr
, &ad
))
2753 if (ad
.base
&& !REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)))
2756 if (ad
.indx
&& !REGNO_OK_FOR_INDEX_P (REGNO (ad
.indx
)))
2762 && !(REGNO (ad
.base
) >= FIRST_PSEUDO_REGISTER
2763 || REGNO_REG_CLASS (REGNO (ad
.base
)) == ADDR_REGS
))
2767 && !(REGNO (ad
.indx
) >= FIRST_PSEUDO_REGISTER
2768 || REGNO_REG_CLASS (REGNO (ad
.indx
)) == ADDR_REGS
))
2774 /* Return true if OP is a valid operand for the LA instruction.
2775 In 31-bit, we need to prove that the result is used as an
2776 address, as LA performs only a 31-bit addition. */
2779 legitimate_la_operand_p (rtx op
)
2781 struct s390_address addr
;
2782 if (!s390_decompose_address (op
, &addr
))
2785 return (TARGET_64BIT
|| addr
.pointer
);
2788 /* Return true if it is valid *and* preferable to use LA to
2789 compute the sum of OP1 and OP2. */
2792 preferred_la_operand_p (rtx op1
, rtx op2
)
2794 struct s390_address addr
;
2796 if (op2
!= const0_rtx
)
2797 op1
= gen_rtx_PLUS (Pmode
, op1
, op2
);
2799 if (!s390_decompose_address (op1
, &addr
))
2801 if (addr
.base
&& !REGNO_OK_FOR_BASE_P (REGNO (addr
.base
)))
2803 if (addr
.indx
&& !REGNO_OK_FOR_INDEX_P (REGNO (addr
.indx
)))
2806 if (!TARGET_64BIT
&& !addr
.pointer
)
2812 if ((addr
.base
&& REG_P (addr
.base
) && REG_POINTER (addr
.base
))
2813 || (addr
.indx
&& REG_P (addr
.indx
) && REG_POINTER (addr
.indx
)))
2819 /* Emit a forced load-address operation to load SRC into DST.
2820 This will use the LOAD ADDRESS instruction even in situations
2821 where legitimate_la_operand_p (SRC) returns false. */
2824 s390_load_address (rtx dst
, rtx src
)
2827 emit_move_insn (dst
, src
);
2829 emit_insn (gen_force_la_31 (dst
, src
));
2832 /* Return a legitimate reference for ORIG (an address) using the
2833 register REG. If REG is 0, a new pseudo is generated.
2835 There are two types of references that must be handled:
2837 1. Global data references must load the address from the GOT, via
2838 the PIC reg. An insn is emitted to do this load, and the reg is
2841 2. Static data references, constant pool addresses, and code labels
2842 compute the address as an offset from the GOT, whose base is in
2843 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
2844 differentiate them from global data objects. The returned
2845 address is the PIC reg + an unspec constant.
2847 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2848 reg also appears in the address. */
2851 legitimize_pic_address (rtx orig
, rtx reg
)
2857 gcc_assert (!TLS_SYMBOLIC_CONST (addr
));
2859 if (GET_CODE (addr
) == LABEL_REF
2860 || (GET_CODE (addr
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (addr
)))
2862 /* This is a local symbol. */
2863 if (TARGET_CPU_ZARCH
&& larl_operand (addr
, VOIDmode
))
2865 /* Access local symbols PC-relative via LARL.
2866 This is the same as in the non-PIC case, so it is
2867 handled automatically ... */
2871 /* Access local symbols relative to the GOT. */
2873 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2875 if (reload_in_progress
|| reload_completed
)
2876 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2878 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTOFF
);
2879 addr
= gen_rtx_CONST (Pmode
, addr
);
2880 addr
= force_const_mem (Pmode
, addr
);
2881 emit_move_insn (temp
, addr
);
2883 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2886 s390_load_address (reg
, new);
2891 else if (GET_CODE (addr
) == SYMBOL_REF
)
2894 reg
= gen_reg_rtx (Pmode
);
2898 /* Assume GOT offset < 4k. This is handled the same way
2899 in both 31- and 64-bit code (@GOT). */
2901 if (reload_in_progress
|| reload_completed
)
2902 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2904 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
2905 new = gen_rtx_CONST (Pmode
, new);
2906 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new);
2907 new = gen_const_mem (Pmode
, new);
2908 emit_move_insn (reg
, new);
2911 else if (TARGET_CPU_ZARCH
)
2913 /* If the GOT offset might be >= 4k, we determine the position
2914 of the GOT entry via a PC-relative LARL (@GOTENT). */
2916 rtx temp
= gen_reg_rtx (Pmode
);
2918 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTENT
);
2919 new = gen_rtx_CONST (Pmode
, new);
2920 emit_move_insn (temp
, new);
2922 new = gen_const_mem (Pmode
, temp
);
2923 emit_move_insn (reg
, new);
2928 /* If the GOT offset might be >= 4k, we have to load it
2929 from the literal pool (@GOT). */
2931 rtx temp
= gen_reg_rtx (Pmode
);
2933 if (reload_in_progress
|| reload_completed
)
2934 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2936 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
2937 addr
= gen_rtx_CONST (Pmode
, addr
);
2938 addr
= force_const_mem (Pmode
, addr
);
2939 emit_move_insn (temp
, addr
);
2941 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2942 new = gen_const_mem (Pmode
, new);
2943 emit_move_insn (reg
, new);
2949 if (GET_CODE (addr
) == CONST
)
2951 addr
= XEXP (addr
, 0);
2952 if (GET_CODE (addr
) == UNSPEC
)
2954 gcc_assert (XVECLEN (addr
, 0) == 1);
2955 switch (XINT (addr
, 1))
2957 /* If someone moved a GOT-relative UNSPEC
2958 out of the literal pool, force them back in. */
2961 new = force_const_mem (Pmode
, orig
);
2964 /* @GOT is OK as is if small. */
2967 new = force_const_mem (Pmode
, orig
);
2970 /* @GOTENT is OK as is. */
2974 /* @PLT is OK as is on 64-bit, must be converted to
2975 GOT-relative @PLTOFF on 31-bit. */
2977 if (!TARGET_CPU_ZARCH
)
2979 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2981 if (reload_in_progress
|| reload_completed
)
2982 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2984 addr
= XVECEXP (addr
, 0, 0);
2985 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
),
2987 addr
= gen_rtx_CONST (Pmode
, addr
);
2988 addr
= force_const_mem (Pmode
, addr
);
2989 emit_move_insn (temp
, addr
);
2991 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2994 s390_load_address (reg
, new);
3000 /* Everything else cannot happen. */
3006 gcc_assert (GET_CODE (addr
) == PLUS
);
3008 if (GET_CODE (addr
) == PLUS
)
3010 rtx op0
= XEXP (addr
, 0), op1
= XEXP (addr
, 1);
3012 gcc_assert (!TLS_SYMBOLIC_CONST (op0
));
3013 gcc_assert (!TLS_SYMBOLIC_CONST (op1
));
3015 /* Check first to see if this is a constant offset
3016 from a local symbol reference. */
3017 if ((GET_CODE (op0
) == LABEL_REF
3018 || (GET_CODE (op0
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (op0
)))
3019 && GET_CODE (op1
) == CONST_INT
)
3021 if (TARGET_CPU_ZARCH
3022 && larl_operand (op0
, VOIDmode
)
3023 && INTVAL (op1
) < (HOST_WIDE_INT
)1 << 31
3024 && INTVAL (op1
) >= -((HOST_WIDE_INT
)1 << 31))
3026 if (INTVAL (op1
) & 1)
3028 /* LARL can't handle odd offsets, so emit a
3029 pair of LARL and LA. */
3030 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
3032 if (!DISP_IN_RANGE (INTVAL (op1
)))
3034 HOST_WIDE_INT even
= INTVAL (op1
) - 1;
3035 op0
= gen_rtx_PLUS (Pmode
, op0
, GEN_INT (even
));
3036 op0
= gen_rtx_CONST (Pmode
, op0
);
3040 emit_move_insn (temp
, op0
);
3041 new = gen_rtx_PLUS (Pmode
, temp
, op1
);
3045 s390_load_address (reg
, new);
3051 /* If the offset is even, we can just use LARL.
3052 This will happen automatically. */
3057 /* Access local symbols relative to the GOT. */
3059 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
3061 if (reload_in_progress
|| reload_completed
)
3062 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
3064 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op0
),
3066 addr
= gen_rtx_PLUS (Pmode
, addr
, op1
);
3067 addr
= gen_rtx_CONST (Pmode
, addr
);
3068 addr
= force_const_mem (Pmode
, addr
);
3069 emit_move_insn (temp
, addr
);
3071 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
3074 s390_load_address (reg
, new);
3080 /* Now, check whether it is a GOT relative symbol plus offset
3081 that was pulled out of the literal pool. Force it back in. */
3083 else if (GET_CODE (op0
) == UNSPEC
3084 && GET_CODE (op1
) == CONST_INT
3085 && XINT (op0
, 1) == UNSPEC_GOTOFF
)
3087 gcc_assert (XVECLEN (op0
, 0) == 1);
3089 new = force_const_mem (Pmode
, orig
);
3092 /* Otherwise, compute the sum. */
3095 base
= legitimize_pic_address (XEXP (addr
, 0), reg
);
3096 new = legitimize_pic_address (XEXP (addr
, 1),
3097 base
== reg
? NULL_RTX
: reg
);
3098 if (GET_CODE (new) == CONST_INT
)
3099 new = plus_constant (base
, INTVAL (new));
3102 if (GET_CODE (new) == PLUS
&& CONSTANT_P (XEXP (new, 1)))
3104 base
= gen_rtx_PLUS (Pmode
, base
, XEXP (new, 0));
3105 new = XEXP (new, 1);
3107 new = gen_rtx_PLUS (Pmode
, base
, new);
3110 if (GET_CODE (new) == CONST
)
3111 new = XEXP (new, 0);
3112 new = force_operand (new, 0);
3119 /* Load the thread pointer into a register. */
3122 s390_get_thread_pointer (void)
3124 rtx tp
= gen_reg_rtx (Pmode
);
3126 emit_move_insn (tp
, gen_rtx_REG (Pmode
, TP_REGNUM
));
3127 mark_reg_pointer (tp
, BITS_PER_WORD
);
3132 /* Emit a tls call insn. The call target is the SYMBOL_REF stored
3133 in s390_tls_symbol which always refers to __tls_get_offset.
3134 The returned offset is written to RESULT_REG and an USE rtx is
3135 generated for TLS_CALL. */
3137 static GTY(()) rtx s390_tls_symbol
;
3140 s390_emit_tls_call_insn (rtx result_reg
, rtx tls_call
)
3144 gcc_assert (flag_pic
);
3146 if (!s390_tls_symbol
)
3147 s390_tls_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "__tls_get_offset");
3149 insn
= s390_emit_call (s390_tls_symbol
, tls_call
, result_reg
,
3150 gen_rtx_REG (Pmode
, RETURN_REGNUM
));
3152 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), result_reg
);
3153 CONST_OR_PURE_CALL_P (insn
) = 1;
3156 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
3157 this (thread-local) address. REG may be used as temporary. */
3160 legitimize_tls_address (rtx addr
, rtx reg
)
3162 rtx
new, tls_call
, temp
, base
, r2
, insn
;
3164 if (GET_CODE (addr
) == SYMBOL_REF
)
3165 switch (tls_symbolic_operand (addr
))
3167 case TLS_MODEL_GLOBAL_DYNAMIC
:
3169 r2
= gen_rtx_REG (Pmode
, 2);
3170 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_TLSGD
);
3171 new = gen_rtx_CONST (Pmode
, tls_call
);
3172 new = force_const_mem (Pmode
, new);
3173 emit_move_insn (r2
, new);
3174 s390_emit_tls_call_insn (r2
, tls_call
);
3175 insn
= get_insns ();
3178 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
3179 temp
= gen_reg_rtx (Pmode
);
3180 emit_libcall_block (insn
, temp
, r2
, new);
3182 new = gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
3185 s390_load_address (reg
, new);
3190 case TLS_MODEL_LOCAL_DYNAMIC
:
3192 r2
= gen_rtx_REG (Pmode
, 2);
3193 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM
);
3194 new = gen_rtx_CONST (Pmode
, tls_call
);
3195 new = force_const_mem (Pmode
, new);
3196 emit_move_insn (r2
, new);
3197 s390_emit_tls_call_insn (r2
, tls_call
);
3198 insn
= get_insns ();
3201 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM_NTPOFF
);
3202 temp
= gen_reg_rtx (Pmode
);
3203 emit_libcall_block (insn
, temp
, r2
, new);
3205 new = gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
3206 base
= gen_reg_rtx (Pmode
);
3207 s390_load_address (base
, new);
3209 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_DTPOFF
);
3210 new = gen_rtx_CONST (Pmode
, new);
3211 new = force_const_mem (Pmode
, new);
3212 temp
= gen_reg_rtx (Pmode
);
3213 emit_move_insn (temp
, new);
3215 new = gen_rtx_PLUS (Pmode
, base
, temp
);
3218 s390_load_address (reg
, new);
3223 case TLS_MODEL_INITIAL_EXEC
:
3226 /* Assume GOT offset < 4k. This is handled the same way
3227 in both 31- and 64-bit code. */
3229 if (reload_in_progress
|| reload_completed
)
3230 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
3232 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
3233 new = gen_rtx_CONST (Pmode
, new);
3234 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new);
3235 new = gen_const_mem (Pmode
, new);
3236 temp
= gen_reg_rtx (Pmode
);
3237 emit_move_insn (temp
, new);
3239 else if (TARGET_CPU_ZARCH
)
3241 /* If the GOT offset might be >= 4k, we determine the position
3242 of the GOT entry via a PC-relative LARL. */
3244 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
3245 new = gen_rtx_CONST (Pmode
, new);
3246 temp
= gen_reg_rtx (Pmode
);
3247 emit_move_insn (temp
, new);
3249 new = gen_const_mem (Pmode
, temp
);
3250 temp
= gen_reg_rtx (Pmode
);
3251 emit_move_insn (temp
, new);
3255 /* If the GOT offset might be >= 4k, we have to load it
3256 from the literal pool. */
3258 if (reload_in_progress
|| reload_completed
)
3259 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
3261 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
3262 new = gen_rtx_CONST (Pmode
, new);
3263 new = force_const_mem (Pmode
, new);
3264 temp
= gen_reg_rtx (Pmode
);
3265 emit_move_insn (temp
, new);
3267 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
3268 new = gen_const_mem (Pmode
, new);
3270 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new, addr
), UNSPEC_TLS_LOAD
);
3271 temp
= gen_reg_rtx (Pmode
);
3272 emit_insn (gen_rtx_SET (Pmode
, temp
, new));
3276 /* In position-dependent code, load the absolute address of
3277 the GOT entry from the literal pool. */
3279 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
3280 new = gen_rtx_CONST (Pmode
, new);
3281 new = force_const_mem (Pmode
, new);
3282 temp
= gen_reg_rtx (Pmode
);
3283 emit_move_insn (temp
, new);
3286 new = gen_const_mem (Pmode
, new);
3287 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new, addr
), UNSPEC_TLS_LOAD
);
3288 temp
= gen_reg_rtx (Pmode
);
3289 emit_insn (gen_rtx_SET (Pmode
, temp
, new));
3292 new = gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
3295 s390_load_address (reg
, new);
3300 case TLS_MODEL_LOCAL_EXEC
:
3301 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
3302 new = gen_rtx_CONST (Pmode
, new);
3303 new = force_const_mem (Pmode
, new);
3304 temp
= gen_reg_rtx (Pmode
);
3305 emit_move_insn (temp
, new);
3307 new = gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
3310 s390_load_address (reg
, new);
3319 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == UNSPEC
)
3321 switch (XINT (XEXP (addr
, 0), 1))
3323 case UNSPEC_INDNTPOFF
:
3324 gcc_assert (TARGET_CPU_ZARCH
);
3333 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == PLUS
3334 && GET_CODE (XEXP (XEXP (addr
, 0), 1)) == CONST_INT
)
3336 new = XEXP (XEXP (addr
, 0), 0);
3337 if (GET_CODE (new) != SYMBOL_REF
)
3338 new = gen_rtx_CONST (Pmode
, new);
3340 new = legitimize_tls_address (new, reg
);
3341 new = plus_constant (new, INTVAL (XEXP (XEXP (addr
, 0), 1)));
3342 new = force_operand (new, 0);
3346 gcc_unreachable (); /* for now ... */
3351 /* Emit insns to move operands[1] into operands[0]. */
3354 emit_symbolic_move (rtx
*operands
)
3356 rtx temp
= no_new_pseudos
? operands
[0] : gen_reg_rtx (Pmode
);
3358 if (GET_CODE (operands
[0]) == MEM
)
3359 operands
[1] = force_reg (Pmode
, operands
[1]);
3360 else if (TLS_SYMBOLIC_CONST (operands
[1]))
3361 operands
[1] = legitimize_tls_address (operands
[1], temp
);
3363 operands
[1] = legitimize_pic_address (operands
[1], temp
);
3366 /* Try machine-dependent ways of modifying an illegitimate address X
3367 to be legitimate. If we find one, return the new, valid address.
3369 OLDX is the address as it was before break_out_memory_refs was called.
3370 In some cases it is useful to look at this to decide what needs to be done.
3372 MODE is the mode of the operand pointed to by X.
3374 When -fpic is used, special handling is needed for symbolic references.
3375 See comments by legitimize_pic_address for details. */
3378 legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
3379 enum machine_mode mode ATTRIBUTE_UNUSED
)
3381 rtx constant_term
= const0_rtx
;
3383 if (TLS_SYMBOLIC_CONST (x
))
3385 x
= legitimize_tls_address (x
, 0);
3387 if (legitimate_address_p (mode
, x
, FALSE
))
3390 else if (GET_CODE (x
) == PLUS
3391 && (TLS_SYMBOLIC_CONST (XEXP (x
, 0))
3392 || TLS_SYMBOLIC_CONST (XEXP (x
, 1))))
3398 if (SYMBOLIC_CONST (x
)
3399 || (GET_CODE (x
) == PLUS
3400 && (SYMBOLIC_CONST (XEXP (x
, 0))
3401 || SYMBOLIC_CONST (XEXP (x
, 1)))))
3402 x
= legitimize_pic_address (x
, 0);
3404 if (legitimate_address_p (mode
, x
, FALSE
))
3408 x
= eliminate_constant_term (x
, &constant_term
);
3410 /* Optimize loading of large displacements by splitting them
3411 into the multiple of 4K and the rest; this allows the
3412 former to be CSE'd if possible.
3414 Don't do this if the displacement is added to a register
3415 pointing into the stack frame, as the offsets will
3416 change later anyway. */
3418 if (GET_CODE (constant_term
) == CONST_INT
3419 && !TARGET_LONG_DISPLACEMENT
3420 && !DISP_IN_RANGE (INTVAL (constant_term
))
3421 && !(REG_P (x
) && REGNO_PTR_FRAME_P (REGNO (x
))))
3423 HOST_WIDE_INT lower
= INTVAL (constant_term
) & 0xfff;
3424 HOST_WIDE_INT upper
= INTVAL (constant_term
) ^ lower
;
3426 rtx temp
= gen_reg_rtx (Pmode
);
3427 rtx val
= force_operand (GEN_INT (upper
), temp
);
3429 emit_move_insn (temp
, val
);
3431 x
= gen_rtx_PLUS (Pmode
, x
, temp
);
3432 constant_term
= GEN_INT (lower
);
3435 if (GET_CODE (x
) == PLUS
)
3437 if (GET_CODE (XEXP (x
, 0)) == REG
)
3439 rtx temp
= gen_reg_rtx (Pmode
);
3440 rtx val
= force_operand (XEXP (x
, 1), temp
);
3442 emit_move_insn (temp
, val
);
3444 x
= gen_rtx_PLUS (Pmode
, XEXP (x
, 0), temp
);
3447 else if (GET_CODE (XEXP (x
, 1)) == REG
)
3449 rtx temp
= gen_reg_rtx (Pmode
);
3450 rtx val
= force_operand (XEXP (x
, 0), temp
);
3452 emit_move_insn (temp
, val
);
3454 x
= gen_rtx_PLUS (Pmode
, temp
, XEXP (x
, 1));
3458 if (constant_term
!= const0_rtx
)
3459 x
= gen_rtx_PLUS (Pmode
, x
, constant_term
);
3464 /* Try a machine-dependent way of reloading an illegitimate address AD
3465 operand. If we find one, push the reload and and return the new address.
3467 MODE is the mode of the enclosing MEM. OPNUM is the operand number
3468 and TYPE is the reload type of the current reload. */
3471 legitimize_reload_address (rtx ad
, enum machine_mode mode ATTRIBUTE_UNUSED
,
3472 int opnum
, int type
)
3474 if (!optimize
|| TARGET_LONG_DISPLACEMENT
)
3477 if (GET_CODE (ad
) == PLUS
)
3479 rtx tem
= simplify_binary_operation (PLUS
, Pmode
,
3480 XEXP (ad
, 0), XEXP (ad
, 1));
3485 if (GET_CODE (ad
) == PLUS
3486 && GET_CODE (XEXP (ad
, 0)) == REG
3487 && GET_CODE (XEXP (ad
, 1)) == CONST_INT
3488 && !DISP_IN_RANGE (INTVAL (XEXP (ad
, 1))))
3490 HOST_WIDE_INT lower
= INTVAL (XEXP (ad
, 1)) & 0xfff;
3491 HOST_WIDE_INT upper
= INTVAL (XEXP (ad
, 1)) ^ lower
;
3494 cst
= GEN_INT (upper
);
3495 if (!legitimate_reload_constant_p (cst
))
3496 cst
= force_const_mem (Pmode
, cst
);
3498 tem
= gen_rtx_PLUS (Pmode
, XEXP (ad
, 0), cst
);
3499 new = gen_rtx_PLUS (Pmode
, tem
, GEN_INT (lower
));
3501 push_reload (XEXP (tem
, 1), 0, &XEXP (tem
, 1), 0,
3502 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
3503 opnum
, (enum reload_type
) type
);
3510 /* Emit code to move LEN bytes from DST to SRC. */
3513 s390_expand_movmem (rtx dst
, rtx src
, rtx len
)
3515 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3517 if (INTVAL (len
) > 0)
3518 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (INTVAL (len
) - 1)));
3521 else if (TARGET_MVCLE
)
3523 emit_insn (gen_movmem_long (dst
, src
, convert_to_mode (Pmode
, len
, 1)));
3528 rtx dst_addr
, src_addr
, count
, blocks
, temp
;
3529 rtx loop_start_label
= gen_label_rtx ();
3530 rtx loop_end_label
= gen_label_rtx ();
3531 rtx end_label
= gen_label_rtx ();
3532 enum machine_mode mode
;
3534 mode
= GET_MODE (len
);
3535 if (mode
== VOIDmode
)
3538 dst_addr
= gen_reg_rtx (Pmode
);
3539 src_addr
= gen_reg_rtx (Pmode
);
3540 count
= gen_reg_rtx (mode
);
3541 blocks
= gen_reg_rtx (mode
);
3543 convert_move (count
, len
, 1);
3544 emit_cmp_and_jump_insns (count
, const0_rtx
,
3545 EQ
, NULL_RTX
, mode
, 1, end_label
);
3547 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
3548 emit_move_insn (src_addr
, force_operand (XEXP (src
, 0), NULL_RTX
));
3549 dst
= change_address (dst
, VOIDmode
, dst_addr
);
3550 src
= change_address (src
, VOIDmode
, src_addr
);
3552 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3554 emit_move_insn (count
, temp
);
3556 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3558 emit_move_insn (blocks
, temp
);
3560 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3561 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3563 emit_label (loop_start_label
);
3565 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (255)));
3566 s390_load_address (dst_addr
,
3567 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
3568 s390_load_address (src_addr
,
3569 gen_rtx_PLUS (Pmode
, src_addr
, GEN_INT (256)));
3571 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3573 emit_move_insn (blocks
, temp
);
3575 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3576 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3578 emit_jump (loop_start_label
);
3579 emit_label (loop_end_label
);
3581 emit_insn (gen_movmem_short (dst
, src
,
3582 convert_to_mode (Pmode
, count
, 1)));
3583 emit_label (end_label
);
3587 /* Emit code to set LEN bytes at DST to VAL.
3588 Make use of clrmem if VAL is zero. */
3591 s390_expand_setmem (rtx dst
, rtx len
, rtx val
)
3593 gcc_assert (GET_CODE (len
) != CONST_INT
|| INTVAL (len
) > 0);
3594 gcc_assert (GET_CODE (val
) == CONST_INT
|| GET_MODE (val
) == QImode
);
3596 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) <= 257)
3598 if (val
== const0_rtx
&& INTVAL (len
) <= 256)
3599 emit_insn (gen_clrmem_short (dst
, GEN_INT (INTVAL (len
) - 1)));
3602 /* Initialize memory by storing the first byte. */
3603 emit_move_insn (adjust_address (dst
, QImode
, 0), val
);
3605 if (INTVAL (len
) > 1)
3607 /* Initiate 1 byte overlap move.
3608 The first byte of DST is propagated through DSTP1.
3609 Prepare a movmem for: DST+1 = DST (length = LEN - 1).
3610 DST is set to size 1 so the rest of the memory location
3611 does not count as source operand. */
3612 rtx dstp1
= adjust_address (dst
, VOIDmode
, 1);
3613 set_mem_size (dst
, const1_rtx
);
3615 emit_insn (gen_movmem_short (dstp1
, dst
,
3616 GEN_INT (INTVAL (len
) - 2)));
3621 else if (TARGET_MVCLE
)
3623 val
= force_not_mem (convert_modes (Pmode
, QImode
, val
, 1));
3624 emit_insn (gen_setmem_long (dst
, convert_to_mode (Pmode
, len
, 1), val
));
3629 rtx dst_addr
, src_addr
, count
, blocks
, temp
, dstp1
= NULL_RTX
;
3630 rtx loop_start_label
= gen_label_rtx ();
3631 rtx loop_end_label
= gen_label_rtx ();
3632 rtx end_label
= gen_label_rtx ();
3633 enum machine_mode mode
;
3635 mode
= GET_MODE (len
);
3636 if (mode
== VOIDmode
)
3639 dst_addr
= gen_reg_rtx (Pmode
);
3640 src_addr
= gen_reg_rtx (Pmode
);
3641 count
= gen_reg_rtx (mode
);
3642 blocks
= gen_reg_rtx (mode
);
3644 convert_move (count
, len
, 1);
3645 emit_cmp_and_jump_insns (count
, const0_rtx
,
3646 EQ
, NULL_RTX
, mode
, 1, end_label
);
3648 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
3649 dst
= change_address (dst
, VOIDmode
, dst_addr
);
3651 if (val
== const0_rtx
)
3652 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3655 dstp1
= adjust_address (dst
, VOIDmode
, 1);
3656 set_mem_size (dst
, const1_rtx
);
3658 /* Initialize memory by storing the first byte. */
3659 emit_move_insn (adjust_address (dst
, QImode
, 0), val
);
3661 /* If count is 1 we are done. */
3662 emit_cmp_and_jump_insns (count
, const1_rtx
,
3663 EQ
, NULL_RTX
, mode
, 1, end_label
);
3665 temp
= expand_binop (mode
, add_optab
, count
, GEN_INT (-2), count
, 1, 0);
3668 emit_move_insn (count
, temp
);
3670 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3672 emit_move_insn (blocks
, temp
);
3674 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3675 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3677 emit_label (loop_start_label
);
3679 if (val
== const0_rtx
)
3680 emit_insn (gen_clrmem_short (dst
, GEN_INT (255)));
3682 emit_insn (gen_movmem_short (dstp1
, dst
, GEN_INT (255)));
3683 s390_load_address (dst_addr
,
3684 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
3686 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3688 emit_move_insn (blocks
, temp
);
3690 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3691 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3693 emit_jump (loop_start_label
);
3694 emit_label (loop_end_label
);
3696 if (val
== const0_rtx
)
3697 emit_insn (gen_clrmem_short (dst
, convert_to_mode (Pmode
, count
, 1)));
3699 emit_insn (gen_movmem_short (dstp1
, dst
, convert_to_mode (Pmode
, count
, 1)));
3700 emit_label (end_label
);
3704 /* Emit code to compare LEN bytes at OP0 with those at OP1,
3705 and return the result in TARGET. */
3708 s390_expand_cmpmem (rtx target
, rtx op0
, rtx op1
, rtx len
)
3710 rtx ccreg
= gen_rtx_REG (CCUmode
, CC_REGNUM
);
3713 /* As the result of CMPINT is inverted compared to what we need,
3714 we have to swap the operands. */
3715 tmp
= op0
; op0
= op1
; op1
= tmp
;
3717 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3719 if (INTVAL (len
) > 0)
3721 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (INTVAL (len
) - 1)));
3722 emit_insn (gen_cmpint (target
, ccreg
));
3725 emit_move_insn (target
, const0_rtx
);
3727 else if (TARGET_MVCLE
)
3729 emit_insn (gen_cmpmem_long (op0
, op1
, convert_to_mode (Pmode
, len
, 1)));
3730 emit_insn (gen_cmpint (target
, ccreg
));
3734 rtx addr0
, addr1
, count
, blocks
, temp
;
3735 rtx loop_start_label
= gen_label_rtx ();
3736 rtx loop_end_label
= gen_label_rtx ();
3737 rtx end_label
= gen_label_rtx ();
3738 enum machine_mode mode
;
3740 mode
= GET_MODE (len
);
3741 if (mode
== VOIDmode
)
3744 addr0
= gen_reg_rtx (Pmode
);
3745 addr1
= gen_reg_rtx (Pmode
);
3746 count
= gen_reg_rtx (mode
);
3747 blocks
= gen_reg_rtx (mode
);
3749 convert_move (count
, len
, 1);
3750 emit_cmp_and_jump_insns (count
, const0_rtx
,
3751 EQ
, NULL_RTX
, mode
, 1, end_label
);
3753 emit_move_insn (addr0
, force_operand (XEXP (op0
, 0), NULL_RTX
));
3754 emit_move_insn (addr1
, force_operand (XEXP (op1
, 0), NULL_RTX
));
3755 op0
= change_address (op0
, VOIDmode
, addr0
);
3756 op1
= change_address (op1
, VOIDmode
, addr1
);
3758 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3760 emit_move_insn (count
, temp
);
3762 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3764 emit_move_insn (blocks
, temp
);
3766 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3767 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3769 emit_label (loop_start_label
);
3771 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (255)));
3772 temp
= gen_rtx_NE (VOIDmode
, ccreg
, const0_rtx
);
3773 temp
= gen_rtx_IF_THEN_ELSE (VOIDmode
, temp
,
3774 gen_rtx_LABEL_REF (VOIDmode
, end_label
), pc_rtx
);
3775 temp
= gen_rtx_SET (VOIDmode
, pc_rtx
, temp
);
3776 emit_jump_insn (temp
);
3778 s390_load_address (addr0
,
3779 gen_rtx_PLUS (Pmode
, addr0
, GEN_INT (256)));
3780 s390_load_address (addr1
,
3781 gen_rtx_PLUS (Pmode
, addr1
, GEN_INT (256)));
3783 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3785 emit_move_insn (blocks
, temp
);
3787 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3788 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3790 emit_jump (loop_start_label
);
3791 emit_label (loop_end_label
);
3793 emit_insn (gen_cmpmem_short (op0
, op1
,
3794 convert_to_mode (Pmode
, count
, 1)));
3795 emit_label (end_label
);
3797 emit_insn (gen_cmpint (target
, ccreg
));
3802 /* Expand conditional increment or decrement using alc/slb instructions.
3803 Should generate code setting DST to either SRC or SRC + INCREMENT,
3804 depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
3805 Returns true if successful, false otherwise.
3807 That makes it possible to implement some if-constructs without jumps e.g.:
3808 (borrow = CC0 | CC1 and carry = CC2 | CC3)
3809 unsigned int a, b, c;
3810 if (a < b) c++; -> CCU b > a -> CC2; c += carry;
3811 if (a < b) c--; -> CCL3 a - b -> borrow; c -= borrow;
3812 if (a <= b) c++; -> CCL3 b - a -> borrow; c += carry;
3813 if (a <= b) c--; -> CCU a <= b -> borrow; c -= borrow;
3815 Checks for EQ and NE with a nonzero value need an additional xor e.g.:
3816 if (a == b) c++; -> CCL3 a ^= b; 0 - a -> borrow; c += carry;
3817 if (a == b) c--; -> CCU a ^= b; a <= 0 -> CC0 | CC1; c -= borrow;
3818 if (a != b) c++; -> CCU a ^= b; a > 0 -> CC2; c += carry;
3819 if (a != b) c--; -> CCL3 a ^= b; 0 - a -> borrow; c -= borrow; */
3822 s390_expand_addcc (enum rtx_code cmp_code
, rtx cmp_op0
, rtx cmp_op1
,
3823 rtx dst
, rtx src
, rtx increment
)
3825 enum machine_mode cmp_mode
;
3826 enum machine_mode cc_mode
;
3832 if ((GET_MODE (cmp_op0
) == SImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
3833 && (GET_MODE (cmp_op1
) == SImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
3835 else if ((GET_MODE (cmp_op0
) == DImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
3836 && (GET_MODE (cmp_op1
) == DImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
3841 /* Try ADD LOGICAL WITH CARRY. */
3842 if (increment
== const1_rtx
)
3844 /* Determine CC mode to use. */
3845 if (cmp_code
== EQ
|| cmp_code
== NE
)
3847 if (cmp_op1
!= const0_rtx
)
3849 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
3850 NULL_RTX
, 0, OPTAB_WIDEN
);
3851 cmp_op1
= const0_rtx
;
3854 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
3857 if (cmp_code
== LTU
|| cmp_code
== LEU
)
3862 cmp_code
= swap_condition (cmp_code
);
3879 /* Emit comparison instruction pattern. */
3880 if (!register_operand (cmp_op0
, cmp_mode
))
3881 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
3883 insn
= gen_rtx_SET (VOIDmode
, gen_rtx_REG (cc_mode
, CC_REGNUM
),
3884 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
3885 /* We use insn_invalid_p here to add clobbers if required. */
3886 ret
= insn_invalid_p (emit_insn (insn
));
3889 /* Emit ALC instruction pattern. */
3890 op_res
= gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
3891 gen_rtx_REG (cc_mode
, CC_REGNUM
),
3894 if (src
!= const0_rtx
)
3896 if (!register_operand (src
, GET_MODE (dst
)))
3897 src
= force_reg (GET_MODE (dst
), src
);
3899 src
= gen_rtx_PLUS (GET_MODE (dst
), src
, const0_rtx
);
3900 op_res
= gen_rtx_PLUS (GET_MODE (dst
), src
, op_res
);
3903 p
= rtvec_alloc (2);
3905 gen_rtx_SET (VOIDmode
, dst
, op_res
);
3907 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
3908 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
3913 /* Try SUBTRACT LOGICAL WITH BORROW. */
3914 if (increment
== constm1_rtx
)
3916 /* Determine CC mode to use. */
3917 if (cmp_code
== EQ
|| cmp_code
== NE
)
3919 if (cmp_op1
!= const0_rtx
)
3921 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
3922 NULL_RTX
, 0, OPTAB_WIDEN
);
3923 cmp_op1
= const0_rtx
;
3926 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
3929 if (cmp_code
== GTU
|| cmp_code
== GEU
)
3934 cmp_code
= swap_condition (cmp_code
);
3951 /* Emit comparison instruction pattern. */
3952 if (!register_operand (cmp_op0
, cmp_mode
))
3953 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
3955 insn
= gen_rtx_SET (VOIDmode
, gen_rtx_REG (cc_mode
, CC_REGNUM
),
3956 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
3957 /* We use insn_invalid_p here to add clobbers if required. */
3958 ret
= insn_invalid_p (emit_insn (insn
));
3961 /* Emit SLB instruction pattern. */
3962 if (!register_operand (src
, GET_MODE (dst
)))
3963 src
= force_reg (GET_MODE (dst
), src
);
3965 op_res
= gen_rtx_MINUS (GET_MODE (dst
),
3966 gen_rtx_MINUS (GET_MODE (dst
), src
, const0_rtx
),
3967 gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
3968 gen_rtx_REG (cc_mode
, CC_REGNUM
),
3970 p
= rtvec_alloc (2);
3972 gen_rtx_SET (VOIDmode
, dst
, op_res
);
3974 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
3975 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
3983 /* Expand code for the insv template. Return true if successful, false else. */
3986 s390_expand_insv (rtx dest
, rtx op1
, rtx op2
, rtx src
)
3988 int bitsize
= INTVAL (op1
);
3989 int bitpos
= INTVAL (op2
);
3991 /* We need byte alignment. */
3992 if (bitsize
% BITS_PER_UNIT
)
3996 && memory_operand (dest
, VOIDmode
)
3997 && (register_operand (src
, word_mode
)
3998 || const_int_operand (src
, VOIDmode
)))
4000 /* Emit standard pattern if possible. */
4001 enum machine_mode mode
= smallest_mode_for_size (bitsize
, MODE_INT
);
4002 if (GET_MODE_BITSIZE (mode
) == bitsize
)
4003 emit_move_insn (adjust_address (dest
, mode
, 0), gen_lowpart (mode
, src
));
4005 /* (set (ze (mem)) (const_int)). */
4006 else if (const_int_operand (src
, VOIDmode
))
4008 int size
= bitsize
/ BITS_PER_UNIT
;
4009 rtx src_mem
= adjust_address (force_const_mem (word_mode
, src
), BLKmode
,
4010 GET_MODE_SIZE (word_mode
) - size
);
4012 dest
= adjust_address (dest
, BLKmode
, 0);
4013 set_mem_size (dest
, GEN_INT (size
));
4014 s390_expand_movmem (dest
, src_mem
, GEN_INT (size
));
4017 /* (set (ze (mem)) (reg)). */
4018 else if (register_operand (src
, word_mode
))
4020 if (bitsize
<= GET_MODE_BITSIZE (SImode
))
4021 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode
, dest
, op1
,
4025 /* Emit st,stcmh sequence. */
4026 int stcmh_width
= bitsize
- GET_MODE_BITSIZE (SImode
);
4027 int size
= stcmh_width
/ BITS_PER_UNIT
;
4029 emit_move_insn (adjust_address (dest
, SImode
, size
),
4030 gen_lowpart (SImode
, src
));
4031 set_mem_size (dest
, GEN_INT (size
));
4032 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode
, dest
, GEN_INT
4033 (stcmh_width
), const0_rtx
),
4034 gen_rtx_LSHIFTRT (word_mode
, src
, GEN_INT
4035 (GET_MODE_BITSIZE (SImode
))));
4044 /* (set (ze (reg)) (const_int)). */
4046 && register_operand (dest
, word_mode
)
4047 && (bitpos
% 16) == 0
4048 && (bitsize
% 16) == 0
4049 && const_int_operand (src
, VOIDmode
))
4051 HOST_WIDE_INT val
= INTVAL (src
);
4052 int regpos
= bitpos
+ bitsize
;
4054 while (regpos
> bitpos
)
4056 enum machine_mode putmode
;
4059 if (TARGET_EXTIMM
&& (regpos
% 32 == 0) && (regpos
>= bitpos
+ 32))
4064 putsize
= GET_MODE_BITSIZE (putmode
);
4066 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode
, dest
,
4069 gen_int_mode (val
, putmode
));
4072 gcc_assert (regpos
== bitpos
);
4079 /* A subroutine of s390_expand_cs_hqi and s390_expand_atomic which returns a
4080 register that holds VAL of mode MODE shifted by COUNT bits. */
4083 s390_expand_mask_and_shift (rtx val
, enum machine_mode mode
, rtx count
)
4085 val
= expand_simple_binop (SImode
, AND
, val
, GEN_INT (GET_MODE_MASK (mode
)),
4086 NULL_RTX
, 1, OPTAB_DIRECT
);
4087 return expand_simple_binop (SImode
, ASHIFT
, val
, count
,
4088 NULL_RTX
, 1, OPTAB_DIRECT
);
4091 /* Structure to hold the initial parameters for a compare_and_swap operation
4092 in HImode and QImode. */
4094 struct alignment_context
4096 rtx memsi
; /* SI aligned memory location. */
4097 rtx shift
; /* Bit offset with regard to lsb. */
4098 rtx modemask
; /* Mask of the HQImode shifted by SHIFT bits. */
4099 rtx modemaski
; /* ~modemask */
4100 bool aligned
; /* True if memory is aligned, false else. */
4103 /* A subroutine of s390_expand_cs_hqi and s390_expand_atomic to initialize
4104 structure AC for transparent simplifying, if the memory alignment is known
4105 to be at least 32bit. MEM is the memory location for the actual operation
4106 and MODE its mode. */
4109 init_alignment_context (struct alignment_context
*ac
, rtx mem
,
4110 enum machine_mode mode
)
4112 ac
->shift
= GEN_INT (GET_MODE_SIZE (SImode
) - GET_MODE_SIZE (mode
));
4113 ac
->aligned
= (MEM_ALIGN (mem
) >= GET_MODE_BITSIZE (SImode
));
4116 ac
->memsi
= adjust_address (mem
, SImode
, 0); /* Memory is aligned. */
4119 /* Alignment is unknown. */
4120 rtx byteoffset
, addr
, align
;
4122 /* Force the address into a register. */
4123 addr
= force_reg (Pmode
, XEXP (mem
, 0));
4125 /* Align it to SImode. */
4126 align
= expand_simple_binop (Pmode
, AND
, addr
,
4127 GEN_INT (-GET_MODE_SIZE (SImode
)),
4128 NULL_RTX
, 1, OPTAB_DIRECT
);
4130 ac
->memsi
= gen_rtx_MEM (SImode
, align
);
4131 MEM_VOLATILE_P (ac
->memsi
) = MEM_VOLATILE_P (mem
);
4132 set_mem_alias_set (ac
->memsi
, ALIAS_SET_MEMORY_BARRIER
);
4133 set_mem_align (ac
->memsi
, GET_MODE_BITSIZE (SImode
));
4135 /* Calculate shiftcount. */
4136 byteoffset
= expand_simple_binop (Pmode
, AND
, addr
,
4137 GEN_INT (GET_MODE_SIZE (SImode
) - 1),
4138 NULL_RTX
, 1, OPTAB_DIRECT
);
4139 /* As we already have some offset, evaluate the remaining distance. */
4140 ac
->shift
= expand_simple_binop (SImode
, MINUS
, ac
->shift
, byteoffset
,
4141 NULL_RTX
, 1, OPTAB_DIRECT
);
4144 /* Shift is the byte count, but we need the bitcount. */
4145 ac
->shift
= expand_simple_binop (SImode
, MULT
, ac
->shift
, GEN_INT (BITS_PER_UNIT
),
4146 NULL_RTX
, 1, OPTAB_DIRECT
);
4147 /* Calculate masks. */
4148 ac
->modemask
= expand_simple_binop (SImode
, ASHIFT
,
4149 GEN_INT (GET_MODE_MASK (mode
)), ac
->shift
,
4150 NULL_RTX
, 1, OPTAB_DIRECT
);
4151 ac
->modemaski
= expand_simple_unop (SImode
, NOT
, ac
->modemask
, NULL_RTX
, 1);
4154 /* Expand an atomic compare and swap operation for HImode and QImode. MEM is
4155 the memory location, CMP the old value to compare MEM with and NEW the value
4156 to set if CMP == MEM.
4157 CMP is never in memory for compare_and_swap_cc because
4158 expand_bool_compare_and_swap puts it into a register for later compare. */
4161 s390_expand_cs_hqi (enum machine_mode mode
, rtx target
, rtx mem
, rtx cmp
, rtx
new)
4163 struct alignment_context ac
;
4164 rtx cmpv
, newv
, val
, resv
, cc
;
4165 rtx res
= gen_reg_rtx (SImode
);
4166 rtx csloop
= gen_label_rtx ();
4167 rtx csend
= gen_label_rtx ();
4169 gcc_assert (register_operand (target
, VOIDmode
));
4170 gcc_assert (MEM_P (mem
));
4172 init_alignment_context (&ac
, mem
, mode
);
4174 /* Shift the values to the correct bit positions. */
4175 if (!(ac
.aligned
&& MEM_P (cmp
)))
4176 cmp
= s390_expand_mask_and_shift (cmp
, mode
, ac
.shift
);
4177 if (!(ac
.aligned
&& MEM_P (new)))
4178 new = s390_expand_mask_and_shift (new, mode
, ac
.shift
);
4180 /* Load full word. Subsequent loads are performed by CS. */
4181 val
= expand_simple_binop (SImode
, AND
, ac
.memsi
, ac
.modemaski
,
4182 NULL_RTX
, 1, OPTAB_DIRECT
);
4184 /* Start CS loop. */
4185 emit_label (csloop
);
4186 /* val = "<mem>00..0<mem>"
4187 * cmp = "00..0<cmp>00..0"
4188 * new = "00..0<new>00..0"
4191 /* Patch cmp and new with val at correct position. */
4192 if (ac
.aligned
&& MEM_P (cmp
))
4194 cmpv
= force_reg (SImode
, val
);
4195 store_bit_field (cmpv
, GET_MODE_BITSIZE (mode
), 0, SImode
, cmp
);
4198 cmpv
= force_reg (SImode
, expand_simple_binop (SImode
, IOR
, cmp
, val
,
4199 NULL_RTX
, 1, OPTAB_DIRECT
));
4200 if (ac
.aligned
&& MEM_P (new))
4202 newv
= force_reg (SImode
, val
);
4203 store_bit_field (newv
, GET_MODE_BITSIZE (mode
), 0, SImode
, new);
4206 newv
= force_reg (SImode
, expand_simple_binop (SImode
, IOR
, new, val
,
4207 NULL_RTX
, 1, OPTAB_DIRECT
));
4209 /* Jump to end if we're done (likely?). */
4210 s390_emit_jump (csend
, s390_emit_compare_and_swap (EQ
, res
, ac
.memsi
,
4213 /* Check for changes outside mode. */
4214 resv
= expand_simple_binop (SImode
, AND
, res
, ac
.modemaski
,
4215 NULL_RTX
, 1, OPTAB_DIRECT
);
4216 cc
= s390_emit_compare (NE
, resv
, val
);
4217 emit_move_insn (val
, resv
);
4218 /* Loop internal if so. */
4219 s390_emit_jump (csloop
, cc
);
4223 /* Return the correct part of the bitfield. */
4224 convert_move (target
, expand_simple_binop (SImode
, LSHIFTRT
, res
, ac
.shift
,
4225 NULL_RTX
, 1, OPTAB_DIRECT
), 1);
4228 /* Expand an atomic operation CODE of mode MODE. MEM is the memory location
4229 and VAL the value to play with. If AFTER is true then store the value
4230 MEM holds after the operation, if AFTER is false then store the value MEM
4231 holds before the operation. If TARGET is zero then discard that value, else
4232 store it to TARGET. */
4235 s390_expand_atomic (enum machine_mode mode
, enum rtx_code code
,
4236 rtx target
, rtx mem
, rtx val
, bool after
)
4238 struct alignment_context ac
;
4240 rtx
new = gen_reg_rtx (SImode
);
4241 rtx orig
= gen_reg_rtx (SImode
);
4242 rtx csloop
= gen_label_rtx ();
4244 gcc_assert (!target
|| register_operand (target
, VOIDmode
));
4245 gcc_assert (MEM_P (mem
));
4247 init_alignment_context (&ac
, mem
, mode
);
4249 /* Shift val to the correct bit positions.
4250 Preserve "icm", but prevent "ex icm". */
4251 if (!(ac
.aligned
&& code
== SET
&& MEM_P (val
)))
4252 val
= s390_expand_mask_and_shift (val
, mode
, ac
.shift
);
4254 /* Further preparation insns. */
4255 if (code
== PLUS
|| code
== MINUS
)
4256 emit_move_insn (orig
, val
);
4257 else if (code
== MULT
|| code
== AND
) /* val = "11..1<val>11..1" */
4258 val
= expand_simple_binop (SImode
, XOR
, val
, ac
.modemaski
,
4259 NULL_RTX
, 1, OPTAB_DIRECT
);
4261 /* Load full word. Subsequent loads are performed by CS. */
4262 cmp
= force_reg (SImode
, ac
.memsi
);
4264 /* Start CS loop. */
4265 emit_label (csloop
);
4266 emit_move_insn (new, cmp
);
4268 /* Patch new with val at correct position. */
4273 val
= expand_simple_binop (SImode
, code
, new, orig
,
4274 NULL_RTX
, 1, OPTAB_DIRECT
);
4275 val
= expand_simple_binop (SImode
, AND
, val
, ac
.modemask
,
4276 NULL_RTX
, 1, OPTAB_DIRECT
);
4279 if (ac
.aligned
&& MEM_P (val
))
4280 store_bit_field (new, GET_MODE_BITSIZE (mode
), 0, SImode
, val
);
4283 new = expand_simple_binop (SImode
, AND
, new, ac
.modemaski
,
4284 NULL_RTX
, 1, OPTAB_DIRECT
);
4285 new = expand_simple_binop (SImode
, IOR
, new, val
,
4286 NULL_RTX
, 1, OPTAB_DIRECT
);
4292 new = expand_simple_binop (SImode
, code
, new, val
,
4293 NULL_RTX
, 1, OPTAB_DIRECT
);
4295 case MULT
: /* NAND */
4296 new = expand_simple_binop (SImode
, XOR
, new, ac
.modemask
,
4297 NULL_RTX
, 1, OPTAB_DIRECT
);
4298 new = expand_simple_binop (SImode
, AND
, new, val
,
4299 NULL_RTX
, 1, OPTAB_DIRECT
);
4305 s390_emit_jump (csloop
, s390_emit_compare_and_swap (NE
, cmp
,
4306 ac
.memsi
, cmp
, new));
4308 /* Return the correct part of the bitfield. */
4310 convert_move (target
, expand_simple_binop (SImode
, LSHIFTRT
,
4311 after
? new : cmp
, ac
.shift
,
4312 NULL_RTX
, 1, OPTAB_DIRECT
), 1);
4315 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
4316 We need to emit DTP-relative relocations. */
4318 static void s390_output_dwarf_dtprel (FILE *, int, rtx
) ATTRIBUTE_UNUSED
;
4321 s390_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
4326 fputs ("\t.long\t", file
);
4329 fputs ("\t.quad\t", file
);
4334 output_addr_const (file
, x
);
4335 fputs ("@DTPOFF", file
);
4338 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
4339 /* Implement TARGET_MANGLE_FUNDAMENTAL_TYPE. */
4342 s390_mangle_fundamental_type (tree type
)
4344 if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
4345 && TARGET_LONG_DOUBLE_128
)
4348 /* For all other types, use normal C++ mangling. */
4353 /* In the name of slightly smaller debug output, and to cater to
4354 general assembler lossage, recognize various UNSPEC sequences
4355 and turn them back into a direct symbol reference. */
4358 s390_delegitimize_address (rtx orig_x
)
4362 if (GET_CODE (x
) != MEM
)
4366 if (GET_CODE (x
) == PLUS
4367 && GET_CODE (XEXP (x
, 1)) == CONST
4368 && GET_CODE (XEXP (x
, 0)) == REG
4369 && REGNO (XEXP (x
, 0)) == PIC_OFFSET_TABLE_REGNUM
)
4371 y
= XEXP (XEXP (x
, 1), 0);
4372 if (GET_CODE (y
) == UNSPEC
4373 && XINT (y
, 1) == UNSPEC_GOT
)
4374 return XVECEXP (y
, 0, 0);
4378 if (GET_CODE (x
) == CONST
)
4381 if (GET_CODE (y
) == UNSPEC
4382 && XINT (y
, 1) == UNSPEC_GOTENT
)
4383 return XVECEXP (y
, 0, 0);
4390 /* Output operand OP to stdio stream FILE.
4391 OP is an address (register + offset) which is not used to address data;
4392 instead the rightmost bits are interpreted as the value. */
4395 print_shift_count_operand (FILE *file
, rtx op
)
4397 HOST_WIDE_INT offset
;
4400 /* Extract base register and offset. */
4401 if (!s390_decompose_shift_count (op
, &base
, &offset
))
4407 gcc_assert (GET_CODE (base
) == REG
);
4408 gcc_assert (REGNO (base
) < FIRST_PSEUDO_REGISTER
);
4409 gcc_assert (REGNO_REG_CLASS (REGNO (base
)) == ADDR_REGS
);
4412 /* Offsets are constricted to twelve bits. */
4413 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
& ((1 << 12) - 1));
4415 fprintf (file
, "(%s)", reg_names
[REGNO (base
)]);
4418 /* See 'get_some_local_dynamic_name'. */
4421 get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
4425 if (GET_CODE (x
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (x
))
4427 x
= get_pool_constant (x
);
4428 return for_each_rtx (&x
, get_some_local_dynamic_name_1
, 0);
4431 if (GET_CODE (x
) == SYMBOL_REF
4432 && tls_symbolic_operand (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
4434 cfun
->machine
->some_ld_name
= XSTR (x
, 0);
4441 /* Locate some local-dynamic symbol still in use by this function
4442 so that we can print its name in local-dynamic base patterns. */
4445 get_some_local_dynamic_name (void)
4449 if (cfun
->machine
->some_ld_name
)
4450 return cfun
->machine
->some_ld_name
;
4452 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
4454 && for_each_rtx (&PATTERN (insn
), get_some_local_dynamic_name_1
, 0))
4455 return cfun
->machine
->some_ld_name
;
4460 /* Output machine-dependent UNSPECs occurring in address constant X
4461 in assembler syntax to stdio stream FILE. Returns true if the
4462 constant X could be recognized, false otherwise. */
4465 s390_output_addr_const_extra (FILE *file
, rtx x
)
4467 if (GET_CODE (x
) == UNSPEC
&& XVECLEN (x
, 0) == 1)
4468 switch (XINT (x
, 1))
4471 output_addr_const (file
, XVECEXP (x
, 0, 0));
4472 fprintf (file
, "@GOTENT");
4475 output_addr_const (file
, XVECEXP (x
, 0, 0));
4476 fprintf (file
, "@GOT");
4479 output_addr_const (file
, XVECEXP (x
, 0, 0));
4480 fprintf (file
, "@GOTOFF");
4483 output_addr_const (file
, XVECEXP (x
, 0, 0));
4484 fprintf (file
, "@PLT");
4487 output_addr_const (file
, XVECEXP (x
, 0, 0));
4488 fprintf (file
, "@PLTOFF");
4491 output_addr_const (file
, XVECEXP (x
, 0, 0));
4492 fprintf (file
, "@TLSGD");
4495 assemble_name (file
, get_some_local_dynamic_name ());
4496 fprintf (file
, "@TLSLDM");
4499 output_addr_const (file
, XVECEXP (x
, 0, 0));
4500 fprintf (file
, "@DTPOFF");
4503 output_addr_const (file
, XVECEXP (x
, 0, 0));
4504 fprintf (file
, "@NTPOFF");
4506 case UNSPEC_GOTNTPOFF
:
4507 output_addr_const (file
, XVECEXP (x
, 0, 0));
4508 fprintf (file
, "@GOTNTPOFF");
4510 case UNSPEC_INDNTPOFF
:
4511 output_addr_const (file
, XVECEXP (x
, 0, 0));
4512 fprintf (file
, "@INDNTPOFF");
4519 /* Output address operand ADDR in assembler syntax to
4520 stdio stream FILE. */
4523 print_operand_address (FILE *file
, rtx addr
)
4525 struct s390_address ad
;
4527 if (!s390_decompose_address (addr
, &ad
)
4528 || (ad
.base
&& !REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)))
4529 || (ad
.indx
&& !REGNO_OK_FOR_INDEX_P (REGNO (ad
.indx
))))
4530 output_operand_lossage ("cannot decompose address");
4533 output_addr_const (file
, ad
.disp
);
4535 fprintf (file
, "0");
4537 if (ad
.base
&& ad
.indx
)
4538 fprintf (file
, "(%s,%s)", reg_names
[REGNO (ad
.indx
)],
4539 reg_names
[REGNO (ad
.base
)]);
4541 fprintf (file
, "(%s)", reg_names
[REGNO (ad
.base
)]);
4544 /* Output operand X in assembler syntax to stdio stream FILE.
4545 CODE specified the format flag. The following format flags
4548 'C': print opcode suffix for branch condition.
4549 'D': print opcode suffix for inverse branch condition.
4550 'J': print tls_load/tls_gdcall/tls_ldcall suffix
4551 'G': print the size of the operand in bytes.
4552 'O': print only the displacement of a memory reference.
4553 'R': print only the base register of a memory reference.
4554 'S': print S-type memory reference (base+displacement).
4555 'N': print the second word of a DImode operand.
4556 'M': print the second word of a TImode operand.
4557 'Y': print shift count operand.
4559 'b': print integer X as if it's an unsigned byte.
4560 'x': print integer X as if it's an unsigned halfword.
4561 'h': print integer X as if it's a signed halfword.
4562 'i': print the first nonzero HImode part of X.
4563 'j': print the first HImode part unequal to -1 of X.
4564 'k': print the first nonzero SImode part of X.
4565 'm': print the first SImode part unequal to -1 of X.
4566 'o': print integer X as if it's an unsigned 32bit word. */
4569 print_operand (FILE *file
, rtx x
, int code
)
4574 fprintf (file
, s390_branch_condition_mnemonic (x
, FALSE
));
4578 fprintf (file
, s390_branch_condition_mnemonic (x
, TRUE
));
4582 if (GET_CODE (x
) == SYMBOL_REF
)
4584 fprintf (file
, "%s", ":tls_load:");
4585 output_addr_const (file
, x
);
4587 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSGD
)
4589 fprintf (file
, "%s", ":tls_gdcall:");
4590 output_addr_const (file
, XVECEXP (x
, 0, 0));
4592 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSLDM
)
4594 fprintf (file
, "%s", ":tls_ldcall:");
4595 assemble_name (file
, get_some_local_dynamic_name ());
4602 fprintf (file
, "%u", GET_MODE_SIZE (GET_MODE (x
)));
4607 struct s390_address ad
;
4610 gcc_assert (GET_CODE (x
) == MEM
);
4611 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
4613 gcc_assert (!ad
.base
|| REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)));
4614 gcc_assert (!ad
.indx
);
4617 output_addr_const (file
, ad
.disp
);
4619 fprintf (file
, "0");
4625 struct s390_address ad
;
4628 gcc_assert (GET_CODE (x
) == MEM
);
4629 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
4631 gcc_assert (!ad
.base
|| REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)));
4632 gcc_assert (!ad
.indx
);
4635 fprintf (file
, "%s", reg_names
[REGNO (ad
.base
)]);
4637 fprintf (file
, "0");
4643 struct s390_address ad
;
4646 gcc_assert (GET_CODE (x
) == MEM
);
4647 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
4649 gcc_assert (!ad
.base
|| REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)));
4650 gcc_assert (!ad
.indx
);
4653 output_addr_const (file
, ad
.disp
);
4655 fprintf (file
, "0");
4658 fprintf (file
, "(%s)", reg_names
[REGNO (ad
.base
)]);
4663 if (GET_CODE (x
) == REG
)
4664 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
4665 else if (GET_CODE (x
) == MEM
)
4666 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 4));
4672 if (GET_CODE (x
) == REG
)
4673 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
4674 else if (GET_CODE (x
) == MEM
)
4675 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 8));
4681 print_shift_count_operand (file
, x
);
4685 switch (GET_CODE (x
))
4688 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
4692 output_address (XEXP (x
, 0));
4699 output_addr_const (file
, x
);
4704 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xff);
4705 else if (code
== 'x')
4706 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xffff);
4707 else if (code
== 'h')
4708 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((INTVAL (x
) & 0xffff) ^ 0x8000) - 0x8000);
4709 else if (code
== 'i')
4710 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
4711 s390_extract_part (x
, HImode
, 0));
4712 else if (code
== 'j')
4713 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
4714 s390_extract_part (x
, HImode
, -1));
4715 else if (code
== 'k')
4716 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
4717 s390_extract_part (x
, SImode
, 0));
4718 else if (code
== 'm')
4719 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
4720 s390_extract_part (x
, SImode
, -1));
4721 else if (code
== 'o')
4722 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xffffffff);
4724 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
4728 gcc_assert (GET_MODE (x
) == VOIDmode
);
4730 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xff);
4731 else if (code
== 'x')
4732 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xffff);
4733 else if (code
== 'h')
4734 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((CONST_DOUBLE_LOW (x
) & 0xffff) ^ 0x8000) - 0x8000);
4740 fatal_insn ("UNKNOWN in print_operand !?", x
);
4745 /* Target hook for assembling integer objects. We need to define it
4746 here to work a round a bug in some versions of GAS, which couldn't
4747 handle values smaller than INT_MIN when printed in decimal. */
4750 s390_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
4752 if (size
== 8 && aligned_p
4753 && GET_CODE (x
) == CONST_INT
&& INTVAL (x
) < INT_MIN
)
4755 fprintf (asm_out_file
, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX
"\n",
4759 return default_assemble_integer (x
, size
, aligned_p
);
4762 /* Returns true if register REGNO is used for forming
4763 a memory address in expression X. */
4766 reg_used_in_mem_p (int regno
, rtx x
)
4768 enum rtx_code code
= GET_CODE (x
);
4774 if (refers_to_regno_p (regno
, regno
+1,
4778 else if (code
== SET
4779 && GET_CODE (SET_DEST (x
)) == PC
)
4781 if (refers_to_regno_p (regno
, regno
+1,
4786 fmt
= GET_RTX_FORMAT (code
);
4787 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
4790 && reg_used_in_mem_p (regno
, XEXP (x
, i
)))
4793 else if (fmt
[i
] == 'E')
4794 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
4795 if (reg_used_in_mem_p (regno
, XVECEXP (x
, i
, j
)))
4801 /* Returns true if expression DEP_RTX sets an address register
4802 used by instruction INSN to address memory. */
4805 addr_generation_dependency_p (rtx dep_rtx
, rtx insn
)
4809 if (GET_CODE (dep_rtx
) == INSN
)
4810 dep_rtx
= PATTERN (dep_rtx
);
4812 if (GET_CODE (dep_rtx
) == SET
)
4814 target
= SET_DEST (dep_rtx
);
4815 if (GET_CODE (target
) == STRICT_LOW_PART
)
4816 target
= XEXP (target
, 0);
4817 while (GET_CODE (target
) == SUBREG
)
4818 target
= SUBREG_REG (target
);
4820 if (GET_CODE (target
) == REG
)
4822 int regno
= REGNO (target
);
4824 if (s390_safe_attr_type (insn
) == TYPE_LA
)
4826 pat
= PATTERN (insn
);
4827 if (GET_CODE (pat
) == PARALLEL
)
4829 gcc_assert (XVECLEN (pat
, 0) == 2);
4830 pat
= XVECEXP (pat
, 0, 0);
4832 gcc_assert (GET_CODE (pat
) == SET
);
4833 return refers_to_regno_p (regno
, regno
+1, SET_SRC (pat
), 0);
4835 else if (get_attr_atype (insn
) == ATYPE_AGEN
)
4836 return reg_used_in_mem_p (regno
, PATTERN (insn
));
4842 /* Return 1, if dep_insn sets register used in insn in the agen unit. */
4845 s390_agen_dep_p (rtx dep_insn
, rtx insn
)
4847 rtx dep_rtx
= PATTERN (dep_insn
);
4850 if (GET_CODE (dep_rtx
) == SET
4851 && addr_generation_dependency_p (dep_rtx
, insn
))
4853 else if (GET_CODE (dep_rtx
) == PARALLEL
)
4855 for (i
= 0; i
< XVECLEN (dep_rtx
, 0); i
++)
4857 if (addr_generation_dependency_p (XVECEXP (dep_rtx
, 0, i
), insn
))
4864 /* A C statement (sans semicolon) to update the integer scheduling priority
4865 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
4866 reduce the priority to execute INSN later. Do not define this macro if
4867 you do not need to adjust the scheduling priorities of insns.
4869 A STD instruction should be scheduled earlier,
4870 in order to use the bypass. */
4873 s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
4875 if (! INSN_P (insn
))
4878 if (s390_tune
!= PROCESSOR_2084_Z990
4879 && s390_tune
!= PROCESSOR_2094_Z9_109
)
4882 switch (s390_safe_attr_type (insn
))
4886 priority
= priority
<< 3;
4890 priority
= priority
<< 1;
4898 /* The number of instructions that can be issued per cycle. */
4901 s390_issue_rate (void)
4903 if (s390_tune
== PROCESSOR_2084_Z990
4904 || s390_tune
== PROCESSOR_2094_Z9_109
)
4910 s390_first_cycle_multipass_dfa_lookahead (void)
4916 /* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
4917 Fix up MEMs as required. */
4920 annotate_constant_pool_refs (rtx
*x
)
4925 gcc_assert (GET_CODE (*x
) != SYMBOL_REF
4926 || !CONSTANT_POOL_ADDRESS_P (*x
));
4928 /* Literal pool references can only occur inside a MEM ... */
4929 if (GET_CODE (*x
) == MEM
)
4931 rtx memref
= XEXP (*x
, 0);
4933 if (GET_CODE (memref
) == SYMBOL_REF
4934 && CONSTANT_POOL_ADDRESS_P (memref
))
4936 rtx base
= cfun
->machine
->base_reg
;
4937 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, memref
, base
),
4940 *x
= replace_equiv_address (*x
, addr
);
4944 if (GET_CODE (memref
) == CONST
4945 && GET_CODE (XEXP (memref
, 0)) == PLUS
4946 && GET_CODE (XEXP (XEXP (memref
, 0), 1)) == CONST_INT
4947 && GET_CODE (XEXP (XEXP (memref
, 0), 0)) == SYMBOL_REF
4948 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (memref
, 0), 0)))
4950 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (memref
, 0), 1));
4951 rtx sym
= XEXP (XEXP (memref
, 0), 0);
4952 rtx base
= cfun
->machine
->base_reg
;
4953 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
4956 *x
= replace_equiv_address (*x
, plus_constant (addr
, off
));
4961 /* ... or a load-address type pattern. */
4962 if (GET_CODE (*x
) == SET
)
4964 rtx addrref
= SET_SRC (*x
);
4966 if (GET_CODE (addrref
) == SYMBOL_REF
4967 && CONSTANT_POOL_ADDRESS_P (addrref
))
4969 rtx base
= cfun
->machine
->base_reg
;
4970 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, addrref
, base
),
4973 SET_SRC (*x
) = addr
;
4977 if (GET_CODE (addrref
) == CONST
4978 && GET_CODE (XEXP (addrref
, 0)) == PLUS
4979 && GET_CODE (XEXP (XEXP (addrref
, 0), 1)) == CONST_INT
4980 && GET_CODE (XEXP (XEXP (addrref
, 0), 0)) == SYMBOL_REF
4981 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (addrref
, 0), 0)))
4983 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (addrref
, 0), 1));
4984 rtx sym
= XEXP (XEXP (addrref
, 0), 0);
4985 rtx base
= cfun
->machine
->base_reg
;
4986 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
4989 SET_SRC (*x
) = plus_constant (addr
, off
);
4994 /* Annotate LTREL_BASE as well. */
4995 if (GET_CODE (*x
) == UNSPEC
4996 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
4998 rtx base
= cfun
->machine
->base_reg
;
4999 *x
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XVECEXP (*x
, 0, 0), base
),
5004 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
5005 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
5009 annotate_constant_pool_refs (&XEXP (*x
, i
));
5011 else if (fmt
[i
] == 'E')
5013 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
5014 annotate_constant_pool_refs (&XVECEXP (*x
, i
, j
));
5019 /* Split all branches that exceed the maximum distance.
5020 Returns true if this created a new literal pool entry. */
5023 s390_split_branches (void)
5025 rtx temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
5026 int new_literal
= 0, ret
;
5027 rtx insn
, pat
, tmp
, target
;
5030 /* We need correct insn addresses. */
5032 shorten_branches (get_insns ());
5034 /* Find all branches that exceed 64KB, and split them. */
5036 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5038 if (GET_CODE (insn
) != JUMP_INSN
)
5041 pat
= PATTERN (insn
);
5042 if (GET_CODE (pat
) == PARALLEL
&& XVECLEN (pat
, 0) > 2)
5043 pat
= XVECEXP (pat
, 0, 0);
5044 if (GET_CODE (pat
) != SET
|| SET_DEST (pat
) != pc_rtx
)
5047 if (GET_CODE (SET_SRC (pat
)) == LABEL_REF
)
5049 label
= &SET_SRC (pat
);
5051 else if (GET_CODE (SET_SRC (pat
)) == IF_THEN_ELSE
)
5053 if (GET_CODE (XEXP (SET_SRC (pat
), 1)) == LABEL_REF
)
5054 label
= &XEXP (SET_SRC (pat
), 1);
5055 else if (GET_CODE (XEXP (SET_SRC (pat
), 2)) == LABEL_REF
)
5056 label
= &XEXP (SET_SRC (pat
), 2);
5063 if (get_attr_length (insn
) <= 4)
5066 /* We are going to use the return register as scratch register,
5067 make sure it will be saved/restored by the prologue/epilogue. */
5068 cfun_frame_layout
.save_return_addr_p
= 1;
5073 tmp
= force_const_mem (Pmode
, *label
);
5074 tmp
= emit_insn_before (gen_rtx_SET (Pmode
, temp_reg
, tmp
), insn
);
5075 INSN_ADDRESSES_NEW (tmp
, -1);
5076 annotate_constant_pool_refs (&PATTERN (tmp
));
5083 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, *label
),
5084 UNSPEC_LTREL_OFFSET
);
5085 target
= gen_rtx_CONST (Pmode
, target
);
5086 target
= force_const_mem (Pmode
, target
);
5087 tmp
= emit_insn_before (gen_rtx_SET (Pmode
, temp_reg
, target
), insn
);
5088 INSN_ADDRESSES_NEW (tmp
, -1);
5089 annotate_constant_pool_refs (&PATTERN (tmp
));
5091 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XEXP (target
, 0),
5092 cfun
->machine
->base_reg
),
5094 target
= gen_rtx_PLUS (Pmode
, temp_reg
, target
);
5097 ret
= validate_change (insn
, label
, target
, 0);
5105 /* Find an annotated literal pool symbol referenced in RTX X,
5106 and store it at REF. Will abort if X contains references to
5107 more than one such pool symbol; multiple references to the same
5108 symbol are allowed, however.
5110 The rtx pointed to by REF must be initialized to NULL_RTX
5111 by the caller before calling this routine. */
5114 find_constant_pool_ref (rtx x
, rtx
*ref
)
5119 /* Ignore LTREL_BASE references. */
5120 if (GET_CODE (x
) == UNSPEC
5121 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
5123 /* Likewise POOL_ENTRY insns. */
5124 if (GET_CODE (x
) == UNSPEC_VOLATILE
5125 && XINT (x
, 1) == UNSPECV_POOL_ENTRY
)
5128 gcc_assert (GET_CODE (x
) != SYMBOL_REF
5129 || !CONSTANT_POOL_ADDRESS_P (x
));
5131 if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_LTREF
)
5133 rtx sym
= XVECEXP (x
, 0, 0);
5134 gcc_assert (GET_CODE (sym
) == SYMBOL_REF
5135 && CONSTANT_POOL_ADDRESS_P (sym
));
5137 if (*ref
== NULL_RTX
)
5140 gcc_assert (*ref
== sym
);
5145 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
5146 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
5150 find_constant_pool_ref (XEXP (x
, i
), ref
);
5152 else if (fmt
[i
] == 'E')
5154 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
5155 find_constant_pool_ref (XVECEXP (x
, i
, j
), ref
);
5160 /* Replace every reference to the annotated literal pool
5161 symbol REF in X by its base plus OFFSET. */
5164 replace_constant_pool_ref (rtx
*x
, rtx ref
, rtx offset
)
5169 gcc_assert (*x
!= ref
);
5171 if (GET_CODE (*x
) == UNSPEC
5172 && XINT (*x
, 1) == UNSPEC_LTREF
5173 && XVECEXP (*x
, 0, 0) == ref
)
5175 *x
= gen_rtx_PLUS (Pmode
, XVECEXP (*x
, 0, 1), offset
);
5179 if (GET_CODE (*x
) == PLUS
5180 && GET_CODE (XEXP (*x
, 1)) == CONST_INT
5181 && GET_CODE (XEXP (*x
, 0)) == UNSPEC
5182 && XINT (XEXP (*x
, 0), 1) == UNSPEC_LTREF
5183 && XVECEXP (XEXP (*x
, 0), 0, 0) == ref
)
5185 rtx addr
= gen_rtx_PLUS (Pmode
, XVECEXP (XEXP (*x
, 0), 0, 1), offset
);
5186 *x
= plus_constant (addr
, INTVAL (XEXP (*x
, 1)));
5190 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
5191 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
5195 replace_constant_pool_ref (&XEXP (*x
, i
), ref
, offset
);
5197 else if (fmt
[i
] == 'E')
5199 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
5200 replace_constant_pool_ref (&XVECEXP (*x
, i
, j
), ref
, offset
);
5205 /* Check whether X contains an UNSPEC_LTREL_BASE.
5206 Return its constant pool symbol if found, NULL_RTX otherwise. */
5209 find_ltrel_base (rtx x
)
5214 if (GET_CODE (x
) == UNSPEC
5215 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
5216 return XVECEXP (x
, 0, 0);
5218 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
5219 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
5223 rtx fnd
= find_ltrel_base (XEXP (x
, i
));
5227 else if (fmt
[i
] == 'E')
5229 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
5231 rtx fnd
= find_ltrel_base (XVECEXP (x
, i
, j
));
5241 /* Replace any occurrence of UNSPEC_LTREL_BASE in X with its base. */
5244 replace_ltrel_base (rtx
*x
)
5249 if (GET_CODE (*x
) == UNSPEC
5250 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
5252 *x
= XVECEXP (*x
, 0, 1);
5256 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
5257 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
5261 replace_ltrel_base (&XEXP (*x
, i
));
5263 else if (fmt
[i
] == 'E')
5265 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
5266 replace_ltrel_base (&XVECEXP (*x
, i
, j
));
5272 /* We keep a list of constants which we have to add to internal
5273 constant tables in the middle of large functions. */
5275 #define NR_C_MODES 11
5276 enum machine_mode constant_modes
[NR_C_MODES
] =
5278 TFmode
, TImode
, TDmode
,
5279 DFmode
, DImode
, DDmode
,
5280 SFmode
, SImode
, SDmode
,
5287 struct constant
*next
;
5292 struct constant_pool
5294 struct constant_pool
*next
;
5299 struct constant
*constants
[NR_C_MODES
];
5300 struct constant
*execute
;
5305 /* Allocate new constant_pool structure. */
5307 static struct constant_pool
*
5308 s390_alloc_pool (void)
5310 struct constant_pool
*pool
;
5313 pool
= (struct constant_pool
*) xmalloc (sizeof *pool
);
5315 for (i
= 0; i
< NR_C_MODES
; i
++)
5316 pool
->constants
[i
] = NULL
;
5318 pool
->execute
= NULL
;
5319 pool
->label
= gen_label_rtx ();
5320 pool
->first_insn
= NULL_RTX
;
5321 pool
->pool_insn
= NULL_RTX
;
5322 pool
->insns
= BITMAP_ALLOC (NULL
);
5328 /* Create new constant pool covering instructions starting at INSN
5329 and chain it to the end of POOL_LIST. */
5331 static struct constant_pool
*
5332 s390_start_pool (struct constant_pool
**pool_list
, rtx insn
)
5334 struct constant_pool
*pool
, **prev
;
5336 pool
= s390_alloc_pool ();
5337 pool
->first_insn
= insn
;
5339 for (prev
= pool_list
; *prev
; prev
= &(*prev
)->next
)
5346 /* End range of instructions covered by POOL at INSN and emit
5347 placeholder insn representing the pool. */
5350 s390_end_pool (struct constant_pool
*pool
, rtx insn
)
5352 rtx pool_size
= GEN_INT (pool
->size
+ 8 /* alignment slop */);
5355 insn
= get_last_insn ();
5357 pool
->pool_insn
= emit_insn_after (gen_pool (pool_size
), insn
);
5358 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
5361 /* Add INSN to the list of insns covered by POOL. */
5364 s390_add_pool_insn (struct constant_pool
*pool
, rtx insn
)
5366 bitmap_set_bit (pool
->insns
, INSN_UID (insn
));
5369 /* Return pool out of POOL_LIST that covers INSN. */
5371 static struct constant_pool
*
5372 s390_find_pool (struct constant_pool
*pool_list
, rtx insn
)
5374 struct constant_pool
*pool
;
5376 for (pool
= pool_list
; pool
; pool
= pool
->next
)
5377 if (bitmap_bit_p (pool
->insns
, INSN_UID (insn
)))
5383 /* Add constant VAL of mode MODE to the constant pool POOL. */
5386 s390_add_constant (struct constant_pool
*pool
, rtx val
, enum machine_mode mode
)
5391 for (i
= 0; i
< NR_C_MODES
; i
++)
5392 if (constant_modes
[i
] == mode
)
5394 gcc_assert (i
!= NR_C_MODES
);
5396 for (c
= pool
->constants
[i
]; c
!= NULL
; c
= c
->next
)
5397 if (rtx_equal_p (val
, c
->value
))
5402 c
= (struct constant
*) xmalloc (sizeof *c
);
5404 c
->label
= gen_label_rtx ();
5405 c
->next
= pool
->constants
[i
];
5406 pool
->constants
[i
] = c
;
5407 pool
->size
+= GET_MODE_SIZE (mode
);
5411 /* Find constant VAL of mode MODE in the constant pool POOL.
5412 Return an RTX describing the distance from the start of
5413 the pool to the location of the new constant. */
5416 s390_find_constant (struct constant_pool
*pool
, rtx val
,
5417 enum machine_mode mode
)
5423 for (i
= 0; i
< NR_C_MODES
; i
++)
5424 if (constant_modes
[i
] == mode
)
5426 gcc_assert (i
!= NR_C_MODES
);
5428 for (c
= pool
->constants
[i
]; c
!= NULL
; c
= c
->next
)
5429 if (rtx_equal_p (val
, c
->value
))
5434 offset
= gen_rtx_MINUS (Pmode
, gen_rtx_LABEL_REF (Pmode
, c
->label
),
5435 gen_rtx_LABEL_REF (Pmode
, pool
->label
));
5436 offset
= gen_rtx_CONST (Pmode
, offset
);
5440 /* Check whether INSN is an execute. Return the label_ref to its
5441 execute target template if so, NULL_RTX otherwise. */
5444 s390_execute_label (rtx insn
)
5446 if (GET_CODE (insn
) == INSN
5447 && GET_CODE (PATTERN (insn
)) == PARALLEL
5448 && GET_CODE (XVECEXP (PATTERN (insn
), 0, 0)) == UNSPEC
5449 && XINT (XVECEXP (PATTERN (insn
), 0, 0), 1) == UNSPEC_EXECUTE
)
5450 return XVECEXP (XVECEXP (PATTERN (insn
), 0, 0), 0, 2);
5455 /* Add execute target for INSN to the constant pool POOL. */
5458 s390_add_execute (struct constant_pool
*pool
, rtx insn
)
5462 for (c
= pool
->execute
; c
!= NULL
; c
= c
->next
)
5463 if (INSN_UID (insn
) == INSN_UID (c
->value
))
5468 c
= (struct constant
*) xmalloc (sizeof *c
);
5470 c
->label
= gen_label_rtx ();
5471 c
->next
= pool
->execute
;
5477 /* Find execute target for INSN in the constant pool POOL.
5478 Return an RTX describing the distance from the start of
5479 the pool to the location of the execute target. */
5482 s390_find_execute (struct constant_pool
*pool
, rtx insn
)
5487 for (c
= pool
->execute
; c
!= NULL
; c
= c
->next
)
5488 if (INSN_UID (insn
) == INSN_UID (c
->value
))
5493 offset
= gen_rtx_MINUS (Pmode
, gen_rtx_LABEL_REF (Pmode
, c
->label
),
5494 gen_rtx_LABEL_REF (Pmode
, pool
->label
));
5495 offset
= gen_rtx_CONST (Pmode
, offset
);
5499 /* For an execute INSN, extract the execute target template. */
5502 s390_execute_target (rtx insn
)
5504 rtx pattern
= PATTERN (insn
);
5505 gcc_assert (s390_execute_label (insn
));
5507 if (XVECLEN (pattern
, 0) == 2)
5509 pattern
= copy_rtx (XVECEXP (pattern
, 0, 1));
5513 rtvec vec
= rtvec_alloc (XVECLEN (pattern
, 0) - 1);
5516 for (i
= 0; i
< XVECLEN (pattern
, 0) - 1; i
++)
5517 RTVEC_ELT (vec
, i
) = copy_rtx (XVECEXP (pattern
, 0, i
+ 1));
5519 pattern
= gen_rtx_PARALLEL (VOIDmode
, vec
);
5525 /* Indicate that INSN cannot be duplicated. This is the case for
5526 execute insns that carry a unique label. */
5529 s390_cannot_copy_insn_p (rtx insn
)
5531 rtx label
= s390_execute_label (insn
);
5532 return label
&& label
!= const0_rtx
;
5535 /* Dump out the constants in POOL. If REMOTE_LABEL is true,
5536 do not emit the pool base label. */
5539 s390_dump_pool (struct constant_pool
*pool
, bool remote_label
)
5542 rtx insn
= pool
->pool_insn
;
5545 /* Switch to rodata section. */
5546 if (TARGET_CPU_ZARCH
)
5548 insn
= emit_insn_after (gen_pool_section_start (), insn
);
5549 INSN_ADDRESSES_NEW (insn
, -1);
5552 /* Ensure minimum pool alignment. */
5553 if (TARGET_CPU_ZARCH
)
5554 insn
= emit_insn_after (gen_pool_align (GEN_INT (8)), insn
);
5556 insn
= emit_insn_after (gen_pool_align (GEN_INT (4)), insn
);
5557 INSN_ADDRESSES_NEW (insn
, -1);
5559 /* Emit pool base label. */
5562 insn
= emit_label_after (pool
->label
, insn
);
5563 INSN_ADDRESSES_NEW (insn
, -1);
5566 /* Dump constants in descending alignment requirement order,
5567 ensuring proper alignment for every constant. */
5568 for (i
= 0; i
< NR_C_MODES
; i
++)
5569 for (c
= pool
->constants
[i
]; c
; c
= c
->next
)
5571 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
5572 rtx value
= c
->value
;
5573 if (GET_CODE (value
) == CONST
5574 && GET_CODE (XEXP (value
, 0)) == UNSPEC
5575 && XINT (XEXP (value
, 0), 1) == UNSPEC_LTREL_OFFSET
5576 && XVECLEN (XEXP (value
, 0), 0) == 1)
5578 value
= gen_rtx_MINUS (Pmode
, XVECEXP (XEXP (value
, 0), 0, 0),
5579 gen_rtx_LABEL_REF (VOIDmode
, pool
->label
));
5580 value
= gen_rtx_CONST (VOIDmode
, value
);
5583 insn
= emit_label_after (c
->label
, insn
);
5584 INSN_ADDRESSES_NEW (insn
, -1);
5586 value
= gen_rtx_UNSPEC_VOLATILE (constant_modes
[i
],
5587 gen_rtvec (1, value
),
5588 UNSPECV_POOL_ENTRY
);
5589 insn
= emit_insn_after (value
, insn
);
5590 INSN_ADDRESSES_NEW (insn
, -1);
5593 /* Ensure minimum alignment for instructions. */
5594 insn
= emit_insn_after (gen_pool_align (GEN_INT (2)), insn
);
5595 INSN_ADDRESSES_NEW (insn
, -1);
5597 /* Output in-pool execute template insns. */
5598 for (c
= pool
->execute
; c
; c
= c
->next
)
5600 insn
= emit_label_after (c
->label
, insn
);
5601 INSN_ADDRESSES_NEW (insn
, -1);
5603 insn
= emit_insn_after (s390_execute_target (c
->value
), insn
);
5604 INSN_ADDRESSES_NEW (insn
, -1);
5607 /* Switch back to previous section. */
5608 if (TARGET_CPU_ZARCH
)
5610 insn
= emit_insn_after (gen_pool_section_end (), insn
);
5611 INSN_ADDRESSES_NEW (insn
, -1);
5614 insn
= emit_barrier_after (insn
);
5615 INSN_ADDRESSES_NEW (insn
, -1);
5617 /* Remove placeholder insn. */
5618 remove_insn (pool
->pool_insn
);
5621 /* Free all memory used by POOL. */
5624 s390_free_pool (struct constant_pool
*pool
)
5626 struct constant
*c
, *next
;
5629 for (i
= 0; i
< NR_C_MODES
; i
++)
5630 for (c
= pool
->constants
[i
]; c
; c
= next
)
5636 for (c
= pool
->execute
; c
; c
= next
)
5642 BITMAP_FREE (pool
->insns
);
5647 /* Collect main literal pool. Return NULL on overflow. */
5649 static struct constant_pool
*
5650 s390_mainpool_start (void)
5652 struct constant_pool
*pool
;
5655 pool
= s390_alloc_pool ();
5657 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5659 if (GET_CODE (insn
) == INSN
5660 && GET_CODE (PATTERN (insn
)) == SET
5661 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC_VOLATILE
5662 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPECV_MAIN_POOL
)
5664 gcc_assert (!pool
->pool_insn
);
5665 pool
->pool_insn
= insn
;
5668 if (!TARGET_CPU_ZARCH
&& s390_execute_label (insn
))
5670 s390_add_execute (pool
, insn
);
5672 else if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5674 rtx pool_ref
= NULL_RTX
;
5675 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5678 rtx constant
= get_pool_constant (pool_ref
);
5679 enum machine_mode mode
= get_pool_mode (pool_ref
);
5680 s390_add_constant (pool
, constant
, mode
);
5685 gcc_assert (pool
->pool_insn
|| pool
->size
== 0);
5687 if (pool
->size
>= 4096)
5689 /* We're going to chunkify the pool, so remove the main
5690 pool placeholder insn. */
5691 remove_insn (pool
->pool_insn
);
5693 s390_free_pool (pool
);
5700 /* POOL holds the main literal pool as collected by s390_mainpool_start.
5701 Modify the current function to output the pool constants as well as
5702 the pool register setup instruction. */
5705 s390_mainpool_finish (struct constant_pool
*pool
)
5707 rtx base_reg
= cfun
->machine
->base_reg
;
5710 /* If the pool is empty, we're done. */
5711 if (pool
->size
== 0)
5713 /* We don't actually need a base register after all. */
5714 cfun
->machine
->base_reg
= NULL_RTX
;
5716 if (pool
->pool_insn
)
5717 remove_insn (pool
->pool_insn
);
5718 s390_free_pool (pool
);
5722 /* We need correct insn addresses. */
5723 shorten_branches (get_insns ());
5725 /* On zSeries, we use a LARL to load the pool register. The pool is
5726 located in the .rodata section, so we emit it after the function. */
5727 if (TARGET_CPU_ZARCH
)
5729 insn
= gen_main_base_64 (base_reg
, pool
->label
);
5730 insn
= emit_insn_after (insn
, pool
->pool_insn
);
5731 INSN_ADDRESSES_NEW (insn
, -1);
5732 remove_insn (pool
->pool_insn
);
5734 insn
= get_last_insn ();
5735 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
5736 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
5738 s390_dump_pool (pool
, 0);
5741 /* On S/390, if the total size of the function's code plus literal pool
5742 does not exceed 4096 bytes, we use BASR to set up a function base
5743 pointer, and emit the literal pool at the end of the function. */
5744 else if (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
5745 + pool
->size
+ 8 /* alignment slop */ < 4096)
5747 insn
= gen_main_base_31_small (base_reg
, pool
->label
);
5748 insn
= emit_insn_after (insn
, pool
->pool_insn
);
5749 INSN_ADDRESSES_NEW (insn
, -1);
5750 remove_insn (pool
->pool_insn
);
5752 insn
= emit_label_after (pool
->label
, insn
);
5753 INSN_ADDRESSES_NEW (insn
, -1);
5755 insn
= get_last_insn ();
5756 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
5757 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
5759 s390_dump_pool (pool
, 1);
5762 /* Otherwise, we emit an inline literal pool and use BASR to branch
5763 over it, setting up the pool register at the same time. */
5766 rtx pool_end
= gen_label_rtx ();
5768 insn
= gen_main_base_31_large (base_reg
, pool
->label
, pool_end
);
5769 insn
= emit_insn_after (insn
, pool
->pool_insn
);
5770 INSN_ADDRESSES_NEW (insn
, -1);
5771 remove_insn (pool
->pool_insn
);
5773 insn
= emit_label_after (pool
->label
, insn
);
5774 INSN_ADDRESSES_NEW (insn
, -1);
5776 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
5777 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
5779 insn
= emit_label_after (pool_end
, pool
->pool_insn
);
5780 INSN_ADDRESSES_NEW (insn
, -1);
5782 s390_dump_pool (pool
, 1);
5786 /* Replace all literal pool references. */
5788 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5791 replace_ltrel_base (&PATTERN (insn
));
5793 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5795 rtx addr
, pool_ref
= NULL_RTX
;
5796 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5799 if (s390_execute_label (insn
))
5800 addr
= s390_find_execute (pool
, insn
);
5802 addr
= s390_find_constant (pool
, get_pool_constant (pool_ref
),
5803 get_pool_mode (pool_ref
));
5805 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
5806 INSN_CODE (insn
) = -1;
5812 /* Free the pool. */
5813 s390_free_pool (pool
);
5816 /* POOL holds the main literal pool as collected by s390_mainpool_start.
5817 We have decided we cannot use this pool, so revert all changes
5818 to the current function that were done by s390_mainpool_start. */
5820 s390_mainpool_cancel (struct constant_pool
*pool
)
5822 /* We didn't actually change the instruction stream, so simply
5823 free the pool memory. */
5824 s390_free_pool (pool
);
5828 /* Chunkify the literal pool. */
5830 #define S390_POOL_CHUNK_MIN 0xc00
5831 #define S390_POOL_CHUNK_MAX 0xe00
5833 static struct constant_pool
*
5834 s390_chunkify_start (void)
5836 struct constant_pool
*curr_pool
= NULL
, *pool_list
= NULL
;
5839 rtx pending_ltrel
= NULL_RTX
;
5842 rtx (*gen_reload_base
) (rtx
, rtx
) =
5843 TARGET_CPU_ZARCH
? gen_reload_base_64
: gen_reload_base_31
;
5846 /* We need correct insn addresses. */
5848 shorten_branches (get_insns ());
5850 /* Scan all insns and move literals to pool chunks. */
5852 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5854 /* Check for pending LTREL_BASE. */
5857 rtx ltrel_base
= find_ltrel_base (PATTERN (insn
));
5860 gcc_assert (ltrel_base
== pending_ltrel
);
5861 pending_ltrel
= NULL_RTX
;
5865 if (!TARGET_CPU_ZARCH
&& s390_execute_label (insn
))
5868 curr_pool
= s390_start_pool (&pool_list
, insn
);
5870 s390_add_execute (curr_pool
, insn
);
5871 s390_add_pool_insn (curr_pool
, insn
);
5873 else if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5875 rtx pool_ref
= NULL_RTX
;
5876 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5879 rtx constant
= get_pool_constant (pool_ref
);
5880 enum machine_mode mode
= get_pool_mode (pool_ref
);
5883 curr_pool
= s390_start_pool (&pool_list
, insn
);
5885 s390_add_constant (curr_pool
, constant
, mode
);
5886 s390_add_pool_insn (curr_pool
, insn
);
5888 /* Don't split the pool chunk between a LTREL_OFFSET load
5889 and the corresponding LTREL_BASE. */
5890 if (GET_CODE (constant
) == CONST
5891 && GET_CODE (XEXP (constant
, 0)) == UNSPEC
5892 && XINT (XEXP (constant
, 0), 1) == UNSPEC_LTREL_OFFSET
)
5894 gcc_assert (!pending_ltrel
);
5895 pending_ltrel
= pool_ref
;
5900 if (GET_CODE (insn
) == JUMP_INSN
|| GET_CODE (insn
) == CODE_LABEL
)
5903 s390_add_pool_insn (curr_pool
, insn
);
5904 /* An LTREL_BASE must follow within the same basic block. */
5905 gcc_assert (!pending_ltrel
);
5909 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn
)
5910 || INSN_ADDRESSES (INSN_UID (insn
)) == -1)
5913 if (TARGET_CPU_ZARCH
)
5915 if (curr_pool
->size
< S390_POOL_CHUNK_MAX
)
5918 s390_end_pool (curr_pool
, NULL_RTX
);
5923 int chunk_size
= INSN_ADDRESSES (INSN_UID (insn
))
5924 - INSN_ADDRESSES (INSN_UID (curr_pool
->first_insn
))
5927 /* We will later have to insert base register reload insns.
5928 Those will have an effect on code size, which we need to
5929 consider here. This calculation makes rather pessimistic
5930 worst-case assumptions. */
5931 if (GET_CODE (insn
) == CODE_LABEL
)
5934 if (chunk_size
< S390_POOL_CHUNK_MIN
5935 && curr_pool
->size
< S390_POOL_CHUNK_MIN
)
5938 /* Pool chunks can only be inserted after BARRIERs ... */
5939 if (GET_CODE (insn
) == BARRIER
)
5941 s390_end_pool (curr_pool
, insn
);
5946 /* ... so if we don't find one in time, create one. */
5947 else if ((chunk_size
> S390_POOL_CHUNK_MAX
5948 || curr_pool
->size
> S390_POOL_CHUNK_MAX
))
5950 rtx label
, jump
, barrier
;
5952 /* We can insert the barrier only after a 'real' insn. */
5953 if (GET_CODE (insn
) != INSN
&& GET_CODE (insn
) != CALL_INSN
)
5955 if (get_attr_length (insn
) == 0)
5958 /* Don't separate LTREL_BASE from the corresponding
5959 LTREL_OFFSET load. */
5963 label
= gen_label_rtx ();
5964 jump
= emit_jump_insn_after (gen_jump (label
), insn
);
5965 barrier
= emit_barrier_after (jump
);
5966 insn
= emit_label_after (label
, barrier
);
5967 JUMP_LABEL (jump
) = label
;
5968 LABEL_NUSES (label
) = 1;
5970 INSN_ADDRESSES_NEW (jump
, -1);
5971 INSN_ADDRESSES_NEW (barrier
, -1);
5972 INSN_ADDRESSES_NEW (insn
, -1);
5974 s390_end_pool (curr_pool
, barrier
);
5982 s390_end_pool (curr_pool
, NULL_RTX
);
5983 gcc_assert (!pending_ltrel
);
5985 /* Find all labels that are branched into
5986 from an insn belonging to a different chunk. */
5988 far_labels
= BITMAP_ALLOC (NULL
);
5990 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5992 /* Labels marked with LABEL_PRESERVE_P can be target
5993 of non-local jumps, so we have to mark them.
5994 The same holds for named labels.
5996 Don't do that, however, if it is the label before
5999 if (GET_CODE (insn
) == CODE_LABEL
6000 && (LABEL_PRESERVE_P (insn
) || LABEL_NAME (insn
)))
6002 rtx vec_insn
= next_real_insn (insn
);
6003 rtx vec_pat
= vec_insn
&& GET_CODE (vec_insn
) == JUMP_INSN
?
6004 PATTERN (vec_insn
) : NULL_RTX
;
6006 || !(GET_CODE (vec_pat
) == ADDR_VEC
6007 || GET_CODE (vec_pat
) == ADDR_DIFF_VEC
))
6008 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (insn
));
6011 /* If we have a direct jump (conditional or unconditional)
6012 or a casesi jump, check all potential targets. */
6013 else if (GET_CODE (insn
) == JUMP_INSN
)
6015 rtx pat
= PATTERN (insn
);
6016 if (GET_CODE (pat
) == PARALLEL
&& XVECLEN (pat
, 0) > 2)
6017 pat
= XVECEXP (pat
, 0, 0);
6019 if (GET_CODE (pat
) == SET
)
6021 rtx label
= JUMP_LABEL (insn
);
6024 if (s390_find_pool (pool_list
, label
)
6025 != s390_find_pool (pool_list
, insn
))
6026 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
6029 else if (GET_CODE (pat
) == PARALLEL
6030 && XVECLEN (pat
, 0) == 2
6031 && GET_CODE (XVECEXP (pat
, 0, 0)) == SET
6032 && GET_CODE (XVECEXP (pat
, 0, 1)) == USE
6033 && GET_CODE (XEXP (XVECEXP (pat
, 0, 1), 0)) == LABEL_REF
)
6035 /* Find the jump table used by this casesi jump. */
6036 rtx vec_label
= XEXP (XEXP (XVECEXP (pat
, 0, 1), 0), 0);
6037 rtx vec_insn
= next_real_insn (vec_label
);
6038 rtx vec_pat
= vec_insn
&& GET_CODE (vec_insn
) == JUMP_INSN
?
6039 PATTERN (vec_insn
) : NULL_RTX
;
6041 && (GET_CODE (vec_pat
) == ADDR_VEC
6042 || GET_CODE (vec_pat
) == ADDR_DIFF_VEC
))
6044 int i
, diff_p
= GET_CODE (vec_pat
) == ADDR_DIFF_VEC
;
6046 for (i
= 0; i
< XVECLEN (vec_pat
, diff_p
); i
++)
6048 rtx label
= XEXP (XVECEXP (vec_pat
, diff_p
, i
), 0);
6050 if (s390_find_pool (pool_list
, label
)
6051 != s390_find_pool (pool_list
, insn
))
6052 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
6059 /* Insert base register reload insns before every pool. */
6061 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
6063 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
6065 rtx insn
= curr_pool
->first_insn
;
6066 INSN_ADDRESSES_NEW (emit_insn_before (new_insn
, insn
), -1);
6069 /* Insert base register reload insns at every far label. */
6071 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6072 if (GET_CODE (insn
) == CODE_LABEL
6073 && bitmap_bit_p (far_labels
, CODE_LABEL_NUMBER (insn
)))
6075 struct constant_pool
*pool
= s390_find_pool (pool_list
, insn
);
6078 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
6080 INSN_ADDRESSES_NEW (emit_insn_after (new_insn
, insn
), -1);
6085 BITMAP_FREE (far_labels
);
6088 /* Recompute insn addresses. */
6090 init_insn_lengths ();
6091 shorten_branches (get_insns ());
6096 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
6097 After we have decided to use this list, finish implementing
6098 all changes to the current function as required. */
6101 s390_chunkify_finish (struct constant_pool
*pool_list
)
6103 struct constant_pool
*curr_pool
= NULL
;
6107 /* Replace all literal pool references. */
6109 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6112 replace_ltrel_base (&PATTERN (insn
));
6114 curr_pool
= s390_find_pool (pool_list
, insn
);
6118 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
6120 rtx addr
, pool_ref
= NULL_RTX
;
6121 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
6124 if (s390_execute_label (insn
))
6125 addr
= s390_find_execute (curr_pool
, insn
);
6127 addr
= s390_find_constant (curr_pool
,
6128 get_pool_constant (pool_ref
),
6129 get_pool_mode (pool_ref
));
6131 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
6132 INSN_CODE (insn
) = -1;
6137 /* Dump out all literal pools. */
6139 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
6140 s390_dump_pool (curr_pool
, 0);
6142 /* Free pool list. */
6146 struct constant_pool
*next
= pool_list
->next
;
6147 s390_free_pool (pool_list
);
6152 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
6153 We have decided we cannot use this list, so revert all changes
6154 to the current function that were done by s390_chunkify_start. */
6157 s390_chunkify_cancel (struct constant_pool
*pool_list
)
6159 struct constant_pool
*curr_pool
= NULL
;
6162 /* Remove all pool placeholder insns. */
6164 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
6166 /* Did we insert an extra barrier? Remove it. */
6167 rtx barrier
= PREV_INSN (curr_pool
->pool_insn
);
6168 rtx jump
= barrier
? PREV_INSN (barrier
) : NULL_RTX
;
6169 rtx label
= NEXT_INSN (curr_pool
->pool_insn
);
6171 if (jump
&& GET_CODE (jump
) == JUMP_INSN
6172 && barrier
&& GET_CODE (barrier
) == BARRIER
6173 && label
&& GET_CODE (label
) == CODE_LABEL
6174 && GET_CODE (PATTERN (jump
)) == SET
6175 && SET_DEST (PATTERN (jump
)) == pc_rtx
6176 && GET_CODE (SET_SRC (PATTERN (jump
))) == LABEL_REF
6177 && XEXP (SET_SRC (PATTERN (jump
)), 0) == label
)
6180 remove_insn (barrier
);
6181 remove_insn (label
);
6184 remove_insn (curr_pool
->pool_insn
);
6187 /* Remove all base register reload insns. */
6189 for (insn
= get_insns (); insn
; )
6191 rtx next_insn
= NEXT_INSN (insn
);
6193 if (GET_CODE (insn
) == INSN
6194 && GET_CODE (PATTERN (insn
)) == SET
6195 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC
6196 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPEC_RELOAD_BASE
)
6202 /* Free pool list. */
6206 struct constant_pool
*next
= pool_list
->next
;
6207 s390_free_pool (pool_list
);
6213 /* Output the constant pool entry EXP in mode MODE with alignment ALIGN. */
6216 s390_output_pool_entry (rtx exp
, enum machine_mode mode
, unsigned int align
)
6220 switch (GET_MODE_CLASS (mode
))
6223 case MODE_DECIMAL_FLOAT
:
6224 gcc_assert (GET_CODE (exp
) == CONST_DOUBLE
);
6226 REAL_VALUE_FROM_CONST_DOUBLE (r
, exp
);
6227 assemble_real (r
, mode
, align
);
6231 assemble_integer (exp
, GET_MODE_SIZE (mode
), align
, 1);
6240 /* Return an RTL expression representing the value of the return address
6241 for the frame COUNT steps up from the current frame. FRAME is the
6242 frame pointer of that frame. */
6245 s390_return_addr_rtx (int count
, rtx frame ATTRIBUTE_UNUSED
)
6250 /* Without backchain, we fail for all but the current frame. */
6252 if (!TARGET_BACKCHAIN
&& count
> 0)
6255 /* For the current frame, we need to make sure the initial
6256 value of RETURN_REGNUM is actually saved. */
6260 /* On non-z architectures branch splitting could overwrite r14. */
6261 if (TARGET_CPU_ZARCH
)
6262 return get_hard_reg_initial_val (Pmode
, RETURN_REGNUM
);
6265 cfun_frame_layout
.save_return_addr_p
= true;
6266 return gen_rtx_MEM (Pmode
, return_address_pointer_rtx
);
6270 if (TARGET_PACKED_STACK
)
6271 offset
= -2 * UNITS_PER_WORD
;
6273 offset
= RETURN_REGNUM
* UNITS_PER_WORD
;
6275 addr
= plus_constant (frame
, offset
);
6276 addr
= memory_address (Pmode
, addr
);
6277 return gen_rtx_MEM (Pmode
, addr
);
6280 /* Return an RTL expression representing the back chain stored in
6281 the current stack frame. */
6284 s390_back_chain_rtx (void)
6288 gcc_assert (TARGET_BACKCHAIN
);
6290 if (TARGET_PACKED_STACK
)
6291 chain
= plus_constant (stack_pointer_rtx
,
6292 STACK_POINTER_OFFSET
- UNITS_PER_WORD
);
6294 chain
= stack_pointer_rtx
;
6296 chain
= gen_rtx_MEM (Pmode
, chain
);
6300 /* Find first call clobbered register unused in a function.
6301 This could be used as base register in a leaf function
6302 or for holding the return address before epilogue. */
6305 find_unused_clobbered_reg (void)
6308 for (i
= 0; i
< 6; i
++)
6309 if (!regs_ever_live
[i
])
6315 /* Helper function for s390_regs_ever_clobbered. Sets the fields in DATA for all
6316 clobbered hard regs in SETREG. */
6319 s390_reg_clobbered_rtx (rtx setreg
, rtx set_insn ATTRIBUTE_UNUSED
, void *data
)
6321 int *regs_ever_clobbered
= (int *)data
;
6322 unsigned int i
, regno
;
6323 enum machine_mode mode
= GET_MODE (setreg
);
6325 if (GET_CODE (setreg
) == SUBREG
)
6327 rtx inner
= SUBREG_REG (setreg
);
6328 if (!GENERAL_REG_P (inner
))
6330 regno
= subreg_regno (setreg
);
6332 else if (GENERAL_REG_P (setreg
))
6333 regno
= REGNO (setreg
);
6338 i
< regno
+ HARD_REGNO_NREGS (regno
, mode
);
6340 regs_ever_clobbered
[i
] = 1;
6343 /* Walks through all basic blocks of the current function looking
6344 for clobbered hard regs using s390_reg_clobbered_rtx. The fields
6345 of the passed integer array REGS_EVER_CLOBBERED are set to one for
6346 each of those regs. */
6349 s390_regs_ever_clobbered (int *regs_ever_clobbered
)
6355 memset (regs_ever_clobbered
, 0, 16 * sizeof (int));
6357 /* For non-leaf functions we have to consider all call clobbered regs to be
6359 if (!current_function_is_leaf
)
6361 for (i
= 0; i
< 16; i
++)
6362 regs_ever_clobbered
[i
] = call_really_used_regs
[i
];
6365 /* Make the "magic" eh_return registers live if necessary. For regs_ever_live
6366 this work is done by liveness analysis (mark_regs_live_at_end).
6367 Special care is needed for functions containing landing pads. Landing pads
6368 may use the eh registers, but the code which sets these registers is not
6369 contained in that function. Hence s390_regs_ever_clobbered is not able to
6370 deal with this automatically. */
6371 if (current_function_calls_eh_return
|| cfun
->machine
->has_landing_pad_p
)
6372 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; i
++)
6373 if (current_function_calls_eh_return
6374 || (cfun
->machine
->has_landing_pad_p
6375 && regs_ever_live
[EH_RETURN_DATA_REGNO (i
)]))
6376 regs_ever_clobbered
[EH_RETURN_DATA_REGNO (i
)] = 1;
6378 /* For nonlocal gotos all call-saved registers have to be saved.
6379 This flag is also set for the unwinding code in libgcc.
6380 See expand_builtin_unwind_init. For regs_ever_live this is done by
6382 if (current_function_has_nonlocal_label
)
6383 for (i
= 0; i
< 16; i
++)
6384 if (!call_really_used_regs
[i
])
6385 regs_ever_clobbered
[i
] = 1;
6387 FOR_EACH_BB (cur_bb
)
6389 FOR_BB_INSNS (cur_bb
, cur_insn
)
6391 if (INSN_P (cur_insn
))
6392 note_stores (PATTERN (cur_insn
),
6393 s390_reg_clobbered_rtx
,
6394 regs_ever_clobbered
);
6399 /* Determine the frame area which actually has to be accessed
6400 in the function epilogue. The values are stored at the
6401 given pointers AREA_BOTTOM (address of the lowest used stack
6402 address) and AREA_TOP (address of the first item which does
6403 not belong to the stack frame). */
6406 s390_frame_area (int *area_bottom
, int *area_top
)
6414 if (cfun_frame_layout
.first_restore_gpr
!= -1)
6416 b
= (cfun_frame_layout
.gprs_offset
6417 + cfun_frame_layout
.first_restore_gpr
* UNITS_PER_WORD
);
6418 t
= b
+ (cfun_frame_layout
.last_restore_gpr
6419 - cfun_frame_layout
.first_restore_gpr
+ 1) * UNITS_PER_WORD
;
6422 if (TARGET_64BIT
&& cfun_save_high_fprs_p
)
6424 b
= MIN (b
, cfun_frame_layout
.f8_offset
);
6425 t
= MAX (t
, (cfun_frame_layout
.f8_offset
6426 + cfun_frame_layout
.high_fprs
* 8));
6430 for (i
= 2; i
< 4; i
++)
6431 if (cfun_fpr_bit_p (i
))
6433 b
= MIN (b
, cfun_frame_layout
.f4_offset
+ (i
- 2) * 8);
6434 t
= MAX (t
, cfun_frame_layout
.f4_offset
+ (i
- 1) * 8);
6441 /* Fill cfun->machine with info about register usage of current function.
6442 Return in CLOBBERED_REGS which GPRs are currently considered set. */
6445 s390_register_info (int clobbered_regs
[])
6449 /* fprs 8 - 15 are call saved for 64 Bit ABI. */
6450 cfun_frame_layout
.fpr_bitmap
= 0;
6451 cfun_frame_layout
.high_fprs
= 0;
6453 for (i
= 24; i
< 32; i
++)
6454 if (regs_ever_live
[i
] && !global_regs
[i
])
6456 cfun_set_fpr_bit (i
- 16);
6457 cfun_frame_layout
.high_fprs
++;
6460 /* Find first and last gpr to be saved. We trust regs_ever_live
6461 data, except that we don't save and restore global registers.
6463 Also, all registers with special meaning to the compiler need
6464 to be handled extra. */
6466 s390_regs_ever_clobbered (clobbered_regs
);
6468 for (i
= 0; i
< 16; i
++)
6469 clobbered_regs
[i
] = clobbered_regs
[i
] && !global_regs
[i
] && !fixed_regs
[i
];
6471 if (frame_pointer_needed
)
6472 clobbered_regs
[HARD_FRAME_POINTER_REGNUM
] = 1;
6475 clobbered_regs
[PIC_OFFSET_TABLE_REGNUM
]
6476 |= regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
];
6478 clobbered_regs
[BASE_REGNUM
]
6479 |= (cfun
->machine
->base_reg
6480 && REGNO (cfun
->machine
->base_reg
) == BASE_REGNUM
);
6482 clobbered_regs
[RETURN_REGNUM
]
6483 |= (!current_function_is_leaf
6484 || TARGET_TPF_PROFILING
6485 || cfun
->machine
->split_branches_pending_p
6486 || cfun_frame_layout
.save_return_addr_p
6487 || current_function_calls_eh_return
6488 || current_function_stdarg
);
6490 clobbered_regs
[STACK_POINTER_REGNUM
]
6491 |= (!current_function_is_leaf
6492 || TARGET_TPF_PROFILING
6493 || cfun_save_high_fprs_p
6494 || get_frame_size () > 0
6495 || current_function_calls_alloca
6496 || current_function_stdarg
);
6498 for (i
= 6; i
< 16; i
++)
6499 if (regs_ever_live
[i
] || clobbered_regs
[i
])
6501 for (j
= 15; j
> i
; j
--)
6502 if (regs_ever_live
[j
] || clobbered_regs
[j
])
6507 /* Nothing to save/restore. */
6508 cfun_frame_layout
.first_save_gpr_slot
= -1;
6509 cfun_frame_layout
.last_save_gpr_slot
= -1;
6510 cfun_frame_layout
.first_save_gpr
= -1;
6511 cfun_frame_layout
.first_restore_gpr
= -1;
6512 cfun_frame_layout
.last_save_gpr
= -1;
6513 cfun_frame_layout
.last_restore_gpr
= -1;
6517 /* Save slots for gprs from i to j. */
6518 cfun_frame_layout
.first_save_gpr_slot
= i
;
6519 cfun_frame_layout
.last_save_gpr_slot
= j
;
6521 for (i
= cfun_frame_layout
.first_save_gpr_slot
;
6522 i
< cfun_frame_layout
.last_save_gpr_slot
+ 1;
6524 if (clobbered_regs
[i
])
6527 for (j
= cfun_frame_layout
.last_save_gpr_slot
; j
> i
; j
--)
6528 if (clobbered_regs
[j
])
6531 if (i
== cfun_frame_layout
.last_save_gpr_slot
+ 1)
6533 /* Nothing to save/restore. */
6534 cfun_frame_layout
.first_save_gpr
= -1;
6535 cfun_frame_layout
.first_restore_gpr
= -1;
6536 cfun_frame_layout
.last_save_gpr
= -1;
6537 cfun_frame_layout
.last_restore_gpr
= -1;
6541 /* Save / Restore from gpr i to j. */
6542 cfun_frame_layout
.first_save_gpr
= i
;
6543 cfun_frame_layout
.first_restore_gpr
= i
;
6544 cfun_frame_layout
.last_save_gpr
= j
;
6545 cfun_frame_layout
.last_restore_gpr
= j
;
6549 if (current_function_stdarg
)
6551 /* Varargs functions need to save gprs 2 to 6. */
6552 if (cfun
->va_list_gpr_size
6553 && current_function_args_info
.gprs
< GP_ARG_NUM_REG
)
6555 int min_gpr
= current_function_args_info
.gprs
;
6556 int max_gpr
= min_gpr
+ cfun
->va_list_gpr_size
;
6557 if (max_gpr
> GP_ARG_NUM_REG
)
6558 max_gpr
= GP_ARG_NUM_REG
;
6560 if (cfun_frame_layout
.first_save_gpr
== -1
6561 || cfun_frame_layout
.first_save_gpr
> 2 + min_gpr
)
6563 cfun_frame_layout
.first_save_gpr
= 2 + min_gpr
;
6564 cfun_frame_layout
.first_save_gpr_slot
= 2 + min_gpr
;
6567 if (cfun_frame_layout
.last_save_gpr
== -1
6568 || cfun_frame_layout
.last_save_gpr
< 2 + max_gpr
- 1)
6570 cfun_frame_layout
.last_save_gpr
= 2 + max_gpr
- 1;
6571 cfun_frame_layout
.last_save_gpr_slot
= 2 + max_gpr
- 1;
6575 /* Mark f0, f2 for 31 bit and f0-f4 for 64 bit to be saved. */
6576 if (TARGET_HARD_FLOAT
&& cfun
->va_list_fpr_size
6577 && current_function_args_info
.fprs
< FP_ARG_NUM_REG
)
6579 int min_fpr
= current_function_args_info
.fprs
;
6580 int max_fpr
= min_fpr
+ cfun
->va_list_fpr_size
;
6581 if (max_fpr
> FP_ARG_NUM_REG
)
6582 max_fpr
= FP_ARG_NUM_REG
;
6584 /* ??? This is currently required to ensure proper location
6585 of the fpr save slots within the va_list save area. */
6586 if (TARGET_PACKED_STACK
)
6589 for (i
= min_fpr
; i
< max_fpr
; i
++)
6590 cfun_set_fpr_bit (i
);
6595 for (i
= 2; i
< 4; i
++)
6596 if (regs_ever_live
[i
+ 16] && !global_regs
[i
+ 16])
6597 cfun_set_fpr_bit (i
);
6600 /* Fill cfun->machine with info about frame of current function. */
6603 s390_frame_info (void)
6607 cfun_frame_layout
.frame_size
= get_frame_size ();
6608 if (!TARGET_64BIT
&& cfun_frame_layout
.frame_size
> 0x7fff0000)
6609 fatal_error ("total size of local variables exceeds architecture limit");
6611 if (!TARGET_PACKED_STACK
)
6613 cfun_frame_layout
.backchain_offset
= 0;
6614 cfun_frame_layout
.f0_offset
= 16 * UNITS_PER_WORD
;
6615 cfun_frame_layout
.f4_offset
= cfun_frame_layout
.f0_offset
+ 2 * 8;
6616 cfun_frame_layout
.f8_offset
= -cfun_frame_layout
.high_fprs
* 8;
6617 cfun_frame_layout
.gprs_offset
= (cfun_frame_layout
.first_save_gpr_slot
6620 else if (TARGET_BACKCHAIN
) /* kernel stack layout */
6622 cfun_frame_layout
.backchain_offset
= (STACK_POINTER_OFFSET
6624 cfun_frame_layout
.gprs_offset
6625 = (cfun_frame_layout
.backchain_offset
6626 - (STACK_POINTER_REGNUM
- cfun_frame_layout
.first_save_gpr_slot
+ 1)
6631 cfun_frame_layout
.f4_offset
6632 = (cfun_frame_layout
.gprs_offset
6633 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6635 cfun_frame_layout
.f0_offset
6636 = (cfun_frame_layout
.f4_offset
6637 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6641 /* On 31 bit we have to care about alignment of the
6642 floating point regs to provide fastest access. */
6643 cfun_frame_layout
.f0_offset
6644 = ((cfun_frame_layout
.gprs_offset
6645 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1))
6646 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6648 cfun_frame_layout
.f4_offset
6649 = (cfun_frame_layout
.f0_offset
6650 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6653 else /* no backchain */
6655 cfun_frame_layout
.f4_offset
6656 = (STACK_POINTER_OFFSET
6657 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6659 cfun_frame_layout
.f0_offset
6660 = (cfun_frame_layout
.f4_offset
6661 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6663 cfun_frame_layout
.gprs_offset
6664 = cfun_frame_layout
.f0_offset
- cfun_gprs_save_area_size
;
6667 if (current_function_is_leaf
6668 && !TARGET_TPF_PROFILING
6669 && cfun_frame_layout
.frame_size
== 0
6670 && !cfun_save_high_fprs_p
6671 && !current_function_calls_alloca
6672 && !current_function_stdarg
)
6675 if (!TARGET_PACKED_STACK
)
6676 cfun_frame_layout
.frame_size
+= (STACK_POINTER_OFFSET
6677 + current_function_outgoing_args_size
6678 + cfun_frame_layout
.high_fprs
* 8);
6681 if (TARGET_BACKCHAIN
)
6682 cfun_frame_layout
.frame_size
+= UNITS_PER_WORD
;
6684 /* No alignment trouble here because f8-f15 are only saved under
6686 cfun_frame_layout
.f8_offset
= (MIN (MIN (cfun_frame_layout
.f0_offset
,
6687 cfun_frame_layout
.f4_offset
),
6688 cfun_frame_layout
.gprs_offset
)
6689 - cfun_frame_layout
.high_fprs
* 8);
6691 cfun_frame_layout
.frame_size
+= cfun_frame_layout
.high_fprs
* 8;
6693 for (i
= 0; i
< 8; i
++)
6694 if (cfun_fpr_bit_p (i
))
6695 cfun_frame_layout
.frame_size
+= 8;
6697 cfun_frame_layout
.frame_size
+= cfun_gprs_save_area_size
;
6699 /* If under 31 bit an odd number of gprs has to be saved we have to adjust
6700 the frame size to sustain 8 byte alignment of stack frames. */
6701 cfun_frame_layout
.frame_size
= ((cfun_frame_layout
.frame_size
+
6702 STACK_BOUNDARY
/ BITS_PER_UNIT
- 1)
6703 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1));
6705 cfun_frame_layout
.frame_size
+= current_function_outgoing_args_size
;
6709 /* Generate frame layout. Fills in register and frame data for the current
6710 function in cfun->machine. This routine can be called multiple times;
6711 it will re-do the complete frame layout every time. */
6714 s390_init_frame_layout (void)
6716 HOST_WIDE_INT frame_size
;
6718 int clobbered_regs
[16];
6720 /* On S/390 machines, we may need to perform branch splitting, which
6721 will require both base and return address register. We have no
6722 choice but to assume we're going to need them until right at the
6723 end of the machine dependent reorg phase. */
6724 if (!TARGET_CPU_ZARCH
)
6725 cfun
->machine
->split_branches_pending_p
= true;
6729 frame_size
= cfun_frame_layout
.frame_size
;
6731 /* Try to predict whether we'll need the base register. */
6732 base_used
= cfun
->machine
->split_branches_pending_p
6733 || current_function_uses_const_pool
6734 || (!DISP_IN_RANGE (frame_size
)
6735 && !CONST_OK_FOR_K (frame_size
));
6737 /* Decide which register to use as literal pool base. In small
6738 leaf functions, try to use an unused call-clobbered register
6739 as base register to avoid save/restore overhead. */
6741 cfun
->machine
->base_reg
= NULL_RTX
;
6742 else if (current_function_is_leaf
&& !regs_ever_live
[5])
6743 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, 5);
6745 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
6747 s390_register_info (clobbered_regs
);
6750 while (frame_size
!= cfun_frame_layout
.frame_size
);
6753 /* Update frame layout. Recompute actual register save data based on
6754 current info and update regs_ever_live for the special registers.
6755 May be called multiple times, but may never cause *more* registers
6756 to be saved than s390_init_frame_layout allocated room for. */
6759 s390_update_frame_layout (void)
6761 int clobbered_regs
[16];
6763 s390_register_info (clobbered_regs
);
6765 regs_ever_live
[BASE_REGNUM
] = clobbered_regs
[BASE_REGNUM
];
6766 regs_ever_live
[RETURN_REGNUM
] = clobbered_regs
[RETURN_REGNUM
];
6767 regs_ever_live
[STACK_POINTER_REGNUM
] = clobbered_regs
[STACK_POINTER_REGNUM
];
6769 if (cfun
->machine
->base_reg
)
6770 regs_ever_live
[REGNO (cfun
->machine
->base_reg
)] = 1;
6773 /* Return true if it is legal to put a value with MODE into REGNO. */
6776 s390_hard_regno_mode_ok (unsigned int regno
, enum machine_mode mode
)
6778 switch (REGNO_REG_CLASS (regno
))
6781 if (REGNO_PAIR_OK (regno
, mode
))
6783 if (mode
== SImode
|| mode
== DImode
)
6786 if (FLOAT_MODE_P (mode
) && GET_MODE_CLASS (mode
) != MODE_VECTOR_FLOAT
)
6791 if (FRAME_REGNO_P (regno
) && mode
== Pmode
)
6796 if (REGNO_PAIR_OK (regno
, mode
))
6799 || (mode
!= TFmode
&& mode
!= TCmode
&& mode
!= TDmode
))
6804 if (GET_MODE_CLASS (mode
) == MODE_CC
)
6808 if (REGNO_PAIR_OK (regno
, mode
))
6810 if (mode
== SImode
|| mode
== Pmode
)
6821 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
6824 s390_hard_regno_rename_ok (unsigned int old_reg
, unsigned int new_reg
)
6826 /* Once we've decided upon a register to use as base register, it must
6827 no longer be used for any other purpose. */
6828 if (cfun
->machine
->base_reg
)
6829 if (REGNO (cfun
->machine
->base_reg
) == old_reg
6830 || REGNO (cfun
->machine
->base_reg
) == new_reg
)
6836 /* Maximum number of registers to represent a value of mode MODE
6837 in a register of class CLASS. */
6840 s390_class_max_nregs (enum reg_class
class, enum machine_mode mode
)
6845 if (GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
)
6846 return 2 * ((GET_MODE_SIZE (mode
) / 2 + 8 - 1) / 8);
6848 return (GET_MODE_SIZE (mode
) + 8 - 1) / 8;
6850 return (GET_MODE_SIZE (mode
) + 4 - 1) / 4;
6854 return (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
6857 /* Return true if register FROM can be eliminated via register TO. */
6860 s390_can_eliminate (int from
, int to
)
6862 /* On zSeries machines, we have not marked the base register as fixed.
6863 Instead, we have an elimination rule BASE_REGNUM -> BASE_REGNUM.
6864 If a function requires the base register, we say here that this
6865 elimination cannot be performed. This will cause reload to free
6866 up the base register (as if it were fixed). On the other hand,
6867 if the current function does *not* require the base register, we
6868 say here the elimination succeeds, which in turn allows reload
6869 to allocate the base register for any other purpose. */
6870 if (from
== BASE_REGNUM
&& to
== BASE_REGNUM
)
6872 if (TARGET_CPU_ZARCH
)
6874 s390_init_frame_layout ();
6875 return cfun
->machine
->base_reg
== NULL_RTX
;
6881 /* Everything else must point into the stack frame. */
6882 gcc_assert (to
== STACK_POINTER_REGNUM
6883 || to
== HARD_FRAME_POINTER_REGNUM
);
6885 gcc_assert (from
== FRAME_POINTER_REGNUM
6886 || from
== ARG_POINTER_REGNUM
6887 || from
== RETURN_ADDRESS_POINTER_REGNUM
);
6889 /* Make sure we actually saved the return address. */
6890 if (from
== RETURN_ADDRESS_POINTER_REGNUM
)
6891 if (!current_function_calls_eh_return
6892 && !current_function_stdarg
6893 && !cfun_frame_layout
.save_return_addr_p
)
6899 /* Return offset between register FROM and TO initially after prolog. */
6902 s390_initial_elimination_offset (int from
, int to
)
6904 HOST_WIDE_INT offset
;
6907 /* ??? Why are we called for non-eliminable pairs? */
6908 if (!s390_can_eliminate (from
, to
))
6913 case FRAME_POINTER_REGNUM
:
6914 offset
= (get_frame_size()
6915 + STACK_POINTER_OFFSET
6916 + current_function_outgoing_args_size
);
6919 case ARG_POINTER_REGNUM
:
6920 s390_init_frame_layout ();
6921 offset
= cfun_frame_layout
.frame_size
+ STACK_POINTER_OFFSET
;
6924 case RETURN_ADDRESS_POINTER_REGNUM
:
6925 s390_init_frame_layout ();
6926 index
= RETURN_REGNUM
- cfun_frame_layout
.first_save_gpr_slot
;
6927 gcc_assert (index
>= 0);
6928 offset
= cfun_frame_layout
.frame_size
+ cfun_frame_layout
.gprs_offset
;
6929 offset
+= index
* UNITS_PER_WORD
;
6943 /* Emit insn to save fpr REGNUM at offset OFFSET relative
6944 to register BASE. Return generated insn. */
6947 save_fpr (rtx base
, int offset
, int regnum
)
6950 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
6952 if (regnum
>= 16 && regnum
<= (16 + FP_ARG_NUM_REG
))
6953 set_mem_alias_set (addr
, get_varargs_alias_set ());
6955 set_mem_alias_set (addr
, get_frame_alias_set ());
6957 return emit_move_insn (addr
, gen_rtx_REG (DFmode
, regnum
));
6960 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
6961 to register BASE. Return generated insn. */
6964 restore_fpr (rtx base
, int offset
, int regnum
)
6967 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
6968 set_mem_alias_set (addr
, get_frame_alias_set ());
6970 return emit_move_insn (gen_rtx_REG (DFmode
, regnum
), addr
);
6973 /* Generate insn to save registers FIRST to LAST into
6974 the register save area located at offset OFFSET
6975 relative to register BASE. */
6978 save_gprs (rtx base
, int offset
, int first
, int last
)
6980 rtx addr
, insn
, note
;
6983 addr
= plus_constant (base
, offset
);
6984 addr
= gen_rtx_MEM (Pmode
, addr
);
6986 set_mem_alias_set (addr
, get_frame_alias_set ());
6988 /* Special-case single register. */
6992 insn
= gen_movdi (addr
, gen_rtx_REG (Pmode
, first
));
6994 insn
= gen_movsi (addr
, gen_rtx_REG (Pmode
, first
));
6996 RTX_FRAME_RELATED_P (insn
) = 1;
7001 insn
= gen_store_multiple (addr
,
7002 gen_rtx_REG (Pmode
, first
),
7003 GEN_INT (last
- first
+ 1));
7005 if (first
<= 6 && current_function_stdarg
)
7006 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
7008 rtx mem
= XEXP (XVECEXP (PATTERN (insn
), 0, i
), 0);
7011 set_mem_alias_set (mem
, get_varargs_alias_set ());
7014 /* We need to set the FRAME_RELATED flag on all SETs
7015 inside the store-multiple pattern.
7017 However, we must not emit DWARF records for registers 2..5
7018 if they are stored for use by variable arguments ...
7020 ??? Unfortunately, it is not enough to simply not the
7021 FRAME_RELATED flags for those SETs, because the first SET
7022 of the PARALLEL is always treated as if it had the flag
7023 set, even if it does not. Therefore we emit a new pattern
7024 without those registers as REG_FRAME_RELATED_EXPR note. */
7028 rtx pat
= PATTERN (insn
);
7030 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
7031 if (GET_CODE (XVECEXP (pat
, 0, i
)) == SET
)
7032 RTX_FRAME_RELATED_P (XVECEXP (pat
, 0, i
)) = 1;
7034 RTX_FRAME_RELATED_P (insn
) = 1;
7038 addr
= plus_constant (base
, offset
+ (6 - first
) * UNITS_PER_WORD
);
7039 note
= gen_store_multiple (gen_rtx_MEM (Pmode
, addr
),
7040 gen_rtx_REG (Pmode
, 6),
7041 GEN_INT (last
- 6 + 1));
7042 note
= PATTERN (note
);
7045 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
7046 note
, REG_NOTES (insn
));
7048 for (i
= 0; i
< XVECLEN (note
, 0); i
++)
7049 if (GET_CODE (XVECEXP (note
, 0, i
)) == SET
)
7050 RTX_FRAME_RELATED_P (XVECEXP (note
, 0, i
)) = 1;
7052 RTX_FRAME_RELATED_P (insn
) = 1;
7058 /* Generate insn to restore registers FIRST to LAST from
7059 the register save area located at offset OFFSET
7060 relative to register BASE. */
7063 restore_gprs (rtx base
, int offset
, int first
, int last
)
7067 addr
= plus_constant (base
, offset
);
7068 addr
= gen_rtx_MEM (Pmode
, addr
);
7069 set_mem_alias_set (addr
, get_frame_alias_set ());
7071 /* Special-case single register. */
7075 insn
= gen_movdi (gen_rtx_REG (Pmode
, first
), addr
);
7077 insn
= gen_movsi (gen_rtx_REG (Pmode
, first
), addr
);
7082 insn
= gen_load_multiple (gen_rtx_REG (Pmode
, first
),
7084 GEN_INT (last
- first
+ 1));
7088 /* Return insn sequence to load the GOT register. */
7090 static GTY(()) rtx got_symbol
;
7092 s390_load_got (void)
7098 got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
7099 SYMBOL_REF_FLAGS (got_symbol
) = SYMBOL_FLAG_LOCAL
;
7104 if (TARGET_CPU_ZARCH
)
7106 emit_move_insn (pic_offset_table_rtx
, got_symbol
);
7112 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, got_symbol
),
7113 UNSPEC_LTREL_OFFSET
);
7114 offset
= gen_rtx_CONST (Pmode
, offset
);
7115 offset
= force_const_mem (Pmode
, offset
);
7117 emit_move_insn (pic_offset_table_rtx
, offset
);
7119 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, XEXP (offset
, 0)),
7121 offset
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, offset
);
7123 emit_move_insn (pic_offset_table_rtx
, offset
);
7126 insns
= get_insns ();
7131 /* Expand the prologue into a bunch of separate insns. */
7134 s390_emit_prologue (void)
7142 /* Complete frame layout. */
7144 s390_update_frame_layout ();
7146 /* Annotate all constant pool references to let the scheduler know
7147 they implicitly use the base register. */
7149 push_topmost_sequence ();
7151 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7153 annotate_constant_pool_refs (&PATTERN (insn
));
7155 pop_topmost_sequence ();
7157 /* Choose best register to use for temp use within prologue.
7158 See below for why TPF must use the register 1. */
7160 if (!has_hard_reg_initial_val (Pmode
, RETURN_REGNUM
)
7161 && !current_function_is_leaf
7162 && !TARGET_TPF_PROFILING
)
7163 temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
7165 temp_reg
= gen_rtx_REG (Pmode
, 1);
7167 /* Save call saved gprs. */
7168 if (cfun_frame_layout
.first_save_gpr
!= -1)
7170 insn
= save_gprs (stack_pointer_rtx
,
7171 cfun_frame_layout
.gprs_offset
+
7172 UNITS_PER_WORD
* (cfun_frame_layout
.first_save_gpr
7173 - cfun_frame_layout
.first_save_gpr_slot
),
7174 cfun_frame_layout
.first_save_gpr
,
7175 cfun_frame_layout
.last_save_gpr
);
7179 /* Dummy insn to mark literal pool slot. */
7181 if (cfun
->machine
->base_reg
)
7182 emit_insn (gen_main_pool (cfun
->machine
->base_reg
));
7184 offset
= cfun_frame_layout
.f0_offset
;
7186 /* Save f0 and f2. */
7187 for (i
= 0; i
< 2; i
++)
7189 if (cfun_fpr_bit_p (i
))
7191 save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
7194 else if (!TARGET_PACKED_STACK
)
7198 /* Save f4 and f6. */
7199 offset
= cfun_frame_layout
.f4_offset
;
7200 for (i
= 2; i
< 4; i
++)
7202 if (cfun_fpr_bit_p (i
))
7204 insn
= save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
7207 /* If f4 and f6 are call clobbered they are saved due to stdargs and
7208 therefore are not frame related. */
7209 if (!call_really_used_regs
[i
+ 16])
7210 RTX_FRAME_RELATED_P (insn
) = 1;
7212 else if (!TARGET_PACKED_STACK
)
7216 if (TARGET_PACKED_STACK
7217 && cfun_save_high_fprs_p
7218 && cfun_frame_layout
.f8_offset
+ cfun_frame_layout
.high_fprs
* 8 > 0)
7220 offset
= (cfun_frame_layout
.f8_offset
7221 + (cfun_frame_layout
.high_fprs
- 1) * 8);
7223 for (i
= 15; i
> 7 && offset
>= 0; i
--)
7224 if (cfun_fpr_bit_p (i
))
7226 insn
= save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
7228 RTX_FRAME_RELATED_P (insn
) = 1;
7231 if (offset
>= cfun_frame_layout
.f8_offset
)
7235 if (!TARGET_PACKED_STACK
)
7236 next_fpr
= cfun_save_high_fprs_p
? 31 : 0;
7238 /* Decrement stack pointer. */
7240 if (cfun_frame_layout
.frame_size
> 0)
7242 rtx frame_off
= GEN_INT (-cfun_frame_layout
.frame_size
);
7244 if (s390_stack_size
)
7246 HOST_WIDE_INT stack_guard
;
7248 if (s390_stack_guard
)
7249 stack_guard
= s390_stack_guard
;
7252 /* If no value for stack guard is provided the smallest power of 2
7253 larger than the current frame size is chosen. */
7255 while (stack_guard
< cfun_frame_layout
.frame_size
)
7259 if (cfun_frame_layout
.frame_size
>= s390_stack_size
)
7261 warning (0, "frame size of function %qs is "
7262 HOST_WIDE_INT_PRINT_DEC
7263 " bytes exceeding user provided stack limit of "
7264 HOST_WIDE_INT_PRINT_DEC
" bytes. "
7265 "An unconditional trap is added.",
7266 current_function_name(), cfun_frame_layout
.frame_size
,
7268 emit_insn (gen_trap ());
7272 HOST_WIDE_INT stack_check_mask
= ((s390_stack_size
- 1)
7273 & ~(stack_guard
- 1));
7274 rtx t
= gen_rtx_AND (Pmode
, stack_pointer_rtx
,
7275 GEN_INT (stack_check_mask
));
7277 gen_cmpdi (t
, const0_rtx
);
7279 gen_cmpsi (t
, const0_rtx
);
7281 emit_insn (gen_conditional_trap (gen_rtx_EQ (CCmode
,
7282 gen_rtx_REG (CCmode
,
7289 if (s390_warn_framesize
> 0
7290 && cfun_frame_layout
.frame_size
>= s390_warn_framesize
)
7291 warning (0, "frame size of %qs is " HOST_WIDE_INT_PRINT_DEC
" bytes",
7292 current_function_name (), cfun_frame_layout
.frame_size
);
7294 if (s390_warn_dynamicstack_p
&& cfun
->calls_alloca
)
7295 warning (0, "%qs uses dynamic stack allocation", current_function_name ());
7297 /* Save incoming stack pointer into temp reg. */
7298 if (TARGET_BACKCHAIN
|| next_fpr
)
7299 insn
= emit_insn (gen_move_insn (temp_reg
, stack_pointer_rtx
));
7301 /* Subtract frame size from stack pointer. */
7303 if (DISP_IN_RANGE (INTVAL (frame_off
)))
7305 insn
= gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
7306 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
7308 insn
= emit_insn (insn
);
7312 if (!CONST_OK_FOR_K (INTVAL (frame_off
)))
7313 frame_off
= force_const_mem (Pmode
, frame_off
);
7315 insn
= emit_insn (gen_add2_insn (stack_pointer_rtx
, frame_off
));
7316 annotate_constant_pool_refs (&PATTERN (insn
));
7319 RTX_FRAME_RELATED_P (insn
) = 1;
7321 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
7322 gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
7323 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
7324 GEN_INT (-cfun_frame_layout
.frame_size
))),
7327 /* Set backchain. */
7329 if (TARGET_BACKCHAIN
)
7331 if (cfun_frame_layout
.backchain_offset
)
7332 addr
= gen_rtx_MEM (Pmode
,
7333 plus_constant (stack_pointer_rtx
,
7334 cfun_frame_layout
.backchain_offset
));
7336 addr
= gen_rtx_MEM (Pmode
, stack_pointer_rtx
);
7337 set_mem_alias_set (addr
, get_frame_alias_set ());
7338 insn
= emit_insn (gen_move_insn (addr
, temp_reg
));
7341 /* If we support asynchronous exceptions (e.g. for Java),
7342 we need to make sure the backchain pointer is set up
7343 before any possibly trapping memory access. */
7345 if (TARGET_BACKCHAIN
&& flag_non_call_exceptions
)
7347 addr
= gen_rtx_MEM (BLKmode
, gen_rtx_SCRATCH (VOIDmode
));
7348 emit_insn (gen_rtx_CLOBBER (VOIDmode
, addr
));
7352 /* Save fprs 8 - 15 (64 bit ABI). */
7354 if (cfun_save_high_fprs_p
&& next_fpr
)
7356 insn
= emit_insn (gen_add2_insn (temp_reg
,
7357 GEN_INT (cfun_frame_layout
.f8_offset
)));
7361 for (i
= 24; i
<= next_fpr
; i
++)
7362 if (cfun_fpr_bit_p (i
- 16))
7364 rtx addr
= plus_constant (stack_pointer_rtx
,
7365 cfun_frame_layout
.frame_size
7366 + cfun_frame_layout
.f8_offset
7369 insn
= save_fpr (temp_reg
, offset
, i
);
7371 RTX_FRAME_RELATED_P (insn
) = 1;
7373 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
7374 gen_rtx_SET (VOIDmode
,
7375 gen_rtx_MEM (DFmode
, addr
),
7376 gen_rtx_REG (DFmode
, i
)),
7381 /* Set frame pointer, if needed. */
7383 if (frame_pointer_needed
)
7385 insn
= emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
);
7386 RTX_FRAME_RELATED_P (insn
) = 1;
7389 /* Set up got pointer, if needed. */
7391 if (flag_pic
&& regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
])
7393 rtx insns
= s390_load_got ();
7395 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
7397 annotate_constant_pool_refs (&PATTERN (insn
));
7399 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD
, NULL_RTX
,
7406 if (TARGET_TPF_PROFILING
)
7408 /* Generate a BAS instruction to serve as a function
7409 entry intercept to facilitate the use of tracing
7410 algorithms located at the branch target. */
7411 emit_insn (gen_prologue_tpf ());
7413 /* Emit a blockage here so that all code
7414 lies between the profiling mechanisms. */
7415 emit_insn (gen_blockage ());
7419 /* Expand the epilogue into a bunch of separate insns. */
7422 s390_emit_epilogue (bool sibcall
)
7424 rtx frame_pointer
, return_reg
;
7425 int area_bottom
, area_top
, offset
= 0;
7430 if (TARGET_TPF_PROFILING
)
7433 /* Generate a BAS instruction to serve as a function
7434 entry intercept to facilitate the use of tracing
7435 algorithms located at the branch target. */
7437 /* Emit a blockage here so that all code
7438 lies between the profiling mechanisms. */
7439 emit_insn (gen_blockage ());
7441 emit_insn (gen_epilogue_tpf ());
7444 /* Check whether to use frame or stack pointer for restore. */
7446 frame_pointer
= (frame_pointer_needed
7447 ? hard_frame_pointer_rtx
: stack_pointer_rtx
);
7449 s390_frame_area (&area_bottom
, &area_top
);
7451 /* Check whether we can access the register save area.
7452 If not, increment the frame pointer as required. */
7454 if (area_top
<= area_bottom
)
7456 /* Nothing to restore. */
7458 else if (DISP_IN_RANGE (cfun_frame_layout
.frame_size
+ area_bottom
)
7459 && DISP_IN_RANGE (cfun_frame_layout
.frame_size
+ area_top
- 1))
7461 /* Area is in range. */
7462 offset
= cfun_frame_layout
.frame_size
;
7466 rtx insn
, frame_off
;
7468 offset
= area_bottom
< 0 ? -area_bottom
: 0;
7469 frame_off
= GEN_INT (cfun_frame_layout
.frame_size
- offset
);
7471 if (DISP_IN_RANGE (INTVAL (frame_off
)))
7473 insn
= gen_rtx_SET (VOIDmode
, frame_pointer
,
7474 gen_rtx_PLUS (Pmode
, frame_pointer
, frame_off
));
7475 insn
= emit_insn (insn
);
7479 if (!CONST_OK_FOR_K (INTVAL (frame_off
)))
7480 frame_off
= force_const_mem (Pmode
, frame_off
);
7482 insn
= emit_insn (gen_add2_insn (frame_pointer
, frame_off
));
7483 annotate_constant_pool_refs (&PATTERN (insn
));
7487 /* Restore call saved fprs. */
7491 if (cfun_save_high_fprs_p
)
7493 next_offset
= cfun_frame_layout
.f8_offset
;
7494 for (i
= 24; i
< 32; i
++)
7496 if (cfun_fpr_bit_p (i
- 16))
7498 restore_fpr (frame_pointer
,
7499 offset
+ next_offset
, i
);
7508 next_offset
= cfun_frame_layout
.f4_offset
;
7509 for (i
= 18; i
< 20; i
++)
7511 if (cfun_fpr_bit_p (i
- 16))
7513 restore_fpr (frame_pointer
,
7514 offset
+ next_offset
, i
);
7517 else if (!TARGET_PACKED_STACK
)
7523 /* Return register. */
7525 return_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
7527 /* Restore call saved gprs. */
7529 if (cfun_frame_layout
.first_restore_gpr
!= -1)
7534 /* Check for global register and save them
7535 to stack location from where they get restored. */
7537 for (i
= cfun_frame_layout
.first_restore_gpr
;
7538 i
<= cfun_frame_layout
.last_restore_gpr
;
7541 /* These registers are special and need to be
7542 restored in any case. */
7543 if (i
== STACK_POINTER_REGNUM
7544 || i
== RETURN_REGNUM
7546 || (flag_pic
&& i
== (int)PIC_OFFSET_TABLE_REGNUM
))
7551 addr
= plus_constant (frame_pointer
,
7552 offset
+ cfun_frame_layout
.gprs_offset
7553 + (i
- cfun_frame_layout
.first_save_gpr_slot
)
7555 addr
= gen_rtx_MEM (Pmode
, addr
);
7556 set_mem_alias_set (addr
, get_frame_alias_set ());
7557 emit_move_insn (addr
, gen_rtx_REG (Pmode
, i
));
7563 /* Fetch return address from stack before load multiple,
7564 this will do good for scheduling. */
7566 if (cfun_frame_layout
.save_return_addr_p
7567 || (cfun_frame_layout
.first_restore_gpr
< BASE_REGNUM
7568 && cfun_frame_layout
.last_restore_gpr
> RETURN_REGNUM
))
7570 int return_regnum
= find_unused_clobbered_reg();
7573 return_reg
= gen_rtx_REG (Pmode
, return_regnum
);
7575 addr
= plus_constant (frame_pointer
,
7576 offset
+ cfun_frame_layout
.gprs_offset
7578 - cfun_frame_layout
.first_save_gpr_slot
)
7580 addr
= gen_rtx_MEM (Pmode
, addr
);
7581 set_mem_alias_set (addr
, get_frame_alias_set ());
7582 emit_move_insn (return_reg
, addr
);
7586 insn
= restore_gprs (frame_pointer
,
7587 offset
+ cfun_frame_layout
.gprs_offset
7588 + (cfun_frame_layout
.first_restore_gpr
7589 - cfun_frame_layout
.first_save_gpr_slot
)
7591 cfun_frame_layout
.first_restore_gpr
,
7592 cfun_frame_layout
.last_restore_gpr
);
7599 /* Return to caller. */
7601 p
= rtvec_alloc (2);
7603 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
7604 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
, return_reg
);
7605 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
7610 /* Return the size in bytes of a function argument of
7611 type TYPE and/or mode MODE. At least one of TYPE or
7612 MODE must be specified. */
7615 s390_function_arg_size (enum machine_mode mode
, tree type
)
7618 return int_size_in_bytes (type
);
7620 /* No type info available for some library calls ... */
7621 if (mode
!= BLKmode
)
7622 return GET_MODE_SIZE (mode
);
7624 /* If we have neither type nor mode, abort */
7628 /* Return true if a function argument of type TYPE and mode MODE
7629 is to be passed in a floating-point register, if available. */
7632 s390_function_arg_float (enum machine_mode mode
, tree type
)
7634 int size
= s390_function_arg_size (mode
, type
);
7638 /* Soft-float changes the ABI: no floating-point registers are used. */
7639 if (TARGET_SOFT_FLOAT
)
7642 /* No type info available for some library calls ... */
7644 return mode
== SFmode
|| mode
== DFmode
|| mode
== SDmode
|| mode
== DDmode
;
7646 /* The ABI says that record types with a single member are treated
7647 just like that member would be. */
7648 while (TREE_CODE (type
) == RECORD_TYPE
)
7650 tree field
, single
= NULL_TREE
;
7652 for (field
= TYPE_FIELDS (type
); field
; field
= TREE_CHAIN (field
))
7654 if (TREE_CODE (field
) != FIELD_DECL
)
7657 if (single
== NULL_TREE
)
7658 single
= TREE_TYPE (field
);
7663 if (single
== NULL_TREE
)
7669 return TREE_CODE (type
) == REAL_TYPE
;
7672 /* Return true if a function argument of type TYPE and mode MODE
7673 is to be passed in an integer register, or a pair of integer
7674 registers, if available. */
7677 s390_function_arg_integer (enum machine_mode mode
, tree type
)
7679 int size
= s390_function_arg_size (mode
, type
);
7683 /* No type info available for some library calls ... */
7685 return GET_MODE_CLASS (mode
) == MODE_INT
7686 || (TARGET_SOFT_FLOAT
&& SCALAR_FLOAT_MODE_P (mode
));
7688 /* We accept small integral (and similar) types. */
7689 if (INTEGRAL_TYPE_P (type
)
7690 || POINTER_TYPE_P (type
)
7691 || TREE_CODE (type
) == OFFSET_TYPE
7692 || (TARGET_SOFT_FLOAT
&& TREE_CODE (type
) == REAL_TYPE
))
7695 /* We also accept structs of size 1, 2, 4, 8 that are not
7696 passed in floating-point registers. */
7697 if (AGGREGATE_TYPE_P (type
)
7698 && exact_log2 (size
) >= 0
7699 && !s390_function_arg_float (mode
, type
))
7705 /* Return 1 if a function argument of type TYPE and mode MODE
7706 is to be passed by reference. The ABI specifies that only
7707 structures of size 1, 2, 4, or 8 bytes are passed by value,
7708 all other structures (and complex numbers) are passed by
7712 s390_pass_by_reference (CUMULATIVE_ARGS
*ca ATTRIBUTE_UNUSED
,
7713 enum machine_mode mode
, tree type
,
7714 bool named ATTRIBUTE_UNUSED
)
7716 int size
= s390_function_arg_size (mode
, type
);
7722 if (AGGREGATE_TYPE_P (type
) && exact_log2 (size
) < 0)
7725 if (TREE_CODE (type
) == COMPLEX_TYPE
7726 || TREE_CODE (type
) == VECTOR_TYPE
)
7733 /* Update the data in CUM to advance over an argument of mode MODE and
7734 data type TYPE. (TYPE is null for libcalls where that information
7735 may not be available.). The boolean NAMED specifies whether the
7736 argument is a named argument (as opposed to an unnamed argument
7737 matching an ellipsis). */
7740 s390_function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
7741 tree type
, int named ATTRIBUTE_UNUSED
)
7743 if (s390_function_arg_float (mode
, type
))
7747 else if (s390_function_arg_integer (mode
, type
))
7749 int size
= s390_function_arg_size (mode
, type
);
7750 cum
->gprs
+= ((size
+ UNITS_PER_WORD
-1) / UNITS_PER_WORD
);
7756 /* Define where to put the arguments to a function.
7757 Value is zero to push the argument on the stack,
7758 or a hard register in which to store the argument.
7760 MODE is the argument's machine mode.
7761 TYPE is the data type of the argument (as a tree).
7762 This is null for libcalls where that information may
7764 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7765 the preceding args and about the function being called.
7766 NAMED is nonzero if this argument is a named parameter
7767 (otherwise it is an extra parameter matching an ellipsis).
7769 On S/390, we use general purpose registers 2 through 6 to
7770 pass integer, pointer, and certain structure arguments, and
7771 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
7772 to pass floating point arguments. All remaining arguments
7773 are pushed to the stack. */
7776 s390_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
, tree type
,
7777 int named ATTRIBUTE_UNUSED
)
7779 if (s390_function_arg_float (mode
, type
))
7781 if (cum
->fprs
+ 1 > FP_ARG_NUM_REG
)
7784 return gen_rtx_REG (mode
, cum
->fprs
+ 16);
7786 else if (s390_function_arg_integer (mode
, type
))
7788 int size
= s390_function_arg_size (mode
, type
);
7789 int n_gprs
= (size
+ UNITS_PER_WORD
-1) / UNITS_PER_WORD
;
7791 if (cum
->gprs
+ n_gprs
> GP_ARG_NUM_REG
)
7794 return gen_rtx_REG (mode
, cum
->gprs
+ 2);
7797 /* After the real arguments, expand_call calls us once again
7798 with a void_type_node type. Whatever we return here is
7799 passed as operand 2 to the call expanders.
7801 We don't need this feature ... */
7802 else if (type
== void_type_node
)
7808 /* Return true if return values of type TYPE should be returned
7809 in a memory buffer whose address is passed by the caller as
7810 hidden first argument. */
7813 s390_return_in_memory (tree type
, tree fundecl ATTRIBUTE_UNUSED
)
7815 /* We accept small integral (and similar) types. */
7816 if (INTEGRAL_TYPE_P (type
)
7817 || POINTER_TYPE_P (type
)
7818 || TREE_CODE (type
) == OFFSET_TYPE
7819 || TREE_CODE (type
) == REAL_TYPE
)
7820 return int_size_in_bytes (type
) > 8;
7822 /* Aggregates and similar constructs are always returned
7824 if (AGGREGATE_TYPE_P (type
)
7825 || TREE_CODE (type
) == COMPLEX_TYPE
7826 || TREE_CODE (type
) == VECTOR_TYPE
)
7829 /* ??? We get called on all sorts of random stuff from
7830 aggregate_value_p. We can't abort, but it's not clear
7831 what's safe to return. Pretend it's a struct I guess. */
7835 /* Define where to return a (scalar) value of type TYPE.
7836 If TYPE is null, define where to return a (scalar)
7837 value of mode MODE from a libcall. */
7840 s390_function_value (tree type
, enum machine_mode mode
)
7844 int unsignedp
= TYPE_UNSIGNED (type
);
7845 mode
= promote_mode (type
, TYPE_MODE (type
), &unsignedp
, 1);
7848 gcc_assert (GET_MODE_CLASS (mode
) == MODE_INT
|| SCALAR_FLOAT_MODE_P (mode
));
7849 gcc_assert (GET_MODE_SIZE (mode
) <= 8);
7851 if (TARGET_HARD_FLOAT
&& SCALAR_FLOAT_MODE_P (mode
))
7852 return gen_rtx_REG (mode
, 16);
7854 return gen_rtx_REG (mode
, 2);
7858 /* Create and return the va_list datatype.
7860 On S/390, va_list is an array type equivalent to
7862 typedef struct __va_list_tag
7866 void *__overflow_arg_area;
7867 void *__reg_save_area;
7870 where __gpr and __fpr hold the number of general purpose
7871 or floating point arguments used up to now, respectively,
7872 __overflow_arg_area points to the stack location of the
7873 next argument passed on the stack, and __reg_save_area
7874 always points to the start of the register area in the
7875 call frame of the current function. The function prologue
7876 saves all registers used for argument passing into this
7877 area if the function uses variable arguments. */
7880 s390_build_builtin_va_list (void)
7882 tree f_gpr
, f_fpr
, f_ovf
, f_sav
, record
, type_decl
;
7884 record
= lang_hooks
.types
.make_type (RECORD_TYPE
);
7887 build_decl (TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
7889 f_gpr
= build_decl (FIELD_DECL
, get_identifier ("__gpr"),
7890 long_integer_type_node
);
7891 f_fpr
= build_decl (FIELD_DECL
, get_identifier ("__fpr"),
7892 long_integer_type_node
);
7893 f_ovf
= build_decl (FIELD_DECL
, get_identifier ("__overflow_arg_area"),
7895 f_sav
= build_decl (FIELD_DECL
, get_identifier ("__reg_save_area"),
7898 va_list_gpr_counter_field
= f_gpr
;
7899 va_list_fpr_counter_field
= f_fpr
;
7901 DECL_FIELD_CONTEXT (f_gpr
) = record
;
7902 DECL_FIELD_CONTEXT (f_fpr
) = record
;
7903 DECL_FIELD_CONTEXT (f_ovf
) = record
;
7904 DECL_FIELD_CONTEXT (f_sav
) = record
;
7906 TREE_CHAIN (record
) = type_decl
;
7907 TYPE_NAME (record
) = type_decl
;
7908 TYPE_FIELDS (record
) = f_gpr
;
7909 TREE_CHAIN (f_gpr
) = f_fpr
;
7910 TREE_CHAIN (f_fpr
) = f_ovf
;
7911 TREE_CHAIN (f_ovf
) = f_sav
;
7913 layout_type (record
);
7915 /* The correct type is an array type of one element. */
7916 return build_array_type (record
, build_index_type (size_zero_node
));
7919 /* Implement va_start by filling the va_list structure VALIST.
7920 STDARG_P is always true, and ignored.
7921 NEXTARG points to the first anonymous stack argument.
7923 The following global variables are used to initialize
7924 the va_list structure:
7926 current_function_args_info:
7927 holds number of gprs and fprs used for named arguments.
7928 current_function_arg_offset_rtx:
7929 holds the offset of the first anonymous stack argument
7930 (relative to the virtual arg pointer). */
7933 s390_va_start (tree valist
, rtx nextarg ATTRIBUTE_UNUSED
)
7935 HOST_WIDE_INT n_gpr
, n_fpr
;
7937 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
7938 tree gpr
, fpr
, ovf
, sav
, t
;
7940 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
7941 f_fpr
= TREE_CHAIN (f_gpr
);
7942 f_ovf
= TREE_CHAIN (f_fpr
);
7943 f_sav
= TREE_CHAIN (f_ovf
);
7945 valist
= build_va_arg_indirect_ref (valist
);
7946 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
7947 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
7948 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
7949 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
7951 /* Count number of gp and fp argument registers used. */
7953 n_gpr
= current_function_args_info
.gprs
;
7954 n_fpr
= current_function_args_info
.fprs
;
7956 if (cfun
->va_list_gpr_size
)
7958 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (gpr
), gpr
,
7959 build_int_cst (NULL_TREE
, n_gpr
));
7960 TREE_SIDE_EFFECTS (t
) = 1;
7961 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7964 if (cfun
->va_list_fpr_size
)
7966 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (fpr
), fpr
,
7967 build_int_cst (NULL_TREE
, n_fpr
));
7968 TREE_SIDE_EFFECTS (t
) = 1;
7969 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7972 /* Find the overflow area. */
7973 if (n_gpr
+ cfun
->va_list_gpr_size
> GP_ARG_NUM_REG
7974 || n_fpr
+ cfun
->va_list_fpr_size
> FP_ARG_NUM_REG
)
7976 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
7978 off
= INTVAL (current_function_arg_offset_rtx
);
7979 off
= off
< 0 ? 0 : off
;
7980 if (TARGET_DEBUG_ARG
)
7981 fprintf (stderr
, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
7982 (int)n_gpr
, (int)n_fpr
, off
);
7984 t
= build2 (PLUS_EXPR
, TREE_TYPE (ovf
), t
, build_int_cst (NULL_TREE
, off
));
7986 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (ovf
), ovf
, t
);
7987 TREE_SIDE_EFFECTS (t
) = 1;
7988 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7991 /* Find the register save area. */
7992 if ((cfun
->va_list_gpr_size
&& n_gpr
< GP_ARG_NUM_REG
)
7993 || (cfun
->va_list_fpr_size
&& n_fpr
< FP_ARG_NUM_REG
))
7995 t
= make_tree (TREE_TYPE (sav
), return_address_pointer_rtx
);
7996 t
= build2 (PLUS_EXPR
, TREE_TYPE (sav
), t
,
7997 build_int_cst (NULL_TREE
, -RETURN_REGNUM
* UNITS_PER_WORD
));
7999 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (sav
), sav
, t
);
8000 TREE_SIDE_EFFECTS (t
) = 1;
8001 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
8005 /* Implement va_arg by updating the va_list structure
8006 VALIST as required to retrieve an argument of type
8007 TYPE, and returning that argument.
8009 Generates code equivalent to:
8011 if (integral value) {
8012 if (size <= 4 && args.gpr < 5 ||
8013 size > 4 && args.gpr < 4 )
8014 ret = args.reg_save_area[args.gpr+8]
8016 ret = *args.overflow_arg_area++;
8017 } else if (float value) {
8019 ret = args.reg_save_area[args.fpr+64]
8021 ret = *args.overflow_arg_area++;
8022 } else if (aggregate value) {
8024 ret = *args.reg_save_area[args.gpr]
8026 ret = **args.overflow_arg_area++;
8030 s390_gimplify_va_arg (tree valist
, tree type
, tree
*pre_p
,
8031 tree
*post_p ATTRIBUTE_UNUSED
)
8033 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
8034 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
8035 int indirect_p
, size
, n_reg
, sav_ofs
, sav_scale
, max_reg
;
8036 tree lab_false
, lab_over
, addr
;
8038 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
8039 f_fpr
= TREE_CHAIN (f_gpr
);
8040 f_ovf
= TREE_CHAIN (f_fpr
);
8041 f_sav
= TREE_CHAIN (f_ovf
);
8043 valist
= build_va_arg_indirect_ref (valist
);
8044 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
8045 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
8046 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
8047 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
8049 size
= int_size_in_bytes (type
);
8051 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
8053 if (TARGET_DEBUG_ARG
)
8055 fprintf (stderr
, "va_arg: aggregate type");
8059 /* Aggregates are passed by reference. */
8064 /* kernel stack layout on 31 bit: It is assumed here that no padding
8065 will be added by s390_frame_info because for va_args always an even
8066 number of gprs has to be saved r15-r2 = 14 regs. */
8067 sav_ofs
= 2 * UNITS_PER_WORD
;
8068 sav_scale
= UNITS_PER_WORD
;
8069 size
= UNITS_PER_WORD
;
8070 max_reg
= GP_ARG_NUM_REG
- n_reg
;
8072 else if (s390_function_arg_float (TYPE_MODE (type
), type
))
8074 if (TARGET_DEBUG_ARG
)
8076 fprintf (stderr
, "va_arg: float type");
8080 /* FP args go in FP registers, if present. */
8084 sav_ofs
= 16 * UNITS_PER_WORD
;
8086 max_reg
= FP_ARG_NUM_REG
- n_reg
;
8090 if (TARGET_DEBUG_ARG
)
8092 fprintf (stderr
, "va_arg: other type");
8096 /* Otherwise into GP registers. */
8099 n_reg
= (size
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
8101 /* kernel stack layout on 31 bit: It is assumed here that no padding
8102 will be added by s390_frame_info because for va_args always an even
8103 number of gprs has to be saved r15-r2 = 14 regs. */
8104 sav_ofs
= 2 * UNITS_PER_WORD
;
8106 if (size
< UNITS_PER_WORD
)
8107 sav_ofs
+= UNITS_PER_WORD
- size
;
8109 sav_scale
= UNITS_PER_WORD
;
8110 max_reg
= GP_ARG_NUM_REG
- n_reg
;
8113 /* Pull the value out of the saved registers ... */
8115 lab_false
= create_artificial_label ();
8116 lab_over
= create_artificial_label ();
8117 addr
= create_tmp_var (ptr_type_node
, "addr");
8118 DECL_POINTER_ALIAS_SET (addr
) = get_varargs_alias_set ();
8120 t
= fold_convert (TREE_TYPE (reg
), size_int (max_reg
));
8121 t
= build2 (GT_EXPR
, boolean_type_node
, reg
, t
);
8122 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
8123 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
8124 gimplify_and_add (t
, pre_p
);
8126 t
= build2 (PLUS_EXPR
, ptr_type_node
, sav
,
8127 fold_convert (ptr_type_node
, size_int (sav_ofs
)));
8128 u
= build2 (MULT_EXPR
, TREE_TYPE (reg
), reg
,
8129 fold_convert (TREE_TYPE (reg
), size_int (sav_scale
)));
8130 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
, fold_convert (ptr_type_node
, u
));
8132 t
= build2 (GIMPLE_MODIFY_STMT
, void_type_node
, addr
, t
);
8133 gimplify_and_add (t
, pre_p
);
8135 t
= build1 (GOTO_EXPR
, void_type_node
, lab_over
);
8136 gimplify_and_add (t
, pre_p
);
8138 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false
);
8139 append_to_statement_list (t
, pre_p
);
8142 /* ... Otherwise out of the overflow area. */
8145 if (size
< UNITS_PER_WORD
)
8146 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
,
8147 fold_convert (ptr_type_node
, size_int (UNITS_PER_WORD
- size
)));
8149 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
8151 u
= build2 (GIMPLE_MODIFY_STMT
, void_type_node
, addr
, t
);
8152 gimplify_and_add (u
, pre_p
);
8154 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
,
8155 fold_convert (ptr_type_node
, size_int (size
)));
8156 t
= build2 (GIMPLE_MODIFY_STMT
, ptr_type_node
, ovf
, t
);
8157 gimplify_and_add (t
, pre_p
);
8159 t
= build1 (LABEL_EXPR
, void_type_node
, lab_over
);
8160 append_to_statement_list (t
, pre_p
);
8163 /* Increment register save count. */
8165 u
= build2 (PREINCREMENT_EXPR
, TREE_TYPE (reg
), reg
,
8166 fold_convert (TREE_TYPE (reg
), size_int (n_reg
)));
8167 gimplify_and_add (u
, pre_p
);
8171 t
= build_pointer_type (build_pointer_type (type
));
8172 addr
= fold_convert (t
, addr
);
8173 addr
= build_va_arg_indirect_ref (addr
);
8177 t
= build_pointer_type (type
);
8178 addr
= fold_convert (t
, addr
);
8181 return build_va_arg_indirect_ref (addr
);
8189 S390_BUILTIN_THREAD_POINTER
,
8190 S390_BUILTIN_SET_THREAD_POINTER
,
8195 static unsigned int const code_for_builtin_64
[S390_BUILTIN_max
] = {
8200 static unsigned int const code_for_builtin_31
[S390_BUILTIN_max
] = {
8206 s390_init_builtins (void)
8210 ftype
= build_function_type (ptr_type_node
, void_list_node
);
8211 add_builtin_function ("__builtin_thread_pointer", ftype
,
8212 S390_BUILTIN_THREAD_POINTER
, BUILT_IN_MD
,
8215 ftype
= build_function_type_list (void_type_node
, ptr_type_node
, NULL_TREE
);
8216 add_builtin_function ("__builtin_set_thread_pointer", ftype
,
8217 S390_BUILTIN_SET_THREAD_POINTER
, BUILT_IN_MD
,
8221 /* Expand an expression EXP that calls a built-in function,
8222 with result going to TARGET if that's convenient
8223 (and in mode MODE if that's convenient).
8224 SUBTARGET may be used as the target for computing one of EXP's operands.
8225 IGNORE is nonzero if the value is to be ignored. */
8228 s390_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
8229 enum machine_mode mode ATTRIBUTE_UNUSED
,
8230 int ignore ATTRIBUTE_UNUSED
)
8234 unsigned int const *code_for_builtin
=
8235 TARGET_64BIT
? code_for_builtin_64
: code_for_builtin_31
;
8237 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8238 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8239 enum insn_code icode
;
8240 rtx op
[MAX_ARGS
], pat
;
8244 call_expr_arg_iterator iter
;
8246 if (fcode
>= S390_BUILTIN_max
)
8247 internal_error ("bad builtin fcode");
8248 icode
= code_for_builtin
[fcode
];
8250 internal_error ("bad builtin fcode");
8252 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
8255 FOR_EACH_CALL_EXPR_ARG (arg
, iter
, exp
)
8257 const struct insn_operand_data
*insn_op
;
8259 if (arg
== error_mark_node
)
8261 if (arity
> MAX_ARGS
)
8264 insn_op
= &insn_data
[icode
].operand
[arity
+ nonvoid
];
8266 op
[arity
] = expand_expr (arg
, NULL_RTX
, insn_op
->mode
, 0);
8268 if (!(*insn_op
->predicate
) (op
[arity
], insn_op
->mode
))
8269 op
[arity
] = copy_to_mode_reg (insn_op
->mode
, op
[arity
]);
8275 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8277 || GET_MODE (target
) != tmode
8278 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8279 target
= gen_reg_rtx (tmode
);
8285 pat
= GEN_FCN (icode
) (target
);
8289 pat
= GEN_FCN (icode
) (target
, op
[0]);
8291 pat
= GEN_FCN (icode
) (op
[0]);
8294 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
8310 /* Output assembly code for the trampoline template to
8313 On S/390, we use gpr 1 internally in the trampoline code;
8314 gpr 0 is used to hold the static chain. */
8317 s390_trampoline_template (FILE *file
)
8320 op
[0] = gen_rtx_REG (Pmode
, 0);
8321 op
[1] = gen_rtx_REG (Pmode
, 1);
8325 output_asm_insn ("basr\t%1,0", op
);
8326 output_asm_insn ("lmg\t%0,%1,14(%1)", op
);
8327 output_asm_insn ("br\t%1", op
);
8328 ASM_OUTPUT_SKIP (file
, (HOST_WIDE_INT
)(TRAMPOLINE_SIZE
- 10));
8332 output_asm_insn ("basr\t%1,0", op
);
8333 output_asm_insn ("lm\t%0,%1,6(%1)", op
);
8334 output_asm_insn ("br\t%1", op
);
8335 ASM_OUTPUT_SKIP (file
, (HOST_WIDE_INT
)(TRAMPOLINE_SIZE
- 8));
8339 /* Emit RTL insns to initialize the variable parts of a trampoline.
8340 FNADDR is an RTX for the address of the function's pure code.
8341 CXT is an RTX for the static chain value for the function. */
8344 s390_initialize_trampoline (rtx addr
, rtx fnaddr
, rtx cxt
)
8346 emit_move_insn (gen_rtx_MEM (Pmode
,
8347 memory_address (Pmode
,
8348 plus_constant (addr
, (TARGET_64BIT
? 16 : 8)))), cxt
);
8349 emit_move_insn (gen_rtx_MEM (Pmode
,
8350 memory_address (Pmode
,
8351 plus_constant (addr
, (TARGET_64BIT
? 24 : 12)))), fnaddr
);
8354 /* Return rtx for 64-bit constant formed from the 32-bit subwords
8355 LOW and HIGH, independent of the host word size. */
8358 s390_gen_rtx_const_DI (int high
, int low
)
8360 #if HOST_BITS_PER_WIDE_INT >= 64
8362 val
= (HOST_WIDE_INT
)high
;
8364 val
|= (HOST_WIDE_INT
)low
;
8366 return GEN_INT (val
);
8368 #if HOST_BITS_PER_WIDE_INT >= 32
8369 return immed_double_const ((HOST_WIDE_INT
)low
, (HOST_WIDE_INT
)high
, DImode
);
8376 /* Output assembler code to FILE to increment profiler label # LABELNO
8377 for profiling a function entry. */
8380 s390_function_profiler (FILE *file
, int labelno
)
8385 ASM_GENERATE_INTERNAL_LABEL (label
, "LP", labelno
);
8387 fprintf (file
, "# function profiler \n");
8389 op
[0] = gen_rtx_REG (Pmode
, RETURN_REGNUM
);
8390 op
[1] = gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
8391 op
[1] = gen_rtx_MEM (Pmode
, plus_constant (op
[1], UNITS_PER_WORD
));
8393 op
[2] = gen_rtx_REG (Pmode
, 1);
8394 op
[3] = gen_rtx_SYMBOL_REF (Pmode
, label
);
8395 SYMBOL_REF_FLAGS (op
[3]) = SYMBOL_FLAG_LOCAL
;
8397 op
[4] = gen_rtx_SYMBOL_REF (Pmode
, "_mcount");
8400 op
[4] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[4]), UNSPEC_PLT
);
8401 op
[4] = gen_rtx_CONST (Pmode
, op
[4]);
8406 output_asm_insn ("stg\t%0,%1", op
);
8407 output_asm_insn ("larl\t%2,%3", op
);
8408 output_asm_insn ("brasl\t%0,%4", op
);
8409 output_asm_insn ("lg\t%0,%1", op
);
8413 op
[6] = gen_label_rtx ();
8415 output_asm_insn ("st\t%0,%1", op
);
8416 output_asm_insn ("bras\t%2,%l6", op
);
8417 output_asm_insn (".long\t%4", op
);
8418 output_asm_insn (".long\t%3", op
);
8419 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
8420 output_asm_insn ("l\t%0,0(%2)", op
);
8421 output_asm_insn ("l\t%2,4(%2)", op
);
8422 output_asm_insn ("basr\t%0,%0", op
);
8423 output_asm_insn ("l\t%0,%1", op
);
8427 op
[5] = gen_label_rtx ();
8428 op
[6] = gen_label_rtx ();
8430 output_asm_insn ("st\t%0,%1", op
);
8431 output_asm_insn ("bras\t%2,%l6", op
);
8432 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[5]));
8433 output_asm_insn (".long\t%4-%l5", op
);
8434 output_asm_insn (".long\t%3-%l5", op
);
8435 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
8436 output_asm_insn ("lr\t%0,%2", op
);
8437 output_asm_insn ("a\t%0,0(%2)", op
);
8438 output_asm_insn ("a\t%2,4(%2)", op
);
8439 output_asm_insn ("basr\t%0,%0", op
);
8440 output_asm_insn ("l\t%0,%1", op
);
8444 /* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
8445 into its SYMBOL_REF_FLAGS. */
8448 s390_encode_section_info (tree decl
, rtx rtl
, int first
)
8450 default_encode_section_info (decl
, rtl
, first
);
8452 /* If a variable has a forced alignment to < 2 bytes, mark it with
8453 SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL operand. */
8454 if (TREE_CODE (decl
) == VAR_DECL
8455 && DECL_USER_ALIGN (decl
) && DECL_ALIGN (decl
) < 16)
8456 SYMBOL_REF_FLAGS (XEXP (rtl
, 0)) |= SYMBOL_FLAG_ALIGN1
;
8459 /* Output thunk to FILE that implements a C++ virtual function call (with
8460 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
8461 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
8462 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
8463 relative to the resulting this pointer. */
8466 s390_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
8467 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
8473 /* Operand 0 is the target function. */
8474 op
[0] = XEXP (DECL_RTL (function
), 0);
8475 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (op
[0]))
8478 op
[0] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[0]),
8479 TARGET_64BIT
? UNSPEC_PLT
: UNSPEC_GOT
);
8480 op
[0] = gen_rtx_CONST (Pmode
, op
[0]);
8483 /* Operand 1 is the 'this' pointer. */
8484 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
8485 op
[1] = gen_rtx_REG (Pmode
, 3);
8487 op
[1] = gen_rtx_REG (Pmode
, 2);
8489 /* Operand 2 is the delta. */
8490 op
[2] = GEN_INT (delta
);
8492 /* Operand 3 is the vcall_offset. */
8493 op
[3] = GEN_INT (vcall_offset
);
8495 /* Operand 4 is the temporary register. */
8496 op
[4] = gen_rtx_REG (Pmode
, 1);
8498 /* Operands 5 to 8 can be used as labels. */
8504 /* Operand 9 can be used for temporary register. */
8507 /* Generate code. */
8510 /* Setup literal pool pointer if required. */
8511 if ((!DISP_IN_RANGE (delta
)
8512 && !CONST_OK_FOR_K (delta
)
8513 && !CONST_OK_FOR_Os (delta
))
8514 || (!DISP_IN_RANGE (vcall_offset
)
8515 && !CONST_OK_FOR_K (vcall_offset
)
8516 && !CONST_OK_FOR_Os (vcall_offset
)))
8518 op
[5] = gen_label_rtx ();
8519 output_asm_insn ("larl\t%4,%5", op
);
8522 /* Add DELTA to this pointer. */
8525 if (CONST_OK_FOR_J (delta
))
8526 output_asm_insn ("la\t%1,%2(%1)", op
);
8527 else if (DISP_IN_RANGE (delta
))
8528 output_asm_insn ("lay\t%1,%2(%1)", op
);
8529 else if (CONST_OK_FOR_K (delta
))
8530 output_asm_insn ("aghi\t%1,%2", op
);
8531 else if (CONST_OK_FOR_Os (delta
))
8532 output_asm_insn ("agfi\t%1,%2", op
);
8535 op
[6] = gen_label_rtx ();
8536 output_asm_insn ("agf\t%1,%6-%5(%4)", op
);
8540 /* Perform vcall adjustment. */
8543 if (DISP_IN_RANGE (vcall_offset
))
8545 output_asm_insn ("lg\t%4,0(%1)", op
);
8546 output_asm_insn ("ag\t%1,%3(%4)", op
);
8548 else if (CONST_OK_FOR_K (vcall_offset
))
8550 output_asm_insn ("lghi\t%4,%3", op
);
8551 output_asm_insn ("ag\t%4,0(%1)", op
);
8552 output_asm_insn ("ag\t%1,0(%4)", op
);
8554 else if (CONST_OK_FOR_Os (vcall_offset
))
8556 output_asm_insn ("lgfi\t%4,%3", op
);
8557 output_asm_insn ("ag\t%4,0(%1)", op
);
8558 output_asm_insn ("ag\t%1,0(%4)", op
);
8562 op
[7] = gen_label_rtx ();
8563 output_asm_insn ("llgf\t%4,%7-%5(%4)", op
);
8564 output_asm_insn ("ag\t%4,0(%1)", op
);
8565 output_asm_insn ("ag\t%1,0(%4)", op
);
8569 /* Jump to target. */
8570 output_asm_insn ("jg\t%0", op
);
8572 /* Output literal pool if required. */
8575 output_asm_insn (".align\t4", op
);
8576 targetm
.asm_out
.internal_label (file
, "L",
8577 CODE_LABEL_NUMBER (op
[5]));
8581 targetm
.asm_out
.internal_label (file
, "L",
8582 CODE_LABEL_NUMBER (op
[6]));
8583 output_asm_insn (".long\t%2", op
);
8587 targetm
.asm_out
.internal_label (file
, "L",
8588 CODE_LABEL_NUMBER (op
[7]));
8589 output_asm_insn (".long\t%3", op
);
8594 /* Setup base pointer if required. */
8596 || (!DISP_IN_RANGE (delta
)
8597 && !CONST_OK_FOR_K (delta
)
8598 && !CONST_OK_FOR_Os (delta
))
8599 || (!DISP_IN_RANGE (delta
)
8600 && !CONST_OK_FOR_K (vcall_offset
)
8601 && !CONST_OK_FOR_Os (vcall_offset
)))
8603 op
[5] = gen_label_rtx ();
8604 output_asm_insn ("basr\t%4,0", op
);
8605 targetm
.asm_out
.internal_label (file
, "L",
8606 CODE_LABEL_NUMBER (op
[5]));
8609 /* Add DELTA to this pointer. */
8612 if (CONST_OK_FOR_J (delta
))
8613 output_asm_insn ("la\t%1,%2(%1)", op
);
8614 else if (DISP_IN_RANGE (delta
))
8615 output_asm_insn ("lay\t%1,%2(%1)", op
);
8616 else if (CONST_OK_FOR_K (delta
))
8617 output_asm_insn ("ahi\t%1,%2", op
);
8618 else if (CONST_OK_FOR_Os (delta
))
8619 output_asm_insn ("afi\t%1,%2", op
);
8622 op
[6] = gen_label_rtx ();
8623 output_asm_insn ("a\t%1,%6-%5(%4)", op
);
8627 /* Perform vcall adjustment. */
8630 if (CONST_OK_FOR_J (vcall_offset
))
8632 output_asm_insn ("l\t%4,0(%1)", op
);
8633 output_asm_insn ("a\t%1,%3(%4)", op
);
8635 else if (DISP_IN_RANGE (vcall_offset
))
8637 output_asm_insn ("l\t%4,0(%1)", op
);
8638 output_asm_insn ("ay\t%1,%3(%4)", op
);
8640 else if (CONST_OK_FOR_K (vcall_offset
))
8642 output_asm_insn ("lhi\t%4,%3", op
);
8643 output_asm_insn ("a\t%4,0(%1)", op
);
8644 output_asm_insn ("a\t%1,0(%4)", op
);
8646 else if (CONST_OK_FOR_Os (vcall_offset
))
8648 output_asm_insn ("iilf\t%4,%3", op
);
8649 output_asm_insn ("a\t%4,0(%1)", op
);
8650 output_asm_insn ("a\t%1,0(%4)", op
);
8654 op
[7] = gen_label_rtx ();
8655 output_asm_insn ("l\t%4,%7-%5(%4)", op
);
8656 output_asm_insn ("a\t%4,0(%1)", op
);
8657 output_asm_insn ("a\t%1,0(%4)", op
);
8660 /* We had to clobber the base pointer register.
8661 Re-setup the base pointer (with a different base). */
8662 op
[5] = gen_label_rtx ();
8663 output_asm_insn ("basr\t%4,0", op
);
8664 targetm
.asm_out
.internal_label (file
, "L",
8665 CODE_LABEL_NUMBER (op
[5]));
8668 /* Jump to target. */
8669 op
[8] = gen_label_rtx ();
8672 output_asm_insn ("l\t%4,%8-%5(%4)", op
);
8674 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
8675 /* We cannot call through .plt, since .plt requires %r12 loaded. */
8676 else if (flag_pic
== 1)
8678 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
8679 output_asm_insn ("l\t%4,%0(%4)", op
);
8681 else if (flag_pic
== 2)
8683 op
[9] = gen_rtx_REG (Pmode
, 0);
8684 output_asm_insn ("l\t%9,%8-4-%5(%4)", op
);
8685 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
8686 output_asm_insn ("ar\t%4,%9", op
);
8687 output_asm_insn ("l\t%4,0(%4)", op
);
8690 output_asm_insn ("br\t%4", op
);
8692 /* Output literal pool. */
8693 output_asm_insn (".align\t4", op
);
8695 if (nonlocal
&& flag_pic
== 2)
8696 output_asm_insn (".long\t%0", op
);
8699 op
[0] = gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
8700 SYMBOL_REF_FLAGS (op
[0]) = SYMBOL_FLAG_LOCAL
;
8703 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[8]));
8705 output_asm_insn (".long\t%0", op
);
8707 output_asm_insn (".long\t%0-%5", op
);
8711 targetm
.asm_out
.internal_label (file
, "L",
8712 CODE_LABEL_NUMBER (op
[6]));
8713 output_asm_insn (".long\t%2", op
);
8717 targetm
.asm_out
.internal_label (file
, "L",
8718 CODE_LABEL_NUMBER (op
[7]));
8719 output_asm_insn (".long\t%3", op
);
8725 s390_valid_pointer_mode (enum machine_mode mode
)
8727 return (mode
== SImode
|| (TARGET_64BIT
&& mode
== DImode
));
8730 /* Checks whether the given CALL_EXPR would use a caller
8731 saved register. This is used to decide whether sibling call
8732 optimization could be performed on the respective function
8736 s390_call_saved_register_used (tree call_expr
)
8738 CUMULATIVE_ARGS cum
;
8740 enum machine_mode mode
;
8745 INIT_CUMULATIVE_ARGS (cum
, NULL
, NULL
, 0, 0);
8747 for (i
= 0; i
< call_expr_nargs (call_expr
); i
++)
8749 parameter
= CALL_EXPR_ARG (call_expr
, i
);
8750 gcc_assert (parameter
);
8752 /* For an undeclared variable passed as parameter we will get
8753 an ERROR_MARK node here. */
8754 if (TREE_CODE (parameter
) == ERROR_MARK
)
8757 type
= TREE_TYPE (parameter
);
8760 mode
= TYPE_MODE (type
);
8763 if (pass_by_reference (&cum
, mode
, type
, true))
8766 type
= build_pointer_type (type
);
8769 parm_rtx
= s390_function_arg (&cum
, mode
, type
, 0);
8771 s390_function_arg_advance (&cum
, mode
, type
, 0);
8773 if (parm_rtx
&& REG_P (parm_rtx
))
8776 reg
< HARD_REGNO_NREGS (REGNO (parm_rtx
), GET_MODE (parm_rtx
));
8778 if (! call_used_regs
[reg
+ REGNO (parm_rtx
)])
8785 /* Return true if the given call expression can be
8786 turned into a sibling call.
8787 DECL holds the declaration of the function to be called whereas
8788 EXP is the call expression itself. */
8791 s390_function_ok_for_sibcall (tree decl
, tree exp
)
8793 /* The TPF epilogue uses register 1. */
8794 if (TARGET_TPF_PROFILING
)
8797 /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
8798 which would have to be restored before the sibcall. */
8799 if (!TARGET_64BIT
&& flag_pic
&& decl
&& !targetm
.binds_local_p (decl
))
8802 /* Register 6 on s390 is available as an argument register but unfortunately
8803 "caller saved". This makes functions needing this register for arguments
8804 not suitable for sibcalls. */
8805 return !s390_call_saved_register_used (exp
);
8808 /* Return the fixed registers used for condition codes. */
8811 s390_fixed_condition_code_regs (unsigned int *p1
, unsigned int *p2
)
8814 *p2
= INVALID_REGNUM
;
8819 /* This function is used by the call expanders of the machine description.
8820 It emits the call insn itself together with the necessary operations
8821 to adjust the target address and returns the emitted insn.
8822 ADDR_LOCATION is the target address rtx
8823 TLS_CALL the location of the thread-local symbol
8824 RESULT_REG the register where the result of the call should be stored
8825 RETADDR_REG the register where the return address should be stored
8826 If this parameter is NULL_RTX the call is considered
8827 to be a sibling call. */
8830 s390_emit_call (rtx addr_location
, rtx tls_call
, rtx result_reg
,
8833 bool plt_call
= false;
8839 /* Direct function calls need special treatment. */
8840 if (GET_CODE (addr_location
) == SYMBOL_REF
)
8842 /* When calling a global routine in PIC mode, we must
8843 replace the symbol itself with the PLT stub. */
8844 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (addr_location
))
8846 addr_location
= gen_rtx_UNSPEC (Pmode
,
8847 gen_rtvec (1, addr_location
),
8849 addr_location
= gen_rtx_CONST (Pmode
, addr_location
);
8853 /* Unless we can use the bras(l) insn, force the
8854 routine address into a register. */
8855 if (!TARGET_SMALL_EXEC
&& !TARGET_CPU_ZARCH
)
8858 addr_location
= legitimize_pic_address (addr_location
, 0);
8860 addr_location
= force_reg (Pmode
, addr_location
);
8864 /* If it is already an indirect call or the code above moved the
8865 SYMBOL_REF to somewhere else make sure the address can be found in
8867 if (retaddr_reg
== NULL_RTX
8868 && GET_CODE (addr_location
) != SYMBOL_REF
8871 emit_move_insn (gen_rtx_REG (Pmode
, SIBCALL_REGNUM
), addr_location
);
8872 addr_location
= gen_rtx_REG (Pmode
, SIBCALL_REGNUM
);
8875 addr_location
= gen_rtx_MEM (QImode
, addr_location
);
8876 call
= gen_rtx_CALL (VOIDmode
, addr_location
, const0_rtx
);
8878 if (result_reg
!= NULL_RTX
)
8879 call
= gen_rtx_SET (VOIDmode
, result_reg
, call
);
8881 if (retaddr_reg
!= NULL_RTX
)
8883 clobber
= gen_rtx_CLOBBER (VOIDmode
, retaddr_reg
);
8885 if (tls_call
!= NULL_RTX
)
8886 vec
= gen_rtvec (3, call
, clobber
,
8887 gen_rtx_USE (VOIDmode
, tls_call
));
8889 vec
= gen_rtvec (2, call
, clobber
);
8891 call
= gen_rtx_PARALLEL (VOIDmode
, vec
);
8894 insn
= emit_call_insn (call
);
8896 /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
8897 if ((!TARGET_64BIT
&& plt_call
) || tls_call
!= NULL_RTX
)
8899 /* s390_function_ok_for_sibcall should
8900 have denied sibcalls in this case. */
8901 gcc_assert (retaddr_reg
!= NULL_RTX
);
8903 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), pic_offset_table_rtx
);
8908 /* Implement CONDITIONAL_REGISTER_USAGE. */
8911 s390_conditional_register_usage (void)
8917 fixed_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
8918 call_used_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
8920 if (TARGET_CPU_ZARCH
)
8922 fixed_regs
[BASE_REGNUM
] = 0;
8923 call_used_regs
[BASE_REGNUM
] = 0;
8924 fixed_regs
[RETURN_REGNUM
] = 0;
8925 call_used_regs
[RETURN_REGNUM
] = 0;
8929 for (i
= 24; i
< 32; i
++)
8930 call_used_regs
[i
] = call_really_used_regs
[i
] = 0;
8934 for (i
= 18; i
< 20; i
++)
8935 call_used_regs
[i
] = call_really_used_regs
[i
] = 0;
8938 if (TARGET_SOFT_FLOAT
)
8940 for (i
= 16; i
< 32; i
++)
8941 call_used_regs
[i
] = fixed_regs
[i
] = 1;
8945 /* Corresponding function to eh_return expander. */
8947 static GTY(()) rtx s390_tpf_eh_return_symbol
;
8949 s390_emit_tpf_eh_return (rtx target
)
8953 if (!s390_tpf_eh_return_symbol
)
8954 s390_tpf_eh_return_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "__tpf_eh_return");
8956 reg
= gen_rtx_REG (Pmode
, 2);
8958 emit_move_insn (reg
, target
);
8959 insn
= s390_emit_call (s390_tpf_eh_return_symbol
, NULL_RTX
, reg
,
8960 gen_rtx_REG (Pmode
, RETURN_REGNUM
));
8961 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), reg
);
8963 emit_move_insn (EH_RETURN_HANDLER_RTX
, reg
);
8966 /* Rework the prologue/epilogue to avoid saving/restoring
8967 registers unnecessarily. */
8970 s390_optimize_prologue (void)
8972 rtx insn
, new_insn
, next_insn
;
8974 /* Do a final recompute of the frame-related data. */
8976 s390_update_frame_layout ();
8978 /* If all special registers are in fact used, there's nothing we
8979 can do, so no point in walking the insn list. */
8981 if (cfun_frame_layout
.first_save_gpr
<= BASE_REGNUM
8982 && cfun_frame_layout
.last_save_gpr
>= BASE_REGNUM
8983 && (TARGET_CPU_ZARCH
8984 || (cfun_frame_layout
.first_save_gpr
<= RETURN_REGNUM
8985 && cfun_frame_layout
.last_save_gpr
>= RETURN_REGNUM
)))
8988 /* Search for prologue/epilogue insns and replace them. */
8990 for (insn
= get_insns (); insn
; insn
= next_insn
)
8992 int first
, last
, off
;
8993 rtx set
, base
, offset
;
8995 next_insn
= NEXT_INSN (insn
);
8997 if (GET_CODE (insn
) != INSN
)
9000 if (GET_CODE (PATTERN (insn
)) == PARALLEL
9001 && store_multiple_operation (PATTERN (insn
), VOIDmode
))
9003 set
= XVECEXP (PATTERN (insn
), 0, 0);
9004 first
= REGNO (SET_SRC (set
));
9005 last
= first
+ XVECLEN (PATTERN (insn
), 0) - 1;
9006 offset
= const0_rtx
;
9007 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
9008 off
= INTVAL (offset
);
9010 if (GET_CODE (base
) != REG
|| off
< 0)
9012 if (cfun_frame_layout
.first_save_gpr
!= -1
9013 && (cfun_frame_layout
.first_save_gpr
< first
9014 || cfun_frame_layout
.last_save_gpr
> last
))
9016 if (REGNO (base
) != STACK_POINTER_REGNUM
9017 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
9019 if (first
> BASE_REGNUM
|| last
< BASE_REGNUM
)
9022 if (cfun_frame_layout
.first_save_gpr
!= -1)
9024 new_insn
= save_gprs (base
,
9025 off
+ (cfun_frame_layout
.first_save_gpr
9026 - first
) * UNITS_PER_WORD
,
9027 cfun_frame_layout
.first_save_gpr
,
9028 cfun_frame_layout
.last_save_gpr
);
9029 new_insn
= emit_insn_before (new_insn
, insn
);
9030 INSN_ADDRESSES_NEW (new_insn
, -1);
9037 if (cfun_frame_layout
.first_save_gpr
== -1
9038 && GET_CODE (PATTERN (insn
)) == SET
9039 && GET_CODE (SET_SRC (PATTERN (insn
))) == REG
9040 && (REGNO (SET_SRC (PATTERN (insn
))) == BASE_REGNUM
9041 || (!TARGET_CPU_ZARCH
9042 && REGNO (SET_SRC (PATTERN (insn
))) == RETURN_REGNUM
))
9043 && GET_CODE (SET_DEST (PATTERN (insn
))) == MEM
)
9045 set
= PATTERN (insn
);
9046 first
= REGNO (SET_SRC (set
));
9047 offset
= const0_rtx
;
9048 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
9049 off
= INTVAL (offset
);
9051 if (GET_CODE (base
) != REG
|| off
< 0)
9053 if (REGNO (base
) != STACK_POINTER_REGNUM
9054 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
9061 if (GET_CODE (PATTERN (insn
)) == PARALLEL
9062 && load_multiple_operation (PATTERN (insn
), VOIDmode
))
9064 set
= XVECEXP (PATTERN (insn
), 0, 0);
9065 first
= REGNO (SET_DEST (set
));
9066 last
= first
+ XVECLEN (PATTERN (insn
), 0) - 1;
9067 offset
= const0_rtx
;
9068 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
9069 off
= INTVAL (offset
);
9071 if (GET_CODE (base
) != REG
|| off
< 0)
9073 if (cfun_frame_layout
.first_restore_gpr
!= -1
9074 && (cfun_frame_layout
.first_restore_gpr
< first
9075 || cfun_frame_layout
.last_restore_gpr
> last
))
9077 if (REGNO (base
) != STACK_POINTER_REGNUM
9078 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
9080 if (first
> BASE_REGNUM
|| last
< BASE_REGNUM
)
9083 if (cfun_frame_layout
.first_restore_gpr
!= -1)
9085 new_insn
= restore_gprs (base
,
9086 off
+ (cfun_frame_layout
.first_restore_gpr
9087 - first
) * UNITS_PER_WORD
,
9088 cfun_frame_layout
.first_restore_gpr
,
9089 cfun_frame_layout
.last_restore_gpr
);
9090 new_insn
= emit_insn_before (new_insn
, insn
);
9091 INSN_ADDRESSES_NEW (new_insn
, -1);
9098 if (cfun_frame_layout
.first_restore_gpr
== -1
9099 && GET_CODE (PATTERN (insn
)) == SET
9100 && GET_CODE (SET_DEST (PATTERN (insn
))) == REG
9101 && (REGNO (SET_DEST (PATTERN (insn
))) == BASE_REGNUM
9102 || (!TARGET_CPU_ZARCH
9103 && REGNO (SET_DEST (PATTERN (insn
))) == RETURN_REGNUM
))
9104 && GET_CODE (SET_SRC (PATTERN (insn
))) == MEM
)
9106 set
= PATTERN (insn
);
9107 first
= REGNO (SET_DEST (set
));
9108 offset
= const0_rtx
;
9109 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
9110 off
= INTVAL (offset
);
9112 if (GET_CODE (base
) != REG
|| off
< 0)
9114 if (REGNO (base
) != STACK_POINTER_REGNUM
9115 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
9124 /* Perform machine-dependent processing. */
9129 bool pool_overflow
= false;
9131 /* Make sure all splits have been performed; splits after
9132 machine_dependent_reorg might confuse insn length counts. */
9133 split_all_insns_noflow ();
9135 /* From here on decomposed literal pool addresses must be accepted. */
9136 cfun
->machine
->decomposed_literal_pool_addresses_ok_p
= true;
9138 /* Install the main literal pool and the associated base
9139 register load insns.
9141 In addition, there are two problematic situations we need
9144 - the literal pool might be > 4096 bytes in size, so that
9145 some of its elements cannot be directly accessed
9147 - a branch target might be > 64K away from the branch, so that
9148 it is not possible to use a PC-relative instruction.
9150 To fix those, we split the single literal pool into multiple
9151 pool chunks, reloading the pool base register at various
9152 points throughout the function to ensure it always points to
9153 the pool chunk the following code expects, and / or replace
9154 PC-relative branches by absolute branches.
9156 However, the two problems are interdependent: splitting the
9157 literal pool can move a branch further away from its target,
9158 causing the 64K limit to overflow, and on the other hand,
9159 replacing a PC-relative branch by an absolute branch means
9160 we need to put the branch target address into the literal
9161 pool, possibly causing it to overflow.
9163 So, we loop trying to fix up both problems until we manage
9164 to satisfy both conditions at the same time. Note that the
9165 loop is guaranteed to terminate as every pass of the loop
9166 strictly decreases the total number of PC-relative branches
9167 in the function. (This is not completely true as there
9168 might be branch-over-pool insns introduced by chunkify_start.
9169 Those never need to be split however.) */
9173 struct constant_pool
*pool
= NULL
;
9175 /* Collect the literal pool. */
9178 pool
= s390_mainpool_start ();
9180 pool_overflow
= true;
9183 /* If literal pool overflowed, start to chunkify it. */
9185 pool
= s390_chunkify_start ();
9187 /* Split out-of-range branches. If this has created new
9188 literal pool entries, cancel current chunk list and
9189 recompute it. zSeries machines have large branch
9190 instructions, so we never need to split a branch. */
9191 if (!TARGET_CPU_ZARCH
&& s390_split_branches ())
9194 s390_chunkify_cancel (pool
);
9196 s390_mainpool_cancel (pool
);
9201 /* If we made it up to here, both conditions are satisfied.
9202 Finish up literal pool related changes. */
9204 s390_chunkify_finish (pool
);
9206 s390_mainpool_finish (pool
);
9208 /* We're done splitting branches. */
9209 cfun
->machine
->split_branches_pending_p
= false;
9213 /* Generate out-of-pool execute target insns. */
9214 if (TARGET_CPU_ZARCH
)
9216 rtx insn
, label
, target
;
9218 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
9220 label
= s390_execute_label (insn
);
9224 gcc_assert (label
!= const0_rtx
);
9226 target
= emit_label (XEXP (label
, 0));
9227 INSN_ADDRESSES_NEW (target
, -1);
9229 target
= emit_insn (s390_execute_target (insn
));
9230 INSN_ADDRESSES_NEW (target
, -1);
9234 /* Try to optimize prologue and epilogue further. */
9235 s390_optimize_prologue ();
9239 /* Initialize GCC target structure. */
9241 #undef TARGET_ASM_ALIGNED_HI_OP
9242 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
9243 #undef TARGET_ASM_ALIGNED_DI_OP
9244 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
9245 #undef TARGET_ASM_INTEGER
9246 #define TARGET_ASM_INTEGER s390_assemble_integer
9248 #undef TARGET_ASM_OPEN_PAREN
9249 #define TARGET_ASM_OPEN_PAREN ""
9251 #undef TARGET_ASM_CLOSE_PAREN
9252 #define TARGET_ASM_CLOSE_PAREN ""
9254 #undef TARGET_DEFAULT_TARGET_FLAGS
9255 #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD)
9256 #undef TARGET_HANDLE_OPTION
9257 #define TARGET_HANDLE_OPTION s390_handle_option
9259 #undef TARGET_ENCODE_SECTION_INFO
9260 #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
9263 #undef TARGET_HAVE_TLS
9264 #define TARGET_HAVE_TLS true
9266 #undef TARGET_CANNOT_FORCE_CONST_MEM
9267 #define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
9269 #undef TARGET_DELEGITIMIZE_ADDRESS
9270 #define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
9272 #undef TARGET_RETURN_IN_MEMORY
9273 #define TARGET_RETURN_IN_MEMORY s390_return_in_memory
9275 #undef TARGET_INIT_BUILTINS
9276 #define TARGET_INIT_BUILTINS s390_init_builtins
9277 #undef TARGET_EXPAND_BUILTIN
9278 #define TARGET_EXPAND_BUILTIN s390_expand_builtin
9280 #undef TARGET_ASM_OUTPUT_MI_THUNK
9281 #define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
9282 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
9283 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
9285 #undef TARGET_SCHED_ADJUST_PRIORITY
9286 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
9287 #undef TARGET_SCHED_ISSUE_RATE
9288 #define TARGET_SCHED_ISSUE_RATE s390_issue_rate
9289 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
9290 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
9292 #undef TARGET_CANNOT_COPY_INSN_P
9293 #define TARGET_CANNOT_COPY_INSN_P s390_cannot_copy_insn_p
9294 #undef TARGET_RTX_COSTS
9295 #define TARGET_RTX_COSTS s390_rtx_costs
9296 #undef TARGET_ADDRESS_COST
9297 #define TARGET_ADDRESS_COST s390_address_cost
9299 #undef TARGET_MACHINE_DEPENDENT_REORG
9300 #define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
9302 #undef TARGET_VALID_POINTER_MODE
9303 #define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
9305 #undef TARGET_BUILD_BUILTIN_VA_LIST
9306 #define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
9307 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
9308 #define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg
9310 #undef TARGET_PROMOTE_FUNCTION_ARGS
9311 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
9312 #undef TARGET_PROMOTE_FUNCTION_RETURN
9313 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
9314 #undef TARGET_PASS_BY_REFERENCE
9315 #define TARGET_PASS_BY_REFERENCE s390_pass_by_reference
9317 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
9318 #define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
9320 #undef TARGET_FIXED_CONDITION_CODE_REGS
9321 #define TARGET_FIXED_CONDITION_CODE_REGS s390_fixed_condition_code_regs
9323 #undef TARGET_CC_MODES_COMPATIBLE
9324 #define TARGET_CC_MODES_COMPATIBLE s390_cc_modes_compatible
9326 #undef TARGET_INVALID_WITHIN_DOLOOP
9327 #define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_rtx_null
9330 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
9331 #define TARGET_ASM_OUTPUT_DWARF_DTPREL s390_output_dwarf_dtprel
9334 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
9335 #undef TARGET_MANGLE_FUNDAMENTAL_TYPE
9336 #define TARGET_MANGLE_FUNDAMENTAL_TYPE s390_mangle_fundamental_type
9339 #undef TARGET_SCALAR_MODE_SUPPORTED_P
9340 #define TARGET_SCALAR_MODE_SUPPORTED_P s390_scalar_mode_supported_p
9342 struct gcc_target targetm
= TARGET_INITIALIZER
;
9344 #include "gt-s390.h"