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_USE_DFA_PIPELINE_INTERFACE
136 #define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE hook_int_void_1
137 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
138 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
140 #undef TARGET_RTX_COSTS
141 #define TARGET_RTX_COSTS s390_rtx_costs
142 #undef TARGET_ADDRESS_COST
143 #define TARGET_ADDRESS_COST s390_address_cost
145 #undef TARGET_MACHINE_DEPENDENT_REORG
146 #define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
148 #undef TARGET_VALID_POINTER_MODE
149 #define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
151 #undef TARGET_BUILD_BUILTIN_VA_LIST
152 #define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
153 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
154 #define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg
156 #undef TARGET_PROMOTE_FUNCTION_ARGS
157 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
158 #undef TARGET_PROMOTE_FUNCTION_RETURN
159 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
160 #undef TARGET_PASS_BY_REFERENCE
161 #define TARGET_PASS_BY_REFERENCE s390_pass_by_reference
163 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
164 #define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
166 struct gcc_target targetm
= TARGET_INITIALIZER
;
168 extern int reload_completed
;
170 /* The alias set for prologue/epilogue register save/restore. */
171 static int s390_sr_alias_set
= 0;
173 /* Save information from a "cmpxx" operation until the branch or scc is
175 rtx s390_compare_op0
, s390_compare_op1
;
177 /* Structure used to hold the components of a S/390 memory
178 address. A legitimate address on S/390 is of the general
180 base + index + displacement
181 where any of the components is optional.
183 base and index are registers of the class ADDR_REGS,
184 displacement is an unsigned 12-bit immediate constant. */
194 /* Which cpu are we tuning for. */
195 enum processor_type s390_tune
;
196 enum processor_flags s390_tune_flags
;
197 /* Which instruction set architecture to use. */
198 enum processor_type s390_arch
;
199 enum processor_flags s390_arch_flags
;
201 /* Strings to hold which cpu and instruction set architecture to use. */
202 const char *s390_tune_string
; /* for -mtune=<xxx> */
203 const char *s390_arch_string
; /* for -march=<xxx> */
205 /* Define the structure for the machine field in struct function. */
207 struct machine_function
GTY(())
209 /* Set, if some of the fprs 8-15 need to be saved (64 bit abi). */
212 /* Set if return address needs to be saved. */
213 bool save_return_addr_p
;
215 /* Number of first and last gpr to be saved, restored. */
217 int first_restore_gpr
;
219 int last_restore_gpr
;
221 /* Size of stack frame. */
222 HOST_WIDE_INT frame_size
;
224 /* Literal pool base register. */
227 /* Some local-dynamic TLS symbol name. */
228 const char *some_ld_name
;
231 static int s390_match_ccmode_set (rtx
, enum machine_mode
);
232 static int s390_branch_condition_mask (rtx
);
233 static const char *s390_branch_condition_mnemonic (rtx
, int);
234 static int check_mode (rtx
, enum machine_mode
*);
235 static int general_s_operand (rtx
, enum machine_mode
, int);
236 static int s390_short_displacement (rtx
);
237 static int s390_decompose_address (rtx
, struct s390_address
*);
238 static rtx
get_thread_pointer (void);
239 static rtx
legitimize_tls_address (rtx
, rtx
);
240 static void print_shift_count_operand (FILE *, rtx
);
241 static const char *get_some_local_dynamic_name (void);
242 static int get_some_local_dynamic_name_1 (rtx
*, void *);
243 static int reg_used_in_mem_p (int, rtx
);
244 static int addr_generation_dependency_p (rtx
, rtx
);
245 static int s390_split_branches (void);
246 static void annotate_constant_pool_refs (rtx
*x
);
247 static void find_constant_pool_ref (rtx
, rtx
*);
248 static void replace_constant_pool_ref (rtx
*, rtx
, rtx
);
249 static rtx
find_ltrel_base (rtx
);
250 static void replace_ltrel_base (rtx
*);
251 static void s390_optimize_prolog (bool);
252 static int find_unused_clobbered_reg (void);
253 static void s390_frame_info (int, int);
254 static rtx
save_fpr (rtx
, int, int);
255 static rtx
restore_fpr (rtx
, int, int);
256 static rtx
save_gprs (rtx
, int, int, int);
257 static rtx
restore_gprs (rtx
, int, int, int);
258 static int s390_function_arg_size (enum machine_mode
, tree
);
259 static bool s390_function_arg_float (enum machine_mode
, tree
);
260 static struct machine_function
* s390_init_machine_status (void);
262 /* Check whether integer displacement is in range. */
263 #define DISP_IN_RANGE(d) \
264 (TARGET_LONG_DISPLACEMENT? ((d) >= -524288 && (d) <= 524287) \
265 : ((d) >= 0 && (d) <= 4095))
267 /* Return true if SET either doesn't set the CC register, or else
268 the source and destination have matching CC modes and that
269 CC mode is at least as constrained as REQ_MODE. */
272 s390_match_ccmode_set (rtx set
, enum machine_mode req_mode
)
274 enum machine_mode set_mode
;
276 if (GET_CODE (set
) != SET
)
279 if (GET_CODE (SET_DEST (set
)) != REG
|| !CC_REGNO_P (REGNO (SET_DEST (set
))))
282 set_mode
= GET_MODE (SET_DEST (set
));
296 if (req_mode
!= set_mode
)
301 if (req_mode
!= CCSmode
&& req_mode
!= CCUmode
&& req_mode
!= CCTmode
302 && req_mode
!= CCSRmode
&& req_mode
!= CCURmode
)
308 if (req_mode
!= CCAmode
)
316 return (GET_MODE (SET_SRC (set
)) == set_mode
);
319 /* Return true if every SET in INSN that sets the CC register
320 has source and destination with matching CC modes and that
321 CC mode is at least as constrained as REQ_MODE.
322 If REQ_MODE is VOIDmode, always return false. */
325 s390_match_ccmode (rtx insn
, enum machine_mode req_mode
)
329 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
330 if (req_mode
== VOIDmode
)
333 if (GET_CODE (PATTERN (insn
)) == SET
)
334 return s390_match_ccmode_set (PATTERN (insn
), req_mode
);
336 if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
337 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
339 rtx set
= XVECEXP (PATTERN (insn
), 0, i
);
340 if (GET_CODE (set
) == SET
)
341 if (!s390_match_ccmode_set (set
, req_mode
))
348 /* If a test-under-mask instruction can be used to implement
349 (compare (and ... OP1) OP2), return the CC mode required
350 to do that. Otherwise, return VOIDmode.
351 MIXED is true if the instruction can distinguish between
352 CC1 and CC2 for mixed selected bits (TMxx), it is false
353 if the instruction cannot (TM). */
356 s390_tm_ccmode (rtx op1
, rtx op2
, int mixed
)
360 /* ??? Fixme: should work on CONST_DOUBLE as well. */
361 if (GET_CODE (op1
) != CONST_INT
|| GET_CODE (op2
) != CONST_INT
)
364 /* Selected bits all zero: CC0. */
365 if (INTVAL (op2
) == 0)
368 /* Selected bits all one: CC3. */
369 if (INTVAL (op2
) == INTVAL (op1
))
372 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. */
375 bit1
= exact_log2 (INTVAL (op2
));
376 bit0
= exact_log2 (INTVAL (op1
) ^ INTVAL (op2
));
377 if (bit0
!= -1 && bit1
!= -1)
378 return bit0
> bit1
? CCT1mode
: CCT2mode
;
384 /* Given a comparison code OP (EQ, NE, etc.) and the operands
385 OP0 and OP1 of a COMPARE, return the mode to be used for the
389 s390_select_ccmode (enum rtx_code code
, rtx op0
, rtx op1
)
395 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
396 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0
, 1)), 'K', "K"))
398 if ((GET_CODE (op0
) == PLUS
|| GET_CODE (op0
) == MINUS
399 || GET_CODE (op1
) == NEG
)
400 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
403 if (GET_CODE (op0
) == AND
)
405 /* Check whether we can potentially do it via TM. */
406 enum machine_mode ccmode
;
407 ccmode
= s390_tm_ccmode (XEXP (op0
, 1), op1
, 1);
408 if (ccmode
!= VOIDmode
)
410 /* Relax CCTmode to CCZmode to allow fall-back to AND
411 if that turns out to be beneficial. */
412 return ccmode
== CCTmode
? CCZmode
: ccmode
;
416 if (register_operand (op0
, HImode
)
417 && GET_CODE (op1
) == CONST_INT
418 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 65535))
420 if (register_operand (op0
, QImode
)
421 && GET_CODE (op1
) == CONST_INT
422 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 255))
431 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
432 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0
, 1)), 'K', "K"))
434 if (INTVAL (XEXP((op0
), 1)) < 0)
447 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
448 && GET_CODE (op1
) != CONST_INT
)
454 if (GET_CODE (op0
) == PLUS
455 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
458 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
459 && GET_CODE (op1
) != CONST_INT
)
465 if (GET_CODE (op0
) == MINUS
466 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
469 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
470 && GET_CODE (op1
) != CONST_INT
)
479 /* Emit a compare instruction suitable to implement the comparison
480 OP0 CODE OP1. Return the correct condition RTL to be placed in
481 the IF_THEN_ELSE of the conditional branch testing the result. */
484 s390_emit_compare (enum rtx_code code
, rtx op0
, rtx op1
)
486 enum machine_mode mode
= s390_select_ccmode (code
, op0
, op1
);
487 rtx cc
= gen_rtx_REG (mode
, CC_REGNUM
);
489 emit_insn (gen_rtx_SET (VOIDmode
, cc
, gen_rtx_COMPARE (mode
, op0
, op1
)));
490 return gen_rtx_fmt_ee (code
, VOIDmode
, cc
, const0_rtx
);
493 /* Emit a jump instruction to TARGET. If COND is NULL_RTX, emit an
494 unconditional jump, else a conditional jump under condition COND. */
497 s390_emit_jump (rtx target
, rtx cond
)
501 target
= gen_rtx_LABEL_REF (VOIDmode
, target
);
503 target
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, target
, pc_rtx
);
505 insn
= gen_rtx_SET (VOIDmode
, pc_rtx
, target
);
506 emit_jump_insn (insn
);
509 /* Return nonzero if OP is a valid comparison operator
510 for an ALC condition in mode MODE. */
513 s390_alc_comparison (rtx op
, enum machine_mode mode
)
515 if (mode
!= VOIDmode
&& mode
!= GET_MODE (op
))
518 while (GET_CODE (op
) == ZERO_EXTEND
|| GET_CODE (op
) == SIGN_EXTEND
)
521 if (!COMPARISON_P (op
))
524 if (GET_CODE (XEXP (op
, 0)) != REG
525 || REGNO (XEXP (op
, 0)) != CC_REGNUM
526 || XEXP (op
, 1) != const0_rtx
)
529 switch (GET_MODE (XEXP (op
, 0)))
532 return GET_CODE (op
) == LTU
;
535 return GET_CODE (op
) == LEU
;
538 return GET_CODE (op
) == GEU
;
541 return GET_CODE (op
) == GTU
;
544 return GET_CODE (op
) == LTU
;
547 return GET_CODE (op
) == UNGT
;
550 return GET_CODE (op
) == UNLT
;
557 /* Return nonzero if OP is a valid comparison operator
558 for an SLB condition in mode MODE. */
561 s390_slb_comparison (rtx op
, enum machine_mode mode
)
563 if (mode
!= VOIDmode
&& mode
!= GET_MODE (op
))
566 while (GET_CODE (op
) == ZERO_EXTEND
|| GET_CODE (op
) == SIGN_EXTEND
)
569 if (!COMPARISON_P (op
))
572 if (GET_CODE (XEXP (op
, 0)) != REG
573 || REGNO (XEXP (op
, 0)) != CC_REGNUM
574 || XEXP (op
, 1) != const0_rtx
)
577 switch (GET_MODE (XEXP (op
, 0)))
580 return GET_CODE (op
) == GEU
;
583 return GET_CODE (op
) == GTU
;
586 return GET_CODE (op
) == LTU
;
589 return GET_CODE (op
) == LEU
;
592 return GET_CODE (op
) == GEU
;
595 return GET_CODE (op
) == LE
;
598 return GET_CODE (op
) == GE
;
605 /* Return branch condition mask to implement a branch
606 specified by CODE. */
609 s390_branch_condition_mask (rtx code
)
611 const int CC0
= 1 << 3;
612 const int CC1
= 1 << 2;
613 const int CC2
= 1 << 1;
614 const int CC3
= 1 << 0;
616 if (GET_CODE (XEXP (code
, 0)) != REG
617 || REGNO (XEXP (code
, 0)) != CC_REGNUM
618 || XEXP (code
, 1) != const0_rtx
)
621 switch (GET_MODE (XEXP (code
, 0)))
624 switch (GET_CODE (code
))
627 case NE
: return CC1
| CC2
| CC3
;
634 switch (GET_CODE (code
))
637 case NE
: return CC0
| CC2
| CC3
;
644 switch (GET_CODE (code
))
647 case NE
: return CC0
| CC1
| CC3
;
654 switch (GET_CODE (code
))
657 case NE
: return CC0
| CC1
| CC2
;
664 switch (GET_CODE (code
))
666 case EQ
: return CC0
| CC2
;
667 case NE
: return CC1
| CC3
;
674 switch (GET_CODE (code
))
676 case LTU
: return CC2
| CC3
; /* carry */
677 case GEU
: return CC0
| CC1
; /* no carry */
684 switch (GET_CODE (code
))
686 case GTU
: return CC0
| CC1
; /* borrow */
687 case LEU
: return CC2
| CC3
; /* no borrow */
694 switch (GET_CODE (code
))
696 case EQ
: return CC0
| CC2
;
697 case NE
: return CC1
| CC3
;
698 case LTU
: return CC1
;
699 case GTU
: return CC3
;
700 case LEU
: return CC1
| CC2
;
701 case GEU
: return CC2
| CC3
;
707 switch (GET_CODE (code
))
710 case NE
: return CC1
| CC2
| CC3
;
711 case LTU
: return CC1
;
712 case GTU
: return CC2
;
713 case LEU
: return CC0
| CC1
;
714 case GEU
: return CC0
| CC2
;
721 switch (GET_CODE (code
))
724 case NE
: return CC2
| CC1
| CC3
;
725 case LTU
: return CC2
;
726 case GTU
: return CC1
;
727 case LEU
: return CC0
| CC2
;
728 case GEU
: return CC0
| CC1
;
735 switch (GET_CODE (code
))
738 case NE
: return CC1
| CC2
| CC3
;
739 case LT
: return CC1
| CC3
;
741 case LE
: return CC0
| CC1
| CC3
;
742 case GE
: return CC0
| CC2
;
749 switch (GET_CODE (code
))
752 case NE
: return CC1
| CC2
| CC3
;
754 case GT
: return CC2
| CC3
;
755 case LE
: return CC0
| CC1
;
756 case GE
: return CC0
| CC2
| CC3
;
763 switch (GET_CODE (code
))
766 case NE
: return CC1
| CC2
| CC3
;
769 case LE
: return CC0
| CC1
;
770 case GE
: return CC0
| CC2
;
771 case UNORDERED
: return CC3
;
772 case ORDERED
: return CC0
| CC1
| CC2
;
773 case UNEQ
: return CC0
| CC3
;
774 case UNLT
: return CC1
| CC3
;
775 case UNGT
: return CC2
| CC3
;
776 case UNLE
: return CC0
| CC1
| CC3
;
777 case UNGE
: return CC0
| CC2
| CC3
;
778 case LTGT
: return CC1
| CC2
;
785 switch (GET_CODE (code
))
788 case NE
: return CC2
| CC1
| CC3
;
791 case LE
: return CC0
| CC2
;
792 case GE
: return CC0
| CC1
;
793 case UNORDERED
: return CC3
;
794 case ORDERED
: return CC0
| CC2
| CC1
;
795 case UNEQ
: return CC0
| CC3
;
796 case UNLT
: return CC2
| CC3
;
797 case UNGT
: return CC1
| CC3
;
798 case UNLE
: return CC0
| CC2
| CC3
;
799 case UNGE
: return CC0
| CC1
| CC3
;
800 case LTGT
: return CC2
| CC1
;
811 /* If INV is false, return assembler mnemonic string to implement
812 a branch specified by CODE. If INV is true, return mnemonic
813 for the corresponding inverted branch. */
816 s390_branch_condition_mnemonic (rtx code
, int inv
)
818 static const char *const mnemonic
[16] =
820 NULL
, "o", "h", "nle",
821 "l", "nhe", "lh", "ne",
822 "e", "nlh", "he", "nl",
823 "le", "nh", "no", NULL
826 int mask
= s390_branch_condition_mask (code
);
831 if (mask
< 1 || mask
> 14)
834 return mnemonic
[mask
];
837 /* Return the part of op which has a value different from def.
838 The size of the part is determined by mode.
839 Use this function only if you already know that op really
840 contains such a part. */
842 unsigned HOST_WIDE_INT
843 s390_extract_part (rtx op
, enum machine_mode mode
, int def
)
845 unsigned HOST_WIDE_INT value
= 0;
846 int max_parts
= HOST_BITS_PER_WIDE_INT
/ GET_MODE_BITSIZE (mode
);
847 int part_bits
= GET_MODE_BITSIZE (mode
);
848 unsigned HOST_WIDE_INT part_mask
= (1 << part_bits
) - 1;
851 for (i
= 0; i
< max_parts
; i
++)
854 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
858 if ((value
& part_mask
) != (def
& part_mask
))
859 return value
& part_mask
;
865 /* If OP is an integer constant of mode MODE with exactly one
866 part of mode PART_MODE unequal to DEF, return the number of that
867 part. Otherwise, return -1. */
870 s390_single_part (rtx op
,
871 enum machine_mode mode
,
872 enum machine_mode part_mode
,
875 unsigned HOST_WIDE_INT value
= 0;
876 int n_parts
= GET_MODE_SIZE (mode
) / GET_MODE_SIZE (part_mode
);
877 unsigned HOST_WIDE_INT part_mask
= (1 << GET_MODE_BITSIZE (part_mode
)) - 1;
880 if (GET_CODE (op
) != CONST_INT
)
883 for (i
= 0; i
< n_parts
; i
++)
886 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
888 value
>>= GET_MODE_BITSIZE (part_mode
);
890 if ((value
& part_mask
) != (def
& part_mask
))
898 return part
== -1 ? -1 : n_parts
- 1 - part
;
901 /* Check whether we can (and want to) split a double-word
902 move in mode MODE from SRC to DST into two single-word
903 moves, moving the subword FIRST_SUBWORD first. */
906 s390_split_ok_p (rtx dst
, rtx src
, enum machine_mode mode
, int first_subword
)
908 /* Floating point registers cannot be split. */
909 if (FP_REG_P (src
) || FP_REG_P (dst
))
912 /* We don't need to split if operands are directly accessible. */
913 if (s_operand (src
, mode
) || s_operand (dst
, mode
))
916 /* Non-offsettable memory references cannot be split. */
917 if ((GET_CODE (src
) == MEM
&& !offsettable_memref_p (src
))
918 || (GET_CODE (dst
) == MEM
&& !offsettable_memref_p (dst
)))
921 /* Moving the first subword must not clobber a register
922 needed to move the second subword. */
923 if (register_operand (dst
, mode
))
925 rtx subreg
= operand_subword (dst
, first_subword
, 0, mode
);
926 if (reg_overlap_mentioned_p (subreg
, src
))
934 /* Change optimizations to be performed, depending on the
937 LEVEL is the optimization level specified; 2 if `-O2' is
938 specified, 1 if `-O' is specified, and 0 if neither is specified.
940 SIZE is nonzero if `-Os' is specified and zero otherwise. */
943 optimization_options (int level ATTRIBUTE_UNUSED
, int size ATTRIBUTE_UNUSED
)
945 /* ??? There are apparently still problems with -fcaller-saves. */
946 flag_caller_saves
= 0;
948 /* By default, always emit DWARF-2 unwind info. This allows debugging
949 without maintaining a stack frame back-chain. */
950 flag_asynchronous_unwind_tables
= 1;
954 override_options (void)
959 const char *const name
; /* processor name or nickname. */
960 const enum processor_type processor
;
961 const enum processor_flags flags
;
963 const processor_alias_table
[] =
965 {"g5", PROCESSOR_9672_G5
, PF_IEEE_FLOAT
},
966 {"g6", PROCESSOR_9672_G6
, PF_IEEE_FLOAT
},
967 {"z900", PROCESSOR_2064_Z900
, PF_IEEE_FLOAT
| PF_ZARCH
},
968 {"z990", PROCESSOR_2084_Z990
, PF_IEEE_FLOAT
| PF_ZARCH
969 | PF_LONG_DISPLACEMENT
},
972 int const pta_size
= ARRAY_SIZE (processor_alias_table
);
974 /* Acquire a unique set number for our register saves and restores. */
975 s390_sr_alias_set
= new_alias_set ();
977 /* Set up function hooks. */
978 init_machine_status
= s390_init_machine_status
;
980 /* Architecture mode defaults according to ABI. */
981 if (!(target_flags_explicit
& MASK_ZARCH
))
984 target_flags
|= MASK_ZARCH
;
986 target_flags
&= ~MASK_ZARCH
;
989 /* Determine processor architectural level. */
990 if (!s390_arch_string
)
991 s390_arch_string
= TARGET_ZARCH
? "z900" : "g5";
993 for (i
= 0; i
< pta_size
; i
++)
994 if (! strcmp (s390_arch_string
, processor_alias_table
[i
].name
))
996 s390_arch
= processor_alias_table
[i
].processor
;
997 s390_arch_flags
= processor_alias_table
[i
].flags
;
1001 error ("Unknown cpu used in -march=%s.", s390_arch_string
);
1003 /* Determine processor to tune for. */
1004 if (!s390_tune_string
)
1006 s390_tune
= s390_arch
;
1007 s390_tune_flags
= s390_arch_flags
;
1008 s390_tune_string
= s390_arch_string
;
1012 for (i
= 0; i
< pta_size
; i
++)
1013 if (! strcmp (s390_tune_string
, processor_alias_table
[i
].name
))
1015 s390_tune
= processor_alias_table
[i
].processor
;
1016 s390_tune_flags
= processor_alias_table
[i
].flags
;
1020 error ("Unknown cpu used in -mtune=%s.", s390_tune_string
);
1023 /* Sanity checks. */
1024 if (TARGET_ZARCH
&& !(s390_arch_flags
& PF_ZARCH
))
1025 error ("z/Architecture mode not supported on %s.", s390_arch_string
);
1026 if (TARGET_64BIT
&& !TARGET_ZARCH
)
1027 error ("64-bit ABI not supported in ESA/390 mode.");
1030 /* Map for smallest class containing reg regno. */
1032 const enum reg_class regclass_map
[FIRST_PSEUDO_REGISTER
] =
1033 { GENERAL_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1034 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1035 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1036 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1037 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1038 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1039 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1040 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1041 ADDR_REGS
, NO_REGS
, ADDR_REGS
1044 /* Return attribute type of insn. */
1046 static enum attr_type
1047 s390_safe_attr_type (rtx insn
)
1049 if (recog_memoized (insn
) >= 0)
1050 return get_attr_type (insn
);
1055 /* Return true if OP a (const_int 0) operand.
1056 OP is the current operation.
1057 MODE is the current operation mode. */
1060 const0_operand (register rtx op
, enum machine_mode mode
)
1062 return op
== CONST0_RTX (mode
);
1065 /* Return true if OP is constant.
1066 OP is the current operation.
1067 MODE is the current operation mode. */
1070 consttable_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1072 return CONSTANT_P (op
);
1075 /* Return true if the mode of operand OP matches MODE.
1076 If MODE is set to VOIDmode, set it to the mode of OP. */
1079 check_mode (register rtx op
, enum machine_mode
*mode
)
1081 if (*mode
== VOIDmode
)
1082 *mode
= GET_MODE (op
);
1085 if (GET_MODE (op
) != VOIDmode
&& GET_MODE (op
) != *mode
)
1091 /* Return true if OP a valid operand for the LARL instruction.
1092 OP is the current operation.
1093 MODE is the current operation mode. */
1096 larl_operand (register rtx op
, enum machine_mode mode
)
1098 if (! check_mode (op
, &mode
))
1101 /* Allow labels and local symbols. */
1102 if (GET_CODE (op
) == LABEL_REF
)
1104 if (GET_CODE (op
) == SYMBOL_REF
)
1105 return ((SYMBOL_REF_FLAGS (op
) & SYMBOL_FLAG_ALIGN1
) == 0
1106 && SYMBOL_REF_TLS_MODEL (op
) == 0
1107 && (!flag_pic
|| SYMBOL_REF_LOCAL_P (op
)));
1109 /* Everything else must have a CONST, so strip it. */
1110 if (GET_CODE (op
) != CONST
)
1114 /* Allow adding *even* in-range constants. */
1115 if (GET_CODE (op
) == PLUS
)
1117 if (GET_CODE (XEXP (op
, 1)) != CONST_INT
1118 || (INTVAL (XEXP (op
, 1)) & 1) != 0)
1120 #if HOST_BITS_PER_WIDE_INT > 32
1121 if (INTVAL (XEXP (op
, 1)) >= (HOST_WIDE_INT
)1 << 32
1122 || INTVAL (XEXP (op
, 1)) < -((HOST_WIDE_INT
)1 << 32))
1128 /* Labels and local symbols allowed here as well. */
1129 if (GET_CODE (op
) == LABEL_REF
)
1131 if (GET_CODE (op
) == SYMBOL_REF
)
1132 return ((SYMBOL_REF_FLAGS (op
) & SYMBOL_FLAG_ALIGN1
) == 0
1133 && SYMBOL_REF_TLS_MODEL (op
) == 0
1134 && (!flag_pic
|| SYMBOL_REF_LOCAL_P (op
)));
1136 /* Now we must have a @GOTENT offset or @PLT stub
1137 or an @INDNTPOFF TLS offset. */
1138 if (GET_CODE (op
) == UNSPEC
1139 && XINT (op
, 1) == UNSPEC_GOTENT
)
1141 if (GET_CODE (op
) == UNSPEC
1142 && XINT (op
, 1) == UNSPEC_PLT
)
1144 if (GET_CODE (op
) == UNSPEC
1145 && XINT (op
, 1) == UNSPEC_INDNTPOFF
)
1151 /* Helper routine to implement s_operand and s_imm_operand.
1152 OP is the current operation.
1153 MODE is the current operation mode.
1154 ALLOW_IMMEDIATE specifies whether immediate operands should
1155 be accepted or not. */
1158 general_s_operand (register rtx op
, enum machine_mode mode
,
1159 int allow_immediate
)
1161 struct s390_address addr
;
1163 /* Call general_operand first, so that we don't have to
1164 check for many special cases. */
1165 if (!general_operand (op
, mode
))
1168 /* Just like memory_operand, allow (subreg (mem ...))
1170 if (reload_completed
1171 && GET_CODE (op
) == SUBREG
1172 && GET_CODE (SUBREG_REG (op
)) == MEM
)
1173 op
= SUBREG_REG (op
);
1175 switch (GET_CODE (op
))
1177 /* Constants are OK as s-operand if ALLOW_IMMEDIATE
1178 is true and we are still before reload. */
1181 if (!allow_immediate
|| reload_completed
)
1185 /* Memory operands are OK unless they already use an
1188 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1192 /* Do not allow literal pool references unless ALLOW_IMMEDIATE
1193 is true. This prevents compares between two literal pool
1194 entries from being accepted. */
1195 if (!allow_immediate
1196 && addr
.base
&& REGNO (addr
.base
) == BASE_REGISTER
)
1207 /* Return true if OP is a valid S-type operand.
1208 OP is the current operation.
1209 MODE is the current operation mode. */
1212 s_operand (register rtx op
, enum machine_mode mode
)
1214 return general_s_operand (op
, mode
, 0);
1217 /* Return true if OP is a valid S-type operand or an immediate
1218 operand that can be addressed as S-type operand by forcing
1219 it into the literal pool.
1220 OP is the current operation.
1221 MODE is the current operation mode. */
1224 s_imm_operand (register rtx op
, enum machine_mode mode
)
1226 return general_s_operand (op
, mode
, 1);
1229 /* Return true if OP a valid shift count operand.
1230 OP is the current operation.
1231 MODE is the current operation mode. */
1234 shift_count_operand (rtx op
, enum machine_mode mode
)
1236 HOST_WIDE_INT offset
= 0;
1238 if (! check_mode (op
, &mode
))
1241 /* We can have an integer constant, an address register,
1242 or a sum of the two. Note that reload already checks
1243 that any register present is an address register, so
1244 we just check for any register here. */
1245 if (GET_CODE (op
) == CONST_INT
)
1247 offset
= INTVAL (op
);
1250 if (op
&& GET_CODE (op
) == PLUS
&& GET_CODE (XEXP (op
, 1)) == CONST_INT
)
1252 offset
= INTVAL (XEXP (op
, 1));
1255 while (op
&& GET_CODE (op
) == SUBREG
)
1256 op
= SUBREG_REG (op
);
1257 if (op
&& GET_CODE (op
) != REG
)
1260 /* Unfortunately we have to reject constants that are invalid
1261 for an address, or else reload will get confused. */
1262 if (!DISP_IN_RANGE (offset
))
1268 /* Return true if DISP is a valid short displacement. */
1271 s390_short_displacement (rtx disp
)
1273 /* No displacement is OK. */
1277 /* Integer displacement in range. */
1278 if (GET_CODE (disp
) == CONST_INT
)
1279 return INTVAL (disp
) >= 0 && INTVAL (disp
) < 4096;
1281 /* GOT offset is not OK, the GOT can be large. */
1282 if (GET_CODE (disp
) == CONST
1283 && GET_CODE (XEXP (disp
, 0)) == UNSPEC
1284 && XINT (XEXP (disp
, 0), 1) == UNSPEC_GOT
)
1287 /* All other symbolic constants are literal pool references,
1288 which are OK as the literal pool must be small. */
1289 if (GET_CODE (disp
) == CONST
)
1295 /* Return true if OP is a valid operand for a C constraint. */
1298 s390_extra_constraint_str (rtx op
, int c
, const char * str
)
1300 struct s390_address addr
;
1308 if (GET_CODE (op
) != MEM
)
1310 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1315 if (TARGET_LONG_DISPLACEMENT
)
1317 if (!s390_short_displacement (addr
.disp
))
1323 if (GET_CODE (op
) != MEM
)
1326 if (TARGET_LONG_DISPLACEMENT
)
1328 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1330 if (!s390_short_displacement (addr
.disp
))
1336 if (!TARGET_LONG_DISPLACEMENT
)
1338 if (GET_CODE (op
) != MEM
)
1340 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1344 if (s390_short_displacement (addr
.disp
))
1349 if (!TARGET_LONG_DISPLACEMENT
)
1351 if (GET_CODE (op
) != MEM
)
1353 /* Any invalid address here will be fixed up by reload,
1354 so accept it for the most generic constraint. */
1355 if (s390_decompose_address (XEXP (op
, 0), &addr
)
1356 && s390_short_displacement (addr
.disp
))
1361 if (TARGET_LONG_DISPLACEMENT
)
1363 if (!s390_decompose_address (op
, &addr
))
1365 if (!s390_short_displacement (addr
.disp
))
1371 if (!TARGET_LONG_DISPLACEMENT
)
1373 /* Any invalid address here will be fixed up by reload,
1374 so accept it for the most generic constraint. */
1375 if (s390_decompose_address (op
, &addr
)
1376 && s390_short_displacement (addr
.disp
))
1381 return shift_count_operand (op
, VOIDmode
);
1390 /* Return true if VALUE matches the constraint STR. */
1393 s390_const_ok_for_constraint_p (HOST_WIDE_INT value
,
1397 enum machine_mode mode
, part_mode
;
1407 return (unsigned int)value
< 256;
1410 return (unsigned int)value
< 4096;
1413 return value
>= -32768 && value
< 32768;
1416 return (TARGET_LONG_DISPLACEMENT
?
1417 (value
>= -524288 && value
<= 524287)
1418 : (value
>= 0 && value
<= 4095));
1420 return value
== 2147483647;
1423 part
= str
[1] - '0';
1427 case 'H': part_mode
= HImode
; break;
1428 case 'Q': part_mode
= QImode
; break;
1434 case 'H': mode
= HImode
; break;
1435 case 'S': mode
= SImode
; break;
1436 case 'D': mode
= DImode
; break;
1442 case '0': def
= 0; break;
1443 case 'F': def
= -1; break;
1447 if (GET_MODE_SIZE (mode
) <= GET_MODE_SIZE (part_mode
))
1450 if (s390_single_part (GEN_INT (value
), mode
, part_mode
, def
) != part
)
1462 /* Compute a (partial) cost for rtx X. Return true if the complete
1463 cost has been computed, and false if subexpressions should be
1464 scanned. In either case, *TOTAL contains the cost result. */
1467 s390_rtx_costs (rtx x
, int code
, int outer_code
, int *total
)
1472 if (GET_CODE (XEXP (x
, 0)) == MINUS
1473 && GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
1480 /* Force_const_mem does not work out of reload, because the
1481 saveable_obstack is set to reload_obstack, which does not
1482 live long enough. Because of this we cannot use force_const_mem
1483 in addsi3. This leads to problems with gen_add2_insn with a
1484 constant greater than a short. Because of that we give an
1485 addition of greater constants a cost of 3 (reload1.c 10096). */
1486 /* ??? saveable_obstack no longer exists. */
1487 if (outer_code
== PLUS
1488 && (INTVAL (x
) > 32767 || INTVAL (x
) < -32768))
1489 *total
= COSTS_N_INSNS (3);
1510 *total
= COSTS_N_INSNS (1);
1514 if (GET_MODE (XEXP (x
, 0)) == DImode
)
1515 *total
= COSTS_N_INSNS (40);
1517 *total
= COSTS_N_INSNS (7);
1524 *total
= COSTS_N_INSNS (33);
1532 /* Return the cost of an address rtx ADDR. */
1535 s390_address_cost (rtx addr
)
1537 struct s390_address ad
;
1538 if (!s390_decompose_address (addr
, &ad
))
1541 return ad
.indx
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
1544 /* Return true if OP is a valid operand for the BRAS instruction.
1545 OP is the current operation.
1546 MODE is the current operation mode. */
1549 bras_sym_operand (register rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1551 register enum rtx_code code
= GET_CODE (op
);
1553 /* Allow SYMBOL_REFs. */
1554 if (code
== SYMBOL_REF
)
1557 /* Allow @PLT stubs. */
1559 && GET_CODE (XEXP (op
, 0)) == UNSPEC
1560 && XINT (XEXP (op
, 0), 1) == UNSPEC_PLT
)
1565 /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
1566 otherwise return 0. */
1569 tls_symbolic_operand (register rtx op
)
1571 if (GET_CODE (op
) != SYMBOL_REF
)
1573 return SYMBOL_REF_TLS_MODEL (op
);
1576 /* Return true if OP is a load multiple operation. It is known to be a
1577 PARALLEL and the first section will be tested.
1578 OP is the current operation.
1579 MODE is the current operation mode. */
1582 load_multiple_operation (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1584 enum machine_mode elt_mode
;
1585 int count
= XVECLEN (op
, 0);
1586 unsigned int dest_regno
;
1591 /* Perform a quick check so we don't blow up below. */
1593 || GET_CODE (XVECEXP (op
, 0, 0)) != SET
1594 || GET_CODE (SET_DEST (XVECEXP (op
, 0, 0))) != REG
1595 || GET_CODE (SET_SRC (XVECEXP (op
, 0, 0))) != MEM
)
1598 dest_regno
= REGNO (SET_DEST (XVECEXP (op
, 0, 0)));
1599 src_addr
= XEXP (SET_SRC (XVECEXP (op
, 0, 0)), 0);
1600 elt_mode
= GET_MODE (SET_DEST (XVECEXP (op
, 0, 0)));
1602 /* Check, is base, or base + displacement. */
1604 if (GET_CODE (src_addr
) == REG
)
1606 else if (GET_CODE (src_addr
) == PLUS
1607 && GET_CODE (XEXP (src_addr
, 0)) == REG
1608 && GET_CODE (XEXP (src_addr
, 1)) == CONST_INT
)
1610 off
= INTVAL (XEXP (src_addr
, 1));
1611 src_addr
= XEXP (src_addr
, 0);
1616 if (src_addr
== frame_pointer_rtx
|| src_addr
== arg_pointer_rtx
)
1619 for (i
= 1; i
< count
; i
++)
1621 rtx elt
= XVECEXP (op
, 0, i
);
1623 if (GET_CODE (elt
) != SET
1624 || GET_CODE (SET_DEST (elt
)) != REG
1625 || GET_MODE (SET_DEST (elt
)) != elt_mode
1626 || REGNO (SET_DEST (elt
)) != dest_regno
+ i
1627 || GET_CODE (SET_SRC (elt
)) != MEM
1628 || GET_MODE (SET_SRC (elt
)) != elt_mode
1629 || GET_CODE (XEXP (SET_SRC (elt
), 0)) != PLUS
1630 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt
), 0), 0), src_addr
)
1631 || GET_CODE (XEXP (XEXP (SET_SRC (elt
), 0), 1)) != CONST_INT
1632 || INTVAL (XEXP (XEXP (SET_SRC (elt
), 0), 1))
1633 != off
+ i
* GET_MODE_SIZE (elt_mode
))
1640 /* Return true if OP is a store multiple operation. It is known to be a
1641 PARALLEL and the first section will be tested.
1642 OP is the current operation.
1643 MODE is the current operation mode. */
1646 store_multiple_operation (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1648 enum machine_mode elt_mode
;
1649 int count
= XVECLEN (op
, 0);
1650 unsigned int src_regno
;
1654 /* Perform a quick check so we don't blow up below. */
1656 || GET_CODE (XVECEXP (op
, 0, 0)) != SET
1657 || GET_CODE (SET_DEST (XVECEXP (op
, 0, 0))) != MEM
1658 || GET_CODE (SET_SRC (XVECEXP (op
, 0, 0))) != REG
)
1661 src_regno
= REGNO (SET_SRC (XVECEXP (op
, 0, 0)));
1662 dest_addr
= XEXP (SET_DEST (XVECEXP (op
, 0, 0)), 0);
1663 elt_mode
= GET_MODE (SET_SRC (XVECEXP (op
, 0, 0)));
1665 /* Check, is base, or base + displacement. */
1667 if (GET_CODE (dest_addr
) == REG
)
1669 else if (GET_CODE (dest_addr
) == PLUS
1670 && GET_CODE (XEXP (dest_addr
, 0)) == REG
1671 && GET_CODE (XEXP (dest_addr
, 1)) == CONST_INT
)
1673 off
= INTVAL (XEXP (dest_addr
, 1));
1674 dest_addr
= XEXP (dest_addr
, 0);
1679 if (dest_addr
== frame_pointer_rtx
|| dest_addr
== arg_pointer_rtx
)
1682 for (i
= 1; i
< count
; i
++)
1684 rtx elt
= XVECEXP (op
, 0, i
);
1686 if (GET_CODE (elt
) != SET
1687 || GET_CODE (SET_SRC (elt
)) != REG
1688 || GET_MODE (SET_SRC (elt
)) != elt_mode
1689 || REGNO (SET_SRC (elt
)) != src_regno
+ i
1690 || GET_CODE (SET_DEST (elt
)) != MEM
1691 || GET_MODE (SET_DEST (elt
)) != elt_mode
1692 || GET_CODE (XEXP (SET_DEST (elt
), 0)) != PLUS
1693 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt
), 0), 0), dest_addr
)
1694 || GET_CODE (XEXP (XEXP (SET_DEST (elt
), 0), 1)) != CONST_INT
1695 || INTVAL (XEXP (XEXP (SET_DEST (elt
), 0), 1))
1696 != off
+ i
* GET_MODE_SIZE (elt_mode
))
1703 /* Return true if OP contains a symbol reference */
1706 symbolic_reference_mentioned_p (rtx op
)
1708 register const char *fmt
;
1711 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
1714 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
1715 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
1721 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
1722 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
1726 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
1733 /* Return true if OP contains a reference to a thread-local symbol. */
1736 tls_symbolic_reference_mentioned_p (rtx op
)
1738 register const char *fmt
;
1741 if (GET_CODE (op
) == SYMBOL_REF
)
1742 return tls_symbolic_operand (op
);
1744 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
1745 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
1751 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
1752 if (tls_symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
1756 else if (fmt
[i
] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op
, i
)))
1764 /* Return true if OP is a legitimate general operand when
1765 generating PIC code. It is given that flag_pic is on
1766 and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
1769 legitimate_pic_operand_p (register rtx op
)
1771 /* Accept all non-symbolic constants. */
1772 if (!SYMBOLIC_CONST (op
))
1775 /* Reject everything else; must be handled
1776 via emit_symbolic_move. */
1780 /* Returns true if the constant value OP is a legitimate general operand.
1781 It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
1784 legitimate_constant_p (register rtx op
)
1786 /* Accept all non-symbolic constants. */
1787 if (!SYMBOLIC_CONST (op
))
1790 /* Accept immediate LARL operands. */
1791 if (TARGET_CPU_ZARCH
&& larl_operand (op
, VOIDmode
))
1794 /* Thread-local symbols are never legal constants. This is
1795 so that emit_call knows that computing such addresses
1796 might require a function call. */
1797 if (TLS_SYMBOLIC_CONST (op
))
1800 /* In the PIC case, symbolic constants must *not* be
1801 forced into the literal pool. We accept them here,
1802 so that they will be handled by emit_symbolic_move. */
1806 /* All remaining non-PIC symbolic constants are
1807 forced into the literal pool. */
1811 /* Determine if it's legal to put X into the constant pool. This
1812 is not possible if X contains the address of a symbol that is
1813 not constant (TLS) or not known at final link time (PIC). */
1816 s390_cannot_force_const_mem (rtx x
)
1818 switch (GET_CODE (x
))
1822 /* Accept all non-symbolic constants. */
1826 /* Labels are OK iff we are non-PIC. */
1827 return flag_pic
!= 0;
1830 /* 'Naked' TLS symbol references are never OK,
1831 non-TLS symbols are OK iff we are non-PIC. */
1832 if (tls_symbolic_operand (x
))
1835 return flag_pic
!= 0;
1838 return s390_cannot_force_const_mem (XEXP (x
, 0));
1841 return s390_cannot_force_const_mem (XEXP (x
, 0))
1842 || s390_cannot_force_const_mem (XEXP (x
, 1));
1845 switch (XINT (x
, 1))
1847 /* Only lt-relative or GOT-relative UNSPECs are OK. */
1848 case UNSPEC_LTREL_OFFSET
:
1856 case UNSPEC_GOTNTPOFF
:
1857 case UNSPEC_INDNTPOFF
:
1870 /* Returns true if the constant value OP is a legitimate general
1871 operand during and after reload. The difference to
1872 legitimate_constant_p is that this function will not accept
1873 a constant that would need to be forced to the literal pool
1874 before it can be used as operand. */
1877 legitimate_reload_constant_p (register rtx op
)
1879 /* Accept la(y) operands. */
1880 if (GET_CODE (op
) == CONST_INT
1881 && DISP_IN_RANGE (INTVAL (op
)))
1884 /* Accept l(g)hi operands. */
1885 if (GET_CODE (op
) == CONST_INT
1886 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op
), 'K', "K"))
1889 /* Accept lliXX operands. */
1891 && s390_single_part (op
, DImode
, HImode
, 0) >= 0)
1894 /* Accept larl operands. */
1895 if (TARGET_CPU_ZARCH
1896 && larl_operand (op
, VOIDmode
))
1899 /* Everything else cannot be handled without reload. */
1903 /* Given an rtx OP being reloaded into a reg required to be in class CLASS,
1904 return the class of reg to actually use. */
1907 s390_preferred_reload_class (rtx op
, enum reg_class
class)
1909 /* This can happen if a floating point constant is being
1910 reloaded into an integer register. Leave well alone. */
1911 if (GET_MODE_CLASS (GET_MODE (op
)) == MODE_FLOAT
1912 && class != FP_REGS
)
1915 switch (GET_CODE (op
))
1917 /* Constants we cannot reload must be forced into the
1922 if (legitimate_reload_constant_p (op
))
1927 /* If a symbolic constant or a PLUS is reloaded,
1928 it is most likely being used as an address, so
1929 prefer ADDR_REGS. If 'class' is not a superset
1930 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
1935 if (reg_class_subset_p (ADDR_REGS
, class))
1947 /* Return the register class of a scratch register needed to
1948 load IN into a register of class CLASS in MODE.
1950 We need a temporary when loading a PLUS expression which
1951 is not a legitimate operand of the LOAD ADDRESS instruction. */
1954 s390_secondary_input_reload_class (enum reg_class
class ATTRIBUTE_UNUSED
,
1955 enum machine_mode mode
, rtx in
)
1957 if (s390_plus_operand (in
, mode
))
1963 /* Return the register class of a scratch register needed to
1964 store a register of class CLASS in MODE into OUT:
1966 We need a temporary when storing a double-word to a
1967 non-offsettable memory address. */
1970 s390_secondary_output_reload_class (enum reg_class
class,
1971 enum machine_mode mode
, rtx out
)
1973 if ((TARGET_64BIT
? mode
== TImode
1974 : (mode
== DImode
|| mode
== DFmode
))
1975 && reg_classes_intersect_p (GENERAL_REGS
, class)
1976 && GET_CODE (out
) == MEM
1977 && !offsettable_memref_p (out
)
1978 && !s_operand (out
, VOIDmode
))
1984 /* Return true if OP is a PLUS that is not a legitimate
1985 operand for the LA instruction.
1986 OP is the current operation.
1987 MODE is the current operation mode. */
1990 s390_plus_operand (register rtx op
, enum machine_mode mode
)
1992 if (!check_mode (op
, &mode
) || mode
!= Pmode
)
1995 if (GET_CODE (op
) != PLUS
)
1998 if (legitimate_la_operand_p (op
))
2004 /* Generate code to load SRC, which is PLUS that is not a
2005 legitimate operand for the LA instruction, into TARGET.
2006 SCRATCH may be used as scratch register. */
2009 s390_expand_plus_operand (register rtx target
, register rtx src
,
2010 register rtx scratch
)
2013 struct s390_address ad
;
2015 /* src must be a PLUS; get its two operands. */
2016 if (GET_CODE (src
) != PLUS
|| GET_MODE (src
) != Pmode
)
2019 /* Check if any of the two operands is already scheduled
2020 for replacement by reload. This can happen e.g. when
2021 float registers occur in an address. */
2022 sum1
= find_replacement (&XEXP (src
, 0));
2023 sum2
= find_replacement (&XEXP (src
, 1));
2024 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
2026 /* If the address is already strictly valid, there's nothing to do. */
2027 if (!s390_decompose_address (src
, &ad
)
2028 || (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
2029 || (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
)))
2031 /* Otherwise, one of the operands cannot be an address register;
2032 we reload its value into the scratch register. */
2033 if (true_regnum (sum1
) < 1 || true_regnum (sum1
) > 15)
2035 emit_move_insn (scratch
, sum1
);
2038 if (true_regnum (sum2
) < 1 || true_regnum (sum2
) > 15)
2040 emit_move_insn (scratch
, sum2
);
2044 /* According to the way these invalid addresses are generated
2045 in reload.c, it should never happen (at least on s390) that
2046 *neither* of the PLUS components, after find_replacements
2047 was applied, is an address register. */
2048 if (sum1
== scratch
&& sum2
== scratch
)
2054 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
2057 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
2058 is only ever performed on addresses, so we can mark the
2059 sum as legitimate for LA in any case. */
2060 s390_load_address (target
, src
);
2064 /* Decompose a RTL expression ADDR for a memory address into
2065 its components, returned in OUT.
2067 Returns 0 if ADDR is not a valid memory address, nonzero
2068 otherwise. If OUT is NULL, don't return the components,
2069 but check for validity only.
2071 Note: Only addresses in canonical form are recognized.
2072 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
2073 canonical form so that they will be recognized. */
2076 s390_decompose_address (register rtx addr
, struct s390_address
*out
)
2078 HOST_WIDE_INT offset
= 0;
2079 rtx base
= NULL_RTX
;
2080 rtx indx
= NULL_RTX
;
2081 rtx disp
= NULL_RTX
;
2083 int pointer
= FALSE
;
2084 int base_ptr
= FALSE
;
2085 int indx_ptr
= FALSE
;
2087 /* Decompose address into base + index + displacement. */
2089 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == UNSPEC
)
2092 else if (GET_CODE (addr
) == PLUS
)
2094 rtx op0
= XEXP (addr
, 0);
2095 rtx op1
= XEXP (addr
, 1);
2096 enum rtx_code code0
= GET_CODE (op0
);
2097 enum rtx_code code1
= GET_CODE (op1
);
2099 if (code0
== REG
|| code0
== UNSPEC
)
2101 if (code1
== REG
|| code1
== UNSPEC
)
2103 indx
= op0
; /* index + base */
2109 base
= op0
; /* base + displacement */
2114 else if (code0
== PLUS
)
2116 indx
= XEXP (op0
, 0); /* index + base + disp */
2117 base
= XEXP (op0
, 1);
2128 disp
= addr
; /* displacement */
2130 /* Extract integer part of displacement. */
2134 if (GET_CODE (disp
) == CONST_INT
)
2136 offset
= INTVAL (disp
);
2139 else if (GET_CODE (disp
) == CONST
2140 && GET_CODE (XEXP (disp
, 0)) == PLUS
2141 && GET_CODE (XEXP (XEXP (disp
, 0), 1)) == CONST_INT
)
2143 offset
= INTVAL (XEXP (XEXP (disp
, 0), 1));
2144 disp
= XEXP (XEXP (disp
, 0), 0);
2148 /* Strip off CONST here to avoid special case tests later. */
2149 if (disp
&& GET_CODE (disp
) == CONST
)
2150 disp
= XEXP (disp
, 0);
2152 /* We can convert literal pool addresses to
2153 displacements by basing them off the base register. */
2154 if (disp
&& GET_CODE (disp
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (disp
))
2156 /* Either base or index must be free to hold the base register. */
2158 base
= gen_rtx_REG (Pmode
, BASE_REGISTER
);
2160 indx
= gen_rtx_REG (Pmode
, BASE_REGISTER
);
2164 /* Mark up the displacement. */
2165 disp
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, disp
),
2166 UNSPEC_LTREL_OFFSET
);
2169 /* Validate base register. */
2172 if (GET_CODE (base
) == UNSPEC
)
2173 switch (XINT (base
, 1))
2177 disp
= gen_rtx_UNSPEC (Pmode
,
2178 gen_rtvec (1, XVECEXP (base
, 0, 0)),
2179 UNSPEC_LTREL_OFFSET
);
2183 base
= gen_rtx_REG (Pmode
, BASE_REGISTER
);
2186 case UNSPEC_LTREL_BASE
:
2187 base
= gen_rtx_REG (Pmode
, BASE_REGISTER
);
2194 if (GET_CODE (base
) != REG
|| GET_MODE (base
) != Pmode
)
2197 if (REGNO (base
) == BASE_REGISTER
2198 || REGNO (base
) == STACK_POINTER_REGNUM
2199 || REGNO (base
) == FRAME_POINTER_REGNUM
2200 || ((reload_completed
|| reload_in_progress
)
2201 && frame_pointer_needed
2202 && REGNO (base
) == HARD_FRAME_POINTER_REGNUM
)
2203 || REGNO (base
) == ARG_POINTER_REGNUM
2205 && REGNO (base
) == PIC_OFFSET_TABLE_REGNUM
))
2206 pointer
= base_ptr
= TRUE
;
2209 /* Validate index register. */
2212 if (GET_CODE (indx
) == UNSPEC
)
2213 switch (XINT (indx
, 1))
2217 disp
= gen_rtx_UNSPEC (Pmode
,
2218 gen_rtvec (1, XVECEXP (indx
, 0, 0)),
2219 UNSPEC_LTREL_OFFSET
);
2223 indx
= gen_rtx_REG (Pmode
, BASE_REGISTER
);
2226 case UNSPEC_LTREL_BASE
:
2227 indx
= gen_rtx_REG (Pmode
, BASE_REGISTER
);
2234 if (GET_CODE (indx
) != REG
|| GET_MODE (indx
) != Pmode
)
2237 if (REGNO (indx
) == BASE_REGISTER
2238 || REGNO (indx
) == STACK_POINTER_REGNUM
2239 || REGNO (indx
) == FRAME_POINTER_REGNUM
2240 || ((reload_completed
|| reload_in_progress
)
2241 && frame_pointer_needed
2242 && REGNO (indx
) == HARD_FRAME_POINTER_REGNUM
)
2243 || REGNO (indx
) == ARG_POINTER_REGNUM
2245 && REGNO (indx
) == PIC_OFFSET_TABLE_REGNUM
))
2246 pointer
= indx_ptr
= TRUE
;
2249 /* Prefer to use pointer as base, not index. */
2250 if (base
&& indx
&& !base_ptr
2251 && (indx_ptr
|| (!REG_POINTER (base
) && REG_POINTER (indx
))))
2258 /* Validate displacement. */
2261 /* If the argument pointer is involved, the displacement will change
2262 later anyway as the argument pointer gets eliminated. This could
2263 make a valid displacement invalid, but it is more likely to make
2264 an invalid displacement valid, because we sometimes access the
2265 register save area via negative offsets to the arg pointer.
2266 Thus we don't check the displacement for validity here. If after
2267 elimination the displacement turns out to be invalid after all,
2268 this is fixed up by reload in any case. */
2269 if (base
!= arg_pointer_rtx
&& indx
!= arg_pointer_rtx
)
2270 if (!DISP_IN_RANGE (offset
))
2275 /* All the special cases are pointers. */
2278 /* In the small-PIC case, the linker converts @GOT
2279 and @GOTNTPOFF offsets to possible displacements. */
2280 if (GET_CODE (disp
) == UNSPEC
2281 && (XINT (disp
, 1) == UNSPEC_GOT
2282 || XINT (disp
, 1) == UNSPEC_GOTNTPOFF
)
2289 /* Accept chunkified literal pool symbol references. */
2290 else if (GET_CODE (disp
) == MINUS
2291 && GET_CODE (XEXP (disp
, 0)) == LABEL_REF
2292 && GET_CODE (XEXP (disp
, 1)) == LABEL_REF
)
2297 /* Accept literal pool references. */
2298 else if (GET_CODE (disp
) == UNSPEC
2299 && XINT (disp
, 1) == UNSPEC_LTREL_OFFSET
)
2301 orig_disp
= gen_rtx_CONST (Pmode
, disp
);
2304 /* If we have an offset, make sure it does not
2305 exceed the size of the constant pool entry. */
2306 rtx sym
= XVECEXP (disp
, 0, 0);
2307 if (offset
>= GET_MODE_SIZE (get_pool_mode (sym
)))
2310 orig_disp
= plus_constant (orig_disp
, offset
);
2325 out
->disp
= orig_disp
;
2326 out
->pointer
= pointer
;
2332 /* Return nonzero if ADDR is a valid memory address.
2333 STRICT specifies whether strict register checking applies. */
2336 legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED
,
2337 register rtx addr
, int strict
)
2339 struct s390_address ad
;
2340 if (!s390_decompose_address (addr
, &ad
))
2345 if (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
2347 if (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
))
2352 if (ad
.base
&& !REG_OK_FOR_BASE_NONSTRICT_P (ad
.base
))
2354 if (ad
.indx
&& !REG_OK_FOR_INDEX_NONSTRICT_P (ad
.indx
))
2361 /* Return 1 if OP is a valid operand for the LA instruction.
2362 In 31-bit, we need to prove that the result is used as an
2363 address, as LA performs only a 31-bit addition. */
2366 legitimate_la_operand_p (register rtx op
)
2368 struct s390_address addr
;
2369 if (!s390_decompose_address (op
, &addr
))
2372 if (TARGET_64BIT
|| addr
.pointer
)
2378 /* Return 1 if OP is a valid operand for the LA instruction,
2379 and we prefer to use LA over addition to compute it. */
2382 preferred_la_operand_p (register rtx op
)
2384 struct s390_address addr
;
2385 if (!s390_decompose_address (op
, &addr
))
2388 if (!TARGET_64BIT
&& !addr
.pointer
)
2394 if ((addr
.base
&& REG_P (addr
.base
) && REG_POINTER (addr
.base
))
2395 || (addr
.indx
&& REG_P (addr
.indx
) && REG_POINTER (addr
.indx
)))
2401 /* Emit a forced load-address operation to load SRC into DST.
2402 This will use the LOAD ADDRESS instruction even in situations
2403 where legitimate_la_operand_p (SRC) returns false. */
2406 s390_load_address (rtx dst
, rtx src
)
2409 emit_move_insn (dst
, src
);
2411 emit_insn (gen_force_la_31 (dst
, src
));
2414 /* Return a legitimate reference for ORIG (an address) using the
2415 register REG. If REG is 0, a new pseudo is generated.
2417 There are two types of references that must be handled:
2419 1. Global data references must load the address from the GOT, via
2420 the PIC reg. An insn is emitted to do this load, and the reg is
2423 2. Static data references, constant pool addresses, and code labels
2424 compute the address as an offset from the GOT, whose base is in
2425 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
2426 differentiate them from global data objects. The returned
2427 address is the PIC reg + an unspec constant.
2429 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2430 reg also appears in the address. */
2433 legitimize_pic_address (rtx orig
, rtx reg
)
2439 if (GET_CODE (addr
) == LABEL_REF
2440 || (GET_CODE (addr
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (addr
)))
2442 /* This is a local symbol. */
2443 if (TARGET_CPU_ZARCH
&& larl_operand (addr
, VOIDmode
))
2445 /* Access local symbols PC-relative via LARL.
2446 This is the same as in the non-PIC case, so it is
2447 handled automatically ... */
2451 /* Access local symbols relative to the GOT. */
2453 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2455 if (reload_in_progress
|| reload_completed
)
2456 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2458 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTOFF
);
2459 addr
= gen_rtx_CONST (Pmode
, addr
);
2460 addr
= force_const_mem (Pmode
, addr
);
2461 emit_move_insn (temp
, addr
);
2463 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2466 emit_move_insn (reg
, new);
2471 else if (GET_CODE (addr
) == SYMBOL_REF
)
2474 reg
= gen_reg_rtx (Pmode
);
2478 /* Assume GOT offset < 4k. This is handled the same way
2479 in both 31- and 64-bit code (@GOT). */
2481 if (reload_in_progress
|| reload_completed
)
2482 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2484 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
2485 new = gen_rtx_CONST (Pmode
, new);
2486 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new);
2487 new = gen_rtx_MEM (Pmode
, new);
2488 RTX_UNCHANGING_P (new) = 1;
2489 emit_move_insn (reg
, new);
2492 else if (TARGET_CPU_ZARCH
)
2494 /* If the GOT offset might be >= 4k, we determine the position
2495 of the GOT entry via a PC-relative LARL (@GOTENT). */
2497 rtx temp
= gen_reg_rtx (Pmode
);
2499 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTENT
);
2500 new = gen_rtx_CONST (Pmode
, new);
2501 emit_move_insn (temp
, new);
2503 new = gen_rtx_MEM (Pmode
, temp
);
2504 RTX_UNCHANGING_P (new) = 1;
2505 emit_move_insn (reg
, new);
2510 /* If the GOT offset might be >= 4k, we have to load it
2511 from the literal pool (@GOT). */
2513 rtx temp
= gen_reg_rtx (Pmode
);
2515 if (reload_in_progress
|| reload_completed
)
2516 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2518 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
2519 addr
= gen_rtx_CONST (Pmode
, addr
);
2520 addr
= force_const_mem (Pmode
, addr
);
2521 emit_move_insn (temp
, addr
);
2523 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2524 new = gen_rtx_MEM (Pmode
, new);
2525 RTX_UNCHANGING_P (new) = 1;
2526 emit_move_insn (reg
, new);
2532 if (GET_CODE (addr
) == CONST
)
2534 addr
= XEXP (addr
, 0);
2535 if (GET_CODE (addr
) == UNSPEC
)
2537 if (XVECLEN (addr
, 0) != 1)
2539 switch (XINT (addr
, 1))
2541 /* If someone moved a GOT-relative UNSPEC
2542 out of the literal pool, force them back in. */
2545 new = force_const_mem (Pmode
, orig
);
2548 /* @GOT is OK as is if small. */
2551 new = force_const_mem (Pmode
, orig
);
2554 /* @GOTENT is OK as is. */
2558 /* @PLT is OK as is on 64-bit, must be converted to
2559 GOT-relative @PLTOFF on 31-bit. */
2561 if (!TARGET_CPU_ZARCH
)
2563 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2565 if (reload_in_progress
|| reload_completed
)
2566 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2568 addr
= XVECEXP (addr
, 0, 0);
2569 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
),
2571 addr
= gen_rtx_CONST (Pmode
, addr
);
2572 addr
= force_const_mem (Pmode
, addr
);
2573 emit_move_insn (temp
, addr
);
2575 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2578 emit_move_insn (reg
, new);
2584 /* Everything else cannot happen. */
2589 else if (GET_CODE (addr
) != PLUS
)
2592 if (GET_CODE (addr
) == PLUS
)
2594 rtx op0
= XEXP (addr
, 0), op1
= XEXP (addr
, 1);
2595 /* Check first to see if this is a constant offset
2596 from a local symbol reference. */
2597 if ((GET_CODE (op0
) == LABEL_REF
2598 || (GET_CODE (op0
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (op0
)))
2599 && GET_CODE (op1
) == CONST_INT
)
2601 if (TARGET_CPU_ZARCH
&& larl_operand (op0
, VOIDmode
))
2603 if (INTVAL (op1
) & 1)
2605 /* LARL can't handle odd offsets, so emit a
2606 pair of LARL and LA. */
2607 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2609 if (!DISP_IN_RANGE (INTVAL (op1
)))
2611 int even
= INTVAL (op1
) - 1;
2612 op0
= gen_rtx_PLUS (Pmode
, op0
, GEN_INT (even
));
2613 op0
= gen_rtx_CONST (Pmode
, op0
);
2617 emit_move_insn (temp
, op0
);
2618 new = gen_rtx_PLUS (Pmode
, temp
, op1
);
2622 emit_move_insn (reg
, new);
2628 /* If the offset is even, we can just use LARL.
2629 This will happen automatically. */
2634 /* Access local symbols relative to the GOT. */
2636 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
2638 if (reload_in_progress
|| reload_completed
)
2639 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2641 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op0
),
2643 addr
= gen_rtx_PLUS (Pmode
, addr
, op1
);
2644 addr
= gen_rtx_CONST (Pmode
, addr
);
2645 addr
= force_const_mem (Pmode
, addr
);
2646 emit_move_insn (temp
, addr
);
2648 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2651 emit_move_insn (reg
, new);
2657 /* Now, check whether it is a GOT relative symbol plus offset
2658 that was pulled out of the literal pool. Force it back in. */
2660 else if (GET_CODE (op0
) == UNSPEC
2661 && GET_CODE (op1
) == CONST_INT
2662 && XINT (op0
, 1) == UNSPEC_GOTOFF
)
2664 if (XVECLEN (op0
, 0) != 1)
2667 new = force_const_mem (Pmode
, orig
);
2670 /* Otherwise, compute the sum. */
2673 base
= legitimize_pic_address (XEXP (addr
, 0), reg
);
2674 new = legitimize_pic_address (XEXP (addr
, 1),
2675 base
== reg
? NULL_RTX
: reg
);
2676 if (GET_CODE (new) == CONST_INT
)
2677 new = plus_constant (base
, INTVAL (new));
2680 if (GET_CODE (new) == PLUS
&& CONSTANT_P (XEXP (new, 1)))
2682 base
= gen_rtx_PLUS (Pmode
, base
, XEXP (new, 0));
2683 new = XEXP (new, 1);
2685 new = gen_rtx_PLUS (Pmode
, base
, new);
2688 if (GET_CODE (new) == CONST
)
2689 new = XEXP (new, 0);
2690 new = force_operand (new, 0);
2697 /* Load the thread pointer into a register. */
2700 get_thread_pointer (void)
2704 tp
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TP
);
2705 tp
= force_reg (Pmode
, tp
);
2706 mark_reg_pointer (tp
, BITS_PER_WORD
);
2711 /* Emit a tls call insn. The call target is the SYMBOL_REF stored
2712 in s390_tls_symbol which always refers to __tls_get_offset.
2713 The returned offset is written to RESULT_REG and an USE rtx is
2714 generated for TLS_CALL. */
2716 static GTY(()) rtx s390_tls_symbol
;
2719 s390_emit_tls_call_insn (rtx result_reg
, rtx tls_call
)
2726 if (!s390_tls_symbol
)
2727 s390_tls_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "__tls_get_offset");
2729 insn
= s390_emit_call (s390_tls_symbol
, tls_call
, result_reg
,
2730 gen_rtx_REG (Pmode
, RETURN_REGNUM
));
2732 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), result_reg
);
2733 CONST_OR_PURE_CALL_P (insn
) = 1;
2736 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
2737 this (thread-local) address. REG may be used as temporary. */
2740 legitimize_tls_address (rtx addr
, rtx reg
)
2742 rtx
new, tls_call
, temp
, base
, r2
, insn
;
2744 if (GET_CODE (addr
) == SYMBOL_REF
)
2745 switch (tls_symbolic_operand (addr
))
2747 case TLS_MODEL_GLOBAL_DYNAMIC
:
2749 r2
= gen_rtx_REG (Pmode
, 2);
2750 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_TLSGD
);
2751 new = gen_rtx_CONST (Pmode
, tls_call
);
2752 new = force_const_mem (Pmode
, new);
2753 emit_move_insn (r2
, new);
2754 s390_emit_tls_call_insn (r2
, tls_call
);
2755 insn
= get_insns ();
2758 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
2759 temp
= gen_reg_rtx (Pmode
);
2760 emit_libcall_block (insn
, temp
, r2
, new);
2762 new = gen_rtx_PLUS (Pmode
, get_thread_pointer (), temp
);
2765 s390_load_address (reg
, new);
2770 case TLS_MODEL_LOCAL_DYNAMIC
:
2772 r2
= gen_rtx_REG (Pmode
, 2);
2773 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM
);
2774 new = gen_rtx_CONST (Pmode
, tls_call
);
2775 new = force_const_mem (Pmode
, new);
2776 emit_move_insn (r2
, new);
2777 s390_emit_tls_call_insn (r2
, tls_call
);
2778 insn
= get_insns ();
2781 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM_NTPOFF
);
2782 temp
= gen_reg_rtx (Pmode
);
2783 emit_libcall_block (insn
, temp
, r2
, new);
2785 new = gen_rtx_PLUS (Pmode
, get_thread_pointer (), temp
);
2786 base
= gen_reg_rtx (Pmode
);
2787 s390_load_address (base
, new);
2789 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_DTPOFF
);
2790 new = gen_rtx_CONST (Pmode
, new);
2791 new = force_const_mem (Pmode
, new);
2792 temp
= gen_reg_rtx (Pmode
);
2793 emit_move_insn (temp
, new);
2795 new = gen_rtx_PLUS (Pmode
, base
, temp
);
2798 s390_load_address (reg
, new);
2803 case TLS_MODEL_INITIAL_EXEC
:
2806 /* Assume GOT offset < 4k. This is handled the same way
2807 in both 31- and 64-bit code. */
2809 if (reload_in_progress
|| reload_completed
)
2810 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2812 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
2813 new = gen_rtx_CONST (Pmode
, new);
2814 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new);
2815 new = gen_rtx_MEM (Pmode
, new);
2816 RTX_UNCHANGING_P (new) = 1;
2817 temp
= gen_reg_rtx (Pmode
);
2818 emit_move_insn (temp
, new);
2820 else if (TARGET_CPU_ZARCH
)
2822 /* If the GOT offset might be >= 4k, we determine the position
2823 of the GOT entry via a PC-relative LARL. */
2825 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
2826 new = gen_rtx_CONST (Pmode
, new);
2827 temp
= gen_reg_rtx (Pmode
);
2828 emit_move_insn (temp
, new);
2830 new = gen_rtx_MEM (Pmode
, temp
);
2831 RTX_UNCHANGING_P (new) = 1;
2832 temp
= gen_reg_rtx (Pmode
);
2833 emit_move_insn (temp
, new);
2837 /* If the GOT offset might be >= 4k, we have to load it
2838 from the literal pool. */
2840 if (reload_in_progress
|| reload_completed
)
2841 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
2843 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
2844 new = gen_rtx_CONST (Pmode
, new);
2845 new = force_const_mem (Pmode
, new);
2846 temp
= gen_reg_rtx (Pmode
);
2847 emit_move_insn (temp
, new);
2849 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
2850 new = gen_rtx_MEM (Pmode
, new);
2851 RTX_UNCHANGING_P (new) = 1;
2853 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new, addr
), UNSPEC_TLS_LOAD
);
2854 temp
= gen_reg_rtx (Pmode
);
2855 emit_insn (gen_rtx_SET (Pmode
, temp
, new));
2859 /* In position-dependent code, load the absolute address of
2860 the GOT entry from the literal pool. */
2862 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
2863 new = gen_rtx_CONST (Pmode
, new);
2864 new = force_const_mem (Pmode
, new);
2865 temp
= gen_reg_rtx (Pmode
);
2866 emit_move_insn (temp
, new);
2869 new = gen_rtx_MEM (Pmode
, new);
2870 RTX_UNCHANGING_P (new) = 1;
2872 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new, addr
), UNSPEC_TLS_LOAD
);
2873 temp
= gen_reg_rtx (Pmode
);
2874 emit_insn (gen_rtx_SET (Pmode
, temp
, new));
2877 new = gen_rtx_PLUS (Pmode
, get_thread_pointer (), temp
);
2880 s390_load_address (reg
, new);
2885 case TLS_MODEL_LOCAL_EXEC
:
2886 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
2887 new = gen_rtx_CONST (Pmode
, new);
2888 new = force_const_mem (Pmode
, new);
2889 temp
= gen_reg_rtx (Pmode
);
2890 emit_move_insn (temp
, new);
2892 new = gen_rtx_PLUS (Pmode
, get_thread_pointer (), temp
);
2895 s390_load_address (reg
, new);
2904 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == UNSPEC
)
2906 switch (XINT (XEXP (addr
, 0), 1))
2908 case UNSPEC_INDNTPOFF
:
2909 if (TARGET_CPU_ZARCH
)
2920 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == PLUS
2921 && GET_CODE (XEXP (XEXP (addr
, 0), 1)) == CONST_INT
)
2923 new = XEXP (XEXP (addr
, 0), 0);
2924 if (GET_CODE (new) != SYMBOL_REF
)
2925 new = gen_rtx_CONST (Pmode
, new);
2927 new = legitimize_tls_address (new, reg
);
2928 new = plus_constant (new, INTVAL (XEXP (XEXP (addr
, 0), 1)));
2929 new = force_operand (new, 0);
2933 abort (); /* for now ... */
2938 /* Emit insns to move operands[1] into operands[0]. */
2941 emit_symbolic_move (rtx
*operands
)
2943 rtx temp
= no_new_pseudos
? operands
[0] : gen_reg_rtx (Pmode
);
2945 if (GET_CODE (operands
[0]) == MEM
)
2946 operands
[1] = force_reg (Pmode
, operands
[1]);
2947 else if (TLS_SYMBOLIC_CONST (operands
[1]))
2948 operands
[1] = legitimize_tls_address (operands
[1], temp
);
2950 operands
[1] = legitimize_pic_address (operands
[1], temp
);
2953 /* Try machine-dependent ways of modifying an illegitimate address X
2954 to be legitimate. If we find one, return the new, valid address.
2956 OLDX is the address as it was before break_out_memory_refs was called.
2957 In some cases it is useful to look at this to decide what needs to be done.
2959 MODE is the mode of the operand pointed to by X.
2961 When -fpic is used, special handling is needed for symbolic references.
2962 See comments by legitimize_pic_address for details. */
2965 legitimize_address (register rtx x
, register rtx oldx ATTRIBUTE_UNUSED
,
2966 enum machine_mode mode ATTRIBUTE_UNUSED
)
2968 rtx constant_term
= const0_rtx
;
2970 if (TLS_SYMBOLIC_CONST (x
))
2972 x
= legitimize_tls_address (x
, 0);
2974 if (legitimate_address_p (mode
, x
, FALSE
))
2979 if (SYMBOLIC_CONST (x
)
2980 || (GET_CODE (x
) == PLUS
2981 && (SYMBOLIC_CONST (XEXP (x
, 0))
2982 || SYMBOLIC_CONST (XEXP (x
, 1)))))
2983 x
= legitimize_pic_address (x
, 0);
2985 if (legitimate_address_p (mode
, x
, FALSE
))
2989 x
= eliminate_constant_term (x
, &constant_term
);
2991 /* Optimize loading of large displacements by splitting them
2992 into the multiple of 4K and the rest; this allows the
2993 former to be CSE'd if possible.
2995 Don't do this if the displacement is added to a register
2996 pointing into the stack frame, as the offsets will
2997 change later anyway. */
2999 if (GET_CODE (constant_term
) == CONST_INT
3000 && !TARGET_LONG_DISPLACEMENT
3001 && !DISP_IN_RANGE (INTVAL (constant_term
))
3002 && !(REG_P (x
) && REGNO_PTR_FRAME_P (REGNO (x
))))
3004 HOST_WIDE_INT lower
= INTVAL (constant_term
) & 0xfff;
3005 HOST_WIDE_INT upper
= INTVAL (constant_term
) ^ lower
;
3007 rtx temp
= gen_reg_rtx (Pmode
);
3008 rtx val
= force_operand (GEN_INT (upper
), temp
);
3010 emit_move_insn (temp
, val
);
3012 x
= gen_rtx_PLUS (Pmode
, x
, temp
);
3013 constant_term
= GEN_INT (lower
);
3016 if (GET_CODE (x
) == PLUS
)
3018 if (GET_CODE (XEXP (x
, 0)) == REG
)
3020 register rtx temp
= gen_reg_rtx (Pmode
);
3021 register rtx val
= force_operand (XEXP (x
, 1), temp
);
3023 emit_move_insn (temp
, val
);
3025 x
= gen_rtx_PLUS (Pmode
, XEXP (x
, 0), temp
);
3028 else if (GET_CODE (XEXP (x
, 1)) == REG
)
3030 register rtx temp
= gen_reg_rtx (Pmode
);
3031 register rtx val
= force_operand (XEXP (x
, 0), temp
);
3033 emit_move_insn (temp
, val
);
3035 x
= gen_rtx_PLUS (Pmode
, temp
, XEXP (x
, 1));
3039 if (constant_term
!= const0_rtx
)
3040 x
= gen_rtx_PLUS (Pmode
, x
, constant_term
);
3045 /* Emit code to move LEN bytes from DST to SRC. */
3048 s390_expand_movmem (rtx dst
, rtx src
, rtx len
)
3050 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3052 if (INTVAL (len
) > 0)
3053 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (INTVAL (len
) - 1)));
3056 else if (TARGET_MVCLE
)
3058 emit_insn (gen_movmem_long (dst
, src
, convert_to_mode (Pmode
, len
, 1)));
3063 rtx dst_addr
, src_addr
, count
, blocks
, temp
;
3064 rtx loop_start_label
= gen_label_rtx ();
3065 rtx loop_end_label
= gen_label_rtx ();
3066 rtx end_label
= gen_label_rtx ();
3067 enum machine_mode mode
;
3069 mode
= GET_MODE (len
);
3070 if (mode
== VOIDmode
)
3073 dst_addr
= gen_reg_rtx (Pmode
);
3074 src_addr
= gen_reg_rtx (Pmode
);
3075 count
= gen_reg_rtx (mode
);
3076 blocks
= gen_reg_rtx (mode
);
3078 convert_move (count
, len
, 1);
3079 emit_cmp_and_jump_insns (count
, const0_rtx
,
3080 EQ
, NULL_RTX
, mode
, 1, end_label
);
3082 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
3083 emit_move_insn (src_addr
, force_operand (XEXP (src
, 0), NULL_RTX
));
3084 dst
= change_address (dst
, VOIDmode
, dst_addr
);
3085 src
= change_address (src
, VOIDmode
, src_addr
);
3087 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3089 emit_move_insn (count
, temp
);
3091 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3093 emit_move_insn (blocks
, temp
);
3095 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3096 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3098 emit_label (loop_start_label
);
3100 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (255)));
3101 s390_load_address (dst_addr
,
3102 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
3103 s390_load_address (src_addr
,
3104 gen_rtx_PLUS (Pmode
, src_addr
, GEN_INT (256)));
3106 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3108 emit_move_insn (blocks
, temp
);
3110 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3111 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3113 emit_jump (loop_start_label
);
3114 emit_label (loop_end_label
);
3116 emit_insn (gen_movmem_short (dst
, src
,
3117 convert_to_mode (Pmode
, count
, 1)));
3118 emit_label (end_label
);
3122 /* Emit code to clear LEN bytes at DST. */
3125 s390_expand_clrmem (rtx dst
, rtx len
)
3127 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3129 if (INTVAL (len
) > 0)
3130 emit_insn (gen_clrmem_short (dst
, GEN_INT (INTVAL (len
) - 1)));
3133 else if (TARGET_MVCLE
)
3135 emit_insn (gen_clrmem_long (dst
, convert_to_mode (Pmode
, len
, 1)));
3140 rtx dst_addr
, src_addr
, count
, blocks
, temp
;
3141 rtx loop_start_label
= gen_label_rtx ();
3142 rtx loop_end_label
= gen_label_rtx ();
3143 rtx end_label
= gen_label_rtx ();
3144 enum machine_mode mode
;
3146 mode
= GET_MODE (len
);
3147 if (mode
== VOIDmode
)
3150 dst_addr
= gen_reg_rtx (Pmode
);
3151 src_addr
= gen_reg_rtx (Pmode
);
3152 count
= gen_reg_rtx (mode
);
3153 blocks
= gen_reg_rtx (mode
);
3155 convert_move (count
, len
, 1);
3156 emit_cmp_and_jump_insns (count
, const0_rtx
,
3157 EQ
, NULL_RTX
, mode
, 1, end_label
);
3159 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
3160 dst
= change_address (dst
, VOIDmode
, dst_addr
);
3162 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3164 emit_move_insn (count
, temp
);
3166 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3168 emit_move_insn (blocks
, temp
);
3170 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3171 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3173 emit_label (loop_start_label
);
3175 emit_insn (gen_clrmem_short (dst
, GEN_INT (255)));
3176 s390_load_address (dst_addr
,
3177 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
3179 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3181 emit_move_insn (blocks
, temp
);
3183 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3184 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3186 emit_jump (loop_start_label
);
3187 emit_label (loop_end_label
);
3189 emit_insn (gen_clrmem_short (dst
, convert_to_mode (Pmode
, count
, 1)));
3190 emit_label (end_label
);
3194 /* Emit code to compare LEN bytes at OP0 with those at OP1,
3195 and return the result in TARGET. */
3198 s390_expand_cmpmem (rtx target
, rtx op0
, rtx op1
, rtx len
)
3200 rtx (*gen_result
) (rtx
) =
3201 GET_MODE (target
) == DImode
? gen_cmpint_di
: gen_cmpint_si
;
3203 op0
= protect_from_queue (op0
, 0);
3204 op1
= protect_from_queue (op1
, 0);
3205 len
= protect_from_queue (len
, 0);
3207 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3209 if (INTVAL (len
) > 0)
3211 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (INTVAL (len
) - 1)));
3212 emit_insn (gen_result (target
));
3215 emit_move_insn (target
, const0_rtx
);
3218 else /* if (TARGET_MVCLE) */
3220 emit_insn (gen_cmpmem_long (op0
, op1
, convert_to_mode (Pmode
, len
, 1)));
3221 emit_insn (gen_result (target
));
3225 /* Deactivate for now as profile code cannot cope with
3226 CC being live across basic block boundaries. */
3229 rtx addr0
, addr1
, count
, blocks
, temp
;
3230 rtx loop_start_label
= gen_label_rtx ();
3231 rtx loop_end_label
= gen_label_rtx ();
3232 rtx end_label
= gen_label_rtx ();
3233 enum machine_mode mode
;
3235 mode
= GET_MODE (len
);
3236 if (mode
== VOIDmode
)
3239 addr0
= gen_reg_rtx (Pmode
);
3240 addr1
= gen_reg_rtx (Pmode
);
3241 count
= gen_reg_rtx (mode
);
3242 blocks
= gen_reg_rtx (mode
);
3244 convert_move (count
, len
, 1);
3245 emit_cmp_and_jump_insns (count
, const0_rtx
,
3246 EQ
, NULL_RTX
, mode
, 1, end_label
);
3248 emit_move_insn (addr0
, force_operand (XEXP (op0
, 0), NULL_RTX
));
3249 emit_move_insn (addr1
, force_operand (XEXP (op1
, 0), NULL_RTX
));
3250 op0
= change_address (op0
, VOIDmode
, addr0
);
3251 op1
= change_address (op1
, VOIDmode
, addr1
);
3253 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3255 emit_move_insn (count
, temp
);
3257 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3259 emit_move_insn (blocks
, temp
);
3261 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3262 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3264 emit_label (loop_start_label
);
3266 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (255)));
3267 temp
= gen_rtx_NE (VOIDmode
, gen_rtx_REG (CCSmode
, 33), const0_rtx
);
3268 temp
= gen_rtx_IF_THEN_ELSE (VOIDmode
, temp
,
3269 gen_rtx_LABEL_REF (VOIDmode
, end_label
), pc_rtx
);
3270 temp
= gen_rtx_SET (VOIDmode
, pc_rtx
, temp
);
3271 emit_jump_insn (temp
);
3273 s390_load_address (addr0
,
3274 gen_rtx_PLUS (Pmode
, addr0
, GEN_INT (256)));
3275 s390_load_address (addr1
,
3276 gen_rtx_PLUS (Pmode
, addr1
, GEN_INT (256)));
3278 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3280 emit_move_insn (blocks
, temp
);
3282 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3283 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3285 emit_jump (loop_start_label
);
3286 emit_label (loop_end_label
);
3288 emit_insn (gen_cmpmem_short (op0
, op1
,
3289 convert_to_mode (Pmode
, count
, 1)));
3290 emit_label (end_label
);
3292 emit_insn (gen_result (target
));
3298 /* Expand conditional increment or decrement using alc/slb instructions.
3299 Should generate code setting DST to either SRC or SRC + INCREMENT,
3300 depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
3301 Returns true if successful, false otherwise. */
3304 s390_expand_addcc (enum rtx_code cmp_code
, rtx cmp_op0
, rtx cmp_op1
,
3305 rtx dst
, rtx src
, rtx increment
)
3307 enum machine_mode cmp_mode
;
3308 enum machine_mode cc_mode
;
3313 if ((GET_MODE (cmp_op0
) == SImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
3314 && (GET_MODE (cmp_op1
) == SImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
3316 else if ((GET_MODE (cmp_op0
) == DImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
3317 && (GET_MODE (cmp_op1
) == DImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
3322 /* Try ADD LOGICAL WITH CARRY. */
3323 if (increment
== const1_rtx
)
3325 /* Determine CC mode to use. */
3326 if (cmp_code
== EQ
|| cmp_code
== NE
)
3328 if (cmp_op1
!= const0_rtx
)
3330 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
3331 NULL_RTX
, 0, OPTAB_WIDEN
);
3332 cmp_op1
= const0_rtx
;
3335 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
3338 if (cmp_code
== LTU
|| cmp_code
== LEU
)
3343 cmp_code
= swap_condition (cmp_code
);
3360 /* Emit comparison instruction pattern. */
3361 if (!register_operand (cmp_op0
, cmp_mode
))
3362 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
3364 insn
= gen_rtx_SET (VOIDmode
, gen_rtx_REG (cc_mode
, CC_REGNUM
),
3365 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
3366 /* We use insn_invalid_p here to add clobbers if required. */
3367 if (insn_invalid_p (emit_insn (insn
)))
3370 /* Emit ALC instruction pattern. */
3371 op_res
= gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
3372 gen_rtx_REG (cc_mode
, CC_REGNUM
),
3375 if (src
!= const0_rtx
)
3377 if (!register_operand (src
, GET_MODE (dst
)))
3378 src
= force_reg (GET_MODE (dst
), src
);
3380 src
= gen_rtx_PLUS (GET_MODE (dst
), src
, const0_rtx
);
3381 op_res
= gen_rtx_PLUS (GET_MODE (dst
), src
, op_res
);
3384 p
= rtvec_alloc (2);
3386 gen_rtx_SET (VOIDmode
, dst
, op_res
);
3388 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
3389 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
3394 /* Try SUBTRACT LOGICAL WITH BORROW. */
3395 if (increment
== constm1_rtx
)
3397 /* Determine CC mode to use. */
3398 if (cmp_code
== EQ
|| cmp_code
== NE
)
3400 if (cmp_op1
!= const0_rtx
)
3402 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
3403 NULL_RTX
, 0, OPTAB_WIDEN
);
3404 cmp_op1
= const0_rtx
;
3407 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
3410 if (cmp_code
== GTU
|| cmp_code
== GEU
)
3415 cmp_code
= swap_condition (cmp_code
);
3432 /* Emit comparison instruction pattern. */
3433 if (!register_operand (cmp_op0
, cmp_mode
))
3434 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
3436 insn
= gen_rtx_SET (VOIDmode
, gen_rtx_REG (cc_mode
, CC_REGNUM
),
3437 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
3438 /* We use insn_invalid_p here to add clobbers if required. */
3439 if (insn_invalid_p (emit_insn (insn
)))
3442 /* Emit SLB instruction pattern. */
3443 if (!register_operand (src
, GET_MODE (dst
)))
3444 src
= force_reg (GET_MODE (dst
), src
);
3446 op_res
= gen_rtx_MINUS (GET_MODE (dst
),
3447 gen_rtx_MINUS (GET_MODE (dst
), src
, const0_rtx
),
3448 gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
3449 gen_rtx_REG (cc_mode
, CC_REGNUM
),
3451 p
= rtvec_alloc (2);
3453 gen_rtx_SET (VOIDmode
, dst
, op_res
);
3455 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
3456 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
3465 /* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
3466 We need to emit DTP-relative relocations. */
3469 s390_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
3474 fputs ("\t.long\t", file
);
3477 fputs ("\t.quad\t", file
);
3482 output_addr_const (file
, x
);
3483 fputs ("@DTPOFF", file
);
3486 /* In the name of slightly smaller debug output, and to cater to
3487 general assembler losage, recognize various UNSPEC sequences
3488 and turn them back into a direct symbol reference. */
3491 s390_delegitimize_address (rtx orig_x
)
3495 if (GET_CODE (x
) != MEM
)
3499 if (GET_CODE (x
) == PLUS
3500 && GET_CODE (XEXP (x
, 1)) == CONST
3501 && GET_CODE (XEXP (x
, 0)) == REG
3502 && REGNO (XEXP (x
, 0)) == PIC_OFFSET_TABLE_REGNUM
)
3504 y
= XEXP (XEXP (x
, 1), 0);
3505 if (GET_CODE (y
) == UNSPEC
3506 && XINT (y
, 1) == UNSPEC_GOT
)
3507 return XVECEXP (y
, 0, 0);
3511 if (GET_CODE (x
) == CONST
)
3514 if (GET_CODE (y
) == UNSPEC
3515 && XINT (y
, 1) == UNSPEC_GOTENT
)
3516 return XVECEXP (y
, 0, 0);
3523 /* Output shift count operand OP to stdio stream FILE. */
3526 print_shift_count_operand (FILE *file
, rtx op
)
3528 HOST_WIDE_INT offset
= 0;
3530 /* We can have an integer constant, an address register,
3531 or a sum of the two. */
3532 if (GET_CODE (op
) == CONST_INT
)
3534 offset
= INTVAL (op
);
3537 if (op
&& GET_CODE (op
) == PLUS
&& GET_CODE (XEXP (op
, 1)) == CONST_INT
)
3539 offset
= INTVAL (XEXP (op
, 1));
3542 while (op
&& GET_CODE (op
) == SUBREG
)
3543 op
= SUBREG_REG (op
);
3546 if (op
&& (GET_CODE (op
) != REG
3547 || REGNO (op
) >= FIRST_PSEUDO_REGISTER
3548 || REGNO_REG_CLASS (REGNO (op
)) != ADDR_REGS
))
3551 /* Shift counts are truncated to the low six bits anyway. */
3552 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
& 63);
3554 fprintf (file
, "(%s)", reg_names
[REGNO (op
)]);
3557 /* Locate some local-dynamic symbol still in use by this function
3558 so that we can print its name in local-dynamic base patterns. */
3561 get_some_local_dynamic_name (void)
3565 if (cfun
->machine
->some_ld_name
)
3566 return cfun
->machine
->some_ld_name
;
3568 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
3570 && for_each_rtx (&PATTERN (insn
), get_some_local_dynamic_name_1
, 0))
3571 return cfun
->machine
->some_ld_name
;
3577 get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
3581 if (GET_CODE (x
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (x
))
3583 x
= get_pool_constant (x
);
3584 return for_each_rtx (&x
, get_some_local_dynamic_name_1
, 0);
3587 if (GET_CODE (x
) == SYMBOL_REF
3588 && tls_symbolic_operand (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
3590 cfun
->machine
->some_ld_name
= XSTR (x
, 0);
3597 /* Output machine-dependent UNSPECs occurring in address constant X
3598 in assembler syntax to stdio stream FILE. Returns true if the
3599 constant X could be recognized, false otherwise. */
3602 s390_output_addr_const_extra (FILE *file
, rtx x
)
3604 if (GET_CODE (x
) == UNSPEC
&& XVECLEN (x
, 0) == 1)
3605 switch (XINT (x
, 1))
3608 output_addr_const (file
, XVECEXP (x
, 0, 0));
3609 fprintf (file
, "@GOTENT");
3612 output_addr_const (file
, XVECEXP (x
, 0, 0));
3613 fprintf (file
, "@GOT");
3616 output_addr_const (file
, XVECEXP (x
, 0, 0));
3617 fprintf (file
, "@GOTOFF");
3620 output_addr_const (file
, XVECEXP (x
, 0, 0));
3621 fprintf (file
, "@PLT");
3624 output_addr_const (file
, XVECEXP (x
, 0, 0));
3625 fprintf (file
, "@PLTOFF");
3628 output_addr_const (file
, XVECEXP (x
, 0, 0));
3629 fprintf (file
, "@TLSGD");
3632 assemble_name (file
, get_some_local_dynamic_name ());
3633 fprintf (file
, "@TLSLDM");
3636 output_addr_const (file
, XVECEXP (x
, 0, 0));
3637 fprintf (file
, "@DTPOFF");
3640 output_addr_const (file
, XVECEXP (x
, 0, 0));
3641 fprintf (file
, "@NTPOFF");
3643 case UNSPEC_GOTNTPOFF
:
3644 output_addr_const (file
, XVECEXP (x
, 0, 0));
3645 fprintf (file
, "@GOTNTPOFF");
3647 case UNSPEC_INDNTPOFF
:
3648 output_addr_const (file
, XVECEXP (x
, 0, 0));
3649 fprintf (file
, "@INDNTPOFF");
3656 /* Output address operand ADDR in assembler syntax to
3657 stdio stream FILE. */
3660 print_operand_address (FILE *file
, rtx addr
)
3662 struct s390_address ad
;
3664 if (!s390_decompose_address (addr
, &ad
)
3665 || (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
3666 || (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
)))
3667 output_operand_lossage ("Cannot decompose address.");
3670 output_addr_const (file
, ad
.disp
);
3672 fprintf (file
, "0");
3674 if (ad
.base
&& ad
.indx
)
3675 fprintf (file
, "(%s,%s)", reg_names
[REGNO (ad
.indx
)],
3676 reg_names
[REGNO (ad
.base
)]);
3678 fprintf (file
, "(%s)", reg_names
[REGNO (ad
.base
)]);
3681 /* Output operand X in assembler syntax to stdio stream FILE.
3682 CODE specified the format flag. The following format flags
3685 'C': print opcode suffix for branch condition.
3686 'D': print opcode suffix for inverse branch condition.
3687 'J': print tls_load/tls_gdcall/tls_ldcall suffix
3688 'O': print only the displacement of a memory reference.
3689 'R': print only the base register of a memory reference.
3690 'N': print the second word of a DImode operand.
3691 'M': print the second word of a TImode operand.
3692 'Y': print shift count operand.
3694 'b': print integer X as if it's an unsigned byte.
3695 'x': print integer X as if it's an unsigned word.
3696 'h': print integer X as if it's a signed word.
3697 'i': print the first nonzero HImode part of X.
3698 'j': print the first HImode part unequal to 0xffff of X. */
3701 print_operand (FILE *file
, rtx x
, int code
)
3706 fprintf (file
, s390_branch_condition_mnemonic (x
, FALSE
));
3710 fprintf (file
, s390_branch_condition_mnemonic (x
, TRUE
));
3714 if (GET_CODE (x
) == SYMBOL_REF
)
3716 fprintf (file
, "%s", ":tls_load:");
3717 output_addr_const (file
, x
);
3719 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSGD
)
3721 fprintf (file
, "%s", ":tls_gdcall:");
3722 output_addr_const (file
, XVECEXP (x
, 0, 0));
3724 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSLDM
)
3726 fprintf (file
, "%s", ":tls_ldcall:");
3727 assemble_name (file
, get_some_local_dynamic_name ());
3735 struct s390_address ad
;
3737 if (GET_CODE (x
) != MEM
3738 || !s390_decompose_address (XEXP (x
, 0), &ad
)
3739 || (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
3744 output_addr_const (file
, ad
.disp
);
3746 fprintf (file
, "0");
3752 struct s390_address ad
;
3754 if (GET_CODE (x
) != MEM
3755 || !s390_decompose_address (XEXP (x
, 0), &ad
)
3756 || (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
3761 fprintf (file
, "%s", reg_names
[REGNO (ad
.base
)]);
3763 fprintf (file
, "0");
3768 if (GET_CODE (x
) == REG
)
3769 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
3770 else if (GET_CODE (x
) == MEM
)
3771 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 4));
3777 if (GET_CODE (x
) == REG
)
3778 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
3779 else if (GET_CODE (x
) == MEM
)
3780 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 8));
3786 print_shift_count_operand (file
, x
);
3790 switch (GET_CODE (x
))
3793 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
3797 output_address (XEXP (x
, 0));
3804 output_addr_const (file
, x
);
3809 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xff);
3810 else if (code
== 'x')
3811 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xffff);
3812 else if (code
== 'h')
3813 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((INTVAL (x
) & 0xffff) ^ 0x8000) - 0x8000);
3814 else if (code
== 'i')
3815 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
3816 s390_extract_part (x
, HImode
, 0));
3817 else if (code
== 'j')
3818 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
3819 s390_extract_part (x
, HImode
, -1));
3821 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
3825 if (GET_MODE (x
) != VOIDmode
)
3828 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xff);
3829 else if (code
== 'x')
3830 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xffff);
3831 else if (code
== 'h')
3832 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((CONST_DOUBLE_LOW (x
) & 0xffff) ^ 0x8000) - 0x8000);
3838 fatal_insn ("UNKNOWN in print_operand !?", x
);
3843 /* Target hook for assembling integer objects. We need to define it
3844 here to work a round a bug in some versions of GAS, which couldn't
3845 handle values smaller than INT_MIN when printed in decimal. */
3848 s390_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
3850 if (size
== 8 && aligned_p
3851 && GET_CODE (x
) == CONST_INT
&& INTVAL (x
) < INT_MIN
)
3853 fprintf (asm_out_file
, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX
"\n",
3857 return default_assemble_integer (x
, size
, aligned_p
);
3860 /* Returns true if register REGNO is used for forming
3861 a memory address in expression X. */
3864 reg_used_in_mem_p (int regno
, rtx x
)
3866 enum rtx_code code
= GET_CODE (x
);
3872 if (refers_to_regno_p (regno
, regno
+1,
3876 else if (code
== SET
3877 && GET_CODE (SET_DEST (x
)) == PC
)
3879 if (refers_to_regno_p (regno
, regno
+1,
3884 fmt
= GET_RTX_FORMAT (code
);
3885 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
3888 && reg_used_in_mem_p (regno
, XEXP (x
, i
)))
3891 else if (fmt
[i
] == 'E')
3892 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
3893 if (reg_used_in_mem_p (regno
, XVECEXP (x
, i
, j
)))
3899 /* Returns true if expression DEP_RTX sets an address register
3900 used by instruction INSN to address memory. */
3903 addr_generation_dependency_p (rtx dep_rtx
, rtx insn
)
3907 if (GET_CODE (dep_rtx
) == INSN
)
3908 dep_rtx
= PATTERN (dep_rtx
);
3910 if (GET_CODE (dep_rtx
) == SET
)
3912 target
= SET_DEST (dep_rtx
);
3913 if (GET_CODE (target
) == STRICT_LOW_PART
)
3914 target
= XEXP (target
, 0);
3915 while (GET_CODE (target
) == SUBREG
)
3916 target
= SUBREG_REG (target
);
3918 if (GET_CODE (target
) == REG
)
3920 int regno
= REGNO (target
);
3922 if (s390_safe_attr_type (insn
) == TYPE_LA
)
3924 pat
= PATTERN (insn
);
3925 if (GET_CODE (pat
) == PARALLEL
)
3927 if (XVECLEN (pat
, 0) != 2)
3929 pat
= XVECEXP (pat
, 0, 0);
3931 if (GET_CODE (pat
) == SET
)
3932 return refers_to_regno_p (regno
, regno
+1, SET_SRC (pat
), 0);
3936 else if (get_attr_atype (insn
) == ATYPE_AGEN
)
3937 return reg_used_in_mem_p (regno
, PATTERN (insn
));
3943 /* Return 1, if dep_insn sets register used in insn in the agen unit. */
3946 s390_agen_dep_p (rtx dep_insn
, rtx insn
)
3948 rtx dep_rtx
= PATTERN (dep_insn
);
3951 if (GET_CODE (dep_rtx
) == SET
3952 && addr_generation_dependency_p (dep_rtx
, insn
))
3954 else if (GET_CODE (dep_rtx
) == PARALLEL
)
3956 for (i
= 0; i
< XVECLEN (dep_rtx
, 0); i
++)
3958 if (addr_generation_dependency_p (XVECEXP (dep_rtx
, 0, i
), insn
))
3965 /* Return the modified cost of the dependency of instruction INSN
3966 on instruction DEP_INSN through the link LINK. COST is the
3967 default cost of that dependency.
3969 Data dependencies are all handled without delay. However, if a
3970 register is modified and subsequently used as base or index
3971 register of a memory reference, at least 4 cycles need to pass
3972 between setting and using the register to avoid pipeline stalls.
3973 An exception is the LA instruction. An address generated by LA can
3974 be used by introducing only a one cycle stall on the pipeline. */
3977 s390_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
3979 /* If the dependence is an anti-dependence, there is no cost. For an
3980 output dependence, there is sometimes a cost, but it doesn't seem
3981 worth handling those few cases. */
3983 if (REG_NOTE_KIND (link
) != 0)
3986 /* If we can't recognize the insns, we can't really do anything. */
3987 if (recog_memoized (insn
) < 0 || recog_memoized (dep_insn
) < 0)
3990 /* Operand forward in case of lr, load and la. */
3991 if (s390_tune
== PROCESSOR_2084_Z990
3993 && (s390_safe_attr_type (dep_insn
) == TYPE_LA
3994 || s390_safe_attr_type (dep_insn
) == TYPE_LR
3995 || s390_safe_attr_type (dep_insn
) == TYPE_LOAD
))
4000 /* A C statement (sans semicolon) to update the integer scheduling priority
4001 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
4002 reduce the priority to execute INSN later. Do not define this macro if
4003 you do not need to adjust the scheduling priorities of insns.
4005 A STD instruction should be scheduled earlier,
4006 in order to use the bypass. */
4009 s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
4011 if (! INSN_P (insn
))
4014 if (s390_tune
!= PROCESSOR_2084_Z990
)
4017 switch (s390_safe_attr_type (insn
))
4021 priority
= priority
<< 3;
4024 priority
= priority
<< 1;
4032 /* The number of instructions that can be issued per cycle. */
4035 s390_issue_rate (void)
4037 if (s390_tune
== PROCESSOR_2084_Z990
)
4043 s390_first_cycle_multipass_dfa_lookahead (void)
4049 /* Split all branches that exceed the maximum distance.
4050 Returns true if this created a new literal pool entry. */
4053 s390_split_branches (void)
4055 rtx temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
4056 int new_literal
= 0;
4057 rtx insn
, pat
, tmp
, target
;
4060 /* We need correct insn addresses. */
4062 shorten_branches (get_insns ());
4064 /* Find all branches that exceed 64KB, and split them. */
4066 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
4068 if (GET_CODE (insn
) != JUMP_INSN
)
4071 pat
= PATTERN (insn
);
4072 if (GET_CODE (pat
) == PARALLEL
&& XVECLEN (pat
, 0) > 2)
4073 pat
= XVECEXP (pat
, 0, 0);
4074 if (GET_CODE (pat
) != SET
|| SET_DEST (pat
) != pc_rtx
)
4077 if (GET_CODE (SET_SRC (pat
)) == LABEL_REF
)
4079 label
= &SET_SRC (pat
);
4081 else if (GET_CODE (SET_SRC (pat
)) == IF_THEN_ELSE
)
4083 if (GET_CODE (XEXP (SET_SRC (pat
), 1)) == LABEL_REF
)
4084 label
= &XEXP (SET_SRC (pat
), 1);
4085 else if (GET_CODE (XEXP (SET_SRC (pat
), 2)) == LABEL_REF
)
4086 label
= &XEXP (SET_SRC (pat
), 2);
4093 if (get_attr_length (insn
) <= 4)
4096 /* We are going to use the return register as scratch register,
4097 make sure it will be saved/restored by the prologue/epilogue. */
4098 cfun
->machine
->save_return_addr_p
= 1;
4103 tmp
= force_const_mem (Pmode
, *label
);
4104 tmp
= emit_insn_before (gen_rtx_SET (Pmode
, temp_reg
, tmp
), insn
);
4105 INSN_ADDRESSES_NEW (tmp
, -1);
4106 annotate_constant_pool_refs (&PATTERN (tmp
));
4113 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, *label
),
4114 UNSPEC_LTREL_OFFSET
);
4115 target
= gen_rtx_CONST (Pmode
, target
);
4116 target
= force_const_mem (Pmode
, target
);
4117 tmp
= emit_insn_before (gen_rtx_SET (Pmode
, temp_reg
, target
), insn
);
4118 INSN_ADDRESSES_NEW (tmp
, -1);
4119 annotate_constant_pool_refs (&PATTERN (tmp
));
4121 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XEXP (target
, 0),
4122 cfun
->machine
->base_reg
),
4124 target
= gen_rtx_PLUS (Pmode
, temp_reg
, target
);
4127 if (!validate_change (insn
, label
, target
, 0))
4134 /* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
4135 Fix up MEMs as required. */
4138 annotate_constant_pool_refs (rtx
*x
)
4143 if (GET_CODE (*x
) == SYMBOL_REF
4144 && CONSTANT_POOL_ADDRESS_P (*x
))
4147 /* Literal pool references can only occur inside a MEM ... */
4148 if (GET_CODE (*x
) == MEM
)
4150 rtx memref
= XEXP (*x
, 0);
4152 if (GET_CODE (memref
) == SYMBOL_REF
4153 && CONSTANT_POOL_ADDRESS_P (memref
))
4155 rtx base
= cfun
->machine
->base_reg
;
4156 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, memref
, base
),
4159 *x
= replace_equiv_address (*x
, addr
);
4163 if (GET_CODE (memref
) == CONST
4164 && GET_CODE (XEXP (memref
, 0)) == PLUS
4165 && GET_CODE (XEXP (XEXP (memref
, 0), 1)) == CONST_INT
4166 && GET_CODE (XEXP (XEXP (memref
, 0), 0)) == SYMBOL_REF
4167 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (memref
, 0), 0)))
4169 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (memref
, 0), 1));
4170 rtx sym
= XEXP (XEXP (memref
, 0), 0);
4171 rtx base
= cfun
->machine
->base_reg
;
4172 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
4175 *x
= replace_equiv_address (*x
, plus_constant (addr
, off
));
4180 /* ... or a load-address type pattern. */
4181 if (GET_CODE (*x
) == SET
)
4183 rtx addrref
= SET_SRC (*x
);
4185 if (GET_CODE (addrref
) == SYMBOL_REF
4186 && CONSTANT_POOL_ADDRESS_P (addrref
))
4188 rtx base
= cfun
->machine
->base_reg
;
4189 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, addrref
, base
),
4192 SET_SRC (*x
) = addr
;
4196 if (GET_CODE (addrref
) == CONST
4197 && GET_CODE (XEXP (addrref
, 0)) == PLUS
4198 && GET_CODE (XEXP (XEXP (addrref
, 0), 1)) == CONST_INT
4199 && GET_CODE (XEXP (XEXP (addrref
, 0), 0)) == SYMBOL_REF
4200 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (addrref
, 0), 0)))
4202 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (addrref
, 0), 1));
4203 rtx sym
= XEXP (XEXP (addrref
, 0), 0);
4204 rtx base
= cfun
->machine
->base_reg
;
4205 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
4208 SET_SRC (*x
) = plus_constant (addr
, off
);
4213 /* Annotate LTREL_BASE as well. */
4214 if (GET_CODE (*x
) == UNSPEC
4215 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
4217 rtx base
= cfun
->machine
->base_reg
;
4218 *x
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XVECEXP (*x
, 0, 0), base
),
4223 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
4224 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
4228 annotate_constant_pool_refs (&XEXP (*x
, i
));
4230 else if (fmt
[i
] == 'E')
4232 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
4233 annotate_constant_pool_refs (&XVECEXP (*x
, i
, j
));
4239 /* Find an annotated literal pool symbol referenced in RTX X,
4240 and store it at REF. Will abort if X contains references to
4241 more than one such pool symbol; multiple references to the same
4242 symbol are allowed, however.
4244 The rtx pointed to by REF must be initialized to NULL_RTX
4245 by the caller before calling this routine. */
4248 find_constant_pool_ref (rtx x
, rtx
*ref
)
4253 /* Ignore LTREL_BASE references. */
4254 if (GET_CODE (x
) == UNSPEC
4255 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
4257 /* Likewise POOL_ENTRY insns. */
4258 if (GET_CODE (x
) == UNSPEC_VOLATILE
4259 && XINT (x
, 1) == UNSPECV_POOL_ENTRY
)
4262 if (GET_CODE (x
) == SYMBOL_REF
4263 && CONSTANT_POOL_ADDRESS_P (x
))
4266 if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_LTREF
)
4268 rtx sym
= XVECEXP (x
, 0, 0);
4269 if (GET_CODE (sym
) != SYMBOL_REF
4270 || !CONSTANT_POOL_ADDRESS_P (sym
))
4273 if (*ref
== NULL_RTX
)
4275 else if (*ref
!= sym
)
4281 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
4282 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
4286 find_constant_pool_ref (XEXP (x
, i
), ref
);
4288 else if (fmt
[i
] == 'E')
4290 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
4291 find_constant_pool_ref (XVECEXP (x
, i
, j
), ref
);
4296 /* Replace every reference to the annotated literal pool
4297 symbol REF in X by its base plus OFFSET. */
4300 replace_constant_pool_ref (rtx
*x
, rtx ref
, rtx offset
)
4308 if (GET_CODE (*x
) == UNSPEC
4309 && XINT (*x
, 1) == UNSPEC_LTREF
4310 && XVECEXP (*x
, 0, 0) == ref
)
4312 *x
= gen_rtx_PLUS (Pmode
, XVECEXP (*x
, 0, 1), offset
);
4316 if (GET_CODE (*x
) == PLUS
4317 && GET_CODE (XEXP (*x
, 1)) == CONST_INT
4318 && GET_CODE (XEXP (*x
, 0)) == UNSPEC
4319 && XINT (XEXP (*x
, 0), 1) == UNSPEC_LTREF
4320 && XVECEXP (XEXP (*x
, 0), 0, 0) == ref
)
4322 rtx addr
= gen_rtx_PLUS (Pmode
, XVECEXP (XEXP (*x
, 0), 0, 1), offset
);
4323 *x
= plus_constant (addr
, INTVAL (XEXP (*x
, 1)));
4327 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
4328 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
4332 replace_constant_pool_ref (&XEXP (*x
, i
), ref
, offset
);
4334 else if (fmt
[i
] == 'E')
4336 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
4337 replace_constant_pool_ref (&XVECEXP (*x
, i
, j
), ref
, offset
);
4342 /* Check whether X contains an UNSPEC_LTREL_BASE.
4343 Return its constant pool symbol if found, NULL_RTX otherwise. */
4346 find_ltrel_base (rtx x
)
4351 if (GET_CODE (x
) == UNSPEC
4352 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
4353 return XVECEXP (x
, 0, 0);
4355 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
4356 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
4360 rtx fnd
= find_ltrel_base (XEXP (x
, i
));
4364 else if (fmt
[i
] == 'E')
4366 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
4368 rtx fnd
= find_ltrel_base (XVECEXP (x
, i
, j
));
4378 /* Replace any occurrence of UNSPEC_LTREL_BASE in X with its base. */
4381 replace_ltrel_base (rtx
*x
)
4386 if (GET_CODE (*x
) == UNSPEC
4387 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
4389 *x
= XVECEXP (*x
, 0, 1);
4393 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
4394 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
4398 replace_ltrel_base (&XEXP (*x
, i
));
4400 else if (fmt
[i
] == 'E')
4402 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
4403 replace_ltrel_base (&XVECEXP (*x
, i
, j
));
4409 /* We keep a list of constants which we have to add to internal
4410 constant tables in the middle of large functions. */
4412 #define NR_C_MODES 7
4413 enum machine_mode constant_modes
[NR_C_MODES
] =
4424 struct constant
*next
;
4429 struct constant_pool
4431 struct constant_pool
*next
;
4436 struct constant
*constants
[NR_C_MODES
];
4441 static struct constant_pool
* s390_mainpool_start (void);
4442 static void s390_mainpool_finish (struct constant_pool
*);
4443 static void s390_mainpool_cancel (struct constant_pool
*);
4445 static struct constant_pool
* s390_chunkify_start (void);
4446 static void s390_chunkify_finish (struct constant_pool
*);
4447 static void s390_chunkify_cancel (struct constant_pool
*);
4449 static struct constant_pool
*s390_start_pool (struct constant_pool
**, rtx
);
4450 static void s390_end_pool (struct constant_pool
*, rtx
);
4451 static void s390_add_pool_insn (struct constant_pool
*, rtx
);
4452 static struct constant_pool
*s390_find_pool (struct constant_pool
*, rtx
);
4453 static void s390_add_constant (struct constant_pool
*, rtx
, enum machine_mode
);
4454 static rtx
s390_find_constant (struct constant_pool
*, rtx
, enum machine_mode
);
4455 static rtx
s390_dump_pool (struct constant_pool
*, bool);
4456 static struct constant_pool
*s390_alloc_pool (void);
4457 static void s390_free_pool (struct constant_pool
*);
4459 /* Create new constant pool covering instructions starting at INSN
4460 and chain it to the end of POOL_LIST. */
4462 static struct constant_pool
*
4463 s390_start_pool (struct constant_pool
**pool_list
, rtx insn
)
4465 struct constant_pool
*pool
, **prev
;
4467 pool
= s390_alloc_pool ();
4468 pool
->first_insn
= insn
;
4470 for (prev
= pool_list
; *prev
; prev
= &(*prev
)->next
)
4477 /* End range of instructions covered by POOL at INSN and emit
4478 placeholder insn representing the pool. */
4481 s390_end_pool (struct constant_pool
*pool
, rtx insn
)
4483 rtx pool_size
= GEN_INT (pool
->size
+ 8 /* alignment slop */);
4486 insn
= get_last_insn ();
4488 pool
->pool_insn
= emit_insn_after (gen_pool (pool_size
), insn
);
4489 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
4492 /* Add INSN to the list of insns covered by POOL. */
4495 s390_add_pool_insn (struct constant_pool
*pool
, rtx insn
)
4497 bitmap_set_bit (pool
->insns
, INSN_UID (insn
));
4500 /* Return pool out of POOL_LIST that covers INSN. */
4502 static struct constant_pool
*
4503 s390_find_pool (struct constant_pool
*pool_list
, rtx insn
)
4505 struct constant_pool
*pool
;
4507 for (pool
= pool_list
; pool
; pool
= pool
->next
)
4508 if (bitmap_bit_p (pool
->insns
, INSN_UID (insn
)))
4514 /* Add constant VAL of mode MODE to the constant pool POOL. */
4517 s390_add_constant (struct constant_pool
*pool
, rtx val
, enum machine_mode mode
)
4522 for (i
= 0; i
< NR_C_MODES
; i
++)
4523 if (constant_modes
[i
] == mode
)
4525 if (i
== NR_C_MODES
)
4528 for (c
= pool
->constants
[i
]; c
!= NULL
; c
= c
->next
)
4529 if (rtx_equal_p (val
, c
->value
))
4534 c
= (struct constant
*) xmalloc (sizeof *c
);
4536 c
->label
= gen_label_rtx ();
4537 c
->next
= pool
->constants
[i
];
4538 pool
->constants
[i
] = c
;
4539 pool
->size
+= GET_MODE_SIZE (mode
);
4543 /* Find constant VAL of mode MODE in the constant pool POOL.
4544 Return an RTX describing the distance from the start of
4545 the pool to the location of the new constant. */
4548 s390_find_constant (struct constant_pool
*pool
, rtx val
,
4549 enum machine_mode mode
)
4555 for (i
= 0; i
< NR_C_MODES
; i
++)
4556 if (constant_modes
[i
] == mode
)
4558 if (i
== NR_C_MODES
)
4561 for (c
= pool
->constants
[i
]; c
!= NULL
; c
= c
->next
)
4562 if (rtx_equal_p (val
, c
->value
))
4568 offset
= gen_rtx_MINUS (Pmode
, gen_rtx_LABEL_REF (Pmode
, c
->label
),
4569 gen_rtx_LABEL_REF (Pmode
, pool
->label
));
4570 offset
= gen_rtx_CONST (Pmode
, offset
);
4574 /* Dump out the constants in POOL. If REMOTE_LABEL is true,
4575 do not emit the pool base label. */
4578 s390_dump_pool (struct constant_pool
*pool
, bool remote_label
)
4584 /* Pool start insn switches to proper section
4585 and guarantees necessary alignment. */
4586 if (TARGET_CPU_ZARCH
)
4587 insn
= emit_insn_after (gen_pool_start_64 (), pool
->pool_insn
);
4589 insn
= emit_insn_after (gen_pool_start_31 (), pool
->pool_insn
);
4590 INSN_ADDRESSES_NEW (insn
, -1);
4594 insn
= emit_label_after (pool
->label
, insn
);
4595 INSN_ADDRESSES_NEW (insn
, -1);
4598 /* Dump constants in descending alignment requirement order,
4599 ensuring proper alignment for every constant. */
4600 for (i
= 0; i
< NR_C_MODES
; i
++)
4601 for (c
= pool
->constants
[i
]; c
; c
= c
->next
)
4603 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
4604 rtx value
= c
->value
;
4605 if (GET_CODE (value
) == CONST
4606 && GET_CODE (XEXP (value
, 0)) == UNSPEC
4607 && XINT (XEXP (value
, 0), 1) == UNSPEC_LTREL_OFFSET
4608 && XVECLEN (XEXP (value
, 0), 0) == 1)
4610 value
= gen_rtx_MINUS (Pmode
, XVECEXP (XEXP (value
, 0), 0, 0),
4611 gen_rtx_LABEL_REF (VOIDmode
, pool
->label
));
4612 value
= gen_rtx_CONST (VOIDmode
, value
);
4615 insn
= emit_label_after (c
->label
, insn
);
4616 INSN_ADDRESSES_NEW (insn
, -1);
4618 value
= gen_rtx_UNSPEC_VOLATILE (constant_modes
[i
],
4619 gen_rtvec (1, value
),
4620 UNSPECV_POOL_ENTRY
);
4621 insn
= emit_insn_after (value
, insn
);
4622 INSN_ADDRESSES_NEW (insn
, -1);
4625 /* Pool end insn switches back to previous section
4626 and guarantees necessary alignment. */
4627 if (TARGET_CPU_ZARCH
)
4628 insn
= emit_insn_after (gen_pool_end_64 (), insn
);
4630 insn
= emit_insn_after (gen_pool_end_31 (), insn
);
4631 INSN_ADDRESSES_NEW (insn
, -1);
4633 insn
= emit_barrier_after (insn
);
4634 INSN_ADDRESSES_NEW (insn
, -1);
4636 /* Remove placeholder insn. */
4637 remove_insn (pool
->pool_insn
);
4642 /* Allocate new constant_pool structure. */
4644 static struct constant_pool
*
4645 s390_alloc_pool (void)
4647 struct constant_pool
*pool
;
4650 pool
= (struct constant_pool
*) xmalloc (sizeof *pool
);
4652 for (i
= 0; i
< NR_C_MODES
; i
++)
4653 pool
->constants
[i
] = NULL
;
4655 pool
->label
= gen_label_rtx ();
4656 pool
->first_insn
= NULL_RTX
;
4657 pool
->pool_insn
= NULL_RTX
;
4658 pool
->insns
= BITMAP_XMALLOC ();
4664 /* Free all memory used by POOL. */
4667 s390_free_pool (struct constant_pool
*pool
)
4671 for (i
= 0; i
< NR_C_MODES
; i
++)
4673 struct constant
*c
= pool
->constants
[i
];
4676 struct constant
*next
= c
->next
;
4682 BITMAP_XFREE (pool
->insns
);
4687 /* Collect main literal pool. Return NULL on overflow. */
4689 static struct constant_pool
*
4690 s390_mainpool_start (void)
4692 struct constant_pool
*pool
;
4695 pool
= s390_alloc_pool ();
4697 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
4699 if (GET_CODE (insn
) == INSN
4700 && GET_CODE (PATTERN (insn
)) == SET
4701 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC_VOLATILE
4702 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPECV_MAIN_POOL
)
4704 if (pool
->pool_insn
)
4706 pool
->pool_insn
= insn
;
4709 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
4711 rtx pool_ref
= NULL_RTX
;
4712 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
4715 rtx constant
= get_pool_constant (pool_ref
);
4716 enum machine_mode mode
= get_pool_mode (pool_ref
);
4717 s390_add_constant (pool
, constant
, mode
);
4722 if (!pool
->pool_insn
)
4725 if (pool
->size
>= 4096)
4727 /* We're going to chunkify the pool, so remove the main
4728 pool placeholder insn. */
4729 remove_insn (pool
->pool_insn
);
4731 s390_free_pool (pool
);
4738 /* POOL holds the main literal pool as collected by s390_mainpool_start.
4739 Modify the current function to output the pool constants as well as
4740 the pool register setup instruction. */
4743 s390_mainpool_finish (struct constant_pool
*pool
)
4745 rtx base_reg
= SET_DEST (PATTERN (pool
->pool_insn
));
4748 /* If the pool is empty, we're done. */
4749 if (pool
->size
== 0)
4751 remove_insn (pool
->pool_insn
);
4752 s390_free_pool (pool
);
4756 /* We need correct insn addresses. */
4757 shorten_branches (get_insns ());
4759 /* On zSeries, we use a LARL to load the pool register. The pool is
4760 located in the .rodata section, so we emit it after the function. */
4761 if (TARGET_CPU_ZARCH
)
4763 insn
= gen_main_base_64 (base_reg
, pool
->label
);
4764 insn
= emit_insn_after (insn
, pool
->pool_insn
);
4765 INSN_ADDRESSES_NEW (insn
, -1);
4766 remove_insn (pool
->pool_insn
);
4768 insn
= get_last_insn ();
4769 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
4770 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
4772 s390_dump_pool (pool
, 0);
4775 /* On S/390, if the total size of the function's code plus literal pool
4776 does not exceed 4096 bytes, we use BASR to set up a function base
4777 pointer, and emit the literal pool at the end of the function. */
4778 else if (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
4779 + pool
->size
+ 8 /* alignment slop */ < 4096)
4781 insn
= gen_main_base_31_small (base_reg
, pool
->label
);
4782 insn
= emit_insn_after (insn
, pool
->pool_insn
);
4783 INSN_ADDRESSES_NEW (insn
, -1);
4784 remove_insn (pool
->pool_insn
);
4786 insn
= emit_label_after (pool
->label
, insn
);
4787 INSN_ADDRESSES_NEW (insn
, -1);
4789 insn
= get_last_insn ();
4790 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
4791 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
4793 s390_dump_pool (pool
, 1);
4796 /* Otherwise, we emit an inline literal pool and use BASR to branch
4797 over it, setting up the pool register at the same time. */
4800 rtx pool_end
= gen_label_rtx ();
4802 insn
= gen_main_base_31_large (base_reg
, pool
->label
, pool_end
);
4803 insn
= emit_insn_after (insn
, pool
->pool_insn
);
4804 INSN_ADDRESSES_NEW (insn
, -1);
4805 remove_insn (pool
->pool_insn
);
4807 insn
= emit_label_after (pool
->label
, insn
);
4808 INSN_ADDRESSES_NEW (insn
, -1);
4810 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
4811 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
4813 insn
= emit_label_after (pool_end
, pool
->pool_insn
);
4814 INSN_ADDRESSES_NEW (insn
, -1);
4816 s390_dump_pool (pool
, 1);
4820 /* Replace all literal pool references. */
4822 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
4825 replace_ltrel_base (&PATTERN (insn
));
4827 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
4829 rtx addr
, pool_ref
= NULL_RTX
;
4830 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
4833 addr
= s390_find_constant (pool
, get_pool_constant (pool_ref
),
4834 get_pool_mode (pool_ref
));
4835 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
4836 INSN_CODE (insn
) = -1;
4842 /* Free the pool. */
4843 s390_free_pool (pool
);
4846 /* POOL holds the main literal pool as collected by s390_mainpool_start.
4847 We have decided we cannot use this pool, so revert all changes
4848 to the current function that were done by s390_mainpool_start. */
4850 s390_mainpool_cancel (struct constant_pool
*pool
)
4852 /* We didn't actually change the instruction stream, so simply
4853 free the pool memory. */
4854 s390_free_pool (pool
);
4858 /* Chunkify the literal pool. */
4860 #define S390_POOL_CHUNK_MIN 0xc00
4861 #define S390_POOL_CHUNK_MAX 0xe00
4863 static struct constant_pool
*
4864 s390_chunkify_start (void)
4866 struct constant_pool
*curr_pool
= NULL
, *pool_list
= NULL
;
4869 rtx pending_ltrel
= NULL_RTX
;
4872 rtx (*gen_reload_base
) (rtx
, rtx
) =
4873 TARGET_CPU_ZARCH
? gen_reload_base_64
: gen_reload_base_31
;
4876 /* We need correct insn addresses. */
4878 shorten_branches (get_insns ());
4880 /* Scan all insns and move literals to pool chunks. */
4882 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
4884 /* Check for pending LTREL_BASE. */
4887 rtx ltrel_base
= find_ltrel_base (PATTERN (insn
));
4890 if (ltrel_base
== pending_ltrel
)
4891 pending_ltrel
= NULL_RTX
;
4897 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
4899 rtx pool_ref
= NULL_RTX
;
4900 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
4903 rtx constant
= get_pool_constant (pool_ref
);
4904 enum machine_mode mode
= get_pool_mode (pool_ref
);
4907 curr_pool
= s390_start_pool (&pool_list
, insn
);
4909 s390_add_constant (curr_pool
, constant
, mode
);
4910 s390_add_pool_insn (curr_pool
, insn
);
4912 /* Don't split the pool chunk between a LTREL_OFFSET load
4913 and the corresponding LTREL_BASE. */
4914 if (GET_CODE (constant
) == CONST
4915 && GET_CODE (XEXP (constant
, 0)) == UNSPEC
4916 && XINT (XEXP (constant
, 0), 1) == UNSPEC_LTREL_OFFSET
)
4920 pending_ltrel
= pool_ref
;
4925 if (GET_CODE (insn
) == JUMP_INSN
|| GET_CODE (insn
) == CODE_LABEL
)
4928 s390_add_pool_insn (curr_pool
, insn
);
4929 /* An LTREL_BASE must follow within the same basic block. */
4935 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn
)
4936 || INSN_ADDRESSES (INSN_UID (insn
)) == -1)
4939 if (TARGET_CPU_ZARCH
)
4941 if (curr_pool
->size
< S390_POOL_CHUNK_MAX
)
4944 s390_end_pool (curr_pool
, NULL_RTX
);
4949 int chunk_size
= INSN_ADDRESSES (INSN_UID (insn
))
4950 - INSN_ADDRESSES (INSN_UID (curr_pool
->first_insn
))
4953 /* We will later have to insert base register reload insns.
4954 Those will have an effect on code size, which we need to
4955 consider here. This calculation makes rather pessimistic
4956 worst-case assumptions. */
4957 if (GET_CODE (insn
) == CODE_LABEL
)
4960 if (chunk_size
< S390_POOL_CHUNK_MIN
4961 && curr_pool
->size
< S390_POOL_CHUNK_MIN
)
4964 /* Pool chunks can only be inserted after BARRIERs ... */
4965 if (GET_CODE (insn
) == BARRIER
)
4967 s390_end_pool (curr_pool
, insn
);
4972 /* ... so if we don't find one in time, create one. */
4973 else if ((chunk_size
> S390_POOL_CHUNK_MAX
4974 || curr_pool
->size
> S390_POOL_CHUNK_MAX
))
4976 rtx label
, jump
, barrier
;
4978 /* We can insert the barrier only after a 'real' insn. */
4979 if (GET_CODE (insn
) != INSN
&& GET_CODE (insn
) != CALL_INSN
)
4981 if (get_attr_length (insn
) == 0)
4984 /* Don't separate LTREL_BASE from the corresponding
4985 LTREL_OFFSET load. */
4989 label
= gen_label_rtx ();
4990 jump
= emit_jump_insn_after (gen_jump (label
), insn
);
4991 barrier
= emit_barrier_after (jump
);
4992 insn
= emit_label_after (label
, barrier
);
4993 JUMP_LABEL (jump
) = label
;
4994 LABEL_NUSES (label
) = 1;
4996 INSN_ADDRESSES_NEW (jump
, -1);
4997 INSN_ADDRESSES_NEW (barrier
, -1);
4998 INSN_ADDRESSES_NEW (insn
, -1);
5000 s390_end_pool (curr_pool
, barrier
);
5008 s390_end_pool (curr_pool
, NULL_RTX
);
5013 /* Find all labels that are branched into
5014 from an insn belonging to a different chunk. */
5016 far_labels
= BITMAP_XMALLOC ();
5018 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5020 /* Labels marked with LABEL_PRESERVE_P can be target
5021 of non-local jumps, so we have to mark them.
5022 The same holds for named labels.
5024 Don't do that, however, if it is the label before
5027 if (GET_CODE (insn
) == CODE_LABEL
5028 && (LABEL_PRESERVE_P (insn
) || LABEL_NAME (insn
)))
5030 rtx vec_insn
= next_real_insn (insn
);
5031 rtx vec_pat
= vec_insn
&& GET_CODE (vec_insn
) == JUMP_INSN
?
5032 PATTERN (vec_insn
) : NULL_RTX
;
5034 || !(GET_CODE (vec_pat
) == ADDR_VEC
5035 || GET_CODE (vec_pat
) == ADDR_DIFF_VEC
))
5036 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (insn
));
5039 /* If we have a direct jump (conditional or unconditional)
5040 or a casesi jump, check all potential targets. */
5041 else if (GET_CODE (insn
) == JUMP_INSN
)
5043 rtx pat
= PATTERN (insn
);
5044 if (GET_CODE (pat
) == PARALLEL
&& XVECLEN (pat
, 0) > 2)
5045 pat
= XVECEXP (pat
, 0, 0);
5047 if (GET_CODE (pat
) == SET
)
5049 rtx label
= JUMP_LABEL (insn
);
5052 if (s390_find_pool (pool_list
, label
)
5053 != s390_find_pool (pool_list
, insn
))
5054 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
5057 else if (GET_CODE (pat
) == PARALLEL
5058 && XVECLEN (pat
, 0) == 2
5059 && GET_CODE (XVECEXP (pat
, 0, 0)) == SET
5060 && GET_CODE (XVECEXP (pat
, 0, 1)) == USE
5061 && GET_CODE (XEXP (XVECEXP (pat
, 0, 1), 0)) == LABEL_REF
)
5063 /* Find the jump table used by this casesi jump. */
5064 rtx vec_label
= XEXP (XEXP (XVECEXP (pat
, 0, 1), 0), 0);
5065 rtx vec_insn
= next_real_insn (vec_label
);
5066 rtx vec_pat
= vec_insn
&& GET_CODE (vec_insn
) == JUMP_INSN
?
5067 PATTERN (vec_insn
) : NULL_RTX
;
5069 && (GET_CODE (vec_pat
) == ADDR_VEC
5070 || GET_CODE (vec_pat
) == ADDR_DIFF_VEC
))
5072 int i
, diff_p
= GET_CODE (vec_pat
) == ADDR_DIFF_VEC
;
5074 for (i
= 0; i
< XVECLEN (vec_pat
, diff_p
); i
++)
5076 rtx label
= XEXP (XVECEXP (vec_pat
, diff_p
, i
), 0);
5078 if (s390_find_pool (pool_list
, label
)
5079 != s390_find_pool (pool_list
, insn
))
5080 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
5087 /* Insert base register reload insns before every pool. */
5089 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
5091 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
5093 rtx insn
= curr_pool
->first_insn
;
5094 INSN_ADDRESSES_NEW (emit_insn_before (new_insn
, insn
), -1);
5097 /* Insert base register reload insns at every far label. */
5099 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5100 if (GET_CODE (insn
) == CODE_LABEL
5101 && bitmap_bit_p (far_labels
, CODE_LABEL_NUMBER (insn
)))
5103 struct constant_pool
*pool
= s390_find_pool (pool_list
, insn
);
5106 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
5108 INSN_ADDRESSES_NEW (emit_insn_after (new_insn
, insn
), -1);
5113 BITMAP_XFREE (far_labels
);
5116 /* Recompute insn addresses. */
5118 init_insn_lengths ();
5119 shorten_branches (get_insns ());
5124 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
5125 After we have decided to use this list, finish implementing
5126 all changes to the current function as required. */
5129 s390_chunkify_finish (struct constant_pool
*pool_list
)
5131 struct constant_pool
*curr_pool
= NULL
;
5135 /* Replace all literal pool references. */
5137 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5140 replace_ltrel_base (&PATTERN (insn
));
5142 curr_pool
= s390_find_pool (pool_list
, insn
);
5146 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5148 rtx addr
, pool_ref
= NULL_RTX
;
5149 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5152 addr
= s390_find_constant (curr_pool
, get_pool_constant (pool_ref
),
5153 get_pool_mode (pool_ref
));
5154 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
5155 INSN_CODE (insn
) = -1;
5160 /* Dump out all literal pools. */
5162 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
5163 s390_dump_pool (curr_pool
, 0);
5165 /* Free pool list. */
5169 struct constant_pool
*next
= pool_list
->next
;
5170 s390_free_pool (pool_list
);
5175 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
5176 We have decided we cannot use this list, so revert all changes
5177 to the current function that were done by s390_chunkify_start. */
5180 s390_chunkify_cancel (struct constant_pool
*pool_list
)
5182 struct constant_pool
*curr_pool
= NULL
;
5185 /* Remove all pool placeholder insns. */
5187 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
5189 /* Did we insert an extra barrier? Remove it. */
5190 rtx barrier
= PREV_INSN (curr_pool
->pool_insn
);
5191 rtx jump
= barrier
? PREV_INSN (barrier
) : NULL_RTX
;
5192 rtx label
= NEXT_INSN (curr_pool
->pool_insn
);
5194 if (jump
&& GET_CODE (jump
) == JUMP_INSN
5195 && barrier
&& GET_CODE (barrier
) == BARRIER
5196 && label
&& GET_CODE (label
) == CODE_LABEL
5197 && GET_CODE (PATTERN (jump
)) == SET
5198 && SET_DEST (PATTERN (jump
)) == pc_rtx
5199 && GET_CODE (SET_SRC (PATTERN (jump
))) == LABEL_REF
5200 && XEXP (SET_SRC (PATTERN (jump
)), 0) == label
)
5203 remove_insn (barrier
);
5204 remove_insn (label
);
5207 remove_insn (curr_pool
->pool_insn
);
5210 /* Remove all base register reload insns. */
5212 for (insn
= get_insns (); insn
; )
5214 rtx next_insn
= NEXT_INSN (insn
);
5216 if (GET_CODE (insn
) == INSN
5217 && GET_CODE (PATTERN (insn
)) == SET
5218 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC
5219 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPEC_RELOAD_BASE
)
5225 /* Free pool list. */
5229 struct constant_pool
*next
= pool_list
->next
;
5230 s390_free_pool (pool_list
);
5236 /* Output the constant pool entry EXP in mode MODE with alignment ALIGN. */
5239 s390_output_pool_entry (rtx exp
, enum machine_mode mode
, unsigned int align
)
5243 switch (GET_MODE_CLASS (mode
))
5246 if (GET_CODE (exp
) != CONST_DOUBLE
)
5249 REAL_VALUE_FROM_CONST_DOUBLE (r
, exp
);
5250 assemble_real (r
, mode
, align
);
5254 assemble_integer (exp
, GET_MODE_SIZE (mode
), align
, 1);
5263 /* Rework the prolog/epilog to avoid saving/restoring
5264 registers unnecessarily. BASE_USED specifies whether
5265 the literal pool base register needs to be saved. */
5268 s390_optimize_prolog (bool base_used
)
5270 rtx insn
, new_insn
, next_insn
;
5272 /* Do a final recompute of the frame-related data. */
5274 s390_frame_info (base_used
, cfun
->machine
->save_return_addr_p
);
5275 regs_ever_live
[BASE_REGISTER
] = base_used
;
5276 regs_ever_live
[RETURN_REGNUM
] = cfun
->machine
->save_return_addr_p
;
5277 regs_ever_live
[STACK_POINTER_REGNUM
] = cfun
->machine
->frame_size
> 0;
5279 /* If all special registers are in fact used, there's nothing we
5280 can do, so no point in walking the insn list. */
5282 if (cfun
->machine
->first_save_gpr
<= BASE_REGISTER
5283 && cfun
->machine
->last_save_gpr
>= BASE_REGISTER
5284 && (TARGET_CPU_ZARCH
5285 || (cfun
->machine
->first_save_gpr
<= RETURN_REGNUM
5286 && cfun
->machine
->last_save_gpr
>= RETURN_REGNUM
)))
5289 /* Search for prolog/epilog insns and replace them. */
5291 for (insn
= get_insns (); insn
; insn
= next_insn
)
5293 int first
, last
, off
;
5294 rtx set
, base
, offset
;
5296 next_insn
= NEXT_INSN (insn
);
5298 if (GET_CODE (insn
) != INSN
)
5301 if (GET_CODE (PATTERN (insn
)) == PARALLEL
5302 && store_multiple_operation (PATTERN (insn
), VOIDmode
))
5304 set
= XVECEXP (PATTERN (insn
), 0, 0);
5305 first
= REGNO (SET_SRC (set
));
5306 last
= first
+ XVECLEN (PATTERN (insn
), 0) - 1;
5307 offset
= const0_rtx
;
5308 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
5309 off
= INTVAL (offset
) - first
* UNITS_PER_WORD
;
5311 if (GET_CODE (base
) != REG
|| off
< 0)
5313 if (first
> BASE_REGISTER
|| last
< BASE_REGISTER
)
5316 if (cfun
->machine
->first_save_gpr
!= -1)
5318 new_insn
= save_gprs (base
, off
, cfun
->machine
->first_save_gpr
,
5319 cfun
->machine
->last_save_gpr
);
5320 new_insn
= emit_insn_before (new_insn
, insn
);
5321 INSN_ADDRESSES_NEW (new_insn
, -1);
5328 if (GET_CODE (PATTERN (insn
)) == SET
5329 && GET_CODE (SET_SRC (PATTERN (insn
))) == REG
5330 && REGNO (SET_SRC (PATTERN (insn
))) == BASE_REGISTER
5331 && GET_CODE (SET_DEST (PATTERN (insn
))) == MEM
)
5333 set
= PATTERN (insn
);
5334 offset
= const0_rtx
;
5335 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
5336 off
= INTVAL (offset
) - BASE_REGISTER
* UNITS_PER_WORD
;
5338 if (GET_CODE (base
) != REG
|| off
< 0)
5341 if (cfun
->machine
->first_save_gpr
!= -1)
5343 new_insn
= save_gprs (base
, off
, cfun
->machine
->first_save_gpr
,
5344 cfun
->machine
->last_save_gpr
);
5345 new_insn
= emit_insn_before (new_insn
, insn
);
5346 INSN_ADDRESSES_NEW (new_insn
, -1);
5353 if (GET_CODE (PATTERN (insn
)) == PARALLEL
5354 && load_multiple_operation (PATTERN (insn
), VOIDmode
))
5356 set
= XVECEXP (PATTERN (insn
), 0, 0);
5357 first
= REGNO (SET_DEST (set
));
5358 last
= first
+ XVECLEN (PATTERN (insn
), 0) - 1;
5359 offset
= const0_rtx
;
5360 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
5361 off
= INTVAL (offset
) - first
* UNITS_PER_WORD
;
5363 if (GET_CODE (base
) != REG
|| off
< 0)
5365 if (first
> BASE_REGISTER
|| last
< BASE_REGISTER
)
5368 if (cfun
->machine
->first_restore_gpr
!= -1)
5370 new_insn
= restore_gprs (base
, off
, cfun
->machine
->first_restore_gpr
,
5371 cfun
->machine
->last_restore_gpr
);
5372 new_insn
= emit_insn_before (new_insn
, insn
);
5373 INSN_ADDRESSES_NEW (new_insn
, -1);
5380 if (GET_CODE (PATTERN (insn
)) == SET
5381 && GET_CODE (SET_DEST (PATTERN (insn
))) == REG
5382 && REGNO (SET_DEST (PATTERN (insn
))) == BASE_REGISTER
5383 && GET_CODE (SET_SRC (PATTERN (insn
))) == MEM
)
5385 set
= PATTERN (insn
);
5386 offset
= const0_rtx
;
5387 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
5388 off
= INTVAL (offset
) - BASE_REGISTER
* UNITS_PER_WORD
;
5390 if (GET_CODE (base
) != REG
|| off
< 0)
5393 if (cfun
->machine
->first_restore_gpr
!= -1)
5395 new_insn
= restore_gprs (base
, off
, cfun
->machine
->first_restore_gpr
,
5396 cfun
->machine
->last_restore_gpr
);
5397 new_insn
= emit_insn_before (new_insn
, insn
);
5398 INSN_ADDRESSES_NEW (new_insn
, -1);
5407 /* Perform machine-dependent processing. */
5412 bool base_used
= false;
5413 bool pool_overflow
= false;
5415 /* Make sure all splits have been performed; splits after
5416 machine_dependent_reorg might confuse insn length counts. */
5417 split_all_insns_noflow ();
5420 /* Install the main literal pool and the associated base
5421 register load insns.
5423 In addition, there are two problematic situations we need
5426 - the literal pool might be > 4096 bytes in size, so that
5427 some of its elements cannot be directly accessed
5429 - a branch target might be > 64K away from the branch, so that
5430 it is not possible to use a PC-relative instruction.
5432 To fix those, we split the single literal pool into multiple
5433 pool chunks, reloading the pool base register at various
5434 points throughout the function to ensure it always points to
5435 the pool chunk the following code expects, and / or replace
5436 PC-relative branches by absolute branches.
5438 However, the two problems are interdependent: splitting the
5439 literal pool can move a branch further away from its target,
5440 causing the 64K limit to overflow, and on the other hand,
5441 replacing a PC-relative branch by an absolute branch means
5442 we need to put the branch target address into the literal
5443 pool, possibly causing it to overflow.
5445 So, we loop trying to fix up both problems until we manage
5446 to satisfy both conditions at the same time. Note that the
5447 loop is guaranteed to terminate as every pass of the loop
5448 strictly decreases the total number of PC-relative branches
5449 in the function. (This is not completely true as there
5450 might be branch-over-pool insns introduced by chunkify_start.
5451 Those never need to be split however.) */
5455 struct constant_pool
*pool
= NULL
;
5457 /* Collect the literal pool. */
5460 pool
= s390_mainpool_start ();
5462 pool_overflow
= true;
5465 /* If literal pool overflowed, start to chunkify it. */
5467 pool
= s390_chunkify_start ();
5469 /* Split out-of-range branches. If this has created new
5470 literal pool entries, cancel current chunk list and
5471 recompute it. zSeries machines have large branch
5472 instructions, so we never need to split a branch. */
5473 if (!TARGET_CPU_ZARCH
&& s390_split_branches ())
5476 s390_chunkify_cancel (pool
);
5478 s390_mainpool_cancel (pool
);
5483 /* If we made it up to here, both conditions are satisfied.
5484 Finish up literal pool related changes. */
5485 if ((pool_overflow
|| pool
->size
> 0)
5486 && REGNO (cfun
->machine
->base_reg
) == BASE_REGISTER
)
5490 s390_chunkify_finish (pool
);
5492 s390_mainpool_finish (pool
);
5497 s390_optimize_prolog (base_used
);
5501 /* Return an RTL expression representing the value of the return address
5502 for the frame COUNT steps up from the current frame. FRAME is the
5503 frame pointer of that frame. */
5506 s390_return_addr_rtx (int count
, rtx frame
)
5510 /* Without backchain, we fail for all but the current frame. */
5512 if (!TARGET_BACKCHAIN
&& count
> 0)
5515 /* For the current frame, we need to make sure the initial
5516 value of RETURN_REGNUM is actually saved. */
5519 cfun
->machine
->save_return_addr_p
= true;
5521 /* To retrieve the return address we read the stack slot where the
5522 corresponding RETURN_REGNUM value was saved. */
5524 addr
= plus_constant (frame
, RETURN_REGNUM
* UNITS_PER_WORD
);
5525 addr
= memory_address (Pmode
, addr
);
5526 return gen_rtx_MEM (Pmode
, addr
);
5529 /* Find first call clobbered register unused in a function.
5530 This could be used as base register in a leaf function
5531 or for holding the return address before epilogue. */
5534 find_unused_clobbered_reg (void)
5537 for (i
= 0; i
< 6; i
++)
5538 if (!regs_ever_live
[i
])
5543 /* Fill cfun->machine with info about frame of current function.
5544 BASE_USED and RETURN_ADDR_USED specify whether we assume the
5545 base and return address register will need to be saved. */
5548 s390_frame_info (int base_used
, int return_addr_used
)
5552 HOST_WIDE_INT fsize
= get_frame_size ();
5554 if (!TARGET_64BIT
&& fsize
> 0x7fff0000)
5555 fatal_error ("Total size of local variables exceeds architecture limit.");
5557 /* fprs 8 - 15 are caller saved for 64 Bit ABI. */
5558 cfun
->machine
->save_fprs_p
= 0;
5560 for (i
= 24; i
< 32; i
++)
5561 if (regs_ever_live
[i
] && !global_regs
[i
])
5563 cfun
->machine
->save_fprs_p
= 1;
5567 cfun
->machine
->frame_size
= fsize
+ cfun
->machine
->save_fprs_p
* 64;
5569 /* Does function need to setup frame and save area. */
5571 if (!current_function_is_leaf
5572 || TARGET_TPF_PROFILING
5573 || cfun
->machine
->frame_size
> 0
5574 || current_function_calls_alloca
5575 || current_function_stdarg
)
5576 cfun
->machine
->frame_size
+= STARTING_FRAME_OFFSET
;
5578 /* Find first and last gpr to be saved. We trust regs_ever_live
5579 data, except that we don't save and restore global registers.
5581 Also, all registers with special meaning to the compiler need
5582 to be handled extra. */
5584 for (i
= 0; i
< 16; i
++)
5585 live_regs
[i
] = regs_ever_live
[i
] && !global_regs
[i
];
5588 live_regs
[PIC_OFFSET_TABLE_REGNUM
] =
5589 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
];
5591 live_regs
[BASE_REGISTER
] = base_used
;
5592 live_regs
[RETURN_REGNUM
] = return_addr_used
;
5593 live_regs
[STACK_POINTER_REGNUM
] = cfun
->machine
->frame_size
> 0;
5595 for (i
= 6; i
< 16; i
++)
5598 for (j
= 15; j
> i
; j
--)
5604 /* Nothing to save/restore. */
5605 cfun
->machine
->first_save_gpr
= -1;
5606 cfun
->machine
->first_restore_gpr
= -1;
5607 cfun
->machine
->last_save_gpr
= -1;
5608 cfun
->machine
->last_restore_gpr
= -1;
5612 /* Save / Restore from gpr i to j. */
5613 cfun
->machine
->first_save_gpr
= i
;
5614 cfun
->machine
->first_restore_gpr
= i
;
5615 cfun
->machine
->last_save_gpr
= j
;
5616 cfun
->machine
->last_restore_gpr
= j
;
5619 /* Varargs functions need to save gprs 2 to 6. */
5620 if (current_function_stdarg
)
5622 if (cfun
->machine
->first_save_gpr
== -1
5623 || cfun
->machine
->first_save_gpr
> 2)
5624 cfun
->machine
->first_save_gpr
= 2;
5626 if (cfun
->machine
->last_save_gpr
== -1
5627 || cfun
->machine
->last_save_gpr
< 6)
5628 cfun
->machine
->last_save_gpr
= 6;
5632 /* Return offset between argument pointer and frame pointer
5633 initially after prologue. */
5636 s390_arg_frame_offset (void)
5638 /* See the comment in s390_emit_prologue about the assumptions we make
5639 whether or not the base and return address register need to be saved. */
5640 int return_addr_used
= !current_function_is_leaf
5641 || TARGET_TPF_PROFILING
5642 || regs_ever_live
[RETURN_REGNUM
]
5643 || cfun
->machine
->save_return_addr_p
;
5645 s390_frame_info (1, !TARGET_CPU_ZARCH
|| return_addr_used
);
5646 return cfun
->machine
->frame_size
+ STACK_POINTER_OFFSET
;
5649 /* Emit insn to save fpr REGNUM at offset OFFSET relative
5650 to register BASE. Return generated insn. */
5653 save_fpr (rtx base
, int offset
, int regnum
)
5656 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
5657 set_mem_alias_set (addr
, s390_sr_alias_set
);
5659 return emit_move_insn (addr
, gen_rtx_REG (DFmode
, regnum
));
5662 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
5663 to register BASE. Return generated insn. */
5666 restore_fpr (rtx base
, int offset
, int regnum
)
5669 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
5670 set_mem_alias_set (addr
, s390_sr_alias_set
);
5672 return emit_move_insn (gen_rtx_REG (DFmode
, regnum
), addr
);
5675 /* Generate insn to save registers FIRST to LAST into
5676 the register save area located at offset OFFSET
5677 relative to register BASE. */
5680 save_gprs (rtx base
, int offset
, int first
, int last
)
5682 rtx addr
, insn
, note
;
5685 addr
= plus_constant (base
, offset
+ first
* UNITS_PER_WORD
);
5686 addr
= gen_rtx_MEM (Pmode
, addr
);
5687 set_mem_alias_set (addr
, s390_sr_alias_set
);
5689 /* Special-case single register. */
5693 insn
= gen_movdi (addr
, gen_rtx_REG (Pmode
, first
));
5695 insn
= gen_movsi (addr
, gen_rtx_REG (Pmode
, first
));
5697 RTX_FRAME_RELATED_P (insn
) = 1;
5702 insn
= gen_store_multiple (addr
,
5703 gen_rtx_REG (Pmode
, first
),
5704 GEN_INT (last
- first
+ 1));
5707 /* We need to set the FRAME_RELATED flag on all SETs
5708 inside the store-multiple pattern.
5710 However, we must not emit DWARF records for registers 2..5
5711 if they are stored for use by variable arguments ...
5713 ??? Unfortunately, it is not enough to simply not the the
5714 FRAME_RELATED flags for those SETs, because the first SET
5715 of the PARALLEL is always treated as if it had the flag
5716 set, even if it does not. Therefore we emit a new pattern
5717 without those registers as REG_FRAME_RELATED_EXPR note. */
5721 rtx pat
= PATTERN (insn
);
5723 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
5724 if (GET_CODE (XVECEXP (pat
, 0, i
)) == SET
)
5725 RTX_FRAME_RELATED_P (XVECEXP (pat
, 0, i
)) = 1;
5727 RTX_FRAME_RELATED_P (insn
) = 1;
5731 addr
= plus_constant (base
, offset
+ 6 * UNITS_PER_WORD
);
5732 note
= gen_store_multiple (gen_rtx_MEM (Pmode
, addr
),
5733 gen_rtx_REG (Pmode
, 6),
5734 GEN_INT (last
- 6 + 1));
5735 note
= PATTERN (note
);
5738 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
5739 note
, REG_NOTES (insn
));
5741 for (i
= 0; i
< XVECLEN (note
, 0); i
++)
5742 if (GET_CODE (XVECEXP (note
, 0, i
)) == SET
)
5743 RTX_FRAME_RELATED_P (XVECEXP (note
, 0, i
)) = 1;
5745 RTX_FRAME_RELATED_P (insn
) = 1;
5751 /* Generate insn to restore registers FIRST to LAST from
5752 the register save area located at offset OFFSET
5753 relative to register BASE. */
5756 restore_gprs (rtx base
, int offset
, int first
, int last
)
5760 addr
= plus_constant (base
, offset
+ first
* UNITS_PER_WORD
);
5761 addr
= gen_rtx_MEM (Pmode
, addr
);
5762 set_mem_alias_set (addr
, s390_sr_alias_set
);
5764 /* Special-case single register. */
5768 insn
= gen_movdi (gen_rtx_REG (Pmode
, first
), addr
);
5770 insn
= gen_movsi (gen_rtx_REG (Pmode
, first
), addr
);
5775 insn
= gen_load_multiple (gen_rtx_REG (Pmode
, first
),
5777 GEN_INT (last
- first
+ 1));
5781 /* Return insn sequence to load the GOT register. */
5783 static GTY(()) rtx got_symbol
;
5785 s390_load_got (void)
5791 got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
5792 SYMBOL_REF_FLAGS (got_symbol
) = SYMBOL_FLAG_LOCAL
;
5797 if (TARGET_CPU_ZARCH
)
5799 emit_move_insn (pic_offset_table_rtx
, got_symbol
);
5805 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, got_symbol
),
5806 UNSPEC_LTREL_OFFSET
);
5807 offset
= gen_rtx_CONST (Pmode
, offset
);
5808 offset
= force_const_mem (Pmode
, offset
);
5810 emit_move_insn (pic_offset_table_rtx
, offset
);
5812 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, XEXP (offset
, 0)),
5814 offset
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, offset
);
5816 emit_move_insn (pic_offset_table_rtx
, offset
);
5819 insns
= get_insns ();
5824 /* Expand the prologue into a bunch of separate insns. */
5827 s390_emit_prologue (void)
5833 /* At this point, we decide whether we'll need to save/restore the
5834 return address register. This decision is final on zSeries machines;
5835 on S/390 it can still be overridden in s390_split_branches. */
5837 if (!current_function_is_leaf
5838 || TARGET_TPF_PROFILING
5839 || regs_ever_live
[RETURN_REGNUM
])
5840 cfun
->machine
->save_return_addr_p
= 1;
5842 /* Decide which register to use as literal pool base. In small leaf
5843 functions, try to use an unused call-clobbered register as base
5844 register to avoid save/restore overhead. */
5846 if (current_function_is_leaf
&& !regs_ever_live
[5])
5847 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, 5);
5849 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, BASE_REGISTER
);
5851 regs_ever_live
[REGNO (cfun
->machine
->base_reg
)] = 1;
5853 /* Compute frame info. Note that at this point, we assume the base
5854 register and -on S/390- the return register always need to be saved.
5855 This is done because the usage of these registers might change even
5856 after the prolog was emitted. If it turns out later that we really
5857 don't need them, the prolog/epilog code is modified again. */
5859 s390_frame_info (1, !TARGET_CPU_ZARCH
|| cfun
->machine
->save_return_addr_p
);
5861 /* We need to update regs_ever_live to avoid data-flow problems. */
5863 regs_ever_live
[BASE_REGISTER
] = 1;
5864 regs_ever_live
[RETURN_REGNUM
] = !TARGET_CPU_ZARCH
5865 || cfun
->machine
->save_return_addr_p
;
5866 regs_ever_live
[STACK_POINTER_REGNUM
] = cfun
->machine
->frame_size
> 0;
5868 /* Annotate all constant pool references to let the scheduler know
5869 they implicitly use the base register. */
5871 push_topmost_sequence ();
5873 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5875 annotate_constant_pool_refs (&PATTERN (insn
));
5877 pop_topmost_sequence ();
5879 /* Choose best register to use for temp use within prologue.
5880 See below for why TPF must use the register 1. */
5882 if (!current_function_is_leaf
5883 && !TARGET_TPF_PROFILING
)
5884 temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
5886 temp_reg
= gen_rtx_REG (Pmode
, 1);
5888 /* Save call saved gprs. */
5890 insn
= save_gprs (stack_pointer_rtx
, 0,
5891 cfun
->machine
->first_save_gpr
, cfun
->machine
->last_save_gpr
);
5894 /* Dummy insn to mark literal pool slot. */
5896 emit_insn (gen_main_pool (cfun
->machine
->base_reg
));
5898 /* Save fprs for variable args. */
5900 if (current_function_stdarg
)
5901 for (i
= 16; i
< (TARGET_64BIT
? 20 : 18); i
++)
5902 save_fpr (stack_pointer_rtx
, 16*UNITS_PER_WORD
+ 8*(i
-16), i
);
5904 /* Save fprs 4 and 6 if used (31 bit ABI). */
5907 for (i
= 18; i
< 20; i
++)
5908 if (regs_ever_live
[i
] && !global_regs
[i
])
5910 insn
= save_fpr (stack_pointer_rtx
, 16*UNITS_PER_WORD
+ 8*(i
-16), i
);
5911 RTX_FRAME_RELATED_P (insn
) = 1;
5914 /* Decrement stack pointer. */
5916 if (cfun
->machine
->frame_size
> 0)
5918 rtx frame_off
= GEN_INT (-cfun
->machine
->frame_size
);
5920 /* Save incoming stack pointer into temp reg. */
5922 if (TARGET_BACKCHAIN
|| cfun
->machine
->save_fprs_p
)
5924 insn
= emit_insn (gen_move_insn (temp_reg
, stack_pointer_rtx
));
5927 /* Subtract frame size from stack pointer. */
5929 if (DISP_IN_RANGE (INTVAL (frame_off
)))
5931 insn
= gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
5932 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
5934 insn
= emit_insn (insn
);
5938 if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off
), 'K', "K"))
5939 frame_off
= force_const_mem (Pmode
, frame_off
);
5941 insn
= emit_insn (gen_add2_insn (stack_pointer_rtx
, frame_off
));
5942 annotate_constant_pool_refs (&PATTERN (insn
));
5945 RTX_FRAME_RELATED_P (insn
) = 1;
5947 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
5948 gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
5949 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
5950 GEN_INT (-cfun
->machine
->frame_size
))),
5953 /* Set backchain. */
5955 if (TARGET_BACKCHAIN
)
5957 addr
= gen_rtx_MEM (Pmode
, stack_pointer_rtx
);
5958 set_mem_alias_set (addr
, s390_sr_alias_set
);
5959 insn
= emit_insn (gen_move_insn (addr
, temp_reg
));
5962 /* If we support asynchronous exceptions (e.g. for Java),
5963 we need to make sure the backchain pointer is set up
5964 before any possibly trapping memory access. */
5966 if (TARGET_BACKCHAIN
&& flag_non_call_exceptions
)
5968 addr
= gen_rtx_MEM (BLKmode
, gen_rtx_SCRATCH (VOIDmode
));
5969 emit_insn (gen_rtx_CLOBBER (VOIDmode
, addr
));
5973 /* Save fprs 8 - 15 (64 bit ABI). */
5975 if (cfun
->machine
->save_fprs_p
)
5977 insn
= emit_insn (gen_add2_insn (temp_reg
, GEN_INT(-64)));
5979 for (i
= 24; i
< 32; i
++)
5980 if (regs_ever_live
[i
] && !global_regs
[i
])
5982 rtx addr
= plus_constant (stack_pointer_rtx
,
5983 cfun
->machine
->frame_size
- 64 + (i
-24)*8);
5985 insn
= save_fpr (temp_reg
, (i
-24)*8, i
);
5986 RTX_FRAME_RELATED_P (insn
) = 1;
5988 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
5989 gen_rtx_SET (VOIDmode
,
5990 gen_rtx_MEM (DFmode
, addr
),
5991 gen_rtx_REG (DFmode
, i
)),
5996 /* Set frame pointer, if needed. */
5998 if (frame_pointer_needed
)
6000 insn
= emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
);
6001 RTX_FRAME_RELATED_P (insn
) = 1;
6004 /* Set up got pointer, if needed. */
6006 if (flag_pic
&& regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
])
6008 rtx insns
= s390_load_got ();
6010 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
6012 annotate_constant_pool_refs (&PATTERN (insn
));
6014 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD
, NULL_RTX
,
6021 if (TARGET_TPF_PROFILING
)
6023 /* Generate a BAS instruction to serve as a function
6024 entry intercept to facilitate the use of tracing
6025 algorithms located at the branch target. */
6026 emit_insn (gen_prologue_tpf ());
6028 /* Emit a blockage here so that all code
6029 lies between the profiling mechanisms. */
6030 emit_insn (gen_blockage ());
6034 /* Expand the epilogue into a bunch of separate insns. */
6037 s390_emit_epilogue (bool sibcall
)
6039 rtx frame_pointer
, return_reg
;
6040 int area_bottom
, area_top
, offset
= 0;
6044 if (TARGET_TPF_PROFILING
)
6047 /* Generate a BAS instruction to serve as a function
6048 entry intercept to facilitate the use of tracing
6049 algorithms located at the branch target. */
6051 /* Emit a blockage here so that all code
6052 lies between the profiling mechanisms. */
6053 emit_insn (gen_blockage ());
6055 emit_insn (gen_epilogue_tpf ());
6058 /* Check whether to use frame or stack pointer for restore. */
6060 frame_pointer
= frame_pointer_needed
?
6061 hard_frame_pointer_rtx
: stack_pointer_rtx
;
6063 /* Compute which parts of the save area we need to access. */
6065 if (cfun
->machine
->first_restore_gpr
!= -1)
6067 area_bottom
= cfun
->machine
->first_restore_gpr
* UNITS_PER_WORD
;
6068 area_top
= (cfun
->machine
->last_restore_gpr
+ 1) * UNITS_PER_WORD
;
6072 area_bottom
= INT_MAX
;
6078 if (cfun
->machine
->save_fprs_p
)
6080 if (area_bottom
> -64)
6088 for (i
= 18; i
< 20; i
++)
6089 if (regs_ever_live
[i
] && !global_regs
[i
])
6091 if (area_bottom
> 16*UNITS_PER_WORD
+ 8*(i
-16))
6092 area_bottom
= 16*UNITS_PER_WORD
+ 8*(i
-16);
6093 if (area_top
< 16*UNITS_PER_WORD
+ 8*(i
-16) + 8)
6094 area_top
= 16*UNITS_PER_WORD
+ 8*(i
-16) + 8;
6098 /* Check whether we can access the register save area.
6099 If not, increment the frame pointer as required. */
6101 if (area_top
<= area_bottom
)
6103 /* Nothing to restore. */
6105 else if (DISP_IN_RANGE (cfun
->machine
->frame_size
+ area_bottom
)
6106 && DISP_IN_RANGE (cfun
->machine
->frame_size
+ area_top
-1))
6108 /* Area is in range. */
6109 offset
= cfun
->machine
->frame_size
;
6113 rtx insn
, frame_off
;
6115 offset
= area_bottom
< 0 ? -area_bottom
: 0;
6116 frame_off
= GEN_INT (cfun
->machine
->frame_size
- offset
);
6118 if (DISP_IN_RANGE (INTVAL (frame_off
)))
6120 insn
= gen_rtx_SET (VOIDmode
, frame_pointer
,
6121 gen_rtx_PLUS (Pmode
, frame_pointer
, frame_off
));
6122 insn
= emit_insn (insn
);
6126 if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off
), 'K', "K"))
6127 frame_off
= force_const_mem (Pmode
, frame_off
);
6129 insn
= emit_insn (gen_add2_insn (frame_pointer
, frame_off
));
6130 annotate_constant_pool_refs (&PATTERN (insn
));
6134 /* Restore call saved fprs. */
6138 if (cfun
->machine
->save_fprs_p
)
6139 for (i
= 24; i
< 32; i
++)
6140 if (regs_ever_live
[i
] && !global_regs
[i
])
6141 restore_fpr (frame_pointer
,
6142 offset
- 64 + (i
-24) * 8, i
);
6146 for (i
= 18; i
< 20; i
++)
6147 if (regs_ever_live
[i
] && !global_regs
[i
])
6148 restore_fpr (frame_pointer
,
6149 offset
+ 16*UNITS_PER_WORD
+ 8*(i
-16), i
);
6152 /* Return register. */
6154 return_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
6156 /* Restore call saved gprs. */
6158 if (cfun
->machine
->first_restore_gpr
!= -1)
6163 /* Check for global register and save them
6164 to stack location from where they get restored. */
6166 for (i
= cfun
->machine
->first_restore_gpr
;
6167 i
<= cfun
->machine
->last_restore_gpr
;
6170 /* These registers are special and need to be
6171 restored in any case. */
6172 if (i
== STACK_POINTER_REGNUM
6173 || i
== RETURN_REGNUM
6174 || i
== BASE_REGISTER
6175 || (flag_pic
&& i
== (int)PIC_OFFSET_TABLE_REGNUM
))
6180 addr
= plus_constant (frame_pointer
,
6181 offset
+ i
* UNITS_PER_WORD
);
6182 addr
= gen_rtx_MEM (Pmode
, addr
);
6183 set_mem_alias_set (addr
, s390_sr_alias_set
);
6184 emit_move_insn (addr
, gen_rtx_REG (Pmode
, i
));
6190 /* Fetch return address from stack before load multiple,
6191 this will do good for scheduling. */
6193 if (cfun
->machine
->save_return_addr_p
6194 || (cfun
->machine
->first_restore_gpr
< BASE_REGISTER
6195 && cfun
->machine
->last_restore_gpr
> RETURN_REGNUM
))
6197 int return_regnum
= find_unused_clobbered_reg();
6200 return_reg
= gen_rtx_REG (Pmode
, return_regnum
);
6202 addr
= plus_constant (frame_pointer
,
6203 offset
+ RETURN_REGNUM
* UNITS_PER_WORD
);
6204 addr
= gen_rtx_MEM (Pmode
, addr
);
6205 set_mem_alias_set (addr
, s390_sr_alias_set
);
6206 emit_move_insn (return_reg
, addr
);
6210 insn
= restore_gprs (frame_pointer
, offset
,
6211 cfun
->machine
->first_restore_gpr
,
6212 cfun
->machine
->last_restore_gpr
);
6219 /* Return to caller. */
6221 p
= rtvec_alloc (2);
6223 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
6224 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
, return_reg
);
6225 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
6230 /* Return the size in bytes of a function argument of
6231 type TYPE and/or mode MODE. At least one of TYPE or
6232 MODE must be specified. */
6235 s390_function_arg_size (enum machine_mode mode
, tree type
)
6238 return int_size_in_bytes (type
);
6240 /* No type info available for some library calls ... */
6241 if (mode
!= BLKmode
)
6242 return GET_MODE_SIZE (mode
);
6244 /* If we have neither type nor mode, abort */
6248 /* Return true if a function argument of type TYPE and mode MODE
6249 is to be passed in a floating-point register, if available. */
6252 s390_function_arg_float (enum machine_mode mode
, tree type
)
6254 int size
= s390_function_arg_size (mode
, type
);
6258 /* Soft-float changes the ABI: no floating-point registers are used. */
6259 if (TARGET_SOFT_FLOAT
)
6262 /* No type info available for some library calls ... */
6264 return mode
== SFmode
|| mode
== DFmode
;
6266 /* The ABI says that record types with a single member are treated
6267 just like that member would be. */
6268 while (TREE_CODE (type
) == RECORD_TYPE
)
6270 tree field
, single
= NULL_TREE
;
6272 for (field
= TYPE_FIELDS (type
); field
; field
= TREE_CHAIN (field
))
6274 if (TREE_CODE (field
) != FIELD_DECL
)
6277 if (single
== NULL_TREE
)
6278 single
= TREE_TYPE (field
);
6283 if (single
== NULL_TREE
)
6289 return TREE_CODE (type
) == REAL_TYPE
;
6292 /* Return true if a function argument of type TYPE and mode MODE
6293 is to be passed in an integer register, or a pair of integer
6294 registers, if available. */
6297 s390_function_arg_integer (enum machine_mode mode
, tree type
)
6299 int size
= s390_function_arg_size (mode
, type
);
6303 /* No type info available for some library calls ... */
6305 return GET_MODE_CLASS (mode
) == MODE_INT
6306 || (TARGET_SOFT_FLOAT
&& GET_MODE_CLASS (mode
) == MODE_FLOAT
);
6308 /* We accept small integral (and similar) types. */
6309 if (INTEGRAL_TYPE_P (type
)
6310 || POINTER_TYPE_P (type
)
6311 || TREE_CODE (type
) == OFFSET_TYPE
6312 || (TARGET_SOFT_FLOAT
&& TREE_CODE (type
) == REAL_TYPE
))
6315 /* We also accept structs of size 1, 2, 4, 8 that are not
6316 passed in floating-point registers. */
6317 if (AGGREGATE_TYPE_P (type
)
6318 && exact_log2 (size
) >= 0
6319 && !s390_function_arg_float (mode
, type
))
6325 /* Return 1 if a function argument of type TYPE and mode MODE
6326 is to be passed by reference. The ABI specifies that only
6327 structures of size 1, 2, 4, or 8 bytes are passed by value,
6328 all other structures (and complex numbers) are passed by
6332 s390_pass_by_reference (CUMULATIVE_ARGS
*ca ATTRIBUTE_UNUSED
,
6333 enum machine_mode mode
, tree type
,
6334 bool named ATTRIBUTE_UNUSED
)
6336 int size
= s390_function_arg_size (mode
, type
);
6342 if (AGGREGATE_TYPE_P (type
) && exact_log2 (size
) < 0)
6345 if (TREE_CODE (type
) == COMPLEX_TYPE
6346 || TREE_CODE (type
) == VECTOR_TYPE
)
6353 /* Update the data in CUM to advance over an argument of mode MODE and
6354 data type TYPE. (TYPE is null for libcalls where that information
6355 may not be available.). The boolean NAMED specifies whether the
6356 argument is a named argument (as opposed to an unnamed argument
6357 matching an ellipsis). */
6360 s390_function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
6361 tree type
, int named ATTRIBUTE_UNUSED
)
6363 if (s390_function_arg_float (mode
, type
))
6367 else if (s390_function_arg_integer (mode
, type
))
6369 int size
= s390_function_arg_size (mode
, type
);
6370 cum
->gprs
+= ((size
+ UNITS_PER_WORD
-1) / UNITS_PER_WORD
);
6376 /* Define where to put the arguments to a function.
6377 Value is zero to push the argument on the stack,
6378 or a hard register in which to store the argument.
6380 MODE is the argument's machine mode.
6381 TYPE is the data type of the argument (as a tree).
6382 This is null for libcalls where that information may
6384 CUM is a variable of type CUMULATIVE_ARGS which gives info about
6385 the preceding args and about the function being called.
6386 NAMED is nonzero if this argument is a named parameter
6387 (otherwise it is an extra parameter matching an ellipsis).
6389 On S/390, we use general purpose registers 2 through 6 to
6390 pass integer, pointer, and certain structure arguments, and
6391 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
6392 to pass floating point arguments. All remaining arguments
6393 are pushed to the stack. */
6396 s390_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
, tree type
,
6397 int named ATTRIBUTE_UNUSED
)
6399 if (s390_function_arg_float (mode
, type
))
6401 if (cum
->fprs
+ 1 > (TARGET_64BIT
? 4 : 2))
6404 return gen_rtx_REG (mode
, cum
->fprs
+ 16);
6406 else if (s390_function_arg_integer (mode
, type
))
6408 int size
= s390_function_arg_size (mode
, type
);
6409 int n_gprs
= (size
+ UNITS_PER_WORD
-1) / UNITS_PER_WORD
;
6411 if (cum
->gprs
+ n_gprs
> 5)
6414 return gen_rtx_REG (mode
, cum
->gprs
+ 2);
6417 /* After the real arguments, expand_call calls us once again
6418 with a void_type_node type. Whatever we return here is
6419 passed as operand 2 to the call expanders.
6421 We don't need this feature ... */
6422 else if (type
== void_type_node
)
6428 /* Return true if return values of type TYPE should be returned
6429 in a memory buffer whose address is passed by the caller as
6430 hidden first argument. */
6433 s390_return_in_memory (tree type
, tree fundecl ATTRIBUTE_UNUSED
)
6435 /* We accept small integral (and similar) types. */
6436 if (INTEGRAL_TYPE_P (type
)
6437 || POINTER_TYPE_P (type
)
6438 || TREE_CODE (type
) == OFFSET_TYPE
6439 || TREE_CODE (type
) == REAL_TYPE
)
6440 return int_size_in_bytes (type
) > 8;
6442 /* Aggregates and similar constructs are always returned
6444 if (AGGREGATE_TYPE_P (type
)
6445 || TREE_CODE (type
) == COMPLEX_TYPE
6446 || TREE_CODE (type
) == VECTOR_TYPE
)
6449 /* ??? We get called on all sorts of random stuff from
6450 aggregate_value_p. We can't abort, but it's not clear
6451 what's safe to return. Pretend it's a struct I guess. */
6455 /* Define where to return a (scalar) value of type TYPE.
6456 If TYPE is null, define where to return a (scalar)
6457 value of mode MODE from a libcall. */
6460 s390_function_value (tree type
, enum machine_mode mode
)
6464 int unsignedp
= TYPE_UNSIGNED (type
);
6465 mode
= promote_mode (type
, TYPE_MODE (type
), &unsignedp
, 1);
6468 if (GET_MODE_CLASS (mode
) != MODE_INT
6469 && GET_MODE_CLASS (mode
) != MODE_FLOAT
)
6471 if (GET_MODE_SIZE (mode
) > 8)
6474 if (TARGET_HARD_FLOAT
&& GET_MODE_CLASS (mode
) == MODE_FLOAT
)
6475 return gen_rtx_REG (mode
, 16);
6477 return gen_rtx_REG (mode
, 2);
6481 /* Create and return the va_list datatype.
6483 On S/390, va_list is an array type equivalent to
6485 typedef struct __va_list_tag
6489 void *__overflow_arg_area;
6490 void *__reg_save_area;
6493 where __gpr and __fpr hold the number of general purpose
6494 or floating point arguments used up to now, respectively,
6495 __overflow_arg_area points to the stack location of the
6496 next argument passed on the stack, and __reg_save_area
6497 always points to the start of the register area in the
6498 call frame of the current function. The function prologue
6499 saves all registers used for argument passing into this
6500 area if the function uses variable arguments. */
6503 s390_build_builtin_va_list (void)
6505 tree f_gpr
, f_fpr
, f_ovf
, f_sav
, record
, type_decl
;
6507 record
= lang_hooks
.types
.make_type (RECORD_TYPE
);
6510 build_decl (TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
6512 f_gpr
= build_decl (FIELD_DECL
, get_identifier ("__gpr"),
6513 long_integer_type_node
);
6514 f_fpr
= build_decl (FIELD_DECL
, get_identifier ("__fpr"),
6515 long_integer_type_node
);
6516 f_ovf
= build_decl (FIELD_DECL
, get_identifier ("__overflow_arg_area"),
6518 f_sav
= build_decl (FIELD_DECL
, get_identifier ("__reg_save_area"),
6521 DECL_FIELD_CONTEXT (f_gpr
) = record
;
6522 DECL_FIELD_CONTEXT (f_fpr
) = record
;
6523 DECL_FIELD_CONTEXT (f_ovf
) = record
;
6524 DECL_FIELD_CONTEXT (f_sav
) = record
;
6526 TREE_CHAIN (record
) = type_decl
;
6527 TYPE_NAME (record
) = type_decl
;
6528 TYPE_FIELDS (record
) = f_gpr
;
6529 TREE_CHAIN (f_gpr
) = f_fpr
;
6530 TREE_CHAIN (f_fpr
) = f_ovf
;
6531 TREE_CHAIN (f_ovf
) = f_sav
;
6533 layout_type (record
);
6535 /* The correct type is an array type of one element. */
6536 return build_array_type (record
, build_index_type (size_zero_node
));
6539 /* Implement va_start by filling the va_list structure VALIST.
6540 STDARG_P is always true, and ignored.
6541 NEXTARG points to the first anonymous stack argument.
6543 The following global variables are used to initialize
6544 the va_list structure:
6546 current_function_args_info:
6547 holds number of gprs and fprs used for named arguments.
6548 current_function_arg_offset_rtx:
6549 holds the offset of the first anonymous stack argument
6550 (relative to the virtual arg pointer). */
6553 s390_va_start (tree valist
, rtx nextarg ATTRIBUTE_UNUSED
)
6555 HOST_WIDE_INT n_gpr
, n_fpr
;
6557 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
6558 tree gpr
, fpr
, ovf
, sav
, t
;
6560 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
6561 f_fpr
= TREE_CHAIN (f_gpr
);
6562 f_ovf
= TREE_CHAIN (f_fpr
);
6563 f_sav
= TREE_CHAIN (f_ovf
);
6565 valist
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (valist
)), valist
);
6566 gpr
= build (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
6567 fpr
= build (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
6568 ovf
= build (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
6569 sav
= build (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
6571 /* Count number of gp and fp argument registers used. */
6573 n_gpr
= current_function_args_info
.gprs
;
6574 n_fpr
= current_function_args_info
.fprs
;
6576 t
= build (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
, build_int_2 (n_gpr
, 0));
6577 TREE_SIDE_EFFECTS (t
) = 1;
6578 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6580 t
= build (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
, build_int_2 (n_fpr
, 0));
6581 TREE_SIDE_EFFECTS (t
) = 1;
6582 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6584 /* Find the overflow area. */
6585 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
6587 off
= INTVAL (current_function_arg_offset_rtx
);
6588 off
= off
< 0 ? 0 : off
;
6589 if (TARGET_DEBUG_ARG
)
6590 fprintf (stderr
, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
6591 (int)n_gpr
, (int)n_fpr
, off
);
6593 t
= build (PLUS_EXPR
, TREE_TYPE (ovf
), t
, build_int_2 (off
, 0));
6595 t
= build (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
6596 TREE_SIDE_EFFECTS (t
) = 1;
6597 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6599 /* Find the register save area. */
6600 t
= make_tree (TREE_TYPE (sav
), virtual_incoming_args_rtx
);
6601 t
= build (PLUS_EXPR
, TREE_TYPE (sav
), t
,
6602 build_int_2 (-STACK_POINTER_OFFSET
, -1));
6603 t
= build (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
6604 TREE_SIDE_EFFECTS (t
) = 1;
6605 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6608 /* Implement va_arg by updating the va_list structure
6609 VALIST as required to retrieve an argument of type
6610 TYPE, and returning that argument.
6612 Generates code equivalent to:
6614 if (integral value) {
6615 if (size <= 4 && args.gpr < 5 ||
6616 size > 4 && args.gpr < 4 )
6617 ret = args.reg_save_area[args.gpr+8]
6619 ret = *args.overflow_arg_area++;
6620 } else if (float value) {
6622 ret = args.reg_save_area[args.fpr+64]
6624 ret = *args.overflow_arg_area++;
6625 } else if (aggregate value) {
6627 ret = *args.reg_save_area[args.gpr]
6629 ret = **args.overflow_arg_area++;
6633 s390_gimplify_va_arg (tree valist
, tree type
, tree
*pre_p
,
6634 tree
*post_p ATTRIBUTE_UNUSED
)
6636 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
6637 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
6638 int indirect_p
, size
, n_reg
, sav_ofs
, sav_scale
, max_reg
;
6639 tree lab_false
, lab_over
, addr
;
6641 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
6642 f_fpr
= TREE_CHAIN (f_gpr
);
6643 f_ovf
= TREE_CHAIN (f_fpr
);
6644 f_sav
= TREE_CHAIN (f_ovf
);
6646 valist
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (valist
)), valist
);
6647 gpr
= build (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
6648 fpr
= build (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
6649 ovf
= build (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
6650 sav
= build (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
6652 size
= int_size_in_bytes (type
);
6654 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
6656 if (TARGET_DEBUG_ARG
)
6658 fprintf (stderr
, "va_arg: aggregate type");
6662 /* Aggregates are passed by reference. */
6666 sav_ofs
= 2 * UNITS_PER_WORD
;
6667 sav_scale
= UNITS_PER_WORD
;
6668 size
= UNITS_PER_WORD
;
6671 else if (s390_function_arg_float (TYPE_MODE (type
), type
))
6673 if (TARGET_DEBUG_ARG
)
6675 fprintf (stderr
, "va_arg: float type");
6679 /* FP args go in FP registers, if present. */
6683 sav_ofs
= 16 * UNITS_PER_WORD
;
6685 /* TARGET_64BIT has up to 4 parameter in fprs */
6686 max_reg
= TARGET_64BIT
? 3 : 1;
6690 if (TARGET_DEBUG_ARG
)
6692 fprintf (stderr
, "va_arg: other type");
6696 /* Otherwise into GP registers. */
6699 n_reg
= (size
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
6700 sav_ofs
= 2 * UNITS_PER_WORD
;
6702 if (size
< UNITS_PER_WORD
)
6703 sav_ofs
+= UNITS_PER_WORD
- size
;
6705 sav_scale
= UNITS_PER_WORD
;
6712 /* Pull the value out of the saved registers ... */
6714 lab_false
= create_artificial_label ();
6715 lab_over
= create_artificial_label ();
6716 addr
= create_tmp_var (ptr_type_node
, "addr");
6718 t
= fold_convert (TREE_TYPE (reg
), size_int (max_reg
));
6719 t
= build2 (GT_EXPR
, boolean_type_node
, reg
, t
);
6720 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
6721 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
6722 gimplify_and_add (t
, pre_p
);
6724 t
= build2 (PLUS_EXPR
, ptr_type_node
, sav
,
6725 fold_convert (ptr_type_node
, size_int (sav_ofs
)));
6726 u
= build2 (MULT_EXPR
, TREE_TYPE (reg
), reg
,
6727 fold_convert (TREE_TYPE (reg
), size_int (sav_scale
)));
6728 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
, fold_convert (ptr_type_node
, u
));
6730 t
= build2 (MODIFY_EXPR
, void_type_node
, addr
, t
);
6731 gimplify_and_add (t
, pre_p
);
6733 t
= build1 (GOTO_EXPR
, void_type_node
, lab_over
);
6734 gimplify_and_add (t
, pre_p
);
6736 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false
);
6737 append_to_statement_list (t
, pre_p
);
6740 /* ... Otherwise out of the overflow area. */
6743 if (size
< UNITS_PER_WORD
)
6744 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
,
6745 fold_convert (ptr_type_node
, size_int (UNITS_PER_WORD
- size
)));
6747 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
6749 u
= build2 (MODIFY_EXPR
, void_type_node
, addr
, t
);
6750 gimplify_and_add (u
, pre_p
);
6752 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
,
6753 fold_convert (ptr_type_node
, size_int (size
)));
6754 t
= build2 (MODIFY_EXPR
, ptr_type_node
, ovf
, t
);
6755 gimplify_and_add (t
, pre_p
);
6757 t
= build1 (LABEL_EXPR
, void_type_node
, lab_over
);
6758 append_to_statement_list (t
, pre_p
);
6761 /* Increment register save count. */
6763 u
= build2 (PREINCREMENT_EXPR
, TREE_TYPE (reg
), reg
,
6764 fold_convert (TREE_TYPE (reg
), size_int (n_reg
)));
6765 gimplify_and_add (u
, pre_p
);
6769 t
= build_pointer_type (build_pointer_type (type
));
6770 addr
= fold_convert (t
, addr
);
6771 addr
= build_fold_indirect_ref (addr
);
6775 t
= build_pointer_type (type
);
6776 addr
= fold_convert (t
, addr
);
6779 return build_fold_indirect_ref (addr
);
6787 S390_BUILTIN_THREAD_POINTER
,
6788 S390_BUILTIN_SET_THREAD_POINTER
,
6793 static unsigned int const code_for_builtin_64
[S390_BUILTIN_max
] = {
6798 static unsigned int const code_for_builtin_31
[S390_BUILTIN_max
] = {
6804 s390_init_builtins (void)
6808 ftype
= build_function_type (ptr_type_node
, void_list_node
);
6809 builtin_function ("__builtin_thread_pointer", ftype
,
6810 S390_BUILTIN_THREAD_POINTER
, BUILT_IN_MD
,
6813 ftype
= build_function_type_list (void_type_node
, ptr_type_node
, NULL_TREE
);
6814 builtin_function ("__builtin_set_thread_pointer", ftype
,
6815 S390_BUILTIN_SET_THREAD_POINTER
, BUILT_IN_MD
,
6819 /* Expand an expression EXP that calls a built-in function,
6820 with result going to TARGET if that's convenient
6821 (and in mode MODE if that's convenient).
6822 SUBTARGET may be used as the target for computing one of EXP's operands.
6823 IGNORE is nonzero if the value is to be ignored. */
6826 s390_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
6827 enum machine_mode mode ATTRIBUTE_UNUSED
,
6828 int ignore ATTRIBUTE_UNUSED
)
6832 unsigned int const *code_for_builtin
=
6833 TARGET_64BIT
? code_for_builtin_64
: code_for_builtin_31
;
6835 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
6836 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
6837 tree arglist
= TREE_OPERAND (exp
, 1);
6838 enum insn_code icode
;
6839 rtx op
[MAX_ARGS
], pat
;
6843 if (fcode
>= S390_BUILTIN_max
)
6844 internal_error ("bad builtin fcode");
6845 icode
= code_for_builtin
[fcode
];
6847 internal_error ("bad builtin fcode");
6849 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
6851 for (arglist
= TREE_OPERAND (exp
, 1), arity
= 0;
6853 arglist
= TREE_CHAIN (arglist
), arity
++)
6855 const struct insn_operand_data
*insn_op
;
6857 tree arg
= TREE_VALUE (arglist
);
6858 if (arg
== error_mark_node
)
6860 if (arity
> MAX_ARGS
)
6863 insn_op
= &insn_data
[icode
].operand
[arity
+ nonvoid
];
6865 op
[arity
] = expand_expr (arg
, NULL_RTX
, insn_op
->mode
, 0);
6867 if (!(*insn_op
->predicate
) (op
[arity
], insn_op
->mode
))
6868 op
[arity
] = copy_to_mode_reg (insn_op
->mode
, op
[arity
]);
6873 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6875 || GET_MODE (target
) != tmode
6876 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6877 target
= gen_reg_rtx (tmode
);
6883 pat
= GEN_FCN (icode
) (target
);
6887 pat
= GEN_FCN (icode
) (target
, op
[0]);
6889 pat
= GEN_FCN (icode
) (op
[0]);
6892 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
6908 /* Output assembly code for the trampoline template to
6911 On S/390, we use gpr 1 internally in the trampoline code;
6912 gpr 0 is used to hold the static chain. */
6915 s390_trampoline_template (FILE *file
)
6919 fprintf (file
, "larl\t%s,0f\n", reg_names
[1]);
6920 fprintf (file
, "lg\t%s,0(%s)\n", reg_names
[0], reg_names
[1]);
6921 fprintf (file
, "lg\t%s,8(%s)\n", reg_names
[1], reg_names
[1]);
6922 fprintf (file
, "br\t%s\n", reg_names
[1]);
6923 fprintf (file
, "0:\t.quad\t0\n");
6924 fprintf (file
, ".quad\t0\n");
6928 fprintf (file
, "basr\t%s,0\n", reg_names
[1]);
6929 fprintf (file
, "l\t%s,10(%s)\n", reg_names
[0], reg_names
[1]);
6930 fprintf (file
, "l\t%s,14(%s)\n", reg_names
[1], reg_names
[1]);
6931 fprintf (file
, "br\t%s\n", reg_names
[1]);
6932 fprintf (file
, ".long\t0\n");
6933 fprintf (file
, ".long\t0\n");
6937 /* Emit RTL insns to initialize the variable parts of a trampoline.
6938 FNADDR is an RTX for the address of the function's pure code.
6939 CXT is an RTX for the static chain value for the function. */
6942 s390_initialize_trampoline (rtx addr
, rtx fnaddr
, rtx cxt
)
6944 emit_move_insn (gen_rtx_MEM (Pmode
,
6945 memory_address (Pmode
,
6946 plus_constant (addr
, (TARGET_64BIT
? 20 : 12) ))), cxt
);
6947 emit_move_insn (gen_rtx_MEM (Pmode
,
6948 memory_address (Pmode
,
6949 plus_constant (addr
, (TARGET_64BIT
? 28 : 16) ))), fnaddr
);
6952 /* Return rtx for 64-bit constant formed from the 32-bit subwords
6953 LOW and HIGH, independent of the host word size. */
6956 s390_gen_rtx_const_DI (int high
, int low
)
6958 #if HOST_BITS_PER_WIDE_INT >= 64
6960 val
= (HOST_WIDE_INT
)high
;
6962 val
|= (HOST_WIDE_INT
)low
;
6964 return GEN_INT (val
);
6966 #if HOST_BITS_PER_WIDE_INT >= 32
6967 return immed_double_const ((HOST_WIDE_INT
)low
, (HOST_WIDE_INT
)high
, DImode
);
6974 /* Output assembler code to FILE to increment profiler label # LABELNO
6975 for profiling a function entry. */
6978 s390_function_profiler (FILE *file
, int labelno
)
6983 ASM_GENERATE_INTERNAL_LABEL (label
, "LP", labelno
);
6985 fprintf (file
, "# function profiler \n");
6987 op
[0] = gen_rtx_REG (Pmode
, RETURN_REGNUM
);
6988 op
[1] = gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
6989 op
[1] = gen_rtx_MEM (Pmode
, plus_constant (op
[1], UNITS_PER_WORD
));
6991 op
[2] = gen_rtx_REG (Pmode
, 1);
6992 op
[3] = gen_rtx_SYMBOL_REF (Pmode
, label
);
6993 SYMBOL_REF_FLAGS (op
[3]) = SYMBOL_FLAG_LOCAL
;
6995 op
[4] = gen_rtx_SYMBOL_REF (Pmode
, "_mcount");
6998 op
[4] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[4]), UNSPEC_PLT
);
6999 op
[4] = gen_rtx_CONST (Pmode
, op
[4]);
7004 output_asm_insn ("stg\t%0,%1", op
);
7005 output_asm_insn ("larl\t%2,%3", op
);
7006 output_asm_insn ("brasl\t%0,%4", op
);
7007 output_asm_insn ("lg\t%0,%1", op
);
7011 op
[6] = gen_label_rtx ();
7013 output_asm_insn ("st\t%0,%1", op
);
7014 output_asm_insn ("bras\t%2,%l6", op
);
7015 output_asm_insn (".long\t%4", op
);
7016 output_asm_insn (".long\t%3", op
);
7017 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
7018 output_asm_insn ("l\t%0,0(%2)", op
);
7019 output_asm_insn ("l\t%2,4(%2)", op
);
7020 output_asm_insn ("basr\t%0,%0", op
);
7021 output_asm_insn ("l\t%0,%1", op
);
7025 op
[5] = gen_label_rtx ();
7026 op
[6] = gen_label_rtx ();
7028 output_asm_insn ("st\t%0,%1", op
);
7029 output_asm_insn ("bras\t%2,%l6", op
);
7030 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[5]));
7031 output_asm_insn (".long\t%4-%l5", op
);
7032 output_asm_insn (".long\t%3-%l5", op
);
7033 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
7034 output_asm_insn ("lr\t%0,%2", op
);
7035 output_asm_insn ("a\t%0,0(%2)", op
);
7036 output_asm_insn ("a\t%2,4(%2)", op
);
7037 output_asm_insn ("basr\t%0,%0", op
);
7038 output_asm_insn ("l\t%0,%1", op
);
7042 /* Select section for constant in constant pool. In 32-bit mode,
7043 constants go in the function section; in 64-bit mode in .rodata. */
7046 s390_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED
,
7047 rtx x ATTRIBUTE_UNUSED
,
7048 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
7050 if (TARGET_CPU_ZARCH
)
7051 readonly_data_section ();
7053 function_section (current_function_decl
);
7056 /* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
7057 into its SYMBOL_REF_FLAGS. */
7060 s390_encode_section_info (tree decl
, rtx rtl
, int first
)
7062 default_encode_section_info (decl
, rtl
, first
);
7064 /* If a variable has a forced alignment to < 2 bytes, mark it with
7065 SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL operand. */
7066 if (TREE_CODE (decl
) == VAR_DECL
7067 && DECL_USER_ALIGN (decl
) && DECL_ALIGN (decl
) < 16)
7068 SYMBOL_REF_FLAGS (XEXP (rtl
, 0)) |= SYMBOL_FLAG_ALIGN1
;
7071 /* Output thunk to FILE that implements a C++ virtual function call (with
7072 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
7073 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
7074 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
7075 relative to the resulting this pointer. */
7078 s390_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
7079 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
7085 /* Operand 0 is the target function. */
7086 op
[0] = XEXP (DECL_RTL (function
), 0);
7087 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (op
[0]))
7090 op
[0] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[0]),
7091 TARGET_64BIT
? UNSPEC_PLT
: UNSPEC_GOT
);
7092 op
[0] = gen_rtx_CONST (Pmode
, op
[0]);
7095 /* Operand 1 is the 'this' pointer. */
7096 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
7097 op
[1] = gen_rtx_REG (Pmode
, 3);
7099 op
[1] = gen_rtx_REG (Pmode
, 2);
7101 /* Operand 2 is the delta. */
7102 op
[2] = GEN_INT (delta
);
7104 /* Operand 3 is the vcall_offset. */
7105 op
[3] = GEN_INT (vcall_offset
);
7107 /* Operand 4 is the temporary register. */
7108 op
[4] = gen_rtx_REG (Pmode
, 1);
7110 /* Operands 5 to 8 can be used as labels. */
7116 /* Operand 9 can be used for temporary register. */
7119 /* Generate code. */
7122 /* Setup literal pool pointer if required. */
7123 if ((!DISP_IN_RANGE (delta
)
7124 && !CONST_OK_FOR_CONSTRAINT_P (delta
, 'K', "K"))
7125 || (!DISP_IN_RANGE (vcall_offset
)
7126 && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'K', "K")))
7128 op
[5] = gen_label_rtx ();
7129 output_asm_insn ("larl\t%4,%5", op
);
7132 /* Add DELTA to this pointer. */
7135 if (CONST_OK_FOR_CONSTRAINT_P (delta
, 'J', "J"))
7136 output_asm_insn ("la\t%1,%2(%1)", op
);
7137 else if (DISP_IN_RANGE (delta
))
7138 output_asm_insn ("lay\t%1,%2(%1)", op
);
7139 else if (CONST_OK_FOR_CONSTRAINT_P (delta
, 'K', "K"))
7140 output_asm_insn ("aghi\t%1,%2", op
);
7143 op
[6] = gen_label_rtx ();
7144 output_asm_insn ("agf\t%1,%6-%5(%4)", op
);
7148 /* Perform vcall adjustment. */
7151 if (DISP_IN_RANGE (vcall_offset
))
7153 output_asm_insn ("lg\t%4,0(%1)", op
);
7154 output_asm_insn ("ag\t%1,%3(%4)", op
);
7156 else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'K', "K"))
7158 output_asm_insn ("lghi\t%4,%3", op
);
7159 output_asm_insn ("ag\t%4,0(%1)", op
);
7160 output_asm_insn ("ag\t%1,0(%4)", op
);
7164 op
[7] = gen_label_rtx ();
7165 output_asm_insn ("llgf\t%4,%7-%5(%4)", op
);
7166 output_asm_insn ("ag\t%4,0(%1)", op
);
7167 output_asm_insn ("ag\t%1,0(%4)", op
);
7171 /* Jump to target. */
7172 output_asm_insn ("jg\t%0", op
);
7174 /* Output literal pool if required. */
7177 output_asm_insn (".align\t4", op
);
7178 targetm
.asm_out
.internal_label (file
, "L",
7179 CODE_LABEL_NUMBER (op
[5]));
7183 targetm
.asm_out
.internal_label (file
, "L",
7184 CODE_LABEL_NUMBER (op
[6]));
7185 output_asm_insn (".long\t%2", op
);
7189 targetm
.asm_out
.internal_label (file
, "L",
7190 CODE_LABEL_NUMBER (op
[7]));
7191 output_asm_insn (".long\t%3", op
);
7196 /* Setup base pointer if required. */
7198 || (!DISP_IN_RANGE (delta
)
7199 && !CONST_OK_FOR_CONSTRAINT_P (delta
, 'K', "K"))
7200 || (!DISP_IN_RANGE (delta
)
7201 && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'K', "K")))
7203 op
[5] = gen_label_rtx ();
7204 output_asm_insn ("basr\t%4,0", op
);
7205 targetm
.asm_out
.internal_label (file
, "L",
7206 CODE_LABEL_NUMBER (op
[5]));
7209 /* Add DELTA to this pointer. */
7212 if (CONST_OK_FOR_CONSTRAINT_P (delta
, 'J', "J"))
7213 output_asm_insn ("la\t%1,%2(%1)", op
);
7214 else if (DISP_IN_RANGE (delta
))
7215 output_asm_insn ("lay\t%1,%2(%1)", op
);
7216 else if (CONST_OK_FOR_CONSTRAINT_P (delta
, 'K', "K"))
7217 output_asm_insn ("ahi\t%1,%2", op
);
7220 op
[6] = gen_label_rtx ();
7221 output_asm_insn ("a\t%1,%6-%5(%4)", op
);
7225 /* Perform vcall adjustment. */
7228 if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'J', "J"))
7230 output_asm_insn ("lg\t%4,0(%1)", op
);
7231 output_asm_insn ("a\t%1,%3(%4)", op
);
7233 else if (DISP_IN_RANGE (vcall_offset
))
7235 output_asm_insn ("lg\t%4,0(%1)", op
);
7236 output_asm_insn ("ay\t%1,%3(%4)", op
);
7238 else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'K', "K"))
7240 output_asm_insn ("lhi\t%4,%3", op
);
7241 output_asm_insn ("a\t%4,0(%1)", op
);
7242 output_asm_insn ("a\t%1,0(%4)", op
);
7246 op
[7] = gen_label_rtx ();
7247 output_asm_insn ("l\t%4,%7-%5(%4)", op
);
7248 output_asm_insn ("a\t%4,0(%1)", op
);
7249 output_asm_insn ("a\t%1,0(%4)", op
);
7252 /* We had to clobber the base pointer register.
7253 Re-setup the base pointer (with a different base). */
7254 op
[5] = gen_label_rtx ();
7255 output_asm_insn ("basr\t%4,0", op
);
7256 targetm
.asm_out
.internal_label (file
, "L",
7257 CODE_LABEL_NUMBER (op
[5]));
7260 /* Jump to target. */
7261 op
[8] = gen_label_rtx ();
7264 output_asm_insn ("l\t%4,%8-%5(%4)", op
);
7266 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
7267 /* We cannot call through .plt, since .plt requires %r12 loaded. */
7268 else if (flag_pic
== 1)
7270 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
7271 output_asm_insn ("l\t%4,%0(%4)", op
);
7273 else if (flag_pic
== 2)
7275 op
[9] = gen_rtx_REG (Pmode
, 0);
7276 output_asm_insn ("l\t%9,%8-4-%5(%4)", op
);
7277 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
7278 output_asm_insn ("ar\t%4,%9", op
);
7279 output_asm_insn ("l\t%4,0(%4)", op
);
7282 output_asm_insn ("br\t%4", op
);
7284 /* Output literal pool. */
7285 output_asm_insn (".align\t4", op
);
7287 if (nonlocal
&& flag_pic
== 2)
7288 output_asm_insn (".long\t%0", op
);
7291 op
[0] = gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
7292 SYMBOL_REF_FLAGS (op
[0]) = SYMBOL_FLAG_LOCAL
;
7295 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[8]));
7297 output_asm_insn (".long\t%0", op
);
7299 output_asm_insn (".long\t%0-%5", op
);
7303 targetm
.asm_out
.internal_label (file
, "L",
7304 CODE_LABEL_NUMBER (op
[6]));
7305 output_asm_insn (".long\t%2", op
);
7309 targetm
.asm_out
.internal_label (file
, "L",
7310 CODE_LABEL_NUMBER (op
[7]));
7311 output_asm_insn (".long\t%3", op
);
7317 s390_valid_pointer_mode (enum machine_mode mode
)
7319 return (mode
== SImode
|| (TARGET_64BIT
&& mode
== DImode
));
7322 /* How to allocate a 'struct machine_function'. */
7324 static struct machine_function
*
7325 s390_init_machine_status (void)
7327 return ggc_alloc_cleared (sizeof (struct machine_function
));
7330 /* Checks whether the given ARGUMENT_LIST would use a caller
7331 saved register. This is used to decide whether sibling call
7332 optimization could be performed on the respective function
7336 s390_call_saved_register_used (tree argument_list
)
7338 CUMULATIVE_ARGS cum
;
7340 enum machine_mode mode
;
7345 INIT_CUMULATIVE_ARGS (cum
, NULL
, NULL
, 0, 0);
7347 while (argument_list
)
7349 parameter
= TREE_VALUE (argument_list
);
7350 argument_list
= TREE_CHAIN (argument_list
);
7355 /* For an undeclared variable passed as parameter we will get
7356 an ERROR_MARK node here. */
7357 if (TREE_CODE (parameter
) == ERROR_MARK
)
7360 if (! (type
= TREE_TYPE (parameter
)))
7363 if (! (mode
= TYPE_MODE (TREE_TYPE (parameter
))))
7366 if (pass_by_reference (&cum
, mode
, type
, true))
7369 type
= build_pointer_type (type
);
7372 parm_rtx
= s390_function_arg (&cum
, mode
, type
, 0);
7374 s390_function_arg_advance (&cum
, mode
, type
, 0);
7376 if (parm_rtx
&& REG_P (parm_rtx
))
7379 reg
< HARD_REGNO_NREGS (REGNO (parm_rtx
), GET_MODE (parm_rtx
));
7381 if (! call_used_regs
[reg
+ REGNO (parm_rtx
)])
7388 /* Return true if the given call expression can be
7389 turned into a sibling call.
7390 DECL holds the declaration of the function to be called whereas
7391 EXP is the call expression itself. */
7394 s390_function_ok_for_sibcall (tree decl
, tree exp
)
7396 /* The TPF epilogue uses register 1. */
7397 if (TARGET_TPF_PROFILING
)
7400 /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
7401 which would have to be restored before the sibcall. */
7402 if (!TARGET_64BIT
&& flag_pic
&& decl
&& TREE_PUBLIC (decl
))
7405 /* Register 6 on s390 is available as an argument register but unfortunately
7406 "caller saved". This makes functions needing this register for arguments
7407 not suitable for sibcalls. */
7408 if (TREE_OPERAND (exp
, 1)
7409 && s390_call_saved_register_used (TREE_OPERAND (exp
, 1)))
7415 /* This function is used by the call expanders of the machine description.
7416 It emits the call insn itself together with the necessary operations
7417 to adjust the target address and returns the emitted insn.
7418 ADDR_LOCATION is the target address rtx
7419 TLS_CALL the location of the thread-local symbol
7420 RESULT_REG the register where the result of the call should be stored
7421 RETADDR_REG the register where the return address should be stored
7422 If this parameter is NULL_RTX the call is considered
7423 to be a sibling call. */
7426 s390_emit_call (rtx addr_location
, rtx tls_call
, rtx result_reg
,
7429 bool plt_call
= false;
7435 /* Direct function calls need special treatment. */
7436 if (GET_CODE (addr_location
) == SYMBOL_REF
)
7438 /* When calling a global routine in PIC mode, we must
7439 replace the symbol itself with the PLT stub. */
7440 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (addr_location
))
7442 addr_location
= gen_rtx_UNSPEC (Pmode
,
7443 gen_rtvec (1, addr_location
),
7445 addr_location
= gen_rtx_CONST (Pmode
, addr_location
);
7449 /* Unless we can use the bras(l) insn, force the
7450 routine address into a register. */
7451 if (!TARGET_SMALL_EXEC
&& !TARGET_CPU_ZARCH
)
7454 addr_location
= legitimize_pic_address (addr_location
, 0);
7456 addr_location
= force_reg (Pmode
, addr_location
);
7460 /* If it is already an indirect call or the code above moved the
7461 SYMBOL_REF to somewhere else make sure the address can be found in
7463 if (retaddr_reg
== NULL_RTX
7464 && GET_CODE (addr_location
) != SYMBOL_REF
7467 emit_move_insn (gen_rtx_REG (Pmode
, SIBCALL_REGNUM
), addr_location
);
7468 addr_location
= gen_rtx_REG (Pmode
, SIBCALL_REGNUM
);
7471 addr_location
= gen_rtx_MEM (QImode
, addr_location
);
7472 call
= gen_rtx_CALL (VOIDmode
, addr_location
, const0_rtx
);
7474 if (result_reg
!= NULL_RTX
)
7475 call
= gen_rtx_SET (VOIDmode
, result_reg
, call
);
7477 if (retaddr_reg
!= NULL_RTX
)
7479 clobber
= gen_rtx_CLOBBER (VOIDmode
, retaddr_reg
);
7481 if (tls_call
!= NULL_RTX
)
7482 vec
= gen_rtvec (3, call
, clobber
,
7483 gen_rtx_USE (VOIDmode
, tls_call
));
7485 vec
= gen_rtvec (2, call
, clobber
);
7487 call
= gen_rtx_PARALLEL (VOIDmode
, vec
);
7490 insn
= emit_call_insn (call
);
7492 /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
7493 if ((!TARGET_64BIT
&& plt_call
) || tls_call
!= NULL_RTX
)
7495 /* s390_function_ok_for_sibcall should
7496 have denied sibcalls in this case. */
7497 if (retaddr_reg
== NULL_RTX
)
7500 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), pic_offset_table_rtx
);
7505 /* Implement CONDITIONAL_REGISTER_USAGE. */
7508 s390_conditional_register_usage (void)
7514 fixed_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
7515 call_used_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
7517 if (TARGET_CPU_ZARCH
)
7519 fixed_regs
[RETURN_REGNUM
] = 0;
7520 call_used_regs
[RETURN_REGNUM
] = 0;
7524 for (i
= 24; i
< 32; i
++)
7525 call_used_regs
[i
] = call_really_used_regs
[i
] = 0;
7529 for (i
= 18; i
< 20; i
++)
7530 call_used_regs
[i
] = call_really_used_regs
[i
] = 0;
7535 #include "gt-s390.h"