1 /* Subroutines used for code generation on IBM S/390 and zSeries
2 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
3 Free Software Foundation, Inc.
4 Contributed by Hartmut Penner (hpenner@de.ibm.com) and
5 Ulrich Weigand (uweigand@de.ibm.com).
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to the Free
21 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26 #include "coretypes.h"
32 #include "hard-reg-set.h"
34 #include "insn-config.h"
35 #include "conditions.h"
37 #include "insn-attr.h"
45 #include "basic-block.h"
46 #include "integrate.h"
49 #include "target-def.h"
51 #include "langhooks.h"
53 #include "tree-gimple.h"
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_encode_section_info (tree
, rtx
, int);
61 static bool s390_cannot_force_const_mem (rtx
);
62 static rtx
s390_delegitimize_address (rtx
);
63 static bool s390_return_in_memory (tree
, tree
);
64 static void s390_init_builtins (void);
65 static rtx
s390_expand_builtin (tree
, rtx
, rtx
, enum machine_mode
, int);
66 static void s390_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
,
68 static enum attr_type
s390_safe_attr_type (rtx
);
70 static int s390_adjust_priority (rtx
, int);
71 static int s390_issue_rate (void);
72 static int s390_first_cycle_multipass_dfa_lookahead (void);
73 static bool s390_cannot_copy_insn_p (rtx
);
74 static bool s390_rtx_costs (rtx
, int, int, int *);
75 static int s390_address_cost (rtx
);
76 static void s390_reorg (void);
77 static bool s390_valid_pointer_mode (enum machine_mode
);
78 static tree
s390_build_builtin_va_list (void);
79 static tree
s390_gimplify_va_arg (tree
, tree
, tree
*, tree
*);
80 static bool s390_function_ok_for_sibcall (tree
, tree
);
81 static bool s390_call_saved_register_used (tree
);
82 static bool s390_pass_by_reference (CUMULATIVE_ARGS
*, enum machine_mode mode
,
84 static bool s390_fixed_condition_code_regs (unsigned int *, unsigned int *);
85 static enum machine_mode
s390_cc_modes_compatible (enum machine_mode
,
89 /* Define the specific costs for a given cpu. */
91 struct processor_costs
94 const int m
; /* cost of an M instruction. */
95 const int mghi
; /* cost of an MGHI instruction. */
96 const int mh
; /* cost of an MH instruction. */
97 const int mhi
; /* cost of an MHI instruction. */
98 const int ml
; /* cost of an ML instruction. */
99 const int mr
; /* cost of an MR instruction. */
100 const int ms
; /* cost of an MS instruction. */
101 const int msg
; /* cost of an MSG instruction. */
102 const int msgf
; /* cost of an MSGF instruction. */
103 const int msgfr
; /* cost of an MSGFR instruction. */
104 const int msgr
; /* cost of an MSGR instruction. */
105 const int msr
; /* cost of an MSR instruction. */
106 const int mult_df
; /* cost of multiplication in DFmode. */
108 const int sqdbr
; /* cost of square root in DFmode. */
109 const int sqebr
; /* cost of square root in SFmode. */
110 /* multiply and add */
111 const int madbr
; /* cost of multiply and add in DFmode. */
112 const int maebr
; /* cost of multiply and add in SFmode. */
125 const struct processor_costs
*s390_cost
;
128 struct processor_costs z900_cost
=
130 COSTS_N_INSNS (5), /* M */
131 COSTS_N_INSNS (10), /* MGHI */
132 COSTS_N_INSNS (5), /* MH */
133 COSTS_N_INSNS (4), /* MHI */
134 COSTS_N_INSNS (5), /* ML */
135 COSTS_N_INSNS (5), /* MR */
136 COSTS_N_INSNS (4), /* MS */
137 COSTS_N_INSNS (15), /* MSG */
138 COSTS_N_INSNS (7), /* MSGF */
139 COSTS_N_INSNS (7), /* MSGFR */
140 COSTS_N_INSNS (10), /* MSGR */
141 COSTS_N_INSNS (4), /* MSR */
142 COSTS_N_INSNS (7), /* multiplication in DFmode */
143 COSTS_N_INSNS (44), /* SQDBR */
144 COSTS_N_INSNS (35), /* SQEBR */
145 COSTS_N_INSNS (18), /* MADBR */
146 COSTS_N_INSNS (13), /* MAEBR */
147 COSTS_N_INSNS (30), /* DDBR */
148 COSTS_N_INSNS (30), /* DDR */
149 COSTS_N_INSNS (27), /* DEBR */
150 COSTS_N_INSNS (26), /* DER */
151 COSTS_N_INSNS (220), /* DLGR */
152 COSTS_N_INSNS (34), /* DLR */
153 COSTS_N_INSNS (34), /* DR */
154 COSTS_N_INSNS (32), /* DSGFR */
155 COSTS_N_INSNS (32), /* DSGR */
159 struct processor_costs z990_cost
=
161 COSTS_N_INSNS (4), /* M */
162 COSTS_N_INSNS (2), /* MGHI */
163 COSTS_N_INSNS (2), /* MH */
164 COSTS_N_INSNS (2), /* MHI */
165 COSTS_N_INSNS (4), /* ML */
166 COSTS_N_INSNS (4), /* MR */
167 COSTS_N_INSNS (5), /* MS */
168 COSTS_N_INSNS (6), /* MSG */
169 COSTS_N_INSNS (4), /* MSGF */
170 COSTS_N_INSNS (4), /* MSGFR */
171 COSTS_N_INSNS (4), /* MSGR */
172 COSTS_N_INSNS (4), /* MSR */
173 COSTS_N_INSNS (1), /* multiplication in DFmode */
174 COSTS_N_INSNS (66), /* SQDBR */
175 COSTS_N_INSNS (38), /* SQEBR */
176 COSTS_N_INSNS (1), /* MADBR */
177 COSTS_N_INSNS (1), /* MAEBR */
178 COSTS_N_INSNS (40), /* DDBR */
179 COSTS_N_INSNS (44), /* DDR */
180 COSTS_N_INSNS (26), /* DDBR */
181 COSTS_N_INSNS (28), /* DER */
182 COSTS_N_INSNS (176), /* DLGR */
183 COSTS_N_INSNS (31), /* DLR */
184 COSTS_N_INSNS (31), /* DR */
185 COSTS_N_INSNS (31), /* DSGFR */
186 COSTS_N_INSNS (31), /* DSGR */
190 #undef TARGET_ASM_ALIGNED_HI_OP
191 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
192 #undef TARGET_ASM_ALIGNED_DI_OP
193 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
194 #undef TARGET_ASM_INTEGER
195 #define TARGET_ASM_INTEGER s390_assemble_integer
197 #undef TARGET_ASM_OPEN_PAREN
198 #define TARGET_ASM_OPEN_PAREN ""
200 #undef TARGET_ASM_CLOSE_PAREN
201 #define TARGET_ASM_CLOSE_PAREN ""
203 #undef TARGET_ENCODE_SECTION_INFO
204 #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
207 #undef TARGET_HAVE_TLS
208 #define TARGET_HAVE_TLS true
210 #undef TARGET_CANNOT_FORCE_CONST_MEM
211 #define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
213 #undef TARGET_DELEGITIMIZE_ADDRESS
214 #define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
216 #undef TARGET_RETURN_IN_MEMORY
217 #define TARGET_RETURN_IN_MEMORY s390_return_in_memory
219 #undef TARGET_INIT_BUILTINS
220 #define TARGET_INIT_BUILTINS s390_init_builtins
221 #undef TARGET_EXPAND_BUILTIN
222 #define TARGET_EXPAND_BUILTIN s390_expand_builtin
224 #undef TARGET_ASM_OUTPUT_MI_THUNK
225 #define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
226 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
227 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
229 #undef TARGET_SCHED_ADJUST_PRIORITY
230 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
231 #undef TARGET_SCHED_ISSUE_RATE
232 #define TARGET_SCHED_ISSUE_RATE s390_issue_rate
233 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
234 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
236 #undef TARGET_CANNOT_COPY_INSN_P
237 #define TARGET_CANNOT_COPY_INSN_P s390_cannot_copy_insn_p
238 #undef TARGET_RTX_COSTS
239 #define TARGET_RTX_COSTS s390_rtx_costs
240 #undef TARGET_ADDRESS_COST
241 #define TARGET_ADDRESS_COST s390_address_cost
243 #undef TARGET_MACHINE_DEPENDENT_REORG
244 #define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
246 #undef TARGET_VALID_POINTER_MODE
247 #define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
249 #undef TARGET_BUILD_BUILTIN_VA_LIST
250 #define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
251 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
252 #define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg
254 #undef TARGET_PROMOTE_FUNCTION_ARGS
255 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
256 #undef TARGET_PROMOTE_FUNCTION_RETURN
257 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
258 #undef TARGET_PASS_BY_REFERENCE
259 #define TARGET_PASS_BY_REFERENCE s390_pass_by_reference
261 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
262 #define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
264 #undef TARGET_FIXED_CONDITION_CODE_REGS
265 #define TARGET_FIXED_CONDITION_CODE_REGS s390_fixed_condition_code_regs
267 #undef TARGET_CC_MODES_COMPATIBLE
268 #define TARGET_CC_MODES_COMPATIBLE s390_cc_modes_compatible
270 struct gcc_target targetm
= TARGET_INITIALIZER
;
272 extern int reload_completed
;
274 /* The alias set for prologue/epilogue register save/restore. */
275 static int s390_sr_alias_set
= 0;
277 /* Save information from a "cmpxx" operation until the branch or scc is
279 rtx s390_compare_op0
, s390_compare_op1
;
281 /* Structure used to hold the components of a S/390 memory
282 address. A legitimate address on S/390 is of the general
284 base + index + displacement
285 where any of the components is optional.
287 base and index are registers of the class ADDR_REGS,
288 displacement is an unsigned 12-bit immediate constant. */
298 /* Which cpu are we tuning for. */
299 enum processor_type s390_tune
;
300 enum processor_flags s390_tune_flags
;
301 /* Which instruction set architecture to use. */
302 enum processor_type s390_arch
;
303 enum processor_flags s390_arch_flags
;
305 /* Strings to hold which cpu and instruction set architecture to use. */
306 const char *s390_tune_string
; /* for -mtune=<xxx> */
307 const char *s390_arch_string
; /* for -march=<xxx> */
309 const char *s390_warn_framesize_string
;
310 const char *s390_warn_dynamicstack_string
;
311 const char *s390_stack_size_string
;
312 const char *s390_stack_guard_string
;
314 HOST_WIDE_INT s390_warn_framesize
= 0;
315 bool s390_warn_dynamicstack_p
= 0;
316 HOST_WIDE_INT s390_stack_size
= 0;
317 HOST_WIDE_INT s390_stack_guard
= 0;
319 /* The following structure is embedded in the machine
320 specific part of struct function. */
322 struct s390_frame_layout
GTY (())
324 /* Offset within stack frame. */
325 HOST_WIDE_INT gprs_offset
;
326 HOST_WIDE_INT f0_offset
;
327 HOST_WIDE_INT f4_offset
;
328 HOST_WIDE_INT f8_offset
;
329 HOST_WIDE_INT backchain_offset
;
331 /* Number of first and last gpr to be saved, restored. */
333 int first_restore_gpr
;
335 int last_restore_gpr
;
337 /* Bits standing for floating point registers. Set, if the
338 respective register has to be saved. Starting with reg 16 (f0)
339 at the rightmost bit.
340 Bit 15 - 8 7 6 5 4 3 2 1 0
341 fpr 15 - 8 7 5 3 1 6 4 2 0
342 reg 31 - 24 23 22 21 20 19 18 17 16 */
343 unsigned int fpr_bitmap
;
345 /* Number of floating point registers f8-f15 which must be saved. */
348 /* Set if return address needs to be saved. */
349 bool save_return_addr_p
;
351 /* Size of stack frame. */
352 HOST_WIDE_INT frame_size
;
355 /* Define the structure for the machine field in struct function. */
357 struct machine_function
GTY(())
359 struct s390_frame_layout frame_layout
;
361 /* Literal pool base register. */
364 /* True if we may need to perform branch splitting. */
365 bool split_branches_pending_p
;
367 /* Some local-dynamic TLS symbol name. */
368 const char *some_ld_name
;
371 /* Few accessor macros for struct cfun->machine->s390_frame_layout. */
373 #define cfun_frame_layout (cfun->machine->frame_layout)
374 #define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)
375 #define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr - \
376 cfun_frame_layout.first_save_gpr + 1) * UNITS_PER_WORD)
377 #define cfun_set_fpr_bit(BITNUM) (cfun->machine->frame_layout.fpr_bitmap |= \
379 #define cfun_fpr_bit_p(BITNUM) (!!(cfun->machine->frame_layout.fpr_bitmap & \
382 static int s390_match_ccmode_set (rtx
, enum machine_mode
);
383 static int s390_branch_condition_mask (rtx
);
384 static const char *s390_branch_condition_mnemonic (rtx
, int);
385 static int check_mode (rtx
, enum machine_mode
*);
386 static int s390_short_displacement (rtx
);
387 static int s390_decompose_address (rtx
, struct s390_address
*);
388 static rtx
get_thread_pointer (void);
389 static rtx
legitimize_tls_address (rtx
, rtx
);
390 static void print_shift_count_operand (FILE *, rtx
);
391 static const char *get_some_local_dynamic_name (void);
392 static int get_some_local_dynamic_name_1 (rtx
*, void *);
393 static int reg_used_in_mem_p (int, rtx
);
394 static int addr_generation_dependency_p (rtx
, rtx
);
395 static int s390_split_branches (void);
396 static void annotate_constant_pool_refs (rtx
*x
);
397 static void find_constant_pool_ref (rtx
, rtx
*);
398 static void replace_constant_pool_ref (rtx
*, rtx
, rtx
);
399 static rtx
find_ltrel_base (rtx
);
400 static void replace_ltrel_base (rtx
*);
401 static void s390_optimize_prologue (void);
402 static int find_unused_clobbered_reg (void);
403 static void s390_frame_area (int *, int *);
404 static void s390_register_info (int []);
405 static void s390_frame_info (void);
406 static void s390_init_frame_layout (void);
407 static void s390_update_frame_layout (void);
408 static rtx
save_fpr (rtx
, int, int);
409 static rtx
restore_fpr (rtx
, int, int);
410 static rtx
save_gprs (rtx
, int, int, int);
411 static rtx
restore_gprs (rtx
, int, int, int);
412 static int s390_function_arg_size (enum machine_mode
, tree
);
413 static bool s390_function_arg_float (enum machine_mode
, tree
);
414 static struct machine_function
* s390_init_machine_status (void);
416 /* Check whether integer displacement is in range. */
417 #define DISP_IN_RANGE(d) \
418 (TARGET_LONG_DISPLACEMENT? ((d) >= -524288 && (d) <= 524287) \
419 : ((d) >= 0 && (d) <= 4095))
421 /* Return true if SET either doesn't set the CC register, or else
422 the source and destination have matching CC modes and that
423 CC mode is at least as constrained as REQ_MODE. */
426 s390_match_ccmode_set (rtx set
, enum machine_mode req_mode
)
428 enum machine_mode set_mode
;
430 if (GET_CODE (set
) != SET
)
433 if (GET_CODE (SET_DEST (set
)) != REG
|| !CC_REGNO_P (REGNO (SET_DEST (set
))))
436 set_mode
= GET_MODE (SET_DEST (set
));
450 if (req_mode
!= set_mode
)
455 if (req_mode
!= CCSmode
&& req_mode
!= CCUmode
&& req_mode
!= CCTmode
456 && req_mode
!= CCSRmode
&& req_mode
!= CCURmode
)
462 if (req_mode
!= CCAmode
)
470 return (GET_MODE (SET_SRC (set
)) == set_mode
);
473 /* Return true if every SET in INSN that sets the CC register
474 has source and destination with matching CC modes and that
475 CC mode is at least as constrained as REQ_MODE.
476 If REQ_MODE is VOIDmode, always return false. */
479 s390_match_ccmode (rtx insn
, enum machine_mode req_mode
)
483 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
484 if (req_mode
== VOIDmode
)
487 if (GET_CODE (PATTERN (insn
)) == SET
)
488 return s390_match_ccmode_set (PATTERN (insn
), req_mode
);
490 if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
491 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
493 rtx set
= XVECEXP (PATTERN (insn
), 0, i
);
494 if (GET_CODE (set
) == SET
)
495 if (!s390_match_ccmode_set (set
, req_mode
))
502 /* If a test-under-mask instruction can be used to implement
503 (compare (and ... OP1) OP2), return the CC mode required
504 to do that. Otherwise, return VOIDmode.
505 MIXED is true if the instruction can distinguish between
506 CC1 and CC2 for mixed selected bits (TMxx), it is false
507 if the instruction cannot (TM). */
510 s390_tm_ccmode (rtx op1
, rtx op2
, int mixed
)
514 /* ??? Fixme: should work on CONST_DOUBLE as well. */
515 if (GET_CODE (op1
) != CONST_INT
|| GET_CODE (op2
) != CONST_INT
)
518 /* Selected bits all zero: CC0.
519 e.g.: int a; if ((a & (16 + 128)) == 0) */
520 if (INTVAL (op2
) == 0)
523 /* Selected bits all one: CC3.
524 e.g.: int a; if ((a & (16 + 128)) == 16 + 128) */
525 if (INTVAL (op2
) == INTVAL (op1
))
528 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. e.g.:
530 if ((a & (16 + 128)) == 16) -> CCT1
531 if ((a & (16 + 128)) == 128) -> CCT2 */
534 bit1
= exact_log2 (INTVAL (op2
));
535 bit0
= exact_log2 (INTVAL (op1
) ^ INTVAL (op2
));
536 if (bit0
!= -1 && bit1
!= -1)
537 return bit0
> bit1
? CCT1mode
: CCT2mode
;
543 /* Given a comparison code OP (EQ, NE, etc.) and the operands
544 OP0 and OP1 of a COMPARE, return the mode to be used for the
548 s390_select_ccmode (enum rtx_code code
, rtx op0
, rtx op1
)
554 if ((GET_CODE (op0
) == NEG
|| GET_CODE (op0
) == ABS
)
555 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
557 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
558 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0
, 1)), 'K', "K"))
560 if ((GET_CODE (op0
) == PLUS
|| GET_CODE (op0
) == MINUS
561 || GET_CODE (op1
) == NEG
)
562 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
565 if (GET_CODE (op0
) == AND
)
567 /* Check whether we can potentially do it via TM. */
568 enum machine_mode ccmode
;
569 ccmode
= s390_tm_ccmode (XEXP (op0
, 1), op1
, 1);
570 if (ccmode
!= VOIDmode
)
572 /* Relax CCTmode to CCZmode to allow fall-back to AND
573 if that turns out to be beneficial. */
574 return ccmode
== CCTmode
? CCZmode
: ccmode
;
578 if (register_operand (op0
, HImode
)
579 && GET_CODE (op1
) == CONST_INT
580 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 65535))
582 if (register_operand (op0
, QImode
)
583 && GET_CODE (op1
) == CONST_INT
584 && (INTVAL (op1
) == -1 || INTVAL (op1
) == 255))
593 /* The only overflow condition of NEG and ABS happens when
594 -INT_MAX is used as parameter, which stays negative. So
595 we have an overflow from a positive value to a negative.
596 Using CCAP mode the resulting cc can be used for comparisons. */
597 if ((GET_CODE (op0
) == NEG
|| GET_CODE (op0
) == ABS
)
598 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
601 /* If constants are involved in an add instruction it is possible to use
602 the resulting cc for comparisons with zero. Knowing the sign of the
603 constant the overflow behavior gets predictable. e.g.:
604 int a, b; if ((b = a + c) > 0)
605 with c as a constant value: c < 0 -> CCAN and c >= 0 -> CCAP */
606 if (GET_CODE (op0
) == PLUS
&& GET_CODE (XEXP (op0
, 1)) == CONST_INT
607 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0
, 1)), 'K', "K"))
609 if (INTVAL (XEXP((op0
), 1)) < 0)
623 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
624 && GET_CODE (op1
) != CONST_INT
)
630 if (GET_CODE (op0
) == PLUS
631 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
634 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
635 && GET_CODE (op1
) != CONST_INT
)
641 if (GET_CODE (op0
) == MINUS
642 && GET_MODE_CLASS (GET_MODE (op0
)) == MODE_INT
)
645 if ((GET_CODE (op0
) == SIGN_EXTEND
|| GET_CODE (op0
) == ZERO_EXTEND
)
646 && GET_CODE (op1
) != CONST_INT
)
655 /* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
656 that we can implement more efficiently. */
659 s390_canonicalize_comparison (enum rtx_code
*code
, rtx
*op0
, rtx
*op1
)
661 /* Convert ZERO_EXTRACT back to AND to enable TM patterns. */
662 if ((*code
== EQ
|| *code
== NE
)
663 && *op1
== const0_rtx
664 && GET_CODE (*op0
) == ZERO_EXTRACT
665 && GET_CODE (XEXP (*op0
, 1)) == CONST_INT
666 && GET_CODE (XEXP (*op0
, 2)) == CONST_INT
667 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0
, 0))))
669 rtx inner
= XEXP (*op0
, 0);
670 HOST_WIDE_INT modesize
= GET_MODE_BITSIZE (GET_MODE (inner
));
671 HOST_WIDE_INT len
= INTVAL (XEXP (*op0
, 1));
672 HOST_WIDE_INT pos
= INTVAL (XEXP (*op0
, 2));
674 if (len
> 0 && len
< modesize
675 && pos
>= 0 && pos
+ len
<= modesize
676 && modesize
<= HOST_BITS_PER_WIDE_INT
)
678 unsigned HOST_WIDE_INT block
;
679 block
= ((unsigned HOST_WIDE_INT
) 1 << len
) - 1;
680 block
<<= modesize
- pos
- len
;
682 *op0
= gen_rtx_AND (GET_MODE (inner
), inner
,
683 gen_int_mode (block
, GET_MODE (inner
)));
687 /* Narrow AND of memory against immediate to enable TM. */
688 if ((*code
== EQ
|| *code
== NE
)
689 && *op1
== const0_rtx
690 && GET_CODE (*op0
) == AND
691 && GET_CODE (XEXP (*op0
, 1)) == CONST_INT
692 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0
, 0))))
694 rtx inner
= XEXP (*op0
, 0);
695 rtx mask
= XEXP (*op0
, 1);
697 /* Ignore paradoxical SUBREGs if all extra bits are masked out. */
698 if (GET_CODE (inner
) == SUBREG
699 && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (inner
)))
700 && (GET_MODE_SIZE (GET_MODE (inner
))
701 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner
))))
703 & GET_MODE_MASK (GET_MODE (inner
))
704 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (inner
))))
706 inner
= SUBREG_REG (inner
);
708 /* Do not change volatile MEMs. */
709 if (MEM_P (inner
) && !MEM_VOLATILE_P (inner
))
711 int part
= s390_single_part (XEXP (*op0
, 1),
712 GET_MODE (inner
), QImode
, 0);
715 mask
= gen_int_mode (s390_extract_part (mask
, QImode
, 0), QImode
);
716 inner
= adjust_address_nv (inner
, QImode
, part
);
717 *op0
= gen_rtx_AND (QImode
, inner
, mask
);
722 /* Narrow comparisons against 0xffff to HImode if possible. */
723 if ((*code
== EQ
|| *code
== NE
)
724 && GET_CODE (*op1
) == CONST_INT
725 && INTVAL (*op1
) == 0xffff
726 && SCALAR_INT_MODE_P (GET_MODE (*op0
))
727 && (nonzero_bits (*op0
, GET_MODE (*op0
))
728 & ~(unsigned HOST_WIDE_INT
) 0xffff) == 0)
730 *op0
= gen_lowpart (HImode
, *op0
);
735 /* Remove redundant UNSPEC_CMPINT conversions if possible. */
736 if (GET_CODE (*op0
) == UNSPEC
737 && XINT (*op0
, 1) == UNSPEC_CMPINT
738 && XVECLEN (*op0
, 0) == 1
739 && GET_MODE (XVECEXP (*op0
, 0, 0)) == CCUmode
740 && GET_CODE (XVECEXP (*op0
, 0, 0)) == REG
741 && REGNO (XVECEXP (*op0
, 0, 0)) == CC_REGNUM
742 && *op1
== const0_rtx
)
744 enum rtx_code new_code
= UNKNOWN
;
747 case EQ
: new_code
= EQ
; break;
748 case NE
: new_code
= NE
; break;
749 case LT
: new_code
= GTU
; break;
750 case GT
: new_code
= LTU
; break;
751 case LE
: new_code
= GEU
; break;
752 case GE
: new_code
= LEU
; break;
756 if (new_code
!= UNKNOWN
)
758 *op0
= XVECEXP (*op0
, 0, 0);
764 /* Emit a compare instruction suitable to implement the comparison
765 OP0 CODE OP1. Return the correct condition RTL to be placed in
766 the IF_THEN_ELSE of the conditional branch testing the result. */
769 s390_emit_compare (enum rtx_code code
, rtx op0
, rtx op1
)
771 enum machine_mode mode
= s390_select_ccmode (code
, op0
, op1
);
772 rtx cc
= gen_rtx_REG (mode
, CC_REGNUM
);
774 emit_insn (gen_rtx_SET (VOIDmode
, cc
, gen_rtx_COMPARE (mode
, op0
, op1
)));
775 return gen_rtx_fmt_ee (code
, VOIDmode
, cc
, const0_rtx
);
778 /* Emit a jump instruction to TARGET. If COND is NULL_RTX, emit an
779 unconditional jump, else a conditional jump under condition COND. */
782 s390_emit_jump (rtx target
, rtx cond
)
786 target
= gen_rtx_LABEL_REF (VOIDmode
, target
);
788 target
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, target
, pc_rtx
);
790 insn
= gen_rtx_SET (VOIDmode
, pc_rtx
, target
);
791 emit_jump_insn (insn
);
794 /* Return nonzero if OP is a valid comparison operator
795 for a branch condition in mode MODE. */
798 s390_comparison (rtx op
, enum machine_mode mode
)
800 if (mode
!= VOIDmode
&& mode
!= GET_MODE (op
))
803 if (!COMPARISON_P (op
))
806 if (GET_CODE (XEXP (op
, 0)) != REG
807 || REGNO (XEXP (op
, 0)) != CC_REGNUM
808 || XEXP (op
, 1) != const0_rtx
)
811 return s390_branch_condition_mask (op
) >= 0;
814 /* Return nonzero if OP is a valid comparison operator
815 for an ALC condition in mode MODE. */
818 s390_alc_comparison (rtx op
, enum machine_mode mode
)
820 if (mode
!= VOIDmode
&& mode
!= GET_MODE (op
))
823 while (GET_CODE (op
) == ZERO_EXTEND
|| GET_CODE (op
) == SIGN_EXTEND
)
826 if (!COMPARISON_P (op
))
829 if (GET_CODE (XEXP (op
, 0)) != REG
830 || REGNO (XEXP (op
, 0)) != CC_REGNUM
831 || XEXP (op
, 1) != const0_rtx
)
834 switch (GET_MODE (XEXP (op
, 0)))
837 return GET_CODE (op
) == LTU
;
840 return GET_CODE (op
) == LEU
;
843 return GET_CODE (op
) == GEU
;
846 return GET_CODE (op
) == GTU
;
849 return GET_CODE (op
) == LTU
;
852 return GET_CODE (op
) == UNGT
;
855 return GET_CODE (op
) == UNLT
;
862 /* Return nonzero if OP is a valid comparison operator
863 for an SLB condition in mode MODE. */
866 s390_slb_comparison (rtx op
, enum machine_mode mode
)
868 if (mode
!= VOIDmode
&& mode
!= GET_MODE (op
))
871 while (GET_CODE (op
) == ZERO_EXTEND
|| GET_CODE (op
) == SIGN_EXTEND
)
874 if (!COMPARISON_P (op
))
877 if (GET_CODE (XEXP (op
, 0)) != REG
878 || REGNO (XEXP (op
, 0)) != CC_REGNUM
879 || XEXP (op
, 1) != const0_rtx
)
882 switch (GET_MODE (XEXP (op
, 0)))
885 return GET_CODE (op
) == GEU
;
888 return GET_CODE (op
) == GTU
;
891 return GET_CODE (op
) == LTU
;
894 return GET_CODE (op
) == LEU
;
897 return GET_CODE (op
) == GEU
;
900 return GET_CODE (op
) == LE
;
903 return GET_CODE (op
) == GE
;
910 /* Return branch condition mask to implement a branch
911 specified by CODE. Return -1 for invalid comparisons. */
914 s390_branch_condition_mask (rtx code
)
916 const int CC0
= 1 << 3;
917 const int CC1
= 1 << 2;
918 const int CC2
= 1 << 1;
919 const int CC3
= 1 << 0;
921 if (GET_CODE (XEXP (code
, 0)) != REG
922 || REGNO (XEXP (code
, 0)) != CC_REGNUM
923 || XEXP (code
, 1) != const0_rtx
)
926 switch (GET_MODE (XEXP (code
, 0)))
929 switch (GET_CODE (code
))
932 case NE
: return CC1
| CC2
| CC3
;
938 switch (GET_CODE (code
))
941 case NE
: return CC0
| CC2
| CC3
;
947 switch (GET_CODE (code
))
950 case NE
: return CC0
| CC1
| CC3
;
956 switch (GET_CODE (code
))
959 case NE
: return CC0
| CC1
| CC2
;
965 switch (GET_CODE (code
))
967 case EQ
: return CC0
| CC2
;
968 case NE
: return CC1
| CC3
;
974 switch (GET_CODE (code
))
976 case LTU
: return CC2
| CC3
; /* carry */
977 case GEU
: return CC0
| CC1
; /* no carry */
983 switch (GET_CODE (code
))
985 case GTU
: return CC0
| CC1
; /* borrow */
986 case LEU
: return CC2
| CC3
; /* no borrow */
992 switch (GET_CODE (code
))
994 case EQ
: return CC0
| CC2
;
995 case NE
: return CC1
| CC3
;
996 case LTU
: return CC1
;
997 case GTU
: return CC3
;
998 case LEU
: return CC1
| CC2
;
999 case GEU
: return CC2
| CC3
;
1004 switch (GET_CODE (code
))
1006 case EQ
: return CC0
;
1007 case NE
: return CC1
| CC2
| CC3
;
1008 case LTU
: return CC1
;
1009 case GTU
: return CC2
;
1010 case LEU
: return CC0
| CC1
;
1011 case GEU
: return CC0
| CC2
;
1017 switch (GET_CODE (code
))
1019 case EQ
: return CC0
;
1020 case NE
: return CC2
| CC1
| CC3
;
1021 case LTU
: return CC2
;
1022 case GTU
: return CC1
;
1023 case LEU
: return CC0
| CC2
;
1024 case GEU
: return CC0
| CC1
;
1030 switch (GET_CODE (code
))
1032 case EQ
: return CC0
;
1033 case NE
: return CC1
| CC2
| CC3
;
1034 case LT
: return CC1
| CC3
;
1035 case GT
: return CC2
;
1036 case LE
: return CC0
| CC1
| CC3
;
1037 case GE
: return CC0
| CC2
;
1043 switch (GET_CODE (code
))
1045 case EQ
: return CC0
;
1046 case NE
: return CC1
| CC2
| CC3
;
1047 case LT
: return CC1
;
1048 case GT
: return CC2
| CC3
;
1049 case LE
: return CC0
| CC1
;
1050 case GE
: return CC0
| CC2
| CC3
;
1056 switch (GET_CODE (code
))
1058 case EQ
: return CC0
;
1059 case NE
: return CC1
| CC2
| CC3
;
1060 case LT
: return CC1
;
1061 case GT
: return CC2
;
1062 case LE
: return CC0
| CC1
;
1063 case GE
: return CC0
| CC2
;
1064 case UNORDERED
: return CC3
;
1065 case ORDERED
: return CC0
| CC1
| CC2
;
1066 case UNEQ
: return CC0
| CC3
;
1067 case UNLT
: return CC1
| CC3
;
1068 case UNGT
: return CC2
| CC3
;
1069 case UNLE
: return CC0
| CC1
| CC3
;
1070 case UNGE
: return CC0
| CC2
| CC3
;
1071 case LTGT
: return CC1
| CC2
;
1077 switch (GET_CODE (code
))
1079 case EQ
: return CC0
;
1080 case NE
: return CC2
| CC1
| CC3
;
1081 case LT
: return CC2
;
1082 case GT
: return CC1
;
1083 case LE
: return CC0
| CC2
;
1084 case GE
: return CC0
| CC1
;
1085 case UNORDERED
: return CC3
;
1086 case ORDERED
: return CC0
| CC2
| CC1
;
1087 case UNEQ
: return CC0
| CC3
;
1088 case UNLT
: return CC2
| CC3
;
1089 case UNGT
: return CC1
| CC3
;
1090 case UNLE
: return CC0
| CC2
| CC3
;
1091 case UNGE
: return CC0
| CC1
| CC3
;
1092 case LTGT
: return CC2
| CC1
;
1102 /* If INV is false, return assembler mnemonic string to implement
1103 a branch specified by CODE. If INV is true, return mnemonic
1104 for the corresponding inverted branch. */
1107 s390_branch_condition_mnemonic (rtx code
, int inv
)
1109 static const char *const mnemonic
[16] =
1111 NULL
, "o", "h", "nle",
1112 "l", "nhe", "lh", "ne",
1113 "e", "nlh", "he", "nl",
1114 "le", "nh", "no", NULL
1117 int mask
= s390_branch_condition_mask (code
);
1118 gcc_assert (mask
>= 0);
1123 if (mask
< 1 || mask
> 14)
1126 return mnemonic
[mask
];
1129 /* Return the part of op which has a value different from def.
1130 The size of the part is determined by mode.
1131 Use this function only if you already know that op really
1132 contains such a part. */
1134 unsigned HOST_WIDE_INT
1135 s390_extract_part (rtx op
, enum machine_mode mode
, int def
)
1137 unsigned HOST_WIDE_INT value
= 0;
1138 int max_parts
= HOST_BITS_PER_WIDE_INT
/ GET_MODE_BITSIZE (mode
);
1139 int part_bits
= GET_MODE_BITSIZE (mode
);
1140 unsigned HOST_WIDE_INT part_mask
= (1 << part_bits
) - 1;
1143 for (i
= 0; i
< max_parts
; i
++)
1146 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
1148 value
>>= part_bits
;
1150 if ((value
& part_mask
) != (def
& part_mask
))
1151 return value
& part_mask
;
1157 /* If OP is an integer constant of mode MODE with exactly one
1158 part of mode PART_MODE unequal to DEF, return the number of that
1159 part. Otherwise, return -1. */
1162 s390_single_part (rtx op
,
1163 enum machine_mode mode
,
1164 enum machine_mode part_mode
,
1167 unsigned HOST_WIDE_INT value
= 0;
1168 int n_parts
= GET_MODE_SIZE (mode
) / GET_MODE_SIZE (part_mode
);
1169 unsigned HOST_WIDE_INT part_mask
= (1 << GET_MODE_BITSIZE (part_mode
)) - 1;
1172 if (GET_CODE (op
) != CONST_INT
)
1175 for (i
= 0; i
< n_parts
; i
++)
1178 value
= (unsigned HOST_WIDE_INT
) INTVAL (op
);
1180 value
>>= GET_MODE_BITSIZE (part_mode
);
1182 if ((value
& part_mask
) != (def
& part_mask
))
1190 return part
== -1 ? -1 : n_parts
- 1 - part
;
1193 /* Check whether we can (and want to) split a double-word
1194 move in mode MODE from SRC to DST into two single-word
1195 moves, moving the subword FIRST_SUBWORD first. */
1198 s390_split_ok_p (rtx dst
, rtx src
, enum machine_mode mode
, int first_subword
)
1200 /* Floating point registers cannot be split. */
1201 if (FP_REG_P (src
) || FP_REG_P (dst
))
1204 /* We don't need to split if operands are directly accessible. */
1205 if (s_operand (src
, mode
) || s_operand (dst
, mode
))
1208 /* Non-offsettable memory references cannot be split. */
1209 if ((GET_CODE (src
) == MEM
&& !offsettable_memref_p (src
))
1210 || (GET_CODE (dst
) == MEM
&& !offsettable_memref_p (dst
)))
1213 /* Moving the first subword must not clobber a register
1214 needed to move the second subword. */
1215 if (register_operand (dst
, mode
))
1217 rtx subreg
= operand_subword (dst
, first_subword
, 0, mode
);
1218 if (reg_overlap_mentioned_p (subreg
, src
))
1225 /* Check whether the address of memory reference MEM2 equals exactly
1226 the address of memory reference MEM1 plus DELTA. Return true if
1227 we can prove this to be the case, false otherwise. */
1230 s390_offset_p (rtx mem1
, rtx mem2
, rtx delta
)
1232 rtx addr1
, addr2
, addr_delta
;
1234 if (GET_CODE (mem1
) != MEM
|| GET_CODE (mem2
) != MEM
)
1237 addr1
= XEXP (mem1
, 0);
1238 addr2
= XEXP (mem2
, 0);
1240 addr_delta
= simplify_binary_operation (MINUS
, Pmode
, addr2
, addr1
);
1241 if (!addr_delta
|| !rtx_equal_p (addr_delta
, delta
))
1247 /* Expand logical operator CODE in mode MODE with operands OPERANDS. */
1250 s390_expand_logical_operator (enum rtx_code code
, enum machine_mode mode
,
1253 enum machine_mode wmode
= mode
;
1254 rtx dst
= operands
[0];
1255 rtx src1
= operands
[1];
1256 rtx src2
= operands
[2];
1259 /* If we cannot handle the operation directly, use a temp register. */
1260 if (!s390_logical_operator_ok_p (operands
))
1261 dst
= gen_reg_rtx (mode
);
1263 /* QImode and HImode patterns make sense only if we have a destination
1264 in memory. Otherwise perform the operation in SImode. */
1265 if ((mode
== QImode
|| mode
== HImode
) && GET_CODE (dst
) != MEM
)
1268 /* Widen operands if required. */
1271 if (GET_CODE (dst
) == SUBREG
1272 && (tem
= simplify_subreg (wmode
, dst
, mode
, 0)) != 0)
1274 else if (REG_P (dst
))
1275 dst
= gen_rtx_SUBREG (wmode
, dst
, 0);
1277 dst
= gen_reg_rtx (wmode
);
1279 if (GET_CODE (src1
) == SUBREG
1280 && (tem
= simplify_subreg (wmode
, src1
, mode
, 0)) != 0)
1282 else if (GET_MODE (src1
) != VOIDmode
)
1283 src1
= gen_rtx_SUBREG (wmode
, force_reg (mode
, src1
), 0);
1285 if (GET_CODE (src2
) == SUBREG
1286 && (tem
= simplify_subreg (wmode
, src2
, mode
, 0)) != 0)
1288 else if (GET_MODE (src2
) != VOIDmode
)
1289 src2
= gen_rtx_SUBREG (wmode
, force_reg (mode
, src2
), 0);
1292 /* Emit the instruction. */
1293 op
= gen_rtx_SET (VOIDmode
, dst
, gen_rtx_fmt_ee (code
, wmode
, src1
, src2
));
1294 clob
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
1295 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, op
, clob
)));
1297 /* Fix up the destination if needed. */
1298 if (dst
!= operands
[0])
1299 emit_move_insn (operands
[0], gen_lowpart (mode
, dst
));
1302 /* Check whether OPERANDS are OK for a logical operation (AND, IOR, XOR). */
1305 s390_logical_operator_ok_p (rtx
*operands
)
1307 /* If the destination operand is in memory, it needs to coincide
1308 with one of the source operands. After reload, it has to be
1309 the first source operand. */
1310 if (GET_CODE (operands
[0]) == MEM
)
1311 return rtx_equal_p (operands
[0], operands
[1])
1312 || (!reload_completed
&& rtx_equal_p (operands
[0], operands
[2]));
1317 /* Narrow logical operation CODE of memory operand MEMOP with immediate
1318 operand IMMOP to switch from SS to SI type instructions. */
1321 s390_narrow_logical_operator (enum rtx_code code
, rtx
*memop
, rtx
*immop
)
1323 int def
= code
== AND
? -1 : 0;
1327 gcc_assert (GET_CODE (*memop
) == MEM
);
1328 gcc_assert (!MEM_VOLATILE_P (*memop
));
1330 mask
= s390_extract_part (*immop
, QImode
, def
);
1331 part
= s390_single_part (*immop
, GET_MODE (*memop
), QImode
, def
);
1332 gcc_assert (part
>= 0);
1334 *memop
= adjust_address (*memop
, QImode
, part
);
1335 *immop
= gen_int_mode (mask
, QImode
);
1339 /* Change optimizations to be performed, depending on the
1342 LEVEL is the optimization level specified; 2 if `-O2' is
1343 specified, 1 if `-O' is specified, and 0 if neither is specified.
1345 SIZE is nonzero if `-Os' is specified and zero otherwise. */
1348 optimization_options (int level ATTRIBUTE_UNUSED
, int size ATTRIBUTE_UNUSED
)
1350 /* ??? There are apparently still problems with -fcaller-saves. */
1351 flag_caller_saves
= 0;
1353 /* By default, always emit DWARF-2 unwind info. This allows debugging
1354 without maintaining a stack frame back-chain. */
1355 flag_asynchronous_unwind_tables
= 1;
1359 override_options (void)
1364 const char *const name
; /* processor name or nickname. */
1365 const enum processor_type processor
;
1366 const enum processor_flags flags
;
1368 const processor_alias_table
[] =
1370 {"g5", PROCESSOR_9672_G5
, PF_IEEE_FLOAT
},
1371 {"g6", PROCESSOR_9672_G6
, PF_IEEE_FLOAT
},
1372 {"z900", PROCESSOR_2064_Z900
, PF_IEEE_FLOAT
| PF_ZARCH
},
1373 {"z990", PROCESSOR_2084_Z990
, PF_IEEE_FLOAT
| PF_ZARCH
1374 | PF_LONG_DISPLACEMENT
},
1377 int const pta_size
= ARRAY_SIZE (processor_alias_table
);
1379 /* Acquire a unique set number for our register saves and restores. */
1380 s390_sr_alias_set
= new_alias_set ();
1382 /* Set up function hooks. */
1383 init_machine_status
= s390_init_machine_status
;
1385 /* Architecture mode defaults according to ABI. */
1386 if (!(target_flags_explicit
& MASK_ZARCH
))
1389 target_flags
|= MASK_ZARCH
;
1391 target_flags
&= ~MASK_ZARCH
;
1394 /* Determine processor architectural level. */
1395 if (!s390_arch_string
)
1396 s390_arch_string
= TARGET_ZARCH
? "z900" : "g5";
1398 for (i
= 0; i
< pta_size
; i
++)
1399 if (! strcmp (s390_arch_string
, processor_alias_table
[i
].name
))
1401 s390_arch
= processor_alias_table
[i
].processor
;
1402 s390_arch_flags
= processor_alias_table
[i
].flags
;
1406 error ("Unknown cpu used in -march=%s.", s390_arch_string
);
1408 /* Determine processor to tune for. */
1409 if (!s390_tune_string
)
1411 s390_tune
= s390_arch
;
1412 s390_tune_flags
= s390_arch_flags
;
1413 s390_tune_string
= s390_arch_string
;
1417 for (i
= 0; i
< pta_size
; i
++)
1418 if (! strcmp (s390_tune_string
, processor_alias_table
[i
].name
))
1420 s390_tune
= processor_alias_table
[i
].processor
;
1421 s390_tune_flags
= processor_alias_table
[i
].flags
;
1425 error ("Unknown cpu used in -mtune=%s.", s390_tune_string
);
1428 /* Sanity checks. */
1429 if (TARGET_ZARCH
&& !(s390_arch_flags
& PF_ZARCH
))
1430 error ("z/Architecture mode not supported on %s.", s390_arch_string
);
1431 if (TARGET_64BIT
&& !TARGET_ZARCH
)
1432 error ("64-bit ABI not supported in ESA/390 mode.");
1435 /* Set processor cost function. */
1436 if (s390_tune
== PROCESSOR_2084_Z990
)
1437 s390_cost
= &z990_cost
;
1439 s390_cost
= &z900_cost
;
1442 if (TARGET_BACKCHAIN
&& TARGET_PACKED_STACK
&& TARGET_HARD_FLOAT
)
1443 error ("-mbackchain -mpacked-stack -mhard-float are not supported "
1446 if (s390_warn_framesize_string
)
1448 if (sscanf (s390_warn_framesize_string
, HOST_WIDE_INT_PRINT_DEC
,
1449 &s390_warn_framesize
) != 1)
1450 error ("invalid value for -mwarn-framesize");
1453 if (s390_warn_dynamicstack_string
)
1454 s390_warn_dynamicstack_p
= 1;
1456 if (s390_stack_size_string
)
1458 if (sscanf (s390_stack_size_string
, HOST_WIDE_INT_PRINT_DEC
,
1459 &s390_stack_size
) != 1)
1460 error ("invalid value for -mstack-size");
1462 if (exact_log2 (s390_stack_size
) == -1)
1463 error ("stack size must be an exact power of 2");
1465 if (s390_stack_guard_string
)
1467 if (sscanf (s390_stack_guard_string
, HOST_WIDE_INT_PRINT_DEC
,
1468 &s390_stack_guard
) != 1)
1469 error ("invalid value for -mstack-guard");
1471 if (s390_stack_guard
>= s390_stack_size
)
1472 error ("stack size must be greater than the stack guard value");
1474 if (exact_log2 (s390_stack_guard
) == -1)
1475 error ("stack guard value must be an exact power of 2");
1478 error ("-mstack-size implies use of -mstack-guard");
1481 if (s390_stack_guard_string
&& !s390_stack_size_string
)
1482 error ("-mstack-guard implies use of -mstack-size");
1485 /* Map for smallest class containing reg regno. */
1487 const enum reg_class regclass_map
[FIRST_PSEUDO_REGISTER
] =
1488 { GENERAL_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1489 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1490 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1491 ADDR_REGS
, ADDR_REGS
, ADDR_REGS
, ADDR_REGS
,
1492 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1493 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1494 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1495 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
1496 ADDR_REGS
, CC_REGS
, ADDR_REGS
, ADDR_REGS
,
1497 ACCESS_REGS
, ACCESS_REGS
1500 /* Return attribute type of insn. */
1502 static enum attr_type
1503 s390_safe_attr_type (rtx insn
)
1505 if (recog_memoized (insn
) >= 0)
1506 return get_attr_type (insn
);
1511 /* Return true if OP a (const_int 0) operand.
1512 OP is the current operation.
1513 MODE is the current operation mode. */
1516 const0_operand (register rtx op
, enum machine_mode mode
)
1518 return op
== CONST0_RTX (mode
);
1521 /* Return true if OP is constant.
1522 OP is the current operation.
1523 MODE is the current operation mode. */
1526 consttable_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1528 return CONSTANT_P (op
);
1531 /* Return true if the mode of operand OP matches MODE.
1532 If MODE is set to VOIDmode, set it to the mode of OP. */
1535 check_mode (register rtx op
, enum machine_mode
*mode
)
1537 if (*mode
== VOIDmode
)
1538 *mode
= GET_MODE (op
);
1541 if (GET_MODE (op
) != VOIDmode
&& GET_MODE (op
) != *mode
)
1547 /* Return true if OP a valid operand for the LARL instruction.
1548 OP is the current operation.
1549 MODE is the current operation mode. */
1552 larl_operand (register rtx op
, enum machine_mode mode
)
1554 if (! check_mode (op
, &mode
))
1557 /* Allow labels and local symbols. */
1558 if (GET_CODE (op
) == LABEL_REF
)
1560 if (GET_CODE (op
) == SYMBOL_REF
)
1561 return ((SYMBOL_REF_FLAGS (op
) & SYMBOL_FLAG_ALIGN1
) == 0
1562 && SYMBOL_REF_TLS_MODEL (op
) == 0
1563 && (!flag_pic
|| SYMBOL_REF_LOCAL_P (op
)));
1565 /* Everything else must have a CONST, so strip it. */
1566 if (GET_CODE (op
) != CONST
)
1570 /* Allow adding *even* in-range constants. */
1571 if (GET_CODE (op
) == PLUS
)
1573 if (GET_CODE (XEXP (op
, 1)) != CONST_INT
1574 || (INTVAL (XEXP (op
, 1)) & 1) != 0)
1576 #if HOST_BITS_PER_WIDE_INT > 32
1577 if (INTVAL (XEXP (op
, 1)) >= (HOST_WIDE_INT
)1 << 32
1578 || INTVAL (XEXP (op
, 1)) < -((HOST_WIDE_INT
)1 << 32))
1584 /* Labels and local symbols allowed here as well. */
1585 if (GET_CODE (op
) == LABEL_REF
)
1587 if (GET_CODE (op
) == SYMBOL_REF
)
1588 return ((SYMBOL_REF_FLAGS (op
) & SYMBOL_FLAG_ALIGN1
) == 0
1589 && SYMBOL_REF_TLS_MODEL (op
) == 0
1590 && (!flag_pic
|| SYMBOL_REF_LOCAL_P (op
)));
1592 /* Now we must have a @GOTENT offset or @PLT stub
1593 or an @INDNTPOFF TLS offset. */
1594 if (GET_CODE (op
) == UNSPEC
1595 && XINT (op
, 1) == UNSPEC_GOTENT
)
1597 if (GET_CODE (op
) == UNSPEC
1598 && XINT (op
, 1) == UNSPEC_PLT
)
1600 if (GET_CODE (op
) == UNSPEC
1601 && XINT (op
, 1) == UNSPEC_INDNTPOFF
)
1607 /* Return true if OP is a valid S-type operand.
1608 OP is the current operation.
1609 MODE is the current operation mode. */
1612 s_operand (rtx op
, enum machine_mode mode
)
1614 struct s390_address addr
;
1616 /* Call general_operand first, so that we don't have to
1617 check for many special cases. */
1618 if (!general_operand (op
, mode
))
1621 /* Just like memory_operand, allow (subreg (mem ...))
1623 if (reload_completed
1624 && GET_CODE (op
) == SUBREG
1625 && GET_CODE (SUBREG_REG (op
)) == MEM
)
1626 op
= SUBREG_REG (op
);
1628 if (GET_CODE (op
) != MEM
)
1630 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1638 /* Return true if OP a valid shift count operand.
1639 OP is the current operation.
1640 MODE is the current operation mode. */
1643 shift_count_operand (rtx op
, enum machine_mode mode
)
1645 HOST_WIDE_INT offset
= 0;
1647 if (! check_mode (op
, &mode
))
1650 /* We can have an integer constant, an address register,
1651 or a sum of the two. Note that reload already checks
1652 that any register present is an address register, so
1653 we just check for any register here. */
1654 if (GET_CODE (op
) == CONST_INT
)
1656 offset
= INTVAL (op
);
1659 if (op
&& GET_CODE (op
) == PLUS
&& GET_CODE (XEXP (op
, 1)) == CONST_INT
)
1661 offset
= INTVAL (XEXP (op
, 1));
1664 while (op
&& GET_CODE (op
) == SUBREG
)
1665 op
= SUBREG_REG (op
);
1666 if (op
&& GET_CODE (op
) != REG
)
1669 /* Unfortunately we have to reject constants that are invalid
1670 for an address, or else reload will get confused. */
1671 if (!DISP_IN_RANGE (offset
))
1677 /* Return true if DISP is a valid short displacement. */
1680 s390_short_displacement (rtx disp
)
1682 /* No displacement is OK. */
1686 /* Integer displacement in range. */
1687 if (GET_CODE (disp
) == CONST_INT
)
1688 return INTVAL (disp
) >= 0 && INTVAL (disp
) < 4096;
1690 /* GOT offset is not OK, the GOT can be large. */
1691 if (GET_CODE (disp
) == CONST
1692 && GET_CODE (XEXP (disp
, 0)) == UNSPEC
1693 && (XINT (XEXP (disp
, 0), 1) == UNSPEC_GOT
1694 || XINT (XEXP (disp
, 0), 1) == UNSPEC_GOTNTPOFF
))
1697 /* All other symbolic constants are literal pool references,
1698 which are OK as the literal pool must be small. */
1699 if (GET_CODE (disp
) == CONST
)
1705 /* Return true if OP is a valid operand for a C constraint. */
1708 s390_extra_constraint_str (rtx op
, int c
, const char * str
)
1710 struct s390_address addr
;
1715 /* Check for offsettable variants of memory constraints. */
1718 /* Only accept non-volatile MEMs. */
1719 if (!MEM_P (op
) || MEM_VOLATILE_P (op
))
1722 if ((reload_completed
|| reload_in_progress
)
1723 ? !offsettable_memref_p (op
)
1724 : !offsettable_nonstrict_memref_p (op
))
1730 /* Check for non-literal-pool variants of memory constraints. */
1733 if (GET_CODE (op
) != MEM
)
1735 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1737 if (addr
.base
&& REG_P (addr
.base
) && REGNO (addr
.base
) == BASE_REGNUM
)
1739 if (addr
.indx
&& REG_P (addr
.indx
) && REGNO (addr
.indx
) == BASE_REGNUM
)
1748 if (GET_CODE (op
) != MEM
)
1750 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1755 if (TARGET_LONG_DISPLACEMENT
)
1757 if (!s390_short_displacement (addr
.disp
))
1763 if (GET_CODE (op
) != MEM
)
1766 if (TARGET_LONG_DISPLACEMENT
)
1768 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1770 if (!s390_short_displacement (addr
.disp
))
1776 if (!TARGET_LONG_DISPLACEMENT
)
1778 if (GET_CODE (op
) != MEM
)
1780 if (!s390_decompose_address (XEXP (op
, 0), &addr
))
1784 if (s390_short_displacement (addr
.disp
))
1789 if (!TARGET_LONG_DISPLACEMENT
)
1791 if (GET_CODE (op
) != MEM
)
1793 /* Any invalid address here will be fixed up by reload,
1794 so accept it for the most generic constraint. */
1795 if (s390_decompose_address (XEXP (op
, 0), &addr
)
1796 && s390_short_displacement (addr
.disp
))
1801 if (TARGET_LONG_DISPLACEMENT
)
1803 if (!s390_decompose_address (op
, &addr
))
1805 if (!s390_short_displacement (addr
.disp
))
1811 if (!TARGET_LONG_DISPLACEMENT
)
1813 /* Any invalid address here will be fixed up by reload,
1814 so accept it for the most generic constraint. */
1815 if (s390_decompose_address (op
, &addr
)
1816 && s390_short_displacement (addr
.disp
))
1821 return shift_count_operand (op
, VOIDmode
);
1830 /* Return true if VALUE matches the constraint STR. */
1833 s390_const_ok_for_constraint_p (HOST_WIDE_INT value
,
1837 enum machine_mode mode
, part_mode
;
1839 int part
, part_goal
;
1847 return (unsigned int)value
< 256;
1850 return (unsigned int)value
< 4096;
1853 return value
>= -32768 && value
< 32768;
1856 return (TARGET_LONG_DISPLACEMENT
?
1857 (value
>= -524288 && value
<= 524287)
1858 : (value
>= 0 && value
<= 4095));
1860 return value
== 2147483647;
1866 part_goal
= str
[1] - '0';
1870 case 'H': part_mode
= HImode
; break;
1871 case 'Q': part_mode
= QImode
; break;
1877 case 'H': mode
= HImode
; break;
1878 case 'S': mode
= SImode
; break;
1879 case 'D': mode
= DImode
; break;
1885 case '0': def
= 0; break;
1886 case 'F': def
= -1; break;
1890 if (GET_MODE_SIZE (mode
) <= GET_MODE_SIZE (part_mode
))
1893 part
= s390_single_part (GEN_INT (value
), mode
, part_mode
, def
);
1896 if (part_goal
!= -1 && part_goal
!= part
)
1908 /* Compute a (partial) cost for rtx X. Return true if the complete
1909 cost has been computed, and false if subexpressions should be
1910 scanned. In either case, *TOTAL contains the cost result.
1911 CODE contains GET_CODE (x), OUTER_CODE contains the code
1912 of the superexpression of x. */
1915 s390_rtx_costs (rtx x
, int code
, int outer_code
, int *total
)
1938 *total
= COSTS_N_INSNS (1);
1943 /* Check for multiply and add. */
1944 if ((GET_MODE (x
) == DFmode
|| GET_MODE (x
) == SFmode
)
1945 && GET_CODE (XEXP (x
, 0)) == MULT
1946 && TARGET_HARD_FLOAT
&& TARGET_IEEE_FLOAT
&& TARGET_FUSED_MADD
)
1948 /* This is the multiply and add case. */
1949 if (GET_MODE (x
) == DFmode
)
1950 *total
= s390_cost
->madbr
;
1952 *total
= s390_cost
->maebr
;
1953 *total
+= rtx_cost (XEXP (XEXP (x
, 0), 0), MULT
)
1954 + rtx_cost (XEXP (XEXP (x
, 0), 1), MULT
)
1955 + rtx_cost (XEXP (x
, 1), code
);
1956 return true; /* Do not do an additional recursive descent. */
1958 *total
= COSTS_N_INSNS (1);
1962 switch (GET_MODE (x
))
1966 rtx left
= XEXP (x
, 0);
1967 rtx right
= XEXP (x
, 1);
1968 if (GET_CODE (right
) == CONST_INT
1969 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (right
), 'K', "K"))
1970 *total
= s390_cost
->mhi
;
1971 else if (GET_CODE (left
) == SIGN_EXTEND
)
1972 *total
= s390_cost
->mh
;
1974 *total
= s390_cost
->ms
; /* msr, ms, msy */
1979 rtx left
= XEXP (x
, 0);
1980 rtx right
= XEXP (x
, 1);
1983 if (GET_CODE (right
) == CONST_INT
1984 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (right
), 'K', "K"))
1985 *total
= s390_cost
->mghi
;
1986 else if (GET_CODE (left
) == SIGN_EXTEND
)
1987 *total
= s390_cost
->msgf
;
1989 *total
= s390_cost
->msg
; /* msgr, msg */
1991 else /* TARGET_31BIT */
1993 if (GET_CODE (left
) == SIGN_EXTEND
1994 && GET_CODE (right
) == SIGN_EXTEND
)
1995 /* mulsidi case: mr, m */
1996 *total
= s390_cost
->m
;
1997 else if (GET_CODE (left
) == ZERO_EXTEND
1998 && GET_CODE (right
) == ZERO_EXTEND
1999 && TARGET_CPU_ZARCH
)
2000 /* umulsidi case: ml, mlr */
2001 *total
= s390_cost
->ml
;
2003 /* Complex calculation is required. */
2004 *total
= COSTS_N_INSNS (40);
2010 *total
= s390_cost
->mult_df
;
2019 if (GET_MODE (x
) == TImode
) /* 128 bit division */
2020 *total
= s390_cost
->dlgr
;
2021 else if (GET_MODE (x
) == DImode
)
2023 rtx right
= XEXP (x
, 1);
2024 if (GET_CODE (right
) == ZERO_EXTEND
) /* 64 by 32 bit division */
2025 *total
= s390_cost
->dlr
;
2026 else /* 64 by 64 bit division */
2027 *total
= s390_cost
->dlgr
;
2029 else if (GET_MODE (x
) == SImode
) /* 32 bit division */
2030 *total
= s390_cost
->dlr
;
2035 if (GET_MODE (x
) == DImode
)
2037 rtx right
= XEXP (x
, 1);
2038 if (GET_CODE (right
) == ZERO_EXTEND
) /* 64 by 32 bit division */
2040 *total
= s390_cost
->dsgfr
;
2042 *total
= s390_cost
->dr
;
2043 else /* 64 by 64 bit division */
2044 *total
= s390_cost
->dsgr
;
2046 else if (GET_MODE (x
) == SImode
) /* 32 bit division */
2047 *total
= s390_cost
->dlr
;
2048 else if (GET_MODE (x
) == SFmode
)
2050 if (TARGET_IEEE_FLOAT
)
2051 *total
= s390_cost
->debr
;
2052 else /* TARGET_IBM_FLOAT */
2053 *total
= s390_cost
->der
;
2055 else if (GET_MODE (x
) == DFmode
)
2057 if (TARGET_IEEE_FLOAT
)
2058 *total
= s390_cost
->ddbr
;
2059 else /* TARGET_IBM_FLOAT */
2060 *total
= s390_cost
->ddr
;
2065 if (GET_MODE (x
) == SFmode
)
2066 *total
= s390_cost
->sqebr
;
2068 *total
= s390_cost
->sqdbr
;
2073 if (outer_code
== MULT
|| outer_code
== DIV
|| outer_code
== MOD
2074 || outer_code
== PLUS
|| outer_code
== MINUS
2075 || outer_code
== COMPARE
)
2080 *total
= COSTS_N_INSNS (1);
2081 if (GET_CODE (XEXP (x
, 0)) == AND
2082 && GET_CODE (XEXP (x
, 1)) == CONST_INT
2083 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
)
2085 rtx op0
= XEXP (XEXP (x
, 0), 0);
2086 rtx op1
= XEXP (XEXP (x
, 0), 1);
2087 rtx op2
= XEXP (x
, 1);
2089 if (memory_operand (op0
, GET_MODE (op0
))
2090 && s390_tm_ccmode (op1
, op2
, 0) != VOIDmode
)
2092 if (register_operand (op0
, GET_MODE (op0
))
2093 && s390_tm_ccmode (op1
, op2
, 1) != VOIDmode
)
2103 /* Return the cost of an address rtx ADDR. */
2106 s390_address_cost (rtx addr
)
2108 struct s390_address ad
;
2109 if (!s390_decompose_address (addr
, &ad
))
2112 return ad
.indx
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
2115 /* Return true if OP is a valid operand for the BRAS instruction.
2116 OP is the current operation.
2117 MODE is the current operation mode. */
2120 bras_sym_operand (register rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
2122 register enum rtx_code code
= GET_CODE (op
);
2124 /* Allow SYMBOL_REFs. */
2125 if (code
== SYMBOL_REF
)
2128 /* Allow @PLT stubs. */
2130 && GET_CODE (XEXP (op
, 0)) == UNSPEC
2131 && XINT (XEXP (op
, 0), 1) == UNSPEC_PLT
)
2136 /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
2137 otherwise return 0. */
2140 tls_symbolic_operand (register rtx op
)
2142 if (GET_CODE (op
) != SYMBOL_REF
)
2144 return SYMBOL_REF_TLS_MODEL (op
);
2147 /* Return true if OP is a load multiple operation. It is known to be a
2148 PARALLEL and the first section will be tested.
2149 OP is the current operation.
2150 MODE is the current operation mode. */
2153 load_multiple_operation (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
2155 enum machine_mode elt_mode
;
2156 int count
= XVECLEN (op
, 0);
2157 unsigned int dest_regno
;
2162 /* Perform a quick check so we don't blow up below. */
2164 || GET_CODE (XVECEXP (op
, 0, 0)) != SET
2165 || GET_CODE (SET_DEST (XVECEXP (op
, 0, 0))) != REG
2166 || GET_CODE (SET_SRC (XVECEXP (op
, 0, 0))) != MEM
)
2169 dest_regno
= REGNO (SET_DEST (XVECEXP (op
, 0, 0)));
2170 src_addr
= XEXP (SET_SRC (XVECEXP (op
, 0, 0)), 0);
2171 elt_mode
= GET_MODE (SET_DEST (XVECEXP (op
, 0, 0)));
2173 /* Check, is base, or base + displacement. */
2175 if (GET_CODE (src_addr
) == REG
)
2177 else if (GET_CODE (src_addr
) == PLUS
2178 && GET_CODE (XEXP (src_addr
, 0)) == REG
2179 && GET_CODE (XEXP (src_addr
, 1)) == CONST_INT
)
2181 off
= INTVAL (XEXP (src_addr
, 1));
2182 src_addr
= XEXP (src_addr
, 0);
2187 for (i
= 1; i
< count
; i
++)
2189 rtx elt
= XVECEXP (op
, 0, i
);
2191 if (GET_CODE (elt
) != SET
2192 || GET_CODE (SET_DEST (elt
)) != REG
2193 || GET_MODE (SET_DEST (elt
)) != elt_mode
2194 || REGNO (SET_DEST (elt
)) != dest_regno
+ i
2195 || GET_CODE (SET_SRC (elt
)) != MEM
2196 || GET_MODE (SET_SRC (elt
)) != elt_mode
2197 || GET_CODE (XEXP (SET_SRC (elt
), 0)) != PLUS
2198 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt
), 0), 0), src_addr
)
2199 || GET_CODE (XEXP (XEXP (SET_SRC (elt
), 0), 1)) != CONST_INT
2200 || INTVAL (XEXP (XEXP (SET_SRC (elt
), 0), 1))
2201 != off
+ i
* GET_MODE_SIZE (elt_mode
))
2208 /* Return true if OP is a store multiple operation. It is known to be a
2209 PARALLEL and the first section will be tested.
2210 OP is the current operation.
2211 MODE is the current operation mode. */
2214 store_multiple_operation (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
2216 enum machine_mode elt_mode
;
2217 int count
= XVECLEN (op
, 0);
2218 unsigned int src_regno
;
2222 /* Perform a quick check so we don't blow up below. */
2224 || GET_CODE (XVECEXP (op
, 0, 0)) != SET
2225 || GET_CODE (SET_DEST (XVECEXP (op
, 0, 0))) != MEM
2226 || GET_CODE (SET_SRC (XVECEXP (op
, 0, 0))) != REG
)
2229 src_regno
= REGNO (SET_SRC (XVECEXP (op
, 0, 0)));
2230 dest_addr
= XEXP (SET_DEST (XVECEXP (op
, 0, 0)), 0);
2231 elt_mode
= GET_MODE (SET_SRC (XVECEXP (op
, 0, 0)));
2233 /* Check, is base, or base + displacement. */
2235 if (GET_CODE (dest_addr
) == REG
)
2237 else if (GET_CODE (dest_addr
) == PLUS
2238 && GET_CODE (XEXP (dest_addr
, 0)) == REG
2239 && GET_CODE (XEXP (dest_addr
, 1)) == CONST_INT
)
2241 off
= INTVAL (XEXP (dest_addr
, 1));
2242 dest_addr
= XEXP (dest_addr
, 0);
2247 for (i
= 1; i
< count
; i
++)
2249 rtx elt
= XVECEXP (op
, 0, i
);
2251 if (GET_CODE (elt
) != SET
2252 || GET_CODE (SET_SRC (elt
)) != REG
2253 || GET_MODE (SET_SRC (elt
)) != elt_mode
2254 || REGNO (SET_SRC (elt
)) != src_regno
+ i
2255 || GET_CODE (SET_DEST (elt
)) != MEM
2256 || GET_MODE (SET_DEST (elt
)) != elt_mode
2257 || GET_CODE (XEXP (SET_DEST (elt
), 0)) != PLUS
2258 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt
), 0), 0), dest_addr
)
2259 || GET_CODE (XEXP (XEXP (SET_DEST (elt
), 0), 1)) != CONST_INT
2260 || INTVAL (XEXP (XEXP (SET_DEST (elt
), 0), 1))
2261 != off
+ i
* GET_MODE_SIZE (elt_mode
))
2267 /* Split DImode access register reference REG (on 64-bit) into its constituent
2268 low and high parts, and store them into LO and HI. Note that gen_lowpart/
2269 gen_highpart cannot be used as they assume all registers are word-sized,
2270 while our access registers have only half that size. */
2273 s390_split_access_reg (rtx reg
, rtx
*lo
, rtx
*hi
)
2275 gcc_assert (TARGET_64BIT
);
2276 gcc_assert (ACCESS_REG_P (reg
));
2277 gcc_assert (GET_MODE (reg
) == DImode
);
2278 gcc_assert (!(REGNO (reg
) & 1));
2280 *lo
= gen_rtx_REG (SImode
, REGNO (reg
) + 1);
2281 *hi
= gen_rtx_REG (SImode
, REGNO (reg
));
2284 /* Return true if OP contains a symbol reference */
2287 symbolic_reference_mentioned_p (rtx op
)
2289 register const char *fmt
;
2292 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
2295 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
2296 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
2302 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
2303 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
2307 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
2314 /* Return true if OP contains a reference to a thread-local symbol. */
2317 tls_symbolic_reference_mentioned_p (rtx op
)
2319 register const char *fmt
;
2322 if (GET_CODE (op
) == SYMBOL_REF
)
2323 return tls_symbolic_operand (op
);
2325 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
2326 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
2332 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
2333 if (tls_symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
2337 else if (fmt
[i
] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op
, i
)))
2345 /* Return true if OP is a legitimate general operand when
2346 generating PIC code. It is given that flag_pic is on
2347 and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2350 legitimate_pic_operand_p (register rtx op
)
2352 /* Accept all non-symbolic constants. */
2353 if (!SYMBOLIC_CONST (op
))
2356 /* Reject everything else; must be handled
2357 via emit_symbolic_move. */
2361 /* Returns true if the constant value OP is a legitimate general operand.
2362 It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
2365 legitimate_constant_p (register rtx op
)
2367 /* Accept all non-symbolic constants. */
2368 if (!SYMBOLIC_CONST (op
))
2371 /* Accept immediate LARL operands. */
2372 if (TARGET_CPU_ZARCH
&& larl_operand (op
, VOIDmode
))
2375 /* Thread-local symbols are never legal constants. This is
2376 so that emit_call knows that computing such addresses
2377 might require a function call. */
2378 if (TLS_SYMBOLIC_CONST (op
))
2381 /* In the PIC case, symbolic constants must *not* be
2382 forced into the literal pool. We accept them here,
2383 so that they will be handled by emit_symbolic_move. */
2387 /* All remaining non-PIC symbolic constants are
2388 forced into the literal pool. */
2392 /* Determine if it's legal to put X into the constant pool. This
2393 is not possible if X contains the address of a symbol that is
2394 not constant (TLS) or not known at final link time (PIC). */
2397 s390_cannot_force_const_mem (rtx x
)
2399 switch (GET_CODE (x
))
2403 /* Accept all non-symbolic constants. */
2407 /* Labels are OK iff we are non-PIC. */
2408 return flag_pic
!= 0;
2411 /* 'Naked' TLS symbol references are never OK,
2412 non-TLS symbols are OK iff we are non-PIC. */
2413 if (tls_symbolic_operand (x
))
2416 return flag_pic
!= 0;
2419 return s390_cannot_force_const_mem (XEXP (x
, 0));
2422 return s390_cannot_force_const_mem (XEXP (x
, 0))
2423 || s390_cannot_force_const_mem (XEXP (x
, 1));
2426 switch (XINT (x
, 1))
2428 /* Only lt-relative or GOT-relative UNSPECs are OK. */
2429 case UNSPEC_LTREL_OFFSET
:
2437 case UNSPEC_GOTNTPOFF
:
2438 case UNSPEC_INDNTPOFF
:
2441 /* If the literal pool shares the code section, be put
2442 execute template placeholders into the pool as well. */
2444 return TARGET_CPU_ZARCH
;
2456 /* Returns true if the constant value OP is a legitimate general
2457 operand during and after reload. The difference to
2458 legitimate_constant_p is that this function will not accept
2459 a constant that would need to be forced to the literal pool
2460 before it can be used as operand. */
2463 legitimate_reload_constant_p (register rtx op
)
2465 /* Accept la(y) operands. */
2466 if (GET_CODE (op
) == CONST_INT
2467 && DISP_IN_RANGE (INTVAL (op
)))
2470 /* Accept l(g)hi operands. */
2471 if (GET_CODE (op
) == CONST_INT
2472 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op
), 'K', "K"))
2475 /* Accept lliXX operands. */
2477 && s390_single_part (op
, DImode
, HImode
, 0) >= 0)
2480 /* Accept larl operands. */
2481 if (TARGET_CPU_ZARCH
2482 && larl_operand (op
, VOIDmode
))
2485 /* Everything else cannot be handled without reload. */
2489 /* Given an rtx OP being reloaded into a reg required to be in class CLASS,
2490 return the class of reg to actually use. */
2493 s390_preferred_reload_class (rtx op
, enum reg_class
class)
2495 switch (GET_CODE (op
))
2497 /* Constants we cannot reload must be forced into the
2502 if (legitimate_reload_constant_p (op
))
2507 /* If a symbolic constant or a PLUS is reloaded,
2508 it is most likely being used as an address, so
2509 prefer ADDR_REGS. If 'class' is not a superset
2510 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
2515 if (reg_class_subset_p (ADDR_REGS
, class))
2527 /* Return the register class of a scratch register needed to
2528 load IN into a register of class CLASS in MODE.
2530 We need a temporary when loading a PLUS expression which
2531 is not a legitimate operand of the LOAD ADDRESS instruction. */
2534 s390_secondary_input_reload_class (enum reg_class
class,
2535 enum machine_mode mode
, rtx in
)
2537 if (s390_plus_operand (in
, mode
))
2540 if (reg_classes_intersect_p (CC_REGS
, class))
2541 return GENERAL_REGS
;
2546 /* Return the register class of a scratch register needed to
2547 store a register of class CLASS in MODE into OUT:
2549 We need a temporary when storing a double-word to a
2550 non-offsettable memory address. */
2553 s390_secondary_output_reload_class (enum reg_class
class,
2554 enum machine_mode mode
, rtx out
)
2556 if ((TARGET_64BIT
? mode
== TImode
2557 : (mode
== DImode
|| mode
== DFmode
))
2558 && reg_classes_intersect_p (GENERAL_REGS
, class)
2559 && GET_CODE (out
) == MEM
2560 && !offsettable_memref_p (out
)
2561 && !s_operand (out
, VOIDmode
))
2564 if (reg_classes_intersect_p (CC_REGS
, class))
2565 return GENERAL_REGS
;
2570 /* Return true if OP is a PLUS that is not a legitimate
2571 operand for the LA instruction.
2572 OP is the current operation.
2573 MODE is the current operation mode. */
2576 s390_plus_operand (register rtx op
, enum machine_mode mode
)
2578 if (!check_mode (op
, &mode
) || mode
!= Pmode
)
2581 if (GET_CODE (op
) != PLUS
)
2584 if (legitimate_la_operand_p (op
))
2590 /* Generate code to load SRC, which is PLUS that is not a
2591 legitimate operand for the LA instruction, into TARGET.
2592 SCRATCH may be used as scratch register. */
2595 s390_expand_plus_operand (register rtx target
, register rtx src
,
2596 register rtx scratch
)
2599 struct s390_address ad
;
2601 /* src must be a PLUS; get its two operands. */
2602 if (GET_CODE (src
) != PLUS
|| GET_MODE (src
) != Pmode
)
2605 /* Check if any of the two operands is already scheduled
2606 for replacement by reload. This can happen e.g. when
2607 float registers occur in an address. */
2608 sum1
= find_replacement (&XEXP (src
, 0));
2609 sum2
= find_replacement (&XEXP (src
, 1));
2610 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
2612 /* If the address is already strictly valid, there's nothing to do. */
2613 if (!s390_decompose_address (src
, &ad
)
2614 || (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
2615 || (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
)))
2617 /* Otherwise, one of the operands cannot be an address register;
2618 we reload its value into the scratch register. */
2619 if (true_regnum (sum1
) < 1 || true_regnum (sum1
) > 15)
2621 emit_move_insn (scratch
, sum1
);
2624 if (true_regnum (sum2
) < 1 || true_regnum (sum2
) > 15)
2626 emit_move_insn (scratch
, sum2
);
2630 /* According to the way these invalid addresses are generated
2631 in reload.c, it should never happen (at least on s390) that
2632 *neither* of the PLUS components, after find_replacements
2633 was applied, is an address register. */
2634 if (sum1
== scratch
&& sum2
== scratch
)
2640 src
= gen_rtx_PLUS (Pmode
, sum1
, sum2
);
2643 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
2644 is only ever performed on addresses, so we can mark the
2645 sum as legitimate for LA in any case. */
2646 s390_load_address (target
, src
);
2650 /* Decompose a RTL expression ADDR for a memory address into
2651 its components, returned in OUT.
2653 Returns 0 if ADDR is not a valid memory address, nonzero
2654 otherwise. If OUT is NULL, don't return the components,
2655 but check for validity only.
2657 Note: Only addresses in canonical form are recognized.
2658 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
2659 canonical form so that they will be recognized. */
2662 s390_decompose_address (register rtx addr
, struct s390_address
*out
)
2664 HOST_WIDE_INT offset
= 0;
2665 rtx base
= NULL_RTX
;
2666 rtx indx
= NULL_RTX
;
2667 rtx disp
= NULL_RTX
;
2669 int pointer
= FALSE
;
2670 int base_ptr
= FALSE
;
2671 int indx_ptr
= FALSE
;
2673 /* Decompose address into base + index + displacement. */
2675 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == UNSPEC
)
2678 else if (GET_CODE (addr
) == PLUS
)
2680 rtx op0
= XEXP (addr
, 0);
2681 rtx op1
= XEXP (addr
, 1);
2682 enum rtx_code code0
= GET_CODE (op0
);
2683 enum rtx_code code1
= GET_CODE (op1
);
2685 if (code0
== REG
|| code0
== UNSPEC
)
2687 if (code1
== REG
|| code1
== UNSPEC
)
2689 indx
= op0
; /* index + base */
2695 base
= op0
; /* base + displacement */
2700 else if (code0
== PLUS
)
2702 indx
= XEXP (op0
, 0); /* index + base + disp */
2703 base
= XEXP (op0
, 1);
2714 disp
= addr
; /* displacement */
2716 /* Extract integer part of displacement. */
2720 if (GET_CODE (disp
) == CONST_INT
)
2722 offset
= INTVAL (disp
);
2725 else if (GET_CODE (disp
) == CONST
2726 && GET_CODE (XEXP (disp
, 0)) == PLUS
2727 && GET_CODE (XEXP (XEXP (disp
, 0), 1)) == CONST_INT
)
2729 offset
= INTVAL (XEXP (XEXP (disp
, 0), 1));
2730 disp
= XEXP (XEXP (disp
, 0), 0);
2734 /* Strip off CONST here to avoid special case tests later. */
2735 if (disp
&& GET_CODE (disp
) == CONST
)
2736 disp
= XEXP (disp
, 0);
2738 /* We can convert literal pool addresses to
2739 displacements by basing them off the base register. */
2740 if (disp
&& GET_CODE (disp
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (disp
))
2742 /* Either base or index must be free to hold the base register. */
2744 base
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
2746 indx
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
2750 /* Mark up the displacement. */
2751 disp
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, disp
),
2752 UNSPEC_LTREL_OFFSET
);
2755 /* Validate base register. */
2758 if (GET_CODE (base
) == UNSPEC
)
2759 switch (XINT (base
, 1))
2763 disp
= gen_rtx_UNSPEC (Pmode
,
2764 gen_rtvec (1, XVECEXP (base
, 0, 0)),
2765 UNSPEC_LTREL_OFFSET
);
2769 base
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
2772 case UNSPEC_LTREL_BASE
:
2773 base
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
2780 if (GET_CODE (base
) != REG
|| GET_MODE (base
) != Pmode
)
2783 if (REGNO (base
) == BASE_REGNUM
2784 || REGNO (base
) == STACK_POINTER_REGNUM
2785 || REGNO (base
) == FRAME_POINTER_REGNUM
2786 || ((reload_completed
|| reload_in_progress
)
2787 && frame_pointer_needed
2788 && REGNO (base
) == HARD_FRAME_POINTER_REGNUM
)
2789 || REGNO (base
) == ARG_POINTER_REGNUM
2791 && REGNO (base
) == PIC_OFFSET_TABLE_REGNUM
))
2792 pointer
= base_ptr
= TRUE
;
2795 /* Validate index register. */
2798 if (GET_CODE (indx
) == UNSPEC
)
2799 switch (XINT (indx
, 1))
2803 disp
= gen_rtx_UNSPEC (Pmode
,
2804 gen_rtvec (1, XVECEXP (indx
, 0, 0)),
2805 UNSPEC_LTREL_OFFSET
);
2809 indx
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
2812 case UNSPEC_LTREL_BASE
:
2813 indx
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
2820 if (GET_CODE (indx
) != REG
|| GET_MODE (indx
) != Pmode
)
2823 if (REGNO (indx
) == BASE_REGNUM
2824 || REGNO (indx
) == STACK_POINTER_REGNUM
2825 || REGNO (indx
) == FRAME_POINTER_REGNUM
2826 || ((reload_completed
|| reload_in_progress
)
2827 && frame_pointer_needed
2828 && REGNO (indx
) == HARD_FRAME_POINTER_REGNUM
)
2829 || REGNO (indx
) == ARG_POINTER_REGNUM
2831 && REGNO (indx
) == PIC_OFFSET_TABLE_REGNUM
))
2832 pointer
= indx_ptr
= TRUE
;
2835 /* Prefer to use pointer as base, not index. */
2836 if (base
&& indx
&& !base_ptr
2837 && (indx_ptr
|| (!REG_POINTER (base
) && REG_POINTER (indx
))))
2844 /* Validate displacement. */
2847 /* If the argument pointer or the return address pointer are involved,
2848 the displacement will change later anyway as the virtual registers get
2849 eliminated. This could make a valid displacement invalid, but it is
2850 more likely to make an invalid displacement valid, because we sometimes
2851 access the register save area via negative offsets to one of those
2853 Thus we don't check the displacement for validity here. If after
2854 elimination the displacement turns out to be invalid after all,
2855 this is fixed up by reload in any case. */
2856 if (base
!= arg_pointer_rtx
2857 && indx
!= arg_pointer_rtx
2858 && base
!= return_address_pointer_rtx
2859 && indx
!= return_address_pointer_rtx
)
2860 if (!DISP_IN_RANGE (offset
))
2865 /* All the special cases are pointers. */
2868 /* In the small-PIC case, the linker converts @GOT
2869 and @GOTNTPOFF offsets to possible displacements. */
2870 if (GET_CODE (disp
) == UNSPEC
2871 && (XINT (disp
, 1) == UNSPEC_GOT
2872 || XINT (disp
, 1) == UNSPEC_GOTNTPOFF
)
2879 /* Accept chunkified literal pool symbol references. */
2880 else if (GET_CODE (disp
) == MINUS
2881 && GET_CODE (XEXP (disp
, 0)) == LABEL_REF
2882 && GET_CODE (XEXP (disp
, 1)) == LABEL_REF
)
2887 /* Accept literal pool references. */
2888 else if (GET_CODE (disp
) == UNSPEC
2889 && XINT (disp
, 1) == UNSPEC_LTREL_OFFSET
)
2891 orig_disp
= gen_rtx_CONST (Pmode
, disp
);
2894 /* If we have an offset, make sure it does not
2895 exceed the size of the constant pool entry. */
2896 rtx sym
= XVECEXP (disp
, 0, 0);
2897 if (offset
>= GET_MODE_SIZE (get_pool_mode (sym
)))
2900 orig_disp
= plus_constant (orig_disp
, offset
);
2915 out
->disp
= orig_disp
;
2916 out
->pointer
= pointer
;
2922 /* Return nonzero if ADDR is a valid memory address.
2923 STRICT specifies whether strict register checking applies. */
2926 legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED
,
2927 register rtx addr
, int strict
)
2929 struct s390_address ad
;
2930 if (!s390_decompose_address (addr
, &ad
))
2935 if (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
2937 if (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
))
2942 if (ad
.base
&& !REG_OK_FOR_BASE_NONSTRICT_P (ad
.base
))
2944 if (ad
.indx
&& !REG_OK_FOR_INDEX_NONSTRICT_P (ad
.indx
))
2951 /* Return 1 if OP is a valid operand for the LA instruction.
2952 In 31-bit, we need to prove that the result is used as an
2953 address, as LA performs only a 31-bit addition. */
2956 legitimate_la_operand_p (register rtx op
)
2958 struct s390_address addr
;
2959 if (!s390_decompose_address (op
, &addr
))
2962 if (TARGET_64BIT
|| addr
.pointer
)
2968 /* Return 1 if it is valid *and* preferable to use LA to
2969 compute the sum of OP1 and OP2. */
2972 preferred_la_operand_p (rtx op1
, rtx op2
)
2974 struct s390_address addr
;
2976 if (op2
!= const0_rtx
)
2977 op1
= gen_rtx_PLUS (Pmode
, op1
, op2
);
2979 if (!s390_decompose_address (op1
, &addr
))
2981 if (addr
.base
&& !REG_OK_FOR_BASE_STRICT_P (addr
.base
))
2983 if (addr
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (addr
.indx
))
2986 if (!TARGET_64BIT
&& !addr
.pointer
)
2992 if ((addr
.base
&& REG_P (addr
.base
) && REG_POINTER (addr
.base
))
2993 || (addr
.indx
&& REG_P (addr
.indx
) && REG_POINTER (addr
.indx
)))
2999 /* Emit a forced load-address operation to load SRC into DST.
3000 This will use the LOAD ADDRESS instruction even in situations
3001 where legitimate_la_operand_p (SRC) returns false. */
3004 s390_load_address (rtx dst
, rtx src
)
3007 emit_move_insn (dst
, src
);
3009 emit_insn (gen_force_la_31 (dst
, src
));
3012 /* Return a legitimate reference for ORIG (an address) using the
3013 register REG. If REG is 0, a new pseudo is generated.
3015 There are two types of references that must be handled:
3017 1. Global data references must load the address from the GOT, via
3018 the PIC reg. An insn is emitted to do this load, and the reg is
3021 2. Static data references, constant pool addresses, and code labels
3022 compute the address as an offset from the GOT, whose base is in
3023 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
3024 differentiate them from global data objects. The returned
3025 address is the PIC reg + an unspec constant.
3027 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
3028 reg also appears in the address. */
3031 legitimize_pic_address (rtx orig
, rtx reg
)
3037 if (GET_CODE (addr
) == LABEL_REF
3038 || (GET_CODE (addr
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (addr
)))
3040 /* This is a local symbol. */
3041 if (TARGET_CPU_ZARCH
&& larl_operand (addr
, VOIDmode
))
3043 /* Access local symbols PC-relative via LARL.
3044 This is the same as in the non-PIC case, so it is
3045 handled automatically ... */
3049 /* Access local symbols relative to the GOT. */
3051 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
3053 if (reload_in_progress
|| reload_completed
)
3054 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
3056 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTOFF
);
3057 addr
= gen_rtx_CONST (Pmode
, addr
);
3058 addr
= force_const_mem (Pmode
, addr
);
3059 emit_move_insn (temp
, addr
);
3061 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
3064 s390_load_address (reg
, new);
3069 else if (GET_CODE (addr
) == SYMBOL_REF
)
3072 reg
= gen_reg_rtx (Pmode
);
3076 /* Assume GOT offset < 4k. This is handled the same way
3077 in both 31- and 64-bit code (@GOT). */
3079 if (reload_in_progress
|| reload_completed
)
3080 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
3082 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
3083 new = gen_rtx_CONST (Pmode
, new);
3084 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new);
3085 new = gen_const_mem (Pmode
, new);
3086 emit_move_insn (reg
, new);
3089 else if (TARGET_CPU_ZARCH
)
3091 /* If the GOT offset might be >= 4k, we determine the position
3092 of the GOT entry via a PC-relative LARL (@GOTENT). */
3094 rtx temp
= gen_reg_rtx (Pmode
);
3096 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTENT
);
3097 new = gen_rtx_CONST (Pmode
, new);
3098 emit_move_insn (temp
, new);
3100 new = gen_const_mem (Pmode
, temp
);
3101 emit_move_insn (reg
, new);
3106 /* If the GOT offset might be >= 4k, we have to load it
3107 from the literal pool (@GOT). */
3109 rtx temp
= gen_reg_rtx (Pmode
);
3111 if (reload_in_progress
|| reload_completed
)
3112 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
3114 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOT
);
3115 addr
= gen_rtx_CONST (Pmode
, addr
);
3116 addr
= force_const_mem (Pmode
, addr
);
3117 emit_move_insn (temp
, addr
);
3119 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
3120 new = gen_const_mem (Pmode
, new);
3121 emit_move_insn (reg
, new);
3127 if (GET_CODE (addr
) == CONST
)
3129 addr
= XEXP (addr
, 0);
3130 if (GET_CODE (addr
) == UNSPEC
)
3132 if (XVECLEN (addr
, 0) != 1)
3134 switch (XINT (addr
, 1))
3136 /* If someone moved a GOT-relative UNSPEC
3137 out of the literal pool, force them back in. */
3140 new = force_const_mem (Pmode
, orig
);
3143 /* @GOT is OK as is if small. */
3146 new = force_const_mem (Pmode
, orig
);
3149 /* @GOTENT is OK as is. */
3153 /* @PLT is OK as is on 64-bit, must be converted to
3154 GOT-relative @PLTOFF on 31-bit. */
3156 if (!TARGET_CPU_ZARCH
)
3158 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
3160 if (reload_in_progress
|| reload_completed
)
3161 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
3163 addr
= XVECEXP (addr
, 0, 0);
3164 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
),
3166 addr
= gen_rtx_CONST (Pmode
, addr
);
3167 addr
= force_const_mem (Pmode
, addr
);
3168 emit_move_insn (temp
, addr
);
3170 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
3173 s390_load_address (reg
, new);
3179 /* Everything else cannot happen. */
3184 else if (GET_CODE (addr
) != PLUS
)
3187 if (GET_CODE (addr
) == PLUS
)
3189 rtx op0
= XEXP (addr
, 0), op1
= XEXP (addr
, 1);
3190 /* Check first to see if this is a constant offset
3191 from a local symbol reference. */
3192 if ((GET_CODE (op0
) == LABEL_REF
3193 || (GET_CODE (op0
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (op0
)))
3194 && GET_CODE (op1
) == CONST_INT
)
3196 if (TARGET_CPU_ZARCH
&& larl_operand (op0
, VOIDmode
))
3198 if (INTVAL (op1
) & 1)
3200 /* LARL can't handle odd offsets, so emit a
3201 pair of LARL and LA. */
3202 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
3204 if (!DISP_IN_RANGE (INTVAL (op1
)))
3206 int even
= INTVAL (op1
) - 1;
3207 op0
= gen_rtx_PLUS (Pmode
, op0
, GEN_INT (even
));
3208 op0
= gen_rtx_CONST (Pmode
, op0
);
3212 emit_move_insn (temp
, op0
);
3213 new = gen_rtx_PLUS (Pmode
, temp
, op1
);
3217 s390_load_address (reg
, new);
3223 /* If the offset is even, we can just use LARL.
3224 This will happen automatically. */
3229 /* Access local symbols relative to the GOT. */
3231 rtx temp
= reg
? reg
: gen_reg_rtx (Pmode
);
3233 if (reload_in_progress
|| reload_completed
)
3234 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
3236 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op0
),
3238 addr
= gen_rtx_PLUS (Pmode
, addr
, op1
);
3239 addr
= gen_rtx_CONST (Pmode
, addr
);
3240 addr
= force_const_mem (Pmode
, addr
);
3241 emit_move_insn (temp
, addr
);
3243 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
3246 s390_load_address (reg
, new);
3252 /* Now, check whether it is a GOT relative symbol plus offset
3253 that was pulled out of the literal pool. Force it back in. */
3255 else if (GET_CODE (op0
) == UNSPEC
3256 && GET_CODE (op1
) == CONST_INT
3257 && XINT (op0
, 1) == UNSPEC_GOTOFF
)
3259 if (XVECLEN (op0
, 0) != 1)
3262 new = force_const_mem (Pmode
, orig
);
3265 /* Otherwise, compute the sum. */
3268 base
= legitimize_pic_address (XEXP (addr
, 0), reg
);
3269 new = legitimize_pic_address (XEXP (addr
, 1),
3270 base
== reg
? NULL_RTX
: reg
);
3271 if (GET_CODE (new) == CONST_INT
)
3272 new = plus_constant (base
, INTVAL (new));
3275 if (GET_CODE (new) == PLUS
&& CONSTANT_P (XEXP (new, 1)))
3277 base
= gen_rtx_PLUS (Pmode
, base
, XEXP (new, 0));
3278 new = XEXP (new, 1);
3280 new = gen_rtx_PLUS (Pmode
, base
, new);
3283 if (GET_CODE (new) == CONST
)
3284 new = XEXP (new, 0);
3285 new = force_operand (new, 0);
3292 /* Load the thread pointer into a register. */
3295 get_thread_pointer (void)
3297 rtx tp
= gen_reg_rtx (Pmode
);
3299 emit_move_insn (tp
, gen_rtx_REG (Pmode
, TP_REGNUM
));
3300 mark_reg_pointer (tp
, BITS_PER_WORD
);
3305 /* Emit a tls call insn. The call target is the SYMBOL_REF stored
3306 in s390_tls_symbol which always refers to __tls_get_offset.
3307 The returned offset is written to RESULT_REG and an USE rtx is
3308 generated for TLS_CALL. */
3310 static GTY(()) rtx s390_tls_symbol
;
3313 s390_emit_tls_call_insn (rtx result_reg
, rtx tls_call
)
3320 if (!s390_tls_symbol
)
3321 s390_tls_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "__tls_get_offset");
3323 insn
= s390_emit_call (s390_tls_symbol
, tls_call
, result_reg
,
3324 gen_rtx_REG (Pmode
, RETURN_REGNUM
));
3326 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), result_reg
);
3327 CONST_OR_PURE_CALL_P (insn
) = 1;
3330 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
3331 this (thread-local) address. REG may be used as temporary. */
3334 legitimize_tls_address (rtx addr
, rtx reg
)
3336 rtx
new, tls_call
, temp
, base
, r2
, insn
;
3338 if (GET_CODE (addr
) == SYMBOL_REF
)
3339 switch (tls_symbolic_operand (addr
))
3341 case TLS_MODEL_GLOBAL_DYNAMIC
:
3343 r2
= gen_rtx_REG (Pmode
, 2);
3344 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_TLSGD
);
3345 new = gen_rtx_CONST (Pmode
, tls_call
);
3346 new = force_const_mem (Pmode
, new);
3347 emit_move_insn (r2
, new);
3348 s390_emit_tls_call_insn (r2
, tls_call
);
3349 insn
= get_insns ();
3352 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
3353 temp
= gen_reg_rtx (Pmode
);
3354 emit_libcall_block (insn
, temp
, r2
, new);
3356 new = gen_rtx_PLUS (Pmode
, get_thread_pointer (), temp
);
3359 s390_load_address (reg
, new);
3364 case TLS_MODEL_LOCAL_DYNAMIC
:
3366 r2
= gen_rtx_REG (Pmode
, 2);
3367 tls_call
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM
);
3368 new = gen_rtx_CONST (Pmode
, tls_call
);
3369 new = force_const_mem (Pmode
, new);
3370 emit_move_insn (r2
, new);
3371 s390_emit_tls_call_insn (r2
, tls_call
);
3372 insn
= get_insns ();
3375 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
), UNSPEC_TLSLDM_NTPOFF
);
3376 temp
= gen_reg_rtx (Pmode
);
3377 emit_libcall_block (insn
, temp
, r2
, new);
3379 new = gen_rtx_PLUS (Pmode
, get_thread_pointer (), temp
);
3380 base
= gen_reg_rtx (Pmode
);
3381 s390_load_address (base
, new);
3383 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_DTPOFF
);
3384 new = gen_rtx_CONST (Pmode
, new);
3385 new = force_const_mem (Pmode
, new);
3386 temp
= gen_reg_rtx (Pmode
);
3387 emit_move_insn (temp
, new);
3389 new = gen_rtx_PLUS (Pmode
, base
, temp
);
3392 s390_load_address (reg
, new);
3397 case TLS_MODEL_INITIAL_EXEC
:
3400 /* Assume GOT offset < 4k. This is handled the same way
3401 in both 31- and 64-bit code. */
3403 if (reload_in_progress
|| reload_completed
)
3404 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
3406 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
3407 new = gen_rtx_CONST (Pmode
, new);
3408 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, new);
3409 new = gen_const_mem (Pmode
, new);
3410 temp
= gen_reg_rtx (Pmode
);
3411 emit_move_insn (temp
, new);
3413 else if (TARGET_CPU_ZARCH
)
3415 /* If the GOT offset might be >= 4k, we determine the position
3416 of the GOT entry via a PC-relative LARL. */
3418 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
3419 new = gen_rtx_CONST (Pmode
, new);
3420 temp
= gen_reg_rtx (Pmode
);
3421 emit_move_insn (temp
, new);
3423 new = gen_const_mem (Pmode
, temp
);
3424 temp
= gen_reg_rtx (Pmode
);
3425 emit_move_insn (temp
, new);
3429 /* If the GOT offset might be >= 4k, we have to load it
3430 from the literal pool. */
3432 if (reload_in_progress
|| reload_completed
)
3433 regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
] = 1;
3435 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_GOTNTPOFF
);
3436 new = gen_rtx_CONST (Pmode
, new);
3437 new = force_const_mem (Pmode
, new);
3438 temp
= gen_reg_rtx (Pmode
);
3439 emit_move_insn (temp
, new);
3441 new = gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, temp
);
3442 new = gen_const_mem (Pmode
, new);
3444 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new, addr
), UNSPEC_TLS_LOAD
);
3445 temp
= gen_reg_rtx (Pmode
);
3446 emit_insn (gen_rtx_SET (Pmode
, temp
, new));
3450 /* In position-dependent code, load the absolute address of
3451 the GOT entry from the literal pool. */
3453 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_INDNTPOFF
);
3454 new = gen_rtx_CONST (Pmode
, new);
3455 new = force_const_mem (Pmode
, new);
3456 temp
= gen_reg_rtx (Pmode
);
3457 emit_move_insn (temp
, new);
3460 new = gen_const_mem (Pmode
, new);
3461 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, new, addr
), UNSPEC_TLS_LOAD
);
3462 temp
= gen_reg_rtx (Pmode
);
3463 emit_insn (gen_rtx_SET (Pmode
, temp
, new));
3466 new = gen_rtx_PLUS (Pmode
, get_thread_pointer (), temp
);
3469 s390_load_address (reg
, new);
3474 case TLS_MODEL_LOCAL_EXEC
:
3475 new = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_NTPOFF
);
3476 new = gen_rtx_CONST (Pmode
, new);
3477 new = force_const_mem (Pmode
, new);
3478 temp
= gen_reg_rtx (Pmode
);
3479 emit_move_insn (temp
, new);
3481 new = gen_rtx_PLUS (Pmode
, get_thread_pointer (), temp
);
3484 s390_load_address (reg
, new);
3493 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == UNSPEC
)
3495 switch (XINT (XEXP (addr
, 0), 1))
3497 case UNSPEC_INDNTPOFF
:
3498 if (TARGET_CPU_ZARCH
)
3509 else if (GET_CODE (addr
) == CONST
&& GET_CODE (XEXP (addr
, 0)) == PLUS
3510 && GET_CODE (XEXP (XEXP (addr
, 0), 1)) == CONST_INT
)
3512 new = XEXP (XEXP (addr
, 0), 0);
3513 if (GET_CODE (new) != SYMBOL_REF
)
3514 new = gen_rtx_CONST (Pmode
, new);
3516 new = legitimize_tls_address (new, reg
);
3517 new = plus_constant (new, INTVAL (XEXP (XEXP (addr
, 0), 1)));
3518 new = force_operand (new, 0);
3522 abort (); /* for now ... */
3527 /* Emit insns to move operands[1] into operands[0]. */
3530 emit_symbolic_move (rtx
*operands
)
3532 rtx temp
= no_new_pseudos
? operands
[0] : gen_reg_rtx (Pmode
);
3534 if (GET_CODE (operands
[0]) == MEM
)
3535 operands
[1] = force_reg (Pmode
, operands
[1]);
3536 else if (TLS_SYMBOLIC_CONST (operands
[1]))
3537 operands
[1] = legitimize_tls_address (operands
[1], temp
);
3539 operands
[1] = legitimize_pic_address (operands
[1], temp
);
3542 /* Try machine-dependent ways of modifying an illegitimate address X
3543 to be legitimate. If we find one, return the new, valid address.
3545 OLDX is the address as it was before break_out_memory_refs was called.
3546 In some cases it is useful to look at this to decide what needs to be done.
3548 MODE is the mode of the operand pointed to by X.
3550 When -fpic is used, special handling is needed for symbolic references.
3551 See comments by legitimize_pic_address for details. */
3554 legitimize_address (register rtx x
, register rtx oldx ATTRIBUTE_UNUSED
,
3555 enum machine_mode mode ATTRIBUTE_UNUSED
)
3557 rtx constant_term
= const0_rtx
;
3559 if (TLS_SYMBOLIC_CONST (x
))
3561 x
= legitimize_tls_address (x
, 0);
3563 if (legitimate_address_p (mode
, x
, FALSE
))
3568 if (SYMBOLIC_CONST (x
)
3569 || (GET_CODE (x
) == PLUS
3570 && (SYMBOLIC_CONST (XEXP (x
, 0))
3571 || SYMBOLIC_CONST (XEXP (x
, 1)))))
3572 x
= legitimize_pic_address (x
, 0);
3574 if (legitimate_address_p (mode
, x
, FALSE
))
3578 x
= eliminate_constant_term (x
, &constant_term
);
3580 /* Optimize loading of large displacements by splitting them
3581 into the multiple of 4K and the rest; this allows the
3582 former to be CSE'd if possible.
3584 Don't do this if the displacement is added to a register
3585 pointing into the stack frame, as the offsets will
3586 change later anyway. */
3588 if (GET_CODE (constant_term
) == CONST_INT
3589 && !TARGET_LONG_DISPLACEMENT
3590 && !DISP_IN_RANGE (INTVAL (constant_term
))
3591 && !(REG_P (x
) && REGNO_PTR_FRAME_P (REGNO (x
))))
3593 HOST_WIDE_INT lower
= INTVAL (constant_term
) & 0xfff;
3594 HOST_WIDE_INT upper
= INTVAL (constant_term
) ^ lower
;
3596 rtx temp
= gen_reg_rtx (Pmode
);
3597 rtx val
= force_operand (GEN_INT (upper
), temp
);
3599 emit_move_insn (temp
, val
);
3601 x
= gen_rtx_PLUS (Pmode
, x
, temp
);
3602 constant_term
= GEN_INT (lower
);
3605 if (GET_CODE (x
) == PLUS
)
3607 if (GET_CODE (XEXP (x
, 0)) == REG
)
3609 register rtx temp
= gen_reg_rtx (Pmode
);
3610 register rtx val
= force_operand (XEXP (x
, 1), temp
);
3612 emit_move_insn (temp
, val
);
3614 x
= gen_rtx_PLUS (Pmode
, XEXP (x
, 0), temp
);
3617 else if (GET_CODE (XEXP (x
, 1)) == REG
)
3619 register rtx temp
= gen_reg_rtx (Pmode
);
3620 register rtx val
= force_operand (XEXP (x
, 0), temp
);
3622 emit_move_insn (temp
, val
);
3624 x
= gen_rtx_PLUS (Pmode
, temp
, XEXP (x
, 1));
3628 if (constant_term
!= const0_rtx
)
3629 x
= gen_rtx_PLUS (Pmode
, x
, constant_term
);
3634 /* Try a machine-dependent way of reloading an illegitimate address AD
3635 operand. If we find one, push the reload and and return the new address.
3637 MODE is the mode of the enclosing MEM. OPNUM is the operand number
3638 and TYPE is the reload type of the current reload. */
3641 legitimize_reload_address (rtx ad
, enum machine_mode mode ATTRIBUTE_UNUSED
,
3642 int opnum
, int type
)
3644 if (!optimize
|| TARGET_LONG_DISPLACEMENT
)
3647 if (GET_CODE (ad
) == PLUS
)
3649 rtx tem
= simplify_binary_operation (PLUS
, Pmode
,
3650 XEXP (ad
, 0), XEXP (ad
, 1));
3655 if (GET_CODE (ad
) == PLUS
3656 && GET_CODE (XEXP (ad
, 0)) == REG
3657 && GET_CODE (XEXP (ad
, 1)) == CONST_INT
3658 && !DISP_IN_RANGE (INTVAL (XEXP (ad
, 1))))
3660 HOST_WIDE_INT lower
= INTVAL (XEXP (ad
, 1)) & 0xfff;
3661 HOST_WIDE_INT upper
= INTVAL (XEXP (ad
, 1)) ^ lower
;
3664 cst
= GEN_INT (upper
);
3665 if (!legitimate_reload_constant_p (cst
))
3666 cst
= force_const_mem (Pmode
, cst
);
3668 tem
= gen_rtx_PLUS (Pmode
, XEXP (ad
, 0), cst
);
3669 new = gen_rtx_PLUS (Pmode
, tem
, GEN_INT (lower
));
3671 push_reload (XEXP (tem
, 1), 0, &XEXP (tem
, 1), 0,
3672 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
3673 opnum
, (enum reload_type
) type
);
3680 /* Emit code to move LEN bytes from DST to SRC. */
3683 s390_expand_movmem (rtx dst
, rtx src
, rtx len
)
3685 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3687 if (INTVAL (len
) > 0)
3688 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (INTVAL (len
) - 1)));
3691 else if (TARGET_MVCLE
)
3693 emit_insn (gen_movmem_long (dst
, src
, convert_to_mode (Pmode
, len
, 1)));
3698 rtx dst_addr
, src_addr
, count
, blocks
, temp
;
3699 rtx loop_start_label
= gen_label_rtx ();
3700 rtx loop_end_label
= gen_label_rtx ();
3701 rtx end_label
= gen_label_rtx ();
3702 enum machine_mode mode
;
3704 mode
= GET_MODE (len
);
3705 if (mode
== VOIDmode
)
3708 dst_addr
= gen_reg_rtx (Pmode
);
3709 src_addr
= gen_reg_rtx (Pmode
);
3710 count
= gen_reg_rtx (mode
);
3711 blocks
= gen_reg_rtx (mode
);
3713 convert_move (count
, len
, 1);
3714 emit_cmp_and_jump_insns (count
, const0_rtx
,
3715 EQ
, NULL_RTX
, mode
, 1, end_label
);
3717 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
3718 emit_move_insn (src_addr
, force_operand (XEXP (src
, 0), NULL_RTX
));
3719 dst
= change_address (dst
, VOIDmode
, dst_addr
);
3720 src
= change_address (src
, VOIDmode
, src_addr
);
3722 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3724 emit_move_insn (count
, temp
);
3726 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3728 emit_move_insn (blocks
, temp
);
3730 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3731 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3733 emit_label (loop_start_label
);
3735 emit_insn (gen_movmem_short (dst
, src
, GEN_INT (255)));
3736 s390_load_address (dst_addr
,
3737 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
3738 s390_load_address (src_addr
,
3739 gen_rtx_PLUS (Pmode
, src_addr
, GEN_INT (256)));
3741 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3743 emit_move_insn (blocks
, temp
);
3745 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3746 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3748 emit_jump (loop_start_label
);
3749 emit_label (loop_end_label
);
3751 emit_insn (gen_movmem_short (dst
, src
,
3752 convert_to_mode (Pmode
, count
, 1)));
3753 emit_label (end_label
);
3757 /* Emit code to clear LEN bytes at DST. */
3760 s390_expand_clrmem (rtx dst
, rtx len
)
3762 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3764 if (INTVAL (len
) > 0)
3765 emit_insn (gen_clrmem_short (dst
, GEN_INT (INTVAL (len
) - 1)));
3768 else if (TARGET_MVCLE
)
3770 emit_insn (gen_clrmem_long (dst
, convert_to_mode (Pmode
, len
, 1)));
3775 rtx dst_addr
, src_addr
, count
, blocks
, temp
;
3776 rtx loop_start_label
= gen_label_rtx ();
3777 rtx loop_end_label
= gen_label_rtx ();
3778 rtx end_label
= gen_label_rtx ();
3779 enum machine_mode mode
;
3781 mode
= GET_MODE (len
);
3782 if (mode
== VOIDmode
)
3785 dst_addr
= gen_reg_rtx (Pmode
);
3786 src_addr
= gen_reg_rtx (Pmode
);
3787 count
= gen_reg_rtx (mode
);
3788 blocks
= gen_reg_rtx (mode
);
3790 convert_move (count
, len
, 1);
3791 emit_cmp_and_jump_insns (count
, const0_rtx
,
3792 EQ
, NULL_RTX
, mode
, 1, end_label
);
3794 emit_move_insn (dst_addr
, force_operand (XEXP (dst
, 0), NULL_RTX
));
3795 dst
= change_address (dst
, VOIDmode
, dst_addr
);
3797 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3799 emit_move_insn (count
, temp
);
3801 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3803 emit_move_insn (blocks
, temp
);
3805 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3806 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3808 emit_label (loop_start_label
);
3810 emit_insn (gen_clrmem_short (dst
, GEN_INT (255)));
3811 s390_load_address (dst_addr
,
3812 gen_rtx_PLUS (Pmode
, dst_addr
, GEN_INT (256)));
3814 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3816 emit_move_insn (blocks
, temp
);
3818 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3819 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3821 emit_jump (loop_start_label
);
3822 emit_label (loop_end_label
);
3824 emit_insn (gen_clrmem_short (dst
, convert_to_mode (Pmode
, count
, 1)));
3825 emit_label (end_label
);
3829 /* Emit code to compare LEN bytes at OP0 with those at OP1,
3830 and return the result in TARGET. */
3833 s390_expand_cmpmem (rtx target
, rtx op0
, rtx op1
, rtx len
)
3835 rtx ccreg
= gen_rtx_REG (CCUmode
, CC_REGNUM
);
3838 /* As the result of CMPINT is inverted compared to what we need,
3839 we have to swap the operands. */
3840 tmp
= op0
; op0
= op1
; op1
= tmp
;
3842 if (GET_CODE (len
) == CONST_INT
&& INTVAL (len
) >= 0 && INTVAL (len
) <= 256)
3844 if (INTVAL (len
) > 0)
3846 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (INTVAL (len
) - 1)));
3847 emit_insn (gen_cmpint (target
, ccreg
));
3850 emit_move_insn (target
, const0_rtx
);
3852 else if (TARGET_MVCLE
)
3854 emit_insn (gen_cmpmem_long (op0
, op1
, convert_to_mode (Pmode
, len
, 1)));
3855 emit_insn (gen_cmpint (target
, ccreg
));
3859 rtx addr0
, addr1
, count
, blocks
, temp
;
3860 rtx loop_start_label
= gen_label_rtx ();
3861 rtx loop_end_label
= gen_label_rtx ();
3862 rtx end_label
= gen_label_rtx ();
3863 enum machine_mode mode
;
3865 mode
= GET_MODE (len
);
3866 if (mode
== VOIDmode
)
3869 addr0
= gen_reg_rtx (Pmode
);
3870 addr1
= gen_reg_rtx (Pmode
);
3871 count
= gen_reg_rtx (mode
);
3872 blocks
= gen_reg_rtx (mode
);
3874 convert_move (count
, len
, 1);
3875 emit_cmp_and_jump_insns (count
, const0_rtx
,
3876 EQ
, NULL_RTX
, mode
, 1, end_label
);
3878 emit_move_insn (addr0
, force_operand (XEXP (op0
, 0), NULL_RTX
));
3879 emit_move_insn (addr1
, force_operand (XEXP (op1
, 0), NULL_RTX
));
3880 op0
= change_address (op0
, VOIDmode
, addr0
);
3881 op1
= change_address (op1
, VOIDmode
, addr1
);
3883 temp
= expand_binop (mode
, add_optab
, count
, constm1_rtx
, count
, 1, 0);
3885 emit_move_insn (count
, temp
);
3887 temp
= expand_binop (mode
, ashr_optab
, count
, GEN_INT (8), blocks
, 1, 0);
3889 emit_move_insn (blocks
, temp
);
3891 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3892 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3894 emit_label (loop_start_label
);
3896 emit_insn (gen_cmpmem_short (op0
, op1
, GEN_INT (255)));
3897 temp
= gen_rtx_NE (VOIDmode
, ccreg
, const0_rtx
);
3898 temp
= gen_rtx_IF_THEN_ELSE (VOIDmode
, temp
,
3899 gen_rtx_LABEL_REF (VOIDmode
, end_label
), pc_rtx
);
3900 temp
= gen_rtx_SET (VOIDmode
, pc_rtx
, temp
);
3901 emit_jump_insn (temp
);
3903 s390_load_address (addr0
,
3904 gen_rtx_PLUS (Pmode
, addr0
, GEN_INT (256)));
3905 s390_load_address (addr1
,
3906 gen_rtx_PLUS (Pmode
, addr1
, GEN_INT (256)));
3908 temp
= expand_binop (mode
, add_optab
, blocks
, constm1_rtx
, blocks
, 1, 0);
3910 emit_move_insn (blocks
, temp
);
3912 emit_cmp_and_jump_insns (blocks
, const0_rtx
,
3913 EQ
, NULL_RTX
, mode
, 1, loop_end_label
);
3915 emit_jump (loop_start_label
);
3916 emit_label (loop_end_label
);
3918 emit_insn (gen_cmpmem_short (op0
, op1
,
3919 convert_to_mode (Pmode
, count
, 1)));
3920 emit_label (end_label
);
3922 emit_insn (gen_cmpint (target
, ccreg
));
3927 /* Expand conditional increment or decrement using alc/slb instructions.
3928 Should generate code setting DST to either SRC or SRC + INCREMENT,
3929 depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
3930 Returns true if successful, false otherwise.
3932 That makes it possible to implement some if-constructs without jumps e.g.:
3933 (borrow = CC0 | CC1 and carry = CC2 | CC3)
3934 unsigned int a, b, c;
3935 if (a < b) c++; -> CCU b > a -> CC2; c += carry;
3936 if (a < b) c--; -> CCL3 a - b -> borrow; c -= borrow;
3937 if (a <= b) c++; -> CCL3 b - a -> borrow; c += carry;
3938 if (a <= b) c--; -> CCU a <= b -> borrow; c -= borrow;
3940 Checks for EQ and NE with a nonzero value need an additional xor e.g.:
3941 if (a == b) c++; -> CCL3 a ^= b; 0 - a -> borrow; c += carry;
3942 if (a == b) c--; -> CCU a ^= b; a <= 0 -> CC0 | CC1; c -= borrow;
3943 if (a != b) c++; -> CCU a ^= b; a > 0 -> CC2; c += carry;
3944 if (a != b) c--; -> CCL3 a ^= b; 0 - a -> borrow; c -= borrow; */
3947 s390_expand_addcc (enum rtx_code cmp_code
, rtx cmp_op0
, rtx cmp_op1
,
3948 rtx dst
, rtx src
, rtx increment
)
3950 enum machine_mode cmp_mode
;
3951 enum machine_mode cc_mode
;
3956 if ((GET_MODE (cmp_op0
) == SImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
3957 && (GET_MODE (cmp_op1
) == SImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
3959 else if ((GET_MODE (cmp_op0
) == DImode
|| GET_MODE (cmp_op0
) == VOIDmode
)
3960 && (GET_MODE (cmp_op1
) == DImode
|| GET_MODE (cmp_op1
) == VOIDmode
))
3965 /* Try ADD LOGICAL WITH CARRY. */
3966 if (increment
== const1_rtx
)
3968 /* Determine CC mode to use. */
3969 if (cmp_code
== EQ
|| cmp_code
== NE
)
3971 if (cmp_op1
!= const0_rtx
)
3973 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
3974 NULL_RTX
, 0, OPTAB_WIDEN
);
3975 cmp_op1
= const0_rtx
;
3978 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
3981 if (cmp_code
== LTU
|| cmp_code
== LEU
)
3986 cmp_code
= swap_condition (cmp_code
);
4003 /* Emit comparison instruction pattern. */
4004 if (!register_operand (cmp_op0
, cmp_mode
))
4005 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
4007 insn
= gen_rtx_SET (VOIDmode
, gen_rtx_REG (cc_mode
, CC_REGNUM
),
4008 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
4009 /* We use insn_invalid_p here to add clobbers if required. */
4010 if (insn_invalid_p (emit_insn (insn
)))
4013 /* Emit ALC instruction pattern. */
4014 op_res
= gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
4015 gen_rtx_REG (cc_mode
, CC_REGNUM
),
4018 if (src
!= const0_rtx
)
4020 if (!register_operand (src
, GET_MODE (dst
)))
4021 src
= force_reg (GET_MODE (dst
), src
);
4023 src
= gen_rtx_PLUS (GET_MODE (dst
), src
, const0_rtx
);
4024 op_res
= gen_rtx_PLUS (GET_MODE (dst
), src
, op_res
);
4027 p
= rtvec_alloc (2);
4029 gen_rtx_SET (VOIDmode
, dst
, op_res
);
4031 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
4032 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
4037 /* Try SUBTRACT LOGICAL WITH BORROW. */
4038 if (increment
== constm1_rtx
)
4040 /* Determine CC mode to use. */
4041 if (cmp_code
== EQ
|| cmp_code
== NE
)
4043 if (cmp_op1
!= const0_rtx
)
4045 cmp_op0
= expand_simple_binop (cmp_mode
, XOR
, cmp_op0
, cmp_op1
,
4046 NULL_RTX
, 0, OPTAB_WIDEN
);
4047 cmp_op1
= const0_rtx
;
4050 cmp_code
= cmp_code
== EQ
? LEU
: GTU
;
4053 if (cmp_code
== GTU
|| cmp_code
== GEU
)
4058 cmp_code
= swap_condition (cmp_code
);
4075 /* Emit comparison instruction pattern. */
4076 if (!register_operand (cmp_op0
, cmp_mode
))
4077 cmp_op0
= force_reg (cmp_mode
, cmp_op0
);
4079 insn
= gen_rtx_SET (VOIDmode
, gen_rtx_REG (cc_mode
, CC_REGNUM
),
4080 gen_rtx_COMPARE (cc_mode
, cmp_op0
, cmp_op1
));
4081 /* We use insn_invalid_p here to add clobbers if required. */
4082 if (insn_invalid_p (emit_insn (insn
)))
4085 /* Emit SLB instruction pattern. */
4086 if (!register_operand (src
, GET_MODE (dst
)))
4087 src
= force_reg (GET_MODE (dst
), src
);
4089 op_res
= gen_rtx_MINUS (GET_MODE (dst
),
4090 gen_rtx_MINUS (GET_MODE (dst
), src
, const0_rtx
),
4091 gen_rtx_fmt_ee (cmp_code
, GET_MODE (dst
),
4092 gen_rtx_REG (cc_mode
, CC_REGNUM
),
4094 p
= rtvec_alloc (2);
4096 gen_rtx_SET (VOIDmode
, dst
, op_res
);
4098 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (CCmode
, CC_REGNUM
));
4099 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
4108 /* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
4109 We need to emit DTP-relative relocations. */
4112 s390_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
4117 fputs ("\t.long\t", file
);
4120 fputs ("\t.quad\t", file
);
4125 output_addr_const (file
, x
);
4126 fputs ("@DTPOFF", file
);
4129 /* In the name of slightly smaller debug output, and to cater to
4130 general assembler losage, recognize various UNSPEC sequences
4131 and turn them back into a direct symbol reference. */
4134 s390_delegitimize_address (rtx orig_x
)
4138 if (GET_CODE (x
) != MEM
)
4142 if (GET_CODE (x
) == PLUS
4143 && GET_CODE (XEXP (x
, 1)) == CONST
4144 && GET_CODE (XEXP (x
, 0)) == REG
4145 && REGNO (XEXP (x
, 0)) == PIC_OFFSET_TABLE_REGNUM
)
4147 y
= XEXP (XEXP (x
, 1), 0);
4148 if (GET_CODE (y
) == UNSPEC
4149 && XINT (y
, 1) == UNSPEC_GOT
)
4150 return XVECEXP (y
, 0, 0);
4154 if (GET_CODE (x
) == CONST
)
4157 if (GET_CODE (y
) == UNSPEC
4158 && XINT (y
, 1) == UNSPEC_GOTENT
)
4159 return XVECEXP (y
, 0, 0);
4166 /* Output shift count operand OP to stdio stream FILE. */
4169 print_shift_count_operand (FILE *file
, rtx op
)
4171 HOST_WIDE_INT offset
= 0;
4173 /* We can have an integer constant, an address register,
4174 or a sum of the two. */
4175 if (GET_CODE (op
) == CONST_INT
)
4177 offset
= INTVAL (op
);
4180 if (op
&& GET_CODE (op
) == PLUS
&& GET_CODE (XEXP (op
, 1)) == CONST_INT
)
4182 offset
= INTVAL (XEXP (op
, 1));
4185 while (op
&& GET_CODE (op
) == SUBREG
)
4186 op
= SUBREG_REG (op
);
4189 if (op
&& (GET_CODE (op
) != REG
4190 || REGNO (op
) >= FIRST_PSEUDO_REGISTER
4191 || REGNO_REG_CLASS (REGNO (op
)) != ADDR_REGS
))
4194 /* Shift counts are truncated to the low six bits anyway. */
4195 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
& 63);
4197 fprintf (file
, "(%s)", reg_names
[REGNO (op
)]);
4200 /* Locate some local-dynamic symbol still in use by this function
4201 so that we can print its name in local-dynamic base patterns. */
4204 get_some_local_dynamic_name (void)
4208 if (cfun
->machine
->some_ld_name
)
4209 return cfun
->machine
->some_ld_name
;
4211 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
4213 && for_each_rtx (&PATTERN (insn
), get_some_local_dynamic_name_1
, 0))
4214 return cfun
->machine
->some_ld_name
;
4220 get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
4224 if (GET_CODE (x
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (x
))
4226 x
= get_pool_constant (x
);
4227 return for_each_rtx (&x
, get_some_local_dynamic_name_1
, 0);
4230 if (GET_CODE (x
) == SYMBOL_REF
4231 && tls_symbolic_operand (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
4233 cfun
->machine
->some_ld_name
= XSTR (x
, 0);
4240 /* Output machine-dependent UNSPECs occurring in address constant X
4241 in assembler syntax to stdio stream FILE. Returns true if the
4242 constant X could be recognized, false otherwise. */
4245 s390_output_addr_const_extra (FILE *file
, rtx x
)
4247 if (GET_CODE (x
) == UNSPEC
&& XVECLEN (x
, 0) == 1)
4248 switch (XINT (x
, 1))
4251 output_addr_const (file
, XVECEXP (x
, 0, 0));
4252 fprintf (file
, "@GOTENT");
4255 output_addr_const (file
, XVECEXP (x
, 0, 0));
4256 fprintf (file
, "@GOT");
4259 output_addr_const (file
, XVECEXP (x
, 0, 0));
4260 fprintf (file
, "@GOTOFF");
4263 output_addr_const (file
, XVECEXP (x
, 0, 0));
4264 fprintf (file
, "@PLT");
4267 output_addr_const (file
, XVECEXP (x
, 0, 0));
4268 fprintf (file
, "@PLTOFF");
4271 output_addr_const (file
, XVECEXP (x
, 0, 0));
4272 fprintf (file
, "@TLSGD");
4275 assemble_name (file
, get_some_local_dynamic_name ());
4276 fprintf (file
, "@TLSLDM");
4279 output_addr_const (file
, XVECEXP (x
, 0, 0));
4280 fprintf (file
, "@DTPOFF");
4283 output_addr_const (file
, XVECEXP (x
, 0, 0));
4284 fprintf (file
, "@NTPOFF");
4286 case UNSPEC_GOTNTPOFF
:
4287 output_addr_const (file
, XVECEXP (x
, 0, 0));
4288 fprintf (file
, "@GOTNTPOFF");
4290 case UNSPEC_INDNTPOFF
:
4291 output_addr_const (file
, XVECEXP (x
, 0, 0));
4292 fprintf (file
, "@INDNTPOFF");
4299 /* Output address operand ADDR in assembler syntax to
4300 stdio stream FILE. */
4303 print_operand_address (FILE *file
, rtx addr
)
4305 struct s390_address ad
;
4307 if (!s390_decompose_address (addr
, &ad
)
4308 || (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
4309 || (ad
.indx
&& !REG_OK_FOR_INDEX_STRICT_P (ad
.indx
)))
4310 output_operand_lossage ("Cannot decompose address.");
4313 output_addr_const (file
, ad
.disp
);
4315 fprintf (file
, "0");
4317 if (ad
.base
&& ad
.indx
)
4318 fprintf (file
, "(%s,%s)", reg_names
[REGNO (ad
.indx
)],
4319 reg_names
[REGNO (ad
.base
)]);
4321 fprintf (file
, "(%s)", reg_names
[REGNO (ad
.base
)]);
4324 /* Output operand X in assembler syntax to stdio stream FILE.
4325 CODE specified the format flag. The following format flags
4328 'C': print opcode suffix for branch condition.
4329 'D': print opcode suffix for inverse branch condition.
4330 'J': print tls_load/tls_gdcall/tls_ldcall suffix
4331 'O': print only the displacement of a memory reference.
4332 'R': print only the base register of a memory reference.
4333 'S': print S-type memory reference (base+displacement).
4334 'N': print the second word of a DImode operand.
4335 'M': print the second word of a TImode operand.
4336 'Y': print shift count operand.
4338 'b': print integer X as if it's an unsigned byte.
4339 'x': print integer X as if it's an unsigned word.
4340 'h': print integer X as if it's a signed word.
4341 'i': print the first nonzero HImode part of X.
4342 'j': print the first HImode part unequal to 0xffff of X. */
4345 print_operand (FILE *file
, rtx x
, int code
)
4350 fprintf (file
, s390_branch_condition_mnemonic (x
, FALSE
));
4354 fprintf (file
, s390_branch_condition_mnemonic (x
, TRUE
));
4358 if (GET_CODE (x
) == SYMBOL_REF
)
4360 fprintf (file
, "%s", ":tls_load:");
4361 output_addr_const (file
, x
);
4363 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSGD
)
4365 fprintf (file
, "%s", ":tls_gdcall:");
4366 output_addr_const (file
, XVECEXP (x
, 0, 0));
4368 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSLDM
)
4370 fprintf (file
, "%s", ":tls_ldcall:");
4371 assemble_name (file
, get_some_local_dynamic_name ());
4379 struct s390_address ad
;
4381 if (GET_CODE (x
) != MEM
4382 || !s390_decompose_address (XEXP (x
, 0), &ad
)
4383 || (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
4388 output_addr_const (file
, ad
.disp
);
4390 fprintf (file
, "0");
4396 struct s390_address ad
;
4398 if (GET_CODE (x
) != MEM
4399 || !s390_decompose_address (XEXP (x
, 0), &ad
)
4400 || (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
4405 fprintf (file
, "%s", reg_names
[REGNO (ad
.base
)]);
4407 fprintf (file
, "0");
4413 struct s390_address ad
;
4415 if (GET_CODE (x
) != MEM
4416 || !s390_decompose_address (XEXP (x
, 0), &ad
)
4417 || (ad
.base
&& !REG_OK_FOR_BASE_STRICT_P (ad
.base
))
4422 output_addr_const (file
, ad
.disp
);
4424 fprintf (file
, "0");
4427 fprintf (file
, "(%s)", reg_names
[REGNO (ad
.base
)]);
4432 if (GET_CODE (x
) == REG
)
4433 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
4434 else if (GET_CODE (x
) == MEM
)
4435 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 4));
4441 if (GET_CODE (x
) == REG
)
4442 x
= gen_rtx_REG (GET_MODE (x
), REGNO (x
) + 1);
4443 else if (GET_CODE (x
) == MEM
)
4444 x
= change_address (x
, VOIDmode
, plus_constant (XEXP (x
, 0), 8));
4450 print_shift_count_operand (file
, x
);
4454 switch (GET_CODE (x
))
4457 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
4461 output_address (XEXP (x
, 0));
4468 output_addr_const (file
, x
);
4473 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xff);
4474 else if (code
== 'x')
4475 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0xffff);
4476 else if (code
== 'h')
4477 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((INTVAL (x
) & 0xffff) ^ 0x8000) - 0x8000);
4478 else if (code
== 'i')
4479 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
4480 s390_extract_part (x
, HImode
, 0));
4481 else if (code
== 'j')
4482 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
4483 s390_extract_part (x
, HImode
, -1));
4485 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
4489 if (GET_MODE (x
) != VOIDmode
)
4492 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xff);
4493 else if (code
== 'x')
4494 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
) & 0xffff);
4495 else if (code
== 'h')
4496 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ((CONST_DOUBLE_LOW (x
) & 0xffff) ^ 0x8000) - 0x8000);
4502 fatal_insn ("UNKNOWN in print_operand !?", x
);
4507 /* Target hook for assembling integer objects. We need to define it
4508 here to work a round a bug in some versions of GAS, which couldn't
4509 handle values smaller than INT_MIN when printed in decimal. */
4512 s390_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
4514 if (size
== 8 && aligned_p
4515 && GET_CODE (x
) == CONST_INT
&& INTVAL (x
) < INT_MIN
)
4517 fprintf (asm_out_file
, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX
"\n",
4521 return default_assemble_integer (x
, size
, aligned_p
);
4524 /* Returns true if register REGNO is used for forming
4525 a memory address in expression X. */
4528 reg_used_in_mem_p (int regno
, rtx x
)
4530 enum rtx_code code
= GET_CODE (x
);
4536 if (refers_to_regno_p (regno
, regno
+1,
4540 else if (code
== SET
4541 && GET_CODE (SET_DEST (x
)) == PC
)
4543 if (refers_to_regno_p (regno
, regno
+1,
4548 fmt
= GET_RTX_FORMAT (code
);
4549 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
4552 && reg_used_in_mem_p (regno
, XEXP (x
, i
)))
4555 else if (fmt
[i
] == 'E')
4556 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
4557 if (reg_used_in_mem_p (regno
, XVECEXP (x
, i
, j
)))
4563 /* Returns true if expression DEP_RTX sets an address register
4564 used by instruction INSN to address memory. */
4567 addr_generation_dependency_p (rtx dep_rtx
, rtx insn
)
4571 if (GET_CODE (dep_rtx
) == INSN
)
4572 dep_rtx
= PATTERN (dep_rtx
);
4574 if (GET_CODE (dep_rtx
) == SET
)
4576 target
= SET_DEST (dep_rtx
);
4577 if (GET_CODE (target
) == STRICT_LOW_PART
)
4578 target
= XEXP (target
, 0);
4579 while (GET_CODE (target
) == SUBREG
)
4580 target
= SUBREG_REG (target
);
4582 if (GET_CODE (target
) == REG
)
4584 int regno
= REGNO (target
);
4586 if (s390_safe_attr_type (insn
) == TYPE_LA
)
4588 pat
= PATTERN (insn
);
4589 if (GET_CODE (pat
) == PARALLEL
)
4591 if (XVECLEN (pat
, 0) != 2)
4593 pat
= XVECEXP (pat
, 0, 0);
4595 if (GET_CODE (pat
) == SET
)
4596 return refers_to_regno_p (regno
, regno
+1, SET_SRC (pat
), 0);
4600 else if (get_attr_atype (insn
) == ATYPE_AGEN
)
4601 return reg_used_in_mem_p (regno
, PATTERN (insn
));
4607 /* Return 1, if dep_insn sets register used in insn in the agen unit. */
4610 s390_agen_dep_p (rtx dep_insn
, rtx insn
)
4612 rtx dep_rtx
= PATTERN (dep_insn
);
4615 if (GET_CODE (dep_rtx
) == SET
4616 && addr_generation_dependency_p (dep_rtx
, insn
))
4618 else if (GET_CODE (dep_rtx
) == PARALLEL
)
4620 for (i
= 0; i
< XVECLEN (dep_rtx
, 0); i
++)
4622 if (addr_generation_dependency_p (XVECEXP (dep_rtx
, 0, i
), insn
))
4629 /* A C statement (sans semicolon) to update the integer scheduling priority
4630 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
4631 reduce the priority to execute INSN later. Do not define this macro if
4632 you do not need to adjust the scheduling priorities of insns.
4634 A STD instruction should be scheduled earlier,
4635 in order to use the bypass. */
4638 s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
4640 if (! INSN_P (insn
))
4643 if (s390_tune
!= PROCESSOR_2084_Z990
)
4646 switch (s390_safe_attr_type (insn
))
4650 priority
= priority
<< 3;
4654 priority
= priority
<< 1;
4662 /* The number of instructions that can be issued per cycle. */
4665 s390_issue_rate (void)
4667 if (s390_tune
== PROCESSOR_2084_Z990
)
4673 s390_first_cycle_multipass_dfa_lookahead (void)
4679 /* Split all branches that exceed the maximum distance.
4680 Returns true if this created a new literal pool entry. */
4683 s390_split_branches (void)
4685 rtx temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
4686 int new_literal
= 0;
4687 rtx insn
, pat
, tmp
, target
;
4690 /* We need correct insn addresses. */
4692 shorten_branches (get_insns ());
4694 /* Find all branches that exceed 64KB, and split them. */
4696 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
4698 if (GET_CODE (insn
) != JUMP_INSN
)
4701 pat
= PATTERN (insn
);
4702 if (GET_CODE (pat
) == PARALLEL
&& XVECLEN (pat
, 0) > 2)
4703 pat
= XVECEXP (pat
, 0, 0);
4704 if (GET_CODE (pat
) != SET
|| SET_DEST (pat
) != pc_rtx
)
4707 if (GET_CODE (SET_SRC (pat
)) == LABEL_REF
)
4709 label
= &SET_SRC (pat
);
4711 else if (GET_CODE (SET_SRC (pat
)) == IF_THEN_ELSE
)
4713 if (GET_CODE (XEXP (SET_SRC (pat
), 1)) == LABEL_REF
)
4714 label
= &XEXP (SET_SRC (pat
), 1);
4715 else if (GET_CODE (XEXP (SET_SRC (pat
), 2)) == LABEL_REF
)
4716 label
= &XEXP (SET_SRC (pat
), 2);
4723 if (get_attr_length (insn
) <= 4)
4726 /* We are going to use the return register as scratch register,
4727 make sure it will be saved/restored by the prologue/epilogue. */
4728 cfun_frame_layout
.save_return_addr_p
= 1;
4733 tmp
= force_const_mem (Pmode
, *label
);
4734 tmp
= emit_insn_before (gen_rtx_SET (Pmode
, temp_reg
, tmp
), insn
);
4735 INSN_ADDRESSES_NEW (tmp
, -1);
4736 annotate_constant_pool_refs (&PATTERN (tmp
));
4743 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, *label
),
4744 UNSPEC_LTREL_OFFSET
);
4745 target
= gen_rtx_CONST (Pmode
, target
);
4746 target
= force_const_mem (Pmode
, target
);
4747 tmp
= emit_insn_before (gen_rtx_SET (Pmode
, temp_reg
, target
), insn
);
4748 INSN_ADDRESSES_NEW (tmp
, -1);
4749 annotate_constant_pool_refs (&PATTERN (tmp
));
4751 target
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XEXP (target
, 0),
4752 cfun
->machine
->base_reg
),
4754 target
= gen_rtx_PLUS (Pmode
, temp_reg
, target
);
4757 if (!validate_change (insn
, label
, target
, 0))
4764 /* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
4765 Fix up MEMs as required. */
4768 annotate_constant_pool_refs (rtx
*x
)
4773 if (GET_CODE (*x
) == SYMBOL_REF
4774 && CONSTANT_POOL_ADDRESS_P (*x
))
4777 /* Literal pool references can only occur inside a MEM ... */
4778 if (GET_CODE (*x
) == MEM
)
4780 rtx memref
= XEXP (*x
, 0);
4782 if (GET_CODE (memref
) == SYMBOL_REF
4783 && CONSTANT_POOL_ADDRESS_P (memref
))
4785 rtx base
= cfun
->machine
->base_reg
;
4786 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, memref
, base
),
4789 *x
= replace_equiv_address (*x
, addr
);
4793 if (GET_CODE (memref
) == CONST
4794 && GET_CODE (XEXP (memref
, 0)) == PLUS
4795 && GET_CODE (XEXP (XEXP (memref
, 0), 1)) == CONST_INT
4796 && GET_CODE (XEXP (XEXP (memref
, 0), 0)) == SYMBOL_REF
4797 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (memref
, 0), 0)))
4799 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (memref
, 0), 1));
4800 rtx sym
= XEXP (XEXP (memref
, 0), 0);
4801 rtx base
= cfun
->machine
->base_reg
;
4802 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
4805 *x
= replace_equiv_address (*x
, plus_constant (addr
, off
));
4810 /* ... or a load-address type pattern. */
4811 if (GET_CODE (*x
) == SET
)
4813 rtx addrref
= SET_SRC (*x
);
4815 if (GET_CODE (addrref
) == SYMBOL_REF
4816 && CONSTANT_POOL_ADDRESS_P (addrref
))
4818 rtx base
= cfun
->machine
->base_reg
;
4819 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, addrref
, base
),
4822 SET_SRC (*x
) = addr
;
4826 if (GET_CODE (addrref
) == CONST
4827 && GET_CODE (XEXP (addrref
, 0)) == PLUS
4828 && GET_CODE (XEXP (XEXP (addrref
, 0), 1)) == CONST_INT
4829 && GET_CODE (XEXP (XEXP (addrref
, 0), 0)) == SYMBOL_REF
4830 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (addrref
, 0), 0)))
4832 HOST_WIDE_INT off
= INTVAL (XEXP (XEXP (addrref
, 0), 1));
4833 rtx sym
= XEXP (XEXP (addrref
, 0), 0);
4834 rtx base
= cfun
->machine
->base_reg
;
4835 rtx addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, sym
, base
),
4838 SET_SRC (*x
) = plus_constant (addr
, off
);
4843 /* Annotate LTREL_BASE as well. */
4844 if (GET_CODE (*x
) == UNSPEC
4845 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
4847 rtx base
= cfun
->machine
->base_reg
;
4848 *x
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (2, XVECEXP (*x
, 0, 0), base
),
4853 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
4854 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
4858 annotate_constant_pool_refs (&XEXP (*x
, i
));
4860 else if (fmt
[i
] == 'E')
4862 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
4863 annotate_constant_pool_refs (&XVECEXP (*x
, i
, j
));
4869 /* Find an annotated literal pool symbol referenced in RTX X,
4870 and store it at REF. Will abort if X contains references to
4871 more than one such pool symbol; multiple references to the same
4872 symbol are allowed, however.
4874 The rtx pointed to by REF must be initialized to NULL_RTX
4875 by the caller before calling this routine. */
4878 find_constant_pool_ref (rtx x
, rtx
*ref
)
4883 /* Ignore LTREL_BASE references. */
4884 if (GET_CODE (x
) == UNSPEC
4885 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
4887 /* Likewise POOL_ENTRY insns. */
4888 if (GET_CODE (x
) == UNSPEC_VOLATILE
4889 && XINT (x
, 1) == UNSPECV_POOL_ENTRY
)
4892 if (GET_CODE (x
) == SYMBOL_REF
4893 && CONSTANT_POOL_ADDRESS_P (x
))
4896 if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_LTREF
)
4898 rtx sym
= XVECEXP (x
, 0, 0);
4899 if (GET_CODE (sym
) != SYMBOL_REF
4900 || !CONSTANT_POOL_ADDRESS_P (sym
))
4903 if (*ref
== NULL_RTX
)
4905 else if (*ref
!= sym
)
4911 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
4912 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
4916 find_constant_pool_ref (XEXP (x
, i
), ref
);
4918 else if (fmt
[i
] == 'E')
4920 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
4921 find_constant_pool_ref (XVECEXP (x
, i
, j
), ref
);
4926 /* Replace every reference to the annotated literal pool
4927 symbol REF in X by its base plus OFFSET. */
4930 replace_constant_pool_ref (rtx
*x
, rtx ref
, rtx offset
)
4938 if (GET_CODE (*x
) == UNSPEC
4939 && XINT (*x
, 1) == UNSPEC_LTREF
4940 && XVECEXP (*x
, 0, 0) == ref
)
4942 *x
= gen_rtx_PLUS (Pmode
, XVECEXP (*x
, 0, 1), offset
);
4946 if (GET_CODE (*x
) == PLUS
4947 && GET_CODE (XEXP (*x
, 1)) == CONST_INT
4948 && GET_CODE (XEXP (*x
, 0)) == UNSPEC
4949 && XINT (XEXP (*x
, 0), 1) == UNSPEC_LTREF
4950 && XVECEXP (XEXP (*x
, 0), 0, 0) == ref
)
4952 rtx addr
= gen_rtx_PLUS (Pmode
, XVECEXP (XEXP (*x
, 0), 0, 1), offset
);
4953 *x
= plus_constant (addr
, INTVAL (XEXP (*x
, 1)));
4957 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
4958 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
4962 replace_constant_pool_ref (&XEXP (*x
, i
), ref
, offset
);
4964 else if (fmt
[i
] == 'E')
4966 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
4967 replace_constant_pool_ref (&XVECEXP (*x
, i
, j
), ref
, offset
);
4972 /* Check whether X contains an UNSPEC_LTREL_BASE.
4973 Return its constant pool symbol if found, NULL_RTX otherwise. */
4976 find_ltrel_base (rtx x
)
4981 if (GET_CODE (x
) == UNSPEC
4982 && XINT (x
, 1) == UNSPEC_LTREL_BASE
)
4983 return XVECEXP (x
, 0, 0);
4985 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
4986 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
4990 rtx fnd
= find_ltrel_base (XEXP (x
, i
));
4994 else if (fmt
[i
] == 'E')
4996 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
4998 rtx fnd
= find_ltrel_base (XVECEXP (x
, i
, j
));
5008 /* Replace any occurrence of UNSPEC_LTREL_BASE in X with its base. */
5011 replace_ltrel_base (rtx
*x
)
5016 if (GET_CODE (*x
) == UNSPEC
5017 && XINT (*x
, 1) == UNSPEC_LTREL_BASE
)
5019 *x
= XVECEXP (*x
, 0, 1);
5023 fmt
= GET_RTX_FORMAT (GET_CODE (*x
));
5024 for (i
= GET_RTX_LENGTH (GET_CODE (*x
)) - 1; i
>= 0; i
--)
5028 replace_ltrel_base (&XEXP (*x
, i
));
5030 else if (fmt
[i
] == 'E')
5032 for (j
= 0; j
< XVECLEN (*x
, i
); j
++)
5033 replace_ltrel_base (&XVECEXP (*x
, i
, j
));
5039 /* We keep a list of constants which we have to add to internal
5040 constant tables in the middle of large functions. */
5042 #define NR_C_MODES 7
5043 enum machine_mode constant_modes
[NR_C_MODES
] =
5054 struct constant
*next
;
5059 struct constant_pool
5061 struct constant_pool
*next
;
5066 struct constant
*constants
[NR_C_MODES
];
5067 struct constant
*execute
;
5072 static struct constant_pool
* s390_mainpool_start (void);
5073 static void s390_mainpool_finish (struct constant_pool
*);
5074 static void s390_mainpool_cancel (struct constant_pool
*);
5076 static struct constant_pool
* s390_chunkify_start (void);
5077 static void s390_chunkify_finish (struct constant_pool
*);
5078 static void s390_chunkify_cancel (struct constant_pool
*);
5080 static struct constant_pool
*s390_start_pool (struct constant_pool
**, rtx
);
5081 static void s390_end_pool (struct constant_pool
*, rtx
);
5082 static void s390_add_pool_insn (struct constant_pool
*, rtx
);
5083 static struct constant_pool
*s390_find_pool (struct constant_pool
*, rtx
);
5084 static void s390_add_constant (struct constant_pool
*, rtx
, enum machine_mode
);
5085 static rtx
s390_find_constant (struct constant_pool
*, rtx
, enum machine_mode
);
5086 static void s390_add_execute (struct constant_pool
*, rtx
);
5087 static rtx
s390_find_execute (struct constant_pool
*, rtx
);
5088 static rtx
s390_execute_label (rtx
);
5089 static rtx
s390_execute_target (rtx
);
5090 static void s390_dump_pool (struct constant_pool
*, bool);
5091 static void s390_dump_execute (struct constant_pool
*);
5092 static struct constant_pool
*s390_alloc_pool (void);
5093 static void s390_free_pool (struct constant_pool
*);
5095 /* Create new constant pool covering instructions starting at INSN
5096 and chain it to the end of POOL_LIST. */
5098 static struct constant_pool
*
5099 s390_start_pool (struct constant_pool
**pool_list
, rtx insn
)
5101 struct constant_pool
*pool
, **prev
;
5103 pool
= s390_alloc_pool ();
5104 pool
->first_insn
= insn
;
5106 for (prev
= pool_list
; *prev
; prev
= &(*prev
)->next
)
5113 /* End range of instructions covered by POOL at INSN and emit
5114 placeholder insn representing the pool. */
5117 s390_end_pool (struct constant_pool
*pool
, rtx insn
)
5119 rtx pool_size
= GEN_INT (pool
->size
+ 8 /* alignment slop */);
5122 insn
= get_last_insn ();
5124 pool
->pool_insn
= emit_insn_after (gen_pool (pool_size
), insn
);
5125 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
5128 /* Add INSN to the list of insns covered by POOL. */
5131 s390_add_pool_insn (struct constant_pool
*pool
, rtx insn
)
5133 bitmap_set_bit (pool
->insns
, INSN_UID (insn
));
5136 /* Return pool out of POOL_LIST that covers INSN. */
5138 static struct constant_pool
*
5139 s390_find_pool (struct constant_pool
*pool_list
, rtx insn
)
5141 struct constant_pool
*pool
;
5143 for (pool
= pool_list
; pool
; pool
= pool
->next
)
5144 if (bitmap_bit_p (pool
->insns
, INSN_UID (insn
)))
5150 /* Add constant VAL of mode MODE to the constant pool POOL. */
5153 s390_add_constant (struct constant_pool
*pool
, rtx val
, enum machine_mode mode
)
5158 for (i
= 0; i
< NR_C_MODES
; i
++)
5159 if (constant_modes
[i
] == mode
)
5161 if (i
== NR_C_MODES
)
5164 for (c
= pool
->constants
[i
]; c
!= NULL
; c
= c
->next
)
5165 if (rtx_equal_p (val
, c
->value
))
5170 c
= (struct constant
*) xmalloc (sizeof *c
);
5172 c
->label
= gen_label_rtx ();
5173 c
->next
= pool
->constants
[i
];
5174 pool
->constants
[i
] = c
;
5175 pool
->size
+= GET_MODE_SIZE (mode
);
5179 /* Find constant VAL of mode MODE in the constant pool POOL.
5180 Return an RTX describing the distance from the start of
5181 the pool to the location of the new constant. */
5184 s390_find_constant (struct constant_pool
*pool
, rtx val
,
5185 enum machine_mode mode
)
5191 for (i
= 0; i
< NR_C_MODES
; i
++)
5192 if (constant_modes
[i
] == mode
)
5194 if (i
== NR_C_MODES
)
5197 for (c
= pool
->constants
[i
]; c
!= NULL
; c
= c
->next
)
5198 if (rtx_equal_p (val
, c
->value
))
5204 offset
= gen_rtx_MINUS (Pmode
, gen_rtx_LABEL_REF (Pmode
, c
->label
),
5205 gen_rtx_LABEL_REF (Pmode
, pool
->label
));
5206 offset
= gen_rtx_CONST (Pmode
, offset
);
5210 /* Add execute target for INSN to the constant pool POOL. */
5213 s390_add_execute (struct constant_pool
*pool
, rtx insn
)
5217 for (c
= pool
->execute
; c
!= NULL
; c
= c
->next
)
5218 if (INSN_UID (insn
) == INSN_UID (c
->value
))
5223 rtx label
= s390_execute_label (insn
);
5226 c
= (struct constant
*) xmalloc (sizeof *c
);
5228 c
->label
= label
== const0_rtx
? gen_label_rtx () : XEXP (label
, 0);
5229 c
->next
= pool
->execute
;
5231 pool
->size
+= label
== const0_rtx
? 6 : 0;
5235 /* Find execute target for INSN in the constant pool POOL.
5236 Return an RTX describing the distance from the start of
5237 the pool to the location of the execute target. */
5240 s390_find_execute (struct constant_pool
*pool
, rtx insn
)
5245 for (c
= pool
->execute
; c
!= NULL
; c
= c
->next
)
5246 if (INSN_UID (insn
) == INSN_UID (c
->value
))
5252 offset
= gen_rtx_MINUS (Pmode
, gen_rtx_LABEL_REF (Pmode
, c
->label
),
5253 gen_rtx_LABEL_REF (Pmode
, pool
->label
));
5254 offset
= gen_rtx_CONST (Pmode
, offset
);
5258 /* Check whether INSN is an execute. Return the label_ref to its
5259 execute target template if so, NULL_RTX otherwise. */
5262 s390_execute_label (rtx insn
)
5264 if (GET_CODE (insn
) == INSN
5265 && GET_CODE (PATTERN (insn
)) == PARALLEL
5266 && GET_CODE (XVECEXP (PATTERN (insn
), 0, 0)) == UNSPEC
5267 && XINT (XVECEXP (PATTERN (insn
), 0, 0), 1) == UNSPEC_EXECUTE
)
5268 return XVECEXP (XVECEXP (PATTERN (insn
), 0, 0), 0, 2);
5273 /* For an execute INSN, extract the execute target template. */
5276 s390_execute_target (rtx insn
)
5278 rtx pattern
= PATTERN (insn
);
5279 gcc_assert (s390_execute_label (insn
));
5281 if (XVECLEN (pattern
, 0) == 2)
5283 pattern
= copy_rtx (XVECEXP (pattern
, 0, 1));
5287 rtvec vec
= rtvec_alloc (XVECLEN (pattern
, 0) - 1);
5290 for (i
= 0; i
< XVECLEN (pattern
, 0) - 1; i
++)
5291 RTVEC_ELT (vec
, i
) = copy_rtx (XVECEXP (pattern
, 0, i
+ 1));
5293 pattern
= gen_rtx_PARALLEL (VOIDmode
, vec
);
5299 /* Indicate that INSN cannot be duplicated. This is the case for
5300 execute insns that carry a unique label. */
5303 s390_cannot_copy_insn_p (rtx insn
)
5305 rtx label
= s390_execute_label (insn
);
5306 return label
&& label
!= const0_rtx
;
5309 /* Dump out the constants in POOL. If REMOTE_LABEL is true,
5310 do not emit the pool base label. */
5313 s390_dump_pool (struct constant_pool
*pool
, bool remote_label
)
5316 rtx insn
= pool
->pool_insn
;
5319 /* Switch to rodata section. */
5320 if (TARGET_CPU_ZARCH
)
5322 insn
= emit_insn_after (gen_pool_section_start (), insn
);
5323 INSN_ADDRESSES_NEW (insn
, -1);
5326 /* Ensure minimum pool alignment. */
5327 if (TARGET_CPU_ZARCH
)
5328 insn
= emit_insn_after (gen_pool_align (GEN_INT (8)), insn
);
5330 insn
= emit_insn_after (gen_pool_align (GEN_INT (4)), insn
);
5331 INSN_ADDRESSES_NEW (insn
, -1);
5333 /* Emit pool base label. */
5336 insn
= emit_label_after (pool
->label
, insn
);
5337 INSN_ADDRESSES_NEW (insn
, -1);
5340 /* Dump constants in descending alignment requirement order,
5341 ensuring proper alignment for every constant. */
5342 for (i
= 0; i
< NR_C_MODES
; i
++)
5343 for (c
= pool
->constants
[i
]; c
; c
= c
->next
)
5345 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
5346 rtx value
= c
->value
;
5347 if (GET_CODE (value
) == CONST
5348 && GET_CODE (XEXP (value
, 0)) == UNSPEC
5349 && XINT (XEXP (value
, 0), 1) == UNSPEC_LTREL_OFFSET
5350 && XVECLEN (XEXP (value
, 0), 0) == 1)
5352 value
= gen_rtx_MINUS (Pmode
, XVECEXP (XEXP (value
, 0), 0, 0),
5353 gen_rtx_LABEL_REF (VOIDmode
, pool
->label
));
5354 value
= gen_rtx_CONST (VOIDmode
, value
);
5357 insn
= emit_label_after (c
->label
, insn
);
5358 INSN_ADDRESSES_NEW (insn
, -1);
5360 value
= gen_rtx_UNSPEC_VOLATILE (constant_modes
[i
],
5361 gen_rtvec (1, value
),
5362 UNSPECV_POOL_ENTRY
);
5363 insn
= emit_insn_after (value
, insn
);
5364 INSN_ADDRESSES_NEW (insn
, -1);
5367 /* Ensure minimum alignment for instructions. */
5368 insn
= emit_insn_after (gen_pool_align (GEN_INT (2)), insn
);
5369 INSN_ADDRESSES_NEW (insn
, -1);
5371 /* Output in-pool execute template insns. */
5372 for (c
= pool
->execute
; c
; c
= c
->next
)
5374 if (s390_execute_label (c
->value
) != const0_rtx
)
5377 insn
= emit_label_after (c
->label
, insn
);
5378 INSN_ADDRESSES_NEW (insn
, -1);
5380 insn
= emit_insn_after (s390_execute_target (c
->value
), insn
);
5381 INSN_ADDRESSES_NEW (insn
, -1);
5384 /* Switch back to previous section. */
5385 if (TARGET_CPU_ZARCH
)
5387 insn
= emit_insn_after (gen_pool_section_end (), insn
);
5388 INSN_ADDRESSES_NEW (insn
, -1);
5391 insn
= emit_barrier_after (insn
);
5392 INSN_ADDRESSES_NEW (insn
, -1);
5394 /* Remove placeholder insn. */
5395 remove_insn (pool
->pool_insn
);
5397 /* Output out-of-pool execute template isns. */
5398 s390_dump_execute (pool
);
5401 /* Dump out the out-of-pool execute template insns in POOL
5402 at the end of the instruction stream. */
5405 s390_dump_execute (struct constant_pool
*pool
)
5410 for (c
= pool
->execute
; c
; c
= c
->next
)
5412 if (s390_execute_label (c
->value
) == const0_rtx
)
5415 insn
= emit_label (c
->label
);
5416 INSN_ADDRESSES_NEW (insn
, -1);
5418 insn
= emit_insn (s390_execute_target (c
->value
));
5419 INSN_ADDRESSES_NEW (insn
, -1);
5423 /* Allocate new constant_pool structure. */
5425 static struct constant_pool
*
5426 s390_alloc_pool (void)
5428 struct constant_pool
*pool
;
5431 pool
= (struct constant_pool
*) xmalloc (sizeof *pool
);
5433 for (i
= 0; i
< NR_C_MODES
; i
++)
5434 pool
->constants
[i
] = NULL
;
5436 pool
->execute
= NULL
;
5437 pool
->label
= gen_label_rtx ();
5438 pool
->first_insn
= NULL_RTX
;
5439 pool
->pool_insn
= NULL_RTX
;
5440 pool
->insns
= BITMAP_XMALLOC ();
5446 /* Free all memory used by POOL. */
5449 s390_free_pool (struct constant_pool
*pool
)
5451 struct constant
*c
, *next
;
5454 for (i
= 0; i
< NR_C_MODES
; i
++)
5455 for (c
= pool
->constants
[i
]; c
; c
= next
)
5461 for (c
= pool
->execute
; c
; c
= next
)
5467 BITMAP_XFREE (pool
->insns
);
5472 /* Collect main literal pool. Return NULL on overflow. */
5474 static struct constant_pool
*
5475 s390_mainpool_start (void)
5477 struct constant_pool
*pool
;
5480 pool
= s390_alloc_pool ();
5482 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5484 if (GET_CODE (insn
) == INSN
5485 && GET_CODE (PATTERN (insn
)) == SET
5486 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC_VOLATILE
5487 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPECV_MAIN_POOL
)
5489 if (pool
->pool_insn
)
5491 pool
->pool_insn
= insn
;
5494 if (s390_execute_label (insn
))
5496 s390_add_execute (pool
, insn
);
5498 else if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5500 rtx pool_ref
= NULL_RTX
;
5501 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5504 rtx constant
= get_pool_constant (pool_ref
);
5505 enum machine_mode mode
= get_pool_mode (pool_ref
);
5506 s390_add_constant (pool
, constant
, mode
);
5511 if (!pool
->pool_insn
&& pool
->size
> 0)
5514 if (pool
->size
>= 4096)
5516 /* We're going to chunkify the pool, so remove the main
5517 pool placeholder insn. */
5518 remove_insn (pool
->pool_insn
);
5520 s390_free_pool (pool
);
5527 /* POOL holds the main literal pool as collected by s390_mainpool_start.
5528 Modify the current function to output the pool constants as well as
5529 the pool register setup instruction. */
5532 s390_mainpool_finish (struct constant_pool
*pool
)
5534 rtx base_reg
= cfun
->machine
->base_reg
;
5537 /* If the pool is empty, we're done. */
5538 if (pool
->size
== 0)
5540 /* However, we may have out-of-pool execute templates. */
5541 s390_dump_execute (pool
);
5543 /* We don't actually need a base register after all. */
5544 cfun
->machine
->base_reg
= NULL_RTX
;
5546 if (pool
->pool_insn
)
5547 remove_insn (pool
->pool_insn
);
5548 s390_free_pool (pool
);
5552 /* We need correct insn addresses. */
5553 shorten_branches (get_insns ());
5555 /* On zSeries, we use a LARL to load the pool register. The pool is
5556 located in the .rodata section, so we emit it after the function. */
5557 if (TARGET_CPU_ZARCH
)
5559 insn
= gen_main_base_64 (base_reg
, pool
->label
);
5560 insn
= emit_insn_after (insn
, pool
->pool_insn
);
5561 INSN_ADDRESSES_NEW (insn
, -1);
5562 remove_insn (pool
->pool_insn
);
5564 insn
= get_last_insn ();
5565 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
5566 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
5568 s390_dump_pool (pool
, 0);
5571 /* On S/390, if the total size of the function's code plus literal pool
5572 does not exceed 4096 bytes, we use BASR to set up a function base
5573 pointer, and emit the literal pool at the end of the function. */
5574 else if (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
5575 + pool
->size
+ 8 /* alignment slop */ < 4096)
5577 insn
= gen_main_base_31_small (base_reg
, pool
->label
);
5578 insn
= emit_insn_after (insn
, pool
->pool_insn
);
5579 INSN_ADDRESSES_NEW (insn
, -1);
5580 remove_insn (pool
->pool_insn
);
5582 insn
= emit_label_after (pool
->label
, insn
);
5583 INSN_ADDRESSES_NEW (insn
, -1);
5585 insn
= get_last_insn ();
5586 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
5587 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
5589 s390_dump_pool (pool
, 1);
5592 /* Otherwise, we emit an inline literal pool and use BASR to branch
5593 over it, setting up the pool register at the same time. */
5596 rtx pool_end
= gen_label_rtx ();
5598 insn
= gen_main_base_31_large (base_reg
, pool
->label
, pool_end
);
5599 insn
= emit_insn_after (insn
, pool
->pool_insn
);
5600 INSN_ADDRESSES_NEW (insn
, -1);
5601 remove_insn (pool
->pool_insn
);
5603 insn
= emit_label_after (pool
->label
, insn
);
5604 INSN_ADDRESSES_NEW (insn
, -1);
5606 pool
->pool_insn
= emit_insn_after (gen_pool (const0_rtx
), insn
);
5607 INSN_ADDRESSES_NEW (pool
->pool_insn
, -1);
5609 insn
= emit_label_after (pool_end
, pool
->pool_insn
);
5610 INSN_ADDRESSES_NEW (insn
, -1);
5612 s390_dump_pool (pool
, 1);
5616 /* Replace all literal pool references. */
5618 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5621 replace_ltrel_base (&PATTERN (insn
));
5623 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5625 rtx addr
, pool_ref
= NULL_RTX
;
5626 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5629 if (s390_execute_label (insn
))
5630 addr
= s390_find_execute (pool
, insn
);
5632 addr
= s390_find_constant (pool
, get_pool_constant (pool_ref
),
5633 get_pool_mode (pool_ref
));
5635 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
5636 INSN_CODE (insn
) = -1;
5642 /* Free the pool. */
5643 s390_free_pool (pool
);
5646 /* POOL holds the main literal pool as collected by s390_mainpool_start.
5647 We have decided we cannot use this pool, so revert all changes
5648 to the current function that were done by s390_mainpool_start. */
5650 s390_mainpool_cancel (struct constant_pool
*pool
)
5652 /* We didn't actually change the instruction stream, so simply
5653 free the pool memory. */
5654 s390_free_pool (pool
);
5658 /* Chunkify the literal pool. */
5660 #define S390_POOL_CHUNK_MIN 0xc00
5661 #define S390_POOL_CHUNK_MAX 0xe00
5663 static struct constant_pool
*
5664 s390_chunkify_start (void)
5666 struct constant_pool
*curr_pool
= NULL
, *pool_list
= NULL
;
5669 rtx pending_ltrel
= NULL_RTX
;
5672 rtx (*gen_reload_base
) (rtx
, rtx
) =
5673 TARGET_CPU_ZARCH
? gen_reload_base_64
: gen_reload_base_31
;
5676 /* We need correct insn addresses. */
5678 shorten_branches (get_insns ());
5680 /* Scan all insns and move literals to pool chunks. */
5682 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5684 /* Check for pending LTREL_BASE. */
5687 rtx ltrel_base
= find_ltrel_base (PATTERN (insn
));
5690 if (ltrel_base
== pending_ltrel
)
5691 pending_ltrel
= NULL_RTX
;
5697 if (s390_execute_label (insn
))
5700 curr_pool
= s390_start_pool (&pool_list
, insn
);
5702 s390_add_execute (curr_pool
, insn
);
5703 s390_add_pool_insn (curr_pool
, insn
);
5705 else if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5707 rtx pool_ref
= NULL_RTX
;
5708 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5711 rtx constant
= get_pool_constant (pool_ref
);
5712 enum machine_mode mode
= get_pool_mode (pool_ref
);
5715 curr_pool
= s390_start_pool (&pool_list
, insn
);
5717 s390_add_constant (curr_pool
, constant
, mode
);
5718 s390_add_pool_insn (curr_pool
, insn
);
5720 /* Don't split the pool chunk between a LTREL_OFFSET load
5721 and the corresponding LTREL_BASE. */
5722 if (GET_CODE (constant
) == CONST
5723 && GET_CODE (XEXP (constant
, 0)) == UNSPEC
5724 && XINT (XEXP (constant
, 0), 1) == UNSPEC_LTREL_OFFSET
)
5728 pending_ltrel
= pool_ref
;
5733 if (GET_CODE (insn
) == JUMP_INSN
|| GET_CODE (insn
) == CODE_LABEL
)
5736 s390_add_pool_insn (curr_pool
, insn
);
5737 /* An LTREL_BASE must follow within the same basic block. */
5743 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn
)
5744 || INSN_ADDRESSES (INSN_UID (insn
)) == -1)
5747 if (TARGET_CPU_ZARCH
)
5749 if (curr_pool
->size
< S390_POOL_CHUNK_MAX
)
5752 s390_end_pool (curr_pool
, NULL_RTX
);
5757 int chunk_size
= INSN_ADDRESSES (INSN_UID (insn
))
5758 - INSN_ADDRESSES (INSN_UID (curr_pool
->first_insn
))
5761 /* We will later have to insert base register reload insns.
5762 Those will have an effect on code size, which we need to
5763 consider here. This calculation makes rather pessimistic
5764 worst-case assumptions. */
5765 if (GET_CODE (insn
) == CODE_LABEL
)
5768 if (chunk_size
< S390_POOL_CHUNK_MIN
5769 && curr_pool
->size
< S390_POOL_CHUNK_MIN
)
5772 /* Pool chunks can only be inserted after BARRIERs ... */
5773 if (GET_CODE (insn
) == BARRIER
)
5775 s390_end_pool (curr_pool
, insn
);
5780 /* ... so if we don't find one in time, create one. */
5781 else if ((chunk_size
> S390_POOL_CHUNK_MAX
5782 || curr_pool
->size
> S390_POOL_CHUNK_MAX
))
5784 rtx label
, jump
, barrier
;
5786 /* We can insert the barrier only after a 'real' insn. */
5787 if (GET_CODE (insn
) != INSN
&& GET_CODE (insn
) != CALL_INSN
)
5789 if (get_attr_length (insn
) == 0)
5792 /* Don't separate LTREL_BASE from the corresponding
5793 LTREL_OFFSET load. */
5797 label
= gen_label_rtx ();
5798 jump
= emit_jump_insn_after (gen_jump (label
), insn
);
5799 barrier
= emit_barrier_after (jump
);
5800 insn
= emit_label_after (label
, barrier
);
5801 JUMP_LABEL (jump
) = label
;
5802 LABEL_NUSES (label
) = 1;
5804 INSN_ADDRESSES_NEW (jump
, -1);
5805 INSN_ADDRESSES_NEW (barrier
, -1);
5806 INSN_ADDRESSES_NEW (insn
, -1);
5808 s390_end_pool (curr_pool
, barrier
);
5816 s390_end_pool (curr_pool
, NULL_RTX
);
5821 /* Find all labels that are branched into
5822 from an insn belonging to a different chunk. */
5824 far_labels
= BITMAP_XMALLOC ();
5826 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5828 /* Labels marked with LABEL_PRESERVE_P can be target
5829 of non-local jumps, so we have to mark them.
5830 The same holds for named labels.
5832 Don't do that, however, if it is the label before
5835 if (GET_CODE (insn
) == CODE_LABEL
5836 && (LABEL_PRESERVE_P (insn
) || LABEL_NAME (insn
)))
5838 rtx vec_insn
= next_real_insn (insn
);
5839 rtx vec_pat
= vec_insn
&& GET_CODE (vec_insn
) == JUMP_INSN
?
5840 PATTERN (vec_insn
) : NULL_RTX
;
5842 || !(GET_CODE (vec_pat
) == ADDR_VEC
5843 || GET_CODE (vec_pat
) == ADDR_DIFF_VEC
))
5844 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (insn
));
5847 /* If we have a direct jump (conditional or unconditional)
5848 or a casesi jump, check all potential targets. */
5849 else if (GET_CODE (insn
) == JUMP_INSN
)
5851 rtx pat
= PATTERN (insn
);
5852 if (GET_CODE (pat
) == PARALLEL
&& XVECLEN (pat
, 0) > 2)
5853 pat
= XVECEXP (pat
, 0, 0);
5855 if (GET_CODE (pat
) == SET
)
5857 rtx label
= JUMP_LABEL (insn
);
5860 if (s390_find_pool (pool_list
, label
)
5861 != s390_find_pool (pool_list
, insn
))
5862 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
5865 else if (GET_CODE (pat
) == PARALLEL
5866 && XVECLEN (pat
, 0) == 2
5867 && GET_CODE (XVECEXP (pat
, 0, 0)) == SET
5868 && GET_CODE (XVECEXP (pat
, 0, 1)) == USE
5869 && GET_CODE (XEXP (XVECEXP (pat
, 0, 1), 0)) == LABEL_REF
)
5871 /* Find the jump table used by this casesi jump. */
5872 rtx vec_label
= XEXP (XEXP (XVECEXP (pat
, 0, 1), 0), 0);
5873 rtx vec_insn
= next_real_insn (vec_label
);
5874 rtx vec_pat
= vec_insn
&& GET_CODE (vec_insn
) == JUMP_INSN
?
5875 PATTERN (vec_insn
) : NULL_RTX
;
5877 && (GET_CODE (vec_pat
) == ADDR_VEC
5878 || GET_CODE (vec_pat
) == ADDR_DIFF_VEC
))
5880 int i
, diff_p
= GET_CODE (vec_pat
) == ADDR_DIFF_VEC
;
5882 for (i
= 0; i
< XVECLEN (vec_pat
, diff_p
); i
++)
5884 rtx label
= XEXP (XVECEXP (vec_pat
, diff_p
, i
), 0);
5886 if (s390_find_pool (pool_list
, label
)
5887 != s390_find_pool (pool_list
, insn
))
5888 bitmap_set_bit (far_labels
, CODE_LABEL_NUMBER (label
));
5895 /* Insert base register reload insns before every pool. */
5897 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
5899 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
5901 rtx insn
= curr_pool
->first_insn
;
5902 INSN_ADDRESSES_NEW (emit_insn_before (new_insn
, insn
), -1);
5905 /* Insert base register reload insns at every far label. */
5907 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5908 if (GET_CODE (insn
) == CODE_LABEL
5909 && bitmap_bit_p (far_labels
, CODE_LABEL_NUMBER (insn
)))
5911 struct constant_pool
*pool
= s390_find_pool (pool_list
, insn
);
5914 rtx new_insn
= gen_reload_base (cfun
->machine
->base_reg
,
5916 INSN_ADDRESSES_NEW (emit_insn_after (new_insn
, insn
), -1);
5921 BITMAP_XFREE (far_labels
);
5924 /* Recompute insn addresses. */
5926 init_insn_lengths ();
5927 shorten_branches (get_insns ());
5932 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
5933 After we have decided to use this list, finish implementing
5934 all changes to the current function as required. */
5937 s390_chunkify_finish (struct constant_pool
*pool_list
)
5939 struct constant_pool
*curr_pool
= NULL
;
5943 /* Replace all literal pool references. */
5945 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5948 replace_ltrel_base (&PATTERN (insn
));
5950 curr_pool
= s390_find_pool (pool_list
, insn
);
5954 if (GET_CODE (insn
) == INSN
|| GET_CODE (insn
) == CALL_INSN
)
5956 rtx addr
, pool_ref
= NULL_RTX
;
5957 find_constant_pool_ref (PATTERN (insn
), &pool_ref
);
5960 if (s390_execute_label (insn
))
5961 addr
= s390_find_execute (curr_pool
, insn
);
5963 addr
= s390_find_constant (curr_pool
,
5964 get_pool_constant (pool_ref
),
5965 get_pool_mode (pool_ref
));
5967 replace_constant_pool_ref (&PATTERN (insn
), pool_ref
, addr
);
5968 INSN_CODE (insn
) = -1;
5973 /* Dump out all literal pools. */
5975 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
5976 s390_dump_pool (curr_pool
, 0);
5978 /* Free pool list. */
5982 struct constant_pool
*next
= pool_list
->next
;
5983 s390_free_pool (pool_list
);
5988 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
5989 We have decided we cannot use this list, so revert all changes
5990 to the current function that were done by s390_chunkify_start. */
5993 s390_chunkify_cancel (struct constant_pool
*pool_list
)
5995 struct constant_pool
*curr_pool
= NULL
;
5998 /* Remove all pool placeholder insns. */
6000 for (curr_pool
= pool_list
; curr_pool
; curr_pool
= curr_pool
->next
)
6002 /* Did we insert an extra barrier? Remove it. */
6003 rtx barrier
= PREV_INSN (curr_pool
->pool_insn
);
6004 rtx jump
= barrier
? PREV_INSN (barrier
) : NULL_RTX
;
6005 rtx label
= NEXT_INSN (curr_pool
->pool_insn
);
6007 if (jump
&& GET_CODE (jump
) == JUMP_INSN
6008 && barrier
&& GET_CODE (barrier
) == BARRIER
6009 && label
&& GET_CODE (label
) == CODE_LABEL
6010 && GET_CODE (PATTERN (jump
)) == SET
6011 && SET_DEST (PATTERN (jump
)) == pc_rtx
6012 && GET_CODE (SET_SRC (PATTERN (jump
))) == LABEL_REF
6013 && XEXP (SET_SRC (PATTERN (jump
)), 0) == label
)
6016 remove_insn (barrier
);
6017 remove_insn (label
);
6020 remove_insn (curr_pool
->pool_insn
);
6023 /* Remove all base register reload insns. */
6025 for (insn
= get_insns (); insn
; )
6027 rtx next_insn
= NEXT_INSN (insn
);
6029 if (GET_CODE (insn
) == INSN
6030 && GET_CODE (PATTERN (insn
)) == SET
6031 && GET_CODE (SET_SRC (PATTERN (insn
))) == UNSPEC
6032 && XINT (SET_SRC (PATTERN (insn
)), 1) == UNSPEC_RELOAD_BASE
)
6038 /* Free pool list. */
6042 struct constant_pool
*next
= pool_list
->next
;
6043 s390_free_pool (pool_list
);
6049 /* Output the constant pool entry EXP in mode MODE with alignment ALIGN. */
6052 s390_output_pool_entry (rtx exp
, enum machine_mode mode
, unsigned int align
)
6056 switch (GET_MODE_CLASS (mode
))
6059 if (GET_CODE (exp
) != CONST_DOUBLE
)
6062 REAL_VALUE_FROM_CONST_DOUBLE (r
, exp
);
6063 assemble_real (r
, mode
, align
);
6067 assemble_integer (exp
, GET_MODE_SIZE (mode
), align
, 1);
6076 /* Rework the prologue/epilogue to avoid saving/restoring
6077 registers unnecessarily. */
6080 s390_optimize_prologue (void)
6082 rtx insn
, new_insn
, next_insn
;
6084 /* Do a final recompute of the frame-related data. */
6086 s390_update_frame_layout ();
6088 /* If all special registers are in fact used, there's nothing we
6089 can do, so no point in walking the insn list. */
6091 if (cfun_frame_layout
.first_save_gpr
<= BASE_REGNUM
6092 && cfun_frame_layout
.last_save_gpr
>= BASE_REGNUM
6093 && (TARGET_CPU_ZARCH
6094 || (cfun_frame_layout
.first_save_gpr
<= RETURN_REGNUM
6095 && cfun_frame_layout
.last_save_gpr
>= RETURN_REGNUM
)))
6098 /* Search for prologue/epilogue insns and replace them. */
6100 for (insn
= get_insns (); insn
; insn
= next_insn
)
6102 int first
, last
, off
;
6103 rtx set
, base
, offset
;
6105 next_insn
= NEXT_INSN (insn
);
6107 if (GET_CODE (insn
) != INSN
)
6110 if (GET_CODE (PATTERN (insn
)) == PARALLEL
6111 && store_multiple_operation (PATTERN (insn
), VOIDmode
))
6113 set
= XVECEXP (PATTERN (insn
), 0, 0);
6114 first
= REGNO (SET_SRC (set
));
6115 last
= first
+ XVECLEN (PATTERN (insn
), 0) - 1;
6116 offset
= const0_rtx
;
6117 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
6118 off
= INTVAL (offset
);
6120 if (GET_CODE (base
) != REG
|| off
< 0)
6122 if (REGNO (base
) != STACK_POINTER_REGNUM
6123 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
6125 if (first
> BASE_REGNUM
|| last
< BASE_REGNUM
)
6128 if (cfun_frame_layout
.first_save_gpr
!= -1)
6130 new_insn
= save_gprs (base
,
6131 off
+ (cfun_frame_layout
.first_save_gpr
6132 - first
) * UNITS_PER_WORD
,
6133 cfun_frame_layout
.first_save_gpr
,
6134 cfun_frame_layout
.last_save_gpr
);
6135 new_insn
= emit_insn_before (new_insn
, insn
);
6136 INSN_ADDRESSES_NEW (new_insn
, -1);
6143 if (GET_CODE (PATTERN (insn
)) == SET
6144 && GET_CODE (SET_SRC (PATTERN (insn
))) == REG
6145 && (REGNO (SET_SRC (PATTERN (insn
))) == BASE_REGNUM
6146 || (!TARGET_CPU_ZARCH
6147 && REGNO (SET_SRC (PATTERN (insn
))) == RETURN_REGNUM
))
6148 && GET_CODE (SET_DEST (PATTERN (insn
))) == MEM
)
6150 set
= PATTERN (insn
);
6151 first
= REGNO (SET_SRC (set
));
6152 offset
= const0_rtx
;
6153 base
= eliminate_constant_term (XEXP (SET_DEST (set
), 0), &offset
);
6154 off
= INTVAL (offset
);
6156 if (GET_CODE (base
) != REG
|| off
< 0)
6158 if (REGNO (base
) != STACK_POINTER_REGNUM
6159 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
6161 if (cfun_frame_layout
.first_save_gpr
!= -1)
6163 new_insn
= save_gprs (base
,
6164 off
+ (cfun_frame_layout
.first_save_gpr
6165 - first
) * UNITS_PER_WORD
,
6166 cfun_frame_layout
.first_save_gpr
,
6167 cfun_frame_layout
.last_save_gpr
);
6168 new_insn
= emit_insn_before (new_insn
, insn
);
6169 INSN_ADDRESSES_NEW (new_insn
, -1);
6176 if (GET_CODE (PATTERN (insn
)) == PARALLEL
6177 && load_multiple_operation (PATTERN (insn
), VOIDmode
))
6179 set
= XVECEXP (PATTERN (insn
), 0, 0);
6180 first
= REGNO (SET_DEST (set
));
6181 last
= first
+ XVECLEN (PATTERN (insn
), 0) - 1;
6182 offset
= const0_rtx
;
6183 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
6184 off
= INTVAL (offset
);
6186 if (GET_CODE (base
) != REG
|| off
< 0)
6188 if (REGNO (base
) != STACK_POINTER_REGNUM
6189 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
6191 if (first
> BASE_REGNUM
|| last
< BASE_REGNUM
)
6194 if (cfun_frame_layout
.first_restore_gpr
!= -1)
6196 new_insn
= restore_gprs (base
,
6197 off
+ (cfun_frame_layout
.first_restore_gpr
6198 - first
) * UNITS_PER_WORD
,
6199 cfun_frame_layout
.first_restore_gpr
,
6200 cfun_frame_layout
.last_restore_gpr
);
6201 new_insn
= emit_insn_before (new_insn
, insn
);
6202 INSN_ADDRESSES_NEW (new_insn
, -1);
6209 if (GET_CODE (PATTERN (insn
)) == SET
6210 && GET_CODE (SET_DEST (PATTERN (insn
))) == REG
6211 && (REGNO (SET_DEST (PATTERN (insn
))) == BASE_REGNUM
6212 || (!TARGET_CPU_ZARCH
6213 && REGNO (SET_DEST (PATTERN (insn
))) == RETURN_REGNUM
))
6214 && GET_CODE (SET_SRC (PATTERN (insn
))) == MEM
)
6216 set
= PATTERN (insn
);
6217 first
= REGNO (SET_DEST (set
));
6218 offset
= const0_rtx
;
6219 base
= eliminate_constant_term (XEXP (SET_SRC (set
), 0), &offset
);
6220 off
= INTVAL (offset
);
6222 if (GET_CODE (base
) != REG
|| off
< 0)
6224 if (REGNO (base
) != STACK_POINTER_REGNUM
6225 && REGNO (base
) != HARD_FRAME_POINTER_REGNUM
)
6227 if (cfun_frame_layout
.first_restore_gpr
!= -1)
6229 new_insn
= restore_gprs (base
,
6230 off
+ (cfun_frame_layout
.first_restore_gpr
6231 - first
) * UNITS_PER_WORD
,
6232 cfun_frame_layout
.first_restore_gpr
,
6233 cfun_frame_layout
.last_restore_gpr
);
6234 new_insn
= emit_insn_before (new_insn
, insn
);
6235 INSN_ADDRESSES_NEW (new_insn
, -1);
6244 /* Perform machine-dependent processing. */
6249 bool pool_overflow
= false;
6251 /* Make sure all splits have been performed; splits after
6252 machine_dependent_reorg might confuse insn length counts. */
6253 split_all_insns_noflow ();
6256 /* Install the main literal pool and the associated base
6257 register load insns.
6259 In addition, there are two problematic situations we need
6262 - the literal pool might be > 4096 bytes in size, so that
6263 some of its elements cannot be directly accessed
6265 - a branch target might be > 64K away from the branch, so that
6266 it is not possible to use a PC-relative instruction.
6268 To fix those, we split the single literal pool into multiple
6269 pool chunks, reloading the pool base register at various
6270 points throughout the function to ensure it always points to
6271 the pool chunk the following code expects, and / or replace
6272 PC-relative branches by absolute branches.
6274 However, the two problems are interdependent: splitting the
6275 literal pool can move a branch further away from its target,
6276 causing the 64K limit to overflow, and on the other hand,
6277 replacing a PC-relative branch by an absolute branch means
6278 we need to put the branch target address into the literal
6279 pool, possibly causing it to overflow.
6281 So, we loop trying to fix up both problems until we manage
6282 to satisfy both conditions at the same time. Note that the
6283 loop is guaranteed to terminate as every pass of the loop
6284 strictly decreases the total number of PC-relative branches
6285 in the function. (This is not completely true as there
6286 might be branch-over-pool insns introduced by chunkify_start.
6287 Those never need to be split however.) */
6291 struct constant_pool
*pool
= NULL
;
6293 /* Collect the literal pool. */
6296 pool
= s390_mainpool_start ();
6298 pool_overflow
= true;
6301 /* If literal pool overflowed, start to chunkify it. */
6303 pool
= s390_chunkify_start ();
6305 /* Split out-of-range branches. If this has created new
6306 literal pool entries, cancel current chunk list and
6307 recompute it. zSeries machines have large branch
6308 instructions, so we never need to split a branch. */
6309 if (!TARGET_CPU_ZARCH
&& s390_split_branches ())
6312 s390_chunkify_cancel (pool
);
6314 s390_mainpool_cancel (pool
);
6319 /* If we made it up to here, both conditions are satisfied.
6320 Finish up literal pool related changes. */
6322 s390_chunkify_finish (pool
);
6324 s390_mainpool_finish (pool
);
6326 /* We're done splitting branches. */
6327 cfun
->machine
->split_branches_pending_p
= false;
6331 s390_optimize_prologue ();
6335 /* Return an RTL expression representing the value of the return address
6336 for the frame COUNT steps up from the current frame. FRAME is the
6337 frame pointer of that frame. */
6340 s390_return_addr_rtx (int count
, rtx frame ATTRIBUTE_UNUSED
)
6345 /* Without backchain, we fail for all but the current frame. */
6347 if (!TARGET_BACKCHAIN
&& count
> 0)
6350 /* For the current frame, we need to make sure the initial
6351 value of RETURN_REGNUM is actually saved. */
6355 cfun_frame_layout
.save_return_addr_p
= true;
6356 return gen_rtx_MEM (Pmode
, return_address_pointer_rtx
);
6359 if (TARGET_PACKED_STACK
)
6360 offset
= -2 * UNITS_PER_WORD
;
6362 offset
= RETURN_REGNUM
* UNITS_PER_WORD
;
6364 addr
= plus_constant (frame
, offset
);
6365 addr
= memory_address (Pmode
, addr
);
6366 return gen_rtx_MEM (Pmode
, addr
);
6369 /* Return an RTL expression representing the back chain stored in
6370 the current stack frame. */
6373 s390_back_chain_rtx (void)
6377 gcc_assert (TARGET_BACKCHAIN
);
6379 if (TARGET_PACKED_STACK
)
6380 chain
= plus_constant (stack_pointer_rtx
,
6381 STACK_POINTER_OFFSET
- UNITS_PER_WORD
);
6383 chain
= stack_pointer_rtx
;
6385 chain
= gen_rtx_MEM (Pmode
, chain
);
6389 /* Find first call clobbered register unused in a function.
6390 This could be used as base register in a leaf function
6391 or for holding the return address before epilogue. */
6394 find_unused_clobbered_reg (void)
6397 for (i
= 0; i
< 6; i
++)
6398 if (!regs_ever_live
[i
])
6403 /* Determine the frame area which actually has to be accessed
6404 in the function epilogue. The values are stored at the
6405 given pointers AREA_BOTTOM (address of the lowest used stack
6406 address) and AREA_TOP (address of the first item which does
6407 not belong to the stack frame). */
6410 s390_frame_area (int *area_bottom
, int *area_top
)
6418 if (cfun_frame_layout
.first_restore_gpr
!= -1)
6420 b
= (cfun_frame_layout
.gprs_offset
6421 + cfun_frame_layout
.first_restore_gpr
* UNITS_PER_WORD
);
6422 t
= b
+ (cfun_frame_layout
.last_restore_gpr
6423 - cfun_frame_layout
.first_restore_gpr
+ 1) * UNITS_PER_WORD
;
6426 if (TARGET_64BIT
&& cfun_save_high_fprs_p
)
6428 b
= MIN (b
, cfun_frame_layout
.f8_offset
);
6429 t
= MAX (t
, (cfun_frame_layout
.f8_offset
6430 + cfun_frame_layout
.high_fprs
* 8));
6434 for (i
= 2; i
< 4; i
++)
6435 if (cfun_fpr_bit_p (i
))
6437 b
= MIN (b
, cfun_frame_layout
.f4_offset
+ (i
- 2) * 8);
6438 t
= MAX (t
, cfun_frame_layout
.f4_offset
+ (i
- 1) * 8);
6445 /* Fill cfun->machine with info about register usage of current function.
6446 Return in LIVE_REGS which GPRs are currently considered live. */
6449 s390_register_info (int live_regs
[])
6453 /* fprs 8 - 15 are call saved for 64 Bit ABI. */
6454 cfun_frame_layout
.fpr_bitmap
= 0;
6455 cfun_frame_layout
.high_fprs
= 0;
6457 for (i
= 24; i
< 32; i
++)
6458 if (regs_ever_live
[i
] && !global_regs
[i
])
6460 cfun_set_fpr_bit (i
- 16);
6461 cfun_frame_layout
.high_fprs
++;
6464 /* Find first and last gpr to be saved. We trust regs_ever_live
6465 data, except that we don't save and restore global registers.
6467 Also, all registers with special meaning to the compiler need
6468 to be handled extra. */
6470 for (i
= 0; i
< 16; i
++)
6471 live_regs
[i
] = regs_ever_live
[i
] && !global_regs
[i
];
6474 live_regs
[PIC_OFFSET_TABLE_REGNUM
]
6475 = regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
];
6477 live_regs
[BASE_REGNUM
]
6478 = cfun
->machine
->base_reg
6479 && REGNO (cfun
->machine
->base_reg
) == BASE_REGNUM
;
6481 live_regs
[RETURN_REGNUM
]
6482 = cfun
->machine
->split_branches_pending_p
6483 || cfun_frame_layout
.save_return_addr_p
;
6485 live_regs
[STACK_POINTER_REGNUM
]
6486 = !current_function_is_leaf
6487 || TARGET_TPF_PROFILING
6488 || cfun_save_high_fprs_p
6489 || get_frame_size () > 0
6490 || current_function_calls_alloca
6491 || current_function_stdarg
;
6493 for (i
= 6; i
< 16; i
++)
6496 for (j
= 15; j
> i
; j
--)
6502 /* Nothing to save/restore. */
6503 cfun_frame_layout
.first_save_gpr
= -1;
6504 cfun_frame_layout
.first_restore_gpr
= -1;
6505 cfun_frame_layout
.last_save_gpr
= -1;
6506 cfun_frame_layout
.last_restore_gpr
= -1;
6510 /* Save / Restore from gpr i to j. */
6511 cfun_frame_layout
.first_save_gpr
= i
;
6512 cfun_frame_layout
.first_restore_gpr
= i
;
6513 cfun_frame_layout
.last_save_gpr
= j
;
6514 cfun_frame_layout
.last_restore_gpr
= j
;
6517 if (current_function_stdarg
)
6519 /* Varargs functions need to save gprs 2 to 6. */
6520 if (cfun_frame_layout
.first_save_gpr
== -1
6521 || cfun_frame_layout
.first_save_gpr
> 2)
6522 cfun_frame_layout
.first_save_gpr
= 2;
6524 if (cfun_frame_layout
.last_save_gpr
== -1
6525 || cfun_frame_layout
.last_save_gpr
< 6)
6526 cfun_frame_layout
.last_save_gpr
= 6;
6528 /* Mark f0, f2 for 31 bit and f0-f4 for 64 bit to be saved. */
6529 if (TARGET_HARD_FLOAT
)
6530 for (i
= 0; i
< (TARGET_64BIT
? 4 : 2); i
++)
6531 cfun_set_fpr_bit (i
);
6535 for (i
= 2; i
< 4; i
++)
6536 if (regs_ever_live
[i
+ 16] && !global_regs
[i
+ 16])
6537 cfun_set_fpr_bit (i
);
6540 /* Fill cfun->machine with info about frame of current function. */
6543 s390_frame_info (void)
6547 cfun_frame_layout
.frame_size
= get_frame_size ();
6548 if (!TARGET_64BIT
&& cfun_frame_layout
.frame_size
> 0x7fff0000)
6549 fatal_error ("Total size of local variables exceeds architecture limit.");
6551 if (!TARGET_PACKED_STACK
)
6553 cfun_frame_layout
.backchain_offset
= 0;
6554 cfun_frame_layout
.f0_offset
= 16 * UNITS_PER_WORD
;
6555 cfun_frame_layout
.f4_offset
= cfun_frame_layout
.f0_offset
+ 2 * 8;
6556 cfun_frame_layout
.f8_offset
= -cfun_frame_layout
.high_fprs
* 8;
6557 cfun_frame_layout
.gprs_offset
= (cfun_frame_layout
.first_save_gpr
6560 else if (TARGET_BACKCHAIN
) /* kernel stack layout */
6562 cfun_frame_layout
.backchain_offset
= (STACK_POINTER_OFFSET
6564 cfun_frame_layout
.gprs_offset
6565 = (cfun_frame_layout
.backchain_offset
6566 - (STACK_POINTER_REGNUM
- cfun_frame_layout
.first_save_gpr
+ 1)
6571 cfun_frame_layout
.f4_offset
6572 = (cfun_frame_layout
.gprs_offset
6573 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6575 cfun_frame_layout
.f0_offset
6576 = (cfun_frame_layout
.f4_offset
6577 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6581 /* On 31 bit we have to care about alignment of the
6582 floating point regs to provide fastest access. */
6583 cfun_frame_layout
.f0_offset
6584 = ((cfun_frame_layout
.gprs_offset
6585 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1))
6586 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6588 cfun_frame_layout
.f4_offset
6589 = (cfun_frame_layout
.f0_offset
6590 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6593 else /* no backchain */
6595 cfun_frame_layout
.f4_offset
6596 = (STACK_POINTER_OFFSET
6597 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
6599 cfun_frame_layout
.f0_offset
6600 = (cfun_frame_layout
.f4_offset
6601 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
6603 cfun_frame_layout
.gprs_offset
6604 = cfun_frame_layout
.f0_offset
- cfun_gprs_save_area_size
;
6607 if (current_function_is_leaf
6608 && !TARGET_TPF_PROFILING
6609 && cfun_frame_layout
.frame_size
== 0
6610 && !cfun_save_high_fprs_p
6611 && !current_function_calls_alloca
6612 && !current_function_stdarg
)
6615 if (!TARGET_PACKED_STACK
)
6616 cfun_frame_layout
.frame_size
+= (STARTING_FRAME_OFFSET
6617 + cfun_frame_layout
.high_fprs
* 8);
6620 if (TARGET_BACKCHAIN
)
6621 cfun_frame_layout
.frame_size
+= UNITS_PER_WORD
;
6623 /* No alignment trouble here because f8-f15 are only saved under
6625 cfun_frame_layout
.f8_offset
= (MIN (MIN (cfun_frame_layout
.f0_offset
,
6626 cfun_frame_layout
.f4_offset
),
6627 cfun_frame_layout
.gprs_offset
)
6628 - cfun_frame_layout
.high_fprs
* 8);
6630 cfun_frame_layout
.frame_size
+= cfun_frame_layout
.high_fprs
* 8;
6632 for (i
= 0; i
< 8; i
++)
6633 if (cfun_fpr_bit_p (i
))
6634 cfun_frame_layout
.frame_size
+= 8;
6636 cfun_frame_layout
.frame_size
+= cfun_gprs_save_area_size
;
6638 /* If under 31 bit an odd number of gprs has to be saved we have to adjust
6639 the frame size to sustain 8 byte alignment of stack frames. */
6640 cfun_frame_layout
.frame_size
= ((cfun_frame_layout
.frame_size
+
6641 STACK_BOUNDARY
/ BITS_PER_UNIT
- 1)
6642 & ~(STACK_BOUNDARY
/ BITS_PER_UNIT
- 1));
6644 cfun_frame_layout
.frame_size
+= current_function_outgoing_args_size
;
6648 /* Generate frame layout. Fills in register and frame data for the current
6649 function in cfun->machine. This routine can be called multiple times;
6650 it will re-do the complete frame layout every time. */
6653 s390_init_frame_layout (void)
6655 HOST_WIDE_INT frame_size
;
6659 /* If return address register is explicitly used, we need to save it. */
6660 if (regs_ever_live
[RETURN_REGNUM
]
6661 || !current_function_is_leaf
6662 || TARGET_TPF_PROFILING
6663 || current_function_stdarg
6664 || current_function_calls_eh_return
)
6665 cfun_frame_layout
.save_return_addr_p
= true;
6667 /* On S/390 machines, we may need to perform branch splitting, which
6668 will require both base and return address register. We have no
6669 choice but to assume we're going to need them until right at the
6670 end of the machine dependent reorg phase. */
6671 if (!TARGET_CPU_ZARCH
)
6672 cfun
->machine
->split_branches_pending_p
= true;
6676 frame_size
= cfun_frame_layout
.frame_size
;
6678 /* Try to predict whether we'll need the base register. */
6679 base_used
= cfun
->machine
->split_branches_pending_p
6680 || current_function_uses_const_pool
6681 || (!DISP_IN_RANGE (-frame_size
)
6682 && !CONST_OK_FOR_CONSTRAINT_P (-frame_size
, 'K', "K"));
6684 /* Decide which register to use as literal pool base. In small
6685 leaf functions, try to use an unused call-clobbered register
6686 as base register to avoid save/restore overhead. */
6688 cfun
->machine
->base_reg
= NULL_RTX
;
6689 else if (current_function_is_leaf
&& !regs_ever_live
[5])
6690 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, 5);
6692 cfun
->machine
->base_reg
= gen_rtx_REG (Pmode
, BASE_REGNUM
);
6694 s390_register_info (live_regs
);
6697 while (frame_size
!= cfun_frame_layout
.frame_size
);
6700 /* Update frame layout. Recompute actual register save data based on
6701 current info and update regs_ever_live for the special registers.
6702 May be called multiple times, but may never cause *more* registers
6703 to be saved than s390_init_frame_layout allocated room for. */
6706 s390_update_frame_layout (void)
6710 s390_register_info (live_regs
);
6712 regs_ever_live
[BASE_REGNUM
] = live_regs
[BASE_REGNUM
];
6713 regs_ever_live
[RETURN_REGNUM
] = live_regs
[RETURN_REGNUM
];
6714 regs_ever_live
[STACK_POINTER_REGNUM
] = live_regs
[STACK_POINTER_REGNUM
];
6716 if (cfun
->machine
->base_reg
)
6717 regs_ever_live
[REGNO (cfun
->machine
->base_reg
)] = 1;
6720 /* Return true if register FROM can be eliminated via register TO. */
6723 s390_can_eliminate (int from
, int to
)
6725 gcc_assert (to
== STACK_POINTER_REGNUM
6726 || to
== HARD_FRAME_POINTER_REGNUM
);
6728 gcc_assert (from
== FRAME_POINTER_REGNUM
6729 || from
== ARG_POINTER_REGNUM
6730 || from
== RETURN_ADDRESS_POINTER_REGNUM
);
6732 /* Make sure we actually saved the return address. */
6733 if (from
== RETURN_ADDRESS_POINTER_REGNUM
)
6734 if (!current_function_calls_eh_return
6735 && !current_function_stdarg
6736 && !cfun_frame_layout
.save_return_addr_p
)
6742 /* Return offset between register FROM and TO initially after prolog. */
6745 s390_initial_elimination_offset (int from
, int to
)
6747 HOST_WIDE_INT offset
;
6750 /* ??? Why are we called for non-eliminable pairs? */
6751 if (!s390_can_eliminate (from
, to
))
6756 case FRAME_POINTER_REGNUM
:
6760 case ARG_POINTER_REGNUM
:
6761 s390_init_frame_layout ();
6762 offset
= cfun_frame_layout
.frame_size
+ STACK_POINTER_OFFSET
;
6765 case RETURN_ADDRESS_POINTER_REGNUM
:
6766 s390_init_frame_layout ();
6767 index
= RETURN_REGNUM
- cfun_frame_layout
.first_save_gpr
;
6768 gcc_assert (index
>= 0);
6769 offset
= cfun_frame_layout
.frame_size
+ cfun_frame_layout
.gprs_offset
;
6770 offset
+= index
* UNITS_PER_WORD
;
6780 /* Emit insn to save fpr REGNUM at offset OFFSET relative
6781 to register BASE. Return generated insn. */
6784 save_fpr (rtx base
, int offset
, int regnum
)
6787 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
6788 set_mem_alias_set (addr
, s390_sr_alias_set
);
6790 return emit_move_insn (addr
, gen_rtx_REG (DFmode
, regnum
));
6793 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
6794 to register BASE. Return generated insn. */
6797 restore_fpr (rtx base
, int offset
, int regnum
)
6800 addr
= gen_rtx_MEM (DFmode
, plus_constant (base
, offset
));
6801 set_mem_alias_set (addr
, s390_sr_alias_set
);
6803 return emit_move_insn (gen_rtx_REG (DFmode
, regnum
), addr
);
6806 /* Generate insn to save registers FIRST to LAST into
6807 the register save area located at offset OFFSET
6808 relative to register BASE. */
6811 save_gprs (rtx base
, int offset
, int first
, int last
)
6813 rtx addr
, insn
, note
;
6816 addr
= plus_constant (base
, offset
);
6817 addr
= gen_rtx_MEM (Pmode
, addr
);
6818 set_mem_alias_set (addr
, s390_sr_alias_set
);
6820 /* Special-case single register. */
6824 insn
= gen_movdi (addr
, gen_rtx_REG (Pmode
, first
));
6826 insn
= gen_movsi (addr
, gen_rtx_REG (Pmode
, first
));
6828 RTX_FRAME_RELATED_P (insn
) = 1;
6833 insn
= gen_store_multiple (addr
,
6834 gen_rtx_REG (Pmode
, first
),
6835 GEN_INT (last
- first
+ 1));
6838 /* We need to set the FRAME_RELATED flag on all SETs
6839 inside the store-multiple pattern.
6841 However, we must not emit DWARF records for registers 2..5
6842 if they are stored for use by variable arguments ...
6844 ??? Unfortunately, it is not enough to simply not the the
6845 FRAME_RELATED flags for those SETs, because the first SET
6846 of the PARALLEL is always treated as if it had the flag
6847 set, even if it does not. Therefore we emit a new pattern
6848 without those registers as REG_FRAME_RELATED_EXPR note. */
6852 rtx pat
= PATTERN (insn
);
6854 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
6855 if (GET_CODE (XVECEXP (pat
, 0, i
)) == SET
)
6856 RTX_FRAME_RELATED_P (XVECEXP (pat
, 0, i
)) = 1;
6858 RTX_FRAME_RELATED_P (insn
) = 1;
6862 addr
= plus_constant (base
, offset
+ (6 - first
) * UNITS_PER_WORD
);
6863 note
= gen_store_multiple (gen_rtx_MEM (Pmode
, addr
),
6864 gen_rtx_REG (Pmode
, 6),
6865 GEN_INT (last
- 6 + 1));
6866 note
= PATTERN (note
);
6869 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
6870 note
, REG_NOTES (insn
));
6872 for (i
= 0; i
< XVECLEN (note
, 0); i
++)
6873 if (GET_CODE (XVECEXP (note
, 0, i
)) == SET
)
6874 RTX_FRAME_RELATED_P (XVECEXP (note
, 0, i
)) = 1;
6876 RTX_FRAME_RELATED_P (insn
) = 1;
6882 /* Generate insn to restore registers FIRST to LAST from
6883 the register save area located at offset OFFSET
6884 relative to register BASE. */
6887 restore_gprs (rtx base
, int offset
, int first
, int last
)
6891 addr
= plus_constant (base
, offset
);
6892 addr
= gen_rtx_MEM (Pmode
, addr
);
6893 set_mem_alias_set (addr
, s390_sr_alias_set
);
6895 /* Special-case single register. */
6899 insn
= gen_movdi (gen_rtx_REG (Pmode
, first
), addr
);
6901 insn
= gen_movsi (gen_rtx_REG (Pmode
, first
), addr
);
6906 insn
= gen_load_multiple (gen_rtx_REG (Pmode
, first
),
6908 GEN_INT (last
- first
+ 1));
6912 /* Return insn sequence to load the GOT register. */
6914 static GTY(()) rtx got_symbol
;
6916 s390_load_got (void)
6922 got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
6923 SYMBOL_REF_FLAGS (got_symbol
) = SYMBOL_FLAG_LOCAL
;
6928 if (TARGET_CPU_ZARCH
)
6930 emit_move_insn (pic_offset_table_rtx
, got_symbol
);
6936 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, got_symbol
),
6937 UNSPEC_LTREL_OFFSET
);
6938 offset
= gen_rtx_CONST (Pmode
, offset
);
6939 offset
= force_const_mem (Pmode
, offset
);
6941 emit_move_insn (pic_offset_table_rtx
, offset
);
6943 offset
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, XEXP (offset
, 0)),
6945 offset
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, offset
);
6947 emit_move_insn (pic_offset_table_rtx
, offset
);
6950 insns
= get_insns ();
6955 /* Expand the prologue into a bunch of separate insns. */
6958 s390_emit_prologue (void)
6966 /* Complete frame layout. */
6968 s390_update_frame_layout ();
6970 /* Annotate all constant pool references to let the scheduler know
6971 they implicitly use the base register. */
6973 push_topmost_sequence ();
6975 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6977 annotate_constant_pool_refs (&PATTERN (insn
));
6979 pop_topmost_sequence ();
6981 /* Choose best register to use for temp use within prologue.
6982 See below for why TPF must use the register 1. */
6984 if (!current_function_is_leaf
&& !TARGET_TPF_PROFILING
)
6985 temp_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
6987 temp_reg
= gen_rtx_REG (Pmode
, 1);
6989 /* Save call saved gprs. */
6990 if (cfun_frame_layout
.first_save_gpr
!= -1)
6992 insn
= save_gprs (stack_pointer_rtx
,
6993 cfun_frame_layout
.gprs_offset
,
6994 cfun_frame_layout
.first_save_gpr
,
6995 cfun_frame_layout
.last_save_gpr
);
6999 /* Dummy insn to mark literal pool slot. */
7001 if (cfun
->machine
->base_reg
)
7002 emit_insn (gen_main_pool (cfun
->machine
->base_reg
));
7004 offset
= cfun_frame_layout
.f0_offset
;
7006 /* Save f0 and f2. */
7007 for (i
= 0; i
< 2; i
++)
7009 if (cfun_fpr_bit_p (i
))
7011 save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
7014 else if (!TARGET_PACKED_STACK
)
7018 /* Save f4 and f6. */
7019 offset
= cfun_frame_layout
.f4_offset
;
7020 for (i
= 2; i
< 4; i
++)
7022 if (cfun_fpr_bit_p (i
))
7024 insn
= save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
7027 /* If f4 and f6 are call clobbered they are saved due to stdargs and
7028 therefore are not frame related. */
7029 if (!call_really_used_regs
[i
+ 16])
7030 RTX_FRAME_RELATED_P (insn
) = 1;
7032 else if (!TARGET_PACKED_STACK
)
7036 if (TARGET_PACKED_STACK
7037 && cfun_save_high_fprs_p
7038 && cfun_frame_layout
.f8_offset
+ cfun_frame_layout
.high_fprs
* 8 > 0)
7040 offset
= (cfun_frame_layout
.f8_offset
7041 + (cfun_frame_layout
.high_fprs
- 1) * 8);
7043 for (i
= 15; i
> 7 && offset
>= 0; i
--)
7044 if (cfun_fpr_bit_p (i
))
7046 insn
= save_fpr (stack_pointer_rtx
, offset
, i
+ 16);
7048 RTX_FRAME_RELATED_P (insn
) = 1;
7051 if (offset
>= cfun_frame_layout
.f8_offset
)
7055 if (!TARGET_PACKED_STACK
)
7056 next_fpr
= cfun_save_high_fprs_p
? 31 : 0;
7058 /* Decrement stack pointer. */
7060 if (cfun_frame_layout
.frame_size
> 0)
7062 rtx frame_off
= GEN_INT (-cfun_frame_layout
.frame_size
);
7064 if (s390_stack_size
)
7066 HOST_WIDE_INT stack_check_mask
= ((s390_stack_size
- 1)
7067 & ~(s390_stack_guard
- 1));
7068 rtx t
= gen_rtx_AND (Pmode
, stack_pointer_rtx
,
7069 GEN_INT (stack_check_mask
));
7072 gen_cmpdi (t
, const0_rtx
);
7074 gen_cmpsi (t
, const0_rtx
);
7076 emit_insn (gen_conditional_trap (gen_rtx_EQ (CCmode
,
7077 gen_rtx_REG (CCmode
,
7083 if (s390_warn_framesize
> 0
7084 && cfun_frame_layout
.frame_size
>= s390_warn_framesize
)
7085 warning ("frame size of %qs is " HOST_WIDE_INT_PRINT_DEC
" bytes",
7086 current_function_name (), cfun_frame_layout
.frame_size
);
7088 if (s390_warn_dynamicstack_p
&& cfun
->calls_alloca
)
7089 warning ("%qs uses dynamic stack allocation", current_function_name ());
7091 /* Save incoming stack pointer into temp reg. */
7092 if (TARGET_BACKCHAIN
|| next_fpr
)
7093 insn
= emit_insn (gen_move_insn (temp_reg
, stack_pointer_rtx
));
7095 /* Subtract frame size from stack pointer. */
7097 if (DISP_IN_RANGE (INTVAL (frame_off
)))
7099 insn
= gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
7100 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
7102 insn
= emit_insn (insn
);
7106 if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off
), 'K', "K"))
7107 frame_off
= force_const_mem (Pmode
, frame_off
);
7109 insn
= emit_insn (gen_add2_insn (stack_pointer_rtx
, frame_off
));
7110 annotate_constant_pool_refs (&PATTERN (insn
));
7113 RTX_FRAME_RELATED_P (insn
) = 1;
7115 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
7116 gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
7117 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
7118 GEN_INT (-cfun_frame_layout
.frame_size
))),
7121 /* Set backchain. */
7123 if (TARGET_BACKCHAIN
)
7125 if (cfun_frame_layout
.backchain_offset
)
7126 addr
= gen_rtx_MEM (Pmode
,
7127 plus_constant (stack_pointer_rtx
,
7128 cfun_frame_layout
.backchain_offset
));
7130 addr
= gen_rtx_MEM (Pmode
, stack_pointer_rtx
);
7131 set_mem_alias_set (addr
, s390_sr_alias_set
);
7132 insn
= emit_insn (gen_move_insn (addr
, temp_reg
));
7135 /* If we support asynchronous exceptions (e.g. for Java),
7136 we need to make sure the backchain pointer is set up
7137 before any possibly trapping memory access. */
7139 if (TARGET_BACKCHAIN
&& flag_non_call_exceptions
)
7141 addr
= gen_rtx_MEM (BLKmode
, gen_rtx_SCRATCH (VOIDmode
));
7142 emit_insn (gen_rtx_CLOBBER (VOIDmode
, addr
));
7146 /* Save fprs 8 - 15 (64 bit ABI). */
7148 if (cfun_save_high_fprs_p
&& next_fpr
)
7150 insn
= emit_insn (gen_add2_insn (temp_reg
,
7151 GEN_INT (cfun_frame_layout
.f8_offset
)));
7155 for (i
= 24; i
<= next_fpr
; i
++)
7156 if (cfun_fpr_bit_p (i
- 16))
7158 rtx addr
= plus_constant (stack_pointer_rtx
,
7159 cfun_frame_layout
.frame_size
7160 + cfun_frame_layout
.f8_offset
7163 insn
= save_fpr (temp_reg
, offset
, i
);
7165 RTX_FRAME_RELATED_P (insn
) = 1;
7167 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
7168 gen_rtx_SET (VOIDmode
,
7169 gen_rtx_MEM (DFmode
, addr
),
7170 gen_rtx_REG (DFmode
, i
)),
7175 /* Set frame pointer, if needed. */
7177 if (frame_pointer_needed
)
7179 insn
= emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
);
7180 RTX_FRAME_RELATED_P (insn
) = 1;
7183 /* Set up got pointer, if needed. */
7185 if (flag_pic
&& regs_ever_live
[PIC_OFFSET_TABLE_REGNUM
])
7187 rtx insns
= s390_load_got ();
7189 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
7191 annotate_constant_pool_refs (&PATTERN (insn
));
7193 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD
, NULL_RTX
,
7200 if (TARGET_TPF_PROFILING
)
7202 /* Generate a BAS instruction to serve as a function
7203 entry intercept to facilitate the use of tracing
7204 algorithms located at the branch target. */
7205 emit_insn (gen_prologue_tpf ());
7207 /* Emit a blockage here so that all code
7208 lies between the profiling mechanisms. */
7209 emit_insn (gen_blockage ());
7213 /* Expand the epilogue into a bunch of separate insns. */
7216 s390_emit_epilogue (bool sibcall
)
7218 rtx frame_pointer
, return_reg
;
7219 int area_bottom
, area_top
, offset
= 0;
7224 if (TARGET_TPF_PROFILING
)
7227 /* Generate a BAS instruction to serve as a function
7228 entry intercept to facilitate the use of tracing
7229 algorithms located at the branch target. */
7231 /* Emit a blockage here so that all code
7232 lies between the profiling mechanisms. */
7233 emit_insn (gen_blockage ());
7235 emit_insn (gen_epilogue_tpf ());
7238 /* Check whether to use frame or stack pointer for restore. */
7240 frame_pointer
= (frame_pointer_needed
7241 ? hard_frame_pointer_rtx
: stack_pointer_rtx
);
7243 s390_frame_area (&area_bottom
, &area_top
);
7245 /* Check whether we can access the register save area.
7246 If not, increment the frame pointer as required. */
7248 if (area_top
<= area_bottom
)
7250 /* Nothing to restore. */
7252 else if (DISP_IN_RANGE (cfun_frame_layout
.frame_size
+ area_bottom
)
7253 && DISP_IN_RANGE (cfun_frame_layout
.frame_size
+ area_top
- 1))
7255 /* Area is in range. */
7256 offset
= cfun_frame_layout
.frame_size
;
7260 rtx insn
, frame_off
;
7262 offset
= area_bottom
< 0 ? -area_bottom
: 0;
7263 frame_off
= GEN_INT (cfun_frame_layout
.frame_size
- offset
);
7265 if (DISP_IN_RANGE (INTVAL (frame_off
)))
7267 insn
= gen_rtx_SET (VOIDmode
, frame_pointer
,
7268 gen_rtx_PLUS (Pmode
, frame_pointer
, frame_off
));
7269 insn
= emit_insn (insn
);
7273 if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off
), 'K', "K"))
7274 frame_off
= force_const_mem (Pmode
, frame_off
);
7276 insn
= emit_insn (gen_add2_insn (frame_pointer
, frame_off
));
7277 annotate_constant_pool_refs (&PATTERN (insn
));
7281 /* Restore call saved fprs. */
7285 if (cfun_save_high_fprs_p
)
7287 next_offset
= cfun_frame_layout
.f8_offset
;
7288 for (i
= 24; i
< 32; i
++)
7290 if (cfun_fpr_bit_p (i
- 16))
7292 restore_fpr (frame_pointer
,
7293 offset
+ next_offset
, i
);
7302 next_offset
= cfun_frame_layout
.f4_offset
;
7303 for (i
= 18; i
< 20; i
++)
7305 if (cfun_fpr_bit_p (i
- 16))
7307 restore_fpr (frame_pointer
,
7308 offset
+ next_offset
, i
);
7311 else if (!TARGET_PACKED_STACK
)
7317 /* Return register. */
7319 return_reg
= gen_rtx_REG (Pmode
, RETURN_REGNUM
);
7321 /* Restore call saved gprs. */
7323 if (cfun_frame_layout
.first_restore_gpr
!= -1)
7328 /* Check for global register and save them
7329 to stack location from where they get restored. */
7331 for (i
= cfun_frame_layout
.first_restore_gpr
;
7332 i
<= cfun_frame_layout
.last_restore_gpr
;
7335 /* These registers are special and need to be
7336 restored in any case. */
7337 if (i
== STACK_POINTER_REGNUM
7338 || i
== RETURN_REGNUM
7340 || (flag_pic
&& i
== (int)PIC_OFFSET_TABLE_REGNUM
))
7345 addr
= plus_constant (frame_pointer
,
7346 offset
+ cfun_frame_layout
.gprs_offset
7347 + (i
- cfun_frame_layout
.first_save_gpr
)
7349 addr
= gen_rtx_MEM (Pmode
, addr
);
7350 set_mem_alias_set (addr
, s390_sr_alias_set
);
7351 emit_move_insn (addr
, gen_rtx_REG (Pmode
, i
));
7357 /* Fetch return address from stack before load multiple,
7358 this will do good for scheduling. */
7360 if (cfun_frame_layout
.save_return_addr_p
7361 || (cfun_frame_layout
.first_restore_gpr
< BASE_REGNUM
7362 && cfun_frame_layout
.last_restore_gpr
> RETURN_REGNUM
))
7364 int return_regnum
= find_unused_clobbered_reg();
7367 return_reg
= gen_rtx_REG (Pmode
, return_regnum
);
7369 addr
= plus_constant (frame_pointer
,
7370 offset
+ cfun_frame_layout
.gprs_offset
7372 - cfun_frame_layout
.first_save_gpr
)
7374 addr
= gen_rtx_MEM (Pmode
, addr
);
7375 set_mem_alias_set (addr
, s390_sr_alias_set
);
7376 emit_move_insn (return_reg
, addr
);
7380 insn
= restore_gprs (frame_pointer
,
7381 offset
+ cfun_frame_layout
.gprs_offset
7382 + (cfun_frame_layout
.first_restore_gpr
7383 - cfun_frame_layout
.first_save_gpr
)
7385 cfun_frame_layout
.first_restore_gpr
,
7386 cfun_frame_layout
.last_restore_gpr
);
7393 /* Return to caller. */
7395 p
= rtvec_alloc (2);
7397 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
7398 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
, return_reg
);
7399 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
7404 /* Return the size in bytes of a function argument of
7405 type TYPE and/or mode MODE. At least one of TYPE or
7406 MODE must be specified. */
7409 s390_function_arg_size (enum machine_mode mode
, tree type
)
7412 return int_size_in_bytes (type
);
7414 /* No type info available for some library calls ... */
7415 if (mode
!= BLKmode
)
7416 return GET_MODE_SIZE (mode
);
7418 /* If we have neither type nor mode, abort */
7422 /* Return true if a function argument of type TYPE and mode MODE
7423 is to be passed in a floating-point register, if available. */
7426 s390_function_arg_float (enum machine_mode mode
, tree type
)
7428 int size
= s390_function_arg_size (mode
, type
);
7432 /* Soft-float changes the ABI: no floating-point registers are used. */
7433 if (TARGET_SOFT_FLOAT
)
7436 /* No type info available for some library calls ... */
7438 return mode
== SFmode
|| mode
== DFmode
;
7440 /* The ABI says that record types with a single member are treated
7441 just like that member would be. */
7442 while (TREE_CODE (type
) == RECORD_TYPE
)
7444 tree field
, single
= NULL_TREE
;
7446 for (field
= TYPE_FIELDS (type
); field
; field
= TREE_CHAIN (field
))
7448 if (TREE_CODE (field
) != FIELD_DECL
)
7451 if (single
== NULL_TREE
)
7452 single
= TREE_TYPE (field
);
7457 if (single
== NULL_TREE
)
7463 return TREE_CODE (type
) == REAL_TYPE
;
7466 /* Return true if a function argument of type TYPE and mode MODE
7467 is to be passed in an integer register, or a pair of integer
7468 registers, if available. */
7471 s390_function_arg_integer (enum machine_mode mode
, tree type
)
7473 int size
= s390_function_arg_size (mode
, type
);
7477 /* No type info available for some library calls ... */
7479 return GET_MODE_CLASS (mode
) == MODE_INT
7480 || (TARGET_SOFT_FLOAT
&& GET_MODE_CLASS (mode
) == MODE_FLOAT
);
7482 /* We accept small integral (and similar) types. */
7483 if (INTEGRAL_TYPE_P (type
)
7484 || POINTER_TYPE_P (type
)
7485 || TREE_CODE (type
) == OFFSET_TYPE
7486 || (TARGET_SOFT_FLOAT
&& TREE_CODE (type
) == REAL_TYPE
))
7489 /* We also accept structs of size 1, 2, 4, 8 that are not
7490 passed in floating-point registers. */
7491 if (AGGREGATE_TYPE_P (type
)
7492 && exact_log2 (size
) >= 0
7493 && !s390_function_arg_float (mode
, type
))
7499 /* Return 1 if a function argument of type TYPE and mode MODE
7500 is to be passed by reference. The ABI specifies that only
7501 structures of size 1, 2, 4, or 8 bytes are passed by value,
7502 all other structures (and complex numbers) are passed by
7506 s390_pass_by_reference (CUMULATIVE_ARGS
*ca ATTRIBUTE_UNUSED
,
7507 enum machine_mode mode
, tree type
,
7508 bool named ATTRIBUTE_UNUSED
)
7510 int size
= s390_function_arg_size (mode
, type
);
7516 if (AGGREGATE_TYPE_P (type
) && exact_log2 (size
) < 0)
7519 if (TREE_CODE (type
) == COMPLEX_TYPE
7520 || TREE_CODE (type
) == VECTOR_TYPE
)
7527 /* Update the data in CUM to advance over an argument of mode MODE and
7528 data type TYPE. (TYPE is null for libcalls where that information
7529 may not be available.). The boolean NAMED specifies whether the
7530 argument is a named argument (as opposed to an unnamed argument
7531 matching an ellipsis). */
7534 s390_function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
7535 tree type
, int named ATTRIBUTE_UNUSED
)
7537 if (s390_function_arg_float (mode
, type
))
7541 else if (s390_function_arg_integer (mode
, type
))
7543 int size
= s390_function_arg_size (mode
, type
);
7544 cum
->gprs
+= ((size
+ UNITS_PER_WORD
-1) / UNITS_PER_WORD
);
7550 /* Define where to put the arguments to a function.
7551 Value is zero to push the argument on the stack,
7552 or a hard register in which to store the argument.
7554 MODE is the argument's machine mode.
7555 TYPE is the data type of the argument (as a tree).
7556 This is null for libcalls where that information may
7558 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7559 the preceding args and about the function being called.
7560 NAMED is nonzero if this argument is a named parameter
7561 (otherwise it is an extra parameter matching an ellipsis).
7563 On S/390, we use general purpose registers 2 through 6 to
7564 pass integer, pointer, and certain structure arguments, and
7565 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
7566 to pass floating point arguments. All remaining arguments
7567 are pushed to the stack. */
7570 s390_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
, tree type
,
7571 int named ATTRIBUTE_UNUSED
)
7573 if (s390_function_arg_float (mode
, type
))
7575 if (cum
->fprs
+ 1 > (TARGET_64BIT
? 4 : 2))
7578 return gen_rtx_REG (mode
, cum
->fprs
+ 16);
7580 else if (s390_function_arg_integer (mode
, type
))
7582 int size
= s390_function_arg_size (mode
, type
);
7583 int n_gprs
= (size
+ UNITS_PER_WORD
-1) / UNITS_PER_WORD
;
7585 if (cum
->gprs
+ n_gprs
> 5)
7588 return gen_rtx_REG (mode
, cum
->gprs
+ 2);
7591 /* After the real arguments, expand_call calls us once again
7592 with a void_type_node type. Whatever we return here is
7593 passed as operand 2 to the call expanders.
7595 We don't need this feature ... */
7596 else if (type
== void_type_node
)
7602 /* Return true if return values of type TYPE should be returned
7603 in a memory buffer whose address is passed by the caller as
7604 hidden first argument. */
7607 s390_return_in_memory (tree type
, tree fundecl ATTRIBUTE_UNUSED
)
7609 /* We accept small integral (and similar) types. */
7610 if (INTEGRAL_TYPE_P (type
)
7611 || POINTER_TYPE_P (type
)
7612 || TREE_CODE (type
) == OFFSET_TYPE
7613 || TREE_CODE (type
) == REAL_TYPE
)
7614 return int_size_in_bytes (type
) > 8;
7616 /* Aggregates and similar constructs are always returned
7618 if (AGGREGATE_TYPE_P (type
)
7619 || TREE_CODE (type
) == COMPLEX_TYPE
7620 || TREE_CODE (type
) == VECTOR_TYPE
)
7623 /* ??? We get called on all sorts of random stuff from
7624 aggregate_value_p. We can't abort, but it's not clear
7625 what's safe to return. Pretend it's a struct I guess. */
7629 /* Define where to return a (scalar) value of type TYPE.
7630 If TYPE is null, define where to return a (scalar)
7631 value of mode MODE from a libcall. */
7634 s390_function_value (tree type
, enum machine_mode mode
)
7638 int unsignedp
= TYPE_UNSIGNED (type
);
7639 mode
= promote_mode (type
, TYPE_MODE (type
), &unsignedp
, 1);
7642 if (GET_MODE_CLASS (mode
) != MODE_INT
7643 && GET_MODE_CLASS (mode
) != MODE_FLOAT
)
7645 if (GET_MODE_SIZE (mode
) > 8)
7648 if (TARGET_HARD_FLOAT
&& GET_MODE_CLASS (mode
) == MODE_FLOAT
)
7649 return gen_rtx_REG (mode
, 16);
7651 return gen_rtx_REG (mode
, 2);
7655 /* Create and return the va_list datatype.
7657 On S/390, va_list is an array type equivalent to
7659 typedef struct __va_list_tag
7663 void *__overflow_arg_area;
7664 void *__reg_save_area;
7667 where __gpr and __fpr hold the number of general purpose
7668 or floating point arguments used up to now, respectively,
7669 __overflow_arg_area points to the stack location of the
7670 next argument passed on the stack, and __reg_save_area
7671 always points to the start of the register area in the
7672 call frame of the current function. The function prologue
7673 saves all registers used for argument passing into this
7674 area if the function uses variable arguments. */
7677 s390_build_builtin_va_list (void)
7679 tree f_gpr
, f_fpr
, f_ovf
, f_sav
, record
, type_decl
;
7681 record
= lang_hooks
.types
.make_type (RECORD_TYPE
);
7684 build_decl (TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
7686 f_gpr
= build_decl (FIELD_DECL
, get_identifier ("__gpr"),
7687 long_integer_type_node
);
7688 f_fpr
= build_decl (FIELD_DECL
, get_identifier ("__fpr"),
7689 long_integer_type_node
);
7690 f_ovf
= build_decl (FIELD_DECL
, get_identifier ("__overflow_arg_area"),
7692 f_sav
= build_decl (FIELD_DECL
, get_identifier ("__reg_save_area"),
7695 DECL_FIELD_CONTEXT (f_gpr
) = record
;
7696 DECL_FIELD_CONTEXT (f_fpr
) = record
;
7697 DECL_FIELD_CONTEXT (f_ovf
) = record
;
7698 DECL_FIELD_CONTEXT (f_sav
) = record
;
7700 TREE_CHAIN (record
) = type_decl
;
7701 TYPE_NAME (record
) = type_decl
;
7702 TYPE_FIELDS (record
) = f_gpr
;
7703 TREE_CHAIN (f_gpr
) = f_fpr
;
7704 TREE_CHAIN (f_fpr
) = f_ovf
;
7705 TREE_CHAIN (f_ovf
) = f_sav
;
7707 layout_type (record
);
7709 /* The correct type is an array type of one element. */
7710 return build_array_type (record
, build_index_type (size_zero_node
));
7713 /* Implement va_start by filling the va_list structure VALIST.
7714 STDARG_P is always true, and ignored.
7715 NEXTARG points to the first anonymous stack argument.
7717 The following global variables are used to initialize
7718 the va_list structure:
7720 current_function_args_info:
7721 holds number of gprs and fprs used for named arguments.
7722 current_function_arg_offset_rtx:
7723 holds the offset of the first anonymous stack argument
7724 (relative to the virtual arg pointer). */
7727 s390_va_start (tree valist
, rtx nextarg ATTRIBUTE_UNUSED
)
7729 HOST_WIDE_INT n_gpr
, n_fpr
;
7731 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
7732 tree gpr
, fpr
, ovf
, sav
, t
;
7734 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
7735 f_fpr
= TREE_CHAIN (f_gpr
);
7736 f_ovf
= TREE_CHAIN (f_fpr
);
7737 f_sav
= TREE_CHAIN (f_ovf
);
7739 valist
= build_va_arg_indirect_ref (valist
);
7740 gpr
= build (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
7741 fpr
= build (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
7742 ovf
= build (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
7743 sav
= build (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
7745 /* Count number of gp and fp argument registers used. */
7747 n_gpr
= current_function_args_info
.gprs
;
7748 n_fpr
= current_function_args_info
.fprs
;
7750 t
= build (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
,
7751 build_int_cst (NULL_TREE
, n_gpr
));
7752 TREE_SIDE_EFFECTS (t
) = 1;
7753 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7755 t
= build (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
,
7756 build_int_cst (NULL_TREE
, n_fpr
));
7757 TREE_SIDE_EFFECTS (t
) = 1;
7758 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7760 /* Find the overflow area. */
7761 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
7763 off
= INTVAL (current_function_arg_offset_rtx
);
7764 off
= off
< 0 ? 0 : off
;
7765 if (TARGET_DEBUG_ARG
)
7766 fprintf (stderr
, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
7767 (int)n_gpr
, (int)n_fpr
, off
);
7769 t
= build (PLUS_EXPR
, TREE_TYPE (ovf
), t
, build_int_cst (NULL_TREE
, off
));
7771 t
= build (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
7772 TREE_SIDE_EFFECTS (t
) = 1;
7773 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7775 /* Find the register save area. */
7776 t
= make_tree (TREE_TYPE (sav
), return_address_pointer_rtx
);
7777 t
= build (PLUS_EXPR
, TREE_TYPE (sav
), t
,
7778 build_int_cst (NULL_TREE
, -RETURN_REGNUM
* UNITS_PER_WORD
));
7780 t
= build (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
7781 TREE_SIDE_EFFECTS (t
) = 1;
7782 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
7785 /* Implement va_arg by updating the va_list structure
7786 VALIST as required to retrieve an argument of type
7787 TYPE, and returning that argument.
7789 Generates code equivalent to:
7791 if (integral value) {
7792 if (size <= 4 && args.gpr < 5 ||
7793 size > 4 && args.gpr < 4 )
7794 ret = args.reg_save_area[args.gpr+8]
7796 ret = *args.overflow_arg_area++;
7797 } else if (float value) {
7799 ret = args.reg_save_area[args.fpr+64]
7801 ret = *args.overflow_arg_area++;
7802 } else if (aggregate value) {
7804 ret = *args.reg_save_area[args.gpr]
7806 ret = **args.overflow_arg_area++;
7810 s390_gimplify_va_arg (tree valist
, tree type
, tree
*pre_p
,
7811 tree
*post_p ATTRIBUTE_UNUSED
)
7813 tree f_gpr
, f_fpr
, f_ovf
, f_sav
;
7814 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
7815 int indirect_p
, size
, n_reg
, sav_ofs
, sav_scale
, max_reg
;
7816 tree lab_false
, lab_over
, addr
;
7818 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
7819 f_fpr
= TREE_CHAIN (f_gpr
);
7820 f_ovf
= TREE_CHAIN (f_fpr
);
7821 f_sav
= TREE_CHAIN (f_ovf
);
7823 valist
= build_va_arg_indirect_ref (valist
);
7824 gpr
= build (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
7825 fpr
= build (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
7826 ovf
= build (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
7827 sav
= build (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
7829 size
= int_size_in_bytes (type
);
7831 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
7833 if (TARGET_DEBUG_ARG
)
7835 fprintf (stderr
, "va_arg: aggregate type");
7839 /* Aggregates are passed by reference. */
7844 /* kernel stack layout on 31 bit: It is assumed here that no padding
7845 will be added by s390_frame_info because for va_args always an even
7846 number of gprs has to be saved r15-r2 = 14 regs. */
7847 sav_ofs
= 2 * UNITS_PER_WORD
;
7848 sav_scale
= UNITS_PER_WORD
;
7849 size
= UNITS_PER_WORD
;
7852 else if (s390_function_arg_float (TYPE_MODE (type
), type
))
7854 if (TARGET_DEBUG_ARG
)
7856 fprintf (stderr
, "va_arg: float type");
7860 /* FP args go in FP registers, if present. */
7864 sav_ofs
= 16 * UNITS_PER_WORD
;
7866 /* TARGET_64BIT has up to 4 parameter in fprs */
7867 max_reg
= TARGET_64BIT
? 3 : 1;
7871 if (TARGET_DEBUG_ARG
)
7873 fprintf (stderr
, "va_arg: other type");
7877 /* Otherwise into GP registers. */
7880 n_reg
= (size
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
7882 /* kernel stack layout on 31 bit: It is assumed here that no padding
7883 will be added by s390_frame_info because for va_args always an even
7884 number of gprs has to be saved r15-r2 = 14 regs. */
7885 sav_ofs
= 2 * UNITS_PER_WORD
;
7887 if (size
< UNITS_PER_WORD
)
7888 sav_ofs
+= UNITS_PER_WORD
- size
;
7890 sav_scale
= UNITS_PER_WORD
;
7897 /* Pull the value out of the saved registers ... */
7899 lab_false
= create_artificial_label ();
7900 lab_over
= create_artificial_label ();
7901 addr
= create_tmp_var (ptr_type_node
, "addr");
7902 DECL_POINTER_ALIAS_SET (addr
) = s390_sr_alias_set
;
7904 t
= fold_convert (TREE_TYPE (reg
), size_int (max_reg
));
7905 t
= build2 (GT_EXPR
, boolean_type_node
, reg
, t
);
7906 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
7907 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
7908 gimplify_and_add (t
, pre_p
);
7910 t
= build2 (PLUS_EXPR
, ptr_type_node
, sav
,
7911 fold_convert (ptr_type_node
, size_int (sav_ofs
)));
7912 u
= build2 (MULT_EXPR
, TREE_TYPE (reg
), reg
,
7913 fold_convert (TREE_TYPE (reg
), size_int (sav_scale
)));
7914 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
, fold_convert (ptr_type_node
, u
));
7916 t
= build2 (MODIFY_EXPR
, void_type_node
, addr
, t
);
7917 gimplify_and_add (t
, pre_p
);
7919 t
= build1 (GOTO_EXPR
, void_type_node
, lab_over
);
7920 gimplify_and_add (t
, pre_p
);
7922 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false
);
7923 append_to_statement_list (t
, pre_p
);
7926 /* ... Otherwise out of the overflow area. */
7929 if (size
< UNITS_PER_WORD
)
7930 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
,
7931 fold_convert (ptr_type_node
, size_int (UNITS_PER_WORD
- size
)));
7933 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
7935 u
= build2 (MODIFY_EXPR
, void_type_node
, addr
, t
);
7936 gimplify_and_add (u
, pre_p
);
7938 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
,
7939 fold_convert (ptr_type_node
, size_int (size
)));
7940 t
= build2 (MODIFY_EXPR
, ptr_type_node
, ovf
, t
);
7941 gimplify_and_add (t
, pre_p
);
7943 t
= build1 (LABEL_EXPR
, void_type_node
, lab_over
);
7944 append_to_statement_list (t
, pre_p
);
7947 /* Increment register save count. */
7949 u
= build2 (PREINCREMENT_EXPR
, TREE_TYPE (reg
), reg
,
7950 fold_convert (TREE_TYPE (reg
), size_int (n_reg
)));
7951 gimplify_and_add (u
, pre_p
);
7955 t
= build_pointer_type (build_pointer_type (type
));
7956 addr
= fold_convert (t
, addr
);
7957 addr
= build_va_arg_indirect_ref (addr
);
7961 t
= build_pointer_type (type
);
7962 addr
= fold_convert (t
, addr
);
7965 return build_va_arg_indirect_ref (addr
);
7973 S390_BUILTIN_THREAD_POINTER
,
7974 S390_BUILTIN_SET_THREAD_POINTER
,
7979 static unsigned int const code_for_builtin_64
[S390_BUILTIN_max
] = {
7984 static unsigned int const code_for_builtin_31
[S390_BUILTIN_max
] = {
7990 s390_init_builtins (void)
7994 ftype
= build_function_type (ptr_type_node
, void_list_node
);
7995 lang_hooks
.builtin_function ("__builtin_thread_pointer", ftype
,
7996 S390_BUILTIN_THREAD_POINTER
, BUILT_IN_MD
,
7999 ftype
= build_function_type_list (void_type_node
, ptr_type_node
, NULL_TREE
);
8000 lang_hooks
.builtin_function ("__builtin_set_thread_pointer", ftype
,
8001 S390_BUILTIN_SET_THREAD_POINTER
, BUILT_IN_MD
,
8005 /* Expand an expression EXP that calls a built-in function,
8006 with result going to TARGET if that's convenient
8007 (and in mode MODE if that's convenient).
8008 SUBTARGET may be used as the target for computing one of EXP's operands.
8009 IGNORE is nonzero if the value is to be ignored. */
8012 s390_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
8013 enum machine_mode mode ATTRIBUTE_UNUSED
,
8014 int ignore ATTRIBUTE_UNUSED
)
8018 unsigned int const *code_for_builtin
=
8019 TARGET_64BIT
? code_for_builtin_64
: code_for_builtin_31
;
8021 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
8022 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8023 tree arglist
= TREE_OPERAND (exp
, 1);
8024 enum insn_code icode
;
8025 rtx op
[MAX_ARGS
], pat
;
8029 if (fcode
>= S390_BUILTIN_max
)
8030 internal_error ("bad builtin fcode");
8031 icode
= code_for_builtin
[fcode
];
8033 internal_error ("bad builtin fcode");
8035 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
8037 for (arglist
= TREE_OPERAND (exp
, 1), arity
= 0;
8039 arglist
= TREE_CHAIN (arglist
), arity
++)
8041 const struct insn_operand_data
*insn_op
;
8043 tree arg
= TREE_VALUE (arglist
);
8044 if (arg
== error_mark_node
)
8046 if (arity
> MAX_ARGS
)
8049 insn_op
= &insn_data
[icode
].operand
[arity
+ nonvoid
];
8051 op
[arity
] = expand_expr (arg
, NULL_RTX
, insn_op
->mode
, 0);
8053 if (!(*insn_op
->predicate
) (op
[arity
], insn_op
->mode
))
8054 op
[arity
] = copy_to_mode_reg (insn_op
->mode
, op
[arity
]);
8059 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8061 || GET_MODE (target
) != tmode
8062 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8063 target
= gen_reg_rtx (tmode
);
8069 pat
= GEN_FCN (icode
) (target
);
8073 pat
= GEN_FCN (icode
) (target
, op
[0]);
8075 pat
= GEN_FCN (icode
) (op
[0]);
8078 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
8094 /* Output assembly code for the trampoline template to
8097 On S/390, we use gpr 1 internally in the trampoline code;
8098 gpr 0 is used to hold the static chain. */
8101 s390_trampoline_template (FILE *file
)
8104 op
[0] = gen_rtx_REG (Pmode
, 0);
8105 op
[1] = gen_rtx_REG (Pmode
, 1);
8109 output_asm_insn ("basr\t%1,0", op
);
8110 output_asm_insn ("lmg\t%0,%1,14(%1)", op
);
8111 output_asm_insn ("br\t%1", op
);
8112 ASM_OUTPUT_SKIP (file
, (HOST_WIDE_INT
)(TRAMPOLINE_SIZE
- 10));
8116 output_asm_insn ("basr\t%1,0", op
);
8117 output_asm_insn ("lm\t%0,%1,6(%1)", op
);
8118 output_asm_insn ("br\t%1", op
);
8119 ASM_OUTPUT_SKIP (file
, (HOST_WIDE_INT
)(TRAMPOLINE_SIZE
- 8));
8123 /* Emit RTL insns to initialize the variable parts of a trampoline.
8124 FNADDR is an RTX for the address of the function's pure code.
8125 CXT is an RTX for the static chain value for the function. */
8128 s390_initialize_trampoline (rtx addr
, rtx fnaddr
, rtx cxt
)
8130 emit_move_insn (gen_rtx_MEM (Pmode
,
8131 memory_address (Pmode
,
8132 plus_constant (addr
, (TARGET_64BIT
? 16 : 8)))), cxt
);
8133 emit_move_insn (gen_rtx_MEM (Pmode
,
8134 memory_address (Pmode
,
8135 plus_constant (addr
, (TARGET_64BIT
? 24 : 12)))), fnaddr
);
8138 /* Return rtx for 64-bit constant formed from the 32-bit subwords
8139 LOW and HIGH, independent of the host word size. */
8142 s390_gen_rtx_const_DI (int high
, int low
)
8144 #if HOST_BITS_PER_WIDE_INT >= 64
8146 val
= (HOST_WIDE_INT
)high
;
8148 val
|= (HOST_WIDE_INT
)low
;
8150 return GEN_INT (val
);
8152 #if HOST_BITS_PER_WIDE_INT >= 32
8153 return immed_double_const ((HOST_WIDE_INT
)low
, (HOST_WIDE_INT
)high
, DImode
);
8160 /* Output assembler code to FILE to increment profiler label # LABELNO
8161 for profiling a function entry. */
8164 s390_function_profiler (FILE *file
, int labelno
)
8169 ASM_GENERATE_INTERNAL_LABEL (label
, "LP", labelno
);
8171 fprintf (file
, "# function profiler \n");
8173 op
[0] = gen_rtx_REG (Pmode
, RETURN_REGNUM
);
8174 op
[1] = gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
8175 op
[1] = gen_rtx_MEM (Pmode
, plus_constant (op
[1], UNITS_PER_WORD
));
8177 op
[2] = gen_rtx_REG (Pmode
, 1);
8178 op
[3] = gen_rtx_SYMBOL_REF (Pmode
, label
);
8179 SYMBOL_REF_FLAGS (op
[3]) = SYMBOL_FLAG_LOCAL
;
8181 op
[4] = gen_rtx_SYMBOL_REF (Pmode
, "_mcount");
8184 op
[4] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[4]), UNSPEC_PLT
);
8185 op
[4] = gen_rtx_CONST (Pmode
, op
[4]);
8190 output_asm_insn ("stg\t%0,%1", op
);
8191 output_asm_insn ("larl\t%2,%3", op
);
8192 output_asm_insn ("brasl\t%0,%4", op
);
8193 output_asm_insn ("lg\t%0,%1", op
);
8197 op
[6] = gen_label_rtx ();
8199 output_asm_insn ("st\t%0,%1", op
);
8200 output_asm_insn ("bras\t%2,%l6", op
);
8201 output_asm_insn (".long\t%4", op
);
8202 output_asm_insn (".long\t%3", op
);
8203 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
8204 output_asm_insn ("l\t%0,0(%2)", op
);
8205 output_asm_insn ("l\t%2,4(%2)", op
);
8206 output_asm_insn ("basr\t%0,%0", op
);
8207 output_asm_insn ("l\t%0,%1", op
);
8211 op
[5] = gen_label_rtx ();
8212 op
[6] = gen_label_rtx ();
8214 output_asm_insn ("st\t%0,%1", op
);
8215 output_asm_insn ("bras\t%2,%l6", op
);
8216 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[5]));
8217 output_asm_insn (".long\t%4-%l5", op
);
8218 output_asm_insn (".long\t%3-%l5", op
);
8219 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[6]));
8220 output_asm_insn ("lr\t%0,%2", op
);
8221 output_asm_insn ("a\t%0,0(%2)", op
);
8222 output_asm_insn ("a\t%2,4(%2)", op
);
8223 output_asm_insn ("basr\t%0,%0", op
);
8224 output_asm_insn ("l\t%0,%1", op
);
8228 /* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
8229 into its SYMBOL_REF_FLAGS. */
8232 s390_encode_section_info (tree decl
, rtx rtl
, int first
)
8234 default_encode_section_info (decl
, rtl
, first
);
8236 /* If a variable has a forced alignment to < 2 bytes, mark it with
8237 SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL operand. */
8238 if (TREE_CODE (decl
) == VAR_DECL
8239 && DECL_USER_ALIGN (decl
) && DECL_ALIGN (decl
) < 16)
8240 SYMBOL_REF_FLAGS (XEXP (rtl
, 0)) |= SYMBOL_FLAG_ALIGN1
;
8243 /* Output thunk to FILE that implements a C++ virtual function call (with
8244 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
8245 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
8246 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
8247 relative to the resulting this pointer. */
8250 s390_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
8251 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
8257 /* Operand 0 is the target function. */
8258 op
[0] = XEXP (DECL_RTL (function
), 0);
8259 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (op
[0]))
8262 op
[0] = gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, op
[0]),
8263 TARGET_64BIT
? UNSPEC_PLT
: UNSPEC_GOT
);
8264 op
[0] = gen_rtx_CONST (Pmode
, op
[0]);
8267 /* Operand 1 is the 'this' pointer. */
8268 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
8269 op
[1] = gen_rtx_REG (Pmode
, 3);
8271 op
[1] = gen_rtx_REG (Pmode
, 2);
8273 /* Operand 2 is the delta. */
8274 op
[2] = GEN_INT (delta
);
8276 /* Operand 3 is the vcall_offset. */
8277 op
[3] = GEN_INT (vcall_offset
);
8279 /* Operand 4 is the temporary register. */
8280 op
[4] = gen_rtx_REG (Pmode
, 1);
8282 /* Operands 5 to 8 can be used as labels. */
8288 /* Operand 9 can be used for temporary register. */
8291 /* Generate code. */
8294 /* Setup literal pool pointer if required. */
8295 if ((!DISP_IN_RANGE (delta
)
8296 && !CONST_OK_FOR_CONSTRAINT_P (delta
, 'K', "K"))
8297 || (!DISP_IN_RANGE (vcall_offset
)
8298 && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'K', "K")))
8300 op
[5] = gen_label_rtx ();
8301 output_asm_insn ("larl\t%4,%5", op
);
8304 /* Add DELTA to this pointer. */
8307 if (CONST_OK_FOR_CONSTRAINT_P (delta
, 'J', "J"))
8308 output_asm_insn ("la\t%1,%2(%1)", op
);
8309 else if (DISP_IN_RANGE (delta
))
8310 output_asm_insn ("lay\t%1,%2(%1)", op
);
8311 else if (CONST_OK_FOR_CONSTRAINT_P (delta
, 'K', "K"))
8312 output_asm_insn ("aghi\t%1,%2", op
);
8315 op
[6] = gen_label_rtx ();
8316 output_asm_insn ("agf\t%1,%6-%5(%4)", op
);
8320 /* Perform vcall adjustment. */
8323 if (DISP_IN_RANGE (vcall_offset
))
8325 output_asm_insn ("lg\t%4,0(%1)", op
);
8326 output_asm_insn ("ag\t%1,%3(%4)", op
);
8328 else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'K', "K"))
8330 output_asm_insn ("lghi\t%4,%3", op
);
8331 output_asm_insn ("ag\t%4,0(%1)", op
);
8332 output_asm_insn ("ag\t%1,0(%4)", op
);
8336 op
[7] = gen_label_rtx ();
8337 output_asm_insn ("llgf\t%4,%7-%5(%4)", op
);
8338 output_asm_insn ("ag\t%4,0(%1)", op
);
8339 output_asm_insn ("ag\t%1,0(%4)", op
);
8343 /* Jump to target. */
8344 output_asm_insn ("jg\t%0", op
);
8346 /* Output literal pool if required. */
8349 output_asm_insn (".align\t4", op
);
8350 targetm
.asm_out
.internal_label (file
, "L",
8351 CODE_LABEL_NUMBER (op
[5]));
8355 targetm
.asm_out
.internal_label (file
, "L",
8356 CODE_LABEL_NUMBER (op
[6]));
8357 output_asm_insn (".long\t%2", op
);
8361 targetm
.asm_out
.internal_label (file
, "L",
8362 CODE_LABEL_NUMBER (op
[7]));
8363 output_asm_insn (".long\t%3", op
);
8368 /* Setup base pointer if required. */
8370 || (!DISP_IN_RANGE (delta
)
8371 && !CONST_OK_FOR_CONSTRAINT_P (delta
, 'K', "K"))
8372 || (!DISP_IN_RANGE (delta
)
8373 && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'K', "K")))
8375 op
[5] = gen_label_rtx ();
8376 output_asm_insn ("basr\t%4,0", op
);
8377 targetm
.asm_out
.internal_label (file
, "L",
8378 CODE_LABEL_NUMBER (op
[5]));
8381 /* Add DELTA to this pointer. */
8384 if (CONST_OK_FOR_CONSTRAINT_P (delta
, 'J', "J"))
8385 output_asm_insn ("la\t%1,%2(%1)", op
);
8386 else if (DISP_IN_RANGE (delta
))
8387 output_asm_insn ("lay\t%1,%2(%1)", op
);
8388 else if (CONST_OK_FOR_CONSTRAINT_P (delta
, 'K', "K"))
8389 output_asm_insn ("ahi\t%1,%2", op
);
8392 op
[6] = gen_label_rtx ();
8393 output_asm_insn ("a\t%1,%6-%5(%4)", op
);
8397 /* Perform vcall adjustment. */
8400 if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'J', "J"))
8402 output_asm_insn ("lg\t%4,0(%1)", op
);
8403 output_asm_insn ("a\t%1,%3(%4)", op
);
8405 else if (DISP_IN_RANGE (vcall_offset
))
8407 output_asm_insn ("lg\t%4,0(%1)", op
);
8408 output_asm_insn ("ay\t%1,%3(%4)", op
);
8410 else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset
, 'K', "K"))
8412 output_asm_insn ("lhi\t%4,%3", op
);
8413 output_asm_insn ("a\t%4,0(%1)", op
);
8414 output_asm_insn ("a\t%1,0(%4)", op
);
8418 op
[7] = gen_label_rtx ();
8419 output_asm_insn ("l\t%4,%7-%5(%4)", op
);
8420 output_asm_insn ("a\t%4,0(%1)", op
);
8421 output_asm_insn ("a\t%1,0(%4)", op
);
8424 /* We had to clobber the base pointer register.
8425 Re-setup the base pointer (with a different base). */
8426 op
[5] = gen_label_rtx ();
8427 output_asm_insn ("basr\t%4,0", op
);
8428 targetm
.asm_out
.internal_label (file
, "L",
8429 CODE_LABEL_NUMBER (op
[5]));
8432 /* Jump to target. */
8433 op
[8] = gen_label_rtx ();
8436 output_asm_insn ("l\t%4,%8-%5(%4)", op
);
8438 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
8439 /* We cannot call through .plt, since .plt requires %r12 loaded. */
8440 else if (flag_pic
== 1)
8442 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
8443 output_asm_insn ("l\t%4,%0(%4)", op
);
8445 else if (flag_pic
== 2)
8447 op
[9] = gen_rtx_REG (Pmode
, 0);
8448 output_asm_insn ("l\t%9,%8-4-%5(%4)", op
);
8449 output_asm_insn ("a\t%4,%8-%5(%4)", op
);
8450 output_asm_insn ("ar\t%4,%9", op
);
8451 output_asm_insn ("l\t%4,0(%4)", op
);
8454 output_asm_insn ("br\t%4", op
);
8456 /* Output literal pool. */
8457 output_asm_insn (".align\t4", op
);
8459 if (nonlocal
&& flag_pic
== 2)
8460 output_asm_insn (".long\t%0", op
);
8463 op
[0] = gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
8464 SYMBOL_REF_FLAGS (op
[0]) = SYMBOL_FLAG_LOCAL
;
8467 targetm
.asm_out
.internal_label (file
, "L", CODE_LABEL_NUMBER (op
[8]));
8469 output_asm_insn (".long\t%0", op
);
8471 output_asm_insn (".long\t%0-%5", op
);
8475 targetm
.asm_out
.internal_label (file
, "L",
8476 CODE_LABEL_NUMBER (op
[6]));
8477 output_asm_insn (".long\t%2", op
);
8481 targetm
.asm_out
.internal_label (file
, "L",
8482 CODE_LABEL_NUMBER (op
[7]));
8483 output_asm_insn (".long\t%3", op
);
8489 s390_valid_pointer_mode (enum machine_mode mode
)
8491 return (mode
== SImode
|| (TARGET_64BIT
&& mode
== DImode
));
8494 /* How to allocate a 'struct machine_function'. */
8496 static struct machine_function
*
8497 s390_init_machine_status (void)
8499 return ggc_alloc_cleared (sizeof (struct machine_function
));
8502 /* Checks whether the given ARGUMENT_LIST would use a caller
8503 saved register. This is used to decide whether sibling call
8504 optimization could be performed on the respective function
8508 s390_call_saved_register_used (tree argument_list
)
8510 CUMULATIVE_ARGS cum
;
8512 enum machine_mode mode
;
8517 INIT_CUMULATIVE_ARGS (cum
, NULL
, NULL
, 0, 0);
8519 while (argument_list
)
8521 parameter
= TREE_VALUE (argument_list
);
8522 argument_list
= TREE_CHAIN (argument_list
);
8527 /* For an undeclared variable passed as parameter we will get
8528 an ERROR_MARK node here. */
8529 if (TREE_CODE (parameter
) == ERROR_MARK
)
8532 if (! (type
= TREE_TYPE (parameter
)))
8535 if (! (mode
= TYPE_MODE (TREE_TYPE (parameter
))))
8538 if (pass_by_reference (&cum
, mode
, type
, true))
8541 type
= build_pointer_type (type
);
8544 parm_rtx
= s390_function_arg (&cum
, mode
, type
, 0);
8546 s390_function_arg_advance (&cum
, mode
, type
, 0);
8548 if (parm_rtx
&& REG_P (parm_rtx
))
8551 reg
< HARD_REGNO_NREGS (REGNO (parm_rtx
), GET_MODE (parm_rtx
));
8553 if (! call_used_regs
[reg
+ REGNO (parm_rtx
)])
8560 /* Return true if the given call expression can be
8561 turned into a sibling call.
8562 DECL holds the declaration of the function to be called whereas
8563 EXP is the call expression itself. */
8566 s390_function_ok_for_sibcall (tree decl
, tree exp
)
8568 /* The TPF epilogue uses register 1. */
8569 if (TARGET_TPF_PROFILING
)
8572 /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
8573 which would have to be restored before the sibcall. */
8574 if (!TARGET_64BIT
&& flag_pic
&& decl
&& TREE_PUBLIC (decl
))
8577 /* Register 6 on s390 is available as an argument register but unfortunately
8578 "caller saved". This makes functions needing this register for arguments
8579 not suitable for sibcalls. */
8580 if (TREE_OPERAND (exp
, 1)
8581 && s390_call_saved_register_used (TREE_OPERAND (exp
, 1)))
8587 /* Return the fixed registers used for condition codes. */
8590 s390_fixed_condition_code_regs (unsigned int *p1
, unsigned int *p2
)
8593 *p2
= INVALID_REGNUM
;
8598 /* If two condition code modes are compatible, return a condition code
8599 mode which is compatible with both. Otherwise, return
8602 static enum machine_mode
8603 s390_cc_modes_compatible (enum machine_mode m1
, enum machine_mode m2
)
8611 if (m2
== CCUmode
|| m2
== CCTmode
8612 || m2
== CCSmode
|| m2
== CCSRmode
|| m2
== CCURmode
)
8632 /* This function is used by the call expanders of the machine description.
8633 It emits the call insn itself together with the necessary operations
8634 to adjust the target address and returns the emitted insn.
8635 ADDR_LOCATION is the target address rtx
8636 TLS_CALL the location of the thread-local symbol
8637 RESULT_REG the register where the result of the call should be stored
8638 RETADDR_REG the register where the return address should be stored
8639 If this parameter is NULL_RTX the call is considered
8640 to be a sibling call. */
8643 s390_emit_call (rtx addr_location
, rtx tls_call
, rtx result_reg
,
8646 bool plt_call
= false;
8652 /* Direct function calls need special treatment. */
8653 if (GET_CODE (addr_location
) == SYMBOL_REF
)
8655 /* When calling a global routine in PIC mode, we must
8656 replace the symbol itself with the PLT stub. */
8657 if (flag_pic
&& !SYMBOL_REF_LOCAL_P (addr_location
))
8659 addr_location
= gen_rtx_UNSPEC (Pmode
,
8660 gen_rtvec (1, addr_location
),
8662 addr_location
= gen_rtx_CONST (Pmode
, addr_location
);
8666 /* Unless we can use the bras(l) insn, force the
8667 routine address into a register. */
8668 if (!TARGET_SMALL_EXEC
&& !TARGET_CPU_ZARCH
)
8671 addr_location
= legitimize_pic_address (addr_location
, 0);
8673 addr_location
= force_reg (Pmode
, addr_location
);
8677 /* If it is already an indirect call or the code above moved the
8678 SYMBOL_REF to somewhere else make sure the address can be found in
8680 if (retaddr_reg
== NULL_RTX
8681 && GET_CODE (addr_location
) != SYMBOL_REF
8684 emit_move_insn (gen_rtx_REG (Pmode
, SIBCALL_REGNUM
), addr_location
);
8685 addr_location
= gen_rtx_REG (Pmode
, SIBCALL_REGNUM
);
8688 addr_location
= gen_rtx_MEM (QImode
, addr_location
);
8689 call
= gen_rtx_CALL (VOIDmode
, addr_location
, const0_rtx
);
8691 if (result_reg
!= NULL_RTX
)
8692 call
= gen_rtx_SET (VOIDmode
, result_reg
, call
);
8694 if (retaddr_reg
!= NULL_RTX
)
8696 clobber
= gen_rtx_CLOBBER (VOIDmode
, retaddr_reg
);
8698 if (tls_call
!= NULL_RTX
)
8699 vec
= gen_rtvec (3, call
, clobber
,
8700 gen_rtx_USE (VOIDmode
, tls_call
));
8702 vec
= gen_rtvec (2, call
, clobber
);
8704 call
= gen_rtx_PARALLEL (VOIDmode
, vec
);
8707 insn
= emit_call_insn (call
);
8709 /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
8710 if ((!TARGET_64BIT
&& plt_call
) || tls_call
!= NULL_RTX
)
8712 /* s390_function_ok_for_sibcall should
8713 have denied sibcalls in this case. */
8714 if (retaddr_reg
== NULL_RTX
)
8717 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), pic_offset_table_rtx
);
8722 /* Implement CONDITIONAL_REGISTER_USAGE. */
8725 s390_conditional_register_usage (void)
8731 fixed_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
8732 call_used_regs
[PIC_OFFSET_TABLE_REGNUM
] = 1;
8734 if (TARGET_CPU_ZARCH
)
8736 fixed_regs
[RETURN_REGNUM
] = 0;
8737 call_used_regs
[RETURN_REGNUM
] = 0;
8741 for (i
= 24; i
< 32; i
++)
8742 call_used_regs
[i
] = call_really_used_regs
[i
] = 0;
8746 for (i
= 18; i
< 20; i
++)
8747 call_used_regs
[i
] = call_really_used_regs
[i
] = 0;
8750 if (TARGET_SOFT_FLOAT
)
8752 for (i
= 16; i
< 32; i
++)
8753 call_used_regs
[i
] = fixed_regs
[i
] = 1;
8757 /* Corresponding function to eh_return expander. */
8759 static GTY(()) rtx s390_tpf_eh_return_symbol
;
8761 s390_emit_tpf_eh_return (rtx target
)
8765 if (!s390_tpf_eh_return_symbol
)
8766 s390_tpf_eh_return_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "__tpf_eh_return");
8768 reg
= gen_rtx_REG (Pmode
, 2);
8770 emit_move_insn (reg
, target
);
8771 insn
= s390_emit_call (s390_tpf_eh_return_symbol
, NULL_RTX
, reg
,
8772 gen_rtx_REG (Pmode
, RETURN_REGNUM
));
8773 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), reg
);
8775 emit_move_insn (EH_RETURN_HANDLER_RTX
, reg
);
8778 #include "gt-s390.h"