1 /* Subroutines used for code generation on IBM S/390 and zSeries
2 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
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"
55 /* Machine-specific symbol_ref flags. */
56 #define SYMBOL_FLAG_ALIGN1 (SYMBOL_FLAG_MACH_DEP << 0)
59 static bool s390_assemble_integer (rtx
, unsigned int, int);
60 static void s390_select_rtx_section (enum machine_mode
, rtx
,
61 unsigned HOST_WIDE_INT
);
62 static void s390_encode_section_info (tree
, rtx
, int);
63 static bool s390_cannot_force_const_mem (rtx
);
64 static rtx
s390_delegitimize_address (rtx
);
65 static bool s390_return_in_memory (tree
, tree
);
66 static void s390_init_builtins (void);
67 static rtx
s390_expand_builtin (tree
, rtx
, rtx
, enum machine_mode
, int);
68 static void s390_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
,
70 static enum attr_type
s390_safe_attr_type (rtx
);
72 static int s390_adjust_cost (rtx
, rtx
, rtx
, int);
73 static int s390_adjust_priority (rtx
, int);
74 static int s390_issue_rate (void);
75 static int s390_first_cycle_multipass_dfa_lookahead (void);
76 static bool s390_rtx_costs (rtx
, int, int, int *);
77 static int s390_address_cost (rtx
);
78 static void s390_reorg (void);
79 static bool s390_valid_pointer_mode (enum machine_mode
);
80 static tree
s390_build_builtin_va_list (void);
81 static tree
s390_gimplify_va_arg (tree
, tree
, tree
*, tree
*);
82 static bool s390_function_ok_for_sibcall (tree
, tree
);
83 static bool s390_call_saved_register_used (tree
);
84 static bool s390_pass_by_reference (CUMULATIVE_ARGS
*, enum machine_mode mode
,
87 #undef TARGET_ASM_ALIGNED_HI_OP
88 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
89 #undef TARGET_ASM_ALIGNED_DI_OP
90 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
91 #undef TARGET_ASM_INTEGER
92 #define TARGET_ASM_INTEGER s390_assemble_integer
94 #undef TARGET_ASM_OPEN_PAREN
95 #define TARGET_ASM_OPEN_PAREN ""
97 #undef TARGET_ASM_CLOSE_PAREN
98 #define TARGET_ASM_CLOSE_PAREN ""
100 #undef TARGET_ASM_SELECT_RTX_SECTION
101 #define TARGET_ASM_SELECT_RTX_SECTION s390_select_rtx_section
103 #undef TARGET_ENCODE_SECTION_INFO
104 #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
107 #undef TARGET_HAVE_TLS
108 #define TARGET_HAVE_TLS true
110 #undef TARGET_CANNOT_FORCE_CONST_MEM
111 #define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
113 #undef TARGET_DELEGITIMIZE_ADDRESS
114 #define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
116 #undef TARGET_RETURN_IN_MEMORY
117 #define TARGET_RETURN_IN_MEMORY s390_return_in_memory
119 #undef TARGET_INIT_BUILTINS
120 #define TARGET_INIT_BUILTINS s390_init_builtins
121 #undef TARGET_EXPAND_BUILTIN
122 #define TARGET_EXPAND_BUILTIN s390_expand_builtin
124 #undef TARGET_ASM_OUTPUT_MI_THUNK
125 #define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
126 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
127 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
129 #undef TARGET_SCHED_ADJUST_COST
130 #define TARGET_SCHED_ADJUST_COST s390_adjust_cost
131 #undef TARGET_SCHED_ADJUST_PRIORITY
132 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
133 #undef TARGET_SCHED_ISSUE_RATE
134 #define TARGET_SCHED_ISSUE_RATE s390_issue_rate
135 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
136 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
138 #undef TARGET_RTX_COSTS
139 #define TARGET_RTX_COSTS s390_rtx_costs
140 #undef TARGET_ADDRESS_COST
141 #define TARGET_ADDRESS_COST s390_address_cost
143 #undef TARGET_MACHINE_DEPENDENT_REORG
144 #define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
146 #undef TARGET_VALID_POINTER_MODE
147 #define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
149 #undef TARGET_BUILD_BUILTIN_VA_LIST
150 #define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
151 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
152 #define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg
154 #undef TARGET_PROMOTE_FUNCTION_ARGS
155 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
156 #undef TARGET_PROMOTE_FUNCTION_RETURN
157 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
158 #undef TARGET_PASS_BY_REFERENCE
159 #define TARGET_PASS_BY_REFERENCE s390_pass_by_reference
161 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
162 #define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
164 struct gcc_target targetm
= TARGET_INITIALIZER
;
166 extern int reload_completed
;
168 /* The alias set for prologue/epilogue register save/restore. */
169 static int s390_sr_alias_set
= 0;
171 /* Save information from a "cmpxx" operation until the branch or scc is
173 rtx s390_compare_op0
, s390_compare_op1
;
175 /* Structure used to hold the components of a S/390 memory
176 address. A legitimate address on S/390 is of the general
178 base + index + displacement
179 where any of the components is optional.
181 base and index are registers of the class ADDR_REGS,
182 displacement is an unsigned 12-bit immediate constant. */
192 /* Which cpu are we tuning for. */
193 enum processor_type s390_tune
;
194 enum processor_flags s390_tune_flags
;
195 /* Which instruction set architecture to use. */
196 enum processor_type s390_arch
;
197 enum processor_flags s390_arch_flags
;
199 /* Strings to hold which cpu and instruction set architecture to use. */
200 const char *s390_tune_string
; /* for -mtune=<xxx> */
201 const char *s390_arch_string
; /* for -march=<xxx> */
203 /* String to specify backchain mode. */
204 const char *s390_backchain_string
= ""; /* "" no-backchain ,"1" backchain,
205 "2" kernel-backchain */
207 /* The following structure is embedded in the machine
208 specific part of struct function. */
210 struct s390_frame_layout
GTY (())
212 /* Offset within stack frame. */
213 HOST_WIDE_INT gprs_offset
;
214 HOST_WIDE_INT f0_offset
;
215 HOST_WIDE_INT f4_offset
;
216 HOST_WIDE_INT f8_offset
;
217 HOST_WIDE_INT backchain_offset
;
219 /* Number of first and last gpr to be saved, restored. */
221 int first_restore_gpr
;
223 int last_restore_gpr
;
225 /* Bits standing for floating point registers. Set, if the
226 respective register has to be saved. Starting with reg 16 (f0)
227 at the rightmost bit.
228 Bit 15 - 8 7 6 5 4 3 2 1 0
229 fpr 15 - 8 7 5 3 1 6 4 2 0
230 reg 31 - 24 23 22 21 20 19 18 17 16 */
231 unsigned int fpr_bitmap
;
233 /* Number of floating point registers f8-f15 which must be saved. */
236 /* Set if return address needs to be saved. */
237 bool save_return_addr_p
;
239 /* Set if backchain needs to be saved. */
240 bool save_backchain_p
;
242 /* Size of stack frame. */
243 HOST_WIDE_INT frame_size
;
246 /* Define the structure for the machine field in struct function. */
248 struct machine_function
GTY(())
250 struct s390_frame_layout frame_layout
;
252 /* Literal pool base register. */
255 /* Some local-dynamic TLS symbol name. */
256 const char *some_ld_name
;
259 /* Few accessor macros for struct cfun->machine->s390_frame_layout. */
261 #define cfun_frame_layout (cfun->machine->frame_layout)
262 #define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)
263 #define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr - \
264 cfun_frame_layout.first_save_gpr + 1) * UNITS_PER_WORD)
265 #define cfun_set_fpr_bit(BITNUM) (cfun->machine->frame_layout.fpr_bitmap |= \
267 #define cfun_fpr_bit_p(BITNUM) (!!(cfun->machine->frame_layout.fpr_bitmap & \
270 static int s390_match_ccmode_set (rtx
, enum machine_mode
);
271 static int s390_branch_condition_mask (rtx
);
272 static const char *s390_branch_condition_mnemonic (rtx
, int);
273 static int check_mode (rtx
, enum machine_mode
*);
274 static int general_s_operand (rtx
, enum machine_mode
, int);
275 static int s390_short_displacement (rtx
);
276 static int s390_decompose_address (rtx
, struct s390_address
*);
277 static rtx
get_thread_pointer (void);
278 static rtx
legitimize_tls_address (rtx
, rtx
);
279 static void print_shift_count_operand (FILE *, rtx
);
280 static const char *get_some_local_dynamic_name (void);
281 static int get_some_local_dynamic_name_1 (rtx
*, void *);
282 static int reg_used_in_mem_p (int, rtx
);
283 static int addr_generation_dependency_p (rtx
, rtx
);
284 static int s390_split_branches (void);
285 static void annotate_constant_pool_refs (rtx
*x
);
286 static void find_constant_pool_ref (rtx
, rtx
*);
287 static void replace_constant_pool_ref (rtx
*, rtx
, rtx
);
288 static rtx
find_ltrel_base (rtx
);
289 static void replace_ltrel_base (rtx
*);
290 static void s390_optimize_prologue (bool);
291 static int find_unused_clobbered_reg (void);
292 static void s390_frame_area (int *, int *);
293 static void s390_register_info (int, int);
294 static void s390_frame_info (int, int);
295 static rtx
save_fpr (rtx
, int, int);
296 static rtx
restore_fpr (rtx
, int, int);
297 static rtx
save_gprs (rtx
, int, int, int);
298 static rtx
restore_gprs (rtx
, int, int, int);
299 static int s390_function_arg_size (enum machine_mode
, tree
);
300 static bool s390_function_arg_float (enum machine_mode
, tree
);
301 static struct machine_function
* s390_init_machine_status (void);
303 /* Check whether integer displacement is in range. */
304 #define DISP_IN_RANGE(d) \
305 (TARGET_LONG_DISPLACEMENT? ((d) >= -524288 && (d) <= 524287) \
306 : ((d) >= 0 && (d) <= 4095))
308 /* Return true if SET either doesn't set the CC register, or else
309 the source and destination have matching CC modes and that
310 CC mode is at least as constrained as REQ_MODE. */
313 s390_match_ccmode_set (rtx set
, enum machine_mode req_mode
)
315 enum machine_mode set_mode
;
317 if (GET_CODE (set
) != SET
)
320 if (GET_CODE (SET_DEST (set
)) != REG
|| !CC_REGNO_P (REGNO (SET_DEST (set
))))
323 set_mode
= GET_MODE (SET_DEST (set
));
337 if (req_mode
!= set_mode
)
342 if (req_mode
!= CCSmode
&& req_mode
!= CCUmode
&& req_mode
!= CCTmode
343 && req_mode
!= CCSRmode
&& req_mode
!= CCURmode
)
349 if (req_mode
!= CCAmode
)
357 return (GET_MODE (SET_SRC (set
)) == set_mode
);
360 /* Return true if every SET in INSN that sets the CC register
361 has source and destination with matching CC modes and that
362 CC mode is at least as constrained as REQ_MODE.
363 If REQ_MODE is VOIDmode, always return false. */
366 s390_match_ccmode (rtx insn
, enum machine_mode req_mode
)
370 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
371 if (req_mode
== VOIDmode
)
374 if (GET_CODE (PATTERN (insn
)) == SET
)
375 return s390_match_ccmode_set (PATTERN (insn
), req_mode
);
377 if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
378 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
380 rtx set
= XVECEXP (PATTERN (insn
), 0, i
);
381 if (GET_CODE (set
) == SET
)
382 if (!s390_match_ccmode_set (set
, req_mode
))
389 /* If a test-under-mask instruction can be used to implement
390 (compare (and ... OP1) OP2), return the CC mode required
391 to do that. Otherwise, return VOIDmode.
392 MIXED is true if the instruction can distinguish between
393 CC1 and CC2 for mixed selected bits (TMxx), it is false
394 if the instruction cannot (TM). */
397 s390_tm_ccmode (rtx op1
, rtx op2
, int mixed
)
401 /* ??? Fixme: should work on CONST_DOUBLE as well. */
402 if (GET_CODE (op1
) != CONST_INT
|| GET_CODE (op2
) != CONST_INT
)
405 /* Selected bits all zero: CC0. */
406 if (INTVAL (op2
) == 0)
409 /* Selected bits all one: CC3. */
410 if (INTVAL (op2
) == INTVAL (op1
))
413 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. */
416 bit1
= exact_log2 (INTVAL (op2
));
417 bit0
= exact_log2 (INTVAL (op1
) ^ INTVAL (op2
));
418 if (bit0
!= -1 && bit1
!= -1)
419 return bit0
> bit1
? CCT1mode
: CCT2mode
;
425 /* Given a comparison code OP (EQ, NE, etc.) and the operands
426 OP0 and OP1 of a COMPARE, return the mode to be used for the
430 s390_select_ccmode (enum rtx_code code
, rtx op0
, rtx op1
)
436 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
437 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0
, 1)), 'K', "K"))
439 if ((GET_CODE (op0
) == PLUS
|| GET_CODE (op0
) == MINUS
440 || GET_CODE (op1
) == NEG
)
441 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
444 if (GET_CODE (op0
) == AND
)
446 /* Check whether we can potentially do it via TM. */
447 enum machine_mode ccmode
;
448 ccmode
= s390_tm_ccmode (XEXP (op0
, 1), op1
, 1);
449 if (ccmode
!= VOIDmode
)
451 /* Relax CCTmode to CCZmode to allow fall-back to AND
452 if that turns out to be beneficial. */
453 return ccmode
== CCTmode
? CCZmode
: ccmode
;
457 if (register_operand (op0
, HImode
)
458 && GET_CODE (op1
) == CONST_INT
459 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 65535))
461 if (register_operand (op0
, QImode
)
462 && GET_CODE (op1
) == CONST_INT
463 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 255))
472 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
473 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0
, 1)), 'K', "K"))
475 if (INTVAL (XEXP((op0
), 1)) < 0)
488 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
489 && GET_CODE (op1
) != CONST_INT
)
495 if (GET_CODE (op0
) == PLUS
496 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
499 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
500 && GET_CODE (op1
) != CONST_INT
)
506 if (GET_CODE (op0
) == MINUS
507 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
510 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
511 && GET_CODE (op1
) != CONST_INT
)
520 /* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
521 that we can implement more efficiently. */
524 s390_canonicalize_comparison (enum rtx_code
*code
, rtx
*op0
, rtx
*op1
)
526 /* Convert ZERO_EXTRACT back to AND to enable TM patterns. */
527 if ((*code
== EQ
|| *code
== NE
)
528 && *op1
== const0_rtx
529 && GET_CODE (*op0
) == ZERO_EXTRACT
530 && GET_CODE (XEXP (*op0
, 1)) == CONST_INT
531 && GET_CODE (XEXP (*op0
, 2)) == CONST_INT
532 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0
, 0))))
534 rtx inner
= XEXP (*op0
, 0);
535 HOST_WIDE_INT modesize
= GET_MODE_BITSIZE (GET_MODE (inner
));
536 HOST_WIDE_INT len
= INTVAL (XEXP (*op0
, 1));
537 HOST_WIDE_INT pos
= INTVAL (XEXP (*op0
, 2));
539 if (len
> 0 && len
< modesize
540 && pos
>= 0 && pos
+ len
<= modesize
541 && modesize
<= HOST_BITS_PER_WIDE_INT
)
543 unsigned HOST_WIDE_INT block
;
544 block
= ((unsigned HOST_WIDE_INT
) 1 << len
) - 1;
545 block
<<= modesize
- pos
- len
;
547 *op0
= gen_rtx_AND (GET_MODE (inner
), inner
,
548 gen_int_mode (block
, GET_MODE (inner
)));
552 /* Narrow AND of memory against immediate to enable TM. */
553 if ((*code
== EQ
|| *code
== NE
)
554 && *op1
== const0_rtx
555 && GET_CODE (*op0
) == AND
556 && GET_CODE (XEXP (*op0
, 1)) == CONST_INT
557 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0
, 0))))
559 rtx inner
= XEXP (*op0
, 0);
560 rtx mask
= XEXP (*op0
, 1);
562 /* Ignore paradoxical SUBREGs if all extra bits are masked out. */
563 if (GET_CODE (inner
) == SUBREG
564 && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (inner
)))
565 && (GET_MODE_SIZE (GET_MODE (inner
))
566 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner
))))
568 & GET_MODE_MASK (GET_MODE (inner
))
569 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (inner
))))
571 inner
= SUBREG_REG (inner
);
573 /* Do not change volatile MEMs. */
574 if (MEM_P (inner
) && !MEM_VOLATILE_P (inner
))
576 int part
= s390_single_part (XEXP (*op0
, 1),
577 GET_MODE (inner
), QImode
, 0);
580 mask
= gen_int_mode (s390_extract_part (mask
, QImode
, 0), QImode
);
581 inner
= adjust_address_nv (inner
, QImode
, part
);
582 *op0
= gen_rtx_AND (QImode
, inner
, mask
);
587 /* Narrow comparisons against 0xffff to HImode if possible. */
589 if ((*code
== EQ
|| *code
== NE
)
590 && GET_CODE (*op1
) == CONST_INT
591 && INTVAL (*op1
) == 0xffff
592 && SCALAR_INT_MODE_P (GET_MODE (*op0
))
593 && (nonzero_bits (*op0
, GET_MODE (*op0
))
594 & ~(unsigned HOST_WIDE_INT
) 0xffff) == 0)
596 *op0
= gen_lowpart (HImode
, *op0
);
601 /* Emit a compare instruction suitable to implement the comparison
602 OP0 CODE OP1. Return the correct condition RTL to be placed in
603 the IF_THEN_ELSE of the conditional branch testing the result. */
606 s390_emit_compare (enum rtx_code code
, rtx op0
, rtx op1
)
608 enum machine_mode mode
= s390_select_ccmode (code
, op0
, op1
);
609 rtx cc
= gen_rtx_REG (mode
, CC_REGNUM
);
611 emit_insn (gen_rtx_SET (VOIDmode
, cc
, gen_rtx_COMPARE (mode
, op0
, op1
)));
612 return gen_rtx_fmt_ee (code
, VOIDmode
, cc
, const0_rtx
);
615 /* Emit a jump instruction to TARGET. If COND is NULL_RTX, emit an
616 unconditional jump, else a conditional jump under condition COND. */
619 s390_emit_jump (rtx target
, rtx cond
)
623 target
= gen_rtx_LABEL_REF (VOIDmode
, target
);
625 target
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, target
, pc_rtx
);
627 insn
= gen_rtx_SET (VOIDmode
, pc_rtx
, target
);
628 emit_jump_insn (insn
);
631 /* Return nonzero if OP is a valid comparison operator
632 for an ALC condition in mode MODE. */
635 s390_alc_comparison (rtx op
, enum machine_mode mode
)
637 if (mode
!= VOIDmode
&& mode
!= GET_MODE (op
))
640 while (GET_CODE (op
) == ZERO_EXTEND
|| GET_CODE (op
) == SIGN_EXTEND
)
643 if (!COMPARISON_P (op
))
646 if (GET_CODE (XEXP (op
, 0)) != REG
647 || REGNO (XEXP (op
, 0)) != CC_REGNUM
648 || XEXP (op
, 1) != const0_rtx
)
651 switch (GET_MODE (XEXP (op
, 0)))
654 return GET_CODE (op
) == LTU
;
657 return GET_CODE (op
) == LEU
;
660 return GET_CODE (op
) == GEU
;
663 return GET_CODE (op
) == GTU
;
666 return GET_CODE (op
) == LTU
;
669 return GET_CODE (op
) == UNGT
;
672 return GET_CODE (op
) == UNLT
;
679 /* Return nonzero if OP is a valid comparison operator
680 for an SLB condition in mode MODE. */
683 s390_slb_comparison (rtx op
, enum machine_mode mode
)
685 if (mode
!= VOIDmode
&& mode
!= GET_MODE (op
))
688 while (GET_CODE (op
) == ZERO_EXTEND
|| GET_CODE (op
) == SIGN_EXTEND
)
691 if (!COMPARISON_P (op
))
694 if (GET_CODE (XEXP (op
, 0)) != REG
695 || REGNO (XEXP (op
, 0)) != CC_REGNUM
696 || XEXP (op
, 1) != const0_rtx
)
699 switch (GET_MODE (XEXP (op
, 0)))
702 return GET_CODE (op
) == GEU
;
705 return GET_CODE (op
) == GTU
;
708 return GET_CODE (op
) == LTU
;
711 return GET_CODE (op
) == LEU
;
714 return GET_CODE (op
) == GEU
;
717 return GET_CODE (op
) == LE
;
720 return GET_CODE (op
) == GE
;
727 /* Return branch condition mask to implement a branch
728 specified by CODE. */
731 s390_branch_condition_mask (rtx code
)
733 const int CC0
= 1 << 3;
734 const int CC1
= 1 << 2;
735 const int CC2
= 1 << 1;
736 const int CC3
= 1 << 0;
738 if (GET_CODE (XEXP (code
, 0)) != REG
739 || REGNO (XEXP (code
, 0)) != CC_REGNUM
740 || XEXP (code
, 1) != const0_rtx
)
743 switch (GET_MODE (XEXP (code
, 0)))
746 switch (GET_CODE (code
))
749 case NE
: return CC1
| CC2
| CC3
;
756 switch (GET_CODE (code
))
759 case NE
: return CC0
| CC2
| CC3
;
766 switch (GET_CODE (code
))
769 case NE
: return CC0
| CC1
| CC3
;
776 switch (GET_CODE (code
))
779 case NE
: return CC0
| CC1
| CC2
;
786 switch (GET_CODE (code
))
788 case EQ
: return CC0
| CC2
;
789 case NE
: return CC1
| CC3
;
796 switch (GET_CODE (code
))
798 case LTU
: return CC2
| CC3
; /* carry */
799 case GEU
: return CC0
| CC1
; /* no carry */
806 switch (GET_CODE (code
))
808 case GTU
: return CC0
| CC1
; /* borrow */
809 case LEU
: return CC2
| CC3
; /* no borrow */
816 switch (GET_CODE (code
))
818 case EQ
: return CC0
| CC2
;
819 case NE
: return CC1
| CC3
;
820 case LTU
: return CC1
;
821 case GTU
: return CC3
;
822 case LEU
: return CC1
| CC2
;
823 case GEU
: return CC2
| CC3
;
829 switch (GET_CODE (code
))
832 case NE
: return CC1
| CC2
| CC3
;
833 case LTU
: return CC1
;
834 case GTU
: return CC2
;
835 case LEU
: return CC0
| CC1
;
836 case GEU
: return CC0
| CC2
;
843 switch (GET_CODE (code
))
846 case NE
: return CC2
| CC1
| CC3
;
847 case LTU
: return CC2
;
848 case GTU
: return CC1
;
849 case LEU
: return CC0
| CC2
;
850 case GEU
: return CC0
| CC1
;
857 switch (GET_CODE (code
))
860 case NE
: return CC1
| CC2
| CC3
;
861 case LT
: return CC1
| CC3
;
863 case LE
: return CC0
| CC1
| CC3
;
864 case GE
: return CC0
| CC2
;
871 switch (GET_CODE (code
))
874 case NE
: return CC1
| CC2
| CC3
;
876 case GT
: return CC2
| CC3
;
877 case LE
: return CC0
| CC1
;
878 case GE
: return CC0
| CC2
| CC3
;
885 switch (GET_CODE (code
))
888 case NE
: return CC1
| CC2
| CC3
;
891 case LE
: return CC0
| CC1
;
892 case GE
: return CC0
| CC2
;
893 case UNORDERED
: return CC3
;
894 case ORDERED
: return CC0
| CC1
| CC2
;
895 case UNEQ
: return CC0
| CC3
;
896 case UNLT
: return CC1
| CC3
;
897 case UNGT
: return CC2
| CC3
;
898 case UNLE
: return CC0
| CC1
| CC3
;
899 case UNGE
: return CC0
| CC2
| CC3
;
900 case LTGT
: return CC1
| CC2
;
907 switch (GET_CODE (code
))
910 case NE
: return CC2
| CC1
| CC3
;
913 case LE
: return CC0
| CC2
;
914 case GE
: return CC0
| CC1
;
915 case UNORDERED
: return CC3
;
916 case ORDERED
: return CC0
| CC2
| CC1
;
917 case UNEQ
: return CC0
| CC3
;
918 case UNLT
: return CC2
| CC3
;
919 case UNGT
: return CC1
| CC3
;
920 case UNLE
: return CC0
| CC2
| CC3
;
921 case UNGE
: return CC0
| CC1
| CC3
;
922 case LTGT
: return CC2
| CC1
;
933 /* If INV is false, return assembler mnemonic string to implement
934 a branch specified by CODE. If INV is true, return mnemonic
935 for the corresponding inverted branch. */
938 s390_branch_condition_mnemonic (rtx code
, int inv
)
940 static const char *const mnemonic
[16] =
942 NULL
, "o", "h", "nle",
943 "l", "nhe", "lh", "ne",
944 "e", "nlh", "he", "nl",
945 "le", "nh", "no", NULL
948 int mask
= s390_branch_condition_mask (code
);
953 if (mask
< 1 || mask
> 14)
956 return mnemonic
[mask
];
959 /* Return the part of op which has a value different from def.
960 The size of the part is determined by mode.
961 Use this function only if you already know that op really
962 contains such a part. */
964 unsigned HOST_WIDE_INT
965 s390_extract_part (rtx op
, enum machine_mode mode
, int def
)
967 unsigned HOST_WIDE_INT value
= 0;
968 int max_parts
= HOST_BITS_PER_WIDE_INT
/ GET_MODE_BITSIZE (mode
);
969 int part_bits
= GET_MODE_BITSIZE (mode
);
970 unsigned HOST_WIDE_INT part_mask
= (1 << part_bits
) - 1;
973 for (i
= 0; i
< max_parts
; i
++)
976 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
980 if ((value
& part_mask
) != (def
& part_mask
))
981 return value
& part_mask
;
987 /* If OP is an integer constant of mode MODE with exactly one
988 part of mode PART_MODE unequal to DEF, return the number of that
989 part. Otherwise, return -1. */
992 s390_single_part (rtx op
,
993 enum machine_mode mode
,
994 enum machine_mode part_mode
,
997 unsigned HOST_WIDE_INT value
= 0;
998 int n_parts
= GET_MODE_SIZE (mode
) / GET_MODE_SIZE (part_mode
);
999 unsigned HOST_WIDE_INT part_mask
= (1 << GET_MODE_BITSIZE (part_mode
)) - 1;
1002 if (GET_CODE (op
) != CONST_INT
)
1005 for (i
= 0; i
< n_parts
; i
++)
1008 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
1010 value
>>= GET_MODE_BITSIZE (part_mode
);
1012 if ((value
& part_mask
) != (def
& part_mask
))
1020 return part
== -1 ? -1 : n_parts
- 1 - part
;
1023 /* Check whether we can (and want to) split a double-word
1024 move in mode MODE from SRC to DST into two single-word
1025 moves, moving the subword FIRST_SUBWORD first. */
1028 s390_split_ok_p (rtx dst
, rtx src
, enum machine_mode mode
, int first_subword
)
1030 /* Floating point registers cannot be split. */
1031 if (FP_REG_P (src
) || FP_REG_P (dst
))
1034 /* We don't need to split if operands are directly accessible. */
1035 if (s_operand (src
, mode
) || s_operand (dst
, mode
))
1038 /* Non-offsettable memory references cannot be split. */
1039 if ((GET_CODE (src
) == MEM
&& !offsettable_memref_p (src
))
1040 || (GET_CODE (dst
) == MEM
&& !offsettable_memref_p (dst
)))
1043 /* Moving the first subword must not clobber a register
1044 needed to move the second subword. */
1045 if (register_operand (dst
, mode
))
1047 rtx subreg
= operand_subword (dst
, first_subword
, 0, mode
);
1048 if (reg_overlap_mentioned_p (subreg
, src
))
1056 /* Change optimizations to be performed, depending on the
1059 LEVEL is the optimization level specified; 2 if `-O2' is
1060 specified, 1 if `-O' is specified, and 0 if neither is specified.
1062 SIZE is nonzero if `-Os' is specified and zero otherwise. */
1065 optimization_options (int level ATTRIBUTE_UNUSED
, int size ATTRIBUTE_UNUSED
)
1067 /* ??? There are apparently still problems with -fcaller-saves. */
1068 flag_caller_saves
= 0;
1070 /* By default, always emit DWARF-2 unwind info. This allows debugging
1071 without maintaining a stack frame back-chain. */
1072 flag_asynchronous_unwind_tables
= 1;
1076 override_options (void)
1081 const char *const name
; /* processor name or nickname. */
1082 const enum processor_type processor
;
1083 const enum processor_flags flags
;
1085 const processor_alias_table
[] =
1087 {"g5", PROCESSOR_9672_G5
, PF_IEEE_FLOAT
},
1088 {"g6", PROCESSOR_9672_G6
, PF_IEEE_FLOAT
},
1089 {"z900", PROCESSOR_2064_Z900
, PF_IEEE_FLOAT
| PF_ZARCH
},
1090 {"z990", PROCESSOR_2084_Z990
, PF_IEEE_FLOAT
| PF_ZARCH
1091 | PF_LONG_DISPLACEMENT
},
1094 int const pta_size
= ARRAY_SIZE (processor_alias_table
);
1096 /* Acquire a unique set number for our register saves and restores. */
1097 s390_sr_alias_set
= new_alias_set ();
1099 /* Set up function hooks. */
1100 init_machine_status
= s390_init_machine_status
;
1102 /* Architecture mode defaults according to ABI. */
1103 if (!(target_flags_explicit
& MASK_ZARCH
))
1106 target_flags
|= MASK_ZARCH
;
1108 target_flags
&= ~MASK_ZARCH
;
1111 /* Determine processor architectural level. */
1112 if (!s390_arch_string
)
1113 s390_arch_string
= TARGET_ZARCH
? "z900" : "g5";
1115 for (i
= 0; i
< pta_size
; i
++)
1116 if (! strcmp (s390_arch_string
, processor_alias_table
[i
].name
))
1118 s390_arch
= processor_alias_table
[i
].processor
;
1119 s390_arch_flags
= processor_alias_table
[i
].flags
;
1123 error ("Unknown cpu used in -march=%s.", s390_arch_string
);
1125 /* Determine processor to tune for. */
1126 if (!s390_tune_string
)
1128 s390_tune
= s390_arch
;
1129 s390_tune_flags
= s390_arch_flags
;
1130 s390_tune_string
= s390_arch_string
;
1134 for (i
= 0; i
< pta_size
; i
++)
1135 if (! strcmp (s390_tune_string
, processor_alias_table
[i
].name
))
1137 s390_tune
= processor_alias_table
[i
].processor
;
1138 s390_tune_flags
= processor_alias_table
[i
].flags
;
1142 error ("Unknown cpu used in -mtune=%s.", s390_tune_string
);
1145 /* Sanity checks. */
1146 if (TARGET_ZARCH
&& !(s390_arch_flags
& PF_ZARCH
))
1147 error ("z/Architecture mode not supported on %s.", s390_arch_string
);
1148 if (TARGET_64BIT
&& !TARGET_ZARCH
)
1149 error ("64-bit ABI not supported in ESA/390 mode.");
1152 /* Map for smallest class containing reg regno. */
1154 const enum reg_class regclass_map
[FIRST_PSEUDO_REGISTER
] =
1155 { GENERAL_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1156 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1157 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1158 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1159 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1160 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1161 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1162 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1163 ADDR_REGS
, NO_REGS
, ADDR_REGS
, ADDR_REGS
1166 /* Return attribute type of insn. */
1168 static enum attr_type
1169 s390_safe_attr_type (rtx insn
)
1171 if (recog_memoized (insn
) >= 0)
1172 return get_attr_type (insn
);
1177 /* Return true if OP a (const_int 0) operand.
1178 OP is the current operation.
1179 MODE is the current operation mode. */
1182 const0_operand (register rtx op
, enum machine_mode mode
)
1184 return op
== CONST0_RTX (mode
);
1187 /* Return true if OP is constant.
1188 OP is the current operation.
1189 MODE is the current operation mode. */
1192 consttable_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1194 return CONSTANT_P (op
);
1197 /* Return true if the mode of operand OP matches MODE.
1198 If MODE is set to VOIDmode, set it to the mode of OP. */
1201 check_mode (register rtx op
, enum machine_mode
*mode
)
1203 if (*mode
== VOIDmode
)
1204 *mode
= GET_MODE (op
);
1207 if (GET_MODE (op
) != VOIDmode
&& GET_MODE (op
) != *mode
)
1213 /* Return true if OP a valid operand for the LARL instruction.
1214 OP is the current operation.
1215 MODE is the current operation mode. */
1218 larl_operand (register rtx op
, enum machine_mode mode
)
1220 if (! check_mode (op
, &mode
))
1223 /* Allow labels and local symbols. */
1224 if (GET_CODE (op
) == LABEL_REF
)
1226 if (GET_CODE (op
) == SYMBOL_REF
)
1227 return ((SYMBOL_REF_FLAGS (op
) & SYMBOL_FLAG_ALIGN1
) == 0
1228 && SYMBOL_REF_TLS_MODEL (op
) == 0
1229 && (!flag_pic
|| SYMBOL_REF_LOCAL_P (op
)));
1231 /* Everything else must have a CONST, so strip it. */
1232 if (GET_CODE (op
) != CONST
)
1236 /* Allow adding *even* in-range constants. */
1237 if (GET_CODE (op
) == PLUS
)
1239 if (GET_CODE (XEXP (op
, 1)) != CONST_INT
1240 || (INTVAL (XEXP (op
, 1)) & 1) != 0)
1242 #if HOST_BITS_PER_WIDE_INT > 32
1243 if (INTVAL (XEXP (op
, 1)) >= (HOST_WIDE_INT
)1 << 32
1244 || INTVAL (XEXP (op
, 1)) < -((HOST_WIDE_INT
)1 << 32))
1250 /* Labels and local symbols allowed here as well. */
1251 if (GET_CODE (op
) == LABEL_REF
)
1253 if (GET_CODE (op
) == SYMBOL_REF
)
1254 return ((SYMBOL_REF_FLAGS (op
) & SYMBOL_FLAG_ALIGN1
) == 0
1255 && SYMBOL_REF_TLS_MODEL (op
) == 0
1256 && (!flag_pic
|| SYMBOL_REF_LOCAL_P (op
)));
1258 /* Now we must have a @GOTENT offset or @PLT stub
1259 or an @INDNTPOFF TLS offset. */
1260 if (GET_CODE (op
) == UNSPEC
1261 && XINT (op
, 1) == UNSPEC_GOTENT
)
1263 if (GET_CODE (op
) == UNSPEC
1264 && XINT (op
, 1) == UNSPEC_PLT
)
1266 if (GET_CODE (op
) == UNSPEC
1267 && XINT (op
, 1) == UNSPEC_INDNTPOFF
)
1273 /* Helper routine to implement s_operand and s_imm_operand.
1274 OP is the current operation.
1275 MODE is the current operation mode.
1276 ALLOW_IMMEDIATE specifies whether immediate operands should
1277 be accepted or not. */
1280 general_s_operand (register rtx op
, enum machine_mode mode
,
1281 int allow_immediate
)
1283 struct s390_address addr
;
1285 /* Call general_operand first, so that we don't have to
1286 check for many special cases. */
1287 if (!general_operand (op
, mode
))
1290 /* Just like memory_operand, allow (subreg (mem ...))
1292 if (reload_completed
1293 && GET_CODE (op
) == SUBREG
1294 && GET_CODE (SUBREG_REG (op
)) == MEM
)
1295 op
= SUBREG_REG (op
);
1297 switch (GET_CODE (op
))
1299 /* Constants are OK as s-operand if ALLOW_IMMEDIATE
1300 is true and we are still before reload. */
1303 if (!allow_immediate
|| reload_completed
)
1307 /* Memory operands are OK unless they already use an
1310 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1314 /* Do not allow literal pool references unless ALLOW_IMMEDIATE
1315 is true. This prevents compares between two literal pool
1316 entries from being accepted. */
1317 if (!allow_immediate
1318 && addr
.base
&& REGNO (addr
.base
) == BASE_REGNUM
)
1329 /* Return true if OP is a valid S-type operand.
1330 OP is the current operation.
1331 MODE is the current operation mode. */
1334 s_operand (register rtx op
, enum machine_mode mode
)
1336 return general_s_operand (op
, mode
, 0);
1339 /* Return true if OP is a valid S-type operand or an immediate
1340 operand that can be addressed as S-type operand by forcing
1341 it into the literal pool.
1342 OP is the current operation.
1343 MODE is the current operation mode. */
1346 s_imm_operand (register rtx op
, enum machine_mode mode
)
1348 return general_s_operand (op
, mode
, 1);
1351 /* Return true if OP a valid shift count operand.
1352 OP is the current operation.
1353 MODE is the current operation mode. */
1356 shift_count_operand (rtx op
, enum machine_mode mode
)
1358 HOST_WIDE_INT offset
= 0;
1360 if (! check_mode (op
, &mode
))
1363 /* We can have an integer constant, an address register,
1364 or a sum of the two. Note that reload already checks
1365 that any register present is an address register, so
1366 we just check for any register here. */
1367 if (GET_CODE (op
) == CONST_INT
)
1369 offset
= INTVAL (op
);
1372 if (op
&& GET_CODE (op
) == PLUS
&& GET_CODE (XEXP (op
, 1)) == CONST_INT
)
1374 offset
= INTVAL (XEXP (op
, 1));
1377 while (op
&& GET_CODE (op
) == SUBREG
)
1378 op
= SUBREG_REG (op
);
1379 if (op
&& GET_CODE (op
) != REG
)
1382 /* Unfortunately we have to reject constants that are invalid
1383 for an address, or else reload will get confused. */
1384 if (!DISP_IN_RANGE (offset
))
1390 /* Return true if DISP is a valid short displacement. */
1393 s390_short_displacement (rtx disp
)
1395 /* No displacement is OK. */
1399 /* Integer displacement in range. */
1400 if (GET_CODE (disp
) == CONST_INT
)
1401 return INTVAL (disp
) >= 0 && INTVAL (disp
) < 4096;
1403 /* GOT offset is not OK, the GOT can be large. */
1404 if (GET_CODE (disp
) == CONST
1405 && GET_CODE (XEXP (disp
, 0)) == UNSPEC
1406 && XINT (XEXP (disp
, 0), 1) == UNSPEC_GOT
)
1409 /* All other symbolic constants are literal pool references,
1410 which are OK as the literal pool must be small. */
1411 if (GET_CODE (disp
) == CONST
)
1417 /* Return true if OP is a valid operand for a C constraint. */
1420 s390_extra_constraint_str (rtx op
, int c
, const char * str
)
1422 struct s390_address addr
;
1430 if (GET_CODE (op
) != MEM
)
1432 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1437 if (TARGET_LONG_DISPLACEMENT
)
1439 if (!s390_short_displacement (addr
.disp
))
1445 if (GET_CODE (op
) != MEM
)
1448 if (TARGET_LONG_DISPLACEMENT
)
1450 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1452 if (!s390_short_displacement (addr
.disp
))
1458 if (!TARGET_LONG_DISPLACEMENT
)
1460 if (GET_CODE (op
) != MEM
)
1462 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1466 if (s390_short_displacement (addr
.disp
))
1471 if (!TARGET_LONG_DISPLACEMENT
)
1473 if (GET_CODE (op
) != MEM
)
1475 /* Any invalid address here will be fixed up by reload,
1476 so accept it for the most generic constraint. */
1477 if (s390_decompose_address (XEXP (op
, 0), &addr
)
1478 && s390_short_displacement (addr
.disp
))
1483 if (TARGET_LONG_DISPLACEMENT
)
1485 if (!s390_decompose_address (op
, &addr
))
1487 if (!s390_short_displacement (addr
.disp
))
1493 if (!TARGET_LONG_DISPLACEMENT
)
1495 /* Any invalid address here will be fixed up by reload,
1496 so accept it for the most generic constraint. */
1497 if (s390_decompose_address (op
, &addr
)
1498 && s390_short_displacement (addr
.disp
))
1503 return shift_count_operand (op
, VOIDmode
);
1512 /* Return true if VALUE matches the constraint STR. */
1515 s390_const_ok_for_constraint_p (HOST_WIDE_INT value
,
1519 enum machine_mode mode
, part_mode
;
1529 return (unsigned int)value
< 256;
1532 return (unsigned int)value
< 4096;
1535 return value
>= -32768 && value
< 32768;
1538 return (TARGET_LONG_DISPLACEMENT
?
1539 (value
>= -524288 && value
<= 524287)
1540 : (value
>= 0 && value
<= 4095));
1542 return value
== 2147483647;
1545 part
= str
[1] - '0';
1549 case 'H': part_mode
= HImode
; break;
1550 case 'Q': part_mode
= QImode
; break;
1556 case 'H': mode
= HImode
; break;
1557 case 'S': mode
= SImode
; break;
1558 case 'D': mode
= DImode
; break;
1564 case '0': def
= 0; break;
1565 case 'F': def
= -1; break;
1569 if (GET_MODE_SIZE (mode
) <= GET_MODE_SIZE (part_mode
))
1572 if (s390_single_part (GEN_INT (value
), mode
, part_mode
, def
) != part
)
1584 /* Compute a (partial) cost for rtx X. Return true if the complete
1585 cost has been computed, and false if subexpressions should be
1586 scanned. In either case, *TOTAL contains the cost result. */
1589 s390_rtx_costs (rtx x
, int code
, int outer_code
, int *total
)
1594 if (GET_CODE (XEXP (x
, 0)) == MINUS
1595 && GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
1602 /* Force_const_mem does not work out of reload, because the
1603 saveable_obstack is set to reload_obstack, which does not
1604 live long enough. Because of this we cannot use force_const_mem
1605 in addsi3. This leads to problems with gen_add2_insn with a
1606 constant greater than a short. Because of that we give an
1607 addition of greater constants a cost of 3 (reload1.c 10096). */
1608 /* ??? saveable_obstack no longer exists. */
1609 if (outer_code
== PLUS
1610 && (INTVAL (x
) > 32767 || INTVAL (x
) < -32768))
1611 *total
= COSTS_N_INSNS (3);
1632 *total
= COSTS_N_INSNS (1);
1636 if (GET_MODE (XEXP (x
, 0)) == DImode
)
1637 *total
= COSTS_N_INSNS (40);
1639 *total
= COSTS_N_INSNS (7);
1646 *total
= COSTS_N_INSNS (33);
1654 /* Return the cost of an address rtx ADDR. */
1657 s390_address_cost (rtx addr
)
1659 struct s390_address ad
;
1660 if (!s390_decompose_address (addr
, &ad
))
1663 return ad
.indx
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
1666 /* Return true if OP is a valid operand for the BRAS instruction.
1667 OP is the current operation.
1668 MODE is the current operation mode. */
1671 bras_sym_operand (register rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1673 register enum rtx_code code
= GET_CODE (op
);
1675 /* Allow SYMBOL_REFs. */
1676 if (code
== SYMBOL_REF
)
1679 /* Allow @PLT stubs. */
1681 && GET_CODE (XEXP (op
, 0)) == UNSPEC
1682 && XINT (XEXP (op
, 0), 1) == UNSPEC_PLT
)
1687 /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
1688 otherwise return 0. */
1691 tls_symbolic_operand (register rtx op
)
1693 if (GET_CODE (op
) != SYMBOL_REF
)
1695 return SYMBOL_REF_TLS_MODEL (op
);
1698 /* Return true if OP is a load multiple operation. It is known to be a
1699 PARALLEL and the first section will be tested.
1700 OP is the current operation.
1701 MODE is the current operation mode. */
1704 load_multiple_operation (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1706 enum machine_mode elt_mode
;
1707 int count
= XVECLEN (op
, 0);
1708 unsigned int dest_regno
;
1713 /* Perform a quick check so we don't blow up below. */
1715 || GET_CODE (XVECEXP (op
, 0, 0)) != SET
1716 || GET_CODE (SET_DEST (XVECEXP (op
, 0, 0))) != REG
1717 || GET_CODE (SET_SRC (XVECEXP (op
, 0, 0))) != MEM
)
1720 dest_regno
= REGNO (SET_DEST (XVECEXP (op
, 0, 0)));
1721 src_addr
= XEXP (SET_SRC (XVECEXP (op
, 0, 0)), 0);
1722 elt_mode
= GET_MODE (SET_DEST (XVECEXP (op
, 0, 0)));
1724 /* Check, is base, or base + displacement. */
1726 if (GET_CODE (src_addr
) == REG
)
1728 else if (GET_CODE (src_addr
) == PLUS
1729 && GET_CODE (XEXP (src_addr
, 0)) == REG
1730 && GET_CODE (XEXP (src_addr
, 1)) == CONST_INT
)
1732 off
= INTVAL (XEXP (src_addr
, 1));
1733 src_addr
= XEXP (src_addr
, 0);
1738 for (i
= 1; i
< count
; i
++)
1740 rtx elt
= XVECEXP (op
, 0, i
);
1742 if (GET_CODE (elt
) != SET
1743 || GET_CODE (SET_DEST (elt
)) != REG
1744 || GET_MODE (SET_DEST (elt
)) != elt_mode
1745 || REGNO (SET_DEST (elt
)) != dest_regno
+ i
1746 || GET_CODE (SET_SRC (elt
)) != MEM
1747 || GET_MODE (SET_SRC (elt
)) != elt_mode
1748 || GET_CODE (XEXP (SET_SRC (elt
), 0)) != PLUS
1749 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt
), 0), 0), src_addr
)
1750 || GET_CODE (XEXP (XEXP (SET_SRC (elt
), 0), 1)) != CONST_INT
1751 || INTVAL (XEXP (XEXP (SET_SRC (elt
), 0), 1))
1752 != off
+ i
* GET_MODE_SIZE (elt_mode
))
1759 /* Return true if OP is a store multiple operation. It is known to be a
1760 PARALLEL and the first section will be tested.
1761 OP is the current operation.
1762 MODE is the current operation mode. */
1765 store_multiple_operation (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1767 enum machine_mode elt_mode
;
1768 int count
= XVECLEN (op
, 0);
1769 unsigned int src_regno
;
1773 /* Perform a quick check so we don't blow up below. */
1775 || GET_CODE (XVECEXP (op
, 0, 0)) != SET
1776 || GET_CODE (SET_DEST (XVECEXP (op
, 0, 0))) != MEM
1777 || GET_CODE (SET_SRC (XVECEXP (op
, 0, 0))) != REG
)
1780 src_regno
= REGNO (SET_SRC (XVECEXP (op
, 0, 0)));
1781 dest_addr
= XEXP (SET_DEST (XVECEXP (op
, 0, 0)), 0);
1782 elt_mode
= GET_MODE (SET_SRC (XVECEXP (op
, 0, 0)));
1784 /* Check, is base, or base + displacement. */
1786 if (GET_CODE (dest_addr
) == REG
)
1788 else if (GET_CODE (dest_addr
) == PLUS
1789 && GET_CODE (XEXP (dest_addr
, 0)) == REG
1790 && GET_CODE (XEXP (dest_addr
, 1)) == CONST_INT
)
1792 off
= INTVAL (XEXP (dest_addr
, 1));
1793 dest_addr
= XEXP (dest_addr
, 0);
1798 for (i
= 1; i
< count
; i
++)
1800 rtx elt
= XVECEXP (op
, 0, i
);
1802 if (GET_CODE (elt
) != SET
1803 || GET_CODE (SET_SRC (elt
)) != REG
1804 || GET_MODE (SET_SRC (elt
)) != elt_mode
1805 || REGNO (SET_SRC (elt
)) != src_regno
+ i
1806 || GET_CODE (SET_DEST (elt
)) != MEM
1807 || GET_MODE (SET_DEST (elt
)) != elt_mode
1808 || GET_CODE (XEXP (SET_DEST (elt
), 0)) != PLUS
1809 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt
), 0), 0), dest_addr
)
1810 || GET_CODE (XEXP (XEXP (SET_DEST (elt
), 0), 1)) != CONST_INT
1811 || INTVAL (XEXP (XEXP (SET_DEST (elt
), 0), 1))
1812 != off
+ i
* GET_MODE_SIZE (elt_mode
))
1819 /* Return true if OP contains a symbol reference */
1822 symbolic_reference_mentioned_p (rtx op
)
1824 register const char *fmt
;
1827 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
1830 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
1831 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
1837 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
1838 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
1842 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
1849 /* Return true if OP contains a reference to a thread-local symbol. */
1852 tls_symbolic_reference_mentioned_p (rtx op
)
1854 register const char *fmt
;
1857 if (GET_CODE (op
) == SYMBOL_REF
)
1858 return tls_symbolic_operand (op
);
1860 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
1861 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
1867 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
1868 if (tls_symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
1872 else if (fmt
[i
] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op
, i
)))
1880 /* Return true if OP is a legitimate general operand when
1881 generating PIC code. It is given that flag_pic is on
1882 and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
1885 legitimate_pic_operand_p (register rtx op
)
1887 /* Accept all non-symbolic constants. */
1888 if (!SYMBOLIC_CONST (op
))
1891 /* Reject everything else; must be handled
1892 via emit_symbolic_move. */
1896 /* Returns true if the constant value OP is a legitimate general operand.
1897 It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
1900 legitimate_constant_p (register rtx op
)
1902 /* Accept all non-symbolic constants. */
1903 if (!SYMBOLIC_CONST (op
))
1906 /* Accept immediate LARL operands. */
1907 if (TARGET_CPU_ZARCH
&& larl_operand (op
, VOIDmode
))
1910 /* Thread-local symbols are never legal constants. This is
1911 so that emit_call knows that computing such addresses
1912 might require a function call. */
1913 if (TLS_SYMBOLIC_CONST (op
))
1916 /* In the PIC case, symbolic constants must *not* be
1917 forced into the literal pool. We accept them here,
1918 so that they will be handled by emit_symbolic_move. */
1922 /* All remaining non-PIC symbolic constants are
1923 forced into the literal pool. */
1927 /* Determine if it's legal to put X into the constant pool. This
1928 is not possible if X contains the address of a symbol that is
1929 not constant (TLS) or not known at final link time (PIC). */
1932 s390_cannot_force_const_mem (rtx x
)
1934 switch (GET_CODE (x
))
1938 /* Accept all non-symbolic constants. */
1942 /* Labels are OK iff we are non-PIC. */
1943 return flag_pic
!= 0;
1946 /* 'Naked' TLS symbol references are never OK,
1947 non-TLS symbols are OK iff we are non-PIC. */
1948 if (tls_symbolic_operand (x
))
1951 return flag_pic
!= 0;
1954 return s390_cannot_force_const_mem (XEXP (x
, 0));
1957 return s390_cannot_force_const_mem (XEXP (x
, 0))
1958 || s390_cannot_force_const_mem (XEXP (x
, 1));
1961 switch (XINT (x
, 1))
1963 /* Only lt-relative or GOT-relative UNSPECs are OK. */
1964 case UNSPEC_LTREL_OFFSET
:
1972 case UNSPEC_GOTNTPOFF
:
1973 case UNSPEC_INDNTPOFF
:
1986 /* Returns true if the constant value OP is a legitimate general
1987 operand during and after reload. The difference to
1988 legitimate_constant_p is that this function will not accept
1989 a constant that would need to be forced to the literal pool
1990 before it can be used as operand. */
1993 legitimate_reload_constant_p (register rtx op
)
1995 /* Accept la(y) operands. */
1996 if (GET_CODE (op
) == CONST_INT
1997 && DISP_IN_RANGE (INTVAL (op
)))
2000 /* Accept l(g)hi operands. */
2001 if (GET_CODE (op
) == CONST_INT
2002 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op
), 'K', "K"))
2005 /* Accept lliXX operands. */
2007 && s390_single_part (op
, DImode
, HImode
, 0) >= 0)
2010 /* Accept larl operands. */
2011 if (TARGET_CPU_ZARCH
2012 && larl_operand (op
, VOIDmode
))
2015 /* Everything else cannot be handled without reload. */
2019 /* Given an rtx OP being reloaded into a reg required to be in class CLASS,
2020 return the class of reg to actually use. */
2023 s390_preferred_reload_class (rtx op
, enum reg_class
class)
2025 /* This can happen if a floating point constant is being
2026 reloaded into an integer register. Leave well alone. */
2027 if (GET_MODE_CLASS (GET_MODE (op
)) == MODE_FLOAT
2028 && class != FP_REGS
)
2031 switch (GET_CODE (op
))
2033 /* Constants we cannot reload must be forced into the
2038 if (legitimate_reload_constant_p (op
))
2043 /* If a symbolic constant or a PLUS is reloaded,
2044 it is most likely being used as an address, so
2045 prefer ADDR_REGS. If 'class' is not a superset
2046 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
2051 if (reg_class_subset_p (ADDR_REGS
, class))
2063 /* Return the register class of a scratch register needed to
2064 load IN into a register of class CLASS in MODE.
2066 We need a temporary when loading a PLUS expression which
2067 is not a legitimate operand of the LOAD ADDRESS instruction. */
2070 s390_secondary_input_reload_class (enum reg_class
class ATTRIBUTE_UNUSED
,
2071 enum machine_mode mode
, rtx in
)
2073 if (s390_plus_operand (in
, mode
))
2079 /* Return the register class of a scratch register needed to
2080 store a register of class CLASS in MODE into OUT:
2082 We need a temporary when storing a double-word to a
2083 non-offsettable memory address. */
2086 s390_secondary_output_reload_class (enum reg_class
class,
2087 enum machine_mode mode
, rtx out
)
2089 if ((TARGET_64BIT
? mode
== TImode
2090 : (mode
== DImode
|| mode
== DFmode
))
2091 && reg_classes_intersect_p (GENERAL_REGS
, class)
2092 && GET_CODE (out
) == MEM
2093 && !offsettable_memref_p (out
)
2094 && !s_operand (out
, VOIDmode
))
2100 /* Return true if OP is a PLUS that is not a legitimate
2101 operand for the LA instruction.
2102 OP is the current operation.
2103 MODE is the current operation mode. */
2106 s390_plus_operand (register rtx op
, enum machine_mode mode
)
2108 if (!check_mode (op
, &mode
) || mode
!= Pmode
)
2111 if (GET_CODE (op
) != PLUS
)
2114 if (legitimate_la_operand_p (op
))
2120 /* Generate code to load SRC, which is PLUS that is not a
2121 legitimate operand for the LA instruction, into TARGET.
2122 SCRATCH may be used as scratch register. */
2125 s390_expand_plus_operand (register rtx target
, register rtx src
,
2126 register rtx scratch
)
2129 struct s390_address ad
;
2131 /* src must be a PLUS; get its two operands. */
2132 if (GET_CODE (src
) != PLUS
|| GET_MODE (src
) != Pmode
)
2135 /* Check if any of the two operands is already scheduled
2136 for replacement by reload. This can happen e.g. when
2137 float registers occur in an address. */
2138 sum1
= find_replacement (&XEXP (src
, 0));
2139 sum2
= find_replacement (&XEXP (src
, 1));
2140 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
2142 /* If the address is already strictly valid, there's nothing to do. */
2143 if (!s390_decompose_address (src
, &ad
)
2144 || (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
2145 || (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
)))
2147 /* Otherwise, one of the operands cannot be an address register;
2148 we reload its value into the scratch register. */
2149 if (true_regnum (sum1
) < 1 || true_regnum (sum1
) > 15)
2151 emit_move_insn (scratch
, sum1
);
2154 if (true_regnum (sum2
) < 1 || true_regnum (sum2
) > 15)
2156 emit_move_insn (scratch
, sum2
);
2160 /* According to the way these invalid addresses are generated
2161 in reload.c, it should never happen (at least on s390) that
2162 *neither* of the PLUS components, after find_replacements
2163 was applied, is an address register. */
2164 if (sum1
== scratch
&& sum2
== scratch
)
2170 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
2173 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
2174 is only ever performed on addresses, so we can mark the
2175 sum as legitimate for LA in any case. */
2176 s390_load_address (target
, src
);
2180 /* Decompose a RTL expression ADDR for a memory address into
2181 its components, returned in OUT.
2183 Returns 0 if ADDR is not a valid memory address, nonzero
2184 otherwise. If OUT is NULL, don't return the components,
2185 but check for validity only.
2187 Note: Only addresses in canonical form are recognized.
2188 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
2189 canonical form so that they will be recognized. */
2192 s390_decompose_address (register rtx addr
, struct s390_address
*out
)
2194 HOST_WIDE_INT offset
= 0;
2195 rtx base
= NULL_RTX
;
2196 rtx indx
= NULL_RTX
;
2197 rtx disp
= NULL_RTX
;
2199 int pointer
= FALSE
;
2200 int base_ptr
= FALSE
;
2201 int indx_ptr
= FALSE
;
2203 /* Decompose address into base + index + displacement. */
2205 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == UNSPEC
)
2208 else if (GET_CODE (addr
) == PLUS
)
2210 rtx op0
= XEXP (addr
, 0);
2211 rtx op1
= XEXP (addr
, 1);
2212 enum rtx_code code0
= GET_CODE (op0
);
2213 enum rtx_code code1
= GET_CODE (op1
);
2215 if (code0
== REG
|| code0
== UNSPEC
)
2217 if (code1
== REG
|| code1
== UNSPEC
)
2219 indx
= op0
; /* index + base */
2225 base
= op0
; /* base + displacement */
2230 else if (code0
== PLUS
)
2232 indx
= XEXP (op0
, 0); /* index + base + disp */
2233 base
= XEXP (op0
, 1);
2244 disp
= addr
; /* displacement */
2246 /* Extract integer part of displacement. */
2250 if (GET_CODE (disp
) == CONST_INT
)
2252 offset
= INTVAL (disp
);
2255 else if (GET_CODE (disp
) == CONST
2256 && GET_CODE (XEXP (disp
, 0)) == PLUS
2257 && GET_CODE (XEXP (XEXP (disp
, 0), 1)) == CONST_INT
)
2259 offset
= INTVAL (XEXP (XEXP (disp
, 0), 1));
2260 disp
= XEXP (XEXP (disp
, 0), 0);
2264 /* Strip off CONST here to avoid special case tests later. */
2265 if (disp
&& GET_CODE (disp
) == CONST
)
2266 disp
= XEXP (disp
, 0);
2268 /* We can convert literal pool addresses to
2269 displacements by basing them off the base register. */
2270 if (disp
&& GET_CODE (disp
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (disp
))
2272 /* Either base or index must be free to hold the base register. */
2274 base
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
2276 indx
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
2280 /* Mark up the displacement. */
2281 disp
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, disp
),
2282 UNSPEC_LTREL_OFFSET
);
2285 /* Validate base register. */
2288 if (GET_CODE (base
) == UNSPEC
)
2289 switch (XINT (base
, 1))
2293 disp
= gen_rtx_UNSPEC (Pmode
,
2294 gen_rtvec (1, XVECEXP (base
, 0, 0)),
2295 UNSPEC_LTREL_OFFSET
);
2299 base
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
2302 case UNSPEC_LTREL_BASE
:
2303 base
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
2310 if (GET_CODE (base
) != REG
|| GET_MODE (base
) != Pmode
)
2313 if (REGNO (base
) == BASE_REGNUM
2314 || REGNO (base
) == STACK_POINTER_REGNUM
2315 || REGNO (base
) == FRAME_POINTER_REGNUM
2316 || ((reload_completed
|| reload_in_progress
)
2317 && frame_pointer_needed
2318 && REGNO (base
) == HARD_FRAME_POINTER_REGNUM
)
2319 || REGNO (base
) == ARG_POINTER_REGNUM
2321 && REGNO (base
) == PIC_OFFSET_TABLE_REGNUM
))
2322 pointer
= base_ptr
= TRUE
;
2325 /* Validate index register. */
2328 if (GET_CODE (indx
) == UNSPEC
)
2329 switch (XINT (indx
, 1))
2333 disp
= gen_rtx_UNSPEC (Pmode
,
2334 gen_rtvec (1, XVECEXP (indx
, 0, 0)),
2335 UNSPEC_LTREL_OFFSET
);
2339 indx
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
2342 case UNSPEC_LTREL_BASE
:
2343 indx
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
2350 if (GET_CODE (indx
) != REG
|| GET_MODE (indx
) != Pmode
)
2353 if (REGNO (indx
) == BASE_REGNUM
2354 || REGNO (indx
) == STACK_POINTER_REGNUM
2355 || REGNO (indx
) == FRAME_POINTER_REGNUM
2356 || ((reload_completed
|| reload_in_progress
)
2357 && frame_pointer_needed
2358 && REGNO (indx
) == HARD_FRAME_POINTER_REGNUM
)
2359 || REGNO (indx
) == ARG_POINTER_REGNUM
2361 && REGNO (indx
) == PIC_OFFSET_TABLE_REGNUM
))
2362 pointer
= indx_ptr
= TRUE
;
2365 /* Prefer to use pointer as base, not index. */
2366 if (base
&& indx
&& !base_ptr
2367 && (indx_ptr
|| (!REG_POINTER (base
) && REG_POINTER (indx
))))
2374 /* Validate displacement. */
2377 /* If the argument pointer or the return address pointer are involved,
2378 the displacement will change later anyway as the virtual registers get
2379 eliminated. This could make a valid displacement invalid, but it is
2380 more likely to make an invalid displacement valid, because we sometimes
2381 access the register save area via negative offsets to one of those
2383 Thus we don't check the displacement for validity here. If after
2384 elimination the displacement turns out to be invalid after all,
2385 this is fixed up by reload in any case. */
2386 if (base
!= arg_pointer_rtx
2387 && indx
!= arg_pointer_rtx
2388 && base
!= return_address_pointer_rtx
2389 && indx
!= return_address_pointer_rtx
)
2390 if (!DISP_IN_RANGE (offset
))
2395 /* All the special cases are pointers. */
2398 /* In the small-PIC case, the linker converts @GOT
2399 and @GOTNTPOFF offsets to possible displacements. */
2400 if (GET_CODE (disp
) == UNSPEC
2401 && (XINT (disp
, 1) == UNSPEC_GOT
2402 || XINT (disp
, 1) == UNSPEC_GOTNTPOFF
)
2409 /* Accept chunkified literal pool symbol references. */
2410 else if (GET_CODE (disp
) == MINUS
2411 && GET_CODE (XEXP (disp
, 0)) == LABEL_REF
2412 && GET_CODE (XEXP (disp
, 1)) == LABEL_REF
)
2417 /* Accept literal pool references. */
2418 else if (GET_CODE (disp
) == UNSPEC
2419 && XINT (disp
, 1) == UNSPEC_LTREL_OFFSET
)
2421 orig_disp
= gen_rtx_CONST (Pmode
, disp
);
2424 /* If we have an offset, make sure it does not
2425 exceed the size of the constant pool entry. */
2426 rtx sym
= XVECEXP (disp
, 0, 0);
2427 if (offset
>= GET_MODE_SIZE (get_pool_mode (sym
)))
2430 orig_disp
= plus_constant (orig_disp
, offset
);
2445 out
->disp
= orig_disp
;
2446 out
->pointer
= pointer
;
2452 /* Return nonzero if ADDR is a valid memory address.
2453 STRICT specifies whether strict register checking applies. */
2456 legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED
,
2457 register rtx addr
, int strict
)
2459 struct s390_address ad
;
2460 if (!s390_decompose_address (addr
, &ad
))
2465 if (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
2467 if (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
))
2472 if (ad
.base
&& !REG_OK_FOR_BASE_NONSTRICT_P (ad
.base
))
2474 if (ad
.indx
&& !REG_OK_FOR_INDEX_NONSTRICT_P (ad
.indx
))
2481 /* Return 1 if OP is a valid operand for the LA instruction.
2482 In 31-bit, we need to prove that the result is used as an
2483 address, as LA performs only a 31-bit addition. */
2486 legitimate_la_operand_p (register rtx op
)
2488 struct s390_address addr
;
2489 if (!s390_decompose_address (op
, &addr
))
2492 if (TARGET_64BIT
|| addr
.pointer
)
2498 /* Return 1 if OP is a valid operand for the LA instruction,
2499 and we prefer to use LA over addition to compute it. */
2502 preferred_la_operand_p (register rtx op
)
2504 struct s390_address addr
;
2505 if (!s390_decompose_address (op
, &addr
))
2508 if (!TARGET_64BIT
&& !addr
.pointer
)
2514 if ((addr
.base
&& REG_P (addr
.base
) && REG_POINTER (addr
.base
))
2515 || (addr
.indx
&& REG_P (addr
.indx
) && REG_POINTER (addr
.indx
)))
2521 /* Emit a forced load-address operation to load SRC into DST.
2522 This will use the LOAD ADDRESS instruction even in situations
2523 where legitimate_la_operand_p (SRC) returns false. */
2526 s390_load_address (rtx dst
, rtx src
)
2529 emit_move_insn (dst
, src
);
2531 emit_insn (gen_force_la_31 (dst
, src
));
2534 /* Return a legitimate reference for ORIG (an address) using the
2535 register REG. If REG is 0, a new pseudo is generated.
2537 There are two types of references that must be handled:
2539 1. Global data references must load the address from the GOT, via
2540 the PIC reg. An insn is emitted to do this load, and the reg is
2543 2. Static data references, constant pool addresses, and code labels
2544 compute the address as an offset from the GOT, whose base is in
2545 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
2546 differentiate them from global data objects. The returned
2547 address is the PIC reg + an unspec constant.
2549 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2550 reg also appears in the address. */
2553 legitimize_pic_address (rtx orig
, rtx reg
)
2559 if (GET_CODE (addr
) == LABEL_REF
2560 || (GET_CODE (addr
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (addr
)))
2562 /* This is a local symbol. */
2563 if (TARGET_CPU_ZARCH
&& larl_operand (addr
, VOIDmode
))
2565 /* Access local symbols PC-relative via LARL.
2566 This is the same as in the non-PIC case, so it is
2567 handled automatically ... */
2571 /* Access local symbols relative to the GOT. */
2573 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2575 if (reload_in_progress
|| reload_completed
)
2576 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2578 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTOFF
);
2579 addr
= gen_rtx_CONST (Pmode
, addr
);
2580 addr
= force_const_mem (Pmode
, addr
);
2581 emit_move_insn (temp
, addr
);
2583 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2586 emit_move_insn (reg
, new);
2591 else if (GET_CODE (addr
) == SYMBOL_REF
)
2594 reg
= gen_reg_rtx (Pmode
);
2598 /* Assume GOT offset < 4k. This is handled the same way
2599 in both 31- and 64-bit code (@GOT). */
2601 if (reload_in_progress
|| reload_completed
)
2602 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2604 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
2605 new = gen_rtx_CONST (Pmode
, new);
2606 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new);
2607 new = gen_rtx_MEM (Pmode
, new);
2608 MEM_READONLY_P (new) = 1;
2609 emit_move_insn (reg
, new);
2612 else if (TARGET_CPU_ZARCH
)
2614 /* If the GOT offset might be >= 4k, we determine the position
2615 of the GOT entry via a PC-relative LARL (@GOTENT). */
2617 rtx temp
= gen_reg_rtx (Pmode
);
2619 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTENT
);
2620 new = gen_rtx_CONST (Pmode
, new);
2621 emit_move_insn (temp
, new);
2623 new = gen_rtx_MEM (Pmode
, temp
);
2624 MEM_READONLY_P (new) = 1;
2625 emit_move_insn (reg
, new);
2630 /* If the GOT offset might be >= 4k, we have to load it
2631 from the literal pool (@GOT). */
2633 rtx temp
= gen_reg_rtx (Pmode
);
2635 if (reload_in_progress
|| reload_completed
)
2636 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2638 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
2639 addr
= gen_rtx_CONST (Pmode
, addr
);
2640 addr
= force_const_mem (Pmode
, addr
);
2641 emit_move_insn (temp
, addr
);
2643 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2644 new = gen_rtx_MEM (Pmode
, new);
2645 MEM_READONLY_P (new) = 1;
2646 emit_move_insn (reg
, new);
2652 if (GET_CODE (addr
) == CONST
)
2654 addr
= XEXP (addr
, 0);
2655 if (GET_CODE (addr
) == UNSPEC
)
2657 if (XVECLEN (addr
, 0) != 1)
2659 switch (XINT (addr
, 1))
2661 /* If someone moved a GOT-relative UNSPEC
2662 out of the literal pool, force them back in. */
2665 new = force_const_mem (Pmode
, orig
);
2668 /* @GOT is OK as is if small. */
2671 new = force_const_mem (Pmode
, orig
);
2674 /* @GOTENT is OK as is. */
2678 /* @PLT is OK as is on 64-bit, must be converted to
2679 GOT-relative @PLTOFF on 31-bit. */
2681 if (!TARGET_CPU_ZARCH
)
2683 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2685 if (reload_in_progress
|| reload_completed
)
2686 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2688 addr
= XVECEXP (addr
, 0, 0);
2689 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
),
2691 addr
= gen_rtx_CONST (Pmode
, addr
);
2692 addr
= force_const_mem (Pmode
, addr
);
2693 emit_move_insn (temp
, addr
);
2695 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2698 emit_move_insn (reg
, new);
2704 /* Everything else cannot happen. */
2709 else if (GET_CODE (addr
) != PLUS
)
2712 if (GET_CODE (addr
) == PLUS
)
2714 rtx op0
= XEXP (addr
, 0), op1
= XEXP (addr
, 1);
2715 /* Check first to see if this is a constant offset
2716 from a local symbol reference. */
2717 if ((GET_CODE (op0
) == LABEL_REF
2718 || (GET_CODE (op0
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (op0
)))
2719 && GET_CODE (op1
) == CONST_INT
)
2721 if (TARGET_CPU_ZARCH
&& larl_operand (op0
, VOIDmode
))
2723 if (INTVAL (op1
) & 1)
2725 /* LARL can't handle odd offsets, so emit a
2726 pair of LARL and LA. */
2727 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2729 if (!DISP_IN_RANGE (INTVAL (op1
)))
2731 int even
= INTVAL (op1
) - 1;
2732 op0
= gen_rtx_PLUS (Pmode
, op0
, GEN_INT (even
));
2733 op0
= gen_rtx_CONST (Pmode
, op0
);
2737 emit_move_insn (temp
, op0
);
2738 new = gen_rtx_PLUS (Pmode
, temp
, op1
);
2742 emit_move_insn (reg
, new);
2748 /* If the offset is even, we can just use LARL.
2749 This will happen automatically. */
2754 /* Access local symbols relative to the GOT. */
2756 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2758 if (reload_in_progress
|| reload_completed
)
2759 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2761 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op0
),
2763 addr
= gen_rtx_PLUS (Pmode
, addr
, op1
);
2764 addr
= gen_rtx_CONST (Pmode
, addr
);
2765 addr
= force_const_mem (Pmode
, addr
);
2766 emit_move_insn (temp
, addr
);
2768 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2771 emit_move_insn (reg
, new);
2777 /* Now, check whether it is a GOT relative symbol plus offset
2778 that was pulled out of the literal pool. Force it back in. */
2780 else if (GET_CODE (op0
) == UNSPEC
2781 && GET_CODE (op1
) == CONST_INT
2782 && XINT (op0
, 1) == UNSPEC_GOTOFF
)
2784 if (XVECLEN (op0
, 0) != 1)
2787 new = force_const_mem (Pmode
, orig
);
2790 /* Otherwise, compute the sum. */
2793 base
= legitimize_pic_address (XEXP (addr
, 0), reg
);
2794 new = legitimize_pic_address (XEXP (addr
, 1),
2795 base
== reg
? NULL_RTX
: reg
);
2796 if (GET_CODE (new) == CONST_INT
)
2797 new = plus_constant (base
, INTVAL (new));
2800 if (GET_CODE (new) == PLUS
&& CONSTANT_P (XEXP (new, 1)))
2802 base
= gen_rtx_PLUS (Pmode
, base
, XEXP (new, 0));
2803 new = XEXP (new, 1);
2805 new = gen_rtx_PLUS (Pmode
, base
, new);
2808 if (GET_CODE (new) == CONST
)
2809 new = XEXP (new, 0);
2810 new = force_operand (new, 0);
2817 /* Load the thread pointer into a register. */
2820 get_thread_pointer (void)
2824 tp
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TP
);
2825 tp
= force_reg (Pmode
, tp
);
2826 mark_reg_pointer (tp
, BITS_PER_WORD
);
2831 /* Emit a tls call insn. The call target is the SYMBOL_REF stored
2832 in s390_tls_symbol which always refers to __tls_get_offset.
2833 The returned offset is written to RESULT_REG and an USE rtx is
2834 generated for TLS_CALL. */
2836 static GTY(()) rtx s390_tls_symbol
;
2839 s390_emit_tls_call_insn (rtx result_reg
, rtx tls_call
)
2846 if (!s390_tls_symbol
)
2847 s390_tls_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "__tls_get_offset");
2849 insn
= s390_emit_call (s390_tls_symbol
, tls_call
, result_reg
,
2850 gen_rtx_REG (Pmode
, RETURN_REGNUM
));
2852 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), result_reg
);
2853 CONST_OR_PURE_CALL_P (insn
) = 1;
2856 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
2857 this (thread-local) address. REG may be used as temporary. */
2860 legitimize_tls_address (rtx addr
, rtx reg
)
2862 rtx
new, tls_call
, temp
, base
, r2
, insn
;
2864 if (GET_CODE (addr
) == SYMBOL_REF
)
2865 switch (tls_symbolic_operand (addr
))
2867 case TLS_MODEL_GLOBAL_DYNAMIC
:
2869 r2
= gen_rtx_REG (Pmode
, 2);
2870 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_TLSGD
);
2871 new = gen_rtx_CONST (Pmode
, tls_call
);
2872 new = force_const_mem (Pmode
, new);
2873 emit_move_insn (r2
, new);
2874 s390_emit_tls_call_insn (r2
, tls_call
);
2875 insn
= get_insns ();
2878 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
2879 temp
= gen_reg_rtx (Pmode
);
2880 emit_libcall_block (insn
, temp
, r2
, new);
2882 new = gen_rtx_PLUS (Pmode
, get_thread_pointer (), temp
);
2885 s390_load_address (reg
, new);
2890 case TLS_MODEL_LOCAL_DYNAMIC
:
2892 r2
= gen_rtx_REG (Pmode
, 2);
2893 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM
);
2894 new = gen_rtx_CONST (Pmode
, tls_call
);
2895 new = force_const_mem (Pmode
, new);
2896 emit_move_insn (r2
, new);
2897 s390_emit_tls_call_insn (r2
, tls_call
);
2898 insn
= get_insns ();
2901 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM_NTPOFF
);
2902 temp
= gen_reg_rtx (Pmode
);
2903 emit_libcall_block (insn
, temp
, r2
, new);
2905 new = gen_rtx_PLUS (Pmode
, get_thread_pointer (), temp
);
2906 base
= gen_reg_rtx (Pmode
);
2907 s390_load_address (base
, new);
2909 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_DTPOFF
);
2910 new = gen_rtx_CONST (Pmode
, new);
2911 new = force_const_mem (Pmode
, new);
2912 temp
= gen_reg_rtx (Pmode
);
2913 emit_move_insn (temp
, new);
2915 new = gen_rtx_PLUS (Pmode
, base
, temp
);
2918 s390_load_address (reg
, new);
2923 case TLS_MODEL_INITIAL_EXEC
:
2926 /* Assume GOT offset < 4k. This is handled the same way
2927 in both 31- and 64-bit code. */
2929 if (reload_in_progress
|| reload_completed
)
2930 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2932 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
2933 new = gen_rtx_CONST (Pmode
, new);
2934 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new);
2935 new = gen_rtx_MEM (Pmode
, new);
2936 MEM_READONLY_P (new) = 1;
2937 temp
= gen_reg_rtx (Pmode
);
2938 emit_move_insn (temp
, new);
2940 else if (TARGET_CPU_ZARCH
)
2942 /* If the GOT offset might be >= 4k, we determine the position
2943 of the GOT entry via a PC-relative LARL. */
2945 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
2946 new = gen_rtx_CONST (Pmode
, new);
2947 temp
= gen_reg_rtx (Pmode
);
2948 emit_move_insn (temp
, new);
2950 new = gen_rtx_MEM (Pmode
, temp
);
2951 MEM_READONLY_P (new) = 1;
2952 temp
= gen_reg_rtx (Pmode
);
2953 emit_move_insn (temp
, new);
2957 /* If the GOT offset might be >= 4k, we have to load it
2958 from the literal pool. */
2960 if (reload_in_progress
|| reload_completed
)
2961 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2963 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
2964 new = gen_rtx_CONST (Pmode
, new);
2965 new = force_const_mem (Pmode
, new);
2966 temp
= gen_reg_rtx (Pmode
);
2967 emit_move_insn (temp
, new);
2969 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2970 new = gen_rtx_MEM (Pmode
, new);
2971 MEM_READONLY_P (new) = 1;
2973 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new, addr
), UNSPEC_TLS_LOAD
);
2974 temp
= gen_reg_rtx (Pmode
);
2975 emit_insn (gen_rtx_SET (Pmode
, temp
, new));
2979 /* In position-dependent code, load the absolute address of
2980 the GOT entry from the literal pool. */
2982 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
2983 new = gen_rtx_CONST (Pmode
, new);
2984 new = force_const_mem (Pmode
, new);
2985 temp
= gen_reg_rtx (Pmode
);
2986 emit_move_insn (temp
, new);
2989 new = gen_rtx_MEM (Pmode
, new);
2990 MEM_READONLY_P (new) = 1;
2992 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new, addr
), UNSPEC_TLS_LOAD
);
2993 temp
= gen_reg_rtx (Pmode
);
2994 emit_insn (gen_rtx_SET (Pmode
, temp
, new));
2997 new = gen_rtx_PLUS (Pmode
, get_thread_pointer (), temp
);
3000 s390_load_address (reg
, new);
3005 case TLS_MODEL_LOCAL_EXEC
:
3006 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
3007 new = gen_rtx_CONST (Pmode
, new);
3008 new = force_const_mem (Pmode
, new);
3009 temp
= gen_reg_rtx (Pmode
);
3010 emit_move_insn (temp
, new);
3012 new = gen_rtx_PLUS (Pmode
, get_thread_pointer (), temp
);
3015 s390_load_address (reg
, new);
3024 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == UNSPEC
)
3026 switch (XINT (XEXP (addr
, 0), 1))
3028 case UNSPEC_INDNTPOFF
:
3029 if (TARGET_CPU_ZARCH
)
3040 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == PLUS
3041 && GET_CODE (XEXP (XEXP (addr
, 0), 1)) == CONST_INT
)
3043 new = XEXP (XEXP (addr
, 0), 0);
3044 if (GET_CODE (new) != SYMBOL_REF
)
3045 new = gen_rtx_CONST (Pmode
, new);
3047 new = legitimize_tls_address (new, reg
);
3048 new = plus_constant (new, INTVAL (XEXP (XEXP (addr
, 0), 1)));
3049 new = force_operand (new, 0);
3053 abort (); /* for now ... */
3058 /* Emit insns to move operands[1] into operands[0]. */
3061 emit_symbolic_move (rtx
*operands
)
3063 rtx temp
= no_new_pseudos
? operands
[0] : gen_reg_rtx (Pmode
);
3065 if (GET_CODE (operands
[0]) == MEM
)
3066 operands
[1] = force_reg (Pmode
, operands
[1]);
3067 else if (TLS_SYMBOLIC_CONST (operands
[1]))
3068 operands
[1] = legitimize_tls_address (operands
[1], temp
);
3070 operands
[1] = legitimize_pic_address (operands
[1], temp
);
3073 /* Try machine-dependent ways of modifying an illegitimate address X
3074 to be legitimate. If we find one, return the new, valid address.
3076 OLDX is the address as it was before break_out_memory_refs was called.
3077 In some cases it is useful to look at this to decide what needs to be done.
3079 MODE is the mode of the operand pointed to by X.
3081 When -fpic is used, special handling is needed for symbolic references.
3082 See comments by legitimize_pic_address for details. */
3085 legitimize_address (register rtx x
, register rtx oldx ATTRIBUTE_UNUSED
,
3086 enum machine_mode mode ATTRIBUTE_UNUSED
)
3088 rtx constant_term
= const0_rtx
;
3090 if (TLS_SYMBOLIC_CONST (x
))
3092 x
= legitimize_tls_address (x
, 0);
3094 if (legitimate_address_p (mode
, x
, FALSE
))
3099 if (SYMBOLIC_CONST (x
)
3100 || (GET_CODE (x
) == PLUS
3101 && (SYMBOLIC_CONST (XEXP (x
, 0))
3102 || SYMBOLIC_CONST (XEXP (x
, 1)))))
3103 x
= legitimize_pic_address (x
, 0);
3105 if (legitimate_address_p (mode
, x
, FALSE
))
3109 x
= eliminate_constant_term (x
, &constant_term
);
3111 /* Optimize loading of large displacements by splitting them
3112 into the multiple of 4K and the rest; this allows the
3113 former to be CSE'd if possible.
3115 Don't do this if the displacement is added to a register
3116 pointing into the stack frame, as the offsets will
3117 change later anyway. */
3119 if (GET_CODE (constant_term
) == CONST_INT
3120 && !TARGET_LONG_DISPLACEMENT
3121 && !DISP_IN_RANGE (INTVAL (constant_term
))
3122 && !(REG_P (x
) && REGNO_PTR_FRAME_P (REGNO (x
))))
3124 HOST_WIDE_INT lower
= INTVAL (constant_term
) & 0xfff;
3125 HOST_WIDE_INT upper
= INTVAL (constant_term
) ^ lower
;
3127 rtx temp
= gen_reg_rtx (Pmode
);
3128 rtx val
= force_operand (GEN_INT (upper
), temp
);
3130 emit_move_insn (temp
, val
);
3132 x
= gen_rtx_PLUS (Pmode
, x
, temp
);
3133 constant_term
= GEN_INT (lower
);
3136 if (GET_CODE (x
) == PLUS
)
3138 if (GET_CODE (XEXP (x
, 0)) == REG
)
3140 register rtx temp
= gen_reg_rtx (Pmode
);
3141 register rtx val
= force_operand (XEXP (x
, 1), temp
);
3143 emit_move_insn (temp
, val
);
3145 x
= gen_rtx_PLUS (Pmode
, XEXP (x
, 0), temp
);
3148 else if (GET_CODE (XEXP (x
, 1)) == REG
)
3150 register rtx temp
= gen_reg_rtx (Pmode
);
3151 register rtx val
= force_operand (XEXP (x
, 0), temp
);
3153 emit_move_insn (temp
, val
);
3155 x
= gen_rtx_PLUS (Pmode
, temp
, XEXP (x
, 1));
3159 if (constant_term
!= const0_rtx
)
3160 x
= gen_rtx_PLUS (Pmode
, x
, constant_term
);
3165 /* Emit code to move LEN bytes from DST to SRC. */
3168 s390_expand_movmem (rtx dst
, rtx src
, rtx len
)
3170 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3172 if (INTVAL (len
) > 0)
3173 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (INTVAL (len
) - 1)));
3176 else if (TARGET_MVCLE
)
3178 emit_insn (gen_movmem_long (dst
, src
, convert_to_mode (Pmode
, len
, 1)));
3183 rtx dst_addr
, src_addr
, count
, blocks
, temp
;
3184 rtx loop_start_label
= gen_label_rtx ();
3185 rtx loop_end_label
= gen_label_rtx ();
3186 rtx end_label
= gen_label_rtx ();
3187 enum machine_mode mode
;
3189 mode
= GET_MODE (len
);
3190 if (mode
== VOIDmode
)
3193 dst_addr
= gen_reg_rtx (Pmode
);
3194 src_addr
= gen_reg_rtx (Pmode
);
3195 count
= gen_reg_rtx (mode
);
3196 blocks
= gen_reg_rtx (mode
);
3198 convert_move (count
, len
, 1);
3199 emit_cmp_and_jump_insns (count
, const0_rtx
,
3200 EQ
, NULL_RTX
, mode
, 1, end_label
);
3202 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
3203 emit_move_insn (src_addr
, force_operand (XEXP (src
, 0), NULL_RTX
));
3204 dst
= change_address (dst
, VOIDmode
, dst_addr
);
3205 src
= change_address (src
, VOIDmode
, src_addr
);
3207 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3209 emit_move_insn (count
, temp
);
3211 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3213 emit_move_insn (blocks
, temp
);
3215 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3216 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3218 emit_label (loop_start_label
);
3220 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (255)));
3221 s390_load_address (dst_addr
,
3222 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
3223 s390_load_address (src_addr
,
3224 gen_rtx_PLUS (Pmode
, src_addr
, GEN_INT (256)));
3226 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3228 emit_move_insn (blocks
, temp
);
3230 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3231 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3233 emit_jump (loop_start_label
);
3234 emit_label (loop_end_label
);
3236 emit_insn (gen_movmem_short (dst
, src
,
3237 convert_to_mode (Pmode
, count
, 1)));
3238 emit_label (end_label
);
3242 /* Emit code to clear LEN bytes at DST. */
3245 s390_expand_clrmem (rtx dst
, rtx len
)
3247 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3249 if (INTVAL (len
) > 0)
3250 emit_insn (gen_clrmem_short (dst
, GEN_INT (INTVAL (len
) - 1)));
3253 else if (TARGET_MVCLE
)
3255 emit_insn (gen_clrmem_long (dst
, convert_to_mode (Pmode
, len
, 1)));
3260 rtx dst_addr
, src_addr
, count
, blocks
, temp
;
3261 rtx loop_start_label
= gen_label_rtx ();
3262 rtx loop_end_label
= gen_label_rtx ();
3263 rtx end_label
= gen_label_rtx ();
3264 enum machine_mode mode
;
3266 mode
= GET_MODE (len
);
3267 if (mode
== VOIDmode
)
3270 dst_addr
= gen_reg_rtx (Pmode
);
3271 src_addr
= gen_reg_rtx (Pmode
);
3272 count
= gen_reg_rtx (mode
);
3273 blocks
= gen_reg_rtx (mode
);
3275 convert_move (count
, len
, 1);
3276 emit_cmp_and_jump_insns (count
, const0_rtx
,
3277 EQ
, NULL_RTX
, mode
, 1, end_label
);
3279 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
3280 dst
= change_address (dst
, VOIDmode
, dst_addr
);
3282 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3284 emit_move_insn (count
, temp
);
3286 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3288 emit_move_insn (blocks
, temp
);
3290 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3291 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3293 emit_label (loop_start_label
);
3295 emit_insn (gen_clrmem_short (dst
, GEN_INT (255)));
3296 s390_load_address (dst_addr
,
3297 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
3299 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3301 emit_move_insn (blocks
, temp
);
3303 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3304 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3306 emit_jump (loop_start_label
);
3307 emit_label (loop_end_label
);
3309 emit_insn (gen_clrmem_short (dst
, convert_to_mode (Pmode
, count
, 1)));
3310 emit_label (end_label
);
3314 /* Emit code to compare LEN bytes at OP0 with those at OP1,
3315 and return the result in TARGET. */
3318 s390_expand_cmpmem (rtx target
, rtx op0
, rtx op1
, rtx len
)
3320 rtx (*gen_result
) (rtx
) =
3321 GET_MODE (target
) == DImode
? gen_cmpint_di
: gen_cmpint_si
;
3323 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3325 if (INTVAL (len
) > 0)
3327 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (INTVAL (len
) - 1)));
3328 emit_insn (gen_result (target
));
3331 emit_move_insn (target
, const0_rtx
);
3334 else /* if (TARGET_MVCLE) */
3336 emit_insn (gen_cmpmem_long (op0
, op1
, convert_to_mode (Pmode
, len
, 1)));
3337 emit_insn (gen_result (target
));
3341 /* Deactivate for now as profile code cannot cope with
3342 CC being live across basic block boundaries. */
3345 rtx addr0
, addr1
, count
, blocks
, temp
;
3346 rtx loop_start_label
= gen_label_rtx ();
3347 rtx loop_end_label
= gen_label_rtx ();
3348 rtx end_label
= gen_label_rtx ();
3349 enum machine_mode mode
;
3351 mode
= GET_MODE (len
);
3352 if (mode
== VOIDmode
)
3355 addr0
= gen_reg_rtx (Pmode
);
3356 addr1
= gen_reg_rtx (Pmode
);
3357 count
= gen_reg_rtx (mode
);
3358 blocks
= gen_reg_rtx (mode
);
3360 convert_move (count
, len
, 1);
3361 emit_cmp_and_jump_insns (count
, const0_rtx
,
3362 EQ
, NULL_RTX
, mode
, 1, end_label
);
3364 emit_move_insn (addr0
, force_operand (XEXP (op0
, 0), NULL_RTX
));
3365 emit_move_insn (addr1
, force_operand (XEXP (op1
, 0), NULL_RTX
));
3366 op0
= change_address (op0
, VOIDmode
, addr0
);
3367 op1
= change_address (op1
, VOIDmode
, addr1
);
3369 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3371 emit_move_insn (count
, temp
);
3373 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3375 emit_move_insn (blocks
, temp
);
3377 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3378 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3380 emit_label (loop_start_label
);
3382 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (255)));
3383 temp
= gen_rtx_NE (VOIDmode
, gen_rtx_REG (CCSmode
, 33), const0_rtx
);
3384 temp
= gen_rtx_IF_THEN_ELSE (VOIDmode
, temp
,
3385 gen_rtx_LABEL_REF (VOIDmode
, end_label
), pc_rtx
);
3386 temp
= gen_rtx_SET (VOIDmode
, pc_rtx
, temp
);
3387 emit_jump_insn (temp
);
3389 s390_load_address (addr0
,
3390 gen_rtx_PLUS (Pmode
, addr0
, GEN_INT (256)));
3391 s390_load_address (addr1
,
3392 gen_rtx_PLUS (Pmode
, addr1
, GEN_INT (256)));
3394 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3396 emit_move_insn (blocks
, temp
);
3398 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3399 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3401 emit_jump (loop_start_label
);
3402 emit_label (loop_end_label
);
3404 emit_insn (gen_cmpmem_short (op0
, op1
,
3405 convert_to_mode (Pmode
, count
, 1)));
3406 emit_label (end_label
);
3408 emit_insn (gen_result (target
));
3414 /* Expand conditional increment or decrement using alc/slb instructions.
3415 Should generate code setting DST to either SRC or SRC + INCREMENT,
3416 depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
3417 Returns true if successful, false otherwise. */
3420 s390_expand_addcc (enum rtx_code cmp_code
, rtx cmp_op0
, rtx cmp_op1
,
3421 rtx dst
, rtx src
, rtx increment
)
3423 enum machine_mode cmp_mode
;
3424 enum machine_mode cc_mode
;
3429 if ((GET_MODE (cmp_op0
) == SImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
3430 && (GET_MODE (cmp_op1
) == SImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
3432 else if ((GET_MODE (cmp_op0
) == DImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
3433 && (GET_MODE (cmp_op1
) == DImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
3438 /* Try ADD LOGICAL WITH CARRY. */
3439 if (increment
== const1_rtx
)
3441 /* Determine CC mode to use. */
3442 if (cmp_code
== EQ
|| cmp_code
== NE
)
3444 if (cmp_op1
!= const0_rtx
)
3446 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
3447 NULL_RTX
, 0, OPTAB_WIDEN
);
3448 cmp_op1
= const0_rtx
;
3451 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
3454 if (cmp_code
== LTU
|| cmp_code
== LEU
)
3459 cmp_code
= swap_condition (cmp_code
);
3476 /* Emit comparison instruction pattern. */
3477 if (!register_operand (cmp_op0
, cmp_mode
))
3478 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
3480 insn
= gen_rtx_SET (VOIDmode
, gen_rtx_REG (cc_mode
, CC_REGNUM
),
3481 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
3482 /* We use insn_invalid_p here to add clobbers if required. */
3483 if (insn_invalid_p (emit_insn (insn
)))
3486 /* Emit ALC instruction pattern. */
3487 op_res
= gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
3488 gen_rtx_REG (cc_mode
, CC_REGNUM
),
3491 if (src
!= const0_rtx
)
3493 if (!register_operand (src
, GET_MODE (dst
)))
3494 src
= force_reg (GET_MODE (dst
), src
);
3496 src
= gen_rtx_PLUS (GET_MODE (dst
), src
, const0_rtx
);
3497 op_res
= gen_rtx_PLUS (GET_MODE (dst
), src
, op_res
);
3500 p
= rtvec_alloc (2);
3502 gen_rtx_SET (VOIDmode
, dst
, op_res
);
3504 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
3505 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
3510 /* Try SUBTRACT LOGICAL WITH BORROW. */
3511 if (increment
== constm1_rtx
)
3513 /* Determine CC mode to use. */
3514 if (cmp_code
== EQ
|| cmp_code
== NE
)
3516 if (cmp_op1
!= const0_rtx
)
3518 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
3519 NULL_RTX
, 0, OPTAB_WIDEN
);
3520 cmp_op1
= const0_rtx
;
3523 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
3526 if (cmp_code
== GTU
|| cmp_code
== GEU
)
3531 cmp_code
= swap_condition (cmp_code
);
3548 /* Emit comparison instruction pattern. */
3549 if (!register_operand (cmp_op0
, cmp_mode
))
3550 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
3552 insn
= gen_rtx_SET (VOIDmode
, gen_rtx_REG (cc_mode
, CC_REGNUM
),
3553 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
3554 /* We use insn_invalid_p here to add clobbers if required. */
3555 if (insn_invalid_p (emit_insn (insn
)))
3558 /* Emit SLB instruction pattern. */
3559 if (!register_operand (src
, GET_MODE (dst
)))
3560 src
= force_reg (GET_MODE (dst
), src
);
3562 op_res
= gen_rtx_MINUS (GET_MODE (dst
),
3563 gen_rtx_MINUS (GET_MODE (dst
), src
, const0_rtx
),
3564 gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
3565 gen_rtx_REG (cc_mode
, CC_REGNUM
),
3567 p
= rtvec_alloc (2);
3569 gen_rtx_SET (VOIDmode
, dst
, op_res
);
3571 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
3572 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
3581 /* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
3582 We need to emit DTP-relative relocations. */
3585 s390_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
3590 fputs ("\t.long\t", file
);
3593 fputs ("\t.quad\t", file
);
3598 output_addr_const (file
, x
);
3599 fputs ("@DTPOFF", file
);
3602 /* In the name of slightly smaller debug output, and to cater to
3603 general assembler losage, recognize various UNSPEC sequences
3604 and turn them back into a direct symbol reference. */
3607 s390_delegitimize_address (rtx orig_x
)
3611 if (GET_CODE (x
) != MEM
)
3615 if (GET_CODE (x
) == PLUS
3616 && GET_CODE (XEXP (x
, 1)) == CONST
3617 && GET_CODE (XEXP (x
, 0)) == REG
3618 && REGNO (XEXP (x
, 0)) == PIC_OFFSET_TABLE_REGNUM
)
3620 y
= XEXP (XEXP (x
, 1), 0);
3621 if (GET_CODE (y
) == UNSPEC
3622 && XINT (y
, 1) == UNSPEC_GOT
)
3623 return XVECEXP (y
, 0, 0);
3627 if (GET_CODE (x
) == CONST
)
3630 if (GET_CODE (y
) == UNSPEC
3631 && XINT (y
, 1) == UNSPEC_GOTENT
)
3632 return XVECEXP (y
, 0, 0);
3639 /* Output shift count operand OP to stdio stream FILE. */
3642 print_shift_count_operand (FILE *file
, rtx op
)
3644 HOST_WIDE_INT offset
= 0;
3646 /* We can have an integer constant, an address register,
3647 or a sum of the two. */
3648 if (GET_CODE (op
) == CONST_INT
)
3650 offset
= INTVAL (op
);
3653 if (op
&& GET_CODE (op
) == PLUS
&& GET_CODE (XEXP (op
, 1)) == CONST_INT
)
3655 offset
= INTVAL (XEXP (op
, 1));
3658 while (op
&& GET_CODE (op
) == SUBREG
)
3659 op
= SUBREG_REG (op
);
3662 if (op
&& (GET_CODE (op
) != REG
3663 || REGNO (op
) >= FIRST_PSEUDO_REGISTER
3664 || REGNO_REG_CLASS (REGNO (op
)) != ADDR_REGS
))
3667 /* Shift counts are truncated to the low six bits anyway. */
3668 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
& 63);
3670 fprintf (file
, "(%s)", reg_names
[REGNO (op
)]);
3673 /* Locate some local-dynamic symbol still in use by this function
3674 so that we can print its name in local-dynamic base patterns. */
3677 get_some_local_dynamic_name (void)
3681 if (cfun
->machine
->some_ld_name
)
3682 return cfun
->machine
->some_ld_name
;
3684 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
3686 && for_each_rtx (&PATTERN (insn
), get_some_local_dynamic_name_1
, 0))
3687 return cfun
->machine
->some_ld_name
;
3693 get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
3697 if (GET_CODE (x
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (x
))
3699 x
= get_pool_constant (x
);
3700 return for_each_rtx (&x
, get_some_local_dynamic_name_1
, 0);
3703 if (GET_CODE (x
) == SYMBOL_REF
3704 && tls_symbolic_operand (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
3706 cfun
->machine
->some_ld_name
= XSTR (x
, 0);
3713 /* Output machine-dependent UNSPECs occurring in address constant X
3714 in assembler syntax to stdio stream FILE. Returns true if the
3715 constant X could be recognized, false otherwise. */
3718 s390_output_addr_const_extra (FILE *file
, rtx x
)
3720 if (GET_CODE (x
) == UNSPEC
&& XVECLEN (x
, 0) == 1)
3721 switch (XINT (x
, 1))
3724 output_addr_const (file
, XVECEXP (x
, 0, 0));
3725 fprintf (file
, "@GOTENT");
3728 output_addr_const (file
, XVECEXP (x
, 0, 0));
3729 fprintf (file
, "@GOT");
3732 output_addr_const (file
, XVECEXP (x
, 0, 0));
3733 fprintf (file
, "@GOTOFF");
3736 output_addr_const (file
, XVECEXP (x
, 0, 0));
3737 fprintf (file
, "@PLT");
3740 output_addr_const (file
, XVECEXP (x
, 0, 0));
3741 fprintf (file
, "@PLTOFF");
3744 output_addr_const (file
, XVECEXP (x
, 0, 0));
3745 fprintf (file
, "@TLSGD");
3748 assemble_name (file
, get_some_local_dynamic_name ());
3749 fprintf (file
, "@TLSLDM");
3752 output_addr_const (file
, XVECEXP (x
, 0, 0));
3753 fprintf (file
, "@DTPOFF");
3756 output_addr_const (file
, XVECEXP (x
, 0, 0));
3757 fprintf (file
, "@NTPOFF");
3759 case UNSPEC_GOTNTPOFF
:
3760 output_addr_const (file
, XVECEXP (x
, 0, 0));
3761 fprintf (file
, "@GOTNTPOFF");
3763 case UNSPEC_INDNTPOFF
:
3764 output_addr_const (file
, XVECEXP (x
, 0, 0));
3765 fprintf (file
, "@INDNTPOFF");
3772 /* Output address operand ADDR in assembler syntax to
3773 stdio stream FILE. */
3776 print_operand_address (FILE *file
, rtx addr
)
3778 struct s390_address ad
;
3780 if (!s390_decompose_address (addr
, &ad
)
3781 || (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
3782 || (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
)))
3783 output_operand_lossage ("Cannot decompose address.");
3786 output_addr_const (file
, ad
.disp
);
3788 fprintf (file
, "0");
3790 if (ad
.base
&& ad
.indx
)
3791 fprintf (file
, "(%s,%s)", reg_names
[REGNO (ad
.indx
)],
3792 reg_names
[REGNO (ad
.base
)]);
3794 fprintf (file
, "(%s)", reg_names
[REGNO (ad
.base
)]);
3797 /* Output operand X in assembler syntax to stdio stream FILE.
3798 CODE specified the format flag. The following format flags
3801 'C': print opcode suffix for branch condition.
3802 'D': print opcode suffix for inverse branch condition.
3803 'J': print tls_load/tls_gdcall/tls_ldcall suffix
3804 'O': print only the displacement of a memory reference.
3805 'R': print only the base register of a memory reference.
3806 'N': print the second word of a DImode operand.
3807 'M': print the second word of a TImode operand.
3808 'Y': print shift count operand.
3810 'b': print integer X as if it's an unsigned byte.
3811 'x': print integer X as if it's an unsigned word.
3812 'h': print integer X as if it's a signed word.
3813 'i': print the first nonzero HImode part of X.
3814 'j': print the first HImode part unequal to 0xffff of X. */
3817 print_operand (FILE *file
, rtx x
, int code
)
3822 fprintf (file
, s390_branch_condition_mnemonic (x
, FALSE
));
3826 fprintf (file
, s390_branch_condition_mnemonic (x
, TRUE
));
3830 if (GET_CODE (x
) == SYMBOL_REF
)
3832 fprintf (file
, "%s", ":tls_load:");
3833 output_addr_const (file
, x
);
3835 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSGD
)
3837 fprintf (file
, "%s", ":tls_gdcall:");
3838 output_addr_const (file
, XVECEXP (x
, 0, 0));
3840 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSLDM
)
3842 fprintf (file
, "%s", ":tls_ldcall:");
3843 assemble_name (file
, get_some_local_dynamic_name ());
3851 struct s390_address ad
;
3853 if (GET_CODE (x
) != MEM
3854 || !s390_decompose_address (XEXP (x
, 0), &ad
)
3855 || (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
3860 output_addr_const (file
, ad
.disp
);
3862 fprintf (file
, "0");
3868 struct s390_address ad
;
3870 if (GET_CODE (x
) != MEM
3871 || !s390_decompose_address (XEXP (x
, 0), &ad
)
3872 || (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
3877 fprintf (file
, "%s", reg_names
[REGNO (ad
.base
)]);
3879 fprintf (file
, "0");
3884 if (GET_CODE (x
) == REG
)
3885 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
3886 else if (GET_CODE (x
) == MEM
)
3887 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 4));
3893 if (GET_CODE (x
) == REG
)
3894 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
3895 else if (GET_CODE (x
) == MEM
)
3896 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 8));
3902 print_shift_count_operand (file
, x
);
3906 switch (GET_CODE (x
))
3909 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
3913 output_address (XEXP (x
, 0));
3920 output_addr_const (file
, x
);
3925 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xff);
3926 else if (code
== 'x')
3927 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xffff);
3928 else if (code
== 'h')
3929 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((INTVAL (x
) & 0xffff) ^ 0x8000) - 0x8000);
3930 else if (code
== 'i')
3931 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
3932 s390_extract_part (x
, HImode
, 0));
3933 else if (code
== 'j')
3934 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
3935 s390_extract_part (x
, HImode
, -1));
3937 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
3941 if (GET_MODE (x
) != VOIDmode
)
3944 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xff);
3945 else if (code
== 'x')
3946 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xffff);
3947 else if (code
== 'h')
3948 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((CONST_DOUBLE_LOW (x
) & 0xffff) ^ 0x8000) - 0x8000);
3954 fatal_insn ("UNKNOWN in print_operand !?", x
);
3959 /* Target hook for assembling integer objects. We need to define it
3960 here to work a round a bug in some versions of GAS, which couldn't
3961 handle values smaller than INT_MIN when printed in decimal. */
3964 s390_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
3966 if (size
== 8 && aligned_p
3967 && GET_CODE (x
) == CONST_INT
&& INTVAL (x
) < INT_MIN
)
3969 fprintf (asm_out_file
, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX
"\n",
3973 return default_assemble_integer (x
, size
, aligned_p
);
3976 /* Returns true if register REGNO is used for forming
3977 a memory address in expression X. */
3980 reg_used_in_mem_p (int regno
, rtx x
)
3982 enum rtx_code code
= GET_CODE (x
);
3988 if (refers_to_regno_p (regno
, regno
+1,
3992 else if (code
== SET
3993 && GET_CODE (SET_DEST (x
)) == PC
)
3995 if (refers_to_regno_p (regno
, regno
+1,
4000 fmt
= GET_RTX_FORMAT (code
);
4001 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
4004 && reg_used_in_mem_p (regno
, XEXP (x
, i
)))
4007 else if (fmt
[i
] == 'E')
4008 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
4009 if (reg_used_in_mem_p (regno
, XVECEXP (x
, i
, j
)))
4015 /* Returns true if expression DEP_RTX sets an address register
4016 used by instruction INSN to address memory. */
4019 addr_generation_dependency_p (rtx dep_rtx
, rtx insn
)
4023 if (GET_CODE (dep_rtx
) == INSN
)
4024 dep_rtx
= PATTERN (dep_rtx
);
4026 if (GET_CODE (dep_rtx
) == SET
)
4028 target
= SET_DEST (dep_rtx
);
4029 if (GET_CODE (target
) == STRICT_LOW_PART
)
4030 target
= XEXP (target
, 0);
4031 while (GET_CODE (target
) == SUBREG
)
4032 target
= SUBREG_REG (target
);
4034 if (GET_CODE (target
) == REG
)
4036 int regno
= REGNO (target
);
4038 if (s390_safe_attr_type (insn
) == TYPE_LA
)
4040 pat
= PATTERN (insn
);
4041 if (GET_CODE (pat
) == PARALLEL
)
4043 if (XVECLEN (pat
, 0) != 2)
4045 pat
= XVECEXP (pat
, 0, 0);
4047 if (GET_CODE (pat
) == SET
)
4048 return refers_to_regno_p (regno
, regno
+1, SET_SRC (pat
), 0);
4052 else if (get_attr_atype (insn
) == ATYPE_AGEN
)
4053 return reg_used_in_mem_p (regno
, PATTERN (insn
));
4059 /* Return 1, if dep_insn sets register used in insn in the agen unit. */
4062 s390_agen_dep_p (rtx dep_insn
, rtx insn
)
4064 rtx dep_rtx
= PATTERN (dep_insn
);
4067 if (GET_CODE (dep_rtx
) == SET
4068 && addr_generation_dependency_p (dep_rtx
, insn
))
4070 else if (GET_CODE (dep_rtx
) == PARALLEL
)
4072 for (i
= 0; i
< XVECLEN (dep_rtx
, 0); i
++)
4074 if (addr_generation_dependency_p (XVECEXP (dep_rtx
, 0, i
), insn
))
4081 /* Return the modified cost of the dependency of instruction INSN
4082 on instruction DEP_INSN through the link LINK. COST is the
4083 default cost of that dependency.
4085 Data dependencies are all handled without delay. However, if a
4086 register is modified and subsequently used as base or index
4087 register of a memory reference, at least 4 cycles need to pass
4088 between setting and using the register to avoid pipeline stalls.
4089 An exception is the LA instruction. An address generated by LA can
4090 be used by introducing only a one cycle stall on the pipeline. */
4093 s390_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
4095 /* If the dependence is an anti-dependence, there is no cost. For an
4096 output dependence, there is sometimes a cost, but it doesn't seem
4097 worth handling those few cases. */
4099 if (REG_NOTE_KIND (link
) != 0)
4102 /* If we can't recognize the insns, we can't really do anything. */
4103 if (recog_memoized (insn
) < 0 || recog_memoized (dep_insn
) < 0)
4106 /* Operand forward in case of lr, load and la. */
4107 if (s390_tune
== PROCESSOR_2084_Z990
4109 && (s390_safe_attr_type (dep_insn
) == TYPE_LA
4110 || s390_safe_attr_type (dep_insn
) == TYPE_LR
4111 || s390_safe_attr_type (dep_insn
) == TYPE_LOAD
))
4116 /* A C statement (sans semicolon) to update the integer scheduling priority
4117 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
4118 reduce the priority to execute INSN later. Do not define this macro if
4119 you do not need to adjust the scheduling priorities of insns.
4121 A STD instruction should be scheduled earlier,
4122 in order to use the bypass. */
4125 s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
4127 if (! INSN_P (insn
))
4130 if (s390_tune
!= PROCESSOR_2084_Z990
)
4133 switch (s390_safe_attr_type (insn
))
4137 priority
= priority
<< 3;
4140 priority
= priority
<< 1;
4148 /* The number of instructions that can be issued per cycle. */
4151 s390_issue_rate (void)
4153 if (s390_tune
== PROCESSOR_2084_Z990
)
4159 s390_first_cycle_multipass_dfa_lookahead (void)
4165 /* Split all branches that exceed the maximum distance.
4166 Returns true if this created a new literal pool entry. */
4169 s390_split_branches (void)
4171 rtx temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
4172 int new_literal
= 0;
4173 rtx insn
, pat
, tmp
, target
;
4176 /* We need correct insn addresses. */
4178 shorten_branches (get_insns ());
4180 /* Find all branches that exceed 64KB, and split them. */
4182 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
4184 if (GET_CODE (insn
) != JUMP_INSN
)
4187 pat
= PATTERN (insn
);
4188 if (GET_CODE (pat
) == PARALLEL
&& XVECLEN (pat
, 0) > 2)
4189 pat
= XVECEXP (pat
, 0, 0);
4190 if (GET_CODE (pat
) != SET
|| SET_DEST (pat
) != pc_rtx
)
4193 if (GET_CODE (SET_SRC (pat
)) == LABEL_REF
)
4195 label
= &SET_SRC (pat
);
4197 else if (GET_CODE (SET_SRC (pat
)) == IF_THEN_ELSE
)
4199 if (GET_CODE (XEXP (SET_SRC (pat
), 1)) == LABEL_REF
)
4200 label
= &XEXP (SET_SRC (pat
), 1);
4201 else if (GET_CODE (XEXP (SET_SRC (pat
), 2)) == LABEL_REF
)
4202 label
= &XEXP (SET_SRC (pat
), 2);
4209 if (get_attr_length (insn
) <= 4)
4212 /* We are going to use the return register as scratch register,
4213 make sure it will be saved/restored by the prologue/epilogue. */
4214 cfun_frame_layout
.save_return_addr_p
= 1;
4219 tmp
= force_const_mem (Pmode
, *label
);
4220 tmp
= emit_insn_before (gen_rtx_SET (Pmode
, temp_reg
, tmp
), insn
);
4221 INSN_ADDRESSES_NEW (tmp
, -1);
4222 annotate_constant_pool_refs (&PATTERN (tmp
));
4229 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, *label
),
4230 UNSPEC_LTREL_OFFSET
);
4231 target
= gen_rtx_CONST (Pmode
, target
);
4232 target
= force_const_mem (Pmode
, target
);
4233 tmp
= emit_insn_before (gen_rtx_SET (Pmode
, temp_reg
, target
), insn
);
4234 INSN_ADDRESSES_NEW (tmp
, -1);
4235 annotate_constant_pool_refs (&PATTERN (tmp
));
4237 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XEXP (target
, 0),
4238 cfun
->machine
->base_reg
),
4240 target
= gen_rtx_PLUS (Pmode
, temp_reg
, target
);
4243 if (!validate_change (insn
, label
, target
, 0))
4250 /* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
4251 Fix up MEMs as required. */
4254 annotate_constant_pool_refs (rtx
*x
)
4259 if (GET_CODE (*x
) == SYMBOL_REF
4260 && CONSTANT_POOL_ADDRESS_P (*x
))
4263 /* Literal pool references can only occur inside a MEM ... */
4264 if (GET_CODE (*x
) == MEM
)
4266 rtx memref
= XEXP (*x
, 0);
4268 if (GET_CODE (memref
) == SYMBOL_REF
4269 && CONSTANT_POOL_ADDRESS_P (memref
))
4271 rtx base
= cfun
->machine
->base_reg
;
4272 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, memref
, base
),
4275 *x
= replace_equiv_address (*x
, addr
);
4279 if (GET_CODE (memref
) == CONST
4280 && GET_CODE (XEXP (memref
, 0)) == PLUS
4281 && GET_CODE (XEXP (XEXP (memref
, 0), 1)) == CONST_INT
4282 && GET_CODE (XEXP (XEXP (memref
, 0), 0)) == SYMBOL_REF
4283 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (memref
, 0), 0)))
4285 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (memref
, 0), 1));
4286 rtx sym
= XEXP (XEXP (memref
, 0), 0);
4287 rtx base
= cfun
->machine
->base_reg
;
4288 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
4291 *x
= replace_equiv_address (*x
, plus_constant (addr
, off
));
4296 /* ... or a load-address type pattern. */
4297 if (GET_CODE (*x
) == SET
)
4299 rtx addrref
= SET_SRC (*x
);
4301 if (GET_CODE (addrref
) == SYMBOL_REF
4302 && CONSTANT_POOL_ADDRESS_P (addrref
))
4304 rtx base
= cfun
->machine
->base_reg
;
4305 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, addrref
, base
),
4308 SET_SRC (*x
) = addr
;
4312 if (GET_CODE (addrref
) == CONST
4313 && GET_CODE (XEXP (addrref
, 0)) == PLUS
4314 && GET_CODE (XEXP (XEXP (addrref
, 0), 1)) == CONST_INT
4315 && GET_CODE (XEXP (XEXP (addrref
, 0), 0)) == SYMBOL_REF
4316 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (addrref
, 0), 0)))
4318 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (addrref
, 0), 1));
4319 rtx sym
= XEXP (XEXP (addrref
, 0), 0);
4320 rtx base
= cfun
->machine
->base_reg
;
4321 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
4324 SET_SRC (*x
) = plus_constant (addr
, off
);
4329 /* Annotate LTREL_BASE as well. */
4330 if (GET_CODE (*x
) == UNSPEC
4331 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
4333 rtx base
= cfun
->machine
->base_reg
;
4334 *x
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XVECEXP (*x
, 0, 0), base
),
4339 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
4340 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
4344 annotate_constant_pool_refs (&XEXP (*x
, i
));
4346 else if (fmt
[i
] == 'E')
4348 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
4349 annotate_constant_pool_refs (&XVECEXP (*x
, i
, j
));
4355 /* Find an annotated literal pool symbol referenced in RTX X,
4356 and store it at REF. Will abort if X contains references to
4357 more than one such pool symbol; multiple references to the same
4358 symbol are allowed, however.
4360 The rtx pointed to by REF must be initialized to NULL_RTX
4361 by the caller before calling this routine. */
4364 find_constant_pool_ref (rtx x
, rtx
*ref
)
4369 /* Ignore LTREL_BASE references. */
4370 if (GET_CODE (x
) == UNSPEC
4371 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
4373 /* Likewise POOL_ENTRY insns. */
4374 if (GET_CODE (x
) == UNSPEC_VOLATILE
4375 && XINT (x
, 1) == UNSPECV_POOL_ENTRY
)
4378 if (GET_CODE (x
) == SYMBOL_REF
4379 && CONSTANT_POOL_ADDRESS_P (x
))
4382 if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_LTREF
)
4384 rtx sym
= XVECEXP (x
, 0, 0);
4385 if (GET_CODE (sym
) != SYMBOL_REF
4386 || !CONSTANT_POOL_ADDRESS_P (sym
))
4389 if (*ref
== NULL_RTX
)
4391 else if (*ref
!= sym
)
4397 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
4398 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
4402 find_constant_pool_ref (XEXP (x
, i
), ref
);
4404 else if (fmt
[i
] == 'E')
4406 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
4407 find_constant_pool_ref (XVECEXP (x
, i
, j
), ref
);
4412 /* Replace every reference to the annotated literal pool
4413 symbol REF in X by its base plus OFFSET. */
4416 replace_constant_pool_ref (rtx
*x
, rtx ref
, rtx offset
)
4424 if (GET_CODE (*x
) == UNSPEC
4425 && XINT (*x
, 1) == UNSPEC_LTREF
4426 && XVECEXP (*x
, 0, 0) == ref
)
4428 *x
= gen_rtx_PLUS (Pmode
, XVECEXP (*x
, 0, 1), offset
);
4432 if (GET_CODE (*x
) == PLUS
4433 && GET_CODE (XEXP (*x
, 1)) == CONST_INT
4434 && GET_CODE (XEXP (*x
, 0)) == UNSPEC
4435 && XINT (XEXP (*x
, 0), 1) == UNSPEC_LTREF
4436 && XVECEXP (XEXP (*x
, 0), 0, 0) == ref
)
4438 rtx addr
= gen_rtx_PLUS (Pmode
, XVECEXP (XEXP (*x
, 0), 0, 1), offset
);
4439 *x
= plus_constant (addr
, INTVAL (XEXP (*x
, 1)));
4443 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
4444 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
4448 replace_constant_pool_ref (&XEXP (*x
, i
), ref
, offset
);
4450 else if (fmt
[i
] == 'E')
4452 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
4453 replace_constant_pool_ref (&XVECEXP (*x
, i
, j
), ref
, offset
);
4458 /* Check whether X contains an UNSPEC_LTREL_BASE.
4459 Return its constant pool symbol if found, NULL_RTX otherwise. */
4462 find_ltrel_base (rtx x
)
4467 if (GET_CODE (x
) == UNSPEC
4468 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
4469 return XVECEXP (x
, 0, 0);
4471 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
4472 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
4476 rtx fnd
= find_ltrel_base (XEXP (x
, i
));
4480 else if (fmt
[i
] == 'E')
4482 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
4484 rtx fnd
= find_ltrel_base (XVECEXP (x
, i
, j
));
4494 /* Replace any occurrence of UNSPEC_LTREL_BASE in X with its base. */
4497 replace_ltrel_base (rtx
*x
)
4502 if (GET_CODE (*x
) == UNSPEC
4503 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
4505 *x
= XVECEXP (*x
, 0, 1);
4509 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
4510 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
4514 replace_ltrel_base (&XEXP (*x
, i
));
4516 else if (fmt
[i
] == 'E')
4518 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
4519 replace_ltrel_base (&XVECEXP (*x
, i
, j
));
4525 /* We keep a list of constants which we have to add to internal
4526 constant tables in the middle of large functions. */
4528 #define NR_C_MODES 7
4529 enum machine_mode constant_modes
[NR_C_MODES
] =
4540 struct constant
*next
;
4545 struct constant_pool
4547 struct constant_pool
*next
;
4552 struct constant
*constants
[NR_C_MODES
];
4557 static struct constant_pool
* s390_mainpool_start (void);
4558 static void s390_mainpool_finish (struct constant_pool
*);
4559 static void s390_mainpool_cancel (struct constant_pool
*);
4561 static struct constant_pool
* s390_chunkify_start (void);
4562 static void s390_chunkify_finish (struct constant_pool
*);
4563 static void s390_chunkify_cancel (struct constant_pool
*);
4565 static struct constant_pool
*s390_start_pool (struct constant_pool
**, rtx
);
4566 static void s390_end_pool (struct constant_pool
*, rtx
);
4567 static void s390_add_pool_insn (struct constant_pool
*, rtx
);
4568 static struct constant_pool
*s390_find_pool (struct constant_pool
*, rtx
);
4569 static void s390_add_constant (struct constant_pool
*, rtx
, enum machine_mode
);
4570 static rtx
s390_find_constant (struct constant_pool
*, rtx
, enum machine_mode
);
4571 static rtx
s390_dump_pool (struct constant_pool
*, bool);
4572 static struct constant_pool
*s390_alloc_pool (void);
4573 static void s390_free_pool (struct constant_pool
*);
4575 /* Create new constant pool covering instructions starting at INSN
4576 and chain it to the end of POOL_LIST. */
4578 static struct constant_pool
*
4579 s390_start_pool (struct constant_pool
**pool_list
, rtx insn
)
4581 struct constant_pool
*pool
, **prev
;
4583 pool
= s390_alloc_pool ();
4584 pool
->first_insn
= insn
;
4586 for (prev
= pool_list
; *prev
; prev
= &(*prev
)->next
)
4593 /* End range of instructions covered by POOL at INSN and emit
4594 placeholder insn representing the pool. */
4597 s390_end_pool (struct constant_pool
*pool
, rtx insn
)
4599 rtx pool_size
= GEN_INT (pool
->size
+ 8 /* alignment slop */);
4602 insn
= get_last_insn ();
4604 pool
->pool_insn
= emit_insn_after (gen_pool (pool_size
), insn
);
4605 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
4608 /* Add INSN to the list of insns covered by POOL. */
4611 s390_add_pool_insn (struct constant_pool
*pool
, rtx insn
)
4613 bitmap_set_bit (pool
->insns
, INSN_UID (insn
));
4616 /* Return pool out of POOL_LIST that covers INSN. */
4618 static struct constant_pool
*
4619 s390_find_pool (struct constant_pool
*pool_list
, rtx insn
)
4621 struct constant_pool
*pool
;
4623 for (pool
= pool_list
; pool
; pool
= pool
->next
)
4624 if (bitmap_bit_p (pool
->insns
, INSN_UID (insn
)))
4630 /* Add constant VAL of mode MODE to the constant pool POOL. */
4633 s390_add_constant (struct constant_pool
*pool
, rtx val
, enum machine_mode mode
)
4638 for (i
= 0; i
< NR_C_MODES
; i
++)
4639 if (constant_modes
[i
] == mode
)
4641 if (i
== NR_C_MODES
)
4644 for (c
= pool
->constants
[i
]; c
!= NULL
; c
= c
->next
)
4645 if (rtx_equal_p (val
, c
->value
))
4650 c
= (struct constant
*) xmalloc (sizeof *c
);
4652 c
->label
= gen_label_rtx ();
4653 c
->next
= pool
->constants
[i
];
4654 pool
->constants
[i
] = c
;
4655 pool
->size
+= GET_MODE_SIZE (mode
);
4659 /* Find constant VAL of mode MODE in the constant pool POOL.
4660 Return an RTX describing the distance from the start of
4661 the pool to the location of the new constant. */
4664 s390_find_constant (struct constant_pool
*pool
, rtx val
,
4665 enum machine_mode mode
)
4671 for (i
= 0; i
< NR_C_MODES
; i
++)
4672 if (constant_modes
[i
] == mode
)
4674 if (i
== NR_C_MODES
)
4677 for (c
= pool
->constants
[i
]; c
!= NULL
; c
= c
->next
)
4678 if (rtx_equal_p (val
, c
->value
))
4684 offset
= gen_rtx_MINUS (Pmode
, gen_rtx_LABEL_REF (Pmode
, c
->label
),
4685 gen_rtx_LABEL_REF (Pmode
, pool
->label
));
4686 offset
= gen_rtx_CONST (Pmode
, offset
);
4690 /* Dump out the constants in POOL. If REMOTE_LABEL is true,
4691 do not emit the pool base label. */
4694 s390_dump_pool (struct constant_pool
*pool
, bool remote_label
)
4700 /* Pool start insn switches to proper section
4701 and guarantees necessary alignment. */
4702 if (TARGET_CPU_ZARCH
)
4703 insn
= emit_insn_after (gen_pool_start_64 (), pool
->pool_insn
);
4705 insn
= emit_insn_after (gen_pool_start_31 (), pool
->pool_insn
);
4706 INSN_ADDRESSES_NEW (insn
, -1);
4710 insn
= emit_label_after (pool
->label
, insn
);
4711 INSN_ADDRESSES_NEW (insn
, -1);
4714 /* Dump constants in descending alignment requirement order,
4715 ensuring proper alignment for every constant. */
4716 for (i
= 0; i
< NR_C_MODES
; i
++)
4717 for (c
= pool
->constants
[i
]; c
; c
= c
->next
)
4719 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
4720 rtx value
= c
->value
;
4721 if (GET_CODE (value
) == CONST
4722 && GET_CODE (XEXP (value
, 0)) == UNSPEC
4723 && XINT (XEXP (value
, 0), 1) == UNSPEC_LTREL_OFFSET
4724 && XVECLEN (XEXP (value
, 0), 0) == 1)
4726 value
= gen_rtx_MINUS (Pmode
, XVECEXP (XEXP (value
, 0), 0, 0),
4727 gen_rtx_LABEL_REF (VOIDmode
, pool
->label
));
4728 value
= gen_rtx_CONST (VOIDmode
, value
);
4731 insn
= emit_label_after (c
->label
, insn
);
4732 INSN_ADDRESSES_NEW (insn
, -1);
4734 value
= gen_rtx_UNSPEC_VOLATILE (constant_modes
[i
],
4735 gen_rtvec (1, value
),
4736 UNSPECV_POOL_ENTRY
);
4737 insn
= emit_insn_after (value
, insn
);
4738 INSN_ADDRESSES_NEW (insn
, -1);
4741 /* Pool end insn switches back to previous section
4742 and guarantees necessary alignment. */
4743 if (TARGET_CPU_ZARCH
)
4744 insn
= emit_insn_after (gen_pool_end_64 (), insn
);
4746 insn
= emit_insn_after (gen_pool_end_31 (), insn
);
4747 INSN_ADDRESSES_NEW (insn
, -1);
4749 insn
= emit_barrier_after (insn
);
4750 INSN_ADDRESSES_NEW (insn
, -1);
4752 /* Remove placeholder insn. */
4753 remove_insn (pool
->pool_insn
);
4758 /* Allocate new constant_pool structure. */
4760 static struct constant_pool
*
4761 s390_alloc_pool (void)
4763 struct constant_pool
*pool
;
4766 pool
= (struct constant_pool
*) xmalloc (sizeof *pool
);
4768 for (i
= 0; i
< NR_C_MODES
; i
++)
4769 pool
->constants
[i
] = NULL
;
4771 pool
->label
= gen_label_rtx ();
4772 pool
->first_insn
= NULL_RTX
;
4773 pool
->pool_insn
= NULL_RTX
;
4774 pool
->insns
= BITMAP_XMALLOC ();
4780 /* Free all memory used by POOL. */
4783 s390_free_pool (struct constant_pool
*pool
)
4787 for (i
= 0; i
< NR_C_MODES
; i
++)
4789 struct constant
*c
= pool
->constants
[i
];
4792 struct constant
*next
= c
->next
;
4798 BITMAP_XFREE (pool
->insns
);
4803 /* Collect main literal pool. Return NULL on overflow. */
4805 static struct constant_pool
*
4806 s390_mainpool_start (void)
4808 struct constant_pool
*pool
;
4811 pool
= s390_alloc_pool ();
4813 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
4815 if (GET_CODE (insn
) == INSN
4816 && GET_CODE (PATTERN (insn
)) == SET
4817 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC_VOLATILE
4818 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPECV_MAIN_POOL
)
4820 if (pool
->pool_insn
)
4822 pool
->pool_insn
= insn
;
4825 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
4827 rtx pool_ref
= NULL_RTX
;
4828 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
4831 rtx constant
= get_pool_constant (pool_ref
);
4832 enum machine_mode mode
= get_pool_mode (pool_ref
);
4833 s390_add_constant (pool
, constant
, mode
);
4838 if (!pool
->pool_insn
)
4841 if (pool
->size
>= 4096)
4843 /* We're going to chunkify the pool, so remove the main
4844 pool placeholder insn. */
4845 remove_insn (pool
->pool_insn
);
4847 s390_free_pool (pool
);
4854 /* POOL holds the main literal pool as collected by s390_mainpool_start.
4855 Modify the current function to output the pool constants as well as
4856 the pool register setup instruction. */
4859 s390_mainpool_finish (struct constant_pool
*pool
)
4861 rtx base_reg
= SET_DEST (PATTERN (pool
->pool_insn
));
4864 /* If the pool is empty, we're done. */
4865 if (pool
->size
== 0)
4867 remove_insn (pool
->pool_insn
);
4868 s390_free_pool (pool
);
4872 /* We need correct insn addresses. */
4873 shorten_branches (get_insns ());
4875 /* On zSeries, we use a LARL to load the pool register. The pool is
4876 located in the .rodata section, so we emit it after the function. */
4877 if (TARGET_CPU_ZARCH
)
4879 insn
= gen_main_base_64 (base_reg
, pool
->label
);
4880 insn
= emit_insn_after (insn
, pool
->pool_insn
);
4881 INSN_ADDRESSES_NEW (insn
, -1);
4882 remove_insn (pool
->pool_insn
);
4884 insn
= get_last_insn ();
4885 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
4886 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
4888 s390_dump_pool (pool
, 0);
4891 /* On S/390, if the total size of the function's code plus literal pool
4892 does not exceed 4096 bytes, we use BASR to set up a function base
4893 pointer, and emit the literal pool at the end of the function. */
4894 else if (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
4895 + pool
->size
+ 8 /* alignment slop */ < 4096)
4897 insn
= gen_main_base_31_small (base_reg
, pool
->label
);
4898 insn
= emit_insn_after (insn
, pool
->pool_insn
);
4899 INSN_ADDRESSES_NEW (insn
, -1);
4900 remove_insn (pool
->pool_insn
);
4902 insn
= emit_label_after (pool
->label
, insn
);
4903 INSN_ADDRESSES_NEW (insn
, -1);
4905 insn
= get_last_insn ();
4906 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
4907 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
4909 s390_dump_pool (pool
, 1);
4912 /* Otherwise, we emit an inline literal pool and use BASR to branch
4913 over it, setting up the pool register at the same time. */
4916 rtx pool_end
= gen_label_rtx ();
4918 insn
= gen_main_base_31_large (base_reg
, pool
->label
, pool_end
);
4919 insn
= emit_insn_after (insn
, pool
->pool_insn
);
4920 INSN_ADDRESSES_NEW (insn
, -1);
4921 remove_insn (pool
->pool_insn
);
4923 insn
= emit_label_after (pool
->label
, insn
);
4924 INSN_ADDRESSES_NEW (insn
, -1);
4926 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
4927 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
4929 insn
= emit_label_after (pool_end
, pool
->pool_insn
);
4930 INSN_ADDRESSES_NEW (insn
, -1);
4932 s390_dump_pool (pool
, 1);
4936 /* Replace all literal pool references. */
4938 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
4941 replace_ltrel_base (&PATTERN (insn
));
4943 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
4945 rtx addr
, pool_ref
= NULL_RTX
;
4946 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
4949 addr
= s390_find_constant (pool
, get_pool_constant (pool_ref
),
4950 get_pool_mode (pool_ref
));
4951 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
4952 INSN_CODE (insn
) = -1;
4958 /* Free the pool. */
4959 s390_free_pool (pool
);
4962 /* POOL holds the main literal pool as collected by s390_mainpool_start.
4963 We have decided we cannot use this pool, so revert all changes
4964 to the current function that were done by s390_mainpool_start. */
4966 s390_mainpool_cancel (struct constant_pool
*pool
)
4968 /* We didn't actually change the instruction stream, so simply
4969 free the pool memory. */
4970 s390_free_pool (pool
);
4974 /* Chunkify the literal pool. */
4976 #define S390_POOL_CHUNK_MIN 0xc00
4977 #define S390_POOL_CHUNK_MAX 0xe00
4979 static struct constant_pool
*
4980 s390_chunkify_start (void)
4982 struct constant_pool
*curr_pool
= NULL
, *pool_list
= NULL
;
4985 rtx pending_ltrel
= NULL_RTX
;
4988 rtx (*gen_reload_base
) (rtx
, rtx
) =
4989 TARGET_CPU_ZARCH
? gen_reload_base_64
: gen_reload_base_31
;
4992 /* We need correct insn addresses. */
4994 shorten_branches (get_insns ());
4996 /* Scan all insns and move literals to pool chunks. */
4998 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5000 /* Check for pending LTREL_BASE. */
5003 rtx ltrel_base
= find_ltrel_base (PATTERN (insn
));
5006 if (ltrel_base
== pending_ltrel
)
5007 pending_ltrel
= NULL_RTX
;
5013 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5015 rtx pool_ref
= NULL_RTX
;
5016 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5019 rtx constant
= get_pool_constant (pool_ref
);
5020 enum machine_mode mode
= get_pool_mode (pool_ref
);
5023 curr_pool
= s390_start_pool (&pool_list
, insn
);
5025 s390_add_constant (curr_pool
, constant
, mode
);
5026 s390_add_pool_insn (curr_pool
, insn
);
5028 /* Don't split the pool chunk between a LTREL_OFFSET load
5029 and the corresponding LTREL_BASE. */
5030 if (GET_CODE (constant
) == CONST
5031 && GET_CODE (XEXP (constant
, 0)) == UNSPEC
5032 && XINT (XEXP (constant
, 0), 1) == UNSPEC_LTREL_OFFSET
)
5036 pending_ltrel
= pool_ref
;
5041 if (GET_CODE (insn
) == JUMP_INSN
|| GET_CODE (insn
) == CODE_LABEL
)
5044 s390_add_pool_insn (curr_pool
, insn
);
5045 /* An LTREL_BASE must follow within the same basic block. */
5051 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn
)
5052 || INSN_ADDRESSES (INSN_UID (insn
)) == -1)
5055 if (TARGET_CPU_ZARCH
)
5057 if (curr_pool
->size
< S390_POOL_CHUNK_MAX
)
5060 s390_end_pool (curr_pool
, NULL_RTX
);
5065 int chunk_size
= INSN_ADDRESSES (INSN_UID (insn
))
5066 - INSN_ADDRESSES (INSN_UID (curr_pool
->first_insn
))
5069 /* We will later have to insert base register reload insns.
5070 Those will have an effect on code size, which we need to
5071 consider here. This calculation makes rather pessimistic
5072 worst-case assumptions. */
5073 if (GET_CODE (insn
) == CODE_LABEL
)
5076 if (chunk_size
< S390_POOL_CHUNK_MIN
5077 && curr_pool
->size
< S390_POOL_CHUNK_MIN
)
5080 /* Pool chunks can only be inserted after BARRIERs ... */
5081 if (GET_CODE (insn
) == BARRIER
)
5083 s390_end_pool (curr_pool
, insn
);
5088 /* ... so if we don't find one in time, create one. */
5089 else if ((chunk_size
> S390_POOL_CHUNK_MAX
5090 || curr_pool
->size
> S390_POOL_CHUNK_MAX
))
5092 rtx label
, jump
, barrier
;
5094 /* We can insert the barrier only after a 'real' insn. */
5095 if (GET_CODE (insn
) != INSN
&& GET_CODE (insn
) != CALL_INSN
)
5097 if (get_attr_length (insn
) == 0)
5100 /* Don't separate LTREL_BASE from the corresponding
5101 LTREL_OFFSET load. */
5105 label
= gen_label_rtx ();
5106 jump
= emit_jump_insn_after (gen_jump (label
), insn
);
5107 barrier
= emit_barrier_after (jump
);
5108 insn
= emit_label_after (label
, barrier
);
5109 JUMP_LABEL (jump
) = label
;
5110 LABEL_NUSES (label
) = 1;
5112 INSN_ADDRESSES_NEW (jump
, -1);
5113 INSN_ADDRESSES_NEW (barrier
, -1);
5114 INSN_ADDRESSES_NEW (insn
, -1);
5116 s390_end_pool (curr_pool
, barrier
);
5124 s390_end_pool (curr_pool
, NULL_RTX
);
5129 /* Find all labels that are branched into
5130 from an insn belonging to a different chunk. */
5132 far_labels
= BITMAP_XMALLOC ();
5134 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5136 /* Labels marked with LABEL_PRESERVE_P can be target
5137 of non-local jumps, so we have to mark them.
5138 The same holds for named labels.
5140 Don't do that, however, if it is the label before
5143 if (GET_CODE (insn
) == CODE_LABEL
5144 && (LABEL_PRESERVE_P (insn
) || LABEL_NAME (insn
)))
5146 rtx vec_insn
= next_real_insn (insn
);
5147 rtx vec_pat
= vec_insn
&& GET_CODE (vec_insn
) == JUMP_INSN
?
5148 PATTERN (vec_insn
) : NULL_RTX
;
5150 || !(GET_CODE (vec_pat
) == ADDR_VEC
5151 || GET_CODE (vec_pat
) == ADDR_DIFF_VEC
))
5152 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (insn
));
5155 /* If we have a direct jump (conditional or unconditional)
5156 or a casesi jump, check all potential targets. */
5157 else if (GET_CODE (insn
) == JUMP_INSN
)
5159 rtx pat
= PATTERN (insn
);
5160 if (GET_CODE (pat
) == PARALLEL
&& XVECLEN (pat
, 0) > 2)
5161 pat
= XVECEXP (pat
, 0, 0);
5163 if (GET_CODE (pat
) == SET
)
5165 rtx label
= JUMP_LABEL (insn
);
5168 if (s390_find_pool (pool_list
, label
)
5169 != s390_find_pool (pool_list
, insn
))
5170 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
5173 else if (GET_CODE (pat
) == PARALLEL
5174 && XVECLEN (pat
, 0) == 2
5175 && GET_CODE (XVECEXP (pat
, 0, 0)) == SET
5176 && GET_CODE (XVECEXP (pat
, 0, 1)) == USE
5177 && GET_CODE (XEXP (XVECEXP (pat
, 0, 1), 0)) == LABEL_REF
)
5179 /* Find the jump table used by this casesi jump. */
5180 rtx vec_label
= XEXP (XEXP (XVECEXP (pat
, 0, 1), 0), 0);
5181 rtx vec_insn
= next_real_insn (vec_label
);
5182 rtx vec_pat
= vec_insn
&& GET_CODE (vec_insn
) == JUMP_INSN
?
5183 PATTERN (vec_insn
) : NULL_RTX
;
5185 && (GET_CODE (vec_pat
) == ADDR_VEC
5186 || GET_CODE (vec_pat
) == ADDR_DIFF_VEC
))
5188 int i
, diff_p
= GET_CODE (vec_pat
) == ADDR_DIFF_VEC
;
5190 for (i
= 0; i
< XVECLEN (vec_pat
, diff_p
); i
++)
5192 rtx label
= XEXP (XVECEXP (vec_pat
, diff_p
, i
), 0);
5194 if (s390_find_pool (pool_list
, label
)
5195 != s390_find_pool (pool_list
, insn
))
5196 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
5203 /* Insert base register reload insns before every pool. */
5205 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
5207 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
5209 rtx insn
= curr_pool
->first_insn
;
5210 INSN_ADDRESSES_NEW (emit_insn_before (new_insn
, insn
), -1);
5213 /* Insert base register reload insns at every far label. */
5215 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5216 if (GET_CODE (insn
) == CODE_LABEL
5217 && bitmap_bit_p (far_labels
, CODE_LABEL_NUMBER (insn
)))
5219 struct constant_pool
*pool
= s390_find_pool (pool_list
, insn
);
5222 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
5224 INSN_ADDRESSES_NEW (emit_insn_after (new_insn
, insn
), -1);
5229 BITMAP_XFREE (far_labels
);
5232 /* Recompute insn addresses. */
5234 init_insn_lengths ();
5235 shorten_branches (get_insns ());
5240 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
5241 After we have decided to use this list, finish implementing
5242 all changes to the current function as required. */
5245 s390_chunkify_finish (struct constant_pool
*pool_list
)
5247 struct constant_pool
*curr_pool
= NULL
;
5251 /* Replace all literal pool references. */
5253 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5256 replace_ltrel_base (&PATTERN (insn
));
5258 curr_pool
= s390_find_pool (pool_list
, insn
);
5262 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5264 rtx addr
, pool_ref
= NULL_RTX
;
5265 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5268 addr
= s390_find_constant (curr_pool
, get_pool_constant (pool_ref
),
5269 get_pool_mode (pool_ref
));
5270 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
5271 INSN_CODE (insn
) = -1;
5276 /* Dump out all literal pools. */
5278 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
5279 s390_dump_pool (curr_pool
, 0);
5281 /* Free pool list. */
5285 struct constant_pool
*next
= pool_list
->next
;
5286 s390_free_pool (pool_list
);
5291 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
5292 We have decided we cannot use this list, so revert all changes
5293 to the current function that were done by s390_chunkify_start. */
5296 s390_chunkify_cancel (struct constant_pool
*pool_list
)
5298 struct constant_pool
*curr_pool
= NULL
;
5301 /* Remove all pool placeholder insns. */
5303 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
5305 /* Did we insert an extra barrier? Remove it. */
5306 rtx barrier
= PREV_INSN (curr_pool
->pool_insn
);
5307 rtx jump
= barrier
? PREV_INSN (barrier
) : NULL_RTX
;
5308 rtx label
= NEXT_INSN (curr_pool
->pool_insn
);
5310 if (jump
&& GET_CODE (jump
) == JUMP_INSN
5311 && barrier
&& GET_CODE (barrier
) == BARRIER
5312 && label
&& GET_CODE (label
) == CODE_LABEL
5313 && GET_CODE (PATTERN (jump
)) == SET
5314 && SET_DEST (PATTERN (jump
)) == pc_rtx
5315 && GET_CODE (SET_SRC (PATTERN (jump
))) == LABEL_REF
5316 && XEXP (SET_SRC (PATTERN (jump
)), 0) == label
)
5319 remove_insn (barrier
);
5320 remove_insn (label
);
5323 remove_insn (curr_pool
->pool_insn
);
5326 /* Remove all base register reload insns. */
5328 for (insn
= get_insns (); insn
; )
5330 rtx next_insn
= NEXT_INSN (insn
);
5332 if (GET_CODE (insn
) == INSN
5333 && GET_CODE (PATTERN (insn
)) == SET
5334 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC
5335 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPEC_RELOAD_BASE
)
5341 /* Free pool list. */
5345 struct constant_pool
*next
= pool_list
->next
;
5346 s390_free_pool (pool_list
);
5352 /* Output the constant pool entry EXP in mode MODE with alignment ALIGN. */
5355 s390_output_pool_entry (rtx exp
, enum machine_mode mode
, unsigned int align
)
5359 switch (GET_MODE_CLASS (mode
))
5362 if (GET_CODE (exp
) != CONST_DOUBLE
)
5365 REAL_VALUE_FROM_CONST_DOUBLE (r
, exp
);
5366 assemble_real (r
, mode
, align
);
5370 assemble_integer (exp
, GET_MODE_SIZE (mode
), align
, 1);
5379 /* Rework the prologue/epilogue to avoid saving/restoring
5380 registers unnecessarily. BASE_USED specifies whether
5381 the literal pool base register needs to be saved. */
5384 s390_optimize_prologue (bool base_used
)
5386 rtx insn
, new_insn
, next_insn
;
5388 /* Do a final recompute of the frame-related data. */
5390 s390_register_info (base_used
, cfun_frame_layout
.save_return_addr_p
);
5391 regs_ever_live
[BASE_REGNUM
] = base_used
;
5392 regs_ever_live
[RETURN_REGNUM
] = cfun_frame_layout
.save_return_addr_p
;
5393 regs_ever_live
[STACK_POINTER_REGNUM
] = cfun_frame_layout
.frame_size
> 0;
5395 /* If all special registers are in fact used, there's nothing we
5396 can do, so no point in walking the insn list. */
5398 if (cfun_frame_layout
.first_save_gpr
<= BASE_REGNUM
5399 && cfun_frame_layout
.last_save_gpr
>= BASE_REGNUM
5400 && (TARGET_CPU_ZARCH
5401 || (cfun_frame_layout
.first_save_gpr
<= RETURN_REGNUM
5402 && cfun_frame_layout
.last_save_gpr
>= RETURN_REGNUM
)))
5405 /* Search for prologue/epilogue insns and replace them. */
5407 for (insn
= get_insns (); insn
; insn
= next_insn
)
5409 int first
, last
, off
;
5410 rtx set
, base
, offset
;
5412 next_insn
= NEXT_INSN (insn
);
5414 if (GET_CODE (insn
) != INSN
)
5417 if (GET_CODE (PATTERN (insn
)) == PARALLEL
5418 && store_multiple_operation (PATTERN (insn
), VOIDmode
))
5420 set
= XVECEXP (PATTERN (insn
), 0, 0);
5421 first
= REGNO (SET_SRC (set
));
5422 last
= first
+ XVECLEN (PATTERN (insn
), 0) - 1;
5423 offset
= const0_rtx
;
5424 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
5425 off
= INTVAL (offset
);
5427 if (GET_CODE (base
) != REG
|| off
< 0)
5429 if (REGNO (base
) != STACK_POINTER_REGNUM
5430 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
5432 if (first
> BASE_REGNUM
|| last
< BASE_REGNUM
)
5435 if (cfun_frame_layout
.first_save_gpr
!= -1)
5437 new_insn
= save_gprs (base
,
5438 off
+ (cfun_frame_layout
.first_save_gpr
5439 - first
) * UNITS_PER_WORD
,
5440 cfun_frame_layout
.first_save_gpr
,
5441 cfun_frame_layout
.last_save_gpr
);
5442 new_insn
= emit_insn_before (new_insn
, insn
);
5443 INSN_ADDRESSES_NEW (new_insn
, -1);
5450 if (GET_CODE (PATTERN (insn
)) == SET
5451 && GET_CODE (SET_SRC (PATTERN (insn
))) == REG
5452 && REGNO (SET_SRC (PATTERN (insn
))) == BASE_REGNUM
5453 && GET_CODE (SET_DEST (PATTERN (insn
))) == MEM
)
5455 set
= PATTERN (insn
);
5456 offset
= const0_rtx
;
5457 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
5458 off
= INTVAL (offset
);
5460 if (GET_CODE (base
) != REG
|| off
< 0)
5462 if (REGNO (base
) != STACK_POINTER_REGNUM
5463 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
5465 if (cfun_frame_layout
.first_save_gpr
!= -1)
5467 new_insn
= save_gprs (base
,
5468 off
+ (cfun_frame_layout
.first_save_gpr
5469 - BASE_REGNUM
) * UNITS_PER_WORD
,
5470 cfun_frame_layout
.first_save_gpr
,
5471 cfun_frame_layout
.last_save_gpr
);
5472 new_insn
= emit_insn_before (new_insn
, insn
);
5473 INSN_ADDRESSES_NEW (new_insn
, -1);
5480 if (GET_CODE (PATTERN (insn
)) == PARALLEL
5481 && load_multiple_operation (PATTERN (insn
), VOIDmode
))
5483 set
= XVECEXP (PATTERN (insn
), 0, 0);
5484 first
= REGNO (SET_DEST (set
));
5485 last
= first
+ XVECLEN (PATTERN (insn
), 0) - 1;
5486 offset
= const0_rtx
;
5487 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
5488 off
= INTVAL (offset
);
5490 if (GET_CODE (base
) != REG
|| off
< 0)
5492 if (REGNO (base
) != STACK_POINTER_REGNUM
5493 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
5495 if (first
> BASE_REGNUM
|| last
< BASE_REGNUM
)
5498 if (cfun_frame_layout
.first_restore_gpr
!= -1)
5500 new_insn
= restore_gprs (base
,
5501 off
+ (cfun_frame_layout
.first_restore_gpr
5502 - first
) * UNITS_PER_WORD
,
5503 cfun_frame_layout
.first_restore_gpr
,
5504 cfun_frame_layout
.last_restore_gpr
);
5505 new_insn
= emit_insn_before (new_insn
, insn
);
5506 INSN_ADDRESSES_NEW (new_insn
, -1);
5513 if (GET_CODE (PATTERN (insn
)) == SET
5514 && GET_CODE (SET_DEST (PATTERN (insn
))) == REG
5515 && REGNO (SET_DEST (PATTERN (insn
))) == BASE_REGNUM
5516 && GET_CODE (SET_SRC (PATTERN (insn
))) == MEM
)
5518 set
= PATTERN (insn
);
5519 offset
= const0_rtx
;
5520 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
5521 off
= INTVAL (offset
);
5523 if (GET_CODE (base
) != REG
|| off
< 0)
5525 if (REGNO (base
) != STACK_POINTER_REGNUM
5526 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
5528 if (cfun_frame_layout
.first_restore_gpr
!= -1)
5530 new_insn
= restore_gprs (base
,
5531 off
+ (cfun_frame_layout
.first_restore_gpr
5532 - BASE_REGNUM
) * UNITS_PER_WORD
,
5533 cfun_frame_layout
.first_restore_gpr
,
5534 cfun_frame_layout
.last_restore_gpr
);
5535 new_insn
= emit_insn_before (new_insn
, insn
);
5536 INSN_ADDRESSES_NEW (new_insn
, -1);
5545 /* Perform machine-dependent processing. */
5550 bool base_used
= false;
5551 bool pool_overflow
= false;
5553 /* Make sure all splits have been performed; splits after
5554 machine_dependent_reorg might confuse insn length counts. */
5555 split_all_insns_noflow ();
5558 /* Install the main literal pool and the associated base
5559 register load insns.
5561 In addition, there are two problematic situations we need
5564 - the literal pool might be > 4096 bytes in size, so that
5565 some of its elements cannot be directly accessed
5567 - a branch target might be > 64K away from the branch, so that
5568 it is not possible to use a PC-relative instruction.
5570 To fix those, we split the single literal pool into multiple
5571 pool chunks, reloading the pool base register at various
5572 points throughout the function to ensure it always points to
5573 the pool chunk the following code expects, and / or replace
5574 PC-relative branches by absolute branches.
5576 However, the two problems are interdependent: splitting the
5577 literal pool can move a branch further away from its target,
5578 causing the 64K limit to overflow, and on the other hand,
5579 replacing a PC-relative branch by an absolute branch means
5580 we need to put the branch target address into the literal
5581 pool, possibly causing it to overflow.
5583 So, we loop trying to fix up both problems until we manage
5584 to satisfy both conditions at the same time. Note that the
5585 loop is guaranteed to terminate as every pass of the loop
5586 strictly decreases the total number of PC-relative branches
5587 in the function. (This is not completely true as there
5588 might be branch-over-pool insns introduced by chunkify_start.
5589 Those never need to be split however.) */
5593 struct constant_pool
*pool
= NULL
;
5595 /* Collect the literal pool. */
5598 pool
= s390_mainpool_start ();
5600 pool_overflow
= true;
5603 /* If literal pool overflowed, start to chunkify it. */
5605 pool
= s390_chunkify_start ();
5607 /* Split out-of-range branches. If this has created new
5608 literal pool entries, cancel current chunk list and
5609 recompute it. zSeries machines have large branch
5610 instructions, so we never need to split a branch. */
5611 if (!TARGET_CPU_ZARCH
&& s390_split_branches ())
5614 s390_chunkify_cancel (pool
);
5616 s390_mainpool_cancel (pool
);
5621 /* If we made it up to here, both conditions are satisfied.
5622 Finish up literal pool related changes. */
5623 if ((pool_overflow
|| pool
->size
> 0)
5624 && REGNO (cfun
->machine
->base_reg
) == BASE_REGNUM
)
5628 s390_chunkify_finish (pool
);
5630 s390_mainpool_finish (pool
);
5635 s390_optimize_prologue (base_used
);
5639 /* Return an RTL expression representing the value of the return address
5640 for the frame COUNT steps up from the current frame. FRAME is the
5641 frame pointer of that frame. */
5644 s390_return_addr_rtx (int count
, rtx frame ATTRIBUTE_UNUSED
)
5649 /* Without backchain, we fail for all but the current frame. */
5651 if (!TARGET_BACKCHAIN
&& !TARGET_KERNEL_BACKCHAIN
&& count
> 0)
5654 /* For the current frame, we need to make sure the initial
5655 value of RETURN_REGNUM is actually saved. */
5659 cfun_frame_layout
.save_return_addr_p
= true;
5660 return gen_rtx_MEM (Pmode
, return_address_pointer_rtx
);
5663 if (TARGET_BACKCHAIN
)
5664 offset
= RETURN_REGNUM
* UNITS_PER_WORD
;
5666 offset
= -2 * UNITS_PER_WORD
;
5668 addr
= plus_constant (frame
, offset
);
5669 addr
= memory_address (Pmode
, addr
);
5670 return gen_rtx_MEM (Pmode
, addr
);
5673 /* Find first call clobbered register unused in a function.
5674 This could be used as base register in a leaf function
5675 or for holding the return address before epilogue. */
5678 find_unused_clobbered_reg (void)
5681 for (i
= 0; i
< 6; i
++)
5682 if (!regs_ever_live
[i
])
5687 /* Determine the frame area which actually has to be accessed
5688 in the function epilogue. The values are stored at the
5689 given pointers AREA_BOTTOM (address of the lowest used stack
5690 address) and AREA_TOP (address of the first item which does
5691 not belong to the stack frame). */
5694 s390_frame_area (int *area_bottom
, int *area_top
)
5702 if (cfun_frame_layout
.first_restore_gpr
!= -1)
5704 b
= (cfun_frame_layout
.gprs_offset
5705 + cfun_frame_layout
.first_restore_gpr
* UNITS_PER_WORD
);
5706 t
= b
+ (cfun_frame_layout
.last_restore_gpr
5707 - cfun_frame_layout
.first_restore_gpr
+ 1) * UNITS_PER_WORD
;
5710 if (TARGET_64BIT
&& cfun_save_high_fprs_p
)
5712 b
= MIN (b
, cfun_frame_layout
.f8_offset
);
5713 t
= MAX (t
, (cfun_frame_layout
.f8_offset
5714 + cfun_frame_layout
.high_fprs
* 8));
5718 for (i
= 2; i
< 4; i
++)
5719 if (cfun_fpr_bit_p (i
))
5721 b
= MIN (b
, cfun_frame_layout
.f4_offset
+ (i
- 2) * 8);
5722 t
= MAX (t
, cfun_frame_layout
.f4_offset
+ (i
- 1) * 8);
5729 /* Fill cfun->machine with info about register usage of current
5730 function. BASE_USED and RETURN_ADDR_USED specify whether we assume the
5731 base and return address register will need to be saved. */
5734 s390_register_info (int base_used
, int return_addr_used
)
5739 /* fprs 8 - 15 are call saved for 64 Bit ABI. */
5740 cfun_frame_layout
.fpr_bitmap
= 0;
5741 cfun_frame_layout
.high_fprs
= 0;
5743 for (i
= 24; i
< 32; i
++)
5744 if (regs_ever_live
[i
] && !global_regs
[i
])
5746 cfun_set_fpr_bit (i
- 16);
5747 cfun_frame_layout
.high_fprs
++;
5750 /* Find first and last gpr to be saved. We trust regs_ever_live
5751 data, except that we don't save and restore global registers.
5753 Also, all registers with special meaning to the compiler need
5754 to be handled extra. */
5756 for (i
= 0; i
< 16; i
++)
5757 live_regs
[i
] = regs_ever_live
[i
] && !global_regs
[i
];
5760 live_regs
[PIC_OFFSET_TABLE_REGNUM
] =
5761 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
];
5763 live_regs
[BASE_REGNUM
] = base_used
;
5764 live_regs
[RETURN_REGNUM
] = return_addr_used
;
5765 live_regs
[STACK_POINTER_REGNUM
] = (!current_function_is_leaf
5766 || TARGET_TPF_PROFILING
5767 || cfun_save_high_fprs_p
5768 || get_frame_size () > 0
5769 || current_function_calls_alloca
5770 || current_function_stdarg
);
5772 for (i
= 6; i
< 16; i
++)
5775 for (j
= 15; j
> i
; j
--)
5781 /* Nothing to save/restore. */
5782 cfun_frame_layout
.first_save_gpr
= -1;
5783 cfun_frame_layout
.first_restore_gpr
= -1;
5784 cfun_frame_layout
.last_save_gpr
= -1;
5785 cfun_frame_layout
.last_restore_gpr
= -1;
5789 /* Save / Restore from gpr i to j. */
5790 cfun_frame_layout
.first_save_gpr
= i
;
5791 cfun_frame_layout
.first_restore_gpr
= i
;
5792 cfun_frame_layout
.last_save_gpr
= j
;
5793 cfun_frame_layout
.last_restore_gpr
= j
;
5796 if (current_function_stdarg
)
5798 /* Varargs functions need to save gprs 2 to 6. */
5799 if (cfun_frame_layout
.first_save_gpr
== -1
5800 || cfun_frame_layout
.first_save_gpr
> 2)
5801 cfun_frame_layout
.first_save_gpr
= 2;
5803 if (cfun_frame_layout
.last_save_gpr
== -1
5804 || cfun_frame_layout
.last_save_gpr
< 6)
5805 cfun_frame_layout
.last_save_gpr
= 6;
5807 /* Mark f0, f2 for 31 bit and f0-f4 for 64 bit to be saved. */
5808 for (i
= 0; i
< (TARGET_64BIT
? 4 : 2); i
++)
5809 cfun_set_fpr_bit (i
);
5813 for (i
= 2; i
< 4; i
++)
5814 if (regs_ever_live
[i
+ 16] && !global_regs
[i
+ 16])
5815 cfun_set_fpr_bit (i
);
5818 /* Fill cfun->machine with info about frame of current
5819 function. BASE_USED and RETURN_ADDR_USED specify whether we assume the
5820 base and return address register will need to be saved. */
5823 s390_frame_info (int base_used
, int return_addr_used
)
5827 cfun_frame_layout
.frame_size
= get_frame_size ();
5829 s390_register_info (base_used
, return_addr_used
);
5831 if (!TARGET_64BIT
&& cfun_frame_layout
.frame_size
> 0x7fff0000)
5832 fatal_error ("Total size of local variables exceeds architecture limit.");
5834 cfun_frame_layout
.save_backchain_p
= (TARGET_BACKCHAIN
5835 || TARGET_KERNEL_BACKCHAIN
);
5837 if (TARGET_BACKCHAIN
)
5839 cfun_frame_layout
.backchain_offset
= 0;
5840 cfun_frame_layout
.f0_offset
= 16 * UNITS_PER_WORD
;
5841 cfun_frame_layout
.f4_offset
= cfun_frame_layout
.f0_offset
+ 2 * 8;
5842 cfun_frame_layout
.f8_offset
= -cfun_frame_layout
.high_fprs
* 8;
5843 cfun_frame_layout
.gprs_offset
= (cfun_frame_layout
.first_save_gpr
5846 else if (TARGET_KERNEL_BACKCHAIN
)
5848 cfun_frame_layout
.backchain_offset
= (STACK_POINTER_OFFSET
5850 cfun_frame_layout
.gprs_offset
5851 = (cfun_frame_layout
.backchain_offset
5852 - (STACK_POINTER_REGNUM
- cfun_frame_layout
.first_save_gpr
+ 1)
5857 cfun_frame_layout
.f4_offset
5858 = (cfun_frame_layout
.gprs_offset
5859 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
5861 cfun_frame_layout
.f0_offset
5862 = (cfun_frame_layout
.f4_offset
5863 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
5867 cfun_frame_layout
.f0_offset
5868 = (cfun_frame_layout
.gprs_offset
5869 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
5871 cfun_frame_layout
.f4_offset
5872 = (cfun_frame_layout
.f0_offset
5873 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
5876 else /* no backchain */
5878 cfun_frame_layout
.f4_offset
5879 = (STACK_POINTER_OFFSET
5880 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
5882 cfun_frame_layout
.f0_offset
5883 = (cfun_frame_layout
.f4_offset
5884 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
5886 cfun_frame_layout
.gprs_offset
5887 = cfun_frame_layout
.f0_offset
- cfun_gprs_save_area_size
;
5890 if (current_function_is_leaf
5891 && !TARGET_TPF_PROFILING
5892 && cfun_frame_layout
.frame_size
== 0
5893 && !cfun_save_high_fprs_p
5894 && !current_function_calls_alloca
5895 && !current_function_stdarg
)
5898 if (TARGET_BACKCHAIN
)
5899 cfun_frame_layout
.frame_size
+= (STARTING_FRAME_OFFSET
5900 + cfun_frame_layout
.high_fprs
* 8);
5903 cfun_frame_layout
.frame_size
+= (cfun_frame_layout
.save_backchain_p
5906 cfun_frame_layout
.f8_offset
= (MIN (MIN (cfun_frame_layout
.f0_offset
,
5907 cfun_frame_layout
.f4_offset
),
5908 cfun_frame_layout
.gprs_offset
)
5909 - cfun_frame_layout
.high_fprs
* 8);
5911 cfun_frame_layout
.frame_size
+= cfun_frame_layout
.high_fprs
* 8;
5913 for (i
= 0; i
< 8; i
++)
5914 if (cfun_fpr_bit_p (i
))
5915 cfun_frame_layout
.frame_size
+= 8;
5917 cfun_frame_layout
.frame_size
+= cfun_gprs_save_area_size
;
5918 cfun_frame_layout
.frame_size
= ((cfun_frame_layout
.frame_size
+
5919 STACK_BOUNDARY
/ BITS_PER_UNIT
- 1)
5920 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1));
5922 cfun_frame_layout
.frame_size
+= current_function_outgoing_args_size
;
5926 /* Return offset between argument pointer and frame pointer
5927 initially after prologue. */
5930 s390_arg_frame_offset (void)
5932 /* See the comment in s390_emit_prologue about the assumptions we make
5933 whether or not the base and return address register need to be saved. */
5934 int return_addr_used
= !current_function_is_leaf
5935 || TARGET_TPF_PROFILING
5936 || regs_ever_live
[RETURN_REGNUM
]
5937 || cfun_frame_layout
.save_return_addr_p
;
5939 s390_frame_info (1, !TARGET_CPU_ZARCH
|| return_addr_used
);
5941 return cfun_frame_layout
.frame_size
+ STACK_POINTER_OFFSET
;
5944 /* Return offset between return address pointer (location of r14
5945 on the stack) and frame pointer initially after prologue. */
5948 s390_return_address_offset (void)
5950 s390_frame_info (1, 1);
5952 if (cfun_frame_layout
.last_save_gpr
< RETURN_REGNUM
)
5955 return (cfun_frame_layout
.frame_size
+ cfun_frame_layout
.gprs_offset
5956 + (RETURN_REGNUM
- cfun_frame_layout
.first_save_gpr
) * UNITS_PER_WORD
);
5959 /* Emit insn to save fpr REGNUM at offset OFFSET relative
5960 to register BASE. Return generated insn. */
5963 save_fpr (rtx base
, int offset
, int regnum
)
5966 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
5967 set_mem_alias_set (addr
, s390_sr_alias_set
);
5969 return emit_move_insn (addr
, gen_rtx_REG (DFmode
, regnum
));
5972 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
5973 to register BASE. Return generated insn. */
5976 restore_fpr (rtx base
, int offset
, int regnum
)
5979 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
5980 set_mem_alias_set (addr
, s390_sr_alias_set
);
5982 return emit_move_insn (gen_rtx_REG (DFmode
, regnum
), addr
);
5985 /* Generate insn to save registers FIRST to LAST into
5986 the register save area located at offset OFFSET
5987 relative to register BASE. */
5990 save_gprs (rtx base
, int offset
, int first
, int last
)
5992 rtx addr
, insn
, note
;
5995 addr
= plus_constant (base
, offset
);
5996 addr
= gen_rtx_MEM (Pmode
, addr
);
5997 set_mem_alias_set (addr
, s390_sr_alias_set
);
5999 /* Special-case single register. */
6003 insn
= gen_movdi (addr
, gen_rtx_REG (Pmode
, first
));
6005 insn
= gen_movsi (addr
, gen_rtx_REG (Pmode
, first
));
6007 RTX_FRAME_RELATED_P (insn
) = 1;
6012 insn
= gen_store_multiple (addr
,
6013 gen_rtx_REG (Pmode
, first
),
6014 GEN_INT (last
- first
+ 1));
6017 /* We need to set the FRAME_RELATED flag on all SETs
6018 inside the store-multiple pattern.
6020 However, we must not emit DWARF records for registers 2..5
6021 if they are stored for use by variable arguments ...
6023 ??? Unfortunately, it is not enough to simply not the the
6024 FRAME_RELATED flags for those SETs, because the first SET
6025 of the PARALLEL is always treated as if it had the flag
6026 set, even if it does not. Therefore we emit a new pattern
6027 without those registers as REG_FRAME_RELATED_EXPR note. */
6031 rtx pat
= PATTERN (insn
);
6033 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
6034 if (GET_CODE (XVECEXP (pat
, 0, i
)) == SET
)
6035 RTX_FRAME_RELATED_P (XVECEXP (pat
, 0, i
)) = 1;
6037 RTX_FRAME_RELATED_P (insn
) = 1;
6041 addr
= plus_constant (base
, offset
+ (6 - first
) * UNITS_PER_WORD
);
6042 note
= gen_store_multiple (gen_rtx_MEM (Pmode
, addr
),
6043 gen_rtx_REG (Pmode
, 6),
6044 GEN_INT (last
- 6 + 1));
6045 note
= PATTERN (note
);
6048 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
6049 note
, REG_NOTES (insn
));
6051 for (i
= 0; i
< XVECLEN (note
, 0); i
++)
6052 if (GET_CODE (XVECEXP (note
, 0, i
)) == SET
)
6053 RTX_FRAME_RELATED_P (XVECEXP (note
, 0, i
)) = 1;
6055 RTX_FRAME_RELATED_P (insn
) = 1;
6061 /* Generate insn to restore registers FIRST to LAST from
6062 the register save area located at offset OFFSET
6063 relative to register BASE. */
6066 restore_gprs (rtx base
, int offset
, int first
, int last
)
6070 addr
= plus_constant (base
, offset
);
6071 addr
= gen_rtx_MEM (Pmode
, addr
);
6072 set_mem_alias_set (addr
, s390_sr_alias_set
);
6074 /* Special-case single register. */
6078 insn
= gen_movdi (gen_rtx_REG (Pmode
, first
), addr
);
6080 insn
= gen_movsi (gen_rtx_REG (Pmode
, first
), addr
);
6085 insn
= gen_load_multiple (gen_rtx_REG (Pmode
, first
),
6087 GEN_INT (last
- first
+ 1));
6091 /* Return insn sequence to load the GOT register. */
6093 static GTY(()) rtx got_symbol
;
6095 s390_load_got (void)
6101 got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
6102 SYMBOL_REF_FLAGS (got_symbol
) = SYMBOL_FLAG_LOCAL
;
6107 if (TARGET_CPU_ZARCH
)
6109 emit_move_insn (pic_offset_table_rtx
, got_symbol
);
6115 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, got_symbol
),
6116 UNSPEC_LTREL_OFFSET
);
6117 offset
= gen_rtx_CONST (Pmode
, offset
);
6118 offset
= force_const_mem (Pmode
, offset
);
6120 emit_move_insn (pic_offset_table_rtx
, offset
);
6122 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, XEXP (offset
, 0)),
6124 offset
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, offset
);
6126 emit_move_insn (pic_offset_table_rtx
, offset
);
6129 insns
= get_insns ();
6134 /* Expand the prologue into a bunch of separate insns. */
6137 s390_emit_prologue (void)
6145 /* At this point, we decide whether we'll need to save/restore the
6146 return address register. This decision is final on zSeries machines;
6147 on S/390 it can still be overridden in s390_split_branches. */
6149 if (!current_function_is_leaf
6150 || TARGET_TPF_PROFILING
6151 || regs_ever_live
[RETURN_REGNUM
])
6152 cfun_frame_layout
.save_return_addr_p
= 1;
6154 /* Decide which register to use as literal pool base. In small leaf
6155 functions, try to use an unused call-clobbered register as base
6156 register to avoid save/restore overhead. */
6158 if (current_function_is_leaf
&& !regs_ever_live
[5])
6159 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, 5);
6161 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
6163 regs_ever_live
[REGNO (cfun
->machine
->base_reg
)] = 1;
6165 /* Compute frame info. Note that at this point, we assume the base
6166 register and -on S/390- the return register always need to be saved.
6167 This is done because the usage of these registers might change even
6168 after the prologue was emitted. If it turns out later that we really
6169 don't need them, the prologue/epilogue code is modified again. */
6171 s390_frame_info (1, !TARGET_CPU_ZARCH
6172 || cfun_frame_layout
.save_return_addr_p
);
6174 /* We need to update regs_ever_live to avoid data-flow problems. */
6176 regs_ever_live
[BASE_REGNUM
] = 1;
6177 regs_ever_live
[RETURN_REGNUM
] = (!TARGET_CPU_ZARCH
6178 || cfun_frame_layout
.save_return_addr_p
);
6179 regs_ever_live
[STACK_POINTER_REGNUM
] = cfun_frame_layout
.frame_size
> 0;
6181 /* Annotate all constant pool references to let the scheduler know
6182 they implicitly use the base register. */
6184 push_topmost_sequence ();
6186 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6188 annotate_constant_pool_refs (&PATTERN (insn
));
6190 pop_topmost_sequence ();
6192 /* Choose best register to use for temp use within prologue.
6193 See below for why TPF must use the register 1. */
6195 if (!current_function_is_leaf
&& !TARGET_TPF_PROFILING
)
6196 temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
6198 temp_reg
= gen_rtx_REG (Pmode
, 1);
6200 /* Save call saved gprs. */
6201 if (cfun_frame_layout
.first_save_gpr
!= -1)
6202 insn
= save_gprs (stack_pointer_rtx
,
6203 cfun_frame_layout
.gprs_offset
,
6204 cfun_frame_layout
.first_save_gpr
,
6205 cfun_frame_layout
.last_save_gpr
);
6208 /* Dummy insn to mark literal pool slot. */
6210 emit_insn (gen_main_pool (cfun
->machine
->base_reg
));
6212 offset
= cfun_frame_layout
.f0_offset
;
6214 /* Save f0 and f2. */
6215 for (i
= 0; i
< 2; i
++)
6217 if (cfun_fpr_bit_p (i
))
6219 save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
6222 else if (TARGET_BACKCHAIN
)
6226 /* Save f4 and f6. */
6227 offset
= cfun_frame_layout
.f4_offset
;
6228 for (i
= 2; i
< 4; i
++)
6230 if (cfun_fpr_bit_p (i
))
6232 insn
= save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
6235 /* If f4 and f6 are call clobbered they are saved due to stdargs and
6236 therefore are not frame related. */
6237 if (!call_really_used_regs
[i
+ 16])
6238 RTX_FRAME_RELATED_P (insn
) = 1;
6240 else if (TARGET_BACKCHAIN
)
6244 if (!TARGET_BACKCHAIN
6245 && cfun_save_high_fprs_p
6246 && cfun_frame_layout
.f8_offset
+ cfun_frame_layout
.high_fprs
* 8 > 0)
6248 offset
= (cfun_frame_layout
.f8_offset
6249 + (cfun_frame_layout
.high_fprs
- 1) * 8);
6251 for (i
= 15; i
> 7 && offset
>= 0; i
--)
6252 if (cfun_fpr_bit_p (i
))
6254 insn
= save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
6256 RTX_FRAME_RELATED_P (insn
) = 1;
6259 if (offset
>= cfun_frame_layout
.f8_offset
)
6263 if (TARGET_BACKCHAIN
)
6264 next_fpr
= cfun_save_high_fprs_p
? 31 : 0;
6266 /* Decrement stack pointer. */
6268 if (cfun_frame_layout
.frame_size
> 0)
6270 rtx frame_off
= GEN_INT (-cfun_frame_layout
.frame_size
);
6272 /* Save incoming stack pointer into temp reg. */
6273 if (cfun_frame_layout
.save_backchain_p
|| next_fpr
)
6274 insn
= emit_insn (gen_move_insn (temp_reg
, stack_pointer_rtx
));
6276 /* Subtract frame size from stack pointer. */
6278 if (DISP_IN_RANGE (INTVAL (frame_off
)))
6280 insn
= gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
6281 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
6283 insn
= emit_insn (insn
);
6287 if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off
), 'K', "K"))
6288 frame_off
= force_const_mem (Pmode
, frame_off
);
6290 insn
= emit_insn (gen_add2_insn (stack_pointer_rtx
, frame_off
));
6291 annotate_constant_pool_refs (&PATTERN (insn
));
6294 RTX_FRAME_RELATED_P (insn
) = 1;
6296 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
6297 gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
6298 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
6299 GEN_INT (-cfun_frame_layout
.frame_size
))),
6302 /* Set backchain. */
6304 if (cfun_frame_layout
.save_backchain_p
)
6306 if (cfun_frame_layout
.backchain_offset
)
6307 addr
= gen_rtx_MEM (Pmode
,
6308 plus_constant (stack_pointer_rtx
,
6309 cfun_frame_layout
.backchain_offset
));
6311 addr
= gen_rtx_MEM (Pmode
, stack_pointer_rtx
);
6312 set_mem_alias_set (addr
, s390_sr_alias_set
);
6313 insn
= emit_insn (gen_move_insn (addr
, temp_reg
));
6316 /* If we support asynchronous exceptions (e.g. for Java),
6317 we need to make sure the backchain pointer is set up
6318 before any possibly trapping memory access. */
6320 if (cfun_frame_layout
.save_backchain_p
&& flag_non_call_exceptions
)
6322 addr
= gen_rtx_MEM (BLKmode
, gen_rtx_SCRATCH (VOIDmode
));
6323 emit_insn (gen_rtx_CLOBBER (VOIDmode
, addr
));
6327 /* Save fprs 8 - 15 (64 bit ABI). */
6329 if (cfun_save_high_fprs_p
&& next_fpr
)
6331 insn
= emit_insn (gen_add2_insn (temp_reg
,
6332 GEN_INT (cfun_frame_layout
.f8_offset
)));
6336 for (i
= 24; i
<= next_fpr
; i
++)
6337 if (cfun_fpr_bit_p (i
- 16))
6339 rtx addr
= plus_constant (stack_pointer_rtx
,
6340 cfun_frame_layout
.frame_size
6341 + cfun_frame_layout
.f8_offset
6344 insn
= save_fpr (temp_reg
, offset
, i
);
6346 RTX_FRAME_RELATED_P (insn
) = 1;
6348 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
6349 gen_rtx_SET (VOIDmode
,
6350 gen_rtx_MEM (DFmode
, addr
),
6351 gen_rtx_REG (DFmode
, i
)),
6356 /* Set frame pointer, if needed. */
6358 if (frame_pointer_needed
)
6360 insn
= emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
);
6361 RTX_FRAME_RELATED_P (insn
) = 1;
6364 /* Set up got pointer, if needed. */
6366 if (flag_pic
&& regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
])
6368 rtx insns
= s390_load_got ();
6370 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
6372 annotate_constant_pool_refs (&PATTERN (insn
));
6374 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD
, NULL_RTX
,
6381 if (TARGET_TPF_PROFILING
)
6383 /* Generate a BAS instruction to serve as a function
6384 entry intercept to facilitate the use of tracing
6385 algorithms located at the branch target. */
6386 emit_insn (gen_prologue_tpf ());
6388 /* Emit a blockage here so that all code
6389 lies between the profiling mechanisms. */
6390 emit_insn (gen_blockage ());
6394 /* Expand the epilogue into a bunch of separate insns. */
6397 s390_emit_epilogue (bool sibcall
)
6399 rtx frame_pointer
, return_reg
;
6400 int area_bottom
, area_top
, offset
= 0;
6405 if (TARGET_TPF_PROFILING
)
6408 /* Generate a BAS instruction to serve as a function
6409 entry intercept to facilitate the use of tracing
6410 algorithms located at the branch target. */
6412 /* Emit a blockage here so that all code
6413 lies between the profiling mechanisms. */
6414 emit_insn (gen_blockage ());
6416 emit_insn (gen_epilogue_tpf ());
6419 /* Check whether to use frame or stack pointer for restore. */
6421 frame_pointer
= (frame_pointer_needed
6422 ? hard_frame_pointer_rtx
: stack_pointer_rtx
);
6424 s390_frame_area (&area_bottom
, &area_top
);
6426 /* Check whether we can access the register save area.
6427 If not, increment the frame pointer as required. */
6429 if (area_top
<= area_bottom
)
6431 /* Nothing to restore. */
6433 else if (DISP_IN_RANGE (cfun_frame_layout
.frame_size
+ area_bottom
)
6434 && DISP_IN_RANGE (cfun_frame_layout
.frame_size
+ area_top
- 1))
6436 /* Area is in range. */
6437 offset
= cfun_frame_layout
.frame_size
;
6441 rtx insn
, frame_off
;
6443 offset
= area_bottom
< 0 ? -area_bottom
: 0;
6444 frame_off
= GEN_INT (cfun_frame_layout
.frame_size
- offset
);
6446 if (DISP_IN_RANGE (INTVAL (frame_off
)))
6448 insn
= gen_rtx_SET (VOIDmode
, frame_pointer
,
6449 gen_rtx_PLUS (Pmode
, frame_pointer
, frame_off
));
6450 insn
= emit_insn (insn
);
6454 if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off
), 'K', "K"))
6455 frame_off
= force_const_mem (Pmode
, frame_off
);
6457 insn
= emit_insn (gen_add2_insn (frame_pointer
, frame_off
));
6458 annotate_constant_pool_refs (&PATTERN (insn
));
6462 /* Restore call saved fprs. */
6466 if (cfun_save_high_fprs_p
)
6468 next_offset
= cfun_frame_layout
.f8_offset
;
6469 for (i
= 24; i
< 32; i
++)
6471 if (cfun_fpr_bit_p (i
- 16))
6473 restore_fpr (frame_pointer
,
6474 offset
+ next_offset
, i
);
6483 next_offset
= cfun_frame_layout
.f4_offset
;
6484 for (i
= 18; i
< 20; i
++)
6486 if (cfun_fpr_bit_p (i
- 16))
6488 restore_fpr (frame_pointer
,
6489 offset
+ next_offset
, i
);
6492 else if (TARGET_BACKCHAIN
)
6498 /* Return register. */
6500 return_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
6502 /* Restore call saved gprs. */
6504 if (cfun_frame_layout
.first_restore_gpr
!= -1)
6509 /* Check for global register and save them
6510 to stack location from where they get restored. */
6512 for (i
= cfun_frame_layout
.first_restore_gpr
;
6513 i
<= cfun_frame_layout
.last_restore_gpr
;
6516 /* These registers are special and need to be
6517 restored in any case. */
6518 if (i
== STACK_POINTER_REGNUM
6519 || i
== RETURN_REGNUM
6521 || (flag_pic
&& i
== (int)PIC_OFFSET_TABLE_REGNUM
))
6526 addr
= plus_constant (frame_pointer
,
6527 offset
+ cfun_frame_layout
.gprs_offset
6528 + (i
- cfun_frame_layout
.first_save_gpr
)
6530 addr
= gen_rtx_MEM (Pmode
, addr
);
6531 set_mem_alias_set (addr
, s390_sr_alias_set
);
6532 emit_move_insn (addr
, gen_rtx_REG (Pmode
, i
));
6538 /* Fetch return address from stack before load multiple,
6539 this will do good for scheduling. */
6541 if (cfun_frame_layout
.save_return_addr_p
6542 || (cfun_frame_layout
.first_restore_gpr
< BASE_REGNUM
6543 && cfun_frame_layout
.last_restore_gpr
> RETURN_REGNUM
))
6545 int return_regnum
= find_unused_clobbered_reg();
6548 return_reg
= gen_rtx_REG (Pmode
, return_regnum
);
6550 addr
= plus_constant (frame_pointer
,
6551 offset
+ cfun_frame_layout
.gprs_offset
6553 - cfun_frame_layout
.first_save_gpr
)
6555 addr
= gen_rtx_MEM (Pmode
, addr
);
6556 set_mem_alias_set (addr
, s390_sr_alias_set
);
6557 emit_move_insn (return_reg
, addr
);
6561 insn
= restore_gprs (frame_pointer
,
6562 offset
+ cfun_frame_layout
.gprs_offset
6563 + (cfun_frame_layout
.first_restore_gpr
6564 - cfun_frame_layout
.first_save_gpr
)
6566 cfun_frame_layout
.first_restore_gpr
,
6567 cfun_frame_layout
.last_restore_gpr
);
6574 /* Return to caller. */
6576 p
= rtvec_alloc (2);
6578 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
6579 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
, return_reg
);
6580 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
6585 /* Return the size in bytes of a function argument of
6586 type TYPE and/or mode MODE. At least one of TYPE or
6587 MODE must be specified. */
6590 s390_function_arg_size (enum machine_mode mode
, tree type
)
6593 return int_size_in_bytes (type
);
6595 /* No type info available for some library calls ... */
6596 if (mode
!= BLKmode
)
6597 return GET_MODE_SIZE (mode
);
6599 /* If we have neither type nor mode, abort */
6603 /* Return true if a function argument of type TYPE and mode MODE
6604 is to be passed in a floating-point register, if available. */
6607 s390_function_arg_float (enum machine_mode mode
, tree type
)
6609 int size
= s390_function_arg_size (mode
, type
);
6613 /* Soft-float changes the ABI: no floating-point registers are used. */
6614 if (TARGET_SOFT_FLOAT
)
6617 /* No type info available for some library calls ... */
6619 return mode
== SFmode
|| mode
== DFmode
;
6621 /* The ABI says that record types with a single member are treated
6622 just like that member would be. */
6623 while (TREE_CODE (type
) == RECORD_TYPE
)
6625 tree field
, single
= NULL_TREE
;
6627 for (field
= TYPE_FIELDS (type
); field
; field
= TREE_CHAIN (field
))
6629 if (TREE_CODE (field
) != FIELD_DECL
)
6632 if (single
== NULL_TREE
)
6633 single
= TREE_TYPE (field
);
6638 if (single
== NULL_TREE
)
6644 return TREE_CODE (type
) == REAL_TYPE
;
6647 /* Return true if a function argument of type TYPE and mode MODE
6648 is to be passed in an integer register, or a pair of integer
6649 registers, if available. */
6652 s390_function_arg_integer (enum machine_mode mode
, tree type
)
6654 int size
= s390_function_arg_size (mode
, type
);
6658 /* No type info available for some library calls ... */
6660 return GET_MODE_CLASS (mode
) == MODE_INT
6661 || (TARGET_SOFT_FLOAT
&& GET_MODE_CLASS (mode
) == MODE_FLOAT
);
6663 /* We accept small integral (and similar) types. */
6664 if (INTEGRAL_TYPE_P (type
)
6665 || POINTER_TYPE_P (type
)
6666 || TREE_CODE (type
) == OFFSET_TYPE
6667 || (TARGET_SOFT_FLOAT
&& TREE_CODE (type
) == REAL_TYPE
))
6670 /* We also accept structs of size 1, 2, 4, 8 that are not
6671 passed in floating-point registers. */
6672 if (AGGREGATE_TYPE_P (type
)
6673 && exact_log2 (size
) >= 0
6674 && !s390_function_arg_float (mode
, type
))
6680 /* Return 1 if a function argument of type TYPE and mode MODE
6681 is to be passed by reference. The ABI specifies that only
6682 structures of size 1, 2, 4, or 8 bytes are passed by value,
6683 all other structures (and complex numbers) are passed by
6687 s390_pass_by_reference (CUMULATIVE_ARGS
*ca ATTRIBUTE_UNUSED
,
6688 enum machine_mode mode
, tree type
,
6689 bool named ATTRIBUTE_UNUSED
)
6691 int size
= s390_function_arg_size (mode
, type
);
6697 if (AGGREGATE_TYPE_P (type
) && exact_log2 (size
) < 0)
6700 if (TREE_CODE (type
) == COMPLEX_TYPE
6701 || TREE_CODE (type
) == VECTOR_TYPE
)
6708 /* Update the data in CUM to advance over an argument of mode MODE and
6709 data type TYPE. (TYPE is null for libcalls where that information
6710 may not be available.). The boolean NAMED specifies whether the
6711 argument is a named argument (as opposed to an unnamed argument
6712 matching an ellipsis). */
6715 s390_function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
6716 tree type
, int named ATTRIBUTE_UNUSED
)
6718 if (s390_function_arg_float (mode
, type
))
6722 else if (s390_function_arg_integer (mode
, type
))
6724 int size
= s390_function_arg_size (mode
, type
);
6725 cum
->gprs
+= ((size
+ UNITS_PER_WORD
-1) / UNITS_PER_WORD
);
6731 /* Define where to put the arguments to a function.
6732 Value is zero to push the argument on the stack,
6733 or a hard register in which to store the argument.
6735 MODE is the argument's machine mode.
6736 TYPE is the data type of the argument (as a tree).
6737 This is null for libcalls where that information may
6739 CUM is a variable of type CUMULATIVE_ARGS which gives info about
6740 the preceding args and about the function being called.
6741 NAMED is nonzero if this argument is a named parameter
6742 (otherwise it is an extra parameter matching an ellipsis).
6744 On S/390, we use general purpose registers 2 through 6 to
6745 pass integer, pointer, and certain structure arguments, and
6746 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
6747 to pass floating point arguments. All remaining arguments
6748 are pushed to the stack. */
6751 s390_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
, tree type
,
6752 int named ATTRIBUTE_UNUSED
)
6754 if (s390_function_arg_float (mode
, type
))
6756 if (cum
->fprs
+ 1 > (TARGET_64BIT
? 4 : 2))
6759 return gen_rtx_REG (mode
, cum
->fprs
+ 16);
6761 else if (s390_function_arg_integer (mode
, type
))
6763 int size
= s390_function_arg_size (mode
, type
);
6764 int n_gprs
= (size
+ UNITS_PER_WORD
-1) / UNITS_PER_WORD
;
6766 if (cum
->gprs
+ n_gprs
> 5)
6769 return gen_rtx_REG (mode
, cum
->gprs
+ 2);
6772 /* After the real arguments, expand_call calls us once again
6773 with a void_type_node type. Whatever we return here is
6774 passed as operand 2 to the call expanders.
6776 We don't need this feature ... */
6777 else if (type
== void_type_node
)
6783 /* Return true if return values of type TYPE should be returned
6784 in a memory buffer whose address is passed by the caller as
6785 hidden first argument. */
6788 s390_return_in_memory (tree type
, tree fundecl ATTRIBUTE_UNUSED
)
6790 /* We accept small integral (and similar) types. */
6791 if (INTEGRAL_TYPE_P (type
)
6792 || POINTER_TYPE_P (type
)
6793 || TREE_CODE (type
) == OFFSET_TYPE
6794 || TREE_CODE (type
) == REAL_TYPE
)
6795 return int_size_in_bytes (type
) > 8;
6797 /* Aggregates and similar constructs are always returned
6799 if (AGGREGATE_TYPE_P (type
)
6800 || TREE_CODE (type
) == COMPLEX_TYPE
6801 || TREE_CODE (type
) == VECTOR_TYPE
)
6804 /* ??? We get called on all sorts of random stuff from
6805 aggregate_value_p. We can't abort, but it's not clear
6806 what's safe to return. Pretend it's a struct I guess. */
6810 /* Define where to return a (scalar) value of type TYPE.
6811 If TYPE is null, define where to return a (scalar)
6812 value of mode MODE from a libcall. */
6815 s390_function_value (tree type
, enum machine_mode mode
)
6819 int unsignedp
= TYPE_UNSIGNED (type
);
6820 mode
= promote_mode (type
, TYPE_MODE (type
), &unsignedp
, 1);
6823 if (GET_MODE_CLASS (mode
) != MODE_INT
6824 && GET_MODE_CLASS (mode
) != MODE_FLOAT
)
6826 if (GET_MODE_SIZE (mode
) > 8)
6829 if (TARGET_HARD_FLOAT
&& GET_MODE_CLASS (mode
) == MODE_FLOAT
)
6830 return gen_rtx_REG (mode
, 16);
6832 return gen_rtx_REG (mode
, 2);
6836 /* Create and return the va_list datatype.
6838 On S/390, va_list is an array type equivalent to
6840 typedef struct __va_list_tag
6844 void *__overflow_arg_area;
6845 void *__reg_save_area;
6848 where __gpr and __fpr hold the number of general purpose
6849 or floating point arguments used up to now, respectively,
6850 __overflow_arg_area points to the stack location of the
6851 next argument passed on the stack, and __reg_save_area
6852 always points to the start of the register area in the
6853 call frame of the current function. The function prologue
6854 saves all registers used for argument passing into this
6855 area if the function uses variable arguments. */
6858 s390_build_builtin_va_list (void)
6860 tree f_gpr
, f_fpr
, f_ovf
, f_sav
, record
, type_decl
;
6862 record
= lang_hooks
.types
.make_type (RECORD_TYPE
);
6865 build_decl (TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
6867 f_gpr
= build_decl (FIELD_DECL
, get_identifier ("__gpr"),
6868 long_integer_type_node
);
6869 f_fpr
= build_decl (FIELD_DECL
, get_identifier ("__fpr"),
6870 long_integer_type_node
);
6871 f_ovf
= build_decl (FIELD_DECL
, get_identifier ("__overflow_arg_area"),
6873 f_sav
= build_decl (FIELD_DECL
, get_identifier ("__reg_save_area"),
6876 DECL_FIELD_CONTEXT (f_gpr
) = record
;
6877 DECL_FIELD_CONTEXT (f_fpr
) = record
;
6878 DECL_FIELD_CONTEXT (f_ovf
) = record
;
6879 DECL_FIELD_CONTEXT (f_sav
) = record
;
6881 TREE_CHAIN (record
) = type_decl
;
6882 TYPE_NAME (record
) = type_decl
;
6883 TYPE_FIELDS (record
) = f_gpr
;
6884 TREE_CHAIN (f_gpr
) = f_fpr
;
6885 TREE_CHAIN (f_fpr
) = f_ovf
;
6886 TREE_CHAIN (f_ovf
) = f_sav
;
6888 layout_type (record
);
6890 /* The correct type is an array type of one element. */
6891 return build_array_type (record
, build_index_type (size_zero_node
));
6894 /* Implement va_start by filling the va_list structure VALIST.
6895 STDARG_P is always true, and ignored.
6896 NEXTARG points to the first anonymous stack argument.
6898 The following global variables are used to initialize
6899 the va_list structure:
6901 current_function_args_info:
6902 holds number of gprs and fprs used for named arguments.
6903 current_function_arg_offset_rtx:
6904 holds the offset of the first anonymous stack argument
6905 (relative to the virtual arg pointer). */
6908 s390_va_start (tree valist
, rtx nextarg ATTRIBUTE_UNUSED
)
6910 HOST_WIDE_INT n_gpr
, n_fpr
;
6912 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
6913 tree gpr
, fpr
, ovf
, sav
, t
;
6915 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
6916 f_fpr
= TREE_CHAIN (f_gpr
);
6917 f_ovf
= TREE_CHAIN (f_fpr
);
6918 f_sav
= TREE_CHAIN (f_ovf
);
6920 valist
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (valist
)), valist
);
6921 gpr
= build (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
6922 fpr
= build (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
6923 ovf
= build (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
6924 sav
= build (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
6926 /* Count number of gp and fp argument registers used. */
6928 n_gpr
= current_function_args_info
.gprs
;
6929 n_fpr
= current_function_args_info
.fprs
;
6931 t
= build (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
,
6932 build_int_cst (NULL_TREE
, n_gpr
, 0));
6933 TREE_SIDE_EFFECTS (t
) = 1;
6934 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6936 t
= build (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
,
6937 build_int_cst (NULL_TREE
, n_fpr
, 0));
6938 TREE_SIDE_EFFECTS (t
) = 1;
6939 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6941 /* Find the overflow area. */
6942 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
6944 off
= INTVAL (current_function_arg_offset_rtx
);
6945 off
= off
< 0 ? 0 : off
;
6946 if (TARGET_DEBUG_ARG
)
6947 fprintf (stderr
, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
6948 (int)n_gpr
, (int)n_fpr
, off
);
6950 t
= build (PLUS_EXPR
, TREE_TYPE (ovf
), t
, build_int_cst (NULL_TREE
, off
, 0));
6952 t
= build (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
6953 TREE_SIDE_EFFECTS (t
) = 1;
6954 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6956 /* Find the register save area. */
6957 t
= make_tree (TREE_TYPE (sav
), return_address_pointer_rtx
);
6958 if (TARGET_KERNEL_BACKCHAIN
)
6959 t
= build (PLUS_EXPR
, TREE_TYPE (sav
), t
,
6960 build_int_cst (NULL_TREE
,
6961 -(RETURN_REGNUM
- 2) * UNITS_PER_WORD
6962 - (TARGET_64BIT
? 4 : 2) * 8, -1));
6964 t
= build (PLUS_EXPR
, TREE_TYPE (sav
), t
,
6965 build_int_cst (NULL_TREE
, -RETURN_REGNUM
* UNITS_PER_WORD
, -1));
6967 t
= build (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
6968 TREE_SIDE_EFFECTS (t
) = 1;
6969 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6972 /* Implement va_arg by updating the va_list structure
6973 VALIST as required to retrieve an argument of type
6974 TYPE, and returning that argument.
6976 Generates code equivalent to:
6978 if (integral value) {
6979 if (size <= 4 && args.gpr < 5 ||
6980 size > 4 && args.gpr < 4 )
6981 ret = args.reg_save_area[args.gpr+8]
6983 ret = *args.overflow_arg_area++;
6984 } else if (float value) {
6986 ret = args.reg_save_area[args.fpr+64]
6988 ret = *args.overflow_arg_area++;
6989 } else if (aggregate value) {
6991 ret = *args.reg_save_area[args.gpr]
6993 ret = **args.overflow_arg_area++;
6997 s390_gimplify_va_arg (tree valist
, tree type
, tree
*pre_p
,
6998 tree
*post_p ATTRIBUTE_UNUSED
)
7000 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
7001 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
7002 int indirect_p
, size
, n_reg
, sav_ofs
, sav_scale
, max_reg
;
7003 tree lab_false
, lab_over
, addr
;
7005 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
7006 f_fpr
= TREE_CHAIN (f_gpr
);
7007 f_ovf
= TREE_CHAIN (f_fpr
);
7008 f_sav
= TREE_CHAIN (f_ovf
);
7010 valist
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (valist
)), valist
);
7011 gpr
= build (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
7012 fpr
= build (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
7013 ovf
= build (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
7014 sav
= build (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
7016 size
= int_size_in_bytes (type
);
7018 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
7020 if (TARGET_DEBUG_ARG
)
7022 fprintf (stderr
, "va_arg: aggregate type");
7026 /* Aggregates are passed by reference. */
7030 sav_ofs
= (TARGET_KERNEL_BACKCHAIN
7031 ? (TARGET_64BIT
? 4 : 2) * 8 : 2 * UNITS_PER_WORD
);
7032 sav_scale
= UNITS_PER_WORD
;
7033 size
= UNITS_PER_WORD
;
7036 else if (s390_function_arg_float (TYPE_MODE (type
), type
))
7038 if (TARGET_DEBUG_ARG
)
7040 fprintf (stderr
, "va_arg: float type");
7044 /* FP args go in FP registers, if present. */
7048 sav_ofs
= TARGET_KERNEL_BACKCHAIN
? 0 : 16 * UNITS_PER_WORD
;
7050 /* TARGET_64BIT has up to 4 parameter in fprs */
7051 max_reg
= TARGET_64BIT
? 3 : 1;
7055 if (TARGET_DEBUG_ARG
)
7057 fprintf (stderr
, "va_arg: other type");
7061 /* Otherwise into GP registers. */
7064 n_reg
= (size
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
7065 sav_ofs
= TARGET_KERNEL_BACKCHAIN
?
7066 (TARGET_64BIT
? 4 : 2) * 8 : 2*UNITS_PER_WORD
;
7068 if (size
< UNITS_PER_WORD
)
7069 sav_ofs
+= UNITS_PER_WORD
- size
;
7071 sav_scale
= UNITS_PER_WORD
;
7078 /* Pull the value out of the saved registers ... */
7080 lab_false
= create_artificial_label ();
7081 lab_over
= create_artificial_label ();
7082 addr
= create_tmp_var (ptr_type_node
, "addr");
7084 t
= fold_convert (TREE_TYPE (reg
), size_int (max_reg
));
7085 t
= build2 (GT_EXPR
, boolean_type_node
, reg
, t
);
7086 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
7087 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
7088 gimplify_and_add (t
, pre_p
);
7090 t
= build2 (PLUS_EXPR
, ptr_type_node
, sav
,
7091 fold_convert (ptr_type_node
, size_int (sav_ofs
)));
7092 u
= build2 (MULT_EXPR
, TREE_TYPE (reg
), reg
,
7093 fold_convert (TREE_TYPE (reg
), size_int (sav_scale
)));
7094 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
, fold_convert (ptr_type_node
, u
));
7096 t
= build2 (MODIFY_EXPR
, void_type_node
, addr
, t
);
7097 gimplify_and_add (t
, pre_p
);
7099 t
= build1 (GOTO_EXPR
, void_type_node
, lab_over
);
7100 gimplify_and_add (t
, pre_p
);
7102 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false
);
7103 append_to_statement_list (t
, pre_p
);
7106 /* ... Otherwise out of the overflow area. */
7109 if (size
< UNITS_PER_WORD
)
7110 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
,
7111 fold_convert (ptr_type_node
, size_int (UNITS_PER_WORD
- size
)));
7113 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
7115 u
= build2 (MODIFY_EXPR
, void_type_node
, addr
, t
);
7116 gimplify_and_add (u
, pre_p
);
7118 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
,
7119 fold_convert (ptr_type_node
, size_int (size
)));
7120 t
= build2 (MODIFY_EXPR
, ptr_type_node
, ovf
, t
);
7121 gimplify_and_add (t
, pre_p
);
7123 t
= build1 (LABEL_EXPR
, void_type_node
, lab_over
);
7124 append_to_statement_list (t
, pre_p
);
7127 /* Increment register save count. */
7129 u
= build2 (PREINCREMENT_EXPR
, TREE_TYPE (reg
), reg
,
7130 fold_convert (TREE_TYPE (reg
), size_int (n_reg
)));
7131 gimplify_and_add (u
, pre_p
);
7135 t
= build_pointer_type (build_pointer_type (type
));
7136 addr
= fold_convert (t
, addr
);
7137 addr
= build_fold_indirect_ref (addr
);
7141 t
= build_pointer_type (type
);
7142 addr
= fold_convert (t
, addr
);
7145 return build_fold_indirect_ref (addr
);
7153 S390_BUILTIN_THREAD_POINTER
,
7154 S390_BUILTIN_SET_THREAD_POINTER
,
7159 static unsigned int const code_for_builtin_64
[S390_BUILTIN_max
] = {
7164 static unsigned int const code_for_builtin_31
[S390_BUILTIN_max
] = {
7170 s390_init_builtins (void)
7174 ftype
= build_function_type (ptr_type_node
, void_list_node
);
7175 lang_hooks
.builtin_function ("__builtin_thread_pointer", ftype
,
7176 S390_BUILTIN_THREAD_POINTER
, BUILT_IN_MD
,
7179 ftype
= build_function_type_list (void_type_node
, ptr_type_node
, NULL_TREE
);
7180 lang_hooks
.builtin_function ("__builtin_set_thread_pointer", ftype
,
7181 S390_BUILTIN_SET_THREAD_POINTER
, BUILT_IN_MD
,
7185 /* Expand an expression EXP that calls a built-in function,
7186 with result going to TARGET if that's convenient
7187 (and in mode MODE if that's convenient).
7188 SUBTARGET may be used as the target for computing one of EXP's operands.
7189 IGNORE is nonzero if the value is to be ignored. */
7192 s390_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
7193 enum machine_mode mode ATTRIBUTE_UNUSED
,
7194 int ignore ATTRIBUTE_UNUSED
)
7198 unsigned int const *code_for_builtin
=
7199 TARGET_64BIT
? code_for_builtin_64
: code_for_builtin_31
;
7201 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
7202 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7203 tree arglist
= TREE_OPERAND (exp
, 1);
7204 enum insn_code icode
;
7205 rtx op
[MAX_ARGS
], pat
;
7209 if (fcode
>= S390_BUILTIN_max
)
7210 internal_error ("bad builtin fcode");
7211 icode
= code_for_builtin
[fcode
];
7213 internal_error ("bad builtin fcode");
7215 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
7217 for (arglist
= TREE_OPERAND (exp
, 1), arity
= 0;
7219 arglist
= TREE_CHAIN (arglist
), arity
++)
7221 const struct insn_operand_data
*insn_op
;
7223 tree arg
= TREE_VALUE (arglist
);
7224 if (arg
== error_mark_node
)
7226 if (arity
> MAX_ARGS
)
7229 insn_op
= &insn_data
[icode
].operand
[arity
+ nonvoid
];
7231 op
[arity
] = expand_expr (arg
, NULL_RTX
, insn_op
->mode
, 0);
7233 if (!(*insn_op
->predicate
) (op
[arity
], insn_op
->mode
))
7234 op
[arity
] = copy_to_mode_reg (insn_op
->mode
, op
[arity
]);
7239 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7241 || GET_MODE (target
) != tmode
7242 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7243 target
= gen_reg_rtx (tmode
);
7249 pat
= GEN_FCN (icode
) (target
);
7253 pat
= GEN_FCN (icode
) (target
, op
[0]);
7255 pat
= GEN_FCN (icode
) (op
[0]);
7258 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
7274 /* Output assembly code for the trampoline template to
7277 On S/390, we use gpr 1 internally in the trampoline code;
7278 gpr 0 is used to hold the static chain. */
7281 s390_trampoline_template (FILE *file
)
7285 fprintf (file
, "larl\t%s,0f\n", reg_names
[1]);
7286 fprintf (file
, "lg\t%s,0(%s)\n", reg_names
[0], reg_names
[1]);
7287 fprintf (file
, "lg\t%s,8(%s)\n", reg_names
[1], reg_names
[1]);
7288 fprintf (file
, "br\t%s\n", reg_names
[1]);
7289 fprintf (file
, "0:\t.quad\t0\n");
7290 fprintf (file
, ".quad\t0\n");
7294 fprintf (file
, "basr\t%s,0\n", reg_names
[1]);
7295 fprintf (file
, "l\t%s,10(%s)\n", reg_names
[0], reg_names
[1]);
7296 fprintf (file
, "l\t%s,14(%s)\n", reg_names
[1], reg_names
[1]);
7297 fprintf (file
, "br\t%s\n", reg_names
[1]);
7298 fprintf (file
, ".long\t0\n");
7299 fprintf (file
, ".long\t0\n");
7303 /* Emit RTL insns to initialize the variable parts of a trampoline.
7304 FNADDR is an RTX for the address of the function's pure code.
7305 CXT is an RTX for the static chain value for the function. */
7308 s390_initialize_trampoline (rtx addr
, rtx fnaddr
, rtx cxt
)
7310 emit_move_insn (gen_rtx_MEM (Pmode
,
7311 memory_address (Pmode
,
7312 plus_constant (addr
, (TARGET_64BIT
? 20 : 12) ))), cxt
);
7313 emit_move_insn (gen_rtx_MEM (Pmode
,
7314 memory_address (Pmode
,
7315 plus_constant (addr
, (TARGET_64BIT
? 28 : 16) ))), fnaddr
);
7318 /* Return rtx for 64-bit constant formed from the 32-bit subwords
7319 LOW and HIGH, independent of the host word size. */
7322 s390_gen_rtx_const_DI (int high
, int low
)
7324 #if HOST_BITS_PER_WIDE_INT >= 64
7326 val
= (HOST_WIDE_INT
)high
;
7328 val
|= (HOST_WIDE_INT
)low
;
7330 return GEN_INT (val
);
7332 #if HOST_BITS_PER_WIDE_INT >= 32
7333 return immed_double_const ((HOST_WIDE_INT
)low
, (HOST_WIDE_INT
)high
, DImode
);
7340 /* Output assembler code to FILE to increment profiler label # LABELNO
7341 for profiling a function entry. */
7344 s390_function_profiler (FILE *file
, int labelno
)
7349 ASM_GENERATE_INTERNAL_LABEL (label
, "LP", labelno
);
7351 fprintf (file
, "# function profiler \n");
7353 op
[0] = gen_rtx_REG (Pmode
, RETURN_REGNUM
);
7354 op
[1] = gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
7355 op
[1] = gen_rtx_MEM (Pmode
, plus_constant (op
[1], UNITS_PER_WORD
));
7357 op
[2] = gen_rtx_REG (Pmode
, 1);
7358 op
[3] = gen_rtx_SYMBOL_REF (Pmode
, label
);
7359 SYMBOL_REF_FLAGS (op
[3]) = SYMBOL_FLAG_LOCAL
;
7361 op
[4] = gen_rtx_SYMBOL_REF (Pmode
, "_mcount");
7364 op
[4] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[4]), UNSPEC_PLT
);
7365 op
[4] = gen_rtx_CONST (Pmode
, op
[4]);
7370 output_asm_insn ("stg\t%0,%1", op
);
7371 output_asm_insn ("larl\t%2,%3", op
);
7372 output_asm_insn ("brasl\t%0,%4", op
);
7373 output_asm_insn ("lg\t%0,%1", op
);
7377 op
[6] = gen_label_rtx ();
7379 output_asm_insn ("st\t%0,%1", op
);
7380 output_asm_insn ("bras\t%2,%l6", op
);
7381 output_asm_insn (".long\t%4", op
);
7382 output_asm_insn (".long\t%3", op
);
7383 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
7384 output_asm_insn ("l\t%0,0(%2)", op
);
7385 output_asm_insn ("l\t%2,4(%2)", op
);
7386 output_asm_insn ("basr\t%0,%0", op
);
7387 output_asm_insn ("l\t%0,%1", op
);
7391 op
[5] = gen_label_rtx ();
7392 op
[6] = gen_label_rtx ();
7394 output_asm_insn ("st\t%0,%1", op
);
7395 output_asm_insn ("bras\t%2,%l6", op
);
7396 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[5]));
7397 output_asm_insn (".long\t%4-%l5", op
);
7398 output_asm_insn (".long\t%3-%l5", op
);
7399 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
7400 output_asm_insn ("lr\t%0,%2", op
);
7401 output_asm_insn ("a\t%0,0(%2)", op
);
7402 output_asm_insn ("a\t%2,4(%2)", op
);
7403 output_asm_insn ("basr\t%0,%0", op
);
7404 output_asm_insn ("l\t%0,%1", op
);
7408 /* Select section for constant in constant pool. In 32-bit mode,
7409 constants go in the function section; in 64-bit mode in .rodata. */
7412 s390_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED
,
7413 rtx x ATTRIBUTE_UNUSED
,
7414 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
7416 if (TARGET_CPU_ZARCH
)
7417 readonly_data_section ();
7419 function_section (current_function_decl
);
7422 /* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
7423 into its SYMBOL_REF_FLAGS. */
7426 s390_encode_section_info (tree decl
, rtx rtl
, int first
)
7428 default_encode_section_info (decl
, rtl
, first
);
7430 /* If a variable has a forced alignment to < 2 bytes, mark it with
7431 SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL operand. */
7432 if (TREE_CODE (decl
) == VAR_DECL
7433 && DECL_USER_ALIGN (decl
) && DECL_ALIGN (decl
) < 16)
7434 SYMBOL_REF_FLAGS (XEXP (rtl
, 0)) |= SYMBOL_FLAG_ALIGN1
;
7437 /* Output thunk to FILE that implements a C++ virtual function call (with
7438 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
7439 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
7440 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
7441 relative to the resulting this pointer. */
7444 s390_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
7445 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
7451 /* Operand 0 is the target function. */
7452 op
[0] = XEXP (DECL_RTL (function
), 0);
7453 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (op
[0]))
7456 op
[0] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[0]),
7457 TARGET_64BIT
? UNSPEC_PLT
: UNSPEC_GOT
);
7458 op
[0] = gen_rtx_CONST (Pmode
, op
[0]);
7461 /* Operand 1 is the 'this' pointer. */
7462 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
7463 op
[1] = gen_rtx_REG (Pmode
, 3);
7465 op
[1] = gen_rtx_REG (Pmode
, 2);
7467 /* Operand 2 is the delta. */
7468 op
[2] = GEN_INT (delta
);
7470 /* Operand 3 is the vcall_offset. */
7471 op
[3] = GEN_INT (vcall_offset
);
7473 /* Operand 4 is the temporary register. */
7474 op
[4] = gen_rtx_REG (Pmode
, 1);
7476 /* Operands 5 to 8 can be used as labels. */
7482 /* Operand 9 can be used for temporary register. */
7485 /* Generate code. */
7488 /* Setup literal pool pointer if required. */
7489 if ((!DISP_IN_RANGE (delta
)
7490 && !CONST_OK_FOR_CONSTRAINT_P (delta
, 'K', "K"))
7491 || (!DISP_IN_RANGE (vcall_offset
)
7492 && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'K', "K")))
7494 op
[5] = gen_label_rtx ();
7495 output_asm_insn ("larl\t%4,%5", op
);
7498 /* Add DELTA to this pointer. */
7501 if (CONST_OK_FOR_CONSTRAINT_P (delta
, 'J', "J"))
7502 output_asm_insn ("la\t%1,%2(%1)", op
);
7503 else if (DISP_IN_RANGE (delta
))
7504 output_asm_insn ("lay\t%1,%2(%1)", op
);
7505 else if (CONST_OK_FOR_CONSTRAINT_P (delta
, 'K', "K"))
7506 output_asm_insn ("aghi\t%1,%2", op
);
7509 op
[6] = gen_label_rtx ();
7510 output_asm_insn ("agf\t%1,%6-%5(%4)", op
);
7514 /* Perform vcall adjustment. */
7517 if (DISP_IN_RANGE (vcall_offset
))
7519 output_asm_insn ("lg\t%4,0(%1)", op
);
7520 output_asm_insn ("ag\t%1,%3(%4)", op
);
7522 else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'K', "K"))
7524 output_asm_insn ("lghi\t%4,%3", op
);
7525 output_asm_insn ("ag\t%4,0(%1)", op
);
7526 output_asm_insn ("ag\t%1,0(%4)", op
);
7530 op
[7] = gen_label_rtx ();
7531 output_asm_insn ("llgf\t%4,%7-%5(%4)", op
);
7532 output_asm_insn ("ag\t%4,0(%1)", op
);
7533 output_asm_insn ("ag\t%1,0(%4)", op
);
7537 /* Jump to target. */
7538 output_asm_insn ("jg\t%0", op
);
7540 /* Output literal pool if required. */
7543 output_asm_insn (".align\t4", op
);
7544 targetm
.asm_out
.internal_label (file
, "L",
7545 CODE_LABEL_NUMBER (op
[5]));
7549 targetm
.asm_out
.internal_label (file
, "L",
7550 CODE_LABEL_NUMBER (op
[6]));
7551 output_asm_insn (".long\t%2", op
);
7555 targetm
.asm_out
.internal_label (file
, "L",
7556 CODE_LABEL_NUMBER (op
[7]));
7557 output_asm_insn (".long\t%3", op
);
7562 /* Setup base pointer if required. */
7564 || (!DISP_IN_RANGE (delta
)
7565 && !CONST_OK_FOR_CONSTRAINT_P (delta
, 'K', "K"))
7566 || (!DISP_IN_RANGE (delta
)
7567 && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'K', "K")))
7569 op
[5] = gen_label_rtx ();
7570 output_asm_insn ("basr\t%4,0", op
);
7571 targetm
.asm_out
.internal_label (file
, "L",
7572 CODE_LABEL_NUMBER (op
[5]));
7575 /* Add DELTA to this pointer. */
7578 if (CONST_OK_FOR_CONSTRAINT_P (delta
, 'J', "J"))
7579 output_asm_insn ("la\t%1,%2(%1)", op
);
7580 else if (DISP_IN_RANGE (delta
))
7581 output_asm_insn ("lay\t%1,%2(%1)", op
);
7582 else if (CONST_OK_FOR_CONSTRAINT_P (delta
, 'K', "K"))
7583 output_asm_insn ("ahi\t%1,%2", op
);
7586 op
[6] = gen_label_rtx ();
7587 output_asm_insn ("a\t%1,%6-%5(%4)", op
);
7591 /* Perform vcall adjustment. */
7594 if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'J', "J"))
7596 output_asm_insn ("lg\t%4,0(%1)", op
);
7597 output_asm_insn ("a\t%1,%3(%4)", op
);
7599 else if (DISP_IN_RANGE (vcall_offset
))
7601 output_asm_insn ("lg\t%4,0(%1)", op
);
7602 output_asm_insn ("ay\t%1,%3(%4)", op
);
7604 else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'K', "K"))
7606 output_asm_insn ("lhi\t%4,%3", op
);
7607 output_asm_insn ("a\t%4,0(%1)", op
);
7608 output_asm_insn ("a\t%1,0(%4)", op
);
7612 op
[7] = gen_label_rtx ();
7613 output_asm_insn ("l\t%4,%7-%5(%4)", op
);
7614 output_asm_insn ("a\t%4,0(%1)", op
);
7615 output_asm_insn ("a\t%1,0(%4)", op
);
7618 /* We had to clobber the base pointer register.
7619 Re-setup the base pointer (with a different base). */
7620 op
[5] = gen_label_rtx ();
7621 output_asm_insn ("basr\t%4,0", op
);
7622 targetm
.asm_out
.internal_label (file
, "L",
7623 CODE_LABEL_NUMBER (op
[5]));
7626 /* Jump to target. */
7627 op
[8] = gen_label_rtx ();
7630 output_asm_insn ("l\t%4,%8-%5(%4)", op
);
7632 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
7633 /* We cannot call through .plt, since .plt requires %r12 loaded. */
7634 else if (flag_pic
== 1)
7636 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
7637 output_asm_insn ("l\t%4,%0(%4)", op
);
7639 else if (flag_pic
== 2)
7641 op
[9] = gen_rtx_REG (Pmode
, 0);
7642 output_asm_insn ("l\t%9,%8-4-%5(%4)", op
);
7643 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
7644 output_asm_insn ("ar\t%4,%9", op
);
7645 output_asm_insn ("l\t%4,0(%4)", op
);
7648 output_asm_insn ("br\t%4", op
);
7650 /* Output literal pool. */
7651 output_asm_insn (".align\t4", op
);
7653 if (nonlocal
&& flag_pic
== 2)
7654 output_asm_insn (".long\t%0", op
);
7657 op
[0] = gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
7658 SYMBOL_REF_FLAGS (op
[0]) = SYMBOL_FLAG_LOCAL
;
7661 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[8]));
7663 output_asm_insn (".long\t%0", op
);
7665 output_asm_insn (".long\t%0-%5", op
);
7669 targetm
.asm_out
.internal_label (file
, "L",
7670 CODE_LABEL_NUMBER (op
[6]));
7671 output_asm_insn (".long\t%2", op
);
7675 targetm
.asm_out
.internal_label (file
, "L",
7676 CODE_LABEL_NUMBER (op
[7]));
7677 output_asm_insn (".long\t%3", op
);
7683 s390_valid_pointer_mode (enum machine_mode mode
)
7685 return (mode
== SImode
|| (TARGET_64BIT
&& mode
== DImode
));
7688 /* How to allocate a 'struct machine_function'. */
7690 static struct machine_function
*
7691 s390_init_machine_status (void)
7693 return ggc_alloc_cleared (sizeof (struct machine_function
));
7696 /* Checks whether the given ARGUMENT_LIST would use a caller
7697 saved register. This is used to decide whether sibling call
7698 optimization could be performed on the respective function
7702 s390_call_saved_register_used (tree argument_list
)
7704 CUMULATIVE_ARGS cum
;
7706 enum machine_mode mode
;
7711 INIT_CUMULATIVE_ARGS (cum
, NULL
, NULL
, 0, 0);
7713 while (argument_list
)
7715 parameter
= TREE_VALUE (argument_list
);
7716 argument_list
= TREE_CHAIN (argument_list
);
7721 /* For an undeclared variable passed as parameter we will get
7722 an ERROR_MARK node here. */
7723 if (TREE_CODE (parameter
) == ERROR_MARK
)
7726 if (! (type
= TREE_TYPE (parameter
)))
7729 if (! (mode
= TYPE_MODE (TREE_TYPE (parameter
))))
7732 if (pass_by_reference (&cum
, mode
, type
, true))
7735 type
= build_pointer_type (type
);
7738 parm_rtx
= s390_function_arg (&cum
, mode
, type
, 0);
7740 s390_function_arg_advance (&cum
, mode
, type
, 0);
7742 if (parm_rtx
&& REG_P (parm_rtx
))
7745 reg
< HARD_REGNO_NREGS (REGNO (parm_rtx
), GET_MODE (parm_rtx
));
7747 if (! call_used_regs
[reg
+ REGNO (parm_rtx
)])
7754 /* Return true if the given call expression can be
7755 turned into a sibling call.
7756 DECL holds the declaration of the function to be called whereas
7757 EXP is the call expression itself. */
7760 s390_function_ok_for_sibcall (tree decl
, tree exp
)
7762 /* The TPF epilogue uses register 1. */
7763 if (TARGET_TPF_PROFILING
)
7766 /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
7767 which would have to be restored before the sibcall. */
7768 if (!TARGET_64BIT
&& flag_pic
&& decl
&& TREE_PUBLIC (decl
))
7771 /* Register 6 on s390 is available as an argument register but unfortunately
7772 "caller saved". This makes functions needing this register for arguments
7773 not suitable for sibcalls. */
7774 if (TREE_OPERAND (exp
, 1)
7775 && s390_call_saved_register_used (TREE_OPERAND (exp
, 1)))
7781 /* This function is used by the call expanders of the machine description.
7782 It emits the call insn itself together with the necessary operations
7783 to adjust the target address and returns the emitted insn.
7784 ADDR_LOCATION is the target address rtx
7785 TLS_CALL the location of the thread-local symbol
7786 RESULT_REG the register where the result of the call should be stored
7787 RETADDR_REG the register where the return address should be stored
7788 If this parameter is NULL_RTX the call is considered
7789 to be a sibling call. */
7792 s390_emit_call (rtx addr_location
, rtx tls_call
, rtx result_reg
,
7795 bool plt_call
= false;
7801 /* Direct function calls need special treatment. */
7802 if (GET_CODE (addr_location
) == SYMBOL_REF
)
7804 /* When calling a global routine in PIC mode, we must
7805 replace the symbol itself with the PLT stub. */
7806 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (addr_location
))
7808 addr_location
= gen_rtx_UNSPEC (Pmode
,
7809 gen_rtvec (1, addr_location
),
7811 addr_location
= gen_rtx_CONST (Pmode
, addr_location
);
7815 /* Unless we can use the bras(l) insn, force the
7816 routine address into a register. */
7817 if (!TARGET_SMALL_EXEC
&& !TARGET_CPU_ZARCH
)
7820 addr_location
= legitimize_pic_address (addr_location
, 0);
7822 addr_location
= force_reg (Pmode
, addr_location
);
7826 /* If it is already an indirect call or the code above moved the
7827 SYMBOL_REF to somewhere else make sure the address can be found in
7829 if (retaddr_reg
== NULL_RTX
7830 && GET_CODE (addr_location
) != SYMBOL_REF
7833 emit_move_insn (gen_rtx_REG (Pmode
, SIBCALL_REGNUM
), addr_location
);
7834 addr_location
= gen_rtx_REG (Pmode
, SIBCALL_REGNUM
);
7837 addr_location
= gen_rtx_MEM (QImode
, addr_location
);
7838 call
= gen_rtx_CALL (VOIDmode
, addr_location
, const0_rtx
);
7840 if (result_reg
!= NULL_RTX
)
7841 call
= gen_rtx_SET (VOIDmode
, result_reg
, call
);
7843 if (retaddr_reg
!= NULL_RTX
)
7845 clobber
= gen_rtx_CLOBBER (VOIDmode
, retaddr_reg
);
7847 if (tls_call
!= NULL_RTX
)
7848 vec
= gen_rtvec (3, call
, clobber
,
7849 gen_rtx_USE (VOIDmode
, tls_call
));
7851 vec
= gen_rtvec (2, call
, clobber
);
7853 call
= gen_rtx_PARALLEL (VOIDmode
, vec
);
7856 insn
= emit_call_insn (call
);
7858 /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
7859 if ((!TARGET_64BIT
&& plt_call
) || tls_call
!= NULL_RTX
)
7861 /* s390_function_ok_for_sibcall should
7862 have denied sibcalls in this case. */
7863 if (retaddr_reg
== NULL_RTX
)
7866 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), pic_offset_table_rtx
);
7871 /* Implement CONDITIONAL_REGISTER_USAGE. */
7874 s390_conditional_register_usage (void)
7880 fixed_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
7881 call_used_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
7883 if (TARGET_CPU_ZARCH
)
7885 fixed_regs
[RETURN_REGNUM
] = 0;
7886 call_used_regs
[RETURN_REGNUM
] = 0;
7890 for (i
= 24; i
< 32; i
++)
7891 call_used_regs
[i
] = call_really_used_regs
[i
] = 0;
7895 for (i
= 18; i
< 20; i
++)
7896 call_used_regs
[i
] = call_really_used_regs
[i
] = 0;
7901 #include "gt-s390.h"