PR target/16201
[official-gcc.git] / gcc / config / s390 / s390.c
blobf9be9cf0a6fb6dbcc3efe88320dd3ed514369ddf
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
12 version.
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
17 for more details.
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
22 02111-1307, USA. */
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "tm_p.h"
31 #include "regs.h"
32 #include "hard-reg-set.h"
33 #include "real.h"
34 #include "insn-config.h"
35 #include "conditions.h"
36 #include "output.h"
37 #include "insn-attr.h"
38 #include "flags.h"
39 #include "except.h"
40 #include "function.h"
41 #include "recog.h"
42 #include "expr.h"
43 #include "reload.h"
44 #include "toplev.h"
45 #include "basic-block.h"
46 #include "integrate.h"
47 #include "ggc.h"
48 #include "target.h"
49 #include "target-def.h"
50 #include "debug.h"
51 #include "langhooks.h"
52 #include "optabs.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,
67 HOST_WIDE_INT, tree);
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,
83 tree, bool);
84 static bool s390_fixed_condition_code_regs (unsigned int *, unsigned int *);
85 static enum machine_mode s390_cc_modes_compatible (enum machine_mode,
86 enum machine_mode);
89 /* Define the specific costs for a given cpu. */
91 struct processor_costs
93 /* multiplication */
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. */
107 /* square root */
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. */
113 /* division */
114 const int ddbr;
115 const int ddr;
116 const int debr;
117 const int der;
118 const int dlgr;
119 const int dlr;
120 const int dr;
121 const int dsgfr;
122 const int dsgr;
125 const struct processor_costs *s390_cost;
127 static const
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 */
158 static const
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
206 #ifdef HAVE_AS_TLS
207 #undef TARGET_HAVE_TLS
208 #define TARGET_HAVE_TLS true
209 #endif
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
278 emitted. */
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
283 form
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. */
290 struct s390_address
292 rtx base;
293 rtx indx;
294 rtx disp;
295 int pointer;
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. */
332 int first_save_gpr;
333 int first_restore_gpr;
334 int last_save_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. */
346 int high_fprs;
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. */
362 rtx base_reg;
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 |= \
378 (1 << (BITNUM)))
379 #define cfun_fpr_bit_p(BITNUM) (!!(cfun->machine->frame_layout.fpr_bitmap & \
380 (1 << (BITNUM))))
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. */
425 static int
426 s390_match_ccmode_set (rtx set, enum machine_mode req_mode)
428 enum machine_mode set_mode;
430 if (GET_CODE (set) != SET)
431 abort ();
433 if (GET_CODE (SET_DEST (set)) != REG || !CC_REGNO_P (REGNO (SET_DEST (set))))
434 return 1;
436 set_mode = GET_MODE (SET_DEST (set));
437 switch (set_mode)
439 case CCSmode:
440 case CCSRmode:
441 case CCUmode:
442 case CCURmode:
443 case CCLmode:
444 case CCL1mode:
445 case CCL2mode:
446 case CCL3mode:
447 case CCT1mode:
448 case CCT2mode:
449 case CCT3mode:
450 if (req_mode != set_mode)
451 return 0;
452 break;
454 case CCZmode:
455 if (req_mode != CCSmode && req_mode != CCUmode && req_mode != CCTmode
456 && req_mode != CCSRmode && req_mode != CCURmode)
457 return 0;
458 break;
460 case CCAPmode:
461 case CCANmode:
462 if (req_mode != CCAmode)
463 return 0;
464 break;
466 default:
467 abort ();
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)
481 int i;
483 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
484 if (req_mode == VOIDmode)
485 return 0;
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))
496 return 0;
499 return 1;
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). */
509 enum machine_mode
510 s390_tm_ccmode (rtx op1, rtx op2, int mixed)
512 int bit0, bit1;
514 /* ??? Fixme: should work on CONST_DOUBLE as well. */
515 if (GET_CODE (op1) != CONST_INT || GET_CODE (op2) != CONST_INT)
516 return VOIDmode;
518 /* Selected bits all zero: CC0.
519 e.g.: int a; if ((a & (16 + 128)) == 0) */
520 if (INTVAL (op2) == 0)
521 return CCTmode;
523 /* Selected bits all one: CC3.
524 e.g.: int a; if ((a & (16 + 128)) == 16 + 128) */
525 if (INTVAL (op2) == INTVAL (op1))
526 return CCT3mode;
528 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. e.g.:
529 int a;
530 if ((a & (16 + 128)) == 16) -> CCT1
531 if ((a & (16 + 128)) == 128) -> CCT2 */
532 if (mixed)
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;
540 return VOIDmode;
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
545 comparison. */
547 enum machine_mode
548 s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
550 switch (code)
552 case EQ:
553 case NE:
554 if ((GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
555 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
556 return CCAPmode;
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"))
559 return CCAPmode;
560 if ((GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
561 || GET_CODE (op1) == NEG)
562 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
563 return CCLmode;
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))
581 return CCT3mode;
582 if (register_operand (op0, QImode)
583 && GET_CODE (op1) == CONST_INT
584 && (INTVAL (op1) == -1 || INTVAL (op1) == 255))
585 return CCT3mode;
587 return CCZmode;
589 case LE:
590 case LT:
591 case GE:
592 case GT:
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)
599 return CCAPmode;
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)
610 return CCANmode;
611 else
612 return CCAPmode;
614 /* Fall through. */
615 case UNORDERED:
616 case ORDERED:
617 case UNEQ:
618 case UNLE:
619 case UNLT:
620 case UNGE:
621 case UNGT:
622 case LTGT:
623 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
624 && GET_CODE (op1) != CONST_INT)
625 return CCSRmode;
626 return CCSmode;
628 case LTU:
629 case GEU:
630 if (GET_CODE (op0) == PLUS
631 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
632 return CCL1mode;
634 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
635 && GET_CODE (op1) != CONST_INT)
636 return CCURmode;
637 return CCUmode;
639 case LEU:
640 case GTU:
641 if (GET_CODE (op0) == MINUS
642 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
643 return CCL2mode;
645 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
646 && GET_CODE (op1) != CONST_INT)
647 return CCURmode;
648 return CCUmode;
650 default:
651 abort ();
655 /* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
656 that we can implement more efficiently. */
658 void
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))))
702 && ((INTVAL (mask)
703 & GET_MODE_MASK (GET_MODE (inner))
704 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (inner))))
705 == 0))
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);
713 if (part >= 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);
731 *op1 = constm1_rtx;
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;
745 switch (*code)
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;
753 default: break;
756 if (new_code != UNKNOWN)
758 *op0 = XVECEXP (*op0, 0, 0);
759 *code = new_code;
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. */
781 void
782 s390_emit_jump (rtx target, rtx cond)
784 rtx insn;
786 target = gen_rtx_LABEL_REF (VOIDmode, target);
787 if (cond)
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))
801 return 0;
803 if (!COMPARISON_P (op))
804 return 0;
806 if (GET_CODE (XEXP (op, 0)) != REG
807 || REGNO (XEXP (op, 0)) != CC_REGNUM
808 || XEXP (op, 1) != const0_rtx)
809 return 0;
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))
821 return 0;
823 while (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND)
824 op = XEXP (op, 0);
826 if (!COMPARISON_P (op))
827 return 0;
829 if (GET_CODE (XEXP (op, 0)) != REG
830 || REGNO (XEXP (op, 0)) != CC_REGNUM
831 || XEXP (op, 1) != const0_rtx)
832 return 0;
834 switch (GET_MODE (XEXP (op, 0)))
836 case CCL1mode:
837 return GET_CODE (op) == LTU;
839 case CCL2mode:
840 return GET_CODE (op) == LEU;
842 case CCL3mode:
843 return GET_CODE (op) == GEU;
845 case CCUmode:
846 return GET_CODE (op) == GTU;
848 case CCURmode:
849 return GET_CODE (op) == LTU;
851 case CCSmode:
852 return GET_CODE (op) == UNGT;
854 case CCSRmode:
855 return GET_CODE (op) == UNLT;
857 default:
858 return 0;
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))
869 return 0;
871 while (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND)
872 op = XEXP (op, 0);
874 if (!COMPARISON_P (op))
875 return 0;
877 if (GET_CODE (XEXP (op, 0)) != REG
878 || REGNO (XEXP (op, 0)) != CC_REGNUM
879 || XEXP (op, 1) != const0_rtx)
880 return 0;
882 switch (GET_MODE (XEXP (op, 0)))
884 case CCL1mode:
885 return GET_CODE (op) == GEU;
887 case CCL2mode:
888 return GET_CODE (op) == GTU;
890 case CCL3mode:
891 return GET_CODE (op) == LTU;
893 case CCUmode:
894 return GET_CODE (op) == LEU;
896 case CCURmode:
897 return GET_CODE (op) == GEU;
899 case CCSmode:
900 return GET_CODE (op) == LE;
902 case CCSRmode:
903 return GET_CODE (op) == GE;
905 default:
906 return 0;
910 /* Return branch condition mask to implement a branch
911 specified by CODE. Return -1 for invalid comparisons. */
913 static int
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)
924 abort ();
926 switch (GET_MODE (XEXP (code, 0)))
928 case CCZmode:
929 switch (GET_CODE (code))
931 case EQ: return CC0;
932 case NE: return CC1 | CC2 | CC3;
933 default: return -1;
935 break;
937 case CCT1mode:
938 switch (GET_CODE (code))
940 case EQ: return CC1;
941 case NE: return CC0 | CC2 | CC3;
942 default: return -1;
944 break;
946 case CCT2mode:
947 switch (GET_CODE (code))
949 case EQ: return CC2;
950 case NE: return CC0 | CC1 | CC3;
951 default: return -1;
953 break;
955 case CCT3mode:
956 switch (GET_CODE (code))
958 case EQ: return CC3;
959 case NE: return CC0 | CC1 | CC2;
960 default: return -1;
962 break;
964 case CCLmode:
965 switch (GET_CODE (code))
967 case EQ: return CC0 | CC2;
968 case NE: return CC1 | CC3;
969 default: return -1;
971 break;
973 case CCL1mode:
974 switch (GET_CODE (code))
976 case LTU: return CC2 | CC3; /* carry */
977 case GEU: return CC0 | CC1; /* no carry */
978 default: return -1;
980 break;
982 case CCL2mode:
983 switch (GET_CODE (code))
985 case GTU: return CC0 | CC1; /* borrow */
986 case LEU: return CC2 | CC3; /* no borrow */
987 default: return -1;
989 break;
991 case CCL3mode:
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;
1000 default: return -1;
1003 case CCUmode:
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;
1012 default: return -1;
1014 break;
1016 case CCURmode:
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;
1025 default: return -1;
1027 break;
1029 case CCAPmode:
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;
1038 default: return -1;
1040 break;
1042 case CCANmode:
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;
1051 default: return -1;
1053 break;
1055 case CCSmode:
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;
1072 default: return -1;
1074 break;
1076 case CCSRmode:
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;
1093 default: return -1;
1095 break;
1097 default:
1098 return -1;
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. */
1106 static const char *
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);
1120 if (inv)
1121 mask ^= 15;
1123 if (mask < 1 || mask > 14)
1124 abort ();
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;
1141 int i;
1143 for (i = 0; i < max_parts; i++)
1145 if (i == 0)
1146 value = (unsigned HOST_WIDE_INT) INTVAL (op);
1147 else
1148 value >>= part_bits;
1150 if ((value & part_mask) != (def & part_mask))
1151 return value & part_mask;
1154 abort ();
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,
1165 int def)
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;
1170 int i, part = -1;
1172 if (GET_CODE (op) != CONST_INT)
1173 return -1;
1175 for (i = 0; i < n_parts; i++)
1177 if (i == 0)
1178 value = (unsigned HOST_WIDE_INT) INTVAL (op);
1179 else
1180 value >>= GET_MODE_BITSIZE (part_mode);
1182 if ((value & part_mask) != (def & part_mask))
1184 if (part != -1)
1185 return -1;
1186 else
1187 part = i;
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. */
1197 bool
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))
1202 return false;
1204 /* We don't need to split if operands are directly accessible. */
1205 if (s_operand (src, mode) || s_operand (dst, mode))
1206 return false;
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)))
1211 return false;
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))
1219 return false;
1222 return true;
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. */
1229 bool
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)
1235 return false;
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))
1242 return false;
1244 return true;
1247 /* Expand logical operator CODE in mode MODE with operands OPERANDS. */
1249 void
1250 s390_expand_logical_operator (enum rtx_code code, enum machine_mode mode,
1251 rtx *operands)
1253 enum machine_mode wmode = mode;
1254 rtx dst = operands[0];
1255 rtx src1 = operands[1];
1256 rtx src2 = operands[2];
1257 rtx op, clob, tem;
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)
1266 wmode = SImode;
1268 /* Widen operands if required. */
1269 if (mode != wmode)
1271 if (GET_CODE (dst) == SUBREG
1272 && (tem = simplify_subreg (wmode, dst, mode, 0)) != 0)
1273 dst = tem;
1274 else if (REG_P (dst))
1275 dst = gen_rtx_SUBREG (wmode, dst, 0);
1276 else
1277 dst = gen_reg_rtx (wmode);
1279 if (GET_CODE (src1) == SUBREG
1280 && (tem = simplify_subreg (wmode, src1, mode, 0)) != 0)
1281 src1 = tem;
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)
1287 src2 = tem;
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). */
1304 bool
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]));
1314 return true;
1317 /* Narrow logical operation CODE of memory operand MEMOP with immediate
1318 operand IMMOP to switch from SS to SI type instructions. */
1320 void
1321 s390_narrow_logical_operator (enum rtx_code code, rtx *memop, rtx *immop)
1323 int def = code == AND ? -1 : 0;
1324 HOST_WIDE_INT mask;
1325 int part;
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
1340 optimization level.
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. */
1347 void
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;
1358 void
1359 override_options (void)
1361 int i;
1362 static struct pta
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))
1388 if (TARGET_64BIT)
1389 target_flags |= MASK_ZARCH;
1390 else
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;
1403 break;
1405 if (i == pta_size)
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;
1415 else
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;
1422 break;
1424 if (i == pta_size)
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;
1438 else
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 "
1444 "in combination.");
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");
1477 else
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);
1507 else
1508 return TYPE_NONE;
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. */
1534 static int
1535 check_mode (register rtx op, enum machine_mode *mode)
1537 if (*mode == VOIDmode)
1538 *mode = GET_MODE (op);
1539 else
1541 if (GET_MODE (op) != VOIDmode && GET_MODE (op) != *mode)
1542 return 0;
1544 return 1;
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))
1555 return 0;
1557 /* Allow labels and local symbols. */
1558 if (GET_CODE (op) == LABEL_REF)
1559 return 1;
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)
1567 return 0;
1568 op = XEXP (op, 0);
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)
1575 return 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))
1579 return 0;
1580 #endif
1581 op = XEXP (op, 0);
1584 /* Labels and local symbols allowed here as well. */
1585 if (GET_CODE (op) == LABEL_REF)
1586 return 1;
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)
1596 return 1;
1597 if (GET_CODE (op) == UNSPEC
1598 && XINT (op, 1) == UNSPEC_PLT)
1599 return 1;
1600 if (GET_CODE (op) == UNSPEC
1601 && XINT (op, 1) == UNSPEC_INDNTPOFF)
1602 return 1;
1604 return 0;
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))
1619 return 0;
1621 /* Just like memory_operand, allow (subreg (mem ...))
1622 after reload. */
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)
1629 return 0;
1630 if (!s390_decompose_address (XEXP (op, 0), &addr))
1631 return 0;
1632 if (addr.indx)
1633 return 0;
1635 return 1;
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))
1648 return 0;
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);
1657 op = NULL_RTX;
1659 if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
1661 offset = INTVAL (XEXP (op, 1));
1662 op = XEXP (op, 0);
1664 while (op && GET_CODE (op) == SUBREG)
1665 op = SUBREG_REG (op);
1666 if (op && GET_CODE (op) != REG)
1667 return 0;
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))
1672 return 0;
1674 return 1;
1677 /* Return true if DISP is a valid short displacement. */
1679 static int
1680 s390_short_displacement (rtx disp)
1682 /* No displacement is OK. */
1683 if (!disp)
1684 return 1;
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))
1695 return 0;
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)
1700 return 1;
1702 return 0;
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;
1712 if (c != str[0])
1713 abort ();
1715 /* Check for offsettable variants of memory constraints. */
1716 if (c == 'A')
1718 /* Only accept non-volatile MEMs. */
1719 if (!MEM_P (op) || MEM_VOLATILE_P (op))
1720 return 0;
1722 if ((reload_completed || reload_in_progress)
1723 ? !offsettable_memref_p (op)
1724 : !offsettable_nonstrict_memref_p (op))
1725 return 0;
1727 c = str[1];
1730 /* Check for non-literal-pool variants of memory constraints. */
1731 else if (c == 'B')
1733 if (GET_CODE (op) != MEM)
1734 return 0;
1735 if (!s390_decompose_address (XEXP (op, 0), &addr))
1736 return 0;
1737 if (addr.base && REG_P (addr.base) && REGNO (addr.base) == BASE_REGNUM)
1738 return 0;
1739 if (addr.indx && REG_P (addr.indx) && REGNO (addr.indx) == BASE_REGNUM)
1740 return 0;
1742 c = str[1];
1745 switch (c)
1747 case 'Q':
1748 if (GET_CODE (op) != MEM)
1749 return 0;
1750 if (!s390_decompose_address (XEXP (op, 0), &addr))
1751 return 0;
1752 if (addr.indx)
1753 return 0;
1755 if (TARGET_LONG_DISPLACEMENT)
1757 if (!s390_short_displacement (addr.disp))
1758 return 0;
1760 break;
1762 case 'R':
1763 if (GET_CODE (op) != MEM)
1764 return 0;
1766 if (TARGET_LONG_DISPLACEMENT)
1768 if (!s390_decompose_address (XEXP (op, 0), &addr))
1769 return 0;
1770 if (!s390_short_displacement (addr.disp))
1771 return 0;
1773 break;
1775 case 'S':
1776 if (!TARGET_LONG_DISPLACEMENT)
1777 return 0;
1778 if (GET_CODE (op) != MEM)
1779 return 0;
1780 if (!s390_decompose_address (XEXP (op, 0), &addr))
1781 return 0;
1782 if (addr.indx)
1783 return 0;
1784 if (s390_short_displacement (addr.disp))
1785 return 0;
1786 break;
1788 case 'T':
1789 if (!TARGET_LONG_DISPLACEMENT)
1790 return 0;
1791 if (GET_CODE (op) != MEM)
1792 return 0;
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))
1797 return 0;
1798 break;
1800 case 'U':
1801 if (TARGET_LONG_DISPLACEMENT)
1803 if (!s390_decompose_address (op, &addr))
1804 return 0;
1805 if (!s390_short_displacement (addr.disp))
1806 return 0;
1808 break;
1810 case 'W':
1811 if (!TARGET_LONG_DISPLACEMENT)
1812 return 0;
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))
1817 return 0;
1818 break;
1820 case 'Y':
1821 return shift_count_operand (op, VOIDmode);
1823 default:
1824 return 0;
1827 return 1;
1830 /* Return true if VALUE matches the constraint STR. */
1833 s390_const_ok_for_constraint_p (HOST_WIDE_INT value,
1834 int c,
1835 const char * str)
1837 enum machine_mode mode, part_mode;
1838 int def;
1839 int part, part_goal;
1841 if (c != str[0])
1842 abort ();
1844 switch (str[0])
1846 case 'I':
1847 return (unsigned int)value < 256;
1849 case 'J':
1850 return (unsigned int)value < 4096;
1852 case 'K':
1853 return value >= -32768 && value < 32768;
1855 case 'L':
1856 return (TARGET_LONG_DISPLACEMENT ?
1857 (value >= -524288 && value <= 524287)
1858 : (value >= 0 && value <= 4095));
1859 case 'M':
1860 return value == 2147483647;
1862 case 'N':
1863 if (str[1] == 'x')
1864 part_goal = -1;
1865 else
1866 part_goal = str[1] - '0';
1868 switch (str[2])
1870 case 'H': part_mode = HImode; break;
1871 case 'Q': part_mode = QImode; break;
1872 default: return 0;
1875 switch (str[3])
1877 case 'H': mode = HImode; break;
1878 case 'S': mode = SImode; break;
1879 case 'D': mode = DImode; break;
1880 default: return 0;
1883 switch (str[4])
1885 case '0': def = 0; break;
1886 case 'F': def = -1; break;
1887 default: return 0;
1890 if (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (part_mode))
1891 return 0;
1893 part = s390_single_part (GEN_INT (value), mode, part_mode, def);
1894 if (part < 0)
1895 return 0;
1896 if (part_goal != -1 && part_goal != part)
1897 return 0;
1899 break;
1901 default:
1902 return 0;
1905 return 1;
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. */
1914 static bool
1915 s390_rtx_costs (rtx x, int code, int outer_code, int *total)
1917 switch (code)
1919 case CONST:
1920 case CONST_INT:
1921 case LABEL_REF:
1922 case SYMBOL_REF:
1923 case CONST_DOUBLE:
1924 case MEM:
1925 *total = 0;
1926 return true;
1928 case ASHIFT:
1929 case ASHIFTRT:
1930 case LSHIFTRT:
1931 case ROTATE:
1932 case ROTATERT:
1933 case AND:
1934 case IOR:
1935 case XOR:
1936 case NEG:
1937 case NOT:
1938 *total = COSTS_N_INSNS (1);
1939 return false;
1941 case PLUS:
1942 case MINUS:
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;
1951 else
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);
1959 return false;
1961 case MULT:
1962 switch (GET_MODE (x))
1964 case SImode:
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;
1973 else
1974 *total = s390_cost->ms; /* msr, ms, msy */
1975 break;
1977 case DImode:
1979 rtx left = XEXP (x, 0);
1980 rtx right = XEXP (x, 1);
1981 if (TARGET_64BIT)
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;
1988 else
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;
2002 else
2003 /* Complex calculation is required. */
2004 *total = COSTS_N_INSNS (40);
2006 break;
2008 case SFmode:
2009 case DFmode:
2010 *total = s390_cost->mult_df;
2011 break;
2012 default:
2013 return false;
2015 return false;
2017 case UDIV:
2018 case UMOD:
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;
2031 return false;
2033 case DIV:
2034 case MOD:
2035 if (GET_MODE (x) == DImode)
2037 rtx right = XEXP (x, 1);
2038 if (GET_CODE (right) == ZERO_EXTEND) /* 64 by 32 bit division */
2039 if (TARGET_64BIT)
2040 *total = s390_cost->dsgfr;
2041 else
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;
2062 return false;
2064 case SQRT:
2065 if (GET_MODE (x) == SFmode)
2066 *total = s390_cost->sqebr;
2067 else /* DFmode */
2068 *total = s390_cost->sqdbr;
2069 return false;
2071 case SIGN_EXTEND:
2072 case ZERO_EXTEND:
2073 if (outer_code == MULT || outer_code == DIV || outer_code == MOD
2074 || outer_code == PLUS || outer_code == MINUS
2075 || outer_code == COMPARE)
2076 *total = 0;
2077 return false;
2079 case 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)
2091 return true;
2092 if (register_operand (op0, GET_MODE (op0))
2093 && s390_tm_ccmode (op1, op2, 1) != VOIDmode)
2094 return true;
2096 return false;
2098 default:
2099 return false;
2103 /* Return the cost of an address rtx ADDR. */
2105 static int
2106 s390_address_cost (rtx addr)
2108 struct s390_address ad;
2109 if (!s390_decompose_address (addr, &ad))
2110 return 1000;
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)
2126 return 1;
2128 /* Allow @PLT stubs. */
2129 if (code == CONST
2130 && GET_CODE (XEXP (op, 0)) == UNSPEC
2131 && XINT (XEXP (op, 0), 1) == UNSPEC_PLT)
2132 return 1;
2133 return 0;
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)
2143 return 0;
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;
2158 rtx src_addr;
2159 int i, off;
2162 /* Perform a quick check so we don't blow up below. */
2163 if (count <= 1
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)
2167 return 0;
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)
2176 off = 0;
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);
2184 else
2185 return 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))
2202 return 0;
2205 return 1;
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;
2219 rtx dest_addr;
2220 int i, off;
2222 /* Perform a quick check so we don't blow up below. */
2223 if (count <= 1
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)
2227 return 0;
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)
2236 off = 0;
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);
2244 else
2245 return 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))
2262 return 0;
2264 return 1;
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. */
2272 void
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;
2290 register int i;
2292 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
2293 return 1;
2295 fmt = GET_RTX_FORMAT (GET_CODE (op));
2296 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
2298 if (fmt[i] == 'E')
2300 register int j;
2302 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
2303 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
2304 return 1;
2307 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
2308 return 1;
2311 return 0;
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;
2320 register int i;
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--)
2328 if (fmt[i] == 'E')
2330 register int j;
2332 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
2333 if (tls_symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
2334 return 1;
2337 else if (fmt[i] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op, i)))
2338 return 1;
2341 return 0;
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))
2354 return 1;
2356 /* Reject everything else; must be handled
2357 via emit_symbolic_move. */
2358 return 0;
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))
2369 return 1;
2371 /* Accept immediate LARL operands. */
2372 if (TARGET_CPU_ZARCH && larl_operand (op, VOIDmode))
2373 return 1;
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))
2379 return 0;
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. */
2384 if (flag_pic)
2385 return 1;
2387 /* All remaining non-PIC symbolic constants are
2388 forced into the literal pool. */
2389 return 0;
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). */
2396 static bool
2397 s390_cannot_force_const_mem (rtx x)
2399 switch (GET_CODE (x))
2401 case CONST_INT:
2402 case CONST_DOUBLE:
2403 /* Accept all non-symbolic constants. */
2404 return false;
2406 case LABEL_REF:
2407 /* Labels are OK iff we are non-PIC. */
2408 return flag_pic != 0;
2410 case SYMBOL_REF:
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))
2414 return true;
2415 else
2416 return flag_pic != 0;
2418 case CONST:
2419 return s390_cannot_force_const_mem (XEXP (x, 0));
2420 case PLUS:
2421 case MINUS:
2422 return s390_cannot_force_const_mem (XEXP (x, 0))
2423 || s390_cannot_force_const_mem (XEXP (x, 1));
2425 case UNSPEC:
2426 switch (XINT (x, 1))
2428 /* Only lt-relative or GOT-relative UNSPECs are OK. */
2429 case UNSPEC_LTREL_OFFSET:
2430 case UNSPEC_GOT:
2431 case UNSPEC_GOTOFF:
2432 case UNSPEC_PLTOFF:
2433 case UNSPEC_TLSGD:
2434 case UNSPEC_TLSLDM:
2435 case UNSPEC_NTPOFF:
2436 case UNSPEC_DTPOFF:
2437 case UNSPEC_GOTNTPOFF:
2438 case UNSPEC_INDNTPOFF:
2439 return false;
2441 /* If the literal pool shares the code section, be put
2442 execute template placeholders into the pool as well. */
2443 case UNSPEC_INSN:
2444 return TARGET_CPU_ZARCH;
2446 default:
2447 return true;
2449 break;
2451 default:
2452 abort ();
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)))
2468 return 1;
2470 /* Accept l(g)hi operands. */
2471 if (GET_CODE (op) == CONST_INT
2472 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'K', "K"))
2473 return 1;
2475 /* Accept lliXX operands. */
2476 if (TARGET_ZARCH
2477 && s390_single_part (op, DImode, HImode, 0) >= 0)
2478 return 1;
2480 /* Accept larl operands. */
2481 if (TARGET_CPU_ZARCH
2482 && larl_operand (op, VOIDmode))
2483 return 1;
2485 /* Everything else cannot be handled without reload. */
2486 return 0;
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. */
2492 enum reg_class
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
2498 literal pool. */
2500 case CONST_DOUBLE:
2501 case CONST_INT:
2502 if (legitimate_reload_constant_p (op))
2503 return class;
2504 else
2505 return NO_REGS;
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. */
2511 case PLUS:
2512 case LABEL_REF:
2513 case SYMBOL_REF:
2514 case CONST:
2515 if (reg_class_subset_p (ADDR_REGS, class))
2516 return ADDR_REGS;
2517 else
2518 return NO_REGS;
2520 default:
2521 break;
2524 return 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. */
2533 enum reg_class
2534 s390_secondary_input_reload_class (enum reg_class class,
2535 enum machine_mode mode, rtx in)
2537 if (s390_plus_operand (in, mode))
2538 return ADDR_REGS;
2540 if (reg_classes_intersect_p (CC_REGS, class))
2541 return GENERAL_REGS;
2543 return NO_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. */
2552 enum reg_class
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))
2562 return ADDR_REGS;
2564 if (reg_classes_intersect_p (CC_REGS, class))
2565 return GENERAL_REGS;
2567 return NO_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)
2579 return FALSE;
2581 if (GET_CODE (op) != PLUS)
2582 return FALSE;
2584 if (legitimate_la_operand_p (op))
2585 return FALSE;
2587 return TRUE;
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. */
2594 void
2595 s390_expand_plus_operand (register rtx target, register rtx src,
2596 register rtx scratch)
2598 rtx sum1, sum2;
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)
2603 abort ();
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);
2622 sum1 = scratch;
2624 if (true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
2626 emit_move_insn (scratch, sum2);
2627 sum2 = scratch;
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)
2636 debug_rtx (src);
2637 abort ();
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. */
2661 static int
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;
2668 rtx orig_disp;
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)
2676 base = addr;
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 */
2690 base = op1;
2693 else
2695 base = op0; /* base + displacement */
2696 disp = op1;
2700 else if (code0 == PLUS)
2702 indx = XEXP (op0, 0); /* index + base + disp */
2703 base = XEXP (op0, 1);
2704 disp = op1;
2707 else
2709 return FALSE;
2713 else
2714 disp = addr; /* displacement */
2716 /* Extract integer part of displacement. */
2717 orig_disp = disp;
2718 if (disp)
2720 if (GET_CODE (disp) == CONST_INT)
2722 offset = INTVAL (disp);
2723 disp = NULL_RTX;
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. */
2743 if (!base)
2744 base = gen_rtx_REG (Pmode, BASE_REGNUM);
2745 else if (!indx)
2746 indx = gen_rtx_REG (Pmode, BASE_REGNUM);
2747 else
2748 return FALSE;
2750 /* Mark up the displacement. */
2751 disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp),
2752 UNSPEC_LTREL_OFFSET);
2755 /* Validate base register. */
2756 if (base)
2758 if (GET_CODE (base) == UNSPEC)
2759 switch (XINT (base, 1))
2761 case UNSPEC_LTREF:
2762 if (!disp)
2763 disp = gen_rtx_UNSPEC (Pmode,
2764 gen_rtvec (1, XVECEXP (base, 0, 0)),
2765 UNSPEC_LTREL_OFFSET);
2766 else
2767 return FALSE;
2769 base = gen_rtx_REG (Pmode, BASE_REGNUM);
2770 break;
2772 case UNSPEC_LTREL_BASE:
2773 base = gen_rtx_REG (Pmode, BASE_REGNUM);
2774 break;
2776 default:
2777 return FALSE;
2780 if (GET_CODE (base) != REG || GET_MODE (base) != Pmode)
2781 return FALSE;
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
2790 || (flag_pic
2791 && REGNO (base) == PIC_OFFSET_TABLE_REGNUM))
2792 pointer = base_ptr = TRUE;
2795 /* Validate index register. */
2796 if (indx)
2798 if (GET_CODE (indx) == UNSPEC)
2799 switch (XINT (indx, 1))
2801 case UNSPEC_LTREF:
2802 if (!disp)
2803 disp = gen_rtx_UNSPEC (Pmode,
2804 gen_rtvec (1, XVECEXP (indx, 0, 0)),
2805 UNSPEC_LTREL_OFFSET);
2806 else
2807 return FALSE;
2809 indx = gen_rtx_REG (Pmode, BASE_REGNUM);
2810 break;
2812 case UNSPEC_LTREL_BASE:
2813 indx = gen_rtx_REG (Pmode, BASE_REGNUM);
2814 break;
2816 default:
2817 return FALSE;
2820 if (GET_CODE (indx) != REG || GET_MODE (indx) != Pmode)
2821 return FALSE;
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
2830 || (flag_pic
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))))
2839 rtx tmp = base;
2840 base = indx;
2841 indx = tmp;
2844 /* Validate displacement. */
2845 if (!disp)
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
2852 registers.
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))
2861 return FALSE;
2863 else
2865 /* All the special cases are pointers. */
2866 pointer = TRUE;
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)
2873 && offset == 0
2874 && flag_pic == 1)
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);
2892 if (offset)
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)))
2898 return FALSE;
2900 orig_disp = plus_constant (orig_disp, offset);
2904 else
2905 return FALSE;
2908 if (!base && !indx)
2909 pointer = TRUE;
2911 if (out)
2913 out->base = base;
2914 out->indx = indx;
2915 out->disp = orig_disp;
2916 out->pointer = pointer;
2919 return TRUE;
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))
2931 return FALSE;
2933 if (strict)
2935 if (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
2936 return FALSE;
2937 if (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx))
2938 return FALSE;
2940 else
2942 if (ad.base && !REG_OK_FOR_BASE_NONSTRICT_P (ad.base))
2943 return FALSE;
2944 if (ad.indx && !REG_OK_FOR_INDEX_NONSTRICT_P (ad.indx))
2945 return FALSE;
2948 return TRUE;
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))
2960 return FALSE;
2962 if (TARGET_64BIT || addr.pointer)
2963 return TRUE;
2965 return FALSE;
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))
2980 return FALSE;
2981 if (addr.base && !REG_OK_FOR_BASE_STRICT_P (addr.base))
2982 return FALSE;
2983 if (addr.indx && !REG_OK_FOR_INDEX_STRICT_P (addr.indx))
2984 return FALSE;
2986 if (!TARGET_64BIT && !addr.pointer)
2987 return FALSE;
2989 if (addr.pointer)
2990 return TRUE;
2992 if ((addr.base && REG_P (addr.base) && REG_POINTER (addr.base))
2993 || (addr.indx && REG_P (addr.indx) && REG_POINTER (addr.indx)))
2994 return TRUE;
2996 return FALSE;
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. */
3003 void
3004 s390_load_address (rtx dst, rtx src)
3006 if (TARGET_64BIT)
3007 emit_move_insn (dst, src);
3008 else
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
3019 returned.
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)
3033 rtx addr = orig;
3034 rtx new = orig;
3035 rtx base;
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 ... */
3047 else
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);
3062 if (reg != 0)
3064 s390_load_address (reg, new);
3065 new = reg;
3069 else if (GET_CODE (addr) == SYMBOL_REF)
3071 if (reg == 0)
3072 reg = gen_reg_rtx (Pmode);
3074 if (flag_pic == 1)
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);
3087 new = reg;
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);
3102 new = reg;
3104 else
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);
3122 new = reg;
3125 else
3127 if (GET_CODE (addr) == CONST)
3129 addr = XEXP (addr, 0);
3130 if (GET_CODE (addr) == UNSPEC)
3132 if (XVECLEN (addr, 0) != 1)
3133 abort ();
3134 switch (XINT (addr, 1))
3136 /* If someone moved a GOT-relative UNSPEC
3137 out of the literal pool, force them back in. */
3138 case UNSPEC_GOTOFF:
3139 case UNSPEC_PLTOFF:
3140 new = force_const_mem (Pmode, orig);
3141 break;
3143 /* @GOT is OK as is if small. */
3144 case UNSPEC_GOT:
3145 if (flag_pic == 2)
3146 new = force_const_mem (Pmode, orig);
3147 break;
3149 /* @GOTENT is OK as is. */
3150 case UNSPEC_GOTENT:
3151 break;
3153 /* @PLT is OK as is on 64-bit, must be converted to
3154 GOT-relative @PLTOFF on 31-bit. */
3155 case UNSPEC_PLT:
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),
3165 UNSPEC_PLTOFF);
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);
3171 if (reg != 0)
3173 s390_load_address (reg, new);
3174 new = reg;
3177 break;
3179 /* Everything else cannot happen. */
3180 default:
3181 abort ();
3184 else if (GET_CODE (addr) != PLUS)
3185 abort ();
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);
3209 op1 = const1_rtx;
3212 emit_move_insn (temp, op0);
3213 new = gen_rtx_PLUS (Pmode, temp, op1);
3215 if (reg != 0)
3217 s390_load_address (reg, new);
3218 new = reg;
3221 else
3223 /* If the offset is even, we can just use LARL.
3224 This will happen automatically. */
3227 else
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),
3237 UNSPEC_GOTOFF);
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);
3244 if (reg != 0)
3246 s390_load_address (reg, new);
3247 new = reg;
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)
3260 abort ();
3262 new = force_const_mem (Pmode, orig);
3265 /* Otherwise, compute the sum. */
3266 else
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));
3273 else
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);
3289 return new;
3292 /* Load the thread pointer into a register. */
3294 static rtx
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);
3302 return tp;
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;
3312 static void
3313 s390_emit_tls_call_insn (rtx result_reg, rtx tls_call)
3315 rtx insn;
3317 if (!flag_pic)
3318 abort ();
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. */
3333 static rtx
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:
3342 start_sequence ();
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 ();
3350 end_sequence ();
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);
3357 if (reg != 0)
3359 s390_load_address (reg, new);
3360 new = reg;
3362 break;
3364 case TLS_MODEL_LOCAL_DYNAMIC:
3365 start_sequence ();
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 ();
3373 end_sequence ();
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);
3390 if (reg != 0)
3392 s390_load_address (reg, new);
3393 new = reg;
3395 break;
3397 case TLS_MODEL_INITIAL_EXEC:
3398 if (flag_pic == 1)
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);
3427 else if (flag_pic)
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));
3448 else
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);
3459 new = temp;
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);
3467 if (reg != 0)
3469 s390_load_address (reg, new);
3470 new = reg;
3472 break;
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);
3482 if (reg != 0)
3484 s390_load_address (reg, new);
3485 new = reg;
3487 break;
3489 default:
3490 abort ();
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)
3499 new = addr;
3500 else
3501 abort ();
3502 break;
3504 default:
3505 abort ();
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);
3521 else
3522 abort (); /* for now ... */
3524 return new;
3527 /* Emit insns to move operands[1] into operands[0]. */
3529 void
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);
3538 else if (flag_pic)
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))
3564 return x;
3566 else if (flag_pic)
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))
3575 return x;
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);
3598 if (val != 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);
3611 if (val != 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);
3621 if (val != 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);
3631 return x;
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. */
3640 rtx
3641 legitimize_reload_address (rtx ad, enum machine_mode mode ATTRIBUTE_UNUSED,
3642 int opnum, int type)
3644 if (!optimize || TARGET_LONG_DISPLACEMENT)
3645 return NULL_RTX;
3647 if (GET_CODE (ad) == PLUS)
3649 rtx tem = simplify_binary_operation (PLUS, Pmode,
3650 XEXP (ad, 0), XEXP (ad, 1));
3651 if (tem)
3652 ad = tem;
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;
3662 rtx cst, tem, new;
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);
3674 return new;
3677 return NULL_RTX;
3680 /* Emit code to move LEN bytes from DST to SRC. */
3682 void
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)));
3696 else
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)
3706 mode = Pmode;
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);
3723 if (temp != count)
3724 emit_move_insn (count, temp);
3726 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
3727 if (temp != blocks)
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);
3742 if (temp != blocks)
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. */
3759 void
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)));
3773 else
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)
3783 mode = Pmode;
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);
3798 if (temp != count)
3799 emit_move_insn (count, temp);
3801 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
3802 if (temp != blocks)
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);
3815 if (temp != blocks)
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. */
3832 void
3833 s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
3835 rtx ccreg = gen_rtx_REG (CCUmode, CC_REGNUM);
3836 rtx tmp;
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));
3849 else
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));
3857 else
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)
3867 mode = Pmode;
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);
3884 if (temp != count)
3885 emit_move_insn (count, temp);
3887 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
3888 if (temp != blocks)
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);
3909 if (temp != blocks)
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; */
3946 bool
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;
3952 rtx op_res;
3953 rtx insn;
3954 rtvec p;
3956 if ((GET_MODE (cmp_op0) == SImode || GET_MODE (cmp_op0) == VOIDmode)
3957 && (GET_MODE (cmp_op1) == SImode || GET_MODE (cmp_op1) == VOIDmode))
3958 cmp_mode = SImode;
3959 else if ((GET_MODE (cmp_op0) == DImode || GET_MODE (cmp_op0) == VOIDmode)
3960 && (GET_MODE (cmp_op1) == DImode || GET_MODE (cmp_op1) == VOIDmode))
3961 cmp_mode = DImode;
3962 else
3963 return false;
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)
3983 rtx tem = cmp_op0;
3984 cmp_op0 = cmp_op1;
3985 cmp_op1 = tem;
3986 cmp_code = swap_condition (cmp_code);
3989 switch (cmp_code)
3991 case GTU:
3992 cc_mode = CCUmode;
3993 break;
3995 case GEU:
3996 cc_mode = CCL3mode;
3997 break;
3999 default:
4000 return false;
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)))
4011 abort ();
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),
4016 const0_rtx);
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);
4028 RTVEC_ELT (p, 0) =
4029 gen_rtx_SET (VOIDmode, dst, op_res);
4030 RTVEC_ELT (p, 1) =
4031 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
4032 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
4034 return true;
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)
4055 rtx tem = cmp_op0;
4056 cmp_op0 = cmp_op1;
4057 cmp_op1 = tem;
4058 cmp_code = swap_condition (cmp_code);
4061 switch (cmp_code)
4063 case LEU:
4064 cc_mode = CCUmode;
4065 break;
4067 case LTU:
4068 cc_mode = CCL3mode;
4069 break;
4071 default:
4072 return false;
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)))
4083 abort ();
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),
4093 const0_rtx));
4094 p = rtvec_alloc (2);
4095 RTVEC_ELT (p, 0) =
4096 gen_rtx_SET (VOIDmode, dst, op_res);
4097 RTVEC_ELT (p, 1) =
4098 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
4099 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
4101 return true;
4104 return false;
4108 /* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
4109 We need to emit DTP-relative relocations. */
4111 void
4112 s390_output_dwarf_dtprel (FILE *file, int size, rtx x)
4114 switch (size)
4116 case 4:
4117 fputs ("\t.long\t", file);
4118 break;
4119 case 8:
4120 fputs ("\t.quad\t", file);
4121 break;
4122 default:
4123 abort ();
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. */
4133 static rtx
4134 s390_delegitimize_address (rtx orig_x)
4136 rtx x = orig_x, y;
4138 if (GET_CODE (x) != MEM)
4139 return orig_x;
4141 x = XEXP (x, 0);
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);
4151 return orig_x;
4154 if (GET_CODE (x) == CONST)
4156 y = XEXP (x, 0);
4157 if (GET_CODE (y) == UNSPEC
4158 && XINT (y, 1) == UNSPEC_GOTENT)
4159 return XVECEXP (y, 0, 0);
4160 return orig_x;
4163 return orig_x;
4166 /* Output shift count operand OP to stdio stream FILE. */
4168 static void
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);
4178 op = NULL_RTX;
4180 if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
4182 offset = INTVAL (XEXP (op, 1));
4183 op = XEXP (op, 0);
4185 while (op && GET_CODE (op) == SUBREG)
4186 op = SUBREG_REG (op);
4188 /* Sanity check. */
4189 if (op && (GET_CODE (op) != REG
4190 || REGNO (op) >= FIRST_PSEUDO_REGISTER
4191 || REGNO_REG_CLASS (REGNO (op)) != ADDR_REGS))
4192 abort ();
4194 /* Shift counts are truncated to the low six bits anyway. */
4195 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset & 63);
4196 if (op)
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. */
4203 static const char *
4204 get_some_local_dynamic_name (void)
4206 rtx insn;
4208 if (cfun->machine->some_ld_name)
4209 return cfun->machine->some_ld_name;
4211 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
4212 if (INSN_P (insn)
4213 && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
4214 return cfun->machine->some_ld_name;
4216 abort ();
4219 static int
4220 get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
4222 rtx x = *px;
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);
4234 return 1;
4237 return 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. */
4244 bool
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))
4250 case UNSPEC_GOTENT:
4251 output_addr_const (file, XVECEXP (x, 0, 0));
4252 fprintf (file, "@GOTENT");
4253 return true;
4254 case UNSPEC_GOT:
4255 output_addr_const (file, XVECEXP (x, 0, 0));
4256 fprintf (file, "@GOT");
4257 return true;
4258 case UNSPEC_GOTOFF:
4259 output_addr_const (file, XVECEXP (x, 0, 0));
4260 fprintf (file, "@GOTOFF");
4261 return true;
4262 case UNSPEC_PLT:
4263 output_addr_const (file, XVECEXP (x, 0, 0));
4264 fprintf (file, "@PLT");
4265 return true;
4266 case UNSPEC_PLTOFF:
4267 output_addr_const (file, XVECEXP (x, 0, 0));
4268 fprintf (file, "@PLTOFF");
4269 return true;
4270 case UNSPEC_TLSGD:
4271 output_addr_const (file, XVECEXP (x, 0, 0));
4272 fprintf (file, "@TLSGD");
4273 return true;
4274 case UNSPEC_TLSLDM:
4275 assemble_name (file, get_some_local_dynamic_name ());
4276 fprintf (file, "@TLSLDM");
4277 return true;
4278 case UNSPEC_DTPOFF:
4279 output_addr_const (file, XVECEXP (x, 0, 0));
4280 fprintf (file, "@DTPOFF");
4281 return true;
4282 case UNSPEC_NTPOFF:
4283 output_addr_const (file, XVECEXP (x, 0, 0));
4284 fprintf (file, "@NTPOFF");
4285 return true;
4286 case UNSPEC_GOTNTPOFF:
4287 output_addr_const (file, XVECEXP (x, 0, 0));
4288 fprintf (file, "@GOTNTPOFF");
4289 return true;
4290 case UNSPEC_INDNTPOFF:
4291 output_addr_const (file, XVECEXP (x, 0, 0));
4292 fprintf (file, "@INDNTPOFF");
4293 return true;
4296 return false;
4299 /* Output address operand ADDR in assembler syntax to
4300 stdio stream FILE. */
4302 void
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.");
4312 if (ad.disp)
4313 output_addr_const (file, ad.disp);
4314 else
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)]);
4320 else if (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
4326 are recognized:
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. */
4344 void
4345 print_operand (FILE *file, rtx x, int code)
4347 switch (code)
4349 case 'C':
4350 fprintf (file, s390_branch_condition_mnemonic (x, FALSE));
4351 return;
4353 case 'D':
4354 fprintf (file, s390_branch_condition_mnemonic (x, TRUE));
4355 return;
4357 case 'J':
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 ());
4373 else
4374 abort ();
4375 return;
4377 case 'O':
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))
4384 || ad.indx)
4385 abort ();
4387 if (ad.disp)
4388 output_addr_const (file, ad.disp);
4389 else
4390 fprintf (file, "0");
4392 return;
4394 case 'R':
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))
4401 || ad.indx)
4402 abort ();
4404 if (ad.base)
4405 fprintf (file, "%s", reg_names[REGNO (ad.base)]);
4406 else
4407 fprintf (file, "0");
4409 return;
4411 case 'S':
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))
4418 || ad.indx)
4419 abort ();
4421 if (ad.disp)
4422 output_addr_const (file, ad.disp);
4423 else
4424 fprintf (file, "0");
4426 if (ad.base)
4427 fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
4429 return;
4431 case 'N':
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));
4436 else
4437 abort ();
4438 break;
4440 case 'M':
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));
4445 else
4446 abort ();
4447 break;
4449 case 'Y':
4450 print_shift_count_operand (file, x);
4451 return;
4454 switch (GET_CODE (x))
4456 case REG:
4457 fprintf (file, "%s", reg_names[REGNO (x)]);
4458 break;
4460 case MEM:
4461 output_address (XEXP (x, 0));
4462 break;
4464 case CONST:
4465 case CODE_LABEL:
4466 case LABEL_REF:
4467 case SYMBOL_REF:
4468 output_addr_const (file, x);
4469 break;
4471 case CONST_INT:
4472 if (code == 'b')
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));
4484 else
4485 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
4486 break;
4488 case CONST_DOUBLE:
4489 if (GET_MODE (x) != VOIDmode)
4490 abort ();
4491 if (code == 'b')
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);
4497 else
4498 abort ();
4499 break;
4501 default:
4502 fatal_insn ("UNKNOWN in print_operand !?", x);
4503 break;
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. */
4511 static bool
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",
4518 INTVAL (x));
4519 return true;
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. */
4527 static int
4528 reg_used_in_mem_p (int regno, rtx x)
4530 enum rtx_code code = GET_CODE (x);
4531 int i, j;
4532 const char *fmt;
4534 if (code == MEM)
4536 if (refers_to_regno_p (regno, regno+1,
4537 XEXP (x, 0), 0))
4538 return 1;
4540 else if (code == SET
4541 && GET_CODE (SET_DEST (x)) == PC)
4543 if (refers_to_regno_p (regno, regno+1,
4544 SET_SRC (x), 0))
4545 return 1;
4548 fmt = GET_RTX_FORMAT (code);
4549 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4551 if (fmt[i] == 'e'
4552 && reg_used_in_mem_p (regno, XEXP (x, i)))
4553 return 1;
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)))
4558 return 1;
4560 return 0;
4563 /* Returns true if expression DEP_RTX sets an address register
4564 used by instruction INSN to address memory. */
4566 static int
4567 addr_generation_dependency_p (rtx dep_rtx, rtx insn)
4569 rtx target, pat;
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)
4592 abort();
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);
4597 else
4598 abort();
4600 else if (get_attr_atype (insn) == ATYPE_AGEN)
4601 return reg_used_in_mem_p (regno, PATTERN (insn));
4604 return 0;
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);
4613 int i;
4615 if (GET_CODE (dep_rtx) == SET
4616 && addr_generation_dependency_p (dep_rtx, insn))
4617 return 1;
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))
4623 return 1;
4626 return 0;
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. */
4637 static int
4638 s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
4640 if (! INSN_P (insn))
4641 return priority;
4643 if (s390_tune != PROCESSOR_2084_Z990)
4644 return priority;
4646 switch (s390_safe_attr_type (insn))
4648 case TYPE_FSTORED:
4649 case TYPE_FSTORES:
4650 priority = priority << 3;
4651 break;
4652 case TYPE_STORE:
4653 case TYPE_STM:
4654 priority = priority << 1;
4655 break;
4656 default:
4657 break;
4659 return priority;
4662 /* The number of instructions that can be issued per cycle. */
4664 static int
4665 s390_issue_rate (void)
4667 if (s390_tune == PROCESSOR_2084_Z990)
4668 return 3;
4669 return 1;
4672 static int
4673 s390_first_cycle_multipass_dfa_lookahead (void)
4675 return 4;
4679 /* Split all branches that exceed the maximum distance.
4680 Returns true if this created a new literal pool entry. */
4682 static int
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;
4688 rtx *label;
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)
4699 continue;
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)
4705 continue;
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);
4717 else
4718 continue;
4720 else
4721 continue;
4723 if (get_attr_length (insn) <= 4)
4724 continue;
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;
4730 if (!flag_pic)
4732 new_literal = 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));
4738 target = temp_reg;
4740 else
4742 new_literal = 1;
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),
4753 UNSPEC_LTREL_BASE);
4754 target = gen_rtx_PLUS (Pmode, temp_reg, target);
4757 if (!validate_change (insn, label, target, 0))
4758 abort ();
4761 return new_literal;
4764 /* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
4765 Fix up MEMs as required. */
4767 static void
4768 annotate_constant_pool_refs (rtx *x)
4770 int i, j;
4771 const char *fmt;
4773 if (GET_CODE (*x) == SYMBOL_REF
4774 && CONSTANT_POOL_ADDRESS_P (*x))
4775 abort ();
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),
4787 UNSPEC_LTREF);
4789 *x = replace_equiv_address (*x, addr);
4790 return;
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),
4803 UNSPEC_LTREF);
4805 *x = replace_equiv_address (*x, plus_constant (addr, off));
4806 return;
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),
4820 UNSPEC_LTREF);
4822 SET_SRC (*x) = addr;
4823 return;
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),
4836 UNSPEC_LTREF);
4838 SET_SRC (*x) = plus_constant (addr, off);
4839 return;
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),
4849 UNSPEC_LTREL_BASE);
4850 return;
4853 fmt = GET_RTX_FORMAT (GET_CODE (*x));
4854 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
4856 if (fmt[i] == 'e')
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. */
4877 static void
4878 find_constant_pool_ref (rtx x, rtx *ref)
4880 int i, j;
4881 const char *fmt;
4883 /* Ignore LTREL_BASE references. */
4884 if (GET_CODE (x) == UNSPEC
4885 && XINT (x, 1) == UNSPEC_LTREL_BASE)
4886 return;
4887 /* Likewise POOL_ENTRY insns. */
4888 if (GET_CODE (x) == UNSPEC_VOLATILE
4889 && XINT (x, 1) == UNSPECV_POOL_ENTRY)
4890 return;
4892 if (GET_CODE (x) == SYMBOL_REF
4893 && CONSTANT_POOL_ADDRESS_P (x))
4894 abort ();
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))
4901 abort ();
4903 if (*ref == NULL_RTX)
4904 *ref = sym;
4905 else if (*ref != sym)
4906 abort ();
4908 return;
4911 fmt = GET_RTX_FORMAT (GET_CODE (x));
4912 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4914 if (fmt[i] == 'e')
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. */
4929 static void
4930 replace_constant_pool_ref (rtx *x, rtx ref, rtx offset)
4932 int i, j;
4933 const char *fmt;
4935 if (*x == ref)
4936 abort ();
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);
4943 return;
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)));
4954 return;
4957 fmt = GET_RTX_FORMAT (GET_CODE (*x));
4958 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
4960 if (fmt[i] == 'e')
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. */
4975 static rtx
4976 find_ltrel_base (rtx x)
4978 int i, j;
4979 const char *fmt;
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--)
4988 if (fmt[i] == 'e')
4990 rtx fnd = find_ltrel_base (XEXP (x, i));
4991 if (fnd)
4992 return fnd;
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));
4999 if (fnd)
5000 return fnd;
5005 return NULL_RTX;
5008 /* Replace any occurrence of UNSPEC_LTREL_BASE in X with its base. */
5010 static void
5011 replace_ltrel_base (rtx *x)
5013 int i, j;
5014 const char *fmt;
5016 if (GET_CODE (*x) == UNSPEC
5017 && XINT (*x, 1) == UNSPEC_LTREL_BASE)
5019 *x = XVECEXP (*x, 0, 1);
5020 return;
5023 fmt = GET_RTX_FORMAT (GET_CODE (*x));
5024 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
5026 if (fmt[i] == 'e')
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] =
5045 TImode,
5046 DFmode, DImode,
5047 SFmode, SImode,
5048 HImode,
5049 QImode
5052 struct constant
5054 struct constant *next;
5055 rtx value;
5056 rtx label;
5059 struct constant_pool
5061 struct constant_pool *next;
5062 rtx first_insn;
5063 rtx pool_insn;
5064 bitmap insns;
5066 struct constant *constants[NR_C_MODES];
5067 struct constant *execute;
5068 rtx label;
5069 int size;
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)
5108 *prev = pool;
5110 return pool;
5113 /* End range of instructions covered by POOL at INSN and emit
5114 placeholder insn representing the pool. */
5116 static void
5117 s390_end_pool (struct constant_pool *pool, rtx insn)
5119 rtx pool_size = GEN_INT (pool->size + 8 /* alignment slop */);
5121 if (!insn)
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. */
5130 static void
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)))
5145 break;
5147 return pool;
5150 /* Add constant VAL of mode MODE to the constant pool POOL. */
5152 static void
5153 s390_add_constant (struct constant_pool *pool, rtx val, enum machine_mode mode)
5155 struct constant *c;
5156 int i;
5158 for (i = 0; i < NR_C_MODES; i++)
5159 if (constant_modes[i] == mode)
5160 break;
5161 if (i == NR_C_MODES)
5162 abort ();
5164 for (c = pool->constants[i]; c != NULL; c = c->next)
5165 if (rtx_equal_p (val, c->value))
5166 break;
5168 if (c == NULL)
5170 c = (struct constant *) xmalloc (sizeof *c);
5171 c->value = val;
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. */
5183 static rtx
5184 s390_find_constant (struct constant_pool *pool, rtx val,
5185 enum machine_mode mode)
5187 struct constant *c;
5188 rtx offset;
5189 int i;
5191 for (i = 0; i < NR_C_MODES; i++)
5192 if (constant_modes[i] == mode)
5193 break;
5194 if (i == NR_C_MODES)
5195 abort ();
5197 for (c = pool->constants[i]; c != NULL; c = c->next)
5198 if (rtx_equal_p (val, c->value))
5199 break;
5201 if (c == NULL)
5202 abort ();
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);
5207 return offset;
5210 /* Add execute target for INSN to the constant pool POOL. */
5212 static void
5213 s390_add_execute (struct constant_pool *pool, rtx insn)
5215 struct constant *c;
5217 for (c = pool->execute; c != NULL; c = c->next)
5218 if (INSN_UID (insn) == INSN_UID (c->value))
5219 break;
5221 if (c == NULL)
5223 rtx label = s390_execute_label (insn);
5224 gcc_assert (label);
5226 c = (struct constant *) xmalloc (sizeof *c);
5227 c->value = insn;
5228 c->label = label == const0_rtx ? gen_label_rtx () : XEXP (label, 0);
5229 c->next = pool->execute;
5230 pool->execute = c;
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. */
5239 static rtx
5240 s390_find_execute (struct constant_pool *pool, rtx insn)
5242 struct constant *c;
5243 rtx offset;
5245 for (c = pool->execute; c != NULL; c = c->next)
5246 if (INSN_UID (insn) == INSN_UID (c->value))
5247 break;
5249 if (c == NULL)
5250 abort ();
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);
5255 return offset;
5258 /* Check whether INSN is an execute. Return the label_ref to its
5259 execute target template if so, NULL_RTX otherwise. */
5261 static rtx
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);
5270 return NULL_RTX;
5273 /* For an execute INSN, extract the execute target template. */
5275 static rtx
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));
5285 else
5287 rtvec vec = rtvec_alloc (XVECLEN (pattern, 0) - 1);
5288 int i;
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);
5296 return pattern;
5299 /* Indicate that INSN cannot be duplicated. This is the case for
5300 execute insns that carry a unique label. */
5302 static bool
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. */
5312 static void
5313 s390_dump_pool (struct constant_pool *pool, bool remote_label)
5315 struct constant *c;
5316 rtx insn = pool->pool_insn;
5317 int i;
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);
5329 else
5330 insn = emit_insn_after (gen_pool_align (GEN_INT (4)), insn);
5331 INSN_ADDRESSES_NEW (insn, -1);
5333 /* Emit pool base label. */
5334 if (!remote_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)
5375 continue;
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. */
5404 static void
5405 s390_dump_execute (struct constant_pool *pool)
5407 struct constant *c;
5408 rtx insn;
5410 for (c = pool->execute; c; c = c->next)
5412 if (s390_execute_label (c->value) == const0_rtx)
5413 continue;
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;
5429 int i;
5431 pool = (struct constant_pool *) xmalloc (sizeof *pool);
5432 pool->next = NULL;
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 ();
5441 pool->size = 0;
5443 return pool;
5446 /* Free all memory used by POOL. */
5448 static void
5449 s390_free_pool (struct constant_pool *pool)
5451 struct constant *c, *next;
5452 int i;
5454 for (i = 0; i < NR_C_MODES; i++)
5455 for (c = pool->constants[i]; c; c = next)
5457 next = c->next;
5458 free (c);
5461 for (c = pool->execute; c; c = next)
5463 next = c->next;
5464 free (c);
5467 BITMAP_XFREE (pool->insns);
5468 free (pool);
5472 /* Collect main literal pool. Return NULL on overflow. */
5474 static struct constant_pool *
5475 s390_mainpool_start (void)
5477 struct constant_pool *pool;
5478 rtx insn;
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)
5490 abort ();
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);
5502 if (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)
5512 abort ();
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);
5521 pool = NULL;
5524 return 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. */
5531 static void
5532 s390_mainpool_finish (struct constant_pool *pool)
5534 rtx base_reg = cfun->machine->base_reg;
5535 rtx insn;
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);
5549 return;
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. */
5594 else
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))
5620 if (INSN_P (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);
5627 if (pool_ref)
5629 if (s390_execute_label (insn))
5630 addr = s390_find_execute (pool, insn);
5631 else
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. */
5649 static void
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;
5667 int extra_size = 0;
5668 bitmap far_labels;
5669 rtx pending_ltrel = NULL_RTX;
5670 rtx insn;
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. */
5685 if (INSN_P (insn))
5687 rtx ltrel_base = find_ltrel_base (PATTERN (insn));
5688 if (ltrel_base)
5690 if (ltrel_base == pending_ltrel)
5691 pending_ltrel = NULL_RTX;
5692 else
5693 abort ();
5697 if (s390_execute_label (insn))
5699 if (!curr_pool)
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);
5709 if (pool_ref)
5711 rtx constant = get_pool_constant (pool_ref);
5712 enum machine_mode mode = get_pool_mode (pool_ref);
5714 if (!curr_pool)
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)
5726 if (pending_ltrel)
5727 abort ();
5728 pending_ltrel = pool_ref;
5733 if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CODE_LABEL)
5735 if (curr_pool)
5736 s390_add_pool_insn (curr_pool, insn);
5737 /* An LTREL_BASE must follow within the same basic block. */
5738 if (pending_ltrel)
5739 abort ();
5742 if (!curr_pool
5743 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn)
5744 || INSN_ADDRESSES (INSN_UID (insn)) == -1)
5745 continue;
5747 if (TARGET_CPU_ZARCH)
5749 if (curr_pool->size < S390_POOL_CHUNK_MAX)
5750 continue;
5752 s390_end_pool (curr_pool, NULL_RTX);
5753 curr_pool = NULL;
5755 else
5757 int chunk_size = INSN_ADDRESSES (INSN_UID (insn))
5758 - INSN_ADDRESSES (INSN_UID (curr_pool->first_insn))
5759 + extra_size;
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)
5766 extra_size += 6;
5768 if (chunk_size < S390_POOL_CHUNK_MIN
5769 && curr_pool->size < S390_POOL_CHUNK_MIN)
5770 continue;
5772 /* Pool chunks can only be inserted after BARRIERs ... */
5773 if (GET_CODE (insn) == BARRIER)
5775 s390_end_pool (curr_pool, insn);
5776 curr_pool = NULL;
5777 extra_size = 0;
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)
5788 continue;
5789 if (get_attr_length (insn) == 0)
5790 continue;
5792 /* Don't separate LTREL_BASE from the corresponding
5793 LTREL_OFFSET load. */
5794 if (pending_ltrel)
5795 continue;
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);
5809 curr_pool = NULL;
5810 extra_size = 0;
5815 if (curr_pool)
5816 s390_end_pool (curr_pool, NULL_RTX);
5817 if (pending_ltrel)
5818 abort ();
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
5833 a jump table. */
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;
5841 if (!vec_pat
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);
5858 if (label)
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;
5876 if (vec_pat
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,
5900 curr_pool->label);
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);
5912 if (pool)
5914 rtx new_insn = gen_reload_base (cfun->machine->base_reg,
5915 pool->label);
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 ());
5929 return pool_list;
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. */
5936 static void
5937 s390_chunkify_finish (struct constant_pool *pool_list)
5939 struct constant_pool *curr_pool = NULL;
5940 rtx insn;
5943 /* Replace all literal pool references. */
5945 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5947 if (INSN_P (insn))
5948 replace_ltrel_base (&PATTERN (insn));
5950 curr_pool = s390_find_pool (pool_list, insn);
5951 if (!curr_pool)
5952 continue;
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);
5958 if (pool_ref)
5960 if (s390_execute_label (insn))
5961 addr = s390_find_execute (curr_pool, insn);
5962 else
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. */
5980 while (pool_list)
5982 struct constant_pool *next = pool_list->next;
5983 s390_free_pool (pool_list);
5984 pool_list = next;
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. */
5992 static void
5993 s390_chunkify_cancel (struct constant_pool *pool_list)
5995 struct constant_pool *curr_pool = NULL;
5996 rtx insn;
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)
6015 remove_insn (jump);
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)
6033 remove_insn (insn);
6035 insn = next_insn;
6038 /* Free pool list. */
6040 while (pool_list)
6042 struct constant_pool *next = pool_list->next;
6043 s390_free_pool (pool_list);
6044 pool_list = next;
6049 /* Output the constant pool entry EXP in mode MODE with alignment ALIGN. */
6051 void
6052 s390_output_pool_entry (rtx exp, enum machine_mode mode, unsigned int align)
6054 REAL_VALUE_TYPE r;
6056 switch (GET_MODE_CLASS (mode))
6058 case MODE_FLOAT:
6059 if (GET_CODE (exp) != CONST_DOUBLE)
6060 abort ();
6062 REAL_VALUE_FROM_CONST_DOUBLE (r, exp);
6063 assemble_real (r, mode, align);
6064 break;
6066 case MODE_INT:
6067 assemble_integer (exp, GET_MODE_SIZE (mode), align, 1);
6068 break;
6070 default:
6071 abort ();
6076 /* Rework the prologue/epilogue to avoid saving/restoring
6077 registers unnecessarily. */
6079 static void
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)))
6096 return;
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)
6108 continue;
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)
6121 continue;
6122 if (REGNO (base) != STACK_POINTER_REGNUM
6123 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
6124 continue;
6125 if (first > BASE_REGNUM || last < BASE_REGNUM)
6126 continue;
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);
6139 remove_insn (insn);
6140 continue;
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)
6157 continue;
6158 if (REGNO (base) != STACK_POINTER_REGNUM
6159 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
6160 continue;
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);
6172 remove_insn (insn);
6173 continue;
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)
6187 continue;
6188 if (REGNO (base) != STACK_POINTER_REGNUM
6189 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
6190 continue;
6191 if (first > BASE_REGNUM || last < BASE_REGNUM)
6192 continue;
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);
6205 remove_insn (insn);
6206 continue;
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)
6223 continue;
6224 if (REGNO (base) != STACK_POINTER_REGNUM
6225 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
6226 continue;
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);
6238 remove_insn (insn);
6239 continue;
6244 /* Perform machine-dependent processing. */
6246 static void
6247 s390_reorg (void)
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
6260 to correct:
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.) */
6289 for (;;)
6291 struct constant_pool *pool = NULL;
6293 /* Collect the literal pool. */
6294 if (!pool_overflow)
6296 pool = s390_mainpool_start ();
6297 if (!pool)
6298 pool_overflow = true;
6301 /* If literal pool overflowed, start to chunkify it. */
6302 if (pool_overflow)
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 ())
6311 if (pool_overflow)
6312 s390_chunkify_cancel (pool);
6313 else
6314 s390_mainpool_cancel (pool);
6316 continue;
6319 /* If we made it up to here, both conditions are satisfied.
6320 Finish up literal pool related changes. */
6321 if (pool_overflow)
6322 s390_chunkify_finish (pool);
6323 else
6324 s390_mainpool_finish (pool);
6326 /* We're done splitting branches. */
6327 cfun->machine->split_branches_pending_p = false;
6328 break;
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)
6342 int offset;
6343 rtx addr;
6345 /* Without backchain, we fail for all but the current frame. */
6347 if (!TARGET_BACKCHAIN && count > 0)
6348 return NULL_RTX;
6350 /* For the current frame, we need to make sure the initial
6351 value of RETURN_REGNUM is actually saved. */
6353 if (count == 0)
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;
6361 else
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)
6375 rtx chain;
6377 gcc_assert (TARGET_BACKCHAIN);
6379 if (TARGET_PACKED_STACK)
6380 chain = plus_constant (stack_pointer_rtx,
6381 STACK_POINTER_OFFSET - UNITS_PER_WORD);
6382 else
6383 chain = stack_pointer_rtx;
6385 chain = gen_rtx_MEM (Pmode, chain);
6386 return 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. */
6393 static int
6394 find_unused_clobbered_reg (void)
6396 int i;
6397 for (i = 0; i < 6; i++)
6398 if (!regs_ever_live[i])
6399 return i;
6400 return 0;
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). */
6409 static void
6410 s390_frame_area (int *area_bottom, int *area_top)
6412 int b, t;
6413 int i;
6415 b = INT_MAX;
6416 t = INT_MIN;
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));
6433 if (!TARGET_64BIT)
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);
6441 *area_bottom = b;
6442 *area_top = t;
6445 /* Fill cfun->machine with info about register usage of current function.
6446 Return in LIVE_REGS which GPRs are currently considered live. */
6448 static void
6449 s390_register_info (int live_regs[])
6451 int i, j;
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;
6456 if (TARGET_64BIT)
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];
6473 if (flag_pic)
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++)
6494 if (live_regs[i])
6495 break;
6496 for (j = 15; j > i; j--)
6497 if (live_regs[j])
6498 break;
6500 if (i == 16)
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;
6508 else
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);
6534 if (!TARGET_64BIT)
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. */
6542 static void
6543 s390_frame_info (void)
6545 int i;
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
6558 * UNITS_PER_WORD);
6560 else if (TARGET_BACKCHAIN) /* kernel stack layout */
6562 cfun_frame_layout.backchain_offset = (STACK_POINTER_OFFSET
6563 - UNITS_PER_WORD);
6564 cfun_frame_layout.gprs_offset
6565 = (cfun_frame_layout.backchain_offset
6566 - (STACK_POINTER_REGNUM - cfun_frame_layout.first_save_gpr + 1)
6567 * UNITS_PER_WORD);
6569 if (TARGET_64BIT)
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)));
6579 else
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)
6613 return;
6615 if (!TARGET_PACKED_STACK)
6616 cfun_frame_layout.frame_size += (STARTING_FRAME_OFFSET
6617 + cfun_frame_layout.high_fprs * 8);
6618 else
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
6624 64 bit. */
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. */
6652 static void
6653 s390_init_frame_layout (void)
6655 HOST_WIDE_INT frame_size;
6656 int base_used;
6657 int live_regs[16];
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. */
6687 if (!base_used)
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);
6691 else
6692 cfun->machine->base_reg = gen_rtx_REG (Pmode, BASE_REGNUM);
6694 s390_register_info (live_regs);
6695 s390_frame_info ();
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. */
6705 static void
6706 s390_update_frame_layout (void)
6708 int live_regs[16];
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. */
6722 bool
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)
6737 return false;
6739 return true;
6742 /* Return offset between register FROM and TO initially after prolog. */
6744 HOST_WIDE_INT
6745 s390_initial_elimination_offset (int from, int to)
6747 HOST_WIDE_INT offset;
6748 int index;
6750 /* ??? Why are we called for non-eliminable pairs? */
6751 if (!s390_can_eliminate (from, to))
6752 return 0;
6754 switch (from)
6756 case FRAME_POINTER_REGNUM:
6757 offset = 0;
6758 break;
6760 case ARG_POINTER_REGNUM:
6761 s390_init_frame_layout ();
6762 offset = cfun_frame_layout.frame_size + STACK_POINTER_OFFSET;
6763 break;
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;
6771 break;
6773 default:
6774 gcc_unreachable ();
6777 return offset;
6780 /* Emit insn to save fpr REGNUM at offset OFFSET relative
6781 to register BASE. Return generated insn. */
6783 static rtx
6784 save_fpr (rtx base, int offset, int regnum)
6786 rtx addr;
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. */
6796 static rtx
6797 restore_fpr (rtx base, int offset, int regnum)
6799 rtx addr;
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. */
6810 static rtx
6811 save_gprs (rtx base, int offset, int first, int last)
6813 rtx addr, insn, note;
6814 int i;
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. */
6821 if (first == last)
6823 if (TARGET_64BIT)
6824 insn = gen_movdi (addr, gen_rtx_REG (Pmode, first));
6825 else
6826 insn = gen_movsi (addr, gen_rtx_REG (Pmode, first));
6828 RTX_FRAME_RELATED_P (insn) = 1;
6829 return insn;
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. */
6850 if (first >= 6)
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;
6860 else if (last >= 6)
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);
6868 REG_NOTES (insn) =
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;
6879 return insn;
6882 /* Generate insn to restore registers FIRST to LAST from
6883 the register save area located at offset OFFSET
6884 relative to register BASE. */
6886 static rtx
6887 restore_gprs (rtx base, int offset, int first, int last)
6889 rtx addr, insn;
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. */
6896 if (first == last)
6898 if (TARGET_64BIT)
6899 insn = gen_movdi (gen_rtx_REG (Pmode, first), addr);
6900 else
6901 insn = gen_movsi (gen_rtx_REG (Pmode, first), addr);
6903 return insn;
6906 insn = gen_load_multiple (gen_rtx_REG (Pmode, first),
6907 addr,
6908 GEN_INT (last - first + 1));
6909 return insn;
6912 /* Return insn sequence to load the GOT register. */
6914 static GTY(()) rtx got_symbol;
6916 s390_load_got (void)
6918 rtx insns;
6920 if (!got_symbol)
6922 got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6923 SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
6926 start_sequence ();
6928 if (TARGET_CPU_ZARCH)
6930 emit_move_insn (pic_offset_table_rtx, got_symbol);
6932 else
6934 rtx offset;
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)),
6944 UNSPEC_LTREL_BASE);
6945 offset = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, offset);
6947 emit_move_insn (pic_offset_table_rtx, offset);
6950 insns = get_insns ();
6951 end_sequence ();
6952 return insns;
6955 /* Expand the prologue into a bunch of separate insns. */
6957 void
6958 s390_emit_prologue (void)
6960 rtx insn, addr;
6961 rtx temp_reg;
6962 int i;
6963 int offset;
6964 int next_fpr = 0;
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))
6976 if (INSN_P (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);
6986 else
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);
6996 emit_insn (insn);
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);
7012 offset += 8;
7014 else if (!TARGET_PACKED_STACK)
7015 offset += 8;
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);
7025 offset += 8;
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)
7033 offset += 8;
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;
7049 offset -= 8;
7051 if (offset >= cfun_frame_layout.f8_offset)
7052 next_fpr = i + 16;
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));
7071 if (TARGET_64BIT)
7072 gen_cmpdi (t, const0_rtx);
7073 else
7074 gen_cmpsi (t, const0_rtx);
7076 emit_insn (gen_conditional_trap (gen_rtx_EQ (CCmode,
7077 gen_rtx_REG (CCmode,
7078 CC_REGNUM),
7079 const0_rtx),
7080 const0_rtx));
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,
7101 frame_off));
7102 insn = emit_insn (insn);
7104 else
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;
7114 REG_NOTES (insn) =
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))),
7119 REG_NOTES (insn));
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));
7129 else
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)));
7153 offset = 0;
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
7161 + offset);
7163 insn = save_fpr (temp_reg, offset, i);
7164 offset += 8;
7165 RTX_FRAME_RELATED_P (insn) = 1;
7166 REG_NOTES (insn) =
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)),
7171 REG_NOTES (insn));
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,
7194 REG_NOTES (insn));
7197 emit_insn (insns);
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. */
7215 void
7216 s390_emit_epilogue (bool sibcall)
7218 rtx frame_pointer, return_reg;
7219 int area_bottom, area_top, offset = 0;
7220 int next_offset;
7221 rtvec p;
7222 int i;
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;
7258 else
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);
7271 else
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. */
7283 if (TARGET_64BIT)
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);
7294 next_offset += 8;
7300 else
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);
7309 next_offset += 8;
7311 else if (!TARGET_PACKED_STACK)
7312 next_offset += 8;
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)
7325 rtx insn, addr;
7326 int i;
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;
7333 i++)
7335 /* These registers are special and need to be
7336 restored in any case. */
7337 if (i == STACK_POINTER_REGNUM
7338 || i == RETURN_REGNUM
7339 || i == BASE_REGNUM
7340 || (flag_pic && i == (int)PIC_OFFSET_TABLE_REGNUM))
7341 continue;
7343 if (global_regs[i])
7345 addr = plus_constant (frame_pointer,
7346 offset + cfun_frame_layout.gprs_offset
7347 + (i - cfun_frame_layout.first_save_gpr)
7348 * UNITS_PER_WORD);
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));
7355 if (! sibcall)
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();
7365 if (!return_regnum)
7366 return_regnum = 4;
7367 return_reg = gen_rtx_REG (Pmode, return_regnum);
7369 addr = plus_constant (frame_pointer,
7370 offset + cfun_frame_layout.gprs_offset
7371 + (RETURN_REGNUM
7372 - cfun_frame_layout.first_save_gpr)
7373 * UNITS_PER_WORD);
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)
7384 * UNITS_PER_WORD,
7385 cfun_frame_layout.first_restore_gpr,
7386 cfun_frame_layout.last_restore_gpr);
7387 emit_insn (insn);
7390 if (! sibcall)
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. */
7408 static int
7409 s390_function_arg_size (enum machine_mode mode, tree type)
7411 if (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 */
7419 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. */
7425 static bool
7426 s390_function_arg_float (enum machine_mode mode, tree type)
7428 int size = s390_function_arg_size (mode, type);
7429 if (size > 8)
7430 return false;
7432 /* Soft-float changes the ABI: no floating-point registers are used. */
7433 if (TARGET_SOFT_FLOAT)
7434 return false;
7436 /* No type info available for some library calls ... */
7437 if (!type)
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)
7449 continue;
7451 if (single == NULL_TREE)
7452 single = TREE_TYPE (field);
7453 else
7454 return false;
7457 if (single == NULL_TREE)
7458 return false;
7459 else
7460 type = single;
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. */
7470 static bool
7471 s390_function_arg_integer (enum machine_mode mode, tree type)
7473 int size = s390_function_arg_size (mode, type);
7474 if (size > 8)
7475 return false;
7477 /* No type info available for some library calls ... */
7478 if (!type)
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))
7487 return true;
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))
7494 return true;
7496 return false;
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
7503 reference. */
7505 static bool
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);
7511 if (size > 8)
7512 return true;
7514 if (type)
7516 if (AGGREGATE_TYPE_P (type) && exact_log2 (size) < 0)
7517 return 1;
7519 if (TREE_CODE (type) == COMPLEX_TYPE
7520 || TREE_CODE (type) == VECTOR_TYPE)
7521 return 1;
7524 return 0;
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). */
7533 void
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))
7539 cum->fprs += 1;
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);
7546 else
7547 abort ();
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
7557 not be available.
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))
7576 return 0;
7577 else
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)
7586 return 0;
7587 else
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)
7597 return const0_rtx;
7599 abort ();
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. */
7606 static bool
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
7617 in memory. */
7618 if (AGGREGATE_TYPE_P (type)
7619 || TREE_CODE (type) == COMPLEX_TYPE
7620 || TREE_CODE (type) == VECTOR_TYPE)
7621 return true;
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. */
7626 return true;
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)
7636 if (type)
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)
7644 abort ();
7645 if (GET_MODE_SIZE (mode) > 8)
7646 abort ();
7648 if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT)
7649 return gen_rtx_REG (mode, 16);
7650 else
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
7661 long __gpr;
7662 long __fpr;
7663 void *__overflow_arg_area;
7664 void *__reg_save_area;
7665 } va_list[1];
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. */
7676 static tree
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);
7683 type_decl =
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"),
7691 ptr_type_node);
7692 f_sav = build_decl (FIELD_DECL, get_identifier ("__reg_save_area"),
7693 ptr_type_node);
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). */
7726 void
7727 s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
7729 HOST_WIDE_INT n_gpr, n_fpr;
7730 int off;
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]
7795 else
7796 ret = *args.overflow_arg_area++;
7797 } else if (float value) {
7798 if (args.fgpr < 2)
7799 ret = args.reg_save_area[args.fpr+64]
7800 else
7801 ret = *args.overflow_arg_area++;
7802 } else if (aggregate value) {
7803 if (args.gpr < 5)
7804 ret = *args.reg_save_area[args.gpr]
7805 else
7806 ret = **args.overflow_arg_area++;
7807 } */
7809 tree
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");
7836 debug_tree (type);
7839 /* Aggregates are passed by reference. */
7840 indirect_p = 1;
7841 reg = gpr;
7842 n_reg = 1;
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;
7850 max_reg = 4;
7852 else if (s390_function_arg_float (TYPE_MODE (type), type))
7854 if (TARGET_DEBUG_ARG)
7856 fprintf (stderr, "va_arg: float type");
7857 debug_tree (type);
7860 /* FP args go in FP registers, if present. */
7861 indirect_p = 0;
7862 reg = fpr;
7863 n_reg = 1;
7864 sav_ofs = 16 * UNITS_PER_WORD;
7865 sav_scale = 8;
7866 /* TARGET_64BIT has up to 4 parameter in fprs */
7867 max_reg = TARGET_64BIT ? 3 : 1;
7869 else
7871 if (TARGET_DEBUG_ARG)
7873 fprintf (stderr, "va_arg: other type");
7874 debug_tree (type);
7877 /* Otherwise into GP registers. */
7878 indirect_p = 0;
7879 reg = gpr;
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;
7891 if (n_reg > 1)
7892 max_reg = 3;
7893 else
7894 max_reg = 4;
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. */
7928 t = ovf;
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);
7953 if (indirect_p)
7955 t = build_pointer_type (build_pointer_type (type));
7956 addr = fold_convert (t, addr);
7957 addr = build_va_arg_indirect_ref (addr);
7959 else
7961 t = build_pointer_type (type);
7962 addr = fold_convert (t, addr);
7965 return build_va_arg_indirect_ref (addr);
7969 /* Builtins. */
7971 enum s390_builtin
7973 S390_BUILTIN_THREAD_POINTER,
7974 S390_BUILTIN_SET_THREAD_POINTER,
7976 S390_BUILTIN_max
7979 static unsigned int const code_for_builtin_64[S390_BUILTIN_max] = {
7980 CODE_FOR_get_tp_64,
7981 CODE_FOR_set_tp_64
7984 static unsigned int const code_for_builtin_31[S390_BUILTIN_max] = {
7985 CODE_FOR_get_tp_31,
7986 CODE_FOR_set_tp_31
7989 static void
7990 s390_init_builtins (void)
7992 tree ftype;
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,
7997 NULL, NULL_TREE);
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,
8002 NULL, NULL_TREE);
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. */
8011 static rtx
8012 s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
8013 enum machine_mode mode ATTRIBUTE_UNUSED,
8014 int ignore ATTRIBUTE_UNUSED)
8016 #define MAX_ARGS 2
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;
8026 int arity;
8027 bool nonvoid;
8029 if (fcode >= S390_BUILTIN_max)
8030 internal_error ("bad builtin fcode");
8031 icode = code_for_builtin[fcode];
8032 if (icode == 0)
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;
8038 arglist;
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)
8045 return NULL_RTX;
8046 if (arity > MAX_ARGS)
8047 return NULL_RTX;
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]);
8057 if (nonvoid)
8059 enum machine_mode tmode = insn_data[icode].operand[0].mode;
8060 if (!target
8061 || GET_MODE (target) != tmode
8062 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
8063 target = gen_reg_rtx (tmode);
8066 switch (arity)
8068 case 0:
8069 pat = GEN_FCN (icode) (target);
8070 break;
8071 case 1:
8072 if (nonvoid)
8073 pat = GEN_FCN (icode) (target, op[0]);
8074 else
8075 pat = GEN_FCN (icode) (op[0]);
8076 break;
8077 case 2:
8078 pat = GEN_FCN (icode) (target, op[0], op[1]);
8079 break;
8080 default:
8081 abort ();
8083 if (!pat)
8084 return NULL_RTX;
8085 emit_insn (pat);
8087 if (nonvoid)
8088 return target;
8089 else
8090 return const0_rtx;
8094 /* Output assembly code for the trampoline template to
8095 stdio stream FILE.
8097 On S/390, we use gpr 1 internally in the trampoline code;
8098 gpr 0 is used to hold the static chain. */
8100 void
8101 s390_trampoline_template (FILE *file)
8103 rtx op[2];
8104 op[0] = gen_rtx_REG (Pmode, 0);
8105 op[1] = gen_rtx_REG (Pmode, 1);
8107 if (TARGET_64BIT)
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));
8114 else
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. */
8127 void
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
8145 HOST_WIDE_INT val;
8146 val = (HOST_WIDE_INT)high;
8147 val <<= 32;
8148 val |= (HOST_WIDE_INT)low;
8150 return GEN_INT (val);
8151 #else
8152 #if HOST_BITS_PER_WIDE_INT >= 32
8153 return immed_double_const ((HOST_WIDE_INT)low, (HOST_WIDE_INT)high, DImode);
8154 #else
8155 abort ();
8156 #endif
8157 #endif
8160 /* Output assembler code to FILE to increment profiler label # LABELNO
8161 for profiling a function entry. */
8163 void
8164 s390_function_profiler (FILE *file, int labelno)
8166 rtx op[7];
8168 char label[128];
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");
8182 if (flag_pic)
8184 op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), UNSPEC_PLT);
8185 op[4] = gen_rtx_CONST (Pmode, op[4]);
8188 if (TARGET_64BIT)
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);
8195 else if (!flag_pic)
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);
8209 else
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. */
8231 static void
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. */
8249 static void
8250 s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
8251 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
8252 tree function)
8254 rtx op[10];
8255 int nonlocal = 0;
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]))
8261 nonlocal = 1;
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);
8270 else
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. */
8283 op[5] = NULL_RTX;
8284 op[6] = NULL_RTX;
8285 op[7] = NULL_RTX;
8286 op[8] = NULL_RTX;
8288 /* Operand 9 can be used for temporary register. */
8289 op[9] = NULL_RTX;
8291 /* Generate code. */
8292 if (TARGET_64BIT)
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. */
8305 if (delta)
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);
8313 else
8315 op[6] = gen_label_rtx ();
8316 output_asm_insn ("agf\t%1,%6-%5(%4)", op);
8320 /* Perform vcall adjustment. */
8321 if (vcall_offset)
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);
8334 else
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. */
8347 if (op[5])
8349 output_asm_insn (".align\t4", op);
8350 targetm.asm_out.internal_label (file, "L",
8351 CODE_LABEL_NUMBER (op[5]));
8353 if (op[6])
8355 targetm.asm_out.internal_label (file, "L",
8356 CODE_LABEL_NUMBER (op[6]));
8357 output_asm_insn (".long\t%2", op);
8359 if (op[7])
8361 targetm.asm_out.internal_label (file, "L",
8362 CODE_LABEL_NUMBER (op[7]));
8363 output_asm_insn (".long\t%3", op);
8366 else
8368 /* Setup base pointer if required. */
8369 if (!vcall_offset
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. */
8382 if (delta)
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);
8390 else
8392 op[6] = gen_label_rtx ();
8393 output_asm_insn ("a\t%1,%6-%5(%4)", op);
8397 /* Perform vcall adjustment. */
8398 if (vcall_offset)
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);
8416 else
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 ();
8435 if (!flag_pic)
8436 output_asm_insn ("l\t%4,%8-%5(%4)", op);
8437 else if (!nonlocal)
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);
8461 if (nonlocal)
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]));
8468 if (!flag_pic)
8469 output_asm_insn (".long\t%0", op);
8470 else
8471 output_asm_insn (".long\t%0-%5", op);
8473 if (op[6])
8475 targetm.asm_out.internal_label (file, "L",
8476 CODE_LABEL_NUMBER (op[6]));
8477 output_asm_insn (".long\t%2", op);
8479 if (op[7])
8481 targetm.asm_out.internal_label (file, "L",
8482 CODE_LABEL_NUMBER (op[7]));
8483 output_asm_insn (".long\t%3", op);
8488 bool
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
8505 call. */
8507 static bool
8508 s390_call_saved_register_used (tree argument_list)
8510 CUMULATIVE_ARGS cum;
8511 tree parameter;
8512 enum machine_mode mode;
8513 tree type;
8514 rtx parm_rtx;
8515 int reg;
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);
8524 if (!parameter)
8525 abort();
8527 /* For an undeclared variable passed as parameter we will get
8528 an ERROR_MARK node here. */
8529 if (TREE_CODE (parameter) == ERROR_MARK)
8530 return true;
8532 if (! (type = TREE_TYPE (parameter)))
8533 abort();
8535 if (! (mode = TYPE_MODE (TREE_TYPE (parameter))))
8536 abort();
8538 if (pass_by_reference (&cum, mode, type, true))
8540 mode = Pmode;
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))
8550 for (reg = 0;
8551 reg < HARD_REGNO_NREGS (REGNO (parm_rtx), GET_MODE (parm_rtx));
8552 reg++)
8553 if (! call_used_regs[reg + REGNO (parm_rtx)])
8554 return true;
8557 return false;
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. */
8565 static bool
8566 s390_function_ok_for_sibcall (tree decl, tree exp)
8568 /* The TPF epilogue uses register 1. */
8569 if (TARGET_TPF_PROFILING)
8570 return false;
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))
8575 return false;
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)))
8582 return false;
8584 return true;
8587 /* Return the fixed registers used for condition codes. */
8589 static bool
8590 s390_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
8592 *p1 = CC_REGNUM;
8593 *p2 = INVALID_REGNUM;
8595 return true;
8598 /* If two condition code modes are compatible, return a condition code
8599 mode which is compatible with both. Otherwise, return
8600 VOIDmode. */
8602 static enum machine_mode
8603 s390_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
8605 if (m1 == m2)
8606 return m1;
8608 switch (m1)
8610 case CCZmode:
8611 if (m2 == CCUmode || m2 == CCTmode
8612 || m2 == CCSmode || m2 == CCSRmode || m2 == CCURmode)
8613 return m2;
8614 return VOIDmode;
8616 case CCSmode:
8617 case CCUmode:
8618 case CCTmode:
8619 case CCSRmode:
8620 case CCURmode:
8621 if (m2 == CCZmode)
8622 return m1;
8624 return VOIDmode;
8626 default:
8627 return VOIDmode;
8629 return VOIDmode;
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,
8644 rtx retaddr_reg)
8646 bool plt_call = false;
8647 rtx insn;
8648 rtx call;
8649 rtx clobber;
8650 rtvec vec;
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),
8661 UNSPEC_PLT);
8662 addr_location = gen_rtx_CONST (Pmode, addr_location);
8663 plt_call = true;
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)
8670 if (flag_pic)
8671 addr_location = legitimize_pic_address (addr_location, 0);
8672 else
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
8679 register 1. */
8680 if (retaddr_reg == NULL_RTX
8681 && GET_CODE (addr_location) != SYMBOL_REF
8682 && !plt_call)
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));
8701 else
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)
8715 abort ();
8717 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
8719 return insn;
8722 /* Implement CONDITIONAL_REGISTER_USAGE. */
8724 void
8725 s390_conditional_register_usage (void)
8727 int i;
8729 if (flag_pic)
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;
8739 if (TARGET_64BIT)
8741 for (i = 24; i < 32; i++)
8742 call_used_regs[i] = call_really_used_regs[i] = 0;
8744 else
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;
8760 void
8761 s390_emit_tpf_eh_return (rtx target)
8763 rtx insn, reg;
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"