2004-09-20 Andreas Krebbel <krebbel1@de.ibm.com>
[official-gcc.git] / gcc / config / s390 / s390.c
blob2dd515b95cb007c89d7573639f55b33758aa8540
1 /* Subroutines used for code generation on IBM S/390 and zSeries
2 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
3 Free Software Foundation, Inc.
4 Contributed by Hartmut Penner (hpenner@de.ibm.com) and
5 Ulrich Weigand (uweigand@de.ibm.com).
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
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_select_rtx_section (enum machine_mode, rtx,
61 unsigned HOST_WIDE_INT);
62 static void s390_encode_section_info (tree, rtx, int);
63 static bool s390_cannot_force_const_mem (rtx);
64 static rtx s390_delegitimize_address (rtx);
65 static bool s390_return_in_memory (tree, tree);
66 static void s390_init_builtins (void);
67 static rtx s390_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
68 static void s390_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
69 HOST_WIDE_INT, tree);
70 static enum attr_type s390_safe_attr_type (rtx);
72 static int s390_adjust_cost (rtx, rtx, rtx, int);
73 static int s390_adjust_priority (rtx, int);
74 static int s390_issue_rate (void);
75 static int s390_first_cycle_multipass_dfa_lookahead (void);
76 static bool s390_rtx_costs (rtx, int, int, int *);
77 static int s390_address_cost (rtx);
78 static void s390_reorg (void);
79 static bool s390_valid_pointer_mode (enum machine_mode);
80 static tree s390_build_builtin_va_list (void);
81 static tree s390_gimplify_va_arg (tree, tree, tree *, tree *);
82 static bool s390_function_ok_for_sibcall (tree, tree);
83 static bool s390_call_saved_register_used (tree);
84 static bool s390_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode mode,
85 tree, bool);
87 #undef TARGET_ASM_ALIGNED_HI_OP
88 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
89 #undef TARGET_ASM_ALIGNED_DI_OP
90 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
91 #undef TARGET_ASM_INTEGER
92 #define TARGET_ASM_INTEGER s390_assemble_integer
94 #undef TARGET_ASM_OPEN_PAREN
95 #define TARGET_ASM_OPEN_PAREN ""
97 #undef TARGET_ASM_CLOSE_PAREN
98 #define TARGET_ASM_CLOSE_PAREN ""
100 #undef TARGET_ASM_SELECT_RTX_SECTION
101 #define TARGET_ASM_SELECT_RTX_SECTION s390_select_rtx_section
103 #undef TARGET_ENCODE_SECTION_INFO
104 #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
106 #ifdef HAVE_AS_TLS
107 #undef TARGET_HAVE_TLS
108 #define TARGET_HAVE_TLS true
109 #endif
110 #undef TARGET_CANNOT_FORCE_CONST_MEM
111 #define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
113 #undef TARGET_DELEGITIMIZE_ADDRESS
114 #define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
116 #undef TARGET_RETURN_IN_MEMORY
117 #define TARGET_RETURN_IN_MEMORY s390_return_in_memory
119 #undef TARGET_INIT_BUILTINS
120 #define TARGET_INIT_BUILTINS s390_init_builtins
121 #undef TARGET_EXPAND_BUILTIN
122 #define TARGET_EXPAND_BUILTIN s390_expand_builtin
124 #undef TARGET_ASM_OUTPUT_MI_THUNK
125 #define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
126 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
127 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
129 #undef TARGET_SCHED_ADJUST_COST
130 #define TARGET_SCHED_ADJUST_COST s390_adjust_cost
131 #undef TARGET_SCHED_ADJUST_PRIORITY
132 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
133 #undef TARGET_SCHED_ISSUE_RATE
134 #define TARGET_SCHED_ISSUE_RATE s390_issue_rate
135 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
136 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
138 #undef TARGET_RTX_COSTS
139 #define TARGET_RTX_COSTS s390_rtx_costs
140 #undef TARGET_ADDRESS_COST
141 #define TARGET_ADDRESS_COST s390_address_cost
143 #undef TARGET_MACHINE_DEPENDENT_REORG
144 #define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
146 #undef TARGET_VALID_POINTER_MODE
147 #define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
149 #undef TARGET_BUILD_BUILTIN_VA_LIST
150 #define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
151 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
152 #define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg
154 #undef TARGET_PROMOTE_FUNCTION_ARGS
155 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
156 #undef TARGET_PROMOTE_FUNCTION_RETURN
157 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
158 #undef TARGET_PASS_BY_REFERENCE
159 #define TARGET_PASS_BY_REFERENCE s390_pass_by_reference
161 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
162 #define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
164 struct gcc_target targetm = TARGET_INITIALIZER;
166 extern int reload_completed;
168 /* The alias set for prologue/epilogue register save/restore. */
169 static int s390_sr_alias_set = 0;
171 /* Save information from a "cmpxx" operation until the branch or scc is
172 emitted. */
173 rtx s390_compare_op0, s390_compare_op1;
175 /* Structure used to hold the components of a S/390 memory
176 address. A legitimate address on S/390 is of the general
177 form
178 base + index + displacement
179 where any of the components is optional.
181 base and index are registers of the class ADDR_REGS,
182 displacement is an unsigned 12-bit immediate constant. */
184 struct s390_address
186 rtx base;
187 rtx indx;
188 rtx disp;
189 int pointer;
192 /* Which cpu are we tuning for. */
193 enum processor_type s390_tune;
194 enum processor_flags s390_tune_flags;
195 /* Which instruction set architecture to use. */
196 enum processor_type s390_arch;
197 enum processor_flags s390_arch_flags;
199 /* Strings to hold which cpu and instruction set architecture to use. */
200 const char *s390_tune_string; /* for -mtune=<xxx> */
201 const char *s390_arch_string; /* for -march=<xxx> */
203 /* String to specify backchain mode. */
204 const char *s390_backchain_string = ""; /* "" no-backchain ,"1" backchain,
205 "2" kernel-backchain */
207 const char *s390_warn_framesize_string;
208 const char *s390_warn_dynamicstack_string;
209 const char *s390_stack_size_string;
210 const char *s390_stack_guard_string;
212 HOST_WIDE_INT s390_warn_framesize = 0;
213 bool s390_warn_dynamicstack_p = 0;
214 HOST_WIDE_INT s390_stack_size = 0;
215 HOST_WIDE_INT s390_stack_guard = 0;
217 /* The following structure is embedded in the machine
218 specific part of struct function. */
220 struct s390_frame_layout GTY (())
222 /* Offset within stack frame. */
223 HOST_WIDE_INT gprs_offset;
224 HOST_WIDE_INT f0_offset;
225 HOST_WIDE_INT f4_offset;
226 HOST_WIDE_INT f8_offset;
227 HOST_WIDE_INT backchain_offset;
229 /* Number of first and last gpr to be saved, restored. */
230 int first_save_gpr;
231 int first_restore_gpr;
232 int last_save_gpr;
233 int last_restore_gpr;
235 /* Bits standing for floating point registers. Set, if the
236 respective register has to be saved. Starting with reg 16 (f0)
237 at the rightmost bit.
238 Bit 15 - 8 7 6 5 4 3 2 1 0
239 fpr 15 - 8 7 5 3 1 6 4 2 0
240 reg 31 - 24 23 22 21 20 19 18 17 16 */
241 unsigned int fpr_bitmap;
243 /* Number of floating point registers f8-f15 which must be saved. */
244 int high_fprs;
246 /* Set if return address needs to be saved. */
247 bool save_return_addr_p;
249 /* Set if backchain needs to be saved. */
250 bool save_backchain_p;
252 /* Size of stack frame. */
253 HOST_WIDE_INT frame_size;
256 /* Define the structure for the machine field in struct function. */
258 struct machine_function GTY(())
260 struct s390_frame_layout frame_layout;
262 /* Literal pool base register. */
263 rtx base_reg;
265 /* Some local-dynamic TLS symbol name. */
266 const char *some_ld_name;
269 /* Few accessor macros for struct cfun->machine->s390_frame_layout. */
271 #define cfun_frame_layout (cfun->machine->frame_layout)
272 #define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)
273 #define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr - \
274 cfun_frame_layout.first_save_gpr + 1) * UNITS_PER_WORD)
275 #define cfun_set_fpr_bit(BITNUM) (cfun->machine->frame_layout.fpr_bitmap |= \
276 (1 << (BITNUM)))
277 #define cfun_fpr_bit_p(BITNUM) (!!(cfun->machine->frame_layout.fpr_bitmap & \
278 (1 << (BITNUM))))
280 static int s390_match_ccmode_set (rtx, enum machine_mode);
281 static int s390_branch_condition_mask (rtx);
282 static const char *s390_branch_condition_mnemonic (rtx, int);
283 static int check_mode (rtx, enum machine_mode *);
284 static int general_s_operand (rtx, enum machine_mode, int);
285 static int s390_short_displacement (rtx);
286 static int s390_decompose_address (rtx, struct s390_address *);
287 static rtx get_thread_pointer (void);
288 static rtx legitimize_tls_address (rtx, rtx);
289 static void print_shift_count_operand (FILE *, rtx);
290 static const char *get_some_local_dynamic_name (void);
291 static int get_some_local_dynamic_name_1 (rtx *, void *);
292 static int reg_used_in_mem_p (int, rtx);
293 static int addr_generation_dependency_p (rtx, rtx);
294 static int s390_split_branches (void);
295 static void annotate_constant_pool_refs (rtx *x);
296 static void find_constant_pool_ref (rtx, rtx *);
297 static void replace_constant_pool_ref (rtx *, rtx, rtx);
298 static rtx find_ltrel_base (rtx);
299 static void replace_ltrel_base (rtx *);
300 static void s390_optimize_prologue (bool);
301 static int find_unused_clobbered_reg (void);
302 static void s390_frame_area (int *, int *);
303 static void s390_register_info (int, int);
304 static void s390_frame_info (int, int);
305 static rtx save_fpr (rtx, int, int);
306 static rtx restore_fpr (rtx, int, int);
307 static rtx save_gprs (rtx, int, int, int);
308 static rtx restore_gprs (rtx, int, int, int);
309 static int s390_function_arg_size (enum machine_mode, tree);
310 static bool s390_function_arg_float (enum machine_mode, tree);
311 static struct machine_function * s390_init_machine_status (void);
313 /* Check whether integer displacement is in range. */
314 #define DISP_IN_RANGE(d) \
315 (TARGET_LONG_DISPLACEMENT? ((d) >= -524288 && (d) <= 524287) \
316 : ((d) >= 0 && (d) <= 4095))
318 /* Return true if SET either doesn't set the CC register, or else
319 the source and destination have matching CC modes and that
320 CC mode is at least as constrained as REQ_MODE. */
322 static int
323 s390_match_ccmode_set (rtx set, enum machine_mode req_mode)
325 enum machine_mode set_mode;
327 if (GET_CODE (set) != SET)
328 abort ();
330 if (GET_CODE (SET_DEST (set)) != REG || !CC_REGNO_P (REGNO (SET_DEST (set))))
331 return 1;
333 set_mode = GET_MODE (SET_DEST (set));
334 switch (set_mode)
336 case CCSmode:
337 case CCSRmode:
338 case CCUmode:
339 case CCURmode:
340 case CCLmode:
341 case CCL1mode:
342 case CCL2mode:
343 case CCL3mode:
344 case CCT1mode:
345 case CCT2mode:
346 case CCT3mode:
347 if (req_mode != set_mode)
348 return 0;
349 break;
351 case CCZmode:
352 if (req_mode != CCSmode && req_mode != CCUmode && req_mode != CCTmode
353 && req_mode != CCSRmode && req_mode != CCURmode)
354 return 0;
355 break;
357 case CCAPmode:
358 case CCANmode:
359 if (req_mode != CCAmode)
360 return 0;
361 break;
363 default:
364 abort ();
367 return (GET_MODE (SET_SRC (set)) == set_mode);
370 /* Return true if every SET in INSN that sets the CC register
371 has source and destination with matching CC modes and that
372 CC mode is at least as constrained as REQ_MODE.
373 If REQ_MODE is VOIDmode, always return false. */
376 s390_match_ccmode (rtx insn, enum machine_mode req_mode)
378 int i;
380 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
381 if (req_mode == VOIDmode)
382 return 0;
384 if (GET_CODE (PATTERN (insn)) == SET)
385 return s390_match_ccmode_set (PATTERN (insn), req_mode);
387 if (GET_CODE (PATTERN (insn)) == PARALLEL)
388 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
390 rtx set = XVECEXP (PATTERN (insn), 0, i);
391 if (GET_CODE (set) == SET)
392 if (!s390_match_ccmode_set (set, req_mode))
393 return 0;
396 return 1;
399 /* If a test-under-mask instruction can be used to implement
400 (compare (and ... OP1) OP2), return the CC mode required
401 to do that. Otherwise, return VOIDmode.
402 MIXED is true if the instruction can distinguish between
403 CC1 and CC2 for mixed selected bits (TMxx), it is false
404 if the instruction cannot (TM). */
406 enum machine_mode
407 s390_tm_ccmode (rtx op1, rtx op2, int mixed)
409 int bit0, bit1;
411 /* ??? Fixme: should work on CONST_DOUBLE as well. */
412 if (GET_CODE (op1) != CONST_INT || GET_CODE (op2) != CONST_INT)
413 return VOIDmode;
415 /* Selected bits all zero: CC0. */
416 if (INTVAL (op2) == 0)
417 return CCTmode;
419 /* Selected bits all one: CC3. */
420 if (INTVAL (op2) == INTVAL (op1))
421 return CCT3mode;
423 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. */
424 if (mixed)
426 bit1 = exact_log2 (INTVAL (op2));
427 bit0 = exact_log2 (INTVAL (op1) ^ INTVAL (op2));
428 if (bit0 != -1 && bit1 != -1)
429 return bit0 > bit1 ? CCT1mode : CCT2mode;
432 return VOIDmode;
435 /* Given a comparison code OP (EQ, NE, etc.) and the operands
436 OP0 and OP1 of a COMPARE, return the mode to be used for the
437 comparison. */
439 enum machine_mode
440 s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
442 switch (code)
444 case EQ:
445 case NE:
446 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
447 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0, 1)), 'K', "K"))
448 return CCAPmode;
449 if ((GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
450 || GET_CODE (op1) == NEG)
451 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
452 return CCLmode;
454 if (GET_CODE (op0) == AND)
456 /* Check whether we can potentially do it via TM. */
457 enum machine_mode ccmode;
458 ccmode = s390_tm_ccmode (XEXP (op0, 1), op1, 1);
459 if (ccmode != VOIDmode)
461 /* Relax CCTmode to CCZmode to allow fall-back to AND
462 if that turns out to be beneficial. */
463 return ccmode == CCTmode ? CCZmode : ccmode;
467 if (register_operand (op0, HImode)
468 && GET_CODE (op1) == CONST_INT
469 && (INTVAL (op1) == -1 || INTVAL (op1) == 65535))
470 return CCT3mode;
471 if (register_operand (op0, QImode)
472 && GET_CODE (op1) == CONST_INT
473 && (INTVAL (op1) == -1 || INTVAL (op1) == 255))
474 return CCT3mode;
476 return CCZmode;
478 case LE:
479 case LT:
480 case GE:
481 case GT:
482 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
483 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0, 1)), 'K', "K"))
485 if (INTVAL (XEXP((op0), 1)) < 0)
486 return CCANmode;
487 else
488 return CCAPmode;
490 case UNORDERED:
491 case ORDERED:
492 case UNEQ:
493 case UNLE:
494 case UNLT:
495 case UNGE:
496 case UNGT:
497 case LTGT:
498 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
499 && GET_CODE (op1) != CONST_INT)
500 return CCSRmode;
501 return CCSmode;
503 case LTU:
504 case GEU:
505 if (GET_CODE (op0) == PLUS
506 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
507 return CCL1mode;
509 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
510 && GET_CODE (op1) != CONST_INT)
511 return CCURmode;
512 return CCUmode;
514 case LEU:
515 case GTU:
516 if (GET_CODE (op0) == MINUS
517 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
518 return CCL2mode;
520 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
521 && GET_CODE (op1) != CONST_INT)
522 return CCURmode;
523 return CCUmode;
525 default:
526 abort ();
530 /* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
531 that we can implement more efficiently. */
533 void
534 s390_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
536 /* Convert ZERO_EXTRACT back to AND to enable TM patterns. */
537 if ((*code == EQ || *code == NE)
538 && *op1 == const0_rtx
539 && GET_CODE (*op0) == ZERO_EXTRACT
540 && GET_CODE (XEXP (*op0, 1)) == CONST_INT
541 && GET_CODE (XEXP (*op0, 2)) == CONST_INT
542 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0, 0))))
544 rtx inner = XEXP (*op0, 0);
545 HOST_WIDE_INT modesize = GET_MODE_BITSIZE (GET_MODE (inner));
546 HOST_WIDE_INT len = INTVAL (XEXP (*op0, 1));
547 HOST_WIDE_INT pos = INTVAL (XEXP (*op0, 2));
549 if (len > 0 && len < modesize
550 && pos >= 0 && pos + len <= modesize
551 && modesize <= HOST_BITS_PER_WIDE_INT)
553 unsigned HOST_WIDE_INT block;
554 block = ((unsigned HOST_WIDE_INT) 1 << len) - 1;
555 block <<= modesize - pos - len;
557 *op0 = gen_rtx_AND (GET_MODE (inner), inner,
558 gen_int_mode (block, GET_MODE (inner)));
562 /* Narrow AND of memory against immediate to enable TM. */
563 if ((*code == EQ || *code == NE)
564 && *op1 == const0_rtx
565 && GET_CODE (*op0) == AND
566 && GET_CODE (XEXP (*op0, 1)) == CONST_INT
567 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0, 0))))
569 rtx inner = XEXP (*op0, 0);
570 rtx mask = XEXP (*op0, 1);
572 /* Ignore paradoxical SUBREGs if all extra bits are masked out. */
573 if (GET_CODE (inner) == SUBREG
574 && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (inner)))
575 && (GET_MODE_SIZE (GET_MODE (inner))
576 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner))))
577 && ((INTVAL (mask)
578 & GET_MODE_MASK (GET_MODE (inner))
579 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (inner))))
580 == 0))
581 inner = SUBREG_REG (inner);
583 /* Do not change volatile MEMs. */
584 if (MEM_P (inner) && !MEM_VOLATILE_P (inner))
586 int part = s390_single_part (XEXP (*op0, 1),
587 GET_MODE (inner), QImode, 0);
588 if (part >= 0)
590 mask = gen_int_mode (s390_extract_part (mask, QImode, 0), QImode);
591 inner = adjust_address_nv (inner, QImode, part);
592 *op0 = gen_rtx_AND (QImode, inner, mask);
597 /* Narrow comparisons against 0xffff to HImode if possible. */
599 if ((*code == EQ || *code == NE)
600 && GET_CODE (*op1) == CONST_INT
601 && INTVAL (*op1) == 0xffff
602 && SCALAR_INT_MODE_P (GET_MODE (*op0))
603 && (nonzero_bits (*op0, GET_MODE (*op0))
604 & ~(unsigned HOST_WIDE_INT) 0xffff) == 0)
606 *op0 = gen_lowpart (HImode, *op0);
607 *op1 = constm1_rtx;
611 /* Emit a compare instruction suitable to implement the comparison
612 OP0 CODE OP1. Return the correct condition RTL to be placed in
613 the IF_THEN_ELSE of the conditional branch testing the result. */
616 s390_emit_compare (enum rtx_code code, rtx op0, rtx op1)
618 enum machine_mode mode = s390_select_ccmode (code, op0, op1);
619 rtx cc = gen_rtx_REG (mode, CC_REGNUM);
621 emit_insn (gen_rtx_SET (VOIDmode, cc, gen_rtx_COMPARE (mode, op0, op1)));
622 return gen_rtx_fmt_ee (code, VOIDmode, cc, const0_rtx);
625 /* Emit a jump instruction to TARGET. If COND is NULL_RTX, emit an
626 unconditional jump, else a conditional jump under condition COND. */
628 void
629 s390_emit_jump (rtx target, rtx cond)
631 rtx insn;
633 target = gen_rtx_LABEL_REF (VOIDmode, target);
634 if (cond)
635 target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, target, pc_rtx);
637 insn = gen_rtx_SET (VOIDmode, pc_rtx, target);
638 emit_jump_insn (insn);
641 /* Return nonzero if OP is a valid comparison operator
642 for an ALC condition in mode MODE. */
645 s390_alc_comparison (rtx op, enum machine_mode mode)
647 if (mode != VOIDmode && mode != GET_MODE (op))
648 return 0;
650 while (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND)
651 op = XEXP (op, 0);
653 if (!COMPARISON_P (op))
654 return 0;
656 if (GET_CODE (XEXP (op, 0)) != REG
657 || REGNO (XEXP (op, 0)) != CC_REGNUM
658 || XEXP (op, 1) != const0_rtx)
659 return 0;
661 switch (GET_MODE (XEXP (op, 0)))
663 case CCL1mode:
664 return GET_CODE (op) == LTU;
666 case CCL2mode:
667 return GET_CODE (op) == LEU;
669 case CCL3mode:
670 return GET_CODE (op) == GEU;
672 case CCUmode:
673 return GET_CODE (op) == GTU;
675 case CCURmode:
676 return GET_CODE (op) == LTU;
678 case CCSmode:
679 return GET_CODE (op) == UNGT;
681 case CCSRmode:
682 return GET_CODE (op) == UNLT;
684 default:
685 return 0;
689 /* Return nonzero if OP is a valid comparison operator
690 for an SLB condition in mode MODE. */
693 s390_slb_comparison (rtx op, enum machine_mode mode)
695 if (mode != VOIDmode && mode != GET_MODE (op))
696 return 0;
698 while (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND)
699 op = XEXP (op, 0);
701 if (!COMPARISON_P (op))
702 return 0;
704 if (GET_CODE (XEXP (op, 0)) != REG
705 || REGNO (XEXP (op, 0)) != CC_REGNUM
706 || XEXP (op, 1) != const0_rtx)
707 return 0;
709 switch (GET_MODE (XEXP (op, 0)))
711 case CCL1mode:
712 return GET_CODE (op) == GEU;
714 case CCL2mode:
715 return GET_CODE (op) == GTU;
717 case CCL3mode:
718 return GET_CODE (op) == LTU;
720 case CCUmode:
721 return GET_CODE (op) == LEU;
723 case CCURmode:
724 return GET_CODE (op) == GEU;
726 case CCSmode:
727 return GET_CODE (op) == LE;
729 case CCSRmode:
730 return GET_CODE (op) == GE;
732 default:
733 return 0;
737 /* Return branch condition mask to implement a branch
738 specified by CODE. */
740 static int
741 s390_branch_condition_mask (rtx code)
743 const int CC0 = 1 << 3;
744 const int CC1 = 1 << 2;
745 const int CC2 = 1 << 1;
746 const int CC3 = 1 << 0;
748 if (GET_CODE (XEXP (code, 0)) != REG
749 || REGNO (XEXP (code, 0)) != CC_REGNUM
750 || XEXP (code, 1) != const0_rtx)
751 abort ();
753 switch (GET_MODE (XEXP (code, 0)))
755 case CCZmode:
756 switch (GET_CODE (code))
758 case EQ: return CC0;
759 case NE: return CC1 | CC2 | CC3;
760 default:
761 abort ();
763 break;
765 case CCT1mode:
766 switch (GET_CODE (code))
768 case EQ: return CC1;
769 case NE: return CC0 | CC2 | CC3;
770 default:
771 abort ();
773 break;
775 case CCT2mode:
776 switch (GET_CODE (code))
778 case EQ: return CC2;
779 case NE: return CC0 | CC1 | CC3;
780 default:
781 abort ();
783 break;
785 case CCT3mode:
786 switch (GET_CODE (code))
788 case EQ: return CC3;
789 case NE: return CC0 | CC1 | CC2;
790 default:
791 abort ();
793 break;
795 case CCLmode:
796 switch (GET_CODE (code))
798 case EQ: return CC0 | CC2;
799 case NE: return CC1 | CC3;
800 default:
801 abort ();
803 break;
805 case CCL1mode:
806 switch (GET_CODE (code))
808 case LTU: return CC2 | CC3; /* carry */
809 case GEU: return CC0 | CC1; /* no carry */
810 default:
811 abort ();
813 break;
815 case CCL2mode:
816 switch (GET_CODE (code))
818 case GTU: return CC0 | CC1; /* borrow */
819 case LEU: return CC2 | CC3; /* no borrow */
820 default:
821 abort ();
823 break;
825 case CCL3mode:
826 switch (GET_CODE (code))
828 case EQ: return CC0 | CC2;
829 case NE: return CC1 | CC3;
830 case LTU: return CC1;
831 case GTU: return CC3;
832 case LEU: return CC1 | CC2;
833 case GEU: return CC2 | CC3;
834 default:
835 abort ();
838 case CCUmode:
839 switch (GET_CODE (code))
841 case EQ: return CC0;
842 case NE: return CC1 | CC2 | CC3;
843 case LTU: return CC1;
844 case GTU: return CC2;
845 case LEU: return CC0 | CC1;
846 case GEU: return CC0 | CC2;
847 default:
848 abort ();
850 break;
852 case CCURmode:
853 switch (GET_CODE (code))
855 case EQ: return CC0;
856 case NE: return CC2 | CC1 | CC3;
857 case LTU: return CC2;
858 case GTU: return CC1;
859 case LEU: return CC0 | CC2;
860 case GEU: return CC0 | CC1;
861 default:
862 abort ();
864 break;
866 case CCAPmode:
867 switch (GET_CODE (code))
869 case EQ: return CC0;
870 case NE: return CC1 | CC2 | CC3;
871 case LT: return CC1 | CC3;
872 case GT: return CC2;
873 case LE: return CC0 | CC1 | CC3;
874 case GE: return CC0 | CC2;
875 default:
876 abort ();
878 break;
880 case CCANmode:
881 switch (GET_CODE (code))
883 case EQ: return CC0;
884 case NE: return CC1 | CC2 | CC3;
885 case LT: return CC1;
886 case GT: return CC2 | CC3;
887 case LE: return CC0 | CC1;
888 case GE: return CC0 | CC2 | CC3;
889 default:
890 abort ();
892 break;
894 case CCSmode:
895 switch (GET_CODE (code))
897 case EQ: return CC0;
898 case NE: return CC1 | CC2 | CC3;
899 case LT: return CC1;
900 case GT: return CC2;
901 case LE: return CC0 | CC1;
902 case GE: return CC0 | CC2;
903 case UNORDERED: return CC3;
904 case ORDERED: return CC0 | CC1 | CC2;
905 case UNEQ: return CC0 | CC3;
906 case UNLT: return CC1 | CC3;
907 case UNGT: return CC2 | CC3;
908 case UNLE: return CC0 | CC1 | CC3;
909 case UNGE: return CC0 | CC2 | CC3;
910 case LTGT: return CC1 | CC2;
911 default:
912 abort ();
914 break;
916 case CCSRmode:
917 switch (GET_CODE (code))
919 case EQ: return CC0;
920 case NE: return CC2 | CC1 | CC3;
921 case LT: return CC2;
922 case GT: return CC1;
923 case LE: return CC0 | CC2;
924 case GE: return CC0 | CC1;
925 case UNORDERED: return CC3;
926 case ORDERED: return CC0 | CC2 | CC1;
927 case UNEQ: return CC0 | CC3;
928 case UNLT: return CC2 | CC3;
929 case UNGT: return CC1 | CC3;
930 case UNLE: return CC0 | CC2 | CC3;
931 case UNGE: return CC0 | CC1 | CC3;
932 case LTGT: return CC2 | CC1;
933 default:
934 abort ();
936 break;
938 default:
939 abort ();
943 /* If INV is false, return assembler mnemonic string to implement
944 a branch specified by CODE. If INV is true, return mnemonic
945 for the corresponding inverted branch. */
947 static const char *
948 s390_branch_condition_mnemonic (rtx code, int inv)
950 static const char *const mnemonic[16] =
952 NULL, "o", "h", "nle",
953 "l", "nhe", "lh", "ne",
954 "e", "nlh", "he", "nl",
955 "le", "nh", "no", NULL
958 int mask = s390_branch_condition_mask (code);
960 if (inv)
961 mask ^= 15;
963 if (mask < 1 || mask > 14)
964 abort ();
966 return mnemonic[mask];
969 /* Return the part of op which has a value different from def.
970 The size of the part is determined by mode.
971 Use this function only if you already know that op really
972 contains such a part. */
974 unsigned HOST_WIDE_INT
975 s390_extract_part (rtx op, enum machine_mode mode, int def)
977 unsigned HOST_WIDE_INT value = 0;
978 int max_parts = HOST_BITS_PER_WIDE_INT / GET_MODE_BITSIZE (mode);
979 int part_bits = GET_MODE_BITSIZE (mode);
980 unsigned HOST_WIDE_INT part_mask = (1 << part_bits) - 1;
981 int i;
983 for (i = 0; i < max_parts; i++)
985 if (i == 0)
986 value = (unsigned HOST_WIDE_INT) INTVAL (op);
987 else
988 value >>= part_bits;
990 if ((value & part_mask) != (def & part_mask))
991 return value & part_mask;
994 abort ();
997 /* If OP is an integer constant of mode MODE with exactly one
998 part of mode PART_MODE unequal to DEF, return the number of that
999 part. Otherwise, return -1. */
1002 s390_single_part (rtx op,
1003 enum machine_mode mode,
1004 enum machine_mode part_mode,
1005 int def)
1007 unsigned HOST_WIDE_INT value = 0;
1008 int n_parts = GET_MODE_SIZE (mode) / GET_MODE_SIZE (part_mode);
1009 unsigned HOST_WIDE_INT part_mask = (1 << GET_MODE_BITSIZE (part_mode)) - 1;
1010 int i, part = -1;
1012 if (GET_CODE (op) != CONST_INT)
1013 return -1;
1015 for (i = 0; i < n_parts; i++)
1017 if (i == 0)
1018 value = (unsigned HOST_WIDE_INT) INTVAL (op);
1019 else
1020 value >>= GET_MODE_BITSIZE (part_mode);
1022 if ((value & part_mask) != (def & part_mask))
1024 if (part != -1)
1025 return -1;
1026 else
1027 part = i;
1030 return part == -1 ? -1 : n_parts - 1 - part;
1033 /* Check whether we can (and want to) split a double-word
1034 move in mode MODE from SRC to DST into two single-word
1035 moves, moving the subword FIRST_SUBWORD first. */
1037 bool
1038 s390_split_ok_p (rtx dst, rtx src, enum machine_mode mode, int first_subword)
1040 /* Floating point registers cannot be split. */
1041 if (FP_REG_P (src) || FP_REG_P (dst))
1042 return false;
1044 /* We don't need to split if operands are directly accessible. */
1045 if (s_operand (src, mode) || s_operand (dst, mode))
1046 return false;
1048 /* Non-offsettable memory references cannot be split. */
1049 if ((GET_CODE (src) == MEM && !offsettable_memref_p (src))
1050 || (GET_CODE (dst) == MEM && !offsettable_memref_p (dst)))
1051 return false;
1053 /* Moving the first subword must not clobber a register
1054 needed to move the second subword. */
1055 if (register_operand (dst, mode))
1057 rtx subreg = operand_subword (dst, first_subword, 0, mode);
1058 if (reg_overlap_mentioned_p (subreg, src))
1059 return false;
1062 return true;
1066 /* Change optimizations to be performed, depending on the
1067 optimization level.
1069 LEVEL is the optimization level specified; 2 if `-O2' is
1070 specified, 1 if `-O' is specified, and 0 if neither is specified.
1072 SIZE is nonzero if `-Os' is specified and zero otherwise. */
1074 void
1075 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
1077 /* ??? There are apparently still problems with -fcaller-saves. */
1078 flag_caller_saves = 0;
1080 /* By default, always emit DWARF-2 unwind info. This allows debugging
1081 without maintaining a stack frame back-chain. */
1082 flag_asynchronous_unwind_tables = 1;
1085 void
1086 override_options (void)
1088 int i;
1089 static struct pta
1091 const char *const name; /* processor name or nickname. */
1092 const enum processor_type processor;
1093 const enum processor_flags flags;
1095 const processor_alias_table[] =
1097 {"g5", PROCESSOR_9672_G5, PF_IEEE_FLOAT},
1098 {"g6", PROCESSOR_9672_G6, PF_IEEE_FLOAT},
1099 {"z900", PROCESSOR_2064_Z900, PF_IEEE_FLOAT | PF_ZARCH},
1100 {"z990", PROCESSOR_2084_Z990, PF_IEEE_FLOAT | PF_ZARCH
1101 | PF_LONG_DISPLACEMENT},
1104 int const pta_size = ARRAY_SIZE (processor_alias_table);
1106 /* Acquire a unique set number for our register saves and restores. */
1107 s390_sr_alias_set = new_alias_set ();
1109 /* Set up function hooks. */
1110 init_machine_status = s390_init_machine_status;
1112 /* Architecture mode defaults according to ABI. */
1113 if (!(target_flags_explicit & MASK_ZARCH))
1115 if (TARGET_64BIT)
1116 target_flags |= MASK_ZARCH;
1117 else
1118 target_flags &= ~MASK_ZARCH;
1121 /* Determine processor architectural level. */
1122 if (!s390_arch_string)
1123 s390_arch_string = TARGET_ZARCH? "z900" : "g5";
1125 for (i = 0; i < pta_size; i++)
1126 if (! strcmp (s390_arch_string, processor_alias_table[i].name))
1128 s390_arch = processor_alias_table[i].processor;
1129 s390_arch_flags = processor_alias_table[i].flags;
1130 break;
1132 if (i == pta_size)
1133 error ("Unknown cpu used in -march=%s.", s390_arch_string);
1135 /* Determine processor to tune for. */
1136 if (!s390_tune_string)
1138 s390_tune = s390_arch;
1139 s390_tune_flags = s390_arch_flags;
1140 s390_tune_string = s390_arch_string;
1142 else
1144 for (i = 0; i < pta_size; i++)
1145 if (! strcmp (s390_tune_string, processor_alias_table[i].name))
1147 s390_tune = processor_alias_table[i].processor;
1148 s390_tune_flags = processor_alias_table[i].flags;
1149 break;
1151 if (i == pta_size)
1152 error ("Unknown cpu used in -mtune=%s.", s390_tune_string);
1155 /* Sanity checks. */
1156 if (TARGET_ZARCH && !(s390_arch_flags & PF_ZARCH))
1157 error ("z/Architecture mode not supported on %s.", s390_arch_string);
1158 if (TARGET_64BIT && !TARGET_ZARCH)
1159 error ("64-bit ABI not supported in ESA/390 mode.");
1161 if (s390_warn_framesize_string)
1163 if (sscanf (s390_warn_framesize_string, HOST_WIDE_INT_PRINT_DEC,
1164 &s390_warn_framesize) != 1)
1165 error ("invalid value for -mwarn-framesize");
1168 if (s390_warn_dynamicstack_string)
1169 s390_warn_dynamicstack_p = 1;
1171 if (s390_stack_size_string)
1173 if (sscanf (s390_stack_size_string, HOST_WIDE_INT_PRINT_DEC,
1174 &s390_stack_size) != 1)
1175 error ("invalid value for -mstack-size");
1177 if (exact_log2 (s390_stack_size) == -1)
1178 error ("stack size must be an exact power of 2");
1180 if (s390_stack_guard_string)
1182 if (sscanf (s390_stack_guard_string, HOST_WIDE_INT_PRINT_DEC,
1183 &s390_stack_guard) != 1)
1184 error ("invalid value for -mstack-guard");
1186 if (s390_stack_guard >= s390_stack_size)
1187 error ("stack size must be greater than the stack guard value");
1189 if (exact_log2 (s390_stack_guard) == -1)
1190 error ("stack guard value must be an exact power of 2");
1192 else
1193 error ("-mstack-size implies use of -mstack-guard");
1196 if (s390_stack_guard_string && !s390_stack_size_string)
1197 error ("-mstack-guard implies use of -mstack-size");
1200 /* Map for smallest class containing reg regno. */
1202 const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
1203 { GENERAL_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1204 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1205 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1206 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1207 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1208 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1209 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1210 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1211 ADDR_REGS, NO_REGS, ADDR_REGS, ADDR_REGS
1214 /* Return attribute type of insn. */
1216 static enum attr_type
1217 s390_safe_attr_type (rtx insn)
1219 if (recog_memoized (insn) >= 0)
1220 return get_attr_type (insn);
1221 else
1222 return TYPE_NONE;
1225 /* Return true if OP a (const_int 0) operand.
1226 OP is the current operation.
1227 MODE is the current operation mode. */
1230 const0_operand (register rtx op, enum machine_mode mode)
1232 return op == CONST0_RTX (mode);
1235 /* Return true if OP is constant.
1236 OP is the current operation.
1237 MODE is the current operation mode. */
1240 consttable_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1242 return CONSTANT_P (op);
1245 /* Return true if the mode of operand OP matches MODE.
1246 If MODE is set to VOIDmode, set it to the mode of OP. */
1248 static int
1249 check_mode (register rtx op, enum machine_mode *mode)
1251 if (*mode == VOIDmode)
1252 *mode = GET_MODE (op);
1253 else
1255 if (GET_MODE (op) != VOIDmode && GET_MODE (op) != *mode)
1256 return 0;
1258 return 1;
1261 /* Return true if OP a valid operand for the LARL instruction.
1262 OP is the current operation.
1263 MODE is the current operation mode. */
1266 larl_operand (register rtx op, enum machine_mode mode)
1268 if (! check_mode (op, &mode))
1269 return 0;
1271 /* Allow labels and local symbols. */
1272 if (GET_CODE (op) == LABEL_REF)
1273 return 1;
1274 if (GET_CODE (op) == SYMBOL_REF)
1275 return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0
1276 && SYMBOL_REF_TLS_MODEL (op) == 0
1277 && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
1279 /* Everything else must have a CONST, so strip it. */
1280 if (GET_CODE (op) != CONST)
1281 return 0;
1282 op = XEXP (op, 0);
1284 /* Allow adding *even* in-range constants. */
1285 if (GET_CODE (op) == PLUS)
1287 if (GET_CODE (XEXP (op, 1)) != CONST_INT
1288 || (INTVAL (XEXP (op, 1)) & 1) != 0)
1289 return 0;
1290 #if HOST_BITS_PER_WIDE_INT > 32
1291 if (INTVAL (XEXP (op, 1)) >= (HOST_WIDE_INT)1 << 32
1292 || INTVAL (XEXP (op, 1)) < -((HOST_WIDE_INT)1 << 32))
1293 return 0;
1294 #endif
1295 op = XEXP (op, 0);
1298 /* Labels and local symbols allowed here as well. */
1299 if (GET_CODE (op) == LABEL_REF)
1300 return 1;
1301 if (GET_CODE (op) == SYMBOL_REF)
1302 return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0
1303 && SYMBOL_REF_TLS_MODEL (op) == 0
1304 && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
1306 /* Now we must have a @GOTENT offset or @PLT stub
1307 or an @INDNTPOFF TLS offset. */
1308 if (GET_CODE (op) == UNSPEC
1309 && XINT (op, 1) == UNSPEC_GOTENT)
1310 return 1;
1311 if (GET_CODE (op) == UNSPEC
1312 && XINT (op, 1) == UNSPEC_PLT)
1313 return 1;
1314 if (GET_CODE (op) == UNSPEC
1315 && XINT (op, 1) == UNSPEC_INDNTPOFF)
1316 return 1;
1318 return 0;
1321 /* Helper routine to implement s_operand and s_imm_operand.
1322 OP is the current operation.
1323 MODE is the current operation mode.
1324 ALLOW_IMMEDIATE specifies whether immediate operands should
1325 be accepted or not. */
1327 static int
1328 general_s_operand (register rtx op, enum machine_mode mode,
1329 int allow_immediate)
1331 struct s390_address addr;
1333 /* Call general_operand first, so that we don't have to
1334 check for many special cases. */
1335 if (!general_operand (op, mode))
1336 return 0;
1338 /* Just like memory_operand, allow (subreg (mem ...))
1339 after reload. */
1340 if (reload_completed
1341 && GET_CODE (op) == SUBREG
1342 && GET_CODE (SUBREG_REG (op)) == MEM)
1343 op = SUBREG_REG (op);
1345 switch (GET_CODE (op))
1347 /* Constants are OK as s-operand if ALLOW_IMMEDIATE
1348 is true and we are still before reload. */
1349 case CONST_INT:
1350 case CONST_DOUBLE:
1351 if (!allow_immediate || reload_completed)
1352 return 0;
1353 return 1;
1355 /* Memory operands are OK unless they already use an
1356 index register. */
1357 case MEM:
1358 if (!s390_decompose_address (XEXP (op, 0), &addr))
1359 return 0;
1360 if (addr.indx)
1361 return 0;
1362 /* Do not allow literal pool references unless ALLOW_IMMEDIATE
1363 is true. This prevents compares between two literal pool
1364 entries from being accepted. */
1365 if (!allow_immediate
1366 && addr.base && REGNO (addr.base) == BASE_REGNUM)
1367 return 0;
1368 return 1;
1370 default:
1371 break;
1374 return 0;
1377 /* Return true if OP is a valid S-type operand.
1378 OP is the current operation.
1379 MODE is the current operation mode. */
1382 s_operand (register rtx op, enum machine_mode mode)
1384 return general_s_operand (op, mode, 0);
1387 /* Return true if OP is a valid S-type operand or an immediate
1388 operand that can be addressed as S-type operand by forcing
1389 it into the literal pool.
1390 OP is the current operation.
1391 MODE is the current operation mode. */
1394 s_imm_operand (register rtx op, enum machine_mode mode)
1396 return general_s_operand (op, mode, 1);
1399 /* Return true if OP a valid shift count operand.
1400 OP is the current operation.
1401 MODE is the current operation mode. */
1404 shift_count_operand (rtx op, enum machine_mode mode)
1406 HOST_WIDE_INT offset = 0;
1408 if (! check_mode (op, &mode))
1409 return 0;
1411 /* We can have an integer constant, an address register,
1412 or a sum of the two. Note that reload already checks
1413 that any register present is an address register, so
1414 we just check for any register here. */
1415 if (GET_CODE (op) == CONST_INT)
1417 offset = INTVAL (op);
1418 op = NULL_RTX;
1420 if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
1422 offset = INTVAL (XEXP (op, 1));
1423 op = XEXP (op, 0);
1425 while (op && GET_CODE (op) == SUBREG)
1426 op = SUBREG_REG (op);
1427 if (op && GET_CODE (op) != REG)
1428 return 0;
1430 /* Unfortunately we have to reject constants that are invalid
1431 for an address, or else reload will get confused. */
1432 if (!DISP_IN_RANGE (offset))
1433 return 0;
1435 return 1;
1438 /* Return true if DISP is a valid short displacement. */
1440 static int
1441 s390_short_displacement (rtx disp)
1443 /* No displacement is OK. */
1444 if (!disp)
1445 return 1;
1447 /* Integer displacement in range. */
1448 if (GET_CODE (disp) == CONST_INT)
1449 return INTVAL (disp) >= 0 && INTVAL (disp) < 4096;
1451 /* GOT offset is not OK, the GOT can be large. */
1452 if (GET_CODE (disp) == CONST
1453 && GET_CODE (XEXP (disp, 0)) == UNSPEC
1454 && XINT (XEXP (disp, 0), 1) == UNSPEC_GOT)
1455 return 0;
1457 /* All other symbolic constants are literal pool references,
1458 which are OK as the literal pool must be small. */
1459 if (GET_CODE (disp) == CONST)
1460 return 1;
1462 return 0;
1465 /* Return true if OP is a valid operand for a C constraint. */
1468 s390_extra_constraint_str (rtx op, int c, const char * str)
1470 struct s390_address addr;
1472 if (c != str[0])
1473 abort ();
1475 switch (c)
1477 case 'Q':
1478 if (GET_CODE (op) != MEM)
1479 return 0;
1480 if (!s390_decompose_address (XEXP (op, 0), &addr))
1481 return 0;
1482 if (addr.indx)
1483 return 0;
1485 if (TARGET_LONG_DISPLACEMENT)
1487 if (!s390_short_displacement (addr.disp))
1488 return 0;
1490 break;
1492 case 'R':
1493 if (GET_CODE (op) != MEM)
1494 return 0;
1496 if (TARGET_LONG_DISPLACEMENT)
1498 if (!s390_decompose_address (XEXP (op, 0), &addr))
1499 return 0;
1500 if (!s390_short_displacement (addr.disp))
1501 return 0;
1503 break;
1505 case 'S':
1506 if (!TARGET_LONG_DISPLACEMENT)
1507 return 0;
1508 if (GET_CODE (op) != MEM)
1509 return 0;
1510 if (!s390_decompose_address (XEXP (op, 0), &addr))
1511 return 0;
1512 if (addr.indx)
1513 return 0;
1514 if (s390_short_displacement (addr.disp))
1515 return 0;
1516 break;
1518 case 'T':
1519 if (!TARGET_LONG_DISPLACEMENT)
1520 return 0;
1521 if (GET_CODE (op) != MEM)
1522 return 0;
1523 /* Any invalid address here will be fixed up by reload,
1524 so accept it for the most generic constraint. */
1525 if (s390_decompose_address (XEXP (op, 0), &addr)
1526 && s390_short_displacement (addr.disp))
1527 return 0;
1528 break;
1530 case 'U':
1531 if (TARGET_LONG_DISPLACEMENT)
1533 if (!s390_decompose_address (op, &addr))
1534 return 0;
1535 if (!s390_short_displacement (addr.disp))
1536 return 0;
1538 break;
1540 case 'W':
1541 if (!TARGET_LONG_DISPLACEMENT)
1542 return 0;
1543 /* Any invalid address here will be fixed up by reload,
1544 so accept it for the most generic constraint. */
1545 if (s390_decompose_address (op, &addr)
1546 && s390_short_displacement (addr.disp))
1547 return 0;
1548 break;
1550 case 'Y':
1551 return shift_count_operand (op, VOIDmode);
1553 default:
1554 return 0;
1557 return 1;
1560 /* Return true if VALUE matches the constraint STR. */
1563 s390_const_ok_for_constraint_p (HOST_WIDE_INT value,
1564 int c,
1565 const char * str)
1567 enum machine_mode mode, part_mode;
1568 int def;
1569 unsigned char part;
1571 if (c != str[0])
1572 abort ();
1574 switch (str[0])
1576 case 'I':
1577 return (unsigned int)value < 256;
1579 case 'J':
1580 return (unsigned int)value < 4096;
1582 case 'K':
1583 return value >= -32768 && value < 32768;
1585 case 'L':
1586 return (TARGET_LONG_DISPLACEMENT ?
1587 (value >= -524288 && value <= 524287)
1588 : (value >= 0 && value <= 4095));
1589 case 'M':
1590 return value == 2147483647;
1592 case 'N':
1593 part = str[1] - '0';
1595 switch (str[2])
1597 case 'H': part_mode = HImode; break;
1598 case 'Q': part_mode = QImode; break;
1599 default: return 0;
1602 switch (str[3])
1604 case 'H': mode = HImode; break;
1605 case 'S': mode = SImode; break;
1606 case 'D': mode = DImode; break;
1607 default: return 0;
1610 switch (str[4])
1612 case '0': def = 0; break;
1613 case 'F': def = -1; break;
1614 default: return 0;
1617 if (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (part_mode))
1618 return 0;
1620 if (s390_single_part (GEN_INT (value), mode, part_mode, def) != part)
1621 return 0;
1623 break;
1625 default:
1626 return 0;
1629 return 1;
1632 /* Compute a (partial) cost for rtx X. Return true if the complete
1633 cost has been computed, and false if subexpressions should be
1634 scanned. In either case, *TOTAL contains the cost result. */
1636 static bool
1637 s390_rtx_costs (rtx x, int code, int outer_code, int *total)
1639 switch (code)
1641 case CONST:
1642 if (GET_CODE (XEXP (x, 0)) == MINUS
1643 && GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
1644 *total = 1000;
1645 else
1646 *total = 0;
1647 return true;
1649 case CONST_INT:
1650 /* Force_const_mem does not work out of reload, because the
1651 saveable_obstack is set to reload_obstack, which does not
1652 live long enough. Because of this we cannot use force_const_mem
1653 in addsi3. This leads to problems with gen_add2_insn with a
1654 constant greater than a short. Because of that we give an
1655 addition of greater constants a cost of 3 (reload1.c 10096). */
1656 /* ??? saveable_obstack no longer exists. */
1657 if (outer_code == PLUS
1658 && (INTVAL (x) > 32767 || INTVAL (x) < -32768))
1659 *total = COSTS_N_INSNS (3);
1660 else
1661 *total = 0;
1662 return true;
1664 case LABEL_REF:
1665 case SYMBOL_REF:
1666 case CONST_DOUBLE:
1667 *total = 0;
1668 return true;
1670 case ASHIFT:
1671 case ASHIFTRT:
1672 case LSHIFTRT:
1673 case PLUS:
1674 case AND:
1675 case IOR:
1676 case XOR:
1677 case MINUS:
1678 case NEG:
1679 case NOT:
1680 *total = COSTS_N_INSNS (1);
1681 return true;
1683 case MULT:
1684 if (GET_MODE (XEXP (x, 0)) == DImode)
1685 *total = COSTS_N_INSNS (40);
1686 else
1687 *total = COSTS_N_INSNS (7);
1688 return true;
1690 case DIV:
1691 case UDIV:
1692 case MOD:
1693 case UMOD:
1694 *total = COSTS_N_INSNS (33);
1695 return true;
1697 default:
1698 return false;
1702 /* Return the cost of an address rtx ADDR. */
1704 static int
1705 s390_address_cost (rtx addr)
1707 struct s390_address ad;
1708 if (!s390_decompose_address (addr, &ad))
1709 return 1000;
1711 return ad.indx? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
1714 /* Return true if OP is a valid operand for the BRAS instruction.
1715 OP is the current operation.
1716 MODE is the current operation mode. */
1719 bras_sym_operand (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1721 register enum rtx_code code = GET_CODE (op);
1723 /* Allow SYMBOL_REFs. */
1724 if (code == SYMBOL_REF)
1725 return 1;
1727 /* Allow @PLT stubs. */
1728 if (code == CONST
1729 && GET_CODE (XEXP (op, 0)) == UNSPEC
1730 && XINT (XEXP (op, 0), 1) == UNSPEC_PLT)
1731 return 1;
1732 return 0;
1735 /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
1736 otherwise return 0. */
1739 tls_symbolic_operand (register rtx op)
1741 if (GET_CODE (op) != SYMBOL_REF)
1742 return 0;
1743 return SYMBOL_REF_TLS_MODEL (op);
1746 /* Return true if OP is a load multiple operation. It is known to be a
1747 PARALLEL and the first section will be tested.
1748 OP is the current operation.
1749 MODE is the current operation mode. */
1752 load_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1754 enum machine_mode elt_mode;
1755 int count = XVECLEN (op, 0);
1756 unsigned int dest_regno;
1757 rtx src_addr;
1758 int i, off;
1761 /* Perform a quick check so we don't blow up below. */
1762 if (count <= 1
1763 || GET_CODE (XVECEXP (op, 0, 0)) != SET
1764 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
1765 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
1766 return 0;
1768 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
1769 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
1770 elt_mode = GET_MODE (SET_DEST (XVECEXP (op, 0, 0)));
1772 /* Check, is base, or base + displacement. */
1774 if (GET_CODE (src_addr) == REG)
1775 off = 0;
1776 else if (GET_CODE (src_addr) == PLUS
1777 && GET_CODE (XEXP (src_addr, 0)) == REG
1778 && GET_CODE (XEXP (src_addr, 1)) == CONST_INT)
1780 off = INTVAL (XEXP (src_addr, 1));
1781 src_addr = XEXP (src_addr, 0);
1783 else
1784 return 0;
1786 for (i = 1; i < count; i++)
1788 rtx elt = XVECEXP (op, 0, i);
1790 if (GET_CODE (elt) != SET
1791 || GET_CODE (SET_DEST (elt)) != REG
1792 || GET_MODE (SET_DEST (elt)) != elt_mode
1793 || REGNO (SET_DEST (elt)) != dest_regno + i
1794 || GET_CODE (SET_SRC (elt)) != MEM
1795 || GET_MODE (SET_SRC (elt)) != elt_mode
1796 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
1797 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
1798 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
1799 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1))
1800 != off + i * GET_MODE_SIZE (elt_mode))
1801 return 0;
1804 return 1;
1807 /* Return true if OP is a store multiple operation. It is known to be a
1808 PARALLEL and the first section will be tested.
1809 OP is the current operation.
1810 MODE is the current operation mode. */
1813 store_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1815 enum machine_mode elt_mode;
1816 int count = XVECLEN (op, 0);
1817 unsigned int src_regno;
1818 rtx dest_addr;
1819 int i, off;
1821 /* Perform a quick check so we don't blow up below. */
1822 if (count <= 1
1823 || GET_CODE (XVECEXP (op, 0, 0)) != SET
1824 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
1825 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
1826 return 0;
1828 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
1829 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
1830 elt_mode = GET_MODE (SET_SRC (XVECEXP (op, 0, 0)));
1832 /* Check, is base, or base + displacement. */
1834 if (GET_CODE (dest_addr) == REG)
1835 off = 0;
1836 else if (GET_CODE (dest_addr) == PLUS
1837 && GET_CODE (XEXP (dest_addr, 0)) == REG
1838 && GET_CODE (XEXP (dest_addr, 1)) == CONST_INT)
1840 off = INTVAL (XEXP (dest_addr, 1));
1841 dest_addr = XEXP (dest_addr, 0);
1843 else
1844 return 0;
1846 for (i = 1; i < count; i++)
1848 rtx elt = XVECEXP (op, 0, i);
1850 if (GET_CODE (elt) != SET
1851 || GET_CODE (SET_SRC (elt)) != REG
1852 || GET_MODE (SET_SRC (elt)) != elt_mode
1853 || REGNO (SET_SRC (elt)) != src_regno + i
1854 || GET_CODE (SET_DEST (elt)) != MEM
1855 || GET_MODE (SET_DEST (elt)) != elt_mode
1856 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
1857 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
1858 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
1859 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1))
1860 != off + i * GET_MODE_SIZE (elt_mode))
1861 return 0;
1863 return 1;
1867 /* Return true if OP contains a symbol reference */
1870 symbolic_reference_mentioned_p (rtx op)
1872 register const char *fmt;
1873 register int i;
1875 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
1876 return 1;
1878 fmt = GET_RTX_FORMAT (GET_CODE (op));
1879 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
1881 if (fmt[i] == 'E')
1883 register int j;
1885 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
1886 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
1887 return 1;
1890 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
1891 return 1;
1894 return 0;
1897 /* Return true if OP contains a reference to a thread-local symbol. */
1900 tls_symbolic_reference_mentioned_p (rtx op)
1902 register const char *fmt;
1903 register int i;
1905 if (GET_CODE (op) == SYMBOL_REF)
1906 return tls_symbolic_operand (op);
1908 fmt = GET_RTX_FORMAT (GET_CODE (op));
1909 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
1911 if (fmt[i] == 'E')
1913 register int j;
1915 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
1916 if (tls_symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
1917 return 1;
1920 else if (fmt[i] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op, i)))
1921 return 1;
1924 return 0;
1928 /* Return true if OP is a legitimate general operand when
1929 generating PIC code. It is given that flag_pic is on
1930 and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
1933 legitimate_pic_operand_p (register rtx op)
1935 /* Accept all non-symbolic constants. */
1936 if (!SYMBOLIC_CONST (op))
1937 return 1;
1939 /* Reject everything else; must be handled
1940 via emit_symbolic_move. */
1941 return 0;
1944 /* Returns true if the constant value OP is a legitimate general operand.
1945 It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
1948 legitimate_constant_p (register rtx op)
1950 /* Accept all non-symbolic constants. */
1951 if (!SYMBOLIC_CONST (op))
1952 return 1;
1954 /* Accept immediate LARL operands. */
1955 if (TARGET_CPU_ZARCH && larl_operand (op, VOIDmode))
1956 return 1;
1958 /* Thread-local symbols are never legal constants. This is
1959 so that emit_call knows that computing such addresses
1960 might require a function call. */
1961 if (TLS_SYMBOLIC_CONST (op))
1962 return 0;
1964 /* In the PIC case, symbolic constants must *not* be
1965 forced into the literal pool. We accept them here,
1966 so that they will be handled by emit_symbolic_move. */
1967 if (flag_pic)
1968 return 1;
1970 /* All remaining non-PIC symbolic constants are
1971 forced into the literal pool. */
1972 return 0;
1975 /* Determine if it's legal to put X into the constant pool. This
1976 is not possible if X contains the address of a symbol that is
1977 not constant (TLS) or not known at final link time (PIC). */
1979 static bool
1980 s390_cannot_force_const_mem (rtx x)
1982 switch (GET_CODE (x))
1984 case CONST_INT:
1985 case CONST_DOUBLE:
1986 /* Accept all non-symbolic constants. */
1987 return false;
1989 case LABEL_REF:
1990 /* Labels are OK iff we are non-PIC. */
1991 return flag_pic != 0;
1993 case SYMBOL_REF:
1994 /* 'Naked' TLS symbol references are never OK,
1995 non-TLS symbols are OK iff we are non-PIC. */
1996 if (tls_symbolic_operand (x))
1997 return true;
1998 else
1999 return flag_pic != 0;
2001 case CONST:
2002 return s390_cannot_force_const_mem (XEXP (x, 0));
2003 case PLUS:
2004 case MINUS:
2005 return s390_cannot_force_const_mem (XEXP (x, 0))
2006 || s390_cannot_force_const_mem (XEXP (x, 1));
2008 case UNSPEC:
2009 switch (XINT (x, 1))
2011 /* Only lt-relative or GOT-relative UNSPECs are OK. */
2012 case UNSPEC_LTREL_OFFSET:
2013 case UNSPEC_GOT:
2014 case UNSPEC_GOTOFF:
2015 case UNSPEC_PLTOFF:
2016 case UNSPEC_TLSGD:
2017 case UNSPEC_TLSLDM:
2018 case UNSPEC_NTPOFF:
2019 case UNSPEC_DTPOFF:
2020 case UNSPEC_GOTNTPOFF:
2021 case UNSPEC_INDNTPOFF:
2022 return false;
2024 default:
2025 return true;
2027 break;
2029 default:
2030 abort ();
2034 /* Returns true if the constant value OP is a legitimate general
2035 operand during and after reload. The difference to
2036 legitimate_constant_p is that this function will not accept
2037 a constant that would need to be forced to the literal pool
2038 before it can be used as operand. */
2041 legitimate_reload_constant_p (register rtx op)
2043 /* Accept la(y) operands. */
2044 if (GET_CODE (op) == CONST_INT
2045 && DISP_IN_RANGE (INTVAL (op)))
2046 return 1;
2048 /* Accept l(g)hi operands. */
2049 if (GET_CODE (op) == CONST_INT
2050 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'K', "K"))
2051 return 1;
2053 /* Accept lliXX operands. */
2054 if (TARGET_ZARCH
2055 && s390_single_part (op, DImode, HImode, 0) >= 0)
2056 return 1;
2058 /* Accept larl operands. */
2059 if (TARGET_CPU_ZARCH
2060 && larl_operand (op, VOIDmode))
2061 return 1;
2063 /* Everything else cannot be handled without reload. */
2064 return 0;
2067 /* Given an rtx OP being reloaded into a reg required to be in class CLASS,
2068 return the class of reg to actually use. */
2070 enum reg_class
2071 s390_preferred_reload_class (rtx op, enum reg_class class)
2073 /* This can happen if a floating point constant is being
2074 reloaded into an integer register. Leave well alone. */
2075 if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT
2076 && class != FP_REGS)
2077 return class;
2079 switch (GET_CODE (op))
2081 /* Constants we cannot reload must be forced into the
2082 literal pool. */
2084 case CONST_DOUBLE:
2085 case CONST_INT:
2086 if (legitimate_reload_constant_p (op))
2087 return class;
2088 else
2089 return NO_REGS;
2091 /* If a symbolic constant or a PLUS is reloaded,
2092 it is most likely being used as an address, so
2093 prefer ADDR_REGS. If 'class' is not a superset
2094 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
2095 case PLUS:
2096 case LABEL_REF:
2097 case SYMBOL_REF:
2098 case CONST:
2099 if (reg_class_subset_p (ADDR_REGS, class))
2100 return ADDR_REGS;
2101 else
2102 return NO_REGS;
2104 default:
2105 break;
2108 return class;
2111 /* Return the register class of a scratch register needed to
2112 load IN into a register of class CLASS in MODE.
2114 We need a temporary when loading a PLUS expression which
2115 is not a legitimate operand of the LOAD ADDRESS instruction. */
2117 enum reg_class
2118 s390_secondary_input_reload_class (enum reg_class class ATTRIBUTE_UNUSED,
2119 enum machine_mode mode, rtx in)
2121 if (s390_plus_operand (in, mode))
2122 return ADDR_REGS;
2124 return NO_REGS;
2127 /* Return the register class of a scratch register needed to
2128 store a register of class CLASS in MODE into OUT:
2130 We need a temporary when storing a double-word to a
2131 non-offsettable memory address. */
2133 enum reg_class
2134 s390_secondary_output_reload_class (enum reg_class class,
2135 enum machine_mode mode, rtx out)
2137 if ((TARGET_64BIT ? mode == TImode
2138 : (mode == DImode || mode == DFmode))
2139 && reg_classes_intersect_p (GENERAL_REGS, class)
2140 && GET_CODE (out) == MEM
2141 && !offsettable_memref_p (out)
2142 && !s_operand (out, VOIDmode))
2143 return ADDR_REGS;
2145 return NO_REGS;
2148 /* Return true if OP is a PLUS that is not a legitimate
2149 operand for the LA instruction.
2150 OP is the current operation.
2151 MODE is the current operation mode. */
2154 s390_plus_operand (register rtx op, enum machine_mode mode)
2156 if (!check_mode (op, &mode) || mode != Pmode)
2157 return FALSE;
2159 if (GET_CODE (op) != PLUS)
2160 return FALSE;
2162 if (legitimate_la_operand_p (op))
2163 return FALSE;
2165 return TRUE;
2168 /* Generate code to load SRC, which is PLUS that is not a
2169 legitimate operand for the LA instruction, into TARGET.
2170 SCRATCH may be used as scratch register. */
2172 void
2173 s390_expand_plus_operand (register rtx target, register rtx src,
2174 register rtx scratch)
2176 rtx sum1, sum2;
2177 struct s390_address ad;
2179 /* src must be a PLUS; get its two operands. */
2180 if (GET_CODE (src) != PLUS || GET_MODE (src) != Pmode)
2181 abort ();
2183 /* Check if any of the two operands is already scheduled
2184 for replacement by reload. This can happen e.g. when
2185 float registers occur in an address. */
2186 sum1 = find_replacement (&XEXP (src, 0));
2187 sum2 = find_replacement (&XEXP (src, 1));
2188 src = gen_rtx_PLUS (Pmode, sum1, sum2);
2190 /* If the address is already strictly valid, there's nothing to do. */
2191 if (!s390_decompose_address (src, &ad)
2192 || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
2193 || (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
2195 /* Otherwise, one of the operands cannot be an address register;
2196 we reload its value into the scratch register. */
2197 if (true_regnum (sum1) < 1 || true_regnum (sum1) > 15)
2199 emit_move_insn (scratch, sum1);
2200 sum1 = scratch;
2202 if (true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
2204 emit_move_insn (scratch, sum2);
2205 sum2 = scratch;
2208 /* According to the way these invalid addresses are generated
2209 in reload.c, it should never happen (at least on s390) that
2210 *neither* of the PLUS components, after find_replacements
2211 was applied, is an address register. */
2212 if (sum1 == scratch && sum2 == scratch)
2214 debug_rtx (src);
2215 abort ();
2218 src = gen_rtx_PLUS (Pmode, sum1, sum2);
2221 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
2222 is only ever performed on addresses, so we can mark the
2223 sum as legitimate for LA in any case. */
2224 s390_load_address (target, src);
2228 /* Decompose a RTL expression ADDR for a memory address into
2229 its components, returned in OUT.
2231 Returns 0 if ADDR is not a valid memory address, nonzero
2232 otherwise. If OUT is NULL, don't return the components,
2233 but check for validity only.
2235 Note: Only addresses in canonical form are recognized.
2236 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
2237 canonical form so that they will be recognized. */
2239 static int
2240 s390_decompose_address (register rtx addr, struct s390_address *out)
2242 HOST_WIDE_INT offset = 0;
2243 rtx base = NULL_RTX;
2244 rtx indx = NULL_RTX;
2245 rtx disp = NULL_RTX;
2246 rtx orig_disp;
2247 int pointer = FALSE;
2248 int base_ptr = FALSE;
2249 int indx_ptr = FALSE;
2251 /* Decompose address into base + index + displacement. */
2253 if (GET_CODE (addr) == REG || GET_CODE (addr) == UNSPEC)
2254 base = addr;
2256 else if (GET_CODE (addr) == PLUS)
2258 rtx op0 = XEXP (addr, 0);
2259 rtx op1 = XEXP (addr, 1);
2260 enum rtx_code code0 = GET_CODE (op0);
2261 enum rtx_code code1 = GET_CODE (op1);
2263 if (code0 == REG || code0 == UNSPEC)
2265 if (code1 == REG || code1 == UNSPEC)
2267 indx = op0; /* index + base */
2268 base = op1;
2271 else
2273 base = op0; /* base + displacement */
2274 disp = op1;
2278 else if (code0 == PLUS)
2280 indx = XEXP (op0, 0); /* index + base + disp */
2281 base = XEXP (op0, 1);
2282 disp = op1;
2285 else
2287 return FALSE;
2291 else
2292 disp = addr; /* displacement */
2294 /* Extract integer part of displacement. */
2295 orig_disp = disp;
2296 if (disp)
2298 if (GET_CODE (disp) == CONST_INT)
2300 offset = INTVAL (disp);
2301 disp = NULL_RTX;
2303 else if (GET_CODE (disp) == CONST
2304 && GET_CODE (XEXP (disp, 0)) == PLUS
2305 && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT)
2307 offset = INTVAL (XEXP (XEXP (disp, 0), 1));
2308 disp = XEXP (XEXP (disp, 0), 0);
2312 /* Strip off CONST here to avoid special case tests later. */
2313 if (disp && GET_CODE (disp) == CONST)
2314 disp = XEXP (disp, 0);
2316 /* We can convert literal pool addresses to
2317 displacements by basing them off the base register. */
2318 if (disp && GET_CODE (disp) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (disp))
2320 /* Either base or index must be free to hold the base register. */
2321 if (!base)
2322 base = gen_rtx_REG (Pmode, BASE_REGNUM);
2323 else if (!indx)
2324 indx = gen_rtx_REG (Pmode, BASE_REGNUM);
2325 else
2326 return FALSE;
2328 /* Mark up the displacement. */
2329 disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp),
2330 UNSPEC_LTREL_OFFSET);
2333 /* Validate base register. */
2334 if (base)
2336 if (GET_CODE (base) == UNSPEC)
2337 switch (XINT (base, 1))
2339 case UNSPEC_LTREF:
2340 if (!disp)
2341 disp = gen_rtx_UNSPEC (Pmode,
2342 gen_rtvec (1, XVECEXP (base, 0, 0)),
2343 UNSPEC_LTREL_OFFSET);
2344 else
2345 return FALSE;
2347 base = gen_rtx_REG (Pmode, BASE_REGNUM);
2348 break;
2350 case UNSPEC_LTREL_BASE:
2351 base = gen_rtx_REG (Pmode, BASE_REGNUM);
2352 break;
2354 default:
2355 return FALSE;
2358 if (GET_CODE (base) != REG || GET_MODE (base) != Pmode)
2359 return FALSE;
2361 if (REGNO (base) == BASE_REGNUM
2362 || REGNO (base) == STACK_POINTER_REGNUM
2363 || REGNO (base) == FRAME_POINTER_REGNUM
2364 || ((reload_completed || reload_in_progress)
2365 && frame_pointer_needed
2366 && REGNO (base) == HARD_FRAME_POINTER_REGNUM)
2367 || REGNO (base) == ARG_POINTER_REGNUM
2368 || (flag_pic
2369 && REGNO (base) == PIC_OFFSET_TABLE_REGNUM))
2370 pointer = base_ptr = TRUE;
2373 /* Validate index register. */
2374 if (indx)
2376 if (GET_CODE (indx) == UNSPEC)
2377 switch (XINT (indx, 1))
2379 case UNSPEC_LTREF:
2380 if (!disp)
2381 disp = gen_rtx_UNSPEC (Pmode,
2382 gen_rtvec (1, XVECEXP (indx, 0, 0)),
2383 UNSPEC_LTREL_OFFSET);
2384 else
2385 return FALSE;
2387 indx = gen_rtx_REG (Pmode, BASE_REGNUM);
2388 break;
2390 case UNSPEC_LTREL_BASE:
2391 indx = gen_rtx_REG (Pmode, BASE_REGNUM);
2392 break;
2394 default:
2395 return FALSE;
2398 if (GET_CODE (indx) != REG || GET_MODE (indx) != Pmode)
2399 return FALSE;
2401 if (REGNO (indx) == BASE_REGNUM
2402 || REGNO (indx) == STACK_POINTER_REGNUM
2403 || REGNO (indx) == FRAME_POINTER_REGNUM
2404 || ((reload_completed || reload_in_progress)
2405 && frame_pointer_needed
2406 && REGNO (indx) == HARD_FRAME_POINTER_REGNUM)
2407 || REGNO (indx) == ARG_POINTER_REGNUM
2408 || (flag_pic
2409 && REGNO (indx) == PIC_OFFSET_TABLE_REGNUM))
2410 pointer = indx_ptr = TRUE;
2413 /* Prefer to use pointer as base, not index. */
2414 if (base && indx && !base_ptr
2415 && (indx_ptr || (!REG_POINTER (base) && REG_POINTER (indx))))
2417 rtx tmp = base;
2418 base = indx;
2419 indx = tmp;
2422 /* Validate displacement. */
2423 if (!disp)
2425 /* If the argument pointer or the return address pointer are involved,
2426 the displacement will change later anyway as the virtual registers get
2427 eliminated. This could make a valid displacement invalid, but it is
2428 more likely to make an invalid displacement valid, because we sometimes
2429 access the register save area via negative offsets to one of those
2430 registers.
2431 Thus we don't check the displacement for validity here. If after
2432 elimination the displacement turns out to be invalid after all,
2433 this is fixed up by reload in any case. */
2434 if (base != arg_pointer_rtx
2435 && indx != arg_pointer_rtx
2436 && base != return_address_pointer_rtx
2437 && indx != return_address_pointer_rtx)
2438 if (!DISP_IN_RANGE (offset))
2439 return FALSE;
2441 else
2443 /* All the special cases are pointers. */
2444 pointer = TRUE;
2446 /* In the small-PIC case, the linker converts @GOT
2447 and @GOTNTPOFF offsets to possible displacements. */
2448 if (GET_CODE (disp) == UNSPEC
2449 && (XINT (disp, 1) == UNSPEC_GOT
2450 || XINT (disp, 1) == UNSPEC_GOTNTPOFF)
2451 && offset == 0
2452 && flag_pic == 1)
2457 /* Accept chunkified literal pool symbol references. */
2458 else if (GET_CODE (disp) == MINUS
2459 && GET_CODE (XEXP (disp, 0)) == LABEL_REF
2460 && GET_CODE (XEXP (disp, 1)) == LABEL_REF)
2465 /* Accept literal pool references. */
2466 else if (GET_CODE (disp) == UNSPEC
2467 && XINT (disp, 1) == UNSPEC_LTREL_OFFSET)
2469 orig_disp = gen_rtx_CONST (Pmode, disp);
2470 if (offset)
2472 /* If we have an offset, make sure it does not
2473 exceed the size of the constant pool entry. */
2474 rtx sym = XVECEXP (disp, 0, 0);
2475 if (offset >= GET_MODE_SIZE (get_pool_mode (sym)))
2476 return FALSE;
2478 orig_disp = plus_constant (orig_disp, offset);
2482 else
2483 return FALSE;
2486 if (!base && !indx)
2487 pointer = TRUE;
2489 if (out)
2491 out->base = base;
2492 out->indx = indx;
2493 out->disp = orig_disp;
2494 out->pointer = pointer;
2497 return TRUE;
2500 /* Return nonzero if ADDR is a valid memory address.
2501 STRICT specifies whether strict register checking applies. */
2504 legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
2505 register rtx addr, int strict)
2507 struct s390_address ad;
2508 if (!s390_decompose_address (addr, &ad))
2509 return FALSE;
2511 if (strict)
2513 if (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
2514 return FALSE;
2515 if (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx))
2516 return FALSE;
2518 else
2520 if (ad.base && !REG_OK_FOR_BASE_NONSTRICT_P (ad.base))
2521 return FALSE;
2522 if (ad.indx && !REG_OK_FOR_INDEX_NONSTRICT_P (ad.indx))
2523 return FALSE;
2526 return TRUE;
2529 /* Return 1 if OP is a valid operand for the LA instruction.
2530 In 31-bit, we need to prove that the result is used as an
2531 address, as LA performs only a 31-bit addition. */
2534 legitimate_la_operand_p (register rtx op)
2536 struct s390_address addr;
2537 if (!s390_decompose_address (op, &addr))
2538 return FALSE;
2540 if (TARGET_64BIT || addr.pointer)
2541 return TRUE;
2543 return FALSE;
2546 /* Return 1 if it is valid *and* preferable to use LA to
2547 compute the sum of OP1 and OP2. */
2550 preferred_la_operand_p (rtx op1, rtx op2)
2552 struct s390_address addr;
2554 if (op2 != const0_rtx)
2555 op1 = gen_rtx_PLUS (Pmode, op1, op2);
2557 if (!s390_decompose_address (op1, &addr))
2558 return FALSE;
2559 if (addr.base && !REG_OK_FOR_BASE_STRICT_P (addr.base))
2560 return FALSE;
2561 if (addr.indx && !REG_OK_FOR_INDEX_STRICT_P (addr.indx))
2562 return FALSE;
2564 if (!TARGET_64BIT && !addr.pointer)
2565 return FALSE;
2567 if (addr.pointer)
2568 return TRUE;
2570 if ((addr.base && REG_P (addr.base) && REG_POINTER (addr.base))
2571 || (addr.indx && REG_P (addr.indx) && REG_POINTER (addr.indx)))
2572 return TRUE;
2574 return FALSE;
2577 /* Emit a forced load-address operation to load SRC into DST.
2578 This will use the LOAD ADDRESS instruction even in situations
2579 where legitimate_la_operand_p (SRC) returns false. */
2581 void
2582 s390_load_address (rtx dst, rtx src)
2584 if (TARGET_64BIT)
2585 emit_move_insn (dst, src);
2586 else
2587 emit_insn (gen_force_la_31 (dst, src));
2590 /* Return a legitimate reference for ORIG (an address) using the
2591 register REG. If REG is 0, a new pseudo is generated.
2593 There are two types of references that must be handled:
2595 1. Global data references must load the address from the GOT, via
2596 the PIC reg. An insn is emitted to do this load, and the reg is
2597 returned.
2599 2. Static data references, constant pool addresses, and code labels
2600 compute the address as an offset from the GOT, whose base is in
2601 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
2602 differentiate them from global data objects. The returned
2603 address is the PIC reg + an unspec constant.
2605 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2606 reg also appears in the address. */
2609 legitimize_pic_address (rtx orig, rtx reg)
2611 rtx addr = orig;
2612 rtx new = orig;
2613 rtx base;
2615 if (GET_CODE (addr) == LABEL_REF
2616 || (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (addr)))
2618 /* This is a local symbol. */
2619 if (TARGET_CPU_ZARCH && larl_operand (addr, VOIDmode))
2621 /* Access local symbols PC-relative via LARL.
2622 This is the same as in the non-PIC case, so it is
2623 handled automatically ... */
2625 else
2627 /* Access local symbols relative to the GOT. */
2629 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2631 if (reload_in_progress || reload_completed)
2632 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2634 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
2635 addr = gen_rtx_CONST (Pmode, addr);
2636 addr = force_const_mem (Pmode, addr);
2637 emit_move_insn (temp, addr);
2639 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2640 if (reg != 0)
2642 emit_move_insn (reg, new);
2643 new = reg;
2647 else if (GET_CODE (addr) == SYMBOL_REF)
2649 if (reg == 0)
2650 reg = gen_reg_rtx (Pmode);
2652 if (flag_pic == 1)
2654 /* Assume GOT offset < 4k. This is handled the same way
2655 in both 31- and 64-bit code (@GOT). */
2657 if (reload_in_progress || reload_completed)
2658 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2660 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
2661 new = gen_rtx_CONST (Pmode, new);
2662 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
2663 new = gen_const_mem (Pmode, new);
2664 emit_move_insn (reg, new);
2665 new = reg;
2667 else if (TARGET_CPU_ZARCH)
2669 /* If the GOT offset might be >= 4k, we determine the position
2670 of the GOT entry via a PC-relative LARL (@GOTENT). */
2672 rtx temp = gen_reg_rtx (Pmode);
2674 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTENT);
2675 new = gen_rtx_CONST (Pmode, new);
2676 emit_move_insn (temp, new);
2678 new = gen_const_mem (Pmode, temp);
2679 emit_move_insn (reg, new);
2680 new = reg;
2682 else
2684 /* If the GOT offset might be >= 4k, we have to load it
2685 from the literal pool (@GOT). */
2687 rtx temp = gen_reg_rtx (Pmode);
2689 if (reload_in_progress || reload_completed)
2690 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2692 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
2693 addr = gen_rtx_CONST (Pmode, addr);
2694 addr = force_const_mem (Pmode, addr);
2695 emit_move_insn (temp, addr);
2697 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2698 new = gen_const_mem (Pmode, new);
2699 emit_move_insn (reg, new);
2700 new = reg;
2703 else
2705 if (GET_CODE (addr) == CONST)
2707 addr = XEXP (addr, 0);
2708 if (GET_CODE (addr) == UNSPEC)
2710 if (XVECLEN (addr, 0) != 1)
2711 abort ();
2712 switch (XINT (addr, 1))
2714 /* If someone moved a GOT-relative UNSPEC
2715 out of the literal pool, force them back in. */
2716 case UNSPEC_GOTOFF:
2717 case UNSPEC_PLTOFF:
2718 new = force_const_mem (Pmode, orig);
2719 break;
2721 /* @GOT is OK as is if small. */
2722 case UNSPEC_GOT:
2723 if (flag_pic == 2)
2724 new = force_const_mem (Pmode, orig);
2725 break;
2727 /* @GOTENT is OK as is. */
2728 case UNSPEC_GOTENT:
2729 break;
2731 /* @PLT is OK as is on 64-bit, must be converted to
2732 GOT-relative @PLTOFF on 31-bit. */
2733 case UNSPEC_PLT:
2734 if (!TARGET_CPU_ZARCH)
2736 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2738 if (reload_in_progress || reload_completed)
2739 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2741 addr = XVECEXP (addr, 0, 0);
2742 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
2743 UNSPEC_PLTOFF);
2744 addr = gen_rtx_CONST (Pmode, addr);
2745 addr = force_const_mem (Pmode, addr);
2746 emit_move_insn (temp, addr);
2748 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2749 if (reg != 0)
2751 emit_move_insn (reg, new);
2752 new = reg;
2755 break;
2757 /* Everything else cannot happen. */
2758 default:
2759 abort ();
2762 else if (GET_CODE (addr) != PLUS)
2763 abort ();
2765 if (GET_CODE (addr) == PLUS)
2767 rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
2768 /* Check first to see if this is a constant offset
2769 from a local symbol reference. */
2770 if ((GET_CODE (op0) == LABEL_REF
2771 || (GET_CODE (op0) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op0)))
2772 && GET_CODE (op1) == CONST_INT)
2774 if (TARGET_CPU_ZARCH && larl_operand (op0, VOIDmode))
2776 if (INTVAL (op1) & 1)
2778 /* LARL can't handle odd offsets, so emit a
2779 pair of LARL and LA. */
2780 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2782 if (!DISP_IN_RANGE (INTVAL (op1)))
2784 int even = INTVAL (op1) - 1;
2785 op0 = gen_rtx_PLUS (Pmode, op0, GEN_INT (even));
2786 op0 = gen_rtx_CONST (Pmode, op0);
2787 op1 = const1_rtx;
2790 emit_move_insn (temp, op0);
2791 new = gen_rtx_PLUS (Pmode, temp, op1);
2793 if (reg != 0)
2795 emit_move_insn (reg, new);
2796 new = reg;
2799 else
2801 /* If the offset is even, we can just use LARL.
2802 This will happen automatically. */
2805 else
2807 /* Access local symbols relative to the GOT. */
2809 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2811 if (reload_in_progress || reload_completed)
2812 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2814 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
2815 UNSPEC_GOTOFF);
2816 addr = gen_rtx_PLUS (Pmode, addr, op1);
2817 addr = gen_rtx_CONST (Pmode, addr);
2818 addr = force_const_mem (Pmode, addr);
2819 emit_move_insn (temp, addr);
2821 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2822 if (reg != 0)
2824 emit_move_insn (reg, new);
2825 new = reg;
2830 /* Now, check whether it is a GOT relative symbol plus offset
2831 that was pulled out of the literal pool. Force it back in. */
2833 else if (GET_CODE (op0) == UNSPEC
2834 && GET_CODE (op1) == CONST_INT
2835 && XINT (op0, 1) == UNSPEC_GOTOFF)
2837 if (XVECLEN (op0, 0) != 1)
2838 abort ();
2840 new = force_const_mem (Pmode, orig);
2843 /* Otherwise, compute the sum. */
2844 else
2846 base = legitimize_pic_address (XEXP (addr, 0), reg);
2847 new = legitimize_pic_address (XEXP (addr, 1),
2848 base == reg ? NULL_RTX : reg);
2849 if (GET_CODE (new) == CONST_INT)
2850 new = plus_constant (base, INTVAL (new));
2851 else
2853 if (GET_CODE (new) == PLUS && CONSTANT_P (XEXP (new, 1)))
2855 base = gen_rtx_PLUS (Pmode, base, XEXP (new, 0));
2856 new = XEXP (new, 1);
2858 new = gen_rtx_PLUS (Pmode, base, new);
2861 if (GET_CODE (new) == CONST)
2862 new = XEXP (new, 0);
2863 new = force_operand (new, 0);
2867 return new;
2870 /* Load the thread pointer into a register. */
2872 static rtx
2873 get_thread_pointer (void)
2875 rtx tp;
2877 tp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
2878 tp = force_reg (Pmode, tp);
2879 mark_reg_pointer (tp, BITS_PER_WORD);
2881 return tp;
2884 /* Emit a tls call insn. The call target is the SYMBOL_REF stored
2885 in s390_tls_symbol which always refers to __tls_get_offset.
2886 The returned offset is written to RESULT_REG and an USE rtx is
2887 generated for TLS_CALL. */
2889 static GTY(()) rtx s390_tls_symbol;
2891 static void
2892 s390_emit_tls_call_insn (rtx result_reg, rtx tls_call)
2894 rtx insn;
2896 if (!flag_pic)
2897 abort ();
2899 if (!s390_tls_symbol)
2900 s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset");
2902 insn = s390_emit_call (s390_tls_symbol, tls_call, result_reg,
2903 gen_rtx_REG (Pmode, RETURN_REGNUM));
2905 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), result_reg);
2906 CONST_OR_PURE_CALL_P (insn) = 1;
2909 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
2910 this (thread-local) address. REG may be used as temporary. */
2912 static rtx
2913 legitimize_tls_address (rtx addr, rtx reg)
2915 rtx new, tls_call, temp, base, r2, insn;
2917 if (GET_CODE (addr) == SYMBOL_REF)
2918 switch (tls_symbolic_operand (addr))
2920 case TLS_MODEL_GLOBAL_DYNAMIC:
2921 start_sequence ();
2922 r2 = gen_rtx_REG (Pmode, 2);
2923 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLSGD);
2924 new = gen_rtx_CONST (Pmode, tls_call);
2925 new = force_const_mem (Pmode, new);
2926 emit_move_insn (r2, new);
2927 s390_emit_tls_call_insn (r2, tls_call);
2928 insn = get_insns ();
2929 end_sequence ();
2931 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
2932 temp = gen_reg_rtx (Pmode);
2933 emit_libcall_block (insn, temp, r2, new);
2935 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2936 if (reg != 0)
2938 s390_load_address (reg, new);
2939 new = reg;
2941 break;
2943 case TLS_MODEL_LOCAL_DYNAMIC:
2944 start_sequence ();
2945 r2 = gen_rtx_REG (Pmode, 2);
2946 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM);
2947 new = gen_rtx_CONST (Pmode, tls_call);
2948 new = force_const_mem (Pmode, new);
2949 emit_move_insn (r2, new);
2950 s390_emit_tls_call_insn (r2, tls_call);
2951 insn = get_insns ();
2952 end_sequence ();
2954 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM_NTPOFF);
2955 temp = gen_reg_rtx (Pmode);
2956 emit_libcall_block (insn, temp, r2, new);
2958 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2959 base = gen_reg_rtx (Pmode);
2960 s390_load_address (base, new);
2962 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_DTPOFF);
2963 new = gen_rtx_CONST (Pmode, new);
2964 new = force_const_mem (Pmode, new);
2965 temp = gen_reg_rtx (Pmode);
2966 emit_move_insn (temp, new);
2968 new = gen_rtx_PLUS (Pmode, base, temp);
2969 if (reg != 0)
2971 s390_load_address (reg, new);
2972 new = reg;
2974 break;
2976 case TLS_MODEL_INITIAL_EXEC:
2977 if (flag_pic == 1)
2979 /* Assume GOT offset < 4k. This is handled the same way
2980 in both 31- and 64-bit code. */
2982 if (reload_in_progress || reload_completed)
2983 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2985 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
2986 new = gen_rtx_CONST (Pmode, new);
2987 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
2988 new = gen_const_mem (Pmode, new);
2989 temp = gen_reg_rtx (Pmode);
2990 emit_move_insn (temp, new);
2992 else if (TARGET_CPU_ZARCH)
2994 /* If the GOT offset might be >= 4k, we determine the position
2995 of the GOT entry via a PC-relative LARL. */
2997 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
2998 new = gen_rtx_CONST (Pmode, new);
2999 temp = gen_reg_rtx (Pmode);
3000 emit_move_insn (temp, new);
3002 new = gen_const_mem (Pmode, temp);
3003 temp = gen_reg_rtx (Pmode);
3004 emit_move_insn (temp, new);
3006 else if (flag_pic)
3008 /* If the GOT offset might be >= 4k, we have to load it
3009 from the literal pool. */
3011 if (reload_in_progress || reload_completed)
3012 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
3014 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
3015 new = gen_rtx_CONST (Pmode, new);
3016 new = force_const_mem (Pmode, new);
3017 temp = gen_reg_rtx (Pmode);
3018 emit_move_insn (temp, new);
3020 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
3021 new = gen_const_mem (Pmode, new);
3023 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new, addr), UNSPEC_TLS_LOAD);
3024 temp = gen_reg_rtx (Pmode);
3025 emit_insn (gen_rtx_SET (Pmode, temp, new));
3027 else
3029 /* In position-dependent code, load the absolute address of
3030 the GOT entry from the literal pool. */
3032 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
3033 new = gen_rtx_CONST (Pmode, new);
3034 new = force_const_mem (Pmode, new);
3035 temp = gen_reg_rtx (Pmode);
3036 emit_move_insn (temp, new);
3038 new = temp;
3039 new = gen_const_mem (Pmode, new);
3040 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new, addr), UNSPEC_TLS_LOAD);
3041 temp = gen_reg_rtx (Pmode);
3042 emit_insn (gen_rtx_SET (Pmode, temp, new));
3045 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
3046 if (reg != 0)
3048 s390_load_address (reg, new);
3049 new = reg;
3051 break;
3053 case TLS_MODEL_LOCAL_EXEC:
3054 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
3055 new = gen_rtx_CONST (Pmode, new);
3056 new = force_const_mem (Pmode, new);
3057 temp = gen_reg_rtx (Pmode);
3058 emit_move_insn (temp, new);
3060 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
3061 if (reg != 0)
3063 s390_load_address (reg, new);
3064 new = reg;
3066 break;
3068 default:
3069 abort ();
3072 else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == UNSPEC)
3074 switch (XINT (XEXP (addr, 0), 1))
3076 case UNSPEC_INDNTPOFF:
3077 if (TARGET_CPU_ZARCH)
3078 new = addr;
3079 else
3080 abort ();
3081 break;
3083 default:
3084 abort ();
3088 else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == PLUS
3089 && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
3091 new = XEXP (XEXP (addr, 0), 0);
3092 if (GET_CODE (new) != SYMBOL_REF)
3093 new = gen_rtx_CONST (Pmode, new);
3095 new = legitimize_tls_address (new, reg);
3096 new = plus_constant (new, INTVAL (XEXP (XEXP (addr, 0), 1)));
3097 new = force_operand (new, 0);
3100 else
3101 abort (); /* for now ... */
3103 return new;
3106 /* Emit insns to move operands[1] into operands[0]. */
3108 void
3109 emit_symbolic_move (rtx *operands)
3111 rtx temp = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
3113 if (GET_CODE (operands[0]) == MEM)
3114 operands[1] = force_reg (Pmode, operands[1]);
3115 else if (TLS_SYMBOLIC_CONST (operands[1]))
3116 operands[1] = legitimize_tls_address (operands[1], temp);
3117 else if (flag_pic)
3118 operands[1] = legitimize_pic_address (operands[1], temp);
3121 /* Try machine-dependent ways of modifying an illegitimate address X
3122 to be legitimate. If we find one, return the new, valid address.
3124 OLDX is the address as it was before break_out_memory_refs was called.
3125 In some cases it is useful to look at this to decide what needs to be done.
3127 MODE is the mode of the operand pointed to by X.
3129 When -fpic is used, special handling is needed for symbolic references.
3130 See comments by legitimize_pic_address for details. */
3133 legitimize_address (register rtx x, register rtx oldx ATTRIBUTE_UNUSED,
3134 enum machine_mode mode ATTRIBUTE_UNUSED)
3136 rtx constant_term = const0_rtx;
3138 if (TLS_SYMBOLIC_CONST (x))
3140 x = legitimize_tls_address (x, 0);
3142 if (legitimate_address_p (mode, x, FALSE))
3143 return x;
3145 else if (flag_pic)
3147 if (SYMBOLIC_CONST (x)
3148 || (GET_CODE (x) == PLUS
3149 && (SYMBOLIC_CONST (XEXP (x, 0))
3150 || SYMBOLIC_CONST (XEXP (x, 1)))))
3151 x = legitimize_pic_address (x, 0);
3153 if (legitimate_address_p (mode, x, FALSE))
3154 return x;
3157 x = eliminate_constant_term (x, &constant_term);
3159 /* Optimize loading of large displacements by splitting them
3160 into the multiple of 4K and the rest; this allows the
3161 former to be CSE'd if possible.
3163 Don't do this if the displacement is added to a register
3164 pointing into the stack frame, as the offsets will
3165 change later anyway. */
3167 if (GET_CODE (constant_term) == CONST_INT
3168 && !TARGET_LONG_DISPLACEMENT
3169 && !DISP_IN_RANGE (INTVAL (constant_term))
3170 && !(REG_P (x) && REGNO_PTR_FRAME_P (REGNO (x))))
3172 HOST_WIDE_INT lower = INTVAL (constant_term) & 0xfff;
3173 HOST_WIDE_INT upper = INTVAL (constant_term) ^ lower;
3175 rtx temp = gen_reg_rtx (Pmode);
3176 rtx val = force_operand (GEN_INT (upper), temp);
3177 if (val != temp)
3178 emit_move_insn (temp, val);
3180 x = gen_rtx_PLUS (Pmode, x, temp);
3181 constant_term = GEN_INT (lower);
3184 if (GET_CODE (x) == PLUS)
3186 if (GET_CODE (XEXP (x, 0)) == REG)
3188 register rtx temp = gen_reg_rtx (Pmode);
3189 register rtx val = force_operand (XEXP (x, 1), temp);
3190 if (val != temp)
3191 emit_move_insn (temp, val);
3193 x = gen_rtx_PLUS (Pmode, XEXP (x, 0), temp);
3196 else if (GET_CODE (XEXP (x, 1)) == REG)
3198 register rtx temp = gen_reg_rtx (Pmode);
3199 register rtx val = force_operand (XEXP (x, 0), temp);
3200 if (val != temp)
3201 emit_move_insn (temp, val);
3203 x = gen_rtx_PLUS (Pmode, temp, XEXP (x, 1));
3207 if (constant_term != const0_rtx)
3208 x = gen_rtx_PLUS (Pmode, x, constant_term);
3210 return x;
3213 /* Try a machine-dependent way of reloading an illegitimate address AD
3214 operand. If we find one, push the reload and and return the new address.
3216 MODE is the mode of the enclosing MEM. OPNUM is the operand number
3217 and TYPE is the reload type of the current reload. */
3219 rtx
3220 legitimize_reload_address (rtx ad, enum machine_mode mode ATTRIBUTE_UNUSED,
3221 int opnum, int type)
3223 if (!optimize || TARGET_LONG_DISPLACEMENT)
3224 return NULL_RTX;
3226 if (GET_CODE (ad) == PLUS)
3228 rtx tem = simplify_binary_operation (PLUS, Pmode,
3229 XEXP (ad, 0), XEXP (ad, 1));
3230 if (tem)
3231 ad = tem;
3234 if (GET_CODE (ad) == PLUS
3235 && GET_CODE (XEXP (ad, 0)) == REG
3236 && GET_CODE (XEXP (ad, 1)) == CONST_INT
3237 && !DISP_IN_RANGE (INTVAL (XEXP (ad, 1))))
3239 HOST_WIDE_INT lower = INTVAL (XEXP (ad, 1)) & 0xfff;
3240 HOST_WIDE_INT upper = INTVAL (XEXP (ad, 1)) ^ lower;
3241 rtx cst, tem, new;
3243 cst = GEN_INT (upper);
3244 if (!legitimate_reload_constant_p (cst))
3245 cst = force_const_mem (Pmode, cst);
3247 tem = gen_rtx_PLUS (Pmode, XEXP (ad, 0), cst);
3248 new = gen_rtx_PLUS (Pmode, tem, GEN_INT (lower));
3250 push_reload (XEXP (tem, 1), 0, &XEXP (tem, 1), 0,
3251 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3252 opnum, (enum reload_type) type);
3253 return new;
3256 return NULL_RTX;
3259 /* Emit code to move LEN bytes from DST to SRC. */
3261 void
3262 s390_expand_movmem (rtx dst, rtx src, rtx len)
3264 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
3266 if (INTVAL (len) > 0)
3267 emit_insn (gen_movmem_short (dst, src, GEN_INT (INTVAL (len) - 1)));
3270 else if (TARGET_MVCLE)
3272 emit_insn (gen_movmem_long (dst, src, convert_to_mode (Pmode, len, 1)));
3275 else
3277 rtx dst_addr, src_addr, count, blocks, temp;
3278 rtx loop_start_label = gen_label_rtx ();
3279 rtx loop_end_label = gen_label_rtx ();
3280 rtx end_label = gen_label_rtx ();
3281 enum machine_mode mode;
3283 mode = GET_MODE (len);
3284 if (mode == VOIDmode)
3285 mode = Pmode;
3287 dst_addr = gen_reg_rtx (Pmode);
3288 src_addr = gen_reg_rtx (Pmode);
3289 count = gen_reg_rtx (mode);
3290 blocks = gen_reg_rtx (mode);
3292 convert_move (count, len, 1);
3293 emit_cmp_and_jump_insns (count, const0_rtx,
3294 EQ, NULL_RTX, mode, 1, end_label);
3296 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
3297 emit_move_insn (src_addr, force_operand (XEXP (src, 0), NULL_RTX));
3298 dst = change_address (dst, VOIDmode, dst_addr);
3299 src = change_address (src, VOIDmode, src_addr);
3301 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3302 if (temp != count)
3303 emit_move_insn (count, temp);
3305 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
3306 if (temp != blocks)
3307 emit_move_insn (blocks, temp);
3309 emit_cmp_and_jump_insns (blocks, const0_rtx,
3310 EQ, NULL_RTX, mode, 1, loop_end_label);
3312 emit_label (loop_start_label);
3314 emit_insn (gen_movmem_short (dst, src, GEN_INT (255)));
3315 s390_load_address (dst_addr,
3316 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
3317 s390_load_address (src_addr,
3318 gen_rtx_PLUS (Pmode, src_addr, GEN_INT (256)));
3320 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3321 if (temp != blocks)
3322 emit_move_insn (blocks, temp);
3324 emit_cmp_and_jump_insns (blocks, const0_rtx,
3325 EQ, NULL_RTX, mode, 1, loop_end_label);
3327 emit_jump (loop_start_label);
3328 emit_label (loop_end_label);
3330 emit_insn (gen_movmem_short (dst, src,
3331 convert_to_mode (Pmode, count, 1)));
3332 emit_label (end_label);
3336 /* Emit code to clear LEN bytes at DST. */
3338 void
3339 s390_expand_clrmem (rtx dst, rtx len)
3341 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
3343 if (INTVAL (len) > 0)
3344 emit_insn (gen_clrmem_short (dst, GEN_INT (INTVAL (len) - 1)));
3347 else if (TARGET_MVCLE)
3349 emit_insn (gen_clrmem_long (dst, convert_to_mode (Pmode, len, 1)));
3352 else
3354 rtx dst_addr, src_addr, count, blocks, temp;
3355 rtx loop_start_label = gen_label_rtx ();
3356 rtx loop_end_label = gen_label_rtx ();
3357 rtx end_label = gen_label_rtx ();
3358 enum machine_mode mode;
3360 mode = GET_MODE (len);
3361 if (mode == VOIDmode)
3362 mode = Pmode;
3364 dst_addr = gen_reg_rtx (Pmode);
3365 src_addr = gen_reg_rtx (Pmode);
3366 count = gen_reg_rtx (mode);
3367 blocks = gen_reg_rtx (mode);
3369 convert_move (count, len, 1);
3370 emit_cmp_and_jump_insns (count, const0_rtx,
3371 EQ, NULL_RTX, mode, 1, end_label);
3373 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
3374 dst = change_address (dst, VOIDmode, dst_addr);
3376 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3377 if (temp != count)
3378 emit_move_insn (count, temp);
3380 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
3381 if (temp != blocks)
3382 emit_move_insn (blocks, temp);
3384 emit_cmp_and_jump_insns (blocks, const0_rtx,
3385 EQ, NULL_RTX, mode, 1, loop_end_label);
3387 emit_label (loop_start_label);
3389 emit_insn (gen_clrmem_short (dst, GEN_INT (255)));
3390 s390_load_address (dst_addr,
3391 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
3393 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3394 if (temp != blocks)
3395 emit_move_insn (blocks, temp);
3397 emit_cmp_and_jump_insns (blocks, const0_rtx,
3398 EQ, NULL_RTX, mode, 1, loop_end_label);
3400 emit_jump (loop_start_label);
3401 emit_label (loop_end_label);
3403 emit_insn (gen_clrmem_short (dst, convert_to_mode (Pmode, count, 1)));
3404 emit_label (end_label);
3408 /* Emit code to compare LEN bytes at OP0 with those at OP1,
3409 and return the result in TARGET. */
3411 void
3412 s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
3414 rtx (*gen_result) (rtx) =
3415 GET_MODE (target) == DImode ? gen_cmpint_di : gen_cmpint_si;
3417 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
3419 if (INTVAL (len) > 0)
3421 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (INTVAL (len) - 1)));
3422 emit_insn (gen_result (target));
3424 else
3425 emit_move_insn (target, const0_rtx);
3428 else /* if (TARGET_MVCLE) */
3430 emit_insn (gen_cmpmem_long (op0, op1, convert_to_mode (Pmode, len, 1)));
3431 emit_insn (gen_result (target));
3434 #if 0
3435 /* Deactivate for now as profile code cannot cope with
3436 CC being live across basic block boundaries. */
3437 else
3439 rtx addr0, addr1, count, blocks, temp;
3440 rtx loop_start_label = gen_label_rtx ();
3441 rtx loop_end_label = gen_label_rtx ();
3442 rtx end_label = gen_label_rtx ();
3443 enum machine_mode mode;
3445 mode = GET_MODE (len);
3446 if (mode == VOIDmode)
3447 mode = Pmode;
3449 addr0 = gen_reg_rtx (Pmode);
3450 addr1 = gen_reg_rtx (Pmode);
3451 count = gen_reg_rtx (mode);
3452 blocks = gen_reg_rtx (mode);
3454 convert_move (count, len, 1);
3455 emit_cmp_and_jump_insns (count, const0_rtx,
3456 EQ, NULL_RTX, mode, 1, end_label);
3458 emit_move_insn (addr0, force_operand (XEXP (op0, 0), NULL_RTX));
3459 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
3460 op0 = change_address (op0, VOIDmode, addr0);
3461 op1 = change_address (op1, VOIDmode, addr1);
3463 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3464 if (temp != count)
3465 emit_move_insn (count, temp);
3467 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
3468 if (temp != blocks)
3469 emit_move_insn (blocks, temp);
3471 emit_cmp_and_jump_insns (blocks, const0_rtx,
3472 EQ, NULL_RTX, mode, 1, loop_end_label);
3474 emit_label (loop_start_label);
3476 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (255)));
3477 temp = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCSmode, 33), const0_rtx);
3478 temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
3479 gen_rtx_LABEL_REF (VOIDmode, end_label), pc_rtx);
3480 temp = gen_rtx_SET (VOIDmode, pc_rtx, temp);
3481 emit_jump_insn (temp);
3483 s390_load_address (addr0,
3484 gen_rtx_PLUS (Pmode, addr0, GEN_INT (256)));
3485 s390_load_address (addr1,
3486 gen_rtx_PLUS (Pmode, addr1, GEN_INT (256)));
3488 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3489 if (temp != blocks)
3490 emit_move_insn (blocks, temp);
3492 emit_cmp_and_jump_insns (blocks, const0_rtx,
3493 EQ, NULL_RTX, mode, 1, loop_end_label);
3495 emit_jump (loop_start_label);
3496 emit_label (loop_end_label);
3498 emit_insn (gen_cmpmem_short (op0, op1,
3499 convert_to_mode (Pmode, count, 1)));
3500 emit_label (end_label);
3502 emit_insn (gen_result (target));
3504 #endif
3508 /* Expand conditional increment or decrement using alc/slb instructions.
3509 Should generate code setting DST to either SRC or SRC + INCREMENT,
3510 depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
3511 Returns true if successful, false otherwise. */
3513 bool
3514 s390_expand_addcc (enum rtx_code cmp_code, rtx cmp_op0, rtx cmp_op1,
3515 rtx dst, rtx src, rtx increment)
3517 enum machine_mode cmp_mode;
3518 enum machine_mode cc_mode;
3519 rtx op_res;
3520 rtx insn;
3521 rtvec p;
3523 if ((GET_MODE (cmp_op0) == SImode || GET_MODE (cmp_op0) == VOIDmode)
3524 && (GET_MODE (cmp_op1) == SImode || GET_MODE (cmp_op1) == VOIDmode))
3525 cmp_mode = SImode;
3526 else if ((GET_MODE (cmp_op0) == DImode || GET_MODE (cmp_op0) == VOIDmode)
3527 && (GET_MODE (cmp_op1) == DImode || GET_MODE (cmp_op1) == VOIDmode))
3528 cmp_mode = DImode;
3529 else
3530 return false;
3532 /* Try ADD LOGICAL WITH CARRY. */
3533 if (increment == const1_rtx)
3535 /* Determine CC mode to use. */
3536 if (cmp_code == EQ || cmp_code == NE)
3538 if (cmp_op1 != const0_rtx)
3540 cmp_op0 = expand_simple_binop (cmp_mode, XOR, cmp_op0, cmp_op1,
3541 NULL_RTX, 0, OPTAB_WIDEN);
3542 cmp_op1 = const0_rtx;
3545 cmp_code = cmp_code == EQ ? LEU : GTU;
3548 if (cmp_code == LTU || cmp_code == LEU)
3550 rtx tem = cmp_op0;
3551 cmp_op0 = cmp_op1;
3552 cmp_op1 = tem;
3553 cmp_code = swap_condition (cmp_code);
3556 switch (cmp_code)
3558 case GTU:
3559 cc_mode = CCUmode;
3560 break;
3562 case GEU:
3563 cc_mode = CCL3mode;
3564 break;
3566 default:
3567 return false;
3570 /* Emit comparison instruction pattern. */
3571 if (!register_operand (cmp_op0, cmp_mode))
3572 cmp_op0 = force_reg (cmp_mode, cmp_op0);
3574 insn = gen_rtx_SET (VOIDmode, gen_rtx_REG (cc_mode, CC_REGNUM),
3575 gen_rtx_COMPARE (cc_mode, cmp_op0, cmp_op1));
3576 /* We use insn_invalid_p here to add clobbers if required. */
3577 if (insn_invalid_p (emit_insn (insn)))
3578 abort ();
3580 /* Emit ALC instruction pattern. */
3581 op_res = gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
3582 gen_rtx_REG (cc_mode, CC_REGNUM),
3583 const0_rtx);
3585 if (src != const0_rtx)
3587 if (!register_operand (src, GET_MODE (dst)))
3588 src = force_reg (GET_MODE (dst), src);
3590 src = gen_rtx_PLUS (GET_MODE (dst), src, const0_rtx);
3591 op_res = gen_rtx_PLUS (GET_MODE (dst), src, op_res);
3594 p = rtvec_alloc (2);
3595 RTVEC_ELT (p, 0) =
3596 gen_rtx_SET (VOIDmode, dst, op_res);
3597 RTVEC_ELT (p, 1) =
3598 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
3599 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
3601 return true;
3604 /* Try SUBTRACT LOGICAL WITH BORROW. */
3605 if (increment == constm1_rtx)
3607 /* Determine CC mode to use. */
3608 if (cmp_code == EQ || cmp_code == NE)
3610 if (cmp_op1 != const0_rtx)
3612 cmp_op0 = expand_simple_binop (cmp_mode, XOR, cmp_op0, cmp_op1,
3613 NULL_RTX, 0, OPTAB_WIDEN);
3614 cmp_op1 = const0_rtx;
3617 cmp_code = cmp_code == EQ ? LEU : GTU;
3620 if (cmp_code == GTU || cmp_code == GEU)
3622 rtx tem = cmp_op0;
3623 cmp_op0 = cmp_op1;
3624 cmp_op1 = tem;
3625 cmp_code = swap_condition (cmp_code);
3628 switch (cmp_code)
3630 case LEU:
3631 cc_mode = CCUmode;
3632 break;
3634 case LTU:
3635 cc_mode = CCL3mode;
3636 break;
3638 default:
3639 return false;
3642 /* Emit comparison instruction pattern. */
3643 if (!register_operand (cmp_op0, cmp_mode))
3644 cmp_op0 = force_reg (cmp_mode, cmp_op0);
3646 insn = gen_rtx_SET (VOIDmode, gen_rtx_REG (cc_mode, CC_REGNUM),
3647 gen_rtx_COMPARE (cc_mode, cmp_op0, cmp_op1));
3648 /* We use insn_invalid_p here to add clobbers if required. */
3649 if (insn_invalid_p (emit_insn (insn)))
3650 abort ();
3652 /* Emit SLB instruction pattern. */
3653 if (!register_operand (src, GET_MODE (dst)))
3654 src = force_reg (GET_MODE (dst), src);
3656 op_res = gen_rtx_MINUS (GET_MODE (dst),
3657 gen_rtx_MINUS (GET_MODE (dst), src, const0_rtx),
3658 gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
3659 gen_rtx_REG (cc_mode, CC_REGNUM),
3660 const0_rtx));
3661 p = rtvec_alloc (2);
3662 RTVEC_ELT (p, 0) =
3663 gen_rtx_SET (VOIDmode, dst, op_res);
3664 RTVEC_ELT (p, 1) =
3665 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
3666 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
3668 return true;
3671 return false;
3675 /* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
3676 We need to emit DTP-relative relocations. */
3678 void
3679 s390_output_dwarf_dtprel (FILE *file, int size, rtx x)
3681 switch (size)
3683 case 4:
3684 fputs ("\t.long\t", file);
3685 break;
3686 case 8:
3687 fputs ("\t.quad\t", file);
3688 break;
3689 default:
3690 abort ();
3692 output_addr_const (file, x);
3693 fputs ("@DTPOFF", file);
3696 /* In the name of slightly smaller debug output, and to cater to
3697 general assembler losage, recognize various UNSPEC sequences
3698 and turn them back into a direct symbol reference. */
3700 static rtx
3701 s390_delegitimize_address (rtx orig_x)
3703 rtx x = orig_x, y;
3705 if (GET_CODE (x) != MEM)
3706 return orig_x;
3708 x = XEXP (x, 0);
3709 if (GET_CODE (x) == PLUS
3710 && GET_CODE (XEXP (x, 1)) == CONST
3711 && GET_CODE (XEXP (x, 0)) == REG
3712 && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM)
3714 y = XEXP (XEXP (x, 1), 0);
3715 if (GET_CODE (y) == UNSPEC
3716 && XINT (y, 1) == UNSPEC_GOT)
3717 return XVECEXP (y, 0, 0);
3718 return orig_x;
3721 if (GET_CODE (x) == CONST)
3723 y = XEXP (x, 0);
3724 if (GET_CODE (y) == UNSPEC
3725 && XINT (y, 1) == UNSPEC_GOTENT)
3726 return XVECEXP (y, 0, 0);
3727 return orig_x;
3730 return orig_x;
3733 /* Output shift count operand OP to stdio stream FILE. */
3735 static void
3736 print_shift_count_operand (FILE *file, rtx op)
3738 HOST_WIDE_INT offset = 0;
3740 /* We can have an integer constant, an address register,
3741 or a sum of the two. */
3742 if (GET_CODE (op) == CONST_INT)
3744 offset = INTVAL (op);
3745 op = NULL_RTX;
3747 if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
3749 offset = INTVAL (XEXP (op, 1));
3750 op = XEXP (op, 0);
3752 while (op && GET_CODE (op) == SUBREG)
3753 op = SUBREG_REG (op);
3755 /* Sanity check. */
3756 if (op && (GET_CODE (op) != REG
3757 || REGNO (op) >= FIRST_PSEUDO_REGISTER
3758 || REGNO_REG_CLASS (REGNO (op)) != ADDR_REGS))
3759 abort ();
3761 /* Shift counts are truncated to the low six bits anyway. */
3762 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset & 63);
3763 if (op)
3764 fprintf (file, "(%s)", reg_names[REGNO (op)]);
3767 /* Locate some local-dynamic symbol still in use by this function
3768 so that we can print its name in local-dynamic base patterns. */
3770 static const char *
3771 get_some_local_dynamic_name (void)
3773 rtx insn;
3775 if (cfun->machine->some_ld_name)
3776 return cfun->machine->some_ld_name;
3778 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
3779 if (INSN_P (insn)
3780 && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
3781 return cfun->machine->some_ld_name;
3783 abort ();
3786 static int
3787 get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
3789 rtx x = *px;
3791 if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
3793 x = get_pool_constant (x);
3794 return for_each_rtx (&x, get_some_local_dynamic_name_1, 0);
3797 if (GET_CODE (x) == SYMBOL_REF
3798 && tls_symbolic_operand (x) == TLS_MODEL_LOCAL_DYNAMIC)
3800 cfun->machine->some_ld_name = XSTR (x, 0);
3801 return 1;
3804 return 0;
3807 /* Output machine-dependent UNSPECs occurring in address constant X
3808 in assembler syntax to stdio stream FILE. Returns true if the
3809 constant X could be recognized, false otherwise. */
3811 bool
3812 s390_output_addr_const_extra (FILE *file, rtx x)
3814 if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 1)
3815 switch (XINT (x, 1))
3817 case UNSPEC_GOTENT:
3818 output_addr_const (file, XVECEXP (x, 0, 0));
3819 fprintf (file, "@GOTENT");
3820 return true;
3821 case UNSPEC_GOT:
3822 output_addr_const (file, XVECEXP (x, 0, 0));
3823 fprintf (file, "@GOT");
3824 return true;
3825 case UNSPEC_GOTOFF:
3826 output_addr_const (file, XVECEXP (x, 0, 0));
3827 fprintf (file, "@GOTOFF");
3828 return true;
3829 case UNSPEC_PLT:
3830 output_addr_const (file, XVECEXP (x, 0, 0));
3831 fprintf (file, "@PLT");
3832 return true;
3833 case UNSPEC_PLTOFF:
3834 output_addr_const (file, XVECEXP (x, 0, 0));
3835 fprintf (file, "@PLTOFF");
3836 return true;
3837 case UNSPEC_TLSGD:
3838 output_addr_const (file, XVECEXP (x, 0, 0));
3839 fprintf (file, "@TLSGD");
3840 return true;
3841 case UNSPEC_TLSLDM:
3842 assemble_name (file, get_some_local_dynamic_name ());
3843 fprintf (file, "@TLSLDM");
3844 return true;
3845 case UNSPEC_DTPOFF:
3846 output_addr_const (file, XVECEXP (x, 0, 0));
3847 fprintf (file, "@DTPOFF");
3848 return true;
3849 case UNSPEC_NTPOFF:
3850 output_addr_const (file, XVECEXP (x, 0, 0));
3851 fprintf (file, "@NTPOFF");
3852 return true;
3853 case UNSPEC_GOTNTPOFF:
3854 output_addr_const (file, XVECEXP (x, 0, 0));
3855 fprintf (file, "@GOTNTPOFF");
3856 return true;
3857 case UNSPEC_INDNTPOFF:
3858 output_addr_const (file, XVECEXP (x, 0, 0));
3859 fprintf (file, "@INDNTPOFF");
3860 return true;
3863 return false;
3866 /* Output address operand ADDR in assembler syntax to
3867 stdio stream FILE. */
3869 void
3870 print_operand_address (FILE *file, rtx addr)
3872 struct s390_address ad;
3874 if (!s390_decompose_address (addr, &ad)
3875 || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
3876 || (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
3877 output_operand_lossage ("Cannot decompose address.");
3879 if (ad.disp)
3880 output_addr_const (file, ad.disp);
3881 else
3882 fprintf (file, "0");
3884 if (ad.base && ad.indx)
3885 fprintf (file, "(%s,%s)", reg_names[REGNO (ad.indx)],
3886 reg_names[REGNO (ad.base)]);
3887 else if (ad.base)
3888 fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
3891 /* Output operand X in assembler syntax to stdio stream FILE.
3892 CODE specified the format flag. The following format flags
3893 are recognized:
3895 'C': print opcode suffix for branch condition.
3896 'D': print opcode suffix for inverse branch condition.
3897 'J': print tls_load/tls_gdcall/tls_ldcall suffix
3898 'O': print only the displacement of a memory reference.
3899 'R': print only the base register of a memory reference.
3900 'N': print the second word of a DImode operand.
3901 'M': print the second word of a TImode operand.
3902 'Y': print shift count operand.
3904 'b': print integer X as if it's an unsigned byte.
3905 'x': print integer X as if it's an unsigned word.
3906 'h': print integer X as if it's a signed word.
3907 'i': print the first nonzero HImode part of X.
3908 'j': print the first HImode part unequal to 0xffff of X. */
3910 void
3911 print_operand (FILE *file, rtx x, int code)
3913 switch (code)
3915 case 'C':
3916 fprintf (file, s390_branch_condition_mnemonic (x, FALSE));
3917 return;
3919 case 'D':
3920 fprintf (file, s390_branch_condition_mnemonic (x, TRUE));
3921 return;
3923 case 'J':
3924 if (GET_CODE (x) == SYMBOL_REF)
3926 fprintf (file, "%s", ":tls_load:");
3927 output_addr_const (file, x);
3929 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD)
3931 fprintf (file, "%s", ":tls_gdcall:");
3932 output_addr_const (file, XVECEXP (x, 0, 0));
3934 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM)
3936 fprintf (file, "%s", ":tls_ldcall:");
3937 assemble_name (file, get_some_local_dynamic_name ());
3939 else
3940 abort ();
3941 return;
3943 case 'O':
3945 struct s390_address ad;
3947 if (GET_CODE (x) != MEM
3948 || !s390_decompose_address (XEXP (x, 0), &ad)
3949 || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
3950 || ad.indx)
3951 abort ();
3953 if (ad.disp)
3954 output_addr_const (file, ad.disp);
3955 else
3956 fprintf (file, "0");
3958 return;
3960 case 'R':
3962 struct s390_address ad;
3964 if (GET_CODE (x) != MEM
3965 || !s390_decompose_address (XEXP (x, 0), &ad)
3966 || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
3967 || ad.indx)
3968 abort ();
3970 if (ad.base)
3971 fprintf (file, "%s", reg_names[REGNO (ad.base)]);
3972 else
3973 fprintf (file, "0");
3975 return;
3977 case 'N':
3978 if (GET_CODE (x) == REG)
3979 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
3980 else if (GET_CODE (x) == MEM)
3981 x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 4));
3982 else
3983 abort ();
3984 break;
3986 case 'M':
3987 if (GET_CODE (x) == REG)
3988 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
3989 else if (GET_CODE (x) == MEM)
3990 x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 8));
3991 else
3992 abort ();
3993 break;
3995 case 'Y':
3996 print_shift_count_operand (file, x);
3997 return;
4000 switch (GET_CODE (x))
4002 case REG:
4003 fprintf (file, "%s", reg_names[REGNO (x)]);
4004 break;
4006 case MEM:
4007 output_address (XEXP (x, 0));
4008 break;
4010 case CONST:
4011 case CODE_LABEL:
4012 case LABEL_REF:
4013 case SYMBOL_REF:
4014 output_addr_const (file, x);
4015 break;
4017 case CONST_INT:
4018 if (code == 'b')
4019 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xff);
4020 else if (code == 'x')
4021 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffff);
4022 else if (code == 'h')
4023 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000);
4024 else if (code == 'i')
4025 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4026 s390_extract_part (x, HImode, 0));
4027 else if (code == 'j')
4028 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4029 s390_extract_part (x, HImode, -1));
4030 else
4031 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
4032 break;
4034 case CONST_DOUBLE:
4035 if (GET_MODE (x) != VOIDmode)
4036 abort ();
4037 if (code == 'b')
4038 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xff);
4039 else if (code == 'x')
4040 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xffff);
4041 else if (code == 'h')
4042 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((CONST_DOUBLE_LOW (x) & 0xffff) ^ 0x8000) - 0x8000);
4043 else
4044 abort ();
4045 break;
4047 default:
4048 fatal_insn ("UNKNOWN in print_operand !?", x);
4049 break;
4053 /* Target hook for assembling integer objects. We need to define it
4054 here to work a round a bug in some versions of GAS, which couldn't
4055 handle values smaller than INT_MIN when printed in decimal. */
4057 static bool
4058 s390_assemble_integer (rtx x, unsigned int size, int aligned_p)
4060 if (size == 8 && aligned_p
4061 && GET_CODE (x) == CONST_INT && INTVAL (x) < INT_MIN)
4063 fprintf (asm_out_file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n",
4064 INTVAL (x));
4065 return true;
4067 return default_assemble_integer (x, size, aligned_p);
4070 /* Returns true if register REGNO is used for forming
4071 a memory address in expression X. */
4073 static int
4074 reg_used_in_mem_p (int regno, rtx x)
4076 enum rtx_code code = GET_CODE (x);
4077 int i, j;
4078 const char *fmt;
4080 if (code == MEM)
4082 if (refers_to_regno_p (regno, regno+1,
4083 XEXP (x, 0), 0))
4084 return 1;
4086 else if (code == SET
4087 && GET_CODE (SET_DEST (x)) == PC)
4089 if (refers_to_regno_p (regno, regno+1,
4090 SET_SRC (x), 0))
4091 return 1;
4094 fmt = GET_RTX_FORMAT (code);
4095 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4097 if (fmt[i] == 'e'
4098 && reg_used_in_mem_p (regno, XEXP (x, i)))
4099 return 1;
4101 else if (fmt[i] == 'E')
4102 for (j = 0; j < XVECLEN (x, i); j++)
4103 if (reg_used_in_mem_p (regno, XVECEXP (x, i, j)))
4104 return 1;
4106 return 0;
4109 /* Returns true if expression DEP_RTX sets an address register
4110 used by instruction INSN to address memory. */
4112 static int
4113 addr_generation_dependency_p (rtx dep_rtx, rtx insn)
4115 rtx target, pat;
4117 if (GET_CODE (dep_rtx) == INSN)
4118 dep_rtx = PATTERN (dep_rtx);
4120 if (GET_CODE (dep_rtx) == SET)
4122 target = SET_DEST (dep_rtx);
4123 if (GET_CODE (target) == STRICT_LOW_PART)
4124 target = XEXP (target, 0);
4125 while (GET_CODE (target) == SUBREG)
4126 target = SUBREG_REG (target);
4128 if (GET_CODE (target) == REG)
4130 int regno = REGNO (target);
4132 if (s390_safe_attr_type (insn) == TYPE_LA)
4134 pat = PATTERN (insn);
4135 if (GET_CODE (pat) == PARALLEL)
4137 if (XVECLEN (pat, 0) != 2)
4138 abort();
4139 pat = XVECEXP (pat, 0, 0);
4141 if (GET_CODE (pat) == SET)
4142 return refers_to_regno_p (regno, regno+1, SET_SRC (pat), 0);
4143 else
4144 abort();
4146 else if (get_attr_atype (insn) == ATYPE_AGEN)
4147 return reg_used_in_mem_p (regno, PATTERN (insn));
4150 return 0;
4153 /* Return 1, if dep_insn sets register used in insn in the agen unit. */
4156 s390_agen_dep_p (rtx dep_insn, rtx insn)
4158 rtx dep_rtx = PATTERN (dep_insn);
4159 int i;
4161 if (GET_CODE (dep_rtx) == SET
4162 && addr_generation_dependency_p (dep_rtx, insn))
4163 return 1;
4164 else if (GET_CODE (dep_rtx) == PARALLEL)
4166 for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
4168 if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i), insn))
4169 return 1;
4172 return 0;
4175 /* Return the modified cost of the dependency of instruction INSN
4176 on instruction DEP_INSN through the link LINK. COST is the
4177 default cost of that dependency.
4179 Data dependencies are all handled without delay. However, if a
4180 register is modified and subsequently used as base or index
4181 register of a memory reference, at least 4 cycles need to pass
4182 between setting and using the register to avoid pipeline stalls.
4183 An exception is the LA instruction. An address generated by LA can
4184 be used by introducing only a one cycle stall on the pipeline. */
4186 static int
4187 s390_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
4189 /* If the dependence is an anti-dependence, there is no cost. For an
4190 output dependence, there is sometimes a cost, but it doesn't seem
4191 worth handling those few cases. */
4193 if (REG_NOTE_KIND (link) != 0)
4194 return 0;
4196 /* If we can't recognize the insns, we can't really do anything. */
4197 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
4198 return cost;
4200 /* Operand forward in case of lr, load and la. */
4201 if (s390_tune == PROCESSOR_2084_Z990
4202 && cost == 1
4203 && (s390_safe_attr_type (dep_insn) == TYPE_LA
4204 || s390_safe_attr_type (dep_insn) == TYPE_LR
4205 || s390_safe_attr_type (dep_insn) == TYPE_LOAD))
4206 return 0;
4207 return cost;
4210 /* A C statement (sans semicolon) to update the integer scheduling priority
4211 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
4212 reduce the priority to execute INSN later. Do not define this macro if
4213 you do not need to adjust the scheduling priorities of insns.
4215 A STD instruction should be scheduled earlier,
4216 in order to use the bypass. */
4218 static int
4219 s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
4221 if (! INSN_P (insn))
4222 return priority;
4224 if (s390_tune != PROCESSOR_2084_Z990)
4225 return priority;
4227 switch (s390_safe_attr_type (insn))
4229 case TYPE_FSTORED:
4230 case TYPE_FSTORES:
4231 priority = priority << 3;
4232 break;
4233 case TYPE_STORE:
4234 priority = priority << 1;
4235 break;
4236 default:
4237 break;
4239 return priority;
4242 /* The number of instructions that can be issued per cycle. */
4244 static int
4245 s390_issue_rate (void)
4247 if (s390_tune == PROCESSOR_2084_Z990)
4248 return 3;
4249 return 1;
4252 static int
4253 s390_first_cycle_multipass_dfa_lookahead (void)
4255 return 4;
4259 /* Split all branches that exceed the maximum distance.
4260 Returns true if this created a new literal pool entry. */
4262 static int
4263 s390_split_branches (void)
4265 rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
4266 int new_literal = 0;
4267 rtx insn, pat, tmp, target;
4268 rtx *label;
4270 /* We need correct insn addresses. */
4272 shorten_branches (get_insns ());
4274 /* Find all branches that exceed 64KB, and split them. */
4276 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4278 if (GET_CODE (insn) != JUMP_INSN)
4279 continue;
4281 pat = PATTERN (insn);
4282 if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
4283 pat = XVECEXP (pat, 0, 0);
4284 if (GET_CODE (pat) != SET || SET_DEST (pat) != pc_rtx)
4285 continue;
4287 if (GET_CODE (SET_SRC (pat)) == LABEL_REF)
4289 label = &SET_SRC (pat);
4291 else if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE)
4293 if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF)
4294 label = &XEXP (SET_SRC (pat), 1);
4295 else if (GET_CODE (XEXP (SET_SRC (pat), 2)) == LABEL_REF)
4296 label = &XEXP (SET_SRC (pat), 2);
4297 else
4298 continue;
4300 else
4301 continue;
4303 if (get_attr_length (insn) <= 4)
4304 continue;
4306 /* We are going to use the return register as scratch register,
4307 make sure it will be saved/restored by the prologue/epilogue. */
4308 cfun_frame_layout.save_return_addr_p = 1;
4310 if (!flag_pic)
4312 new_literal = 1;
4313 tmp = force_const_mem (Pmode, *label);
4314 tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, tmp), insn);
4315 INSN_ADDRESSES_NEW (tmp, -1);
4316 annotate_constant_pool_refs (&PATTERN (tmp));
4318 target = temp_reg;
4320 else
4322 new_literal = 1;
4323 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, *label),
4324 UNSPEC_LTREL_OFFSET);
4325 target = gen_rtx_CONST (Pmode, target);
4326 target = force_const_mem (Pmode, target);
4327 tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, target), insn);
4328 INSN_ADDRESSES_NEW (tmp, -1);
4329 annotate_constant_pool_refs (&PATTERN (tmp));
4331 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, XEXP (target, 0),
4332 cfun->machine->base_reg),
4333 UNSPEC_LTREL_BASE);
4334 target = gen_rtx_PLUS (Pmode, temp_reg, target);
4337 if (!validate_change (insn, label, target, 0))
4338 abort ();
4341 return new_literal;
4344 /* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
4345 Fix up MEMs as required. */
4347 static void
4348 annotate_constant_pool_refs (rtx *x)
4350 int i, j;
4351 const char *fmt;
4353 if (GET_CODE (*x) == SYMBOL_REF
4354 && CONSTANT_POOL_ADDRESS_P (*x))
4355 abort ();
4357 /* Literal pool references can only occur inside a MEM ... */
4358 if (GET_CODE (*x) == MEM)
4360 rtx memref = XEXP (*x, 0);
4362 if (GET_CODE (memref) == SYMBOL_REF
4363 && CONSTANT_POOL_ADDRESS_P (memref))
4365 rtx base = cfun->machine->base_reg;
4366 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, memref, base),
4367 UNSPEC_LTREF);
4369 *x = replace_equiv_address (*x, addr);
4370 return;
4373 if (GET_CODE (memref) == CONST
4374 && GET_CODE (XEXP (memref, 0)) == PLUS
4375 && GET_CODE (XEXP (XEXP (memref, 0), 1)) == CONST_INT
4376 && GET_CODE (XEXP (XEXP (memref, 0), 0)) == SYMBOL_REF
4377 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (memref, 0), 0)))
4379 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (memref, 0), 1));
4380 rtx sym = XEXP (XEXP (memref, 0), 0);
4381 rtx base = cfun->machine->base_reg;
4382 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, sym, base),
4383 UNSPEC_LTREF);
4385 *x = replace_equiv_address (*x, plus_constant (addr, off));
4386 return;
4390 /* ... or a load-address type pattern. */
4391 if (GET_CODE (*x) == SET)
4393 rtx addrref = SET_SRC (*x);
4395 if (GET_CODE (addrref) == SYMBOL_REF
4396 && CONSTANT_POOL_ADDRESS_P (addrref))
4398 rtx base = cfun->machine->base_reg;
4399 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, addrref, base),
4400 UNSPEC_LTREF);
4402 SET_SRC (*x) = addr;
4403 return;
4406 if (GET_CODE (addrref) == CONST
4407 && GET_CODE (XEXP (addrref, 0)) == PLUS
4408 && GET_CODE (XEXP (XEXP (addrref, 0), 1)) == CONST_INT
4409 && GET_CODE (XEXP (XEXP (addrref, 0), 0)) == SYMBOL_REF
4410 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (addrref, 0), 0)))
4412 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (addrref, 0), 1));
4413 rtx sym = XEXP (XEXP (addrref, 0), 0);
4414 rtx base = cfun->machine->base_reg;
4415 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, sym, base),
4416 UNSPEC_LTREF);
4418 SET_SRC (*x) = plus_constant (addr, off);
4419 return;
4423 /* Annotate LTREL_BASE as well. */
4424 if (GET_CODE (*x) == UNSPEC
4425 && XINT (*x, 1) == UNSPEC_LTREL_BASE)
4427 rtx base = cfun->machine->base_reg;
4428 *x = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, XVECEXP (*x, 0, 0), base),
4429 UNSPEC_LTREL_BASE);
4430 return;
4433 fmt = GET_RTX_FORMAT (GET_CODE (*x));
4434 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
4436 if (fmt[i] == 'e')
4438 annotate_constant_pool_refs (&XEXP (*x, i));
4440 else if (fmt[i] == 'E')
4442 for (j = 0; j < XVECLEN (*x, i); j++)
4443 annotate_constant_pool_refs (&XVECEXP (*x, i, j));
4449 /* Find an annotated literal pool symbol referenced in RTX X,
4450 and store it at REF. Will abort if X contains references to
4451 more than one such pool symbol; multiple references to the same
4452 symbol are allowed, however.
4454 The rtx pointed to by REF must be initialized to NULL_RTX
4455 by the caller before calling this routine. */
4457 static void
4458 find_constant_pool_ref (rtx x, rtx *ref)
4460 int i, j;
4461 const char *fmt;
4463 /* Ignore LTREL_BASE references. */
4464 if (GET_CODE (x) == UNSPEC
4465 && XINT (x, 1) == UNSPEC_LTREL_BASE)
4466 return;
4467 /* Likewise POOL_ENTRY insns. */
4468 if (GET_CODE (x) == UNSPEC_VOLATILE
4469 && XINT (x, 1) == UNSPECV_POOL_ENTRY)
4470 return;
4472 if (GET_CODE (x) == SYMBOL_REF
4473 && CONSTANT_POOL_ADDRESS_P (x))
4474 abort ();
4476 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_LTREF)
4478 rtx sym = XVECEXP (x, 0, 0);
4479 if (GET_CODE (sym) != SYMBOL_REF
4480 || !CONSTANT_POOL_ADDRESS_P (sym))
4481 abort ();
4483 if (*ref == NULL_RTX)
4484 *ref = sym;
4485 else if (*ref != sym)
4486 abort ();
4488 return;
4491 fmt = GET_RTX_FORMAT (GET_CODE (x));
4492 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4494 if (fmt[i] == 'e')
4496 find_constant_pool_ref (XEXP (x, i), ref);
4498 else if (fmt[i] == 'E')
4500 for (j = 0; j < XVECLEN (x, i); j++)
4501 find_constant_pool_ref (XVECEXP (x, i, j), ref);
4506 /* Replace every reference to the annotated literal pool
4507 symbol REF in X by its base plus OFFSET. */
4509 static void
4510 replace_constant_pool_ref (rtx *x, rtx ref, rtx offset)
4512 int i, j;
4513 const char *fmt;
4515 if (*x == ref)
4516 abort ();
4518 if (GET_CODE (*x) == UNSPEC
4519 && XINT (*x, 1) == UNSPEC_LTREF
4520 && XVECEXP (*x, 0, 0) == ref)
4522 *x = gen_rtx_PLUS (Pmode, XVECEXP (*x, 0, 1), offset);
4523 return;
4526 if (GET_CODE (*x) == PLUS
4527 && GET_CODE (XEXP (*x, 1)) == CONST_INT
4528 && GET_CODE (XEXP (*x, 0)) == UNSPEC
4529 && XINT (XEXP (*x, 0), 1) == UNSPEC_LTREF
4530 && XVECEXP (XEXP (*x, 0), 0, 0) == ref)
4532 rtx addr = gen_rtx_PLUS (Pmode, XVECEXP (XEXP (*x, 0), 0, 1), offset);
4533 *x = plus_constant (addr, INTVAL (XEXP (*x, 1)));
4534 return;
4537 fmt = GET_RTX_FORMAT (GET_CODE (*x));
4538 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
4540 if (fmt[i] == 'e')
4542 replace_constant_pool_ref (&XEXP (*x, i), ref, offset);
4544 else if (fmt[i] == 'E')
4546 for (j = 0; j < XVECLEN (*x, i); j++)
4547 replace_constant_pool_ref (&XVECEXP (*x, i, j), ref, offset);
4552 /* Check whether X contains an UNSPEC_LTREL_BASE.
4553 Return its constant pool symbol if found, NULL_RTX otherwise. */
4555 static rtx
4556 find_ltrel_base (rtx x)
4558 int i, j;
4559 const char *fmt;
4561 if (GET_CODE (x) == UNSPEC
4562 && XINT (x, 1) == UNSPEC_LTREL_BASE)
4563 return XVECEXP (x, 0, 0);
4565 fmt = GET_RTX_FORMAT (GET_CODE (x));
4566 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4568 if (fmt[i] == 'e')
4570 rtx fnd = find_ltrel_base (XEXP (x, i));
4571 if (fnd)
4572 return fnd;
4574 else if (fmt[i] == 'E')
4576 for (j = 0; j < XVECLEN (x, i); j++)
4578 rtx fnd = find_ltrel_base (XVECEXP (x, i, j));
4579 if (fnd)
4580 return fnd;
4585 return NULL_RTX;
4588 /* Replace any occurrence of UNSPEC_LTREL_BASE in X with its base. */
4590 static void
4591 replace_ltrel_base (rtx *x)
4593 int i, j;
4594 const char *fmt;
4596 if (GET_CODE (*x) == UNSPEC
4597 && XINT (*x, 1) == UNSPEC_LTREL_BASE)
4599 *x = XVECEXP (*x, 0, 1);
4600 return;
4603 fmt = GET_RTX_FORMAT (GET_CODE (*x));
4604 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
4606 if (fmt[i] == 'e')
4608 replace_ltrel_base (&XEXP (*x, i));
4610 else if (fmt[i] == 'E')
4612 for (j = 0; j < XVECLEN (*x, i); j++)
4613 replace_ltrel_base (&XVECEXP (*x, i, j));
4619 /* We keep a list of constants which we have to add to internal
4620 constant tables in the middle of large functions. */
4622 #define NR_C_MODES 7
4623 enum machine_mode constant_modes[NR_C_MODES] =
4625 TImode,
4626 DFmode, DImode,
4627 SFmode, SImode,
4628 HImode,
4629 QImode
4632 struct constant
4634 struct constant *next;
4635 rtx value;
4636 rtx label;
4639 struct constant_pool
4641 struct constant_pool *next;
4642 rtx first_insn;
4643 rtx pool_insn;
4644 bitmap insns;
4646 struct constant *constants[NR_C_MODES];
4647 rtx label;
4648 int size;
4651 static struct constant_pool * s390_mainpool_start (void);
4652 static void s390_mainpool_finish (struct constant_pool *);
4653 static void s390_mainpool_cancel (struct constant_pool *);
4655 static struct constant_pool * s390_chunkify_start (void);
4656 static void s390_chunkify_finish (struct constant_pool *);
4657 static void s390_chunkify_cancel (struct constant_pool *);
4659 static struct constant_pool *s390_start_pool (struct constant_pool **, rtx);
4660 static void s390_end_pool (struct constant_pool *, rtx);
4661 static void s390_add_pool_insn (struct constant_pool *, rtx);
4662 static struct constant_pool *s390_find_pool (struct constant_pool *, rtx);
4663 static void s390_add_constant (struct constant_pool *, rtx, enum machine_mode);
4664 static rtx s390_find_constant (struct constant_pool *, rtx, enum machine_mode);
4665 static rtx s390_dump_pool (struct constant_pool *, bool);
4666 static struct constant_pool *s390_alloc_pool (void);
4667 static void s390_free_pool (struct constant_pool *);
4669 /* Create new constant pool covering instructions starting at INSN
4670 and chain it to the end of POOL_LIST. */
4672 static struct constant_pool *
4673 s390_start_pool (struct constant_pool **pool_list, rtx insn)
4675 struct constant_pool *pool, **prev;
4677 pool = s390_alloc_pool ();
4678 pool->first_insn = insn;
4680 for (prev = pool_list; *prev; prev = &(*prev)->next)
4682 *prev = pool;
4684 return pool;
4687 /* End range of instructions covered by POOL at INSN and emit
4688 placeholder insn representing the pool. */
4690 static void
4691 s390_end_pool (struct constant_pool *pool, rtx insn)
4693 rtx pool_size = GEN_INT (pool->size + 8 /* alignment slop */);
4695 if (!insn)
4696 insn = get_last_insn ();
4698 pool->pool_insn = emit_insn_after (gen_pool (pool_size), insn);
4699 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
4702 /* Add INSN to the list of insns covered by POOL. */
4704 static void
4705 s390_add_pool_insn (struct constant_pool *pool, rtx insn)
4707 bitmap_set_bit (pool->insns, INSN_UID (insn));
4710 /* Return pool out of POOL_LIST that covers INSN. */
4712 static struct constant_pool *
4713 s390_find_pool (struct constant_pool *pool_list, rtx insn)
4715 struct constant_pool *pool;
4717 for (pool = pool_list; pool; pool = pool->next)
4718 if (bitmap_bit_p (pool->insns, INSN_UID (insn)))
4719 break;
4721 return pool;
4724 /* Add constant VAL of mode MODE to the constant pool POOL. */
4726 static void
4727 s390_add_constant (struct constant_pool *pool, rtx val, enum machine_mode mode)
4729 struct constant *c;
4730 int i;
4732 for (i = 0; i < NR_C_MODES; i++)
4733 if (constant_modes[i] == mode)
4734 break;
4735 if (i == NR_C_MODES)
4736 abort ();
4738 for (c = pool->constants[i]; c != NULL; c = c->next)
4739 if (rtx_equal_p (val, c->value))
4740 break;
4742 if (c == NULL)
4744 c = (struct constant *) xmalloc (sizeof *c);
4745 c->value = val;
4746 c->label = gen_label_rtx ();
4747 c->next = pool->constants[i];
4748 pool->constants[i] = c;
4749 pool->size += GET_MODE_SIZE (mode);
4753 /* Find constant VAL of mode MODE in the constant pool POOL.
4754 Return an RTX describing the distance from the start of
4755 the pool to the location of the new constant. */
4757 static rtx
4758 s390_find_constant (struct constant_pool *pool, rtx val,
4759 enum machine_mode mode)
4761 struct constant *c;
4762 rtx offset;
4763 int i;
4765 for (i = 0; i < NR_C_MODES; i++)
4766 if (constant_modes[i] == mode)
4767 break;
4768 if (i == NR_C_MODES)
4769 abort ();
4771 for (c = pool->constants[i]; c != NULL; c = c->next)
4772 if (rtx_equal_p (val, c->value))
4773 break;
4775 if (c == NULL)
4776 abort ();
4778 offset = gen_rtx_MINUS (Pmode, gen_rtx_LABEL_REF (Pmode, c->label),
4779 gen_rtx_LABEL_REF (Pmode, pool->label));
4780 offset = gen_rtx_CONST (Pmode, offset);
4781 return offset;
4784 /* Dump out the constants in POOL. If REMOTE_LABEL is true,
4785 do not emit the pool base label. */
4787 static rtx
4788 s390_dump_pool (struct constant_pool *pool, bool remote_label)
4790 struct constant *c;
4791 rtx insn;
4792 int i;
4794 /* Pool start insn switches to proper section
4795 and guarantees necessary alignment. */
4796 if (TARGET_CPU_ZARCH)
4797 insn = emit_insn_after (gen_pool_start_64 (), pool->pool_insn);
4798 else
4799 insn = emit_insn_after (gen_pool_start_31 (), pool->pool_insn);
4800 INSN_ADDRESSES_NEW (insn, -1);
4802 if (!remote_label)
4804 insn = emit_label_after (pool->label, insn);
4805 INSN_ADDRESSES_NEW (insn, -1);
4808 /* Dump constants in descending alignment requirement order,
4809 ensuring proper alignment for every constant. */
4810 for (i = 0; i < NR_C_MODES; i++)
4811 for (c = pool->constants[i]; c; c = c->next)
4813 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
4814 rtx value = c->value;
4815 if (GET_CODE (value) == CONST
4816 && GET_CODE (XEXP (value, 0)) == UNSPEC
4817 && XINT (XEXP (value, 0), 1) == UNSPEC_LTREL_OFFSET
4818 && XVECLEN (XEXP (value, 0), 0) == 1)
4820 value = gen_rtx_MINUS (Pmode, XVECEXP (XEXP (value, 0), 0, 0),
4821 gen_rtx_LABEL_REF (VOIDmode, pool->label));
4822 value = gen_rtx_CONST (VOIDmode, value);
4825 insn = emit_label_after (c->label, insn);
4826 INSN_ADDRESSES_NEW (insn, -1);
4828 value = gen_rtx_UNSPEC_VOLATILE (constant_modes[i],
4829 gen_rtvec (1, value),
4830 UNSPECV_POOL_ENTRY);
4831 insn = emit_insn_after (value, insn);
4832 INSN_ADDRESSES_NEW (insn, -1);
4835 /* Pool end insn switches back to previous section
4836 and guarantees necessary alignment. */
4837 if (TARGET_CPU_ZARCH)
4838 insn = emit_insn_after (gen_pool_end_64 (), insn);
4839 else
4840 insn = emit_insn_after (gen_pool_end_31 (), insn);
4841 INSN_ADDRESSES_NEW (insn, -1);
4843 insn = emit_barrier_after (insn);
4844 INSN_ADDRESSES_NEW (insn, -1);
4846 /* Remove placeholder insn. */
4847 remove_insn (pool->pool_insn);
4849 return insn;
4852 /* Allocate new constant_pool structure. */
4854 static struct constant_pool *
4855 s390_alloc_pool (void)
4857 struct constant_pool *pool;
4858 int i;
4860 pool = (struct constant_pool *) xmalloc (sizeof *pool);
4861 pool->next = NULL;
4862 for (i = 0; i < NR_C_MODES; i++)
4863 pool->constants[i] = NULL;
4865 pool->label = gen_label_rtx ();
4866 pool->first_insn = NULL_RTX;
4867 pool->pool_insn = NULL_RTX;
4868 pool->insns = BITMAP_XMALLOC ();
4869 pool->size = 0;
4871 return pool;
4874 /* Free all memory used by POOL. */
4876 static void
4877 s390_free_pool (struct constant_pool *pool)
4879 int i;
4881 for (i = 0; i < NR_C_MODES; i++)
4883 struct constant *c = pool->constants[i];
4884 while (c != NULL)
4886 struct constant *next = c->next;
4887 free (c);
4888 c = next;
4892 BITMAP_XFREE (pool->insns);
4893 free (pool);
4897 /* Collect main literal pool. Return NULL on overflow. */
4899 static struct constant_pool *
4900 s390_mainpool_start (void)
4902 struct constant_pool *pool;
4903 rtx insn;
4905 pool = s390_alloc_pool ();
4907 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4909 if (GET_CODE (insn) == INSN
4910 && GET_CODE (PATTERN (insn)) == SET
4911 && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC_VOLATILE
4912 && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPECV_MAIN_POOL)
4914 if (pool->pool_insn)
4915 abort ();
4916 pool->pool_insn = insn;
4919 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
4921 rtx pool_ref = NULL_RTX;
4922 find_constant_pool_ref (PATTERN (insn), &pool_ref);
4923 if (pool_ref)
4925 rtx constant = get_pool_constant (pool_ref);
4926 enum machine_mode mode = get_pool_mode (pool_ref);
4927 s390_add_constant (pool, constant, mode);
4932 if (!pool->pool_insn)
4933 abort ();
4935 if (pool->size >= 4096)
4937 /* We're going to chunkify the pool, so remove the main
4938 pool placeholder insn. */
4939 remove_insn (pool->pool_insn);
4941 s390_free_pool (pool);
4942 pool = NULL;
4945 return pool;
4948 /* POOL holds the main literal pool as collected by s390_mainpool_start.
4949 Modify the current function to output the pool constants as well as
4950 the pool register setup instruction. */
4952 static void
4953 s390_mainpool_finish (struct constant_pool *pool)
4955 rtx base_reg = SET_DEST (PATTERN (pool->pool_insn));
4956 rtx insn;
4958 /* If the pool is empty, we're done. */
4959 if (pool->size == 0)
4961 remove_insn (pool->pool_insn);
4962 s390_free_pool (pool);
4963 return;
4966 /* We need correct insn addresses. */
4967 shorten_branches (get_insns ());
4969 /* On zSeries, we use a LARL to load the pool register. The pool is
4970 located in the .rodata section, so we emit it after the function. */
4971 if (TARGET_CPU_ZARCH)
4973 insn = gen_main_base_64 (base_reg, pool->label);
4974 insn = emit_insn_after (insn, pool->pool_insn);
4975 INSN_ADDRESSES_NEW (insn, -1);
4976 remove_insn (pool->pool_insn);
4978 insn = get_last_insn ();
4979 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
4980 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
4982 s390_dump_pool (pool, 0);
4985 /* On S/390, if the total size of the function's code plus literal pool
4986 does not exceed 4096 bytes, we use BASR to set up a function base
4987 pointer, and emit the literal pool at the end of the function. */
4988 else if (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
4989 + pool->size + 8 /* alignment slop */ < 4096)
4991 insn = gen_main_base_31_small (base_reg, pool->label);
4992 insn = emit_insn_after (insn, pool->pool_insn);
4993 INSN_ADDRESSES_NEW (insn, -1);
4994 remove_insn (pool->pool_insn);
4996 insn = emit_label_after (pool->label, insn);
4997 INSN_ADDRESSES_NEW (insn, -1);
4999 insn = get_last_insn ();
5000 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
5001 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
5003 s390_dump_pool (pool, 1);
5006 /* Otherwise, we emit an inline literal pool and use BASR to branch
5007 over it, setting up the pool register at the same time. */
5008 else
5010 rtx pool_end = gen_label_rtx ();
5012 insn = gen_main_base_31_large (base_reg, pool->label, pool_end);
5013 insn = emit_insn_after (insn, pool->pool_insn);
5014 INSN_ADDRESSES_NEW (insn, -1);
5015 remove_insn (pool->pool_insn);
5017 insn = emit_label_after (pool->label, insn);
5018 INSN_ADDRESSES_NEW (insn, -1);
5020 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
5021 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
5023 insn = emit_label_after (pool_end, pool->pool_insn);
5024 INSN_ADDRESSES_NEW (insn, -1);
5026 s390_dump_pool (pool, 1);
5030 /* Replace all literal pool references. */
5032 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5034 if (INSN_P (insn))
5035 replace_ltrel_base (&PATTERN (insn));
5037 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
5039 rtx addr, pool_ref = NULL_RTX;
5040 find_constant_pool_ref (PATTERN (insn), &pool_ref);
5041 if (pool_ref)
5043 addr = s390_find_constant (pool, get_pool_constant (pool_ref),
5044 get_pool_mode (pool_ref));
5045 replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
5046 INSN_CODE (insn) = -1;
5052 /* Free the pool. */
5053 s390_free_pool (pool);
5056 /* POOL holds the main literal pool as collected by s390_mainpool_start.
5057 We have decided we cannot use this pool, so revert all changes
5058 to the current function that were done by s390_mainpool_start. */
5059 static void
5060 s390_mainpool_cancel (struct constant_pool *pool)
5062 /* We didn't actually change the instruction stream, so simply
5063 free the pool memory. */
5064 s390_free_pool (pool);
5068 /* Chunkify the literal pool. */
5070 #define S390_POOL_CHUNK_MIN 0xc00
5071 #define S390_POOL_CHUNK_MAX 0xe00
5073 static struct constant_pool *
5074 s390_chunkify_start (void)
5076 struct constant_pool *curr_pool = NULL, *pool_list = NULL;
5077 int extra_size = 0;
5078 bitmap far_labels;
5079 rtx pending_ltrel = NULL_RTX;
5080 rtx insn;
5082 rtx (*gen_reload_base) (rtx, rtx) =
5083 TARGET_CPU_ZARCH? gen_reload_base_64 : gen_reload_base_31;
5086 /* We need correct insn addresses. */
5088 shorten_branches (get_insns ());
5090 /* Scan all insns and move literals to pool chunks. */
5092 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5094 /* Check for pending LTREL_BASE. */
5095 if (INSN_P (insn))
5097 rtx ltrel_base = find_ltrel_base (PATTERN (insn));
5098 if (ltrel_base)
5100 if (ltrel_base == pending_ltrel)
5101 pending_ltrel = NULL_RTX;
5102 else
5103 abort ();
5107 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
5109 rtx pool_ref = NULL_RTX;
5110 find_constant_pool_ref (PATTERN (insn), &pool_ref);
5111 if (pool_ref)
5113 rtx constant = get_pool_constant (pool_ref);
5114 enum machine_mode mode = get_pool_mode (pool_ref);
5116 if (!curr_pool)
5117 curr_pool = s390_start_pool (&pool_list, insn);
5119 s390_add_constant (curr_pool, constant, mode);
5120 s390_add_pool_insn (curr_pool, insn);
5122 /* Don't split the pool chunk between a LTREL_OFFSET load
5123 and the corresponding LTREL_BASE. */
5124 if (GET_CODE (constant) == CONST
5125 && GET_CODE (XEXP (constant, 0)) == UNSPEC
5126 && XINT (XEXP (constant, 0), 1) == UNSPEC_LTREL_OFFSET)
5128 if (pending_ltrel)
5129 abort ();
5130 pending_ltrel = pool_ref;
5135 if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CODE_LABEL)
5137 if (curr_pool)
5138 s390_add_pool_insn (curr_pool, insn);
5139 /* An LTREL_BASE must follow within the same basic block. */
5140 if (pending_ltrel)
5141 abort ();
5144 if (!curr_pool
5145 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn)
5146 || INSN_ADDRESSES (INSN_UID (insn)) == -1)
5147 continue;
5149 if (TARGET_CPU_ZARCH)
5151 if (curr_pool->size < S390_POOL_CHUNK_MAX)
5152 continue;
5154 s390_end_pool (curr_pool, NULL_RTX);
5155 curr_pool = NULL;
5157 else
5159 int chunk_size = INSN_ADDRESSES (INSN_UID (insn))
5160 - INSN_ADDRESSES (INSN_UID (curr_pool->first_insn))
5161 + extra_size;
5163 /* We will later have to insert base register reload insns.
5164 Those will have an effect on code size, which we need to
5165 consider here. This calculation makes rather pessimistic
5166 worst-case assumptions. */
5167 if (GET_CODE (insn) == CODE_LABEL)
5168 extra_size += 6;
5170 if (chunk_size < S390_POOL_CHUNK_MIN
5171 && curr_pool->size < S390_POOL_CHUNK_MIN)
5172 continue;
5174 /* Pool chunks can only be inserted after BARRIERs ... */
5175 if (GET_CODE (insn) == BARRIER)
5177 s390_end_pool (curr_pool, insn);
5178 curr_pool = NULL;
5179 extra_size = 0;
5182 /* ... so if we don't find one in time, create one. */
5183 else if ((chunk_size > S390_POOL_CHUNK_MAX
5184 || curr_pool->size > S390_POOL_CHUNK_MAX))
5186 rtx label, jump, barrier;
5188 /* We can insert the barrier only after a 'real' insn. */
5189 if (GET_CODE (insn) != INSN && GET_CODE (insn) != CALL_INSN)
5190 continue;
5191 if (get_attr_length (insn) == 0)
5192 continue;
5194 /* Don't separate LTREL_BASE from the corresponding
5195 LTREL_OFFSET load. */
5196 if (pending_ltrel)
5197 continue;
5199 label = gen_label_rtx ();
5200 jump = emit_jump_insn_after (gen_jump (label), insn);
5201 barrier = emit_barrier_after (jump);
5202 insn = emit_label_after (label, barrier);
5203 JUMP_LABEL (jump) = label;
5204 LABEL_NUSES (label) = 1;
5206 INSN_ADDRESSES_NEW (jump, -1);
5207 INSN_ADDRESSES_NEW (barrier, -1);
5208 INSN_ADDRESSES_NEW (insn, -1);
5210 s390_end_pool (curr_pool, barrier);
5211 curr_pool = NULL;
5212 extra_size = 0;
5217 if (curr_pool)
5218 s390_end_pool (curr_pool, NULL_RTX);
5219 if (pending_ltrel)
5220 abort ();
5223 /* Find all labels that are branched into
5224 from an insn belonging to a different chunk. */
5226 far_labels = BITMAP_XMALLOC ();
5228 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5230 /* Labels marked with LABEL_PRESERVE_P can be target
5231 of non-local jumps, so we have to mark them.
5232 The same holds for named labels.
5234 Don't do that, however, if it is the label before
5235 a jump table. */
5237 if (GET_CODE (insn) == CODE_LABEL
5238 && (LABEL_PRESERVE_P (insn) || LABEL_NAME (insn)))
5240 rtx vec_insn = next_real_insn (insn);
5241 rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
5242 PATTERN (vec_insn) : NULL_RTX;
5243 if (!vec_pat
5244 || !(GET_CODE (vec_pat) == ADDR_VEC
5245 || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
5246 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (insn));
5249 /* If we have a direct jump (conditional or unconditional)
5250 or a casesi jump, check all potential targets. */
5251 else if (GET_CODE (insn) == JUMP_INSN)
5253 rtx pat = PATTERN (insn);
5254 if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
5255 pat = XVECEXP (pat, 0, 0);
5257 if (GET_CODE (pat) == SET)
5259 rtx label = JUMP_LABEL (insn);
5260 if (label)
5262 if (s390_find_pool (pool_list, label)
5263 != s390_find_pool (pool_list, insn))
5264 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
5267 else if (GET_CODE (pat) == PARALLEL
5268 && XVECLEN (pat, 0) == 2
5269 && GET_CODE (XVECEXP (pat, 0, 0)) == SET
5270 && GET_CODE (XVECEXP (pat, 0, 1)) == USE
5271 && GET_CODE (XEXP (XVECEXP (pat, 0, 1), 0)) == LABEL_REF)
5273 /* Find the jump table used by this casesi jump. */
5274 rtx vec_label = XEXP (XEXP (XVECEXP (pat, 0, 1), 0), 0);
5275 rtx vec_insn = next_real_insn (vec_label);
5276 rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
5277 PATTERN (vec_insn) : NULL_RTX;
5278 if (vec_pat
5279 && (GET_CODE (vec_pat) == ADDR_VEC
5280 || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
5282 int i, diff_p = GET_CODE (vec_pat) == ADDR_DIFF_VEC;
5284 for (i = 0; i < XVECLEN (vec_pat, diff_p); i++)
5286 rtx label = XEXP (XVECEXP (vec_pat, diff_p, i), 0);
5288 if (s390_find_pool (pool_list, label)
5289 != s390_find_pool (pool_list, insn))
5290 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
5297 /* Insert base register reload insns before every pool. */
5299 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
5301 rtx new_insn = gen_reload_base (cfun->machine->base_reg,
5302 curr_pool->label);
5303 rtx insn = curr_pool->first_insn;
5304 INSN_ADDRESSES_NEW (emit_insn_before (new_insn, insn), -1);
5307 /* Insert base register reload insns at every far label. */
5309 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5310 if (GET_CODE (insn) == CODE_LABEL
5311 && bitmap_bit_p (far_labels, CODE_LABEL_NUMBER (insn)))
5313 struct constant_pool *pool = s390_find_pool (pool_list, insn);
5314 if (pool)
5316 rtx new_insn = gen_reload_base (cfun->machine->base_reg,
5317 pool->label);
5318 INSN_ADDRESSES_NEW (emit_insn_after (new_insn, insn), -1);
5323 BITMAP_XFREE (far_labels);
5326 /* Recompute insn addresses. */
5328 init_insn_lengths ();
5329 shorten_branches (get_insns ());
5331 return pool_list;
5334 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
5335 After we have decided to use this list, finish implementing
5336 all changes to the current function as required. */
5338 static void
5339 s390_chunkify_finish (struct constant_pool *pool_list)
5341 struct constant_pool *curr_pool = NULL;
5342 rtx insn;
5345 /* Replace all literal pool references. */
5347 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5349 if (INSN_P (insn))
5350 replace_ltrel_base (&PATTERN (insn));
5352 curr_pool = s390_find_pool (pool_list, insn);
5353 if (!curr_pool)
5354 continue;
5356 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
5358 rtx addr, pool_ref = NULL_RTX;
5359 find_constant_pool_ref (PATTERN (insn), &pool_ref);
5360 if (pool_ref)
5362 addr = s390_find_constant (curr_pool, get_pool_constant (pool_ref),
5363 get_pool_mode (pool_ref));
5364 replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
5365 INSN_CODE (insn) = -1;
5370 /* Dump out all literal pools. */
5372 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
5373 s390_dump_pool (curr_pool, 0);
5375 /* Free pool list. */
5377 while (pool_list)
5379 struct constant_pool *next = pool_list->next;
5380 s390_free_pool (pool_list);
5381 pool_list = next;
5385 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
5386 We have decided we cannot use this list, so revert all changes
5387 to the current function that were done by s390_chunkify_start. */
5389 static void
5390 s390_chunkify_cancel (struct constant_pool *pool_list)
5392 struct constant_pool *curr_pool = NULL;
5393 rtx insn;
5395 /* Remove all pool placeholder insns. */
5397 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
5399 /* Did we insert an extra barrier? Remove it. */
5400 rtx barrier = PREV_INSN (curr_pool->pool_insn);
5401 rtx jump = barrier? PREV_INSN (barrier) : NULL_RTX;
5402 rtx label = NEXT_INSN (curr_pool->pool_insn);
5404 if (jump && GET_CODE (jump) == JUMP_INSN
5405 && barrier && GET_CODE (barrier) == BARRIER
5406 && label && GET_CODE (label) == CODE_LABEL
5407 && GET_CODE (PATTERN (jump)) == SET
5408 && SET_DEST (PATTERN (jump)) == pc_rtx
5409 && GET_CODE (SET_SRC (PATTERN (jump))) == LABEL_REF
5410 && XEXP (SET_SRC (PATTERN (jump)), 0) == label)
5412 remove_insn (jump);
5413 remove_insn (barrier);
5414 remove_insn (label);
5417 remove_insn (curr_pool->pool_insn);
5420 /* Remove all base register reload insns. */
5422 for (insn = get_insns (); insn; )
5424 rtx next_insn = NEXT_INSN (insn);
5426 if (GET_CODE (insn) == INSN
5427 && GET_CODE (PATTERN (insn)) == SET
5428 && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC
5429 && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPEC_RELOAD_BASE)
5430 remove_insn (insn);
5432 insn = next_insn;
5435 /* Free pool list. */
5437 while (pool_list)
5439 struct constant_pool *next = pool_list->next;
5440 s390_free_pool (pool_list);
5441 pool_list = next;
5446 /* Output the constant pool entry EXP in mode MODE with alignment ALIGN. */
5448 void
5449 s390_output_pool_entry (rtx exp, enum machine_mode mode, unsigned int align)
5451 REAL_VALUE_TYPE r;
5453 switch (GET_MODE_CLASS (mode))
5455 case MODE_FLOAT:
5456 if (GET_CODE (exp) != CONST_DOUBLE)
5457 abort ();
5459 REAL_VALUE_FROM_CONST_DOUBLE (r, exp);
5460 assemble_real (r, mode, align);
5461 break;
5463 case MODE_INT:
5464 assemble_integer (exp, GET_MODE_SIZE (mode), align, 1);
5465 break;
5467 default:
5468 abort ();
5473 /* Rework the prologue/epilogue to avoid saving/restoring
5474 registers unnecessarily. BASE_USED specifies whether
5475 the literal pool base register needs to be saved. */
5477 static void
5478 s390_optimize_prologue (bool base_used)
5480 rtx insn, new_insn, next_insn;
5482 /* Do a final recompute of the frame-related data. */
5484 s390_register_info (base_used, cfun_frame_layout.save_return_addr_p);
5485 regs_ever_live[BASE_REGNUM] = base_used;
5486 regs_ever_live[RETURN_REGNUM] = cfun_frame_layout.save_return_addr_p;
5487 regs_ever_live[STACK_POINTER_REGNUM] = cfun_frame_layout.frame_size > 0;
5489 /* If all special registers are in fact used, there's nothing we
5490 can do, so no point in walking the insn list. */
5492 if (cfun_frame_layout.first_save_gpr <= BASE_REGNUM
5493 && cfun_frame_layout.last_save_gpr >= BASE_REGNUM
5494 && (TARGET_CPU_ZARCH
5495 || (cfun_frame_layout.first_save_gpr <= RETURN_REGNUM
5496 && cfun_frame_layout.last_save_gpr >= RETURN_REGNUM)))
5497 return;
5499 /* Search for prologue/epilogue insns and replace them. */
5501 for (insn = get_insns (); insn; insn = next_insn)
5503 int first, last, off;
5504 rtx set, base, offset;
5506 next_insn = NEXT_INSN (insn);
5508 if (GET_CODE (insn) != INSN)
5509 continue;
5511 if (GET_CODE (PATTERN (insn)) == PARALLEL
5512 && store_multiple_operation (PATTERN (insn), VOIDmode))
5514 set = XVECEXP (PATTERN (insn), 0, 0);
5515 first = REGNO (SET_SRC (set));
5516 last = first + XVECLEN (PATTERN (insn), 0) - 1;
5517 offset = const0_rtx;
5518 base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
5519 off = INTVAL (offset);
5521 if (GET_CODE (base) != REG || off < 0)
5522 continue;
5523 if (REGNO (base) != STACK_POINTER_REGNUM
5524 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
5525 continue;
5526 if (first > BASE_REGNUM || last < BASE_REGNUM)
5527 continue;
5529 if (cfun_frame_layout.first_save_gpr != -1)
5531 new_insn = save_gprs (base,
5532 off + (cfun_frame_layout.first_save_gpr
5533 - first) * UNITS_PER_WORD,
5534 cfun_frame_layout.first_save_gpr,
5535 cfun_frame_layout.last_save_gpr);
5536 new_insn = emit_insn_before (new_insn, insn);
5537 INSN_ADDRESSES_NEW (new_insn, -1);
5540 remove_insn (insn);
5541 continue;
5544 if (GET_CODE (PATTERN (insn)) == SET
5545 && GET_CODE (SET_SRC (PATTERN (insn))) == REG
5546 && REGNO (SET_SRC (PATTERN (insn))) == BASE_REGNUM
5547 && GET_CODE (SET_DEST (PATTERN (insn))) == MEM)
5549 set = PATTERN (insn);
5550 offset = const0_rtx;
5551 base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
5552 off = INTVAL (offset);
5554 if (GET_CODE (base) != REG || off < 0)
5555 continue;
5556 if (REGNO (base) != STACK_POINTER_REGNUM
5557 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
5558 continue;
5559 if (cfun_frame_layout.first_save_gpr != -1)
5561 new_insn = save_gprs (base,
5562 off + (cfun_frame_layout.first_save_gpr
5563 - BASE_REGNUM) * UNITS_PER_WORD,
5564 cfun_frame_layout.first_save_gpr,
5565 cfun_frame_layout.last_save_gpr);
5566 new_insn = emit_insn_before (new_insn, insn);
5567 INSN_ADDRESSES_NEW (new_insn, -1);
5570 remove_insn (insn);
5571 continue;
5574 if (GET_CODE (PATTERN (insn)) == PARALLEL
5575 && load_multiple_operation (PATTERN (insn), VOIDmode))
5577 set = XVECEXP (PATTERN (insn), 0, 0);
5578 first = REGNO (SET_DEST (set));
5579 last = first + XVECLEN (PATTERN (insn), 0) - 1;
5580 offset = const0_rtx;
5581 base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
5582 off = INTVAL (offset);
5584 if (GET_CODE (base) != REG || off < 0)
5585 continue;
5586 if (REGNO (base) != STACK_POINTER_REGNUM
5587 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
5588 continue;
5589 if (first > BASE_REGNUM || last < BASE_REGNUM)
5590 continue;
5592 if (cfun_frame_layout.first_restore_gpr != -1)
5594 new_insn = restore_gprs (base,
5595 off + (cfun_frame_layout.first_restore_gpr
5596 - first) * UNITS_PER_WORD,
5597 cfun_frame_layout.first_restore_gpr,
5598 cfun_frame_layout.last_restore_gpr);
5599 new_insn = emit_insn_before (new_insn, insn);
5600 INSN_ADDRESSES_NEW (new_insn, -1);
5603 remove_insn (insn);
5604 continue;
5607 if (GET_CODE (PATTERN (insn)) == SET
5608 && GET_CODE (SET_DEST (PATTERN (insn))) == REG
5609 && REGNO (SET_DEST (PATTERN (insn))) == BASE_REGNUM
5610 && GET_CODE (SET_SRC (PATTERN (insn))) == MEM)
5612 set = PATTERN (insn);
5613 offset = const0_rtx;
5614 base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
5615 off = INTVAL (offset);
5617 if (GET_CODE (base) != REG || off < 0)
5618 continue;
5619 if (REGNO (base) != STACK_POINTER_REGNUM
5620 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
5621 continue;
5622 if (cfun_frame_layout.first_restore_gpr != -1)
5624 new_insn = restore_gprs (base,
5625 off + (cfun_frame_layout.first_restore_gpr
5626 - BASE_REGNUM) * UNITS_PER_WORD,
5627 cfun_frame_layout.first_restore_gpr,
5628 cfun_frame_layout.last_restore_gpr);
5629 new_insn = emit_insn_before (new_insn, insn);
5630 INSN_ADDRESSES_NEW (new_insn, -1);
5633 remove_insn (insn);
5634 continue;
5639 /* Perform machine-dependent processing. */
5641 static void
5642 s390_reorg (void)
5644 bool base_used = false;
5645 bool pool_overflow = false;
5647 /* Make sure all splits have been performed; splits after
5648 machine_dependent_reorg might confuse insn length counts. */
5649 split_all_insns_noflow ();
5652 /* Install the main literal pool and the associated base
5653 register load insns.
5655 In addition, there are two problematic situations we need
5656 to correct:
5658 - the literal pool might be > 4096 bytes in size, so that
5659 some of its elements cannot be directly accessed
5661 - a branch target might be > 64K away from the branch, so that
5662 it is not possible to use a PC-relative instruction.
5664 To fix those, we split the single literal pool into multiple
5665 pool chunks, reloading the pool base register at various
5666 points throughout the function to ensure it always points to
5667 the pool chunk the following code expects, and / or replace
5668 PC-relative branches by absolute branches.
5670 However, the two problems are interdependent: splitting the
5671 literal pool can move a branch further away from its target,
5672 causing the 64K limit to overflow, and on the other hand,
5673 replacing a PC-relative branch by an absolute branch means
5674 we need to put the branch target address into the literal
5675 pool, possibly causing it to overflow.
5677 So, we loop trying to fix up both problems until we manage
5678 to satisfy both conditions at the same time. Note that the
5679 loop is guaranteed to terminate as every pass of the loop
5680 strictly decreases the total number of PC-relative branches
5681 in the function. (This is not completely true as there
5682 might be branch-over-pool insns introduced by chunkify_start.
5683 Those never need to be split however.) */
5685 for (;;)
5687 struct constant_pool *pool = NULL;
5689 /* Collect the literal pool. */
5690 if (!pool_overflow)
5692 pool = s390_mainpool_start ();
5693 if (!pool)
5694 pool_overflow = true;
5697 /* If literal pool overflowed, start to chunkify it. */
5698 if (pool_overflow)
5699 pool = s390_chunkify_start ();
5701 /* Split out-of-range branches. If this has created new
5702 literal pool entries, cancel current chunk list and
5703 recompute it. zSeries machines have large branch
5704 instructions, so we never need to split a branch. */
5705 if (!TARGET_CPU_ZARCH && s390_split_branches ())
5707 if (pool_overflow)
5708 s390_chunkify_cancel (pool);
5709 else
5710 s390_mainpool_cancel (pool);
5712 continue;
5715 /* If we made it up to here, both conditions are satisfied.
5716 Finish up literal pool related changes. */
5717 if ((pool_overflow || pool->size > 0)
5718 && REGNO (cfun->machine->base_reg) == BASE_REGNUM)
5719 base_used = true;
5721 if (pool_overflow)
5722 s390_chunkify_finish (pool);
5723 else
5724 s390_mainpool_finish (pool);
5726 break;
5729 s390_optimize_prologue (base_used);
5733 /* Return an RTL expression representing the value of the return address
5734 for the frame COUNT steps up from the current frame. FRAME is the
5735 frame pointer of that frame. */
5738 s390_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
5740 int offset;
5741 rtx addr;
5743 /* Without backchain, we fail for all but the current frame. */
5745 if (!TARGET_BACKCHAIN && !TARGET_KERNEL_BACKCHAIN && count > 0)
5746 return NULL_RTX;
5748 /* For the current frame, we need to make sure the initial
5749 value of RETURN_REGNUM is actually saved. */
5751 if (count == 0)
5753 cfun_frame_layout.save_return_addr_p = true;
5754 return gen_rtx_MEM (Pmode, return_address_pointer_rtx);
5757 if (TARGET_BACKCHAIN)
5758 offset = RETURN_REGNUM * UNITS_PER_WORD;
5759 else
5760 offset = -2 * UNITS_PER_WORD;
5762 addr = plus_constant (frame, offset);
5763 addr = memory_address (Pmode, addr);
5764 return gen_rtx_MEM (Pmode, addr);
5767 /* Find first call clobbered register unused in a function.
5768 This could be used as base register in a leaf function
5769 or for holding the return address before epilogue. */
5771 static int
5772 find_unused_clobbered_reg (void)
5774 int i;
5775 for (i = 0; i < 6; i++)
5776 if (!regs_ever_live[i])
5777 return i;
5778 return 0;
5781 /* Determine the frame area which actually has to be accessed
5782 in the function epilogue. The values are stored at the
5783 given pointers AREA_BOTTOM (address of the lowest used stack
5784 address) and AREA_TOP (address of the first item which does
5785 not belong to the stack frame). */
5787 static void
5788 s390_frame_area (int *area_bottom, int *area_top)
5790 int b, t;
5791 int i;
5793 b = INT_MAX;
5794 t = INT_MIN;
5796 if (cfun_frame_layout.first_restore_gpr != -1)
5798 b = (cfun_frame_layout.gprs_offset
5799 + cfun_frame_layout.first_restore_gpr * UNITS_PER_WORD);
5800 t = b + (cfun_frame_layout.last_restore_gpr
5801 - cfun_frame_layout.first_restore_gpr + 1) * UNITS_PER_WORD;
5804 if (TARGET_64BIT && cfun_save_high_fprs_p)
5806 b = MIN (b, cfun_frame_layout.f8_offset);
5807 t = MAX (t, (cfun_frame_layout.f8_offset
5808 + cfun_frame_layout.high_fprs * 8));
5811 if (!TARGET_64BIT)
5812 for (i = 2; i < 4; i++)
5813 if (cfun_fpr_bit_p (i))
5815 b = MIN (b, cfun_frame_layout.f4_offset + (i - 2) * 8);
5816 t = MAX (t, cfun_frame_layout.f4_offset + (i - 1) * 8);
5819 *area_bottom = b;
5820 *area_top = t;
5823 /* Fill cfun->machine with info about register usage of current
5824 function. BASE_USED and RETURN_ADDR_USED specify whether we assume the
5825 base and return address register will need to be saved. */
5827 static void
5828 s390_register_info (int base_used, int return_addr_used)
5830 int live_regs[16];
5831 int i, j;
5833 /* fprs 8 - 15 are call saved for 64 Bit ABI. */
5834 cfun_frame_layout.fpr_bitmap = 0;
5835 cfun_frame_layout.high_fprs = 0;
5836 if (TARGET_64BIT)
5837 for (i = 24; i < 32; i++)
5838 if (regs_ever_live[i] && !global_regs[i])
5840 cfun_set_fpr_bit (i - 16);
5841 cfun_frame_layout.high_fprs++;
5844 /* Find first and last gpr to be saved. We trust regs_ever_live
5845 data, except that we don't save and restore global registers.
5847 Also, all registers with special meaning to the compiler need
5848 to be handled extra. */
5850 for (i = 0; i < 16; i++)
5851 live_regs[i] = regs_ever_live[i] && !global_regs[i];
5853 if (flag_pic)
5854 live_regs[PIC_OFFSET_TABLE_REGNUM] =
5855 regs_ever_live[PIC_OFFSET_TABLE_REGNUM];
5857 live_regs[BASE_REGNUM] = base_used;
5858 live_regs[RETURN_REGNUM] = return_addr_used;
5859 live_regs[STACK_POINTER_REGNUM] = (!current_function_is_leaf
5860 || TARGET_TPF_PROFILING
5861 || cfun_save_high_fprs_p
5862 || get_frame_size () > 0
5863 || current_function_calls_alloca
5864 || current_function_stdarg);
5866 for (i = 6; i < 16; i++)
5867 if (live_regs[i])
5868 break;
5869 for (j = 15; j > i; j--)
5870 if (live_regs[j])
5871 break;
5873 if (i == 16)
5875 /* Nothing to save/restore. */
5876 cfun_frame_layout.first_save_gpr = -1;
5877 cfun_frame_layout.first_restore_gpr = -1;
5878 cfun_frame_layout.last_save_gpr = -1;
5879 cfun_frame_layout.last_restore_gpr = -1;
5881 else
5883 /* Save / Restore from gpr i to j. */
5884 cfun_frame_layout.first_save_gpr = i;
5885 cfun_frame_layout.first_restore_gpr = i;
5886 cfun_frame_layout.last_save_gpr = j;
5887 cfun_frame_layout.last_restore_gpr = j;
5890 if (current_function_stdarg)
5892 /* Varargs functions need to save gprs 2 to 6. */
5893 if (cfun_frame_layout.first_save_gpr == -1
5894 || cfun_frame_layout.first_save_gpr > 2)
5895 cfun_frame_layout.first_save_gpr = 2;
5897 if (cfun_frame_layout.last_save_gpr == -1
5898 || cfun_frame_layout.last_save_gpr < 6)
5899 cfun_frame_layout.last_save_gpr = 6;
5901 /* Mark f0, f2 for 31 bit and f0-f4 for 64 bit to be saved. */
5902 for (i = 0; i < (TARGET_64BIT ? 4 : 2); i++)
5903 cfun_set_fpr_bit (i);
5906 if (!TARGET_64BIT)
5907 for (i = 2; i < 4; i++)
5908 if (regs_ever_live[i + 16] && !global_regs[i + 16])
5909 cfun_set_fpr_bit (i);
5912 /* Fill cfun->machine with info about frame of current
5913 function. BASE_USED and RETURN_ADDR_USED specify whether we assume the
5914 base and return address register will need to be saved. */
5916 static void
5917 s390_frame_info (int base_used, int return_addr_used)
5919 int i;
5921 cfun_frame_layout.frame_size = get_frame_size ();
5923 s390_register_info (base_used, return_addr_used);
5925 if (!TARGET_64BIT && cfun_frame_layout.frame_size > 0x7fff0000)
5926 fatal_error ("Total size of local variables exceeds architecture limit.");
5928 cfun_frame_layout.save_backchain_p = (TARGET_BACKCHAIN
5929 || TARGET_KERNEL_BACKCHAIN);
5931 if (TARGET_BACKCHAIN)
5933 cfun_frame_layout.backchain_offset = 0;
5934 cfun_frame_layout.f0_offset = 16 * UNITS_PER_WORD;
5935 cfun_frame_layout.f4_offset = cfun_frame_layout.f0_offset + 2 * 8;
5936 cfun_frame_layout.f8_offset = -cfun_frame_layout.high_fprs * 8;
5937 cfun_frame_layout.gprs_offset = (cfun_frame_layout.first_save_gpr
5938 * UNITS_PER_WORD);
5940 else if (TARGET_KERNEL_BACKCHAIN)
5942 cfun_frame_layout.backchain_offset = (STACK_POINTER_OFFSET
5943 - UNITS_PER_WORD);
5944 cfun_frame_layout.gprs_offset
5945 = (cfun_frame_layout.backchain_offset
5946 - (STACK_POINTER_REGNUM - cfun_frame_layout.first_save_gpr + 1)
5947 * UNITS_PER_WORD);
5949 if (TARGET_64BIT)
5951 cfun_frame_layout.f4_offset
5952 = (cfun_frame_layout.gprs_offset
5953 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
5955 cfun_frame_layout.f0_offset
5956 = (cfun_frame_layout.f4_offset
5957 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
5959 else
5961 /* On 31 bit we have to care about alignment of the
5962 floating point regs to provide fastest access. */
5963 cfun_frame_layout.f0_offset
5964 = ((cfun_frame_layout.gprs_offset
5965 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1))
5966 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
5968 cfun_frame_layout.f4_offset
5969 = (cfun_frame_layout.f0_offset
5970 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
5973 else /* no backchain */
5975 cfun_frame_layout.f4_offset
5976 = (STACK_POINTER_OFFSET
5977 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
5979 cfun_frame_layout.f0_offset
5980 = (cfun_frame_layout.f4_offset
5981 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
5983 cfun_frame_layout.gprs_offset
5984 = cfun_frame_layout.f0_offset - cfun_gprs_save_area_size;
5987 if (current_function_is_leaf
5988 && !TARGET_TPF_PROFILING
5989 && cfun_frame_layout.frame_size == 0
5990 && !cfun_save_high_fprs_p
5991 && !current_function_calls_alloca
5992 && !current_function_stdarg)
5993 return;
5995 if (TARGET_BACKCHAIN)
5996 cfun_frame_layout.frame_size += (STARTING_FRAME_OFFSET
5997 + cfun_frame_layout.high_fprs * 8);
5998 else
6000 cfun_frame_layout.frame_size += (cfun_frame_layout.save_backchain_p
6001 * UNITS_PER_WORD);
6003 /* No alignment trouble here because f8-f15 are only saved under
6004 64 bit. */
6005 cfun_frame_layout.f8_offset = (MIN (MIN (cfun_frame_layout.f0_offset,
6006 cfun_frame_layout.f4_offset),
6007 cfun_frame_layout.gprs_offset)
6008 - cfun_frame_layout.high_fprs * 8);
6010 cfun_frame_layout.frame_size += cfun_frame_layout.high_fprs * 8;
6012 for (i = 0; i < 8; i++)
6013 if (cfun_fpr_bit_p (i))
6014 cfun_frame_layout.frame_size += 8;
6016 cfun_frame_layout.frame_size += cfun_gprs_save_area_size;
6018 /* If under 31 bit an odd number of gprs has to be saved we have to adjust
6019 the frame size to sustain 8 byte alignment of stack frames. */
6020 cfun_frame_layout.frame_size = ((cfun_frame_layout.frame_size +
6021 STACK_BOUNDARY / BITS_PER_UNIT - 1)
6022 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
6024 cfun_frame_layout.frame_size += current_function_outgoing_args_size;
6028 /* Return offset between argument pointer and frame pointer
6029 initially after prologue. */
6031 HOST_WIDE_INT
6032 s390_arg_frame_offset (void)
6034 /* See the comment in s390_emit_prologue about the assumptions we make
6035 whether or not the base and return address register need to be saved. */
6036 int return_addr_used = !current_function_is_leaf
6037 || TARGET_TPF_PROFILING
6038 || regs_ever_live[RETURN_REGNUM]
6039 || cfun_frame_layout.save_return_addr_p;
6041 s390_frame_info (1, !TARGET_CPU_ZARCH || return_addr_used);
6043 return cfun_frame_layout.frame_size + STACK_POINTER_OFFSET;
6046 /* Return offset between return address pointer (location of r14
6047 on the stack) and frame pointer initially after prologue. */
6049 HOST_WIDE_INT
6050 s390_return_address_offset (void)
6052 s390_frame_info (1, 1);
6054 if (cfun_frame_layout.last_save_gpr < RETURN_REGNUM)
6055 abort ();
6057 return (cfun_frame_layout.frame_size + cfun_frame_layout.gprs_offset
6058 + (RETURN_REGNUM - cfun_frame_layout.first_save_gpr) * UNITS_PER_WORD);
6061 /* Emit insn to save fpr REGNUM at offset OFFSET relative
6062 to register BASE. Return generated insn. */
6064 static rtx
6065 save_fpr (rtx base, int offset, int regnum)
6067 rtx addr;
6068 addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
6069 set_mem_alias_set (addr, s390_sr_alias_set);
6071 return emit_move_insn (addr, gen_rtx_REG (DFmode, regnum));
6074 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
6075 to register BASE. Return generated insn. */
6077 static rtx
6078 restore_fpr (rtx base, int offset, int regnum)
6080 rtx addr;
6081 addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
6082 set_mem_alias_set (addr, s390_sr_alias_set);
6084 return emit_move_insn (gen_rtx_REG (DFmode, regnum), addr);
6087 /* Generate insn to save registers FIRST to LAST into
6088 the register save area located at offset OFFSET
6089 relative to register BASE. */
6091 static rtx
6092 save_gprs (rtx base, int offset, int first, int last)
6094 rtx addr, insn, note;
6095 int i;
6097 addr = plus_constant (base, offset);
6098 addr = gen_rtx_MEM (Pmode, addr);
6099 set_mem_alias_set (addr, s390_sr_alias_set);
6101 /* Special-case single register. */
6102 if (first == last)
6104 if (TARGET_64BIT)
6105 insn = gen_movdi (addr, gen_rtx_REG (Pmode, first));
6106 else
6107 insn = gen_movsi (addr, gen_rtx_REG (Pmode, first));
6109 RTX_FRAME_RELATED_P (insn) = 1;
6110 return insn;
6114 insn = gen_store_multiple (addr,
6115 gen_rtx_REG (Pmode, first),
6116 GEN_INT (last - first + 1));
6119 /* We need to set the FRAME_RELATED flag on all SETs
6120 inside the store-multiple pattern.
6122 However, we must not emit DWARF records for registers 2..5
6123 if they are stored for use by variable arguments ...
6125 ??? Unfortunately, it is not enough to simply not the the
6126 FRAME_RELATED flags for those SETs, because the first SET
6127 of the PARALLEL is always treated as if it had the flag
6128 set, even if it does not. Therefore we emit a new pattern
6129 without those registers as REG_FRAME_RELATED_EXPR note. */
6131 if (first >= 6)
6133 rtx pat = PATTERN (insn);
6135 for (i = 0; i < XVECLEN (pat, 0); i++)
6136 if (GET_CODE (XVECEXP (pat, 0, i)) == SET)
6137 RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1;
6139 RTX_FRAME_RELATED_P (insn) = 1;
6141 else if (last >= 6)
6143 addr = plus_constant (base, offset + (6 - first) * UNITS_PER_WORD);
6144 note = gen_store_multiple (gen_rtx_MEM (Pmode, addr),
6145 gen_rtx_REG (Pmode, 6),
6146 GEN_INT (last - 6 + 1));
6147 note = PATTERN (note);
6149 REG_NOTES (insn) =
6150 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
6151 note, REG_NOTES (insn));
6153 for (i = 0; i < XVECLEN (note, 0); i++)
6154 if (GET_CODE (XVECEXP (note, 0, i)) == SET)
6155 RTX_FRAME_RELATED_P (XVECEXP (note, 0, i)) = 1;
6157 RTX_FRAME_RELATED_P (insn) = 1;
6160 return insn;
6163 /* Generate insn to restore registers FIRST to LAST from
6164 the register save area located at offset OFFSET
6165 relative to register BASE. */
6167 static rtx
6168 restore_gprs (rtx base, int offset, int first, int last)
6170 rtx addr, insn;
6172 addr = plus_constant (base, offset);
6173 addr = gen_rtx_MEM (Pmode, addr);
6174 set_mem_alias_set (addr, s390_sr_alias_set);
6176 /* Special-case single register. */
6177 if (first == last)
6179 if (TARGET_64BIT)
6180 insn = gen_movdi (gen_rtx_REG (Pmode, first), addr);
6181 else
6182 insn = gen_movsi (gen_rtx_REG (Pmode, first), addr);
6184 return insn;
6187 insn = gen_load_multiple (gen_rtx_REG (Pmode, first),
6188 addr,
6189 GEN_INT (last - first + 1));
6190 return insn;
6193 /* Return insn sequence to load the GOT register. */
6195 static GTY(()) rtx got_symbol;
6197 s390_load_got (void)
6199 rtx insns;
6201 if (!got_symbol)
6203 got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6204 SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
6207 start_sequence ();
6209 if (TARGET_CPU_ZARCH)
6211 emit_move_insn (pic_offset_table_rtx, got_symbol);
6213 else
6215 rtx offset;
6217 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got_symbol),
6218 UNSPEC_LTREL_OFFSET);
6219 offset = gen_rtx_CONST (Pmode, offset);
6220 offset = force_const_mem (Pmode, offset);
6222 emit_move_insn (pic_offset_table_rtx, offset);
6224 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (offset, 0)),
6225 UNSPEC_LTREL_BASE);
6226 offset = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, offset);
6228 emit_move_insn (pic_offset_table_rtx, offset);
6231 insns = get_insns ();
6232 end_sequence ();
6233 return insns;
6236 /* Expand the prologue into a bunch of separate insns. */
6238 void
6239 s390_emit_prologue (void)
6241 rtx insn, addr;
6242 rtx temp_reg;
6243 int i;
6244 int offset;
6245 int next_fpr = 0;
6247 /* At this point, we decide whether we'll need to save/restore the
6248 return address register. This decision is final on zSeries machines;
6249 on S/390 it can still be overridden in s390_split_branches. */
6251 if (!current_function_is_leaf
6252 || TARGET_TPF_PROFILING
6253 || regs_ever_live[RETURN_REGNUM])
6254 cfun_frame_layout.save_return_addr_p = 1;
6256 /* Decide which register to use as literal pool base. In small leaf
6257 functions, try to use an unused call-clobbered register as base
6258 register to avoid save/restore overhead. */
6260 if (current_function_is_leaf && !regs_ever_live[5])
6261 cfun->machine->base_reg = gen_rtx_REG (Pmode, 5);
6262 else
6263 cfun->machine->base_reg = gen_rtx_REG (Pmode, BASE_REGNUM);
6265 regs_ever_live[REGNO (cfun->machine->base_reg)] = 1;
6267 /* Compute frame info. Note that at this point, we assume the base
6268 register and -on S/390- the return register always need to be saved.
6269 This is done because the usage of these registers might change even
6270 after the prologue was emitted. If it turns out later that we really
6271 don't need them, the prologue/epilogue code is modified again. */
6273 s390_frame_info (1, !TARGET_CPU_ZARCH
6274 || cfun_frame_layout.save_return_addr_p);
6276 /* We need to update regs_ever_live to avoid data-flow problems. */
6278 regs_ever_live[BASE_REGNUM] = 1;
6279 regs_ever_live[RETURN_REGNUM] = (!TARGET_CPU_ZARCH
6280 || cfun_frame_layout.save_return_addr_p);
6281 regs_ever_live[STACK_POINTER_REGNUM] = cfun_frame_layout.frame_size > 0;
6283 /* Annotate all constant pool references to let the scheduler know
6284 they implicitly use the base register. */
6286 push_topmost_sequence ();
6288 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6289 if (INSN_P (insn))
6290 annotate_constant_pool_refs (&PATTERN (insn));
6292 pop_topmost_sequence ();
6294 /* Choose best register to use for temp use within prologue.
6295 See below for why TPF must use the register 1. */
6297 if (!current_function_is_leaf && !TARGET_TPF_PROFILING)
6298 temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
6299 else
6300 temp_reg = gen_rtx_REG (Pmode, 1);
6302 /* Save call saved gprs. */
6303 if (cfun_frame_layout.first_save_gpr != -1)
6305 insn = save_gprs (stack_pointer_rtx,
6306 cfun_frame_layout.gprs_offset,
6307 cfun_frame_layout.first_save_gpr,
6308 cfun_frame_layout.last_save_gpr);
6309 emit_insn (insn);
6312 /* Dummy insn to mark literal pool slot. */
6314 emit_insn (gen_main_pool (cfun->machine->base_reg));
6316 offset = cfun_frame_layout.f0_offset;
6318 /* Save f0 and f2. */
6319 for (i = 0; i < 2; i++)
6321 if (cfun_fpr_bit_p (i))
6323 save_fpr (stack_pointer_rtx, offset, i + 16);
6324 offset += 8;
6326 else if (TARGET_BACKCHAIN)
6327 offset += 8;
6330 /* Save f4 and f6. */
6331 offset = cfun_frame_layout.f4_offset;
6332 for (i = 2; i < 4; i++)
6334 if (cfun_fpr_bit_p (i))
6336 insn = save_fpr (stack_pointer_rtx, offset, i + 16);
6337 offset += 8;
6339 /* If f4 and f6 are call clobbered they are saved due to stdargs and
6340 therefore are not frame related. */
6341 if (!call_really_used_regs[i + 16])
6342 RTX_FRAME_RELATED_P (insn) = 1;
6344 else if (TARGET_BACKCHAIN)
6345 offset += 8;
6348 if (!TARGET_BACKCHAIN
6349 && cfun_save_high_fprs_p
6350 && cfun_frame_layout.f8_offset + cfun_frame_layout.high_fprs * 8 > 0)
6352 offset = (cfun_frame_layout.f8_offset
6353 + (cfun_frame_layout.high_fprs - 1) * 8);
6355 for (i = 15; i > 7 && offset >= 0; i--)
6356 if (cfun_fpr_bit_p (i))
6358 insn = save_fpr (stack_pointer_rtx, offset, i + 16);
6360 RTX_FRAME_RELATED_P (insn) = 1;
6361 offset -= 8;
6363 if (offset >= cfun_frame_layout.f8_offset)
6364 next_fpr = i + 16;
6367 if (TARGET_BACKCHAIN)
6368 next_fpr = cfun_save_high_fprs_p ? 31 : 0;
6370 /* Decrement stack pointer. */
6372 if (cfun_frame_layout.frame_size > 0)
6374 rtx frame_off = GEN_INT (-cfun_frame_layout.frame_size);
6376 if (s390_stack_size)
6378 HOST_WIDE_INT stack_check_mask = ((s390_stack_size - 1)
6379 & ~(s390_stack_guard - 1));
6380 rtx t = gen_rtx_AND (Pmode, stack_pointer_rtx,
6381 GEN_INT (stack_check_mask));
6383 if (TARGET_64BIT)
6384 gen_cmpdi (t, const0_rtx);
6385 else
6386 gen_cmpsi (t, const0_rtx);
6388 emit_insn (gen_conditional_trap (gen_rtx_EQ (CCmode,
6389 gen_rtx_REG (CCmode,
6390 CC_REGNUM),
6391 const0_rtx),
6392 const0_rtx));
6395 if (s390_warn_framesize > 0
6396 && cfun_frame_layout.frame_size >= s390_warn_framesize)
6397 warning ("frame size of `%s' is " HOST_WIDE_INT_PRINT_DEC " bytes",
6398 current_function_name (), cfun_frame_layout.frame_size);
6400 if (s390_warn_dynamicstack_p && cfun->calls_alloca)
6401 warning ("`%s' uses dynamic stack allocation", current_function_name ());
6403 /* Save incoming stack pointer into temp reg. */
6404 if (cfun_frame_layout.save_backchain_p || next_fpr)
6405 insn = emit_insn (gen_move_insn (temp_reg, stack_pointer_rtx));
6407 /* Subtract frame size from stack pointer. */
6409 if (DISP_IN_RANGE (INTVAL (frame_off)))
6411 insn = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
6412 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
6413 frame_off));
6414 insn = emit_insn (insn);
6416 else
6418 if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off), 'K', "K"))
6419 frame_off = force_const_mem (Pmode, frame_off);
6421 insn = emit_insn (gen_add2_insn (stack_pointer_rtx, frame_off));
6422 annotate_constant_pool_refs (&PATTERN (insn));
6425 RTX_FRAME_RELATED_P (insn) = 1;
6426 REG_NOTES (insn) =
6427 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
6428 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
6429 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
6430 GEN_INT (-cfun_frame_layout.frame_size))),
6431 REG_NOTES (insn));
6433 /* Set backchain. */
6435 if (cfun_frame_layout.save_backchain_p)
6437 if (cfun_frame_layout.backchain_offset)
6438 addr = gen_rtx_MEM (Pmode,
6439 plus_constant (stack_pointer_rtx,
6440 cfun_frame_layout.backchain_offset));
6441 else
6442 addr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
6443 set_mem_alias_set (addr, s390_sr_alias_set);
6444 insn = emit_insn (gen_move_insn (addr, temp_reg));
6447 /* If we support asynchronous exceptions (e.g. for Java),
6448 we need to make sure the backchain pointer is set up
6449 before any possibly trapping memory access. */
6451 if (cfun_frame_layout.save_backchain_p && flag_non_call_exceptions)
6453 addr = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
6454 emit_insn (gen_rtx_CLOBBER (VOIDmode, addr));
6458 /* Save fprs 8 - 15 (64 bit ABI). */
6460 if (cfun_save_high_fprs_p && next_fpr)
6462 insn = emit_insn (gen_add2_insn (temp_reg,
6463 GEN_INT (cfun_frame_layout.f8_offset)));
6465 offset = 0;
6467 for (i = 24; i <= next_fpr; i++)
6468 if (cfun_fpr_bit_p (i - 16))
6470 rtx addr = plus_constant (stack_pointer_rtx,
6471 cfun_frame_layout.frame_size
6472 + cfun_frame_layout.f8_offset
6473 + offset);
6475 insn = save_fpr (temp_reg, offset, i);
6476 offset += 8;
6477 RTX_FRAME_RELATED_P (insn) = 1;
6478 REG_NOTES (insn) =
6479 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
6480 gen_rtx_SET (VOIDmode,
6481 gen_rtx_MEM (DFmode, addr),
6482 gen_rtx_REG (DFmode, i)),
6483 REG_NOTES (insn));
6487 /* Set frame pointer, if needed. */
6489 if (frame_pointer_needed)
6491 insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
6492 RTX_FRAME_RELATED_P (insn) = 1;
6495 /* Set up got pointer, if needed. */
6497 if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
6499 rtx insns = s390_load_got ();
6501 for (insn = insns; insn; insn = NEXT_INSN (insn))
6503 annotate_constant_pool_refs (&PATTERN (insn));
6505 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
6506 REG_NOTES (insn));
6509 emit_insn (insns);
6512 if (TARGET_TPF_PROFILING)
6514 /* Generate a BAS instruction to serve as a function
6515 entry intercept to facilitate the use of tracing
6516 algorithms located at the branch target. */
6517 emit_insn (gen_prologue_tpf ());
6519 /* Emit a blockage here so that all code
6520 lies between the profiling mechanisms. */
6521 emit_insn (gen_blockage ());
6525 /* Expand the epilogue into a bunch of separate insns. */
6527 void
6528 s390_emit_epilogue (bool sibcall)
6530 rtx frame_pointer, return_reg;
6531 int area_bottom, area_top, offset = 0;
6532 int next_offset;
6533 rtvec p;
6534 int i;
6536 if (TARGET_TPF_PROFILING)
6539 /* Generate a BAS instruction to serve as a function
6540 entry intercept to facilitate the use of tracing
6541 algorithms located at the branch target. */
6543 /* Emit a blockage here so that all code
6544 lies between the profiling mechanisms. */
6545 emit_insn (gen_blockage ());
6547 emit_insn (gen_epilogue_tpf ());
6550 /* Check whether to use frame or stack pointer for restore. */
6552 frame_pointer = (frame_pointer_needed
6553 ? hard_frame_pointer_rtx : stack_pointer_rtx);
6555 s390_frame_area (&area_bottom, &area_top);
6557 /* Check whether we can access the register save area.
6558 If not, increment the frame pointer as required. */
6560 if (area_top <= area_bottom)
6562 /* Nothing to restore. */
6564 else if (DISP_IN_RANGE (cfun_frame_layout.frame_size + area_bottom)
6565 && DISP_IN_RANGE (cfun_frame_layout.frame_size + area_top - 1))
6567 /* Area is in range. */
6568 offset = cfun_frame_layout.frame_size;
6570 else
6572 rtx insn, frame_off;
6574 offset = area_bottom < 0 ? -area_bottom : 0;
6575 frame_off = GEN_INT (cfun_frame_layout.frame_size - offset);
6577 if (DISP_IN_RANGE (INTVAL (frame_off)))
6579 insn = gen_rtx_SET (VOIDmode, frame_pointer,
6580 gen_rtx_PLUS (Pmode, frame_pointer, frame_off));
6581 insn = emit_insn (insn);
6583 else
6585 if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off), 'K', "K"))
6586 frame_off = force_const_mem (Pmode, frame_off);
6588 insn = emit_insn (gen_add2_insn (frame_pointer, frame_off));
6589 annotate_constant_pool_refs (&PATTERN (insn));
6593 /* Restore call saved fprs. */
6595 if (TARGET_64BIT)
6597 if (cfun_save_high_fprs_p)
6599 next_offset = cfun_frame_layout.f8_offset;
6600 for (i = 24; i < 32; i++)
6602 if (cfun_fpr_bit_p (i - 16))
6604 restore_fpr (frame_pointer,
6605 offset + next_offset, i);
6606 next_offset += 8;
6612 else
6614 next_offset = cfun_frame_layout.f4_offset;
6615 for (i = 18; i < 20; i++)
6617 if (cfun_fpr_bit_p (i - 16))
6619 restore_fpr (frame_pointer,
6620 offset + next_offset, i);
6621 next_offset += 8;
6623 else if (TARGET_BACKCHAIN)
6624 next_offset += 8;
6629 /* Return register. */
6631 return_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
6633 /* Restore call saved gprs. */
6635 if (cfun_frame_layout.first_restore_gpr != -1)
6637 rtx insn, addr;
6638 int i;
6640 /* Check for global register and save them
6641 to stack location from where they get restored. */
6643 for (i = cfun_frame_layout.first_restore_gpr;
6644 i <= cfun_frame_layout.last_restore_gpr;
6645 i++)
6647 /* These registers are special and need to be
6648 restored in any case. */
6649 if (i == STACK_POINTER_REGNUM
6650 || i == RETURN_REGNUM
6651 || i == BASE_REGNUM
6652 || (flag_pic && i == (int)PIC_OFFSET_TABLE_REGNUM))
6653 continue;
6655 if (global_regs[i])
6657 addr = plus_constant (frame_pointer,
6658 offset + cfun_frame_layout.gprs_offset
6659 + (i - cfun_frame_layout.first_save_gpr)
6660 * UNITS_PER_WORD);
6661 addr = gen_rtx_MEM (Pmode, addr);
6662 set_mem_alias_set (addr, s390_sr_alias_set);
6663 emit_move_insn (addr, gen_rtx_REG (Pmode, i));
6667 if (! sibcall)
6669 /* Fetch return address from stack before load multiple,
6670 this will do good for scheduling. */
6672 if (cfun_frame_layout.save_return_addr_p
6673 || (cfun_frame_layout.first_restore_gpr < BASE_REGNUM
6674 && cfun_frame_layout.last_restore_gpr > RETURN_REGNUM))
6676 int return_regnum = find_unused_clobbered_reg();
6677 if (!return_regnum)
6678 return_regnum = 4;
6679 return_reg = gen_rtx_REG (Pmode, return_regnum);
6681 addr = plus_constant (frame_pointer,
6682 offset + cfun_frame_layout.gprs_offset
6683 + (RETURN_REGNUM
6684 - cfun_frame_layout.first_save_gpr)
6685 * UNITS_PER_WORD);
6686 addr = gen_rtx_MEM (Pmode, addr);
6687 set_mem_alias_set (addr, s390_sr_alias_set);
6688 emit_move_insn (return_reg, addr);
6692 insn = restore_gprs (frame_pointer,
6693 offset + cfun_frame_layout.gprs_offset
6694 + (cfun_frame_layout.first_restore_gpr
6695 - cfun_frame_layout.first_save_gpr)
6696 * UNITS_PER_WORD,
6697 cfun_frame_layout.first_restore_gpr,
6698 cfun_frame_layout.last_restore_gpr);
6699 emit_insn (insn);
6702 if (! sibcall)
6705 /* Return to caller. */
6707 p = rtvec_alloc (2);
6709 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
6710 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, return_reg);
6711 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
6716 /* Return the size in bytes of a function argument of
6717 type TYPE and/or mode MODE. At least one of TYPE or
6718 MODE must be specified. */
6720 static int
6721 s390_function_arg_size (enum machine_mode mode, tree type)
6723 if (type)
6724 return int_size_in_bytes (type);
6726 /* No type info available for some library calls ... */
6727 if (mode != BLKmode)
6728 return GET_MODE_SIZE (mode);
6730 /* If we have neither type nor mode, abort */
6731 abort ();
6734 /* Return true if a function argument of type TYPE and mode MODE
6735 is to be passed in a floating-point register, if available. */
6737 static bool
6738 s390_function_arg_float (enum machine_mode mode, tree type)
6740 int size = s390_function_arg_size (mode, type);
6741 if (size > 8)
6742 return false;
6744 /* Soft-float changes the ABI: no floating-point registers are used. */
6745 if (TARGET_SOFT_FLOAT)
6746 return false;
6748 /* No type info available for some library calls ... */
6749 if (!type)
6750 return mode == SFmode || mode == DFmode;
6752 /* The ABI says that record types with a single member are treated
6753 just like that member would be. */
6754 while (TREE_CODE (type) == RECORD_TYPE)
6756 tree field, single = NULL_TREE;
6758 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
6760 if (TREE_CODE (field) != FIELD_DECL)
6761 continue;
6763 if (single == NULL_TREE)
6764 single = TREE_TYPE (field);
6765 else
6766 return false;
6769 if (single == NULL_TREE)
6770 return false;
6771 else
6772 type = single;
6775 return TREE_CODE (type) == REAL_TYPE;
6778 /* Return true if a function argument of type TYPE and mode MODE
6779 is to be passed in an integer register, or a pair of integer
6780 registers, if available. */
6782 static bool
6783 s390_function_arg_integer (enum machine_mode mode, tree type)
6785 int size = s390_function_arg_size (mode, type);
6786 if (size > 8)
6787 return false;
6789 /* No type info available for some library calls ... */
6790 if (!type)
6791 return GET_MODE_CLASS (mode) == MODE_INT
6792 || (TARGET_SOFT_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT);
6794 /* We accept small integral (and similar) types. */
6795 if (INTEGRAL_TYPE_P (type)
6796 || POINTER_TYPE_P (type)
6797 || TREE_CODE (type) == OFFSET_TYPE
6798 || (TARGET_SOFT_FLOAT && TREE_CODE (type) == REAL_TYPE))
6799 return true;
6801 /* We also accept structs of size 1, 2, 4, 8 that are not
6802 passed in floating-point registers. */
6803 if (AGGREGATE_TYPE_P (type)
6804 && exact_log2 (size) >= 0
6805 && !s390_function_arg_float (mode, type))
6806 return true;
6808 return false;
6811 /* Return 1 if a function argument of type TYPE and mode MODE
6812 is to be passed by reference. The ABI specifies that only
6813 structures of size 1, 2, 4, or 8 bytes are passed by value,
6814 all other structures (and complex numbers) are passed by
6815 reference. */
6817 static bool
6818 s390_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
6819 enum machine_mode mode, tree type,
6820 bool named ATTRIBUTE_UNUSED)
6822 int size = s390_function_arg_size (mode, type);
6823 if (size > 8)
6824 return true;
6826 if (type)
6828 if (AGGREGATE_TYPE_P (type) && exact_log2 (size) < 0)
6829 return 1;
6831 if (TREE_CODE (type) == COMPLEX_TYPE
6832 || TREE_CODE (type) == VECTOR_TYPE)
6833 return 1;
6836 return 0;
6839 /* Update the data in CUM to advance over an argument of mode MODE and
6840 data type TYPE. (TYPE is null for libcalls where that information
6841 may not be available.). The boolean NAMED specifies whether the
6842 argument is a named argument (as opposed to an unnamed argument
6843 matching an ellipsis). */
6845 void
6846 s390_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
6847 tree type, int named ATTRIBUTE_UNUSED)
6849 if (s390_function_arg_float (mode, type))
6851 cum->fprs += 1;
6853 else if (s390_function_arg_integer (mode, type))
6855 int size = s390_function_arg_size (mode, type);
6856 cum->gprs += ((size + UNITS_PER_WORD-1) / UNITS_PER_WORD);
6858 else
6859 abort ();
6862 /* Define where to put the arguments to a function.
6863 Value is zero to push the argument on the stack,
6864 or a hard register in which to store the argument.
6866 MODE is the argument's machine mode.
6867 TYPE is the data type of the argument (as a tree).
6868 This is null for libcalls where that information may
6869 not be available.
6870 CUM is a variable of type CUMULATIVE_ARGS which gives info about
6871 the preceding args and about the function being called.
6872 NAMED is nonzero if this argument is a named parameter
6873 (otherwise it is an extra parameter matching an ellipsis).
6875 On S/390, we use general purpose registers 2 through 6 to
6876 pass integer, pointer, and certain structure arguments, and
6877 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
6878 to pass floating point arguments. All remaining arguments
6879 are pushed to the stack. */
6882 s390_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
6883 int named ATTRIBUTE_UNUSED)
6885 if (s390_function_arg_float (mode, type))
6887 if (cum->fprs + 1 > (TARGET_64BIT? 4 : 2))
6888 return 0;
6889 else
6890 return gen_rtx_REG (mode, cum->fprs + 16);
6892 else if (s390_function_arg_integer (mode, type))
6894 int size = s390_function_arg_size (mode, type);
6895 int n_gprs = (size + UNITS_PER_WORD-1) / UNITS_PER_WORD;
6897 if (cum->gprs + n_gprs > 5)
6898 return 0;
6899 else
6900 return gen_rtx_REG (mode, cum->gprs + 2);
6903 /* After the real arguments, expand_call calls us once again
6904 with a void_type_node type. Whatever we return here is
6905 passed as operand 2 to the call expanders.
6907 We don't need this feature ... */
6908 else if (type == void_type_node)
6909 return const0_rtx;
6911 abort ();
6914 /* Return true if return values of type TYPE should be returned
6915 in a memory buffer whose address is passed by the caller as
6916 hidden first argument. */
6918 static bool
6919 s390_return_in_memory (tree type, tree fundecl ATTRIBUTE_UNUSED)
6921 /* We accept small integral (and similar) types. */
6922 if (INTEGRAL_TYPE_P (type)
6923 || POINTER_TYPE_P (type)
6924 || TREE_CODE (type) == OFFSET_TYPE
6925 || TREE_CODE (type) == REAL_TYPE)
6926 return int_size_in_bytes (type) > 8;
6928 /* Aggregates and similar constructs are always returned
6929 in memory. */
6930 if (AGGREGATE_TYPE_P (type)
6931 || TREE_CODE (type) == COMPLEX_TYPE
6932 || TREE_CODE (type) == VECTOR_TYPE)
6933 return true;
6935 /* ??? We get called on all sorts of random stuff from
6936 aggregate_value_p. We can't abort, but it's not clear
6937 what's safe to return. Pretend it's a struct I guess. */
6938 return true;
6941 /* Define where to return a (scalar) value of type TYPE.
6942 If TYPE is null, define where to return a (scalar)
6943 value of mode MODE from a libcall. */
6946 s390_function_value (tree type, enum machine_mode mode)
6948 if (type)
6950 int unsignedp = TYPE_UNSIGNED (type);
6951 mode = promote_mode (type, TYPE_MODE (type), &unsignedp, 1);
6954 if (GET_MODE_CLASS (mode) != MODE_INT
6955 && GET_MODE_CLASS (mode) != MODE_FLOAT)
6956 abort ();
6957 if (GET_MODE_SIZE (mode) > 8)
6958 abort ();
6960 if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT)
6961 return gen_rtx_REG (mode, 16);
6962 else
6963 return gen_rtx_REG (mode, 2);
6967 /* Create and return the va_list datatype.
6969 On S/390, va_list is an array type equivalent to
6971 typedef struct __va_list_tag
6973 long __gpr;
6974 long __fpr;
6975 void *__overflow_arg_area;
6976 void *__reg_save_area;
6977 } va_list[1];
6979 where __gpr and __fpr hold the number of general purpose
6980 or floating point arguments used up to now, respectively,
6981 __overflow_arg_area points to the stack location of the
6982 next argument passed on the stack, and __reg_save_area
6983 always points to the start of the register area in the
6984 call frame of the current function. The function prologue
6985 saves all registers used for argument passing into this
6986 area if the function uses variable arguments. */
6988 static tree
6989 s390_build_builtin_va_list (void)
6991 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
6993 record = lang_hooks.types.make_type (RECORD_TYPE);
6995 type_decl =
6996 build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
6998 f_gpr = build_decl (FIELD_DECL, get_identifier ("__gpr"),
6999 long_integer_type_node);
7000 f_fpr = build_decl (FIELD_DECL, get_identifier ("__fpr"),
7001 long_integer_type_node);
7002 f_ovf = build_decl (FIELD_DECL, get_identifier ("__overflow_arg_area"),
7003 ptr_type_node);
7004 f_sav = build_decl (FIELD_DECL, get_identifier ("__reg_save_area"),
7005 ptr_type_node);
7007 DECL_FIELD_CONTEXT (f_gpr) = record;
7008 DECL_FIELD_CONTEXT (f_fpr) = record;
7009 DECL_FIELD_CONTEXT (f_ovf) = record;
7010 DECL_FIELD_CONTEXT (f_sav) = record;
7012 TREE_CHAIN (record) = type_decl;
7013 TYPE_NAME (record) = type_decl;
7014 TYPE_FIELDS (record) = f_gpr;
7015 TREE_CHAIN (f_gpr) = f_fpr;
7016 TREE_CHAIN (f_fpr) = f_ovf;
7017 TREE_CHAIN (f_ovf) = f_sav;
7019 layout_type (record);
7021 /* The correct type is an array type of one element. */
7022 return build_array_type (record, build_index_type (size_zero_node));
7025 /* Implement va_start by filling the va_list structure VALIST.
7026 STDARG_P is always true, and ignored.
7027 NEXTARG points to the first anonymous stack argument.
7029 The following global variables are used to initialize
7030 the va_list structure:
7032 current_function_args_info:
7033 holds number of gprs and fprs used for named arguments.
7034 current_function_arg_offset_rtx:
7035 holds the offset of the first anonymous stack argument
7036 (relative to the virtual arg pointer). */
7038 void
7039 s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
7041 HOST_WIDE_INT n_gpr, n_fpr;
7042 int off;
7043 tree f_gpr, f_fpr, f_ovf, f_sav;
7044 tree gpr, fpr, ovf, sav, t;
7046 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
7047 f_fpr = TREE_CHAIN (f_gpr);
7048 f_ovf = TREE_CHAIN (f_fpr);
7049 f_sav = TREE_CHAIN (f_ovf);
7051 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
7052 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
7053 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
7054 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
7055 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
7057 /* Count number of gp and fp argument registers used. */
7059 n_gpr = current_function_args_info.gprs;
7060 n_fpr = current_function_args_info.fprs;
7062 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
7063 build_int_cst (NULL_TREE, n_gpr));
7064 TREE_SIDE_EFFECTS (t) = 1;
7065 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7067 t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
7068 build_int_cst (NULL_TREE, n_fpr));
7069 TREE_SIDE_EFFECTS (t) = 1;
7070 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7072 /* Find the overflow area. */
7073 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
7075 off = INTVAL (current_function_arg_offset_rtx);
7076 off = off < 0 ? 0 : off;
7077 if (TARGET_DEBUG_ARG)
7078 fprintf (stderr, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
7079 (int)n_gpr, (int)n_fpr, off);
7081 t = build (PLUS_EXPR, TREE_TYPE (ovf), t, build_int_cst (NULL_TREE, off));
7083 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
7084 TREE_SIDE_EFFECTS (t) = 1;
7085 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7087 /* Find the register save area. */
7088 t = make_tree (TREE_TYPE (sav), return_address_pointer_rtx);
7089 if (TARGET_KERNEL_BACKCHAIN)
7090 t = build (PLUS_EXPR, TREE_TYPE (sav), t,
7091 build_int_cst (NULL_TREE,
7092 -(RETURN_REGNUM - 2) * UNITS_PER_WORD
7093 - (TARGET_64BIT ? 4 : 2) * 8));
7094 else
7095 t = build (PLUS_EXPR, TREE_TYPE (sav), t,
7096 build_int_cst (NULL_TREE, -RETURN_REGNUM * UNITS_PER_WORD));
7098 t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
7099 TREE_SIDE_EFFECTS (t) = 1;
7100 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
7103 /* Implement va_arg by updating the va_list structure
7104 VALIST as required to retrieve an argument of type
7105 TYPE, and returning that argument.
7107 Generates code equivalent to:
7109 if (integral value) {
7110 if (size <= 4 && args.gpr < 5 ||
7111 size > 4 && args.gpr < 4 )
7112 ret = args.reg_save_area[args.gpr+8]
7113 else
7114 ret = *args.overflow_arg_area++;
7115 } else if (float value) {
7116 if (args.fgpr < 2)
7117 ret = args.reg_save_area[args.fpr+64]
7118 else
7119 ret = *args.overflow_arg_area++;
7120 } else if (aggregate value) {
7121 if (args.gpr < 5)
7122 ret = *args.reg_save_area[args.gpr]
7123 else
7124 ret = **args.overflow_arg_area++;
7125 } */
7127 tree
7128 s390_gimplify_va_arg (tree valist, tree type, tree *pre_p,
7129 tree *post_p ATTRIBUTE_UNUSED)
7131 tree f_gpr, f_fpr, f_ovf, f_sav;
7132 tree gpr, fpr, ovf, sav, reg, t, u;
7133 int indirect_p, size, n_reg, sav_ofs, sav_scale, max_reg;
7134 tree lab_false, lab_over, addr;
7136 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
7137 f_fpr = TREE_CHAIN (f_gpr);
7138 f_ovf = TREE_CHAIN (f_fpr);
7139 f_sav = TREE_CHAIN (f_ovf);
7141 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
7142 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
7143 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
7144 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
7145 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
7147 size = int_size_in_bytes (type);
7149 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
7151 if (TARGET_DEBUG_ARG)
7153 fprintf (stderr, "va_arg: aggregate type");
7154 debug_tree (type);
7157 /* Aggregates are passed by reference. */
7158 indirect_p = 1;
7159 reg = gpr;
7160 n_reg = 1;
7162 /* TARGET_KERNEL_BACKCHAIN on 31 bit: It is assumed here that no padding
7163 will be added by s390_frame_info because for va_args always an even
7164 number of gprs has to be saved r15-r2 = 14 regs. */
7165 sav_ofs = (TARGET_KERNEL_BACKCHAIN
7166 ? (TARGET_64BIT ? 4 : 2) * 8 : 2 * UNITS_PER_WORD);
7167 sav_scale = UNITS_PER_WORD;
7168 size = UNITS_PER_WORD;
7169 max_reg = 4;
7171 else if (s390_function_arg_float (TYPE_MODE (type), type))
7173 if (TARGET_DEBUG_ARG)
7175 fprintf (stderr, "va_arg: float type");
7176 debug_tree (type);
7179 /* FP args go in FP registers, if present. */
7180 indirect_p = 0;
7181 reg = fpr;
7182 n_reg = 1;
7183 sav_ofs = TARGET_KERNEL_BACKCHAIN ? 0 : 16 * UNITS_PER_WORD;
7184 sav_scale = 8;
7185 /* TARGET_64BIT has up to 4 parameter in fprs */
7186 max_reg = TARGET_64BIT ? 3 : 1;
7188 else
7190 if (TARGET_DEBUG_ARG)
7192 fprintf (stderr, "va_arg: other type");
7193 debug_tree (type);
7196 /* Otherwise into GP registers. */
7197 indirect_p = 0;
7198 reg = gpr;
7199 n_reg = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
7201 /* TARGET_KERNEL_BACKCHAIN on 31 bit: It is assumed here that no padding
7202 will be added by s390_frame_info because for va_args always an even
7203 number of gprs has to be saved r15-r2 = 14 regs. */
7204 sav_ofs = TARGET_KERNEL_BACKCHAIN ?
7205 (TARGET_64BIT ? 4 : 2) * 8 : 2*UNITS_PER_WORD;
7207 if (size < UNITS_PER_WORD)
7208 sav_ofs += UNITS_PER_WORD - size;
7210 sav_scale = UNITS_PER_WORD;
7211 if (n_reg > 1)
7212 max_reg = 3;
7213 else
7214 max_reg = 4;
7217 /* Pull the value out of the saved registers ... */
7219 lab_false = create_artificial_label ();
7220 lab_over = create_artificial_label ();
7221 addr = create_tmp_var (ptr_type_node, "addr");
7223 t = fold_convert (TREE_TYPE (reg), size_int (max_reg));
7224 t = build2 (GT_EXPR, boolean_type_node, reg, t);
7225 u = build1 (GOTO_EXPR, void_type_node, lab_false);
7226 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
7227 gimplify_and_add (t, pre_p);
7229 t = build2 (PLUS_EXPR, ptr_type_node, sav,
7230 fold_convert (ptr_type_node, size_int (sav_ofs)));
7231 u = build2 (MULT_EXPR, TREE_TYPE (reg), reg,
7232 fold_convert (TREE_TYPE (reg), size_int (sav_scale)));
7233 t = build2 (PLUS_EXPR, ptr_type_node, t, fold_convert (ptr_type_node, u));
7235 t = build2 (MODIFY_EXPR, void_type_node, addr, t);
7236 gimplify_and_add (t, pre_p);
7238 t = build1 (GOTO_EXPR, void_type_node, lab_over);
7239 gimplify_and_add (t, pre_p);
7241 t = build1 (LABEL_EXPR, void_type_node, lab_false);
7242 append_to_statement_list (t, pre_p);
7245 /* ... Otherwise out of the overflow area. */
7247 t = ovf;
7248 if (size < UNITS_PER_WORD)
7249 t = build2 (PLUS_EXPR, ptr_type_node, t,
7250 fold_convert (ptr_type_node, size_int (UNITS_PER_WORD - size)));
7252 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
7254 u = build2 (MODIFY_EXPR, void_type_node, addr, t);
7255 gimplify_and_add (u, pre_p);
7257 t = build2 (PLUS_EXPR, ptr_type_node, t,
7258 fold_convert (ptr_type_node, size_int (size)));
7259 t = build2 (MODIFY_EXPR, ptr_type_node, ovf, t);
7260 gimplify_and_add (t, pre_p);
7262 t = build1 (LABEL_EXPR, void_type_node, lab_over);
7263 append_to_statement_list (t, pre_p);
7266 /* Increment register save count. */
7268 u = build2 (PREINCREMENT_EXPR, TREE_TYPE (reg), reg,
7269 fold_convert (TREE_TYPE (reg), size_int (n_reg)));
7270 gimplify_and_add (u, pre_p);
7272 if (indirect_p)
7274 t = build_pointer_type (build_pointer_type (type));
7275 addr = fold_convert (t, addr);
7276 addr = build_fold_indirect_ref (addr);
7278 else
7280 t = build_pointer_type (type);
7281 addr = fold_convert (t, addr);
7284 return build_fold_indirect_ref (addr);
7288 /* Builtins. */
7290 enum s390_builtin
7292 S390_BUILTIN_THREAD_POINTER,
7293 S390_BUILTIN_SET_THREAD_POINTER,
7295 S390_BUILTIN_max
7298 static unsigned int const code_for_builtin_64[S390_BUILTIN_max] = {
7299 CODE_FOR_get_tp_64,
7300 CODE_FOR_set_tp_64
7303 static unsigned int const code_for_builtin_31[S390_BUILTIN_max] = {
7304 CODE_FOR_get_tp_31,
7305 CODE_FOR_set_tp_31
7308 static void
7309 s390_init_builtins (void)
7311 tree ftype;
7313 ftype = build_function_type (ptr_type_node, void_list_node);
7314 lang_hooks.builtin_function ("__builtin_thread_pointer", ftype,
7315 S390_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
7316 NULL, NULL_TREE);
7318 ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
7319 lang_hooks.builtin_function ("__builtin_set_thread_pointer", ftype,
7320 S390_BUILTIN_SET_THREAD_POINTER, BUILT_IN_MD,
7321 NULL, NULL_TREE);
7324 /* Expand an expression EXP that calls a built-in function,
7325 with result going to TARGET if that's convenient
7326 (and in mode MODE if that's convenient).
7327 SUBTARGET may be used as the target for computing one of EXP's operands.
7328 IGNORE is nonzero if the value is to be ignored. */
7330 static rtx
7331 s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
7332 enum machine_mode mode ATTRIBUTE_UNUSED,
7333 int ignore ATTRIBUTE_UNUSED)
7335 #define MAX_ARGS 2
7337 unsigned int const *code_for_builtin =
7338 TARGET_64BIT ? code_for_builtin_64 : code_for_builtin_31;
7340 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7341 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7342 tree arglist = TREE_OPERAND (exp, 1);
7343 enum insn_code icode;
7344 rtx op[MAX_ARGS], pat;
7345 int arity;
7346 bool nonvoid;
7348 if (fcode >= S390_BUILTIN_max)
7349 internal_error ("bad builtin fcode");
7350 icode = code_for_builtin[fcode];
7351 if (icode == 0)
7352 internal_error ("bad builtin fcode");
7354 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
7356 for (arglist = TREE_OPERAND (exp, 1), arity = 0;
7357 arglist;
7358 arglist = TREE_CHAIN (arglist), arity++)
7360 const struct insn_operand_data *insn_op;
7362 tree arg = TREE_VALUE (arglist);
7363 if (arg == error_mark_node)
7364 return NULL_RTX;
7365 if (arity > MAX_ARGS)
7366 return NULL_RTX;
7368 insn_op = &insn_data[icode].operand[arity + nonvoid];
7370 op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, 0);
7372 if (!(*insn_op->predicate) (op[arity], insn_op->mode))
7373 op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
7376 if (nonvoid)
7378 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7379 if (!target
7380 || GET_MODE (target) != tmode
7381 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
7382 target = gen_reg_rtx (tmode);
7385 switch (arity)
7387 case 0:
7388 pat = GEN_FCN (icode) (target);
7389 break;
7390 case 1:
7391 if (nonvoid)
7392 pat = GEN_FCN (icode) (target, op[0]);
7393 else
7394 pat = GEN_FCN (icode) (op[0]);
7395 break;
7396 case 2:
7397 pat = GEN_FCN (icode) (target, op[0], op[1]);
7398 break;
7399 default:
7400 abort ();
7402 if (!pat)
7403 return NULL_RTX;
7404 emit_insn (pat);
7406 if (nonvoid)
7407 return target;
7408 else
7409 return const0_rtx;
7413 /* Output assembly code for the trampoline template to
7414 stdio stream FILE.
7416 On S/390, we use gpr 1 internally in the trampoline code;
7417 gpr 0 is used to hold the static chain. */
7419 void
7420 s390_trampoline_template (FILE *file)
7422 if (TARGET_64BIT)
7424 fprintf (file, "larl\t%s,0f\n", reg_names[1]);
7425 fprintf (file, "lg\t%s,0(%s)\n", reg_names[0], reg_names[1]);
7426 fprintf (file, "lg\t%s,8(%s)\n", reg_names[1], reg_names[1]);
7427 fprintf (file, "br\t%s\n", reg_names[1]);
7428 fprintf (file, "0:\t.quad\t0\n");
7429 fprintf (file, ".quad\t0\n");
7431 else
7433 fprintf (file, "basr\t%s,0\n", reg_names[1]);
7434 fprintf (file, "l\t%s,10(%s)\n", reg_names[0], reg_names[1]);
7435 fprintf (file, "l\t%s,14(%s)\n", reg_names[1], reg_names[1]);
7436 fprintf (file, "br\t%s\n", reg_names[1]);
7437 fprintf (file, ".long\t0\n");
7438 fprintf (file, ".long\t0\n");
7442 /* Emit RTL insns to initialize the variable parts of a trampoline.
7443 FNADDR is an RTX for the address of the function's pure code.
7444 CXT is an RTX for the static chain value for the function. */
7446 void
7447 s390_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
7449 emit_move_insn (gen_rtx_MEM (Pmode,
7450 memory_address (Pmode,
7451 plus_constant (addr, (TARGET_64BIT ? 20 : 12) ))), cxt);
7452 emit_move_insn (gen_rtx_MEM (Pmode,
7453 memory_address (Pmode,
7454 plus_constant (addr, (TARGET_64BIT ? 28 : 16) ))), fnaddr);
7457 /* Return rtx for 64-bit constant formed from the 32-bit subwords
7458 LOW and HIGH, independent of the host word size. */
7461 s390_gen_rtx_const_DI (int high, int low)
7463 #if HOST_BITS_PER_WIDE_INT >= 64
7464 HOST_WIDE_INT val;
7465 val = (HOST_WIDE_INT)high;
7466 val <<= 32;
7467 val |= (HOST_WIDE_INT)low;
7469 return GEN_INT (val);
7470 #else
7471 #if HOST_BITS_PER_WIDE_INT >= 32
7472 return immed_double_const ((HOST_WIDE_INT)low, (HOST_WIDE_INT)high, DImode);
7473 #else
7474 abort ();
7475 #endif
7476 #endif
7479 /* Output assembler code to FILE to increment profiler label # LABELNO
7480 for profiling a function entry. */
7482 void
7483 s390_function_profiler (FILE *file, int labelno)
7485 rtx op[7];
7487 char label[128];
7488 ASM_GENERATE_INTERNAL_LABEL (label, "LP", labelno);
7490 fprintf (file, "# function profiler \n");
7492 op[0] = gen_rtx_REG (Pmode, RETURN_REGNUM);
7493 op[1] = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
7494 op[1] = gen_rtx_MEM (Pmode, plus_constant (op[1], UNITS_PER_WORD));
7496 op[2] = gen_rtx_REG (Pmode, 1);
7497 op[3] = gen_rtx_SYMBOL_REF (Pmode, label);
7498 SYMBOL_REF_FLAGS (op[3]) = SYMBOL_FLAG_LOCAL;
7500 op[4] = gen_rtx_SYMBOL_REF (Pmode, "_mcount");
7501 if (flag_pic)
7503 op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), UNSPEC_PLT);
7504 op[4] = gen_rtx_CONST (Pmode, op[4]);
7507 if (TARGET_64BIT)
7509 output_asm_insn ("stg\t%0,%1", op);
7510 output_asm_insn ("larl\t%2,%3", op);
7511 output_asm_insn ("brasl\t%0,%4", op);
7512 output_asm_insn ("lg\t%0,%1", op);
7514 else if (!flag_pic)
7516 op[6] = gen_label_rtx ();
7518 output_asm_insn ("st\t%0,%1", op);
7519 output_asm_insn ("bras\t%2,%l6", op);
7520 output_asm_insn (".long\t%4", op);
7521 output_asm_insn (".long\t%3", op);
7522 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
7523 output_asm_insn ("l\t%0,0(%2)", op);
7524 output_asm_insn ("l\t%2,4(%2)", op);
7525 output_asm_insn ("basr\t%0,%0", op);
7526 output_asm_insn ("l\t%0,%1", op);
7528 else
7530 op[5] = gen_label_rtx ();
7531 op[6] = gen_label_rtx ();
7533 output_asm_insn ("st\t%0,%1", op);
7534 output_asm_insn ("bras\t%2,%l6", op);
7535 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[5]));
7536 output_asm_insn (".long\t%4-%l5", op);
7537 output_asm_insn (".long\t%3-%l5", op);
7538 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
7539 output_asm_insn ("lr\t%0,%2", op);
7540 output_asm_insn ("a\t%0,0(%2)", op);
7541 output_asm_insn ("a\t%2,4(%2)", op);
7542 output_asm_insn ("basr\t%0,%0", op);
7543 output_asm_insn ("l\t%0,%1", op);
7547 /* Select section for constant in constant pool. In 32-bit mode,
7548 constants go in the function section; in 64-bit mode in .rodata. */
7550 static void
7551 s390_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED,
7552 rtx x ATTRIBUTE_UNUSED,
7553 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
7555 if (TARGET_CPU_ZARCH)
7556 readonly_data_section ();
7557 else
7558 function_section (current_function_decl);
7561 /* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
7562 into its SYMBOL_REF_FLAGS. */
7564 static void
7565 s390_encode_section_info (tree decl, rtx rtl, int first)
7567 default_encode_section_info (decl, rtl, first);
7569 /* If a variable has a forced alignment to < 2 bytes, mark it with
7570 SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL operand. */
7571 if (TREE_CODE (decl) == VAR_DECL
7572 && DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) < 16)
7573 SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_ALIGN1;
7576 /* Output thunk to FILE that implements a C++ virtual function call (with
7577 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
7578 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
7579 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
7580 relative to the resulting this pointer. */
7582 static void
7583 s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
7584 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
7585 tree function)
7587 rtx op[10];
7588 int nonlocal = 0;
7590 /* Operand 0 is the target function. */
7591 op[0] = XEXP (DECL_RTL (function), 0);
7592 if (flag_pic && !SYMBOL_REF_LOCAL_P (op[0]))
7594 nonlocal = 1;
7595 op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]),
7596 TARGET_64BIT ? UNSPEC_PLT : UNSPEC_GOT);
7597 op[0] = gen_rtx_CONST (Pmode, op[0]);
7600 /* Operand 1 is the 'this' pointer. */
7601 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
7602 op[1] = gen_rtx_REG (Pmode, 3);
7603 else
7604 op[1] = gen_rtx_REG (Pmode, 2);
7606 /* Operand 2 is the delta. */
7607 op[2] = GEN_INT (delta);
7609 /* Operand 3 is the vcall_offset. */
7610 op[3] = GEN_INT (vcall_offset);
7612 /* Operand 4 is the temporary register. */
7613 op[4] = gen_rtx_REG (Pmode, 1);
7615 /* Operands 5 to 8 can be used as labels. */
7616 op[5] = NULL_RTX;
7617 op[6] = NULL_RTX;
7618 op[7] = NULL_RTX;
7619 op[8] = NULL_RTX;
7621 /* Operand 9 can be used for temporary register. */
7622 op[9] = NULL_RTX;
7624 /* Generate code. */
7625 if (TARGET_64BIT)
7627 /* Setup literal pool pointer if required. */
7628 if ((!DISP_IN_RANGE (delta)
7629 && !CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
7630 || (!DISP_IN_RANGE (vcall_offset)
7631 && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K")))
7633 op[5] = gen_label_rtx ();
7634 output_asm_insn ("larl\t%4,%5", op);
7637 /* Add DELTA to this pointer. */
7638 if (delta)
7640 if (CONST_OK_FOR_CONSTRAINT_P (delta, 'J', "J"))
7641 output_asm_insn ("la\t%1,%2(%1)", op);
7642 else if (DISP_IN_RANGE (delta))
7643 output_asm_insn ("lay\t%1,%2(%1)", op);
7644 else if (CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
7645 output_asm_insn ("aghi\t%1,%2", op);
7646 else
7648 op[6] = gen_label_rtx ();
7649 output_asm_insn ("agf\t%1,%6-%5(%4)", op);
7653 /* Perform vcall adjustment. */
7654 if (vcall_offset)
7656 if (DISP_IN_RANGE (vcall_offset))
7658 output_asm_insn ("lg\t%4,0(%1)", op);
7659 output_asm_insn ("ag\t%1,%3(%4)", op);
7661 else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K"))
7663 output_asm_insn ("lghi\t%4,%3", op);
7664 output_asm_insn ("ag\t%4,0(%1)", op);
7665 output_asm_insn ("ag\t%1,0(%4)", op);
7667 else
7669 op[7] = gen_label_rtx ();
7670 output_asm_insn ("llgf\t%4,%7-%5(%4)", op);
7671 output_asm_insn ("ag\t%4,0(%1)", op);
7672 output_asm_insn ("ag\t%1,0(%4)", op);
7676 /* Jump to target. */
7677 output_asm_insn ("jg\t%0", op);
7679 /* Output literal pool if required. */
7680 if (op[5])
7682 output_asm_insn (".align\t4", op);
7683 targetm.asm_out.internal_label (file, "L",
7684 CODE_LABEL_NUMBER (op[5]));
7686 if (op[6])
7688 targetm.asm_out.internal_label (file, "L",
7689 CODE_LABEL_NUMBER (op[6]));
7690 output_asm_insn (".long\t%2", op);
7692 if (op[7])
7694 targetm.asm_out.internal_label (file, "L",
7695 CODE_LABEL_NUMBER (op[7]));
7696 output_asm_insn (".long\t%3", op);
7699 else
7701 /* Setup base pointer if required. */
7702 if (!vcall_offset
7703 || (!DISP_IN_RANGE (delta)
7704 && !CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
7705 || (!DISP_IN_RANGE (delta)
7706 && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K")))
7708 op[5] = gen_label_rtx ();
7709 output_asm_insn ("basr\t%4,0", op);
7710 targetm.asm_out.internal_label (file, "L",
7711 CODE_LABEL_NUMBER (op[5]));
7714 /* Add DELTA to this pointer. */
7715 if (delta)
7717 if (CONST_OK_FOR_CONSTRAINT_P (delta, 'J', "J"))
7718 output_asm_insn ("la\t%1,%2(%1)", op);
7719 else if (DISP_IN_RANGE (delta))
7720 output_asm_insn ("lay\t%1,%2(%1)", op);
7721 else if (CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
7722 output_asm_insn ("ahi\t%1,%2", op);
7723 else
7725 op[6] = gen_label_rtx ();
7726 output_asm_insn ("a\t%1,%6-%5(%4)", op);
7730 /* Perform vcall adjustment. */
7731 if (vcall_offset)
7733 if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'J', "J"))
7735 output_asm_insn ("lg\t%4,0(%1)", op);
7736 output_asm_insn ("a\t%1,%3(%4)", op);
7738 else if (DISP_IN_RANGE (vcall_offset))
7740 output_asm_insn ("lg\t%4,0(%1)", op);
7741 output_asm_insn ("ay\t%1,%3(%4)", op);
7743 else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K"))
7745 output_asm_insn ("lhi\t%4,%3", op);
7746 output_asm_insn ("a\t%4,0(%1)", op);
7747 output_asm_insn ("a\t%1,0(%4)", op);
7749 else
7751 op[7] = gen_label_rtx ();
7752 output_asm_insn ("l\t%4,%7-%5(%4)", op);
7753 output_asm_insn ("a\t%4,0(%1)", op);
7754 output_asm_insn ("a\t%1,0(%4)", op);
7757 /* We had to clobber the base pointer register.
7758 Re-setup the base pointer (with a different base). */
7759 op[5] = gen_label_rtx ();
7760 output_asm_insn ("basr\t%4,0", op);
7761 targetm.asm_out.internal_label (file, "L",
7762 CODE_LABEL_NUMBER (op[5]));
7765 /* Jump to target. */
7766 op[8] = gen_label_rtx ();
7768 if (!flag_pic)
7769 output_asm_insn ("l\t%4,%8-%5(%4)", op);
7770 else if (!nonlocal)
7771 output_asm_insn ("a\t%4,%8-%5(%4)", op);
7772 /* We cannot call through .plt, since .plt requires %r12 loaded. */
7773 else if (flag_pic == 1)
7775 output_asm_insn ("a\t%4,%8-%5(%4)", op);
7776 output_asm_insn ("l\t%4,%0(%4)", op);
7778 else if (flag_pic == 2)
7780 op[9] = gen_rtx_REG (Pmode, 0);
7781 output_asm_insn ("l\t%9,%8-4-%5(%4)", op);
7782 output_asm_insn ("a\t%4,%8-%5(%4)", op);
7783 output_asm_insn ("ar\t%4,%9", op);
7784 output_asm_insn ("l\t%4,0(%4)", op);
7787 output_asm_insn ("br\t%4", op);
7789 /* Output literal pool. */
7790 output_asm_insn (".align\t4", op);
7792 if (nonlocal && flag_pic == 2)
7793 output_asm_insn (".long\t%0", op);
7794 if (nonlocal)
7796 op[0] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
7797 SYMBOL_REF_FLAGS (op[0]) = SYMBOL_FLAG_LOCAL;
7800 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[8]));
7801 if (!flag_pic)
7802 output_asm_insn (".long\t%0", op);
7803 else
7804 output_asm_insn (".long\t%0-%5", op);
7806 if (op[6])
7808 targetm.asm_out.internal_label (file, "L",
7809 CODE_LABEL_NUMBER (op[6]));
7810 output_asm_insn (".long\t%2", op);
7812 if (op[7])
7814 targetm.asm_out.internal_label (file, "L",
7815 CODE_LABEL_NUMBER (op[7]));
7816 output_asm_insn (".long\t%3", op);
7821 bool
7822 s390_valid_pointer_mode (enum machine_mode mode)
7824 return (mode == SImode || (TARGET_64BIT && mode == DImode));
7827 /* How to allocate a 'struct machine_function'. */
7829 static struct machine_function *
7830 s390_init_machine_status (void)
7832 return ggc_alloc_cleared (sizeof (struct machine_function));
7835 /* Checks whether the given ARGUMENT_LIST would use a caller
7836 saved register. This is used to decide whether sibling call
7837 optimization could be performed on the respective function
7838 call. */
7840 static bool
7841 s390_call_saved_register_used (tree argument_list)
7843 CUMULATIVE_ARGS cum;
7844 tree parameter;
7845 enum machine_mode mode;
7846 tree type;
7847 rtx parm_rtx;
7848 int reg;
7850 INIT_CUMULATIVE_ARGS (cum, NULL, NULL, 0, 0);
7852 while (argument_list)
7854 parameter = TREE_VALUE (argument_list);
7855 argument_list = TREE_CHAIN (argument_list);
7857 if (!parameter)
7858 abort();
7860 /* For an undeclared variable passed as parameter we will get
7861 an ERROR_MARK node here. */
7862 if (TREE_CODE (parameter) == ERROR_MARK)
7863 return true;
7865 if (! (type = TREE_TYPE (parameter)))
7866 abort();
7868 if (! (mode = TYPE_MODE (TREE_TYPE (parameter))))
7869 abort();
7871 if (pass_by_reference (&cum, mode, type, true))
7873 mode = Pmode;
7874 type = build_pointer_type (type);
7877 parm_rtx = s390_function_arg (&cum, mode, type, 0);
7879 s390_function_arg_advance (&cum, mode, type, 0);
7881 if (parm_rtx && REG_P (parm_rtx))
7883 for (reg = 0;
7884 reg < HARD_REGNO_NREGS (REGNO (parm_rtx), GET_MODE (parm_rtx));
7885 reg++)
7886 if (! call_used_regs[reg + REGNO (parm_rtx)])
7887 return true;
7890 return false;
7893 /* Return true if the given call expression can be
7894 turned into a sibling call.
7895 DECL holds the declaration of the function to be called whereas
7896 EXP is the call expression itself. */
7898 static bool
7899 s390_function_ok_for_sibcall (tree decl, tree exp)
7901 /* The TPF epilogue uses register 1. */
7902 if (TARGET_TPF_PROFILING)
7903 return false;
7905 /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
7906 which would have to be restored before the sibcall. */
7907 if (!TARGET_64BIT && flag_pic && decl && TREE_PUBLIC (decl))
7908 return false;
7910 /* Register 6 on s390 is available as an argument register but unfortunately
7911 "caller saved". This makes functions needing this register for arguments
7912 not suitable for sibcalls. */
7913 if (TREE_OPERAND (exp, 1)
7914 && s390_call_saved_register_used (TREE_OPERAND (exp, 1)))
7915 return false;
7917 return true;
7920 /* This function is used by the call expanders of the machine description.
7921 It emits the call insn itself together with the necessary operations
7922 to adjust the target address and returns the emitted insn.
7923 ADDR_LOCATION is the target address rtx
7924 TLS_CALL the location of the thread-local symbol
7925 RESULT_REG the register where the result of the call should be stored
7926 RETADDR_REG the register where the return address should be stored
7927 If this parameter is NULL_RTX the call is considered
7928 to be a sibling call. */
7931 s390_emit_call (rtx addr_location, rtx tls_call, rtx result_reg,
7932 rtx retaddr_reg)
7934 bool plt_call = false;
7935 rtx insn;
7936 rtx call;
7937 rtx clobber;
7938 rtvec vec;
7940 /* Direct function calls need special treatment. */
7941 if (GET_CODE (addr_location) == SYMBOL_REF)
7943 /* When calling a global routine in PIC mode, we must
7944 replace the symbol itself with the PLT stub. */
7945 if (flag_pic && !SYMBOL_REF_LOCAL_P (addr_location))
7947 addr_location = gen_rtx_UNSPEC (Pmode,
7948 gen_rtvec (1, addr_location),
7949 UNSPEC_PLT);
7950 addr_location = gen_rtx_CONST (Pmode, addr_location);
7951 plt_call = true;
7954 /* Unless we can use the bras(l) insn, force the
7955 routine address into a register. */
7956 if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
7958 if (flag_pic)
7959 addr_location = legitimize_pic_address (addr_location, 0);
7960 else
7961 addr_location = force_reg (Pmode, addr_location);
7965 /* If it is already an indirect call or the code above moved the
7966 SYMBOL_REF to somewhere else make sure the address can be found in
7967 register 1. */
7968 if (retaddr_reg == NULL_RTX
7969 && GET_CODE (addr_location) != SYMBOL_REF
7970 && !plt_call)
7972 emit_move_insn (gen_rtx_REG (Pmode, SIBCALL_REGNUM), addr_location);
7973 addr_location = gen_rtx_REG (Pmode, SIBCALL_REGNUM);
7976 addr_location = gen_rtx_MEM (QImode, addr_location);
7977 call = gen_rtx_CALL (VOIDmode, addr_location, const0_rtx);
7979 if (result_reg != NULL_RTX)
7980 call = gen_rtx_SET (VOIDmode, result_reg, call);
7982 if (retaddr_reg != NULL_RTX)
7984 clobber = gen_rtx_CLOBBER (VOIDmode, retaddr_reg);
7986 if (tls_call != NULL_RTX)
7987 vec = gen_rtvec (3, call, clobber,
7988 gen_rtx_USE (VOIDmode, tls_call));
7989 else
7990 vec = gen_rtvec (2, call, clobber);
7992 call = gen_rtx_PARALLEL (VOIDmode, vec);
7995 insn = emit_call_insn (call);
7997 /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
7998 if ((!TARGET_64BIT && plt_call) || tls_call != NULL_RTX)
8000 /* s390_function_ok_for_sibcall should
8001 have denied sibcalls in this case. */
8002 if (retaddr_reg == NULL_RTX)
8003 abort ();
8005 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
8007 return insn;
8010 /* Implement CONDITIONAL_REGISTER_USAGE. */
8012 void
8013 s390_conditional_register_usage (void)
8015 int i;
8017 if (flag_pic)
8019 fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
8020 call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
8022 if (TARGET_CPU_ZARCH)
8024 fixed_regs[RETURN_REGNUM] = 0;
8025 call_used_regs[RETURN_REGNUM] = 0;
8027 if (TARGET_64BIT)
8029 for (i = 24; i < 32; i++)
8030 call_used_regs[i] = call_really_used_regs[i] = 0;
8032 else
8034 for (i = 18; i < 20; i++)
8035 call_used_regs[i] = call_really_used_regs[i] = 0;
8040 #include "gt-s390.h"