1 /* Subroutines used for code generation on IBM S/390 and zSeries
2 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
3 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
4 Contributed by Hartmut Penner (hpenner@de.ibm.com) and
5 Ulrich Weigand (uweigand@de.ibm.com) and
6 Andreas Krebbel (Andreas.Krebbel@de.ibm.com).
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
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"
59 /* Define the specific costs for a given cpu. */
61 struct processor_costs
64 const int m
; /* cost of an M instruction. */
65 const int mghi
; /* cost of an MGHI instruction. */
66 const int mh
; /* cost of an MH instruction. */
67 const int mhi
; /* cost of an MHI instruction. */
68 const int ml
; /* cost of an ML instruction. */
69 const int mr
; /* cost of an MR instruction. */
70 const int ms
; /* cost of an MS instruction. */
71 const int msg
; /* cost of an MSG instruction. */
72 const int msgf
; /* cost of an MSGF instruction. */
73 const int msgfr
; /* cost of an MSGFR instruction. */
74 const int msgr
; /* cost of an MSGR instruction. */
75 const int msr
; /* cost of an MSR instruction. */
76 const int mult_df
; /* cost of multiplication in DFmode. */
79 const int sqxbr
; /* cost of square root in TFmode. */
80 const int sqdbr
; /* cost of square root in DFmode. */
81 const int sqebr
; /* cost of square root in SFmode. */
82 /* multiply and add */
83 const int madbr
; /* cost of multiply and add in DFmode. */
84 const int maebr
; /* cost of multiply and add in SFmode. */
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 (30), /* DDBR */
122 COSTS_N_INSNS (27), /* DEBR */
123 COSTS_N_INSNS (220), /* DLGR */
124 COSTS_N_INSNS (34), /* DLR */
125 COSTS_N_INSNS (34), /* DR */
126 COSTS_N_INSNS (32), /* DSGFR */
127 COSTS_N_INSNS (32), /* DSGR */
131 struct processor_costs z990_cost
=
133 COSTS_N_INSNS (4), /* M */
134 COSTS_N_INSNS (2), /* MGHI */
135 COSTS_N_INSNS (2), /* MH */
136 COSTS_N_INSNS (2), /* MHI */
137 COSTS_N_INSNS (4), /* ML */
138 COSTS_N_INSNS (4), /* MR */
139 COSTS_N_INSNS (5), /* MS */
140 COSTS_N_INSNS (6), /* MSG */
141 COSTS_N_INSNS (4), /* MSGF */
142 COSTS_N_INSNS (4), /* MSGFR */
143 COSTS_N_INSNS (4), /* MSGR */
144 COSTS_N_INSNS (4), /* MSR */
145 COSTS_N_INSNS (1), /* multiplication in DFmode */
146 COSTS_N_INSNS (28), /* MXBR */
147 COSTS_N_INSNS (130), /* SQXBR */
148 COSTS_N_INSNS (66), /* SQDBR */
149 COSTS_N_INSNS (38), /* SQEBR */
150 COSTS_N_INSNS (1), /* MADBR */
151 COSTS_N_INSNS (1), /* MAEBR */
152 COSTS_N_INSNS (60), /* DXBR */
153 COSTS_N_INSNS (40), /* DDBR */
154 COSTS_N_INSNS (26), /* DEBR */
155 COSTS_N_INSNS (176), /* DLGR */
156 COSTS_N_INSNS (31), /* DLR */
157 COSTS_N_INSNS (31), /* DR */
158 COSTS_N_INSNS (31), /* DSGFR */
159 COSTS_N_INSNS (31), /* DSGR */
163 struct processor_costs z9_109_cost
=
165 COSTS_N_INSNS (4), /* M */
166 COSTS_N_INSNS (2), /* MGHI */
167 COSTS_N_INSNS (2), /* MH */
168 COSTS_N_INSNS (2), /* MHI */
169 COSTS_N_INSNS (4), /* ML */
170 COSTS_N_INSNS (4), /* MR */
171 COSTS_N_INSNS (5), /* MS */
172 COSTS_N_INSNS (6), /* MSG */
173 COSTS_N_INSNS (4), /* MSGF */
174 COSTS_N_INSNS (4), /* MSGFR */
175 COSTS_N_INSNS (4), /* MSGR */
176 COSTS_N_INSNS (4), /* MSR */
177 COSTS_N_INSNS (1), /* multiplication in DFmode */
178 COSTS_N_INSNS (28), /* MXBR */
179 COSTS_N_INSNS (130), /* SQXBR */
180 COSTS_N_INSNS (66), /* SQDBR */
181 COSTS_N_INSNS (38), /* SQEBR */
182 COSTS_N_INSNS (1), /* MADBR */
183 COSTS_N_INSNS (1), /* MAEBR */
184 COSTS_N_INSNS (60), /* DXBR */
185 COSTS_N_INSNS (40), /* DDBR */
186 COSTS_N_INSNS (26), /* DEBR */
187 COSTS_N_INSNS (30), /* DLGR */
188 COSTS_N_INSNS (23), /* DLR */
189 COSTS_N_INSNS (23), /* DR */
190 COSTS_N_INSNS (24), /* DSGFR */
191 COSTS_N_INSNS (24), /* DSGR */
195 struct processor_costs z10_cost
=
197 COSTS_N_INSNS (10), /* M */
198 COSTS_N_INSNS (10), /* MGHI */
199 COSTS_N_INSNS (10), /* MH */
200 COSTS_N_INSNS (10), /* MHI */
201 COSTS_N_INSNS (10), /* ML */
202 COSTS_N_INSNS (10), /* MR */
203 COSTS_N_INSNS (10), /* MS */
204 COSTS_N_INSNS (10), /* MSG */
205 COSTS_N_INSNS (10), /* MSGF */
206 COSTS_N_INSNS (10), /* MSGFR */
207 COSTS_N_INSNS (10), /* MSGR */
208 COSTS_N_INSNS (10), /* MSR */
209 COSTS_N_INSNS (1) , /* multiplication in DFmode */
210 COSTS_N_INSNS (50), /* MXBR */
211 COSTS_N_INSNS (120), /* SQXBR */
212 COSTS_N_INSNS (52), /* SQDBR */
213 COSTS_N_INSNS (38), /* SQEBR */
214 COSTS_N_INSNS (1), /* MADBR */
215 COSTS_N_INSNS (1), /* MAEBR */
216 COSTS_N_INSNS (111), /* DXBR */
217 COSTS_N_INSNS (39), /* DDBR */
218 COSTS_N_INSNS (32), /* DEBR */
219 COSTS_N_INSNS (160), /* DLGR */
220 COSTS_N_INSNS (71), /* DLR */
221 COSTS_N_INSNS (71), /* DR */
222 COSTS_N_INSNS (71), /* DSGFR */
223 COSTS_N_INSNS (71), /* DSGR */
226 extern int reload_completed
;
228 /* Kept up to date using the SCHED_VARIABLE_ISSUE hook. */
229 static rtx last_scheduled_insn
;
231 /* Structure used to hold the components of a S/390 memory
232 address. A legitimate address on S/390 is of the general
234 base + index + displacement
235 where any of the components is optional.
237 base and index are registers of the class ADDR_REGS,
238 displacement is an unsigned 12-bit immediate constant. */
249 /* Which cpu are we tuning for. */
250 enum processor_type s390_tune
= PROCESSOR_max
;
252 /* Which instruction set architecture to use. */
253 enum processor_type s390_arch
;
256 HOST_WIDE_INT s390_warn_framesize
= 0;
257 HOST_WIDE_INT s390_stack_size
= 0;
258 HOST_WIDE_INT s390_stack_guard
= 0;
260 /* The following structure is embedded in the machine
261 specific part of struct function. */
263 struct GTY (()) s390_frame_layout
265 /* Offset within stack frame. */
266 HOST_WIDE_INT gprs_offset
;
267 HOST_WIDE_INT f0_offset
;
268 HOST_WIDE_INT f4_offset
;
269 HOST_WIDE_INT f8_offset
;
270 HOST_WIDE_INT backchain_offset
;
272 /* Number of first and last gpr where slots in the register
273 save area are reserved for. */
274 int first_save_gpr_slot
;
275 int last_save_gpr_slot
;
277 /* Number of first and last gpr to be saved, restored. */
279 int first_restore_gpr
;
281 int last_restore_gpr
;
283 /* Bits standing for floating point registers. Set, if the
284 respective register has to be saved. Starting with reg 16 (f0)
285 at the rightmost bit.
286 Bit 15 - 8 7 6 5 4 3 2 1 0
287 fpr 15 - 8 7 5 3 1 6 4 2 0
288 reg 31 - 24 23 22 21 20 19 18 17 16 */
289 unsigned int fpr_bitmap
;
291 /* Number of floating point registers f8-f15 which must be saved. */
294 /* Set if return address needs to be saved.
295 This flag is set by s390_return_addr_rtx if it could not use
296 the initial value of r14 and therefore depends on r14 saved
298 bool save_return_addr_p
;
300 /* Size of stack frame. */
301 HOST_WIDE_INT frame_size
;
304 /* Define the structure for the machine field in struct function. */
306 struct GTY(()) machine_function
308 struct s390_frame_layout frame_layout
;
310 /* Literal pool base register. */
313 /* True if we may need to perform branch splitting. */
314 bool split_branches_pending_p
;
316 /* Some local-dynamic TLS symbol name. */
317 const char *some_ld_name
;
319 bool has_landing_pad_p
;
322 /* Few accessor macros for struct cfun->machine->s390_frame_layout. */
324 #define cfun_frame_layout (cfun->machine->frame_layout)
325 #define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)
326 #define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr_slot - \
327 cfun_frame_layout.first_save_gpr_slot + 1) * UNITS_PER_WORD)
328 #define cfun_set_fpr_bit(BITNUM) (cfun->machine->frame_layout.fpr_bitmap |= \
330 #define cfun_fpr_bit_p(BITNUM) (!!(cfun->machine->frame_layout.fpr_bitmap & \
333 /* Number of GPRs and FPRs used for argument passing. */
334 #define GP_ARG_NUM_REG 5
335 #define FP_ARG_NUM_REG (TARGET_64BIT? 4 : 2)
337 /* A couple of shortcuts. */
338 #define CONST_OK_FOR_J(x) \
339 CONST_OK_FOR_CONSTRAINT_P((x), 'J', "J")
340 #define CONST_OK_FOR_K(x) \
341 CONST_OK_FOR_CONSTRAINT_P((x), 'K', "K")
342 #define CONST_OK_FOR_Os(x) \
343 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Os")
344 #define CONST_OK_FOR_Op(x) \
345 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Op")
346 #define CONST_OK_FOR_On(x) \
347 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "On")
349 #define REGNO_PAIR_OK(REGNO, MODE) \
350 (HARD_REGNO_NREGS ((REGNO), (MODE)) == 1 || !((REGNO) & 1))
352 /* That's the read ahead of the dynamic branch prediction unit in
353 bytes on a z10 CPU. */
354 #define Z10_PREDICT_DISTANCE 384
356 static enum machine_mode
357 s390_libgcc_cmp_return_mode (void)
359 return TARGET_64BIT
? DImode
: SImode
;
362 static enum machine_mode
363 s390_libgcc_shift_count_mode (void)
365 return TARGET_64BIT
? DImode
: SImode
;
368 /* Return true if the back end supports mode MODE. */
370 s390_scalar_mode_supported_p (enum machine_mode mode
)
372 if (DECIMAL_FLOAT_MODE_P (mode
))
373 return default_decimal_float_supported_p ();
375 return default_scalar_mode_supported_p (mode
);
378 /* Set the has_landing_pad_p flag in struct machine_function to VALUE. */
381 s390_set_has_landing_pad_p (bool value
)
383 cfun
->machine
->has_landing_pad_p
= value
;
386 /* If two condition code modes are compatible, return a condition code
387 mode which is compatible with both. Otherwise, return
390 static enum machine_mode
391 s390_cc_modes_compatible (enum machine_mode m1
, enum machine_mode m2
)
399 if (m2
== CCUmode
|| m2
== CCTmode
|| m2
== CCZ1mode
400 || m2
== CCSmode
|| m2
== CCSRmode
|| m2
== CCURmode
)
421 /* Return true if SET either doesn't set the CC register, or else
422 the source and destination have matching CC modes and that
423 CC mode is at least as constrained as REQ_MODE. */
426 s390_match_ccmode_set (rtx set
, enum machine_mode req_mode
)
428 enum machine_mode set_mode
;
430 gcc_assert (GET_CODE (set
) == SET
);
432 if (GET_CODE (SET_DEST (set
)) != REG
|| !CC_REGNO_P (REGNO (SET_DEST (set
))))
435 set_mode
= GET_MODE (SET_DEST (set
));
449 if (req_mode
!= set_mode
)
454 if (req_mode
!= CCSmode
&& req_mode
!= CCUmode
&& req_mode
!= CCTmode
455 && req_mode
!= CCSRmode
&& req_mode
!= CCURmode
)
461 if (req_mode
!= CCAmode
)
469 return (GET_MODE (SET_SRC (set
)) == set_mode
);
472 /* Return true if every SET in INSN that sets the CC register
473 has source and destination with matching CC modes and that
474 CC mode is at least as constrained as REQ_MODE.
475 If REQ_MODE is VOIDmode, always return false. */
478 s390_match_ccmode (rtx insn
, enum machine_mode req_mode
)
482 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
483 if (req_mode
== VOIDmode
)
486 if (GET_CODE (PATTERN (insn
)) == SET
)
487 return s390_match_ccmode_set (PATTERN (insn
), req_mode
);
489 if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
490 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
492 rtx set
= XVECEXP (PATTERN (insn
), 0, i
);
493 if (GET_CODE (set
) == SET
)
494 if (!s390_match_ccmode_set (set
, req_mode
))
501 /* If a test-under-mask instruction can be used to implement
502 (compare (and ... OP1) OP2), return the CC mode required
503 to do that. Otherwise, return VOIDmode.
504 MIXED is true if the instruction can distinguish between
505 CC1 and CC2 for mixed selected bits (TMxx), it is false
506 if the instruction cannot (TM). */
509 s390_tm_ccmode (rtx op1
, rtx op2
, bool mixed
)
513 /* ??? Fixme: should work on CONST_DOUBLE as well. */
514 if (GET_CODE (op1
) != CONST_INT
|| GET_CODE (op2
) != CONST_INT
)
517 /* Selected bits all zero: CC0.
518 e.g.: int a; if ((a & (16 + 128)) == 0) */
519 if (INTVAL (op2
) == 0)
522 /* Selected bits all one: CC3.
523 e.g.: int a; if ((a & (16 + 128)) == 16 + 128) */
524 if (INTVAL (op2
) == INTVAL (op1
))
527 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. e.g.:
529 if ((a & (16 + 128)) == 16) -> CCT1
530 if ((a & (16 + 128)) == 128) -> CCT2 */
533 bit1
= exact_log2 (INTVAL (op2
));
534 bit0
= exact_log2 (INTVAL (op1
) ^ INTVAL (op2
));
535 if (bit0
!= -1 && bit1
!= -1)
536 return bit0
> bit1
? CCT1mode
: CCT2mode
;
542 /* Given a comparison code OP (EQ, NE, etc.) and the operands
543 OP0 and OP1 of a COMPARE, return the mode to be used for the
547 s390_select_ccmode (enum rtx_code code
, rtx op0
, rtx op1
)
553 if ((GET_CODE (op0
) == NEG
|| GET_CODE (op0
) == ABS
)
554 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
556 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
557 && CONST_OK_FOR_K (INTVAL (XEXP (op0
, 1))))
559 if ((GET_CODE (op0
) == PLUS
|| GET_CODE (op0
) == MINUS
560 || GET_CODE (op1
) == NEG
)
561 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
564 if (GET_CODE (op0
) == AND
)
566 /* Check whether we can potentially do it via TM. */
567 enum machine_mode ccmode
;
568 ccmode
= s390_tm_ccmode (XEXP (op0
, 1), op1
, 1);
569 if (ccmode
!= VOIDmode
)
571 /* Relax CCTmode to CCZmode to allow fall-back to AND
572 if that turns out to be beneficial. */
573 return ccmode
== CCTmode
? CCZmode
: ccmode
;
577 if (register_operand (op0
, HImode
)
578 && GET_CODE (op1
) == CONST_INT
579 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 65535))
581 if (register_operand (op0
, QImode
)
582 && GET_CODE (op1
) == CONST_INT
583 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 255))
592 /* The only overflow condition of NEG and ABS happens when
593 -INT_MAX is used as parameter, which stays negative. So
594 we have an overflow from a positive value to a negative.
595 Using CCAP mode the resulting cc can be used for comparisons. */
596 if ((GET_CODE (op0
) == NEG
|| GET_CODE (op0
) == ABS
)
597 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
600 /* If constants are involved in an add instruction it is possible to use
601 the resulting cc for comparisons with zero. Knowing the sign of the
602 constant the overflow behavior gets predictable. e.g.:
603 int a, b; if ((b = a + c) > 0)
604 with c as a constant value: c < 0 -> CCAN and c >= 0 -> CCAP */
605 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
606 && CONST_OK_FOR_K (INTVAL (XEXP (op0
, 1))))
608 if (INTVAL (XEXP((op0
), 1)) < 0)
622 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
623 && GET_CODE (op1
) != CONST_INT
)
629 if (GET_CODE (op0
) == PLUS
630 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
633 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
634 && GET_CODE (op1
) != CONST_INT
)
640 if (GET_CODE (op0
) == MINUS
641 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
644 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
645 && GET_CODE (op1
) != CONST_INT
)
654 /* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
655 that we can implement more efficiently. */
658 s390_canonicalize_comparison (enum rtx_code
*code
, rtx
*op0
, rtx
*op1
)
660 /* Convert ZERO_EXTRACT back to AND to enable TM patterns. */
661 if ((*code
== EQ
|| *code
== NE
)
662 && *op1
== const0_rtx
663 && GET_CODE (*op0
) == ZERO_EXTRACT
664 && GET_CODE (XEXP (*op0
, 1)) == CONST_INT
665 && GET_CODE (XEXP (*op0
, 2)) == CONST_INT
666 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0
, 0))))
668 rtx inner
= XEXP (*op0
, 0);
669 HOST_WIDE_INT modesize
= GET_MODE_BITSIZE (GET_MODE (inner
));
670 HOST_WIDE_INT len
= INTVAL (XEXP (*op0
, 1));
671 HOST_WIDE_INT pos
= INTVAL (XEXP (*op0
, 2));
673 if (len
> 0 && len
< modesize
674 && pos
>= 0 && pos
+ len
<= modesize
675 && modesize
<= HOST_BITS_PER_WIDE_INT
)
677 unsigned HOST_WIDE_INT block
;
678 block
= ((unsigned HOST_WIDE_INT
) 1 << len
) - 1;
679 block
<<= modesize
- pos
- len
;
681 *op0
= gen_rtx_AND (GET_MODE (inner
), inner
,
682 gen_int_mode (block
, GET_MODE (inner
)));
686 /* Narrow AND of memory against immediate to enable TM. */
687 if ((*code
== EQ
|| *code
== NE
)
688 && *op1
== const0_rtx
689 && GET_CODE (*op0
) == AND
690 && GET_CODE (XEXP (*op0
, 1)) == CONST_INT
691 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0
, 0))))
693 rtx inner
= XEXP (*op0
, 0);
694 rtx mask
= XEXP (*op0
, 1);
696 /* Ignore paradoxical SUBREGs if all extra bits are masked out. */
697 if (GET_CODE (inner
) == SUBREG
698 && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (inner
)))
699 && (GET_MODE_SIZE (GET_MODE (inner
))
700 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner
))))
702 & GET_MODE_MASK (GET_MODE (inner
))
703 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (inner
))))
705 inner
= SUBREG_REG (inner
);
707 /* Do not change volatile MEMs. */
708 if (MEM_P (inner
) && !MEM_VOLATILE_P (inner
))
710 int part
= s390_single_part (XEXP (*op0
, 1),
711 GET_MODE (inner
), QImode
, 0);
714 mask
= gen_int_mode (s390_extract_part (mask
, QImode
, 0), QImode
);
715 inner
= adjust_address_nv (inner
, QImode
, part
);
716 *op0
= gen_rtx_AND (QImode
, inner
, mask
);
721 /* Narrow comparisons against 0xffff to HImode if possible. */
722 if ((*code
== EQ
|| *code
== NE
)
723 && GET_CODE (*op1
) == CONST_INT
724 && INTVAL (*op1
) == 0xffff
725 && SCALAR_INT_MODE_P (GET_MODE (*op0
))
726 && (nonzero_bits (*op0
, GET_MODE (*op0
))
727 & ~(unsigned HOST_WIDE_INT
) 0xffff) == 0)
729 *op0
= gen_lowpart (HImode
, *op0
);
733 /* Remove redundant UNSPEC_CCU_TO_INT conversions if possible. */
734 if (GET_CODE (*op0
) == UNSPEC
735 && XINT (*op0
, 1) == UNSPEC_CCU_TO_INT
736 && XVECLEN (*op0
, 0) == 1
737 && GET_MODE (XVECEXP (*op0
, 0, 0)) == CCUmode
738 && GET_CODE (XVECEXP (*op0
, 0, 0)) == REG
739 && REGNO (XVECEXP (*op0
, 0, 0)) == CC_REGNUM
740 && *op1
== const0_rtx
)
742 enum rtx_code new_code
= UNKNOWN
;
745 case EQ
: new_code
= EQ
; break;
746 case NE
: new_code
= NE
; break;
747 case LT
: new_code
= GTU
; break;
748 case GT
: new_code
= LTU
; break;
749 case LE
: new_code
= GEU
; break;
750 case GE
: new_code
= LEU
; break;
754 if (new_code
!= UNKNOWN
)
756 *op0
= XVECEXP (*op0
, 0, 0);
761 /* Remove redundant UNSPEC_CCZ_TO_INT conversions if possible. */
762 if (GET_CODE (*op0
) == UNSPEC
763 && XINT (*op0
, 1) == UNSPEC_CCZ_TO_INT
764 && XVECLEN (*op0
, 0) == 1
765 && GET_MODE (XVECEXP (*op0
, 0, 0)) == CCZmode
766 && GET_CODE (XVECEXP (*op0
, 0, 0)) == REG
767 && REGNO (XVECEXP (*op0
, 0, 0)) == CC_REGNUM
768 && *op1
== const0_rtx
)
770 enum rtx_code new_code
= UNKNOWN
;
773 case EQ
: new_code
= EQ
; break;
774 case NE
: new_code
= NE
; break;
778 if (new_code
!= UNKNOWN
)
780 *op0
= XVECEXP (*op0
, 0, 0);
785 /* Simplify cascaded EQ, NE with const0_rtx. */
786 if ((*code
== NE
|| *code
== EQ
)
787 && (GET_CODE (*op0
) == EQ
|| GET_CODE (*op0
) == NE
)
788 && GET_MODE (*op0
) == SImode
789 && GET_MODE (XEXP (*op0
, 0)) == CCZ1mode
790 && REG_P (XEXP (*op0
, 0))
791 && XEXP (*op0
, 1) == const0_rtx
792 && *op1
== const0_rtx
)
794 if ((*code
== EQ
&& GET_CODE (*op0
) == NE
)
795 || (*code
== NE
&& GET_CODE (*op0
) == EQ
))
799 *op0
= XEXP (*op0
, 0);
802 /* Prefer register over memory as first operand. */
803 if (MEM_P (*op0
) && REG_P (*op1
))
805 rtx tem
= *op0
; *op0
= *op1
; *op1
= tem
;
806 *code
= swap_condition (*code
);
810 /* Emit a compare instruction suitable to implement the comparison
811 OP0 CODE OP1. Return the correct condition RTL to be placed in
812 the IF_THEN_ELSE of the conditional branch testing the result. */
815 s390_emit_compare (enum rtx_code code
, rtx op0
, rtx op1
)
817 enum machine_mode mode
= s390_select_ccmode (code
, op0
, op1
);
820 /* Do not output a redundant compare instruction if a compare_and_swap
821 pattern already computed the result and the machine modes are compatible. */
822 if (GET_MODE_CLASS (GET_MODE (op0
)) == MODE_CC
)
824 gcc_assert (s390_cc_modes_compatible (GET_MODE (op0
), mode
)
830 cc
= gen_rtx_REG (mode
, CC_REGNUM
);
831 emit_insn (gen_rtx_SET (VOIDmode
, cc
, gen_rtx_COMPARE (mode
, op0
, op1
)));
834 return gen_rtx_fmt_ee (code
, VOIDmode
, cc
, const0_rtx
);
837 /* Emit a SImode compare and swap instruction setting MEM to NEW_RTX if OLD
839 Return the correct condition RTL to be placed in the IF_THEN_ELSE of the
840 conditional branch testing the result. */
843 s390_emit_compare_and_swap (enum rtx_code code
, rtx old
, rtx mem
, rtx cmp
, rtx new_rtx
)
845 emit_insn (gen_sync_compare_and_swapsi (old
, mem
, cmp
, new_rtx
));
846 return s390_emit_compare (code
, gen_rtx_REG (CCZ1mode
, CC_REGNUM
), const0_rtx
);
849 /* Emit a jump instruction to TARGET. If COND is NULL_RTX, emit an
850 unconditional jump, else a conditional jump under condition COND. */
853 s390_emit_jump (rtx target
, rtx cond
)
857 target
= gen_rtx_LABEL_REF (VOIDmode
, target
);
859 target
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, target
, pc_rtx
);
861 insn
= gen_rtx_SET (VOIDmode
, pc_rtx
, target
);
862 emit_jump_insn (insn
);
865 /* Return branch condition mask to implement a branch
866 specified by CODE. Return -1 for invalid comparisons. */
869 s390_branch_condition_mask (rtx code
)
871 const int CC0
= 1 << 3;
872 const int CC1
= 1 << 2;
873 const int CC2
= 1 << 1;
874 const int CC3
= 1 << 0;
876 gcc_assert (GET_CODE (XEXP (code
, 0)) == REG
);
877 gcc_assert (REGNO (XEXP (code
, 0)) == CC_REGNUM
);
878 gcc_assert (XEXP (code
, 1) == const0_rtx
);
880 switch (GET_MODE (XEXP (code
, 0)))
884 switch (GET_CODE (code
))
887 case NE
: return CC1
| CC2
| CC3
;
893 switch (GET_CODE (code
))
896 case NE
: return CC0
| CC2
| CC3
;
902 switch (GET_CODE (code
))
905 case NE
: return CC0
| CC1
| CC3
;
911 switch (GET_CODE (code
))
914 case NE
: return CC0
| CC1
| CC2
;
920 switch (GET_CODE (code
))
922 case EQ
: return CC0
| CC2
;
923 case NE
: return CC1
| CC3
;
929 switch (GET_CODE (code
))
931 case LTU
: return CC2
| CC3
; /* carry */
932 case GEU
: return CC0
| CC1
; /* no carry */
938 switch (GET_CODE (code
))
940 case GTU
: return CC0
| CC1
; /* borrow */
941 case LEU
: return CC2
| CC3
; /* no borrow */
947 switch (GET_CODE (code
))
949 case EQ
: return CC0
| CC2
;
950 case NE
: return CC1
| CC3
;
951 case LTU
: return CC1
;
952 case GTU
: return CC3
;
953 case LEU
: return CC1
| CC2
;
954 case GEU
: return CC2
| CC3
;
959 switch (GET_CODE (code
))
962 case NE
: return CC1
| CC2
| CC3
;
963 case LTU
: return CC1
;
964 case GTU
: return CC2
;
965 case LEU
: return CC0
| CC1
;
966 case GEU
: return CC0
| CC2
;
972 switch (GET_CODE (code
))
975 case NE
: return CC2
| CC1
| CC3
;
976 case LTU
: return CC2
;
977 case GTU
: return CC1
;
978 case LEU
: return CC0
| CC2
;
979 case GEU
: return CC0
| CC1
;
985 switch (GET_CODE (code
))
988 case NE
: return CC1
| CC2
| CC3
;
989 case LT
: return CC1
| CC3
;
991 case LE
: return CC0
| CC1
| CC3
;
992 case GE
: return CC0
| CC2
;
998 switch (GET_CODE (code
))
1000 case EQ
: return CC0
;
1001 case NE
: return CC1
| CC2
| CC3
;
1002 case LT
: return CC1
;
1003 case GT
: return CC2
| CC3
;
1004 case LE
: return CC0
| CC1
;
1005 case GE
: return CC0
| CC2
| CC3
;
1011 switch (GET_CODE (code
))
1013 case EQ
: return CC0
;
1014 case NE
: return CC1
| CC2
| CC3
;
1015 case LT
: return CC1
;
1016 case GT
: return CC2
;
1017 case LE
: return CC0
| CC1
;
1018 case GE
: return CC0
| CC2
;
1019 case UNORDERED
: return CC3
;
1020 case ORDERED
: return CC0
| CC1
| CC2
;
1021 case UNEQ
: return CC0
| CC3
;
1022 case UNLT
: return CC1
| CC3
;
1023 case UNGT
: return CC2
| CC3
;
1024 case UNLE
: return CC0
| CC1
| CC3
;
1025 case UNGE
: return CC0
| CC2
| CC3
;
1026 case LTGT
: return CC1
| CC2
;
1032 switch (GET_CODE (code
))
1034 case EQ
: return CC0
;
1035 case NE
: return CC2
| CC1
| CC3
;
1036 case LT
: return CC2
;
1037 case GT
: return CC1
;
1038 case LE
: return CC0
| CC2
;
1039 case GE
: return CC0
| CC1
;
1040 case UNORDERED
: return CC3
;
1041 case ORDERED
: return CC0
| CC2
| CC1
;
1042 case UNEQ
: return CC0
| CC3
;
1043 case UNLT
: return CC2
| CC3
;
1044 case UNGT
: return CC1
| CC3
;
1045 case UNLE
: return CC0
| CC2
| CC3
;
1046 case UNGE
: return CC0
| CC1
| CC3
;
1047 case LTGT
: return CC2
| CC1
;
1058 /* Return branch condition mask to implement a compare and branch
1059 specified by CODE. Return -1 for invalid comparisons. */
1062 s390_compare_and_branch_condition_mask (rtx code
)
1064 const int CC0
= 1 << 3;
1065 const int CC1
= 1 << 2;
1066 const int CC2
= 1 << 1;
1068 switch (GET_CODE (code
))
1092 /* If INV is false, return assembler mnemonic string to implement
1093 a branch specified by CODE. If INV is true, return mnemonic
1094 for the corresponding inverted branch. */
1097 s390_branch_condition_mnemonic (rtx code
, int inv
)
1101 static const char *const mnemonic
[16] =
1103 NULL
, "o", "h", "nle",
1104 "l", "nhe", "lh", "ne",
1105 "e", "nlh", "he", "nl",
1106 "le", "nh", "no", NULL
1109 if (GET_CODE (XEXP (code
, 0)) == REG
1110 && REGNO (XEXP (code
, 0)) == CC_REGNUM
1111 && XEXP (code
, 1) == const0_rtx
)
1112 mask
= s390_branch_condition_mask (code
);
1114 mask
= s390_compare_and_branch_condition_mask (code
);
1116 gcc_assert (mask
>= 0);
1121 gcc_assert (mask
>= 1 && mask
<= 14);
1123 return mnemonic
[mask
];
1126 /* Return the part of op which has a value different from def.
1127 The size of the part is determined by mode.
1128 Use this function only if you already know that op really
1129 contains such a part. */
1131 unsigned HOST_WIDE_INT
1132 s390_extract_part (rtx op
, enum machine_mode mode
, int def
)
1134 unsigned HOST_WIDE_INT value
= 0;
1135 int max_parts
= HOST_BITS_PER_WIDE_INT
/ GET_MODE_BITSIZE (mode
);
1136 int part_bits
= GET_MODE_BITSIZE (mode
);
1137 unsigned HOST_WIDE_INT part_mask
1138 = ((unsigned HOST_WIDE_INT
)1 << part_bits
) - 1;
1141 for (i
= 0; i
< max_parts
; i
++)
1144 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
1146 value
>>= part_bits
;
1148 if ((value
& part_mask
) != (def
& part_mask
))
1149 return value
& part_mask
;
1155 /* If OP is an integer constant of mode MODE with exactly one
1156 part of mode PART_MODE unequal to DEF, return the number of that
1157 part. Otherwise, return -1. */
1160 s390_single_part (rtx op
,
1161 enum machine_mode mode
,
1162 enum machine_mode part_mode
,
1165 unsigned HOST_WIDE_INT value
= 0;
1166 int n_parts
= GET_MODE_SIZE (mode
) / GET_MODE_SIZE (part_mode
);
1167 unsigned HOST_WIDE_INT part_mask
1168 = ((unsigned HOST_WIDE_INT
)1 << GET_MODE_BITSIZE (part_mode
)) - 1;
1171 if (GET_CODE (op
) != CONST_INT
)
1174 for (i
= 0; i
< n_parts
; i
++)
1177 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
1179 value
>>= GET_MODE_BITSIZE (part_mode
);
1181 if ((value
& part_mask
) != (def
& part_mask
))
1189 return part
== -1 ? -1 : n_parts
- 1 - part
;
1192 /* Return true if IN contains a contiguous bitfield in the lower SIZE
1193 bits and no other bits are set in IN. POS and LENGTH can be used
1194 to obtain the start position and the length of the bitfield.
1196 POS gives the position of the first bit of the bitfield counting
1197 from the lowest order bit starting with zero. In order to use this
1198 value for S/390 instructions this has to be converted to "bits big
1202 s390_contiguous_bitmask_p (unsigned HOST_WIDE_INT in
, int size
,
1203 int *pos
, int *length
)
1208 unsigned HOST_WIDE_INT mask
= 1ULL;
1209 bool contiguous
= false;
1211 for (i
= 0; i
< size
; mask
<<= 1, i
++)
1235 /* Calculate a mask for all bits beyond the contiguous bits. */
1236 mask
= (-1LL & ~(((1ULL << (tmp_length
+ tmp_pos
- 1)) << 1) - 1));
1241 if (tmp_length
+ tmp_pos
- 1 > size
)
1245 *length
= tmp_length
;
1253 /* Check whether we can (and want to) split a double-word
1254 move in mode MODE from SRC to DST into two single-word
1255 moves, moving the subword FIRST_SUBWORD first. */
1258 s390_split_ok_p (rtx dst
, rtx src
, enum machine_mode mode
, int first_subword
)
1260 /* Floating point registers cannot be split. */
1261 if (FP_REG_P (src
) || FP_REG_P (dst
))
1264 /* We don't need to split if operands are directly accessible. */
1265 if (s_operand (src
, mode
) || s_operand (dst
, mode
))
1268 /* Non-offsettable memory references cannot be split. */
1269 if ((GET_CODE (src
) == MEM
&& !offsettable_memref_p (src
))
1270 || (GET_CODE (dst
) == MEM
&& !offsettable_memref_p (dst
)))
1273 /* Moving the first subword must not clobber a register
1274 needed to move the second subword. */
1275 if (register_operand (dst
, mode
))
1277 rtx subreg
= operand_subword (dst
, first_subword
, 0, mode
);
1278 if (reg_overlap_mentioned_p (subreg
, src
))
1285 /* Return true if it can be proven that [MEM1, MEM1 + SIZE]
1286 and [MEM2, MEM2 + SIZE] do overlap and false
1290 s390_overlap_p (rtx mem1
, rtx mem2
, HOST_WIDE_INT size
)
1292 rtx addr1
, addr2
, addr_delta
;
1293 HOST_WIDE_INT delta
;
1295 if (GET_CODE (mem1
) != MEM
|| GET_CODE (mem2
) != MEM
)
1301 addr1
= XEXP (mem1
, 0);
1302 addr2
= XEXP (mem2
, 0);
1304 addr_delta
= simplify_binary_operation (MINUS
, Pmode
, addr2
, addr1
);
1306 /* This overlapping check is used by peepholes merging memory block operations.
1307 Overlapping operations would otherwise be recognized by the S/390 hardware
1308 and would fall back to a slower implementation. Allowing overlapping
1309 operations would lead to slow code but not to wrong code. Therefore we are
1310 somewhat optimistic if we cannot prove that the memory blocks are
1312 That's why we return false here although this may accept operations on
1313 overlapping memory areas. */
1314 if (!addr_delta
|| GET_CODE (addr_delta
) != CONST_INT
)
1317 delta
= INTVAL (addr_delta
);
1320 || (delta
> 0 && delta
< size
)
1321 || (delta
< 0 && -delta
< size
))
1327 /* Check whether the address of memory reference MEM2 equals exactly
1328 the address of memory reference MEM1 plus DELTA. Return true if
1329 we can prove this to be the case, false otherwise. */
1332 s390_offset_p (rtx mem1
, rtx mem2
, rtx delta
)
1334 rtx addr1
, addr2
, addr_delta
;
1336 if (GET_CODE (mem1
) != MEM
|| GET_CODE (mem2
) != MEM
)
1339 addr1
= XEXP (mem1
, 0);
1340 addr2
= XEXP (mem2
, 0);
1342 addr_delta
= simplify_binary_operation (MINUS
, Pmode
, addr2
, addr1
);
1343 if (!addr_delta
|| !rtx_equal_p (addr_delta
, delta
))
1349 /* Expand logical operator CODE in mode MODE with operands OPERANDS. */
1352 s390_expand_logical_operator (enum rtx_code code
, enum machine_mode mode
,
1355 enum machine_mode wmode
= mode
;
1356 rtx dst
= operands
[0];
1357 rtx src1
= operands
[1];
1358 rtx src2
= operands
[2];
1361 /* If we cannot handle the operation directly, use a temp register. */
1362 if (!s390_logical_operator_ok_p (operands
))
1363 dst
= gen_reg_rtx (mode
);
1365 /* QImode and HImode patterns make sense only if we have a destination
1366 in memory. Otherwise perform the operation in SImode. */
1367 if ((mode
== QImode
|| mode
== HImode
) && GET_CODE (dst
) != MEM
)
1370 /* Widen operands if required. */
1373 if (GET_CODE (dst
) == SUBREG
1374 && (tem
= simplify_subreg (wmode
, dst
, mode
, 0)) != 0)
1376 else if (REG_P (dst
))
1377 dst
= gen_rtx_SUBREG (wmode
, dst
, 0);
1379 dst
= gen_reg_rtx (wmode
);
1381 if (GET_CODE (src1
) == SUBREG
1382 && (tem
= simplify_subreg (wmode
, src1
, mode
, 0)) != 0)
1384 else if (GET_MODE (src1
) != VOIDmode
)
1385 src1
= gen_rtx_SUBREG (wmode
, force_reg (mode
, src1
), 0);
1387 if (GET_CODE (src2
) == SUBREG
1388 && (tem
= simplify_subreg (wmode
, src2
, mode
, 0)) != 0)
1390 else if (GET_MODE (src2
) != VOIDmode
)
1391 src2
= gen_rtx_SUBREG (wmode
, force_reg (mode
, src2
), 0);
1394 /* Emit the instruction. */
1395 op
= gen_rtx_SET (VOIDmode
, dst
, gen_rtx_fmt_ee (code
, wmode
, src1
, src2
));
1396 clob
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
1397 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, op
, clob
)));
1399 /* Fix up the destination if needed. */
1400 if (dst
!= operands
[0])
1401 emit_move_insn (operands
[0], gen_lowpart (mode
, dst
));
1404 /* Check whether OPERANDS are OK for a logical operation (AND, IOR, XOR). */
1407 s390_logical_operator_ok_p (rtx
*operands
)
1409 /* If the destination operand is in memory, it needs to coincide
1410 with one of the source operands. After reload, it has to be
1411 the first source operand. */
1412 if (GET_CODE (operands
[0]) == MEM
)
1413 return rtx_equal_p (operands
[0], operands
[1])
1414 || (!reload_completed
&& rtx_equal_p (operands
[0], operands
[2]));
1419 /* Narrow logical operation CODE of memory operand MEMOP with immediate
1420 operand IMMOP to switch from SS to SI type instructions. */
1423 s390_narrow_logical_operator (enum rtx_code code
, rtx
*memop
, rtx
*immop
)
1425 int def
= code
== AND
? -1 : 0;
1429 gcc_assert (GET_CODE (*memop
) == MEM
);
1430 gcc_assert (!MEM_VOLATILE_P (*memop
));
1432 mask
= s390_extract_part (*immop
, QImode
, def
);
1433 part
= s390_single_part (*immop
, GET_MODE (*memop
), QImode
, def
);
1434 gcc_assert (part
>= 0);
1436 *memop
= adjust_address (*memop
, QImode
, part
);
1437 *immop
= gen_int_mode (mask
, QImode
);
1441 /* How to allocate a 'struct machine_function'. */
1443 static struct machine_function
*
1444 s390_init_machine_status (void)
1446 return GGC_CNEW (struct machine_function
);
1449 /* Change optimizations to be performed, depending on the
1452 LEVEL is the optimization level specified; 2 if `-O2' is
1453 specified, 1 if `-O' is specified, and 0 if neither is specified.
1455 SIZE is nonzero if `-Os' is specified and zero otherwise. */
1458 optimization_options (int level ATTRIBUTE_UNUSED
, int size ATTRIBUTE_UNUSED
)
1460 /* ??? There are apparently still problems with -fcaller-saves. */
1461 flag_caller_saves
= 0;
1463 /* By default, always emit DWARF-2 unwind info. This allows debugging
1464 without maintaining a stack frame back-chain. */
1465 flag_asynchronous_unwind_tables
= 1;
1467 /* Use MVCLE instructions to decrease code size if requested. */
1469 target_flags
|= MASK_MVCLE
;
1472 /* Return true if ARG is the name of a processor. Set *TYPE and *FLAGS
1473 to the associated processor_type and processor_flags if so. */
1476 s390_handle_arch_option (const char *arg
,
1477 enum processor_type
*type
,
1482 const char *const name
; /* processor name or nickname. */
1483 const enum processor_type processor
;
1484 const int flags
; /* From enum processor_flags. */
1486 const processor_alias_table
[] =
1488 {"g5", PROCESSOR_9672_G5
, PF_IEEE_FLOAT
},
1489 {"g6", PROCESSOR_9672_G6
, PF_IEEE_FLOAT
},
1490 {"z900", PROCESSOR_2064_Z900
, PF_IEEE_FLOAT
| PF_ZARCH
},
1491 {"z990", PROCESSOR_2084_Z990
, PF_IEEE_FLOAT
| PF_ZARCH
1492 | PF_LONG_DISPLACEMENT
},
1493 {"z9-109", PROCESSOR_2094_Z9_109
, PF_IEEE_FLOAT
| PF_ZARCH
1494 | PF_LONG_DISPLACEMENT
| PF_EXTIMM
},
1495 {"z9-ec", PROCESSOR_2094_Z9_109
, PF_IEEE_FLOAT
| PF_ZARCH
1496 | PF_LONG_DISPLACEMENT
| PF_EXTIMM
| PF_DFP
},
1497 {"z10", PROCESSOR_2097_Z10
, PF_IEEE_FLOAT
| PF_ZARCH
1498 | PF_LONG_DISPLACEMENT
| PF_EXTIMM
| PF_DFP
| PF_Z10
},
1502 for (i
= 0; i
< ARRAY_SIZE (processor_alias_table
); i
++)
1503 if (strcmp (arg
, processor_alias_table
[i
].name
) == 0)
1505 *type
= processor_alias_table
[i
].processor
;
1506 *flags
= processor_alias_table
[i
].flags
;
1512 /* Implement TARGET_HANDLE_OPTION. */
1515 s390_handle_option (size_t code
, const char *arg
, int value ATTRIBUTE_UNUSED
)
1520 return s390_handle_arch_option (arg
, &s390_arch
, &s390_arch_flags
);
1522 case OPT_mstack_guard_
:
1523 if (sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_stack_guard
) != 1)
1525 if (exact_log2 (s390_stack_guard
) == -1)
1526 error ("stack guard value must be an exact power of 2");
1529 case OPT_mstack_size_
:
1530 if (sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_stack_size
) != 1)
1532 if (exact_log2 (s390_stack_size
) == -1)
1533 error ("stack size must be an exact power of 2");
1537 return s390_handle_arch_option (arg
, &s390_tune
, &s390_tune_flags
);
1539 case OPT_mwarn_framesize_
:
1540 return sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_warn_framesize
) == 1;
1548 override_options (void)
1550 /* Set up function hooks. */
1551 init_machine_status
= s390_init_machine_status
;
1553 /* Architecture mode defaults according to ABI. */
1554 if (!(target_flags_explicit
& MASK_ZARCH
))
1557 target_flags
|= MASK_ZARCH
;
1559 target_flags
&= ~MASK_ZARCH
;
1562 /* Determine processor architectural level. */
1563 if (!s390_arch_string
)
1565 s390_arch_string
= TARGET_ZARCH
? "z900" : "g5";
1566 s390_handle_arch_option (s390_arch_string
, &s390_arch
, &s390_arch_flags
);
1569 /* Determine processor to tune for. */
1570 if (s390_tune
== PROCESSOR_max
)
1572 s390_tune
= s390_arch
;
1573 s390_tune_flags
= s390_arch_flags
;
1576 /* Sanity checks. */
1577 if (TARGET_ZARCH
&& !TARGET_CPU_ZARCH
)
1578 error ("z/Architecture mode not supported on %s", s390_arch_string
);
1579 if (TARGET_64BIT
&& !TARGET_ZARCH
)
1580 error ("64-bit ABI not supported in ESA/390 mode");
1582 if (TARGET_HARD_DFP
&& !TARGET_DFP
)
1584 if (target_flags_explicit
& MASK_HARD_DFP
)
1586 if (!TARGET_CPU_DFP
)
1587 error ("Hardware decimal floating point instructions"
1588 " not available on %s", s390_arch_string
);
1590 error ("Hardware decimal floating point instructions"
1591 " not available in ESA/390 mode");
1594 target_flags
&= ~MASK_HARD_DFP
;
1597 if ((target_flags_explicit
& MASK_SOFT_FLOAT
) && TARGET_SOFT_FLOAT
)
1599 if ((target_flags_explicit
& MASK_HARD_DFP
) && TARGET_HARD_DFP
)
1600 error ("-mhard-dfp can't be used in conjunction with -msoft-float");
1602 target_flags
&= ~MASK_HARD_DFP
;
1605 /* Set processor cost function. */
1608 case PROCESSOR_2084_Z990
:
1609 s390_cost
= &z990_cost
;
1611 case PROCESSOR_2094_Z9_109
:
1612 s390_cost
= &z9_109_cost
;
1614 case PROCESSOR_2097_Z10
:
1615 s390_cost
= &z10_cost
;
1618 s390_cost
= &z900_cost
;
1621 if (TARGET_BACKCHAIN
&& TARGET_PACKED_STACK
&& TARGET_HARD_FLOAT
)
1622 error ("-mbackchain -mpacked-stack -mhard-float are not supported "
1625 if (s390_stack_size
)
1627 if (s390_stack_guard
>= s390_stack_size
)
1628 error ("stack size must be greater than the stack guard value");
1629 else if (s390_stack_size
> 1 << 16)
1630 error ("stack size must not be greater than 64k");
1632 else if (s390_stack_guard
)
1633 error ("-mstack-guard implies use of -mstack-size");
1635 #ifdef TARGET_DEFAULT_LONG_DOUBLE_128
1636 if (!(target_flags_explicit
& MASK_LONG_DOUBLE_128
))
1637 target_flags
|= MASK_LONG_DOUBLE_128
;
1640 if (s390_tune
== PROCESSOR_2097_Z10
)
1642 if (!PARAM_SET_P (PARAM_MAX_UNROLLED_INSNS
))
1643 set_param_value ("max-unrolled-insns", 100);
1644 if (!PARAM_SET_P (PARAM_MAX_UNROLL_TIMES
))
1645 set_param_value ("max-unroll-times", 32);
1646 if (!PARAM_SET_P (PARAM_MAX_COMPLETELY_PEELED_INSNS
))
1647 set_param_value ("max-completely-peeled-insns", 800);
1648 if (!PARAM_SET_P (PARAM_MAX_COMPLETELY_PEEL_TIMES
))
1649 set_param_value ("max-completely-peel-times", 64);
1652 set_param_value ("max-pending-list-length", 256);
1655 /* Map for smallest class containing reg regno. */
1657 const enum reg_class regclass_map
[FIRST_PSEUDO_REGISTER
] =
1658 { GENERAL_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1659 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1660 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1661 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1662 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1663 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1664 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1665 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1666 ADDR_REGS
, CC_REGS
, ADDR_REGS
, ADDR_REGS
,
1667 ACCESS_REGS
, ACCESS_REGS
1670 /* Return attribute type of insn. */
1672 static enum attr_type
1673 s390_safe_attr_type (rtx insn
)
1675 if (recog_memoized (insn
) >= 0)
1676 return get_attr_type (insn
);
1681 /* Return true if DISP is a valid short displacement. */
1684 s390_short_displacement (rtx disp
)
1686 /* No displacement is OK. */
1690 /* Without the long displacement facility we don't need to
1691 distingiush between long and short displacement. */
1692 if (!TARGET_LONG_DISPLACEMENT
)
1695 /* Integer displacement in range. */
1696 if (GET_CODE (disp
) == CONST_INT
)
1697 return INTVAL (disp
) >= 0 && INTVAL (disp
) < 4096;
1699 /* GOT offset is not OK, the GOT can be large. */
1700 if (GET_CODE (disp
) == CONST
1701 && GET_CODE (XEXP (disp
, 0)) == UNSPEC
1702 && (XINT (XEXP (disp
, 0), 1) == UNSPEC_GOT
1703 || XINT (XEXP (disp
, 0), 1) == UNSPEC_GOTNTPOFF
))
1706 /* All other symbolic constants are literal pool references,
1707 which are OK as the literal pool must be small. */
1708 if (GET_CODE (disp
) == CONST
)
1714 /* Decompose a RTL expression ADDR for a memory address into
1715 its components, returned in OUT.
1717 Returns false if ADDR is not a valid memory address, true
1718 otherwise. If OUT is NULL, don't return the components,
1719 but check for validity only.
1721 Note: Only addresses in canonical form are recognized.
1722 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
1723 canonical form so that they will be recognized. */
1726 s390_decompose_address (rtx addr
, struct s390_address
*out
)
1728 HOST_WIDE_INT offset
= 0;
1729 rtx base
= NULL_RTX
;
1730 rtx indx
= NULL_RTX
;
1731 rtx disp
= NULL_RTX
;
1733 bool pointer
= false;
1734 bool base_ptr
= false;
1735 bool indx_ptr
= false;
1736 bool literal_pool
= false;
1738 /* We may need to substitute the literal pool base register into the address
1739 below. However, at this point we do not know which register is going to
1740 be used as base, so we substitute the arg pointer register. This is going
1741 to be treated as holding a pointer below -- it shouldn't be used for any
1743 rtx fake_pool_base
= gen_rtx_REG (Pmode
, ARG_POINTER_REGNUM
);
1745 /* Decompose address into base + index + displacement. */
1747 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == UNSPEC
)
1750 else if (GET_CODE (addr
) == PLUS
)
1752 rtx op0
= XEXP (addr
, 0);
1753 rtx op1
= XEXP (addr
, 1);
1754 enum rtx_code code0
= GET_CODE (op0
);
1755 enum rtx_code code1
= GET_CODE (op1
);
1757 if (code0
== REG
|| code0
== UNSPEC
)
1759 if (code1
== REG
|| code1
== UNSPEC
)
1761 indx
= op0
; /* index + base */
1767 base
= op0
; /* base + displacement */
1772 else if (code0
== PLUS
)
1774 indx
= XEXP (op0
, 0); /* index + base + disp */
1775 base
= XEXP (op0
, 1);
1786 disp
= addr
; /* displacement */
1788 /* Extract integer part of displacement. */
1792 if (GET_CODE (disp
) == CONST_INT
)
1794 offset
= INTVAL (disp
);
1797 else if (GET_CODE (disp
) == CONST
1798 && GET_CODE (XEXP (disp
, 0)) == PLUS
1799 && GET_CODE (XEXP (XEXP (disp
, 0), 1)) == CONST_INT
)
1801 offset
= INTVAL (XEXP (XEXP (disp
, 0), 1));
1802 disp
= XEXP (XEXP (disp
, 0), 0);
1806 /* Strip off CONST here to avoid special case tests later. */
1807 if (disp
&& GET_CODE (disp
) == CONST
)
1808 disp
= XEXP (disp
, 0);
1810 /* We can convert literal pool addresses to
1811 displacements by basing them off the base register. */
1812 if (disp
&& GET_CODE (disp
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (disp
))
1814 /* Either base or index must be free to hold the base register. */
1816 base
= fake_pool_base
, literal_pool
= true;
1818 indx
= fake_pool_base
, literal_pool
= true;
1822 /* Mark up the displacement. */
1823 disp
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, disp
),
1824 UNSPEC_LTREL_OFFSET
);
1827 /* Validate base register. */
1830 if (GET_CODE (base
) == UNSPEC
)
1831 switch (XINT (base
, 1))
1835 disp
= gen_rtx_UNSPEC (Pmode
,
1836 gen_rtvec (1, XVECEXP (base
, 0, 0)),
1837 UNSPEC_LTREL_OFFSET
);
1841 base
= XVECEXP (base
, 0, 1);
1844 case UNSPEC_LTREL_BASE
:
1845 if (XVECLEN (base
, 0) == 1)
1846 base
= fake_pool_base
, literal_pool
= true;
1848 base
= XVECEXP (base
, 0, 1);
1856 || (GET_MODE (base
) != SImode
1857 && GET_MODE (base
) != Pmode
))
1860 if (REGNO (base
) == STACK_POINTER_REGNUM
1861 || REGNO (base
) == FRAME_POINTER_REGNUM
1862 || ((reload_completed
|| reload_in_progress
)
1863 && frame_pointer_needed
1864 && REGNO (base
) == HARD_FRAME_POINTER_REGNUM
)
1865 || REGNO (base
) == ARG_POINTER_REGNUM
1867 && REGNO (base
) == PIC_OFFSET_TABLE_REGNUM
))
1868 pointer
= base_ptr
= true;
1870 if ((reload_completed
|| reload_in_progress
)
1871 && base
== cfun
->machine
->base_reg
)
1872 pointer
= base_ptr
= literal_pool
= true;
1875 /* Validate index register. */
1878 if (GET_CODE (indx
) == UNSPEC
)
1879 switch (XINT (indx
, 1))
1883 disp
= gen_rtx_UNSPEC (Pmode
,
1884 gen_rtvec (1, XVECEXP (indx
, 0, 0)),
1885 UNSPEC_LTREL_OFFSET
);
1889 indx
= XVECEXP (indx
, 0, 1);
1892 case UNSPEC_LTREL_BASE
:
1893 if (XVECLEN (indx
, 0) == 1)
1894 indx
= fake_pool_base
, literal_pool
= true;
1896 indx
= XVECEXP (indx
, 0, 1);
1904 || (GET_MODE (indx
) != SImode
1905 && GET_MODE (indx
) != Pmode
))
1908 if (REGNO (indx
) == STACK_POINTER_REGNUM
1909 || REGNO (indx
) == FRAME_POINTER_REGNUM
1910 || ((reload_completed
|| reload_in_progress
)
1911 && frame_pointer_needed
1912 && REGNO (indx
) == HARD_FRAME_POINTER_REGNUM
)
1913 || REGNO (indx
) == ARG_POINTER_REGNUM
1915 && REGNO (indx
) == PIC_OFFSET_TABLE_REGNUM
))
1916 pointer
= indx_ptr
= true;
1918 if ((reload_completed
|| reload_in_progress
)
1919 && indx
== cfun
->machine
->base_reg
)
1920 pointer
= indx_ptr
= literal_pool
= true;
1923 /* Prefer to use pointer as base, not index. */
1924 if (base
&& indx
&& !base_ptr
1925 && (indx_ptr
|| (!REG_POINTER (base
) && REG_POINTER (indx
))))
1932 /* Validate displacement. */
1935 /* If virtual registers are involved, the displacement will change later
1936 anyway as the virtual registers get eliminated. This could make a
1937 valid displacement invalid, but it is more likely to make an invalid
1938 displacement valid, because we sometimes access the register save area
1939 via negative offsets to one of those registers.
1940 Thus we don't check the displacement for validity here. If after
1941 elimination the displacement turns out to be invalid after all,
1942 this is fixed up by reload in any case. */
1943 if (base
!= arg_pointer_rtx
1944 && indx
!= arg_pointer_rtx
1945 && base
!= return_address_pointer_rtx
1946 && indx
!= return_address_pointer_rtx
1947 && base
!= frame_pointer_rtx
1948 && indx
!= frame_pointer_rtx
1949 && base
!= virtual_stack_vars_rtx
1950 && indx
!= virtual_stack_vars_rtx
)
1951 if (!DISP_IN_RANGE (offset
))
1956 /* All the special cases are pointers. */
1959 /* In the small-PIC case, the linker converts @GOT
1960 and @GOTNTPOFF offsets to possible displacements. */
1961 if (GET_CODE (disp
) == UNSPEC
1962 && (XINT (disp
, 1) == UNSPEC_GOT
1963 || XINT (disp
, 1) == UNSPEC_GOTNTPOFF
)
1969 /* Accept pool label offsets. */
1970 else if (GET_CODE (disp
) == UNSPEC
1971 && XINT (disp
, 1) == UNSPEC_POOL_OFFSET
)
1974 /* Accept literal pool references. */
1975 else if (GET_CODE (disp
) == UNSPEC
1976 && XINT (disp
, 1) == UNSPEC_LTREL_OFFSET
)
1978 orig_disp
= gen_rtx_CONST (Pmode
, disp
);
1981 /* If we have an offset, make sure it does not
1982 exceed the size of the constant pool entry. */
1983 rtx sym
= XVECEXP (disp
, 0, 0);
1984 if (offset
>= GET_MODE_SIZE (get_pool_mode (sym
)))
1987 orig_disp
= plus_constant (orig_disp
, offset
);
2002 out
->disp
= orig_disp
;
2003 out
->pointer
= pointer
;
2004 out
->literal_pool
= literal_pool
;
2010 /* Decompose a RTL expression OP for a shift count into its components,
2011 and return the base register in BASE and the offset in OFFSET.
2013 Return true if OP is a valid shift count, false if not. */
2016 s390_decompose_shift_count (rtx op
, rtx
*base
, HOST_WIDE_INT
*offset
)
2018 HOST_WIDE_INT off
= 0;
2020 /* We can have an integer constant, an address register,
2021 or a sum of the two. */
2022 if (GET_CODE (op
) == CONST_INT
)
2027 if (op
&& GET_CODE (op
) == PLUS
&& GET_CODE (XEXP (op
, 1)) == CONST_INT
)
2029 off
= INTVAL (XEXP (op
, 1));
2032 while (op
&& GET_CODE (op
) == SUBREG
)
2033 op
= SUBREG_REG (op
);
2035 if (op
&& GET_CODE (op
) != REG
)
2047 /* Return true if CODE is a valid address without index. */
2050 s390_legitimate_address_without_index_p (rtx op
)
2052 struct s390_address addr
;
2054 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
2063 /* Return true if ADDR is of kind symbol_ref or symbol_ref + const_int
2064 and return these parts in SYMREF and ADDEND. You can pass NULL in
2065 SYMREF and/or ADDEND if you are not interested in these values. */
2068 s390_symref_operand_p (rtx addr
, rtx
*symref
, HOST_WIDE_INT
*addend
)
2070 HOST_WIDE_INT tmpaddend
= 0;
2072 if (GET_CODE (addr
) == CONST
)
2073 addr
= XEXP (addr
, 0);
2075 if (GET_CODE (addr
) == PLUS
)
2077 if (GET_CODE (XEXP (addr
, 0)) == SYMBOL_REF
2078 && CONST_INT_P (XEXP (addr
, 1)))
2080 tmpaddend
= INTVAL (XEXP (addr
, 1));
2081 addr
= XEXP (addr
, 0);
2087 if (GET_CODE (addr
) != SYMBOL_REF
)
2093 *addend
= tmpaddend
;
2099 /* Return true if the address in OP is valid for constraint letter C
2100 if wrapped in a MEM rtx. Set LIT_POOL_OK to true if it literal
2101 pool MEMs should be accepted. Only the Q, R, S, T constraint
2102 letters are allowed for C. */
2105 s390_check_qrst_address (char c
, rtx op
, bool lit_pool_ok
)
2107 struct s390_address addr
;
2108 bool decomposed
= false;
2110 /* This check makes sure that no symbolic address (except literal
2111 pool references) are accepted by the R or T constraints. */
2112 if (s390_symref_operand_p (op
, NULL
, NULL
))
2116 if (!s390_decompose_address (op
, &addr
))
2118 if (!addr
.literal_pool
)
2125 case 'Q': /* no index short displacement */
2126 if (!decomposed
&& !s390_decompose_address (op
, &addr
))
2130 if (!s390_short_displacement (addr
.disp
))
2134 case 'R': /* with index short displacement */
2135 if (TARGET_LONG_DISPLACEMENT
)
2137 if (!decomposed
&& !s390_decompose_address (op
, &addr
))
2139 if (!s390_short_displacement (addr
.disp
))
2142 /* Any invalid address here will be fixed up by reload,
2143 so accept it for the most generic constraint. */
2146 case 'S': /* no index long displacement */
2147 if (!TARGET_LONG_DISPLACEMENT
)
2149 if (!decomposed
&& !s390_decompose_address (op
, &addr
))
2153 if (s390_short_displacement (addr
.disp
))
2157 case 'T': /* with index long displacement */
2158 if (!TARGET_LONG_DISPLACEMENT
)
2160 /* Any invalid address here will be fixed up by reload,
2161 so accept it for the most generic constraint. */
2162 if ((decomposed
|| s390_decompose_address (op
, &addr
))
2163 && s390_short_displacement (addr
.disp
))
2173 /* Evaluates constraint strings described by the regular expression
2174 ([A|B|Z](Q|R|S|T))|U|W|Y and returns 1 if OP is a valid operand for
2175 the constraint given in STR, or 0 else. */
2178 s390_mem_constraint (const char *str
, rtx op
)
2185 /* Check for offsettable variants of memory constraints. */
2186 if (!MEM_P (op
) || MEM_VOLATILE_P (op
))
2188 if ((reload_completed
|| reload_in_progress
)
2189 ? !offsettable_memref_p (op
) : !offsettable_nonstrict_memref_p (op
))
2191 return s390_check_qrst_address (str
[1], XEXP (op
, 0), true);
2193 /* Check for non-literal-pool variants of memory constraints. */
2196 return s390_check_qrst_address (str
[1], XEXP (op
, 0), false);
2201 if (GET_CODE (op
) != MEM
)
2203 return s390_check_qrst_address (c
, XEXP (op
, 0), true);
2205 return (s390_check_qrst_address ('Q', op
, true)
2206 || s390_check_qrst_address ('R', op
, true));
2208 return (s390_check_qrst_address ('S', op
, true)
2209 || s390_check_qrst_address ('T', op
, true));
2211 /* Simply check for the basic form of a shift count. Reload will
2212 take care of making sure we have a proper base register. */
2213 if (!s390_decompose_shift_count (op
, NULL
, NULL
))
2217 return s390_check_qrst_address (str
[1], op
, true);
2225 /* Evaluates constraint strings starting with letter O. Input
2226 parameter C is the second letter following the "O" in the constraint
2227 string. Returns 1 if VALUE meets the respective constraint and 0
2231 s390_O_constraint_str (const char c
, HOST_WIDE_INT value
)
2239 return trunc_int_for_mode (value
, SImode
) == value
;
2243 || s390_single_part (GEN_INT (value
), DImode
, SImode
, 0) == 1;
2246 return s390_single_part (GEN_INT (value
- 1), DImode
, SImode
, -1) == 1;
2254 /* Evaluates constraint strings starting with letter N. Parameter STR
2255 contains the letters following letter "N" in the constraint string.
2256 Returns true if VALUE matches the constraint. */
2259 s390_N_constraint_str (const char *str
, HOST_WIDE_INT value
)
2261 enum machine_mode mode
, part_mode
;
2263 int part
, part_goal
;
2269 part_goal
= str
[0] - '0';
2313 if (GET_MODE_SIZE (mode
) <= GET_MODE_SIZE (part_mode
))
2316 part
= s390_single_part (GEN_INT (value
), mode
, part_mode
, def
);
2319 if (part_goal
!= -1 && part_goal
!= part
)
2326 /* Returns true if the input parameter VALUE is a float zero. */
2329 s390_float_const_zero_p (rtx value
)
2331 return (GET_MODE_CLASS (GET_MODE (value
)) == MODE_FLOAT
2332 && value
== CONST0_RTX (GET_MODE (value
)));
2336 /* Compute a (partial) cost for rtx X. Return true if the complete
2337 cost has been computed, and false if subexpressions should be
2338 scanned. In either case, *TOTAL contains the cost result.
2339 CODE contains GET_CODE (x), OUTER_CODE contains the code
2340 of the superexpression of x. */
2343 s390_rtx_costs (rtx x
, int code
, int outer_code
, int *total
,
2344 bool speed ATTRIBUTE_UNUSED
)
2367 *total
= COSTS_N_INSNS (1);
2372 /* Check for multiply and add. */
2373 if ((GET_MODE (x
) == DFmode
|| GET_MODE (x
) == SFmode
)
2374 && GET_CODE (XEXP (x
, 0)) == MULT
2375 && TARGET_HARD_FLOAT
&& TARGET_FUSED_MADD
)
2377 /* This is the multiply and add case. */
2378 if (GET_MODE (x
) == DFmode
)
2379 *total
= s390_cost
->madbr
;
2381 *total
= s390_cost
->maebr
;
2382 *total
+= (rtx_cost (XEXP (XEXP (x
, 0), 0), MULT
, speed
)
2383 + rtx_cost (XEXP (XEXP (x
, 0), 1), MULT
, speed
)
2384 + rtx_cost (XEXP (x
, 1), (enum rtx_code
) code
, speed
));
2385 return true; /* Do not do an additional recursive descent. */
2387 *total
= COSTS_N_INSNS (1);
2391 switch (GET_MODE (x
))
2395 rtx left
= XEXP (x
, 0);
2396 rtx right
= XEXP (x
, 1);
2397 if (GET_CODE (right
) == CONST_INT
2398 && CONST_OK_FOR_K (INTVAL (right
)))
2399 *total
= s390_cost
->mhi
;
2400 else if (GET_CODE (left
) == SIGN_EXTEND
)
2401 *total
= s390_cost
->mh
;
2403 *total
= s390_cost
->ms
; /* msr, ms, msy */
2408 rtx left
= XEXP (x
, 0);
2409 rtx right
= XEXP (x
, 1);
2412 if (GET_CODE (right
) == CONST_INT
2413 && CONST_OK_FOR_K (INTVAL (right
)))
2414 *total
= s390_cost
->mghi
;
2415 else if (GET_CODE (left
) == SIGN_EXTEND
)
2416 *total
= s390_cost
->msgf
;
2418 *total
= s390_cost
->msg
; /* msgr, msg */
2420 else /* TARGET_31BIT */
2422 if (GET_CODE (left
) == SIGN_EXTEND
2423 && GET_CODE (right
) == SIGN_EXTEND
)
2424 /* mulsidi case: mr, m */
2425 *total
= s390_cost
->m
;
2426 else if (GET_CODE (left
) == ZERO_EXTEND
2427 && GET_CODE (right
) == ZERO_EXTEND
2428 && TARGET_CPU_ZARCH
)
2429 /* umulsidi case: ml, mlr */
2430 *total
= s390_cost
->ml
;
2432 /* Complex calculation is required. */
2433 *total
= COSTS_N_INSNS (40);
2439 *total
= s390_cost
->mult_df
;
2442 *total
= s390_cost
->mxbr
;
2451 if (GET_MODE (x
) == TImode
) /* 128 bit division */
2452 *total
= s390_cost
->dlgr
;
2453 else if (GET_MODE (x
) == DImode
)
2455 rtx right
= XEXP (x
, 1);
2456 if (GET_CODE (right
) == ZERO_EXTEND
) /* 64 by 32 bit division */
2457 *total
= s390_cost
->dlr
;
2458 else /* 64 by 64 bit division */
2459 *total
= s390_cost
->dlgr
;
2461 else if (GET_MODE (x
) == SImode
) /* 32 bit division */
2462 *total
= s390_cost
->dlr
;
2467 if (GET_MODE (x
) == DImode
)
2469 rtx right
= XEXP (x
, 1);
2470 if (GET_CODE (right
) == ZERO_EXTEND
) /* 64 by 32 bit division */
2472 *total
= s390_cost
->dsgfr
;
2474 *total
= s390_cost
->dr
;
2475 else /* 64 by 64 bit division */
2476 *total
= s390_cost
->dsgr
;
2478 else if (GET_MODE (x
) == SImode
) /* 32 bit division */
2479 *total
= s390_cost
->dlr
;
2480 else if (GET_MODE (x
) == SFmode
)
2482 *total
= s390_cost
->debr
;
2484 else if (GET_MODE (x
) == DFmode
)
2486 *total
= s390_cost
->ddbr
;
2488 else if (GET_MODE (x
) == TFmode
)
2490 *total
= s390_cost
->dxbr
;
2495 if (GET_MODE (x
) == SFmode
)
2496 *total
= s390_cost
->sqebr
;
2497 else if (GET_MODE (x
) == DFmode
)
2498 *total
= s390_cost
->sqdbr
;
2500 *total
= s390_cost
->sqxbr
;
2505 if (outer_code
== MULT
|| outer_code
== DIV
|| outer_code
== MOD
2506 || outer_code
== PLUS
|| outer_code
== MINUS
2507 || outer_code
== COMPARE
)
2512 *total
= COSTS_N_INSNS (1);
2513 if (GET_CODE (XEXP (x
, 0)) == AND
2514 && GET_CODE (XEXP (x
, 1)) == CONST_INT
2515 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
)
2517 rtx op0
= XEXP (XEXP (x
, 0), 0);
2518 rtx op1
= XEXP (XEXP (x
, 0), 1);
2519 rtx op2
= XEXP (x
, 1);
2521 if (memory_operand (op0
, GET_MODE (op0
))
2522 && s390_tm_ccmode (op1
, op2
, 0) != VOIDmode
)
2524 if (register_operand (op0
, GET_MODE (op0
))
2525 && s390_tm_ccmode (op1
, op2
, 1) != VOIDmode
)
2535 /* Return the cost of an address rtx ADDR. */
2538 s390_address_cost (rtx addr
, bool speed ATTRIBUTE_UNUSED
)
2540 struct s390_address ad
;
2541 if (!s390_decompose_address (addr
, &ad
))
2544 return ad
.indx
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
2547 /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
2548 otherwise return 0. */
2551 tls_symbolic_operand (rtx op
)
2553 if (GET_CODE (op
) != SYMBOL_REF
)
2555 return SYMBOL_REF_TLS_MODEL (op
);
2558 /* Split DImode access register reference REG (on 64-bit) into its constituent
2559 low and high parts, and store them into LO and HI. Note that gen_lowpart/
2560 gen_highpart cannot be used as they assume all registers are word-sized,
2561 while our access registers have only half that size. */
2564 s390_split_access_reg (rtx reg
, rtx
*lo
, rtx
*hi
)
2566 gcc_assert (TARGET_64BIT
);
2567 gcc_assert (ACCESS_REG_P (reg
));
2568 gcc_assert (GET_MODE (reg
) == DImode
);
2569 gcc_assert (!(REGNO (reg
) & 1));
2571 *lo
= gen_rtx_REG (SImode
, REGNO (reg
) + 1);
2572 *hi
= gen_rtx_REG (SImode
, REGNO (reg
));
2575 /* Return true if OP contains a symbol reference */
2578 symbolic_reference_mentioned_p (rtx op
)
2583 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
2586 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
2587 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
2593 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
2594 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
2598 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
2605 /* Return true if OP contains a reference to a thread-local symbol. */
2608 tls_symbolic_reference_mentioned_p (rtx op
)
2613 if (GET_CODE (op
) == SYMBOL_REF
)
2614 return tls_symbolic_operand (op
);
2616 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
2617 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
2623 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
2624 if (tls_symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
2628 else if (fmt
[i
] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op
, i
)))
2636 /* Return true if OP is a legitimate general operand when
2637 generating PIC code. It is given that flag_pic is on
2638 and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2641 legitimate_pic_operand_p (rtx op
)
2643 /* Accept all non-symbolic constants. */
2644 if (!SYMBOLIC_CONST (op
))
2647 /* Reject everything else; must be handled
2648 via emit_symbolic_move. */
2652 /* Returns true if the constant value OP is a legitimate general operand.
2653 It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2656 legitimate_constant_p (rtx op
)
2658 /* Accept all non-symbolic constants. */
2659 if (!SYMBOLIC_CONST (op
))
2662 /* Accept immediate LARL operands. */
2663 if (TARGET_CPU_ZARCH
&& larl_operand (op
, VOIDmode
))
2666 /* Thread-local symbols are never legal constants. This is
2667 so that emit_call knows that computing such addresses
2668 might require a function call. */
2669 if (TLS_SYMBOLIC_CONST (op
))
2672 /* In the PIC case, symbolic constants must *not* be
2673 forced into the literal pool. We accept them here,
2674 so that they will be handled by emit_symbolic_move. */
2678 /* All remaining non-PIC symbolic constants are
2679 forced into the literal pool. */
2683 /* Determine if it's legal to put X into the constant pool. This
2684 is not possible if X contains the address of a symbol that is
2685 not constant (TLS) or not known at final link time (PIC). */
2688 s390_cannot_force_const_mem (rtx x
)
2690 switch (GET_CODE (x
))
2694 /* Accept all non-symbolic constants. */
2698 /* Labels are OK iff we are non-PIC. */
2699 return flag_pic
!= 0;
2702 /* 'Naked' TLS symbol references are never OK,
2703 non-TLS symbols are OK iff we are non-PIC. */
2704 if (tls_symbolic_operand (x
))
2707 return flag_pic
!= 0;
2710 return s390_cannot_force_const_mem (XEXP (x
, 0));
2713 return s390_cannot_force_const_mem (XEXP (x
, 0))
2714 || s390_cannot_force_const_mem (XEXP (x
, 1));
2717 switch (XINT (x
, 1))
2719 /* Only lt-relative or GOT-relative UNSPECs are OK. */
2720 case UNSPEC_LTREL_OFFSET
:
2728 case UNSPEC_GOTNTPOFF
:
2729 case UNSPEC_INDNTPOFF
:
2732 /* If the literal pool shares the code section, be put
2733 execute template placeholders into the pool as well. */
2735 return TARGET_CPU_ZARCH
;
2747 /* Returns true if the constant value OP is a legitimate general
2748 operand during and after reload. The difference to
2749 legitimate_constant_p is that this function will not accept
2750 a constant that would need to be forced to the literal pool
2751 before it can be used as operand. */
2754 legitimate_reload_constant_p (rtx op
)
2756 /* Accept la(y) operands. */
2757 if (GET_CODE (op
) == CONST_INT
2758 && DISP_IN_RANGE (INTVAL (op
)))
2761 /* Accept l(g)hi/l(g)fi operands. */
2762 if (GET_CODE (op
) == CONST_INT
2763 && (CONST_OK_FOR_K (INTVAL (op
)) || CONST_OK_FOR_Os (INTVAL (op
))))
2766 /* Accept lliXX operands. */
2768 && GET_CODE (op
) == CONST_INT
2769 && trunc_int_for_mode (INTVAL (op
), word_mode
) == INTVAL (op
)
2770 && s390_single_part (op
, word_mode
, HImode
, 0) >= 0)
2774 && GET_CODE (op
) == CONST_INT
2775 && trunc_int_for_mode (INTVAL (op
), word_mode
) == INTVAL (op
)
2776 && s390_single_part (op
, word_mode
, SImode
, 0) >= 0)
2779 /* Accept larl operands. */
2780 if (TARGET_CPU_ZARCH
2781 && larl_operand (op
, VOIDmode
))
2784 /* Accept lzXX operands. */
2785 if (GET_CODE (op
) == CONST_DOUBLE
2786 && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op
, 'G', "G"))
2789 /* Accept double-word operands that can be split. */
2790 if (GET_CODE (op
) == CONST_INT
2791 && trunc_int_for_mode (INTVAL (op
), word_mode
) != INTVAL (op
))
2793 enum machine_mode dword_mode
= word_mode
== SImode
? DImode
: TImode
;
2794 rtx hi
= operand_subword (op
, 0, 0, dword_mode
);
2795 rtx lo
= operand_subword (op
, 1, 0, dword_mode
);
2796 return legitimate_reload_constant_p (hi
)
2797 && legitimate_reload_constant_p (lo
);
2800 /* Everything else cannot be handled without reload. */
2804 /* Given an rtx OP being reloaded into a reg required to be in class RCLASS,
2805 return the class of reg to actually use. */
2808 s390_preferred_reload_class (rtx op
, enum reg_class rclass
)
2810 switch (GET_CODE (op
))
2812 /* Constants we cannot reload must be forced into the
2817 if (legitimate_reload_constant_p (op
))
2822 /* If a symbolic constant or a PLUS is reloaded,
2823 it is most likely being used as an address, so
2824 prefer ADDR_REGS. If 'class' is not a superset
2825 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
2830 if (reg_class_subset_p (ADDR_REGS
, rclass
))
2842 /* Return true if ADDR is SYMBOL_REF + addend with addend being a
2843 multiple of ALIGNMENT and the SYMBOL_REF being naturally
2847 s390_check_symref_alignment (rtx addr
, HOST_WIDE_INT alignment
)
2849 HOST_WIDE_INT addend
;
2852 if (!s390_symref_operand_p (addr
, &symref
, &addend
))
2855 return (!SYMBOL_REF_NOT_NATURALLY_ALIGNED_P (symref
)
2856 && !(addend
& (alignment
- 1)));
2859 /* ADDR is moved into REG using larl. If ADDR isn't a valid larl
2860 operand SCRATCH is used to reload the even part of the address and
2864 s390_reload_larl_operand (rtx reg
, rtx addr
, rtx scratch
)
2866 HOST_WIDE_INT addend
;
2869 if (!s390_symref_operand_p (addr
, &symref
, &addend
))
2873 /* Easy case. The addend is even so larl will do fine. */
2874 emit_move_insn (reg
, addr
);
2877 /* We can leave the scratch register untouched if the target
2878 register is a valid base register. */
2879 if (REGNO (reg
) < FIRST_PSEUDO_REGISTER
2880 && REGNO_REG_CLASS (REGNO (reg
)) == ADDR_REGS
)
2883 gcc_assert (REGNO (scratch
) < FIRST_PSEUDO_REGISTER
);
2884 gcc_assert (REGNO_REG_CLASS (REGNO (scratch
)) == ADDR_REGS
);
2887 emit_move_insn (scratch
,
2888 gen_rtx_CONST (Pmode
,
2889 gen_rtx_PLUS (Pmode
, symref
,
2890 GEN_INT (addend
- 1))));
2892 emit_move_insn (scratch
, symref
);
2894 /* Increment the address using la in order to avoid clobbering cc. */
2895 emit_move_insn (reg
, gen_rtx_PLUS (Pmode
, scratch
, const1_rtx
));
2899 /* Generate what is necessary to move between REG and MEM using
2900 SCRATCH. The direction is given by TOMEM. */
2903 s390_reload_symref_address (rtx reg
, rtx mem
, rtx scratch
, bool tomem
)
2905 /* Reload might have pulled a constant out of the literal pool.
2906 Force it back in. */
2907 if (CONST_INT_P (mem
) || GET_CODE (mem
) == CONST_DOUBLE
2908 || GET_CODE (mem
) == CONST
)
2909 mem
= force_const_mem (GET_MODE (reg
), mem
);
2911 gcc_assert (MEM_P (mem
));
2913 /* For a load from memory we can leave the scratch register
2914 untouched if the target register is a valid base register. */
2916 && REGNO (reg
) < FIRST_PSEUDO_REGISTER
2917 && REGNO_REG_CLASS (REGNO (reg
)) == ADDR_REGS
2918 && GET_MODE (reg
) == GET_MODE (scratch
))
2921 /* Load address into scratch register. Since we can't have a
2922 secondary reload for a secondary reload we have to cover the case
2923 where larl would need a secondary reload here as well. */
2924 s390_reload_larl_operand (scratch
, XEXP (mem
, 0), scratch
);
2926 /* Now we can use a standard load/store to do the move. */
2928 emit_move_insn (replace_equiv_address (mem
, scratch
), reg
);
2930 emit_move_insn (reg
, replace_equiv_address (mem
, scratch
));
2933 /* Inform reload about cases where moving X with a mode MODE to a register in
2934 RCLASS requires an extra scratch or immediate register. Return the class
2935 needed for the immediate register. */
2937 static enum reg_class
2938 s390_secondary_reload (bool in_p
, rtx x
, enum reg_class rclass
,
2939 enum machine_mode mode
, secondary_reload_info
*sri
)
2941 /* Intermediate register needed. */
2942 if (reg_classes_intersect_p (CC_REGS
, rclass
))
2943 return GENERAL_REGS
;
2947 /* On z10 several optimizer steps may generate larl operands with
2950 && s390_symref_operand_p (x
, NULL
, NULL
)
2952 && !s390_check_symref_alignment (x
, 2))
2953 sri
->icode
= ((mode
== DImode
) ? CODE_FOR_reloaddi_larl_odd_addend_z10
2954 : CODE_FOR_reloadsi_larl_odd_addend_z10
);
2956 /* On z10 we need a scratch register when moving QI, TI or floating
2957 point mode values from or to a memory location with a SYMBOL_REF
2958 or if the symref addend of a SI or DI move is not aligned to the
2959 width of the access. */
2961 && s390_symref_operand_p (XEXP (x
, 0), NULL
, NULL
)
2962 && (mode
== QImode
|| mode
== TImode
|| FLOAT_MODE_P (mode
)
2963 || (!TARGET_64BIT
&& mode
== DImode
)
2964 || ((mode
== HImode
|| mode
== SImode
|| mode
== DImode
)
2965 && (!s390_check_symref_alignment (XEXP (x
, 0),
2966 GET_MODE_SIZE (mode
))))))
2968 #define __SECONDARY_RELOAD_CASE(M,m) \
2971 sri->icode = in_p ? CODE_FOR_reload##m##di_toreg_z10 : \
2972 CODE_FOR_reload##m##di_tomem_z10; \
2974 sri->icode = in_p ? CODE_FOR_reload##m##si_toreg_z10 : \
2975 CODE_FOR_reload##m##si_tomem_z10; \
2978 switch (GET_MODE (x
))
2980 __SECONDARY_RELOAD_CASE (QI
, qi
);
2981 __SECONDARY_RELOAD_CASE (HI
, hi
);
2982 __SECONDARY_RELOAD_CASE (SI
, si
);
2983 __SECONDARY_RELOAD_CASE (DI
, di
);
2984 __SECONDARY_RELOAD_CASE (TI
, ti
);
2985 __SECONDARY_RELOAD_CASE (SF
, sf
);
2986 __SECONDARY_RELOAD_CASE (DF
, df
);
2987 __SECONDARY_RELOAD_CASE (TF
, tf
);
2988 __SECONDARY_RELOAD_CASE (SD
, sd
);
2989 __SECONDARY_RELOAD_CASE (DD
, dd
);
2990 __SECONDARY_RELOAD_CASE (TD
, td
);
2995 #undef __SECONDARY_RELOAD_CASE
2999 /* We need a scratch register when loading a PLUS expression which
3000 is not a legitimate operand of the LOAD ADDRESS instruction. */
3001 if (in_p
&& s390_plus_operand (x
, mode
))
3002 sri
->icode
= (TARGET_64BIT
?
3003 CODE_FOR_reloaddi_plus
: CODE_FOR_reloadsi_plus
);
3005 /* Performing a multiword move from or to memory we have to make sure the
3006 second chunk in memory is addressable without causing a displacement
3007 overflow. If that would be the case we calculate the address in
3008 a scratch register. */
3010 && GET_CODE (XEXP (x
, 0)) == PLUS
3011 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
3012 && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (x
, 0), 1))
3013 + GET_MODE_SIZE (mode
) - 1))
3015 /* For GENERAL_REGS a displacement overflow is no problem if occurring
3016 in a s_operand address since we may fallback to lm/stm. So we only
3017 have to care about overflows in the b+i+d case. */
3018 if ((reg_classes_intersect_p (GENERAL_REGS
, rclass
)
3019 && s390_class_max_nregs (GENERAL_REGS
, mode
) > 1
3020 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == PLUS
)
3021 /* For FP_REGS no lm/stm is available so this check is triggered
3022 for displacement overflows in b+i+d and b+d like addresses. */
3023 || (reg_classes_intersect_p (FP_REGS
, rclass
)
3024 && s390_class_max_nregs (FP_REGS
, mode
) > 1))
3027 sri
->icode
= (TARGET_64BIT
?
3028 CODE_FOR_reloaddi_nonoffmem_in
:
3029 CODE_FOR_reloadsi_nonoffmem_in
);
3031 sri
->icode
= (TARGET_64BIT
?
3032 CODE_FOR_reloaddi_nonoffmem_out
:
3033 CODE_FOR_reloadsi_nonoffmem_out
);
3037 /* A scratch address register is needed when a symbolic constant is
3038 copied to r0 compiling with -fPIC. In other cases the target
3039 register might be used as temporary (see legitimize_pic_address). */
3040 if (in_p
&& SYMBOLIC_CONST (x
) && flag_pic
== 2 && rclass
!= ADDR_REGS
)
3041 sri
->icode
= (TARGET_64BIT
?
3042 CODE_FOR_reloaddi_PIC_addr
:
3043 CODE_FOR_reloadsi_PIC_addr
);
3045 /* Either scratch or no register needed. */
3049 /* Generate code to load SRC, which is PLUS that is not a
3050 legitimate operand for the LA instruction, into TARGET.
3051 SCRATCH may be used as scratch register. */
3054 s390_expand_plus_operand (rtx target
, rtx src
,
3058 struct s390_address ad
;
3060 /* src must be a PLUS; get its two operands. */
3061 gcc_assert (GET_CODE (src
) == PLUS
);
3062 gcc_assert (GET_MODE (src
) == Pmode
);
3064 /* Check if any of the two operands is already scheduled
3065 for replacement by reload. This can happen e.g. when
3066 float registers occur in an address. */
3067 sum1
= find_replacement (&XEXP (src
, 0));
3068 sum2
= find_replacement (&XEXP (src
, 1));
3069 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
3071 /* If the address is already strictly valid, there's nothing to do. */
3072 if (!s390_decompose_address (src
, &ad
)
3073 || (ad
.base
&& !REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)))
3074 || (ad
.indx
&& !REGNO_OK_FOR_INDEX_P (REGNO (ad
.indx
))))
3076 /* Otherwise, one of the operands cannot be an address register;
3077 we reload its value into the scratch register. */
3078 if (true_regnum (sum1
) < 1 || true_regnum (sum1
) > 15)
3080 emit_move_insn (scratch
, sum1
);
3083 if (true_regnum (sum2
) < 1 || true_regnum (sum2
) > 15)
3085 emit_move_insn (scratch
, sum2
);
3089 /* According to the way these invalid addresses are generated
3090 in reload.c, it should never happen (at least on s390) that
3091 *neither* of the PLUS components, after find_replacements
3092 was applied, is an address register. */
3093 if (sum1
== scratch
&& sum2
== scratch
)
3099 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
3102 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
3103 is only ever performed on addresses, so we can mark the
3104 sum as legitimate for LA in any case. */
3105 s390_load_address (target
, src
);
3109 /* Return true if ADDR is a valid memory address.
3110 STRICT specifies whether strict register checking applies. */
3113 s390_legitimate_address_p (enum machine_mode mode
, rtx addr
, bool strict
)
3115 struct s390_address ad
;
3118 && larl_operand (addr
, VOIDmode
)
3119 && (mode
== VOIDmode
3120 || s390_check_symref_alignment (addr
, GET_MODE_SIZE (mode
))))
3123 if (!s390_decompose_address (addr
, &ad
))
3128 if (ad
.base
&& !REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)))
3131 if (ad
.indx
&& !REGNO_OK_FOR_INDEX_P (REGNO (ad
.indx
)))
3137 && !(REGNO (ad
.base
) >= FIRST_PSEUDO_REGISTER
3138 || REGNO_REG_CLASS (REGNO (ad
.base
)) == ADDR_REGS
))
3142 && !(REGNO (ad
.indx
) >= FIRST_PSEUDO_REGISTER
3143 || REGNO_REG_CLASS (REGNO (ad
.indx
)) == ADDR_REGS
))
3149 /* Return true if OP is a valid operand for the LA instruction.
3150 In 31-bit, we need to prove that the result is used as an
3151 address, as LA performs only a 31-bit addition. */
3154 legitimate_la_operand_p (rtx op
)
3156 struct s390_address addr
;
3157 if (!s390_decompose_address (op
, &addr
))
3160 return (TARGET_64BIT
|| addr
.pointer
);
3163 /* Return true if it is valid *and* preferable to use LA to
3164 compute the sum of OP1 and OP2. */
3167 preferred_la_operand_p (rtx op1
, rtx op2
)
3169 struct s390_address addr
;
3171 if (op2
!= const0_rtx
)
3172 op1
= gen_rtx_PLUS (Pmode
, op1
, op2
);
3174 if (!s390_decompose_address (op1
, &addr
))
3176 if (addr
.base
&& !REGNO_OK_FOR_BASE_P (REGNO (addr
.base
)))
3178 if (addr
.indx
&& !REGNO_OK_FOR_INDEX_P (REGNO (addr
.indx
)))
3181 if (!TARGET_64BIT
&& !addr
.pointer
)
3187 if ((addr
.base
&& REG_P (addr
.base
) && REG_POINTER (addr
.base
))
3188 || (addr
.indx
&& REG_P (addr
.indx
) && REG_POINTER (addr
.indx
)))
3194 /* Emit a forced load-address operation to load SRC into DST.
3195 This will use the LOAD ADDRESS instruction even in situations
3196 where legitimate_la_operand_p (SRC) returns false. */
3199 s390_load_address (rtx dst
, rtx src
)
3202 emit_move_insn (dst
, src
);
3204 emit_insn (gen_force_la_31 (dst
, src
));
3207 /* Return a legitimate reference for ORIG (an address) using the
3208 register REG. If REG is 0, a new pseudo is generated.
3210 There are two types of references that must be handled:
3212 1. Global data references must load the address from the GOT, via
3213 the PIC reg. An insn is emitted to do this load, and the reg is
3216 2. Static data references, constant pool addresses, and code labels
3217 compute the address as an offset from the GOT, whose base is in
3218 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
3219 differentiate them from global data objects. The returned
3220 address is the PIC reg + an unspec constant.
3222 TARGET_LEGITIMIZE_ADDRESS_P rejects symbolic references unless the PIC
3223 reg also appears in the address. */
3226 legitimize_pic_address (rtx orig
, rtx reg
)
3232 gcc_assert (!TLS_SYMBOLIC_CONST (addr
));
3234 if (GET_CODE (addr
) == LABEL_REF
3235 || (GET_CODE (addr
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (addr
)))
3237 /* This is a local symbol. */
3238 if (TARGET_CPU_ZARCH
&& larl_operand (addr
, VOIDmode
))
3240 /* Access local symbols PC-relative via LARL.
3241 This is the same as in the non-PIC case, so it is
3242 handled automatically ... */
3246 /* Access local symbols relative to the GOT. */
3248 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
3250 if (reload_in_progress
|| reload_completed
)
3251 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM
, true);
3253 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTOFF
);
3254 addr
= gen_rtx_CONST (Pmode
, addr
);
3255 addr
= force_const_mem (Pmode
, addr
);
3256 emit_move_insn (temp
, addr
);
3258 new_rtx
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
3261 s390_load_address (reg
, new_rtx
);
3266 else if (GET_CODE (addr
) == SYMBOL_REF
)
3269 reg
= gen_reg_rtx (Pmode
);
3273 /* Assume GOT offset < 4k. This is handled the same way
3274 in both 31- and 64-bit code (@GOT). */
3276 if (reload_in_progress
|| reload_completed
)
3277 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM
, true);
3279 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
3280 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
3281 new_rtx
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new_rtx
);
3282 new_rtx
= gen_const_mem (Pmode
, new_rtx
);
3283 emit_move_insn (reg
, new_rtx
);
3286 else if (TARGET_CPU_ZARCH
)
3288 /* If the GOT offset might be >= 4k, we determine the position
3289 of the GOT entry via a PC-relative LARL (@GOTENT). */
3291 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
3293 gcc_assert (REGNO (temp
) >= FIRST_PSEUDO_REGISTER
3294 || REGNO_REG_CLASS (REGNO (temp
)) == ADDR_REGS
);
3296 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTENT
);
3297 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
3298 emit_move_insn (temp
, new_rtx
);
3300 new_rtx
= gen_const_mem (Pmode
, temp
);
3301 emit_move_insn (reg
, new_rtx
);
3306 /* If the GOT offset might be >= 4k, we have to load it
3307 from the literal pool (@GOT). */
3309 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
3311 gcc_assert (REGNO (temp
) >= FIRST_PSEUDO_REGISTER
3312 || REGNO_REG_CLASS (REGNO (temp
)) == ADDR_REGS
);
3314 if (reload_in_progress
|| reload_completed
)
3315 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM
, true);
3317 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
3318 addr
= gen_rtx_CONST (Pmode
, addr
);
3319 addr
= force_const_mem (Pmode
, addr
);
3320 emit_move_insn (temp
, addr
);
3322 new_rtx
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
3323 new_rtx
= gen_const_mem (Pmode
, new_rtx
);
3324 emit_move_insn (reg
, new_rtx
);
3330 if (GET_CODE (addr
) == CONST
)
3332 addr
= XEXP (addr
, 0);
3333 if (GET_CODE (addr
) == UNSPEC
)
3335 gcc_assert (XVECLEN (addr
, 0) == 1);
3336 switch (XINT (addr
, 1))
3338 /* If someone moved a GOT-relative UNSPEC
3339 out of the literal pool, force them back in. */
3342 new_rtx
= force_const_mem (Pmode
, orig
);
3345 /* @GOT is OK as is if small. */
3348 new_rtx
= force_const_mem (Pmode
, orig
);
3351 /* @GOTENT is OK as is. */
3355 /* @PLT is OK as is on 64-bit, must be converted to
3356 GOT-relative @PLTOFF on 31-bit. */
3358 if (!TARGET_CPU_ZARCH
)
3360 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
3362 if (reload_in_progress
|| reload_completed
)
3363 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM
, true);
3365 addr
= XVECEXP (addr
, 0, 0);
3366 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
),
3368 addr
= gen_rtx_CONST (Pmode
, addr
);
3369 addr
= force_const_mem (Pmode
, addr
);
3370 emit_move_insn (temp
, addr
);
3372 new_rtx
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
3375 s390_load_address (reg
, new_rtx
);
3381 /* Everything else cannot happen. */
3387 gcc_assert (GET_CODE (addr
) == PLUS
);
3389 if (GET_CODE (addr
) == PLUS
)
3391 rtx op0
= XEXP (addr
, 0), op1
= XEXP (addr
, 1);
3393 gcc_assert (!TLS_SYMBOLIC_CONST (op0
));
3394 gcc_assert (!TLS_SYMBOLIC_CONST (op1
));
3396 /* Check first to see if this is a constant offset
3397 from a local symbol reference. */
3398 if ((GET_CODE (op0
) == LABEL_REF
3399 || (GET_CODE (op0
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (op0
)))
3400 && GET_CODE (op1
) == CONST_INT
)
3402 if (TARGET_CPU_ZARCH
3403 && larl_operand (op0
, VOIDmode
)
3404 && INTVAL (op1
) < (HOST_WIDE_INT
)1 << 31
3405 && INTVAL (op1
) >= -((HOST_WIDE_INT
)1 << 31))
3407 if (INTVAL (op1
) & 1)
3409 /* LARL can't handle odd offsets, so emit a
3410 pair of LARL and LA. */
3411 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
3413 if (!DISP_IN_RANGE (INTVAL (op1
)))
3415 HOST_WIDE_INT even
= INTVAL (op1
) - 1;
3416 op0
= gen_rtx_PLUS (Pmode
, op0
, GEN_INT (even
));
3417 op0
= gen_rtx_CONST (Pmode
, op0
);
3421 emit_move_insn (temp
, op0
);
3422 new_rtx
= gen_rtx_PLUS (Pmode
, temp
, op1
);
3426 s390_load_address (reg
, new_rtx
);
3432 /* If the offset is even, we can just use LARL.
3433 This will happen automatically. */
3438 /* Access local symbols relative to the GOT. */
3440 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
3442 if (reload_in_progress
|| reload_completed
)
3443 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM
, true);
3445 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op0
),
3447 addr
= gen_rtx_PLUS (Pmode
, addr
, op1
);
3448 addr
= gen_rtx_CONST (Pmode
, addr
);
3449 addr
= force_const_mem (Pmode
, addr
);
3450 emit_move_insn (temp
, addr
);
3452 new_rtx
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
3455 s390_load_address (reg
, new_rtx
);
3461 /* Now, check whether it is a GOT relative symbol plus offset
3462 that was pulled out of the literal pool. Force it back in. */
3464 else if (GET_CODE (op0
) == UNSPEC
3465 && GET_CODE (op1
) == CONST_INT
3466 && XINT (op0
, 1) == UNSPEC_GOTOFF
)
3468 gcc_assert (XVECLEN (op0
, 0) == 1);
3470 new_rtx
= force_const_mem (Pmode
, orig
);
3473 /* Otherwise, compute the sum. */
3476 base
= legitimize_pic_address (XEXP (addr
, 0), reg
);
3477 new_rtx
= legitimize_pic_address (XEXP (addr
, 1),
3478 base
== reg
? NULL_RTX
: reg
);
3479 if (GET_CODE (new_rtx
) == CONST_INT
)
3480 new_rtx
= plus_constant (base
, INTVAL (new_rtx
));
3483 if (GET_CODE (new_rtx
) == PLUS
&& CONSTANT_P (XEXP (new_rtx
, 1)))
3485 base
= gen_rtx_PLUS (Pmode
, base
, XEXP (new_rtx
, 0));
3486 new_rtx
= XEXP (new_rtx
, 1);
3488 new_rtx
= gen_rtx_PLUS (Pmode
, base
, new_rtx
);
3491 if (GET_CODE (new_rtx
) == CONST
)
3492 new_rtx
= XEXP (new_rtx
, 0);
3493 new_rtx
= force_operand (new_rtx
, 0);
3500 /* Load the thread pointer into a register. */
3503 s390_get_thread_pointer (void)
3505 rtx tp
= gen_reg_rtx (Pmode
);
3507 emit_move_insn (tp
, gen_rtx_REG (Pmode
, TP_REGNUM
));
3508 mark_reg_pointer (tp
, BITS_PER_WORD
);
3513 /* Emit a tls call insn. The call target is the SYMBOL_REF stored
3514 in s390_tls_symbol which always refers to __tls_get_offset.
3515 The returned offset is written to RESULT_REG and an USE rtx is
3516 generated for TLS_CALL. */
3518 static GTY(()) rtx s390_tls_symbol
;
3521 s390_emit_tls_call_insn (rtx result_reg
, rtx tls_call
)
3525 gcc_assert (flag_pic
);
3527 if (!s390_tls_symbol
)
3528 s390_tls_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "__tls_get_offset");
3530 insn
= s390_emit_call (s390_tls_symbol
, tls_call
, result_reg
,
3531 gen_rtx_REG (Pmode
, RETURN_REGNUM
));
3533 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), result_reg
);
3534 RTL_CONST_CALL_P (insn
) = 1;
3537 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
3538 this (thread-local) address. REG may be used as temporary. */
3541 legitimize_tls_address (rtx addr
, rtx reg
)
3543 rtx new_rtx
, tls_call
, temp
, base
, r2
, insn
;
3545 if (GET_CODE (addr
) == SYMBOL_REF
)
3546 switch (tls_symbolic_operand (addr
))
3548 case TLS_MODEL_GLOBAL_DYNAMIC
:
3550 r2
= gen_rtx_REG (Pmode
, 2);
3551 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_TLSGD
);
3552 new_rtx
= gen_rtx_CONST (Pmode
, tls_call
);
3553 new_rtx
= force_const_mem (Pmode
, new_rtx
);
3554 emit_move_insn (r2
, new_rtx
);
3555 s390_emit_tls_call_insn (r2
, tls_call
);
3556 insn
= get_insns ();
3559 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
3560 temp
= gen_reg_rtx (Pmode
);
3561 emit_libcall_block (insn
, temp
, r2
, new_rtx
);
3563 new_rtx
= gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
3566 s390_load_address (reg
, new_rtx
);
3571 case TLS_MODEL_LOCAL_DYNAMIC
:
3573 r2
= gen_rtx_REG (Pmode
, 2);
3574 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM
);
3575 new_rtx
= gen_rtx_CONST (Pmode
, tls_call
);
3576 new_rtx
= force_const_mem (Pmode
, new_rtx
);
3577 emit_move_insn (r2
, new_rtx
);
3578 s390_emit_tls_call_insn (r2
, tls_call
);
3579 insn
= get_insns ();
3582 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM_NTPOFF
);
3583 temp
= gen_reg_rtx (Pmode
);
3584 emit_libcall_block (insn
, temp
, r2
, new_rtx
);
3586 new_rtx
= gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
3587 base
= gen_reg_rtx (Pmode
);
3588 s390_load_address (base
, new_rtx
);
3590 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_DTPOFF
);
3591 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
3592 new_rtx
= force_const_mem (Pmode
, new_rtx
);
3593 temp
= gen_reg_rtx (Pmode
);
3594 emit_move_insn (temp
, new_rtx
);
3596 new_rtx
= gen_rtx_PLUS (Pmode
, base
, temp
);
3599 s390_load_address (reg
, new_rtx
);
3604 case TLS_MODEL_INITIAL_EXEC
:
3607 /* Assume GOT offset < 4k. This is handled the same way
3608 in both 31- and 64-bit code. */
3610 if (reload_in_progress
|| reload_completed
)
3611 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM
, true);
3613 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
3614 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
3615 new_rtx
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new_rtx
);
3616 new_rtx
= gen_const_mem (Pmode
, new_rtx
);
3617 temp
= gen_reg_rtx (Pmode
);
3618 emit_move_insn (temp
, new_rtx
);
3620 else if (TARGET_CPU_ZARCH
)
3622 /* If the GOT offset might be >= 4k, we determine the position
3623 of the GOT entry via a PC-relative LARL. */
3625 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
3626 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
3627 temp
= gen_reg_rtx (Pmode
);
3628 emit_move_insn (temp
, new_rtx
);
3630 new_rtx
= gen_const_mem (Pmode
, temp
);
3631 temp
= gen_reg_rtx (Pmode
);
3632 emit_move_insn (temp
, new_rtx
);
3636 /* If the GOT offset might be >= 4k, we have to load it
3637 from the literal pool. */
3639 if (reload_in_progress
|| reload_completed
)
3640 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM
, true);
3642 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
3643 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
3644 new_rtx
= force_const_mem (Pmode
, new_rtx
);
3645 temp
= gen_reg_rtx (Pmode
);
3646 emit_move_insn (temp
, new_rtx
);
3648 new_rtx
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
3649 new_rtx
= gen_const_mem (Pmode
, new_rtx
);
3651 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new_rtx
, addr
), UNSPEC_TLS_LOAD
);
3652 temp
= gen_reg_rtx (Pmode
);
3653 emit_insn (gen_rtx_SET (Pmode
, temp
, new_rtx
));
3657 /* In position-dependent code, load the absolute address of
3658 the GOT entry from the literal pool. */
3660 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
3661 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
3662 new_rtx
= force_const_mem (Pmode
, new_rtx
);
3663 temp
= gen_reg_rtx (Pmode
);
3664 emit_move_insn (temp
, new_rtx
);
3667 new_rtx
= gen_const_mem (Pmode
, new_rtx
);
3668 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new_rtx
, addr
), UNSPEC_TLS_LOAD
);
3669 temp
= gen_reg_rtx (Pmode
);
3670 emit_insn (gen_rtx_SET (Pmode
, temp
, new_rtx
));
3673 new_rtx
= gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
3676 s390_load_address (reg
, new_rtx
);
3681 case TLS_MODEL_LOCAL_EXEC
:
3682 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
3683 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
3684 new_rtx
= force_const_mem (Pmode
, new_rtx
);
3685 temp
= gen_reg_rtx (Pmode
);
3686 emit_move_insn (temp
, new_rtx
);
3688 new_rtx
= gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
3691 s390_load_address (reg
, new_rtx
);
3700 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == UNSPEC
)
3702 switch (XINT (XEXP (addr
, 0), 1))
3704 case UNSPEC_INDNTPOFF
:
3705 gcc_assert (TARGET_CPU_ZARCH
);
3714 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == PLUS
3715 && GET_CODE (XEXP (XEXP (addr
, 0), 1)) == CONST_INT
)
3717 new_rtx
= XEXP (XEXP (addr
, 0), 0);
3718 if (GET_CODE (new_rtx
) != SYMBOL_REF
)
3719 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
3721 new_rtx
= legitimize_tls_address (new_rtx
, reg
);
3722 new_rtx
= plus_constant (new_rtx
, INTVAL (XEXP (XEXP (addr
, 0), 1)));
3723 new_rtx
= force_operand (new_rtx
, 0);
3727 gcc_unreachable (); /* for now ... */
3732 /* Emit insns making the address in operands[1] valid for a standard
3733 move to operands[0]. operands[1] is replaced by an address which
3734 should be used instead of the former RTX to emit the move
3738 emit_symbolic_move (rtx
*operands
)
3740 rtx temp
= !can_create_pseudo_p () ? operands
[0] : gen_reg_rtx (Pmode
);
3742 if (GET_CODE (operands
[0]) == MEM
)
3743 operands
[1] = force_reg (Pmode
, operands
[1]);
3744 else if (TLS_SYMBOLIC_CONST (operands
[1]))
3745 operands
[1] = legitimize_tls_address (operands
[1], temp
);
3747 operands
[1] = legitimize_pic_address (operands
[1], temp
);
3750 /* Try machine-dependent ways of modifying an illegitimate address X
3751 to be legitimate. If we find one, return the new, valid address.
3753 OLDX is the address as it was before break_out_memory_refs was called.
3754 In some cases it is useful to look at this to decide what needs to be done.
3756 MODE is the mode of the operand pointed to by X.
3758 When -fpic is used, special handling is needed for symbolic references.
3759 See comments by legitimize_pic_address for details. */
3762 s390_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
3763 enum machine_mode mode ATTRIBUTE_UNUSED
)
3765 rtx constant_term
= const0_rtx
;
3767 if (TLS_SYMBOLIC_CONST (x
))
3769 x
= legitimize_tls_address (x
, 0);
3771 if (s390_legitimate_address_p (mode
, x
, FALSE
))
3774 else if (GET_CODE (x
) == PLUS
3775 && (TLS_SYMBOLIC_CONST (XEXP (x
, 0))
3776 || TLS_SYMBOLIC_CONST (XEXP (x
, 1))))
3782 if (SYMBOLIC_CONST (x
)
3783 || (GET_CODE (x
) == PLUS
3784 && (SYMBOLIC_CONST (XEXP (x
, 0))
3785 || SYMBOLIC_CONST (XEXP (x
, 1)))))
3786 x
= legitimize_pic_address (x
, 0);
3788 if (s390_legitimate_address_p (mode
, x
, FALSE
))
3792 x
= eliminate_constant_term (x
, &constant_term
);
3794 /* Optimize loading of large displacements by splitting them
3795 into the multiple of 4K and the rest; this allows the
3796 former to be CSE'd if possible.
3798 Don't do this if the displacement is added to a register
3799 pointing into the stack frame, as the offsets will
3800 change later anyway. */
3802 if (GET_CODE (constant_term
) == CONST_INT
3803 && !TARGET_LONG_DISPLACEMENT
3804 && !DISP_IN_RANGE (INTVAL (constant_term
))
3805 && !(REG_P (x
) && REGNO_PTR_FRAME_P (REGNO (x
))))
3807 HOST_WIDE_INT lower
= INTVAL (constant_term
) & 0xfff;
3808 HOST_WIDE_INT upper
= INTVAL (constant_term
) ^ lower
;
3810 rtx temp
= gen_reg_rtx (Pmode
);
3811 rtx val
= force_operand (GEN_INT (upper
), temp
);
3813 emit_move_insn (temp
, val
);
3815 x
= gen_rtx_PLUS (Pmode
, x
, temp
);
3816 constant_term
= GEN_INT (lower
);
3819 if (GET_CODE (x
) == PLUS
)
3821 if (GET_CODE (XEXP (x
, 0)) == REG
)
3823 rtx temp
= gen_reg_rtx (Pmode
);
3824 rtx val
= force_operand (XEXP (x
, 1), temp
);
3826 emit_move_insn (temp
, val
);
3828 x
= gen_rtx_PLUS (Pmode
, XEXP (x
, 0), temp
);
3831 else if (GET_CODE (XEXP (x
, 1)) == REG
)
3833 rtx temp
= gen_reg_rtx (Pmode
);
3834 rtx val
= force_operand (XEXP (x
, 0), temp
);
3836 emit_move_insn (temp
, val
);
3838 x
= gen_rtx_PLUS (Pmode
, temp
, XEXP (x
, 1));
3842 if (constant_term
!= const0_rtx
)
3843 x
= gen_rtx_PLUS (Pmode
, x
, constant_term
);
3848 /* Try a machine-dependent way of reloading an illegitimate address AD
3849 operand. If we find one, push the reload and and return the new address.
3851 MODE is the mode of the enclosing MEM. OPNUM is the operand number
3852 and TYPE is the reload type of the current reload. */
3855 legitimize_reload_address (rtx ad
, enum machine_mode mode ATTRIBUTE_UNUSED
,
3856 int opnum
, int type
)
3858 if (!optimize
|| TARGET_LONG_DISPLACEMENT
)
3861 if (GET_CODE (ad
) == PLUS
)
3863 rtx tem
= simplify_binary_operation (PLUS
, Pmode
,
3864 XEXP (ad
, 0), XEXP (ad
, 1));
3869 if (GET_CODE (ad
) == PLUS
3870 && GET_CODE (XEXP (ad
, 0)) == REG
3871 && GET_CODE (XEXP (ad
, 1)) == CONST_INT
3872 && !DISP_IN_RANGE (INTVAL (XEXP (ad
, 1))))
3874 HOST_WIDE_INT lower
= INTVAL (XEXP (ad
, 1)) & 0xfff;
3875 HOST_WIDE_INT upper
= INTVAL (XEXP (ad
, 1)) ^ lower
;
3876 rtx cst
, tem
, new_rtx
;
3878 cst
= GEN_INT (upper
);
3879 if (!legitimate_reload_constant_p (cst
))
3880 cst
= force_const_mem (Pmode
, cst
);
3882 tem
= gen_rtx_PLUS (Pmode
, XEXP (ad
, 0), cst
);
3883 new_rtx
= gen_rtx_PLUS (Pmode
, tem
, GEN_INT (lower
));
3885 push_reload (XEXP (tem
, 1), 0, &XEXP (tem
, 1), 0,
3886 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
3887 opnum
, (enum reload_type
) type
);
3894 /* Emit code to move LEN bytes from DST to SRC. */
3897 s390_expand_movmem (rtx dst
, rtx src
, rtx len
)
3899 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3901 if (INTVAL (len
) > 0)
3902 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (INTVAL (len
) - 1)));
3905 else if (TARGET_MVCLE
)
3907 emit_insn (gen_movmem_long (dst
, src
, convert_to_mode (Pmode
, len
, 1)));
3912 rtx dst_addr
, src_addr
, count
, blocks
, temp
;
3913 rtx loop_start_label
= gen_label_rtx ();
3914 rtx loop_end_label
= gen_label_rtx ();
3915 rtx end_label
= gen_label_rtx ();
3916 enum machine_mode mode
;
3918 mode
= GET_MODE (len
);
3919 if (mode
== VOIDmode
)
3922 dst_addr
= gen_reg_rtx (Pmode
);
3923 src_addr
= gen_reg_rtx (Pmode
);
3924 count
= gen_reg_rtx (mode
);
3925 blocks
= gen_reg_rtx (mode
);
3927 convert_move (count
, len
, 1);
3928 emit_cmp_and_jump_insns (count
, const0_rtx
,
3929 EQ
, NULL_RTX
, mode
, 1, end_label
);
3931 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
3932 emit_move_insn (src_addr
, force_operand (XEXP (src
, 0), NULL_RTX
));
3933 dst
= change_address (dst
, VOIDmode
, dst_addr
);
3934 src
= change_address (src
, VOIDmode
, src_addr
);
3936 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1,
3939 emit_move_insn (count
, temp
);
3941 temp
= expand_binop (mode
, lshr_optab
, count
, GEN_INT (8), blocks
, 1,
3944 emit_move_insn (blocks
, temp
);
3946 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3947 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3949 emit_label (loop_start_label
);
3952 && (GET_CODE (len
) != CONST_INT
|| INTVAL (len
) > 768))
3956 /* Issue a read prefetch for the +3 cache line. */
3957 prefetch
= gen_prefetch (gen_rtx_PLUS (Pmode
, src_addr
, GEN_INT (768)),
3958 const0_rtx
, const0_rtx
);
3959 PREFETCH_SCHEDULE_BARRIER_P (prefetch
) = true;
3960 emit_insn (prefetch
);
3962 /* Issue a write prefetch for the +3 cache line. */
3963 prefetch
= gen_prefetch (gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (768)),
3964 const1_rtx
, const0_rtx
);
3965 PREFETCH_SCHEDULE_BARRIER_P (prefetch
) = true;
3966 emit_insn (prefetch
);
3969 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (255)));
3970 s390_load_address (dst_addr
,
3971 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
3972 s390_load_address (src_addr
,
3973 gen_rtx_PLUS (Pmode
, src_addr
, GEN_INT (256)));
3975 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1,
3978 emit_move_insn (blocks
, temp
);
3980 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3981 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3983 emit_jump (loop_start_label
);
3984 emit_label (loop_end_label
);
3986 emit_insn (gen_movmem_short (dst
, src
,
3987 convert_to_mode (Pmode
, count
, 1)));
3988 emit_label (end_label
);
3992 /* Emit code to set LEN bytes at DST to VAL.
3993 Make use of clrmem if VAL is zero. */
3996 s390_expand_setmem (rtx dst
, rtx len
, rtx val
)
3998 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) == 0)
4001 gcc_assert (GET_CODE (val
) == CONST_INT
|| GET_MODE (val
) == QImode
);
4003 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) > 0 && INTVAL (len
) <= 257)
4005 if (val
== const0_rtx
&& INTVAL (len
) <= 256)
4006 emit_insn (gen_clrmem_short (dst
, GEN_INT (INTVAL (len
) - 1)));
4009 /* Initialize memory by storing the first byte. */
4010 emit_move_insn (adjust_address (dst
, QImode
, 0), val
);
4012 if (INTVAL (len
) > 1)
4014 /* Initiate 1 byte overlap move.
4015 The first byte of DST is propagated through DSTP1.
4016 Prepare a movmem for: DST+1 = DST (length = LEN - 1).
4017 DST is set to size 1 so the rest of the memory location
4018 does not count as source operand. */
4019 rtx dstp1
= adjust_address (dst
, VOIDmode
, 1);
4020 set_mem_size (dst
, const1_rtx
);
4022 emit_insn (gen_movmem_short (dstp1
, dst
,
4023 GEN_INT (INTVAL (len
) - 2)));
4028 else if (TARGET_MVCLE
)
4030 val
= force_not_mem (convert_modes (Pmode
, QImode
, val
, 1));
4031 emit_insn (gen_setmem_long (dst
, convert_to_mode (Pmode
, len
, 1), val
));
4036 rtx dst_addr
, src_addr
, count
, blocks
, temp
, dstp1
= NULL_RTX
;
4037 rtx loop_start_label
= gen_label_rtx ();
4038 rtx loop_end_label
= gen_label_rtx ();
4039 rtx end_label
= gen_label_rtx ();
4040 enum machine_mode mode
;
4042 mode
= GET_MODE (len
);
4043 if (mode
== VOIDmode
)
4046 dst_addr
= gen_reg_rtx (Pmode
);
4047 src_addr
= gen_reg_rtx (Pmode
);
4048 count
= gen_reg_rtx (mode
);
4049 blocks
= gen_reg_rtx (mode
);
4051 convert_move (count
, len
, 1);
4052 emit_cmp_and_jump_insns (count
, const0_rtx
,
4053 EQ
, NULL_RTX
, mode
, 1, end_label
);
4055 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
4056 dst
= change_address (dst
, VOIDmode
, dst_addr
);
4058 if (val
== const0_rtx
)
4059 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1,
4063 dstp1
= adjust_address (dst
, VOIDmode
, 1);
4064 set_mem_size (dst
, const1_rtx
);
4066 /* Initialize memory by storing the first byte. */
4067 emit_move_insn (adjust_address (dst
, QImode
, 0), val
);
4069 /* If count is 1 we are done. */
4070 emit_cmp_and_jump_insns (count
, const1_rtx
,
4071 EQ
, NULL_RTX
, mode
, 1, end_label
);
4073 temp
= expand_binop (mode
, add_optab
, count
, GEN_INT (-2), count
, 1,
4077 emit_move_insn (count
, temp
);
4079 temp
= expand_binop (mode
, lshr_optab
, count
, GEN_INT (8), blocks
, 1,
4082 emit_move_insn (blocks
, temp
);
4084 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
4085 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
4087 emit_label (loop_start_label
);
4090 && (GET_CODE (len
) != CONST_INT
|| INTVAL (len
) > 1024))
4092 /* Issue a write prefetch for the +4 cache line. */
4093 rtx prefetch
= gen_prefetch (gen_rtx_PLUS (Pmode
, dst_addr
,
4095 const1_rtx
, const0_rtx
);
4096 emit_insn (prefetch
);
4097 PREFETCH_SCHEDULE_BARRIER_P (prefetch
) = true;
4100 if (val
== const0_rtx
)
4101 emit_insn (gen_clrmem_short (dst
, GEN_INT (255)));
4103 emit_insn (gen_movmem_short (dstp1
, dst
, GEN_INT (255)));
4104 s390_load_address (dst_addr
,
4105 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
4107 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1,
4110 emit_move_insn (blocks
, temp
);
4112 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
4113 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
4115 emit_jump (loop_start_label
);
4116 emit_label (loop_end_label
);
4118 if (val
== const0_rtx
)
4119 emit_insn (gen_clrmem_short (dst
, convert_to_mode (Pmode
, count
, 1)));
4121 emit_insn (gen_movmem_short (dstp1
, dst
, convert_to_mode (Pmode
, count
, 1)));
4122 emit_label (end_label
);
4126 /* Emit code to compare LEN bytes at OP0 with those at OP1,
4127 and return the result in TARGET. */
4130 s390_expand_cmpmem (rtx target
, rtx op0
, rtx op1
, rtx len
)
4132 rtx ccreg
= gen_rtx_REG (CCUmode
, CC_REGNUM
);
4135 /* As the result of CMPINT is inverted compared to what we need,
4136 we have to swap the operands. */
4137 tmp
= op0
; op0
= op1
; op1
= tmp
;
4139 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
4141 if (INTVAL (len
) > 0)
4143 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (INTVAL (len
) - 1)));
4144 emit_insn (gen_cmpint (target
, ccreg
));
4147 emit_move_insn (target
, const0_rtx
);
4149 else if (TARGET_MVCLE
)
4151 emit_insn (gen_cmpmem_long (op0
, op1
, convert_to_mode (Pmode
, len
, 1)));
4152 emit_insn (gen_cmpint (target
, ccreg
));
4156 rtx addr0
, addr1
, count
, blocks
, temp
;
4157 rtx loop_start_label
= gen_label_rtx ();
4158 rtx loop_end_label
= gen_label_rtx ();
4159 rtx end_label
= gen_label_rtx ();
4160 enum machine_mode mode
;
4162 mode
= GET_MODE (len
);
4163 if (mode
== VOIDmode
)
4166 addr0
= gen_reg_rtx (Pmode
);
4167 addr1
= gen_reg_rtx (Pmode
);
4168 count
= gen_reg_rtx (mode
);
4169 blocks
= gen_reg_rtx (mode
);
4171 convert_move (count
, len
, 1);
4172 emit_cmp_and_jump_insns (count
, const0_rtx
,
4173 EQ
, NULL_RTX
, mode
, 1, end_label
);
4175 emit_move_insn (addr0
, force_operand (XEXP (op0
, 0), NULL_RTX
));
4176 emit_move_insn (addr1
, force_operand (XEXP (op1
, 0), NULL_RTX
));
4177 op0
= change_address (op0
, VOIDmode
, addr0
);
4178 op1
= change_address (op1
, VOIDmode
, addr1
);
4180 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1,
4183 emit_move_insn (count
, temp
);
4185 temp
= expand_binop (mode
, lshr_optab
, count
, GEN_INT (8), blocks
, 1,
4188 emit_move_insn (blocks
, temp
);
4190 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
4191 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
4193 emit_label (loop_start_label
);
4196 && (GET_CODE (len
) != CONST_INT
|| INTVAL (len
) > 512))
4200 /* Issue a read prefetch for the +2 cache line of operand 1. */
4201 prefetch
= gen_prefetch (gen_rtx_PLUS (Pmode
, addr0
, GEN_INT (512)),
4202 const0_rtx
, const0_rtx
);
4203 emit_insn (prefetch
);
4204 PREFETCH_SCHEDULE_BARRIER_P (prefetch
) = true;
4206 /* Issue a read prefetch for the +2 cache line of operand 2. */
4207 prefetch
= gen_prefetch (gen_rtx_PLUS (Pmode
, addr1
, GEN_INT (512)),
4208 const0_rtx
, const0_rtx
);
4209 emit_insn (prefetch
);
4210 PREFETCH_SCHEDULE_BARRIER_P (prefetch
) = true;
4213 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (255)));
4214 temp
= gen_rtx_NE (VOIDmode
, ccreg
, const0_rtx
);
4215 temp
= gen_rtx_IF_THEN_ELSE (VOIDmode
, temp
,
4216 gen_rtx_LABEL_REF (VOIDmode
, end_label
), pc_rtx
);
4217 temp
= gen_rtx_SET (VOIDmode
, pc_rtx
, temp
);
4218 emit_jump_insn (temp
);
4220 s390_load_address (addr0
,
4221 gen_rtx_PLUS (Pmode
, addr0
, GEN_INT (256)));
4222 s390_load_address (addr1
,
4223 gen_rtx_PLUS (Pmode
, addr1
, GEN_INT (256)));
4225 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1,
4228 emit_move_insn (blocks
, temp
);
4230 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
4231 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
4233 emit_jump (loop_start_label
);
4234 emit_label (loop_end_label
);
4236 emit_insn (gen_cmpmem_short (op0
, op1
,
4237 convert_to_mode (Pmode
, count
, 1)));
4238 emit_label (end_label
);
4240 emit_insn (gen_cmpint (target
, ccreg
));
4245 /* Expand conditional increment or decrement using alc/slb instructions.
4246 Should generate code setting DST to either SRC or SRC + INCREMENT,
4247 depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
4248 Returns true if successful, false otherwise.
4250 That makes it possible to implement some if-constructs without jumps e.g.:
4251 (borrow = CC0 | CC1 and carry = CC2 | CC3)
4252 unsigned int a, b, c;
4253 if (a < b) c++; -> CCU b > a -> CC2; c += carry;
4254 if (a < b) c--; -> CCL3 a - b -> borrow; c -= borrow;
4255 if (a <= b) c++; -> CCL3 b - a -> borrow; c += carry;
4256 if (a <= b) c--; -> CCU a <= b -> borrow; c -= borrow;
4258 Checks for EQ and NE with a nonzero value need an additional xor e.g.:
4259 if (a == b) c++; -> CCL3 a ^= b; 0 - a -> borrow; c += carry;
4260 if (a == b) c--; -> CCU a ^= b; a <= 0 -> CC0 | CC1; c -= borrow;
4261 if (a != b) c++; -> CCU a ^= b; a > 0 -> CC2; c += carry;
4262 if (a != b) c--; -> CCL3 a ^= b; 0 - a -> borrow; c -= borrow; */
4265 s390_expand_addcc (enum rtx_code cmp_code
, rtx cmp_op0
, rtx cmp_op1
,
4266 rtx dst
, rtx src
, rtx increment
)
4268 enum machine_mode cmp_mode
;
4269 enum machine_mode cc_mode
;
4275 if ((GET_MODE (cmp_op0
) == SImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
4276 && (GET_MODE (cmp_op1
) == SImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
4278 else if ((GET_MODE (cmp_op0
) == DImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
4279 && (GET_MODE (cmp_op1
) == DImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
4284 /* Try ADD LOGICAL WITH CARRY. */
4285 if (increment
== const1_rtx
)
4287 /* Determine CC mode to use. */
4288 if (cmp_code
== EQ
|| cmp_code
== NE
)
4290 if (cmp_op1
!= const0_rtx
)
4292 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
4293 NULL_RTX
, 0, OPTAB_WIDEN
);
4294 cmp_op1
= const0_rtx
;
4297 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
4300 if (cmp_code
== LTU
|| cmp_code
== LEU
)
4305 cmp_code
= swap_condition (cmp_code
);
4322 /* Emit comparison instruction pattern. */
4323 if (!register_operand (cmp_op0
, cmp_mode
))
4324 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
4326 insn
= gen_rtx_SET (VOIDmode
, gen_rtx_REG (cc_mode
, CC_REGNUM
),
4327 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
4328 /* We use insn_invalid_p here to add clobbers if required. */
4329 ret
= insn_invalid_p (emit_insn (insn
));
4332 /* Emit ALC instruction pattern. */
4333 op_res
= gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
4334 gen_rtx_REG (cc_mode
, CC_REGNUM
),
4337 if (src
!= const0_rtx
)
4339 if (!register_operand (src
, GET_MODE (dst
)))
4340 src
= force_reg (GET_MODE (dst
), src
);
4342 op_res
= gen_rtx_PLUS (GET_MODE (dst
), op_res
, src
);
4343 op_res
= gen_rtx_PLUS (GET_MODE (dst
), op_res
, const0_rtx
);
4346 p
= rtvec_alloc (2);
4348 gen_rtx_SET (VOIDmode
, dst
, op_res
);
4350 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
4351 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
4356 /* Try SUBTRACT LOGICAL WITH BORROW. */
4357 if (increment
== constm1_rtx
)
4359 /* Determine CC mode to use. */
4360 if (cmp_code
== EQ
|| cmp_code
== NE
)
4362 if (cmp_op1
!= const0_rtx
)
4364 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
4365 NULL_RTX
, 0, OPTAB_WIDEN
);
4366 cmp_op1
= const0_rtx
;
4369 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
4372 if (cmp_code
== GTU
|| cmp_code
== GEU
)
4377 cmp_code
= swap_condition (cmp_code
);
4394 /* Emit comparison instruction pattern. */
4395 if (!register_operand (cmp_op0
, cmp_mode
))
4396 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
4398 insn
= gen_rtx_SET (VOIDmode
, gen_rtx_REG (cc_mode
, CC_REGNUM
),
4399 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
4400 /* We use insn_invalid_p here to add clobbers if required. */
4401 ret
= insn_invalid_p (emit_insn (insn
));
4404 /* Emit SLB instruction pattern. */
4405 if (!register_operand (src
, GET_MODE (dst
)))
4406 src
= force_reg (GET_MODE (dst
), src
);
4408 op_res
= gen_rtx_MINUS (GET_MODE (dst
),
4409 gen_rtx_MINUS (GET_MODE (dst
), src
, const0_rtx
),
4410 gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
4411 gen_rtx_REG (cc_mode
, CC_REGNUM
),
4413 p
= rtvec_alloc (2);
4415 gen_rtx_SET (VOIDmode
, dst
, op_res
);
4417 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
4418 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
4426 /* Expand code for the insv template. Return true if successful. */
4429 s390_expand_insv (rtx dest
, rtx op1
, rtx op2
, rtx src
)
4431 int bitsize
= INTVAL (op1
);
4432 int bitpos
= INTVAL (op2
);
4434 /* On z10 we can use the risbg instruction to implement insv. */
4436 && ((GET_MODE (dest
) == DImode
&& GET_MODE (src
) == DImode
)
4437 || (GET_MODE (dest
) == SImode
&& GET_MODE (src
) == SImode
)))
4442 op
= gen_rtx_SET (GET_MODE(src
),
4443 gen_rtx_ZERO_EXTRACT (GET_MODE (dest
), dest
, op1
, op2
),
4445 clobber
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
4446 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, op
, clobber
)));
4451 /* We need byte alignment. */
4452 if (bitsize
% BITS_PER_UNIT
)
4456 && memory_operand (dest
, VOIDmode
)
4457 && (register_operand (src
, word_mode
)
4458 || const_int_operand (src
, VOIDmode
)))
4460 /* Emit standard pattern if possible. */
4461 enum machine_mode mode
= smallest_mode_for_size (bitsize
, MODE_INT
);
4462 if (GET_MODE_BITSIZE (mode
) == bitsize
)
4463 emit_move_insn (adjust_address (dest
, mode
, 0), gen_lowpart (mode
, src
));
4465 /* (set (ze (mem)) (const_int)). */
4466 else if (const_int_operand (src
, VOIDmode
))
4468 int size
= bitsize
/ BITS_PER_UNIT
;
4469 rtx src_mem
= adjust_address (force_const_mem (word_mode
, src
), BLKmode
,
4470 GET_MODE_SIZE (word_mode
) - size
);
4472 dest
= adjust_address (dest
, BLKmode
, 0);
4473 set_mem_size (dest
, GEN_INT (size
));
4474 s390_expand_movmem (dest
, src_mem
, GEN_INT (size
));
4477 /* (set (ze (mem)) (reg)). */
4478 else if (register_operand (src
, word_mode
))
4480 if (bitsize
<= GET_MODE_BITSIZE (SImode
))
4481 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode
, dest
, op1
,
4485 /* Emit st,stcmh sequence. */
4486 int stcmh_width
= bitsize
- GET_MODE_BITSIZE (SImode
);
4487 int size
= stcmh_width
/ BITS_PER_UNIT
;
4489 emit_move_insn (adjust_address (dest
, SImode
, size
),
4490 gen_lowpart (SImode
, src
));
4491 set_mem_size (dest
, GEN_INT (size
));
4492 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode
, dest
, GEN_INT
4493 (stcmh_width
), const0_rtx
),
4494 gen_rtx_LSHIFTRT (word_mode
, src
, GEN_INT
4495 (GET_MODE_BITSIZE (SImode
))));
4504 /* (set (ze (reg)) (const_int)). */
4506 && register_operand (dest
, word_mode
)
4507 && (bitpos
% 16) == 0
4508 && (bitsize
% 16) == 0
4509 && const_int_operand (src
, VOIDmode
))
4511 HOST_WIDE_INT val
= INTVAL (src
);
4512 int regpos
= bitpos
+ bitsize
;
4514 while (regpos
> bitpos
)
4516 enum machine_mode putmode
;
4519 if (TARGET_EXTIMM
&& (regpos
% 32 == 0) && (regpos
>= bitpos
+ 32))
4524 putsize
= GET_MODE_BITSIZE (putmode
);
4526 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode
, dest
,
4529 gen_int_mode (val
, putmode
));
4532 gcc_assert (regpos
== bitpos
);
4539 /* A subroutine of s390_expand_cs_hqi and s390_expand_atomic which returns a
4540 register that holds VAL of mode MODE shifted by COUNT bits. */
4543 s390_expand_mask_and_shift (rtx val
, enum machine_mode mode
, rtx count
)
4545 val
= expand_simple_binop (SImode
, AND
, val
, GEN_INT (GET_MODE_MASK (mode
)),
4546 NULL_RTX
, 1, OPTAB_DIRECT
);
4547 return expand_simple_binop (SImode
, ASHIFT
, val
, count
,
4548 NULL_RTX
, 1, OPTAB_DIRECT
);
4551 /* Structure to hold the initial parameters for a compare_and_swap operation
4552 in HImode and QImode. */
4554 struct alignment_context
4556 rtx memsi
; /* SI aligned memory location. */
4557 rtx shift
; /* Bit offset with regard to lsb. */
4558 rtx modemask
; /* Mask of the HQImode shifted by SHIFT bits. */
4559 rtx modemaski
; /* ~modemask */
4560 bool aligned
; /* True if memory is aligned, false else. */
4563 /* A subroutine of s390_expand_cs_hqi and s390_expand_atomic to initialize
4564 structure AC for transparent simplifying, if the memory alignment is known
4565 to be at least 32bit. MEM is the memory location for the actual operation
4566 and MODE its mode. */
4569 init_alignment_context (struct alignment_context
*ac
, rtx mem
,
4570 enum machine_mode mode
)
4572 ac
->shift
= GEN_INT (GET_MODE_SIZE (SImode
) - GET_MODE_SIZE (mode
));
4573 ac
->aligned
= (MEM_ALIGN (mem
) >= GET_MODE_BITSIZE (SImode
));
4576 ac
->memsi
= adjust_address (mem
, SImode
, 0); /* Memory is aligned. */
4579 /* Alignment is unknown. */
4580 rtx byteoffset
, addr
, align
;
4582 /* Force the address into a register. */
4583 addr
= force_reg (Pmode
, XEXP (mem
, 0));
4585 /* Align it to SImode. */
4586 align
= expand_simple_binop (Pmode
, AND
, addr
,
4587 GEN_INT (-GET_MODE_SIZE (SImode
)),
4588 NULL_RTX
, 1, OPTAB_DIRECT
);
4590 ac
->memsi
= gen_rtx_MEM (SImode
, align
);
4591 MEM_VOLATILE_P (ac
->memsi
) = MEM_VOLATILE_P (mem
);
4592 set_mem_alias_set (ac
->memsi
, ALIAS_SET_MEMORY_BARRIER
);
4593 set_mem_align (ac
->memsi
, GET_MODE_BITSIZE (SImode
));
4595 /* Calculate shiftcount. */
4596 byteoffset
= expand_simple_binop (Pmode
, AND
, addr
,
4597 GEN_INT (GET_MODE_SIZE (SImode
) - 1),
4598 NULL_RTX
, 1, OPTAB_DIRECT
);
4599 /* As we already have some offset, evaluate the remaining distance. */
4600 ac
->shift
= expand_simple_binop (SImode
, MINUS
, ac
->shift
, byteoffset
,
4601 NULL_RTX
, 1, OPTAB_DIRECT
);
4604 /* Shift is the byte count, but we need the bitcount. */
4605 ac
->shift
= expand_simple_binop (SImode
, MULT
, ac
->shift
, GEN_INT (BITS_PER_UNIT
),
4606 NULL_RTX
, 1, OPTAB_DIRECT
);
4607 /* Calculate masks. */
4608 ac
->modemask
= expand_simple_binop (SImode
, ASHIFT
,
4609 GEN_INT (GET_MODE_MASK (mode
)), ac
->shift
,
4610 NULL_RTX
, 1, OPTAB_DIRECT
);
4611 ac
->modemaski
= expand_simple_unop (SImode
, NOT
, ac
->modemask
, NULL_RTX
, 1);
4614 /* Expand an atomic compare and swap operation for HImode and QImode. MEM is
4615 the memory location, CMP the old value to compare MEM with and NEW_RTX the value
4616 to set if CMP == MEM.
4617 CMP is never in memory for compare_and_swap_cc because
4618 expand_bool_compare_and_swap puts it into a register for later compare. */
4621 s390_expand_cs_hqi (enum machine_mode mode
, rtx target
, rtx mem
, rtx cmp
, rtx new_rtx
)
4623 struct alignment_context ac
;
4624 rtx cmpv
, newv
, val
, resv
, cc
;
4625 rtx res
= gen_reg_rtx (SImode
);
4626 rtx csloop
= gen_label_rtx ();
4627 rtx csend
= gen_label_rtx ();
4629 gcc_assert (register_operand (target
, VOIDmode
));
4630 gcc_assert (MEM_P (mem
));
4632 init_alignment_context (&ac
, mem
, mode
);
4634 /* Shift the values to the correct bit positions. */
4635 if (!(ac
.aligned
&& MEM_P (cmp
)))
4636 cmp
= s390_expand_mask_and_shift (cmp
, mode
, ac
.shift
);
4637 if (!(ac
.aligned
&& MEM_P (new_rtx
)))
4638 new_rtx
= s390_expand_mask_and_shift (new_rtx
, mode
, ac
.shift
);
4640 /* Load full word. Subsequent loads are performed by CS. */
4641 val
= expand_simple_binop (SImode
, AND
, ac
.memsi
, ac
.modemaski
,
4642 NULL_RTX
, 1, OPTAB_DIRECT
);
4644 /* Start CS loop. */
4645 emit_label (csloop
);
4646 /* val = "<mem>00..0<mem>"
4647 * cmp = "00..0<cmp>00..0"
4648 * new = "00..0<new>00..0"
4651 /* Patch cmp and new with val at correct position. */
4652 if (ac
.aligned
&& MEM_P (cmp
))
4654 cmpv
= force_reg (SImode
, val
);
4655 store_bit_field (cmpv
, GET_MODE_BITSIZE (mode
), 0, SImode
, cmp
);
4658 cmpv
= force_reg (SImode
, expand_simple_binop (SImode
, IOR
, cmp
, val
,
4659 NULL_RTX
, 1, OPTAB_DIRECT
));
4660 if (ac
.aligned
&& MEM_P (new_rtx
))
4662 newv
= force_reg (SImode
, val
);
4663 store_bit_field (newv
, GET_MODE_BITSIZE (mode
), 0, SImode
, new_rtx
);
4666 newv
= force_reg (SImode
, expand_simple_binop (SImode
, IOR
, new_rtx
, val
,
4667 NULL_RTX
, 1, OPTAB_DIRECT
));
4669 /* Jump to end if we're done (likely?). */
4670 s390_emit_jump (csend
, s390_emit_compare_and_swap (EQ
, res
, ac
.memsi
,
4673 /* Check for changes outside mode. */
4674 resv
= expand_simple_binop (SImode
, AND
, res
, ac
.modemaski
,
4675 NULL_RTX
, 1, OPTAB_DIRECT
);
4676 cc
= s390_emit_compare (NE
, resv
, val
);
4677 emit_move_insn (val
, resv
);
4678 /* Loop internal if so. */
4679 s390_emit_jump (csloop
, cc
);
4683 /* Return the correct part of the bitfield. */
4684 convert_move (target
, expand_simple_binop (SImode
, LSHIFTRT
, res
, ac
.shift
,
4685 NULL_RTX
, 1, OPTAB_DIRECT
), 1);
4688 /* Expand an atomic operation CODE of mode MODE. MEM is the memory location
4689 and VAL the value to play with. If AFTER is true then store the value
4690 MEM holds after the operation, if AFTER is false then store the value MEM
4691 holds before the operation. If TARGET is zero then discard that value, else
4692 store it to TARGET. */
4695 s390_expand_atomic (enum machine_mode mode
, enum rtx_code code
,
4696 rtx target
, rtx mem
, rtx val
, bool after
)
4698 struct alignment_context ac
;
4700 rtx new_rtx
= gen_reg_rtx (SImode
);
4701 rtx orig
= gen_reg_rtx (SImode
);
4702 rtx csloop
= gen_label_rtx ();
4704 gcc_assert (!target
|| register_operand (target
, VOIDmode
));
4705 gcc_assert (MEM_P (mem
));
4707 init_alignment_context (&ac
, mem
, mode
);
4709 /* Shift val to the correct bit positions.
4710 Preserve "icm", but prevent "ex icm". */
4711 if (!(ac
.aligned
&& code
== SET
&& MEM_P (val
)))
4712 val
= s390_expand_mask_and_shift (val
, mode
, ac
.shift
);
4714 /* Further preparation insns. */
4715 if (code
== PLUS
|| code
== MINUS
)
4716 emit_move_insn (orig
, val
);
4717 else if (code
== MULT
|| code
== AND
) /* val = "11..1<val>11..1" */
4718 val
= expand_simple_binop (SImode
, XOR
, val
, ac
.modemaski
,
4719 NULL_RTX
, 1, OPTAB_DIRECT
);
4721 /* Load full word. Subsequent loads are performed by CS. */
4722 cmp
= force_reg (SImode
, ac
.memsi
);
4724 /* Start CS loop. */
4725 emit_label (csloop
);
4726 emit_move_insn (new_rtx
, cmp
);
4728 /* Patch new with val at correct position. */
4733 val
= expand_simple_binop (SImode
, code
, new_rtx
, orig
,
4734 NULL_RTX
, 1, OPTAB_DIRECT
);
4735 val
= expand_simple_binop (SImode
, AND
, val
, ac
.modemask
,
4736 NULL_RTX
, 1, OPTAB_DIRECT
);
4739 if (ac
.aligned
&& MEM_P (val
))
4740 store_bit_field (new_rtx
, GET_MODE_BITSIZE (mode
), 0, SImode
, val
);
4743 new_rtx
= expand_simple_binop (SImode
, AND
, new_rtx
, ac
.modemaski
,
4744 NULL_RTX
, 1, OPTAB_DIRECT
);
4745 new_rtx
= expand_simple_binop (SImode
, IOR
, new_rtx
, val
,
4746 NULL_RTX
, 1, OPTAB_DIRECT
);
4752 new_rtx
= expand_simple_binop (SImode
, code
, new_rtx
, val
,
4753 NULL_RTX
, 1, OPTAB_DIRECT
);
4755 case MULT
: /* NAND */
4756 new_rtx
= expand_simple_binop (SImode
, AND
, new_rtx
, val
,
4757 NULL_RTX
, 1, OPTAB_DIRECT
);
4758 new_rtx
= expand_simple_binop (SImode
, XOR
, new_rtx
, ac
.modemask
,
4759 NULL_RTX
, 1, OPTAB_DIRECT
);
4765 s390_emit_jump (csloop
, s390_emit_compare_and_swap (NE
, cmp
,
4766 ac
.memsi
, cmp
, new_rtx
));
4768 /* Return the correct part of the bitfield. */
4770 convert_move (target
, expand_simple_binop (SImode
, LSHIFTRT
,
4771 after
? new_rtx
: cmp
, ac
.shift
,
4772 NULL_RTX
, 1, OPTAB_DIRECT
), 1);
4775 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
4776 We need to emit DTP-relative relocations. */
4778 static void s390_output_dwarf_dtprel (FILE *, int, rtx
) ATTRIBUTE_UNUSED
;
4781 s390_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
4786 fputs ("\t.long\t", file
);
4789 fputs ("\t.quad\t", file
);
4794 output_addr_const (file
, x
);
4795 fputs ("@DTPOFF", file
);
4798 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
4799 /* Implement TARGET_MANGLE_TYPE. */
4802 s390_mangle_type (const_tree type
)
4804 if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
4805 && TARGET_LONG_DOUBLE_128
)
4808 /* For all other types, use normal C++ mangling. */
4813 /* In the name of slightly smaller debug output, and to cater to
4814 general assembler lossage, recognize various UNSPEC sequences
4815 and turn them back into a direct symbol reference. */
4818 s390_delegitimize_address (rtx orig_x
)
4822 orig_x
= delegitimize_mem_from_attrs (orig_x
);
4824 if (GET_CODE (x
) != MEM
)
4828 if (GET_CODE (x
) == PLUS
4829 && GET_CODE (XEXP (x
, 1)) == CONST
4830 && GET_CODE (XEXP (x
, 0)) == REG
4831 && REGNO (XEXP (x
, 0)) == PIC_OFFSET_TABLE_REGNUM
)
4833 y
= XEXP (XEXP (x
, 1), 0);
4834 if (GET_CODE (y
) == UNSPEC
4835 && XINT (y
, 1) == UNSPEC_GOT
)
4836 return XVECEXP (y
, 0, 0);
4840 if (GET_CODE (x
) == CONST
)
4843 if (GET_CODE (y
) == UNSPEC
4844 && XINT (y
, 1) == UNSPEC_GOTENT
)
4845 return XVECEXP (y
, 0, 0);
4852 /* Output operand OP to stdio stream FILE.
4853 OP is an address (register + offset) which is not used to address data;
4854 instead the rightmost bits are interpreted as the value. */
4857 print_shift_count_operand (FILE *file
, rtx op
)
4859 HOST_WIDE_INT offset
;
4862 /* Extract base register and offset. */
4863 if (!s390_decompose_shift_count (op
, &base
, &offset
))
4869 gcc_assert (GET_CODE (base
) == REG
);
4870 gcc_assert (REGNO (base
) < FIRST_PSEUDO_REGISTER
);
4871 gcc_assert (REGNO_REG_CLASS (REGNO (base
)) == ADDR_REGS
);
4874 /* Offsets are constricted to twelve bits. */
4875 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
& ((1 << 12) - 1));
4877 fprintf (file
, "(%s)", reg_names
[REGNO (base
)]);
4880 /* See 'get_some_local_dynamic_name'. */
4883 get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
4887 if (GET_CODE (x
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (x
))
4889 x
= get_pool_constant (x
);
4890 return for_each_rtx (&x
, get_some_local_dynamic_name_1
, 0);
4893 if (GET_CODE (x
) == SYMBOL_REF
4894 && tls_symbolic_operand (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
4896 cfun
->machine
->some_ld_name
= XSTR (x
, 0);
4903 /* Locate some local-dynamic symbol still in use by this function
4904 so that we can print its name in local-dynamic base patterns. */
4907 get_some_local_dynamic_name (void)
4911 if (cfun
->machine
->some_ld_name
)
4912 return cfun
->machine
->some_ld_name
;
4914 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
4916 && for_each_rtx (&PATTERN (insn
), get_some_local_dynamic_name_1
, 0))
4917 return cfun
->machine
->some_ld_name
;
4922 /* Output machine-dependent UNSPECs occurring in address constant X
4923 in assembler syntax to stdio stream FILE. Returns true if the
4924 constant X could be recognized, false otherwise. */
4927 s390_output_addr_const_extra (FILE *file
, rtx x
)
4929 if (GET_CODE (x
) == UNSPEC
&& XVECLEN (x
, 0) == 1)
4930 switch (XINT (x
, 1))
4933 output_addr_const (file
, XVECEXP (x
, 0, 0));
4934 fprintf (file
, "@GOTENT");
4937 output_addr_const (file
, XVECEXP (x
, 0, 0));
4938 fprintf (file
, "@GOT");
4941 output_addr_const (file
, XVECEXP (x
, 0, 0));
4942 fprintf (file
, "@GOTOFF");
4945 output_addr_const (file
, XVECEXP (x
, 0, 0));
4946 fprintf (file
, "@PLT");
4949 output_addr_const (file
, XVECEXP (x
, 0, 0));
4950 fprintf (file
, "@PLTOFF");
4953 output_addr_const (file
, XVECEXP (x
, 0, 0));
4954 fprintf (file
, "@TLSGD");
4957 assemble_name (file
, get_some_local_dynamic_name ());
4958 fprintf (file
, "@TLSLDM");
4961 output_addr_const (file
, XVECEXP (x
, 0, 0));
4962 fprintf (file
, "@DTPOFF");
4965 output_addr_const (file
, XVECEXP (x
, 0, 0));
4966 fprintf (file
, "@NTPOFF");
4968 case UNSPEC_GOTNTPOFF
:
4969 output_addr_const (file
, XVECEXP (x
, 0, 0));
4970 fprintf (file
, "@GOTNTPOFF");
4972 case UNSPEC_INDNTPOFF
:
4973 output_addr_const (file
, XVECEXP (x
, 0, 0));
4974 fprintf (file
, "@INDNTPOFF");
4978 if (GET_CODE (x
) == UNSPEC
&& XVECLEN (x
, 0) == 2)
4979 switch (XINT (x
, 1))
4981 case UNSPEC_POOL_OFFSET
:
4982 x
= gen_rtx_MINUS (GET_MODE (x
), XVECEXP (x
, 0, 0), XVECEXP (x
, 0, 1));
4983 output_addr_const (file
, x
);
4989 /* Output address operand ADDR in assembler syntax to
4990 stdio stream FILE. */
4993 print_operand_address (FILE *file
, rtx addr
)
4995 struct s390_address ad
;
4997 if (s390_symref_operand_p (addr
, NULL
, NULL
))
4999 gcc_assert (TARGET_Z10
);
5000 output_addr_const (file
, addr
);
5004 if (!s390_decompose_address (addr
, &ad
)
5005 || (ad
.base
&& !REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)))
5006 || (ad
.indx
&& !REGNO_OK_FOR_INDEX_P (REGNO (ad
.indx
))))
5007 output_operand_lossage ("cannot decompose address");
5010 output_addr_const (file
, ad
.disp
);
5012 fprintf (file
, "0");
5014 if (ad
.base
&& ad
.indx
)
5015 fprintf (file
, "(%s,%s)", reg_names
[REGNO (ad
.indx
)],
5016 reg_names
[REGNO (ad
.base
)]);
5018 fprintf (file
, "(%s)", reg_names
[REGNO (ad
.base
)]);
5021 /* Output operand X in assembler syntax to stdio stream FILE.
5022 CODE specified the format flag. The following format flags
5025 'C': print opcode suffix for branch condition.
5026 'D': print opcode suffix for inverse branch condition.
5027 'E': print opcode suffix for branch on index instruction.
5028 'J': print tls_load/tls_gdcall/tls_ldcall suffix
5029 'G': print the size of the operand in bytes.
5030 'O': print only the displacement of a memory reference.
5031 'R': print only the base register of a memory reference.
5032 'S': print S-type memory reference (base+displacement).
5033 'N': print the second word of a DImode operand.
5034 'M': print the second word of a TImode operand.
5035 'Y': print shift count operand.
5037 'b': print integer X as if it's an unsigned byte.
5038 'c': print integer X as if it's an signed byte.
5039 'x': print integer X as if it's an unsigned halfword.
5040 'h': print integer X as if it's a signed halfword.
5041 'i': print the first nonzero HImode part of X.
5042 'j': print the first HImode part unequal to -1 of X.
5043 'k': print the first nonzero SImode part of X.
5044 'm': print the first SImode part unequal to -1 of X.
5045 'o': print integer X as if it's an unsigned 32bit word. */
5048 print_operand (FILE *file
, rtx x
, int code
)
5053 fprintf (file
, s390_branch_condition_mnemonic (x
, FALSE
));
5057 fprintf (file
, s390_branch_condition_mnemonic (x
, TRUE
));
5061 if (GET_CODE (x
) == LE
)
5062 fprintf (file
, "l");
5063 else if (GET_CODE (x
) == GT
)
5064 fprintf (file
, "h");
5070 if (GET_CODE (x
) == SYMBOL_REF
)
5072 fprintf (file
, "%s", ":tls_load:");
5073 output_addr_const (file
, x
);
5075 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSGD
)
5077 fprintf (file
, "%s", ":tls_gdcall:");
5078 output_addr_const (file
, XVECEXP (x
, 0, 0));
5080 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSLDM
)
5082 fprintf (file
, "%s", ":tls_ldcall:");
5083 assemble_name (file
, get_some_local_dynamic_name ());
5090 fprintf (file
, "%u", GET_MODE_SIZE (GET_MODE (x
)));
5095 struct s390_address ad
;
5098 gcc_assert (GET_CODE (x
) == MEM
);
5099 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
5101 gcc_assert (!ad
.base
|| REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)));
5102 gcc_assert (!ad
.indx
);
5105 output_addr_const (file
, ad
.disp
);
5107 fprintf (file
, "0");
5113 struct s390_address ad
;
5116 gcc_assert (GET_CODE (x
) == MEM
);
5117 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
5119 gcc_assert (!ad
.base
|| REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)));
5120 gcc_assert (!ad
.indx
);
5123 fprintf (file
, "%s", reg_names
[REGNO (ad
.base
)]);
5125 fprintf (file
, "0");
5131 struct s390_address ad
;
5134 gcc_assert (GET_CODE (x
) == MEM
);
5135 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
5137 gcc_assert (!ad
.base
|| REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)));
5138 gcc_assert (!ad
.indx
);
5141 output_addr_const (file
, ad
.disp
);
5143 fprintf (file
, "0");
5146 fprintf (file
, "(%s)", reg_names
[REGNO (ad
.base
)]);
5151 if (GET_CODE (x
) == REG
)
5152 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
5153 else if (GET_CODE (x
) == MEM
)
5154 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 4));
5160 if (GET_CODE (x
) == REG
)
5161 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
5162 else if (GET_CODE (x
) == MEM
)
5163 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 8));
5169 print_shift_count_operand (file
, x
);
5173 switch (GET_CODE (x
))
5176 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
5180 output_address (XEXP (x
, 0));
5187 output_addr_const (file
, x
);
5192 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xff);
5193 else if (code
== 'c')
5194 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((INTVAL (x
) & 0xff) ^ 0x80) - 0x80);
5195 else if (code
== 'x')
5196 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xffff);
5197 else if (code
== 'h')
5198 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((INTVAL (x
) & 0xffff) ^ 0x8000) - 0x8000);
5199 else if (code
== 'i')
5200 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
5201 s390_extract_part (x
, HImode
, 0));
5202 else if (code
== 'j')
5203 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
5204 s390_extract_part (x
, HImode
, -1));
5205 else if (code
== 'k')
5206 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
5207 s390_extract_part (x
, SImode
, 0));
5208 else if (code
== 'm')
5209 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
5210 s390_extract_part (x
, SImode
, -1));
5211 else if (code
== 'o')
5212 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xffffffff);
5214 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
5218 gcc_assert (GET_MODE (x
) == VOIDmode
);
5220 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xff);
5221 else if (code
== 'x')
5222 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xffff);
5223 else if (code
== 'h')
5224 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((CONST_DOUBLE_LOW (x
) & 0xffff) ^ 0x8000) - 0x8000);
5230 fatal_insn ("UNKNOWN in print_operand !?", x
);
5235 /* Target hook for assembling integer objects. We need to define it
5236 here to work a round a bug in some versions of GAS, which couldn't
5237 handle values smaller than INT_MIN when printed in decimal. */
5240 s390_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
5242 if (size
== 8 && aligned_p
5243 && GET_CODE (x
) == CONST_INT
&& INTVAL (x
) < INT_MIN
)
5245 fprintf (asm_out_file
, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX
"\n",
5249 return default_assemble_integer (x
, size
, aligned_p
);
5252 /* Returns true if register REGNO is used for forming
5253 a memory address in expression X. */
5256 reg_used_in_mem_p (int regno
, rtx x
)
5258 enum rtx_code code
= GET_CODE (x
);
5264 if (refers_to_regno_p (regno
, regno
+1,
5268 else if (code
== SET
5269 && GET_CODE (SET_DEST (x
)) == PC
)
5271 if (refers_to_regno_p (regno
, regno
+1,
5276 fmt
= GET_RTX_FORMAT (code
);
5277 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
5280 && reg_used_in_mem_p (regno
, XEXP (x
, i
)))
5283 else if (fmt
[i
] == 'E')
5284 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
5285 if (reg_used_in_mem_p (regno
, XVECEXP (x
, i
, j
)))
5291 /* Returns true if expression DEP_RTX sets an address register
5292 used by instruction INSN to address memory. */
5295 addr_generation_dependency_p (rtx dep_rtx
, rtx insn
)
5299 if (GET_CODE (dep_rtx
) == INSN
)
5300 dep_rtx
= PATTERN (dep_rtx
);
5302 if (GET_CODE (dep_rtx
) == SET
)
5304 target
= SET_DEST (dep_rtx
);
5305 if (GET_CODE (target
) == STRICT_LOW_PART
)
5306 target
= XEXP (target
, 0);
5307 while (GET_CODE (target
) == SUBREG
)
5308 target
= SUBREG_REG (target
);
5310 if (GET_CODE (target
) == REG
)
5312 int regno
= REGNO (target
);
5314 if (s390_safe_attr_type (insn
) == TYPE_LA
)
5316 pat
= PATTERN (insn
);
5317 if (GET_CODE (pat
) == PARALLEL
)
5319 gcc_assert (XVECLEN (pat
, 0) == 2);
5320 pat
= XVECEXP (pat
, 0, 0);
5322 gcc_assert (GET_CODE (pat
) == SET
);
5323 return refers_to_regno_p (regno
, regno
+1, SET_SRC (pat
), 0);
5325 else if (get_attr_atype (insn
) == ATYPE_AGEN
)
5326 return reg_used_in_mem_p (regno
, PATTERN (insn
));
5332 /* Return 1, if dep_insn sets register used in insn in the agen unit. */
5335 s390_agen_dep_p (rtx dep_insn
, rtx insn
)
5337 rtx dep_rtx
= PATTERN (dep_insn
);
5340 if (GET_CODE (dep_rtx
) == SET
5341 && addr_generation_dependency_p (dep_rtx
, insn
))
5343 else if (GET_CODE (dep_rtx
) == PARALLEL
)
5345 for (i
= 0; i
< XVECLEN (dep_rtx
, 0); i
++)
5347 if (addr_generation_dependency_p (XVECEXP (dep_rtx
, 0, i
), insn
))
5355 /* A C statement (sans semicolon) to update the integer scheduling priority
5356 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
5357 reduce the priority to execute INSN later. Do not define this macro if
5358 you do not need to adjust the scheduling priorities of insns.
5360 A STD instruction should be scheduled earlier,
5361 in order to use the bypass. */
5365 s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
5367 if (! INSN_P (insn
))
5370 if (s390_tune
!= PROCESSOR_2084_Z990
5371 && s390_tune
!= PROCESSOR_2094_Z9_109
5372 && s390_tune
!= PROCESSOR_2097_Z10
)
5375 switch (s390_safe_attr_type (insn
))
5379 priority
= priority
<< 3;
5383 priority
= priority
<< 1;
5392 /* The number of instructions that can be issued per cycle. */
5395 s390_issue_rate (void)
5399 case PROCESSOR_2084_Z990
:
5400 case PROCESSOR_2094_Z9_109
:
5402 case PROCESSOR_2097_Z10
:
5410 s390_first_cycle_multipass_dfa_lookahead (void)
5416 /* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
5417 Fix up MEMs as required. */
5420 annotate_constant_pool_refs (rtx
*x
)
5425 gcc_assert (GET_CODE (*x
) != SYMBOL_REF
5426 || !CONSTANT_POOL_ADDRESS_P (*x
));
5428 /* Literal pool references can only occur inside a MEM ... */
5429 if (GET_CODE (*x
) == MEM
)
5431 rtx memref
= XEXP (*x
, 0);
5433 if (GET_CODE (memref
) == SYMBOL_REF
5434 && CONSTANT_POOL_ADDRESS_P (memref
))
5436 rtx base
= cfun
->machine
->base_reg
;
5437 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, memref
, base
),
5440 *x
= replace_equiv_address (*x
, addr
);
5444 if (GET_CODE (memref
) == CONST
5445 && GET_CODE (XEXP (memref
, 0)) == PLUS
5446 && GET_CODE (XEXP (XEXP (memref
, 0), 1)) == CONST_INT
5447 && GET_CODE (XEXP (XEXP (memref
, 0), 0)) == SYMBOL_REF
5448 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (memref
, 0), 0)))
5450 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (memref
, 0), 1));
5451 rtx sym
= XEXP (XEXP (memref
, 0), 0);
5452 rtx base
= cfun
->machine
->base_reg
;
5453 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
5456 *x
= replace_equiv_address (*x
, plus_constant (addr
, off
));
5461 /* ... or a load-address type pattern. */
5462 if (GET_CODE (*x
) == SET
)
5464 rtx addrref
= SET_SRC (*x
);
5466 if (GET_CODE (addrref
) == SYMBOL_REF
5467 && CONSTANT_POOL_ADDRESS_P (addrref
))
5469 rtx base
= cfun
->machine
->base_reg
;
5470 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, addrref
, base
),
5473 SET_SRC (*x
) = addr
;
5477 if (GET_CODE (addrref
) == CONST
5478 && GET_CODE (XEXP (addrref
, 0)) == PLUS
5479 && GET_CODE (XEXP (XEXP (addrref
, 0), 1)) == CONST_INT
5480 && GET_CODE (XEXP (XEXP (addrref
, 0), 0)) == SYMBOL_REF
5481 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (addrref
, 0), 0)))
5483 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (addrref
, 0), 1));
5484 rtx sym
= XEXP (XEXP (addrref
, 0), 0);
5485 rtx base
= cfun
->machine
->base_reg
;
5486 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
5489 SET_SRC (*x
) = plus_constant (addr
, off
);
5494 /* Annotate LTREL_BASE as well. */
5495 if (GET_CODE (*x
) == UNSPEC
5496 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
5498 rtx base
= cfun
->machine
->base_reg
;
5499 *x
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XVECEXP (*x
, 0, 0), base
),
5504 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
5505 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
5509 annotate_constant_pool_refs (&XEXP (*x
, i
));
5511 else if (fmt
[i
] == 'E')
5513 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
5514 annotate_constant_pool_refs (&XVECEXP (*x
, i
, j
));
5519 /* Split all branches that exceed the maximum distance.
5520 Returns true if this created a new literal pool entry. */
5523 s390_split_branches (void)
5525 rtx temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
5526 int new_literal
= 0, ret
;
5527 rtx insn
, pat
, tmp
, target
;
5530 /* We need correct insn addresses. */
5532 shorten_branches (get_insns ());
5534 /* Find all branches that exceed 64KB, and split them. */
5536 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5538 if (GET_CODE (insn
) != JUMP_INSN
)
5541 pat
= PATTERN (insn
);
5542 if (GET_CODE (pat
) == PARALLEL
&& XVECLEN (pat
, 0) > 2)
5543 pat
= XVECEXP (pat
, 0, 0);
5544 if (GET_CODE (pat
) != SET
|| SET_DEST (pat
) != pc_rtx
)
5547 if (GET_CODE (SET_SRC (pat
)) == LABEL_REF
)
5549 label
= &SET_SRC (pat
);
5551 else if (GET_CODE (SET_SRC (pat
)) == IF_THEN_ELSE
)
5553 if (GET_CODE (XEXP (SET_SRC (pat
), 1)) == LABEL_REF
)
5554 label
= &XEXP (SET_SRC (pat
), 1);
5555 else if (GET_CODE (XEXP (SET_SRC (pat
), 2)) == LABEL_REF
)
5556 label
= &XEXP (SET_SRC (pat
), 2);
5563 if (get_attr_length (insn
) <= 4)
5566 /* We are going to use the return register as scratch register,
5567 make sure it will be saved/restored by the prologue/epilogue. */
5568 cfun_frame_layout
.save_return_addr_p
= 1;
5573 tmp
= force_const_mem (Pmode
, *label
);
5574 tmp
= emit_insn_before (gen_rtx_SET (Pmode
, temp_reg
, tmp
), insn
);
5575 INSN_ADDRESSES_NEW (tmp
, -1);
5576 annotate_constant_pool_refs (&PATTERN (tmp
));
5583 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, *label
),
5584 UNSPEC_LTREL_OFFSET
);
5585 target
= gen_rtx_CONST (Pmode
, target
);
5586 target
= force_const_mem (Pmode
, target
);
5587 tmp
= emit_insn_before (gen_rtx_SET (Pmode
, temp_reg
, target
), insn
);
5588 INSN_ADDRESSES_NEW (tmp
, -1);
5589 annotate_constant_pool_refs (&PATTERN (tmp
));
5591 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XEXP (target
, 0),
5592 cfun
->machine
->base_reg
),
5594 target
= gen_rtx_PLUS (Pmode
, temp_reg
, target
);
5597 ret
= validate_change (insn
, label
, target
, 0);
5605 /* Find an annotated literal pool symbol referenced in RTX X,
5606 and store it at REF. Will abort if X contains references to
5607 more than one such pool symbol; multiple references to the same
5608 symbol are allowed, however.
5610 The rtx pointed to by REF must be initialized to NULL_RTX
5611 by the caller before calling this routine. */
5614 find_constant_pool_ref (rtx x
, rtx
*ref
)
5619 /* Ignore LTREL_BASE references. */
5620 if (GET_CODE (x
) == UNSPEC
5621 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
5623 /* Likewise POOL_ENTRY insns. */
5624 if (GET_CODE (x
) == UNSPEC_VOLATILE
5625 && XINT (x
, 1) == UNSPECV_POOL_ENTRY
)
5628 gcc_assert (GET_CODE (x
) != SYMBOL_REF
5629 || !CONSTANT_POOL_ADDRESS_P (x
));
5631 if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_LTREF
)
5633 rtx sym
= XVECEXP (x
, 0, 0);
5634 gcc_assert (GET_CODE (sym
) == SYMBOL_REF
5635 && CONSTANT_POOL_ADDRESS_P (sym
));
5637 if (*ref
== NULL_RTX
)
5640 gcc_assert (*ref
== sym
);
5645 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
5646 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
5650 find_constant_pool_ref (XEXP (x
, i
), ref
);
5652 else if (fmt
[i
] == 'E')
5654 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
5655 find_constant_pool_ref (XVECEXP (x
, i
, j
), ref
);
5660 /* Replace every reference to the annotated literal pool
5661 symbol REF in X by its base plus OFFSET. */
5664 replace_constant_pool_ref (rtx
*x
, rtx ref
, rtx offset
)
5669 gcc_assert (*x
!= ref
);
5671 if (GET_CODE (*x
) == UNSPEC
5672 && XINT (*x
, 1) == UNSPEC_LTREF
5673 && XVECEXP (*x
, 0, 0) == ref
)
5675 *x
= gen_rtx_PLUS (Pmode
, XVECEXP (*x
, 0, 1), offset
);
5679 if (GET_CODE (*x
) == PLUS
5680 && GET_CODE (XEXP (*x
, 1)) == CONST_INT
5681 && GET_CODE (XEXP (*x
, 0)) == UNSPEC
5682 && XINT (XEXP (*x
, 0), 1) == UNSPEC_LTREF
5683 && XVECEXP (XEXP (*x
, 0), 0, 0) == ref
)
5685 rtx addr
= gen_rtx_PLUS (Pmode
, XVECEXP (XEXP (*x
, 0), 0, 1), offset
);
5686 *x
= plus_constant (addr
, INTVAL (XEXP (*x
, 1)));
5690 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
5691 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
5695 replace_constant_pool_ref (&XEXP (*x
, i
), ref
, offset
);
5697 else if (fmt
[i
] == 'E')
5699 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
5700 replace_constant_pool_ref (&XVECEXP (*x
, i
, j
), ref
, offset
);
5705 /* Check whether X contains an UNSPEC_LTREL_BASE.
5706 Return its constant pool symbol if found, NULL_RTX otherwise. */
5709 find_ltrel_base (rtx x
)
5714 if (GET_CODE (x
) == UNSPEC
5715 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
5716 return XVECEXP (x
, 0, 0);
5718 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
5719 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
5723 rtx fnd
= find_ltrel_base (XEXP (x
, i
));
5727 else if (fmt
[i
] == 'E')
5729 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
5731 rtx fnd
= find_ltrel_base (XVECEXP (x
, i
, j
));
5741 /* Replace any occurrence of UNSPEC_LTREL_BASE in X with its base. */
5744 replace_ltrel_base (rtx
*x
)
5749 if (GET_CODE (*x
) == UNSPEC
5750 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
5752 *x
= XVECEXP (*x
, 0, 1);
5756 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
5757 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
5761 replace_ltrel_base (&XEXP (*x
, i
));
5763 else if (fmt
[i
] == 'E')
5765 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
5766 replace_ltrel_base (&XVECEXP (*x
, i
, j
));
5772 /* We keep a list of constants which we have to add to internal
5773 constant tables in the middle of large functions. */
5775 #define NR_C_MODES 11
5776 enum machine_mode constant_modes
[NR_C_MODES
] =
5778 TFmode
, TImode
, TDmode
,
5779 DFmode
, DImode
, DDmode
,
5780 SFmode
, SImode
, SDmode
,
5787 struct constant
*next
;
5792 struct constant_pool
5794 struct constant_pool
*next
;
5798 rtx emit_pool_after
;
5800 struct constant
*constants
[NR_C_MODES
];
5801 struct constant
*execute
;
5806 /* Allocate new constant_pool structure. */
5808 static struct constant_pool
*
5809 s390_alloc_pool (void)
5811 struct constant_pool
*pool
;
5814 pool
= (struct constant_pool
*) xmalloc (sizeof *pool
);
5816 for (i
= 0; i
< NR_C_MODES
; i
++)
5817 pool
->constants
[i
] = NULL
;
5819 pool
->execute
= NULL
;
5820 pool
->label
= gen_label_rtx ();
5821 pool
->first_insn
= NULL_RTX
;
5822 pool
->pool_insn
= NULL_RTX
;
5823 pool
->insns
= BITMAP_ALLOC (NULL
);
5825 pool
->emit_pool_after
= NULL_RTX
;
5830 /* Create new constant pool covering instructions starting at INSN
5831 and chain it to the end of POOL_LIST. */
5833 static struct constant_pool
*
5834 s390_start_pool (struct constant_pool
**pool_list
, rtx insn
)
5836 struct constant_pool
*pool
, **prev
;
5838 pool
= s390_alloc_pool ();
5839 pool
->first_insn
= insn
;
5841 for (prev
= pool_list
; *prev
; prev
= &(*prev
)->next
)
5848 /* End range of instructions covered by POOL at INSN and emit
5849 placeholder insn representing the pool. */
5852 s390_end_pool (struct constant_pool
*pool
, rtx insn
)
5854 rtx pool_size
= GEN_INT (pool
->size
+ 8 /* alignment slop */);
5857 insn
= get_last_insn ();
5859 pool
->pool_insn
= emit_insn_after (gen_pool (pool_size
), insn
);
5860 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
5863 /* Add INSN to the list of insns covered by POOL. */
5866 s390_add_pool_insn (struct constant_pool
*pool
, rtx insn
)
5868 bitmap_set_bit (pool
->insns
, INSN_UID (insn
));
5871 /* Return pool out of POOL_LIST that covers INSN. */
5873 static struct constant_pool
*
5874 s390_find_pool (struct constant_pool
*pool_list
, rtx insn
)
5876 struct constant_pool
*pool
;
5878 for (pool
= pool_list
; pool
; pool
= pool
->next
)
5879 if (bitmap_bit_p (pool
->insns
, INSN_UID (insn
)))
5885 /* Add constant VAL of mode MODE to the constant pool POOL. */
5888 s390_add_constant (struct constant_pool
*pool
, rtx val
, enum machine_mode mode
)
5893 for (i
= 0; i
< NR_C_MODES
; i
++)
5894 if (constant_modes
[i
] == mode
)
5896 gcc_assert (i
!= NR_C_MODES
);
5898 for (c
= pool
->constants
[i
]; c
!= NULL
; c
= c
->next
)
5899 if (rtx_equal_p (val
, c
->value
))
5904 c
= (struct constant
*) xmalloc (sizeof *c
);
5906 c
->label
= gen_label_rtx ();
5907 c
->next
= pool
->constants
[i
];
5908 pool
->constants
[i
] = c
;
5909 pool
->size
+= GET_MODE_SIZE (mode
);
5913 /* Return an rtx that represents the offset of X from the start of
5917 s390_pool_offset (struct constant_pool
*pool
, rtx x
)
5921 label
= gen_rtx_LABEL_REF (GET_MODE (x
), pool
->label
);
5922 x
= gen_rtx_UNSPEC (GET_MODE (x
), gen_rtvec (2, x
, label
),
5923 UNSPEC_POOL_OFFSET
);
5924 return gen_rtx_CONST (GET_MODE (x
), x
);
5927 /* Find constant VAL of mode MODE in the constant pool POOL.
5928 Return an RTX describing the distance from the start of
5929 the pool to the location of the new constant. */
5932 s390_find_constant (struct constant_pool
*pool
, rtx val
,
5933 enum machine_mode mode
)
5938 for (i
= 0; i
< NR_C_MODES
; i
++)
5939 if (constant_modes
[i
] == mode
)
5941 gcc_assert (i
!= NR_C_MODES
);
5943 for (c
= pool
->constants
[i
]; c
!= NULL
; c
= c
->next
)
5944 if (rtx_equal_p (val
, c
->value
))
5949 return s390_pool_offset (pool
, gen_rtx_LABEL_REF (Pmode
, c
->label
));
5952 /* Check whether INSN is an execute. Return the label_ref to its
5953 execute target template if so, NULL_RTX otherwise. */
5956 s390_execute_label (rtx insn
)
5958 if (GET_CODE (insn
) == INSN
5959 && GET_CODE (PATTERN (insn
)) == PARALLEL
5960 && GET_CODE (XVECEXP (PATTERN (insn
), 0, 0)) == UNSPEC
5961 && XINT (XVECEXP (PATTERN (insn
), 0, 0), 1) == UNSPEC_EXECUTE
)
5962 return XVECEXP (XVECEXP (PATTERN (insn
), 0, 0), 0, 2);
5967 /* Add execute target for INSN to the constant pool POOL. */
5970 s390_add_execute (struct constant_pool
*pool
, rtx insn
)
5974 for (c
= pool
->execute
; c
!= NULL
; c
= c
->next
)
5975 if (INSN_UID (insn
) == INSN_UID (c
->value
))
5980 c
= (struct constant
*) xmalloc (sizeof *c
);
5982 c
->label
= gen_label_rtx ();
5983 c
->next
= pool
->execute
;
5989 /* Find execute target for INSN in the constant pool POOL.
5990 Return an RTX describing the distance from the start of
5991 the pool to the location of the execute target. */
5994 s390_find_execute (struct constant_pool
*pool
, rtx insn
)
5998 for (c
= pool
->execute
; c
!= NULL
; c
= c
->next
)
5999 if (INSN_UID (insn
) == INSN_UID (c
->value
))
6004 return s390_pool_offset (pool
, gen_rtx_LABEL_REF (Pmode
, c
->label
));
6007 /* For an execute INSN, extract the execute target template. */
6010 s390_execute_target (rtx insn
)
6012 rtx pattern
= PATTERN (insn
);
6013 gcc_assert (s390_execute_label (insn
));
6015 if (XVECLEN (pattern
, 0) == 2)
6017 pattern
= copy_rtx (XVECEXP (pattern
, 0, 1));
6021 rtvec vec
= rtvec_alloc (XVECLEN (pattern
, 0) - 1);
6024 for (i
= 0; i
< XVECLEN (pattern
, 0) - 1; i
++)
6025 RTVEC_ELT (vec
, i
) = copy_rtx (XVECEXP (pattern
, 0, i
+ 1));
6027 pattern
= gen_rtx_PARALLEL (VOIDmode
, vec
);
6033 /* Indicate that INSN cannot be duplicated. This is the case for
6034 execute insns that carry a unique label. */
6037 s390_cannot_copy_insn_p (rtx insn
)
6039 rtx label
= s390_execute_label (insn
);
6040 return label
&& label
!= const0_rtx
;
6043 /* Dump out the constants in POOL. If REMOTE_LABEL is true,
6044 do not emit the pool base label. */
6047 s390_dump_pool (struct constant_pool
*pool
, bool remote_label
)
6050 rtx insn
= pool
->pool_insn
;
6053 /* Switch to rodata section. */
6054 if (TARGET_CPU_ZARCH
)
6056 insn
= emit_insn_after (gen_pool_section_start (), insn
);
6057 INSN_ADDRESSES_NEW (insn
, -1);
6060 /* Ensure minimum pool alignment. */
6061 if (TARGET_CPU_ZARCH
)
6062 insn
= emit_insn_after (gen_pool_align (GEN_INT (8)), insn
);
6064 insn
= emit_insn_after (gen_pool_align (GEN_INT (4)), insn
);
6065 INSN_ADDRESSES_NEW (insn
, -1);
6067 /* Emit pool base label. */
6070 insn
= emit_label_after (pool
->label
, insn
);
6071 INSN_ADDRESSES_NEW (insn
, -1);
6074 /* Dump constants in descending alignment requirement order,
6075 ensuring proper alignment for every constant. */
6076 for (i
= 0; i
< NR_C_MODES
; i
++)
6077 for (c
= pool
->constants
[i
]; c
; c
= c
->next
)
6079 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
6080 rtx value
= copy_rtx (c
->value
);
6081 if (GET_CODE (value
) == CONST
6082 && GET_CODE (XEXP (value
, 0)) == UNSPEC
6083 && XINT (XEXP (value
, 0), 1) == UNSPEC_LTREL_OFFSET
6084 && XVECLEN (XEXP (value
, 0), 0) == 1)
6085 value
= s390_pool_offset (pool
, XVECEXP (XEXP (value
, 0), 0, 0));
6087 insn
= emit_label_after (c
->label
, insn
);
6088 INSN_ADDRESSES_NEW (insn
, -1);
6090 value
= gen_rtx_UNSPEC_VOLATILE (constant_modes
[i
],
6091 gen_rtvec (1, value
),
6092 UNSPECV_POOL_ENTRY
);
6093 insn
= emit_insn_after (value
, insn
);
6094 INSN_ADDRESSES_NEW (insn
, -1);
6097 /* Ensure minimum alignment for instructions. */
6098 insn
= emit_insn_after (gen_pool_align (GEN_INT (2)), insn
);
6099 INSN_ADDRESSES_NEW (insn
, -1);
6101 /* Output in-pool execute template insns. */
6102 for (c
= pool
->execute
; c
; c
= c
->next
)
6104 insn
= emit_label_after (c
->label
, insn
);
6105 INSN_ADDRESSES_NEW (insn
, -1);
6107 insn
= emit_insn_after (s390_execute_target (c
->value
), insn
);
6108 INSN_ADDRESSES_NEW (insn
, -1);
6111 /* Switch back to previous section. */
6112 if (TARGET_CPU_ZARCH
)
6114 insn
= emit_insn_after (gen_pool_section_end (), insn
);
6115 INSN_ADDRESSES_NEW (insn
, -1);
6118 insn
= emit_barrier_after (insn
);
6119 INSN_ADDRESSES_NEW (insn
, -1);
6121 /* Remove placeholder insn. */
6122 remove_insn (pool
->pool_insn
);
6125 /* Free all memory used by POOL. */
6128 s390_free_pool (struct constant_pool
*pool
)
6130 struct constant
*c
, *next
;
6133 for (i
= 0; i
< NR_C_MODES
; i
++)
6134 for (c
= pool
->constants
[i
]; c
; c
= next
)
6140 for (c
= pool
->execute
; c
; c
= next
)
6146 BITMAP_FREE (pool
->insns
);
6151 /* Collect main literal pool. Return NULL on overflow. */
6153 static struct constant_pool
*
6154 s390_mainpool_start (void)
6156 struct constant_pool
*pool
;
6159 pool
= s390_alloc_pool ();
6161 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6163 if (GET_CODE (insn
) == INSN
6164 && GET_CODE (PATTERN (insn
)) == SET
6165 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC_VOLATILE
6166 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPECV_MAIN_POOL
)
6168 gcc_assert (!pool
->pool_insn
);
6169 pool
->pool_insn
= insn
;
6172 if (!TARGET_CPU_ZARCH
&& s390_execute_label (insn
))
6174 s390_add_execute (pool
, insn
);
6176 else if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
6178 rtx pool_ref
= NULL_RTX
;
6179 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
6182 rtx constant
= get_pool_constant (pool_ref
);
6183 enum machine_mode mode
= get_pool_mode (pool_ref
);
6184 s390_add_constant (pool
, constant
, mode
);
6188 /* If hot/cold partitioning is enabled we have to make sure that
6189 the literal pool is emitted in the same section where the
6190 initialization of the literal pool base pointer takes place.
6191 emit_pool_after is only used in the non-overflow case on non
6192 Z cpus where we can emit the literal pool at the end of the
6193 function body within the text section. */
6195 && NOTE_KIND (insn
) == NOTE_INSN_SWITCH_TEXT_SECTIONS
6196 && !pool
->emit_pool_after
)
6197 pool
->emit_pool_after
= PREV_INSN (insn
);
6200 gcc_assert (pool
->pool_insn
|| pool
->size
== 0);
6202 if (pool
->size
>= 4096)
6204 /* We're going to chunkify the pool, so remove the main
6205 pool placeholder insn. */
6206 remove_insn (pool
->pool_insn
);
6208 s390_free_pool (pool
);
6212 /* If the functions ends with the section where the literal pool
6213 should be emitted set the marker to its end. */
6214 if (pool
&& !pool
->emit_pool_after
)
6215 pool
->emit_pool_after
= get_last_insn ();
6220 /* POOL holds the main literal pool as collected by s390_mainpool_start.
6221 Modify the current function to output the pool constants as well as
6222 the pool register setup instruction. */
6225 s390_mainpool_finish (struct constant_pool
*pool
)
6227 rtx base_reg
= cfun
->machine
->base_reg
;
6230 /* If the pool is empty, we're done. */
6231 if (pool
->size
== 0)
6233 /* We don't actually need a base register after all. */
6234 cfun
->machine
->base_reg
= NULL_RTX
;
6236 if (pool
->pool_insn
)
6237 remove_insn (pool
->pool_insn
);
6238 s390_free_pool (pool
);
6242 /* We need correct insn addresses. */
6243 shorten_branches (get_insns ());
6245 /* On zSeries, we use a LARL to load the pool register. The pool is
6246 located in the .rodata section, so we emit it after the function. */
6247 if (TARGET_CPU_ZARCH
)
6249 insn
= gen_main_base_64 (base_reg
, pool
->label
);
6250 insn
= emit_insn_after (insn
, pool
->pool_insn
);
6251 INSN_ADDRESSES_NEW (insn
, -1);
6252 remove_insn (pool
->pool_insn
);
6254 insn
= get_last_insn ();
6255 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
6256 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
6258 s390_dump_pool (pool
, 0);
6261 /* On S/390, if the total size of the function's code plus literal pool
6262 does not exceed 4096 bytes, we use BASR to set up a function base
6263 pointer, and emit the literal pool at the end of the function. */
6264 else if (INSN_ADDRESSES (INSN_UID (pool
->emit_pool_after
))
6265 + pool
->size
+ 8 /* alignment slop */ < 4096)
6267 insn
= gen_main_base_31_small (base_reg
, pool
->label
);
6268 insn
= emit_insn_after (insn
, pool
->pool_insn
);
6269 INSN_ADDRESSES_NEW (insn
, -1);
6270 remove_insn (pool
->pool_insn
);
6272 insn
= emit_label_after (pool
->label
, insn
);
6273 INSN_ADDRESSES_NEW (insn
, -1);
6275 /* emit_pool_after will be set by s390_mainpool_start to the
6276 last insn of the section where the literal pool should be
6278 insn
= pool
->emit_pool_after
;
6280 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
6281 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
6283 s390_dump_pool (pool
, 1);
6286 /* Otherwise, we emit an inline literal pool and use BASR to branch
6287 over it, setting up the pool register at the same time. */
6290 rtx pool_end
= gen_label_rtx ();
6292 insn
= gen_main_base_31_large (base_reg
, pool
->label
, pool_end
);
6293 insn
= emit_insn_after (insn
, pool
->pool_insn
);
6294 INSN_ADDRESSES_NEW (insn
, -1);
6295 remove_insn (pool
->pool_insn
);
6297 insn
= emit_label_after (pool
->label
, insn
);
6298 INSN_ADDRESSES_NEW (insn
, -1);
6300 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
6301 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
6303 insn
= emit_label_after (pool_end
, pool
->pool_insn
);
6304 INSN_ADDRESSES_NEW (insn
, -1);
6306 s390_dump_pool (pool
, 1);
6310 /* Replace all literal pool references. */
6312 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6315 replace_ltrel_base (&PATTERN (insn
));
6317 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
6319 rtx addr
, pool_ref
= NULL_RTX
;
6320 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
6323 if (s390_execute_label (insn
))
6324 addr
= s390_find_execute (pool
, insn
);
6326 addr
= s390_find_constant (pool
, get_pool_constant (pool_ref
),
6327 get_pool_mode (pool_ref
));
6329 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
6330 INSN_CODE (insn
) = -1;
6336 /* Free the pool. */
6337 s390_free_pool (pool
);
6340 /* POOL holds the main literal pool as collected by s390_mainpool_start.
6341 We have decided we cannot use this pool, so revert all changes
6342 to the current function that were done by s390_mainpool_start. */
6344 s390_mainpool_cancel (struct constant_pool
*pool
)
6346 /* We didn't actually change the instruction stream, so simply
6347 free the pool memory. */
6348 s390_free_pool (pool
);
6352 /* Chunkify the literal pool. */
6354 #define S390_POOL_CHUNK_MIN 0xc00
6355 #define S390_POOL_CHUNK_MAX 0xe00
6357 static struct constant_pool
*
6358 s390_chunkify_start (void)
6360 struct constant_pool
*curr_pool
= NULL
, *pool_list
= NULL
;
6363 rtx pending_ltrel
= NULL_RTX
;
6366 rtx (*gen_reload_base
) (rtx
, rtx
) =
6367 TARGET_CPU_ZARCH
? gen_reload_base_64
: gen_reload_base_31
;
6370 /* We need correct insn addresses. */
6372 shorten_branches (get_insns ());
6374 /* Scan all insns and move literals to pool chunks. */
6376 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6378 bool section_switch_p
= false;
6380 /* Check for pending LTREL_BASE. */
6383 rtx ltrel_base
= find_ltrel_base (PATTERN (insn
));
6386 gcc_assert (ltrel_base
== pending_ltrel
);
6387 pending_ltrel
= NULL_RTX
;
6391 if (!TARGET_CPU_ZARCH
&& s390_execute_label (insn
))
6394 curr_pool
= s390_start_pool (&pool_list
, insn
);
6396 s390_add_execute (curr_pool
, insn
);
6397 s390_add_pool_insn (curr_pool
, insn
);
6399 else if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
6401 rtx pool_ref
= NULL_RTX
;
6402 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
6405 rtx constant
= get_pool_constant (pool_ref
);
6406 enum machine_mode mode
= get_pool_mode (pool_ref
);
6409 curr_pool
= s390_start_pool (&pool_list
, insn
);
6411 s390_add_constant (curr_pool
, constant
, mode
);
6412 s390_add_pool_insn (curr_pool
, insn
);
6414 /* Don't split the pool chunk between a LTREL_OFFSET load
6415 and the corresponding LTREL_BASE. */
6416 if (GET_CODE (constant
) == CONST
6417 && GET_CODE (XEXP (constant
, 0)) == UNSPEC
6418 && XINT (XEXP (constant
, 0), 1) == UNSPEC_LTREL_OFFSET
)
6420 gcc_assert (!pending_ltrel
);
6421 pending_ltrel
= pool_ref
;
6426 if (GET_CODE (insn
) == JUMP_INSN
|| GET_CODE (insn
) == CODE_LABEL
)
6429 s390_add_pool_insn (curr_pool
, insn
);
6430 /* An LTREL_BASE must follow within the same basic block. */
6431 gcc_assert (!pending_ltrel
);
6434 if (NOTE_P (insn
) && NOTE_KIND (insn
) == NOTE_INSN_SWITCH_TEXT_SECTIONS
)
6435 section_switch_p
= true;
6438 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn
)
6439 || INSN_ADDRESSES (INSN_UID (insn
)) == -1)
6442 if (TARGET_CPU_ZARCH
)
6444 if (curr_pool
->size
< S390_POOL_CHUNK_MAX
)
6447 s390_end_pool (curr_pool
, NULL_RTX
);
6452 int chunk_size
= INSN_ADDRESSES (INSN_UID (insn
))
6453 - INSN_ADDRESSES (INSN_UID (curr_pool
->first_insn
))
6456 /* We will later have to insert base register reload insns.
6457 Those will have an effect on code size, which we need to
6458 consider here. This calculation makes rather pessimistic
6459 worst-case assumptions. */
6460 if (GET_CODE (insn
) == CODE_LABEL
)
6463 if (chunk_size
< S390_POOL_CHUNK_MIN
6464 && curr_pool
->size
< S390_POOL_CHUNK_MIN
6465 && !section_switch_p
)
6468 /* Pool chunks can only be inserted after BARRIERs ... */
6469 if (GET_CODE (insn
) == BARRIER
)
6471 s390_end_pool (curr_pool
, insn
);
6476 /* ... so if we don't find one in time, create one. */
6477 else if (chunk_size
> S390_POOL_CHUNK_MAX
6478 || curr_pool
->size
> S390_POOL_CHUNK_MAX
6479 || section_switch_p
)
6481 rtx label
, jump
, barrier
;
6483 if (!section_switch_p
)
6485 /* We can insert the barrier only after a 'real' insn. */
6486 if (GET_CODE (insn
) != INSN
&& GET_CODE (insn
) != CALL_INSN
)
6488 if (get_attr_length (insn
) == 0)
6490 /* Don't separate LTREL_BASE from the corresponding
6491 LTREL_OFFSET load. */
6497 gcc_assert (!pending_ltrel
);
6499 /* The old pool has to end before the section switch
6500 note in order to make it part of the current
6502 insn
= PREV_INSN (insn
);
6505 label
= gen_label_rtx ();
6506 jump
= emit_jump_insn_after (gen_jump (label
), insn
);
6507 barrier
= emit_barrier_after (jump
);
6508 insn
= emit_label_after (label
, barrier
);
6509 JUMP_LABEL (jump
) = label
;
6510 LABEL_NUSES (label
) = 1;
6512 INSN_ADDRESSES_NEW (jump
, -1);
6513 INSN_ADDRESSES_NEW (barrier
, -1);
6514 INSN_ADDRESSES_NEW (insn
, -1);
6516 s390_end_pool (curr_pool
, barrier
);
6524 s390_end_pool (curr_pool
, NULL_RTX
);
6525 gcc_assert (!pending_ltrel
);
6527 /* Find all labels that are branched into
6528 from an insn belonging to a different chunk. */
6530 far_labels
= BITMAP_ALLOC (NULL
);
6532 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6534 /* Labels marked with LABEL_PRESERVE_P can be target
6535 of non-local jumps, so we have to mark them.
6536 The same holds for named labels.
6538 Don't do that, however, if it is the label before
6541 if (GET_CODE (insn
) == CODE_LABEL
6542 && (LABEL_PRESERVE_P (insn
) || LABEL_NAME (insn
)))
6544 rtx vec_insn
= next_real_insn (insn
);
6545 rtx vec_pat
= vec_insn
&& GET_CODE (vec_insn
) == JUMP_INSN
?
6546 PATTERN (vec_insn
) : NULL_RTX
;
6548 || !(GET_CODE (vec_pat
) == ADDR_VEC
6549 || GET_CODE (vec_pat
) == ADDR_DIFF_VEC
))
6550 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (insn
));
6553 /* If we have a direct jump (conditional or unconditional)
6554 or a casesi jump, check all potential targets. */
6555 else if (GET_CODE (insn
) == JUMP_INSN
)
6557 rtx pat
= PATTERN (insn
);
6558 if (GET_CODE (pat
) == PARALLEL
&& XVECLEN (pat
, 0) > 2)
6559 pat
= XVECEXP (pat
, 0, 0);
6561 if (GET_CODE (pat
) == SET
)
6563 rtx label
= JUMP_LABEL (insn
);
6566 if (s390_find_pool (pool_list
, label
)
6567 != s390_find_pool (pool_list
, insn
))
6568 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
6571 else if (GET_CODE (pat
) == PARALLEL
6572 && XVECLEN (pat
, 0) == 2
6573 && GET_CODE (XVECEXP (pat
, 0, 0)) == SET
6574 && GET_CODE (XVECEXP (pat
, 0, 1)) == USE
6575 && GET_CODE (XEXP (XVECEXP (pat
, 0, 1), 0)) == LABEL_REF
)
6577 /* Find the jump table used by this casesi jump. */
6578 rtx vec_label
= XEXP (XEXP (XVECEXP (pat
, 0, 1), 0), 0);
6579 rtx vec_insn
= next_real_insn (vec_label
);
6580 rtx vec_pat
= vec_insn
&& GET_CODE (vec_insn
) == JUMP_INSN
?
6581 PATTERN (vec_insn
) : NULL_RTX
;
6583 && (GET_CODE (vec_pat
) == ADDR_VEC
6584 || GET_CODE (vec_pat
) == ADDR_DIFF_VEC
))
6586 int i
, diff_p
= GET_CODE (vec_pat
) == ADDR_DIFF_VEC
;
6588 for (i
= 0; i
< XVECLEN (vec_pat
, diff_p
); i
++)
6590 rtx label
= XEXP (XVECEXP (vec_pat
, diff_p
, i
), 0);
6592 if (s390_find_pool (pool_list
, label
)
6593 != s390_find_pool (pool_list
, insn
))
6594 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
6601 /* Insert base register reload insns before every pool. */
6603 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
6605 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
6607 rtx insn
= curr_pool
->first_insn
;
6608 INSN_ADDRESSES_NEW (emit_insn_before (new_insn
, insn
), -1);
6611 /* Insert base register reload insns at every far label. */
6613 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6614 if (GET_CODE (insn
) == CODE_LABEL
6615 && bitmap_bit_p (far_labels
, CODE_LABEL_NUMBER (insn
)))
6617 struct constant_pool
*pool
= s390_find_pool (pool_list
, insn
);
6620 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
6622 INSN_ADDRESSES_NEW (emit_insn_after (new_insn
, insn
), -1);
6627 BITMAP_FREE (far_labels
);
6630 /* Recompute insn addresses. */
6632 init_insn_lengths ();
6633 shorten_branches (get_insns ());
6638 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
6639 After we have decided to use this list, finish implementing
6640 all changes to the current function as required. */
6643 s390_chunkify_finish (struct constant_pool
*pool_list
)
6645 struct constant_pool
*curr_pool
= NULL
;
6649 /* Replace all literal pool references. */
6651 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6654 replace_ltrel_base (&PATTERN (insn
));
6656 curr_pool
= s390_find_pool (pool_list
, insn
);
6660 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
6662 rtx addr
, pool_ref
= NULL_RTX
;
6663 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
6666 if (s390_execute_label (insn
))
6667 addr
= s390_find_execute (curr_pool
, insn
);
6669 addr
= s390_find_constant (curr_pool
,
6670 get_pool_constant (pool_ref
),
6671 get_pool_mode (pool_ref
));
6673 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
6674 INSN_CODE (insn
) = -1;
6679 /* Dump out all literal pools. */
6681 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
6682 s390_dump_pool (curr_pool
, 0);
6684 /* Free pool list. */
6688 struct constant_pool
*next
= pool_list
->next
;
6689 s390_free_pool (pool_list
);
6694 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
6695 We have decided we cannot use this list, so revert all changes
6696 to the current function that were done by s390_chunkify_start. */
6699 s390_chunkify_cancel (struct constant_pool
*pool_list
)
6701 struct constant_pool
*curr_pool
= NULL
;
6704 /* Remove all pool placeholder insns. */
6706 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
6708 /* Did we insert an extra barrier? Remove it. */
6709 rtx barrier
= PREV_INSN (curr_pool
->pool_insn
);
6710 rtx jump
= barrier
? PREV_INSN (barrier
) : NULL_RTX
;
6711 rtx label
= NEXT_INSN (curr_pool
->pool_insn
);
6713 if (jump
&& GET_CODE (jump
) == JUMP_INSN
6714 && barrier
&& GET_CODE (barrier
) == BARRIER
6715 && label
&& GET_CODE (label
) == CODE_LABEL
6716 && GET_CODE (PATTERN (jump
)) == SET
6717 && SET_DEST (PATTERN (jump
)) == pc_rtx
6718 && GET_CODE (SET_SRC (PATTERN (jump
))) == LABEL_REF
6719 && XEXP (SET_SRC (PATTERN (jump
)), 0) == label
)
6722 remove_insn (barrier
);
6723 remove_insn (label
);
6726 remove_insn (curr_pool
->pool_insn
);
6729 /* Remove all base register reload insns. */
6731 for (insn
= get_insns (); insn
; )
6733 rtx next_insn
= NEXT_INSN (insn
);
6735 if (GET_CODE (insn
) == INSN
6736 && GET_CODE (PATTERN (insn
)) == SET
6737 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC
6738 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPEC_RELOAD_BASE
)
6744 /* Free pool list. */
6748 struct constant_pool
*next
= pool_list
->next
;
6749 s390_free_pool (pool_list
);
6754 /* Output the constant pool entry EXP in mode MODE with alignment ALIGN. */
6757 s390_output_pool_entry (rtx exp
, enum machine_mode mode
, unsigned int align
)
6761 switch (GET_MODE_CLASS (mode
))
6764 case MODE_DECIMAL_FLOAT
:
6765 gcc_assert (GET_CODE (exp
) == CONST_DOUBLE
);
6767 REAL_VALUE_FROM_CONST_DOUBLE (r
, exp
);
6768 assemble_real (r
, mode
, align
);
6772 assemble_integer (exp
, GET_MODE_SIZE (mode
), align
, 1);
6773 mark_symbol_refs_as_used (exp
);
6782 /* Return an RTL expression representing the value of the return address
6783 for the frame COUNT steps up from the current frame. FRAME is the
6784 frame pointer of that frame. */
6787 s390_return_addr_rtx (int count
, rtx frame ATTRIBUTE_UNUSED
)
6792 /* Without backchain, we fail for all but the current frame. */
6794 if (!TARGET_BACKCHAIN
&& count
> 0)
6797 /* For the current frame, we need to make sure the initial
6798 value of RETURN_REGNUM is actually saved. */
6802 /* On non-z architectures branch splitting could overwrite r14. */
6803 if (TARGET_CPU_ZARCH
)
6804 return get_hard_reg_initial_val (Pmode
, RETURN_REGNUM
);
6807 cfun_frame_layout
.save_return_addr_p
= true;
6808 return gen_rtx_MEM (Pmode
, return_address_pointer_rtx
);
6812 if (TARGET_PACKED_STACK
)
6813 offset
= -2 * UNITS_PER_WORD
;
6815 offset
= RETURN_REGNUM
* UNITS_PER_WORD
;
6817 addr
= plus_constant (frame
, offset
);
6818 addr
= memory_address (Pmode
, addr
);
6819 return gen_rtx_MEM (Pmode
, addr
);
6822 /* Return an RTL expression representing the back chain stored in
6823 the current stack frame. */
6826 s390_back_chain_rtx (void)
6830 gcc_assert (TARGET_BACKCHAIN
);
6832 if (TARGET_PACKED_STACK
)
6833 chain
= plus_constant (stack_pointer_rtx
,
6834 STACK_POINTER_OFFSET
- UNITS_PER_WORD
);
6836 chain
= stack_pointer_rtx
;
6838 chain
= gen_rtx_MEM (Pmode
, chain
);
6842 /* Find first call clobbered register unused in a function.
6843 This could be used as base register in a leaf function
6844 or for holding the return address before epilogue. */
6847 find_unused_clobbered_reg (void)
6850 for (i
= 0; i
< 6; i
++)
6851 if (!df_regs_ever_live_p (i
))
6857 /* Helper function for s390_regs_ever_clobbered. Sets the fields in DATA for all
6858 clobbered hard regs in SETREG. */
6861 s390_reg_clobbered_rtx (rtx setreg
, const_rtx set_insn ATTRIBUTE_UNUSED
, void *data
)
6863 int *regs_ever_clobbered
= (int *)data
;
6864 unsigned int i
, regno
;
6865 enum machine_mode mode
= GET_MODE (setreg
);
6867 if (GET_CODE (setreg
) == SUBREG
)
6869 rtx inner
= SUBREG_REG (setreg
);
6870 if (!GENERAL_REG_P (inner
))
6872 regno
= subreg_regno (setreg
);
6874 else if (GENERAL_REG_P (setreg
))
6875 regno
= REGNO (setreg
);
6880 i
< regno
+ HARD_REGNO_NREGS (regno
, mode
);
6882 regs_ever_clobbered
[i
] = 1;
6885 /* Walks through all basic blocks of the current function looking
6886 for clobbered hard regs using s390_reg_clobbered_rtx. The fields
6887 of the passed integer array REGS_EVER_CLOBBERED are set to one for
6888 each of those regs. */
6891 s390_regs_ever_clobbered (int *regs_ever_clobbered
)
6897 memset (regs_ever_clobbered
, 0, 16 * sizeof (int));
6899 /* For non-leaf functions we have to consider all call clobbered regs to be
6901 if (!current_function_is_leaf
)
6903 for (i
= 0; i
< 16; i
++)
6904 regs_ever_clobbered
[i
] = call_really_used_regs
[i
];
6907 /* Make the "magic" eh_return registers live if necessary. For regs_ever_live
6908 this work is done by liveness analysis (mark_regs_live_at_end).
6909 Special care is needed for functions containing landing pads. Landing pads
6910 may use the eh registers, but the code which sets these registers is not
6911 contained in that function. Hence s390_regs_ever_clobbered is not able to
6912 deal with this automatically. */
6913 if (crtl
->calls_eh_return
|| cfun
->machine
->has_landing_pad_p
)
6914 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; i
++)
6915 if (crtl
->calls_eh_return
6916 || (cfun
->machine
->has_landing_pad_p
6917 && df_regs_ever_live_p (EH_RETURN_DATA_REGNO (i
))))
6918 regs_ever_clobbered
[EH_RETURN_DATA_REGNO (i
)] = 1;
6920 /* For nonlocal gotos all call-saved registers have to be saved.
6921 This flag is also set for the unwinding code in libgcc.
6922 See expand_builtin_unwind_init. For regs_ever_live this is done by
6924 if (cfun
->has_nonlocal_label
)
6925 for (i
= 0; i
< 16; i
++)
6926 if (!call_really_used_regs
[i
])
6927 regs_ever_clobbered
[i
] = 1;
6929 FOR_EACH_BB (cur_bb
)
6931 FOR_BB_INSNS (cur_bb
, cur_insn
)
6933 if (INSN_P (cur_insn
))
6934 note_stores (PATTERN (cur_insn
),
6935 s390_reg_clobbered_rtx
,
6936 regs_ever_clobbered
);
6941 /* Determine the frame area which actually has to be accessed
6942 in the function epilogue. The values are stored at the
6943 given pointers AREA_BOTTOM (address of the lowest used stack
6944 address) and AREA_TOP (address of the first item which does
6945 not belong to the stack frame). */
6948 s390_frame_area (int *area_bottom
, int *area_top
)
6956 if (cfun_frame_layout
.first_restore_gpr
!= -1)
6958 b
= (cfun_frame_layout
.gprs_offset
6959 + cfun_frame_layout
.first_restore_gpr
* UNITS_PER_WORD
);
6960 t
= b
+ (cfun_frame_layout
.last_restore_gpr
6961 - cfun_frame_layout
.first_restore_gpr
+ 1) * UNITS_PER_WORD
;
6964 if (TARGET_64BIT
&& cfun_save_high_fprs_p
)
6966 b
= MIN (b
, cfun_frame_layout
.f8_offset
);
6967 t
= MAX (t
, (cfun_frame_layout
.f8_offset
6968 + cfun_frame_layout
.high_fprs
* 8));
6972 for (i
= 2; i
< 4; i
++)
6973 if (cfun_fpr_bit_p (i
))
6975 b
= MIN (b
, cfun_frame_layout
.f4_offset
+ (i
- 2) * 8);
6976 t
= MAX (t
, cfun_frame_layout
.f4_offset
+ (i
- 1) * 8);
6983 /* Fill cfun->machine with info about register usage of current function.
6984 Return in CLOBBERED_REGS which GPRs are currently considered set. */
6987 s390_register_info (int clobbered_regs
[])
6991 /* fprs 8 - 15 are call saved for 64 Bit ABI. */
6992 cfun_frame_layout
.fpr_bitmap
= 0;
6993 cfun_frame_layout
.high_fprs
= 0;
6995 for (i
= 24; i
< 32; i
++)
6996 if (df_regs_ever_live_p (i
) && !global_regs
[i
])
6998 cfun_set_fpr_bit (i
- 16);
6999 cfun_frame_layout
.high_fprs
++;
7002 /* Find first and last gpr to be saved. We trust regs_ever_live
7003 data, except that we don't save and restore global registers.
7005 Also, all registers with special meaning to the compiler need
7006 to be handled extra. */
7008 s390_regs_ever_clobbered (clobbered_regs
);
7010 for (i
= 0; i
< 16; i
++)
7011 clobbered_regs
[i
] = clobbered_regs
[i
] && !global_regs
[i
] && !fixed_regs
[i
];
7013 if (frame_pointer_needed
)
7014 clobbered_regs
[HARD_FRAME_POINTER_REGNUM
] = 1;
7017 clobbered_regs
[PIC_OFFSET_TABLE_REGNUM
]
7018 |= df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM
);
7020 clobbered_regs
[BASE_REGNUM
]
7021 |= (cfun
->machine
->base_reg
7022 && REGNO (cfun
->machine
->base_reg
) == BASE_REGNUM
);
7024 clobbered_regs
[RETURN_REGNUM
]
7025 |= (!current_function_is_leaf
7026 || TARGET_TPF_PROFILING
7027 || cfun
->machine
->split_branches_pending_p
7028 || cfun_frame_layout
.save_return_addr_p
7029 || crtl
->calls_eh_return
7032 clobbered_regs
[STACK_POINTER_REGNUM
]
7033 |= (!current_function_is_leaf
7034 || TARGET_TPF_PROFILING
7035 || cfun_save_high_fprs_p
7036 || get_frame_size () > 0
7037 || cfun
->calls_alloca
7040 for (i
= 6; i
< 16; i
++)
7041 if (df_regs_ever_live_p (i
) || clobbered_regs
[i
])
7043 for (j
= 15; j
> i
; j
--)
7044 if (df_regs_ever_live_p (j
) || clobbered_regs
[j
])
7049 /* Nothing to save/restore. */
7050 cfun_frame_layout
.first_save_gpr_slot
= -1;
7051 cfun_frame_layout
.last_save_gpr_slot
= -1;
7052 cfun_frame_layout
.first_save_gpr
= -1;
7053 cfun_frame_layout
.first_restore_gpr
= -1;
7054 cfun_frame_layout
.last_save_gpr
= -1;
7055 cfun_frame_layout
.last_restore_gpr
= -1;
7059 /* Save slots for gprs from i to j. */
7060 cfun_frame_layout
.first_save_gpr_slot
= i
;
7061 cfun_frame_layout
.last_save_gpr_slot
= j
;
7063 for (i
= cfun_frame_layout
.first_save_gpr_slot
;
7064 i
< cfun_frame_layout
.last_save_gpr_slot
+ 1;
7066 if (clobbered_regs
[i
])
7069 for (j
= cfun_frame_layout
.last_save_gpr_slot
; j
> i
; j
--)
7070 if (clobbered_regs
[j
])
7073 if (i
== cfun_frame_layout
.last_save_gpr_slot
+ 1)
7075 /* Nothing to save/restore. */
7076 cfun_frame_layout
.first_save_gpr
= -1;
7077 cfun_frame_layout
.first_restore_gpr
= -1;
7078 cfun_frame_layout
.last_save_gpr
= -1;
7079 cfun_frame_layout
.last_restore_gpr
= -1;
7083 /* Save / Restore from gpr i to j. */
7084 cfun_frame_layout
.first_save_gpr
= i
;
7085 cfun_frame_layout
.first_restore_gpr
= i
;
7086 cfun_frame_layout
.last_save_gpr
= j
;
7087 cfun_frame_layout
.last_restore_gpr
= j
;
7093 /* Varargs functions need to save gprs 2 to 6. */
7094 if (cfun
->va_list_gpr_size
7095 && crtl
->args
.info
.gprs
< GP_ARG_NUM_REG
)
7097 int min_gpr
= crtl
->args
.info
.gprs
;
7098 int max_gpr
= min_gpr
+ cfun
->va_list_gpr_size
;
7099 if (max_gpr
> GP_ARG_NUM_REG
)
7100 max_gpr
= GP_ARG_NUM_REG
;
7102 if (cfun_frame_layout
.first_save_gpr
== -1
7103 || cfun_frame_layout
.first_save_gpr
> 2 + min_gpr
)
7105 cfun_frame_layout
.first_save_gpr
= 2 + min_gpr
;
7106 cfun_frame_layout
.first_save_gpr_slot
= 2 + min_gpr
;
7109 if (cfun_frame_layout
.last_save_gpr
== -1
7110 || cfun_frame_layout
.last_save_gpr
< 2 + max_gpr
- 1)
7112 cfun_frame_layout
.last_save_gpr
= 2 + max_gpr
- 1;
7113 cfun_frame_layout
.last_save_gpr_slot
= 2 + max_gpr
- 1;
7117 /* Mark f0, f2 for 31 bit and f0-f4 for 64 bit to be saved. */
7118 if (TARGET_HARD_FLOAT
&& cfun
->va_list_fpr_size
7119 && crtl
->args
.info
.fprs
< FP_ARG_NUM_REG
)
7121 int min_fpr
= crtl
->args
.info
.fprs
;
7122 int max_fpr
= min_fpr
+ cfun
->va_list_fpr_size
;
7123 if (max_fpr
> FP_ARG_NUM_REG
)
7124 max_fpr
= FP_ARG_NUM_REG
;
7126 /* ??? This is currently required to ensure proper location
7127 of the fpr save slots within the va_list save area. */
7128 if (TARGET_PACKED_STACK
)
7131 for (i
= min_fpr
; i
< max_fpr
; i
++)
7132 cfun_set_fpr_bit (i
);
7137 for (i
= 2; i
< 4; i
++)
7138 if (df_regs_ever_live_p (i
+ 16) && !global_regs
[i
+ 16])
7139 cfun_set_fpr_bit (i
);
7142 /* Fill cfun->machine with info about frame of current function. */
7145 s390_frame_info (void)
7149 cfun_frame_layout
.frame_size
= get_frame_size ();
7150 if (!TARGET_64BIT
&& cfun_frame_layout
.frame_size
> 0x7fff0000)
7151 fatal_error ("total size of local variables exceeds architecture limit");
7153 if (!TARGET_PACKED_STACK
)
7155 cfun_frame_layout
.backchain_offset
= 0;
7156 cfun_frame_layout
.f0_offset
= 16 * UNITS_PER_WORD
;
7157 cfun_frame_layout
.f4_offset
= cfun_frame_layout
.f0_offset
+ 2 * 8;
7158 cfun_frame_layout
.f8_offset
= -cfun_frame_layout
.high_fprs
* 8;
7159 cfun_frame_layout
.gprs_offset
= (cfun_frame_layout
.first_save_gpr_slot
7162 else if (TARGET_BACKCHAIN
) /* kernel stack layout */
7164 cfun_frame_layout
.backchain_offset
= (STACK_POINTER_OFFSET
7166 cfun_frame_layout
.gprs_offset
7167 = (cfun_frame_layout
.backchain_offset
7168 - (STACK_POINTER_REGNUM
- cfun_frame_layout
.first_save_gpr_slot
+ 1)
7173 cfun_frame_layout
.f4_offset
7174 = (cfun_frame_layout
.gprs_offset
7175 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
7177 cfun_frame_layout
.f0_offset
7178 = (cfun_frame_layout
.f4_offset
7179 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
7183 /* On 31 bit we have to care about alignment of the
7184 floating point regs to provide fastest access. */
7185 cfun_frame_layout
.f0_offset
7186 = ((cfun_frame_layout
.gprs_offset
7187 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1))
7188 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
7190 cfun_frame_layout
.f4_offset
7191 = (cfun_frame_layout
.f0_offset
7192 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
7195 else /* no backchain */
7197 cfun_frame_layout
.f4_offset
7198 = (STACK_POINTER_OFFSET
7199 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
7201 cfun_frame_layout
.f0_offset
7202 = (cfun_frame_layout
.f4_offset
7203 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
7205 cfun_frame_layout
.gprs_offset
7206 = cfun_frame_layout
.f0_offset
- cfun_gprs_save_area_size
;
7209 if (current_function_is_leaf
7210 && !TARGET_TPF_PROFILING
7211 && cfun_frame_layout
.frame_size
== 0
7212 && !cfun_save_high_fprs_p
7213 && !cfun
->calls_alloca
7217 if (!TARGET_PACKED_STACK
)
7218 cfun_frame_layout
.frame_size
+= (STACK_POINTER_OFFSET
7219 + crtl
->outgoing_args_size
7220 + cfun_frame_layout
.high_fprs
* 8);
7223 if (TARGET_BACKCHAIN
)
7224 cfun_frame_layout
.frame_size
+= UNITS_PER_WORD
;
7226 /* No alignment trouble here because f8-f15 are only saved under
7228 cfun_frame_layout
.f8_offset
= (MIN (MIN (cfun_frame_layout
.f0_offset
,
7229 cfun_frame_layout
.f4_offset
),
7230 cfun_frame_layout
.gprs_offset
)
7231 - cfun_frame_layout
.high_fprs
* 8);
7233 cfun_frame_layout
.frame_size
+= cfun_frame_layout
.high_fprs
* 8;
7235 for (i
= 0; i
< 8; i
++)
7236 if (cfun_fpr_bit_p (i
))
7237 cfun_frame_layout
.frame_size
+= 8;
7239 cfun_frame_layout
.frame_size
+= cfun_gprs_save_area_size
;
7241 /* If under 31 bit an odd number of gprs has to be saved we have to adjust
7242 the frame size to sustain 8 byte alignment of stack frames. */
7243 cfun_frame_layout
.frame_size
= ((cfun_frame_layout
.frame_size
+
7244 STACK_BOUNDARY
/ BITS_PER_UNIT
- 1)
7245 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1));
7247 cfun_frame_layout
.frame_size
+= crtl
->outgoing_args_size
;
7251 /* Generate frame layout. Fills in register and frame data for the current
7252 function in cfun->machine. This routine can be called multiple times;
7253 it will re-do the complete frame layout every time. */
7256 s390_init_frame_layout (void)
7258 HOST_WIDE_INT frame_size
;
7260 int clobbered_regs
[16];
7262 /* On S/390 machines, we may need to perform branch splitting, which
7263 will require both base and return address register. We have no
7264 choice but to assume we're going to need them until right at the
7265 end of the machine dependent reorg phase. */
7266 if (!TARGET_CPU_ZARCH
)
7267 cfun
->machine
->split_branches_pending_p
= true;
7271 frame_size
= cfun_frame_layout
.frame_size
;
7273 /* Try to predict whether we'll need the base register. */
7274 base_used
= cfun
->machine
->split_branches_pending_p
7275 || crtl
->uses_const_pool
7276 || (!DISP_IN_RANGE (frame_size
)
7277 && !CONST_OK_FOR_K (frame_size
));
7279 /* Decide which register to use as literal pool base. In small
7280 leaf functions, try to use an unused call-clobbered register
7281 as base register to avoid save/restore overhead. */
7283 cfun
->machine
->base_reg
= NULL_RTX
;
7284 else if (current_function_is_leaf
&& !df_regs_ever_live_p (5))
7285 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, 5);
7287 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
7289 s390_register_info (clobbered_regs
);
7292 while (frame_size
!= cfun_frame_layout
.frame_size
);
7295 /* Update frame layout. Recompute actual register save data based on
7296 current info and update regs_ever_live for the special registers.
7297 May be called multiple times, but may never cause *more* registers
7298 to be saved than s390_init_frame_layout allocated room for. */
7301 s390_update_frame_layout (void)
7303 int clobbered_regs
[16];
7305 s390_register_info (clobbered_regs
);
7307 df_set_regs_ever_live (BASE_REGNUM
,
7308 clobbered_regs
[BASE_REGNUM
] ? true : false);
7309 df_set_regs_ever_live (RETURN_REGNUM
,
7310 clobbered_regs
[RETURN_REGNUM
] ? true : false);
7311 df_set_regs_ever_live (STACK_POINTER_REGNUM
,
7312 clobbered_regs
[STACK_POINTER_REGNUM
] ? true : false);
7314 if (cfun
->machine
->base_reg
)
7315 df_set_regs_ever_live (REGNO (cfun
->machine
->base_reg
), true);
7318 /* Return true if it is legal to put a value with MODE into REGNO. */
7321 s390_hard_regno_mode_ok (unsigned int regno
, enum machine_mode mode
)
7323 switch (REGNO_REG_CLASS (regno
))
7326 if (REGNO_PAIR_OK (regno
, mode
))
7328 if (mode
== SImode
|| mode
== DImode
)
7331 if (FLOAT_MODE_P (mode
) && GET_MODE_CLASS (mode
) != MODE_VECTOR_FLOAT
)
7336 if (FRAME_REGNO_P (regno
) && mode
== Pmode
)
7341 if (REGNO_PAIR_OK (regno
, mode
))
7344 || (mode
!= TFmode
&& mode
!= TCmode
&& mode
!= TDmode
))
7349 if (GET_MODE_CLASS (mode
) == MODE_CC
)
7353 if (REGNO_PAIR_OK (regno
, mode
))
7355 if (mode
== SImode
|| mode
== Pmode
)
7366 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
7369 s390_hard_regno_rename_ok (unsigned int old_reg
, unsigned int new_reg
)
7371 /* Once we've decided upon a register to use as base register, it must
7372 no longer be used for any other purpose. */
7373 if (cfun
->machine
->base_reg
)
7374 if (REGNO (cfun
->machine
->base_reg
) == old_reg
7375 || REGNO (cfun
->machine
->base_reg
) == new_reg
)
7381 /* Maximum number of registers to represent a value of mode MODE
7382 in a register of class RCLASS. */
7385 s390_class_max_nregs (enum reg_class rclass
, enum machine_mode mode
)
7390 if (GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
)
7391 return 2 * ((GET_MODE_SIZE (mode
) / 2 + 8 - 1) / 8);
7393 return (GET_MODE_SIZE (mode
) + 8 - 1) / 8;
7395 return (GET_MODE_SIZE (mode
) + 4 - 1) / 4;
7399 return (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
7402 /* Return true if register FROM can be eliminated via register TO. */
7405 s390_can_eliminate (const int from
, const int to
)
7407 /* On zSeries machines, we have not marked the base register as fixed.
7408 Instead, we have an elimination rule BASE_REGNUM -> BASE_REGNUM.
7409 If a function requires the base register, we say here that this
7410 elimination cannot be performed. This will cause reload to free
7411 up the base register (as if it were fixed). On the other hand,
7412 if the current function does *not* require the base register, we
7413 say here the elimination succeeds, which in turn allows reload
7414 to allocate the base register for any other purpose. */
7415 if (from
== BASE_REGNUM
&& to
== BASE_REGNUM
)
7417 if (TARGET_CPU_ZARCH
)
7419 s390_init_frame_layout ();
7420 return cfun
->machine
->base_reg
== NULL_RTX
;
7426 /* Everything else must point into the stack frame. */
7427 gcc_assert (to
== STACK_POINTER_REGNUM
7428 || to
== HARD_FRAME_POINTER_REGNUM
);
7430 gcc_assert (from
== FRAME_POINTER_REGNUM
7431 || from
== ARG_POINTER_REGNUM
7432 || from
== RETURN_ADDRESS_POINTER_REGNUM
);
7434 /* Make sure we actually saved the return address. */
7435 if (from
== RETURN_ADDRESS_POINTER_REGNUM
)
7436 if (!crtl
->calls_eh_return
7438 && !cfun_frame_layout
.save_return_addr_p
)
7444 /* Return offset between register FROM and TO initially after prolog. */
7447 s390_initial_elimination_offset (int from
, int to
)
7449 HOST_WIDE_INT offset
;
7452 /* ??? Why are we called for non-eliminable pairs? */
7453 if (!s390_can_eliminate (from
, to
))
7458 case FRAME_POINTER_REGNUM
:
7459 offset
= (get_frame_size()
7460 + STACK_POINTER_OFFSET
7461 + crtl
->outgoing_args_size
);
7464 case ARG_POINTER_REGNUM
:
7465 s390_init_frame_layout ();
7466 offset
= cfun_frame_layout
.frame_size
+ STACK_POINTER_OFFSET
;
7469 case RETURN_ADDRESS_POINTER_REGNUM
:
7470 s390_init_frame_layout ();
7471 index
= RETURN_REGNUM
- cfun_frame_layout
.first_save_gpr_slot
;
7472 gcc_assert (index
>= 0);
7473 offset
= cfun_frame_layout
.frame_size
+ cfun_frame_layout
.gprs_offset
;
7474 offset
+= index
* UNITS_PER_WORD
;
7488 /* Emit insn to save fpr REGNUM at offset OFFSET relative
7489 to register BASE. Return generated insn. */
7492 save_fpr (rtx base
, int offset
, int regnum
)
7495 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
7497 if (regnum
>= 16 && regnum
<= (16 + FP_ARG_NUM_REG
))
7498 set_mem_alias_set (addr
, get_varargs_alias_set ());
7500 set_mem_alias_set (addr
, get_frame_alias_set ());
7502 return emit_move_insn (addr
, gen_rtx_REG (DFmode
, regnum
));
7505 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
7506 to register BASE. Return generated insn. */
7509 restore_fpr (rtx base
, int offset
, int regnum
)
7512 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
7513 set_mem_alias_set (addr
, get_frame_alias_set ());
7515 return emit_move_insn (gen_rtx_REG (DFmode
, regnum
), addr
);
7518 /* Return true if REGNO is a global register, but not one
7519 of the special ones that need to be saved/restored in anyway. */
7522 global_not_special_regno_p (int regno
)
7524 return (global_regs
[regno
]
7525 /* These registers are special and need to be
7526 restored in any case. */
7527 && !(regno
== STACK_POINTER_REGNUM
7528 || regno
== RETURN_REGNUM
7529 || regno
== BASE_REGNUM
7530 || (flag_pic
&& regno
== (int)PIC_OFFSET_TABLE_REGNUM
)));
7533 /* Generate insn to save registers FIRST to LAST into
7534 the register save area located at offset OFFSET
7535 relative to register BASE. */
7538 save_gprs (rtx base
, int offset
, int first
, int last
)
7540 rtx addr
, insn
, note
;
7543 addr
= plus_constant (base
, offset
);
7544 addr
= gen_rtx_MEM (Pmode
, addr
);
7546 set_mem_alias_set (addr
, get_frame_alias_set ());
7548 /* Special-case single register. */
7552 insn
= gen_movdi (addr
, gen_rtx_REG (Pmode
, first
));
7554 insn
= gen_movsi (addr
, gen_rtx_REG (Pmode
, first
));
7556 if (!global_not_special_regno_p (first
))
7557 RTX_FRAME_RELATED_P (insn
) = 1;
7562 insn
= gen_store_multiple (addr
,
7563 gen_rtx_REG (Pmode
, first
),
7564 GEN_INT (last
- first
+ 1));
7566 if (first
<= 6 && cfun
->stdarg
)
7567 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
7569 rtx mem
= XEXP (XVECEXP (PATTERN (insn
), 0, i
), 0);
7572 set_mem_alias_set (mem
, get_varargs_alias_set ());
7575 /* We need to set the FRAME_RELATED flag on all SETs
7576 inside the store-multiple pattern.
7578 However, we must not emit DWARF records for registers 2..5
7579 if they are stored for use by variable arguments ...
7581 ??? Unfortunately, it is not enough to simply not the
7582 FRAME_RELATED flags for those SETs, because the first SET
7583 of the PARALLEL is always treated as if it had the flag
7584 set, even if it does not. Therefore we emit a new pattern
7585 without those registers as REG_FRAME_RELATED_EXPR note. */
7587 if (first
>= 6 && !global_not_special_regno_p (first
))
7589 rtx pat
= PATTERN (insn
);
7591 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
7592 if (GET_CODE (XVECEXP (pat
, 0, i
)) == SET
7593 && !global_not_special_regno_p (REGNO (SET_SRC (XVECEXP (pat
,
7595 RTX_FRAME_RELATED_P (XVECEXP (pat
, 0, i
)) = 1;
7597 RTX_FRAME_RELATED_P (insn
) = 1;
7603 for (start
= first
>= 6 ? first
: 6; start
<= last
; start
++)
7604 if (!global_not_special_regno_p (start
))
7610 addr
= plus_constant (base
, offset
+ (start
- first
) * UNITS_PER_WORD
);
7611 note
= gen_store_multiple (gen_rtx_MEM (Pmode
, addr
),
7612 gen_rtx_REG (Pmode
, start
),
7613 GEN_INT (last
- start
+ 1));
7614 note
= PATTERN (note
);
7616 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note
);
7618 for (i
= 0; i
< XVECLEN (note
, 0); i
++)
7619 if (GET_CODE (XVECEXP (note
, 0, i
)) == SET
7620 && !global_not_special_regno_p (REGNO (SET_SRC (XVECEXP (note
,
7622 RTX_FRAME_RELATED_P (XVECEXP (note
, 0, i
)) = 1;
7624 RTX_FRAME_RELATED_P (insn
) = 1;
7630 /* Generate insn to restore registers FIRST to LAST from
7631 the register save area located at offset OFFSET
7632 relative to register BASE. */
7635 restore_gprs (rtx base
, int offset
, int first
, int last
)
7639 addr
= plus_constant (base
, offset
);
7640 addr
= gen_rtx_MEM (Pmode
, addr
);
7641 set_mem_alias_set (addr
, get_frame_alias_set ());
7643 /* Special-case single register. */
7647 insn
= gen_movdi (gen_rtx_REG (Pmode
, first
), addr
);
7649 insn
= gen_movsi (gen_rtx_REG (Pmode
, first
), addr
);
7654 insn
= gen_load_multiple (gen_rtx_REG (Pmode
, first
),
7656 GEN_INT (last
- first
+ 1));
7660 /* Return insn sequence to load the GOT register. */
7662 static GTY(()) rtx got_symbol
;
7664 s390_load_got (void)
7670 got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
7671 SYMBOL_REF_FLAGS (got_symbol
) = SYMBOL_FLAG_LOCAL
;
7676 if (TARGET_CPU_ZARCH
)
7678 emit_move_insn (pic_offset_table_rtx
, got_symbol
);
7684 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, got_symbol
),
7685 UNSPEC_LTREL_OFFSET
);
7686 offset
= gen_rtx_CONST (Pmode
, offset
);
7687 offset
= force_const_mem (Pmode
, offset
);
7689 emit_move_insn (pic_offset_table_rtx
, offset
);
7691 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, XEXP (offset
, 0)),
7693 offset
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, offset
);
7695 emit_move_insn (pic_offset_table_rtx
, offset
);
7698 insns
= get_insns ();
7703 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
7704 and the change to the stack pointer. */
7707 s390_emit_stack_tie (void)
7709 rtx mem
= gen_frame_mem (BLKmode
,
7710 gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
));
7712 emit_insn (gen_stack_tie (mem
));
7715 /* Expand the prologue into a bunch of separate insns. */
7718 s390_emit_prologue (void)
7726 /* Complete frame layout. */
7728 s390_update_frame_layout ();
7730 /* Annotate all constant pool references to let the scheduler know
7731 they implicitly use the base register. */
7733 push_topmost_sequence ();
7735 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7738 annotate_constant_pool_refs (&PATTERN (insn
));
7739 df_insn_rescan (insn
);
7742 pop_topmost_sequence ();
7744 /* Choose best register to use for temp use within prologue.
7745 See below for why TPF must use the register 1. */
7747 if (!has_hard_reg_initial_val (Pmode
, RETURN_REGNUM
)
7748 && !current_function_is_leaf
7749 && !TARGET_TPF_PROFILING
)
7750 temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
7752 temp_reg
= gen_rtx_REG (Pmode
, 1);
7754 /* Save call saved gprs. */
7755 if (cfun_frame_layout
.first_save_gpr
!= -1)
7757 insn
= save_gprs (stack_pointer_rtx
,
7758 cfun_frame_layout
.gprs_offset
+
7759 UNITS_PER_WORD
* (cfun_frame_layout
.first_save_gpr
7760 - cfun_frame_layout
.first_save_gpr_slot
),
7761 cfun_frame_layout
.first_save_gpr
,
7762 cfun_frame_layout
.last_save_gpr
);
7766 /* Dummy insn to mark literal pool slot. */
7768 if (cfun
->machine
->base_reg
)
7769 emit_insn (gen_main_pool (cfun
->machine
->base_reg
));
7771 offset
= cfun_frame_layout
.f0_offset
;
7773 /* Save f0 and f2. */
7774 for (i
= 0; i
< 2; i
++)
7776 if (cfun_fpr_bit_p (i
))
7778 save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
7781 else if (!TARGET_PACKED_STACK
)
7785 /* Save f4 and f6. */
7786 offset
= cfun_frame_layout
.f4_offset
;
7787 for (i
= 2; i
< 4; i
++)
7789 if (cfun_fpr_bit_p (i
))
7791 insn
= save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
7794 /* If f4 and f6 are call clobbered they are saved due to stdargs and
7795 therefore are not frame related. */
7796 if (!call_really_used_regs
[i
+ 16])
7797 RTX_FRAME_RELATED_P (insn
) = 1;
7799 else if (!TARGET_PACKED_STACK
)
7803 if (TARGET_PACKED_STACK
7804 && cfun_save_high_fprs_p
7805 && cfun_frame_layout
.f8_offset
+ cfun_frame_layout
.high_fprs
* 8 > 0)
7807 offset
= (cfun_frame_layout
.f8_offset
7808 + (cfun_frame_layout
.high_fprs
- 1) * 8);
7810 for (i
= 15; i
> 7 && offset
>= 0; i
--)
7811 if (cfun_fpr_bit_p (i
))
7813 insn
= save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
7815 RTX_FRAME_RELATED_P (insn
) = 1;
7818 if (offset
>= cfun_frame_layout
.f8_offset
)
7822 if (!TARGET_PACKED_STACK
)
7823 next_fpr
= cfun_save_high_fprs_p
? 31 : 0;
7825 /* Decrement stack pointer. */
7827 if (cfun_frame_layout
.frame_size
> 0)
7829 rtx frame_off
= GEN_INT (-cfun_frame_layout
.frame_size
);
7832 if (s390_stack_size
)
7834 HOST_WIDE_INT stack_guard
;
7836 if (s390_stack_guard
)
7837 stack_guard
= s390_stack_guard
;
7840 /* If no value for stack guard is provided the smallest power of 2
7841 larger than the current frame size is chosen. */
7843 while (stack_guard
< cfun_frame_layout
.frame_size
)
7847 if (cfun_frame_layout
.frame_size
>= s390_stack_size
)
7849 warning (0, "frame size of function %qs is "
7850 HOST_WIDE_INT_PRINT_DEC
7851 " bytes exceeding user provided stack limit of "
7852 HOST_WIDE_INT_PRINT_DEC
" bytes. "
7853 "An unconditional trap is added.",
7854 current_function_name(), cfun_frame_layout
.frame_size
,
7856 emit_insn (gen_trap ());
7860 /* stack_guard has to be smaller than s390_stack_size.
7861 Otherwise we would emit an AND with zero which would
7862 not match the test under mask pattern. */
7863 if (stack_guard
>= s390_stack_size
)
7865 warning (0, "frame size of function %qs is "
7866 HOST_WIDE_INT_PRINT_DEC
7867 " bytes which is more than half the stack size. "
7868 "The dynamic check would not be reliable. "
7869 "No check emitted for this function.",
7870 current_function_name(),
7871 cfun_frame_layout
.frame_size
);
7875 HOST_WIDE_INT stack_check_mask
= ((s390_stack_size
- 1)
7876 & ~(stack_guard
- 1));
7878 rtx t
= gen_rtx_AND (Pmode
, stack_pointer_rtx
,
7879 GEN_INT (stack_check_mask
));
7881 emit_insn (gen_ctrapdi4 (gen_rtx_EQ (VOIDmode
,
7883 t
, const0_rtx
, const0_rtx
));
7885 emit_insn (gen_ctrapsi4 (gen_rtx_EQ (VOIDmode
,
7887 t
, const0_rtx
, const0_rtx
));
7892 if (s390_warn_framesize
> 0
7893 && cfun_frame_layout
.frame_size
>= s390_warn_framesize
)
7894 warning (0, "frame size of %qs is " HOST_WIDE_INT_PRINT_DEC
" bytes",
7895 current_function_name (), cfun_frame_layout
.frame_size
);
7897 if (s390_warn_dynamicstack_p
&& cfun
->calls_alloca
)
7898 warning (0, "%qs uses dynamic stack allocation", current_function_name ());
7900 /* Save incoming stack pointer into temp reg. */
7901 if (TARGET_BACKCHAIN
|| next_fpr
)
7902 insn
= emit_insn (gen_move_insn (temp_reg
, stack_pointer_rtx
));
7904 /* Subtract frame size from stack pointer. */
7906 if (DISP_IN_RANGE (INTVAL (frame_off
)))
7908 insn
= gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
7909 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
7911 insn
= emit_insn (insn
);
7915 if (!CONST_OK_FOR_K (INTVAL (frame_off
)))
7916 frame_off
= force_const_mem (Pmode
, frame_off
);
7918 insn
= emit_insn (gen_add2_insn (stack_pointer_rtx
, frame_off
));
7919 annotate_constant_pool_refs (&PATTERN (insn
));
7922 RTX_FRAME_RELATED_P (insn
) = 1;
7923 real_frame_off
= GEN_INT (-cfun_frame_layout
.frame_size
);
7924 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
,
7925 gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
7926 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
7929 /* Set backchain. */
7931 if (TARGET_BACKCHAIN
)
7933 if (cfun_frame_layout
.backchain_offset
)
7934 addr
= gen_rtx_MEM (Pmode
,
7935 plus_constant (stack_pointer_rtx
,
7936 cfun_frame_layout
.backchain_offset
));
7938 addr
= gen_rtx_MEM (Pmode
, stack_pointer_rtx
);
7939 set_mem_alias_set (addr
, get_frame_alias_set ());
7940 insn
= emit_insn (gen_move_insn (addr
, temp_reg
));
7943 /* If we support asynchronous exceptions (e.g. for Java),
7944 we need to make sure the backchain pointer is set up
7945 before any possibly trapping memory access. */
7947 if (TARGET_BACKCHAIN
&& flag_non_call_exceptions
)
7949 addr
= gen_rtx_MEM (BLKmode
, gen_rtx_SCRATCH (VOIDmode
));
7950 emit_clobber (addr
);
7954 /* Save fprs 8 - 15 (64 bit ABI). */
7956 if (cfun_save_high_fprs_p
&& next_fpr
)
7958 /* If the stack might be accessed through a different register
7959 we have to make sure that the stack pointer decrement is not
7960 moved below the use of the stack slots. */
7961 s390_emit_stack_tie ();
7963 insn
= emit_insn (gen_add2_insn (temp_reg
,
7964 GEN_INT (cfun_frame_layout
.f8_offset
)));
7968 for (i
= 24; i
<= next_fpr
; i
++)
7969 if (cfun_fpr_bit_p (i
- 16))
7971 rtx addr
= plus_constant (stack_pointer_rtx
,
7972 cfun_frame_layout
.frame_size
7973 + cfun_frame_layout
.f8_offset
7976 insn
= save_fpr (temp_reg
, offset
, i
);
7978 RTX_FRAME_RELATED_P (insn
) = 1;
7979 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
,
7980 gen_rtx_SET (VOIDmode
,
7981 gen_rtx_MEM (DFmode
, addr
),
7982 gen_rtx_REG (DFmode
, i
)));
7986 /* Set frame pointer, if needed. */
7988 if (frame_pointer_needed
)
7990 insn
= emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
);
7991 RTX_FRAME_RELATED_P (insn
) = 1;
7994 /* Set up got pointer, if needed. */
7996 if (flag_pic
&& df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM
))
7998 rtx insns
= s390_load_got ();
8000 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
8001 annotate_constant_pool_refs (&PATTERN (insn
));
8006 if (TARGET_TPF_PROFILING
)
8008 /* Generate a BAS instruction to serve as a function
8009 entry intercept to facilitate the use of tracing
8010 algorithms located at the branch target. */
8011 emit_insn (gen_prologue_tpf ());
8013 /* Emit a blockage here so that all code
8014 lies between the profiling mechanisms. */
8015 emit_insn (gen_blockage ());
8019 /* Expand the epilogue into a bunch of separate insns. */
8022 s390_emit_epilogue (bool sibcall
)
8024 rtx frame_pointer
, return_reg
, cfa_restores
= NULL_RTX
;
8025 int area_bottom
, area_top
, offset
= 0;
8030 if (TARGET_TPF_PROFILING
)
8033 /* Generate a BAS instruction to serve as a function
8034 entry intercept to facilitate the use of tracing
8035 algorithms located at the branch target. */
8037 /* Emit a blockage here so that all code
8038 lies between the profiling mechanisms. */
8039 emit_insn (gen_blockage ());
8041 emit_insn (gen_epilogue_tpf ());
8044 /* Check whether to use frame or stack pointer for restore. */
8046 frame_pointer
= (frame_pointer_needed
8047 ? hard_frame_pointer_rtx
: stack_pointer_rtx
);
8049 s390_frame_area (&area_bottom
, &area_top
);
8051 /* Check whether we can access the register save area.
8052 If not, increment the frame pointer as required. */
8054 if (area_top
<= area_bottom
)
8056 /* Nothing to restore. */
8058 else if (DISP_IN_RANGE (cfun_frame_layout
.frame_size
+ area_bottom
)
8059 && DISP_IN_RANGE (cfun_frame_layout
.frame_size
+ area_top
- 1))
8061 /* Area is in range. */
8062 offset
= cfun_frame_layout
.frame_size
;
8066 rtx insn
, frame_off
, cfa
;
8068 offset
= area_bottom
< 0 ? -area_bottom
: 0;
8069 frame_off
= GEN_INT (cfun_frame_layout
.frame_size
- offset
);
8071 cfa
= gen_rtx_SET (VOIDmode
, frame_pointer
,
8072 gen_rtx_PLUS (Pmode
, frame_pointer
, frame_off
));
8073 if (DISP_IN_RANGE (INTVAL (frame_off
)))
8075 insn
= gen_rtx_SET (VOIDmode
, frame_pointer
,
8076 gen_rtx_PLUS (Pmode
, frame_pointer
, frame_off
));
8077 insn
= emit_insn (insn
);
8081 if (!CONST_OK_FOR_K (INTVAL (frame_off
)))
8082 frame_off
= force_const_mem (Pmode
, frame_off
);
8084 insn
= emit_insn (gen_add2_insn (frame_pointer
, frame_off
));
8085 annotate_constant_pool_refs (&PATTERN (insn
));
8087 add_reg_note (insn
, REG_CFA_ADJUST_CFA
, cfa
);
8088 RTX_FRAME_RELATED_P (insn
) = 1;
8091 /* Restore call saved fprs. */
8095 if (cfun_save_high_fprs_p
)
8097 next_offset
= cfun_frame_layout
.f8_offset
;
8098 for (i
= 24; i
< 32; i
++)
8100 if (cfun_fpr_bit_p (i
- 16))
8102 restore_fpr (frame_pointer
,
8103 offset
+ next_offset
, i
);
8105 = alloc_reg_note (REG_CFA_RESTORE
,
8106 gen_rtx_REG (DFmode
, i
), cfa_restores
);
8115 next_offset
= cfun_frame_layout
.f4_offset
;
8116 for (i
= 18; i
< 20; i
++)
8118 if (cfun_fpr_bit_p (i
- 16))
8120 restore_fpr (frame_pointer
,
8121 offset
+ next_offset
, i
);
8123 = alloc_reg_note (REG_CFA_RESTORE
,
8124 gen_rtx_REG (DFmode
, i
), cfa_restores
);
8127 else if (!TARGET_PACKED_STACK
)
8133 /* Return register. */
8135 return_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
8137 /* Restore call saved gprs. */
8139 if (cfun_frame_layout
.first_restore_gpr
!= -1)
8144 /* Check for global register and save them
8145 to stack location from where they get restored. */
8147 for (i
= cfun_frame_layout
.first_restore_gpr
;
8148 i
<= cfun_frame_layout
.last_restore_gpr
;
8151 if (global_not_special_regno_p (i
))
8153 addr
= plus_constant (frame_pointer
,
8154 offset
+ cfun_frame_layout
.gprs_offset
8155 + (i
- cfun_frame_layout
.first_save_gpr_slot
)
8157 addr
= gen_rtx_MEM (Pmode
, addr
);
8158 set_mem_alias_set (addr
, get_frame_alias_set ());
8159 emit_move_insn (addr
, gen_rtx_REG (Pmode
, i
));
8163 = alloc_reg_note (REG_CFA_RESTORE
,
8164 gen_rtx_REG (Pmode
, i
), cfa_restores
);
8169 /* Fetch return address from stack before load multiple,
8170 this will do good for scheduling. */
8172 if (cfun_frame_layout
.save_return_addr_p
8173 || (cfun_frame_layout
.first_restore_gpr
< BASE_REGNUM
8174 && cfun_frame_layout
.last_restore_gpr
> RETURN_REGNUM
))
8176 int return_regnum
= find_unused_clobbered_reg();
8179 return_reg
= gen_rtx_REG (Pmode
, return_regnum
);
8181 addr
= plus_constant (frame_pointer
,
8182 offset
+ cfun_frame_layout
.gprs_offset
8184 - cfun_frame_layout
.first_save_gpr_slot
)
8186 addr
= gen_rtx_MEM (Pmode
, addr
);
8187 set_mem_alias_set (addr
, get_frame_alias_set ());
8188 emit_move_insn (return_reg
, addr
);
8192 insn
= restore_gprs (frame_pointer
,
8193 offset
+ cfun_frame_layout
.gprs_offset
8194 + (cfun_frame_layout
.first_restore_gpr
8195 - cfun_frame_layout
.first_save_gpr_slot
)
8197 cfun_frame_layout
.first_restore_gpr
,
8198 cfun_frame_layout
.last_restore_gpr
);
8199 insn
= emit_insn (insn
);
8200 REG_NOTES (insn
) = cfa_restores
;
8201 add_reg_note (insn
, REG_CFA_DEF_CFA
,
8202 plus_constant (stack_pointer_rtx
, STACK_POINTER_OFFSET
));
8203 RTX_FRAME_RELATED_P (insn
) = 1;
8209 /* Return to caller. */
8211 p
= rtvec_alloc (2);
8213 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
8214 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
, return_reg
);
8215 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
8220 /* Return the size in bytes of a function argument of
8221 type TYPE and/or mode MODE. At least one of TYPE or
8222 MODE must be specified. */
8225 s390_function_arg_size (enum machine_mode mode
, const_tree type
)
8228 return int_size_in_bytes (type
);
8230 /* No type info available for some library calls ... */
8231 if (mode
!= BLKmode
)
8232 return GET_MODE_SIZE (mode
);
8234 /* If we have neither type nor mode, abort */
8238 /* Return true if a function argument of type TYPE and mode MODE
8239 is to be passed in a floating-point register, if available. */
8242 s390_function_arg_float (enum machine_mode mode
, tree type
)
8244 int size
= s390_function_arg_size (mode
, type
);
8248 /* Soft-float changes the ABI: no floating-point registers are used. */
8249 if (TARGET_SOFT_FLOAT
)
8252 /* No type info available for some library calls ... */
8254 return mode
== SFmode
|| mode
== DFmode
|| mode
== SDmode
|| mode
== DDmode
;
8256 /* The ABI says that record types with a single member are treated
8257 just like that member would be. */
8258 while (TREE_CODE (type
) == RECORD_TYPE
)
8260 tree field
, single
= NULL_TREE
;
8262 for (field
= TYPE_FIELDS (type
); field
; field
= TREE_CHAIN (field
))
8264 if (TREE_CODE (field
) != FIELD_DECL
)
8267 if (single
== NULL_TREE
)
8268 single
= TREE_TYPE (field
);
8273 if (single
== NULL_TREE
)
8279 return TREE_CODE (type
) == REAL_TYPE
;
8282 /* Return true if a function argument of type TYPE and mode MODE
8283 is to be passed in an integer register, or a pair of integer
8284 registers, if available. */
8287 s390_function_arg_integer (enum machine_mode mode
, tree type
)
8289 int size
= s390_function_arg_size (mode
, type
);
8293 /* No type info available for some library calls ... */
8295 return GET_MODE_CLASS (mode
) == MODE_INT
8296 || (TARGET_SOFT_FLOAT
&& SCALAR_FLOAT_MODE_P (mode
));
8298 /* We accept small integral (and similar) types. */
8299 if (INTEGRAL_TYPE_P (type
)
8300 || POINTER_TYPE_P (type
)
8301 || TREE_CODE (type
) == OFFSET_TYPE
8302 || (TARGET_SOFT_FLOAT
&& TREE_CODE (type
) == REAL_TYPE
))
8305 /* We also accept structs of size 1, 2, 4, 8 that are not
8306 passed in floating-point registers. */
8307 if (AGGREGATE_TYPE_P (type
)
8308 && exact_log2 (size
) >= 0
8309 && !s390_function_arg_float (mode
, type
))
8315 /* Return 1 if a function argument of type TYPE and mode MODE
8316 is to be passed by reference. The ABI specifies that only
8317 structures of size 1, 2, 4, or 8 bytes are passed by value,
8318 all other structures (and complex numbers) are passed by
8322 s390_pass_by_reference (CUMULATIVE_ARGS
*ca ATTRIBUTE_UNUSED
,
8323 enum machine_mode mode
, const_tree type
,
8324 bool named ATTRIBUTE_UNUSED
)
8326 int size
= s390_function_arg_size (mode
, type
);
8332 if (AGGREGATE_TYPE_P (type
) && exact_log2 (size
) < 0)
8335 if (TREE_CODE (type
) == COMPLEX_TYPE
8336 || TREE_CODE (type
) == VECTOR_TYPE
)
8343 /* Update the data in CUM to advance over an argument of mode MODE and
8344 data type TYPE. (TYPE is null for libcalls where that information
8345 may not be available.). The boolean NAMED specifies whether the
8346 argument is a named argument (as opposed to an unnamed argument
8347 matching an ellipsis). */
8350 s390_function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
8351 tree type
, int named ATTRIBUTE_UNUSED
)
8353 if (s390_function_arg_float (mode
, type
))
8357 else if (s390_function_arg_integer (mode
, type
))
8359 int size
= s390_function_arg_size (mode
, type
);
8360 cum
->gprs
+= ((size
+ UNITS_PER_WORD
-1) / UNITS_PER_WORD
);
8366 /* Define where to put the arguments to a function.
8367 Value is zero to push the argument on the stack,
8368 or a hard register in which to store the argument.
8370 MODE is the argument's machine mode.
8371 TYPE is the data type of the argument (as a tree).
8372 This is null for libcalls where that information may
8374 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8375 the preceding args and about the function being called.
8376 NAMED is nonzero if this argument is a named parameter
8377 (otherwise it is an extra parameter matching an ellipsis).
8379 On S/390, we use general purpose registers 2 through 6 to
8380 pass integer, pointer, and certain structure arguments, and
8381 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
8382 to pass floating point arguments. All remaining arguments
8383 are pushed to the stack. */
8386 s390_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
, tree type
,
8387 int named ATTRIBUTE_UNUSED
)
8389 if (s390_function_arg_float (mode
, type
))
8391 if (cum
->fprs
+ 1 > FP_ARG_NUM_REG
)
8394 return gen_rtx_REG (mode
, cum
->fprs
+ 16);
8396 else if (s390_function_arg_integer (mode
, type
))
8398 int size
= s390_function_arg_size (mode
, type
);
8399 int n_gprs
= (size
+ UNITS_PER_WORD
-1) / UNITS_PER_WORD
;
8401 if (cum
->gprs
+ n_gprs
> GP_ARG_NUM_REG
)
8404 return gen_rtx_REG (mode
, cum
->gprs
+ 2);
8407 /* After the real arguments, expand_call calls us once again
8408 with a void_type_node type. Whatever we return here is
8409 passed as operand 2 to the call expanders.
8411 We don't need this feature ... */
8412 else if (type
== void_type_node
)
8418 /* Return true if return values of type TYPE should be returned
8419 in a memory buffer whose address is passed by the caller as
8420 hidden first argument. */
8423 s390_return_in_memory (const_tree type
, const_tree fundecl ATTRIBUTE_UNUSED
)
8425 /* We accept small integral (and similar) types. */
8426 if (INTEGRAL_TYPE_P (type
)
8427 || POINTER_TYPE_P (type
)
8428 || TREE_CODE (type
) == OFFSET_TYPE
8429 || TREE_CODE (type
) == REAL_TYPE
)
8430 return int_size_in_bytes (type
) > 8;
8432 /* Aggregates and similar constructs are always returned
8434 if (AGGREGATE_TYPE_P (type
)
8435 || TREE_CODE (type
) == COMPLEX_TYPE
8436 || TREE_CODE (type
) == VECTOR_TYPE
)
8439 /* ??? We get called on all sorts of random stuff from
8440 aggregate_value_p. We can't abort, but it's not clear
8441 what's safe to return. Pretend it's a struct I guess. */
8445 /* Function arguments and return values are promoted to word size. */
8447 static enum machine_mode
8448 s390_promote_function_mode (const_tree type
, enum machine_mode mode
,
8450 const_tree fntype ATTRIBUTE_UNUSED
,
8451 int for_return ATTRIBUTE_UNUSED
)
8453 if (INTEGRAL_MODE_P (mode
)
8454 && GET_MODE_SIZE (mode
) < UNITS_PER_WORD
)
8456 if (POINTER_TYPE_P (type
))
8457 *punsignedp
= POINTERS_EXTEND_UNSIGNED
;
8464 /* Define where to return a (scalar) value of type TYPE.
8465 If TYPE is null, define where to return a (scalar)
8466 value of mode MODE from a libcall. */
8469 s390_function_value (const_tree type
, const_tree fn
, enum machine_mode mode
)
8473 int unsignedp
= TYPE_UNSIGNED (type
);
8474 mode
= promote_function_mode (type
, TYPE_MODE (type
), &unsignedp
, fn
, 1);
8477 gcc_assert (GET_MODE_CLASS (mode
) == MODE_INT
|| SCALAR_FLOAT_MODE_P (mode
));
8478 gcc_assert (GET_MODE_SIZE (mode
) <= 8);
8480 if (TARGET_HARD_FLOAT
&& SCALAR_FLOAT_MODE_P (mode
))
8481 return gen_rtx_REG (mode
, 16);
8483 return gen_rtx_REG (mode
, 2);
8487 /* Create and return the va_list datatype.
8489 On S/390, va_list is an array type equivalent to
8491 typedef struct __va_list_tag
8495 void *__overflow_arg_area;
8496 void *__reg_save_area;
8499 where __gpr and __fpr hold the number of general purpose
8500 or floating point arguments used up to now, respectively,
8501 __overflow_arg_area points to the stack location of the
8502 next argument passed on the stack, and __reg_save_area
8503 always points to the start of the register area in the
8504 call frame of the current function. The function prologue
8505 saves all registers used for argument passing into this
8506 area if the function uses variable arguments. */
8509 s390_build_builtin_va_list (void)
8511 tree f_gpr
, f_fpr
, f_ovf
, f_sav
, record
, type_decl
;
8513 record
= lang_hooks
.types
.make_type (RECORD_TYPE
);
8516 build_decl (BUILTINS_LOCATION
,
8517 TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
8519 f_gpr
= build_decl (BUILTINS_LOCATION
,
8520 FIELD_DECL
, get_identifier ("__gpr"),
8521 long_integer_type_node
);
8522 f_fpr
= build_decl (BUILTINS_LOCATION
,
8523 FIELD_DECL
, get_identifier ("__fpr"),
8524 long_integer_type_node
);
8525 f_ovf
= build_decl (BUILTINS_LOCATION
,
8526 FIELD_DECL
, get_identifier ("__overflow_arg_area"),
8528 f_sav
= build_decl (BUILTINS_LOCATION
,
8529 FIELD_DECL
, get_identifier ("__reg_save_area"),
8532 va_list_gpr_counter_field
= f_gpr
;
8533 va_list_fpr_counter_field
= f_fpr
;
8535 DECL_FIELD_CONTEXT (f_gpr
) = record
;
8536 DECL_FIELD_CONTEXT (f_fpr
) = record
;
8537 DECL_FIELD_CONTEXT (f_ovf
) = record
;
8538 DECL_FIELD_CONTEXT (f_sav
) = record
;
8540 TREE_CHAIN (record
) = type_decl
;
8541 TYPE_NAME (record
) = type_decl
;
8542 TYPE_FIELDS (record
) = f_gpr
;
8543 TREE_CHAIN (f_gpr
) = f_fpr
;
8544 TREE_CHAIN (f_fpr
) = f_ovf
;
8545 TREE_CHAIN (f_ovf
) = f_sav
;
8547 layout_type (record
);
8549 /* The correct type is an array type of one element. */
8550 return build_array_type (record
, build_index_type (size_zero_node
));
8553 /* Implement va_start by filling the va_list structure VALIST.
8554 STDARG_P is always true, and ignored.
8555 NEXTARG points to the first anonymous stack argument.
8557 The following global variables are used to initialize
8558 the va_list structure:
8561 holds number of gprs and fprs used for named arguments.
8562 crtl->args.arg_offset_rtx:
8563 holds the offset of the first anonymous stack argument
8564 (relative to the virtual arg pointer). */
8567 s390_va_start (tree valist
, rtx nextarg ATTRIBUTE_UNUSED
)
8569 HOST_WIDE_INT n_gpr
, n_fpr
;
8571 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
8572 tree gpr
, fpr
, ovf
, sav
, t
;
8574 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
8575 f_fpr
= TREE_CHAIN (f_gpr
);
8576 f_ovf
= TREE_CHAIN (f_fpr
);
8577 f_sav
= TREE_CHAIN (f_ovf
);
8579 valist
= build_va_arg_indirect_ref (valist
);
8580 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
8581 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
8582 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
8583 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
8585 /* Count number of gp and fp argument registers used. */
8587 n_gpr
= crtl
->args
.info
.gprs
;
8588 n_fpr
= crtl
->args
.info
.fprs
;
8590 if (cfun
->va_list_gpr_size
)
8592 t
= build2 (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
,
8593 build_int_cst (NULL_TREE
, n_gpr
));
8594 TREE_SIDE_EFFECTS (t
) = 1;
8595 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
8598 if (cfun
->va_list_fpr_size
)
8600 t
= build2 (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
,
8601 build_int_cst (NULL_TREE
, n_fpr
));
8602 TREE_SIDE_EFFECTS (t
) = 1;
8603 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
8606 /* Find the overflow area. */
8607 if (n_gpr
+ cfun
->va_list_gpr_size
> GP_ARG_NUM_REG
8608 || n_fpr
+ cfun
->va_list_fpr_size
> FP_ARG_NUM_REG
)
8610 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
8612 off
= INTVAL (crtl
->args
.arg_offset_rtx
);
8613 off
= off
< 0 ? 0 : off
;
8614 if (TARGET_DEBUG_ARG
)
8615 fprintf (stderr
, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
8616 (int)n_gpr
, (int)n_fpr
, off
);
8618 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (ovf
), t
, size_int (off
));
8620 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
8621 TREE_SIDE_EFFECTS (t
) = 1;
8622 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
8625 /* Find the register save area. */
8626 if ((cfun
->va_list_gpr_size
&& n_gpr
< GP_ARG_NUM_REG
)
8627 || (cfun
->va_list_fpr_size
&& n_fpr
< FP_ARG_NUM_REG
))
8629 t
= make_tree (TREE_TYPE (sav
), return_address_pointer_rtx
);
8630 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (sav
), t
,
8631 size_int (-RETURN_REGNUM
* UNITS_PER_WORD
));
8633 t
= build2 (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
8634 TREE_SIDE_EFFECTS (t
) = 1;
8635 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
8639 /* Implement va_arg by updating the va_list structure
8640 VALIST as required to retrieve an argument of type
8641 TYPE, and returning that argument.
8643 Generates code equivalent to:
8645 if (integral value) {
8646 if (size <= 4 && args.gpr < 5 ||
8647 size > 4 && args.gpr < 4 )
8648 ret = args.reg_save_area[args.gpr+8]
8650 ret = *args.overflow_arg_area++;
8651 } else if (float value) {
8653 ret = args.reg_save_area[args.fpr+64]
8655 ret = *args.overflow_arg_area++;
8656 } else if (aggregate value) {
8658 ret = *args.reg_save_area[args.gpr]
8660 ret = **args.overflow_arg_area++;
8664 s390_gimplify_va_arg (tree valist
, tree type
, gimple_seq
*pre_p
,
8665 gimple_seq
*post_p ATTRIBUTE_UNUSED
)
8667 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
8668 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
8669 int indirect_p
, size
, n_reg
, sav_ofs
, sav_scale
, max_reg
;
8670 tree lab_false
, lab_over
, addr
;
8672 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
8673 f_fpr
= TREE_CHAIN (f_gpr
);
8674 f_ovf
= TREE_CHAIN (f_fpr
);
8675 f_sav
= TREE_CHAIN (f_ovf
);
8677 valist
= build_va_arg_indirect_ref (valist
);
8678 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
8679 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
8680 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
8682 /* The tree for args* cannot be shared between gpr/fpr and ovf since
8683 both appear on a lhs. */
8684 valist
= unshare_expr (valist
);
8685 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
8687 size
= int_size_in_bytes (type
);
8689 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
8691 if (TARGET_DEBUG_ARG
)
8693 fprintf (stderr
, "va_arg: aggregate type");
8697 /* Aggregates are passed by reference. */
8702 /* kernel stack layout on 31 bit: It is assumed here that no padding
8703 will be added by s390_frame_info because for va_args always an even
8704 number of gprs has to be saved r15-r2 = 14 regs. */
8705 sav_ofs
= 2 * UNITS_PER_WORD
;
8706 sav_scale
= UNITS_PER_WORD
;
8707 size
= UNITS_PER_WORD
;
8708 max_reg
= GP_ARG_NUM_REG
- n_reg
;
8710 else if (s390_function_arg_float (TYPE_MODE (type
), type
))
8712 if (TARGET_DEBUG_ARG
)
8714 fprintf (stderr
, "va_arg: float type");
8718 /* FP args go in FP registers, if present. */
8722 sav_ofs
= 16 * UNITS_PER_WORD
;
8724 max_reg
= FP_ARG_NUM_REG
- n_reg
;
8728 if (TARGET_DEBUG_ARG
)
8730 fprintf (stderr
, "va_arg: other type");
8734 /* Otherwise into GP registers. */
8737 n_reg
= (size
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
8739 /* kernel stack layout on 31 bit: It is assumed here that no padding
8740 will be added by s390_frame_info because for va_args always an even
8741 number of gprs has to be saved r15-r2 = 14 regs. */
8742 sav_ofs
= 2 * UNITS_PER_WORD
;
8744 if (size
< UNITS_PER_WORD
)
8745 sav_ofs
+= UNITS_PER_WORD
- size
;
8747 sav_scale
= UNITS_PER_WORD
;
8748 max_reg
= GP_ARG_NUM_REG
- n_reg
;
8751 /* Pull the value out of the saved registers ... */
8753 lab_false
= create_artificial_label (UNKNOWN_LOCATION
);
8754 lab_over
= create_artificial_label (UNKNOWN_LOCATION
);
8755 addr
= create_tmp_var (ptr_type_node
, "addr");
8757 t
= fold_convert (TREE_TYPE (reg
), size_int (max_reg
));
8758 t
= build2 (GT_EXPR
, boolean_type_node
, reg
, t
);
8759 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
8760 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
8761 gimplify_and_add (t
, pre_p
);
8763 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, sav
,
8764 size_int (sav_ofs
));
8765 u
= build2 (MULT_EXPR
, TREE_TYPE (reg
), reg
,
8766 fold_convert (TREE_TYPE (reg
), size_int (sav_scale
)));
8767 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, t
, fold_convert (sizetype
, u
));
8769 gimplify_assign (addr
, t
, pre_p
);
8771 gimple_seq_add_stmt (pre_p
, gimple_build_goto (lab_over
));
8773 gimple_seq_add_stmt (pre_p
, gimple_build_label (lab_false
));
8776 /* ... Otherwise out of the overflow area. */
8779 if (size
< UNITS_PER_WORD
)
8780 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, t
,
8781 size_int (UNITS_PER_WORD
- size
));
8783 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
8785 gimplify_assign (addr
, t
, pre_p
);
8787 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, t
,
8789 gimplify_assign (ovf
, t
, pre_p
);
8791 gimple_seq_add_stmt (pre_p
, gimple_build_label (lab_over
));
8794 /* Increment register save count. */
8796 u
= build2 (PREINCREMENT_EXPR
, TREE_TYPE (reg
), reg
,
8797 fold_convert (TREE_TYPE (reg
), size_int (n_reg
)));
8798 gimplify_and_add (u
, pre_p
);
8802 t
= build_pointer_type_for_mode (build_pointer_type (type
),
8804 addr
= fold_convert (t
, addr
);
8805 addr
= build_va_arg_indirect_ref (addr
);
8809 t
= build_pointer_type_for_mode (type
, ptr_mode
, true);
8810 addr
= fold_convert (t
, addr
);
8813 return build_va_arg_indirect_ref (addr
);
8821 S390_BUILTIN_THREAD_POINTER
,
8822 S390_BUILTIN_SET_THREAD_POINTER
,
8827 static enum insn_code
const code_for_builtin_64
[S390_BUILTIN_max
] = {
8832 static enum insn_code
const code_for_builtin_31
[S390_BUILTIN_max
] = {
8838 s390_init_builtins (void)
8842 ftype
= build_function_type (ptr_type_node
, void_list_node
);
8843 add_builtin_function ("__builtin_thread_pointer", ftype
,
8844 S390_BUILTIN_THREAD_POINTER
, BUILT_IN_MD
,
8847 ftype
= build_function_type_list (void_type_node
, ptr_type_node
, NULL_TREE
);
8848 add_builtin_function ("__builtin_set_thread_pointer", ftype
,
8849 S390_BUILTIN_SET_THREAD_POINTER
, BUILT_IN_MD
,
8853 /* Expand an expression EXP that calls a built-in function,
8854 with result going to TARGET if that's convenient
8855 (and in mode MODE if that's convenient).
8856 SUBTARGET may be used as the target for computing one of EXP's operands.
8857 IGNORE is nonzero if the value is to be ignored. */
8860 s390_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
8861 enum machine_mode mode ATTRIBUTE_UNUSED
,
8862 int ignore ATTRIBUTE_UNUSED
)
8866 enum insn_code
const *code_for_builtin
=
8867 TARGET_64BIT
? code_for_builtin_64
: code_for_builtin_31
;
8869 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8870 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8871 enum insn_code icode
;
8872 rtx op
[MAX_ARGS
], pat
;
8876 call_expr_arg_iterator iter
;
8878 if (fcode
>= S390_BUILTIN_max
)
8879 internal_error ("bad builtin fcode");
8880 icode
= code_for_builtin
[fcode
];
8882 internal_error ("bad builtin fcode");
8884 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
8887 FOR_EACH_CALL_EXPR_ARG (arg
, iter
, exp
)
8889 const struct insn_operand_data
*insn_op
;
8891 if (arg
== error_mark_node
)
8893 if (arity
> MAX_ARGS
)
8896 insn_op
= &insn_data
[icode
].operand
[arity
+ nonvoid
];
8898 op
[arity
] = expand_expr (arg
, NULL_RTX
, insn_op
->mode
, EXPAND_NORMAL
);
8900 if (!(*insn_op
->predicate
) (op
[arity
], insn_op
->mode
))
8901 op
[arity
] = copy_to_mode_reg (insn_op
->mode
, op
[arity
]);
8907 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8909 || GET_MODE (target
) != tmode
8910 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8911 target
= gen_reg_rtx (tmode
);
8917 pat
= GEN_FCN (icode
) (target
);
8921 pat
= GEN_FCN (icode
) (target
, op
[0]);
8923 pat
= GEN_FCN (icode
) (op
[0]);
8926 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
8942 /* Output assembly code for the trampoline template to
8945 On S/390, we use gpr 1 internally in the trampoline code;
8946 gpr 0 is used to hold the static chain. */
8949 s390_asm_trampoline_template (FILE *file
)
8952 op
[0] = gen_rtx_REG (Pmode
, 0);
8953 op
[1] = gen_rtx_REG (Pmode
, 1);
8957 output_asm_insn ("basr\t%1,0", op
);
8958 output_asm_insn ("lmg\t%0,%1,14(%1)", op
);
8959 output_asm_insn ("br\t%1", op
);
8960 ASM_OUTPUT_SKIP (file
, (HOST_WIDE_INT
)(TRAMPOLINE_SIZE
- 10));
8964 output_asm_insn ("basr\t%1,0", op
);
8965 output_asm_insn ("lm\t%0,%1,6(%1)", op
);
8966 output_asm_insn ("br\t%1", op
);
8967 ASM_OUTPUT_SKIP (file
, (HOST_WIDE_INT
)(TRAMPOLINE_SIZE
- 8));
8971 /* Emit RTL insns to initialize the variable parts of a trampoline.
8972 FNADDR is an RTX for the address of the function's pure code.
8973 CXT is an RTX for the static chain value for the function. */
8976 s390_trampoline_init (rtx m_tramp
, tree fndecl
, rtx cxt
)
8978 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
8981 emit_block_move (m_tramp
, assemble_trampoline_template (),
8982 GEN_INT (2*UNITS_PER_WORD
), BLOCK_OP_NORMAL
);
8984 mem
= adjust_address (m_tramp
, Pmode
, 2*UNITS_PER_WORD
);
8985 emit_move_insn (mem
, cxt
);
8986 mem
= adjust_address (m_tramp
, Pmode
, 3*UNITS_PER_WORD
);
8987 emit_move_insn (mem
, fnaddr
);
8990 /* Output assembler code to FILE to increment profiler label # LABELNO
8991 for profiling a function entry. */
8994 s390_function_profiler (FILE *file
, int labelno
)
8999 ASM_GENERATE_INTERNAL_LABEL (label
, "LP", labelno
);
9001 fprintf (file
, "# function profiler \n");
9003 op
[0] = gen_rtx_REG (Pmode
, RETURN_REGNUM
);
9004 op
[1] = gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
9005 op
[1] = gen_rtx_MEM (Pmode
, plus_constant (op
[1], UNITS_PER_WORD
));
9007 op
[2] = gen_rtx_REG (Pmode
, 1);
9008 op
[3] = gen_rtx_SYMBOL_REF (Pmode
, label
);
9009 SYMBOL_REF_FLAGS (op
[3]) = SYMBOL_FLAG_LOCAL
;
9011 op
[4] = gen_rtx_SYMBOL_REF (Pmode
, "_mcount");
9014 op
[4] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[4]), UNSPEC_PLT
);
9015 op
[4] = gen_rtx_CONST (Pmode
, op
[4]);
9020 output_asm_insn ("stg\t%0,%1", op
);
9021 output_asm_insn ("larl\t%2,%3", op
);
9022 output_asm_insn ("brasl\t%0,%4", op
);
9023 output_asm_insn ("lg\t%0,%1", op
);
9027 op
[6] = gen_label_rtx ();
9029 output_asm_insn ("st\t%0,%1", op
);
9030 output_asm_insn ("bras\t%2,%l6", op
);
9031 output_asm_insn (".long\t%4", op
);
9032 output_asm_insn (".long\t%3", op
);
9033 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
9034 output_asm_insn ("l\t%0,0(%2)", op
);
9035 output_asm_insn ("l\t%2,4(%2)", op
);
9036 output_asm_insn ("basr\t%0,%0", op
);
9037 output_asm_insn ("l\t%0,%1", op
);
9041 op
[5] = gen_label_rtx ();
9042 op
[6] = gen_label_rtx ();
9044 output_asm_insn ("st\t%0,%1", op
);
9045 output_asm_insn ("bras\t%2,%l6", op
);
9046 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[5]));
9047 output_asm_insn (".long\t%4-%l5", op
);
9048 output_asm_insn (".long\t%3-%l5", op
);
9049 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
9050 output_asm_insn ("lr\t%0,%2", op
);
9051 output_asm_insn ("a\t%0,0(%2)", op
);
9052 output_asm_insn ("a\t%2,4(%2)", op
);
9053 output_asm_insn ("basr\t%0,%0", op
);
9054 output_asm_insn ("l\t%0,%1", op
);
9058 /* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
9059 into its SYMBOL_REF_FLAGS. */
9062 s390_encode_section_info (tree decl
, rtx rtl
, int first
)
9064 default_encode_section_info (decl
, rtl
, first
);
9066 if (TREE_CODE (decl
) == VAR_DECL
)
9068 /* If a variable has a forced alignment to < 2 bytes, mark it
9069 with SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL
9071 if (DECL_USER_ALIGN (decl
) && DECL_ALIGN (decl
) < 16)
9072 SYMBOL_REF_FLAGS (XEXP (rtl
, 0)) |= SYMBOL_FLAG_ALIGN1
;
9073 if (!DECL_SIZE (decl
)
9074 || !DECL_ALIGN (decl
)
9075 || !host_integerp (DECL_SIZE (decl
), 0)
9076 || (DECL_ALIGN (decl
) <= 64
9077 && DECL_ALIGN (decl
) != tree_low_cst (DECL_SIZE (decl
), 0)))
9078 SYMBOL_REF_FLAGS (XEXP (rtl
, 0)) |= SYMBOL_FLAG_NOT_NATURALLY_ALIGNED
;
9081 /* Literal pool references don't have a decl so they are handled
9082 differently here. We rely on the information in the MEM_ALIGN
9083 entry to decide upon natural alignment. */
9085 && GET_CODE (XEXP (rtl
, 0)) == SYMBOL_REF
9086 && TREE_CONSTANT_POOL_ADDRESS_P (XEXP (rtl
, 0))
9087 && (MEM_ALIGN (rtl
) == 0
9088 || GET_MODE_BITSIZE (GET_MODE (rtl
)) == 0
9089 || MEM_ALIGN (rtl
) < GET_MODE_BITSIZE (GET_MODE (rtl
))))
9090 SYMBOL_REF_FLAGS (XEXP (rtl
, 0)) |= SYMBOL_FLAG_NOT_NATURALLY_ALIGNED
;
9093 /* Output thunk to FILE that implements a C++ virtual function call (with
9094 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
9095 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
9096 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
9097 relative to the resulting this pointer. */
9100 s390_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
9101 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
9107 /* Make sure unwind info is emitted for the thunk if needed. */
9108 final_start_function (emit_barrier (), file
, 1);
9110 /* Operand 0 is the target function. */
9111 op
[0] = XEXP (DECL_RTL (function
), 0);
9112 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (op
[0]))
9115 op
[0] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[0]),
9116 TARGET_64BIT
? UNSPEC_PLT
: UNSPEC_GOT
);
9117 op
[0] = gen_rtx_CONST (Pmode
, op
[0]);
9120 /* Operand 1 is the 'this' pointer. */
9121 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
9122 op
[1] = gen_rtx_REG (Pmode
, 3);
9124 op
[1] = gen_rtx_REG (Pmode
, 2);
9126 /* Operand 2 is the delta. */
9127 op
[2] = GEN_INT (delta
);
9129 /* Operand 3 is the vcall_offset. */
9130 op
[3] = GEN_INT (vcall_offset
);
9132 /* Operand 4 is the temporary register. */
9133 op
[4] = gen_rtx_REG (Pmode
, 1);
9135 /* Operands 5 to 8 can be used as labels. */
9141 /* Operand 9 can be used for temporary register. */
9144 /* Generate code. */
9147 /* Setup literal pool pointer if required. */
9148 if ((!DISP_IN_RANGE (delta
)
9149 && !CONST_OK_FOR_K (delta
)
9150 && !CONST_OK_FOR_Os (delta
))
9151 || (!DISP_IN_RANGE (vcall_offset
)
9152 && !CONST_OK_FOR_K (vcall_offset
)
9153 && !CONST_OK_FOR_Os (vcall_offset
)))
9155 op
[5] = gen_label_rtx ();
9156 output_asm_insn ("larl\t%4,%5", op
);
9159 /* Add DELTA to this pointer. */
9162 if (CONST_OK_FOR_J (delta
))
9163 output_asm_insn ("la\t%1,%2(%1)", op
);
9164 else if (DISP_IN_RANGE (delta
))
9165 output_asm_insn ("lay\t%1,%2(%1)", op
);
9166 else if (CONST_OK_FOR_K (delta
))
9167 output_asm_insn ("aghi\t%1,%2", op
);
9168 else if (CONST_OK_FOR_Os (delta
))
9169 output_asm_insn ("agfi\t%1,%2", op
);
9172 op
[6] = gen_label_rtx ();
9173 output_asm_insn ("agf\t%1,%6-%5(%4)", op
);
9177 /* Perform vcall adjustment. */
9180 if (DISP_IN_RANGE (vcall_offset
))
9182 output_asm_insn ("lg\t%4,0(%1)", op
);
9183 output_asm_insn ("ag\t%1,%3(%4)", op
);
9185 else if (CONST_OK_FOR_K (vcall_offset
))
9187 output_asm_insn ("lghi\t%4,%3", op
);
9188 output_asm_insn ("ag\t%4,0(%1)", op
);
9189 output_asm_insn ("ag\t%1,0(%4)", op
);
9191 else if (CONST_OK_FOR_Os (vcall_offset
))
9193 output_asm_insn ("lgfi\t%4,%3", op
);
9194 output_asm_insn ("ag\t%4,0(%1)", op
);
9195 output_asm_insn ("ag\t%1,0(%4)", op
);
9199 op
[7] = gen_label_rtx ();
9200 output_asm_insn ("llgf\t%4,%7-%5(%4)", op
);
9201 output_asm_insn ("ag\t%4,0(%1)", op
);
9202 output_asm_insn ("ag\t%1,0(%4)", op
);
9206 /* Jump to target. */
9207 output_asm_insn ("jg\t%0", op
);
9209 /* Output literal pool if required. */
9212 output_asm_insn (".align\t4", op
);
9213 targetm
.asm_out
.internal_label (file
, "L",
9214 CODE_LABEL_NUMBER (op
[5]));
9218 targetm
.asm_out
.internal_label (file
, "L",
9219 CODE_LABEL_NUMBER (op
[6]));
9220 output_asm_insn (".long\t%2", op
);
9224 targetm
.asm_out
.internal_label (file
, "L",
9225 CODE_LABEL_NUMBER (op
[7]));
9226 output_asm_insn (".long\t%3", op
);
9231 /* Setup base pointer if required. */
9233 || (!DISP_IN_RANGE (delta
)
9234 && !CONST_OK_FOR_K (delta
)
9235 && !CONST_OK_FOR_Os (delta
))
9236 || (!DISP_IN_RANGE (delta
)
9237 && !CONST_OK_FOR_K (vcall_offset
)
9238 && !CONST_OK_FOR_Os (vcall_offset
)))
9240 op
[5] = gen_label_rtx ();
9241 output_asm_insn ("basr\t%4,0", op
);
9242 targetm
.asm_out
.internal_label (file
, "L",
9243 CODE_LABEL_NUMBER (op
[5]));
9246 /* Add DELTA to this pointer. */
9249 if (CONST_OK_FOR_J (delta
))
9250 output_asm_insn ("la\t%1,%2(%1)", op
);
9251 else if (DISP_IN_RANGE (delta
))
9252 output_asm_insn ("lay\t%1,%2(%1)", op
);
9253 else if (CONST_OK_FOR_K (delta
))
9254 output_asm_insn ("ahi\t%1,%2", op
);
9255 else if (CONST_OK_FOR_Os (delta
))
9256 output_asm_insn ("afi\t%1,%2", op
);
9259 op
[6] = gen_label_rtx ();
9260 output_asm_insn ("a\t%1,%6-%5(%4)", op
);
9264 /* Perform vcall adjustment. */
9267 if (CONST_OK_FOR_J (vcall_offset
))
9269 output_asm_insn ("l\t%4,0(%1)", op
);
9270 output_asm_insn ("a\t%1,%3(%4)", op
);
9272 else if (DISP_IN_RANGE (vcall_offset
))
9274 output_asm_insn ("l\t%4,0(%1)", op
);
9275 output_asm_insn ("ay\t%1,%3(%4)", op
);
9277 else if (CONST_OK_FOR_K (vcall_offset
))
9279 output_asm_insn ("lhi\t%4,%3", op
);
9280 output_asm_insn ("a\t%4,0(%1)", op
);
9281 output_asm_insn ("a\t%1,0(%4)", op
);
9283 else if (CONST_OK_FOR_Os (vcall_offset
))
9285 output_asm_insn ("iilf\t%4,%3", op
);
9286 output_asm_insn ("a\t%4,0(%1)", op
);
9287 output_asm_insn ("a\t%1,0(%4)", op
);
9291 op
[7] = gen_label_rtx ();
9292 output_asm_insn ("l\t%4,%7-%5(%4)", op
);
9293 output_asm_insn ("a\t%4,0(%1)", op
);
9294 output_asm_insn ("a\t%1,0(%4)", op
);
9297 /* We had to clobber the base pointer register.
9298 Re-setup the base pointer (with a different base). */
9299 op
[5] = gen_label_rtx ();
9300 output_asm_insn ("basr\t%4,0", op
);
9301 targetm
.asm_out
.internal_label (file
, "L",
9302 CODE_LABEL_NUMBER (op
[5]));
9305 /* Jump to target. */
9306 op
[8] = gen_label_rtx ();
9309 output_asm_insn ("l\t%4,%8-%5(%4)", op
);
9311 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
9312 /* We cannot call through .plt, since .plt requires %r12 loaded. */
9313 else if (flag_pic
== 1)
9315 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
9316 output_asm_insn ("l\t%4,%0(%4)", op
);
9318 else if (flag_pic
== 2)
9320 op
[9] = gen_rtx_REG (Pmode
, 0);
9321 output_asm_insn ("l\t%9,%8-4-%5(%4)", op
);
9322 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
9323 output_asm_insn ("ar\t%4,%9", op
);
9324 output_asm_insn ("l\t%4,0(%4)", op
);
9327 output_asm_insn ("br\t%4", op
);
9329 /* Output literal pool. */
9330 output_asm_insn (".align\t4", op
);
9332 if (nonlocal
&& flag_pic
== 2)
9333 output_asm_insn (".long\t%0", op
);
9336 op
[0] = gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
9337 SYMBOL_REF_FLAGS (op
[0]) = SYMBOL_FLAG_LOCAL
;
9340 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[8]));
9342 output_asm_insn (".long\t%0", op
);
9344 output_asm_insn (".long\t%0-%5", op
);
9348 targetm
.asm_out
.internal_label (file
, "L",
9349 CODE_LABEL_NUMBER (op
[6]));
9350 output_asm_insn (".long\t%2", op
);
9354 targetm
.asm_out
.internal_label (file
, "L",
9355 CODE_LABEL_NUMBER (op
[7]));
9356 output_asm_insn (".long\t%3", op
);
9359 final_end_function ();
9363 s390_valid_pointer_mode (enum machine_mode mode
)
9365 return (mode
== SImode
|| (TARGET_64BIT
&& mode
== DImode
));
9368 /* Checks whether the given CALL_EXPR would use a caller
9369 saved register. This is used to decide whether sibling call
9370 optimization could be performed on the respective function
9374 s390_call_saved_register_used (tree call_expr
)
9376 CUMULATIVE_ARGS cum
;
9378 enum machine_mode mode
;
9383 INIT_CUMULATIVE_ARGS (cum
, NULL
, NULL
, 0, 0);
9385 for (i
= 0; i
< call_expr_nargs (call_expr
); i
++)
9387 parameter
= CALL_EXPR_ARG (call_expr
, i
);
9388 gcc_assert (parameter
);
9390 /* For an undeclared variable passed as parameter we will get
9391 an ERROR_MARK node here. */
9392 if (TREE_CODE (parameter
) == ERROR_MARK
)
9395 type
= TREE_TYPE (parameter
);
9398 mode
= TYPE_MODE (type
);
9401 if (pass_by_reference (&cum
, mode
, type
, true))
9404 type
= build_pointer_type (type
);
9407 parm_rtx
= s390_function_arg (&cum
, mode
, type
, 0);
9409 s390_function_arg_advance (&cum
, mode
, type
, 0);
9411 if (parm_rtx
&& REG_P (parm_rtx
))
9414 reg
< HARD_REGNO_NREGS (REGNO (parm_rtx
), GET_MODE (parm_rtx
));
9416 if (! call_used_regs
[reg
+ REGNO (parm_rtx
)])
9423 /* Return true if the given call expression can be
9424 turned into a sibling call.
9425 DECL holds the declaration of the function to be called whereas
9426 EXP is the call expression itself. */
9429 s390_function_ok_for_sibcall (tree decl
, tree exp
)
9431 /* The TPF epilogue uses register 1. */
9432 if (TARGET_TPF_PROFILING
)
9435 /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
9436 which would have to be restored before the sibcall. */
9437 if (!TARGET_64BIT
&& flag_pic
&& decl
&& !targetm
.binds_local_p (decl
))
9440 /* Register 6 on s390 is available as an argument register but unfortunately
9441 "caller saved". This makes functions needing this register for arguments
9442 not suitable for sibcalls. */
9443 return !s390_call_saved_register_used (exp
);
9446 /* Return the fixed registers used for condition codes. */
9449 s390_fixed_condition_code_regs (unsigned int *p1
, unsigned int *p2
)
9452 *p2
= INVALID_REGNUM
;
9457 /* This function is used by the call expanders of the machine description.
9458 It emits the call insn itself together with the necessary operations
9459 to adjust the target address and returns the emitted insn.
9460 ADDR_LOCATION is the target address rtx
9461 TLS_CALL the location of the thread-local symbol
9462 RESULT_REG the register where the result of the call should be stored
9463 RETADDR_REG the register where the return address should be stored
9464 If this parameter is NULL_RTX the call is considered
9465 to be a sibling call. */
9468 s390_emit_call (rtx addr_location
, rtx tls_call
, rtx result_reg
,
9471 bool plt_call
= false;
9477 /* Direct function calls need special treatment. */
9478 if (GET_CODE (addr_location
) == SYMBOL_REF
)
9480 /* When calling a global routine in PIC mode, we must
9481 replace the symbol itself with the PLT stub. */
9482 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (addr_location
))
9484 addr_location
= gen_rtx_UNSPEC (Pmode
,
9485 gen_rtvec (1, addr_location
),
9487 addr_location
= gen_rtx_CONST (Pmode
, addr_location
);
9491 /* Unless we can use the bras(l) insn, force the
9492 routine address into a register. */
9493 if (!TARGET_SMALL_EXEC
&& !TARGET_CPU_ZARCH
)
9496 addr_location
= legitimize_pic_address (addr_location
, 0);
9498 addr_location
= force_reg (Pmode
, addr_location
);
9502 /* If it is already an indirect call or the code above moved the
9503 SYMBOL_REF to somewhere else make sure the address can be found in
9505 if (retaddr_reg
== NULL_RTX
9506 && GET_CODE (addr_location
) != SYMBOL_REF
9509 emit_move_insn (gen_rtx_REG (Pmode
, SIBCALL_REGNUM
), addr_location
);
9510 addr_location
= gen_rtx_REG (Pmode
, SIBCALL_REGNUM
);
9513 addr_location
= gen_rtx_MEM (QImode
, addr_location
);
9514 call
= gen_rtx_CALL (VOIDmode
, addr_location
, const0_rtx
);
9516 if (result_reg
!= NULL_RTX
)
9517 call
= gen_rtx_SET (VOIDmode
, result_reg
, call
);
9519 if (retaddr_reg
!= NULL_RTX
)
9521 clobber
= gen_rtx_CLOBBER (VOIDmode
, retaddr_reg
);
9523 if (tls_call
!= NULL_RTX
)
9524 vec
= gen_rtvec (3, call
, clobber
,
9525 gen_rtx_USE (VOIDmode
, tls_call
));
9527 vec
= gen_rtvec (2, call
, clobber
);
9529 call
= gen_rtx_PARALLEL (VOIDmode
, vec
);
9532 insn
= emit_call_insn (call
);
9534 /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
9535 if ((!TARGET_64BIT
&& plt_call
) || tls_call
!= NULL_RTX
)
9537 /* s390_function_ok_for_sibcall should
9538 have denied sibcalls in this case. */
9539 gcc_assert (retaddr_reg
!= NULL_RTX
);
9541 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), pic_offset_table_rtx
);
9546 /* Implement CONDITIONAL_REGISTER_USAGE. */
9549 s390_conditional_register_usage (void)
9555 fixed_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
9556 call_used_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
9558 if (TARGET_CPU_ZARCH
)
9560 fixed_regs
[BASE_REGNUM
] = 0;
9561 call_used_regs
[BASE_REGNUM
] = 0;
9562 fixed_regs
[RETURN_REGNUM
] = 0;
9563 call_used_regs
[RETURN_REGNUM
] = 0;
9567 for (i
= 24; i
< 32; i
++)
9568 call_used_regs
[i
] = call_really_used_regs
[i
] = 0;
9572 for (i
= 18; i
< 20; i
++)
9573 call_used_regs
[i
] = call_really_used_regs
[i
] = 0;
9576 if (TARGET_SOFT_FLOAT
)
9578 for (i
= 16; i
< 32; i
++)
9579 call_used_regs
[i
] = fixed_regs
[i
] = 1;
9583 /* Corresponding function to eh_return expander. */
9585 static GTY(()) rtx s390_tpf_eh_return_symbol
;
9587 s390_emit_tpf_eh_return (rtx target
)
9591 if (!s390_tpf_eh_return_symbol
)
9592 s390_tpf_eh_return_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "__tpf_eh_return");
9594 reg
= gen_rtx_REG (Pmode
, 2);
9596 emit_move_insn (reg
, target
);
9597 insn
= s390_emit_call (s390_tpf_eh_return_symbol
, NULL_RTX
, reg
,
9598 gen_rtx_REG (Pmode
, RETURN_REGNUM
));
9599 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), reg
);
9601 emit_move_insn (EH_RETURN_HANDLER_RTX
, reg
);
9604 /* Rework the prologue/epilogue to avoid saving/restoring
9605 registers unnecessarily. */
9608 s390_optimize_prologue (void)
9610 rtx insn
, new_insn
, next_insn
;
9612 /* Do a final recompute of the frame-related data. */
9614 s390_update_frame_layout ();
9616 /* If all special registers are in fact used, there's nothing we
9617 can do, so no point in walking the insn list. */
9619 if (cfun_frame_layout
.first_save_gpr
<= BASE_REGNUM
9620 && cfun_frame_layout
.last_save_gpr
>= BASE_REGNUM
9621 && (TARGET_CPU_ZARCH
9622 || (cfun_frame_layout
.first_save_gpr
<= RETURN_REGNUM
9623 && cfun_frame_layout
.last_save_gpr
>= RETURN_REGNUM
)))
9626 /* Search for prologue/epilogue insns and replace them. */
9628 for (insn
= get_insns (); insn
; insn
= next_insn
)
9630 int first
, last
, off
;
9631 rtx set
, base
, offset
;
9633 next_insn
= NEXT_INSN (insn
);
9635 if (GET_CODE (insn
) != INSN
)
9638 if (GET_CODE (PATTERN (insn
)) == PARALLEL
9639 && store_multiple_operation (PATTERN (insn
), VOIDmode
))
9641 set
= XVECEXP (PATTERN (insn
), 0, 0);
9642 first
= REGNO (SET_SRC (set
));
9643 last
= first
+ XVECLEN (PATTERN (insn
), 0) - 1;
9644 offset
= const0_rtx
;
9645 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
9646 off
= INTVAL (offset
);
9648 if (GET_CODE (base
) != REG
|| off
< 0)
9650 if (cfun_frame_layout
.first_save_gpr
!= -1
9651 && (cfun_frame_layout
.first_save_gpr
< first
9652 || cfun_frame_layout
.last_save_gpr
> last
))
9654 if (REGNO (base
) != STACK_POINTER_REGNUM
9655 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
9657 if (first
> BASE_REGNUM
|| last
< BASE_REGNUM
)
9660 if (cfun_frame_layout
.first_save_gpr
!= -1)
9662 new_insn
= save_gprs (base
,
9663 off
+ (cfun_frame_layout
.first_save_gpr
9664 - first
) * UNITS_PER_WORD
,
9665 cfun_frame_layout
.first_save_gpr
,
9666 cfun_frame_layout
.last_save_gpr
);
9667 new_insn
= emit_insn_before (new_insn
, insn
);
9668 INSN_ADDRESSES_NEW (new_insn
, -1);
9675 if (cfun_frame_layout
.first_save_gpr
== -1
9676 && GET_CODE (PATTERN (insn
)) == SET
9677 && GET_CODE (SET_SRC (PATTERN (insn
))) == REG
9678 && (REGNO (SET_SRC (PATTERN (insn
))) == BASE_REGNUM
9679 || (!TARGET_CPU_ZARCH
9680 && REGNO (SET_SRC (PATTERN (insn
))) == RETURN_REGNUM
))
9681 && GET_CODE (SET_DEST (PATTERN (insn
))) == MEM
)
9683 set
= PATTERN (insn
);
9684 first
= REGNO (SET_SRC (set
));
9685 offset
= const0_rtx
;
9686 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
9687 off
= INTVAL (offset
);
9689 if (GET_CODE (base
) != REG
|| off
< 0)
9691 if (REGNO (base
) != STACK_POINTER_REGNUM
9692 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
9699 if (GET_CODE (PATTERN (insn
)) == PARALLEL
9700 && load_multiple_operation (PATTERN (insn
), VOIDmode
))
9702 set
= XVECEXP (PATTERN (insn
), 0, 0);
9703 first
= REGNO (SET_DEST (set
));
9704 last
= first
+ XVECLEN (PATTERN (insn
), 0) - 1;
9705 offset
= const0_rtx
;
9706 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
9707 off
= INTVAL (offset
);
9709 if (GET_CODE (base
) != REG
|| off
< 0)
9711 if (cfun_frame_layout
.first_restore_gpr
!= -1
9712 && (cfun_frame_layout
.first_restore_gpr
< first
9713 || cfun_frame_layout
.last_restore_gpr
> last
))
9715 if (REGNO (base
) != STACK_POINTER_REGNUM
9716 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
9718 if (first
> BASE_REGNUM
|| last
< BASE_REGNUM
)
9721 if (cfun_frame_layout
.first_restore_gpr
!= -1)
9723 new_insn
= restore_gprs (base
,
9724 off
+ (cfun_frame_layout
.first_restore_gpr
9725 - first
) * UNITS_PER_WORD
,
9726 cfun_frame_layout
.first_restore_gpr
,
9727 cfun_frame_layout
.last_restore_gpr
);
9728 new_insn
= emit_insn_before (new_insn
, insn
);
9729 INSN_ADDRESSES_NEW (new_insn
, -1);
9736 if (cfun_frame_layout
.first_restore_gpr
== -1
9737 && GET_CODE (PATTERN (insn
)) == SET
9738 && GET_CODE (SET_DEST (PATTERN (insn
))) == REG
9739 && (REGNO (SET_DEST (PATTERN (insn
))) == BASE_REGNUM
9740 || (!TARGET_CPU_ZARCH
9741 && REGNO (SET_DEST (PATTERN (insn
))) == RETURN_REGNUM
))
9742 && GET_CODE (SET_SRC (PATTERN (insn
))) == MEM
)
9744 set
= PATTERN (insn
);
9745 first
= REGNO (SET_DEST (set
));
9746 offset
= const0_rtx
;
9747 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
9748 off
= INTVAL (offset
);
9750 if (GET_CODE (base
) != REG
|| off
< 0)
9752 if (REGNO (base
) != STACK_POINTER_REGNUM
9753 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
9762 /* On z10 the dynamic branch prediction must see the backward jump in
9763 a window of 384 bytes. If not it falls back to the static
9764 prediction. This function rearranges the loop backward branch in a
9765 way which makes the static prediction always correct. The function
9766 returns true if it added an instruction. */
9768 s390_z10_fix_long_loop_prediction (rtx insn
)
9770 rtx set
= single_set (insn
);
9771 rtx code_label
, label_ref
, new_label
;
9777 /* This will exclude branch on count and branch on index patterns
9778 since these are correctly statically predicted. */
9780 || SET_DEST (set
) != pc_rtx
9781 || GET_CODE (SET_SRC(set
)) != IF_THEN_ELSE
)
9784 label_ref
= (GET_CODE (XEXP (SET_SRC (set
), 1)) == LABEL_REF
?
9785 XEXP (SET_SRC (set
), 1) : XEXP (SET_SRC (set
), 2));
9787 gcc_assert (GET_CODE (label_ref
) == LABEL_REF
);
9789 code_label
= XEXP (label_ref
, 0);
9791 if (INSN_ADDRESSES (INSN_UID (code_label
)) == -1
9792 || INSN_ADDRESSES (INSN_UID (insn
)) == -1
9793 || (INSN_ADDRESSES (INSN_UID (insn
))
9794 - INSN_ADDRESSES (INSN_UID (code_label
)) < Z10_PREDICT_DISTANCE
))
9797 for (distance
= 0, cur_insn
= PREV_INSN (insn
);
9798 distance
< Z10_PREDICT_DISTANCE
- 6;
9799 distance
+= get_attr_length (cur_insn
), cur_insn
= PREV_INSN (cur_insn
))
9800 if (!cur_insn
|| JUMP_P (cur_insn
) || LABEL_P (cur_insn
))
9803 new_label
= gen_label_rtx ();
9804 uncond_jump
= emit_jump_insn_after (
9805 gen_rtx_SET (VOIDmode
, pc_rtx
,
9806 gen_rtx_LABEL_REF (VOIDmode
, code_label
)),
9808 emit_label_after (new_label
, uncond_jump
);
9810 tmp
= XEXP (SET_SRC (set
), 1);
9811 XEXP (SET_SRC (set
), 1) = XEXP (SET_SRC (set
), 2);
9812 XEXP (SET_SRC (set
), 2) = tmp
;
9813 INSN_CODE (insn
) = -1;
9815 XEXP (label_ref
, 0) = new_label
;
9816 JUMP_LABEL (insn
) = new_label
;
9817 JUMP_LABEL (uncond_jump
) = code_label
;
9822 /* Returns 1 if INSN reads the value of REG for purposes not related
9823 to addressing of memory, and 0 otherwise. */
9825 s390_non_addr_reg_read_p (rtx reg
, rtx insn
)
9827 return reg_referenced_p (reg
, PATTERN (insn
))
9828 && !reg_used_in_mem_p (REGNO (reg
), PATTERN (insn
));
9831 /* Starting from INSN find_cond_jump looks downwards in the insn
9832 stream for a single jump insn which is the last user of the
9833 condition code set in INSN. */
9835 find_cond_jump (rtx insn
)
9837 for (; insn
; insn
= NEXT_INSN (insn
))
9846 if (reg_mentioned_p (gen_rtx_REG (CCmode
, CC_REGNUM
), insn
))
9851 /* This will be triggered by a return. */
9852 if (GET_CODE (PATTERN (insn
)) != SET
)
9855 gcc_assert (SET_DEST (PATTERN (insn
)) == pc_rtx
);
9856 ite
= SET_SRC (PATTERN (insn
));
9858 if (GET_CODE (ite
) != IF_THEN_ELSE
)
9861 cc
= XEXP (XEXP (ite
, 0), 0);
9862 if (!REG_P (cc
) || !CC_REGNO_P (REGNO (cc
)))
9865 if (find_reg_note (insn
, REG_DEAD
, cc
))
9873 /* Swap the condition in COND and the operands in OP0 and OP1 so that
9874 the semantics does not change. If NULL_RTX is passed as COND the
9875 function tries to find the conditional jump starting with INSN. */
9877 s390_swap_cmp (rtx cond
, rtx
*op0
, rtx
*op1
, rtx insn
)
9881 if (cond
== NULL_RTX
)
9883 rtx jump
= find_cond_jump (NEXT_INSN (insn
));
9884 jump
= jump
? single_set (jump
) : NULL_RTX
;
9886 if (jump
== NULL_RTX
)
9889 cond
= XEXP (XEXP (jump
, 1), 0);
9894 PUT_CODE (cond
, swap_condition (GET_CODE (cond
)));
9897 /* On z10, instructions of the compare-and-branch family have the
9898 property to access the register occurring as second operand with
9899 its bits complemented. If such a compare is grouped with a second
9900 instruction that accesses the same register non-complemented, and
9901 if that register's value is delivered via a bypass, then the
9902 pipeline recycles, thereby causing significant performance decline.
9903 This function locates such situations and exchanges the two
9904 operands of the compare. The function return true whenever it
9907 s390_z10_optimize_cmp (rtx insn
)
9909 rtx prev_insn
, next_insn
;
9910 bool insn_added_p
= false;
9911 rtx cond
, *op0
, *op1
;
9913 if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
9915 /* Handle compare and branch and branch on count
9917 rtx pattern
= single_set (insn
);
9920 || SET_DEST (pattern
) != pc_rtx
9921 || GET_CODE (SET_SRC (pattern
)) != IF_THEN_ELSE
)
9924 cond
= XEXP (SET_SRC (pattern
), 0);
9925 op0
= &XEXP (cond
, 0);
9926 op1
= &XEXP (cond
, 1);
9928 else if (GET_CODE (PATTERN (insn
)) == SET
)
9932 /* Handle normal compare instructions. */
9933 src
= SET_SRC (PATTERN (insn
));
9934 dest
= SET_DEST (PATTERN (insn
));
9937 || !CC_REGNO_P (REGNO (dest
))
9938 || GET_CODE (src
) != COMPARE
)
9941 /* s390_swap_cmp will try to find the conditional
9942 jump when passing NULL_RTX as condition. */
9944 op0
= &XEXP (src
, 0);
9945 op1
= &XEXP (src
, 1);
9950 if (!REG_P (*op0
) || !REG_P (*op1
))
9953 if (GET_MODE_CLASS (GET_MODE (*op0
)) != MODE_INT
)
9956 /* Swap the COMPARE arguments and its mask if there is a
9957 conflicting access in the previous insn. */
9958 prev_insn
= prev_active_insn (insn
);
9959 if (prev_insn
!= NULL_RTX
&& INSN_P (prev_insn
)
9960 && reg_referenced_p (*op1
, PATTERN (prev_insn
)))
9961 s390_swap_cmp (cond
, op0
, op1
, insn
);
9963 /* Check if there is a conflict with the next insn. If there
9964 was no conflict with the previous insn, then swap the
9965 COMPARE arguments and its mask. If we already swapped
9966 the operands, or if swapping them would cause a conflict
9967 with the previous insn, issue a NOP after the COMPARE in
9968 order to separate the two instuctions. */
9969 next_insn
= next_active_insn (insn
);
9970 if (next_insn
!= NULL_RTX
&& INSN_P (next_insn
)
9971 && s390_non_addr_reg_read_p (*op1
, next_insn
))
9973 if (prev_insn
!= NULL_RTX
&& INSN_P (prev_insn
)
9974 && s390_non_addr_reg_read_p (*op0
, prev_insn
))
9976 if (REGNO (*op1
) == 0)
9977 emit_insn_after (gen_nop1 (), insn
);
9979 emit_insn_after (gen_nop (), insn
);
9980 insn_added_p
= true;
9983 s390_swap_cmp (cond
, op0
, op1
, insn
);
9985 return insn_added_p
;
9988 /* Perform machine-dependent processing. */
9993 bool pool_overflow
= false;
9995 /* Make sure all splits have been performed; splits after
9996 machine_dependent_reorg might confuse insn length counts. */
9997 split_all_insns_noflow ();
9999 /* Install the main literal pool and the associated base
10000 register load insns.
10002 In addition, there are two problematic situations we need
10005 - the literal pool might be > 4096 bytes in size, so that
10006 some of its elements cannot be directly accessed
10008 - a branch target might be > 64K away from the branch, so that
10009 it is not possible to use a PC-relative instruction.
10011 To fix those, we split the single literal pool into multiple
10012 pool chunks, reloading the pool base register at various
10013 points throughout the function to ensure it always points to
10014 the pool chunk the following code expects, and / or replace
10015 PC-relative branches by absolute branches.
10017 However, the two problems are interdependent: splitting the
10018 literal pool can move a branch further away from its target,
10019 causing the 64K limit to overflow, and on the other hand,
10020 replacing a PC-relative branch by an absolute branch means
10021 we need to put the branch target address into the literal
10022 pool, possibly causing it to overflow.
10024 So, we loop trying to fix up both problems until we manage
10025 to satisfy both conditions at the same time. Note that the
10026 loop is guaranteed to terminate as every pass of the loop
10027 strictly decreases the total number of PC-relative branches
10028 in the function. (This is not completely true as there
10029 might be branch-over-pool insns introduced by chunkify_start.
10030 Those never need to be split however.) */
10034 struct constant_pool
*pool
= NULL
;
10036 /* Collect the literal pool. */
10037 if (!pool_overflow
)
10039 pool
= s390_mainpool_start ();
10041 pool_overflow
= true;
10044 /* If literal pool overflowed, start to chunkify it. */
10046 pool
= s390_chunkify_start ();
10048 /* Split out-of-range branches. If this has created new
10049 literal pool entries, cancel current chunk list and
10050 recompute it. zSeries machines have large branch
10051 instructions, so we never need to split a branch. */
10052 if (!TARGET_CPU_ZARCH
&& s390_split_branches ())
10055 s390_chunkify_cancel (pool
);
10057 s390_mainpool_cancel (pool
);
10062 /* If we made it up to here, both conditions are satisfied.
10063 Finish up literal pool related changes. */
10065 s390_chunkify_finish (pool
);
10067 s390_mainpool_finish (pool
);
10069 /* We're done splitting branches. */
10070 cfun
->machine
->split_branches_pending_p
= false;
10074 /* Generate out-of-pool execute target insns. */
10075 if (TARGET_CPU_ZARCH
)
10077 rtx insn
, label
, target
;
10079 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
10081 label
= s390_execute_label (insn
);
10085 gcc_assert (label
!= const0_rtx
);
10087 target
= emit_label (XEXP (label
, 0));
10088 INSN_ADDRESSES_NEW (target
, -1);
10090 target
= emit_insn (s390_execute_target (insn
));
10091 INSN_ADDRESSES_NEW (target
, -1);
10095 /* Try to optimize prologue and epilogue further. */
10096 s390_optimize_prologue ();
10098 /* Walk over the insns and do some z10 specific changes. */
10099 if (s390_tune
== PROCESSOR_2097_Z10
)
10102 bool insn_added_p
= false;
10104 /* The insn lengths and addresses have to be up to date for the
10105 following manipulations. */
10106 shorten_branches (get_insns ());
10108 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
10110 if (!INSN_P (insn
) || INSN_CODE (insn
) <= 0)
10114 insn_added_p
|= s390_z10_fix_long_loop_prediction (insn
);
10116 if (GET_CODE (PATTERN (insn
)) == PARALLEL
10117 || GET_CODE (PATTERN (insn
)) == SET
)
10118 insn_added_p
|= s390_z10_optimize_cmp (insn
);
10121 /* Adjust branches if we added new instructions. */
10123 shorten_branches (get_insns ());
10127 /* Return true if INSN is a fp load insn writing register REGNO. */
10129 s390_fpload_toreg (rtx insn
, unsigned int regno
)
10132 enum attr_type flag
= s390_safe_attr_type (insn
);
10134 if (flag
!= TYPE_FLOADSF
&& flag
!= TYPE_FLOADDF
)
10137 set
= single_set (insn
);
10139 if (set
== NULL_RTX
)
10142 if (!REG_P (SET_DEST (set
)) || !MEM_P (SET_SRC (set
)))
10145 if (REGNO (SET_DEST (set
)) != regno
)
10151 /* This value describes the distance to be avoided between an
10152 aritmetic fp instruction and an fp load writing the same register.
10153 Z10_EARLYLOAD_DISTANCE - 1 as well as Z10_EARLYLOAD_DISTANCE + 1 is
10154 fine but the exact value has to be avoided. Otherwise the FP
10155 pipeline will throw an exception causing a major penalty. */
10156 #define Z10_EARLYLOAD_DISTANCE 7
10158 /* Rearrange the ready list in order to avoid the situation described
10159 for Z10_EARLYLOAD_DISTANCE. A problematic load instruction is
10160 moved to the very end of the ready list. */
10162 s390_z10_prevent_earlyload_conflicts (rtx
*ready
, int *nready_p
)
10164 unsigned int regno
;
10165 int nready
= *nready_p
;
10170 enum attr_type flag
;
10173 /* Skip DISTANCE - 1 active insns. */
10174 for (insn
= last_scheduled_insn
, distance
= Z10_EARLYLOAD_DISTANCE
- 1;
10175 distance
> 0 && insn
!= NULL_RTX
;
10176 distance
--, insn
= prev_active_insn (insn
))
10177 if (CALL_P (insn
) || JUMP_P (insn
))
10180 if (insn
== NULL_RTX
)
10183 set
= single_set (insn
);
10185 if (set
== NULL_RTX
|| !REG_P (SET_DEST (set
))
10186 || GET_MODE_CLASS (GET_MODE (SET_DEST (set
))) != MODE_FLOAT
)
10189 flag
= s390_safe_attr_type (insn
);
10191 if (flag
== TYPE_FLOADSF
|| flag
== TYPE_FLOADDF
)
10194 regno
= REGNO (SET_DEST (set
));
10197 while (!s390_fpload_toreg (ready
[i
], regno
) && i
> 0)
10204 memmove (&ready
[1], &ready
[0], sizeof (rtx
) * i
);
10208 /* This function is called via hook TARGET_SCHED_REORDER before
10209 issueing one insn from list READY which contains *NREADYP entries.
10210 For target z10 it reorders load instructions to avoid early load
10211 conflicts in the floating point pipeline */
10213 s390_sched_reorder (FILE *file ATTRIBUTE_UNUSED
, int verbose ATTRIBUTE_UNUSED
,
10214 rtx
*ready
, int *nreadyp
, int clock ATTRIBUTE_UNUSED
)
10216 if (s390_tune
== PROCESSOR_2097_Z10
)
10217 if (reload_completed
&& *nreadyp
> 1)
10218 s390_z10_prevent_earlyload_conflicts (ready
, nreadyp
);
10220 return s390_issue_rate ();
10223 /* This function is called via hook TARGET_SCHED_VARIABLE_ISSUE after
10224 the scheduler has issued INSN. It stores the last issued insn into
10225 last_scheduled_insn in order to make it available for
10226 s390_sched_reorder. */
10228 s390_sched_variable_issue (FILE *file ATTRIBUTE_UNUSED
,
10229 int verbose ATTRIBUTE_UNUSED
,
10230 rtx insn
, int more
)
10232 last_scheduled_insn
= insn
;
10234 if (GET_CODE (PATTERN (insn
)) != USE
10235 && GET_CODE (PATTERN (insn
)) != CLOBBER
)
10242 s390_sched_init (FILE *file ATTRIBUTE_UNUSED
,
10243 int verbose ATTRIBUTE_UNUSED
,
10244 int max_ready ATTRIBUTE_UNUSED
)
10246 last_scheduled_insn
= NULL_RTX
;
10249 /* This function checks the whole of insn X for memory references. The
10250 function always returns zero because the framework it is called
10251 from would stop recursively analyzing the insn upon a return value
10252 other than zero. The real result of this function is updating
10253 counter variable MEM_COUNT. */
10255 check_dpu (rtx
*x
, unsigned *mem_count
)
10257 if (*x
!= NULL_RTX
&& MEM_P (*x
))
10262 /* This target hook implementation for TARGET_LOOP_UNROLL_ADJUST calculates
10263 a new number struct loop *loop should be unrolled if tuned for the z10
10264 cpu. The loop is analyzed for memory accesses by calling check_dpu for
10265 each rtx of the loop. Depending on the loop_depth and the amount of
10266 memory accesses a new number <=nunroll is returned to improve the
10267 behaviour of the hardware prefetch unit. */
10269 s390_loop_unroll_adjust (unsigned nunroll
, struct loop
*loop
)
10274 unsigned mem_count
= 0;
10276 /* Only z10 needs special handling. */
10277 if (s390_tune
!= PROCESSOR_2097_Z10
)
10280 /* Count the number of memory references within the loop body. */
10281 bbs
= get_loop_body (loop
);
10282 for (i
= 0; i
< loop
->num_nodes
; i
++)
10284 for (insn
= BB_HEAD (bbs
[i
]); insn
!= BB_END (bbs
[i
]); insn
= NEXT_INSN (insn
))
10285 if (INSN_P (insn
) && INSN_CODE (insn
) != -1)
10286 for_each_rtx (&insn
, (rtx_function
) check_dpu
, &mem_count
);
10290 /* Prevent division by zero, and we do not need to adjust nunroll in this case. */
10291 if (mem_count
== 0)
10294 switch (loop_depth(loop
))
10297 return MIN (nunroll
, 28 / mem_count
);
10299 return MIN (nunroll
, 22 / mem_count
);
10301 return MIN (nunroll
, 16 / mem_count
);
10305 /* Initialize GCC target structure. */
10307 #undef TARGET_ASM_ALIGNED_HI_OP
10308 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
10309 #undef TARGET_ASM_ALIGNED_DI_OP
10310 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
10311 #undef TARGET_ASM_INTEGER
10312 #define TARGET_ASM_INTEGER s390_assemble_integer
10314 #undef TARGET_ASM_OPEN_PAREN
10315 #define TARGET_ASM_OPEN_PAREN ""
10317 #undef TARGET_ASM_CLOSE_PAREN
10318 #define TARGET_ASM_CLOSE_PAREN ""
10320 #undef TARGET_DEFAULT_TARGET_FLAGS
10321 #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD)
10322 #undef TARGET_HANDLE_OPTION
10323 #define TARGET_HANDLE_OPTION s390_handle_option
10325 #undef TARGET_ENCODE_SECTION_INFO
10326 #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
10329 #undef TARGET_HAVE_TLS
10330 #define TARGET_HAVE_TLS true
10332 #undef TARGET_CANNOT_FORCE_CONST_MEM
10333 #define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
10335 #undef TARGET_DELEGITIMIZE_ADDRESS
10336 #define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
10338 #undef TARGET_LEGITIMIZE_ADDRESS
10339 #define TARGET_LEGITIMIZE_ADDRESS s390_legitimize_address
10341 #undef TARGET_RETURN_IN_MEMORY
10342 #define TARGET_RETURN_IN_MEMORY s390_return_in_memory
10344 #undef TARGET_INIT_BUILTINS
10345 #define TARGET_INIT_BUILTINS s390_init_builtins
10346 #undef TARGET_EXPAND_BUILTIN
10347 #define TARGET_EXPAND_BUILTIN s390_expand_builtin
10349 #undef TARGET_ASM_OUTPUT_MI_THUNK
10350 #define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
10351 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
10352 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
10354 #undef TARGET_SCHED_ADJUST_PRIORITY
10355 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
10356 #undef TARGET_SCHED_ISSUE_RATE
10357 #define TARGET_SCHED_ISSUE_RATE s390_issue_rate
10358 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
10359 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
10361 #undef TARGET_SCHED_VARIABLE_ISSUE
10362 #define TARGET_SCHED_VARIABLE_ISSUE s390_sched_variable_issue
10363 #undef TARGET_SCHED_REORDER
10364 #define TARGET_SCHED_REORDER s390_sched_reorder
10365 #undef TARGET_SCHED_INIT
10366 #define TARGET_SCHED_INIT s390_sched_init
10368 #undef TARGET_CANNOT_COPY_INSN_P
10369 #define TARGET_CANNOT_COPY_INSN_P s390_cannot_copy_insn_p
10370 #undef TARGET_RTX_COSTS
10371 #define TARGET_RTX_COSTS s390_rtx_costs
10372 #undef TARGET_ADDRESS_COST
10373 #define TARGET_ADDRESS_COST s390_address_cost
10375 #undef TARGET_MACHINE_DEPENDENT_REORG
10376 #define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
10378 #undef TARGET_VALID_POINTER_MODE
10379 #define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
10381 #undef TARGET_BUILD_BUILTIN_VA_LIST
10382 #define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
10383 #undef TARGET_EXPAND_BUILTIN_VA_START
10384 #define TARGET_EXPAND_BUILTIN_VA_START s390_va_start
10385 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
10386 #define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg
10388 #undef TARGET_PROMOTE_FUNCTION_MODE
10389 #define TARGET_PROMOTE_FUNCTION_MODE s390_promote_function_mode
10390 #undef TARGET_PASS_BY_REFERENCE
10391 #define TARGET_PASS_BY_REFERENCE s390_pass_by_reference
10393 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
10394 #define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
10396 #undef TARGET_FIXED_CONDITION_CODE_REGS
10397 #define TARGET_FIXED_CONDITION_CODE_REGS s390_fixed_condition_code_regs
10399 #undef TARGET_CC_MODES_COMPATIBLE
10400 #define TARGET_CC_MODES_COMPATIBLE s390_cc_modes_compatible
10402 #undef TARGET_INVALID_WITHIN_DOLOOP
10403 #define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_const_rtx_null
10406 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
10407 #define TARGET_ASM_OUTPUT_DWARF_DTPREL s390_output_dwarf_dtprel
10410 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
10411 #undef TARGET_MANGLE_TYPE
10412 #define TARGET_MANGLE_TYPE s390_mangle_type
10415 #undef TARGET_SCALAR_MODE_SUPPORTED_P
10416 #define TARGET_SCALAR_MODE_SUPPORTED_P s390_scalar_mode_supported_p
10418 #undef TARGET_SECONDARY_RELOAD
10419 #define TARGET_SECONDARY_RELOAD s390_secondary_reload
10421 #undef TARGET_LIBGCC_CMP_RETURN_MODE
10422 #define TARGET_LIBGCC_CMP_RETURN_MODE s390_libgcc_cmp_return_mode
10424 #undef TARGET_LIBGCC_SHIFT_COUNT_MODE
10425 #define TARGET_LIBGCC_SHIFT_COUNT_MODE s390_libgcc_shift_count_mode
10427 #undef TARGET_LEGITIMATE_ADDRESS_P
10428 #define TARGET_LEGITIMATE_ADDRESS_P s390_legitimate_address_p
10430 #undef TARGET_CAN_ELIMINATE
10431 #define TARGET_CAN_ELIMINATE s390_can_eliminate
10433 #undef TARGET_LOOP_UNROLL_ADJUST
10434 #define TARGET_LOOP_UNROLL_ADJUST s390_loop_unroll_adjust
10436 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
10437 #define TARGET_ASM_TRAMPOLINE_TEMPLATE s390_asm_trampoline_template
10438 #undef TARGET_TRAMPOLINE_INIT
10439 #define TARGET_TRAMPOLINE_INIT s390_trampoline_init
10441 struct gcc_target targetm
= TARGET_INITIALIZER
;
10443 #include "gt-s390.h"