1 /* Subroutines used for code generation on IBM S/390 and zSeries
2 Copyright (C) 1999-2015 Free Software Foundation, Inc.
3 Contributed by Hartmut Penner (hpenner@de.ibm.com) and
4 Ulrich Weigand (uweigand@de.ibm.com) and
5 Andreas Krebbel (Andreas.Krebbel@de.ibm.com).
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
31 #include "double-int.h"
38 #include "fold-const.h"
39 #include "print-tree.h"
40 #include "stringpool.h"
41 #include "stor-layout.h"
46 #include "hard-reg-set.h"
47 #include "insn-config.h"
48 #include "conditions.h"
50 #include "insn-attr.h"
56 #include "statistics.h"
58 #include "fixed-value.h"
66 #include "diagnostic-core.h"
68 #include "dominance.h"
74 #include "cfgcleanup.h"
75 #include "basic-block.h"
78 #include "target-def.h"
80 #include "langhooks.h"
81 #include "insn-codes.h"
83 #include "hash-table.h"
84 #include "tree-ssa-alias.h"
85 #include "internal-fn.h"
86 #include "gimple-fold.h"
88 #include "gimple-expr.h"
96 #include "tree-pass.h"
101 #include "plugin-api.h"
105 /* Define the specific costs for a given cpu. */
107 struct processor_costs
110 const int m
; /* cost of an M instruction. */
111 const int mghi
; /* cost of an MGHI instruction. */
112 const int mh
; /* cost of an MH instruction. */
113 const int mhi
; /* cost of an MHI instruction. */
114 const int ml
; /* cost of an ML instruction. */
115 const int mr
; /* cost of an MR instruction. */
116 const int ms
; /* cost of an MS instruction. */
117 const int msg
; /* cost of an MSG instruction. */
118 const int msgf
; /* cost of an MSGF instruction. */
119 const int msgfr
; /* cost of an MSGFR instruction. */
120 const int msgr
; /* cost of an MSGR instruction. */
121 const int msr
; /* cost of an MSR instruction. */
122 const int mult_df
; /* cost of multiplication in DFmode. */
125 const int sqxbr
; /* cost of square root in TFmode. */
126 const int sqdbr
; /* cost of square root in DFmode. */
127 const int sqebr
; /* cost of square root in SFmode. */
128 /* multiply and add */
129 const int madbr
; /* cost of multiply and add in DFmode. */
130 const int maebr
; /* cost of multiply and add in SFmode. */
142 const struct processor_costs
*s390_cost
;
145 struct processor_costs z900_cost
=
147 COSTS_N_INSNS (5), /* M */
148 COSTS_N_INSNS (10), /* MGHI */
149 COSTS_N_INSNS (5), /* MH */
150 COSTS_N_INSNS (4), /* MHI */
151 COSTS_N_INSNS (5), /* ML */
152 COSTS_N_INSNS (5), /* MR */
153 COSTS_N_INSNS (4), /* MS */
154 COSTS_N_INSNS (15), /* MSG */
155 COSTS_N_INSNS (7), /* MSGF */
156 COSTS_N_INSNS (7), /* MSGFR */
157 COSTS_N_INSNS (10), /* MSGR */
158 COSTS_N_INSNS (4), /* MSR */
159 COSTS_N_INSNS (7), /* multiplication in DFmode */
160 COSTS_N_INSNS (13), /* MXBR */
161 COSTS_N_INSNS (136), /* SQXBR */
162 COSTS_N_INSNS (44), /* SQDBR */
163 COSTS_N_INSNS (35), /* SQEBR */
164 COSTS_N_INSNS (18), /* MADBR */
165 COSTS_N_INSNS (13), /* MAEBR */
166 COSTS_N_INSNS (134), /* DXBR */
167 COSTS_N_INSNS (30), /* DDBR */
168 COSTS_N_INSNS (27), /* DEBR */
169 COSTS_N_INSNS (220), /* DLGR */
170 COSTS_N_INSNS (34), /* DLR */
171 COSTS_N_INSNS (34), /* DR */
172 COSTS_N_INSNS (32), /* DSGFR */
173 COSTS_N_INSNS (32), /* DSGR */
177 struct processor_costs z990_cost
=
179 COSTS_N_INSNS (4), /* M */
180 COSTS_N_INSNS (2), /* MGHI */
181 COSTS_N_INSNS (2), /* MH */
182 COSTS_N_INSNS (2), /* MHI */
183 COSTS_N_INSNS (4), /* ML */
184 COSTS_N_INSNS (4), /* MR */
185 COSTS_N_INSNS (5), /* MS */
186 COSTS_N_INSNS (6), /* MSG */
187 COSTS_N_INSNS (4), /* MSGF */
188 COSTS_N_INSNS (4), /* MSGFR */
189 COSTS_N_INSNS (4), /* MSGR */
190 COSTS_N_INSNS (4), /* MSR */
191 COSTS_N_INSNS (1), /* multiplication in DFmode */
192 COSTS_N_INSNS (28), /* MXBR */
193 COSTS_N_INSNS (130), /* SQXBR */
194 COSTS_N_INSNS (66), /* SQDBR */
195 COSTS_N_INSNS (38), /* SQEBR */
196 COSTS_N_INSNS (1), /* MADBR */
197 COSTS_N_INSNS (1), /* MAEBR */
198 COSTS_N_INSNS (60), /* DXBR */
199 COSTS_N_INSNS (40), /* DDBR */
200 COSTS_N_INSNS (26), /* DEBR */
201 COSTS_N_INSNS (176), /* DLGR */
202 COSTS_N_INSNS (31), /* DLR */
203 COSTS_N_INSNS (31), /* DR */
204 COSTS_N_INSNS (31), /* DSGFR */
205 COSTS_N_INSNS (31), /* DSGR */
209 struct processor_costs z9_109_cost
=
211 COSTS_N_INSNS (4), /* M */
212 COSTS_N_INSNS (2), /* MGHI */
213 COSTS_N_INSNS (2), /* MH */
214 COSTS_N_INSNS (2), /* MHI */
215 COSTS_N_INSNS (4), /* ML */
216 COSTS_N_INSNS (4), /* MR */
217 COSTS_N_INSNS (5), /* MS */
218 COSTS_N_INSNS (6), /* MSG */
219 COSTS_N_INSNS (4), /* MSGF */
220 COSTS_N_INSNS (4), /* MSGFR */
221 COSTS_N_INSNS (4), /* MSGR */
222 COSTS_N_INSNS (4), /* MSR */
223 COSTS_N_INSNS (1), /* multiplication in DFmode */
224 COSTS_N_INSNS (28), /* MXBR */
225 COSTS_N_INSNS (130), /* SQXBR */
226 COSTS_N_INSNS (66), /* SQDBR */
227 COSTS_N_INSNS (38), /* SQEBR */
228 COSTS_N_INSNS (1), /* MADBR */
229 COSTS_N_INSNS (1), /* MAEBR */
230 COSTS_N_INSNS (60), /* DXBR */
231 COSTS_N_INSNS (40), /* DDBR */
232 COSTS_N_INSNS (26), /* DEBR */
233 COSTS_N_INSNS (30), /* DLGR */
234 COSTS_N_INSNS (23), /* DLR */
235 COSTS_N_INSNS (23), /* DR */
236 COSTS_N_INSNS (24), /* DSGFR */
237 COSTS_N_INSNS (24), /* DSGR */
241 struct processor_costs z10_cost
=
243 COSTS_N_INSNS (10), /* M */
244 COSTS_N_INSNS (10), /* MGHI */
245 COSTS_N_INSNS (10), /* MH */
246 COSTS_N_INSNS (10), /* MHI */
247 COSTS_N_INSNS (10), /* ML */
248 COSTS_N_INSNS (10), /* MR */
249 COSTS_N_INSNS (10), /* MS */
250 COSTS_N_INSNS (10), /* MSG */
251 COSTS_N_INSNS (10), /* MSGF */
252 COSTS_N_INSNS (10), /* MSGFR */
253 COSTS_N_INSNS (10), /* MSGR */
254 COSTS_N_INSNS (10), /* MSR */
255 COSTS_N_INSNS (1) , /* multiplication in DFmode */
256 COSTS_N_INSNS (50), /* MXBR */
257 COSTS_N_INSNS (120), /* SQXBR */
258 COSTS_N_INSNS (52), /* SQDBR */
259 COSTS_N_INSNS (38), /* SQEBR */
260 COSTS_N_INSNS (1), /* MADBR */
261 COSTS_N_INSNS (1), /* MAEBR */
262 COSTS_N_INSNS (111), /* DXBR */
263 COSTS_N_INSNS (39), /* DDBR */
264 COSTS_N_INSNS (32), /* DEBR */
265 COSTS_N_INSNS (160), /* DLGR */
266 COSTS_N_INSNS (71), /* DLR */
267 COSTS_N_INSNS (71), /* DR */
268 COSTS_N_INSNS (71), /* DSGFR */
269 COSTS_N_INSNS (71), /* DSGR */
273 struct processor_costs z196_cost
=
275 COSTS_N_INSNS (7), /* M */
276 COSTS_N_INSNS (5), /* MGHI */
277 COSTS_N_INSNS (5), /* MH */
278 COSTS_N_INSNS (5), /* MHI */
279 COSTS_N_INSNS (7), /* ML */
280 COSTS_N_INSNS (7), /* MR */
281 COSTS_N_INSNS (6), /* MS */
282 COSTS_N_INSNS (8), /* MSG */
283 COSTS_N_INSNS (6), /* MSGF */
284 COSTS_N_INSNS (6), /* MSGFR */
285 COSTS_N_INSNS (8), /* MSGR */
286 COSTS_N_INSNS (6), /* MSR */
287 COSTS_N_INSNS (1) , /* multiplication in DFmode */
288 COSTS_N_INSNS (40), /* MXBR B+40 */
289 COSTS_N_INSNS (100), /* SQXBR B+100 */
290 COSTS_N_INSNS (42), /* SQDBR B+42 */
291 COSTS_N_INSNS (28), /* SQEBR B+28 */
292 COSTS_N_INSNS (1), /* MADBR B */
293 COSTS_N_INSNS (1), /* MAEBR B */
294 COSTS_N_INSNS (101), /* DXBR B+101 */
295 COSTS_N_INSNS (29), /* DDBR */
296 COSTS_N_INSNS (22), /* DEBR */
297 COSTS_N_INSNS (160), /* DLGR cracked */
298 COSTS_N_INSNS (160), /* DLR cracked */
299 COSTS_N_INSNS (160), /* DR expanded */
300 COSTS_N_INSNS (160), /* DSGFR cracked */
301 COSTS_N_INSNS (160), /* DSGR cracked */
305 struct processor_costs zEC12_cost
=
307 COSTS_N_INSNS (7), /* M */
308 COSTS_N_INSNS (5), /* MGHI */
309 COSTS_N_INSNS (5), /* MH */
310 COSTS_N_INSNS (5), /* MHI */
311 COSTS_N_INSNS (7), /* ML */
312 COSTS_N_INSNS (7), /* MR */
313 COSTS_N_INSNS (6), /* MS */
314 COSTS_N_INSNS (8), /* MSG */
315 COSTS_N_INSNS (6), /* MSGF */
316 COSTS_N_INSNS (6), /* MSGFR */
317 COSTS_N_INSNS (8), /* MSGR */
318 COSTS_N_INSNS (6), /* MSR */
319 COSTS_N_INSNS (1) , /* multiplication in DFmode */
320 COSTS_N_INSNS (40), /* MXBR B+40 */
321 COSTS_N_INSNS (100), /* SQXBR B+100 */
322 COSTS_N_INSNS (42), /* SQDBR B+42 */
323 COSTS_N_INSNS (28), /* SQEBR B+28 */
324 COSTS_N_INSNS (1), /* MADBR B */
325 COSTS_N_INSNS (1), /* MAEBR B */
326 COSTS_N_INSNS (131), /* DXBR B+131 */
327 COSTS_N_INSNS (29), /* DDBR */
328 COSTS_N_INSNS (22), /* DEBR */
329 COSTS_N_INSNS (160), /* DLGR cracked */
330 COSTS_N_INSNS (160), /* DLR cracked */
331 COSTS_N_INSNS (160), /* DR expanded */
332 COSTS_N_INSNS (160), /* DSGFR cracked */
333 COSTS_N_INSNS (160), /* DSGR cracked */
336 extern int reload_completed
;
338 /* Kept up to date using the SCHED_VARIABLE_ISSUE hook. */
339 static rtx_insn
*last_scheduled_insn
;
341 /* Structure used to hold the components of a S/390 memory
342 address. A legitimate address on S/390 is of the general
344 base + index + displacement
345 where any of the components is optional.
347 base and index are registers of the class ADDR_REGS,
348 displacement is an unsigned 12-bit immediate constant. */
359 /* The following structure is embedded in the machine
360 specific part of struct function. */
362 struct GTY (()) s390_frame_layout
364 /* Offset within stack frame. */
365 HOST_WIDE_INT gprs_offset
;
366 HOST_WIDE_INT f0_offset
;
367 HOST_WIDE_INT f4_offset
;
368 HOST_WIDE_INT f8_offset
;
369 HOST_WIDE_INT backchain_offset
;
371 /* Number of first and last gpr where slots in the register
372 save area are reserved for. */
373 int first_save_gpr_slot
;
374 int last_save_gpr_slot
;
376 /* Location (FP register number) where GPRs (r0-r15) should
378 0 - does not need to be saved at all
380 signed char gpr_save_slots
[16];
382 /* Number of first and last gpr to be saved, restored. */
384 int first_restore_gpr
;
386 int last_restore_gpr
;
388 /* Bits standing for floating point registers. Set, if the
389 respective register has to be saved. Starting with reg 16 (f0)
390 at the rightmost bit.
391 Bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
392 fpr 15 13 11 9 14 12 10 8 7 5 3 1 6 4 2 0
393 reg 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 */
394 unsigned int fpr_bitmap
;
396 /* Number of floating point registers f8-f15 which must be saved. */
399 /* Set if return address needs to be saved.
400 This flag is set by s390_return_addr_rtx if it could not use
401 the initial value of r14 and therefore depends on r14 saved
403 bool save_return_addr_p
;
405 /* Size of stack frame. */
406 HOST_WIDE_INT frame_size
;
409 /* Define the structure for the machine field in struct function. */
411 struct GTY(()) machine_function
413 struct s390_frame_layout frame_layout
;
415 /* Literal pool base register. */
418 /* True if we may need to perform branch splitting. */
419 bool split_branches_pending_p
;
421 bool has_landing_pad_p
;
423 /* True if the current function may contain a tbegin clobbering
428 /* Few accessor macros for struct cfun->machine->s390_frame_layout. */
430 #define cfun_frame_layout (cfun->machine->frame_layout)
431 #define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)
432 #define cfun_save_arg_fprs_p (!!(TARGET_64BIT \
433 ? cfun_frame_layout.fpr_bitmap & 0x0f \
434 : cfun_frame_layout.fpr_bitmap & 0x03))
435 #define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr_slot - \
436 cfun_frame_layout.first_save_gpr_slot + 1) * UNITS_PER_LONG)
437 #define cfun_set_fpr_save(REGNO) (cfun->machine->frame_layout.fpr_bitmap |= \
438 (1 << (REGNO - FPR0_REGNUM)))
439 #define cfun_fpr_save_p(REGNO) (!!(cfun->machine->frame_layout.fpr_bitmap & \
440 (1 << (REGNO - FPR0_REGNUM))))
441 #define cfun_gpr_save_slot(REGNO) \
442 cfun->machine->frame_layout.gpr_save_slots[REGNO]
444 /* Number of GPRs and FPRs used for argument passing. */
445 #define GP_ARG_NUM_REG 5
446 #define FP_ARG_NUM_REG (TARGET_64BIT? 4 : 2)
447 #define VEC_ARG_NUM_REG 8
449 /* A couple of shortcuts. */
450 #define CONST_OK_FOR_J(x) \
451 CONST_OK_FOR_CONSTRAINT_P((x), 'J', "J")
452 #define CONST_OK_FOR_K(x) \
453 CONST_OK_FOR_CONSTRAINT_P((x), 'K', "K")
454 #define CONST_OK_FOR_Os(x) \
455 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Os")
456 #define CONST_OK_FOR_Op(x) \
457 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Op")
458 #define CONST_OK_FOR_On(x) \
459 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "On")
461 #define REGNO_PAIR_OK(REGNO, MODE) \
462 (HARD_REGNO_NREGS ((REGNO), (MODE)) == 1 || !((REGNO) & 1))
464 /* That's the read ahead of the dynamic branch prediction unit in
465 bytes on a z10 (or higher) CPU. */
466 #define PREDICT_DISTANCE (TARGET_Z10 ? 384 : 2048)
468 static const int s390_hotpatch_hw_max
= 1000000;
469 static int s390_hotpatch_hw_before_label
= 0;
470 static int s390_hotpatch_hw_after_label
= 0;
472 /* Check whether the hotpatch attribute is applied to a function and, if it has
473 an argument, the argument is valid. */
476 s390_handle_hotpatch_attribute (tree
*node
, tree name
, tree args
,
477 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
483 if (TREE_CODE (*node
) != FUNCTION_DECL
)
485 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
487 *no_add_attrs
= true;
489 if (args
!= NULL
&& TREE_CHAIN (args
) != NULL
)
491 expr
= TREE_VALUE (args
);
492 expr2
= TREE_VALUE (TREE_CHAIN (args
));
494 if (args
== NULL
|| TREE_CHAIN (args
) == NULL
)
496 else if (TREE_CODE (expr
) != INTEGER_CST
497 || !INTEGRAL_TYPE_P (TREE_TYPE (expr
))
498 || wi::gtu_p (expr
, s390_hotpatch_hw_max
))
500 else if (TREE_CODE (expr2
) != INTEGER_CST
501 || !INTEGRAL_TYPE_P (TREE_TYPE (expr2
))
502 || wi::gtu_p (expr2
, s390_hotpatch_hw_max
))
508 error ("requested %qE attribute is not a comma separated pair of"
509 " non-negative integer constants or too large (max. %d)", name
,
510 s390_hotpatch_hw_max
);
511 *no_add_attrs
= true;
517 static const struct attribute_spec s390_attribute_table
[] = {
518 { "hotpatch", 2, 2, true, false, false, s390_handle_hotpatch_attribute
, false
521 { NULL
, 0, 0, false, false, false, NULL
, false }
524 /* Return the alignment for LABEL. We default to the -falign-labels
525 value except for the literal pool base label. */
527 s390_label_align (rtx label
)
529 rtx_insn
*prev_insn
= prev_active_insn (label
);
532 if (prev_insn
== NULL_RTX
)
535 set
= single_set (prev_insn
);
542 /* Don't align literal pool base labels. */
543 if (GET_CODE (src
) == UNSPEC
544 && XINT (src
, 1) == UNSPEC_MAIN_BASE
)
548 return align_labels_log
;
552 s390_libgcc_cmp_return_mode (void)
554 return TARGET_64BIT
? DImode
: SImode
;
558 s390_libgcc_shift_count_mode (void)
560 return TARGET_64BIT
? DImode
: SImode
;
564 s390_unwind_word_mode (void)
566 return TARGET_64BIT
? DImode
: SImode
;
569 /* Return true if the back end supports mode MODE. */
571 s390_scalar_mode_supported_p (machine_mode mode
)
573 /* In contrast to the default implementation reject TImode constants on 31bit
574 TARGET_ZARCH for ABI compliance. */
575 if (!TARGET_64BIT
&& TARGET_ZARCH
&& mode
== TImode
)
578 if (DECIMAL_FLOAT_MODE_P (mode
))
579 return default_decimal_float_supported_p ();
581 return default_scalar_mode_supported_p (mode
);
584 /* Return true if the back end supports vector mode MODE. */
586 s390_vector_mode_supported_p (machine_mode mode
)
590 if (!VECTOR_MODE_P (mode
)
592 || GET_MODE_SIZE (mode
) > 16)
595 inner
= GET_MODE_INNER (mode
);
613 /* Set the has_landing_pad_p flag in struct machine_function to VALUE. */
616 s390_set_has_landing_pad_p (bool value
)
618 cfun
->machine
->has_landing_pad_p
= value
;
621 /* If two condition code modes are compatible, return a condition code
622 mode which is compatible with both. Otherwise, return
626 s390_cc_modes_compatible (machine_mode m1
, machine_mode m2
)
634 if (m2
== CCUmode
|| m2
== CCTmode
|| m2
== CCZ1mode
635 || m2
== CCSmode
|| m2
== CCSRmode
|| m2
== CCURmode
)
656 /* Return true if SET either doesn't set the CC register, or else
657 the source and destination have matching CC modes and that
658 CC mode is at least as constrained as REQ_MODE. */
661 s390_match_ccmode_set (rtx set
, machine_mode req_mode
)
663 machine_mode set_mode
;
665 gcc_assert (GET_CODE (set
) == SET
);
667 if (GET_CODE (SET_DEST (set
)) != REG
|| !CC_REGNO_P (REGNO (SET_DEST (set
))))
670 set_mode
= GET_MODE (SET_DEST (set
));
687 if (req_mode
!= set_mode
)
692 if (req_mode
!= CCSmode
&& req_mode
!= CCUmode
&& req_mode
!= CCTmode
693 && req_mode
!= CCSRmode
&& req_mode
!= CCURmode
)
699 if (req_mode
!= CCAmode
)
707 return (GET_MODE (SET_SRC (set
)) == set_mode
);
710 /* Return true if every SET in INSN that sets the CC register
711 has source and destination with matching CC modes and that
712 CC mode is at least as constrained as REQ_MODE.
713 If REQ_MODE is VOIDmode, always return false. */
716 s390_match_ccmode (rtx_insn
*insn
, machine_mode req_mode
)
720 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
721 if (req_mode
== VOIDmode
)
724 if (GET_CODE (PATTERN (insn
)) == SET
)
725 return s390_match_ccmode_set (PATTERN (insn
), req_mode
);
727 if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
728 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
730 rtx set
= XVECEXP (PATTERN (insn
), 0, i
);
731 if (GET_CODE (set
) == SET
)
732 if (!s390_match_ccmode_set (set
, req_mode
))
739 /* If a test-under-mask instruction can be used to implement
740 (compare (and ... OP1) OP2), return the CC mode required
741 to do that. Otherwise, return VOIDmode.
742 MIXED is true if the instruction can distinguish between
743 CC1 and CC2 for mixed selected bits (TMxx), it is false
744 if the instruction cannot (TM). */
747 s390_tm_ccmode (rtx op1
, rtx op2
, bool mixed
)
751 /* ??? Fixme: should work on CONST_DOUBLE as well. */
752 if (GET_CODE (op1
) != CONST_INT
|| GET_CODE (op2
) != CONST_INT
)
755 /* Selected bits all zero: CC0.
756 e.g.: int a; if ((a & (16 + 128)) == 0) */
757 if (INTVAL (op2
) == 0)
760 /* Selected bits all one: CC3.
761 e.g.: int a; if ((a & (16 + 128)) == 16 + 128) */
762 if (INTVAL (op2
) == INTVAL (op1
))
765 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. e.g.:
767 if ((a & (16 + 128)) == 16) -> CCT1
768 if ((a & (16 + 128)) == 128) -> CCT2 */
771 bit1
= exact_log2 (INTVAL (op2
));
772 bit0
= exact_log2 (INTVAL (op1
) ^ INTVAL (op2
));
773 if (bit0
!= -1 && bit1
!= -1)
774 return bit0
> bit1
? CCT1mode
: CCT2mode
;
780 /* Given a comparison code OP (EQ, NE, etc.) and the operands
781 OP0 and OP1 of a COMPARE, return the mode to be used for the
785 s390_select_ccmode (enum rtx_code code
, rtx op0
, rtx op1
)
788 && register_operand (op0
, DFmode
)
789 && register_operand (op1
, DFmode
))
791 /* LT, LE, UNGT, UNGE require swapping OP0 and OP1. Either
792 s390_emit_compare or s390_canonicalize_comparison will take
814 if ((GET_CODE (op0
) == NEG
|| GET_CODE (op0
) == ABS
)
815 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
817 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
818 && CONST_OK_FOR_K (INTVAL (XEXP (op0
, 1))))
820 if ((GET_CODE (op0
) == PLUS
|| GET_CODE (op0
) == MINUS
821 || GET_CODE (op1
) == NEG
)
822 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
825 if (GET_CODE (op0
) == AND
)
827 /* Check whether we can potentially do it via TM. */
829 ccmode
= s390_tm_ccmode (XEXP (op0
, 1), op1
, 1);
830 if (ccmode
!= VOIDmode
)
832 /* Relax CCTmode to CCZmode to allow fall-back to AND
833 if that turns out to be beneficial. */
834 return ccmode
== CCTmode
? CCZmode
: ccmode
;
838 if (register_operand (op0
, HImode
)
839 && GET_CODE (op1
) == CONST_INT
840 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 65535))
842 if (register_operand (op0
, QImode
)
843 && GET_CODE (op1
) == CONST_INT
844 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 255))
853 /* The only overflow condition of NEG and ABS happens when
854 -INT_MAX is used as parameter, which stays negative. So
855 we have an overflow from a positive value to a negative.
856 Using CCAP mode the resulting cc can be used for comparisons. */
857 if ((GET_CODE (op0
) == NEG
|| GET_CODE (op0
) == ABS
)
858 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
861 /* If constants are involved in an add instruction it is possible to use
862 the resulting cc for comparisons with zero. Knowing the sign of the
863 constant the overflow behavior gets predictable. e.g.:
864 int a, b; if ((b = a + c) > 0)
865 with c as a constant value: c < 0 -> CCAN and c >= 0 -> CCAP */
866 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
867 && (CONST_OK_FOR_K (INTVAL (XEXP (op0
, 1)))
868 || (CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0
, 1)), 'O', "Os")
869 /* Avoid INT32_MIN on 32 bit. */
870 && (!TARGET_ZARCH
|| INTVAL (XEXP (op0
, 1)) != -0x7fffffff - 1))))
872 if (INTVAL (XEXP((op0
), 1)) < 0)
886 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
887 && GET_CODE (op1
) != CONST_INT
)
893 if (GET_CODE (op0
) == PLUS
894 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
897 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
898 && GET_CODE (op1
) != CONST_INT
)
904 if (GET_CODE (op0
) == MINUS
905 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
908 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
909 && GET_CODE (op1
) != CONST_INT
)
918 /* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
919 that we can implement more efficiently. */
922 s390_canonicalize_comparison (int *code
, rtx
*op0
, rtx
*op1
,
923 bool op0_preserve_value
)
925 if (op0_preserve_value
)
928 /* Convert ZERO_EXTRACT back to AND to enable TM patterns. */
929 if ((*code
== EQ
|| *code
== NE
)
930 && *op1
== const0_rtx
931 && GET_CODE (*op0
) == ZERO_EXTRACT
932 && GET_CODE (XEXP (*op0
, 1)) == CONST_INT
933 && GET_CODE (XEXP (*op0
, 2)) == CONST_INT
934 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0
, 0))))
936 rtx inner
= XEXP (*op0
, 0);
937 HOST_WIDE_INT modesize
= GET_MODE_BITSIZE (GET_MODE (inner
));
938 HOST_WIDE_INT len
= INTVAL (XEXP (*op0
, 1));
939 HOST_WIDE_INT pos
= INTVAL (XEXP (*op0
, 2));
941 if (len
> 0 && len
< modesize
942 && pos
>= 0 && pos
+ len
<= modesize
943 && modesize
<= HOST_BITS_PER_WIDE_INT
)
945 unsigned HOST_WIDE_INT block
;
946 block
= ((unsigned HOST_WIDE_INT
) 1 << len
) - 1;
947 block
<<= modesize
- pos
- len
;
949 *op0
= gen_rtx_AND (GET_MODE (inner
), inner
,
950 gen_int_mode (block
, GET_MODE (inner
)));
954 /* Narrow AND of memory against immediate to enable TM. */
955 if ((*code
== EQ
|| *code
== NE
)
956 && *op1
== const0_rtx
957 && GET_CODE (*op0
) == AND
958 && GET_CODE (XEXP (*op0
, 1)) == CONST_INT
959 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0
, 0))))
961 rtx inner
= XEXP (*op0
, 0);
962 rtx mask
= XEXP (*op0
, 1);
964 /* Ignore paradoxical SUBREGs if all extra bits are masked out. */
965 if (GET_CODE (inner
) == SUBREG
966 && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (inner
)))
967 && (GET_MODE_SIZE (GET_MODE (inner
))
968 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner
))))
970 & GET_MODE_MASK (GET_MODE (inner
))
971 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (inner
))))
973 inner
= SUBREG_REG (inner
);
975 /* Do not change volatile MEMs. */
976 if (MEM_P (inner
) && !MEM_VOLATILE_P (inner
))
978 int part
= s390_single_part (XEXP (*op0
, 1),
979 GET_MODE (inner
), QImode
, 0);
982 mask
= gen_int_mode (s390_extract_part (mask
, QImode
, 0), QImode
);
983 inner
= adjust_address_nv (inner
, QImode
, part
);
984 *op0
= gen_rtx_AND (QImode
, inner
, mask
);
989 /* Narrow comparisons against 0xffff to HImode if possible. */
990 if ((*code
== EQ
|| *code
== NE
)
991 && GET_CODE (*op1
) == CONST_INT
992 && INTVAL (*op1
) == 0xffff
993 && SCALAR_INT_MODE_P (GET_MODE (*op0
))
994 && (nonzero_bits (*op0
, GET_MODE (*op0
))
995 & ~(unsigned HOST_WIDE_INT
) 0xffff) == 0)
997 *op0
= gen_lowpart (HImode
, *op0
);
1001 /* Remove redundant UNSPEC_STRCMPCC_TO_INT conversions if possible. */
1002 if (GET_CODE (*op0
) == UNSPEC
1003 && XINT (*op0
, 1) == UNSPEC_STRCMPCC_TO_INT
1004 && XVECLEN (*op0
, 0) == 1
1005 && GET_MODE (XVECEXP (*op0
, 0, 0)) == CCUmode
1006 && GET_CODE (XVECEXP (*op0
, 0, 0)) == REG
1007 && REGNO (XVECEXP (*op0
, 0, 0)) == CC_REGNUM
1008 && *op1
== const0_rtx
)
1010 enum rtx_code new_code
= UNKNOWN
;
1013 case EQ
: new_code
= EQ
; break;
1014 case NE
: new_code
= NE
; break;
1015 case LT
: new_code
= GTU
; break;
1016 case GT
: new_code
= LTU
; break;
1017 case LE
: new_code
= GEU
; break;
1018 case GE
: new_code
= LEU
; break;
1022 if (new_code
!= UNKNOWN
)
1024 *op0
= XVECEXP (*op0
, 0, 0);
1029 /* Remove redundant UNSPEC_CC_TO_INT conversions if possible. */
1030 if (GET_CODE (*op0
) == UNSPEC
1031 && XINT (*op0
, 1) == UNSPEC_CC_TO_INT
1032 && XVECLEN (*op0
, 0) == 1
1033 && GET_CODE (XVECEXP (*op0
, 0, 0)) == REG
1034 && REGNO (XVECEXP (*op0
, 0, 0)) == CC_REGNUM
1035 && CONST_INT_P (*op1
))
1037 enum rtx_code new_code
= UNKNOWN
;
1038 switch (GET_MODE (XVECEXP (*op0
, 0, 0)))
1044 case EQ
: new_code
= EQ
; break;
1045 case NE
: new_code
= NE
; break;
1052 if (new_code
!= UNKNOWN
)
1054 /* For CCRAWmode put the required cc mask into the second
1056 if (GET_MODE (XVECEXP (*op0
, 0, 0)) == CCRAWmode
1057 && INTVAL (*op1
) >= 0 && INTVAL (*op1
) <= 3)
1058 *op1
= gen_rtx_CONST_INT (VOIDmode
, 1 << (3 - INTVAL (*op1
)));
1059 *op0
= XVECEXP (*op0
, 0, 0);
1064 /* Simplify cascaded EQ, NE with const0_rtx. */
1065 if ((*code
== NE
|| *code
== EQ
)
1066 && (GET_CODE (*op0
) == EQ
|| GET_CODE (*op0
) == NE
)
1067 && GET_MODE (*op0
) == SImode
1068 && GET_MODE (XEXP (*op0
, 0)) == CCZ1mode
1069 && REG_P (XEXP (*op0
, 0))
1070 && XEXP (*op0
, 1) == const0_rtx
1071 && *op1
== const0_rtx
)
1073 if ((*code
== EQ
&& GET_CODE (*op0
) == NE
)
1074 || (*code
== NE
&& GET_CODE (*op0
) == EQ
))
1078 *op0
= XEXP (*op0
, 0);
1081 /* Prefer register over memory as first operand. */
1082 if (MEM_P (*op0
) && REG_P (*op1
))
1084 rtx tem
= *op0
; *op0
= *op1
; *op1
= tem
;
1085 *code
= (int)swap_condition ((enum rtx_code
)*code
);
1088 /* Using the scalar variants of vector instructions for 64 bit FP
1089 comparisons might require swapping the operands. */
1091 && register_operand (*op0
, DFmode
)
1092 && register_operand (*op1
, DFmode
)
1093 && (*code
== LT
|| *code
== LE
|| *code
== UNGT
|| *code
== UNGE
))
1099 case LT
: *code
= GT
; break;
1100 case LE
: *code
= GE
; break;
1101 case UNGT
: *code
= UNLE
; break;
1102 case UNGE
: *code
= UNLT
; break;
1105 tmp
= *op0
; *op0
= *op1
; *op1
= tmp
;
1109 /* Helper function for s390_emit_compare. If possible emit a 64 bit
1110 FP compare using the single element variant of vector instructions.
1111 Replace CODE with the comparison code to be used in the CC reg
1112 compare and return the condition code register RTX in CC. */
1115 s390_expand_vec_compare_scalar (enum rtx_code
*code
, rtx cmp1
, rtx cmp2
,
1118 machine_mode cmp_mode
;
1119 bool swap_p
= false;
1123 case EQ
: cmp_mode
= CCVEQmode
; break;
1124 case NE
: cmp_mode
= CCVEQmode
; break;
1125 case GT
: cmp_mode
= CCVFHmode
; break;
1126 case GE
: cmp_mode
= CCVFHEmode
; break;
1127 case UNLE
: cmp_mode
= CCVFHmode
; break;
1128 case UNLT
: cmp_mode
= CCVFHEmode
; break;
1129 case LT
: cmp_mode
= CCVFHmode
; *code
= GT
; swap_p
= true; break;
1130 case LE
: cmp_mode
= CCVFHEmode
; *code
= GE
; swap_p
= true; break;
1131 case UNGE
: cmp_mode
= CCVFHmode
; *code
= UNLE
; swap_p
= true; break;
1132 case UNGT
: cmp_mode
= CCVFHEmode
; *code
= UNLT
; swap_p
= true; break;
1133 default: return false;
1142 *cc
= gen_rtx_REG (cmp_mode
, CC_REGNUM
);
1143 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
1146 gen_rtx_COMPARE (cmp_mode
, cmp1
,
1148 gen_rtx_CLOBBER (VOIDmode
,
1149 gen_rtx_SCRATCH (V2DImode
)))));
1154 /* Emit a compare instruction suitable to implement the comparison
1155 OP0 CODE OP1. Return the correct condition RTL to be placed in
1156 the IF_THEN_ELSE of the conditional branch testing the result. */
1159 s390_emit_compare (enum rtx_code code
, rtx op0
, rtx op1
)
1161 machine_mode mode
= s390_select_ccmode (code
, op0
, op1
);
1165 && register_operand (op0
, DFmode
)
1166 && register_operand (op1
, DFmode
)
1167 && s390_expand_vec_compare_scalar (&code
, op0
, op1
, &cc
))
1169 /* Work has been done by s390_expand_vec_compare_scalar already. */
1171 else if (GET_MODE_CLASS (GET_MODE (op0
)) == MODE_CC
)
1173 /* Do not output a redundant compare instruction if a
1174 compare_and_swap pattern already computed the result and the
1175 machine modes are compatible. */
1176 gcc_assert (s390_cc_modes_compatible (GET_MODE (op0
), mode
)
1182 cc
= gen_rtx_REG (mode
, CC_REGNUM
);
1183 emit_insn (gen_rtx_SET (cc
, gen_rtx_COMPARE (mode
, op0
, op1
)));
1186 return gen_rtx_fmt_ee (code
, VOIDmode
, cc
, const0_rtx
);
1189 /* Emit a SImode compare and swap instruction setting MEM to NEW_RTX if OLD
1191 Return the correct condition RTL to be placed in the IF_THEN_ELSE of the
1192 conditional branch testing the result. */
1195 s390_emit_compare_and_swap (enum rtx_code code
, rtx old
, rtx mem
,
1196 rtx cmp
, rtx new_rtx
)
1198 emit_insn (gen_atomic_compare_and_swapsi_internal (old
, mem
, cmp
, new_rtx
));
1199 return s390_emit_compare (code
, gen_rtx_REG (CCZ1mode
, CC_REGNUM
),
1203 /* Emit a jump instruction to TARGET and return it. If COND is
1204 NULL_RTX, emit an unconditional jump, else a conditional jump under
1208 s390_emit_jump (rtx target
, rtx cond
)
1212 target
= gen_rtx_LABEL_REF (VOIDmode
, target
);
1214 target
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, target
, pc_rtx
);
1216 insn
= gen_rtx_SET (pc_rtx
, target
);
1217 return emit_jump_insn (insn
);
1220 /* Return branch condition mask to implement a branch
1221 specified by CODE. Return -1 for invalid comparisons. */
1224 s390_branch_condition_mask (rtx code
)
1226 const int CC0
= 1 << 3;
1227 const int CC1
= 1 << 2;
1228 const int CC2
= 1 << 1;
1229 const int CC3
= 1 << 0;
1231 gcc_assert (GET_CODE (XEXP (code
, 0)) == REG
);
1232 gcc_assert (REGNO (XEXP (code
, 0)) == CC_REGNUM
);
1233 gcc_assert (XEXP (code
, 1) == const0_rtx
1234 || (GET_MODE (XEXP (code
, 0)) == CCRAWmode
1235 && CONST_INT_P (XEXP (code
, 1))));
1238 switch (GET_MODE (XEXP (code
, 0)))
1242 switch (GET_CODE (code
))
1244 case EQ
: return CC0
;
1245 case NE
: return CC1
| CC2
| CC3
;
1251 switch (GET_CODE (code
))
1253 case EQ
: return CC1
;
1254 case NE
: return CC0
| CC2
| CC3
;
1260 switch (GET_CODE (code
))
1262 case EQ
: return CC2
;
1263 case NE
: return CC0
| CC1
| CC3
;
1269 switch (GET_CODE (code
))
1271 case EQ
: return CC3
;
1272 case NE
: return CC0
| CC1
| CC2
;
1278 switch (GET_CODE (code
))
1280 case EQ
: return CC0
| CC2
;
1281 case NE
: return CC1
| CC3
;
1287 switch (GET_CODE (code
))
1289 case LTU
: return CC2
| CC3
; /* carry */
1290 case GEU
: return CC0
| CC1
; /* no carry */
1296 switch (GET_CODE (code
))
1298 case GTU
: return CC0
| CC1
; /* borrow */
1299 case LEU
: return CC2
| CC3
; /* no borrow */
1305 switch (GET_CODE (code
))
1307 case EQ
: return CC0
| CC2
;
1308 case NE
: return CC1
| CC3
;
1309 case LTU
: return CC1
;
1310 case GTU
: return CC3
;
1311 case LEU
: return CC1
| CC2
;
1312 case GEU
: return CC2
| CC3
;
1317 switch (GET_CODE (code
))
1319 case EQ
: return CC0
;
1320 case NE
: return CC1
| CC2
| CC3
;
1321 case LTU
: return CC1
;
1322 case GTU
: return CC2
;
1323 case LEU
: return CC0
| CC1
;
1324 case GEU
: return CC0
| CC2
;
1330 switch (GET_CODE (code
))
1332 case EQ
: return CC0
;
1333 case NE
: return CC2
| CC1
| CC3
;
1334 case LTU
: return CC2
;
1335 case GTU
: return CC1
;
1336 case LEU
: return CC0
| CC2
;
1337 case GEU
: return CC0
| CC1
;
1343 switch (GET_CODE (code
))
1345 case EQ
: return CC0
;
1346 case NE
: return CC1
| CC2
| CC3
;
1347 case LT
: return CC1
| CC3
;
1348 case GT
: return CC2
;
1349 case LE
: return CC0
| CC1
| CC3
;
1350 case GE
: return CC0
| CC2
;
1356 switch (GET_CODE (code
))
1358 case EQ
: return CC0
;
1359 case NE
: return CC1
| CC2
| CC3
;
1360 case LT
: return CC1
;
1361 case GT
: return CC2
| CC3
;
1362 case LE
: return CC0
| CC1
;
1363 case GE
: return CC0
| CC2
| CC3
;
1369 switch (GET_CODE (code
))
1371 case EQ
: return CC0
;
1372 case NE
: return CC1
| CC2
| CC3
;
1373 case LT
: return CC1
;
1374 case GT
: return CC2
;
1375 case LE
: return CC0
| CC1
;
1376 case GE
: return CC0
| CC2
;
1377 case UNORDERED
: return CC3
;
1378 case ORDERED
: return CC0
| CC1
| CC2
;
1379 case UNEQ
: return CC0
| CC3
;
1380 case UNLT
: return CC1
| CC3
;
1381 case UNGT
: return CC2
| CC3
;
1382 case UNLE
: return CC0
| CC1
| CC3
;
1383 case UNGE
: return CC0
| CC2
| CC3
;
1384 case LTGT
: return CC1
| CC2
;
1390 switch (GET_CODE (code
))
1392 case EQ
: return CC0
;
1393 case NE
: return CC2
| CC1
| CC3
;
1394 case LT
: return CC2
;
1395 case GT
: return CC1
;
1396 case LE
: return CC0
| CC2
;
1397 case GE
: return CC0
| CC1
;
1398 case UNORDERED
: return CC3
;
1399 case ORDERED
: return CC0
| CC2
| CC1
;
1400 case UNEQ
: return CC0
| CC3
;
1401 case UNLT
: return CC2
| CC3
;
1402 case UNGT
: return CC1
| CC3
;
1403 case UNLE
: return CC0
| CC2
| CC3
;
1404 case UNGE
: return CC0
| CC1
| CC3
;
1405 case LTGT
: return CC2
| CC1
;
1410 /* Vector comparison modes. */
1413 switch (GET_CODE (code
))
1415 case EQ
: return CC0
;
1416 case NE
: return CC3
;
1419 /* FP vector compare modes. */
1422 switch (GET_CODE (code
))
1424 case GT
: return CC0
;
1425 case UNLE
: return CC3
;
1429 switch (GET_CODE (code
))
1431 case GE
: return CC0
;
1432 case UNLT
: return CC3
;
1436 switch (GET_CODE (code
))
1439 return INTVAL (XEXP (code
, 1));
1441 return (INTVAL (XEXP (code
, 1))) ^ 0xf;
1452 /* Return branch condition mask to implement a compare and branch
1453 specified by CODE. Return -1 for invalid comparisons. */
1456 s390_compare_and_branch_condition_mask (rtx code
)
1458 const int CC0
= 1 << 3;
1459 const int CC1
= 1 << 2;
1460 const int CC2
= 1 << 1;
1462 switch (GET_CODE (code
))
1486 /* If INV is false, return assembler mnemonic string to implement
1487 a branch specified by CODE. If INV is true, return mnemonic
1488 for the corresponding inverted branch. */
1491 s390_branch_condition_mnemonic (rtx code
, int inv
)
1495 static const char *const mnemonic
[16] =
1497 NULL
, "o", "h", "nle",
1498 "l", "nhe", "lh", "ne",
1499 "e", "nlh", "he", "nl",
1500 "le", "nh", "no", NULL
1503 if (GET_CODE (XEXP (code
, 0)) == REG
1504 && REGNO (XEXP (code
, 0)) == CC_REGNUM
1505 && (XEXP (code
, 1) == const0_rtx
1506 || (GET_MODE (XEXP (code
, 0)) == CCRAWmode
1507 && CONST_INT_P (XEXP (code
, 1)))))
1508 mask
= s390_branch_condition_mask (code
);
1510 mask
= s390_compare_and_branch_condition_mask (code
);
1512 gcc_assert (mask
>= 0);
1517 gcc_assert (mask
>= 1 && mask
<= 14);
1519 return mnemonic
[mask
];
1522 /* Return the part of op which has a value different from def.
1523 The size of the part is determined by mode.
1524 Use this function only if you already know that op really
1525 contains such a part. */
1527 unsigned HOST_WIDE_INT
1528 s390_extract_part (rtx op
, machine_mode mode
, int def
)
1530 unsigned HOST_WIDE_INT value
= 0;
1531 int max_parts
= HOST_BITS_PER_WIDE_INT
/ GET_MODE_BITSIZE (mode
);
1532 int part_bits
= GET_MODE_BITSIZE (mode
);
1533 unsigned HOST_WIDE_INT part_mask
1534 = ((unsigned HOST_WIDE_INT
)1 << part_bits
) - 1;
1537 for (i
= 0; i
< max_parts
; i
++)
1540 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
1542 value
>>= part_bits
;
1544 if ((value
& part_mask
) != (def
& part_mask
))
1545 return value
& part_mask
;
1551 /* If OP is an integer constant of mode MODE with exactly one
1552 part of mode PART_MODE unequal to DEF, return the number of that
1553 part. Otherwise, return -1. */
1556 s390_single_part (rtx op
,
1558 machine_mode part_mode
,
1561 unsigned HOST_WIDE_INT value
= 0;
1562 int n_parts
= GET_MODE_SIZE (mode
) / GET_MODE_SIZE (part_mode
);
1563 unsigned HOST_WIDE_INT part_mask
1564 = ((unsigned HOST_WIDE_INT
)1 << GET_MODE_BITSIZE (part_mode
)) - 1;
1567 if (GET_CODE (op
) != CONST_INT
)
1570 for (i
= 0; i
< n_parts
; i
++)
1573 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
1575 value
>>= GET_MODE_BITSIZE (part_mode
);
1577 if ((value
& part_mask
) != (def
& part_mask
))
1585 return part
== -1 ? -1 : n_parts
- 1 - part
;
1588 /* Return true if IN contains a contiguous bitfield in the lower SIZE
1589 bits and no other bits are set in IN. POS and LENGTH can be used
1590 to obtain the start position and the length of the bitfield.
1592 POS gives the position of the first bit of the bitfield counting
1593 from the lowest order bit starting with zero. In order to use this
1594 value for S/390 instructions this has to be converted to "bits big
1598 s390_contiguous_bitmask_p (unsigned HOST_WIDE_INT in
, int size
,
1599 int *pos
, int *length
)
1604 unsigned HOST_WIDE_INT mask
= 1ULL;
1605 bool contiguous
= false;
1607 for (i
= 0; i
< size
; mask
<<= 1, i
++)
1631 /* Calculate a mask for all bits beyond the contiguous bits. */
1632 mask
= (-1LL & ~(((1ULL << (tmp_length
+ tmp_pos
- 1)) << 1) - 1));
1634 if ((unsigned)size
< sizeof (HOST_WIDE_INT
) * BITS_PER_UNIT
)
1635 mask
&= (HOST_WIDE_INT_1U
<< size
) - 1;
1640 if (tmp_length
+ tmp_pos
- 1 > size
)
1644 *length
= tmp_length
;
1652 /* Return true if OP contains the same contiguous bitfield in *all*
1653 its elements. START and END can be used to obtain the start and
1654 end position of the bitfield.
1656 START/STOP give the position of the first/last bit of the bitfield
1657 counting from the lowest order bit starting with zero. In order to
1658 use these values for S/390 instructions this has to be converted to
1659 "bits big endian" style. */
1662 s390_contiguous_bitmask_vector_p (rtx op
, int *start
, int *end
)
1664 unsigned HOST_WIDE_INT mask
;
1667 if (!VECTOR_MODE_P (GET_MODE (op
))
1668 || GET_CODE (op
) != CONST_VECTOR
1669 || !CONST_INT_P (XVECEXP (op
, 0, 0)))
1672 if (GET_MODE_NUNITS (GET_MODE (op
)) > 1)
1676 for (i
= 1; i
< GET_MODE_NUNITS (GET_MODE (op
)); ++i
)
1677 if (!rtx_equal_p (XVECEXP (op
, 0, i
), XVECEXP (op
, 0, 0)))
1681 size
= GET_MODE_UNIT_BITSIZE (GET_MODE (op
));
1682 mask
= UINTVAL (XVECEXP (op
, 0, 0));
1683 if (s390_contiguous_bitmask_p (mask
, size
, start
,
1684 end
!= NULL
? &length
: NULL
))
1687 *end
= *start
+ length
- 1;
1690 /* 0xff00000f style immediates can be covered by swapping start and
1691 end indices in vgm. */
1692 if (s390_contiguous_bitmask_p (~mask
, size
, start
,
1693 end
!= NULL
? &length
: NULL
))
1698 *start
= *start
+ length
;
1704 /* Return true if C consists only of byte chunks being either 0 or
1705 0xff. If MASK is !=NULL a byte mask is generated which is
1706 appropriate for the vector generate byte mask instruction. */
1709 s390_bytemask_vector_p (rtx op
, unsigned *mask
)
1712 unsigned tmp_mask
= 0;
1713 int nunit
, unit_size
;
1715 if (!VECTOR_MODE_P (GET_MODE (op
))
1716 || GET_CODE (op
) != CONST_VECTOR
1717 || !CONST_INT_P (XVECEXP (op
, 0, 0)))
1720 nunit
= GET_MODE_NUNITS (GET_MODE (op
));
1721 unit_size
= GET_MODE_UNIT_SIZE (GET_MODE (op
));
1723 for (i
= 0; i
< nunit
; i
++)
1725 unsigned HOST_WIDE_INT c
;
1728 if (!CONST_INT_P (XVECEXP (op
, 0, i
)))
1731 c
= UINTVAL (XVECEXP (op
, 0, i
));
1732 for (j
= 0; j
< unit_size
; j
++)
1734 if ((c
& 0xff) != 0 && (c
& 0xff) != 0xff)
1736 tmp_mask
|= (c
& 1) << ((nunit
- 1 - i
) * unit_size
+ j
);
1737 c
= c
>> BITS_PER_UNIT
;
1747 /* Check whether a rotate of ROTL followed by an AND of CONTIG is
1748 equivalent to a shift followed by the AND. In particular, CONTIG
1749 should not overlap the (rotated) bit 0/bit 63 gap. Negative values
1750 for ROTL indicate a rotate to the right. */
1753 s390_extzv_shift_ok (int bitsize
, int rotl
, unsigned HOST_WIDE_INT contig
)
1758 ok
= s390_contiguous_bitmask_p (contig
, bitsize
, &pos
, &len
);
1761 return ((rotl
>= 0 && rotl
<= pos
)
1762 || (rotl
< 0 && -rotl
<= bitsize
- len
- pos
));
1765 /* Check whether we can (and want to) split a double-word
1766 move in mode MODE from SRC to DST into two single-word
1767 moves, moving the subword FIRST_SUBWORD first. */
1770 s390_split_ok_p (rtx dst
, rtx src
, machine_mode mode
, int first_subword
)
1772 /* Floating point and vector registers cannot be split. */
1773 if (FP_REG_P (src
) || FP_REG_P (dst
) || VECTOR_REG_P (src
) || VECTOR_REG_P (dst
))
1776 /* We don't need to split if operands are directly accessible. */
1777 if (s_operand (src
, mode
) || s_operand (dst
, mode
))
1780 /* Non-offsettable memory references cannot be split. */
1781 if ((GET_CODE (src
) == MEM
&& !offsettable_memref_p (src
))
1782 || (GET_CODE (dst
) == MEM
&& !offsettable_memref_p (dst
)))
1785 /* Moving the first subword must not clobber a register
1786 needed to move the second subword. */
1787 if (register_operand (dst
, mode
))
1789 rtx subreg
= operand_subword (dst
, first_subword
, 0, mode
);
1790 if (reg_overlap_mentioned_p (subreg
, src
))
1797 /* Return true if it can be proven that [MEM1, MEM1 + SIZE]
1798 and [MEM2, MEM2 + SIZE] do overlap and false
1802 s390_overlap_p (rtx mem1
, rtx mem2
, HOST_WIDE_INT size
)
1804 rtx addr1
, addr2
, addr_delta
;
1805 HOST_WIDE_INT delta
;
1807 if (GET_CODE (mem1
) != MEM
|| GET_CODE (mem2
) != MEM
)
1813 addr1
= XEXP (mem1
, 0);
1814 addr2
= XEXP (mem2
, 0);
1816 addr_delta
= simplify_binary_operation (MINUS
, Pmode
, addr2
, addr1
);
1818 /* This overlapping check is used by peepholes merging memory block operations.
1819 Overlapping operations would otherwise be recognized by the S/390 hardware
1820 and would fall back to a slower implementation. Allowing overlapping
1821 operations would lead to slow code but not to wrong code. Therefore we are
1822 somewhat optimistic if we cannot prove that the memory blocks are
1824 That's why we return false here although this may accept operations on
1825 overlapping memory areas. */
1826 if (!addr_delta
|| GET_CODE (addr_delta
) != CONST_INT
)
1829 delta
= INTVAL (addr_delta
);
1832 || (delta
> 0 && delta
< size
)
1833 || (delta
< 0 && -delta
< size
))
1839 /* Check whether the address of memory reference MEM2 equals exactly
1840 the address of memory reference MEM1 plus DELTA. Return true if
1841 we can prove this to be the case, false otherwise. */
1844 s390_offset_p (rtx mem1
, rtx mem2
, rtx delta
)
1846 rtx addr1
, addr2
, addr_delta
;
1848 if (GET_CODE (mem1
) != MEM
|| GET_CODE (mem2
) != MEM
)
1851 addr1
= XEXP (mem1
, 0);
1852 addr2
= XEXP (mem2
, 0);
1854 addr_delta
= simplify_binary_operation (MINUS
, Pmode
, addr2
, addr1
);
1855 if (!addr_delta
|| !rtx_equal_p (addr_delta
, delta
))
1861 /* Expand logical operator CODE in mode MODE with operands OPERANDS. */
1864 s390_expand_logical_operator (enum rtx_code code
, machine_mode mode
,
1867 machine_mode wmode
= mode
;
1868 rtx dst
= operands
[0];
1869 rtx src1
= operands
[1];
1870 rtx src2
= operands
[2];
1873 /* If we cannot handle the operation directly, use a temp register. */
1874 if (!s390_logical_operator_ok_p (operands
))
1875 dst
= gen_reg_rtx (mode
);
1877 /* QImode and HImode patterns make sense only if we have a destination
1878 in memory. Otherwise perform the operation in SImode. */
1879 if ((mode
== QImode
|| mode
== HImode
) && GET_CODE (dst
) != MEM
)
1882 /* Widen operands if required. */
1885 if (GET_CODE (dst
) == SUBREG
1886 && (tem
= simplify_subreg (wmode
, dst
, mode
, 0)) != 0)
1888 else if (REG_P (dst
))
1889 dst
= gen_rtx_SUBREG (wmode
, dst
, 0);
1891 dst
= gen_reg_rtx (wmode
);
1893 if (GET_CODE (src1
) == SUBREG
1894 && (tem
= simplify_subreg (wmode
, src1
, mode
, 0)) != 0)
1896 else if (GET_MODE (src1
) != VOIDmode
)
1897 src1
= gen_rtx_SUBREG (wmode
, force_reg (mode
, src1
), 0);
1899 if (GET_CODE (src2
) == SUBREG
1900 && (tem
= simplify_subreg (wmode
, src2
, mode
, 0)) != 0)
1902 else if (GET_MODE (src2
) != VOIDmode
)
1903 src2
= gen_rtx_SUBREG (wmode
, force_reg (mode
, src2
), 0);
1906 /* Emit the instruction. */
1907 op
= gen_rtx_SET (dst
, gen_rtx_fmt_ee (code
, wmode
, src1
, src2
));
1908 clob
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
1909 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, op
, clob
)));
1911 /* Fix up the destination if needed. */
1912 if (dst
!= operands
[0])
1913 emit_move_insn (operands
[0], gen_lowpart (mode
, dst
));
1916 /* Check whether OPERANDS are OK for a logical operation (AND, IOR, XOR). */
1919 s390_logical_operator_ok_p (rtx
*operands
)
1921 /* If the destination operand is in memory, it needs to coincide
1922 with one of the source operands. After reload, it has to be
1923 the first source operand. */
1924 if (GET_CODE (operands
[0]) == MEM
)
1925 return rtx_equal_p (operands
[0], operands
[1])
1926 || (!reload_completed
&& rtx_equal_p (operands
[0], operands
[2]));
1931 /* Narrow logical operation CODE of memory operand MEMOP with immediate
1932 operand IMMOP to switch from SS to SI type instructions. */
1935 s390_narrow_logical_operator (enum rtx_code code
, rtx
*memop
, rtx
*immop
)
1937 int def
= code
== AND
? -1 : 0;
1941 gcc_assert (GET_CODE (*memop
) == MEM
);
1942 gcc_assert (!MEM_VOLATILE_P (*memop
));
1944 mask
= s390_extract_part (*immop
, QImode
, def
);
1945 part
= s390_single_part (*immop
, GET_MODE (*memop
), QImode
, def
);
1946 gcc_assert (part
>= 0);
1948 *memop
= adjust_address (*memop
, QImode
, part
);
1949 *immop
= gen_int_mode (mask
, QImode
);
1953 /* How to allocate a 'struct machine_function'. */
1955 static struct machine_function
*
1956 s390_init_machine_status (void)
1958 return ggc_cleared_alloc
<machine_function
> ();
1961 /* Map for smallest class containing reg regno. */
1963 const enum reg_class regclass_map
[FIRST_PSEUDO_REGISTER
] =
1964 { GENERAL_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, /* 0 */
1965 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, /* 4 */
1966 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, /* 8 */
1967 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, /* 12 */
1968 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
, /* 16 */
1969 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
, /* 20 */
1970 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
, /* 24 */
1971 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
, /* 28 */
1972 ADDR_REGS
, CC_REGS
, ADDR_REGS
, ADDR_REGS
, /* 32 */
1973 ACCESS_REGS
, ACCESS_REGS
, VEC_REGS
, VEC_REGS
, /* 36 */
1974 VEC_REGS
, VEC_REGS
, VEC_REGS
, VEC_REGS
, /* 40 */
1975 VEC_REGS
, VEC_REGS
, VEC_REGS
, VEC_REGS
, /* 44 */
1976 VEC_REGS
, VEC_REGS
, VEC_REGS
, VEC_REGS
, /* 48 */
1977 VEC_REGS
, VEC_REGS
/* 52 */
1980 /* Return attribute type of insn. */
1982 static enum attr_type
1983 s390_safe_attr_type (rtx_insn
*insn
)
1985 if (recog_memoized (insn
) >= 0)
1986 return get_attr_type (insn
);
1991 /* Return true if DISP is a valid short displacement. */
1994 s390_short_displacement (rtx disp
)
1996 /* No displacement is OK. */
2000 /* Without the long displacement facility we don't need to
2001 distingiush between long and short displacement. */
2002 if (!TARGET_LONG_DISPLACEMENT
)
2005 /* Integer displacement in range. */
2006 if (GET_CODE (disp
) == CONST_INT
)
2007 return INTVAL (disp
) >= 0 && INTVAL (disp
) < 4096;
2009 /* GOT offset is not OK, the GOT can be large. */
2010 if (GET_CODE (disp
) == CONST
2011 && GET_CODE (XEXP (disp
, 0)) == UNSPEC
2012 && (XINT (XEXP (disp
, 0), 1) == UNSPEC_GOT
2013 || XINT (XEXP (disp
, 0), 1) == UNSPEC_GOTNTPOFF
))
2016 /* All other symbolic constants are literal pool references,
2017 which are OK as the literal pool must be small. */
2018 if (GET_CODE (disp
) == CONST
)
2024 /* Decompose a RTL expression ADDR for a memory address into
2025 its components, returned in OUT.
2027 Returns false if ADDR is not a valid memory address, true
2028 otherwise. If OUT is NULL, don't return the components,
2029 but check for validity only.
2031 Note: Only addresses in canonical form are recognized.
2032 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
2033 canonical form so that they will be recognized. */
2036 s390_decompose_address (rtx addr
, struct s390_address
*out
)
2038 HOST_WIDE_INT offset
= 0;
2039 rtx base
= NULL_RTX
;
2040 rtx indx
= NULL_RTX
;
2041 rtx disp
= NULL_RTX
;
2043 bool pointer
= false;
2044 bool base_ptr
= false;
2045 bool indx_ptr
= false;
2046 bool literal_pool
= false;
2048 /* We may need to substitute the literal pool base register into the address
2049 below. However, at this point we do not know which register is going to
2050 be used as base, so we substitute the arg pointer register. This is going
2051 to be treated as holding a pointer below -- it shouldn't be used for any
2053 rtx fake_pool_base
= gen_rtx_REG (Pmode
, ARG_POINTER_REGNUM
);
2055 /* Decompose address into base + index + displacement. */
2057 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == UNSPEC
)
2060 else if (GET_CODE (addr
) == PLUS
)
2062 rtx op0
= XEXP (addr
, 0);
2063 rtx op1
= XEXP (addr
, 1);
2064 enum rtx_code code0
= GET_CODE (op0
);
2065 enum rtx_code code1
= GET_CODE (op1
);
2067 if (code0
== REG
|| code0
== UNSPEC
)
2069 if (code1
== REG
|| code1
== UNSPEC
)
2071 indx
= op0
; /* index + base */
2077 base
= op0
; /* base + displacement */
2082 else if (code0
== PLUS
)
2084 indx
= XEXP (op0
, 0); /* index + base + disp */
2085 base
= XEXP (op0
, 1);
2096 disp
= addr
; /* displacement */
2098 /* Extract integer part of displacement. */
2102 if (GET_CODE (disp
) == CONST_INT
)
2104 offset
= INTVAL (disp
);
2107 else if (GET_CODE (disp
) == CONST
2108 && GET_CODE (XEXP (disp
, 0)) == PLUS
2109 && GET_CODE (XEXP (XEXP (disp
, 0), 1)) == CONST_INT
)
2111 offset
= INTVAL (XEXP (XEXP (disp
, 0), 1));
2112 disp
= XEXP (XEXP (disp
, 0), 0);
2116 /* Strip off CONST here to avoid special case tests later. */
2117 if (disp
&& GET_CODE (disp
) == CONST
)
2118 disp
= XEXP (disp
, 0);
2120 /* We can convert literal pool addresses to
2121 displacements by basing them off the base register. */
2122 if (disp
&& GET_CODE (disp
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (disp
))
2124 /* Either base or index must be free to hold the base register. */
2126 base
= fake_pool_base
, literal_pool
= true;
2128 indx
= fake_pool_base
, literal_pool
= true;
2132 /* Mark up the displacement. */
2133 disp
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, disp
),
2134 UNSPEC_LTREL_OFFSET
);
2137 /* Validate base register. */
2140 if (GET_CODE (base
) == UNSPEC
)
2141 switch (XINT (base
, 1))
2145 disp
= gen_rtx_UNSPEC (Pmode
,
2146 gen_rtvec (1, XVECEXP (base
, 0, 0)),
2147 UNSPEC_LTREL_OFFSET
);
2151 base
= XVECEXP (base
, 0, 1);
2154 case UNSPEC_LTREL_BASE
:
2155 if (XVECLEN (base
, 0) == 1)
2156 base
= fake_pool_base
, literal_pool
= true;
2158 base
= XVECEXP (base
, 0, 1);
2166 || (GET_MODE (base
) != SImode
2167 && GET_MODE (base
) != Pmode
))
2170 if (REGNO (base
) == STACK_POINTER_REGNUM
2171 || REGNO (base
) == FRAME_POINTER_REGNUM
2172 || ((reload_completed
|| reload_in_progress
)
2173 && frame_pointer_needed
2174 && REGNO (base
) == HARD_FRAME_POINTER_REGNUM
)
2175 || REGNO (base
) == ARG_POINTER_REGNUM
2177 && REGNO (base
) == PIC_OFFSET_TABLE_REGNUM
))
2178 pointer
= base_ptr
= true;
2180 if ((reload_completed
|| reload_in_progress
)
2181 && base
== cfun
->machine
->base_reg
)
2182 pointer
= base_ptr
= literal_pool
= true;
2185 /* Validate index register. */
2188 if (GET_CODE (indx
) == UNSPEC
)
2189 switch (XINT (indx
, 1))
2193 disp
= gen_rtx_UNSPEC (Pmode
,
2194 gen_rtvec (1, XVECEXP (indx
, 0, 0)),
2195 UNSPEC_LTREL_OFFSET
);
2199 indx
= XVECEXP (indx
, 0, 1);
2202 case UNSPEC_LTREL_BASE
:
2203 if (XVECLEN (indx
, 0) == 1)
2204 indx
= fake_pool_base
, literal_pool
= true;
2206 indx
= XVECEXP (indx
, 0, 1);
2214 || (GET_MODE (indx
) != SImode
2215 && GET_MODE (indx
) != Pmode
))
2218 if (REGNO (indx
) == STACK_POINTER_REGNUM
2219 || REGNO (indx
) == FRAME_POINTER_REGNUM
2220 || ((reload_completed
|| reload_in_progress
)
2221 && frame_pointer_needed
2222 && REGNO (indx
) == HARD_FRAME_POINTER_REGNUM
)
2223 || REGNO (indx
) == ARG_POINTER_REGNUM
2225 && REGNO (indx
) == PIC_OFFSET_TABLE_REGNUM
))
2226 pointer
= indx_ptr
= true;
2228 if ((reload_completed
|| reload_in_progress
)
2229 && indx
== cfun
->machine
->base_reg
)
2230 pointer
= indx_ptr
= literal_pool
= true;
2233 /* Prefer to use pointer as base, not index. */
2234 if (base
&& indx
&& !base_ptr
2235 && (indx_ptr
|| (!REG_POINTER (base
) && REG_POINTER (indx
))))
2242 /* Validate displacement. */
2245 /* If virtual registers are involved, the displacement will change later
2246 anyway as the virtual registers get eliminated. This could make a
2247 valid displacement invalid, but it is more likely to make an invalid
2248 displacement valid, because we sometimes access the register save area
2249 via negative offsets to one of those registers.
2250 Thus we don't check the displacement for validity here. If after
2251 elimination the displacement turns out to be invalid after all,
2252 this is fixed up by reload in any case. */
2253 /* LRA maintains always displacements up to date and we need to
2254 know the displacement is right during all LRA not only at the
2255 final elimination. */
2257 || (base
!= arg_pointer_rtx
2258 && indx
!= arg_pointer_rtx
2259 && base
!= return_address_pointer_rtx
2260 && indx
!= return_address_pointer_rtx
2261 && base
!= frame_pointer_rtx
2262 && indx
!= frame_pointer_rtx
2263 && base
!= virtual_stack_vars_rtx
2264 && indx
!= virtual_stack_vars_rtx
))
2265 if (!DISP_IN_RANGE (offset
))
2270 /* All the special cases are pointers. */
2273 /* In the small-PIC case, the linker converts @GOT
2274 and @GOTNTPOFF offsets to possible displacements. */
2275 if (GET_CODE (disp
) == UNSPEC
2276 && (XINT (disp
, 1) == UNSPEC_GOT
2277 || XINT (disp
, 1) == UNSPEC_GOTNTPOFF
)
2283 /* Accept pool label offsets. */
2284 else if (GET_CODE (disp
) == UNSPEC
2285 && XINT (disp
, 1) == UNSPEC_POOL_OFFSET
)
2288 /* Accept literal pool references. */
2289 else if (GET_CODE (disp
) == UNSPEC
2290 && XINT (disp
, 1) == UNSPEC_LTREL_OFFSET
)
2292 /* In case CSE pulled a non literal pool reference out of
2293 the pool we have to reject the address. This is
2294 especially important when loading the GOT pointer on non
2295 zarch CPUs. In this case the literal pool contains an lt
2296 relative offset to the _GLOBAL_OFFSET_TABLE_ label which
2297 will most likely exceed the displacement. */
2298 if (GET_CODE (XVECEXP (disp
, 0, 0)) != SYMBOL_REF
2299 || !CONSTANT_POOL_ADDRESS_P (XVECEXP (disp
, 0, 0)))
2302 orig_disp
= gen_rtx_CONST (Pmode
, disp
);
2305 /* If we have an offset, make sure it does not
2306 exceed the size of the constant pool entry. */
2307 rtx sym
= XVECEXP (disp
, 0, 0);
2308 if (offset
>= GET_MODE_SIZE (get_pool_mode (sym
)))
2311 orig_disp
= plus_constant (Pmode
, orig_disp
, offset
);
2326 out
->disp
= orig_disp
;
2327 out
->pointer
= pointer
;
2328 out
->literal_pool
= literal_pool
;
2334 /* Decompose a RTL expression OP for a shift count into its components,
2335 and return the base register in BASE and the offset in OFFSET.
2337 Return true if OP is a valid shift count, false if not. */
2340 s390_decompose_shift_count (rtx op
, rtx
*base
, HOST_WIDE_INT
*offset
)
2342 HOST_WIDE_INT off
= 0;
2344 /* We can have an integer constant, an address register,
2345 or a sum of the two. */
2346 if (GET_CODE (op
) == CONST_INT
)
2351 if (op
&& GET_CODE (op
) == PLUS
&& GET_CODE (XEXP (op
, 1)) == CONST_INT
)
2353 off
= INTVAL (XEXP (op
, 1));
2356 while (op
&& GET_CODE (op
) == SUBREG
)
2357 op
= SUBREG_REG (op
);
2359 if (op
&& GET_CODE (op
) != REG
)
2371 /* Return true if CODE is a valid address without index. */
2374 s390_legitimate_address_without_index_p (rtx op
)
2376 struct s390_address addr
;
2378 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
2387 /* Return TRUE if ADDR is an operand valid for a load/store relative
2388 instruction. Be aware that the alignment of the operand needs to
2389 be checked separately.
2390 Valid addresses are single references or a sum of a reference and a
2391 constant integer. Return these parts in SYMREF and ADDEND. You can
2392 pass NULL in REF and/or ADDEND if you are not interested in these
2393 values. Literal pool references are *not* considered symbol
2397 s390_loadrelative_operand_p (rtx addr
, rtx
*symref
, HOST_WIDE_INT
*addend
)
2399 HOST_WIDE_INT tmpaddend
= 0;
2401 if (GET_CODE (addr
) == CONST
)
2402 addr
= XEXP (addr
, 0);
2404 if (GET_CODE (addr
) == PLUS
)
2406 if (!CONST_INT_P (XEXP (addr
, 1)))
2409 tmpaddend
= INTVAL (XEXP (addr
, 1));
2410 addr
= XEXP (addr
, 0);
2413 if ((GET_CODE (addr
) == SYMBOL_REF
&& !CONSTANT_POOL_ADDRESS_P (addr
))
2414 || (GET_CODE (addr
) == UNSPEC
2415 && (XINT (addr
, 1) == UNSPEC_GOTENT
2416 || (TARGET_CPU_ZARCH
&& XINT (addr
, 1) == UNSPEC_PLT
))))
2421 *addend
= tmpaddend
;
2428 /* Return true if the address in OP is valid for constraint letter C
2429 if wrapped in a MEM rtx. Set LIT_POOL_OK to true if it literal
2430 pool MEMs should be accepted. Only the Q, R, S, T constraint
2431 letters are allowed for C. */
2434 s390_check_qrst_address (char c
, rtx op
, bool lit_pool_ok
)
2436 struct s390_address addr
;
2437 bool decomposed
= false;
2439 /* This check makes sure that no symbolic address (except literal
2440 pool references) are accepted by the R or T constraints. */
2441 if (s390_loadrelative_operand_p (op
, NULL
, NULL
))
2444 /* Ensure literal pool references are only accepted if LIT_POOL_OK. */
2447 if (!s390_decompose_address (op
, &addr
))
2449 if (addr
.literal_pool
)
2456 case 'Q': /* no index short displacement */
2457 if (!decomposed
&& !s390_decompose_address (op
, &addr
))
2461 if (!s390_short_displacement (addr
.disp
))
2465 case 'R': /* with index short displacement */
2466 if (TARGET_LONG_DISPLACEMENT
)
2468 if (!decomposed
&& !s390_decompose_address (op
, &addr
))
2470 if (!s390_short_displacement (addr
.disp
))
2473 /* Any invalid address here will be fixed up by reload,
2474 so accept it for the most generic constraint. */
2477 case 'S': /* no index long displacement */
2478 if (!TARGET_LONG_DISPLACEMENT
)
2480 if (!decomposed
&& !s390_decompose_address (op
, &addr
))
2484 if (s390_short_displacement (addr
.disp
))
2488 case 'T': /* with index long displacement */
2489 if (!TARGET_LONG_DISPLACEMENT
)
2491 /* Any invalid address here will be fixed up by reload,
2492 so accept it for the most generic constraint. */
2493 if ((decomposed
|| s390_decompose_address (op
, &addr
))
2494 && s390_short_displacement (addr
.disp
))
2504 /* Evaluates constraint strings described by the regular expression
2505 ([A|B|Z](Q|R|S|T))|U|W|Y and returns 1 if OP is a valid operand for
2506 the constraint given in STR, or 0 else. */
2509 s390_mem_constraint (const char *str
, rtx op
)
2516 /* Check for offsettable variants of memory constraints. */
2517 if (!MEM_P (op
) || MEM_VOLATILE_P (op
))
2519 if ((reload_completed
|| reload_in_progress
)
2520 ? !offsettable_memref_p (op
) : !offsettable_nonstrict_memref_p (op
))
2522 return s390_check_qrst_address (str
[1], XEXP (op
, 0), true);
2524 /* Check for non-literal-pool variants of memory constraints. */
2527 return s390_check_qrst_address (str
[1], XEXP (op
, 0), false);
2532 if (GET_CODE (op
) != MEM
)
2534 return s390_check_qrst_address (c
, XEXP (op
, 0), true);
2536 return (s390_check_qrst_address ('Q', op
, true)
2537 || s390_check_qrst_address ('R', op
, true));
2539 return (s390_check_qrst_address ('S', op
, true)
2540 || s390_check_qrst_address ('T', op
, true));
2542 /* Simply check for the basic form of a shift count. Reload will
2543 take care of making sure we have a proper base register. */
2544 if (!s390_decompose_shift_count (op
, NULL
, NULL
))
2548 return s390_check_qrst_address (str
[1], op
, true);
2556 /* Evaluates constraint strings starting with letter O. Input
2557 parameter C is the second letter following the "O" in the constraint
2558 string. Returns 1 if VALUE meets the respective constraint and 0
2562 s390_O_constraint_str (const char c
, HOST_WIDE_INT value
)
2570 return trunc_int_for_mode (value
, SImode
) == value
;
2574 || s390_single_part (GEN_INT (value
), DImode
, SImode
, 0) == 1;
2577 return s390_single_part (GEN_INT (value
- 1), DImode
, SImode
, -1) == 1;
2585 /* Evaluates constraint strings starting with letter N. Parameter STR
2586 contains the letters following letter "N" in the constraint string.
2587 Returns true if VALUE matches the constraint. */
2590 s390_N_constraint_str (const char *str
, HOST_WIDE_INT value
)
2592 machine_mode mode
, part_mode
;
2594 int part
, part_goal
;
2600 part_goal
= str
[0] - '0';
2644 if (GET_MODE_SIZE (mode
) <= GET_MODE_SIZE (part_mode
))
2647 part
= s390_single_part (GEN_INT (value
), mode
, part_mode
, def
);
2650 if (part_goal
!= -1 && part_goal
!= part
)
2657 /* Returns true if the input parameter VALUE is a float zero. */
2660 s390_float_const_zero_p (rtx value
)
2662 return (GET_MODE_CLASS (GET_MODE (value
)) == MODE_FLOAT
2663 && value
== CONST0_RTX (GET_MODE (value
)));
2666 /* Implement TARGET_REGISTER_MOVE_COST. */
2669 s390_register_move_cost (machine_mode mode
,
2670 reg_class_t from
, reg_class_t to
)
2672 /* On s390, copy between fprs and gprs is expensive. */
2674 /* It becomes somewhat faster having ldgr/lgdr. */
2675 if (TARGET_Z10
&& GET_MODE_SIZE (mode
) == 8)
2677 /* ldgr is single cycle. */
2678 if (reg_classes_intersect_p (from
, GENERAL_REGS
)
2679 && reg_classes_intersect_p (to
, FP_REGS
))
2681 /* lgdr needs 3 cycles. */
2682 if (reg_classes_intersect_p (to
, GENERAL_REGS
)
2683 && reg_classes_intersect_p (from
, FP_REGS
))
2687 /* Otherwise copying is done via memory. */
2688 if ((reg_classes_intersect_p (from
, GENERAL_REGS
)
2689 && reg_classes_intersect_p (to
, FP_REGS
))
2690 || (reg_classes_intersect_p (from
, FP_REGS
)
2691 && reg_classes_intersect_p (to
, GENERAL_REGS
)))
2697 /* Implement TARGET_MEMORY_MOVE_COST. */
2700 s390_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
2701 reg_class_t rclass ATTRIBUTE_UNUSED
,
2702 bool in ATTRIBUTE_UNUSED
)
2707 /* Compute a (partial) cost for rtx X. Return true if the complete
2708 cost has been computed, and false if subexpressions should be
2709 scanned. In either case, *TOTAL contains the cost result.
2710 CODE contains GET_CODE (x), OUTER_CODE contains the code
2711 of the superexpression of x. */
2714 s390_rtx_costs (rtx x
, int code
, int outer_code
, int opno ATTRIBUTE_UNUSED
,
2715 int *total
, bool speed ATTRIBUTE_UNUSED
)
2738 *total
= COSTS_N_INSNS (1);
2743 *total
= COSTS_N_INSNS (1);
2747 switch (GET_MODE (x
))
2751 rtx left
= XEXP (x
, 0);
2752 rtx right
= XEXP (x
, 1);
2753 if (GET_CODE (right
) == CONST_INT
2754 && CONST_OK_FOR_K (INTVAL (right
)))
2755 *total
= s390_cost
->mhi
;
2756 else if (GET_CODE (left
) == SIGN_EXTEND
)
2757 *total
= s390_cost
->mh
;
2759 *total
= s390_cost
->ms
; /* msr, ms, msy */
2764 rtx left
= XEXP (x
, 0);
2765 rtx right
= XEXP (x
, 1);
2768 if (GET_CODE (right
) == CONST_INT
2769 && CONST_OK_FOR_K (INTVAL (right
)))
2770 *total
= s390_cost
->mghi
;
2771 else if (GET_CODE (left
) == SIGN_EXTEND
)
2772 *total
= s390_cost
->msgf
;
2774 *total
= s390_cost
->msg
; /* msgr, msg */
2776 else /* TARGET_31BIT */
2778 if (GET_CODE (left
) == SIGN_EXTEND
2779 && GET_CODE (right
) == SIGN_EXTEND
)
2780 /* mulsidi case: mr, m */
2781 *total
= s390_cost
->m
;
2782 else if (GET_CODE (left
) == ZERO_EXTEND
2783 && GET_CODE (right
) == ZERO_EXTEND
2784 && TARGET_CPU_ZARCH
)
2785 /* umulsidi case: ml, mlr */
2786 *total
= s390_cost
->ml
;
2788 /* Complex calculation is required. */
2789 *total
= COSTS_N_INSNS (40);
2795 *total
= s390_cost
->mult_df
;
2798 *total
= s390_cost
->mxbr
;
2806 switch (GET_MODE (x
))
2809 *total
= s390_cost
->madbr
;
2812 *total
= s390_cost
->maebr
;
2817 /* Negate in the third argument is free: FMSUB. */
2818 if (GET_CODE (XEXP (x
, 2)) == NEG
)
2820 *total
+= (rtx_cost (XEXP (x
, 0), FMA
, 0, speed
)
2821 + rtx_cost (XEXP (x
, 1), FMA
, 1, speed
)
2822 + rtx_cost (XEXP (XEXP (x
, 2), 0), FMA
, 2, speed
));
2829 if (GET_MODE (x
) == TImode
) /* 128 bit division */
2830 *total
= s390_cost
->dlgr
;
2831 else if (GET_MODE (x
) == DImode
)
2833 rtx right
= XEXP (x
, 1);
2834 if (GET_CODE (right
) == ZERO_EXTEND
) /* 64 by 32 bit division */
2835 *total
= s390_cost
->dlr
;
2836 else /* 64 by 64 bit division */
2837 *total
= s390_cost
->dlgr
;
2839 else if (GET_MODE (x
) == SImode
) /* 32 bit division */
2840 *total
= s390_cost
->dlr
;
2845 if (GET_MODE (x
) == DImode
)
2847 rtx right
= XEXP (x
, 1);
2848 if (GET_CODE (right
) == ZERO_EXTEND
) /* 64 by 32 bit division */
2850 *total
= s390_cost
->dsgfr
;
2852 *total
= s390_cost
->dr
;
2853 else /* 64 by 64 bit division */
2854 *total
= s390_cost
->dsgr
;
2856 else if (GET_MODE (x
) == SImode
) /* 32 bit division */
2857 *total
= s390_cost
->dlr
;
2858 else if (GET_MODE (x
) == SFmode
)
2860 *total
= s390_cost
->debr
;
2862 else if (GET_MODE (x
) == DFmode
)
2864 *total
= s390_cost
->ddbr
;
2866 else if (GET_MODE (x
) == TFmode
)
2868 *total
= s390_cost
->dxbr
;
2873 if (GET_MODE (x
) == SFmode
)
2874 *total
= s390_cost
->sqebr
;
2875 else if (GET_MODE (x
) == DFmode
)
2876 *total
= s390_cost
->sqdbr
;
2878 *total
= s390_cost
->sqxbr
;
2883 if (outer_code
== MULT
|| outer_code
== DIV
|| outer_code
== MOD
2884 || outer_code
== PLUS
|| outer_code
== MINUS
2885 || outer_code
== COMPARE
)
2890 *total
= COSTS_N_INSNS (1);
2891 if (GET_CODE (XEXP (x
, 0)) == AND
2892 && GET_CODE (XEXP (x
, 1)) == CONST_INT
2893 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
)
2895 rtx op0
= XEXP (XEXP (x
, 0), 0);
2896 rtx op1
= XEXP (XEXP (x
, 0), 1);
2897 rtx op2
= XEXP (x
, 1);
2899 if (memory_operand (op0
, GET_MODE (op0
))
2900 && s390_tm_ccmode (op1
, op2
, 0) != VOIDmode
)
2902 if (register_operand (op0
, GET_MODE (op0
))
2903 && s390_tm_ccmode (op1
, op2
, 1) != VOIDmode
)
2913 /* Return the cost of an address rtx ADDR. */
2916 s390_address_cost (rtx addr
, machine_mode mode ATTRIBUTE_UNUSED
,
2917 addr_space_t as ATTRIBUTE_UNUSED
,
2918 bool speed ATTRIBUTE_UNUSED
)
2920 struct s390_address ad
;
2921 if (!s390_decompose_address (addr
, &ad
))
2924 return ad
.indx
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
2927 /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
2928 otherwise return 0. */
2931 tls_symbolic_operand (rtx op
)
2933 if (GET_CODE (op
) != SYMBOL_REF
)
2935 return SYMBOL_REF_TLS_MODEL (op
);
2938 /* Split DImode access register reference REG (on 64-bit) into its constituent
2939 low and high parts, and store them into LO and HI. Note that gen_lowpart/
2940 gen_highpart cannot be used as they assume all registers are word-sized,
2941 while our access registers have only half that size. */
2944 s390_split_access_reg (rtx reg
, rtx
*lo
, rtx
*hi
)
2946 gcc_assert (TARGET_64BIT
);
2947 gcc_assert (ACCESS_REG_P (reg
));
2948 gcc_assert (GET_MODE (reg
) == DImode
);
2949 gcc_assert (!(REGNO (reg
) & 1));
2951 *lo
= gen_rtx_REG (SImode
, REGNO (reg
) + 1);
2952 *hi
= gen_rtx_REG (SImode
, REGNO (reg
));
2955 /* Return true if OP contains a symbol reference */
2958 symbolic_reference_mentioned_p (rtx op
)
2963 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
2966 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
2967 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
2973 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
2974 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
2978 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
2985 /* Return true if OP contains a reference to a thread-local symbol. */
2988 tls_symbolic_reference_mentioned_p (rtx op
)
2993 if (GET_CODE (op
) == SYMBOL_REF
)
2994 return tls_symbolic_operand (op
);
2996 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
2997 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
3003 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
3004 if (tls_symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
3008 else if (fmt
[i
] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op
, i
)))
3016 /* Return true if OP is a legitimate general operand when
3017 generating PIC code. It is given that flag_pic is on
3018 and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
3021 legitimate_pic_operand_p (rtx op
)
3023 /* Accept all non-symbolic constants. */
3024 if (!SYMBOLIC_CONST (op
))
3027 /* Reject everything else; must be handled
3028 via emit_symbolic_move. */
3032 /* Returns true if the constant value OP is a legitimate general operand.
3033 It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
3036 s390_legitimate_constant_p (machine_mode mode
, rtx op
)
3038 if (VECTOR_MODE_P (mode
) && GET_CODE (op
) == CONST_VECTOR
)
3040 if (GET_MODE_SIZE (mode
) != 16)
3043 if (!const0_operand (op
, mode
)
3044 && !s390_contiguous_bitmask_vector_p (op
, NULL
, NULL
)
3045 && !s390_bytemask_vector_p (op
, NULL
))
3049 /* Accept all non-symbolic constants. */
3050 if (!SYMBOLIC_CONST (op
))
3053 /* Accept immediate LARL operands. */
3054 if (TARGET_CPU_ZARCH
&& larl_operand (op
, mode
))
3057 /* Thread-local symbols are never legal constants. This is
3058 so that emit_call knows that computing such addresses
3059 might require a function call. */
3060 if (TLS_SYMBOLIC_CONST (op
))
3063 /* In the PIC case, symbolic constants must *not* be
3064 forced into the literal pool. We accept them here,
3065 so that they will be handled by emit_symbolic_move. */
3069 /* All remaining non-PIC symbolic constants are
3070 forced into the literal pool. */
3074 /* Determine if it's legal to put X into the constant pool. This
3075 is not possible if X contains the address of a symbol that is
3076 not constant (TLS) or not known at final link time (PIC). */
3079 s390_cannot_force_const_mem (machine_mode mode
, rtx x
)
3081 switch (GET_CODE (x
))
3086 /* Accept all non-symbolic constants. */
3090 /* Labels are OK iff we are non-PIC. */
3091 return flag_pic
!= 0;
3094 /* 'Naked' TLS symbol references are never OK,
3095 non-TLS symbols are OK iff we are non-PIC. */
3096 if (tls_symbolic_operand (x
))
3099 return flag_pic
!= 0;
3102 return s390_cannot_force_const_mem (mode
, XEXP (x
, 0));
3105 return s390_cannot_force_const_mem (mode
, XEXP (x
, 0))
3106 || s390_cannot_force_const_mem (mode
, XEXP (x
, 1));
3109 switch (XINT (x
, 1))
3111 /* Only lt-relative or GOT-relative UNSPECs are OK. */
3112 case UNSPEC_LTREL_OFFSET
:
3120 case UNSPEC_GOTNTPOFF
:
3121 case UNSPEC_INDNTPOFF
:
3124 /* If the literal pool shares the code section, be put
3125 execute template placeholders into the pool as well. */
3127 return TARGET_CPU_ZARCH
;
3139 /* Returns true if the constant value OP is a legitimate general
3140 operand during and after reload. The difference to
3141 legitimate_constant_p is that this function will not accept
3142 a constant that would need to be forced to the literal pool
3143 before it can be used as operand.
3144 This function accepts all constants which can be loaded directly
3148 legitimate_reload_constant_p (rtx op
)
3150 /* Accept la(y) operands. */
3151 if (GET_CODE (op
) == CONST_INT
3152 && DISP_IN_RANGE (INTVAL (op
)))
3155 /* Accept l(g)hi/l(g)fi operands. */
3156 if (GET_CODE (op
) == CONST_INT
3157 && (CONST_OK_FOR_K (INTVAL (op
)) || CONST_OK_FOR_Os (INTVAL (op
))))
3160 /* Accept lliXX operands. */
3162 && GET_CODE (op
) == CONST_INT
3163 && trunc_int_for_mode (INTVAL (op
), word_mode
) == INTVAL (op
)
3164 && s390_single_part (op
, word_mode
, HImode
, 0) >= 0)
3168 && GET_CODE (op
) == CONST_INT
3169 && trunc_int_for_mode (INTVAL (op
), word_mode
) == INTVAL (op
)
3170 && s390_single_part (op
, word_mode
, SImode
, 0) >= 0)
3173 /* Accept larl operands. */
3174 if (TARGET_CPU_ZARCH
3175 && larl_operand (op
, VOIDmode
))
3178 /* Accept floating-point zero operands that fit into a single GPR. */
3179 if (GET_CODE (op
) == CONST_DOUBLE
3180 && s390_float_const_zero_p (op
)
3181 && GET_MODE_SIZE (GET_MODE (op
)) <= UNITS_PER_WORD
)
3184 /* Accept double-word operands that can be split. */
3185 if (GET_CODE (op
) == CONST_INT
3186 && trunc_int_for_mode (INTVAL (op
), word_mode
) != INTVAL (op
))
3188 machine_mode dword_mode
= word_mode
== SImode
? DImode
: TImode
;
3189 rtx hi
= operand_subword (op
, 0, 0, dword_mode
);
3190 rtx lo
= operand_subword (op
, 1, 0, dword_mode
);
3191 return legitimate_reload_constant_p (hi
)
3192 && legitimate_reload_constant_p (lo
);
3195 /* Everything else cannot be handled without reload. */
3199 /* Returns true if the constant value OP is a legitimate fp operand
3200 during and after reload.
3201 This function accepts all constants which can be loaded directly
3205 legitimate_reload_fp_constant_p (rtx op
)
3207 /* Accept floating-point zero operands if the load zero instruction
3208 can be used. Prior to z196 the load fp zero instruction caused a
3209 performance penalty if the result is used as BFP number. */
3211 && GET_CODE (op
) == CONST_DOUBLE
3212 && s390_float_const_zero_p (op
))
3218 /* Returns true if the constant value OP is a legitimate vector operand
3219 during and after reload.
3220 This function accepts all constants which can be loaded directly
3224 legitimate_reload_vector_constant_p (rtx op
)
3226 /* FIXME: Support constant vectors with all the same 16 bit unsigned
3227 operands. These can be loaded with vrepi. */
3229 if (TARGET_VX
&& GET_MODE_SIZE (GET_MODE (op
)) == 16
3230 && (const0_operand (op
, GET_MODE (op
))
3231 || constm1_operand (op
, GET_MODE (op
))
3232 || s390_contiguous_bitmask_vector_p (op
, NULL
, NULL
)
3233 || s390_bytemask_vector_p (op
, NULL
)))
3239 /* Given an rtx OP being reloaded into a reg required to be in class RCLASS,
3240 return the class of reg to actually use. */
3243 s390_preferred_reload_class (rtx op
, reg_class_t rclass
)
3245 switch (GET_CODE (op
))
3247 /* Constants we cannot reload into general registers
3248 must be forced into the literal pool. */
3252 if (reg_class_subset_p (GENERAL_REGS
, rclass
)
3253 && legitimate_reload_constant_p (op
))
3254 return GENERAL_REGS
;
3255 else if (reg_class_subset_p (ADDR_REGS
, rclass
)
3256 && legitimate_reload_constant_p (op
))
3258 else if (reg_class_subset_p (FP_REGS
, rclass
)
3259 && legitimate_reload_fp_constant_p (op
))
3261 else if (reg_class_subset_p (VEC_REGS
, rclass
)
3262 && legitimate_reload_vector_constant_p (op
))
3267 /* If a symbolic constant or a PLUS is reloaded,
3268 it is most likely being used as an address, so
3269 prefer ADDR_REGS. If 'class' is not a superset
3270 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
3272 /* Symrefs cannot be pushed into the literal pool with -fPIC
3273 so we *MUST NOT* return NO_REGS for these cases
3274 (s390_cannot_force_const_mem will return true).
3276 On the other hand we MUST return NO_REGS for symrefs with
3277 invalid addend which might have been pushed to the literal
3278 pool (no -fPIC). Usually we would expect them to be
3279 handled via secondary reload but this does not happen if
3280 they are used as literal pool slot replacement in reload
3281 inheritance (see emit_input_reload_insns). */
3282 if (TARGET_CPU_ZARCH
3283 && GET_CODE (XEXP (op
, 0)) == PLUS
3284 && GET_CODE (XEXP (XEXP(op
, 0), 0)) == SYMBOL_REF
3285 && GET_CODE (XEXP (XEXP(op
, 0), 1)) == CONST_INT
)
3287 if (flag_pic
&& reg_class_subset_p (ADDR_REGS
, rclass
))
3295 if (!legitimate_reload_constant_p (op
))
3299 /* load address will be used. */
3300 if (reg_class_subset_p (ADDR_REGS
, rclass
))
3312 /* Return true if ADDR is SYMBOL_REF + addend with addend being a
3313 multiple of ALIGNMENT and the SYMBOL_REF being naturally
3317 s390_check_symref_alignment (rtx addr
, HOST_WIDE_INT alignment
)
3319 HOST_WIDE_INT addend
;
3322 if (!s390_loadrelative_operand_p (addr
, &symref
, &addend
))
3325 if (addend
& (alignment
- 1))
3328 if (GET_CODE (symref
) == SYMBOL_REF
3329 && !SYMBOL_REF_NOT_NATURALLY_ALIGNED_P (symref
))
3332 if (GET_CODE (symref
) == UNSPEC
3333 && alignment
<= UNITS_PER_LONG
)
3339 /* ADDR is moved into REG using larl. If ADDR isn't a valid larl
3340 operand SCRATCH is used to reload the even part of the address and
3344 s390_reload_larl_operand (rtx reg
, rtx addr
, rtx scratch
)
3346 HOST_WIDE_INT addend
;
3349 if (!s390_loadrelative_operand_p (addr
, &symref
, &addend
))
3353 /* Easy case. The addend is even so larl will do fine. */
3354 emit_move_insn (reg
, addr
);
3357 /* We can leave the scratch register untouched if the target
3358 register is a valid base register. */
3359 if (REGNO (reg
) < FIRST_PSEUDO_REGISTER
3360 && REGNO_REG_CLASS (REGNO (reg
)) == ADDR_REGS
)
3363 gcc_assert (REGNO (scratch
) < FIRST_PSEUDO_REGISTER
);
3364 gcc_assert (REGNO_REG_CLASS (REGNO (scratch
)) == ADDR_REGS
);
3367 emit_move_insn (scratch
,
3368 gen_rtx_CONST (Pmode
,
3369 gen_rtx_PLUS (Pmode
, symref
,
3370 GEN_INT (addend
- 1))));
3372 emit_move_insn (scratch
, symref
);
3374 /* Increment the address using la in order to avoid clobbering cc. */
3375 s390_load_address (reg
, gen_rtx_PLUS (Pmode
, scratch
, const1_rtx
));
3379 /* Generate what is necessary to move between REG and MEM using
3380 SCRATCH. The direction is given by TOMEM. */
3383 s390_reload_symref_address (rtx reg
, rtx mem
, rtx scratch
, bool tomem
)
3385 /* Reload might have pulled a constant out of the literal pool.
3386 Force it back in. */
3387 if (CONST_INT_P (mem
) || GET_CODE (mem
) == CONST_DOUBLE
3388 || GET_CODE (mem
) == CONST_VECTOR
3389 || GET_CODE (mem
) == CONST
)
3390 mem
= force_const_mem (GET_MODE (reg
), mem
);
3392 gcc_assert (MEM_P (mem
));
3394 /* For a load from memory we can leave the scratch register
3395 untouched if the target register is a valid base register. */
3397 && REGNO (reg
) < FIRST_PSEUDO_REGISTER
3398 && REGNO_REG_CLASS (REGNO (reg
)) == ADDR_REGS
3399 && GET_MODE (reg
) == GET_MODE (scratch
))
3402 /* Load address into scratch register. Since we can't have a
3403 secondary reload for a secondary reload we have to cover the case
3404 where larl would need a secondary reload here as well. */
3405 s390_reload_larl_operand (scratch
, XEXP (mem
, 0), scratch
);
3407 /* Now we can use a standard load/store to do the move. */
3409 emit_move_insn (replace_equiv_address (mem
, scratch
), reg
);
3411 emit_move_insn (reg
, replace_equiv_address (mem
, scratch
));
3414 /* Inform reload about cases where moving X with a mode MODE to a register in
3415 RCLASS requires an extra scratch or immediate register. Return the class
3416 needed for the immediate register. */
3419 s390_secondary_reload (bool in_p
, rtx x
, reg_class_t rclass_i
,
3420 machine_mode mode
, secondary_reload_info
*sri
)
3422 enum reg_class rclass
= (enum reg_class
) rclass_i
;
3424 /* Intermediate register needed. */
3425 if (reg_classes_intersect_p (CC_REGS
, rclass
))
3426 return GENERAL_REGS
;
3430 /* The vst/vl vector move instructions allow only for short
3433 && GET_CODE (XEXP (x
, 0)) == PLUS
3434 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
3435 && !SHORT_DISP_IN_RANGE(INTVAL (XEXP (XEXP (x
, 0), 1)))
3436 && reg_class_subset_p (rclass
, VEC_REGS
)
3437 && (!reg_class_subset_p (rclass
, FP_REGS
)
3438 || (GET_MODE_SIZE (mode
) > 8
3439 && s390_class_max_nregs (FP_REGS
, mode
) == 1)))
3442 sri
->icode
= (TARGET_64BIT
?
3443 CODE_FOR_reloaddi_la_in
:
3444 CODE_FOR_reloadsi_la_in
);
3446 sri
->icode
= (TARGET_64BIT
?
3447 CODE_FOR_reloaddi_la_out
:
3448 CODE_FOR_reloadsi_la_out
);
3454 HOST_WIDE_INT offset
;
3457 /* On z10 several optimizer steps may generate larl operands with
3460 && s390_loadrelative_operand_p (x
, &symref
, &offset
)
3462 && !SYMBOL_REF_ALIGN1_P (symref
)
3463 && (offset
& 1) == 1)
3464 sri
->icode
= ((mode
== DImode
) ? CODE_FOR_reloaddi_larl_odd_addend_z10
3465 : CODE_FOR_reloadsi_larl_odd_addend_z10
);
3467 /* Handle all the (mem (symref)) accesses we cannot use the z10
3468 instructions for. */
3470 && s390_loadrelative_operand_p (XEXP (x
, 0), NULL
, NULL
)
3472 || !reg_classes_intersect_p (GENERAL_REGS
, rclass
)
3473 || GET_MODE_SIZE (mode
) > UNITS_PER_WORD
3474 || !s390_check_symref_alignment (XEXP (x
, 0),
3475 GET_MODE_SIZE (mode
))))
3477 #define __SECONDARY_RELOAD_CASE(M,m) \
3480 sri->icode = in_p ? CODE_FOR_reload##m##di_toreg_z10 : \
3481 CODE_FOR_reload##m##di_tomem_z10; \
3483 sri->icode = in_p ? CODE_FOR_reload##m##si_toreg_z10 : \
3484 CODE_FOR_reload##m##si_tomem_z10; \
3487 switch (GET_MODE (x
))
3489 __SECONDARY_RELOAD_CASE (QI
, qi
);
3490 __SECONDARY_RELOAD_CASE (HI
, hi
);
3491 __SECONDARY_RELOAD_CASE (SI
, si
);
3492 __SECONDARY_RELOAD_CASE (DI
, di
);
3493 __SECONDARY_RELOAD_CASE (TI
, ti
);
3494 __SECONDARY_RELOAD_CASE (SF
, sf
);
3495 __SECONDARY_RELOAD_CASE (DF
, df
);
3496 __SECONDARY_RELOAD_CASE (TF
, tf
);
3497 __SECONDARY_RELOAD_CASE (SD
, sd
);
3498 __SECONDARY_RELOAD_CASE (DD
, dd
);
3499 __SECONDARY_RELOAD_CASE (TD
, td
);
3500 __SECONDARY_RELOAD_CASE (V1QI
, v1qi
);
3501 __SECONDARY_RELOAD_CASE (V2QI
, v2qi
);
3502 __SECONDARY_RELOAD_CASE (V4QI
, v4qi
);
3503 __SECONDARY_RELOAD_CASE (V8QI
, v8qi
);
3504 __SECONDARY_RELOAD_CASE (V16QI
, v16qi
);
3505 __SECONDARY_RELOAD_CASE (V1HI
, v1hi
);
3506 __SECONDARY_RELOAD_CASE (V2HI
, v2hi
);
3507 __SECONDARY_RELOAD_CASE (V4HI
, v4hi
);
3508 __SECONDARY_RELOAD_CASE (V8HI
, v8hi
);
3509 __SECONDARY_RELOAD_CASE (V1SI
, v1si
);
3510 __SECONDARY_RELOAD_CASE (V2SI
, v2si
);
3511 __SECONDARY_RELOAD_CASE (V4SI
, v4si
);
3512 __SECONDARY_RELOAD_CASE (V1DI
, v1di
);
3513 __SECONDARY_RELOAD_CASE (V2DI
, v2di
);
3514 __SECONDARY_RELOAD_CASE (V1TI
, v1ti
);
3515 __SECONDARY_RELOAD_CASE (V1SF
, v1sf
);
3516 __SECONDARY_RELOAD_CASE (V2SF
, v2sf
);
3517 __SECONDARY_RELOAD_CASE (V4SF
, v4sf
);
3518 __SECONDARY_RELOAD_CASE (V1DF
, v1df
);
3519 __SECONDARY_RELOAD_CASE (V2DF
, v2df
);
3520 __SECONDARY_RELOAD_CASE (V1TF
, v1tf
);
3524 #undef __SECONDARY_RELOAD_CASE
3528 /* We need a scratch register when loading a PLUS expression which
3529 is not a legitimate operand of the LOAD ADDRESS instruction. */
3530 /* LRA can deal with transformation of plus op very well -- so we
3531 don't need to prompt LRA in this case. */
3532 if (! lra_in_progress
&& in_p
&& s390_plus_operand (x
, mode
))
3533 sri
->icode
= (TARGET_64BIT
?
3534 CODE_FOR_reloaddi_plus
: CODE_FOR_reloadsi_plus
);
3536 /* Performing a multiword move from or to memory we have to make sure the
3537 second chunk in memory is addressable without causing a displacement
3538 overflow. If that would be the case we calculate the address in
3539 a scratch register. */
3541 && GET_CODE (XEXP (x
, 0)) == PLUS
3542 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
3543 && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (x
, 0), 1))
3544 + GET_MODE_SIZE (mode
) - 1))
3546 /* For GENERAL_REGS a displacement overflow is no problem if occurring
3547 in a s_operand address since we may fallback to lm/stm. So we only
3548 have to care about overflows in the b+i+d case. */
3549 if ((reg_classes_intersect_p (GENERAL_REGS
, rclass
)
3550 && s390_class_max_nregs (GENERAL_REGS
, mode
) > 1
3551 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == PLUS
)
3552 /* For FP_REGS no lm/stm is available so this check is triggered
3553 for displacement overflows in b+i+d and b+d like addresses. */
3554 || (reg_classes_intersect_p (FP_REGS
, rclass
)
3555 && s390_class_max_nregs (FP_REGS
, mode
) > 1))
3558 sri
->icode
= (TARGET_64BIT
?
3559 CODE_FOR_reloaddi_la_in
:
3560 CODE_FOR_reloadsi_la_in
);
3562 sri
->icode
= (TARGET_64BIT
?
3563 CODE_FOR_reloaddi_la_out
:
3564 CODE_FOR_reloadsi_la_out
);
3568 /* A scratch address register is needed when a symbolic constant is
3569 copied to r0 compiling with -fPIC. In other cases the target
3570 register might be used as temporary (see legitimize_pic_address). */
3571 if (in_p
&& SYMBOLIC_CONST (x
) && flag_pic
== 2 && rclass
!= ADDR_REGS
)
3572 sri
->icode
= (TARGET_64BIT
?
3573 CODE_FOR_reloaddi_PIC_addr
:
3574 CODE_FOR_reloadsi_PIC_addr
);
3576 /* Either scratch or no register needed. */
3580 /* Generate code to load SRC, which is PLUS that is not a
3581 legitimate operand for the LA instruction, into TARGET.
3582 SCRATCH may be used as scratch register. */
3585 s390_expand_plus_operand (rtx target
, rtx src
,
3589 struct s390_address ad
;
3591 /* src must be a PLUS; get its two operands. */
3592 gcc_assert (GET_CODE (src
) == PLUS
);
3593 gcc_assert (GET_MODE (src
) == Pmode
);
3595 /* Check if any of the two operands is already scheduled
3596 for replacement by reload. This can happen e.g. when
3597 float registers occur in an address. */
3598 sum1
= find_replacement (&XEXP (src
, 0));
3599 sum2
= find_replacement (&XEXP (src
, 1));
3600 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
3602 /* If the address is already strictly valid, there's nothing to do. */
3603 if (!s390_decompose_address (src
, &ad
)
3604 || (ad
.base
&& !REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)))
3605 || (ad
.indx
&& !REGNO_OK_FOR_INDEX_P (REGNO (ad
.indx
))))
3607 /* Otherwise, one of the operands cannot be an address register;
3608 we reload its value into the scratch register. */
3609 if (true_regnum (sum1
) < 1 || true_regnum (sum1
) > 15)
3611 emit_move_insn (scratch
, sum1
);
3614 if (true_regnum (sum2
) < 1 || true_regnum (sum2
) > 15)
3616 emit_move_insn (scratch
, sum2
);
3620 /* According to the way these invalid addresses are generated
3621 in reload.c, it should never happen (at least on s390) that
3622 *neither* of the PLUS components, after find_replacements
3623 was applied, is an address register. */
3624 if (sum1
== scratch
&& sum2
== scratch
)
3630 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
3633 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
3634 is only ever performed on addresses, so we can mark the
3635 sum as legitimate for LA in any case. */
3636 s390_load_address (target
, src
);
3640 /* Return true if ADDR is a valid memory address.
3641 STRICT specifies whether strict register checking applies. */
3644 s390_legitimate_address_p (machine_mode mode
, rtx addr
, bool strict
)
3646 struct s390_address ad
;
3649 && larl_operand (addr
, VOIDmode
)
3650 && (mode
== VOIDmode
3651 || s390_check_symref_alignment (addr
, GET_MODE_SIZE (mode
))))
3654 if (!s390_decompose_address (addr
, &ad
))
3659 if (ad
.base
&& !REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)))
3662 if (ad
.indx
&& !REGNO_OK_FOR_INDEX_P (REGNO (ad
.indx
)))
3668 && !(REGNO (ad
.base
) >= FIRST_PSEUDO_REGISTER
3669 || REGNO_REG_CLASS (REGNO (ad
.base
)) == ADDR_REGS
))
3673 && !(REGNO (ad
.indx
) >= FIRST_PSEUDO_REGISTER
3674 || REGNO_REG_CLASS (REGNO (ad
.indx
)) == ADDR_REGS
))
3680 /* Return true if OP is a valid operand for the LA instruction.
3681 In 31-bit, we need to prove that the result is used as an
3682 address, as LA performs only a 31-bit addition. */
3685 legitimate_la_operand_p (rtx op
)
3687 struct s390_address addr
;
3688 if (!s390_decompose_address (op
, &addr
))
3691 return (TARGET_64BIT
|| addr
.pointer
);
3694 /* Return true if it is valid *and* preferable to use LA to
3695 compute the sum of OP1 and OP2. */
3698 preferred_la_operand_p (rtx op1
, rtx op2
)
3700 struct s390_address addr
;
3702 if (op2
!= const0_rtx
)
3703 op1
= gen_rtx_PLUS (Pmode
, op1
, op2
);
3705 if (!s390_decompose_address (op1
, &addr
))
3707 if (addr
.base
&& !REGNO_OK_FOR_BASE_P (REGNO (addr
.base
)))
3709 if (addr
.indx
&& !REGNO_OK_FOR_INDEX_P (REGNO (addr
.indx
)))
3712 /* Avoid LA instructions with index register on z196; it is
3713 preferable to use regular add instructions when possible.
3714 Starting with zEC12 the la with index register is "uncracked"
3716 if (addr
.indx
&& s390_tune
== PROCESSOR_2817_Z196
)
3719 if (!TARGET_64BIT
&& !addr
.pointer
)
3725 if ((addr
.base
&& REG_P (addr
.base
) && REG_POINTER (addr
.base
))
3726 || (addr
.indx
&& REG_P (addr
.indx
) && REG_POINTER (addr
.indx
)))
3732 /* Emit a forced load-address operation to load SRC into DST.
3733 This will use the LOAD ADDRESS instruction even in situations
3734 where legitimate_la_operand_p (SRC) returns false. */
3737 s390_load_address (rtx dst
, rtx src
)
3740 emit_move_insn (dst
, src
);
3742 emit_insn (gen_force_la_31 (dst
, src
));
3745 /* Return a legitimate reference for ORIG (an address) using the
3746 register REG. If REG is 0, a new pseudo is generated.
3748 There are two types of references that must be handled:
3750 1. Global data references must load the address from the GOT, via
3751 the PIC reg. An insn is emitted to do this load, and the reg is
3754 2. Static data references, constant pool addresses, and code labels
3755 compute the address as an offset from the GOT, whose base is in
3756 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
3757 differentiate them from global data objects. The returned
3758 address is the PIC reg + an unspec constant.
3760 TARGET_LEGITIMIZE_ADDRESS_P rejects symbolic references unless the PIC
3761 reg also appears in the address. */
3764 legitimize_pic_address (rtx orig
, rtx reg
)
3767 rtx addend
= const0_rtx
;
3770 gcc_assert (!TLS_SYMBOLIC_CONST (addr
));
3772 if (GET_CODE (addr
) == CONST
)
3773 addr
= XEXP (addr
, 0);
3775 if (GET_CODE (addr
) == PLUS
)
3777 addend
= XEXP (addr
, 1);
3778 addr
= XEXP (addr
, 0);
3781 if ((GET_CODE (addr
) == LABEL_REF
3782 || (GET_CODE (addr
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (addr
))
3783 || (GET_CODE (addr
) == UNSPEC
&&
3784 (XINT (addr
, 1) == UNSPEC_GOTENT
3785 || (TARGET_CPU_ZARCH
&& XINT (addr
, 1) == UNSPEC_PLT
))))
3786 && GET_CODE (addend
) == CONST_INT
)
3788 /* This can be locally addressed. */
3790 /* larl_operand requires UNSPECs to be wrapped in a const rtx. */
3791 rtx const_addr
= (GET_CODE (addr
) == UNSPEC
?
3792 gen_rtx_CONST (Pmode
, addr
) : addr
);
3794 if (TARGET_CPU_ZARCH
3795 && larl_operand (const_addr
, VOIDmode
)
3796 && INTVAL (addend
) < (HOST_WIDE_INT
)1 << 31
3797 && INTVAL (addend
) >= -((HOST_WIDE_INT
)1 << 31))
3799 if (INTVAL (addend
) & 1)
3801 /* LARL can't handle odd offsets, so emit a pair of LARL
3803 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
3805 if (!DISP_IN_RANGE (INTVAL (addend
)))
3807 HOST_WIDE_INT even
= INTVAL (addend
) - 1;
3808 addr
= gen_rtx_PLUS (Pmode
, addr
, GEN_INT (even
));
3809 addr
= gen_rtx_CONST (Pmode
, addr
);
3810 addend
= const1_rtx
;
3813 emit_move_insn (temp
, addr
);
3814 new_rtx
= gen_rtx_PLUS (Pmode
, temp
, addend
);
3818 s390_load_address (reg
, new_rtx
);
3824 /* If the offset is even, we can just use LARL. This
3825 will happen automatically. */
3830 /* No larl - Access local symbols relative to the GOT. */
3832 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
3834 if (reload_in_progress
|| reload_completed
)
3835 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM
, true);
3837 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTOFF
);
3838 if (addend
!= const0_rtx
)
3839 addr
= gen_rtx_PLUS (Pmode
, addr
, addend
);
3840 addr
= gen_rtx_CONST (Pmode
, addr
);
3841 addr
= force_const_mem (Pmode
, addr
);
3842 emit_move_insn (temp
, addr
);
3844 new_rtx
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
3847 s390_load_address (reg
, new_rtx
);
3852 else if (GET_CODE (addr
) == SYMBOL_REF
&& addend
== const0_rtx
)
3854 /* A non-local symbol reference without addend.
3856 The symbol ref is wrapped into an UNSPEC to make sure the
3857 proper operand modifier (@GOT or @GOTENT) will be emitted.
3858 This will tell the linker to put the symbol into the GOT.
3860 Additionally the code dereferencing the GOT slot is emitted here.
3862 An addend to the symref needs to be added afterwards.
3863 legitimize_pic_address calls itself recursively to handle
3864 that case. So no need to do it here. */
3867 reg
= gen_reg_rtx (Pmode
);
3871 /* Use load relative if possible.
3872 lgrl <target>, sym@GOTENT */
3873 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTENT
);
3874 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
3875 new_rtx
= gen_const_mem (GET_MODE (reg
), new_rtx
);
3877 emit_move_insn (reg
, new_rtx
);
3880 else if (flag_pic
== 1)
3882 /* Assume GOT offset is a valid displacement operand (< 4k
3883 or < 512k with z990). This is handled the same way in
3884 both 31- and 64-bit code (@GOT).
3885 lg <target>, sym@GOT(r12) */
3887 if (reload_in_progress
|| reload_completed
)
3888 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM
, true);
3890 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
3891 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
3892 new_rtx
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new_rtx
);
3893 new_rtx
= gen_const_mem (Pmode
, new_rtx
);
3894 emit_move_insn (reg
, new_rtx
);
3897 else if (TARGET_CPU_ZARCH
)
3899 /* If the GOT offset might be >= 4k, we determine the position
3900 of the GOT entry via a PC-relative LARL (@GOTENT).
3901 larl temp, sym@GOTENT
3902 lg <target>, 0(temp) */
3904 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
3906 gcc_assert (REGNO (temp
) >= FIRST_PSEUDO_REGISTER
3907 || REGNO_REG_CLASS (REGNO (temp
)) == ADDR_REGS
);
3909 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTENT
);
3910 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
3911 emit_move_insn (temp
, new_rtx
);
3913 new_rtx
= gen_const_mem (Pmode
, temp
);
3914 emit_move_insn (reg
, new_rtx
);
3920 /* If the GOT offset might be >= 4k, we have to load it
3921 from the literal pool (@GOT).
3923 lg temp, lit-litbase(r13)
3924 lg <target>, 0(temp)
3925 lit: .long sym@GOT */
3927 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
3929 gcc_assert (REGNO (temp
) >= FIRST_PSEUDO_REGISTER
3930 || REGNO_REG_CLASS (REGNO (temp
)) == ADDR_REGS
);
3932 if (reload_in_progress
|| reload_completed
)
3933 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM
, true);
3935 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
3936 addr
= gen_rtx_CONST (Pmode
, addr
);
3937 addr
= force_const_mem (Pmode
, addr
);
3938 emit_move_insn (temp
, addr
);
3940 new_rtx
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
3941 new_rtx
= gen_const_mem (Pmode
, new_rtx
);
3942 emit_move_insn (reg
, new_rtx
);
3946 else if (GET_CODE (addr
) == UNSPEC
&& GET_CODE (addend
) == CONST_INT
)
3948 gcc_assert (XVECLEN (addr
, 0) == 1);
3949 switch (XINT (addr
, 1))
3951 /* These address symbols (or PLT slots) relative to the GOT
3952 (not GOT slots!). In general this will exceed the
3953 displacement range so these value belong into the literal
3957 new_rtx
= force_const_mem (Pmode
, orig
);
3960 /* For -fPIC the GOT size might exceed the displacement
3961 range so make sure the value is in the literal pool. */
3964 new_rtx
= force_const_mem (Pmode
, orig
);
3967 /* For @GOTENT larl is used. This is handled like local
3973 /* @PLT is OK as is on 64-bit, must be converted to
3974 GOT-relative @PLTOFF on 31-bit. */
3976 if (!TARGET_CPU_ZARCH
)
3978 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
3980 if (reload_in_progress
|| reload_completed
)
3981 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM
, true);
3983 addr
= XVECEXP (addr
, 0, 0);
3984 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
),
3986 if (addend
!= const0_rtx
)
3987 addr
= gen_rtx_PLUS (Pmode
, addr
, addend
);
3988 addr
= gen_rtx_CONST (Pmode
, addr
);
3989 addr
= force_const_mem (Pmode
, addr
);
3990 emit_move_insn (temp
, addr
);
3992 new_rtx
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
3995 s390_load_address (reg
, new_rtx
);
4000 /* On 64 bit larl can be used. This case is handled like
4001 local symbol refs. */
4005 /* Everything else cannot happen. */
4010 else if (addend
!= const0_rtx
)
4012 /* Otherwise, compute the sum. */
4014 rtx base
= legitimize_pic_address (addr
, reg
);
4015 new_rtx
= legitimize_pic_address (addend
,
4016 base
== reg
? NULL_RTX
: reg
);
4017 if (GET_CODE (new_rtx
) == CONST_INT
)
4018 new_rtx
= plus_constant (Pmode
, base
, INTVAL (new_rtx
));
4021 if (GET_CODE (new_rtx
) == PLUS
&& CONSTANT_P (XEXP (new_rtx
, 1)))
4023 base
= gen_rtx_PLUS (Pmode
, base
, XEXP (new_rtx
, 0));
4024 new_rtx
= XEXP (new_rtx
, 1);
4026 new_rtx
= gen_rtx_PLUS (Pmode
, base
, new_rtx
);
4029 if (GET_CODE (new_rtx
) == CONST
)
4030 new_rtx
= XEXP (new_rtx
, 0);
4031 new_rtx
= force_operand (new_rtx
, 0);
4037 /* Load the thread pointer into a register. */
4040 s390_get_thread_pointer (void)
4042 rtx tp
= gen_reg_rtx (Pmode
);
4044 emit_move_insn (tp
, gen_rtx_REG (Pmode
, TP_REGNUM
));
4045 mark_reg_pointer (tp
, BITS_PER_WORD
);
4050 /* Emit a tls call insn. The call target is the SYMBOL_REF stored
4051 in s390_tls_symbol which always refers to __tls_get_offset.
4052 The returned offset is written to RESULT_REG and an USE rtx is
4053 generated for TLS_CALL. */
4055 static GTY(()) rtx s390_tls_symbol
;
4058 s390_emit_tls_call_insn (rtx result_reg
, rtx tls_call
)
4063 emit_insn (s390_load_got ());
4065 if (!s390_tls_symbol
)
4066 s390_tls_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "__tls_get_offset");
4068 insn
= s390_emit_call (s390_tls_symbol
, tls_call
, result_reg
,
4069 gen_rtx_REG (Pmode
, RETURN_REGNUM
));
4071 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), result_reg
);
4072 RTL_CONST_CALL_P (insn
) = 1;
4075 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
4076 this (thread-local) address. REG may be used as temporary. */
4079 legitimize_tls_address (rtx addr
, rtx reg
)
4081 rtx new_rtx
, tls_call
, temp
, base
, r2
, insn
;
4083 if (GET_CODE (addr
) == SYMBOL_REF
)
4084 switch (tls_symbolic_operand (addr
))
4086 case TLS_MODEL_GLOBAL_DYNAMIC
:
4088 r2
= gen_rtx_REG (Pmode
, 2);
4089 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_TLSGD
);
4090 new_rtx
= gen_rtx_CONST (Pmode
, tls_call
);
4091 new_rtx
= force_const_mem (Pmode
, new_rtx
);
4092 emit_move_insn (r2
, new_rtx
);
4093 s390_emit_tls_call_insn (r2
, tls_call
);
4094 insn
= get_insns ();
4097 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
4098 temp
= gen_reg_rtx (Pmode
);
4099 emit_libcall_block (insn
, temp
, r2
, new_rtx
);
4101 new_rtx
= gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
4104 s390_load_address (reg
, new_rtx
);
4109 case TLS_MODEL_LOCAL_DYNAMIC
:
4111 r2
= gen_rtx_REG (Pmode
, 2);
4112 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM
);
4113 new_rtx
= gen_rtx_CONST (Pmode
, tls_call
);
4114 new_rtx
= force_const_mem (Pmode
, new_rtx
);
4115 emit_move_insn (r2
, new_rtx
);
4116 s390_emit_tls_call_insn (r2
, tls_call
);
4117 insn
= get_insns ();
4120 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM_NTPOFF
);
4121 temp
= gen_reg_rtx (Pmode
);
4122 emit_libcall_block (insn
, temp
, r2
, new_rtx
);
4124 new_rtx
= gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
4125 base
= gen_reg_rtx (Pmode
);
4126 s390_load_address (base
, new_rtx
);
4128 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_DTPOFF
);
4129 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
4130 new_rtx
= force_const_mem (Pmode
, new_rtx
);
4131 temp
= gen_reg_rtx (Pmode
);
4132 emit_move_insn (temp
, new_rtx
);
4134 new_rtx
= gen_rtx_PLUS (Pmode
, base
, temp
);
4137 s390_load_address (reg
, new_rtx
);
4142 case TLS_MODEL_INITIAL_EXEC
:
4145 /* Assume GOT offset < 4k. This is handled the same way
4146 in both 31- and 64-bit code. */
4148 if (reload_in_progress
|| reload_completed
)
4149 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM
, true);
4151 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
4152 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
4153 new_rtx
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new_rtx
);
4154 new_rtx
= gen_const_mem (Pmode
, new_rtx
);
4155 temp
= gen_reg_rtx (Pmode
);
4156 emit_move_insn (temp
, new_rtx
);
4158 else if (TARGET_CPU_ZARCH
)
4160 /* If the GOT offset might be >= 4k, we determine the position
4161 of the GOT entry via a PC-relative LARL. */
4163 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
4164 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
4165 temp
= gen_reg_rtx (Pmode
);
4166 emit_move_insn (temp
, new_rtx
);
4168 new_rtx
= gen_const_mem (Pmode
, temp
);
4169 temp
= gen_reg_rtx (Pmode
);
4170 emit_move_insn (temp
, new_rtx
);
4174 /* If the GOT offset might be >= 4k, we have to load it
4175 from the literal pool. */
4177 if (reload_in_progress
|| reload_completed
)
4178 df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM
, true);
4180 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
4181 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
4182 new_rtx
= force_const_mem (Pmode
, new_rtx
);
4183 temp
= gen_reg_rtx (Pmode
);
4184 emit_move_insn (temp
, new_rtx
);
4186 new_rtx
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
4187 new_rtx
= gen_const_mem (Pmode
, new_rtx
);
4189 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new_rtx
, addr
), UNSPEC_TLS_LOAD
);
4190 temp
= gen_reg_rtx (Pmode
);
4191 emit_insn (gen_rtx_SET (temp
, new_rtx
));
4195 /* In position-dependent code, load the absolute address of
4196 the GOT entry from the literal pool. */
4198 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
4199 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
4200 new_rtx
= force_const_mem (Pmode
, new_rtx
);
4201 temp
= gen_reg_rtx (Pmode
);
4202 emit_move_insn (temp
, new_rtx
);
4205 new_rtx
= gen_const_mem (Pmode
, new_rtx
);
4206 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new_rtx
, addr
), UNSPEC_TLS_LOAD
);
4207 temp
= gen_reg_rtx (Pmode
);
4208 emit_insn (gen_rtx_SET (temp
, new_rtx
));
4211 new_rtx
= gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
4214 s390_load_address (reg
, new_rtx
);
4219 case TLS_MODEL_LOCAL_EXEC
:
4220 new_rtx
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
4221 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
4222 new_rtx
= force_const_mem (Pmode
, new_rtx
);
4223 temp
= gen_reg_rtx (Pmode
);
4224 emit_move_insn (temp
, new_rtx
);
4226 new_rtx
= gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
4229 s390_load_address (reg
, new_rtx
);
4238 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == UNSPEC
)
4240 switch (XINT (XEXP (addr
, 0), 1))
4242 case UNSPEC_INDNTPOFF
:
4243 gcc_assert (TARGET_CPU_ZARCH
);
4252 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == PLUS
4253 && GET_CODE (XEXP (XEXP (addr
, 0), 1)) == CONST_INT
)
4255 new_rtx
= XEXP (XEXP (addr
, 0), 0);
4256 if (GET_CODE (new_rtx
) != SYMBOL_REF
)
4257 new_rtx
= gen_rtx_CONST (Pmode
, new_rtx
);
4259 new_rtx
= legitimize_tls_address (new_rtx
, reg
);
4260 new_rtx
= plus_constant (Pmode
, new_rtx
,
4261 INTVAL (XEXP (XEXP (addr
, 0), 1)));
4262 new_rtx
= force_operand (new_rtx
, 0);
4266 gcc_unreachable (); /* for now ... */
4271 /* Emit insns making the address in operands[1] valid for a standard
4272 move to operands[0]. operands[1] is replaced by an address which
4273 should be used instead of the former RTX to emit the move
4277 emit_symbolic_move (rtx
*operands
)
4279 rtx temp
= !can_create_pseudo_p () ? operands
[0] : gen_reg_rtx (Pmode
);
4281 if (GET_CODE (operands
[0]) == MEM
)
4282 operands
[1] = force_reg (Pmode
, operands
[1]);
4283 else if (TLS_SYMBOLIC_CONST (operands
[1]))
4284 operands
[1] = legitimize_tls_address (operands
[1], temp
);
4286 operands
[1] = legitimize_pic_address (operands
[1], temp
);
4289 /* Try machine-dependent ways of modifying an illegitimate address X
4290 to be legitimate. If we find one, return the new, valid address.
4292 OLDX is the address as it was before break_out_memory_refs was called.
4293 In some cases it is useful to look at this to decide what needs to be done.
4295 MODE is the mode of the operand pointed to by X.
4297 When -fpic is used, special handling is needed for symbolic references.
4298 See comments by legitimize_pic_address for details. */
4301 s390_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
4302 machine_mode mode ATTRIBUTE_UNUSED
)
4304 rtx constant_term
= const0_rtx
;
4306 if (TLS_SYMBOLIC_CONST (x
))
4308 x
= legitimize_tls_address (x
, 0);
4310 if (s390_legitimate_address_p (mode
, x
, FALSE
))
4313 else if (GET_CODE (x
) == PLUS
4314 && (TLS_SYMBOLIC_CONST (XEXP (x
, 0))
4315 || TLS_SYMBOLIC_CONST (XEXP (x
, 1))))
4321 if (SYMBOLIC_CONST (x
)
4322 || (GET_CODE (x
) == PLUS
4323 && (SYMBOLIC_CONST (XEXP (x
, 0))
4324 || SYMBOLIC_CONST (XEXP (x
, 1)))))
4325 x
= legitimize_pic_address (x
, 0);
4327 if (s390_legitimate_address_p (mode
, x
, FALSE
))
4331 x
= eliminate_constant_term (x
, &constant_term
);
4333 /* Optimize loading of large displacements by splitting them
4334 into the multiple of 4K and the rest; this allows the
4335 former to be CSE'd if possible.
4337 Don't do this if the displacement is added to a register
4338 pointing into the stack frame, as the offsets will
4339 change later anyway. */
4341 if (GET_CODE (constant_term
) == CONST_INT
4342 && !TARGET_LONG_DISPLACEMENT
4343 && !DISP_IN_RANGE (INTVAL (constant_term
))
4344 && !(REG_P (x
) && REGNO_PTR_FRAME_P (REGNO (x
))))
4346 HOST_WIDE_INT lower
= INTVAL (constant_term
) & 0xfff;
4347 HOST_WIDE_INT upper
= INTVAL (constant_term
) ^ lower
;
4349 rtx temp
= gen_reg_rtx (Pmode
);
4350 rtx val
= force_operand (GEN_INT (upper
), temp
);
4352 emit_move_insn (temp
, val
);
4354 x
= gen_rtx_PLUS (Pmode
, x
, temp
);
4355 constant_term
= GEN_INT (lower
);
4358 if (GET_CODE (x
) == PLUS
)
4360 if (GET_CODE (XEXP (x
, 0)) == REG
)
4362 rtx temp
= gen_reg_rtx (Pmode
);
4363 rtx val
= force_operand (XEXP (x
, 1), temp
);
4365 emit_move_insn (temp
, val
);
4367 x
= gen_rtx_PLUS (Pmode
, XEXP (x
, 0), temp
);
4370 else if (GET_CODE (XEXP (x
, 1)) == REG
)
4372 rtx temp
= gen_reg_rtx (Pmode
);
4373 rtx val
= force_operand (XEXP (x
, 0), temp
);
4375 emit_move_insn (temp
, val
);
4377 x
= gen_rtx_PLUS (Pmode
, temp
, XEXP (x
, 1));
4381 if (constant_term
!= const0_rtx
)
4382 x
= gen_rtx_PLUS (Pmode
, x
, constant_term
);
4387 /* Try a machine-dependent way of reloading an illegitimate address AD
4388 operand. If we find one, push the reload and return the new address.
4390 MODE is the mode of the enclosing MEM. OPNUM is the operand number
4391 and TYPE is the reload type of the current reload. */
4394 legitimize_reload_address (rtx ad
, machine_mode mode ATTRIBUTE_UNUSED
,
4395 int opnum
, int type
)
4397 if (!optimize
|| TARGET_LONG_DISPLACEMENT
)
4400 if (GET_CODE (ad
) == PLUS
)
4402 rtx tem
= simplify_binary_operation (PLUS
, Pmode
,
4403 XEXP (ad
, 0), XEXP (ad
, 1));
4408 if (GET_CODE (ad
) == PLUS
4409 && GET_CODE (XEXP (ad
, 0)) == REG
4410 && GET_CODE (XEXP (ad
, 1)) == CONST_INT
4411 && !DISP_IN_RANGE (INTVAL (XEXP (ad
, 1))))
4413 HOST_WIDE_INT lower
= INTVAL (XEXP (ad
, 1)) & 0xfff;
4414 HOST_WIDE_INT upper
= INTVAL (XEXP (ad
, 1)) ^ lower
;
4415 rtx cst
, tem
, new_rtx
;
4417 cst
= GEN_INT (upper
);
4418 if (!legitimate_reload_constant_p (cst
))
4419 cst
= force_const_mem (Pmode
, cst
);
4421 tem
= gen_rtx_PLUS (Pmode
, XEXP (ad
, 0), cst
);
4422 new_rtx
= gen_rtx_PLUS (Pmode
, tem
, GEN_INT (lower
));
4424 push_reload (XEXP (tem
, 1), 0, &XEXP (tem
, 1), 0,
4425 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
4426 opnum
, (enum reload_type
) type
);
4433 /* Emit code to move LEN bytes from DST to SRC. */
4436 s390_expand_movmem (rtx dst
, rtx src
, rtx len
)
4438 /* When tuning for z10 or higher we rely on the Glibc functions to
4439 do the right thing. Only for constant lengths below 64k we will
4440 generate inline code. */
4441 if (s390_tune
>= PROCESSOR_2097_Z10
4442 && (GET_CODE (len
) != CONST_INT
|| INTVAL (len
) > (1<<16)))
4445 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
4447 if (INTVAL (len
) > 0)
4448 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (INTVAL (len
) - 1)));
4451 else if (TARGET_MVCLE
)
4453 emit_insn (gen_movmem_long (dst
, src
, convert_to_mode (Pmode
, len
, 1)));
4458 rtx dst_addr
, src_addr
, count
, blocks
, temp
;
4459 rtx_code_label
*loop_start_label
= gen_label_rtx ();
4460 rtx_code_label
*loop_end_label
= gen_label_rtx ();
4461 rtx_code_label
*end_label
= gen_label_rtx ();
4464 mode
= GET_MODE (len
);
4465 if (mode
== VOIDmode
)
4468 dst_addr
= gen_reg_rtx (Pmode
);
4469 src_addr
= gen_reg_rtx (Pmode
);
4470 count
= gen_reg_rtx (mode
);
4471 blocks
= gen_reg_rtx (mode
);
4473 convert_move (count
, len
, 1);
4474 emit_cmp_and_jump_insns (count
, const0_rtx
,
4475 EQ
, NULL_RTX
, mode
, 1, end_label
);
4477 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
4478 emit_move_insn (src_addr
, force_operand (XEXP (src
, 0), NULL_RTX
));
4479 dst
= change_address (dst
, VOIDmode
, dst_addr
);
4480 src
= change_address (src
, VOIDmode
, src_addr
);
4482 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1,
4485 emit_move_insn (count
, temp
);
4487 temp
= expand_binop (mode
, lshr_optab
, count
, GEN_INT (8), blocks
, 1,
4490 emit_move_insn (blocks
, temp
);
4492 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
4493 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
4495 emit_label (loop_start_label
);
4498 && (GET_CODE (len
) != CONST_INT
|| INTVAL (len
) > 768))
4502 /* Issue a read prefetch for the +3 cache line. */
4503 prefetch
= gen_prefetch (gen_rtx_PLUS (Pmode
, src_addr
, GEN_INT (768)),
4504 const0_rtx
, const0_rtx
);
4505 PREFETCH_SCHEDULE_BARRIER_P (prefetch
) = true;
4506 emit_insn (prefetch
);
4508 /* Issue a write prefetch for the +3 cache line. */
4509 prefetch
= gen_prefetch (gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (768)),
4510 const1_rtx
, const0_rtx
);
4511 PREFETCH_SCHEDULE_BARRIER_P (prefetch
) = true;
4512 emit_insn (prefetch
);
4515 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (255)));
4516 s390_load_address (dst_addr
,
4517 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
4518 s390_load_address (src_addr
,
4519 gen_rtx_PLUS (Pmode
, src_addr
, GEN_INT (256)));
4521 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1,
4524 emit_move_insn (blocks
, temp
);
4526 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
4527 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
4529 emit_jump (loop_start_label
);
4530 emit_label (loop_end_label
);
4532 emit_insn (gen_movmem_short (dst
, src
,
4533 convert_to_mode (Pmode
, count
, 1)));
4534 emit_label (end_label
);
4539 /* Emit code to set LEN bytes at DST to VAL.
4540 Make use of clrmem if VAL is zero. */
4543 s390_expand_setmem (rtx dst
, rtx len
, rtx val
)
4545 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) == 0)
4548 gcc_assert (GET_CODE (val
) == CONST_INT
|| GET_MODE (val
) == QImode
);
4550 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) > 0 && INTVAL (len
) <= 257)
4552 if (val
== const0_rtx
&& INTVAL (len
) <= 256)
4553 emit_insn (gen_clrmem_short (dst
, GEN_INT (INTVAL (len
) - 1)));
4556 /* Initialize memory by storing the first byte. */
4557 emit_move_insn (adjust_address (dst
, QImode
, 0), val
);
4559 if (INTVAL (len
) > 1)
4561 /* Initiate 1 byte overlap move.
4562 The first byte of DST is propagated through DSTP1.
4563 Prepare a movmem for: DST+1 = DST (length = LEN - 1).
4564 DST is set to size 1 so the rest of the memory location
4565 does not count as source operand. */
4566 rtx dstp1
= adjust_address (dst
, VOIDmode
, 1);
4567 set_mem_size (dst
, 1);
4569 emit_insn (gen_movmem_short (dstp1
, dst
,
4570 GEN_INT (INTVAL (len
) - 2)));
4575 else if (TARGET_MVCLE
)
4577 val
= force_not_mem (convert_modes (Pmode
, QImode
, val
, 1));
4578 emit_insn (gen_setmem_long (dst
, convert_to_mode (Pmode
, len
, 1), val
));
4583 rtx dst_addr
, count
, blocks
, temp
, dstp1
= NULL_RTX
;
4584 rtx_code_label
*loop_start_label
= gen_label_rtx ();
4585 rtx_code_label
*loop_end_label
= gen_label_rtx ();
4586 rtx_code_label
*end_label
= gen_label_rtx ();
4589 mode
= GET_MODE (len
);
4590 if (mode
== VOIDmode
)
4593 dst_addr
= gen_reg_rtx (Pmode
);
4594 count
= gen_reg_rtx (mode
);
4595 blocks
= gen_reg_rtx (mode
);
4597 convert_move (count
, len
, 1);
4598 emit_cmp_and_jump_insns (count
, const0_rtx
,
4599 EQ
, NULL_RTX
, mode
, 1, end_label
);
4601 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
4602 dst
= change_address (dst
, VOIDmode
, dst_addr
);
4604 if (val
== const0_rtx
)
4605 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1,
4609 dstp1
= adjust_address (dst
, VOIDmode
, 1);
4610 set_mem_size (dst
, 1);
4612 /* Initialize memory by storing the first byte. */
4613 emit_move_insn (adjust_address (dst
, QImode
, 0), val
);
4615 /* If count is 1 we are done. */
4616 emit_cmp_and_jump_insns (count
, const1_rtx
,
4617 EQ
, NULL_RTX
, mode
, 1, end_label
);
4619 temp
= expand_binop (mode
, add_optab
, count
, GEN_INT (-2), count
, 1,
4623 emit_move_insn (count
, temp
);
4625 temp
= expand_binop (mode
, lshr_optab
, count
, GEN_INT (8), blocks
, 1,
4628 emit_move_insn (blocks
, temp
);
4630 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
4631 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
4633 emit_label (loop_start_label
);
4636 && (GET_CODE (len
) != CONST_INT
|| INTVAL (len
) > 1024))
4638 /* Issue a write prefetch for the +4 cache line. */
4639 rtx prefetch
= gen_prefetch (gen_rtx_PLUS (Pmode
, dst_addr
,
4641 const1_rtx
, const0_rtx
);
4642 emit_insn (prefetch
);
4643 PREFETCH_SCHEDULE_BARRIER_P (prefetch
) = true;
4646 if (val
== const0_rtx
)
4647 emit_insn (gen_clrmem_short (dst
, GEN_INT (255)));
4649 emit_insn (gen_movmem_short (dstp1
, dst
, GEN_INT (255)));
4650 s390_load_address (dst_addr
,
4651 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
4653 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1,
4656 emit_move_insn (blocks
, temp
);
4658 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
4659 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
4661 emit_jump (loop_start_label
);
4662 emit_label (loop_end_label
);
4664 if (val
== const0_rtx
)
4665 emit_insn (gen_clrmem_short (dst
, convert_to_mode (Pmode
, count
, 1)));
4667 emit_insn (gen_movmem_short (dstp1
, dst
, convert_to_mode (Pmode
, count
, 1)));
4668 emit_label (end_label
);
4672 /* Emit code to compare LEN bytes at OP0 with those at OP1,
4673 and return the result in TARGET. */
4676 s390_expand_cmpmem (rtx target
, rtx op0
, rtx op1
, rtx len
)
4678 rtx ccreg
= gen_rtx_REG (CCUmode
, CC_REGNUM
);
4681 /* When tuning for z10 or higher we rely on the Glibc functions to
4682 do the right thing. Only for constant lengths below 64k we will
4683 generate inline code. */
4684 if (s390_tune
>= PROCESSOR_2097_Z10
4685 && (GET_CODE (len
) != CONST_INT
|| INTVAL (len
) > (1<<16)))
4688 /* As the result of CMPINT is inverted compared to what we need,
4689 we have to swap the operands. */
4690 tmp
= op0
; op0
= op1
; op1
= tmp
;
4692 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
4694 if (INTVAL (len
) > 0)
4696 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (INTVAL (len
) - 1)));
4697 emit_insn (gen_cmpint (target
, ccreg
));
4700 emit_move_insn (target
, const0_rtx
);
4702 else if (TARGET_MVCLE
)
4704 emit_insn (gen_cmpmem_long (op0
, op1
, convert_to_mode (Pmode
, len
, 1)));
4705 emit_insn (gen_cmpint (target
, ccreg
));
4709 rtx addr0
, addr1
, count
, blocks
, temp
;
4710 rtx_code_label
*loop_start_label
= gen_label_rtx ();
4711 rtx_code_label
*loop_end_label
= gen_label_rtx ();
4712 rtx_code_label
*end_label
= gen_label_rtx ();
4715 mode
= GET_MODE (len
);
4716 if (mode
== VOIDmode
)
4719 addr0
= gen_reg_rtx (Pmode
);
4720 addr1
= gen_reg_rtx (Pmode
);
4721 count
= gen_reg_rtx (mode
);
4722 blocks
= gen_reg_rtx (mode
);
4724 convert_move (count
, len
, 1);
4725 emit_cmp_and_jump_insns (count
, const0_rtx
,
4726 EQ
, NULL_RTX
, mode
, 1, end_label
);
4728 emit_move_insn (addr0
, force_operand (XEXP (op0
, 0), NULL_RTX
));
4729 emit_move_insn (addr1
, force_operand (XEXP (op1
, 0), NULL_RTX
));
4730 op0
= change_address (op0
, VOIDmode
, addr0
);
4731 op1
= change_address (op1
, VOIDmode
, addr1
);
4733 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1,
4736 emit_move_insn (count
, temp
);
4738 temp
= expand_binop (mode
, lshr_optab
, count
, GEN_INT (8), blocks
, 1,
4741 emit_move_insn (blocks
, temp
);
4743 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
4744 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
4746 emit_label (loop_start_label
);
4749 && (GET_CODE (len
) != CONST_INT
|| INTVAL (len
) > 512))
4753 /* Issue a read prefetch for the +2 cache line of operand 1. */
4754 prefetch
= gen_prefetch (gen_rtx_PLUS (Pmode
, addr0
, GEN_INT (512)),
4755 const0_rtx
, const0_rtx
);
4756 emit_insn (prefetch
);
4757 PREFETCH_SCHEDULE_BARRIER_P (prefetch
) = true;
4759 /* Issue a read prefetch for the +2 cache line of operand 2. */
4760 prefetch
= gen_prefetch (gen_rtx_PLUS (Pmode
, addr1
, GEN_INT (512)),
4761 const0_rtx
, const0_rtx
);
4762 emit_insn (prefetch
);
4763 PREFETCH_SCHEDULE_BARRIER_P (prefetch
) = true;
4766 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (255)));
4767 temp
= gen_rtx_NE (VOIDmode
, ccreg
, const0_rtx
);
4768 temp
= gen_rtx_IF_THEN_ELSE (VOIDmode
, temp
,
4769 gen_rtx_LABEL_REF (VOIDmode
, end_label
), pc_rtx
);
4770 temp
= gen_rtx_SET (pc_rtx
, temp
);
4771 emit_jump_insn (temp
);
4773 s390_load_address (addr0
,
4774 gen_rtx_PLUS (Pmode
, addr0
, GEN_INT (256)));
4775 s390_load_address (addr1
,
4776 gen_rtx_PLUS (Pmode
, addr1
, GEN_INT (256)));
4778 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1,
4781 emit_move_insn (blocks
, temp
);
4783 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
4784 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
4786 emit_jump (loop_start_label
);
4787 emit_label (loop_end_label
);
4789 emit_insn (gen_cmpmem_short (op0
, op1
,
4790 convert_to_mode (Pmode
, count
, 1)));
4791 emit_label (end_label
);
4793 emit_insn (gen_cmpint (target
, ccreg
));
4798 /* Emit a conditional jump to LABEL for condition code mask MASK using
4799 comparsion operator COMPARISON. Return the emitted jump insn. */
4802 s390_emit_ccraw_jump (HOST_WIDE_INT mask
, enum rtx_code comparison
, rtx label
)
4806 gcc_assert (comparison
== EQ
|| comparison
== NE
);
4807 gcc_assert (mask
> 0 && mask
< 15);
4809 temp
= gen_rtx_fmt_ee (comparison
, VOIDmode
,
4810 gen_rtx_REG (CCRAWmode
, CC_REGNUM
), GEN_INT (mask
));
4811 temp
= gen_rtx_IF_THEN_ELSE (VOIDmode
, temp
,
4812 gen_rtx_LABEL_REF (VOIDmode
, label
), pc_rtx
);
4813 temp
= gen_rtx_SET (pc_rtx
, temp
);
4814 return emit_jump_insn (temp
);
4817 /* Emit the instructions to implement strlen of STRING and store the
4818 result in TARGET. The string has the known ALIGNMENT. This
4819 version uses vector instructions and is therefore not appropriate
4820 for targets prior to z13. */
4823 s390_expand_vec_strlen (rtx target
, rtx string
, rtx alignment
)
4825 int very_unlikely
= REG_BR_PROB_BASE
/ 100 - 1;
4826 int very_likely
= REG_BR_PROB_BASE
- 1;
4827 rtx highest_index_to_load_reg
= gen_reg_rtx (Pmode
);
4828 rtx str_reg
= gen_reg_rtx (V16QImode
);
4829 rtx str_addr_base_reg
= gen_reg_rtx (Pmode
);
4830 rtx str_idx_reg
= gen_reg_rtx (Pmode
);
4831 rtx result_reg
= gen_reg_rtx (V16QImode
);
4832 rtx is_aligned_label
= gen_label_rtx ();
4833 rtx into_loop_label
= NULL_RTX
;
4834 rtx loop_start_label
= gen_label_rtx ();
4836 rtx len
= gen_reg_rtx (QImode
);
4839 s390_load_address (str_addr_base_reg
, XEXP (string
, 0));
4840 emit_move_insn (str_idx_reg
, const0_rtx
);
4842 if (INTVAL (alignment
) < 16)
4844 /* Check whether the address happens to be aligned properly so
4845 jump directly to the aligned loop. */
4846 emit_cmp_and_jump_insns (gen_rtx_AND (Pmode
,
4847 str_addr_base_reg
, GEN_INT (15)),
4848 const0_rtx
, EQ
, NULL_RTX
,
4849 Pmode
, 1, is_aligned_label
);
4851 temp
= gen_reg_rtx (Pmode
);
4852 temp
= expand_binop (Pmode
, and_optab
, str_addr_base_reg
,
4853 GEN_INT (15), temp
, 1, OPTAB_DIRECT
);
4854 gcc_assert (REG_P (temp
));
4855 highest_index_to_load_reg
=
4856 expand_binop (Pmode
, sub_optab
, GEN_INT (15), temp
,
4857 highest_index_to_load_reg
, 1, OPTAB_DIRECT
);
4858 gcc_assert (REG_P (highest_index_to_load_reg
));
4859 emit_insn (gen_vllv16qi (str_reg
,
4860 convert_to_mode (SImode
, highest_index_to_load_reg
, 1),
4861 gen_rtx_MEM (BLKmode
, str_addr_base_reg
)));
4863 into_loop_label
= gen_label_rtx ();
4864 s390_emit_jump (into_loop_label
, NULL_RTX
);
4868 emit_label (is_aligned_label
);
4869 LABEL_NUSES (is_aligned_label
) = INTVAL (alignment
) < 16 ? 2 : 1;
4871 /* Reaching this point we are only performing 16 bytes aligned
4873 emit_move_insn (highest_index_to_load_reg
, GEN_INT (15));
4875 emit_label (loop_start_label
);
4876 LABEL_NUSES (loop_start_label
) = 1;
4878 /* Load 16 bytes of the string into VR. */
4879 emit_move_insn (str_reg
,
4880 gen_rtx_MEM (V16QImode
,
4881 gen_rtx_PLUS (Pmode
, str_idx_reg
,
4882 str_addr_base_reg
)));
4883 if (into_loop_label
!= NULL_RTX
)
4885 emit_label (into_loop_label
);
4886 LABEL_NUSES (into_loop_label
) = 1;
4889 /* Increment string index by 16 bytes. */
4890 expand_binop (Pmode
, add_optab
, str_idx_reg
, GEN_INT (16),
4891 str_idx_reg
, 1, OPTAB_DIRECT
);
4893 emit_insn (gen_vec_vfenesv16qi (result_reg
, str_reg
, str_reg
,
4894 GEN_INT (VSTRING_FLAG_ZS
| VSTRING_FLAG_CS
)));
4896 add_int_reg_note (s390_emit_ccraw_jump (8, NE
, loop_start_label
),
4897 REG_BR_PROB
, very_likely
);
4898 emit_insn (gen_vec_extractv16qi (len
, result_reg
, GEN_INT (7)));
4900 /* If the string pointer wasn't aligned we have loaded less then 16
4901 bytes and the remaining bytes got filled with zeros (by vll).
4902 Now we have to check whether the resulting index lies within the
4903 bytes actually part of the string. */
4905 cond
= s390_emit_compare (GT
, convert_to_mode (Pmode
, len
, 1),
4906 highest_index_to_load_reg
);
4907 s390_load_address (highest_index_to_load_reg
,
4908 gen_rtx_PLUS (Pmode
, highest_index_to_load_reg
,
4911 emit_insn (gen_movdicc (str_idx_reg
, cond
,
4912 highest_index_to_load_reg
, str_idx_reg
));
4914 emit_insn (gen_movsicc (str_idx_reg
, cond
,
4915 highest_index_to_load_reg
, str_idx_reg
));
4917 add_int_reg_note (s390_emit_jump (is_aligned_label
, cond
), REG_BR_PROB
,
4920 expand_binop (Pmode
, add_optab
, str_idx_reg
,
4921 GEN_INT (-16), str_idx_reg
, 1, OPTAB_DIRECT
);
4922 /* FIXME: len is already zero extended - so avoid the llgcr emitted
4924 temp
= expand_binop (Pmode
, add_optab
, str_idx_reg
,
4925 convert_to_mode (Pmode
, len
, 1),
4926 target
, 1, OPTAB_DIRECT
);
4928 emit_move_insn (target
, temp
);
4931 /* Expand conditional increment or decrement using alc/slb instructions.
4932 Should generate code setting DST to either SRC or SRC + INCREMENT,
4933 depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
4934 Returns true if successful, false otherwise.
4936 That makes it possible to implement some if-constructs without jumps e.g.:
4937 (borrow = CC0 | CC1 and carry = CC2 | CC3)
4938 unsigned int a, b, c;
4939 if (a < b) c++; -> CCU b > a -> CC2; c += carry;
4940 if (a < b) c--; -> CCL3 a - b -> borrow; c -= borrow;
4941 if (a <= b) c++; -> CCL3 b - a -> borrow; c += carry;
4942 if (a <= b) c--; -> CCU a <= b -> borrow; c -= borrow;
4944 Checks for EQ and NE with a nonzero value need an additional xor e.g.:
4945 if (a == b) c++; -> CCL3 a ^= b; 0 - a -> borrow; c += carry;
4946 if (a == b) c--; -> CCU a ^= b; a <= 0 -> CC0 | CC1; c -= borrow;
4947 if (a != b) c++; -> CCU a ^= b; a > 0 -> CC2; c += carry;
4948 if (a != b) c--; -> CCL3 a ^= b; 0 - a -> borrow; c -= borrow; */
4951 s390_expand_addcc (enum rtx_code cmp_code
, rtx cmp_op0
, rtx cmp_op1
,
4952 rtx dst
, rtx src
, rtx increment
)
4954 machine_mode cmp_mode
;
4955 machine_mode cc_mode
;
4961 if ((GET_MODE (cmp_op0
) == SImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
4962 && (GET_MODE (cmp_op1
) == SImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
4964 else if ((GET_MODE (cmp_op0
) == DImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
4965 && (GET_MODE (cmp_op1
) == DImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
4970 /* Try ADD LOGICAL WITH CARRY. */
4971 if (increment
== const1_rtx
)
4973 /* Determine CC mode to use. */
4974 if (cmp_code
== EQ
|| cmp_code
== NE
)
4976 if (cmp_op1
!= const0_rtx
)
4978 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
4979 NULL_RTX
, 0, OPTAB_WIDEN
);
4980 cmp_op1
= const0_rtx
;
4983 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
4986 if (cmp_code
== LTU
|| cmp_code
== LEU
)
4991 cmp_code
= swap_condition (cmp_code
);
5008 /* Emit comparison instruction pattern. */
5009 if (!register_operand (cmp_op0
, cmp_mode
))
5010 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
5012 insn
= gen_rtx_SET (gen_rtx_REG (cc_mode
, CC_REGNUM
),
5013 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
5014 /* We use insn_invalid_p here to add clobbers if required. */
5015 ret
= insn_invalid_p (emit_insn (insn
), false);
5018 /* Emit ALC instruction pattern. */
5019 op_res
= gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
5020 gen_rtx_REG (cc_mode
, CC_REGNUM
),
5023 if (src
!= const0_rtx
)
5025 if (!register_operand (src
, GET_MODE (dst
)))
5026 src
= force_reg (GET_MODE (dst
), src
);
5028 op_res
= gen_rtx_PLUS (GET_MODE (dst
), op_res
, src
);
5029 op_res
= gen_rtx_PLUS (GET_MODE (dst
), op_res
, const0_rtx
);
5032 p
= rtvec_alloc (2);
5034 gen_rtx_SET (dst
, op_res
);
5036 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
5037 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
5042 /* Try SUBTRACT LOGICAL WITH BORROW. */
5043 if (increment
== constm1_rtx
)
5045 /* Determine CC mode to use. */
5046 if (cmp_code
== EQ
|| cmp_code
== NE
)
5048 if (cmp_op1
!= const0_rtx
)
5050 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
5051 NULL_RTX
, 0, OPTAB_WIDEN
);
5052 cmp_op1
= const0_rtx
;
5055 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
5058 if (cmp_code
== GTU
|| cmp_code
== GEU
)
5063 cmp_code
= swap_condition (cmp_code
);
5080 /* Emit comparison instruction pattern. */
5081 if (!register_operand (cmp_op0
, cmp_mode
))
5082 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
5084 insn
= gen_rtx_SET (gen_rtx_REG (cc_mode
, CC_REGNUM
),
5085 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
5086 /* We use insn_invalid_p here to add clobbers if required. */
5087 ret
= insn_invalid_p (emit_insn (insn
), false);
5090 /* Emit SLB instruction pattern. */
5091 if (!register_operand (src
, GET_MODE (dst
)))
5092 src
= force_reg (GET_MODE (dst
), src
);
5094 op_res
= gen_rtx_MINUS (GET_MODE (dst
),
5095 gen_rtx_MINUS (GET_MODE (dst
), src
, const0_rtx
),
5096 gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
5097 gen_rtx_REG (cc_mode
, CC_REGNUM
),
5099 p
= rtvec_alloc (2);
5101 gen_rtx_SET (dst
, op_res
);
5103 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
5104 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
5112 /* Expand code for the insv template. Return true if successful. */
5115 s390_expand_insv (rtx dest
, rtx op1
, rtx op2
, rtx src
)
5117 int bitsize
= INTVAL (op1
);
5118 int bitpos
= INTVAL (op2
);
5119 machine_mode mode
= GET_MODE (dest
);
5121 int smode_bsize
, mode_bsize
;
5124 if (bitsize
+ bitpos
> GET_MODE_BITSIZE (mode
))
5127 /* Generate INSERT IMMEDIATE (IILL et al). */
5128 /* (set (ze (reg)) (const_int)). */
5130 && register_operand (dest
, word_mode
)
5131 && (bitpos
% 16) == 0
5132 && (bitsize
% 16) == 0
5133 && const_int_operand (src
, VOIDmode
))
5135 HOST_WIDE_INT val
= INTVAL (src
);
5136 int regpos
= bitpos
+ bitsize
;
5138 while (regpos
> bitpos
)
5140 machine_mode putmode
;
5143 if (TARGET_EXTIMM
&& (regpos
% 32 == 0) && (regpos
>= bitpos
+ 32))
5148 putsize
= GET_MODE_BITSIZE (putmode
);
5150 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode
, dest
,
5153 gen_int_mode (val
, putmode
));
5156 gcc_assert (regpos
== bitpos
);
5160 smode
= smallest_mode_for_size (bitsize
, MODE_INT
);
5161 smode_bsize
= GET_MODE_BITSIZE (smode
);
5162 mode_bsize
= GET_MODE_BITSIZE (mode
);
5164 /* Generate STORE CHARACTERS UNDER MASK (STCM et al). */
5166 && (bitsize
% BITS_PER_UNIT
) == 0
5168 && (register_operand (src
, word_mode
)
5169 || const_int_operand (src
, VOIDmode
)))
5171 /* Emit standard pattern if possible. */
5172 if (smode_bsize
== bitsize
)
5174 emit_move_insn (adjust_address (dest
, smode
, 0),
5175 gen_lowpart (smode
, src
));
5179 /* (set (ze (mem)) (const_int)). */
5180 else if (const_int_operand (src
, VOIDmode
))
5182 int size
= bitsize
/ BITS_PER_UNIT
;
5183 rtx src_mem
= adjust_address (force_const_mem (word_mode
, src
),
5185 UNITS_PER_WORD
- size
);
5187 dest
= adjust_address (dest
, BLKmode
, 0);
5188 set_mem_size (dest
, size
);
5189 s390_expand_movmem (dest
, src_mem
, GEN_INT (size
));
5193 /* (set (ze (mem)) (reg)). */
5194 else if (register_operand (src
, word_mode
))
5197 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode
, dest
, op1
,
5201 /* Emit st,stcmh sequence. */
5202 int stcmh_width
= bitsize
- 32;
5203 int size
= stcmh_width
/ BITS_PER_UNIT
;
5205 emit_move_insn (adjust_address (dest
, SImode
, size
),
5206 gen_lowpart (SImode
, src
));
5207 set_mem_size (dest
, size
);
5208 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode
, dest
,
5209 GEN_INT (stcmh_width
),
5211 gen_rtx_LSHIFTRT (word_mode
, src
, GEN_INT (32)));
5217 /* Generate INSERT CHARACTERS UNDER MASK (IC, ICM et al). */
5218 if ((bitpos
% BITS_PER_UNIT
) == 0
5219 && (bitsize
% BITS_PER_UNIT
) == 0
5220 && (bitpos
& 32) == ((bitpos
+ bitsize
- 1) & 32)
5222 && (mode
== DImode
|| mode
== SImode
)
5223 && register_operand (dest
, mode
))
5225 /* Emit a strict_low_part pattern if possible. */
5226 if (smode_bsize
== bitsize
&& bitpos
== mode_bsize
- smode_bsize
)
5228 op
= gen_rtx_STRICT_LOW_PART (VOIDmode
, gen_lowpart (smode
, dest
));
5229 op
= gen_rtx_SET (op
, gen_lowpart (smode
, src
));
5230 clobber
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
5231 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, op
, clobber
)));
5235 /* ??? There are more powerful versions of ICM that are not
5236 completely represented in the md file. */
5239 /* For z10, generate ROTATE THEN INSERT SELECTED BITS (RISBG et al). */
5240 if (TARGET_Z10
&& (mode
== DImode
|| mode
== SImode
))
5242 machine_mode mode_s
= GET_MODE (src
);
5244 if (mode_s
== VOIDmode
)
5246 /* Assume const_int etc already in the proper mode. */
5247 src
= force_reg (mode
, src
);
5249 else if (mode_s
!= mode
)
5251 gcc_assert (GET_MODE_BITSIZE (mode_s
) >= bitsize
);
5252 src
= force_reg (mode_s
, src
);
5253 src
= gen_lowpart (mode
, src
);
5256 op
= gen_rtx_ZERO_EXTRACT (mode
, dest
, op1
, op2
),
5257 op
= gen_rtx_SET (op
, src
);
5261 clobber
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
5262 op
= gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, op
, clobber
));
5272 /* A subroutine of s390_expand_cs_hqi and s390_expand_atomic which returns a
5273 register that holds VAL of mode MODE shifted by COUNT bits. */
5276 s390_expand_mask_and_shift (rtx val
, machine_mode mode
, rtx count
)
5278 val
= expand_simple_binop (SImode
, AND
, val
, GEN_INT (GET_MODE_MASK (mode
)),
5279 NULL_RTX
, 1, OPTAB_DIRECT
);
5280 return expand_simple_binop (SImode
, ASHIFT
, val
, count
,
5281 NULL_RTX
, 1, OPTAB_DIRECT
);
5284 /* Generate a vector comparison COND of CMP_OP1 and CMP_OP2 and store
5285 the result in TARGET. */
5288 s390_expand_vec_compare (rtx target
, enum rtx_code cond
,
5289 rtx cmp_op1
, rtx cmp_op2
)
5291 machine_mode mode
= GET_MODE (target
);
5292 bool neg_p
= false, swap_p
= false;
5295 if (GET_MODE (cmp_op1
) == V2DFmode
)
5299 /* NE a != b -> !(a == b) */
5300 case NE
: cond
= EQ
; neg_p
= true; break;
5301 /* UNGT a u> b -> !(b >= a) */
5302 case UNGT
: cond
= GE
; neg_p
= true; swap_p
= true; break;
5303 /* UNGE a u>= b -> !(b > a) */
5304 case UNGE
: cond
= GT
; neg_p
= true; swap_p
= true; break;
5305 /* LE: a <= b -> b >= a */
5306 case LE
: cond
= GE
; swap_p
= true; break;
5307 /* UNLE: a u<= b -> !(a > b) */
5308 case UNLE
: cond
= GT
; neg_p
= true; break;
5309 /* LT: a < b -> b > a */
5310 case LT
: cond
= GT
; swap_p
= true; break;
5311 /* UNLT: a u< b -> !(a >= b) */
5312 case UNLT
: cond
= GE
; neg_p
= true; break;
5314 emit_insn (gen_vec_cmpuneqv2df (target
, cmp_op1
, cmp_op2
));
5317 emit_insn (gen_vec_cmpltgtv2df (target
, cmp_op1
, cmp_op2
));
5320 emit_insn (gen_vec_orderedv2df (target
, cmp_op1
, cmp_op2
));
5323 emit_insn (gen_vec_unorderedv2df (target
, cmp_op1
, cmp_op2
));
5332 /* NE: a != b -> !(a == b) */
5333 case NE
: cond
= EQ
; neg_p
= true; break;
5334 /* GE: a >= b -> !(b > a) */
5335 case GE
: cond
= GT
; neg_p
= true; swap_p
= true; break;
5336 /* GEU: a >= b -> !(b > a) */
5337 case GEU
: cond
= GTU
; neg_p
= true; swap_p
= true; break;
5338 /* LE: a <= b -> !(a > b) */
5339 case LE
: cond
= GT
; neg_p
= true; break;
5340 /* LEU: a <= b -> !(a > b) */
5341 case LEU
: cond
= GTU
; neg_p
= true; break;
5342 /* LT: a < b -> b > a */
5343 case LT
: cond
= GT
; swap_p
= true; break;
5344 /* LTU: a < b -> b > a */
5345 case LTU
: cond
= GTU
; swap_p
= true; break;
5352 tmp
= cmp_op1
; cmp_op1
= cmp_op2
; cmp_op2
= tmp
;
5355 emit_insn (gen_rtx_SET (target
, gen_rtx_fmt_ee (cond
,
5357 cmp_op1
, cmp_op2
)));
5359 emit_insn (gen_rtx_SET (target
, gen_rtx_NOT (mode
, target
)));
5362 /* Generate a vector comparison expression loading either elements of
5363 THEN or ELS into TARGET depending on the comparison COND of CMP_OP1
5367 s390_expand_vcond (rtx target
, rtx then
, rtx els
,
5368 enum rtx_code cond
, rtx cmp_op1
, rtx cmp_op2
)
5371 machine_mode result_mode
;
5374 /* We always use an integral type vector to hold the comparison
5376 result_mode
= GET_MODE (cmp_op1
) == V2DFmode
? V2DImode
: GET_MODE (cmp_op1
);
5377 result_target
= gen_reg_rtx (result_mode
);
5379 /* Alternatively this could be done by reload by lowering the cmp*
5380 predicates. But it appears to be better for scheduling etc. to
5381 have that in early. */
5382 if (!REG_P (cmp_op1
))
5383 cmp_op1
= force_reg (GET_MODE (target
), cmp_op1
);
5385 if (!REG_P (cmp_op2
))
5386 cmp_op2
= force_reg (GET_MODE (target
), cmp_op2
);
5388 s390_expand_vec_compare (result_target
, cond
,
5391 /* If the results are supposed to be either -1 or 0 we are done
5392 since this is what our compare instructions generate anyway. */
5393 if (constm1_operand (then
, GET_MODE (then
))
5394 && const0_operand (els
, GET_MODE (els
)))
5396 emit_move_insn (target
, gen_rtx_SUBREG (GET_MODE (target
),
5401 /* Otherwise we will do a vsel afterwards. */
5402 /* This gets triggered e.g.
5403 with gcc.c-torture/compile/pr53410-1.c */
5405 then
= force_reg (GET_MODE (target
), then
);
5408 els
= force_reg (GET_MODE (target
), els
);
5410 tmp
= gen_rtx_fmt_ee (EQ
, VOIDmode
,
5412 CONST0_RTX (result_mode
));
5414 /* We compared the result against zero above so we have to swap then
5416 tmp
= gen_rtx_IF_THEN_ELSE (GET_MODE (target
), tmp
, els
, then
);
5418 gcc_assert (GET_MODE (target
) == GET_MODE (then
));
5419 emit_insn (gen_rtx_SET (target
, tmp
));
5422 /* Emit the RTX necessary to initialize the vector TARGET with values
5425 s390_expand_vec_init (rtx target
, rtx vals
)
5427 machine_mode mode
= GET_MODE (target
);
5428 machine_mode inner_mode
= GET_MODE_INNER (mode
);
5429 int n_elts
= GET_MODE_NUNITS (mode
);
5430 bool all_same
= true, all_regs
= true, all_const_int
= true;
5434 for (i
= 0; i
< n_elts
; ++i
)
5436 x
= XVECEXP (vals
, 0, i
);
5438 if (!CONST_INT_P (x
))
5439 all_const_int
= false;
5441 if (i
> 0 && !rtx_equal_p (x
, XVECEXP (vals
, 0, 0)))
5448 /* Use vector gen mask or vector gen byte mask if possible. */
5449 if (all_same
&& all_const_int
5450 && (XVECEXP (vals
, 0, 0) == const0_rtx
5451 || s390_contiguous_bitmask_vector_p (XVECEXP (vals
, 0, 0),
5453 || s390_bytemask_vector_p (XVECEXP (vals
, 0, 0), NULL
)))
5455 emit_insn (gen_rtx_SET (target
,
5456 gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0))));
5462 emit_insn (gen_rtx_SET (target
,
5463 gen_rtx_VEC_DUPLICATE (mode
,
5464 XVECEXP (vals
, 0, 0))));
5468 if (all_regs
&& REG_P (target
) && n_elts
== 2 && inner_mode
== DImode
)
5470 /* Use vector load pair. */
5471 emit_insn (gen_rtx_SET (target
,
5472 gen_rtx_VEC_CONCAT (mode
,
5473 XVECEXP (vals
, 0, 0),
5474 XVECEXP (vals
, 0, 1))));
5478 /* We are about to set the vector elements one by one. Zero out the
5479 full register first in order to help the data flow framework to
5480 detect it as full VR set. */
5481 emit_insn (gen_rtx_SET (target
, CONST0_RTX (mode
)));
5483 /* Unfortunately the vec_init expander is not allowed to fail. So
5484 we have to implement the fallback ourselves. */
5485 for (i
= 0; i
< n_elts
; i
++)
5486 emit_insn (gen_rtx_SET (target
,
5487 gen_rtx_UNSPEC (mode
,
5488 gen_rtvec (3, XVECEXP (vals
, 0, i
),
5489 GEN_INT (i
), target
),
5493 /* Structure to hold the initial parameters for a compare_and_swap operation
5494 in HImode and QImode. */
5496 struct alignment_context
5498 rtx memsi
; /* SI aligned memory location. */
5499 rtx shift
; /* Bit offset with regard to lsb. */
5500 rtx modemask
; /* Mask of the HQImode shifted by SHIFT bits. */
5501 rtx modemaski
; /* ~modemask */
5502 bool aligned
; /* True if memory is aligned, false else. */
5505 /* A subroutine of s390_expand_cs_hqi and s390_expand_atomic to initialize
5506 structure AC for transparent simplifying, if the memory alignment is known
5507 to be at least 32bit. MEM is the memory location for the actual operation
5508 and MODE its mode. */
5511 init_alignment_context (struct alignment_context
*ac
, rtx mem
,
5514 ac
->shift
= GEN_INT (GET_MODE_SIZE (SImode
) - GET_MODE_SIZE (mode
));
5515 ac
->aligned
= (MEM_ALIGN (mem
) >= GET_MODE_BITSIZE (SImode
));
5518 ac
->memsi
= adjust_address (mem
, SImode
, 0); /* Memory is aligned. */
5521 /* Alignment is unknown. */
5522 rtx byteoffset
, addr
, align
;
5524 /* Force the address into a register. */
5525 addr
= force_reg (Pmode
, XEXP (mem
, 0));
5527 /* Align it to SImode. */
5528 align
= expand_simple_binop (Pmode
, AND
, addr
,
5529 GEN_INT (-GET_MODE_SIZE (SImode
)),
5530 NULL_RTX
, 1, OPTAB_DIRECT
);
5532 ac
->memsi
= gen_rtx_MEM (SImode
, align
);
5533 MEM_VOLATILE_P (ac
->memsi
) = MEM_VOLATILE_P (mem
);
5534 set_mem_alias_set (ac
->memsi
, ALIAS_SET_MEMORY_BARRIER
);
5535 set_mem_align (ac
->memsi
, GET_MODE_BITSIZE (SImode
));
5537 /* Calculate shiftcount. */
5538 byteoffset
= expand_simple_binop (Pmode
, AND
, addr
,
5539 GEN_INT (GET_MODE_SIZE (SImode
) - 1),
5540 NULL_RTX
, 1, OPTAB_DIRECT
);
5541 /* As we already have some offset, evaluate the remaining distance. */
5542 ac
->shift
= expand_simple_binop (SImode
, MINUS
, ac
->shift
, byteoffset
,
5543 NULL_RTX
, 1, OPTAB_DIRECT
);
5546 /* Shift is the byte count, but we need the bitcount. */
5547 ac
->shift
= expand_simple_binop (SImode
, ASHIFT
, ac
->shift
, GEN_INT (3),
5548 NULL_RTX
, 1, OPTAB_DIRECT
);
5550 /* Calculate masks. */
5551 ac
->modemask
= expand_simple_binop (SImode
, ASHIFT
,
5552 GEN_INT (GET_MODE_MASK (mode
)),
5553 ac
->shift
, NULL_RTX
, 1, OPTAB_DIRECT
);
5554 ac
->modemaski
= expand_simple_unop (SImode
, NOT
, ac
->modemask
,
5558 /* A subroutine of s390_expand_cs_hqi. Insert INS into VAL. If possible,
5559 use a single insv insn into SEQ2. Otherwise, put prep insns in SEQ1 and
5560 perform the merge in SEQ2. */
5563 s390_two_part_insv (struct alignment_context
*ac
, rtx
*seq1
, rtx
*seq2
,
5564 machine_mode mode
, rtx val
, rtx ins
)
5571 tmp
= copy_to_mode_reg (SImode
, val
);
5572 if (s390_expand_insv (tmp
, GEN_INT (GET_MODE_BITSIZE (mode
)),
5576 *seq2
= get_insns ();
5583 /* Failed to use insv. Generate a two part shift and mask. */
5585 tmp
= s390_expand_mask_and_shift (ins
, mode
, ac
->shift
);
5586 *seq1
= get_insns ();
5590 tmp
= expand_simple_binop (SImode
, IOR
, tmp
, val
, NULL_RTX
, 1, OPTAB_DIRECT
);
5591 *seq2
= get_insns ();
5597 /* Expand an atomic compare and swap operation for HImode and QImode. MEM is
5598 the memory location, CMP the old value to compare MEM with and NEW_RTX the
5599 value to set if CMP == MEM. */
5602 s390_expand_cs_hqi (machine_mode mode
, rtx btarget
, rtx vtarget
, rtx mem
,
5603 rtx cmp
, rtx new_rtx
, bool is_weak
)
5605 struct alignment_context ac
;
5606 rtx cmpv
, newv
, val
, cc
, seq0
, seq1
, seq2
, seq3
;
5607 rtx res
= gen_reg_rtx (SImode
);
5608 rtx_code_label
*csloop
= NULL
, *csend
= NULL
;
5610 gcc_assert (MEM_P (mem
));
5612 init_alignment_context (&ac
, mem
, mode
);
5614 /* Load full word. Subsequent loads are performed by CS. */
5615 val
= expand_simple_binop (SImode
, AND
, ac
.memsi
, ac
.modemaski
,
5616 NULL_RTX
, 1, OPTAB_DIRECT
);
5618 /* Prepare insertions of cmp and new_rtx into the loaded value. When
5619 possible, we try to use insv to make this happen efficiently. If
5620 that fails we'll generate code both inside and outside the loop. */
5621 cmpv
= s390_two_part_insv (&ac
, &seq0
, &seq2
, mode
, val
, cmp
);
5622 newv
= s390_two_part_insv (&ac
, &seq1
, &seq3
, mode
, val
, new_rtx
);
5629 /* Start CS loop. */
5632 /* Begin assuming success. */
5633 emit_move_insn (btarget
, const1_rtx
);
5635 csloop
= gen_label_rtx ();
5636 csend
= gen_label_rtx ();
5637 emit_label (csloop
);
5640 /* val = "<mem>00..0<mem>"
5641 * cmp = "00..0<cmp>00..0"
5642 * new = "00..0<new>00..0"
5648 cc
= s390_emit_compare_and_swap (EQ
, res
, ac
.memsi
, cmpv
, newv
);
5650 emit_insn (gen_cstorecc4 (btarget
, cc
, XEXP (cc
, 0), XEXP (cc
, 1)));
5655 /* Jump to end if we're done (likely?). */
5656 s390_emit_jump (csend
, cc
);
5658 /* Check for changes outside mode, and loop internal if so.
5659 Arrange the moves so that the compare is adjacent to the
5660 branch so that we can generate CRJ. */
5661 tmp
= copy_to_reg (val
);
5662 force_expand_binop (SImode
, and_optab
, res
, ac
.modemaski
, val
,
5664 cc
= s390_emit_compare (NE
, val
, tmp
);
5665 s390_emit_jump (csloop
, cc
);
5668 emit_move_insn (btarget
, const0_rtx
);
5672 /* Return the correct part of the bitfield. */
5673 convert_move (vtarget
, expand_simple_binop (SImode
, LSHIFTRT
, res
, ac
.shift
,
5674 NULL_RTX
, 1, OPTAB_DIRECT
), 1);
5677 /* Expand an atomic operation CODE of mode MODE. MEM is the memory location
5678 and VAL the value to play with. If AFTER is true then store the value
5679 MEM holds after the operation, if AFTER is false then store the value MEM
5680 holds before the operation. If TARGET is zero then discard that value, else
5681 store it to TARGET. */
5684 s390_expand_atomic (machine_mode mode
, enum rtx_code code
,
5685 rtx target
, rtx mem
, rtx val
, bool after
)
5687 struct alignment_context ac
;
5689 rtx new_rtx
= gen_reg_rtx (SImode
);
5690 rtx orig
= gen_reg_rtx (SImode
);
5691 rtx_code_label
*csloop
= gen_label_rtx ();
5693 gcc_assert (!target
|| register_operand (target
, VOIDmode
));
5694 gcc_assert (MEM_P (mem
));
5696 init_alignment_context (&ac
, mem
, mode
);
5698 /* Shift val to the correct bit positions.
5699 Preserve "icm", but prevent "ex icm". */
5700 if (!(ac
.aligned
&& code
== SET
&& MEM_P (val
)))
5701 val
= s390_expand_mask_and_shift (val
, mode
, ac
.shift
);
5703 /* Further preparation insns. */
5704 if (code
== PLUS
|| code
== MINUS
)
5705 emit_move_insn (orig
, val
);
5706 else if (code
== MULT
|| code
== AND
) /* val = "11..1<val>11..1" */
5707 val
= expand_simple_binop (SImode
, XOR
, val
, ac
.modemaski
,
5708 NULL_RTX
, 1, OPTAB_DIRECT
);
5710 /* Load full word. Subsequent loads are performed by CS. */
5711 cmp
= force_reg (SImode
, ac
.memsi
);
5713 /* Start CS loop. */
5714 emit_label (csloop
);
5715 emit_move_insn (new_rtx
, cmp
);
5717 /* Patch new with val at correct position. */
5722 val
= expand_simple_binop (SImode
, code
, new_rtx
, orig
,
5723 NULL_RTX
, 1, OPTAB_DIRECT
);
5724 val
= expand_simple_binop (SImode
, AND
, val
, ac
.modemask
,
5725 NULL_RTX
, 1, OPTAB_DIRECT
);
5728 if (ac
.aligned
&& MEM_P (val
))
5729 store_bit_field (new_rtx
, GET_MODE_BITSIZE (mode
), 0,
5733 new_rtx
= expand_simple_binop (SImode
, AND
, new_rtx
, ac
.modemaski
,
5734 NULL_RTX
, 1, OPTAB_DIRECT
);
5735 new_rtx
= expand_simple_binop (SImode
, IOR
, new_rtx
, val
,
5736 NULL_RTX
, 1, OPTAB_DIRECT
);
5742 new_rtx
= expand_simple_binop (SImode
, code
, new_rtx
, val
,
5743 NULL_RTX
, 1, OPTAB_DIRECT
);
5745 case MULT
: /* NAND */
5746 new_rtx
= expand_simple_binop (SImode
, AND
, new_rtx
, val
,
5747 NULL_RTX
, 1, OPTAB_DIRECT
);
5748 new_rtx
= expand_simple_binop (SImode
, XOR
, new_rtx
, ac
.modemask
,
5749 NULL_RTX
, 1, OPTAB_DIRECT
);
5755 s390_emit_jump (csloop
, s390_emit_compare_and_swap (NE
, cmp
,
5756 ac
.memsi
, cmp
, new_rtx
));
5758 /* Return the correct part of the bitfield. */
5760 convert_move (target
, expand_simple_binop (SImode
, LSHIFTRT
,
5761 after
? new_rtx
: cmp
, ac
.shift
,
5762 NULL_RTX
, 1, OPTAB_DIRECT
), 1);
5765 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5766 We need to emit DTP-relative relocations. */
5768 static void s390_output_dwarf_dtprel (FILE *, int, rtx
) ATTRIBUTE_UNUSED
;
5771 s390_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
5776 fputs ("\t.long\t", file
);
5779 fputs ("\t.quad\t", file
);
5784 output_addr_const (file
, x
);
5785 fputs ("@DTPOFF", file
);
5788 /* Return the proper mode for REGNO being represented in the dwarf
5791 s390_dwarf_frame_reg_mode (int regno
)
5793 machine_mode save_mode
= default_dwarf_frame_reg_mode (regno
);
5795 /* The rightmost 64 bits of vector registers are call-clobbered. */
5796 if (GET_MODE_SIZE (save_mode
) > 8)
5802 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
5803 /* Implement TARGET_MANGLE_TYPE. */
5806 s390_mangle_type (const_tree type
)
5808 if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
5809 && TARGET_LONG_DOUBLE_128
)
5812 /* For all other types, use normal C++ mangling. */
5817 /* In the name of slightly smaller debug output, and to cater to
5818 general assembler lossage, recognize various UNSPEC sequences
5819 and turn them back into a direct symbol reference. */
5822 s390_delegitimize_address (rtx orig_x
)
5826 orig_x
= delegitimize_mem_from_attrs (orig_x
);
5829 /* Extract the symbol ref from:
5830 (plus:SI (reg:SI 12 %r12)
5831 (const:SI (unspec:SI [(symbol_ref/f:SI ("*.LC0"))]
5832 UNSPEC_GOTOFF/PLTOFF)))
5834 (plus:SI (reg:SI 12 %r12)
5835 (const:SI (plus:SI (unspec:SI [(symbol_ref:SI ("L"))]
5836 UNSPEC_GOTOFF/PLTOFF)
5837 (const_int 4 [0x4])))) */
5838 if (GET_CODE (x
) == PLUS
5839 && REG_P (XEXP (x
, 0))
5840 && REGNO (XEXP (x
, 0)) == PIC_OFFSET_TABLE_REGNUM
5841 && GET_CODE (XEXP (x
, 1)) == CONST
)
5843 HOST_WIDE_INT offset
= 0;
5845 /* The const operand. */
5846 y
= XEXP (XEXP (x
, 1), 0);
5848 if (GET_CODE (y
) == PLUS
5849 && GET_CODE (XEXP (y
, 1)) == CONST_INT
)
5851 offset
= INTVAL (XEXP (y
, 1));
5855 if (GET_CODE (y
) == UNSPEC
5856 && (XINT (y
, 1) == UNSPEC_GOTOFF
5857 || XINT (y
, 1) == UNSPEC_PLTOFF
))
5858 return plus_constant (Pmode
, XVECEXP (y
, 0, 0), offset
);
5861 if (GET_CODE (x
) != MEM
)
5865 if (GET_CODE (x
) == PLUS
5866 && GET_CODE (XEXP (x
, 1)) == CONST
5867 && GET_CODE (XEXP (x
, 0)) == REG
5868 && REGNO (XEXP (x
, 0)) == PIC_OFFSET_TABLE_REGNUM
)
5870 y
= XEXP (XEXP (x
, 1), 0);
5871 if (GET_CODE (y
) == UNSPEC
5872 && XINT (y
, 1) == UNSPEC_GOT
)
5873 y
= XVECEXP (y
, 0, 0);
5877 else if (GET_CODE (x
) == CONST
)
5879 /* Extract the symbol ref from:
5880 (mem:QI (const:DI (unspec:DI [(symbol_ref:DI ("foo"))]
5881 UNSPEC_PLT/GOTENT))) */
5884 if (GET_CODE (y
) == UNSPEC
5885 && (XINT (y
, 1) == UNSPEC_GOTENT
5886 || XINT (y
, 1) == UNSPEC_PLT
))
5887 y
= XVECEXP (y
, 0, 0);
5894 if (GET_MODE (orig_x
) != Pmode
)
5896 if (GET_MODE (orig_x
) == BLKmode
)
5898 y
= lowpart_subreg (GET_MODE (orig_x
), y
, Pmode
);
5905 /* Output operand OP to stdio stream FILE.
5906 OP is an address (register + offset) which is not used to address data;
5907 instead the rightmost bits are interpreted as the value. */
5910 print_shift_count_operand (FILE *file
, rtx op
)
5912 HOST_WIDE_INT offset
;
5915 /* Extract base register and offset. */
5916 if (!s390_decompose_shift_count (op
, &base
, &offset
))
5922 gcc_assert (GET_CODE (base
) == REG
);
5923 gcc_assert (REGNO (base
) < FIRST_PSEUDO_REGISTER
);
5924 gcc_assert (REGNO_REG_CLASS (REGNO (base
)) == ADDR_REGS
);
5927 /* Offsets are constricted to twelve bits. */
5928 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
& ((1 << 12) - 1));
5930 fprintf (file
, "(%s)", reg_names
[REGNO (base
)]);
5933 /* Assigns the number of NOP halfwords to be emitted before and after the
5934 function label to *HW_BEFORE and *HW_AFTER. Both pointers must not be NULL.
5935 If hotpatching is disabled for the function, the values are set to zero.
5939 s390_function_num_hotpatch_hw (tree decl
,
5945 attr
= lookup_attribute ("hotpatch", DECL_ATTRIBUTES (decl
));
5947 /* Handle the arguments of the hotpatch attribute. The values
5948 specified via attribute might override the cmdline argument
5952 tree args
= TREE_VALUE (attr
);
5954 *hw_before
= TREE_INT_CST_LOW (TREE_VALUE (args
));
5955 *hw_after
= TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (args
)));
5959 /* Use the values specified by the cmdline arguments. */
5960 *hw_before
= s390_hotpatch_hw_before_label
;
5961 *hw_after
= s390_hotpatch_hw_after_label
;
5965 /* Write the extra assembler code needed to declare a function properly. */
5968 s390_asm_output_function_label (FILE *asm_out_file
, const char *fname
,
5971 int hw_before
, hw_after
;
5973 s390_function_num_hotpatch_hw (decl
, &hw_before
, &hw_after
);
5976 unsigned int function_alignment
;
5979 /* Add a trampoline code area before the function label and initialize it
5980 with two-byte nop instructions. This area can be overwritten with code
5981 that jumps to a patched version of the function. */
5982 asm_fprintf (asm_out_file
, "\tnopr\t%%r7"
5983 "\t# pre-label NOPs for hotpatch (%d halfwords)\n",
5985 for (i
= 1; i
< hw_before
; i
++)
5986 fputs ("\tnopr\t%r7\n", asm_out_file
);
5988 /* Note: The function label must be aligned so that (a) the bytes of the
5989 following nop do not cross a cacheline boundary, and (b) a jump address
5990 (eight bytes for 64 bit targets, 4 bytes for 32 bit targets) can be
5991 stored directly before the label without crossing a cacheline
5992 boundary. All this is necessary to make sure the trampoline code can
5993 be changed atomically.
5994 This alignment is done automatically using the FOUNCTION_BOUNDARY, but
5995 if there are NOPs before the function label, the alignment is placed
5996 before them. So it is necessary to duplicate the alignment after the
5998 function_alignment
= MAX (8, DECL_ALIGN (decl
) / BITS_PER_UNIT
);
5999 if (! DECL_USER_ALIGN (decl
))
6000 function_alignment
= MAX (function_alignment
,
6001 (unsigned int) align_functions
);
6002 fputs ("\t# alignment for hotpatch\n", asm_out_file
);
6003 ASM_OUTPUT_ALIGN (asm_out_file
, floor_log2 (function_alignment
));
6006 ASM_OUTPUT_LABEL (asm_out_file
, fname
);
6008 asm_fprintf (asm_out_file
,
6009 "\t# post-label NOPs for hotpatch (%d halfwords)\n",
6013 /* Output machine-dependent UNSPECs occurring in address constant X
6014 in assembler syntax to stdio stream FILE. Returns true if the
6015 constant X could be recognized, false otherwise. */
6018 s390_output_addr_const_extra (FILE *file
, rtx x
)
6020 if (GET_CODE (x
) == UNSPEC
&& XVECLEN (x
, 0) == 1)
6021 switch (XINT (x
, 1))
6024 output_addr_const (file
, XVECEXP (x
, 0, 0));
6025 fprintf (file
, "@GOTENT");
6028 output_addr_const (file
, XVECEXP (x
, 0, 0));
6029 fprintf (file
, "@GOT");
6032 output_addr_const (file
, XVECEXP (x
, 0, 0));
6033 fprintf (file
, "@GOTOFF");
6036 output_addr_const (file
, XVECEXP (x
, 0, 0));
6037 fprintf (file
, "@PLT");
6040 output_addr_const (file
, XVECEXP (x
, 0, 0));
6041 fprintf (file
, "@PLTOFF");
6044 output_addr_const (file
, XVECEXP (x
, 0, 0));
6045 fprintf (file
, "@TLSGD");
6048 assemble_name (file
, get_some_local_dynamic_name ());
6049 fprintf (file
, "@TLSLDM");
6052 output_addr_const (file
, XVECEXP (x
, 0, 0));
6053 fprintf (file
, "@DTPOFF");
6056 output_addr_const (file
, XVECEXP (x
, 0, 0));
6057 fprintf (file
, "@NTPOFF");
6059 case UNSPEC_GOTNTPOFF
:
6060 output_addr_const (file
, XVECEXP (x
, 0, 0));
6061 fprintf (file
, "@GOTNTPOFF");
6063 case UNSPEC_INDNTPOFF
:
6064 output_addr_const (file
, XVECEXP (x
, 0, 0));
6065 fprintf (file
, "@INDNTPOFF");
6069 if (GET_CODE (x
) == UNSPEC
&& XVECLEN (x
, 0) == 2)
6070 switch (XINT (x
, 1))
6072 case UNSPEC_POOL_OFFSET
:
6073 x
= gen_rtx_MINUS (GET_MODE (x
), XVECEXP (x
, 0, 0), XVECEXP (x
, 0, 1));
6074 output_addr_const (file
, x
);
6080 /* Output address operand ADDR in assembler syntax to
6081 stdio stream FILE. */
6084 print_operand_address (FILE *file
, rtx addr
)
6086 struct s390_address ad
;
6088 if (s390_loadrelative_operand_p (addr
, NULL
, NULL
))
6092 output_operand_lossage ("symbolic memory references are "
6093 "only supported on z10 or later");
6096 output_addr_const (file
, addr
);
6100 if (!s390_decompose_address (addr
, &ad
)
6101 || (ad
.base
&& !REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)))
6102 || (ad
.indx
&& !REGNO_OK_FOR_INDEX_P (REGNO (ad
.indx
))))
6103 output_operand_lossage ("cannot decompose address");
6106 output_addr_const (file
, ad
.disp
);
6108 fprintf (file
, "0");
6110 if (ad
.base
&& ad
.indx
)
6111 fprintf (file
, "(%s,%s)", reg_names
[REGNO (ad
.indx
)],
6112 reg_names
[REGNO (ad
.base
)]);
6114 fprintf (file
, "(%s)", reg_names
[REGNO (ad
.base
)]);
6117 /* Output operand X in assembler syntax to stdio stream FILE.
6118 CODE specified the format flag. The following format flags
6121 'C': print opcode suffix for branch condition.
6122 'D': print opcode suffix for inverse branch condition.
6123 'E': print opcode suffix for branch on index instruction.
6124 'G': print the size of the operand in bytes.
6125 'J': print tls_load/tls_gdcall/tls_ldcall suffix
6126 'M': print the second word of a TImode operand.
6127 'N': print the second word of a DImode operand.
6128 'O': print only the displacement of a memory reference or address.
6129 'R': print only the base register of a memory reference or address.
6130 'S': print S-type memory reference (base+displacement).
6131 'Y': print shift count operand.
6133 'b': print integer X as if it's an unsigned byte.
6134 'c': print integer X as if it's an signed byte.
6135 'e': "end" contiguous bitmask X in either DImode or vector inner mode.
6136 'f': "end" contiguous bitmask X in SImode.
6137 'h': print integer X as if it's a signed halfword.
6138 'i': print the first nonzero HImode part of X.
6139 'j': print the first HImode part unequal to -1 of X.
6140 'k': print the first nonzero SImode part of X.
6141 'm': print the first SImode part unequal to -1 of X.
6142 'o': print integer X as if it's an unsigned 32bit word.
6143 's': "start" of contiguous bitmask X in either DImode or vector inner mode.
6144 't': CONST_INT: "start" of contiguous bitmask X in SImode.
6145 CONST_VECTOR: Generate a bitmask for vgbm instruction.
6146 'x': print integer X as if it's an unsigned halfword.
6147 'v': print register number as vector register (v1 instead of f1).
6151 print_operand (FILE *file
, rtx x
, int code
)
6158 fprintf (file
, s390_branch_condition_mnemonic (x
, FALSE
));
6162 fprintf (file
, s390_branch_condition_mnemonic (x
, TRUE
));
6166 if (GET_CODE (x
) == LE
)
6167 fprintf (file
, "l");
6168 else if (GET_CODE (x
) == GT
)
6169 fprintf (file
, "h");
6171 output_operand_lossage ("invalid comparison operator "
6172 "for 'E' output modifier");
6176 if (GET_CODE (x
) == SYMBOL_REF
)
6178 fprintf (file
, "%s", ":tls_load:");
6179 output_addr_const (file
, x
);
6181 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSGD
)
6183 fprintf (file
, "%s", ":tls_gdcall:");
6184 output_addr_const (file
, XVECEXP (x
, 0, 0));
6186 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSLDM
)
6188 fprintf (file
, "%s", ":tls_ldcall:");
6189 const char *name
= get_some_local_dynamic_name ();
6191 assemble_name (file
, name
);
6194 output_operand_lossage ("invalid reference for 'J' output modifier");
6198 fprintf (file
, "%u", GET_MODE_SIZE (GET_MODE (x
)));
6203 struct s390_address ad
;
6206 ret
= s390_decompose_address (MEM_P (x
) ? XEXP (x
, 0) : x
, &ad
);
6209 || (ad
.base
&& !REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)))
6212 output_operand_lossage ("invalid address for 'O' output modifier");
6217 output_addr_const (file
, ad
.disp
);
6219 fprintf (file
, "0");
6225 struct s390_address ad
;
6228 ret
= s390_decompose_address (MEM_P (x
) ? XEXP (x
, 0) : x
, &ad
);
6231 || (ad
.base
&& !REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)))
6234 output_operand_lossage ("invalid address for 'R' output modifier");
6239 fprintf (file
, "%s", reg_names
[REGNO (ad
.base
)]);
6241 fprintf (file
, "0");
6247 struct s390_address ad
;
6252 output_operand_lossage ("memory reference expected for "
6253 "'S' output modifier");
6256 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
6259 || (ad
.base
&& !REGNO_OK_FOR_BASE_P (REGNO (ad
.base
)))
6262 output_operand_lossage ("invalid address for 'S' output modifier");
6267 output_addr_const (file
, ad
.disp
);
6269 fprintf (file
, "0");
6272 fprintf (file
, "(%s)", reg_names
[REGNO (ad
.base
)]);
6277 if (GET_CODE (x
) == REG
)
6278 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
6279 else if (GET_CODE (x
) == MEM
)
6280 x
= change_address (x
, VOIDmode
,
6281 plus_constant (Pmode
, XEXP (x
, 0), 4));
6283 output_operand_lossage ("register or memory expression expected "
6284 "for 'N' output modifier");
6288 if (GET_CODE (x
) == REG
)
6289 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
6290 else if (GET_CODE (x
) == MEM
)
6291 x
= change_address (x
, VOIDmode
,
6292 plus_constant (Pmode
, XEXP (x
, 0), 8));
6294 output_operand_lossage ("register or memory expression expected "
6295 "for 'M' output modifier");
6299 print_shift_count_operand (file
, x
);
6303 switch (GET_CODE (x
))
6306 /* Print FP regs as fx instead of vx when they are accessed
6307 through non-vector mode. */
6309 || VECTOR_NOFP_REG_P (x
)
6310 || (FP_REG_P (x
) && VECTOR_MODE_P (GET_MODE (x
)))
6311 || (VECTOR_REG_P (x
)
6312 && (GET_MODE_SIZE (GET_MODE (x
)) /
6313 s390_class_max_nregs (FP_REGS
, GET_MODE (x
))) > 8))
6314 fprintf (file
, "%%v%s", reg_names
[REGNO (x
)] + 2);
6316 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
6320 output_address (XEXP (x
, 0));
6327 output_addr_const (file
, x
);
6340 ival
= ((ival
& 0xff) ^ 0x80) - 0x80;
6346 ival
= ((ival
& 0xffff) ^ 0x8000) - 0x8000;
6349 ival
= s390_extract_part (x
, HImode
, 0);
6352 ival
= s390_extract_part (x
, HImode
, -1);
6355 ival
= s390_extract_part (x
, SImode
, 0);
6358 ival
= s390_extract_part (x
, SImode
, -1);
6369 len
= (code
== 's' || code
== 'e' ? 64 : 32);
6370 ok
= s390_contiguous_bitmask_p (ival
, len
, &pos
, &len
);
6372 if (code
== 's' || code
== 't')
6373 ival
= 64 - pos
- len
;
6375 ival
= 64 - 1 - pos
;
6379 output_operand_lossage ("invalid constant for output modifier '%c'", code
);
6381 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ival
);
6385 gcc_assert (GET_MODE (x
) == VOIDmode
);
6387 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xff);
6388 else if (code
== 'x')
6389 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xffff);
6390 else if (code
== 'h')
6391 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
6392 ((CONST_DOUBLE_LOW (x
) & 0xffff) ^ 0x8000) - 0x8000);
6396 output_operand_lossage ("invalid constant - try using "
6397 "an output modifier");
6399 output_operand_lossage ("invalid constant for output modifier '%c'",
6409 int start
, stop
, inner_len
;
6412 inner_len
= GET_MODE_UNIT_BITSIZE (GET_MODE (x
));
6413 ok
= s390_contiguous_bitmask_vector_p (x
, &start
, &stop
);
6415 if (code
== 's' || code
== 't')
6416 ival
= inner_len
- stop
- 1;
6418 ival
= inner_len
- start
- 1;
6419 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ival
);
6425 bool ok
= s390_bytemask_vector_p (x
, &mask
);
6427 fprintf (file
, "%u", mask
);
6432 output_operand_lossage ("invalid constant vector for output "
6433 "modifier '%c'", code
);
6439 output_operand_lossage ("invalid expression - try using "
6440 "an output modifier");
6442 output_operand_lossage ("invalid expression for output "
6443 "modifier '%c'", code
);
6448 /* Target hook for assembling integer objects. We need to define it
6449 here to work a round a bug in some versions of GAS, which couldn't
6450 handle values smaller than INT_MIN when printed in decimal. */
6453 s390_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
6455 if (size
== 8 && aligned_p
6456 && GET_CODE (x
) == CONST_INT
&& INTVAL (x
) < INT_MIN
)
6458 fprintf (asm_out_file
, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX
"\n",
6462 return default_assemble_integer (x
, size
, aligned_p
);
6465 /* Returns true if register REGNO is used for forming
6466 a memory address in expression X. */
6469 reg_used_in_mem_p (int regno
, rtx x
)
6471 enum rtx_code code
= GET_CODE (x
);
6477 if (refers_to_regno_p (regno
, XEXP (x
, 0)))
6480 else if (code
== SET
6481 && GET_CODE (SET_DEST (x
)) == PC
)
6483 if (refers_to_regno_p (regno
, SET_SRC (x
)))
6487 fmt
= GET_RTX_FORMAT (code
);
6488 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
6491 && reg_used_in_mem_p (regno
, XEXP (x
, i
)))
6494 else if (fmt
[i
] == 'E')
6495 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
6496 if (reg_used_in_mem_p (regno
, XVECEXP (x
, i
, j
)))
6502 /* Returns true if expression DEP_RTX sets an address register
6503 used by instruction INSN to address memory. */
6506 addr_generation_dependency_p (rtx dep_rtx
, rtx_insn
*insn
)
6510 if (NONJUMP_INSN_P (dep_rtx
))
6511 dep_rtx
= PATTERN (dep_rtx
);
6513 if (GET_CODE (dep_rtx
) == SET
)
6515 target
= SET_DEST (dep_rtx
);
6516 if (GET_CODE (target
) == STRICT_LOW_PART
)
6517 target
= XEXP (target
, 0);
6518 while (GET_CODE (target
) == SUBREG
)
6519 target
= SUBREG_REG (target
);
6521 if (GET_CODE (target
) == REG
)
6523 int regno
= REGNO (target
);
6525 if (s390_safe_attr_type (insn
) == TYPE_LA
)
6527 pat
= PATTERN (insn
);
6528 if (GET_CODE (pat
) == PARALLEL
)
6530 gcc_assert (XVECLEN (pat
, 0) == 2);
6531 pat
= XVECEXP (pat
, 0, 0);
6533 gcc_assert (GET_CODE (pat
) == SET
);
6534 return refers_to_regno_p (regno
, SET_SRC (pat
));
6536 else if (get_attr_atype (insn
) == ATYPE_AGEN
)
6537 return reg_used_in_mem_p (regno
, PATTERN (insn
));
6543 /* Return 1, if dep_insn sets register used in insn in the agen unit. */
6546 s390_agen_dep_p (rtx_insn
*dep_insn
, rtx_insn
*insn
)
6548 rtx dep_rtx
= PATTERN (dep_insn
);
6551 if (GET_CODE (dep_rtx
) == SET
6552 && addr_generation_dependency_p (dep_rtx
, insn
))
6554 else if (GET_CODE (dep_rtx
) == PARALLEL
)
6556 for (i
= 0; i
< XVECLEN (dep_rtx
, 0); i
++)
6558 if (addr_generation_dependency_p (XVECEXP (dep_rtx
, 0, i
), insn
))
6566 /* A C statement (sans semicolon) to update the integer scheduling priority
6567 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
6568 reduce the priority to execute INSN later. Do not define this macro if
6569 you do not need to adjust the scheduling priorities of insns.
6571 A STD instruction should be scheduled earlier,
6572 in order to use the bypass. */
6574 s390_adjust_priority (rtx_insn
*insn
, int priority
)
6576 if (! INSN_P (insn
))
6579 if (s390_tune
!= PROCESSOR_2084_Z990
6580 && s390_tune
!= PROCESSOR_2094_Z9_109
6581 && s390_tune
!= PROCESSOR_2097_Z10
6582 && s390_tune
!= PROCESSOR_2817_Z196
6583 && s390_tune
!= PROCESSOR_2827_ZEC12
6584 && s390_tune
!= PROCESSOR_2964_Z13
)
6587 switch (s390_safe_attr_type (insn
))
6591 priority
= priority
<< 3;
6595 priority
= priority
<< 1;
6604 /* The number of instructions that can be issued per cycle. */
6607 s390_issue_rate (void)
6611 case PROCESSOR_2084_Z990
:
6612 case PROCESSOR_2094_Z9_109
:
6613 case PROCESSOR_2817_Z196
:
6615 case PROCESSOR_2097_Z10
:
6617 /* Starting with EC12 we use the sched_reorder hook to take care
6618 of instruction dispatch constraints. The algorithm only
6619 picks the best instruction and assumes only a single
6620 instruction gets issued per cycle. */
6621 case PROCESSOR_2827_ZEC12
:
6628 s390_first_cycle_multipass_dfa_lookahead (void)
6633 /* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
6634 Fix up MEMs as required. */
6637 annotate_constant_pool_refs (rtx
*x
)
6642 gcc_assert (GET_CODE (*x
) != SYMBOL_REF
6643 || !CONSTANT_POOL_ADDRESS_P (*x
));
6645 /* Literal pool references can only occur inside a MEM ... */
6646 if (GET_CODE (*x
) == MEM
)
6648 rtx memref
= XEXP (*x
, 0);
6650 if (GET_CODE (memref
) == SYMBOL_REF
6651 && CONSTANT_POOL_ADDRESS_P (memref
))
6653 rtx base
= cfun
->machine
->base_reg
;
6654 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, memref
, base
),
6657 *x
= replace_equiv_address (*x
, addr
);
6661 if (GET_CODE (memref
) == CONST
6662 && GET_CODE (XEXP (memref
, 0)) == PLUS
6663 && GET_CODE (XEXP (XEXP (memref
, 0), 1)) == CONST_INT
6664 && GET_CODE (XEXP (XEXP (memref
, 0), 0)) == SYMBOL_REF
6665 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (memref
, 0), 0)))
6667 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (memref
, 0), 1));
6668 rtx sym
= XEXP (XEXP (memref
, 0), 0);
6669 rtx base
= cfun
->machine
->base_reg
;
6670 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
6673 *x
= replace_equiv_address (*x
, plus_constant (Pmode
, addr
, off
));
6678 /* ... or a load-address type pattern. */
6679 if (GET_CODE (*x
) == SET
)
6681 rtx addrref
= SET_SRC (*x
);
6683 if (GET_CODE (addrref
) == SYMBOL_REF
6684 && CONSTANT_POOL_ADDRESS_P (addrref
))
6686 rtx base
= cfun
->machine
->base_reg
;
6687 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, addrref
, base
),
6690 SET_SRC (*x
) = addr
;
6694 if (GET_CODE (addrref
) == CONST
6695 && GET_CODE (XEXP (addrref
, 0)) == PLUS
6696 && GET_CODE (XEXP (XEXP (addrref
, 0), 1)) == CONST_INT
6697 && GET_CODE (XEXP (XEXP (addrref
, 0), 0)) == SYMBOL_REF
6698 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (addrref
, 0), 0)))
6700 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (addrref
, 0), 1));
6701 rtx sym
= XEXP (XEXP (addrref
, 0), 0);
6702 rtx base
= cfun
->machine
->base_reg
;
6703 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
6706 SET_SRC (*x
) = plus_constant (Pmode
, addr
, off
);
6711 /* Annotate LTREL_BASE as well. */
6712 if (GET_CODE (*x
) == UNSPEC
6713 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
6715 rtx base
= cfun
->machine
->base_reg
;
6716 *x
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XVECEXP (*x
, 0, 0), base
),
6721 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
6722 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
6726 annotate_constant_pool_refs (&XEXP (*x
, i
));
6728 else if (fmt
[i
] == 'E')
6730 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
6731 annotate_constant_pool_refs (&XVECEXP (*x
, i
, j
));
6736 /* Split all branches that exceed the maximum distance.
6737 Returns true if this created a new literal pool entry. */
6740 s390_split_branches (void)
6742 rtx temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
6743 int new_literal
= 0, ret
;
6748 /* We need correct insn addresses. */
6750 shorten_branches (get_insns ());
6752 /* Find all branches that exceed 64KB, and split them. */
6754 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6756 if (! JUMP_P (insn
) || tablejump_p (insn
, NULL
, NULL
))
6759 pat
= PATTERN (insn
);
6760 if (GET_CODE (pat
) == PARALLEL
)
6761 pat
= XVECEXP (pat
, 0, 0);
6762 if (GET_CODE (pat
) != SET
|| SET_DEST (pat
) != pc_rtx
)
6765 if (GET_CODE (SET_SRC (pat
)) == LABEL_REF
)
6767 label
= &SET_SRC (pat
);
6769 else if (GET_CODE (SET_SRC (pat
)) == IF_THEN_ELSE
)
6771 if (GET_CODE (XEXP (SET_SRC (pat
), 1)) == LABEL_REF
)
6772 label
= &XEXP (SET_SRC (pat
), 1);
6773 else if (GET_CODE (XEXP (SET_SRC (pat
), 2)) == LABEL_REF
)
6774 label
= &XEXP (SET_SRC (pat
), 2);
6781 if (get_attr_length (insn
) <= 4)
6784 /* We are going to use the return register as scratch register,
6785 make sure it will be saved/restored by the prologue/epilogue. */
6786 cfun_frame_layout
.save_return_addr_p
= 1;
6791 rtx mem
= force_const_mem (Pmode
, *label
);
6792 rtx_insn
*set_insn
= emit_insn_before (gen_rtx_SET (temp_reg
, mem
),
6794 INSN_ADDRESSES_NEW (set_insn
, -1);
6795 annotate_constant_pool_refs (&PATTERN (set_insn
));
6802 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, *label
),
6803 UNSPEC_LTREL_OFFSET
);
6804 target
= gen_rtx_CONST (Pmode
, target
);
6805 target
= force_const_mem (Pmode
, target
);
6806 rtx_insn
*set_insn
= emit_insn_before (gen_rtx_SET (temp_reg
, target
),
6808 INSN_ADDRESSES_NEW (set_insn
, -1);
6809 annotate_constant_pool_refs (&PATTERN (set_insn
));
6811 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XEXP (target
, 0),
6812 cfun
->machine
->base_reg
),
6814 target
= gen_rtx_PLUS (Pmode
, temp_reg
, target
);
6817 ret
= validate_change (insn
, label
, target
, 0);
6825 /* Find an annotated literal pool symbol referenced in RTX X,
6826 and store it at REF. Will abort if X contains references to
6827 more than one such pool symbol; multiple references to the same
6828 symbol are allowed, however.
6830 The rtx pointed to by REF must be initialized to NULL_RTX
6831 by the caller before calling this routine. */
6834 find_constant_pool_ref (rtx x
, rtx
*ref
)
6839 /* Ignore LTREL_BASE references. */
6840 if (GET_CODE (x
) == UNSPEC
6841 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
6843 /* Likewise POOL_ENTRY insns. */
6844 if (GET_CODE (x
) == UNSPEC_VOLATILE
6845 && XINT (x
, 1) == UNSPECV_POOL_ENTRY
)
6848 gcc_assert (GET_CODE (x
) != SYMBOL_REF
6849 || !CONSTANT_POOL_ADDRESS_P (x
));
6851 if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_LTREF
)
6853 rtx sym
= XVECEXP (x
, 0, 0);
6854 gcc_assert (GET_CODE (sym
) == SYMBOL_REF
6855 && CONSTANT_POOL_ADDRESS_P (sym
));
6857 if (*ref
== NULL_RTX
)
6860 gcc_assert (*ref
== sym
);
6865 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
6866 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
6870 find_constant_pool_ref (XEXP (x
, i
), ref
);
6872 else if (fmt
[i
] == 'E')
6874 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
6875 find_constant_pool_ref (XVECEXP (x
, i
, j
), ref
);
6880 /* Replace every reference to the annotated literal pool
6881 symbol REF in X by its base plus OFFSET. */
6884 replace_constant_pool_ref (rtx
*x
, rtx ref
, rtx offset
)
6889 gcc_assert (*x
!= ref
);
6891 if (GET_CODE (*x
) == UNSPEC
6892 && XINT (*x
, 1) == UNSPEC_LTREF
6893 && XVECEXP (*x
, 0, 0) == ref
)
6895 *x
= gen_rtx_PLUS (Pmode
, XVECEXP (*x
, 0, 1), offset
);
6899 if (GET_CODE (*x
) == PLUS
6900 && GET_CODE (XEXP (*x
, 1)) == CONST_INT
6901 && GET_CODE (XEXP (*x
, 0)) == UNSPEC
6902 && XINT (XEXP (*x
, 0), 1) == UNSPEC_LTREF
6903 && XVECEXP (XEXP (*x
, 0), 0, 0) == ref
)
6905 rtx addr
= gen_rtx_PLUS (Pmode
, XVECEXP (XEXP (*x
, 0), 0, 1), offset
);
6906 *x
= plus_constant (Pmode
, addr
, INTVAL (XEXP (*x
, 1)));
6910 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
6911 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
6915 replace_constant_pool_ref (&XEXP (*x
, i
), ref
, offset
);
6917 else if (fmt
[i
] == 'E')
6919 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
6920 replace_constant_pool_ref (&XVECEXP (*x
, i
, j
), ref
, offset
);
6925 /* Check whether X contains an UNSPEC_LTREL_BASE.
6926 Return its constant pool symbol if found, NULL_RTX otherwise. */
6929 find_ltrel_base (rtx x
)
6934 if (GET_CODE (x
) == UNSPEC
6935 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
6936 return XVECEXP (x
, 0, 0);
6938 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
6939 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
6943 rtx fnd
= find_ltrel_base (XEXP (x
, i
));
6947 else if (fmt
[i
] == 'E')
6949 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
6951 rtx fnd
= find_ltrel_base (XVECEXP (x
, i
, j
));
6961 /* Replace any occurrence of UNSPEC_LTREL_BASE in X with its base. */
6964 replace_ltrel_base (rtx
*x
)
6969 if (GET_CODE (*x
) == UNSPEC
6970 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
6972 *x
= XVECEXP (*x
, 0, 1);
6976 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
6977 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
6981 replace_ltrel_base (&XEXP (*x
, i
));
6983 else if (fmt
[i
] == 'E')
6985 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
6986 replace_ltrel_base (&XVECEXP (*x
, i
, j
));
6992 /* We keep a list of constants which we have to add to internal
6993 constant tables in the middle of large functions. */
6995 #define NR_C_MODES 31
6996 machine_mode constant_modes
[NR_C_MODES
] =
6998 TFmode
, TImode
, TDmode
,
6999 V16QImode
, V8HImode
, V4SImode
, V2DImode
, V4SFmode
, V2DFmode
, V1TFmode
,
7000 DFmode
, DImode
, DDmode
,
7001 V8QImode
, V4HImode
, V2SImode
, V1DImode
, V2SFmode
, V1DFmode
,
7002 SFmode
, SImode
, SDmode
,
7003 V4QImode
, V2HImode
, V1SImode
, V1SFmode
,
7012 struct constant
*next
;
7014 rtx_code_label
*label
;
7017 struct constant_pool
7019 struct constant_pool
*next
;
7020 rtx_insn
*first_insn
;
7021 rtx_insn
*pool_insn
;
7023 rtx_insn
*emit_pool_after
;
7025 struct constant
*constants
[NR_C_MODES
];
7026 struct constant
*execute
;
7027 rtx_code_label
*label
;
7031 /* Allocate new constant_pool structure. */
7033 static struct constant_pool
*
7034 s390_alloc_pool (void)
7036 struct constant_pool
*pool
;
7039 pool
= (struct constant_pool
*) xmalloc (sizeof *pool
);
7041 for (i
= 0; i
< NR_C_MODES
; i
++)
7042 pool
->constants
[i
] = NULL
;
7044 pool
->execute
= NULL
;
7045 pool
->label
= gen_label_rtx ();
7046 pool
->first_insn
= NULL
;
7047 pool
->pool_insn
= NULL
;
7048 pool
->insns
= BITMAP_ALLOC (NULL
);
7050 pool
->emit_pool_after
= NULL
;
7055 /* Create new constant pool covering instructions starting at INSN
7056 and chain it to the end of POOL_LIST. */
7058 static struct constant_pool
*
7059 s390_start_pool (struct constant_pool
**pool_list
, rtx_insn
*insn
)
7061 struct constant_pool
*pool
, **prev
;
7063 pool
= s390_alloc_pool ();
7064 pool
->first_insn
= insn
;
7066 for (prev
= pool_list
; *prev
; prev
= &(*prev
)->next
)
7073 /* End range of instructions covered by POOL at INSN and emit
7074 placeholder insn representing the pool. */
7077 s390_end_pool (struct constant_pool
*pool
, rtx_insn
*insn
)
7079 rtx pool_size
= GEN_INT (pool
->size
+ 8 /* alignment slop */);
7082 insn
= get_last_insn ();
7084 pool
->pool_insn
= emit_insn_after (gen_pool (pool_size
), insn
);
7085 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
7088 /* Add INSN to the list of insns covered by POOL. */
7091 s390_add_pool_insn (struct constant_pool
*pool
, rtx insn
)
7093 bitmap_set_bit (pool
->insns
, INSN_UID (insn
));
7096 /* Return pool out of POOL_LIST that covers INSN. */
7098 static struct constant_pool
*
7099 s390_find_pool (struct constant_pool
*pool_list
, rtx insn
)
7101 struct constant_pool
*pool
;
7103 for (pool
= pool_list
; pool
; pool
= pool
->next
)
7104 if (bitmap_bit_p (pool
->insns
, INSN_UID (insn
)))
7110 /* Add constant VAL of mode MODE to the constant pool POOL. */
7113 s390_add_constant (struct constant_pool
*pool
, rtx val
, machine_mode mode
)
7118 for (i
= 0; i
< NR_C_MODES
; i
++)
7119 if (constant_modes
[i
] == mode
)
7121 gcc_assert (i
!= NR_C_MODES
);
7123 for (c
= pool
->constants
[i
]; c
!= NULL
; c
= c
->next
)
7124 if (rtx_equal_p (val
, c
->value
))
7129 c
= (struct constant
*) xmalloc (sizeof *c
);
7131 c
->label
= gen_label_rtx ();
7132 c
->next
= pool
->constants
[i
];
7133 pool
->constants
[i
] = c
;
7134 pool
->size
+= GET_MODE_SIZE (mode
);
7138 /* Return an rtx that represents the offset of X from the start of
7142 s390_pool_offset (struct constant_pool
*pool
, rtx x
)
7146 label
= gen_rtx_LABEL_REF (GET_MODE (x
), pool
->label
);
7147 x
= gen_rtx_UNSPEC (GET_MODE (x
), gen_rtvec (2, x
, label
),
7148 UNSPEC_POOL_OFFSET
);
7149 return gen_rtx_CONST (GET_MODE (x
), x
);
7152 /* Find constant VAL of mode MODE in the constant pool POOL.
7153 Return an RTX describing the distance from the start of
7154 the pool to the location of the new constant. */
7157 s390_find_constant (struct constant_pool
*pool
, rtx val
,
7163 for (i
= 0; i
< NR_C_MODES
; i
++)
7164 if (constant_modes
[i
] == mode
)
7166 gcc_assert (i
!= NR_C_MODES
);
7168 for (c
= pool
->constants
[i
]; c
!= NULL
; c
= c
->next
)
7169 if (rtx_equal_p (val
, c
->value
))
7174 return s390_pool_offset (pool
, gen_rtx_LABEL_REF (Pmode
, c
->label
));
7177 /* Check whether INSN is an execute. Return the label_ref to its
7178 execute target template if so, NULL_RTX otherwise. */
7181 s390_execute_label (rtx insn
)
7183 if (NONJUMP_INSN_P (insn
)
7184 && GET_CODE (PATTERN (insn
)) == PARALLEL
7185 && GET_CODE (XVECEXP (PATTERN (insn
), 0, 0)) == UNSPEC
7186 && XINT (XVECEXP (PATTERN (insn
), 0, 0), 1) == UNSPEC_EXECUTE
)
7187 return XVECEXP (XVECEXP (PATTERN (insn
), 0, 0), 0, 2);
7192 /* Add execute target for INSN to the constant pool POOL. */
7195 s390_add_execute (struct constant_pool
*pool
, rtx insn
)
7199 for (c
= pool
->execute
; c
!= NULL
; c
= c
->next
)
7200 if (INSN_UID (insn
) == INSN_UID (c
->value
))
7205 c
= (struct constant
*) xmalloc (sizeof *c
);
7207 c
->label
= gen_label_rtx ();
7208 c
->next
= pool
->execute
;
7214 /* Find execute target for INSN in the constant pool POOL.
7215 Return an RTX describing the distance from the start of
7216 the pool to the location of the execute target. */
7219 s390_find_execute (struct constant_pool
*pool
, rtx insn
)
7223 for (c
= pool
->execute
; c
!= NULL
; c
= c
->next
)
7224 if (INSN_UID (insn
) == INSN_UID (c
->value
))
7229 return s390_pool_offset (pool
, gen_rtx_LABEL_REF (Pmode
, c
->label
));
7232 /* For an execute INSN, extract the execute target template. */
7235 s390_execute_target (rtx insn
)
7237 rtx pattern
= PATTERN (insn
);
7238 gcc_assert (s390_execute_label (insn
));
7240 if (XVECLEN (pattern
, 0) == 2)
7242 pattern
= copy_rtx (XVECEXP (pattern
, 0, 1));
7246 rtvec vec
= rtvec_alloc (XVECLEN (pattern
, 0) - 1);
7249 for (i
= 0; i
< XVECLEN (pattern
, 0) - 1; i
++)
7250 RTVEC_ELT (vec
, i
) = copy_rtx (XVECEXP (pattern
, 0, i
+ 1));
7252 pattern
= gen_rtx_PARALLEL (VOIDmode
, vec
);
7258 /* Indicate that INSN cannot be duplicated. This is the case for
7259 execute insns that carry a unique label. */
7262 s390_cannot_copy_insn_p (rtx_insn
*insn
)
7264 rtx label
= s390_execute_label (insn
);
7265 return label
&& label
!= const0_rtx
;
7268 /* Dump out the constants in POOL. If REMOTE_LABEL is true,
7269 do not emit the pool base label. */
7272 s390_dump_pool (struct constant_pool
*pool
, bool remote_label
)
7275 rtx_insn
*insn
= pool
->pool_insn
;
7278 /* Switch to rodata section. */
7279 if (TARGET_CPU_ZARCH
)
7281 insn
= emit_insn_after (gen_pool_section_start (), insn
);
7282 INSN_ADDRESSES_NEW (insn
, -1);
7285 /* Ensure minimum pool alignment. */
7286 if (TARGET_CPU_ZARCH
)
7287 insn
= emit_insn_after (gen_pool_align (GEN_INT (8)), insn
);
7289 insn
= emit_insn_after (gen_pool_align (GEN_INT (4)), insn
);
7290 INSN_ADDRESSES_NEW (insn
, -1);
7292 /* Emit pool base label. */
7295 insn
= emit_label_after (pool
->label
, insn
);
7296 INSN_ADDRESSES_NEW (insn
, -1);
7299 /* Dump constants in descending alignment requirement order,
7300 ensuring proper alignment for every constant. */
7301 for (i
= 0; i
< NR_C_MODES
; i
++)
7302 for (c
= pool
->constants
[i
]; c
; c
= c
->next
)
7304 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
7305 rtx value
= copy_rtx (c
->value
);
7306 if (GET_CODE (value
) == CONST
7307 && GET_CODE (XEXP (value
, 0)) == UNSPEC
7308 && XINT (XEXP (value
, 0), 1) == UNSPEC_LTREL_OFFSET
7309 && XVECLEN (XEXP (value
, 0), 0) == 1)
7310 value
= s390_pool_offset (pool
, XVECEXP (XEXP (value
, 0), 0, 0));
7312 insn
= emit_label_after (c
->label
, insn
);
7313 INSN_ADDRESSES_NEW (insn
, -1);
7315 value
= gen_rtx_UNSPEC_VOLATILE (constant_modes
[i
],
7316 gen_rtvec (1, value
),
7317 UNSPECV_POOL_ENTRY
);
7318 insn
= emit_insn_after (value
, insn
);
7319 INSN_ADDRESSES_NEW (insn
, -1);
7322 /* Ensure minimum alignment for instructions. */
7323 insn
= emit_insn_after (gen_pool_align (GEN_INT (2)), insn
);
7324 INSN_ADDRESSES_NEW (insn
, -1);
7326 /* Output in-pool execute template insns. */
7327 for (c
= pool
->execute
; c
; c
= c
->next
)
7329 insn
= emit_label_after (c
->label
, insn
);
7330 INSN_ADDRESSES_NEW (insn
, -1);
7332 insn
= emit_insn_after (s390_execute_target (c
->value
), insn
);
7333 INSN_ADDRESSES_NEW (insn
, -1);
7336 /* Switch back to previous section. */
7337 if (TARGET_CPU_ZARCH
)
7339 insn
= emit_insn_after (gen_pool_section_end (), insn
);
7340 INSN_ADDRESSES_NEW (insn
, -1);
7343 insn
= emit_barrier_after (insn
);
7344 INSN_ADDRESSES_NEW (insn
, -1);
7346 /* Remove placeholder insn. */
7347 remove_insn (pool
->pool_insn
);
7350 /* Free all memory used by POOL. */
7353 s390_free_pool (struct constant_pool
*pool
)
7355 struct constant
*c
, *next
;
7358 for (i
= 0; i
< NR_C_MODES
; i
++)
7359 for (c
= pool
->constants
[i
]; c
; c
= next
)
7365 for (c
= pool
->execute
; c
; c
= next
)
7371 BITMAP_FREE (pool
->insns
);
7376 /* Collect main literal pool. Return NULL on overflow. */
7378 static struct constant_pool
*
7379 s390_mainpool_start (void)
7381 struct constant_pool
*pool
;
7384 pool
= s390_alloc_pool ();
7386 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7388 if (NONJUMP_INSN_P (insn
)
7389 && GET_CODE (PATTERN (insn
)) == SET
7390 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC_VOLATILE
7391 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPECV_MAIN_POOL
)
7393 /* There might be two main_pool instructions if base_reg
7394 is call-clobbered; one for shrink-wrapped code and one
7395 for the rest. We want to keep the first. */
7396 if (pool
->pool_insn
)
7398 insn
= PREV_INSN (insn
);
7399 delete_insn (NEXT_INSN (insn
));
7402 pool
->pool_insn
= insn
;
7405 if (!TARGET_CPU_ZARCH
&& s390_execute_label (insn
))
7407 s390_add_execute (pool
, insn
);
7409 else if (NONJUMP_INSN_P (insn
) || CALL_P (insn
))
7411 rtx pool_ref
= NULL_RTX
;
7412 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
7415 rtx constant
= get_pool_constant (pool_ref
);
7416 machine_mode mode
= get_pool_mode (pool_ref
);
7417 s390_add_constant (pool
, constant
, mode
);
7421 /* If hot/cold partitioning is enabled we have to make sure that
7422 the literal pool is emitted in the same section where the
7423 initialization of the literal pool base pointer takes place.
7424 emit_pool_after is only used in the non-overflow case on non
7425 Z cpus where we can emit the literal pool at the end of the
7426 function body within the text section. */
7428 && NOTE_KIND (insn
) == NOTE_INSN_SWITCH_TEXT_SECTIONS
7429 && !pool
->emit_pool_after
)
7430 pool
->emit_pool_after
= PREV_INSN (insn
);
7433 gcc_assert (pool
->pool_insn
|| pool
->size
== 0);
7435 if (pool
->size
>= 4096)
7437 /* We're going to chunkify the pool, so remove the main
7438 pool placeholder insn. */
7439 remove_insn (pool
->pool_insn
);
7441 s390_free_pool (pool
);
7445 /* If the functions ends with the section where the literal pool
7446 should be emitted set the marker to its end. */
7447 if (pool
&& !pool
->emit_pool_after
)
7448 pool
->emit_pool_after
= get_last_insn ();
7453 /* POOL holds the main literal pool as collected by s390_mainpool_start.
7454 Modify the current function to output the pool constants as well as
7455 the pool register setup instruction. */
7458 s390_mainpool_finish (struct constant_pool
*pool
)
7460 rtx base_reg
= cfun
->machine
->base_reg
;
7462 /* If the pool is empty, we're done. */
7463 if (pool
->size
== 0)
7465 /* We don't actually need a base register after all. */
7466 cfun
->machine
->base_reg
= NULL_RTX
;
7468 if (pool
->pool_insn
)
7469 remove_insn (pool
->pool_insn
);
7470 s390_free_pool (pool
);
7474 /* We need correct insn addresses. */
7475 shorten_branches (get_insns ());
7477 /* On zSeries, we use a LARL to load the pool register. The pool is
7478 located in the .rodata section, so we emit it after the function. */
7479 if (TARGET_CPU_ZARCH
)
7481 rtx set
= gen_main_base_64 (base_reg
, pool
->label
);
7482 rtx_insn
*insn
= emit_insn_after (set
, pool
->pool_insn
);
7483 INSN_ADDRESSES_NEW (insn
, -1);
7484 remove_insn (pool
->pool_insn
);
7486 insn
= get_last_insn ();
7487 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
7488 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
7490 s390_dump_pool (pool
, 0);
7493 /* On S/390, if the total size of the function's code plus literal pool
7494 does not exceed 4096 bytes, we use BASR to set up a function base
7495 pointer, and emit the literal pool at the end of the function. */
7496 else if (INSN_ADDRESSES (INSN_UID (pool
->emit_pool_after
))
7497 + pool
->size
+ 8 /* alignment slop */ < 4096)
7499 rtx set
= gen_main_base_31_small (base_reg
, pool
->label
);
7500 rtx_insn
*insn
= emit_insn_after (set
, pool
->pool_insn
);
7501 INSN_ADDRESSES_NEW (insn
, -1);
7502 remove_insn (pool
->pool_insn
);
7504 insn
= emit_label_after (pool
->label
, insn
);
7505 INSN_ADDRESSES_NEW (insn
, -1);
7507 /* emit_pool_after will be set by s390_mainpool_start to the
7508 last insn of the section where the literal pool should be
7510 insn
= pool
->emit_pool_after
;
7512 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
7513 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
7515 s390_dump_pool (pool
, 1);
7518 /* Otherwise, we emit an inline literal pool and use BASR to branch
7519 over it, setting up the pool register at the same time. */
7522 rtx_code_label
*pool_end
= gen_label_rtx ();
7524 rtx pat
= gen_main_base_31_large (base_reg
, pool
->label
, pool_end
);
7525 rtx_insn
*insn
= emit_jump_insn_after (pat
, pool
->pool_insn
);
7526 JUMP_LABEL (insn
) = pool_end
;
7527 INSN_ADDRESSES_NEW (insn
, -1);
7528 remove_insn (pool
->pool_insn
);
7530 insn
= emit_label_after (pool
->label
, insn
);
7531 INSN_ADDRESSES_NEW (insn
, -1);
7533 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
7534 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
7536 insn
= emit_label_after (pool_end
, pool
->pool_insn
);
7537 INSN_ADDRESSES_NEW (insn
, -1);
7539 s390_dump_pool (pool
, 1);
7543 /* Replace all literal pool references. */
7545 for (rtx_insn
*insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7548 replace_ltrel_base (&PATTERN (insn
));
7550 if (NONJUMP_INSN_P (insn
) || CALL_P (insn
))
7552 rtx addr
, pool_ref
= NULL_RTX
;
7553 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
7556 if (s390_execute_label (insn
))
7557 addr
= s390_find_execute (pool
, insn
);
7559 addr
= s390_find_constant (pool
, get_pool_constant (pool_ref
),
7560 get_pool_mode (pool_ref
));
7562 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
7563 INSN_CODE (insn
) = -1;
7569 /* Free the pool. */
7570 s390_free_pool (pool
);
7573 /* POOL holds the main literal pool as collected by s390_mainpool_start.
7574 We have decided we cannot use this pool, so revert all changes
7575 to the current function that were done by s390_mainpool_start. */
7577 s390_mainpool_cancel (struct constant_pool
*pool
)
7579 /* We didn't actually change the instruction stream, so simply
7580 free the pool memory. */
7581 s390_free_pool (pool
);
7585 /* Chunkify the literal pool. */
7587 #define S390_POOL_CHUNK_MIN 0xc00
7588 #define S390_POOL_CHUNK_MAX 0xe00
7590 static struct constant_pool
*
7591 s390_chunkify_start (void)
7593 struct constant_pool
*curr_pool
= NULL
, *pool_list
= NULL
;
7596 rtx pending_ltrel
= NULL_RTX
;
7599 rtx (*gen_reload_base
) (rtx
, rtx
) =
7600 TARGET_CPU_ZARCH
? gen_reload_base_64
: gen_reload_base_31
;
7603 /* We need correct insn addresses. */
7605 shorten_branches (get_insns ());
7607 /* Scan all insns and move literals to pool chunks. */
7609 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7611 bool section_switch_p
= false;
7613 /* Check for pending LTREL_BASE. */
7616 rtx ltrel_base
= find_ltrel_base (PATTERN (insn
));
7619 gcc_assert (ltrel_base
== pending_ltrel
);
7620 pending_ltrel
= NULL_RTX
;
7624 if (!TARGET_CPU_ZARCH
&& s390_execute_label (insn
))
7627 curr_pool
= s390_start_pool (&pool_list
, insn
);
7629 s390_add_execute (curr_pool
, insn
);
7630 s390_add_pool_insn (curr_pool
, insn
);
7632 else if (NONJUMP_INSN_P (insn
) || CALL_P (insn
))
7634 rtx pool_ref
= NULL_RTX
;
7635 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
7638 rtx constant
= get_pool_constant (pool_ref
);
7639 machine_mode mode
= get_pool_mode (pool_ref
);
7642 curr_pool
= s390_start_pool (&pool_list
, insn
);
7644 s390_add_constant (curr_pool
, constant
, mode
);
7645 s390_add_pool_insn (curr_pool
, insn
);
7647 /* Don't split the pool chunk between a LTREL_OFFSET load
7648 and the corresponding LTREL_BASE. */
7649 if (GET_CODE (constant
) == CONST
7650 && GET_CODE (XEXP (constant
, 0)) == UNSPEC
7651 && XINT (XEXP (constant
, 0), 1) == UNSPEC_LTREL_OFFSET
)
7653 gcc_assert (!pending_ltrel
);
7654 pending_ltrel
= pool_ref
;
7659 if (JUMP_P (insn
) || JUMP_TABLE_DATA_P (insn
) || LABEL_P (insn
))
7662 s390_add_pool_insn (curr_pool
, insn
);
7663 /* An LTREL_BASE must follow within the same basic block. */
7664 gcc_assert (!pending_ltrel
);
7668 switch (NOTE_KIND (insn
))
7670 case NOTE_INSN_SWITCH_TEXT_SECTIONS
:
7671 section_switch_p
= true;
7673 case NOTE_INSN_VAR_LOCATION
:
7674 case NOTE_INSN_CALL_ARG_LOCATION
:
7681 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn
)
7682 || INSN_ADDRESSES (INSN_UID (insn
)) == -1)
7685 if (TARGET_CPU_ZARCH
)
7687 if (curr_pool
->size
< S390_POOL_CHUNK_MAX
)
7690 s390_end_pool (curr_pool
, NULL
);
7695 int chunk_size
= INSN_ADDRESSES (INSN_UID (insn
))
7696 - INSN_ADDRESSES (INSN_UID (curr_pool
->first_insn
))
7699 /* We will later have to insert base register reload insns.
7700 Those will have an effect on code size, which we need to
7701 consider here. This calculation makes rather pessimistic
7702 worst-case assumptions. */
7706 if (chunk_size
< S390_POOL_CHUNK_MIN
7707 && curr_pool
->size
< S390_POOL_CHUNK_MIN
7708 && !section_switch_p
)
7711 /* Pool chunks can only be inserted after BARRIERs ... */
7712 if (BARRIER_P (insn
))
7714 s390_end_pool (curr_pool
, insn
);
7719 /* ... so if we don't find one in time, create one. */
7720 else if (chunk_size
> S390_POOL_CHUNK_MAX
7721 || curr_pool
->size
> S390_POOL_CHUNK_MAX
7722 || section_switch_p
)
7724 rtx_insn
*label
, *jump
, *barrier
, *next
, *prev
;
7726 if (!section_switch_p
)
7728 /* We can insert the barrier only after a 'real' insn. */
7729 if (! NONJUMP_INSN_P (insn
) && ! CALL_P (insn
))
7731 if (get_attr_length (insn
) == 0)
7733 /* Don't separate LTREL_BASE from the corresponding
7734 LTREL_OFFSET load. */
7741 next
= NEXT_INSN (insn
);
7745 && (NOTE_KIND (next
) == NOTE_INSN_VAR_LOCATION
7746 || NOTE_KIND (next
) == NOTE_INSN_CALL_ARG_LOCATION
));
7750 gcc_assert (!pending_ltrel
);
7752 /* The old pool has to end before the section switch
7753 note in order to make it part of the current
7755 insn
= PREV_INSN (insn
);
7758 label
= gen_label_rtx ();
7760 if (prev
&& NOTE_P (prev
))
7761 prev
= prev_nonnote_insn (prev
);
7763 jump
= emit_jump_insn_after_setloc (gen_jump (label
), insn
,
7764 INSN_LOCATION (prev
));
7766 jump
= emit_jump_insn_after_noloc (gen_jump (label
), insn
);
7767 barrier
= emit_barrier_after (jump
);
7768 insn
= emit_label_after (label
, barrier
);
7769 JUMP_LABEL (jump
) = label
;
7770 LABEL_NUSES (label
) = 1;
7772 INSN_ADDRESSES_NEW (jump
, -1);
7773 INSN_ADDRESSES_NEW (barrier
, -1);
7774 INSN_ADDRESSES_NEW (insn
, -1);
7776 s390_end_pool (curr_pool
, barrier
);
7784 s390_end_pool (curr_pool
, NULL
);
7785 gcc_assert (!pending_ltrel
);
7787 /* Find all labels that are branched into
7788 from an insn belonging to a different chunk. */
7790 far_labels
= BITMAP_ALLOC (NULL
);
7792 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7794 rtx_jump_table_data
*table
;
7796 /* Labels marked with LABEL_PRESERVE_P can be target
7797 of non-local jumps, so we have to mark them.
7798 The same holds for named labels.
7800 Don't do that, however, if it is the label before
7804 && (LABEL_PRESERVE_P (insn
) || LABEL_NAME (insn
)))
7806 rtx_insn
*vec_insn
= NEXT_INSN (insn
);
7807 if (! vec_insn
|| ! JUMP_TABLE_DATA_P (vec_insn
))
7808 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (insn
));
7810 /* Check potential targets in a table jump (casesi_jump). */
7811 else if (tablejump_p (insn
, NULL
, &table
))
7813 rtx vec_pat
= PATTERN (table
);
7814 int i
, diff_p
= GET_CODE (vec_pat
) == ADDR_DIFF_VEC
;
7816 for (i
= 0; i
< XVECLEN (vec_pat
, diff_p
); i
++)
7818 rtx label
= XEXP (XVECEXP (vec_pat
, diff_p
, i
), 0);
7820 if (s390_find_pool (pool_list
, label
)
7821 != s390_find_pool (pool_list
, insn
))
7822 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
7825 /* If we have a direct jump (conditional or unconditional),
7826 check all potential targets. */
7827 else if (JUMP_P (insn
))
7829 rtx pat
= PATTERN (insn
);
7831 if (GET_CODE (pat
) == PARALLEL
)
7832 pat
= XVECEXP (pat
, 0, 0);
7834 if (GET_CODE (pat
) == SET
)
7836 rtx label
= JUMP_LABEL (insn
);
7837 if (label
&& !ANY_RETURN_P (label
))
7839 if (s390_find_pool (pool_list
, label
)
7840 != s390_find_pool (pool_list
, insn
))
7841 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
7847 /* Insert base register reload insns before every pool. */
7849 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
7851 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
7853 rtx_insn
*insn
= curr_pool
->first_insn
;
7854 INSN_ADDRESSES_NEW (emit_insn_before (new_insn
, insn
), -1);
7857 /* Insert base register reload insns at every far label. */
7859 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7861 && bitmap_bit_p (far_labels
, CODE_LABEL_NUMBER (insn
)))
7863 struct constant_pool
*pool
= s390_find_pool (pool_list
, insn
);
7866 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
7868 INSN_ADDRESSES_NEW (emit_insn_after (new_insn
, insn
), -1);
7873 BITMAP_FREE (far_labels
);
7876 /* Recompute insn addresses. */
7878 init_insn_lengths ();
7879 shorten_branches (get_insns ());
7884 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
7885 After we have decided to use this list, finish implementing
7886 all changes to the current function as required. */
7889 s390_chunkify_finish (struct constant_pool
*pool_list
)
7891 struct constant_pool
*curr_pool
= NULL
;
7895 /* Replace all literal pool references. */
7897 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7900 replace_ltrel_base (&PATTERN (insn
));
7902 curr_pool
= s390_find_pool (pool_list
, insn
);
7906 if (NONJUMP_INSN_P (insn
) || CALL_P (insn
))
7908 rtx addr
, pool_ref
= NULL_RTX
;
7909 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
7912 if (s390_execute_label (insn
))
7913 addr
= s390_find_execute (curr_pool
, insn
);
7915 addr
= s390_find_constant (curr_pool
,
7916 get_pool_constant (pool_ref
),
7917 get_pool_mode (pool_ref
));
7919 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
7920 INSN_CODE (insn
) = -1;
7925 /* Dump out all literal pools. */
7927 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
7928 s390_dump_pool (curr_pool
, 0);
7930 /* Free pool list. */
7934 struct constant_pool
*next
= pool_list
->next
;
7935 s390_free_pool (pool_list
);
7940 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
7941 We have decided we cannot use this list, so revert all changes
7942 to the current function that were done by s390_chunkify_start. */
7945 s390_chunkify_cancel (struct constant_pool
*pool_list
)
7947 struct constant_pool
*curr_pool
= NULL
;
7950 /* Remove all pool placeholder insns. */
7952 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
7954 /* Did we insert an extra barrier? Remove it. */
7955 rtx_insn
*barrier
= PREV_INSN (curr_pool
->pool_insn
);
7956 rtx_insn
*jump
= barrier
? PREV_INSN (barrier
) : NULL
;
7957 rtx_insn
*label
= NEXT_INSN (curr_pool
->pool_insn
);
7959 if (jump
&& JUMP_P (jump
)
7960 && barrier
&& BARRIER_P (barrier
)
7961 && label
&& LABEL_P (label
)
7962 && GET_CODE (PATTERN (jump
)) == SET
7963 && SET_DEST (PATTERN (jump
)) == pc_rtx
7964 && GET_CODE (SET_SRC (PATTERN (jump
))) == LABEL_REF
7965 && XEXP (SET_SRC (PATTERN (jump
)), 0) == label
)
7968 remove_insn (barrier
);
7969 remove_insn (label
);
7972 remove_insn (curr_pool
->pool_insn
);
7975 /* Remove all base register reload insns. */
7977 for (insn
= get_insns (); insn
; )
7979 rtx_insn
*next_insn
= NEXT_INSN (insn
);
7981 if (NONJUMP_INSN_P (insn
)
7982 && GET_CODE (PATTERN (insn
)) == SET
7983 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC
7984 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPEC_RELOAD_BASE
)
7990 /* Free pool list. */
7994 struct constant_pool
*next
= pool_list
->next
;
7995 s390_free_pool (pool_list
);
8000 /* Output the constant pool entry EXP in mode MODE with alignment ALIGN. */
8003 s390_output_pool_entry (rtx exp
, machine_mode mode
, unsigned int align
)
8007 switch (GET_MODE_CLASS (mode
))
8010 case MODE_DECIMAL_FLOAT
:
8011 gcc_assert (GET_CODE (exp
) == CONST_DOUBLE
);
8013 REAL_VALUE_FROM_CONST_DOUBLE (r
, exp
);
8014 assemble_real (r
, mode
, align
);
8018 assemble_integer (exp
, GET_MODE_SIZE (mode
), align
, 1);
8019 mark_symbol_refs_as_used (exp
);
8022 case MODE_VECTOR_INT
:
8023 case MODE_VECTOR_FLOAT
:
8026 machine_mode inner_mode
;
8027 gcc_assert (GET_CODE (exp
) == CONST_VECTOR
);
8029 inner_mode
= GET_MODE_INNER (GET_MODE (exp
));
8030 for (i
= 0; i
< XVECLEN (exp
, 0); i
++)
8031 s390_output_pool_entry (XVECEXP (exp
, 0, i
),
8035 : GET_MODE_BITSIZE (inner_mode
));
8045 /* Return an RTL expression representing the value of the return address
8046 for the frame COUNT steps up from the current frame. FRAME is the
8047 frame pointer of that frame. */
8050 s390_return_addr_rtx (int count
, rtx frame ATTRIBUTE_UNUSED
)
8055 /* Without backchain, we fail for all but the current frame. */
8057 if (!TARGET_BACKCHAIN
&& count
> 0)
8060 /* For the current frame, we need to make sure the initial
8061 value of RETURN_REGNUM is actually saved. */
8065 /* On non-z architectures branch splitting could overwrite r14. */
8066 if (TARGET_CPU_ZARCH
)
8067 return get_hard_reg_initial_val (Pmode
, RETURN_REGNUM
);
8070 cfun_frame_layout
.save_return_addr_p
= true;
8071 return gen_rtx_MEM (Pmode
, return_address_pointer_rtx
);
8075 if (TARGET_PACKED_STACK
)
8076 offset
= -2 * UNITS_PER_LONG
;
8078 offset
= RETURN_REGNUM
* UNITS_PER_LONG
;
8080 addr
= plus_constant (Pmode
, frame
, offset
);
8081 addr
= memory_address (Pmode
, addr
);
8082 return gen_rtx_MEM (Pmode
, addr
);
8085 /* Return an RTL expression representing the back chain stored in
8086 the current stack frame. */
8089 s390_back_chain_rtx (void)
8093 gcc_assert (TARGET_BACKCHAIN
);
8095 if (TARGET_PACKED_STACK
)
8096 chain
= plus_constant (Pmode
, stack_pointer_rtx
,
8097 STACK_POINTER_OFFSET
- UNITS_PER_LONG
);
8099 chain
= stack_pointer_rtx
;
8101 chain
= gen_rtx_MEM (Pmode
, chain
);
8105 /* Find first call clobbered register unused in a function.
8106 This could be used as base register in a leaf function
8107 or for holding the return address before epilogue. */
8110 find_unused_clobbered_reg (void)
8113 for (i
= 0; i
< 6; i
++)
8114 if (!df_regs_ever_live_p (i
))
8120 /* Helper function for s390_regs_ever_clobbered. Sets the fields in DATA for all
8121 clobbered hard regs in SETREG. */
8124 s390_reg_clobbered_rtx (rtx setreg
, const_rtx set_insn ATTRIBUTE_UNUSED
, void *data
)
8126 char *regs_ever_clobbered
= (char *)data
;
8127 unsigned int i
, regno
;
8128 machine_mode mode
= GET_MODE (setreg
);
8130 if (GET_CODE (setreg
) == SUBREG
)
8132 rtx inner
= SUBREG_REG (setreg
);
8133 if (!GENERAL_REG_P (inner
) && !FP_REG_P (inner
))
8135 regno
= subreg_regno (setreg
);
8137 else if (GENERAL_REG_P (setreg
) || FP_REG_P (setreg
))
8138 regno
= REGNO (setreg
);
8143 i
< regno
+ HARD_REGNO_NREGS (regno
, mode
);
8145 regs_ever_clobbered
[i
] = 1;
8148 /* Walks through all basic blocks of the current function looking
8149 for clobbered hard regs using s390_reg_clobbered_rtx. The fields
8150 of the passed integer array REGS_EVER_CLOBBERED are set to one for
8151 each of those regs. */
8154 s390_regs_ever_clobbered (char regs_ever_clobbered
[])
8160 memset (regs_ever_clobbered
, 0, 32);
8162 /* For non-leaf functions we have to consider all call clobbered regs to be
8166 for (i
= 0; i
< 32; i
++)
8167 regs_ever_clobbered
[i
] = call_really_used_regs
[i
];
8170 /* Make the "magic" eh_return registers live if necessary. For regs_ever_live
8171 this work is done by liveness analysis (mark_regs_live_at_end).
8172 Special care is needed for functions containing landing pads. Landing pads
8173 may use the eh registers, but the code which sets these registers is not
8174 contained in that function. Hence s390_regs_ever_clobbered is not able to
8175 deal with this automatically. */
8176 if (crtl
->calls_eh_return
|| cfun
->machine
->has_landing_pad_p
)
8177 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; i
++)
8178 if (crtl
->calls_eh_return
8179 || (cfun
->machine
->has_landing_pad_p
8180 && df_regs_ever_live_p (EH_RETURN_DATA_REGNO (i
))))
8181 regs_ever_clobbered
[EH_RETURN_DATA_REGNO (i
)] = 1;
8183 /* For nonlocal gotos all call-saved registers have to be saved.
8184 This flag is also set for the unwinding code in libgcc.
8185 See expand_builtin_unwind_init. For regs_ever_live this is done by
8187 if (crtl
->saves_all_registers
)
8188 for (i
= 0; i
< 32; i
++)
8189 if (!call_really_used_regs
[i
])
8190 regs_ever_clobbered
[i
] = 1;
8192 FOR_EACH_BB_FN (cur_bb
, cfun
)
8194 FOR_BB_INSNS (cur_bb
, cur_insn
)
8198 if (!INSN_P (cur_insn
))
8201 pat
= PATTERN (cur_insn
);
8203 /* Ignore GPR restore insns. */
8204 if (epilogue_completed
&& RTX_FRAME_RELATED_P (cur_insn
))
8206 if (GET_CODE (pat
) == SET
8207 && GENERAL_REG_P (SET_DEST (pat
)))
8210 if (GET_MODE (SET_SRC (pat
)) == DImode
8211 && FP_REG_P (SET_SRC (pat
)))
8215 if (GET_CODE (SET_SRC (pat
)) == MEM
)
8220 if (GET_CODE (pat
) == PARALLEL
8221 && load_multiple_operation (pat
, VOIDmode
))
8226 s390_reg_clobbered_rtx
,
8227 regs_ever_clobbered
);
8232 /* Determine the frame area which actually has to be accessed
8233 in the function epilogue. The values are stored at the
8234 given pointers AREA_BOTTOM (address of the lowest used stack
8235 address) and AREA_TOP (address of the first item which does
8236 not belong to the stack frame). */
8239 s390_frame_area (int *area_bottom
, int *area_top
)
8246 if (cfun_frame_layout
.first_restore_gpr
!= -1)
8248 b
= (cfun_frame_layout
.gprs_offset
8249 + cfun_frame_layout
.first_restore_gpr
* UNITS_PER_LONG
);
8250 t
= b
+ (cfun_frame_layout
.last_restore_gpr
8251 - cfun_frame_layout
.first_restore_gpr
+ 1) * UNITS_PER_LONG
;
8254 if (TARGET_64BIT
&& cfun_save_high_fprs_p
)
8256 b
= MIN (b
, cfun_frame_layout
.f8_offset
);
8257 t
= MAX (t
, (cfun_frame_layout
.f8_offset
8258 + cfun_frame_layout
.high_fprs
* 8));
8263 if (cfun_fpr_save_p (FPR4_REGNUM
))
8265 b
= MIN (b
, cfun_frame_layout
.f4_offset
);
8266 t
= MAX (t
, cfun_frame_layout
.f4_offset
+ 8);
8268 if (cfun_fpr_save_p (FPR6_REGNUM
))
8270 b
= MIN (b
, cfun_frame_layout
.f4_offset
+ 8);
8271 t
= MAX (t
, cfun_frame_layout
.f4_offset
+ 16);
8277 /* Update gpr_save_slots in the frame layout trying to make use of
8278 FPRs as GPR save slots.
8279 This is a helper routine of s390_register_info. */
8282 s390_register_info_gprtofpr ()
8284 int save_reg_slot
= FPR0_REGNUM
;
8287 if (!TARGET_Z10
|| !TARGET_HARD_FLOAT
|| !crtl
->is_leaf
)
8290 for (i
= 15; i
>= 6; i
--)
8292 if (cfun_gpr_save_slot (i
) == 0)
8295 /* Advance to the next FP register which can be used as a
8297 while ((!call_really_used_regs
[save_reg_slot
]
8298 || df_regs_ever_live_p (save_reg_slot
)
8299 || cfun_fpr_save_p (save_reg_slot
))
8300 && FP_REGNO_P (save_reg_slot
))
8302 if (!FP_REGNO_P (save_reg_slot
))
8304 /* We only want to use ldgr/lgdr if we can get rid of
8305 stm/lm entirely. So undo the gpr slot allocation in
8306 case we ran out of FPR save slots. */
8307 for (j
= 6; j
<= 15; j
++)
8308 if (FP_REGNO_P (cfun_gpr_save_slot (j
)))
8309 cfun_gpr_save_slot (j
) = -1;
8312 cfun_gpr_save_slot (i
) = save_reg_slot
++;
8316 /* Set the bits in fpr_bitmap for FPRs which need to be saved due to
8318 This is a helper routine for s390_register_info. */
8321 s390_register_info_stdarg_fpr ()
8327 /* Save the FP argument regs for stdarg. f0, f2 for 31 bit and
8328 f0-f4 for 64 bit. */
8330 || !TARGET_HARD_FLOAT
8331 || !cfun
->va_list_fpr_size
8332 || crtl
->args
.info
.fprs
>= FP_ARG_NUM_REG
)
8335 min_fpr
= crtl
->args
.info
.fprs
;
8336 max_fpr
= min_fpr
+ cfun
->va_list_fpr_size
;
8337 if (max_fpr
> FP_ARG_NUM_REG
)
8338 max_fpr
= FP_ARG_NUM_REG
;
8340 for (i
= min_fpr
; i
< max_fpr
; i
++)
8341 cfun_set_fpr_save (i
+ FPR0_REGNUM
);
8344 /* Reserve the GPR save slots for GPRs which need to be saved due to
8346 This is a helper routine for s390_register_info. */
8349 s390_register_info_stdarg_gpr ()
8356 || !cfun
->va_list_gpr_size
8357 || crtl
->args
.info
.gprs
>= GP_ARG_NUM_REG
)
8360 min_gpr
= crtl
->args
.info
.gprs
;
8361 max_gpr
= min_gpr
+ cfun
->va_list_gpr_size
;
8362 if (max_gpr
> GP_ARG_NUM_REG
)
8363 max_gpr
= GP_ARG_NUM_REG
;
8365 for (i
= min_gpr
; i
< max_gpr
; i
++)
8366 cfun_gpr_save_slot (2 + i
) = -1;
8369 /* The GPR and FPR save slots in cfun->machine->frame_layout are set
8370 for registers which need to be saved in function prologue.
8371 This function can be used until the insns emitted for save/restore
8372 of the regs are visible in the RTL stream. */
8375 s390_register_info ()
8378 char clobbered_regs
[32];
8380 gcc_assert (!epilogue_completed
);
8382 if (reload_completed
)
8383 /* After reload we rely on our own routine to determine which
8384 registers need saving. */
8385 s390_regs_ever_clobbered (clobbered_regs
);
8387 /* During reload we use regs_ever_live as a base since reload
8388 does changes in there which we otherwise would not be aware
8390 for (i
= 0; i
< 32; i
++)
8391 clobbered_regs
[i
] = df_regs_ever_live_p (i
);
8393 for (i
= 0; i
< 32; i
++)
8394 clobbered_regs
[i
] = clobbered_regs
[i
] && !global_regs
[i
];
8396 /* Mark the call-saved FPRs which need to be saved.
8397 This needs to be done before checking the special GPRs since the
8398 stack pointer usage depends on whether high FPRs have to be saved
8400 cfun_frame_layout
.fpr_bitmap
= 0;
8401 cfun_frame_layout
.high_fprs
= 0;
8402 for (i
= FPR0_REGNUM
; i
<= FPR15_REGNUM
; i
++)
8403 if (clobbered_regs
[i
] && !call_really_used_regs
[i
])
8405 cfun_set_fpr_save (i
);
8406 if (i
>= FPR8_REGNUM
)
8407 cfun_frame_layout
.high_fprs
++;
8411 clobbered_regs
[PIC_OFFSET_TABLE_REGNUM
]
8412 |= !!df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM
);
8414 clobbered_regs
[BASE_REGNUM
]
8415 |= (cfun
->machine
->base_reg
8416 && REGNO (cfun
->machine
->base_reg
) == BASE_REGNUM
);
8418 clobbered_regs
[HARD_FRAME_POINTER_REGNUM
]
8419 |= !!frame_pointer_needed
;
8421 /* On pre z900 machines this might take until machine dependent
8423 save_return_addr_p will only be set on non-zarch machines so
8424 there is no risk that r14 goes into an FPR instead of a stack
8426 clobbered_regs
[RETURN_REGNUM
]
8428 || TARGET_TPF_PROFILING
8429 || cfun
->machine
->split_branches_pending_p
8430 || cfun_frame_layout
.save_return_addr_p
8431 || crtl
->calls_eh_return
);
8433 clobbered_regs
[STACK_POINTER_REGNUM
]
8435 || TARGET_TPF_PROFILING
8436 || cfun_save_high_fprs_p
8437 || get_frame_size () > 0
8438 || (reload_completed
&& cfun_frame_layout
.frame_size
> 0)
8439 || cfun
->calls_alloca
);
8441 memset (cfun_frame_layout
.gpr_save_slots
, 0, 16);
8443 for (i
= 6; i
< 16; i
++)
8444 if (clobbered_regs
[i
])
8445 cfun_gpr_save_slot (i
) = -1;
8447 s390_register_info_stdarg_fpr ();
8448 s390_register_info_gprtofpr ();
8450 /* First find the range of GPRs to be restored. Vararg regs don't
8451 need to be restored so we do it before assigning slots to the
8453 for (i
= 0; i
< 16 && cfun_gpr_save_slot (i
) != -1; i
++);
8454 for (j
= 15; j
> i
&& cfun_gpr_save_slot (j
) != -1; j
--);
8455 cfun_frame_layout
.first_restore_gpr
= (i
== 16) ? -1 : i
;
8456 cfun_frame_layout
.last_restore_gpr
= (i
== 16) ? -1 : j
;
8458 /* stdarg functions might need to save GPRs 2 to 6. This might
8459 override the GPR->FPR save decision made above for r6 since
8460 vararg regs must go to the stack. */
8461 s390_register_info_stdarg_gpr ();
8463 /* Now the range of GPRs which need saving. */
8464 for (i
= 0; i
< 16 && cfun_gpr_save_slot (i
) != -1; i
++);
8465 for (j
= 15; j
> i
&& cfun_gpr_save_slot (j
) != -1; j
--);
8466 cfun_frame_layout
.first_save_gpr
= (i
== 16) ? -1 : i
;
8467 cfun_frame_layout
.last_save_gpr
= (i
== 16) ? -1 : j
;
8470 /* This function is called by s390_optimize_prologue in order to get
8471 rid of unnecessary GPR save/restore instructions. The register info
8472 for the GPRs is re-computed and the ranges are re-calculated. */
8475 s390_optimize_register_info ()
8477 char clobbered_regs
[32];
8480 gcc_assert (epilogue_completed
);
8481 gcc_assert (!cfun
->machine
->split_branches_pending_p
);
8483 s390_regs_ever_clobbered (clobbered_regs
);
8485 for (i
= 0; i
< 32; i
++)
8486 clobbered_regs
[i
] = clobbered_regs
[i
] && !global_regs
[i
];
8488 /* There is still special treatment needed for cases invisible to
8489 s390_regs_ever_clobbered. */
8490 clobbered_regs
[RETURN_REGNUM
]
8491 |= (TARGET_TPF_PROFILING
8492 /* When expanding builtin_return_addr in ESA mode we do not
8493 know whether r14 will later be needed as scratch reg when
8494 doing branch splitting. So the builtin always accesses the
8495 r14 save slot and we need to stick to the save/restore
8496 decision for r14 even if it turns out that it didn't get
8498 || cfun_frame_layout
.save_return_addr_p
8499 || crtl
->calls_eh_return
);
8501 memset (cfun_frame_layout
.gpr_save_slots
, 0, 6);
8503 for (i
= 6; i
< 16; i
++)
8504 if (!clobbered_regs
[i
])
8505 cfun_gpr_save_slot (i
) = 0;
8507 for (i
= 0; i
< 16 && cfun_gpr_save_slot (i
) != -1; i
++);
8508 for (j
= 15; j
> i
&& cfun_gpr_save_slot (j
) != -1; j
--);
8509 cfun_frame_layout
.first_restore_gpr
= (i
== 16) ? -1 : i
;
8510 cfun_frame_layout
.last_restore_gpr
= (i
== 16) ? -1 : j
;
8512 s390_register_info_stdarg_gpr ();
8514 for (i
= 0; i
< 16 && cfun_gpr_save_slot (i
) != -1; i
++);
8515 for (j
= 15; j
> i
&& cfun_gpr_save_slot (j
) != -1; j
--);
8516 cfun_frame_layout
.first_save_gpr
= (i
== 16) ? -1 : i
;
8517 cfun_frame_layout
.last_save_gpr
= (i
== 16) ? -1 : j
;
8520 /* Fill cfun->machine with info about frame of current function. */
8523 s390_frame_info (void)
8525 HOST_WIDE_INT lowest_offset
;
8527 cfun_frame_layout
.first_save_gpr_slot
= cfun_frame_layout
.first_save_gpr
;
8528 cfun_frame_layout
.last_save_gpr_slot
= cfun_frame_layout
.last_save_gpr
;
8530 /* The va_arg builtin uses a constant distance of 16 *
8531 UNITS_PER_LONG (r0-r15) to reach the FPRs from the reg_save_area
8532 pointer. So even if we are going to save the stack pointer in an
8533 FPR we need the stack space in order to keep the offsets
8535 if (cfun
->stdarg
&& cfun_save_arg_fprs_p
)
8537 cfun_frame_layout
.last_save_gpr_slot
= STACK_POINTER_REGNUM
;
8539 if (cfun_frame_layout
.first_save_gpr_slot
== -1)
8540 cfun_frame_layout
.first_save_gpr_slot
= STACK_POINTER_REGNUM
;
8543 cfun_frame_layout
.frame_size
= get_frame_size ();
8544 if (!TARGET_64BIT
&& cfun_frame_layout
.frame_size
> 0x7fff0000)
8545 fatal_error (input_location
,
8546 "total size of local variables exceeds architecture limit");
8548 if (!TARGET_PACKED_STACK
)
8550 /* Fixed stack layout. */
8551 cfun_frame_layout
.backchain_offset
= 0;
8552 cfun_frame_layout
.f0_offset
= 16 * UNITS_PER_LONG
;
8553 cfun_frame_layout
.f4_offset
= cfun_frame_layout
.f0_offset
+ 2 * 8;
8554 cfun_frame_layout
.f8_offset
= -cfun_frame_layout
.high_fprs
* 8;
8555 cfun_frame_layout
.gprs_offset
= (cfun_frame_layout
.first_save_gpr_slot
8558 else if (TARGET_BACKCHAIN
)
8560 /* Kernel stack layout - packed stack, backchain, no float */
8561 gcc_assert (TARGET_SOFT_FLOAT
);
8562 cfun_frame_layout
.backchain_offset
= (STACK_POINTER_OFFSET
8565 /* The distance between the backchain and the return address
8566 save slot must not change. So we always need a slot for the
8567 stack pointer which resides in between. */
8568 cfun_frame_layout
.last_save_gpr_slot
= STACK_POINTER_REGNUM
;
8570 cfun_frame_layout
.gprs_offset
8571 = cfun_frame_layout
.backchain_offset
- cfun_gprs_save_area_size
;
8573 /* FPRs will not be saved. Nevertheless pick sane values to
8574 keep area calculations valid. */
8575 cfun_frame_layout
.f0_offset
=
8576 cfun_frame_layout
.f4_offset
=
8577 cfun_frame_layout
.f8_offset
= cfun_frame_layout
.gprs_offset
;
8583 /* Packed stack layout without backchain. */
8585 /* With stdarg FPRs need their dedicated slots. */
8586 num_fprs
= (TARGET_64BIT
&& cfun
->stdarg
? 2
8587 : (cfun_fpr_save_p (FPR4_REGNUM
) +
8588 cfun_fpr_save_p (FPR6_REGNUM
)));
8589 cfun_frame_layout
.f4_offset
= STACK_POINTER_OFFSET
- 8 * num_fprs
;
8591 num_fprs
= (cfun
->stdarg
? 2
8592 : (cfun_fpr_save_p (FPR0_REGNUM
)
8593 + cfun_fpr_save_p (FPR2_REGNUM
)));
8594 cfun_frame_layout
.f0_offset
= cfun_frame_layout
.f4_offset
- 8 * num_fprs
;
8596 cfun_frame_layout
.gprs_offset
8597 = cfun_frame_layout
.f0_offset
- cfun_gprs_save_area_size
;
8599 cfun_frame_layout
.f8_offset
= (cfun_frame_layout
.gprs_offset
8600 - cfun_frame_layout
.high_fprs
* 8);
8603 if (cfun_save_high_fprs_p
)
8604 cfun_frame_layout
.frame_size
+= cfun_frame_layout
.high_fprs
* 8;
8607 cfun_frame_layout
.frame_size
+= crtl
->outgoing_args_size
;
8609 /* In the following cases we have to allocate a STACK_POINTER_OFFSET
8610 sized area at the bottom of the stack. This is required also for
8611 leaf functions. When GCC generates a local stack reference it
8612 will always add STACK_POINTER_OFFSET to all these references. */
8614 && !TARGET_TPF_PROFILING
8615 && cfun_frame_layout
.frame_size
== 0
8616 && !cfun
->calls_alloca
)
8619 /* Calculate the number of bytes we have used in our own register
8620 save area. With the packed stack layout we can re-use the
8621 remaining bytes for normal stack elements. */
8623 if (TARGET_PACKED_STACK
)
8624 lowest_offset
= MIN (MIN (cfun_frame_layout
.f0_offset
,
8625 cfun_frame_layout
.f4_offset
),
8626 cfun_frame_layout
.gprs_offset
);
8630 if (TARGET_BACKCHAIN
)
8631 lowest_offset
= MIN (lowest_offset
, cfun_frame_layout
.backchain_offset
);
8633 cfun_frame_layout
.frame_size
+= STACK_POINTER_OFFSET
- lowest_offset
;
8635 /* If under 31 bit an odd number of gprs has to be saved we have to
8636 adjust the frame size to sustain 8 byte alignment of stack
8638 cfun_frame_layout
.frame_size
= ((cfun_frame_layout
.frame_size
+
8639 STACK_BOUNDARY
/ BITS_PER_UNIT
- 1)
8640 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1));
8643 /* Generate frame layout. Fills in register and frame data for the current
8644 function in cfun->machine. This routine can be called multiple times;
8645 it will re-do the complete frame layout every time. */
8648 s390_init_frame_layout (void)
8650 HOST_WIDE_INT frame_size
;
8653 gcc_assert (!reload_completed
);
8655 /* On S/390 machines, we may need to perform branch splitting, which
8656 will require both base and return address register. We have no
8657 choice but to assume we're going to need them until right at the
8658 end of the machine dependent reorg phase. */
8659 if (!TARGET_CPU_ZARCH
)
8660 cfun
->machine
->split_branches_pending_p
= true;
8664 frame_size
= cfun_frame_layout
.frame_size
;
8666 /* Try to predict whether we'll need the base register. */
8667 base_used
= cfun
->machine
->split_branches_pending_p
8668 || crtl
->uses_const_pool
8669 || (!DISP_IN_RANGE (frame_size
)
8670 && !CONST_OK_FOR_K (frame_size
));
8672 /* Decide which register to use as literal pool base. In small
8673 leaf functions, try to use an unused call-clobbered register
8674 as base register to avoid save/restore overhead. */
8676 cfun
->machine
->base_reg
= NULL_RTX
;
8677 else if (crtl
->is_leaf
&& !df_regs_ever_live_p (5))
8678 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, 5);
8680 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
8682 s390_register_info ();
8685 while (frame_size
!= cfun_frame_layout
.frame_size
);
8688 /* Remove the FPR clobbers from a tbegin insn if it can be proven that
8689 the TX is nonescaping. A transaction is considered escaping if
8690 there is at least one path from tbegin returning CC0 to the
8691 function exit block without an tend.
8693 The check so far has some limitations:
8694 - only single tbegin/tend BBs are supported
8695 - the first cond jump after tbegin must separate the CC0 path from ~CC0
8696 - when CC is copied to a GPR and the CC0 check is done with the GPR
8697 this is not supported
8701 s390_optimize_nonescaping_tx (void)
8703 const unsigned int CC0
= 1 << 3;
8704 basic_block tbegin_bb
= NULL
;
8705 basic_block tend_bb
= NULL
;
8710 rtx_insn
*tbegin_insn
= NULL
;
8712 if (!cfun
->machine
->tbegin_p
)
8715 for (bb_index
= 0; bb_index
< n_basic_blocks_for_fn (cfun
); bb_index
++)
8717 bb
= BASIC_BLOCK_FOR_FN (cfun
, bb_index
);
8722 FOR_BB_INSNS (bb
, insn
)
8724 rtx ite
, cc
, pat
, target
;
8725 unsigned HOST_WIDE_INT mask
;
8727 if (!INSN_P (insn
) || INSN_CODE (insn
) <= 0)
8730 pat
= PATTERN (insn
);
8732 if (GET_CODE (pat
) == PARALLEL
)
8733 pat
= XVECEXP (pat
, 0, 0);
8735 if (GET_CODE (pat
) != SET
8736 || GET_CODE (SET_SRC (pat
)) != UNSPEC_VOLATILE
)
8739 if (XINT (SET_SRC (pat
), 1) == UNSPECV_TBEGIN
)
8745 /* Just return if the tbegin doesn't have clobbers. */
8746 if (GET_CODE (PATTERN (insn
)) != PARALLEL
)
8749 if (tbegin_bb
!= NULL
)
8752 /* Find the next conditional jump. */
8753 for (tmp
= NEXT_INSN (insn
);
8755 tmp
= NEXT_INSN (tmp
))
8757 if (reg_set_p (gen_rtx_REG (CCmode
, CC_REGNUM
), tmp
))
8762 ite
= SET_SRC (PATTERN (tmp
));
8763 if (GET_CODE (ite
) != IF_THEN_ELSE
)
8766 cc
= XEXP (XEXP (ite
, 0), 0);
8767 if (!REG_P (cc
) || !CC_REGNO_P (REGNO (cc
))
8768 || GET_MODE (cc
) != CCRAWmode
8769 || GET_CODE (XEXP (XEXP (ite
, 0), 1)) != CONST_INT
)
8772 if (bb
->succs
->length () != 2)
8775 mask
= INTVAL (XEXP (XEXP (ite
, 0), 1));
8776 if (GET_CODE (XEXP (ite
, 0)) == NE
)
8780 target
= XEXP (ite
, 1);
8781 else if (mask
== (CC0
^ 0xf))
8782 target
= XEXP (ite
, 2);
8790 ei
= ei_start (bb
->succs
);
8791 e1
= ei_safe_edge (ei
);
8793 e2
= ei_safe_edge (ei
);
8795 if (e2
->flags
& EDGE_FALLTHRU
)
8798 e1
= ei_safe_edge (ei
);
8801 if (!(e1
->flags
& EDGE_FALLTHRU
))
8804 tbegin_bb
= (target
== pc_rtx
) ? e1
->dest
: e2
->dest
;
8806 if (tmp
== BB_END (bb
))
8811 if (XINT (SET_SRC (pat
), 1) == UNSPECV_TEND
)
8813 if (tend_bb
!= NULL
)
8820 /* Either we successfully remove the FPR clobbers here or we are not
8821 able to do anything for this TX. Both cases don't qualify for
8823 cfun
->machine
->tbegin_p
= false;
8825 if (tbegin_bb
== NULL
|| tend_bb
== NULL
)
8828 calculate_dominance_info (CDI_POST_DOMINATORS
);
8829 result
= dominated_by_p (CDI_POST_DOMINATORS
, tbegin_bb
, tend_bb
);
8830 free_dominance_info (CDI_POST_DOMINATORS
);
8835 PATTERN (tbegin_insn
) = gen_rtx_PARALLEL (VOIDmode
,
8837 XVECEXP (PATTERN (tbegin_insn
), 0, 0),
8838 XVECEXP (PATTERN (tbegin_insn
), 0, 1)));
8839 INSN_CODE (tbegin_insn
) = -1;
8840 df_insn_rescan (tbegin_insn
);
8845 /* Return true if it is legal to put a value with MODE into REGNO. */
8848 s390_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
8850 if (!TARGET_VX
&& VECTOR_NOFP_REGNO_P (regno
))
8853 switch (REGNO_REG_CLASS (regno
))
8856 return ((GET_MODE_CLASS (mode
) == MODE_INT
8857 && s390_class_max_nregs (VEC_REGS
, mode
) == 1)
8859 || s390_vector_mode_supported_p (mode
));
8863 && ((GET_MODE_CLASS (mode
) == MODE_INT
8864 && s390_class_max_nregs (FP_REGS
, mode
) == 1)
8866 || s390_vector_mode_supported_p (mode
)))
8869 if (REGNO_PAIR_OK (regno
, mode
))
8871 if (mode
== SImode
|| mode
== DImode
)
8874 if (FLOAT_MODE_P (mode
) && GET_MODE_CLASS (mode
) != MODE_VECTOR_FLOAT
)
8879 if (FRAME_REGNO_P (regno
) && mode
== Pmode
)
8884 if (REGNO_PAIR_OK (regno
, mode
))
8887 || (mode
!= TFmode
&& mode
!= TCmode
&& mode
!= TDmode
))
8892 if (GET_MODE_CLASS (mode
) == MODE_CC
)
8896 if (REGNO_PAIR_OK (regno
, mode
))
8898 if (mode
== SImode
|| mode
== Pmode
)
8909 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
8912 s390_hard_regno_rename_ok (unsigned int old_reg
, unsigned int new_reg
)
8914 /* Once we've decided upon a register to use as base register, it must
8915 no longer be used for any other purpose. */
8916 if (cfun
->machine
->base_reg
)
8917 if (REGNO (cfun
->machine
->base_reg
) == old_reg
8918 || REGNO (cfun
->machine
->base_reg
) == new_reg
)
8921 /* Prevent regrename from using call-saved regs which haven't
8922 actually been saved. This is necessary since regrename assumes
8923 the backend save/restore decisions are based on
8924 df_regs_ever_live. Since we have our own routine we have to tell
8925 regrename manually about it. */
8926 if (GENERAL_REGNO_P (new_reg
)
8927 && !call_really_used_regs
[new_reg
]
8928 && cfun_gpr_save_slot (new_reg
) == 0)
8934 /* Return nonzero if register REGNO can be used as a scratch register
8938 s390_hard_regno_scratch_ok (unsigned int regno
)
8940 /* See s390_hard_regno_rename_ok. */
8941 if (GENERAL_REGNO_P (regno
)
8942 && !call_really_used_regs
[regno
]
8943 && cfun_gpr_save_slot (regno
) == 0)
8949 /* Maximum number of registers to represent a value of mode MODE
8950 in a register of class RCLASS. */
8953 s390_class_max_nregs (enum reg_class rclass
, machine_mode mode
)
8956 bool reg_pair_required_p
= false;
8962 reg_size
= TARGET_VX
? 16 : 8;
8964 /* TF and TD modes would fit into a VR but we put them into a
8965 register pair since we do not have 128bit FP instructions on
8968 && SCALAR_FLOAT_MODE_P (mode
)
8969 && GET_MODE_SIZE (mode
) >= 16)
8970 reg_pair_required_p
= true;
8972 /* Even if complex types would fit into a single FPR/VR we force
8973 them into a register pair to deal with the parts more easily.
8974 (FIXME: What about complex ints?) */
8975 if (GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
)
8976 reg_pair_required_p
= true;
8982 reg_size
= UNITS_PER_WORD
;
8986 if (reg_pair_required_p
)
8987 return 2 * ((GET_MODE_SIZE (mode
) / 2 + reg_size
- 1) / reg_size
);
8989 return (GET_MODE_SIZE (mode
) + reg_size
- 1) / reg_size
;
8992 /* Return TRUE if changing mode from FROM to TO should not be allowed
8993 for register class CLASS. */
8996 s390_cannot_change_mode_class (machine_mode from_mode
,
8997 machine_mode to_mode
,
8998 enum reg_class rclass
)
9000 machine_mode small_mode
;
9001 machine_mode big_mode
;
9003 if (GET_MODE_SIZE (from_mode
) == GET_MODE_SIZE (to_mode
))
9006 if (GET_MODE_SIZE (from_mode
) < GET_MODE_SIZE (to_mode
))
9008 small_mode
= from_mode
;
9013 small_mode
= to_mode
;
9014 big_mode
= from_mode
;
9017 /* Values residing in VRs are little-endian style. All modes are
9018 placed left-aligned in an VR. This means that we cannot allow
9019 switching between modes with differing sizes. Also if the vector
9020 facility is available we still place TFmode values in VR register
9021 pairs, since the only instructions we have operating on TFmodes
9022 only deal with register pairs. Therefore we have to allow DFmode
9023 subregs of TFmodes to enable the TFmode splitters. */
9024 if (reg_classes_intersect_p (VEC_REGS
, rclass
)
9025 && (GET_MODE_SIZE (small_mode
) < 8
9026 || s390_class_max_nregs (VEC_REGS
, big_mode
) == 1))
9029 /* Likewise for access registers, since they have only half the
9030 word size on 64-bit. */
9031 if (reg_classes_intersect_p (ACCESS_REGS
, rclass
))
9037 /* Return true if we use LRA instead of reload pass. */
9041 return s390_lra_flag
;
9044 /* Return true if register FROM can be eliminated via register TO. */
9047 s390_can_eliminate (const int from
, const int to
)
9049 /* On zSeries machines, we have not marked the base register as fixed.
9050 Instead, we have an elimination rule BASE_REGNUM -> BASE_REGNUM.
9051 If a function requires the base register, we say here that this
9052 elimination cannot be performed. This will cause reload to free
9053 up the base register (as if it were fixed). On the other hand,
9054 if the current function does *not* require the base register, we
9055 say here the elimination succeeds, which in turn allows reload
9056 to allocate the base register for any other purpose. */
9057 if (from
== BASE_REGNUM
&& to
== BASE_REGNUM
)
9059 if (TARGET_CPU_ZARCH
)
9061 s390_init_frame_layout ();
9062 return cfun
->machine
->base_reg
== NULL_RTX
;
9068 /* Everything else must point into the stack frame. */
9069 gcc_assert (to
== STACK_POINTER_REGNUM
9070 || to
== HARD_FRAME_POINTER_REGNUM
);
9072 gcc_assert (from
== FRAME_POINTER_REGNUM
9073 || from
== ARG_POINTER_REGNUM
9074 || from
== RETURN_ADDRESS_POINTER_REGNUM
);
9076 /* Make sure we actually saved the return address. */
9077 if (from
== RETURN_ADDRESS_POINTER_REGNUM
)
9078 if (!crtl
->calls_eh_return
9080 && !cfun_frame_layout
.save_return_addr_p
)
9086 /* Return offset between register FROM and TO initially after prolog. */
9089 s390_initial_elimination_offset (int from
, int to
)
9091 HOST_WIDE_INT offset
;
9093 /* ??? Why are we called for non-eliminable pairs? */
9094 if (!s390_can_eliminate (from
, to
))
9099 case FRAME_POINTER_REGNUM
:
9100 offset
= (get_frame_size()
9101 + STACK_POINTER_OFFSET
9102 + crtl
->outgoing_args_size
);
9105 case ARG_POINTER_REGNUM
:
9106 s390_init_frame_layout ();
9107 offset
= cfun_frame_layout
.frame_size
+ STACK_POINTER_OFFSET
;
9110 case RETURN_ADDRESS_POINTER_REGNUM
:
9111 s390_init_frame_layout ();
9113 if (cfun_frame_layout
.first_save_gpr_slot
== -1)
9115 /* If it turns out that for stdarg nothing went into the reg
9116 save area we also do not need the return address
9118 if (cfun
->stdarg
&& !cfun_save_arg_fprs_p
)
9124 /* In order to make the following work it is not necessary for
9125 r14 to have a save slot. It is sufficient if one other GPR
9126 got one. Since the GPRs are always stored without gaps we
9127 are able to calculate where the r14 save slot would
9129 offset
= (cfun_frame_layout
.frame_size
+ cfun_frame_layout
.gprs_offset
+
9130 (RETURN_REGNUM
- cfun_frame_layout
.first_save_gpr_slot
) *
9145 /* Emit insn to save fpr REGNUM at offset OFFSET relative
9146 to register BASE. Return generated insn. */
9149 save_fpr (rtx base
, int offset
, int regnum
)
9152 addr
= gen_rtx_MEM (DFmode
, plus_constant (Pmode
, base
, offset
));
9154 if (regnum
>= 16 && regnum
<= (16 + FP_ARG_NUM_REG
))
9155 set_mem_alias_set (addr
, get_varargs_alias_set ());
9157 set_mem_alias_set (addr
, get_frame_alias_set ());
9159 return emit_move_insn (addr
, gen_rtx_REG (DFmode
, regnum
));
9162 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
9163 to register BASE. Return generated insn. */
9166 restore_fpr (rtx base
, int offset
, int regnum
)
9169 addr
= gen_rtx_MEM (DFmode
, plus_constant (Pmode
, base
, offset
));
9170 set_mem_alias_set (addr
, get_frame_alias_set ());
9172 return emit_move_insn (gen_rtx_REG (DFmode
, regnum
), addr
);
9175 /* Return true if REGNO is a global register, but not one
9176 of the special ones that need to be saved/restored in anyway. */
9179 global_not_special_regno_p (int regno
)
9181 return (global_regs
[regno
]
9182 /* These registers are special and need to be
9183 restored in any case. */
9184 && !(regno
== STACK_POINTER_REGNUM
9185 || regno
== RETURN_REGNUM
9186 || regno
== BASE_REGNUM
9187 || (flag_pic
&& regno
== (int)PIC_OFFSET_TABLE_REGNUM
)));
9190 /* Generate insn to save registers FIRST to LAST into
9191 the register save area located at offset OFFSET
9192 relative to register BASE. */
9195 save_gprs (rtx base
, int offset
, int first
, int last
)
9197 rtx addr
, insn
, note
;
9200 addr
= plus_constant (Pmode
, base
, offset
);
9201 addr
= gen_rtx_MEM (Pmode
, addr
);
9203 set_mem_alias_set (addr
, get_frame_alias_set ());
9205 /* Special-case single register. */
9209 insn
= gen_movdi (addr
, gen_rtx_REG (Pmode
, first
));
9211 insn
= gen_movsi (addr
, gen_rtx_REG (Pmode
, first
));
9213 if (!global_not_special_regno_p (first
))
9214 RTX_FRAME_RELATED_P (insn
) = 1;
9219 insn
= gen_store_multiple (addr
,
9220 gen_rtx_REG (Pmode
, first
),
9221 GEN_INT (last
- first
+ 1));
9223 if (first
<= 6 && cfun
->stdarg
)
9224 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
9226 rtx mem
= XEXP (XVECEXP (PATTERN (insn
), 0, i
), 0);
9229 set_mem_alias_set (mem
, get_varargs_alias_set ());
9232 /* We need to set the FRAME_RELATED flag on all SETs
9233 inside the store-multiple pattern.
9235 However, we must not emit DWARF records for registers 2..5
9236 if they are stored for use by variable arguments ...
9238 ??? Unfortunately, it is not enough to simply not the
9239 FRAME_RELATED flags for those SETs, because the first SET
9240 of the PARALLEL is always treated as if it had the flag
9241 set, even if it does not. Therefore we emit a new pattern
9242 without those registers as REG_FRAME_RELATED_EXPR note. */
9244 if (first
>= 6 && !global_not_special_regno_p (first
))
9246 rtx pat
= PATTERN (insn
);
9248 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
9249 if (GET_CODE (XVECEXP (pat
, 0, i
)) == SET
9250 && !global_not_special_regno_p (REGNO (SET_SRC (XVECEXP (pat
,
9252 RTX_FRAME_RELATED_P (XVECEXP (pat
, 0, i
)) = 1;
9254 RTX_FRAME_RELATED_P (insn
) = 1;
9260 for (start
= first
>= 6 ? first
: 6; start
<= last
; start
++)
9261 if (!global_not_special_regno_p (start
))
9267 addr
= plus_constant (Pmode
, base
,
9268 offset
+ (start
- first
) * UNITS_PER_LONG
);
9273 note
= gen_movdi (gen_rtx_MEM (Pmode
, addr
),
9274 gen_rtx_REG (Pmode
, start
));
9276 note
= gen_movsi (gen_rtx_MEM (Pmode
, addr
),
9277 gen_rtx_REG (Pmode
, start
));
9278 note
= PATTERN (note
);
9280 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note
);
9281 RTX_FRAME_RELATED_P (insn
) = 1;
9286 note
= gen_store_multiple (gen_rtx_MEM (Pmode
, addr
),
9287 gen_rtx_REG (Pmode
, start
),
9288 GEN_INT (last
- start
+ 1));
9289 note
= PATTERN (note
);
9291 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note
);
9293 for (i
= 0; i
< XVECLEN (note
, 0); i
++)
9294 if (GET_CODE (XVECEXP (note
, 0, i
)) == SET
9295 && !global_not_special_regno_p (REGNO (SET_SRC (XVECEXP (note
,
9297 RTX_FRAME_RELATED_P (XVECEXP (note
, 0, i
)) = 1;
9299 RTX_FRAME_RELATED_P (insn
) = 1;
9305 /* Generate insn to restore registers FIRST to LAST from
9306 the register save area located at offset OFFSET
9307 relative to register BASE. */
9310 restore_gprs (rtx base
, int offset
, int first
, int last
)
9314 addr
= plus_constant (Pmode
, base
, offset
);
9315 addr
= gen_rtx_MEM (Pmode
, addr
);
9316 set_mem_alias_set (addr
, get_frame_alias_set ());
9318 /* Special-case single register. */
9322 insn
= gen_movdi (gen_rtx_REG (Pmode
, first
), addr
);
9324 insn
= gen_movsi (gen_rtx_REG (Pmode
, first
), addr
);
9326 RTX_FRAME_RELATED_P (insn
) = 1;
9330 insn
= gen_load_multiple (gen_rtx_REG (Pmode
, first
),
9332 GEN_INT (last
- first
+ 1));
9333 RTX_FRAME_RELATED_P (insn
) = 1;
9337 /* Return insn sequence to load the GOT register. */
9339 static GTY(()) rtx got_symbol
;
9341 s390_load_got (void)
9345 /* We cannot use pic_offset_table_rtx here since we use this
9346 function also for non-pic if __tls_get_offset is called and in
9347 that case PIC_OFFSET_TABLE_REGNUM as well as pic_offset_table_rtx
9349 rtx got_rtx
= gen_rtx_REG (Pmode
, 12);
9353 got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
9354 SYMBOL_REF_FLAGS (got_symbol
) = SYMBOL_FLAG_LOCAL
;
9359 if (TARGET_CPU_ZARCH
)
9361 emit_move_insn (got_rtx
, got_symbol
);
9367 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, got_symbol
),
9368 UNSPEC_LTREL_OFFSET
);
9369 offset
= gen_rtx_CONST (Pmode
, offset
);
9370 offset
= force_const_mem (Pmode
, offset
);
9372 emit_move_insn (got_rtx
, offset
);
9374 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, XEXP (offset
, 0)),
9376 offset
= gen_rtx_PLUS (Pmode
, got_rtx
, offset
);
9378 emit_move_insn (got_rtx
, offset
);
9381 insns
= get_insns ();
9386 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
9387 and the change to the stack pointer. */
9390 s390_emit_stack_tie (void)
9392 rtx mem
= gen_frame_mem (BLKmode
,
9393 gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
));
9395 emit_insn (gen_stack_tie (mem
));
9398 /* Copy GPRS into FPR save slots. */
9401 s390_save_gprs_to_fprs (void)
9405 if (!TARGET_Z10
|| !TARGET_HARD_FLOAT
|| !crtl
->is_leaf
)
9408 for (i
= 6; i
< 16; i
++)
9410 if (FP_REGNO_P (cfun_gpr_save_slot (i
)))
9413 emit_move_insn (gen_rtx_REG (DImode
, cfun_gpr_save_slot (i
)),
9414 gen_rtx_REG (DImode
, i
));
9415 RTX_FRAME_RELATED_P (insn
) = 1;
9420 /* Restore GPRs from FPR save slots. */
9423 s390_restore_gprs_from_fprs (void)
9427 if (!TARGET_Z10
|| !TARGET_HARD_FLOAT
|| !crtl
->is_leaf
)
9430 for (i
= 6; i
< 16; i
++)
9432 if (FP_REGNO_P (cfun_gpr_save_slot (i
)))
9435 emit_move_insn (gen_rtx_REG (DImode
, i
),
9436 gen_rtx_REG (DImode
, cfun_gpr_save_slot (i
)));
9437 df_set_regs_ever_live (i
, true);
9438 add_reg_note (insn
, REG_CFA_RESTORE
, gen_rtx_REG (DImode
, i
));
9439 if (i
== STACK_POINTER_REGNUM
)
9440 add_reg_note (insn
, REG_CFA_DEF_CFA
,
9441 plus_constant (Pmode
, stack_pointer_rtx
,
9442 STACK_POINTER_OFFSET
));
9443 RTX_FRAME_RELATED_P (insn
) = 1;
9449 /* A pass run immediately before shrink-wrapping and prologue and epilogue
9454 const pass_data pass_data_s390_early_mach
=
9456 RTL_PASS
, /* type */
9457 "early_mach", /* name */
9458 OPTGROUP_NONE
, /* optinfo_flags */
9459 TV_MACH_DEP
, /* tv_id */
9460 0, /* properties_required */
9461 0, /* properties_provided */
9462 0, /* properties_destroyed */
9463 0, /* todo_flags_start */
9464 ( TODO_df_verify
| TODO_df_finish
), /* todo_flags_finish */
9467 class pass_s390_early_mach
: public rtl_opt_pass
9470 pass_s390_early_mach (gcc::context
*ctxt
)
9471 : rtl_opt_pass (pass_data_s390_early_mach
, ctxt
)
9474 /* opt_pass methods: */
9475 virtual unsigned int execute (function
*);
9477 }; // class pass_s390_early_mach
9480 pass_s390_early_mach::execute (function
*fun
)
9484 /* Try to get rid of the FPR clobbers. */
9485 s390_optimize_nonescaping_tx ();
9487 /* Re-compute register info. */
9488 s390_register_info ();
9490 /* If we're using a base register, ensure that it is always valid for
9491 the first non-prologue instruction. */
9492 if (fun
->machine
->base_reg
)
9493 emit_insn_at_entry (gen_main_pool (fun
->machine
->base_reg
));
9495 /* Annotate all constant pool references to let the scheduler know
9496 they implicitly use the base register. */
9497 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
9500 annotate_constant_pool_refs (&PATTERN (insn
));
9501 df_insn_rescan (insn
);
9508 /* Expand the prologue into a bunch of separate insns. */
9511 s390_emit_prologue (void)
9519 /* Choose best register to use for temp use within prologue.
9520 See below for why TPF must use the register 1. */
9522 if (!has_hard_reg_initial_val (Pmode
, RETURN_REGNUM
)
9524 && !TARGET_TPF_PROFILING
)
9525 temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
9527 temp_reg
= gen_rtx_REG (Pmode
, 1);
9529 s390_save_gprs_to_fprs ();
9531 /* Save call saved gprs. */
9532 if (cfun_frame_layout
.first_save_gpr
!= -1)
9534 insn
= save_gprs (stack_pointer_rtx
,
9535 cfun_frame_layout
.gprs_offset
+
9536 UNITS_PER_LONG
* (cfun_frame_layout
.first_save_gpr
9537 - cfun_frame_layout
.first_save_gpr_slot
),
9538 cfun_frame_layout
.first_save_gpr
,
9539 cfun_frame_layout
.last_save_gpr
);
9543 /* Dummy insn to mark literal pool slot. */
9545 if (cfun
->machine
->base_reg
)
9546 emit_insn (gen_main_pool (cfun
->machine
->base_reg
));
9548 offset
= cfun_frame_layout
.f0_offset
;
9550 /* Save f0 and f2. */
9551 for (i
= FPR0_REGNUM
; i
<= FPR0_REGNUM
+ 1; i
++)
9553 if (cfun_fpr_save_p (i
))
9555 save_fpr (stack_pointer_rtx
, offset
, i
);
9558 else if (!TARGET_PACKED_STACK
|| cfun
->stdarg
)
9562 /* Save f4 and f6. */
9563 offset
= cfun_frame_layout
.f4_offset
;
9564 for (i
= FPR4_REGNUM
; i
<= FPR4_REGNUM
+ 1; i
++)
9566 if (cfun_fpr_save_p (i
))
9568 insn
= save_fpr (stack_pointer_rtx
, offset
, i
);
9571 /* If f4 and f6 are call clobbered they are saved due to
9572 stdargs and therefore are not frame related. */
9573 if (!call_really_used_regs
[i
])
9574 RTX_FRAME_RELATED_P (insn
) = 1;
9576 else if (!TARGET_PACKED_STACK
|| call_really_used_regs
[i
])
9580 if (TARGET_PACKED_STACK
9581 && cfun_save_high_fprs_p
9582 && cfun_frame_layout
.f8_offset
+ cfun_frame_layout
.high_fprs
* 8 > 0)
9584 offset
= (cfun_frame_layout
.f8_offset
9585 + (cfun_frame_layout
.high_fprs
- 1) * 8);
9587 for (i
= FPR15_REGNUM
; i
>= FPR8_REGNUM
&& offset
>= 0; i
--)
9588 if (cfun_fpr_save_p (i
))
9590 insn
= save_fpr (stack_pointer_rtx
, offset
, i
);
9592 RTX_FRAME_RELATED_P (insn
) = 1;
9595 if (offset
>= cfun_frame_layout
.f8_offset
)
9599 if (!TARGET_PACKED_STACK
)
9600 next_fpr
= cfun_save_high_fprs_p
? FPR15_REGNUM
: 0;
9602 if (flag_stack_usage_info
)
9603 current_function_static_stack_size
= cfun_frame_layout
.frame_size
;
9605 /* Decrement stack pointer. */
9607 if (cfun_frame_layout
.frame_size
> 0)
9609 rtx frame_off
= GEN_INT (-cfun_frame_layout
.frame_size
);
9612 if (s390_stack_size
)
9614 HOST_WIDE_INT stack_guard
;
9616 if (s390_stack_guard
)
9617 stack_guard
= s390_stack_guard
;
9620 /* If no value for stack guard is provided the smallest power of 2
9621 larger than the current frame size is chosen. */
9623 while (stack_guard
< cfun_frame_layout
.frame_size
)
9627 if (cfun_frame_layout
.frame_size
>= s390_stack_size
)
9629 warning (0, "frame size of function %qs is %wd"
9630 " bytes exceeding user provided stack limit of "
9632 "An unconditional trap is added.",
9633 current_function_name(), cfun_frame_layout
.frame_size
,
9635 emit_insn (gen_trap ());
9639 /* stack_guard has to be smaller than s390_stack_size.
9640 Otherwise we would emit an AND with zero which would
9641 not match the test under mask pattern. */
9642 if (stack_guard
>= s390_stack_size
)
9644 warning (0, "frame size of function %qs is %wd"
9645 " bytes which is more than half the stack size. "
9646 "The dynamic check would not be reliable. "
9647 "No check emitted for this function.",
9648 current_function_name(),
9649 cfun_frame_layout
.frame_size
);
9653 HOST_WIDE_INT stack_check_mask
= ((s390_stack_size
- 1)
9654 & ~(stack_guard
- 1));
9656 rtx t
= gen_rtx_AND (Pmode
, stack_pointer_rtx
,
9657 GEN_INT (stack_check_mask
));
9659 emit_insn (gen_ctrapdi4 (gen_rtx_EQ (VOIDmode
,
9661 t
, const0_rtx
, const0_rtx
));
9663 emit_insn (gen_ctrapsi4 (gen_rtx_EQ (VOIDmode
,
9665 t
, const0_rtx
, const0_rtx
));
9670 if (s390_warn_framesize
> 0
9671 && cfun_frame_layout
.frame_size
>= s390_warn_framesize
)
9672 warning (0, "frame size of %qs is %wd bytes",
9673 current_function_name (), cfun_frame_layout
.frame_size
);
9675 if (s390_warn_dynamicstack_p
&& cfun
->calls_alloca
)
9676 warning (0, "%qs uses dynamic stack allocation", current_function_name ());
9678 /* Save incoming stack pointer into temp reg. */
9679 if (TARGET_BACKCHAIN
|| next_fpr
)
9680 insn
= emit_insn (gen_move_insn (temp_reg
, stack_pointer_rtx
));
9682 /* Subtract frame size from stack pointer. */
9684 if (DISP_IN_RANGE (INTVAL (frame_off
)))
9686 insn
= gen_rtx_SET (stack_pointer_rtx
,
9687 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
9689 insn
= emit_insn (insn
);
9693 if (!CONST_OK_FOR_K (INTVAL (frame_off
)))
9694 frame_off
= force_const_mem (Pmode
, frame_off
);
9696 insn
= emit_insn (gen_add2_insn (stack_pointer_rtx
, frame_off
));
9697 annotate_constant_pool_refs (&PATTERN (insn
));
9700 RTX_FRAME_RELATED_P (insn
) = 1;
9701 real_frame_off
= GEN_INT (-cfun_frame_layout
.frame_size
);
9702 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
,
9703 gen_rtx_SET (stack_pointer_rtx
,
9704 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
9707 /* Set backchain. */
9709 if (TARGET_BACKCHAIN
)
9711 if (cfun_frame_layout
.backchain_offset
)
9712 addr
= gen_rtx_MEM (Pmode
,
9713 plus_constant (Pmode
, stack_pointer_rtx
,
9714 cfun_frame_layout
.backchain_offset
));
9716 addr
= gen_rtx_MEM (Pmode
, stack_pointer_rtx
);
9717 set_mem_alias_set (addr
, get_frame_alias_set ());
9718 insn
= emit_insn (gen_move_insn (addr
, temp_reg
));
9721 /* If we support non-call exceptions (e.g. for Java),
9722 we need to make sure the backchain pointer is set up
9723 before any possibly trapping memory access. */
9724 if (TARGET_BACKCHAIN
&& cfun
->can_throw_non_call_exceptions
)
9726 addr
= gen_rtx_MEM (BLKmode
, gen_rtx_SCRATCH (VOIDmode
));
9727 emit_clobber (addr
);
9731 /* Save fprs 8 - 15 (64 bit ABI). */
9733 if (cfun_save_high_fprs_p
&& next_fpr
)
9735 /* If the stack might be accessed through a different register
9736 we have to make sure that the stack pointer decrement is not
9737 moved below the use of the stack slots. */
9738 s390_emit_stack_tie ();
9740 insn
= emit_insn (gen_add2_insn (temp_reg
,
9741 GEN_INT (cfun_frame_layout
.f8_offset
)));
9745 for (i
= FPR8_REGNUM
; i
<= next_fpr
; i
++)
9746 if (cfun_fpr_save_p (i
))
9748 rtx addr
= plus_constant (Pmode
, stack_pointer_rtx
,
9749 cfun_frame_layout
.frame_size
9750 + cfun_frame_layout
.f8_offset
9753 insn
= save_fpr (temp_reg
, offset
, i
);
9755 RTX_FRAME_RELATED_P (insn
) = 1;
9756 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
,
9757 gen_rtx_SET (gen_rtx_MEM (DFmode
, addr
),
9758 gen_rtx_REG (DFmode
, i
)));
9762 /* Set frame pointer, if needed. */
9764 if (frame_pointer_needed
)
9766 insn
= emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
);
9767 RTX_FRAME_RELATED_P (insn
) = 1;
9770 /* Set up got pointer, if needed. */
9772 if (flag_pic
&& df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM
))
9774 rtx_insn
*insns
= s390_load_got ();
9776 for (rtx_insn
*insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
9777 annotate_constant_pool_refs (&PATTERN (insn
));
9782 if (TARGET_TPF_PROFILING
)
9784 /* Generate a BAS instruction to serve as a function
9785 entry intercept to facilitate the use of tracing
9786 algorithms located at the branch target. */
9787 emit_insn (gen_prologue_tpf ());
9789 /* Emit a blockage here so that all code
9790 lies between the profiling mechanisms. */
9791 emit_insn (gen_blockage ());
9795 /* Expand the epilogue into a bunch of separate insns. */
9798 s390_emit_epilogue (bool sibcall
)
9800 rtx frame_pointer
, return_reg
, cfa_restores
= NULL_RTX
;
9801 int area_bottom
, area_top
, offset
= 0;
9806 if (TARGET_TPF_PROFILING
)
9809 /* Generate a BAS instruction to serve as a function
9810 entry intercept to facilitate the use of tracing
9811 algorithms located at the branch target. */
9813 /* Emit a blockage here so that all code
9814 lies between the profiling mechanisms. */
9815 emit_insn (gen_blockage ());
9817 emit_insn (gen_epilogue_tpf ());
9820 /* Check whether to use frame or stack pointer for restore. */
9822 frame_pointer
= (frame_pointer_needed
9823 ? hard_frame_pointer_rtx
: stack_pointer_rtx
);
9825 s390_frame_area (&area_bottom
, &area_top
);
9827 /* Check whether we can access the register save area.
9828 If not, increment the frame pointer as required. */
9830 if (area_top
<= area_bottom
)
9832 /* Nothing to restore. */
9834 else if (DISP_IN_RANGE (cfun_frame_layout
.frame_size
+ area_bottom
)
9835 && DISP_IN_RANGE (cfun_frame_layout
.frame_size
+ area_top
- 1))
9837 /* Area is in range. */
9838 offset
= cfun_frame_layout
.frame_size
;
9842 rtx insn
, frame_off
, cfa
;
9844 offset
= area_bottom
< 0 ? -area_bottom
: 0;
9845 frame_off
= GEN_INT (cfun_frame_layout
.frame_size
- offset
);
9847 cfa
= gen_rtx_SET (frame_pointer
,
9848 gen_rtx_PLUS (Pmode
, frame_pointer
, frame_off
));
9849 if (DISP_IN_RANGE (INTVAL (frame_off
)))
9851 insn
= gen_rtx_SET (frame_pointer
,
9852 gen_rtx_PLUS (Pmode
, frame_pointer
, frame_off
));
9853 insn
= emit_insn (insn
);
9857 if (!CONST_OK_FOR_K (INTVAL (frame_off
)))
9858 frame_off
= force_const_mem (Pmode
, frame_off
);
9860 insn
= emit_insn (gen_add2_insn (frame_pointer
, frame_off
));
9861 annotate_constant_pool_refs (&PATTERN (insn
));
9863 add_reg_note (insn
, REG_CFA_ADJUST_CFA
, cfa
);
9864 RTX_FRAME_RELATED_P (insn
) = 1;
9867 /* Restore call saved fprs. */
9871 if (cfun_save_high_fprs_p
)
9873 next_offset
= cfun_frame_layout
.f8_offset
;
9874 for (i
= FPR8_REGNUM
; i
<= FPR15_REGNUM
; i
++)
9876 if (cfun_fpr_save_p (i
))
9878 restore_fpr (frame_pointer
,
9879 offset
+ next_offset
, i
);
9881 = alloc_reg_note (REG_CFA_RESTORE
,
9882 gen_rtx_REG (DFmode
, i
), cfa_restores
);
9891 next_offset
= cfun_frame_layout
.f4_offset
;
9893 for (i
= FPR4_REGNUM
; i
<= FPR4_REGNUM
+ 1; i
++)
9895 if (cfun_fpr_save_p (i
))
9897 restore_fpr (frame_pointer
,
9898 offset
+ next_offset
, i
);
9900 = alloc_reg_note (REG_CFA_RESTORE
,
9901 gen_rtx_REG (DFmode
, i
), cfa_restores
);
9904 else if (!TARGET_PACKED_STACK
)
9910 /* Return register. */
9912 return_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
9914 /* Restore call saved gprs. */
9916 if (cfun_frame_layout
.first_restore_gpr
!= -1)
9921 /* Check for global register and save them
9922 to stack location from where they get restored. */
9924 for (i
= cfun_frame_layout
.first_restore_gpr
;
9925 i
<= cfun_frame_layout
.last_restore_gpr
;
9928 if (global_not_special_regno_p (i
))
9930 addr
= plus_constant (Pmode
, frame_pointer
,
9931 offset
+ cfun_frame_layout
.gprs_offset
9932 + (i
- cfun_frame_layout
.first_save_gpr_slot
)
9934 addr
= gen_rtx_MEM (Pmode
, addr
);
9935 set_mem_alias_set (addr
, get_frame_alias_set ());
9936 emit_move_insn (addr
, gen_rtx_REG (Pmode
, i
));
9940 = alloc_reg_note (REG_CFA_RESTORE
,
9941 gen_rtx_REG (Pmode
, i
), cfa_restores
);
9946 /* Fetch return address from stack before load multiple,
9947 this will do good for scheduling.
9949 Only do this if we already decided that r14 needs to be
9950 saved to a stack slot. (And not just because r14 happens to
9951 be in between two GPRs which need saving.) Otherwise it
9952 would be difficult to take that decision back in
9953 s390_optimize_prologue. */
9954 if (cfun_gpr_save_slot (RETURN_REGNUM
) == -1)
9956 int return_regnum
= find_unused_clobbered_reg();
9959 return_reg
= gen_rtx_REG (Pmode
, return_regnum
);
9961 addr
= plus_constant (Pmode
, frame_pointer
,
9962 offset
+ cfun_frame_layout
.gprs_offset
9964 - cfun_frame_layout
.first_save_gpr_slot
)
9966 addr
= gen_rtx_MEM (Pmode
, addr
);
9967 set_mem_alias_set (addr
, get_frame_alias_set ());
9968 emit_move_insn (return_reg
, addr
);
9970 /* Once we did that optimization we have to make sure
9971 s390_optimize_prologue does not try to remove the
9972 store of r14 since we will not be able to find the
9973 load issued here. */
9974 cfun_frame_layout
.save_return_addr_p
= true;
9978 insn
= restore_gprs (frame_pointer
,
9979 offset
+ cfun_frame_layout
.gprs_offset
9980 + (cfun_frame_layout
.first_restore_gpr
9981 - cfun_frame_layout
.first_save_gpr_slot
)
9983 cfun_frame_layout
.first_restore_gpr
,
9984 cfun_frame_layout
.last_restore_gpr
);
9985 insn
= emit_insn (insn
);
9986 REG_NOTES (insn
) = cfa_restores
;
9987 add_reg_note (insn
, REG_CFA_DEF_CFA
,
9988 plus_constant (Pmode
, stack_pointer_rtx
,
9989 STACK_POINTER_OFFSET
));
9990 RTX_FRAME_RELATED_P (insn
) = 1;
9993 s390_restore_gprs_from_fprs ();
9998 /* Return to caller. */
10000 p
= rtvec_alloc (2);
10002 RTVEC_ELT (p
, 0) = ret_rtx
;
10003 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
, return_reg
);
10004 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
10008 /* Implement TARGET_SET_UP_BY_PROLOGUE. */
10011 s300_set_up_by_prologue (hard_reg_set_container
*regs
)
10013 if (cfun
->machine
->base_reg
10014 && !call_really_used_regs
[REGNO (cfun
->machine
->base_reg
)])
10015 SET_HARD_REG_BIT (regs
->set
, REGNO (cfun
->machine
->base_reg
));
10018 /* Return true if the function can use simple_return to return outside
10019 of a shrink-wrapped region. At present shrink-wrapping is supported
10023 s390_can_use_simple_return_insn (void)
10028 /* Return true if the epilogue is guaranteed to contain only a return
10029 instruction and if a direct return can therefore be used instead.
10030 One of the main advantages of using direct return instructions
10031 is that we can then use conditional returns. */
10034 s390_can_use_return_insn (void)
10038 if (!reload_completed
)
10044 if (TARGET_TPF_PROFILING
)
10047 for (i
= 0; i
< 16; i
++)
10048 if (cfun_gpr_save_slot (i
))
10051 /* For 31 bit this is not covered by the frame_size check below
10052 since f4, f6 are saved in the register save area without needing
10053 additional stack space. */
10055 && (cfun_fpr_save_p (FPR4_REGNUM
) || cfun_fpr_save_p (FPR6_REGNUM
)))
10058 if (cfun
->machine
->base_reg
10059 && !call_really_used_regs
[REGNO (cfun
->machine
->base_reg
)])
10062 return cfun_frame_layout
.frame_size
== 0;
10065 /* The VX ABI differs for vararg functions. Therefore we need the
10066 prototype of the callee to be available when passing vector type
10068 static const char *
10069 s390_invalid_arg_for_unprototyped_fn (const_tree typelist
, const_tree funcdecl
, const_tree val
)
10071 return ((TARGET_VX_ABI
10073 && VECTOR_TYPE_P (TREE_TYPE (val
))
10074 && (funcdecl
== NULL_TREE
10075 || (TREE_CODE (funcdecl
) == FUNCTION_DECL
10076 && DECL_BUILT_IN_CLASS (funcdecl
) != BUILT_IN_MD
)))
10077 ? N_("Vector argument passed to unprototyped function")
10082 /* Return the size in bytes of a function argument of
10083 type TYPE and/or mode MODE. At least one of TYPE or
10084 MODE must be specified. */
10087 s390_function_arg_size (machine_mode mode
, const_tree type
)
10090 return int_size_in_bytes (type
);
10092 /* No type info available for some library calls ... */
10093 if (mode
!= BLKmode
)
10094 return GET_MODE_SIZE (mode
);
10096 /* If we have neither type nor mode, abort */
10097 gcc_unreachable ();
10100 /* Return true if a function argument of type TYPE and mode MODE
10101 is to be passed in a vector register, if available. */
10104 s390_function_arg_vector (machine_mode mode
, const_tree type
)
10106 if (!TARGET_VX_ABI
)
10109 if (s390_function_arg_size (mode
, type
) > 16)
10112 /* No type info available for some library calls ... */
10114 return VECTOR_MODE_P (mode
);
10116 /* The ABI says that record types with a single member are treated
10117 just like that member would be. */
10118 while (TREE_CODE (type
) == RECORD_TYPE
)
10120 tree field
, single
= NULL_TREE
;
10122 for (field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
10124 if (TREE_CODE (field
) != FIELD_DECL
)
10127 if (single
== NULL_TREE
)
10128 single
= TREE_TYPE (field
);
10133 if (single
== NULL_TREE
)
10137 /* If the field declaration adds extra byte due to
10138 e.g. padding this is not accepted as vector type. */
10139 if (int_size_in_bytes (single
) <= 0
10140 || int_size_in_bytes (single
) != int_size_in_bytes (type
))
10146 return VECTOR_TYPE_P (type
);
10149 /* Return true if a function argument of type TYPE and mode MODE
10150 is to be passed in a floating-point register, if available. */
10153 s390_function_arg_float (machine_mode mode
, const_tree type
)
10155 if (s390_function_arg_size (mode
, type
) > 8)
10158 /* Soft-float changes the ABI: no floating-point registers are used. */
10159 if (TARGET_SOFT_FLOAT
)
10162 /* No type info available for some library calls ... */
10164 return mode
== SFmode
|| mode
== DFmode
|| mode
== SDmode
|| mode
== DDmode
;
10166 /* The ABI says that record types with a single member are treated
10167 just like that member would be. */
10168 while (TREE_CODE (type
) == RECORD_TYPE
)
10170 tree field
, single
= NULL_TREE
;
10172 for (field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
10174 if (TREE_CODE (field
) != FIELD_DECL
)
10177 if (single
== NULL_TREE
)
10178 single
= TREE_TYPE (field
);
10183 if (single
== NULL_TREE
)
10189 return TREE_CODE (type
) == REAL_TYPE
;
10192 /* Return true if a function argument of type TYPE and mode MODE
10193 is to be passed in an integer register, or a pair of integer
10194 registers, if available. */
10197 s390_function_arg_integer (machine_mode mode
, const_tree type
)
10199 int size
= s390_function_arg_size (mode
, type
);
10203 /* No type info available for some library calls ... */
10205 return GET_MODE_CLASS (mode
) == MODE_INT
10206 || (TARGET_SOFT_FLOAT
&& SCALAR_FLOAT_MODE_P (mode
));
10208 /* We accept small integral (and similar) types. */
10209 if (INTEGRAL_TYPE_P (type
)
10210 || POINTER_TYPE_P (type
)
10211 || TREE_CODE (type
) == NULLPTR_TYPE
10212 || TREE_CODE (type
) == OFFSET_TYPE
10213 || (TARGET_SOFT_FLOAT
&& TREE_CODE (type
) == REAL_TYPE
))
10216 /* We also accept structs of size 1, 2, 4, 8 that are not
10217 passed in floating-point registers. */
10218 if (AGGREGATE_TYPE_P (type
)
10219 && exact_log2 (size
) >= 0
10220 && !s390_function_arg_float (mode
, type
))
10226 /* Return 1 if a function argument of type TYPE and mode MODE
10227 is to be passed by reference. The ABI specifies that only
10228 structures of size 1, 2, 4, or 8 bytes are passed by value,
10229 all other structures (and complex numbers) are passed by
10233 s390_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED
,
10234 machine_mode mode
, const_tree type
,
10235 bool named ATTRIBUTE_UNUSED
)
10237 int size
= s390_function_arg_size (mode
, type
);
10239 if (s390_function_arg_vector (mode
, type
))
10247 if (AGGREGATE_TYPE_P (type
) && exact_log2 (size
) < 0)
10250 if (TREE_CODE (type
) == COMPLEX_TYPE
10251 || TREE_CODE (type
) == VECTOR_TYPE
)
10258 /* Update the data in CUM to advance over an argument of mode MODE and
10259 data type TYPE. (TYPE is null for libcalls where that information
10260 may not be available.). The boolean NAMED specifies whether the
10261 argument is a named argument (as opposed to an unnamed argument
10262 matching an ellipsis). */
10265 s390_function_arg_advance (cumulative_args_t cum_v
, machine_mode mode
,
10266 const_tree type
, bool named
)
10268 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
10270 if (s390_function_arg_vector (mode
, type
))
10272 /* We are called for unnamed vector stdarg arguments which are
10273 passed on the stack. In this case this hook does not have to
10274 do anything since stack arguments are tracked by common
10280 else if (s390_function_arg_float (mode
, type
))
10284 else if (s390_function_arg_integer (mode
, type
))
10286 int size
= s390_function_arg_size (mode
, type
);
10287 cum
->gprs
+= ((size
+ UNITS_PER_LONG
- 1) / UNITS_PER_LONG
);
10290 gcc_unreachable ();
10293 /* Define where to put the arguments to a function.
10294 Value is zero to push the argument on the stack,
10295 or a hard register in which to store the argument.
10297 MODE is the argument's machine mode.
10298 TYPE is the data type of the argument (as a tree).
10299 This is null for libcalls where that information may
10301 CUM is a variable of type CUMULATIVE_ARGS which gives info about
10302 the preceding args and about the function being called.
10303 NAMED is nonzero if this argument is a named parameter
10304 (otherwise it is an extra parameter matching an ellipsis).
10306 On S/390, we use general purpose registers 2 through 6 to
10307 pass integer, pointer, and certain structure arguments, and
10308 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
10309 to pass floating point arguments. All remaining arguments
10310 are pushed to the stack. */
10313 s390_function_arg (cumulative_args_t cum_v
, machine_mode mode
,
10314 const_tree type
, bool named
)
10316 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
10319 if (s390_function_arg_vector (mode
, type
))
10321 /* Vector arguments being part of the ellipsis are passed on the
10323 if (!named
|| (cum
->vrs
+ 1 > VEC_ARG_NUM_REG
))
10326 return gen_rtx_REG (mode
, cum
->vrs
+ FIRST_VEC_ARG_REGNO
);
10328 else if (s390_function_arg_float (mode
, type
))
10330 if (cum
->fprs
+ 1 > FP_ARG_NUM_REG
)
10333 return gen_rtx_REG (mode
, cum
->fprs
+ 16);
10335 else if (s390_function_arg_integer (mode
, type
))
10337 int size
= s390_function_arg_size (mode
, type
);
10338 int n_gprs
= (size
+ UNITS_PER_LONG
- 1) / UNITS_PER_LONG
;
10340 if (cum
->gprs
+ n_gprs
> GP_ARG_NUM_REG
)
10342 else if (n_gprs
== 1 || UNITS_PER_WORD
== UNITS_PER_LONG
)
10343 return gen_rtx_REG (mode
, cum
->gprs
+ 2);
10344 else if (n_gprs
== 2)
10346 rtvec p
= rtvec_alloc (2);
10349 = gen_rtx_EXPR_LIST (SImode
, gen_rtx_REG (SImode
, cum
->gprs
+ 2),
10352 = gen_rtx_EXPR_LIST (SImode
, gen_rtx_REG (SImode
, cum
->gprs
+ 3),
10355 return gen_rtx_PARALLEL (mode
, p
);
10359 /* After the real arguments, expand_call calls us once again
10360 with a void_type_node type. Whatever we return here is
10361 passed as operand 2 to the call expanders.
10363 We don't need this feature ... */
10364 else if (type
== void_type_node
)
10367 gcc_unreachable ();
10370 /* Return true if return values of type TYPE should be returned
10371 in a memory buffer whose address is passed by the caller as
10372 hidden first argument. */
10375 s390_return_in_memory (const_tree type
, const_tree fundecl ATTRIBUTE_UNUSED
)
10377 /* We accept small integral (and similar) types. */
10378 if (INTEGRAL_TYPE_P (type
)
10379 || POINTER_TYPE_P (type
)
10380 || TREE_CODE (type
) == OFFSET_TYPE
10381 || TREE_CODE (type
) == REAL_TYPE
)
10382 return int_size_in_bytes (type
) > 8;
10384 /* vector types which fit into a VR. */
10386 && VECTOR_TYPE_P (type
)
10387 && int_size_in_bytes (type
) <= 16)
10390 /* Aggregates and similar constructs are always returned
10392 if (AGGREGATE_TYPE_P (type
)
10393 || TREE_CODE (type
) == COMPLEX_TYPE
10394 || VECTOR_TYPE_P (type
))
10397 /* ??? We get called on all sorts of random stuff from
10398 aggregate_value_p. We can't abort, but it's not clear
10399 what's safe to return. Pretend it's a struct I guess. */
10403 /* Function arguments and return values are promoted to word size. */
10405 static machine_mode
10406 s390_promote_function_mode (const_tree type
, machine_mode mode
,
10408 const_tree fntype ATTRIBUTE_UNUSED
,
10409 int for_return ATTRIBUTE_UNUSED
)
10411 if (INTEGRAL_MODE_P (mode
)
10412 && GET_MODE_SIZE (mode
) < UNITS_PER_LONG
)
10414 if (type
!= NULL_TREE
&& POINTER_TYPE_P (type
))
10415 *punsignedp
= POINTERS_EXTEND_UNSIGNED
;
10422 /* Define where to return a (scalar) value of type RET_TYPE.
10423 If RET_TYPE is null, define where to return a (scalar)
10424 value of mode MODE from a libcall. */
10427 s390_function_and_libcall_value (machine_mode mode
,
10428 const_tree ret_type
,
10429 const_tree fntype_or_decl
,
10430 bool outgoing ATTRIBUTE_UNUSED
)
10432 /* For vector return types it is important to use the RET_TYPE
10433 argument whenever available since the middle-end might have
10434 changed the mode to a scalar mode. */
10435 bool vector_ret_type_p
= ((ret_type
&& VECTOR_TYPE_P (ret_type
))
10436 || (!ret_type
&& VECTOR_MODE_P (mode
)));
10438 /* For normal functions perform the promotion as
10439 promote_function_mode would do. */
10442 int unsignedp
= TYPE_UNSIGNED (ret_type
);
10443 mode
= promote_function_mode (ret_type
, mode
, &unsignedp
,
10444 fntype_or_decl
, 1);
10447 gcc_assert (GET_MODE_CLASS (mode
) == MODE_INT
10448 || SCALAR_FLOAT_MODE_P (mode
)
10449 || (TARGET_VX_ABI
&& vector_ret_type_p
));
10450 gcc_assert (GET_MODE_SIZE (mode
) <= (TARGET_VX_ABI
? 16 : 8));
10452 if (TARGET_VX_ABI
&& vector_ret_type_p
)
10453 return gen_rtx_REG (mode
, FIRST_VEC_ARG_REGNO
);
10454 else if (TARGET_HARD_FLOAT
&& SCALAR_FLOAT_MODE_P (mode
))
10455 return gen_rtx_REG (mode
, 16);
10456 else if (GET_MODE_SIZE (mode
) <= UNITS_PER_LONG
10457 || UNITS_PER_LONG
== UNITS_PER_WORD
)
10458 return gen_rtx_REG (mode
, 2);
10459 else if (GET_MODE_SIZE (mode
) == 2 * UNITS_PER_LONG
)
10461 /* This case is triggered when returning a 64 bit value with
10462 -m31 -mzarch. Although the value would fit into a single
10463 register it has to be forced into a 32 bit register pair in
10464 order to match the ABI. */
10465 rtvec p
= rtvec_alloc (2);
10468 = gen_rtx_EXPR_LIST (SImode
, gen_rtx_REG (SImode
, 2), const0_rtx
);
10470 = gen_rtx_EXPR_LIST (SImode
, gen_rtx_REG (SImode
, 3), GEN_INT (4));
10472 return gen_rtx_PARALLEL (mode
, p
);
10475 gcc_unreachable ();
10478 /* Define where to return a scalar return value of type RET_TYPE. */
10481 s390_function_value (const_tree ret_type
, const_tree fn_decl_or_type
,
10484 return s390_function_and_libcall_value (TYPE_MODE (ret_type
), ret_type
,
10485 fn_decl_or_type
, outgoing
);
10488 /* Define where to return a scalar libcall return value of mode
10492 s390_libcall_value (machine_mode mode
, const_rtx fun ATTRIBUTE_UNUSED
)
10494 return s390_function_and_libcall_value (mode
, NULL_TREE
,
10499 /* Create and return the va_list datatype.
10501 On S/390, va_list is an array type equivalent to
10503 typedef struct __va_list_tag
10507 void *__overflow_arg_area;
10508 void *__reg_save_area;
10511 where __gpr and __fpr hold the number of general purpose
10512 or floating point arguments used up to now, respectively,
10513 __overflow_arg_area points to the stack location of the
10514 next argument passed on the stack, and __reg_save_area
10515 always points to the start of the register area in the
10516 call frame of the current function. The function prologue
10517 saves all registers used for argument passing into this
10518 area if the function uses variable arguments. */
10521 s390_build_builtin_va_list (void)
10523 tree f_gpr
, f_fpr
, f_ovf
, f_sav
, record
, type_decl
;
10525 record
= lang_hooks
.types
.make_type (RECORD_TYPE
);
10528 build_decl (BUILTINS_LOCATION
,
10529 TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
10531 f_gpr
= build_decl (BUILTINS_LOCATION
,
10532 FIELD_DECL
, get_identifier ("__gpr"),
10533 long_integer_type_node
);
10534 f_fpr
= build_decl (BUILTINS_LOCATION
,
10535 FIELD_DECL
, get_identifier ("__fpr"),
10536 long_integer_type_node
);
10537 f_ovf
= build_decl (BUILTINS_LOCATION
,
10538 FIELD_DECL
, get_identifier ("__overflow_arg_area"),
10540 f_sav
= build_decl (BUILTINS_LOCATION
,
10541 FIELD_DECL
, get_identifier ("__reg_save_area"),
10544 va_list_gpr_counter_field
= f_gpr
;
10545 va_list_fpr_counter_field
= f_fpr
;
10547 DECL_FIELD_CONTEXT (f_gpr
) = record
;
10548 DECL_FIELD_CONTEXT (f_fpr
) = record
;
10549 DECL_FIELD_CONTEXT (f_ovf
) = record
;
10550 DECL_FIELD_CONTEXT (f_sav
) = record
;
10552 TYPE_STUB_DECL (record
) = type_decl
;
10553 TYPE_NAME (record
) = type_decl
;
10554 TYPE_FIELDS (record
) = f_gpr
;
10555 DECL_CHAIN (f_gpr
) = f_fpr
;
10556 DECL_CHAIN (f_fpr
) = f_ovf
;
10557 DECL_CHAIN (f_ovf
) = f_sav
;
10559 layout_type (record
);
10561 /* The correct type is an array type of one element. */
10562 return build_array_type (record
, build_index_type (size_zero_node
));
10565 /* Implement va_start by filling the va_list structure VALIST.
10566 STDARG_P is always true, and ignored.
10567 NEXTARG points to the first anonymous stack argument.
10569 The following global variables are used to initialize
10570 the va_list structure:
10573 holds number of gprs and fprs used for named arguments.
10574 crtl->args.arg_offset_rtx:
10575 holds the offset of the first anonymous stack argument
10576 (relative to the virtual arg pointer). */
10579 s390_va_start (tree valist
, rtx nextarg ATTRIBUTE_UNUSED
)
10581 HOST_WIDE_INT n_gpr
, n_fpr
;
10583 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
10584 tree gpr
, fpr
, ovf
, sav
, t
;
10586 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
10587 f_fpr
= DECL_CHAIN (f_gpr
);
10588 f_ovf
= DECL_CHAIN (f_fpr
);
10589 f_sav
= DECL_CHAIN (f_ovf
);
10591 valist
= build_simple_mem_ref (valist
);
10592 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
10593 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
10594 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
10595 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
10597 /* Count number of gp and fp argument registers used. */
10599 n_gpr
= crtl
->args
.info
.gprs
;
10600 n_fpr
= crtl
->args
.info
.fprs
;
10602 if (cfun
->va_list_gpr_size
)
10604 t
= build2 (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
,
10605 build_int_cst (NULL_TREE
, n_gpr
));
10606 TREE_SIDE_EFFECTS (t
) = 1;
10607 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
10610 if (cfun
->va_list_fpr_size
)
10612 t
= build2 (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
,
10613 build_int_cst (NULL_TREE
, n_fpr
));
10614 TREE_SIDE_EFFECTS (t
) = 1;
10615 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
10618 /* Find the overflow area.
10619 FIXME: This currently is too pessimistic when the vector ABI is
10620 enabled. In that case we *always* set up the overflow area
10622 if (n_gpr
+ cfun
->va_list_gpr_size
> GP_ARG_NUM_REG
10623 || n_fpr
+ cfun
->va_list_fpr_size
> FP_ARG_NUM_REG
10626 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
10628 off
= INTVAL (crtl
->args
.arg_offset_rtx
);
10629 off
= off
< 0 ? 0 : off
;
10630 if (TARGET_DEBUG_ARG
)
10631 fprintf (stderr
, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
10632 (int)n_gpr
, (int)n_fpr
, off
);
10634 t
= fold_build_pointer_plus_hwi (t
, off
);
10636 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
10637 TREE_SIDE_EFFECTS (t
) = 1;
10638 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
10641 /* Find the register save area. */
10642 if ((cfun
->va_list_gpr_size
&& n_gpr
< GP_ARG_NUM_REG
)
10643 || (cfun
->va_list_fpr_size
&& n_fpr
< FP_ARG_NUM_REG
))
10645 t
= make_tree (TREE_TYPE (sav
), return_address_pointer_rtx
);
10646 t
= fold_build_pointer_plus_hwi (t
, -RETURN_REGNUM
* UNITS_PER_LONG
);
10648 t
= build2 (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
10649 TREE_SIDE_EFFECTS (t
) = 1;
10650 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
10654 /* Implement va_arg by updating the va_list structure
10655 VALIST as required to retrieve an argument of type
10656 TYPE, and returning that argument.
10658 Generates code equivalent to:
10660 if (integral value) {
10661 if (size <= 4 && args.gpr < 5 ||
10662 size > 4 && args.gpr < 4 )
10663 ret = args.reg_save_area[args.gpr+8]
10665 ret = *args.overflow_arg_area++;
10666 } else if (vector value) {
10667 ret = *args.overflow_arg_area;
10668 args.overflow_arg_area += size / 8;
10669 } else if (float value) {
10671 ret = args.reg_save_area[args.fpr+64]
10673 ret = *args.overflow_arg_area++;
10674 } else if (aggregate value) {
10676 ret = *args.reg_save_area[args.gpr]
10678 ret = **args.overflow_arg_area++;
10682 s390_gimplify_va_arg (tree valist
, tree type
, gimple_seq
*pre_p
,
10683 gimple_seq
*post_p ATTRIBUTE_UNUSED
)
10685 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
10686 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
10687 int indirect_p
, size
, n_reg
, sav_ofs
, sav_scale
, max_reg
;
10688 tree lab_false
, lab_over
;
10689 tree addr
= create_tmp_var (ptr_type_node
, "addr");
10690 bool left_align_p
; /* How a value < UNITS_PER_LONG is aligned within
10693 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
10694 f_fpr
= DECL_CHAIN (f_gpr
);
10695 f_ovf
= DECL_CHAIN (f_fpr
);
10696 f_sav
= DECL_CHAIN (f_ovf
);
10698 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
10699 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
10700 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
10702 /* The tree for args* cannot be shared between gpr/fpr and ovf since
10703 both appear on a lhs. */
10704 valist
= unshare_expr (valist
);
10705 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
10707 size
= int_size_in_bytes (type
);
10709 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
10711 if (TARGET_DEBUG_ARG
)
10713 fprintf (stderr
, "va_arg: aggregate type");
10717 /* Aggregates are passed by reference. */
10722 /* kernel stack layout on 31 bit: It is assumed here that no padding
10723 will be added by s390_frame_info because for va_args always an even
10724 number of gprs has to be saved r15-r2 = 14 regs. */
10725 sav_ofs
= 2 * UNITS_PER_LONG
;
10726 sav_scale
= UNITS_PER_LONG
;
10727 size
= UNITS_PER_LONG
;
10728 max_reg
= GP_ARG_NUM_REG
- n_reg
;
10729 left_align_p
= false;
10731 else if (s390_function_arg_vector (TYPE_MODE (type
), type
))
10733 if (TARGET_DEBUG_ARG
)
10735 fprintf (stderr
, "va_arg: vector type");
10745 left_align_p
= true;
10747 else if (s390_function_arg_float (TYPE_MODE (type
), type
))
10749 if (TARGET_DEBUG_ARG
)
10751 fprintf (stderr
, "va_arg: float type");
10755 /* FP args go in FP registers, if present. */
10759 sav_ofs
= 16 * UNITS_PER_LONG
;
10761 max_reg
= FP_ARG_NUM_REG
- n_reg
;
10762 left_align_p
= false;
10766 if (TARGET_DEBUG_ARG
)
10768 fprintf (stderr
, "va_arg: other type");
10772 /* Otherwise into GP registers. */
10775 n_reg
= (size
+ UNITS_PER_LONG
- 1) / UNITS_PER_LONG
;
10777 /* kernel stack layout on 31 bit: It is assumed here that no padding
10778 will be added by s390_frame_info because for va_args always an even
10779 number of gprs has to be saved r15-r2 = 14 regs. */
10780 sav_ofs
= 2 * UNITS_PER_LONG
;
10782 if (size
< UNITS_PER_LONG
)
10783 sav_ofs
+= UNITS_PER_LONG
- size
;
10785 sav_scale
= UNITS_PER_LONG
;
10786 max_reg
= GP_ARG_NUM_REG
- n_reg
;
10787 left_align_p
= false;
10790 /* Pull the value out of the saved registers ... */
10792 if (reg
!= NULL_TREE
)
10795 if (reg > ((typeof (reg))max_reg))
10798 addr = sav + sav_ofs + reg * save_scale;
10805 lab_false
= create_artificial_label (UNKNOWN_LOCATION
);
10806 lab_over
= create_artificial_label (UNKNOWN_LOCATION
);
10808 t
= fold_convert (TREE_TYPE (reg
), size_int (max_reg
));
10809 t
= build2 (GT_EXPR
, boolean_type_node
, reg
, t
);
10810 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
10811 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
10812 gimplify_and_add (t
, pre_p
);
10814 t
= fold_build_pointer_plus_hwi (sav
, sav_ofs
);
10815 u
= build2 (MULT_EXPR
, TREE_TYPE (reg
), reg
,
10816 fold_convert (TREE_TYPE (reg
), size_int (sav_scale
)));
10817 t
= fold_build_pointer_plus (t
, u
);
10819 gimplify_assign (addr
, t
, pre_p
);
10821 gimple_seq_add_stmt (pre_p
, gimple_build_goto (lab_over
));
10823 gimple_seq_add_stmt (pre_p
, gimple_build_label (lab_false
));
10826 /* ... Otherwise out of the overflow area. */
10829 if (size
< UNITS_PER_LONG
&& !left_align_p
)
10830 t
= fold_build_pointer_plus_hwi (t
, UNITS_PER_LONG
- size
);
10832 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
10834 gimplify_assign (addr
, t
, pre_p
);
10836 if (size
< UNITS_PER_LONG
&& left_align_p
)
10837 t
= fold_build_pointer_plus_hwi (t
, UNITS_PER_LONG
);
10839 t
= fold_build_pointer_plus_hwi (t
, size
);
10841 gimplify_assign (ovf
, t
, pre_p
);
10843 if (reg
!= NULL_TREE
)
10844 gimple_seq_add_stmt (pre_p
, gimple_build_label (lab_over
));
10847 /* Increment register save count. */
10851 u
= build2 (PREINCREMENT_EXPR
, TREE_TYPE (reg
), reg
,
10852 fold_convert (TREE_TYPE (reg
), size_int (n_reg
)));
10853 gimplify_and_add (u
, pre_p
);
10858 t
= build_pointer_type_for_mode (build_pointer_type (type
),
10860 addr
= fold_convert (t
, addr
);
10861 addr
= build_va_arg_indirect_ref (addr
);
10865 t
= build_pointer_type_for_mode (type
, ptr_mode
, true);
10866 addr
= fold_convert (t
, addr
);
10869 return build_va_arg_indirect_ref (addr
);
10872 /* Emit rtl for the tbegin or tbegin_retry (RETRY != NULL_RTX)
10874 DEST - Register location where CC will be stored.
10875 TDB - Pointer to a 256 byte area where to store the transaction.
10876 diagnostic block. NULL if TDB is not needed.
10877 RETRY - Retry count value. If non-NULL a retry loop for CC2
10879 CLOBBER_FPRS_P - If true clobbers for all FPRs are emitted as part
10880 of the tbegin instruction pattern. */
10883 s390_expand_tbegin (rtx dest
, rtx tdb
, rtx retry
, bool clobber_fprs_p
)
10885 rtx retry_plus_two
= gen_reg_rtx (SImode
);
10886 rtx retry_reg
= gen_reg_rtx (SImode
);
10887 rtx_code_label
*retry_label
= NULL
;
10889 if (retry
!= NULL_RTX
)
10891 emit_move_insn (retry_reg
, retry
);
10892 emit_insn (gen_addsi3 (retry_plus_two
, retry_reg
, const2_rtx
));
10893 emit_insn (gen_addsi3 (retry_reg
, retry_reg
, const1_rtx
));
10894 retry_label
= gen_label_rtx ();
10895 emit_label (retry_label
);
10898 if (clobber_fprs_p
)
10899 emit_insn (gen_tbegin_1 (gen_rtx_CONST_INT (VOIDmode
, TBEGIN_MASK
), tdb
));
10901 emit_insn (gen_tbegin_nofloat_1 (gen_rtx_CONST_INT (VOIDmode
, TBEGIN_MASK
),
10904 emit_move_insn (dest
, gen_rtx_UNSPEC (SImode
,
10905 gen_rtvec (1, gen_rtx_REG (CCRAWmode
,
10907 UNSPEC_CC_TO_INT
));
10908 if (retry
!= NULL_RTX
)
10910 const int CC0
= 1 << 3;
10911 const int CC1
= 1 << 2;
10912 const int CC3
= 1 << 0;
10914 rtx count
= gen_reg_rtx (SImode
);
10915 rtx_code_label
*leave_label
= gen_label_rtx ();
10917 /* Exit for success and permanent failures. */
10918 jump
= s390_emit_jump (leave_label
,
10919 gen_rtx_EQ (VOIDmode
,
10920 gen_rtx_REG (CCRAWmode
, CC_REGNUM
),
10921 gen_rtx_CONST_INT (VOIDmode
, CC0
| CC1
| CC3
)));
10922 LABEL_NUSES (leave_label
) = 1;
10924 /* CC2 - transient failure. Perform retry with ppa. */
10925 emit_move_insn (count
, retry_plus_two
);
10926 emit_insn (gen_subsi3 (count
, count
, retry_reg
));
10927 emit_insn (gen_tx_assist (count
));
10928 jump
= emit_jump_insn (gen_doloop_si64 (retry_label
,
10931 JUMP_LABEL (jump
) = retry_label
;
10932 LABEL_NUSES (retry_label
) = 1;
10933 emit_label (leave_label
);
10941 S390_BUILTIN_TBEGIN
,
10942 S390_BUILTIN_TBEGIN_NOFLOAT
,
10943 S390_BUILTIN_TBEGIN_RETRY
,
10944 S390_BUILTIN_TBEGIN_RETRY_NOFLOAT
,
10945 S390_BUILTIN_TBEGINC
,
10947 S390_BUILTIN_TABORT
,
10948 S390_BUILTIN_NON_TX_STORE
,
10949 S390_BUILTIN_TX_NESTING_DEPTH
,
10950 S390_BUILTIN_TX_ASSIST
,
10952 S390_BUILTIN_S390_SFPC
,
10953 S390_BUILTIN_S390_EFPC
,
10958 tree s390_builtin_decls
[S390_BUILTIN_MAX
];
10960 static enum insn_code
const code_for_builtin
[S390_BUILTIN_MAX
] = {
10962 CODE_FOR_tbegin_nofloat
,
10963 CODE_FOR_tbegin_retry
,
10964 CODE_FOR_tbegin_retry_nofloat
,
10970 CODE_FOR_tx_assist
,
10972 CODE_FOR_s390_sfpc
,
10977 s390_init_builtins (void)
10979 tree ftype
, uint64_type
;
10980 tree returns_twice_attr
= tree_cons (get_identifier ("returns_twice"),
10982 tree noreturn_attr
= tree_cons (get_identifier ("noreturn"), NULL
, NULL
);
10984 /* void foo (void) */
10985 ftype
= build_function_type_list (void_type_node
, NULL_TREE
);
10986 s390_builtin_decls
[S390_BUILTIN_TBEGINC
] =
10987 add_builtin_function ("__builtin_tbeginc", ftype
, S390_BUILTIN_TBEGINC
,
10988 BUILT_IN_MD
, NULL
, NULL_TREE
);
10990 /* void foo (int) */
10991 ftype
= build_function_type_list (void_type_node
, integer_type_node
,
10993 s390_builtin_decls
[S390_BUILTIN_TABORT
] =
10994 add_builtin_function ("__builtin_tabort", ftype
,
10995 S390_BUILTIN_TABORT
, BUILT_IN_MD
, NULL
,
10997 s390_builtin_decls
[S390_BUILTIN_TX_ASSIST
] =
10998 add_builtin_function ("__builtin_tx_assist", ftype
,
10999 S390_BUILTIN_TX_ASSIST
, BUILT_IN_MD
, NULL
, NULL_TREE
);
11001 /* void foo (unsigned) */
11002 ftype
= build_function_type_list (void_type_node
, unsigned_type_node
,
11004 s390_builtin_decls
[S390_BUILTIN_S390_SFPC
] =
11005 add_builtin_function ("__builtin_s390_sfpc", ftype
,
11006 S390_BUILTIN_S390_SFPC
, BUILT_IN_MD
, NULL
, NULL_TREE
);
11008 /* int foo (void *) */
11009 ftype
= build_function_type_list (integer_type_node
, ptr_type_node
,
11011 s390_builtin_decls
[S390_BUILTIN_TBEGIN
] =
11012 add_builtin_function ("__builtin_tbegin", ftype
, S390_BUILTIN_TBEGIN
,
11013 BUILT_IN_MD
, NULL
, returns_twice_attr
);
11014 s390_builtin_decls
[S390_BUILTIN_TBEGIN_NOFLOAT
] =
11015 add_builtin_function ("__builtin_tbegin_nofloat", ftype
,
11016 S390_BUILTIN_TBEGIN_NOFLOAT
,
11017 BUILT_IN_MD
, NULL
, returns_twice_attr
);
11019 /* int foo (void *, int) */
11020 ftype
= build_function_type_list (integer_type_node
, ptr_type_node
,
11021 integer_type_node
, NULL_TREE
);
11022 s390_builtin_decls
[S390_BUILTIN_TBEGIN_RETRY
] =
11023 add_builtin_function ("__builtin_tbegin_retry", ftype
,
11024 S390_BUILTIN_TBEGIN_RETRY
,
11026 NULL
, returns_twice_attr
);
11027 s390_builtin_decls
[S390_BUILTIN_TBEGIN_RETRY_NOFLOAT
] =
11028 add_builtin_function ("__builtin_tbegin_retry_nofloat", ftype
,
11029 S390_BUILTIN_TBEGIN_RETRY_NOFLOAT
,
11031 NULL
, returns_twice_attr
);
11033 /* int foo (void) */
11034 ftype
= build_function_type_list (integer_type_node
, NULL_TREE
);
11035 s390_builtin_decls
[S390_BUILTIN_TX_NESTING_DEPTH
] =
11036 add_builtin_function ("__builtin_tx_nesting_depth", ftype
,
11037 S390_BUILTIN_TX_NESTING_DEPTH
,
11038 BUILT_IN_MD
, NULL
, NULL_TREE
);
11039 s390_builtin_decls
[S390_BUILTIN_TEND
] =
11040 add_builtin_function ("__builtin_tend", ftype
,
11041 S390_BUILTIN_TEND
, BUILT_IN_MD
, NULL
, NULL_TREE
);
11043 /* unsigned foo (void) */
11044 ftype
= build_function_type_list (unsigned_type_node
, NULL_TREE
);
11045 s390_builtin_decls
[S390_BUILTIN_S390_EFPC
] =
11046 add_builtin_function ("__builtin_s390_efpc", ftype
,
11047 S390_BUILTIN_S390_EFPC
, BUILT_IN_MD
, NULL
, NULL_TREE
);
11049 /* void foo (uint64_t *, uint64_t) */
11051 uint64_type
= long_unsigned_type_node
;
11053 uint64_type
= long_long_unsigned_type_node
;
11055 ftype
= build_function_type_list (void_type_node
,
11056 build_pointer_type (uint64_type
),
11057 uint64_type
, NULL_TREE
);
11058 s390_builtin_decls
[S390_BUILTIN_NON_TX_STORE
] =
11059 add_builtin_function ("__builtin_non_tx_store", ftype
,
11060 S390_BUILTIN_NON_TX_STORE
,
11061 BUILT_IN_MD
, NULL
, NULL_TREE
);
11064 /* Expand an expression EXP that calls a built-in function,
11065 with result going to TARGET if that's convenient
11066 (and in mode MODE if that's convenient).
11067 SUBTARGET may be used as the target for computing one of EXP's operands.
11068 IGNORE is nonzero if the value is to be ignored. */
11071 s390_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
11072 machine_mode mode ATTRIBUTE_UNUSED
,
11073 int ignore ATTRIBUTE_UNUSED
)
11077 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
11078 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
11079 enum insn_code icode
;
11080 rtx op
[MAX_ARGS
], pat
;
11084 call_expr_arg_iterator iter
;
11086 if (fcode
>= S390_BUILTIN_MAX
)
11087 internal_error ("bad builtin fcode");
11088 icode
= code_for_builtin
[fcode
];
11090 internal_error ("bad builtin fcode");
11092 if (!TARGET_HTM
&& fcode
<= S390_BUILTIN_TX_ASSIST
)
11093 error ("Transactional execution builtins not enabled (-mhtm)\n");
11095 /* Set a flag in the machine specific cfun part in order to support
11096 saving/restoring of FPRs. */
11097 if (fcode
== S390_BUILTIN_TBEGIN
|| fcode
== S390_BUILTIN_TBEGIN_RETRY
)
11098 cfun
->machine
->tbegin_p
= true;
11100 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
11103 FOR_EACH_CALL_EXPR_ARG (arg
, iter
, exp
)
11105 const struct insn_operand_data
*insn_op
;
11107 if (arg
== error_mark_node
)
11109 if (arity
>= MAX_ARGS
)
11112 insn_op
= &insn_data
[icode
].operand
[arity
+ nonvoid
];
11114 op
[arity
] = expand_expr (arg
, NULL_RTX
, insn_op
->mode
, EXPAND_NORMAL
);
11116 if (!(*insn_op
->predicate
) (op
[arity
], insn_op
->mode
))
11118 if (insn_op
->predicate
== memory_operand
)
11120 /* Don't move a NULL pointer into a register. Otherwise
11121 we have to rely on combine being able to move it back
11122 in order to get an immediate 0 in the instruction. */
11123 if (op
[arity
] != const0_rtx
)
11124 op
[arity
] = copy_to_mode_reg (Pmode
, op
[arity
]);
11125 op
[arity
] = gen_rtx_MEM (insn_op
->mode
, op
[arity
]);
11128 op
[arity
] = copy_to_mode_reg (insn_op
->mode
, op
[arity
]);
11136 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
11138 || GET_MODE (target
) != tmode
11139 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
11140 target
= gen_reg_rtx (tmode
);
11146 pat
= GEN_FCN (icode
) (target
);
11150 pat
= GEN_FCN (icode
) (target
, op
[0]);
11152 pat
= GEN_FCN (icode
) (op
[0]);
11156 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
11158 pat
= GEN_FCN (icode
) (op
[0], op
[1]);
11161 gcc_unreachable ();
11173 /* Return the decl for the target specific builtin with the function
11177 s390_builtin_decl (unsigned fcode
, bool initialized_p ATTRIBUTE_UNUSED
)
11179 if (fcode
>= S390_BUILTIN_MAX
)
11180 return error_mark_node
;
11182 return s390_builtin_decls
[fcode
];
11185 /* We call mcount before the function prologue. So a profiled leaf
11186 function should stay a leaf function. */
11189 s390_keep_leaf_when_profiled ()
11194 /* Output assembly code for the trampoline template to
11197 On S/390, we use gpr 1 internally in the trampoline code;
11198 gpr 0 is used to hold the static chain. */
11201 s390_asm_trampoline_template (FILE *file
)
11204 op
[0] = gen_rtx_REG (Pmode
, 0);
11205 op
[1] = gen_rtx_REG (Pmode
, 1);
11209 output_asm_insn ("basr\t%1,0", op
); /* 2 byte */
11210 output_asm_insn ("lmg\t%0,%1,14(%1)", op
); /* 6 byte */
11211 output_asm_insn ("br\t%1", op
); /* 2 byte */
11212 ASM_OUTPUT_SKIP (file
, (HOST_WIDE_INT
)(TRAMPOLINE_SIZE
- 10));
11216 output_asm_insn ("basr\t%1,0", op
); /* 2 byte */
11217 output_asm_insn ("lm\t%0,%1,6(%1)", op
); /* 4 byte */
11218 output_asm_insn ("br\t%1", op
); /* 2 byte */
11219 ASM_OUTPUT_SKIP (file
, (HOST_WIDE_INT
)(TRAMPOLINE_SIZE
- 8));
11223 /* Emit RTL insns to initialize the variable parts of a trampoline.
11224 FNADDR is an RTX for the address of the function's pure code.
11225 CXT is an RTX for the static chain value for the function. */
11228 s390_trampoline_init (rtx m_tramp
, tree fndecl
, rtx cxt
)
11230 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
11233 emit_block_move (m_tramp
, assemble_trampoline_template (),
11234 GEN_INT (2 * UNITS_PER_LONG
), BLOCK_OP_NORMAL
);
11236 mem
= adjust_address (m_tramp
, Pmode
, 2 * UNITS_PER_LONG
);
11237 emit_move_insn (mem
, cxt
);
11238 mem
= adjust_address (m_tramp
, Pmode
, 3 * UNITS_PER_LONG
);
11239 emit_move_insn (mem
, fnaddr
);
11242 /* Output assembler code to FILE to increment profiler label # LABELNO
11243 for profiling a function entry. */
11246 s390_function_profiler (FILE *file
, int labelno
)
11251 ASM_GENERATE_INTERNAL_LABEL (label
, "LP", labelno
);
11253 fprintf (file
, "# function profiler \n");
11255 op
[0] = gen_rtx_REG (Pmode
, RETURN_REGNUM
);
11256 op
[1] = gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
11257 op
[1] = gen_rtx_MEM (Pmode
, plus_constant (Pmode
, op
[1], UNITS_PER_LONG
));
11259 op
[2] = gen_rtx_REG (Pmode
, 1);
11260 op
[3] = gen_rtx_SYMBOL_REF (Pmode
, label
);
11261 SYMBOL_REF_FLAGS (op
[3]) = SYMBOL_FLAG_LOCAL
;
11263 op
[4] = gen_rtx_SYMBOL_REF (Pmode
, "_mcount");
11266 op
[4] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[4]), UNSPEC_PLT
);
11267 op
[4] = gen_rtx_CONST (Pmode
, op
[4]);
11272 output_asm_insn ("stg\t%0,%1", op
);
11273 output_asm_insn ("larl\t%2,%3", op
);
11274 output_asm_insn ("brasl\t%0,%4", op
);
11275 output_asm_insn ("lg\t%0,%1", op
);
11277 else if (!flag_pic
)
11279 op
[6] = gen_label_rtx ();
11281 output_asm_insn ("st\t%0,%1", op
);
11282 output_asm_insn ("bras\t%2,%l6", op
);
11283 output_asm_insn (".long\t%4", op
);
11284 output_asm_insn (".long\t%3", op
);
11285 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
11286 output_asm_insn ("l\t%0,0(%2)", op
);
11287 output_asm_insn ("l\t%2,4(%2)", op
);
11288 output_asm_insn ("basr\t%0,%0", op
);
11289 output_asm_insn ("l\t%0,%1", op
);
11293 op
[5] = gen_label_rtx ();
11294 op
[6] = gen_label_rtx ();
11296 output_asm_insn ("st\t%0,%1", op
);
11297 output_asm_insn ("bras\t%2,%l6", op
);
11298 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[5]));
11299 output_asm_insn (".long\t%4-%l5", op
);
11300 output_asm_insn (".long\t%3-%l5", op
);
11301 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
11302 output_asm_insn ("lr\t%0,%2", op
);
11303 output_asm_insn ("a\t%0,0(%2)", op
);
11304 output_asm_insn ("a\t%2,4(%2)", op
);
11305 output_asm_insn ("basr\t%0,%0", op
);
11306 output_asm_insn ("l\t%0,%1", op
);
11310 /* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
11311 into its SYMBOL_REF_FLAGS. */
11314 s390_encode_section_info (tree decl
, rtx rtl
, int first
)
11316 default_encode_section_info (decl
, rtl
, first
);
11318 if (TREE_CODE (decl
) == VAR_DECL
)
11320 /* If a variable has a forced alignment to < 2 bytes, mark it
11321 with SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL
11323 if (DECL_USER_ALIGN (decl
) && DECL_ALIGN (decl
) < 16)
11324 SYMBOL_REF_FLAGS (XEXP (rtl
, 0)) |= SYMBOL_FLAG_ALIGN1
;
11325 if (!DECL_SIZE (decl
)
11326 || !DECL_ALIGN (decl
)
11327 || !tree_fits_shwi_p (DECL_SIZE (decl
))
11328 || (DECL_ALIGN (decl
) <= 64
11329 && DECL_ALIGN (decl
) != tree_to_shwi (DECL_SIZE (decl
))))
11330 SYMBOL_REF_FLAGS (XEXP (rtl
, 0)) |= SYMBOL_FLAG_NOT_NATURALLY_ALIGNED
;
11333 /* Literal pool references don't have a decl so they are handled
11334 differently here. We rely on the information in the MEM_ALIGN
11335 entry to decide upon natural alignment. */
11337 && GET_CODE (XEXP (rtl
, 0)) == SYMBOL_REF
11338 && TREE_CONSTANT_POOL_ADDRESS_P (XEXP (rtl
, 0))
11339 && (MEM_ALIGN (rtl
) == 0
11340 || GET_MODE_BITSIZE (GET_MODE (rtl
)) == 0
11341 || MEM_ALIGN (rtl
) < GET_MODE_BITSIZE (GET_MODE (rtl
))))
11342 SYMBOL_REF_FLAGS (XEXP (rtl
, 0)) |= SYMBOL_FLAG_NOT_NATURALLY_ALIGNED
;
11345 /* Output thunk to FILE that implements a C++ virtual function call (with
11346 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
11347 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
11348 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
11349 relative to the resulting this pointer. */
11352 s390_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
11353 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
11359 /* Make sure unwind info is emitted for the thunk if needed. */
11360 final_start_function (emit_barrier (), file
, 1);
11362 /* Operand 0 is the target function. */
11363 op
[0] = XEXP (DECL_RTL (function
), 0);
11364 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (op
[0]))
11367 op
[0] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[0]),
11368 TARGET_64BIT
? UNSPEC_PLT
: UNSPEC_GOT
);
11369 op
[0] = gen_rtx_CONST (Pmode
, op
[0]);
11372 /* Operand 1 is the 'this' pointer. */
11373 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
11374 op
[1] = gen_rtx_REG (Pmode
, 3);
11376 op
[1] = gen_rtx_REG (Pmode
, 2);
11378 /* Operand 2 is the delta. */
11379 op
[2] = GEN_INT (delta
);
11381 /* Operand 3 is the vcall_offset. */
11382 op
[3] = GEN_INT (vcall_offset
);
11384 /* Operand 4 is the temporary register. */
11385 op
[4] = gen_rtx_REG (Pmode
, 1);
11387 /* Operands 5 to 8 can be used as labels. */
11393 /* Operand 9 can be used for temporary register. */
11396 /* Generate code. */
11399 /* Setup literal pool pointer if required. */
11400 if ((!DISP_IN_RANGE (delta
)
11401 && !CONST_OK_FOR_K (delta
)
11402 && !CONST_OK_FOR_Os (delta
))
11403 || (!DISP_IN_RANGE (vcall_offset
)
11404 && !CONST_OK_FOR_K (vcall_offset
)
11405 && !CONST_OK_FOR_Os (vcall_offset
)))
11407 op
[5] = gen_label_rtx ();
11408 output_asm_insn ("larl\t%4,%5", op
);
11411 /* Add DELTA to this pointer. */
11414 if (CONST_OK_FOR_J (delta
))
11415 output_asm_insn ("la\t%1,%2(%1)", op
);
11416 else if (DISP_IN_RANGE (delta
))
11417 output_asm_insn ("lay\t%1,%2(%1)", op
);
11418 else if (CONST_OK_FOR_K (delta
))
11419 output_asm_insn ("aghi\t%1,%2", op
);
11420 else if (CONST_OK_FOR_Os (delta
))
11421 output_asm_insn ("agfi\t%1,%2", op
);
11424 op
[6] = gen_label_rtx ();
11425 output_asm_insn ("agf\t%1,%6-%5(%4)", op
);
11429 /* Perform vcall adjustment. */
11432 if (DISP_IN_RANGE (vcall_offset
))
11434 output_asm_insn ("lg\t%4,0(%1)", op
);
11435 output_asm_insn ("ag\t%1,%3(%4)", op
);
11437 else if (CONST_OK_FOR_K (vcall_offset
))
11439 output_asm_insn ("lghi\t%4,%3", op
);
11440 output_asm_insn ("ag\t%4,0(%1)", op
);
11441 output_asm_insn ("ag\t%1,0(%4)", op
);
11443 else if (CONST_OK_FOR_Os (vcall_offset
))
11445 output_asm_insn ("lgfi\t%4,%3", op
);
11446 output_asm_insn ("ag\t%4,0(%1)", op
);
11447 output_asm_insn ("ag\t%1,0(%4)", op
);
11451 op
[7] = gen_label_rtx ();
11452 output_asm_insn ("llgf\t%4,%7-%5(%4)", op
);
11453 output_asm_insn ("ag\t%4,0(%1)", op
);
11454 output_asm_insn ("ag\t%1,0(%4)", op
);
11458 /* Jump to target. */
11459 output_asm_insn ("jg\t%0", op
);
11461 /* Output literal pool if required. */
11464 output_asm_insn (".align\t4", op
);
11465 targetm
.asm_out
.internal_label (file
, "L",
11466 CODE_LABEL_NUMBER (op
[5]));
11470 targetm
.asm_out
.internal_label (file
, "L",
11471 CODE_LABEL_NUMBER (op
[6]));
11472 output_asm_insn (".long\t%2", op
);
11476 targetm
.asm_out
.internal_label (file
, "L",
11477 CODE_LABEL_NUMBER (op
[7]));
11478 output_asm_insn (".long\t%3", op
);
11483 /* Setup base pointer if required. */
11485 || (!DISP_IN_RANGE (delta
)
11486 && !CONST_OK_FOR_K (delta
)
11487 && !CONST_OK_FOR_Os (delta
))
11488 || (!DISP_IN_RANGE (delta
)
11489 && !CONST_OK_FOR_K (vcall_offset
)
11490 && !CONST_OK_FOR_Os (vcall_offset
)))
11492 op
[5] = gen_label_rtx ();
11493 output_asm_insn ("basr\t%4,0", op
);
11494 targetm
.asm_out
.internal_label (file
, "L",
11495 CODE_LABEL_NUMBER (op
[5]));
11498 /* Add DELTA to this pointer. */
11501 if (CONST_OK_FOR_J (delta
))
11502 output_asm_insn ("la\t%1,%2(%1)", op
);
11503 else if (DISP_IN_RANGE (delta
))
11504 output_asm_insn ("lay\t%1,%2(%1)", op
);
11505 else if (CONST_OK_FOR_K (delta
))
11506 output_asm_insn ("ahi\t%1,%2", op
);
11507 else if (CONST_OK_FOR_Os (delta
))
11508 output_asm_insn ("afi\t%1,%2", op
);
11511 op
[6] = gen_label_rtx ();
11512 output_asm_insn ("a\t%1,%6-%5(%4)", op
);
11516 /* Perform vcall adjustment. */
11519 if (CONST_OK_FOR_J (vcall_offset
))
11521 output_asm_insn ("l\t%4,0(%1)", op
);
11522 output_asm_insn ("a\t%1,%3(%4)", op
);
11524 else if (DISP_IN_RANGE (vcall_offset
))
11526 output_asm_insn ("l\t%4,0(%1)", op
);
11527 output_asm_insn ("ay\t%1,%3(%4)", op
);
11529 else if (CONST_OK_FOR_K (vcall_offset
))
11531 output_asm_insn ("lhi\t%4,%3", op
);
11532 output_asm_insn ("a\t%4,0(%1)", op
);
11533 output_asm_insn ("a\t%1,0(%4)", op
);
11535 else if (CONST_OK_FOR_Os (vcall_offset
))
11537 output_asm_insn ("iilf\t%4,%3", op
);
11538 output_asm_insn ("a\t%4,0(%1)", op
);
11539 output_asm_insn ("a\t%1,0(%4)", op
);
11543 op
[7] = gen_label_rtx ();
11544 output_asm_insn ("l\t%4,%7-%5(%4)", op
);
11545 output_asm_insn ("a\t%4,0(%1)", op
);
11546 output_asm_insn ("a\t%1,0(%4)", op
);
11549 /* We had to clobber the base pointer register.
11550 Re-setup the base pointer (with a different base). */
11551 op
[5] = gen_label_rtx ();
11552 output_asm_insn ("basr\t%4,0", op
);
11553 targetm
.asm_out
.internal_label (file
, "L",
11554 CODE_LABEL_NUMBER (op
[5]));
11557 /* Jump to target. */
11558 op
[8] = gen_label_rtx ();
11561 output_asm_insn ("l\t%4,%8-%5(%4)", op
);
11562 else if (!nonlocal
)
11563 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
11564 /* We cannot call through .plt, since .plt requires %r12 loaded. */
11565 else if (flag_pic
== 1)
11567 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
11568 output_asm_insn ("l\t%4,%0(%4)", op
);
11570 else if (flag_pic
== 2)
11572 op
[9] = gen_rtx_REG (Pmode
, 0);
11573 output_asm_insn ("l\t%9,%8-4-%5(%4)", op
);
11574 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
11575 output_asm_insn ("ar\t%4,%9", op
);
11576 output_asm_insn ("l\t%4,0(%4)", op
);
11579 output_asm_insn ("br\t%4", op
);
11581 /* Output literal pool. */
11582 output_asm_insn (".align\t4", op
);
11584 if (nonlocal
&& flag_pic
== 2)
11585 output_asm_insn (".long\t%0", op
);
11588 op
[0] = gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
11589 SYMBOL_REF_FLAGS (op
[0]) = SYMBOL_FLAG_LOCAL
;
11592 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[8]));
11594 output_asm_insn (".long\t%0", op
);
11596 output_asm_insn (".long\t%0-%5", op
);
11600 targetm
.asm_out
.internal_label (file
, "L",
11601 CODE_LABEL_NUMBER (op
[6]));
11602 output_asm_insn (".long\t%2", op
);
11606 targetm
.asm_out
.internal_label (file
, "L",
11607 CODE_LABEL_NUMBER (op
[7]));
11608 output_asm_insn (".long\t%3", op
);
11611 final_end_function ();
11615 s390_valid_pointer_mode (machine_mode mode
)
11617 return (mode
== SImode
|| (TARGET_64BIT
&& mode
== DImode
));
11620 /* Checks whether the given CALL_EXPR would use a caller
11621 saved register. This is used to decide whether sibling call
11622 optimization could be performed on the respective function
11626 s390_call_saved_register_used (tree call_expr
)
11628 CUMULATIVE_ARGS cum_v
;
11629 cumulative_args_t cum
;
11636 INIT_CUMULATIVE_ARGS (cum_v
, NULL
, NULL
, 0, 0);
11637 cum
= pack_cumulative_args (&cum_v
);
11639 for (i
= 0; i
< call_expr_nargs (call_expr
); i
++)
11641 parameter
= CALL_EXPR_ARG (call_expr
, i
);
11642 gcc_assert (parameter
);
11644 /* For an undeclared variable passed as parameter we will get
11645 an ERROR_MARK node here. */
11646 if (TREE_CODE (parameter
) == ERROR_MARK
)
11649 type
= TREE_TYPE (parameter
);
11652 mode
= TYPE_MODE (type
);
11655 /* We assume that in the target function all parameters are
11656 named. This only has an impact on vector argument register
11657 usage none of which is call-saved. */
11658 if (pass_by_reference (&cum_v
, mode
, type
, true))
11661 type
= build_pointer_type (type
);
11664 parm_rtx
= s390_function_arg (cum
, mode
, type
, true);
11666 s390_function_arg_advance (cum
, mode
, type
, true);
11671 if (REG_P (parm_rtx
))
11674 reg
< HARD_REGNO_NREGS (REGNO (parm_rtx
), GET_MODE (parm_rtx
));
11676 if (!call_used_regs
[reg
+ REGNO (parm_rtx
)])
11680 if (GET_CODE (parm_rtx
) == PARALLEL
)
11684 for (i
= 0; i
< XVECLEN (parm_rtx
, 0); i
++)
11686 rtx r
= XEXP (XVECEXP (parm_rtx
, 0, i
), 0);
11688 gcc_assert (REG_P (r
));
11691 reg
< HARD_REGNO_NREGS (REGNO (r
), GET_MODE (r
));
11693 if (!call_used_regs
[reg
+ REGNO (r
)])
11702 /* Return true if the given call expression can be
11703 turned into a sibling call.
11704 DECL holds the declaration of the function to be called whereas
11705 EXP is the call expression itself. */
11708 s390_function_ok_for_sibcall (tree decl
, tree exp
)
11710 /* The TPF epilogue uses register 1. */
11711 if (TARGET_TPF_PROFILING
)
11714 /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
11715 which would have to be restored before the sibcall. */
11716 if (!TARGET_64BIT
&& flag_pic
&& decl
&& !targetm
.binds_local_p (decl
))
11719 /* Register 6 on s390 is available as an argument register but unfortunately
11720 "caller saved". This makes functions needing this register for arguments
11721 not suitable for sibcalls. */
11722 return !s390_call_saved_register_used (exp
);
11725 /* Return the fixed registers used for condition codes. */
11728 s390_fixed_condition_code_regs (unsigned int *p1
, unsigned int *p2
)
11731 *p2
= INVALID_REGNUM
;
11736 /* This function is used by the call expanders of the machine description.
11737 It emits the call insn itself together with the necessary operations
11738 to adjust the target address and returns the emitted insn.
11739 ADDR_LOCATION is the target address rtx
11740 TLS_CALL the location of the thread-local symbol
11741 RESULT_REG the register where the result of the call should be stored
11742 RETADDR_REG the register where the return address should be stored
11743 If this parameter is NULL_RTX the call is considered
11744 to be a sibling call. */
11747 s390_emit_call (rtx addr_location
, rtx tls_call
, rtx result_reg
,
11750 bool plt_call
= false;
11756 /* Direct function calls need special treatment. */
11757 if (GET_CODE (addr_location
) == SYMBOL_REF
)
11759 /* When calling a global routine in PIC mode, we must
11760 replace the symbol itself with the PLT stub. */
11761 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (addr_location
))
11763 if (retaddr_reg
!= NULL_RTX
)
11765 addr_location
= gen_rtx_UNSPEC (Pmode
,
11766 gen_rtvec (1, addr_location
),
11768 addr_location
= gen_rtx_CONST (Pmode
, addr_location
);
11772 /* For -fpic code the PLT entries might use r12 which is
11773 call-saved. Therefore we cannot do a sibcall when
11774 calling directly using a symbol ref. When reaching
11775 this point we decided (in s390_function_ok_for_sibcall)
11776 to do a sibcall for a function pointer but one of the
11777 optimizers was able to get rid of the function pointer
11778 by propagating the symbol ref into the call. This
11779 optimization is illegal for S/390 so we turn the direct
11780 call into a indirect call again. */
11781 addr_location
= force_reg (Pmode
, addr_location
);
11784 /* Unless we can use the bras(l) insn, force the
11785 routine address into a register. */
11786 if (!TARGET_SMALL_EXEC
&& !TARGET_CPU_ZARCH
)
11789 addr_location
= legitimize_pic_address (addr_location
, 0);
11791 addr_location
= force_reg (Pmode
, addr_location
);
11795 /* If it is already an indirect call or the code above moved the
11796 SYMBOL_REF to somewhere else make sure the address can be found in
11798 if (retaddr_reg
== NULL_RTX
11799 && GET_CODE (addr_location
) != SYMBOL_REF
11802 emit_move_insn (gen_rtx_REG (Pmode
, SIBCALL_REGNUM
), addr_location
);
11803 addr_location
= gen_rtx_REG (Pmode
, SIBCALL_REGNUM
);
11806 addr_location
= gen_rtx_MEM (QImode
, addr_location
);
11807 call
= gen_rtx_CALL (VOIDmode
, addr_location
, const0_rtx
);
11809 if (result_reg
!= NULL_RTX
)
11810 call
= gen_rtx_SET (result_reg
, call
);
11812 if (retaddr_reg
!= NULL_RTX
)
11814 clobber
= gen_rtx_CLOBBER (VOIDmode
, retaddr_reg
);
11816 if (tls_call
!= NULL_RTX
)
11817 vec
= gen_rtvec (3, call
, clobber
,
11818 gen_rtx_USE (VOIDmode
, tls_call
));
11820 vec
= gen_rtvec (2, call
, clobber
);
11822 call
= gen_rtx_PARALLEL (VOIDmode
, vec
);
11825 insn
= emit_call_insn (call
);
11827 /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
11828 if ((!TARGET_64BIT
&& plt_call
) || tls_call
!= NULL_RTX
)
11830 /* s390_function_ok_for_sibcall should
11831 have denied sibcalls in this case. */
11832 gcc_assert (retaddr_reg
!= NULL_RTX
);
11833 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), gen_rtx_REG (Pmode
, 12));
11838 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
11841 s390_conditional_register_usage (void)
11847 fixed_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
11848 call_used_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
11850 if (TARGET_CPU_ZARCH
)
11852 fixed_regs
[BASE_REGNUM
] = 0;
11853 call_used_regs
[BASE_REGNUM
] = 0;
11854 fixed_regs
[RETURN_REGNUM
] = 0;
11855 call_used_regs
[RETURN_REGNUM
] = 0;
11859 for (i
= FPR8_REGNUM
; i
<= FPR15_REGNUM
; i
++)
11860 call_used_regs
[i
] = call_really_used_regs
[i
] = 0;
11864 call_used_regs
[FPR4_REGNUM
] = call_really_used_regs
[FPR4_REGNUM
] = 0;
11865 call_used_regs
[FPR6_REGNUM
] = call_really_used_regs
[FPR6_REGNUM
] = 0;
11868 if (TARGET_SOFT_FLOAT
)
11870 for (i
= FPR0_REGNUM
; i
<= FPR15_REGNUM
; i
++)
11871 call_used_regs
[i
] = fixed_regs
[i
] = 1;
11874 /* Disable v16 - v31 for non-vector target. */
11877 for (i
= VR16_REGNUM
; i
<= VR31_REGNUM
; i
++)
11878 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
11882 /* Corresponding function to eh_return expander. */
11884 static GTY(()) rtx s390_tpf_eh_return_symbol
;
11886 s390_emit_tpf_eh_return (rtx target
)
11891 if (!s390_tpf_eh_return_symbol
)
11892 s390_tpf_eh_return_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "__tpf_eh_return");
11894 reg
= gen_rtx_REG (Pmode
, 2);
11895 orig_ra
= gen_rtx_REG (Pmode
, 3);
11897 emit_move_insn (reg
, target
);
11898 emit_move_insn (orig_ra
, get_hard_reg_initial_val (Pmode
, RETURN_REGNUM
));
11899 insn
= s390_emit_call (s390_tpf_eh_return_symbol
, NULL_RTX
, reg
,
11900 gen_rtx_REG (Pmode
, RETURN_REGNUM
));
11901 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), reg
);
11902 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), orig_ra
);
11904 emit_move_insn (EH_RETURN_HANDLER_RTX
, reg
);
11907 /* Rework the prologue/epilogue to avoid saving/restoring
11908 registers unnecessarily. */
11911 s390_optimize_prologue (void)
11913 rtx_insn
*insn
, *new_insn
, *next_insn
;
11915 /* Do a final recompute of the frame-related data. */
11916 s390_optimize_register_info ();
11918 /* If all special registers are in fact used, there's nothing we
11919 can do, so no point in walking the insn list. */
11921 if (cfun_frame_layout
.first_save_gpr
<= BASE_REGNUM
11922 && cfun_frame_layout
.last_save_gpr
>= BASE_REGNUM
11923 && (TARGET_CPU_ZARCH
11924 || (cfun_frame_layout
.first_save_gpr
<= RETURN_REGNUM
11925 && cfun_frame_layout
.last_save_gpr
>= RETURN_REGNUM
)))
11928 /* Search for prologue/epilogue insns and replace them. */
11930 for (insn
= get_insns (); insn
; insn
= next_insn
)
11932 int first
, last
, off
;
11933 rtx set
, base
, offset
;
11936 next_insn
= NEXT_INSN (insn
);
11938 if (! NONJUMP_INSN_P (insn
) || ! RTX_FRAME_RELATED_P (insn
))
11941 pat
= PATTERN (insn
);
11943 /* Remove ldgr/lgdr instructions used for saving and restore
11944 GPRs if possible. */
11946 && GET_CODE (pat
) == SET
11947 && GET_MODE (SET_SRC (pat
)) == DImode
11948 && REG_P (SET_SRC (pat
))
11949 && REG_P (SET_DEST (pat
)))
11951 int src_regno
= REGNO (SET_SRC (pat
));
11952 int dest_regno
= REGNO (SET_DEST (pat
));
11956 if (!((GENERAL_REGNO_P (src_regno
) && FP_REGNO_P (dest_regno
))
11957 || (FP_REGNO_P (src_regno
) && GENERAL_REGNO_P (dest_regno
))))
11960 gpr_regno
= GENERAL_REGNO_P (src_regno
) ? src_regno
: dest_regno
;
11961 fpr_regno
= FP_REGNO_P (src_regno
) ? src_regno
: dest_regno
;
11963 /* GPR must be call-saved, FPR must be call-clobbered. */
11964 if (!call_really_used_regs
[fpr_regno
]
11965 || call_really_used_regs
[gpr_regno
])
11968 /* It must not happen that what we once saved in an FPR now
11969 needs a stack slot. */
11970 gcc_assert (cfun_gpr_save_slot (gpr_regno
) != -1);
11972 if (cfun_gpr_save_slot (gpr_regno
) == 0)
11974 remove_insn (insn
);
11979 if (GET_CODE (pat
) == PARALLEL
11980 && store_multiple_operation (pat
, VOIDmode
))
11982 set
= XVECEXP (pat
, 0, 0);
11983 first
= REGNO (SET_SRC (set
));
11984 last
= first
+ XVECLEN (pat
, 0) - 1;
11985 offset
= const0_rtx
;
11986 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
11987 off
= INTVAL (offset
);
11989 if (GET_CODE (base
) != REG
|| off
< 0)
11991 if (cfun_frame_layout
.first_save_gpr
!= -1
11992 && (cfun_frame_layout
.first_save_gpr
< first
11993 || cfun_frame_layout
.last_save_gpr
> last
))
11995 if (REGNO (base
) != STACK_POINTER_REGNUM
11996 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
11998 if (first
> BASE_REGNUM
|| last
< BASE_REGNUM
)
12001 if (cfun_frame_layout
.first_save_gpr
!= -1)
12003 rtx s_pat
= save_gprs (base
,
12004 off
+ (cfun_frame_layout
.first_save_gpr
12005 - first
) * UNITS_PER_LONG
,
12006 cfun_frame_layout
.first_save_gpr
,
12007 cfun_frame_layout
.last_save_gpr
);
12008 new_insn
= emit_insn_before (s_pat
, insn
);
12009 INSN_ADDRESSES_NEW (new_insn
, -1);
12012 remove_insn (insn
);
12016 if (cfun_frame_layout
.first_save_gpr
== -1
12017 && GET_CODE (pat
) == SET
12018 && GENERAL_REG_P (SET_SRC (pat
))
12019 && GET_CODE (SET_DEST (pat
)) == MEM
)
12022 first
= REGNO (SET_SRC (set
));
12023 offset
= const0_rtx
;
12024 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
12025 off
= INTVAL (offset
);
12027 if (GET_CODE (base
) != REG
|| off
< 0)
12029 if (REGNO (base
) != STACK_POINTER_REGNUM
12030 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
12033 remove_insn (insn
);
12037 if (GET_CODE (pat
) == PARALLEL
12038 && load_multiple_operation (pat
, VOIDmode
))
12040 set
= XVECEXP (pat
, 0, 0);
12041 first
= REGNO (SET_DEST (set
));
12042 last
= first
+ XVECLEN (pat
, 0) - 1;
12043 offset
= const0_rtx
;
12044 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
12045 off
= INTVAL (offset
);
12047 if (GET_CODE (base
) != REG
|| off
< 0)
12050 if (cfun_frame_layout
.first_restore_gpr
!= -1
12051 && (cfun_frame_layout
.first_restore_gpr
< first
12052 || cfun_frame_layout
.last_restore_gpr
> last
))
12054 if (REGNO (base
) != STACK_POINTER_REGNUM
12055 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
12057 if (first
> BASE_REGNUM
|| last
< BASE_REGNUM
)
12060 if (cfun_frame_layout
.first_restore_gpr
!= -1)
12062 rtx rpat
= restore_gprs (base
,
12063 off
+ (cfun_frame_layout
.first_restore_gpr
12064 - first
) * UNITS_PER_LONG
,
12065 cfun_frame_layout
.first_restore_gpr
,
12066 cfun_frame_layout
.last_restore_gpr
);
12068 /* Remove REG_CFA_RESTOREs for registers that we no
12069 longer need to save. */
12070 REG_NOTES (rpat
) = REG_NOTES (insn
);
12071 for (rtx
*ptr
= ®_NOTES (rpat
); *ptr
; )
12072 if (REG_NOTE_KIND (*ptr
) == REG_CFA_RESTORE
12073 && ((int) REGNO (XEXP (*ptr
, 0))
12074 < cfun_frame_layout
.first_restore_gpr
))
12075 *ptr
= XEXP (*ptr
, 1);
12077 ptr
= &XEXP (*ptr
, 1);
12078 new_insn
= emit_insn_before (rpat
, insn
);
12079 RTX_FRAME_RELATED_P (new_insn
) = 1;
12080 INSN_ADDRESSES_NEW (new_insn
, -1);
12083 remove_insn (insn
);
12087 if (cfun_frame_layout
.first_restore_gpr
== -1
12088 && GET_CODE (pat
) == SET
12089 && GENERAL_REG_P (SET_DEST (pat
))
12090 && GET_CODE (SET_SRC (pat
)) == MEM
)
12093 first
= REGNO (SET_DEST (set
));
12094 offset
= const0_rtx
;
12095 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
12096 off
= INTVAL (offset
);
12098 if (GET_CODE (base
) != REG
|| off
< 0)
12101 if (REGNO (base
) != STACK_POINTER_REGNUM
12102 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
12105 remove_insn (insn
);
12111 /* On z10 and later the dynamic branch prediction must see the
12112 backward jump within a certain windows. If not it falls back to
12113 the static prediction. This function rearranges the loop backward
12114 branch in a way which makes the static prediction always correct.
12115 The function returns true if it added an instruction. */
12117 s390_fix_long_loop_prediction (rtx_insn
*insn
)
12119 rtx set
= single_set (insn
);
12120 rtx code_label
, label_ref
, new_label
;
12121 rtx_insn
*uncond_jump
;
12122 rtx_insn
*cur_insn
;
12126 /* This will exclude branch on count and branch on index patterns
12127 since these are correctly statically predicted. */
12129 || SET_DEST (set
) != pc_rtx
12130 || GET_CODE (SET_SRC(set
)) != IF_THEN_ELSE
)
12133 /* Skip conditional returns. */
12134 if (ANY_RETURN_P (XEXP (SET_SRC (set
), 1))
12135 && XEXP (SET_SRC (set
), 2) == pc_rtx
)
12138 label_ref
= (GET_CODE (XEXP (SET_SRC (set
), 1)) == LABEL_REF
?
12139 XEXP (SET_SRC (set
), 1) : XEXP (SET_SRC (set
), 2));
12141 gcc_assert (GET_CODE (label_ref
) == LABEL_REF
);
12143 code_label
= XEXP (label_ref
, 0);
12145 if (INSN_ADDRESSES (INSN_UID (code_label
)) == -1
12146 || INSN_ADDRESSES (INSN_UID (insn
)) == -1
12147 || (INSN_ADDRESSES (INSN_UID (insn
))
12148 - INSN_ADDRESSES (INSN_UID (code_label
)) < PREDICT_DISTANCE
))
12151 for (distance
= 0, cur_insn
= PREV_INSN (insn
);
12152 distance
< PREDICT_DISTANCE
- 6;
12153 distance
+= get_attr_length (cur_insn
), cur_insn
= PREV_INSN (cur_insn
))
12154 if (!cur_insn
|| JUMP_P (cur_insn
) || LABEL_P (cur_insn
))
12157 new_label
= gen_label_rtx ();
12158 uncond_jump
= emit_jump_insn_after (
12159 gen_rtx_SET (pc_rtx
,
12160 gen_rtx_LABEL_REF (VOIDmode
, code_label
)),
12162 emit_label_after (new_label
, uncond_jump
);
12164 tmp
= XEXP (SET_SRC (set
), 1);
12165 XEXP (SET_SRC (set
), 1) = XEXP (SET_SRC (set
), 2);
12166 XEXP (SET_SRC (set
), 2) = tmp
;
12167 INSN_CODE (insn
) = -1;
12169 XEXP (label_ref
, 0) = new_label
;
12170 JUMP_LABEL (insn
) = new_label
;
12171 JUMP_LABEL (uncond_jump
) = code_label
;
12176 /* Returns 1 if INSN reads the value of REG for purposes not related
12177 to addressing of memory, and 0 otherwise. */
12179 s390_non_addr_reg_read_p (rtx reg
, rtx_insn
*insn
)
12181 return reg_referenced_p (reg
, PATTERN (insn
))
12182 && !reg_used_in_mem_p (REGNO (reg
), PATTERN (insn
));
12185 /* Starting from INSN find_cond_jump looks downwards in the insn
12186 stream for a single jump insn which is the last user of the
12187 condition code set in INSN. */
12189 find_cond_jump (rtx_insn
*insn
)
12191 for (; insn
; insn
= NEXT_INSN (insn
))
12195 if (LABEL_P (insn
))
12198 if (!JUMP_P (insn
))
12200 if (reg_mentioned_p (gen_rtx_REG (CCmode
, CC_REGNUM
), insn
))
12205 /* This will be triggered by a return. */
12206 if (GET_CODE (PATTERN (insn
)) != SET
)
12209 gcc_assert (SET_DEST (PATTERN (insn
)) == pc_rtx
);
12210 ite
= SET_SRC (PATTERN (insn
));
12212 if (GET_CODE (ite
) != IF_THEN_ELSE
)
12215 cc
= XEXP (XEXP (ite
, 0), 0);
12216 if (!REG_P (cc
) || !CC_REGNO_P (REGNO (cc
)))
12219 if (find_reg_note (insn
, REG_DEAD
, cc
))
12227 /* Swap the condition in COND and the operands in OP0 and OP1 so that
12228 the semantics does not change. If NULL_RTX is passed as COND the
12229 function tries to find the conditional jump starting with INSN. */
12231 s390_swap_cmp (rtx cond
, rtx
*op0
, rtx
*op1
, rtx_insn
*insn
)
12235 if (cond
== NULL_RTX
)
12237 rtx_insn
*jump
= find_cond_jump (NEXT_INSN (insn
));
12238 rtx set
= jump
? single_set (jump
) : NULL_RTX
;
12240 if (set
== NULL_RTX
)
12243 cond
= XEXP (SET_SRC (set
), 0);
12248 PUT_CODE (cond
, swap_condition (GET_CODE (cond
)));
12251 /* On z10, instructions of the compare-and-branch family have the
12252 property to access the register occurring as second operand with
12253 its bits complemented. If such a compare is grouped with a second
12254 instruction that accesses the same register non-complemented, and
12255 if that register's value is delivered via a bypass, then the
12256 pipeline recycles, thereby causing significant performance decline.
12257 This function locates such situations and exchanges the two
12258 operands of the compare. The function return true whenever it
12261 s390_z10_optimize_cmp (rtx_insn
*insn
)
12263 rtx_insn
*prev_insn
, *next_insn
;
12264 bool insn_added_p
= false;
12265 rtx cond
, *op0
, *op1
;
12267 if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
12269 /* Handle compare and branch and branch on count
12271 rtx pattern
= single_set (insn
);
12274 || SET_DEST (pattern
) != pc_rtx
12275 || GET_CODE (SET_SRC (pattern
)) != IF_THEN_ELSE
)
12278 cond
= XEXP (SET_SRC (pattern
), 0);
12279 op0
= &XEXP (cond
, 0);
12280 op1
= &XEXP (cond
, 1);
12282 else if (GET_CODE (PATTERN (insn
)) == SET
)
12286 /* Handle normal compare instructions. */
12287 src
= SET_SRC (PATTERN (insn
));
12288 dest
= SET_DEST (PATTERN (insn
));
12291 || !CC_REGNO_P (REGNO (dest
))
12292 || GET_CODE (src
) != COMPARE
)
12295 /* s390_swap_cmp will try to find the conditional
12296 jump when passing NULL_RTX as condition. */
12298 op0
= &XEXP (src
, 0);
12299 op1
= &XEXP (src
, 1);
12304 if (!REG_P (*op0
) || !REG_P (*op1
))
12307 if (GET_MODE_CLASS (GET_MODE (*op0
)) != MODE_INT
)
12310 /* Swap the COMPARE arguments and its mask if there is a
12311 conflicting access in the previous insn. */
12312 prev_insn
= prev_active_insn (insn
);
12313 if (prev_insn
!= NULL_RTX
&& INSN_P (prev_insn
)
12314 && reg_referenced_p (*op1
, PATTERN (prev_insn
)))
12315 s390_swap_cmp (cond
, op0
, op1
, insn
);
12317 /* Check if there is a conflict with the next insn. If there
12318 was no conflict with the previous insn, then swap the
12319 COMPARE arguments and its mask. If we already swapped
12320 the operands, or if swapping them would cause a conflict
12321 with the previous insn, issue a NOP after the COMPARE in
12322 order to separate the two instuctions. */
12323 next_insn
= next_active_insn (insn
);
12324 if (next_insn
!= NULL_RTX
&& INSN_P (next_insn
)
12325 && s390_non_addr_reg_read_p (*op1
, next_insn
))
12327 if (prev_insn
!= NULL_RTX
&& INSN_P (prev_insn
)
12328 && s390_non_addr_reg_read_p (*op0
, prev_insn
))
12330 if (REGNO (*op1
) == 0)
12331 emit_insn_after (gen_nop1 (), insn
);
12333 emit_insn_after (gen_nop (), insn
);
12334 insn_added_p
= true;
12337 s390_swap_cmp (cond
, op0
, op1
, insn
);
12339 return insn_added_p
;
12342 /* Perform machine-dependent processing. */
12347 bool pool_overflow
= false;
12348 int hw_before
, hw_after
;
12350 /* Make sure all splits have been performed; splits after
12351 machine_dependent_reorg might confuse insn length counts. */
12352 split_all_insns_noflow ();
12354 /* Install the main literal pool and the associated base
12355 register load insns.
12357 In addition, there are two problematic situations we need
12360 - the literal pool might be > 4096 bytes in size, so that
12361 some of its elements cannot be directly accessed
12363 - a branch target might be > 64K away from the branch, so that
12364 it is not possible to use a PC-relative instruction.
12366 To fix those, we split the single literal pool into multiple
12367 pool chunks, reloading the pool base register at various
12368 points throughout the function to ensure it always points to
12369 the pool chunk the following code expects, and / or replace
12370 PC-relative branches by absolute branches.
12372 However, the two problems are interdependent: splitting the
12373 literal pool can move a branch further away from its target,
12374 causing the 64K limit to overflow, and on the other hand,
12375 replacing a PC-relative branch by an absolute branch means
12376 we need to put the branch target address into the literal
12377 pool, possibly causing it to overflow.
12379 So, we loop trying to fix up both problems until we manage
12380 to satisfy both conditions at the same time. Note that the
12381 loop is guaranteed to terminate as every pass of the loop
12382 strictly decreases the total number of PC-relative branches
12383 in the function. (This is not completely true as there
12384 might be branch-over-pool insns introduced by chunkify_start.
12385 Those never need to be split however.) */
12389 struct constant_pool
*pool
= NULL
;
12391 /* Collect the literal pool. */
12392 if (!pool_overflow
)
12394 pool
= s390_mainpool_start ();
12396 pool_overflow
= true;
12399 /* If literal pool overflowed, start to chunkify it. */
12401 pool
= s390_chunkify_start ();
12403 /* Split out-of-range branches. If this has created new
12404 literal pool entries, cancel current chunk list and
12405 recompute it. zSeries machines have large branch
12406 instructions, so we never need to split a branch. */
12407 if (!TARGET_CPU_ZARCH
&& s390_split_branches ())
12410 s390_chunkify_cancel (pool
);
12412 s390_mainpool_cancel (pool
);
12417 /* If we made it up to here, both conditions are satisfied.
12418 Finish up literal pool related changes. */
12420 s390_chunkify_finish (pool
);
12422 s390_mainpool_finish (pool
);
12424 /* We're done splitting branches. */
12425 cfun
->machine
->split_branches_pending_p
= false;
12429 /* Generate out-of-pool execute target insns. */
12430 if (TARGET_CPU_ZARCH
)
12432 rtx_insn
*insn
, *target
;
12435 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
12437 label
= s390_execute_label (insn
);
12441 gcc_assert (label
!= const0_rtx
);
12443 target
= emit_label (XEXP (label
, 0));
12444 INSN_ADDRESSES_NEW (target
, -1);
12446 target
= emit_insn (s390_execute_target (insn
));
12447 INSN_ADDRESSES_NEW (target
, -1);
12451 /* Try to optimize prologue and epilogue further. */
12452 s390_optimize_prologue ();
12454 /* Walk over the insns and do some >=z10 specific changes. */
12455 if (s390_tune
== PROCESSOR_2097_Z10
12456 || s390_tune
== PROCESSOR_2817_Z196
12457 || s390_tune
== PROCESSOR_2827_ZEC12
12458 || s390_tune
== PROCESSOR_2964_Z13
)
12461 bool insn_added_p
= false;
12463 /* The insn lengths and addresses have to be up to date for the
12464 following manipulations. */
12465 shorten_branches (get_insns ());
12467 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
12469 if (!INSN_P (insn
) || INSN_CODE (insn
) <= 0)
12473 insn_added_p
|= s390_fix_long_loop_prediction (insn
);
12475 if ((GET_CODE (PATTERN (insn
)) == PARALLEL
12476 || GET_CODE (PATTERN (insn
)) == SET
)
12477 && s390_tune
== PROCESSOR_2097_Z10
)
12478 insn_added_p
|= s390_z10_optimize_cmp (insn
);
12481 /* Adjust branches if we added new instructions. */
12483 shorten_branches (get_insns ());
12486 s390_function_num_hotpatch_hw (current_function_decl
, &hw_before
, &hw_after
);
12491 /* Insert NOPs for hotpatching. */
12492 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
12494 if (NOTE_P (insn
) && NOTE_KIND (insn
) == NOTE_INSN_FUNCTION_BEG
)
12498 /* Output a series of NOPs after the NOTE_INSN_FUNCTION_BEG. */
12499 while (hw_after
> 0)
12501 if (hw_after
>= 3 && TARGET_CPU_ZARCH
)
12503 insn
= emit_insn_after (gen_nop_6_byte (), insn
);
12506 else if (hw_after
>= 2)
12508 insn
= emit_insn_after (gen_nop_4_byte (), insn
);
12513 insn
= emit_insn_after (gen_nop_2_byte (), insn
);
12517 gcc_assert (hw_after
== 0);
12521 /* Return true if INSN is a fp load insn writing register REGNO. */
12523 s390_fpload_toreg (rtx_insn
*insn
, unsigned int regno
)
12526 enum attr_type flag
= s390_safe_attr_type (insn
);
12528 if (flag
!= TYPE_FLOADSF
&& flag
!= TYPE_FLOADDF
)
12531 set
= single_set (insn
);
12533 if (set
== NULL_RTX
)
12536 if (!REG_P (SET_DEST (set
)) || !MEM_P (SET_SRC (set
)))
12539 if (REGNO (SET_DEST (set
)) != regno
)
12545 /* This value describes the distance to be avoided between an
12546 aritmetic fp instruction and an fp load writing the same register.
12547 Z10_EARLYLOAD_DISTANCE - 1 as well as Z10_EARLYLOAD_DISTANCE + 1 is
12548 fine but the exact value has to be avoided. Otherwise the FP
12549 pipeline will throw an exception causing a major penalty. */
12550 #define Z10_EARLYLOAD_DISTANCE 7
12552 /* Rearrange the ready list in order to avoid the situation described
12553 for Z10_EARLYLOAD_DISTANCE. A problematic load instruction is
12554 moved to the very end of the ready list. */
12556 s390_z10_prevent_earlyload_conflicts (rtx_insn
**ready
, int *nready_p
)
12558 unsigned int regno
;
12559 int nready
= *nready_p
;
12564 enum attr_type flag
;
12567 /* Skip DISTANCE - 1 active insns. */
12568 for (insn
= last_scheduled_insn
, distance
= Z10_EARLYLOAD_DISTANCE
- 1;
12569 distance
> 0 && insn
!= NULL_RTX
;
12570 distance
--, insn
= prev_active_insn (insn
))
12571 if (CALL_P (insn
) || JUMP_P (insn
))
12574 if (insn
== NULL_RTX
)
12577 set
= single_set (insn
);
12579 if (set
== NULL_RTX
|| !REG_P (SET_DEST (set
))
12580 || GET_MODE_CLASS (GET_MODE (SET_DEST (set
))) != MODE_FLOAT
)
12583 flag
= s390_safe_attr_type (insn
);
12585 if (flag
== TYPE_FLOADSF
|| flag
== TYPE_FLOADDF
)
12588 regno
= REGNO (SET_DEST (set
));
12591 while (!s390_fpload_toreg (ready
[i
], regno
) && i
> 0)
12598 memmove (&ready
[1], &ready
[0], sizeof (rtx_insn
*) * i
);
12603 /* The s390_sched_state variable tracks the state of the current or
12604 the last instruction group.
12606 0,1,2 number of instructions scheduled in the current group
12607 3 the last group is complete - normal insns
12608 4 the last group was a cracked/expanded insn */
12610 static int s390_sched_state
;
12612 #define S390_OOO_SCHED_STATE_NORMAL 3
12613 #define S390_OOO_SCHED_STATE_CRACKED 4
12615 #define S390_OOO_SCHED_ATTR_MASK_CRACKED 0x1
12616 #define S390_OOO_SCHED_ATTR_MASK_EXPANDED 0x2
12617 #define S390_OOO_SCHED_ATTR_MASK_ENDGROUP 0x4
12618 #define S390_OOO_SCHED_ATTR_MASK_GROUPALONE 0x8
12620 static unsigned int
12621 s390_get_sched_attrmask (rtx_insn
*insn
)
12623 unsigned int mask
= 0;
12625 if (get_attr_ooo_cracked (insn
))
12626 mask
|= S390_OOO_SCHED_ATTR_MASK_CRACKED
;
12627 if (get_attr_ooo_expanded (insn
))
12628 mask
|= S390_OOO_SCHED_ATTR_MASK_EXPANDED
;
12629 if (get_attr_ooo_endgroup (insn
))
12630 mask
|= S390_OOO_SCHED_ATTR_MASK_ENDGROUP
;
12631 if (get_attr_ooo_groupalone (insn
))
12632 mask
|= S390_OOO_SCHED_ATTR_MASK_GROUPALONE
;
12636 /* Return the scheduling score for INSN. The higher the score the
12637 better. The score is calculated from the OOO scheduling attributes
12638 of INSN and the scheduling state s390_sched_state. */
12640 s390_sched_score (rtx_insn
*insn
)
12642 unsigned int mask
= s390_get_sched_attrmask (insn
);
12645 switch (s390_sched_state
)
12648 /* Try to put insns into the first slot which would otherwise
12650 if ((mask
& S390_OOO_SCHED_ATTR_MASK_CRACKED
) != 0
12651 || (mask
& S390_OOO_SCHED_ATTR_MASK_EXPANDED
) != 0)
12653 if ((mask
& S390_OOO_SCHED_ATTR_MASK_GROUPALONE
) != 0)
12656 /* Prefer not cracked insns while trying to put together a
12658 if ((mask
& S390_OOO_SCHED_ATTR_MASK_CRACKED
) == 0
12659 && (mask
& S390_OOO_SCHED_ATTR_MASK_EXPANDED
) == 0
12660 && (mask
& S390_OOO_SCHED_ATTR_MASK_GROUPALONE
) == 0)
12662 if ((mask
& S390_OOO_SCHED_ATTR_MASK_ENDGROUP
) == 0)
12666 /* Prefer not cracked insns while trying to put together a
12668 if ((mask
& S390_OOO_SCHED_ATTR_MASK_CRACKED
) == 0
12669 && (mask
& S390_OOO_SCHED_ATTR_MASK_EXPANDED
) == 0
12670 && (mask
& S390_OOO_SCHED_ATTR_MASK_GROUPALONE
) == 0)
12672 /* Prefer endgroup insns in the last slot. */
12673 if ((mask
& S390_OOO_SCHED_ATTR_MASK_ENDGROUP
) != 0)
12676 case S390_OOO_SCHED_STATE_NORMAL
:
12677 /* Prefer not cracked insns if the last was not cracked. */
12678 if ((mask
& S390_OOO_SCHED_ATTR_MASK_CRACKED
) == 0
12679 && (mask
& S390_OOO_SCHED_ATTR_MASK_EXPANDED
) == 0)
12681 if ((mask
& S390_OOO_SCHED_ATTR_MASK_GROUPALONE
) != 0)
12684 case S390_OOO_SCHED_STATE_CRACKED
:
12685 /* Try to keep cracked insns together to prevent them from
12686 interrupting groups. */
12687 if ((mask
& S390_OOO_SCHED_ATTR_MASK_CRACKED
) != 0
12688 || (mask
& S390_OOO_SCHED_ATTR_MASK_EXPANDED
) != 0)
12695 /* This function is called via hook TARGET_SCHED_REORDER before
12696 issuing one insn from list READY which contains *NREADYP entries.
12697 For target z10 it reorders load instructions to avoid early load
12698 conflicts in the floating point pipeline */
12700 s390_sched_reorder (FILE *file
, int verbose
,
12701 rtx_insn
**ready
, int *nreadyp
, int clock ATTRIBUTE_UNUSED
)
12703 if (s390_tune
== PROCESSOR_2097_Z10
)
12704 if (reload_completed
&& *nreadyp
> 1)
12705 s390_z10_prevent_earlyload_conflicts (ready
, nreadyp
);
12707 if ((s390_tune
== PROCESSOR_2827_ZEC12
12708 || s390_tune
== PROCESSOR_2964_Z13
)
12709 && reload_completed
12713 int last_index
= *nreadyp
- 1;
12714 int max_index
= -1;
12715 int max_score
= -1;
12718 /* Just move the insn with the highest score to the top (the
12719 end) of the list. A full sort is not needed since a conflict
12720 in the hazard recognition cannot happen. So the top insn in
12721 the ready list will always be taken. */
12722 for (i
= last_index
; i
>= 0; i
--)
12726 if (recog_memoized (ready
[i
]) < 0)
12729 score
= s390_sched_score (ready
[i
]);
12730 if (score
> max_score
)
12737 if (max_index
!= -1)
12739 if (max_index
!= last_index
)
12741 tmp
= ready
[max_index
];
12742 ready
[max_index
] = ready
[last_index
];
12743 ready
[last_index
] = tmp
;
12747 "move insn %d to the top of list\n",
12748 INSN_UID (ready
[last_index
]));
12750 else if (verbose
> 5)
12752 "best insn %d already on top\n",
12753 INSN_UID (ready
[last_index
]));
12758 fprintf (file
, "ready list ooo attributes - sched state: %d\n",
12761 for (i
= last_index
; i
>= 0; i
--)
12763 if (recog_memoized (ready
[i
]) < 0)
12765 fprintf (file
, "insn %d score: %d: ", INSN_UID (ready
[i
]),
12766 s390_sched_score (ready
[i
]));
12767 #define PRINT_OOO_ATTR(ATTR) fprintf (file, "%s ", get_attr_##ATTR (ready[i]) ? #ATTR : "!" #ATTR);
12768 PRINT_OOO_ATTR (ooo_cracked
);
12769 PRINT_OOO_ATTR (ooo_expanded
);
12770 PRINT_OOO_ATTR (ooo_endgroup
);
12771 PRINT_OOO_ATTR (ooo_groupalone
);
12772 #undef PRINT_OOO_ATTR
12773 fprintf (file
, "\n");
12778 return s390_issue_rate ();
12782 /* This function is called via hook TARGET_SCHED_VARIABLE_ISSUE after
12783 the scheduler has issued INSN. It stores the last issued insn into
12784 last_scheduled_insn in order to make it available for
12785 s390_sched_reorder. */
12787 s390_sched_variable_issue (FILE *file
, int verbose
, rtx_insn
*insn
, int more
)
12789 last_scheduled_insn
= insn
;
12791 if ((s390_tune
== PROCESSOR_2827_ZEC12
12792 || s390_tune
== PROCESSOR_2964_Z13
)
12793 && reload_completed
12794 && recog_memoized (insn
) >= 0)
12796 unsigned int mask
= s390_get_sched_attrmask (insn
);
12798 if ((mask
& S390_OOO_SCHED_ATTR_MASK_CRACKED
) != 0
12799 || (mask
& S390_OOO_SCHED_ATTR_MASK_EXPANDED
) != 0)
12800 s390_sched_state
= S390_OOO_SCHED_STATE_CRACKED
;
12801 else if ((mask
& S390_OOO_SCHED_ATTR_MASK_ENDGROUP
) != 0
12802 || (mask
& S390_OOO_SCHED_ATTR_MASK_GROUPALONE
) != 0)
12803 s390_sched_state
= S390_OOO_SCHED_STATE_NORMAL
;
12806 /* Only normal insns are left (mask == 0). */
12807 switch (s390_sched_state
)
12812 case S390_OOO_SCHED_STATE_NORMAL
:
12813 if (s390_sched_state
== S390_OOO_SCHED_STATE_NORMAL
)
12814 s390_sched_state
= 1;
12816 s390_sched_state
++;
12819 case S390_OOO_SCHED_STATE_CRACKED
:
12820 s390_sched_state
= S390_OOO_SCHED_STATE_NORMAL
;
12826 fprintf (file
, "insn %d: ", INSN_UID (insn
));
12827 #define PRINT_OOO_ATTR(ATTR) \
12828 fprintf (file, "%s ", get_attr_##ATTR (insn) ? #ATTR : "");
12829 PRINT_OOO_ATTR (ooo_cracked
);
12830 PRINT_OOO_ATTR (ooo_expanded
);
12831 PRINT_OOO_ATTR (ooo_endgroup
);
12832 PRINT_OOO_ATTR (ooo_groupalone
);
12833 #undef PRINT_OOO_ATTR
12834 fprintf (file
, "\n");
12835 fprintf (file
, "sched state: %d\n", s390_sched_state
);
12839 if (GET_CODE (PATTERN (insn
)) != USE
12840 && GET_CODE (PATTERN (insn
)) != CLOBBER
)
12847 s390_sched_init (FILE *file ATTRIBUTE_UNUSED
,
12848 int verbose ATTRIBUTE_UNUSED
,
12849 int max_ready ATTRIBUTE_UNUSED
)
12851 last_scheduled_insn
= NULL
;
12852 s390_sched_state
= 0;
12855 /* This target hook implementation for TARGET_LOOP_UNROLL_ADJUST calculates
12856 a new number struct loop *loop should be unrolled if tuned for cpus with
12857 a built-in stride prefetcher.
12858 The loop is analyzed for memory accesses by calling check_dpu for
12859 each rtx of the loop. Depending on the loop_depth and the amount of
12860 memory accesses a new number <=nunroll is returned to improve the
12861 behaviour of the hardware prefetch unit. */
12863 s390_loop_unroll_adjust (unsigned nunroll
, struct loop
*loop
)
12868 unsigned mem_count
= 0;
12870 if (s390_tune
!= PROCESSOR_2097_Z10
12871 && s390_tune
!= PROCESSOR_2817_Z196
12872 && s390_tune
!= PROCESSOR_2827_ZEC12
12873 && s390_tune
!= PROCESSOR_2964_Z13
)
12876 /* Count the number of memory references within the loop body. */
12877 bbs
= get_loop_body (loop
);
12878 subrtx_iterator::array_type array
;
12879 for (i
= 0; i
< loop
->num_nodes
; i
++)
12880 FOR_BB_INSNS (bbs
[i
], insn
)
12881 if (INSN_P (insn
) && INSN_CODE (insn
) != -1)
12882 FOR_EACH_SUBRTX (iter
, array
, PATTERN (insn
), NONCONST
)
12887 /* Prevent division by zero, and we do not need to adjust nunroll in this case. */
12888 if (mem_count
== 0)
12891 switch (loop_depth(loop
))
12894 return MIN (nunroll
, 28 / mem_count
);
12896 return MIN (nunroll
, 22 / mem_count
);
12898 return MIN (nunroll
, 16 / mem_count
);
12903 s390_option_override (void)
12906 cl_deferred_option
*opt
;
12907 vec
<cl_deferred_option
> *v
=
12908 (vec
<cl_deferred_option
> *) s390_deferred_options
;
12911 FOR_EACH_VEC_ELT (*v
, i
, opt
)
12913 switch (opt
->opt_index
)
12915 case OPT_mhotpatch_
:
12922 strncpy (s
, opt
->arg
, 256);
12924 t
= strchr (s
, ',');
12929 val1
= integral_argument (s
);
12930 val2
= integral_argument (t
);
12937 if (val1
== -1 || val2
== -1)
12939 /* argument is not a plain number */
12940 error ("arguments to %qs should be non-negative integers",
12944 else if (val1
> s390_hotpatch_hw_max
12945 || val2
> s390_hotpatch_hw_max
)
12947 error ("argument to %qs is too large (max. %d)",
12948 "-mhotpatch=n,m", s390_hotpatch_hw_max
);
12951 s390_hotpatch_hw_before_label
= val1
;
12952 s390_hotpatch_hw_after_label
= val2
;
12956 gcc_unreachable ();
12960 /* Set up function hooks. */
12961 init_machine_status
= s390_init_machine_status
;
12963 /* Architecture mode defaults according to ABI. */
12964 if (!(target_flags_explicit
& MASK_ZARCH
))
12967 target_flags
|= MASK_ZARCH
;
12969 target_flags
&= ~MASK_ZARCH
;
12972 /* Set the march default in case it hasn't been specified on
12974 if (s390_arch
== PROCESSOR_max
)
12976 s390_arch_string
= TARGET_ZARCH
? "z900" : "g5";
12977 s390_arch
= TARGET_ZARCH
? PROCESSOR_2064_Z900
: PROCESSOR_9672_G5
;
12978 s390_arch_flags
= processor_flags_table
[(int)s390_arch
];
12981 /* Determine processor to tune for. */
12982 if (s390_tune
== PROCESSOR_max
)
12984 s390_tune
= s390_arch
;
12985 s390_tune_flags
= s390_arch_flags
;
12988 /* Sanity checks. */
12989 if (TARGET_ZARCH
&& !TARGET_CPU_ZARCH
)
12990 error ("z/Architecture mode not supported on %s", s390_arch_string
);
12991 if (TARGET_64BIT
&& !TARGET_ZARCH
)
12992 error ("64-bit ABI not supported in ESA/390 mode");
12994 /* Use hardware DFP if available and not explicitly disabled by
12995 user. E.g. with -m31 -march=z10 -mzarch */
12996 if (!(target_flags_explicit
& MASK_HARD_DFP
) && TARGET_DFP
)
12997 target_flags
|= MASK_HARD_DFP
;
12999 /* Enable hardware transactions if available and not explicitly
13000 disabled by user. E.g. with -m31 -march=zEC12 -mzarch */
13001 if (!(target_flags_explicit
& MASK_OPT_HTM
) && TARGET_CPU_HTM
&& TARGET_ZARCH
)
13002 target_flags
|= MASK_OPT_HTM
;
13004 if (target_flags_explicit
& MASK_OPT_VX
)
13008 if (!TARGET_CPU_VX
)
13009 error ("hardware vector support not available on %s",
13011 if (TARGET_SOFT_FLOAT
)
13012 error ("hardware vector support not available with -msoft-float");
13015 else if (TARGET_CPU_VX
)
13016 /* Enable vector support if available and not explicitly disabled
13017 by user. E.g. with -m31 -march=z13 -mzarch */
13018 target_flags
|= MASK_OPT_VX
;
13020 if (TARGET_HARD_DFP
&& !TARGET_DFP
)
13022 if (target_flags_explicit
& MASK_HARD_DFP
)
13024 if (!TARGET_CPU_DFP
)
13025 error ("hardware decimal floating point instructions"
13026 " not available on %s", s390_arch_string
);
13028 error ("hardware decimal floating point instructions"
13029 " not available in ESA/390 mode");
13032 target_flags
&= ~MASK_HARD_DFP
;
13035 if ((target_flags_explicit
& MASK_SOFT_FLOAT
) && TARGET_SOFT_FLOAT
)
13037 if ((target_flags_explicit
& MASK_HARD_DFP
) && TARGET_HARD_DFP
)
13038 error ("-mhard-dfp can%'t be used in conjunction with -msoft-float");
13040 target_flags
&= ~MASK_HARD_DFP
;
13043 /* Set processor cost function. */
13046 case PROCESSOR_2084_Z990
:
13047 s390_cost
= &z990_cost
;
13049 case PROCESSOR_2094_Z9_109
:
13050 s390_cost
= &z9_109_cost
;
13052 case PROCESSOR_2097_Z10
:
13053 s390_cost
= &z10_cost
;
13055 case PROCESSOR_2817_Z196
:
13056 s390_cost
= &z196_cost
;
13058 case PROCESSOR_2827_ZEC12
:
13059 case PROCESSOR_2964_Z13
:
13060 s390_cost
= &zEC12_cost
;
13063 s390_cost
= &z900_cost
;
13066 if (TARGET_BACKCHAIN
&& TARGET_PACKED_STACK
&& TARGET_HARD_FLOAT
)
13067 error ("-mbackchain -mpacked-stack -mhard-float are not supported "
13070 if (s390_stack_size
)
13072 if (s390_stack_guard
>= s390_stack_size
)
13073 error ("stack size must be greater than the stack guard value");
13074 else if (s390_stack_size
> 1 << 16)
13075 error ("stack size must not be greater than 64k");
13077 else if (s390_stack_guard
)
13078 error ("-mstack-guard implies use of -mstack-size");
13080 #ifdef TARGET_DEFAULT_LONG_DOUBLE_128
13081 if (!(target_flags_explicit
& MASK_LONG_DOUBLE_128
))
13082 target_flags
|= MASK_LONG_DOUBLE_128
;
13085 if (s390_tune
== PROCESSOR_2097_Z10
13086 || s390_tune
== PROCESSOR_2817_Z196
13087 || s390_tune
== PROCESSOR_2827_ZEC12
13088 || s390_tune
== PROCESSOR_2964_Z13
)
13090 maybe_set_param_value (PARAM_MAX_UNROLLED_INSNS
, 100,
13091 global_options
.x_param_values
,
13092 global_options_set
.x_param_values
);
13093 maybe_set_param_value (PARAM_MAX_UNROLL_TIMES
, 32,
13094 global_options
.x_param_values
,
13095 global_options_set
.x_param_values
);
13096 maybe_set_param_value (PARAM_MAX_COMPLETELY_PEELED_INSNS
, 2000,
13097 global_options
.x_param_values
,
13098 global_options_set
.x_param_values
);
13099 maybe_set_param_value (PARAM_MAX_COMPLETELY_PEEL_TIMES
, 64,
13100 global_options
.x_param_values
,
13101 global_options_set
.x_param_values
);
13104 maybe_set_param_value (PARAM_MAX_PENDING_LIST_LENGTH
, 256,
13105 global_options
.x_param_values
,
13106 global_options_set
.x_param_values
);
13107 /* values for loop prefetching */
13108 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE
, 256,
13109 global_options
.x_param_values
,
13110 global_options_set
.x_param_values
);
13111 maybe_set_param_value (PARAM_L1_CACHE_SIZE
, 128,
13112 global_options
.x_param_values
,
13113 global_options_set
.x_param_values
);
13114 /* s390 has more than 2 levels and the size is much larger. Since
13115 we are always running virtualized assume that we only get a small
13116 part of the caches above l1. */
13117 maybe_set_param_value (PARAM_L2_CACHE_SIZE
, 1500,
13118 global_options
.x_param_values
,
13119 global_options_set
.x_param_values
);
13120 maybe_set_param_value (PARAM_PREFETCH_MIN_INSN_TO_MEM_RATIO
, 2,
13121 global_options
.x_param_values
,
13122 global_options_set
.x_param_values
);
13123 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES
, 6,
13124 global_options
.x_param_values
,
13125 global_options_set
.x_param_values
);
13127 /* This cannot reside in s390_option_optimization_table since HAVE_prefetch
13128 requires the arch flags to be evaluated already. Since prefetching
13129 is beneficial on s390, we enable it if available. */
13130 if (flag_prefetch_loop_arrays
< 0 && HAVE_prefetch
&& optimize
>= 3)
13131 flag_prefetch_loop_arrays
= 1;
13133 /* Use the alternative scheduling-pressure algorithm by default. */
13134 maybe_set_param_value (PARAM_SCHED_PRESSURE_ALGORITHM
, 2,
13135 global_options
.x_param_values
,
13136 global_options_set
.x_param_values
);
13140 /* Don't emit DWARF3/4 unless specifically selected. The TPF
13141 debuggers do not yet support DWARF 3/4. */
13142 if (!global_options_set
.x_dwarf_strict
)
13144 if (!global_options_set
.x_dwarf_version
)
13148 /* Register a target-specific optimization-and-lowering pass
13149 to run immediately before prologue and epilogue generation.
13151 Registering the pass must be done at start up. It's
13152 convenient to do it here. */
13153 opt_pass
*new_pass
= new pass_s390_early_mach (g
);
13154 struct register_pass_info insert_pass_s390_early_mach
=
13156 new_pass
, /* pass */
13157 "pro_and_epilogue", /* reference_pass_name */
13158 1, /* ref_pass_instance_number */
13159 PASS_POS_INSERT_BEFORE
/* po_op */
13161 register_pass (&insert_pass_s390_early_mach
);
13164 /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
13167 s390_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size
,
13168 unsigned int align ATTRIBUTE_UNUSED
,
13169 enum by_pieces_operation op ATTRIBUTE_UNUSED
,
13170 bool speed_p ATTRIBUTE_UNUSED
)
13172 return (size
== 1 || size
== 2
13173 || size
== 4 || (TARGET_ZARCH
&& size
== 8));
13176 /* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV hook. */
13179 s390_atomic_assign_expand_fenv (tree
*hold
, tree
*clear
, tree
*update
)
13181 tree sfpc
= s390_builtin_decls
[S390_BUILTIN_S390_SFPC
];
13182 tree efpc
= s390_builtin_decls
[S390_BUILTIN_S390_EFPC
];
13183 tree call_efpc
= build_call_expr (efpc
, 0);
13184 tree fenv_var
= create_tmp_var (unsigned_type_node
);
13186 #define FPC_EXCEPTION_MASK HOST_WIDE_INT_UC (0xf8000000)
13187 #define FPC_FLAGS_MASK HOST_WIDE_INT_UC (0x00f80000)
13188 #define FPC_DXC_MASK HOST_WIDE_INT_UC (0x0000ff00)
13189 #define FPC_EXCEPTION_MASK_SHIFT HOST_WIDE_INT_UC (24)
13190 #define FPC_FLAGS_SHIFT HOST_WIDE_INT_UC (16)
13191 #define FPC_DXC_SHIFT HOST_WIDE_INT_UC (8)
13193 /* Generates the equivalent of feholdexcept (&fenv_var)
13195 fenv_var = __builtin_s390_efpc ();
13196 __builtin_s390_sfpc (fenv_var & mask) */
13197 tree old_fpc
= build2 (MODIFY_EXPR
, unsigned_type_node
, fenv_var
, call_efpc
);
13199 build2 (BIT_AND_EXPR
, unsigned_type_node
, fenv_var
,
13200 build_int_cst (unsigned_type_node
,
13201 ~(FPC_DXC_MASK
| FPC_FLAGS_MASK
|
13202 FPC_EXCEPTION_MASK
)));
13203 tree set_new_fpc
= build_call_expr (sfpc
, 1, new_fpc
);
13204 *hold
= build2 (COMPOUND_EXPR
, void_type_node
, old_fpc
, set_new_fpc
);
13206 /* Generates the equivalent of feclearexcept (FE_ALL_EXCEPT)
13208 __builtin_s390_sfpc (__builtin_s390_efpc () & mask) */
13209 new_fpc
= build2 (BIT_AND_EXPR
, unsigned_type_node
, call_efpc
,
13210 build_int_cst (unsigned_type_node
,
13211 ~(FPC_DXC_MASK
| FPC_FLAGS_MASK
)));
13212 *clear
= build_call_expr (sfpc
, 1, new_fpc
);
13214 /* Generates the equivalent of feupdateenv (fenv_var)
13216 old_fpc = __builtin_s390_efpc ();
13217 __builtin_s390_sfpc (fenv_var);
13218 __atomic_feraiseexcept ((old_fpc & FPC_FLAGS_MASK) >> FPC_FLAGS_SHIFT); */
13220 old_fpc
= create_tmp_var (unsigned_type_node
);
13221 tree store_old_fpc
= build2 (MODIFY_EXPR
, void_type_node
,
13222 old_fpc
, call_efpc
);
13224 set_new_fpc
= build_call_expr (sfpc
, 1, fenv_var
);
13226 tree raise_old_except
= build2 (BIT_AND_EXPR
, unsigned_type_node
, old_fpc
,
13227 build_int_cst (unsigned_type_node
,
13229 raise_old_except
= build2 (RSHIFT_EXPR
, unsigned_type_node
, raise_old_except
,
13230 build_int_cst (unsigned_type_node
,
13232 tree atomic_feraiseexcept
13233 = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT
);
13234 raise_old_except
= build_call_expr (atomic_feraiseexcept
,
13235 1, raise_old_except
);
13237 *update
= build2 (COMPOUND_EXPR
, void_type_node
,
13238 build2 (COMPOUND_EXPR
, void_type_node
,
13239 store_old_fpc
, set_new_fpc
),
13242 #undef FPC_EXCEPTION_MASK
13243 #undef FPC_FLAGS_MASK
13244 #undef FPC_DXC_MASK
13245 #undef FPC_EXCEPTION_MASK_SHIFT
13246 #undef FPC_FLAGS_SHIFT
13247 #undef FPC_DXC_SHIFT
13250 /* Return the vector mode to be used for inner mode MODE when doing
13252 static machine_mode
13253 s390_preferred_simd_mode (machine_mode mode
)
13273 /* Our hardware does not require vectors to be strictly aligned. */
13275 s390_support_vector_misalignment (machine_mode mode ATTRIBUTE_UNUSED
,
13276 const_tree type ATTRIBUTE_UNUSED
,
13277 int misalignment ATTRIBUTE_UNUSED
,
13278 bool is_packed ATTRIBUTE_UNUSED
)
13283 /* The vector ABI requires vector types to be aligned on an 8 byte
13284 boundary (our stack alignment). However, we allow this to be
13285 overriden by the user, while this definitely breaks the ABI. */
13286 static HOST_WIDE_INT
13287 s390_vector_alignment (const_tree type
)
13289 if (!TARGET_VX_ABI
)
13290 return default_vector_alignment (type
);
13292 if (TYPE_USER_ALIGN (type
))
13293 return TYPE_ALIGN (type
);
13295 return MIN (64, tree_to_shwi (TYPE_SIZE (type
)));
13299 /* Initialize GCC target structure. */
13301 #undef TARGET_ASM_ALIGNED_HI_OP
13302 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
13303 #undef TARGET_ASM_ALIGNED_DI_OP
13304 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
13305 #undef TARGET_ASM_INTEGER
13306 #define TARGET_ASM_INTEGER s390_assemble_integer
13308 #undef TARGET_ASM_OPEN_PAREN
13309 #define TARGET_ASM_OPEN_PAREN ""
13311 #undef TARGET_ASM_CLOSE_PAREN
13312 #define TARGET_ASM_CLOSE_PAREN ""
13314 #undef TARGET_OPTION_OVERRIDE
13315 #define TARGET_OPTION_OVERRIDE s390_option_override
13317 #undef TARGET_ENCODE_SECTION_INFO
13318 #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
13320 #undef TARGET_SCALAR_MODE_SUPPORTED_P
13321 #define TARGET_SCALAR_MODE_SUPPORTED_P s390_scalar_mode_supported_p
13324 #undef TARGET_HAVE_TLS
13325 #define TARGET_HAVE_TLS true
13327 #undef TARGET_CANNOT_FORCE_CONST_MEM
13328 #define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
13330 #undef TARGET_DELEGITIMIZE_ADDRESS
13331 #define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
13333 #undef TARGET_LEGITIMIZE_ADDRESS
13334 #define TARGET_LEGITIMIZE_ADDRESS s390_legitimize_address
13336 #undef TARGET_RETURN_IN_MEMORY
13337 #define TARGET_RETURN_IN_MEMORY s390_return_in_memory
13339 #undef TARGET_INIT_BUILTINS
13340 #define TARGET_INIT_BUILTINS s390_init_builtins
13341 #undef TARGET_EXPAND_BUILTIN
13342 #define TARGET_EXPAND_BUILTIN s390_expand_builtin
13343 #undef TARGET_BUILTIN_DECL
13344 #define TARGET_BUILTIN_DECL s390_builtin_decl
13346 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
13347 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA s390_output_addr_const_extra
13349 #undef TARGET_ASM_OUTPUT_MI_THUNK
13350 #define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
13351 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
13352 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
13354 #undef TARGET_SCHED_ADJUST_PRIORITY
13355 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
13356 #undef TARGET_SCHED_ISSUE_RATE
13357 #define TARGET_SCHED_ISSUE_RATE s390_issue_rate
13358 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
13359 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
13361 #undef TARGET_SCHED_VARIABLE_ISSUE
13362 #define TARGET_SCHED_VARIABLE_ISSUE s390_sched_variable_issue
13363 #undef TARGET_SCHED_REORDER
13364 #define TARGET_SCHED_REORDER s390_sched_reorder
13365 #undef TARGET_SCHED_INIT
13366 #define TARGET_SCHED_INIT s390_sched_init
13368 #undef TARGET_CANNOT_COPY_INSN_P
13369 #define TARGET_CANNOT_COPY_INSN_P s390_cannot_copy_insn_p
13370 #undef TARGET_RTX_COSTS
13371 #define TARGET_RTX_COSTS s390_rtx_costs
13372 #undef TARGET_ADDRESS_COST
13373 #define TARGET_ADDRESS_COST s390_address_cost
13374 #undef TARGET_REGISTER_MOVE_COST
13375 #define TARGET_REGISTER_MOVE_COST s390_register_move_cost
13376 #undef TARGET_MEMORY_MOVE_COST
13377 #define TARGET_MEMORY_MOVE_COST s390_memory_move_cost
13379 #undef TARGET_MACHINE_DEPENDENT_REORG
13380 #define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
13382 #undef TARGET_VALID_POINTER_MODE
13383 #define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
13385 #undef TARGET_BUILD_BUILTIN_VA_LIST
13386 #define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
13387 #undef TARGET_EXPAND_BUILTIN_VA_START
13388 #define TARGET_EXPAND_BUILTIN_VA_START s390_va_start
13389 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
13390 #define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg
13392 #undef TARGET_PROMOTE_FUNCTION_MODE
13393 #define TARGET_PROMOTE_FUNCTION_MODE s390_promote_function_mode
13394 #undef TARGET_PASS_BY_REFERENCE
13395 #define TARGET_PASS_BY_REFERENCE s390_pass_by_reference
13397 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
13398 #define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
13399 #undef TARGET_FUNCTION_ARG
13400 #define TARGET_FUNCTION_ARG s390_function_arg
13401 #undef TARGET_FUNCTION_ARG_ADVANCE
13402 #define TARGET_FUNCTION_ARG_ADVANCE s390_function_arg_advance
13403 #undef TARGET_FUNCTION_VALUE
13404 #define TARGET_FUNCTION_VALUE s390_function_value
13405 #undef TARGET_LIBCALL_VALUE
13406 #define TARGET_LIBCALL_VALUE s390_libcall_value
13407 #undef TARGET_STRICT_ARGUMENT_NAMING
13408 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
13410 #undef TARGET_KEEP_LEAF_WHEN_PROFILED
13411 #define TARGET_KEEP_LEAF_WHEN_PROFILED s390_keep_leaf_when_profiled
13413 #undef TARGET_FIXED_CONDITION_CODE_REGS
13414 #define TARGET_FIXED_CONDITION_CODE_REGS s390_fixed_condition_code_regs
13416 #undef TARGET_CC_MODES_COMPATIBLE
13417 #define TARGET_CC_MODES_COMPATIBLE s390_cc_modes_compatible
13419 #undef TARGET_INVALID_WITHIN_DOLOOP
13420 #define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_const_rtx_insn_null
13423 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
13424 #define TARGET_ASM_OUTPUT_DWARF_DTPREL s390_output_dwarf_dtprel
13427 #undef TARGET_DWARF_FRAME_REG_MODE
13428 #define TARGET_DWARF_FRAME_REG_MODE s390_dwarf_frame_reg_mode
13430 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
13431 #undef TARGET_MANGLE_TYPE
13432 #define TARGET_MANGLE_TYPE s390_mangle_type
13435 #undef TARGET_SCALAR_MODE_SUPPORTED_P
13436 #define TARGET_SCALAR_MODE_SUPPORTED_P s390_scalar_mode_supported_p
13438 #undef TARGET_VECTOR_MODE_SUPPORTED_P
13439 #define TARGET_VECTOR_MODE_SUPPORTED_P s390_vector_mode_supported_p
13441 #undef TARGET_PREFERRED_RELOAD_CLASS
13442 #define TARGET_PREFERRED_RELOAD_CLASS s390_preferred_reload_class
13444 #undef TARGET_SECONDARY_RELOAD
13445 #define TARGET_SECONDARY_RELOAD s390_secondary_reload
13447 #undef TARGET_LIBGCC_CMP_RETURN_MODE
13448 #define TARGET_LIBGCC_CMP_RETURN_MODE s390_libgcc_cmp_return_mode
13450 #undef TARGET_LIBGCC_SHIFT_COUNT_MODE
13451 #define TARGET_LIBGCC_SHIFT_COUNT_MODE s390_libgcc_shift_count_mode
13453 #undef TARGET_LEGITIMATE_ADDRESS_P
13454 #define TARGET_LEGITIMATE_ADDRESS_P s390_legitimate_address_p
13456 #undef TARGET_LEGITIMATE_CONSTANT_P
13457 #define TARGET_LEGITIMATE_CONSTANT_P s390_legitimate_constant_p
13459 #undef TARGET_LRA_P
13460 #define TARGET_LRA_P s390_lra_p
13462 #undef TARGET_CAN_ELIMINATE
13463 #define TARGET_CAN_ELIMINATE s390_can_eliminate
13465 #undef TARGET_CONDITIONAL_REGISTER_USAGE
13466 #define TARGET_CONDITIONAL_REGISTER_USAGE s390_conditional_register_usage
13468 #undef TARGET_LOOP_UNROLL_ADJUST
13469 #define TARGET_LOOP_UNROLL_ADJUST s390_loop_unroll_adjust
13471 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
13472 #define TARGET_ASM_TRAMPOLINE_TEMPLATE s390_asm_trampoline_template
13473 #undef TARGET_TRAMPOLINE_INIT
13474 #define TARGET_TRAMPOLINE_INIT s390_trampoline_init
13476 #undef TARGET_UNWIND_WORD_MODE
13477 #define TARGET_UNWIND_WORD_MODE s390_unwind_word_mode
13479 #undef TARGET_CANONICALIZE_COMPARISON
13480 #define TARGET_CANONICALIZE_COMPARISON s390_canonicalize_comparison
13482 #undef TARGET_HARD_REGNO_SCRATCH_OK
13483 #define TARGET_HARD_REGNO_SCRATCH_OK s390_hard_regno_scratch_ok
13485 #undef TARGET_ATTRIBUTE_TABLE
13486 #define TARGET_ATTRIBUTE_TABLE s390_attribute_table
13488 #undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
13489 #define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_const_tree_true
13491 #undef TARGET_SET_UP_BY_PROLOGUE
13492 #define TARGET_SET_UP_BY_PROLOGUE s300_set_up_by_prologue
13494 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
13495 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
13496 s390_use_by_pieces_infrastructure_p
13498 #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
13499 #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV s390_atomic_assign_expand_fenv
13501 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
13502 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN s390_invalid_arg_for_unprototyped_fn
13504 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
13505 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE s390_preferred_simd_mode
13507 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
13508 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT s390_support_vector_misalignment
13510 #undef TARGET_VECTOR_ALIGNMENT
13511 #define TARGET_VECTOR_ALIGNMENT s390_vector_alignment
13513 struct gcc_target targetm
= TARGET_INITIALIZER
;
13515 #include "gt-s390.h"