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 extern int reload_completed
;
159 /* The alias set for prologue/epilogue register save/restore. */
160 static int s390_sr_alias_set
= 0;
162 /* Save information from a "cmpxx" operation until the branch or scc is
164 rtx s390_compare_op0
, s390_compare_op1
;
166 /* Save the result of a compare_and_swap until the branch or scc is
168 rtx s390_compare_emitted
= NULL_RTX
;
170 /* Structure used to hold the components of a S/390 memory
171 address. A legitimate address on S/390 is of the general
173 base + index + displacement
174 where any of the components is optional.
176 base and index are registers of the class ADDR_REGS,
177 displacement is an unsigned 12-bit immediate constant. */
187 /* Which cpu are we tuning for. */
188 enum processor_type s390_tune
= PROCESSOR_max
;
189 enum processor_flags s390_tune_flags
;
190 /* Which instruction set architecture to use. */
191 enum processor_type s390_arch
;
192 enum processor_flags s390_arch_flags
;
194 HOST_WIDE_INT s390_warn_framesize
= 0;
195 HOST_WIDE_INT s390_stack_size
= 0;
196 HOST_WIDE_INT s390_stack_guard
= 0;
198 /* The following structure is embedded in the machine
199 specific part of struct function. */
201 struct s390_frame_layout
GTY (())
203 /* Offset within stack frame. */
204 HOST_WIDE_INT gprs_offset
;
205 HOST_WIDE_INT f0_offset
;
206 HOST_WIDE_INT f4_offset
;
207 HOST_WIDE_INT f8_offset
;
208 HOST_WIDE_INT backchain_offset
;
210 /* Number of first and last gpr to be saved, restored. */
212 int first_restore_gpr
;
214 int last_restore_gpr
;
216 /* Bits standing for floating point registers. Set, if the
217 respective register has to be saved. Starting with reg 16 (f0)
218 at the rightmost bit.
219 Bit 15 - 8 7 6 5 4 3 2 1 0
220 fpr 15 - 8 7 5 3 1 6 4 2 0
221 reg 31 - 24 23 22 21 20 19 18 17 16 */
222 unsigned int fpr_bitmap
;
224 /* Number of floating point registers f8-f15 which must be saved. */
227 /* Set if return address needs to be saved. */
228 bool save_return_addr_p
;
230 /* Size of stack frame. */
231 HOST_WIDE_INT frame_size
;
234 /* Define the structure for the machine field in struct function. */
236 struct machine_function
GTY(())
238 struct s390_frame_layout frame_layout
;
240 /* Literal pool base register. */
243 /* True if we may need to perform branch splitting. */
244 bool split_branches_pending_p
;
246 /* Some local-dynamic TLS symbol name. */
247 const char *some_ld_name
;
249 bool has_landing_pad_p
;
252 /* Few accessor macros for struct cfun->machine->s390_frame_layout. */
254 #define cfun_frame_layout (cfun->machine->frame_layout)
255 #define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)
256 #define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr - \
257 cfun_frame_layout.first_save_gpr + 1) * UNITS_PER_WORD)
258 #define cfun_set_fpr_bit(BITNUM) (cfun->machine->frame_layout.fpr_bitmap |= \
260 #define cfun_fpr_bit_p(BITNUM) (!!(cfun->machine->frame_layout.fpr_bitmap & \
263 /* Number of GPRs and FPRs used for argument passing. */
264 #define GP_ARG_NUM_REG 5
265 #define FP_ARG_NUM_REG (TARGET_64BIT? 4 : 2)
267 /* Set the has_landing_pad_p flag in struct machine_function to VALUE. */
270 s390_set_has_landing_pad_p (bool value
)
272 cfun
->machine
->has_landing_pad_p
= value
;
275 /* Return true if SET either doesn't set the CC register, or else
276 the source and destination have matching CC modes and that
277 CC mode is at least as constrained as REQ_MODE. */
280 s390_match_ccmode_set (rtx set
, enum machine_mode req_mode
)
282 enum machine_mode set_mode
;
284 gcc_assert (GET_CODE (set
) == SET
);
286 if (GET_CODE (SET_DEST (set
)) != REG
|| !CC_REGNO_P (REGNO (SET_DEST (set
))))
289 set_mode
= GET_MODE (SET_DEST (set
));
303 if (req_mode
!= set_mode
)
308 if (req_mode
!= CCSmode
&& req_mode
!= CCUmode
&& req_mode
!= CCTmode
309 && req_mode
!= CCSRmode
&& req_mode
!= CCURmode
)
315 if (req_mode
!= CCAmode
)
323 return (GET_MODE (SET_SRC (set
)) == set_mode
);
326 /* Return true if every SET in INSN that sets the CC register
327 has source and destination with matching CC modes and that
328 CC mode is at least as constrained as REQ_MODE.
329 If REQ_MODE is VOIDmode, always return false. */
332 s390_match_ccmode (rtx insn
, enum machine_mode req_mode
)
336 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
337 if (req_mode
== VOIDmode
)
340 if (GET_CODE (PATTERN (insn
)) == SET
)
341 return s390_match_ccmode_set (PATTERN (insn
), req_mode
);
343 if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
344 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
346 rtx set
= XVECEXP (PATTERN (insn
), 0, i
);
347 if (GET_CODE (set
) == SET
)
348 if (!s390_match_ccmode_set (set
, req_mode
))
355 /* If a test-under-mask instruction can be used to implement
356 (compare (and ... OP1) OP2), return the CC mode required
357 to do that. Otherwise, return VOIDmode.
358 MIXED is true if the instruction can distinguish between
359 CC1 and CC2 for mixed selected bits (TMxx), it is false
360 if the instruction cannot (TM). */
363 s390_tm_ccmode (rtx op1
, rtx op2
, bool mixed
)
367 /* ??? Fixme: should work on CONST_DOUBLE as well. */
368 if (GET_CODE (op1
) != CONST_INT
|| GET_CODE (op2
) != CONST_INT
)
371 /* Selected bits all zero: CC0.
372 e.g.: int a; if ((a & (16 + 128)) == 0) */
373 if (INTVAL (op2
) == 0)
376 /* Selected bits all one: CC3.
377 e.g.: int a; if ((a & (16 + 128)) == 16 + 128) */
378 if (INTVAL (op2
) == INTVAL (op1
))
381 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. e.g.:
383 if ((a & (16 + 128)) == 16) -> CCT1
384 if ((a & (16 + 128)) == 128) -> CCT2 */
387 bit1
= exact_log2 (INTVAL (op2
));
388 bit0
= exact_log2 (INTVAL (op1
) ^ INTVAL (op2
));
389 if (bit0
!= -1 && bit1
!= -1)
390 return bit0
> bit1
? CCT1mode
: CCT2mode
;
396 /* Given a comparison code OP (EQ, NE, etc.) and the operands
397 OP0 and OP1 of a COMPARE, return the mode to be used for the
401 s390_select_ccmode (enum rtx_code code
, rtx op0
, rtx op1
)
407 if ((GET_CODE (op0
) == NEG
|| GET_CODE (op0
) == ABS
)
408 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
410 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
411 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0
, 1)), 'K', "K"))
413 if ((GET_CODE (op0
) == PLUS
|| GET_CODE (op0
) == MINUS
414 || GET_CODE (op1
) == NEG
)
415 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
418 if (GET_CODE (op0
) == AND
)
420 /* Check whether we can potentially do it via TM. */
421 enum machine_mode ccmode
;
422 ccmode
= s390_tm_ccmode (XEXP (op0
, 1), op1
, 1);
423 if (ccmode
!= VOIDmode
)
425 /* Relax CCTmode to CCZmode to allow fall-back to AND
426 if that turns out to be beneficial. */
427 return ccmode
== CCTmode
? CCZmode
: ccmode
;
431 if (register_operand (op0
, HImode
)
432 && GET_CODE (op1
) == CONST_INT
433 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 65535))
435 if (register_operand (op0
, QImode
)
436 && GET_CODE (op1
) == CONST_INT
437 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 255))
446 /* The only overflow condition of NEG and ABS happens when
447 -INT_MAX is used as parameter, which stays negative. So
448 we have an overflow from a positive value to a negative.
449 Using CCAP mode the resulting cc can be used for comparisons. */
450 if ((GET_CODE (op0
) == NEG
|| GET_CODE (op0
) == ABS
)
451 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
454 /* If constants are involved in an add instruction it is possible to use
455 the resulting cc for comparisons with zero. Knowing the sign of the
456 constant the overflow behavior gets predictable. e.g.:
457 int a, b; if ((b = a + c) > 0)
458 with c as a constant value: c < 0 -> CCAN and c >= 0 -> CCAP */
459 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
460 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0
, 1)), 'K', "K"))
462 if (INTVAL (XEXP((op0
), 1)) < 0)
476 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
477 && GET_CODE (op1
) != CONST_INT
)
483 if (GET_CODE (op0
) == PLUS
484 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
487 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
488 && GET_CODE (op1
) != CONST_INT
)
494 if (GET_CODE (op0
) == MINUS
495 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
498 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
499 && GET_CODE (op1
) != CONST_INT
)
508 /* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
509 that we can implement more efficiently. */
512 s390_canonicalize_comparison (enum rtx_code
*code
, rtx
*op0
, rtx
*op1
)
514 /* Convert ZERO_EXTRACT back to AND to enable TM patterns. */
515 if ((*code
== EQ
|| *code
== NE
)
516 && *op1
== const0_rtx
517 && GET_CODE (*op0
) == ZERO_EXTRACT
518 && GET_CODE (XEXP (*op0
, 1)) == CONST_INT
519 && GET_CODE (XEXP (*op0
, 2)) == CONST_INT
520 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0
, 0))))
522 rtx inner
= XEXP (*op0
, 0);
523 HOST_WIDE_INT modesize
= GET_MODE_BITSIZE (GET_MODE (inner
));
524 HOST_WIDE_INT len
= INTVAL (XEXP (*op0
, 1));
525 HOST_WIDE_INT pos
= INTVAL (XEXP (*op0
, 2));
527 if (len
> 0 && len
< modesize
528 && pos
>= 0 && pos
+ len
<= modesize
529 && modesize
<= HOST_BITS_PER_WIDE_INT
)
531 unsigned HOST_WIDE_INT block
;
532 block
= ((unsigned HOST_WIDE_INT
) 1 << len
) - 1;
533 block
<<= modesize
- pos
- len
;
535 *op0
= gen_rtx_AND (GET_MODE (inner
), inner
,
536 gen_int_mode (block
, GET_MODE (inner
)));
540 /* Narrow AND of memory against immediate to enable TM. */
541 if ((*code
== EQ
|| *code
== NE
)
542 && *op1
== const0_rtx
543 && GET_CODE (*op0
) == AND
544 && GET_CODE (XEXP (*op0
, 1)) == CONST_INT
545 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0
, 0))))
547 rtx inner
= XEXP (*op0
, 0);
548 rtx mask
= XEXP (*op0
, 1);
550 /* Ignore paradoxical SUBREGs if all extra bits are masked out. */
551 if (GET_CODE (inner
) == SUBREG
552 && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (inner
)))
553 && (GET_MODE_SIZE (GET_MODE (inner
))
554 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner
))))
556 & GET_MODE_MASK (GET_MODE (inner
))
557 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (inner
))))
559 inner
= SUBREG_REG (inner
);
561 /* Do not change volatile MEMs. */
562 if (MEM_P (inner
) && !MEM_VOLATILE_P (inner
))
564 int part
= s390_single_part (XEXP (*op0
, 1),
565 GET_MODE (inner
), QImode
, 0);
568 mask
= gen_int_mode (s390_extract_part (mask
, QImode
, 0), QImode
);
569 inner
= adjust_address_nv (inner
, QImode
, part
);
570 *op0
= gen_rtx_AND (QImode
, inner
, mask
);
575 /* Narrow comparisons against 0xffff to HImode if possible. */
576 if ((*code
== EQ
|| *code
== NE
)
577 && GET_CODE (*op1
) == CONST_INT
578 && INTVAL (*op1
) == 0xffff
579 && SCALAR_INT_MODE_P (GET_MODE (*op0
))
580 && (nonzero_bits (*op0
, GET_MODE (*op0
))
581 & ~(unsigned HOST_WIDE_INT
) 0xffff) == 0)
583 *op0
= gen_lowpart (HImode
, *op0
);
588 /* Remove redundant UNSPEC_CMPINT conversions if possible. */
589 if (GET_CODE (*op0
) == UNSPEC
590 && XINT (*op0
, 1) == UNSPEC_CMPINT
591 && XVECLEN (*op0
, 0) == 1
592 && GET_MODE (XVECEXP (*op0
, 0, 0)) == CCUmode
593 && GET_CODE (XVECEXP (*op0
, 0, 0)) == REG
594 && REGNO (XVECEXP (*op0
, 0, 0)) == CC_REGNUM
595 && *op1
== const0_rtx
)
597 enum rtx_code new_code
= UNKNOWN
;
600 case EQ
: new_code
= EQ
; break;
601 case NE
: new_code
= NE
; break;
602 case LT
: new_code
= GTU
; break;
603 case GT
: new_code
= LTU
; break;
604 case LE
: new_code
= GEU
; break;
605 case GE
: new_code
= LEU
; break;
609 if (new_code
!= UNKNOWN
)
611 *op0
= XVECEXP (*op0
, 0, 0);
617 /* Emit a compare instruction suitable to implement the comparison
618 OP0 CODE OP1. Return the correct condition RTL to be placed in
619 the IF_THEN_ELSE of the conditional branch testing the result. */
622 s390_emit_compare (enum rtx_code code
, rtx op0
, rtx op1
)
624 enum machine_mode mode
= s390_select_ccmode (code
, op0
, op1
);
627 /* Do not output a redundant compare instruction if a compare_and_swap
628 pattern already computed the result and the machine modes match. */
629 if (s390_compare_emitted
&& GET_MODE (s390_compare_emitted
) == mode
)
630 ret
= gen_rtx_fmt_ee (code
, VOIDmode
, s390_compare_emitted
, const0_rtx
);
633 rtx cc
= gen_rtx_REG (mode
, CC_REGNUM
);
635 emit_insn (gen_rtx_SET (VOIDmode
, cc
, gen_rtx_COMPARE (mode
, op0
, op1
)));
636 ret
= gen_rtx_fmt_ee (code
, VOIDmode
, cc
, const0_rtx
);
638 s390_compare_emitted
= NULL_RTX
;
642 /* Emit a jump instruction to TARGET. If COND is NULL_RTX, emit an
643 unconditional jump, else a conditional jump under condition COND. */
646 s390_emit_jump (rtx target
, rtx cond
)
650 target
= gen_rtx_LABEL_REF (VOIDmode
, target
);
652 target
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, target
, pc_rtx
);
654 insn
= gen_rtx_SET (VOIDmode
, pc_rtx
, target
);
655 emit_jump_insn (insn
);
658 /* Return branch condition mask to implement a branch
659 specified by CODE. Return -1 for invalid comparisons. */
662 s390_branch_condition_mask (rtx code
)
664 const int CC0
= 1 << 3;
665 const int CC1
= 1 << 2;
666 const int CC2
= 1 << 1;
667 const int CC3
= 1 << 0;
669 gcc_assert (GET_CODE (XEXP (code
, 0)) == REG
);
670 gcc_assert (REGNO (XEXP (code
, 0)) == CC_REGNUM
);
671 gcc_assert (XEXP (code
, 1) == const0_rtx
);
673 switch (GET_MODE (XEXP (code
, 0)))
676 switch (GET_CODE (code
))
679 case NE
: return CC1
| CC2
| CC3
;
685 switch (GET_CODE (code
))
688 case NE
: return CC0
| CC2
| CC3
;
694 switch (GET_CODE (code
))
697 case NE
: return CC0
| CC1
| CC3
;
703 switch (GET_CODE (code
))
706 case NE
: return CC0
| CC1
| CC2
;
712 switch (GET_CODE (code
))
714 case EQ
: return CC0
| CC2
;
715 case NE
: return CC1
| CC3
;
721 switch (GET_CODE (code
))
723 case LTU
: return CC2
| CC3
; /* carry */
724 case GEU
: return CC0
| CC1
; /* no carry */
730 switch (GET_CODE (code
))
732 case GTU
: return CC0
| CC1
; /* borrow */
733 case LEU
: return CC2
| CC3
; /* no borrow */
739 switch (GET_CODE (code
))
741 case EQ
: return CC0
| CC2
;
742 case NE
: return CC1
| CC3
;
743 case LTU
: return CC1
;
744 case GTU
: return CC3
;
745 case LEU
: return CC1
| CC2
;
746 case GEU
: return CC2
| CC3
;
751 switch (GET_CODE (code
))
754 case NE
: return CC1
| CC2
| CC3
;
755 case LTU
: return CC1
;
756 case GTU
: return CC2
;
757 case LEU
: return CC0
| CC1
;
758 case GEU
: return CC0
| CC2
;
764 switch (GET_CODE (code
))
767 case NE
: return CC2
| CC1
| CC3
;
768 case LTU
: return CC2
;
769 case GTU
: return CC1
;
770 case LEU
: return CC0
| CC2
;
771 case GEU
: return CC0
| CC1
;
777 switch (GET_CODE (code
))
780 case NE
: return CC1
| CC2
| CC3
;
781 case LT
: return CC1
| CC3
;
783 case LE
: return CC0
| CC1
| CC3
;
784 case GE
: return CC0
| CC2
;
790 switch (GET_CODE (code
))
793 case NE
: return CC1
| CC2
| CC3
;
795 case GT
: return CC2
| CC3
;
796 case LE
: return CC0
| CC1
;
797 case GE
: return CC0
| CC2
| CC3
;
803 switch (GET_CODE (code
))
806 case NE
: return CC1
| CC2
| CC3
;
809 case LE
: return CC0
| CC1
;
810 case GE
: return CC0
| CC2
;
811 case UNORDERED
: return CC3
;
812 case ORDERED
: return CC0
| CC1
| CC2
;
813 case UNEQ
: return CC0
| CC3
;
814 case UNLT
: return CC1
| CC3
;
815 case UNGT
: return CC2
| CC3
;
816 case UNLE
: return CC0
| CC1
| CC3
;
817 case UNGE
: return CC0
| CC2
| CC3
;
818 case LTGT
: return CC1
| CC2
;
824 switch (GET_CODE (code
))
827 case NE
: return CC2
| CC1
| CC3
;
830 case LE
: return CC0
| CC2
;
831 case GE
: return CC0
| CC1
;
832 case UNORDERED
: return CC3
;
833 case ORDERED
: return CC0
| CC2
| CC1
;
834 case UNEQ
: return CC0
| CC3
;
835 case UNLT
: return CC2
| CC3
;
836 case UNGT
: return CC1
| CC3
;
837 case UNLE
: return CC0
| CC2
| CC3
;
838 case UNGE
: return CC0
| CC1
| CC3
;
839 case LTGT
: return CC2
| CC1
;
849 /* If INV is false, return assembler mnemonic string to implement
850 a branch specified by CODE. If INV is true, return mnemonic
851 for the corresponding inverted branch. */
854 s390_branch_condition_mnemonic (rtx code
, int inv
)
856 static const char *const mnemonic
[16] =
858 NULL
, "o", "h", "nle",
859 "l", "nhe", "lh", "ne",
860 "e", "nlh", "he", "nl",
861 "le", "nh", "no", NULL
864 int mask
= s390_branch_condition_mask (code
);
865 gcc_assert (mask
>= 0);
870 gcc_assert (mask
>= 1 && mask
<= 14);
872 return mnemonic
[mask
];
875 /* Return the part of op which has a value different from def.
876 The size of the part is determined by mode.
877 Use this function only if you already know that op really
878 contains such a part. */
880 unsigned HOST_WIDE_INT
881 s390_extract_part (rtx op
, enum machine_mode mode
, int def
)
883 unsigned HOST_WIDE_INT value
= 0;
884 int max_parts
= HOST_BITS_PER_WIDE_INT
/ GET_MODE_BITSIZE (mode
);
885 int part_bits
= GET_MODE_BITSIZE (mode
);
886 unsigned HOST_WIDE_INT part_mask
= (1 << part_bits
) - 1;
889 for (i
= 0; i
< max_parts
; i
++)
892 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
896 if ((value
& part_mask
) != (def
& part_mask
))
897 return value
& part_mask
;
903 /* If OP is an integer constant of mode MODE with exactly one
904 part of mode PART_MODE unequal to DEF, return the number of that
905 part. Otherwise, return -1. */
908 s390_single_part (rtx op
,
909 enum machine_mode mode
,
910 enum machine_mode part_mode
,
913 unsigned HOST_WIDE_INT value
= 0;
914 int n_parts
= GET_MODE_SIZE (mode
) / GET_MODE_SIZE (part_mode
);
915 unsigned HOST_WIDE_INT part_mask
= (1 << GET_MODE_BITSIZE (part_mode
)) - 1;
918 if (GET_CODE (op
) != CONST_INT
)
921 for (i
= 0; i
< n_parts
; i
++)
924 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
926 value
>>= GET_MODE_BITSIZE (part_mode
);
928 if ((value
& part_mask
) != (def
& part_mask
))
936 return part
== -1 ? -1 : n_parts
- 1 - part
;
939 /* Check whether we can (and want to) split a double-word
940 move in mode MODE from SRC to DST into two single-word
941 moves, moving the subword FIRST_SUBWORD first. */
944 s390_split_ok_p (rtx dst
, rtx src
, enum machine_mode mode
, int first_subword
)
946 /* Floating point registers cannot be split. */
947 if (FP_REG_P (src
) || FP_REG_P (dst
))
950 /* We don't need to split if operands are directly accessible. */
951 if (s_operand (src
, mode
) || s_operand (dst
, mode
))
954 /* Non-offsettable memory references cannot be split. */
955 if ((GET_CODE (src
) == MEM
&& !offsettable_memref_p (src
))
956 || (GET_CODE (dst
) == MEM
&& !offsettable_memref_p (dst
)))
959 /* Moving the first subword must not clobber a register
960 needed to move the second subword. */
961 if (register_operand (dst
, mode
))
963 rtx subreg
= operand_subword (dst
, first_subword
, 0, mode
);
964 if (reg_overlap_mentioned_p (subreg
, src
))
971 /* Check whether the address of memory reference MEM2 equals exactly
972 the address of memory reference MEM1 plus DELTA. Return true if
973 we can prove this to be the case, false otherwise. */
976 s390_offset_p (rtx mem1
, rtx mem2
, rtx delta
)
978 rtx addr1
, addr2
, addr_delta
;
980 if (GET_CODE (mem1
) != MEM
|| GET_CODE (mem2
) != MEM
)
983 addr1
= XEXP (mem1
, 0);
984 addr2
= XEXP (mem2
, 0);
986 addr_delta
= simplify_binary_operation (MINUS
, Pmode
, addr2
, addr1
);
987 if (!addr_delta
|| !rtx_equal_p (addr_delta
, delta
))
993 /* Expand logical operator CODE in mode MODE with operands OPERANDS. */
996 s390_expand_logical_operator (enum rtx_code code
, enum machine_mode mode
,
999 enum machine_mode wmode
= mode
;
1000 rtx dst
= operands
[0];
1001 rtx src1
= operands
[1];
1002 rtx src2
= operands
[2];
1005 /* If we cannot handle the operation directly, use a temp register. */
1006 if (!s390_logical_operator_ok_p (operands
))
1007 dst
= gen_reg_rtx (mode
);
1009 /* QImode and HImode patterns make sense only if we have a destination
1010 in memory. Otherwise perform the operation in SImode. */
1011 if ((mode
== QImode
|| mode
== HImode
) && GET_CODE (dst
) != MEM
)
1014 /* Widen operands if required. */
1017 if (GET_CODE (dst
) == SUBREG
1018 && (tem
= simplify_subreg (wmode
, dst
, mode
, 0)) != 0)
1020 else if (REG_P (dst
))
1021 dst
= gen_rtx_SUBREG (wmode
, dst
, 0);
1023 dst
= gen_reg_rtx (wmode
);
1025 if (GET_CODE (src1
) == SUBREG
1026 && (tem
= simplify_subreg (wmode
, src1
, mode
, 0)) != 0)
1028 else if (GET_MODE (src1
) != VOIDmode
)
1029 src1
= gen_rtx_SUBREG (wmode
, force_reg (mode
, src1
), 0);
1031 if (GET_CODE (src2
) == SUBREG
1032 && (tem
= simplify_subreg (wmode
, src2
, mode
, 0)) != 0)
1034 else if (GET_MODE (src2
) != VOIDmode
)
1035 src2
= gen_rtx_SUBREG (wmode
, force_reg (mode
, src2
), 0);
1038 /* Emit the instruction. */
1039 op
= gen_rtx_SET (VOIDmode
, dst
, gen_rtx_fmt_ee (code
, wmode
, src1
, src2
));
1040 clob
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
1041 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, op
, clob
)));
1043 /* Fix up the destination if needed. */
1044 if (dst
!= operands
[0])
1045 emit_move_insn (operands
[0], gen_lowpart (mode
, dst
));
1048 /* Check whether OPERANDS are OK for a logical operation (AND, IOR, XOR). */
1051 s390_logical_operator_ok_p (rtx
*operands
)
1053 /* If the destination operand is in memory, it needs to coincide
1054 with one of the source operands. After reload, it has to be
1055 the first source operand. */
1056 if (GET_CODE (operands
[0]) == MEM
)
1057 return rtx_equal_p (operands
[0], operands
[1])
1058 || (!reload_completed
&& rtx_equal_p (operands
[0], operands
[2]));
1063 /* Narrow logical operation CODE of memory operand MEMOP with immediate
1064 operand IMMOP to switch from SS to SI type instructions. */
1067 s390_narrow_logical_operator (enum rtx_code code
, rtx
*memop
, rtx
*immop
)
1069 int def
= code
== AND
? -1 : 0;
1073 gcc_assert (GET_CODE (*memop
) == MEM
);
1074 gcc_assert (!MEM_VOLATILE_P (*memop
));
1076 mask
= s390_extract_part (*immop
, QImode
, def
);
1077 part
= s390_single_part (*immop
, GET_MODE (*memop
), QImode
, def
);
1078 gcc_assert (part
>= 0);
1080 *memop
= adjust_address (*memop
, QImode
, part
);
1081 *immop
= gen_int_mode (mask
, QImode
);
1085 /* How to allocate a 'struct machine_function'. */
1087 static struct machine_function
*
1088 s390_init_machine_status (void)
1090 return ggc_alloc_cleared (sizeof (struct machine_function
));
1093 /* Change optimizations to be performed, depending on the
1096 LEVEL is the optimization level specified; 2 if `-O2' is
1097 specified, 1 if `-O' is specified, and 0 if neither is specified.
1099 SIZE is nonzero if `-Os' is specified and zero otherwise. */
1102 optimization_options (int level ATTRIBUTE_UNUSED
, int size ATTRIBUTE_UNUSED
)
1104 /* ??? There are apparently still problems with -fcaller-saves. */
1105 flag_caller_saves
= 0;
1107 /* By default, always emit DWARF-2 unwind info. This allows debugging
1108 without maintaining a stack frame back-chain. */
1109 flag_asynchronous_unwind_tables
= 1;
1112 /* Return true if ARG is the name of a processor. Set *TYPE and *FLAGS
1113 to the associated processor_type and processor_flags if so. */
1116 s390_handle_arch_option (const char *arg
,
1117 enum processor_type
*type
,
1118 enum processor_flags
*flags
)
1122 const char *const name
; /* processor name or nickname. */
1123 const enum processor_type processor
;
1124 const enum processor_flags flags
;
1126 const processor_alias_table
[] =
1128 {"g5", PROCESSOR_9672_G5
, PF_IEEE_FLOAT
},
1129 {"g6", PROCESSOR_9672_G6
, PF_IEEE_FLOAT
},
1130 {"z900", PROCESSOR_2064_Z900
, PF_IEEE_FLOAT
| PF_ZARCH
},
1131 {"z990", PROCESSOR_2084_Z990
, PF_IEEE_FLOAT
| PF_ZARCH
1132 | PF_LONG_DISPLACEMENT
},
1136 for (i
= 0; i
< ARRAY_SIZE (processor_alias_table
); i
++)
1137 if (strcmp (arg
, processor_alias_table
[i
].name
) == 0)
1139 *type
= processor_alias_table
[i
].processor
;
1140 *flags
= processor_alias_table
[i
].flags
;
1146 /* Implement TARGET_HANDLE_OPTION. */
1149 s390_handle_option (size_t code
, const char *arg
, int value ATTRIBUTE_UNUSED
)
1154 return s390_handle_arch_option (arg
, &s390_arch
, &s390_arch_flags
);
1156 case OPT_mstack_guard_
:
1157 if (sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_stack_guard
) != 1)
1159 if (exact_log2 (s390_stack_guard
) == -1)
1160 error ("stack guard value must be an exact power of 2");
1163 case OPT_mstack_size_
:
1164 if (sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_stack_size
) != 1)
1166 if (exact_log2 (s390_stack_size
) == -1)
1167 error ("stack size must be an exact power of 2");
1171 return s390_handle_arch_option (arg
, &s390_tune
, &s390_tune_flags
);
1173 case OPT_mwarn_framesize_
:
1174 return sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_warn_framesize
) == 1;
1182 override_options (void)
1184 /* Acquire a unique set number for our register saves and restores. */
1185 s390_sr_alias_set
= new_alias_set ();
1187 /* Set up function hooks. */
1188 init_machine_status
= s390_init_machine_status
;
1190 /* Architecture mode defaults according to ABI. */
1191 if (!(target_flags_explicit
& MASK_ZARCH
))
1194 target_flags
|= MASK_ZARCH
;
1196 target_flags
&= ~MASK_ZARCH
;
1199 /* Determine processor architectural level. */
1200 if (!s390_arch_string
)
1202 s390_arch_string
= TARGET_ZARCH
? "z900" : "g5";
1203 s390_handle_arch_option (s390_arch_string
, &s390_arch
, &s390_arch_flags
);
1206 /* Determine processor to tune for. */
1207 if (s390_tune
== PROCESSOR_max
)
1209 s390_tune
= s390_arch
;
1210 s390_tune_flags
= s390_arch_flags
;
1213 /* Sanity checks. */
1214 if (TARGET_ZARCH
&& !(s390_arch_flags
& PF_ZARCH
))
1215 error ("z/Architecture mode not supported on %s.", s390_arch_string
);
1216 if (TARGET_64BIT
&& !TARGET_ZARCH
)
1217 error ("64-bit ABI not supported in ESA/390 mode.");
1220 /* Set processor cost function. */
1221 if (s390_tune
== PROCESSOR_2084_Z990
)
1222 s390_cost
= &z990_cost
;
1224 s390_cost
= &z900_cost
;
1227 if (TARGET_BACKCHAIN
&& TARGET_PACKED_STACK
&& TARGET_HARD_FLOAT
)
1228 error ("-mbackchain -mpacked-stack -mhard-float are not supported "
1231 if (s390_stack_size
)
1233 if (!s390_stack_guard
)
1234 error ("-mstack-size implies use of -mstack-guard");
1235 else if (s390_stack_guard
>= s390_stack_size
)
1236 error ("stack size must be greater than the stack guard value");
1238 else if (s390_stack_guard
)
1239 error ("-mstack-guard implies use of -mstack-size");
1242 /* Map for smallest class containing reg regno. */
1244 const enum reg_class regclass_map
[FIRST_PSEUDO_REGISTER
] =
1245 { GENERAL_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1246 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1247 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1248 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1249 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1250 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1251 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1252 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1253 ADDR_REGS
, CC_REGS
, ADDR_REGS
, ADDR_REGS
,
1254 ACCESS_REGS
, ACCESS_REGS
1257 /* Return attribute type of insn. */
1259 static enum attr_type
1260 s390_safe_attr_type (rtx insn
)
1262 if (recog_memoized (insn
) >= 0)
1263 return get_attr_type (insn
);
1268 /* Return true if DISP is a valid short displacement. */
1271 s390_short_displacement (rtx disp
)
1273 /* No displacement is OK. */
1277 /* Integer displacement in range. */
1278 if (GET_CODE (disp
) == CONST_INT
)
1279 return INTVAL (disp
) >= 0 && INTVAL (disp
) < 4096;
1281 /* GOT offset is not OK, the GOT can be large. */
1282 if (GET_CODE (disp
) == CONST
1283 && GET_CODE (XEXP (disp
, 0)) == UNSPEC
1284 && (XINT (XEXP (disp
, 0), 1) == UNSPEC_GOT
1285 || XINT (XEXP (disp
, 0), 1) == UNSPEC_GOTNTPOFF
))
1288 /* All other symbolic constants are literal pool references,
1289 which are OK as the literal pool must be small. */
1290 if (GET_CODE (disp
) == CONST
)
1296 /* Decompose a RTL expression ADDR for a memory address into
1297 its components, returned in OUT.
1299 Returns false if ADDR is not a valid memory address, true
1300 otherwise. If OUT is NULL, don't return the components,
1301 but check for validity only.
1303 Note: Only addresses in canonical form are recognized.
1304 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
1305 canonical form so that they will be recognized. */
1308 s390_decompose_address (rtx addr
, struct s390_address
*out
)
1310 HOST_WIDE_INT offset
= 0;
1311 rtx base
= NULL_RTX
;
1312 rtx indx
= NULL_RTX
;
1313 rtx disp
= NULL_RTX
;
1315 bool pointer
= false;
1316 bool base_ptr
= false;
1317 bool indx_ptr
= false;
1319 /* Decompose address into base + index + displacement. */
1321 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == UNSPEC
)
1324 else if (GET_CODE (addr
) == PLUS
)
1326 rtx op0
= XEXP (addr
, 0);
1327 rtx op1
= XEXP (addr
, 1);
1328 enum rtx_code code0
= GET_CODE (op0
);
1329 enum rtx_code code1
= GET_CODE (op1
);
1331 if (code0
== REG
|| code0
== UNSPEC
)
1333 if (code1
== REG
|| code1
== UNSPEC
)
1335 indx
= op0
; /* index + base */
1341 base
= op0
; /* base + displacement */
1346 else if (code0
== PLUS
)
1348 indx
= XEXP (op0
, 0); /* index + base + disp */
1349 base
= XEXP (op0
, 1);
1360 disp
= addr
; /* displacement */
1362 /* Extract integer part of displacement. */
1366 if (GET_CODE (disp
) == CONST_INT
)
1368 offset
= INTVAL (disp
);
1371 else if (GET_CODE (disp
) == CONST
1372 && GET_CODE (XEXP (disp
, 0)) == PLUS
1373 && GET_CODE (XEXP (XEXP (disp
, 0), 1)) == CONST_INT
)
1375 offset
= INTVAL (XEXP (XEXP (disp
, 0), 1));
1376 disp
= XEXP (XEXP (disp
, 0), 0);
1380 /* Strip off CONST here to avoid special case tests later. */
1381 if (disp
&& GET_CODE (disp
) == CONST
)
1382 disp
= XEXP (disp
, 0);
1384 /* We can convert literal pool addresses to
1385 displacements by basing them off the base register. */
1386 if (disp
&& GET_CODE (disp
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (disp
))
1388 /* Either base or index must be free to hold the base register. */
1390 base
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1392 indx
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1396 /* Mark up the displacement. */
1397 disp
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, disp
),
1398 UNSPEC_LTREL_OFFSET
);
1401 /* Validate base register. */
1404 if (GET_CODE (base
) == UNSPEC
)
1405 switch (XINT (base
, 1))
1409 disp
= gen_rtx_UNSPEC (Pmode
,
1410 gen_rtvec (1, XVECEXP (base
, 0, 0)),
1411 UNSPEC_LTREL_OFFSET
);
1415 base
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1418 case UNSPEC_LTREL_BASE
:
1419 base
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1426 if (GET_CODE (base
) != REG
|| GET_MODE (base
) != Pmode
)
1429 if (REGNO (base
) == BASE_REGNUM
1430 || REGNO (base
) == STACK_POINTER_REGNUM
1431 || REGNO (base
) == FRAME_POINTER_REGNUM
1432 || ((reload_completed
|| reload_in_progress
)
1433 && frame_pointer_needed
1434 && REGNO (base
) == HARD_FRAME_POINTER_REGNUM
)
1435 || REGNO (base
) == ARG_POINTER_REGNUM
1437 && REGNO (base
) == PIC_OFFSET_TABLE_REGNUM
))
1438 pointer
= base_ptr
= true;
1441 /* Validate index register. */
1444 if (GET_CODE (indx
) == UNSPEC
)
1445 switch (XINT (indx
, 1))
1449 disp
= gen_rtx_UNSPEC (Pmode
,
1450 gen_rtvec (1, XVECEXP (indx
, 0, 0)),
1451 UNSPEC_LTREL_OFFSET
);
1455 indx
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1458 case UNSPEC_LTREL_BASE
:
1459 indx
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1466 if (GET_CODE (indx
) != REG
|| GET_MODE (indx
) != Pmode
)
1469 if (REGNO (indx
) == BASE_REGNUM
1470 || REGNO (indx
) == STACK_POINTER_REGNUM
1471 || REGNO (indx
) == FRAME_POINTER_REGNUM
1472 || ((reload_completed
|| reload_in_progress
)
1473 && frame_pointer_needed
1474 && REGNO (indx
) == HARD_FRAME_POINTER_REGNUM
)
1475 || REGNO (indx
) == ARG_POINTER_REGNUM
1477 && REGNO (indx
) == PIC_OFFSET_TABLE_REGNUM
))
1478 pointer
= indx_ptr
= true;
1481 /* Prefer to use pointer as base, not index. */
1482 if (base
&& indx
&& !base_ptr
1483 && (indx_ptr
|| (!REG_POINTER (base
) && REG_POINTER (indx
))))
1490 /* Validate displacement. */
1493 /* If virtual registers are involved, the displacement will change later
1494 anyway as the virtual registers get eliminated. This could make a
1495 valid displacement invalid, but it is more likely to make an invalid
1496 displacement valid, because we sometimes access the register save area
1497 via negative offsets to one of those registers.
1498 Thus we don't check the displacement for validity here. If after
1499 elimination the displacement turns out to be invalid after all,
1500 this is fixed up by reload in any case. */
1501 if (base
!= arg_pointer_rtx
1502 && indx
!= arg_pointer_rtx
1503 && base
!= return_address_pointer_rtx
1504 && indx
!= return_address_pointer_rtx
1505 && base
!= frame_pointer_rtx
1506 && indx
!= frame_pointer_rtx
1507 && base
!= virtual_stack_vars_rtx
1508 && indx
!= virtual_stack_vars_rtx
)
1509 if (!DISP_IN_RANGE (offset
))
1514 /* All the special cases are pointers. */
1517 /* In the small-PIC case, the linker converts @GOT
1518 and @GOTNTPOFF offsets to possible displacements. */
1519 if (GET_CODE (disp
) == UNSPEC
1520 && (XINT (disp
, 1) == UNSPEC_GOT
1521 || XINT (disp
, 1) == UNSPEC_GOTNTPOFF
)
1528 /* Accept chunkified literal pool symbol references. */
1529 else if (GET_CODE (disp
) == MINUS
1530 && GET_CODE (XEXP (disp
, 0)) == LABEL_REF
1531 && GET_CODE (XEXP (disp
, 1)) == LABEL_REF
)
1536 /* Accept literal pool references. */
1537 else if (GET_CODE (disp
) == UNSPEC
1538 && XINT (disp
, 1) == UNSPEC_LTREL_OFFSET
)
1540 orig_disp
= gen_rtx_CONST (Pmode
, disp
);
1543 /* If we have an offset, make sure it does not
1544 exceed the size of the constant pool entry. */
1545 rtx sym
= XVECEXP (disp
, 0, 0);
1546 if (offset
>= GET_MODE_SIZE (get_pool_mode (sym
)))
1549 orig_disp
= plus_constant (orig_disp
, offset
);
1564 out
->disp
= orig_disp
;
1565 out
->pointer
= pointer
;
1571 /* Return true if CODE is a valid address without index. */
1574 s390_legitimate_address_without_index_p (rtx op
)
1576 struct s390_address addr
;
1578 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1586 /* Return 1 if OP is a valid operand for a C constraint, 0 else. */
1589 s390_extra_constraint_str (rtx op
, int c
, const char * str
)
1591 struct s390_address addr
;
1593 gcc_assert (c
== str
[0]);
1595 /* Check for offsettable variants of memory constraints. */
1598 /* Only accept non-volatile MEMs. */
1599 if (!MEM_P (op
) || MEM_VOLATILE_P (op
))
1602 if ((reload_completed
|| reload_in_progress
)
1603 ? !offsettable_memref_p (op
)
1604 : !offsettable_nonstrict_memref_p (op
))
1610 /* Check for non-literal-pool variants of memory constraints. */
1613 if (GET_CODE (op
) != MEM
)
1615 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1617 if (addr
.base
&& REG_P (addr
.base
) && REGNO (addr
.base
) == BASE_REGNUM
)
1619 if (addr
.indx
&& REG_P (addr
.indx
) && REGNO (addr
.indx
) == BASE_REGNUM
)
1628 if (GET_CODE (op
) != MEM
)
1630 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1635 if (TARGET_LONG_DISPLACEMENT
)
1637 if (!s390_short_displacement (addr
.disp
))
1643 if (GET_CODE (op
) != MEM
)
1646 if (TARGET_LONG_DISPLACEMENT
)
1648 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1650 if (!s390_short_displacement (addr
.disp
))
1656 if (!TARGET_LONG_DISPLACEMENT
)
1658 if (GET_CODE (op
) != MEM
)
1660 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1664 if (s390_short_displacement (addr
.disp
))
1669 if (!TARGET_LONG_DISPLACEMENT
)
1671 if (GET_CODE (op
) != MEM
)
1673 /* Any invalid address here will be fixed up by reload,
1674 so accept it for the most generic constraint. */
1675 if (s390_decompose_address (XEXP (op
, 0), &addr
)
1676 && s390_short_displacement (addr
.disp
))
1681 if (TARGET_LONG_DISPLACEMENT
)
1683 if (!s390_decompose_address (op
, &addr
))
1685 if (!s390_short_displacement (addr
.disp
))
1691 if (!TARGET_LONG_DISPLACEMENT
)
1693 /* Any invalid address here will be fixed up by reload,
1694 so accept it for the most generic constraint. */
1695 if (s390_decompose_address (op
, &addr
)
1696 && s390_short_displacement (addr
.disp
))
1701 return shift_count_operand (op
, VOIDmode
);
1710 /* Return true if VALUE matches the constraint STR. */
1713 s390_const_double_ok_for_constraint_p (rtx value
,
1717 gcc_assert (c
== str
[0]);
1722 /* The floating point zero constant. */
1723 return (GET_MODE_CLASS (GET_MODE (value
)) == MODE_FLOAT
1724 && value
== CONST0_RTX (GET_MODE (value
)));
1731 /* Return true if VALUE matches the constraint STR. */
1734 s390_const_ok_for_constraint_p (HOST_WIDE_INT value
,
1738 enum machine_mode mode
, part_mode
;
1740 int part
, part_goal
;
1742 gcc_assert (c
== str
[0]);
1747 return (unsigned int)value
< 256;
1750 return (unsigned int)value
< 4096;
1753 return value
>= -32768 && value
< 32768;
1756 return (TARGET_LONG_DISPLACEMENT
?
1757 (value
>= -524288 && value
<= 524287)
1758 : (value
>= 0 && value
<= 4095));
1760 return value
== 2147483647;
1766 part_goal
= str
[1] - '0';
1770 case 'H': part_mode
= HImode
; break;
1771 case 'Q': part_mode
= QImode
; break;
1777 case 'H': mode
= HImode
; break;
1778 case 'S': mode
= SImode
; break;
1779 case 'D': mode
= DImode
; break;
1785 case '0': def
= 0; break;
1786 case 'F': def
= -1; break;
1790 if (GET_MODE_SIZE (mode
) <= GET_MODE_SIZE (part_mode
))
1793 part
= s390_single_part (GEN_INT (value
), mode
, part_mode
, def
);
1796 if (part_goal
!= -1 && part_goal
!= part
)
1808 /* Compute a (partial) cost for rtx X. Return true if the complete
1809 cost has been computed, and false if subexpressions should be
1810 scanned. In either case, *TOTAL contains the cost result.
1811 CODE contains GET_CODE (x), OUTER_CODE contains the code
1812 of the superexpression of x. */
1815 s390_rtx_costs (rtx x
, int code
, int outer_code
, int *total
)
1838 *total
= COSTS_N_INSNS (1);
1843 /* Check for multiply and add. */
1844 if ((GET_MODE (x
) == DFmode
|| GET_MODE (x
) == SFmode
)
1845 && GET_CODE (XEXP (x
, 0)) == MULT
1846 && TARGET_HARD_FLOAT
&& TARGET_IEEE_FLOAT
&& TARGET_FUSED_MADD
)
1848 /* This is the multiply and add case. */
1849 if (GET_MODE (x
) == DFmode
)
1850 *total
= s390_cost
->madbr
;
1852 *total
= s390_cost
->maebr
;
1853 *total
+= rtx_cost (XEXP (XEXP (x
, 0), 0), MULT
)
1854 + rtx_cost (XEXP (XEXP (x
, 0), 1), MULT
)
1855 + rtx_cost (XEXP (x
, 1), code
);
1856 return true; /* Do not do an additional recursive descent. */
1858 *total
= COSTS_N_INSNS (1);
1862 switch (GET_MODE (x
))
1866 rtx left
= XEXP (x
, 0);
1867 rtx right
= XEXP (x
, 1);
1868 if (GET_CODE (right
) == CONST_INT
1869 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (right
), 'K', "K"))
1870 *total
= s390_cost
->mhi
;
1871 else if (GET_CODE (left
) == SIGN_EXTEND
)
1872 *total
= s390_cost
->mh
;
1874 *total
= s390_cost
->ms
; /* msr, ms, msy */
1879 rtx left
= XEXP (x
, 0);
1880 rtx right
= XEXP (x
, 1);
1883 if (GET_CODE (right
) == CONST_INT
1884 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (right
), 'K', "K"))
1885 *total
= s390_cost
->mghi
;
1886 else if (GET_CODE (left
) == SIGN_EXTEND
)
1887 *total
= s390_cost
->msgf
;
1889 *total
= s390_cost
->msg
; /* msgr, msg */
1891 else /* TARGET_31BIT */
1893 if (GET_CODE (left
) == SIGN_EXTEND
1894 && GET_CODE (right
) == SIGN_EXTEND
)
1895 /* mulsidi case: mr, m */
1896 *total
= s390_cost
->m
;
1897 else if (GET_CODE (left
) == ZERO_EXTEND
1898 && GET_CODE (right
) == ZERO_EXTEND
1899 && TARGET_CPU_ZARCH
)
1900 /* umulsidi case: ml, mlr */
1901 *total
= s390_cost
->ml
;
1903 /* Complex calculation is required. */
1904 *total
= COSTS_N_INSNS (40);
1910 *total
= s390_cost
->mult_df
;
1919 if (GET_MODE (x
) == TImode
) /* 128 bit division */
1920 *total
= s390_cost
->dlgr
;
1921 else if (GET_MODE (x
) == DImode
)
1923 rtx right
= XEXP (x
, 1);
1924 if (GET_CODE (right
) == ZERO_EXTEND
) /* 64 by 32 bit division */
1925 *total
= s390_cost
->dlr
;
1926 else /* 64 by 64 bit division */
1927 *total
= s390_cost
->dlgr
;
1929 else if (GET_MODE (x
) == SImode
) /* 32 bit division */
1930 *total
= s390_cost
->dlr
;
1935 if (GET_MODE (x
) == DImode
)
1937 rtx right
= XEXP (x
, 1);
1938 if (GET_CODE (right
) == ZERO_EXTEND
) /* 64 by 32 bit division */
1940 *total
= s390_cost
->dsgfr
;
1942 *total
= s390_cost
->dr
;
1943 else /* 64 by 64 bit division */
1944 *total
= s390_cost
->dsgr
;
1946 else if (GET_MODE (x
) == SImode
) /* 32 bit division */
1947 *total
= s390_cost
->dlr
;
1948 else if (GET_MODE (x
) == SFmode
)
1950 if (TARGET_IEEE_FLOAT
)
1951 *total
= s390_cost
->debr
;
1952 else /* TARGET_IBM_FLOAT */
1953 *total
= s390_cost
->der
;
1955 else if (GET_MODE (x
) == DFmode
)
1957 if (TARGET_IEEE_FLOAT
)
1958 *total
= s390_cost
->ddbr
;
1959 else /* TARGET_IBM_FLOAT */
1960 *total
= s390_cost
->ddr
;
1965 if (GET_MODE (x
) == SFmode
)
1966 *total
= s390_cost
->sqebr
;
1968 *total
= s390_cost
->sqdbr
;
1973 if (outer_code
== MULT
|| outer_code
== DIV
|| outer_code
== MOD
1974 || outer_code
== PLUS
|| outer_code
== MINUS
1975 || outer_code
== COMPARE
)
1980 *total
= COSTS_N_INSNS (1);
1981 if (GET_CODE (XEXP (x
, 0)) == AND
1982 && GET_CODE (XEXP (x
, 1)) == CONST_INT
1983 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
)
1985 rtx op0
= XEXP (XEXP (x
, 0), 0);
1986 rtx op1
= XEXP (XEXP (x
, 0), 1);
1987 rtx op2
= XEXP (x
, 1);
1989 if (memory_operand (op0
, GET_MODE (op0
))
1990 && s390_tm_ccmode (op1
, op2
, 0) != VOIDmode
)
1992 if (register_operand (op0
, GET_MODE (op0
))
1993 && s390_tm_ccmode (op1
, op2
, 1) != VOIDmode
)
2003 /* Return the cost of an address rtx ADDR. */
2006 s390_address_cost (rtx addr
)
2008 struct s390_address ad
;
2009 if (!s390_decompose_address (addr
, &ad
))
2012 return ad
.indx
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
2015 /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
2016 otherwise return 0. */
2019 tls_symbolic_operand (rtx op
)
2021 if (GET_CODE (op
) != SYMBOL_REF
)
2023 return SYMBOL_REF_TLS_MODEL (op
);
2026 /* Split DImode access register reference REG (on 64-bit) into its constituent
2027 low and high parts, and store them into LO and HI. Note that gen_lowpart/
2028 gen_highpart cannot be used as they assume all registers are word-sized,
2029 while our access registers have only half that size. */
2032 s390_split_access_reg (rtx reg
, rtx
*lo
, rtx
*hi
)
2034 gcc_assert (TARGET_64BIT
);
2035 gcc_assert (ACCESS_REG_P (reg
));
2036 gcc_assert (GET_MODE (reg
) == DImode
);
2037 gcc_assert (!(REGNO (reg
) & 1));
2039 *lo
= gen_rtx_REG (SImode
, REGNO (reg
) + 1);
2040 *hi
= gen_rtx_REG (SImode
, REGNO (reg
));
2043 /* Return true if OP contains a symbol reference */
2046 symbolic_reference_mentioned_p (rtx op
)
2051 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
2054 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
2055 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
2061 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
2062 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
2066 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
2073 /* Return true if OP contains a reference to a thread-local symbol. */
2076 tls_symbolic_reference_mentioned_p (rtx op
)
2081 if (GET_CODE (op
) == SYMBOL_REF
)
2082 return tls_symbolic_operand (op
);
2084 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
2085 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
2091 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
2092 if (tls_symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
2096 else if (fmt
[i
] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op
, i
)))
2104 /* Return true if OP is a legitimate general operand when
2105 generating PIC code. It is given that flag_pic is on
2106 and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2109 legitimate_pic_operand_p (rtx op
)
2111 /* Accept all non-symbolic constants. */
2112 if (!SYMBOLIC_CONST (op
))
2115 /* Reject everything else; must be handled
2116 via emit_symbolic_move. */
2120 /* Returns true if the constant value OP is a legitimate general operand.
2121 It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2124 legitimate_constant_p (rtx op
)
2126 /* Accept all non-symbolic constants. */
2127 if (!SYMBOLIC_CONST (op
))
2130 /* Accept immediate LARL operands. */
2131 if (TARGET_CPU_ZARCH
&& larl_operand (op
, VOIDmode
))
2134 /* Thread-local symbols are never legal constants. This is
2135 so that emit_call knows that computing such addresses
2136 might require a function call. */
2137 if (TLS_SYMBOLIC_CONST (op
))
2140 /* In the PIC case, symbolic constants must *not* be
2141 forced into the literal pool. We accept them here,
2142 so that they will be handled by emit_symbolic_move. */
2146 /* All remaining non-PIC symbolic constants are
2147 forced into the literal pool. */
2151 /* Determine if it's legal to put X into the constant pool. This
2152 is not possible if X contains the address of a symbol that is
2153 not constant (TLS) or not known at final link time (PIC). */
2156 s390_cannot_force_const_mem (rtx x
)
2158 switch (GET_CODE (x
))
2162 /* Accept all non-symbolic constants. */
2166 /* Labels are OK iff we are non-PIC. */
2167 return flag_pic
!= 0;
2170 /* 'Naked' TLS symbol references are never OK,
2171 non-TLS symbols are OK iff we are non-PIC. */
2172 if (tls_symbolic_operand (x
))
2175 return flag_pic
!= 0;
2178 return s390_cannot_force_const_mem (XEXP (x
, 0));
2181 return s390_cannot_force_const_mem (XEXP (x
, 0))
2182 || s390_cannot_force_const_mem (XEXP (x
, 1));
2185 switch (XINT (x
, 1))
2187 /* Only lt-relative or GOT-relative UNSPECs are OK. */
2188 case UNSPEC_LTREL_OFFSET
:
2196 case UNSPEC_GOTNTPOFF
:
2197 case UNSPEC_INDNTPOFF
:
2200 /* If the literal pool shares the code section, be put
2201 execute template placeholders into the pool as well. */
2203 return TARGET_CPU_ZARCH
;
2215 /* Returns true if the constant value OP is a legitimate general
2216 operand during and after reload. The difference to
2217 legitimate_constant_p is that this function will not accept
2218 a constant that would need to be forced to the literal pool
2219 before it can be used as operand. */
2222 legitimate_reload_constant_p (rtx op
)
2224 /* Accept la(y) operands. */
2225 if (GET_CODE (op
) == CONST_INT
2226 && DISP_IN_RANGE (INTVAL (op
)))
2229 /* Accept l(g)hi operands. */
2230 if (GET_CODE (op
) == CONST_INT
2231 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op
), 'K', "K"))
2234 /* Accept lliXX operands. */
2236 && s390_single_part (op
, DImode
, HImode
, 0) >= 0)
2239 /* Accept larl operands. */
2240 if (TARGET_CPU_ZARCH
2241 && larl_operand (op
, VOIDmode
))
2244 /* Accept lzXX operands. */
2245 if (GET_CODE (op
) == CONST_DOUBLE
2246 && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op
, 'G', "G"))
2249 /* Everything else cannot be handled without reload. */
2253 /* Given an rtx OP being reloaded into a reg required to be in class CLASS,
2254 return the class of reg to actually use. */
2257 s390_preferred_reload_class (rtx op
, enum reg_class
class)
2259 switch (GET_CODE (op
))
2261 /* Constants we cannot reload must be forced into the
2266 if (legitimate_reload_constant_p (op
))
2271 /* If a symbolic constant or a PLUS is reloaded,
2272 it is most likely being used as an address, so
2273 prefer ADDR_REGS. If 'class' is not a superset
2274 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
2279 if (reg_class_subset_p (ADDR_REGS
, class))
2291 /* Return the register class of a scratch register needed to
2292 load IN into a register of class CLASS in MODE.
2294 We need a temporary when loading a PLUS expression which
2295 is not a legitimate operand of the LOAD ADDRESS instruction. */
2298 s390_secondary_input_reload_class (enum reg_class
class,
2299 enum machine_mode mode
, rtx in
)
2301 if (s390_plus_operand (in
, mode
))
2304 if (reg_classes_intersect_p (CC_REGS
, class))
2305 return GENERAL_REGS
;
2310 /* Return the register class of a scratch register needed to
2311 store a register of class CLASS in MODE into OUT:
2313 We need a temporary when storing a double-word to a
2314 non-offsettable memory address. */
2317 s390_secondary_output_reload_class (enum reg_class
class,
2318 enum machine_mode mode
, rtx out
)
2320 if ((TARGET_64BIT
? mode
== TImode
2321 : (mode
== DImode
|| mode
== DFmode
))
2322 && reg_classes_intersect_p (GENERAL_REGS
, class)
2323 && GET_CODE (out
) == MEM
2324 && GET_CODE (XEXP (out
, 0)) == PLUS
2325 && GET_CODE (XEXP (XEXP (out
, 0), 0)) == PLUS
2326 && GET_CODE (XEXP (XEXP (out
, 0), 1)) == CONST_INT
2327 && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (out
, 0), 1))
2328 + GET_MODE_SIZE (mode
) - 1))
2331 if (reg_classes_intersect_p (CC_REGS
, class))
2332 return GENERAL_REGS
;
2337 /* Generate code to load SRC, which is PLUS that is not a
2338 legitimate operand for the LA instruction, into TARGET.
2339 SCRATCH may be used as scratch register. */
2342 s390_expand_plus_operand (rtx target
, rtx src
,
2346 struct s390_address ad
;
2348 /* src must be a PLUS; get its two operands. */
2349 gcc_assert (GET_CODE (src
) == PLUS
);
2350 gcc_assert (GET_MODE (src
) == Pmode
);
2352 /* Check if any of the two operands is already scheduled
2353 for replacement by reload. This can happen e.g. when
2354 float registers occur in an address. */
2355 sum1
= find_replacement (&XEXP (src
, 0));
2356 sum2
= find_replacement (&XEXP (src
, 1));
2357 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
2359 /* If the address is already strictly valid, there's nothing to do. */
2360 if (!s390_decompose_address (src
, &ad
)
2361 || (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
2362 || (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
)))
2364 /* Otherwise, one of the operands cannot be an address register;
2365 we reload its value into the scratch register. */
2366 if (true_regnum (sum1
) < 1 || true_regnum (sum1
) > 15)
2368 emit_move_insn (scratch
, sum1
);
2371 if (true_regnum (sum2
) < 1 || true_regnum (sum2
) > 15)
2373 emit_move_insn (scratch
, sum2
);
2377 /* According to the way these invalid addresses are generated
2378 in reload.c, it should never happen (at least on s390) that
2379 *neither* of the PLUS components, after find_replacements
2380 was applied, is an address register. */
2381 if (sum1
== scratch
&& sum2
== scratch
)
2387 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
2390 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
2391 is only ever performed on addresses, so we can mark the
2392 sum as legitimate for LA in any case. */
2393 s390_load_address (target
, src
);
2397 /* Return true if ADDR is a valid memory address.
2398 STRICT specifies whether strict register checking applies. */
2401 legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED
,
2402 rtx addr
, int strict
)
2404 struct s390_address ad
;
2405 if (!s390_decompose_address (addr
, &ad
))
2410 if (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
2412 if (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
))
2417 if (ad
.base
&& !REG_OK_FOR_BASE_NONSTRICT_P (ad
.base
))
2419 if (ad
.indx
&& !REG_OK_FOR_INDEX_NONSTRICT_P (ad
.indx
))
2426 /* Return true if OP is a valid operand for the LA instruction.
2427 In 31-bit, we need to prove that the result is used as an
2428 address, as LA performs only a 31-bit addition. */
2431 legitimate_la_operand_p (rtx op
)
2433 struct s390_address addr
;
2434 if (!s390_decompose_address (op
, &addr
))
2437 return (TARGET_64BIT
|| addr
.pointer
);
2440 /* Return true if it is valid *and* preferable to use LA to
2441 compute the sum of OP1 and OP2. */
2444 preferred_la_operand_p (rtx op1
, rtx op2
)
2446 struct s390_address addr
;
2448 if (op2
!= const0_rtx
)
2449 op1
= gen_rtx_PLUS (Pmode
, op1
, op2
);
2451 if (!s390_decompose_address (op1
, &addr
))
2453 if (addr
.base
&& !REG_OK_FOR_BASE_STRICT_P (addr
.base
))
2455 if (addr
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (addr
.indx
))
2458 if (!TARGET_64BIT
&& !addr
.pointer
)
2464 if ((addr
.base
&& REG_P (addr
.base
) && REG_POINTER (addr
.base
))
2465 || (addr
.indx
&& REG_P (addr
.indx
) && REG_POINTER (addr
.indx
)))
2471 /* Emit a forced load-address operation to load SRC into DST.
2472 This will use the LOAD ADDRESS instruction even in situations
2473 where legitimate_la_operand_p (SRC) returns false. */
2476 s390_load_address (rtx dst
, rtx src
)
2479 emit_move_insn (dst
, src
);
2481 emit_insn (gen_force_la_31 (dst
, src
));
2484 /* Return a legitimate reference for ORIG (an address) using the
2485 register REG. If REG is 0, a new pseudo is generated.
2487 There are two types of references that must be handled:
2489 1. Global data references must load the address from the GOT, via
2490 the PIC reg. An insn is emitted to do this load, and the reg is
2493 2. Static data references, constant pool addresses, and code labels
2494 compute the address as an offset from the GOT, whose base is in
2495 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
2496 differentiate them from global data objects. The returned
2497 address is the PIC reg + an unspec constant.
2499 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2500 reg also appears in the address. */
2503 legitimize_pic_address (rtx orig
, rtx reg
)
2509 if (GET_CODE (addr
) == LABEL_REF
2510 || (GET_CODE (addr
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (addr
)))
2512 /* This is a local symbol. */
2513 if (TARGET_CPU_ZARCH
&& larl_operand (addr
, VOIDmode
))
2515 /* Access local symbols PC-relative via LARL.
2516 This is the same as in the non-PIC case, so it is
2517 handled automatically ... */
2521 /* Access local symbols relative to the GOT. */
2523 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2525 if (reload_in_progress
|| reload_completed
)
2526 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2528 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTOFF
);
2529 addr
= gen_rtx_CONST (Pmode
, addr
);
2530 addr
= force_const_mem (Pmode
, addr
);
2531 emit_move_insn (temp
, addr
);
2533 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2536 s390_load_address (reg
, new);
2541 else if (GET_CODE (addr
) == SYMBOL_REF
)
2544 reg
= gen_reg_rtx (Pmode
);
2548 /* Assume GOT offset < 4k. This is handled the same way
2549 in both 31- and 64-bit code (@GOT). */
2551 if (reload_in_progress
|| reload_completed
)
2552 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2554 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
2555 new = gen_rtx_CONST (Pmode
, new);
2556 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new);
2557 new = gen_const_mem (Pmode
, new);
2558 emit_move_insn (reg
, new);
2561 else if (TARGET_CPU_ZARCH
)
2563 /* If the GOT offset might be >= 4k, we determine the position
2564 of the GOT entry via a PC-relative LARL (@GOTENT). */
2566 rtx temp
= gen_reg_rtx (Pmode
);
2568 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTENT
);
2569 new = gen_rtx_CONST (Pmode
, new);
2570 emit_move_insn (temp
, new);
2572 new = gen_const_mem (Pmode
, temp
);
2573 emit_move_insn (reg
, new);
2578 /* If the GOT offset might be >= 4k, we have to load it
2579 from the literal pool (@GOT). */
2581 rtx temp
= gen_reg_rtx (Pmode
);
2583 if (reload_in_progress
|| reload_completed
)
2584 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2586 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
2587 addr
= gen_rtx_CONST (Pmode
, addr
);
2588 addr
= force_const_mem (Pmode
, addr
);
2589 emit_move_insn (temp
, addr
);
2591 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2592 new = gen_const_mem (Pmode
, new);
2593 emit_move_insn (reg
, new);
2599 if (GET_CODE (addr
) == CONST
)
2601 addr
= XEXP (addr
, 0);
2602 if (GET_CODE (addr
) == UNSPEC
)
2604 gcc_assert (XVECLEN (addr
, 0) == 1);
2605 switch (XINT (addr
, 1))
2607 /* If someone moved a GOT-relative UNSPEC
2608 out of the literal pool, force them back in. */
2611 new = force_const_mem (Pmode
, orig
);
2614 /* @GOT is OK as is if small. */
2617 new = force_const_mem (Pmode
, orig
);
2620 /* @GOTENT is OK as is. */
2624 /* @PLT is OK as is on 64-bit, must be converted to
2625 GOT-relative @PLTOFF on 31-bit. */
2627 if (!TARGET_CPU_ZARCH
)
2629 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2631 if (reload_in_progress
|| reload_completed
)
2632 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2634 addr
= XVECEXP (addr
, 0, 0);
2635 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
),
2637 addr
= gen_rtx_CONST (Pmode
, addr
);
2638 addr
= force_const_mem (Pmode
, addr
);
2639 emit_move_insn (temp
, addr
);
2641 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2644 s390_load_address (reg
, new);
2650 /* Everything else cannot happen. */
2656 gcc_assert (GET_CODE (addr
) == PLUS
);
2658 if (GET_CODE (addr
) == PLUS
)
2660 rtx op0
= XEXP (addr
, 0), op1
= XEXP (addr
, 1);
2661 /* Check first to see if this is a constant offset
2662 from a local symbol reference. */
2663 if ((GET_CODE (op0
) == LABEL_REF
2664 || (GET_CODE (op0
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (op0
)))
2665 && GET_CODE (op1
) == CONST_INT
)
2667 if (TARGET_CPU_ZARCH
&& larl_operand (op0
, VOIDmode
))
2669 if (INTVAL (op1
) & 1)
2671 /* LARL can't handle odd offsets, so emit a
2672 pair of LARL and LA. */
2673 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2675 if (!DISP_IN_RANGE (INTVAL (op1
)))
2677 int even
= INTVAL (op1
) - 1;
2678 op0
= gen_rtx_PLUS (Pmode
, op0
, GEN_INT (even
));
2679 op0
= gen_rtx_CONST (Pmode
, op0
);
2683 emit_move_insn (temp
, op0
);
2684 new = gen_rtx_PLUS (Pmode
, temp
, op1
);
2688 s390_load_address (reg
, new);
2694 /* If the offset is even, we can just use LARL.
2695 This will happen automatically. */
2700 /* Access local symbols relative to the GOT. */
2702 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2704 if (reload_in_progress
|| reload_completed
)
2705 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2707 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op0
),
2709 addr
= gen_rtx_PLUS (Pmode
, addr
, op1
);
2710 addr
= gen_rtx_CONST (Pmode
, addr
);
2711 addr
= force_const_mem (Pmode
, addr
);
2712 emit_move_insn (temp
, addr
);
2714 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2717 s390_load_address (reg
, new);
2723 /* Now, check whether it is a GOT relative symbol plus offset
2724 that was pulled out of the literal pool. Force it back in. */
2726 else if (GET_CODE (op0
) == UNSPEC
2727 && GET_CODE (op1
) == CONST_INT
2728 && XINT (op0
, 1) == UNSPEC_GOTOFF
)
2730 gcc_assert (XVECLEN (op0
, 0) == 1);
2732 new = force_const_mem (Pmode
, orig
);
2735 /* Otherwise, compute the sum. */
2738 base
= legitimize_pic_address (XEXP (addr
, 0), reg
);
2739 new = legitimize_pic_address (XEXP (addr
, 1),
2740 base
== reg
? NULL_RTX
: reg
);
2741 if (GET_CODE (new) == CONST_INT
)
2742 new = plus_constant (base
, INTVAL (new));
2745 if (GET_CODE (new) == PLUS
&& CONSTANT_P (XEXP (new, 1)))
2747 base
= gen_rtx_PLUS (Pmode
, base
, XEXP (new, 0));
2748 new = XEXP (new, 1);
2750 new = gen_rtx_PLUS (Pmode
, base
, new);
2753 if (GET_CODE (new) == CONST
)
2754 new = XEXP (new, 0);
2755 new = force_operand (new, 0);
2762 /* Load the thread pointer into a register. */
2765 get_thread_pointer (void)
2767 rtx tp
= gen_reg_rtx (Pmode
);
2769 emit_move_insn (tp
, gen_rtx_REG (Pmode
, TP_REGNUM
));
2770 mark_reg_pointer (tp
, BITS_PER_WORD
);
2775 /* Emit a tls call insn. The call target is the SYMBOL_REF stored
2776 in s390_tls_symbol which always refers to __tls_get_offset.
2777 The returned offset is written to RESULT_REG and an USE rtx is
2778 generated for TLS_CALL. */
2780 static GTY(()) rtx s390_tls_symbol
;
2783 s390_emit_tls_call_insn (rtx result_reg
, rtx tls_call
)
2787 gcc_assert (flag_pic
);
2789 if (!s390_tls_symbol
)
2790 s390_tls_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "__tls_get_offset");
2792 insn
= s390_emit_call (s390_tls_symbol
, tls_call
, result_reg
,
2793 gen_rtx_REG (Pmode
, RETURN_REGNUM
));
2795 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), result_reg
);
2796 CONST_OR_PURE_CALL_P (insn
) = 1;
2799 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
2800 this (thread-local) address. REG may be used as temporary. */
2803 legitimize_tls_address (rtx addr
, rtx reg
)
2805 rtx
new, tls_call
, temp
, base
, r2
, insn
;
2807 if (GET_CODE (addr
) == SYMBOL_REF
)
2808 switch (tls_symbolic_operand (addr
))
2810 case TLS_MODEL_GLOBAL_DYNAMIC
:
2812 r2
= gen_rtx_REG (Pmode
, 2);
2813 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_TLSGD
);
2814 new = gen_rtx_CONST (Pmode
, tls_call
);
2815 new = force_const_mem (Pmode
, new);
2816 emit_move_insn (r2
, new);
2817 s390_emit_tls_call_insn (r2
, tls_call
);
2818 insn
= get_insns ();
2821 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
2822 temp
= gen_reg_rtx (Pmode
);
2823 emit_libcall_block (insn
, temp
, r2
, new);
2825 new = gen_rtx_PLUS (Pmode
, get_thread_pointer (), temp
);
2828 s390_load_address (reg
, new);
2833 case TLS_MODEL_LOCAL_DYNAMIC
:
2835 r2
= gen_rtx_REG (Pmode
, 2);
2836 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM
);
2837 new = gen_rtx_CONST (Pmode
, tls_call
);
2838 new = force_const_mem (Pmode
, new);
2839 emit_move_insn (r2
, new);
2840 s390_emit_tls_call_insn (r2
, tls_call
);
2841 insn
= get_insns ();
2844 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM_NTPOFF
);
2845 temp
= gen_reg_rtx (Pmode
);
2846 emit_libcall_block (insn
, temp
, r2
, new);
2848 new = gen_rtx_PLUS (Pmode
, get_thread_pointer (), temp
);
2849 base
= gen_reg_rtx (Pmode
);
2850 s390_load_address (base
, new);
2852 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_DTPOFF
);
2853 new = gen_rtx_CONST (Pmode
, new);
2854 new = force_const_mem (Pmode
, new);
2855 temp
= gen_reg_rtx (Pmode
);
2856 emit_move_insn (temp
, new);
2858 new = gen_rtx_PLUS (Pmode
, base
, temp
);
2861 s390_load_address (reg
, new);
2866 case TLS_MODEL_INITIAL_EXEC
:
2869 /* Assume GOT offset < 4k. This is handled the same way
2870 in both 31- and 64-bit code. */
2872 if (reload_in_progress
|| reload_completed
)
2873 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2875 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
2876 new = gen_rtx_CONST (Pmode
, new);
2877 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new);
2878 new = gen_const_mem (Pmode
, new);
2879 temp
= gen_reg_rtx (Pmode
);
2880 emit_move_insn (temp
, new);
2882 else if (TARGET_CPU_ZARCH
)
2884 /* If the GOT offset might be >= 4k, we determine the position
2885 of the GOT entry via a PC-relative LARL. */
2887 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
2888 new = gen_rtx_CONST (Pmode
, new);
2889 temp
= gen_reg_rtx (Pmode
);
2890 emit_move_insn (temp
, new);
2892 new = gen_const_mem (Pmode
, temp
);
2893 temp
= gen_reg_rtx (Pmode
);
2894 emit_move_insn (temp
, new);
2898 /* If the GOT offset might be >= 4k, we have to load it
2899 from the literal pool. */
2901 if (reload_in_progress
|| reload_completed
)
2902 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2904 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
2905 new = gen_rtx_CONST (Pmode
, new);
2906 new = force_const_mem (Pmode
, new);
2907 temp
= gen_reg_rtx (Pmode
);
2908 emit_move_insn (temp
, new);
2910 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2911 new = gen_const_mem (Pmode
, new);
2913 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new, addr
), UNSPEC_TLS_LOAD
);
2914 temp
= gen_reg_rtx (Pmode
);
2915 emit_insn (gen_rtx_SET (Pmode
, temp
, new));
2919 /* In position-dependent code, load the absolute address of
2920 the GOT entry from the literal pool. */
2922 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
2923 new = gen_rtx_CONST (Pmode
, new);
2924 new = force_const_mem (Pmode
, new);
2925 temp
= gen_reg_rtx (Pmode
);
2926 emit_move_insn (temp
, new);
2929 new = gen_const_mem (Pmode
, new);
2930 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new, addr
), UNSPEC_TLS_LOAD
);
2931 temp
= gen_reg_rtx (Pmode
);
2932 emit_insn (gen_rtx_SET (Pmode
, temp
, new));
2935 new = gen_rtx_PLUS (Pmode
, get_thread_pointer (), temp
);
2938 s390_load_address (reg
, new);
2943 case TLS_MODEL_LOCAL_EXEC
:
2944 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
2945 new = gen_rtx_CONST (Pmode
, new);
2946 new = force_const_mem (Pmode
, new);
2947 temp
= gen_reg_rtx (Pmode
);
2948 emit_move_insn (temp
, new);
2950 new = gen_rtx_PLUS (Pmode
, get_thread_pointer (), temp
);
2953 s390_load_address (reg
, new);
2962 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == UNSPEC
)
2964 switch (XINT (XEXP (addr
, 0), 1))
2966 case UNSPEC_INDNTPOFF
:
2967 gcc_assert (TARGET_CPU_ZARCH
);
2976 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == PLUS
2977 && GET_CODE (XEXP (XEXP (addr
, 0), 1)) == CONST_INT
)
2979 new = XEXP (XEXP (addr
, 0), 0);
2980 if (GET_CODE (new) != SYMBOL_REF
)
2981 new = gen_rtx_CONST (Pmode
, new);
2983 new = legitimize_tls_address (new, reg
);
2984 new = plus_constant (new, INTVAL (XEXP (XEXP (addr
, 0), 1)));
2985 new = force_operand (new, 0);
2989 gcc_unreachable (); /* for now ... */
2994 /* Emit insns to move operands[1] into operands[0]. */
2997 emit_symbolic_move (rtx
*operands
)
2999 rtx temp
= no_new_pseudos
? operands
[0] : gen_reg_rtx (Pmode
);
3001 if (GET_CODE (operands
[0]) == MEM
)
3002 operands
[1] = force_reg (Pmode
, operands
[1]);
3003 else if (TLS_SYMBOLIC_CONST (operands
[1]))
3004 operands
[1] = legitimize_tls_address (operands
[1], temp
);
3006 operands
[1] = legitimize_pic_address (operands
[1], temp
);
3009 /* Try machine-dependent ways of modifying an illegitimate address X
3010 to be legitimate. If we find one, return the new, valid address.
3012 OLDX is the address as it was before break_out_memory_refs was called.
3013 In some cases it is useful to look at this to decide what needs to be done.
3015 MODE is the mode of the operand pointed to by X.
3017 When -fpic is used, special handling is needed for symbolic references.
3018 See comments by legitimize_pic_address for details. */
3021 legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
3022 enum machine_mode mode ATTRIBUTE_UNUSED
)
3024 rtx constant_term
= const0_rtx
;
3026 if (TLS_SYMBOLIC_CONST (x
))
3028 x
= legitimize_tls_address (x
, 0);
3030 if (legitimate_address_p (mode
, x
, FALSE
))
3035 if (SYMBOLIC_CONST (x
)
3036 || (GET_CODE (x
) == PLUS
3037 && (SYMBOLIC_CONST (XEXP (x
, 0))
3038 || SYMBOLIC_CONST (XEXP (x
, 1)))))
3039 x
= legitimize_pic_address (x
, 0);
3041 if (legitimate_address_p (mode
, x
, FALSE
))
3045 x
= eliminate_constant_term (x
, &constant_term
);
3047 /* Optimize loading of large displacements by splitting them
3048 into the multiple of 4K and the rest; this allows the
3049 former to be CSE'd if possible.
3051 Don't do this if the displacement is added to a register
3052 pointing into the stack frame, as the offsets will
3053 change later anyway. */
3055 if (GET_CODE (constant_term
) == CONST_INT
3056 && !TARGET_LONG_DISPLACEMENT
3057 && !DISP_IN_RANGE (INTVAL (constant_term
))
3058 && !(REG_P (x
) && REGNO_PTR_FRAME_P (REGNO (x
))))
3060 HOST_WIDE_INT lower
= INTVAL (constant_term
) & 0xfff;
3061 HOST_WIDE_INT upper
= INTVAL (constant_term
) ^ lower
;
3063 rtx temp
= gen_reg_rtx (Pmode
);
3064 rtx val
= force_operand (GEN_INT (upper
), temp
);
3066 emit_move_insn (temp
, val
);
3068 x
= gen_rtx_PLUS (Pmode
, x
, temp
);
3069 constant_term
= GEN_INT (lower
);
3072 if (GET_CODE (x
) == PLUS
)
3074 if (GET_CODE (XEXP (x
, 0)) == REG
)
3076 rtx temp
= gen_reg_rtx (Pmode
);
3077 rtx val
= force_operand (XEXP (x
, 1), temp
);
3079 emit_move_insn (temp
, val
);
3081 x
= gen_rtx_PLUS (Pmode
, XEXP (x
, 0), temp
);
3084 else if (GET_CODE (XEXP (x
, 1)) == REG
)
3086 rtx temp
= gen_reg_rtx (Pmode
);
3087 rtx val
= force_operand (XEXP (x
, 0), temp
);
3089 emit_move_insn (temp
, val
);
3091 x
= gen_rtx_PLUS (Pmode
, temp
, XEXP (x
, 1));
3095 if (constant_term
!= const0_rtx
)
3096 x
= gen_rtx_PLUS (Pmode
, x
, constant_term
);
3101 /* Try a machine-dependent way of reloading an illegitimate address AD
3102 operand. If we find one, push the reload and and return the new address.
3104 MODE is the mode of the enclosing MEM. OPNUM is the operand number
3105 and TYPE is the reload type of the current reload. */
3108 legitimize_reload_address (rtx ad
, enum machine_mode mode ATTRIBUTE_UNUSED
,
3109 int opnum
, int type
)
3111 if (!optimize
|| TARGET_LONG_DISPLACEMENT
)
3114 if (GET_CODE (ad
) == PLUS
)
3116 rtx tem
= simplify_binary_operation (PLUS
, Pmode
,
3117 XEXP (ad
, 0), XEXP (ad
, 1));
3122 if (GET_CODE (ad
) == PLUS
3123 && GET_CODE (XEXP (ad
, 0)) == REG
3124 && GET_CODE (XEXP (ad
, 1)) == CONST_INT
3125 && !DISP_IN_RANGE (INTVAL (XEXP (ad
, 1))))
3127 HOST_WIDE_INT lower
= INTVAL (XEXP (ad
, 1)) & 0xfff;
3128 HOST_WIDE_INT upper
= INTVAL (XEXP (ad
, 1)) ^ lower
;
3131 cst
= GEN_INT (upper
);
3132 if (!legitimate_reload_constant_p (cst
))
3133 cst
= force_const_mem (Pmode
, cst
);
3135 tem
= gen_rtx_PLUS (Pmode
, XEXP (ad
, 0), cst
);
3136 new = gen_rtx_PLUS (Pmode
, tem
, GEN_INT (lower
));
3138 push_reload (XEXP (tem
, 1), 0, &XEXP (tem
, 1), 0,
3139 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
3140 opnum
, (enum reload_type
) type
);
3147 /* Emit code to move LEN bytes from DST to SRC. */
3150 s390_expand_movmem (rtx dst
, rtx src
, rtx len
)
3152 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3154 if (INTVAL (len
) > 0)
3155 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (INTVAL (len
) - 1)));
3158 else if (TARGET_MVCLE
)
3160 emit_insn (gen_movmem_long (dst
, src
, convert_to_mode (Pmode
, len
, 1)));
3165 rtx dst_addr
, src_addr
, count
, blocks
, temp
;
3166 rtx loop_start_label
= gen_label_rtx ();
3167 rtx loop_end_label
= gen_label_rtx ();
3168 rtx end_label
= gen_label_rtx ();
3169 enum machine_mode mode
;
3171 mode
= GET_MODE (len
);
3172 if (mode
== VOIDmode
)
3175 dst_addr
= gen_reg_rtx (Pmode
);
3176 src_addr
= gen_reg_rtx (Pmode
);
3177 count
= gen_reg_rtx (mode
);
3178 blocks
= gen_reg_rtx (mode
);
3180 convert_move (count
, len
, 1);
3181 emit_cmp_and_jump_insns (count
, const0_rtx
,
3182 EQ
, NULL_RTX
, mode
, 1, end_label
);
3184 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
3185 emit_move_insn (src_addr
, force_operand (XEXP (src
, 0), NULL_RTX
));
3186 dst
= change_address (dst
, VOIDmode
, dst_addr
);
3187 src
= change_address (src
, VOIDmode
, src_addr
);
3189 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3191 emit_move_insn (count
, temp
);
3193 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3195 emit_move_insn (blocks
, temp
);
3197 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3198 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3200 emit_label (loop_start_label
);
3202 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (255)));
3203 s390_load_address (dst_addr
,
3204 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
3205 s390_load_address (src_addr
,
3206 gen_rtx_PLUS (Pmode
, src_addr
, GEN_INT (256)));
3208 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3210 emit_move_insn (blocks
, temp
);
3212 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3213 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3215 emit_jump (loop_start_label
);
3216 emit_label (loop_end_label
);
3218 emit_insn (gen_movmem_short (dst
, src
,
3219 convert_to_mode (Pmode
, count
, 1)));
3220 emit_label (end_label
);
3224 /* Emit code to clear LEN bytes at DST. */
3227 s390_expand_clrmem (rtx dst
, rtx len
)
3229 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3231 if (INTVAL (len
) > 0)
3232 emit_insn (gen_clrmem_short (dst
, GEN_INT (INTVAL (len
) - 1)));
3235 else if (TARGET_MVCLE
)
3237 emit_insn (gen_clrmem_long (dst
, convert_to_mode (Pmode
, len
, 1)));
3242 rtx dst_addr
, src_addr
, count
, blocks
, temp
;
3243 rtx loop_start_label
= gen_label_rtx ();
3244 rtx loop_end_label
= gen_label_rtx ();
3245 rtx end_label
= gen_label_rtx ();
3246 enum machine_mode mode
;
3248 mode
= GET_MODE (len
);
3249 if (mode
== VOIDmode
)
3252 dst_addr
= gen_reg_rtx (Pmode
);
3253 src_addr
= gen_reg_rtx (Pmode
);
3254 count
= gen_reg_rtx (mode
);
3255 blocks
= gen_reg_rtx (mode
);
3257 convert_move (count
, len
, 1);
3258 emit_cmp_and_jump_insns (count
, const0_rtx
,
3259 EQ
, NULL_RTX
, mode
, 1, end_label
);
3261 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
3262 dst
= change_address (dst
, VOIDmode
, dst_addr
);
3264 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3266 emit_move_insn (count
, temp
);
3268 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3270 emit_move_insn (blocks
, temp
);
3272 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3273 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3275 emit_label (loop_start_label
);
3277 emit_insn (gen_clrmem_short (dst
, GEN_INT (255)));
3278 s390_load_address (dst_addr
,
3279 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
3281 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3283 emit_move_insn (blocks
, temp
);
3285 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3286 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3288 emit_jump (loop_start_label
);
3289 emit_label (loop_end_label
);
3291 emit_insn (gen_clrmem_short (dst
, convert_to_mode (Pmode
, count
, 1)));
3292 emit_label (end_label
);
3296 /* Emit code to compare LEN bytes at OP0 with those at OP1,
3297 and return the result in TARGET. */
3300 s390_expand_cmpmem (rtx target
, rtx op0
, rtx op1
, rtx len
)
3302 rtx ccreg
= gen_rtx_REG (CCUmode
, CC_REGNUM
);
3305 /* As the result of CMPINT is inverted compared to what we need,
3306 we have to swap the operands. */
3307 tmp
= op0
; op0
= op1
; op1
= tmp
;
3309 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3311 if (INTVAL (len
) > 0)
3313 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (INTVAL (len
) - 1)));
3314 emit_insn (gen_cmpint (target
, ccreg
));
3317 emit_move_insn (target
, const0_rtx
);
3319 else if (TARGET_MVCLE
)
3321 emit_insn (gen_cmpmem_long (op0
, op1
, convert_to_mode (Pmode
, len
, 1)));
3322 emit_insn (gen_cmpint (target
, ccreg
));
3326 rtx addr0
, addr1
, count
, blocks
, temp
;
3327 rtx loop_start_label
= gen_label_rtx ();
3328 rtx loop_end_label
= gen_label_rtx ();
3329 rtx end_label
= gen_label_rtx ();
3330 enum machine_mode mode
;
3332 mode
= GET_MODE (len
);
3333 if (mode
== VOIDmode
)
3336 addr0
= gen_reg_rtx (Pmode
);
3337 addr1
= gen_reg_rtx (Pmode
);
3338 count
= gen_reg_rtx (mode
);
3339 blocks
= gen_reg_rtx (mode
);
3341 convert_move (count
, len
, 1);
3342 emit_cmp_and_jump_insns (count
, const0_rtx
,
3343 EQ
, NULL_RTX
, mode
, 1, end_label
);
3345 emit_move_insn (addr0
, force_operand (XEXP (op0
, 0), NULL_RTX
));
3346 emit_move_insn (addr1
, force_operand (XEXP (op1
, 0), NULL_RTX
));
3347 op0
= change_address (op0
, VOIDmode
, addr0
);
3348 op1
= change_address (op1
, VOIDmode
, addr1
);
3350 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3352 emit_move_insn (count
, temp
);
3354 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3356 emit_move_insn (blocks
, temp
);
3358 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3359 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3361 emit_label (loop_start_label
);
3363 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (255)));
3364 temp
= gen_rtx_NE (VOIDmode
, ccreg
, const0_rtx
);
3365 temp
= gen_rtx_IF_THEN_ELSE (VOIDmode
, temp
,
3366 gen_rtx_LABEL_REF (VOIDmode
, end_label
), pc_rtx
);
3367 temp
= gen_rtx_SET (VOIDmode
, pc_rtx
, temp
);
3368 emit_jump_insn (temp
);
3370 s390_load_address (addr0
,
3371 gen_rtx_PLUS (Pmode
, addr0
, GEN_INT (256)));
3372 s390_load_address (addr1
,
3373 gen_rtx_PLUS (Pmode
, addr1
, GEN_INT (256)));
3375 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3377 emit_move_insn (blocks
, temp
);
3379 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3380 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3382 emit_jump (loop_start_label
);
3383 emit_label (loop_end_label
);
3385 emit_insn (gen_cmpmem_short (op0
, op1
,
3386 convert_to_mode (Pmode
, count
, 1)));
3387 emit_label (end_label
);
3389 emit_insn (gen_cmpint (target
, ccreg
));
3394 /* Expand conditional increment or decrement using alc/slb instructions.
3395 Should generate code setting DST to either SRC or SRC + INCREMENT,
3396 depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
3397 Returns true if successful, false otherwise.
3399 That makes it possible to implement some if-constructs without jumps e.g.:
3400 (borrow = CC0 | CC1 and carry = CC2 | CC3)
3401 unsigned int a, b, c;
3402 if (a < b) c++; -> CCU b > a -> CC2; c += carry;
3403 if (a < b) c--; -> CCL3 a - b -> borrow; c -= borrow;
3404 if (a <= b) c++; -> CCL3 b - a -> borrow; c += carry;
3405 if (a <= b) c--; -> CCU a <= b -> borrow; c -= borrow;
3407 Checks for EQ and NE with a nonzero value need an additional xor e.g.:
3408 if (a == b) c++; -> CCL3 a ^= b; 0 - a -> borrow; c += carry;
3409 if (a == b) c--; -> CCU a ^= b; a <= 0 -> CC0 | CC1; c -= borrow;
3410 if (a != b) c++; -> CCU a ^= b; a > 0 -> CC2; c += carry;
3411 if (a != b) c--; -> CCL3 a ^= b; 0 - a -> borrow; c -= borrow; */
3414 s390_expand_addcc (enum rtx_code cmp_code
, rtx cmp_op0
, rtx cmp_op1
,
3415 rtx dst
, rtx src
, rtx increment
)
3417 enum machine_mode cmp_mode
;
3418 enum machine_mode cc_mode
;
3424 if ((GET_MODE (cmp_op0
) == SImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
3425 && (GET_MODE (cmp_op1
) == SImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
3427 else if ((GET_MODE (cmp_op0
) == DImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
3428 && (GET_MODE (cmp_op1
) == DImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
3433 /* Try ADD LOGICAL WITH CARRY. */
3434 if (increment
== const1_rtx
)
3436 /* Determine CC mode to use. */
3437 if (cmp_code
== EQ
|| cmp_code
== NE
)
3439 if (cmp_op1
!= const0_rtx
)
3441 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
3442 NULL_RTX
, 0, OPTAB_WIDEN
);
3443 cmp_op1
= const0_rtx
;
3446 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
3449 if (cmp_code
== LTU
|| cmp_code
== LEU
)
3454 cmp_code
= swap_condition (cmp_code
);
3471 /* Emit comparison instruction pattern. */
3472 if (!register_operand (cmp_op0
, cmp_mode
))
3473 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
3475 insn
= gen_rtx_SET (VOIDmode
, gen_rtx_REG (cc_mode
, CC_REGNUM
),
3476 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
3477 /* We use insn_invalid_p here to add clobbers if required. */
3478 ret
= insn_invalid_p (emit_insn (insn
));
3481 /* Emit ALC instruction pattern. */
3482 op_res
= gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
3483 gen_rtx_REG (cc_mode
, CC_REGNUM
),
3486 if (src
!= const0_rtx
)
3488 if (!register_operand (src
, GET_MODE (dst
)))
3489 src
= force_reg (GET_MODE (dst
), src
);
3491 src
= gen_rtx_PLUS (GET_MODE (dst
), src
, const0_rtx
);
3492 op_res
= gen_rtx_PLUS (GET_MODE (dst
), src
, op_res
);
3495 p
= rtvec_alloc (2);
3497 gen_rtx_SET (VOIDmode
, dst
, op_res
);
3499 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
3500 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
3505 /* Try SUBTRACT LOGICAL WITH BORROW. */
3506 if (increment
== constm1_rtx
)
3508 /* Determine CC mode to use. */
3509 if (cmp_code
== EQ
|| cmp_code
== NE
)
3511 if (cmp_op1
!= const0_rtx
)
3513 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
3514 NULL_RTX
, 0, OPTAB_WIDEN
);
3515 cmp_op1
= const0_rtx
;
3518 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
3521 if (cmp_code
== GTU
|| cmp_code
== GEU
)
3526 cmp_code
= swap_condition (cmp_code
);
3543 /* Emit comparison instruction pattern. */
3544 if (!register_operand (cmp_op0
, cmp_mode
))
3545 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
3547 insn
= gen_rtx_SET (VOIDmode
, gen_rtx_REG (cc_mode
, CC_REGNUM
),
3548 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
3549 /* We use insn_invalid_p here to add clobbers if required. */
3550 ret
= insn_invalid_p (emit_insn (insn
));
3553 /* Emit SLB instruction pattern. */
3554 if (!register_operand (src
, GET_MODE (dst
)))
3555 src
= force_reg (GET_MODE (dst
), src
);
3557 op_res
= gen_rtx_MINUS (GET_MODE (dst
),
3558 gen_rtx_MINUS (GET_MODE (dst
), src
, const0_rtx
),
3559 gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
3560 gen_rtx_REG (cc_mode
, CC_REGNUM
),
3562 p
= rtvec_alloc (2);
3564 gen_rtx_SET (VOIDmode
, dst
, op_res
);
3566 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
3567 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
3576 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
3577 We need to emit DTP-relative relocations. */
3579 static void s390_output_dwarf_dtprel (FILE *, int, rtx
) ATTRIBUTE_UNUSED
;
3582 s390_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
3587 fputs ("\t.long\t", file
);
3590 fputs ("\t.quad\t", file
);
3595 output_addr_const (file
, x
);
3596 fputs ("@DTPOFF", file
);
3599 /* In the name of slightly smaller debug output, and to cater to
3600 general assembler lossage, recognize various UNSPEC sequences
3601 and turn them back into a direct symbol reference. */
3604 s390_delegitimize_address (rtx orig_x
)
3608 if (GET_CODE (x
) != MEM
)
3612 if (GET_CODE (x
) == PLUS
3613 && GET_CODE (XEXP (x
, 1)) == CONST
3614 && GET_CODE (XEXP (x
, 0)) == REG
3615 && REGNO (XEXP (x
, 0)) == PIC_OFFSET_TABLE_REGNUM
)
3617 y
= XEXP (XEXP (x
, 1), 0);
3618 if (GET_CODE (y
) == UNSPEC
3619 && XINT (y
, 1) == UNSPEC_GOT
)
3620 return XVECEXP (y
, 0, 0);
3624 if (GET_CODE (x
) == CONST
)
3627 if (GET_CODE (y
) == UNSPEC
3628 && XINT (y
, 1) == UNSPEC_GOTENT
)
3629 return XVECEXP (y
, 0, 0);
3636 /* Output shift count operand OP to stdio stream FILE. */
3639 print_shift_count_operand (FILE *file
, rtx op
)
3641 HOST_WIDE_INT offset
= 0;
3643 /* We can have an integer constant, an address register,
3644 or a sum of the two. */
3645 if (GET_CODE (op
) == CONST_INT
)
3647 offset
= INTVAL (op
);
3650 if (op
&& GET_CODE (op
) == PLUS
&& GET_CODE (XEXP (op
, 1)) == CONST_INT
)
3652 offset
= INTVAL (XEXP (op
, 1));
3655 while (op
&& GET_CODE (op
) == SUBREG
)
3656 op
= SUBREG_REG (op
);
3661 gcc_assert (GET_CODE (op
) == REG
);
3662 gcc_assert (REGNO (op
) < FIRST_PSEUDO_REGISTER
);
3663 gcc_assert (REGNO_REG_CLASS (REGNO (op
)) == ADDR_REGS
);
3666 /* Shift counts are truncated to the low six bits anyway. */
3667 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
& 63);
3669 fprintf (file
, "(%s)", reg_names
[REGNO (op
)]);
3672 /* See 'get_some_local_dynamic_name'. */
3675 get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
3679 if (GET_CODE (x
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (x
))
3681 x
= get_pool_constant (x
);
3682 return for_each_rtx (&x
, get_some_local_dynamic_name_1
, 0);
3685 if (GET_CODE (x
) == SYMBOL_REF
3686 && tls_symbolic_operand (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
3688 cfun
->machine
->some_ld_name
= XSTR (x
, 0);
3695 /* Locate some local-dynamic symbol still in use by this function
3696 so that we can print its name in local-dynamic base patterns. */
3699 get_some_local_dynamic_name (void)
3703 if (cfun
->machine
->some_ld_name
)
3704 return cfun
->machine
->some_ld_name
;
3706 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
3708 && for_each_rtx (&PATTERN (insn
), get_some_local_dynamic_name_1
, 0))
3709 return cfun
->machine
->some_ld_name
;
3714 /* Output machine-dependent UNSPECs occurring in address constant X
3715 in assembler syntax to stdio stream FILE. Returns true if the
3716 constant X could be recognized, false otherwise. */
3719 s390_output_addr_const_extra (FILE *file
, rtx x
)
3721 if (GET_CODE (x
) == UNSPEC
&& XVECLEN (x
, 0) == 1)
3722 switch (XINT (x
, 1))
3725 output_addr_const (file
, XVECEXP (x
, 0, 0));
3726 fprintf (file
, "@GOTENT");
3729 output_addr_const (file
, XVECEXP (x
, 0, 0));
3730 fprintf (file
, "@GOT");
3733 output_addr_const (file
, XVECEXP (x
, 0, 0));
3734 fprintf (file
, "@GOTOFF");
3737 output_addr_const (file
, XVECEXP (x
, 0, 0));
3738 fprintf (file
, "@PLT");
3741 output_addr_const (file
, XVECEXP (x
, 0, 0));
3742 fprintf (file
, "@PLTOFF");
3745 output_addr_const (file
, XVECEXP (x
, 0, 0));
3746 fprintf (file
, "@TLSGD");
3749 assemble_name (file
, get_some_local_dynamic_name ());
3750 fprintf (file
, "@TLSLDM");
3753 output_addr_const (file
, XVECEXP (x
, 0, 0));
3754 fprintf (file
, "@DTPOFF");
3757 output_addr_const (file
, XVECEXP (x
, 0, 0));
3758 fprintf (file
, "@NTPOFF");
3760 case UNSPEC_GOTNTPOFF
:
3761 output_addr_const (file
, XVECEXP (x
, 0, 0));
3762 fprintf (file
, "@GOTNTPOFF");
3764 case UNSPEC_INDNTPOFF
:
3765 output_addr_const (file
, XVECEXP (x
, 0, 0));
3766 fprintf (file
, "@INDNTPOFF");
3773 /* Output address operand ADDR in assembler syntax to
3774 stdio stream FILE. */
3777 print_operand_address (FILE *file
, rtx addr
)
3779 struct s390_address ad
;
3781 if (!s390_decompose_address (addr
, &ad
)
3782 || (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
3783 || (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
)))
3784 output_operand_lossage ("Cannot decompose address.");
3787 output_addr_const (file
, ad
.disp
);
3789 fprintf (file
, "0");
3791 if (ad
.base
&& ad
.indx
)
3792 fprintf (file
, "(%s,%s)", reg_names
[REGNO (ad
.indx
)],
3793 reg_names
[REGNO (ad
.base
)]);
3795 fprintf (file
, "(%s)", reg_names
[REGNO (ad
.base
)]);
3798 /* Output operand X in assembler syntax to stdio stream FILE.
3799 CODE specified the format flag. The following format flags
3802 'C': print opcode suffix for branch condition.
3803 'D': print opcode suffix for inverse branch condition.
3804 'J': print tls_load/tls_gdcall/tls_ldcall suffix
3805 'O': print only the displacement of a memory reference.
3806 'R': print only the base register of a memory reference.
3807 'S': print S-type memory reference (base+displacement).
3808 'N': print the second word of a DImode operand.
3809 'M': print the second word of a TImode operand.
3810 'Y': print shift count operand.
3812 'b': print integer X as if it's an unsigned byte.
3813 'x': print integer X as if it's an unsigned word.
3814 'h': print integer X as if it's a signed word.
3815 'i': print the first nonzero HImode part of X.
3816 'j': print the first HImode part unequal to 0xffff of X. */
3819 print_operand (FILE *file
, rtx x
, int code
)
3824 fprintf (file
, s390_branch_condition_mnemonic (x
, FALSE
));
3828 fprintf (file
, s390_branch_condition_mnemonic (x
, TRUE
));
3832 if (GET_CODE (x
) == SYMBOL_REF
)
3834 fprintf (file
, "%s", ":tls_load:");
3835 output_addr_const (file
, x
);
3837 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSGD
)
3839 fprintf (file
, "%s", ":tls_gdcall:");
3840 output_addr_const (file
, XVECEXP (x
, 0, 0));
3842 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSLDM
)
3844 fprintf (file
, "%s", ":tls_ldcall:");
3845 assemble_name (file
, get_some_local_dynamic_name ());
3853 struct s390_address ad
;
3856 gcc_assert (GET_CODE (x
) == MEM
);
3857 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
3859 gcc_assert (!ad
.base
|| REG_OK_FOR_BASE_STRICT_P (ad
.base
));
3860 gcc_assert (!ad
.indx
);
3863 output_addr_const (file
, ad
.disp
);
3865 fprintf (file
, "0");
3871 struct s390_address ad
;
3874 gcc_assert (GET_CODE (x
) == MEM
);
3875 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
3877 gcc_assert (!ad
.base
|| REG_OK_FOR_BASE_STRICT_P (ad
.base
));
3878 gcc_assert (!ad
.indx
);
3881 fprintf (file
, "%s", reg_names
[REGNO (ad
.base
)]);
3883 fprintf (file
, "0");
3889 struct s390_address ad
;
3892 gcc_assert (GET_CODE (x
) == MEM
);
3893 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
3895 gcc_assert (!ad
.base
|| REG_OK_FOR_BASE_STRICT_P (ad
.base
));
3896 gcc_assert (!ad
.indx
);
3899 output_addr_const (file
, ad
.disp
);
3901 fprintf (file
, "0");
3904 fprintf (file
, "(%s)", reg_names
[REGNO (ad
.base
)]);
3909 if (GET_CODE (x
) == REG
)
3910 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
3911 else if (GET_CODE (x
) == MEM
)
3912 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 4));
3918 if (GET_CODE (x
) == REG
)
3919 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
3920 else if (GET_CODE (x
) == MEM
)
3921 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 8));
3927 print_shift_count_operand (file
, x
);
3931 switch (GET_CODE (x
))
3934 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
3938 output_address (XEXP (x
, 0));
3945 output_addr_const (file
, x
);
3950 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xff);
3951 else if (code
== 'x')
3952 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xffff);
3953 else if (code
== 'h')
3954 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((INTVAL (x
) & 0xffff) ^ 0x8000) - 0x8000);
3955 else if (code
== 'i')
3956 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
3957 s390_extract_part (x
, HImode
, 0));
3958 else if (code
== 'j')
3959 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
3960 s390_extract_part (x
, HImode
, -1));
3962 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
3966 gcc_assert (GET_MODE (x
) == VOIDmode
);
3968 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xff);
3969 else if (code
== 'x')
3970 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xffff);
3971 else if (code
== 'h')
3972 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((CONST_DOUBLE_LOW (x
) & 0xffff) ^ 0x8000) - 0x8000);
3978 fatal_insn ("UNKNOWN in print_operand !?", x
);
3983 /* Target hook for assembling integer objects. We need to define it
3984 here to work a round a bug in some versions of GAS, which couldn't
3985 handle values smaller than INT_MIN when printed in decimal. */
3988 s390_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
3990 if (size
== 8 && aligned_p
3991 && GET_CODE (x
) == CONST_INT
&& INTVAL (x
) < INT_MIN
)
3993 fprintf (asm_out_file
, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX
"\n",
3997 return default_assemble_integer (x
, size
, aligned_p
);
4000 /* Returns true if register REGNO is used for forming
4001 a memory address in expression X. */
4004 reg_used_in_mem_p (int regno
, rtx x
)
4006 enum rtx_code code
= GET_CODE (x
);
4012 if (refers_to_regno_p (regno
, regno
+1,
4016 else if (code
== SET
4017 && GET_CODE (SET_DEST (x
)) == PC
)
4019 if (refers_to_regno_p (regno
, regno
+1,
4024 fmt
= GET_RTX_FORMAT (code
);
4025 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
4028 && reg_used_in_mem_p (regno
, XEXP (x
, i
)))
4031 else if (fmt
[i
] == 'E')
4032 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
4033 if (reg_used_in_mem_p (regno
, XVECEXP (x
, i
, j
)))
4039 /* Returns true if expression DEP_RTX sets an address register
4040 used by instruction INSN to address memory. */
4043 addr_generation_dependency_p (rtx dep_rtx
, rtx insn
)
4047 if (GET_CODE (dep_rtx
) == INSN
)
4048 dep_rtx
= PATTERN (dep_rtx
);
4050 if (GET_CODE (dep_rtx
) == SET
)
4052 target
= SET_DEST (dep_rtx
);
4053 if (GET_CODE (target
) == STRICT_LOW_PART
)
4054 target
= XEXP (target
, 0);
4055 while (GET_CODE (target
) == SUBREG
)
4056 target
= SUBREG_REG (target
);
4058 if (GET_CODE (target
) == REG
)
4060 int regno
= REGNO (target
);
4062 if (s390_safe_attr_type (insn
) == TYPE_LA
)
4064 pat
= PATTERN (insn
);
4065 if (GET_CODE (pat
) == PARALLEL
)
4067 gcc_assert (XVECLEN (pat
, 0) == 2);
4068 pat
= XVECEXP (pat
, 0, 0);
4070 gcc_assert (GET_CODE (pat
) == SET
);
4071 return refers_to_regno_p (regno
, regno
+1, SET_SRC (pat
), 0);
4073 else if (get_attr_atype (insn
) == ATYPE_AGEN
)
4074 return reg_used_in_mem_p (regno
, PATTERN (insn
));
4080 /* Return 1, if dep_insn sets register used in insn in the agen unit. */
4083 s390_agen_dep_p (rtx dep_insn
, rtx insn
)
4085 rtx dep_rtx
= PATTERN (dep_insn
);
4088 if (GET_CODE (dep_rtx
) == SET
4089 && addr_generation_dependency_p (dep_rtx
, insn
))
4091 else if (GET_CODE (dep_rtx
) == PARALLEL
)
4093 for (i
= 0; i
< XVECLEN (dep_rtx
, 0); i
++)
4095 if (addr_generation_dependency_p (XVECEXP (dep_rtx
, 0, i
), insn
))
4102 /* A C statement (sans semicolon) to update the integer scheduling priority
4103 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
4104 reduce the priority to execute INSN later. Do not define this macro if
4105 you do not need to adjust the scheduling priorities of insns.
4107 A STD instruction should be scheduled earlier,
4108 in order to use the bypass. */
4111 s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
4113 if (! INSN_P (insn
))
4116 if (s390_tune
!= PROCESSOR_2084_Z990
)
4119 switch (s390_safe_attr_type (insn
))
4123 priority
= priority
<< 3;
4127 priority
= priority
<< 1;
4135 /* The number of instructions that can be issued per cycle. */
4138 s390_issue_rate (void)
4140 if (s390_tune
== PROCESSOR_2084_Z990
)
4146 s390_first_cycle_multipass_dfa_lookahead (void)
4152 /* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
4153 Fix up MEMs as required. */
4156 annotate_constant_pool_refs (rtx
*x
)
4161 gcc_assert (GET_CODE (*x
) != SYMBOL_REF
4162 || !CONSTANT_POOL_ADDRESS_P (*x
));
4164 /* Literal pool references can only occur inside a MEM ... */
4165 if (GET_CODE (*x
) == MEM
)
4167 rtx memref
= XEXP (*x
, 0);
4169 if (GET_CODE (memref
) == SYMBOL_REF
4170 && CONSTANT_POOL_ADDRESS_P (memref
))
4172 rtx base
= cfun
->machine
->base_reg
;
4173 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, memref
, base
),
4176 *x
= replace_equiv_address (*x
, addr
);
4180 if (GET_CODE (memref
) == CONST
4181 && GET_CODE (XEXP (memref
, 0)) == PLUS
4182 && GET_CODE (XEXP (XEXP (memref
, 0), 1)) == CONST_INT
4183 && GET_CODE (XEXP (XEXP (memref
, 0), 0)) == SYMBOL_REF
4184 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (memref
, 0), 0)))
4186 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (memref
, 0), 1));
4187 rtx sym
= XEXP (XEXP (memref
, 0), 0);
4188 rtx base
= cfun
->machine
->base_reg
;
4189 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
4192 *x
= replace_equiv_address (*x
, plus_constant (addr
, off
));
4197 /* ... or a load-address type pattern. */
4198 if (GET_CODE (*x
) == SET
)
4200 rtx addrref
= SET_SRC (*x
);
4202 if (GET_CODE (addrref
) == SYMBOL_REF
4203 && CONSTANT_POOL_ADDRESS_P (addrref
))
4205 rtx base
= cfun
->machine
->base_reg
;
4206 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, addrref
, base
),
4209 SET_SRC (*x
) = addr
;
4213 if (GET_CODE (addrref
) == CONST
4214 && GET_CODE (XEXP (addrref
, 0)) == PLUS
4215 && GET_CODE (XEXP (XEXP (addrref
, 0), 1)) == CONST_INT
4216 && GET_CODE (XEXP (XEXP (addrref
, 0), 0)) == SYMBOL_REF
4217 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (addrref
, 0), 0)))
4219 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (addrref
, 0), 1));
4220 rtx sym
= XEXP (XEXP (addrref
, 0), 0);
4221 rtx base
= cfun
->machine
->base_reg
;
4222 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
4225 SET_SRC (*x
) = plus_constant (addr
, off
);
4230 /* Annotate LTREL_BASE as well. */
4231 if (GET_CODE (*x
) == UNSPEC
4232 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
4234 rtx base
= cfun
->machine
->base_reg
;
4235 *x
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XVECEXP (*x
, 0, 0), base
),
4240 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
4241 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
4245 annotate_constant_pool_refs (&XEXP (*x
, i
));
4247 else if (fmt
[i
] == 'E')
4249 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
4250 annotate_constant_pool_refs (&XVECEXP (*x
, i
, j
));
4255 /* Split all branches that exceed the maximum distance.
4256 Returns true if this created a new literal pool entry. */
4259 s390_split_branches (void)
4261 rtx temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
4262 int new_literal
= 0, ret
;
4263 rtx insn
, pat
, tmp
, target
;
4266 /* We need correct insn addresses. */
4268 shorten_branches (get_insns ());
4270 /* Find all branches that exceed 64KB, and split them. */
4272 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
4274 if (GET_CODE (insn
) != JUMP_INSN
)
4277 pat
= PATTERN (insn
);
4278 if (GET_CODE (pat
) == PARALLEL
&& XVECLEN (pat
, 0) > 2)
4279 pat
= XVECEXP (pat
, 0, 0);
4280 if (GET_CODE (pat
) != SET
|| SET_DEST (pat
) != pc_rtx
)
4283 if (GET_CODE (SET_SRC (pat
)) == LABEL_REF
)
4285 label
= &SET_SRC (pat
);
4287 else if (GET_CODE (SET_SRC (pat
)) == IF_THEN_ELSE
)
4289 if (GET_CODE (XEXP (SET_SRC (pat
), 1)) == LABEL_REF
)
4290 label
= &XEXP (SET_SRC (pat
), 1);
4291 else if (GET_CODE (XEXP (SET_SRC (pat
), 2)) == LABEL_REF
)
4292 label
= &XEXP (SET_SRC (pat
), 2);
4299 if (get_attr_length (insn
) <= 4)
4302 /* We are going to use the return register as scratch register,
4303 make sure it will be saved/restored by the prologue/epilogue. */
4304 cfun_frame_layout
.save_return_addr_p
= 1;
4309 tmp
= force_const_mem (Pmode
, *label
);
4310 tmp
= emit_insn_before (gen_rtx_SET (Pmode
, temp_reg
, tmp
), insn
);
4311 INSN_ADDRESSES_NEW (tmp
, -1);
4312 annotate_constant_pool_refs (&PATTERN (tmp
));
4319 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, *label
),
4320 UNSPEC_LTREL_OFFSET
);
4321 target
= gen_rtx_CONST (Pmode
, target
);
4322 target
= force_const_mem (Pmode
, target
);
4323 tmp
= emit_insn_before (gen_rtx_SET (Pmode
, temp_reg
, target
), insn
);
4324 INSN_ADDRESSES_NEW (tmp
, -1);
4325 annotate_constant_pool_refs (&PATTERN (tmp
));
4327 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XEXP (target
, 0),
4328 cfun
->machine
->base_reg
),
4330 target
= gen_rtx_PLUS (Pmode
, temp_reg
, target
);
4333 ret
= validate_change (insn
, label
, target
, 0);
4341 /* Find an annotated literal pool symbol referenced in RTX X,
4342 and store it at REF. Will abort if X contains references to
4343 more than one such pool symbol; multiple references to the same
4344 symbol are allowed, however.
4346 The rtx pointed to by REF must be initialized to NULL_RTX
4347 by the caller before calling this routine. */
4350 find_constant_pool_ref (rtx x
, rtx
*ref
)
4355 /* Ignore LTREL_BASE references. */
4356 if (GET_CODE (x
) == UNSPEC
4357 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
4359 /* Likewise POOL_ENTRY insns. */
4360 if (GET_CODE (x
) == UNSPEC_VOLATILE
4361 && XINT (x
, 1) == UNSPECV_POOL_ENTRY
)
4364 gcc_assert (GET_CODE (x
) != SYMBOL_REF
4365 || !CONSTANT_POOL_ADDRESS_P (x
));
4367 if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_LTREF
)
4369 rtx sym
= XVECEXP (x
, 0, 0);
4370 gcc_assert (GET_CODE (sym
) == SYMBOL_REF
4371 && CONSTANT_POOL_ADDRESS_P (sym
));
4373 if (*ref
== NULL_RTX
)
4376 gcc_assert (*ref
== sym
);
4381 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
4382 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
4386 find_constant_pool_ref (XEXP (x
, i
), ref
);
4388 else if (fmt
[i
] == 'E')
4390 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
4391 find_constant_pool_ref (XVECEXP (x
, i
, j
), ref
);
4396 /* Replace every reference to the annotated literal pool
4397 symbol REF in X by its base plus OFFSET. */
4400 replace_constant_pool_ref (rtx
*x
, rtx ref
, rtx offset
)
4405 gcc_assert (*x
!= ref
);
4407 if (GET_CODE (*x
) == UNSPEC
4408 && XINT (*x
, 1) == UNSPEC_LTREF
4409 && XVECEXP (*x
, 0, 0) == ref
)
4411 *x
= gen_rtx_PLUS (Pmode
, XVECEXP (*x
, 0, 1), offset
);
4415 if (GET_CODE (*x
) == PLUS
4416 && GET_CODE (XEXP (*x
, 1)) == CONST_INT
4417 && GET_CODE (XEXP (*x
, 0)) == UNSPEC
4418 && XINT (XEXP (*x
, 0), 1) == UNSPEC_LTREF
4419 && XVECEXP (XEXP (*x
, 0), 0, 0) == ref
)
4421 rtx addr
= gen_rtx_PLUS (Pmode
, XVECEXP (XEXP (*x
, 0), 0, 1), offset
);
4422 *x
= plus_constant (addr
, INTVAL (XEXP (*x
, 1)));
4426 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
4427 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
4431 replace_constant_pool_ref (&XEXP (*x
, i
), ref
, offset
);
4433 else if (fmt
[i
] == 'E')
4435 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
4436 replace_constant_pool_ref (&XVECEXP (*x
, i
, j
), ref
, offset
);
4441 /* Check whether X contains an UNSPEC_LTREL_BASE.
4442 Return its constant pool symbol if found, NULL_RTX otherwise. */
4445 find_ltrel_base (rtx x
)
4450 if (GET_CODE (x
) == UNSPEC
4451 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
4452 return XVECEXP (x
, 0, 0);
4454 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
4455 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
4459 rtx fnd
= find_ltrel_base (XEXP (x
, i
));
4463 else if (fmt
[i
] == 'E')
4465 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
4467 rtx fnd
= find_ltrel_base (XVECEXP (x
, i
, j
));
4477 /* Replace any occurrence of UNSPEC_LTREL_BASE in X with its base. */
4480 replace_ltrel_base (rtx
*x
)
4485 if (GET_CODE (*x
) == UNSPEC
4486 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
4488 *x
= XVECEXP (*x
, 0, 1);
4492 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
4493 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
4497 replace_ltrel_base (&XEXP (*x
, i
));
4499 else if (fmt
[i
] == 'E')
4501 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
4502 replace_ltrel_base (&XVECEXP (*x
, i
, j
));
4508 /* We keep a list of constants which we have to add to internal
4509 constant tables in the middle of large functions. */
4511 #define NR_C_MODES 7
4512 enum machine_mode constant_modes
[NR_C_MODES
] =
4523 struct constant
*next
;
4528 struct constant_pool
4530 struct constant_pool
*next
;
4535 struct constant
*constants
[NR_C_MODES
];
4536 struct constant
*execute
;
4541 /* Allocate new constant_pool structure. */
4543 static struct constant_pool
*
4544 s390_alloc_pool (void)
4546 struct constant_pool
*pool
;
4549 pool
= (struct constant_pool
*) xmalloc (sizeof *pool
);
4551 for (i
= 0; i
< NR_C_MODES
; i
++)
4552 pool
->constants
[i
] = NULL
;
4554 pool
->execute
= NULL
;
4555 pool
->label
= gen_label_rtx ();
4556 pool
->first_insn
= NULL_RTX
;
4557 pool
->pool_insn
= NULL_RTX
;
4558 pool
->insns
= BITMAP_ALLOC (NULL
);
4564 /* Create new constant pool covering instructions starting at INSN
4565 and chain it to the end of POOL_LIST. */
4567 static struct constant_pool
*
4568 s390_start_pool (struct constant_pool
**pool_list
, rtx insn
)
4570 struct constant_pool
*pool
, **prev
;
4572 pool
= s390_alloc_pool ();
4573 pool
->first_insn
= insn
;
4575 for (prev
= pool_list
; *prev
; prev
= &(*prev
)->next
)
4582 /* End range of instructions covered by POOL at INSN and emit
4583 placeholder insn representing the pool. */
4586 s390_end_pool (struct constant_pool
*pool
, rtx insn
)
4588 rtx pool_size
= GEN_INT (pool
->size
+ 8 /* alignment slop */);
4591 insn
= get_last_insn ();
4593 pool
->pool_insn
= emit_insn_after (gen_pool (pool_size
), insn
);
4594 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
4597 /* Add INSN to the list of insns covered by POOL. */
4600 s390_add_pool_insn (struct constant_pool
*pool
, rtx insn
)
4602 bitmap_set_bit (pool
->insns
, INSN_UID (insn
));
4605 /* Return pool out of POOL_LIST that covers INSN. */
4607 static struct constant_pool
*
4608 s390_find_pool (struct constant_pool
*pool_list
, rtx insn
)
4610 struct constant_pool
*pool
;
4612 for (pool
= pool_list
; pool
; pool
= pool
->next
)
4613 if (bitmap_bit_p (pool
->insns
, INSN_UID (insn
)))
4619 /* Add constant VAL of mode MODE to the constant pool POOL. */
4622 s390_add_constant (struct constant_pool
*pool
, rtx val
, enum machine_mode mode
)
4627 for (i
= 0; i
< NR_C_MODES
; i
++)
4628 if (constant_modes
[i
] == mode
)
4630 gcc_assert (i
!= NR_C_MODES
);
4632 for (c
= pool
->constants
[i
]; c
!= NULL
; c
= c
->next
)
4633 if (rtx_equal_p (val
, c
->value
))
4638 c
= (struct constant
*) xmalloc (sizeof *c
);
4640 c
->label
= gen_label_rtx ();
4641 c
->next
= pool
->constants
[i
];
4642 pool
->constants
[i
] = c
;
4643 pool
->size
+= GET_MODE_SIZE (mode
);
4647 /* Find constant VAL of mode MODE in the constant pool POOL.
4648 Return an RTX describing the distance from the start of
4649 the pool to the location of the new constant. */
4652 s390_find_constant (struct constant_pool
*pool
, rtx val
,
4653 enum machine_mode mode
)
4659 for (i
= 0; i
< NR_C_MODES
; i
++)
4660 if (constant_modes
[i
] == mode
)
4662 gcc_assert (i
!= NR_C_MODES
);
4664 for (c
= pool
->constants
[i
]; c
!= NULL
; c
= c
->next
)
4665 if (rtx_equal_p (val
, c
->value
))
4670 offset
= gen_rtx_MINUS (Pmode
, gen_rtx_LABEL_REF (Pmode
, c
->label
),
4671 gen_rtx_LABEL_REF (Pmode
, pool
->label
));
4672 offset
= gen_rtx_CONST (Pmode
, offset
);
4676 /* Check whether INSN is an execute. Return the label_ref to its
4677 execute target template if so, NULL_RTX otherwise. */
4680 s390_execute_label (rtx insn
)
4682 if (GET_CODE (insn
) == INSN
4683 && GET_CODE (PATTERN (insn
)) == PARALLEL
4684 && GET_CODE (XVECEXP (PATTERN (insn
), 0, 0)) == UNSPEC
4685 && XINT (XVECEXP (PATTERN (insn
), 0, 0), 1) == UNSPEC_EXECUTE
)
4686 return XVECEXP (XVECEXP (PATTERN (insn
), 0, 0), 0, 2);
4691 /* Add execute target for INSN to the constant pool POOL. */
4694 s390_add_execute (struct constant_pool
*pool
, rtx insn
)
4698 for (c
= pool
->execute
; c
!= NULL
; c
= c
->next
)
4699 if (INSN_UID (insn
) == INSN_UID (c
->value
))
4704 c
= (struct constant
*) xmalloc (sizeof *c
);
4706 c
->label
= gen_label_rtx ();
4707 c
->next
= pool
->execute
;
4713 /* Find execute target for INSN in the constant pool POOL.
4714 Return an RTX describing the distance from the start of
4715 the pool to the location of the execute target. */
4718 s390_find_execute (struct constant_pool
*pool
, rtx insn
)
4723 for (c
= pool
->execute
; c
!= NULL
; c
= c
->next
)
4724 if (INSN_UID (insn
) == INSN_UID (c
->value
))
4729 offset
= gen_rtx_MINUS (Pmode
, gen_rtx_LABEL_REF (Pmode
, c
->label
),
4730 gen_rtx_LABEL_REF (Pmode
, pool
->label
));
4731 offset
= gen_rtx_CONST (Pmode
, offset
);
4735 /* For an execute INSN, extract the execute target template. */
4738 s390_execute_target (rtx insn
)
4740 rtx pattern
= PATTERN (insn
);
4741 gcc_assert (s390_execute_label (insn
));
4743 if (XVECLEN (pattern
, 0) == 2)
4745 pattern
= copy_rtx (XVECEXP (pattern
, 0, 1));
4749 rtvec vec
= rtvec_alloc (XVECLEN (pattern
, 0) - 1);
4752 for (i
= 0; i
< XVECLEN (pattern
, 0) - 1; i
++)
4753 RTVEC_ELT (vec
, i
) = copy_rtx (XVECEXP (pattern
, 0, i
+ 1));
4755 pattern
= gen_rtx_PARALLEL (VOIDmode
, vec
);
4761 /* Indicate that INSN cannot be duplicated. This is the case for
4762 execute insns that carry a unique label. */
4765 s390_cannot_copy_insn_p (rtx insn
)
4767 rtx label
= s390_execute_label (insn
);
4768 return label
&& label
!= const0_rtx
;
4771 /* Dump out the constants in POOL. If REMOTE_LABEL is true,
4772 do not emit the pool base label. */
4775 s390_dump_pool (struct constant_pool
*pool
, bool remote_label
)
4778 rtx insn
= pool
->pool_insn
;
4781 /* Switch to rodata section. */
4782 if (TARGET_CPU_ZARCH
)
4784 insn
= emit_insn_after (gen_pool_section_start (), insn
);
4785 INSN_ADDRESSES_NEW (insn
, -1);
4788 /* Ensure minimum pool alignment. */
4789 if (TARGET_CPU_ZARCH
)
4790 insn
= emit_insn_after (gen_pool_align (GEN_INT (8)), insn
);
4792 insn
= emit_insn_after (gen_pool_align (GEN_INT (4)), insn
);
4793 INSN_ADDRESSES_NEW (insn
, -1);
4795 /* Emit pool base label. */
4798 insn
= emit_label_after (pool
->label
, insn
);
4799 INSN_ADDRESSES_NEW (insn
, -1);
4802 /* Dump constants in descending alignment requirement order,
4803 ensuring proper alignment for every constant. */
4804 for (i
= 0; i
< NR_C_MODES
; i
++)
4805 for (c
= pool
->constants
[i
]; c
; c
= c
->next
)
4807 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
4808 rtx value
= c
->value
;
4809 if (GET_CODE (value
) == CONST
4810 && GET_CODE (XEXP (value
, 0)) == UNSPEC
4811 && XINT (XEXP (value
, 0), 1) == UNSPEC_LTREL_OFFSET
4812 && XVECLEN (XEXP (value
, 0), 0) == 1)
4814 value
= gen_rtx_MINUS (Pmode
, XVECEXP (XEXP (value
, 0), 0, 0),
4815 gen_rtx_LABEL_REF (VOIDmode
, pool
->label
));
4816 value
= gen_rtx_CONST (VOIDmode
, value
);
4819 insn
= emit_label_after (c
->label
, insn
);
4820 INSN_ADDRESSES_NEW (insn
, -1);
4822 value
= gen_rtx_UNSPEC_VOLATILE (constant_modes
[i
],
4823 gen_rtvec (1, value
),
4824 UNSPECV_POOL_ENTRY
);
4825 insn
= emit_insn_after (value
, insn
);
4826 INSN_ADDRESSES_NEW (insn
, -1);
4829 /* Ensure minimum alignment for instructions. */
4830 insn
= emit_insn_after (gen_pool_align (GEN_INT (2)), insn
);
4831 INSN_ADDRESSES_NEW (insn
, -1);
4833 /* Output in-pool execute template insns. */
4834 for (c
= pool
->execute
; c
; c
= c
->next
)
4836 insn
= emit_label_after (c
->label
, insn
);
4837 INSN_ADDRESSES_NEW (insn
, -1);
4839 insn
= emit_insn_after (s390_execute_target (c
->value
), insn
);
4840 INSN_ADDRESSES_NEW (insn
, -1);
4843 /* Switch back to previous section. */
4844 if (TARGET_CPU_ZARCH
)
4846 insn
= emit_insn_after (gen_pool_section_end (), insn
);
4847 INSN_ADDRESSES_NEW (insn
, -1);
4850 insn
= emit_barrier_after (insn
);
4851 INSN_ADDRESSES_NEW (insn
, -1);
4853 /* Remove placeholder insn. */
4854 remove_insn (pool
->pool_insn
);
4857 /* Free all memory used by POOL. */
4860 s390_free_pool (struct constant_pool
*pool
)
4862 struct constant
*c
, *next
;
4865 for (i
= 0; i
< NR_C_MODES
; i
++)
4866 for (c
= pool
->constants
[i
]; c
; c
= next
)
4872 for (c
= pool
->execute
; c
; c
= next
)
4878 BITMAP_FREE (pool
->insns
);
4883 /* Collect main literal pool. Return NULL on overflow. */
4885 static struct constant_pool
*
4886 s390_mainpool_start (void)
4888 struct constant_pool
*pool
;
4891 pool
= s390_alloc_pool ();
4893 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
4895 if (GET_CODE (insn
) == INSN
4896 && GET_CODE (PATTERN (insn
)) == SET
4897 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC_VOLATILE
4898 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPECV_MAIN_POOL
)
4900 gcc_assert (!pool
->pool_insn
);
4901 pool
->pool_insn
= insn
;
4904 if (!TARGET_CPU_ZARCH
&& s390_execute_label (insn
))
4906 s390_add_execute (pool
, insn
);
4908 else if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
4910 rtx pool_ref
= NULL_RTX
;
4911 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
4914 rtx constant
= get_pool_constant (pool_ref
);
4915 enum machine_mode mode
= get_pool_mode (pool_ref
);
4916 s390_add_constant (pool
, constant
, mode
);
4921 gcc_assert (pool
->pool_insn
|| pool
->size
== 0);
4923 if (pool
->size
>= 4096)
4925 /* We're going to chunkify the pool, so remove the main
4926 pool placeholder insn. */
4927 remove_insn (pool
->pool_insn
);
4929 s390_free_pool (pool
);
4936 /* POOL holds the main literal pool as collected by s390_mainpool_start.
4937 Modify the current function to output the pool constants as well as
4938 the pool register setup instruction. */
4941 s390_mainpool_finish (struct constant_pool
*pool
)
4943 rtx base_reg
= cfun
->machine
->base_reg
;
4946 /* If the pool is empty, we're done. */
4947 if (pool
->size
== 0)
4949 /* We don't actually need a base register after all. */
4950 cfun
->machine
->base_reg
= NULL_RTX
;
4952 if (pool
->pool_insn
)
4953 remove_insn (pool
->pool_insn
);
4954 s390_free_pool (pool
);
4958 /* We need correct insn addresses. */
4959 shorten_branches (get_insns ());
4961 /* On zSeries, we use a LARL to load the pool register. The pool is
4962 located in the .rodata section, so we emit it after the function. */
4963 if (TARGET_CPU_ZARCH
)
4965 insn
= gen_main_base_64 (base_reg
, pool
->label
);
4966 insn
= emit_insn_after (insn
, pool
->pool_insn
);
4967 INSN_ADDRESSES_NEW (insn
, -1);
4968 remove_insn (pool
->pool_insn
);
4970 insn
= get_last_insn ();
4971 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
4972 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
4974 s390_dump_pool (pool
, 0);
4977 /* On S/390, if the total size of the function's code plus literal pool
4978 does not exceed 4096 bytes, we use BASR to set up a function base
4979 pointer, and emit the literal pool at the end of the function. */
4980 else if (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
4981 + pool
->size
+ 8 /* alignment slop */ < 4096)
4983 insn
= gen_main_base_31_small (base_reg
, pool
->label
);
4984 insn
= emit_insn_after (insn
, pool
->pool_insn
);
4985 INSN_ADDRESSES_NEW (insn
, -1);
4986 remove_insn (pool
->pool_insn
);
4988 insn
= emit_label_after (pool
->label
, insn
);
4989 INSN_ADDRESSES_NEW (insn
, -1);
4991 insn
= get_last_insn ();
4992 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
4993 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
4995 s390_dump_pool (pool
, 1);
4998 /* Otherwise, we emit an inline literal pool and use BASR to branch
4999 over it, setting up the pool register at the same time. */
5002 rtx pool_end
= gen_label_rtx ();
5004 insn
= gen_main_base_31_large (base_reg
, pool
->label
, pool_end
);
5005 insn
= emit_insn_after (insn
, pool
->pool_insn
);
5006 INSN_ADDRESSES_NEW (insn
, -1);
5007 remove_insn (pool
->pool_insn
);
5009 insn
= emit_label_after (pool
->label
, insn
);
5010 INSN_ADDRESSES_NEW (insn
, -1);
5012 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
5013 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
5015 insn
= emit_label_after (pool_end
, pool
->pool_insn
);
5016 INSN_ADDRESSES_NEW (insn
, -1);
5018 s390_dump_pool (pool
, 1);
5022 /* Replace all literal pool references. */
5024 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5027 replace_ltrel_base (&PATTERN (insn
));
5029 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5031 rtx addr
, pool_ref
= NULL_RTX
;
5032 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5035 if (s390_execute_label (insn
))
5036 addr
= s390_find_execute (pool
, insn
);
5038 addr
= s390_find_constant (pool
, get_pool_constant (pool_ref
),
5039 get_pool_mode (pool_ref
));
5041 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
5042 INSN_CODE (insn
) = -1;
5048 /* Free the pool. */
5049 s390_free_pool (pool
);
5052 /* POOL holds the main literal pool as collected by s390_mainpool_start.
5053 We have decided we cannot use this pool, so revert all changes
5054 to the current function that were done by s390_mainpool_start. */
5056 s390_mainpool_cancel (struct constant_pool
*pool
)
5058 /* We didn't actually change the instruction stream, so simply
5059 free the pool memory. */
5060 s390_free_pool (pool
);
5064 /* Chunkify the literal pool. */
5066 #define S390_POOL_CHUNK_MIN 0xc00
5067 #define S390_POOL_CHUNK_MAX 0xe00
5069 static struct constant_pool
*
5070 s390_chunkify_start (void)
5072 struct constant_pool
*curr_pool
= NULL
, *pool_list
= NULL
;
5075 rtx pending_ltrel
= NULL_RTX
;
5078 rtx (*gen_reload_base
) (rtx
, rtx
) =
5079 TARGET_CPU_ZARCH
? gen_reload_base_64
: gen_reload_base_31
;
5082 /* We need correct insn addresses. */
5084 shorten_branches (get_insns ());
5086 /* Scan all insns and move literals to pool chunks. */
5088 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5090 /* Check for pending LTREL_BASE. */
5093 rtx ltrel_base
= find_ltrel_base (PATTERN (insn
));
5096 gcc_assert (ltrel_base
== pending_ltrel
);
5097 pending_ltrel
= NULL_RTX
;
5101 if (!TARGET_CPU_ZARCH
&& s390_execute_label (insn
))
5104 curr_pool
= s390_start_pool (&pool_list
, insn
);
5106 s390_add_execute (curr_pool
, insn
);
5107 s390_add_pool_insn (curr_pool
, insn
);
5109 else if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5111 rtx pool_ref
= NULL_RTX
;
5112 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5115 rtx constant
= get_pool_constant (pool_ref
);
5116 enum machine_mode mode
= get_pool_mode (pool_ref
);
5119 curr_pool
= s390_start_pool (&pool_list
, insn
);
5121 s390_add_constant (curr_pool
, constant
, mode
);
5122 s390_add_pool_insn (curr_pool
, insn
);
5124 /* Don't split the pool chunk between a LTREL_OFFSET load
5125 and the corresponding LTREL_BASE. */
5126 if (GET_CODE (constant
) == CONST
5127 && GET_CODE (XEXP (constant
, 0)) == UNSPEC
5128 && XINT (XEXP (constant
, 0), 1) == UNSPEC_LTREL_OFFSET
)
5130 gcc_assert (!pending_ltrel
);
5131 pending_ltrel
= pool_ref
;
5136 if (GET_CODE (insn
) == JUMP_INSN
|| GET_CODE (insn
) == CODE_LABEL
)
5139 s390_add_pool_insn (curr_pool
, insn
);
5140 /* An LTREL_BASE must follow within the same basic block. */
5141 gcc_assert (!pending_ltrel
);
5145 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn
)
5146 || INSN_ADDRESSES (INSN_UID (insn
)) == -1)
5149 if (TARGET_CPU_ZARCH
)
5151 if (curr_pool
->size
< S390_POOL_CHUNK_MAX
)
5154 s390_end_pool (curr_pool
, NULL_RTX
);
5159 int chunk_size
= INSN_ADDRESSES (INSN_UID (insn
))
5160 - INSN_ADDRESSES (INSN_UID (curr_pool
->first_insn
))
5163 /* We will later have to insert base register reload insns.
5164 Those will have an effect on code size, which we need to
5165 consider here. This calculation makes rather pessimistic
5166 worst-case assumptions. */
5167 if (GET_CODE (insn
) == CODE_LABEL
)
5170 if (chunk_size
< S390_POOL_CHUNK_MIN
5171 && curr_pool
->size
< S390_POOL_CHUNK_MIN
)
5174 /* Pool chunks can only be inserted after BARRIERs ... */
5175 if (GET_CODE (insn
) == BARRIER
)
5177 s390_end_pool (curr_pool
, insn
);
5182 /* ... so if we don't find one in time, create one. */
5183 else if ((chunk_size
> S390_POOL_CHUNK_MAX
5184 || curr_pool
->size
> S390_POOL_CHUNK_MAX
))
5186 rtx label
, jump
, barrier
;
5188 /* We can insert the barrier only after a 'real' insn. */
5189 if (GET_CODE (insn
) != INSN
&& GET_CODE (insn
) != CALL_INSN
)
5191 if (get_attr_length (insn
) == 0)
5194 /* Don't separate LTREL_BASE from the corresponding
5195 LTREL_OFFSET load. */
5199 label
= gen_label_rtx ();
5200 jump
= emit_jump_insn_after (gen_jump (label
), insn
);
5201 barrier
= emit_barrier_after (jump
);
5202 insn
= emit_label_after (label
, barrier
);
5203 JUMP_LABEL (jump
) = label
;
5204 LABEL_NUSES (label
) = 1;
5206 INSN_ADDRESSES_NEW (jump
, -1);
5207 INSN_ADDRESSES_NEW (barrier
, -1);
5208 INSN_ADDRESSES_NEW (insn
, -1);
5210 s390_end_pool (curr_pool
, barrier
);
5218 s390_end_pool (curr_pool
, NULL_RTX
);
5219 gcc_assert (!pending_ltrel
);
5221 /* Find all labels that are branched into
5222 from an insn belonging to a different chunk. */
5224 far_labels
= BITMAP_ALLOC (NULL
);
5226 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5228 /* Labels marked with LABEL_PRESERVE_P can be target
5229 of non-local jumps, so we have to mark them.
5230 The same holds for named labels.
5232 Don't do that, however, if it is the label before
5235 if (GET_CODE (insn
) == CODE_LABEL
5236 && (LABEL_PRESERVE_P (insn
) || LABEL_NAME (insn
)))
5238 rtx vec_insn
= next_real_insn (insn
);
5239 rtx vec_pat
= vec_insn
&& GET_CODE (vec_insn
) == JUMP_INSN
?
5240 PATTERN (vec_insn
) : NULL_RTX
;
5242 || !(GET_CODE (vec_pat
) == ADDR_VEC
5243 || GET_CODE (vec_pat
) == ADDR_DIFF_VEC
))
5244 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (insn
));
5247 /* If we have a direct jump (conditional or unconditional)
5248 or a casesi jump, check all potential targets. */
5249 else if (GET_CODE (insn
) == JUMP_INSN
)
5251 rtx pat
= PATTERN (insn
);
5252 if (GET_CODE (pat
) == PARALLEL
&& XVECLEN (pat
, 0) > 2)
5253 pat
= XVECEXP (pat
, 0, 0);
5255 if (GET_CODE (pat
) == SET
)
5257 rtx label
= JUMP_LABEL (insn
);
5260 if (s390_find_pool (pool_list
, label
)
5261 != s390_find_pool (pool_list
, insn
))
5262 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
5265 else if (GET_CODE (pat
) == PARALLEL
5266 && XVECLEN (pat
, 0) == 2
5267 && GET_CODE (XVECEXP (pat
, 0, 0)) == SET
5268 && GET_CODE (XVECEXP (pat
, 0, 1)) == USE
5269 && GET_CODE (XEXP (XVECEXP (pat
, 0, 1), 0)) == LABEL_REF
)
5271 /* Find the jump table used by this casesi jump. */
5272 rtx vec_label
= XEXP (XEXP (XVECEXP (pat
, 0, 1), 0), 0);
5273 rtx vec_insn
= next_real_insn (vec_label
);
5274 rtx vec_pat
= vec_insn
&& GET_CODE (vec_insn
) == JUMP_INSN
?
5275 PATTERN (vec_insn
) : NULL_RTX
;
5277 && (GET_CODE (vec_pat
) == ADDR_VEC
5278 || GET_CODE (vec_pat
) == ADDR_DIFF_VEC
))
5280 int i
, diff_p
= GET_CODE (vec_pat
) == ADDR_DIFF_VEC
;
5282 for (i
= 0; i
< XVECLEN (vec_pat
, diff_p
); i
++)
5284 rtx label
= XEXP (XVECEXP (vec_pat
, diff_p
, i
), 0);
5286 if (s390_find_pool (pool_list
, label
)
5287 != s390_find_pool (pool_list
, insn
))
5288 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
5295 /* Insert base register reload insns before every pool. */
5297 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
5299 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
5301 rtx insn
= curr_pool
->first_insn
;
5302 INSN_ADDRESSES_NEW (emit_insn_before (new_insn
, insn
), -1);
5305 /* Insert base register reload insns at every far label. */
5307 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5308 if (GET_CODE (insn
) == CODE_LABEL
5309 && bitmap_bit_p (far_labels
, CODE_LABEL_NUMBER (insn
)))
5311 struct constant_pool
*pool
= s390_find_pool (pool_list
, insn
);
5314 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
5316 INSN_ADDRESSES_NEW (emit_insn_after (new_insn
, insn
), -1);
5321 BITMAP_FREE (far_labels
);
5324 /* Recompute insn addresses. */
5326 init_insn_lengths ();
5327 shorten_branches (get_insns ());
5332 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
5333 After we have decided to use this list, finish implementing
5334 all changes to the current function as required. */
5337 s390_chunkify_finish (struct constant_pool
*pool_list
)
5339 struct constant_pool
*curr_pool
= NULL
;
5343 /* Replace all literal pool references. */
5345 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5348 replace_ltrel_base (&PATTERN (insn
));
5350 curr_pool
= s390_find_pool (pool_list
, insn
);
5354 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5356 rtx addr
, pool_ref
= NULL_RTX
;
5357 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5360 if (s390_execute_label (insn
))
5361 addr
= s390_find_execute (curr_pool
, insn
);
5363 addr
= s390_find_constant (curr_pool
,
5364 get_pool_constant (pool_ref
),
5365 get_pool_mode (pool_ref
));
5367 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
5368 INSN_CODE (insn
) = -1;
5373 /* Dump out all literal pools. */
5375 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
5376 s390_dump_pool (curr_pool
, 0);
5378 /* Free pool list. */
5382 struct constant_pool
*next
= pool_list
->next
;
5383 s390_free_pool (pool_list
);
5388 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
5389 We have decided we cannot use this list, so revert all changes
5390 to the current function that were done by s390_chunkify_start. */
5393 s390_chunkify_cancel (struct constant_pool
*pool_list
)
5395 struct constant_pool
*curr_pool
= NULL
;
5398 /* Remove all pool placeholder insns. */
5400 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
5402 /* Did we insert an extra barrier? Remove it. */
5403 rtx barrier
= PREV_INSN (curr_pool
->pool_insn
);
5404 rtx jump
= barrier
? PREV_INSN (barrier
) : NULL_RTX
;
5405 rtx label
= NEXT_INSN (curr_pool
->pool_insn
);
5407 if (jump
&& GET_CODE (jump
) == JUMP_INSN
5408 && barrier
&& GET_CODE (barrier
) == BARRIER
5409 && label
&& GET_CODE (label
) == CODE_LABEL
5410 && GET_CODE (PATTERN (jump
)) == SET
5411 && SET_DEST (PATTERN (jump
)) == pc_rtx
5412 && GET_CODE (SET_SRC (PATTERN (jump
))) == LABEL_REF
5413 && XEXP (SET_SRC (PATTERN (jump
)), 0) == label
)
5416 remove_insn (barrier
);
5417 remove_insn (label
);
5420 remove_insn (curr_pool
->pool_insn
);
5423 /* Remove all base register reload insns. */
5425 for (insn
= get_insns (); insn
; )
5427 rtx next_insn
= NEXT_INSN (insn
);
5429 if (GET_CODE (insn
) == INSN
5430 && GET_CODE (PATTERN (insn
)) == SET
5431 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC
5432 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPEC_RELOAD_BASE
)
5438 /* Free pool list. */
5442 struct constant_pool
*next
= pool_list
->next
;
5443 s390_free_pool (pool_list
);
5449 /* Output the constant pool entry EXP in mode MODE with alignment ALIGN. */
5452 s390_output_pool_entry (rtx exp
, enum machine_mode mode
, unsigned int align
)
5456 switch (GET_MODE_CLASS (mode
))
5459 gcc_assert (GET_CODE (exp
) == CONST_DOUBLE
);
5461 REAL_VALUE_FROM_CONST_DOUBLE (r
, exp
);
5462 assemble_real (r
, mode
, align
);
5466 assemble_integer (exp
, GET_MODE_SIZE (mode
), align
, 1);
5475 /* Return an RTL expression representing the value of the return address
5476 for the frame COUNT steps up from the current frame. FRAME is the
5477 frame pointer of that frame. */
5480 s390_return_addr_rtx (int count
, rtx frame ATTRIBUTE_UNUSED
)
5485 /* Without backchain, we fail for all but the current frame. */
5487 if (!TARGET_BACKCHAIN
&& count
> 0)
5490 /* For the current frame, we need to make sure the initial
5491 value of RETURN_REGNUM is actually saved. */
5495 /* On non-z architectures branch splitting could overwrite r14. */
5496 if (TARGET_CPU_ZARCH
)
5497 return get_hard_reg_initial_val (Pmode
, RETURN_REGNUM
);
5500 cfun_frame_layout
.save_return_addr_p
= true;
5501 return gen_rtx_MEM (Pmode
, return_address_pointer_rtx
);
5505 if (TARGET_PACKED_STACK
)
5506 offset
= -2 * UNITS_PER_WORD
;
5508 offset
= RETURN_REGNUM
* UNITS_PER_WORD
;
5510 addr
= plus_constant (frame
, offset
);
5511 addr
= memory_address (Pmode
, addr
);
5512 return gen_rtx_MEM (Pmode
, addr
);
5515 /* Return an RTL expression representing the back chain stored in
5516 the current stack frame. */
5519 s390_back_chain_rtx (void)
5523 gcc_assert (TARGET_BACKCHAIN
);
5525 if (TARGET_PACKED_STACK
)
5526 chain
= plus_constant (stack_pointer_rtx
,
5527 STACK_POINTER_OFFSET
- UNITS_PER_WORD
);
5529 chain
= stack_pointer_rtx
;
5531 chain
= gen_rtx_MEM (Pmode
, chain
);
5535 /* Find first call clobbered register unused in a function.
5536 This could be used as base register in a leaf function
5537 or for holding the return address before epilogue. */
5540 find_unused_clobbered_reg (void)
5543 for (i
= 0; i
< 6; i
++)
5544 if (!regs_ever_live
[i
])
5550 /* Helper function for s390_regs_ever_clobbered. Sets the fields in DATA for all
5551 clobbered hard regs in SETREG. */
5554 s390_reg_clobbered_rtx (rtx setreg
, rtx set_insn ATTRIBUTE_UNUSED
, void *data
)
5556 int *regs_ever_clobbered
= (int *)data
;
5557 unsigned int i
, regno
;
5558 enum machine_mode mode
= GET_MODE (setreg
);
5560 if (GET_CODE (setreg
) == SUBREG
)
5562 rtx inner
= SUBREG_REG (setreg
);
5563 if (!GENERAL_REG_P (inner
))
5565 regno
= subreg_regno (setreg
);
5567 else if (GENERAL_REG_P (setreg
))
5568 regno
= REGNO (setreg
);
5573 i
< regno
+ HARD_REGNO_NREGS (regno
, mode
);
5575 regs_ever_clobbered
[i
] = 1;
5578 /* Walks through all basic blocks of the current function looking
5579 for clobbered hard regs using s390_reg_clobbered_rtx. The fields
5580 of the passed integer array REGS_EVER_CLOBBERED are set to one for
5581 each of those regs. */
5584 s390_regs_ever_clobbered (int *regs_ever_clobbered
)
5590 memset (regs_ever_clobbered
, 0, 16 * sizeof (int));
5592 /* For non-leaf functions we have to consider all call clobbered regs to be
5594 if (!current_function_is_leaf
)
5596 for (i
= 0; i
< 16; i
++)
5597 regs_ever_clobbered
[i
] = call_really_used_regs
[i
];
5600 /* Make the "magic" eh_return registers live if necessary. For regs_ever_live
5601 this work is done by liveness analysis (mark_regs_live_at_end).
5602 Special care is needed for functions containing landing pads. Landing pads
5603 may use the eh registers, but the code which sets these registers is not
5604 contained in that function. Hence s390_regs_ever_clobbered is not able to
5605 deal with this automatically. */
5606 if (current_function_calls_eh_return
|| cfun
->machine
->has_landing_pad_p
)
5607 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; i
++)
5608 regs_ever_clobbered
[EH_RETURN_DATA_REGNO (i
)] = 1;
5610 /* For nonlocal gotos all call-saved registers have to be saved.
5611 This flag is also set for the unwinding code in libgcc.
5612 See expand_builtin_unwind_init. For regs_ever_live this is done by
5614 if (current_function_has_nonlocal_label
)
5615 for (i
= 0; i
< 16; i
++)
5616 if (!call_really_used_regs
[i
])
5617 regs_ever_clobbered
[i
] = 1;
5619 FOR_EACH_BB (cur_bb
)
5621 FOR_BB_INSNS (cur_bb
, cur_insn
)
5623 if (INSN_P (cur_insn
))
5624 note_stores (PATTERN (cur_insn
),
5625 s390_reg_clobbered_rtx
,
5626 regs_ever_clobbered
);
5631 /* Determine the frame area which actually has to be accessed
5632 in the function epilogue. The values are stored at the
5633 given pointers AREA_BOTTOM (address of the lowest used stack
5634 address) and AREA_TOP (address of the first item which does
5635 not belong to the stack frame). */
5638 s390_frame_area (int *area_bottom
, int *area_top
)
5646 if (cfun_frame_layout
.first_restore_gpr
!= -1)
5648 b
= (cfun_frame_layout
.gprs_offset
5649 + cfun_frame_layout
.first_restore_gpr
* UNITS_PER_WORD
);
5650 t
= b
+ (cfun_frame_layout
.last_restore_gpr
5651 - cfun_frame_layout
.first_restore_gpr
+ 1) * UNITS_PER_WORD
;
5654 if (TARGET_64BIT
&& cfun_save_high_fprs_p
)
5656 b
= MIN (b
, cfun_frame_layout
.f8_offset
);
5657 t
= MAX (t
, (cfun_frame_layout
.f8_offset
5658 + cfun_frame_layout
.high_fprs
* 8));
5662 for (i
= 2; i
< 4; i
++)
5663 if (cfun_fpr_bit_p (i
))
5665 b
= MIN (b
, cfun_frame_layout
.f4_offset
+ (i
- 2) * 8);
5666 t
= MAX (t
, cfun_frame_layout
.f4_offset
+ (i
- 1) * 8);
5673 /* Fill cfun->machine with info about register usage of current function.
5674 Return in CLOBBERED_REGS which GPRs are currently considered set. */
5677 s390_register_info (int clobbered_regs
[])
5681 /* fprs 8 - 15 are call saved for 64 Bit ABI. */
5682 cfun_frame_layout
.fpr_bitmap
= 0;
5683 cfun_frame_layout
.high_fprs
= 0;
5685 for (i
= 24; i
< 32; i
++)
5686 if (regs_ever_live
[i
] && !global_regs
[i
])
5688 cfun_set_fpr_bit (i
- 16);
5689 cfun_frame_layout
.high_fprs
++;
5692 /* Find first and last gpr to be saved. We trust regs_ever_live
5693 data, except that we don't save and restore global registers.
5695 Also, all registers with special meaning to the compiler need
5696 to be handled extra. */
5698 s390_regs_ever_clobbered (clobbered_regs
);
5700 for (i
= 0; i
< 16; i
++)
5701 clobbered_regs
[i
] = clobbered_regs
[i
] && !global_regs
[i
];
5703 if (frame_pointer_needed
)
5704 clobbered_regs
[HARD_FRAME_POINTER_REGNUM
] = 1;
5707 clobbered_regs
[PIC_OFFSET_TABLE_REGNUM
]
5708 = regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
];
5710 clobbered_regs
[BASE_REGNUM
]
5711 = cfun
->machine
->base_reg
5712 && REGNO (cfun
->machine
->base_reg
) == BASE_REGNUM
;
5714 clobbered_regs
[RETURN_REGNUM
]
5715 = cfun
->machine
->split_branches_pending_p
5716 || cfun_frame_layout
.save_return_addr_p
;
5718 clobbered_regs
[STACK_POINTER_REGNUM
]
5719 = !current_function_is_leaf
5720 || TARGET_TPF_PROFILING
5721 || cfun_save_high_fprs_p
5722 || get_frame_size () > 0
5723 || current_function_calls_alloca
5724 || current_function_stdarg
;
5726 for (i
= 6; i
< 16; i
++)
5727 if (clobbered_regs
[i
])
5729 for (j
= 15; j
> i
; j
--)
5730 if (clobbered_regs
[j
])
5735 /* Nothing to save/restore. */
5736 cfun_frame_layout
.first_save_gpr
= -1;
5737 cfun_frame_layout
.first_restore_gpr
= -1;
5738 cfun_frame_layout
.last_save_gpr
= -1;
5739 cfun_frame_layout
.last_restore_gpr
= -1;
5743 /* Save / Restore from gpr i to j. */
5744 cfun_frame_layout
.first_save_gpr
= i
;
5745 cfun_frame_layout
.first_restore_gpr
= i
;
5746 cfun_frame_layout
.last_save_gpr
= j
;
5747 cfun_frame_layout
.last_restore_gpr
= j
;
5750 if (current_function_stdarg
)
5752 /* Varargs functions need to save gprs 2 to 6. */
5753 if (cfun
->va_list_gpr_size
5754 && current_function_args_info
.gprs
< GP_ARG_NUM_REG
)
5756 int min_gpr
= current_function_args_info
.gprs
;
5757 int max_gpr
= min_gpr
+ cfun
->va_list_gpr_size
;
5758 if (max_gpr
> GP_ARG_NUM_REG
)
5759 max_gpr
= GP_ARG_NUM_REG
;
5761 if (cfun_frame_layout
.first_save_gpr
== -1
5762 || cfun_frame_layout
.first_save_gpr
> 2 + min_gpr
)
5763 cfun_frame_layout
.first_save_gpr
= 2 + min_gpr
;
5765 if (cfun_frame_layout
.last_save_gpr
== -1
5766 || cfun_frame_layout
.last_save_gpr
< 2 + max_gpr
- 1)
5767 cfun_frame_layout
.last_save_gpr
= 2 + max_gpr
- 1;
5770 /* Mark f0, f2 for 31 bit and f0-f4 for 64 bit to be saved. */
5771 if (TARGET_HARD_FLOAT
&& cfun
->va_list_fpr_size
5772 && current_function_args_info
.fprs
< FP_ARG_NUM_REG
)
5774 int min_fpr
= current_function_args_info
.fprs
;
5775 int max_fpr
= min_fpr
+ cfun
->va_list_fpr_size
;
5776 if (max_fpr
> FP_ARG_NUM_REG
)
5777 max_fpr
= FP_ARG_NUM_REG
;
5779 /* ??? This is currently required to ensure proper location
5780 of the fpr save slots within the va_list save area. */
5781 if (TARGET_PACKED_STACK
)
5784 for (i
= min_fpr
; i
< max_fpr
; i
++)
5785 cfun_set_fpr_bit (i
);
5790 for (i
= 2; i
< 4; i
++)
5791 if (regs_ever_live
[i
+ 16] && !global_regs
[i
+ 16])
5792 cfun_set_fpr_bit (i
);
5795 /* Fill cfun->machine with info about frame of current function. */
5798 s390_frame_info (void)
5802 cfun_frame_layout
.frame_size
= get_frame_size ();
5803 if (!TARGET_64BIT
&& cfun_frame_layout
.frame_size
> 0x7fff0000)
5804 fatal_error ("Total size of local variables exceeds architecture limit.");
5806 if (!TARGET_PACKED_STACK
)
5808 cfun_frame_layout
.backchain_offset
= 0;
5809 cfun_frame_layout
.f0_offset
= 16 * UNITS_PER_WORD
;
5810 cfun_frame_layout
.f4_offset
= cfun_frame_layout
.f0_offset
+ 2 * 8;
5811 cfun_frame_layout
.f8_offset
= -cfun_frame_layout
.high_fprs
* 8;
5812 cfun_frame_layout
.gprs_offset
= (cfun_frame_layout
.first_save_gpr
5815 else if (TARGET_BACKCHAIN
) /* kernel stack layout */
5817 cfun_frame_layout
.backchain_offset
= (STACK_POINTER_OFFSET
5819 cfun_frame_layout
.gprs_offset
5820 = (cfun_frame_layout
.backchain_offset
5821 - (STACK_POINTER_REGNUM
- cfun_frame_layout
.first_save_gpr
+ 1)
5826 cfun_frame_layout
.f4_offset
5827 = (cfun_frame_layout
.gprs_offset
5828 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
5830 cfun_frame_layout
.f0_offset
5831 = (cfun_frame_layout
.f4_offset
5832 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
5836 /* On 31 bit we have to care about alignment of the
5837 floating point regs to provide fastest access. */
5838 cfun_frame_layout
.f0_offset
5839 = ((cfun_frame_layout
.gprs_offset
5840 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1))
5841 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
5843 cfun_frame_layout
.f4_offset
5844 = (cfun_frame_layout
.f0_offset
5845 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
5848 else /* no backchain */
5850 cfun_frame_layout
.f4_offset
5851 = (STACK_POINTER_OFFSET
5852 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
5854 cfun_frame_layout
.f0_offset
5855 = (cfun_frame_layout
.f4_offset
5856 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
5858 cfun_frame_layout
.gprs_offset
5859 = cfun_frame_layout
.f0_offset
- cfun_gprs_save_area_size
;
5862 if (current_function_is_leaf
5863 && !TARGET_TPF_PROFILING
5864 && cfun_frame_layout
.frame_size
== 0
5865 && !cfun_save_high_fprs_p
5866 && !current_function_calls_alloca
5867 && !current_function_stdarg
)
5870 if (!TARGET_PACKED_STACK
)
5871 cfun_frame_layout
.frame_size
+= (STACK_POINTER_OFFSET
5872 + current_function_outgoing_args_size
5873 + cfun_frame_layout
.high_fprs
* 8);
5876 if (TARGET_BACKCHAIN
)
5877 cfun_frame_layout
.frame_size
+= UNITS_PER_WORD
;
5879 /* No alignment trouble here because f8-f15 are only saved under
5881 cfun_frame_layout
.f8_offset
= (MIN (MIN (cfun_frame_layout
.f0_offset
,
5882 cfun_frame_layout
.f4_offset
),
5883 cfun_frame_layout
.gprs_offset
)
5884 - cfun_frame_layout
.high_fprs
* 8);
5886 cfun_frame_layout
.frame_size
+= cfun_frame_layout
.high_fprs
* 8;
5888 for (i
= 0; i
< 8; i
++)
5889 if (cfun_fpr_bit_p (i
))
5890 cfun_frame_layout
.frame_size
+= 8;
5892 cfun_frame_layout
.frame_size
+= cfun_gprs_save_area_size
;
5894 /* If under 31 bit an odd number of gprs has to be saved we have to adjust
5895 the frame size to sustain 8 byte alignment of stack frames. */
5896 cfun_frame_layout
.frame_size
= ((cfun_frame_layout
.frame_size
+
5897 STACK_BOUNDARY
/ BITS_PER_UNIT
- 1)
5898 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1));
5900 cfun_frame_layout
.frame_size
+= current_function_outgoing_args_size
;
5904 /* Generate frame layout. Fills in register and frame data for the current
5905 function in cfun->machine. This routine can be called multiple times;
5906 it will re-do the complete frame layout every time. */
5909 s390_init_frame_layout (void)
5911 HOST_WIDE_INT frame_size
;
5913 int clobbered_regs
[16];
5915 /* If return address register is explicitly used, we need to save it. */
5916 s390_regs_ever_clobbered (clobbered_regs
);
5918 if (clobbered_regs
[RETURN_REGNUM
]
5919 || !current_function_is_leaf
5920 || TARGET_TPF_PROFILING
5921 || current_function_stdarg
5922 || current_function_calls_eh_return
)
5923 cfun_frame_layout
.save_return_addr_p
= true;
5925 /* On S/390 machines, we may need to perform branch splitting, which
5926 will require both base and return address register. We have no
5927 choice but to assume we're going to need them until right at the
5928 end of the machine dependent reorg phase. */
5929 if (!TARGET_CPU_ZARCH
)
5930 cfun
->machine
->split_branches_pending_p
= true;
5934 frame_size
= cfun_frame_layout
.frame_size
;
5936 /* Try to predict whether we'll need the base register. */
5937 base_used
= cfun
->machine
->split_branches_pending_p
5938 || current_function_uses_const_pool
5939 || (!DISP_IN_RANGE (-frame_size
)
5940 && !CONST_OK_FOR_CONSTRAINT_P (-frame_size
, 'K', "K"));
5942 /* Decide which register to use as literal pool base. In small
5943 leaf functions, try to use an unused call-clobbered register
5944 as base register to avoid save/restore overhead. */
5946 cfun
->machine
->base_reg
= NULL_RTX
;
5947 else if (current_function_is_leaf
&& !regs_ever_live
[5])
5948 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, 5);
5950 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
5952 s390_register_info (clobbered_regs
);
5955 while (frame_size
!= cfun_frame_layout
.frame_size
);
5958 /* Update frame layout. Recompute actual register save data based on
5959 current info and update regs_ever_live for the special registers.
5960 May be called multiple times, but may never cause *more* registers
5961 to be saved than s390_init_frame_layout allocated room for. */
5964 s390_update_frame_layout (void)
5966 int clobbered_regs
[16];
5968 s390_register_info (clobbered_regs
);
5970 regs_ever_live
[BASE_REGNUM
] = clobbered_regs
[BASE_REGNUM
];
5971 regs_ever_live
[RETURN_REGNUM
] = clobbered_regs
[RETURN_REGNUM
];
5972 regs_ever_live
[STACK_POINTER_REGNUM
] = clobbered_regs
[STACK_POINTER_REGNUM
];
5974 if (cfun
->machine
->base_reg
)
5975 regs_ever_live
[REGNO (cfun
->machine
->base_reg
)] = 1;
5978 /* Return true if register FROM can be eliminated via register TO. */
5981 s390_can_eliminate (int from
, int to
)
5983 gcc_assert (to
== STACK_POINTER_REGNUM
5984 || to
== HARD_FRAME_POINTER_REGNUM
);
5986 gcc_assert (from
== FRAME_POINTER_REGNUM
5987 || from
== ARG_POINTER_REGNUM
5988 || from
== RETURN_ADDRESS_POINTER_REGNUM
);
5990 /* Make sure we actually saved the return address. */
5991 if (from
== RETURN_ADDRESS_POINTER_REGNUM
)
5992 if (!current_function_calls_eh_return
5993 && !current_function_stdarg
5994 && !cfun_frame_layout
.save_return_addr_p
)
6000 /* Return offset between register FROM and TO initially after prolog. */
6003 s390_initial_elimination_offset (int from
, int to
)
6005 HOST_WIDE_INT offset
;
6008 /* ??? Why are we called for non-eliminable pairs? */
6009 if (!s390_can_eliminate (from
, to
))
6014 case FRAME_POINTER_REGNUM
:
6015 offset
= (get_frame_size()
6016 + STACK_POINTER_OFFSET
6017 + current_function_outgoing_args_size
);
6020 case ARG_POINTER_REGNUM
:
6021 s390_init_frame_layout ();
6022 offset
= cfun_frame_layout
.frame_size
+ STACK_POINTER_OFFSET
;
6025 case RETURN_ADDRESS_POINTER_REGNUM
:
6026 s390_init_frame_layout ();
6027 index
= RETURN_REGNUM
- cfun_frame_layout
.first_save_gpr
;
6028 gcc_assert (index
>= 0);
6029 offset
= cfun_frame_layout
.frame_size
+ cfun_frame_layout
.gprs_offset
;
6030 offset
+= index
* UNITS_PER_WORD
;
6040 /* Emit insn to save fpr REGNUM at offset OFFSET relative
6041 to register BASE. Return generated insn. */
6044 save_fpr (rtx base
, int offset
, int regnum
)
6047 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
6048 set_mem_alias_set (addr
, s390_sr_alias_set
);
6050 return emit_move_insn (addr
, gen_rtx_REG (DFmode
, regnum
));
6053 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
6054 to register BASE. Return generated insn. */
6057 restore_fpr (rtx base
, int offset
, int regnum
)
6060 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
6061 set_mem_alias_set (addr
, s390_sr_alias_set
);
6063 return emit_move_insn (gen_rtx_REG (DFmode
, regnum
), addr
);
6066 /* Generate insn to save registers FIRST to LAST into
6067 the register save area located at offset OFFSET
6068 relative to register BASE. */
6071 save_gprs (rtx base
, int offset
, int first
, int last
)
6073 rtx addr
, insn
, note
;
6076 addr
= plus_constant (base
, offset
);
6077 addr
= gen_rtx_MEM (Pmode
, addr
);
6078 set_mem_alias_set (addr
, s390_sr_alias_set
);
6080 /* Special-case single register. */
6084 insn
= gen_movdi (addr
, gen_rtx_REG (Pmode
, first
));
6086 insn
= gen_movsi (addr
, gen_rtx_REG (Pmode
, first
));
6088 RTX_FRAME_RELATED_P (insn
) = 1;
6093 insn
= gen_store_multiple (addr
,
6094 gen_rtx_REG (Pmode
, first
),
6095 GEN_INT (last
- first
+ 1));
6098 /* We need to set the FRAME_RELATED flag on all SETs
6099 inside the store-multiple pattern.
6101 However, we must not emit DWARF records for registers 2..5
6102 if they are stored for use by variable arguments ...
6104 ??? Unfortunately, it is not enough to simply not the the
6105 FRAME_RELATED flags for those SETs, because the first SET
6106 of the PARALLEL is always treated as if it had the flag
6107 set, even if it does not. Therefore we emit a new pattern
6108 without those registers as REG_FRAME_RELATED_EXPR note. */
6112 rtx pat
= PATTERN (insn
);
6114 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
6115 if (GET_CODE (XVECEXP (pat
, 0, i
)) == SET
)
6116 RTX_FRAME_RELATED_P (XVECEXP (pat
, 0, i
)) = 1;
6118 RTX_FRAME_RELATED_P (insn
) = 1;
6122 addr
= plus_constant (base
, offset
+ (6 - first
) * UNITS_PER_WORD
);
6123 note
= gen_store_multiple (gen_rtx_MEM (Pmode
, addr
),
6124 gen_rtx_REG (Pmode
, 6),
6125 GEN_INT (last
- 6 + 1));
6126 note
= PATTERN (note
);
6129 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
6130 note
, REG_NOTES (insn
));
6132 for (i
= 0; i
< XVECLEN (note
, 0); i
++)
6133 if (GET_CODE (XVECEXP (note
, 0, i
)) == SET
)
6134 RTX_FRAME_RELATED_P (XVECEXP (note
, 0, i
)) = 1;
6136 RTX_FRAME_RELATED_P (insn
) = 1;
6142 /* Generate insn to restore registers FIRST to LAST from
6143 the register save area located at offset OFFSET
6144 relative to register BASE. */
6147 restore_gprs (rtx base
, int offset
, int first
, int last
)
6151 addr
= plus_constant (base
, offset
);
6152 addr
= gen_rtx_MEM (Pmode
, addr
);
6153 set_mem_alias_set (addr
, s390_sr_alias_set
);
6155 /* Special-case single register. */
6159 insn
= gen_movdi (gen_rtx_REG (Pmode
, first
), addr
);
6161 insn
= gen_movsi (gen_rtx_REG (Pmode
, first
), addr
);
6166 insn
= gen_load_multiple (gen_rtx_REG (Pmode
, first
),
6168 GEN_INT (last
- first
+ 1));
6172 /* Return insn sequence to load the GOT register. */
6174 static GTY(()) rtx got_symbol
;
6176 s390_load_got (void)
6182 got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
6183 SYMBOL_REF_FLAGS (got_symbol
) = SYMBOL_FLAG_LOCAL
;
6188 if (TARGET_CPU_ZARCH
)
6190 emit_move_insn (pic_offset_table_rtx
, got_symbol
);
6196 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, got_symbol
),
6197 UNSPEC_LTREL_OFFSET
);
6198 offset
= gen_rtx_CONST (Pmode
, offset
);
6199 offset
= force_const_mem (Pmode
, offset
);
6201 emit_move_insn (pic_offset_table_rtx
, offset
);
6203 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, XEXP (offset
, 0)),
6205 offset
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, offset
);
6207 emit_move_insn (pic_offset_table_rtx
, offset
);
6210 insns
= get_insns ();
6215 /* Expand the prologue into a bunch of separate insns. */
6218 s390_emit_prologue (void)
6226 /* Complete frame layout. */
6228 s390_update_frame_layout ();
6230 /* Annotate all constant pool references to let the scheduler know
6231 they implicitly use the base register. */
6233 push_topmost_sequence ();
6235 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6237 annotate_constant_pool_refs (&PATTERN (insn
));
6239 pop_topmost_sequence ();
6241 /* Choose best register to use for temp use within prologue.
6242 See below for why TPF must use the register 1. */
6244 if (!has_hard_reg_initial_val (Pmode
, RETURN_REGNUM
)
6245 && !current_function_is_leaf
6246 && !TARGET_TPF_PROFILING
)
6247 temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
6249 temp_reg
= gen_rtx_REG (Pmode
, 1);
6251 /* Save call saved gprs. */
6252 if (cfun_frame_layout
.first_save_gpr
!= -1)
6254 insn
= save_gprs (stack_pointer_rtx
,
6255 cfun_frame_layout
.gprs_offset
,
6256 cfun_frame_layout
.first_save_gpr
,
6257 cfun_frame_layout
.last_save_gpr
);
6261 /* Dummy insn to mark literal pool slot. */
6263 if (cfun
->machine
->base_reg
)
6264 emit_insn (gen_main_pool (cfun
->machine
->base_reg
));
6266 offset
= cfun_frame_layout
.f0_offset
;
6268 /* Save f0 and f2. */
6269 for (i
= 0; i
< 2; i
++)
6271 if (cfun_fpr_bit_p (i
))
6273 save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
6276 else if (!TARGET_PACKED_STACK
)
6280 /* Save f4 and f6. */
6281 offset
= cfun_frame_layout
.f4_offset
;
6282 for (i
= 2; i
< 4; i
++)
6284 if (cfun_fpr_bit_p (i
))
6286 insn
= save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
6289 /* If f4 and f6 are call clobbered they are saved due to stdargs and
6290 therefore are not frame related. */
6291 if (!call_really_used_regs
[i
+ 16])
6292 RTX_FRAME_RELATED_P (insn
) = 1;
6294 else if (!TARGET_PACKED_STACK
)
6298 if (TARGET_PACKED_STACK
6299 && cfun_save_high_fprs_p
6300 && cfun_frame_layout
.f8_offset
+ cfun_frame_layout
.high_fprs
* 8 > 0)
6302 offset
= (cfun_frame_layout
.f8_offset
6303 + (cfun_frame_layout
.high_fprs
- 1) * 8);
6305 for (i
= 15; i
> 7 && offset
>= 0; i
--)
6306 if (cfun_fpr_bit_p (i
))
6308 insn
= save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
6310 RTX_FRAME_RELATED_P (insn
) = 1;
6313 if (offset
>= cfun_frame_layout
.f8_offset
)
6317 if (!TARGET_PACKED_STACK
)
6318 next_fpr
= cfun_save_high_fprs_p
? 31 : 0;
6320 /* Decrement stack pointer. */
6322 if (cfun_frame_layout
.frame_size
> 0)
6324 rtx frame_off
= GEN_INT (-cfun_frame_layout
.frame_size
);
6326 if (s390_stack_size
)
6328 HOST_WIDE_INT stack_check_mask
= ((s390_stack_size
- 1)
6329 & ~(s390_stack_guard
- 1));
6330 rtx t
= gen_rtx_AND (Pmode
, stack_pointer_rtx
,
6331 GEN_INT (stack_check_mask
));
6334 gen_cmpdi (t
, const0_rtx
);
6336 gen_cmpsi (t
, const0_rtx
);
6338 emit_insn (gen_conditional_trap (gen_rtx_EQ (CCmode
,
6339 gen_rtx_REG (CCmode
,
6345 if (s390_warn_framesize
> 0
6346 && cfun_frame_layout
.frame_size
>= s390_warn_framesize
)
6347 warning (0, "frame size of %qs is " HOST_WIDE_INT_PRINT_DEC
" bytes",
6348 current_function_name (), cfun_frame_layout
.frame_size
);
6350 if (s390_warn_dynamicstack_p
&& cfun
->calls_alloca
)
6351 warning (0, "%qs uses dynamic stack allocation", current_function_name ());
6353 /* Save incoming stack pointer into temp reg. */
6354 if (TARGET_BACKCHAIN
|| next_fpr
)
6355 insn
= emit_insn (gen_move_insn (temp_reg
, stack_pointer_rtx
));
6357 /* Subtract frame size from stack pointer. */
6359 if (DISP_IN_RANGE (INTVAL (frame_off
)))
6361 insn
= gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
6362 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
6364 insn
= emit_insn (insn
);
6368 if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off
), 'K', "K"))
6369 frame_off
= force_const_mem (Pmode
, frame_off
);
6371 insn
= emit_insn (gen_add2_insn (stack_pointer_rtx
, frame_off
));
6372 annotate_constant_pool_refs (&PATTERN (insn
));
6375 RTX_FRAME_RELATED_P (insn
) = 1;
6377 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
6378 gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
6379 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
6380 GEN_INT (-cfun_frame_layout
.frame_size
))),
6383 /* Set backchain. */
6385 if (TARGET_BACKCHAIN
)
6387 if (cfun_frame_layout
.backchain_offset
)
6388 addr
= gen_rtx_MEM (Pmode
,
6389 plus_constant (stack_pointer_rtx
,
6390 cfun_frame_layout
.backchain_offset
));
6392 addr
= gen_rtx_MEM (Pmode
, stack_pointer_rtx
);
6393 set_mem_alias_set (addr
, s390_sr_alias_set
);
6394 insn
= emit_insn (gen_move_insn (addr
, temp_reg
));
6397 /* If we support asynchronous exceptions (e.g. for Java),
6398 we need to make sure the backchain pointer is set up
6399 before any possibly trapping memory access. */
6401 if (TARGET_BACKCHAIN
&& flag_non_call_exceptions
)
6403 addr
= gen_rtx_MEM (BLKmode
, gen_rtx_SCRATCH (VOIDmode
));
6404 emit_insn (gen_rtx_CLOBBER (VOIDmode
, addr
));
6408 /* Save fprs 8 - 15 (64 bit ABI). */
6410 if (cfun_save_high_fprs_p
&& next_fpr
)
6412 insn
= emit_insn (gen_add2_insn (temp_reg
,
6413 GEN_INT (cfun_frame_layout
.f8_offset
)));
6417 for (i
= 24; i
<= next_fpr
; i
++)
6418 if (cfun_fpr_bit_p (i
- 16))
6420 rtx addr
= plus_constant (stack_pointer_rtx
,
6421 cfun_frame_layout
.frame_size
6422 + cfun_frame_layout
.f8_offset
6425 insn
= save_fpr (temp_reg
, offset
, i
);
6427 RTX_FRAME_RELATED_P (insn
) = 1;
6429 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
6430 gen_rtx_SET (VOIDmode
,
6431 gen_rtx_MEM (DFmode
, addr
),
6432 gen_rtx_REG (DFmode
, i
)),
6437 /* Set frame pointer, if needed. */
6439 if (frame_pointer_needed
)
6441 insn
= emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
);
6442 RTX_FRAME_RELATED_P (insn
) = 1;
6445 /* Set up got pointer, if needed. */
6447 if (flag_pic
&& regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
])
6449 rtx insns
= s390_load_got ();
6451 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
6453 annotate_constant_pool_refs (&PATTERN (insn
));
6455 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD
, NULL_RTX
,
6462 if (TARGET_TPF_PROFILING
)
6464 /* Generate a BAS instruction to serve as a function
6465 entry intercept to facilitate the use of tracing
6466 algorithms located at the branch target. */
6467 emit_insn (gen_prologue_tpf ());
6469 /* Emit a blockage here so that all code
6470 lies between the profiling mechanisms. */
6471 emit_insn (gen_blockage ());
6475 /* Expand the epilogue into a bunch of separate insns. */
6478 s390_emit_epilogue (bool sibcall
)
6480 rtx frame_pointer
, return_reg
;
6481 int area_bottom
, area_top
, offset
= 0;
6486 if (TARGET_TPF_PROFILING
)
6489 /* Generate a BAS instruction to serve as a function
6490 entry intercept to facilitate the use of tracing
6491 algorithms located at the branch target. */
6493 /* Emit a blockage here so that all code
6494 lies between the profiling mechanisms. */
6495 emit_insn (gen_blockage ());
6497 emit_insn (gen_epilogue_tpf ());
6500 /* Check whether to use frame or stack pointer for restore. */
6502 frame_pointer
= (frame_pointer_needed
6503 ? hard_frame_pointer_rtx
: stack_pointer_rtx
);
6505 s390_frame_area (&area_bottom
, &area_top
);
6507 /* Check whether we can access the register save area.
6508 If not, increment the frame pointer as required. */
6510 if (area_top
<= area_bottom
)
6512 /* Nothing to restore. */
6514 else if (DISP_IN_RANGE (cfun_frame_layout
.frame_size
+ area_bottom
)
6515 && DISP_IN_RANGE (cfun_frame_layout
.frame_size
+ area_top
- 1))
6517 /* Area is in range. */
6518 offset
= cfun_frame_layout
.frame_size
;
6522 rtx insn
, frame_off
;
6524 offset
= area_bottom
< 0 ? -area_bottom
: 0;
6525 frame_off
= GEN_INT (cfun_frame_layout
.frame_size
- offset
);
6527 if (DISP_IN_RANGE (INTVAL (frame_off
)))
6529 insn
= gen_rtx_SET (VOIDmode
, frame_pointer
,
6530 gen_rtx_PLUS (Pmode
, frame_pointer
, frame_off
));
6531 insn
= emit_insn (insn
);
6535 if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off
), 'K', "K"))
6536 frame_off
= force_const_mem (Pmode
, frame_off
);
6538 insn
= emit_insn (gen_add2_insn (frame_pointer
, frame_off
));
6539 annotate_constant_pool_refs (&PATTERN (insn
));
6543 /* Restore call saved fprs. */
6547 if (cfun_save_high_fprs_p
)
6549 next_offset
= cfun_frame_layout
.f8_offset
;
6550 for (i
= 24; i
< 32; i
++)
6552 if (cfun_fpr_bit_p (i
- 16))
6554 restore_fpr (frame_pointer
,
6555 offset
+ next_offset
, i
);
6564 next_offset
= cfun_frame_layout
.f4_offset
;
6565 for (i
= 18; i
< 20; i
++)
6567 if (cfun_fpr_bit_p (i
- 16))
6569 restore_fpr (frame_pointer
,
6570 offset
+ next_offset
, i
);
6573 else if (!TARGET_PACKED_STACK
)
6579 /* Return register. */
6581 return_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
6583 /* Restore call saved gprs. */
6585 if (cfun_frame_layout
.first_restore_gpr
!= -1)
6590 /* Check for global register and save them
6591 to stack location from where they get restored. */
6593 for (i
= cfun_frame_layout
.first_restore_gpr
;
6594 i
<= cfun_frame_layout
.last_restore_gpr
;
6597 /* These registers are special and need to be
6598 restored in any case. */
6599 if (i
== STACK_POINTER_REGNUM
6600 || i
== RETURN_REGNUM
6602 || (flag_pic
&& i
== (int)PIC_OFFSET_TABLE_REGNUM
))
6607 addr
= plus_constant (frame_pointer
,
6608 offset
+ cfun_frame_layout
.gprs_offset
6609 + (i
- cfun_frame_layout
.first_save_gpr
)
6611 addr
= gen_rtx_MEM (Pmode
, addr
);
6612 set_mem_alias_set (addr
, s390_sr_alias_set
);
6613 emit_move_insn (addr
, gen_rtx_REG (Pmode
, i
));
6619 /* Fetch return address from stack before load multiple,
6620 this will do good for scheduling. */
6622 if (cfun_frame_layout
.save_return_addr_p
6623 || (cfun_frame_layout
.first_restore_gpr
< BASE_REGNUM
6624 && cfun_frame_layout
.last_restore_gpr
> RETURN_REGNUM
))
6626 int return_regnum
= find_unused_clobbered_reg();
6629 return_reg
= gen_rtx_REG (Pmode
, return_regnum
);
6631 addr
= plus_constant (frame_pointer
,
6632 offset
+ cfun_frame_layout
.gprs_offset
6634 - cfun_frame_layout
.first_save_gpr
)
6636 addr
= gen_rtx_MEM (Pmode
, addr
);
6637 set_mem_alias_set (addr
, s390_sr_alias_set
);
6638 emit_move_insn (return_reg
, addr
);
6642 insn
= restore_gprs (frame_pointer
,
6643 offset
+ cfun_frame_layout
.gprs_offset
6644 + (cfun_frame_layout
.first_restore_gpr
6645 - cfun_frame_layout
.first_save_gpr
)
6647 cfun_frame_layout
.first_restore_gpr
,
6648 cfun_frame_layout
.last_restore_gpr
);
6655 /* Return to caller. */
6657 p
= rtvec_alloc (2);
6659 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
6660 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
, return_reg
);
6661 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
6666 /* Return the size in bytes of a function argument of
6667 type TYPE and/or mode MODE. At least one of TYPE or
6668 MODE must be specified. */
6671 s390_function_arg_size (enum machine_mode mode
, tree type
)
6674 return int_size_in_bytes (type
);
6676 /* No type info available for some library calls ... */
6677 if (mode
!= BLKmode
)
6678 return GET_MODE_SIZE (mode
);
6680 /* If we have neither type nor mode, abort */
6684 /* Return true if a function argument of type TYPE and mode MODE
6685 is to be passed in a floating-point register, if available. */
6688 s390_function_arg_float (enum machine_mode mode
, tree type
)
6690 int size
= s390_function_arg_size (mode
, type
);
6694 /* Soft-float changes the ABI: no floating-point registers are used. */
6695 if (TARGET_SOFT_FLOAT
)
6698 /* No type info available for some library calls ... */
6700 return mode
== SFmode
|| mode
== DFmode
;
6702 /* The ABI says that record types with a single member are treated
6703 just like that member would be. */
6704 while (TREE_CODE (type
) == RECORD_TYPE
)
6706 tree field
, single
= NULL_TREE
;
6708 for (field
= TYPE_FIELDS (type
); field
; field
= TREE_CHAIN (field
))
6710 if (TREE_CODE (field
) != FIELD_DECL
)
6713 if (single
== NULL_TREE
)
6714 single
= TREE_TYPE (field
);
6719 if (single
== NULL_TREE
)
6725 return TREE_CODE (type
) == REAL_TYPE
;
6728 /* Return true if a function argument of type TYPE and mode MODE
6729 is to be passed in an integer register, or a pair of integer
6730 registers, if available. */
6733 s390_function_arg_integer (enum machine_mode mode
, tree type
)
6735 int size
= s390_function_arg_size (mode
, type
);
6739 /* No type info available for some library calls ... */
6741 return GET_MODE_CLASS (mode
) == MODE_INT
6742 || (TARGET_SOFT_FLOAT
&& GET_MODE_CLASS (mode
) == MODE_FLOAT
);
6744 /* We accept small integral (and similar) types. */
6745 if (INTEGRAL_TYPE_P (type
)
6746 || POINTER_TYPE_P (type
)
6747 || TREE_CODE (type
) == OFFSET_TYPE
6748 || (TARGET_SOFT_FLOAT
&& TREE_CODE (type
) == REAL_TYPE
))
6751 /* We also accept structs of size 1, 2, 4, 8 that are not
6752 passed in floating-point registers. */
6753 if (AGGREGATE_TYPE_P (type
)
6754 && exact_log2 (size
) >= 0
6755 && !s390_function_arg_float (mode
, type
))
6761 /* Return 1 if a function argument of type TYPE and mode MODE
6762 is to be passed by reference. The ABI specifies that only
6763 structures of size 1, 2, 4, or 8 bytes are passed by value,
6764 all other structures (and complex numbers) are passed by
6768 s390_pass_by_reference (CUMULATIVE_ARGS
*ca ATTRIBUTE_UNUSED
,
6769 enum machine_mode mode
, tree type
,
6770 bool named ATTRIBUTE_UNUSED
)
6772 int size
= s390_function_arg_size (mode
, type
);
6778 if (AGGREGATE_TYPE_P (type
) && exact_log2 (size
) < 0)
6781 if (TREE_CODE (type
) == COMPLEX_TYPE
6782 || TREE_CODE (type
) == VECTOR_TYPE
)
6789 /* Update the data in CUM to advance over an argument of mode MODE and
6790 data type TYPE. (TYPE is null for libcalls where that information
6791 may not be available.). The boolean NAMED specifies whether the
6792 argument is a named argument (as opposed to an unnamed argument
6793 matching an ellipsis). */
6796 s390_function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
6797 tree type
, int named ATTRIBUTE_UNUSED
)
6799 if (s390_function_arg_float (mode
, type
))
6803 else if (s390_function_arg_integer (mode
, type
))
6805 int size
= s390_function_arg_size (mode
, type
);
6806 cum
->gprs
+= ((size
+ UNITS_PER_WORD
-1) / UNITS_PER_WORD
);
6812 /* Define where to put the arguments to a function.
6813 Value is zero to push the argument on the stack,
6814 or a hard register in which to store the argument.
6816 MODE is the argument's machine mode.
6817 TYPE is the data type of the argument (as a tree).
6818 This is null for libcalls where that information may
6820 CUM is a variable of type CUMULATIVE_ARGS which gives info about
6821 the preceding args and about the function being called.
6822 NAMED is nonzero if this argument is a named parameter
6823 (otherwise it is an extra parameter matching an ellipsis).
6825 On S/390, we use general purpose registers 2 through 6 to
6826 pass integer, pointer, and certain structure arguments, and
6827 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
6828 to pass floating point arguments. All remaining arguments
6829 are pushed to the stack. */
6832 s390_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
, tree type
,
6833 int named ATTRIBUTE_UNUSED
)
6835 if (s390_function_arg_float (mode
, type
))
6837 if (cum
->fprs
+ 1 > FP_ARG_NUM_REG
)
6840 return gen_rtx_REG (mode
, cum
->fprs
+ 16);
6842 else if (s390_function_arg_integer (mode
, type
))
6844 int size
= s390_function_arg_size (mode
, type
);
6845 int n_gprs
= (size
+ UNITS_PER_WORD
-1) / UNITS_PER_WORD
;
6847 if (cum
->gprs
+ n_gprs
> GP_ARG_NUM_REG
)
6850 return gen_rtx_REG (mode
, cum
->gprs
+ 2);
6853 /* After the real arguments, expand_call calls us once again
6854 with a void_type_node type. Whatever we return here is
6855 passed as operand 2 to the call expanders.
6857 We don't need this feature ... */
6858 else if (type
== void_type_node
)
6864 /* Return true if return values of type TYPE should be returned
6865 in a memory buffer whose address is passed by the caller as
6866 hidden first argument. */
6869 s390_return_in_memory (tree type
, tree fundecl ATTRIBUTE_UNUSED
)
6871 /* We accept small integral (and similar) types. */
6872 if (INTEGRAL_TYPE_P (type
)
6873 || POINTER_TYPE_P (type
)
6874 || TREE_CODE (type
) == OFFSET_TYPE
6875 || TREE_CODE (type
) == REAL_TYPE
)
6876 return int_size_in_bytes (type
) > 8;
6878 /* Aggregates and similar constructs are always returned
6880 if (AGGREGATE_TYPE_P (type
)
6881 || TREE_CODE (type
) == COMPLEX_TYPE
6882 || TREE_CODE (type
) == VECTOR_TYPE
)
6885 /* ??? We get called on all sorts of random stuff from
6886 aggregate_value_p. We can't abort, but it's not clear
6887 what's safe to return. Pretend it's a struct I guess. */
6891 /* Define where to return a (scalar) value of type TYPE.
6892 If TYPE is null, define where to return a (scalar)
6893 value of mode MODE from a libcall. */
6896 s390_function_value (tree type
, enum machine_mode mode
)
6900 int unsignedp
= TYPE_UNSIGNED (type
);
6901 mode
= promote_mode (type
, TYPE_MODE (type
), &unsignedp
, 1);
6904 gcc_assert (GET_MODE_CLASS (mode
) == MODE_INT
6905 || GET_MODE_CLASS (mode
) == MODE_FLOAT
);
6906 gcc_assert (GET_MODE_SIZE (mode
) <= 8);
6908 if (TARGET_HARD_FLOAT
&& GET_MODE_CLASS (mode
) == MODE_FLOAT
)
6909 return gen_rtx_REG (mode
, 16);
6911 return gen_rtx_REG (mode
, 2);
6915 /* Create and return the va_list datatype.
6917 On S/390, va_list is an array type equivalent to
6919 typedef struct __va_list_tag
6923 void *__overflow_arg_area;
6924 void *__reg_save_area;
6927 where __gpr and __fpr hold the number of general purpose
6928 or floating point arguments used up to now, respectively,
6929 __overflow_arg_area points to the stack location of the
6930 next argument passed on the stack, and __reg_save_area
6931 always points to the start of the register area in the
6932 call frame of the current function. The function prologue
6933 saves all registers used for argument passing into this
6934 area if the function uses variable arguments. */
6937 s390_build_builtin_va_list (void)
6939 tree f_gpr
, f_fpr
, f_ovf
, f_sav
, record
, type_decl
;
6941 record
= lang_hooks
.types
.make_type (RECORD_TYPE
);
6944 build_decl (TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
6946 f_gpr
= build_decl (FIELD_DECL
, get_identifier ("__gpr"),
6947 long_integer_type_node
);
6948 f_fpr
= build_decl (FIELD_DECL
, get_identifier ("__fpr"),
6949 long_integer_type_node
);
6950 f_ovf
= build_decl (FIELD_DECL
, get_identifier ("__overflow_arg_area"),
6952 f_sav
= build_decl (FIELD_DECL
, get_identifier ("__reg_save_area"),
6955 va_list_gpr_counter_field
= f_gpr
;
6956 va_list_fpr_counter_field
= f_fpr
;
6958 DECL_FIELD_CONTEXT (f_gpr
) = record
;
6959 DECL_FIELD_CONTEXT (f_fpr
) = record
;
6960 DECL_FIELD_CONTEXT (f_ovf
) = record
;
6961 DECL_FIELD_CONTEXT (f_sav
) = record
;
6963 TREE_CHAIN (record
) = type_decl
;
6964 TYPE_NAME (record
) = type_decl
;
6965 TYPE_FIELDS (record
) = f_gpr
;
6966 TREE_CHAIN (f_gpr
) = f_fpr
;
6967 TREE_CHAIN (f_fpr
) = f_ovf
;
6968 TREE_CHAIN (f_ovf
) = f_sav
;
6970 layout_type (record
);
6972 /* The correct type is an array type of one element. */
6973 return build_array_type (record
, build_index_type (size_zero_node
));
6976 /* Implement va_start by filling the va_list structure VALIST.
6977 STDARG_P is always true, and ignored.
6978 NEXTARG points to the first anonymous stack argument.
6980 The following global variables are used to initialize
6981 the va_list structure:
6983 current_function_args_info:
6984 holds number of gprs and fprs used for named arguments.
6985 current_function_arg_offset_rtx:
6986 holds the offset of the first anonymous stack argument
6987 (relative to the virtual arg pointer). */
6990 s390_va_start (tree valist
, rtx nextarg ATTRIBUTE_UNUSED
)
6992 HOST_WIDE_INT n_gpr
, n_fpr
;
6994 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
6995 tree gpr
, fpr
, ovf
, sav
, t
;
6997 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
6998 f_fpr
= TREE_CHAIN (f_gpr
);
6999 f_ovf
= TREE_CHAIN (f_fpr
);
7000 f_sav
= TREE_CHAIN (f_ovf
);
7002 valist
= build_va_arg_indirect_ref (valist
);
7003 gpr
= build (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
7004 fpr
= build (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
7005 ovf
= build (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
7006 sav
= build (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
7008 /* Count number of gp and fp argument registers used. */
7010 n_gpr
= current_function_args_info
.gprs
;
7011 n_fpr
= current_function_args_info
.fprs
;
7013 if (cfun
->va_list_gpr_size
)
7015 t
= build (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
,
7016 build_int_cst (NULL_TREE
, n_gpr
));
7017 TREE_SIDE_EFFECTS (t
) = 1;
7018 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7021 if (cfun
->va_list_fpr_size
)
7023 t
= build (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
,
7024 build_int_cst (NULL_TREE
, n_fpr
));
7025 TREE_SIDE_EFFECTS (t
) = 1;
7026 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7029 /* Find the overflow area. */
7030 if (n_gpr
+ cfun
->va_list_gpr_size
> GP_ARG_NUM_REG
7031 || n_fpr
+ cfun
->va_list_fpr_size
> FP_ARG_NUM_REG
)
7033 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
7035 off
= INTVAL (current_function_arg_offset_rtx
);
7036 off
= off
< 0 ? 0 : off
;
7037 if (TARGET_DEBUG_ARG
)
7038 fprintf (stderr
, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
7039 (int)n_gpr
, (int)n_fpr
, off
);
7041 t
= build (PLUS_EXPR
, TREE_TYPE (ovf
), t
, build_int_cst (NULL_TREE
, off
));
7043 t
= build (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
7044 TREE_SIDE_EFFECTS (t
) = 1;
7045 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7048 /* Find the register save area. */
7049 if ((cfun
->va_list_gpr_size
&& n_gpr
< GP_ARG_NUM_REG
)
7050 || (cfun
->va_list_fpr_size
&& n_fpr
< FP_ARG_NUM_REG
))
7052 t
= make_tree (TREE_TYPE (sav
), return_address_pointer_rtx
);
7053 t
= build (PLUS_EXPR
, TREE_TYPE (sav
), t
,
7054 build_int_cst (NULL_TREE
, -RETURN_REGNUM
* UNITS_PER_WORD
));
7056 t
= build (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
7057 TREE_SIDE_EFFECTS (t
) = 1;
7058 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7062 /* Implement va_arg by updating the va_list structure
7063 VALIST as required to retrieve an argument of type
7064 TYPE, and returning that argument.
7066 Generates code equivalent to:
7068 if (integral value) {
7069 if (size <= 4 && args.gpr < 5 ||
7070 size > 4 && args.gpr < 4 )
7071 ret = args.reg_save_area[args.gpr+8]
7073 ret = *args.overflow_arg_area++;
7074 } else if (float value) {
7076 ret = args.reg_save_area[args.fpr+64]
7078 ret = *args.overflow_arg_area++;
7079 } else if (aggregate value) {
7081 ret = *args.reg_save_area[args.gpr]
7083 ret = **args.overflow_arg_area++;
7087 s390_gimplify_va_arg (tree valist
, tree type
, tree
*pre_p
,
7088 tree
*post_p ATTRIBUTE_UNUSED
)
7090 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
7091 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
7092 int indirect_p
, size
, n_reg
, sav_ofs
, sav_scale
, max_reg
;
7093 tree lab_false
, lab_over
, addr
;
7095 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
7096 f_fpr
= TREE_CHAIN (f_gpr
);
7097 f_ovf
= TREE_CHAIN (f_fpr
);
7098 f_sav
= TREE_CHAIN (f_ovf
);
7100 valist
= build_va_arg_indirect_ref (valist
);
7101 gpr
= build (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
7102 fpr
= build (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
7103 ovf
= build (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
7104 sav
= build (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
7106 size
= int_size_in_bytes (type
);
7108 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
7110 if (TARGET_DEBUG_ARG
)
7112 fprintf (stderr
, "va_arg: aggregate type");
7116 /* Aggregates are passed by reference. */
7121 /* kernel stack layout on 31 bit: It is assumed here that no padding
7122 will be added by s390_frame_info because for va_args always an even
7123 number of gprs has to be saved r15-r2 = 14 regs. */
7124 sav_ofs
= 2 * UNITS_PER_WORD
;
7125 sav_scale
= UNITS_PER_WORD
;
7126 size
= UNITS_PER_WORD
;
7127 max_reg
= GP_ARG_NUM_REG
- n_reg
;
7129 else if (s390_function_arg_float (TYPE_MODE (type
), type
))
7131 if (TARGET_DEBUG_ARG
)
7133 fprintf (stderr
, "va_arg: float type");
7137 /* FP args go in FP registers, if present. */
7141 sav_ofs
= 16 * UNITS_PER_WORD
;
7143 max_reg
= FP_ARG_NUM_REG
- n_reg
;
7147 if (TARGET_DEBUG_ARG
)
7149 fprintf (stderr
, "va_arg: other type");
7153 /* Otherwise into GP registers. */
7156 n_reg
= (size
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
7158 /* kernel stack layout on 31 bit: It is assumed here that no padding
7159 will be added by s390_frame_info because for va_args always an even
7160 number of gprs has to be saved r15-r2 = 14 regs. */
7161 sav_ofs
= 2 * UNITS_PER_WORD
;
7163 if (size
< UNITS_PER_WORD
)
7164 sav_ofs
+= UNITS_PER_WORD
- size
;
7166 sav_scale
= UNITS_PER_WORD
;
7167 max_reg
= GP_ARG_NUM_REG
- n_reg
;
7170 /* Pull the value out of the saved registers ... */
7172 lab_false
= create_artificial_label ();
7173 lab_over
= create_artificial_label ();
7174 addr
= create_tmp_var (ptr_type_node
, "addr");
7175 DECL_POINTER_ALIAS_SET (addr
) = s390_sr_alias_set
;
7177 t
= fold_convert (TREE_TYPE (reg
), size_int (max_reg
));
7178 t
= build2 (GT_EXPR
, boolean_type_node
, reg
, t
);
7179 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
7180 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
7181 gimplify_and_add (t
, pre_p
);
7183 t
= build2 (PLUS_EXPR
, ptr_type_node
, sav
,
7184 fold_convert (ptr_type_node
, size_int (sav_ofs
)));
7185 u
= build2 (MULT_EXPR
, TREE_TYPE (reg
), reg
,
7186 fold_convert (TREE_TYPE (reg
), size_int (sav_scale
)));
7187 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
, fold_convert (ptr_type_node
, u
));
7189 t
= build2 (MODIFY_EXPR
, void_type_node
, addr
, t
);
7190 gimplify_and_add (t
, pre_p
);
7192 t
= build1 (GOTO_EXPR
, void_type_node
, lab_over
);
7193 gimplify_and_add (t
, pre_p
);
7195 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false
);
7196 append_to_statement_list (t
, pre_p
);
7199 /* ... Otherwise out of the overflow area. */
7202 if (size
< UNITS_PER_WORD
)
7203 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
,
7204 fold_convert (ptr_type_node
, size_int (UNITS_PER_WORD
- size
)));
7206 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
7208 u
= build2 (MODIFY_EXPR
, void_type_node
, addr
, t
);
7209 gimplify_and_add (u
, pre_p
);
7211 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
,
7212 fold_convert (ptr_type_node
, size_int (size
)));
7213 t
= build2 (MODIFY_EXPR
, ptr_type_node
, ovf
, t
);
7214 gimplify_and_add (t
, pre_p
);
7216 t
= build1 (LABEL_EXPR
, void_type_node
, lab_over
);
7217 append_to_statement_list (t
, pre_p
);
7220 /* Increment register save count. */
7222 u
= build2 (PREINCREMENT_EXPR
, TREE_TYPE (reg
), reg
,
7223 fold_convert (TREE_TYPE (reg
), size_int (n_reg
)));
7224 gimplify_and_add (u
, pre_p
);
7228 t
= build_pointer_type (build_pointer_type (type
));
7229 addr
= fold_convert (t
, addr
);
7230 addr
= build_va_arg_indirect_ref (addr
);
7234 t
= build_pointer_type (type
);
7235 addr
= fold_convert (t
, addr
);
7238 return build_va_arg_indirect_ref (addr
);
7246 S390_BUILTIN_THREAD_POINTER
,
7247 S390_BUILTIN_SET_THREAD_POINTER
,
7252 static unsigned int const code_for_builtin_64
[S390_BUILTIN_max
] = {
7257 static unsigned int const code_for_builtin_31
[S390_BUILTIN_max
] = {
7263 s390_init_builtins (void)
7267 ftype
= build_function_type (ptr_type_node
, void_list_node
);
7268 lang_hooks
.builtin_function ("__builtin_thread_pointer", ftype
,
7269 S390_BUILTIN_THREAD_POINTER
, BUILT_IN_MD
,
7272 ftype
= build_function_type_list (void_type_node
, ptr_type_node
, NULL_TREE
);
7273 lang_hooks
.builtin_function ("__builtin_set_thread_pointer", ftype
,
7274 S390_BUILTIN_SET_THREAD_POINTER
, BUILT_IN_MD
,
7278 /* Expand an expression EXP that calls a built-in function,
7279 with result going to TARGET if that's convenient
7280 (and in mode MODE if that's convenient).
7281 SUBTARGET may be used as the target for computing one of EXP's operands.
7282 IGNORE is nonzero if the value is to be ignored. */
7285 s390_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
7286 enum machine_mode mode ATTRIBUTE_UNUSED
,
7287 int ignore ATTRIBUTE_UNUSED
)
7291 unsigned int const *code_for_builtin
=
7292 TARGET_64BIT
? code_for_builtin_64
: code_for_builtin_31
;
7294 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
7295 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7296 tree arglist
= TREE_OPERAND (exp
, 1);
7297 enum insn_code icode
;
7298 rtx op
[MAX_ARGS
], pat
;
7302 if (fcode
>= S390_BUILTIN_max
)
7303 internal_error ("bad builtin fcode");
7304 icode
= code_for_builtin
[fcode
];
7306 internal_error ("bad builtin fcode");
7308 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
7310 for (arglist
= TREE_OPERAND (exp
, 1), arity
= 0;
7312 arglist
= TREE_CHAIN (arglist
), arity
++)
7314 const struct insn_operand_data
*insn_op
;
7316 tree arg
= TREE_VALUE (arglist
);
7317 if (arg
== error_mark_node
)
7319 if (arity
> MAX_ARGS
)
7322 insn_op
= &insn_data
[icode
].operand
[arity
+ nonvoid
];
7324 op
[arity
] = expand_expr (arg
, NULL_RTX
, insn_op
->mode
, 0);
7326 if (!(*insn_op
->predicate
) (op
[arity
], insn_op
->mode
))
7327 op
[arity
] = copy_to_mode_reg (insn_op
->mode
, op
[arity
]);
7332 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7334 || GET_MODE (target
) != tmode
7335 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7336 target
= gen_reg_rtx (tmode
);
7342 pat
= GEN_FCN (icode
) (target
);
7346 pat
= GEN_FCN (icode
) (target
, op
[0]);
7348 pat
= GEN_FCN (icode
) (op
[0]);
7351 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
7367 /* Output assembly code for the trampoline template to
7370 On S/390, we use gpr 1 internally in the trampoline code;
7371 gpr 0 is used to hold the static chain. */
7374 s390_trampoline_template (FILE *file
)
7377 op
[0] = gen_rtx_REG (Pmode
, 0);
7378 op
[1] = gen_rtx_REG (Pmode
, 1);
7382 output_asm_insn ("basr\t%1,0", op
);
7383 output_asm_insn ("lmg\t%0,%1,14(%1)", op
);
7384 output_asm_insn ("br\t%1", op
);
7385 ASM_OUTPUT_SKIP (file
, (HOST_WIDE_INT
)(TRAMPOLINE_SIZE
- 10));
7389 output_asm_insn ("basr\t%1,0", op
);
7390 output_asm_insn ("lm\t%0,%1,6(%1)", op
);
7391 output_asm_insn ("br\t%1", op
);
7392 ASM_OUTPUT_SKIP (file
, (HOST_WIDE_INT
)(TRAMPOLINE_SIZE
- 8));
7396 /* Emit RTL insns to initialize the variable parts of a trampoline.
7397 FNADDR is an RTX for the address of the function's pure code.
7398 CXT is an RTX for the static chain value for the function. */
7401 s390_initialize_trampoline (rtx addr
, rtx fnaddr
, rtx cxt
)
7403 emit_move_insn (gen_rtx_MEM (Pmode
,
7404 memory_address (Pmode
,
7405 plus_constant (addr
, (TARGET_64BIT
? 16 : 8)))), cxt
);
7406 emit_move_insn (gen_rtx_MEM (Pmode
,
7407 memory_address (Pmode
,
7408 plus_constant (addr
, (TARGET_64BIT
? 24 : 12)))), fnaddr
);
7411 /* Return rtx for 64-bit constant formed from the 32-bit subwords
7412 LOW and HIGH, independent of the host word size. */
7415 s390_gen_rtx_const_DI (int high
, int low
)
7417 #if HOST_BITS_PER_WIDE_INT >= 64
7419 val
= (HOST_WIDE_INT
)high
;
7421 val
|= (HOST_WIDE_INT
)low
;
7423 return GEN_INT (val
);
7425 #if HOST_BITS_PER_WIDE_INT >= 32
7426 return immed_double_const ((HOST_WIDE_INT
)low
, (HOST_WIDE_INT
)high
, DImode
);
7433 /* Output assembler code to FILE to increment profiler label # LABELNO
7434 for profiling a function entry. */
7437 s390_function_profiler (FILE *file
, int labelno
)
7442 ASM_GENERATE_INTERNAL_LABEL (label
, "LP", labelno
);
7444 fprintf (file
, "# function profiler \n");
7446 op
[0] = gen_rtx_REG (Pmode
, RETURN_REGNUM
);
7447 op
[1] = gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
7448 op
[1] = gen_rtx_MEM (Pmode
, plus_constant (op
[1], UNITS_PER_WORD
));
7450 op
[2] = gen_rtx_REG (Pmode
, 1);
7451 op
[3] = gen_rtx_SYMBOL_REF (Pmode
, label
);
7452 SYMBOL_REF_FLAGS (op
[3]) = SYMBOL_FLAG_LOCAL
;
7454 op
[4] = gen_rtx_SYMBOL_REF (Pmode
, "_mcount");
7457 op
[4] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[4]), UNSPEC_PLT
);
7458 op
[4] = gen_rtx_CONST (Pmode
, op
[4]);
7463 output_asm_insn ("stg\t%0,%1", op
);
7464 output_asm_insn ("larl\t%2,%3", op
);
7465 output_asm_insn ("brasl\t%0,%4", op
);
7466 output_asm_insn ("lg\t%0,%1", op
);
7470 op
[6] = gen_label_rtx ();
7472 output_asm_insn ("st\t%0,%1", op
);
7473 output_asm_insn ("bras\t%2,%l6", op
);
7474 output_asm_insn (".long\t%4", op
);
7475 output_asm_insn (".long\t%3", op
);
7476 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
7477 output_asm_insn ("l\t%0,0(%2)", op
);
7478 output_asm_insn ("l\t%2,4(%2)", op
);
7479 output_asm_insn ("basr\t%0,%0", op
);
7480 output_asm_insn ("l\t%0,%1", op
);
7484 op
[5] = gen_label_rtx ();
7485 op
[6] = gen_label_rtx ();
7487 output_asm_insn ("st\t%0,%1", op
);
7488 output_asm_insn ("bras\t%2,%l6", op
);
7489 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[5]));
7490 output_asm_insn (".long\t%4-%l5", op
);
7491 output_asm_insn (".long\t%3-%l5", op
);
7492 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
7493 output_asm_insn ("lr\t%0,%2", op
);
7494 output_asm_insn ("a\t%0,0(%2)", op
);
7495 output_asm_insn ("a\t%2,4(%2)", op
);
7496 output_asm_insn ("basr\t%0,%0", op
);
7497 output_asm_insn ("l\t%0,%1", op
);
7501 /* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
7502 into its SYMBOL_REF_FLAGS. */
7505 s390_encode_section_info (tree decl
, rtx rtl
, int first
)
7507 default_encode_section_info (decl
, rtl
, first
);
7509 /* If a variable has a forced alignment to < 2 bytes, mark it with
7510 SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL operand. */
7511 if (TREE_CODE (decl
) == VAR_DECL
7512 && DECL_USER_ALIGN (decl
) && DECL_ALIGN (decl
) < 16)
7513 SYMBOL_REF_FLAGS (XEXP (rtl
, 0)) |= SYMBOL_FLAG_ALIGN1
;
7516 /* Output thunk to FILE that implements a C++ virtual function call (with
7517 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
7518 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
7519 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
7520 relative to the resulting this pointer. */
7523 s390_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
7524 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
7530 /* Operand 0 is the target function. */
7531 op
[0] = XEXP (DECL_RTL (function
), 0);
7532 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (op
[0]))
7535 op
[0] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[0]),
7536 TARGET_64BIT
? UNSPEC_PLT
: UNSPEC_GOT
);
7537 op
[0] = gen_rtx_CONST (Pmode
, op
[0]);
7540 /* Operand 1 is the 'this' pointer. */
7541 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
7542 op
[1] = gen_rtx_REG (Pmode
, 3);
7544 op
[1] = gen_rtx_REG (Pmode
, 2);
7546 /* Operand 2 is the delta. */
7547 op
[2] = GEN_INT (delta
);
7549 /* Operand 3 is the vcall_offset. */
7550 op
[3] = GEN_INT (vcall_offset
);
7552 /* Operand 4 is the temporary register. */
7553 op
[4] = gen_rtx_REG (Pmode
, 1);
7555 /* Operands 5 to 8 can be used as labels. */
7561 /* Operand 9 can be used for temporary register. */
7564 /* Generate code. */
7567 /* Setup literal pool pointer if required. */
7568 if ((!DISP_IN_RANGE (delta
)
7569 && !CONST_OK_FOR_CONSTRAINT_P (delta
, 'K', "K"))
7570 || (!DISP_IN_RANGE (vcall_offset
)
7571 && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'K', "K")))
7573 op
[5] = gen_label_rtx ();
7574 output_asm_insn ("larl\t%4,%5", op
);
7577 /* Add DELTA to this pointer. */
7580 if (CONST_OK_FOR_CONSTRAINT_P (delta
, 'J', "J"))
7581 output_asm_insn ("la\t%1,%2(%1)", op
);
7582 else if (DISP_IN_RANGE (delta
))
7583 output_asm_insn ("lay\t%1,%2(%1)", op
);
7584 else if (CONST_OK_FOR_CONSTRAINT_P (delta
, 'K', "K"))
7585 output_asm_insn ("aghi\t%1,%2", op
);
7588 op
[6] = gen_label_rtx ();
7589 output_asm_insn ("agf\t%1,%6-%5(%4)", op
);
7593 /* Perform vcall adjustment. */
7596 if (DISP_IN_RANGE (vcall_offset
))
7598 output_asm_insn ("lg\t%4,0(%1)", op
);
7599 output_asm_insn ("ag\t%1,%3(%4)", op
);
7601 else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'K', "K"))
7603 output_asm_insn ("lghi\t%4,%3", op
);
7604 output_asm_insn ("ag\t%4,0(%1)", op
);
7605 output_asm_insn ("ag\t%1,0(%4)", op
);
7609 op
[7] = gen_label_rtx ();
7610 output_asm_insn ("llgf\t%4,%7-%5(%4)", op
);
7611 output_asm_insn ("ag\t%4,0(%1)", op
);
7612 output_asm_insn ("ag\t%1,0(%4)", op
);
7616 /* Jump to target. */
7617 output_asm_insn ("jg\t%0", op
);
7619 /* Output literal pool if required. */
7622 output_asm_insn (".align\t4", op
);
7623 targetm
.asm_out
.internal_label (file
, "L",
7624 CODE_LABEL_NUMBER (op
[5]));
7628 targetm
.asm_out
.internal_label (file
, "L",
7629 CODE_LABEL_NUMBER (op
[6]));
7630 output_asm_insn (".long\t%2", op
);
7634 targetm
.asm_out
.internal_label (file
, "L",
7635 CODE_LABEL_NUMBER (op
[7]));
7636 output_asm_insn (".long\t%3", op
);
7641 /* Setup base pointer if required. */
7643 || (!DISP_IN_RANGE (delta
)
7644 && !CONST_OK_FOR_CONSTRAINT_P (delta
, 'K', "K"))
7645 || (!DISP_IN_RANGE (delta
)
7646 && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'K', "K")))
7648 op
[5] = gen_label_rtx ();
7649 output_asm_insn ("basr\t%4,0", op
);
7650 targetm
.asm_out
.internal_label (file
, "L",
7651 CODE_LABEL_NUMBER (op
[5]));
7654 /* Add DELTA to this pointer. */
7657 if (CONST_OK_FOR_CONSTRAINT_P (delta
, 'J', "J"))
7658 output_asm_insn ("la\t%1,%2(%1)", op
);
7659 else if (DISP_IN_RANGE (delta
))
7660 output_asm_insn ("lay\t%1,%2(%1)", op
);
7661 else if (CONST_OK_FOR_CONSTRAINT_P (delta
, 'K', "K"))
7662 output_asm_insn ("ahi\t%1,%2", op
);
7665 op
[6] = gen_label_rtx ();
7666 output_asm_insn ("a\t%1,%6-%5(%4)", op
);
7670 /* Perform vcall adjustment. */
7673 if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'J', "J"))
7675 output_asm_insn ("lg\t%4,0(%1)", op
);
7676 output_asm_insn ("a\t%1,%3(%4)", op
);
7678 else if (DISP_IN_RANGE (vcall_offset
))
7680 output_asm_insn ("lg\t%4,0(%1)", op
);
7681 output_asm_insn ("ay\t%1,%3(%4)", op
);
7683 else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'K', "K"))
7685 output_asm_insn ("lhi\t%4,%3", op
);
7686 output_asm_insn ("a\t%4,0(%1)", op
);
7687 output_asm_insn ("a\t%1,0(%4)", op
);
7691 op
[7] = gen_label_rtx ();
7692 output_asm_insn ("l\t%4,%7-%5(%4)", op
);
7693 output_asm_insn ("a\t%4,0(%1)", op
);
7694 output_asm_insn ("a\t%1,0(%4)", op
);
7697 /* We had to clobber the base pointer register.
7698 Re-setup the base pointer (with a different base). */
7699 op
[5] = gen_label_rtx ();
7700 output_asm_insn ("basr\t%4,0", op
);
7701 targetm
.asm_out
.internal_label (file
, "L",
7702 CODE_LABEL_NUMBER (op
[5]));
7705 /* Jump to target. */
7706 op
[8] = gen_label_rtx ();
7709 output_asm_insn ("l\t%4,%8-%5(%4)", op
);
7711 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
7712 /* We cannot call through .plt, since .plt requires %r12 loaded. */
7713 else if (flag_pic
== 1)
7715 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
7716 output_asm_insn ("l\t%4,%0(%4)", op
);
7718 else if (flag_pic
== 2)
7720 op
[9] = gen_rtx_REG (Pmode
, 0);
7721 output_asm_insn ("l\t%9,%8-4-%5(%4)", op
);
7722 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
7723 output_asm_insn ("ar\t%4,%9", op
);
7724 output_asm_insn ("l\t%4,0(%4)", op
);
7727 output_asm_insn ("br\t%4", op
);
7729 /* Output literal pool. */
7730 output_asm_insn (".align\t4", op
);
7732 if (nonlocal
&& flag_pic
== 2)
7733 output_asm_insn (".long\t%0", op
);
7736 op
[0] = gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
7737 SYMBOL_REF_FLAGS (op
[0]) = SYMBOL_FLAG_LOCAL
;
7740 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[8]));
7742 output_asm_insn (".long\t%0", op
);
7744 output_asm_insn (".long\t%0-%5", op
);
7748 targetm
.asm_out
.internal_label (file
, "L",
7749 CODE_LABEL_NUMBER (op
[6]));
7750 output_asm_insn (".long\t%2", op
);
7754 targetm
.asm_out
.internal_label (file
, "L",
7755 CODE_LABEL_NUMBER (op
[7]));
7756 output_asm_insn (".long\t%3", op
);
7762 s390_valid_pointer_mode (enum machine_mode mode
)
7764 return (mode
== SImode
|| (TARGET_64BIT
&& mode
== DImode
));
7767 /* Checks whether the given ARGUMENT_LIST would use a caller
7768 saved register. This is used to decide whether sibling call
7769 optimization could be performed on the respective function
7773 s390_call_saved_register_used (tree argument_list
)
7775 CUMULATIVE_ARGS cum
;
7777 enum machine_mode mode
;
7782 INIT_CUMULATIVE_ARGS (cum
, NULL
, NULL
, 0, 0);
7784 while (argument_list
)
7786 parameter
= TREE_VALUE (argument_list
);
7787 argument_list
= TREE_CHAIN (argument_list
);
7789 gcc_assert (parameter
);
7791 /* For an undeclared variable passed as parameter we will get
7792 an ERROR_MARK node here. */
7793 if (TREE_CODE (parameter
) == ERROR_MARK
)
7796 type
= TREE_TYPE (parameter
);
7799 mode
= TYPE_MODE (type
);
7802 if (pass_by_reference (&cum
, mode
, type
, true))
7805 type
= build_pointer_type (type
);
7808 parm_rtx
= s390_function_arg (&cum
, mode
, type
, 0);
7810 s390_function_arg_advance (&cum
, mode
, type
, 0);
7812 if (parm_rtx
&& REG_P (parm_rtx
))
7815 reg
< HARD_REGNO_NREGS (REGNO (parm_rtx
), GET_MODE (parm_rtx
));
7817 if (! call_used_regs
[reg
+ REGNO (parm_rtx
)])
7824 /* Return true if the given call expression can be
7825 turned into a sibling call.
7826 DECL holds the declaration of the function to be called whereas
7827 EXP is the call expression itself. */
7830 s390_function_ok_for_sibcall (tree decl
, tree exp
)
7832 /* The TPF epilogue uses register 1. */
7833 if (TARGET_TPF_PROFILING
)
7836 /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
7837 which would have to be restored before the sibcall. */
7838 if (!TARGET_64BIT
&& flag_pic
&& decl
&& TREE_PUBLIC (decl
))
7841 /* Register 6 on s390 is available as an argument register but unfortunately
7842 "caller saved". This makes functions needing this register for arguments
7843 not suitable for sibcalls. */
7844 if (TREE_OPERAND (exp
, 1)
7845 && s390_call_saved_register_used (TREE_OPERAND (exp
, 1)))
7851 /* Return the fixed registers used for condition codes. */
7854 s390_fixed_condition_code_regs (unsigned int *p1
, unsigned int *p2
)
7857 *p2
= INVALID_REGNUM
;
7862 /* If two condition code modes are compatible, return a condition code
7863 mode which is compatible with both. Otherwise, return
7866 static enum machine_mode
7867 s390_cc_modes_compatible (enum machine_mode m1
, enum machine_mode m2
)
7875 if (m2
== CCUmode
|| m2
== CCTmode
7876 || m2
== CCSmode
|| m2
== CCSRmode
|| m2
== CCURmode
)
7896 /* This function is used by the call expanders of the machine description.
7897 It emits the call insn itself together with the necessary operations
7898 to adjust the target address and returns the emitted insn.
7899 ADDR_LOCATION is the target address rtx
7900 TLS_CALL the location of the thread-local symbol
7901 RESULT_REG the register where the result of the call should be stored
7902 RETADDR_REG the register where the return address should be stored
7903 If this parameter is NULL_RTX the call is considered
7904 to be a sibling call. */
7907 s390_emit_call (rtx addr_location
, rtx tls_call
, rtx result_reg
,
7910 bool plt_call
= false;
7916 /* Direct function calls need special treatment. */
7917 if (GET_CODE (addr_location
) == SYMBOL_REF
)
7919 /* When calling a global routine in PIC mode, we must
7920 replace the symbol itself with the PLT stub. */
7921 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (addr_location
))
7923 addr_location
= gen_rtx_UNSPEC (Pmode
,
7924 gen_rtvec (1, addr_location
),
7926 addr_location
= gen_rtx_CONST (Pmode
, addr_location
);
7930 /* Unless we can use the bras(l) insn, force the
7931 routine address into a register. */
7932 if (!TARGET_SMALL_EXEC
&& !TARGET_CPU_ZARCH
)
7935 addr_location
= legitimize_pic_address (addr_location
, 0);
7937 addr_location
= force_reg (Pmode
, addr_location
);
7941 /* If it is already an indirect call or the code above moved the
7942 SYMBOL_REF to somewhere else make sure the address can be found in
7944 if (retaddr_reg
== NULL_RTX
7945 && GET_CODE (addr_location
) != SYMBOL_REF
7948 emit_move_insn (gen_rtx_REG (Pmode
, SIBCALL_REGNUM
), addr_location
);
7949 addr_location
= gen_rtx_REG (Pmode
, SIBCALL_REGNUM
);
7952 addr_location
= gen_rtx_MEM (QImode
, addr_location
);
7953 call
= gen_rtx_CALL (VOIDmode
, addr_location
, const0_rtx
);
7955 if (result_reg
!= NULL_RTX
)
7956 call
= gen_rtx_SET (VOIDmode
, result_reg
, call
);
7958 if (retaddr_reg
!= NULL_RTX
)
7960 clobber
= gen_rtx_CLOBBER (VOIDmode
, retaddr_reg
);
7962 if (tls_call
!= NULL_RTX
)
7963 vec
= gen_rtvec (3, call
, clobber
,
7964 gen_rtx_USE (VOIDmode
, tls_call
));
7966 vec
= gen_rtvec (2, call
, clobber
);
7968 call
= gen_rtx_PARALLEL (VOIDmode
, vec
);
7971 insn
= emit_call_insn (call
);
7973 /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
7974 if ((!TARGET_64BIT
&& plt_call
) || tls_call
!= NULL_RTX
)
7976 /* s390_function_ok_for_sibcall should
7977 have denied sibcalls in this case. */
7978 gcc_assert (retaddr_reg
!= NULL_RTX
);
7980 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), pic_offset_table_rtx
);
7985 /* Implement CONDITIONAL_REGISTER_USAGE. */
7988 s390_conditional_register_usage (void)
7994 fixed_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
7995 call_used_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
7997 if (TARGET_CPU_ZARCH
)
7999 fixed_regs
[RETURN_REGNUM
] = 0;
8000 call_used_regs
[RETURN_REGNUM
] = 0;
8004 for (i
= 24; i
< 32; i
++)
8005 call_used_regs
[i
] = call_really_used_regs
[i
] = 0;
8009 for (i
= 18; i
< 20; i
++)
8010 call_used_regs
[i
] = call_really_used_regs
[i
] = 0;
8013 if (TARGET_SOFT_FLOAT
)
8015 for (i
= 16; i
< 32; i
++)
8016 call_used_regs
[i
] = fixed_regs
[i
] = 1;
8020 /* Corresponding function to eh_return expander. */
8022 static GTY(()) rtx s390_tpf_eh_return_symbol
;
8024 s390_emit_tpf_eh_return (rtx target
)
8028 if (!s390_tpf_eh_return_symbol
)
8029 s390_tpf_eh_return_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "__tpf_eh_return");
8031 reg
= gen_rtx_REG (Pmode
, 2);
8033 emit_move_insn (reg
, target
);
8034 insn
= s390_emit_call (s390_tpf_eh_return_symbol
, NULL_RTX
, reg
,
8035 gen_rtx_REG (Pmode
, RETURN_REGNUM
));
8036 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), reg
);
8038 emit_move_insn (EH_RETURN_HANDLER_RTX
, reg
);
8041 /* Rework the prologue/epilogue to avoid saving/restoring
8042 registers unnecessarily. */
8045 s390_optimize_prologue (void)
8047 rtx insn
, new_insn
, next_insn
;
8049 /* Do a final recompute of the frame-related data. */
8051 s390_update_frame_layout ();
8053 /* If all special registers are in fact used, there's nothing we
8054 can do, so no point in walking the insn list. */
8056 if (cfun_frame_layout
.first_save_gpr
<= BASE_REGNUM
8057 && cfun_frame_layout
.last_save_gpr
>= BASE_REGNUM
8058 && (TARGET_CPU_ZARCH
8059 || (cfun_frame_layout
.first_save_gpr
<= RETURN_REGNUM
8060 && cfun_frame_layout
.last_save_gpr
>= RETURN_REGNUM
)))
8063 /* Search for prologue/epilogue insns and replace them. */
8065 for (insn
= get_insns (); insn
; insn
= next_insn
)
8067 int first
, last
, off
;
8068 rtx set
, base
, offset
;
8070 next_insn
= NEXT_INSN (insn
);
8072 if (GET_CODE (insn
) != INSN
)
8075 if (GET_CODE (PATTERN (insn
)) == PARALLEL
8076 && store_multiple_operation (PATTERN (insn
), VOIDmode
))
8078 set
= XVECEXP (PATTERN (insn
), 0, 0);
8079 first
= REGNO (SET_SRC (set
));
8080 last
= first
+ XVECLEN (PATTERN (insn
), 0) - 1;
8081 offset
= const0_rtx
;
8082 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
8083 off
= INTVAL (offset
);
8085 if (GET_CODE (base
) != REG
|| off
< 0)
8087 if (cfun_frame_layout
.first_save_gpr
!= -1
8088 && (cfun_frame_layout
.first_save_gpr
< first
8089 || cfun_frame_layout
.last_save_gpr
> last
))
8091 if (REGNO (base
) != STACK_POINTER_REGNUM
8092 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
8094 if (first
> BASE_REGNUM
|| last
< BASE_REGNUM
)
8097 if (cfun_frame_layout
.first_save_gpr
!= -1)
8099 new_insn
= save_gprs (base
,
8100 off
+ (cfun_frame_layout
.first_save_gpr
8101 - first
) * UNITS_PER_WORD
,
8102 cfun_frame_layout
.first_save_gpr
,
8103 cfun_frame_layout
.last_save_gpr
);
8104 new_insn
= emit_insn_before (new_insn
, insn
);
8105 INSN_ADDRESSES_NEW (new_insn
, -1);
8112 if (cfun_frame_layout
.first_save_gpr
== -1
8113 && GET_CODE (PATTERN (insn
)) == SET
8114 && GET_CODE (SET_SRC (PATTERN (insn
))) == REG
8115 && (REGNO (SET_SRC (PATTERN (insn
))) == BASE_REGNUM
8116 || (!TARGET_CPU_ZARCH
8117 && REGNO (SET_SRC (PATTERN (insn
))) == RETURN_REGNUM
))
8118 && GET_CODE (SET_DEST (PATTERN (insn
))) == MEM
)
8120 set
= PATTERN (insn
);
8121 first
= REGNO (SET_SRC (set
));
8122 offset
= const0_rtx
;
8123 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
8124 off
= INTVAL (offset
);
8126 if (GET_CODE (base
) != REG
|| off
< 0)
8128 if (REGNO (base
) != STACK_POINTER_REGNUM
8129 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
8136 if (GET_CODE (PATTERN (insn
)) == PARALLEL
8137 && load_multiple_operation (PATTERN (insn
), VOIDmode
))
8139 set
= XVECEXP (PATTERN (insn
), 0, 0);
8140 first
= REGNO (SET_DEST (set
));
8141 last
= first
+ XVECLEN (PATTERN (insn
), 0) - 1;
8142 offset
= const0_rtx
;
8143 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
8144 off
= INTVAL (offset
);
8146 if (GET_CODE (base
) != REG
|| off
< 0)
8148 if (cfun_frame_layout
.first_restore_gpr
!= -1
8149 && (cfun_frame_layout
.first_restore_gpr
< first
8150 || cfun_frame_layout
.last_restore_gpr
> last
))
8152 if (REGNO (base
) != STACK_POINTER_REGNUM
8153 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
8155 if (first
> BASE_REGNUM
|| last
< BASE_REGNUM
)
8158 if (cfun_frame_layout
.first_restore_gpr
!= -1)
8160 new_insn
= restore_gprs (base
,
8161 off
+ (cfun_frame_layout
.first_restore_gpr
8162 - first
) * UNITS_PER_WORD
,
8163 cfun_frame_layout
.first_restore_gpr
,
8164 cfun_frame_layout
.last_restore_gpr
);
8165 new_insn
= emit_insn_before (new_insn
, insn
);
8166 INSN_ADDRESSES_NEW (new_insn
, -1);
8173 if (cfun_frame_layout
.first_restore_gpr
== -1
8174 && GET_CODE (PATTERN (insn
)) == SET
8175 && GET_CODE (SET_DEST (PATTERN (insn
))) == REG
8176 && (REGNO (SET_DEST (PATTERN (insn
))) == BASE_REGNUM
8177 || (!TARGET_CPU_ZARCH
8178 && REGNO (SET_DEST (PATTERN (insn
))) == RETURN_REGNUM
))
8179 && GET_CODE (SET_SRC (PATTERN (insn
))) == MEM
)
8181 set
= PATTERN (insn
);
8182 first
= REGNO (SET_DEST (set
));
8183 offset
= const0_rtx
;
8184 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
8185 off
= INTVAL (offset
);
8187 if (GET_CODE (base
) != REG
|| off
< 0)
8189 if (REGNO (base
) != STACK_POINTER_REGNUM
8190 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
8199 /* Perform machine-dependent processing. */
8204 bool pool_overflow
= false;
8206 /* Make sure all splits have been performed; splits after
8207 machine_dependent_reorg might confuse insn length counts. */
8208 split_all_insns_noflow ();
8211 /* Install the main literal pool and the associated base
8212 register load insns.
8214 In addition, there are two problematic situations we need
8217 - the literal pool might be > 4096 bytes in size, so that
8218 some of its elements cannot be directly accessed
8220 - a branch target might be > 64K away from the branch, so that
8221 it is not possible to use a PC-relative instruction.
8223 To fix those, we split the single literal pool into multiple
8224 pool chunks, reloading the pool base register at various
8225 points throughout the function to ensure it always points to
8226 the pool chunk the following code expects, and / or replace
8227 PC-relative branches by absolute branches.
8229 However, the two problems are interdependent: splitting the
8230 literal pool can move a branch further away from its target,
8231 causing the 64K limit to overflow, and on the other hand,
8232 replacing a PC-relative branch by an absolute branch means
8233 we need to put the branch target address into the literal
8234 pool, possibly causing it to overflow.
8236 So, we loop trying to fix up both problems until we manage
8237 to satisfy both conditions at the same time. Note that the
8238 loop is guaranteed to terminate as every pass of the loop
8239 strictly decreases the total number of PC-relative branches
8240 in the function. (This is not completely true as there
8241 might be branch-over-pool insns introduced by chunkify_start.
8242 Those never need to be split however.) */
8246 struct constant_pool
*pool
= NULL
;
8248 /* Collect the literal pool. */
8251 pool
= s390_mainpool_start ();
8253 pool_overflow
= true;
8256 /* If literal pool overflowed, start to chunkify it. */
8258 pool
= s390_chunkify_start ();
8260 /* Split out-of-range branches. If this has created new
8261 literal pool entries, cancel current chunk list and
8262 recompute it. zSeries machines have large branch
8263 instructions, so we never need to split a branch. */
8264 if (!TARGET_CPU_ZARCH
&& s390_split_branches ())
8267 s390_chunkify_cancel (pool
);
8269 s390_mainpool_cancel (pool
);
8274 /* If we made it up to here, both conditions are satisfied.
8275 Finish up literal pool related changes. */
8277 s390_chunkify_finish (pool
);
8279 s390_mainpool_finish (pool
);
8281 /* We're done splitting branches. */
8282 cfun
->machine
->split_branches_pending_p
= false;
8286 /* Generate out-of-pool execute target insns. */
8287 if (TARGET_CPU_ZARCH
)
8289 rtx insn
, label
, target
;
8291 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
8293 label
= s390_execute_label (insn
);
8297 gcc_assert (label
!= const0_rtx
);
8299 target
= emit_label (XEXP (label
, 0));
8300 INSN_ADDRESSES_NEW (target
, -1);
8302 target
= emit_insn (s390_execute_target (insn
));
8303 INSN_ADDRESSES_NEW (target
, -1);
8307 /* Try to optimize prologue and epilogue further. */
8308 s390_optimize_prologue ();
8312 /* Initialize GCC target structure. */
8314 #undef TARGET_ASM_ALIGNED_HI_OP
8315 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
8316 #undef TARGET_ASM_ALIGNED_DI_OP
8317 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
8318 #undef TARGET_ASM_INTEGER
8319 #define TARGET_ASM_INTEGER s390_assemble_integer
8321 #undef TARGET_ASM_OPEN_PAREN
8322 #define TARGET_ASM_OPEN_PAREN ""
8324 #undef TARGET_ASM_CLOSE_PAREN
8325 #define TARGET_ASM_CLOSE_PAREN ""
8327 #undef TARGET_DEFAULT_TARGET_FLAGS
8328 #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD)
8329 #undef TARGET_HANDLE_OPTION
8330 #define TARGET_HANDLE_OPTION s390_handle_option
8332 #undef TARGET_ENCODE_SECTION_INFO
8333 #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
8336 #undef TARGET_HAVE_TLS
8337 #define TARGET_HAVE_TLS true
8339 #undef TARGET_CANNOT_FORCE_CONST_MEM
8340 #define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
8342 #undef TARGET_DELEGITIMIZE_ADDRESS
8343 #define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
8345 #undef TARGET_RETURN_IN_MEMORY
8346 #define TARGET_RETURN_IN_MEMORY s390_return_in_memory
8348 #undef TARGET_INIT_BUILTINS
8349 #define TARGET_INIT_BUILTINS s390_init_builtins
8350 #undef TARGET_EXPAND_BUILTIN
8351 #define TARGET_EXPAND_BUILTIN s390_expand_builtin
8353 #undef TARGET_ASM_OUTPUT_MI_THUNK
8354 #define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
8355 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
8356 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
8358 #undef TARGET_SCHED_ADJUST_PRIORITY
8359 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
8360 #undef TARGET_SCHED_ISSUE_RATE
8361 #define TARGET_SCHED_ISSUE_RATE s390_issue_rate
8362 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
8363 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
8365 #undef TARGET_CANNOT_COPY_INSN_P
8366 #define TARGET_CANNOT_COPY_INSN_P s390_cannot_copy_insn_p
8367 #undef TARGET_RTX_COSTS
8368 #define TARGET_RTX_COSTS s390_rtx_costs
8369 #undef TARGET_ADDRESS_COST
8370 #define TARGET_ADDRESS_COST s390_address_cost
8372 #undef TARGET_MACHINE_DEPENDENT_REORG
8373 #define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
8375 #undef TARGET_VALID_POINTER_MODE
8376 #define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
8378 #undef TARGET_BUILD_BUILTIN_VA_LIST
8379 #define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
8380 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
8381 #define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg
8383 #undef TARGET_PROMOTE_FUNCTION_ARGS
8384 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
8385 #undef TARGET_PROMOTE_FUNCTION_RETURN
8386 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
8387 #undef TARGET_PASS_BY_REFERENCE
8388 #define TARGET_PASS_BY_REFERENCE s390_pass_by_reference
8390 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
8391 #define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
8393 #undef TARGET_FIXED_CONDITION_CODE_REGS
8394 #define TARGET_FIXED_CONDITION_CODE_REGS s390_fixed_condition_code_regs
8396 #undef TARGET_CC_MODES_COMPATIBLE
8397 #define TARGET_CC_MODES_COMPATIBLE s390_cc_modes_compatible
8399 #undef TARGET_INVALID_WITHIN_DOLOOP
8400 #define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_rtx_null
8403 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
8404 #define TARGET_ASM_OUTPUT_DWARF_DTPREL s390_output_dwarf_dtprel
8407 struct gcc_target targetm
= TARGET_INITIALIZER
;
8409 #include "gt-s390.h"