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_LONG)
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 static enum machine_mode
369 s390_unwind_word_mode (void)
371 return TARGET_64BIT
? DImode
: SImode
;
374 /* Return true if the back end supports mode MODE. */
376 s390_scalar_mode_supported_p (enum machine_mode mode
)
378 /* In contrast to the default implementation reject TImode constants on 31bit
379 TARGET_ZARCH for ABI compliance. */
380 if (!TARGET_64BIT
&& TARGET_ZARCH
&& mode
== TImode
)
383 if (DECIMAL_FLOAT_MODE_P (mode
))
384 return default_decimal_float_supported_p ();
386 return default_scalar_mode_supported_p (mode
);
389 /* Set the has_landing_pad_p flag in struct machine_function to VALUE. */
392 s390_set_has_landing_pad_p (bool value
)
394 cfun
->machine
->has_landing_pad_p
= value
;
397 /* If two condition code modes are compatible, return a condition code
398 mode which is compatible with both. Otherwise, return
401 static enum machine_mode
402 s390_cc_modes_compatible (enum machine_mode m1
, enum machine_mode m2
)
410 if (m2
== CCUmode
|| m2
== CCTmode
|| m2
== CCZ1mode
411 || m2
== CCSmode
|| m2
== CCSRmode
|| m2
== CCURmode
)
432 /* Return true if SET either doesn't set the CC register, or else
433 the source and destination have matching CC modes and that
434 CC mode is at least as constrained as REQ_MODE. */
437 s390_match_ccmode_set (rtx set
, enum machine_mode req_mode
)
439 enum machine_mode set_mode
;
441 gcc_assert (GET_CODE (set
) == SET
);
443 if (GET_CODE (SET_DEST (set
)) != REG
|| !CC_REGNO_P (REGNO (SET_DEST (set
))))
446 set_mode
= GET_MODE (SET_DEST (set
));
460 if (req_mode
!= set_mode
)
465 if (req_mode
!= CCSmode
&& req_mode
!= CCUmode
&& req_mode
!= CCTmode
466 && req_mode
!= CCSRmode
&& req_mode
!= CCURmode
)
472 if (req_mode
!= CCAmode
)
480 return (GET_MODE (SET_SRC (set
)) == set_mode
);
483 /* Return true if every SET in INSN that sets the CC register
484 has source and destination with matching CC modes and that
485 CC mode is at least as constrained as REQ_MODE.
486 If REQ_MODE is VOIDmode, always return false. */
489 s390_match_ccmode (rtx insn
, enum machine_mode req_mode
)
493 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
494 if (req_mode
== VOIDmode
)
497 if (GET_CODE (PATTERN (insn
)) == SET
)
498 return s390_match_ccmode_set (PATTERN (insn
), req_mode
);
500 if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
501 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
503 rtx set
= XVECEXP (PATTERN (insn
), 0, i
);
504 if (GET_CODE (set
) == SET
)
505 if (!s390_match_ccmode_set (set
, req_mode
))
512 /* If a test-under-mask instruction can be used to implement
513 (compare (and ... OP1) OP2), return the CC mode required
514 to do that. Otherwise, return VOIDmode.
515 MIXED is true if the instruction can distinguish between
516 CC1 and CC2 for mixed selected bits (TMxx), it is false
517 if the instruction cannot (TM). */
520 s390_tm_ccmode (rtx op1
, rtx op2
, bool mixed
)
524 /* ??? Fixme: should work on CONST_DOUBLE as well. */
525 if (GET_CODE (op1
) != CONST_INT
|| GET_CODE (op2
) != CONST_INT
)
528 /* Selected bits all zero: CC0.
529 e.g.: int a; if ((a & (16 + 128)) == 0) */
530 if (INTVAL (op2
) == 0)
533 /* Selected bits all one: CC3.
534 e.g.: int a; if ((a & (16 + 128)) == 16 + 128) */
535 if (INTVAL (op2
) == INTVAL (op1
))
538 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. e.g.:
540 if ((a & (16 + 128)) == 16) -> CCT1
541 if ((a & (16 + 128)) == 128) -> CCT2 */
544 bit1
= exact_log2 (INTVAL (op2
));
545 bit0
= exact_log2 (INTVAL (op1
) ^ INTVAL (op2
));
546 if (bit0
!= -1 && bit1
!= -1)
547 return bit0
> bit1
? CCT1mode
: CCT2mode
;
553 /* Given a comparison code OP (EQ, NE, etc.) and the operands
554 OP0 and OP1 of a COMPARE, return the mode to be used for the
558 s390_select_ccmode (enum rtx_code code
, rtx op0
, rtx op1
)
564 if ((GET_CODE (op0
) == NEG
|| GET_CODE (op0
) == ABS
)
565 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
567 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
568 && CONST_OK_FOR_K (INTVAL (XEXP (op0
, 1))))
570 if ((GET_CODE (op0
) == PLUS
|| GET_CODE (op0
) == MINUS
571 || GET_CODE (op1
) == NEG
)
572 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
575 if (GET_CODE (op0
) == AND
)
577 /* Check whether we can potentially do it via TM. */
578 enum machine_mode ccmode
;
579 ccmode
= s390_tm_ccmode (XEXP (op0
, 1), op1
, 1);
580 if (ccmode
!= VOIDmode
)
582 /* Relax CCTmode to CCZmode to allow fall-back to AND
583 if that turns out to be beneficial. */
584 return ccmode
== CCTmode
? CCZmode
: ccmode
;
588 if (register_operand (op0
, HImode
)
589 && GET_CODE (op1
) == CONST_INT
590 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 65535))
592 if (register_operand (op0
, QImode
)
593 && GET_CODE (op1
) == CONST_INT
594 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 255))
603 /* The only overflow condition of NEG and ABS happens when
604 -INT_MAX is used as parameter, which stays negative. So
605 we have an overflow from a positive value to a negative.
606 Using CCAP mode the resulting cc can be used for comparisons. */
607 if ((GET_CODE (op0
) == NEG
|| GET_CODE (op0
) == ABS
)
608 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
611 /* If constants are involved in an add instruction it is possible to use
612 the resulting cc for comparisons with zero. Knowing the sign of the
613 constant the overflow behavior gets predictable. e.g.:
614 int a, b; if ((b = a + c) > 0)
615 with c as a constant value: c < 0 -> CCAN and c >= 0 -> CCAP */
616 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
617 && CONST_OK_FOR_K (INTVAL (XEXP (op0
, 1))))
619 if (INTVAL (XEXP((op0
), 1)) < 0)
633 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
634 && GET_CODE (op1
) != CONST_INT
)
640 if (GET_CODE (op0
) == PLUS
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
)
651 if (GET_CODE (op0
) == MINUS
652 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
655 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
656 && GET_CODE (op1
) != CONST_INT
)
665 /* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
666 that we can implement more efficiently. */
669 s390_canonicalize_comparison (enum rtx_code
*code
, rtx
*op0
, rtx
*op1
)
671 /* Convert ZERO_EXTRACT back to AND to enable TM patterns. */
672 if ((*code
== EQ
|| *code
== NE
)
673 && *op1
== const0_rtx
674 && GET_CODE (*op0
) == ZERO_EXTRACT
675 && GET_CODE (XEXP (*op0
, 1)) == CONST_INT
676 && GET_CODE (XEXP (*op0
, 2)) == CONST_INT
677 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0
, 0))))
679 rtx inner
= XEXP (*op0
, 0);
680 HOST_WIDE_INT modesize
= GET_MODE_BITSIZE (GET_MODE (inner
));
681 HOST_WIDE_INT len
= INTVAL (XEXP (*op0
, 1));
682 HOST_WIDE_INT pos
= INTVAL (XEXP (*op0
, 2));
684 if (len
> 0 && len
< modesize
685 && pos
>= 0 && pos
+ len
<= modesize
686 && modesize
<= HOST_BITS_PER_WIDE_INT
)
688 unsigned HOST_WIDE_INT block
;
689 block
= ((unsigned HOST_WIDE_INT
) 1 << len
) - 1;
690 block
<<= modesize
- pos
- len
;
692 *op0
= gen_rtx_AND (GET_MODE (inner
), inner
,
693 gen_int_mode (block
, GET_MODE (inner
)));
697 /* Narrow AND of memory against immediate to enable TM. */
698 if ((*code
== EQ
|| *code
== NE
)
699 && *op1
== const0_rtx
700 && GET_CODE (*op0
) == AND
701 && GET_CODE (XEXP (*op0
, 1)) == CONST_INT
702 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0
, 0))))
704 rtx inner
= XEXP (*op0
, 0);
705 rtx mask
= XEXP (*op0
, 1);
707 /* Ignore paradoxical SUBREGs if all extra bits are masked out. */
708 if (GET_CODE (inner
) == SUBREG
709 && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (inner
)))
710 && (GET_MODE_SIZE (GET_MODE (inner
))
711 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner
))))
713 & GET_MODE_MASK (GET_MODE (inner
))
714 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (inner
))))
716 inner
= SUBREG_REG (inner
);
718 /* Do not change volatile MEMs. */
719 if (MEM_P (inner
) && !MEM_VOLATILE_P (inner
))
721 int part
= s390_single_part (XEXP (*op0
, 1),
722 GET_MODE (inner
), QImode
, 0);
725 mask
= gen_int_mode (s390_extract_part (mask
, QImode
, 0), QImode
);
726 inner
= adjust_address_nv (inner
, QImode
, part
);
727 *op0
= gen_rtx_AND (QImode
, inner
, mask
);
732 /* Narrow comparisons against 0xffff to HImode if possible. */
733 if ((*code
== EQ
|| *code
== NE
)
734 && GET_CODE (*op1
) == CONST_INT
735 && INTVAL (*op1
) == 0xffff
736 && SCALAR_INT_MODE_P (GET_MODE (*op0
))
737 && (nonzero_bits (*op0
, GET_MODE (*op0
))
738 & ~(unsigned HOST_WIDE_INT
) 0xffff) == 0)
740 *op0
= gen_lowpart (HImode
, *op0
);
744 /* Remove redundant UNSPEC_CCU_TO_INT conversions if possible. */
745 if (GET_CODE (*op0
) == UNSPEC
746 && XINT (*op0
, 1) == UNSPEC_CCU_TO_INT
747 && XVECLEN (*op0
, 0) == 1
748 && GET_MODE (XVECEXP (*op0
, 0, 0)) == CCUmode
749 && GET_CODE (XVECEXP (*op0
, 0, 0)) == REG
750 && REGNO (XVECEXP (*op0
, 0, 0)) == CC_REGNUM
751 && *op1
== const0_rtx
)
753 enum rtx_code new_code
= UNKNOWN
;
756 case EQ
: new_code
= EQ
; break;
757 case NE
: new_code
= NE
; break;
758 case LT
: new_code
= GTU
; break;
759 case GT
: new_code
= LTU
; break;
760 case LE
: new_code
= GEU
; break;
761 case GE
: new_code
= LEU
; break;
765 if (new_code
!= UNKNOWN
)
767 *op0
= XVECEXP (*op0
, 0, 0);
772 /* Remove redundant UNSPEC_CCZ_TO_INT conversions if possible. */
773 if (GET_CODE (*op0
) == UNSPEC
774 && XINT (*op0
, 1) == UNSPEC_CCZ_TO_INT
775 && XVECLEN (*op0
, 0) == 1
776 && GET_MODE (XVECEXP (*op0
, 0, 0)) == CCZmode
777 && GET_CODE (XVECEXP (*op0
, 0, 0)) == REG
778 && REGNO (XVECEXP (*op0
, 0, 0)) == CC_REGNUM
779 && *op1
== const0_rtx
)
781 enum rtx_code new_code
= UNKNOWN
;
784 case EQ
: new_code
= EQ
; break;
785 case NE
: new_code
= NE
; break;
789 if (new_code
!= UNKNOWN
)
791 *op0
= XVECEXP (*op0
, 0, 0);
796 /* Simplify cascaded EQ, NE with const0_rtx. */
797 if ((*code
== NE
|| *code
== EQ
)
798 && (GET_CODE (*op0
) == EQ
|| GET_CODE (*op0
) == NE
)
799 && GET_MODE (*op0
) == SImode
800 && GET_MODE (XEXP (*op0
, 0)) == CCZ1mode
801 && REG_P (XEXP (*op0
, 0))
802 && XEXP (*op0
, 1) == const0_rtx
803 && *op1
== const0_rtx
)
805 if ((*code
== EQ
&& GET_CODE (*op0
) == NE
)
806 || (*code
== NE
&& GET_CODE (*op0
) == EQ
))
810 *op0
= XEXP (*op0
, 0);
813 /* Prefer register over memory as first operand. */
814 if (MEM_P (*op0
) && REG_P (*op1
))
816 rtx tem
= *op0
; *op0
= *op1
; *op1
= tem
;
817 *code
= swap_condition (*code
);
821 /* Emit a compare instruction suitable to implement the comparison
822 OP0 CODE OP1. Return the correct condition RTL to be placed in
823 the IF_THEN_ELSE of the conditional branch testing the result. */
826 s390_emit_compare (enum rtx_code code
, rtx op0
, rtx op1
)
828 enum machine_mode mode
= s390_select_ccmode (code
, op0
, op1
);
831 /* Do not output a redundant compare instruction if a compare_and_swap
832 pattern already computed the result and the machine modes are compatible. */
833 if (GET_MODE_CLASS (GET_MODE (op0
)) == MODE_CC
)
835 gcc_assert (s390_cc_modes_compatible (GET_MODE (op0
), mode
)
841 cc
= gen_rtx_REG (mode
, CC_REGNUM
);
842 emit_insn (gen_rtx_SET (VOIDmode
, cc
, gen_rtx_COMPARE (mode
, op0
, op1
)));
845 return gen_rtx_fmt_ee (code
, VOIDmode
, cc
, const0_rtx
);
848 /* Emit a SImode compare and swap instruction setting MEM to NEW_RTX if OLD
850 Return the correct condition RTL to be placed in the IF_THEN_ELSE of the
851 conditional branch testing the result. */
854 s390_emit_compare_and_swap (enum rtx_code code
, rtx old
, rtx mem
, rtx cmp
, rtx new_rtx
)
856 emit_insn (gen_sync_compare_and_swapsi (old
, mem
, cmp
, new_rtx
));
857 return s390_emit_compare (code
, gen_rtx_REG (CCZ1mode
, CC_REGNUM
), const0_rtx
);
860 /* Emit a jump instruction to TARGET. If COND is NULL_RTX, emit an
861 unconditional jump, else a conditional jump under condition COND. */
864 s390_emit_jump (rtx target
, rtx cond
)
868 target
= gen_rtx_LABEL_REF (VOIDmode
, target
);
870 target
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, target
, pc_rtx
);
872 insn
= gen_rtx_SET (VOIDmode
, pc_rtx
, target
);
873 emit_jump_insn (insn
);
876 /* Return branch condition mask to implement a branch
877 specified by CODE. Return -1 for invalid comparisons. */
880 s390_branch_condition_mask (rtx code
)
882 const int CC0
= 1 << 3;
883 const int CC1
= 1 << 2;
884 const int CC2
= 1 << 1;
885 const int CC3
= 1 << 0;
887 gcc_assert (GET_CODE (XEXP (code
, 0)) == REG
);
888 gcc_assert (REGNO (XEXP (code
, 0)) == CC_REGNUM
);
889 gcc_assert (XEXP (code
, 1) == const0_rtx
);
891 switch (GET_MODE (XEXP (code
, 0)))
895 switch (GET_CODE (code
))
898 case NE
: return CC1
| CC2
| CC3
;
904 switch (GET_CODE (code
))
907 case NE
: return CC0
| CC2
| CC3
;
913 switch (GET_CODE (code
))
916 case NE
: return CC0
| CC1
| CC3
;
922 switch (GET_CODE (code
))
925 case NE
: return CC0
| CC1
| CC2
;
931 switch (GET_CODE (code
))
933 case EQ
: return CC0
| CC2
;
934 case NE
: return CC1
| CC3
;
940 switch (GET_CODE (code
))
942 case LTU
: return CC2
| CC3
; /* carry */
943 case GEU
: return CC0
| CC1
; /* no carry */
949 switch (GET_CODE (code
))
951 case GTU
: return CC0
| CC1
; /* borrow */
952 case LEU
: return CC2
| CC3
; /* no borrow */
958 switch (GET_CODE (code
))
960 case EQ
: return CC0
| CC2
;
961 case NE
: return CC1
| CC3
;
962 case LTU
: return CC1
;
963 case GTU
: return CC3
;
964 case LEU
: return CC1
| CC2
;
965 case GEU
: return CC2
| CC3
;
970 switch (GET_CODE (code
))
973 case NE
: return CC1
| CC2
| CC3
;
974 case LTU
: return CC1
;
975 case GTU
: return CC2
;
976 case LEU
: return CC0
| CC1
;
977 case GEU
: return CC0
| CC2
;
983 switch (GET_CODE (code
))
986 case NE
: return CC2
| CC1
| CC3
;
987 case LTU
: return CC2
;
988 case GTU
: return CC1
;
989 case LEU
: return CC0
| CC2
;
990 case GEU
: return CC0
| CC1
;
996 switch (GET_CODE (code
))
999 case NE
: return CC1
| CC2
| CC3
;
1000 case LT
: return CC1
| CC3
;
1001 case GT
: return CC2
;
1002 case LE
: return CC0
| CC1
| CC3
;
1003 case GE
: return CC0
| CC2
;
1009 switch (GET_CODE (code
))
1011 case EQ
: return CC0
;
1012 case NE
: return CC1
| CC2
| CC3
;
1013 case LT
: return CC1
;
1014 case GT
: return CC2
| CC3
;
1015 case LE
: return CC0
| CC1
;
1016 case GE
: return CC0
| CC2
| CC3
;
1022 switch (GET_CODE (code
))
1024 case EQ
: return CC0
;
1025 case NE
: return CC1
| CC2
| CC3
;
1026 case LT
: return CC1
;
1027 case GT
: return CC2
;
1028 case LE
: return CC0
| CC1
;
1029 case GE
: return CC0
| CC2
;
1030 case UNORDERED
: return CC3
;
1031 case ORDERED
: return CC0
| CC1
| CC2
;
1032 case UNEQ
: return CC0
| CC3
;
1033 case UNLT
: return CC1
| CC3
;
1034 case UNGT
: return CC2
| CC3
;
1035 case UNLE
: return CC0
| CC1
| CC3
;
1036 case UNGE
: return CC0
| CC2
| CC3
;
1037 case LTGT
: return CC1
| CC2
;
1043 switch (GET_CODE (code
))
1045 case EQ
: return CC0
;
1046 case NE
: return CC2
| CC1
| CC3
;
1047 case LT
: return CC2
;
1048 case GT
: return CC1
;
1049 case LE
: return CC0
| CC2
;
1050 case GE
: return CC0
| CC1
;
1051 case UNORDERED
: return CC3
;
1052 case ORDERED
: return CC0
| CC2
| CC1
;
1053 case UNEQ
: return CC0
| CC3
;
1054 case UNLT
: return CC2
| CC3
;
1055 case UNGT
: return CC1
| CC3
;
1056 case UNLE
: return CC0
| CC2
| CC3
;
1057 case UNGE
: return CC0
| CC1
| CC3
;
1058 case LTGT
: return CC2
| CC1
;
1069 /* Return branch condition mask to implement a compare and branch
1070 specified by CODE. Return -1 for invalid comparisons. */
1073 s390_compare_and_branch_condition_mask (rtx code
)
1075 const int CC0
= 1 << 3;
1076 const int CC1
= 1 << 2;
1077 const int CC2
= 1 << 1;
1079 switch (GET_CODE (code
))
1103 /* If INV is false, return assembler mnemonic string to implement
1104 a branch specified by CODE. If INV is true, return mnemonic
1105 for the corresponding inverted branch. */
1108 s390_branch_condition_mnemonic (rtx code
, int inv
)
1112 static const char *const mnemonic
[16] =
1114 NULL
, "o", "h", "nle",
1115 "l", "nhe", "lh", "ne",
1116 "e", "nlh", "he", "nl",
1117 "le", "nh", "no", NULL
1120 if (GET_CODE (XEXP (code
, 0)) == REG
1121 && REGNO (XEXP (code
, 0)) == CC_REGNUM
1122 && XEXP (code
, 1) == const0_rtx
)
1123 mask
= s390_branch_condition_mask (code
);
1125 mask
= s390_compare_and_branch_condition_mask (code
);
1127 gcc_assert (mask
>= 0);
1132 gcc_assert (mask
>= 1 && mask
<= 14);
1134 return mnemonic
[mask
];
1137 /* Return the part of op which has a value different from def.
1138 The size of the part is determined by mode.
1139 Use this function only if you already know that op really
1140 contains such a part. */
1142 unsigned HOST_WIDE_INT
1143 s390_extract_part (rtx op
, enum machine_mode mode
, int def
)
1145 unsigned HOST_WIDE_INT value
= 0;
1146 int max_parts
= HOST_BITS_PER_WIDE_INT
/ GET_MODE_BITSIZE (mode
);
1147 int part_bits
= GET_MODE_BITSIZE (mode
);
1148 unsigned HOST_WIDE_INT part_mask
1149 = ((unsigned HOST_WIDE_INT
)1 << part_bits
) - 1;
1152 for (i
= 0; i
< max_parts
; i
++)
1155 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
1157 value
>>= part_bits
;
1159 if ((value
& part_mask
) != (def
& part_mask
))
1160 return value
& part_mask
;
1166 /* If OP is an integer constant of mode MODE with exactly one
1167 part of mode PART_MODE unequal to DEF, return the number of that
1168 part. Otherwise, return -1. */
1171 s390_single_part (rtx op
,
1172 enum machine_mode mode
,
1173 enum machine_mode part_mode
,
1176 unsigned HOST_WIDE_INT value
= 0;
1177 int n_parts
= GET_MODE_SIZE (mode
) / GET_MODE_SIZE (part_mode
);
1178 unsigned HOST_WIDE_INT part_mask
1179 = ((unsigned HOST_WIDE_INT
)1 << GET_MODE_BITSIZE (part_mode
)) - 1;
1182 if (GET_CODE (op
) != CONST_INT
)
1185 for (i
= 0; i
< n_parts
; i
++)
1188 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
1190 value
>>= GET_MODE_BITSIZE (part_mode
);
1192 if ((value
& part_mask
) != (def
& part_mask
))
1200 return part
== -1 ? -1 : n_parts
- 1 - part
;
1203 /* Return true if IN contains a contiguous bitfield in the lower SIZE
1204 bits and no other bits are set in IN. POS and LENGTH can be used
1205 to obtain the start position and the length of the bitfield.
1207 POS gives the position of the first bit of the bitfield counting
1208 from the lowest order bit starting with zero. In order to use this
1209 value for S/390 instructions this has to be converted to "bits big
1213 s390_contiguous_bitmask_p (unsigned HOST_WIDE_INT in
, int size
,
1214 int *pos
, int *length
)
1219 unsigned HOST_WIDE_INT mask
= 1ULL;
1220 bool contiguous
= false;
1222 for (i
= 0; i
< size
; mask
<<= 1, i
++)
1246 /* Calculate a mask for all bits beyond the contiguous bits. */
1247 mask
= (-1LL & ~(((1ULL << (tmp_length
+ tmp_pos
- 1)) << 1) - 1));
1252 if (tmp_length
+ tmp_pos
- 1 > size
)
1256 *length
= tmp_length
;
1264 /* Check whether we can (and want to) split a double-word
1265 move in mode MODE from SRC to DST into two single-word
1266 moves, moving the subword FIRST_SUBWORD first. */
1269 s390_split_ok_p (rtx dst
, rtx src
, enum machine_mode mode
, int first_subword
)
1271 /* Floating point registers cannot be split. */
1272 if (FP_REG_P (src
) || FP_REG_P (dst
))
1275 /* We don't need to split if operands are directly accessible. */
1276 if (s_operand (src
, mode
) || s_operand (dst
, mode
))
1279 /* Non-offsettable memory references cannot be split. */
1280 if ((GET_CODE (src
) == MEM
&& !offsettable_memref_p (src
))
1281 || (GET_CODE (dst
) == MEM
&& !offsettable_memref_p (dst
)))
1284 /* Moving the first subword must not clobber a register
1285 needed to move the second subword. */
1286 if (register_operand (dst
, mode
))
1288 rtx subreg
= operand_subword (dst
, first_subword
, 0, mode
);
1289 if (reg_overlap_mentioned_p (subreg
, src
))
1296 /* Return true if it can be proven that [MEM1, MEM1 + SIZE]
1297 and [MEM2, MEM2 + SIZE] do overlap and false
1301 s390_overlap_p (rtx mem1
, rtx mem2
, HOST_WIDE_INT size
)
1303 rtx addr1
, addr2
, addr_delta
;
1304 HOST_WIDE_INT delta
;
1306 if (GET_CODE (mem1
) != MEM
|| GET_CODE (mem2
) != MEM
)
1312 addr1
= XEXP (mem1
, 0);
1313 addr2
= XEXP (mem2
, 0);
1315 addr_delta
= simplify_binary_operation (MINUS
, Pmode
, addr2
, addr1
);
1317 /* This overlapping check is used by peepholes merging memory block operations.
1318 Overlapping operations would otherwise be recognized by the S/390 hardware
1319 and would fall back to a slower implementation. Allowing overlapping
1320 operations would lead to slow code but not to wrong code. Therefore we are
1321 somewhat optimistic if we cannot prove that the memory blocks are
1323 That's why we return false here although this may accept operations on
1324 overlapping memory areas. */
1325 if (!addr_delta
|| GET_CODE (addr_delta
) != CONST_INT
)
1328 delta
= INTVAL (addr_delta
);
1331 || (delta
> 0 && delta
< size
)
1332 || (delta
< 0 && -delta
< size
))
1338 /* Check whether the address of memory reference MEM2 equals exactly
1339 the address of memory reference MEM1 plus DELTA. Return true if
1340 we can prove this to be the case, false otherwise. */
1343 s390_offset_p (rtx mem1
, rtx mem2
, rtx delta
)
1345 rtx addr1
, addr2
, addr_delta
;
1347 if (GET_CODE (mem1
) != MEM
|| GET_CODE (mem2
) != MEM
)
1350 addr1
= XEXP (mem1
, 0);
1351 addr2
= XEXP (mem2
, 0);
1353 addr_delta
= simplify_binary_operation (MINUS
, Pmode
, addr2
, addr1
);
1354 if (!addr_delta
|| !rtx_equal_p (addr_delta
, delta
))
1360 /* Expand logical operator CODE in mode MODE with operands OPERANDS. */
1363 s390_expand_logical_operator (enum rtx_code code
, enum machine_mode mode
,
1366 enum machine_mode wmode
= mode
;
1367 rtx dst
= operands
[0];
1368 rtx src1
= operands
[1];
1369 rtx src2
= operands
[2];
1372 /* If we cannot handle the operation directly, use a temp register. */
1373 if (!s390_logical_operator_ok_p (operands
))
1374 dst
= gen_reg_rtx (mode
);
1376 /* QImode and HImode patterns make sense only if we have a destination
1377 in memory. Otherwise perform the operation in SImode. */
1378 if ((mode
== QImode
|| mode
== HImode
) && GET_CODE (dst
) != MEM
)
1381 /* Widen operands if required. */
1384 if (GET_CODE (dst
) == SUBREG
1385 && (tem
= simplify_subreg (wmode
, dst
, mode
, 0)) != 0)
1387 else if (REG_P (dst
))
1388 dst
= gen_rtx_SUBREG (wmode
, dst
, 0);
1390 dst
= gen_reg_rtx (wmode
);
1392 if (GET_CODE (src1
) == SUBREG
1393 && (tem
= simplify_subreg (wmode
, src1
, mode
, 0)) != 0)
1395 else if (GET_MODE (src1
) != VOIDmode
)
1396 src1
= gen_rtx_SUBREG (wmode
, force_reg (mode
, src1
), 0);
1398 if (GET_CODE (src2
) == SUBREG
1399 && (tem
= simplify_subreg (wmode
, src2
, mode
, 0)) != 0)
1401 else if (GET_MODE (src2
) != VOIDmode
)
1402 src2
= gen_rtx_SUBREG (wmode
, force_reg (mode
, src2
), 0);
1405 /* Emit the instruction. */
1406 op
= gen_rtx_SET (VOIDmode
, dst
, gen_rtx_fmt_ee (code
, wmode
, src1
, src2
));
1407 clob
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
1408 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, op
, clob
)));
1410 /* Fix up the destination if needed. */
1411 if (dst
!= operands
[0])
1412 emit_move_insn (operands
[0], gen_lowpart (mode
, dst
));
1415 /* Check whether OPERANDS are OK for a logical operation (AND, IOR, XOR). */
1418 s390_logical_operator_ok_p (rtx
*operands
)
1420 /* If the destination operand is in memory, it needs to coincide
1421 with one of the source operands. After reload, it has to be
1422 the first source operand. */
1423 if (GET_CODE (operands
[0]) == MEM
)
1424 return rtx_equal_p (operands
[0], operands
[1])
1425 || (!reload_completed
&& rtx_equal_p (operands
[0], operands
[2]));
1430 /* Narrow logical operation CODE of memory operand MEMOP with immediate
1431 operand IMMOP to switch from SS to SI type instructions. */
1434 s390_narrow_logical_operator (enum rtx_code code
, rtx
*memop
, rtx
*immop
)
1436 int def
= code
== AND
? -1 : 0;
1440 gcc_assert (GET_CODE (*memop
) == MEM
);
1441 gcc_assert (!MEM_VOLATILE_P (*memop
));
1443 mask
= s390_extract_part (*immop
, QImode
, def
);
1444 part
= s390_single_part (*immop
, GET_MODE (*memop
), QImode
, def
);
1445 gcc_assert (part
>= 0);
1447 *memop
= adjust_address (*memop
, QImode
, part
);
1448 *immop
= gen_int_mode (mask
, QImode
);
1452 /* How to allocate a 'struct machine_function'. */
1454 static struct machine_function
*
1455 s390_init_machine_status (void)
1457 return GGC_CNEW (struct machine_function
);
1460 /* Change optimizations to be performed, depending on the
1463 LEVEL is the optimization level specified; 2 if `-O2' is
1464 specified, 1 if `-O' is specified, and 0 if neither is specified.
1466 SIZE is nonzero if `-Os' is specified and zero otherwise. */
1469 optimization_options (int level ATTRIBUTE_UNUSED
, int size ATTRIBUTE_UNUSED
)
1471 /* ??? There are apparently still problems with -fcaller-saves. */
1472 flag_caller_saves
= 0;
1474 /* By default, always emit DWARF-2 unwind info. This allows debugging
1475 without maintaining a stack frame back-chain. */
1476 flag_asynchronous_unwind_tables
= 1;
1478 /* Use MVCLE instructions to decrease code size if requested. */
1480 target_flags
|= MASK_MVCLE
;
1483 /* Return true if ARG is the name of a processor. Set *TYPE and *FLAGS
1484 to the associated processor_type and processor_flags if so. */
1487 s390_handle_arch_option (const char *arg
,
1488 enum processor_type
*type
,
1493 const char *const name
; /* processor name or nickname. */
1494 const enum processor_type processor
;
1495 const int flags
; /* From enum processor_flags. */
1497 const processor_alias_table
[] =
1499 {"g5", PROCESSOR_9672_G5
, PF_IEEE_FLOAT
},
1500 {"g6", PROCESSOR_9672_G6
, PF_IEEE_FLOAT
},
1501 {"z900", PROCESSOR_2064_Z900
, PF_IEEE_FLOAT
| PF_ZARCH
},
1502 {"z990", PROCESSOR_2084_Z990
, PF_IEEE_FLOAT
| PF_ZARCH
1503 | PF_LONG_DISPLACEMENT
},
1504 {"z9-109", PROCESSOR_2094_Z9_109
, PF_IEEE_FLOAT
| PF_ZARCH
1505 | PF_LONG_DISPLACEMENT
| PF_EXTIMM
},
1506 {"z9-ec", PROCESSOR_2094_Z9_109
, PF_IEEE_FLOAT
| PF_ZARCH
1507 | PF_LONG_DISPLACEMENT
| PF_EXTIMM
| PF_DFP
},
1508 {"z10", PROCESSOR_2097_Z10
, PF_IEEE_FLOAT
| PF_ZARCH
1509 | PF_LONG_DISPLACEMENT
| PF_EXTIMM
| PF_DFP
| PF_Z10
},
1513 for (i
= 0; i
< ARRAY_SIZE (processor_alias_table
); i
++)
1514 if (strcmp (arg
, processor_alias_table
[i
].name
) == 0)
1516 *type
= processor_alias_table
[i
].processor
;
1517 *flags
= processor_alias_table
[i
].flags
;
1523 /* Implement TARGET_HANDLE_OPTION. */
1526 s390_handle_option (size_t code
, const char *arg
, int value ATTRIBUTE_UNUSED
)
1531 return s390_handle_arch_option (arg
, &s390_arch
, &s390_arch_flags
);
1533 case OPT_mstack_guard_
:
1534 if (sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_stack_guard
) != 1)
1536 if (exact_log2 (s390_stack_guard
) == -1)
1537 error ("stack guard value must be an exact power of 2");
1540 case OPT_mstack_size_
:
1541 if (sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_stack_size
) != 1)
1543 if (exact_log2 (s390_stack_size
) == -1)
1544 error ("stack size must be an exact power of 2");
1548 return s390_handle_arch_option (arg
, &s390_tune
, &s390_tune_flags
);
1550 case OPT_mwarn_framesize_
:
1551 return sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_warn_framesize
) == 1;
1559 override_options (void)
1561 /* Set up function hooks. */
1562 init_machine_status
= s390_init_machine_status
;
1564 /* Architecture mode defaults according to ABI. */
1565 if (!(target_flags_explicit
& MASK_ZARCH
))
1568 target_flags
|= MASK_ZARCH
;
1570 target_flags
&= ~MASK_ZARCH
;
1573 /* Determine processor architectural level. */
1574 if (!s390_arch_string
)
1576 s390_arch_string
= TARGET_ZARCH
? "z900" : "g5";
1577 s390_handle_arch_option (s390_arch_string
, &s390_arch
, &s390_arch_flags
);
1580 /* Determine processor to tune for. */
1581 if (s390_tune
== PROCESSOR_max
)
1583 s390_tune
= s390_arch
;
1584 s390_tune_flags
= s390_arch_flags
;
1587 /* Sanity checks. */
1588 if (TARGET_ZARCH
&& !TARGET_CPU_ZARCH
)
1589 error ("z/Architecture mode not supported on %s", s390_arch_string
);
1590 if (TARGET_64BIT
&& !TARGET_ZARCH
)
1591 error ("64-bit ABI not supported in ESA/390 mode");
1593 if (TARGET_HARD_DFP
&& !TARGET_DFP
)
1595 if (target_flags_explicit
& MASK_HARD_DFP
)
1597 if (!TARGET_CPU_DFP
)
1598 error ("Hardware decimal floating point instructions"
1599 " not available on %s", s390_arch_string
);
1601 error ("Hardware decimal floating point instructions"
1602 " not available in ESA/390 mode");
1605 target_flags
&= ~MASK_HARD_DFP
;
1608 if ((target_flags_explicit
& MASK_SOFT_FLOAT
) && TARGET_SOFT_FLOAT
)
1610 if ((target_flags_explicit
& MASK_HARD_DFP
) && TARGET_HARD_DFP
)
1611 error ("-mhard-dfp can't be used in conjunction with -msoft-float");
1613 target_flags
&= ~MASK_HARD_DFP
;
1616 /* Set processor cost function. */
1619 case PROCESSOR_2084_Z990
:
1620 s390_cost
= &z990_cost
;
1622 case PROCESSOR_2094_Z9_109
:
1623 s390_cost
= &z9_109_cost
;
1625 case PROCESSOR_2097_Z10
:
1626 s390_cost
= &z10_cost
;
1629 s390_cost
= &z900_cost
;
1632 if (TARGET_BACKCHAIN
&& TARGET_PACKED_STACK
&& TARGET_HARD_FLOAT
)
1633 error ("-mbackchain -mpacked-stack -mhard-float are not supported "
1636 if (s390_stack_size
)
1638 if (s390_stack_guard
>= s390_stack_size
)
1639 error ("stack size must be greater than the stack guard value");
1640 else if (s390_stack_size
> 1 << 16)
1641 error ("stack size must not be greater than 64k");
1643 else if (s390_stack_guard
)
1644 error ("-mstack-guard implies use of -mstack-size");
1646 #ifdef TARGET_DEFAULT_LONG_DOUBLE_128
1647 if (!(target_flags_explicit
& MASK_LONG_DOUBLE_128
))
1648 target_flags
|= MASK_LONG_DOUBLE_128
;
1651 if (s390_tune
== PROCESSOR_2097_Z10
)
1653 if (!PARAM_SET_P (PARAM_MAX_UNROLLED_INSNS
))
1654 set_param_value ("max-unrolled-insns", 100);
1655 if (!PARAM_SET_P (PARAM_MAX_UNROLL_TIMES
))
1656 set_param_value ("max-unroll-times", 32);
1657 if (!PARAM_SET_P (PARAM_MAX_COMPLETELY_PEELED_INSNS
))
1658 set_param_value ("max-completely-peeled-insns", 800);
1659 if (!PARAM_SET_P (PARAM_MAX_COMPLETELY_PEEL_TIMES
))
1660 set_param_value ("max-completely-peel-times", 64);
1663 set_param_value ("max-pending-list-length", 256);
1666 /* Map for smallest class containing reg regno. */
1668 const enum reg_class regclass_map
[FIRST_PSEUDO_REGISTER
] =
1669 { GENERAL_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1670 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1671 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1672 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1673 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1674 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1675 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1676 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1677 ADDR_REGS
, CC_REGS
, ADDR_REGS
, ADDR_REGS
,
1678 ACCESS_REGS
, ACCESS_REGS
1681 /* Return attribute type of insn. */
1683 static enum attr_type
1684 s390_safe_attr_type (rtx insn
)
1686 if (recog_memoized (insn
) >= 0)
1687 return get_attr_type (insn
);
1692 /* Return true if DISP is a valid short displacement. */
1695 s390_short_displacement (rtx disp
)
1697 /* No displacement is OK. */
1701 /* Without the long displacement facility we don't need to
1702 distingiush between long and short displacement. */
1703 if (!TARGET_LONG_DISPLACEMENT
)
1706 /* Integer displacement in range. */
1707 if (GET_CODE (disp
) == CONST_INT
)
1708 return INTVAL (disp
) >= 0 && INTVAL (disp
) < 4096;
1710 /* GOT offset is not OK, the GOT can be large. */
1711 if (GET_CODE (disp
) == CONST
1712 && GET_CODE (XEXP (disp
, 0)) == UNSPEC
1713 && (XINT (XEXP (disp
, 0), 1) == UNSPEC_GOT
1714 || XINT (XEXP (disp
, 0), 1) == UNSPEC_GOTNTPOFF
))
1717 /* All other symbolic constants are literal pool references,
1718 which are OK as the literal pool must be small. */
1719 if (GET_CODE (disp
) == CONST
)
1725 /* Decompose a RTL expression ADDR for a memory address into
1726 its components, returned in OUT.
1728 Returns false if ADDR is not a valid memory address, true
1729 otherwise. If OUT is NULL, don't return the components,
1730 but check for validity only.
1732 Note: Only addresses in canonical form are recognized.
1733 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
1734 canonical form so that they will be recognized. */
1737 s390_decompose_address (rtx addr
, struct s390_address
*out
)
1739 HOST_WIDE_INT offset
= 0;
1740 rtx base
= NULL_RTX
;
1741 rtx indx
= NULL_RTX
;
1742 rtx disp
= NULL_RTX
;
1744 bool pointer
= false;
1745 bool base_ptr
= false;
1746 bool indx_ptr
= false;
1747 bool literal_pool
= false;
1749 /* We may need to substitute the literal pool base register into the address
1750 below. However, at this point we do not know which register is going to
1751 be used as base, so we substitute the arg pointer register. This is going
1752 to be treated as holding a pointer below -- it shouldn't be used for any
1754 rtx fake_pool_base
= gen_rtx_REG (Pmode
, ARG_POINTER_REGNUM
);
1756 /* Decompose address into base + index + displacement. */
1758 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == UNSPEC
)
1761 else if (GET_CODE (addr
) == PLUS
)
1763 rtx op0
= XEXP (addr
, 0);
1764 rtx op1
= XEXP (addr
, 1);
1765 enum rtx_code code0
= GET_CODE (op0
);
1766 enum rtx_code code1
= GET_CODE (op1
);
1768 if (code0
== REG
|| code0
== UNSPEC
)
1770 if (code1
== REG
|| code1
== UNSPEC
)
1772 indx
= op0
; /* index + base */
1778 base
= op0
; /* base + displacement */
1783 else if (code0
== PLUS
)
1785 indx
= XEXP (op0
, 0); /* index + base + disp */
1786 base
= XEXP (op0
, 1);
1797 disp
= addr
; /* displacement */
1799 /* Extract integer part of displacement. */
1803 if (GET_CODE (disp
) == CONST_INT
)
1805 offset
= INTVAL (disp
);
1808 else if (GET_CODE (disp
) == CONST
1809 && GET_CODE (XEXP (disp
, 0)) == PLUS
1810 && GET_CODE (XEXP (XEXP (disp
, 0), 1)) == CONST_INT
)
1812 offset
= INTVAL (XEXP (XEXP (disp
, 0), 1));
1813 disp
= XEXP (XEXP (disp
, 0), 0);
1817 /* Strip off CONST here to avoid special case tests later. */
1818 if (disp
&& GET_CODE (disp
) == CONST
)
1819 disp
= XEXP (disp
, 0);
1821 /* We can convert literal pool addresses to
1822 displacements by basing them off the base register. */
1823 if (disp
&& GET_CODE (disp
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (disp
))
1825 /* Either base or index must be free to hold the base register. */
1827 base
= fake_pool_base
, literal_pool
= true;
1829 indx
= fake_pool_base
, literal_pool
= true;
1833 /* Mark up the displacement. */
1834 disp
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, disp
),
1835 UNSPEC_LTREL_OFFSET
);
1838 /* Validate base register. */
1841 if (GET_CODE (base
) == UNSPEC
)
1842 switch (XINT (base
, 1))
1846 disp
= gen_rtx_UNSPEC (Pmode
,
1847 gen_rtvec (1, XVECEXP (base
, 0, 0)),
1848 UNSPEC_LTREL_OFFSET
);
1852 base
= XVECEXP (base
, 0, 1);
1855 case UNSPEC_LTREL_BASE
:
1856 if (XVECLEN (base
, 0) == 1)
1857 base
= fake_pool_base
, literal_pool
= true;
1859 base
= XVECEXP (base
, 0, 1);
1867 || (GET_MODE (base
) != SImode
1868 && GET_MODE (base
) != Pmode
))
1871 if (REGNO (base
) == STACK_POINTER_REGNUM
1872 || REGNO (base
) == FRAME_POINTER_REGNUM
1873 || ((reload_completed
|| reload_in_progress
)
1874 && frame_pointer_needed
1875 && REGNO (base
) == HARD_FRAME_POINTER_REGNUM
)
1876 || REGNO (base
) == ARG_POINTER_REGNUM
1878 && REGNO (base
) == PIC_OFFSET_TABLE_REGNUM
))
1879 pointer
= base_ptr
= true;
1881 if ((reload_completed
|| reload_in_progress
)
1882 && base
== cfun
->machine
->base_reg
)
1883 pointer
= base_ptr
= literal_pool
= true;
1886 /* Validate index register. */
1889 if (GET_CODE (indx
) == UNSPEC
)
1890 switch (XINT (indx
, 1))
1894 disp
= gen_rtx_UNSPEC (Pmode
,
1895 gen_rtvec (1, XVECEXP (indx
, 0, 0)),
1896 UNSPEC_LTREL_OFFSET
);
1900 indx
= XVECEXP (indx
, 0, 1);
1903 case UNSPEC_LTREL_BASE
:
1904 if (XVECLEN (indx
, 0) == 1)
1905 indx
= fake_pool_base
, literal_pool
= true;
1907 indx
= XVECEXP (indx
, 0, 1);
1915 || (GET_MODE (indx
) != SImode
1916 && GET_MODE (indx
) != Pmode
))
1919 if (REGNO (indx
) == STACK_POINTER_REGNUM
1920 || REGNO (indx
) == FRAME_POINTER_REGNUM
1921 || ((reload_completed
|| reload_in_progress
)
1922 && frame_pointer_needed
1923 && REGNO (indx
) == HARD_FRAME_POINTER_REGNUM
)
1924 || REGNO (indx
) == ARG_POINTER_REGNUM
1926 && REGNO (indx
) == PIC_OFFSET_TABLE_REGNUM
))
1927 pointer
= indx_ptr
= true;
1929 if ((reload_completed
|| reload_in_progress
)
1930 && indx
== cfun
->machine
->base_reg
)
1931 pointer
= indx_ptr
= literal_pool
= true;
1934 /* Prefer to use pointer as base, not index. */
1935 if (base
&& indx
&& !base_ptr
1936 && (indx_ptr
|| (!REG_POINTER (base
) && REG_POINTER (indx
))))
1943 /* Validate displacement. */
1946 /* If virtual registers are involved, the displacement will change later
1947 anyway as the virtual registers get eliminated. This could make a
1948 valid displacement invalid, but it is more likely to make an invalid
1949 displacement valid, because we sometimes access the register save area
1950 via negative offsets to one of those registers.
1951 Thus we don't check the displacement for validity here. If after
1952 elimination the displacement turns out to be invalid after all,
1953 this is fixed up by reload in any case. */
1954 if (base
!= arg_pointer_rtx
1955 && indx
!= arg_pointer_rtx
1956 && base
!= return_address_pointer_rtx
1957 && indx
!= return_address_pointer_rtx
1958 && base
!= frame_pointer_rtx
1959 && indx
!= frame_pointer_rtx
1960 && base
!= virtual_stack_vars_rtx
1961 && indx
!= virtual_stack_vars_rtx
)
1962 if (!DISP_IN_RANGE (offset
))
1967 /* All the special cases are pointers. */
1970 /* In the small-PIC case, the linker converts @GOT
1971 and @GOTNTPOFF offsets to possible displacements. */
1972 if (GET_CODE (disp
) == UNSPEC
1973 && (XINT (disp
, 1) == UNSPEC_GOT
1974 || XINT (disp
, 1) == UNSPEC_GOTNTPOFF
)
1980 /* Accept pool label offsets. */
1981 else if (GET_CODE (disp
) == UNSPEC
1982 && XINT (disp
, 1) == UNSPEC_POOL_OFFSET
)
1985 /* Accept literal pool references. */
1986 else if (GET_CODE (disp
) == UNSPEC
1987 && XINT (disp
, 1) == UNSPEC_LTREL_OFFSET
)
1989 orig_disp
= gen_rtx_CONST (Pmode
, disp
);
1992 /* If we have an offset, make sure it does not
1993 exceed the size of the constant pool entry. */
1994 rtx sym
= XVECEXP (disp
, 0, 0);
1995 if (offset
>= GET_MODE_SIZE (get_pool_mode (sym
)))
1998 orig_disp
= plus_constant (orig_disp
, offset
);
2013 out
->disp
= orig_disp
;
2014 out
->pointer
= pointer
;
2015 out
->literal_pool
= literal_pool
;
2021 /* Decompose a RTL expression OP for a shift count into its components,
2022 and return the base register in BASE and the offset in OFFSET.
2024 Return true if OP is a valid shift count, false if not. */
2027 s390_decompose_shift_count (rtx op
, rtx
*base
, HOST_WIDE_INT
*offset
)
2029 HOST_WIDE_INT off
= 0;
2031 /* We can have an integer constant, an address register,
2032 or a sum of the two. */
2033 if (GET_CODE (op
) == CONST_INT
)
2038 if (op
&& GET_CODE (op
) == PLUS
&& GET_CODE (XEXP (op
, 1)) == CONST_INT
)
2040 off
= INTVAL (XEXP (op
, 1));
2043 while (op
&& GET_CODE (op
) == SUBREG
)
2044 op
= SUBREG_REG (op
);
2046 if (op
&& GET_CODE (op
) != REG
)
2058 /* Return true if CODE is a valid address without index. */
2061 s390_legitimate_address_without_index_p (rtx op
)
2063 struct s390_address addr
;
2065 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
2074 /* Return true if ADDR is of kind symbol_ref or symbol_ref + const_int
2075 and return these parts in SYMREF and ADDEND. You can pass NULL in
2076 SYMREF and/or ADDEND if you are not interested in these values. */
2079 s390_symref_operand_p (rtx addr
, rtx
*symref
, HOST_WIDE_INT
*addend
)
2081 HOST_WIDE_INT tmpaddend
= 0;
2083 if (GET_CODE (addr
) == CONST
)
2084 addr
= XEXP (addr
, 0);
2086 if (GET_CODE (addr
) == PLUS
)
2088 if (GET_CODE (XEXP (addr
, 0)) == SYMBOL_REF
2089 && CONST_INT_P (XEXP (addr
, 1)))
2091 tmpaddend
= INTVAL (XEXP (addr
, 1));
2092 addr
= XEXP (addr
, 0);
2098 if (GET_CODE (addr
) != SYMBOL_REF
)
2104 *addend
= tmpaddend
;
2110 /* Return true if the address in OP is valid for constraint letter C
2111 if wrapped in a MEM rtx. Set LIT_POOL_OK to true if it literal
2112 pool MEMs should be accepted. Only the Q, R, S, T constraint
2113 letters are allowed for C. */
2116 s390_check_qrst_address (char c
, rtx op
, bool lit_pool_ok
)
2118 struct s390_address addr
;
2119 bool decomposed
= false;
2121 /* This check makes sure that no symbolic address (except literal
2122 pool references) are accepted by the R or T constraints. */
2123 if (s390_symref_operand_p (op
, NULL
, NULL
))
2127 if (!s390_decompose_address (op
, &addr
))
2129 if (!addr
.literal_pool
)
2136 case 'Q': /* no index short displacement */
2137 if (!decomposed
&& !s390_decompose_address (op
, &addr
))
2141 if (!s390_short_displacement (addr
.disp
))
2145 case 'R': /* with index short displacement */
2146 if (TARGET_LONG_DISPLACEMENT
)
2148 if (!decomposed
&& !s390_decompose_address (op
, &addr
))
2150 if (!s390_short_displacement (addr
.disp
))
2153 /* Any invalid address here will be fixed up by reload,
2154 so accept it for the most generic constraint. */
2157 case 'S': /* no index long displacement */
2158 if (!TARGET_LONG_DISPLACEMENT
)
2160 if (!decomposed
&& !s390_decompose_address (op
, &addr
))
2164 if (s390_short_displacement (addr
.disp
))
2168 case 'T': /* with index long displacement */
2169 if (!TARGET_LONG_DISPLACEMENT
)
2171 /* Any invalid address here will be fixed up by reload,
2172 so accept it for the most generic constraint. */
2173 if ((decomposed
|| s390_decompose_address (op
, &addr
))
2174 && s390_short_displacement (addr
.disp
))
2184 /* Evaluates constraint strings described by the regular expression
2185 ([A|B|Z](Q|R|S|T))|U|W|Y and returns 1 if OP is a valid operand for
2186 the constraint given in STR, or 0 else. */
2189 s390_mem_constraint (const char *str
, rtx op
)
2196 /* Check for offsettable variants of memory constraints. */
2197 if (!MEM_P (op
) || MEM_VOLATILE_P (op
))
2199 if ((reload_completed
|| reload_in_progress
)
2200 ? !offsettable_memref_p (op
) : !offsettable_nonstrict_memref_p (op
))
2202 return s390_check_qrst_address (str
[1], XEXP (op
, 0), true);
2204 /* Check for non-literal-pool variants of memory constraints. */
2207 return s390_check_qrst_address (str
[1], XEXP (op
, 0), false);
2212 if (GET_CODE (op
) != MEM
)
2214 return s390_check_qrst_address (c
, XEXP (op
, 0), true);
2216 return (s390_check_qrst_address ('Q', op
, true)
2217 || s390_check_qrst_address ('R', op
, true));
2219 return (s390_check_qrst_address ('S', op
, true)
2220 || s390_check_qrst_address ('T', op
, true));
2222 /* Simply check for the basic form of a shift count. Reload will
2223 take care of making sure we have a proper base register. */
2224 if (!s390_decompose_shift_count (op
, NULL
, NULL
))
2228 return s390_check_qrst_address (str
[1], op
, true);
2236 /* Evaluates constraint strings starting with letter O. Input
2237 parameter C is the second letter following the "O" in the constraint
2238 string. Returns 1 if VALUE meets the respective constraint and 0
2242 s390_O_constraint_str (const char c
, HOST_WIDE_INT value
)
2250 return trunc_int_for_mode (value
, SImode
) == value
;
2254 || s390_single_part (GEN_INT (value
), DImode
, SImode
, 0) == 1;
2257 return s390_single_part (GEN_INT (value
- 1), DImode
, SImode
, -1) == 1;
2265 /* Evaluates constraint strings starting with letter N. Parameter STR
2266 contains the letters following letter "N" in the constraint string.
2267 Returns true if VALUE matches the constraint. */
2270 s390_N_constraint_str (const char *str
, HOST_WIDE_INT value
)
2272 enum machine_mode mode
, part_mode
;
2274 int part
, part_goal
;
2280 part_goal
= str
[0] - '0';
2324 if (GET_MODE_SIZE (mode
) <= GET_MODE_SIZE (part_mode
))
2327 part
= s390_single_part (GEN_INT (value
), mode
, part_mode
, def
);
2330 if (part_goal
!= -1 && part_goal
!= part
)
2337 /* Returns true if the input parameter VALUE is a float zero. */
2340 s390_float_const_zero_p (rtx value
)
2342 return (GET_MODE_CLASS (GET_MODE (value
)) == MODE_FLOAT
2343 && value
== CONST0_RTX (GET_MODE (value
)));
2347 /* Compute a (partial) cost for rtx X. Return true if the complete
2348 cost has been computed, and false if subexpressions should be
2349 scanned. In either case, *TOTAL contains the cost result.
2350 CODE contains GET_CODE (x), OUTER_CODE contains the code
2351 of the superexpression of x. */
2354 s390_rtx_costs (rtx x
, int code
, int outer_code
, int *total
,
2355 bool speed ATTRIBUTE_UNUSED
)
2378 *total
= COSTS_N_INSNS (1);
2383 /* Check for multiply and add. */
2384 if ((GET_MODE (x
) == DFmode
|| GET_MODE (x
) == SFmode
)
2385 && GET_CODE (XEXP (x
, 0)) == MULT
2386 && TARGET_HARD_FLOAT
&& TARGET_FUSED_MADD
)
2388 /* This is the multiply and add case. */
2389 if (GET_MODE (x
) == DFmode
)
2390 *total
= s390_cost
->madbr
;
2392 *total
= s390_cost
->maebr
;
2393 *total
+= (rtx_cost (XEXP (XEXP (x
, 0), 0), MULT
, speed
)
2394 + rtx_cost (XEXP (XEXP (x
, 0), 1), MULT
, speed
)
2395 + rtx_cost (XEXP (x
, 1), (enum rtx_code
) code
, speed
));
2396 return true; /* Do not do an additional recursive descent. */
2398 *total
= COSTS_N_INSNS (1);
2402 switch (GET_MODE (x
))
2406 rtx left
= XEXP (x
, 0);
2407 rtx right
= XEXP (x
, 1);
2408 if (GET_CODE (right
) == CONST_INT
2409 && CONST_OK_FOR_K (INTVAL (right
)))
2410 *total
= s390_cost
->mhi
;
2411 else if (GET_CODE (left
) == SIGN_EXTEND
)
2412 *total
= s390_cost
->mh
;
2414 *total
= s390_cost
->ms
; /* msr, ms, msy */
2419 rtx left
= XEXP (x
, 0);
2420 rtx right
= XEXP (x
, 1);
2423 if (GET_CODE (right
) == CONST_INT
2424 && CONST_OK_FOR_K (INTVAL (right
)))
2425 *total
= s390_cost
->mghi
;
2426 else if (GET_CODE (left
) == SIGN_EXTEND
)
2427 *total
= s390_cost
->msgf
;
2429 *total
= s390_cost
->msg
; /* msgr, msg */
2431 else /* TARGET_31BIT */
2433 if (GET_CODE (left
) == SIGN_EXTEND
2434 && GET_CODE (right
) == SIGN_EXTEND
)
2435 /* mulsidi case: mr, m */
2436 *total
= s390_cost
->m
;
2437 else if (GET_CODE (left
) == ZERO_EXTEND
2438 && GET_CODE (right
) == ZERO_EXTEND
2439 && TARGET_CPU_ZARCH
)
2440 /* umulsidi case: ml, mlr */
2441 *total
= s390_cost
->ml
;
2443 /* Complex calculation is required. */
2444 *total
= COSTS_N_INSNS (40);
2450 *total
= s390_cost
->mult_df
;
2453 *total
= s390_cost
->mxbr
;
2462 if (GET_MODE (x
) == TImode
) /* 128 bit division */
2463 *total
= s390_cost
->dlgr
;
2464 else if (GET_MODE (x
) == DImode
)
2466 rtx right
= XEXP (x
, 1);
2467 if (GET_CODE (right
) == ZERO_EXTEND
) /* 64 by 32 bit division */
2468 *total
= s390_cost
->dlr
;
2469 else /* 64 by 64 bit division */
2470 *total
= s390_cost
->dlgr
;
2472 else if (GET_MODE (x
) == SImode
) /* 32 bit division */
2473 *total
= s390_cost
->dlr
;
2478 if (GET_MODE (x
) == DImode
)
2480 rtx right
= XEXP (x
, 1);
2481 if (GET_CODE (right
) == ZERO_EXTEND
) /* 64 by 32 bit division */
2483 *total
= s390_cost
->dsgfr
;
2485 *total
= s390_cost
->dr
;
2486 else /* 64 by 64 bit division */
2487 *total
= s390_cost
->dsgr
;
2489 else if (GET_MODE (x
) == SImode
) /* 32 bit division */
2490 *total
= s390_cost
->dlr
;
2491 else if (GET_MODE (x
) == SFmode
)
2493 *total
= s390_cost
->debr
;
2495 else if (GET_MODE (x
) == DFmode
)
2497 *total
= s390_cost
->ddbr
;
2499 else if (GET_MODE (x
) == TFmode
)
2501 *total
= s390_cost
->dxbr
;
2506 if (GET_MODE (x
) == SFmode
)
2507 *total
= s390_cost
->sqebr
;
2508 else if (GET_MODE (x
) == DFmode
)
2509 *total
= s390_cost
->sqdbr
;
2511 *total
= s390_cost
->sqxbr
;
2516 if (outer_code
== MULT
|| outer_code
== DIV
|| outer_code
== MOD
2517 || outer_code
== PLUS
|| outer_code
== MINUS
2518 || outer_code
== COMPARE
)
2523 *total
= COSTS_N_INSNS (1);
2524 if (GET_CODE (XEXP (x
, 0)) == AND
2525 && GET_CODE (XEXP (x
, 1)) == CONST_INT
2526 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
)
2528 rtx op0
= XEXP (XEXP (x
, 0), 0);
2529 rtx op1
= XEXP (XEXP (x
, 0), 1);
2530 rtx op2
= XEXP (x
, 1);
2532 if (memory_operand (op0
, GET_MODE (op0
))
2533 && s390_tm_ccmode (op1
, op2
, 0) != VOIDmode
)
2535 if (register_operand (op0
, GET_MODE (op0
))
2536 && s390_tm_ccmode (op1
, op2
, 1) != VOIDmode
)
2546 /* Return the cost of an address rtx ADDR. */
2549 s390_address_cost (rtx addr
, bool speed ATTRIBUTE_UNUSED
)
2551 struct s390_address ad
;
2552 if (!s390_decompose_address (addr
, &ad
))
2555 return ad
.indx
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
2558 /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
2559 otherwise return 0. */
2562 tls_symbolic_operand (rtx op
)
2564 if (GET_CODE (op
) != SYMBOL_REF
)
2566 return SYMBOL_REF_TLS_MODEL (op
);
2569 /* Split DImode access register reference REG (on 64-bit) into its constituent
2570 low and high parts, and store them into LO and HI. Note that gen_lowpart/
2571 gen_highpart cannot be used as they assume all registers are word-sized,
2572 while our access registers have only half that size. */
2575 s390_split_access_reg (rtx reg
, rtx
*lo
, rtx
*hi
)
2577 gcc_assert (TARGET_64BIT
);
2578 gcc_assert (ACCESS_REG_P (reg
));
2579 gcc_assert (GET_MODE (reg
) == DImode
);
2580 gcc_assert (!(REGNO (reg
) & 1));
2582 *lo
= gen_rtx_REG (SImode
, REGNO (reg
) + 1);
2583 *hi
= gen_rtx_REG (SImode
, REGNO (reg
));
2586 /* Return true if OP contains a symbol reference */
2589 symbolic_reference_mentioned_p (rtx op
)
2594 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
2597 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
2598 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
2604 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
2605 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
2609 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
2616 /* Return true if OP contains a reference to a thread-local symbol. */
2619 tls_symbolic_reference_mentioned_p (rtx op
)
2624 if (GET_CODE (op
) == SYMBOL_REF
)
2625 return tls_symbolic_operand (op
);
2627 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
2628 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
2634 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
2635 if (tls_symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
2639 else if (fmt
[i
] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op
, i
)))
2647 /* Return true if OP is a legitimate general operand when
2648 generating PIC code. It is given that flag_pic is on
2649 and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2652 legitimate_pic_operand_p (rtx op
)
2654 /* Accept all non-symbolic constants. */
2655 if (!SYMBOLIC_CONST (op
))
2658 /* Reject everything else; must be handled
2659 via emit_symbolic_move. */
2663 /* Returns true if the constant value OP is a legitimate general operand.
2664 It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2667 legitimate_constant_p (rtx op
)
2669 /* Accept all non-symbolic constants. */
2670 if (!SYMBOLIC_CONST (op
))
2673 /* Accept immediate LARL operands. */
2674 if (TARGET_CPU_ZARCH
&& larl_operand (op
, VOIDmode
))
2677 /* Thread-local symbols are never legal constants. This is
2678 so that emit_call knows that computing such addresses
2679 might require a function call. */
2680 if (TLS_SYMBOLIC_CONST (op
))
2683 /* In the PIC case, symbolic constants must *not* be
2684 forced into the literal pool. We accept them here,
2685 so that they will be handled by emit_symbolic_move. */
2689 /* All remaining non-PIC symbolic constants are
2690 forced into the literal pool. */
2694 /* Determine if it's legal to put X into the constant pool. This
2695 is not possible if X contains the address of a symbol that is
2696 not constant (TLS) or not known at final link time (PIC). */
2699 s390_cannot_force_const_mem (rtx x
)
2701 switch (GET_CODE (x
))
2705 /* Accept all non-symbolic constants. */
2709 /* Labels are OK iff we are non-PIC. */
2710 return flag_pic
!= 0;
2713 /* 'Naked' TLS symbol references are never OK,
2714 non-TLS symbols are OK iff we are non-PIC. */
2715 if (tls_symbolic_operand (x
))
2718 return flag_pic
!= 0;
2721 return s390_cannot_force_const_mem (XEXP (x
, 0));
2724 return s390_cannot_force_const_mem (XEXP (x
, 0))
2725 || s390_cannot_force_const_mem (XEXP (x
, 1));
2728 switch (XINT (x
, 1))
2730 /* Only lt-relative or GOT-relative UNSPECs are OK. */
2731 case UNSPEC_LTREL_OFFSET
:
2739 case UNSPEC_GOTNTPOFF
:
2740 case UNSPEC_INDNTPOFF
:
2743 /* If the literal pool shares the code section, be put
2744 execute template placeholders into the pool as well. */
2746 return TARGET_CPU_ZARCH
;
2758 /* Returns true if the constant value OP is a legitimate general
2759 operand during and after reload. The difference to
2760 legitimate_constant_p is that this function will not accept
2761 a constant that would need to be forced to the literal pool
2762 before it can be used as operand. */
2765 legitimate_reload_constant_p (rtx op
)
2767 /* Accept la(y) operands. */
2768 if (GET_CODE (op
) == CONST_INT
2769 && DISP_IN_RANGE (INTVAL (op
)))
2772 /* Accept l(g)hi/l(g)fi operands. */
2773 if (GET_CODE (op
) == CONST_INT
2774 && (CONST_OK_FOR_K (INTVAL (op
)) || CONST_OK_FOR_Os (INTVAL (op
))))
2777 /* Accept lliXX operands. */
2779 && GET_CODE (op
) == CONST_INT
2780 && trunc_int_for_mode (INTVAL (op
), word_mode
) == INTVAL (op
)
2781 && s390_single_part (op
, word_mode
, HImode
, 0) >= 0)
2785 && GET_CODE (op
) == CONST_INT
2786 && trunc_int_for_mode (INTVAL (op
), word_mode
) == INTVAL (op
)
2787 && s390_single_part (op
, word_mode
, SImode
, 0) >= 0)
2790 /* Accept larl operands. */
2791 if (TARGET_CPU_ZARCH
2792 && larl_operand (op
, VOIDmode
))
2795 /* Accept lzXX operands. */
2796 if (GET_CODE (op
) == CONST_DOUBLE
2797 && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op
, 'G', "G"))
2800 /* Accept double-word operands that can be split. */
2801 if (GET_CODE (op
) == CONST_INT
2802 && trunc_int_for_mode (INTVAL (op
), word_mode
) != INTVAL (op
))
2804 enum machine_mode dword_mode
= word_mode
== SImode
? DImode
: TImode
;
2805 rtx hi
= operand_subword (op
, 0, 0, dword_mode
);
2806 rtx lo
= operand_subword (op
, 1, 0, dword_mode
);
2807 return legitimate_reload_constant_p (hi
)
2808 && legitimate_reload_constant_p (lo
);
2811 /* Everything else cannot be handled without reload. */
2815 /* Given an rtx OP being reloaded into a reg required to be in class RCLASS,
2816 return the class of reg to actually use. */
2819 s390_preferred_reload_class (rtx op
, enum reg_class rclass
)
2821 switch (GET_CODE (op
))
2823 /* Constants we cannot reload must be forced into the
2828 if (legitimate_reload_constant_p (op
))
2833 /* If a symbolic constant or a PLUS is reloaded,
2834 it is most likely being used as an address, so
2835 prefer ADDR_REGS. If 'class' is not a superset
2836 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
2841 if (reg_class_subset_p (ADDR_REGS
, rclass
))
2853 /* Return true if ADDR is SYMBOL_REF + addend with addend being a
2854 multiple of ALIGNMENT and the SYMBOL_REF being naturally
2858 s390_check_symref_alignment (rtx addr
, HOST_WIDE_INT alignment
)
2860 HOST_WIDE_INT addend
;
2863 if (!s390_symref_operand_p (addr
, &symref
, &addend
))
2866 return (!SYMBOL_REF_NOT_NATURALLY_ALIGNED_P (symref
)
2867 && !(addend
& (alignment
- 1)));
2870 /* ADDR is moved into REG using larl. If ADDR isn't a valid larl
2871 operand SCRATCH is used to reload the even part of the address and
2875 s390_reload_larl_operand (rtx reg
, rtx addr
, rtx scratch
)
2877 HOST_WIDE_INT addend
;
2880 if (!s390_symref_operand_p (addr
, &symref
, &addend
))
2884 /* Easy case. The addend is even so larl will do fine. */
2885 emit_move_insn (reg
, addr
);
2888 /* We can leave the scratch register untouched if the target
2889 register is a valid base register. */
2890 if (REGNO (reg
) < FIRST_PSEUDO_REGISTER
2891 && REGNO_REG_CLASS (REGNO (reg
)) == ADDR_REGS
)
2894 gcc_assert (REGNO (scratch
) < FIRST_PSEUDO_REGISTER
);
2895 gcc_assert (REGNO_REG_CLASS (REGNO (scratch
)) == ADDR_REGS
);
2898 emit_move_insn (scratch
,
2899 gen_rtx_CONST (Pmode
,
2900 gen_rtx_PLUS (Pmode
, symref
,
2901 GEN_INT (addend
- 1))));
2903 emit_move_insn (scratch
, symref
);
2905 /* Increment the address using la in order to avoid clobbering cc. */
2906 emit_move_insn (reg
, gen_rtx_PLUS (Pmode
, scratch
, const1_rtx
));
2910 /* Generate what is necessary to move between REG and MEM using
2911 SCRATCH. The direction is given by TOMEM. */
2914 s390_reload_symref_address (rtx reg
, rtx mem
, rtx scratch
, bool tomem
)
2916 /* Reload might have pulled a constant out of the literal pool.
2917 Force it back in. */
2918 if (CONST_INT_P (mem
) || GET_CODE (mem
) == CONST_DOUBLE
2919 || GET_CODE (mem
) == CONST
)
2920 mem
= force_const_mem (GET_MODE (reg
), mem
);
2922 gcc_assert (MEM_P (mem
));
2924 /* For a load from memory we can leave the scratch register
2925 untouched if the target register is a valid base register. */
2927 && REGNO (reg
) < FIRST_PSEUDO_REGISTER
2928 && REGNO_REG_CLASS (REGNO (reg
)) == ADDR_REGS
2929 && GET_MODE (reg
) == GET_MODE (scratch
))
2932 /* Load address into scratch register. Since we can't have a
2933 secondary reload for a secondary reload we have to cover the case
2934 where larl would need a secondary reload here as well. */
2935 s390_reload_larl_operand (scratch
, XEXP (mem
, 0), scratch
);
2937 /* Now we can use a standard load/store to do the move. */
2939 emit_move_insn (replace_equiv_address (mem
, scratch
), reg
);
2941 emit_move_insn (reg
, replace_equiv_address (mem
, scratch
));
2944 /* Inform reload about cases where moving X with a mode MODE to a register in
2945 RCLASS requires an extra scratch or immediate register. Return the class
2946 needed for the immediate register. */
2948 static enum reg_class
2949 s390_secondary_reload (bool in_p
, rtx x
, enum reg_class rclass
,
2950 enum machine_mode mode
, secondary_reload_info
*sri
)
2952 /* Intermediate register needed. */
2953 if (reg_classes_intersect_p (CC_REGS
, rclass
))
2954 return GENERAL_REGS
;
2958 /* On z10 several optimizer steps may generate larl operands with
2961 && s390_symref_operand_p (x
, NULL
, NULL
)
2963 && !s390_check_symref_alignment (x
, 2))
2964 sri
->icode
= ((mode
== DImode
) ? CODE_FOR_reloaddi_larl_odd_addend_z10
2965 : CODE_FOR_reloadsi_larl_odd_addend_z10
);
2967 /* On z10 we need a scratch register when moving QI, TI or floating
2968 point mode values from or to a memory location with a SYMBOL_REF
2969 or if the symref addend of a SI or DI move is not aligned to the
2970 width of the access. */
2972 && s390_symref_operand_p (XEXP (x
, 0), NULL
, NULL
)
2973 && (mode
== QImode
|| mode
== TImode
|| FLOAT_MODE_P (mode
)
2974 || (!TARGET_ZARCH
&& mode
== DImode
)
2975 || ((mode
== HImode
|| mode
== SImode
|| mode
== DImode
)
2976 && (!s390_check_symref_alignment (XEXP (x
, 0),
2977 GET_MODE_SIZE (mode
))))))
2979 #define __SECONDARY_RELOAD_CASE(M,m) \
2982 sri->icode = in_p ? CODE_FOR_reload##m##di_toreg_z10 : \
2983 CODE_FOR_reload##m##di_tomem_z10; \
2985 sri->icode = in_p ? CODE_FOR_reload##m##si_toreg_z10 : \
2986 CODE_FOR_reload##m##si_tomem_z10; \
2989 switch (GET_MODE (x
))
2991 __SECONDARY_RELOAD_CASE (QI
, qi
);
2992 __SECONDARY_RELOAD_CASE (HI
, hi
);
2993 __SECONDARY_RELOAD_CASE (SI
, si
);
2994 __SECONDARY_RELOAD_CASE (DI
, di
);
2995 __SECONDARY_RELOAD_CASE (TI
, ti
);
2996 __SECONDARY_RELOAD_CASE (SF
, sf
);
2997 __SECONDARY_RELOAD_CASE (DF
, df
);
2998 __SECONDARY_RELOAD_CASE (TF
, tf
);
2999 __SECONDARY_RELOAD_CASE (SD
, sd
);
3000 __SECONDARY_RELOAD_CASE (DD
, dd
);
3001 __SECONDARY_RELOAD_CASE (TD
, td
);
3006 #undef __SECONDARY_RELOAD_CASE
3010 /* We need a scratch register when loading a PLUS expression which
3011 is not a legitimate operand of the LOAD ADDRESS instruction. */
3012 if (in_p
&& s390_plus_operand (x
, mode
))
3013 sri
->icode
= (TARGET_64BIT
?
3014 CODE_FOR_reloaddi_plus
: CODE_FOR_reloadsi_plus
);
3016 /* Performing a multiword move from or to memory we have to make sure the
3017 second chunk in memory is addressable without causing a displacement
3018 overflow. If that would be the case we calculate the address in
3019 a scratch register. */
3021 && GET_CODE (XEXP (x
, 0)) == PLUS
3022 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
3023 && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (x
, 0), 1))
3024 + GET_MODE_SIZE (mode
) - 1))
3026 /* For GENERAL_REGS a displacement overflow is no problem if occurring
3027 in a s_operand address since we may fallback to lm/stm. So we only
3028 have to care about overflows in the b+i+d case. */
3029 if ((reg_classes_intersect_p (GENERAL_REGS
, rclass
)
3030 && s390_class_max_nregs (GENERAL_REGS
, mode
) > 1
3031 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == PLUS
)
3032 /* For FP_REGS no lm/stm is available so this check is triggered
3033 for displacement overflows in b+i+d and b+d like addresses. */
3034 || (reg_classes_intersect_p (FP_REGS
, rclass
)
3035 && s390_class_max_nregs (FP_REGS
, mode
) > 1))
3038 sri
->icode
= (TARGET_64BIT
?
3039 CODE_FOR_reloaddi_nonoffmem_in
:
3040 CODE_FOR_reloadsi_nonoffmem_in
);
3042 sri
->icode
= (TARGET_64BIT
?
3043 CODE_FOR_reloaddi_nonoffmem_out
:
3044 CODE_FOR_reloadsi_nonoffmem_out
);
3048 /* A scratch address register is needed when a symbolic constant is
3049 copied to r0 compiling with -fPIC. In other cases the target
3050 register might be used as temporary (see legitimize_pic_address). */
3051 if (in_p
&& SYMBOLIC_CONST (x
) && flag_pic
== 2 && rclass
!= ADDR_REGS
)
3052 sri
->icode
= (TARGET_64BIT
?
3053 CODE_FOR_reloaddi_PIC_addr
:
3054 CODE_FOR_reloadsi_PIC_addr
);
3056 /* Either scratch or no register needed. */
3060 /* Generate code to load SRC, which is PLUS that is not a
3061 legitimate operand for the LA instruction, into TARGET.
3062 SCRATCH may be used as scratch register. */
3065 s390_expand_plus_operand (rtx target
, rtx src
,
3069 struct s390_address ad
;
3071 /* src must be a PLUS; get its two operands. */
3072 gcc_assert (GET_CODE (src
) == PLUS
);
3073 gcc_assert (GET_MODE (src
) == Pmode
);
3075 /* Check if any of the two operands is already scheduled
3076 for replacement by reload. This can happen e.g. when
3077 float registers occur in an address. */
3078 sum1
= find_replacement (&XEXP (src
, 0));
3079 sum2
= find_replacement (&XEXP (src
, 1));
3080 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
3082 /* If the address is already strictly valid, there's nothing to do. */
3083 if (!s390_decompose_address (src
, &ad
)
3084 || (ad
.base
&& !REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)))
3085 || (ad
.indx
&& !REGNO_OK_FOR_INDEX_P (REGNO (ad
.indx
))))
3087 /* Otherwise, one of the operands cannot be an address register;
3088 we reload its value into the scratch register. */
3089 if (true_regnum (sum1
) < 1 || true_regnum (sum1
) > 15)
3091 emit_move_insn (scratch
, sum1
);
3094 if (true_regnum (sum2
) < 1 || true_regnum (sum2
) > 15)
3096 emit_move_insn (scratch
, sum2
);
3100 /* According to the way these invalid addresses are generated
3101 in reload.c, it should never happen (at least on s390) that
3102 *neither* of the PLUS components, after find_replacements
3103 was applied, is an address register. */
3104 if (sum1
== scratch
&& sum2
== scratch
)
3110 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
3113 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
3114 is only ever performed on addresses, so we can mark the
3115 sum as legitimate for LA in any case. */
3116 s390_load_address (target
, src
);
3120 /* Return true if ADDR is a valid memory address.
3121 STRICT specifies whether strict register checking applies. */
3124 s390_legitimate_address_p (enum machine_mode mode
, rtx addr
, bool strict
)
3126 struct s390_address ad
;
3129 && larl_operand (addr
, VOIDmode
)
3130 && (mode
== VOIDmode
3131 || s390_check_symref_alignment (addr
, GET_MODE_SIZE (mode
))))
3134 if (!s390_decompose_address (addr
, &ad
))
3139 if (ad
.base
&& !REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)))
3142 if (ad
.indx
&& !REGNO_OK_FOR_INDEX_P (REGNO (ad
.indx
)))
3148 && !(REGNO (ad
.base
) >= FIRST_PSEUDO_REGISTER
3149 || REGNO_REG_CLASS (REGNO (ad
.base
)) == ADDR_REGS
))
3153 && !(REGNO (ad
.indx
) >= FIRST_PSEUDO_REGISTER
3154 || REGNO_REG_CLASS (REGNO (ad
.indx
)) == ADDR_REGS
))
3160 /* Return true if OP is a valid operand for the LA instruction.
3161 In 31-bit, we need to prove that the result is used as an
3162 address, as LA performs only a 31-bit addition. */
3165 legitimate_la_operand_p (rtx op
)
3167 struct s390_address addr
;
3168 if (!s390_decompose_address (op
, &addr
))
3171 return (TARGET_64BIT
|| addr
.pointer
);
3174 /* Return true if it is valid *and* preferable to use LA to
3175 compute the sum of OP1 and OP2. */
3178 preferred_la_operand_p (rtx op1
, rtx op2
)
3180 struct s390_address addr
;
3182 if (op2
!= const0_rtx
)
3183 op1
= gen_rtx_PLUS (Pmode
, op1
, op2
);
3185 if (!s390_decompose_address (op1
, &addr
))
3187 if (addr
.base
&& !REGNO_OK_FOR_BASE_P (REGNO (addr
.base
)))
3189 if (addr
.indx
&& !REGNO_OK_FOR_INDEX_P (REGNO (addr
.indx
)))
3192 if (!TARGET_64BIT
&& !addr
.pointer
)
3198 if ((addr
.base
&& REG_P (addr
.base
) && REG_POINTER (addr
.base
))
3199 || (addr
.indx
&& REG_P (addr
.indx
) && REG_POINTER (addr
.indx
)))
3205 /* Emit a forced load-address operation to load SRC into DST.
3206 This will use the LOAD ADDRESS instruction even in situations
3207 where legitimate_la_operand_p (SRC) returns false. */
3210 s390_load_address (rtx dst
, rtx src
)
3213 emit_move_insn (dst
, src
);
3215 emit_insn (gen_force_la_31 (dst
, src
));
3218 /* Return a legitimate reference for ORIG (an address) using the
3219 register REG. If REG is 0, a new pseudo is generated.
3221 There are two types of references that must be handled:
3223 1. Global data references must load the address from the GOT, via
3224 the PIC reg. An insn is emitted to do this load, and the reg is
3227 2. Static data references, constant pool addresses, and code labels
3228 compute the address as an offset from the GOT, whose base is in
3229 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
3230 differentiate them from global data objects. The returned
3231 address is the PIC reg + an unspec constant.
3233 TARGET_LEGITIMIZE_ADDRESS_P rejects symbolic references unless the PIC
3234 reg also appears in the address. */
3237 legitimize_pic_address (rtx orig
, rtx reg
)
3243 gcc_assert (!TLS_SYMBOLIC_CONST (addr
));
3245 if (GET_CODE (addr
) == LABEL_REF
3246 || (GET_CODE (addr
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (addr
)))
3248 /* This is a local symbol. */
3249 if (TARGET_CPU_ZARCH
&& larl_operand (addr
, VOIDmode
))
3251 /* Access local symbols PC-relative via LARL.
3252 This is the same as in the non-PIC case, so it is
3253 handled automatically ... */
3257 /* Access local symbols relative to the GOT. */
3259 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
3261 if (reload_in_progress
|| reload_completed
)
3262 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM
, true);
3264 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTOFF
);
3265 addr
= gen_rtx_CONST (Pmode
, addr
);
3266 addr
= force_const_mem (Pmode
, addr
);
3267 emit_move_insn (temp
, addr
);
3269 new_rtx
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
3272 s390_load_address (reg
, new_rtx
);
3277 else if (GET_CODE (addr
) == SYMBOL_REF
)
3280 reg
= gen_reg_rtx (Pmode
);
3284 /* Assume GOT offset < 4k. This is handled the same way
3285 in both 31- and 64-bit code (@GOT). */
3287 if (reload_in_progress
|| reload_completed
)
3288 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM
, true);
3290 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
3291 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
3292 new_rtx
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new_rtx
);
3293 new_rtx
= gen_const_mem (Pmode
, new_rtx
);
3294 emit_move_insn (reg
, new_rtx
);
3297 else if (TARGET_CPU_ZARCH
)
3299 /* If the GOT offset might be >= 4k, we determine the position
3300 of the GOT entry via a PC-relative LARL (@GOTENT). */
3302 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
3304 gcc_assert (REGNO (temp
) >= FIRST_PSEUDO_REGISTER
3305 || REGNO_REG_CLASS (REGNO (temp
)) == ADDR_REGS
);
3307 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTENT
);
3308 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
3309 emit_move_insn (temp
, new_rtx
);
3311 new_rtx
= gen_const_mem (Pmode
, temp
);
3312 emit_move_insn (reg
, new_rtx
);
3317 /* If the GOT offset might be >= 4k, we have to load it
3318 from the literal pool (@GOT). */
3320 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
3322 gcc_assert (REGNO (temp
) >= FIRST_PSEUDO_REGISTER
3323 || REGNO_REG_CLASS (REGNO (temp
)) == ADDR_REGS
);
3325 if (reload_in_progress
|| reload_completed
)
3326 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM
, true);
3328 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
3329 addr
= gen_rtx_CONST (Pmode
, addr
);
3330 addr
= force_const_mem (Pmode
, addr
);
3331 emit_move_insn (temp
, addr
);
3333 new_rtx
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
3334 new_rtx
= gen_const_mem (Pmode
, new_rtx
);
3335 emit_move_insn (reg
, new_rtx
);
3341 if (GET_CODE (addr
) == CONST
)
3343 addr
= XEXP (addr
, 0);
3344 if (GET_CODE (addr
) == UNSPEC
)
3346 gcc_assert (XVECLEN (addr
, 0) == 1);
3347 switch (XINT (addr
, 1))
3349 /* If someone moved a GOT-relative UNSPEC
3350 out of the literal pool, force them back in. */
3353 new_rtx
= force_const_mem (Pmode
, orig
);
3356 /* @GOT is OK as is if small. */
3359 new_rtx
= force_const_mem (Pmode
, orig
);
3362 /* @GOTENT is OK as is. */
3366 /* @PLT is OK as is on 64-bit, must be converted to
3367 GOT-relative @PLTOFF on 31-bit. */
3369 if (!TARGET_CPU_ZARCH
)
3371 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
3373 if (reload_in_progress
|| reload_completed
)
3374 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM
, true);
3376 addr
= XVECEXP (addr
, 0, 0);
3377 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
),
3379 addr
= gen_rtx_CONST (Pmode
, addr
);
3380 addr
= force_const_mem (Pmode
, addr
);
3381 emit_move_insn (temp
, addr
);
3383 new_rtx
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
3386 s390_load_address (reg
, new_rtx
);
3392 /* Everything else cannot happen. */
3398 gcc_assert (GET_CODE (addr
) == PLUS
);
3400 if (GET_CODE (addr
) == PLUS
)
3402 rtx op0
= XEXP (addr
, 0), op1
= XEXP (addr
, 1);
3404 gcc_assert (!TLS_SYMBOLIC_CONST (op0
));
3405 gcc_assert (!TLS_SYMBOLIC_CONST (op1
));
3407 /* Check first to see if this is a constant offset
3408 from a local symbol reference. */
3409 if ((GET_CODE (op0
) == LABEL_REF
3410 || (GET_CODE (op0
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (op0
)))
3411 && GET_CODE (op1
) == CONST_INT
)
3413 if (TARGET_CPU_ZARCH
3414 && larl_operand (op0
, VOIDmode
)
3415 && INTVAL (op1
) < (HOST_WIDE_INT
)1 << 31
3416 && INTVAL (op1
) >= -((HOST_WIDE_INT
)1 << 31))
3418 if (INTVAL (op1
) & 1)
3420 /* LARL can't handle odd offsets, so emit a
3421 pair of LARL and LA. */
3422 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
3424 if (!DISP_IN_RANGE (INTVAL (op1
)))
3426 HOST_WIDE_INT even
= INTVAL (op1
) - 1;
3427 op0
= gen_rtx_PLUS (Pmode
, op0
, GEN_INT (even
));
3428 op0
= gen_rtx_CONST (Pmode
, op0
);
3432 emit_move_insn (temp
, op0
);
3433 new_rtx
= gen_rtx_PLUS (Pmode
, temp
, op1
);
3437 s390_load_address (reg
, new_rtx
);
3443 /* If the offset is even, we can just use LARL.
3444 This will happen automatically. */
3449 /* Access local symbols relative to the GOT. */
3451 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
3453 if (reload_in_progress
|| reload_completed
)
3454 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM
, true);
3456 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op0
),
3458 addr
= gen_rtx_PLUS (Pmode
, addr
, op1
);
3459 addr
= gen_rtx_CONST (Pmode
, addr
);
3460 addr
= force_const_mem (Pmode
, addr
);
3461 emit_move_insn (temp
, addr
);
3463 new_rtx
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
3466 s390_load_address (reg
, new_rtx
);
3472 /* Now, check whether it is a GOT relative symbol plus offset
3473 that was pulled out of the literal pool. Force it back in. */
3475 else if (GET_CODE (op0
) == UNSPEC
3476 && GET_CODE (op1
) == CONST_INT
3477 && XINT (op0
, 1) == UNSPEC_GOTOFF
)
3479 gcc_assert (XVECLEN (op0
, 0) == 1);
3481 new_rtx
= force_const_mem (Pmode
, orig
);
3484 /* Otherwise, compute the sum. */
3487 base
= legitimize_pic_address (XEXP (addr
, 0), reg
);
3488 new_rtx
= legitimize_pic_address (XEXP (addr
, 1),
3489 base
== reg
? NULL_RTX
: reg
);
3490 if (GET_CODE (new_rtx
) == CONST_INT
)
3491 new_rtx
= plus_constant (base
, INTVAL (new_rtx
));
3494 if (GET_CODE (new_rtx
) == PLUS
&& CONSTANT_P (XEXP (new_rtx
, 1)))
3496 base
= gen_rtx_PLUS (Pmode
, base
, XEXP (new_rtx
, 0));
3497 new_rtx
= XEXP (new_rtx
, 1);
3499 new_rtx
= gen_rtx_PLUS (Pmode
, base
, new_rtx
);
3502 if (GET_CODE (new_rtx
) == CONST
)
3503 new_rtx
= XEXP (new_rtx
, 0);
3504 new_rtx
= force_operand (new_rtx
, 0);
3511 /* Load the thread pointer into a register. */
3514 s390_get_thread_pointer (void)
3516 rtx tp
= gen_reg_rtx (Pmode
);
3518 emit_move_insn (tp
, gen_rtx_REG (Pmode
, TP_REGNUM
));
3519 mark_reg_pointer (tp
, BITS_PER_WORD
);
3524 /* Emit a tls call insn. The call target is the SYMBOL_REF stored
3525 in s390_tls_symbol which always refers to __tls_get_offset.
3526 The returned offset is written to RESULT_REG and an USE rtx is
3527 generated for TLS_CALL. */
3529 static GTY(()) rtx s390_tls_symbol
;
3532 s390_emit_tls_call_insn (rtx result_reg
, rtx tls_call
)
3536 gcc_assert (flag_pic
);
3538 if (!s390_tls_symbol
)
3539 s390_tls_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "__tls_get_offset");
3541 insn
= s390_emit_call (s390_tls_symbol
, tls_call
, result_reg
,
3542 gen_rtx_REG (Pmode
, RETURN_REGNUM
));
3544 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), result_reg
);
3545 RTL_CONST_CALL_P (insn
) = 1;
3548 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
3549 this (thread-local) address. REG may be used as temporary. */
3552 legitimize_tls_address (rtx addr
, rtx reg
)
3554 rtx new_rtx
, tls_call
, temp
, base
, r2
, insn
;
3556 if (GET_CODE (addr
) == SYMBOL_REF
)
3557 switch (tls_symbolic_operand (addr
))
3559 case TLS_MODEL_GLOBAL_DYNAMIC
:
3561 r2
= gen_rtx_REG (Pmode
, 2);
3562 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_TLSGD
);
3563 new_rtx
= gen_rtx_CONST (Pmode
, tls_call
);
3564 new_rtx
= force_const_mem (Pmode
, new_rtx
);
3565 emit_move_insn (r2
, new_rtx
);
3566 s390_emit_tls_call_insn (r2
, tls_call
);
3567 insn
= get_insns ();
3570 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
3571 temp
= gen_reg_rtx (Pmode
);
3572 emit_libcall_block (insn
, temp
, r2
, new_rtx
);
3574 new_rtx
= gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
3577 s390_load_address (reg
, new_rtx
);
3582 case TLS_MODEL_LOCAL_DYNAMIC
:
3584 r2
= gen_rtx_REG (Pmode
, 2);
3585 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM
);
3586 new_rtx
= gen_rtx_CONST (Pmode
, tls_call
);
3587 new_rtx
= force_const_mem (Pmode
, new_rtx
);
3588 emit_move_insn (r2
, new_rtx
);
3589 s390_emit_tls_call_insn (r2
, tls_call
);
3590 insn
= get_insns ();
3593 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM_NTPOFF
);
3594 temp
= gen_reg_rtx (Pmode
);
3595 emit_libcall_block (insn
, temp
, r2
, new_rtx
);
3597 new_rtx
= gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
3598 base
= gen_reg_rtx (Pmode
);
3599 s390_load_address (base
, new_rtx
);
3601 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_DTPOFF
);
3602 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
3603 new_rtx
= force_const_mem (Pmode
, new_rtx
);
3604 temp
= gen_reg_rtx (Pmode
);
3605 emit_move_insn (temp
, new_rtx
);
3607 new_rtx
= gen_rtx_PLUS (Pmode
, base
, temp
);
3610 s390_load_address (reg
, new_rtx
);
3615 case TLS_MODEL_INITIAL_EXEC
:
3618 /* Assume GOT offset < 4k. This is handled the same way
3619 in both 31- and 64-bit code. */
3621 if (reload_in_progress
|| reload_completed
)
3622 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM
, true);
3624 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
3625 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
3626 new_rtx
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new_rtx
);
3627 new_rtx
= gen_const_mem (Pmode
, new_rtx
);
3628 temp
= gen_reg_rtx (Pmode
);
3629 emit_move_insn (temp
, new_rtx
);
3631 else if (TARGET_CPU_ZARCH
)
3633 /* If the GOT offset might be >= 4k, we determine the position
3634 of the GOT entry via a PC-relative LARL. */
3636 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
3637 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
3638 temp
= gen_reg_rtx (Pmode
);
3639 emit_move_insn (temp
, new_rtx
);
3641 new_rtx
= gen_const_mem (Pmode
, temp
);
3642 temp
= gen_reg_rtx (Pmode
);
3643 emit_move_insn (temp
, new_rtx
);
3647 /* If the GOT offset might be >= 4k, we have to load it
3648 from the literal pool. */
3650 if (reload_in_progress
|| reload_completed
)
3651 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM
, true);
3653 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
3654 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
3655 new_rtx
= force_const_mem (Pmode
, new_rtx
);
3656 temp
= gen_reg_rtx (Pmode
);
3657 emit_move_insn (temp
, new_rtx
);
3659 new_rtx
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
3660 new_rtx
= gen_const_mem (Pmode
, new_rtx
);
3662 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new_rtx
, addr
), UNSPEC_TLS_LOAD
);
3663 temp
= gen_reg_rtx (Pmode
);
3664 emit_insn (gen_rtx_SET (Pmode
, temp
, new_rtx
));
3668 /* In position-dependent code, load the absolute address of
3669 the GOT entry from the literal pool. */
3671 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
3672 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
3673 new_rtx
= force_const_mem (Pmode
, new_rtx
);
3674 temp
= gen_reg_rtx (Pmode
);
3675 emit_move_insn (temp
, new_rtx
);
3678 new_rtx
= gen_const_mem (Pmode
, new_rtx
);
3679 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new_rtx
, addr
), UNSPEC_TLS_LOAD
);
3680 temp
= gen_reg_rtx (Pmode
);
3681 emit_insn (gen_rtx_SET (Pmode
, temp
, new_rtx
));
3684 new_rtx
= gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
3687 s390_load_address (reg
, new_rtx
);
3692 case TLS_MODEL_LOCAL_EXEC
:
3693 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
3694 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
3695 new_rtx
= force_const_mem (Pmode
, new_rtx
);
3696 temp
= gen_reg_rtx (Pmode
);
3697 emit_move_insn (temp
, new_rtx
);
3699 new_rtx
= gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
3702 s390_load_address (reg
, new_rtx
);
3711 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == UNSPEC
)
3713 switch (XINT (XEXP (addr
, 0), 1))
3715 case UNSPEC_INDNTPOFF
:
3716 gcc_assert (TARGET_CPU_ZARCH
);
3725 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == PLUS
3726 && GET_CODE (XEXP (XEXP (addr
, 0), 1)) == CONST_INT
)
3728 new_rtx
= XEXP (XEXP (addr
, 0), 0);
3729 if (GET_CODE (new_rtx
) != SYMBOL_REF
)
3730 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
3732 new_rtx
= legitimize_tls_address (new_rtx
, reg
);
3733 new_rtx
= plus_constant (new_rtx
, INTVAL (XEXP (XEXP (addr
, 0), 1)));
3734 new_rtx
= force_operand (new_rtx
, 0);
3738 gcc_unreachable (); /* for now ... */
3743 /* Emit insns making the address in operands[1] valid for a standard
3744 move to operands[0]. operands[1] is replaced by an address which
3745 should be used instead of the former RTX to emit the move
3749 emit_symbolic_move (rtx
*operands
)
3751 rtx temp
= !can_create_pseudo_p () ? operands
[0] : gen_reg_rtx (Pmode
);
3753 if (GET_CODE (operands
[0]) == MEM
)
3754 operands
[1] = force_reg (Pmode
, operands
[1]);
3755 else if (TLS_SYMBOLIC_CONST (operands
[1]))
3756 operands
[1] = legitimize_tls_address (operands
[1], temp
);
3758 operands
[1] = legitimize_pic_address (operands
[1], temp
);
3761 /* Try machine-dependent ways of modifying an illegitimate address X
3762 to be legitimate. If we find one, return the new, valid address.
3764 OLDX is the address as it was before break_out_memory_refs was called.
3765 In some cases it is useful to look at this to decide what needs to be done.
3767 MODE is the mode of the operand pointed to by X.
3769 When -fpic is used, special handling is needed for symbolic references.
3770 See comments by legitimize_pic_address for details. */
3773 s390_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
3774 enum machine_mode mode ATTRIBUTE_UNUSED
)
3776 rtx constant_term
= const0_rtx
;
3778 if (TLS_SYMBOLIC_CONST (x
))
3780 x
= legitimize_tls_address (x
, 0);
3782 if (s390_legitimate_address_p (mode
, x
, FALSE
))
3785 else if (GET_CODE (x
) == PLUS
3786 && (TLS_SYMBOLIC_CONST (XEXP (x
, 0))
3787 || TLS_SYMBOLIC_CONST (XEXP (x
, 1))))
3793 if (SYMBOLIC_CONST (x
)
3794 || (GET_CODE (x
) == PLUS
3795 && (SYMBOLIC_CONST (XEXP (x
, 0))
3796 || SYMBOLIC_CONST (XEXP (x
, 1)))))
3797 x
= legitimize_pic_address (x
, 0);
3799 if (s390_legitimate_address_p (mode
, x
, FALSE
))
3803 x
= eliminate_constant_term (x
, &constant_term
);
3805 /* Optimize loading of large displacements by splitting them
3806 into the multiple of 4K and the rest; this allows the
3807 former to be CSE'd if possible.
3809 Don't do this if the displacement is added to a register
3810 pointing into the stack frame, as the offsets will
3811 change later anyway. */
3813 if (GET_CODE (constant_term
) == CONST_INT
3814 && !TARGET_LONG_DISPLACEMENT
3815 && !DISP_IN_RANGE (INTVAL (constant_term
))
3816 && !(REG_P (x
) && REGNO_PTR_FRAME_P (REGNO (x
))))
3818 HOST_WIDE_INT lower
= INTVAL (constant_term
) & 0xfff;
3819 HOST_WIDE_INT upper
= INTVAL (constant_term
) ^ lower
;
3821 rtx temp
= gen_reg_rtx (Pmode
);
3822 rtx val
= force_operand (GEN_INT (upper
), temp
);
3824 emit_move_insn (temp
, val
);
3826 x
= gen_rtx_PLUS (Pmode
, x
, temp
);
3827 constant_term
= GEN_INT (lower
);
3830 if (GET_CODE (x
) == PLUS
)
3832 if (GET_CODE (XEXP (x
, 0)) == REG
)
3834 rtx temp
= gen_reg_rtx (Pmode
);
3835 rtx val
= force_operand (XEXP (x
, 1), temp
);
3837 emit_move_insn (temp
, val
);
3839 x
= gen_rtx_PLUS (Pmode
, XEXP (x
, 0), temp
);
3842 else if (GET_CODE (XEXP (x
, 1)) == REG
)
3844 rtx temp
= gen_reg_rtx (Pmode
);
3845 rtx val
= force_operand (XEXP (x
, 0), temp
);
3847 emit_move_insn (temp
, val
);
3849 x
= gen_rtx_PLUS (Pmode
, temp
, XEXP (x
, 1));
3853 if (constant_term
!= const0_rtx
)
3854 x
= gen_rtx_PLUS (Pmode
, x
, constant_term
);
3859 /* Try a machine-dependent way of reloading an illegitimate address AD
3860 operand. If we find one, push the reload and and return the new address.
3862 MODE is the mode of the enclosing MEM. OPNUM is the operand number
3863 and TYPE is the reload type of the current reload. */
3866 legitimize_reload_address (rtx ad
, enum machine_mode mode ATTRIBUTE_UNUSED
,
3867 int opnum
, int type
)
3869 if (!optimize
|| TARGET_LONG_DISPLACEMENT
)
3872 if (GET_CODE (ad
) == PLUS
)
3874 rtx tem
= simplify_binary_operation (PLUS
, Pmode
,
3875 XEXP (ad
, 0), XEXP (ad
, 1));
3880 if (GET_CODE (ad
) == PLUS
3881 && GET_CODE (XEXP (ad
, 0)) == REG
3882 && GET_CODE (XEXP (ad
, 1)) == CONST_INT
3883 && !DISP_IN_RANGE (INTVAL (XEXP (ad
, 1))))
3885 HOST_WIDE_INT lower
= INTVAL (XEXP (ad
, 1)) & 0xfff;
3886 HOST_WIDE_INT upper
= INTVAL (XEXP (ad
, 1)) ^ lower
;
3887 rtx cst
, tem
, new_rtx
;
3889 cst
= GEN_INT (upper
);
3890 if (!legitimate_reload_constant_p (cst
))
3891 cst
= force_const_mem (Pmode
, cst
);
3893 tem
= gen_rtx_PLUS (Pmode
, XEXP (ad
, 0), cst
);
3894 new_rtx
= gen_rtx_PLUS (Pmode
, tem
, GEN_INT (lower
));
3896 push_reload (XEXP (tem
, 1), 0, &XEXP (tem
, 1), 0,
3897 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
3898 opnum
, (enum reload_type
) type
);
3905 /* Emit code to move LEN bytes from DST to SRC. */
3908 s390_expand_movmem (rtx dst
, rtx src
, rtx len
)
3910 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3912 if (INTVAL (len
) > 0)
3913 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (INTVAL (len
) - 1)));
3916 else if (TARGET_MVCLE
)
3918 emit_insn (gen_movmem_long (dst
, src
, convert_to_mode (Pmode
, len
, 1)));
3923 rtx dst_addr
, src_addr
, count
, blocks
, temp
;
3924 rtx loop_start_label
= gen_label_rtx ();
3925 rtx loop_end_label
= gen_label_rtx ();
3926 rtx end_label
= gen_label_rtx ();
3927 enum machine_mode mode
;
3929 mode
= GET_MODE (len
);
3930 if (mode
== VOIDmode
)
3933 dst_addr
= gen_reg_rtx (Pmode
);
3934 src_addr
= gen_reg_rtx (Pmode
);
3935 count
= gen_reg_rtx (mode
);
3936 blocks
= gen_reg_rtx (mode
);
3938 convert_move (count
, len
, 1);
3939 emit_cmp_and_jump_insns (count
, const0_rtx
,
3940 EQ
, NULL_RTX
, mode
, 1, end_label
);
3942 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
3943 emit_move_insn (src_addr
, force_operand (XEXP (src
, 0), NULL_RTX
));
3944 dst
= change_address (dst
, VOIDmode
, dst_addr
);
3945 src
= change_address (src
, VOIDmode
, src_addr
);
3947 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1,
3950 emit_move_insn (count
, temp
);
3952 temp
= expand_binop (mode
, lshr_optab
, count
, GEN_INT (8), blocks
, 1,
3955 emit_move_insn (blocks
, temp
);
3957 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3958 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3960 emit_label (loop_start_label
);
3963 && (GET_CODE (len
) != CONST_INT
|| INTVAL (len
) > 768))
3967 /* Issue a read prefetch for the +3 cache line. */
3968 prefetch
= gen_prefetch (gen_rtx_PLUS (Pmode
, src_addr
, GEN_INT (768)),
3969 const0_rtx
, const0_rtx
);
3970 PREFETCH_SCHEDULE_BARRIER_P (prefetch
) = true;
3971 emit_insn (prefetch
);
3973 /* Issue a write prefetch for the +3 cache line. */
3974 prefetch
= gen_prefetch (gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (768)),
3975 const1_rtx
, const0_rtx
);
3976 PREFETCH_SCHEDULE_BARRIER_P (prefetch
) = true;
3977 emit_insn (prefetch
);
3980 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (255)));
3981 s390_load_address (dst_addr
,
3982 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
3983 s390_load_address (src_addr
,
3984 gen_rtx_PLUS (Pmode
, src_addr
, GEN_INT (256)));
3986 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1,
3989 emit_move_insn (blocks
, temp
);
3991 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3992 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3994 emit_jump (loop_start_label
);
3995 emit_label (loop_end_label
);
3997 emit_insn (gen_movmem_short (dst
, src
,
3998 convert_to_mode (Pmode
, count
, 1)));
3999 emit_label (end_label
);
4003 /* Emit code to set LEN bytes at DST to VAL.
4004 Make use of clrmem if VAL is zero. */
4007 s390_expand_setmem (rtx dst
, rtx len
, rtx val
)
4009 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) == 0)
4012 gcc_assert (GET_CODE (val
) == CONST_INT
|| GET_MODE (val
) == QImode
);
4014 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) > 0 && INTVAL (len
) <= 257)
4016 if (val
== const0_rtx
&& INTVAL (len
) <= 256)
4017 emit_insn (gen_clrmem_short (dst
, GEN_INT (INTVAL (len
) - 1)));
4020 /* Initialize memory by storing the first byte. */
4021 emit_move_insn (adjust_address (dst
, QImode
, 0), val
);
4023 if (INTVAL (len
) > 1)
4025 /* Initiate 1 byte overlap move.
4026 The first byte of DST is propagated through DSTP1.
4027 Prepare a movmem for: DST+1 = DST (length = LEN - 1).
4028 DST is set to size 1 so the rest of the memory location
4029 does not count as source operand. */
4030 rtx dstp1
= adjust_address (dst
, VOIDmode
, 1);
4031 set_mem_size (dst
, const1_rtx
);
4033 emit_insn (gen_movmem_short (dstp1
, dst
,
4034 GEN_INT (INTVAL (len
) - 2)));
4039 else if (TARGET_MVCLE
)
4041 val
= force_not_mem (convert_modes (Pmode
, QImode
, val
, 1));
4042 emit_insn (gen_setmem_long (dst
, convert_to_mode (Pmode
, len
, 1), val
));
4047 rtx dst_addr
, count
, blocks
, temp
, dstp1
= NULL_RTX
;
4048 rtx loop_start_label
= gen_label_rtx ();
4049 rtx loop_end_label
= gen_label_rtx ();
4050 rtx end_label
= gen_label_rtx ();
4051 enum machine_mode mode
;
4053 mode
= GET_MODE (len
);
4054 if (mode
== VOIDmode
)
4057 dst_addr
= gen_reg_rtx (Pmode
);
4058 count
= gen_reg_rtx (mode
);
4059 blocks
= gen_reg_rtx (mode
);
4061 convert_move (count
, len
, 1);
4062 emit_cmp_and_jump_insns (count
, const0_rtx
,
4063 EQ
, NULL_RTX
, mode
, 1, end_label
);
4065 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
4066 dst
= change_address (dst
, VOIDmode
, dst_addr
);
4068 if (val
== const0_rtx
)
4069 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1,
4073 dstp1
= adjust_address (dst
, VOIDmode
, 1);
4074 set_mem_size (dst
, const1_rtx
);
4076 /* Initialize memory by storing the first byte. */
4077 emit_move_insn (adjust_address (dst
, QImode
, 0), val
);
4079 /* If count is 1 we are done. */
4080 emit_cmp_and_jump_insns (count
, const1_rtx
,
4081 EQ
, NULL_RTX
, mode
, 1, end_label
);
4083 temp
= expand_binop (mode
, add_optab
, count
, GEN_INT (-2), count
, 1,
4087 emit_move_insn (count
, temp
);
4089 temp
= expand_binop (mode
, lshr_optab
, count
, GEN_INT (8), blocks
, 1,
4092 emit_move_insn (blocks
, temp
);
4094 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
4095 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
4097 emit_label (loop_start_label
);
4100 && (GET_CODE (len
) != CONST_INT
|| INTVAL (len
) > 1024))
4102 /* Issue a write prefetch for the +4 cache line. */
4103 rtx prefetch
= gen_prefetch (gen_rtx_PLUS (Pmode
, dst_addr
,
4105 const1_rtx
, const0_rtx
);
4106 emit_insn (prefetch
);
4107 PREFETCH_SCHEDULE_BARRIER_P (prefetch
) = true;
4110 if (val
== const0_rtx
)
4111 emit_insn (gen_clrmem_short (dst
, GEN_INT (255)));
4113 emit_insn (gen_movmem_short (dstp1
, dst
, GEN_INT (255)));
4114 s390_load_address (dst_addr
,
4115 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
4117 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1,
4120 emit_move_insn (blocks
, temp
);
4122 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
4123 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
4125 emit_jump (loop_start_label
);
4126 emit_label (loop_end_label
);
4128 if (val
== const0_rtx
)
4129 emit_insn (gen_clrmem_short (dst
, convert_to_mode (Pmode
, count
, 1)));
4131 emit_insn (gen_movmem_short (dstp1
, dst
, convert_to_mode (Pmode
, count
, 1)));
4132 emit_label (end_label
);
4136 /* Emit code to compare LEN bytes at OP0 with those at OP1,
4137 and return the result in TARGET. */
4140 s390_expand_cmpmem (rtx target
, rtx op0
, rtx op1
, rtx len
)
4142 rtx ccreg
= gen_rtx_REG (CCUmode
, CC_REGNUM
);
4145 /* As the result of CMPINT is inverted compared to what we need,
4146 we have to swap the operands. */
4147 tmp
= op0
; op0
= op1
; op1
= tmp
;
4149 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
4151 if (INTVAL (len
) > 0)
4153 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (INTVAL (len
) - 1)));
4154 emit_insn (gen_cmpint (target
, ccreg
));
4157 emit_move_insn (target
, const0_rtx
);
4159 else if (TARGET_MVCLE
)
4161 emit_insn (gen_cmpmem_long (op0
, op1
, convert_to_mode (Pmode
, len
, 1)));
4162 emit_insn (gen_cmpint (target
, ccreg
));
4166 rtx addr0
, addr1
, count
, blocks
, temp
;
4167 rtx loop_start_label
= gen_label_rtx ();
4168 rtx loop_end_label
= gen_label_rtx ();
4169 rtx end_label
= gen_label_rtx ();
4170 enum machine_mode mode
;
4172 mode
= GET_MODE (len
);
4173 if (mode
== VOIDmode
)
4176 addr0
= gen_reg_rtx (Pmode
);
4177 addr1
= gen_reg_rtx (Pmode
);
4178 count
= gen_reg_rtx (mode
);
4179 blocks
= gen_reg_rtx (mode
);
4181 convert_move (count
, len
, 1);
4182 emit_cmp_and_jump_insns (count
, const0_rtx
,
4183 EQ
, NULL_RTX
, mode
, 1, end_label
);
4185 emit_move_insn (addr0
, force_operand (XEXP (op0
, 0), NULL_RTX
));
4186 emit_move_insn (addr1
, force_operand (XEXP (op1
, 0), NULL_RTX
));
4187 op0
= change_address (op0
, VOIDmode
, addr0
);
4188 op1
= change_address (op1
, VOIDmode
, addr1
);
4190 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1,
4193 emit_move_insn (count
, temp
);
4195 temp
= expand_binop (mode
, lshr_optab
, count
, GEN_INT (8), blocks
, 1,
4198 emit_move_insn (blocks
, temp
);
4200 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
4201 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
4203 emit_label (loop_start_label
);
4206 && (GET_CODE (len
) != CONST_INT
|| INTVAL (len
) > 512))
4210 /* Issue a read prefetch for the +2 cache line of operand 1. */
4211 prefetch
= gen_prefetch (gen_rtx_PLUS (Pmode
, addr0
, GEN_INT (512)),
4212 const0_rtx
, const0_rtx
);
4213 emit_insn (prefetch
);
4214 PREFETCH_SCHEDULE_BARRIER_P (prefetch
) = true;
4216 /* Issue a read prefetch for the +2 cache line of operand 2. */
4217 prefetch
= gen_prefetch (gen_rtx_PLUS (Pmode
, addr1
, GEN_INT (512)),
4218 const0_rtx
, const0_rtx
);
4219 emit_insn (prefetch
);
4220 PREFETCH_SCHEDULE_BARRIER_P (prefetch
) = true;
4223 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (255)));
4224 temp
= gen_rtx_NE (VOIDmode
, ccreg
, const0_rtx
);
4225 temp
= gen_rtx_IF_THEN_ELSE (VOIDmode
, temp
,
4226 gen_rtx_LABEL_REF (VOIDmode
, end_label
), pc_rtx
);
4227 temp
= gen_rtx_SET (VOIDmode
, pc_rtx
, temp
);
4228 emit_jump_insn (temp
);
4230 s390_load_address (addr0
,
4231 gen_rtx_PLUS (Pmode
, addr0
, GEN_INT (256)));
4232 s390_load_address (addr1
,
4233 gen_rtx_PLUS (Pmode
, addr1
, GEN_INT (256)));
4235 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1,
4238 emit_move_insn (blocks
, temp
);
4240 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
4241 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
4243 emit_jump (loop_start_label
);
4244 emit_label (loop_end_label
);
4246 emit_insn (gen_cmpmem_short (op0
, op1
,
4247 convert_to_mode (Pmode
, count
, 1)));
4248 emit_label (end_label
);
4250 emit_insn (gen_cmpint (target
, ccreg
));
4255 /* Expand conditional increment or decrement using alc/slb instructions.
4256 Should generate code setting DST to either SRC or SRC + INCREMENT,
4257 depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
4258 Returns true if successful, false otherwise.
4260 That makes it possible to implement some if-constructs without jumps e.g.:
4261 (borrow = CC0 | CC1 and carry = CC2 | CC3)
4262 unsigned int a, b, c;
4263 if (a < b) c++; -> CCU b > a -> CC2; c += carry;
4264 if (a < b) c--; -> CCL3 a - b -> borrow; c -= borrow;
4265 if (a <= b) c++; -> CCL3 b - a -> borrow; c += carry;
4266 if (a <= b) c--; -> CCU a <= b -> borrow; c -= borrow;
4268 Checks for EQ and NE with a nonzero value need an additional xor e.g.:
4269 if (a == b) c++; -> CCL3 a ^= b; 0 - a -> borrow; c += carry;
4270 if (a == b) c--; -> CCU a ^= b; a <= 0 -> CC0 | CC1; c -= borrow;
4271 if (a != b) c++; -> CCU a ^= b; a > 0 -> CC2; c += carry;
4272 if (a != b) c--; -> CCL3 a ^= b; 0 - a -> borrow; c -= borrow; */
4275 s390_expand_addcc (enum rtx_code cmp_code
, rtx cmp_op0
, rtx cmp_op1
,
4276 rtx dst
, rtx src
, rtx increment
)
4278 enum machine_mode cmp_mode
;
4279 enum machine_mode cc_mode
;
4285 if ((GET_MODE (cmp_op0
) == SImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
4286 && (GET_MODE (cmp_op1
) == SImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
4288 else if ((GET_MODE (cmp_op0
) == DImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
4289 && (GET_MODE (cmp_op1
) == DImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
4294 /* Try ADD LOGICAL WITH CARRY. */
4295 if (increment
== const1_rtx
)
4297 /* Determine CC mode to use. */
4298 if (cmp_code
== EQ
|| cmp_code
== NE
)
4300 if (cmp_op1
!= const0_rtx
)
4302 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
4303 NULL_RTX
, 0, OPTAB_WIDEN
);
4304 cmp_op1
= const0_rtx
;
4307 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
4310 if (cmp_code
== LTU
|| cmp_code
== LEU
)
4315 cmp_code
= swap_condition (cmp_code
);
4332 /* Emit comparison instruction pattern. */
4333 if (!register_operand (cmp_op0
, cmp_mode
))
4334 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
4336 insn
= gen_rtx_SET (VOIDmode
, gen_rtx_REG (cc_mode
, CC_REGNUM
),
4337 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
4338 /* We use insn_invalid_p here to add clobbers if required. */
4339 ret
= insn_invalid_p (emit_insn (insn
));
4342 /* Emit ALC instruction pattern. */
4343 op_res
= gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
4344 gen_rtx_REG (cc_mode
, CC_REGNUM
),
4347 if (src
!= const0_rtx
)
4349 if (!register_operand (src
, GET_MODE (dst
)))
4350 src
= force_reg (GET_MODE (dst
), src
);
4352 op_res
= gen_rtx_PLUS (GET_MODE (dst
), op_res
, src
);
4353 op_res
= gen_rtx_PLUS (GET_MODE (dst
), op_res
, const0_rtx
);
4356 p
= rtvec_alloc (2);
4358 gen_rtx_SET (VOIDmode
, dst
, op_res
);
4360 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
4361 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
4366 /* Try SUBTRACT LOGICAL WITH BORROW. */
4367 if (increment
== constm1_rtx
)
4369 /* Determine CC mode to use. */
4370 if (cmp_code
== EQ
|| cmp_code
== NE
)
4372 if (cmp_op1
!= const0_rtx
)
4374 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
4375 NULL_RTX
, 0, OPTAB_WIDEN
);
4376 cmp_op1
= const0_rtx
;
4379 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
4382 if (cmp_code
== GTU
|| cmp_code
== GEU
)
4387 cmp_code
= swap_condition (cmp_code
);
4404 /* Emit comparison instruction pattern. */
4405 if (!register_operand (cmp_op0
, cmp_mode
))
4406 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
4408 insn
= gen_rtx_SET (VOIDmode
, gen_rtx_REG (cc_mode
, CC_REGNUM
),
4409 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
4410 /* We use insn_invalid_p here to add clobbers if required. */
4411 ret
= insn_invalid_p (emit_insn (insn
));
4414 /* Emit SLB instruction pattern. */
4415 if (!register_operand (src
, GET_MODE (dst
)))
4416 src
= force_reg (GET_MODE (dst
), src
);
4418 op_res
= gen_rtx_MINUS (GET_MODE (dst
),
4419 gen_rtx_MINUS (GET_MODE (dst
), src
, const0_rtx
),
4420 gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
4421 gen_rtx_REG (cc_mode
, CC_REGNUM
),
4423 p
= rtvec_alloc (2);
4425 gen_rtx_SET (VOIDmode
, dst
, op_res
);
4427 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
4428 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
4436 /* Expand code for the insv template. Return true if successful. */
4439 s390_expand_insv (rtx dest
, rtx op1
, rtx op2
, rtx src
)
4441 int bitsize
= INTVAL (op1
);
4442 int bitpos
= INTVAL (op2
);
4444 /* On z10 we can use the risbg instruction to implement insv. */
4446 && ((GET_MODE (dest
) == DImode
&& GET_MODE (src
) == DImode
)
4447 || (GET_MODE (dest
) == SImode
&& GET_MODE (src
) == SImode
)))
4452 op
= gen_rtx_SET (GET_MODE(src
),
4453 gen_rtx_ZERO_EXTRACT (GET_MODE (dest
), dest
, op1
, op2
),
4455 clobber
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
4456 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, op
, clobber
)));
4461 /* We need byte alignment. */
4462 if (bitsize
% BITS_PER_UNIT
)
4466 && memory_operand (dest
, VOIDmode
)
4467 && (register_operand (src
, word_mode
)
4468 || const_int_operand (src
, VOIDmode
)))
4470 /* Emit standard pattern if possible. */
4471 enum machine_mode mode
= smallest_mode_for_size (bitsize
, MODE_INT
);
4472 if (GET_MODE_BITSIZE (mode
) == bitsize
)
4473 emit_move_insn (adjust_address (dest
, mode
, 0), gen_lowpart (mode
, src
));
4475 /* (set (ze (mem)) (const_int)). */
4476 else if (const_int_operand (src
, VOIDmode
))
4478 int size
= bitsize
/ BITS_PER_UNIT
;
4479 rtx src_mem
= adjust_address (force_const_mem (word_mode
, src
), BLKmode
,
4480 GET_MODE_SIZE (word_mode
) - size
);
4482 dest
= adjust_address (dest
, BLKmode
, 0);
4483 set_mem_size (dest
, GEN_INT (size
));
4484 s390_expand_movmem (dest
, src_mem
, GEN_INT (size
));
4487 /* (set (ze (mem)) (reg)). */
4488 else if (register_operand (src
, word_mode
))
4490 if (bitsize
<= GET_MODE_BITSIZE (SImode
))
4491 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode
, dest
, op1
,
4495 /* Emit st,stcmh sequence. */
4496 int stcmh_width
= bitsize
- GET_MODE_BITSIZE (SImode
);
4497 int size
= stcmh_width
/ BITS_PER_UNIT
;
4499 emit_move_insn (adjust_address (dest
, SImode
, size
),
4500 gen_lowpart (SImode
, src
));
4501 set_mem_size (dest
, GEN_INT (size
));
4502 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode
, dest
, GEN_INT
4503 (stcmh_width
), const0_rtx
),
4504 gen_rtx_LSHIFTRT (word_mode
, src
, GEN_INT
4505 (GET_MODE_BITSIZE (SImode
))));
4514 /* (set (ze (reg)) (const_int)). */
4516 && register_operand (dest
, word_mode
)
4517 && (bitpos
% 16) == 0
4518 && (bitsize
% 16) == 0
4519 && const_int_operand (src
, VOIDmode
))
4521 HOST_WIDE_INT val
= INTVAL (src
);
4522 int regpos
= bitpos
+ bitsize
;
4524 while (regpos
> bitpos
)
4526 enum machine_mode putmode
;
4529 if (TARGET_EXTIMM
&& (regpos
% 32 == 0) && (regpos
>= bitpos
+ 32))
4534 putsize
= GET_MODE_BITSIZE (putmode
);
4536 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode
, dest
,
4539 gen_int_mode (val
, putmode
));
4542 gcc_assert (regpos
== bitpos
);
4549 /* A subroutine of s390_expand_cs_hqi and s390_expand_atomic which returns a
4550 register that holds VAL of mode MODE shifted by COUNT bits. */
4553 s390_expand_mask_and_shift (rtx val
, enum machine_mode mode
, rtx count
)
4555 val
= expand_simple_binop (SImode
, AND
, val
, GEN_INT (GET_MODE_MASK (mode
)),
4556 NULL_RTX
, 1, OPTAB_DIRECT
);
4557 return expand_simple_binop (SImode
, ASHIFT
, val
, count
,
4558 NULL_RTX
, 1, OPTAB_DIRECT
);
4561 /* Structure to hold the initial parameters for a compare_and_swap operation
4562 in HImode and QImode. */
4564 struct alignment_context
4566 rtx memsi
; /* SI aligned memory location. */
4567 rtx shift
; /* Bit offset with regard to lsb. */
4568 rtx modemask
; /* Mask of the HQImode shifted by SHIFT bits. */
4569 rtx modemaski
; /* ~modemask */
4570 bool aligned
; /* True if memory is aligned, false else. */
4573 /* A subroutine of s390_expand_cs_hqi and s390_expand_atomic to initialize
4574 structure AC for transparent simplifying, if the memory alignment is known
4575 to be at least 32bit. MEM is the memory location for the actual operation
4576 and MODE its mode. */
4579 init_alignment_context (struct alignment_context
*ac
, rtx mem
,
4580 enum machine_mode mode
)
4582 ac
->shift
= GEN_INT (GET_MODE_SIZE (SImode
) - GET_MODE_SIZE (mode
));
4583 ac
->aligned
= (MEM_ALIGN (mem
) >= GET_MODE_BITSIZE (SImode
));
4586 ac
->memsi
= adjust_address (mem
, SImode
, 0); /* Memory is aligned. */
4589 /* Alignment is unknown. */
4590 rtx byteoffset
, addr
, align
;
4592 /* Force the address into a register. */
4593 addr
= force_reg (Pmode
, XEXP (mem
, 0));
4595 /* Align it to SImode. */
4596 align
= expand_simple_binop (Pmode
, AND
, addr
,
4597 GEN_INT (-GET_MODE_SIZE (SImode
)),
4598 NULL_RTX
, 1, OPTAB_DIRECT
);
4600 ac
->memsi
= gen_rtx_MEM (SImode
, align
);
4601 MEM_VOLATILE_P (ac
->memsi
) = MEM_VOLATILE_P (mem
);
4602 set_mem_alias_set (ac
->memsi
, ALIAS_SET_MEMORY_BARRIER
);
4603 set_mem_align (ac
->memsi
, GET_MODE_BITSIZE (SImode
));
4605 /* Calculate shiftcount. */
4606 byteoffset
= expand_simple_binop (Pmode
, AND
, addr
,
4607 GEN_INT (GET_MODE_SIZE (SImode
) - 1),
4608 NULL_RTX
, 1, OPTAB_DIRECT
);
4609 /* As we already have some offset, evaluate the remaining distance. */
4610 ac
->shift
= expand_simple_binop (SImode
, MINUS
, ac
->shift
, byteoffset
,
4611 NULL_RTX
, 1, OPTAB_DIRECT
);
4614 /* Shift is the byte count, but we need the bitcount. */
4615 ac
->shift
= expand_simple_binop (SImode
, MULT
, ac
->shift
, GEN_INT (BITS_PER_UNIT
),
4616 NULL_RTX
, 1, OPTAB_DIRECT
);
4617 /* Calculate masks. */
4618 ac
->modemask
= expand_simple_binop (SImode
, ASHIFT
,
4619 GEN_INT (GET_MODE_MASK (mode
)), ac
->shift
,
4620 NULL_RTX
, 1, OPTAB_DIRECT
);
4621 ac
->modemaski
= expand_simple_unop (SImode
, NOT
, ac
->modemask
, NULL_RTX
, 1);
4624 /* Expand an atomic compare and swap operation for HImode and QImode. MEM is
4625 the memory location, CMP the old value to compare MEM with and NEW_RTX the value
4626 to set if CMP == MEM.
4627 CMP is never in memory for compare_and_swap_cc because
4628 expand_bool_compare_and_swap puts it into a register for later compare. */
4631 s390_expand_cs_hqi (enum machine_mode mode
, rtx target
, rtx mem
, rtx cmp
, rtx new_rtx
)
4633 struct alignment_context ac
;
4634 rtx cmpv
, newv
, val
, resv
, cc
;
4635 rtx res
= gen_reg_rtx (SImode
);
4636 rtx csloop
= gen_label_rtx ();
4637 rtx csend
= gen_label_rtx ();
4639 gcc_assert (register_operand (target
, VOIDmode
));
4640 gcc_assert (MEM_P (mem
));
4642 init_alignment_context (&ac
, mem
, mode
);
4644 /* Shift the values to the correct bit positions. */
4645 if (!(ac
.aligned
&& MEM_P (cmp
)))
4646 cmp
= s390_expand_mask_and_shift (cmp
, mode
, ac
.shift
);
4647 if (!(ac
.aligned
&& MEM_P (new_rtx
)))
4648 new_rtx
= s390_expand_mask_and_shift (new_rtx
, mode
, ac
.shift
);
4650 /* Load full word. Subsequent loads are performed by CS. */
4651 val
= expand_simple_binop (SImode
, AND
, ac
.memsi
, ac
.modemaski
,
4652 NULL_RTX
, 1, OPTAB_DIRECT
);
4654 /* Start CS loop. */
4655 emit_label (csloop
);
4656 /* val = "<mem>00..0<mem>"
4657 * cmp = "00..0<cmp>00..0"
4658 * new = "00..0<new>00..0"
4661 /* Patch cmp and new with val at correct position. */
4662 if (ac
.aligned
&& MEM_P (cmp
))
4664 cmpv
= force_reg (SImode
, val
);
4665 store_bit_field (cmpv
, GET_MODE_BITSIZE (mode
), 0, SImode
, cmp
);
4668 cmpv
= force_reg (SImode
, expand_simple_binop (SImode
, IOR
, cmp
, val
,
4669 NULL_RTX
, 1, OPTAB_DIRECT
));
4670 if (ac
.aligned
&& MEM_P (new_rtx
))
4672 newv
= force_reg (SImode
, val
);
4673 store_bit_field (newv
, GET_MODE_BITSIZE (mode
), 0, SImode
, new_rtx
);
4676 newv
= force_reg (SImode
, expand_simple_binop (SImode
, IOR
, new_rtx
, val
,
4677 NULL_RTX
, 1, OPTAB_DIRECT
));
4679 /* Jump to end if we're done (likely?). */
4680 s390_emit_jump (csend
, s390_emit_compare_and_swap (EQ
, res
, ac
.memsi
,
4683 /* Check for changes outside mode. */
4684 resv
= expand_simple_binop (SImode
, AND
, res
, ac
.modemaski
,
4685 NULL_RTX
, 1, OPTAB_DIRECT
);
4686 cc
= s390_emit_compare (NE
, resv
, val
);
4687 emit_move_insn (val
, resv
);
4688 /* Loop internal if so. */
4689 s390_emit_jump (csloop
, cc
);
4693 /* Return the correct part of the bitfield. */
4694 convert_move (target
, expand_simple_binop (SImode
, LSHIFTRT
, res
, ac
.shift
,
4695 NULL_RTX
, 1, OPTAB_DIRECT
), 1);
4698 /* Expand an atomic operation CODE of mode MODE. MEM is the memory location
4699 and VAL the value to play with. If AFTER is true then store the value
4700 MEM holds after the operation, if AFTER is false then store the value MEM
4701 holds before the operation. If TARGET is zero then discard that value, else
4702 store it to TARGET. */
4705 s390_expand_atomic (enum machine_mode mode
, enum rtx_code code
,
4706 rtx target
, rtx mem
, rtx val
, bool after
)
4708 struct alignment_context ac
;
4710 rtx new_rtx
= gen_reg_rtx (SImode
);
4711 rtx orig
= gen_reg_rtx (SImode
);
4712 rtx csloop
= gen_label_rtx ();
4714 gcc_assert (!target
|| register_operand (target
, VOIDmode
));
4715 gcc_assert (MEM_P (mem
));
4717 init_alignment_context (&ac
, mem
, mode
);
4719 /* Shift val to the correct bit positions.
4720 Preserve "icm", but prevent "ex icm". */
4721 if (!(ac
.aligned
&& code
== SET
&& MEM_P (val
)))
4722 val
= s390_expand_mask_and_shift (val
, mode
, ac
.shift
);
4724 /* Further preparation insns. */
4725 if (code
== PLUS
|| code
== MINUS
)
4726 emit_move_insn (orig
, val
);
4727 else if (code
== MULT
|| code
== AND
) /* val = "11..1<val>11..1" */
4728 val
= expand_simple_binop (SImode
, XOR
, val
, ac
.modemaski
,
4729 NULL_RTX
, 1, OPTAB_DIRECT
);
4731 /* Load full word. Subsequent loads are performed by CS. */
4732 cmp
= force_reg (SImode
, ac
.memsi
);
4734 /* Start CS loop. */
4735 emit_label (csloop
);
4736 emit_move_insn (new_rtx
, cmp
);
4738 /* Patch new with val at correct position. */
4743 val
= expand_simple_binop (SImode
, code
, new_rtx
, orig
,
4744 NULL_RTX
, 1, OPTAB_DIRECT
);
4745 val
= expand_simple_binop (SImode
, AND
, val
, ac
.modemask
,
4746 NULL_RTX
, 1, OPTAB_DIRECT
);
4749 if (ac
.aligned
&& MEM_P (val
))
4750 store_bit_field (new_rtx
, GET_MODE_BITSIZE (mode
), 0, SImode
, val
);
4753 new_rtx
= expand_simple_binop (SImode
, AND
, new_rtx
, ac
.modemaski
,
4754 NULL_RTX
, 1, OPTAB_DIRECT
);
4755 new_rtx
= expand_simple_binop (SImode
, IOR
, new_rtx
, val
,
4756 NULL_RTX
, 1, OPTAB_DIRECT
);
4762 new_rtx
= expand_simple_binop (SImode
, code
, new_rtx
, val
,
4763 NULL_RTX
, 1, OPTAB_DIRECT
);
4765 case MULT
: /* NAND */
4766 new_rtx
= expand_simple_binop (SImode
, AND
, new_rtx
, val
,
4767 NULL_RTX
, 1, OPTAB_DIRECT
);
4768 new_rtx
= expand_simple_binop (SImode
, XOR
, new_rtx
, ac
.modemask
,
4769 NULL_RTX
, 1, OPTAB_DIRECT
);
4775 s390_emit_jump (csloop
, s390_emit_compare_and_swap (NE
, cmp
,
4776 ac
.memsi
, cmp
, new_rtx
));
4778 /* Return the correct part of the bitfield. */
4780 convert_move (target
, expand_simple_binop (SImode
, LSHIFTRT
,
4781 after
? new_rtx
: cmp
, ac
.shift
,
4782 NULL_RTX
, 1, OPTAB_DIRECT
), 1);
4785 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
4786 We need to emit DTP-relative relocations. */
4788 static void s390_output_dwarf_dtprel (FILE *, int, rtx
) ATTRIBUTE_UNUSED
;
4791 s390_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
4796 fputs ("\t.long\t", file
);
4799 fputs ("\t.quad\t", file
);
4804 output_addr_const (file
, x
);
4805 fputs ("@DTPOFF", file
);
4808 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
4809 /* Implement TARGET_MANGLE_TYPE. */
4812 s390_mangle_type (const_tree type
)
4814 if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
4815 && TARGET_LONG_DOUBLE_128
)
4818 /* For all other types, use normal C++ mangling. */
4823 /* In the name of slightly smaller debug output, and to cater to
4824 general assembler lossage, recognize various UNSPEC sequences
4825 and turn them back into a direct symbol reference. */
4828 s390_delegitimize_address (rtx orig_x
)
4832 orig_x
= delegitimize_mem_from_attrs (orig_x
);
4834 if (GET_CODE (x
) != MEM
)
4838 if (GET_CODE (x
) == PLUS
4839 && GET_CODE (XEXP (x
, 1)) == CONST
4840 && GET_CODE (XEXP (x
, 0)) == REG
4841 && REGNO (XEXP (x
, 0)) == PIC_OFFSET_TABLE_REGNUM
)
4843 y
= XEXP (XEXP (x
, 1), 0);
4844 if (GET_CODE (y
) == UNSPEC
4845 && XINT (y
, 1) == UNSPEC_GOT
)
4846 return XVECEXP (y
, 0, 0);
4850 if (GET_CODE (x
) == CONST
)
4853 if (GET_CODE (y
) == UNSPEC
4854 && XINT (y
, 1) == UNSPEC_GOTENT
)
4855 return XVECEXP (y
, 0, 0);
4862 /* Output operand OP to stdio stream FILE.
4863 OP is an address (register + offset) which is not used to address data;
4864 instead the rightmost bits are interpreted as the value. */
4867 print_shift_count_operand (FILE *file
, rtx op
)
4869 HOST_WIDE_INT offset
;
4872 /* Extract base register and offset. */
4873 if (!s390_decompose_shift_count (op
, &base
, &offset
))
4879 gcc_assert (GET_CODE (base
) == REG
);
4880 gcc_assert (REGNO (base
) < FIRST_PSEUDO_REGISTER
);
4881 gcc_assert (REGNO_REG_CLASS (REGNO (base
)) == ADDR_REGS
);
4884 /* Offsets are constricted to twelve bits. */
4885 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
& ((1 << 12) - 1));
4887 fprintf (file
, "(%s)", reg_names
[REGNO (base
)]);
4890 /* See 'get_some_local_dynamic_name'. */
4893 get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
4897 if (GET_CODE (x
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (x
))
4899 x
= get_pool_constant (x
);
4900 return for_each_rtx (&x
, get_some_local_dynamic_name_1
, 0);
4903 if (GET_CODE (x
) == SYMBOL_REF
4904 && tls_symbolic_operand (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
4906 cfun
->machine
->some_ld_name
= XSTR (x
, 0);
4913 /* Locate some local-dynamic symbol still in use by this function
4914 so that we can print its name in local-dynamic base patterns. */
4917 get_some_local_dynamic_name (void)
4921 if (cfun
->machine
->some_ld_name
)
4922 return cfun
->machine
->some_ld_name
;
4924 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
4926 && for_each_rtx (&PATTERN (insn
), get_some_local_dynamic_name_1
, 0))
4927 return cfun
->machine
->some_ld_name
;
4932 /* Output machine-dependent UNSPECs occurring in address constant X
4933 in assembler syntax to stdio stream FILE. Returns true if the
4934 constant X could be recognized, false otherwise. */
4937 s390_output_addr_const_extra (FILE *file
, rtx x
)
4939 if (GET_CODE (x
) == UNSPEC
&& XVECLEN (x
, 0) == 1)
4940 switch (XINT (x
, 1))
4943 output_addr_const (file
, XVECEXP (x
, 0, 0));
4944 fprintf (file
, "@GOTENT");
4947 output_addr_const (file
, XVECEXP (x
, 0, 0));
4948 fprintf (file
, "@GOT");
4951 output_addr_const (file
, XVECEXP (x
, 0, 0));
4952 fprintf (file
, "@GOTOFF");
4955 output_addr_const (file
, XVECEXP (x
, 0, 0));
4956 fprintf (file
, "@PLT");
4959 output_addr_const (file
, XVECEXP (x
, 0, 0));
4960 fprintf (file
, "@PLTOFF");
4963 output_addr_const (file
, XVECEXP (x
, 0, 0));
4964 fprintf (file
, "@TLSGD");
4967 assemble_name (file
, get_some_local_dynamic_name ());
4968 fprintf (file
, "@TLSLDM");
4971 output_addr_const (file
, XVECEXP (x
, 0, 0));
4972 fprintf (file
, "@DTPOFF");
4975 output_addr_const (file
, XVECEXP (x
, 0, 0));
4976 fprintf (file
, "@NTPOFF");
4978 case UNSPEC_GOTNTPOFF
:
4979 output_addr_const (file
, XVECEXP (x
, 0, 0));
4980 fprintf (file
, "@GOTNTPOFF");
4982 case UNSPEC_INDNTPOFF
:
4983 output_addr_const (file
, XVECEXP (x
, 0, 0));
4984 fprintf (file
, "@INDNTPOFF");
4988 if (GET_CODE (x
) == UNSPEC
&& XVECLEN (x
, 0) == 2)
4989 switch (XINT (x
, 1))
4991 case UNSPEC_POOL_OFFSET
:
4992 x
= gen_rtx_MINUS (GET_MODE (x
), XVECEXP (x
, 0, 0), XVECEXP (x
, 0, 1));
4993 output_addr_const (file
, x
);
4999 /* Output address operand ADDR in assembler syntax to
5000 stdio stream FILE. */
5003 print_operand_address (FILE *file
, rtx addr
)
5005 struct s390_address ad
;
5007 if (s390_symref_operand_p (addr
, NULL
, NULL
))
5009 gcc_assert (TARGET_Z10
);
5010 output_addr_const (file
, addr
);
5014 if (!s390_decompose_address (addr
, &ad
)
5015 || (ad
.base
&& !REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)))
5016 || (ad
.indx
&& !REGNO_OK_FOR_INDEX_P (REGNO (ad
.indx
))))
5017 output_operand_lossage ("cannot decompose address");
5020 output_addr_const (file
, ad
.disp
);
5022 fprintf (file
, "0");
5024 if (ad
.base
&& ad
.indx
)
5025 fprintf (file
, "(%s,%s)", reg_names
[REGNO (ad
.indx
)],
5026 reg_names
[REGNO (ad
.base
)]);
5028 fprintf (file
, "(%s)", reg_names
[REGNO (ad
.base
)]);
5031 /* Output operand X in assembler syntax to stdio stream FILE.
5032 CODE specified the format flag. The following format flags
5035 'C': print opcode suffix for branch condition.
5036 'D': print opcode suffix for inverse branch condition.
5037 'E': print opcode suffix for branch on index instruction.
5038 'J': print tls_load/tls_gdcall/tls_ldcall suffix
5039 'G': print the size of the operand in bytes.
5040 'O': print only the displacement of a memory reference.
5041 'R': print only the base register of a memory reference.
5042 'S': print S-type memory reference (base+displacement).
5043 'N': print the second word of a DImode operand.
5044 'M': print the second word of a TImode operand.
5045 'Y': print shift count operand.
5047 'b': print integer X as if it's an unsigned byte.
5048 'c': print integer X as if it's an signed byte.
5049 'x': print integer X as if it's an unsigned halfword.
5050 'h': print integer X as if it's a signed halfword.
5051 'i': print the first nonzero HImode part of X.
5052 'j': print the first HImode part unequal to -1 of X.
5053 'k': print the first nonzero SImode part of X.
5054 'm': print the first SImode part unequal to -1 of X.
5055 'o': print integer X as if it's an unsigned 32bit word. */
5058 print_operand (FILE *file
, rtx x
, int code
)
5063 fprintf (file
, s390_branch_condition_mnemonic (x
, FALSE
));
5067 fprintf (file
, s390_branch_condition_mnemonic (x
, TRUE
));
5071 if (GET_CODE (x
) == LE
)
5072 fprintf (file
, "l");
5073 else if (GET_CODE (x
) == GT
)
5074 fprintf (file
, "h");
5080 if (GET_CODE (x
) == SYMBOL_REF
)
5082 fprintf (file
, "%s", ":tls_load:");
5083 output_addr_const (file
, x
);
5085 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSGD
)
5087 fprintf (file
, "%s", ":tls_gdcall:");
5088 output_addr_const (file
, XVECEXP (x
, 0, 0));
5090 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSLDM
)
5092 fprintf (file
, "%s", ":tls_ldcall:");
5093 assemble_name (file
, get_some_local_dynamic_name ());
5100 fprintf (file
, "%u", GET_MODE_SIZE (GET_MODE (x
)));
5105 struct s390_address ad
;
5108 gcc_assert (GET_CODE (x
) == MEM
);
5109 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
5111 gcc_assert (!ad
.base
|| REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)));
5112 gcc_assert (!ad
.indx
);
5115 output_addr_const (file
, ad
.disp
);
5117 fprintf (file
, "0");
5123 struct s390_address ad
;
5126 gcc_assert (GET_CODE (x
) == MEM
);
5127 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
5129 gcc_assert (!ad
.base
|| REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)));
5130 gcc_assert (!ad
.indx
);
5133 fprintf (file
, "%s", reg_names
[REGNO (ad
.base
)]);
5135 fprintf (file
, "0");
5141 struct s390_address ad
;
5144 gcc_assert (GET_CODE (x
) == MEM
);
5145 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
5147 gcc_assert (!ad
.base
|| REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)));
5148 gcc_assert (!ad
.indx
);
5151 output_addr_const (file
, ad
.disp
);
5153 fprintf (file
, "0");
5156 fprintf (file
, "(%s)", reg_names
[REGNO (ad
.base
)]);
5161 if (GET_CODE (x
) == REG
)
5162 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
5163 else if (GET_CODE (x
) == MEM
)
5164 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 4));
5170 if (GET_CODE (x
) == REG
)
5171 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
5172 else if (GET_CODE (x
) == MEM
)
5173 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 8));
5179 print_shift_count_operand (file
, x
);
5183 switch (GET_CODE (x
))
5186 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
5190 output_address (XEXP (x
, 0));
5197 output_addr_const (file
, x
);
5202 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xff);
5203 else if (code
== 'c')
5204 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((INTVAL (x
) & 0xff) ^ 0x80) - 0x80);
5205 else if (code
== 'x')
5206 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xffff);
5207 else if (code
== 'h')
5208 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((INTVAL (x
) & 0xffff) ^ 0x8000) - 0x8000);
5209 else if (code
== 'i')
5210 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
5211 s390_extract_part (x
, HImode
, 0));
5212 else if (code
== 'j')
5213 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
5214 s390_extract_part (x
, HImode
, -1));
5215 else if (code
== 'k')
5216 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
5217 s390_extract_part (x
, SImode
, 0));
5218 else if (code
== 'm')
5219 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
5220 s390_extract_part (x
, SImode
, -1));
5221 else if (code
== 'o')
5222 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xffffffff);
5224 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
5228 gcc_assert (GET_MODE (x
) == VOIDmode
);
5230 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xff);
5231 else if (code
== 'x')
5232 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xffff);
5233 else if (code
== 'h')
5234 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((CONST_DOUBLE_LOW (x
) & 0xffff) ^ 0x8000) - 0x8000);
5240 fatal_insn ("UNKNOWN in print_operand !?", x
);
5245 /* Target hook for assembling integer objects. We need to define it
5246 here to work a round a bug in some versions of GAS, which couldn't
5247 handle values smaller than INT_MIN when printed in decimal. */
5250 s390_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
5252 if (size
== 8 && aligned_p
5253 && GET_CODE (x
) == CONST_INT
&& INTVAL (x
) < INT_MIN
)
5255 fprintf (asm_out_file
, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX
"\n",
5259 return default_assemble_integer (x
, size
, aligned_p
);
5262 /* Returns true if register REGNO is used for forming
5263 a memory address in expression X. */
5266 reg_used_in_mem_p (int regno
, rtx x
)
5268 enum rtx_code code
= GET_CODE (x
);
5274 if (refers_to_regno_p (regno
, regno
+1,
5278 else if (code
== SET
5279 && GET_CODE (SET_DEST (x
)) == PC
)
5281 if (refers_to_regno_p (regno
, regno
+1,
5286 fmt
= GET_RTX_FORMAT (code
);
5287 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
5290 && reg_used_in_mem_p (regno
, XEXP (x
, i
)))
5293 else if (fmt
[i
] == 'E')
5294 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
5295 if (reg_used_in_mem_p (regno
, XVECEXP (x
, i
, j
)))
5301 /* Returns true if expression DEP_RTX sets an address register
5302 used by instruction INSN to address memory. */
5305 addr_generation_dependency_p (rtx dep_rtx
, rtx insn
)
5309 if (GET_CODE (dep_rtx
) == INSN
)
5310 dep_rtx
= PATTERN (dep_rtx
);
5312 if (GET_CODE (dep_rtx
) == SET
)
5314 target
= SET_DEST (dep_rtx
);
5315 if (GET_CODE (target
) == STRICT_LOW_PART
)
5316 target
= XEXP (target
, 0);
5317 while (GET_CODE (target
) == SUBREG
)
5318 target
= SUBREG_REG (target
);
5320 if (GET_CODE (target
) == REG
)
5322 int regno
= REGNO (target
);
5324 if (s390_safe_attr_type (insn
) == TYPE_LA
)
5326 pat
= PATTERN (insn
);
5327 if (GET_CODE (pat
) == PARALLEL
)
5329 gcc_assert (XVECLEN (pat
, 0) == 2);
5330 pat
= XVECEXP (pat
, 0, 0);
5332 gcc_assert (GET_CODE (pat
) == SET
);
5333 return refers_to_regno_p (regno
, regno
+1, SET_SRC (pat
), 0);
5335 else if (get_attr_atype (insn
) == ATYPE_AGEN
)
5336 return reg_used_in_mem_p (regno
, PATTERN (insn
));
5342 /* Return 1, if dep_insn sets register used in insn in the agen unit. */
5345 s390_agen_dep_p (rtx dep_insn
, rtx insn
)
5347 rtx dep_rtx
= PATTERN (dep_insn
);
5350 if (GET_CODE (dep_rtx
) == SET
5351 && addr_generation_dependency_p (dep_rtx
, insn
))
5353 else if (GET_CODE (dep_rtx
) == PARALLEL
)
5355 for (i
= 0; i
< XVECLEN (dep_rtx
, 0); i
++)
5357 if (addr_generation_dependency_p (XVECEXP (dep_rtx
, 0, i
), insn
))
5365 /* A C statement (sans semicolon) to update the integer scheduling priority
5366 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
5367 reduce the priority to execute INSN later. Do not define this macro if
5368 you do not need to adjust the scheduling priorities of insns.
5370 A STD instruction should be scheduled earlier,
5371 in order to use the bypass. */
5375 s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
5377 if (! INSN_P (insn
))
5380 if (s390_tune
!= PROCESSOR_2084_Z990
5381 && s390_tune
!= PROCESSOR_2094_Z9_109
5382 && s390_tune
!= PROCESSOR_2097_Z10
)
5385 switch (s390_safe_attr_type (insn
))
5389 priority
= priority
<< 3;
5393 priority
= priority
<< 1;
5402 /* The number of instructions that can be issued per cycle. */
5405 s390_issue_rate (void)
5409 case PROCESSOR_2084_Z990
:
5410 case PROCESSOR_2094_Z9_109
:
5412 case PROCESSOR_2097_Z10
:
5420 s390_first_cycle_multipass_dfa_lookahead (void)
5425 /* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
5426 Fix up MEMs as required. */
5429 annotate_constant_pool_refs (rtx
*x
)
5434 gcc_assert (GET_CODE (*x
) != SYMBOL_REF
5435 || !CONSTANT_POOL_ADDRESS_P (*x
));
5437 /* Literal pool references can only occur inside a MEM ... */
5438 if (GET_CODE (*x
) == MEM
)
5440 rtx memref
= XEXP (*x
, 0);
5442 if (GET_CODE (memref
) == SYMBOL_REF
5443 && CONSTANT_POOL_ADDRESS_P (memref
))
5445 rtx base
= cfun
->machine
->base_reg
;
5446 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, memref
, base
),
5449 *x
= replace_equiv_address (*x
, addr
);
5453 if (GET_CODE (memref
) == CONST
5454 && GET_CODE (XEXP (memref
, 0)) == PLUS
5455 && GET_CODE (XEXP (XEXP (memref
, 0), 1)) == CONST_INT
5456 && GET_CODE (XEXP (XEXP (memref
, 0), 0)) == SYMBOL_REF
5457 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (memref
, 0), 0)))
5459 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (memref
, 0), 1));
5460 rtx sym
= XEXP (XEXP (memref
, 0), 0);
5461 rtx base
= cfun
->machine
->base_reg
;
5462 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
5465 *x
= replace_equiv_address (*x
, plus_constant (addr
, off
));
5470 /* ... or a load-address type pattern. */
5471 if (GET_CODE (*x
) == SET
)
5473 rtx addrref
= SET_SRC (*x
);
5475 if (GET_CODE (addrref
) == SYMBOL_REF
5476 && CONSTANT_POOL_ADDRESS_P (addrref
))
5478 rtx base
= cfun
->machine
->base_reg
;
5479 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, addrref
, base
),
5482 SET_SRC (*x
) = addr
;
5486 if (GET_CODE (addrref
) == CONST
5487 && GET_CODE (XEXP (addrref
, 0)) == PLUS
5488 && GET_CODE (XEXP (XEXP (addrref
, 0), 1)) == CONST_INT
5489 && GET_CODE (XEXP (XEXP (addrref
, 0), 0)) == SYMBOL_REF
5490 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (addrref
, 0), 0)))
5492 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (addrref
, 0), 1));
5493 rtx sym
= XEXP (XEXP (addrref
, 0), 0);
5494 rtx base
= cfun
->machine
->base_reg
;
5495 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
5498 SET_SRC (*x
) = plus_constant (addr
, off
);
5503 /* Annotate LTREL_BASE as well. */
5504 if (GET_CODE (*x
) == UNSPEC
5505 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
5507 rtx base
= cfun
->machine
->base_reg
;
5508 *x
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XVECEXP (*x
, 0, 0), base
),
5513 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
5514 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
5518 annotate_constant_pool_refs (&XEXP (*x
, i
));
5520 else if (fmt
[i
] == 'E')
5522 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
5523 annotate_constant_pool_refs (&XVECEXP (*x
, i
, j
));
5528 /* Split all branches that exceed the maximum distance.
5529 Returns true if this created a new literal pool entry. */
5532 s390_split_branches (void)
5534 rtx temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
5535 int new_literal
= 0, ret
;
5536 rtx insn
, pat
, tmp
, target
;
5539 /* We need correct insn addresses. */
5541 shorten_branches (get_insns ());
5543 /* Find all branches that exceed 64KB, and split them. */
5545 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5547 if (GET_CODE (insn
) != JUMP_INSN
)
5550 pat
= PATTERN (insn
);
5551 if (GET_CODE (pat
) == PARALLEL
&& XVECLEN (pat
, 0) > 2)
5552 pat
= XVECEXP (pat
, 0, 0);
5553 if (GET_CODE (pat
) != SET
|| SET_DEST (pat
) != pc_rtx
)
5556 if (GET_CODE (SET_SRC (pat
)) == LABEL_REF
)
5558 label
= &SET_SRC (pat
);
5560 else if (GET_CODE (SET_SRC (pat
)) == IF_THEN_ELSE
)
5562 if (GET_CODE (XEXP (SET_SRC (pat
), 1)) == LABEL_REF
)
5563 label
= &XEXP (SET_SRC (pat
), 1);
5564 else if (GET_CODE (XEXP (SET_SRC (pat
), 2)) == LABEL_REF
)
5565 label
= &XEXP (SET_SRC (pat
), 2);
5572 if (get_attr_length (insn
) <= 4)
5575 /* We are going to use the return register as scratch register,
5576 make sure it will be saved/restored by the prologue/epilogue. */
5577 cfun_frame_layout
.save_return_addr_p
= 1;
5582 tmp
= force_const_mem (Pmode
, *label
);
5583 tmp
= emit_insn_before (gen_rtx_SET (Pmode
, temp_reg
, tmp
), insn
);
5584 INSN_ADDRESSES_NEW (tmp
, -1);
5585 annotate_constant_pool_refs (&PATTERN (tmp
));
5592 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, *label
),
5593 UNSPEC_LTREL_OFFSET
);
5594 target
= gen_rtx_CONST (Pmode
, target
);
5595 target
= force_const_mem (Pmode
, target
);
5596 tmp
= emit_insn_before (gen_rtx_SET (Pmode
, temp_reg
, target
), insn
);
5597 INSN_ADDRESSES_NEW (tmp
, -1);
5598 annotate_constant_pool_refs (&PATTERN (tmp
));
5600 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XEXP (target
, 0),
5601 cfun
->machine
->base_reg
),
5603 target
= gen_rtx_PLUS (Pmode
, temp_reg
, target
);
5606 ret
= validate_change (insn
, label
, target
, 0);
5614 /* Find an annotated literal pool symbol referenced in RTX X,
5615 and store it at REF. Will abort if X contains references to
5616 more than one such pool symbol; multiple references to the same
5617 symbol are allowed, however.
5619 The rtx pointed to by REF must be initialized to NULL_RTX
5620 by the caller before calling this routine. */
5623 find_constant_pool_ref (rtx x
, rtx
*ref
)
5628 /* Ignore LTREL_BASE references. */
5629 if (GET_CODE (x
) == UNSPEC
5630 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
5632 /* Likewise POOL_ENTRY insns. */
5633 if (GET_CODE (x
) == UNSPEC_VOLATILE
5634 && XINT (x
, 1) == UNSPECV_POOL_ENTRY
)
5637 gcc_assert (GET_CODE (x
) != SYMBOL_REF
5638 || !CONSTANT_POOL_ADDRESS_P (x
));
5640 if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_LTREF
)
5642 rtx sym
= XVECEXP (x
, 0, 0);
5643 gcc_assert (GET_CODE (sym
) == SYMBOL_REF
5644 && CONSTANT_POOL_ADDRESS_P (sym
));
5646 if (*ref
== NULL_RTX
)
5649 gcc_assert (*ref
== sym
);
5654 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
5655 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
5659 find_constant_pool_ref (XEXP (x
, i
), ref
);
5661 else if (fmt
[i
] == 'E')
5663 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
5664 find_constant_pool_ref (XVECEXP (x
, i
, j
), ref
);
5669 /* Replace every reference to the annotated literal pool
5670 symbol REF in X by its base plus OFFSET. */
5673 replace_constant_pool_ref (rtx
*x
, rtx ref
, rtx offset
)
5678 gcc_assert (*x
!= ref
);
5680 if (GET_CODE (*x
) == UNSPEC
5681 && XINT (*x
, 1) == UNSPEC_LTREF
5682 && XVECEXP (*x
, 0, 0) == ref
)
5684 *x
= gen_rtx_PLUS (Pmode
, XVECEXP (*x
, 0, 1), offset
);
5688 if (GET_CODE (*x
) == PLUS
5689 && GET_CODE (XEXP (*x
, 1)) == CONST_INT
5690 && GET_CODE (XEXP (*x
, 0)) == UNSPEC
5691 && XINT (XEXP (*x
, 0), 1) == UNSPEC_LTREF
5692 && XVECEXP (XEXP (*x
, 0), 0, 0) == ref
)
5694 rtx addr
= gen_rtx_PLUS (Pmode
, XVECEXP (XEXP (*x
, 0), 0, 1), offset
);
5695 *x
= plus_constant (addr
, INTVAL (XEXP (*x
, 1)));
5699 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
5700 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
5704 replace_constant_pool_ref (&XEXP (*x
, i
), ref
, offset
);
5706 else if (fmt
[i
] == 'E')
5708 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
5709 replace_constant_pool_ref (&XVECEXP (*x
, i
, j
), ref
, offset
);
5714 /* Check whether X contains an UNSPEC_LTREL_BASE.
5715 Return its constant pool symbol if found, NULL_RTX otherwise. */
5718 find_ltrel_base (rtx x
)
5723 if (GET_CODE (x
) == UNSPEC
5724 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
5725 return XVECEXP (x
, 0, 0);
5727 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
5728 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
5732 rtx fnd
= find_ltrel_base (XEXP (x
, i
));
5736 else if (fmt
[i
] == 'E')
5738 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
5740 rtx fnd
= find_ltrel_base (XVECEXP (x
, i
, j
));
5750 /* Replace any occurrence of UNSPEC_LTREL_BASE in X with its base. */
5753 replace_ltrel_base (rtx
*x
)
5758 if (GET_CODE (*x
) == UNSPEC
5759 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
5761 *x
= XVECEXP (*x
, 0, 1);
5765 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
5766 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
5770 replace_ltrel_base (&XEXP (*x
, i
));
5772 else if (fmt
[i
] == 'E')
5774 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
5775 replace_ltrel_base (&XVECEXP (*x
, i
, j
));
5781 /* We keep a list of constants which we have to add to internal
5782 constant tables in the middle of large functions. */
5784 #define NR_C_MODES 11
5785 enum machine_mode constant_modes
[NR_C_MODES
] =
5787 TFmode
, TImode
, TDmode
,
5788 DFmode
, DImode
, DDmode
,
5789 SFmode
, SImode
, SDmode
,
5796 struct constant
*next
;
5801 struct constant_pool
5803 struct constant_pool
*next
;
5807 rtx emit_pool_after
;
5809 struct constant
*constants
[NR_C_MODES
];
5810 struct constant
*execute
;
5815 /* Allocate new constant_pool structure. */
5817 static struct constant_pool
*
5818 s390_alloc_pool (void)
5820 struct constant_pool
*pool
;
5823 pool
= (struct constant_pool
*) xmalloc (sizeof *pool
);
5825 for (i
= 0; i
< NR_C_MODES
; i
++)
5826 pool
->constants
[i
] = NULL
;
5828 pool
->execute
= NULL
;
5829 pool
->label
= gen_label_rtx ();
5830 pool
->first_insn
= NULL_RTX
;
5831 pool
->pool_insn
= NULL_RTX
;
5832 pool
->insns
= BITMAP_ALLOC (NULL
);
5834 pool
->emit_pool_after
= NULL_RTX
;
5839 /* Create new constant pool covering instructions starting at INSN
5840 and chain it to the end of POOL_LIST. */
5842 static struct constant_pool
*
5843 s390_start_pool (struct constant_pool
**pool_list
, rtx insn
)
5845 struct constant_pool
*pool
, **prev
;
5847 pool
= s390_alloc_pool ();
5848 pool
->first_insn
= insn
;
5850 for (prev
= pool_list
; *prev
; prev
= &(*prev
)->next
)
5857 /* End range of instructions covered by POOL at INSN and emit
5858 placeholder insn representing the pool. */
5861 s390_end_pool (struct constant_pool
*pool
, rtx insn
)
5863 rtx pool_size
= GEN_INT (pool
->size
+ 8 /* alignment slop */);
5866 insn
= get_last_insn ();
5868 pool
->pool_insn
= emit_insn_after (gen_pool (pool_size
), insn
);
5869 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
5872 /* Add INSN to the list of insns covered by POOL. */
5875 s390_add_pool_insn (struct constant_pool
*pool
, rtx insn
)
5877 bitmap_set_bit (pool
->insns
, INSN_UID (insn
));
5880 /* Return pool out of POOL_LIST that covers INSN. */
5882 static struct constant_pool
*
5883 s390_find_pool (struct constant_pool
*pool_list
, rtx insn
)
5885 struct constant_pool
*pool
;
5887 for (pool
= pool_list
; pool
; pool
= pool
->next
)
5888 if (bitmap_bit_p (pool
->insns
, INSN_UID (insn
)))
5894 /* Add constant VAL of mode MODE to the constant pool POOL. */
5897 s390_add_constant (struct constant_pool
*pool
, rtx val
, enum machine_mode mode
)
5902 for (i
= 0; i
< NR_C_MODES
; i
++)
5903 if (constant_modes
[i
] == mode
)
5905 gcc_assert (i
!= NR_C_MODES
);
5907 for (c
= pool
->constants
[i
]; c
!= NULL
; c
= c
->next
)
5908 if (rtx_equal_p (val
, c
->value
))
5913 c
= (struct constant
*) xmalloc (sizeof *c
);
5915 c
->label
= gen_label_rtx ();
5916 c
->next
= pool
->constants
[i
];
5917 pool
->constants
[i
] = c
;
5918 pool
->size
+= GET_MODE_SIZE (mode
);
5922 /* Return an rtx that represents the offset of X from the start of
5926 s390_pool_offset (struct constant_pool
*pool
, rtx x
)
5930 label
= gen_rtx_LABEL_REF (GET_MODE (x
), pool
->label
);
5931 x
= gen_rtx_UNSPEC (GET_MODE (x
), gen_rtvec (2, x
, label
),
5932 UNSPEC_POOL_OFFSET
);
5933 return gen_rtx_CONST (GET_MODE (x
), x
);
5936 /* Find constant VAL of mode MODE in the constant pool POOL.
5937 Return an RTX describing the distance from the start of
5938 the pool to the location of the new constant. */
5941 s390_find_constant (struct constant_pool
*pool
, rtx val
,
5942 enum machine_mode mode
)
5947 for (i
= 0; i
< NR_C_MODES
; i
++)
5948 if (constant_modes
[i
] == mode
)
5950 gcc_assert (i
!= NR_C_MODES
);
5952 for (c
= pool
->constants
[i
]; c
!= NULL
; c
= c
->next
)
5953 if (rtx_equal_p (val
, c
->value
))
5958 return s390_pool_offset (pool
, gen_rtx_LABEL_REF (Pmode
, c
->label
));
5961 /* Check whether INSN is an execute. Return the label_ref to its
5962 execute target template if so, NULL_RTX otherwise. */
5965 s390_execute_label (rtx insn
)
5967 if (GET_CODE (insn
) == INSN
5968 && GET_CODE (PATTERN (insn
)) == PARALLEL
5969 && GET_CODE (XVECEXP (PATTERN (insn
), 0, 0)) == UNSPEC
5970 && XINT (XVECEXP (PATTERN (insn
), 0, 0), 1) == UNSPEC_EXECUTE
)
5971 return XVECEXP (XVECEXP (PATTERN (insn
), 0, 0), 0, 2);
5976 /* Add execute target for INSN to the constant pool POOL. */
5979 s390_add_execute (struct constant_pool
*pool
, rtx insn
)
5983 for (c
= pool
->execute
; c
!= NULL
; c
= c
->next
)
5984 if (INSN_UID (insn
) == INSN_UID (c
->value
))
5989 c
= (struct constant
*) xmalloc (sizeof *c
);
5991 c
->label
= gen_label_rtx ();
5992 c
->next
= pool
->execute
;
5998 /* Find execute target for INSN in the constant pool POOL.
5999 Return an RTX describing the distance from the start of
6000 the pool to the location of the execute target. */
6003 s390_find_execute (struct constant_pool
*pool
, rtx insn
)
6007 for (c
= pool
->execute
; c
!= NULL
; c
= c
->next
)
6008 if (INSN_UID (insn
) == INSN_UID (c
->value
))
6013 return s390_pool_offset (pool
, gen_rtx_LABEL_REF (Pmode
, c
->label
));
6016 /* For an execute INSN, extract the execute target template. */
6019 s390_execute_target (rtx insn
)
6021 rtx pattern
= PATTERN (insn
);
6022 gcc_assert (s390_execute_label (insn
));
6024 if (XVECLEN (pattern
, 0) == 2)
6026 pattern
= copy_rtx (XVECEXP (pattern
, 0, 1));
6030 rtvec vec
= rtvec_alloc (XVECLEN (pattern
, 0) - 1);
6033 for (i
= 0; i
< XVECLEN (pattern
, 0) - 1; i
++)
6034 RTVEC_ELT (vec
, i
) = copy_rtx (XVECEXP (pattern
, 0, i
+ 1));
6036 pattern
= gen_rtx_PARALLEL (VOIDmode
, vec
);
6042 /* Indicate that INSN cannot be duplicated. This is the case for
6043 execute insns that carry a unique label. */
6046 s390_cannot_copy_insn_p (rtx insn
)
6048 rtx label
= s390_execute_label (insn
);
6049 return label
&& label
!= const0_rtx
;
6052 /* Dump out the constants in POOL. If REMOTE_LABEL is true,
6053 do not emit the pool base label. */
6056 s390_dump_pool (struct constant_pool
*pool
, bool remote_label
)
6059 rtx insn
= pool
->pool_insn
;
6062 /* Switch to rodata section. */
6063 if (TARGET_CPU_ZARCH
)
6065 insn
= emit_insn_after (gen_pool_section_start (), insn
);
6066 INSN_ADDRESSES_NEW (insn
, -1);
6069 /* Ensure minimum pool alignment. */
6070 if (TARGET_CPU_ZARCH
)
6071 insn
= emit_insn_after (gen_pool_align (GEN_INT (8)), insn
);
6073 insn
= emit_insn_after (gen_pool_align (GEN_INT (4)), insn
);
6074 INSN_ADDRESSES_NEW (insn
, -1);
6076 /* Emit pool base label. */
6079 insn
= emit_label_after (pool
->label
, insn
);
6080 INSN_ADDRESSES_NEW (insn
, -1);
6083 /* Dump constants in descending alignment requirement order,
6084 ensuring proper alignment for every constant. */
6085 for (i
= 0; i
< NR_C_MODES
; i
++)
6086 for (c
= pool
->constants
[i
]; c
; c
= c
->next
)
6088 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
6089 rtx value
= copy_rtx (c
->value
);
6090 if (GET_CODE (value
) == CONST
6091 && GET_CODE (XEXP (value
, 0)) == UNSPEC
6092 && XINT (XEXP (value
, 0), 1) == UNSPEC_LTREL_OFFSET
6093 && XVECLEN (XEXP (value
, 0), 0) == 1)
6094 value
= s390_pool_offset (pool
, XVECEXP (XEXP (value
, 0), 0, 0));
6096 insn
= emit_label_after (c
->label
, insn
);
6097 INSN_ADDRESSES_NEW (insn
, -1);
6099 value
= gen_rtx_UNSPEC_VOLATILE (constant_modes
[i
],
6100 gen_rtvec (1, value
),
6101 UNSPECV_POOL_ENTRY
);
6102 insn
= emit_insn_after (value
, insn
);
6103 INSN_ADDRESSES_NEW (insn
, -1);
6106 /* Ensure minimum alignment for instructions. */
6107 insn
= emit_insn_after (gen_pool_align (GEN_INT (2)), insn
);
6108 INSN_ADDRESSES_NEW (insn
, -1);
6110 /* Output in-pool execute template insns. */
6111 for (c
= pool
->execute
; c
; c
= c
->next
)
6113 insn
= emit_label_after (c
->label
, insn
);
6114 INSN_ADDRESSES_NEW (insn
, -1);
6116 insn
= emit_insn_after (s390_execute_target (c
->value
), insn
);
6117 INSN_ADDRESSES_NEW (insn
, -1);
6120 /* Switch back to previous section. */
6121 if (TARGET_CPU_ZARCH
)
6123 insn
= emit_insn_after (gen_pool_section_end (), insn
);
6124 INSN_ADDRESSES_NEW (insn
, -1);
6127 insn
= emit_barrier_after (insn
);
6128 INSN_ADDRESSES_NEW (insn
, -1);
6130 /* Remove placeholder insn. */
6131 remove_insn (pool
->pool_insn
);
6134 /* Free all memory used by POOL. */
6137 s390_free_pool (struct constant_pool
*pool
)
6139 struct constant
*c
, *next
;
6142 for (i
= 0; i
< NR_C_MODES
; i
++)
6143 for (c
= pool
->constants
[i
]; c
; c
= next
)
6149 for (c
= pool
->execute
; c
; c
= next
)
6155 BITMAP_FREE (pool
->insns
);
6160 /* Collect main literal pool. Return NULL on overflow. */
6162 static struct constant_pool
*
6163 s390_mainpool_start (void)
6165 struct constant_pool
*pool
;
6168 pool
= s390_alloc_pool ();
6170 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6172 if (GET_CODE (insn
) == INSN
6173 && GET_CODE (PATTERN (insn
)) == SET
6174 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC_VOLATILE
6175 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPECV_MAIN_POOL
)
6177 gcc_assert (!pool
->pool_insn
);
6178 pool
->pool_insn
= insn
;
6181 if (!TARGET_CPU_ZARCH
&& s390_execute_label (insn
))
6183 s390_add_execute (pool
, insn
);
6185 else if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
6187 rtx pool_ref
= NULL_RTX
;
6188 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
6191 rtx constant
= get_pool_constant (pool_ref
);
6192 enum machine_mode mode
= get_pool_mode (pool_ref
);
6193 s390_add_constant (pool
, constant
, mode
);
6197 /* If hot/cold partitioning is enabled we have to make sure that
6198 the literal pool is emitted in the same section where the
6199 initialization of the literal pool base pointer takes place.
6200 emit_pool_after is only used in the non-overflow case on non
6201 Z cpus where we can emit the literal pool at the end of the
6202 function body within the text section. */
6204 && NOTE_KIND (insn
) == NOTE_INSN_SWITCH_TEXT_SECTIONS
6205 && !pool
->emit_pool_after
)
6206 pool
->emit_pool_after
= PREV_INSN (insn
);
6209 gcc_assert (pool
->pool_insn
|| pool
->size
== 0);
6211 if (pool
->size
>= 4096)
6213 /* We're going to chunkify the pool, so remove the main
6214 pool placeholder insn. */
6215 remove_insn (pool
->pool_insn
);
6217 s390_free_pool (pool
);
6221 /* If the functions ends with the section where the literal pool
6222 should be emitted set the marker to its end. */
6223 if (pool
&& !pool
->emit_pool_after
)
6224 pool
->emit_pool_after
= get_last_insn ();
6229 /* POOL holds the main literal pool as collected by s390_mainpool_start.
6230 Modify the current function to output the pool constants as well as
6231 the pool register setup instruction. */
6234 s390_mainpool_finish (struct constant_pool
*pool
)
6236 rtx base_reg
= cfun
->machine
->base_reg
;
6239 /* If the pool is empty, we're done. */
6240 if (pool
->size
== 0)
6242 /* We don't actually need a base register after all. */
6243 cfun
->machine
->base_reg
= NULL_RTX
;
6245 if (pool
->pool_insn
)
6246 remove_insn (pool
->pool_insn
);
6247 s390_free_pool (pool
);
6251 /* We need correct insn addresses. */
6252 shorten_branches (get_insns ());
6254 /* On zSeries, we use a LARL to load the pool register. The pool is
6255 located in the .rodata section, so we emit it after the function. */
6256 if (TARGET_CPU_ZARCH
)
6258 insn
= gen_main_base_64 (base_reg
, pool
->label
);
6259 insn
= emit_insn_after (insn
, pool
->pool_insn
);
6260 INSN_ADDRESSES_NEW (insn
, -1);
6261 remove_insn (pool
->pool_insn
);
6263 insn
= get_last_insn ();
6264 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
6265 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
6267 s390_dump_pool (pool
, 0);
6270 /* On S/390, if the total size of the function's code plus literal pool
6271 does not exceed 4096 bytes, we use BASR to set up a function base
6272 pointer, and emit the literal pool at the end of the function. */
6273 else if (INSN_ADDRESSES (INSN_UID (pool
->emit_pool_after
))
6274 + pool
->size
+ 8 /* alignment slop */ < 4096)
6276 insn
= gen_main_base_31_small (base_reg
, pool
->label
);
6277 insn
= emit_insn_after (insn
, pool
->pool_insn
);
6278 INSN_ADDRESSES_NEW (insn
, -1);
6279 remove_insn (pool
->pool_insn
);
6281 insn
= emit_label_after (pool
->label
, insn
);
6282 INSN_ADDRESSES_NEW (insn
, -1);
6284 /* emit_pool_after will be set by s390_mainpool_start to the
6285 last insn of the section where the literal pool should be
6287 insn
= pool
->emit_pool_after
;
6289 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
6290 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
6292 s390_dump_pool (pool
, 1);
6295 /* Otherwise, we emit an inline literal pool and use BASR to branch
6296 over it, setting up the pool register at the same time. */
6299 rtx pool_end
= gen_label_rtx ();
6301 insn
= gen_main_base_31_large (base_reg
, pool
->label
, pool_end
);
6302 insn
= emit_insn_after (insn
, pool
->pool_insn
);
6303 INSN_ADDRESSES_NEW (insn
, -1);
6304 remove_insn (pool
->pool_insn
);
6306 insn
= emit_label_after (pool
->label
, insn
);
6307 INSN_ADDRESSES_NEW (insn
, -1);
6309 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
6310 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
6312 insn
= emit_label_after (pool_end
, pool
->pool_insn
);
6313 INSN_ADDRESSES_NEW (insn
, -1);
6315 s390_dump_pool (pool
, 1);
6319 /* Replace all literal pool references. */
6321 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6324 replace_ltrel_base (&PATTERN (insn
));
6326 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
6328 rtx addr
, pool_ref
= NULL_RTX
;
6329 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
6332 if (s390_execute_label (insn
))
6333 addr
= s390_find_execute (pool
, insn
);
6335 addr
= s390_find_constant (pool
, get_pool_constant (pool_ref
),
6336 get_pool_mode (pool_ref
));
6338 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
6339 INSN_CODE (insn
) = -1;
6345 /* Free the pool. */
6346 s390_free_pool (pool
);
6349 /* POOL holds the main literal pool as collected by s390_mainpool_start.
6350 We have decided we cannot use this pool, so revert all changes
6351 to the current function that were done by s390_mainpool_start. */
6353 s390_mainpool_cancel (struct constant_pool
*pool
)
6355 /* We didn't actually change the instruction stream, so simply
6356 free the pool memory. */
6357 s390_free_pool (pool
);
6361 /* Chunkify the literal pool. */
6363 #define S390_POOL_CHUNK_MIN 0xc00
6364 #define S390_POOL_CHUNK_MAX 0xe00
6366 static struct constant_pool
*
6367 s390_chunkify_start (void)
6369 struct constant_pool
*curr_pool
= NULL
, *pool_list
= NULL
;
6372 rtx pending_ltrel
= NULL_RTX
;
6375 rtx (*gen_reload_base
) (rtx
, rtx
) =
6376 TARGET_CPU_ZARCH
? gen_reload_base_64
: gen_reload_base_31
;
6379 /* We need correct insn addresses. */
6381 shorten_branches (get_insns ());
6383 /* Scan all insns and move literals to pool chunks. */
6385 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6387 bool section_switch_p
= false;
6389 /* Check for pending LTREL_BASE. */
6392 rtx ltrel_base
= find_ltrel_base (PATTERN (insn
));
6395 gcc_assert (ltrel_base
== pending_ltrel
);
6396 pending_ltrel
= NULL_RTX
;
6400 if (!TARGET_CPU_ZARCH
&& s390_execute_label (insn
))
6403 curr_pool
= s390_start_pool (&pool_list
, insn
);
6405 s390_add_execute (curr_pool
, insn
);
6406 s390_add_pool_insn (curr_pool
, insn
);
6408 else if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
6410 rtx pool_ref
= NULL_RTX
;
6411 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
6414 rtx constant
= get_pool_constant (pool_ref
);
6415 enum machine_mode mode
= get_pool_mode (pool_ref
);
6418 curr_pool
= s390_start_pool (&pool_list
, insn
);
6420 s390_add_constant (curr_pool
, constant
, mode
);
6421 s390_add_pool_insn (curr_pool
, insn
);
6423 /* Don't split the pool chunk between a LTREL_OFFSET load
6424 and the corresponding LTREL_BASE. */
6425 if (GET_CODE (constant
) == CONST
6426 && GET_CODE (XEXP (constant
, 0)) == UNSPEC
6427 && XINT (XEXP (constant
, 0), 1) == UNSPEC_LTREL_OFFSET
)
6429 gcc_assert (!pending_ltrel
);
6430 pending_ltrel
= pool_ref
;
6435 if (GET_CODE (insn
) == JUMP_INSN
|| GET_CODE (insn
) == CODE_LABEL
)
6438 s390_add_pool_insn (curr_pool
, insn
);
6439 /* An LTREL_BASE must follow within the same basic block. */
6440 gcc_assert (!pending_ltrel
);
6443 if (NOTE_P (insn
) && NOTE_KIND (insn
) == NOTE_INSN_SWITCH_TEXT_SECTIONS
)
6444 section_switch_p
= true;
6447 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn
)
6448 || INSN_ADDRESSES (INSN_UID (insn
)) == -1)
6451 if (TARGET_CPU_ZARCH
)
6453 if (curr_pool
->size
< S390_POOL_CHUNK_MAX
)
6456 s390_end_pool (curr_pool
, NULL_RTX
);
6461 int chunk_size
= INSN_ADDRESSES (INSN_UID (insn
))
6462 - INSN_ADDRESSES (INSN_UID (curr_pool
->first_insn
))
6465 /* We will later have to insert base register reload insns.
6466 Those will have an effect on code size, which we need to
6467 consider here. This calculation makes rather pessimistic
6468 worst-case assumptions. */
6469 if (GET_CODE (insn
) == CODE_LABEL
)
6472 if (chunk_size
< S390_POOL_CHUNK_MIN
6473 && curr_pool
->size
< S390_POOL_CHUNK_MIN
6474 && !section_switch_p
)
6477 /* Pool chunks can only be inserted after BARRIERs ... */
6478 if (GET_CODE (insn
) == BARRIER
)
6480 s390_end_pool (curr_pool
, insn
);
6485 /* ... so if we don't find one in time, create one. */
6486 else if (chunk_size
> S390_POOL_CHUNK_MAX
6487 || curr_pool
->size
> S390_POOL_CHUNK_MAX
6488 || section_switch_p
)
6490 rtx label
, jump
, barrier
;
6492 if (!section_switch_p
)
6494 /* We can insert the barrier only after a 'real' insn. */
6495 if (GET_CODE (insn
) != INSN
&& GET_CODE (insn
) != CALL_INSN
)
6497 if (get_attr_length (insn
) == 0)
6499 /* Don't separate LTREL_BASE from the corresponding
6500 LTREL_OFFSET load. */
6506 gcc_assert (!pending_ltrel
);
6508 /* The old pool has to end before the section switch
6509 note in order to make it part of the current
6511 insn
= PREV_INSN (insn
);
6514 label
= gen_label_rtx ();
6515 jump
= emit_jump_insn_after (gen_jump (label
), insn
);
6516 barrier
= emit_barrier_after (jump
);
6517 insn
= emit_label_after (label
, barrier
);
6518 JUMP_LABEL (jump
) = label
;
6519 LABEL_NUSES (label
) = 1;
6521 INSN_ADDRESSES_NEW (jump
, -1);
6522 INSN_ADDRESSES_NEW (barrier
, -1);
6523 INSN_ADDRESSES_NEW (insn
, -1);
6525 s390_end_pool (curr_pool
, barrier
);
6533 s390_end_pool (curr_pool
, NULL_RTX
);
6534 gcc_assert (!pending_ltrel
);
6536 /* Find all labels that are branched into
6537 from an insn belonging to a different chunk. */
6539 far_labels
= BITMAP_ALLOC (NULL
);
6541 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6543 /* Labels marked with LABEL_PRESERVE_P can be target
6544 of non-local jumps, so we have to mark them.
6545 The same holds for named labels.
6547 Don't do that, however, if it is the label before
6550 if (GET_CODE (insn
) == CODE_LABEL
6551 && (LABEL_PRESERVE_P (insn
) || LABEL_NAME (insn
)))
6553 rtx vec_insn
= next_real_insn (insn
);
6554 rtx vec_pat
= vec_insn
&& GET_CODE (vec_insn
) == JUMP_INSN
?
6555 PATTERN (vec_insn
) : NULL_RTX
;
6557 || !(GET_CODE (vec_pat
) == ADDR_VEC
6558 || GET_CODE (vec_pat
) == ADDR_DIFF_VEC
))
6559 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (insn
));
6562 /* If we have a direct jump (conditional or unconditional)
6563 or a casesi jump, check all potential targets. */
6564 else if (GET_CODE (insn
) == JUMP_INSN
)
6566 rtx pat
= PATTERN (insn
);
6567 if (GET_CODE (pat
) == PARALLEL
&& XVECLEN (pat
, 0) > 2)
6568 pat
= XVECEXP (pat
, 0, 0);
6570 if (GET_CODE (pat
) == SET
)
6572 rtx label
= JUMP_LABEL (insn
);
6575 if (s390_find_pool (pool_list
, label
)
6576 != s390_find_pool (pool_list
, insn
))
6577 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
6580 else if (GET_CODE (pat
) == PARALLEL
6581 && XVECLEN (pat
, 0) == 2
6582 && GET_CODE (XVECEXP (pat
, 0, 0)) == SET
6583 && GET_CODE (XVECEXP (pat
, 0, 1)) == USE
6584 && GET_CODE (XEXP (XVECEXP (pat
, 0, 1), 0)) == LABEL_REF
)
6586 /* Find the jump table used by this casesi jump. */
6587 rtx vec_label
= XEXP (XEXP (XVECEXP (pat
, 0, 1), 0), 0);
6588 rtx vec_insn
= next_real_insn (vec_label
);
6589 rtx vec_pat
= vec_insn
&& GET_CODE (vec_insn
) == JUMP_INSN
?
6590 PATTERN (vec_insn
) : NULL_RTX
;
6592 && (GET_CODE (vec_pat
) == ADDR_VEC
6593 || GET_CODE (vec_pat
) == ADDR_DIFF_VEC
))
6595 int i
, diff_p
= GET_CODE (vec_pat
) == ADDR_DIFF_VEC
;
6597 for (i
= 0; i
< XVECLEN (vec_pat
, diff_p
); i
++)
6599 rtx label
= XEXP (XVECEXP (vec_pat
, diff_p
, i
), 0);
6601 if (s390_find_pool (pool_list
, label
)
6602 != s390_find_pool (pool_list
, insn
))
6603 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
6610 /* Insert base register reload insns before every pool. */
6612 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
6614 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
6616 rtx insn
= curr_pool
->first_insn
;
6617 INSN_ADDRESSES_NEW (emit_insn_before (new_insn
, insn
), -1);
6620 /* Insert base register reload insns at every far label. */
6622 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6623 if (GET_CODE (insn
) == CODE_LABEL
6624 && bitmap_bit_p (far_labels
, CODE_LABEL_NUMBER (insn
)))
6626 struct constant_pool
*pool
= s390_find_pool (pool_list
, insn
);
6629 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
6631 INSN_ADDRESSES_NEW (emit_insn_after (new_insn
, insn
), -1);
6636 BITMAP_FREE (far_labels
);
6639 /* Recompute insn addresses. */
6641 init_insn_lengths ();
6642 shorten_branches (get_insns ());
6647 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
6648 After we have decided to use this list, finish implementing
6649 all changes to the current function as required. */
6652 s390_chunkify_finish (struct constant_pool
*pool_list
)
6654 struct constant_pool
*curr_pool
= NULL
;
6658 /* Replace all literal pool references. */
6660 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6663 replace_ltrel_base (&PATTERN (insn
));
6665 curr_pool
= s390_find_pool (pool_list
, insn
);
6669 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
6671 rtx addr
, pool_ref
= NULL_RTX
;
6672 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
6675 if (s390_execute_label (insn
))
6676 addr
= s390_find_execute (curr_pool
, insn
);
6678 addr
= s390_find_constant (curr_pool
,
6679 get_pool_constant (pool_ref
),
6680 get_pool_mode (pool_ref
));
6682 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
6683 INSN_CODE (insn
) = -1;
6688 /* Dump out all literal pools. */
6690 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
6691 s390_dump_pool (curr_pool
, 0);
6693 /* Free pool list. */
6697 struct constant_pool
*next
= pool_list
->next
;
6698 s390_free_pool (pool_list
);
6703 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
6704 We have decided we cannot use this list, so revert all changes
6705 to the current function that were done by s390_chunkify_start. */
6708 s390_chunkify_cancel (struct constant_pool
*pool_list
)
6710 struct constant_pool
*curr_pool
= NULL
;
6713 /* Remove all pool placeholder insns. */
6715 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
6717 /* Did we insert an extra barrier? Remove it. */
6718 rtx barrier
= PREV_INSN (curr_pool
->pool_insn
);
6719 rtx jump
= barrier
? PREV_INSN (barrier
) : NULL_RTX
;
6720 rtx label
= NEXT_INSN (curr_pool
->pool_insn
);
6722 if (jump
&& GET_CODE (jump
) == JUMP_INSN
6723 && barrier
&& GET_CODE (barrier
) == BARRIER
6724 && label
&& GET_CODE (label
) == CODE_LABEL
6725 && GET_CODE (PATTERN (jump
)) == SET
6726 && SET_DEST (PATTERN (jump
)) == pc_rtx
6727 && GET_CODE (SET_SRC (PATTERN (jump
))) == LABEL_REF
6728 && XEXP (SET_SRC (PATTERN (jump
)), 0) == label
)
6731 remove_insn (barrier
);
6732 remove_insn (label
);
6735 remove_insn (curr_pool
->pool_insn
);
6738 /* Remove all base register reload insns. */
6740 for (insn
= get_insns (); insn
; )
6742 rtx next_insn
= NEXT_INSN (insn
);
6744 if (GET_CODE (insn
) == INSN
6745 && GET_CODE (PATTERN (insn
)) == SET
6746 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC
6747 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPEC_RELOAD_BASE
)
6753 /* Free pool list. */
6757 struct constant_pool
*next
= pool_list
->next
;
6758 s390_free_pool (pool_list
);
6763 /* Output the constant pool entry EXP in mode MODE with alignment ALIGN. */
6766 s390_output_pool_entry (rtx exp
, enum machine_mode mode
, unsigned int align
)
6770 switch (GET_MODE_CLASS (mode
))
6773 case MODE_DECIMAL_FLOAT
:
6774 gcc_assert (GET_CODE (exp
) == CONST_DOUBLE
);
6776 REAL_VALUE_FROM_CONST_DOUBLE (r
, exp
);
6777 assemble_real (r
, mode
, align
);
6781 assemble_integer (exp
, GET_MODE_SIZE (mode
), align
, 1);
6782 mark_symbol_refs_as_used (exp
);
6791 /* Return an RTL expression representing the value of the return address
6792 for the frame COUNT steps up from the current frame. FRAME is the
6793 frame pointer of that frame. */
6796 s390_return_addr_rtx (int count
, rtx frame ATTRIBUTE_UNUSED
)
6801 /* Without backchain, we fail for all but the current frame. */
6803 if (!TARGET_BACKCHAIN
&& count
> 0)
6806 /* For the current frame, we need to make sure the initial
6807 value of RETURN_REGNUM is actually saved. */
6811 /* On non-z architectures branch splitting could overwrite r14. */
6812 if (TARGET_CPU_ZARCH
)
6813 return get_hard_reg_initial_val (Pmode
, RETURN_REGNUM
);
6816 cfun_frame_layout
.save_return_addr_p
= true;
6817 return gen_rtx_MEM (Pmode
, return_address_pointer_rtx
);
6821 if (TARGET_PACKED_STACK
)
6822 offset
= -2 * UNITS_PER_LONG
;
6824 offset
= RETURN_REGNUM
* UNITS_PER_LONG
;
6826 addr
= plus_constant (frame
, offset
);
6827 addr
= memory_address (Pmode
, addr
);
6828 return gen_rtx_MEM (Pmode
, addr
);
6831 /* Return an RTL expression representing the back chain stored in
6832 the current stack frame. */
6835 s390_back_chain_rtx (void)
6839 gcc_assert (TARGET_BACKCHAIN
);
6841 if (TARGET_PACKED_STACK
)
6842 chain
= plus_constant (stack_pointer_rtx
,
6843 STACK_POINTER_OFFSET
- UNITS_PER_LONG
);
6845 chain
= stack_pointer_rtx
;
6847 chain
= gen_rtx_MEM (Pmode
, chain
);
6851 /* Find first call clobbered register unused in a function.
6852 This could be used as base register in a leaf function
6853 or for holding the return address before epilogue. */
6856 find_unused_clobbered_reg (void)
6859 for (i
= 0; i
< 6; i
++)
6860 if (!df_regs_ever_live_p (i
))
6866 /* Helper function for s390_regs_ever_clobbered. Sets the fields in DATA for all
6867 clobbered hard regs in SETREG. */
6870 s390_reg_clobbered_rtx (rtx setreg
, const_rtx set_insn ATTRIBUTE_UNUSED
, void *data
)
6872 int *regs_ever_clobbered
= (int *)data
;
6873 unsigned int i
, regno
;
6874 enum machine_mode mode
= GET_MODE (setreg
);
6876 if (GET_CODE (setreg
) == SUBREG
)
6878 rtx inner
= SUBREG_REG (setreg
);
6879 if (!GENERAL_REG_P (inner
))
6881 regno
= subreg_regno (setreg
);
6883 else if (GENERAL_REG_P (setreg
))
6884 regno
= REGNO (setreg
);
6889 i
< regno
+ HARD_REGNO_NREGS (regno
, mode
);
6891 regs_ever_clobbered
[i
] = 1;
6894 /* Walks through all basic blocks of the current function looking
6895 for clobbered hard regs using s390_reg_clobbered_rtx. The fields
6896 of the passed integer array REGS_EVER_CLOBBERED are set to one for
6897 each of those regs. */
6900 s390_regs_ever_clobbered (int *regs_ever_clobbered
)
6906 memset (regs_ever_clobbered
, 0, 16 * sizeof (int));
6908 /* For non-leaf functions we have to consider all call clobbered regs to be
6910 if (!current_function_is_leaf
)
6912 for (i
= 0; i
< 16; i
++)
6913 regs_ever_clobbered
[i
] = call_really_used_regs
[i
];
6916 /* Make the "magic" eh_return registers live if necessary. For regs_ever_live
6917 this work is done by liveness analysis (mark_regs_live_at_end).
6918 Special care is needed for functions containing landing pads. Landing pads
6919 may use the eh registers, but the code which sets these registers is not
6920 contained in that function. Hence s390_regs_ever_clobbered is not able to
6921 deal with this automatically. */
6922 if (crtl
->calls_eh_return
|| cfun
->machine
->has_landing_pad_p
)
6923 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; i
++)
6924 if (crtl
->calls_eh_return
6925 || (cfun
->machine
->has_landing_pad_p
6926 && df_regs_ever_live_p (EH_RETURN_DATA_REGNO (i
))))
6927 regs_ever_clobbered
[EH_RETURN_DATA_REGNO (i
)] = 1;
6929 /* For nonlocal gotos all call-saved registers have to be saved.
6930 This flag is also set for the unwinding code in libgcc.
6931 See expand_builtin_unwind_init. For regs_ever_live this is done by
6933 if (cfun
->has_nonlocal_label
)
6934 for (i
= 0; i
< 16; i
++)
6935 if (!call_really_used_regs
[i
])
6936 regs_ever_clobbered
[i
] = 1;
6938 FOR_EACH_BB (cur_bb
)
6940 FOR_BB_INSNS (cur_bb
, cur_insn
)
6942 if (INSN_P (cur_insn
))
6943 note_stores (PATTERN (cur_insn
),
6944 s390_reg_clobbered_rtx
,
6945 regs_ever_clobbered
);
6950 /* Determine the frame area which actually has to be accessed
6951 in the function epilogue. The values are stored at the
6952 given pointers AREA_BOTTOM (address of the lowest used stack
6953 address) and AREA_TOP (address of the first item which does
6954 not belong to the stack frame). */
6957 s390_frame_area (int *area_bottom
, int *area_top
)
6965 if (cfun_frame_layout
.first_restore_gpr
!= -1)
6967 b
= (cfun_frame_layout
.gprs_offset
6968 + cfun_frame_layout
.first_restore_gpr
* UNITS_PER_LONG
);
6969 t
= b
+ (cfun_frame_layout
.last_restore_gpr
6970 - cfun_frame_layout
.first_restore_gpr
+ 1) * UNITS_PER_LONG
;
6973 if (TARGET_64BIT
&& cfun_save_high_fprs_p
)
6975 b
= MIN (b
, cfun_frame_layout
.f8_offset
);
6976 t
= MAX (t
, (cfun_frame_layout
.f8_offset
6977 + cfun_frame_layout
.high_fprs
* 8));
6981 for (i
= 2; i
< 4; i
++)
6982 if (cfun_fpr_bit_p (i
))
6984 b
= MIN (b
, cfun_frame_layout
.f4_offset
+ (i
- 2) * 8);
6985 t
= MAX (t
, cfun_frame_layout
.f4_offset
+ (i
- 1) * 8);
6992 /* Fill cfun->machine with info about register usage of current function.
6993 Return in CLOBBERED_REGS which GPRs are currently considered set. */
6996 s390_register_info (int clobbered_regs
[])
7000 /* fprs 8 - 15 are call saved for 64 Bit ABI. */
7001 cfun_frame_layout
.fpr_bitmap
= 0;
7002 cfun_frame_layout
.high_fprs
= 0;
7004 for (i
= 24; i
< 32; i
++)
7005 if (df_regs_ever_live_p (i
) && !global_regs
[i
])
7007 cfun_set_fpr_bit (i
- 16);
7008 cfun_frame_layout
.high_fprs
++;
7011 /* Find first and last gpr to be saved. We trust regs_ever_live
7012 data, except that we don't save and restore global registers.
7014 Also, all registers with special meaning to the compiler need
7015 to be handled extra. */
7017 s390_regs_ever_clobbered (clobbered_regs
);
7019 for (i
= 0; i
< 16; i
++)
7020 clobbered_regs
[i
] = clobbered_regs
[i
] && !global_regs
[i
] && !fixed_regs
[i
];
7022 if (frame_pointer_needed
)
7023 clobbered_regs
[HARD_FRAME_POINTER_REGNUM
] = 1;
7026 clobbered_regs
[PIC_OFFSET_TABLE_REGNUM
]
7027 |= df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM
);
7029 clobbered_regs
[BASE_REGNUM
]
7030 |= (cfun
->machine
->base_reg
7031 && REGNO (cfun
->machine
->base_reg
) == BASE_REGNUM
);
7033 clobbered_regs
[RETURN_REGNUM
]
7034 |= (!current_function_is_leaf
7035 || TARGET_TPF_PROFILING
7036 || cfun
->machine
->split_branches_pending_p
7037 || cfun_frame_layout
.save_return_addr_p
7038 || crtl
->calls_eh_return
7041 clobbered_regs
[STACK_POINTER_REGNUM
]
7042 |= (!current_function_is_leaf
7043 || TARGET_TPF_PROFILING
7044 || cfun_save_high_fprs_p
7045 || get_frame_size () > 0
7046 || cfun
->calls_alloca
7049 for (i
= 6; i
< 16; i
++)
7050 if (df_regs_ever_live_p (i
) || clobbered_regs
[i
])
7052 for (j
= 15; j
> i
; j
--)
7053 if (df_regs_ever_live_p (j
) || clobbered_regs
[j
])
7058 /* Nothing to save/restore. */
7059 cfun_frame_layout
.first_save_gpr_slot
= -1;
7060 cfun_frame_layout
.last_save_gpr_slot
= -1;
7061 cfun_frame_layout
.first_save_gpr
= -1;
7062 cfun_frame_layout
.first_restore_gpr
= -1;
7063 cfun_frame_layout
.last_save_gpr
= -1;
7064 cfun_frame_layout
.last_restore_gpr
= -1;
7068 /* Save slots for gprs from i to j. */
7069 cfun_frame_layout
.first_save_gpr_slot
= i
;
7070 cfun_frame_layout
.last_save_gpr_slot
= j
;
7072 for (i
= cfun_frame_layout
.first_save_gpr_slot
;
7073 i
< cfun_frame_layout
.last_save_gpr_slot
+ 1;
7075 if (clobbered_regs
[i
])
7078 for (j
= cfun_frame_layout
.last_save_gpr_slot
; j
> i
; j
--)
7079 if (clobbered_regs
[j
])
7082 if (i
== cfun_frame_layout
.last_save_gpr_slot
+ 1)
7084 /* Nothing to save/restore. */
7085 cfun_frame_layout
.first_save_gpr
= -1;
7086 cfun_frame_layout
.first_restore_gpr
= -1;
7087 cfun_frame_layout
.last_save_gpr
= -1;
7088 cfun_frame_layout
.last_restore_gpr
= -1;
7092 /* Save / Restore from gpr i to j. */
7093 cfun_frame_layout
.first_save_gpr
= i
;
7094 cfun_frame_layout
.first_restore_gpr
= i
;
7095 cfun_frame_layout
.last_save_gpr
= j
;
7096 cfun_frame_layout
.last_restore_gpr
= j
;
7102 /* Varargs functions need to save gprs 2 to 6. */
7103 if (cfun
->va_list_gpr_size
7104 && crtl
->args
.info
.gprs
< GP_ARG_NUM_REG
)
7106 int min_gpr
= crtl
->args
.info
.gprs
;
7107 int max_gpr
= min_gpr
+ cfun
->va_list_gpr_size
;
7108 if (max_gpr
> GP_ARG_NUM_REG
)
7109 max_gpr
= GP_ARG_NUM_REG
;
7111 if (cfun_frame_layout
.first_save_gpr
== -1
7112 || cfun_frame_layout
.first_save_gpr
> 2 + min_gpr
)
7114 cfun_frame_layout
.first_save_gpr
= 2 + min_gpr
;
7115 cfun_frame_layout
.first_save_gpr_slot
= 2 + min_gpr
;
7118 if (cfun_frame_layout
.last_save_gpr
== -1
7119 || cfun_frame_layout
.last_save_gpr
< 2 + max_gpr
- 1)
7121 cfun_frame_layout
.last_save_gpr
= 2 + max_gpr
- 1;
7122 cfun_frame_layout
.last_save_gpr_slot
= 2 + max_gpr
- 1;
7126 /* Mark f0, f2 for 31 bit and f0-f4 for 64 bit to be saved. */
7127 if (TARGET_HARD_FLOAT
&& cfun
->va_list_fpr_size
7128 && crtl
->args
.info
.fprs
< FP_ARG_NUM_REG
)
7130 int min_fpr
= crtl
->args
.info
.fprs
;
7131 int max_fpr
= min_fpr
+ cfun
->va_list_fpr_size
;
7132 if (max_fpr
> FP_ARG_NUM_REG
)
7133 max_fpr
= FP_ARG_NUM_REG
;
7135 /* ??? This is currently required to ensure proper location
7136 of the fpr save slots within the va_list save area. */
7137 if (TARGET_PACKED_STACK
)
7140 for (i
= min_fpr
; i
< max_fpr
; i
++)
7141 cfun_set_fpr_bit (i
);
7146 for (i
= 2; i
< 4; i
++)
7147 if (df_regs_ever_live_p (i
+ 16) && !global_regs
[i
+ 16])
7148 cfun_set_fpr_bit (i
);
7151 /* Fill cfun->machine with info about frame of current function. */
7154 s390_frame_info (void)
7158 cfun_frame_layout
.frame_size
= get_frame_size ();
7159 if (!TARGET_64BIT
&& cfun_frame_layout
.frame_size
> 0x7fff0000)
7160 fatal_error ("total size of local variables exceeds architecture limit");
7162 if (!TARGET_PACKED_STACK
)
7164 cfun_frame_layout
.backchain_offset
= 0;
7165 cfun_frame_layout
.f0_offset
= 16 * UNITS_PER_LONG
;
7166 cfun_frame_layout
.f4_offset
= cfun_frame_layout
.f0_offset
+ 2 * 8;
7167 cfun_frame_layout
.f8_offset
= -cfun_frame_layout
.high_fprs
* 8;
7168 cfun_frame_layout
.gprs_offset
= (cfun_frame_layout
.first_save_gpr_slot
7171 else if (TARGET_BACKCHAIN
) /* kernel stack layout */
7173 cfun_frame_layout
.backchain_offset
= (STACK_POINTER_OFFSET
7175 cfun_frame_layout
.gprs_offset
7176 = (cfun_frame_layout
.backchain_offset
7177 - (STACK_POINTER_REGNUM
- cfun_frame_layout
.first_save_gpr_slot
+ 1)
7182 cfun_frame_layout
.f4_offset
7183 = (cfun_frame_layout
.gprs_offset
7184 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
7186 cfun_frame_layout
.f0_offset
7187 = (cfun_frame_layout
.f4_offset
7188 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
7192 /* On 31 bit we have to care about alignment of the
7193 floating point regs to provide fastest access. */
7194 cfun_frame_layout
.f0_offset
7195 = ((cfun_frame_layout
.gprs_offset
7196 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1))
7197 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
7199 cfun_frame_layout
.f4_offset
7200 = (cfun_frame_layout
.f0_offset
7201 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
7204 else /* no backchain */
7206 cfun_frame_layout
.f4_offset
7207 = (STACK_POINTER_OFFSET
7208 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
7210 cfun_frame_layout
.f0_offset
7211 = (cfun_frame_layout
.f4_offset
7212 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
7214 cfun_frame_layout
.gprs_offset
7215 = cfun_frame_layout
.f0_offset
- cfun_gprs_save_area_size
;
7218 if (current_function_is_leaf
7219 && !TARGET_TPF_PROFILING
7220 && cfun_frame_layout
.frame_size
== 0
7221 && !cfun_save_high_fprs_p
7222 && !cfun
->calls_alloca
7226 if (!TARGET_PACKED_STACK
)
7227 cfun_frame_layout
.frame_size
+= (STACK_POINTER_OFFSET
7228 + crtl
->outgoing_args_size
7229 + cfun_frame_layout
.high_fprs
* 8);
7232 if (TARGET_BACKCHAIN
)
7233 cfun_frame_layout
.frame_size
+= UNITS_PER_LONG
;
7235 /* No alignment trouble here because f8-f15 are only saved under
7237 cfun_frame_layout
.f8_offset
= (MIN (MIN (cfun_frame_layout
.f0_offset
,
7238 cfun_frame_layout
.f4_offset
),
7239 cfun_frame_layout
.gprs_offset
)
7240 - cfun_frame_layout
.high_fprs
* 8);
7242 cfun_frame_layout
.frame_size
+= cfun_frame_layout
.high_fprs
* 8;
7244 for (i
= 0; i
< 8; i
++)
7245 if (cfun_fpr_bit_p (i
))
7246 cfun_frame_layout
.frame_size
+= 8;
7248 cfun_frame_layout
.frame_size
+= cfun_gprs_save_area_size
;
7250 /* If under 31 bit an odd number of gprs has to be saved we have to adjust
7251 the frame size to sustain 8 byte alignment of stack frames. */
7252 cfun_frame_layout
.frame_size
= ((cfun_frame_layout
.frame_size
+
7253 STACK_BOUNDARY
/ BITS_PER_UNIT
- 1)
7254 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1));
7256 cfun_frame_layout
.frame_size
+= crtl
->outgoing_args_size
;
7260 /* Generate frame layout. Fills in register and frame data for the current
7261 function in cfun->machine. This routine can be called multiple times;
7262 it will re-do the complete frame layout every time. */
7265 s390_init_frame_layout (void)
7267 HOST_WIDE_INT frame_size
;
7269 int clobbered_regs
[16];
7271 /* On S/390 machines, we may need to perform branch splitting, which
7272 will require both base and return address register. We have no
7273 choice but to assume we're going to need them until right at the
7274 end of the machine dependent reorg phase. */
7275 if (!TARGET_CPU_ZARCH
)
7276 cfun
->machine
->split_branches_pending_p
= true;
7280 frame_size
= cfun_frame_layout
.frame_size
;
7282 /* Try to predict whether we'll need the base register. */
7283 base_used
= cfun
->machine
->split_branches_pending_p
7284 || crtl
->uses_const_pool
7285 || (!DISP_IN_RANGE (frame_size
)
7286 && !CONST_OK_FOR_K (frame_size
));
7288 /* Decide which register to use as literal pool base. In small
7289 leaf functions, try to use an unused call-clobbered register
7290 as base register to avoid save/restore overhead. */
7292 cfun
->machine
->base_reg
= NULL_RTX
;
7293 else if (current_function_is_leaf
&& !df_regs_ever_live_p (5))
7294 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, 5);
7296 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
7298 s390_register_info (clobbered_regs
);
7301 while (frame_size
!= cfun_frame_layout
.frame_size
);
7304 /* Update frame layout. Recompute actual register save data based on
7305 current info and update regs_ever_live for the special registers.
7306 May be called multiple times, but may never cause *more* registers
7307 to be saved than s390_init_frame_layout allocated room for. */
7310 s390_update_frame_layout (void)
7312 int clobbered_regs
[16];
7314 s390_register_info (clobbered_regs
);
7316 df_set_regs_ever_live (BASE_REGNUM
,
7317 clobbered_regs
[BASE_REGNUM
] ? true : false);
7318 df_set_regs_ever_live (RETURN_REGNUM
,
7319 clobbered_regs
[RETURN_REGNUM
] ? true : false);
7320 df_set_regs_ever_live (STACK_POINTER_REGNUM
,
7321 clobbered_regs
[STACK_POINTER_REGNUM
] ? true : false);
7323 if (cfun
->machine
->base_reg
)
7324 df_set_regs_ever_live (REGNO (cfun
->machine
->base_reg
), true);
7327 /* Return true if it is legal to put a value with MODE into REGNO. */
7330 s390_hard_regno_mode_ok (unsigned int regno
, enum machine_mode mode
)
7332 switch (REGNO_REG_CLASS (regno
))
7335 if (REGNO_PAIR_OK (regno
, mode
))
7337 if (mode
== SImode
|| mode
== DImode
)
7340 if (FLOAT_MODE_P (mode
) && GET_MODE_CLASS (mode
) != MODE_VECTOR_FLOAT
)
7345 if (FRAME_REGNO_P (regno
) && mode
== Pmode
)
7350 if (REGNO_PAIR_OK (regno
, mode
))
7353 || (mode
!= TFmode
&& mode
!= TCmode
&& mode
!= TDmode
))
7358 if (GET_MODE_CLASS (mode
) == MODE_CC
)
7362 if (REGNO_PAIR_OK (regno
, mode
))
7364 if (mode
== SImode
|| mode
== Pmode
)
7375 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
7378 s390_hard_regno_rename_ok (unsigned int old_reg
, unsigned int new_reg
)
7380 /* Once we've decided upon a register to use as base register, it must
7381 no longer be used for any other purpose. */
7382 if (cfun
->machine
->base_reg
)
7383 if (REGNO (cfun
->machine
->base_reg
) == old_reg
7384 || REGNO (cfun
->machine
->base_reg
) == new_reg
)
7390 /* Maximum number of registers to represent a value of mode MODE
7391 in a register of class RCLASS. */
7394 s390_class_max_nregs (enum reg_class rclass
, enum machine_mode mode
)
7399 if (GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
)
7400 return 2 * ((GET_MODE_SIZE (mode
) / 2 + 8 - 1) / 8);
7402 return (GET_MODE_SIZE (mode
) + 8 - 1) / 8;
7404 return (GET_MODE_SIZE (mode
) + 4 - 1) / 4;
7408 return (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
7411 /* Return true if register FROM can be eliminated via register TO. */
7414 s390_can_eliminate (const int from
, const int to
)
7416 /* On zSeries machines, we have not marked the base register as fixed.
7417 Instead, we have an elimination rule BASE_REGNUM -> BASE_REGNUM.
7418 If a function requires the base register, we say here that this
7419 elimination cannot be performed. This will cause reload to free
7420 up the base register (as if it were fixed). On the other hand,
7421 if the current function does *not* require the base register, we
7422 say here the elimination succeeds, which in turn allows reload
7423 to allocate the base register for any other purpose. */
7424 if (from
== BASE_REGNUM
&& to
== BASE_REGNUM
)
7426 if (TARGET_CPU_ZARCH
)
7428 s390_init_frame_layout ();
7429 return cfun
->machine
->base_reg
== NULL_RTX
;
7435 /* Everything else must point into the stack frame. */
7436 gcc_assert (to
== STACK_POINTER_REGNUM
7437 || to
== HARD_FRAME_POINTER_REGNUM
);
7439 gcc_assert (from
== FRAME_POINTER_REGNUM
7440 || from
== ARG_POINTER_REGNUM
7441 || from
== RETURN_ADDRESS_POINTER_REGNUM
);
7443 /* Make sure we actually saved the return address. */
7444 if (from
== RETURN_ADDRESS_POINTER_REGNUM
)
7445 if (!crtl
->calls_eh_return
7447 && !cfun_frame_layout
.save_return_addr_p
)
7453 /* Return offset between register FROM and TO initially after prolog. */
7456 s390_initial_elimination_offset (int from
, int to
)
7458 HOST_WIDE_INT offset
;
7461 /* ??? Why are we called for non-eliminable pairs? */
7462 if (!s390_can_eliminate (from
, to
))
7467 case FRAME_POINTER_REGNUM
:
7468 offset
= (get_frame_size()
7469 + STACK_POINTER_OFFSET
7470 + crtl
->outgoing_args_size
);
7473 case ARG_POINTER_REGNUM
:
7474 s390_init_frame_layout ();
7475 offset
= cfun_frame_layout
.frame_size
+ STACK_POINTER_OFFSET
;
7478 case RETURN_ADDRESS_POINTER_REGNUM
:
7479 s390_init_frame_layout ();
7480 index
= RETURN_REGNUM
- cfun_frame_layout
.first_save_gpr_slot
;
7481 gcc_assert (index
>= 0);
7482 offset
= cfun_frame_layout
.frame_size
+ cfun_frame_layout
.gprs_offset
;
7483 offset
+= index
* UNITS_PER_LONG
;
7497 /* Emit insn to save fpr REGNUM at offset OFFSET relative
7498 to register BASE. Return generated insn. */
7501 save_fpr (rtx base
, int offset
, int regnum
)
7504 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
7506 if (regnum
>= 16 && regnum
<= (16 + FP_ARG_NUM_REG
))
7507 set_mem_alias_set (addr
, get_varargs_alias_set ());
7509 set_mem_alias_set (addr
, get_frame_alias_set ());
7511 return emit_move_insn (addr
, gen_rtx_REG (DFmode
, regnum
));
7514 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
7515 to register BASE. Return generated insn. */
7518 restore_fpr (rtx base
, int offset
, int regnum
)
7521 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
7522 set_mem_alias_set (addr
, get_frame_alias_set ());
7524 return emit_move_insn (gen_rtx_REG (DFmode
, regnum
), addr
);
7527 /* Return true if REGNO is a global register, but not one
7528 of the special ones that need to be saved/restored in anyway. */
7531 global_not_special_regno_p (int regno
)
7533 return (global_regs
[regno
]
7534 /* These registers are special and need to be
7535 restored in any case. */
7536 && !(regno
== STACK_POINTER_REGNUM
7537 || regno
== RETURN_REGNUM
7538 || regno
== BASE_REGNUM
7539 || (flag_pic
&& regno
== (int)PIC_OFFSET_TABLE_REGNUM
)));
7542 /* Generate insn to save registers FIRST to LAST into
7543 the register save area located at offset OFFSET
7544 relative to register BASE. */
7547 save_gprs (rtx base
, int offset
, int first
, int last
)
7549 rtx addr
, insn
, note
;
7552 addr
= plus_constant (base
, offset
);
7553 addr
= gen_rtx_MEM (Pmode
, addr
);
7555 set_mem_alias_set (addr
, get_frame_alias_set ());
7557 /* Special-case single register. */
7561 insn
= gen_movdi (addr
, gen_rtx_REG (Pmode
, first
));
7563 insn
= gen_movsi (addr
, gen_rtx_REG (Pmode
, first
));
7565 if (!global_not_special_regno_p (first
))
7566 RTX_FRAME_RELATED_P (insn
) = 1;
7571 insn
= gen_store_multiple (addr
,
7572 gen_rtx_REG (Pmode
, first
),
7573 GEN_INT (last
- first
+ 1));
7575 if (first
<= 6 && cfun
->stdarg
)
7576 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
7578 rtx mem
= XEXP (XVECEXP (PATTERN (insn
), 0, i
), 0);
7581 set_mem_alias_set (mem
, get_varargs_alias_set ());
7584 /* We need to set the FRAME_RELATED flag on all SETs
7585 inside the store-multiple pattern.
7587 However, we must not emit DWARF records for registers 2..5
7588 if they are stored for use by variable arguments ...
7590 ??? Unfortunately, it is not enough to simply not the
7591 FRAME_RELATED flags for those SETs, because the first SET
7592 of the PARALLEL is always treated as if it had the flag
7593 set, even if it does not. Therefore we emit a new pattern
7594 without those registers as REG_FRAME_RELATED_EXPR note. */
7596 if (first
>= 6 && !global_not_special_regno_p (first
))
7598 rtx pat
= PATTERN (insn
);
7600 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
7601 if (GET_CODE (XVECEXP (pat
, 0, i
)) == SET
7602 && !global_not_special_regno_p (REGNO (SET_SRC (XVECEXP (pat
,
7604 RTX_FRAME_RELATED_P (XVECEXP (pat
, 0, i
)) = 1;
7606 RTX_FRAME_RELATED_P (insn
) = 1;
7612 for (start
= first
>= 6 ? first
: 6; start
<= last
; start
++)
7613 if (!global_not_special_regno_p (start
))
7619 addr
= plus_constant (base
, offset
+ (start
- first
) * UNITS_PER_LONG
);
7620 note
= gen_store_multiple (gen_rtx_MEM (Pmode
, addr
),
7621 gen_rtx_REG (Pmode
, start
),
7622 GEN_INT (last
- start
+ 1));
7623 note
= PATTERN (note
);
7625 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note
);
7627 for (i
= 0; i
< XVECLEN (note
, 0); i
++)
7628 if (GET_CODE (XVECEXP (note
, 0, i
)) == SET
7629 && !global_not_special_regno_p (REGNO (SET_SRC (XVECEXP (note
,
7631 RTX_FRAME_RELATED_P (XVECEXP (note
, 0, i
)) = 1;
7633 RTX_FRAME_RELATED_P (insn
) = 1;
7639 /* Generate insn to restore registers FIRST to LAST from
7640 the register save area located at offset OFFSET
7641 relative to register BASE. */
7644 restore_gprs (rtx base
, int offset
, int first
, int last
)
7648 addr
= plus_constant (base
, offset
);
7649 addr
= gen_rtx_MEM (Pmode
, addr
);
7650 set_mem_alias_set (addr
, get_frame_alias_set ());
7652 /* Special-case single register. */
7656 insn
= gen_movdi (gen_rtx_REG (Pmode
, first
), addr
);
7658 insn
= gen_movsi (gen_rtx_REG (Pmode
, first
), addr
);
7663 insn
= gen_load_multiple (gen_rtx_REG (Pmode
, first
),
7665 GEN_INT (last
- first
+ 1));
7669 /* Return insn sequence to load the GOT register. */
7671 static GTY(()) rtx got_symbol
;
7673 s390_load_got (void)
7679 got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
7680 SYMBOL_REF_FLAGS (got_symbol
) = SYMBOL_FLAG_LOCAL
;
7685 if (TARGET_CPU_ZARCH
)
7687 emit_move_insn (pic_offset_table_rtx
, got_symbol
);
7693 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, got_symbol
),
7694 UNSPEC_LTREL_OFFSET
);
7695 offset
= gen_rtx_CONST (Pmode
, offset
);
7696 offset
= force_const_mem (Pmode
, offset
);
7698 emit_move_insn (pic_offset_table_rtx
, offset
);
7700 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, XEXP (offset
, 0)),
7702 offset
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, offset
);
7704 emit_move_insn (pic_offset_table_rtx
, offset
);
7707 insns
= get_insns ();
7712 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
7713 and the change to the stack pointer. */
7716 s390_emit_stack_tie (void)
7718 rtx mem
= gen_frame_mem (BLKmode
,
7719 gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
));
7721 emit_insn (gen_stack_tie (mem
));
7724 /* Expand the prologue into a bunch of separate insns. */
7727 s390_emit_prologue (void)
7735 /* Complete frame layout. */
7737 s390_update_frame_layout ();
7739 /* Annotate all constant pool references to let the scheduler know
7740 they implicitly use the base register. */
7742 push_topmost_sequence ();
7744 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7747 annotate_constant_pool_refs (&PATTERN (insn
));
7748 df_insn_rescan (insn
);
7751 pop_topmost_sequence ();
7753 /* Choose best register to use for temp use within prologue.
7754 See below for why TPF must use the register 1. */
7756 if (!has_hard_reg_initial_val (Pmode
, RETURN_REGNUM
)
7757 && !current_function_is_leaf
7758 && !TARGET_TPF_PROFILING
)
7759 temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
7761 temp_reg
= gen_rtx_REG (Pmode
, 1);
7763 /* Save call saved gprs. */
7764 if (cfun_frame_layout
.first_save_gpr
!= -1)
7766 insn
= save_gprs (stack_pointer_rtx
,
7767 cfun_frame_layout
.gprs_offset
+
7768 UNITS_PER_LONG
* (cfun_frame_layout
.first_save_gpr
7769 - cfun_frame_layout
.first_save_gpr_slot
),
7770 cfun_frame_layout
.first_save_gpr
,
7771 cfun_frame_layout
.last_save_gpr
);
7775 /* Dummy insn to mark literal pool slot. */
7777 if (cfun
->machine
->base_reg
)
7778 emit_insn (gen_main_pool (cfun
->machine
->base_reg
));
7780 offset
= cfun_frame_layout
.f0_offset
;
7782 /* Save f0 and f2. */
7783 for (i
= 0; i
< 2; i
++)
7785 if (cfun_fpr_bit_p (i
))
7787 save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
7790 else if (!TARGET_PACKED_STACK
)
7794 /* Save f4 and f6. */
7795 offset
= cfun_frame_layout
.f4_offset
;
7796 for (i
= 2; i
< 4; i
++)
7798 if (cfun_fpr_bit_p (i
))
7800 insn
= save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
7803 /* If f4 and f6 are call clobbered they are saved due to stdargs and
7804 therefore are not frame related. */
7805 if (!call_really_used_regs
[i
+ 16])
7806 RTX_FRAME_RELATED_P (insn
) = 1;
7808 else if (!TARGET_PACKED_STACK
)
7812 if (TARGET_PACKED_STACK
7813 && cfun_save_high_fprs_p
7814 && cfun_frame_layout
.f8_offset
+ cfun_frame_layout
.high_fprs
* 8 > 0)
7816 offset
= (cfun_frame_layout
.f8_offset
7817 + (cfun_frame_layout
.high_fprs
- 1) * 8);
7819 for (i
= 15; i
> 7 && offset
>= 0; i
--)
7820 if (cfun_fpr_bit_p (i
))
7822 insn
= save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
7824 RTX_FRAME_RELATED_P (insn
) = 1;
7827 if (offset
>= cfun_frame_layout
.f8_offset
)
7831 if (!TARGET_PACKED_STACK
)
7832 next_fpr
= cfun_save_high_fprs_p
? 31 : 0;
7834 /* Decrement stack pointer. */
7836 if (cfun_frame_layout
.frame_size
> 0)
7838 rtx frame_off
= GEN_INT (-cfun_frame_layout
.frame_size
);
7841 if (s390_stack_size
)
7843 HOST_WIDE_INT stack_guard
;
7845 if (s390_stack_guard
)
7846 stack_guard
= s390_stack_guard
;
7849 /* If no value for stack guard is provided the smallest power of 2
7850 larger than the current frame size is chosen. */
7852 while (stack_guard
< cfun_frame_layout
.frame_size
)
7856 if (cfun_frame_layout
.frame_size
>= s390_stack_size
)
7858 warning (0, "frame size of function %qs is "
7859 HOST_WIDE_INT_PRINT_DEC
7860 " bytes exceeding user provided stack limit of "
7861 HOST_WIDE_INT_PRINT_DEC
" bytes. "
7862 "An unconditional trap is added.",
7863 current_function_name(), cfun_frame_layout
.frame_size
,
7865 emit_insn (gen_trap ());
7869 /* stack_guard has to be smaller than s390_stack_size.
7870 Otherwise we would emit an AND with zero which would
7871 not match the test under mask pattern. */
7872 if (stack_guard
>= s390_stack_size
)
7874 warning (0, "frame size of function %qs is "
7875 HOST_WIDE_INT_PRINT_DEC
7876 " bytes which is more than half the stack size. "
7877 "The dynamic check would not be reliable. "
7878 "No check emitted for this function.",
7879 current_function_name(),
7880 cfun_frame_layout
.frame_size
);
7884 HOST_WIDE_INT stack_check_mask
= ((s390_stack_size
- 1)
7885 & ~(stack_guard
- 1));
7887 rtx t
= gen_rtx_AND (Pmode
, stack_pointer_rtx
,
7888 GEN_INT (stack_check_mask
));
7890 emit_insn (gen_ctrapdi4 (gen_rtx_EQ (VOIDmode
,
7892 t
, const0_rtx
, const0_rtx
));
7894 emit_insn (gen_ctrapsi4 (gen_rtx_EQ (VOIDmode
,
7896 t
, const0_rtx
, const0_rtx
));
7901 if (s390_warn_framesize
> 0
7902 && cfun_frame_layout
.frame_size
>= s390_warn_framesize
)
7903 warning (0, "frame size of %qs is " HOST_WIDE_INT_PRINT_DEC
" bytes",
7904 current_function_name (), cfun_frame_layout
.frame_size
);
7906 if (s390_warn_dynamicstack_p
&& cfun
->calls_alloca
)
7907 warning (0, "%qs uses dynamic stack allocation", current_function_name ());
7909 /* Save incoming stack pointer into temp reg. */
7910 if (TARGET_BACKCHAIN
|| next_fpr
)
7911 insn
= emit_insn (gen_move_insn (temp_reg
, stack_pointer_rtx
));
7913 /* Subtract frame size from stack pointer. */
7915 if (DISP_IN_RANGE (INTVAL (frame_off
)))
7917 insn
= gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
7918 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
7920 insn
= emit_insn (insn
);
7924 if (!CONST_OK_FOR_K (INTVAL (frame_off
)))
7925 frame_off
= force_const_mem (Pmode
, frame_off
);
7927 insn
= emit_insn (gen_add2_insn (stack_pointer_rtx
, frame_off
));
7928 annotate_constant_pool_refs (&PATTERN (insn
));
7931 RTX_FRAME_RELATED_P (insn
) = 1;
7932 real_frame_off
= GEN_INT (-cfun_frame_layout
.frame_size
);
7933 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
,
7934 gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
7935 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
7938 /* Set backchain. */
7940 if (TARGET_BACKCHAIN
)
7942 if (cfun_frame_layout
.backchain_offset
)
7943 addr
= gen_rtx_MEM (Pmode
,
7944 plus_constant (stack_pointer_rtx
,
7945 cfun_frame_layout
.backchain_offset
));
7947 addr
= gen_rtx_MEM (Pmode
, stack_pointer_rtx
);
7948 set_mem_alias_set (addr
, get_frame_alias_set ());
7949 insn
= emit_insn (gen_move_insn (addr
, temp_reg
));
7952 /* If we support asynchronous exceptions (e.g. for Java),
7953 we need to make sure the backchain pointer is set up
7954 before any possibly trapping memory access. */
7956 if (TARGET_BACKCHAIN
&& flag_non_call_exceptions
)
7958 addr
= gen_rtx_MEM (BLKmode
, gen_rtx_SCRATCH (VOIDmode
));
7959 emit_clobber (addr
);
7963 /* Save fprs 8 - 15 (64 bit ABI). */
7965 if (cfun_save_high_fprs_p
&& next_fpr
)
7967 /* If the stack might be accessed through a different register
7968 we have to make sure that the stack pointer decrement is not
7969 moved below the use of the stack slots. */
7970 s390_emit_stack_tie ();
7972 insn
= emit_insn (gen_add2_insn (temp_reg
,
7973 GEN_INT (cfun_frame_layout
.f8_offset
)));
7977 for (i
= 24; i
<= next_fpr
; i
++)
7978 if (cfun_fpr_bit_p (i
- 16))
7980 rtx addr
= plus_constant (stack_pointer_rtx
,
7981 cfun_frame_layout
.frame_size
7982 + cfun_frame_layout
.f8_offset
7985 insn
= save_fpr (temp_reg
, offset
, i
);
7987 RTX_FRAME_RELATED_P (insn
) = 1;
7988 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
,
7989 gen_rtx_SET (VOIDmode
,
7990 gen_rtx_MEM (DFmode
, addr
),
7991 gen_rtx_REG (DFmode
, i
)));
7995 /* Set frame pointer, if needed. */
7997 if (frame_pointer_needed
)
7999 insn
= emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
);
8000 RTX_FRAME_RELATED_P (insn
) = 1;
8003 /* Set up got pointer, if needed. */
8005 if (flag_pic
&& df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM
))
8007 rtx insns
= s390_load_got ();
8009 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
8010 annotate_constant_pool_refs (&PATTERN (insn
));
8015 if (TARGET_TPF_PROFILING
)
8017 /* Generate a BAS instruction to serve as a function
8018 entry intercept to facilitate the use of tracing
8019 algorithms located at the branch target. */
8020 emit_insn (gen_prologue_tpf ());
8022 /* Emit a blockage here so that all code
8023 lies between the profiling mechanisms. */
8024 emit_insn (gen_blockage ());
8028 /* Expand the epilogue into a bunch of separate insns. */
8031 s390_emit_epilogue (bool sibcall
)
8033 rtx frame_pointer
, return_reg
, cfa_restores
= NULL_RTX
;
8034 int area_bottom
, area_top
, offset
= 0;
8039 if (TARGET_TPF_PROFILING
)
8042 /* Generate a BAS instruction to serve as a function
8043 entry intercept to facilitate the use of tracing
8044 algorithms located at the branch target. */
8046 /* Emit a blockage here so that all code
8047 lies between the profiling mechanisms. */
8048 emit_insn (gen_blockage ());
8050 emit_insn (gen_epilogue_tpf ());
8053 /* Check whether to use frame or stack pointer for restore. */
8055 frame_pointer
= (frame_pointer_needed
8056 ? hard_frame_pointer_rtx
: stack_pointer_rtx
);
8058 s390_frame_area (&area_bottom
, &area_top
);
8060 /* Check whether we can access the register save area.
8061 If not, increment the frame pointer as required. */
8063 if (area_top
<= area_bottom
)
8065 /* Nothing to restore. */
8067 else if (DISP_IN_RANGE (cfun_frame_layout
.frame_size
+ area_bottom
)
8068 && DISP_IN_RANGE (cfun_frame_layout
.frame_size
+ area_top
- 1))
8070 /* Area is in range. */
8071 offset
= cfun_frame_layout
.frame_size
;
8075 rtx insn
, frame_off
, cfa
;
8077 offset
= area_bottom
< 0 ? -area_bottom
: 0;
8078 frame_off
= GEN_INT (cfun_frame_layout
.frame_size
- offset
);
8080 cfa
= gen_rtx_SET (VOIDmode
, frame_pointer
,
8081 gen_rtx_PLUS (Pmode
, frame_pointer
, frame_off
));
8082 if (DISP_IN_RANGE (INTVAL (frame_off
)))
8084 insn
= gen_rtx_SET (VOIDmode
, frame_pointer
,
8085 gen_rtx_PLUS (Pmode
, frame_pointer
, frame_off
));
8086 insn
= emit_insn (insn
);
8090 if (!CONST_OK_FOR_K (INTVAL (frame_off
)))
8091 frame_off
= force_const_mem (Pmode
, frame_off
);
8093 insn
= emit_insn (gen_add2_insn (frame_pointer
, frame_off
));
8094 annotate_constant_pool_refs (&PATTERN (insn
));
8096 add_reg_note (insn
, REG_CFA_ADJUST_CFA
, cfa
);
8097 RTX_FRAME_RELATED_P (insn
) = 1;
8100 /* Restore call saved fprs. */
8104 if (cfun_save_high_fprs_p
)
8106 next_offset
= cfun_frame_layout
.f8_offset
;
8107 for (i
= 24; i
< 32; i
++)
8109 if (cfun_fpr_bit_p (i
- 16))
8111 restore_fpr (frame_pointer
,
8112 offset
+ next_offset
, i
);
8114 = alloc_reg_note (REG_CFA_RESTORE
,
8115 gen_rtx_REG (DFmode
, i
), cfa_restores
);
8124 next_offset
= cfun_frame_layout
.f4_offset
;
8125 for (i
= 18; i
< 20; i
++)
8127 if (cfun_fpr_bit_p (i
- 16))
8129 restore_fpr (frame_pointer
,
8130 offset
+ next_offset
, i
);
8132 = alloc_reg_note (REG_CFA_RESTORE
,
8133 gen_rtx_REG (DFmode
, i
), cfa_restores
);
8136 else if (!TARGET_PACKED_STACK
)
8142 /* Return register. */
8144 return_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
8146 /* Restore call saved gprs. */
8148 if (cfun_frame_layout
.first_restore_gpr
!= -1)
8153 /* Check for global register and save them
8154 to stack location from where they get restored. */
8156 for (i
= cfun_frame_layout
.first_restore_gpr
;
8157 i
<= cfun_frame_layout
.last_restore_gpr
;
8160 if (global_not_special_regno_p (i
))
8162 addr
= plus_constant (frame_pointer
,
8163 offset
+ cfun_frame_layout
.gprs_offset
8164 + (i
- cfun_frame_layout
.first_save_gpr_slot
)
8166 addr
= gen_rtx_MEM (Pmode
, addr
);
8167 set_mem_alias_set (addr
, get_frame_alias_set ());
8168 emit_move_insn (addr
, gen_rtx_REG (Pmode
, i
));
8172 = alloc_reg_note (REG_CFA_RESTORE
,
8173 gen_rtx_REG (Pmode
, i
), cfa_restores
);
8178 /* Fetch return address from stack before load multiple,
8179 this will do good for scheduling. */
8181 if (cfun_frame_layout
.save_return_addr_p
8182 || (cfun_frame_layout
.first_restore_gpr
< BASE_REGNUM
8183 && cfun_frame_layout
.last_restore_gpr
> RETURN_REGNUM
))
8185 int return_regnum
= find_unused_clobbered_reg();
8188 return_reg
= gen_rtx_REG (Pmode
, return_regnum
);
8190 addr
= plus_constant (frame_pointer
,
8191 offset
+ cfun_frame_layout
.gprs_offset
8193 - cfun_frame_layout
.first_save_gpr_slot
)
8195 addr
= gen_rtx_MEM (Pmode
, addr
);
8196 set_mem_alias_set (addr
, get_frame_alias_set ());
8197 emit_move_insn (return_reg
, addr
);
8201 insn
= restore_gprs (frame_pointer
,
8202 offset
+ cfun_frame_layout
.gprs_offset
8203 + (cfun_frame_layout
.first_restore_gpr
8204 - cfun_frame_layout
.first_save_gpr_slot
)
8206 cfun_frame_layout
.first_restore_gpr
,
8207 cfun_frame_layout
.last_restore_gpr
);
8208 insn
= emit_insn (insn
);
8209 REG_NOTES (insn
) = cfa_restores
;
8210 add_reg_note (insn
, REG_CFA_DEF_CFA
,
8211 plus_constant (stack_pointer_rtx
, STACK_POINTER_OFFSET
));
8212 RTX_FRAME_RELATED_P (insn
) = 1;
8218 /* Return to caller. */
8220 p
= rtvec_alloc (2);
8222 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
8223 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
, return_reg
);
8224 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
8229 /* Return the size in bytes of a function argument of
8230 type TYPE and/or mode MODE. At least one of TYPE or
8231 MODE must be specified. */
8234 s390_function_arg_size (enum machine_mode mode
, const_tree type
)
8237 return int_size_in_bytes (type
);
8239 /* No type info available for some library calls ... */
8240 if (mode
!= BLKmode
)
8241 return GET_MODE_SIZE (mode
);
8243 /* If we have neither type nor mode, abort */
8247 /* Return true if a function argument of type TYPE and mode MODE
8248 is to be passed in a floating-point register, if available. */
8251 s390_function_arg_float (enum machine_mode mode
, tree type
)
8253 int size
= s390_function_arg_size (mode
, type
);
8257 /* Soft-float changes the ABI: no floating-point registers are used. */
8258 if (TARGET_SOFT_FLOAT
)
8261 /* No type info available for some library calls ... */
8263 return mode
== SFmode
|| mode
== DFmode
|| mode
== SDmode
|| mode
== DDmode
;
8265 /* The ABI says that record types with a single member are treated
8266 just like that member would be. */
8267 while (TREE_CODE (type
) == RECORD_TYPE
)
8269 tree field
, single
= NULL_TREE
;
8271 for (field
= TYPE_FIELDS (type
); field
; field
= TREE_CHAIN (field
))
8273 if (TREE_CODE (field
) != FIELD_DECL
)
8276 if (single
== NULL_TREE
)
8277 single
= TREE_TYPE (field
);
8282 if (single
== NULL_TREE
)
8288 return TREE_CODE (type
) == REAL_TYPE
;
8291 /* Return true if a function argument of type TYPE and mode MODE
8292 is to be passed in an integer register, or a pair of integer
8293 registers, if available. */
8296 s390_function_arg_integer (enum machine_mode mode
, tree type
)
8298 int size
= s390_function_arg_size (mode
, type
);
8302 /* No type info available for some library calls ... */
8304 return GET_MODE_CLASS (mode
) == MODE_INT
8305 || (TARGET_SOFT_FLOAT
&& SCALAR_FLOAT_MODE_P (mode
));
8307 /* We accept small integral (and similar) types. */
8308 if (INTEGRAL_TYPE_P (type
)
8309 || POINTER_TYPE_P (type
)
8310 || TREE_CODE (type
) == OFFSET_TYPE
8311 || (TARGET_SOFT_FLOAT
&& TREE_CODE (type
) == REAL_TYPE
))
8314 /* We also accept structs of size 1, 2, 4, 8 that are not
8315 passed in floating-point registers. */
8316 if (AGGREGATE_TYPE_P (type
)
8317 && exact_log2 (size
) >= 0
8318 && !s390_function_arg_float (mode
, type
))
8324 /* Return 1 if a function argument of type TYPE and mode MODE
8325 is to be passed by reference. The ABI specifies that only
8326 structures of size 1, 2, 4, or 8 bytes are passed by value,
8327 all other structures (and complex numbers) are passed by
8331 s390_pass_by_reference (CUMULATIVE_ARGS
*ca ATTRIBUTE_UNUSED
,
8332 enum machine_mode mode
, const_tree type
,
8333 bool named ATTRIBUTE_UNUSED
)
8335 int size
= s390_function_arg_size (mode
, type
);
8341 if (AGGREGATE_TYPE_P (type
) && exact_log2 (size
) < 0)
8344 if (TREE_CODE (type
) == COMPLEX_TYPE
8345 || TREE_CODE (type
) == VECTOR_TYPE
)
8352 /* Update the data in CUM to advance over an argument of mode MODE and
8353 data type TYPE. (TYPE is null for libcalls where that information
8354 may not be available.). The boolean NAMED specifies whether the
8355 argument is a named argument (as opposed to an unnamed argument
8356 matching an ellipsis). */
8359 s390_function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
8360 tree type
, int named ATTRIBUTE_UNUSED
)
8362 if (s390_function_arg_float (mode
, type
))
8366 else if (s390_function_arg_integer (mode
, type
))
8368 int size
= s390_function_arg_size (mode
, type
);
8369 cum
->gprs
+= ((size
+ UNITS_PER_LONG
- 1) / UNITS_PER_LONG
);
8375 /* Define where to put the arguments to a function.
8376 Value is zero to push the argument on the stack,
8377 or a hard register in which to store the argument.
8379 MODE is the argument's machine mode.
8380 TYPE is the data type of the argument (as a tree).
8381 This is null for libcalls where that information may
8383 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8384 the preceding args and about the function being called.
8385 NAMED is nonzero if this argument is a named parameter
8386 (otherwise it is an extra parameter matching an ellipsis).
8388 On S/390, we use general purpose registers 2 through 6 to
8389 pass integer, pointer, and certain structure arguments, and
8390 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
8391 to pass floating point arguments. All remaining arguments
8392 are pushed to the stack. */
8395 s390_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
, tree type
,
8396 int named ATTRIBUTE_UNUSED
)
8398 if (s390_function_arg_float (mode
, type
))
8400 if (cum
->fprs
+ 1 > FP_ARG_NUM_REG
)
8403 return gen_rtx_REG (mode
, cum
->fprs
+ 16);
8405 else if (s390_function_arg_integer (mode
, type
))
8407 int size
= s390_function_arg_size (mode
, type
);
8408 int n_gprs
= (size
+ UNITS_PER_LONG
- 1) / UNITS_PER_LONG
;
8410 if (cum
->gprs
+ n_gprs
> GP_ARG_NUM_REG
)
8412 else if (n_gprs
== 1 || UNITS_PER_WORD
== UNITS_PER_LONG
)
8413 return gen_rtx_REG (mode
, cum
->gprs
+ 2);
8414 else if (n_gprs
== 2)
8416 rtvec p
= rtvec_alloc (2);
8419 = gen_rtx_EXPR_LIST (SImode
, gen_rtx_REG (SImode
, cum
->gprs
+ 2),
8422 = gen_rtx_EXPR_LIST (SImode
, gen_rtx_REG (SImode
, cum
->gprs
+ 3),
8425 return gen_rtx_PARALLEL (mode
, p
);
8429 /* After the real arguments, expand_call calls us once again
8430 with a void_type_node type. Whatever we return here is
8431 passed as operand 2 to the call expanders.
8433 We don't need this feature ... */
8434 else if (type
== void_type_node
)
8440 /* Return true if return values of type TYPE should be returned
8441 in a memory buffer whose address is passed by the caller as
8442 hidden first argument. */
8445 s390_return_in_memory (const_tree type
, const_tree fundecl ATTRIBUTE_UNUSED
)
8447 /* We accept small integral (and similar) types. */
8448 if (INTEGRAL_TYPE_P (type
)
8449 || POINTER_TYPE_P (type
)
8450 || TREE_CODE (type
) == OFFSET_TYPE
8451 || TREE_CODE (type
) == REAL_TYPE
)
8452 return int_size_in_bytes (type
) > 8;
8454 /* Aggregates and similar constructs are always returned
8456 if (AGGREGATE_TYPE_P (type
)
8457 || TREE_CODE (type
) == COMPLEX_TYPE
8458 || TREE_CODE (type
) == VECTOR_TYPE
)
8461 /* ??? We get called on all sorts of random stuff from
8462 aggregate_value_p. We can't abort, but it's not clear
8463 what's safe to return. Pretend it's a struct I guess. */
8467 /* Function arguments and return values are promoted to word size. */
8469 static enum machine_mode
8470 s390_promote_function_mode (const_tree type
, enum machine_mode mode
,
8472 const_tree fntype ATTRIBUTE_UNUSED
,
8473 int for_return ATTRIBUTE_UNUSED
)
8475 if (INTEGRAL_MODE_P (mode
)
8476 && GET_MODE_SIZE (mode
) < UNITS_PER_LONG
)
8478 if (POINTER_TYPE_P (type
))
8479 *punsignedp
= POINTERS_EXTEND_UNSIGNED
;
8486 /* Define where to return a (scalar) value of type TYPE.
8487 If TYPE is null, define where to return a (scalar)
8488 value of mode MODE from a libcall. */
8491 s390_function_value (const_tree type
, const_tree fn
, enum machine_mode mode
)
8495 int unsignedp
= TYPE_UNSIGNED (type
);
8496 mode
= promote_function_mode (type
, TYPE_MODE (type
), &unsignedp
, fn
, 1);
8499 gcc_assert (GET_MODE_CLASS (mode
) == MODE_INT
|| SCALAR_FLOAT_MODE_P (mode
));
8500 gcc_assert (GET_MODE_SIZE (mode
) <= 8);
8502 if (TARGET_HARD_FLOAT
&& SCALAR_FLOAT_MODE_P (mode
))
8503 return gen_rtx_REG (mode
, 16);
8504 else if (GET_MODE_SIZE (mode
) <= UNITS_PER_LONG
8505 || UNITS_PER_LONG
== UNITS_PER_WORD
)
8506 return gen_rtx_REG (mode
, 2);
8507 else if (GET_MODE_SIZE (mode
) == 2 * UNITS_PER_LONG
)
8509 rtvec p
= rtvec_alloc (2);
8512 = gen_rtx_EXPR_LIST (SImode
, gen_rtx_REG (SImode
, 2), const0_rtx
);
8514 = gen_rtx_EXPR_LIST (SImode
, gen_rtx_REG (SImode
, 3), GEN_INT (4));
8516 return gen_rtx_PARALLEL (mode
, p
);
8523 /* Create and return the va_list datatype.
8525 On S/390, va_list is an array type equivalent to
8527 typedef struct __va_list_tag
8531 void *__overflow_arg_area;
8532 void *__reg_save_area;
8535 where __gpr and __fpr hold the number of general purpose
8536 or floating point arguments used up to now, respectively,
8537 __overflow_arg_area points to the stack location of the
8538 next argument passed on the stack, and __reg_save_area
8539 always points to the start of the register area in the
8540 call frame of the current function. The function prologue
8541 saves all registers used for argument passing into this
8542 area if the function uses variable arguments. */
8545 s390_build_builtin_va_list (void)
8547 tree f_gpr
, f_fpr
, f_ovf
, f_sav
, record
, type_decl
;
8549 record
= lang_hooks
.types
.make_type (RECORD_TYPE
);
8552 build_decl (BUILTINS_LOCATION
,
8553 TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
8555 f_gpr
= build_decl (BUILTINS_LOCATION
,
8556 FIELD_DECL
, get_identifier ("__gpr"),
8557 long_integer_type_node
);
8558 f_fpr
= build_decl (BUILTINS_LOCATION
,
8559 FIELD_DECL
, get_identifier ("__fpr"),
8560 long_integer_type_node
);
8561 f_ovf
= build_decl (BUILTINS_LOCATION
,
8562 FIELD_DECL
, get_identifier ("__overflow_arg_area"),
8564 f_sav
= build_decl (BUILTINS_LOCATION
,
8565 FIELD_DECL
, get_identifier ("__reg_save_area"),
8568 va_list_gpr_counter_field
= f_gpr
;
8569 va_list_fpr_counter_field
= f_fpr
;
8571 DECL_FIELD_CONTEXT (f_gpr
) = record
;
8572 DECL_FIELD_CONTEXT (f_fpr
) = record
;
8573 DECL_FIELD_CONTEXT (f_ovf
) = record
;
8574 DECL_FIELD_CONTEXT (f_sav
) = record
;
8576 TREE_CHAIN (record
) = type_decl
;
8577 TYPE_NAME (record
) = type_decl
;
8578 TYPE_FIELDS (record
) = f_gpr
;
8579 TREE_CHAIN (f_gpr
) = f_fpr
;
8580 TREE_CHAIN (f_fpr
) = f_ovf
;
8581 TREE_CHAIN (f_ovf
) = f_sav
;
8583 layout_type (record
);
8585 /* The correct type is an array type of one element. */
8586 return build_array_type (record
, build_index_type (size_zero_node
));
8589 /* Implement va_start by filling the va_list structure VALIST.
8590 STDARG_P is always true, and ignored.
8591 NEXTARG points to the first anonymous stack argument.
8593 The following global variables are used to initialize
8594 the va_list structure:
8597 holds number of gprs and fprs used for named arguments.
8598 crtl->args.arg_offset_rtx:
8599 holds the offset of the first anonymous stack argument
8600 (relative to the virtual arg pointer). */
8603 s390_va_start (tree valist
, rtx nextarg ATTRIBUTE_UNUSED
)
8605 HOST_WIDE_INT n_gpr
, n_fpr
;
8607 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
8608 tree gpr
, fpr
, ovf
, sav
, t
;
8610 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
8611 f_fpr
= TREE_CHAIN (f_gpr
);
8612 f_ovf
= TREE_CHAIN (f_fpr
);
8613 f_sav
= TREE_CHAIN (f_ovf
);
8615 valist
= build_va_arg_indirect_ref (valist
);
8616 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
8617 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
8618 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
8619 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
8621 /* Count number of gp and fp argument registers used. */
8623 n_gpr
= crtl
->args
.info
.gprs
;
8624 n_fpr
= crtl
->args
.info
.fprs
;
8626 if (cfun
->va_list_gpr_size
)
8628 t
= build2 (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
,
8629 build_int_cst (NULL_TREE
, n_gpr
));
8630 TREE_SIDE_EFFECTS (t
) = 1;
8631 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
8634 if (cfun
->va_list_fpr_size
)
8636 t
= build2 (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
,
8637 build_int_cst (NULL_TREE
, n_fpr
));
8638 TREE_SIDE_EFFECTS (t
) = 1;
8639 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
8642 /* Find the overflow area. */
8643 if (n_gpr
+ cfun
->va_list_gpr_size
> GP_ARG_NUM_REG
8644 || n_fpr
+ cfun
->va_list_fpr_size
> FP_ARG_NUM_REG
)
8646 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
8648 off
= INTVAL (crtl
->args
.arg_offset_rtx
);
8649 off
= off
< 0 ? 0 : off
;
8650 if (TARGET_DEBUG_ARG
)
8651 fprintf (stderr
, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
8652 (int)n_gpr
, (int)n_fpr
, off
);
8654 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (ovf
), t
, size_int (off
));
8656 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
8657 TREE_SIDE_EFFECTS (t
) = 1;
8658 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
8661 /* Find the register save area. */
8662 if ((cfun
->va_list_gpr_size
&& n_gpr
< GP_ARG_NUM_REG
)
8663 || (cfun
->va_list_fpr_size
&& n_fpr
< FP_ARG_NUM_REG
))
8665 t
= make_tree (TREE_TYPE (sav
), return_address_pointer_rtx
);
8666 t
= build2 (POINTER_PLUS_EXPR
, TREE_TYPE (sav
), t
,
8667 size_int (-RETURN_REGNUM
* UNITS_PER_LONG
));
8669 t
= build2 (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
8670 TREE_SIDE_EFFECTS (t
) = 1;
8671 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
8675 /* Implement va_arg by updating the va_list structure
8676 VALIST as required to retrieve an argument of type
8677 TYPE, and returning that argument.
8679 Generates code equivalent to:
8681 if (integral value) {
8682 if (size <= 4 && args.gpr < 5 ||
8683 size > 4 && args.gpr < 4 )
8684 ret = args.reg_save_area[args.gpr+8]
8686 ret = *args.overflow_arg_area++;
8687 } else if (float value) {
8689 ret = args.reg_save_area[args.fpr+64]
8691 ret = *args.overflow_arg_area++;
8692 } else if (aggregate value) {
8694 ret = *args.reg_save_area[args.gpr]
8696 ret = **args.overflow_arg_area++;
8700 s390_gimplify_va_arg (tree valist
, tree type
, gimple_seq
*pre_p
,
8701 gimple_seq
*post_p ATTRIBUTE_UNUSED
)
8703 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
8704 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
8705 int indirect_p
, size
, n_reg
, sav_ofs
, sav_scale
, max_reg
;
8706 tree lab_false
, lab_over
, addr
;
8708 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
8709 f_fpr
= TREE_CHAIN (f_gpr
);
8710 f_ovf
= TREE_CHAIN (f_fpr
);
8711 f_sav
= TREE_CHAIN (f_ovf
);
8713 valist
= build_va_arg_indirect_ref (valist
);
8714 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
8715 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
8716 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
8718 /* The tree for args* cannot be shared between gpr/fpr and ovf since
8719 both appear on a lhs. */
8720 valist
= unshare_expr (valist
);
8721 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
8723 size
= int_size_in_bytes (type
);
8725 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
8727 if (TARGET_DEBUG_ARG
)
8729 fprintf (stderr
, "va_arg: aggregate type");
8733 /* Aggregates are passed by reference. */
8738 /* kernel stack layout on 31 bit: It is assumed here that no padding
8739 will be added by s390_frame_info because for va_args always an even
8740 number of gprs has to be saved r15-r2 = 14 regs. */
8741 sav_ofs
= 2 * UNITS_PER_LONG
;
8742 sav_scale
= UNITS_PER_LONG
;
8743 size
= UNITS_PER_LONG
;
8744 max_reg
= GP_ARG_NUM_REG
- n_reg
;
8746 else if (s390_function_arg_float (TYPE_MODE (type
), type
))
8748 if (TARGET_DEBUG_ARG
)
8750 fprintf (stderr
, "va_arg: float type");
8754 /* FP args go in FP registers, if present. */
8758 sav_ofs
= 16 * UNITS_PER_LONG
;
8760 max_reg
= FP_ARG_NUM_REG
- n_reg
;
8764 if (TARGET_DEBUG_ARG
)
8766 fprintf (stderr
, "va_arg: other type");
8770 /* Otherwise into GP registers. */
8773 n_reg
= (size
+ UNITS_PER_LONG
- 1) / UNITS_PER_LONG
;
8775 /* kernel stack layout on 31 bit: It is assumed here that no padding
8776 will be added by s390_frame_info because for va_args always an even
8777 number of gprs has to be saved r15-r2 = 14 regs. */
8778 sav_ofs
= 2 * UNITS_PER_LONG
;
8780 if (size
< UNITS_PER_LONG
)
8781 sav_ofs
+= UNITS_PER_LONG
- size
;
8783 sav_scale
= UNITS_PER_LONG
;
8784 max_reg
= GP_ARG_NUM_REG
- n_reg
;
8787 /* Pull the value out of the saved registers ... */
8789 lab_false
= create_artificial_label (UNKNOWN_LOCATION
);
8790 lab_over
= create_artificial_label (UNKNOWN_LOCATION
);
8791 addr
= create_tmp_var (ptr_type_node
, "addr");
8793 t
= fold_convert (TREE_TYPE (reg
), size_int (max_reg
));
8794 t
= build2 (GT_EXPR
, boolean_type_node
, reg
, t
);
8795 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
8796 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
8797 gimplify_and_add (t
, pre_p
);
8799 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, sav
,
8800 size_int (sav_ofs
));
8801 u
= build2 (MULT_EXPR
, TREE_TYPE (reg
), reg
,
8802 fold_convert (TREE_TYPE (reg
), size_int (sav_scale
)));
8803 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, t
, fold_convert (sizetype
, u
));
8805 gimplify_assign (addr
, t
, pre_p
);
8807 gimple_seq_add_stmt (pre_p
, gimple_build_goto (lab_over
));
8809 gimple_seq_add_stmt (pre_p
, gimple_build_label (lab_false
));
8812 /* ... Otherwise out of the overflow area. */
8815 if (size
< UNITS_PER_LONG
)
8816 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, t
,
8817 size_int (UNITS_PER_LONG
- size
));
8819 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
8821 gimplify_assign (addr
, t
, pre_p
);
8823 t
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, t
,
8825 gimplify_assign (ovf
, t
, pre_p
);
8827 gimple_seq_add_stmt (pre_p
, gimple_build_label (lab_over
));
8830 /* Increment register save count. */
8832 u
= build2 (PREINCREMENT_EXPR
, TREE_TYPE (reg
), reg
,
8833 fold_convert (TREE_TYPE (reg
), size_int (n_reg
)));
8834 gimplify_and_add (u
, pre_p
);
8838 t
= build_pointer_type_for_mode (build_pointer_type (type
),
8840 addr
= fold_convert (t
, addr
);
8841 addr
= build_va_arg_indirect_ref (addr
);
8845 t
= build_pointer_type_for_mode (type
, ptr_mode
, true);
8846 addr
= fold_convert (t
, addr
);
8849 return build_va_arg_indirect_ref (addr
);
8857 S390_BUILTIN_THREAD_POINTER
,
8858 S390_BUILTIN_SET_THREAD_POINTER
,
8863 static enum insn_code
const code_for_builtin_64
[S390_BUILTIN_max
] = {
8868 static enum insn_code
const code_for_builtin_31
[S390_BUILTIN_max
] = {
8874 s390_init_builtins (void)
8878 ftype
= build_function_type (ptr_type_node
, void_list_node
);
8879 add_builtin_function ("__builtin_thread_pointer", ftype
,
8880 S390_BUILTIN_THREAD_POINTER
, BUILT_IN_MD
,
8883 ftype
= build_function_type_list (void_type_node
, ptr_type_node
, NULL_TREE
);
8884 add_builtin_function ("__builtin_set_thread_pointer", ftype
,
8885 S390_BUILTIN_SET_THREAD_POINTER
, BUILT_IN_MD
,
8889 /* Expand an expression EXP that calls a built-in function,
8890 with result going to TARGET if that's convenient
8891 (and in mode MODE if that's convenient).
8892 SUBTARGET may be used as the target for computing one of EXP's operands.
8893 IGNORE is nonzero if the value is to be ignored. */
8896 s390_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
8897 enum machine_mode mode ATTRIBUTE_UNUSED
,
8898 int ignore ATTRIBUTE_UNUSED
)
8902 enum insn_code
const *code_for_builtin
=
8903 TARGET_64BIT
? code_for_builtin_64
: code_for_builtin_31
;
8905 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8906 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8907 enum insn_code icode
;
8908 rtx op
[MAX_ARGS
], pat
;
8912 call_expr_arg_iterator iter
;
8914 if (fcode
>= S390_BUILTIN_max
)
8915 internal_error ("bad builtin fcode");
8916 icode
= code_for_builtin
[fcode
];
8918 internal_error ("bad builtin fcode");
8920 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
8923 FOR_EACH_CALL_EXPR_ARG (arg
, iter
, exp
)
8925 const struct insn_operand_data
*insn_op
;
8927 if (arg
== error_mark_node
)
8929 if (arity
> MAX_ARGS
)
8932 insn_op
= &insn_data
[icode
].operand
[arity
+ nonvoid
];
8934 op
[arity
] = expand_expr (arg
, NULL_RTX
, insn_op
->mode
, EXPAND_NORMAL
);
8936 if (!(*insn_op
->predicate
) (op
[arity
], insn_op
->mode
))
8937 op
[arity
] = copy_to_mode_reg (insn_op
->mode
, op
[arity
]);
8943 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8945 || GET_MODE (target
) != tmode
8946 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8947 target
= gen_reg_rtx (tmode
);
8953 pat
= GEN_FCN (icode
) (target
);
8957 pat
= GEN_FCN (icode
) (target
, op
[0]);
8959 pat
= GEN_FCN (icode
) (op
[0]);
8962 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
8978 /* Output assembly code for the trampoline template to
8981 On S/390, we use gpr 1 internally in the trampoline code;
8982 gpr 0 is used to hold the static chain. */
8985 s390_asm_trampoline_template (FILE *file
)
8988 op
[0] = gen_rtx_REG (Pmode
, 0);
8989 op
[1] = gen_rtx_REG (Pmode
, 1);
8993 output_asm_insn ("basr\t%1,0", op
);
8994 output_asm_insn ("lmg\t%0,%1,14(%1)", op
);
8995 output_asm_insn ("br\t%1", op
);
8996 ASM_OUTPUT_SKIP (file
, (HOST_WIDE_INT
)(TRAMPOLINE_SIZE
- 10));
9000 output_asm_insn ("basr\t%1,0", op
);
9001 output_asm_insn ("lm\t%0,%1,6(%1)", op
);
9002 output_asm_insn ("br\t%1", op
);
9003 ASM_OUTPUT_SKIP (file
, (HOST_WIDE_INT
)(TRAMPOLINE_SIZE
- 8));
9007 /* Emit RTL insns to initialize the variable parts of a trampoline.
9008 FNADDR is an RTX for the address of the function's pure code.
9009 CXT is an RTX for the static chain value for the function. */
9012 s390_trampoline_init (rtx m_tramp
, tree fndecl
, rtx cxt
)
9014 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
9017 emit_block_move (m_tramp
, assemble_trampoline_template (),
9018 GEN_INT (2*UNITS_PER_WORD
), BLOCK_OP_NORMAL
);
9020 mem
= adjust_address (m_tramp
, Pmode
, 2*UNITS_PER_WORD
);
9021 emit_move_insn (mem
, cxt
);
9022 mem
= adjust_address (m_tramp
, Pmode
, 3*UNITS_PER_WORD
);
9023 emit_move_insn (mem
, fnaddr
);
9026 /* Output assembler code to FILE to increment profiler label # LABELNO
9027 for profiling a function entry. */
9030 s390_function_profiler (FILE *file
, int labelno
)
9035 ASM_GENERATE_INTERNAL_LABEL (label
, "LP", labelno
);
9037 fprintf (file
, "# function profiler \n");
9039 op
[0] = gen_rtx_REG (Pmode
, RETURN_REGNUM
);
9040 op
[1] = gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
9041 op
[1] = gen_rtx_MEM (Pmode
, plus_constant (op
[1], UNITS_PER_LONG
));
9043 op
[2] = gen_rtx_REG (Pmode
, 1);
9044 op
[3] = gen_rtx_SYMBOL_REF (Pmode
, label
);
9045 SYMBOL_REF_FLAGS (op
[3]) = SYMBOL_FLAG_LOCAL
;
9047 op
[4] = gen_rtx_SYMBOL_REF (Pmode
, "_mcount");
9050 op
[4] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[4]), UNSPEC_PLT
);
9051 op
[4] = gen_rtx_CONST (Pmode
, op
[4]);
9056 output_asm_insn ("stg\t%0,%1", op
);
9057 output_asm_insn ("larl\t%2,%3", op
);
9058 output_asm_insn ("brasl\t%0,%4", op
);
9059 output_asm_insn ("lg\t%0,%1", op
);
9063 op
[6] = gen_label_rtx ();
9065 output_asm_insn ("st\t%0,%1", op
);
9066 output_asm_insn ("bras\t%2,%l6", op
);
9067 output_asm_insn (".long\t%4", op
);
9068 output_asm_insn (".long\t%3", op
);
9069 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
9070 output_asm_insn ("l\t%0,0(%2)", op
);
9071 output_asm_insn ("l\t%2,4(%2)", op
);
9072 output_asm_insn ("basr\t%0,%0", op
);
9073 output_asm_insn ("l\t%0,%1", op
);
9077 op
[5] = gen_label_rtx ();
9078 op
[6] = gen_label_rtx ();
9080 output_asm_insn ("st\t%0,%1", op
);
9081 output_asm_insn ("bras\t%2,%l6", op
);
9082 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[5]));
9083 output_asm_insn (".long\t%4-%l5", op
);
9084 output_asm_insn (".long\t%3-%l5", op
);
9085 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
9086 output_asm_insn ("lr\t%0,%2", op
);
9087 output_asm_insn ("a\t%0,0(%2)", op
);
9088 output_asm_insn ("a\t%2,4(%2)", op
);
9089 output_asm_insn ("basr\t%0,%0", op
);
9090 output_asm_insn ("l\t%0,%1", op
);
9094 /* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
9095 into its SYMBOL_REF_FLAGS. */
9098 s390_encode_section_info (tree decl
, rtx rtl
, int first
)
9100 default_encode_section_info (decl
, rtl
, first
);
9102 if (TREE_CODE (decl
) == VAR_DECL
)
9104 /* If a variable has a forced alignment to < 2 bytes, mark it
9105 with SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL
9107 if (DECL_USER_ALIGN (decl
) && DECL_ALIGN (decl
) < 16)
9108 SYMBOL_REF_FLAGS (XEXP (rtl
, 0)) |= SYMBOL_FLAG_ALIGN1
;
9109 if (!DECL_SIZE (decl
)
9110 || !DECL_ALIGN (decl
)
9111 || !host_integerp (DECL_SIZE (decl
), 0)
9112 || (DECL_ALIGN (decl
) <= 64
9113 && DECL_ALIGN (decl
) != tree_low_cst (DECL_SIZE (decl
), 0)))
9114 SYMBOL_REF_FLAGS (XEXP (rtl
, 0)) |= SYMBOL_FLAG_NOT_NATURALLY_ALIGNED
;
9117 /* Literal pool references don't have a decl so they are handled
9118 differently here. We rely on the information in the MEM_ALIGN
9119 entry to decide upon natural alignment. */
9121 && GET_CODE (XEXP (rtl
, 0)) == SYMBOL_REF
9122 && TREE_CONSTANT_POOL_ADDRESS_P (XEXP (rtl
, 0))
9123 && (MEM_ALIGN (rtl
) == 0
9124 || GET_MODE_BITSIZE (GET_MODE (rtl
)) == 0
9125 || MEM_ALIGN (rtl
) < GET_MODE_BITSIZE (GET_MODE (rtl
))))
9126 SYMBOL_REF_FLAGS (XEXP (rtl
, 0)) |= SYMBOL_FLAG_NOT_NATURALLY_ALIGNED
;
9129 /* Output thunk to FILE that implements a C++ virtual function call (with
9130 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
9131 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
9132 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
9133 relative to the resulting this pointer. */
9136 s390_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
9137 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
9143 /* Make sure unwind info is emitted for the thunk if needed. */
9144 final_start_function (emit_barrier (), file
, 1);
9146 /* Operand 0 is the target function. */
9147 op
[0] = XEXP (DECL_RTL (function
), 0);
9148 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (op
[0]))
9151 op
[0] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[0]),
9152 TARGET_64BIT
? UNSPEC_PLT
: UNSPEC_GOT
);
9153 op
[0] = gen_rtx_CONST (Pmode
, op
[0]);
9156 /* Operand 1 is the 'this' pointer. */
9157 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
9158 op
[1] = gen_rtx_REG (Pmode
, 3);
9160 op
[1] = gen_rtx_REG (Pmode
, 2);
9162 /* Operand 2 is the delta. */
9163 op
[2] = GEN_INT (delta
);
9165 /* Operand 3 is the vcall_offset. */
9166 op
[3] = GEN_INT (vcall_offset
);
9168 /* Operand 4 is the temporary register. */
9169 op
[4] = gen_rtx_REG (Pmode
, 1);
9171 /* Operands 5 to 8 can be used as labels. */
9177 /* Operand 9 can be used for temporary register. */
9180 /* Generate code. */
9183 /* Setup literal pool pointer if required. */
9184 if ((!DISP_IN_RANGE (delta
)
9185 && !CONST_OK_FOR_K (delta
)
9186 && !CONST_OK_FOR_Os (delta
))
9187 || (!DISP_IN_RANGE (vcall_offset
)
9188 && !CONST_OK_FOR_K (vcall_offset
)
9189 && !CONST_OK_FOR_Os (vcall_offset
)))
9191 op
[5] = gen_label_rtx ();
9192 output_asm_insn ("larl\t%4,%5", op
);
9195 /* Add DELTA to this pointer. */
9198 if (CONST_OK_FOR_J (delta
))
9199 output_asm_insn ("la\t%1,%2(%1)", op
);
9200 else if (DISP_IN_RANGE (delta
))
9201 output_asm_insn ("lay\t%1,%2(%1)", op
);
9202 else if (CONST_OK_FOR_K (delta
))
9203 output_asm_insn ("aghi\t%1,%2", op
);
9204 else if (CONST_OK_FOR_Os (delta
))
9205 output_asm_insn ("agfi\t%1,%2", op
);
9208 op
[6] = gen_label_rtx ();
9209 output_asm_insn ("agf\t%1,%6-%5(%4)", op
);
9213 /* Perform vcall adjustment. */
9216 if (DISP_IN_RANGE (vcall_offset
))
9218 output_asm_insn ("lg\t%4,0(%1)", op
);
9219 output_asm_insn ("ag\t%1,%3(%4)", op
);
9221 else if (CONST_OK_FOR_K (vcall_offset
))
9223 output_asm_insn ("lghi\t%4,%3", op
);
9224 output_asm_insn ("ag\t%4,0(%1)", op
);
9225 output_asm_insn ("ag\t%1,0(%4)", op
);
9227 else if (CONST_OK_FOR_Os (vcall_offset
))
9229 output_asm_insn ("lgfi\t%4,%3", op
);
9230 output_asm_insn ("ag\t%4,0(%1)", op
);
9231 output_asm_insn ("ag\t%1,0(%4)", op
);
9235 op
[7] = gen_label_rtx ();
9236 output_asm_insn ("llgf\t%4,%7-%5(%4)", op
);
9237 output_asm_insn ("ag\t%4,0(%1)", op
);
9238 output_asm_insn ("ag\t%1,0(%4)", op
);
9242 /* Jump to target. */
9243 output_asm_insn ("jg\t%0", op
);
9245 /* Output literal pool if required. */
9248 output_asm_insn (".align\t4", op
);
9249 targetm
.asm_out
.internal_label (file
, "L",
9250 CODE_LABEL_NUMBER (op
[5]));
9254 targetm
.asm_out
.internal_label (file
, "L",
9255 CODE_LABEL_NUMBER (op
[6]));
9256 output_asm_insn (".long\t%2", op
);
9260 targetm
.asm_out
.internal_label (file
, "L",
9261 CODE_LABEL_NUMBER (op
[7]));
9262 output_asm_insn (".long\t%3", op
);
9267 /* Setup base pointer if required. */
9269 || (!DISP_IN_RANGE (delta
)
9270 && !CONST_OK_FOR_K (delta
)
9271 && !CONST_OK_FOR_Os (delta
))
9272 || (!DISP_IN_RANGE (delta
)
9273 && !CONST_OK_FOR_K (vcall_offset
)
9274 && !CONST_OK_FOR_Os (vcall_offset
)))
9276 op
[5] = gen_label_rtx ();
9277 output_asm_insn ("basr\t%4,0", op
);
9278 targetm
.asm_out
.internal_label (file
, "L",
9279 CODE_LABEL_NUMBER (op
[5]));
9282 /* Add DELTA to this pointer. */
9285 if (CONST_OK_FOR_J (delta
))
9286 output_asm_insn ("la\t%1,%2(%1)", op
);
9287 else if (DISP_IN_RANGE (delta
))
9288 output_asm_insn ("lay\t%1,%2(%1)", op
);
9289 else if (CONST_OK_FOR_K (delta
))
9290 output_asm_insn ("ahi\t%1,%2", op
);
9291 else if (CONST_OK_FOR_Os (delta
))
9292 output_asm_insn ("afi\t%1,%2", op
);
9295 op
[6] = gen_label_rtx ();
9296 output_asm_insn ("a\t%1,%6-%5(%4)", op
);
9300 /* Perform vcall adjustment. */
9303 if (CONST_OK_FOR_J (vcall_offset
))
9305 output_asm_insn ("l\t%4,0(%1)", op
);
9306 output_asm_insn ("a\t%1,%3(%4)", op
);
9308 else if (DISP_IN_RANGE (vcall_offset
))
9310 output_asm_insn ("l\t%4,0(%1)", op
);
9311 output_asm_insn ("ay\t%1,%3(%4)", op
);
9313 else if (CONST_OK_FOR_K (vcall_offset
))
9315 output_asm_insn ("lhi\t%4,%3", op
);
9316 output_asm_insn ("a\t%4,0(%1)", op
);
9317 output_asm_insn ("a\t%1,0(%4)", op
);
9319 else if (CONST_OK_FOR_Os (vcall_offset
))
9321 output_asm_insn ("iilf\t%4,%3", op
);
9322 output_asm_insn ("a\t%4,0(%1)", op
);
9323 output_asm_insn ("a\t%1,0(%4)", op
);
9327 op
[7] = gen_label_rtx ();
9328 output_asm_insn ("l\t%4,%7-%5(%4)", op
);
9329 output_asm_insn ("a\t%4,0(%1)", op
);
9330 output_asm_insn ("a\t%1,0(%4)", op
);
9333 /* We had to clobber the base pointer register.
9334 Re-setup the base pointer (with a different base). */
9335 op
[5] = gen_label_rtx ();
9336 output_asm_insn ("basr\t%4,0", op
);
9337 targetm
.asm_out
.internal_label (file
, "L",
9338 CODE_LABEL_NUMBER (op
[5]));
9341 /* Jump to target. */
9342 op
[8] = gen_label_rtx ();
9345 output_asm_insn ("l\t%4,%8-%5(%4)", op
);
9347 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
9348 /* We cannot call through .plt, since .plt requires %r12 loaded. */
9349 else if (flag_pic
== 1)
9351 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
9352 output_asm_insn ("l\t%4,%0(%4)", op
);
9354 else if (flag_pic
== 2)
9356 op
[9] = gen_rtx_REG (Pmode
, 0);
9357 output_asm_insn ("l\t%9,%8-4-%5(%4)", op
);
9358 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
9359 output_asm_insn ("ar\t%4,%9", op
);
9360 output_asm_insn ("l\t%4,0(%4)", op
);
9363 output_asm_insn ("br\t%4", op
);
9365 /* Output literal pool. */
9366 output_asm_insn (".align\t4", op
);
9368 if (nonlocal
&& flag_pic
== 2)
9369 output_asm_insn (".long\t%0", op
);
9372 op
[0] = gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
9373 SYMBOL_REF_FLAGS (op
[0]) = SYMBOL_FLAG_LOCAL
;
9376 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[8]));
9378 output_asm_insn (".long\t%0", op
);
9380 output_asm_insn (".long\t%0-%5", op
);
9384 targetm
.asm_out
.internal_label (file
, "L",
9385 CODE_LABEL_NUMBER (op
[6]));
9386 output_asm_insn (".long\t%2", op
);
9390 targetm
.asm_out
.internal_label (file
, "L",
9391 CODE_LABEL_NUMBER (op
[7]));
9392 output_asm_insn (".long\t%3", op
);
9395 final_end_function ();
9399 s390_valid_pointer_mode (enum machine_mode mode
)
9401 return (mode
== SImode
|| (TARGET_64BIT
&& mode
== DImode
));
9404 /* Checks whether the given CALL_EXPR would use a caller
9405 saved register. This is used to decide whether sibling call
9406 optimization could be performed on the respective function
9410 s390_call_saved_register_used (tree call_expr
)
9412 CUMULATIVE_ARGS cum
;
9414 enum machine_mode mode
;
9419 INIT_CUMULATIVE_ARGS (cum
, NULL
, NULL
, 0, 0);
9421 for (i
= 0; i
< call_expr_nargs (call_expr
); i
++)
9423 parameter
= CALL_EXPR_ARG (call_expr
, i
);
9424 gcc_assert (parameter
);
9426 /* For an undeclared variable passed as parameter we will get
9427 an ERROR_MARK node here. */
9428 if (TREE_CODE (parameter
) == ERROR_MARK
)
9431 type
= TREE_TYPE (parameter
);
9434 mode
= TYPE_MODE (type
);
9437 if (pass_by_reference (&cum
, mode
, type
, true))
9440 type
= build_pointer_type (type
);
9443 parm_rtx
= s390_function_arg (&cum
, mode
, type
, 0);
9445 s390_function_arg_advance (&cum
, mode
, type
, 0);
9450 if (REG_P (parm_rtx
))
9453 reg
< HARD_REGNO_NREGS (REGNO (parm_rtx
), GET_MODE (parm_rtx
));
9455 if (!call_used_regs
[reg
+ REGNO (parm_rtx
)])
9459 if (GET_CODE (parm_rtx
) == PARALLEL
)
9463 for (i
= 0; i
< XVECLEN (parm_rtx
, 0); i
++)
9465 rtx r
= XEXP (XVECEXP (parm_rtx
, 0, i
), 0);
9467 gcc_assert (REG_P (r
));
9470 reg
< HARD_REGNO_NREGS (REGNO (r
), GET_MODE (r
));
9472 if (!call_used_regs
[reg
+ REGNO (r
)])
9481 /* Return true if the given call expression can be
9482 turned into a sibling call.
9483 DECL holds the declaration of the function to be called whereas
9484 EXP is the call expression itself. */
9487 s390_function_ok_for_sibcall (tree decl
, tree exp
)
9489 /* The TPF epilogue uses register 1. */
9490 if (TARGET_TPF_PROFILING
)
9493 /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
9494 which would have to be restored before the sibcall. */
9495 if (!TARGET_64BIT
&& flag_pic
&& decl
&& !targetm
.binds_local_p (decl
))
9498 /* Register 6 on s390 is available as an argument register but unfortunately
9499 "caller saved". This makes functions needing this register for arguments
9500 not suitable for sibcalls. */
9501 return !s390_call_saved_register_used (exp
);
9504 /* Return the fixed registers used for condition codes. */
9507 s390_fixed_condition_code_regs (unsigned int *p1
, unsigned int *p2
)
9510 *p2
= INVALID_REGNUM
;
9515 /* This function is used by the call expanders of the machine description.
9516 It emits the call insn itself together with the necessary operations
9517 to adjust the target address and returns the emitted insn.
9518 ADDR_LOCATION is the target address rtx
9519 TLS_CALL the location of the thread-local symbol
9520 RESULT_REG the register where the result of the call should be stored
9521 RETADDR_REG the register where the return address should be stored
9522 If this parameter is NULL_RTX the call is considered
9523 to be a sibling call. */
9526 s390_emit_call (rtx addr_location
, rtx tls_call
, rtx result_reg
,
9529 bool plt_call
= false;
9535 /* Direct function calls need special treatment. */
9536 if (GET_CODE (addr_location
) == SYMBOL_REF
)
9538 /* When calling a global routine in PIC mode, we must
9539 replace the symbol itself with the PLT stub. */
9540 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (addr_location
))
9542 addr_location
= gen_rtx_UNSPEC (Pmode
,
9543 gen_rtvec (1, addr_location
),
9545 addr_location
= gen_rtx_CONST (Pmode
, addr_location
);
9549 /* Unless we can use the bras(l) insn, force the
9550 routine address into a register. */
9551 if (!TARGET_SMALL_EXEC
&& !TARGET_CPU_ZARCH
)
9554 addr_location
= legitimize_pic_address (addr_location
, 0);
9556 addr_location
= force_reg (Pmode
, addr_location
);
9560 /* If it is already an indirect call or the code above moved the
9561 SYMBOL_REF to somewhere else make sure the address can be found in
9563 if (retaddr_reg
== NULL_RTX
9564 && GET_CODE (addr_location
) != SYMBOL_REF
9567 emit_move_insn (gen_rtx_REG (Pmode
, SIBCALL_REGNUM
), addr_location
);
9568 addr_location
= gen_rtx_REG (Pmode
, SIBCALL_REGNUM
);
9571 addr_location
= gen_rtx_MEM (QImode
, addr_location
);
9572 call
= gen_rtx_CALL (VOIDmode
, addr_location
, const0_rtx
);
9574 if (result_reg
!= NULL_RTX
)
9575 call
= gen_rtx_SET (VOIDmode
, result_reg
, call
);
9577 if (retaddr_reg
!= NULL_RTX
)
9579 clobber
= gen_rtx_CLOBBER (VOIDmode
, retaddr_reg
);
9581 if (tls_call
!= NULL_RTX
)
9582 vec
= gen_rtvec (3, call
, clobber
,
9583 gen_rtx_USE (VOIDmode
, tls_call
));
9585 vec
= gen_rtvec (2, call
, clobber
);
9587 call
= gen_rtx_PARALLEL (VOIDmode
, vec
);
9590 insn
= emit_call_insn (call
);
9592 /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
9593 if ((!TARGET_64BIT
&& plt_call
) || tls_call
!= NULL_RTX
)
9595 /* s390_function_ok_for_sibcall should
9596 have denied sibcalls in this case. */
9597 gcc_assert (retaddr_reg
!= NULL_RTX
);
9599 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), pic_offset_table_rtx
);
9604 /* Implement CONDITIONAL_REGISTER_USAGE. */
9607 s390_conditional_register_usage (void)
9613 fixed_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
9614 call_used_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
9616 if (TARGET_CPU_ZARCH
)
9618 fixed_regs
[BASE_REGNUM
] = 0;
9619 call_used_regs
[BASE_REGNUM
] = 0;
9620 fixed_regs
[RETURN_REGNUM
] = 0;
9621 call_used_regs
[RETURN_REGNUM
] = 0;
9625 for (i
= 24; i
< 32; i
++)
9626 call_used_regs
[i
] = call_really_used_regs
[i
] = 0;
9630 for (i
= 18; i
< 20; i
++)
9631 call_used_regs
[i
] = call_really_used_regs
[i
] = 0;
9634 if (TARGET_SOFT_FLOAT
)
9636 for (i
= 16; i
< 32; i
++)
9637 call_used_regs
[i
] = fixed_regs
[i
] = 1;
9641 /* Corresponding function to eh_return expander. */
9643 static GTY(()) rtx s390_tpf_eh_return_symbol
;
9645 s390_emit_tpf_eh_return (rtx target
)
9649 if (!s390_tpf_eh_return_symbol
)
9650 s390_tpf_eh_return_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "__tpf_eh_return");
9652 reg
= gen_rtx_REG (Pmode
, 2);
9654 emit_move_insn (reg
, target
);
9655 insn
= s390_emit_call (s390_tpf_eh_return_symbol
, NULL_RTX
, reg
,
9656 gen_rtx_REG (Pmode
, RETURN_REGNUM
));
9657 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), reg
);
9659 emit_move_insn (EH_RETURN_HANDLER_RTX
, reg
);
9662 /* Rework the prologue/epilogue to avoid saving/restoring
9663 registers unnecessarily. */
9666 s390_optimize_prologue (void)
9668 rtx insn
, new_insn
, next_insn
;
9670 /* Do a final recompute of the frame-related data. */
9672 s390_update_frame_layout ();
9674 /* If all special registers are in fact used, there's nothing we
9675 can do, so no point in walking the insn list. */
9677 if (cfun_frame_layout
.first_save_gpr
<= BASE_REGNUM
9678 && cfun_frame_layout
.last_save_gpr
>= BASE_REGNUM
9679 && (TARGET_CPU_ZARCH
9680 || (cfun_frame_layout
.first_save_gpr
<= RETURN_REGNUM
9681 && cfun_frame_layout
.last_save_gpr
>= RETURN_REGNUM
)))
9684 /* Search for prologue/epilogue insns and replace them. */
9686 for (insn
= get_insns (); insn
; insn
= next_insn
)
9688 int first
, last
, off
;
9689 rtx set
, base
, offset
;
9691 next_insn
= NEXT_INSN (insn
);
9693 if (GET_CODE (insn
) != INSN
)
9696 if (GET_CODE (PATTERN (insn
)) == PARALLEL
9697 && store_multiple_operation (PATTERN (insn
), VOIDmode
))
9699 set
= XVECEXP (PATTERN (insn
), 0, 0);
9700 first
= REGNO (SET_SRC (set
));
9701 last
= first
+ XVECLEN (PATTERN (insn
), 0) - 1;
9702 offset
= const0_rtx
;
9703 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
9704 off
= INTVAL (offset
);
9706 if (GET_CODE (base
) != REG
|| off
< 0)
9708 if (cfun_frame_layout
.first_save_gpr
!= -1
9709 && (cfun_frame_layout
.first_save_gpr
< first
9710 || cfun_frame_layout
.last_save_gpr
> last
))
9712 if (REGNO (base
) != STACK_POINTER_REGNUM
9713 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
9715 if (first
> BASE_REGNUM
|| last
< BASE_REGNUM
)
9718 if (cfun_frame_layout
.first_save_gpr
!= -1)
9720 new_insn
= save_gprs (base
,
9721 off
+ (cfun_frame_layout
.first_save_gpr
9722 - first
) * UNITS_PER_LONG
,
9723 cfun_frame_layout
.first_save_gpr
,
9724 cfun_frame_layout
.last_save_gpr
);
9725 new_insn
= emit_insn_before (new_insn
, insn
);
9726 INSN_ADDRESSES_NEW (new_insn
, -1);
9733 if (cfun_frame_layout
.first_save_gpr
== -1
9734 && GET_CODE (PATTERN (insn
)) == SET
9735 && GET_CODE (SET_SRC (PATTERN (insn
))) == REG
9736 && (REGNO (SET_SRC (PATTERN (insn
))) == BASE_REGNUM
9737 || (!TARGET_CPU_ZARCH
9738 && REGNO (SET_SRC (PATTERN (insn
))) == RETURN_REGNUM
))
9739 && GET_CODE (SET_DEST (PATTERN (insn
))) == MEM
)
9741 set
= PATTERN (insn
);
9742 first
= REGNO (SET_SRC (set
));
9743 offset
= const0_rtx
;
9744 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
9745 off
= INTVAL (offset
);
9747 if (GET_CODE (base
) != REG
|| off
< 0)
9749 if (REGNO (base
) != STACK_POINTER_REGNUM
9750 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
9757 if (GET_CODE (PATTERN (insn
)) == PARALLEL
9758 && load_multiple_operation (PATTERN (insn
), VOIDmode
))
9760 set
= XVECEXP (PATTERN (insn
), 0, 0);
9761 first
= REGNO (SET_DEST (set
));
9762 last
= first
+ XVECLEN (PATTERN (insn
), 0) - 1;
9763 offset
= const0_rtx
;
9764 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
9765 off
= INTVAL (offset
);
9767 if (GET_CODE (base
) != REG
|| off
< 0)
9769 if (cfun_frame_layout
.first_restore_gpr
!= -1
9770 && (cfun_frame_layout
.first_restore_gpr
< first
9771 || cfun_frame_layout
.last_restore_gpr
> last
))
9773 if (REGNO (base
) != STACK_POINTER_REGNUM
9774 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
9776 if (first
> BASE_REGNUM
|| last
< BASE_REGNUM
)
9779 if (cfun_frame_layout
.first_restore_gpr
!= -1)
9781 new_insn
= restore_gprs (base
,
9782 off
+ (cfun_frame_layout
.first_restore_gpr
9783 - first
) * UNITS_PER_LONG
,
9784 cfun_frame_layout
.first_restore_gpr
,
9785 cfun_frame_layout
.last_restore_gpr
);
9786 new_insn
= emit_insn_before (new_insn
, insn
);
9787 INSN_ADDRESSES_NEW (new_insn
, -1);
9794 if (cfun_frame_layout
.first_restore_gpr
== -1
9795 && GET_CODE (PATTERN (insn
)) == SET
9796 && GET_CODE (SET_DEST (PATTERN (insn
))) == REG
9797 && (REGNO (SET_DEST (PATTERN (insn
))) == BASE_REGNUM
9798 || (!TARGET_CPU_ZARCH
9799 && REGNO (SET_DEST (PATTERN (insn
))) == RETURN_REGNUM
))
9800 && GET_CODE (SET_SRC (PATTERN (insn
))) == MEM
)
9802 set
= PATTERN (insn
);
9803 first
= REGNO (SET_DEST (set
));
9804 offset
= const0_rtx
;
9805 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
9806 off
= INTVAL (offset
);
9808 if (GET_CODE (base
) != REG
|| off
< 0)
9810 if (REGNO (base
) != STACK_POINTER_REGNUM
9811 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
9820 /* On z10 the dynamic branch prediction must see the backward jump in
9821 a window of 384 bytes. If not it falls back to the static
9822 prediction. This function rearranges the loop backward branch in a
9823 way which makes the static prediction always correct. The function
9824 returns true if it added an instruction. */
9826 s390_z10_fix_long_loop_prediction (rtx insn
)
9828 rtx set
= single_set (insn
);
9829 rtx code_label
, label_ref
, new_label
;
9835 /* This will exclude branch on count and branch on index patterns
9836 since these are correctly statically predicted. */
9838 || SET_DEST (set
) != pc_rtx
9839 || GET_CODE (SET_SRC(set
)) != IF_THEN_ELSE
)
9842 label_ref
= (GET_CODE (XEXP (SET_SRC (set
), 1)) == LABEL_REF
?
9843 XEXP (SET_SRC (set
), 1) : XEXP (SET_SRC (set
), 2));
9845 gcc_assert (GET_CODE (label_ref
) == LABEL_REF
);
9847 code_label
= XEXP (label_ref
, 0);
9849 if (INSN_ADDRESSES (INSN_UID (code_label
)) == -1
9850 || INSN_ADDRESSES (INSN_UID (insn
)) == -1
9851 || (INSN_ADDRESSES (INSN_UID (insn
))
9852 - INSN_ADDRESSES (INSN_UID (code_label
)) < Z10_PREDICT_DISTANCE
))
9855 for (distance
= 0, cur_insn
= PREV_INSN (insn
);
9856 distance
< Z10_PREDICT_DISTANCE
- 6;
9857 distance
+= get_attr_length (cur_insn
), cur_insn
= PREV_INSN (cur_insn
))
9858 if (!cur_insn
|| JUMP_P (cur_insn
) || LABEL_P (cur_insn
))
9861 new_label
= gen_label_rtx ();
9862 uncond_jump
= emit_jump_insn_after (
9863 gen_rtx_SET (VOIDmode
, pc_rtx
,
9864 gen_rtx_LABEL_REF (VOIDmode
, code_label
)),
9866 emit_label_after (new_label
, uncond_jump
);
9868 tmp
= XEXP (SET_SRC (set
), 1);
9869 XEXP (SET_SRC (set
), 1) = XEXP (SET_SRC (set
), 2);
9870 XEXP (SET_SRC (set
), 2) = tmp
;
9871 INSN_CODE (insn
) = -1;
9873 XEXP (label_ref
, 0) = new_label
;
9874 JUMP_LABEL (insn
) = new_label
;
9875 JUMP_LABEL (uncond_jump
) = code_label
;
9880 /* Returns 1 if INSN reads the value of REG for purposes not related
9881 to addressing of memory, and 0 otherwise. */
9883 s390_non_addr_reg_read_p (rtx reg
, rtx insn
)
9885 return reg_referenced_p (reg
, PATTERN (insn
))
9886 && !reg_used_in_mem_p (REGNO (reg
), PATTERN (insn
));
9889 /* Starting from INSN find_cond_jump looks downwards in the insn
9890 stream for a single jump insn which is the last user of the
9891 condition code set in INSN. */
9893 find_cond_jump (rtx insn
)
9895 for (; insn
; insn
= NEXT_INSN (insn
))
9904 if (reg_mentioned_p (gen_rtx_REG (CCmode
, CC_REGNUM
), insn
))
9909 /* This will be triggered by a return. */
9910 if (GET_CODE (PATTERN (insn
)) != SET
)
9913 gcc_assert (SET_DEST (PATTERN (insn
)) == pc_rtx
);
9914 ite
= SET_SRC (PATTERN (insn
));
9916 if (GET_CODE (ite
) != IF_THEN_ELSE
)
9919 cc
= XEXP (XEXP (ite
, 0), 0);
9920 if (!REG_P (cc
) || !CC_REGNO_P (REGNO (cc
)))
9923 if (find_reg_note (insn
, REG_DEAD
, cc
))
9931 /* Swap the condition in COND and the operands in OP0 and OP1 so that
9932 the semantics does not change. If NULL_RTX is passed as COND the
9933 function tries to find the conditional jump starting with INSN. */
9935 s390_swap_cmp (rtx cond
, rtx
*op0
, rtx
*op1
, rtx insn
)
9939 if (cond
== NULL_RTX
)
9941 rtx jump
= find_cond_jump (NEXT_INSN (insn
));
9942 jump
= jump
? single_set (jump
) : NULL_RTX
;
9944 if (jump
== NULL_RTX
)
9947 cond
= XEXP (XEXP (jump
, 1), 0);
9952 PUT_CODE (cond
, swap_condition (GET_CODE (cond
)));
9955 /* On z10, instructions of the compare-and-branch family have the
9956 property to access the register occurring as second operand with
9957 its bits complemented. If such a compare is grouped with a second
9958 instruction that accesses the same register non-complemented, and
9959 if that register's value is delivered via a bypass, then the
9960 pipeline recycles, thereby causing significant performance decline.
9961 This function locates such situations and exchanges the two
9962 operands of the compare. The function return true whenever it
9965 s390_z10_optimize_cmp (rtx insn
)
9967 rtx prev_insn
, next_insn
;
9968 bool insn_added_p
= false;
9969 rtx cond
, *op0
, *op1
;
9971 if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
9973 /* Handle compare and branch and branch on count
9975 rtx pattern
= single_set (insn
);
9978 || SET_DEST (pattern
) != pc_rtx
9979 || GET_CODE (SET_SRC (pattern
)) != IF_THEN_ELSE
)
9982 cond
= XEXP (SET_SRC (pattern
), 0);
9983 op0
= &XEXP (cond
, 0);
9984 op1
= &XEXP (cond
, 1);
9986 else if (GET_CODE (PATTERN (insn
)) == SET
)
9990 /* Handle normal compare instructions. */
9991 src
= SET_SRC (PATTERN (insn
));
9992 dest
= SET_DEST (PATTERN (insn
));
9995 || !CC_REGNO_P (REGNO (dest
))
9996 || GET_CODE (src
) != COMPARE
)
9999 /* s390_swap_cmp will try to find the conditional
10000 jump when passing NULL_RTX as condition. */
10002 op0
= &XEXP (src
, 0);
10003 op1
= &XEXP (src
, 1);
10008 if (!REG_P (*op0
) || !REG_P (*op1
))
10011 if (GET_MODE_CLASS (GET_MODE (*op0
)) != MODE_INT
)
10014 /* Swap the COMPARE arguments and its mask if there is a
10015 conflicting access in the previous insn. */
10016 prev_insn
= prev_active_insn (insn
);
10017 if (prev_insn
!= NULL_RTX
&& INSN_P (prev_insn
)
10018 && reg_referenced_p (*op1
, PATTERN (prev_insn
)))
10019 s390_swap_cmp (cond
, op0
, op1
, insn
);
10021 /* Check if there is a conflict with the next insn. If there
10022 was no conflict with the previous insn, then swap the
10023 COMPARE arguments and its mask. If we already swapped
10024 the operands, or if swapping them would cause a conflict
10025 with the previous insn, issue a NOP after the COMPARE in
10026 order to separate the two instuctions. */
10027 next_insn
= next_active_insn (insn
);
10028 if (next_insn
!= NULL_RTX
&& INSN_P (next_insn
)
10029 && s390_non_addr_reg_read_p (*op1
, next_insn
))
10031 if (prev_insn
!= NULL_RTX
&& INSN_P (prev_insn
)
10032 && s390_non_addr_reg_read_p (*op0
, prev_insn
))
10034 if (REGNO (*op1
) == 0)
10035 emit_insn_after (gen_nop1 (), insn
);
10037 emit_insn_after (gen_nop (), insn
);
10038 insn_added_p
= true;
10041 s390_swap_cmp (cond
, op0
, op1
, insn
);
10043 return insn_added_p
;
10046 /* Perform machine-dependent processing. */
10051 bool pool_overflow
= false;
10053 /* Make sure all splits have been performed; splits after
10054 machine_dependent_reorg might confuse insn length counts. */
10055 split_all_insns_noflow ();
10057 /* Install the main literal pool and the associated base
10058 register load insns.
10060 In addition, there are two problematic situations we need
10063 - the literal pool might be > 4096 bytes in size, so that
10064 some of its elements cannot be directly accessed
10066 - a branch target might be > 64K away from the branch, so that
10067 it is not possible to use a PC-relative instruction.
10069 To fix those, we split the single literal pool into multiple
10070 pool chunks, reloading the pool base register at various
10071 points throughout the function to ensure it always points to
10072 the pool chunk the following code expects, and / or replace
10073 PC-relative branches by absolute branches.
10075 However, the two problems are interdependent: splitting the
10076 literal pool can move a branch further away from its target,
10077 causing the 64K limit to overflow, and on the other hand,
10078 replacing a PC-relative branch by an absolute branch means
10079 we need to put the branch target address into the literal
10080 pool, possibly causing it to overflow.
10082 So, we loop trying to fix up both problems until we manage
10083 to satisfy both conditions at the same time. Note that the
10084 loop is guaranteed to terminate as every pass of the loop
10085 strictly decreases the total number of PC-relative branches
10086 in the function. (This is not completely true as there
10087 might be branch-over-pool insns introduced by chunkify_start.
10088 Those never need to be split however.) */
10092 struct constant_pool
*pool
= NULL
;
10094 /* Collect the literal pool. */
10095 if (!pool_overflow
)
10097 pool
= s390_mainpool_start ();
10099 pool_overflow
= true;
10102 /* If literal pool overflowed, start to chunkify it. */
10104 pool
= s390_chunkify_start ();
10106 /* Split out-of-range branches. If this has created new
10107 literal pool entries, cancel current chunk list and
10108 recompute it. zSeries machines have large branch
10109 instructions, so we never need to split a branch. */
10110 if (!TARGET_CPU_ZARCH
&& s390_split_branches ())
10113 s390_chunkify_cancel (pool
);
10115 s390_mainpool_cancel (pool
);
10120 /* If we made it up to here, both conditions are satisfied.
10121 Finish up literal pool related changes. */
10123 s390_chunkify_finish (pool
);
10125 s390_mainpool_finish (pool
);
10127 /* We're done splitting branches. */
10128 cfun
->machine
->split_branches_pending_p
= false;
10132 /* Generate out-of-pool execute target insns. */
10133 if (TARGET_CPU_ZARCH
)
10135 rtx insn
, label
, target
;
10137 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
10139 label
= s390_execute_label (insn
);
10143 gcc_assert (label
!= const0_rtx
);
10145 target
= emit_label (XEXP (label
, 0));
10146 INSN_ADDRESSES_NEW (target
, -1);
10148 target
= emit_insn (s390_execute_target (insn
));
10149 INSN_ADDRESSES_NEW (target
, -1);
10153 /* Try to optimize prologue and epilogue further. */
10154 s390_optimize_prologue ();
10156 /* Walk over the insns and do some z10 specific changes. */
10157 if (s390_tune
== PROCESSOR_2097_Z10
)
10160 bool insn_added_p
= false;
10162 /* The insn lengths and addresses have to be up to date for the
10163 following manipulations. */
10164 shorten_branches (get_insns ());
10166 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
10168 if (!INSN_P (insn
) || INSN_CODE (insn
) <= 0)
10172 insn_added_p
|= s390_z10_fix_long_loop_prediction (insn
);
10174 if (GET_CODE (PATTERN (insn
)) == PARALLEL
10175 || GET_CODE (PATTERN (insn
)) == SET
)
10176 insn_added_p
|= s390_z10_optimize_cmp (insn
);
10179 /* Adjust branches if we added new instructions. */
10181 shorten_branches (get_insns ());
10185 /* Return true if INSN is a fp load insn writing register REGNO. */
10187 s390_fpload_toreg (rtx insn
, unsigned int regno
)
10190 enum attr_type flag
= s390_safe_attr_type (insn
);
10192 if (flag
!= TYPE_FLOADSF
&& flag
!= TYPE_FLOADDF
)
10195 set
= single_set (insn
);
10197 if (set
== NULL_RTX
)
10200 if (!REG_P (SET_DEST (set
)) || !MEM_P (SET_SRC (set
)))
10203 if (REGNO (SET_DEST (set
)) != regno
)
10209 /* This value describes the distance to be avoided between an
10210 aritmetic fp instruction and an fp load writing the same register.
10211 Z10_EARLYLOAD_DISTANCE - 1 as well as Z10_EARLYLOAD_DISTANCE + 1 is
10212 fine but the exact value has to be avoided. Otherwise the FP
10213 pipeline will throw an exception causing a major penalty. */
10214 #define Z10_EARLYLOAD_DISTANCE 7
10216 /* Rearrange the ready list in order to avoid the situation described
10217 for Z10_EARLYLOAD_DISTANCE. A problematic load instruction is
10218 moved to the very end of the ready list. */
10220 s390_z10_prevent_earlyload_conflicts (rtx
*ready
, int *nready_p
)
10222 unsigned int regno
;
10223 int nready
= *nready_p
;
10228 enum attr_type flag
;
10231 /* Skip DISTANCE - 1 active insns. */
10232 for (insn
= last_scheduled_insn
, distance
= Z10_EARLYLOAD_DISTANCE
- 1;
10233 distance
> 0 && insn
!= NULL_RTX
;
10234 distance
--, insn
= prev_active_insn (insn
))
10235 if (CALL_P (insn
) || JUMP_P (insn
))
10238 if (insn
== NULL_RTX
)
10241 set
= single_set (insn
);
10243 if (set
== NULL_RTX
|| !REG_P (SET_DEST (set
))
10244 || GET_MODE_CLASS (GET_MODE (SET_DEST (set
))) != MODE_FLOAT
)
10247 flag
= s390_safe_attr_type (insn
);
10249 if (flag
== TYPE_FLOADSF
|| flag
== TYPE_FLOADDF
)
10252 regno
= REGNO (SET_DEST (set
));
10255 while (!s390_fpload_toreg (ready
[i
], regno
) && i
> 0)
10262 memmove (&ready
[1], &ready
[0], sizeof (rtx
) * i
);
10266 /* This function is called via hook TARGET_SCHED_REORDER before
10267 issueing one insn from list READY which contains *NREADYP entries.
10268 For target z10 it reorders load instructions to avoid early load
10269 conflicts in the floating point pipeline */
10271 s390_sched_reorder (FILE *file ATTRIBUTE_UNUSED
, int verbose ATTRIBUTE_UNUSED
,
10272 rtx
*ready
, int *nreadyp
, int clock ATTRIBUTE_UNUSED
)
10274 if (s390_tune
== PROCESSOR_2097_Z10
)
10275 if (reload_completed
&& *nreadyp
> 1)
10276 s390_z10_prevent_earlyload_conflicts (ready
, nreadyp
);
10278 return s390_issue_rate ();
10281 /* This function is called via hook TARGET_SCHED_VARIABLE_ISSUE after
10282 the scheduler has issued INSN. It stores the last issued insn into
10283 last_scheduled_insn in order to make it available for
10284 s390_sched_reorder. */
10286 s390_sched_variable_issue (FILE *file ATTRIBUTE_UNUSED
,
10287 int verbose ATTRIBUTE_UNUSED
,
10288 rtx insn
, int more
)
10290 last_scheduled_insn
= insn
;
10292 if (GET_CODE (PATTERN (insn
)) != USE
10293 && GET_CODE (PATTERN (insn
)) != CLOBBER
)
10300 s390_sched_init (FILE *file ATTRIBUTE_UNUSED
,
10301 int verbose ATTRIBUTE_UNUSED
,
10302 int max_ready ATTRIBUTE_UNUSED
)
10304 last_scheduled_insn
= NULL_RTX
;
10307 /* This function checks the whole of insn X for memory references. The
10308 function always returns zero because the framework it is called
10309 from would stop recursively analyzing the insn upon a return value
10310 other than zero. The real result of this function is updating
10311 counter variable MEM_COUNT. */
10313 check_dpu (rtx
*x
, unsigned *mem_count
)
10315 if (*x
!= NULL_RTX
&& MEM_P (*x
))
10320 /* This target hook implementation for TARGET_LOOP_UNROLL_ADJUST calculates
10321 a new number struct loop *loop should be unrolled if tuned for the z10
10322 cpu. The loop is analyzed for memory accesses by calling check_dpu for
10323 each rtx of the loop. Depending on the loop_depth and the amount of
10324 memory accesses a new number <=nunroll is returned to improve the
10325 behaviour of the hardware prefetch unit. */
10327 s390_loop_unroll_adjust (unsigned nunroll
, struct loop
*loop
)
10332 unsigned mem_count
= 0;
10334 /* Only z10 needs special handling. */
10335 if (s390_tune
!= PROCESSOR_2097_Z10
)
10338 /* Count the number of memory references within the loop body. */
10339 bbs
= get_loop_body (loop
);
10340 for (i
= 0; i
< loop
->num_nodes
; i
++)
10342 for (insn
= BB_HEAD (bbs
[i
]); insn
!= BB_END (bbs
[i
]); insn
= NEXT_INSN (insn
))
10343 if (INSN_P (insn
) && INSN_CODE (insn
) != -1)
10344 for_each_rtx (&insn
, (rtx_function
) check_dpu
, &mem_count
);
10348 /* Prevent division by zero, and we do not need to adjust nunroll in this case. */
10349 if (mem_count
== 0)
10352 switch (loop_depth(loop
))
10355 return MIN (nunroll
, 28 / mem_count
);
10357 return MIN (nunroll
, 22 / mem_count
);
10359 return MIN (nunroll
, 16 / mem_count
);
10363 /* Initialize GCC target structure. */
10365 #undef TARGET_ASM_ALIGNED_HI_OP
10366 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
10367 #undef TARGET_ASM_ALIGNED_DI_OP
10368 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
10369 #undef TARGET_ASM_INTEGER
10370 #define TARGET_ASM_INTEGER s390_assemble_integer
10372 #undef TARGET_ASM_OPEN_PAREN
10373 #define TARGET_ASM_OPEN_PAREN ""
10375 #undef TARGET_ASM_CLOSE_PAREN
10376 #define TARGET_ASM_CLOSE_PAREN ""
10378 #undef TARGET_DEFAULT_TARGET_FLAGS
10379 #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD)
10381 #undef TARGET_HANDLE_OPTION
10382 #define TARGET_HANDLE_OPTION s390_handle_option
10384 #undef TARGET_ENCODE_SECTION_INFO
10385 #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
10387 #undef TARGET_SCALAR_MODE_SUPPORTED_P
10388 #define TARGET_SCALAR_MODE_SUPPORTED_P s390_scalar_mode_supported_p
10391 #undef TARGET_HAVE_TLS
10392 #define TARGET_HAVE_TLS true
10394 #undef TARGET_CANNOT_FORCE_CONST_MEM
10395 #define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
10397 #undef TARGET_DELEGITIMIZE_ADDRESS
10398 #define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
10400 #undef TARGET_LEGITIMIZE_ADDRESS
10401 #define TARGET_LEGITIMIZE_ADDRESS s390_legitimize_address
10403 #undef TARGET_RETURN_IN_MEMORY
10404 #define TARGET_RETURN_IN_MEMORY s390_return_in_memory
10406 #undef TARGET_INIT_BUILTINS
10407 #define TARGET_INIT_BUILTINS s390_init_builtins
10408 #undef TARGET_EXPAND_BUILTIN
10409 #define TARGET_EXPAND_BUILTIN s390_expand_builtin
10411 #undef TARGET_ASM_OUTPUT_MI_THUNK
10412 #define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
10413 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
10414 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
10416 #undef TARGET_SCHED_ADJUST_PRIORITY
10417 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
10418 #undef TARGET_SCHED_ISSUE_RATE
10419 #define TARGET_SCHED_ISSUE_RATE s390_issue_rate
10420 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
10421 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
10423 #undef TARGET_SCHED_VARIABLE_ISSUE
10424 #define TARGET_SCHED_VARIABLE_ISSUE s390_sched_variable_issue
10425 #undef TARGET_SCHED_REORDER
10426 #define TARGET_SCHED_REORDER s390_sched_reorder
10427 #undef TARGET_SCHED_INIT
10428 #define TARGET_SCHED_INIT s390_sched_init
10430 #undef TARGET_CANNOT_COPY_INSN_P
10431 #define TARGET_CANNOT_COPY_INSN_P s390_cannot_copy_insn_p
10432 #undef TARGET_RTX_COSTS
10433 #define TARGET_RTX_COSTS s390_rtx_costs
10434 #undef TARGET_ADDRESS_COST
10435 #define TARGET_ADDRESS_COST s390_address_cost
10437 #undef TARGET_MACHINE_DEPENDENT_REORG
10438 #define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
10440 #undef TARGET_VALID_POINTER_MODE
10441 #define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
10443 #undef TARGET_BUILD_BUILTIN_VA_LIST
10444 #define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
10445 #undef TARGET_EXPAND_BUILTIN_VA_START
10446 #define TARGET_EXPAND_BUILTIN_VA_START s390_va_start
10447 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
10448 #define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg
10450 #undef TARGET_PROMOTE_FUNCTION_MODE
10451 #define TARGET_PROMOTE_FUNCTION_MODE s390_promote_function_mode
10452 #undef TARGET_PASS_BY_REFERENCE
10453 #define TARGET_PASS_BY_REFERENCE s390_pass_by_reference
10455 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
10456 #define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
10458 #undef TARGET_FIXED_CONDITION_CODE_REGS
10459 #define TARGET_FIXED_CONDITION_CODE_REGS s390_fixed_condition_code_regs
10461 #undef TARGET_CC_MODES_COMPATIBLE
10462 #define TARGET_CC_MODES_COMPATIBLE s390_cc_modes_compatible
10464 #undef TARGET_INVALID_WITHIN_DOLOOP
10465 #define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_const_rtx_null
10468 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
10469 #define TARGET_ASM_OUTPUT_DWARF_DTPREL s390_output_dwarf_dtprel
10472 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
10473 #undef TARGET_MANGLE_TYPE
10474 #define TARGET_MANGLE_TYPE s390_mangle_type
10477 #undef TARGET_SCALAR_MODE_SUPPORTED_P
10478 #define TARGET_SCALAR_MODE_SUPPORTED_P s390_scalar_mode_supported_p
10480 #undef TARGET_SECONDARY_RELOAD
10481 #define TARGET_SECONDARY_RELOAD s390_secondary_reload
10483 #undef TARGET_LIBGCC_CMP_RETURN_MODE
10484 #define TARGET_LIBGCC_CMP_RETURN_MODE s390_libgcc_cmp_return_mode
10486 #undef TARGET_LIBGCC_SHIFT_COUNT_MODE
10487 #define TARGET_LIBGCC_SHIFT_COUNT_MODE s390_libgcc_shift_count_mode
10489 #undef TARGET_LEGITIMATE_ADDRESS_P
10490 #define TARGET_LEGITIMATE_ADDRESS_P s390_legitimate_address_p
10492 #undef TARGET_CAN_ELIMINATE
10493 #define TARGET_CAN_ELIMINATE s390_can_eliminate
10495 #undef TARGET_LOOP_UNROLL_ADJUST
10496 #define TARGET_LOOP_UNROLL_ADJUST s390_loop_unroll_adjust
10498 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
10499 #define TARGET_ASM_TRAMPOLINE_TEMPLATE s390_asm_trampoline_template
10500 #undef TARGET_TRAMPOLINE_INIT
10501 #define TARGET_TRAMPOLINE_INIT s390_trampoline_init
10503 #undef TARGET_UNWIND_WORD_MODE
10504 #define TARGET_UNWIND_WORD_MODE s390_unwind_word_mode
10506 struct gcc_target targetm
= TARGET_INITIALIZER
;
10508 #include "gt-s390.h"