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. */
214 /* Which cpu are we tuning for. */
215 enum processor_type s390_tune
= PROCESSOR_max
;
216 enum processor_flags s390_tune_flags
;
217 /* Which instruction set architecture to use. */
218 enum processor_type s390_arch
;
219 enum processor_flags s390_arch_flags
;
221 HOST_WIDE_INT s390_warn_framesize
= 0;
222 HOST_WIDE_INT s390_stack_size
= 0;
223 HOST_WIDE_INT s390_stack_guard
= 0;
225 /* The following structure is embedded in the machine
226 specific part of struct function. */
228 struct s390_frame_layout
GTY (())
230 /* Offset within stack frame. */
231 HOST_WIDE_INT gprs_offset
;
232 HOST_WIDE_INT f0_offset
;
233 HOST_WIDE_INT f4_offset
;
234 HOST_WIDE_INT f8_offset
;
235 HOST_WIDE_INT backchain_offset
;
237 /* Number of first and last gpr where slots in the register
238 save area are reserved for. */
239 int first_save_gpr_slot
;
240 int last_save_gpr_slot
;
242 /* Number of first and last gpr to be saved, restored. */
244 int first_restore_gpr
;
246 int last_restore_gpr
;
248 /* Bits standing for floating point registers. Set, if the
249 respective register has to be saved. Starting with reg 16 (f0)
250 at the rightmost bit.
251 Bit 15 - 8 7 6 5 4 3 2 1 0
252 fpr 15 - 8 7 5 3 1 6 4 2 0
253 reg 31 - 24 23 22 21 20 19 18 17 16 */
254 unsigned int fpr_bitmap
;
256 /* Number of floating point registers f8-f15 which must be saved. */
259 /* Set if return address needs to be saved.
260 This flag is set by s390_return_addr_rtx if it could not use
261 the initial value of r14 and therefore depends on r14 saved
263 bool save_return_addr_p
;
265 /* Size of stack frame. */
266 HOST_WIDE_INT frame_size
;
269 /* Define the structure for the machine field in struct function. */
271 struct machine_function
GTY(())
273 struct s390_frame_layout frame_layout
;
275 /* Literal pool base register. */
278 /* True if we may need to perform branch splitting. */
279 bool split_branches_pending_p
;
281 /* Some local-dynamic TLS symbol name. */
282 const char *some_ld_name
;
284 bool has_landing_pad_p
;
287 /* Few accessor macros for struct cfun->machine->s390_frame_layout. */
289 #define cfun_frame_layout (cfun->machine->frame_layout)
290 #define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)
291 #define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr_slot - \
292 cfun_frame_layout.first_save_gpr_slot + 1) * UNITS_PER_WORD)
293 #define cfun_set_fpr_bit(BITNUM) (cfun->machine->frame_layout.fpr_bitmap |= \
295 #define cfun_fpr_bit_p(BITNUM) (!!(cfun->machine->frame_layout.fpr_bitmap & \
298 /* Number of GPRs and FPRs used for argument passing. */
299 #define GP_ARG_NUM_REG 5
300 #define FP_ARG_NUM_REG (TARGET_64BIT? 4 : 2)
302 /* A couple of shortcuts. */
303 #define CONST_OK_FOR_J(x) \
304 CONST_OK_FOR_CONSTRAINT_P((x), 'J', "J")
305 #define CONST_OK_FOR_K(x) \
306 CONST_OK_FOR_CONSTRAINT_P((x), 'K', "K")
307 #define CONST_OK_FOR_Os(x) \
308 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Os")
309 #define CONST_OK_FOR_Op(x) \
310 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "Op")
311 #define CONST_OK_FOR_On(x) \
312 CONST_OK_FOR_CONSTRAINT_P((x), 'O', "On")
314 /* Set the has_landing_pad_p flag in struct machine_function to VALUE. */
317 s390_set_has_landing_pad_p (bool value
)
319 cfun
->machine
->has_landing_pad_p
= value
;
322 /* If two condition code modes are compatible, return a condition code
323 mode which is compatible with both. Otherwise, return
326 static enum machine_mode
327 s390_cc_modes_compatible (enum machine_mode m1
, enum machine_mode m2
)
335 if (m2
== CCUmode
|| m2
== CCTmode
|| m2
== CCZ1mode
336 || m2
== CCSmode
|| m2
== CCSRmode
|| m2
== CCURmode
)
357 /* Return true if SET either doesn't set the CC register, or else
358 the source and destination have matching CC modes and that
359 CC mode is at least as constrained as REQ_MODE. */
362 s390_match_ccmode_set (rtx set
, enum machine_mode req_mode
)
364 enum machine_mode set_mode
;
366 gcc_assert (GET_CODE (set
) == SET
);
368 if (GET_CODE (SET_DEST (set
)) != REG
|| !CC_REGNO_P (REGNO (SET_DEST (set
))))
371 set_mode
= GET_MODE (SET_DEST (set
));
385 if (req_mode
!= set_mode
)
390 if (req_mode
!= CCSmode
&& req_mode
!= CCUmode
&& req_mode
!= CCTmode
391 && req_mode
!= CCSRmode
&& req_mode
!= CCURmode
)
397 if (req_mode
!= CCAmode
)
405 return (GET_MODE (SET_SRC (set
)) == set_mode
);
408 /* Return true if every SET in INSN that sets the CC register
409 has source and destination with matching CC modes and that
410 CC mode is at least as constrained as REQ_MODE.
411 If REQ_MODE is VOIDmode, always return false. */
414 s390_match_ccmode (rtx insn
, enum machine_mode req_mode
)
418 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
419 if (req_mode
== VOIDmode
)
422 if (GET_CODE (PATTERN (insn
)) == SET
)
423 return s390_match_ccmode_set (PATTERN (insn
), req_mode
);
425 if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
426 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
428 rtx set
= XVECEXP (PATTERN (insn
), 0, i
);
429 if (GET_CODE (set
) == SET
)
430 if (!s390_match_ccmode_set (set
, req_mode
))
437 /* If a test-under-mask instruction can be used to implement
438 (compare (and ... OP1) OP2), return the CC mode required
439 to do that. Otherwise, return VOIDmode.
440 MIXED is true if the instruction can distinguish between
441 CC1 and CC2 for mixed selected bits (TMxx), it is false
442 if the instruction cannot (TM). */
445 s390_tm_ccmode (rtx op1
, rtx op2
, bool mixed
)
449 /* ??? Fixme: should work on CONST_DOUBLE as well. */
450 if (GET_CODE (op1
) != CONST_INT
|| GET_CODE (op2
) != CONST_INT
)
453 /* Selected bits all zero: CC0.
454 e.g.: int a; if ((a & (16 + 128)) == 0) */
455 if (INTVAL (op2
) == 0)
458 /* Selected bits all one: CC3.
459 e.g.: int a; if ((a & (16 + 128)) == 16 + 128) */
460 if (INTVAL (op2
) == INTVAL (op1
))
463 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. e.g.:
465 if ((a & (16 + 128)) == 16) -> CCT1
466 if ((a & (16 + 128)) == 128) -> CCT2 */
469 bit1
= exact_log2 (INTVAL (op2
));
470 bit0
= exact_log2 (INTVAL (op1
) ^ INTVAL (op2
));
471 if (bit0
!= -1 && bit1
!= -1)
472 return bit0
> bit1
? CCT1mode
: CCT2mode
;
478 /* Given a comparison code OP (EQ, NE, etc.) and the operands
479 OP0 and OP1 of a COMPARE, return the mode to be used for the
483 s390_select_ccmode (enum rtx_code code
, rtx op0
, rtx op1
)
489 if ((GET_CODE (op0
) == NEG
|| GET_CODE (op0
) == ABS
)
490 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
492 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
493 && CONST_OK_FOR_K (INTVAL (XEXP (op0
, 1))))
495 if ((GET_CODE (op0
) == PLUS
|| GET_CODE (op0
) == MINUS
496 || GET_CODE (op1
) == NEG
)
497 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
500 if (GET_CODE (op0
) == AND
)
502 /* Check whether we can potentially do it via TM. */
503 enum machine_mode ccmode
;
504 ccmode
= s390_tm_ccmode (XEXP (op0
, 1), op1
, 1);
505 if (ccmode
!= VOIDmode
)
507 /* Relax CCTmode to CCZmode to allow fall-back to AND
508 if that turns out to be beneficial. */
509 return ccmode
== CCTmode
? CCZmode
: ccmode
;
513 if (register_operand (op0
, HImode
)
514 && GET_CODE (op1
) == CONST_INT
515 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 65535))
517 if (register_operand (op0
, QImode
)
518 && GET_CODE (op1
) == CONST_INT
519 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 255))
528 /* The only overflow condition of NEG and ABS happens when
529 -INT_MAX is used as parameter, which stays negative. So
530 we have an overflow from a positive value to a negative.
531 Using CCAP mode the resulting cc can be used for comparisons. */
532 if ((GET_CODE (op0
) == NEG
|| GET_CODE (op0
) == ABS
)
533 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
536 /* If constants are involved in an add instruction it is possible to use
537 the resulting cc for comparisons with zero. Knowing the sign of the
538 constant the overflow behavior gets predictable. e.g.:
539 int a, b; if ((b = a + c) > 0)
540 with c as a constant value: c < 0 -> CCAN and c >= 0 -> CCAP */
541 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
542 && CONST_OK_FOR_K (INTVAL (XEXP (op0
, 1))))
544 if (INTVAL (XEXP((op0
), 1)) < 0)
558 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
559 && GET_CODE (op1
) != CONST_INT
)
565 if (GET_CODE (op0
) == PLUS
566 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
569 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
570 && GET_CODE (op1
) != CONST_INT
)
576 if (GET_CODE (op0
) == MINUS
577 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
580 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
581 && GET_CODE (op1
) != CONST_INT
)
590 /* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
591 that we can implement more efficiently. */
594 s390_canonicalize_comparison (enum rtx_code
*code
, rtx
*op0
, rtx
*op1
)
596 /* Convert ZERO_EXTRACT back to AND to enable TM patterns. */
597 if ((*code
== EQ
|| *code
== NE
)
598 && *op1
== const0_rtx
599 && GET_CODE (*op0
) == ZERO_EXTRACT
600 && GET_CODE (XEXP (*op0
, 1)) == CONST_INT
601 && GET_CODE (XEXP (*op0
, 2)) == CONST_INT
602 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0
, 0))))
604 rtx inner
= XEXP (*op0
, 0);
605 HOST_WIDE_INT modesize
= GET_MODE_BITSIZE (GET_MODE (inner
));
606 HOST_WIDE_INT len
= INTVAL (XEXP (*op0
, 1));
607 HOST_WIDE_INT pos
= INTVAL (XEXP (*op0
, 2));
609 if (len
> 0 && len
< modesize
610 && pos
>= 0 && pos
+ len
<= modesize
611 && modesize
<= HOST_BITS_PER_WIDE_INT
)
613 unsigned HOST_WIDE_INT block
;
614 block
= ((unsigned HOST_WIDE_INT
) 1 << len
) - 1;
615 block
<<= modesize
- pos
- len
;
617 *op0
= gen_rtx_AND (GET_MODE (inner
), inner
,
618 gen_int_mode (block
, GET_MODE (inner
)));
622 /* Narrow AND of memory against immediate to enable TM. */
623 if ((*code
== EQ
|| *code
== NE
)
624 && *op1
== const0_rtx
625 && GET_CODE (*op0
) == AND
626 && GET_CODE (XEXP (*op0
, 1)) == CONST_INT
627 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0
, 0))))
629 rtx inner
= XEXP (*op0
, 0);
630 rtx mask
= XEXP (*op0
, 1);
632 /* Ignore paradoxical SUBREGs if all extra bits are masked out. */
633 if (GET_CODE (inner
) == SUBREG
634 && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (inner
)))
635 && (GET_MODE_SIZE (GET_MODE (inner
))
636 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner
))))
638 & GET_MODE_MASK (GET_MODE (inner
))
639 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (inner
))))
641 inner
= SUBREG_REG (inner
);
643 /* Do not change volatile MEMs. */
644 if (MEM_P (inner
) && !MEM_VOLATILE_P (inner
))
646 int part
= s390_single_part (XEXP (*op0
, 1),
647 GET_MODE (inner
), QImode
, 0);
650 mask
= gen_int_mode (s390_extract_part (mask
, QImode
, 0), QImode
);
651 inner
= adjust_address_nv (inner
, QImode
, part
);
652 *op0
= gen_rtx_AND (QImode
, inner
, mask
);
657 /* Narrow comparisons against 0xffff to HImode if possible. */
658 if ((*code
== EQ
|| *code
== NE
)
659 && GET_CODE (*op1
) == CONST_INT
660 && INTVAL (*op1
) == 0xffff
661 && SCALAR_INT_MODE_P (GET_MODE (*op0
))
662 && (nonzero_bits (*op0
, GET_MODE (*op0
))
663 & ~(unsigned HOST_WIDE_INT
) 0xffff) == 0)
665 *op0
= gen_lowpart (HImode
, *op0
);
670 /* Remove redundant UNSPEC_CMPINT conversions if possible. */
671 if (GET_CODE (*op0
) == UNSPEC
672 && XINT (*op0
, 1) == UNSPEC_CMPINT
673 && XVECLEN (*op0
, 0) == 1
674 && GET_MODE (XVECEXP (*op0
, 0, 0)) == CCUmode
675 && GET_CODE (XVECEXP (*op0
, 0, 0)) == REG
676 && REGNO (XVECEXP (*op0
, 0, 0)) == CC_REGNUM
677 && *op1
== const0_rtx
)
679 enum rtx_code new_code
= UNKNOWN
;
682 case EQ
: new_code
= EQ
; break;
683 case NE
: new_code
= NE
; break;
684 case LT
: new_code
= GTU
; break;
685 case GT
: new_code
= LTU
; break;
686 case LE
: new_code
= GEU
; break;
687 case GE
: new_code
= LEU
; break;
691 if (new_code
!= UNKNOWN
)
693 *op0
= XVECEXP (*op0
, 0, 0);
698 /* Simplify cascaded EQ, NE with const0_rtx. */
699 if ((*code
== NE
|| *code
== EQ
)
700 && (GET_CODE (*op0
) == EQ
|| GET_CODE (*op0
) == NE
)
701 && GET_MODE (*op0
) == SImode
702 && GET_MODE (XEXP (*op0
, 0)) == CCZ1mode
703 && REG_P (XEXP (*op0
, 0))
704 && XEXP (*op0
, 1) == const0_rtx
705 && *op1
== const0_rtx
)
707 if ((*code
== EQ
&& GET_CODE (*op0
) == NE
)
708 || (*code
== NE
&& GET_CODE (*op0
) == EQ
))
712 *op0
= XEXP (*op0
, 0);
715 /* Prefer register over memory as first operand. */
716 if (MEM_P (*op0
) && REG_P (*op1
))
718 rtx tem
= *op0
; *op0
= *op1
; *op1
= tem
;
719 *code
= swap_condition (*code
);
723 /* Emit a compare instruction suitable to implement the comparison
724 OP0 CODE OP1. Return the correct condition RTL to be placed in
725 the IF_THEN_ELSE of the conditional branch testing the result. */
728 s390_emit_compare (enum rtx_code code
, rtx op0
, rtx op1
)
730 enum machine_mode mode
= s390_select_ccmode (code
, op0
, op1
);
733 /* Do not output a redundant compare instruction if a compare_and_swap
734 pattern already computed the result and the machine modes are compatible. */
735 if (s390_compare_emitted
736 && (s390_cc_modes_compatible (GET_MODE (s390_compare_emitted
), mode
)
737 == GET_MODE (s390_compare_emitted
)))
738 ret
= gen_rtx_fmt_ee (code
, VOIDmode
, s390_compare_emitted
, const0_rtx
);
741 rtx cc
= gen_rtx_REG (mode
, CC_REGNUM
);
743 emit_insn (gen_rtx_SET (VOIDmode
, cc
, gen_rtx_COMPARE (mode
, op0
, op1
)));
744 ret
= gen_rtx_fmt_ee (code
, VOIDmode
, cc
, const0_rtx
);
746 s390_compare_emitted
= NULL_RTX
;
750 /* Emit a jump instruction to TARGET. If COND is NULL_RTX, emit an
751 unconditional jump, else a conditional jump under condition COND. */
754 s390_emit_jump (rtx target
, rtx cond
)
758 target
= gen_rtx_LABEL_REF (VOIDmode
, target
);
760 target
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, target
, pc_rtx
);
762 insn
= gen_rtx_SET (VOIDmode
, pc_rtx
, target
);
763 emit_jump_insn (insn
);
766 /* Return branch condition mask to implement a branch
767 specified by CODE. Return -1 for invalid comparisons. */
770 s390_branch_condition_mask (rtx code
)
772 const int CC0
= 1 << 3;
773 const int CC1
= 1 << 2;
774 const int CC2
= 1 << 1;
775 const int CC3
= 1 << 0;
777 gcc_assert (GET_CODE (XEXP (code
, 0)) == REG
);
778 gcc_assert (REGNO (XEXP (code
, 0)) == CC_REGNUM
);
779 gcc_assert (XEXP (code
, 1) == const0_rtx
);
781 switch (GET_MODE (XEXP (code
, 0)))
785 switch (GET_CODE (code
))
788 case NE
: return CC1
| CC2
| CC3
;
794 switch (GET_CODE (code
))
797 case NE
: return CC0
| CC2
| CC3
;
803 switch (GET_CODE (code
))
806 case NE
: return CC0
| CC1
| CC3
;
812 switch (GET_CODE (code
))
815 case NE
: return CC0
| CC1
| CC2
;
821 switch (GET_CODE (code
))
823 case EQ
: return CC0
| CC2
;
824 case NE
: return CC1
| CC3
;
830 switch (GET_CODE (code
))
832 case LTU
: return CC2
| CC3
; /* carry */
833 case GEU
: return CC0
| CC1
; /* no carry */
839 switch (GET_CODE (code
))
841 case GTU
: return CC0
| CC1
; /* borrow */
842 case LEU
: return CC2
| CC3
; /* no borrow */
848 switch (GET_CODE (code
))
850 case EQ
: return CC0
| CC2
;
851 case NE
: return CC1
| CC3
;
852 case LTU
: return CC1
;
853 case GTU
: return CC3
;
854 case LEU
: return CC1
| CC2
;
855 case GEU
: return CC2
| CC3
;
860 switch (GET_CODE (code
))
863 case NE
: return CC1
| CC2
| CC3
;
864 case LTU
: return CC1
;
865 case GTU
: return CC2
;
866 case LEU
: return CC0
| CC1
;
867 case GEU
: return CC0
| CC2
;
873 switch (GET_CODE (code
))
876 case NE
: return CC2
| CC1
| CC3
;
877 case LTU
: return CC2
;
878 case GTU
: return CC1
;
879 case LEU
: return CC0
| CC2
;
880 case GEU
: return CC0
| CC1
;
886 switch (GET_CODE (code
))
889 case NE
: return CC1
| CC2
| CC3
;
890 case LT
: return CC1
| CC3
;
892 case LE
: return CC0
| CC1
| CC3
;
893 case GE
: return CC0
| CC2
;
899 switch (GET_CODE (code
))
902 case NE
: return CC1
| CC2
| CC3
;
904 case GT
: return CC2
| CC3
;
905 case LE
: return CC0
| CC1
;
906 case GE
: return CC0
| CC2
| CC3
;
912 switch (GET_CODE (code
))
915 case NE
: return CC1
| CC2
| CC3
;
918 case LE
: return CC0
| CC1
;
919 case GE
: return CC0
| CC2
;
920 case UNORDERED
: return CC3
;
921 case ORDERED
: return CC0
| CC1
| CC2
;
922 case UNEQ
: return CC0
| CC3
;
923 case UNLT
: return CC1
| CC3
;
924 case UNGT
: return CC2
| CC3
;
925 case UNLE
: return CC0
| CC1
| CC3
;
926 case UNGE
: return CC0
| CC2
| CC3
;
927 case LTGT
: return CC1
| CC2
;
933 switch (GET_CODE (code
))
936 case NE
: return CC2
| CC1
| CC3
;
939 case LE
: return CC0
| CC2
;
940 case GE
: return CC0
| CC1
;
941 case UNORDERED
: return CC3
;
942 case ORDERED
: return CC0
| CC2
| CC1
;
943 case UNEQ
: return CC0
| CC3
;
944 case UNLT
: return CC2
| CC3
;
945 case UNGT
: return CC1
| CC3
;
946 case UNLE
: return CC0
| CC2
| CC3
;
947 case UNGE
: return CC0
| CC1
| CC3
;
948 case LTGT
: return CC2
| CC1
;
958 /* If INV is false, return assembler mnemonic string to implement
959 a branch specified by CODE. If INV is true, return mnemonic
960 for the corresponding inverted branch. */
963 s390_branch_condition_mnemonic (rtx code
, int inv
)
965 static const char *const mnemonic
[16] =
967 NULL
, "o", "h", "nle",
968 "l", "nhe", "lh", "ne",
969 "e", "nlh", "he", "nl",
970 "le", "nh", "no", NULL
973 int mask
= s390_branch_condition_mask (code
);
974 gcc_assert (mask
>= 0);
979 gcc_assert (mask
>= 1 && mask
<= 14);
981 return mnemonic
[mask
];
984 /* Return the part of op which has a value different from def.
985 The size of the part is determined by mode.
986 Use this function only if you already know that op really
987 contains such a part. */
989 unsigned HOST_WIDE_INT
990 s390_extract_part (rtx op
, enum machine_mode mode
, int def
)
992 unsigned HOST_WIDE_INT value
= 0;
993 int max_parts
= HOST_BITS_PER_WIDE_INT
/ GET_MODE_BITSIZE (mode
);
994 int part_bits
= GET_MODE_BITSIZE (mode
);
995 unsigned HOST_WIDE_INT part_mask
996 = ((unsigned HOST_WIDE_INT
)1 << part_bits
) - 1;
999 for (i
= 0; i
< max_parts
; i
++)
1002 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
1004 value
>>= part_bits
;
1006 if ((value
& part_mask
) != (def
& part_mask
))
1007 return value
& part_mask
;
1013 /* If OP is an integer constant of mode MODE with exactly one
1014 part of mode PART_MODE unequal to DEF, return the number of that
1015 part. Otherwise, return -1. */
1018 s390_single_part (rtx op
,
1019 enum machine_mode mode
,
1020 enum machine_mode part_mode
,
1023 unsigned HOST_WIDE_INT value
= 0;
1024 int n_parts
= GET_MODE_SIZE (mode
) / GET_MODE_SIZE (part_mode
);
1025 unsigned HOST_WIDE_INT part_mask
1026 = ((unsigned HOST_WIDE_INT
)1 << GET_MODE_BITSIZE (part_mode
)) - 1;
1029 if (GET_CODE (op
) != CONST_INT
)
1032 for (i
= 0; i
< n_parts
; i
++)
1035 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
1037 value
>>= GET_MODE_BITSIZE (part_mode
);
1039 if ((value
& part_mask
) != (def
& part_mask
))
1047 return part
== -1 ? -1 : n_parts
- 1 - part
;
1050 /* Check whether we can (and want to) split a double-word
1051 move in mode MODE from SRC to DST into two single-word
1052 moves, moving the subword FIRST_SUBWORD first. */
1055 s390_split_ok_p (rtx dst
, rtx src
, enum machine_mode mode
, int first_subword
)
1057 /* Floating point registers cannot be split. */
1058 if (FP_REG_P (src
) || FP_REG_P (dst
))
1061 /* We don't need to split if operands are directly accessible. */
1062 if (s_operand (src
, mode
) || s_operand (dst
, mode
))
1065 /* Non-offsettable memory references cannot be split. */
1066 if ((GET_CODE (src
) == MEM
&& !offsettable_memref_p (src
))
1067 || (GET_CODE (dst
) == MEM
&& !offsettable_memref_p (dst
)))
1070 /* Moving the first subword must not clobber a register
1071 needed to move the second subword. */
1072 if (register_operand (dst
, mode
))
1074 rtx subreg
= operand_subword (dst
, first_subword
, 0, mode
);
1075 if (reg_overlap_mentioned_p (subreg
, src
))
1082 /* Return true if it can be proven that [MEM1, MEM1 + SIZE]
1083 and [MEM2, MEM2 + SIZE] do overlap and false
1087 s390_overlap_p (rtx mem1
, rtx mem2
, HOST_WIDE_INT size
)
1089 rtx addr1
, addr2
, addr_delta
;
1090 HOST_WIDE_INT delta
;
1092 if (GET_CODE (mem1
) != MEM
|| GET_CODE (mem2
) != MEM
)
1098 addr1
= XEXP (mem1
, 0);
1099 addr2
= XEXP (mem2
, 0);
1101 addr_delta
= simplify_binary_operation (MINUS
, Pmode
, addr2
, addr1
);
1103 /* This overlapping check is used by peepholes merging memory block operations.
1104 Overlapping operations would otherwise be recognized by the S/390 hardware
1105 and would fall back to a slower implementation. Allowing overlapping
1106 operations would lead to slow code but not to wrong code. Therefore we are
1107 somewhat optimistic if we cannot prove that the memory blocks are
1109 That's why we return false here although this may accept operations on
1110 overlapping memory areas. */
1111 if (!addr_delta
|| GET_CODE (addr_delta
) != CONST_INT
)
1114 delta
= INTVAL (addr_delta
);
1117 || (delta
> 0 && delta
< size
)
1118 || (delta
< 0 && -delta
< size
))
1124 /* Check whether the address of memory reference MEM2 equals exactly
1125 the address of memory reference MEM1 plus DELTA. Return true if
1126 we can prove this to be the case, false otherwise. */
1129 s390_offset_p (rtx mem1
, rtx mem2
, rtx delta
)
1131 rtx addr1
, addr2
, addr_delta
;
1133 if (GET_CODE (mem1
) != MEM
|| GET_CODE (mem2
) != MEM
)
1136 addr1
= XEXP (mem1
, 0);
1137 addr2
= XEXP (mem2
, 0);
1139 addr_delta
= simplify_binary_operation (MINUS
, Pmode
, addr2
, addr1
);
1140 if (!addr_delta
|| !rtx_equal_p (addr_delta
, delta
))
1146 /* Expand logical operator CODE in mode MODE with operands OPERANDS. */
1149 s390_expand_logical_operator (enum rtx_code code
, enum machine_mode mode
,
1152 enum machine_mode wmode
= mode
;
1153 rtx dst
= operands
[0];
1154 rtx src1
= operands
[1];
1155 rtx src2
= operands
[2];
1158 /* If we cannot handle the operation directly, use a temp register. */
1159 if (!s390_logical_operator_ok_p (operands
))
1160 dst
= gen_reg_rtx (mode
);
1162 /* QImode and HImode patterns make sense only if we have a destination
1163 in memory. Otherwise perform the operation in SImode. */
1164 if ((mode
== QImode
|| mode
== HImode
) && GET_CODE (dst
) != MEM
)
1167 /* Widen operands if required. */
1170 if (GET_CODE (dst
) == SUBREG
1171 && (tem
= simplify_subreg (wmode
, dst
, mode
, 0)) != 0)
1173 else if (REG_P (dst
))
1174 dst
= gen_rtx_SUBREG (wmode
, dst
, 0);
1176 dst
= gen_reg_rtx (wmode
);
1178 if (GET_CODE (src1
) == SUBREG
1179 && (tem
= simplify_subreg (wmode
, src1
, mode
, 0)) != 0)
1181 else if (GET_MODE (src1
) != VOIDmode
)
1182 src1
= gen_rtx_SUBREG (wmode
, force_reg (mode
, src1
), 0);
1184 if (GET_CODE (src2
) == SUBREG
1185 && (tem
= simplify_subreg (wmode
, src2
, mode
, 0)) != 0)
1187 else if (GET_MODE (src2
) != VOIDmode
)
1188 src2
= gen_rtx_SUBREG (wmode
, force_reg (mode
, src2
), 0);
1191 /* Emit the instruction. */
1192 op
= gen_rtx_SET (VOIDmode
, dst
, gen_rtx_fmt_ee (code
, wmode
, src1
, src2
));
1193 clob
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
1194 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, op
, clob
)));
1196 /* Fix up the destination if needed. */
1197 if (dst
!= operands
[0])
1198 emit_move_insn (operands
[0], gen_lowpart (mode
, dst
));
1201 /* Check whether OPERANDS are OK for a logical operation (AND, IOR, XOR). */
1204 s390_logical_operator_ok_p (rtx
*operands
)
1206 /* If the destination operand is in memory, it needs to coincide
1207 with one of the source operands. After reload, it has to be
1208 the first source operand. */
1209 if (GET_CODE (operands
[0]) == MEM
)
1210 return rtx_equal_p (operands
[0], operands
[1])
1211 || (!reload_completed
&& rtx_equal_p (operands
[0], operands
[2]));
1216 /* Narrow logical operation CODE of memory operand MEMOP with immediate
1217 operand IMMOP to switch from SS to SI type instructions. */
1220 s390_narrow_logical_operator (enum rtx_code code
, rtx
*memop
, rtx
*immop
)
1222 int def
= code
== AND
? -1 : 0;
1226 gcc_assert (GET_CODE (*memop
) == MEM
);
1227 gcc_assert (!MEM_VOLATILE_P (*memop
));
1229 mask
= s390_extract_part (*immop
, QImode
, def
);
1230 part
= s390_single_part (*immop
, GET_MODE (*memop
), QImode
, def
);
1231 gcc_assert (part
>= 0);
1233 *memop
= adjust_address (*memop
, QImode
, part
);
1234 *immop
= gen_int_mode (mask
, QImode
);
1238 /* How to allocate a 'struct machine_function'. */
1240 static struct machine_function
*
1241 s390_init_machine_status (void)
1243 return ggc_alloc_cleared (sizeof (struct machine_function
));
1246 /* Change optimizations to be performed, depending on the
1249 LEVEL is the optimization level specified; 2 if `-O2' is
1250 specified, 1 if `-O' is specified, and 0 if neither is specified.
1252 SIZE is nonzero if `-Os' is specified and zero otherwise. */
1255 optimization_options (int level ATTRIBUTE_UNUSED
, int size ATTRIBUTE_UNUSED
)
1257 /* ??? There are apparently still problems with -fcaller-saves. */
1258 flag_caller_saves
= 0;
1260 /* By default, always emit DWARF-2 unwind info. This allows debugging
1261 without maintaining a stack frame back-chain. */
1262 flag_asynchronous_unwind_tables
= 1;
1264 /* Use MVCLE instructions to decrease code size if requested. */
1266 target_flags
|= MASK_MVCLE
;
1269 /* Return true if ARG is the name of a processor. Set *TYPE and *FLAGS
1270 to the associated processor_type and processor_flags if so. */
1273 s390_handle_arch_option (const char *arg
,
1274 enum processor_type
*type
,
1275 enum processor_flags
*flags
)
1279 const char *const name
; /* processor name or nickname. */
1280 const enum processor_type processor
;
1281 const enum processor_flags flags
;
1283 const processor_alias_table
[] =
1285 {"g5", PROCESSOR_9672_G5
, PF_IEEE_FLOAT
},
1286 {"g6", PROCESSOR_9672_G6
, PF_IEEE_FLOAT
},
1287 {"z900", PROCESSOR_2064_Z900
, PF_IEEE_FLOAT
| PF_ZARCH
},
1288 {"z990", PROCESSOR_2084_Z990
, PF_IEEE_FLOAT
| PF_ZARCH
1289 | PF_LONG_DISPLACEMENT
},
1290 {"z9-109", PROCESSOR_2094_Z9_109
, PF_IEEE_FLOAT
| PF_ZARCH
1291 | PF_LONG_DISPLACEMENT
| PF_EXTIMM
},
1295 for (i
= 0; i
< ARRAY_SIZE (processor_alias_table
); i
++)
1296 if (strcmp (arg
, processor_alias_table
[i
].name
) == 0)
1298 *type
= processor_alias_table
[i
].processor
;
1299 *flags
= processor_alias_table
[i
].flags
;
1305 /* Implement TARGET_HANDLE_OPTION. */
1308 s390_handle_option (size_t code
, const char *arg
, int value ATTRIBUTE_UNUSED
)
1313 return s390_handle_arch_option (arg
, &s390_arch
, &s390_arch_flags
);
1315 case OPT_mstack_guard_
:
1316 if (sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_stack_guard
) != 1)
1318 if (exact_log2 (s390_stack_guard
) == -1)
1319 error ("stack guard value must be an exact power of 2");
1322 case OPT_mstack_size_
:
1323 if (sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_stack_size
) != 1)
1325 if (exact_log2 (s390_stack_size
) == -1)
1326 error ("stack size must be an exact power of 2");
1330 return s390_handle_arch_option (arg
, &s390_tune
, &s390_tune_flags
);
1332 case OPT_mwarn_framesize_
:
1333 return sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_warn_framesize
) == 1;
1341 override_options (void)
1343 /* Set up function hooks. */
1344 init_machine_status
= s390_init_machine_status
;
1346 /* Architecture mode defaults according to ABI. */
1347 if (!(target_flags_explicit
& MASK_ZARCH
))
1350 target_flags
|= MASK_ZARCH
;
1352 target_flags
&= ~MASK_ZARCH
;
1355 /* Determine processor architectural level. */
1356 if (!s390_arch_string
)
1358 s390_arch_string
= TARGET_ZARCH
? "z900" : "g5";
1359 s390_handle_arch_option (s390_arch_string
, &s390_arch
, &s390_arch_flags
);
1362 /* Determine processor to tune for. */
1363 if (s390_tune
== PROCESSOR_max
)
1365 s390_tune
= s390_arch
;
1366 s390_tune_flags
= s390_arch_flags
;
1369 /* Sanity checks. */
1370 if (TARGET_ZARCH
&& !(s390_arch_flags
& PF_ZARCH
))
1371 error ("z/Architecture mode not supported on %s", s390_arch_string
);
1372 if (TARGET_64BIT
&& !TARGET_ZARCH
)
1373 error ("64-bit ABI not supported in ESA/390 mode");
1375 /* Set processor cost function. */
1376 if (s390_tune
== PROCESSOR_2094_Z9_109
)
1377 s390_cost
= &z9_109_cost
;
1378 else if (s390_tune
== PROCESSOR_2084_Z990
)
1379 s390_cost
= &z990_cost
;
1381 s390_cost
= &z900_cost
;
1383 if (TARGET_BACKCHAIN
&& TARGET_PACKED_STACK
&& TARGET_HARD_FLOAT
)
1384 error ("-mbackchain -mpacked-stack -mhard-float are not supported "
1387 if (s390_stack_size
)
1389 if (!s390_stack_guard
)
1390 error ("-mstack-size implies use of -mstack-guard");
1391 else if (s390_stack_guard
>= s390_stack_size
)
1392 error ("stack size must be greater than the stack guard value");
1393 else if (s390_stack_size
> 1 << 16)
1394 error ("stack size must not be greater than 64k");
1396 else if (s390_stack_guard
)
1397 error ("-mstack-guard implies use of -mstack-size");
1400 /* Map for smallest class containing reg regno. */
1402 const enum reg_class regclass_map
[FIRST_PSEUDO_REGISTER
] =
1403 { GENERAL_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1404 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1405 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1406 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1407 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1408 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1409 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1410 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1411 ADDR_REGS
, CC_REGS
, ADDR_REGS
, ADDR_REGS
,
1412 ACCESS_REGS
, ACCESS_REGS
1415 /* Return attribute type of insn. */
1417 static enum attr_type
1418 s390_safe_attr_type (rtx insn
)
1420 if (recog_memoized (insn
) >= 0)
1421 return get_attr_type (insn
);
1426 /* Return true if DISP is a valid short displacement. */
1429 s390_short_displacement (rtx disp
)
1431 /* No displacement is OK. */
1435 /* Integer displacement in range. */
1436 if (GET_CODE (disp
) == CONST_INT
)
1437 return INTVAL (disp
) >= 0 && INTVAL (disp
) < 4096;
1439 /* GOT offset is not OK, the GOT can be large. */
1440 if (GET_CODE (disp
) == CONST
1441 && GET_CODE (XEXP (disp
, 0)) == UNSPEC
1442 && (XINT (XEXP (disp
, 0), 1) == UNSPEC_GOT
1443 || XINT (XEXP (disp
, 0), 1) == UNSPEC_GOTNTPOFF
))
1446 /* All other symbolic constants are literal pool references,
1447 which are OK as the literal pool must be small. */
1448 if (GET_CODE (disp
) == CONST
)
1454 /* Decompose a RTL expression ADDR for a memory address into
1455 its components, returned in OUT.
1457 Returns false if ADDR is not a valid memory address, true
1458 otherwise. If OUT is NULL, don't return the components,
1459 but check for validity only.
1461 Note: Only addresses in canonical form are recognized.
1462 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
1463 canonical form so that they will be recognized. */
1466 s390_decompose_address (rtx addr
, struct s390_address
*out
)
1468 HOST_WIDE_INT offset
= 0;
1469 rtx base
= NULL_RTX
;
1470 rtx indx
= NULL_RTX
;
1471 rtx disp
= NULL_RTX
;
1473 bool pointer
= false;
1474 bool base_ptr
= false;
1475 bool indx_ptr
= false;
1477 /* Decompose address into base + index + displacement. */
1479 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == UNSPEC
)
1482 else if (GET_CODE (addr
) == PLUS
)
1484 rtx op0
= XEXP (addr
, 0);
1485 rtx op1
= XEXP (addr
, 1);
1486 enum rtx_code code0
= GET_CODE (op0
);
1487 enum rtx_code code1
= GET_CODE (op1
);
1489 if (code0
== REG
|| code0
== UNSPEC
)
1491 if (code1
== REG
|| code1
== UNSPEC
)
1493 indx
= op0
; /* index + base */
1499 base
= op0
; /* base + displacement */
1504 else if (code0
== PLUS
)
1506 indx
= XEXP (op0
, 0); /* index + base + disp */
1507 base
= XEXP (op0
, 1);
1518 disp
= addr
; /* displacement */
1520 /* Extract integer part of displacement. */
1524 if (GET_CODE (disp
) == CONST_INT
)
1526 offset
= INTVAL (disp
);
1529 else if (GET_CODE (disp
) == CONST
1530 && GET_CODE (XEXP (disp
, 0)) == PLUS
1531 && GET_CODE (XEXP (XEXP (disp
, 0), 1)) == CONST_INT
)
1533 offset
= INTVAL (XEXP (XEXP (disp
, 0), 1));
1534 disp
= XEXP (XEXP (disp
, 0), 0);
1538 /* Strip off CONST here to avoid special case tests later. */
1539 if (disp
&& GET_CODE (disp
) == CONST
)
1540 disp
= XEXP (disp
, 0);
1542 /* We can convert literal pool addresses to
1543 displacements by basing them off the base register. */
1544 if (disp
&& GET_CODE (disp
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (disp
))
1546 /* Either base or index must be free to hold the base register. */
1548 base
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1550 indx
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1554 /* Mark up the displacement. */
1555 disp
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, disp
),
1556 UNSPEC_LTREL_OFFSET
);
1559 /* Validate base register. */
1562 if (GET_CODE (base
) == UNSPEC
)
1563 switch (XINT (base
, 1))
1567 disp
= gen_rtx_UNSPEC (Pmode
,
1568 gen_rtvec (1, XVECEXP (base
, 0, 0)),
1569 UNSPEC_LTREL_OFFSET
);
1573 base
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1576 case UNSPEC_LTREL_BASE
:
1577 base
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1584 if (GET_CODE (base
) != REG
|| GET_MODE (base
) != Pmode
)
1587 if (REGNO (base
) == BASE_REGNUM
1588 || REGNO (base
) == STACK_POINTER_REGNUM
1589 || REGNO (base
) == FRAME_POINTER_REGNUM
1590 || ((reload_completed
|| reload_in_progress
)
1591 && frame_pointer_needed
1592 && REGNO (base
) == HARD_FRAME_POINTER_REGNUM
)
1593 || REGNO (base
) == ARG_POINTER_REGNUM
1595 && REGNO (base
) == PIC_OFFSET_TABLE_REGNUM
))
1596 pointer
= base_ptr
= true;
1599 /* Validate index register. */
1602 if (GET_CODE (indx
) == UNSPEC
)
1603 switch (XINT (indx
, 1))
1607 disp
= gen_rtx_UNSPEC (Pmode
,
1608 gen_rtvec (1, XVECEXP (indx
, 0, 0)),
1609 UNSPEC_LTREL_OFFSET
);
1613 indx
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1616 case UNSPEC_LTREL_BASE
:
1617 indx
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1624 if (GET_CODE (indx
) != REG
|| GET_MODE (indx
) != Pmode
)
1627 if (REGNO (indx
) == BASE_REGNUM
1628 || REGNO (indx
) == STACK_POINTER_REGNUM
1629 || REGNO (indx
) == FRAME_POINTER_REGNUM
1630 || ((reload_completed
|| reload_in_progress
)
1631 && frame_pointer_needed
1632 && REGNO (indx
) == HARD_FRAME_POINTER_REGNUM
)
1633 || REGNO (indx
) == ARG_POINTER_REGNUM
1635 && REGNO (indx
) == PIC_OFFSET_TABLE_REGNUM
))
1636 pointer
= indx_ptr
= true;
1639 /* Prefer to use pointer as base, not index. */
1640 if (base
&& indx
&& !base_ptr
1641 && (indx_ptr
|| (!REG_POINTER (base
) && REG_POINTER (indx
))))
1648 /* Validate displacement. */
1651 /* If virtual registers are involved, the displacement will change later
1652 anyway as the virtual registers get eliminated. This could make a
1653 valid displacement invalid, but it is more likely to make an invalid
1654 displacement valid, because we sometimes access the register save area
1655 via negative offsets to one of those registers.
1656 Thus we don't check the displacement for validity here. If after
1657 elimination the displacement turns out to be invalid after all,
1658 this is fixed up by reload in any case. */
1659 if (base
!= arg_pointer_rtx
1660 && indx
!= arg_pointer_rtx
1661 && base
!= return_address_pointer_rtx
1662 && indx
!= return_address_pointer_rtx
1663 && base
!= frame_pointer_rtx
1664 && indx
!= frame_pointer_rtx
1665 && base
!= virtual_stack_vars_rtx
1666 && indx
!= virtual_stack_vars_rtx
)
1667 if (!DISP_IN_RANGE (offset
))
1672 /* All the special cases are pointers. */
1675 /* In the small-PIC case, the linker converts @GOT
1676 and @GOTNTPOFF offsets to possible displacements. */
1677 if (GET_CODE (disp
) == UNSPEC
1678 && (XINT (disp
, 1) == UNSPEC_GOT
1679 || XINT (disp
, 1) == UNSPEC_GOTNTPOFF
)
1686 /* Accept chunkified literal pool symbol references. */
1687 else if (GET_CODE (disp
) == MINUS
1688 && GET_CODE (XEXP (disp
, 0)) == LABEL_REF
1689 && GET_CODE (XEXP (disp
, 1)) == LABEL_REF
)
1694 /* Accept literal pool references. */
1695 else if (GET_CODE (disp
) == UNSPEC
1696 && XINT (disp
, 1) == UNSPEC_LTREL_OFFSET
)
1698 orig_disp
= gen_rtx_CONST (Pmode
, disp
);
1701 /* If we have an offset, make sure it does not
1702 exceed the size of the constant pool entry. */
1703 rtx sym
= XVECEXP (disp
, 0, 0);
1704 if (offset
>= GET_MODE_SIZE (get_pool_mode (sym
)))
1707 orig_disp
= plus_constant (orig_disp
, offset
);
1722 out
->disp
= orig_disp
;
1723 out
->pointer
= pointer
;
1729 /* Decompose a RTL expression OP for a shift count into its components,
1730 and return the base register in BASE and the offset in OFFSET.
1732 If BITS is non-zero, the expression is used in a context where only
1733 that number to low-order bits is significant. We then allow OP to
1734 contain and outer AND that does not affect significant bits. If BITS
1735 is zero, we allow OP to contain any outer AND with a constant.
1737 Return true if OP is a valid shift count, false if not. */
1740 s390_decompose_shift_count (rtx op
, rtx
*base
, HOST_WIDE_INT
*offset
, int bits
)
1742 HOST_WIDE_INT off
= 0;
1744 /* Drop outer ANDs. */
1745 if (GET_CODE (op
) == AND
&& GET_CODE (XEXP (op
, 1)) == CONST_INT
)
1747 HOST_WIDE_INT mask
= ((HOST_WIDE_INT
)1 << bits
) - 1;
1748 if ((INTVAL (XEXP (op
, 1)) & mask
) != mask
)
1754 /* We can have an integer constant, an address register,
1755 or a sum of the two. */
1756 if (GET_CODE (op
) == CONST_INT
)
1761 if (op
&& GET_CODE (op
) == PLUS
&& GET_CODE (XEXP (op
, 1)) == CONST_INT
)
1763 off
= INTVAL (XEXP (op
, 1));
1766 while (op
&& GET_CODE (op
) == SUBREG
)
1767 op
= SUBREG_REG (op
);
1769 if (op
&& GET_CODE (op
) != REG
)
1781 /* Return true if CODE is a valid address without index. */
1784 s390_legitimate_address_without_index_p (rtx op
)
1786 struct s390_address addr
;
1788 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1796 /* Return 1 if OP is a valid operand for a C constraint, 0 else. */
1799 s390_extra_constraint_str (rtx op
, int c
, const char * str
)
1801 struct s390_address addr
;
1803 gcc_assert (c
== str
[0]);
1805 /* Check for offsettable variants of memory constraints. */
1808 /* Only accept non-volatile MEMs. */
1809 if (!MEM_P (op
) || MEM_VOLATILE_P (op
))
1812 if ((reload_completed
|| reload_in_progress
)
1813 ? !offsettable_memref_p (op
)
1814 : !offsettable_nonstrict_memref_p (op
))
1820 /* Check for non-literal-pool variants of memory constraints. */
1823 if (GET_CODE (op
) != MEM
)
1825 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1827 if (addr
.base
&& REG_P (addr
.base
) && REGNO (addr
.base
) == BASE_REGNUM
)
1829 if (addr
.indx
&& REG_P (addr
.indx
) && REGNO (addr
.indx
) == BASE_REGNUM
)
1838 if (GET_CODE (op
) != MEM
)
1840 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1845 if (TARGET_LONG_DISPLACEMENT
)
1847 if (!s390_short_displacement (addr
.disp
))
1853 if (GET_CODE (op
) != MEM
)
1856 if (TARGET_LONG_DISPLACEMENT
)
1858 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1860 if (!s390_short_displacement (addr
.disp
))
1866 if (!TARGET_LONG_DISPLACEMENT
)
1868 if (GET_CODE (op
) != MEM
)
1870 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1874 if (s390_short_displacement (addr
.disp
))
1879 if (!TARGET_LONG_DISPLACEMENT
)
1881 if (GET_CODE (op
) != MEM
)
1883 /* Any invalid address here will be fixed up by reload,
1884 so accept it for the most generic constraint. */
1885 if (s390_decompose_address (XEXP (op
, 0), &addr
)
1886 && s390_short_displacement (addr
.disp
))
1891 if (TARGET_LONG_DISPLACEMENT
)
1893 if (!s390_decompose_address (op
, &addr
))
1895 if (!s390_short_displacement (addr
.disp
))
1901 if (!TARGET_LONG_DISPLACEMENT
)
1903 /* Any invalid address here will be fixed up by reload,
1904 so accept it for the most generic constraint. */
1905 if (s390_decompose_address (op
, &addr
)
1906 && s390_short_displacement (addr
.disp
))
1911 /* Simply check for the basic form of a shift count. Reload will
1912 take care of making sure we have a proper base register. */
1913 if (!s390_decompose_shift_count (op
, NULL
, NULL
, 0))
1924 /* Return true if VALUE matches the constraint STR. */
1927 s390_const_double_ok_for_constraint_p (rtx value
,
1931 gcc_assert (c
== str
[0]);
1936 /* The floating point zero constant. */
1937 return (GET_MODE_CLASS (GET_MODE (value
)) == MODE_FLOAT
1938 && value
== CONST0_RTX (GET_MODE (value
)));
1945 /* Return true if VALUE matches the constraint STR. */
1948 s390_const_ok_for_constraint_p (HOST_WIDE_INT value
,
1952 enum machine_mode mode
, part_mode
;
1954 int part
, part_goal
;
1956 gcc_assert (c
== str
[0]);
1961 return (unsigned int)value
< 256;
1964 return (unsigned int)value
< 4096;
1967 return value
>= -32768 && value
< 32768;
1970 return (TARGET_LONG_DISPLACEMENT
?
1971 (value
>= -524288 && value
<= 524287)
1972 : (value
>= 0 && value
<= 4095));
1974 return value
== 2147483647;
1980 part_goal
= str
[1] - '0';
1984 case 'Q': part_mode
= QImode
; break;
1985 case 'H': part_mode
= HImode
; break;
1986 case 'S': part_mode
= SImode
; break;
1992 case 'H': mode
= HImode
; break;
1993 case 'S': mode
= SImode
; break;
1994 case 'D': mode
= DImode
; break;
2000 case '0': def
= 0; break;
2001 case 'F': def
= -1; break;
2005 if (GET_MODE_SIZE (mode
) <= GET_MODE_SIZE (part_mode
))
2008 part
= s390_single_part (GEN_INT (value
), mode
, part_mode
, def
);
2011 if (part_goal
!= -1 && part_goal
!= part
)
2023 return trunc_int_for_mode (value
, SImode
) == value
;
2027 || s390_single_part (GEN_INT (value
), DImode
, SImode
, 0) == 1;
2031 || s390_single_part (GEN_INT (value
), DImode
, SImode
, -1) == 1;
2039 return legitimate_reload_constant_p (GEN_INT (value
));
2048 /* Compute a (partial) cost for rtx X. Return true if the complete
2049 cost has been computed, and false if subexpressions should be
2050 scanned. In either case, *TOTAL contains the cost result.
2051 CODE contains GET_CODE (x), OUTER_CODE contains the code
2052 of the superexpression of x. */
2055 s390_rtx_costs (rtx x
, int code
, int outer_code
, int *total
)
2078 *total
= COSTS_N_INSNS (1);
2083 /* Check for multiply and add. */
2084 if ((GET_MODE (x
) == DFmode
|| GET_MODE (x
) == SFmode
)
2085 && GET_CODE (XEXP (x
, 0)) == MULT
2086 && TARGET_HARD_FLOAT
&& TARGET_IEEE_FLOAT
&& TARGET_FUSED_MADD
)
2088 /* This is the multiply and add case. */
2089 if (GET_MODE (x
) == DFmode
)
2090 *total
= s390_cost
->madbr
;
2092 *total
= s390_cost
->maebr
;
2093 *total
+= rtx_cost (XEXP (XEXP (x
, 0), 0), MULT
)
2094 + rtx_cost (XEXP (XEXP (x
, 0), 1), MULT
)
2095 + rtx_cost (XEXP (x
, 1), code
);
2096 return true; /* Do not do an additional recursive descent. */
2098 *total
= COSTS_N_INSNS (1);
2102 switch (GET_MODE (x
))
2106 rtx left
= XEXP (x
, 0);
2107 rtx right
= XEXP (x
, 1);
2108 if (GET_CODE (right
) == CONST_INT
2109 && CONST_OK_FOR_K (INTVAL (right
)))
2110 *total
= s390_cost
->mhi
;
2111 else if (GET_CODE (left
) == SIGN_EXTEND
)
2112 *total
= s390_cost
->mh
;
2114 *total
= s390_cost
->ms
; /* msr, ms, msy */
2119 rtx left
= XEXP (x
, 0);
2120 rtx right
= XEXP (x
, 1);
2123 if (GET_CODE (right
) == CONST_INT
2124 && CONST_OK_FOR_K (INTVAL (right
)))
2125 *total
= s390_cost
->mghi
;
2126 else if (GET_CODE (left
) == SIGN_EXTEND
)
2127 *total
= s390_cost
->msgf
;
2129 *total
= s390_cost
->msg
; /* msgr, msg */
2131 else /* TARGET_31BIT */
2133 if (GET_CODE (left
) == SIGN_EXTEND
2134 && GET_CODE (right
) == SIGN_EXTEND
)
2135 /* mulsidi case: mr, m */
2136 *total
= s390_cost
->m
;
2137 else if (GET_CODE (left
) == ZERO_EXTEND
2138 && GET_CODE (right
) == ZERO_EXTEND
2139 && TARGET_CPU_ZARCH
)
2140 /* umulsidi case: ml, mlr */
2141 *total
= s390_cost
->ml
;
2143 /* Complex calculation is required. */
2144 *total
= COSTS_N_INSNS (40);
2150 *total
= s390_cost
->mult_df
;
2159 if (GET_MODE (x
) == TImode
) /* 128 bit division */
2160 *total
= s390_cost
->dlgr
;
2161 else if (GET_MODE (x
) == DImode
)
2163 rtx right
= XEXP (x
, 1);
2164 if (GET_CODE (right
) == ZERO_EXTEND
) /* 64 by 32 bit division */
2165 *total
= s390_cost
->dlr
;
2166 else /* 64 by 64 bit division */
2167 *total
= s390_cost
->dlgr
;
2169 else if (GET_MODE (x
) == SImode
) /* 32 bit division */
2170 *total
= s390_cost
->dlr
;
2175 if (GET_MODE (x
) == DImode
)
2177 rtx right
= XEXP (x
, 1);
2178 if (GET_CODE (right
) == ZERO_EXTEND
) /* 64 by 32 bit division */
2180 *total
= s390_cost
->dsgfr
;
2182 *total
= s390_cost
->dr
;
2183 else /* 64 by 64 bit division */
2184 *total
= s390_cost
->dsgr
;
2186 else if (GET_MODE (x
) == SImode
) /* 32 bit division */
2187 *total
= s390_cost
->dlr
;
2188 else if (GET_MODE (x
) == SFmode
)
2190 if (TARGET_IEEE_FLOAT
)
2191 *total
= s390_cost
->debr
;
2192 else /* TARGET_IBM_FLOAT */
2193 *total
= s390_cost
->der
;
2195 else if (GET_MODE (x
) == DFmode
)
2197 if (TARGET_IEEE_FLOAT
)
2198 *total
= s390_cost
->ddbr
;
2199 else /* TARGET_IBM_FLOAT */
2200 *total
= s390_cost
->ddr
;
2205 if (GET_MODE (x
) == SFmode
)
2206 *total
= s390_cost
->sqebr
;
2208 *total
= s390_cost
->sqdbr
;
2213 if (outer_code
== MULT
|| outer_code
== DIV
|| outer_code
== MOD
2214 || outer_code
== PLUS
|| outer_code
== MINUS
2215 || outer_code
== COMPARE
)
2220 *total
= COSTS_N_INSNS (1);
2221 if (GET_CODE (XEXP (x
, 0)) == AND
2222 && GET_CODE (XEXP (x
, 1)) == CONST_INT
2223 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
)
2225 rtx op0
= XEXP (XEXP (x
, 0), 0);
2226 rtx op1
= XEXP (XEXP (x
, 0), 1);
2227 rtx op2
= XEXP (x
, 1);
2229 if (memory_operand (op0
, GET_MODE (op0
))
2230 && s390_tm_ccmode (op1
, op2
, 0) != VOIDmode
)
2232 if (register_operand (op0
, GET_MODE (op0
))
2233 && s390_tm_ccmode (op1
, op2
, 1) != VOIDmode
)
2243 /* Return the cost of an address rtx ADDR. */
2246 s390_address_cost (rtx addr
)
2248 struct s390_address ad
;
2249 if (!s390_decompose_address (addr
, &ad
))
2252 return ad
.indx
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
2255 /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
2256 otherwise return 0. */
2259 tls_symbolic_operand (rtx op
)
2261 if (GET_CODE (op
) != SYMBOL_REF
)
2263 return SYMBOL_REF_TLS_MODEL (op
);
2266 /* Split DImode access register reference REG (on 64-bit) into its constituent
2267 low and high parts, and store them into LO and HI. Note that gen_lowpart/
2268 gen_highpart cannot be used as they assume all registers are word-sized,
2269 while our access registers have only half that size. */
2272 s390_split_access_reg (rtx reg
, rtx
*lo
, rtx
*hi
)
2274 gcc_assert (TARGET_64BIT
);
2275 gcc_assert (ACCESS_REG_P (reg
));
2276 gcc_assert (GET_MODE (reg
) == DImode
);
2277 gcc_assert (!(REGNO (reg
) & 1));
2279 *lo
= gen_rtx_REG (SImode
, REGNO (reg
) + 1);
2280 *hi
= gen_rtx_REG (SImode
, REGNO (reg
));
2283 /* Return true if OP contains a symbol reference */
2286 symbolic_reference_mentioned_p (rtx op
)
2291 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
2294 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
2295 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
2301 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
2302 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
2306 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
2313 /* Return true if OP contains a reference to a thread-local symbol. */
2316 tls_symbolic_reference_mentioned_p (rtx op
)
2321 if (GET_CODE (op
) == SYMBOL_REF
)
2322 return tls_symbolic_operand (op
);
2324 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
2325 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
2331 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
2332 if (tls_symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
2336 else if (fmt
[i
] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op
, i
)))
2344 /* Return true if OP is a legitimate general operand when
2345 generating PIC code. It is given that flag_pic is on
2346 and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2349 legitimate_pic_operand_p (rtx op
)
2351 /* Accept all non-symbolic constants. */
2352 if (!SYMBOLIC_CONST (op
))
2355 /* Reject everything else; must be handled
2356 via emit_symbolic_move. */
2360 /* Returns true if the constant value OP is a legitimate general operand.
2361 It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2364 legitimate_constant_p (rtx op
)
2366 /* Accept all non-symbolic constants. */
2367 if (!SYMBOLIC_CONST (op
))
2370 /* Accept immediate LARL operands. */
2371 if (TARGET_CPU_ZARCH
&& larl_operand (op
, VOIDmode
))
2374 /* Thread-local symbols are never legal constants. This is
2375 so that emit_call knows that computing such addresses
2376 might require a function call. */
2377 if (TLS_SYMBOLIC_CONST (op
))
2380 /* In the PIC case, symbolic constants must *not* be
2381 forced into the literal pool. We accept them here,
2382 so that they will be handled by emit_symbolic_move. */
2386 /* All remaining non-PIC symbolic constants are
2387 forced into the literal pool. */
2391 /* Determine if it's legal to put X into the constant pool. This
2392 is not possible if X contains the address of a symbol that is
2393 not constant (TLS) or not known at final link time (PIC). */
2396 s390_cannot_force_const_mem (rtx x
)
2398 switch (GET_CODE (x
))
2402 /* Accept all non-symbolic constants. */
2406 /* Labels are OK iff we are non-PIC. */
2407 return flag_pic
!= 0;
2410 /* 'Naked' TLS symbol references are never OK,
2411 non-TLS symbols are OK iff we are non-PIC. */
2412 if (tls_symbolic_operand (x
))
2415 return flag_pic
!= 0;
2418 return s390_cannot_force_const_mem (XEXP (x
, 0));
2421 return s390_cannot_force_const_mem (XEXP (x
, 0))
2422 || s390_cannot_force_const_mem (XEXP (x
, 1));
2425 switch (XINT (x
, 1))
2427 /* Only lt-relative or GOT-relative UNSPECs are OK. */
2428 case UNSPEC_LTREL_OFFSET
:
2436 case UNSPEC_GOTNTPOFF
:
2437 case UNSPEC_INDNTPOFF
:
2440 /* If the literal pool shares the code section, be put
2441 execute template placeholders into the pool as well. */
2443 return TARGET_CPU_ZARCH
;
2455 /* Returns true if the constant value OP is a legitimate general
2456 operand during and after reload. The difference to
2457 legitimate_constant_p is that this function will not accept
2458 a constant that would need to be forced to the literal pool
2459 before it can be used as operand. */
2462 legitimate_reload_constant_p (rtx op
)
2464 /* Accept la(y) operands. */
2465 if (GET_CODE (op
) == CONST_INT
2466 && DISP_IN_RANGE (INTVAL (op
)))
2469 /* Accept l(g)hi/l(g)fi operands. */
2470 if (GET_CODE (op
) == CONST_INT
2471 && (CONST_OK_FOR_K (INTVAL (op
)) || CONST_OK_FOR_Os (INTVAL (op
))))
2474 /* Accept lliXX operands. */
2476 && GET_CODE (op
) == CONST_INT
2477 && trunc_int_for_mode (INTVAL (op
), word_mode
) == INTVAL (op
)
2478 && s390_single_part (op
, word_mode
, HImode
, 0) >= 0)
2482 && GET_CODE (op
) == CONST_INT
2483 && trunc_int_for_mode (INTVAL (op
), word_mode
) == INTVAL (op
)
2484 && s390_single_part (op
, word_mode
, SImode
, 0) >= 0)
2487 /* Accept larl operands. */
2488 if (TARGET_CPU_ZARCH
2489 && larl_operand (op
, VOIDmode
))
2492 /* Accept lzXX operands. */
2493 if (GET_CODE (op
) == CONST_DOUBLE
2494 && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op
, 'G', "G"))
2497 /* Accept double-word operands that can be split. */
2498 if (GET_CODE (op
) == CONST_INT
2499 && trunc_int_for_mode (INTVAL (op
), word_mode
) != INTVAL (op
))
2501 enum machine_mode dword_mode
= word_mode
== SImode
? DImode
: TImode
;
2502 rtx hi
= operand_subword (op
, 0, 0, dword_mode
);
2503 rtx lo
= operand_subword (op
, 1, 0, dword_mode
);
2504 return legitimate_reload_constant_p (hi
)
2505 && legitimate_reload_constant_p (lo
);
2508 /* Everything else cannot be handled without reload. */
2512 /* Given an rtx OP being reloaded into a reg required to be in class CLASS,
2513 return the class of reg to actually use. */
2516 s390_preferred_reload_class (rtx op
, enum reg_class
class)
2518 switch (GET_CODE (op
))
2520 /* Constants we cannot reload must be forced into the
2525 if (legitimate_reload_constant_p (op
))
2530 /* If a symbolic constant or a PLUS is reloaded,
2531 it is most likely being used as an address, so
2532 prefer ADDR_REGS. If 'class' is not a superset
2533 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
2538 if (reg_class_subset_p (ADDR_REGS
, class))
2550 /* Return the register class of a scratch register needed to
2551 load IN into a register of class CLASS in MODE.
2553 We need a temporary when loading a PLUS expression which
2554 is not a legitimate operand of the LOAD ADDRESS instruction. */
2557 s390_secondary_input_reload_class (enum reg_class
class,
2558 enum machine_mode mode
, rtx in
)
2560 if (s390_plus_operand (in
, mode
))
2563 if (reg_classes_intersect_p (CC_REGS
, class))
2564 return GENERAL_REGS
;
2569 /* Return the register class of a scratch register needed to
2570 store a register of class CLASS in MODE into OUT:
2572 We need a temporary when storing a double-word to a
2573 non-offsettable memory address. */
2576 s390_secondary_output_reload_class (enum reg_class
class,
2577 enum machine_mode mode
, rtx out
)
2579 if ((TARGET_64BIT
? mode
== TImode
2580 : (mode
== DImode
|| mode
== DFmode
))
2581 && reg_classes_intersect_p (GENERAL_REGS
, class)
2582 && GET_CODE (out
) == MEM
2583 && GET_CODE (XEXP (out
, 0)) == PLUS
2584 && GET_CODE (XEXP (XEXP (out
, 0), 0)) == PLUS
2585 && GET_CODE (XEXP (XEXP (out
, 0), 1)) == CONST_INT
2586 && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (out
, 0), 1))
2587 + GET_MODE_SIZE (mode
) - 1))
2590 if (reg_classes_intersect_p (CC_REGS
, class))
2591 return GENERAL_REGS
;
2596 /* Generate code to load SRC, which is PLUS that is not a
2597 legitimate operand for the LA instruction, into TARGET.
2598 SCRATCH may be used as scratch register. */
2601 s390_expand_plus_operand (rtx target
, rtx src
,
2605 struct s390_address ad
;
2607 /* src must be a PLUS; get its two operands. */
2608 gcc_assert (GET_CODE (src
) == PLUS
);
2609 gcc_assert (GET_MODE (src
) == Pmode
);
2611 /* Check if any of the two operands is already scheduled
2612 for replacement by reload. This can happen e.g. when
2613 float registers occur in an address. */
2614 sum1
= find_replacement (&XEXP (src
, 0));
2615 sum2
= find_replacement (&XEXP (src
, 1));
2616 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
2618 /* If the address is already strictly valid, there's nothing to do. */
2619 if (!s390_decompose_address (src
, &ad
)
2620 || (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
2621 || (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
)))
2623 /* Otherwise, one of the operands cannot be an address register;
2624 we reload its value into the scratch register. */
2625 if (true_regnum (sum1
) < 1 || true_regnum (sum1
) > 15)
2627 emit_move_insn (scratch
, sum1
);
2630 if (true_regnum (sum2
) < 1 || true_regnum (sum2
) > 15)
2632 emit_move_insn (scratch
, sum2
);
2636 /* According to the way these invalid addresses are generated
2637 in reload.c, it should never happen (at least on s390) that
2638 *neither* of the PLUS components, after find_replacements
2639 was applied, is an address register. */
2640 if (sum1
== scratch
&& sum2
== scratch
)
2646 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
2649 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
2650 is only ever performed on addresses, so we can mark the
2651 sum as legitimate for LA in any case. */
2652 s390_load_address (target
, src
);
2656 /* Return true if ADDR is a valid memory address.
2657 STRICT specifies whether strict register checking applies. */
2660 legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED
,
2661 rtx addr
, int strict
)
2663 struct s390_address ad
;
2664 if (!s390_decompose_address (addr
, &ad
))
2669 if (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
2671 if (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
))
2676 if (ad
.base
&& !REG_OK_FOR_BASE_NONSTRICT_P (ad
.base
))
2678 if (ad
.indx
&& !REG_OK_FOR_INDEX_NONSTRICT_P (ad
.indx
))
2685 /* Return true if OP is a valid operand for the LA instruction.
2686 In 31-bit, we need to prove that the result is used as an
2687 address, as LA performs only a 31-bit addition. */
2690 legitimate_la_operand_p (rtx op
)
2692 struct s390_address addr
;
2693 if (!s390_decompose_address (op
, &addr
))
2696 return (TARGET_64BIT
|| addr
.pointer
);
2699 /* Return true if it is valid *and* preferable to use LA to
2700 compute the sum of OP1 and OP2. */
2703 preferred_la_operand_p (rtx op1
, rtx op2
)
2705 struct s390_address addr
;
2707 if (op2
!= const0_rtx
)
2708 op1
= gen_rtx_PLUS (Pmode
, op1
, op2
);
2710 if (!s390_decompose_address (op1
, &addr
))
2712 if (addr
.base
&& !REG_OK_FOR_BASE_STRICT_P (addr
.base
))
2714 if (addr
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (addr
.indx
))
2717 if (!TARGET_64BIT
&& !addr
.pointer
)
2723 if ((addr
.base
&& REG_P (addr
.base
) && REG_POINTER (addr
.base
))
2724 || (addr
.indx
&& REG_P (addr
.indx
) && REG_POINTER (addr
.indx
)))
2730 /* Emit a forced load-address operation to load SRC into DST.
2731 This will use the LOAD ADDRESS instruction even in situations
2732 where legitimate_la_operand_p (SRC) returns false. */
2735 s390_load_address (rtx dst
, rtx src
)
2738 emit_move_insn (dst
, src
);
2740 emit_insn (gen_force_la_31 (dst
, src
));
2743 /* Return a legitimate reference for ORIG (an address) using the
2744 register REG. If REG is 0, a new pseudo is generated.
2746 There are two types of references that must be handled:
2748 1. Global data references must load the address from the GOT, via
2749 the PIC reg. An insn is emitted to do this load, and the reg is
2752 2. Static data references, constant pool addresses, and code labels
2753 compute the address as an offset from the GOT, whose base is in
2754 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
2755 differentiate them from global data objects. The returned
2756 address is the PIC reg + an unspec constant.
2758 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2759 reg also appears in the address. */
2762 legitimize_pic_address (rtx orig
, rtx reg
)
2768 if (GET_CODE (addr
) == LABEL_REF
2769 || (GET_CODE (addr
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (addr
)))
2771 /* This is a local symbol. */
2772 if (TARGET_CPU_ZARCH
&& larl_operand (addr
, VOIDmode
))
2774 /* Access local symbols PC-relative via LARL.
2775 This is the same as in the non-PIC case, so it is
2776 handled automatically ... */
2780 /* Access local symbols relative to the GOT. */
2782 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2784 if (reload_in_progress
|| reload_completed
)
2785 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2787 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTOFF
);
2788 addr
= gen_rtx_CONST (Pmode
, addr
);
2789 addr
= force_const_mem (Pmode
, addr
);
2790 emit_move_insn (temp
, addr
);
2792 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2795 s390_load_address (reg
, new);
2800 else if (GET_CODE (addr
) == SYMBOL_REF
)
2803 reg
= gen_reg_rtx (Pmode
);
2807 /* Assume GOT offset < 4k. This is handled the same way
2808 in both 31- and 64-bit code (@GOT). */
2810 if (reload_in_progress
|| reload_completed
)
2811 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2813 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
2814 new = gen_rtx_CONST (Pmode
, new);
2815 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new);
2816 new = gen_const_mem (Pmode
, new);
2817 emit_move_insn (reg
, new);
2820 else if (TARGET_CPU_ZARCH
)
2822 /* If the GOT offset might be >= 4k, we determine the position
2823 of the GOT entry via a PC-relative LARL (@GOTENT). */
2825 rtx temp
= gen_reg_rtx (Pmode
);
2827 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTENT
);
2828 new = gen_rtx_CONST (Pmode
, new);
2829 emit_move_insn (temp
, new);
2831 new = gen_const_mem (Pmode
, temp
);
2832 emit_move_insn (reg
, new);
2837 /* If the GOT offset might be >= 4k, we have to load it
2838 from the literal pool (@GOT). */
2840 rtx temp
= gen_reg_rtx (Pmode
);
2842 if (reload_in_progress
|| reload_completed
)
2843 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2845 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
2846 addr
= gen_rtx_CONST (Pmode
, addr
);
2847 addr
= force_const_mem (Pmode
, addr
);
2848 emit_move_insn (temp
, addr
);
2850 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2851 new = gen_const_mem (Pmode
, new);
2852 emit_move_insn (reg
, new);
2858 if (GET_CODE (addr
) == CONST
)
2860 addr
= XEXP (addr
, 0);
2861 if (GET_CODE (addr
) == UNSPEC
)
2863 gcc_assert (XVECLEN (addr
, 0) == 1);
2864 switch (XINT (addr
, 1))
2866 /* If someone moved a GOT-relative UNSPEC
2867 out of the literal pool, force them back in. */
2870 new = force_const_mem (Pmode
, orig
);
2873 /* @GOT is OK as is if small. */
2876 new = force_const_mem (Pmode
, orig
);
2879 /* @GOTENT is OK as is. */
2883 /* @PLT is OK as is on 64-bit, must be converted to
2884 GOT-relative @PLTOFF on 31-bit. */
2886 if (!TARGET_CPU_ZARCH
)
2888 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2890 if (reload_in_progress
|| reload_completed
)
2891 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2893 addr
= XVECEXP (addr
, 0, 0);
2894 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
),
2896 addr
= gen_rtx_CONST (Pmode
, addr
);
2897 addr
= force_const_mem (Pmode
, addr
);
2898 emit_move_insn (temp
, addr
);
2900 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2903 s390_load_address (reg
, new);
2909 /* Everything else cannot happen. */
2915 gcc_assert (GET_CODE (addr
) == PLUS
);
2917 if (GET_CODE (addr
) == PLUS
)
2919 rtx op0
= XEXP (addr
, 0), op1
= XEXP (addr
, 1);
2920 /* Check first to see if this is a constant offset
2921 from a local symbol reference. */
2922 if ((GET_CODE (op0
) == LABEL_REF
2923 || (GET_CODE (op0
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (op0
)))
2924 && GET_CODE (op1
) == CONST_INT
)
2926 if (TARGET_CPU_ZARCH
&& larl_operand (op0
, VOIDmode
))
2928 if (INTVAL (op1
) & 1)
2930 /* LARL can't handle odd offsets, so emit a
2931 pair of LARL and LA. */
2932 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2934 if (!DISP_IN_RANGE (INTVAL (op1
)))
2936 int even
= INTVAL (op1
) - 1;
2937 op0
= gen_rtx_PLUS (Pmode
, op0
, GEN_INT (even
));
2938 op0
= gen_rtx_CONST (Pmode
, op0
);
2942 emit_move_insn (temp
, op0
);
2943 new = gen_rtx_PLUS (Pmode
, temp
, op1
);
2947 s390_load_address (reg
, new);
2953 /* If the offset is even, we can just use LARL.
2954 This will happen automatically. */
2959 /* Access local symbols relative to the GOT. */
2961 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2963 if (reload_in_progress
|| reload_completed
)
2964 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2966 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op0
),
2968 addr
= gen_rtx_PLUS (Pmode
, addr
, op1
);
2969 addr
= gen_rtx_CONST (Pmode
, addr
);
2970 addr
= force_const_mem (Pmode
, addr
);
2971 emit_move_insn (temp
, addr
);
2973 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2976 s390_load_address (reg
, new);
2982 /* Now, check whether it is a GOT relative symbol plus offset
2983 that was pulled out of the literal pool. Force it back in. */
2985 else if (GET_CODE (op0
) == UNSPEC
2986 && GET_CODE (op1
) == CONST_INT
2987 && XINT (op0
, 1) == UNSPEC_GOTOFF
)
2989 gcc_assert (XVECLEN (op0
, 0) == 1);
2991 new = force_const_mem (Pmode
, orig
);
2994 /* Otherwise, compute the sum. */
2997 base
= legitimize_pic_address (XEXP (addr
, 0), reg
);
2998 new = legitimize_pic_address (XEXP (addr
, 1),
2999 base
== reg
? NULL_RTX
: reg
);
3000 if (GET_CODE (new) == CONST_INT
)
3001 new = plus_constant (base
, INTVAL (new));
3004 if (GET_CODE (new) == PLUS
&& CONSTANT_P (XEXP (new, 1)))
3006 base
= gen_rtx_PLUS (Pmode
, base
, XEXP (new, 0));
3007 new = XEXP (new, 1);
3009 new = gen_rtx_PLUS (Pmode
, base
, new);
3012 if (GET_CODE (new) == CONST
)
3013 new = XEXP (new, 0);
3014 new = force_operand (new, 0);
3021 /* Load the thread pointer into a register. */
3024 s390_get_thread_pointer (void)
3026 rtx tp
= gen_reg_rtx (Pmode
);
3028 emit_move_insn (tp
, gen_rtx_REG (Pmode
, TP_REGNUM
));
3029 mark_reg_pointer (tp
, BITS_PER_WORD
);
3034 /* Emit a tls call insn. The call target is the SYMBOL_REF stored
3035 in s390_tls_symbol which always refers to __tls_get_offset.
3036 The returned offset is written to RESULT_REG and an USE rtx is
3037 generated for TLS_CALL. */
3039 static GTY(()) rtx s390_tls_symbol
;
3042 s390_emit_tls_call_insn (rtx result_reg
, rtx tls_call
)
3046 gcc_assert (flag_pic
);
3048 if (!s390_tls_symbol
)
3049 s390_tls_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "__tls_get_offset");
3051 insn
= s390_emit_call (s390_tls_symbol
, tls_call
, result_reg
,
3052 gen_rtx_REG (Pmode
, RETURN_REGNUM
));
3054 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), result_reg
);
3055 CONST_OR_PURE_CALL_P (insn
) = 1;
3058 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
3059 this (thread-local) address. REG may be used as temporary. */
3062 legitimize_tls_address (rtx addr
, rtx reg
)
3064 rtx
new, tls_call
, temp
, base
, r2
, insn
;
3066 if (GET_CODE (addr
) == SYMBOL_REF
)
3067 switch (tls_symbolic_operand (addr
))
3069 case TLS_MODEL_GLOBAL_DYNAMIC
:
3071 r2
= gen_rtx_REG (Pmode
, 2);
3072 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_TLSGD
);
3073 new = gen_rtx_CONST (Pmode
, tls_call
);
3074 new = force_const_mem (Pmode
, new);
3075 emit_move_insn (r2
, new);
3076 s390_emit_tls_call_insn (r2
, tls_call
);
3077 insn
= get_insns ();
3080 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
3081 temp
= gen_reg_rtx (Pmode
);
3082 emit_libcall_block (insn
, temp
, r2
, new);
3084 new = gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
3087 s390_load_address (reg
, new);
3092 case TLS_MODEL_LOCAL_DYNAMIC
:
3094 r2
= gen_rtx_REG (Pmode
, 2);
3095 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM
);
3096 new = gen_rtx_CONST (Pmode
, tls_call
);
3097 new = force_const_mem (Pmode
, new);
3098 emit_move_insn (r2
, new);
3099 s390_emit_tls_call_insn (r2
, tls_call
);
3100 insn
= get_insns ();
3103 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM_NTPOFF
);
3104 temp
= gen_reg_rtx (Pmode
);
3105 emit_libcall_block (insn
, temp
, r2
, new);
3107 new = gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
3108 base
= gen_reg_rtx (Pmode
);
3109 s390_load_address (base
, new);
3111 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_DTPOFF
);
3112 new = gen_rtx_CONST (Pmode
, new);
3113 new = force_const_mem (Pmode
, new);
3114 temp
= gen_reg_rtx (Pmode
);
3115 emit_move_insn (temp
, new);
3117 new = gen_rtx_PLUS (Pmode
, base
, temp
);
3120 s390_load_address (reg
, new);
3125 case TLS_MODEL_INITIAL_EXEC
:
3128 /* Assume GOT offset < 4k. This is handled the same way
3129 in both 31- and 64-bit code. */
3131 if (reload_in_progress
|| reload_completed
)
3132 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
3134 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
3135 new = gen_rtx_CONST (Pmode
, new);
3136 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new);
3137 new = gen_const_mem (Pmode
, new);
3138 temp
= gen_reg_rtx (Pmode
);
3139 emit_move_insn (temp
, new);
3141 else if (TARGET_CPU_ZARCH
)
3143 /* If the GOT offset might be >= 4k, we determine the position
3144 of the GOT entry via a PC-relative LARL. */
3146 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
3147 new = gen_rtx_CONST (Pmode
, new);
3148 temp
= gen_reg_rtx (Pmode
);
3149 emit_move_insn (temp
, new);
3151 new = gen_const_mem (Pmode
, temp
);
3152 temp
= gen_reg_rtx (Pmode
);
3153 emit_move_insn (temp
, new);
3157 /* If the GOT offset might be >= 4k, we have to load it
3158 from the literal pool. */
3160 if (reload_in_progress
|| reload_completed
)
3161 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
3163 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
3164 new = gen_rtx_CONST (Pmode
, new);
3165 new = force_const_mem (Pmode
, new);
3166 temp
= gen_reg_rtx (Pmode
);
3167 emit_move_insn (temp
, new);
3169 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
3170 new = gen_const_mem (Pmode
, new);
3172 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new, addr
), UNSPEC_TLS_LOAD
);
3173 temp
= gen_reg_rtx (Pmode
);
3174 emit_insn (gen_rtx_SET (Pmode
, temp
, new));
3178 /* In position-dependent code, load the absolute address of
3179 the GOT entry from the literal pool. */
3181 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
3182 new = gen_rtx_CONST (Pmode
, new);
3183 new = force_const_mem (Pmode
, new);
3184 temp
= gen_reg_rtx (Pmode
);
3185 emit_move_insn (temp
, new);
3188 new = gen_const_mem (Pmode
, new);
3189 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new, addr
), UNSPEC_TLS_LOAD
);
3190 temp
= gen_reg_rtx (Pmode
);
3191 emit_insn (gen_rtx_SET (Pmode
, temp
, new));
3194 new = gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
3197 s390_load_address (reg
, new);
3202 case TLS_MODEL_LOCAL_EXEC
:
3203 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
3204 new = gen_rtx_CONST (Pmode
, new);
3205 new = force_const_mem (Pmode
, new);
3206 temp
= gen_reg_rtx (Pmode
);
3207 emit_move_insn (temp
, new);
3209 new = gen_rtx_PLUS (Pmode
, s390_get_thread_pointer (), temp
);
3212 s390_load_address (reg
, new);
3221 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == UNSPEC
)
3223 switch (XINT (XEXP (addr
, 0), 1))
3225 case UNSPEC_INDNTPOFF
:
3226 gcc_assert (TARGET_CPU_ZARCH
);
3235 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == PLUS
3236 && GET_CODE (XEXP (XEXP (addr
, 0), 1)) == CONST_INT
)
3238 new = XEXP (XEXP (addr
, 0), 0);
3239 if (GET_CODE (new) != SYMBOL_REF
)
3240 new = gen_rtx_CONST (Pmode
, new);
3242 new = legitimize_tls_address (new, reg
);
3243 new = plus_constant (new, INTVAL (XEXP (XEXP (addr
, 0), 1)));
3244 new = force_operand (new, 0);
3248 gcc_unreachable (); /* for now ... */
3253 /* Emit insns to move operands[1] into operands[0]. */
3256 emit_symbolic_move (rtx
*operands
)
3258 rtx temp
= no_new_pseudos
? operands
[0] : gen_reg_rtx (Pmode
);
3260 if (GET_CODE (operands
[0]) == MEM
)
3261 operands
[1] = force_reg (Pmode
, operands
[1]);
3262 else if (TLS_SYMBOLIC_CONST (operands
[1]))
3263 operands
[1] = legitimize_tls_address (operands
[1], temp
);
3265 operands
[1] = legitimize_pic_address (operands
[1], temp
);
3268 /* Try machine-dependent ways of modifying an illegitimate address X
3269 to be legitimate. If we find one, return the new, valid address.
3271 OLDX is the address as it was before break_out_memory_refs was called.
3272 In some cases it is useful to look at this to decide what needs to be done.
3274 MODE is the mode of the operand pointed to by X.
3276 When -fpic is used, special handling is needed for symbolic references.
3277 See comments by legitimize_pic_address for details. */
3280 legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
3281 enum machine_mode mode ATTRIBUTE_UNUSED
)
3283 rtx constant_term
= const0_rtx
;
3285 if (TLS_SYMBOLIC_CONST (x
))
3287 x
= legitimize_tls_address (x
, 0);
3289 if (legitimate_address_p (mode
, x
, FALSE
))
3294 if (SYMBOLIC_CONST (x
)
3295 || (GET_CODE (x
) == PLUS
3296 && (SYMBOLIC_CONST (XEXP (x
, 0))
3297 || SYMBOLIC_CONST (XEXP (x
, 1)))))
3298 x
= legitimize_pic_address (x
, 0);
3300 if (legitimate_address_p (mode
, x
, FALSE
))
3304 x
= eliminate_constant_term (x
, &constant_term
);
3306 /* Optimize loading of large displacements by splitting them
3307 into the multiple of 4K and the rest; this allows the
3308 former to be CSE'd if possible.
3310 Don't do this if the displacement is added to a register
3311 pointing into the stack frame, as the offsets will
3312 change later anyway. */
3314 if (GET_CODE (constant_term
) == CONST_INT
3315 && !TARGET_LONG_DISPLACEMENT
3316 && !DISP_IN_RANGE (INTVAL (constant_term
))
3317 && !(REG_P (x
) && REGNO_PTR_FRAME_P (REGNO (x
))))
3319 HOST_WIDE_INT lower
= INTVAL (constant_term
) & 0xfff;
3320 HOST_WIDE_INT upper
= INTVAL (constant_term
) ^ lower
;
3322 rtx temp
= gen_reg_rtx (Pmode
);
3323 rtx val
= force_operand (GEN_INT (upper
), temp
);
3325 emit_move_insn (temp
, val
);
3327 x
= gen_rtx_PLUS (Pmode
, x
, temp
);
3328 constant_term
= GEN_INT (lower
);
3331 if (GET_CODE (x
) == PLUS
)
3333 if (GET_CODE (XEXP (x
, 0)) == REG
)
3335 rtx temp
= gen_reg_rtx (Pmode
);
3336 rtx val
= force_operand (XEXP (x
, 1), temp
);
3338 emit_move_insn (temp
, val
);
3340 x
= gen_rtx_PLUS (Pmode
, XEXP (x
, 0), temp
);
3343 else if (GET_CODE (XEXP (x
, 1)) == REG
)
3345 rtx temp
= gen_reg_rtx (Pmode
);
3346 rtx val
= force_operand (XEXP (x
, 0), temp
);
3348 emit_move_insn (temp
, val
);
3350 x
= gen_rtx_PLUS (Pmode
, temp
, XEXP (x
, 1));
3354 if (constant_term
!= const0_rtx
)
3355 x
= gen_rtx_PLUS (Pmode
, x
, constant_term
);
3360 /* Try a machine-dependent way of reloading an illegitimate address AD
3361 operand. If we find one, push the reload and and return the new address.
3363 MODE is the mode of the enclosing MEM. OPNUM is the operand number
3364 and TYPE is the reload type of the current reload. */
3367 legitimize_reload_address (rtx ad
, enum machine_mode mode ATTRIBUTE_UNUSED
,
3368 int opnum
, int type
)
3370 if (!optimize
|| TARGET_LONG_DISPLACEMENT
)
3373 if (GET_CODE (ad
) == PLUS
)
3375 rtx tem
= simplify_binary_operation (PLUS
, Pmode
,
3376 XEXP (ad
, 0), XEXP (ad
, 1));
3381 if (GET_CODE (ad
) == PLUS
3382 && GET_CODE (XEXP (ad
, 0)) == REG
3383 && GET_CODE (XEXP (ad
, 1)) == CONST_INT
3384 && !DISP_IN_RANGE (INTVAL (XEXP (ad
, 1))))
3386 HOST_WIDE_INT lower
= INTVAL (XEXP (ad
, 1)) & 0xfff;
3387 HOST_WIDE_INT upper
= INTVAL (XEXP (ad
, 1)) ^ lower
;
3390 cst
= GEN_INT (upper
);
3391 if (!legitimate_reload_constant_p (cst
))
3392 cst
= force_const_mem (Pmode
, cst
);
3394 tem
= gen_rtx_PLUS (Pmode
, XEXP (ad
, 0), cst
);
3395 new = gen_rtx_PLUS (Pmode
, tem
, GEN_INT (lower
));
3397 push_reload (XEXP (tem
, 1), 0, &XEXP (tem
, 1), 0,
3398 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
3399 opnum
, (enum reload_type
) type
);
3406 /* Emit code to move LEN bytes from DST to SRC. */
3409 s390_expand_movmem (rtx dst
, rtx src
, rtx len
)
3411 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3413 if (INTVAL (len
) > 0)
3414 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (INTVAL (len
) - 1)));
3417 else if (TARGET_MVCLE
)
3419 emit_insn (gen_movmem_long (dst
, src
, convert_to_mode (Pmode
, len
, 1)));
3424 rtx dst_addr
, src_addr
, count
, blocks
, temp
;
3425 rtx loop_start_label
= gen_label_rtx ();
3426 rtx loop_end_label
= gen_label_rtx ();
3427 rtx end_label
= gen_label_rtx ();
3428 enum machine_mode mode
;
3430 mode
= GET_MODE (len
);
3431 if (mode
== VOIDmode
)
3434 dst_addr
= gen_reg_rtx (Pmode
);
3435 src_addr
= gen_reg_rtx (Pmode
);
3436 count
= gen_reg_rtx (mode
);
3437 blocks
= gen_reg_rtx (mode
);
3439 convert_move (count
, len
, 1);
3440 emit_cmp_and_jump_insns (count
, const0_rtx
,
3441 EQ
, NULL_RTX
, mode
, 1, end_label
);
3443 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
3444 emit_move_insn (src_addr
, force_operand (XEXP (src
, 0), NULL_RTX
));
3445 dst
= change_address (dst
, VOIDmode
, dst_addr
);
3446 src
= change_address (src
, VOIDmode
, src_addr
);
3448 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3450 emit_move_insn (count
, temp
);
3452 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3454 emit_move_insn (blocks
, temp
);
3456 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3457 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3459 emit_label (loop_start_label
);
3461 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (255)));
3462 s390_load_address (dst_addr
,
3463 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
3464 s390_load_address (src_addr
,
3465 gen_rtx_PLUS (Pmode
, src_addr
, GEN_INT (256)));
3467 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3469 emit_move_insn (blocks
, temp
);
3471 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3472 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3474 emit_jump (loop_start_label
);
3475 emit_label (loop_end_label
);
3477 emit_insn (gen_movmem_short (dst
, src
,
3478 convert_to_mode (Pmode
, count
, 1)));
3479 emit_label (end_label
);
3483 /* Emit code to set LEN bytes at DST to VAL.
3484 Make use of clrmem if VAL is zero. */
3487 s390_expand_setmem (rtx dst
, rtx len
, rtx val
)
3489 gcc_assert (GET_CODE (len
) != CONST_INT
|| INTVAL (len
) > 0);
3490 gcc_assert (GET_CODE (val
) == CONST_INT
|| GET_MODE (val
) == QImode
);
3492 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) <= 257)
3494 if (val
== const0_rtx
&& INTVAL (len
) <= 256)
3495 emit_insn (gen_clrmem_short (dst
, GEN_INT (INTVAL (len
) - 1)));
3498 /* Initialize memory by storing the first byte. */
3499 emit_move_insn (adjust_address (dst
, QImode
, 0), val
);
3501 if (INTVAL (len
) > 1)
3503 /* Initiate 1 byte overlap move.
3504 The first byte of DST is propagated through DSTP1.
3505 Prepare a movmem for: DST+1 = DST (length = LEN - 1).
3506 DST is set to size 1 so the rest of the memory location
3507 does not count as source operand. */
3508 rtx dstp1
= adjust_address (dst
, VOIDmode
, 1);
3509 set_mem_size (dst
, const1_rtx
);
3511 emit_insn (gen_movmem_short (dstp1
, dst
,
3512 GEN_INT (INTVAL (len
) - 2)));
3517 else if (TARGET_MVCLE
)
3519 val
= force_not_mem (convert_modes (Pmode
, QImode
, val
, 1));
3520 emit_insn (gen_setmem_long (dst
, convert_to_mode (Pmode
, len
, 1), val
));
3525 rtx dst_addr
, src_addr
, count
, blocks
, temp
, dstp1
= NULL_RTX
;
3526 rtx loop_start_label
= gen_label_rtx ();
3527 rtx loop_end_label
= gen_label_rtx ();
3528 rtx end_label
= gen_label_rtx ();
3529 enum machine_mode mode
;
3531 mode
= GET_MODE (len
);
3532 if (mode
== VOIDmode
)
3535 dst_addr
= gen_reg_rtx (Pmode
);
3536 src_addr
= gen_reg_rtx (Pmode
);
3537 count
= gen_reg_rtx (mode
);
3538 blocks
= gen_reg_rtx (mode
);
3540 convert_move (count
, len
, 1);
3541 emit_cmp_and_jump_insns (count
, const0_rtx
,
3542 EQ
, NULL_RTX
, mode
, 1, end_label
);
3544 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
3545 dst
= change_address (dst
, VOIDmode
, dst_addr
);
3547 if (val
== const0_rtx
)
3548 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3551 dstp1
= adjust_address (dst
, VOIDmode
, 1);
3552 set_mem_size (dst
, const1_rtx
);
3554 /* Initialize memory by storing the first byte. */
3555 emit_move_insn (adjust_address (dst
, QImode
, 0), val
);
3557 /* If count is 1 we are done. */
3558 emit_cmp_and_jump_insns (count
, const1_rtx
,
3559 EQ
, NULL_RTX
, mode
, 1, end_label
);
3561 temp
= expand_binop (mode
, add_optab
, count
, GEN_INT (-2), count
, 1, 0);
3564 emit_move_insn (count
, temp
);
3566 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3568 emit_move_insn (blocks
, temp
);
3570 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3571 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3573 emit_label (loop_start_label
);
3575 if (val
== const0_rtx
)
3576 emit_insn (gen_clrmem_short (dst
, GEN_INT (255)));
3578 emit_insn (gen_movmem_short (dstp1
, dst
, GEN_INT (255)));
3579 s390_load_address (dst_addr
,
3580 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
3582 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3584 emit_move_insn (blocks
, temp
);
3586 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3587 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3589 emit_jump (loop_start_label
);
3590 emit_label (loop_end_label
);
3592 if (val
== const0_rtx
)
3593 emit_insn (gen_clrmem_short (dst
, convert_to_mode (Pmode
, count
, 1)));
3595 emit_insn (gen_movmem_short (dstp1
, dst
, convert_to_mode (Pmode
, count
, 1)));
3596 emit_label (end_label
);
3600 /* Emit code to compare LEN bytes at OP0 with those at OP1,
3601 and return the result in TARGET. */
3604 s390_expand_cmpmem (rtx target
, rtx op0
, rtx op1
, rtx len
)
3606 rtx ccreg
= gen_rtx_REG (CCUmode
, CC_REGNUM
);
3609 /* As the result of CMPINT is inverted compared to what we need,
3610 we have to swap the operands. */
3611 tmp
= op0
; op0
= op1
; op1
= tmp
;
3613 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3615 if (INTVAL (len
) > 0)
3617 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (INTVAL (len
) - 1)));
3618 emit_insn (gen_cmpint (target
, ccreg
));
3621 emit_move_insn (target
, const0_rtx
);
3623 else if (TARGET_MVCLE
)
3625 emit_insn (gen_cmpmem_long (op0
, op1
, convert_to_mode (Pmode
, len
, 1)));
3626 emit_insn (gen_cmpint (target
, ccreg
));
3630 rtx addr0
, addr1
, count
, blocks
, temp
;
3631 rtx loop_start_label
= gen_label_rtx ();
3632 rtx loop_end_label
= gen_label_rtx ();
3633 rtx end_label
= gen_label_rtx ();
3634 enum machine_mode mode
;
3636 mode
= GET_MODE (len
);
3637 if (mode
== VOIDmode
)
3640 addr0
= gen_reg_rtx (Pmode
);
3641 addr1
= gen_reg_rtx (Pmode
);
3642 count
= gen_reg_rtx (mode
);
3643 blocks
= gen_reg_rtx (mode
);
3645 convert_move (count
, len
, 1);
3646 emit_cmp_and_jump_insns (count
, const0_rtx
,
3647 EQ
, NULL_RTX
, mode
, 1, end_label
);
3649 emit_move_insn (addr0
, force_operand (XEXP (op0
, 0), NULL_RTX
));
3650 emit_move_insn (addr1
, force_operand (XEXP (op1
, 0), NULL_RTX
));
3651 op0
= change_address (op0
, VOIDmode
, addr0
);
3652 op1
= change_address (op1
, VOIDmode
, addr1
);
3654 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3656 emit_move_insn (count
, temp
);
3658 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3660 emit_move_insn (blocks
, temp
);
3662 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3663 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3665 emit_label (loop_start_label
);
3667 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (255)));
3668 temp
= gen_rtx_NE (VOIDmode
, ccreg
, const0_rtx
);
3669 temp
= gen_rtx_IF_THEN_ELSE (VOIDmode
, temp
,
3670 gen_rtx_LABEL_REF (VOIDmode
, end_label
), pc_rtx
);
3671 temp
= gen_rtx_SET (VOIDmode
, pc_rtx
, temp
);
3672 emit_jump_insn (temp
);
3674 s390_load_address (addr0
,
3675 gen_rtx_PLUS (Pmode
, addr0
, GEN_INT (256)));
3676 s390_load_address (addr1
,
3677 gen_rtx_PLUS (Pmode
, addr1
, GEN_INT (256)));
3679 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3681 emit_move_insn (blocks
, temp
);
3683 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3684 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3686 emit_jump (loop_start_label
);
3687 emit_label (loop_end_label
);
3689 emit_insn (gen_cmpmem_short (op0
, op1
,
3690 convert_to_mode (Pmode
, count
, 1)));
3691 emit_label (end_label
);
3693 emit_insn (gen_cmpint (target
, ccreg
));
3698 /* Expand conditional increment or decrement using alc/slb instructions.
3699 Should generate code setting DST to either SRC or SRC + INCREMENT,
3700 depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
3701 Returns true if successful, false otherwise.
3703 That makes it possible to implement some if-constructs without jumps e.g.:
3704 (borrow = CC0 | CC1 and carry = CC2 | CC3)
3705 unsigned int a, b, c;
3706 if (a < b) c++; -> CCU b > a -> CC2; c += carry;
3707 if (a < b) c--; -> CCL3 a - b -> borrow; c -= borrow;
3708 if (a <= b) c++; -> CCL3 b - a -> borrow; c += carry;
3709 if (a <= b) c--; -> CCU a <= b -> borrow; c -= borrow;
3711 Checks for EQ and NE with a nonzero value need an additional xor e.g.:
3712 if (a == b) c++; -> CCL3 a ^= b; 0 - a -> borrow; c += carry;
3713 if (a == b) c--; -> CCU a ^= b; a <= 0 -> CC0 | CC1; c -= borrow;
3714 if (a != b) c++; -> CCU a ^= b; a > 0 -> CC2; c += carry;
3715 if (a != b) c--; -> CCL3 a ^= b; 0 - a -> borrow; c -= borrow; */
3718 s390_expand_addcc (enum rtx_code cmp_code
, rtx cmp_op0
, rtx cmp_op1
,
3719 rtx dst
, rtx src
, rtx increment
)
3721 enum machine_mode cmp_mode
;
3722 enum machine_mode cc_mode
;
3728 if ((GET_MODE (cmp_op0
) == SImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
3729 && (GET_MODE (cmp_op1
) == SImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
3731 else if ((GET_MODE (cmp_op0
) == DImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
3732 && (GET_MODE (cmp_op1
) == DImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
3737 /* Try ADD LOGICAL WITH CARRY. */
3738 if (increment
== const1_rtx
)
3740 /* Determine CC mode to use. */
3741 if (cmp_code
== EQ
|| cmp_code
== NE
)
3743 if (cmp_op1
!= const0_rtx
)
3745 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
3746 NULL_RTX
, 0, OPTAB_WIDEN
);
3747 cmp_op1
= const0_rtx
;
3750 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
3753 if (cmp_code
== LTU
|| cmp_code
== LEU
)
3758 cmp_code
= swap_condition (cmp_code
);
3775 /* Emit comparison instruction pattern. */
3776 if (!register_operand (cmp_op0
, cmp_mode
))
3777 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
3779 insn
= gen_rtx_SET (VOIDmode
, gen_rtx_REG (cc_mode
, CC_REGNUM
),
3780 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
3781 /* We use insn_invalid_p here to add clobbers if required. */
3782 ret
= insn_invalid_p (emit_insn (insn
));
3785 /* Emit ALC instruction pattern. */
3786 op_res
= gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
3787 gen_rtx_REG (cc_mode
, CC_REGNUM
),
3790 if (src
!= const0_rtx
)
3792 if (!register_operand (src
, GET_MODE (dst
)))
3793 src
= force_reg (GET_MODE (dst
), src
);
3795 src
= gen_rtx_PLUS (GET_MODE (dst
), src
, const0_rtx
);
3796 op_res
= gen_rtx_PLUS (GET_MODE (dst
), src
, op_res
);
3799 p
= rtvec_alloc (2);
3801 gen_rtx_SET (VOIDmode
, dst
, op_res
);
3803 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
3804 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
3809 /* Try SUBTRACT LOGICAL WITH BORROW. */
3810 if (increment
== constm1_rtx
)
3812 /* Determine CC mode to use. */
3813 if (cmp_code
== EQ
|| cmp_code
== NE
)
3815 if (cmp_op1
!= const0_rtx
)
3817 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
3818 NULL_RTX
, 0, OPTAB_WIDEN
);
3819 cmp_op1
= const0_rtx
;
3822 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
3825 if (cmp_code
== GTU
|| cmp_code
== GEU
)
3830 cmp_code
= swap_condition (cmp_code
);
3847 /* Emit comparison instruction pattern. */
3848 if (!register_operand (cmp_op0
, cmp_mode
))
3849 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
3851 insn
= gen_rtx_SET (VOIDmode
, gen_rtx_REG (cc_mode
, CC_REGNUM
),
3852 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
3853 /* We use insn_invalid_p here to add clobbers if required. */
3854 ret
= insn_invalid_p (emit_insn (insn
));
3857 /* Emit SLB instruction pattern. */
3858 if (!register_operand (src
, GET_MODE (dst
)))
3859 src
= force_reg (GET_MODE (dst
), src
);
3861 op_res
= gen_rtx_MINUS (GET_MODE (dst
),
3862 gen_rtx_MINUS (GET_MODE (dst
), src
, const0_rtx
),
3863 gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
3864 gen_rtx_REG (cc_mode
, CC_REGNUM
),
3866 p
= rtvec_alloc (2);
3868 gen_rtx_SET (VOIDmode
, dst
, op_res
);
3870 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
3871 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
3879 /* Expand code for the insv template. Return true if successful, false else. */
3882 s390_expand_insv (rtx dest
, rtx op1
, rtx op2
, rtx src
)
3884 int bitsize
= INTVAL (op1
);
3885 int bitpos
= INTVAL (op2
);
3887 /* We need byte alignment. */
3888 if (bitsize
% BITS_PER_UNIT
)
3892 && memory_operand (dest
, VOIDmode
)
3893 && (register_operand (src
, word_mode
)
3894 || const_int_operand (src
, VOIDmode
)))
3896 /* Emit standard pattern if possible. */
3897 enum machine_mode mode
= smallest_mode_for_size (bitsize
, MODE_INT
);
3898 if (GET_MODE_BITSIZE (mode
) == bitsize
)
3899 emit_move_insn (adjust_address (dest
, mode
, 0), gen_lowpart (mode
, src
));
3901 /* (set (ze (mem)) (const_int)). */
3902 else if (const_int_operand (src
, VOIDmode
))
3904 int size
= bitsize
/ BITS_PER_UNIT
;
3905 rtx src_mem
= adjust_address (force_const_mem (word_mode
, src
), BLKmode
,
3906 GET_MODE_SIZE (word_mode
) - size
);
3908 dest
= adjust_address (dest
, BLKmode
, 0);
3909 set_mem_size (dest
, GEN_INT (size
));
3910 s390_expand_movmem (dest
, src_mem
, GEN_INT (size
));
3913 /* (set (ze (mem)) (reg)). */
3914 else if (register_operand (src
, word_mode
))
3916 if (bitsize
<= GET_MODE_BITSIZE (SImode
))
3917 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode
, dest
, op1
,
3921 /* Emit st,stcmh sequence. */
3922 int stcmh_width
= bitsize
- GET_MODE_BITSIZE (SImode
);
3923 int size
= stcmh_width
/ BITS_PER_UNIT
;
3925 emit_move_insn (adjust_address (dest
, SImode
, size
),
3926 gen_lowpart (SImode
, src
));
3927 set_mem_size (dest
, GEN_INT (size
));
3928 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode
, dest
, GEN_INT
3929 (stcmh_width
), const0_rtx
),
3930 gen_rtx_LSHIFTRT (word_mode
, src
, GEN_INT
3931 (GET_MODE_BITSIZE (SImode
))));
3940 /* (set (ze (reg)) (const_int)). */
3942 && register_operand (dest
, word_mode
)
3943 && (bitpos
% 16) == 0
3944 && (bitsize
% 16) == 0
3945 && const_int_operand (src
, VOIDmode
))
3947 HOST_WIDE_INT val
= INTVAL (src
);
3948 int regpos
= bitpos
+ bitsize
;
3950 while (regpos
> bitpos
)
3952 enum machine_mode putmode
;
3955 if (TARGET_EXTIMM
&& (regpos
% 32 == 0) && (regpos
>= bitpos
+ 32))
3960 putsize
= GET_MODE_BITSIZE (putmode
);
3962 emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode
, dest
,
3965 gen_int_mode (val
, putmode
));
3968 gcc_assert (regpos
== bitpos
);
3975 /* A subroutine of s390_expand_cs_hqi and s390_expand_atomic which returns a
3976 register that holds VAL of mode MODE shifted by COUNT bits. */
3979 s390_expand_mask_and_shift (rtx val
, enum machine_mode mode
, rtx count
)
3981 val
= expand_simple_binop (SImode
, AND
, val
, GEN_INT (GET_MODE_MASK (mode
)),
3982 NULL_RTX
, 1, OPTAB_DIRECT
);
3983 return expand_simple_binop (SImode
, ASHIFT
, val
, count
,
3984 NULL_RTX
, 1, OPTAB_DIRECT
);
3987 /* Structure to hold the initial parameters for a compare_and_swap operation
3988 in HImode and QImode. */
3990 struct alignment_context
3992 rtx memsi
; /* SI aligned memory location. */
3993 rtx shift
; /* Bit offset with regard to lsb. */
3994 rtx modemask
; /* Mask of the HQImode shifted by SHIFT bits. */
3995 rtx modemaski
; /* ~modemask */
3996 bool aligned
; /* True if memory is aliged, false else. */
3999 /* A subroutine of s390_expand_cs_hqi and s390_expand_atomic to initialize
4000 structure AC for transparent simplifying, if the memory alignment is known
4001 to be at least 32bit. MEM is the memory location for the actual operation
4002 and MODE its mode. */
4005 init_alignment_context (struct alignment_context
*ac
, rtx mem
,
4006 enum machine_mode mode
)
4008 ac
->shift
= GEN_INT (GET_MODE_SIZE (SImode
) - GET_MODE_SIZE (mode
));
4009 ac
->aligned
= (MEM_ALIGN (mem
) >= GET_MODE_BITSIZE (SImode
));
4012 ac
->memsi
= adjust_address (mem
, SImode
, 0); /* Memory is aligned. */
4015 /* Alignment is unknown. */
4016 rtx byteoffset
, addr
, align
;
4018 /* Force the address into a register. */
4019 addr
= force_reg (Pmode
, XEXP (mem
, 0));
4021 /* Align it to SImode. */
4022 align
= expand_simple_binop (Pmode
, AND
, addr
,
4023 GEN_INT (-GET_MODE_SIZE (SImode
)),
4024 NULL_RTX
, 1, OPTAB_DIRECT
);
4026 ac
->memsi
= gen_rtx_MEM (SImode
, align
);
4027 MEM_VOLATILE_P (ac
->memsi
) = MEM_VOLATILE_P (mem
);
4028 set_mem_align (ac
->memsi
, GET_MODE_BITSIZE (SImode
));
4030 /* Calculate shiftcount. */
4031 byteoffset
= expand_simple_binop (Pmode
, AND
, addr
,
4032 GEN_INT (GET_MODE_SIZE (SImode
) - 1),
4033 NULL_RTX
, 1, OPTAB_DIRECT
);
4034 /* As we already have some offset, evaluate the remaining distance. */
4035 ac
->shift
= expand_simple_binop (SImode
, MINUS
, ac
->shift
, byteoffset
,
4036 NULL_RTX
, 1, OPTAB_DIRECT
);
4039 /* Shift is the byte count, but we need the bitcount. */
4040 ac
->shift
= expand_simple_binop (SImode
, MULT
, ac
->shift
, GEN_INT (BITS_PER_UNIT
),
4041 NULL_RTX
, 1, OPTAB_DIRECT
);
4042 /* Calculate masks. */
4043 ac
->modemask
= expand_simple_binop (SImode
, ASHIFT
,
4044 GEN_INT (GET_MODE_MASK (mode
)), ac
->shift
,
4045 NULL_RTX
, 1, OPTAB_DIRECT
);
4046 ac
->modemaski
= expand_simple_unop (SImode
, NOT
, ac
->modemask
, NULL_RTX
, 1);
4049 /* Expand an atomic compare and swap operation for HImode and QImode. MEM is
4050 the memory location, CMP the old value to compare MEM with and NEW the value
4051 to set if CMP == MEM.
4052 CMP is never in memory for compare_and_swap_cc because
4053 expand_bool_compare_and_swap puts it into a register for later compare. */
4056 s390_expand_cs_hqi (enum machine_mode mode
, rtx target
, rtx mem
, rtx cmp
, rtx
new)
4058 struct alignment_context ac
;
4059 rtx cmpv
, newv
, val
, resv
, cc
;
4060 rtx res
= gen_reg_rtx (SImode
);
4061 rtx csloop
= gen_label_rtx ();
4062 rtx csend
= gen_label_rtx ();
4064 gcc_assert (register_operand (target
, VOIDmode
));
4065 gcc_assert (MEM_P (mem
));
4067 init_alignment_context (&ac
, mem
, mode
);
4069 /* Shift the values to the correct bit positions. */
4070 if (!(ac
.aligned
&& MEM_P (cmp
)))
4071 cmp
= s390_expand_mask_and_shift (cmp
, mode
, ac
.shift
);
4072 if (!(ac
.aligned
&& MEM_P (new)))
4073 new = s390_expand_mask_and_shift (new, mode
, ac
.shift
);
4075 /* Load full word. Subsequent loads are performed by CS. */
4076 val
= expand_simple_binop (SImode
, AND
, ac
.memsi
, ac
.modemaski
,
4077 NULL_RTX
, 1, OPTAB_DIRECT
);
4079 /* Start CS loop. */
4080 emit_label (csloop
);
4081 /* val = "<mem>00..0<mem>"
4082 * cmp = "00..0<cmp>00..0"
4083 * new = "00..0<new>00..0"
4086 /* Patch cmp and new with val at correct position. */
4087 if (ac
.aligned
&& MEM_P (cmp
))
4089 cmpv
= force_reg (SImode
, val
);
4090 store_bit_field (cmpv
, GET_MODE_BITSIZE (mode
), 0, SImode
, cmp
);
4093 cmpv
= force_reg (SImode
, expand_simple_binop (SImode
, IOR
, cmp
, val
,
4094 NULL_RTX
, 1, OPTAB_DIRECT
));
4095 if (ac
.aligned
&& MEM_P (new))
4097 newv
= force_reg (SImode
, val
);
4098 store_bit_field (newv
, GET_MODE_BITSIZE (mode
), 0, SImode
, new);
4101 newv
= force_reg (SImode
, expand_simple_binop (SImode
, IOR
, new, val
,
4102 NULL_RTX
, 1, OPTAB_DIRECT
));
4104 /* Emit compare_and_swap pattern. */
4105 emit_insn (gen_sync_compare_and_swap_ccsi (res
, ac
.memsi
, cmpv
, newv
));
4107 /* Jump to end if we're done (likely?). */
4108 s390_emit_jump (csend
, s390_emit_compare (EQ
, cmpv
, ac
.memsi
));
4110 /* Check for changes outside mode. */
4111 resv
= expand_simple_binop (SImode
, AND
, res
, ac
.modemaski
,
4112 NULL_RTX
, 1, OPTAB_DIRECT
);
4113 cc
= s390_emit_compare (NE
, resv
, val
);
4114 emit_move_insn (val
, resv
);
4115 /* Loop internal if so. */
4116 s390_emit_jump (csloop
, cc
);
4120 /* Return the correct part of the bitfield. */
4121 convert_move (target
, expand_simple_binop (SImode
, LSHIFTRT
, res
, ac
.shift
,
4122 NULL_RTX
, 1, OPTAB_DIRECT
), 1);
4125 /* Expand an atomic operation CODE of mode MODE. MEM is the memory location
4126 and VAL the value to play with. If AFTER is true then store the the value
4127 MEM holds after the operation, if AFTER is false then store the value MEM
4128 holds before the operation. If TARGET is zero then discard that value, else
4129 store it to TARGET. */
4132 s390_expand_atomic (enum machine_mode mode
, enum rtx_code code
,
4133 rtx target
, rtx mem
, rtx val
, bool after
)
4135 struct alignment_context ac
;
4137 rtx
new = gen_reg_rtx (SImode
);
4138 rtx orig
= gen_reg_rtx (SImode
);
4139 rtx csloop
= gen_label_rtx ();
4141 gcc_assert (!target
|| register_operand (target
, VOIDmode
));
4142 gcc_assert (MEM_P (mem
));
4144 init_alignment_context (&ac
, mem
, mode
);
4146 /* Shift val to the correct bit positions.
4147 Preserve "icm", but prevent "ex icm". */
4148 if (!(ac
.aligned
&& code
== SET
&& MEM_P (val
)))
4149 val
= s390_expand_mask_and_shift (val
, mode
, ac
.shift
);
4151 /* Further preparation insns. */
4152 if (code
== PLUS
|| code
== MINUS
)
4153 emit_move_insn (orig
, val
);
4154 else if (code
== MULT
|| code
== AND
) /* val = "11..1<val>11..1" */
4155 val
= expand_simple_binop (SImode
, XOR
, val
, ac
.modemaski
,
4156 NULL_RTX
, 1, OPTAB_DIRECT
);
4158 /* Load full word. Subsequent loads are performed by CS. */
4159 cmp
= force_reg (SImode
, ac
.memsi
);
4161 /* Start CS loop. */
4162 emit_label (csloop
);
4163 emit_move_insn (new, cmp
);
4165 /* Patch new with val at correct position. */
4170 val
= expand_simple_binop (SImode
, code
, new, orig
,
4171 NULL_RTX
, 1, OPTAB_DIRECT
);
4172 val
= expand_simple_binop (SImode
, AND
, val
, ac
.modemask
,
4173 NULL_RTX
, 1, OPTAB_DIRECT
);
4176 if (ac
.aligned
&& MEM_P (val
))
4177 store_bit_field (new, GET_MODE_BITSIZE (mode
), 0, SImode
, val
);
4180 new = expand_simple_binop (SImode
, AND
, new, ac
.modemaski
,
4181 NULL_RTX
, 1, OPTAB_DIRECT
);
4182 new = expand_simple_binop (SImode
, IOR
, new, val
,
4183 NULL_RTX
, 1, OPTAB_DIRECT
);
4189 new = expand_simple_binop (SImode
, code
, new, val
,
4190 NULL_RTX
, 1, OPTAB_DIRECT
);
4192 case MULT
: /* NAND */
4193 new = expand_simple_binop (SImode
, XOR
, new, ac
.modemask
,
4194 NULL_RTX
, 1, OPTAB_DIRECT
);
4195 new = expand_simple_binop (SImode
, AND
, new, val
,
4196 NULL_RTX
, 1, OPTAB_DIRECT
);
4201 /* Emit compare_and_swap pattern. */
4202 emit_insn (gen_sync_compare_and_swap_ccsi (cmp
, ac
.memsi
, cmp
, new));
4204 /* Loop until swapped (unlikely?). */
4205 s390_emit_jump (csloop
, gen_rtx_fmt_ee (NE
, CCZ1mode
,
4206 gen_rtx_REG (CCZ1mode
, CC_REGNUM
),
4209 /* Return the correct part of the bitfield. */
4211 convert_move (target
, expand_simple_binop (SImode
, LSHIFTRT
,
4212 after
? new : cmp
, ac
.shift
,
4213 NULL_RTX
, 1, OPTAB_DIRECT
), 1);
4216 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
4217 We need to emit DTP-relative relocations. */
4219 static void s390_output_dwarf_dtprel (FILE *, int, rtx
) ATTRIBUTE_UNUSED
;
4222 s390_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
4227 fputs ("\t.long\t", file
);
4230 fputs ("\t.quad\t", file
);
4235 output_addr_const (file
, x
);
4236 fputs ("@DTPOFF", file
);
4239 /* In the name of slightly smaller debug output, and to cater to
4240 general assembler lossage, recognize various UNSPEC sequences
4241 and turn them back into a direct symbol reference. */
4244 s390_delegitimize_address (rtx orig_x
)
4248 if (GET_CODE (x
) != MEM
)
4252 if (GET_CODE (x
) == PLUS
4253 && GET_CODE (XEXP (x
, 1)) == CONST
4254 && GET_CODE (XEXP (x
, 0)) == REG
4255 && REGNO (XEXP (x
, 0)) == PIC_OFFSET_TABLE_REGNUM
)
4257 y
= XEXP (XEXP (x
, 1), 0);
4258 if (GET_CODE (y
) == UNSPEC
4259 && XINT (y
, 1) == UNSPEC_GOT
)
4260 return XVECEXP (y
, 0, 0);
4264 if (GET_CODE (x
) == CONST
)
4267 if (GET_CODE (y
) == UNSPEC
4268 && XINT (y
, 1) == UNSPEC_GOTENT
)
4269 return XVECEXP (y
, 0, 0);
4276 /* Output operand OP to stdio stream FILE.
4277 OP is an address (register + offset) which is not used to address data;
4278 instead the rightmost bits are interpreted as the value. */
4281 print_shift_count_operand (FILE *file
, rtx op
)
4283 HOST_WIDE_INT offset
;
4286 /* Extract base register and offset. */
4287 if (!s390_decompose_shift_count (op
, &base
, &offset
, 0))
4293 gcc_assert (GET_CODE (base
) == REG
);
4294 gcc_assert (REGNO (base
) < FIRST_PSEUDO_REGISTER
);
4295 gcc_assert (REGNO_REG_CLASS (REGNO (base
)) == ADDR_REGS
);
4298 /* Offsets are constricted to twelve bits. */
4299 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
& ((1 << 12) - 1));
4301 fprintf (file
, "(%s)", reg_names
[REGNO (base
)]);
4304 /* See 'get_some_local_dynamic_name'. */
4307 get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
4311 if (GET_CODE (x
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (x
))
4313 x
= get_pool_constant (x
);
4314 return for_each_rtx (&x
, get_some_local_dynamic_name_1
, 0);
4317 if (GET_CODE (x
) == SYMBOL_REF
4318 && tls_symbolic_operand (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
4320 cfun
->machine
->some_ld_name
= XSTR (x
, 0);
4327 /* Locate some local-dynamic symbol still in use by this function
4328 so that we can print its name in local-dynamic base patterns. */
4331 get_some_local_dynamic_name (void)
4335 if (cfun
->machine
->some_ld_name
)
4336 return cfun
->machine
->some_ld_name
;
4338 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
4340 && for_each_rtx (&PATTERN (insn
), get_some_local_dynamic_name_1
, 0))
4341 return cfun
->machine
->some_ld_name
;
4346 /* Output machine-dependent UNSPECs occurring in address constant X
4347 in assembler syntax to stdio stream FILE. Returns true if the
4348 constant X could be recognized, false otherwise. */
4351 s390_output_addr_const_extra (FILE *file
, rtx x
)
4353 if (GET_CODE (x
) == UNSPEC
&& XVECLEN (x
, 0) == 1)
4354 switch (XINT (x
, 1))
4357 output_addr_const (file
, XVECEXP (x
, 0, 0));
4358 fprintf (file
, "@GOTENT");
4361 output_addr_const (file
, XVECEXP (x
, 0, 0));
4362 fprintf (file
, "@GOT");
4365 output_addr_const (file
, XVECEXP (x
, 0, 0));
4366 fprintf (file
, "@GOTOFF");
4369 output_addr_const (file
, XVECEXP (x
, 0, 0));
4370 fprintf (file
, "@PLT");
4373 output_addr_const (file
, XVECEXP (x
, 0, 0));
4374 fprintf (file
, "@PLTOFF");
4377 output_addr_const (file
, XVECEXP (x
, 0, 0));
4378 fprintf (file
, "@TLSGD");
4381 assemble_name (file
, get_some_local_dynamic_name ());
4382 fprintf (file
, "@TLSLDM");
4385 output_addr_const (file
, XVECEXP (x
, 0, 0));
4386 fprintf (file
, "@DTPOFF");
4389 output_addr_const (file
, XVECEXP (x
, 0, 0));
4390 fprintf (file
, "@NTPOFF");
4392 case UNSPEC_GOTNTPOFF
:
4393 output_addr_const (file
, XVECEXP (x
, 0, 0));
4394 fprintf (file
, "@GOTNTPOFF");
4396 case UNSPEC_INDNTPOFF
:
4397 output_addr_const (file
, XVECEXP (x
, 0, 0));
4398 fprintf (file
, "@INDNTPOFF");
4405 /* Output address operand ADDR in assembler syntax to
4406 stdio stream FILE. */
4409 print_operand_address (FILE *file
, rtx addr
)
4411 struct s390_address ad
;
4413 if (!s390_decompose_address (addr
, &ad
)
4414 || (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
4415 || (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
)))
4416 output_operand_lossage ("cannot decompose address");
4419 output_addr_const (file
, ad
.disp
);
4421 fprintf (file
, "0");
4423 if (ad
.base
&& ad
.indx
)
4424 fprintf (file
, "(%s,%s)", reg_names
[REGNO (ad
.indx
)],
4425 reg_names
[REGNO (ad
.base
)]);
4427 fprintf (file
, "(%s)", reg_names
[REGNO (ad
.base
)]);
4430 /* Output operand X in assembler syntax to stdio stream FILE.
4431 CODE specified the format flag. The following format flags
4434 'C': print opcode suffix for branch condition.
4435 'D': print opcode suffix for inverse branch condition.
4436 'J': print tls_load/tls_gdcall/tls_ldcall suffix
4437 'G': print the size of the operand in bytes.
4438 'O': print only the displacement of a memory reference.
4439 'R': print only the base register of a memory reference.
4440 'S': print S-type memory reference (base+displacement).
4441 'N': print the second word of a DImode operand.
4442 'M': print the second word of a TImode operand.
4443 'Y': print shift count operand.
4445 'b': print integer X as if it's an unsigned byte.
4446 'x': print integer X as if it's an unsigned halfword.
4447 'h': print integer X as if it's a signed halfword.
4448 'i': print the first nonzero HImode part of X.
4449 'j': print the first HImode part unequal to -1 of X.
4450 'k': print the first nonzero SImode part of X.
4451 'm': print the first SImode part unequal to -1 of X.
4452 'o': print integer X as if it's an unsigned 32bit word. */
4455 print_operand (FILE *file
, rtx x
, int code
)
4460 fprintf (file
, s390_branch_condition_mnemonic (x
, FALSE
));
4464 fprintf (file
, s390_branch_condition_mnemonic (x
, TRUE
));
4468 if (GET_CODE (x
) == SYMBOL_REF
)
4470 fprintf (file
, "%s", ":tls_load:");
4471 output_addr_const (file
, x
);
4473 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSGD
)
4475 fprintf (file
, "%s", ":tls_gdcall:");
4476 output_addr_const (file
, XVECEXP (x
, 0, 0));
4478 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSLDM
)
4480 fprintf (file
, "%s", ":tls_ldcall:");
4481 assemble_name (file
, get_some_local_dynamic_name ());
4488 fprintf (file
, "%u", GET_MODE_SIZE (GET_MODE (x
)));
4493 struct s390_address ad
;
4496 gcc_assert (GET_CODE (x
) == MEM
);
4497 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
4499 gcc_assert (!ad
.base
|| REG_OK_FOR_BASE_STRICT_P (ad
.base
));
4500 gcc_assert (!ad
.indx
);
4503 output_addr_const (file
, ad
.disp
);
4505 fprintf (file
, "0");
4511 struct s390_address ad
;
4514 gcc_assert (GET_CODE (x
) == MEM
);
4515 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
4517 gcc_assert (!ad
.base
|| REG_OK_FOR_BASE_STRICT_P (ad
.base
));
4518 gcc_assert (!ad
.indx
);
4521 fprintf (file
, "%s", reg_names
[REGNO (ad
.base
)]);
4523 fprintf (file
, "0");
4529 struct s390_address ad
;
4532 gcc_assert (GET_CODE (x
) == MEM
);
4533 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
4535 gcc_assert (!ad
.base
|| REG_OK_FOR_BASE_STRICT_P (ad
.base
));
4536 gcc_assert (!ad
.indx
);
4539 output_addr_const (file
, ad
.disp
);
4541 fprintf (file
, "0");
4544 fprintf (file
, "(%s)", reg_names
[REGNO (ad
.base
)]);
4549 if (GET_CODE (x
) == REG
)
4550 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
4551 else if (GET_CODE (x
) == MEM
)
4552 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 4));
4558 if (GET_CODE (x
) == REG
)
4559 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
4560 else if (GET_CODE (x
) == MEM
)
4561 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 8));
4567 print_shift_count_operand (file
, x
);
4571 switch (GET_CODE (x
))
4574 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
4578 output_address (XEXP (x
, 0));
4585 output_addr_const (file
, x
);
4590 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xff);
4591 else if (code
== 'x')
4592 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xffff);
4593 else if (code
== 'h')
4594 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((INTVAL (x
) & 0xffff) ^ 0x8000) - 0x8000);
4595 else if (code
== 'i')
4596 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
4597 s390_extract_part (x
, HImode
, 0));
4598 else if (code
== 'j')
4599 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
4600 s390_extract_part (x
, HImode
, -1));
4601 else if (code
== 'k')
4602 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
4603 s390_extract_part (x
, SImode
, 0));
4604 else if (code
== 'm')
4605 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
4606 s390_extract_part (x
, SImode
, -1));
4607 else if (code
== 'o')
4608 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xffffffff);
4610 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
4614 gcc_assert (GET_MODE (x
) == VOIDmode
);
4616 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xff);
4617 else if (code
== 'x')
4618 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xffff);
4619 else if (code
== 'h')
4620 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((CONST_DOUBLE_LOW (x
) & 0xffff) ^ 0x8000) - 0x8000);
4626 fatal_insn ("UNKNOWN in print_operand !?", x
);
4631 /* Target hook for assembling integer objects. We need to define it
4632 here to work a round a bug in some versions of GAS, which couldn't
4633 handle values smaller than INT_MIN when printed in decimal. */
4636 s390_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
4638 if (size
== 8 && aligned_p
4639 && GET_CODE (x
) == CONST_INT
&& INTVAL (x
) < INT_MIN
)
4641 fprintf (asm_out_file
, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX
"\n",
4645 return default_assemble_integer (x
, size
, aligned_p
);
4648 /* Returns true if register REGNO is used for forming
4649 a memory address in expression X. */
4652 reg_used_in_mem_p (int regno
, rtx x
)
4654 enum rtx_code code
= GET_CODE (x
);
4660 if (refers_to_regno_p (regno
, regno
+1,
4664 else if (code
== SET
4665 && GET_CODE (SET_DEST (x
)) == PC
)
4667 if (refers_to_regno_p (regno
, regno
+1,
4672 fmt
= GET_RTX_FORMAT (code
);
4673 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
4676 && reg_used_in_mem_p (regno
, XEXP (x
, i
)))
4679 else if (fmt
[i
] == 'E')
4680 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
4681 if (reg_used_in_mem_p (regno
, XVECEXP (x
, i
, j
)))
4687 /* Returns true if expression DEP_RTX sets an address register
4688 used by instruction INSN to address memory. */
4691 addr_generation_dependency_p (rtx dep_rtx
, rtx insn
)
4695 if (GET_CODE (dep_rtx
) == INSN
)
4696 dep_rtx
= PATTERN (dep_rtx
);
4698 if (GET_CODE (dep_rtx
) == SET
)
4700 target
= SET_DEST (dep_rtx
);
4701 if (GET_CODE (target
) == STRICT_LOW_PART
)
4702 target
= XEXP (target
, 0);
4703 while (GET_CODE (target
) == SUBREG
)
4704 target
= SUBREG_REG (target
);
4706 if (GET_CODE (target
) == REG
)
4708 int regno
= REGNO (target
);
4710 if (s390_safe_attr_type (insn
) == TYPE_LA
)
4712 pat
= PATTERN (insn
);
4713 if (GET_CODE (pat
) == PARALLEL
)
4715 gcc_assert (XVECLEN (pat
, 0) == 2);
4716 pat
= XVECEXP (pat
, 0, 0);
4718 gcc_assert (GET_CODE (pat
) == SET
);
4719 return refers_to_regno_p (regno
, regno
+1, SET_SRC (pat
), 0);
4721 else if (get_attr_atype (insn
) == ATYPE_AGEN
)
4722 return reg_used_in_mem_p (regno
, PATTERN (insn
));
4728 /* Return 1, if dep_insn sets register used in insn in the agen unit. */
4731 s390_agen_dep_p (rtx dep_insn
, rtx insn
)
4733 rtx dep_rtx
= PATTERN (dep_insn
);
4736 if (GET_CODE (dep_rtx
) == SET
4737 && addr_generation_dependency_p (dep_rtx
, insn
))
4739 else if (GET_CODE (dep_rtx
) == PARALLEL
)
4741 for (i
= 0; i
< XVECLEN (dep_rtx
, 0); i
++)
4743 if (addr_generation_dependency_p (XVECEXP (dep_rtx
, 0, i
), insn
))
4750 /* A C statement (sans semicolon) to update the integer scheduling priority
4751 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
4752 reduce the priority to execute INSN later. Do not define this macro if
4753 you do not need to adjust the scheduling priorities of insns.
4755 A STD instruction should be scheduled earlier,
4756 in order to use the bypass. */
4759 s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
4761 if (! INSN_P (insn
))
4764 if (s390_tune
!= PROCESSOR_2084_Z990
4765 && s390_tune
!= PROCESSOR_2094_Z9_109
)
4768 switch (s390_safe_attr_type (insn
))
4772 priority
= priority
<< 3;
4776 priority
= priority
<< 1;
4784 /* The number of instructions that can be issued per cycle. */
4787 s390_issue_rate (void)
4789 if (s390_tune
== PROCESSOR_2084_Z990
4790 || s390_tune
== PROCESSOR_2094_Z9_109
)
4796 s390_first_cycle_multipass_dfa_lookahead (void)
4802 /* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
4803 Fix up MEMs as required. */
4806 annotate_constant_pool_refs (rtx
*x
)
4811 gcc_assert (GET_CODE (*x
) != SYMBOL_REF
4812 || !CONSTANT_POOL_ADDRESS_P (*x
));
4814 /* Literal pool references can only occur inside a MEM ... */
4815 if (GET_CODE (*x
) == MEM
)
4817 rtx memref
= XEXP (*x
, 0);
4819 if (GET_CODE (memref
) == SYMBOL_REF
4820 && CONSTANT_POOL_ADDRESS_P (memref
))
4822 rtx base
= cfun
->machine
->base_reg
;
4823 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, memref
, base
),
4826 *x
= replace_equiv_address (*x
, addr
);
4830 if (GET_CODE (memref
) == CONST
4831 && GET_CODE (XEXP (memref
, 0)) == PLUS
4832 && GET_CODE (XEXP (XEXP (memref
, 0), 1)) == CONST_INT
4833 && GET_CODE (XEXP (XEXP (memref
, 0), 0)) == SYMBOL_REF
4834 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (memref
, 0), 0)))
4836 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (memref
, 0), 1));
4837 rtx sym
= XEXP (XEXP (memref
, 0), 0);
4838 rtx base
= cfun
->machine
->base_reg
;
4839 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
4842 *x
= replace_equiv_address (*x
, plus_constant (addr
, off
));
4847 /* ... or a load-address type pattern. */
4848 if (GET_CODE (*x
) == SET
)
4850 rtx addrref
= SET_SRC (*x
);
4852 if (GET_CODE (addrref
) == SYMBOL_REF
4853 && CONSTANT_POOL_ADDRESS_P (addrref
))
4855 rtx base
= cfun
->machine
->base_reg
;
4856 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, addrref
, base
),
4859 SET_SRC (*x
) = addr
;
4863 if (GET_CODE (addrref
) == CONST
4864 && GET_CODE (XEXP (addrref
, 0)) == PLUS
4865 && GET_CODE (XEXP (XEXP (addrref
, 0), 1)) == CONST_INT
4866 && GET_CODE (XEXP (XEXP (addrref
, 0), 0)) == SYMBOL_REF
4867 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (addrref
, 0), 0)))
4869 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (addrref
, 0), 1));
4870 rtx sym
= XEXP (XEXP (addrref
, 0), 0);
4871 rtx base
= cfun
->machine
->base_reg
;
4872 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
4875 SET_SRC (*x
) = plus_constant (addr
, off
);
4880 /* Annotate LTREL_BASE as well. */
4881 if (GET_CODE (*x
) == UNSPEC
4882 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
4884 rtx base
= cfun
->machine
->base_reg
;
4885 *x
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XVECEXP (*x
, 0, 0), base
),
4890 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
4891 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
4895 annotate_constant_pool_refs (&XEXP (*x
, i
));
4897 else if (fmt
[i
] == 'E')
4899 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
4900 annotate_constant_pool_refs (&XVECEXP (*x
, i
, j
));
4905 /* Split all branches that exceed the maximum distance.
4906 Returns true if this created a new literal pool entry. */
4909 s390_split_branches (void)
4911 rtx temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
4912 int new_literal
= 0, ret
;
4913 rtx insn
, pat
, tmp
, target
;
4916 /* We need correct insn addresses. */
4918 shorten_branches (get_insns ());
4920 /* Find all branches that exceed 64KB, and split them. */
4922 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
4924 if (GET_CODE (insn
) != JUMP_INSN
)
4927 pat
= PATTERN (insn
);
4928 if (GET_CODE (pat
) == PARALLEL
&& XVECLEN (pat
, 0) > 2)
4929 pat
= XVECEXP (pat
, 0, 0);
4930 if (GET_CODE (pat
) != SET
|| SET_DEST (pat
) != pc_rtx
)
4933 if (GET_CODE (SET_SRC (pat
)) == LABEL_REF
)
4935 label
= &SET_SRC (pat
);
4937 else if (GET_CODE (SET_SRC (pat
)) == IF_THEN_ELSE
)
4939 if (GET_CODE (XEXP (SET_SRC (pat
), 1)) == LABEL_REF
)
4940 label
= &XEXP (SET_SRC (pat
), 1);
4941 else if (GET_CODE (XEXP (SET_SRC (pat
), 2)) == LABEL_REF
)
4942 label
= &XEXP (SET_SRC (pat
), 2);
4949 if (get_attr_length (insn
) <= 4)
4952 /* We are going to use the return register as scratch register,
4953 make sure it will be saved/restored by the prologue/epilogue. */
4954 cfun_frame_layout
.save_return_addr_p
= 1;
4959 tmp
= force_const_mem (Pmode
, *label
);
4960 tmp
= emit_insn_before (gen_rtx_SET (Pmode
, temp_reg
, tmp
), insn
);
4961 INSN_ADDRESSES_NEW (tmp
, -1);
4962 annotate_constant_pool_refs (&PATTERN (tmp
));
4969 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, *label
),
4970 UNSPEC_LTREL_OFFSET
);
4971 target
= gen_rtx_CONST (Pmode
, target
);
4972 target
= force_const_mem (Pmode
, target
);
4973 tmp
= emit_insn_before (gen_rtx_SET (Pmode
, temp_reg
, target
), insn
);
4974 INSN_ADDRESSES_NEW (tmp
, -1);
4975 annotate_constant_pool_refs (&PATTERN (tmp
));
4977 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XEXP (target
, 0),
4978 cfun
->machine
->base_reg
),
4980 target
= gen_rtx_PLUS (Pmode
, temp_reg
, target
);
4983 ret
= validate_change (insn
, label
, target
, 0);
4991 /* Find an annotated literal pool symbol referenced in RTX X,
4992 and store it at REF. Will abort if X contains references to
4993 more than one such pool symbol; multiple references to the same
4994 symbol are allowed, however.
4996 The rtx pointed to by REF must be initialized to NULL_RTX
4997 by the caller before calling this routine. */
5000 find_constant_pool_ref (rtx x
, rtx
*ref
)
5005 /* Ignore LTREL_BASE references. */
5006 if (GET_CODE (x
) == UNSPEC
5007 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
5009 /* Likewise POOL_ENTRY insns. */
5010 if (GET_CODE (x
) == UNSPEC_VOLATILE
5011 && XINT (x
, 1) == UNSPECV_POOL_ENTRY
)
5014 gcc_assert (GET_CODE (x
) != SYMBOL_REF
5015 || !CONSTANT_POOL_ADDRESS_P (x
));
5017 if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_LTREF
)
5019 rtx sym
= XVECEXP (x
, 0, 0);
5020 gcc_assert (GET_CODE (sym
) == SYMBOL_REF
5021 && CONSTANT_POOL_ADDRESS_P (sym
));
5023 if (*ref
== NULL_RTX
)
5026 gcc_assert (*ref
== sym
);
5031 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
5032 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
5036 find_constant_pool_ref (XEXP (x
, i
), ref
);
5038 else if (fmt
[i
] == 'E')
5040 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
5041 find_constant_pool_ref (XVECEXP (x
, i
, j
), ref
);
5046 /* Replace every reference to the annotated literal pool
5047 symbol REF in X by its base plus OFFSET. */
5050 replace_constant_pool_ref (rtx
*x
, rtx ref
, rtx offset
)
5055 gcc_assert (*x
!= ref
);
5057 if (GET_CODE (*x
) == UNSPEC
5058 && XINT (*x
, 1) == UNSPEC_LTREF
5059 && XVECEXP (*x
, 0, 0) == ref
)
5061 *x
= gen_rtx_PLUS (Pmode
, XVECEXP (*x
, 0, 1), offset
);
5065 if (GET_CODE (*x
) == PLUS
5066 && GET_CODE (XEXP (*x
, 1)) == CONST_INT
5067 && GET_CODE (XEXP (*x
, 0)) == UNSPEC
5068 && XINT (XEXP (*x
, 0), 1) == UNSPEC_LTREF
5069 && XVECEXP (XEXP (*x
, 0), 0, 0) == ref
)
5071 rtx addr
= gen_rtx_PLUS (Pmode
, XVECEXP (XEXP (*x
, 0), 0, 1), offset
);
5072 *x
= plus_constant (addr
, INTVAL (XEXP (*x
, 1)));
5076 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
5077 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
5081 replace_constant_pool_ref (&XEXP (*x
, i
), ref
, offset
);
5083 else if (fmt
[i
] == 'E')
5085 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
5086 replace_constant_pool_ref (&XVECEXP (*x
, i
, j
), ref
, offset
);
5091 /* Check whether X contains an UNSPEC_LTREL_BASE.
5092 Return its constant pool symbol if found, NULL_RTX otherwise. */
5095 find_ltrel_base (rtx x
)
5100 if (GET_CODE (x
) == UNSPEC
5101 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
5102 return XVECEXP (x
, 0, 0);
5104 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
5105 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
5109 rtx fnd
= find_ltrel_base (XEXP (x
, i
));
5113 else if (fmt
[i
] == 'E')
5115 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
5117 rtx fnd
= find_ltrel_base (XVECEXP (x
, i
, j
));
5127 /* Replace any occurrence of UNSPEC_LTREL_BASE in X with its base. */
5130 replace_ltrel_base (rtx
*x
)
5135 if (GET_CODE (*x
) == UNSPEC
5136 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
5138 *x
= XVECEXP (*x
, 0, 1);
5142 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
5143 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
5147 replace_ltrel_base (&XEXP (*x
, i
));
5149 else if (fmt
[i
] == 'E')
5151 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
5152 replace_ltrel_base (&XVECEXP (*x
, i
, j
));
5158 /* We keep a list of constants which we have to add to internal
5159 constant tables in the middle of large functions. */
5161 #define NR_C_MODES 7
5162 enum machine_mode constant_modes
[NR_C_MODES
] =
5173 struct constant
*next
;
5178 struct constant_pool
5180 struct constant_pool
*next
;
5185 struct constant
*constants
[NR_C_MODES
];
5186 struct constant
*execute
;
5191 /* Allocate new constant_pool structure. */
5193 static struct constant_pool
*
5194 s390_alloc_pool (void)
5196 struct constant_pool
*pool
;
5199 pool
= (struct constant_pool
*) xmalloc (sizeof *pool
);
5201 for (i
= 0; i
< NR_C_MODES
; i
++)
5202 pool
->constants
[i
] = NULL
;
5204 pool
->execute
= NULL
;
5205 pool
->label
= gen_label_rtx ();
5206 pool
->first_insn
= NULL_RTX
;
5207 pool
->pool_insn
= NULL_RTX
;
5208 pool
->insns
= BITMAP_ALLOC (NULL
);
5214 /* Create new constant pool covering instructions starting at INSN
5215 and chain it to the end of POOL_LIST. */
5217 static struct constant_pool
*
5218 s390_start_pool (struct constant_pool
**pool_list
, rtx insn
)
5220 struct constant_pool
*pool
, **prev
;
5222 pool
= s390_alloc_pool ();
5223 pool
->first_insn
= insn
;
5225 for (prev
= pool_list
; *prev
; prev
= &(*prev
)->next
)
5232 /* End range of instructions covered by POOL at INSN and emit
5233 placeholder insn representing the pool. */
5236 s390_end_pool (struct constant_pool
*pool
, rtx insn
)
5238 rtx pool_size
= GEN_INT (pool
->size
+ 8 /* alignment slop */);
5241 insn
= get_last_insn ();
5243 pool
->pool_insn
= emit_insn_after (gen_pool (pool_size
), insn
);
5244 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
5247 /* Add INSN to the list of insns covered by POOL. */
5250 s390_add_pool_insn (struct constant_pool
*pool
, rtx insn
)
5252 bitmap_set_bit (pool
->insns
, INSN_UID (insn
));
5255 /* Return pool out of POOL_LIST that covers INSN. */
5257 static struct constant_pool
*
5258 s390_find_pool (struct constant_pool
*pool_list
, rtx insn
)
5260 struct constant_pool
*pool
;
5262 for (pool
= pool_list
; pool
; pool
= pool
->next
)
5263 if (bitmap_bit_p (pool
->insns
, INSN_UID (insn
)))
5269 /* Add constant VAL of mode MODE to the constant pool POOL. */
5272 s390_add_constant (struct constant_pool
*pool
, rtx val
, enum machine_mode mode
)
5277 for (i
= 0; i
< NR_C_MODES
; i
++)
5278 if (constant_modes
[i
] == mode
)
5280 gcc_assert (i
!= NR_C_MODES
);
5282 for (c
= pool
->constants
[i
]; c
!= NULL
; c
= c
->next
)
5283 if (rtx_equal_p (val
, c
->value
))
5288 c
= (struct constant
*) xmalloc (sizeof *c
);
5290 c
->label
= gen_label_rtx ();
5291 c
->next
= pool
->constants
[i
];
5292 pool
->constants
[i
] = c
;
5293 pool
->size
+= GET_MODE_SIZE (mode
);
5297 /* Find constant VAL of mode MODE in the constant pool POOL.
5298 Return an RTX describing the distance from the start of
5299 the pool to the location of the new constant. */
5302 s390_find_constant (struct constant_pool
*pool
, rtx val
,
5303 enum machine_mode mode
)
5309 for (i
= 0; i
< NR_C_MODES
; i
++)
5310 if (constant_modes
[i
] == mode
)
5312 gcc_assert (i
!= NR_C_MODES
);
5314 for (c
= pool
->constants
[i
]; c
!= NULL
; c
= c
->next
)
5315 if (rtx_equal_p (val
, c
->value
))
5320 offset
= gen_rtx_MINUS (Pmode
, gen_rtx_LABEL_REF (Pmode
, c
->label
),
5321 gen_rtx_LABEL_REF (Pmode
, pool
->label
));
5322 offset
= gen_rtx_CONST (Pmode
, offset
);
5326 /* Check whether INSN is an execute. Return the label_ref to its
5327 execute target template if so, NULL_RTX otherwise. */
5330 s390_execute_label (rtx insn
)
5332 if (GET_CODE (insn
) == INSN
5333 && GET_CODE (PATTERN (insn
)) == PARALLEL
5334 && GET_CODE (XVECEXP (PATTERN (insn
), 0, 0)) == UNSPEC
5335 && XINT (XVECEXP (PATTERN (insn
), 0, 0), 1) == UNSPEC_EXECUTE
)
5336 return XVECEXP (XVECEXP (PATTERN (insn
), 0, 0), 0, 2);
5341 /* Add execute target for INSN to the constant pool POOL. */
5344 s390_add_execute (struct constant_pool
*pool
, rtx insn
)
5348 for (c
= pool
->execute
; c
!= NULL
; c
= c
->next
)
5349 if (INSN_UID (insn
) == INSN_UID (c
->value
))
5354 c
= (struct constant
*) xmalloc (sizeof *c
);
5356 c
->label
= gen_label_rtx ();
5357 c
->next
= pool
->execute
;
5363 /* Find execute target for INSN in the constant pool POOL.
5364 Return an RTX describing the distance from the start of
5365 the pool to the location of the execute target. */
5368 s390_find_execute (struct constant_pool
*pool
, rtx insn
)
5373 for (c
= pool
->execute
; c
!= NULL
; c
= c
->next
)
5374 if (INSN_UID (insn
) == INSN_UID (c
->value
))
5379 offset
= gen_rtx_MINUS (Pmode
, gen_rtx_LABEL_REF (Pmode
, c
->label
),
5380 gen_rtx_LABEL_REF (Pmode
, pool
->label
));
5381 offset
= gen_rtx_CONST (Pmode
, offset
);
5385 /* For an execute INSN, extract the execute target template. */
5388 s390_execute_target (rtx insn
)
5390 rtx pattern
= PATTERN (insn
);
5391 gcc_assert (s390_execute_label (insn
));
5393 if (XVECLEN (pattern
, 0) == 2)
5395 pattern
= copy_rtx (XVECEXP (pattern
, 0, 1));
5399 rtvec vec
= rtvec_alloc (XVECLEN (pattern
, 0) - 1);
5402 for (i
= 0; i
< XVECLEN (pattern
, 0) - 1; i
++)
5403 RTVEC_ELT (vec
, i
) = copy_rtx (XVECEXP (pattern
, 0, i
+ 1));
5405 pattern
= gen_rtx_PARALLEL (VOIDmode
, vec
);
5411 /* Indicate that INSN cannot be duplicated. This is the case for
5412 execute insns that carry a unique label. */
5415 s390_cannot_copy_insn_p (rtx insn
)
5417 rtx label
= s390_execute_label (insn
);
5418 return label
&& label
!= const0_rtx
;
5421 /* Dump out the constants in POOL. If REMOTE_LABEL is true,
5422 do not emit the pool base label. */
5425 s390_dump_pool (struct constant_pool
*pool
, bool remote_label
)
5428 rtx insn
= pool
->pool_insn
;
5431 /* Switch to rodata section. */
5432 if (TARGET_CPU_ZARCH
)
5434 insn
= emit_insn_after (gen_pool_section_start (), insn
);
5435 INSN_ADDRESSES_NEW (insn
, -1);
5438 /* Ensure minimum pool alignment. */
5439 if (TARGET_CPU_ZARCH
)
5440 insn
= emit_insn_after (gen_pool_align (GEN_INT (8)), insn
);
5442 insn
= emit_insn_after (gen_pool_align (GEN_INT (4)), insn
);
5443 INSN_ADDRESSES_NEW (insn
, -1);
5445 /* Emit pool base label. */
5448 insn
= emit_label_after (pool
->label
, insn
);
5449 INSN_ADDRESSES_NEW (insn
, -1);
5452 /* Dump constants in descending alignment requirement order,
5453 ensuring proper alignment for every constant. */
5454 for (i
= 0; i
< NR_C_MODES
; i
++)
5455 for (c
= pool
->constants
[i
]; c
; c
= c
->next
)
5457 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
5458 rtx value
= c
->value
;
5459 if (GET_CODE (value
) == CONST
5460 && GET_CODE (XEXP (value
, 0)) == UNSPEC
5461 && XINT (XEXP (value
, 0), 1) == UNSPEC_LTREL_OFFSET
5462 && XVECLEN (XEXP (value
, 0), 0) == 1)
5464 value
= gen_rtx_MINUS (Pmode
, XVECEXP (XEXP (value
, 0), 0, 0),
5465 gen_rtx_LABEL_REF (VOIDmode
, pool
->label
));
5466 value
= gen_rtx_CONST (VOIDmode
, value
);
5469 insn
= emit_label_after (c
->label
, insn
);
5470 INSN_ADDRESSES_NEW (insn
, -1);
5472 value
= gen_rtx_UNSPEC_VOLATILE (constant_modes
[i
],
5473 gen_rtvec (1, value
),
5474 UNSPECV_POOL_ENTRY
);
5475 insn
= emit_insn_after (value
, insn
);
5476 INSN_ADDRESSES_NEW (insn
, -1);
5479 /* Ensure minimum alignment for instructions. */
5480 insn
= emit_insn_after (gen_pool_align (GEN_INT (2)), insn
);
5481 INSN_ADDRESSES_NEW (insn
, -1);
5483 /* Output in-pool execute template insns. */
5484 for (c
= pool
->execute
; c
; c
= c
->next
)
5486 insn
= emit_label_after (c
->label
, insn
);
5487 INSN_ADDRESSES_NEW (insn
, -1);
5489 insn
= emit_insn_after (s390_execute_target (c
->value
), insn
);
5490 INSN_ADDRESSES_NEW (insn
, -1);
5493 /* Switch back to previous section. */
5494 if (TARGET_CPU_ZARCH
)
5496 insn
= emit_insn_after (gen_pool_section_end (), insn
);
5497 INSN_ADDRESSES_NEW (insn
, -1);
5500 insn
= emit_barrier_after (insn
);
5501 INSN_ADDRESSES_NEW (insn
, -1);
5503 /* Remove placeholder insn. */
5504 remove_insn (pool
->pool_insn
);
5507 /* Free all memory used by POOL. */
5510 s390_free_pool (struct constant_pool
*pool
)
5512 struct constant
*c
, *next
;
5515 for (i
= 0; i
< NR_C_MODES
; i
++)
5516 for (c
= pool
->constants
[i
]; c
; c
= next
)
5522 for (c
= pool
->execute
; c
; c
= next
)
5528 BITMAP_FREE (pool
->insns
);
5533 /* Collect main literal pool. Return NULL on overflow. */
5535 static struct constant_pool
*
5536 s390_mainpool_start (void)
5538 struct constant_pool
*pool
;
5541 pool
= s390_alloc_pool ();
5543 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5545 if (GET_CODE (insn
) == INSN
5546 && GET_CODE (PATTERN (insn
)) == SET
5547 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC_VOLATILE
5548 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPECV_MAIN_POOL
)
5550 gcc_assert (!pool
->pool_insn
);
5551 pool
->pool_insn
= insn
;
5554 if (!TARGET_CPU_ZARCH
&& s390_execute_label (insn
))
5556 s390_add_execute (pool
, insn
);
5558 else if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5560 rtx pool_ref
= NULL_RTX
;
5561 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5564 rtx constant
= get_pool_constant (pool_ref
);
5565 enum machine_mode mode
= get_pool_mode (pool_ref
);
5566 s390_add_constant (pool
, constant
, mode
);
5571 gcc_assert (pool
->pool_insn
|| pool
->size
== 0);
5573 if (pool
->size
>= 4096)
5575 /* We're going to chunkify the pool, so remove the main
5576 pool placeholder insn. */
5577 remove_insn (pool
->pool_insn
);
5579 s390_free_pool (pool
);
5586 /* POOL holds the main literal pool as collected by s390_mainpool_start.
5587 Modify the current function to output the pool constants as well as
5588 the pool register setup instruction. */
5591 s390_mainpool_finish (struct constant_pool
*pool
)
5593 rtx base_reg
= cfun
->machine
->base_reg
;
5596 /* If the pool is empty, we're done. */
5597 if (pool
->size
== 0)
5599 /* We don't actually need a base register after all. */
5600 cfun
->machine
->base_reg
= NULL_RTX
;
5602 if (pool
->pool_insn
)
5603 remove_insn (pool
->pool_insn
);
5604 s390_free_pool (pool
);
5608 /* We need correct insn addresses. */
5609 shorten_branches (get_insns ());
5611 /* On zSeries, we use a LARL to load the pool register. The pool is
5612 located in the .rodata section, so we emit it after the function. */
5613 if (TARGET_CPU_ZARCH
)
5615 insn
= gen_main_base_64 (base_reg
, pool
->label
);
5616 insn
= emit_insn_after (insn
, pool
->pool_insn
);
5617 INSN_ADDRESSES_NEW (insn
, -1);
5618 remove_insn (pool
->pool_insn
);
5620 insn
= get_last_insn ();
5621 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
5622 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
5624 s390_dump_pool (pool
, 0);
5627 /* On S/390, if the total size of the function's code plus literal pool
5628 does not exceed 4096 bytes, we use BASR to set up a function base
5629 pointer, and emit the literal pool at the end of the function. */
5630 else if (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
5631 + pool
->size
+ 8 /* alignment slop */ < 4096)
5633 insn
= gen_main_base_31_small (base_reg
, pool
->label
);
5634 insn
= emit_insn_after (insn
, pool
->pool_insn
);
5635 INSN_ADDRESSES_NEW (insn
, -1);
5636 remove_insn (pool
->pool_insn
);
5638 insn
= emit_label_after (pool
->label
, insn
);
5639 INSN_ADDRESSES_NEW (insn
, -1);
5641 insn
= get_last_insn ();
5642 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
5643 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
5645 s390_dump_pool (pool
, 1);
5648 /* Otherwise, we emit an inline literal pool and use BASR to branch
5649 over it, setting up the pool register at the same time. */
5652 rtx pool_end
= gen_label_rtx ();
5654 insn
= gen_main_base_31_large (base_reg
, pool
->label
, pool_end
);
5655 insn
= emit_insn_after (insn
, pool
->pool_insn
);
5656 INSN_ADDRESSES_NEW (insn
, -1);
5657 remove_insn (pool
->pool_insn
);
5659 insn
= emit_label_after (pool
->label
, insn
);
5660 INSN_ADDRESSES_NEW (insn
, -1);
5662 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
5663 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
5665 insn
= emit_label_after (pool_end
, pool
->pool_insn
);
5666 INSN_ADDRESSES_NEW (insn
, -1);
5668 s390_dump_pool (pool
, 1);
5672 /* Replace all literal pool references. */
5674 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5677 replace_ltrel_base (&PATTERN (insn
));
5679 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5681 rtx addr
, pool_ref
= NULL_RTX
;
5682 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5685 if (s390_execute_label (insn
))
5686 addr
= s390_find_execute (pool
, insn
);
5688 addr
= s390_find_constant (pool
, get_pool_constant (pool_ref
),
5689 get_pool_mode (pool_ref
));
5691 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
5692 INSN_CODE (insn
) = -1;
5698 /* Free the pool. */
5699 s390_free_pool (pool
);
5702 /* POOL holds the main literal pool as collected by s390_mainpool_start.
5703 We have decided we cannot use this pool, so revert all changes
5704 to the current function that were done by s390_mainpool_start. */
5706 s390_mainpool_cancel (struct constant_pool
*pool
)
5708 /* We didn't actually change the instruction stream, so simply
5709 free the pool memory. */
5710 s390_free_pool (pool
);
5714 /* Chunkify the literal pool. */
5716 #define S390_POOL_CHUNK_MIN 0xc00
5717 #define S390_POOL_CHUNK_MAX 0xe00
5719 static struct constant_pool
*
5720 s390_chunkify_start (void)
5722 struct constant_pool
*curr_pool
= NULL
, *pool_list
= NULL
;
5725 rtx pending_ltrel
= NULL_RTX
;
5728 rtx (*gen_reload_base
) (rtx
, rtx
) =
5729 TARGET_CPU_ZARCH
? gen_reload_base_64
: gen_reload_base_31
;
5732 /* We need correct insn addresses. */
5734 shorten_branches (get_insns ());
5736 /* Scan all insns and move literals to pool chunks. */
5738 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5740 /* Check for pending LTREL_BASE. */
5743 rtx ltrel_base
= find_ltrel_base (PATTERN (insn
));
5746 gcc_assert (ltrel_base
== pending_ltrel
);
5747 pending_ltrel
= NULL_RTX
;
5751 if (!TARGET_CPU_ZARCH
&& s390_execute_label (insn
))
5754 curr_pool
= s390_start_pool (&pool_list
, insn
);
5756 s390_add_execute (curr_pool
, insn
);
5757 s390_add_pool_insn (curr_pool
, insn
);
5759 else if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5761 rtx pool_ref
= NULL_RTX
;
5762 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5765 rtx constant
= get_pool_constant (pool_ref
);
5766 enum machine_mode mode
= get_pool_mode (pool_ref
);
5769 curr_pool
= s390_start_pool (&pool_list
, insn
);
5771 s390_add_constant (curr_pool
, constant
, mode
);
5772 s390_add_pool_insn (curr_pool
, insn
);
5774 /* Don't split the pool chunk between a LTREL_OFFSET load
5775 and the corresponding LTREL_BASE. */
5776 if (GET_CODE (constant
) == CONST
5777 && GET_CODE (XEXP (constant
, 0)) == UNSPEC
5778 && XINT (XEXP (constant
, 0), 1) == UNSPEC_LTREL_OFFSET
)
5780 gcc_assert (!pending_ltrel
);
5781 pending_ltrel
= pool_ref
;
5786 if (GET_CODE (insn
) == JUMP_INSN
|| GET_CODE (insn
) == CODE_LABEL
)
5789 s390_add_pool_insn (curr_pool
, insn
);
5790 /* An LTREL_BASE must follow within the same basic block. */
5791 gcc_assert (!pending_ltrel
);
5795 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn
)
5796 || INSN_ADDRESSES (INSN_UID (insn
)) == -1)
5799 if (TARGET_CPU_ZARCH
)
5801 if (curr_pool
->size
< S390_POOL_CHUNK_MAX
)
5804 s390_end_pool (curr_pool
, NULL_RTX
);
5809 int chunk_size
= INSN_ADDRESSES (INSN_UID (insn
))
5810 - INSN_ADDRESSES (INSN_UID (curr_pool
->first_insn
))
5813 /* We will later have to insert base register reload insns.
5814 Those will have an effect on code size, which we need to
5815 consider here. This calculation makes rather pessimistic
5816 worst-case assumptions. */
5817 if (GET_CODE (insn
) == CODE_LABEL
)
5820 if (chunk_size
< S390_POOL_CHUNK_MIN
5821 && curr_pool
->size
< S390_POOL_CHUNK_MIN
)
5824 /* Pool chunks can only be inserted after BARRIERs ... */
5825 if (GET_CODE (insn
) == BARRIER
)
5827 s390_end_pool (curr_pool
, insn
);
5832 /* ... so if we don't find one in time, create one. */
5833 else if ((chunk_size
> S390_POOL_CHUNK_MAX
5834 || curr_pool
->size
> S390_POOL_CHUNK_MAX
))
5836 rtx label
, jump
, barrier
;
5838 /* We can insert the barrier only after a 'real' insn. */
5839 if (GET_CODE (insn
) != INSN
&& GET_CODE (insn
) != CALL_INSN
)
5841 if (get_attr_length (insn
) == 0)
5844 /* Don't separate LTREL_BASE from the corresponding
5845 LTREL_OFFSET load. */
5849 label
= gen_label_rtx ();
5850 jump
= emit_jump_insn_after (gen_jump (label
), insn
);
5851 barrier
= emit_barrier_after (jump
);
5852 insn
= emit_label_after (label
, barrier
);
5853 JUMP_LABEL (jump
) = label
;
5854 LABEL_NUSES (label
) = 1;
5856 INSN_ADDRESSES_NEW (jump
, -1);
5857 INSN_ADDRESSES_NEW (barrier
, -1);
5858 INSN_ADDRESSES_NEW (insn
, -1);
5860 s390_end_pool (curr_pool
, barrier
);
5868 s390_end_pool (curr_pool
, NULL_RTX
);
5869 gcc_assert (!pending_ltrel
);
5871 /* Find all labels that are branched into
5872 from an insn belonging to a different chunk. */
5874 far_labels
= BITMAP_ALLOC (NULL
);
5876 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5878 /* Labels marked with LABEL_PRESERVE_P can be target
5879 of non-local jumps, so we have to mark them.
5880 The same holds for named labels.
5882 Don't do that, however, if it is the label before
5885 if (GET_CODE (insn
) == CODE_LABEL
5886 && (LABEL_PRESERVE_P (insn
) || LABEL_NAME (insn
)))
5888 rtx vec_insn
= next_real_insn (insn
);
5889 rtx vec_pat
= vec_insn
&& GET_CODE (vec_insn
) == JUMP_INSN
?
5890 PATTERN (vec_insn
) : NULL_RTX
;
5892 || !(GET_CODE (vec_pat
) == ADDR_VEC
5893 || GET_CODE (vec_pat
) == ADDR_DIFF_VEC
))
5894 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (insn
));
5897 /* If we have a direct jump (conditional or unconditional)
5898 or a casesi jump, check all potential targets. */
5899 else if (GET_CODE (insn
) == JUMP_INSN
)
5901 rtx pat
= PATTERN (insn
);
5902 if (GET_CODE (pat
) == PARALLEL
&& XVECLEN (pat
, 0) > 2)
5903 pat
= XVECEXP (pat
, 0, 0);
5905 if (GET_CODE (pat
) == SET
)
5907 rtx label
= JUMP_LABEL (insn
);
5910 if (s390_find_pool (pool_list
, label
)
5911 != s390_find_pool (pool_list
, insn
))
5912 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
5915 else if (GET_CODE (pat
) == PARALLEL
5916 && XVECLEN (pat
, 0) == 2
5917 && GET_CODE (XVECEXP (pat
, 0, 0)) == SET
5918 && GET_CODE (XVECEXP (pat
, 0, 1)) == USE
5919 && GET_CODE (XEXP (XVECEXP (pat
, 0, 1), 0)) == LABEL_REF
)
5921 /* Find the jump table used by this casesi jump. */
5922 rtx vec_label
= XEXP (XEXP (XVECEXP (pat
, 0, 1), 0), 0);
5923 rtx vec_insn
= next_real_insn (vec_label
);
5924 rtx vec_pat
= vec_insn
&& GET_CODE (vec_insn
) == JUMP_INSN
?
5925 PATTERN (vec_insn
) : NULL_RTX
;
5927 && (GET_CODE (vec_pat
) == ADDR_VEC
5928 || GET_CODE (vec_pat
) == ADDR_DIFF_VEC
))
5930 int i
, diff_p
= GET_CODE (vec_pat
) == ADDR_DIFF_VEC
;
5932 for (i
= 0; i
< XVECLEN (vec_pat
, diff_p
); i
++)
5934 rtx label
= XEXP (XVECEXP (vec_pat
, diff_p
, i
), 0);
5936 if (s390_find_pool (pool_list
, label
)
5937 != s390_find_pool (pool_list
, insn
))
5938 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
5945 /* Insert base register reload insns before every pool. */
5947 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
5949 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
5951 rtx insn
= curr_pool
->first_insn
;
5952 INSN_ADDRESSES_NEW (emit_insn_before (new_insn
, insn
), -1);
5955 /* Insert base register reload insns at every far label. */
5957 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5958 if (GET_CODE (insn
) == CODE_LABEL
5959 && bitmap_bit_p (far_labels
, CODE_LABEL_NUMBER (insn
)))
5961 struct constant_pool
*pool
= s390_find_pool (pool_list
, insn
);
5964 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
5966 INSN_ADDRESSES_NEW (emit_insn_after (new_insn
, insn
), -1);
5971 BITMAP_FREE (far_labels
);
5974 /* Recompute insn addresses. */
5976 init_insn_lengths ();
5977 shorten_branches (get_insns ());
5982 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
5983 After we have decided to use this list, finish implementing
5984 all changes to the current function as required. */
5987 s390_chunkify_finish (struct constant_pool
*pool_list
)
5989 struct constant_pool
*curr_pool
= NULL
;
5993 /* Replace all literal pool references. */
5995 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5998 replace_ltrel_base (&PATTERN (insn
));
6000 curr_pool
= s390_find_pool (pool_list
, insn
);
6004 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
6006 rtx addr
, pool_ref
= NULL_RTX
;
6007 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
6010 if (s390_execute_label (insn
))
6011 addr
= s390_find_execute (curr_pool
, insn
);
6013 addr
= s390_find_constant (curr_pool
,
6014 get_pool_constant (pool_ref
),
6015 get_pool_mode (pool_ref
));
6017 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
6018 INSN_CODE (insn
) = -1;
6023 /* Dump out all literal pools. */
6025 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
6026 s390_dump_pool (curr_pool
, 0);
6028 /* Free pool list. */
6032 struct constant_pool
*next
= pool_list
->next
;
6033 s390_free_pool (pool_list
);
6038 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
6039 We have decided we cannot use this list, so revert all changes
6040 to the current function that were done by s390_chunkify_start. */
6043 s390_chunkify_cancel (struct constant_pool
*pool_list
)
6045 struct constant_pool
*curr_pool
= NULL
;
6048 /* Remove all pool placeholder insns. */
6050 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
6052 /* Did we insert an extra barrier? Remove it. */
6053 rtx barrier
= PREV_INSN (curr_pool
->pool_insn
);
6054 rtx jump
= barrier
? PREV_INSN (barrier
) : NULL_RTX
;
6055 rtx label
= NEXT_INSN (curr_pool
->pool_insn
);
6057 if (jump
&& GET_CODE (jump
) == JUMP_INSN
6058 && barrier
&& GET_CODE (barrier
) == BARRIER
6059 && label
&& GET_CODE (label
) == CODE_LABEL
6060 && GET_CODE (PATTERN (jump
)) == SET
6061 && SET_DEST (PATTERN (jump
)) == pc_rtx
6062 && GET_CODE (SET_SRC (PATTERN (jump
))) == LABEL_REF
6063 && XEXP (SET_SRC (PATTERN (jump
)), 0) == label
)
6066 remove_insn (barrier
);
6067 remove_insn (label
);
6070 remove_insn (curr_pool
->pool_insn
);
6073 /* Remove all base register reload insns. */
6075 for (insn
= get_insns (); insn
; )
6077 rtx next_insn
= NEXT_INSN (insn
);
6079 if (GET_CODE (insn
) == INSN
6080 && GET_CODE (PATTERN (insn
)) == SET
6081 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC
6082 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPEC_RELOAD_BASE
)
6088 /* Free pool list. */
6092 struct constant_pool
*next
= pool_list
->next
;
6093 s390_free_pool (pool_list
);
6099 /* Output the constant pool entry EXP in mode MODE with alignment ALIGN. */
6102 s390_output_pool_entry (rtx exp
, enum machine_mode mode
, unsigned int align
)
6106 switch (GET_MODE_CLASS (mode
))
6109 gcc_assert (GET_CODE (exp
) == CONST_DOUBLE
);
6111 REAL_VALUE_FROM_CONST_DOUBLE (r
, exp
);
6112 assemble_real (r
, mode
, align
);
6116 assemble_integer (exp
, GET_MODE_SIZE (mode
), align
, 1);
6125 /* Return an RTL expression representing the value of the return address
6126 for the frame COUNT steps up from the current frame. FRAME is the
6127 frame pointer of that frame. */
6130 s390_return_addr_rtx (int count
, rtx frame ATTRIBUTE_UNUSED
)
6135 /* Without backchain, we fail for all but the current frame. */
6137 if (!TARGET_BACKCHAIN
&& count
> 0)
6140 /* For the current frame, we need to make sure the initial
6141 value of RETURN_REGNUM is actually saved. */
6145 /* On non-z architectures branch splitting could overwrite r14. */
6146 if (TARGET_CPU_ZARCH
)
6147 return get_hard_reg_initial_val (Pmode
, RETURN_REGNUM
);
6150 cfun_frame_layout
.save_return_addr_p
= true;
6151 return gen_rtx_MEM (Pmode
, return_address_pointer_rtx
);
6155 if (TARGET_PACKED_STACK
)
6156 offset
= -2 * UNITS_PER_WORD
;
6158 offset
= RETURN_REGNUM
* UNITS_PER_WORD
;
6160 addr
= plus_constant (frame
, offset
);
6161 addr
= memory_address (Pmode
, addr
);
6162 return gen_rtx_MEM (Pmode
, addr
);
6165 /* Return an RTL expression representing the back chain stored in
6166 the current stack frame. */
6169 s390_back_chain_rtx (void)
6173 gcc_assert (TARGET_BACKCHAIN
);
6175 if (TARGET_PACKED_STACK
)
6176 chain
= plus_constant (stack_pointer_rtx
,
6177 STACK_POINTER_OFFSET
- UNITS_PER_WORD
);
6179 chain
= stack_pointer_rtx
;
6181 chain
= gen_rtx_MEM (Pmode
, chain
);
6185 /* Find first call clobbered register unused in a function.
6186 This could be used as base register in a leaf function
6187 or for holding the return address before epilogue. */
6190 find_unused_clobbered_reg (void)
6193 for (i
= 0; i
< 6; i
++)
6194 if (!regs_ever_live
[i
])
6200 /* Helper function for s390_regs_ever_clobbered. Sets the fields in DATA for all
6201 clobbered hard regs in SETREG. */
6204 s390_reg_clobbered_rtx (rtx setreg
, rtx set_insn ATTRIBUTE_UNUSED
, void *data
)
6206 int *regs_ever_clobbered
= (int *)data
;
6207 unsigned int i
, regno
;
6208 enum machine_mode mode
= GET_MODE (setreg
);
6210 if (GET_CODE (setreg
) == SUBREG
)
6212 rtx inner
= SUBREG_REG (setreg
);
6213 if (!GENERAL_REG_P (inner
))
6215 regno
= subreg_regno (setreg
);
6217 else if (GENERAL_REG_P (setreg
))
6218 regno
= REGNO (setreg
);
6223 i
< regno
+ HARD_REGNO_NREGS (regno
, mode
);
6225 regs_ever_clobbered
[i
] = 1;
6228 /* Walks through all basic blocks of the current function looking
6229 for clobbered hard regs using s390_reg_clobbered_rtx. The fields
6230 of the passed integer array REGS_EVER_CLOBBERED are set to one for
6231 each of those regs. */
6234 s390_regs_ever_clobbered (int *regs_ever_clobbered
)
6240 memset (regs_ever_clobbered
, 0, 16 * sizeof (int));
6242 /* For non-leaf functions we have to consider all call clobbered regs to be
6244 if (!current_function_is_leaf
)
6246 for (i
= 0; i
< 16; i
++)
6247 regs_ever_clobbered
[i
] = call_really_used_regs
[i
];
6250 /* Make the "magic" eh_return registers live if necessary. For regs_ever_live
6251 this work is done by liveness analysis (mark_regs_live_at_end).
6252 Special care is needed for functions containing landing pads. Landing pads
6253 may use the eh registers, but the code which sets these registers is not
6254 contained in that function. Hence s390_regs_ever_clobbered is not able to
6255 deal with this automatically. */
6256 if (current_function_calls_eh_return
|| cfun
->machine
->has_landing_pad_p
)
6257 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; i
++)
6258 if (current_function_calls_eh_return
6259 || (cfun
->machine
->has_landing_pad_p
6260 && regs_ever_live
[EH_RETURN_DATA_REGNO (i
)]))
6261 regs_ever_clobbered
[EH_RETURN_DATA_REGNO (i
)] = 1;
6263 /* For nonlocal gotos all call-saved registers have to be saved.
6264 This flag is also set for the unwinding code in libgcc.
6265 See expand_builtin_unwind_init. For regs_ever_live this is done by
6267 if (current_function_has_nonlocal_label
)
6268 for (i
= 0; i
< 16; i
++)
6269 if (!call_really_used_regs
[i
])
6270 regs_ever_clobbered
[i
] = 1;
6272 FOR_EACH_BB (cur_bb
)
6274 FOR_BB_INSNS (cur_bb
, cur_insn
)
6276 if (INSN_P (cur_insn
))
6277 note_stores (PATTERN (cur_insn
),
6278 s390_reg_clobbered_rtx
,
6279 regs_ever_clobbered
);
6284 /* Determine the frame area which actually has to be accessed
6285 in the function epilogue. The values are stored at the
6286 given pointers AREA_BOTTOM (address of the lowest used stack
6287 address) and AREA_TOP (address of the first item which does
6288 not belong to the stack frame). */
6291 s390_frame_area (int *area_bottom
, int *area_top
)
6299 if (cfun_frame_layout
.first_restore_gpr
!= -1)
6301 b
= (cfun_frame_layout
.gprs_offset
6302 + cfun_frame_layout
.first_restore_gpr
* UNITS_PER_WORD
);
6303 t
= b
+ (cfun_frame_layout
.last_restore_gpr
6304 - cfun_frame_layout
.first_restore_gpr
+ 1) * UNITS_PER_WORD
;
6307 if (TARGET_64BIT
&& cfun_save_high_fprs_p
)
6309 b
= MIN (b
, cfun_frame_layout
.f8_offset
);
6310 t
= MAX (t
, (cfun_frame_layout
.f8_offset
6311 + cfun_frame_layout
.high_fprs
* 8));
6315 for (i
= 2; i
< 4; i
++)
6316 if (cfun_fpr_bit_p (i
))
6318 b
= MIN (b
, cfun_frame_layout
.f4_offset
+ (i
- 2) * 8);
6319 t
= MAX (t
, cfun_frame_layout
.f4_offset
+ (i
- 1) * 8);
6326 /* Fill cfun->machine with info about register usage of current function.
6327 Return in CLOBBERED_REGS which GPRs are currently considered set. */
6330 s390_register_info (int clobbered_regs
[])
6334 /* fprs 8 - 15 are call saved for 64 Bit ABI. */
6335 cfun_frame_layout
.fpr_bitmap
= 0;
6336 cfun_frame_layout
.high_fprs
= 0;
6338 for (i
= 24; i
< 32; i
++)
6339 if (regs_ever_live
[i
] && !global_regs
[i
])
6341 cfun_set_fpr_bit (i
- 16);
6342 cfun_frame_layout
.high_fprs
++;
6345 /* Find first and last gpr to be saved. We trust regs_ever_live
6346 data, except that we don't save and restore global registers.
6348 Also, all registers with special meaning to the compiler need
6349 to be handled extra. */
6351 s390_regs_ever_clobbered (clobbered_regs
);
6353 for (i
= 0; i
< 16; i
++)
6354 clobbered_regs
[i
] = clobbered_regs
[i
] && !global_regs
[i
] && !fixed_regs
[i
];
6356 if (frame_pointer_needed
)
6357 clobbered_regs
[HARD_FRAME_POINTER_REGNUM
] = 1;
6360 clobbered_regs
[PIC_OFFSET_TABLE_REGNUM
]
6361 |= regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
];
6363 clobbered_regs
[BASE_REGNUM
]
6364 |= (cfun
->machine
->base_reg
6365 && REGNO (cfun
->machine
->base_reg
) == BASE_REGNUM
);
6367 clobbered_regs
[RETURN_REGNUM
]
6368 |= (!current_function_is_leaf
6369 || TARGET_TPF_PROFILING
6370 || cfun
->machine
->split_branches_pending_p
6371 || cfun_frame_layout
.save_return_addr_p
6372 || current_function_calls_eh_return
6373 || current_function_stdarg
);
6375 clobbered_regs
[STACK_POINTER_REGNUM
]
6376 |= (!current_function_is_leaf
6377 || TARGET_TPF_PROFILING
6378 || cfun_save_high_fprs_p
6379 || get_frame_size () > 0
6380 || current_function_calls_alloca
6381 || current_function_stdarg
);
6383 for (i
= 6; i
< 16; i
++)
6384 if (regs_ever_live
[i
] || clobbered_regs
[i
])
6386 for (j
= 15; j
> i
; j
--)
6387 if (regs_ever_live
[j
] || clobbered_regs
[j
])
6392 /* Nothing to save/restore. */
6393 cfun_frame_layout
.first_save_gpr_slot
= -1;
6394 cfun_frame_layout
.last_save_gpr_slot
= -1;
6395 cfun_frame_layout
.first_save_gpr
= -1;
6396 cfun_frame_layout
.first_restore_gpr
= -1;
6397 cfun_frame_layout
.last_save_gpr
= -1;
6398 cfun_frame_layout
.last_restore_gpr
= -1;
6402 /* Save slots for gprs from i to j. */
6403 cfun_frame_layout
.first_save_gpr_slot
= i
;
6404 cfun_frame_layout
.last_save_gpr_slot
= j
;
6406 for (i
= cfun_frame_layout
.first_save_gpr_slot
;
6407 i
< cfun_frame_layout
.last_save_gpr_slot
+ 1;
6409 if (clobbered_regs
[i
])
6412 for (j
= cfun_frame_layout
.last_save_gpr_slot
; j
> i
; j
--)
6413 if (clobbered_regs
[j
])
6416 if (i
== cfun_frame_layout
.last_save_gpr_slot
+ 1)
6418 /* Nothing to save/restore. */
6419 cfun_frame_layout
.first_save_gpr
= -1;
6420 cfun_frame_layout
.first_restore_gpr
= -1;
6421 cfun_frame_layout
.last_save_gpr
= -1;
6422 cfun_frame_layout
.last_restore_gpr
= -1;
6426 /* Save / Restore from gpr i to j. */
6427 cfun_frame_layout
.first_save_gpr
= i
;
6428 cfun_frame_layout
.first_restore_gpr
= i
;
6429 cfun_frame_layout
.last_save_gpr
= j
;
6430 cfun_frame_layout
.last_restore_gpr
= j
;
6434 if (current_function_stdarg
)
6436 /* Varargs functions need to save gprs 2 to 6. */
6437 if (cfun
->va_list_gpr_size
6438 && current_function_args_info
.gprs
< GP_ARG_NUM_REG
)
6440 int min_gpr
= current_function_args_info
.gprs
;
6441 int max_gpr
= min_gpr
+ cfun
->va_list_gpr_size
;
6442 if (max_gpr
> GP_ARG_NUM_REG
)
6443 max_gpr
= GP_ARG_NUM_REG
;
6445 if (cfun_frame_layout
.first_save_gpr
== -1
6446 || cfun_frame_layout
.first_save_gpr
> 2 + min_gpr
)
6448 cfun_frame_layout
.first_save_gpr
= 2 + min_gpr
;
6449 cfun_frame_layout
.first_save_gpr_slot
= 2 + min_gpr
;
6452 if (cfun_frame_layout
.last_save_gpr
== -1
6453 || cfun_frame_layout
.last_save_gpr
< 2 + max_gpr
- 1)
6455 cfun_frame_layout
.last_save_gpr
= 2 + max_gpr
- 1;
6456 cfun_frame_layout
.last_save_gpr_slot
= 2 + max_gpr
- 1;
6460 /* Mark f0, f2 for 31 bit and f0-f4 for 64 bit to be saved. */
6461 if (TARGET_HARD_FLOAT
&& cfun
->va_list_fpr_size
6462 && current_function_args_info
.fprs
< FP_ARG_NUM_REG
)
6464 int min_fpr
= current_function_args_info
.fprs
;
6465 int max_fpr
= min_fpr
+ cfun
->va_list_fpr_size
;
6466 if (max_fpr
> FP_ARG_NUM_REG
)
6467 max_fpr
= FP_ARG_NUM_REG
;
6469 /* ??? This is currently required to ensure proper location
6470 of the fpr save slots within the va_list save area. */
6471 if (TARGET_PACKED_STACK
)
6474 for (i
= min_fpr
; i
< max_fpr
; i
++)
6475 cfun_set_fpr_bit (i
);
6480 for (i
= 2; i
< 4; i
++)
6481 if (regs_ever_live
[i
+ 16] && !global_regs
[i
+ 16])
6482 cfun_set_fpr_bit (i
);
6485 /* Fill cfun->machine with info about frame of current function. */
6488 s390_frame_info (void)
6492 cfun_frame_layout
.frame_size
= get_frame_size ();
6493 if (!TARGET_64BIT
&& cfun_frame_layout
.frame_size
> 0x7fff0000)
6494 fatal_error ("total size of local variables exceeds architecture limit");
6496 if (!TARGET_PACKED_STACK
)
6498 cfun_frame_layout
.backchain_offset
= 0;
6499 cfun_frame_layout
.f0_offset
= 16 * UNITS_PER_WORD
;
6500 cfun_frame_layout
.f4_offset
= cfun_frame_layout
.f0_offset
+ 2 * 8;
6501 cfun_frame_layout
.f8_offset
= -cfun_frame_layout
.high_fprs
* 8;
6502 cfun_frame_layout
.gprs_offset
= (cfun_frame_layout
.first_save_gpr_slot
6505 else if (TARGET_BACKCHAIN
) /* kernel stack layout */
6507 cfun_frame_layout
.backchain_offset
= (STACK_POINTER_OFFSET
6509 cfun_frame_layout
.gprs_offset
6510 = (cfun_frame_layout
.backchain_offset
6511 - (STACK_POINTER_REGNUM
- cfun_frame_layout
.first_save_gpr_slot
+ 1)
6516 cfun_frame_layout
.f4_offset
6517 = (cfun_frame_layout
.gprs_offset
6518 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6520 cfun_frame_layout
.f0_offset
6521 = (cfun_frame_layout
.f4_offset
6522 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6526 /* On 31 bit we have to care about alignment of the
6527 floating point regs to provide fastest access. */
6528 cfun_frame_layout
.f0_offset
6529 = ((cfun_frame_layout
.gprs_offset
6530 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1))
6531 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6533 cfun_frame_layout
.f4_offset
6534 = (cfun_frame_layout
.f0_offset
6535 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6538 else /* no backchain */
6540 cfun_frame_layout
.f4_offset
6541 = (STACK_POINTER_OFFSET
6542 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6544 cfun_frame_layout
.f0_offset
6545 = (cfun_frame_layout
.f4_offset
6546 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6548 cfun_frame_layout
.gprs_offset
6549 = cfun_frame_layout
.f0_offset
- cfun_gprs_save_area_size
;
6552 if (current_function_is_leaf
6553 && !TARGET_TPF_PROFILING
6554 && cfun_frame_layout
.frame_size
== 0
6555 && !cfun_save_high_fprs_p
6556 && !current_function_calls_alloca
6557 && !current_function_stdarg
)
6560 if (!TARGET_PACKED_STACK
)
6561 cfun_frame_layout
.frame_size
+= (STACK_POINTER_OFFSET
6562 + current_function_outgoing_args_size
6563 + cfun_frame_layout
.high_fprs
* 8);
6566 if (TARGET_BACKCHAIN
)
6567 cfun_frame_layout
.frame_size
+= UNITS_PER_WORD
;
6569 /* No alignment trouble here because f8-f15 are only saved under
6571 cfun_frame_layout
.f8_offset
= (MIN (MIN (cfun_frame_layout
.f0_offset
,
6572 cfun_frame_layout
.f4_offset
),
6573 cfun_frame_layout
.gprs_offset
)
6574 - cfun_frame_layout
.high_fprs
* 8);
6576 cfun_frame_layout
.frame_size
+= cfun_frame_layout
.high_fprs
* 8;
6578 for (i
= 0; i
< 8; i
++)
6579 if (cfun_fpr_bit_p (i
))
6580 cfun_frame_layout
.frame_size
+= 8;
6582 cfun_frame_layout
.frame_size
+= cfun_gprs_save_area_size
;
6584 /* If under 31 bit an odd number of gprs has to be saved we have to adjust
6585 the frame size to sustain 8 byte alignment of stack frames. */
6586 cfun_frame_layout
.frame_size
= ((cfun_frame_layout
.frame_size
+
6587 STACK_BOUNDARY
/ BITS_PER_UNIT
- 1)
6588 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1));
6590 cfun_frame_layout
.frame_size
+= current_function_outgoing_args_size
;
6594 /* Generate frame layout. Fills in register and frame data for the current
6595 function in cfun->machine. This routine can be called multiple times;
6596 it will re-do the complete frame layout every time. */
6599 s390_init_frame_layout (void)
6601 HOST_WIDE_INT frame_size
;
6603 int clobbered_regs
[16];
6605 /* On S/390 machines, we may need to perform branch splitting, which
6606 will require both base and return address register. We have no
6607 choice but to assume we're going to need them until right at the
6608 end of the machine dependent reorg phase. */
6609 if (!TARGET_CPU_ZARCH
)
6610 cfun
->machine
->split_branches_pending_p
= true;
6614 frame_size
= cfun_frame_layout
.frame_size
;
6616 /* Try to predict whether we'll need the base register. */
6617 base_used
= cfun
->machine
->split_branches_pending_p
6618 || current_function_uses_const_pool
6619 || (!DISP_IN_RANGE (-frame_size
)
6620 && !CONST_OK_FOR_K (-frame_size
));
6622 /* Decide which register to use as literal pool base. In small
6623 leaf functions, try to use an unused call-clobbered register
6624 as base register to avoid save/restore overhead. */
6626 cfun
->machine
->base_reg
= NULL_RTX
;
6627 else if (current_function_is_leaf
&& !regs_ever_live
[5])
6628 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, 5);
6630 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
6632 s390_register_info (clobbered_regs
);
6635 while (frame_size
!= cfun_frame_layout
.frame_size
);
6638 /* Update frame layout. Recompute actual register save data based on
6639 current info and update regs_ever_live for the special registers.
6640 May be called multiple times, but may never cause *more* registers
6641 to be saved than s390_init_frame_layout allocated room for. */
6644 s390_update_frame_layout (void)
6646 int clobbered_regs
[16];
6648 s390_register_info (clobbered_regs
);
6650 regs_ever_live
[BASE_REGNUM
] = clobbered_regs
[BASE_REGNUM
];
6651 regs_ever_live
[RETURN_REGNUM
] = clobbered_regs
[RETURN_REGNUM
];
6652 regs_ever_live
[STACK_POINTER_REGNUM
] = clobbered_regs
[STACK_POINTER_REGNUM
];
6654 if (cfun
->machine
->base_reg
)
6655 regs_ever_live
[REGNO (cfun
->machine
->base_reg
)] = 1;
6658 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
6661 s390_hard_regno_rename_ok (unsigned int old_reg
, unsigned int new_reg
)
6663 /* Once we've decided upon a register to use as base register, it must
6664 no longer be used for any other purpose. */
6665 if (cfun
->machine
->base_reg
)
6666 if (REGNO (cfun
->machine
->base_reg
) == old_reg
6667 || REGNO (cfun
->machine
->base_reg
) == new_reg
)
6673 /* Return true if register FROM can be eliminated via register TO. */
6676 s390_can_eliminate (int from
, int to
)
6678 /* On zSeries machines, we have not marked the base register as fixed.
6679 Instead, we have an elimination rule BASE_REGNUM -> BASE_REGNUM.
6680 If a function requires the base register, we say here that this
6681 elimination cannot be performed. This will cause reload to free
6682 up the base register (as if it were fixed). On the other hand,
6683 if the current function does *not* require the base register, we
6684 say here the elimination succeeds, which in turn allows reload
6685 to allocate the base register for any other purpose. */
6686 if (from
== BASE_REGNUM
&& to
== BASE_REGNUM
)
6688 if (TARGET_CPU_ZARCH
)
6690 s390_init_frame_layout ();
6691 return cfun
->machine
->base_reg
== NULL_RTX
;
6697 /* Everything else must point into the stack frame. */
6698 gcc_assert (to
== STACK_POINTER_REGNUM
6699 || to
== HARD_FRAME_POINTER_REGNUM
);
6701 gcc_assert (from
== FRAME_POINTER_REGNUM
6702 || from
== ARG_POINTER_REGNUM
6703 || from
== RETURN_ADDRESS_POINTER_REGNUM
);
6705 /* Make sure we actually saved the return address. */
6706 if (from
== RETURN_ADDRESS_POINTER_REGNUM
)
6707 if (!current_function_calls_eh_return
6708 && !current_function_stdarg
6709 && !cfun_frame_layout
.save_return_addr_p
)
6715 /* Return offset between register FROM and TO initially after prolog. */
6718 s390_initial_elimination_offset (int from
, int to
)
6720 HOST_WIDE_INT offset
;
6723 /* ??? Why are we called for non-eliminable pairs? */
6724 if (!s390_can_eliminate (from
, to
))
6729 case FRAME_POINTER_REGNUM
:
6730 offset
= (get_frame_size()
6731 + STACK_POINTER_OFFSET
6732 + current_function_outgoing_args_size
);
6735 case ARG_POINTER_REGNUM
:
6736 s390_init_frame_layout ();
6737 offset
= cfun_frame_layout
.frame_size
+ STACK_POINTER_OFFSET
;
6740 case RETURN_ADDRESS_POINTER_REGNUM
:
6741 s390_init_frame_layout ();
6742 index
= RETURN_REGNUM
- cfun_frame_layout
.first_save_gpr_slot
;
6743 gcc_assert (index
>= 0);
6744 offset
= cfun_frame_layout
.frame_size
+ cfun_frame_layout
.gprs_offset
;
6745 offset
+= index
* UNITS_PER_WORD
;
6759 /* Emit insn to save fpr REGNUM at offset OFFSET relative
6760 to register BASE. Return generated insn. */
6763 save_fpr (rtx base
, int offset
, int regnum
)
6766 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
6768 if (regnum
>= 16 && regnum
<= (16 + FP_ARG_NUM_REG
))
6769 set_mem_alias_set (addr
, get_varargs_alias_set ());
6771 set_mem_alias_set (addr
, get_frame_alias_set ());
6773 return emit_move_insn (addr
, gen_rtx_REG (DFmode
, regnum
));
6776 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
6777 to register BASE. Return generated insn. */
6780 restore_fpr (rtx base
, int offset
, int regnum
)
6783 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
6784 set_mem_alias_set (addr
, get_frame_alias_set ());
6786 return emit_move_insn (gen_rtx_REG (DFmode
, regnum
), addr
);
6789 /* Generate insn to save registers FIRST to LAST into
6790 the register save area located at offset OFFSET
6791 relative to register BASE. */
6794 save_gprs (rtx base
, int offset
, int first
, int last
)
6796 rtx addr
, insn
, note
;
6799 addr
= plus_constant (base
, offset
);
6800 addr
= gen_rtx_MEM (Pmode
, addr
);
6802 set_mem_alias_set (addr
, get_frame_alias_set ());
6804 /* Special-case single register. */
6808 insn
= gen_movdi (addr
, gen_rtx_REG (Pmode
, first
));
6810 insn
= gen_movsi (addr
, gen_rtx_REG (Pmode
, first
));
6812 RTX_FRAME_RELATED_P (insn
) = 1;
6817 insn
= gen_store_multiple (addr
,
6818 gen_rtx_REG (Pmode
, first
),
6819 GEN_INT (last
- first
+ 1));
6821 if (first
<= 6 && current_function_stdarg
)
6822 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
6824 rtx mem
= XEXP (XVECEXP (PATTERN (insn
), 0, i
), 0);
6827 set_mem_alias_set (mem
, get_varargs_alias_set ());
6830 /* We need to set the FRAME_RELATED flag on all SETs
6831 inside the store-multiple pattern.
6833 However, we must not emit DWARF records for registers 2..5
6834 if they are stored for use by variable arguments ...
6836 ??? Unfortunately, it is not enough to simply not the
6837 FRAME_RELATED flags for those SETs, because the first SET
6838 of the PARALLEL is always treated as if it had the flag
6839 set, even if it does not. Therefore we emit a new pattern
6840 without those registers as REG_FRAME_RELATED_EXPR note. */
6844 rtx pat
= PATTERN (insn
);
6846 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
6847 if (GET_CODE (XVECEXP (pat
, 0, i
)) == SET
)
6848 RTX_FRAME_RELATED_P (XVECEXP (pat
, 0, i
)) = 1;
6850 RTX_FRAME_RELATED_P (insn
) = 1;
6854 addr
= plus_constant (base
, offset
+ (6 - first
) * UNITS_PER_WORD
);
6855 note
= gen_store_multiple (gen_rtx_MEM (Pmode
, addr
),
6856 gen_rtx_REG (Pmode
, 6),
6857 GEN_INT (last
- 6 + 1));
6858 note
= PATTERN (note
);
6861 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
6862 note
, REG_NOTES (insn
));
6864 for (i
= 0; i
< XVECLEN (note
, 0); i
++)
6865 if (GET_CODE (XVECEXP (note
, 0, i
)) == SET
)
6866 RTX_FRAME_RELATED_P (XVECEXP (note
, 0, i
)) = 1;
6868 RTX_FRAME_RELATED_P (insn
) = 1;
6874 /* Generate insn to restore registers FIRST to LAST from
6875 the register save area located at offset OFFSET
6876 relative to register BASE. */
6879 restore_gprs (rtx base
, int offset
, int first
, int last
)
6883 addr
= plus_constant (base
, offset
);
6884 addr
= gen_rtx_MEM (Pmode
, addr
);
6885 set_mem_alias_set (addr
, get_frame_alias_set ());
6887 /* Special-case single register. */
6891 insn
= gen_movdi (gen_rtx_REG (Pmode
, first
), addr
);
6893 insn
= gen_movsi (gen_rtx_REG (Pmode
, first
), addr
);
6898 insn
= gen_load_multiple (gen_rtx_REG (Pmode
, first
),
6900 GEN_INT (last
- first
+ 1));
6904 /* Return insn sequence to load the GOT register. */
6906 static GTY(()) rtx got_symbol
;
6908 s390_load_got (void)
6914 got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
6915 SYMBOL_REF_FLAGS (got_symbol
) = SYMBOL_FLAG_LOCAL
;
6920 if (TARGET_CPU_ZARCH
)
6922 emit_move_insn (pic_offset_table_rtx
, got_symbol
);
6928 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, got_symbol
),
6929 UNSPEC_LTREL_OFFSET
);
6930 offset
= gen_rtx_CONST (Pmode
, offset
);
6931 offset
= force_const_mem (Pmode
, offset
);
6933 emit_move_insn (pic_offset_table_rtx
, offset
);
6935 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, XEXP (offset
, 0)),
6937 offset
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, offset
);
6939 emit_move_insn (pic_offset_table_rtx
, offset
);
6942 insns
= get_insns ();
6947 /* Expand the prologue into a bunch of separate insns. */
6950 s390_emit_prologue (void)
6958 /* Complete frame layout. */
6960 s390_update_frame_layout ();
6962 /* Annotate all constant pool references to let the scheduler know
6963 they implicitly use the base register. */
6965 push_topmost_sequence ();
6967 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6969 annotate_constant_pool_refs (&PATTERN (insn
));
6971 pop_topmost_sequence ();
6973 /* Choose best register to use for temp use within prologue.
6974 See below for why TPF must use the register 1. */
6976 if (!has_hard_reg_initial_val (Pmode
, RETURN_REGNUM
)
6977 && !current_function_is_leaf
6978 && !TARGET_TPF_PROFILING
)
6979 temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
6981 temp_reg
= gen_rtx_REG (Pmode
, 1);
6983 /* Save call saved gprs. */
6984 if (cfun_frame_layout
.first_save_gpr
!= -1)
6986 insn
= save_gprs (stack_pointer_rtx
,
6987 cfun_frame_layout
.gprs_offset
+
6988 UNITS_PER_WORD
* (cfun_frame_layout
.first_save_gpr
6989 - cfun_frame_layout
.first_save_gpr_slot
),
6990 cfun_frame_layout
.first_save_gpr
,
6991 cfun_frame_layout
.last_save_gpr
);
6995 /* Dummy insn to mark literal pool slot. */
6997 if (cfun
->machine
->base_reg
)
6998 emit_insn (gen_main_pool (cfun
->machine
->base_reg
));
7000 offset
= cfun_frame_layout
.f0_offset
;
7002 /* Save f0 and f2. */
7003 for (i
= 0; i
< 2; i
++)
7005 if (cfun_fpr_bit_p (i
))
7007 save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
7010 else if (!TARGET_PACKED_STACK
)
7014 /* Save f4 and f6. */
7015 offset
= cfun_frame_layout
.f4_offset
;
7016 for (i
= 2; i
< 4; i
++)
7018 if (cfun_fpr_bit_p (i
))
7020 insn
= save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
7023 /* If f4 and f6 are call clobbered they are saved due to stdargs and
7024 therefore are not frame related. */
7025 if (!call_really_used_regs
[i
+ 16])
7026 RTX_FRAME_RELATED_P (insn
) = 1;
7028 else if (!TARGET_PACKED_STACK
)
7032 if (TARGET_PACKED_STACK
7033 && cfun_save_high_fprs_p
7034 && cfun_frame_layout
.f8_offset
+ cfun_frame_layout
.high_fprs
* 8 > 0)
7036 offset
= (cfun_frame_layout
.f8_offset
7037 + (cfun_frame_layout
.high_fprs
- 1) * 8);
7039 for (i
= 15; i
> 7 && offset
>= 0; i
--)
7040 if (cfun_fpr_bit_p (i
))
7042 insn
= save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
7044 RTX_FRAME_RELATED_P (insn
) = 1;
7047 if (offset
>= cfun_frame_layout
.f8_offset
)
7051 if (!TARGET_PACKED_STACK
)
7052 next_fpr
= cfun_save_high_fprs_p
? 31 : 0;
7054 /* Decrement stack pointer. */
7056 if (cfun_frame_layout
.frame_size
> 0)
7058 rtx frame_off
= GEN_INT (-cfun_frame_layout
.frame_size
);
7060 if (s390_stack_size
)
7062 HOST_WIDE_INT stack_check_mask
= ((s390_stack_size
- 1)
7063 & ~(s390_stack_guard
- 1));
7064 rtx t
= gen_rtx_AND (Pmode
, stack_pointer_rtx
,
7065 GEN_INT (stack_check_mask
));
7068 gen_cmpdi (t
, const0_rtx
);
7070 gen_cmpsi (t
, const0_rtx
);
7072 emit_insn (gen_conditional_trap (gen_rtx_EQ (CCmode
,
7073 gen_rtx_REG (CCmode
,
7079 if (s390_warn_framesize
> 0
7080 && cfun_frame_layout
.frame_size
>= s390_warn_framesize
)
7081 warning (0, "frame size of %qs is " HOST_WIDE_INT_PRINT_DEC
" bytes",
7082 current_function_name (), cfun_frame_layout
.frame_size
);
7084 if (s390_warn_dynamicstack_p
&& cfun
->calls_alloca
)
7085 warning (0, "%qs uses dynamic stack allocation", current_function_name ());
7087 /* Save incoming stack pointer into temp reg. */
7088 if (TARGET_BACKCHAIN
|| next_fpr
)
7089 insn
= emit_insn (gen_move_insn (temp_reg
, stack_pointer_rtx
));
7091 /* Subtract frame size from stack pointer. */
7093 if (DISP_IN_RANGE (INTVAL (frame_off
)))
7095 insn
= gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
7096 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
7098 insn
= emit_insn (insn
);
7102 if (!CONST_OK_FOR_K (INTVAL (frame_off
)))
7103 frame_off
= force_const_mem (Pmode
, frame_off
);
7105 insn
= emit_insn (gen_add2_insn (stack_pointer_rtx
, frame_off
));
7106 annotate_constant_pool_refs (&PATTERN (insn
));
7109 RTX_FRAME_RELATED_P (insn
) = 1;
7111 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
7112 gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
7113 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
7114 GEN_INT (-cfun_frame_layout
.frame_size
))),
7117 /* Set backchain. */
7119 if (TARGET_BACKCHAIN
)
7121 if (cfun_frame_layout
.backchain_offset
)
7122 addr
= gen_rtx_MEM (Pmode
,
7123 plus_constant (stack_pointer_rtx
,
7124 cfun_frame_layout
.backchain_offset
));
7126 addr
= gen_rtx_MEM (Pmode
, stack_pointer_rtx
);
7127 set_mem_alias_set (addr
, get_frame_alias_set ());
7128 insn
= emit_insn (gen_move_insn (addr
, temp_reg
));
7131 /* If we support asynchronous exceptions (e.g. for Java),
7132 we need to make sure the backchain pointer is set up
7133 before any possibly trapping memory access. */
7135 if (TARGET_BACKCHAIN
&& flag_non_call_exceptions
)
7137 addr
= gen_rtx_MEM (BLKmode
, gen_rtx_SCRATCH (VOIDmode
));
7138 emit_insn (gen_rtx_CLOBBER (VOIDmode
, addr
));
7142 /* Save fprs 8 - 15 (64 bit ABI). */
7144 if (cfun_save_high_fprs_p
&& next_fpr
)
7146 insn
= emit_insn (gen_add2_insn (temp_reg
,
7147 GEN_INT (cfun_frame_layout
.f8_offset
)));
7151 for (i
= 24; i
<= next_fpr
; i
++)
7152 if (cfun_fpr_bit_p (i
- 16))
7154 rtx addr
= plus_constant (stack_pointer_rtx
,
7155 cfun_frame_layout
.frame_size
7156 + cfun_frame_layout
.f8_offset
7159 insn
= save_fpr (temp_reg
, offset
, i
);
7161 RTX_FRAME_RELATED_P (insn
) = 1;
7163 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
7164 gen_rtx_SET (VOIDmode
,
7165 gen_rtx_MEM (DFmode
, addr
),
7166 gen_rtx_REG (DFmode
, i
)),
7171 /* Set frame pointer, if needed. */
7173 if (frame_pointer_needed
)
7175 insn
= emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
);
7176 RTX_FRAME_RELATED_P (insn
) = 1;
7179 /* Set up got pointer, if needed. */
7181 if (flag_pic
&& regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
])
7183 rtx insns
= s390_load_got ();
7185 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
7187 annotate_constant_pool_refs (&PATTERN (insn
));
7189 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD
, NULL_RTX
,
7196 if (TARGET_TPF_PROFILING
)
7198 /* Generate a BAS instruction to serve as a function
7199 entry intercept to facilitate the use of tracing
7200 algorithms located at the branch target. */
7201 emit_insn (gen_prologue_tpf ());
7203 /* Emit a blockage here so that all code
7204 lies between the profiling mechanisms. */
7205 emit_insn (gen_blockage ());
7209 /* Expand the epilogue into a bunch of separate insns. */
7212 s390_emit_epilogue (bool sibcall
)
7214 rtx frame_pointer
, return_reg
;
7215 int area_bottom
, area_top
, offset
= 0;
7220 if (TARGET_TPF_PROFILING
)
7223 /* Generate a BAS instruction to serve as a function
7224 entry intercept to facilitate the use of tracing
7225 algorithms located at the branch target. */
7227 /* Emit a blockage here so that all code
7228 lies between the profiling mechanisms. */
7229 emit_insn (gen_blockage ());
7231 emit_insn (gen_epilogue_tpf ());
7234 /* Check whether to use frame or stack pointer for restore. */
7236 frame_pointer
= (frame_pointer_needed
7237 ? hard_frame_pointer_rtx
: stack_pointer_rtx
);
7239 s390_frame_area (&area_bottom
, &area_top
);
7241 /* Check whether we can access the register save area.
7242 If not, increment the frame pointer as required. */
7244 if (area_top
<= area_bottom
)
7246 /* Nothing to restore. */
7248 else if (DISP_IN_RANGE (cfun_frame_layout
.frame_size
+ area_bottom
)
7249 && DISP_IN_RANGE (cfun_frame_layout
.frame_size
+ area_top
- 1))
7251 /* Area is in range. */
7252 offset
= cfun_frame_layout
.frame_size
;
7256 rtx insn
, frame_off
;
7258 offset
= area_bottom
< 0 ? -area_bottom
: 0;
7259 frame_off
= GEN_INT (cfun_frame_layout
.frame_size
- offset
);
7261 if (DISP_IN_RANGE (INTVAL (frame_off
)))
7263 insn
= gen_rtx_SET (VOIDmode
, frame_pointer
,
7264 gen_rtx_PLUS (Pmode
, frame_pointer
, frame_off
));
7265 insn
= emit_insn (insn
);
7269 if (!CONST_OK_FOR_K (INTVAL (frame_off
)))
7270 frame_off
= force_const_mem (Pmode
, frame_off
);
7272 insn
= emit_insn (gen_add2_insn (frame_pointer
, frame_off
));
7273 annotate_constant_pool_refs (&PATTERN (insn
));
7277 /* Restore call saved fprs. */
7281 if (cfun_save_high_fprs_p
)
7283 next_offset
= cfun_frame_layout
.f8_offset
;
7284 for (i
= 24; i
< 32; i
++)
7286 if (cfun_fpr_bit_p (i
- 16))
7288 restore_fpr (frame_pointer
,
7289 offset
+ next_offset
, i
);
7298 next_offset
= cfun_frame_layout
.f4_offset
;
7299 for (i
= 18; i
< 20; i
++)
7301 if (cfun_fpr_bit_p (i
- 16))
7303 restore_fpr (frame_pointer
,
7304 offset
+ next_offset
, i
);
7307 else if (!TARGET_PACKED_STACK
)
7313 /* Return register. */
7315 return_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
7317 /* Restore call saved gprs. */
7319 if (cfun_frame_layout
.first_restore_gpr
!= -1)
7324 /* Check for global register and save them
7325 to stack location from where they get restored. */
7327 for (i
= cfun_frame_layout
.first_restore_gpr
;
7328 i
<= cfun_frame_layout
.last_restore_gpr
;
7331 /* These registers are special and need to be
7332 restored in any case. */
7333 if (i
== STACK_POINTER_REGNUM
7334 || i
== RETURN_REGNUM
7336 || (flag_pic
&& i
== (int)PIC_OFFSET_TABLE_REGNUM
))
7341 addr
= plus_constant (frame_pointer
,
7342 offset
+ cfun_frame_layout
.gprs_offset
7343 + (i
- cfun_frame_layout
.first_save_gpr_slot
)
7345 addr
= gen_rtx_MEM (Pmode
, addr
);
7346 set_mem_alias_set (addr
, get_frame_alias_set ());
7347 emit_move_insn (addr
, gen_rtx_REG (Pmode
, i
));
7353 /* Fetch return address from stack before load multiple,
7354 this will do good for scheduling. */
7356 if (cfun_frame_layout
.save_return_addr_p
7357 || (cfun_frame_layout
.first_restore_gpr
< BASE_REGNUM
7358 && cfun_frame_layout
.last_restore_gpr
> RETURN_REGNUM
))
7360 int return_regnum
= find_unused_clobbered_reg();
7363 return_reg
= gen_rtx_REG (Pmode
, return_regnum
);
7365 addr
= plus_constant (frame_pointer
,
7366 offset
+ cfun_frame_layout
.gprs_offset
7368 - cfun_frame_layout
.first_save_gpr_slot
)
7370 addr
= gen_rtx_MEM (Pmode
, addr
);
7371 set_mem_alias_set (addr
, get_frame_alias_set ());
7372 emit_move_insn (return_reg
, addr
);
7376 insn
= restore_gprs (frame_pointer
,
7377 offset
+ cfun_frame_layout
.gprs_offset
7378 + (cfun_frame_layout
.first_restore_gpr
7379 - cfun_frame_layout
.first_save_gpr_slot
)
7381 cfun_frame_layout
.first_restore_gpr
,
7382 cfun_frame_layout
.last_restore_gpr
);
7389 /* Return to caller. */
7391 p
= rtvec_alloc (2);
7393 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
7394 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
, return_reg
);
7395 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
7400 /* Return the size in bytes of a function argument of
7401 type TYPE and/or mode MODE. At least one of TYPE or
7402 MODE must be specified. */
7405 s390_function_arg_size (enum machine_mode mode
, tree type
)
7408 return int_size_in_bytes (type
);
7410 /* No type info available for some library calls ... */
7411 if (mode
!= BLKmode
)
7412 return GET_MODE_SIZE (mode
);
7414 /* If we have neither type nor mode, abort */
7418 /* Return true if a function argument of type TYPE and mode MODE
7419 is to be passed in a floating-point register, if available. */
7422 s390_function_arg_float (enum machine_mode mode
, tree type
)
7424 int size
= s390_function_arg_size (mode
, type
);
7428 /* Soft-float changes the ABI: no floating-point registers are used. */
7429 if (TARGET_SOFT_FLOAT
)
7432 /* No type info available for some library calls ... */
7434 return mode
== SFmode
|| mode
== DFmode
;
7436 /* The ABI says that record types with a single member are treated
7437 just like that member would be. */
7438 while (TREE_CODE (type
) == RECORD_TYPE
)
7440 tree field
, single
= NULL_TREE
;
7442 for (field
= TYPE_FIELDS (type
); field
; field
= TREE_CHAIN (field
))
7444 if (TREE_CODE (field
) != FIELD_DECL
)
7447 if (single
== NULL_TREE
)
7448 single
= TREE_TYPE (field
);
7453 if (single
== NULL_TREE
)
7459 return TREE_CODE (type
) == REAL_TYPE
;
7462 /* Return true if a function argument of type TYPE and mode MODE
7463 is to be passed in an integer register, or a pair of integer
7464 registers, if available. */
7467 s390_function_arg_integer (enum machine_mode mode
, tree type
)
7469 int size
= s390_function_arg_size (mode
, type
);
7473 /* No type info available for some library calls ... */
7475 return GET_MODE_CLASS (mode
) == MODE_INT
7476 || (TARGET_SOFT_FLOAT
&& GET_MODE_CLASS (mode
) == MODE_FLOAT
);
7478 /* We accept small integral (and similar) types. */
7479 if (INTEGRAL_TYPE_P (type
)
7480 || POINTER_TYPE_P (type
)
7481 || TREE_CODE (type
) == OFFSET_TYPE
7482 || (TARGET_SOFT_FLOAT
&& TREE_CODE (type
) == REAL_TYPE
))
7485 /* We also accept structs of size 1, 2, 4, 8 that are not
7486 passed in floating-point registers. */
7487 if (AGGREGATE_TYPE_P (type
)
7488 && exact_log2 (size
) >= 0
7489 && !s390_function_arg_float (mode
, type
))
7495 /* Return 1 if a function argument of type TYPE and mode MODE
7496 is to be passed by reference. The ABI specifies that only
7497 structures of size 1, 2, 4, or 8 bytes are passed by value,
7498 all other structures (and complex numbers) are passed by
7502 s390_pass_by_reference (CUMULATIVE_ARGS
*ca ATTRIBUTE_UNUSED
,
7503 enum machine_mode mode
, tree type
,
7504 bool named ATTRIBUTE_UNUSED
)
7506 int size
= s390_function_arg_size (mode
, type
);
7512 if (AGGREGATE_TYPE_P (type
) && exact_log2 (size
) < 0)
7515 if (TREE_CODE (type
) == COMPLEX_TYPE
7516 || TREE_CODE (type
) == VECTOR_TYPE
)
7523 /* Update the data in CUM to advance over an argument of mode MODE and
7524 data type TYPE. (TYPE is null for libcalls where that information
7525 may not be available.). The boolean NAMED specifies whether the
7526 argument is a named argument (as opposed to an unnamed argument
7527 matching an ellipsis). */
7530 s390_function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
7531 tree type
, int named ATTRIBUTE_UNUSED
)
7533 if (s390_function_arg_float (mode
, type
))
7537 else if (s390_function_arg_integer (mode
, type
))
7539 int size
= s390_function_arg_size (mode
, type
);
7540 cum
->gprs
+= ((size
+ UNITS_PER_WORD
-1) / UNITS_PER_WORD
);
7546 /* Define where to put the arguments to a function.
7547 Value is zero to push the argument on the stack,
7548 or a hard register in which to store the argument.
7550 MODE is the argument's machine mode.
7551 TYPE is the data type of the argument (as a tree).
7552 This is null for libcalls where that information may
7554 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7555 the preceding args and about the function being called.
7556 NAMED is nonzero if this argument is a named parameter
7557 (otherwise it is an extra parameter matching an ellipsis).
7559 On S/390, we use general purpose registers 2 through 6 to
7560 pass integer, pointer, and certain structure arguments, and
7561 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
7562 to pass floating point arguments. All remaining arguments
7563 are pushed to the stack. */
7566 s390_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
, tree type
,
7567 int named ATTRIBUTE_UNUSED
)
7569 if (s390_function_arg_float (mode
, type
))
7571 if (cum
->fprs
+ 1 > FP_ARG_NUM_REG
)
7574 return gen_rtx_REG (mode
, cum
->fprs
+ 16);
7576 else if (s390_function_arg_integer (mode
, type
))
7578 int size
= s390_function_arg_size (mode
, type
);
7579 int n_gprs
= (size
+ UNITS_PER_WORD
-1) / UNITS_PER_WORD
;
7581 if (cum
->gprs
+ n_gprs
> GP_ARG_NUM_REG
)
7584 return gen_rtx_REG (mode
, cum
->gprs
+ 2);
7587 /* After the real arguments, expand_call calls us once again
7588 with a void_type_node type. Whatever we return here is
7589 passed as operand 2 to the call expanders.
7591 We don't need this feature ... */
7592 else if (type
== void_type_node
)
7598 /* Return true if return values of type TYPE should be returned
7599 in a memory buffer whose address is passed by the caller as
7600 hidden first argument. */
7603 s390_return_in_memory (tree type
, tree fundecl ATTRIBUTE_UNUSED
)
7605 /* We accept small integral (and similar) types. */
7606 if (INTEGRAL_TYPE_P (type
)
7607 || POINTER_TYPE_P (type
)
7608 || TREE_CODE (type
) == OFFSET_TYPE
7609 || TREE_CODE (type
) == REAL_TYPE
)
7610 return int_size_in_bytes (type
) > 8;
7612 /* Aggregates and similar constructs are always returned
7614 if (AGGREGATE_TYPE_P (type
)
7615 || TREE_CODE (type
) == COMPLEX_TYPE
7616 || TREE_CODE (type
) == VECTOR_TYPE
)
7619 /* ??? We get called on all sorts of random stuff from
7620 aggregate_value_p. We can't abort, but it's not clear
7621 what's safe to return. Pretend it's a struct I guess. */
7625 /* Define where to return a (scalar) value of type TYPE.
7626 If TYPE is null, define where to return a (scalar)
7627 value of mode MODE from a libcall. */
7630 s390_function_value (tree type
, enum machine_mode mode
)
7634 int unsignedp
= TYPE_UNSIGNED (type
);
7635 mode
= promote_mode (type
, TYPE_MODE (type
), &unsignedp
, 1);
7638 gcc_assert (GET_MODE_CLASS (mode
) == MODE_INT
7639 || GET_MODE_CLASS (mode
) == MODE_FLOAT
);
7640 gcc_assert (GET_MODE_SIZE (mode
) <= 8);
7642 if (TARGET_HARD_FLOAT
&& GET_MODE_CLASS (mode
) == MODE_FLOAT
)
7643 return gen_rtx_REG (mode
, 16);
7645 return gen_rtx_REG (mode
, 2);
7649 /* Create and return the va_list datatype.
7651 On S/390, va_list is an array type equivalent to
7653 typedef struct __va_list_tag
7657 void *__overflow_arg_area;
7658 void *__reg_save_area;
7661 where __gpr and __fpr hold the number of general purpose
7662 or floating point arguments used up to now, respectively,
7663 __overflow_arg_area points to the stack location of the
7664 next argument passed on the stack, and __reg_save_area
7665 always points to the start of the register area in the
7666 call frame of the current function. The function prologue
7667 saves all registers used for argument passing into this
7668 area if the function uses variable arguments. */
7671 s390_build_builtin_va_list (void)
7673 tree f_gpr
, f_fpr
, f_ovf
, f_sav
, record
, type_decl
;
7675 record
= lang_hooks
.types
.make_type (RECORD_TYPE
);
7678 build_decl (TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
7680 f_gpr
= build_decl (FIELD_DECL
, get_identifier ("__gpr"),
7681 long_integer_type_node
);
7682 f_fpr
= build_decl (FIELD_DECL
, get_identifier ("__fpr"),
7683 long_integer_type_node
);
7684 f_ovf
= build_decl (FIELD_DECL
, get_identifier ("__overflow_arg_area"),
7686 f_sav
= build_decl (FIELD_DECL
, get_identifier ("__reg_save_area"),
7689 va_list_gpr_counter_field
= f_gpr
;
7690 va_list_fpr_counter_field
= f_fpr
;
7692 DECL_FIELD_CONTEXT (f_gpr
) = record
;
7693 DECL_FIELD_CONTEXT (f_fpr
) = record
;
7694 DECL_FIELD_CONTEXT (f_ovf
) = record
;
7695 DECL_FIELD_CONTEXT (f_sav
) = record
;
7697 TREE_CHAIN (record
) = type_decl
;
7698 TYPE_NAME (record
) = type_decl
;
7699 TYPE_FIELDS (record
) = f_gpr
;
7700 TREE_CHAIN (f_gpr
) = f_fpr
;
7701 TREE_CHAIN (f_fpr
) = f_ovf
;
7702 TREE_CHAIN (f_ovf
) = f_sav
;
7704 layout_type (record
);
7706 /* The correct type is an array type of one element. */
7707 return build_array_type (record
, build_index_type (size_zero_node
));
7710 /* Implement va_start by filling the va_list structure VALIST.
7711 STDARG_P is always true, and ignored.
7712 NEXTARG points to the first anonymous stack argument.
7714 The following global variables are used to initialize
7715 the va_list structure:
7717 current_function_args_info:
7718 holds number of gprs and fprs used for named arguments.
7719 current_function_arg_offset_rtx:
7720 holds the offset of the first anonymous stack argument
7721 (relative to the virtual arg pointer). */
7724 s390_va_start (tree valist
, rtx nextarg ATTRIBUTE_UNUSED
)
7726 HOST_WIDE_INT n_gpr
, n_fpr
;
7728 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
7729 tree gpr
, fpr
, ovf
, sav
, t
;
7731 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
7732 f_fpr
= TREE_CHAIN (f_gpr
);
7733 f_ovf
= TREE_CHAIN (f_fpr
);
7734 f_sav
= TREE_CHAIN (f_ovf
);
7736 valist
= build_va_arg_indirect_ref (valist
);
7737 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
7738 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
7739 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
7740 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
7742 /* Count number of gp and fp argument registers used. */
7744 n_gpr
= current_function_args_info
.gprs
;
7745 n_fpr
= current_function_args_info
.fprs
;
7747 if (cfun
->va_list_gpr_size
)
7749 t
= build2 (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
,
7750 build_int_cst (NULL_TREE
, n_gpr
));
7751 TREE_SIDE_EFFECTS (t
) = 1;
7752 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7755 if (cfun
->va_list_fpr_size
)
7757 t
= build2 (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
,
7758 build_int_cst (NULL_TREE
, n_fpr
));
7759 TREE_SIDE_EFFECTS (t
) = 1;
7760 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7763 /* Find the overflow area. */
7764 if (n_gpr
+ cfun
->va_list_gpr_size
> GP_ARG_NUM_REG
7765 || n_fpr
+ cfun
->va_list_fpr_size
> FP_ARG_NUM_REG
)
7767 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
7769 off
= INTVAL (current_function_arg_offset_rtx
);
7770 off
= off
< 0 ? 0 : off
;
7771 if (TARGET_DEBUG_ARG
)
7772 fprintf (stderr
, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
7773 (int)n_gpr
, (int)n_fpr
, off
);
7775 t
= build2 (PLUS_EXPR
, TREE_TYPE (ovf
), t
, build_int_cst (NULL_TREE
, off
));
7777 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
7778 TREE_SIDE_EFFECTS (t
) = 1;
7779 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7782 /* Find the register save area. */
7783 if ((cfun
->va_list_gpr_size
&& n_gpr
< GP_ARG_NUM_REG
)
7784 || (cfun
->va_list_fpr_size
&& n_fpr
< FP_ARG_NUM_REG
))
7786 t
= make_tree (TREE_TYPE (sav
), return_address_pointer_rtx
);
7787 t
= build2 (PLUS_EXPR
, TREE_TYPE (sav
), t
,
7788 build_int_cst (NULL_TREE
, -RETURN_REGNUM
* UNITS_PER_WORD
));
7790 t
= build2 (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
7791 TREE_SIDE_EFFECTS (t
) = 1;
7792 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7796 /* Implement va_arg by updating the va_list structure
7797 VALIST as required to retrieve an argument of type
7798 TYPE, and returning that argument.
7800 Generates code equivalent to:
7802 if (integral value) {
7803 if (size <= 4 && args.gpr < 5 ||
7804 size > 4 && args.gpr < 4 )
7805 ret = args.reg_save_area[args.gpr+8]
7807 ret = *args.overflow_arg_area++;
7808 } else if (float value) {
7810 ret = args.reg_save_area[args.fpr+64]
7812 ret = *args.overflow_arg_area++;
7813 } else if (aggregate value) {
7815 ret = *args.reg_save_area[args.gpr]
7817 ret = **args.overflow_arg_area++;
7821 s390_gimplify_va_arg (tree valist
, tree type
, tree
*pre_p
,
7822 tree
*post_p ATTRIBUTE_UNUSED
)
7824 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
7825 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
7826 int indirect_p
, size
, n_reg
, sav_ofs
, sav_scale
, max_reg
;
7827 tree lab_false
, lab_over
, addr
;
7829 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
7830 f_fpr
= TREE_CHAIN (f_gpr
);
7831 f_ovf
= TREE_CHAIN (f_fpr
);
7832 f_sav
= TREE_CHAIN (f_ovf
);
7834 valist
= build_va_arg_indirect_ref (valist
);
7835 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
7836 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
7837 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
7838 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
7840 size
= int_size_in_bytes (type
);
7842 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
7844 if (TARGET_DEBUG_ARG
)
7846 fprintf (stderr
, "va_arg: aggregate type");
7850 /* Aggregates are passed by reference. */
7855 /* kernel stack layout on 31 bit: It is assumed here that no padding
7856 will be added by s390_frame_info because for va_args always an even
7857 number of gprs has to be saved r15-r2 = 14 regs. */
7858 sav_ofs
= 2 * UNITS_PER_WORD
;
7859 sav_scale
= UNITS_PER_WORD
;
7860 size
= UNITS_PER_WORD
;
7861 max_reg
= GP_ARG_NUM_REG
- n_reg
;
7863 else if (s390_function_arg_float (TYPE_MODE (type
), type
))
7865 if (TARGET_DEBUG_ARG
)
7867 fprintf (stderr
, "va_arg: float type");
7871 /* FP args go in FP registers, if present. */
7875 sav_ofs
= 16 * UNITS_PER_WORD
;
7877 max_reg
= FP_ARG_NUM_REG
- n_reg
;
7881 if (TARGET_DEBUG_ARG
)
7883 fprintf (stderr
, "va_arg: other type");
7887 /* Otherwise into GP registers. */
7890 n_reg
= (size
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
7892 /* kernel stack layout on 31 bit: It is assumed here that no padding
7893 will be added by s390_frame_info because for va_args always an even
7894 number of gprs has to be saved r15-r2 = 14 regs. */
7895 sav_ofs
= 2 * UNITS_PER_WORD
;
7897 if (size
< UNITS_PER_WORD
)
7898 sav_ofs
+= UNITS_PER_WORD
- size
;
7900 sav_scale
= UNITS_PER_WORD
;
7901 max_reg
= GP_ARG_NUM_REG
- n_reg
;
7904 /* Pull the value out of the saved registers ... */
7906 lab_false
= create_artificial_label ();
7907 lab_over
= create_artificial_label ();
7908 addr
= create_tmp_var (ptr_type_node
, "addr");
7909 DECL_POINTER_ALIAS_SET (addr
) = get_varargs_alias_set ();
7911 t
= fold_convert (TREE_TYPE (reg
), size_int (max_reg
));
7912 t
= build2 (GT_EXPR
, boolean_type_node
, reg
, t
);
7913 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
7914 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
7915 gimplify_and_add (t
, pre_p
);
7917 t
= build2 (PLUS_EXPR
, ptr_type_node
, sav
,
7918 fold_convert (ptr_type_node
, size_int (sav_ofs
)));
7919 u
= build2 (MULT_EXPR
, TREE_TYPE (reg
), reg
,
7920 fold_convert (TREE_TYPE (reg
), size_int (sav_scale
)));
7921 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
, fold_convert (ptr_type_node
, u
));
7923 t
= build2 (MODIFY_EXPR
, void_type_node
, addr
, t
);
7924 gimplify_and_add (t
, pre_p
);
7926 t
= build1 (GOTO_EXPR
, void_type_node
, lab_over
);
7927 gimplify_and_add (t
, pre_p
);
7929 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false
);
7930 append_to_statement_list (t
, pre_p
);
7933 /* ... Otherwise out of the overflow area. */
7936 if (size
< UNITS_PER_WORD
)
7937 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
,
7938 fold_convert (ptr_type_node
, size_int (UNITS_PER_WORD
- size
)));
7940 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
7942 u
= build2 (MODIFY_EXPR
, void_type_node
, addr
, t
);
7943 gimplify_and_add (u
, pre_p
);
7945 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
,
7946 fold_convert (ptr_type_node
, size_int (size
)));
7947 t
= build2 (MODIFY_EXPR
, ptr_type_node
, ovf
, t
);
7948 gimplify_and_add (t
, pre_p
);
7950 t
= build1 (LABEL_EXPR
, void_type_node
, lab_over
);
7951 append_to_statement_list (t
, pre_p
);
7954 /* Increment register save count. */
7956 u
= build2 (PREINCREMENT_EXPR
, TREE_TYPE (reg
), reg
,
7957 fold_convert (TREE_TYPE (reg
), size_int (n_reg
)));
7958 gimplify_and_add (u
, pre_p
);
7962 t
= build_pointer_type (build_pointer_type (type
));
7963 addr
= fold_convert (t
, addr
);
7964 addr
= build_va_arg_indirect_ref (addr
);
7968 t
= build_pointer_type (type
);
7969 addr
= fold_convert (t
, addr
);
7972 return build_va_arg_indirect_ref (addr
);
7980 S390_BUILTIN_THREAD_POINTER
,
7981 S390_BUILTIN_SET_THREAD_POINTER
,
7986 static unsigned int const code_for_builtin_64
[S390_BUILTIN_max
] = {
7991 static unsigned int const code_for_builtin_31
[S390_BUILTIN_max
] = {
7997 s390_init_builtins (void)
8001 ftype
= build_function_type (ptr_type_node
, void_list_node
);
8002 lang_hooks
.builtin_function ("__builtin_thread_pointer", ftype
,
8003 S390_BUILTIN_THREAD_POINTER
, BUILT_IN_MD
,
8006 ftype
= build_function_type_list (void_type_node
, ptr_type_node
, NULL_TREE
);
8007 lang_hooks
.builtin_function ("__builtin_set_thread_pointer", ftype
,
8008 S390_BUILTIN_SET_THREAD_POINTER
, BUILT_IN_MD
,
8012 /* Expand an expression EXP that calls a built-in function,
8013 with result going to TARGET if that's convenient
8014 (and in mode MODE if that's convenient).
8015 SUBTARGET may be used as the target for computing one of EXP's operands.
8016 IGNORE is nonzero if the value is to be ignored. */
8019 s390_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
8020 enum machine_mode mode ATTRIBUTE_UNUSED
,
8021 int ignore ATTRIBUTE_UNUSED
)
8025 unsigned int const *code_for_builtin
=
8026 TARGET_64BIT
? code_for_builtin_64
: code_for_builtin_31
;
8028 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
8029 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8030 tree arglist
= TREE_OPERAND (exp
, 1);
8031 enum insn_code icode
;
8032 rtx op
[MAX_ARGS
], pat
;
8036 if (fcode
>= S390_BUILTIN_max
)
8037 internal_error ("bad builtin fcode");
8038 icode
= code_for_builtin
[fcode
];
8040 internal_error ("bad builtin fcode");
8042 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
8044 for (arglist
= TREE_OPERAND (exp
, 1), arity
= 0;
8046 arglist
= TREE_CHAIN (arglist
), arity
++)
8048 const struct insn_operand_data
*insn_op
;
8050 tree arg
= TREE_VALUE (arglist
);
8051 if (arg
== error_mark_node
)
8053 if (arity
> MAX_ARGS
)
8056 insn_op
= &insn_data
[icode
].operand
[arity
+ nonvoid
];
8058 op
[arity
] = expand_expr (arg
, NULL_RTX
, insn_op
->mode
, 0);
8060 if (!(*insn_op
->predicate
) (op
[arity
], insn_op
->mode
))
8061 op
[arity
] = copy_to_mode_reg (insn_op
->mode
, op
[arity
]);
8066 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8068 || GET_MODE (target
) != tmode
8069 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8070 target
= gen_reg_rtx (tmode
);
8076 pat
= GEN_FCN (icode
) (target
);
8080 pat
= GEN_FCN (icode
) (target
, op
[0]);
8082 pat
= GEN_FCN (icode
) (op
[0]);
8085 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
8101 /* Output assembly code for the trampoline template to
8104 On S/390, we use gpr 1 internally in the trampoline code;
8105 gpr 0 is used to hold the static chain. */
8108 s390_trampoline_template (FILE *file
)
8111 op
[0] = gen_rtx_REG (Pmode
, 0);
8112 op
[1] = gen_rtx_REG (Pmode
, 1);
8116 output_asm_insn ("basr\t%1,0", op
);
8117 output_asm_insn ("lmg\t%0,%1,14(%1)", op
);
8118 output_asm_insn ("br\t%1", op
);
8119 ASM_OUTPUT_SKIP (file
, (HOST_WIDE_INT
)(TRAMPOLINE_SIZE
- 10));
8123 output_asm_insn ("basr\t%1,0", op
);
8124 output_asm_insn ("lm\t%0,%1,6(%1)", op
);
8125 output_asm_insn ("br\t%1", op
);
8126 ASM_OUTPUT_SKIP (file
, (HOST_WIDE_INT
)(TRAMPOLINE_SIZE
- 8));
8130 /* Emit RTL insns to initialize the variable parts of a trampoline.
8131 FNADDR is an RTX for the address of the function's pure code.
8132 CXT is an RTX for the static chain value for the function. */
8135 s390_initialize_trampoline (rtx addr
, rtx fnaddr
, rtx cxt
)
8137 emit_move_insn (gen_rtx_MEM (Pmode
,
8138 memory_address (Pmode
,
8139 plus_constant (addr
, (TARGET_64BIT
? 16 : 8)))), cxt
);
8140 emit_move_insn (gen_rtx_MEM (Pmode
,
8141 memory_address (Pmode
,
8142 plus_constant (addr
, (TARGET_64BIT
? 24 : 12)))), fnaddr
);
8145 /* Return rtx for 64-bit constant formed from the 32-bit subwords
8146 LOW and HIGH, independent of the host word size. */
8149 s390_gen_rtx_const_DI (int high
, int low
)
8151 #if HOST_BITS_PER_WIDE_INT >= 64
8153 val
= (HOST_WIDE_INT
)high
;
8155 val
|= (HOST_WIDE_INT
)low
;
8157 return GEN_INT (val
);
8159 #if HOST_BITS_PER_WIDE_INT >= 32
8160 return immed_double_const ((HOST_WIDE_INT
)low
, (HOST_WIDE_INT
)high
, DImode
);
8167 /* Output assembler code to FILE to increment profiler label # LABELNO
8168 for profiling a function entry. */
8171 s390_function_profiler (FILE *file
, int labelno
)
8176 ASM_GENERATE_INTERNAL_LABEL (label
, "LP", labelno
);
8178 fprintf (file
, "# function profiler \n");
8180 op
[0] = gen_rtx_REG (Pmode
, RETURN_REGNUM
);
8181 op
[1] = gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
8182 op
[1] = gen_rtx_MEM (Pmode
, plus_constant (op
[1], UNITS_PER_WORD
));
8184 op
[2] = gen_rtx_REG (Pmode
, 1);
8185 op
[3] = gen_rtx_SYMBOL_REF (Pmode
, label
);
8186 SYMBOL_REF_FLAGS (op
[3]) = SYMBOL_FLAG_LOCAL
;
8188 op
[4] = gen_rtx_SYMBOL_REF (Pmode
, "_mcount");
8191 op
[4] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[4]), UNSPEC_PLT
);
8192 op
[4] = gen_rtx_CONST (Pmode
, op
[4]);
8197 output_asm_insn ("stg\t%0,%1", op
);
8198 output_asm_insn ("larl\t%2,%3", op
);
8199 output_asm_insn ("brasl\t%0,%4", op
);
8200 output_asm_insn ("lg\t%0,%1", op
);
8204 op
[6] = gen_label_rtx ();
8206 output_asm_insn ("st\t%0,%1", op
);
8207 output_asm_insn ("bras\t%2,%l6", op
);
8208 output_asm_insn (".long\t%4", op
);
8209 output_asm_insn (".long\t%3", op
);
8210 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
8211 output_asm_insn ("l\t%0,0(%2)", op
);
8212 output_asm_insn ("l\t%2,4(%2)", op
);
8213 output_asm_insn ("basr\t%0,%0", op
);
8214 output_asm_insn ("l\t%0,%1", op
);
8218 op
[5] = gen_label_rtx ();
8219 op
[6] = gen_label_rtx ();
8221 output_asm_insn ("st\t%0,%1", op
);
8222 output_asm_insn ("bras\t%2,%l6", op
);
8223 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[5]));
8224 output_asm_insn (".long\t%4-%l5", op
);
8225 output_asm_insn (".long\t%3-%l5", op
);
8226 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
8227 output_asm_insn ("lr\t%0,%2", op
);
8228 output_asm_insn ("a\t%0,0(%2)", op
);
8229 output_asm_insn ("a\t%2,4(%2)", op
);
8230 output_asm_insn ("basr\t%0,%0", op
);
8231 output_asm_insn ("l\t%0,%1", op
);
8235 /* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
8236 into its SYMBOL_REF_FLAGS. */
8239 s390_encode_section_info (tree decl
, rtx rtl
, int first
)
8241 default_encode_section_info (decl
, rtl
, first
);
8243 /* If a variable has a forced alignment to < 2 bytes, mark it with
8244 SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL operand. */
8245 if (TREE_CODE (decl
) == VAR_DECL
8246 && DECL_USER_ALIGN (decl
) && DECL_ALIGN (decl
) < 16)
8247 SYMBOL_REF_FLAGS (XEXP (rtl
, 0)) |= SYMBOL_FLAG_ALIGN1
;
8250 /* Output thunk to FILE that implements a C++ virtual function call (with
8251 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
8252 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
8253 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
8254 relative to the resulting this pointer. */
8257 s390_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
8258 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
8264 /* Operand 0 is the target function. */
8265 op
[0] = XEXP (DECL_RTL (function
), 0);
8266 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (op
[0]))
8269 op
[0] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[0]),
8270 TARGET_64BIT
? UNSPEC_PLT
: UNSPEC_GOT
);
8271 op
[0] = gen_rtx_CONST (Pmode
, op
[0]);
8274 /* Operand 1 is the 'this' pointer. */
8275 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
8276 op
[1] = gen_rtx_REG (Pmode
, 3);
8278 op
[1] = gen_rtx_REG (Pmode
, 2);
8280 /* Operand 2 is the delta. */
8281 op
[2] = GEN_INT (delta
);
8283 /* Operand 3 is the vcall_offset. */
8284 op
[3] = GEN_INT (vcall_offset
);
8286 /* Operand 4 is the temporary register. */
8287 op
[4] = gen_rtx_REG (Pmode
, 1);
8289 /* Operands 5 to 8 can be used as labels. */
8295 /* Operand 9 can be used for temporary register. */
8298 /* Generate code. */
8301 /* Setup literal pool pointer if required. */
8302 if ((!DISP_IN_RANGE (delta
)
8303 && !CONST_OK_FOR_K (delta
)
8304 && !CONST_OK_FOR_Os (delta
))
8305 || (!DISP_IN_RANGE (vcall_offset
)
8306 && !CONST_OK_FOR_K (vcall_offset
)
8307 && !CONST_OK_FOR_Os (vcall_offset
)))
8309 op
[5] = gen_label_rtx ();
8310 output_asm_insn ("larl\t%4,%5", op
);
8313 /* Add DELTA to this pointer. */
8316 if (CONST_OK_FOR_J (delta
))
8317 output_asm_insn ("la\t%1,%2(%1)", op
);
8318 else if (DISP_IN_RANGE (delta
))
8319 output_asm_insn ("lay\t%1,%2(%1)", op
);
8320 else if (CONST_OK_FOR_K (delta
))
8321 output_asm_insn ("aghi\t%1,%2", op
);
8322 else if (CONST_OK_FOR_Os (delta
))
8323 output_asm_insn ("agfi\t%1,%2", op
);
8326 op
[6] = gen_label_rtx ();
8327 output_asm_insn ("agf\t%1,%6-%5(%4)", op
);
8331 /* Perform vcall adjustment. */
8334 if (DISP_IN_RANGE (vcall_offset
))
8336 output_asm_insn ("lg\t%4,0(%1)", op
);
8337 output_asm_insn ("ag\t%1,%3(%4)", op
);
8339 else if (CONST_OK_FOR_K (vcall_offset
))
8341 output_asm_insn ("lghi\t%4,%3", op
);
8342 output_asm_insn ("ag\t%4,0(%1)", op
);
8343 output_asm_insn ("ag\t%1,0(%4)", op
);
8345 else if (CONST_OK_FOR_Os (vcall_offset
))
8347 output_asm_insn ("lgfi\t%4,%3", op
);
8348 output_asm_insn ("ag\t%4,0(%1)", op
);
8349 output_asm_insn ("ag\t%1,0(%4)", op
);
8353 op
[7] = gen_label_rtx ();
8354 output_asm_insn ("llgf\t%4,%7-%5(%4)", op
);
8355 output_asm_insn ("ag\t%4,0(%1)", op
);
8356 output_asm_insn ("ag\t%1,0(%4)", op
);
8360 /* Jump to target. */
8361 output_asm_insn ("jg\t%0", op
);
8363 /* Output literal pool if required. */
8366 output_asm_insn (".align\t4", op
);
8367 targetm
.asm_out
.internal_label (file
, "L",
8368 CODE_LABEL_NUMBER (op
[5]));
8372 targetm
.asm_out
.internal_label (file
, "L",
8373 CODE_LABEL_NUMBER (op
[6]));
8374 output_asm_insn (".long\t%2", op
);
8378 targetm
.asm_out
.internal_label (file
, "L",
8379 CODE_LABEL_NUMBER (op
[7]));
8380 output_asm_insn (".long\t%3", op
);
8385 /* Setup base pointer if required. */
8387 || (!DISP_IN_RANGE (delta
)
8388 && !CONST_OK_FOR_K (delta
)
8389 && !CONST_OK_FOR_Os (delta
))
8390 || (!DISP_IN_RANGE (delta
)
8391 && !CONST_OK_FOR_K (vcall_offset
)
8392 && !CONST_OK_FOR_Os (vcall_offset
)))
8394 op
[5] = gen_label_rtx ();
8395 output_asm_insn ("basr\t%4,0", op
);
8396 targetm
.asm_out
.internal_label (file
, "L",
8397 CODE_LABEL_NUMBER (op
[5]));
8400 /* Add DELTA to this pointer. */
8403 if (CONST_OK_FOR_J (delta
))
8404 output_asm_insn ("la\t%1,%2(%1)", op
);
8405 else if (DISP_IN_RANGE (delta
))
8406 output_asm_insn ("lay\t%1,%2(%1)", op
);
8407 else if (CONST_OK_FOR_K (delta
))
8408 output_asm_insn ("ahi\t%1,%2", op
);
8409 else if (CONST_OK_FOR_Os (delta
))
8410 output_asm_insn ("afi\t%1,%2", op
);
8413 op
[6] = gen_label_rtx ();
8414 output_asm_insn ("a\t%1,%6-%5(%4)", op
);
8418 /* Perform vcall adjustment. */
8421 if (CONST_OK_FOR_J (vcall_offset
))
8423 output_asm_insn ("l\t%4,0(%1)", op
);
8424 output_asm_insn ("a\t%1,%3(%4)", op
);
8426 else if (DISP_IN_RANGE (vcall_offset
))
8428 output_asm_insn ("l\t%4,0(%1)", op
);
8429 output_asm_insn ("ay\t%1,%3(%4)", op
);
8431 else if (CONST_OK_FOR_K (vcall_offset
))
8433 output_asm_insn ("lhi\t%4,%3", op
);
8434 output_asm_insn ("a\t%4,0(%1)", op
);
8435 output_asm_insn ("a\t%1,0(%4)", op
);
8437 else if (CONST_OK_FOR_Os (vcall_offset
))
8439 output_asm_insn ("iilf\t%4,%3", op
);
8440 output_asm_insn ("a\t%4,0(%1)", op
);
8441 output_asm_insn ("a\t%1,0(%4)", op
);
8445 op
[7] = gen_label_rtx ();
8446 output_asm_insn ("l\t%4,%7-%5(%4)", op
);
8447 output_asm_insn ("a\t%4,0(%1)", op
);
8448 output_asm_insn ("a\t%1,0(%4)", op
);
8451 /* We had to clobber the base pointer register.
8452 Re-setup the base pointer (with a different base). */
8453 op
[5] = gen_label_rtx ();
8454 output_asm_insn ("basr\t%4,0", op
);
8455 targetm
.asm_out
.internal_label (file
, "L",
8456 CODE_LABEL_NUMBER (op
[5]));
8459 /* Jump to target. */
8460 op
[8] = gen_label_rtx ();
8463 output_asm_insn ("l\t%4,%8-%5(%4)", op
);
8465 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
8466 /* We cannot call through .plt, since .plt requires %r12 loaded. */
8467 else if (flag_pic
== 1)
8469 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
8470 output_asm_insn ("l\t%4,%0(%4)", op
);
8472 else if (flag_pic
== 2)
8474 op
[9] = gen_rtx_REG (Pmode
, 0);
8475 output_asm_insn ("l\t%9,%8-4-%5(%4)", op
);
8476 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
8477 output_asm_insn ("ar\t%4,%9", op
);
8478 output_asm_insn ("l\t%4,0(%4)", op
);
8481 output_asm_insn ("br\t%4", op
);
8483 /* Output literal pool. */
8484 output_asm_insn (".align\t4", op
);
8486 if (nonlocal
&& flag_pic
== 2)
8487 output_asm_insn (".long\t%0", op
);
8490 op
[0] = gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
8491 SYMBOL_REF_FLAGS (op
[0]) = SYMBOL_FLAG_LOCAL
;
8494 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[8]));
8496 output_asm_insn (".long\t%0", op
);
8498 output_asm_insn (".long\t%0-%5", op
);
8502 targetm
.asm_out
.internal_label (file
, "L",
8503 CODE_LABEL_NUMBER (op
[6]));
8504 output_asm_insn (".long\t%2", op
);
8508 targetm
.asm_out
.internal_label (file
, "L",
8509 CODE_LABEL_NUMBER (op
[7]));
8510 output_asm_insn (".long\t%3", op
);
8516 s390_valid_pointer_mode (enum machine_mode mode
)
8518 return (mode
== SImode
|| (TARGET_64BIT
&& mode
== DImode
));
8521 /* Checks whether the given ARGUMENT_LIST would use a caller
8522 saved register. This is used to decide whether sibling call
8523 optimization could be performed on the respective function
8527 s390_call_saved_register_used (tree argument_list
)
8529 CUMULATIVE_ARGS cum
;
8531 enum machine_mode mode
;
8536 INIT_CUMULATIVE_ARGS (cum
, NULL
, NULL
, 0, 0);
8538 while (argument_list
)
8540 parameter
= TREE_VALUE (argument_list
);
8541 argument_list
= TREE_CHAIN (argument_list
);
8543 gcc_assert (parameter
);
8545 /* For an undeclared variable passed as parameter we will get
8546 an ERROR_MARK node here. */
8547 if (TREE_CODE (parameter
) == ERROR_MARK
)
8550 type
= TREE_TYPE (parameter
);
8553 mode
= TYPE_MODE (type
);
8556 if (pass_by_reference (&cum
, mode
, type
, true))
8559 type
= build_pointer_type (type
);
8562 parm_rtx
= s390_function_arg (&cum
, mode
, type
, 0);
8564 s390_function_arg_advance (&cum
, mode
, type
, 0);
8566 if (parm_rtx
&& REG_P (parm_rtx
))
8569 reg
< HARD_REGNO_NREGS (REGNO (parm_rtx
), GET_MODE (parm_rtx
));
8571 if (! call_used_regs
[reg
+ REGNO (parm_rtx
)])
8578 /* Return true if the given call expression can be
8579 turned into a sibling call.
8580 DECL holds the declaration of the function to be called whereas
8581 EXP is the call expression itself. */
8584 s390_function_ok_for_sibcall (tree decl
, tree exp
)
8586 /* The TPF epilogue uses register 1. */
8587 if (TARGET_TPF_PROFILING
)
8590 /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
8591 which would have to be restored before the sibcall. */
8592 if (!TARGET_64BIT
&& flag_pic
&& decl
&& TREE_PUBLIC (decl
))
8595 /* Register 6 on s390 is available as an argument register but unfortunately
8596 "caller saved". This makes functions needing this register for arguments
8597 not suitable for sibcalls. */
8598 if (TREE_OPERAND (exp
, 1)
8599 && s390_call_saved_register_used (TREE_OPERAND (exp
, 1)))
8605 /* Return the fixed registers used for condition codes. */
8608 s390_fixed_condition_code_regs (unsigned int *p1
, unsigned int *p2
)
8611 *p2
= INVALID_REGNUM
;
8616 /* This function is used by the call expanders of the machine description.
8617 It emits the call insn itself together with the necessary operations
8618 to adjust the target address and returns the emitted insn.
8619 ADDR_LOCATION is the target address rtx
8620 TLS_CALL the location of the thread-local symbol
8621 RESULT_REG the register where the result of the call should be stored
8622 RETADDR_REG the register where the return address should be stored
8623 If this parameter is NULL_RTX the call is considered
8624 to be a sibling call. */
8627 s390_emit_call (rtx addr_location
, rtx tls_call
, rtx result_reg
,
8630 bool plt_call
= false;
8636 /* Direct function calls need special treatment. */
8637 if (GET_CODE (addr_location
) == SYMBOL_REF
)
8639 /* When calling a global routine in PIC mode, we must
8640 replace the symbol itself with the PLT stub. */
8641 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (addr_location
))
8643 addr_location
= gen_rtx_UNSPEC (Pmode
,
8644 gen_rtvec (1, addr_location
),
8646 addr_location
= gen_rtx_CONST (Pmode
, addr_location
);
8650 /* Unless we can use the bras(l) insn, force the
8651 routine address into a register. */
8652 if (!TARGET_SMALL_EXEC
&& !TARGET_CPU_ZARCH
)
8655 addr_location
= legitimize_pic_address (addr_location
, 0);
8657 addr_location
= force_reg (Pmode
, addr_location
);
8661 /* If it is already an indirect call or the code above moved the
8662 SYMBOL_REF to somewhere else make sure the address can be found in
8664 if (retaddr_reg
== NULL_RTX
8665 && GET_CODE (addr_location
) != SYMBOL_REF
8668 emit_move_insn (gen_rtx_REG (Pmode
, SIBCALL_REGNUM
), addr_location
);
8669 addr_location
= gen_rtx_REG (Pmode
, SIBCALL_REGNUM
);
8672 addr_location
= gen_rtx_MEM (QImode
, addr_location
);
8673 call
= gen_rtx_CALL (VOIDmode
, addr_location
, const0_rtx
);
8675 if (result_reg
!= NULL_RTX
)
8676 call
= gen_rtx_SET (VOIDmode
, result_reg
, call
);
8678 if (retaddr_reg
!= NULL_RTX
)
8680 clobber
= gen_rtx_CLOBBER (VOIDmode
, retaddr_reg
);
8682 if (tls_call
!= NULL_RTX
)
8683 vec
= gen_rtvec (3, call
, clobber
,
8684 gen_rtx_USE (VOIDmode
, tls_call
));
8686 vec
= gen_rtvec (2, call
, clobber
);
8688 call
= gen_rtx_PARALLEL (VOIDmode
, vec
);
8691 insn
= emit_call_insn (call
);
8693 /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
8694 if ((!TARGET_64BIT
&& plt_call
) || tls_call
!= NULL_RTX
)
8696 /* s390_function_ok_for_sibcall should
8697 have denied sibcalls in this case. */
8698 gcc_assert (retaddr_reg
!= NULL_RTX
);
8700 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), pic_offset_table_rtx
);
8705 /* Implement CONDITIONAL_REGISTER_USAGE. */
8708 s390_conditional_register_usage (void)
8714 fixed_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
8715 call_used_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
8717 if (TARGET_CPU_ZARCH
)
8719 fixed_regs
[BASE_REGNUM
] = 0;
8720 call_used_regs
[BASE_REGNUM
] = 0;
8721 fixed_regs
[RETURN_REGNUM
] = 0;
8722 call_used_regs
[RETURN_REGNUM
] = 0;
8726 for (i
= 24; i
< 32; i
++)
8727 call_used_regs
[i
] = call_really_used_regs
[i
] = 0;
8731 for (i
= 18; i
< 20; i
++)
8732 call_used_regs
[i
] = call_really_used_regs
[i
] = 0;
8735 if (TARGET_SOFT_FLOAT
)
8737 for (i
= 16; i
< 32; i
++)
8738 call_used_regs
[i
] = fixed_regs
[i
] = 1;
8742 /* Corresponding function to eh_return expander. */
8744 static GTY(()) rtx s390_tpf_eh_return_symbol
;
8746 s390_emit_tpf_eh_return (rtx target
)
8750 if (!s390_tpf_eh_return_symbol
)
8751 s390_tpf_eh_return_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "__tpf_eh_return");
8753 reg
= gen_rtx_REG (Pmode
, 2);
8755 emit_move_insn (reg
, target
);
8756 insn
= s390_emit_call (s390_tpf_eh_return_symbol
, NULL_RTX
, reg
,
8757 gen_rtx_REG (Pmode
, RETURN_REGNUM
));
8758 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), reg
);
8760 emit_move_insn (EH_RETURN_HANDLER_RTX
, reg
);
8763 /* Rework the prologue/epilogue to avoid saving/restoring
8764 registers unnecessarily. */
8767 s390_optimize_prologue (void)
8769 rtx insn
, new_insn
, next_insn
;
8771 /* Do a final recompute of the frame-related data. */
8773 s390_update_frame_layout ();
8775 /* If all special registers are in fact used, there's nothing we
8776 can do, so no point in walking the insn list. */
8778 if (cfun_frame_layout
.first_save_gpr
<= BASE_REGNUM
8779 && cfun_frame_layout
.last_save_gpr
>= BASE_REGNUM
8780 && (TARGET_CPU_ZARCH
8781 || (cfun_frame_layout
.first_save_gpr
<= RETURN_REGNUM
8782 && cfun_frame_layout
.last_save_gpr
>= RETURN_REGNUM
)))
8785 /* Search for prologue/epilogue insns and replace them. */
8787 for (insn
= get_insns (); insn
; insn
= next_insn
)
8789 int first
, last
, off
;
8790 rtx set
, base
, offset
;
8792 next_insn
= NEXT_INSN (insn
);
8794 if (GET_CODE (insn
) != INSN
)
8797 if (GET_CODE (PATTERN (insn
)) == PARALLEL
8798 && store_multiple_operation (PATTERN (insn
), VOIDmode
))
8800 set
= XVECEXP (PATTERN (insn
), 0, 0);
8801 first
= REGNO (SET_SRC (set
));
8802 last
= first
+ XVECLEN (PATTERN (insn
), 0) - 1;
8803 offset
= const0_rtx
;
8804 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
8805 off
= INTVAL (offset
);
8807 if (GET_CODE (base
) != REG
|| off
< 0)
8809 if (cfun_frame_layout
.first_save_gpr
!= -1
8810 && (cfun_frame_layout
.first_save_gpr
< first
8811 || cfun_frame_layout
.last_save_gpr
> last
))
8813 if (REGNO (base
) != STACK_POINTER_REGNUM
8814 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
8816 if (first
> BASE_REGNUM
|| last
< BASE_REGNUM
)
8819 if (cfun_frame_layout
.first_save_gpr
!= -1)
8821 new_insn
= save_gprs (base
,
8822 off
+ (cfun_frame_layout
.first_save_gpr
8823 - first
) * UNITS_PER_WORD
,
8824 cfun_frame_layout
.first_save_gpr
,
8825 cfun_frame_layout
.last_save_gpr
);
8826 new_insn
= emit_insn_before (new_insn
, insn
);
8827 INSN_ADDRESSES_NEW (new_insn
, -1);
8834 if (cfun_frame_layout
.first_save_gpr
== -1
8835 && GET_CODE (PATTERN (insn
)) == SET
8836 && GET_CODE (SET_SRC (PATTERN (insn
))) == REG
8837 && (REGNO (SET_SRC (PATTERN (insn
))) == BASE_REGNUM
8838 || (!TARGET_CPU_ZARCH
8839 && REGNO (SET_SRC (PATTERN (insn
))) == RETURN_REGNUM
))
8840 && GET_CODE (SET_DEST (PATTERN (insn
))) == MEM
)
8842 set
= PATTERN (insn
);
8843 first
= REGNO (SET_SRC (set
));
8844 offset
= const0_rtx
;
8845 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
8846 off
= INTVAL (offset
);
8848 if (GET_CODE (base
) != REG
|| off
< 0)
8850 if (REGNO (base
) != STACK_POINTER_REGNUM
8851 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
8858 if (GET_CODE (PATTERN (insn
)) == PARALLEL
8859 && load_multiple_operation (PATTERN (insn
), VOIDmode
))
8861 set
= XVECEXP (PATTERN (insn
), 0, 0);
8862 first
= REGNO (SET_DEST (set
));
8863 last
= first
+ XVECLEN (PATTERN (insn
), 0) - 1;
8864 offset
= const0_rtx
;
8865 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
8866 off
= INTVAL (offset
);
8868 if (GET_CODE (base
) != REG
|| off
< 0)
8870 if (cfun_frame_layout
.first_restore_gpr
!= -1
8871 && (cfun_frame_layout
.first_restore_gpr
< first
8872 || cfun_frame_layout
.last_restore_gpr
> last
))
8874 if (REGNO (base
) != STACK_POINTER_REGNUM
8875 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
8877 if (first
> BASE_REGNUM
|| last
< BASE_REGNUM
)
8880 if (cfun_frame_layout
.first_restore_gpr
!= -1)
8882 new_insn
= restore_gprs (base
,
8883 off
+ (cfun_frame_layout
.first_restore_gpr
8884 - first
) * UNITS_PER_WORD
,
8885 cfun_frame_layout
.first_restore_gpr
,
8886 cfun_frame_layout
.last_restore_gpr
);
8887 new_insn
= emit_insn_before (new_insn
, insn
);
8888 INSN_ADDRESSES_NEW (new_insn
, -1);
8895 if (cfun_frame_layout
.first_restore_gpr
== -1
8896 && GET_CODE (PATTERN (insn
)) == SET
8897 && GET_CODE (SET_DEST (PATTERN (insn
))) == REG
8898 && (REGNO (SET_DEST (PATTERN (insn
))) == BASE_REGNUM
8899 || (!TARGET_CPU_ZARCH
8900 && REGNO (SET_DEST (PATTERN (insn
))) == RETURN_REGNUM
))
8901 && GET_CODE (SET_SRC (PATTERN (insn
))) == MEM
)
8903 set
= PATTERN (insn
);
8904 first
= REGNO (SET_DEST (set
));
8905 offset
= const0_rtx
;
8906 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
8907 off
= INTVAL (offset
);
8909 if (GET_CODE (base
) != REG
|| off
< 0)
8911 if (REGNO (base
) != STACK_POINTER_REGNUM
8912 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
8921 /* Perform machine-dependent processing. */
8926 bool pool_overflow
= false;
8928 /* Make sure all splits have been performed; splits after
8929 machine_dependent_reorg might confuse insn length counts. */
8930 split_all_insns_noflow ();
8933 /* Install the main literal pool and the associated base
8934 register load insns.
8936 In addition, there are two problematic situations we need
8939 - the literal pool might be > 4096 bytes in size, so that
8940 some of its elements cannot be directly accessed
8942 - a branch target might be > 64K away from the branch, so that
8943 it is not possible to use a PC-relative instruction.
8945 To fix those, we split the single literal pool into multiple
8946 pool chunks, reloading the pool base register at various
8947 points throughout the function to ensure it always points to
8948 the pool chunk the following code expects, and / or replace
8949 PC-relative branches by absolute branches.
8951 However, the two problems are interdependent: splitting the
8952 literal pool can move a branch further away from its target,
8953 causing the 64K limit to overflow, and on the other hand,
8954 replacing a PC-relative branch by an absolute branch means
8955 we need to put the branch target address into the literal
8956 pool, possibly causing it to overflow.
8958 So, we loop trying to fix up both problems until we manage
8959 to satisfy both conditions at the same time. Note that the
8960 loop is guaranteed to terminate as every pass of the loop
8961 strictly decreases the total number of PC-relative branches
8962 in the function. (This is not completely true as there
8963 might be branch-over-pool insns introduced by chunkify_start.
8964 Those never need to be split however.) */
8968 struct constant_pool
*pool
= NULL
;
8970 /* Collect the literal pool. */
8973 pool
= s390_mainpool_start ();
8975 pool_overflow
= true;
8978 /* If literal pool overflowed, start to chunkify it. */
8980 pool
= s390_chunkify_start ();
8982 /* Split out-of-range branches. If this has created new
8983 literal pool entries, cancel current chunk list and
8984 recompute it. zSeries machines have large branch
8985 instructions, so we never need to split a branch. */
8986 if (!TARGET_CPU_ZARCH
&& s390_split_branches ())
8989 s390_chunkify_cancel (pool
);
8991 s390_mainpool_cancel (pool
);
8996 /* If we made it up to here, both conditions are satisfied.
8997 Finish up literal pool related changes. */
8999 s390_chunkify_finish (pool
);
9001 s390_mainpool_finish (pool
);
9003 /* We're done splitting branches. */
9004 cfun
->machine
->split_branches_pending_p
= false;
9008 /* Generate out-of-pool execute target insns. */
9009 if (TARGET_CPU_ZARCH
)
9011 rtx insn
, label
, target
;
9013 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
9015 label
= s390_execute_label (insn
);
9019 gcc_assert (label
!= const0_rtx
);
9021 target
= emit_label (XEXP (label
, 0));
9022 INSN_ADDRESSES_NEW (target
, -1);
9024 target
= emit_insn (s390_execute_target (insn
));
9025 INSN_ADDRESSES_NEW (target
, -1);
9029 /* Try to optimize prologue and epilogue further. */
9030 s390_optimize_prologue ();
9034 /* Initialize GCC target structure. */
9036 #undef TARGET_ASM_ALIGNED_HI_OP
9037 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
9038 #undef TARGET_ASM_ALIGNED_DI_OP
9039 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
9040 #undef TARGET_ASM_INTEGER
9041 #define TARGET_ASM_INTEGER s390_assemble_integer
9043 #undef TARGET_ASM_OPEN_PAREN
9044 #define TARGET_ASM_OPEN_PAREN ""
9046 #undef TARGET_ASM_CLOSE_PAREN
9047 #define TARGET_ASM_CLOSE_PAREN ""
9049 #undef TARGET_DEFAULT_TARGET_FLAGS
9050 #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD)
9051 #undef TARGET_HANDLE_OPTION
9052 #define TARGET_HANDLE_OPTION s390_handle_option
9054 #undef TARGET_ENCODE_SECTION_INFO
9055 #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
9058 #undef TARGET_HAVE_TLS
9059 #define TARGET_HAVE_TLS true
9061 #undef TARGET_CANNOT_FORCE_CONST_MEM
9062 #define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
9064 #undef TARGET_DELEGITIMIZE_ADDRESS
9065 #define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
9067 #undef TARGET_RETURN_IN_MEMORY
9068 #define TARGET_RETURN_IN_MEMORY s390_return_in_memory
9070 #undef TARGET_INIT_BUILTINS
9071 #define TARGET_INIT_BUILTINS s390_init_builtins
9072 #undef TARGET_EXPAND_BUILTIN
9073 #define TARGET_EXPAND_BUILTIN s390_expand_builtin
9075 #undef TARGET_ASM_OUTPUT_MI_THUNK
9076 #define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
9077 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
9078 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
9080 #undef TARGET_SCHED_ADJUST_PRIORITY
9081 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
9082 #undef TARGET_SCHED_ISSUE_RATE
9083 #define TARGET_SCHED_ISSUE_RATE s390_issue_rate
9084 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
9085 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
9087 #undef TARGET_CANNOT_COPY_INSN_P
9088 #define TARGET_CANNOT_COPY_INSN_P s390_cannot_copy_insn_p
9089 #undef TARGET_RTX_COSTS
9090 #define TARGET_RTX_COSTS s390_rtx_costs
9091 #undef TARGET_ADDRESS_COST
9092 #define TARGET_ADDRESS_COST s390_address_cost
9094 #undef TARGET_MACHINE_DEPENDENT_REORG
9095 #define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
9097 #undef TARGET_VALID_POINTER_MODE
9098 #define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
9100 #undef TARGET_BUILD_BUILTIN_VA_LIST
9101 #define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
9102 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
9103 #define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg
9105 #undef TARGET_PROMOTE_FUNCTION_ARGS
9106 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
9107 #undef TARGET_PROMOTE_FUNCTION_RETURN
9108 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
9109 #undef TARGET_PASS_BY_REFERENCE
9110 #define TARGET_PASS_BY_REFERENCE s390_pass_by_reference
9112 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
9113 #define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
9115 #undef TARGET_FIXED_CONDITION_CODE_REGS
9116 #define TARGET_FIXED_CONDITION_CODE_REGS s390_fixed_condition_code_regs
9118 #undef TARGET_CC_MODES_COMPATIBLE
9119 #define TARGET_CC_MODES_COMPATIBLE s390_cc_modes_compatible
9121 #undef TARGET_INVALID_WITHIN_DOLOOP
9122 #define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_rtx_null
9125 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
9126 #define TARGET_ASM_OUTPUT_DWARF_DTPREL s390_output_dwarf_dtprel
9129 struct gcc_target targetm
= TARGET_INITIALIZER
;
9131 #include "gt-s390.h"