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, 59 Temple Place - Suite 330, 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 /* Structure used to hold the components of a S/390 memory
167 address. A legitimate address on S/390 is of the general
169 base + index + displacement
170 where any of the components is optional.
172 base and index are registers of the class ADDR_REGS,
173 displacement is an unsigned 12-bit immediate constant. */
183 /* Which cpu are we tuning for. */
184 enum processor_type s390_tune
= PROCESSOR_max
;
185 enum processor_flags s390_tune_flags
;
186 /* Which instruction set architecture to use. */
187 enum processor_type s390_arch
;
188 enum processor_flags s390_arch_flags
;
189 static const char *s390_arch_string
;
191 HOST_WIDE_INT s390_warn_framesize
= 0;
192 HOST_WIDE_INT s390_stack_size
= 0;
193 HOST_WIDE_INT s390_stack_guard
= 0;
195 /* The following structure is embedded in the machine
196 specific part of struct function. */
198 struct s390_frame_layout
GTY (())
200 /* Offset within stack frame. */
201 HOST_WIDE_INT gprs_offset
;
202 HOST_WIDE_INT f0_offset
;
203 HOST_WIDE_INT f4_offset
;
204 HOST_WIDE_INT f8_offset
;
205 HOST_WIDE_INT backchain_offset
;
207 /* Number of first and last gpr to be saved, restored. */
209 int first_restore_gpr
;
211 int last_restore_gpr
;
213 /* Bits standing for floating point registers. Set, if the
214 respective register has to be saved. Starting with reg 16 (f0)
215 at the rightmost bit.
216 Bit 15 - 8 7 6 5 4 3 2 1 0
217 fpr 15 - 8 7 5 3 1 6 4 2 0
218 reg 31 - 24 23 22 21 20 19 18 17 16 */
219 unsigned int fpr_bitmap
;
221 /* Number of floating point registers f8-f15 which must be saved. */
224 /* Set if return address needs to be saved. */
225 bool save_return_addr_p
;
227 /* Size of stack frame. */
228 HOST_WIDE_INT frame_size
;
231 /* Define the structure for the machine field in struct function. */
233 struct machine_function
GTY(())
235 struct s390_frame_layout frame_layout
;
237 /* Literal pool base register. */
240 /* True if we may need to perform branch splitting. */
241 bool split_branches_pending_p
;
243 /* Some local-dynamic TLS symbol name. */
244 const char *some_ld_name
;
247 /* Few accessor macros for struct cfun->machine->s390_frame_layout. */
249 #define cfun_frame_layout (cfun->machine->frame_layout)
250 #define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)
251 #define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr - \
252 cfun_frame_layout.first_save_gpr + 1) * UNITS_PER_WORD)
253 #define cfun_set_fpr_bit(BITNUM) (cfun->machine->frame_layout.fpr_bitmap |= \
255 #define cfun_fpr_bit_p(BITNUM) (!!(cfun->machine->frame_layout.fpr_bitmap & \
258 /* Return true if SET either doesn't set the CC register, or else
259 the source and destination have matching CC modes and that
260 CC mode is at least as constrained as REQ_MODE. */
263 s390_match_ccmode_set (rtx set
, enum machine_mode req_mode
)
265 enum machine_mode set_mode
;
267 gcc_assert (GET_CODE (set
) == SET
);
269 if (GET_CODE (SET_DEST (set
)) != REG
|| !CC_REGNO_P (REGNO (SET_DEST (set
))))
272 set_mode
= GET_MODE (SET_DEST (set
));
286 if (req_mode
!= set_mode
)
291 if (req_mode
!= CCSmode
&& req_mode
!= CCUmode
&& req_mode
!= CCTmode
292 && req_mode
!= CCSRmode
&& req_mode
!= CCURmode
)
298 if (req_mode
!= CCAmode
)
306 return (GET_MODE (SET_SRC (set
)) == set_mode
);
309 /* Return true if every SET in INSN that sets the CC register
310 has source and destination with matching CC modes and that
311 CC mode is at least as constrained as REQ_MODE.
312 If REQ_MODE is VOIDmode, always return false. */
315 s390_match_ccmode (rtx insn
, enum machine_mode req_mode
)
319 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
320 if (req_mode
== VOIDmode
)
323 if (GET_CODE (PATTERN (insn
)) == SET
)
324 return s390_match_ccmode_set (PATTERN (insn
), req_mode
);
326 if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
327 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
329 rtx set
= XVECEXP (PATTERN (insn
), 0, i
);
330 if (GET_CODE (set
) == SET
)
331 if (!s390_match_ccmode_set (set
, req_mode
))
338 /* If a test-under-mask instruction can be used to implement
339 (compare (and ... OP1) OP2), return the CC mode required
340 to do that. Otherwise, return VOIDmode.
341 MIXED is true if the instruction can distinguish between
342 CC1 and CC2 for mixed selected bits (TMxx), it is false
343 if the instruction cannot (TM). */
346 s390_tm_ccmode (rtx op1
, rtx op2
, bool mixed
)
350 /* ??? Fixme: should work on CONST_DOUBLE as well. */
351 if (GET_CODE (op1
) != CONST_INT
|| GET_CODE (op2
) != CONST_INT
)
354 /* Selected bits all zero: CC0.
355 e.g.: int a; if ((a & (16 + 128)) == 0) */
356 if (INTVAL (op2
) == 0)
359 /* Selected bits all one: CC3.
360 e.g.: int a; if ((a & (16 + 128)) == 16 + 128) */
361 if (INTVAL (op2
) == INTVAL (op1
))
364 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. e.g.:
366 if ((a & (16 + 128)) == 16) -> CCT1
367 if ((a & (16 + 128)) == 128) -> CCT2 */
370 bit1
= exact_log2 (INTVAL (op2
));
371 bit0
= exact_log2 (INTVAL (op1
) ^ INTVAL (op2
));
372 if (bit0
!= -1 && bit1
!= -1)
373 return bit0
> bit1
? CCT1mode
: CCT2mode
;
379 /* Given a comparison code OP (EQ, NE, etc.) and the operands
380 OP0 and OP1 of a COMPARE, return the mode to be used for the
384 s390_select_ccmode (enum rtx_code code
, rtx op0
, rtx op1
)
390 if ((GET_CODE (op0
) == NEG
|| GET_CODE (op0
) == ABS
)
391 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
393 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
394 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0
, 1)), 'K', "K"))
396 if ((GET_CODE (op0
) == PLUS
|| GET_CODE (op0
) == MINUS
397 || GET_CODE (op1
) == NEG
)
398 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
401 if (GET_CODE (op0
) == AND
)
403 /* Check whether we can potentially do it via TM. */
404 enum machine_mode ccmode
;
405 ccmode
= s390_tm_ccmode (XEXP (op0
, 1), op1
, 1);
406 if (ccmode
!= VOIDmode
)
408 /* Relax CCTmode to CCZmode to allow fall-back to AND
409 if that turns out to be beneficial. */
410 return ccmode
== CCTmode
? CCZmode
: ccmode
;
414 if (register_operand (op0
, HImode
)
415 && GET_CODE (op1
) == CONST_INT
416 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 65535))
418 if (register_operand (op0
, QImode
)
419 && GET_CODE (op1
) == CONST_INT
420 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 255))
429 /* The only overflow condition of NEG and ABS happens when
430 -INT_MAX is used as parameter, which stays negative. So
431 we have an overflow from a positive value to a negative.
432 Using CCAP mode the resulting cc can be used for comparisons. */
433 if ((GET_CODE (op0
) == NEG
|| GET_CODE (op0
) == ABS
)
434 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
437 /* If constants are involved in an add instruction it is possible to use
438 the resulting cc for comparisons with zero. Knowing the sign of the
439 constant the overflow behavior gets predictable. e.g.:
440 int a, b; if ((b = a + c) > 0)
441 with c as a constant value: c < 0 -> CCAN and c >= 0 -> CCAP */
442 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
443 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0
, 1)), 'K', "K"))
445 if (INTVAL (XEXP((op0
), 1)) < 0)
459 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
460 && GET_CODE (op1
) != CONST_INT
)
466 if (GET_CODE (op0
) == PLUS
467 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
470 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
471 && GET_CODE (op1
) != CONST_INT
)
477 if (GET_CODE (op0
) == MINUS
478 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
481 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
482 && GET_CODE (op1
) != CONST_INT
)
491 /* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
492 that we can implement more efficiently. */
495 s390_canonicalize_comparison (enum rtx_code
*code
, rtx
*op0
, rtx
*op1
)
497 /* Convert ZERO_EXTRACT back to AND to enable TM patterns. */
498 if ((*code
== EQ
|| *code
== NE
)
499 && *op1
== const0_rtx
500 && GET_CODE (*op0
) == ZERO_EXTRACT
501 && GET_CODE (XEXP (*op0
, 1)) == CONST_INT
502 && GET_CODE (XEXP (*op0
, 2)) == CONST_INT
503 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0
, 0))))
505 rtx inner
= XEXP (*op0
, 0);
506 HOST_WIDE_INT modesize
= GET_MODE_BITSIZE (GET_MODE (inner
));
507 HOST_WIDE_INT len
= INTVAL (XEXP (*op0
, 1));
508 HOST_WIDE_INT pos
= INTVAL (XEXP (*op0
, 2));
510 if (len
> 0 && len
< modesize
511 && pos
>= 0 && pos
+ len
<= modesize
512 && modesize
<= HOST_BITS_PER_WIDE_INT
)
514 unsigned HOST_WIDE_INT block
;
515 block
= ((unsigned HOST_WIDE_INT
) 1 << len
) - 1;
516 block
<<= modesize
- pos
- len
;
518 *op0
= gen_rtx_AND (GET_MODE (inner
), inner
,
519 gen_int_mode (block
, GET_MODE (inner
)));
523 /* Narrow AND of memory against immediate to enable TM. */
524 if ((*code
== EQ
|| *code
== NE
)
525 && *op1
== const0_rtx
526 && GET_CODE (*op0
) == AND
527 && GET_CODE (XEXP (*op0
, 1)) == CONST_INT
528 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0
, 0))))
530 rtx inner
= XEXP (*op0
, 0);
531 rtx mask
= XEXP (*op0
, 1);
533 /* Ignore paradoxical SUBREGs if all extra bits are masked out. */
534 if (GET_CODE (inner
) == SUBREG
535 && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (inner
)))
536 && (GET_MODE_SIZE (GET_MODE (inner
))
537 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner
))))
539 & GET_MODE_MASK (GET_MODE (inner
))
540 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (inner
))))
542 inner
= SUBREG_REG (inner
);
544 /* Do not change volatile MEMs. */
545 if (MEM_P (inner
) && !MEM_VOLATILE_P (inner
))
547 int part
= s390_single_part (XEXP (*op0
, 1),
548 GET_MODE (inner
), QImode
, 0);
551 mask
= gen_int_mode (s390_extract_part (mask
, QImode
, 0), QImode
);
552 inner
= adjust_address_nv (inner
, QImode
, part
);
553 *op0
= gen_rtx_AND (QImode
, inner
, mask
);
558 /* Narrow comparisons against 0xffff to HImode if possible. */
559 if ((*code
== EQ
|| *code
== NE
)
560 && GET_CODE (*op1
) == CONST_INT
561 && INTVAL (*op1
) == 0xffff
562 && SCALAR_INT_MODE_P (GET_MODE (*op0
))
563 && (nonzero_bits (*op0
, GET_MODE (*op0
))
564 & ~(unsigned HOST_WIDE_INT
) 0xffff) == 0)
566 *op0
= gen_lowpart (HImode
, *op0
);
571 /* Remove redundant UNSPEC_CMPINT conversions if possible. */
572 if (GET_CODE (*op0
) == UNSPEC
573 && XINT (*op0
, 1) == UNSPEC_CMPINT
574 && XVECLEN (*op0
, 0) == 1
575 && GET_MODE (XVECEXP (*op0
, 0, 0)) == CCUmode
576 && GET_CODE (XVECEXP (*op0
, 0, 0)) == REG
577 && REGNO (XVECEXP (*op0
, 0, 0)) == CC_REGNUM
578 && *op1
== const0_rtx
)
580 enum rtx_code new_code
= UNKNOWN
;
583 case EQ
: new_code
= EQ
; break;
584 case NE
: new_code
= NE
; break;
585 case LT
: new_code
= GTU
; break;
586 case GT
: new_code
= LTU
; break;
587 case LE
: new_code
= GEU
; break;
588 case GE
: new_code
= LEU
; break;
592 if (new_code
!= UNKNOWN
)
594 *op0
= XVECEXP (*op0
, 0, 0);
600 /* Emit a compare instruction suitable to implement the comparison
601 OP0 CODE OP1. Return the correct condition RTL to be placed in
602 the IF_THEN_ELSE of the conditional branch testing the result. */
605 s390_emit_compare (enum rtx_code code
, rtx op0
, rtx op1
)
607 enum machine_mode mode
= s390_select_ccmode (code
, op0
, op1
);
608 rtx cc
= gen_rtx_REG (mode
, CC_REGNUM
);
610 emit_insn (gen_rtx_SET (VOIDmode
, cc
, gen_rtx_COMPARE (mode
, op0
, op1
)));
611 return gen_rtx_fmt_ee (code
, VOIDmode
, cc
, const0_rtx
);
614 /* Emit a jump instruction to TARGET. If COND is NULL_RTX, emit an
615 unconditional jump, else a conditional jump under condition COND. */
618 s390_emit_jump (rtx target
, rtx cond
)
622 target
= gen_rtx_LABEL_REF (VOIDmode
, target
);
624 target
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, target
, pc_rtx
);
626 insn
= gen_rtx_SET (VOIDmode
, pc_rtx
, target
);
627 emit_jump_insn (insn
);
630 /* Return branch condition mask to implement a branch
631 specified by CODE. Return -1 for invalid comparisons. */
634 s390_branch_condition_mask (rtx code
)
636 const int CC0
= 1 << 3;
637 const int CC1
= 1 << 2;
638 const int CC2
= 1 << 1;
639 const int CC3
= 1 << 0;
641 gcc_assert (GET_CODE (XEXP (code
, 0)) == REG
);
642 gcc_assert (REGNO (XEXP (code
, 0)) == CC_REGNUM
);
643 gcc_assert (XEXP (code
, 1) == const0_rtx
);
645 switch (GET_MODE (XEXP (code
, 0)))
648 switch (GET_CODE (code
))
651 case NE
: return CC1
| CC2
| CC3
;
657 switch (GET_CODE (code
))
660 case NE
: return CC0
| CC2
| CC3
;
666 switch (GET_CODE (code
))
669 case NE
: return CC0
| CC1
| CC3
;
675 switch (GET_CODE (code
))
678 case NE
: return CC0
| CC1
| CC2
;
684 switch (GET_CODE (code
))
686 case EQ
: return CC0
| CC2
;
687 case NE
: return CC1
| CC3
;
693 switch (GET_CODE (code
))
695 case LTU
: return CC2
| CC3
; /* carry */
696 case GEU
: return CC0
| CC1
; /* no carry */
702 switch (GET_CODE (code
))
704 case GTU
: return CC0
| CC1
; /* borrow */
705 case LEU
: return CC2
| CC3
; /* no borrow */
711 switch (GET_CODE (code
))
713 case EQ
: return CC0
| CC2
;
714 case NE
: return CC1
| CC3
;
715 case LTU
: return CC1
;
716 case GTU
: return CC3
;
717 case LEU
: return CC1
| CC2
;
718 case GEU
: return CC2
| CC3
;
723 switch (GET_CODE (code
))
726 case NE
: return CC1
| CC2
| CC3
;
727 case LTU
: return CC1
;
728 case GTU
: return CC2
;
729 case LEU
: return CC0
| CC1
;
730 case GEU
: return CC0
| CC2
;
736 switch (GET_CODE (code
))
739 case NE
: return CC2
| CC1
| CC3
;
740 case LTU
: return CC2
;
741 case GTU
: return CC1
;
742 case LEU
: return CC0
| CC2
;
743 case GEU
: return CC0
| CC1
;
749 switch (GET_CODE (code
))
752 case NE
: return CC1
| CC2
| CC3
;
753 case LT
: return CC1
| CC3
;
755 case LE
: return CC0
| CC1
| CC3
;
756 case GE
: return CC0
| CC2
;
762 switch (GET_CODE (code
))
765 case NE
: return CC1
| CC2
| CC3
;
767 case GT
: return CC2
| CC3
;
768 case LE
: return CC0
| CC1
;
769 case GE
: return CC0
| CC2
| CC3
;
775 switch (GET_CODE (code
))
778 case NE
: return CC1
| CC2
| CC3
;
781 case LE
: return CC0
| CC1
;
782 case GE
: return CC0
| CC2
;
783 case UNORDERED
: return CC3
;
784 case ORDERED
: return CC0
| CC1
| CC2
;
785 case UNEQ
: return CC0
| CC3
;
786 case UNLT
: return CC1
| CC3
;
787 case UNGT
: return CC2
| CC3
;
788 case UNLE
: return CC0
| CC1
| CC3
;
789 case UNGE
: return CC0
| CC2
| CC3
;
790 case LTGT
: return CC1
| CC2
;
796 switch (GET_CODE (code
))
799 case NE
: return CC2
| CC1
| CC3
;
802 case LE
: return CC0
| CC2
;
803 case GE
: return CC0
| CC1
;
804 case UNORDERED
: return CC3
;
805 case ORDERED
: return CC0
| CC2
| CC1
;
806 case UNEQ
: return CC0
| CC3
;
807 case UNLT
: return CC2
| CC3
;
808 case UNGT
: return CC1
| CC3
;
809 case UNLE
: return CC0
| CC2
| CC3
;
810 case UNGE
: return CC0
| CC1
| CC3
;
811 case LTGT
: return CC2
| CC1
;
821 /* If INV is false, return assembler mnemonic string to implement
822 a branch specified by CODE. If INV is true, return mnemonic
823 for the corresponding inverted branch. */
826 s390_branch_condition_mnemonic (rtx code
, int inv
)
828 static const char *const mnemonic
[16] =
830 NULL
, "o", "h", "nle",
831 "l", "nhe", "lh", "ne",
832 "e", "nlh", "he", "nl",
833 "le", "nh", "no", NULL
836 int mask
= s390_branch_condition_mask (code
);
837 gcc_assert (mask
>= 0);
842 gcc_assert (mask
>= 1 && mask
<= 14);
844 return mnemonic
[mask
];
847 /* Return the part of op which has a value different from def.
848 The size of the part is determined by mode.
849 Use this function only if you already know that op really
850 contains such a part. */
852 unsigned HOST_WIDE_INT
853 s390_extract_part (rtx op
, enum machine_mode mode
, int def
)
855 unsigned HOST_WIDE_INT value
= 0;
856 int max_parts
= HOST_BITS_PER_WIDE_INT
/ GET_MODE_BITSIZE (mode
);
857 int part_bits
= GET_MODE_BITSIZE (mode
);
858 unsigned HOST_WIDE_INT part_mask
= (1 << part_bits
) - 1;
861 for (i
= 0; i
< max_parts
; i
++)
864 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
868 if ((value
& part_mask
) != (def
& part_mask
))
869 return value
& part_mask
;
875 /* If OP is an integer constant of mode MODE with exactly one
876 part of mode PART_MODE unequal to DEF, return the number of that
877 part. Otherwise, return -1. */
880 s390_single_part (rtx op
,
881 enum machine_mode mode
,
882 enum machine_mode part_mode
,
885 unsigned HOST_WIDE_INT value
= 0;
886 int n_parts
= GET_MODE_SIZE (mode
) / GET_MODE_SIZE (part_mode
);
887 unsigned HOST_WIDE_INT part_mask
= (1 << GET_MODE_BITSIZE (part_mode
)) - 1;
890 if (GET_CODE (op
) != CONST_INT
)
893 for (i
= 0; i
< n_parts
; i
++)
896 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
898 value
>>= GET_MODE_BITSIZE (part_mode
);
900 if ((value
& part_mask
) != (def
& part_mask
))
908 return part
== -1 ? -1 : n_parts
- 1 - part
;
911 /* Check whether we can (and want to) split a double-word
912 move in mode MODE from SRC to DST into two single-word
913 moves, moving the subword FIRST_SUBWORD first. */
916 s390_split_ok_p (rtx dst
, rtx src
, enum machine_mode mode
, int first_subword
)
918 /* Floating point registers cannot be split. */
919 if (FP_REG_P (src
) || FP_REG_P (dst
))
922 /* We don't need to split if operands are directly accessible. */
923 if (s_operand (src
, mode
) || s_operand (dst
, mode
))
926 /* Non-offsettable memory references cannot be split. */
927 if ((GET_CODE (src
) == MEM
&& !offsettable_memref_p (src
))
928 || (GET_CODE (dst
) == MEM
&& !offsettable_memref_p (dst
)))
931 /* Moving the first subword must not clobber a register
932 needed to move the second subword. */
933 if (register_operand (dst
, mode
))
935 rtx subreg
= operand_subword (dst
, first_subword
, 0, mode
);
936 if (reg_overlap_mentioned_p (subreg
, src
))
943 /* Check whether the address of memory reference MEM2 equals exactly
944 the address of memory reference MEM1 plus DELTA. Return true if
945 we can prove this to be the case, false otherwise. */
948 s390_offset_p (rtx mem1
, rtx mem2
, rtx delta
)
950 rtx addr1
, addr2
, addr_delta
;
952 if (GET_CODE (mem1
) != MEM
|| GET_CODE (mem2
) != MEM
)
955 addr1
= XEXP (mem1
, 0);
956 addr2
= XEXP (mem2
, 0);
958 addr_delta
= simplify_binary_operation (MINUS
, Pmode
, addr2
, addr1
);
959 if (!addr_delta
|| !rtx_equal_p (addr_delta
, delta
))
965 /* Expand logical operator CODE in mode MODE with operands OPERANDS. */
968 s390_expand_logical_operator (enum rtx_code code
, enum machine_mode mode
,
971 enum machine_mode wmode
= mode
;
972 rtx dst
= operands
[0];
973 rtx src1
= operands
[1];
974 rtx src2
= operands
[2];
977 /* If we cannot handle the operation directly, use a temp register. */
978 if (!s390_logical_operator_ok_p (operands
))
979 dst
= gen_reg_rtx (mode
);
981 /* QImode and HImode patterns make sense only if we have a destination
982 in memory. Otherwise perform the operation in SImode. */
983 if ((mode
== QImode
|| mode
== HImode
) && GET_CODE (dst
) != MEM
)
986 /* Widen operands if required. */
989 if (GET_CODE (dst
) == SUBREG
990 && (tem
= simplify_subreg (wmode
, dst
, mode
, 0)) != 0)
992 else if (REG_P (dst
))
993 dst
= gen_rtx_SUBREG (wmode
, dst
, 0);
995 dst
= gen_reg_rtx (wmode
);
997 if (GET_CODE (src1
) == SUBREG
998 && (tem
= simplify_subreg (wmode
, src1
, mode
, 0)) != 0)
1000 else if (GET_MODE (src1
) != VOIDmode
)
1001 src1
= gen_rtx_SUBREG (wmode
, force_reg (mode
, src1
), 0);
1003 if (GET_CODE (src2
) == SUBREG
1004 && (tem
= simplify_subreg (wmode
, src2
, mode
, 0)) != 0)
1006 else if (GET_MODE (src2
) != VOIDmode
)
1007 src2
= gen_rtx_SUBREG (wmode
, force_reg (mode
, src2
), 0);
1010 /* Emit the instruction. */
1011 op
= gen_rtx_SET (VOIDmode
, dst
, gen_rtx_fmt_ee (code
, wmode
, src1
, src2
));
1012 clob
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
1013 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, op
, clob
)));
1015 /* Fix up the destination if needed. */
1016 if (dst
!= operands
[0])
1017 emit_move_insn (operands
[0], gen_lowpart (mode
, dst
));
1020 /* Check whether OPERANDS are OK for a logical operation (AND, IOR, XOR). */
1023 s390_logical_operator_ok_p (rtx
*operands
)
1025 /* If the destination operand is in memory, it needs to coincide
1026 with one of the source operands. After reload, it has to be
1027 the first source operand. */
1028 if (GET_CODE (operands
[0]) == MEM
)
1029 return rtx_equal_p (operands
[0], operands
[1])
1030 || (!reload_completed
&& rtx_equal_p (operands
[0], operands
[2]));
1035 /* Narrow logical operation CODE of memory operand MEMOP with immediate
1036 operand IMMOP to switch from SS to SI type instructions. */
1039 s390_narrow_logical_operator (enum rtx_code code
, rtx
*memop
, rtx
*immop
)
1041 int def
= code
== AND
? -1 : 0;
1045 gcc_assert (GET_CODE (*memop
) == MEM
);
1046 gcc_assert (!MEM_VOLATILE_P (*memop
));
1048 mask
= s390_extract_part (*immop
, QImode
, def
);
1049 part
= s390_single_part (*immop
, GET_MODE (*memop
), QImode
, def
);
1050 gcc_assert (part
>= 0);
1052 *memop
= adjust_address (*memop
, QImode
, part
);
1053 *immop
= gen_int_mode (mask
, QImode
);
1057 /* How to allocate a 'struct machine_function'. */
1059 static struct machine_function
*
1060 s390_init_machine_status (void)
1062 return ggc_alloc_cleared (sizeof (struct machine_function
));
1065 /* Change optimizations to be performed, depending on the
1068 LEVEL is the optimization level specified; 2 if `-O2' is
1069 specified, 1 if `-O' is specified, and 0 if neither is specified.
1071 SIZE is nonzero if `-Os' is specified and zero otherwise. */
1074 optimization_options (int level ATTRIBUTE_UNUSED
, int size ATTRIBUTE_UNUSED
)
1076 /* ??? There are apparently still problems with -fcaller-saves. */
1077 flag_caller_saves
= 0;
1079 /* By default, always emit DWARF-2 unwind info. This allows debugging
1080 without maintaining a stack frame back-chain. */
1081 flag_asynchronous_unwind_tables
= 1;
1084 /* Return true if ARG is the name of a processor. Set *TYPE and *FLAGS
1085 to the associated processor_type and processor_flags if so. */
1088 s390_handle_arch_option (const char *arg
,
1089 enum processor_type
*type
,
1090 enum processor_flags
*flags
)
1094 const char *const name
; /* processor name or nickname. */
1095 const enum processor_type processor
;
1096 const enum processor_flags flags
;
1098 const processor_alias_table
[] =
1100 {"g5", PROCESSOR_9672_G5
, PF_IEEE_FLOAT
},
1101 {"g6", PROCESSOR_9672_G6
, PF_IEEE_FLOAT
},
1102 {"z900", PROCESSOR_2064_Z900
, PF_IEEE_FLOAT
| PF_ZARCH
},
1103 {"z990", PROCESSOR_2084_Z990
, PF_IEEE_FLOAT
| PF_ZARCH
1104 | PF_LONG_DISPLACEMENT
},
1108 for (i
= 0; i
< ARRAY_SIZE (processor_alias_table
); i
++)
1109 if (strcmp (arg
, processor_alias_table
[i
].name
) == 0)
1111 *type
= processor_alias_table
[i
].processor
;
1112 *flags
= processor_alias_table
[i
].flags
;
1118 /* Implement TARGET_HANDLE_OPTION. */
1121 s390_handle_option (size_t code
, const char *arg
, int value ATTRIBUTE_UNUSED
)
1126 s390_arch_string
= arg
;
1127 return s390_handle_arch_option (arg
, &s390_arch
, &s390_arch_flags
);
1129 case OPT_mstack_guard_
:
1130 if (sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_stack_guard
) != 1)
1132 if (exact_log2 (s390_stack_guard
) == -1)
1133 error ("stack guard value must be an exact power of 2");
1136 case OPT_mstack_size_
:
1137 if (sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_stack_size
) != 1)
1139 if (exact_log2 (s390_stack_size
) == -1)
1140 error ("stack size must be an exact power of 2");
1144 return s390_handle_arch_option (arg
, &s390_tune
, &s390_tune_flags
);
1146 case OPT_mwarn_framesize_
:
1147 return sscanf (arg
, HOST_WIDE_INT_PRINT_DEC
, &s390_warn_framesize
) == 1;
1155 override_options (void)
1157 /* Acquire a unique set number for our register saves and restores. */
1158 s390_sr_alias_set
= new_alias_set ();
1160 /* Set up function hooks. */
1161 init_machine_status
= s390_init_machine_status
;
1163 /* Architecture mode defaults according to ABI. */
1164 if (!(target_flags_explicit
& MASK_ZARCH
))
1167 target_flags
|= MASK_ZARCH
;
1169 target_flags
&= ~MASK_ZARCH
;
1172 /* Determine processor architectural level. */
1173 if (!s390_arch_string
)
1175 s390_arch_string
= TARGET_ZARCH
? "z900" : "g5";
1176 s390_handle_arch_option (s390_arch_string
, &s390_arch
, &s390_arch_flags
);
1179 /* Determine processor to tune for. */
1180 if (s390_tune
== PROCESSOR_max
)
1182 s390_tune
= s390_arch
;
1183 s390_tune_flags
= s390_arch_flags
;
1186 /* Sanity checks. */
1187 if (TARGET_ZARCH
&& !(s390_arch_flags
& PF_ZARCH
))
1188 error ("z/Architecture mode not supported on %s.", s390_arch_string
);
1189 if (TARGET_64BIT
&& !TARGET_ZARCH
)
1190 error ("64-bit ABI not supported in ESA/390 mode.");
1193 /* Set processor cost function. */
1194 if (s390_tune
== PROCESSOR_2084_Z990
)
1195 s390_cost
= &z990_cost
;
1197 s390_cost
= &z900_cost
;
1200 if (TARGET_BACKCHAIN
&& TARGET_PACKED_STACK
&& TARGET_HARD_FLOAT
)
1201 error ("-mbackchain -mpacked-stack -mhard-float are not supported "
1204 if (s390_stack_size
)
1206 if (!s390_stack_guard
)
1207 error ("-mstack-size implies use of -mstack-guard");
1208 else if (s390_stack_guard
>= s390_stack_size
)
1209 error ("stack size must be greater than the stack guard value");
1211 else if (s390_stack_guard
)
1212 error ("-mstack-guard implies use of -mstack-size");
1215 /* Map for smallest class containing reg regno. */
1217 const enum reg_class regclass_map
[FIRST_PSEUDO_REGISTER
] =
1218 { GENERAL_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1219 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1220 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1221 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1222 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1223 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1224 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1225 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1226 ADDR_REGS
, CC_REGS
, ADDR_REGS
, ADDR_REGS
,
1227 ACCESS_REGS
, ACCESS_REGS
1230 /* Return attribute type of insn. */
1232 static enum attr_type
1233 s390_safe_attr_type (rtx insn
)
1235 if (recog_memoized (insn
) >= 0)
1236 return get_attr_type (insn
);
1241 /* Return true if DISP is a valid short displacement. */
1244 s390_short_displacement (rtx disp
)
1246 /* No displacement is OK. */
1250 /* Integer displacement in range. */
1251 if (GET_CODE (disp
) == CONST_INT
)
1252 return INTVAL (disp
) >= 0 && INTVAL (disp
) < 4096;
1254 /* GOT offset is not OK, the GOT can be large. */
1255 if (GET_CODE (disp
) == CONST
1256 && GET_CODE (XEXP (disp
, 0)) == UNSPEC
1257 && (XINT (XEXP (disp
, 0), 1) == UNSPEC_GOT
1258 || XINT (XEXP (disp
, 0), 1) == UNSPEC_GOTNTPOFF
))
1261 /* All other symbolic constants are literal pool references,
1262 which are OK as the literal pool must be small. */
1263 if (GET_CODE (disp
) == CONST
)
1269 /* Decompose a RTL expression ADDR for a memory address into
1270 its components, returned in OUT.
1272 Returns false if ADDR is not a valid memory address, true
1273 otherwise. If OUT is NULL, don't return the components,
1274 but check for validity only.
1276 Note: Only addresses in canonical form are recognized.
1277 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
1278 canonical form so that they will be recognized. */
1281 s390_decompose_address (rtx addr
, struct s390_address
*out
)
1283 HOST_WIDE_INT offset
= 0;
1284 rtx base
= NULL_RTX
;
1285 rtx indx
= NULL_RTX
;
1286 rtx disp
= NULL_RTX
;
1288 bool pointer
= false;
1289 bool base_ptr
= false;
1290 bool indx_ptr
= false;
1292 /* Decompose address into base + index + displacement. */
1294 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == UNSPEC
)
1297 else if (GET_CODE (addr
) == PLUS
)
1299 rtx op0
= XEXP (addr
, 0);
1300 rtx op1
= XEXP (addr
, 1);
1301 enum rtx_code code0
= GET_CODE (op0
);
1302 enum rtx_code code1
= GET_CODE (op1
);
1304 if (code0
== REG
|| code0
== UNSPEC
)
1306 if (code1
== REG
|| code1
== UNSPEC
)
1308 indx
= op0
; /* index + base */
1314 base
= op0
; /* base + displacement */
1319 else if (code0
== PLUS
)
1321 indx
= XEXP (op0
, 0); /* index + base + disp */
1322 base
= XEXP (op0
, 1);
1333 disp
= addr
; /* displacement */
1335 /* Extract integer part of displacement. */
1339 if (GET_CODE (disp
) == CONST_INT
)
1341 offset
= INTVAL (disp
);
1344 else if (GET_CODE (disp
) == CONST
1345 && GET_CODE (XEXP (disp
, 0)) == PLUS
1346 && GET_CODE (XEXP (XEXP (disp
, 0), 1)) == CONST_INT
)
1348 offset
= INTVAL (XEXP (XEXP (disp
, 0), 1));
1349 disp
= XEXP (XEXP (disp
, 0), 0);
1353 /* Strip off CONST here to avoid special case tests later. */
1354 if (disp
&& GET_CODE (disp
) == CONST
)
1355 disp
= XEXP (disp
, 0);
1357 /* We can convert literal pool addresses to
1358 displacements by basing them off the base register. */
1359 if (disp
&& GET_CODE (disp
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (disp
))
1361 /* Either base or index must be free to hold the base register. */
1363 base
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1365 indx
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1369 /* Mark up the displacement. */
1370 disp
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, disp
),
1371 UNSPEC_LTREL_OFFSET
);
1374 /* Validate base register. */
1377 if (GET_CODE (base
) == UNSPEC
)
1378 switch (XINT (base
, 1))
1382 disp
= gen_rtx_UNSPEC (Pmode
,
1383 gen_rtvec (1, XVECEXP (base
, 0, 0)),
1384 UNSPEC_LTREL_OFFSET
);
1388 base
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1391 case UNSPEC_LTREL_BASE
:
1392 base
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1399 if (GET_CODE (base
) != REG
|| GET_MODE (base
) != Pmode
)
1402 if (REGNO (base
) == BASE_REGNUM
1403 || REGNO (base
) == STACK_POINTER_REGNUM
1404 || REGNO (base
) == FRAME_POINTER_REGNUM
1405 || ((reload_completed
|| reload_in_progress
)
1406 && frame_pointer_needed
1407 && REGNO (base
) == HARD_FRAME_POINTER_REGNUM
)
1408 || REGNO (base
) == ARG_POINTER_REGNUM
1410 && REGNO (base
) == PIC_OFFSET_TABLE_REGNUM
))
1411 pointer
= base_ptr
= true;
1414 /* Validate index register. */
1417 if (GET_CODE (indx
) == UNSPEC
)
1418 switch (XINT (indx
, 1))
1422 disp
= gen_rtx_UNSPEC (Pmode
,
1423 gen_rtvec (1, XVECEXP (indx
, 0, 0)),
1424 UNSPEC_LTREL_OFFSET
);
1428 indx
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1431 case UNSPEC_LTREL_BASE
:
1432 indx
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
1439 if (GET_CODE (indx
) != REG
|| GET_MODE (indx
) != Pmode
)
1442 if (REGNO (indx
) == BASE_REGNUM
1443 || REGNO (indx
) == STACK_POINTER_REGNUM
1444 || REGNO (indx
) == FRAME_POINTER_REGNUM
1445 || ((reload_completed
|| reload_in_progress
)
1446 && frame_pointer_needed
1447 && REGNO (indx
) == HARD_FRAME_POINTER_REGNUM
)
1448 || REGNO (indx
) == ARG_POINTER_REGNUM
1450 && REGNO (indx
) == PIC_OFFSET_TABLE_REGNUM
))
1451 pointer
= indx_ptr
= true;
1454 /* Prefer to use pointer as base, not index. */
1455 if (base
&& indx
&& !base_ptr
1456 && (indx_ptr
|| (!REG_POINTER (base
) && REG_POINTER (indx
))))
1463 /* Validate displacement. */
1466 /* If the argument pointer or the return address pointer are involved,
1467 the displacement will change later anyway as the virtual registers get
1468 eliminated. This could make a valid displacement invalid, but it is
1469 more likely to make an invalid displacement valid, because we sometimes
1470 access the register save area via negative offsets to one of those
1472 Thus we don't check the displacement for validity here. If after
1473 elimination the displacement turns out to be invalid after all,
1474 this is fixed up by reload in any case. */
1475 if (base
!= arg_pointer_rtx
1476 && indx
!= arg_pointer_rtx
1477 && base
!= return_address_pointer_rtx
1478 && indx
!= return_address_pointer_rtx
)
1479 if (!DISP_IN_RANGE (offset
))
1484 /* All the special cases are pointers. */
1487 /* In the small-PIC case, the linker converts @GOT
1488 and @GOTNTPOFF offsets to possible displacements. */
1489 if (GET_CODE (disp
) == UNSPEC
1490 && (XINT (disp
, 1) == UNSPEC_GOT
1491 || XINT (disp
, 1) == UNSPEC_GOTNTPOFF
)
1498 /* Accept chunkified literal pool symbol references. */
1499 else if (GET_CODE (disp
) == MINUS
1500 && GET_CODE (XEXP (disp
, 0)) == LABEL_REF
1501 && GET_CODE (XEXP (disp
, 1)) == LABEL_REF
)
1506 /* Accept literal pool references. */
1507 else if (GET_CODE (disp
) == UNSPEC
1508 && XINT (disp
, 1) == UNSPEC_LTREL_OFFSET
)
1510 orig_disp
= gen_rtx_CONST (Pmode
, disp
);
1513 /* If we have an offset, make sure it does not
1514 exceed the size of the constant pool entry. */
1515 rtx sym
= XVECEXP (disp
, 0, 0);
1516 if (offset
>= GET_MODE_SIZE (get_pool_mode (sym
)))
1519 orig_disp
= plus_constant (orig_disp
, offset
);
1534 out
->disp
= orig_disp
;
1535 out
->pointer
= pointer
;
1541 /* Return true if CODE is a valid address without index. */
1544 s390_legitimate_address_without_index_p (rtx op
)
1546 struct s390_address addr
;
1548 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1556 /* Return 1 if OP is a valid operand for a C constraint, 0 else. */
1559 s390_extra_constraint_str (rtx op
, int c
, const char * str
)
1561 struct s390_address addr
;
1563 gcc_assert (c
== str
[0]);
1565 /* Check for offsettable variants of memory constraints. */
1568 /* Only accept non-volatile MEMs. */
1569 if (!MEM_P (op
) || MEM_VOLATILE_P (op
))
1572 if ((reload_completed
|| reload_in_progress
)
1573 ? !offsettable_memref_p (op
)
1574 : !offsettable_nonstrict_memref_p (op
))
1580 /* Check for non-literal-pool variants of memory constraints. */
1583 if (GET_CODE (op
) != MEM
)
1585 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1587 if (addr
.base
&& REG_P (addr
.base
) && REGNO (addr
.base
) == BASE_REGNUM
)
1589 if (addr
.indx
&& REG_P (addr
.indx
) && REGNO (addr
.indx
) == BASE_REGNUM
)
1598 if (GET_CODE (op
) != MEM
)
1600 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1605 if (TARGET_LONG_DISPLACEMENT
)
1607 if (!s390_short_displacement (addr
.disp
))
1613 if (GET_CODE (op
) != MEM
)
1616 if (TARGET_LONG_DISPLACEMENT
)
1618 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1620 if (!s390_short_displacement (addr
.disp
))
1626 if (!TARGET_LONG_DISPLACEMENT
)
1628 if (GET_CODE (op
) != MEM
)
1630 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1634 if (s390_short_displacement (addr
.disp
))
1639 if (!TARGET_LONG_DISPLACEMENT
)
1641 if (GET_CODE (op
) != MEM
)
1643 /* Any invalid address here will be fixed up by reload,
1644 so accept it for the most generic constraint. */
1645 if (s390_decompose_address (XEXP (op
, 0), &addr
)
1646 && s390_short_displacement (addr
.disp
))
1651 if (TARGET_LONG_DISPLACEMENT
)
1653 if (!s390_decompose_address (op
, &addr
))
1655 if (!s390_short_displacement (addr
.disp
))
1661 if (!TARGET_LONG_DISPLACEMENT
)
1663 /* Any invalid address here will be fixed up by reload,
1664 so accept it for the most generic constraint. */
1665 if (s390_decompose_address (op
, &addr
)
1666 && s390_short_displacement (addr
.disp
))
1671 return shift_count_operand (op
, VOIDmode
);
1680 /* Return true if VALUE matches the constraint STR. */
1683 s390_const_double_ok_for_constraint_p (rtx value
,
1687 gcc_assert (c
== str
[0]);
1692 /* The floating point zero constant. */
1693 return (GET_MODE_CLASS (GET_MODE (value
)) == MODE_FLOAT
1694 && value
== CONST0_RTX (GET_MODE (value
)));
1701 /* Return true if VALUE matches the constraint STR. */
1704 s390_const_ok_for_constraint_p (HOST_WIDE_INT value
,
1708 enum machine_mode mode
, part_mode
;
1710 int part
, part_goal
;
1712 gcc_assert (c
== str
[0]);
1717 return (unsigned int)value
< 256;
1720 return (unsigned int)value
< 4096;
1723 return value
>= -32768 && value
< 32768;
1726 return (TARGET_LONG_DISPLACEMENT
?
1727 (value
>= -524288 && value
<= 524287)
1728 : (value
>= 0 && value
<= 4095));
1730 return value
== 2147483647;
1736 part_goal
= str
[1] - '0';
1740 case 'H': part_mode
= HImode
; break;
1741 case 'Q': part_mode
= QImode
; break;
1747 case 'H': mode
= HImode
; break;
1748 case 'S': mode
= SImode
; break;
1749 case 'D': mode
= DImode
; break;
1755 case '0': def
= 0; break;
1756 case 'F': def
= -1; break;
1760 if (GET_MODE_SIZE (mode
) <= GET_MODE_SIZE (part_mode
))
1763 part
= s390_single_part (GEN_INT (value
), mode
, part_mode
, def
);
1766 if (part_goal
!= -1 && part_goal
!= part
)
1778 /* Compute a (partial) cost for rtx X. Return true if the complete
1779 cost has been computed, and false if subexpressions should be
1780 scanned. In either case, *TOTAL contains the cost result.
1781 CODE contains GET_CODE (x), OUTER_CODE contains the code
1782 of the superexpression of x. */
1785 s390_rtx_costs (rtx x
, int code
, int outer_code
, int *total
)
1808 *total
= COSTS_N_INSNS (1);
1813 /* Check for multiply and add. */
1814 if ((GET_MODE (x
) == DFmode
|| GET_MODE (x
) == SFmode
)
1815 && GET_CODE (XEXP (x
, 0)) == MULT
1816 && TARGET_HARD_FLOAT
&& TARGET_IEEE_FLOAT
&& TARGET_FUSED_MADD
)
1818 /* This is the multiply and add case. */
1819 if (GET_MODE (x
) == DFmode
)
1820 *total
= s390_cost
->madbr
;
1822 *total
= s390_cost
->maebr
;
1823 *total
+= rtx_cost (XEXP (XEXP (x
, 0), 0), MULT
)
1824 + rtx_cost (XEXP (XEXP (x
, 0), 1), MULT
)
1825 + rtx_cost (XEXP (x
, 1), code
);
1826 return true; /* Do not do an additional recursive descent. */
1828 *total
= COSTS_N_INSNS (1);
1832 switch (GET_MODE (x
))
1836 rtx left
= XEXP (x
, 0);
1837 rtx right
= XEXP (x
, 1);
1838 if (GET_CODE (right
) == CONST_INT
1839 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (right
), 'K', "K"))
1840 *total
= s390_cost
->mhi
;
1841 else if (GET_CODE (left
) == SIGN_EXTEND
)
1842 *total
= s390_cost
->mh
;
1844 *total
= s390_cost
->ms
; /* msr, ms, msy */
1849 rtx left
= XEXP (x
, 0);
1850 rtx right
= XEXP (x
, 1);
1853 if (GET_CODE (right
) == CONST_INT
1854 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (right
), 'K', "K"))
1855 *total
= s390_cost
->mghi
;
1856 else if (GET_CODE (left
) == SIGN_EXTEND
)
1857 *total
= s390_cost
->msgf
;
1859 *total
= s390_cost
->msg
; /* msgr, msg */
1861 else /* TARGET_31BIT */
1863 if (GET_CODE (left
) == SIGN_EXTEND
1864 && GET_CODE (right
) == SIGN_EXTEND
)
1865 /* mulsidi case: mr, m */
1866 *total
= s390_cost
->m
;
1867 else if (GET_CODE (left
) == ZERO_EXTEND
1868 && GET_CODE (right
) == ZERO_EXTEND
1869 && TARGET_CPU_ZARCH
)
1870 /* umulsidi case: ml, mlr */
1871 *total
= s390_cost
->ml
;
1873 /* Complex calculation is required. */
1874 *total
= COSTS_N_INSNS (40);
1880 *total
= s390_cost
->mult_df
;
1889 if (GET_MODE (x
) == TImode
) /* 128 bit division */
1890 *total
= s390_cost
->dlgr
;
1891 else if (GET_MODE (x
) == DImode
)
1893 rtx right
= XEXP (x
, 1);
1894 if (GET_CODE (right
) == ZERO_EXTEND
) /* 64 by 32 bit division */
1895 *total
= s390_cost
->dlr
;
1896 else /* 64 by 64 bit division */
1897 *total
= s390_cost
->dlgr
;
1899 else if (GET_MODE (x
) == SImode
) /* 32 bit division */
1900 *total
= s390_cost
->dlr
;
1905 if (GET_MODE (x
) == DImode
)
1907 rtx right
= XEXP (x
, 1);
1908 if (GET_CODE (right
) == ZERO_EXTEND
) /* 64 by 32 bit division */
1910 *total
= s390_cost
->dsgfr
;
1912 *total
= s390_cost
->dr
;
1913 else /* 64 by 64 bit division */
1914 *total
= s390_cost
->dsgr
;
1916 else if (GET_MODE (x
) == SImode
) /* 32 bit division */
1917 *total
= s390_cost
->dlr
;
1918 else if (GET_MODE (x
) == SFmode
)
1920 if (TARGET_IEEE_FLOAT
)
1921 *total
= s390_cost
->debr
;
1922 else /* TARGET_IBM_FLOAT */
1923 *total
= s390_cost
->der
;
1925 else if (GET_MODE (x
) == DFmode
)
1927 if (TARGET_IEEE_FLOAT
)
1928 *total
= s390_cost
->ddbr
;
1929 else /* TARGET_IBM_FLOAT */
1930 *total
= s390_cost
->ddr
;
1935 if (GET_MODE (x
) == SFmode
)
1936 *total
= s390_cost
->sqebr
;
1938 *total
= s390_cost
->sqdbr
;
1943 if (outer_code
== MULT
|| outer_code
== DIV
|| outer_code
== MOD
1944 || outer_code
== PLUS
|| outer_code
== MINUS
1945 || outer_code
== COMPARE
)
1950 *total
= COSTS_N_INSNS (1);
1951 if (GET_CODE (XEXP (x
, 0)) == AND
1952 && GET_CODE (XEXP (x
, 1)) == CONST_INT
1953 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
)
1955 rtx op0
= XEXP (XEXP (x
, 0), 0);
1956 rtx op1
= XEXP (XEXP (x
, 0), 1);
1957 rtx op2
= XEXP (x
, 1);
1959 if (memory_operand (op0
, GET_MODE (op0
))
1960 && s390_tm_ccmode (op1
, op2
, 0) != VOIDmode
)
1962 if (register_operand (op0
, GET_MODE (op0
))
1963 && s390_tm_ccmode (op1
, op2
, 1) != VOIDmode
)
1973 /* Return the cost of an address rtx ADDR. */
1976 s390_address_cost (rtx addr
)
1978 struct s390_address ad
;
1979 if (!s390_decompose_address (addr
, &ad
))
1982 return ad
.indx
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
1985 /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
1986 otherwise return 0. */
1989 tls_symbolic_operand (rtx op
)
1991 if (GET_CODE (op
) != SYMBOL_REF
)
1993 return SYMBOL_REF_TLS_MODEL (op
);
1996 /* Split DImode access register reference REG (on 64-bit) into its constituent
1997 low and high parts, and store them into LO and HI. Note that gen_lowpart/
1998 gen_highpart cannot be used as they assume all registers are word-sized,
1999 while our access registers have only half that size. */
2002 s390_split_access_reg (rtx reg
, rtx
*lo
, rtx
*hi
)
2004 gcc_assert (TARGET_64BIT
);
2005 gcc_assert (ACCESS_REG_P (reg
));
2006 gcc_assert (GET_MODE (reg
) == DImode
);
2007 gcc_assert (!(REGNO (reg
) & 1));
2009 *lo
= gen_rtx_REG (SImode
, REGNO (reg
) + 1);
2010 *hi
= gen_rtx_REG (SImode
, REGNO (reg
));
2013 /* Return true if OP contains a symbol reference */
2016 symbolic_reference_mentioned_p (rtx op
)
2021 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
2024 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
2025 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
2031 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
2032 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
2036 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
2043 /* Return true if OP contains a reference to a thread-local symbol. */
2046 tls_symbolic_reference_mentioned_p (rtx op
)
2051 if (GET_CODE (op
) == SYMBOL_REF
)
2052 return tls_symbolic_operand (op
);
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 (tls_symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
2066 else if (fmt
[i
] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op
, i
)))
2074 /* Return true if OP is a legitimate general operand when
2075 generating PIC code. It is given that flag_pic is on
2076 and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2079 legitimate_pic_operand_p (rtx op
)
2081 /* Accept all non-symbolic constants. */
2082 if (!SYMBOLIC_CONST (op
))
2085 /* Reject everything else; must be handled
2086 via emit_symbolic_move. */
2090 /* Returns true if the constant value OP is a legitimate general operand.
2091 It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2094 legitimate_constant_p (rtx op
)
2096 /* Accept all non-symbolic constants. */
2097 if (!SYMBOLIC_CONST (op
))
2100 /* Accept immediate LARL operands. */
2101 if (TARGET_CPU_ZARCH
&& larl_operand (op
, VOIDmode
))
2104 /* Thread-local symbols are never legal constants. This is
2105 so that emit_call knows that computing such addresses
2106 might require a function call. */
2107 if (TLS_SYMBOLIC_CONST (op
))
2110 /* In the PIC case, symbolic constants must *not* be
2111 forced into the literal pool. We accept them here,
2112 so that they will be handled by emit_symbolic_move. */
2116 /* All remaining non-PIC symbolic constants are
2117 forced into the literal pool. */
2121 /* Determine if it's legal to put X into the constant pool. This
2122 is not possible if X contains the address of a symbol that is
2123 not constant (TLS) or not known at final link time (PIC). */
2126 s390_cannot_force_const_mem (rtx x
)
2128 switch (GET_CODE (x
))
2132 /* Accept all non-symbolic constants. */
2136 /* Labels are OK iff we are non-PIC. */
2137 return flag_pic
!= 0;
2140 /* 'Naked' TLS symbol references are never OK,
2141 non-TLS symbols are OK iff we are non-PIC. */
2142 if (tls_symbolic_operand (x
))
2145 return flag_pic
!= 0;
2148 return s390_cannot_force_const_mem (XEXP (x
, 0));
2151 return s390_cannot_force_const_mem (XEXP (x
, 0))
2152 || s390_cannot_force_const_mem (XEXP (x
, 1));
2155 switch (XINT (x
, 1))
2157 /* Only lt-relative or GOT-relative UNSPECs are OK. */
2158 case UNSPEC_LTREL_OFFSET
:
2166 case UNSPEC_GOTNTPOFF
:
2167 case UNSPEC_INDNTPOFF
:
2170 /* If the literal pool shares the code section, be put
2171 execute template placeholders into the pool as well. */
2173 return TARGET_CPU_ZARCH
;
2185 /* Returns true if the constant value OP is a legitimate general
2186 operand during and after reload. The difference to
2187 legitimate_constant_p is that this function will not accept
2188 a constant that would need to be forced to the literal pool
2189 before it can be used as operand. */
2192 legitimate_reload_constant_p (rtx op
)
2194 /* Accept la(y) operands. */
2195 if (GET_CODE (op
) == CONST_INT
2196 && DISP_IN_RANGE (INTVAL (op
)))
2199 /* Accept l(g)hi operands. */
2200 if (GET_CODE (op
) == CONST_INT
2201 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op
), 'K', "K"))
2204 /* Accept lliXX operands. */
2206 && s390_single_part (op
, DImode
, HImode
, 0) >= 0)
2209 /* Accept larl operands. */
2210 if (TARGET_CPU_ZARCH
2211 && larl_operand (op
, VOIDmode
))
2214 /* Accept lzXX operands. */
2215 if (GET_CODE (op
) == CONST_DOUBLE
2216 && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op
, 'G', "G"))
2219 /* Everything else cannot be handled without reload. */
2223 /* Given an rtx OP being reloaded into a reg required to be in class CLASS,
2224 return the class of reg to actually use. */
2227 s390_preferred_reload_class (rtx op
, enum reg_class
class)
2229 switch (GET_CODE (op
))
2231 /* Constants we cannot reload must be forced into the
2236 if (legitimate_reload_constant_p (op
))
2241 /* If a symbolic constant or a PLUS is reloaded,
2242 it is most likely being used as an address, so
2243 prefer ADDR_REGS. If 'class' is not a superset
2244 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
2249 if (reg_class_subset_p (ADDR_REGS
, class))
2261 /* Return the register class of a scratch register needed to
2262 load IN into a register of class CLASS in MODE.
2264 We need a temporary when loading a PLUS expression which
2265 is not a legitimate operand of the LOAD ADDRESS instruction. */
2268 s390_secondary_input_reload_class (enum reg_class
class,
2269 enum machine_mode mode
, rtx in
)
2271 if (s390_plus_operand (in
, mode
))
2274 if (reg_classes_intersect_p (CC_REGS
, class))
2275 return GENERAL_REGS
;
2280 /* Return the register class of a scratch register needed to
2281 store a register of class CLASS in MODE into OUT:
2283 We need a temporary when storing a double-word to a
2284 non-offsettable memory address. */
2287 s390_secondary_output_reload_class (enum reg_class
class,
2288 enum machine_mode mode
, rtx out
)
2290 if ((TARGET_64BIT
? mode
== TImode
2291 : (mode
== DImode
|| mode
== DFmode
))
2292 && reg_classes_intersect_p (GENERAL_REGS
, class)
2293 && GET_CODE (out
) == MEM
2294 && GET_CODE (XEXP (out
, 0)) == PLUS
2295 && GET_CODE (XEXP (XEXP (out
, 0), 0)) == PLUS
2296 && GET_CODE (XEXP (XEXP (out
, 0), 1)) == CONST_INT
2297 && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (out
, 0), 1))
2298 + GET_MODE_SIZE (mode
) - 1))
2301 if (reg_classes_intersect_p (CC_REGS
, class))
2302 return GENERAL_REGS
;
2307 /* Generate code to load SRC, which is PLUS that is not a
2308 legitimate operand for the LA instruction, into TARGET.
2309 SCRATCH may be used as scratch register. */
2312 s390_expand_plus_operand (rtx target
, rtx src
,
2316 struct s390_address ad
;
2318 /* src must be a PLUS; get its two operands. */
2319 gcc_assert (GET_CODE (src
) == PLUS
);
2320 gcc_assert (GET_MODE (src
) == Pmode
);
2322 /* Check if any of the two operands is already scheduled
2323 for replacement by reload. This can happen e.g. when
2324 float registers occur in an address. */
2325 sum1
= find_replacement (&XEXP (src
, 0));
2326 sum2
= find_replacement (&XEXP (src
, 1));
2327 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
2329 /* If the address is already strictly valid, there's nothing to do. */
2330 if (!s390_decompose_address (src
, &ad
)
2331 || (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
2332 || (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
)))
2334 /* Otherwise, one of the operands cannot be an address register;
2335 we reload its value into the scratch register. */
2336 if (true_regnum (sum1
) < 1 || true_regnum (sum1
) > 15)
2338 emit_move_insn (scratch
, sum1
);
2341 if (true_regnum (sum2
) < 1 || true_regnum (sum2
) > 15)
2343 emit_move_insn (scratch
, sum2
);
2347 /* According to the way these invalid addresses are generated
2348 in reload.c, it should never happen (at least on s390) that
2349 *neither* of the PLUS components, after find_replacements
2350 was applied, is an address register. */
2351 if (sum1
== scratch
&& sum2
== scratch
)
2357 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
2360 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
2361 is only ever performed on addresses, so we can mark the
2362 sum as legitimate for LA in any case. */
2363 s390_load_address (target
, src
);
2367 /* Return true if ADDR is a valid memory address.
2368 STRICT specifies whether strict register checking applies. */
2371 legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED
,
2372 rtx addr
, int strict
)
2374 struct s390_address ad
;
2375 if (!s390_decompose_address (addr
, &ad
))
2380 if (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
2382 if (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
))
2387 if (ad
.base
&& !REG_OK_FOR_BASE_NONSTRICT_P (ad
.base
))
2389 if (ad
.indx
&& !REG_OK_FOR_INDEX_NONSTRICT_P (ad
.indx
))
2396 /* Return true if OP is a valid operand for the LA instruction.
2397 In 31-bit, we need to prove that the result is used as an
2398 address, as LA performs only a 31-bit addition. */
2401 legitimate_la_operand_p (rtx op
)
2403 struct s390_address addr
;
2404 if (!s390_decompose_address (op
, &addr
))
2407 return (TARGET_64BIT
|| addr
.pointer
);
2410 /* Return true if it is valid *and* preferable to use LA to
2411 compute the sum of OP1 and OP2. */
2414 preferred_la_operand_p (rtx op1
, rtx op2
)
2416 struct s390_address addr
;
2418 if (op2
!= const0_rtx
)
2419 op1
= gen_rtx_PLUS (Pmode
, op1
, op2
);
2421 if (!s390_decompose_address (op1
, &addr
))
2423 if (addr
.base
&& !REG_OK_FOR_BASE_STRICT_P (addr
.base
))
2425 if (addr
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (addr
.indx
))
2428 if (!TARGET_64BIT
&& !addr
.pointer
)
2434 if ((addr
.base
&& REG_P (addr
.base
) && REG_POINTER (addr
.base
))
2435 || (addr
.indx
&& REG_P (addr
.indx
) && REG_POINTER (addr
.indx
)))
2441 /* Emit a forced load-address operation to load SRC into DST.
2442 This will use the LOAD ADDRESS instruction even in situations
2443 where legitimate_la_operand_p (SRC) returns false. */
2446 s390_load_address (rtx dst
, rtx src
)
2449 emit_move_insn (dst
, src
);
2451 emit_insn (gen_force_la_31 (dst
, src
));
2454 /* Return a legitimate reference for ORIG (an address) using the
2455 register REG. If REG is 0, a new pseudo is generated.
2457 There are two types of references that must be handled:
2459 1. Global data references must load the address from the GOT, via
2460 the PIC reg. An insn is emitted to do this load, and the reg is
2463 2. Static data references, constant pool addresses, and code labels
2464 compute the address as an offset from the GOT, whose base is in
2465 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
2466 differentiate them from global data objects. The returned
2467 address is the PIC reg + an unspec constant.
2469 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2470 reg also appears in the address. */
2473 legitimize_pic_address (rtx orig
, rtx reg
)
2479 if (GET_CODE (addr
) == LABEL_REF
2480 || (GET_CODE (addr
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (addr
)))
2482 /* This is a local symbol. */
2483 if (TARGET_CPU_ZARCH
&& larl_operand (addr
, VOIDmode
))
2485 /* Access local symbols PC-relative via LARL.
2486 This is the same as in the non-PIC case, so it is
2487 handled automatically ... */
2491 /* Access local symbols relative to the GOT. */
2493 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2495 if (reload_in_progress
|| reload_completed
)
2496 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2498 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTOFF
);
2499 addr
= gen_rtx_CONST (Pmode
, addr
);
2500 addr
= force_const_mem (Pmode
, addr
);
2501 emit_move_insn (temp
, addr
);
2503 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2506 s390_load_address (reg
, new);
2511 else if (GET_CODE (addr
) == SYMBOL_REF
)
2514 reg
= gen_reg_rtx (Pmode
);
2518 /* Assume GOT offset < 4k. This is handled the same way
2519 in both 31- and 64-bit code (@GOT). */
2521 if (reload_in_progress
|| reload_completed
)
2522 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2524 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
2525 new = gen_rtx_CONST (Pmode
, new);
2526 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new);
2527 new = gen_const_mem (Pmode
, new);
2528 emit_move_insn (reg
, new);
2531 else if (TARGET_CPU_ZARCH
)
2533 /* If the GOT offset might be >= 4k, we determine the position
2534 of the GOT entry via a PC-relative LARL (@GOTENT). */
2536 rtx temp
= gen_reg_rtx (Pmode
);
2538 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTENT
);
2539 new = gen_rtx_CONST (Pmode
, new);
2540 emit_move_insn (temp
, new);
2542 new = gen_const_mem (Pmode
, temp
);
2543 emit_move_insn (reg
, new);
2548 /* If the GOT offset might be >= 4k, we have to load it
2549 from the literal pool (@GOT). */
2551 rtx temp
= gen_reg_rtx (Pmode
);
2553 if (reload_in_progress
|| reload_completed
)
2554 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2556 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
2557 addr
= gen_rtx_CONST (Pmode
, addr
);
2558 addr
= force_const_mem (Pmode
, addr
);
2559 emit_move_insn (temp
, addr
);
2561 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2562 new = gen_const_mem (Pmode
, new);
2563 emit_move_insn (reg
, new);
2569 if (GET_CODE (addr
) == CONST
)
2571 addr
= XEXP (addr
, 0);
2572 if (GET_CODE (addr
) == UNSPEC
)
2574 gcc_assert (XVECLEN (addr
, 0) == 1);
2575 switch (XINT (addr
, 1))
2577 /* If someone moved a GOT-relative UNSPEC
2578 out of the literal pool, force them back in. */
2581 new = force_const_mem (Pmode
, orig
);
2584 /* @GOT is OK as is if small. */
2587 new = force_const_mem (Pmode
, orig
);
2590 /* @GOTENT is OK as is. */
2594 /* @PLT is OK as is on 64-bit, must be converted to
2595 GOT-relative @PLTOFF on 31-bit. */
2597 if (!TARGET_CPU_ZARCH
)
2599 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2601 if (reload_in_progress
|| reload_completed
)
2602 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2604 addr
= XVECEXP (addr
, 0, 0);
2605 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
),
2607 addr
= gen_rtx_CONST (Pmode
, addr
);
2608 addr
= force_const_mem (Pmode
, addr
);
2609 emit_move_insn (temp
, addr
);
2611 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2614 s390_load_address (reg
, new);
2620 /* Everything else cannot happen. */
2626 gcc_assert (GET_CODE (addr
) == PLUS
);
2628 if (GET_CODE (addr
) == PLUS
)
2630 rtx op0
= XEXP (addr
, 0), op1
= XEXP (addr
, 1);
2631 /* Check first to see if this is a constant offset
2632 from a local symbol reference. */
2633 if ((GET_CODE (op0
) == LABEL_REF
2634 || (GET_CODE (op0
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (op0
)))
2635 && GET_CODE (op1
) == CONST_INT
)
2637 if (TARGET_CPU_ZARCH
&& larl_operand (op0
, VOIDmode
))
2639 if (INTVAL (op1
) & 1)
2641 /* LARL can't handle odd offsets, so emit a
2642 pair of LARL and LA. */
2643 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2645 if (!DISP_IN_RANGE (INTVAL (op1
)))
2647 int even
= INTVAL (op1
) - 1;
2648 op0
= gen_rtx_PLUS (Pmode
, op0
, GEN_INT (even
));
2649 op0
= gen_rtx_CONST (Pmode
, op0
);
2653 emit_move_insn (temp
, op0
);
2654 new = gen_rtx_PLUS (Pmode
, temp
, op1
);
2658 s390_load_address (reg
, new);
2664 /* If the offset is even, we can just use LARL.
2665 This will happen automatically. */
2670 /* Access local symbols relative to the GOT. */
2672 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2674 if (reload_in_progress
|| reload_completed
)
2675 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2677 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op0
),
2679 addr
= gen_rtx_PLUS (Pmode
, addr
, op1
);
2680 addr
= gen_rtx_CONST (Pmode
, addr
);
2681 addr
= force_const_mem (Pmode
, addr
);
2682 emit_move_insn (temp
, addr
);
2684 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2687 s390_load_address (reg
, new);
2693 /* Now, check whether it is a GOT relative symbol plus offset
2694 that was pulled out of the literal pool. Force it back in. */
2696 else if (GET_CODE (op0
) == UNSPEC
2697 && GET_CODE (op1
) == CONST_INT
2698 && XINT (op0
, 1) == UNSPEC_GOTOFF
)
2700 gcc_assert (XVECLEN (op0
, 0) == 1);
2702 new = force_const_mem (Pmode
, orig
);
2705 /* Otherwise, compute the sum. */
2708 base
= legitimize_pic_address (XEXP (addr
, 0), reg
);
2709 new = legitimize_pic_address (XEXP (addr
, 1),
2710 base
== reg
? NULL_RTX
: reg
);
2711 if (GET_CODE (new) == CONST_INT
)
2712 new = plus_constant (base
, INTVAL (new));
2715 if (GET_CODE (new) == PLUS
&& CONSTANT_P (XEXP (new, 1)))
2717 base
= gen_rtx_PLUS (Pmode
, base
, XEXP (new, 0));
2718 new = XEXP (new, 1);
2720 new = gen_rtx_PLUS (Pmode
, base
, new);
2723 if (GET_CODE (new) == CONST
)
2724 new = XEXP (new, 0);
2725 new = force_operand (new, 0);
2732 /* Load the thread pointer into a register. */
2735 get_thread_pointer (void)
2737 rtx tp
= gen_reg_rtx (Pmode
);
2739 emit_move_insn (tp
, gen_rtx_REG (Pmode
, TP_REGNUM
));
2740 mark_reg_pointer (tp
, BITS_PER_WORD
);
2745 /* Emit a tls call insn. The call target is the SYMBOL_REF stored
2746 in s390_tls_symbol which always refers to __tls_get_offset.
2747 The returned offset is written to RESULT_REG and an USE rtx is
2748 generated for TLS_CALL. */
2750 static GTY(()) rtx s390_tls_symbol
;
2753 s390_emit_tls_call_insn (rtx result_reg
, rtx tls_call
)
2757 gcc_assert (flag_pic
);
2759 if (!s390_tls_symbol
)
2760 s390_tls_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "__tls_get_offset");
2762 insn
= s390_emit_call (s390_tls_symbol
, tls_call
, result_reg
,
2763 gen_rtx_REG (Pmode
, RETURN_REGNUM
));
2765 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), result_reg
);
2766 CONST_OR_PURE_CALL_P (insn
) = 1;
2769 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
2770 this (thread-local) address. REG may be used as temporary. */
2773 legitimize_tls_address (rtx addr
, rtx reg
)
2775 rtx
new, tls_call
, temp
, base
, r2
, insn
;
2777 if (GET_CODE (addr
) == SYMBOL_REF
)
2778 switch (tls_symbolic_operand (addr
))
2780 case TLS_MODEL_GLOBAL_DYNAMIC
:
2782 r2
= gen_rtx_REG (Pmode
, 2);
2783 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_TLSGD
);
2784 new = gen_rtx_CONST (Pmode
, tls_call
);
2785 new = force_const_mem (Pmode
, new);
2786 emit_move_insn (r2
, new);
2787 s390_emit_tls_call_insn (r2
, tls_call
);
2788 insn
= get_insns ();
2791 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
2792 temp
= gen_reg_rtx (Pmode
);
2793 emit_libcall_block (insn
, temp
, r2
, new);
2795 new = gen_rtx_PLUS (Pmode
, get_thread_pointer (), temp
);
2798 s390_load_address (reg
, new);
2803 case TLS_MODEL_LOCAL_DYNAMIC
:
2805 r2
= gen_rtx_REG (Pmode
, 2);
2806 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM
);
2807 new = gen_rtx_CONST (Pmode
, tls_call
);
2808 new = force_const_mem (Pmode
, new);
2809 emit_move_insn (r2
, new);
2810 s390_emit_tls_call_insn (r2
, tls_call
);
2811 insn
= get_insns ();
2814 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM_NTPOFF
);
2815 temp
= gen_reg_rtx (Pmode
);
2816 emit_libcall_block (insn
, temp
, r2
, new);
2818 new = gen_rtx_PLUS (Pmode
, get_thread_pointer (), temp
);
2819 base
= gen_reg_rtx (Pmode
);
2820 s390_load_address (base
, new);
2822 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_DTPOFF
);
2823 new = gen_rtx_CONST (Pmode
, new);
2824 new = force_const_mem (Pmode
, new);
2825 temp
= gen_reg_rtx (Pmode
);
2826 emit_move_insn (temp
, new);
2828 new = gen_rtx_PLUS (Pmode
, base
, temp
);
2831 s390_load_address (reg
, new);
2836 case TLS_MODEL_INITIAL_EXEC
:
2839 /* Assume GOT offset < 4k. This is handled the same way
2840 in both 31- and 64-bit code. */
2842 if (reload_in_progress
|| reload_completed
)
2843 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2845 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
2846 new = gen_rtx_CONST (Pmode
, new);
2847 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new);
2848 new = gen_const_mem (Pmode
, new);
2849 temp
= gen_reg_rtx (Pmode
);
2850 emit_move_insn (temp
, new);
2852 else if (TARGET_CPU_ZARCH
)
2854 /* If the GOT offset might be >= 4k, we determine the position
2855 of the GOT entry via a PC-relative LARL. */
2857 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
2858 new = gen_rtx_CONST (Pmode
, new);
2859 temp
= gen_reg_rtx (Pmode
);
2860 emit_move_insn (temp
, new);
2862 new = gen_const_mem (Pmode
, temp
);
2863 temp
= gen_reg_rtx (Pmode
);
2864 emit_move_insn (temp
, new);
2868 /* If the GOT offset might be >= 4k, we have to load it
2869 from the literal pool. */
2871 if (reload_in_progress
|| reload_completed
)
2872 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2874 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
2875 new = gen_rtx_CONST (Pmode
, new);
2876 new = force_const_mem (Pmode
, new);
2877 temp
= gen_reg_rtx (Pmode
);
2878 emit_move_insn (temp
, new);
2880 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2881 new = gen_const_mem (Pmode
, new);
2883 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new, addr
), UNSPEC_TLS_LOAD
);
2884 temp
= gen_reg_rtx (Pmode
);
2885 emit_insn (gen_rtx_SET (Pmode
, temp
, new));
2889 /* In position-dependent code, load the absolute address of
2890 the GOT entry from the literal pool. */
2892 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
2893 new = gen_rtx_CONST (Pmode
, new);
2894 new = force_const_mem (Pmode
, new);
2895 temp
= gen_reg_rtx (Pmode
);
2896 emit_move_insn (temp
, new);
2899 new = gen_const_mem (Pmode
, new);
2900 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new, addr
), UNSPEC_TLS_LOAD
);
2901 temp
= gen_reg_rtx (Pmode
);
2902 emit_insn (gen_rtx_SET (Pmode
, temp
, new));
2905 new = gen_rtx_PLUS (Pmode
, get_thread_pointer (), temp
);
2908 s390_load_address (reg
, new);
2913 case TLS_MODEL_LOCAL_EXEC
:
2914 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
2915 new = gen_rtx_CONST (Pmode
, new);
2916 new = force_const_mem (Pmode
, new);
2917 temp
= gen_reg_rtx (Pmode
);
2918 emit_move_insn (temp
, new);
2920 new = gen_rtx_PLUS (Pmode
, get_thread_pointer (), temp
);
2923 s390_load_address (reg
, new);
2932 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == UNSPEC
)
2934 switch (XINT (XEXP (addr
, 0), 1))
2936 case UNSPEC_INDNTPOFF
:
2937 gcc_assert (TARGET_CPU_ZARCH
);
2946 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == PLUS
2947 && GET_CODE (XEXP (XEXP (addr
, 0), 1)) == CONST_INT
)
2949 new = XEXP (XEXP (addr
, 0), 0);
2950 if (GET_CODE (new) != SYMBOL_REF
)
2951 new = gen_rtx_CONST (Pmode
, new);
2953 new = legitimize_tls_address (new, reg
);
2954 new = plus_constant (new, INTVAL (XEXP (XEXP (addr
, 0), 1)));
2955 new = force_operand (new, 0);
2959 gcc_unreachable (); /* for now ... */
2964 /* Emit insns to move operands[1] into operands[0]. */
2967 emit_symbolic_move (rtx
*operands
)
2969 rtx temp
= no_new_pseudos
? operands
[0] : gen_reg_rtx (Pmode
);
2971 if (GET_CODE (operands
[0]) == MEM
)
2972 operands
[1] = force_reg (Pmode
, operands
[1]);
2973 else if (TLS_SYMBOLIC_CONST (operands
[1]))
2974 operands
[1] = legitimize_tls_address (operands
[1], temp
);
2976 operands
[1] = legitimize_pic_address (operands
[1], temp
);
2979 /* Try machine-dependent ways of modifying an illegitimate address X
2980 to be legitimate. If we find one, return the new, valid address.
2982 OLDX is the address as it was before break_out_memory_refs was called.
2983 In some cases it is useful to look at this to decide what needs to be done.
2985 MODE is the mode of the operand pointed to by X.
2987 When -fpic is used, special handling is needed for symbolic references.
2988 See comments by legitimize_pic_address for details. */
2991 legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
2992 enum machine_mode mode ATTRIBUTE_UNUSED
)
2994 rtx constant_term
= const0_rtx
;
2996 if (TLS_SYMBOLIC_CONST (x
))
2998 x
= legitimize_tls_address (x
, 0);
3000 if (legitimate_address_p (mode
, x
, FALSE
))
3005 if (SYMBOLIC_CONST (x
)
3006 || (GET_CODE (x
) == PLUS
3007 && (SYMBOLIC_CONST (XEXP (x
, 0))
3008 || SYMBOLIC_CONST (XEXP (x
, 1)))))
3009 x
= legitimize_pic_address (x
, 0);
3011 if (legitimate_address_p (mode
, x
, FALSE
))
3015 x
= eliminate_constant_term (x
, &constant_term
);
3017 /* Optimize loading of large displacements by splitting them
3018 into the multiple of 4K and the rest; this allows the
3019 former to be CSE'd if possible.
3021 Don't do this if the displacement is added to a register
3022 pointing into the stack frame, as the offsets will
3023 change later anyway. */
3025 if (GET_CODE (constant_term
) == CONST_INT
3026 && !TARGET_LONG_DISPLACEMENT
3027 && !DISP_IN_RANGE (INTVAL (constant_term
))
3028 && !(REG_P (x
) && REGNO_PTR_FRAME_P (REGNO (x
))))
3030 HOST_WIDE_INT lower
= INTVAL (constant_term
) & 0xfff;
3031 HOST_WIDE_INT upper
= INTVAL (constant_term
) ^ lower
;
3033 rtx temp
= gen_reg_rtx (Pmode
);
3034 rtx val
= force_operand (GEN_INT (upper
), temp
);
3036 emit_move_insn (temp
, val
);
3038 x
= gen_rtx_PLUS (Pmode
, x
, temp
);
3039 constant_term
= GEN_INT (lower
);
3042 if (GET_CODE (x
) == PLUS
)
3044 if (GET_CODE (XEXP (x
, 0)) == REG
)
3046 rtx temp
= gen_reg_rtx (Pmode
);
3047 rtx val
= force_operand (XEXP (x
, 1), temp
);
3049 emit_move_insn (temp
, val
);
3051 x
= gen_rtx_PLUS (Pmode
, XEXP (x
, 0), temp
);
3054 else if (GET_CODE (XEXP (x
, 1)) == REG
)
3056 rtx temp
= gen_reg_rtx (Pmode
);
3057 rtx val
= force_operand (XEXP (x
, 0), temp
);
3059 emit_move_insn (temp
, val
);
3061 x
= gen_rtx_PLUS (Pmode
, temp
, XEXP (x
, 1));
3065 if (constant_term
!= const0_rtx
)
3066 x
= gen_rtx_PLUS (Pmode
, x
, constant_term
);
3071 /* Try a machine-dependent way of reloading an illegitimate address AD
3072 operand. If we find one, push the reload and and return the new address.
3074 MODE is the mode of the enclosing MEM. OPNUM is the operand number
3075 and TYPE is the reload type of the current reload. */
3078 legitimize_reload_address (rtx ad
, enum machine_mode mode ATTRIBUTE_UNUSED
,
3079 int opnum
, int type
)
3081 if (!optimize
|| TARGET_LONG_DISPLACEMENT
)
3084 if (GET_CODE (ad
) == PLUS
)
3086 rtx tem
= simplify_binary_operation (PLUS
, Pmode
,
3087 XEXP (ad
, 0), XEXP (ad
, 1));
3092 if (GET_CODE (ad
) == PLUS
3093 && GET_CODE (XEXP (ad
, 0)) == REG
3094 && GET_CODE (XEXP (ad
, 1)) == CONST_INT
3095 && !DISP_IN_RANGE (INTVAL (XEXP (ad
, 1))))
3097 HOST_WIDE_INT lower
= INTVAL (XEXP (ad
, 1)) & 0xfff;
3098 HOST_WIDE_INT upper
= INTVAL (XEXP (ad
, 1)) ^ lower
;
3101 cst
= GEN_INT (upper
);
3102 if (!legitimate_reload_constant_p (cst
))
3103 cst
= force_const_mem (Pmode
, cst
);
3105 tem
= gen_rtx_PLUS (Pmode
, XEXP (ad
, 0), cst
);
3106 new = gen_rtx_PLUS (Pmode
, tem
, GEN_INT (lower
));
3108 push_reload (XEXP (tem
, 1), 0, &XEXP (tem
, 1), 0,
3109 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
3110 opnum
, (enum reload_type
) type
);
3117 /* Emit code to move LEN bytes from DST to SRC. */
3120 s390_expand_movmem (rtx dst
, rtx src
, rtx len
)
3122 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3124 if (INTVAL (len
) > 0)
3125 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (INTVAL (len
) - 1)));
3128 else if (TARGET_MVCLE
)
3130 emit_insn (gen_movmem_long (dst
, src
, convert_to_mode (Pmode
, len
, 1)));
3135 rtx dst_addr
, src_addr
, count
, blocks
, temp
;
3136 rtx loop_start_label
= gen_label_rtx ();
3137 rtx loop_end_label
= gen_label_rtx ();
3138 rtx end_label
= gen_label_rtx ();
3139 enum machine_mode mode
;
3141 mode
= GET_MODE (len
);
3142 if (mode
== VOIDmode
)
3145 dst_addr
= gen_reg_rtx (Pmode
);
3146 src_addr
= gen_reg_rtx (Pmode
);
3147 count
= gen_reg_rtx (mode
);
3148 blocks
= gen_reg_rtx (mode
);
3150 convert_move (count
, len
, 1);
3151 emit_cmp_and_jump_insns (count
, const0_rtx
,
3152 EQ
, NULL_RTX
, mode
, 1, end_label
);
3154 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
3155 emit_move_insn (src_addr
, force_operand (XEXP (src
, 0), NULL_RTX
));
3156 dst
= change_address (dst
, VOIDmode
, dst_addr
);
3157 src
= change_address (src
, VOIDmode
, src_addr
);
3159 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3161 emit_move_insn (count
, temp
);
3163 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3165 emit_move_insn (blocks
, temp
);
3167 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3168 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3170 emit_label (loop_start_label
);
3172 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (255)));
3173 s390_load_address (dst_addr
,
3174 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
3175 s390_load_address (src_addr
,
3176 gen_rtx_PLUS (Pmode
, src_addr
, GEN_INT (256)));
3178 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3180 emit_move_insn (blocks
, temp
);
3182 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3183 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3185 emit_jump (loop_start_label
);
3186 emit_label (loop_end_label
);
3188 emit_insn (gen_movmem_short (dst
, src
,
3189 convert_to_mode (Pmode
, count
, 1)));
3190 emit_label (end_label
);
3194 /* Emit code to clear LEN bytes at DST. */
3197 s390_expand_clrmem (rtx dst
, rtx len
)
3199 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3201 if (INTVAL (len
) > 0)
3202 emit_insn (gen_clrmem_short (dst
, GEN_INT (INTVAL (len
) - 1)));
3205 else if (TARGET_MVCLE
)
3207 emit_insn (gen_clrmem_long (dst
, convert_to_mode (Pmode
, len
, 1)));
3212 rtx dst_addr
, src_addr
, count
, blocks
, temp
;
3213 rtx loop_start_label
= gen_label_rtx ();
3214 rtx loop_end_label
= gen_label_rtx ();
3215 rtx end_label
= gen_label_rtx ();
3216 enum machine_mode mode
;
3218 mode
= GET_MODE (len
);
3219 if (mode
== VOIDmode
)
3222 dst_addr
= gen_reg_rtx (Pmode
);
3223 src_addr
= gen_reg_rtx (Pmode
);
3224 count
= gen_reg_rtx (mode
);
3225 blocks
= gen_reg_rtx (mode
);
3227 convert_move (count
, len
, 1);
3228 emit_cmp_and_jump_insns (count
, const0_rtx
,
3229 EQ
, NULL_RTX
, mode
, 1, end_label
);
3231 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
3232 dst
= change_address (dst
, VOIDmode
, dst_addr
);
3234 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3236 emit_move_insn (count
, temp
);
3238 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3240 emit_move_insn (blocks
, temp
);
3242 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3243 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3245 emit_label (loop_start_label
);
3247 emit_insn (gen_clrmem_short (dst
, GEN_INT (255)));
3248 s390_load_address (dst_addr
,
3249 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
3251 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3253 emit_move_insn (blocks
, temp
);
3255 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3256 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3258 emit_jump (loop_start_label
);
3259 emit_label (loop_end_label
);
3261 emit_insn (gen_clrmem_short (dst
, convert_to_mode (Pmode
, count
, 1)));
3262 emit_label (end_label
);
3266 /* Emit code to compare LEN bytes at OP0 with those at OP1,
3267 and return the result in TARGET. */
3270 s390_expand_cmpmem (rtx target
, rtx op0
, rtx op1
, rtx len
)
3272 rtx ccreg
= gen_rtx_REG (CCUmode
, CC_REGNUM
);
3275 /* As the result of CMPINT is inverted compared to what we need,
3276 we have to swap the operands. */
3277 tmp
= op0
; op0
= op1
; op1
= tmp
;
3279 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3281 if (INTVAL (len
) > 0)
3283 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (INTVAL (len
) - 1)));
3284 emit_insn (gen_cmpint (target
, ccreg
));
3287 emit_move_insn (target
, const0_rtx
);
3289 else if (TARGET_MVCLE
)
3291 emit_insn (gen_cmpmem_long (op0
, op1
, convert_to_mode (Pmode
, len
, 1)));
3292 emit_insn (gen_cmpint (target
, ccreg
));
3296 rtx addr0
, addr1
, count
, blocks
, temp
;
3297 rtx loop_start_label
= gen_label_rtx ();
3298 rtx loop_end_label
= gen_label_rtx ();
3299 rtx end_label
= gen_label_rtx ();
3300 enum machine_mode mode
;
3302 mode
= GET_MODE (len
);
3303 if (mode
== VOIDmode
)
3306 addr0
= gen_reg_rtx (Pmode
);
3307 addr1
= gen_reg_rtx (Pmode
);
3308 count
= gen_reg_rtx (mode
);
3309 blocks
= gen_reg_rtx (mode
);
3311 convert_move (count
, len
, 1);
3312 emit_cmp_and_jump_insns (count
, const0_rtx
,
3313 EQ
, NULL_RTX
, mode
, 1, end_label
);
3315 emit_move_insn (addr0
, force_operand (XEXP (op0
, 0), NULL_RTX
));
3316 emit_move_insn (addr1
, force_operand (XEXP (op1
, 0), NULL_RTX
));
3317 op0
= change_address (op0
, VOIDmode
, addr0
);
3318 op1
= change_address (op1
, VOIDmode
, addr1
);
3320 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3322 emit_move_insn (count
, temp
);
3324 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3326 emit_move_insn (blocks
, temp
);
3328 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3329 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3331 emit_label (loop_start_label
);
3333 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (255)));
3334 temp
= gen_rtx_NE (VOIDmode
, ccreg
, const0_rtx
);
3335 temp
= gen_rtx_IF_THEN_ELSE (VOIDmode
, temp
,
3336 gen_rtx_LABEL_REF (VOIDmode
, end_label
), pc_rtx
);
3337 temp
= gen_rtx_SET (VOIDmode
, pc_rtx
, temp
);
3338 emit_jump_insn (temp
);
3340 s390_load_address (addr0
,
3341 gen_rtx_PLUS (Pmode
, addr0
, GEN_INT (256)));
3342 s390_load_address (addr1
,
3343 gen_rtx_PLUS (Pmode
, addr1
, GEN_INT (256)));
3345 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3347 emit_move_insn (blocks
, temp
);
3349 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3350 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3352 emit_jump (loop_start_label
);
3353 emit_label (loop_end_label
);
3355 emit_insn (gen_cmpmem_short (op0
, op1
,
3356 convert_to_mode (Pmode
, count
, 1)));
3357 emit_label (end_label
);
3359 emit_insn (gen_cmpint (target
, ccreg
));
3364 /* Expand conditional increment or decrement using alc/slb instructions.
3365 Should generate code setting DST to either SRC or SRC + INCREMENT,
3366 depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
3367 Returns true if successful, false otherwise.
3369 That makes it possible to implement some if-constructs without jumps e.g.:
3370 (borrow = CC0 | CC1 and carry = CC2 | CC3)
3371 unsigned int a, b, c;
3372 if (a < b) c++; -> CCU b > a -> CC2; c += carry;
3373 if (a < b) c--; -> CCL3 a - b -> borrow; c -= borrow;
3374 if (a <= b) c++; -> CCL3 b - a -> borrow; c += carry;
3375 if (a <= b) c--; -> CCU a <= b -> borrow; c -= borrow;
3377 Checks for EQ and NE with a nonzero value need an additional xor e.g.:
3378 if (a == b) c++; -> CCL3 a ^= b; 0 - a -> borrow; c += carry;
3379 if (a == b) c--; -> CCU a ^= b; a <= 0 -> CC0 | CC1; c -= borrow;
3380 if (a != b) c++; -> CCU a ^= b; a > 0 -> CC2; c += carry;
3381 if (a != b) c--; -> CCL3 a ^= b; 0 - a -> borrow; c -= borrow; */
3384 s390_expand_addcc (enum rtx_code cmp_code
, rtx cmp_op0
, rtx cmp_op1
,
3385 rtx dst
, rtx src
, rtx increment
)
3387 enum machine_mode cmp_mode
;
3388 enum machine_mode cc_mode
;
3394 if ((GET_MODE (cmp_op0
) == SImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
3395 && (GET_MODE (cmp_op1
) == SImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
3397 else if ((GET_MODE (cmp_op0
) == DImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
3398 && (GET_MODE (cmp_op1
) == DImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
3403 /* Try ADD LOGICAL WITH CARRY. */
3404 if (increment
== const1_rtx
)
3406 /* Determine CC mode to use. */
3407 if (cmp_code
== EQ
|| cmp_code
== NE
)
3409 if (cmp_op1
!= const0_rtx
)
3411 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
3412 NULL_RTX
, 0, OPTAB_WIDEN
);
3413 cmp_op1
= const0_rtx
;
3416 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
3419 if (cmp_code
== LTU
|| cmp_code
== LEU
)
3424 cmp_code
= swap_condition (cmp_code
);
3441 /* Emit comparison instruction pattern. */
3442 if (!register_operand (cmp_op0
, cmp_mode
))
3443 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
3445 insn
= gen_rtx_SET (VOIDmode
, gen_rtx_REG (cc_mode
, CC_REGNUM
),
3446 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
3447 /* We use insn_invalid_p here to add clobbers if required. */
3448 ret
= insn_invalid_p (emit_insn (insn
));
3451 /* Emit ALC instruction pattern. */
3452 op_res
= gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
3453 gen_rtx_REG (cc_mode
, CC_REGNUM
),
3456 if (src
!= const0_rtx
)
3458 if (!register_operand (src
, GET_MODE (dst
)))
3459 src
= force_reg (GET_MODE (dst
), src
);
3461 src
= gen_rtx_PLUS (GET_MODE (dst
), src
, const0_rtx
);
3462 op_res
= gen_rtx_PLUS (GET_MODE (dst
), src
, op_res
);
3465 p
= rtvec_alloc (2);
3467 gen_rtx_SET (VOIDmode
, dst
, op_res
);
3469 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
3470 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
3475 /* Try SUBTRACT LOGICAL WITH BORROW. */
3476 if (increment
== constm1_rtx
)
3478 /* Determine CC mode to use. */
3479 if (cmp_code
== EQ
|| cmp_code
== NE
)
3481 if (cmp_op1
!= const0_rtx
)
3483 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
3484 NULL_RTX
, 0, OPTAB_WIDEN
);
3485 cmp_op1
= const0_rtx
;
3488 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
3491 if (cmp_code
== GTU
|| cmp_code
== GEU
)
3496 cmp_code
= swap_condition (cmp_code
);
3513 /* Emit comparison instruction pattern. */
3514 if (!register_operand (cmp_op0
, cmp_mode
))
3515 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
3517 insn
= gen_rtx_SET (VOIDmode
, gen_rtx_REG (cc_mode
, CC_REGNUM
),
3518 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
3519 /* We use insn_invalid_p here to add clobbers if required. */
3520 ret
= insn_invalid_p (emit_insn (insn
));
3523 /* Emit SLB instruction pattern. */
3524 if (!register_operand (src
, GET_MODE (dst
)))
3525 src
= force_reg (GET_MODE (dst
), src
);
3527 op_res
= gen_rtx_MINUS (GET_MODE (dst
),
3528 gen_rtx_MINUS (GET_MODE (dst
), src
, const0_rtx
),
3529 gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
3530 gen_rtx_REG (cc_mode
, CC_REGNUM
),
3532 p
= rtvec_alloc (2);
3534 gen_rtx_SET (VOIDmode
, dst
, op_res
);
3536 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
3537 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
3546 /* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
3547 We need to emit DTP-relative relocations. */
3550 s390_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
3555 fputs ("\t.long\t", file
);
3558 fputs ("\t.quad\t", file
);
3563 output_addr_const (file
, x
);
3564 fputs ("@DTPOFF", file
);
3567 /* In the name of slightly smaller debug output, and to cater to
3568 general assembler lossage, recognize various UNSPEC sequences
3569 and turn them back into a direct symbol reference. */
3572 s390_delegitimize_address (rtx orig_x
)
3576 if (GET_CODE (x
) != MEM
)
3580 if (GET_CODE (x
) == PLUS
3581 && GET_CODE (XEXP (x
, 1)) == CONST
3582 && GET_CODE (XEXP (x
, 0)) == REG
3583 && REGNO (XEXP (x
, 0)) == PIC_OFFSET_TABLE_REGNUM
)
3585 y
= XEXP (XEXP (x
, 1), 0);
3586 if (GET_CODE (y
) == UNSPEC
3587 && XINT (y
, 1) == UNSPEC_GOT
)
3588 return XVECEXP (y
, 0, 0);
3592 if (GET_CODE (x
) == CONST
)
3595 if (GET_CODE (y
) == UNSPEC
3596 && XINT (y
, 1) == UNSPEC_GOTENT
)
3597 return XVECEXP (y
, 0, 0);
3604 /* Output shift count operand OP to stdio stream FILE. */
3607 print_shift_count_operand (FILE *file
, rtx op
)
3609 HOST_WIDE_INT offset
= 0;
3611 /* We can have an integer constant, an address register,
3612 or a sum of the two. */
3613 if (GET_CODE (op
) == CONST_INT
)
3615 offset
= INTVAL (op
);
3618 if (op
&& GET_CODE (op
) == PLUS
&& GET_CODE (XEXP (op
, 1)) == CONST_INT
)
3620 offset
= INTVAL (XEXP (op
, 1));
3623 while (op
&& GET_CODE (op
) == SUBREG
)
3624 op
= SUBREG_REG (op
);
3629 gcc_assert (GET_CODE (op
) == REG
);
3630 gcc_assert (REGNO (op
) < FIRST_PSEUDO_REGISTER
);
3631 gcc_assert (REGNO_REG_CLASS (REGNO (op
)) == ADDR_REGS
);
3634 /* Shift counts are truncated to the low six bits anyway. */
3635 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
& 63);
3637 fprintf (file
, "(%s)", reg_names
[REGNO (op
)]);
3640 /* See 'get_some_local_dynamic_name'. */
3643 get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
3647 if (GET_CODE (x
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (x
))
3649 x
= get_pool_constant (x
);
3650 return for_each_rtx (&x
, get_some_local_dynamic_name_1
, 0);
3653 if (GET_CODE (x
) == SYMBOL_REF
3654 && tls_symbolic_operand (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
3656 cfun
->machine
->some_ld_name
= XSTR (x
, 0);
3663 /* Locate some local-dynamic symbol still in use by this function
3664 so that we can print its name in local-dynamic base patterns. */
3667 get_some_local_dynamic_name (void)
3671 if (cfun
->machine
->some_ld_name
)
3672 return cfun
->machine
->some_ld_name
;
3674 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
3676 && for_each_rtx (&PATTERN (insn
), get_some_local_dynamic_name_1
, 0))
3677 return cfun
->machine
->some_ld_name
;
3682 /* Output machine-dependent UNSPECs occurring in address constant X
3683 in assembler syntax to stdio stream FILE. Returns true if the
3684 constant X could be recognized, false otherwise. */
3687 s390_output_addr_const_extra (FILE *file
, rtx x
)
3689 if (GET_CODE (x
) == UNSPEC
&& XVECLEN (x
, 0) == 1)
3690 switch (XINT (x
, 1))
3693 output_addr_const (file
, XVECEXP (x
, 0, 0));
3694 fprintf (file
, "@GOTENT");
3697 output_addr_const (file
, XVECEXP (x
, 0, 0));
3698 fprintf (file
, "@GOT");
3701 output_addr_const (file
, XVECEXP (x
, 0, 0));
3702 fprintf (file
, "@GOTOFF");
3705 output_addr_const (file
, XVECEXP (x
, 0, 0));
3706 fprintf (file
, "@PLT");
3709 output_addr_const (file
, XVECEXP (x
, 0, 0));
3710 fprintf (file
, "@PLTOFF");
3713 output_addr_const (file
, XVECEXP (x
, 0, 0));
3714 fprintf (file
, "@TLSGD");
3717 assemble_name (file
, get_some_local_dynamic_name ());
3718 fprintf (file
, "@TLSLDM");
3721 output_addr_const (file
, XVECEXP (x
, 0, 0));
3722 fprintf (file
, "@DTPOFF");
3725 output_addr_const (file
, XVECEXP (x
, 0, 0));
3726 fprintf (file
, "@NTPOFF");
3728 case UNSPEC_GOTNTPOFF
:
3729 output_addr_const (file
, XVECEXP (x
, 0, 0));
3730 fprintf (file
, "@GOTNTPOFF");
3732 case UNSPEC_INDNTPOFF
:
3733 output_addr_const (file
, XVECEXP (x
, 0, 0));
3734 fprintf (file
, "@INDNTPOFF");
3741 /* Output address operand ADDR in assembler syntax to
3742 stdio stream FILE. */
3745 print_operand_address (FILE *file
, rtx addr
)
3747 struct s390_address ad
;
3749 if (!s390_decompose_address (addr
, &ad
)
3750 || (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
3751 || (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
)))
3752 output_operand_lossage ("Cannot decompose address.");
3755 output_addr_const (file
, ad
.disp
);
3757 fprintf (file
, "0");
3759 if (ad
.base
&& ad
.indx
)
3760 fprintf (file
, "(%s,%s)", reg_names
[REGNO (ad
.indx
)],
3761 reg_names
[REGNO (ad
.base
)]);
3763 fprintf (file
, "(%s)", reg_names
[REGNO (ad
.base
)]);
3766 /* Output operand X in assembler syntax to stdio stream FILE.
3767 CODE specified the format flag. The following format flags
3770 'C': print opcode suffix for branch condition.
3771 'D': print opcode suffix for inverse branch condition.
3772 'J': print tls_load/tls_gdcall/tls_ldcall suffix
3773 'O': print only the displacement of a memory reference.
3774 'R': print only the base register of a memory reference.
3775 'S': print S-type memory reference (base+displacement).
3776 'N': print the second word of a DImode operand.
3777 'M': print the second word of a TImode operand.
3778 'Y': print shift count operand.
3780 'b': print integer X as if it's an unsigned byte.
3781 'x': print integer X as if it's an unsigned word.
3782 'h': print integer X as if it's a signed word.
3783 'i': print the first nonzero HImode part of X.
3784 'j': print the first HImode part unequal to 0xffff of X. */
3787 print_operand (FILE *file
, rtx x
, int code
)
3792 fprintf (file
, s390_branch_condition_mnemonic (x
, FALSE
));
3796 fprintf (file
, s390_branch_condition_mnemonic (x
, TRUE
));
3800 if (GET_CODE (x
) == SYMBOL_REF
)
3802 fprintf (file
, "%s", ":tls_load:");
3803 output_addr_const (file
, x
);
3805 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSGD
)
3807 fprintf (file
, "%s", ":tls_gdcall:");
3808 output_addr_const (file
, XVECEXP (x
, 0, 0));
3810 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSLDM
)
3812 fprintf (file
, "%s", ":tls_ldcall:");
3813 assemble_name (file
, get_some_local_dynamic_name ());
3821 struct s390_address ad
;
3824 gcc_assert (GET_CODE (x
) == MEM
);
3825 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
3827 gcc_assert (!ad
.base
|| REG_OK_FOR_BASE_STRICT_P (ad
.base
));
3828 gcc_assert (!ad
.indx
);
3831 output_addr_const (file
, ad
.disp
);
3833 fprintf (file
, "0");
3839 struct s390_address ad
;
3842 gcc_assert (GET_CODE (x
) == MEM
);
3843 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
3845 gcc_assert (!ad
.base
|| REG_OK_FOR_BASE_STRICT_P (ad
.base
));
3846 gcc_assert (!ad
.indx
);
3849 fprintf (file
, "%s", reg_names
[REGNO (ad
.base
)]);
3851 fprintf (file
, "0");
3857 struct s390_address ad
;
3860 gcc_assert (GET_CODE (x
) == MEM
);
3861 ret
= s390_decompose_address (XEXP (x
, 0), &ad
);
3863 gcc_assert (!ad
.base
|| REG_OK_FOR_BASE_STRICT_P (ad
.base
));
3864 gcc_assert (!ad
.indx
);
3867 output_addr_const (file
, ad
.disp
);
3869 fprintf (file
, "0");
3872 fprintf (file
, "(%s)", reg_names
[REGNO (ad
.base
)]);
3877 if (GET_CODE (x
) == REG
)
3878 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
3879 else if (GET_CODE (x
) == MEM
)
3880 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 4));
3886 if (GET_CODE (x
) == REG
)
3887 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
3888 else if (GET_CODE (x
) == MEM
)
3889 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 8));
3895 print_shift_count_operand (file
, x
);
3899 switch (GET_CODE (x
))
3902 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
3906 output_address (XEXP (x
, 0));
3913 output_addr_const (file
, x
);
3918 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xff);
3919 else if (code
== 'x')
3920 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xffff);
3921 else if (code
== 'h')
3922 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((INTVAL (x
) & 0xffff) ^ 0x8000) - 0x8000);
3923 else if (code
== 'i')
3924 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
3925 s390_extract_part (x
, HImode
, 0));
3926 else if (code
== 'j')
3927 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
3928 s390_extract_part (x
, HImode
, -1));
3930 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
3934 gcc_assert (GET_MODE (x
) == VOIDmode
);
3936 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xff);
3937 else if (code
== 'x')
3938 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xffff);
3939 else if (code
== 'h')
3940 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((CONST_DOUBLE_LOW (x
) & 0xffff) ^ 0x8000) - 0x8000);
3946 fatal_insn ("UNKNOWN in print_operand !?", x
);
3951 /* Target hook for assembling integer objects. We need to define it
3952 here to work a round a bug in some versions of GAS, which couldn't
3953 handle values smaller than INT_MIN when printed in decimal. */
3956 s390_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
3958 if (size
== 8 && aligned_p
3959 && GET_CODE (x
) == CONST_INT
&& INTVAL (x
) < INT_MIN
)
3961 fprintf (asm_out_file
, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX
"\n",
3965 return default_assemble_integer (x
, size
, aligned_p
);
3968 /* Returns true if register REGNO is used for forming
3969 a memory address in expression X. */
3972 reg_used_in_mem_p (int regno
, rtx x
)
3974 enum rtx_code code
= GET_CODE (x
);
3980 if (refers_to_regno_p (regno
, regno
+1,
3984 else if (code
== SET
3985 && GET_CODE (SET_DEST (x
)) == PC
)
3987 if (refers_to_regno_p (regno
, regno
+1,
3992 fmt
= GET_RTX_FORMAT (code
);
3993 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
3996 && reg_used_in_mem_p (regno
, XEXP (x
, i
)))
3999 else if (fmt
[i
] == 'E')
4000 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
4001 if (reg_used_in_mem_p (regno
, XVECEXP (x
, i
, j
)))
4007 /* Returns true if expression DEP_RTX sets an address register
4008 used by instruction INSN to address memory. */
4011 addr_generation_dependency_p (rtx dep_rtx
, rtx insn
)
4015 if (GET_CODE (dep_rtx
) == INSN
)
4016 dep_rtx
= PATTERN (dep_rtx
);
4018 if (GET_CODE (dep_rtx
) == SET
)
4020 target
= SET_DEST (dep_rtx
);
4021 if (GET_CODE (target
) == STRICT_LOW_PART
)
4022 target
= XEXP (target
, 0);
4023 while (GET_CODE (target
) == SUBREG
)
4024 target
= SUBREG_REG (target
);
4026 if (GET_CODE (target
) == REG
)
4028 int regno
= REGNO (target
);
4030 if (s390_safe_attr_type (insn
) == TYPE_LA
)
4032 pat
= PATTERN (insn
);
4033 if (GET_CODE (pat
) == PARALLEL
)
4035 gcc_assert (XVECLEN (pat
, 0) == 2);
4036 pat
= XVECEXP (pat
, 0, 0);
4038 gcc_assert (GET_CODE (pat
) == SET
);
4039 return refers_to_regno_p (regno
, regno
+1, SET_SRC (pat
), 0);
4041 else if (get_attr_atype (insn
) == ATYPE_AGEN
)
4042 return reg_used_in_mem_p (regno
, PATTERN (insn
));
4048 /* Return 1, if dep_insn sets register used in insn in the agen unit. */
4051 s390_agen_dep_p (rtx dep_insn
, rtx insn
)
4053 rtx dep_rtx
= PATTERN (dep_insn
);
4056 if (GET_CODE (dep_rtx
) == SET
4057 && addr_generation_dependency_p (dep_rtx
, insn
))
4059 else if (GET_CODE (dep_rtx
) == PARALLEL
)
4061 for (i
= 0; i
< XVECLEN (dep_rtx
, 0); i
++)
4063 if (addr_generation_dependency_p (XVECEXP (dep_rtx
, 0, i
), insn
))
4070 /* A C statement (sans semicolon) to update the integer scheduling priority
4071 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
4072 reduce the priority to execute INSN later. Do not define this macro if
4073 you do not need to adjust the scheduling priorities of insns.
4075 A STD instruction should be scheduled earlier,
4076 in order to use the bypass. */
4079 s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
4081 if (! INSN_P (insn
))
4084 if (s390_tune
!= PROCESSOR_2084_Z990
)
4087 switch (s390_safe_attr_type (insn
))
4091 priority
= priority
<< 3;
4095 priority
= priority
<< 1;
4103 /* The number of instructions that can be issued per cycle. */
4106 s390_issue_rate (void)
4108 if (s390_tune
== PROCESSOR_2084_Z990
)
4114 s390_first_cycle_multipass_dfa_lookahead (void)
4120 /* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
4121 Fix up MEMs as required. */
4124 annotate_constant_pool_refs (rtx
*x
)
4129 gcc_assert (GET_CODE (*x
) != SYMBOL_REF
4130 || !CONSTANT_POOL_ADDRESS_P (*x
));
4132 /* Literal pool references can only occur inside a MEM ... */
4133 if (GET_CODE (*x
) == MEM
)
4135 rtx memref
= XEXP (*x
, 0);
4137 if (GET_CODE (memref
) == SYMBOL_REF
4138 && CONSTANT_POOL_ADDRESS_P (memref
))
4140 rtx base
= cfun
->machine
->base_reg
;
4141 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, memref
, base
),
4144 *x
= replace_equiv_address (*x
, addr
);
4148 if (GET_CODE (memref
) == CONST
4149 && GET_CODE (XEXP (memref
, 0)) == PLUS
4150 && GET_CODE (XEXP (XEXP (memref
, 0), 1)) == CONST_INT
4151 && GET_CODE (XEXP (XEXP (memref
, 0), 0)) == SYMBOL_REF
4152 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (memref
, 0), 0)))
4154 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (memref
, 0), 1));
4155 rtx sym
= XEXP (XEXP (memref
, 0), 0);
4156 rtx base
= cfun
->machine
->base_reg
;
4157 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
4160 *x
= replace_equiv_address (*x
, plus_constant (addr
, off
));
4165 /* ... or a load-address type pattern. */
4166 if (GET_CODE (*x
) == SET
)
4168 rtx addrref
= SET_SRC (*x
);
4170 if (GET_CODE (addrref
) == SYMBOL_REF
4171 && CONSTANT_POOL_ADDRESS_P (addrref
))
4173 rtx base
= cfun
->machine
->base_reg
;
4174 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, addrref
, base
),
4177 SET_SRC (*x
) = addr
;
4181 if (GET_CODE (addrref
) == CONST
4182 && GET_CODE (XEXP (addrref
, 0)) == PLUS
4183 && GET_CODE (XEXP (XEXP (addrref
, 0), 1)) == CONST_INT
4184 && GET_CODE (XEXP (XEXP (addrref
, 0), 0)) == SYMBOL_REF
4185 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (addrref
, 0), 0)))
4187 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (addrref
, 0), 1));
4188 rtx sym
= XEXP (XEXP (addrref
, 0), 0);
4189 rtx base
= cfun
->machine
->base_reg
;
4190 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
4193 SET_SRC (*x
) = plus_constant (addr
, off
);
4198 /* Annotate LTREL_BASE as well. */
4199 if (GET_CODE (*x
) == UNSPEC
4200 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
4202 rtx base
= cfun
->machine
->base_reg
;
4203 *x
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XVECEXP (*x
, 0, 0), base
),
4208 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
4209 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
4213 annotate_constant_pool_refs (&XEXP (*x
, i
));
4215 else if (fmt
[i
] == 'E')
4217 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
4218 annotate_constant_pool_refs (&XVECEXP (*x
, i
, j
));
4223 /* Split all branches that exceed the maximum distance.
4224 Returns true if this created a new literal pool entry. */
4227 s390_split_branches (void)
4229 rtx temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
4230 int new_literal
= 0, ret
;
4231 rtx insn
, pat
, tmp
, target
;
4234 /* We need correct insn addresses. */
4236 shorten_branches (get_insns ());
4238 /* Find all branches that exceed 64KB, and split them. */
4240 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
4242 if (GET_CODE (insn
) != JUMP_INSN
)
4245 pat
= PATTERN (insn
);
4246 if (GET_CODE (pat
) == PARALLEL
&& XVECLEN (pat
, 0) > 2)
4247 pat
= XVECEXP (pat
, 0, 0);
4248 if (GET_CODE (pat
) != SET
|| SET_DEST (pat
) != pc_rtx
)
4251 if (GET_CODE (SET_SRC (pat
)) == LABEL_REF
)
4253 label
= &SET_SRC (pat
);
4255 else if (GET_CODE (SET_SRC (pat
)) == IF_THEN_ELSE
)
4257 if (GET_CODE (XEXP (SET_SRC (pat
), 1)) == LABEL_REF
)
4258 label
= &XEXP (SET_SRC (pat
), 1);
4259 else if (GET_CODE (XEXP (SET_SRC (pat
), 2)) == LABEL_REF
)
4260 label
= &XEXP (SET_SRC (pat
), 2);
4267 if (get_attr_length (insn
) <= 4)
4270 /* We are going to use the return register as scratch register,
4271 make sure it will be saved/restored by the prologue/epilogue. */
4272 cfun_frame_layout
.save_return_addr_p
= 1;
4277 tmp
= force_const_mem (Pmode
, *label
);
4278 tmp
= emit_insn_before (gen_rtx_SET (Pmode
, temp_reg
, tmp
), insn
);
4279 INSN_ADDRESSES_NEW (tmp
, -1);
4280 annotate_constant_pool_refs (&PATTERN (tmp
));
4287 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, *label
),
4288 UNSPEC_LTREL_OFFSET
);
4289 target
= gen_rtx_CONST (Pmode
, target
);
4290 target
= force_const_mem (Pmode
, target
);
4291 tmp
= emit_insn_before (gen_rtx_SET (Pmode
, temp_reg
, target
), insn
);
4292 INSN_ADDRESSES_NEW (tmp
, -1);
4293 annotate_constant_pool_refs (&PATTERN (tmp
));
4295 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XEXP (target
, 0),
4296 cfun
->machine
->base_reg
),
4298 target
= gen_rtx_PLUS (Pmode
, temp_reg
, target
);
4301 ret
= validate_change (insn
, label
, target
, 0);
4309 /* Find an annotated literal pool symbol referenced in RTX X,
4310 and store it at REF. Will abort if X contains references to
4311 more than one such pool symbol; multiple references to the same
4312 symbol are allowed, however.
4314 The rtx pointed to by REF must be initialized to NULL_RTX
4315 by the caller before calling this routine. */
4318 find_constant_pool_ref (rtx x
, rtx
*ref
)
4323 /* Ignore LTREL_BASE references. */
4324 if (GET_CODE (x
) == UNSPEC
4325 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
4327 /* Likewise POOL_ENTRY insns. */
4328 if (GET_CODE (x
) == UNSPEC_VOLATILE
4329 && XINT (x
, 1) == UNSPECV_POOL_ENTRY
)
4332 gcc_assert (GET_CODE (x
) != SYMBOL_REF
4333 || !CONSTANT_POOL_ADDRESS_P (x
));
4335 if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_LTREF
)
4337 rtx sym
= XVECEXP (x
, 0, 0);
4338 gcc_assert (GET_CODE (sym
) == SYMBOL_REF
4339 && CONSTANT_POOL_ADDRESS_P (sym
));
4341 if (*ref
== NULL_RTX
)
4344 gcc_assert (*ref
== sym
);
4349 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
4350 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
4354 find_constant_pool_ref (XEXP (x
, i
), ref
);
4356 else if (fmt
[i
] == 'E')
4358 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
4359 find_constant_pool_ref (XVECEXP (x
, i
, j
), ref
);
4364 /* Replace every reference to the annotated literal pool
4365 symbol REF in X by its base plus OFFSET. */
4368 replace_constant_pool_ref (rtx
*x
, rtx ref
, rtx offset
)
4373 gcc_assert (*x
!= ref
);
4375 if (GET_CODE (*x
) == UNSPEC
4376 && XINT (*x
, 1) == UNSPEC_LTREF
4377 && XVECEXP (*x
, 0, 0) == ref
)
4379 *x
= gen_rtx_PLUS (Pmode
, XVECEXP (*x
, 0, 1), offset
);
4383 if (GET_CODE (*x
) == PLUS
4384 && GET_CODE (XEXP (*x
, 1)) == CONST_INT
4385 && GET_CODE (XEXP (*x
, 0)) == UNSPEC
4386 && XINT (XEXP (*x
, 0), 1) == UNSPEC_LTREF
4387 && XVECEXP (XEXP (*x
, 0), 0, 0) == ref
)
4389 rtx addr
= gen_rtx_PLUS (Pmode
, XVECEXP (XEXP (*x
, 0), 0, 1), offset
);
4390 *x
= plus_constant (addr
, INTVAL (XEXP (*x
, 1)));
4394 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
4395 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
4399 replace_constant_pool_ref (&XEXP (*x
, i
), ref
, offset
);
4401 else if (fmt
[i
] == 'E')
4403 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
4404 replace_constant_pool_ref (&XVECEXP (*x
, i
, j
), ref
, offset
);
4409 /* Check whether X contains an UNSPEC_LTREL_BASE.
4410 Return its constant pool symbol if found, NULL_RTX otherwise. */
4413 find_ltrel_base (rtx x
)
4418 if (GET_CODE (x
) == UNSPEC
4419 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
4420 return XVECEXP (x
, 0, 0);
4422 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
4423 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
4427 rtx fnd
= find_ltrel_base (XEXP (x
, i
));
4431 else if (fmt
[i
] == 'E')
4433 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
4435 rtx fnd
= find_ltrel_base (XVECEXP (x
, i
, j
));
4445 /* Replace any occurrence of UNSPEC_LTREL_BASE in X with its base. */
4448 replace_ltrel_base (rtx
*x
)
4453 if (GET_CODE (*x
) == UNSPEC
4454 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
4456 *x
= XVECEXP (*x
, 0, 1);
4460 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
4461 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
4465 replace_ltrel_base (&XEXP (*x
, i
));
4467 else if (fmt
[i
] == 'E')
4469 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
4470 replace_ltrel_base (&XVECEXP (*x
, i
, j
));
4476 /* We keep a list of constants which we have to add to internal
4477 constant tables in the middle of large functions. */
4479 #define NR_C_MODES 7
4480 enum machine_mode constant_modes
[NR_C_MODES
] =
4491 struct constant
*next
;
4496 struct constant_pool
4498 struct constant_pool
*next
;
4503 struct constant
*constants
[NR_C_MODES
];
4504 struct constant
*execute
;
4509 /* Allocate new constant_pool structure. */
4511 static struct constant_pool
*
4512 s390_alloc_pool (void)
4514 struct constant_pool
*pool
;
4517 pool
= (struct constant_pool
*) xmalloc (sizeof *pool
);
4519 for (i
= 0; i
< NR_C_MODES
; i
++)
4520 pool
->constants
[i
] = NULL
;
4522 pool
->execute
= NULL
;
4523 pool
->label
= gen_label_rtx ();
4524 pool
->first_insn
= NULL_RTX
;
4525 pool
->pool_insn
= NULL_RTX
;
4526 pool
->insns
= BITMAP_ALLOC (NULL
);
4532 /* Create new constant pool covering instructions starting at INSN
4533 and chain it to the end of POOL_LIST. */
4535 static struct constant_pool
*
4536 s390_start_pool (struct constant_pool
**pool_list
, rtx insn
)
4538 struct constant_pool
*pool
, **prev
;
4540 pool
= s390_alloc_pool ();
4541 pool
->first_insn
= insn
;
4543 for (prev
= pool_list
; *prev
; prev
= &(*prev
)->next
)
4550 /* End range of instructions covered by POOL at INSN and emit
4551 placeholder insn representing the pool. */
4554 s390_end_pool (struct constant_pool
*pool
, rtx insn
)
4556 rtx pool_size
= GEN_INT (pool
->size
+ 8 /* alignment slop */);
4559 insn
= get_last_insn ();
4561 pool
->pool_insn
= emit_insn_after (gen_pool (pool_size
), insn
);
4562 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
4565 /* Add INSN to the list of insns covered by POOL. */
4568 s390_add_pool_insn (struct constant_pool
*pool
, rtx insn
)
4570 bitmap_set_bit (pool
->insns
, INSN_UID (insn
));
4573 /* Return pool out of POOL_LIST that covers INSN. */
4575 static struct constant_pool
*
4576 s390_find_pool (struct constant_pool
*pool_list
, rtx insn
)
4578 struct constant_pool
*pool
;
4580 for (pool
= pool_list
; pool
; pool
= pool
->next
)
4581 if (bitmap_bit_p (pool
->insns
, INSN_UID (insn
)))
4587 /* Add constant VAL of mode MODE to the constant pool POOL. */
4590 s390_add_constant (struct constant_pool
*pool
, rtx val
, enum machine_mode mode
)
4595 for (i
= 0; i
< NR_C_MODES
; i
++)
4596 if (constant_modes
[i
] == mode
)
4598 gcc_assert (i
!= NR_C_MODES
);
4600 for (c
= pool
->constants
[i
]; c
!= NULL
; c
= c
->next
)
4601 if (rtx_equal_p (val
, c
->value
))
4606 c
= (struct constant
*) xmalloc (sizeof *c
);
4608 c
->label
= gen_label_rtx ();
4609 c
->next
= pool
->constants
[i
];
4610 pool
->constants
[i
] = c
;
4611 pool
->size
+= GET_MODE_SIZE (mode
);
4615 /* Find constant VAL of mode MODE in the constant pool POOL.
4616 Return an RTX describing the distance from the start of
4617 the pool to the location of the new constant. */
4620 s390_find_constant (struct constant_pool
*pool
, rtx val
,
4621 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 offset
= gen_rtx_MINUS (Pmode
, gen_rtx_LABEL_REF (Pmode
, c
->label
),
4639 gen_rtx_LABEL_REF (Pmode
, pool
->label
));
4640 offset
= gen_rtx_CONST (Pmode
, offset
);
4644 /* Check whether INSN is an execute. Return the label_ref to its
4645 execute target template if so, NULL_RTX otherwise. */
4648 s390_execute_label (rtx insn
)
4650 if (GET_CODE (insn
) == INSN
4651 && GET_CODE (PATTERN (insn
)) == PARALLEL
4652 && GET_CODE (XVECEXP (PATTERN (insn
), 0, 0)) == UNSPEC
4653 && XINT (XVECEXP (PATTERN (insn
), 0, 0), 1) == UNSPEC_EXECUTE
)
4654 return XVECEXP (XVECEXP (PATTERN (insn
), 0, 0), 0, 2);
4659 /* Add execute target for INSN to the constant pool POOL. */
4662 s390_add_execute (struct constant_pool
*pool
, rtx insn
)
4666 for (c
= pool
->execute
; c
!= NULL
; c
= c
->next
)
4667 if (INSN_UID (insn
) == INSN_UID (c
->value
))
4672 rtx label
= s390_execute_label (insn
);
4675 c
= (struct constant
*) xmalloc (sizeof *c
);
4677 c
->label
= label
== const0_rtx
? gen_label_rtx () : XEXP (label
, 0);
4678 c
->next
= pool
->execute
;
4680 pool
->size
+= label
== const0_rtx
? 6 : 0;
4684 /* Find execute target for INSN in the constant pool POOL.
4685 Return an RTX describing the distance from the start of
4686 the pool to the location of the execute target. */
4689 s390_find_execute (struct constant_pool
*pool
, rtx insn
)
4694 for (c
= pool
->execute
; c
!= NULL
; c
= c
->next
)
4695 if (INSN_UID (insn
) == INSN_UID (c
->value
))
4700 offset
= gen_rtx_MINUS (Pmode
, gen_rtx_LABEL_REF (Pmode
, c
->label
),
4701 gen_rtx_LABEL_REF (Pmode
, pool
->label
));
4702 offset
= gen_rtx_CONST (Pmode
, offset
);
4706 /* For an execute INSN, extract the execute target template. */
4709 s390_execute_target (rtx insn
)
4711 rtx pattern
= PATTERN (insn
);
4712 gcc_assert (s390_execute_label (insn
));
4714 if (XVECLEN (pattern
, 0) == 2)
4716 pattern
= copy_rtx (XVECEXP (pattern
, 0, 1));
4720 rtvec vec
= rtvec_alloc (XVECLEN (pattern
, 0) - 1);
4723 for (i
= 0; i
< XVECLEN (pattern
, 0) - 1; i
++)
4724 RTVEC_ELT (vec
, i
) = copy_rtx (XVECEXP (pattern
, 0, i
+ 1));
4726 pattern
= gen_rtx_PARALLEL (VOIDmode
, vec
);
4732 /* Dump out the out-of-pool execute template insns in POOL
4733 at the end of the instruction stream. */
4736 s390_dump_execute (struct constant_pool
*pool
)
4741 for (c
= pool
->execute
; c
; c
= c
->next
)
4743 if (s390_execute_label (c
->value
) == const0_rtx
)
4746 insn
= emit_label (c
->label
);
4747 INSN_ADDRESSES_NEW (insn
, -1);
4749 insn
= emit_insn (s390_execute_target (c
->value
));
4750 INSN_ADDRESSES_NEW (insn
, -1);
4754 /* Indicate that INSN cannot be duplicated. This is the case for
4755 execute insns that carry a unique label. */
4758 s390_cannot_copy_insn_p (rtx insn
)
4760 rtx label
= s390_execute_label (insn
);
4761 return label
&& label
!= const0_rtx
;
4764 /* Dump out the constants in POOL. If REMOTE_LABEL is true,
4765 do not emit the pool base label. */
4768 s390_dump_pool (struct constant_pool
*pool
, bool remote_label
)
4771 rtx insn
= pool
->pool_insn
;
4774 /* Switch to rodata section. */
4775 if (TARGET_CPU_ZARCH
)
4777 insn
= emit_insn_after (gen_pool_section_start (), insn
);
4778 INSN_ADDRESSES_NEW (insn
, -1);
4781 /* Ensure minimum pool alignment. */
4782 if (TARGET_CPU_ZARCH
)
4783 insn
= emit_insn_after (gen_pool_align (GEN_INT (8)), insn
);
4785 insn
= emit_insn_after (gen_pool_align (GEN_INT (4)), insn
);
4786 INSN_ADDRESSES_NEW (insn
, -1);
4788 /* Emit pool base label. */
4791 insn
= emit_label_after (pool
->label
, insn
);
4792 INSN_ADDRESSES_NEW (insn
, -1);
4795 /* Dump constants in descending alignment requirement order,
4796 ensuring proper alignment for every constant. */
4797 for (i
= 0; i
< NR_C_MODES
; i
++)
4798 for (c
= pool
->constants
[i
]; c
; c
= c
->next
)
4800 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
4801 rtx value
= c
->value
;
4802 if (GET_CODE (value
) == CONST
4803 && GET_CODE (XEXP (value
, 0)) == UNSPEC
4804 && XINT (XEXP (value
, 0), 1) == UNSPEC_LTREL_OFFSET
4805 && XVECLEN (XEXP (value
, 0), 0) == 1)
4807 value
= gen_rtx_MINUS (Pmode
, XVECEXP (XEXP (value
, 0), 0, 0),
4808 gen_rtx_LABEL_REF (VOIDmode
, pool
->label
));
4809 value
= gen_rtx_CONST (VOIDmode
, value
);
4812 insn
= emit_label_after (c
->label
, insn
);
4813 INSN_ADDRESSES_NEW (insn
, -1);
4815 value
= gen_rtx_UNSPEC_VOLATILE (constant_modes
[i
],
4816 gen_rtvec (1, value
),
4817 UNSPECV_POOL_ENTRY
);
4818 insn
= emit_insn_after (value
, insn
);
4819 INSN_ADDRESSES_NEW (insn
, -1);
4822 /* Ensure minimum alignment for instructions. */
4823 insn
= emit_insn_after (gen_pool_align (GEN_INT (2)), insn
);
4824 INSN_ADDRESSES_NEW (insn
, -1);
4826 /* Output in-pool execute template insns. */
4827 for (c
= pool
->execute
; c
; c
= c
->next
)
4829 if (s390_execute_label (c
->value
) != const0_rtx
)
4832 insn
= emit_label_after (c
->label
, insn
);
4833 INSN_ADDRESSES_NEW (insn
, -1);
4835 insn
= emit_insn_after (s390_execute_target (c
->value
), insn
);
4836 INSN_ADDRESSES_NEW (insn
, -1);
4839 /* Switch back to previous section. */
4840 if (TARGET_CPU_ZARCH
)
4842 insn
= emit_insn_after (gen_pool_section_end (), insn
);
4843 INSN_ADDRESSES_NEW (insn
, -1);
4846 insn
= emit_barrier_after (insn
);
4847 INSN_ADDRESSES_NEW (insn
, -1);
4849 /* Remove placeholder insn. */
4850 remove_insn (pool
->pool_insn
);
4852 /* Output out-of-pool execute template isns. */
4853 s390_dump_execute (pool
);
4856 /* Free all memory used by POOL. */
4859 s390_free_pool (struct constant_pool
*pool
)
4861 struct constant
*c
, *next
;
4864 for (i
= 0; i
< NR_C_MODES
; i
++)
4865 for (c
= pool
->constants
[i
]; c
; c
= next
)
4871 for (c
= pool
->execute
; c
; c
= next
)
4877 BITMAP_FREE (pool
->insns
);
4882 /* Collect main literal pool. Return NULL on overflow. */
4884 static struct constant_pool
*
4885 s390_mainpool_start (void)
4887 struct constant_pool
*pool
;
4890 pool
= s390_alloc_pool ();
4892 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
4894 if (GET_CODE (insn
) == INSN
4895 && GET_CODE (PATTERN (insn
)) == SET
4896 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC_VOLATILE
4897 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPECV_MAIN_POOL
)
4899 gcc_assert (!pool
->pool_insn
);
4900 pool
->pool_insn
= insn
;
4903 if (s390_execute_label (insn
))
4905 s390_add_execute (pool
, insn
);
4907 else if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
4909 rtx pool_ref
= NULL_RTX
;
4910 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
4913 rtx constant
= get_pool_constant (pool_ref
);
4914 enum machine_mode mode
= get_pool_mode (pool_ref
);
4915 s390_add_constant (pool
, constant
, mode
);
4920 gcc_assert (pool
->pool_insn
|| pool
->size
== 0);
4922 if (pool
->size
>= 4096)
4924 /* We're going to chunkify the pool, so remove the main
4925 pool placeholder insn. */
4926 remove_insn (pool
->pool_insn
);
4928 s390_free_pool (pool
);
4935 /* POOL holds the main literal pool as collected by s390_mainpool_start.
4936 Modify the current function to output the pool constants as well as
4937 the pool register setup instruction. */
4940 s390_mainpool_finish (struct constant_pool
*pool
)
4942 rtx base_reg
= cfun
->machine
->base_reg
;
4945 /* If the pool is empty, we're done. */
4946 if (pool
->size
== 0)
4948 /* However, we may have out-of-pool execute templates. */
4949 s390_dump_execute (pool
);
4951 /* We don't actually need a base register after all. */
4952 cfun
->machine
->base_reg
= NULL_RTX
;
4954 if (pool
->pool_insn
)
4955 remove_insn (pool
->pool_insn
);
4956 s390_free_pool (pool
);
4960 /* We need correct insn addresses. */
4961 shorten_branches (get_insns ());
4963 /* On zSeries, we use a LARL to load the pool register. The pool is
4964 located in the .rodata section, so we emit it after the function. */
4965 if (TARGET_CPU_ZARCH
)
4967 insn
= gen_main_base_64 (base_reg
, pool
->label
);
4968 insn
= emit_insn_after (insn
, pool
->pool_insn
);
4969 INSN_ADDRESSES_NEW (insn
, -1);
4970 remove_insn (pool
->pool_insn
);
4972 insn
= get_last_insn ();
4973 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
4974 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
4976 s390_dump_pool (pool
, 0);
4979 /* On S/390, if the total size of the function's code plus literal pool
4980 does not exceed 4096 bytes, we use BASR to set up a function base
4981 pointer, and emit the literal pool at the end of the function. */
4982 else if (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
4983 + pool
->size
+ 8 /* alignment slop */ < 4096)
4985 insn
= gen_main_base_31_small (base_reg
, pool
->label
);
4986 insn
= emit_insn_after (insn
, pool
->pool_insn
);
4987 INSN_ADDRESSES_NEW (insn
, -1);
4988 remove_insn (pool
->pool_insn
);
4990 insn
= emit_label_after (pool
->label
, insn
);
4991 INSN_ADDRESSES_NEW (insn
, -1);
4993 insn
= get_last_insn ();
4994 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
4995 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
4997 s390_dump_pool (pool
, 1);
5000 /* Otherwise, we emit an inline literal pool and use BASR to branch
5001 over it, setting up the pool register at the same time. */
5004 rtx pool_end
= gen_label_rtx ();
5006 insn
= gen_main_base_31_large (base_reg
, pool
->label
, pool_end
);
5007 insn
= emit_insn_after (insn
, pool
->pool_insn
);
5008 INSN_ADDRESSES_NEW (insn
, -1);
5009 remove_insn (pool
->pool_insn
);
5011 insn
= emit_label_after (pool
->label
, insn
);
5012 INSN_ADDRESSES_NEW (insn
, -1);
5014 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
5015 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
5017 insn
= emit_label_after (pool_end
, pool
->pool_insn
);
5018 INSN_ADDRESSES_NEW (insn
, -1);
5020 s390_dump_pool (pool
, 1);
5024 /* Replace all literal pool references. */
5026 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5029 replace_ltrel_base (&PATTERN (insn
));
5031 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5033 rtx addr
, pool_ref
= NULL_RTX
;
5034 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5037 if (s390_execute_label (insn
))
5038 addr
= s390_find_execute (pool
, insn
);
5040 addr
= s390_find_constant (pool
, get_pool_constant (pool_ref
),
5041 get_pool_mode (pool_ref
));
5043 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
5044 INSN_CODE (insn
) = -1;
5050 /* Free the pool. */
5051 s390_free_pool (pool
);
5054 /* POOL holds the main literal pool as collected by s390_mainpool_start.
5055 We have decided we cannot use this pool, so revert all changes
5056 to the current function that were done by s390_mainpool_start. */
5058 s390_mainpool_cancel (struct constant_pool
*pool
)
5060 /* We didn't actually change the instruction stream, so simply
5061 free the pool memory. */
5062 s390_free_pool (pool
);
5066 /* Chunkify the literal pool. */
5068 #define S390_POOL_CHUNK_MIN 0xc00
5069 #define S390_POOL_CHUNK_MAX 0xe00
5071 static struct constant_pool
*
5072 s390_chunkify_start (void)
5074 struct constant_pool
*curr_pool
= NULL
, *pool_list
= NULL
;
5077 rtx pending_ltrel
= NULL_RTX
;
5080 rtx (*gen_reload_base
) (rtx
, rtx
) =
5081 TARGET_CPU_ZARCH
? gen_reload_base_64
: gen_reload_base_31
;
5084 /* We need correct insn addresses. */
5086 shorten_branches (get_insns ());
5088 /* Scan all insns and move literals to pool chunks. */
5090 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5092 /* Check for pending LTREL_BASE. */
5095 rtx ltrel_base
= find_ltrel_base (PATTERN (insn
));
5098 gcc_assert (ltrel_base
== pending_ltrel
);
5099 pending_ltrel
= NULL_RTX
;
5103 if (s390_execute_label (insn
))
5106 curr_pool
= s390_start_pool (&pool_list
, insn
);
5108 s390_add_execute (curr_pool
, insn
);
5109 s390_add_pool_insn (curr_pool
, insn
);
5111 else if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5113 rtx pool_ref
= NULL_RTX
;
5114 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5117 rtx constant
= get_pool_constant (pool_ref
);
5118 enum machine_mode mode
= get_pool_mode (pool_ref
);
5121 curr_pool
= s390_start_pool (&pool_list
, insn
);
5123 s390_add_constant (curr_pool
, constant
, mode
);
5124 s390_add_pool_insn (curr_pool
, insn
);
5126 /* Don't split the pool chunk between a LTREL_OFFSET load
5127 and the corresponding LTREL_BASE. */
5128 if (GET_CODE (constant
) == CONST
5129 && GET_CODE (XEXP (constant
, 0)) == UNSPEC
5130 && XINT (XEXP (constant
, 0), 1) == UNSPEC_LTREL_OFFSET
)
5132 gcc_assert (!pending_ltrel
);
5133 pending_ltrel
= pool_ref
;
5138 if (GET_CODE (insn
) == JUMP_INSN
|| GET_CODE (insn
) == CODE_LABEL
)
5141 s390_add_pool_insn (curr_pool
, insn
);
5142 /* An LTREL_BASE must follow within the same basic block. */
5143 gcc_assert (!pending_ltrel
);
5147 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn
)
5148 || INSN_ADDRESSES (INSN_UID (insn
)) == -1)
5151 if (TARGET_CPU_ZARCH
)
5153 if (curr_pool
->size
< S390_POOL_CHUNK_MAX
)
5156 s390_end_pool (curr_pool
, NULL_RTX
);
5161 int chunk_size
= INSN_ADDRESSES (INSN_UID (insn
))
5162 - INSN_ADDRESSES (INSN_UID (curr_pool
->first_insn
))
5165 /* We will later have to insert base register reload insns.
5166 Those will have an effect on code size, which we need to
5167 consider here. This calculation makes rather pessimistic
5168 worst-case assumptions. */
5169 if (GET_CODE (insn
) == CODE_LABEL
)
5172 if (chunk_size
< S390_POOL_CHUNK_MIN
5173 && curr_pool
->size
< S390_POOL_CHUNK_MIN
)
5176 /* Pool chunks can only be inserted after BARRIERs ... */
5177 if (GET_CODE (insn
) == BARRIER
)
5179 s390_end_pool (curr_pool
, insn
);
5184 /* ... so if we don't find one in time, create one. */
5185 else if ((chunk_size
> S390_POOL_CHUNK_MAX
5186 || curr_pool
->size
> S390_POOL_CHUNK_MAX
))
5188 rtx label
, jump
, barrier
;
5190 /* We can insert the barrier only after a 'real' insn. */
5191 if (GET_CODE (insn
) != INSN
&& GET_CODE (insn
) != CALL_INSN
)
5193 if (get_attr_length (insn
) == 0)
5196 /* Don't separate LTREL_BASE from the corresponding
5197 LTREL_OFFSET load. */
5201 label
= gen_label_rtx ();
5202 jump
= emit_jump_insn_after (gen_jump (label
), insn
);
5203 barrier
= emit_barrier_after (jump
);
5204 insn
= emit_label_after (label
, barrier
);
5205 JUMP_LABEL (jump
) = label
;
5206 LABEL_NUSES (label
) = 1;
5208 INSN_ADDRESSES_NEW (jump
, -1);
5209 INSN_ADDRESSES_NEW (barrier
, -1);
5210 INSN_ADDRESSES_NEW (insn
, -1);
5212 s390_end_pool (curr_pool
, barrier
);
5220 s390_end_pool (curr_pool
, NULL_RTX
);
5221 gcc_assert (!pending_ltrel
);
5223 /* Find all labels that are branched into
5224 from an insn belonging to a different chunk. */
5226 far_labels
= BITMAP_ALLOC (NULL
);
5228 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5230 /* Labels marked with LABEL_PRESERVE_P can be target
5231 of non-local jumps, so we have to mark them.
5232 The same holds for named labels.
5234 Don't do that, however, if it is the label before
5237 if (GET_CODE (insn
) == CODE_LABEL
5238 && (LABEL_PRESERVE_P (insn
) || LABEL_NAME (insn
)))
5240 rtx vec_insn
= next_real_insn (insn
);
5241 rtx vec_pat
= vec_insn
&& GET_CODE (vec_insn
) == JUMP_INSN
?
5242 PATTERN (vec_insn
) : NULL_RTX
;
5244 || !(GET_CODE (vec_pat
) == ADDR_VEC
5245 || GET_CODE (vec_pat
) == ADDR_DIFF_VEC
))
5246 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (insn
));
5249 /* If we have a direct jump (conditional or unconditional)
5250 or a casesi jump, check all potential targets. */
5251 else if (GET_CODE (insn
) == JUMP_INSN
)
5253 rtx pat
= PATTERN (insn
);
5254 if (GET_CODE (pat
) == PARALLEL
&& XVECLEN (pat
, 0) > 2)
5255 pat
= XVECEXP (pat
, 0, 0);
5257 if (GET_CODE (pat
) == SET
)
5259 rtx label
= JUMP_LABEL (insn
);
5262 if (s390_find_pool (pool_list
, label
)
5263 != s390_find_pool (pool_list
, insn
))
5264 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
5267 else if (GET_CODE (pat
) == PARALLEL
5268 && XVECLEN (pat
, 0) == 2
5269 && GET_CODE (XVECEXP (pat
, 0, 0)) == SET
5270 && GET_CODE (XVECEXP (pat
, 0, 1)) == USE
5271 && GET_CODE (XEXP (XVECEXP (pat
, 0, 1), 0)) == LABEL_REF
)
5273 /* Find the jump table used by this casesi jump. */
5274 rtx vec_label
= XEXP (XEXP (XVECEXP (pat
, 0, 1), 0), 0);
5275 rtx vec_insn
= next_real_insn (vec_label
);
5276 rtx vec_pat
= vec_insn
&& GET_CODE (vec_insn
) == JUMP_INSN
?
5277 PATTERN (vec_insn
) : NULL_RTX
;
5279 && (GET_CODE (vec_pat
) == ADDR_VEC
5280 || GET_CODE (vec_pat
) == ADDR_DIFF_VEC
))
5282 int i
, diff_p
= GET_CODE (vec_pat
) == ADDR_DIFF_VEC
;
5284 for (i
= 0; i
< XVECLEN (vec_pat
, diff_p
); i
++)
5286 rtx label
= XEXP (XVECEXP (vec_pat
, diff_p
, i
), 0);
5288 if (s390_find_pool (pool_list
, label
)
5289 != s390_find_pool (pool_list
, insn
))
5290 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
5297 /* Insert base register reload insns before every pool. */
5299 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
5301 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
5303 rtx insn
= curr_pool
->first_insn
;
5304 INSN_ADDRESSES_NEW (emit_insn_before (new_insn
, insn
), -1);
5307 /* Insert base register reload insns at every far label. */
5309 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5310 if (GET_CODE (insn
) == CODE_LABEL
5311 && bitmap_bit_p (far_labels
, CODE_LABEL_NUMBER (insn
)))
5313 struct constant_pool
*pool
= s390_find_pool (pool_list
, insn
);
5316 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
5318 INSN_ADDRESSES_NEW (emit_insn_after (new_insn
, insn
), -1);
5323 BITMAP_FREE (far_labels
);
5326 /* Recompute insn addresses. */
5328 init_insn_lengths ();
5329 shorten_branches (get_insns ());
5334 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
5335 After we have decided to use this list, finish implementing
5336 all changes to the current function as required. */
5339 s390_chunkify_finish (struct constant_pool
*pool_list
)
5341 struct constant_pool
*curr_pool
= NULL
;
5345 /* Replace all literal pool references. */
5347 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5350 replace_ltrel_base (&PATTERN (insn
));
5352 curr_pool
= s390_find_pool (pool_list
, insn
);
5356 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5358 rtx addr
, pool_ref
= NULL_RTX
;
5359 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5362 if (s390_execute_label (insn
))
5363 addr
= s390_find_execute (curr_pool
, insn
);
5365 addr
= s390_find_constant (curr_pool
,
5366 get_pool_constant (pool_ref
),
5367 get_pool_mode (pool_ref
));
5369 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
5370 INSN_CODE (insn
) = -1;
5375 /* Dump out all literal pools. */
5377 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
5378 s390_dump_pool (curr_pool
, 0);
5380 /* Free pool list. */
5384 struct constant_pool
*next
= pool_list
->next
;
5385 s390_free_pool (pool_list
);
5390 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
5391 We have decided we cannot use this list, so revert all changes
5392 to the current function that were done by s390_chunkify_start. */
5395 s390_chunkify_cancel (struct constant_pool
*pool_list
)
5397 struct constant_pool
*curr_pool
= NULL
;
5400 /* Remove all pool placeholder insns. */
5402 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
5404 /* Did we insert an extra barrier? Remove it. */
5405 rtx barrier
= PREV_INSN (curr_pool
->pool_insn
);
5406 rtx jump
= barrier
? PREV_INSN (barrier
) : NULL_RTX
;
5407 rtx label
= NEXT_INSN (curr_pool
->pool_insn
);
5409 if (jump
&& GET_CODE (jump
) == JUMP_INSN
5410 && barrier
&& GET_CODE (barrier
) == BARRIER
5411 && label
&& GET_CODE (label
) == CODE_LABEL
5412 && GET_CODE (PATTERN (jump
)) == SET
5413 && SET_DEST (PATTERN (jump
)) == pc_rtx
5414 && GET_CODE (SET_SRC (PATTERN (jump
))) == LABEL_REF
5415 && XEXP (SET_SRC (PATTERN (jump
)), 0) == label
)
5418 remove_insn (barrier
);
5419 remove_insn (label
);
5422 remove_insn (curr_pool
->pool_insn
);
5425 /* Remove all base register reload insns. */
5427 for (insn
= get_insns (); insn
; )
5429 rtx next_insn
= NEXT_INSN (insn
);
5431 if (GET_CODE (insn
) == INSN
5432 && GET_CODE (PATTERN (insn
)) == SET
5433 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC
5434 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPEC_RELOAD_BASE
)
5440 /* Free pool list. */
5444 struct constant_pool
*next
= pool_list
->next
;
5445 s390_free_pool (pool_list
);
5451 /* Output the constant pool entry EXP in mode MODE with alignment ALIGN. */
5454 s390_output_pool_entry (rtx exp
, enum machine_mode mode
, unsigned int align
)
5458 switch (GET_MODE_CLASS (mode
))
5461 gcc_assert (GET_CODE (exp
) == CONST_DOUBLE
);
5463 REAL_VALUE_FROM_CONST_DOUBLE (r
, exp
);
5464 assemble_real (r
, mode
, align
);
5468 assemble_integer (exp
, GET_MODE_SIZE (mode
), align
, 1);
5477 /* Return an RTL expression representing the value of the return address
5478 for the frame COUNT steps up from the current frame. FRAME is the
5479 frame pointer of that frame. */
5482 s390_return_addr_rtx (int count
, rtx frame ATTRIBUTE_UNUSED
)
5487 /* Without backchain, we fail for all but the current frame. */
5489 if (!TARGET_BACKCHAIN
&& count
> 0)
5492 /* For the current frame, we need to make sure the initial
5493 value of RETURN_REGNUM is actually saved. */
5497 cfun_frame_layout
.save_return_addr_p
= true;
5498 return gen_rtx_MEM (Pmode
, return_address_pointer_rtx
);
5501 if (TARGET_PACKED_STACK
)
5502 offset
= -2 * UNITS_PER_WORD
;
5504 offset
= RETURN_REGNUM
* UNITS_PER_WORD
;
5506 addr
= plus_constant (frame
, offset
);
5507 addr
= memory_address (Pmode
, addr
);
5508 return gen_rtx_MEM (Pmode
, addr
);
5511 /* Return an RTL expression representing the back chain stored in
5512 the current stack frame. */
5515 s390_back_chain_rtx (void)
5519 gcc_assert (TARGET_BACKCHAIN
);
5521 if (TARGET_PACKED_STACK
)
5522 chain
= plus_constant (stack_pointer_rtx
,
5523 STACK_POINTER_OFFSET
- UNITS_PER_WORD
);
5525 chain
= stack_pointer_rtx
;
5527 chain
= gen_rtx_MEM (Pmode
, chain
);
5531 /* Find first call clobbered register unused in a function.
5532 This could be used as base register in a leaf function
5533 or for holding the return address before epilogue. */
5536 find_unused_clobbered_reg (void)
5539 for (i
= 0; i
< 6; i
++)
5540 if (!regs_ever_live
[i
])
5545 /* Determine the frame area which actually has to be accessed
5546 in the function epilogue. The values are stored at the
5547 given pointers AREA_BOTTOM (address of the lowest used stack
5548 address) and AREA_TOP (address of the first item which does
5549 not belong to the stack frame). */
5552 s390_frame_area (int *area_bottom
, int *area_top
)
5560 if (cfun_frame_layout
.first_restore_gpr
!= -1)
5562 b
= (cfun_frame_layout
.gprs_offset
5563 + cfun_frame_layout
.first_restore_gpr
* UNITS_PER_WORD
);
5564 t
= b
+ (cfun_frame_layout
.last_restore_gpr
5565 - cfun_frame_layout
.first_restore_gpr
+ 1) * UNITS_PER_WORD
;
5568 if (TARGET_64BIT
&& cfun_save_high_fprs_p
)
5570 b
= MIN (b
, cfun_frame_layout
.f8_offset
);
5571 t
= MAX (t
, (cfun_frame_layout
.f8_offset
5572 + cfun_frame_layout
.high_fprs
* 8));
5576 for (i
= 2; i
< 4; i
++)
5577 if (cfun_fpr_bit_p (i
))
5579 b
= MIN (b
, cfun_frame_layout
.f4_offset
+ (i
- 2) * 8);
5580 t
= MAX (t
, cfun_frame_layout
.f4_offset
+ (i
- 1) * 8);
5587 /* Fill cfun->machine with info about register usage of current function.
5588 Return in LIVE_REGS which GPRs are currently considered live. */
5591 s390_register_info (int live_regs
[])
5595 /* fprs 8 - 15 are call saved for 64 Bit ABI. */
5596 cfun_frame_layout
.fpr_bitmap
= 0;
5597 cfun_frame_layout
.high_fprs
= 0;
5599 for (i
= 24; i
< 32; i
++)
5600 if (regs_ever_live
[i
] && !global_regs
[i
])
5602 cfun_set_fpr_bit (i
- 16);
5603 cfun_frame_layout
.high_fprs
++;
5606 /* Find first and last gpr to be saved. We trust regs_ever_live
5607 data, except that we don't save and restore global registers.
5609 Also, all registers with special meaning to the compiler need
5610 to be handled extra. */
5612 for (i
= 0; i
< 16; i
++)
5613 live_regs
[i
] = regs_ever_live
[i
] && !global_regs
[i
];
5616 live_regs
[PIC_OFFSET_TABLE_REGNUM
]
5617 = regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
];
5619 live_regs
[BASE_REGNUM
]
5620 = cfun
->machine
->base_reg
5621 && REGNO (cfun
->machine
->base_reg
) == BASE_REGNUM
;
5623 live_regs
[RETURN_REGNUM
]
5624 = cfun
->machine
->split_branches_pending_p
5625 || cfun_frame_layout
.save_return_addr_p
;
5627 live_regs
[STACK_POINTER_REGNUM
]
5628 = !current_function_is_leaf
5629 || TARGET_TPF_PROFILING
5630 || cfun_save_high_fprs_p
5631 || get_frame_size () > 0
5632 || current_function_calls_alloca
5633 || current_function_stdarg
;
5635 for (i
= 6; i
< 16; i
++)
5638 for (j
= 15; j
> i
; j
--)
5644 /* Nothing to save/restore. */
5645 cfun_frame_layout
.first_save_gpr
= -1;
5646 cfun_frame_layout
.first_restore_gpr
= -1;
5647 cfun_frame_layout
.last_save_gpr
= -1;
5648 cfun_frame_layout
.last_restore_gpr
= -1;
5652 /* Save / Restore from gpr i to j. */
5653 cfun_frame_layout
.first_save_gpr
= i
;
5654 cfun_frame_layout
.first_restore_gpr
= i
;
5655 cfun_frame_layout
.last_save_gpr
= j
;
5656 cfun_frame_layout
.last_restore_gpr
= j
;
5659 if (current_function_stdarg
)
5661 /* Varargs functions need to save gprs 2 to 6. */
5662 if (cfun_frame_layout
.first_save_gpr
== -1
5663 || cfun_frame_layout
.first_save_gpr
> 2)
5664 cfun_frame_layout
.first_save_gpr
= 2;
5666 if (cfun_frame_layout
.last_save_gpr
== -1
5667 || cfun_frame_layout
.last_save_gpr
< 6)
5668 cfun_frame_layout
.last_save_gpr
= 6;
5670 /* Mark f0, f2 for 31 bit and f0-f4 for 64 bit to be saved. */
5671 if (TARGET_HARD_FLOAT
)
5672 for (i
= 0; i
< (TARGET_64BIT
? 4 : 2); i
++)
5673 cfun_set_fpr_bit (i
);
5677 for (i
= 2; i
< 4; i
++)
5678 if (regs_ever_live
[i
+ 16] && !global_regs
[i
+ 16])
5679 cfun_set_fpr_bit (i
);
5682 /* Fill cfun->machine with info about frame of current function. */
5685 s390_frame_info (void)
5689 cfun_frame_layout
.frame_size
= get_frame_size ();
5690 if (!TARGET_64BIT
&& cfun_frame_layout
.frame_size
> 0x7fff0000)
5691 fatal_error ("Total size of local variables exceeds architecture limit.");
5693 if (!TARGET_PACKED_STACK
)
5695 cfun_frame_layout
.backchain_offset
= 0;
5696 cfun_frame_layout
.f0_offset
= 16 * UNITS_PER_WORD
;
5697 cfun_frame_layout
.f4_offset
= cfun_frame_layout
.f0_offset
+ 2 * 8;
5698 cfun_frame_layout
.f8_offset
= -cfun_frame_layout
.high_fprs
* 8;
5699 cfun_frame_layout
.gprs_offset
= (cfun_frame_layout
.first_save_gpr
5702 else if (TARGET_BACKCHAIN
) /* kernel stack layout */
5704 cfun_frame_layout
.backchain_offset
= (STACK_POINTER_OFFSET
5706 cfun_frame_layout
.gprs_offset
5707 = (cfun_frame_layout
.backchain_offset
5708 - (STACK_POINTER_REGNUM
- cfun_frame_layout
.first_save_gpr
+ 1)
5713 cfun_frame_layout
.f4_offset
5714 = (cfun_frame_layout
.gprs_offset
5715 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
5717 cfun_frame_layout
.f0_offset
5718 = (cfun_frame_layout
.f4_offset
5719 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
5723 /* On 31 bit we have to care about alignment of the
5724 floating point regs to provide fastest access. */
5725 cfun_frame_layout
.f0_offset
5726 = ((cfun_frame_layout
.gprs_offset
5727 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1))
5728 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
5730 cfun_frame_layout
.f4_offset
5731 = (cfun_frame_layout
.f0_offset
5732 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
5735 else /* no backchain */
5737 cfun_frame_layout
.f4_offset
5738 = (STACK_POINTER_OFFSET
5739 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
5741 cfun_frame_layout
.f0_offset
5742 = (cfun_frame_layout
.f4_offset
5743 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
5745 cfun_frame_layout
.gprs_offset
5746 = cfun_frame_layout
.f0_offset
- cfun_gprs_save_area_size
;
5749 if (current_function_is_leaf
5750 && !TARGET_TPF_PROFILING
5751 && cfun_frame_layout
.frame_size
== 0
5752 && !cfun_save_high_fprs_p
5753 && !current_function_calls_alloca
5754 && !current_function_stdarg
)
5757 if (!TARGET_PACKED_STACK
)
5758 cfun_frame_layout
.frame_size
+= (STARTING_FRAME_OFFSET
5759 + cfun_frame_layout
.high_fprs
* 8);
5762 if (TARGET_BACKCHAIN
)
5763 cfun_frame_layout
.frame_size
+= UNITS_PER_WORD
;
5765 /* No alignment trouble here because f8-f15 are only saved under
5767 cfun_frame_layout
.f8_offset
= (MIN (MIN (cfun_frame_layout
.f0_offset
,
5768 cfun_frame_layout
.f4_offset
),
5769 cfun_frame_layout
.gprs_offset
)
5770 - cfun_frame_layout
.high_fprs
* 8);
5772 cfun_frame_layout
.frame_size
+= cfun_frame_layout
.high_fprs
* 8;
5774 for (i
= 0; i
< 8; i
++)
5775 if (cfun_fpr_bit_p (i
))
5776 cfun_frame_layout
.frame_size
+= 8;
5778 cfun_frame_layout
.frame_size
+= cfun_gprs_save_area_size
;
5780 /* If under 31 bit an odd number of gprs has to be saved we have to adjust
5781 the frame size to sustain 8 byte alignment of stack frames. */
5782 cfun_frame_layout
.frame_size
= ((cfun_frame_layout
.frame_size
+
5783 STACK_BOUNDARY
/ BITS_PER_UNIT
- 1)
5784 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1));
5786 cfun_frame_layout
.frame_size
+= current_function_outgoing_args_size
;
5790 /* Generate frame layout. Fills in register and frame data for the current
5791 function in cfun->machine. This routine can be called multiple times;
5792 it will re-do the complete frame layout every time. */
5795 s390_init_frame_layout (void)
5797 HOST_WIDE_INT frame_size
;
5801 /* If return address register is explicitly used, we need to save it. */
5802 if (regs_ever_live
[RETURN_REGNUM
]
5803 || !current_function_is_leaf
5804 || TARGET_TPF_PROFILING
5805 || current_function_stdarg
5806 || current_function_calls_eh_return
)
5807 cfun_frame_layout
.save_return_addr_p
= true;
5809 /* On S/390 machines, we may need to perform branch splitting, which
5810 will require both base and return address register. We have no
5811 choice but to assume we're going to need them until right at the
5812 end of the machine dependent reorg phase. */
5813 if (!TARGET_CPU_ZARCH
)
5814 cfun
->machine
->split_branches_pending_p
= true;
5818 frame_size
= cfun_frame_layout
.frame_size
;
5820 /* Try to predict whether we'll need the base register. */
5821 base_used
= cfun
->machine
->split_branches_pending_p
5822 || current_function_uses_const_pool
5823 || (!DISP_IN_RANGE (-frame_size
)
5824 && !CONST_OK_FOR_CONSTRAINT_P (-frame_size
, 'K', "K"));
5826 /* Decide which register to use as literal pool base. In small
5827 leaf functions, try to use an unused call-clobbered register
5828 as base register to avoid save/restore overhead. */
5830 cfun
->machine
->base_reg
= NULL_RTX
;
5831 else if (current_function_is_leaf
&& !regs_ever_live
[5])
5832 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, 5);
5834 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
5836 s390_register_info (live_regs
);
5839 while (frame_size
!= cfun_frame_layout
.frame_size
);
5842 /* Update frame layout. Recompute actual register save data based on
5843 current info and update regs_ever_live for the special registers.
5844 May be called multiple times, but may never cause *more* registers
5845 to be saved than s390_init_frame_layout allocated room for. */
5848 s390_update_frame_layout (void)
5852 s390_register_info (live_regs
);
5854 regs_ever_live
[BASE_REGNUM
] = live_regs
[BASE_REGNUM
];
5855 regs_ever_live
[RETURN_REGNUM
] = live_regs
[RETURN_REGNUM
];
5856 regs_ever_live
[STACK_POINTER_REGNUM
] = live_regs
[STACK_POINTER_REGNUM
];
5858 if (cfun
->machine
->base_reg
)
5859 regs_ever_live
[REGNO (cfun
->machine
->base_reg
)] = 1;
5862 /* Return true if register FROM can be eliminated via register TO. */
5865 s390_can_eliminate (int from
, int to
)
5867 gcc_assert (to
== STACK_POINTER_REGNUM
5868 || to
== HARD_FRAME_POINTER_REGNUM
);
5870 gcc_assert (from
== FRAME_POINTER_REGNUM
5871 || from
== ARG_POINTER_REGNUM
5872 || from
== RETURN_ADDRESS_POINTER_REGNUM
);
5874 /* Make sure we actually saved the return address. */
5875 if (from
== RETURN_ADDRESS_POINTER_REGNUM
)
5876 if (!current_function_calls_eh_return
5877 && !current_function_stdarg
5878 && !cfun_frame_layout
.save_return_addr_p
)
5884 /* Return offset between register FROM and TO initially after prolog. */
5887 s390_initial_elimination_offset (int from
, int to
)
5889 HOST_WIDE_INT offset
;
5892 /* ??? Why are we called for non-eliminable pairs? */
5893 if (!s390_can_eliminate (from
, to
))
5898 case FRAME_POINTER_REGNUM
:
5902 case ARG_POINTER_REGNUM
:
5903 s390_init_frame_layout ();
5904 offset
= cfun_frame_layout
.frame_size
+ STACK_POINTER_OFFSET
;
5907 case RETURN_ADDRESS_POINTER_REGNUM
:
5908 s390_init_frame_layout ();
5909 index
= RETURN_REGNUM
- cfun_frame_layout
.first_save_gpr
;
5910 gcc_assert (index
>= 0);
5911 offset
= cfun_frame_layout
.frame_size
+ cfun_frame_layout
.gprs_offset
;
5912 offset
+= index
* UNITS_PER_WORD
;
5922 /* Emit insn to save fpr REGNUM at offset OFFSET relative
5923 to register BASE. Return generated insn. */
5926 save_fpr (rtx base
, int offset
, int regnum
)
5929 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
5930 set_mem_alias_set (addr
, s390_sr_alias_set
);
5932 return emit_move_insn (addr
, gen_rtx_REG (DFmode
, regnum
));
5935 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
5936 to register BASE. Return generated insn. */
5939 restore_fpr (rtx base
, int offset
, int regnum
)
5942 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
5943 set_mem_alias_set (addr
, s390_sr_alias_set
);
5945 return emit_move_insn (gen_rtx_REG (DFmode
, regnum
), addr
);
5948 /* Generate insn to save registers FIRST to LAST into
5949 the register save area located at offset OFFSET
5950 relative to register BASE. */
5953 save_gprs (rtx base
, int offset
, int first
, int last
)
5955 rtx addr
, insn
, note
;
5958 addr
= plus_constant (base
, offset
);
5959 addr
= gen_rtx_MEM (Pmode
, addr
);
5960 set_mem_alias_set (addr
, s390_sr_alias_set
);
5962 /* Special-case single register. */
5966 insn
= gen_movdi (addr
, gen_rtx_REG (Pmode
, first
));
5968 insn
= gen_movsi (addr
, gen_rtx_REG (Pmode
, first
));
5970 RTX_FRAME_RELATED_P (insn
) = 1;
5975 insn
= gen_store_multiple (addr
,
5976 gen_rtx_REG (Pmode
, first
),
5977 GEN_INT (last
- first
+ 1));
5980 /* We need to set the FRAME_RELATED flag on all SETs
5981 inside the store-multiple pattern.
5983 However, we must not emit DWARF records for registers 2..5
5984 if they are stored for use by variable arguments ...
5986 ??? Unfortunately, it is not enough to simply not the the
5987 FRAME_RELATED flags for those SETs, because the first SET
5988 of the PARALLEL is always treated as if it had the flag
5989 set, even if it does not. Therefore we emit a new pattern
5990 without those registers as REG_FRAME_RELATED_EXPR note. */
5994 rtx pat
= PATTERN (insn
);
5996 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
5997 if (GET_CODE (XVECEXP (pat
, 0, i
)) == SET
)
5998 RTX_FRAME_RELATED_P (XVECEXP (pat
, 0, i
)) = 1;
6000 RTX_FRAME_RELATED_P (insn
) = 1;
6004 addr
= plus_constant (base
, offset
+ (6 - first
) * UNITS_PER_WORD
);
6005 note
= gen_store_multiple (gen_rtx_MEM (Pmode
, addr
),
6006 gen_rtx_REG (Pmode
, 6),
6007 GEN_INT (last
- 6 + 1));
6008 note
= PATTERN (note
);
6011 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
6012 note
, REG_NOTES (insn
));
6014 for (i
= 0; i
< XVECLEN (note
, 0); i
++)
6015 if (GET_CODE (XVECEXP (note
, 0, i
)) == SET
)
6016 RTX_FRAME_RELATED_P (XVECEXP (note
, 0, i
)) = 1;
6018 RTX_FRAME_RELATED_P (insn
) = 1;
6024 /* Generate insn to restore registers FIRST to LAST from
6025 the register save area located at offset OFFSET
6026 relative to register BASE. */
6029 restore_gprs (rtx base
, int offset
, int first
, int last
)
6033 addr
= plus_constant (base
, offset
);
6034 addr
= gen_rtx_MEM (Pmode
, addr
);
6035 set_mem_alias_set (addr
, s390_sr_alias_set
);
6037 /* Special-case single register. */
6041 insn
= gen_movdi (gen_rtx_REG (Pmode
, first
), addr
);
6043 insn
= gen_movsi (gen_rtx_REG (Pmode
, first
), addr
);
6048 insn
= gen_load_multiple (gen_rtx_REG (Pmode
, first
),
6050 GEN_INT (last
- first
+ 1));
6054 /* Return insn sequence to load the GOT register. */
6056 static GTY(()) rtx got_symbol
;
6058 s390_load_got (void)
6064 got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
6065 SYMBOL_REF_FLAGS (got_symbol
) = SYMBOL_FLAG_LOCAL
;
6070 if (TARGET_CPU_ZARCH
)
6072 emit_move_insn (pic_offset_table_rtx
, got_symbol
);
6078 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, got_symbol
),
6079 UNSPEC_LTREL_OFFSET
);
6080 offset
= gen_rtx_CONST (Pmode
, offset
);
6081 offset
= force_const_mem (Pmode
, offset
);
6083 emit_move_insn (pic_offset_table_rtx
, offset
);
6085 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, XEXP (offset
, 0)),
6087 offset
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, offset
);
6089 emit_move_insn (pic_offset_table_rtx
, offset
);
6092 insns
= get_insns ();
6097 /* Expand the prologue into a bunch of separate insns. */
6100 s390_emit_prologue (void)
6108 /* Complete frame layout. */
6110 s390_update_frame_layout ();
6112 /* Annotate all constant pool references to let the scheduler know
6113 they implicitly use the base register. */
6115 push_topmost_sequence ();
6117 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6119 annotate_constant_pool_refs (&PATTERN (insn
));
6121 pop_topmost_sequence ();
6123 /* Choose best register to use for temp use within prologue.
6124 See below for why TPF must use the register 1. */
6126 if (!current_function_is_leaf
&& !TARGET_TPF_PROFILING
)
6127 temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
6129 temp_reg
= gen_rtx_REG (Pmode
, 1);
6131 /* Save call saved gprs. */
6132 if (cfun_frame_layout
.first_save_gpr
!= -1)
6134 insn
= save_gprs (stack_pointer_rtx
,
6135 cfun_frame_layout
.gprs_offset
,
6136 cfun_frame_layout
.first_save_gpr
,
6137 cfun_frame_layout
.last_save_gpr
);
6141 /* Dummy insn to mark literal pool slot. */
6143 if (cfun
->machine
->base_reg
)
6144 emit_insn (gen_main_pool (cfun
->machine
->base_reg
));
6146 offset
= cfun_frame_layout
.f0_offset
;
6148 /* Save f0 and f2. */
6149 for (i
= 0; i
< 2; i
++)
6151 if (cfun_fpr_bit_p (i
))
6153 save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
6156 else if (!TARGET_PACKED_STACK
)
6160 /* Save f4 and f6. */
6161 offset
= cfun_frame_layout
.f4_offset
;
6162 for (i
= 2; i
< 4; i
++)
6164 if (cfun_fpr_bit_p (i
))
6166 insn
= save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
6169 /* If f4 and f6 are call clobbered they are saved due to stdargs and
6170 therefore are not frame related. */
6171 if (!call_really_used_regs
[i
+ 16])
6172 RTX_FRAME_RELATED_P (insn
) = 1;
6174 else if (!TARGET_PACKED_STACK
)
6178 if (TARGET_PACKED_STACK
6179 && cfun_save_high_fprs_p
6180 && cfun_frame_layout
.f8_offset
+ cfun_frame_layout
.high_fprs
* 8 > 0)
6182 offset
= (cfun_frame_layout
.f8_offset
6183 + (cfun_frame_layout
.high_fprs
- 1) * 8);
6185 for (i
= 15; i
> 7 && offset
>= 0; i
--)
6186 if (cfun_fpr_bit_p (i
))
6188 insn
= save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
6190 RTX_FRAME_RELATED_P (insn
) = 1;
6193 if (offset
>= cfun_frame_layout
.f8_offset
)
6197 if (!TARGET_PACKED_STACK
)
6198 next_fpr
= cfun_save_high_fprs_p
? 31 : 0;
6200 /* Decrement stack pointer. */
6202 if (cfun_frame_layout
.frame_size
> 0)
6204 rtx frame_off
= GEN_INT (-cfun_frame_layout
.frame_size
);
6206 if (s390_stack_size
)
6208 HOST_WIDE_INT stack_check_mask
= ((s390_stack_size
- 1)
6209 & ~(s390_stack_guard
- 1));
6210 rtx t
= gen_rtx_AND (Pmode
, stack_pointer_rtx
,
6211 GEN_INT (stack_check_mask
));
6214 gen_cmpdi (t
, const0_rtx
);
6216 gen_cmpsi (t
, const0_rtx
);
6218 emit_insn (gen_conditional_trap (gen_rtx_EQ (CCmode
,
6219 gen_rtx_REG (CCmode
,
6225 if (s390_warn_framesize
> 0
6226 && cfun_frame_layout
.frame_size
>= s390_warn_framesize
)
6227 warning (0, "frame size of %qs is " HOST_WIDE_INT_PRINT_DEC
" bytes",
6228 current_function_name (), cfun_frame_layout
.frame_size
);
6230 if (s390_warn_dynamicstack_p
&& cfun
->calls_alloca
)
6231 warning (0, "%qs uses dynamic stack allocation", current_function_name ());
6233 /* Save incoming stack pointer into temp reg. */
6234 if (TARGET_BACKCHAIN
|| next_fpr
)
6235 insn
= emit_insn (gen_move_insn (temp_reg
, stack_pointer_rtx
));
6237 /* Subtract frame size from stack pointer. */
6239 if (DISP_IN_RANGE (INTVAL (frame_off
)))
6241 insn
= gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
6242 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
6244 insn
= emit_insn (insn
);
6248 if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off
), 'K', "K"))
6249 frame_off
= force_const_mem (Pmode
, frame_off
);
6251 insn
= emit_insn (gen_add2_insn (stack_pointer_rtx
, frame_off
));
6252 annotate_constant_pool_refs (&PATTERN (insn
));
6255 RTX_FRAME_RELATED_P (insn
) = 1;
6257 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
6258 gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
6259 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
6260 GEN_INT (-cfun_frame_layout
.frame_size
))),
6263 /* Set backchain. */
6265 if (TARGET_BACKCHAIN
)
6267 if (cfun_frame_layout
.backchain_offset
)
6268 addr
= gen_rtx_MEM (Pmode
,
6269 plus_constant (stack_pointer_rtx
,
6270 cfun_frame_layout
.backchain_offset
));
6272 addr
= gen_rtx_MEM (Pmode
, stack_pointer_rtx
);
6273 set_mem_alias_set (addr
, s390_sr_alias_set
);
6274 insn
= emit_insn (gen_move_insn (addr
, temp_reg
));
6277 /* If we support asynchronous exceptions (e.g. for Java),
6278 we need to make sure the backchain pointer is set up
6279 before any possibly trapping memory access. */
6281 if (TARGET_BACKCHAIN
&& flag_non_call_exceptions
)
6283 addr
= gen_rtx_MEM (BLKmode
, gen_rtx_SCRATCH (VOIDmode
));
6284 emit_insn (gen_rtx_CLOBBER (VOIDmode
, addr
));
6288 /* Save fprs 8 - 15 (64 bit ABI). */
6290 if (cfun_save_high_fprs_p
&& next_fpr
)
6292 insn
= emit_insn (gen_add2_insn (temp_reg
,
6293 GEN_INT (cfun_frame_layout
.f8_offset
)));
6297 for (i
= 24; i
<= next_fpr
; i
++)
6298 if (cfun_fpr_bit_p (i
- 16))
6300 rtx addr
= plus_constant (stack_pointer_rtx
,
6301 cfun_frame_layout
.frame_size
6302 + cfun_frame_layout
.f8_offset
6305 insn
= save_fpr (temp_reg
, offset
, i
);
6307 RTX_FRAME_RELATED_P (insn
) = 1;
6309 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
6310 gen_rtx_SET (VOIDmode
,
6311 gen_rtx_MEM (DFmode
, addr
),
6312 gen_rtx_REG (DFmode
, i
)),
6317 /* Set frame pointer, if needed. */
6319 if (frame_pointer_needed
)
6321 insn
= emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
);
6322 RTX_FRAME_RELATED_P (insn
) = 1;
6325 /* Set up got pointer, if needed. */
6327 if (flag_pic
&& regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
])
6329 rtx insns
= s390_load_got ();
6331 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
6333 annotate_constant_pool_refs (&PATTERN (insn
));
6335 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD
, NULL_RTX
,
6342 if (TARGET_TPF_PROFILING
)
6344 /* Generate a BAS instruction to serve as a function
6345 entry intercept to facilitate the use of tracing
6346 algorithms located at the branch target. */
6347 emit_insn (gen_prologue_tpf ());
6349 /* Emit a blockage here so that all code
6350 lies between the profiling mechanisms. */
6351 emit_insn (gen_blockage ());
6355 /* Expand the epilogue into a bunch of separate insns. */
6358 s390_emit_epilogue (bool sibcall
)
6360 rtx frame_pointer
, return_reg
;
6361 int area_bottom
, area_top
, offset
= 0;
6366 if (TARGET_TPF_PROFILING
)
6369 /* Generate a BAS instruction to serve as a function
6370 entry intercept to facilitate the use of tracing
6371 algorithms located at the branch target. */
6373 /* Emit a blockage here so that all code
6374 lies between the profiling mechanisms. */
6375 emit_insn (gen_blockage ());
6377 emit_insn (gen_epilogue_tpf ());
6380 /* Check whether to use frame or stack pointer for restore. */
6382 frame_pointer
= (frame_pointer_needed
6383 ? hard_frame_pointer_rtx
: stack_pointer_rtx
);
6385 s390_frame_area (&area_bottom
, &area_top
);
6387 /* Check whether we can access the register save area.
6388 If not, increment the frame pointer as required. */
6390 if (area_top
<= area_bottom
)
6392 /* Nothing to restore. */
6394 else if (DISP_IN_RANGE (cfun_frame_layout
.frame_size
+ area_bottom
)
6395 && DISP_IN_RANGE (cfun_frame_layout
.frame_size
+ area_top
- 1))
6397 /* Area is in range. */
6398 offset
= cfun_frame_layout
.frame_size
;
6402 rtx insn
, frame_off
;
6404 offset
= area_bottom
< 0 ? -area_bottom
: 0;
6405 frame_off
= GEN_INT (cfun_frame_layout
.frame_size
- offset
);
6407 if (DISP_IN_RANGE (INTVAL (frame_off
)))
6409 insn
= gen_rtx_SET (VOIDmode
, frame_pointer
,
6410 gen_rtx_PLUS (Pmode
, frame_pointer
, frame_off
));
6411 insn
= emit_insn (insn
);
6415 if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off
), 'K', "K"))
6416 frame_off
= force_const_mem (Pmode
, frame_off
);
6418 insn
= emit_insn (gen_add2_insn (frame_pointer
, frame_off
));
6419 annotate_constant_pool_refs (&PATTERN (insn
));
6423 /* Restore call saved fprs. */
6427 if (cfun_save_high_fprs_p
)
6429 next_offset
= cfun_frame_layout
.f8_offset
;
6430 for (i
= 24; i
< 32; i
++)
6432 if (cfun_fpr_bit_p (i
- 16))
6434 restore_fpr (frame_pointer
,
6435 offset
+ next_offset
, i
);
6444 next_offset
= cfun_frame_layout
.f4_offset
;
6445 for (i
= 18; i
< 20; i
++)
6447 if (cfun_fpr_bit_p (i
- 16))
6449 restore_fpr (frame_pointer
,
6450 offset
+ next_offset
, i
);
6453 else if (!TARGET_PACKED_STACK
)
6459 /* Return register. */
6461 return_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
6463 /* Restore call saved gprs. */
6465 if (cfun_frame_layout
.first_restore_gpr
!= -1)
6470 /* Check for global register and save them
6471 to stack location from where they get restored. */
6473 for (i
= cfun_frame_layout
.first_restore_gpr
;
6474 i
<= cfun_frame_layout
.last_restore_gpr
;
6477 /* These registers are special and need to be
6478 restored in any case. */
6479 if (i
== STACK_POINTER_REGNUM
6480 || i
== RETURN_REGNUM
6482 || (flag_pic
&& i
== (int)PIC_OFFSET_TABLE_REGNUM
))
6487 addr
= plus_constant (frame_pointer
,
6488 offset
+ cfun_frame_layout
.gprs_offset
6489 + (i
- cfun_frame_layout
.first_save_gpr
)
6491 addr
= gen_rtx_MEM (Pmode
, addr
);
6492 set_mem_alias_set (addr
, s390_sr_alias_set
);
6493 emit_move_insn (addr
, gen_rtx_REG (Pmode
, i
));
6499 /* Fetch return address from stack before load multiple,
6500 this will do good for scheduling. */
6502 if (cfun_frame_layout
.save_return_addr_p
6503 || (cfun_frame_layout
.first_restore_gpr
< BASE_REGNUM
6504 && cfun_frame_layout
.last_restore_gpr
> RETURN_REGNUM
))
6506 int return_regnum
= find_unused_clobbered_reg();
6509 return_reg
= gen_rtx_REG (Pmode
, return_regnum
);
6511 addr
= plus_constant (frame_pointer
,
6512 offset
+ cfun_frame_layout
.gprs_offset
6514 - cfun_frame_layout
.first_save_gpr
)
6516 addr
= gen_rtx_MEM (Pmode
, addr
);
6517 set_mem_alias_set (addr
, s390_sr_alias_set
);
6518 emit_move_insn (return_reg
, addr
);
6522 insn
= restore_gprs (frame_pointer
,
6523 offset
+ cfun_frame_layout
.gprs_offset
6524 + (cfun_frame_layout
.first_restore_gpr
6525 - cfun_frame_layout
.first_save_gpr
)
6527 cfun_frame_layout
.first_restore_gpr
,
6528 cfun_frame_layout
.last_restore_gpr
);
6535 /* Return to caller. */
6537 p
= rtvec_alloc (2);
6539 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
6540 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
, return_reg
);
6541 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
6546 /* Return the size in bytes of a function argument of
6547 type TYPE and/or mode MODE. At least one of TYPE or
6548 MODE must be specified. */
6551 s390_function_arg_size (enum machine_mode mode
, tree type
)
6554 return int_size_in_bytes (type
);
6556 /* No type info available for some library calls ... */
6557 if (mode
!= BLKmode
)
6558 return GET_MODE_SIZE (mode
);
6560 /* If we have neither type nor mode, abort */
6564 /* Return true if a function argument of type TYPE and mode MODE
6565 is to be passed in a floating-point register, if available. */
6568 s390_function_arg_float (enum machine_mode mode
, tree type
)
6570 int size
= s390_function_arg_size (mode
, type
);
6574 /* Soft-float changes the ABI: no floating-point registers are used. */
6575 if (TARGET_SOFT_FLOAT
)
6578 /* No type info available for some library calls ... */
6580 return mode
== SFmode
|| mode
== DFmode
;
6582 /* The ABI says that record types with a single member are treated
6583 just like that member would be. */
6584 while (TREE_CODE (type
) == RECORD_TYPE
)
6586 tree field
, single
= NULL_TREE
;
6588 for (field
= TYPE_FIELDS (type
); field
; field
= TREE_CHAIN (field
))
6590 if (TREE_CODE (field
) != FIELD_DECL
)
6593 if (single
== NULL_TREE
)
6594 single
= TREE_TYPE (field
);
6599 if (single
== NULL_TREE
)
6605 return TREE_CODE (type
) == REAL_TYPE
;
6608 /* Return true if a function argument of type TYPE and mode MODE
6609 is to be passed in an integer register, or a pair of integer
6610 registers, if available. */
6613 s390_function_arg_integer (enum machine_mode mode
, tree type
)
6615 int size
= s390_function_arg_size (mode
, type
);
6619 /* No type info available for some library calls ... */
6621 return GET_MODE_CLASS (mode
) == MODE_INT
6622 || (TARGET_SOFT_FLOAT
&& GET_MODE_CLASS (mode
) == MODE_FLOAT
);
6624 /* We accept small integral (and similar) types. */
6625 if (INTEGRAL_TYPE_P (type
)
6626 || POINTER_TYPE_P (type
)
6627 || TREE_CODE (type
) == OFFSET_TYPE
6628 || (TARGET_SOFT_FLOAT
&& TREE_CODE (type
) == REAL_TYPE
))
6631 /* We also accept structs of size 1, 2, 4, 8 that are not
6632 passed in floating-point registers. */
6633 if (AGGREGATE_TYPE_P (type
)
6634 && exact_log2 (size
) >= 0
6635 && !s390_function_arg_float (mode
, type
))
6641 /* Return 1 if a function argument of type TYPE and mode MODE
6642 is to be passed by reference. The ABI specifies that only
6643 structures of size 1, 2, 4, or 8 bytes are passed by value,
6644 all other structures (and complex numbers) are passed by
6648 s390_pass_by_reference (CUMULATIVE_ARGS
*ca ATTRIBUTE_UNUSED
,
6649 enum machine_mode mode
, tree type
,
6650 bool named ATTRIBUTE_UNUSED
)
6652 int size
= s390_function_arg_size (mode
, type
);
6658 if (AGGREGATE_TYPE_P (type
) && exact_log2 (size
) < 0)
6661 if (TREE_CODE (type
) == COMPLEX_TYPE
6662 || TREE_CODE (type
) == VECTOR_TYPE
)
6669 /* Update the data in CUM to advance over an argument of mode MODE and
6670 data type TYPE. (TYPE is null for libcalls where that information
6671 may not be available.). The boolean NAMED specifies whether the
6672 argument is a named argument (as opposed to an unnamed argument
6673 matching an ellipsis). */
6676 s390_function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
6677 tree type
, int named ATTRIBUTE_UNUSED
)
6679 if (s390_function_arg_float (mode
, type
))
6683 else if (s390_function_arg_integer (mode
, type
))
6685 int size
= s390_function_arg_size (mode
, type
);
6686 cum
->gprs
+= ((size
+ UNITS_PER_WORD
-1) / UNITS_PER_WORD
);
6692 /* Define where to put the arguments to a function.
6693 Value is zero to push the argument on the stack,
6694 or a hard register in which to store the argument.
6696 MODE is the argument's machine mode.
6697 TYPE is the data type of the argument (as a tree).
6698 This is null for libcalls where that information may
6700 CUM is a variable of type CUMULATIVE_ARGS which gives info about
6701 the preceding args and about the function being called.
6702 NAMED is nonzero if this argument is a named parameter
6703 (otherwise it is an extra parameter matching an ellipsis).
6705 On S/390, we use general purpose registers 2 through 6 to
6706 pass integer, pointer, and certain structure arguments, and
6707 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
6708 to pass floating point arguments. All remaining arguments
6709 are pushed to the stack. */
6712 s390_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
, tree type
,
6713 int named ATTRIBUTE_UNUSED
)
6715 if (s390_function_arg_float (mode
, type
))
6717 if (cum
->fprs
+ 1 > (TARGET_64BIT
? 4 : 2))
6720 return gen_rtx_REG (mode
, cum
->fprs
+ 16);
6722 else if (s390_function_arg_integer (mode
, type
))
6724 int size
= s390_function_arg_size (mode
, type
);
6725 int n_gprs
= (size
+ UNITS_PER_WORD
-1) / UNITS_PER_WORD
;
6727 if (cum
->gprs
+ n_gprs
> 5)
6730 return gen_rtx_REG (mode
, cum
->gprs
+ 2);
6733 /* After the real arguments, expand_call calls us once again
6734 with a void_type_node type. Whatever we return here is
6735 passed as operand 2 to the call expanders.
6737 We don't need this feature ... */
6738 else if (type
== void_type_node
)
6744 /* Return true if return values of type TYPE should be returned
6745 in a memory buffer whose address is passed by the caller as
6746 hidden first argument. */
6749 s390_return_in_memory (tree type
, tree fundecl ATTRIBUTE_UNUSED
)
6751 /* We accept small integral (and similar) types. */
6752 if (INTEGRAL_TYPE_P (type
)
6753 || POINTER_TYPE_P (type
)
6754 || TREE_CODE (type
) == OFFSET_TYPE
6755 || TREE_CODE (type
) == REAL_TYPE
)
6756 return int_size_in_bytes (type
) > 8;
6758 /* Aggregates and similar constructs are always returned
6760 if (AGGREGATE_TYPE_P (type
)
6761 || TREE_CODE (type
) == COMPLEX_TYPE
6762 || TREE_CODE (type
) == VECTOR_TYPE
)
6765 /* ??? We get called on all sorts of random stuff from
6766 aggregate_value_p. We can't abort, but it's not clear
6767 what's safe to return. Pretend it's a struct I guess. */
6771 /* Define where to return a (scalar) value of type TYPE.
6772 If TYPE is null, define where to return a (scalar)
6773 value of mode MODE from a libcall. */
6776 s390_function_value (tree type
, enum machine_mode mode
)
6780 int unsignedp
= TYPE_UNSIGNED (type
);
6781 mode
= promote_mode (type
, TYPE_MODE (type
), &unsignedp
, 1);
6784 gcc_assert (GET_MODE_CLASS (mode
) == MODE_INT
6785 || GET_MODE_CLASS (mode
) == MODE_FLOAT
);
6786 gcc_assert (GET_MODE_SIZE (mode
) <= 8);
6788 if (TARGET_HARD_FLOAT
&& GET_MODE_CLASS (mode
) == MODE_FLOAT
)
6789 return gen_rtx_REG (mode
, 16);
6791 return gen_rtx_REG (mode
, 2);
6795 /* Create and return the va_list datatype.
6797 On S/390, va_list is an array type equivalent to
6799 typedef struct __va_list_tag
6803 void *__overflow_arg_area;
6804 void *__reg_save_area;
6807 where __gpr and __fpr hold the number of general purpose
6808 or floating point arguments used up to now, respectively,
6809 __overflow_arg_area points to the stack location of the
6810 next argument passed on the stack, and __reg_save_area
6811 always points to the start of the register area in the
6812 call frame of the current function. The function prologue
6813 saves all registers used for argument passing into this
6814 area if the function uses variable arguments. */
6817 s390_build_builtin_va_list (void)
6819 tree f_gpr
, f_fpr
, f_ovf
, f_sav
, record
, type_decl
;
6821 record
= lang_hooks
.types
.make_type (RECORD_TYPE
);
6824 build_decl (TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
6826 f_gpr
= build_decl (FIELD_DECL
, get_identifier ("__gpr"),
6827 long_integer_type_node
);
6828 f_fpr
= build_decl (FIELD_DECL
, get_identifier ("__fpr"),
6829 long_integer_type_node
);
6830 f_ovf
= build_decl (FIELD_DECL
, get_identifier ("__overflow_arg_area"),
6832 f_sav
= build_decl (FIELD_DECL
, get_identifier ("__reg_save_area"),
6835 DECL_FIELD_CONTEXT (f_gpr
) = record
;
6836 DECL_FIELD_CONTEXT (f_fpr
) = record
;
6837 DECL_FIELD_CONTEXT (f_ovf
) = record
;
6838 DECL_FIELD_CONTEXT (f_sav
) = record
;
6840 TREE_CHAIN (record
) = type_decl
;
6841 TYPE_NAME (record
) = type_decl
;
6842 TYPE_FIELDS (record
) = f_gpr
;
6843 TREE_CHAIN (f_gpr
) = f_fpr
;
6844 TREE_CHAIN (f_fpr
) = f_ovf
;
6845 TREE_CHAIN (f_ovf
) = f_sav
;
6847 layout_type (record
);
6849 /* The correct type is an array type of one element. */
6850 return build_array_type (record
, build_index_type (size_zero_node
));
6853 /* Implement va_start by filling the va_list structure VALIST.
6854 STDARG_P is always true, and ignored.
6855 NEXTARG points to the first anonymous stack argument.
6857 The following global variables are used to initialize
6858 the va_list structure:
6860 current_function_args_info:
6861 holds number of gprs and fprs used for named arguments.
6862 current_function_arg_offset_rtx:
6863 holds the offset of the first anonymous stack argument
6864 (relative to the virtual arg pointer). */
6867 s390_va_start (tree valist
, rtx nextarg ATTRIBUTE_UNUSED
)
6869 HOST_WIDE_INT n_gpr
, n_fpr
;
6871 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
6872 tree gpr
, fpr
, ovf
, sav
, t
;
6874 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
6875 f_fpr
= TREE_CHAIN (f_gpr
);
6876 f_ovf
= TREE_CHAIN (f_fpr
);
6877 f_sav
= TREE_CHAIN (f_ovf
);
6879 valist
= build_va_arg_indirect_ref (valist
);
6880 gpr
= build (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
6881 fpr
= build (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
6882 ovf
= build (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
6883 sav
= build (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
6885 /* Count number of gp and fp argument registers used. */
6887 n_gpr
= current_function_args_info
.gprs
;
6888 n_fpr
= current_function_args_info
.fprs
;
6890 t
= build (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
,
6891 build_int_cst (NULL_TREE
, n_gpr
));
6892 TREE_SIDE_EFFECTS (t
) = 1;
6893 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6895 t
= build (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
,
6896 build_int_cst (NULL_TREE
, n_fpr
));
6897 TREE_SIDE_EFFECTS (t
) = 1;
6898 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6900 /* Find the overflow area. */
6901 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
6903 off
= INTVAL (current_function_arg_offset_rtx
);
6904 off
= off
< 0 ? 0 : off
;
6905 if (TARGET_DEBUG_ARG
)
6906 fprintf (stderr
, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
6907 (int)n_gpr
, (int)n_fpr
, off
);
6909 t
= build (PLUS_EXPR
, TREE_TYPE (ovf
), t
, build_int_cst (NULL_TREE
, off
));
6911 t
= build (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
6912 TREE_SIDE_EFFECTS (t
) = 1;
6913 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6915 /* Find the register save area. */
6916 t
= make_tree (TREE_TYPE (sav
), return_address_pointer_rtx
);
6917 t
= build (PLUS_EXPR
, TREE_TYPE (sav
), t
,
6918 build_int_cst (NULL_TREE
, -RETURN_REGNUM
* UNITS_PER_WORD
));
6920 t
= build (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
6921 TREE_SIDE_EFFECTS (t
) = 1;
6922 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6925 /* Implement va_arg by updating the va_list structure
6926 VALIST as required to retrieve an argument of type
6927 TYPE, and returning that argument.
6929 Generates code equivalent to:
6931 if (integral value) {
6932 if (size <= 4 && args.gpr < 5 ||
6933 size > 4 && args.gpr < 4 )
6934 ret = args.reg_save_area[args.gpr+8]
6936 ret = *args.overflow_arg_area++;
6937 } else if (float value) {
6939 ret = args.reg_save_area[args.fpr+64]
6941 ret = *args.overflow_arg_area++;
6942 } else if (aggregate value) {
6944 ret = *args.reg_save_area[args.gpr]
6946 ret = **args.overflow_arg_area++;
6950 s390_gimplify_va_arg (tree valist
, tree type
, tree
*pre_p
,
6951 tree
*post_p ATTRIBUTE_UNUSED
)
6953 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
6954 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
6955 int indirect_p
, size
, n_reg
, sav_ofs
, sav_scale
, max_reg
;
6956 tree lab_false
, lab_over
, addr
;
6958 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
6959 f_fpr
= TREE_CHAIN (f_gpr
);
6960 f_ovf
= TREE_CHAIN (f_fpr
);
6961 f_sav
= TREE_CHAIN (f_ovf
);
6963 valist
= build_va_arg_indirect_ref (valist
);
6964 gpr
= build (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
6965 fpr
= build (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
6966 ovf
= build (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
6967 sav
= build (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
6969 size
= int_size_in_bytes (type
);
6971 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
6973 if (TARGET_DEBUG_ARG
)
6975 fprintf (stderr
, "va_arg: aggregate type");
6979 /* Aggregates are passed by reference. */
6984 /* kernel stack layout on 31 bit: It is assumed here that no padding
6985 will be added by s390_frame_info because for va_args always an even
6986 number of gprs has to be saved r15-r2 = 14 regs. */
6987 sav_ofs
= 2 * UNITS_PER_WORD
;
6988 sav_scale
= UNITS_PER_WORD
;
6989 size
= UNITS_PER_WORD
;
6992 else if (s390_function_arg_float (TYPE_MODE (type
), type
))
6994 if (TARGET_DEBUG_ARG
)
6996 fprintf (stderr
, "va_arg: float type");
7000 /* FP args go in FP registers, if present. */
7004 sav_ofs
= 16 * UNITS_PER_WORD
;
7006 /* TARGET_64BIT has up to 4 parameter in fprs */
7007 max_reg
= TARGET_64BIT
? 3 : 1;
7011 if (TARGET_DEBUG_ARG
)
7013 fprintf (stderr
, "va_arg: other type");
7017 /* Otherwise into GP registers. */
7020 n_reg
= (size
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
7022 /* kernel stack layout on 31 bit: It is assumed here that no padding
7023 will be added by s390_frame_info because for va_args always an even
7024 number of gprs has to be saved r15-r2 = 14 regs. */
7025 sav_ofs
= 2 * UNITS_PER_WORD
;
7027 if (size
< UNITS_PER_WORD
)
7028 sav_ofs
+= UNITS_PER_WORD
- size
;
7030 sav_scale
= UNITS_PER_WORD
;
7037 /* Pull the value out of the saved registers ... */
7039 lab_false
= create_artificial_label ();
7040 lab_over
= create_artificial_label ();
7041 addr
= create_tmp_var (ptr_type_node
, "addr");
7042 DECL_POINTER_ALIAS_SET (addr
) = s390_sr_alias_set
;
7044 t
= fold_convert (TREE_TYPE (reg
), size_int (max_reg
));
7045 t
= build2 (GT_EXPR
, boolean_type_node
, reg
, t
);
7046 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
7047 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
7048 gimplify_and_add (t
, pre_p
);
7050 t
= build2 (PLUS_EXPR
, ptr_type_node
, sav
,
7051 fold_convert (ptr_type_node
, size_int (sav_ofs
)));
7052 u
= build2 (MULT_EXPR
, TREE_TYPE (reg
), reg
,
7053 fold_convert (TREE_TYPE (reg
), size_int (sav_scale
)));
7054 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
, fold_convert (ptr_type_node
, u
));
7056 t
= build2 (MODIFY_EXPR
, void_type_node
, addr
, t
);
7057 gimplify_and_add (t
, pre_p
);
7059 t
= build1 (GOTO_EXPR
, void_type_node
, lab_over
);
7060 gimplify_and_add (t
, pre_p
);
7062 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false
);
7063 append_to_statement_list (t
, pre_p
);
7066 /* ... Otherwise out of the overflow area. */
7069 if (size
< UNITS_PER_WORD
)
7070 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
,
7071 fold_convert (ptr_type_node
, size_int (UNITS_PER_WORD
- size
)));
7073 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
7075 u
= build2 (MODIFY_EXPR
, void_type_node
, addr
, t
);
7076 gimplify_and_add (u
, pre_p
);
7078 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
,
7079 fold_convert (ptr_type_node
, size_int (size
)));
7080 t
= build2 (MODIFY_EXPR
, ptr_type_node
, ovf
, t
);
7081 gimplify_and_add (t
, pre_p
);
7083 t
= build1 (LABEL_EXPR
, void_type_node
, lab_over
);
7084 append_to_statement_list (t
, pre_p
);
7087 /* Increment register save count. */
7089 u
= build2 (PREINCREMENT_EXPR
, TREE_TYPE (reg
), reg
,
7090 fold_convert (TREE_TYPE (reg
), size_int (n_reg
)));
7091 gimplify_and_add (u
, pre_p
);
7095 t
= build_pointer_type (build_pointer_type (type
));
7096 addr
= fold_convert (t
, addr
);
7097 addr
= build_va_arg_indirect_ref (addr
);
7101 t
= build_pointer_type (type
);
7102 addr
= fold_convert (t
, addr
);
7105 return build_va_arg_indirect_ref (addr
);
7113 S390_BUILTIN_THREAD_POINTER
,
7114 S390_BUILTIN_SET_THREAD_POINTER
,
7119 static unsigned int const code_for_builtin_64
[S390_BUILTIN_max
] = {
7124 static unsigned int const code_for_builtin_31
[S390_BUILTIN_max
] = {
7130 s390_init_builtins (void)
7134 ftype
= build_function_type (ptr_type_node
, void_list_node
);
7135 lang_hooks
.builtin_function ("__builtin_thread_pointer", ftype
,
7136 S390_BUILTIN_THREAD_POINTER
, BUILT_IN_MD
,
7139 ftype
= build_function_type_list (void_type_node
, ptr_type_node
, NULL_TREE
);
7140 lang_hooks
.builtin_function ("__builtin_set_thread_pointer", ftype
,
7141 S390_BUILTIN_SET_THREAD_POINTER
, BUILT_IN_MD
,
7145 /* Expand an expression EXP that calls a built-in function,
7146 with result going to TARGET if that's convenient
7147 (and in mode MODE if that's convenient).
7148 SUBTARGET may be used as the target for computing one of EXP's operands.
7149 IGNORE is nonzero if the value is to be ignored. */
7152 s390_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
7153 enum machine_mode mode ATTRIBUTE_UNUSED
,
7154 int ignore ATTRIBUTE_UNUSED
)
7158 unsigned int const *code_for_builtin
=
7159 TARGET_64BIT
? code_for_builtin_64
: code_for_builtin_31
;
7161 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
7162 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7163 tree arglist
= TREE_OPERAND (exp
, 1);
7164 enum insn_code icode
;
7165 rtx op
[MAX_ARGS
], pat
;
7169 if (fcode
>= S390_BUILTIN_max
)
7170 internal_error ("bad builtin fcode");
7171 icode
= code_for_builtin
[fcode
];
7173 internal_error ("bad builtin fcode");
7175 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
7177 for (arglist
= TREE_OPERAND (exp
, 1), arity
= 0;
7179 arglist
= TREE_CHAIN (arglist
), arity
++)
7181 const struct insn_operand_data
*insn_op
;
7183 tree arg
= TREE_VALUE (arglist
);
7184 if (arg
== error_mark_node
)
7186 if (arity
> MAX_ARGS
)
7189 insn_op
= &insn_data
[icode
].operand
[arity
+ nonvoid
];
7191 op
[arity
] = expand_expr (arg
, NULL_RTX
, insn_op
->mode
, 0);
7193 if (!(*insn_op
->predicate
) (op
[arity
], insn_op
->mode
))
7194 op
[arity
] = copy_to_mode_reg (insn_op
->mode
, op
[arity
]);
7199 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7201 || GET_MODE (target
) != tmode
7202 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7203 target
= gen_reg_rtx (tmode
);
7209 pat
= GEN_FCN (icode
) (target
);
7213 pat
= GEN_FCN (icode
) (target
, op
[0]);
7215 pat
= GEN_FCN (icode
) (op
[0]);
7218 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
7234 /* Output assembly code for the trampoline template to
7237 On S/390, we use gpr 1 internally in the trampoline code;
7238 gpr 0 is used to hold the static chain. */
7241 s390_trampoline_template (FILE *file
)
7244 op
[0] = gen_rtx_REG (Pmode
, 0);
7245 op
[1] = gen_rtx_REG (Pmode
, 1);
7249 output_asm_insn ("basr\t%1,0", op
);
7250 output_asm_insn ("lmg\t%0,%1,14(%1)", op
);
7251 output_asm_insn ("br\t%1", op
);
7252 ASM_OUTPUT_SKIP (file
, (HOST_WIDE_INT
)(TRAMPOLINE_SIZE
- 10));
7256 output_asm_insn ("basr\t%1,0", op
);
7257 output_asm_insn ("lm\t%0,%1,6(%1)", op
);
7258 output_asm_insn ("br\t%1", op
);
7259 ASM_OUTPUT_SKIP (file
, (HOST_WIDE_INT
)(TRAMPOLINE_SIZE
- 8));
7263 /* Emit RTL insns to initialize the variable parts of a trampoline.
7264 FNADDR is an RTX for the address of the function's pure code.
7265 CXT is an RTX for the static chain value for the function. */
7268 s390_initialize_trampoline (rtx addr
, rtx fnaddr
, rtx cxt
)
7270 emit_move_insn (gen_rtx_MEM (Pmode
,
7271 memory_address (Pmode
,
7272 plus_constant (addr
, (TARGET_64BIT
? 16 : 8)))), cxt
);
7273 emit_move_insn (gen_rtx_MEM (Pmode
,
7274 memory_address (Pmode
,
7275 plus_constant (addr
, (TARGET_64BIT
? 24 : 12)))), fnaddr
);
7278 /* Return rtx for 64-bit constant formed from the 32-bit subwords
7279 LOW and HIGH, independent of the host word size. */
7282 s390_gen_rtx_const_DI (int high
, int low
)
7284 #if HOST_BITS_PER_WIDE_INT >= 64
7286 val
= (HOST_WIDE_INT
)high
;
7288 val
|= (HOST_WIDE_INT
)low
;
7290 return GEN_INT (val
);
7292 #if HOST_BITS_PER_WIDE_INT >= 32
7293 return immed_double_const ((HOST_WIDE_INT
)low
, (HOST_WIDE_INT
)high
, DImode
);
7300 /* Output assembler code to FILE to increment profiler label # LABELNO
7301 for profiling a function entry. */
7304 s390_function_profiler (FILE *file
, int labelno
)
7309 ASM_GENERATE_INTERNAL_LABEL (label
, "LP", labelno
);
7311 fprintf (file
, "# function profiler \n");
7313 op
[0] = gen_rtx_REG (Pmode
, RETURN_REGNUM
);
7314 op
[1] = gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
7315 op
[1] = gen_rtx_MEM (Pmode
, plus_constant (op
[1], UNITS_PER_WORD
));
7317 op
[2] = gen_rtx_REG (Pmode
, 1);
7318 op
[3] = gen_rtx_SYMBOL_REF (Pmode
, label
);
7319 SYMBOL_REF_FLAGS (op
[3]) = SYMBOL_FLAG_LOCAL
;
7321 op
[4] = gen_rtx_SYMBOL_REF (Pmode
, "_mcount");
7324 op
[4] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[4]), UNSPEC_PLT
);
7325 op
[4] = gen_rtx_CONST (Pmode
, op
[4]);
7330 output_asm_insn ("stg\t%0,%1", op
);
7331 output_asm_insn ("larl\t%2,%3", op
);
7332 output_asm_insn ("brasl\t%0,%4", op
);
7333 output_asm_insn ("lg\t%0,%1", op
);
7337 op
[6] = gen_label_rtx ();
7339 output_asm_insn ("st\t%0,%1", op
);
7340 output_asm_insn ("bras\t%2,%l6", op
);
7341 output_asm_insn (".long\t%4", op
);
7342 output_asm_insn (".long\t%3", op
);
7343 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
7344 output_asm_insn ("l\t%0,0(%2)", op
);
7345 output_asm_insn ("l\t%2,4(%2)", op
);
7346 output_asm_insn ("basr\t%0,%0", op
);
7347 output_asm_insn ("l\t%0,%1", op
);
7351 op
[5] = gen_label_rtx ();
7352 op
[6] = gen_label_rtx ();
7354 output_asm_insn ("st\t%0,%1", op
);
7355 output_asm_insn ("bras\t%2,%l6", op
);
7356 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[5]));
7357 output_asm_insn (".long\t%4-%l5", op
);
7358 output_asm_insn (".long\t%3-%l5", op
);
7359 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
7360 output_asm_insn ("lr\t%0,%2", op
);
7361 output_asm_insn ("a\t%0,0(%2)", op
);
7362 output_asm_insn ("a\t%2,4(%2)", op
);
7363 output_asm_insn ("basr\t%0,%0", op
);
7364 output_asm_insn ("l\t%0,%1", op
);
7368 /* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
7369 into its SYMBOL_REF_FLAGS. */
7372 s390_encode_section_info (tree decl
, rtx rtl
, int first
)
7374 default_encode_section_info (decl
, rtl
, first
);
7376 /* If a variable has a forced alignment to < 2 bytes, mark it with
7377 SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL operand. */
7378 if (TREE_CODE (decl
) == VAR_DECL
7379 && DECL_USER_ALIGN (decl
) && DECL_ALIGN (decl
) < 16)
7380 SYMBOL_REF_FLAGS (XEXP (rtl
, 0)) |= SYMBOL_FLAG_ALIGN1
;
7383 /* Output thunk to FILE that implements a C++ virtual function call (with
7384 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
7385 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
7386 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
7387 relative to the resulting this pointer. */
7390 s390_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
7391 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
7397 /* Operand 0 is the target function. */
7398 op
[0] = XEXP (DECL_RTL (function
), 0);
7399 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (op
[0]))
7402 op
[0] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[0]),
7403 TARGET_64BIT
? UNSPEC_PLT
: UNSPEC_GOT
);
7404 op
[0] = gen_rtx_CONST (Pmode
, op
[0]);
7407 /* Operand 1 is the 'this' pointer. */
7408 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
7409 op
[1] = gen_rtx_REG (Pmode
, 3);
7411 op
[1] = gen_rtx_REG (Pmode
, 2);
7413 /* Operand 2 is the delta. */
7414 op
[2] = GEN_INT (delta
);
7416 /* Operand 3 is the vcall_offset. */
7417 op
[3] = GEN_INT (vcall_offset
);
7419 /* Operand 4 is the temporary register. */
7420 op
[4] = gen_rtx_REG (Pmode
, 1);
7422 /* Operands 5 to 8 can be used as labels. */
7428 /* Operand 9 can be used for temporary register. */
7431 /* Generate code. */
7434 /* Setup literal pool pointer if required. */
7435 if ((!DISP_IN_RANGE (delta
)
7436 && !CONST_OK_FOR_CONSTRAINT_P (delta
, 'K', "K"))
7437 || (!DISP_IN_RANGE (vcall_offset
)
7438 && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'K', "K")))
7440 op
[5] = gen_label_rtx ();
7441 output_asm_insn ("larl\t%4,%5", op
);
7444 /* Add DELTA to this pointer. */
7447 if (CONST_OK_FOR_CONSTRAINT_P (delta
, 'J', "J"))
7448 output_asm_insn ("la\t%1,%2(%1)", op
);
7449 else if (DISP_IN_RANGE (delta
))
7450 output_asm_insn ("lay\t%1,%2(%1)", op
);
7451 else if (CONST_OK_FOR_CONSTRAINT_P (delta
, 'K', "K"))
7452 output_asm_insn ("aghi\t%1,%2", op
);
7455 op
[6] = gen_label_rtx ();
7456 output_asm_insn ("agf\t%1,%6-%5(%4)", op
);
7460 /* Perform vcall adjustment. */
7463 if (DISP_IN_RANGE (vcall_offset
))
7465 output_asm_insn ("lg\t%4,0(%1)", op
);
7466 output_asm_insn ("ag\t%1,%3(%4)", op
);
7468 else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'K', "K"))
7470 output_asm_insn ("lghi\t%4,%3", op
);
7471 output_asm_insn ("ag\t%4,0(%1)", op
);
7472 output_asm_insn ("ag\t%1,0(%4)", op
);
7476 op
[7] = gen_label_rtx ();
7477 output_asm_insn ("llgf\t%4,%7-%5(%4)", op
);
7478 output_asm_insn ("ag\t%4,0(%1)", op
);
7479 output_asm_insn ("ag\t%1,0(%4)", op
);
7483 /* Jump to target. */
7484 output_asm_insn ("jg\t%0", op
);
7486 /* Output literal pool if required. */
7489 output_asm_insn (".align\t4", op
);
7490 targetm
.asm_out
.internal_label (file
, "L",
7491 CODE_LABEL_NUMBER (op
[5]));
7495 targetm
.asm_out
.internal_label (file
, "L",
7496 CODE_LABEL_NUMBER (op
[6]));
7497 output_asm_insn (".long\t%2", op
);
7501 targetm
.asm_out
.internal_label (file
, "L",
7502 CODE_LABEL_NUMBER (op
[7]));
7503 output_asm_insn (".long\t%3", op
);
7508 /* Setup base pointer if required. */
7510 || (!DISP_IN_RANGE (delta
)
7511 && !CONST_OK_FOR_CONSTRAINT_P (delta
, 'K', "K"))
7512 || (!DISP_IN_RANGE (delta
)
7513 && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'K', "K")))
7515 op
[5] = gen_label_rtx ();
7516 output_asm_insn ("basr\t%4,0", op
);
7517 targetm
.asm_out
.internal_label (file
, "L",
7518 CODE_LABEL_NUMBER (op
[5]));
7521 /* Add DELTA to this pointer. */
7524 if (CONST_OK_FOR_CONSTRAINT_P (delta
, 'J', "J"))
7525 output_asm_insn ("la\t%1,%2(%1)", op
);
7526 else if (DISP_IN_RANGE (delta
))
7527 output_asm_insn ("lay\t%1,%2(%1)", op
);
7528 else if (CONST_OK_FOR_CONSTRAINT_P (delta
, 'K', "K"))
7529 output_asm_insn ("ahi\t%1,%2", op
);
7532 op
[6] = gen_label_rtx ();
7533 output_asm_insn ("a\t%1,%6-%5(%4)", op
);
7537 /* Perform vcall adjustment. */
7540 if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'J', "J"))
7542 output_asm_insn ("lg\t%4,0(%1)", op
);
7543 output_asm_insn ("a\t%1,%3(%4)", op
);
7545 else if (DISP_IN_RANGE (vcall_offset
))
7547 output_asm_insn ("lg\t%4,0(%1)", op
);
7548 output_asm_insn ("ay\t%1,%3(%4)", op
);
7550 else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'K', "K"))
7552 output_asm_insn ("lhi\t%4,%3", op
);
7553 output_asm_insn ("a\t%4,0(%1)", op
);
7554 output_asm_insn ("a\t%1,0(%4)", op
);
7558 op
[7] = gen_label_rtx ();
7559 output_asm_insn ("l\t%4,%7-%5(%4)", op
);
7560 output_asm_insn ("a\t%4,0(%1)", op
);
7561 output_asm_insn ("a\t%1,0(%4)", op
);
7564 /* We had to clobber the base pointer register.
7565 Re-setup the base pointer (with a different base). */
7566 op
[5] = gen_label_rtx ();
7567 output_asm_insn ("basr\t%4,0", op
);
7568 targetm
.asm_out
.internal_label (file
, "L",
7569 CODE_LABEL_NUMBER (op
[5]));
7572 /* Jump to target. */
7573 op
[8] = gen_label_rtx ();
7576 output_asm_insn ("l\t%4,%8-%5(%4)", op
);
7578 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
7579 /* We cannot call through .plt, since .plt requires %r12 loaded. */
7580 else if (flag_pic
== 1)
7582 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
7583 output_asm_insn ("l\t%4,%0(%4)", op
);
7585 else if (flag_pic
== 2)
7587 op
[9] = gen_rtx_REG (Pmode
, 0);
7588 output_asm_insn ("l\t%9,%8-4-%5(%4)", op
);
7589 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
7590 output_asm_insn ("ar\t%4,%9", op
);
7591 output_asm_insn ("l\t%4,0(%4)", op
);
7594 output_asm_insn ("br\t%4", op
);
7596 /* Output literal pool. */
7597 output_asm_insn (".align\t4", op
);
7599 if (nonlocal
&& flag_pic
== 2)
7600 output_asm_insn (".long\t%0", op
);
7603 op
[0] = gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
7604 SYMBOL_REF_FLAGS (op
[0]) = SYMBOL_FLAG_LOCAL
;
7607 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[8]));
7609 output_asm_insn (".long\t%0", op
);
7611 output_asm_insn (".long\t%0-%5", op
);
7615 targetm
.asm_out
.internal_label (file
, "L",
7616 CODE_LABEL_NUMBER (op
[6]));
7617 output_asm_insn (".long\t%2", op
);
7621 targetm
.asm_out
.internal_label (file
, "L",
7622 CODE_LABEL_NUMBER (op
[7]));
7623 output_asm_insn (".long\t%3", op
);
7629 s390_valid_pointer_mode (enum machine_mode mode
)
7631 return (mode
== SImode
|| (TARGET_64BIT
&& mode
== DImode
));
7634 /* Checks whether the given ARGUMENT_LIST would use a caller
7635 saved register. This is used to decide whether sibling call
7636 optimization could be performed on the respective function
7640 s390_call_saved_register_used (tree argument_list
)
7642 CUMULATIVE_ARGS cum
;
7644 enum machine_mode mode
;
7649 INIT_CUMULATIVE_ARGS (cum
, NULL
, NULL
, 0, 0);
7651 while (argument_list
)
7653 parameter
= TREE_VALUE (argument_list
);
7654 argument_list
= TREE_CHAIN (argument_list
);
7656 gcc_assert (parameter
);
7658 /* For an undeclared variable passed as parameter we will get
7659 an ERROR_MARK node here. */
7660 if (TREE_CODE (parameter
) == ERROR_MARK
)
7663 type
= TREE_TYPE (parameter
);
7666 mode
= TYPE_MODE (type
);
7669 if (pass_by_reference (&cum
, mode
, type
, true))
7672 type
= build_pointer_type (type
);
7675 parm_rtx
= s390_function_arg (&cum
, mode
, type
, 0);
7677 s390_function_arg_advance (&cum
, mode
, type
, 0);
7679 if (parm_rtx
&& REG_P (parm_rtx
))
7682 reg
< HARD_REGNO_NREGS (REGNO (parm_rtx
), GET_MODE (parm_rtx
));
7684 if (! call_used_regs
[reg
+ REGNO (parm_rtx
)])
7691 /* Return true if the given call expression can be
7692 turned into a sibling call.
7693 DECL holds the declaration of the function to be called whereas
7694 EXP is the call expression itself. */
7697 s390_function_ok_for_sibcall (tree decl
, tree exp
)
7699 /* The TPF epilogue uses register 1. */
7700 if (TARGET_TPF_PROFILING
)
7703 /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
7704 which would have to be restored before the sibcall. */
7705 if (!TARGET_64BIT
&& flag_pic
&& decl
&& TREE_PUBLIC (decl
))
7708 /* Register 6 on s390 is available as an argument register but unfortunately
7709 "caller saved". This makes functions needing this register for arguments
7710 not suitable for sibcalls. */
7711 if (TREE_OPERAND (exp
, 1)
7712 && s390_call_saved_register_used (TREE_OPERAND (exp
, 1)))
7718 /* Return the fixed registers used for condition codes. */
7721 s390_fixed_condition_code_regs (unsigned int *p1
, unsigned int *p2
)
7724 *p2
= INVALID_REGNUM
;
7729 /* If two condition code modes are compatible, return a condition code
7730 mode which is compatible with both. Otherwise, return
7733 static enum machine_mode
7734 s390_cc_modes_compatible (enum machine_mode m1
, enum machine_mode m2
)
7742 if (m2
== CCUmode
|| m2
== CCTmode
7743 || m2
== CCSmode
|| m2
== CCSRmode
|| m2
== CCURmode
)
7763 /* This function is used by the call expanders of the machine description.
7764 It emits the call insn itself together with the necessary operations
7765 to adjust the target address and returns the emitted insn.
7766 ADDR_LOCATION is the target address rtx
7767 TLS_CALL the location of the thread-local symbol
7768 RESULT_REG the register where the result of the call should be stored
7769 RETADDR_REG the register where the return address should be stored
7770 If this parameter is NULL_RTX the call is considered
7771 to be a sibling call. */
7774 s390_emit_call (rtx addr_location
, rtx tls_call
, rtx result_reg
,
7777 bool plt_call
= false;
7783 /* Direct function calls need special treatment. */
7784 if (GET_CODE (addr_location
) == SYMBOL_REF
)
7786 /* When calling a global routine in PIC mode, we must
7787 replace the symbol itself with the PLT stub. */
7788 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (addr_location
))
7790 addr_location
= gen_rtx_UNSPEC (Pmode
,
7791 gen_rtvec (1, addr_location
),
7793 addr_location
= gen_rtx_CONST (Pmode
, addr_location
);
7797 /* Unless we can use the bras(l) insn, force the
7798 routine address into a register. */
7799 if (!TARGET_SMALL_EXEC
&& !TARGET_CPU_ZARCH
)
7802 addr_location
= legitimize_pic_address (addr_location
, 0);
7804 addr_location
= force_reg (Pmode
, addr_location
);
7808 /* If it is already an indirect call or the code above moved the
7809 SYMBOL_REF to somewhere else make sure the address can be found in
7811 if (retaddr_reg
== NULL_RTX
7812 && GET_CODE (addr_location
) != SYMBOL_REF
7815 emit_move_insn (gen_rtx_REG (Pmode
, SIBCALL_REGNUM
), addr_location
);
7816 addr_location
= gen_rtx_REG (Pmode
, SIBCALL_REGNUM
);
7819 addr_location
= gen_rtx_MEM (QImode
, addr_location
);
7820 call
= gen_rtx_CALL (VOIDmode
, addr_location
, const0_rtx
);
7822 if (result_reg
!= NULL_RTX
)
7823 call
= gen_rtx_SET (VOIDmode
, result_reg
, call
);
7825 if (retaddr_reg
!= NULL_RTX
)
7827 clobber
= gen_rtx_CLOBBER (VOIDmode
, retaddr_reg
);
7829 if (tls_call
!= NULL_RTX
)
7830 vec
= gen_rtvec (3, call
, clobber
,
7831 gen_rtx_USE (VOIDmode
, tls_call
));
7833 vec
= gen_rtvec (2, call
, clobber
);
7835 call
= gen_rtx_PARALLEL (VOIDmode
, vec
);
7838 insn
= emit_call_insn (call
);
7840 /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
7841 if ((!TARGET_64BIT
&& plt_call
) || tls_call
!= NULL_RTX
)
7843 /* s390_function_ok_for_sibcall should
7844 have denied sibcalls in this case. */
7845 gcc_assert (retaddr_reg
!= NULL_RTX
);
7847 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), pic_offset_table_rtx
);
7852 /* Implement CONDITIONAL_REGISTER_USAGE. */
7855 s390_conditional_register_usage (void)
7861 fixed_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
7862 call_used_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
7864 if (TARGET_CPU_ZARCH
)
7866 fixed_regs
[RETURN_REGNUM
] = 0;
7867 call_used_regs
[RETURN_REGNUM
] = 0;
7871 for (i
= 24; i
< 32; i
++)
7872 call_used_regs
[i
] = call_really_used_regs
[i
] = 0;
7876 for (i
= 18; i
< 20; i
++)
7877 call_used_regs
[i
] = call_really_used_regs
[i
] = 0;
7880 if (TARGET_SOFT_FLOAT
)
7882 for (i
= 16; i
< 32; i
++)
7883 call_used_regs
[i
] = fixed_regs
[i
] = 1;
7887 /* Corresponding function to eh_return expander. */
7889 static GTY(()) rtx s390_tpf_eh_return_symbol
;
7891 s390_emit_tpf_eh_return (rtx target
)
7895 if (!s390_tpf_eh_return_symbol
)
7896 s390_tpf_eh_return_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "__tpf_eh_return");
7898 reg
= gen_rtx_REG (Pmode
, 2);
7900 emit_move_insn (reg
, target
);
7901 insn
= s390_emit_call (s390_tpf_eh_return_symbol
, NULL_RTX
, reg
,
7902 gen_rtx_REG (Pmode
, RETURN_REGNUM
));
7903 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), reg
);
7905 emit_move_insn (EH_RETURN_HANDLER_RTX
, reg
);
7908 /* Rework the prologue/epilogue to avoid saving/restoring
7909 registers unnecessarily. */
7912 s390_optimize_prologue (void)
7914 rtx insn
, new_insn
, next_insn
;
7916 /* Do a final recompute of the frame-related data. */
7918 s390_update_frame_layout ();
7920 /* If all special registers are in fact used, there's nothing we
7921 can do, so no point in walking the insn list. */
7923 if (cfun_frame_layout
.first_save_gpr
<= BASE_REGNUM
7924 && cfun_frame_layout
.last_save_gpr
>= BASE_REGNUM
7925 && (TARGET_CPU_ZARCH
7926 || (cfun_frame_layout
.first_save_gpr
<= RETURN_REGNUM
7927 && cfun_frame_layout
.last_save_gpr
>= RETURN_REGNUM
)))
7930 /* Search for prologue/epilogue insns and replace them. */
7932 for (insn
= get_insns (); insn
; insn
= next_insn
)
7934 int first
, last
, off
;
7935 rtx set
, base
, offset
;
7937 next_insn
= NEXT_INSN (insn
);
7939 if (GET_CODE (insn
) != INSN
)
7942 if (GET_CODE (PATTERN (insn
)) == PARALLEL
7943 && store_multiple_operation (PATTERN (insn
), VOIDmode
))
7945 set
= XVECEXP (PATTERN (insn
), 0, 0);
7946 first
= REGNO (SET_SRC (set
));
7947 last
= first
+ XVECLEN (PATTERN (insn
), 0) - 1;
7948 offset
= const0_rtx
;
7949 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
7950 off
= INTVAL (offset
);
7952 if (GET_CODE (base
) != REG
|| off
< 0)
7954 if (REGNO (base
) != STACK_POINTER_REGNUM
7955 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
7957 if (first
> BASE_REGNUM
|| last
< BASE_REGNUM
)
7960 if (cfun_frame_layout
.first_save_gpr
!= -1)
7962 new_insn
= save_gprs (base
,
7963 off
+ (cfun_frame_layout
.first_save_gpr
7964 - first
) * UNITS_PER_WORD
,
7965 cfun_frame_layout
.first_save_gpr
,
7966 cfun_frame_layout
.last_save_gpr
);
7967 new_insn
= emit_insn_before (new_insn
, insn
);
7968 INSN_ADDRESSES_NEW (new_insn
, -1);
7975 if (GET_CODE (PATTERN (insn
)) == SET
7976 && GET_CODE (SET_SRC (PATTERN (insn
))) == REG
7977 && (REGNO (SET_SRC (PATTERN (insn
))) == BASE_REGNUM
7978 || (!TARGET_CPU_ZARCH
7979 && REGNO (SET_SRC (PATTERN (insn
))) == RETURN_REGNUM
))
7980 && GET_CODE (SET_DEST (PATTERN (insn
))) == MEM
)
7982 set
= PATTERN (insn
);
7983 first
= REGNO (SET_SRC (set
));
7984 offset
= const0_rtx
;
7985 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
7986 off
= INTVAL (offset
);
7988 if (GET_CODE (base
) != REG
|| off
< 0)
7990 if (REGNO (base
) != STACK_POINTER_REGNUM
7991 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
7993 if (cfun_frame_layout
.first_save_gpr
!= -1)
7995 new_insn
= save_gprs (base
,
7996 off
+ (cfun_frame_layout
.first_save_gpr
7997 - first
) * UNITS_PER_WORD
,
7998 cfun_frame_layout
.first_save_gpr
,
7999 cfun_frame_layout
.last_save_gpr
);
8000 new_insn
= emit_insn_before (new_insn
, insn
);
8001 INSN_ADDRESSES_NEW (new_insn
, -1);
8008 if (GET_CODE (PATTERN (insn
)) == PARALLEL
8009 && load_multiple_operation (PATTERN (insn
), VOIDmode
))
8011 set
= XVECEXP (PATTERN (insn
), 0, 0);
8012 first
= REGNO (SET_DEST (set
));
8013 last
= first
+ XVECLEN (PATTERN (insn
), 0) - 1;
8014 offset
= const0_rtx
;
8015 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
8016 off
= INTVAL (offset
);
8018 if (GET_CODE (base
) != REG
|| off
< 0)
8020 if (REGNO (base
) != STACK_POINTER_REGNUM
8021 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
8023 if (first
> BASE_REGNUM
|| last
< BASE_REGNUM
)
8026 if (cfun_frame_layout
.first_restore_gpr
!= -1)
8028 new_insn
= restore_gprs (base
,
8029 off
+ (cfun_frame_layout
.first_restore_gpr
8030 - first
) * UNITS_PER_WORD
,
8031 cfun_frame_layout
.first_restore_gpr
,
8032 cfun_frame_layout
.last_restore_gpr
);
8033 new_insn
= emit_insn_before (new_insn
, insn
);
8034 INSN_ADDRESSES_NEW (new_insn
, -1);
8041 if (GET_CODE (PATTERN (insn
)) == SET
8042 && GET_CODE (SET_DEST (PATTERN (insn
))) == REG
8043 && (REGNO (SET_DEST (PATTERN (insn
))) == BASE_REGNUM
8044 || (!TARGET_CPU_ZARCH
8045 && REGNO (SET_DEST (PATTERN (insn
))) == RETURN_REGNUM
))
8046 && GET_CODE (SET_SRC (PATTERN (insn
))) == MEM
)
8048 set
= PATTERN (insn
);
8049 first
= REGNO (SET_DEST (set
));
8050 offset
= const0_rtx
;
8051 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
8052 off
= INTVAL (offset
);
8054 if (GET_CODE (base
) != REG
|| off
< 0)
8056 if (REGNO (base
) != STACK_POINTER_REGNUM
8057 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
8059 if (cfun_frame_layout
.first_restore_gpr
!= -1)
8061 new_insn
= restore_gprs (base
,
8062 off
+ (cfun_frame_layout
.first_restore_gpr
8063 - first
) * UNITS_PER_WORD
,
8064 cfun_frame_layout
.first_restore_gpr
,
8065 cfun_frame_layout
.last_restore_gpr
);
8066 new_insn
= emit_insn_before (new_insn
, insn
);
8067 INSN_ADDRESSES_NEW (new_insn
, -1);
8076 /* Perform machine-dependent processing. */
8081 bool pool_overflow
= false;
8083 /* Make sure all splits have been performed; splits after
8084 machine_dependent_reorg might confuse insn length counts. */
8085 split_all_insns_noflow ();
8088 /* Install the main literal pool and the associated base
8089 register load insns.
8091 In addition, there are two problematic situations we need
8094 - the literal pool might be > 4096 bytes in size, so that
8095 some of its elements cannot be directly accessed
8097 - a branch target might be > 64K away from the branch, so that
8098 it is not possible to use a PC-relative instruction.
8100 To fix those, we split the single literal pool into multiple
8101 pool chunks, reloading the pool base register at various
8102 points throughout the function to ensure it always points to
8103 the pool chunk the following code expects, and / or replace
8104 PC-relative branches by absolute branches.
8106 However, the two problems are interdependent: splitting the
8107 literal pool can move a branch further away from its target,
8108 causing the 64K limit to overflow, and on the other hand,
8109 replacing a PC-relative branch by an absolute branch means
8110 we need to put the branch target address into the literal
8111 pool, possibly causing it to overflow.
8113 So, we loop trying to fix up both problems until we manage
8114 to satisfy both conditions at the same time. Note that the
8115 loop is guaranteed to terminate as every pass of the loop
8116 strictly decreases the total number of PC-relative branches
8117 in the function. (This is not completely true as there
8118 might be branch-over-pool insns introduced by chunkify_start.
8119 Those never need to be split however.) */
8123 struct constant_pool
*pool
= NULL
;
8125 /* Collect the literal pool. */
8128 pool
= s390_mainpool_start ();
8130 pool_overflow
= true;
8133 /* If literal pool overflowed, start to chunkify it. */
8135 pool
= s390_chunkify_start ();
8137 /* Split out-of-range branches. If this has created new
8138 literal pool entries, cancel current chunk list and
8139 recompute it. zSeries machines have large branch
8140 instructions, so we never need to split a branch. */
8141 if (!TARGET_CPU_ZARCH
&& s390_split_branches ())
8144 s390_chunkify_cancel (pool
);
8146 s390_mainpool_cancel (pool
);
8151 /* If we made it up to here, both conditions are satisfied.
8152 Finish up literal pool related changes. */
8154 s390_chunkify_finish (pool
);
8156 s390_mainpool_finish (pool
);
8158 /* We're done splitting branches. */
8159 cfun
->machine
->split_branches_pending_p
= false;
8163 s390_optimize_prologue ();
8167 /* Initialize GCC target structure. */
8169 #undef TARGET_ASM_ALIGNED_HI_OP
8170 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
8171 #undef TARGET_ASM_ALIGNED_DI_OP
8172 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
8173 #undef TARGET_ASM_INTEGER
8174 #define TARGET_ASM_INTEGER s390_assemble_integer
8176 #undef TARGET_ASM_OPEN_PAREN
8177 #define TARGET_ASM_OPEN_PAREN ""
8179 #undef TARGET_ASM_CLOSE_PAREN
8180 #define TARGET_ASM_CLOSE_PAREN ""
8182 #undef TARGET_DEFAULT_TARGET_FLAGS
8183 #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD)
8184 #undef TARGET_HANDLE_OPTION
8185 #define TARGET_HANDLE_OPTION s390_handle_option
8187 #undef TARGET_ENCODE_SECTION_INFO
8188 #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
8191 #undef TARGET_HAVE_TLS
8192 #define TARGET_HAVE_TLS true
8194 #undef TARGET_CANNOT_FORCE_CONST_MEM
8195 #define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
8197 #undef TARGET_DELEGITIMIZE_ADDRESS
8198 #define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
8200 #undef TARGET_RETURN_IN_MEMORY
8201 #define TARGET_RETURN_IN_MEMORY s390_return_in_memory
8203 #undef TARGET_INIT_BUILTINS
8204 #define TARGET_INIT_BUILTINS s390_init_builtins
8205 #undef TARGET_EXPAND_BUILTIN
8206 #define TARGET_EXPAND_BUILTIN s390_expand_builtin
8208 #undef TARGET_ASM_OUTPUT_MI_THUNK
8209 #define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
8210 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
8211 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
8213 #undef TARGET_SCHED_ADJUST_PRIORITY
8214 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
8215 #undef TARGET_SCHED_ISSUE_RATE
8216 #define TARGET_SCHED_ISSUE_RATE s390_issue_rate
8217 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
8218 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
8220 #undef TARGET_CANNOT_COPY_INSN_P
8221 #define TARGET_CANNOT_COPY_INSN_P s390_cannot_copy_insn_p
8222 #undef TARGET_RTX_COSTS
8223 #define TARGET_RTX_COSTS s390_rtx_costs
8224 #undef TARGET_ADDRESS_COST
8225 #define TARGET_ADDRESS_COST s390_address_cost
8227 #undef TARGET_MACHINE_DEPENDENT_REORG
8228 #define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
8230 #undef TARGET_VALID_POINTER_MODE
8231 #define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
8233 #undef TARGET_BUILD_BUILTIN_VA_LIST
8234 #define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
8235 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
8236 #define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg
8238 #undef TARGET_PROMOTE_FUNCTION_ARGS
8239 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
8240 #undef TARGET_PROMOTE_FUNCTION_RETURN
8241 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
8242 #undef TARGET_PASS_BY_REFERENCE
8243 #define TARGET_PASS_BY_REFERENCE s390_pass_by_reference
8245 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
8246 #define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
8248 #undef TARGET_FIXED_CONDITION_CODE_REGS
8249 #define TARGET_FIXED_CONDITION_CODE_REGS s390_fixed_condition_code_regs
8251 #undef TARGET_CC_MODES_COMPATIBLE
8252 #define TARGET_CC_MODES_COMPATIBLE s390_cc_modes_compatible
8254 struct gcc_target targetm
= TARGET_INITIALIZER
;
8256 #include "gt-s390.h"