1 /* Subroutines used for code generation on IBM S/390 and zSeries
2 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
3 Free Software Foundation, Inc.
4 Contributed by Hartmut Penner (hpenner@de.ibm.com) and
5 Ulrich Weigand (uweigand@de.ibm.com).
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to the Free
21 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
26 #include "coretypes.h"
32 #include "hard-reg-set.h"
34 #include "insn-config.h"
35 #include "conditions.h"
37 #include "insn-attr.h"
45 #include "basic-block.h"
46 #include "integrate.h"
49 #include "target-def.h"
51 #include "langhooks.h"
53 #include "tree-gimple.h"
56 /* Define the specific costs for a given cpu. */
58 struct processor_costs
61 const int m
; /* cost of an M instruction. */
62 const int mghi
; /* cost of an MGHI instruction. */
63 const int mh
; /* cost of an MH instruction. */
64 const int mhi
; /* cost of an MHI instruction. */
65 const int ml
; /* cost of an ML instruction. */
66 const int mr
; /* cost of an MR instruction. */
67 const int ms
; /* cost of an MS instruction. */
68 const int msg
; /* cost of an MSG instruction. */
69 const int msgf
; /* cost of an MSGF instruction. */
70 const int msgfr
; /* cost of an MSGFR instruction. */
71 const int msgr
; /* cost of an MSGR instruction. */
72 const int msr
; /* cost of an MSR instruction. */
73 const int mult_df
; /* cost of multiplication in DFmode. */
75 const int sqdbr
; /* cost of square root in DFmode. */
76 const int sqebr
; /* cost of square root in SFmode. */
77 /* multiply and add */
78 const int madbr
; /* cost of multiply and add in DFmode. */
79 const int maebr
; /* cost of multiply and add in SFmode. */
92 const struct processor_costs
*s390_cost
;
95 struct processor_costs z900_cost
=
97 COSTS_N_INSNS (5), /* M */
98 COSTS_N_INSNS (10), /* MGHI */
99 COSTS_N_INSNS (5), /* MH */
100 COSTS_N_INSNS (4), /* MHI */
101 COSTS_N_INSNS (5), /* ML */
102 COSTS_N_INSNS (5), /* MR */
103 COSTS_N_INSNS (4), /* MS */
104 COSTS_N_INSNS (15), /* MSG */
105 COSTS_N_INSNS (7), /* MSGF */
106 COSTS_N_INSNS (7), /* MSGFR */
107 COSTS_N_INSNS (10), /* MSGR */
108 COSTS_N_INSNS (4), /* MSR */
109 COSTS_N_INSNS (7), /* multiplication in DFmode */
110 COSTS_N_INSNS (44), /* SQDBR */
111 COSTS_N_INSNS (35), /* SQEBR */
112 COSTS_N_INSNS (18), /* MADBR */
113 COSTS_N_INSNS (13), /* MAEBR */
114 COSTS_N_INSNS (30), /* DDBR */
115 COSTS_N_INSNS (30), /* DDR */
116 COSTS_N_INSNS (27), /* DEBR */
117 COSTS_N_INSNS (26), /* DER */
118 COSTS_N_INSNS (220), /* DLGR */
119 COSTS_N_INSNS (34), /* DLR */
120 COSTS_N_INSNS (34), /* DR */
121 COSTS_N_INSNS (32), /* DSGFR */
122 COSTS_N_INSNS (32), /* DSGR */
126 struct processor_costs z990_cost
=
128 COSTS_N_INSNS (4), /* M */
129 COSTS_N_INSNS (2), /* MGHI */
130 COSTS_N_INSNS (2), /* MH */
131 COSTS_N_INSNS (2), /* MHI */
132 COSTS_N_INSNS (4), /* ML */
133 COSTS_N_INSNS (4), /* MR */
134 COSTS_N_INSNS (5), /* MS */
135 COSTS_N_INSNS (6), /* MSG */
136 COSTS_N_INSNS (4), /* MSGF */
137 COSTS_N_INSNS (4), /* MSGFR */
138 COSTS_N_INSNS (4), /* MSGR */
139 COSTS_N_INSNS (4), /* MSR */
140 COSTS_N_INSNS (1), /* multiplication in DFmode */
141 COSTS_N_INSNS (66), /* SQDBR */
142 COSTS_N_INSNS (38), /* SQEBR */
143 COSTS_N_INSNS (1), /* MADBR */
144 COSTS_N_INSNS (1), /* MAEBR */
145 COSTS_N_INSNS (40), /* DDBR */
146 COSTS_N_INSNS (44), /* DDR */
147 COSTS_N_INSNS (26), /* DDBR */
148 COSTS_N_INSNS (28), /* DER */
149 COSTS_N_INSNS (176), /* DLGR */
150 COSTS_N_INSNS (31), /* DLR */
151 COSTS_N_INSNS (31), /* DR */
152 COSTS_N_INSNS (31), /* DSGFR */
153 COSTS_N_INSNS (31), /* DSGR */
157 struct processor_costs z9_109_cost
=
159 COSTS_N_INSNS (4), /* M */
160 COSTS_N_INSNS (2), /* MGHI */
161 COSTS_N_INSNS (2), /* MH */
162 COSTS_N_INSNS (2), /* MHI */
163 COSTS_N_INSNS (4), /* ML */
164 COSTS_N_INSNS (4), /* MR */
165 COSTS_N_INSNS (5), /* MS */
166 COSTS_N_INSNS (6), /* MSG */
167 COSTS_N_INSNS (4), /* MSGF */
168 COSTS_N_INSNS (4), /* MSGFR */
169 COSTS_N_INSNS (4), /* MSGR */
170 COSTS_N_INSNS (4), /* MSR */
171 COSTS_N_INSNS (1), /* multiplication in DFmode */
172 COSTS_N_INSNS (66), /* SQDBR */
173 COSTS_N_INSNS (38), /* SQEBR */
174 COSTS_N_INSNS (1), /* MADBR */
175 COSTS_N_INSNS (1), /* MAEBR */
176 COSTS_N_INSNS (40), /* DDBR */
177 COSTS_N_INSNS (37), /* DDR */
178 COSTS_N_INSNS (26), /* DDBR */
179 COSTS_N_INSNS (28), /* DER */
180 COSTS_N_INSNS (30), /* DLGR */
181 COSTS_N_INSNS (23), /* DLR */
182 COSTS_N_INSNS (23), /* DR */
183 COSTS_N_INSNS (24), /* DSGFR */
184 COSTS_N_INSNS (24), /* DSGR */
187 extern int reload_completed
;
189 /* Save information from a "cmpxx" operation until the branch or scc is
191 rtx s390_compare_op0
, s390_compare_op1
;
193 /* Save the result of a compare_and_swap until the branch or scc is
195 rtx s390_compare_emitted
= NULL_RTX
;
197 /* Structure used to hold the components of a S/390 memory
198 address. A legitimate address on S/390 is of the general
200 base + index + displacement
201 where any of the components is optional.
203 base and index are registers of the class ADDR_REGS,
204 displacement is an unsigned 12-bit immediate constant. */
215 /* Which cpu are we tuning for. */
216 enum processor_type s390_tune
= PROCESSOR_max
;
217 enum processor_flags s390_tune_flags
;
218 /* Which instruction set architecture to use. */
219 enum processor_type s390_arch
;
220 enum processor_flags s390_arch_flags
;
222 HOST_WIDE_INT s390_warn_framesize
= 0;
223 HOST_WIDE_INT s390_stack_size
= 0;
224 HOST_WIDE_INT s390_stack_guard
= 0;
226 /* The following structure is embedded in the machine
227 specific part of struct function. */
229 struct s390_frame_layout
GTY (())
231 /* Offset within stack frame. */
232 HOST_WIDE_INT gprs_offset
;
233 HOST_WIDE_INT f0_offset
;
234 HOST_WIDE_INT f4_offset
;
235 HOST_WIDE_INT f8_offset
;
236 HOST_WIDE_INT backchain_offset
;
238 /* Number of first and last gpr where slots in the register
239 save area are reserved for. */
240 int first_save_gpr_slot
;
241 int last_save_gpr_slot
;
243 /* Number of first and last gpr to be saved, restored. */
245 int first_restore_gpr
;
247 int last_restore_gpr
;
249 /* Bits standing for floating point registers. Set, if the
250 respective register has to be saved. Starting with reg 16 (f0)
251 at the rightmost bit.
252 Bit 15 - 8 7 6 5 4 3 2 1 0
253 fpr 15 - 8 7 5 3 1 6 4 2 0
254 reg 31 - 24 23 22 21 20 19 18 17 16 */
255 unsigned int fpr_bitmap
;
257 /* Number of floating point registers f8-f15 which must be saved. */
260 /* Set if return address needs to be saved.
261 This flag is set by s390_return_addr_rtx if it could not use
262 the initial value of r14 and therefore depends on r14 saved
264 bool save_return_addr_p
;
266 /* Size of stack frame. */
267 HOST_WIDE_INT frame_size
;
270 /* Define the structure for the machine field in struct function. */
272 struct machine_function
GTY(())
274 struct s390_frame_layout frame_layout
;
276 /* Literal pool base register. */
279 /* True if we may need to perform branch splitting. */
280 bool split_branches_pending_p
;
282 /* True during final stage of literal pool processing. */
283 bool decomposed_literal_pool_addresses_ok_p
;
285 /* Some local-dynamic TLS symbol name. */
286 const char *some_ld_name
;
288 bool has_landing_pad_p
;
291 /* Few accessor macros for struct cfun->machine->s390_frame_layout. */
293 #define cfun_frame_layout (cfun->machine->frame_layout)
294 #define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)
295 #define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr_slot - \
296 cfun_frame_layout.first_save_gpr_slot + 1) * UNITS_PER_WORD)
297 #define cfun_set_fpr_bit(BITNUM) (cfun->machine->frame_layout.fpr_bitmap |= \
299 #define cfun_fpr_bit_p(BITNUM) (!!(cfun->machine->frame_layout.fpr_bitmap & \
302 /* Number of GPRs and FPRs used for argument passing. */
303 #define GP_ARG_NUM_REG 5
304 #define FP_ARG_NUM_REG (TARGET_64BIT? 4 : 2)
306 /* A couple of shortcuts. */
307 #define CONST_OK_FOR_J(x) \
308 CONST_OK_FOR_CONSTRAINT_P((x), 'J', "J")
309 #define CONST_OK_FOR_K(x) \
310 CONST_OK_FOR_CONSTRAINT_P((x), 'K', "K")
311 #define CONST_OK_FOR_Os(x) \
312 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Os")
313 #define CONST_OK_FOR_Op(x) \
314 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Op")
315 #define CONST_OK_FOR_On(x) \
316 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "On")
318 /* Set the has_landing_pad_p flag in struct machine_function to VALUE. */
321 s390_set_has_landing_pad_p (bool value
)
323 cfun
->machine
->has_landing_pad_p
= value
;
326 /* If two condition code modes are compatible, return a condition code
327 mode which is compatible with both. Otherwise, return
330 static enum machine_mode
331 s390_cc_modes_compatible (enum machine_mode m1
, enum machine_mode m2
)
339 if (m2
== CCUmode
|| m2
== CCTmode
|| m2
== CCZ1mode
340 || m2
== CCSmode
|| m2
== CCSRmode
|| m2
== CCURmode
)
361 /* Return true if SET either doesn't set the CC register, or else
362 the source and destination have matching CC modes and that
363 CC mode is at least as constrained as REQ_MODE. */
366 s390_match_ccmode_set (rtx set
, enum machine_mode req_mode
)
368 enum machine_mode set_mode
;
370 gcc_assert (GET_CODE (set
) == SET
);
372 if (GET_CODE (SET_DEST (set
)) != REG
|| !CC_REGNO_P (REGNO (SET_DEST (set
))))
375 set_mode
= GET_MODE (SET_DEST (set
));
389 if (req_mode
!= set_mode
)
394 if (req_mode
!= CCSmode
&& req_mode
!= CCUmode
&& req_mode
!= CCTmode
395 && req_mode
!= CCSRmode
&& req_mode
!= CCURmode
)
401 if (req_mode
!= CCAmode
)
409 return (GET_MODE (SET_SRC (set
)) == set_mode
);
412 /* Return true if every SET in INSN that sets the CC register
413 has source and destination with matching CC modes and that
414 CC mode is at least as constrained as REQ_MODE.
415 If REQ_MODE is VOIDmode, always return false. */
418 s390_match_ccmode (rtx insn
, enum machine_mode req_mode
)
422 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
423 if (req_mode
== VOIDmode
)
426 if (GET_CODE (PATTERN (insn
)) == SET
)
427 return s390_match_ccmode_set (PATTERN (insn
), req_mode
);
429 if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
430 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
432 rtx set
= XVECEXP (PATTERN (insn
), 0, i
);
433 if (GET_CODE (set
) == SET
)
434 if (!s390_match_ccmode_set (set
, req_mode
))
441 /* If a test-under-mask instruction can be used to implement
442 (compare (and ... OP1) OP2), return the CC mode required
443 to do that. Otherwise, return VOIDmode.
444 MIXED is true if the instruction can distinguish between
445 CC1 and CC2 for mixed selected bits (TMxx), it is false
446 if the instruction cannot (TM). */
449 s390_tm_ccmode (rtx op1
, rtx op2
, bool mixed
)
453 /* ??? Fixme: should work on CONST_DOUBLE as well. */
454 if (GET_CODE (op1
) != CONST_INT
|| GET_CODE (op2
) != CONST_INT
)
457 /* Selected bits all zero: CC0.
458 e.g.: int a; if ((a & (16 + 128)) == 0) */
459 if (INTVAL (op2
) == 0)
462 /* Selected bits all one: CC3.
463 e.g.: int a; if ((a & (16 + 128)) == 16 + 128) */
464 if (INTVAL (op2
) == INTVAL (op1
))
467 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. e.g.:
469 if ((a & (16 + 128)) == 16) -> CCT1
470 if ((a & (16 + 128)) == 128) -> CCT2 */
473 bit1
= exact_log2 (INTVAL (op2
));
474 bit0
= exact_log2 (INTVAL (op1
) ^ INTVAL (op2
));
475 if (bit0
!= -1 && bit1
!= -1)
476 return bit0
> bit1
? CCT1mode
: CCT2mode
;
482 /* Given a comparison code OP (EQ, NE, etc.) and the operands
483 OP0 and OP1 of a COMPARE, return the mode to be used for the
487 s390_select_ccmode (enum rtx_code code
, rtx op0
, rtx op1
)
493 if ((GET_CODE (op0
) == NEG
|| GET_CODE (op0
) == ABS
)
494 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
496 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
497 && CONST_OK_FOR_K (INTVAL (XEXP (op0
, 1))))
499 if ((GET_CODE (op0
) == PLUS
|| GET_CODE (op0
) == MINUS
500 || GET_CODE (op1
) == NEG
)
501 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
504 if (GET_CODE (op0
) == AND
)
506 /* Check whether we can potentially do it via TM. */
507 enum machine_mode ccmode
;
508 ccmode
= s390_tm_ccmode (XEXP (op0
, 1), op1
, 1);
509 if (ccmode
!= VOIDmode
)
511 /* Relax CCTmode to CCZmode to allow fall-back to AND
512 if that turns out to be beneficial. */
513 return ccmode
== CCTmode
? CCZmode
: ccmode
;
517 if (register_operand (op0
, HImode
)
518 && GET_CODE (op1
) == CONST_INT
519 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 65535))
521 if (register_operand (op0
, QImode
)
522 && GET_CODE (op1
) == CONST_INT
523 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 255))
532 /* The only overflow condition of NEG and ABS happens when
533 -INT_MAX is used as parameter, which stays negative. So
534 we have an overflow from a positive value to a negative.
535 Using CCAP mode the resulting cc can be used for comparisons. */
536 if ((GET_CODE (op0
) == NEG
|| GET_CODE (op0
) == ABS
)
537 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
540 /* If constants are involved in an add instruction it is possible to use
541 the resulting cc for comparisons with zero. Knowing the sign of the
542 constant the overflow behavior gets predictable. e.g.:
543 int a, b; if ((b = a + c) > 0)
544 with c as a constant value: c < 0 -> CCAN and c >= 0 -> CCAP */
545 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
546 && CONST_OK_FOR_K (INTVAL (XEXP (op0
, 1))))
548 if (INTVAL (XEXP((op0
), 1)) < 0)
562 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
563 && GET_CODE (op1
) != CONST_INT
)
569 if (GET_CODE (op0
) == PLUS
570 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
573 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
574 && GET_CODE (op1
) != CONST_INT
)
580 if (GET_CODE (op0
) == MINUS
581 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
584 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
585 && GET_CODE (op1
) != CONST_INT
)
594 /* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
595 that we can implement more efficiently. */
598 s390_canonicalize_comparison (enum rtx_code
*code
, rtx
*op0
, rtx
*op1
)
600 /* Convert ZERO_EXTRACT back to AND to enable TM patterns. */
601 if ((*code
== EQ
|| *code
== NE
)
602 && *op1
== const0_rtx
603 && GET_CODE (*op0
) == ZERO_EXTRACT
604 && GET_CODE (XEXP (*op0
, 1)) == CONST_INT
605 && GET_CODE (XEXP (*op0
, 2)) == CONST_INT
606 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0
, 0))))
608 rtx inner
= XEXP (*op0
, 0);
609 HOST_WIDE_INT modesize
= GET_MODE_BITSIZE (GET_MODE (inner
));
610 HOST_WIDE_INT len
= INTVAL (XEXP (*op0
, 1));
611 HOST_WIDE_INT pos
= INTVAL (XEXP (*op0
, 2));
613 if (len
> 0 && len
< modesize
614 && pos
>= 0 && pos
+ len
<= modesize
615 && modesize
<= HOST_BITS_PER_WIDE_INT
)
617 unsigned HOST_WIDE_INT block
;
618 block
= ((unsigned HOST_WIDE_INT
) 1 << len
) - 1;
619 block
<<= modesize
- pos
- len
;
621 *op0
= gen_rtx_AND (GET_MODE (inner
), inner
,
622 gen_int_mode (block
, GET_MODE (inner
)));
626 /* Narrow AND of memory against immediate to enable TM. */
627 if ((*code
== EQ
|| *code
== NE
)
628 && *op1
== const0_rtx
629 && GET_CODE (*op0
) == AND
630 && GET_CODE (XEXP (*op0
, 1)) == CONST_INT
631 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0
, 0))))
633 rtx inner
= XEXP (*op0
, 0);
634 rtx mask
= XEXP (*op0
, 1);
636 /* Ignore paradoxical SUBREGs if all extra bits are masked out. */
637 if (GET_CODE (inner
) == SUBREG
638 && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (inner
)))
639 && (GET_MODE_SIZE (GET_MODE (inner
))
640 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner
))))
642 & GET_MODE_MASK (GET_MODE (inner
))
643 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (inner
))))
645 inner
= SUBREG_REG (inner
);
647 /* Do not change volatile MEMs. */
648 if (MEM_P (inner
) && !MEM_VOLATILE_P (inner
))
650 int part
= s390_single_part (XEXP (*op0
, 1),
651 GET_MODE (inner
), QImode
, 0);
654 mask
= gen_int_mode (s390_extract_part (mask
, QImode
, 0), QImode
);
655 inner
= adjust_address_nv (inner
, QImode
, part
);
656 *op0
= gen_rtx_AND (QImode
, inner
, mask
);
661 /* Narrow comparisons against 0xffff to HImode if possible. */
662 if ((*code
== EQ
|| *code
== NE
)
663 && GET_CODE (*op1
) == CONST_INT
664 && INTVAL (*op1
) == 0xffff
665 && SCALAR_INT_MODE_P (GET_MODE (*op0
))
666 && (nonzero_bits (*op0
, GET_MODE (*op0
))
667 & ~(unsigned HOST_WIDE_INT
) 0xffff) == 0)
669 *op0
= gen_lowpart (HImode
, *op0
);
674 /* Remove redundant UNSPEC_CMPINT conversions if possible. */
675 if (GET_CODE (*op0
) == UNSPEC
676 && XINT (*op0
, 1) == UNSPEC_CMPINT
677 && XVECLEN (*op0
, 0) == 1
678 && GET_MODE (XVECEXP (*op0
, 0, 0)) == CCUmode
679 && GET_CODE (XVECEXP (*op0
, 0, 0)) == REG
680 && REGNO (XVECEXP (*op0
, 0, 0)) == CC_REGNUM
681 && *op1
== const0_rtx
)
683 enum rtx_code new_code
= UNKNOWN
;
686 case EQ
: new_code
= EQ
; break;
687 case NE
: new_code
= NE
; break;
688 case LT
: new_code
= GTU
; break;
689 case GT
: new_code
= LTU
; break;
690 case LE
: new_code
= GEU
; break;
691 case GE
: new_code
= LEU
; break;
695 if (new_code
!= UNKNOWN
)
697 *op0
= XVECEXP (*op0
, 0, 0);
702 /* Simplify cascaded EQ, NE with const0_rtx. */
703 if ((*code
== NE
|| *code
== EQ
)
704 && (GET_CODE (*op0
) == EQ
|| GET_CODE (*op0
) == NE
)
705 && GET_MODE (*op0
) == SImode
706 && GET_MODE (XEXP (*op0
, 0)) == CCZ1mode
707 && REG_P (XEXP (*op0
, 0))
708 && XEXP (*op0
, 1) == const0_rtx
709 && *op1
== const0_rtx
)
711 if ((*code
== EQ
&& GET_CODE (*op0
) == NE
)
712 || (*code
== NE
&& GET_CODE (*op0
) == EQ
))
716 *op0
= XEXP (*op0
, 0);
719 /* Prefer register over memory as first operand. */
720 if (MEM_P (*op0
) && REG_P (*op1
))
722 rtx tem
= *op0
; *op0
= *op1
; *op1
= tem
;
723 *code
= swap_condition (*code
);
727 /* Emit a compare instruction suitable to implement the comparison
728 OP0 CODE OP1. Return the correct condition RTL to be placed in
729 the IF_THEN_ELSE of the conditional branch testing the result. */
732 s390_emit_compare (enum rtx_code code
, rtx op0
, rtx op1
)
734 enum machine_mode mode
= s390_select_ccmode (code
, op0
, op1
);
737 /* Do not output a redundant compare instruction if a compare_and_swap
738 pattern already computed the result and the machine modes are compatible. */
739 if (s390_compare_emitted
740 && (s390_cc_modes_compatible (GET_MODE (s390_compare_emitted
), mode
)
741 == GET_MODE (s390_compare_emitted
)))
742 ret
= gen_rtx_fmt_ee (code
, VOIDmode
, s390_compare_emitted
, const0_rtx
);
745 rtx cc
= gen_rtx_REG (mode
, CC_REGNUM
);
747 emit_insn (gen_rtx_SET (VOIDmode
, cc
, gen_rtx_COMPARE (mode
, op0
, op1
)));
748 ret
= gen_rtx_fmt_ee (code
, VOIDmode
, cc
, const0_rtx
);
750 s390_compare_emitted
= NULL_RTX
;
754 /* Emit a jump instruction to TARGET. If COND is NULL_RTX, emit an
755 unconditional jump, else a conditional jump under condition COND. */
758 s390_emit_jump (rtx target
, rtx cond
)
762 target
= gen_rtx_LABEL_REF (VOIDmode
, target
);
764 target
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, target
, pc_rtx
);
766 insn
= gen_rtx_SET (VOIDmode
, pc_rtx
, target
);
767 emit_jump_insn (insn
);
770 /* Return branch condition mask to implement a branch
771 specified by CODE. Return -1 for invalid comparisons. */
774 s390_branch_condition_mask (rtx code
)
776 const int CC0
= 1 << 3;
777 const int CC1
= 1 << 2;
778 const int CC2
= 1 << 1;
779 const int CC3
= 1 << 0;
781 gcc_assert (GET_CODE (XEXP (code
, 0)) == REG
);
782 gcc_assert (REGNO (XEXP (code
, 0)) == CC_REGNUM
);
783 gcc_assert (XEXP (code
, 1) == const0_rtx
);
785 switch (GET_MODE (XEXP (code
, 0)))
789 switch (GET_CODE (code
))
792 case NE
: return CC1
| CC2
| CC3
;
798 switch (GET_CODE (code
))
801 case NE
: return CC0
| CC2
| CC3
;
807 switch (GET_CODE (code
))
810 case NE
: return CC0
| CC1
| CC3
;
816 switch (GET_CODE (code
))
819 case NE
: return CC0
| CC1
| CC2
;
825 switch (GET_CODE (code
))
827 case EQ
: return CC0
| CC2
;
828 case NE
: return CC1
| CC3
;
834 switch (GET_CODE (code
))
836 case LTU
: return CC2
| CC3
; /* carry */
837 case GEU
: return CC0
| CC1
; /* no carry */
843 switch (GET_CODE (code
))
845 case GTU
: return CC0
| CC1
; /* borrow */
846 case LEU
: return CC2
| CC3
; /* no borrow */
852 switch (GET_CODE (code
))
854 case EQ
: return CC0
| CC2
;
855 case NE
: return CC1
| CC3
;
856 case LTU
: return CC1
;
857 case GTU
: return CC3
;
858 case LEU
: return CC1
| CC2
;
859 case GEU
: return CC2
| CC3
;
864 switch (GET_CODE (code
))
867 case NE
: return CC1
| CC2
| CC3
;
868 case LTU
: return CC1
;
869 case GTU
: return CC2
;
870 case LEU
: return CC0
| CC1
;
871 case GEU
: return CC0
| CC2
;
877 switch (GET_CODE (code
))
880 case NE
: return CC2
| CC1
| CC3
;
881 case LTU
: return CC2
;
882 case GTU
: return CC1
;
883 case LEU
: return CC0
| CC2
;
884 case GEU
: return CC0
| CC1
;
890 switch (GET_CODE (code
))
893 case NE
: return CC1
| CC2
| CC3
;
894 case LT
: return CC1
| CC3
;
896 case LE
: return CC0
| CC1
| CC3
;
897 case GE
: return CC0
| CC2
;
903 switch (GET_CODE (code
))
906 case NE
: return CC1
| CC2
| CC3
;
908 case GT
: return CC2
| CC3
;
909 case LE
: return CC0
| CC1
;
910 case GE
: return CC0
| CC2
| CC3
;
916 switch (GET_CODE (code
))
919 case NE
: return CC1
| CC2
| CC3
;
922 case LE
: return CC0
| CC1
;
923 case GE
: return CC0
| CC2
;
924 case UNORDERED
: return CC3
;
925 case ORDERED
: return CC0
| CC1
| CC2
;
926 case UNEQ
: return CC0
| CC3
;
927 case UNLT
: return CC1
| CC3
;
928 case UNGT
: return CC2
| CC3
;
929 case UNLE
: return CC0
| CC1
| CC3
;
930 case UNGE
: return CC0
| CC2
| CC3
;
931 case LTGT
: return CC1
| CC2
;
937 switch (GET_CODE (code
))
940 case NE
: return CC2
| CC1
| CC3
;
943 case LE
: return CC0
| CC2
;
944 case GE
: return CC0
| CC1
;
945 case UNORDERED
: return CC3
;
946 case ORDERED
: return CC0
| CC2
| CC1
;
947 case UNEQ
: return CC0
| CC3
;
948 case UNLT
: return CC2
| CC3
;
949 case UNGT
: return CC1
| CC3
;
950 case UNLE
: return CC0
| CC2
| CC3
;
951 case UNGE
: return CC0
| CC1
| CC3
;
952 case LTGT
: return CC2
| CC1
;
962 /* If INV is false, return assembler mnemonic string to implement
963 a branch specified by CODE. If INV is true, return mnemonic
964 for the corresponding inverted branch. */
967 s390_branch_condition_mnemonic (rtx code
, int inv
)
969 static const char *const mnemonic
[16] =
971 NULL
, "o", "h", "nle",
972 "l", "nhe", "lh", "ne",
973 "e", "nlh", "he", "nl",
974 "le", "nh", "no", NULL
977 int mask
= s390_branch_condition_mask (code
);
978 gcc_assert (mask
>= 0);
983 gcc_assert (mask
>= 1 && mask
<= 14);
985 return mnemonic
[mask
];
988 /* Return the part of op which has a value different from def.
989 The size of the part is determined by mode.
990 Use this function only if you already know that op really
991 contains such a part. */
993 unsigned HOST_WIDE_INT
994 s390_extract_part (rtx op
, enum machine_mode mode
, int def
)
996 unsigned HOST_WIDE_INT value
= 0;
997 int max_parts
= HOST_BITS_PER_WIDE_INT
/ GET_MODE_BITSIZE (mode
);
998 int part_bits
= GET_MODE_BITSIZE (mode
);
999 unsigned HOST_WIDE_INT part_mask
1000 = ((unsigned HOST_WIDE_INT
)1 << part_bits
) - 1;
1003 for (i
= 0; i
< max_parts
; i
++)
1006 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
1008 value
>>= part_bits
;
1010 if ((value
& part_mask
) != (def
& part_mask
))
1011 return value
& part_mask
;
1017 /* If OP is an integer constant of mode MODE with exactly one
1018 part of mode PART_MODE unequal to DEF, return the number of that
1019 part. Otherwise, return -1. */
1022 s390_single_part (rtx op
,
1023 enum machine_mode mode
,
1024 enum machine_mode part_mode
,
1027 unsigned HOST_WIDE_INT value
= 0;
1028 int n_parts
= GET_MODE_SIZE (mode
) / GET_MODE_SIZE (part_mode
);
1029 unsigned HOST_WIDE_INT part_mask
1030 = ((unsigned HOST_WIDE_INT
)1 << GET_MODE_BITSIZE (part_mode
)) - 1;
1033 if (GET_CODE (op
) != CONST_INT
)
1036 for (i
= 0; i
< n_parts
; i
++)
1039 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
1041 value
>>= GET_MODE_BITSIZE (part_mode
);
1043 if ((value
& part_mask
) != (def
& part_mask
))
1051 return part
== -1 ? -1 : n_parts
- 1 - part
;
1054 /* Check whether we can (and want to) split a double-word
1055 move in mode MODE from SRC to DST into two single-word
1056 moves, moving the subword FIRST_SUBWORD first. */
1059 s390_split_ok_p (rtx dst
, rtx src
, enum machine_mode mode
, int first_subword
)
1061 /* Floating point registers cannot be split. */
1062 if (FP_REG_P (src
) || FP_REG_P (dst
))
1065 /* We don't need to split if operands are directly accessible. */
1066 if (s_operand (src
, mode
) || s_operand (dst
, mode
))
1069 /* Non-offsettable memory references cannot be split. */
1070 if ((GET_CODE (src
) == MEM
&& !offsettable_memref_p (src
))
1071 || (GET_CODE (dst
) == MEM
&& !offsettable_memref_p (dst
)))
1074 /* Moving the first subword must not clobber a register
1075 needed to move the second subword. */
1076 if (register_operand (dst
, mode
))
1078 rtx subreg
= operand_subword (dst
, first_subword
, 0, mode
);
1079 if (reg_overlap_mentioned_p (subreg
, src
))
1086 /* Return true if it can be proven that [MEM1, MEM1 + SIZE]
1087 and [MEM2, MEM2 + SIZE] do overlap and false
1091 s390_overlap_p (rtx mem1
, rtx mem2
, HOST_WIDE_INT size
)
1093 rtx addr1
, addr2
, addr_delta
;
1094 HOST_WIDE_INT delta
;
1096 if (GET_CODE (mem1
) != MEM
|| GET_CODE (mem2
) != MEM
)
1102 addr1
= XEXP (mem1
, 0);
1103 addr2
= XEXP (mem2
, 0);
1105 addr_delta
= simplify_binary_operation (MINUS
, Pmode
, addr2
, addr1
);
1107 /* This overlapping check is used by peepholes merging memory block operations.
1108 Overlapping operations would otherwise be recognized by the S/390 hardware
1109 and would fall back to a slower implementation. Allowing overlapping
1110 operations would lead to slow code but not to wrong code. Therefore we are
1111 somewhat optimistic if we cannot prove that the memory blocks are
1113 That's why we return false here although this may accept operations on
1114 overlapping memory areas. */
1115 if (!addr_delta
|| GET_CODE (addr_delta
) != CONST_INT
)
1118 delta
= INTVAL (addr_delta
);
1121 || (delta
> 0 && delta
< size
)
1122 || (delta
< 0 && -delta
< size
))
1128 /* Check whether the address of memory reference MEM2 equals exactly
1129 the address of memory reference MEM1 plus DELTA. Return true if
1130 we can prove this to be the case, false otherwise. */
1133 s390_offset_p (rtx mem1
, rtx mem2
, rtx delta
)
1135 rtx addr1
, addr2
, addr_delta
;
1137 if (GET_CODE (mem1
) != MEM
|| GET_CODE (mem2
) != MEM
)
1140 addr1
= XEXP (mem1
, 0);
1141 addr2
= XEXP (mem2
, 0);
1143 addr_delta
= simplify_binary_operation (MINUS
, Pmode
, addr2
, addr1
);
1144 if (!addr_delta
|| !rtx_equal_p (addr_delta
, delta
))
1150 /* Expand logical operator CODE in mode MODE with operands OPERANDS. */
1153 s390_expand_logical_operator (enum rtx_code code
, enum machine_mode mode
,
1156 enum machine_mode wmode
= mode
;
1157 rtx dst
= operands
[0];
1158 rtx src1
= operands
[1];
1159 rtx src2
= operands
[2];
1162 /* If we cannot handle the operation directly, use a temp register. */
1163 if (!s390_logical_operator_ok_p (operands
))
1164 dst
= gen_reg_rtx (mode
);
1166 /* QImode and HImode patterns make sense only if we have a destination
1167 in memory. Otherwise perform the operation in SImode. */
1168 if ((mode
== QImode
|| mode
== HImode
) && GET_CODE (dst
) != MEM
)
1171 /* Widen operands if required. */
1174 if (GET_CODE (dst
) == SUBREG
1175 && (tem
= simplify_subreg (wmode
, dst
, mode
, 0)) != 0)
1177 else if (REG_P (dst
))
1178 dst
= gen_rtx_SUBREG (wmode
, dst
, 0);
1180 dst
= gen_reg_rtx (wmode
);
1182 if (GET_CODE (src1
) == SUBREG
1183 && (tem
= simplify_subreg (wmode
, src1
, mode
, 0)) != 0)
1185 else if (GET_MODE (src1
) != VOIDmode
)
1186 src1
= gen_rtx_SUBREG (wmode
, force_reg (mode
, src1
), 0);
1188 if (GET_CODE (src2
) == SUBREG
1189 && (tem
= simplify_subreg (wmode
, src2
, mode
, 0)) != 0)
1191 else if (GET_MODE (src2
) != VOIDmode
)
1192 src2
= gen_rtx_SUBREG (wmode
, force_reg (mode
, src2
), 0);
1195 /* Emit the instruction. */
1196 op
= gen_rtx_SET (VOIDmode
, dst
, gen_rtx_fmt_ee (code
, wmode
, src1
, src2
));
1197 clob
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
1198 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, op
, clob
)));
1200 /* Fix up the destination if needed. */
1201 if (dst
!= operands
[0])
1202 emit_move_insn (operands
[0], gen_lowpart (mode
, dst
));
1205 /* Check whether OPERANDS are OK for a logical operation (AND, IOR, XOR). */
1208 s390_logical_operator_ok_p (rtx
*operands
)
1210 /* If the destination operand is in memory, it needs to coincide
1211 with one of the source operands. After reload, it has to be
1212 the first source operand. */
1213 if (GET_CODE (operands
[0]) == MEM
)
1214 return rtx_equal_p (operands
[0], operands
[1])
1215 || (!reload_completed
&& rtx_equal_p (operands
[0], operands
[2]));
1220 /* Narrow logical operation CODE of memory operand MEMOP with immediate
1221 operand IMMOP to switch from SS to SI type instructions. */
1224 s390_narrow_logical_operator (enum rtx_code code
, rtx
*memop
, rtx
*immop
)
1226 int def
= code
== AND
? -1 : 0;
1230 gcc_assert (GET_CODE (*memop
) == MEM
);
1231 gcc_assert (!MEM_VOLATILE_P (*memop
));
1233 mask
= s390_extract_part (*immop
, QImode
, def
);
1234 part
= s390_single_part (*immop
, GET_MODE (*memop
), QImode
, def
);
1235 gcc_assert (part
>= 0);
1237 *memop
= adjust_address (*memop
, QImode
, part
);
1238 *immop
= gen_int_mode (mask
, QImode
);
1242 /* How to allocate a 'struct machine_function'. */
1244 static struct machine_function
*
1245 s390_init_machine_status (void)
1247 return ggc_alloc_cleared (sizeof (struct machine_function
));
1250 /* Change optimizations to be performed, depending on the
1253 LEVEL is the optimization level specified; 2 if `-O2' is
1254 specified, 1 if `-O' is specified, and 0 if neither is specified.
1256 SIZE is nonzero if `-Os' is specified and zero otherwise. */
1259 optimization_options (int level ATTRIBUTE_UNUSED
, int size ATTRIBUTE_UNUSED
)
1261 /* ??? There are apparently still problems with -fcaller-saves. */
1262 flag_caller_saves
= 0;
1264 /* By default, always emit DWARF-2 unwind info. This allows debugging
1265 without maintaining a stack frame back-chain. */
1266 flag_asynchronous_unwind_tables
= 1;
1268 /* Use MVCLE instructions to decrease code size if requested. */
1270 target_flags
|= MASK_MVCLE
;
1273 /* Return true if ARG is the name of a processor. Set *TYPE and *FLAGS
1274 to the associated processor_type and processor_flags if so. */
1277 s390_handle_arch_option (const char *arg
,
1278 enum processor_type
*type
,
1279 enum processor_flags
*flags
)
1283 const char *const name
; /* processor name or nickname. */
1284 const enum processor_type processor
;
1285 const enum processor_flags flags
;
1287 const processor_alias_table
[] =
1289 {"g5", PROCESSOR_9672_G5
, PF_IEEE_FLOAT
},
1290 {"g6", PROCESSOR_9672_G6
, PF_IEEE_FLOAT
},
1291 {"z900", PROCESSOR_2064_Z900
, PF_IEEE_FLOAT
| PF_ZARCH
},
1292 {"z990", PROCESSOR_2084_Z990
, PF_IEEE_FLOAT
| PF_ZARCH
1293 | PF_LONG_DISPLACEMENT
},
1294 {"z9-109", PROCESSOR_2094_Z9_109
, PF_IEEE_FLOAT
| PF_ZARCH
1295 | PF_LONG_DISPLACEMENT
| PF_EXTIMM
},
1299 for (i
= 0; i
< ARRAY_SIZE (processor_alias_table
); i
++)
1300 if (strcmp (arg
, processor_alias_table
[i
].name
) == 0)
1302 *type
= processor_alias_table
[i
].processor
;
1303 *flags
= processor_alias_table
[i
].flags
;
1309 /* Implement TARGET_HANDLE_OPTION. */
1312 s390_handle_option (size_t code
, const char *arg
, int value ATTRIBUTE_UNUSED
)
1317 return s390_handle_arch_option (arg
, &s390_arch
, &s390_arch_flags
);
1319 case OPT_mstack_guard_
:
1320 if (sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_stack_guard
) != 1)
1322 if (exact_log2 (s390_stack_guard
) == -1)
1323 error ("stack guard value must be an exact power of 2");
1326 case OPT_mstack_size_
:
1327 if (sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_stack_size
) != 1)
1329 if (exact_log2 (s390_stack_size
) == -1)
1330 error ("stack size must be an exact power of 2");
1334 return s390_handle_arch_option (arg
, &s390_tune
, &s390_tune_flags
);
1336 case OPT_mwarn_framesize_
:
1337 return sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_warn_framesize
) == 1;
1345 override_options (void)
1347 /* Set up function hooks. */
1348 init_machine_status
= s390_init_machine_status
;
1350 /* Architecture mode defaults according to ABI. */
1351 if (!(target_flags_explicit
& MASK_ZARCH
))
1354 target_flags
|= MASK_ZARCH
;
1356 target_flags
&= ~MASK_ZARCH
;
1359 /* Determine processor architectural level. */
1360 if (!s390_arch_string
)
1362 s390_arch_string
= TARGET_ZARCH
? "z900" : "g5";
1363 s390_handle_arch_option (s390_arch_string
, &s390_arch
, &s390_arch_flags
);
1366 /* Determine processor to tune for. */
1367 if (s390_tune
== PROCESSOR_max
)
1369 s390_tune
= s390_arch
;
1370 s390_tune_flags
= s390_arch_flags
;
1373 /* Sanity checks. */
1374 if (TARGET_ZARCH
&& !(s390_arch_flags
& PF_ZARCH
))
1375 error ("z/Architecture mode not supported on %s", s390_arch_string
);
1376 if (TARGET_64BIT
&& !TARGET_ZARCH
)
1377 error ("64-bit ABI not supported in ESA/390 mode");
1379 /* Set processor cost function. */
1380 if (s390_tune
== PROCESSOR_2094_Z9_109
)
1381 s390_cost
= &z9_109_cost
;
1382 else if (s390_tune
== PROCESSOR_2084_Z990
)
1383 s390_cost
= &z990_cost
;
1385 s390_cost
= &z900_cost
;
1387 if (TARGET_BACKCHAIN
&& TARGET_PACKED_STACK
&& TARGET_HARD_FLOAT
)
1388 error ("-mbackchain -mpacked-stack -mhard-float are not supported "
1391 if (s390_stack_size
)
1393 if (!s390_stack_guard
)
1394 error ("-mstack-size implies use of -mstack-guard");
1395 else if (s390_stack_guard
>= s390_stack_size
)
1396 error ("stack size must be greater than the stack guard value");
1397 else if (s390_stack_size
> 1 << 16)
1398 error ("stack size must not be greater than 64k");
1400 else if (s390_stack_guard
)
1401 error ("-mstack-guard implies use of -mstack-size");
1404 /* Map for smallest class containing reg regno. */
1406 const enum reg_class regclass_map
[FIRST_PSEUDO_REGISTER
] =
1407 { GENERAL_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1408 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1409 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1410 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1411 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1412 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1413 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1414 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1415 ADDR_REGS
, CC_REGS
, ADDR_REGS
, ADDR_REGS
,
1416 ACCESS_REGS
, ACCESS_REGS
1419 /* Return attribute type of insn. */
1421 static enum attr_type
1422 s390_safe_attr_type (rtx insn
)
1424 if (recog_memoized (insn
) >= 0)
1425 return get_attr_type (insn
);
1430 /* Return true if DISP is a valid short displacement. */
1433 s390_short_displacement (rtx disp
)
1435 /* No displacement is OK. */
1439 /* Integer displacement in range. */
1440 if (GET_CODE (disp
) == CONST_INT
)
1441 return INTVAL (disp
) >= 0 && INTVAL (disp
) < 4096;
1443 /* GOT offset is not OK, the GOT can be large. */
1444 if (GET_CODE (disp
) == CONST
1445 && GET_CODE (XEXP (disp
, 0)) == UNSPEC
1446 && (XINT (XEXP (disp
, 0), 1) == UNSPEC_GOT
1447 || XINT (XEXP (disp
, 0), 1) == UNSPEC_GOTNTPOFF
))
1450 /* All other symbolic constants are literal pool references,
1451 which are OK as the literal pool must be small. */
1452 if (GET_CODE (disp
) == CONST
)
1458 /* Decompose a RTL expression ADDR for a memory address into
1459 its components, returned in OUT.
1461 Returns false if ADDR is not a valid memory address, true
1462 otherwise. If OUT is NULL, don't return the components,
1463 but check for validity only.
1465 Note: Only addresses in canonical form are recognized.
1466 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
1467 canonical form so that they will be recognized. */
1470 s390_decompose_address (rtx addr
, struct s390_address
*out
)
1472 HOST_WIDE_INT offset
= 0;
1473 rtx base
= NULL_RTX
;
1474 rtx indx
= NULL_RTX
;
1475 rtx disp
= NULL_RTX
;
1477 bool pointer
= false;
1478 bool base_ptr
= false;
1479 bool indx_ptr
= false;
1480 bool literal_pool
= false;
1482 /* We may need to substitute the literal pool base register into the address
1483 below. However, at this point we do not know which register is going to
1484 be used as base, so we substitute the arg pointer register. This is going
1485 to be treated as holding a pointer below -- it shouldn't be used for any
1487 rtx fake_pool_base
= gen_rtx_REG (Pmode
, ARG_POINTER_REGNUM
);
1489 /* Decompose address into base + index + displacement. */
1491 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == UNSPEC
)
1494 else if (GET_CODE (addr
) == PLUS
)
1496 rtx op0
= XEXP (addr
, 0);
1497 rtx op1
= XEXP (addr
, 1);
1498 enum rtx_code code0
= GET_CODE (op0
);
1499 enum rtx_code code1
= GET_CODE (op1
);
1501 if (code0
== REG
|| code0
== UNSPEC
)
1503 if (code1
== REG
|| code1
== UNSPEC
)
1505 indx
= op0
; /* index + base */
1511 base
= op0
; /* base + displacement */
1516 else if (code0
== PLUS
)
1518 indx
= XEXP (op0
, 0); /* index + base + disp */
1519 base
= XEXP (op0
, 1);
1530 disp
= addr
; /* displacement */
1532 /* Extract integer part of displacement. */
1536 if (GET_CODE (disp
) == CONST_INT
)
1538 offset
= INTVAL (disp
);
1541 else if (GET_CODE (disp
) == CONST
1542 && GET_CODE (XEXP (disp
, 0)) == PLUS
1543 && GET_CODE (XEXP (XEXP (disp
, 0), 1)) == CONST_INT
)
1545 offset
= INTVAL (XEXP (XEXP (disp
, 0), 1));
1546 disp
= XEXP (XEXP (disp
, 0), 0);
1550 /* Strip off CONST here to avoid special case tests later. */
1551 if (disp
&& GET_CODE (disp
) == CONST
)
1552 disp
= XEXP (disp
, 0);
1554 /* We can convert literal pool addresses to
1555 displacements by basing them off the base register. */
1556 if (disp
&& GET_CODE (disp
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (disp
))
1558 /* Either base or index must be free to hold the base register. */
1560 base
= fake_pool_base
, literal_pool
= true;
1562 indx
= fake_pool_base
, literal_pool
= true;
1566 /* Mark up the displacement. */
1567 disp
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, disp
),
1568 UNSPEC_LTREL_OFFSET
);
1571 /* Validate base register. */
1574 if (GET_CODE (base
) == UNSPEC
)
1575 switch (XINT (base
, 1))
1579 disp
= gen_rtx_UNSPEC (Pmode
,
1580 gen_rtvec (1, XVECEXP (base
, 0, 0)),
1581 UNSPEC_LTREL_OFFSET
);
1585 base
= XVECEXP (base
, 0, 1);
1588 case UNSPEC_LTREL_BASE
:
1589 if (XVECLEN (base
, 0) == 1)
1590 base
= fake_pool_base
, literal_pool
= true;
1592 base
= XVECEXP (base
, 0, 1);
1599 if (GET_CODE (base
) != REG
|| GET_MODE (base
) != Pmode
)
1602 if (REGNO (base
) == STACK_POINTER_REGNUM
1603 || REGNO (base
) == FRAME_POINTER_REGNUM
1604 || ((reload_completed
|| reload_in_progress
)
1605 && frame_pointer_needed
1606 && REGNO (base
) == HARD_FRAME_POINTER_REGNUM
)
1607 || REGNO (base
) == ARG_POINTER_REGNUM
1609 && REGNO (base
) == PIC_OFFSET_TABLE_REGNUM
))
1610 pointer
= base_ptr
= true;
1612 if ((reload_completed
|| reload_in_progress
)
1613 && base
== cfun
->machine
->base_reg
)
1614 pointer
= base_ptr
= literal_pool
= true;
1617 /* Validate index register. */
1620 if (GET_CODE (indx
) == UNSPEC
)
1621 switch (XINT (indx
, 1))
1625 disp
= gen_rtx_UNSPEC (Pmode
,
1626 gen_rtvec (1, XVECEXP (indx
, 0, 0)),
1627 UNSPEC_LTREL_OFFSET
);
1631 indx
= XVECEXP (indx
, 0, 1);
1634 case UNSPEC_LTREL_BASE
:
1635 if (XVECLEN (indx
, 0) == 1)
1636 indx
= fake_pool_base
, literal_pool
= true;
1638 indx
= XVECEXP (indx
, 0, 1);
1645 if (GET_CODE (indx
) != REG
|| GET_MODE (indx
) != Pmode
)
1648 if (REGNO (indx
) == STACK_POINTER_REGNUM
1649 || REGNO (indx
) == FRAME_POINTER_REGNUM
1650 || ((reload_completed
|| reload_in_progress
)
1651 && frame_pointer_needed
1652 && REGNO (indx
) == HARD_FRAME_POINTER_REGNUM
)
1653 || REGNO (indx
) == ARG_POINTER_REGNUM
1655 && REGNO (indx
) == PIC_OFFSET_TABLE_REGNUM
))
1656 pointer
= indx_ptr
= true;
1658 if ((reload_completed
|| reload_in_progress
)
1659 && indx
== cfun
->machine
->base_reg
)
1660 pointer
= indx_ptr
= literal_pool
= true;
1663 /* Prefer to use pointer as base, not index. */
1664 if (base
&& indx
&& !base_ptr
1665 && (indx_ptr
|| (!REG_POINTER (base
) && REG_POINTER (indx
))))
1672 /* Validate displacement. */
1675 /* If virtual registers are involved, the displacement will change later
1676 anyway as the virtual registers get eliminated. This could make a
1677 valid displacement invalid, but it is more likely to make an invalid
1678 displacement valid, because we sometimes access the register save area
1679 via negative offsets to one of those registers.
1680 Thus we don't check the displacement for validity here. If after
1681 elimination the displacement turns out to be invalid after all,
1682 this is fixed up by reload in any case. */
1683 if (base
!= arg_pointer_rtx
1684 && indx
!= arg_pointer_rtx
1685 && base
!= return_address_pointer_rtx
1686 && indx
!= return_address_pointer_rtx
1687 && base
!= frame_pointer_rtx
1688 && indx
!= frame_pointer_rtx
1689 && base
!= virtual_stack_vars_rtx
1690 && indx
!= virtual_stack_vars_rtx
)
1691 if (!DISP_IN_RANGE (offset
))
1696 /* All the special cases are pointers. */
1699 /* In the small-PIC case, the linker converts @GOT
1700 and @GOTNTPOFF offsets to possible displacements. */
1701 if (GET_CODE (disp
) == UNSPEC
1702 && (XINT (disp
, 1) == UNSPEC_GOT
1703 || XINT (disp
, 1) == UNSPEC_GOTNTPOFF
)
1710 /* Accept chunkified literal pool symbol references. */
1711 else if (cfun
&& cfun
->machine
1712 && cfun
->machine
->decomposed_literal_pool_addresses_ok_p
1713 && GET_CODE (disp
) == MINUS
1714 && GET_CODE (XEXP (disp
, 0)) == LABEL_REF
1715 && GET_CODE (XEXP (disp
, 1)) == LABEL_REF
)
1720 /* Accept literal pool references. */
1721 else if (GET_CODE (disp
) == UNSPEC
1722 && XINT (disp
, 1) == UNSPEC_LTREL_OFFSET
)
1724 orig_disp
= gen_rtx_CONST (Pmode
, disp
);
1727 /* If we have an offset, make sure it does not
1728 exceed the size of the constant pool entry. */
1729 rtx sym
= XVECEXP (disp
, 0, 0);
1730 if (offset
>= GET_MODE_SIZE (get_pool_mode (sym
)))
1733 orig_disp
= plus_constant (orig_disp
, offset
);
1748 out
->disp
= orig_disp
;
1749 out
->pointer
= pointer
;
1750 out
->literal_pool
= literal_pool
;
1756 /* Decompose a RTL expression OP for a shift count into its components,
1757 and return the base register in BASE and the offset in OFFSET.
1759 Return true if OP is a valid shift count, false if not. */
1762 s390_decompose_shift_count (rtx op
, rtx
*base
, HOST_WIDE_INT
*offset
)
1764 HOST_WIDE_INT off
= 0;
1766 /* We can have an integer constant, an address register,
1767 or a sum of the two. */
1768 if (GET_CODE (op
) == CONST_INT
)
1773 if (op
&& GET_CODE (op
) == PLUS
&& GET_CODE (XEXP (op
, 1)) == CONST_INT
)
1775 off
= INTVAL (XEXP (op
, 1));
1778 while (op
&& GET_CODE (op
) == SUBREG
)
1779 op
= SUBREG_REG (op
);
1781 if (op
&& GET_CODE (op
) != REG
)
1793 /* Return true if CODE is a valid address without index. */
1796 s390_legitimate_address_without_index_p (rtx op
)
1798 struct s390_address addr
;
1800 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1808 /* Return 1 if OP is a valid operand for a C constraint, 0 else. */
1811 s390_extra_constraint_str (rtx op
, int c
, const char * str
)
1813 struct s390_address addr
;
1815 gcc_assert (c
== str
[0]);
1817 /* Check for offsettable variants of memory constraints. */
1820 /* Only accept non-volatile MEMs. */
1821 if (!MEM_P (op
) || MEM_VOLATILE_P (op
))
1824 if ((reload_completed
|| reload_in_progress
)
1825 ? !offsettable_memref_p (op
)
1826 : !offsettable_nonstrict_memref_p (op
))
1832 /* Check for non-literal-pool variants of memory constraints. */
1835 if (GET_CODE (op
) != MEM
)
1837 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1839 if (addr
.literal_pool
)
1848 if (GET_CODE (op
) != MEM
)
1850 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1855 if (TARGET_LONG_DISPLACEMENT
)
1857 if (!s390_short_displacement (addr
.disp
))
1863 if (GET_CODE (op
) != MEM
)
1866 if (TARGET_LONG_DISPLACEMENT
)
1868 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1870 if (!s390_short_displacement (addr
.disp
))
1876 if (!TARGET_LONG_DISPLACEMENT
)
1878 if (GET_CODE (op
) != MEM
)
1880 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1884 if (s390_short_displacement (addr
.disp
))
1889 if (!TARGET_LONG_DISPLACEMENT
)
1891 if (GET_CODE (op
) != MEM
)
1893 /* Any invalid address here will be fixed up by reload,
1894 so accept it for the most generic constraint. */
1895 if (s390_decompose_address (XEXP (op
, 0), &addr
)
1896 && s390_short_displacement (addr
.disp
))
1901 if (TARGET_LONG_DISPLACEMENT
)
1903 if (!s390_decompose_address (op
, &addr
))
1905 if (!s390_short_displacement (addr
.disp
))
1911 if (!TARGET_LONG_DISPLACEMENT
)
1913 /* Any invalid address here will be fixed up by reload,
1914 so accept it for the most generic constraint. */
1915 if (s390_decompose_address (op
, &addr
)
1916 && s390_short_displacement (addr
.disp
))
1921 /* Simply check for the basic form of a shift count. Reload will
1922 take care of making sure we have a proper base register. */
1923 if (!s390_decompose_shift_count (op
, NULL
, NULL
))
1934 /* Return true if VALUE matches the constraint STR. */
1937 s390_const_double_ok_for_constraint_p (rtx value
,
1941 gcc_assert (c
== str
[0]);
1946 /* The floating point zero constant. */
1947 return (GET_MODE_CLASS (GET_MODE (value
)) == MODE_FLOAT
1948 && value
== CONST0_RTX (GET_MODE (value
)));
1955 /* Return true if VALUE matches the constraint STR. */
1958 s390_const_ok_for_constraint_p (HOST_WIDE_INT value
,
1962 enum machine_mode mode
, part_mode
;
1964 int part
, part_goal
;
1966 gcc_assert (c
== str
[0]);
1971 return (unsigned int)value
< 256;
1974 return (unsigned int)value
< 4096;
1977 return value
>= -32768 && value
< 32768;
1980 return (TARGET_LONG_DISPLACEMENT
?
1981 (value
>= -524288 && value
<= 524287)
1982 : (value
>= 0 && value
<= 4095));
1984 return value
== 2147483647;
1990 part_goal
= str
[1] - '0';
1994 case 'Q': part_mode
= QImode
; break;
1995 case 'H': part_mode
= HImode
; break;
1996 case 'S': part_mode
= SImode
; break;
2002 case 'H': mode
= HImode
; break;
2003 case 'S': mode
= SImode
; break;
2004 case 'D': mode
= DImode
; break;
2010 case '0': def
= 0; break;
2011 case 'F': def
= -1; break;
2015 if (GET_MODE_SIZE (mode
) <= GET_MODE_SIZE (part_mode
))
2018 part
= s390_single_part (GEN_INT (value
), mode
, part_mode
, def
);
2021 if (part_goal
!= -1 && part_goal
!= part
)
2033 return trunc_int_for_mode (value
, SImode
) == value
;
2037 || s390_single_part (GEN_INT (value
), DImode
, SImode
, 0) == 1;
2041 || s390_single_part (GEN_INT (value
), DImode
, SImode
, -1) == 1;
2049 return legitimate_reload_constant_p (GEN_INT (value
));
2058 /* Compute a (partial) cost for rtx X. Return true if the complete
2059 cost has been computed, and false if subexpressions should be
2060 scanned. In either case, *TOTAL contains the cost result.
2061 CODE contains GET_CODE (x), OUTER_CODE contains the code
2062 of the superexpression of x. */
2065 s390_rtx_costs (rtx x
, int code
, int outer_code
, int *total
)
2088 *total
= COSTS_N_INSNS (1);
2093 /* Check for multiply and add. */
2094 if ((GET_MODE (x
) == DFmode
|| GET_MODE (x
) == SFmode
)
2095 && GET_CODE (XEXP (x
, 0)) == MULT
2096 && TARGET_HARD_FLOAT
&& TARGET_IEEE_FLOAT
&& TARGET_FUSED_MADD
)
2098 /* This is the multiply and add case. */
2099 if (GET_MODE (x
) == DFmode
)
2100 *total
= s390_cost
->madbr
;
2102 *total
= s390_cost
->maebr
;
2103 *total
+= rtx_cost (XEXP (XEXP (x
, 0), 0), MULT
)
2104 + rtx_cost (XEXP (XEXP (x
, 0), 1), MULT
)
2105 + rtx_cost (XEXP (x
, 1), code
);
2106 return true; /* Do not do an additional recursive descent. */
2108 *total
= COSTS_N_INSNS (1);
2112 switch (GET_MODE (x
))
2116 rtx left
= XEXP (x
, 0);
2117 rtx right
= XEXP (x
, 1);
2118 if (GET_CODE (right
) == CONST_INT
2119 && CONST_OK_FOR_K (INTVAL (right
)))
2120 *total
= s390_cost
->mhi
;
2121 else if (GET_CODE (left
) == SIGN_EXTEND
)
2122 *total
= s390_cost
->mh
;
2124 *total
= s390_cost
->ms
; /* msr, ms, msy */
2129 rtx left
= XEXP (x
, 0);
2130 rtx right
= XEXP (x
, 1);
2133 if (GET_CODE (right
) == CONST_INT
2134 && CONST_OK_FOR_K (INTVAL (right
)))
2135 *total
= s390_cost
->mghi
;
2136 else if (GET_CODE (left
) == SIGN_EXTEND
)
2137 *total
= s390_cost
->msgf
;
2139 *total
= s390_cost
->msg
; /* msgr, msg */
2141 else /* TARGET_31BIT */
2143 if (GET_CODE (left
) == SIGN_EXTEND
2144 && GET_CODE (right
) == SIGN_EXTEND
)
2145 /* mulsidi case: mr, m */
2146 *total
= s390_cost
->m
;
2147 else if (GET_CODE (left
) == ZERO_EXTEND
2148 && GET_CODE (right
) == ZERO_EXTEND
2149 && TARGET_CPU_ZARCH
)
2150 /* umulsidi case: ml, mlr */
2151 *total
= s390_cost
->ml
;
2153 /* Complex calculation is required. */
2154 *total
= COSTS_N_INSNS (40);
2160 *total
= s390_cost
->mult_df
;
2169 if (GET_MODE (x
) == TImode
) /* 128 bit division */
2170 *total
= s390_cost
->dlgr
;
2171 else if (GET_MODE (x
) == DImode
)
2173 rtx right
= XEXP (x
, 1);
2174 if (GET_CODE (right
) == ZERO_EXTEND
) /* 64 by 32 bit division */
2175 *total
= s390_cost
->dlr
;
2176 else /* 64 by 64 bit division */
2177 *total
= s390_cost
->dlgr
;
2179 else if (GET_MODE (x
) == SImode
) /* 32 bit division */
2180 *total
= s390_cost
->dlr
;
2185 if (GET_MODE (x
) == DImode
)
2187 rtx right
= XEXP (x
, 1);
2188 if (GET_CODE (right
) == ZERO_EXTEND
) /* 64 by 32 bit division */
2190 *total
= s390_cost
->dsgfr
;
2192 *total
= s390_cost
->dr
;
2193 else /* 64 by 64 bit division */
2194 *total
= s390_cost
->dsgr
;
2196 else if (GET_MODE (x
) == SImode
) /* 32 bit division */
2197 *total
= s390_cost
->dlr
;
2198 else if (GET_MODE (x
) == SFmode
)
2200 if (TARGET_IEEE_FLOAT
)
2201 *total
= s390_cost
->debr
;
2202 else /* TARGET_IBM_FLOAT */
2203 *total
= s390_cost
->der
;
2205 else if (GET_MODE (x
) == DFmode
)
2207 if (TARGET_IEEE_FLOAT
)
2208 *total
= s390_cost
->ddbr
;
2209 else /* TARGET_IBM_FLOAT */
2210 *total
= s390_cost
->ddr
;
2215 if (GET_MODE (x
) == SFmode
)
2216 *total
= s390_cost
->sqebr
;
2218 *total
= s390_cost
->sqdbr
;
2223 if (outer_code
== MULT
|| outer_code
== DIV
|| outer_code
== MOD
2224 || outer_code
== PLUS
|| outer_code
== MINUS
2225 || outer_code
== COMPARE
)
2230 *total
= COSTS_N_INSNS (1);
2231 if (GET_CODE (XEXP (x
, 0)) == AND
2232 && GET_CODE (XEXP (x
, 1)) == CONST_INT
2233 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
)
2235 rtx op0
= XEXP (XEXP (x
, 0), 0);
2236 rtx op1
= XEXP (XEXP (x
, 0), 1);
2237 rtx op2
= XEXP (x
, 1);
2239 if (memory_operand (op0
, GET_MODE (op0
))
2240 && s390_tm_ccmode (op1
, op2
, 0) != VOIDmode
)
2242 if (register_operand (op0
, GET_MODE (op0
))
2243 && s390_tm_ccmode (op1
, op2
, 1) != VOIDmode
)
2253 /* Return the cost of an address rtx ADDR. */
2256 s390_address_cost (rtx addr
)
2258 struct s390_address ad
;
2259 if (!s390_decompose_address (addr
, &ad
))
2262 return ad
.indx
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
2265 /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
2266 otherwise return 0. */
2269 tls_symbolic_operand (rtx op
)
2271 if (GET_CODE (op
) != SYMBOL_REF
)
2273 return SYMBOL_REF_TLS_MODEL (op
);
2276 /* Split DImode access register reference REG (on 64-bit) into its constituent
2277 low and high parts, and store them into LO and HI. Note that gen_lowpart/
2278 gen_highpart cannot be used as they assume all registers are word-sized,
2279 while our access registers have only half that size. */
2282 s390_split_access_reg (rtx reg
, rtx
*lo
, rtx
*hi
)
2284 gcc_assert (TARGET_64BIT
);
2285 gcc_assert (ACCESS_REG_P (reg
));
2286 gcc_assert (GET_MODE (reg
) == DImode
);
2287 gcc_assert (!(REGNO (reg
) & 1));
2289 *lo
= gen_rtx_REG (SImode
, REGNO (reg
) + 1);
2290 *hi
= gen_rtx_REG (SImode
, REGNO (reg
));
2293 /* Return true if OP contains a symbol reference */
2296 symbolic_reference_mentioned_p (rtx op
)
2301 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
2304 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
2305 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
2311 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
2312 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
2316 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
2323 /* Return true if OP contains a reference to a thread-local symbol. */
2326 tls_symbolic_reference_mentioned_p (rtx op
)
2331 if (GET_CODE (op
) == SYMBOL_REF
)
2332 return tls_symbolic_operand (op
);
2334 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
2335 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
2341 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
2342 if (tls_symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
2346 else if (fmt
[i
] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op
, i
)))
2354 /* Return true if OP is a legitimate general operand when
2355 generating PIC code. It is given that flag_pic is on
2356 and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2359 legitimate_pic_operand_p (rtx op
)
2361 /* Accept all non-symbolic constants. */
2362 if (!SYMBOLIC_CONST (op
))
2365 /* Reject everything else; must be handled
2366 via emit_symbolic_move. */
2370 /* Returns true if the constant value OP is a legitimate general operand.
2371 It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2374 legitimate_constant_p (rtx op
)
2376 /* Accept all non-symbolic constants. */
2377 if (!SYMBOLIC_CONST (op
))
2380 /* Accept immediate LARL operands. */
2381 if (TARGET_CPU_ZARCH
&& larl_operand (op
, VOIDmode
))
2384 /* Thread-local symbols are never legal constants. This is
2385 so that emit_call knows that computing such addresses
2386 might require a function call. */
2387 if (TLS_SYMBOLIC_CONST (op
))
2390 /* In the PIC case, symbolic constants must *not* be
2391 forced into the literal pool. We accept them here,
2392 so that they will be handled by emit_symbolic_move. */
2396 /* All remaining non-PIC symbolic constants are
2397 forced into the literal pool. */
2401 /* Determine if it's legal to put X into the constant pool. This
2402 is not possible if X contains the address of a symbol that is
2403 not constant (TLS) or not known at final link time (PIC). */
2406 s390_cannot_force_const_mem (rtx x
)
2408 switch (GET_CODE (x
))
2412 /* Accept all non-symbolic constants. */
2416 /* Labels are OK iff we are non-PIC. */
2417 return flag_pic
!= 0;
2420 /* 'Naked' TLS symbol references are never OK,
2421 non-TLS symbols are OK iff we are non-PIC. */
2422 if (tls_symbolic_operand (x
))
2425 return flag_pic
!= 0;
2428 return s390_cannot_force_const_mem (XEXP (x
, 0));
2431 return s390_cannot_force_const_mem (XEXP (x
, 0))
2432 || s390_cannot_force_const_mem (XEXP (x
, 1));
2435 switch (XINT (x
, 1))
2437 /* Only lt-relative or GOT-relative UNSPECs are OK. */
2438 case UNSPEC_LTREL_OFFSET
:
2446 case UNSPEC_GOTNTPOFF
:
2447 case UNSPEC_INDNTPOFF
:
2450 /* If the literal pool shares the code section, be put
2451 execute template placeholders into the pool as well. */
2453 return TARGET_CPU_ZARCH
;
2465 /* Returns true if the constant value OP is a legitimate general
2466 operand during and after reload. The difference to
2467 legitimate_constant_p is that this function will not accept
2468 a constant that would need to be forced to the literal pool
2469 before it can be used as operand. */
2472 legitimate_reload_constant_p (rtx op
)
2474 /* Accept la(y) operands. */
2475 if (GET_CODE (op
) == CONST_INT
2476 && DISP_IN_RANGE (INTVAL (op
)))
2479 /* Accept l(g)hi/l(g)fi operands. */
2480 if (GET_CODE (op
) == CONST_INT
2481 && (CONST_OK_FOR_K (INTVAL (op
)) || CONST_OK_FOR_Os (INTVAL (op
))))
2484 /* Accept lliXX operands. */
2486 && GET_CODE (op
) == CONST_INT
2487 && trunc_int_for_mode (INTVAL (op
), word_mode
) == INTVAL (op
)
2488 && s390_single_part (op
, word_mode
, HImode
, 0) >= 0)
2492 && GET_CODE (op
) == CONST_INT
2493 && trunc_int_for_mode (INTVAL (op
), word_mode
) == INTVAL (op
)
2494 && s390_single_part (op
, word_mode
, SImode
, 0) >= 0)
2497 /* Accept larl operands. */
2498 if (TARGET_CPU_ZARCH
2499 && larl_operand (op
, VOIDmode
))
2502 /* Accept lzXX operands. */
2503 if (GET_CODE (op
) == CONST_DOUBLE
2504 && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op
, 'G', "G"))
2507 /* Accept double-word operands that can be split. */
2508 if (GET_CODE (op
) == CONST_INT
2509 && trunc_int_for_mode (INTVAL (op
), word_mode
) != INTVAL (op
))
2511 enum machine_mode dword_mode
= word_mode
== SImode
? DImode
: TImode
;
2512 rtx hi
= operand_subword (op
, 0, 0, dword_mode
);
2513 rtx lo
= operand_subword (op
, 1, 0, dword_mode
);
2514 return legitimate_reload_constant_p (hi
)
2515 && legitimate_reload_constant_p (lo
);
2518 /* Everything else cannot be handled without reload. */
2522 /* Given an rtx OP being reloaded into a reg required to be in class CLASS,
2523 return the class of reg to actually use. */
2526 s390_preferred_reload_class (rtx op
, enum reg_class
class)
2528 switch (GET_CODE (op
))
2530 /* Constants we cannot reload must be forced into the
2535 if (legitimate_reload_constant_p (op
))
2540 /* If a symbolic constant or a PLUS is reloaded,
2541 it is most likely being used as an address, so
2542 prefer ADDR_REGS. If 'class' is not a superset
2543 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
2548 if (reg_class_subset_p (ADDR_REGS
, class))
2560 /* Return the register class of a scratch register needed to
2561 load IN into a register of class CLASS in MODE.
2563 We need a temporary when loading a PLUS expression which
2564 is not a legitimate operand of the LOAD ADDRESS instruction. */
2567 s390_secondary_input_reload_class (enum reg_class
class,
2568 enum machine_mode mode
, rtx in
)
2570 if (s390_plus_operand (in
, mode
))
2573 if (reg_classes_intersect_p (CC_REGS
, class))
2574 return GENERAL_REGS
;
2579 /* Return the register class of a scratch register needed to
2580 store a register of class CLASS in MODE into OUT:
2582 We need a temporary when storing a double-word to a
2583 non-offsettable memory address. */
2586 s390_secondary_output_reload_class (enum reg_class
class,
2587 enum machine_mode mode
, rtx out
)
2589 if ((TARGET_64BIT
? mode
== TImode
2590 : (mode
== DImode
|| mode
== DFmode
))
2591 && reg_classes_intersect_p (GENERAL_REGS
, class)
2592 && GET_CODE (out
) == MEM
2593 && GET_CODE (XEXP (out
, 0)) == PLUS
2594 && GET_CODE (XEXP (XEXP (out
, 0), 0)) == PLUS
2595 && GET_CODE (XEXP (XEXP (out
, 0), 1)) == CONST_INT
2596 && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (out
, 0), 1))
2597 + GET_MODE_SIZE (mode
) - 1))
2600 if (reg_classes_intersect_p (CC_REGS
, class))
2601 return GENERAL_REGS
;
2606 /* Generate code to load SRC, which is PLUS that is not a
2607 legitimate operand for the LA instruction, into TARGET.
2608 SCRATCH may be used as scratch register. */
2611 s390_expand_plus_operand (rtx target
, rtx src
,
2615 struct s390_address ad
;
2617 /* src must be a PLUS; get its two operands. */
2618 gcc_assert (GET_CODE (src
) == PLUS
);
2619 gcc_assert (GET_MODE (src
) == Pmode
);
2621 /* Check if any of the two operands is already scheduled
2622 for replacement by reload. This can happen e.g. when
2623 float registers occur in an address. */
2624 sum1
= find_replacement (&XEXP (src
, 0));
2625 sum2
= find_replacement (&XEXP (src
, 1));
2626 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
2628 /* If the address is already strictly valid, there's nothing to do. */
2629 if (!s390_decompose_address (src
, &ad
)
2630 || (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
2631 || (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
)))
2633 /* Otherwise, one of the operands cannot be an address register;
2634 we reload its value into the scratch register. */
2635 if (true_regnum (sum1
) < 1 || true_regnum (sum1
) > 15)
2637 emit_move_insn (scratch
, sum1
);
2640 if (true_regnum (sum2
) < 1 || true_regnum (sum2
) > 15)
2642 emit_move_insn (scratch
, sum2
);
2646 /* According to the way these invalid addresses are generated
2647 in reload.c, it should never happen (at least on s390) that
2648 *neither* of the PLUS components, after find_replacements
2649 was applied, is an address register. */
2650 if (sum1
== scratch
&& sum2
== scratch
)
2656 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
2659 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
2660 is only ever performed on addresses, so we can mark the
2661 sum as legitimate for LA in any case. */
2662 s390_load_address (target
, src
);
2666 /* Return true if ADDR is a valid memory address.
2667 STRICT specifies whether strict register checking applies. */
2670 legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED
,
2671 rtx addr
, int strict
)
2673 struct s390_address ad
;
2674 if (!s390_decompose_address (addr
, &ad
))
2679 if (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
2681 if (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
))
2686 if (ad
.base
&& !REG_OK_FOR_BASE_NONSTRICT_P (ad
.base
))
2688 if (ad
.indx
&& !REG_OK_FOR_INDEX_NONSTRICT_P (ad
.indx
))
2695 /* Return true if OP is a valid operand for the LA instruction.
2696 In 31-bit, we need to prove that the result is used as an
2697 address, as LA performs only a 31-bit addition. */
2700 legitimate_la_operand_p (rtx op
)
2702 struct s390_address addr
;
2703 if (!s390_decompose_address (op
, &addr
))
2706 return (TARGET_64BIT
|| addr
.pointer
);
2709 /* Return true if it is valid *and* preferable to use LA to
2710 compute the sum of OP1 and OP2. */
2713 preferred_la_operand_p (rtx op1
, rtx op2
)
2715 struct s390_address addr
;
2717 if (op2
!= const0_rtx
)
2718 op1
= gen_rtx_PLUS (Pmode
, op1
, op2
);
2720 if (!s390_decompose_address (op1
, &addr
))
2722 if (addr
.base
&& !REG_OK_FOR_BASE_STRICT_P (addr
.base
))
2724 if (addr
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (addr
.indx
))
2727 if (!TARGET_64BIT
&& !addr
.pointer
)
2733 if ((addr
.base
&& REG_P (addr
.base
) && REG_POINTER (addr
.base
))
2734 || (addr
.indx
&& REG_P (addr
.indx
) && REG_POINTER (addr
.indx
)))
2740 /* Emit a forced load-address operation to load SRC into DST.
2741 This will use the LOAD ADDRESS instruction even in situations
2742 where legitimate_la_operand_p (SRC) returns false. */
2745 s390_load_address (rtx dst
, rtx src
)
2748 emit_move_insn (dst
, src
);
2750 emit_insn (gen_force_la_31 (dst
, src
));
2753 /* Return a legitimate reference for ORIG (an address) using the
2754 register REG. If REG is 0, a new pseudo is generated.
2756 There are two types of references that must be handled:
2758 1. Global data references must load the address from the GOT, via
2759 the PIC reg. An insn is emitted to do this load, and the reg is
2762 2. Static data references, constant pool addresses, and code labels
2763 compute the address as an offset from the GOT, whose base is in
2764 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
2765 differentiate them from global data objects. The returned
2766 address is the PIC reg + an unspec constant.
2768 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2769 reg also appears in the address. */
2772 legitimize_pic_address (rtx orig
, rtx reg
)
2778 if (GET_CODE (addr
) == LABEL_REF
2779 || (GET_CODE (addr
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (addr
)))
2781 /* This is a local symbol. */
2782 if (TARGET_CPU_ZARCH
&& larl_operand (addr
, VOIDmode
))
2784 /* Access local symbols PC-relative via LARL.
2785 This is the same as in the non-PIC case, so it is
2786 handled automatically ... */
2790 /* Access local symbols relative to the GOT. */
2792 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2794 if (reload_in_progress
|| reload_completed
)
2795 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2797 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTOFF
);
2798 addr
= gen_rtx_CONST (Pmode
, addr
);
2799 addr
= force_const_mem (Pmode
, addr
);
2800 emit_move_insn (temp
, addr
);
2802 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2805 s390_load_address (reg
, new);
2810 else if (GET_CODE (addr
) == SYMBOL_REF
)
2813 reg
= gen_reg_rtx (Pmode
);
2817 /* Assume GOT offset < 4k. This is handled the same way
2818 in both 31- and 64-bit code (@GOT). */
2820 if (reload_in_progress
|| reload_completed
)
2821 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2823 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
2824 new = gen_rtx_CONST (Pmode
, new);
2825 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new);
2826 new = gen_const_mem (Pmode
, new);
2827 emit_move_insn (reg
, new);
2830 else if (TARGET_CPU_ZARCH
)
2832 /* If the GOT offset might be >= 4k, we determine the position
2833 of the GOT entry via a PC-relative LARL (@GOTENT). */
2835 rtx temp
= gen_reg_rtx (Pmode
);
2837 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTENT
);
2838 new = gen_rtx_CONST (Pmode
, new);
2839 emit_move_insn (temp
, new);
2841 new = gen_const_mem (Pmode
, temp
);
2842 emit_move_insn (reg
, new);
2847 /* If the GOT offset might be >= 4k, we have to load it
2848 from the literal pool (@GOT). */
2850 rtx temp
= gen_reg_rtx (Pmode
);
2852 if (reload_in_progress
|| reload_completed
)
2853 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2855 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
2856 addr
= gen_rtx_CONST (Pmode
, addr
);
2857 addr
= force_const_mem (Pmode
, addr
);
2858 emit_move_insn (temp
, addr
);
2860 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2861 new = gen_const_mem (Pmode
, new);
2862 emit_move_insn (reg
, new);
2868 if (GET_CODE (addr
) == CONST
)
2870 addr
= XEXP (addr
, 0);
2871 if (GET_CODE (addr
) == UNSPEC
)
2873 gcc_assert (XVECLEN (addr
, 0) == 1);
2874 switch (XINT (addr
, 1))
2876 /* If someone moved a GOT-relative UNSPEC
2877 out of the literal pool, force them back in. */
2880 new = force_const_mem (Pmode
, orig
);
2883 /* @GOT is OK as is if small. */
2886 new = force_const_mem (Pmode
, orig
);
2889 /* @GOTENT is OK as is. */
2893 /* @PLT is OK as is on 64-bit, must be converted to
2894 GOT-relative @PLTOFF on 31-bit. */
2896 if (!TARGET_CPU_ZARCH
)
2898 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2900 if (reload_in_progress
|| reload_completed
)
2901 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2903 addr
= XVECEXP (addr
, 0, 0);
2904 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
),
2906 addr
= gen_rtx_CONST (Pmode
, addr
);
2907 addr
= force_const_mem (Pmode
, addr
);
2908 emit_move_insn (temp
, addr
);
2910 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2913 s390_load_address (reg
, new);
2919 /* Everything else cannot happen. */
2925 gcc_assert (GET_CODE (addr
) == PLUS
);
2927 if (GET_CODE (addr
) == PLUS
)
2929 rtx op0
= XEXP (addr
, 0), op1
= XEXP (addr
, 1);
2930 /* Check first to see if this is a constant offset
2931 from a local symbol reference. */
2932 if ((GET_CODE (op0
) == LABEL_REF
2933 || (GET_CODE (op0
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (op0
)))
2934 && GET_CODE (op1
) == CONST_INT
)
2936 if (TARGET_CPU_ZARCH
&& larl_operand (op0
, VOIDmode
))
2938 if (INTVAL (op1
) & 1)
2940 /* LARL can't handle odd offsets, so emit a
2941 pair of LARL and LA. */
2942 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2944 if (!DISP_IN_RANGE (INTVAL (op1
)))
2946 int even
= INTVAL (op1
) - 1;
2947 op0
= gen_rtx_PLUS (Pmode
, op0
, GEN_INT (even
));
2948 op0
= gen_rtx_CONST (Pmode
, op0
);
2952 emit_move_insn (temp
, op0
);
2953 new = gen_rtx_PLUS (Pmode
, temp
, op1
);
2957 s390_load_address (reg
, new);
2963 /* If the offset is even, we can just use LARL.
2964 This will happen automatically. */
2969 /* Access local symbols relative to the GOT. */
2971 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2973 if (reload_in_progress
|| reload_completed
)
2974 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2976 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op0
),
2978 addr
= gen_rtx_PLUS (Pmode
, addr
, op1
);
2979 addr
= gen_rtx_CONST (Pmode
, addr
);
2980 addr
= force_const_mem (Pmode
, addr
);
2981 emit_move_insn (temp
, addr
);
2983 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2986 s390_load_address (reg
, new);
2992 /* Now, check whether it is a GOT relative symbol plus offset
2993 that was pulled out of the literal pool. Force it back in. */
2995 else if (GET_CODE (op0
) == UNSPEC
2996 && GET_CODE (op1
) == CONST_INT
2997 && XINT (op0
, 1) == UNSPEC_GOTOFF
)
2999 gcc_assert (XVECLEN (op0
, 0) == 1);
3001 new = force_const_mem (Pmode
, orig
);
3004 /* Otherwise, compute the sum. */
3007 base
= legitimize_pic_address (XEXP (addr
, 0), reg
);
3008 new = legitimize_pic_address (XEXP (addr
, 1),
3009 base
== reg
? NULL_RTX
: reg
);
3010 if (GET_CODE (new) == CONST_INT
)
3011 new = plus_constant (base
, INTVAL (new));
3014 if (GET_CODE (new) == PLUS
&& CONSTANT_P (XEXP (new, 1)))
3016 base
= gen_rtx_PLUS (Pmode
, base
, XEXP (new, 0));
3017 new = XEXP (new, 1);
3019 new = gen_rtx_PLUS (Pmode
, base
, new);
3022 if (GET_CODE (new) == CONST
)
3023 new = XEXP (new, 0);
3024 new = force_operand (new, 0);
3031 /* Load the thread pointer into a register. */
3034 s390_get_thread_pointer (void)
3036 rtx tp
= gen_reg_rtx (Pmode
);
3038 emit_move_insn (tp
, gen_rtx_REG (Pmode
, TP_REGNUM
));
3039 mark_reg_pointer (tp
, BITS_PER_WORD
);
3044 /* Emit a tls call insn. The call target is the SYMBOL_REF stored
3045 in s390_tls_symbol which always refers to __tls_get_offset.
3046 The returned offset is written to RESULT_REG and an USE rtx is
3047 generated for TLS_CALL. */
3049 static GTY(()) rtx s390_tls_symbol
;
3052 s390_emit_tls_call_insn (rtx result_reg
, rtx tls_call
)
3056 gcc_assert (flag_pic
);
3058 if (!s390_tls_symbol
)
3059 s390_tls_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "__tls_get_offset");
3061 insn
= s390_emit_call (s390_tls_symbol
, tls_call
, result_reg
,
3062 gen_rtx_REG (Pmode
, RETURN_REGNUM
));
3064 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), result_reg
);
3065 CONST_OR_PURE_CALL_P (insn
) = 1;
3068 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
3069 this (thread-local) address. REG may be used as temporary. */
3072 legitimize_tls_address (rtx addr
, rtx reg
)
3074 rtx
new, tls_call
, temp
, base
, r2
, insn
;
3076 if (GET_CODE (addr
) == SYMBOL_REF
)
3077 switch (tls_symbolic_operand (addr
))
3079 case TLS_MODEL_GLOBAL_DYNAMIC
:
3081 r2
= gen_rtx_REG (Pmode
, 2);
3082 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_TLSGD
);
3083 new = gen_rtx_CONST (Pmode
, tls_call
);
3084 new = force_const_mem (Pmode
, new);
3085 emit_move_insn (r2
, new);
3086 s390_emit_tls_call_insn (r2
, tls_call
);
3087 insn
= get_insns ();
3090 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
3091 temp
= gen_reg_rtx (Pmode
);
3092 emit_libcall_block (insn
, temp
, r2
, new);
3094 new = gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
3097 s390_load_address (reg
, new);
3102 case TLS_MODEL_LOCAL_DYNAMIC
:
3104 r2
= gen_rtx_REG (Pmode
, 2);
3105 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM
);
3106 new = gen_rtx_CONST (Pmode
, tls_call
);
3107 new = force_const_mem (Pmode
, new);
3108 emit_move_insn (r2
, new);
3109 s390_emit_tls_call_insn (r2
, tls_call
);
3110 insn
= get_insns ();
3113 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM_NTPOFF
);
3114 temp
= gen_reg_rtx (Pmode
);
3115 emit_libcall_block (insn
, temp
, r2
, new);
3117 new = gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
3118 base
= gen_reg_rtx (Pmode
);
3119 s390_load_address (base
, new);
3121 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_DTPOFF
);
3122 new = gen_rtx_CONST (Pmode
, new);
3123 new = force_const_mem (Pmode
, new);
3124 temp
= gen_reg_rtx (Pmode
);
3125 emit_move_insn (temp
, new);
3127 new = gen_rtx_PLUS (Pmode
, base
, temp
);
3130 s390_load_address (reg
, new);
3135 case TLS_MODEL_INITIAL_EXEC
:
3138 /* Assume GOT offset < 4k. This is handled the same way
3139 in both 31- and 64-bit code. */
3141 if (reload_in_progress
|| reload_completed
)
3142 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
3144 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
3145 new = gen_rtx_CONST (Pmode
, new);
3146 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new);
3147 new = gen_const_mem (Pmode
, new);
3148 temp
= gen_reg_rtx (Pmode
);
3149 emit_move_insn (temp
, new);
3151 else if (TARGET_CPU_ZARCH
)
3153 /* If the GOT offset might be >= 4k, we determine the position
3154 of the GOT entry via a PC-relative LARL. */
3156 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
3157 new = gen_rtx_CONST (Pmode
, new);
3158 temp
= gen_reg_rtx (Pmode
);
3159 emit_move_insn (temp
, new);
3161 new = gen_const_mem (Pmode
, temp
);
3162 temp
= gen_reg_rtx (Pmode
);
3163 emit_move_insn (temp
, new);
3167 /* If the GOT offset might be >= 4k, we have to load it
3168 from the literal pool. */
3170 if (reload_in_progress
|| reload_completed
)
3171 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
3173 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
3174 new = gen_rtx_CONST (Pmode
, new);
3175 new = force_const_mem (Pmode
, new);
3176 temp
= gen_reg_rtx (Pmode
);
3177 emit_move_insn (temp
, new);
3179 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
3180 new = gen_const_mem (Pmode
, new);
3182 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new, addr
), UNSPEC_TLS_LOAD
);
3183 temp
= gen_reg_rtx (Pmode
);
3184 emit_insn (gen_rtx_SET (Pmode
, temp
, new));
3188 /* In position-dependent code, load the absolute address of
3189 the GOT entry from the literal pool. */
3191 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
3192 new = gen_rtx_CONST (Pmode
, new);
3193 new = force_const_mem (Pmode
, new);
3194 temp
= gen_reg_rtx (Pmode
);
3195 emit_move_insn (temp
, new);
3198 new = gen_const_mem (Pmode
, new);
3199 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new, addr
), UNSPEC_TLS_LOAD
);
3200 temp
= gen_reg_rtx (Pmode
);
3201 emit_insn (gen_rtx_SET (Pmode
, temp
, new));
3204 new = gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
3207 s390_load_address (reg
, new);
3212 case TLS_MODEL_LOCAL_EXEC
:
3213 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
3214 new = gen_rtx_CONST (Pmode
, new);
3215 new = force_const_mem (Pmode
, new);
3216 temp
= gen_reg_rtx (Pmode
);
3217 emit_move_insn (temp
, new);
3219 new = gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
3222 s390_load_address (reg
, new);
3231 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == UNSPEC
)
3233 switch (XINT (XEXP (addr
, 0), 1))
3235 case UNSPEC_INDNTPOFF
:
3236 gcc_assert (TARGET_CPU_ZARCH
);
3245 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == PLUS
3246 && GET_CODE (XEXP (XEXP (addr
, 0), 1)) == CONST_INT
)
3248 new = XEXP (XEXP (addr
, 0), 0);
3249 if (GET_CODE (new) != SYMBOL_REF
)
3250 new = gen_rtx_CONST (Pmode
, new);
3252 new = legitimize_tls_address (new, reg
);
3253 new = plus_constant (new, INTVAL (XEXP (XEXP (addr
, 0), 1)));
3254 new = force_operand (new, 0);
3258 gcc_unreachable (); /* for now ... */
3263 /* Emit insns to move operands[1] into operands[0]. */
3266 emit_symbolic_move (rtx
*operands
)
3268 rtx temp
= no_new_pseudos
? operands
[0] : gen_reg_rtx (Pmode
);
3270 if (GET_CODE (operands
[0]) == MEM
)
3271 operands
[1] = force_reg (Pmode
, operands
[1]);
3272 else if (TLS_SYMBOLIC_CONST (operands
[1]))
3273 operands
[1] = legitimize_tls_address (operands
[1], temp
);
3275 operands
[1] = legitimize_pic_address (operands
[1], temp
);
3278 /* Try machine-dependent ways of modifying an illegitimate address X
3279 to be legitimate. If we find one, return the new, valid address.
3281 OLDX is the address as it was before break_out_memory_refs was called.
3282 In some cases it is useful to look at this to decide what needs to be done.
3284 MODE is the mode of the operand pointed to by X.
3286 When -fpic is used, special handling is needed for symbolic references.
3287 See comments by legitimize_pic_address for details. */
3290 legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
3291 enum machine_mode mode ATTRIBUTE_UNUSED
)
3293 rtx constant_term
= const0_rtx
;
3295 if (TLS_SYMBOLIC_CONST (x
))
3297 x
= legitimize_tls_address (x
, 0);
3299 if (legitimate_address_p (mode
, x
, FALSE
))
3304 if (SYMBOLIC_CONST (x
)
3305 || (GET_CODE (x
) == PLUS
3306 && (SYMBOLIC_CONST (XEXP (x
, 0))
3307 || SYMBOLIC_CONST (XEXP (x
, 1)))))
3308 x
= legitimize_pic_address (x
, 0);
3310 if (legitimate_address_p (mode
, x
, FALSE
))
3314 x
= eliminate_constant_term (x
, &constant_term
);
3316 /* Optimize loading of large displacements by splitting them
3317 into the multiple of 4K and the rest; this allows the
3318 former to be CSE'd if possible.
3320 Don't do this if the displacement is added to a register
3321 pointing into the stack frame, as the offsets will
3322 change later anyway. */
3324 if (GET_CODE (constant_term
) == CONST_INT
3325 && !TARGET_LONG_DISPLACEMENT
3326 && !DISP_IN_RANGE (INTVAL (constant_term
))
3327 && !(REG_P (x
) && REGNO_PTR_FRAME_P (REGNO (x
))))
3329 HOST_WIDE_INT lower
= INTVAL (constant_term
) & 0xfff;
3330 HOST_WIDE_INT upper
= INTVAL (constant_term
) ^ lower
;
3332 rtx temp
= gen_reg_rtx (Pmode
);
3333 rtx val
= force_operand (GEN_INT (upper
), temp
);
3335 emit_move_insn (temp
, val
);
3337 x
= gen_rtx_PLUS (Pmode
, x
, temp
);
3338 constant_term
= GEN_INT (lower
);
3341 if (GET_CODE (x
) == PLUS
)
3343 if (GET_CODE (XEXP (x
, 0)) == REG
)
3345 rtx temp
= gen_reg_rtx (Pmode
);
3346 rtx val
= force_operand (XEXP (x
, 1), temp
);
3348 emit_move_insn (temp
, val
);
3350 x
= gen_rtx_PLUS (Pmode
, XEXP (x
, 0), temp
);
3353 else if (GET_CODE (XEXP (x
, 1)) == REG
)
3355 rtx temp
= gen_reg_rtx (Pmode
);
3356 rtx val
= force_operand (XEXP (x
, 0), temp
);
3358 emit_move_insn (temp
, val
);
3360 x
= gen_rtx_PLUS (Pmode
, temp
, XEXP (x
, 1));
3364 if (constant_term
!= const0_rtx
)
3365 x
= gen_rtx_PLUS (Pmode
, x
, constant_term
);
3370 /* Try a machine-dependent way of reloading an illegitimate address AD
3371 operand. If we find one, push the reload and and return the new address.
3373 MODE is the mode of the enclosing MEM. OPNUM is the operand number
3374 and TYPE is the reload type of the current reload. */
3377 legitimize_reload_address (rtx ad
, enum machine_mode mode ATTRIBUTE_UNUSED
,
3378 int opnum
, int type
)
3380 if (!optimize
|| TARGET_LONG_DISPLACEMENT
)
3383 if (GET_CODE (ad
) == PLUS
)
3385 rtx tem
= simplify_binary_operation (PLUS
, Pmode
,
3386 XEXP (ad
, 0), XEXP (ad
, 1));
3391 if (GET_CODE (ad
) == PLUS
3392 && GET_CODE (XEXP (ad
, 0)) == REG
3393 && GET_CODE (XEXP (ad
, 1)) == CONST_INT
3394 && !DISP_IN_RANGE (INTVAL (XEXP (ad
, 1))))
3396 HOST_WIDE_INT lower
= INTVAL (XEXP (ad
, 1)) & 0xfff;
3397 HOST_WIDE_INT upper
= INTVAL (XEXP (ad
, 1)) ^ lower
;
3400 cst
= GEN_INT (upper
);
3401 if (!legitimate_reload_constant_p (cst
))
3402 cst
= force_const_mem (Pmode
, cst
);
3404 tem
= gen_rtx_PLUS (Pmode
, XEXP (ad
, 0), cst
);
3405 new = gen_rtx_PLUS (Pmode
, tem
, GEN_INT (lower
));
3407 push_reload (XEXP (tem
, 1), 0, &XEXP (tem
, 1), 0,
3408 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
3409 opnum
, (enum reload_type
) type
);
3416 /* Emit code to move LEN bytes from DST to SRC. */
3419 s390_expand_movmem (rtx dst
, rtx src
, rtx len
)
3421 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3423 if (INTVAL (len
) > 0)
3424 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (INTVAL (len
) - 1)));
3427 else if (TARGET_MVCLE
)
3429 emit_insn (gen_movmem_long (dst
, src
, convert_to_mode (Pmode
, len
, 1)));
3434 rtx dst_addr
, src_addr
, count
, blocks
, temp
;
3435 rtx loop_start_label
= gen_label_rtx ();
3436 rtx loop_end_label
= gen_label_rtx ();
3437 rtx end_label
= gen_label_rtx ();
3438 enum machine_mode mode
;
3440 mode
= GET_MODE (len
);
3441 if (mode
== VOIDmode
)
3444 dst_addr
= gen_reg_rtx (Pmode
);
3445 src_addr
= gen_reg_rtx (Pmode
);
3446 count
= gen_reg_rtx (mode
);
3447 blocks
= gen_reg_rtx (mode
);
3449 convert_move (count
, len
, 1);
3450 emit_cmp_and_jump_insns (count
, const0_rtx
,
3451 EQ
, NULL_RTX
, mode
, 1, end_label
);
3453 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
3454 emit_move_insn (src_addr
, force_operand (XEXP (src
, 0), NULL_RTX
));
3455 dst
= change_address (dst
, VOIDmode
, dst_addr
);
3456 src
= change_address (src
, VOIDmode
, src_addr
);
3458 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3460 emit_move_insn (count
, temp
);
3462 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3464 emit_move_insn (blocks
, temp
);
3466 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3467 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3469 emit_label (loop_start_label
);
3471 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (255)));
3472 s390_load_address (dst_addr
,
3473 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
3474 s390_load_address (src_addr
,
3475 gen_rtx_PLUS (Pmode
, src_addr
, GEN_INT (256)));
3477 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3479 emit_move_insn (blocks
, temp
);
3481 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3482 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3484 emit_jump (loop_start_label
);
3485 emit_label (loop_end_label
);
3487 emit_insn (gen_movmem_short (dst
, src
,
3488 convert_to_mode (Pmode
, count
, 1)));
3489 emit_label (end_label
);
3493 /* Emit code to set LEN bytes at DST to VAL.
3494 Make use of clrmem if VAL is zero. */
3497 s390_expand_setmem (rtx dst
, rtx len
, rtx val
)
3499 gcc_assert (GET_CODE (len
) != CONST_INT
|| INTVAL (len
) > 0);
3500 gcc_assert (GET_CODE (val
) == CONST_INT
|| GET_MODE (val
) == QImode
);
3502 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) <= 257)
3504 if (val
== const0_rtx
&& INTVAL (len
) <= 256)
3505 emit_insn (gen_clrmem_short (dst
, GEN_INT (INTVAL (len
) - 1)));
3508 /* Initialize memory by storing the first byte. */
3509 emit_move_insn (adjust_address (dst
, QImode
, 0), val
);
3511 if (INTVAL (len
) > 1)
3513 /* Initiate 1 byte overlap move.
3514 The first byte of DST is propagated through DSTP1.
3515 Prepare a movmem for: DST+1 = DST (length = LEN - 1).
3516 DST is set to size 1 so the rest of the memory location
3517 does not count as source operand. */
3518 rtx dstp1
= adjust_address (dst
, VOIDmode
, 1);
3519 set_mem_size (dst
, const1_rtx
);
3521 emit_insn (gen_movmem_short (dstp1
, dst
,
3522 GEN_INT (INTVAL (len
) - 2)));
3527 else if (TARGET_MVCLE
)
3529 val
= force_not_mem (convert_modes (Pmode
, QImode
, val
, 1));
3530 emit_insn (gen_setmem_long (dst
, convert_to_mode (Pmode
, len
, 1), val
));
3535 rtx dst_addr
, src_addr
, count
, blocks
, temp
, dstp1
= NULL_RTX
;
3536 rtx loop_start_label
= gen_label_rtx ();
3537 rtx loop_end_label
= gen_label_rtx ();
3538 rtx end_label
= gen_label_rtx ();
3539 enum machine_mode mode
;
3541 mode
= GET_MODE (len
);
3542 if (mode
== VOIDmode
)
3545 dst_addr
= gen_reg_rtx (Pmode
);
3546 src_addr
= gen_reg_rtx (Pmode
);
3547 count
= gen_reg_rtx (mode
);
3548 blocks
= gen_reg_rtx (mode
);
3550 convert_move (count
, len
, 1);
3551 emit_cmp_and_jump_insns (count
, const0_rtx
,
3552 EQ
, NULL_RTX
, mode
, 1, end_label
);
3554 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
3555 dst
= change_address (dst
, VOIDmode
, dst_addr
);
3557 if (val
== const0_rtx
)
3558 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3561 dstp1
= adjust_address (dst
, VOIDmode
, 1);
3562 set_mem_size (dst
, const1_rtx
);
3564 /* Initialize memory by storing the first byte. */
3565 emit_move_insn (adjust_address (dst
, QImode
, 0), val
);
3567 /* If count is 1 we are done. */
3568 emit_cmp_and_jump_insns (count
, const1_rtx
,
3569 EQ
, NULL_RTX
, mode
, 1, end_label
);
3571 temp
= expand_binop (mode
, add_optab
, count
, GEN_INT (-2), count
, 1, 0);
3574 emit_move_insn (count
, temp
);
3576 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3578 emit_move_insn (blocks
, temp
);
3580 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3581 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3583 emit_label (loop_start_label
);
3585 if (val
== const0_rtx
)
3586 emit_insn (gen_clrmem_short (dst
, GEN_INT (255)));
3588 emit_insn (gen_movmem_short (dstp1
, dst
, GEN_INT (255)));
3589 s390_load_address (dst_addr
,
3590 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
3592 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3594 emit_move_insn (blocks
, temp
);
3596 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3597 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3599 emit_jump (loop_start_label
);
3600 emit_label (loop_end_label
);
3602 if (val
== const0_rtx
)
3603 emit_insn (gen_clrmem_short (dst
, convert_to_mode (Pmode
, count
, 1)));
3605 emit_insn (gen_movmem_short (dstp1
, dst
, convert_to_mode (Pmode
, count
, 1)));
3606 emit_label (end_label
);
3610 /* Emit code to compare LEN bytes at OP0 with those at OP1,
3611 and return the result in TARGET. */
3614 s390_expand_cmpmem (rtx target
, rtx op0
, rtx op1
, rtx len
)
3616 rtx ccreg
= gen_rtx_REG (CCUmode
, CC_REGNUM
);
3619 /* As the result of CMPINT is inverted compared to what we need,
3620 we have to swap the operands. */
3621 tmp
= op0
; op0
= op1
; op1
= tmp
;
3623 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3625 if (INTVAL (len
) > 0)
3627 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (INTVAL (len
) - 1)));
3628 emit_insn (gen_cmpint (target
, ccreg
));
3631 emit_move_insn (target
, const0_rtx
);
3633 else if (TARGET_MVCLE
)
3635 emit_insn (gen_cmpmem_long (op0
, op1
, convert_to_mode (Pmode
, len
, 1)));
3636 emit_insn (gen_cmpint (target
, ccreg
));
3640 rtx addr0
, addr1
, count
, blocks
, temp
;
3641 rtx loop_start_label
= gen_label_rtx ();
3642 rtx loop_end_label
= gen_label_rtx ();
3643 rtx end_label
= gen_label_rtx ();
3644 enum machine_mode mode
;
3646 mode
= GET_MODE (len
);
3647 if (mode
== VOIDmode
)
3650 addr0
= gen_reg_rtx (Pmode
);
3651 addr1
= gen_reg_rtx (Pmode
);
3652 count
= gen_reg_rtx (mode
);
3653 blocks
= gen_reg_rtx (mode
);
3655 convert_move (count
, len
, 1);
3656 emit_cmp_and_jump_insns (count
, const0_rtx
,
3657 EQ
, NULL_RTX
, mode
, 1, end_label
);
3659 emit_move_insn (addr0
, force_operand (XEXP (op0
, 0), NULL_RTX
));
3660 emit_move_insn (addr1
, force_operand (XEXP (op1
, 0), NULL_RTX
));
3661 op0
= change_address (op0
, VOIDmode
, addr0
);
3662 op1
= change_address (op1
, VOIDmode
, addr1
);
3664 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3666 emit_move_insn (count
, temp
);
3668 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3670 emit_move_insn (blocks
, temp
);
3672 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3673 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3675 emit_label (loop_start_label
);
3677 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (255)));
3678 temp
= gen_rtx_NE (VOIDmode
, ccreg
, const0_rtx
);
3679 temp
= gen_rtx_IF_THEN_ELSE (VOIDmode
, temp
,
3680 gen_rtx_LABEL_REF (VOIDmode
, end_label
), pc_rtx
);
3681 temp
= gen_rtx_SET (VOIDmode
, pc_rtx
, temp
);
3682 emit_jump_insn (temp
);
3684 s390_load_address (addr0
,
3685 gen_rtx_PLUS (Pmode
, addr0
, GEN_INT (256)));
3686 s390_load_address (addr1
,
3687 gen_rtx_PLUS (Pmode
, addr1
, GEN_INT (256)));
3689 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3691 emit_move_insn (blocks
, temp
);
3693 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3694 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3696 emit_jump (loop_start_label
);
3697 emit_label (loop_end_label
);
3699 emit_insn (gen_cmpmem_short (op0
, op1
,
3700 convert_to_mode (Pmode
, count
, 1)));
3701 emit_label (end_label
);
3703 emit_insn (gen_cmpint (target
, ccreg
));
3708 /* Expand conditional increment or decrement using alc/slb instructions.
3709 Should generate code setting DST to either SRC or SRC + INCREMENT,
3710 depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
3711 Returns true if successful, false otherwise.
3713 That makes it possible to implement some if-constructs without jumps e.g.:
3714 (borrow = CC0 | CC1 and carry = CC2 | CC3)
3715 unsigned int a, b, c;
3716 if (a < b) c++; -> CCU b > a -> CC2; c += carry;
3717 if (a < b) c--; -> CCL3 a - b -> borrow; c -= borrow;
3718 if (a <= b) c++; -> CCL3 b - a -> borrow; c += carry;
3719 if (a <= b) c--; -> CCU a <= b -> borrow; c -= borrow;
3721 Checks for EQ and NE with a nonzero value need an additional xor e.g.:
3722 if (a == b) c++; -> CCL3 a ^= b; 0 - a -> borrow; c += carry;
3723 if (a == b) c--; -> CCU a ^= b; a <= 0 -> CC0 | CC1; c -= borrow;
3724 if (a != b) c++; -> CCU a ^= b; a > 0 -> CC2; c += carry;
3725 if (a != b) c--; -> CCL3 a ^= b; 0 - a -> borrow; c -= borrow; */
3728 s390_expand_addcc (enum rtx_code cmp_code
, rtx cmp_op0
, rtx cmp_op1
,
3729 rtx dst
, rtx src
, rtx increment
)
3731 enum machine_mode cmp_mode
;
3732 enum machine_mode cc_mode
;
3738 if ((GET_MODE (cmp_op0
) == SImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
3739 && (GET_MODE (cmp_op1
) == SImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
3741 else if ((GET_MODE (cmp_op0
) == DImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
3742 && (GET_MODE (cmp_op1
) == DImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
3747 /* Try ADD LOGICAL WITH CARRY. */
3748 if (increment
== const1_rtx
)
3750 /* Determine CC mode to use. */
3751 if (cmp_code
== EQ
|| cmp_code
== NE
)
3753 if (cmp_op1
!= const0_rtx
)
3755 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
3756 NULL_RTX
, 0, OPTAB_WIDEN
);
3757 cmp_op1
= const0_rtx
;
3760 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
3763 if (cmp_code
== LTU
|| cmp_code
== LEU
)
3768 cmp_code
= swap_condition (cmp_code
);
3785 /* Emit comparison instruction pattern. */
3786 if (!register_operand (cmp_op0
, cmp_mode
))
3787 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
3789 insn
= gen_rtx_SET (VOIDmode
, gen_rtx_REG (cc_mode
, CC_REGNUM
),
3790 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
3791 /* We use insn_invalid_p here to add clobbers if required. */
3792 ret
= insn_invalid_p (emit_insn (insn
));
3795 /* Emit ALC instruction pattern. */
3796 op_res
= gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
3797 gen_rtx_REG (cc_mode
, CC_REGNUM
),
3800 if (src
!= const0_rtx
)
3802 if (!register_operand (src
, GET_MODE (dst
)))
3803 src
= force_reg (GET_MODE (dst
), src
);
3805 src
= gen_rtx_PLUS (GET_MODE (dst
), src
, const0_rtx
);
3806 op_res
= gen_rtx_PLUS (GET_MODE (dst
), src
, op_res
);
3809 p
= rtvec_alloc (2);
3811 gen_rtx_SET (VOIDmode
, dst
, op_res
);
3813 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
3814 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
3819 /* Try SUBTRACT LOGICAL WITH BORROW. */
3820 if (increment
== constm1_rtx
)
3822 /* Determine CC mode to use. */
3823 if (cmp_code
== EQ
|| cmp_code
== NE
)
3825 if (cmp_op1
!= const0_rtx
)
3827 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
3828 NULL_RTX
, 0, OPTAB_WIDEN
);
3829 cmp_op1
= const0_rtx
;
3832 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
3835 if (cmp_code
== GTU
|| cmp_code
== GEU
)
3840 cmp_code
= swap_condition (cmp_code
);
3857 /* Emit comparison instruction pattern. */
3858 if (!register_operand (cmp_op0
, cmp_mode
))
3859 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
3861 insn
= gen_rtx_SET (VOIDmode
, gen_rtx_REG (cc_mode
, CC_REGNUM
),
3862 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
3863 /* We use insn_invalid_p here to add clobbers if required. */
3864 ret
= insn_invalid_p (emit_insn (insn
));
3867 /* Emit SLB instruction pattern. */
3868 if (!register_operand (src
, GET_MODE (dst
)))
3869 src
= force_reg (GET_MODE (dst
), src
);
3871 op_res
= gen_rtx_MINUS (GET_MODE (dst
),
3872 gen_rtx_MINUS (GET_MODE (dst
), src
, const0_rtx
),
3873 gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
3874 gen_rtx_REG (cc_mode
, CC_REGNUM
),
3876 p
= rtvec_alloc (2);
3878 gen_rtx_SET (VOIDmode
, dst
, op_res
);
3880 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
3881 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
3889 /* Expand code for the insv template. Return true if successful, false else. */
3892 s390_expand_insv (rtx dest
, rtx op1
, rtx op2
, rtx src
)
3894 int bitsize
= INTVAL (op1
);
3895 int bitpos
= INTVAL (op2
);
3897 /* We need byte alignment. */
3898 if (bitsize
% BITS_PER_UNIT
)
3902 && memory_operand (dest
, VOIDmode
)
3903 && (register_operand (src
, word_mode
)
3904 || const_int_operand (src
, VOIDmode
)))
3906 /* Emit standard pattern if possible. */
3907 enum machine_mode mode
= smallest_mode_for_size (bitsize
, MODE_INT
);
3908 if (GET_MODE_BITSIZE (mode
) == bitsize
)
3909 emit_move_insn (adjust_address (dest
, mode
, 0), gen_lowpart (mode
, src
));
3911 /* (set (ze (mem)) (const_int)). */
3912 else if (const_int_operand (src
, VOIDmode
))
3914 int size
= bitsize
/ BITS_PER_UNIT
;
3915 rtx src_mem
= adjust_address (force_const_mem (word_mode
, src
), BLKmode
,
3916 GET_MODE_SIZE (word_mode
) - size
);
3918 dest
= adjust_address (dest
, BLKmode
, 0);
3919 set_mem_size (dest
, GEN_INT (size
));
3920 s390_expand_movmem (dest
, src_mem
, GEN_INT (size
));
3923 /* (set (ze (mem)) (reg)). */
3924 else if (register_operand (src
, word_mode
))
3926 if (bitsize
<= GET_MODE_BITSIZE (SImode
))
3927 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode
, dest
, op1
,
3931 /* Emit st,stcmh sequence. */
3932 int stcmh_width
= bitsize
- GET_MODE_BITSIZE (SImode
);
3933 int size
= stcmh_width
/ BITS_PER_UNIT
;
3935 emit_move_insn (adjust_address (dest
, SImode
, size
),
3936 gen_lowpart (SImode
, src
));
3937 set_mem_size (dest
, GEN_INT (size
));
3938 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode
, dest
, GEN_INT
3939 (stcmh_width
), const0_rtx
),
3940 gen_rtx_LSHIFTRT (word_mode
, src
, GEN_INT
3941 (GET_MODE_BITSIZE (SImode
))));
3950 /* (set (ze (reg)) (const_int)). */
3952 && register_operand (dest
, word_mode
)
3953 && (bitpos
% 16) == 0
3954 && (bitsize
% 16) == 0
3955 && const_int_operand (src
, VOIDmode
))
3957 HOST_WIDE_INT val
= INTVAL (src
);
3958 int regpos
= bitpos
+ bitsize
;
3960 while (regpos
> bitpos
)
3962 enum machine_mode putmode
;
3965 if (TARGET_EXTIMM
&& (regpos
% 32 == 0) && (regpos
>= bitpos
+ 32))
3970 putsize
= GET_MODE_BITSIZE (putmode
);
3972 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode
, dest
,
3975 gen_int_mode (val
, putmode
));
3978 gcc_assert (regpos
== bitpos
);
3985 /* A subroutine of s390_expand_cs_hqi and s390_expand_atomic which returns a
3986 register that holds VAL of mode MODE shifted by COUNT bits. */
3989 s390_expand_mask_and_shift (rtx val
, enum machine_mode mode
, rtx count
)
3991 val
= expand_simple_binop (SImode
, AND
, val
, GEN_INT (GET_MODE_MASK (mode
)),
3992 NULL_RTX
, 1, OPTAB_DIRECT
);
3993 return expand_simple_binop (SImode
, ASHIFT
, val
, count
,
3994 NULL_RTX
, 1, OPTAB_DIRECT
);
3997 /* Structure to hold the initial parameters for a compare_and_swap operation
3998 in HImode and QImode. */
4000 struct alignment_context
4002 rtx memsi
; /* SI aligned memory location. */
4003 rtx shift
; /* Bit offset with regard to lsb. */
4004 rtx modemask
; /* Mask of the HQImode shifted by SHIFT bits. */
4005 rtx modemaski
; /* ~modemask */
4006 bool aligned
; /* True if memory is aligned, false else. */
4009 /* A subroutine of s390_expand_cs_hqi and s390_expand_atomic to initialize
4010 structure AC for transparent simplifying, if the memory alignment is known
4011 to be at least 32bit. MEM is the memory location for the actual operation
4012 and MODE its mode. */
4015 init_alignment_context (struct alignment_context
*ac
, rtx mem
,
4016 enum machine_mode mode
)
4018 ac
->shift
= GEN_INT (GET_MODE_SIZE (SImode
) - GET_MODE_SIZE (mode
));
4019 ac
->aligned
= (MEM_ALIGN (mem
) >= GET_MODE_BITSIZE (SImode
));
4022 ac
->memsi
= adjust_address (mem
, SImode
, 0); /* Memory is aligned. */
4025 /* Alignment is unknown. */
4026 rtx byteoffset
, addr
, align
;
4028 /* Force the address into a register. */
4029 addr
= force_reg (Pmode
, XEXP (mem
, 0));
4031 /* Align it to SImode. */
4032 align
= expand_simple_binop (Pmode
, AND
, addr
,
4033 GEN_INT (-GET_MODE_SIZE (SImode
)),
4034 NULL_RTX
, 1, OPTAB_DIRECT
);
4036 ac
->memsi
= gen_rtx_MEM (SImode
, align
);
4037 MEM_VOLATILE_P (ac
->memsi
) = MEM_VOLATILE_P (mem
);
4038 set_mem_alias_set (ac
->memsi
, ALIAS_SET_MEMORY_BARRIER
);
4039 set_mem_align (ac
->memsi
, GET_MODE_BITSIZE (SImode
));
4041 /* Calculate shiftcount. */
4042 byteoffset
= expand_simple_binop (Pmode
, AND
, addr
,
4043 GEN_INT (GET_MODE_SIZE (SImode
) - 1),
4044 NULL_RTX
, 1, OPTAB_DIRECT
);
4045 /* As we already have some offset, evaluate the remaining distance. */
4046 ac
->shift
= expand_simple_binop (SImode
, MINUS
, ac
->shift
, byteoffset
,
4047 NULL_RTX
, 1, OPTAB_DIRECT
);
4050 /* Shift is the byte count, but we need the bitcount. */
4051 ac
->shift
= expand_simple_binop (SImode
, MULT
, ac
->shift
, GEN_INT (BITS_PER_UNIT
),
4052 NULL_RTX
, 1, OPTAB_DIRECT
);
4053 /* Calculate masks. */
4054 ac
->modemask
= expand_simple_binop (SImode
, ASHIFT
,
4055 GEN_INT (GET_MODE_MASK (mode
)), ac
->shift
,
4056 NULL_RTX
, 1, OPTAB_DIRECT
);
4057 ac
->modemaski
= expand_simple_unop (SImode
, NOT
, ac
->modemask
, NULL_RTX
, 1);
4060 /* Expand an atomic compare and swap operation for HImode and QImode. MEM is
4061 the memory location, CMP the old value to compare MEM with and NEW the value
4062 to set if CMP == MEM.
4063 CMP is never in memory for compare_and_swap_cc because
4064 expand_bool_compare_and_swap puts it into a register for later compare. */
4067 s390_expand_cs_hqi (enum machine_mode mode
, rtx target
, rtx mem
, rtx cmp
, rtx
new)
4069 struct alignment_context ac
;
4070 rtx cmpv
, newv
, val
, resv
, cc
;
4071 rtx res
= gen_reg_rtx (SImode
);
4072 rtx csloop
= gen_label_rtx ();
4073 rtx csend
= gen_label_rtx ();
4075 gcc_assert (register_operand (target
, VOIDmode
));
4076 gcc_assert (MEM_P (mem
));
4078 init_alignment_context (&ac
, mem
, mode
);
4080 /* Shift the values to the correct bit positions. */
4081 if (!(ac
.aligned
&& MEM_P (cmp
)))
4082 cmp
= s390_expand_mask_and_shift (cmp
, mode
, ac
.shift
);
4083 if (!(ac
.aligned
&& MEM_P (new)))
4084 new = s390_expand_mask_and_shift (new, mode
, ac
.shift
);
4086 /* Load full word. Subsequent loads are performed by CS. */
4087 val
= expand_simple_binop (SImode
, AND
, ac
.memsi
, ac
.modemaski
,
4088 NULL_RTX
, 1, OPTAB_DIRECT
);
4090 /* Start CS loop. */
4091 emit_label (csloop
);
4092 /* val = "<mem>00..0<mem>"
4093 * cmp = "00..0<cmp>00..0"
4094 * new = "00..0<new>00..0"
4097 /* Patch cmp and new with val at correct position. */
4098 if (ac
.aligned
&& MEM_P (cmp
))
4100 cmpv
= force_reg (SImode
, val
);
4101 store_bit_field (cmpv
, GET_MODE_BITSIZE (mode
), 0, SImode
, cmp
);
4104 cmpv
= force_reg (SImode
, expand_simple_binop (SImode
, IOR
, cmp
, val
,
4105 NULL_RTX
, 1, OPTAB_DIRECT
));
4106 if (ac
.aligned
&& MEM_P (new))
4108 newv
= force_reg (SImode
, val
);
4109 store_bit_field (newv
, GET_MODE_BITSIZE (mode
), 0, SImode
, new);
4112 newv
= force_reg (SImode
, expand_simple_binop (SImode
, IOR
, new, val
,
4113 NULL_RTX
, 1, OPTAB_DIRECT
));
4115 /* Emit compare_and_swap pattern. */
4116 emit_insn (gen_sync_compare_and_swap_ccsi (res
, ac
.memsi
, cmpv
, newv
));
4118 /* Jump to end if we're done (likely?). */
4119 s390_emit_jump (csend
, s390_emit_compare (EQ
, cmpv
, ac
.memsi
));
4121 /* Check for changes outside mode. */
4122 resv
= expand_simple_binop (SImode
, AND
, res
, ac
.modemaski
,
4123 NULL_RTX
, 1, OPTAB_DIRECT
);
4124 cc
= s390_emit_compare (NE
, resv
, val
);
4125 emit_move_insn (val
, resv
);
4126 /* Loop internal if so. */
4127 s390_emit_jump (csloop
, cc
);
4131 /* Return the correct part of the bitfield. */
4132 convert_move (target
, expand_simple_binop (SImode
, LSHIFTRT
, res
, ac
.shift
,
4133 NULL_RTX
, 1, OPTAB_DIRECT
), 1);
4136 /* Expand an atomic operation CODE of mode MODE. MEM is the memory location
4137 and VAL the value to play with. If AFTER is true then store the the value
4138 MEM holds after the operation, if AFTER is false then store the value MEM
4139 holds before the operation. If TARGET is zero then discard that value, else
4140 store it to TARGET. */
4143 s390_expand_atomic (enum machine_mode mode
, enum rtx_code code
,
4144 rtx target
, rtx mem
, rtx val
, bool after
)
4146 struct alignment_context ac
;
4148 rtx
new = gen_reg_rtx (SImode
);
4149 rtx orig
= gen_reg_rtx (SImode
);
4150 rtx csloop
= gen_label_rtx ();
4152 gcc_assert (!target
|| register_operand (target
, VOIDmode
));
4153 gcc_assert (MEM_P (mem
));
4155 init_alignment_context (&ac
, mem
, mode
);
4157 /* Shift val to the correct bit positions.
4158 Preserve "icm", but prevent "ex icm". */
4159 if (!(ac
.aligned
&& code
== SET
&& MEM_P (val
)))
4160 val
= s390_expand_mask_and_shift (val
, mode
, ac
.shift
);
4162 /* Further preparation insns. */
4163 if (code
== PLUS
|| code
== MINUS
)
4164 emit_move_insn (orig
, val
);
4165 else if (code
== MULT
|| code
== AND
) /* val = "11..1<val>11..1" */
4166 val
= expand_simple_binop (SImode
, XOR
, val
, ac
.modemaski
,
4167 NULL_RTX
, 1, OPTAB_DIRECT
);
4169 /* Load full word. Subsequent loads are performed by CS. */
4170 cmp
= force_reg (SImode
, ac
.memsi
);
4172 /* Start CS loop. */
4173 emit_label (csloop
);
4174 emit_move_insn (new, cmp
);
4176 /* Patch new with val at correct position. */
4181 val
= expand_simple_binop (SImode
, code
, new, orig
,
4182 NULL_RTX
, 1, OPTAB_DIRECT
);
4183 val
= expand_simple_binop (SImode
, AND
, val
, ac
.modemask
,
4184 NULL_RTX
, 1, OPTAB_DIRECT
);
4187 if (ac
.aligned
&& MEM_P (val
))
4188 store_bit_field (new, GET_MODE_BITSIZE (mode
), 0, SImode
, val
);
4191 new = expand_simple_binop (SImode
, AND
, new, ac
.modemaski
,
4192 NULL_RTX
, 1, OPTAB_DIRECT
);
4193 new = expand_simple_binop (SImode
, IOR
, new, val
,
4194 NULL_RTX
, 1, OPTAB_DIRECT
);
4200 new = expand_simple_binop (SImode
, code
, new, val
,
4201 NULL_RTX
, 1, OPTAB_DIRECT
);
4203 case MULT
: /* NAND */
4204 new = expand_simple_binop (SImode
, XOR
, new, ac
.modemask
,
4205 NULL_RTX
, 1, OPTAB_DIRECT
);
4206 new = expand_simple_binop (SImode
, AND
, new, val
,
4207 NULL_RTX
, 1, OPTAB_DIRECT
);
4212 /* Emit compare_and_swap pattern. */
4213 emit_insn (gen_sync_compare_and_swap_ccsi (cmp
, ac
.memsi
, cmp
, new));
4215 /* Loop until swapped (unlikely?). */
4216 s390_emit_jump (csloop
, gen_rtx_fmt_ee (NE
, CCZ1mode
,
4217 gen_rtx_REG (CCZ1mode
, CC_REGNUM
),
4220 /* Return the correct part of the bitfield. */
4222 convert_move (target
, expand_simple_binop (SImode
, LSHIFTRT
,
4223 after
? new : cmp
, ac
.shift
,
4224 NULL_RTX
, 1, OPTAB_DIRECT
), 1);
4227 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
4228 We need to emit DTP-relative relocations. */
4230 static void s390_output_dwarf_dtprel (FILE *, int, rtx
) ATTRIBUTE_UNUSED
;
4233 s390_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
4238 fputs ("\t.long\t", file
);
4241 fputs ("\t.quad\t", file
);
4246 output_addr_const (file
, x
);
4247 fputs ("@DTPOFF", file
);
4250 /* In the name of slightly smaller debug output, and to cater to
4251 general assembler lossage, recognize various UNSPEC sequences
4252 and turn them back into a direct symbol reference. */
4255 s390_delegitimize_address (rtx orig_x
)
4259 if (GET_CODE (x
) != MEM
)
4263 if (GET_CODE (x
) == PLUS
4264 && GET_CODE (XEXP (x
, 1)) == CONST
4265 && GET_CODE (XEXP (x
, 0)) == REG
4266 && REGNO (XEXP (x
, 0)) == PIC_OFFSET_TABLE_REGNUM
)
4268 y
= XEXP (XEXP (x
, 1), 0);
4269 if (GET_CODE (y
) == UNSPEC
4270 && XINT (y
, 1) == UNSPEC_GOT
)
4271 return XVECEXP (y
, 0, 0);
4275 if (GET_CODE (x
) == CONST
)
4278 if (GET_CODE (y
) == UNSPEC
4279 && XINT (y
, 1) == UNSPEC_GOTENT
)
4280 return XVECEXP (y
, 0, 0);
4287 /* Output operand OP to stdio stream FILE.
4288 OP is an address (register + offset) which is not used to address data;
4289 instead the rightmost bits are interpreted as the value. */
4292 print_shift_count_operand (FILE *file
, rtx op
)
4294 HOST_WIDE_INT offset
;
4297 /* Extract base register and offset. */
4298 if (!s390_decompose_shift_count (op
, &base
, &offset
))
4304 gcc_assert (GET_CODE (base
) == REG
);
4305 gcc_assert (REGNO (base
) < FIRST_PSEUDO_REGISTER
);
4306 gcc_assert (REGNO_REG_CLASS (REGNO (base
)) == ADDR_REGS
);
4309 /* Offsets are constricted to twelve bits. */
4310 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
& ((1 << 12) - 1));
4312 fprintf (file
, "(%s)", reg_names
[REGNO (base
)]);
4315 /* See 'get_some_local_dynamic_name'. */
4318 get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
4322 if (GET_CODE (x
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (x
))
4324 x
= get_pool_constant (x
);
4325 return for_each_rtx (&x
, get_some_local_dynamic_name_1
, 0);
4328 if (GET_CODE (x
) == SYMBOL_REF
4329 && tls_symbolic_operand (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
4331 cfun
->machine
->some_ld_name
= XSTR (x
, 0);
4338 /* Locate some local-dynamic symbol still in use by this function
4339 so that we can print its name in local-dynamic base patterns. */
4342 get_some_local_dynamic_name (void)
4346 if (cfun
->machine
->some_ld_name
)
4347 return cfun
->machine
->some_ld_name
;
4349 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
4351 && for_each_rtx (&PATTERN (insn
), get_some_local_dynamic_name_1
, 0))
4352 return cfun
->machine
->some_ld_name
;
4357 /* Output machine-dependent UNSPECs occurring in address constant X
4358 in assembler syntax to stdio stream FILE. Returns true if the
4359 constant X could be recognized, false otherwise. */
4362 s390_output_addr_const_extra (FILE *file
, rtx x
)
4364 if (GET_CODE (x
) == UNSPEC
&& XVECLEN (x
, 0) == 1)
4365 switch (XINT (x
, 1))
4368 output_addr_const (file
, XVECEXP (x
, 0, 0));
4369 fprintf (file
, "@GOTENT");
4372 output_addr_const (file
, XVECEXP (x
, 0, 0));
4373 fprintf (file
, "@GOT");
4376 output_addr_const (file
, XVECEXP (x
, 0, 0));
4377 fprintf (file
, "@GOTOFF");
4380 output_addr_const (file
, XVECEXP (x
, 0, 0));
4381 fprintf (file
, "@PLT");
4384 output_addr_const (file
, XVECEXP (x
, 0, 0));
4385 fprintf (file
, "@PLTOFF");
4388 output_addr_const (file
, XVECEXP (x
, 0, 0));
4389 fprintf (file
, "@TLSGD");
4392 assemble_name (file
, get_some_local_dynamic_name ());
4393 fprintf (file
, "@TLSLDM");
4396 output_addr_const (file
, XVECEXP (x
, 0, 0));
4397 fprintf (file
, "@DTPOFF");
4400 output_addr_const (file
, XVECEXP (x
, 0, 0));
4401 fprintf (file
, "@NTPOFF");
4403 case UNSPEC_GOTNTPOFF
:
4404 output_addr_const (file
, XVECEXP (x
, 0, 0));
4405 fprintf (file
, "@GOTNTPOFF");
4407 case UNSPEC_INDNTPOFF
:
4408 output_addr_const (file
, XVECEXP (x
, 0, 0));
4409 fprintf (file
, "@INDNTPOFF");
4416 /* Output address operand ADDR in assembler syntax to
4417 stdio stream FILE. */
4420 print_operand_address (FILE *file
, rtx addr
)
4422 struct s390_address ad
;
4424 if (!s390_decompose_address (addr
, &ad
)
4425 || (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
4426 || (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
)))
4427 output_operand_lossage ("cannot decompose address");
4430 output_addr_const (file
, ad
.disp
);
4432 fprintf (file
, "0");
4434 if (ad
.base
&& ad
.indx
)
4435 fprintf (file
, "(%s,%s)", reg_names
[REGNO (ad
.indx
)],
4436 reg_names
[REGNO (ad
.base
)]);
4438 fprintf (file
, "(%s)", reg_names
[REGNO (ad
.base
)]);
4441 /* Output operand X in assembler syntax to stdio stream FILE.
4442 CODE specified the format flag. The following format flags
4445 'C': print opcode suffix for branch condition.
4446 'D': print opcode suffix for inverse branch condition.
4447 'J': print tls_load/tls_gdcall/tls_ldcall suffix
4448 'G': print the size of the operand in bytes.
4449 'O': print only the displacement of a memory reference.
4450 'R': print only the base register of a memory reference.
4451 'S': print S-type memory reference (base+displacement).
4452 'N': print the second word of a DImode operand.
4453 'M': print the second word of a TImode operand.
4454 'Y': print shift count operand.
4456 'b': print integer X as if it's an unsigned byte.
4457 'x': print integer X as if it's an unsigned halfword.
4458 'h': print integer X as if it's a signed halfword.
4459 'i': print the first nonzero HImode part of X.
4460 'j': print the first HImode part unequal to -1 of X.
4461 'k': print the first nonzero SImode part of X.
4462 'm': print the first SImode part unequal to -1 of X.
4463 'o': print integer X as if it's an unsigned 32bit word. */
4466 print_operand (FILE *file
, rtx x
, int code
)
4471 fprintf (file
, s390_branch_condition_mnemonic (x
, FALSE
));
4475 fprintf (file
, s390_branch_condition_mnemonic (x
, TRUE
));
4479 if (GET_CODE (x
) == SYMBOL_REF
)
4481 fprintf (file
, "%s", ":tls_load:");
4482 output_addr_const (file
, x
);
4484 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSGD
)
4486 fprintf (file
, "%s", ":tls_gdcall:");
4487 output_addr_const (file
, XVECEXP (x
, 0, 0));
4489 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSLDM
)
4491 fprintf (file
, "%s", ":tls_ldcall:");
4492 assemble_name (file
, get_some_local_dynamic_name ());
4499 fprintf (file
, "%u", GET_MODE_SIZE (GET_MODE (x
)));
4504 struct s390_address ad
;
4507 gcc_assert (GET_CODE (x
) == MEM
);
4508 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
4510 gcc_assert (!ad
.base
|| REG_OK_FOR_BASE_STRICT_P (ad
.base
));
4511 gcc_assert (!ad
.indx
);
4514 output_addr_const (file
, ad
.disp
);
4516 fprintf (file
, "0");
4522 struct s390_address ad
;
4525 gcc_assert (GET_CODE (x
) == MEM
);
4526 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
4528 gcc_assert (!ad
.base
|| REG_OK_FOR_BASE_STRICT_P (ad
.base
));
4529 gcc_assert (!ad
.indx
);
4532 fprintf (file
, "%s", reg_names
[REGNO (ad
.base
)]);
4534 fprintf (file
, "0");
4540 struct s390_address ad
;
4543 gcc_assert (GET_CODE (x
) == MEM
);
4544 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
4546 gcc_assert (!ad
.base
|| REG_OK_FOR_BASE_STRICT_P (ad
.base
));
4547 gcc_assert (!ad
.indx
);
4550 output_addr_const (file
, ad
.disp
);
4552 fprintf (file
, "0");
4555 fprintf (file
, "(%s)", reg_names
[REGNO (ad
.base
)]);
4560 if (GET_CODE (x
) == REG
)
4561 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
4562 else if (GET_CODE (x
) == MEM
)
4563 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 4));
4569 if (GET_CODE (x
) == REG
)
4570 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
4571 else if (GET_CODE (x
) == MEM
)
4572 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 8));
4578 print_shift_count_operand (file
, x
);
4582 switch (GET_CODE (x
))
4585 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
4589 output_address (XEXP (x
, 0));
4596 output_addr_const (file
, x
);
4601 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xff);
4602 else if (code
== 'x')
4603 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xffff);
4604 else if (code
== 'h')
4605 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((INTVAL (x
) & 0xffff) ^ 0x8000) - 0x8000);
4606 else if (code
== 'i')
4607 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
4608 s390_extract_part (x
, HImode
, 0));
4609 else if (code
== 'j')
4610 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
4611 s390_extract_part (x
, HImode
, -1));
4612 else if (code
== 'k')
4613 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
4614 s390_extract_part (x
, SImode
, 0));
4615 else if (code
== 'm')
4616 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
4617 s390_extract_part (x
, SImode
, -1));
4618 else if (code
== 'o')
4619 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xffffffff);
4621 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
4625 gcc_assert (GET_MODE (x
) == VOIDmode
);
4627 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xff);
4628 else if (code
== 'x')
4629 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xffff);
4630 else if (code
== 'h')
4631 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((CONST_DOUBLE_LOW (x
) & 0xffff) ^ 0x8000) - 0x8000);
4637 fatal_insn ("UNKNOWN in print_operand !?", x
);
4642 /* Target hook for assembling integer objects. We need to define it
4643 here to work a round a bug in some versions of GAS, which couldn't
4644 handle values smaller than INT_MIN when printed in decimal. */
4647 s390_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
4649 if (size
== 8 && aligned_p
4650 && GET_CODE (x
) == CONST_INT
&& INTVAL (x
) < INT_MIN
)
4652 fprintf (asm_out_file
, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX
"\n",
4656 return default_assemble_integer (x
, size
, aligned_p
);
4659 /* Returns true if register REGNO is used for forming
4660 a memory address in expression X. */
4663 reg_used_in_mem_p (int regno
, rtx x
)
4665 enum rtx_code code
= GET_CODE (x
);
4671 if (refers_to_regno_p (regno
, regno
+1,
4675 else if (code
== SET
4676 && GET_CODE (SET_DEST (x
)) == PC
)
4678 if (refers_to_regno_p (regno
, regno
+1,
4683 fmt
= GET_RTX_FORMAT (code
);
4684 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
4687 && reg_used_in_mem_p (regno
, XEXP (x
, i
)))
4690 else if (fmt
[i
] == 'E')
4691 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
4692 if (reg_used_in_mem_p (regno
, XVECEXP (x
, i
, j
)))
4698 /* Returns true if expression DEP_RTX sets an address register
4699 used by instruction INSN to address memory. */
4702 addr_generation_dependency_p (rtx dep_rtx
, rtx insn
)
4706 if (GET_CODE (dep_rtx
) == INSN
)
4707 dep_rtx
= PATTERN (dep_rtx
);
4709 if (GET_CODE (dep_rtx
) == SET
)
4711 target
= SET_DEST (dep_rtx
);
4712 if (GET_CODE (target
) == STRICT_LOW_PART
)
4713 target
= XEXP (target
, 0);
4714 while (GET_CODE (target
) == SUBREG
)
4715 target
= SUBREG_REG (target
);
4717 if (GET_CODE (target
) == REG
)
4719 int regno
= REGNO (target
);
4721 if (s390_safe_attr_type (insn
) == TYPE_LA
)
4723 pat
= PATTERN (insn
);
4724 if (GET_CODE (pat
) == PARALLEL
)
4726 gcc_assert (XVECLEN (pat
, 0) == 2);
4727 pat
= XVECEXP (pat
, 0, 0);
4729 gcc_assert (GET_CODE (pat
) == SET
);
4730 return refers_to_regno_p (regno
, regno
+1, SET_SRC (pat
), 0);
4732 else if (get_attr_atype (insn
) == ATYPE_AGEN
)
4733 return reg_used_in_mem_p (regno
, PATTERN (insn
));
4739 /* Return 1, if dep_insn sets register used in insn in the agen unit. */
4742 s390_agen_dep_p (rtx dep_insn
, rtx insn
)
4744 rtx dep_rtx
= PATTERN (dep_insn
);
4747 if (GET_CODE (dep_rtx
) == SET
4748 && addr_generation_dependency_p (dep_rtx
, insn
))
4750 else if (GET_CODE (dep_rtx
) == PARALLEL
)
4752 for (i
= 0; i
< XVECLEN (dep_rtx
, 0); i
++)
4754 if (addr_generation_dependency_p (XVECEXP (dep_rtx
, 0, i
), insn
))
4761 /* A C statement (sans semicolon) to update the integer scheduling priority
4762 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
4763 reduce the priority to execute INSN later. Do not define this macro if
4764 you do not need to adjust the scheduling priorities of insns.
4766 A STD instruction should be scheduled earlier,
4767 in order to use the bypass. */
4770 s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
4772 if (! INSN_P (insn
))
4775 if (s390_tune
!= PROCESSOR_2084_Z990
4776 && s390_tune
!= PROCESSOR_2094_Z9_109
)
4779 switch (s390_safe_attr_type (insn
))
4783 priority
= priority
<< 3;
4787 priority
= priority
<< 1;
4795 /* The number of instructions that can be issued per cycle. */
4798 s390_issue_rate (void)
4800 if (s390_tune
== PROCESSOR_2084_Z990
4801 || s390_tune
== PROCESSOR_2094_Z9_109
)
4807 s390_first_cycle_multipass_dfa_lookahead (void)
4813 /* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
4814 Fix up MEMs as required. */
4817 annotate_constant_pool_refs (rtx
*x
)
4822 gcc_assert (GET_CODE (*x
) != SYMBOL_REF
4823 || !CONSTANT_POOL_ADDRESS_P (*x
));
4825 /* Literal pool references can only occur inside a MEM ... */
4826 if (GET_CODE (*x
) == MEM
)
4828 rtx memref
= XEXP (*x
, 0);
4830 if (GET_CODE (memref
) == SYMBOL_REF
4831 && CONSTANT_POOL_ADDRESS_P (memref
))
4833 rtx base
= cfun
->machine
->base_reg
;
4834 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, memref
, base
),
4837 *x
= replace_equiv_address (*x
, addr
);
4841 if (GET_CODE (memref
) == CONST
4842 && GET_CODE (XEXP (memref
, 0)) == PLUS
4843 && GET_CODE (XEXP (XEXP (memref
, 0), 1)) == CONST_INT
4844 && GET_CODE (XEXP (XEXP (memref
, 0), 0)) == SYMBOL_REF
4845 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (memref
, 0), 0)))
4847 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (memref
, 0), 1));
4848 rtx sym
= XEXP (XEXP (memref
, 0), 0);
4849 rtx base
= cfun
->machine
->base_reg
;
4850 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
4853 *x
= replace_equiv_address (*x
, plus_constant (addr
, off
));
4858 /* ... or a load-address type pattern. */
4859 if (GET_CODE (*x
) == SET
)
4861 rtx addrref
= SET_SRC (*x
);
4863 if (GET_CODE (addrref
) == SYMBOL_REF
4864 && CONSTANT_POOL_ADDRESS_P (addrref
))
4866 rtx base
= cfun
->machine
->base_reg
;
4867 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, addrref
, base
),
4870 SET_SRC (*x
) = addr
;
4874 if (GET_CODE (addrref
) == CONST
4875 && GET_CODE (XEXP (addrref
, 0)) == PLUS
4876 && GET_CODE (XEXP (XEXP (addrref
, 0), 1)) == CONST_INT
4877 && GET_CODE (XEXP (XEXP (addrref
, 0), 0)) == SYMBOL_REF
4878 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (addrref
, 0), 0)))
4880 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (addrref
, 0), 1));
4881 rtx sym
= XEXP (XEXP (addrref
, 0), 0);
4882 rtx base
= cfun
->machine
->base_reg
;
4883 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
4886 SET_SRC (*x
) = plus_constant (addr
, off
);
4891 /* Annotate LTREL_BASE as well. */
4892 if (GET_CODE (*x
) == UNSPEC
4893 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
4895 rtx base
= cfun
->machine
->base_reg
;
4896 *x
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XVECEXP (*x
, 0, 0), base
),
4901 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
4902 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
4906 annotate_constant_pool_refs (&XEXP (*x
, i
));
4908 else if (fmt
[i
] == 'E')
4910 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
4911 annotate_constant_pool_refs (&XVECEXP (*x
, i
, j
));
4916 /* Split all branches that exceed the maximum distance.
4917 Returns true if this created a new literal pool entry. */
4920 s390_split_branches (void)
4922 rtx temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
4923 int new_literal
= 0, ret
;
4924 rtx insn
, pat
, tmp
, target
;
4927 /* We need correct insn addresses. */
4929 shorten_branches (get_insns ());
4931 /* Find all branches that exceed 64KB, and split them. */
4933 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
4935 if (GET_CODE (insn
) != JUMP_INSN
)
4938 pat
= PATTERN (insn
);
4939 if (GET_CODE (pat
) == PARALLEL
&& XVECLEN (pat
, 0) > 2)
4940 pat
= XVECEXP (pat
, 0, 0);
4941 if (GET_CODE (pat
) != SET
|| SET_DEST (pat
) != pc_rtx
)
4944 if (GET_CODE (SET_SRC (pat
)) == LABEL_REF
)
4946 label
= &SET_SRC (pat
);
4948 else if (GET_CODE (SET_SRC (pat
)) == IF_THEN_ELSE
)
4950 if (GET_CODE (XEXP (SET_SRC (pat
), 1)) == LABEL_REF
)
4951 label
= &XEXP (SET_SRC (pat
), 1);
4952 else if (GET_CODE (XEXP (SET_SRC (pat
), 2)) == LABEL_REF
)
4953 label
= &XEXP (SET_SRC (pat
), 2);
4960 if (get_attr_length (insn
) <= 4)
4963 /* We are going to use the return register as scratch register,
4964 make sure it will be saved/restored by the prologue/epilogue. */
4965 cfun_frame_layout
.save_return_addr_p
= 1;
4970 tmp
= force_const_mem (Pmode
, *label
);
4971 tmp
= emit_insn_before (gen_rtx_SET (Pmode
, temp_reg
, tmp
), insn
);
4972 INSN_ADDRESSES_NEW (tmp
, -1);
4973 annotate_constant_pool_refs (&PATTERN (tmp
));
4980 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, *label
),
4981 UNSPEC_LTREL_OFFSET
);
4982 target
= gen_rtx_CONST (Pmode
, target
);
4983 target
= force_const_mem (Pmode
, target
);
4984 tmp
= emit_insn_before (gen_rtx_SET (Pmode
, temp_reg
, target
), insn
);
4985 INSN_ADDRESSES_NEW (tmp
, -1);
4986 annotate_constant_pool_refs (&PATTERN (tmp
));
4988 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XEXP (target
, 0),
4989 cfun
->machine
->base_reg
),
4991 target
= gen_rtx_PLUS (Pmode
, temp_reg
, target
);
4994 ret
= validate_change (insn
, label
, target
, 0);
5002 /* Find an annotated literal pool symbol referenced in RTX X,
5003 and store it at REF. Will abort if X contains references to
5004 more than one such pool symbol; multiple references to the same
5005 symbol are allowed, however.
5007 The rtx pointed to by REF must be initialized to NULL_RTX
5008 by the caller before calling this routine. */
5011 find_constant_pool_ref (rtx x
, rtx
*ref
)
5016 /* Ignore LTREL_BASE references. */
5017 if (GET_CODE (x
) == UNSPEC
5018 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
5020 /* Likewise POOL_ENTRY insns. */
5021 if (GET_CODE (x
) == UNSPEC_VOLATILE
5022 && XINT (x
, 1) == UNSPECV_POOL_ENTRY
)
5025 gcc_assert (GET_CODE (x
) != SYMBOL_REF
5026 || !CONSTANT_POOL_ADDRESS_P (x
));
5028 if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_LTREF
)
5030 rtx sym
= XVECEXP (x
, 0, 0);
5031 gcc_assert (GET_CODE (sym
) == SYMBOL_REF
5032 && CONSTANT_POOL_ADDRESS_P (sym
));
5034 if (*ref
== NULL_RTX
)
5037 gcc_assert (*ref
== sym
);
5042 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
5043 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
5047 find_constant_pool_ref (XEXP (x
, i
), ref
);
5049 else if (fmt
[i
] == 'E')
5051 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
5052 find_constant_pool_ref (XVECEXP (x
, i
, j
), ref
);
5057 /* Replace every reference to the annotated literal pool
5058 symbol REF in X by its base plus OFFSET. */
5061 replace_constant_pool_ref (rtx
*x
, rtx ref
, rtx offset
)
5066 gcc_assert (*x
!= ref
);
5068 if (GET_CODE (*x
) == UNSPEC
5069 && XINT (*x
, 1) == UNSPEC_LTREF
5070 && XVECEXP (*x
, 0, 0) == ref
)
5072 *x
= gen_rtx_PLUS (Pmode
, XVECEXP (*x
, 0, 1), offset
);
5076 if (GET_CODE (*x
) == PLUS
5077 && GET_CODE (XEXP (*x
, 1)) == CONST_INT
5078 && GET_CODE (XEXP (*x
, 0)) == UNSPEC
5079 && XINT (XEXP (*x
, 0), 1) == UNSPEC_LTREF
5080 && XVECEXP (XEXP (*x
, 0), 0, 0) == ref
)
5082 rtx addr
= gen_rtx_PLUS (Pmode
, XVECEXP (XEXP (*x
, 0), 0, 1), offset
);
5083 *x
= plus_constant (addr
, INTVAL (XEXP (*x
, 1)));
5087 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
5088 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
5092 replace_constant_pool_ref (&XEXP (*x
, i
), ref
, offset
);
5094 else if (fmt
[i
] == 'E')
5096 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
5097 replace_constant_pool_ref (&XVECEXP (*x
, i
, j
), ref
, offset
);
5102 /* Check whether X contains an UNSPEC_LTREL_BASE.
5103 Return its constant pool symbol if found, NULL_RTX otherwise. */
5106 find_ltrel_base (rtx x
)
5111 if (GET_CODE (x
) == UNSPEC
5112 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
5113 return XVECEXP (x
, 0, 0);
5115 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
5116 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
5120 rtx fnd
= find_ltrel_base (XEXP (x
, i
));
5124 else if (fmt
[i
] == 'E')
5126 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
5128 rtx fnd
= find_ltrel_base (XVECEXP (x
, i
, j
));
5138 /* Replace any occurrence of UNSPEC_LTREL_BASE in X with its base. */
5141 replace_ltrel_base (rtx
*x
)
5146 if (GET_CODE (*x
) == UNSPEC
5147 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
5149 *x
= XVECEXP (*x
, 0, 1);
5153 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
5154 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
5158 replace_ltrel_base (&XEXP (*x
, i
));
5160 else if (fmt
[i
] == 'E')
5162 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
5163 replace_ltrel_base (&XVECEXP (*x
, i
, j
));
5169 /* We keep a list of constants which we have to add to internal
5170 constant tables in the middle of large functions. */
5172 #define NR_C_MODES 7
5173 enum machine_mode constant_modes
[NR_C_MODES
] =
5184 struct constant
*next
;
5189 struct constant_pool
5191 struct constant_pool
*next
;
5196 struct constant
*constants
[NR_C_MODES
];
5197 struct constant
*execute
;
5202 /* Allocate new constant_pool structure. */
5204 static struct constant_pool
*
5205 s390_alloc_pool (void)
5207 struct constant_pool
*pool
;
5210 pool
= (struct constant_pool
*) xmalloc (sizeof *pool
);
5212 for (i
= 0; i
< NR_C_MODES
; i
++)
5213 pool
->constants
[i
] = NULL
;
5215 pool
->execute
= NULL
;
5216 pool
->label
= gen_label_rtx ();
5217 pool
->first_insn
= NULL_RTX
;
5218 pool
->pool_insn
= NULL_RTX
;
5219 pool
->insns
= BITMAP_ALLOC (NULL
);
5225 /* Create new constant pool covering instructions starting at INSN
5226 and chain it to the end of POOL_LIST. */
5228 static struct constant_pool
*
5229 s390_start_pool (struct constant_pool
**pool_list
, rtx insn
)
5231 struct constant_pool
*pool
, **prev
;
5233 pool
= s390_alloc_pool ();
5234 pool
->first_insn
= insn
;
5236 for (prev
= pool_list
; *prev
; prev
= &(*prev
)->next
)
5243 /* End range of instructions covered by POOL at INSN and emit
5244 placeholder insn representing the pool. */
5247 s390_end_pool (struct constant_pool
*pool
, rtx insn
)
5249 rtx pool_size
= GEN_INT (pool
->size
+ 8 /* alignment slop */);
5252 insn
= get_last_insn ();
5254 pool
->pool_insn
= emit_insn_after (gen_pool (pool_size
), insn
);
5255 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
5258 /* Add INSN to the list of insns covered by POOL. */
5261 s390_add_pool_insn (struct constant_pool
*pool
, rtx insn
)
5263 bitmap_set_bit (pool
->insns
, INSN_UID (insn
));
5266 /* Return pool out of POOL_LIST that covers INSN. */
5268 static struct constant_pool
*
5269 s390_find_pool (struct constant_pool
*pool_list
, rtx insn
)
5271 struct constant_pool
*pool
;
5273 for (pool
= pool_list
; pool
; pool
= pool
->next
)
5274 if (bitmap_bit_p (pool
->insns
, INSN_UID (insn
)))
5280 /* Add constant VAL of mode MODE to the constant pool POOL. */
5283 s390_add_constant (struct constant_pool
*pool
, rtx val
, enum machine_mode mode
)
5288 for (i
= 0; i
< NR_C_MODES
; i
++)
5289 if (constant_modes
[i
] == mode
)
5291 gcc_assert (i
!= NR_C_MODES
);
5293 for (c
= pool
->constants
[i
]; c
!= NULL
; c
= c
->next
)
5294 if (rtx_equal_p (val
, c
->value
))
5299 c
= (struct constant
*) xmalloc (sizeof *c
);
5301 c
->label
= gen_label_rtx ();
5302 c
->next
= pool
->constants
[i
];
5303 pool
->constants
[i
] = c
;
5304 pool
->size
+= GET_MODE_SIZE (mode
);
5308 /* Find constant VAL of mode MODE in the constant pool POOL.
5309 Return an RTX describing the distance from the start of
5310 the pool to the location of the new constant. */
5313 s390_find_constant (struct constant_pool
*pool
, rtx val
,
5314 enum machine_mode mode
)
5320 for (i
= 0; i
< NR_C_MODES
; i
++)
5321 if (constant_modes
[i
] == mode
)
5323 gcc_assert (i
!= NR_C_MODES
);
5325 for (c
= pool
->constants
[i
]; c
!= NULL
; c
= c
->next
)
5326 if (rtx_equal_p (val
, c
->value
))
5331 offset
= gen_rtx_MINUS (Pmode
, gen_rtx_LABEL_REF (Pmode
, c
->label
),
5332 gen_rtx_LABEL_REF (Pmode
, pool
->label
));
5333 offset
= gen_rtx_CONST (Pmode
, offset
);
5337 /* Check whether INSN is an execute. Return the label_ref to its
5338 execute target template if so, NULL_RTX otherwise. */
5341 s390_execute_label (rtx insn
)
5343 if (GET_CODE (insn
) == INSN
5344 && GET_CODE (PATTERN (insn
)) == PARALLEL
5345 && GET_CODE (XVECEXP (PATTERN (insn
), 0, 0)) == UNSPEC
5346 && XINT (XVECEXP (PATTERN (insn
), 0, 0), 1) == UNSPEC_EXECUTE
)
5347 return XVECEXP (XVECEXP (PATTERN (insn
), 0, 0), 0, 2);
5352 /* Add execute target for INSN to the constant pool POOL. */
5355 s390_add_execute (struct constant_pool
*pool
, rtx insn
)
5359 for (c
= pool
->execute
; c
!= NULL
; c
= c
->next
)
5360 if (INSN_UID (insn
) == INSN_UID (c
->value
))
5365 c
= (struct constant
*) xmalloc (sizeof *c
);
5367 c
->label
= gen_label_rtx ();
5368 c
->next
= pool
->execute
;
5374 /* Find execute target for INSN in the constant pool POOL.
5375 Return an RTX describing the distance from the start of
5376 the pool to the location of the execute target. */
5379 s390_find_execute (struct constant_pool
*pool
, rtx insn
)
5384 for (c
= pool
->execute
; c
!= NULL
; c
= c
->next
)
5385 if (INSN_UID (insn
) == INSN_UID (c
->value
))
5390 offset
= gen_rtx_MINUS (Pmode
, gen_rtx_LABEL_REF (Pmode
, c
->label
),
5391 gen_rtx_LABEL_REF (Pmode
, pool
->label
));
5392 offset
= gen_rtx_CONST (Pmode
, offset
);
5396 /* For an execute INSN, extract the execute target template. */
5399 s390_execute_target (rtx insn
)
5401 rtx pattern
= PATTERN (insn
);
5402 gcc_assert (s390_execute_label (insn
));
5404 if (XVECLEN (pattern
, 0) == 2)
5406 pattern
= copy_rtx (XVECEXP (pattern
, 0, 1));
5410 rtvec vec
= rtvec_alloc (XVECLEN (pattern
, 0) - 1);
5413 for (i
= 0; i
< XVECLEN (pattern
, 0) - 1; i
++)
5414 RTVEC_ELT (vec
, i
) = copy_rtx (XVECEXP (pattern
, 0, i
+ 1));
5416 pattern
= gen_rtx_PARALLEL (VOIDmode
, vec
);
5422 /* Indicate that INSN cannot be duplicated. This is the case for
5423 execute insns that carry a unique label. */
5426 s390_cannot_copy_insn_p (rtx insn
)
5428 rtx label
= s390_execute_label (insn
);
5429 return label
&& label
!= const0_rtx
;
5432 /* Dump out the constants in POOL. If REMOTE_LABEL is true,
5433 do not emit the pool base label. */
5436 s390_dump_pool (struct constant_pool
*pool
, bool remote_label
)
5439 rtx insn
= pool
->pool_insn
;
5442 /* Switch to rodata section. */
5443 if (TARGET_CPU_ZARCH
)
5445 insn
= emit_insn_after (gen_pool_section_start (), insn
);
5446 INSN_ADDRESSES_NEW (insn
, -1);
5449 /* Ensure minimum pool alignment. */
5450 if (TARGET_CPU_ZARCH
)
5451 insn
= emit_insn_after (gen_pool_align (GEN_INT (8)), insn
);
5453 insn
= emit_insn_after (gen_pool_align (GEN_INT (4)), insn
);
5454 INSN_ADDRESSES_NEW (insn
, -1);
5456 /* Emit pool base label. */
5459 insn
= emit_label_after (pool
->label
, insn
);
5460 INSN_ADDRESSES_NEW (insn
, -1);
5463 /* Dump constants in descending alignment requirement order,
5464 ensuring proper alignment for every constant. */
5465 for (i
= 0; i
< NR_C_MODES
; i
++)
5466 for (c
= pool
->constants
[i
]; c
; c
= c
->next
)
5468 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
5469 rtx value
= c
->value
;
5470 if (GET_CODE (value
) == CONST
5471 && GET_CODE (XEXP (value
, 0)) == UNSPEC
5472 && XINT (XEXP (value
, 0), 1) == UNSPEC_LTREL_OFFSET
5473 && XVECLEN (XEXP (value
, 0), 0) == 1)
5475 value
= gen_rtx_MINUS (Pmode
, XVECEXP (XEXP (value
, 0), 0, 0),
5476 gen_rtx_LABEL_REF (VOIDmode
, pool
->label
));
5477 value
= gen_rtx_CONST (VOIDmode
, value
);
5480 insn
= emit_label_after (c
->label
, insn
);
5481 INSN_ADDRESSES_NEW (insn
, -1);
5483 value
= gen_rtx_UNSPEC_VOLATILE (constant_modes
[i
],
5484 gen_rtvec (1, value
),
5485 UNSPECV_POOL_ENTRY
);
5486 insn
= emit_insn_after (value
, insn
);
5487 INSN_ADDRESSES_NEW (insn
, -1);
5490 /* Ensure minimum alignment for instructions. */
5491 insn
= emit_insn_after (gen_pool_align (GEN_INT (2)), insn
);
5492 INSN_ADDRESSES_NEW (insn
, -1);
5494 /* Output in-pool execute template insns. */
5495 for (c
= pool
->execute
; c
; c
= c
->next
)
5497 insn
= emit_label_after (c
->label
, insn
);
5498 INSN_ADDRESSES_NEW (insn
, -1);
5500 insn
= emit_insn_after (s390_execute_target (c
->value
), insn
);
5501 INSN_ADDRESSES_NEW (insn
, -1);
5504 /* Switch back to previous section. */
5505 if (TARGET_CPU_ZARCH
)
5507 insn
= emit_insn_after (gen_pool_section_end (), insn
);
5508 INSN_ADDRESSES_NEW (insn
, -1);
5511 insn
= emit_barrier_after (insn
);
5512 INSN_ADDRESSES_NEW (insn
, -1);
5514 /* Remove placeholder insn. */
5515 remove_insn (pool
->pool_insn
);
5518 /* Free all memory used by POOL. */
5521 s390_free_pool (struct constant_pool
*pool
)
5523 struct constant
*c
, *next
;
5526 for (i
= 0; i
< NR_C_MODES
; i
++)
5527 for (c
= pool
->constants
[i
]; c
; c
= next
)
5533 for (c
= pool
->execute
; c
; c
= next
)
5539 BITMAP_FREE (pool
->insns
);
5544 /* Collect main literal pool. Return NULL on overflow. */
5546 static struct constant_pool
*
5547 s390_mainpool_start (void)
5549 struct constant_pool
*pool
;
5552 pool
= s390_alloc_pool ();
5554 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5556 if (GET_CODE (insn
) == INSN
5557 && GET_CODE (PATTERN (insn
)) == SET
5558 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC_VOLATILE
5559 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPECV_MAIN_POOL
)
5561 gcc_assert (!pool
->pool_insn
);
5562 pool
->pool_insn
= insn
;
5565 if (!TARGET_CPU_ZARCH
&& s390_execute_label (insn
))
5567 s390_add_execute (pool
, insn
);
5569 else if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5571 rtx pool_ref
= NULL_RTX
;
5572 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5575 rtx constant
= get_pool_constant (pool_ref
);
5576 enum machine_mode mode
= get_pool_mode (pool_ref
);
5577 s390_add_constant (pool
, constant
, mode
);
5582 gcc_assert (pool
->pool_insn
|| pool
->size
== 0);
5584 if (pool
->size
>= 4096)
5586 /* We're going to chunkify the pool, so remove the main
5587 pool placeholder insn. */
5588 remove_insn (pool
->pool_insn
);
5590 s390_free_pool (pool
);
5597 /* POOL holds the main literal pool as collected by s390_mainpool_start.
5598 Modify the current function to output the pool constants as well as
5599 the pool register setup instruction. */
5602 s390_mainpool_finish (struct constant_pool
*pool
)
5604 rtx base_reg
= cfun
->machine
->base_reg
;
5607 /* If the pool is empty, we're done. */
5608 if (pool
->size
== 0)
5610 /* We don't actually need a base register after all. */
5611 cfun
->machine
->base_reg
= NULL_RTX
;
5613 if (pool
->pool_insn
)
5614 remove_insn (pool
->pool_insn
);
5615 s390_free_pool (pool
);
5619 /* We need correct insn addresses. */
5620 shorten_branches (get_insns ());
5622 /* On zSeries, we use a LARL to load the pool register. The pool is
5623 located in the .rodata section, so we emit it after the function. */
5624 if (TARGET_CPU_ZARCH
)
5626 insn
= gen_main_base_64 (base_reg
, pool
->label
);
5627 insn
= emit_insn_after (insn
, pool
->pool_insn
);
5628 INSN_ADDRESSES_NEW (insn
, -1);
5629 remove_insn (pool
->pool_insn
);
5631 insn
= get_last_insn ();
5632 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
5633 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
5635 s390_dump_pool (pool
, 0);
5638 /* On S/390, if the total size of the function's code plus literal pool
5639 does not exceed 4096 bytes, we use BASR to set up a function base
5640 pointer, and emit the literal pool at the end of the function. */
5641 else if (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
5642 + pool
->size
+ 8 /* alignment slop */ < 4096)
5644 insn
= gen_main_base_31_small (base_reg
, pool
->label
);
5645 insn
= emit_insn_after (insn
, pool
->pool_insn
);
5646 INSN_ADDRESSES_NEW (insn
, -1);
5647 remove_insn (pool
->pool_insn
);
5649 insn
= emit_label_after (pool
->label
, insn
);
5650 INSN_ADDRESSES_NEW (insn
, -1);
5652 insn
= get_last_insn ();
5653 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
5654 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
5656 s390_dump_pool (pool
, 1);
5659 /* Otherwise, we emit an inline literal pool and use BASR to branch
5660 over it, setting up the pool register at the same time. */
5663 rtx pool_end
= gen_label_rtx ();
5665 insn
= gen_main_base_31_large (base_reg
, pool
->label
, pool_end
);
5666 insn
= emit_insn_after (insn
, pool
->pool_insn
);
5667 INSN_ADDRESSES_NEW (insn
, -1);
5668 remove_insn (pool
->pool_insn
);
5670 insn
= emit_label_after (pool
->label
, insn
);
5671 INSN_ADDRESSES_NEW (insn
, -1);
5673 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
5674 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
5676 insn
= emit_label_after (pool_end
, pool
->pool_insn
);
5677 INSN_ADDRESSES_NEW (insn
, -1);
5679 s390_dump_pool (pool
, 1);
5683 /* Replace all literal pool references. */
5685 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5688 replace_ltrel_base (&PATTERN (insn
));
5690 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5692 rtx addr
, pool_ref
= NULL_RTX
;
5693 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5696 if (s390_execute_label (insn
))
5697 addr
= s390_find_execute (pool
, insn
);
5699 addr
= s390_find_constant (pool
, get_pool_constant (pool_ref
),
5700 get_pool_mode (pool_ref
));
5702 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
5703 INSN_CODE (insn
) = -1;
5709 /* Free the pool. */
5710 s390_free_pool (pool
);
5713 /* POOL holds the main literal pool as collected by s390_mainpool_start.
5714 We have decided we cannot use this pool, so revert all changes
5715 to the current function that were done by s390_mainpool_start. */
5717 s390_mainpool_cancel (struct constant_pool
*pool
)
5719 /* We didn't actually change the instruction stream, so simply
5720 free the pool memory. */
5721 s390_free_pool (pool
);
5725 /* Chunkify the literal pool. */
5727 #define S390_POOL_CHUNK_MIN 0xc00
5728 #define S390_POOL_CHUNK_MAX 0xe00
5730 static struct constant_pool
*
5731 s390_chunkify_start (void)
5733 struct constant_pool
*curr_pool
= NULL
, *pool_list
= NULL
;
5736 rtx pending_ltrel
= NULL_RTX
;
5739 rtx (*gen_reload_base
) (rtx
, rtx
) =
5740 TARGET_CPU_ZARCH
? gen_reload_base_64
: gen_reload_base_31
;
5743 /* We need correct insn addresses. */
5745 shorten_branches (get_insns ());
5747 /* Scan all insns and move literals to pool chunks. */
5749 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5751 /* Check for pending LTREL_BASE. */
5754 rtx ltrel_base
= find_ltrel_base (PATTERN (insn
));
5757 gcc_assert (ltrel_base
== pending_ltrel
);
5758 pending_ltrel
= NULL_RTX
;
5762 if (!TARGET_CPU_ZARCH
&& s390_execute_label (insn
))
5765 curr_pool
= s390_start_pool (&pool_list
, insn
);
5767 s390_add_execute (curr_pool
, insn
);
5768 s390_add_pool_insn (curr_pool
, insn
);
5770 else if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5772 rtx pool_ref
= NULL_RTX
;
5773 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5776 rtx constant
= get_pool_constant (pool_ref
);
5777 enum machine_mode mode
= get_pool_mode (pool_ref
);
5780 curr_pool
= s390_start_pool (&pool_list
, insn
);
5782 s390_add_constant (curr_pool
, constant
, mode
);
5783 s390_add_pool_insn (curr_pool
, insn
);
5785 /* Don't split the pool chunk between a LTREL_OFFSET load
5786 and the corresponding LTREL_BASE. */
5787 if (GET_CODE (constant
) == CONST
5788 && GET_CODE (XEXP (constant
, 0)) == UNSPEC
5789 && XINT (XEXP (constant
, 0), 1) == UNSPEC_LTREL_OFFSET
)
5791 gcc_assert (!pending_ltrel
);
5792 pending_ltrel
= pool_ref
;
5797 if (GET_CODE (insn
) == JUMP_INSN
|| GET_CODE (insn
) == CODE_LABEL
)
5800 s390_add_pool_insn (curr_pool
, insn
);
5801 /* An LTREL_BASE must follow within the same basic block. */
5802 gcc_assert (!pending_ltrel
);
5806 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn
)
5807 || INSN_ADDRESSES (INSN_UID (insn
)) == -1)
5810 if (TARGET_CPU_ZARCH
)
5812 if (curr_pool
->size
< S390_POOL_CHUNK_MAX
)
5815 s390_end_pool (curr_pool
, NULL_RTX
);
5820 int chunk_size
= INSN_ADDRESSES (INSN_UID (insn
))
5821 - INSN_ADDRESSES (INSN_UID (curr_pool
->first_insn
))
5824 /* We will later have to insert base register reload insns.
5825 Those will have an effect on code size, which we need to
5826 consider here. This calculation makes rather pessimistic
5827 worst-case assumptions. */
5828 if (GET_CODE (insn
) == CODE_LABEL
)
5831 if (chunk_size
< S390_POOL_CHUNK_MIN
5832 && curr_pool
->size
< S390_POOL_CHUNK_MIN
)
5835 /* Pool chunks can only be inserted after BARRIERs ... */
5836 if (GET_CODE (insn
) == BARRIER
)
5838 s390_end_pool (curr_pool
, insn
);
5843 /* ... so if we don't find one in time, create one. */
5844 else if ((chunk_size
> S390_POOL_CHUNK_MAX
5845 || curr_pool
->size
> S390_POOL_CHUNK_MAX
))
5847 rtx label
, jump
, barrier
;
5849 /* We can insert the barrier only after a 'real' insn. */
5850 if (GET_CODE (insn
) != INSN
&& GET_CODE (insn
) != CALL_INSN
)
5852 if (get_attr_length (insn
) == 0)
5855 /* Don't separate LTREL_BASE from the corresponding
5856 LTREL_OFFSET load. */
5860 label
= gen_label_rtx ();
5861 jump
= emit_jump_insn_after (gen_jump (label
), insn
);
5862 barrier
= emit_barrier_after (jump
);
5863 insn
= emit_label_after (label
, barrier
);
5864 JUMP_LABEL (jump
) = label
;
5865 LABEL_NUSES (label
) = 1;
5867 INSN_ADDRESSES_NEW (jump
, -1);
5868 INSN_ADDRESSES_NEW (barrier
, -1);
5869 INSN_ADDRESSES_NEW (insn
, -1);
5871 s390_end_pool (curr_pool
, barrier
);
5879 s390_end_pool (curr_pool
, NULL_RTX
);
5880 gcc_assert (!pending_ltrel
);
5882 /* Find all labels that are branched into
5883 from an insn belonging to a different chunk. */
5885 far_labels
= BITMAP_ALLOC (NULL
);
5887 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5889 /* Labels marked with LABEL_PRESERVE_P can be target
5890 of non-local jumps, so we have to mark them.
5891 The same holds for named labels.
5893 Don't do that, however, if it is the label before
5896 if (GET_CODE (insn
) == CODE_LABEL
5897 && (LABEL_PRESERVE_P (insn
) || LABEL_NAME (insn
)))
5899 rtx vec_insn
= next_real_insn (insn
);
5900 rtx vec_pat
= vec_insn
&& GET_CODE (vec_insn
) == JUMP_INSN
?
5901 PATTERN (vec_insn
) : NULL_RTX
;
5903 || !(GET_CODE (vec_pat
) == ADDR_VEC
5904 || GET_CODE (vec_pat
) == ADDR_DIFF_VEC
))
5905 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (insn
));
5908 /* If we have a direct jump (conditional or unconditional)
5909 or a casesi jump, check all potential targets. */
5910 else if (GET_CODE (insn
) == JUMP_INSN
)
5912 rtx pat
= PATTERN (insn
);
5913 if (GET_CODE (pat
) == PARALLEL
&& XVECLEN (pat
, 0) > 2)
5914 pat
= XVECEXP (pat
, 0, 0);
5916 if (GET_CODE (pat
) == SET
)
5918 rtx label
= JUMP_LABEL (insn
);
5921 if (s390_find_pool (pool_list
, label
)
5922 != s390_find_pool (pool_list
, insn
))
5923 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
5926 else if (GET_CODE (pat
) == PARALLEL
5927 && XVECLEN (pat
, 0) == 2
5928 && GET_CODE (XVECEXP (pat
, 0, 0)) == SET
5929 && GET_CODE (XVECEXP (pat
, 0, 1)) == USE
5930 && GET_CODE (XEXP (XVECEXP (pat
, 0, 1), 0)) == LABEL_REF
)
5932 /* Find the jump table used by this casesi jump. */
5933 rtx vec_label
= XEXP (XEXP (XVECEXP (pat
, 0, 1), 0), 0);
5934 rtx vec_insn
= next_real_insn (vec_label
);
5935 rtx vec_pat
= vec_insn
&& GET_CODE (vec_insn
) == JUMP_INSN
?
5936 PATTERN (vec_insn
) : NULL_RTX
;
5938 && (GET_CODE (vec_pat
) == ADDR_VEC
5939 || GET_CODE (vec_pat
) == ADDR_DIFF_VEC
))
5941 int i
, diff_p
= GET_CODE (vec_pat
) == ADDR_DIFF_VEC
;
5943 for (i
= 0; i
< XVECLEN (vec_pat
, diff_p
); i
++)
5945 rtx label
= XEXP (XVECEXP (vec_pat
, diff_p
, i
), 0);
5947 if (s390_find_pool (pool_list
, label
)
5948 != s390_find_pool (pool_list
, insn
))
5949 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
5956 /* Insert base register reload insns before every pool. */
5958 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
5960 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
5962 rtx insn
= curr_pool
->first_insn
;
5963 INSN_ADDRESSES_NEW (emit_insn_before (new_insn
, insn
), -1);
5966 /* Insert base register reload insns at every far label. */
5968 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5969 if (GET_CODE (insn
) == CODE_LABEL
5970 && bitmap_bit_p (far_labels
, CODE_LABEL_NUMBER (insn
)))
5972 struct constant_pool
*pool
= s390_find_pool (pool_list
, insn
);
5975 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
5977 INSN_ADDRESSES_NEW (emit_insn_after (new_insn
, insn
), -1);
5982 BITMAP_FREE (far_labels
);
5985 /* Recompute insn addresses. */
5987 init_insn_lengths ();
5988 shorten_branches (get_insns ());
5993 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
5994 After we have decided to use this list, finish implementing
5995 all changes to the current function as required. */
5998 s390_chunkify_finish (struct constant_pool
*pool_list
)
6000 struct constant_pool
*curr_pool
= NULL
;
6004 /* Replace all literal pool references. */
6006 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6009 replace_ltrel_base (&PATTERN (insn
));
6011 curr_pool
= s390_find_pool (pool_list
, insn
);
6015 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
6017 rtx addr
, pool_ref
= NULL_RTX
;
6018 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
6021 if (s390_execute_label (insn
))
6022 addr
= s390_find_execute (curr_pool
, insn
);
6024 addr
= s390_find_constant (curr_pool
,
6025 get_pool_constant (pool_ref
),
6026 get_pool_mode (pool_ref
));
6028 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
6029 INSN_CODE (insn
) = -1;
6034 /* Dump out all literal pools. */
6036 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
6037 s390_dump_pool (curr_pool
, 0);
6039 /* Free pool list. */
6043 struct constant_pool
*next
= pool_list
->next
;
6044 s390_free_pool (pool_list
);
6049 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
6050 We have decided we cannot use this list, so revert all changes
6051 to the current function that were done by s390_chunkify_start. */
6054 s390_chunkify_cancel (struct constant_pool
*pool_list
)
6056 struct constant_pool
*curr_pool
= NULL
;
6059 /* Remove all pool placeholder insns. */
6061 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
6063 /* Did we insert an extra barrier? Remove it. */
6064 rtx barrier
= PREV_INSN (curr_pool
->pool_insn
);
6065 rtx jump
= barrier
? PREV_INSN (barrier
) : NULL_RTX
;
6066 rtx label
= NEXT_INSN (curr_pool
->pool_insn
);
6068 if (jump
&& GET_CODE (jump
) == JUMP_INSN
6069 && barrier
&& GET_CODE (barrier
) == BARRIER
6070 && label
&& GET_CODE (label
) == CODE_LABEL
6071 && GET_CODE (PATTERN (jump
)) == SET
6072 && SET_DEST (PATTERN (jump
)) == pc_rtx
6073 && GET_CODE (SET_SRC (PATTERN (jump
))) == LABEL_REF
6074 && XEXP (SET_SRC (PATTERN (jump
)), 0) == label
)
6077 remove_insn (barrier
);
6078 remove_insn (label
);
6081 remove_insn (curr_pool
->pool_insn
);
6084 /* Remove all base register reload insns. */
6086 for (insn
= get_insns (); insn
; )
6088 rtx next_insn
= NEXT_INSN (insn
);
6090 if (GET_CODE (insn
) == INSN
6091 && GET_CODE (PATTERN (insn
)) == SET
6092 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC
6093 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPEC_RELOAD_BASE
)
6099 /* Free pool list. */
6103 struct constant_pool
*next
= pool_list
->next
;
6104 s390_free_pool (pool_list
);
6110 /* Output the constant pool entry EXP in mode MODE with alignment ALIGN. */
6113 s390_output_pool_entry (rtx exp
, enum machine_mode mode
, unsigned int align
)
6117 switch (GET_MODE_CLASS (mode
))
6120 gcc_assert (GET_CODE (exp
) == CONST_DOUBLE
);
6122 REAL_VALUE_FROM_CONST_DOUBLE (r
, exp
);
6123 assemble_real (r
, mode
, align
);
6127 assemble_integer (exp
, GET_MODE_SIZE (mode
), align
, 1);
6136 /* Return an RTL expression representing the value of the return address
6137 for the frame COUNT steps up from the current frame. FRAME is the
6138 frame pointer of that frame. */
6141 s390_return_addr_rtx (int count
, rtx frame ATTRIBUTE_UNUSED
)
6146 /* Without backchain, we fail for all but the current frame. */
6148 if (!TARGET_BACKCHAIN
&& count
> 0)
6151 /* For the current frame, we need to make sure the initial
6152 value of RETURN_REGNUM is actually saved. */
6156 /* On non-z architectures branch splitting could overwrite r14. */
6157 if (TARGET_CPU_ZARCH
)
6158 return get_hard_reg_initial_val (Pmode
, RETURN_REGNUM
);
6161 cfun_frame_layout
.save_return_addr_p
= true;
6162 return gen_rtx_MEM (Pmode
, return_address_pointer_rtx
);
6166 if (TARGET_PACKED_STACK
)
6167 offset
= -2 * UNITS_PER_WORD
;
6169 offset
= RETURN_REGNUM
* UNITS_PER_WORD
;
6171 addr
= plus_constant (frame
, offset
);
6172 addr
= memory_address (Pmode
, addr
);
6173 return gen_rtx_MEM (Pmode
, addr
);
6176 /* Return an RTL expression representing the back chain stored in
6177 the current stack frame. */
6180 s390_back_chain_rtx (void)
6184 gcc_assert (TARGET_BACKCHAIN
);
6186 if (TARGET_PACKED_STACK
)
6187 chain
= plus_constant (stack_pointer_rtx
,
6188 STACK_POINTER_OFFSET
- UNITS_PER_WORD
);
6190 chain
= stack_pointer_rtx
;
6192 chain
= gen_rtx_MEM (Pmode
, chain
);
6196 /* Find first call clobbered register unused in a function.
6197 This could be used as base register in a leaf function
6198 or for holding the return address before epilogue. */
6201 find_unused_clobbered_reg (void)
6204 for (i
= 0; i
< 6; i
++)
6205 if (!regs_ever_live
[i
])
6211 /* Helper function for s390_regs_ever_clobbered. Sets the fields in DATA for all
6212 clobbered hard regs in SETREG. */
6215 s390_reg_clobbered_rtx (rtx setreg
, rtx set_insn ATTRIBUTE_UNUSED
, void *data
)
6217 int *regs_ever_clobbered
= (int *)data
;
6218 unsigned int i
, regno
;
6219 enum machine_mode mode
= GET_MODE (setreg
);
6221 if (GET_CODE (setreg
) == SUBREG
)
6223 rtx inner
= SUBREG_REG (setreg
);
6224 if (!GENERAL_REG_P (inner
))
6226 regno
= subreg_regno (setreg
);
6228 else if (GENERAL_REG_P (setreg
))
6229 regno
= REGNO (setreg
);
6234 i
< regno
+ HARD_REGNO_NREGS (regno
, mode
);
6236 regs_ever_clobbered
[i
] = 1;
6239 /* Walks through all basic blocks of the current function looking
6240 for clobbered hard regs using s390_reg_clobbered_rtx. The fields
6241 of the passed integer array REGS_EVER_CLOBBERED are set to one for
6242 each of those regs. */
6245 s390_regs_ever_clobbered (int *regs_ever_clobbered
)
6251 memset (regs_ever_clobbered
, 0, 16 * sizeof (int));
6253 /* For non-leaf functions we have to consider all call clobbered regs to be
6255 if (!current_function_is_leaf
)
6257 for (i
= 0; i
< 16; i
++)
6258 regs_ever_clobbered
[i
] = call_really_used_regs
[i
];
6261 /* Make the "magic" eh_return registers live if necessary. For regs_ever_live
6262 this work is done by liveness analysis (mark_regs_live_at_end).
6263 Special care is needed for functions containing landing pads. Landing pads
6264 may use the eh registers, but the code which sets these registers is not
6265 contained in that function. Hence s390_regs_ever_clobbered is not able to
6266 deal with this automatically. */
6267 if (current_function_calls_eh_return
|| cfun
->machine
->has_landing_pad_p
)
6268 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; i
++)
6269 if (current_function_calls_eh_return
6270 || (cfun
->machine
->has_landing_pad_p
6271 && regs_ever_live
[EH_RETURN_DATA_REGNO (i
)]))
6272 regs_ever_clobbered
[EH_RETURN_DATA_REGNO (i
)] = 1;
6274 /* For nonlocal gotos all call-saved registers have to be saved.
6275 This flag is also set for the unwinding code in libgcc.
6276 See expand_builtin_unwind_init. For regs_ever_live this is done by
6278 if (current_function_has_nonlocal_label
)
6279 for (i
= 0; i
< 16; i
++)
6280 if (!call_really_used_regs
[i
])
6281 regs_ever_clobbered
[i
] = 1;
6283 FOR_EACH_BB (cur_bb
)
6285 FOR_BB_INSNS (cur_bb
, cur_insn
)
6287 if (INSN_P (cur_insn
))
6288 note_stores (PATTERN (cur_insn
),
6289 s390_reg_clobbered_rtx
,
6290 regs_ever_clobbered
);
6295 /* Determine the frame area which actually has to be accessed
6296 in the function epilogue. The values are stored at the
6297 given pointers AREA_BOTTOM (address of the lowest used stack
6298 address) and AREA_TOP (address of the first item which does
6299 not belong to the stack frame). */
6302 s390_frame_area (int *area_bottom
, int *area_top
)
6310 if (cfun_frame_layout
.first_restore_gpr
!= -1)
6312 b
= (cfun_frame_layout
.gprs_offset
6313 + cfun_frame_layout
.first_restore_gpr
* UNITS_PER_WORD
);
6314 t
= b
+ (cfun_frame_layout
.last_restore_gpr
6315 - cfun_frame_layout
.first_restore_gpr
+ 1) * UNITS_PER_WORD
;
6318 if (TARGET_64BIT
&& cfun_save_high_fprs_p
)
6320 b
= MIN (b
, cfun_frame_layout
.f8_offset
);
6321 t
= MAX (t
, (cfun_frame_layout
.f8_offset
6322 + cfun_frame_layout
.high_fprs
* 8));
6326 for (i
= 2; i
< 4; i
++)
6327 if (cfun_fpr_bit_p (i
))
6329 b
= MIN (b
, cfun_frame_layout
.f4_offset
+ (i
- 2) * 8);
6330 t
= MAX (t
, cfun_frame_layout
.f4_offset
+ (i
- 1) * 8);
6337 /* Fill cfun->machine with info about register usage of current function.
6338 Return in CLOBBERED_REGS which GPRs are currently considered set. */
6341 s390_register_info (int clobbered_regs
[])
6345 /* fprs 8 - 15 are call saved for 64 Bit ABI. */
6346 cfun_frame_layout
.fpr_bitmap
= 0;
6347 cfun_frame_layout
.high_fprs
= 0;
6349 for (i
= 24; i
< 32; i
++)
6350 if (regs_ever_live
[i
] && !global_regs
[i
])
6352 cfun_set_fpr_bit (i
- 16);
6353 cfun_frame_layout
.high_fprs
++;
6356 /* Find first and last gpr to be saved. We trust regs_ever_live
6357 data, except that we don't save and restore global registers.
6359 Also, all registers with special meaning to the compiler need
6360 to be handled extra. */
6362 s390_regs_ever_clobbered (clobbered_regs
);
6364 for (i
= 0; i
< 16; i
++)
6365 clobbered_regs
[i
] = clobbered_regs
[i
] && !global_regs
[i
] && !fixed_regs
[i
];
6367 if (frame_pointer_needed
)
6368 clobbered_regs
[HARD_FRAME_POINTER_REGNUM
] = 1;
6371 clobbered_regs
[PIC_OFFSET_TABLE_REGNUM
]
6372 |= regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
];
6374 clobbered_regs
[BASE_REGNUM
]
6375 |= (cfun
->machine
->base_reg
6376 && REGNO (cfun
->machine
->base_reg
) == BASE_REGNUM
);
6378 clobbered_regs
[RETURN_REGNUM
]
6379 |= (!current_function_is_leaf
6380 || TARGET_TPF_PROFILING
6381 || cfun
->machine
->split_branches_pending_p
6382 || cfun_frame_layout
.save_return_addr_p
6383 || current_function_calls_eh_return
6384 || current_function_stdarg
);
6386 clobbered_regs
[STACK_POINTER_REGNUM
]
6387 |= (!current_function_is_leaf
6388 || TARGET_TPF_PROFILING
6389 || cfun_save_high_fprs_p
6390 || get_frame_size () > 0
6391 || current_function_calls_alloca
6392 || current_function_stdarg
);
6394 for (i
= 6; i
< 16; i
++)
6395 if (regs_ever_live
[i
] || clobbered_regs
[i
])
6397 for (j
= 15; j
> i
; j
--)
6398 if (regs_ever_live
[j
] || clobbered_regs
[j
])
6403 /* Nothing to save/restore. */
6404 cfun_frame_layout
.first_save_gpr_slot
= -1;
6405 cfun_frame_layout
.last_save_gpr_slot
= -1;
6406 cfun_frame_layout
.first_save_gpr
= -1;
6407 cfun_frame_layout
.first_restore_gpr
= -1;
6408 cfun_frame_layout
.last_save_gpr
= -1;
6409 cfun_frame_layout
.last_restore_gpr
= -1;
6413 /* Save slots for gprs from i to j. */
6414 cfun_frame_layout
.first_save_gpr_slot
= i
;
6415 cfun_frame_layout
.last_save_gpr_slot
= j
;
6417 for (i
= cfun_frame_layout
.first_save_gpr_slot
;
6418 i
< cfun_frame_layout
.last_save_gpr_slot
+ 1;
6420 if (clobbered_regs
[i
])
6423 for (j
= cfun_frame_layout
.last_save_gpr_slot
; j
> i
; j
--)
6424 if (clobbered_regs
[j
])
6427 if (i
== cfun_frame_layout
.last_save_gpr_slot
+ 1)
6429 /* Nothing to save/restore. */
6430 cfun_frame_layout
.first_save_gpr
= -1;
6431 cfun_frame_layout
.first_restore_gpr
= -1;
6432 cfun_frame_layout
.last_save_gpr
= -1;
6433 cfun_frame_layout
.last_restore_gpr
= -1;
6437 /* Save / Restore from gpr i to j. */
6438 cfun_frame_layout
.first_save_gpr
= i
;
6439 cfun_frame_layout
.first_restore_gpr
= i
;
6440 cfun_frame_layout
.last_save_gpr
= j
;
6441 cfun_frame_layout
.last_restore_gpr
= j
;
6445 if (current_function_stdarg
)
6447 /* Varargs functions need to save gprs 2 to 6. */
6448 if (cfun
->va_list_gpr_size
6449 && current_function_args_info
.gprs
< GP_ARG_NUM_REG
)
6451 int min_gpr
= current_function_args_info
.gprs
;
6452 int max_gpr
= min_gpr
+ cfun
->va_list_gpr_size
;
6453 if (max_gpr
> GP_ARG_NUM_REG
)
6454 max_gpr
= GP_ARG_NUM_REG
;
6456 if (cfun_frame_layout
.first_save_gpr
== -1
6457 || cfun_frame_layout
.first_save_gpr
> 2 + min_gpr
)
6459 cfun_frame_layout
.first_save_gpr
= 2 + min_gpr
;
6460 cfun_frame_layout
.first_save_gpr_slot
= 2 + min_gpr
;
6463 if (cfun_frame_layout
.last_save_gpr
== -1
6464 || cfun_frame_layout
.last_save_gpr
< 2 + max_gpr
- 1)
6466 cfun_frame_layout
.last_save_gpr
= 2 + max_gpr
- 1;
6467 cfun_frame_layout
.last_save_gpr_slot
= 2 + max_gpr
- 1;
6471 /* Mark f0, f2 for 31 bit and f0-f4 for 64 bit to be saved. */
6472 if (TARGET_HARD_FLOAT
&& cfun
->va_list_fpr_size
6473 && current_function_args_info
.fprs
< FP_ARG_NUM_REG
)
6475 int min_fpr
= current_function_args_info
.fprs
;
6476 int max_fpr
= min_fpr
+ cfun
->va_list_fpr_size
;
6477 if (max_fpr
> FP_ARG_NUM_REG
)
6478 max_fpr
= FP_ARG_NUM_REG
;
6480 /* ??? This is currently required to ensure proper location
6481 of the fpr save slots within the va_list save area. */
6482 if (TARGET_PACKED_STACK
)
6485 for (i
= min_fpr
; i
< max_fpr
; i
++)
6486 cfun_set_fpr_bit (i
);
6491 for (i
= 2; i
< 4; i
++)
6492 if (regs_ever_live
[i
+ 16] && !global_regs
[i
+ 16])
6493 cfun_set_fpr_bit (i
);
6496 /* Fill cfun->machine with info about frame of current function. */
6499 s390_frame_info (void)
6503 cfun_frame_layout
.frame_size
= get_frame_size ();
6504 if (!TARGET_64BIT
&& cfun_frame_layout
.frame_size
> 0x7fff0000)
6505 fatal_error ("total size of local variables exceeds architecture limit");
6507 if (!TARGET_PACKED_STACK
)
6509 cfun_frame_layout
.backchain_offset
= 0;
6510 cfun_frame_layout
.f0_offset
= 16 * UNITS_PER_WORD
;
6511 cfun_frame_layout
.f4_offset
= cfun_frame_layout
.f0_offset
+ 2 * 8;
6512 cfun_frame_layout
.f8_offset
= -cfun_frame_layout
.high_fprs
* 8;
6513 cfun_frame_layout
.gprs_offset
= (cfun_frame_layout
.first_save_gpr_slot
6516 else if (TARGET_BACKCHAIN
) /* kernel stack layout */
6518 cfun_frame_layout
.backchain_offset
= (STACK_POINTER_OFFSET
6520 cfun_frame_layout
.gprs_offset
6521 = (cfun_frame_layout
.backchain_offset
6522 - (STACK_POINTER_REGNUM
- cfun_frame_layout
.first_save_gpr_slot
+ 1)
6527 cfun_frame_layout
.f4_offset
6528 = (cfun_frame_layout
.gprs_offset
6529 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6531 cfun_frame_layout
.f0_offset
6532 = (cfun_frame_layout
.f4_offset
6533 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6537 /* On 31 bit we have to care about alignment of the
6538 floating point regs to provide fastest access. */
6539 cfun_frame_layout
.f0_offset
6540 = ((cfun_frame_layout
.gprs_offset
6541 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1))
6542 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6544 cfun_frame_layout
.f4_offset
6545 = (cfun_frame_layout
.f0_offset
6546 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6549 else /* no backchain */
6551 cfun_frame_layout
.f4_offset
6552 = (STACK_POINTER_OFFSET
6553 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6555 cfun_frame_layout
.f0_offset
6556 = (cfun_frame_layout
.f4_offset
6557 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6559 cfun_frame_layout
.gprs_offset
6560 = cfun_frame_layout
.f0_offset
- cfun_gprs_save_area_size
;
6563 if (current_function_is_leaf
6564 && !TARGET_TPF_PROFILING
6565 && cfun_frame_layout
.frame_size
== 0
6566 && !cfun_save_high_fprs_p
6567 && !current_function_calls_alloca
6568 && !current_function_stdarg
)
6571 if (!TARGET_PACKED_STACK
)
6572 cfun_frame_layout
.frame_size
+= (STACK_POINTER_OFFSET
6573 + current_function_outgoing_args_size
6574 + cfun_frame_layout
.high_fprs
* 8);
6577 if (TARGET_BACKCHAIN
)
6578 cfun_frame_layout
.frame_size
+= UNITS_PER_WORD
;
6580 /* No alignment trouble here because f8-f15 are only saved under
6582 cfun_frame_layout
.f8_offset
= (MIN (MIN (cfun_frame_layout
.f0_offset
,
6583 cfun_frame_layout
.f4_offset
),
6584 cfun_frame_layout
.gprs_offset
)
6585 - cfun_frame_layout
.high_fprs
* 8);
6587 cfun_frame_layout
.frame_size
+= cfun_frame_layout
.high_fprs
* 8;
6589 for (i
= 0; i
< 8; i
++)
6590 if (cfun_fpr_bit_p (i
))
6591 cfun_frame_layout
.frame_size
+= 8;
6593 cfun_frame_layout
.frame_size
+= cfun_gprs_save_area_size
;
6595 /* If under 31 bit an odd number of gprs has to be saved we have to adjust
6596 the frame size to sustain 8 byte alignment of stack frames. */
6597 cfun_frame_layout
.frame_size
= ((cfun_frame_layout
.frame_size
+
6598 STACK_BOUNDARY
/ BITS_PER_UNIT
- 1)
6599 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1));
6601 cfun_frame_layout
.frame_size
+= current_function_outgoing_args_size
;
6605 /* Generate frame layout. Fills in register and frame data for the current
6606 function in cfun->machine. This routine can be called multiple times;
6607 it will re-do the complete frame layout every time. */
6610 s390_init_frame_layout (void)
6612 HOST_WIDE_INT frame_size
;
6614 int clobbered_regs
[16];
6616 /* On S/390 machines, we may need to perform branch splitting, which
6617 will require both base and return address register. We have no
6618 choice but to assume we're going to need them until right at the
6619 end of the machine dependent reorg phase. */
6620 if (!TARGET_CPU_ZARCH
)
6621 cfun
->machine
->split_branches_pending_p
= true;
6625 frame_size
= cfun_frame_layout
.frame_size
;
6627 /* Try to predict whether we'll need the base register. */
6628 base_used
= cfun
->machine
->split_branches_pending_p
6629 || current_function_uses_const_pool
6630 || (!DISP_IN_RANGE (-frame_size
)
6631 && !CONST_OK_FOR_K (-frame_size
));
6633 /* Decide which register to use as literal pool base. In small
6634 leaf functions, try to use an unused call-clobbered register
6635 as base register to avoid save/restore overhead. */
6637 cfun
->machine
->base_reg
= NULL_RTX
;
6638 else if (current_function_is_leaf
&& !regs_ever_live
[5])
6639 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, 5);
6641 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
6643 s390_register_info (clobbered_regs
);
6646 while (frame_size
!= cfun_frame_layout
.frame_size
);
6649 /* Update frame layout. Recompute actual register save data based on
6650 current info and update regs_ever_live for the special registers.
6651 May be called multiple times, but may never cause *more* registers
6652 to be saved than s390_init_frame_layout allocated room for. */
6655 s390_update_frame_layout (void)
6657 int clobbered_regs
[16];
6659 s390_register_info (clobbered_regs
);
6661 regs_ever_live
[BASE_REGNUM
] = clobbered_regs
[BASE_REGNUM
];
6662 regs_ever_live
[RETURN_REGNUM
] = clobbered_regs
[RETURN_REGNUM
];
6663 regs_ever_live
[STACK_POINTER_REGNUM
] = clobbered_regs
[STACK_POINTER_REGNUM
];
6665 if (cfun
->machine
->base_reg
)
6666 regs_ever_live
[REGNO (cfun
->machine
->base_reg
)] = 1;
6669 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
6672 s390_hard_regno_rename_ok (unsigned int old_reg
, unsigned int new_reg
)
6674 /* Once we've decided upon a register to use as base register, it must
6675 no longer be used for any other purpose. */
6676 if (cfun
->machine
->base_reg
)
6677 if (REGNO (cfun
->machine
->base_reg
) == old_reg
6678 || REGNO (cfun
->machine
->base_reg
) == new_reg
)
6684 /* Return true if register FROM can be eliminated via register TO. */
6687 s390_can_eliminate (int from
, int to
)
6689 /* On zSeries machines, we have not marked the base register as fixed.
6690 Instead, we have an elimination rule BASE_REGNUM -> BASE_REGNUM.
6691 If a function requires the base register, we say here that this
6692 elimination cannot be performed. This will cause reload to free
6693 up the base register (as if it were fixed). On the other hand,
6694 if the current function does *not* require the base register, we
6695 say here the elimination succeeds, which in turn allows reload
6696 to allocate the base register for any other purpose. */
6697 if (from
== BASE_REGNUM
&& to
== BASE_REGNUM
)
6699 if (TARGET_CPU_ZARCH
)
6701 s390_init_frame_layout ();
6702 return cfun
->machine
->base_reg
== NULL_RTX
;
6708 /* Everything else must point into the stack frame. */
6709 gcc_assert (to
== STACK_POINTER_REGNUM
6710 || to
== HARD_FRAME_POINTER_REGNUM
);
6712 gcc_assert (from
== FRAME_POINTER_REGNUM
6713 || from
== ARG_POINTER_REGNUM
6714 || from
== RETURN_ADDRESS_POINTER_REGNUM
);
6716 /* Make sure we actually saved the return address. */
6717 if (from
== RETURN_ADDRESS_POINTER_REGNUM
)
6718 if (!current_function_calls_eh_return
6719 && !current_function_stdarg
6720 && !cfun_frame_layout
.save_return_addr_p
)
6726 /* Return offset between register FROM and TO initially after prolog. */
6729 s390_initial_elimination_offset (int from
, int to
)
6731 HOST_WIDE_INT offset
;
6734 /* ??? Why are we called for non-eliminable pairs? */
6735 if (!s390_can_eliminate (from
, to
))
6740 case FRAME_POINTER_REGNUM
:
6741 offset
= (get_frame_size()
6742 + STACK_POINTER_OFFSET
6743 + current_function_outgoing_args_size
);
6746 case ARG_POINTER_REGNUM
:
6747 s390_init_frame_layout ();
6748 offset
= cfun_frame_layout
.frame_size
+ STACK_POINTER_OFFSET
;
6751 case RETURN_ADDRESS_POINTER_REGNUM
:
6752 s390_init_frame_layout ();
6753 index
= RETURN_REGNUM
- cfun_frame_layout
.first_save_gpr_slot
;
6754 gcc_assert (index
>= 0);
6755 offset
= cfun_frame_layout
.frame_size
+ cfun_frame_layout
.gprs_offset
;
6756 offset
+= index
* UNITS_PER_WORD
;
6770 /* Emit insn to save fpr REGNUM at offset OFFSET relative
6771 to register BASE. Return generated insn. */
6774 save_fpr (rtx base
, int offset
, int regnum
)
6777 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
6779 if (regnum
>= 16 && regnum
<= (16 + FP_ARG_NUM_REG
))
6780 set_mem_alias_set (addr
, get_varargs_alias_set ());
6782 set_mem_alias_set (addr
, get_frame_alias_set ());
6784 return emit_move_insn (addr
, gen_rtx_REG (DFmode
, regnum
));
6787 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
6788 to register BASE. Return generated insn. */
6791 restore_fpr (rtx base
, int offset
, int regnum
)
6794 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
6795 set_mem_alias_set (addr
, get_frame_alias_set ());
6797 return emit_move_insn (gen_rtx_REG (DFmode
, regnum
), addr
);
6800 /* Generate insn to save registers FIRST to LAST into
6801 the register save area located at offset OFFSET
6802 relative to register BASE. */
6805 save_gprs (rtx base
, int offset
, int first
, int last
)
6807 rtx addr
, insn
, note
;
6810 addr
= plus_constant (base
, offset
);
6811 addr
= gen_rtx_MEM (Pmode
, addr
);
6813 set_mem_alias_set (addr
, get_frame_alias_set ());
6815 /* Special-case single register. */
6819 insn
= gen_movdi (addr
, gen_rtx_REG (Pmode
, first
));
6821 insn
= gen_movsi (addr
, gen_rtx_REG (Pmode
, first
));
6823 RTX_FRAME_RELATED_P (insn
) = 1;
6828 insn
= gen_store_multiple (addr
,
6829 gen_rtx_REG (Pmode
, first
),
6830 GEN_INT (last
- first
+ 1));
6832 if (first
<= 6 && current_function_stdarg
)
6833 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
6835 rtx mem
= XEXP (XVECEXP (PATTERN (insn
), 0, i
), 0);
6838 set_mem_alias_set (mem
, get_varargs_alias_set ());
6841 /* We need to set the FRAME_RELATED flag on all SETs
6842 inside the store-multiple pattern.
6844 However, we must not emit DWARF records for registers 2..5
6845 if they are stored for use by variable arguments ...
6847 ??? Unfortunately, it is not enough to simply not the
6848 FRAME_RELATED flags for those SETs, because the first SET
6849 of the PARALLEL is always treated as if it had the flag
6850 set, even if it does not. Therefore we emit a new pattern
6851 without those registers as REG_FRAME_RELATED_EXPR note. */
6855 rtx pat
= PATTERN (insn
);
6857 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
6858 if (GET_CODE (XVECEXP (pat
, 0, i
)) == SET
)
6859 RTX_FRAME_RELATED_P (XVECEXP (pat
, 0, i
)) = 1;
6861 RTX_FRAME_RELATED_P (insn
) = 1;
6865 addr
= plus_constant (base
, offset
+ (6 - first
) * UNITS_PER_WORD
);
6866 note
= gen_store_multiple (gen_rtx_MEM (Pmode
, addr
),
6867 gen_rtx_REG (Pmode
, 6),
6868 GEN_INT (last
- 6 + 1));
6869 note
= PATTERN (note
);
6872 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
6873 note
, REG_NOTES (insn
));
6875 for (i
= 0; i
< XVECLEN (note
, 0); i
++)
6876 if (GET_CODE (XVECEXP (note
, 0, i
)) == SET
)
6877 RTX_FRAME_RELATED_P (XVECEXP (note
, 0, i
)) = 1;
6879 RTX_FRAME_RELATED_P (insn
) = 1;
6885 /* Generate insn to restore registers FIRST to LAST from
6886 the register save area located at offset OFFSET
6887 relative to register BASE. */
6890 restore_gprs (rtx base
, int offset
, int first
, int last
)
6894 addr
= plus_constant (base
, offset
);
6895 addr
= gen_rtx_MEM (Pmode
, addr
);
6896 set_mem_alias_set (addr
, get_frame_alias_set ());
6898 /* Special-case single register. */
6902 insn
= gen_movdi (gen_rtx_REG (Pmode
, first
), addr
);
6904 insn
= gen_movsi (gen_rtx_REG (Pmode
, first
), addr
);
6909 insn
= gen_load_multiple (gen_rtx_REG (Pmode
, first
),
6911 GEN_INT (last
- first
+ 1));
6915 /* Return insn sequence to load the GOT register. */
6917 static GTY(()) rtx got_symbol
;
6919 s390_load_got (void)
6925 got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
6926 SYMBOL_REF_FLAGS (got_symbol
) = SYMBOL_FLAG_LOCAL
;
6931 if (TARGET_CPU_ZARCH
)
6933 emit_move_insn (pic_offset_table_rtx
, got_symbol
);
6939 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, got_symbol
),
6940 UNSPEC_LTREL_OFFSET
);
6941 offset
= gen_rtx_CONST (Pmode
, offset
);
6942 offset
= force_const_mem (Pmode
, offset
);
6944 emit_move_insn (pic_offset_table_rtx
, offset
);
6946 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, XEXP (offset
, 0)),
6948 offset
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, offset
);
6950 emit_move_insn (pic_offset_table_rtx
, offset
);
6953 insns
= get_insns ();
6958 /* Expand the prologue into a bunch of separate insns. */
6961 s390_emit_prologue (void)
6969 /* Complete frame layout. */
6971 s390_update_frame_layout ();
6973 /* Annotate all constant pool references to let the scheduler know
6974 they implicitly use the base register. */
6976 push_topmost_sequence ();
6978 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6980 annotate_constant_pool_refs (&PATTERN (insn
));
6982 pop_topmost_sequence ();
6984 /* Choose best register to use for temp use within prologue.
6985 See below for why TPF must use the register 1. */
6987 if (!has_hard_reg_initial_val (Pmode
, RETURN_REGNUM
)
6988 && !current_function_is_leaf
6989 && !TARGET_TPF_PROFILING
)
6990 temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
6992 temp_reg
= gen_rtx_REG (Pmode
, 1);
6994 /* Save call saved gprs. */
6995 if (cfun_frame_layout
.first_save_gpr
!= -1)
6997 insn
= save_gprs (stack_pointer_rtx
,
6998 cfun_frame_layout
.gprs_offset
+
6999 UNITS_PER_WORD
* (cfun_frame_layout
.first_save_gpr
7000 - cfun_frame_layout
.first_save_gpr_slot
),
7001 cfun_frame_layout
.first_save_gpr
,
7002 cfun_frame_layout
.last_save_gpr
);
7006 /* Dummy insn to mark literal pool slot. */
7008 if (cfun
->machine
->base_reg
)
7009 emit_insn (gen_main_pool (cfun
->machine
->base_reg
));
7011 offset
= cfun_frame_layout
.f0_offset
;
7013 /* Save f0 and f2. */
7014 for (i
= 0; i
< 2; i
++)
7016 if (cfun_fpr_bit_p (i
))
7018 save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
7021 else if (!TARGET_PACKED_STACK
)
7025 /* Save f4 and f6. */
7026 offset
= cfun_frame_layout
.f4_offset
;
7027 for (i
= 2; i
< 4; i
++)
7029 if (cfun_fpr_bit_p (i
))
7031 insn
= save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
7034 /* If f4 and f6 are call clobbered they are saved due to stdargs and
7035 therefore are not frame related. */
7036 if (!call_really_used_regs
[i
+ 16])
7037 RTX_FRAME_RELATED_P (insn
) = 1;
7039 else if (!TARGET_PACKED_STACK
)
7043 if (TARGET_PACKED_STACK
7044 && cfun_save_high_fprs_p
7045 && cfun_frame_layout
.f8_offset
+ cfun_frame_layout
.high_fprs
* 8 > 0)
7047 offset
= (cfun_frame_layout
.f8_offset
7048 + (cfun_frame_layout
.high_fprs
- 1) * 8);
7050 for (i
= 15; i
> 7 && offset
>= 0; i
--)
7051 if (cfun_fpr_bit_p (i
))
7053 insn
= save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
7055 RTX_FRAME_RELATED_P (insn
) = 1;
7058 if (offset
>= cfun_frame_layout
.f8_offset
)
7062 if (!TARGET_PACKED_STACK
)
7063 next_fpr
= cfun_save_high_fprs_p
? 31 : 0;
7065 /* Decrement stack pointer. */
7067 if (cfun_frame_layout
.frame_size
> 0)
7069 rtx frame_off
= GEN_INT (-cfun_frame_layout
.frame_size
);
7071 if (s390_stack_size
)
7073 HOST_WIDE_INT stack_check_mask
= ((s390_stack_size
- 1)
7074 & ~(s390_stack_guard
- 1));
7075 rtx t
= gen_rtx_AND (Pmode
, stack_pointer_rtx
,
7076 GEN_INT (stack_check_mask
));
7079 gen_cmpdi (t
, const0_rtx
);
7081 gen_cmpsi (t
, const0_rtx
);
7083 emit_insn (gen_conditional_trap (gen_rtx_EQ (CCmode
,
7084 gen_rtx_REG (CCmode
,
7090 if (s390_warn_framesize
> 0
7091 && cfun_frame_layout
.frame_size
>= s390_warn_framesize
)
7092 warning (0, "frame size of %qs is " HOST_WIDE_INT_PRINT_DEC
" bytes",
7093 current_function_name (), cfun_frame_layout
.frame_size
);
7095 if (s390_warn_dynamicstack_p
&& cfun
->calls_alloca
)
7096 warning (0, "%qs uses dynamic stack allocation", current_function_name ());
7098 /* Save incoming stack pointer into temp reg. */
7099 if (TARGET_BACKCHAIN
|| next_fpr
)
7100 insn
= emit_insn (gen_move_insn (temp_reg
, stack_pointer_rtx
));
7102 /* Subtract frame size from stack pointer. */
7104 if (DISP_IN_RANGE (INTVAL (frame_off
)))
7106 insn
= gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
7107 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
7109 insn
= emit_insn (insn
);
7113 if (!CONST_OK_FOR_K (INTVAL (frame_off
)))
7114 frame_off
= force_const_mem (Pmode
, frame_off
);
7116 insn
= emit_insn (gen_add2_insn (stack_pointer_rtx
, frame_off
));
7117 annotate_constant_pool_refs (&PATTERN (insn
));
7120 RTX_FRAME_RELATED_P (insn
) = 1;
7122 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
7123 gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
7124 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
7125 GEN_INT (-cfun_frame_layout
.frame_size
))),
7128 /* Set backchain. */
7130 if (TARGET_BACKCHAIN
)
7132 if (cfun_frame_layout
.backchain_offset
)
7133 addr
= gen_rtx_MEM (Pmode
,
7134 plus_constant (stack_pointer_rtx
,
7135 cfun_frame_layout
.backchain_offset
));
7137 addr
= gen_rtx_MEM (Pmode
, stack_pointer_rtx
);
7138 set_mem_alias_set (addr
, get_frame_alias_set ());
7139 insn
= emit_insn (gen_move_insn (addr
, temp_reg
));
7142 /* If we support asynchronous exceptions (e.g. for Java),
7143 we need to make sure the backchain pointer is set up
7144 before any possibly trapping memory access. */
7146 if (TARGET_BACKCHAIN
&& flag_non_call_exceptions
)
7148 addr
= gen_rtx_MEM (BLKmode
, gen_rtx_SCRATCH (VOIDmode
));
7149 emit_insn (gen_rtx_CLOBBER (VOIDmode
, addr
));
7153 /* Save fprs 8 - 15 (64 bit ABI). */
7155 if (cfun_save_high_fprs_p
&& next_fpr
)
7157 insn
= emit_insn (gen_add2_insn (temp_reg
,
7158 GEN_INT (cfun_frame_layout
.f8_offset
)));
7162 for (i
= 24; i
<= next_fpr
; i
++)
7163 if (cfun_fpr_bit_p (i
- 16))
7165 rtx addr
= plus_constant (stack_pointer_rtx
,
7166 cfun_frame_layout
.frame_size
7167 + cfun_frame_layout
.f8_offset
7170 insn
= save_fpr (temp_reg
, offset
, i
);
7172 RTX_FRAME_RELATED_P (insn
) = 1;
7174 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
7175 gen_rtx_SET (VOIDmode
,
7176 gen_rtx_MEM (DFmode
, addr
),
7177 gen_rtx_REG (DFmode
, i
)),
7182 /* Set frame pointer, if needed. */
7184 if (frame_pointer_needed
)
7186 insn
= emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
);
7187 RTX_FRAME_RELATED_P (insn
) = 1;
7190 /* Set up got pointer, if needed. */
7192 if (flag_pic
&& regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
])
7194 rtx insns
= s390_load_got ();
7196 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
7198 annotate_constant_pool_refs (&PATTERN (insn
));
7200 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD
, NULL_RTX
,
7207 if (TARGET_TPF_PROFILING
)
7209 /* Generate a BAS instruction to serve as a function
7210 entry intercept to facilitate the use of tracing
7211 algorithms located at the branch target. */
7212 emit_insn (gen_prologue_tpf ());
7214 /* Emit a blockage here so that all code
7215 lies between the profiling mechanisms. */
7216 emit_insn (gen_blockage ());
7220 /* Expand the epilogue into a bunch of separate insns. */
7223 s390_emit_epilogue (bool sibcall
)
7225 rtx frame_pointer
, return_reg
;
7226 int area_bottom
, area_top
, offset
= 0;
7231 if (TARGET_TPF_PROFILING
)
7234 /* Generate a BAS instruction to serve as a function
7235 entry intercept to facilitate the use of tracing
7236 algorithms located at the branch target. */
7238 /* Emit a blockage here so that all code
7239 lies between the profiling mechanisms. */
7240 emit_insn (gen_blockage ());
7242 emit_insn (gen_epilogue_tpf ());
7245 /* Check whether to use frame or stack pointer for restore. */
7247 frame_pointer
= (frame_pointer_needed
7248 ? hard_frame_pointer_rtx
: stack_pointer_rtx
);
7250 s390_frame_area (&area_bottom
, &area_top
);
7252 /* Check whether we can access the register save area.
7253 If not, increment the frame pointer as required. */
7255 if (area_top
<= area_bottom
)
7257 /* Nothing to restore. */
7259 else if (DISP_IN_RANGE (cfun_frame_layout
.frame_size
+ area_bottom
)
7260 && DISP_IN_RANGE (cfun_frame_layout
.frame_size
+ area_top
- 1))
7262 /* Area is in range. */
7263 offset
= cfun_frame_layout
.frame_size
;
7267 rtx insn
, frame_off
;
7269 offset
= area_bottom
< 0 ? -area_bottom
: 0;
7270 frame_off
= GEN_INT (cfun_frame_layout
.frame_size
- offset
);
7272 if (DISP_IN_RANGE (INTVAL (frame_off
)))
7274 insn
= gen_rtx_SET (VOIDmode
, frame_pointer
,
7275 gen_rtx_PLUS (Pmode
, frame_pointer
, frame_off
));
7276 insn
= emit_insn (insn
);
7280 if (!CONST_OK_FOR_K (INTVAL (frame_off
)))
7281 frame_off
= force_const_mem (Pmode
, frame_off
);
7283 insn
= emit_insn (gen_add2_insn (frame_pointer
, frame_off
));
7284 annotate_constant_pool_refs (&PATTERN (insn
));
7288 /* Restore call saved fprs. */
7292 if (cfun_save_high_fprs_p
)
7294 next_offset
= cfun_frame_layout
.f8_offset
;
7295 for (i
= 24; i
< 32; i
++)
7297 if (cfun_fpr_bit_p (i
- 16))
7299 restore_fpr (frame_pointer
,
7300 offset
+ next_offset
, i
);
7309 next_offset
= cfun_frame_layout
.f4_offset
;
7310 for (i
= 18; i
< 20; i
++)
7312 if (cfun_fpr_bit_p (i
- 16))
7314 restore_fpr (frame_pointer
,
7315 offset
+ next_offset
, i
);
7318 else if (!TARGET_PACKED_STACK
)
7324 /* Return register. */
7326 return_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
7328 /* Restore call saved gprs. */
7330 if (cfun_frame_layout
.first_restore_gpr
!= -1)
7335 /* Check for global register and save them
7336 to stack location from where they get restored. */
7338 for (i
= cfun_frame_layout
.first_restore_gpr
;
7339 i
<= cfun_frame_layout
.last_restore_gpr
;
7342 /* These registers are special and need to be
7343 restored in any case. */
7344 if (i
== STACK_POINTER_REGNUM
7345 || i
== RETURN_REGNUM
7347 || (flag_pic
&& i
== (int)PIC_OFFSET_TABLE_REGNUM
))
7352 addr
= plus_constant (frame_pointer
,
7353 offset
+ cfun_frame_layout
.gprs_offset
7354 + (i
- cfun_frame_layout
.first_save_gpr_slot
)
7356 addr
= gen_rtx_MEM (Pmode
, addr
);
7357 set_mem_alias_set (addr
, get_frame_alias_set ());
7358 emit_move_insn (addr
, gen_rtx_REG (Pmode
, i
));
7364 /* Fetch return address from stack before load multiple,
7365 this will do good for scheduling. */
7367 if (cfun_frame_layout
.save_return_addr_p
7368 || (cfun_frame_layout
.first_restore_gpr
< BASE_REGNUM
7369 && cfun_frame_layout
.last_restore_gpr
> RETURN_REGNUM
))
7371 int return_regnum
= find_unused_clobbered_reg();
7374 return_reg
= gen_rtx_REG (Pmode
, return_regnum
);
7376 addr
= plus_constant (frame_pointer
,
7377 offset
+ cfun_frame_layout
.gprs_offset
7379 - cfun_frame_layout
.first_save_gpr_slot
)
7381 addr
= gen_rtx_MEM (Pmode
, addr
);
7382 set_mem_alias_set (addr
, get_frame_alias_set ());
7383 emit_move_insn (return_reg
, addr
);
7387 insn
= restore_gprs (frame_pointer
,
7388 offset
+ cfun_frame_layout
.gprs_offset
7389 + (cfun_frame_layout
.first_restore_gpr
7390 - cfun_frame_layout
.first_save_gpr_slot
)
7392 cfun_frame_layout
.first_restore_gpr
,
7393 cfun_frame_layout
.last_restore_gpr
);
7400 /* Return to caller. */
7402 p
= rtvec_alloc (2);
7404 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
7405 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
, return_reg
);
7406 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
7411 /* Return the size in bytes of a function argument of
7412 type TYPE and/or mode MODE. At least one of TYPE or
7413 MODE must be specified. */
7416 s390_function_arg_size (enum machine_mode mode
, tree type
)
7419 return int_size_in_bytes (type
);
7421 /* No type info available for some library calls ... */
7422 if (mode
!= BLKmode
)
7423 return GET_MODE_SIZE (mode
);
7425 /* If we have neither type nor mode, abort */
7429 /* Return true if a function argument of type TYPE and mode MODE
7430 is to be passed in a floating-point register, if available. */
7433 s390_function_arg_float (enum machine_mode mode
, tree type
)
7435 int size
= s390_function_arg_size (mode
, type
);
7439 /* Soft-float changes the ABI: no floating-point registers are used. */
7440 if (TARGET_SOFT_FLOAT
)
7443 /* No type info available for some library calls ... */
7445 return mode
== SFmode
|| mode
== DFmode
;
7447 /* The ABI says that record types with a single member are treated
7448 just like that member would be. */
7449 while (TREE_CODE (type
) == RECORD_TYPE
)
7451 tree field
, single
= NULL_TREE
;
7453 for (field
= TYPE_FIELDS (type
); field
; field
= TREE_CHAIN (field
))
7455 if (TREE_CODE (field
) != FIELD_DECL
)
7458 if (single
== NULL_TREE
)
7459 single
= TREE_TYPE (field
);
7464 if (single
== NULL_TREE
)
7470 return TREE_CODE (type
) == REAL_TYPE
;
7473 /* Return true if a function argument of type TYPE and mode MODE
7474 is to be passed in an integer register, or a pair of integer
7475 registers, if available. */
7478 s390_function_arg_integer (enum machine_mode mode
, tree type
)
7480 int size
= s390_function_arg_size (mode
, type
);
7484 /* No type info available for some library calls ... */
7486 return GET_MODE_CLASS (mode
) == MODE_INT
7487 || (TARGET_SOFT_FLOAT
&& GET_MODE_CLASS (mode
) == MODE_FLOAT
);
7489 /* We accept small integral (and similar) types. */
7490 if (INTEGRAL_TYPE_P (type
)
7491 || POINTER_TYPE_P (type
)
7492 || TREE_CODE (type
) == OFFSET_TYPE
7493 || (TARGET_SOFT_FLOAT
&& TREE_CODE (type
) == REAL_TYPE
))
7496 /* We also accept structs of size 1, 2, 4, 8 that are not
7497 passed in floating-point registers. */
7498 if (AGGREGATE_TYPE_P (type
)
7499 && exact_log2 (size
) >= 0
7500 && !s390_function_arg_float (mode
, type
))
7506 /* Return 1 if a function argument of type TYPE and mode MODE
7507 is to be passed by reference. The ABI specifies that only
7508 structures of size 1, 2, 4, or 8 bytes are passed by value,
7509 all other structures (and complex numbers) are passed by
7513 s390_pass_by_reference (CUMULATIVE_ARGS
*ca ATTRIBUTE_UNUSED
,
7514 enum machine_mode mode
, tree type
,
7515 bool named ATTRIBUTE_UNUSED
)
7517 int size
= s390_function_arg_size (mode
, type
);
7523 if (AGGREGATE_TYPE_P (type
) && exact_log2 (size
) < 0)
7526 if (TREE_CODE (type
) == COMPLEX_TYPE
7527 || TREE_CODE (type
) == VECTOR_TYPE
)
7534 /* Update the data in CUM to advance over an argument of mode MODE and
7535 data type TYPE. (TYPE is null for libcalls where that information
7536 may not be available.). The boolean NAMED specifies whether the
7537 argument is a named argument (as opposed to an unnamed argument
7538 matching an ellipsis). */
7541 s390_function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
7542 tree type
, int named ATTRIBUTE_UNUSED
)
7544 if (s390_function_arg_float (mode
, type
))
7548 else if (s390_function_arg_integer (mode
, type
))
7550 int size
= s390_function_arg_size (mode
, type
);
7551 cum
->gprs
+= ((size
+ UNITS_PER_WORD
-1) / UNITS_PER_WORD
);
7557 /* Define where to put the arguments to a function.
7558 Value is zero to push the argument on the stack,
7559 or a hard register in which to store the argument.
7561 MODE is the argument's machine mode.
7562 TYPE is the data type of the argument (as a tree).
7563 This is null for libcalls where that information may
7565 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7566 the preceding args and about the function being called.
7567 NAMED is nonzero if this argument is a named parameter
7568 (otherwise it is an extra parameter matching an ellipsis).
7570 On S/390, we use general purpose registers 2 through 6 to
7571 pass integer, pointer, and certain structure arguments, and
7572 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
7573 to pass floating point arguments. All remaining arguments
7574 are pushed to the stack. */
7577 s390_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
, tree type
,
7578 int named ATTRIBUTE_UNUSED
)
7580 if (s390_function_arg_float (mode
, type
))
7582 if (cum
->fprs
+ 1 > FP_ARG_NUM_REG
)
7585 return gen_rtx_REG (mode
, cum
->fprs
+ 16);
7587 else if (s390_function_arg_integer (mode
, type
))
7589 int size
= s390_function_arg_size (mode
, type
);
7590 int n_gprs
= (size
+ UNITS_PER_WORD
-1) / UNITS_PER_WORD
;
7592 if (cum
->gprs
+ n_gprs
> GP_ARG_NUM_REG
)
7595 return gen_rtx_REG (mode
, cum
->gprs
+ 2);
7598 /* After the real arguments, expand_call calls us once again
7599 with a void_type_node type. Whatever we return here is
7600 passed as operand 2 to the call expanders.
7602 We don't need this feature ... */
7603 else if (type
== void_type_node
)
7609 /* Return true if return values of type TYPE should be returned
7610 in a memory buffer whose address is passed by the caller as
7611 hidden first argument. */
7614 s390_return_in_memory (tree type
, tree fundecl ATTRIBUTE_UNUSED
)
7616 /* We accept small integral (and similar) types. */
7617 if (INTEGRAL_TYPE_P (type
)
7618 || POINTER_TYPE_P (type
)
7619 || TREE_CODE (type
) == OFFSET_TYPE
7620 || TREE_CODE (type
) == REAL_TYPE
)
7621 return int_size_in_bytes (type
) > 8;
7623 /* Aggregates and similar constructs are always returned
7625 if (AGGREGATE_TYPE_P (type
)
7626 || TREE_CODE (type
) == COMPLEX_TYPE
7627 || TREE_CODE (type
) == VECTOR_TYPE
)
7630 /* ??? We get called on all sorts of random stuff from
7631 aggregate_value_p. We can't abort, but it's not clear
7632 what's safe to return. Pretend it's a struct I guess. */
7636 /* Define where to return a (scalar) value of type TYPE.
7637 If TYPE is null, define where to return a (scalar)
7638 value of mode MODE from a libcall. */
7641 s390_function_value (tree type
, enum machine_mode mode
)
7645 int unsignedp
= TYPE_UNSIGNED (type
);
7646 mode
= promote_mode (type
, TYPE_MODE (type
), &unsignedp
, 1);
7649 gcc_assert (GET_MODE_CLASS (mode
) == MODE_INT
7650 || GET_MODE_CLASS (mode
) == MODE_FLOAT
);
7651 gcc_assert (GET_MODE_SIZE (mode
) <= 8);
7653 if (TARGET_HARD_FLOAT
&& GET_MODE_CLASS (mode
) == MODE_FLOAT
)
7654 return gen_rtx_REG (mode
, 16);
7656 return gen_rtx_REG (mode
, 2);
7660 /* Create and return the va_list datatype.
7662 On S/390, va_list is an array type equivalent to
7664 typedef struct __va_list_tag
7668 void *__overflow_arg_area;
7669 void *__reg_save_area;
7672 where __gpr and __fpr hold the number of general purpose
7673 or floating point arguments used up to now, respectively,
7674 __overflow_arg_area points to the stack location of the
7675 next argument passed on the stack, and __reg_save_area
7676 always points to the start of the register area in the
7677 call frame of the current function. The function prologue
7678 saves all registers used for argument passing into this
7679 area if the function uses variable arguments. */
7682 s390_build_builtin_va_list (void)
7684 tree f_gpr
, f_fpr
, f_ovf
, f_sav
, record
, type_decl
;
7686 record
= lang_hooks
.types
.make_type (RECORD_TYPE
);
7689 build_decl (TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
7691 f_gpr
= build_decl (FIELD_DECL
, get_identifier ("__gpr"),
7692 long_integer_type_node
);
7693 f_fpr
= build_decl (FIELD_DECL
, get_identifier ("__fpr"),
7694 long_integer_type_node
);
7695 f_ovf
= build_decl (FIELD_DECL
, get_identifier ("__overflow_arg_area"),
7697 f_sav
= build_decl (FIELD_DECL
, get_identifier ("__reg_save_area"),
7700 va_list_gpr_counter_field
= f_gpr
;
7701 va_list_fpr_counter_field
= f_fpr
;
7703 DECL_FIELD_CONTEXT (f_gpr
) = record
;
7704 DECL_FIELD_CONTEXT (f_fpr
) = record
;
7705 DECL_FIELD_CONTEXT (f_ovf
) = record
;
7706 DECL_FIELD_CONTEXT (f_sav
) = record
;
7708 TREE_CHAIN (record
) = type_decl
;
7709 TYPE_NAME (record
) = type_decl
;
7710 TYPE_FIELDS (record
) = f_gpr
;
7711 TREE_CHAIN (f_gpr
) = f_fpr
;
7712 TREE_CHAIN (f_fpr
) = f_ovf
;
7713 TREE_CHAIN (f_ovf
) = f_sav
;
7715 layout_type (record
);
7717 /* The correct type is an array type of one element. */
7718 return build_array_type (record
, build_index_type (size_zero_node
));
7721 /* Implement va_start by filling the va_list structure VALIST.
7722 STDARG_P is always true, and ignored.
7723 NEXTARG points to the first anonymous stack argument.
7725 The following global variables are used to initialize
7726 the va_list structure:
7728 current_function_args_info:
7729 holds number of gprs and fprs used for named arguments.
7730 current_function_arg_offset_rtx:
7731 holds the offset of the first anonymous stack argument
7732 (relative to the virtual arg pointer). */
7735 s390_va_start (tree valist
, rtx nextarg ATTRIBUTE_UNUSED
)
7737 HOST_WIDE_INT n_gpr
, n_fpr
;
7739 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
7740 tree gpr
, fpr
, ovf
, sav
, t
;
7742 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
7743 f_fpr
= TREE_CHAIN (f_gpr
);
7744 f_ovf
= TREE_CHAIN (f_fpr
);
7745 f_sav
= TREE_CHAIN (f_ovf
);
7747 valist
= build_va_arg_indirect_ref (valist
);
7748 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
7749 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
7750 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
7751 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
7753 /* Count number of gp and fp argument registers used. */
7755 n_gpr
= current_function_args_info
.gprs
;
7756 n_fpr
= current_function_args_info
.fprs
;
7758 if (cfun
->va_list_gpr_size
)
7760 t
= build2 (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
,
7761 build_int_cst (NULL_TREE
, n_gpr
));
7762 TREE_SIDE_EFFECTS (t
) = 1;
7763 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7766 if (cfun
->va_list_fpr_size
)
7768 t
= build2 (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
,
7769 build_int_cst (NULL_TREE
, n_fpr
));
7770 TREE_SIDE_EFFECTS (t
) = 1;
7771 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7774 /* Find the overflow area. */
7775 if (n_gpr
+ cfun
->va_list_gpr_size
> GP_ARG_NUM_REG
7776 || n_fpr
+ cfun
->va_list_fpr_size
> FP_ARG_NUM_REG
)
7778 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
7780 off
= INTVAL (current_function_arg_offset_rtx
);
7781 off
= off
< 0 ? 0 : off
;
7782 if (TARGET_DEBUG_ARG
)
7783 fprintf (stderr
, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
7784 (int)n_gpr
, (int)n_fpr
, off
);
7786 t
= build2 (PLUS_EXPR
, TREE_TYPE (ovf
), t
, build_int_cst (NULL_TREE
, off
));
7788 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
7789 TREE_SIDE_EFFECTS (t
) = 1;
7790 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7793 /* Find the register save area. */
7794 if ((cfun
->va_list_gpr_size
&& n_gpr
< GP_ARG_NUM_REG
)
7795 || (cfun
->va_list_fpr_size
&& n_fpr
< FP_ARG_NUM_REG
))
7797 t
= make_tree (TREE_TYPE (sav
), return_address_pointer_rtx
);
7798 t
= build2 (PLUS_EXPR
, TREE_TYPE (sav
), t
,
7799 build_int_cst (NULL_TREE
, -RETURN_REGNUM
* UNITS_PER_WORD
));
7801 t
= build2 (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
7802 TREE_SIDE_EFFECTS (t
) = 1;
7803 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7807 /* Implement va_arg by updating the va_list structure
7808 VALIST as required to retrieve an argument of type
7809 TYPE, and returning that argument.
7811 Generates code equivalent to:
7813 if (integral value) {
7814 if (size <= 4 && args.gpr < 5 ||
7815 size > 4 && args.gpr < 4 )
7816 ret = args.reg_save_area[args.gpr+8]
7818 ret = *args.overflow_arg_area++;
7819 } else if (float value) {
7821 ret = args.reg_save_area[args.fpr+64]
7823 ret = *args.overflow_arg_area++;
7824 } else if (aggregate value) {
7826 ret = *args.reg_save_area[args.gpr]
7828 ret = **args.overflow_arg_area++;
7832 s390_gimplify_va_arg (tree valist
, tree type
, tree
*pre_p
,
7833 tree
*post_p ATTRIBUTE_UNUSED
)
7835 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
7836 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
7837 int indirect_p
, size
, n_reg
, sav_ofs
, sav_scale
, max_reg
;
7838 tree lab_false
, lab_over
, addr
;
7840 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
7841 f_fpr
= TREE_CHAIN (f_gpr
);
7842 f_ovf
= TREE_CHAIN (f_fpr
);
7843 f_sav
= TREE_CHAIN (f_ovf
);
7845 valist
= build_va_arg_indirect_ref (valist
);
7846 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
7847 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
7848 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
7849 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
7851 size
= int_size_in_bytes (type
);
7853 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
7855 if (TARGET_DEBUG_ARG
)
7857 fprintf (stderr
, "va_arg: aggregate type");
7861 /* Aggregates are passed by reference. */
7866 /* kernel stack layout on 31 bit: It is assumed here that no padding
7867 will be added by s390_frame_info because for va_args always an even
7868 number of gprs has to be saved r15-r2 = 14 regs. */
7869 sav_ofs
= 2 * UNITS_PER_WORD
;
7870 sav_scale
= UNITS_PER_WORD
;
7871 size
= UNITS_PER_WORD
;
7872 max_reg
= GP_ARG_NUM_REG
- n_reg
;
7874 else if (s390_function_arg_float (TYPE_MODE (type
), type
))
7876 if (TARGET_DEBUG_ARG
)
7878 fprintf (stderr
, "va_arg: float type");
7882 /* FP args go in FP registers, if present. */
7886 sav_ofs
= 16 * UNITS_PER_WORD
;
7888 max_reg
= FP_ARG_NUM_REG
- n_reg
;
7892 if (TARGET_DEBUG_ARG
)
7894 fprintf (stderr
, "va_arg: other type");
7898 /* Otherwise into GP registers. */
7901 n_reg
= (size
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
7903 /* kernel stack layout on 31 bit: It is assumed here that no padding
7904 will be added by s390_frame_info because for va_args always an even
7905 number of gprs has to be saved r15-r2 = 14 regs. */
7906 sav_ofs
= 2 * UNITS_PER_WORD
;
7908 if (size
< UNITS_PER_WORD
)
7909 sav_ofs
+= UNITS_PER_WORD
- size
;
7911 sav_scale
= UNITS_PER_WORD
;
7912 max_reg
= GP_ARG_NUM_REG
- n_reg
;
7915 /* Pull the value out of the saved registers ... */
7917 lab_false
= create_artificial_label ();
7918 lab_over
= create_artificial_label ();
7919 addr
= create_tmp_var (ptr_type_node
, "addr");
7920 DECL_POINTER_ALIAS_SET (addr
) = get_varargs_alias_set ();
7922 t
= fold_convert (TREE_TYPE (reg
), size_int (max_reg
));
7923 t
= build2 (GT_EXPR
, boolean_type_node
, reg
, t
);
7924 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
7925 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
7926 gimplify_and_add (t
, pre_p
);
7928 t
= build2 (PLUS_EXPR
, ptr_type_node
, sav
,
7929 fold_convert (ptr_type_node
, size_int (sav_ofs
)));
7930 u
= build2 (MULT_EXPR
, TREE_TYPE (reg
), reg
,
7931 fold_convert (TREE_TYPE (reg
), size_int (sav_scale
)));
7932 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
, fold_convert (ptr_type_node
, u
));
7934 t
= build2 (MODIFY_EXPR
, void_type_node
, addr
, t
);
7935 gimplify_and_add (t
, pre_p
);
7937 t
= build1 (GOTO_EXPR
, void_type_node
, lab_over
);
7938 gimplify_and_add (t
, pre_p
);
7940 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false
);
7941 append_to_statement_list (t
, pre_p
);
7944 /* ... Otherwise out of the overflow area. */
7947 if (size
< UNITS_PER_WORD
)
7948 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
,
7949 fold_convert (ptr_type_node
, size_int (UNITS_PER_WORD
- size
)));
7951 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
7953 u
= build2 (MODIFY_EXPR
, void_type_node
, addr
, t
);
7954 gimplify_and_add (u
, pre_p
);
7956 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
,
7957 fold_convert (ptr_type_node
, size_int (size
)));
7958 t
= build2 (MODIFY_EXPR
, ptr_type_node
, ovf
, t
);
7959 gimplify_and_add (t
, pre_p
);
7961 t
= build1 (LABEL_EXPR
, void_type_node
, lab_over
);
7962 append_to_statement_list (t
, pre_p
);
7965 /* Increment register save count. */
7967 u
= build2 (PREINCREMENT_EXPR
, TREE_TYPE (reg
), reg
,
7968 fold_convert (TREE_TYPE (reg
), size_int (n_reg
)));
7969 gimplify_and_add (u
, pre_p
);
7973 t
= build_pointer_type (build_pointer_type (type
));
7974 addr
= fold_convert (t
, addr
);
7975 addr
= build_va_arg_indirect_ref (addr
);
7979 t
= build_pointer_type (type
);
7980 addr
= fold_convert (t
, addr
);
7983 return build_va_arg_indirect_ref (addr
);
7991 S390_BUILTIN_THREAD_POINTER
,
7992 S390_BUILTIN_SET_THREAD_POINTER
,
7997 static unsigned int const code_for_builtin_64
[S390_BUILTIN_max
] = {
8002 static unsigned int const code_for_builtin_31
[S390_BUILTIN_max
] = {
8008 s390_init_builtins (void)
8012 ftype
= build_function_type (ptr_type_node
, void_list_node
);
8013 lang_hooks
.builtin_function ("__builtin_thread_pointer", ftype
,
8014 S390_BUILTIN_THREAD_POINTER
, BUILT_IN_MD
,
8017 ftype
= build_function_type_list (void_type_node
, ptr_type_node
, NULL_TREE
);
8018 lang_hooks
.builtin_function ("__builtin_set_thread_pointer", ftype
,
8019 S390_BUILTIN_SET_THREAD_POINTER
, BUILT_IN_MD
,
8023 /* Expand an expression EXP that calls a built-in function,
8024 with result going to TARGET if that's convenient
8025 (and in mode MODE if that's convenient).
8026 SUBTARGET may be used as the target for computing one of EXP's operands.
8027 IGNORE is nonzero if the value is to be ignored. */
8030 s390_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
8031 enum machine_mode mode ATTRIBUTE_UNUSED
,
8032 int ignore ATTRIBUTE_UNUSED
)
8036 unsigned int const *code_for_builtin
=
8037 TARGET_64BIT
? code_for_builtin_64
: code_for_builtin_31
;
8039 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
8040 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8041 tree arglist
= TREE_OPERAND (exp
, 1);
8042 enum insn_code icode
;
8043 rtx op
[MAX_ARGS
], pat
;
8047 if (fcode
>= S390_BUILTIN_max
)
8048 internal_error ("bad builtin fcode");
8049 icode
= code_for_builtin
[fcode
];
8051 internal_error ("bad builtin fcode");
8053 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
8055 for (arglist
= TREE_OPERAND (exp
, 1), arity
= 0;
8057 arglist
= TREE_CHAIN (arglist
), arity
++)
8059 const struct insn_operand_data
*insn_op
;
8061 tree arg
= TREE_VALUE (arglist
);
8062 if (arg
== error_mark_node
)
8064 if (arity
> MAX_ARGS
)
8067 insn_op
= &insn_data
[icode
].operand
[arity
+ nonvoid
];
8069 op
[arity
] = expand_expr (arg
, NULL_RTX
, insn_op
->mode
, 0);
8071 if (!(*insn_op
->predicate
) (op
[arity
], insn_op
->mode
))
8072 op
[arity
] = copy_to_mode_reg (insn_op
->mode
, op
[arity
]);
8077 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8079 || GET_MODE (target
) != tmode
8080 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8081 target
= gen_reg_rtx (tmode
);
8087 pat
= GEN_FCN (icode
) (target
);
8091 pat
= GEN_FCN (icode
) (target
, op
[0]);
8093 pat
= GEN_FCN (icode
) (op
[0]);
8096 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
8112 /* Output assembly code for the trampoline template to
8115 On S/390, we use gpr 1 internally in the trampoline code;
8116 gpr 0 is used to hold the static chain. */
8119 s390_trampoline_template (FILE *file
)
8122 op
[0] = gen_rtx_REG (Pmode
, 0);
8123 op
[1] = gen_rtx_REG (Pmode
, 1);
8127 output_asm_insn ("basr\t%1,0", op
);
8128 output_asm_insn ("lmg\t%0,%1,14(%1)", op
);
8129 output_asm_insn ("br\t%1", op
);
8130 ASM_OUTPUT_SKIP (file
, (HOST_WIDE_INT
)(TRAMPOLINE_SIZE
- 10));
8134 output_asm_insn ("basr\t%1,0", op
);
8135 output_asm_insn ("lm\t%0,%1,6(%1)", op
);
8136 output_asm_insn ("br\t%1", op
);
8137 ASM_OUTPUT_SKIP (file
, (HOST_WIDE_INT
)(TRAMPOLINE_SIZE
- 8));
8141 /* Emit RTL insns to initialize the variable parts of a trampoline.
8142 FNADDR is an RTX for the address of the function's pure code.
8143 CXT is an RTX for the static chain value for the function. */
8146 s390_initialize_trampoline (rtx addr
, rtx fnaddr
, rtx cxt
)
8148 emit_move_insn (gen_rtx_MEM (Pmode
,
8149 memory_address (Pmode
,
8150 plus_constant (addr
, (TARGET_64BIT
? 16 : 8)))), cxt
);
8151 emit_move_insn (gen_rtx_MEM (Pmode
,
8152 memory_address (Pmode
,
8153 plus_constant (addr
, (TARGET_64BIT
? 24 : 12)))), fnaddr
);
8156 /* Return rtx for 64-bit constant formed from the 32-bit subwords
8157 LOW and HIGH, independent of the host word size. */
8160 s390_gen_rtx_const_DI (int high
, int low
)
8162 #if HOST_BITS_PER_WIDE_INT >= 64
8164 val
= (HOST_WIDE_INT
)high
;
8166 val
|= (HOST_WIDE_INT
)low
;
8168 return GEN_INT (val
);
8170 #if HOST_BITS_PER_WIDE_INT >= 32
8171 return immed_double_const ((HOST_WIDE_INT
)low
, (HOST_WIDE_INT
)high
, DImode
);
8178 /* Output assembler code to FILE to increment profiler label # LABELNO
8179 for profiling a function entry. */
8182 s390_function_profiler (FILE *file
, int labelno
)
8187 ASM_GENERATE_INTERNAL_LABEL (label
, "LP", labelno
);
8189 fprintf (file
, "# function profiler \n");
8191 op
[0] = gen_rtx_REG (Pmode
, RETURN_REGNUM
);
8192 op
[1] = gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
8193 op
[1] = gen_rtx_MEM (Pmode
, plus_constant (op
[1], UNITS_PER_WORD
));
8195 op
[2] = gen_rtx_REG (Pmode
, 1);
8196 op
[3] = gen_rtx_SYMBOL_REF (Pmode
, label
);
8197 SYMBOL_REF_FLAGS (op
[3]) = SYMBOL_FLAG_LOCAL
;
8199 op
[4] = gen_rtx_SYMBOL_REF (Pmode
, "_mcount");
8202 op
[4] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[4]), UNSPEC_PLT
);
8203 op
[4] = gen_rtx_CONST (Pmode
, op
[4]);
8208 output_asm_insn ("stg\t%0,%1", op
);
8209 output_asm_insn ("larl\t%2,%3", op
);
8210 output_asm_insn ("brasl\t%0,%4", op
);
8211 output_asm_insn ("lg\t%0,%1", op
);
8215 op
[6] = gen_label_rtx ();
8217 output_asm_insn ("st\t%0,%1", op
);
8218 output_asm_insn ("bras\t%2,%l6", op
);
8219 output_asm_insn (".long\t%4", op
);
8220 output_asm_insn (".long\t%3", op
);
8221 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
8222 output_asm_insn ("l\t%0,0(%2)", op
);
8223 output_asm_insn ("l\t%2,4(%2)", op
);
8224 output_asm_insn ("basr\t%0,%0", op
);
8225 output_asm_insn ("l\t%0,%1", op
);
8229 op
[5] = gen_label_rtx ();
8230 op
[6] = gen_label_rtx ();
8232 output_asm_insn ("st\t%0,%1", op
);
8233 output_asm_insn ("bras\t%2,%l6", op
);
8234 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[5]));
8235 output_asm_insn (".long\t%4-%l5", op
);
8236 output_asm_insn (".long\t%3-%l5", op
);
8237 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
8238 output_asm_insn ("lr\t%0,%2", op
);
8239 output_asm_insn ("a\t%0,0(%2)", op
);
8240 output_asm_insn ("a\t%2,4(%2)", op
);
8241 output_asm_insn ("basr\t%0,%0", op
);
8242 output_asm_insn ("l\t%0,%1", op
);
8246 /* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
8247 into its SYMBOL_REF_FLAGS. */
8250 s390_encode_section_info (tree decl
, rtx rtl
, int first
)
8252 default_encode_section_info (decl
, rtl
, first
);
8254 /* If a variable has a forced alignment to < 2 bytes, mark it with
8255 SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL operand. */
8256 if (TREE_CODE (decl
) == VAR_DECL
8257 && DECL_USER_ALIGN (decl
) && DECL_ALIGN (decl
) < 16)
8258 SYMBOL_REF_FLAGS (XEXP (rtl
, 0)) |= SYMBOL_FLAG_ALIGN1
;
8261 /* Output thunk to FILE that implements a C++ virtual function call (with
8262 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
8263 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
8264 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
8265 relative to the resulting this pointer. */
8268 s390_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
8269 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
8275 /* Operand 0 is the target function. */
8276 op
[0] = XEXP (DECL_RTL (function
), 0);
8277 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (op
[0]))
8280 op
[0] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[0]),
8281 TARGET_64BIT
? UNSPEC_PLT
: UNSPEC_GOT
);
8282 op
[0] = gen_rtx_CONST (Pmode
, op
[0]);
8285 /* Operand 1 is the 'this' pointer. */
8286 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
8287 op
[1] = gen_rtx_REG (Pmode
, 3);
8289 op
[1] = gen_rtx_REG (Pmode
, 2);
8291 /* Operand 2 is the delta. */
8292 op
[2] = GEN_INT (delta
);
8294 /* Operand 3 is the vcall_offset. */
8295 op
[3] = GEN_INT (vcall_offset
);
8297 /* Operand 4 is the temporary register. */
8298 op
[4] = gen_rtx_REG (Pmode
, 1);
8300 /* Operands 5 to 8 can be used as labels. */
8306 /* Operand 9 can be used for temporary register. */
8309 /* Generate code. */
8312 /* Setup literal pool pointer if required. */
8313 if ((!DISP_IN_RANGE (delta
)
8314 && !CONST_OK_FOR_K (delta
)
8315 && !CONST_OK_FOR_Os (delta
))
8316 || (!DISP_IN_RANGE (vcall_offset
)
8317 && !CONST_OK_FOR_K (vcall_offset
)
8318 && !CONST_OK_FOR_Os (vcall_offset
)))
8320 op
[5] = gen_label_rtx ();
8321 output_asm_insn ("larl\t%4,%5", op
);
8324 /* Add DELTA to this pointer. */
8327 if (CONST_OK_FOR_J (delta
))
8328 output_asm_insn ("la\t%1,%2(%1)", op
);
8329 else if (DISP_IN_RANGE (delta
))
8330 output_asm_insn ("lay\t%1,%2(%1)", op
);
8331 else if (CONST_OK_FOR_K (delta
))
8332 output_asm_insn ("aghi\t%1,%2", op
);
8333 else if (CONST_OK_FOR_Os (delta
))
8334 output_asm_insn ("agfi\t%1,%2", op
);
8337 op
[6] = gen_label_rtx ();
8338 output_asm_insn ("agf\t%1,%6-%5(%4)", op
);
8342 /* Perform vcall adjustment. */
8345 if (DISP_IN_RANGE (vcall_offset
))
8347 output_asm_insn ("lg\t%4,0(%1)", op
);
8348 output_asm_insn ("ag\t%1,%3(%4)", op
);
8350 else if (CONST_OK_FOR_K (vcall_offset
))
8352 output_asm_insn ("lghi\t%4,%3", op
);
8353 output_asm_insn ("ag\t%4,0(%1)", op
);
8354 output_asm_insn ("ag\t%1,0(%4)", op
);
8356 else if (CONST_OK_FOR_Os (vcall_offset
))
8358 output_asm_insn ("lgfi\t%4,%3", op
);
8359 output_asm_insn ("ag\t%4,0(%1)", op
);
8360 output_asm_insn ("ag\t%1,0(%4)", op
);
8364 op
[7] = gen_label_rtx ();
8365 output_asm_insn ("llgf\t%4,%7-%5(%4)", op
);
8366 output_asm_insn ("ag\t%4,0(%1)", op
);
8367 output_asm_insn ("ag\t%1,0(%4)", op
);
8371 /* Jump to target. */
8372 output_asm_insn ("jg\t%0", op
);
8374 /* Output literal pool if required. */
8377 output_asm_insn (".align\t4", op
);
8378 targetm
.asm_out
.internal_label (file
, "L",
8379 CODE_LABEL_NUMBER (op
[5]));
8383 targetm
.asm_out
.internal_label (file
, "L",
8384 CODE_LABEL_NUMBER (op
[6]));
8385 output_asm_insn (".long\t%2", op
);
8389 targetm
.asm_out
.internal_label (file
, "L",
8390 CODE_LABEL_NUMBER (op
[7]));
8391 output_asm_insn (".long\t%3", op
);
8396 /* Setup base pointer if required. */
8398 || (!DISP_IN_RANGE (delta
)
8399 && !CONST_OK_FOR_K (delta
)
8400 && !CONST_OK_FOR_Os (delta
))
8401 || (!DISP_IN_RANGE (delta
)
8402 && !CONST_OK_FOR_K (vcall_offset
)
8403 && !CONST_OK_FOR_Os (vcall_offset
)))
8405 op
[5] = gen_label_rtx ();
8406 output_asm_insn ("basr\t%4,0", op
);
8407 targetm
.asm_out
.internal_label (file
, "L",
8408 CODE_LABEL_NUMBER (op
[5]));
8411 /* Add DELTA to this pointer. */
8414 if (CONST_OK_FOR_J (delta
))
8415 output_asm_insn ("la\t%1,%2(%1)", op
);
8416 else if (DISP_IN_RANGE (delta
))
8417 output_asm_insn ("lay\t%1,%2(%1)", op
);
8418 else if (CONST_OK_FOR_K (delta
))
8419 output_asm_insn ("ahi\t%1,%2", op
);
8420 else if (CONST_OK_FOR_Os (delta
))
8421 output_asm_insn ("afi\t%1,%2", op
);
8424 op
[6] = gen_label_rtx ();
8425 output_asm_insn ("a\t%1,%6-%5(%4)", op
);
8429 /* Perform vcall adjustment. */
8432 if (CONST_OK_FOR_J (vcall_offset
))
8434 output_asm_insn ("l\t%4,0(%1)", op
);
8435 output_asm_insn ("a\t%1,%3(%4)", op
);
8437 else if (DISP_IN_RANGE (vcall_offset
))
8439 output_asm_insn ("l\t%4,0(%1)", op
);
8440 output_asm_insn ("ay\t%1,%3(%4)", op
);
8442 else if (CONST_OK_FOR_K (vcall_offset
))
8444 output_asm_insn ("lhi\t%4,%3", op
);
8445 output_asm_insn ("a\t%4,0(%1)", op
);
8446 output_asm_insn ("a\t%1,0(%4)", op
);
8448 else if (CONST_OK_FOR_Os (vcall_offset
))
8450 output_asm_insn ("iilf\t%4,%3", op
);
8451 output_asm_insn ("a\t%4,0(%1)", op
);
8452 output_asm_insn ("a\t%1,0(%4)", op
);
8456 op
[7] = gen_label_rtx ();
8457 output_asm_insn ("l\t%4,%7-%5(%4)", op
);
8458 output_asm_insn ("a\t%4,0(%1)", op
);
8459 output_asm_insn ("a\t%1,0(%4)", op
);
8462 /* We had to clobber the base pointer register.
8463 Re-setup the base pointer (with a different base). */
8464 op
[5] = gen_label_rtx ();
8465 output_asm_insn ("basr\t%4,0", op
);
8466 targetm
.asm_out
.internal_label (file
, "L",
8467 CODE_LABEL_NUMBER (op
[5]));
8470 /* Jump to target. */
8471 op
[8] = gen_label_rtx ();
8474 output_asm_insn ("l\t%4,%8-%5(%4)", op
);
8476 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
8477 /* We cannot call through .plt, since .plt requires %r12 loaded. */
8478 else if (flag_pic
== 1)
8480 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
8481 output_asm_insn ("l\t%4,%0(%4)", op
);
8483 else if (flag_pic
== 2)
8485 op
[9] = gen_rtx_REG (Pmode
, 0);
8486 output_asm_insn ("l\t%9,%8-4-%5(%4)", op
);
8487 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
8488 output_asm_insn ("ar\t%4,%9", op
);
8489 output_asm_insn ("l\t%4,0(%4)", op
);
8492 output_asm_insn ("br\t%4", op
);
8494 /* Output literal pool. */
8495 output_asm_insn (".align\t4", op
);
8497 if (nonlocal
&& flag_pic
== 2)
8498 output_asm_insn (".long\t%0", op
);
8501 op
[0] = gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
8502 SYMBOL_REF_FLAGS (op
[0]) = SYMBOL_FLAG_LOCAL
;
8505 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[8]));
8507 output_asm_insn (".long\t%0", op
);
8509 output_asm_insn (".long\t%0-%5", op
);
8513 targetm
.asm_out
.internal_label (file
, "L",
8514 CODE_LABEL_NUMBER (op
[6]));
8515 output_asm_insn (".long\t%2", op
);
8519 targetm
.asm_out
.internal_label (file
, "L",
8520 CODE_LABEL_NUMBER (op
[7]));
8521 output_asm_insn (".long\t%3", op
);
8527 s390_valid_pointer_mode (enum machine_mode mode
)
8529 return (mode
== SImode
|| (TARGET_64BIT
&& mode
== DImode
));
8532 /* Checks whether the given ARGUMENT_LIST would use a caller
8533 saved register. This is used to decide whether sibling call
8534 optimization could be performed on the respective function
8538 s390_call_saved_register_used (tree argument_list
)
8540 CUMULATIVE_ARGS cum
;
8542 enum machine_mode mode
;
8547 INIT_CUMULATIVE_ARGS (cum
, NULL
, NULL
, 0, 0);
8549 while (argument_list
)
8551 parameter
= TREE_VALUE (argument_list
);
8552 argument_list
= TREE_CHAIN (argument_list
);
8554 gcc_assert (parameter
);
8556 /* For an undeclared variable passed as parameter we will get
8557 an ERROR_MARK node here. */
8558 if (TREE_CODE (parameter
) == ERROR_MARK
)
8561 type
= TREE_TYPE (parameter
);
8564 mode
= TYPE_MODE (type
);
8567 if (pass_by_reference (&cum
, mode
, type
, true))
8570 type
= build_pointer_type (type
);
8573 parm_rtx
= s390_function_arg (&cum
, mode
, type
, 0);
8575 s390_function_arg_advance (&cum
, mode
, type
, 0);
8577 if (parm_rtx
&& REG_P (parm_rtx
))
8580 reg
< HARD_REGNO_NREGS (REGNO (parm_rtx
), GET_MODE (parm_rtx
));
8582 if (! call_used_regs
[reg
+ REGNO (parm_rtx
)])
8589 /* Return true if the given call expression can be
8590 turned into a sibling call.
8591 DECL holds the declaration of the function to be called whereas
8592 EXP is the call expression itself. */
8595 s390_function_ok_for_sibcall (tree decl
, tree exp
)
8597 /* The TPF epilogue uses register 1. */
8598 if (TARGET_TPF_PROFILING
)
8601 /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
8602 which would have to be restored before the sibcall. */
8603 if (!TARGET_64BIT
&& flag_pic
&& decl
&& !targetm
.binds_local_p (decl
))
8606 /* Register 6 on s390 is available as an argument register but unfortunately
8607 "caller saved". This makes functions needing this register for arguments
8608 not suitable for sibcalls. */
8609 if (TREE_OPERAND (exp
, 1)
8610 && s390_call_saved_register_used (TREE_OPERAND (exp
, 1)))
8616 /* Return the fixed registers used for condition codes. */
8619 s390_fixed_condition_code_regs (unsigned int *p1
, unsigned int *p2
)
8622 *p2
= INVALID_REGNUM
;
8627 /* This function is used by the call expanders of the machine description.
8628 It emits the call insn itself together with the necessary operations
8629 to adjust the target address and returns the emitted insn.
8630 ADDR_LOCATION is the target address rtx
8631 TLS_CALL the location of the thread-local symbol
8632 RESULT_REG the register where the result of the call should be stored
8633 RETADDR_REG the register where the return address should be stored
8634 If this parameter is NULL_RTX the call is considered
8635 to be a sibling call. */
8638 s390_emit_call (rtx addr_location
, rtx tls_call
, rtx result_reg
,
8641 bool plt_call
= false;
8647 /* Direct function calls need special treatment. */
8648 if (GET_CODE (addr_location
) == SYMBOL_REF
)
8650 /* When calling a global routine in PIC mode, we must
8651 replace the symbol itself with the PLT stub. */
8652 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (addr_location
))
8654 addr_location
= gen_rtx_UNSPEC (Pmode
,
8655 gen_rtvec (1, addr_location
),
8657 addr_location
= gen_rtx_CONST (Pmode
, addr_location
);
8661 /* Unless we can use the bras(l) insn, force the
8662 routine address into a register. */
8663 if (!TARGET_SMALL_EXEC
&& !TARGET_CPU_ZARCH
)
8666 addr_location
= legitimize_pic_address (addr_location
, 0);
8668 addr_location
= force_reg (Pmode
, addr_location
);
8672 /* If it is already an indirect call or the code above moved the
8673 SYMBOL_REF to somewhere else make sure the address can be found in
8675 if (retaddr_reg
== NULL_RTX
8676 && GET_CODE (addr_location
) != SYMBOL_REF
8679 emit_move_insn (gen_rtx_REG (Pmode
, SIBCALL_REGNUM
), addr_location
);
8680 addr_location
= gen_rtx_REG (Pmode
, SIBCALL_REGNUM
);
8683 addr_location
= gen_rtx_MEM (QImode
, addr_location
);
8684 call
= gen_rtx_CALL (VOIDmode
, addr_location
, const0_rtx
);
8686 if (result_reg
!= NULL_RTX
)
8687 call
= gen_rtx_SET (VOIDmode
, result_reg
, call
);
8689 if (retaddr_reg
!= NULL_RTX
)
8691 clobber
= gen_rtx_CLOBBER (VOIDmode
, retaddr_reg
);
8693 if (tls_call
!= NULL_RTX
)
8694 vec
= gen_rtvec (3, call
, clobber
,
8695 gen_rtx_USE (VOIDmode
, tls_call
));
8697 vec
= gen_rtvec (2, call
, clobber
);
8699 call
= gen_rtx_PARALLEL (VOIDmode
, vec
);
8702 insn
= emit_call_insn (call
);
8704 /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
8705 if ((!TARGET_64BIT
&& plt_call
) || tls_call
!= NULL_RTX
)
8707 /* s390_function_ok_for_sibcall should
8708 have denied sibcalls in this case. */
8709 gcc_assert (retaddr_reg
!= NULL_RTX
);
8711 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), pic_offset_table_rtx
);
8716 /* Implement CONDITIONAL_REGISTER_USAGE. */
8719 s390_conditional_register_usage (void)
8725 fixed_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
8726 call_used_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
8728 if (TARGET_CPU_ZARCH
)
8730 fixed_regs
[BASE_REGNUM
] = 0;
8731 call_used_regs
[BASE_REGNUM
] = 0;
8732 fixed_regs
[RETURN_REGNUM
] = 0;
8733 call_used_regs
[RETURN_REGNUM
] = 0;
8737 for (i
= 24; i
< 32; i
++)
8738 call_used_regs
[i
] = call_really_used_regs
[i
] = 0;
8742 for (i
= 18; i
< 20; i
++)
8743 call_used_regs
[i
] = call_really_used_regs
[i
] = 0;
8746 if (TARGET_SOFT_FLOAT
)
8748 for (i
= 16; i
< 32; i
++)
8749 call_used_regs
[i
] = fixed_regs
[i
] = 1;
8753 /* Corresponding function to eh_return expander. */
8755 static GTY(()) rtx s390_tpf_eh_return_symbol
;
8757 s390_emit_tpf_eh_return (rtx target
)
8761 if (!s390_tpf_eh_return_symbol
)
8762 s390_tpf_eh_return_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "__tpf_eh_return");
8764 reg
= gen_rtx_REG (Pmode
, 2);
8766 emit_move_insn (reg
, target
);
8767 insn
= s390_emit_call (s390_tpf_eh_return_symbol
, NULL_RTX
, reg
,
8768 gen_rtx_REG (Pmode
, RETURN_REGNUM
));
8769 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), reg
);
8771 emit_move_insn (EH_RETURN_HANDLER_RTX
, reg
);
8774 /* Rework the prologue/epilogue to avoid saving/restoring
8775 registers unnecessarily. */
8778 s390_optimize_prologue (void)
8780 rtx insn
, new_insn
, next_insn
;
8782 /* Do a final recompute of the frame-related data. */
8784 s390_update_frame_layout ();
8786 /* If all special registers are in fact used, there's nothing we
8787 can do, so no point in walking the insn list. */
8789 if (cfun_frame_layout
.first_save_gpr
<= BASE_REGNUM
8790 && cfun_frame_layout
.last_save_gpr
>= BASE_REGNUM
8791 && (TARGET_CPU_ZARCH
8792 || (cfun_frame_layout
.first_save_gpr
<= RETURN_REGNUM
8793 && cfun_frame_layout
.last_save_gpr
>= RETURN_REGNUM
)))
8796 /* Search for prologue/epilogue insns and replace them. */
8798 for (insn
= get_insns (); insn
; insn
= next_insn
)
8800 int first
, last
, off
;
8801 rtx set
, base
, offset
;
8803 next_insn
= NEXT_INSN (insn
);
8805 if (GET_CODE (insn
) != INSN
)
8808 if (GET_CODE (PATTERN (insn
)) == PARALLEL
8809 && store_multiple_operation (PATTERN (insn
), VOIDmode
))
8811 set
= XVECEXP (PATTERN (insn
), 0, 0);
8812 first
= REGNO (SET_SRC (set
));
8813 last
= first
+ XVECLEN (PATTERN (insn
), 0) - 1;
8814 offset
= const0_rtx
;
8815 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
8816 off
= INTVAL (offset
);
8818 if (GET_CODE (base
) != REG
|| off
< 0)
8820 if (cfun_frame_layout
.first_save_gpr
!= -1
8821 && (cfun_frame_layout
.first_save_gpr
< first
8822 || cfun_frame_layout
.last_save_gpr
> last
))
8824 if (REGNO (base
) != STACK_POINTER_REGNUM
8825 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
8827 if (first
> BASE_REGNUM
|| last
< BASE_REGNUM
)
8830 if (cfun_frame_layout
.first_save_gpr
!= -1)
8832 new_insn
= save_gprs (base
,
8833 off
+ (cfun_frame_layout
.first_save_gpr
8834 - first
) * UNITS_PER_WORD
,
8835 cfun_frame_layout
.first_save_gpr
,
8836 cfun_frame_layout
.last_save_gpr
);
8837 new_insn
= emit_insn_before (new_insn
, insn
);
8838 INSN_ADDRESSES_NEW (new_insn
, -1);
8845 if (cfun_frame_layout
.first_save_gpr
== -1
8846 && GET_CODE (PATTERN (insn
)) == SET
8847 && GET_CODE (SET_SRC (PATTERN (insn
))) == REG
8848 && (REGNO (SET_SRC (PATTERN (insn
))) == BASE_REGNUM
8849 || (!TARGET_CPU_ZARCH
8850 && REGNO (SET_SRC (PATTERN (insn
))) == RETURN_REGNUM
))
8851 && GET_CODE (SET_DEST (PATTERN (insn
))) == MEM
)
8853 set
= PATTERN (insn
);
8854 first
= REGNO (SET_SRC (set
));
8855 offset
= const0_rtx
;
8856 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
8857 off
= INTVAL (offset
);
8859 if (GET_CODE (base
) != REG
|| off
< 0)
8861 if (REGNO (base
) != STACK_POINTER_REGNUM
8862 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
8869 if (GET_CODE (PATTERN (insn
)) == PARALLEL
8870 && load_multiple_operation (PATTERN (insn
), VOIDmode
))
8872 set
= XVECEXP (PATTERN (insn
), 0, 0);
8873 first
= REGNO (SET_DEST (set
));
8874 last
= first
+ XVECLEN (PATTERN (insn
), 0) - 1;
8875 offset
= const0_rtx
;
8876 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
8877 off
= INTVAL (offset
);
8879 if (GET_CODE (base
) != REG
|| off
< 0)
8881 if (cfun_frame_layout
.first_restore_gpr
!= -1
8882 && (cfun_frame_layout
.first_restore_gpr
< first
8883 || cfun_frame_layout
.last_restore_gpr
> last
))
8885 if (REGNO (base
) != STACK_POINTER_REGNUM
8886 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
8888 if (first
> BASE_REGNUM
|| last
< BASE_REGNUM
)
8891 if (cfun_frame_layout
.first_restore_gpr
!= -1)
8893 new_insn
= restore_gprs (base
,
8894 off
+ (cfun_frame_layout
.first_restore_gpr
8895 - first
) * UNITS_PER_WORD
,
8896 cfun_frame_layout
.first_restore_gpr
,
8897 cfun_frame_layout
.last_restore_gpr
);
8898 new_insn
= emit_insn_before (new_insn
, insn
);
8899 INSN_ADDRESSES_NEW (new_insn
, -1);
8906 if (cfun_frame_layout
.first_restore_gpr
== -1
8907 && GET_CODE (PATTERN (insn
)) == SET
8908 && GET_CODE (SET_DEST (PATTERN (insn
))) == REG
8909 && (REGNO (SET_DEST (PATTERN (insn
))) == BASE_REGNUM
8910 || (!TARGET_CPU_ZARCH
8911 && REGNO (SET_DEST (PATTERN (insn
))) == RETURN_REGNUM
))
8912 && GET_CODE (SET_SRC (PATTERN (insn
))) == MEM
)
8914 set
= PATTERN (insn
);
8915 first
= REGNO (SET_DEST (set
));
8916 offset
= const0_rtx
;
8917 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
8918 off
= INTVAL (offset
);
8920 if (GET_CODE (base
) != REG
|| off
< 0)
8922 if (REGNO (base
) != STACK_POINTER_REGNUM
8923 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
8932 /* Perform machine-dependent processing. */
8937 bool pool_overflow
= false;
8939 /* Make sure all splits have been performed; splits after
8940 machine_dependent_reorg might confuse insn length counts. */
8941 split_all_insns_noflow ();
8943 /* From here on decomposed literal pool addresses must be accepted. */
8944 cfun
->machine
->decomposed_literal_pool_addresses_ok_p
= true;
8946 /* Install the main literal pool and the associated base
8947 register load insns.
8949 In addition, there are two problematic situations we need
8952 - the literal pool might be > 4096 bytes in size, so that
8953 some of its elements cannot be directly accessed
8955 - a branch target might be > 64K away from the branch, so that
8956 it is not possible to use a PC-relative instruction.
8958 To fix those, we split the single literal pool into multiple
8959 pool chunks, reloading the pool base register at various
8960 points throughout the function to ensure it always points to
8961 the pool chunk the following code expects, and / or replace
8962 PC-relative branches by absolute branches.
8964 However, the two problems are interdependent: splitting the
8965 literal pool can move a branch further away from its target,
8966 causing the 64K limit to overflow, and on the other hand,
8967 replacing a PC-relative branch by an absolute branch means
8968 we need to put the branch target address into the literal
8969 pool, possibly causing it to overflow.
8971 So, we loop trying to fix up both problems until we manage
8972 to satisfy both conditions at the same time. Note that the
8973 loop is guaranteed to terminate as every pass of the loop
8974 strictly decreases the total number of PC-relative branches
8975 in the function. (This is not completely true as there
8976 might be branch-over-pool insns introduced by chunkify_start.
8977 Those never need to be split however.) */
8981 struct constant_pool
*pool
= NULL
;
8983 /* Collect the literal pool. */
8986 pool
= s390_mainpool_start ();
8988 pool_overflow
= true;
8991 /* If literal pool overflowed, start to chunkify it. */
8993 pool
= s390_chunkify_start ();
8995 /* Split out-of-range branches. If this has created new
8996 literal pool entries, cancel current chunk list and
8997 recompute it. zSeries machines have large branch
8998 instructions, so we never need to split a branch. */
8999 if (!TARGET_CPU_ZARCH
&& s390_split_branches ())
9002 s390_chunkify_cancel (pool
);
9004 s390_mainpool_cancel (pool
);
9009 /* If we made it up to here, both conditions are satisfied.
9010 Finish up literal pool related changes. */
9012 s390_chunkify_finish (pool
);
9014 s390_mainpool_finish (pool
);
9016 /* We're done splitting branches. */
9017 cfun
->machine
->split_branches_pending_p
= false;
9021 /* Generate out-of-pool execute target insns. */
9022 if (TARGET_CPU_ZARCH
)
9024 rtx insn
, label
, target
;
9026 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
9028 label
= s390_execute_label (insn
);
9032 gcc_assert (label
!= const0_rtx
);
9034 target
= emit_label (XEXP (label
, 0));
9035 INSN_ADDRESSES_NEW (target
, -1);
9037 target
= emit_insn (s390_execute_target (insn
));
9038 INSN_ADDRESSES_NEW (target
, -1);
9042 /* Try to optimize prologue and epilogue further. */
9043 s390_optimize_prologue ();
9047 /* Initialize GCC target structure. */
9049 #undef TARGET_ASM_ALIGNED_HI_OP
9050 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
9051 #undef TARGET_ASM_ALIGNED_DI_OP
9052 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
9053 #undef TARGET_ASM_INTEGER
9054 #define TARGET_ASM_INTEGER s390_assemble_integer
9056 #undef TARGET_ASM_OPEN_PAREN
9057 #define TARGET_ASM_OPEN_PAREN ""
9059 #undef TARGET_ASM_CLOSE_PAREN
9060 #define TARGET_ASM_CLOSE_PAREN ""
9062 #undef TARGET_DEFAULT_TARGET_FLAGS
9063 #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD)
9064 #undef TARGET_HANDLE_OPTION
9065 #define TARGET_HANDLE_OPTION s390_handle_option
9067 #undef TARGET_ENCODE_SECTION_INFO
9068 #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
9071 #undef TARGET_HAVE_TLS
9072 #define TARGET_HAVE_TLS true
9074 #undef TARGET_CANNOT_FORCE_CONST_MEM
9075 #define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
9077 #undef TARGET_DELEGITIMIZE_ADDRESS
9078 #define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
9080 #undef TARGET_RETURN_IN_MEMORY
9081 #define TARGET_RETURN_IN_MEMORY s390_return_in_memory
9083 #undef TARGET_INIT_BUILTINS
9084 #define TARGET_INIT_BUILTINS s390_init_builtins
9085 #undef TARGET_EXPAND_BUILTIN
9086 #define TARGET_EXPAND_BUILTIN s390_expand_builtin
9088 #undef TARGET_ASM_OUTPUT_MI_THUNK
9089 #define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
9090 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
9091 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
9093 #undef TARGET_SCHED_ADJUST_PRIORITY
9094 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
9095 #undef TARGET_SCHED_ISSUE_RATE
9096 #define TARGET_SCHED_ISSUE_RATE s390_issue_rate
9097 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
9098 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
9100 #undef TARGET_CANNOT_COPY_INSN_P
9101 #define TARGET_CANNOT_COPY_INSN_P s390_cannot_copy_insn_p
9102 #undef TARGET_RTX_COSTS
9103 #define TARGET_RTX_COSTS s390_rtx_costs
9104 #undef TARGET_ADDRESS_COST
9105 #define TARGET_ADDRESS_COST s390_address_cost
9107 #undef TARGET_MACHINE_DEPENDENT_REORG
9108 #define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
9110 #undef TARGET_VALID_POINTER_MODE
9111 #define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
9113 #undef TARGET_BUILD_BUILTIN_VA_LIST
9114 #define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
9115 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
9116 #define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg
9118 #undef TARGET_PROMOTE_FUNCTION_ARGS
9119 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
9120 #undef TARGET_PROMOTE_FUNCTION_RETURN
9121 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
9122 #undef TARGET_PASS_BY_REFERENCE
9123 #define TARGET_PASS_BY_REFERENCE s390_pass_by_reference
9125 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
9126 #define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
9128 #undef TARGET_FIXED_CONDITION_CODE_REGS
9129 #define TARGET_FIXED_CONDITION_CODE_REGS s390_fixed_condition_code_regs
9131 #undef TARGET_CC_MODES_COMPATIBLE
9132 #define TARGET_CC_MODES_COMPATIBLE s390_cc_modes_compatible
9134 #undef TARGET_INVALID_WITHIN_DOLOOP
9135 #define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_rtx_null
9138 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
9139 #define TARGET_ASM_OUTPUT_DWARF_DTPREL s390_output_dwarf_dtprel
9142 struct gcc_target targetm
= TARGET_INITIALIZER
;
9144 #include "gt-s390.h"