* rtl.h (MEM_READONLY_P): Replace RTX_UNCHANGING_P.
[official-gcc.git] / gcc / config / s390 / s390.c
blob49d4a24d8c84eddac58540e426415c8052d9f90f
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 /* The following structure is embedded in the machine
208 specific part of struct function. */
210 struct s390_frame_layout GTY (())
212 /* Offset within stack frame. */
213 HOST_WIDE_INT gprs_offset;
214 HOST_WIDE_INT f0_offset;
215 HOST_WIDE_INT f4_offset;
216 HOST_WIDE_INT f8_offset;
217 HOST_WIDE_INT backchain_offset;
219 /* Number of first and last gpr to be saved, restored. */
220 int first_save_gpr;
221 int first_restore_gpr;
222 int last_save_gpr;
223 int last_restore_gpr;
225 /* Bits standing for floating point registers. Set, if the
226 respective register has to be saved. Starting with reg 16 (f0)
227 at the rightmost bit.
228 Bit 15 - 8 7 6 5 4 3 2 1 0
229 fpr 15 - 8 7 5 3 1 6 4 2 0
230 reg 31 - 24 23 22 21 20 19 18 17 16 */
231 unsigned int fpr_bitmap;
233 /* Number of floating point registers f8-f15 which must be saved. */
234 int high_fprs;
236 /* Set if return address needs to be saved. */
237 bool save_return_addr_p;
239 /* Set if backchain needs to be saved. */
240 bool save_backchain_p;
242 /* Size of stack frame. */
243 HOST_WIDE_INT frame_size;
246 /* Define the structure for the machine field in struct function. */
248 struct machine_function GTY(())
250 struct s390_frame_layout frame_layout;
252 /* Literal pool base register. */
253 rtx base_reg;
255 /* Some local-dynamic TLS symbol name. */
256 const char *some_ld_name;
259 /* Few accessor macros for struct cfun->machine->s390_frame_layout. */
261 #define cfun_frame_layout (cfun->machine->frame_layout)
262 #define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)
263 #define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr - \
264 cfun_frame_layout.first_save_gpr + 1) * UNITS_PER_WORD)
265 #define cfun_set_fpr_bit(BITNUM) (cfun->machine->frame_layout.fpr_bitmap |= \
266 (1 << (BITNUM)))
267 #define cfun_fpr_bit_p(BITNUM) (!!(cfun->machine->frame_layout.fpr_bitmap & \
268 (1 << (BITNUM))))
270 static int s390_match_ccmode_set (rtx, enum machine_mode);
271 static int s390_branch_condition_mask (rtx);
272 static const char *s390_branch_condition_mnemonic (rtx, int);
273 static int check_mode (rtx, enum machine_mode *);
274 static int general_s_operand (rtx, enum machine_mode, int);
275 static int s390_short_displacement (rtx);
276 static int s390_decompose_address (rtx, struct s390_address *);
277 static rtx get_thread_pointer (void);
278 static rtx legitimize_tls_address (rtx, rtx);
279 static void print_shift_count_operand (FILE *, rtx);
280 static const char *get_some_local_dynamic_name (void);
281 static int get_some_local_dynamic_name_1 (rtx *, void *);
282 static int reg_used_in_mem_p (int, rtx);
283 static int addr_generation_dependency_p (rtx, rtx);
284 static int s390_split_branches (void);
285 static void annotate_constant_pool_refs (rtx *x);
286 static void find_constant_pool_ref (rtx, rtx *);
287 static void replace_constant_pool_ref (rtx *, rtx, rtx);
288 static rtx find_ltrel_base (rtx);
289 static void replace_ltrel_base (rtx *);
290 static void s390_optimize_prologue (bool);
291 static int find_unused_clobbered_reg (void);
292 static void s390_frame_area (int *, int *);
293 static void s390_register_info (int, int);
294 static void s390_frame_info (int, int);
295 static rtx save_fpr (rtx, int, int);
296 static rtx restore_fpr (rtx, int, int);
297 static rtx save_gprs (rtx, int, int, int);
298 static rtx restore_gprs (rtx, int, int, int);
299 static int s390_function_arg_size (enum machine_mode, tree);
300 static bool s390_function_arg_float (enum machine_mode, tree);
301 static struct machine_function * s390_init_machine_status (void);
303 /* Check whether integer displacement is in range. */
304 #define DISP_IN_RANGE(d) \
305 (TARGET_LONG_DISPLACEMENT? ((d) >= -524288 && (d) <= 524287) \
306 : ((d) >= 0 && (d) <= 4095))
308 /* Return true if SET either doesn't set the CC register, or else
309 the source and destination have matching CC modes and that
310 CC mode is at least as constrained as REQ_MODE. */
312 static int
313 s390_match_ccmode_set (rtx set, enum machine_mode req_mode)
315 enum machine_mode set_mode;
317 if (GET_CODE (set) != SET)
318 abort ();
320 if (GET_CODE (SET_DEST (set)) != REG || !CC_REGNO_P (REGNO (SET_DEST (set))))
321 return 1;
323 set_mode = GET_MODE (SET_DEST (set));
324 switch (set_mode)
326 case CCSmode:
327 case CCSRmode:
328 case CCUmode:
329 case CCURmode:
330 case CCLmode:
331 case CCL1mode:
332 case CCL2mode:
333 case CCL3mode:
334 case CCT1mode:
335 case CCT2mode:
336 case CCT3mode:
337 if (req_mode != set_mode)
338 return 0;
339 break;
341 case CCZmode:
342 if (req_mode != CCSmode && req_mode != CCUmode && req_mode != CCTmode
343 && req_mode != CCSRmode && req_mode != CCURmode)
344 return 0;
345 break;
347 case CCAPmode:
348 case CCANmode:
349 if (req_mode != CCAmode)
350 return 0;
351 break;
353 default:
354 abort ();
357 return (GET_MODE (SET_SRC (set)) == set_mode);
360 /* Return true if every SET in INSN that sets the CC register
361 has source and destination with matching CC modes and that
362 CC mode is at least as constrained as REQ_MODE.
363 If REQ_MODE is VOIDmode, always return false. */
366 s390_match_ccmode (rtx insn, enum machine_mode req_mode)
368 int i;
370 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
371 if (req_mode == VOIDmode)
372 return 0;
374 if (GET_CODE (PATTERN (insn)) == SET)
375 return s390_match_ccmode_set (PATTERN (insn), req_mode);
377 if (GET_CODE (PATTERN (insn)) == PARALLEL)
378 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
380 rtx set = XVECEXP (PATTERN (insn), 0, i);
381 if (GET_CODE (set) == SET)
382 if (!s390_match_ccmode_set (set, req_mode))
383 return 0;
386 return 1;
389 /* If a test-under-mask instruction can be used to implement
390 (compare (and ... OP1) OP2), return the CC mode required
391 to do that. Otherwise, return VOIDmode.
392 MIXED is true if the instruction can distinguish between
393 CC1 and CC2 for mixed selected bits (TMxx), it is false
394 if the instruction cannot (TM). */
396 enum machine_mode
397 s390_tm_ccmode (rtx op1, rtx op2, int mixed)
399 int bit0, bit1;
401 /* ??? Fixme: should work on CONST_DOUBLE as well. */
402 if (GET_CODE (op1) != CONST_INT || GET_CODE (op2) != CONST_INT)
403 return VOIDmode;
405 /* Selected bits all zero: CC0. */
406 if (INTVAL (op2) == 0)
407 return CCTmode;
409 /* Selected bits all one: CC3. */
410 if (INTVAL (op2) == INTVAL (op1))
411 return CCT3mode;
413 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. */
414 if (mixed)
416 bit1 = exact_log2 (INTVAL (op2));
417 bit0 = exact_log2 (INTVAL (op1) ^ INTVAL (op2));
418 if (bit0 != -1 && bit1 != -1)
419 return bit0 > bit1 ? CCT1mode : CCT2mode;
422 return VOIDmode;
425 /* Given a comparison code OP (EQ, NE, etc.) and the operands
426 OP0 and OP1 of a COMPARE, return the mode to be used for the
427 comparison. */
429 enum machine_mode
430 s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
432 switch (code)
434 case EQ:
435 case NE:
436 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
437 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0, 1)), 'K', "K"))
438 return CCAPmode;
439 if ((GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
440 || GET_CODE (op1) == NEG)
441 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
442 return CCLmode;
444 if (GET_CODE (op0) == AND)
446 /* Check whether we can potentially do it via TM. */
447 enum machine_mode ccmode;
448 ccmode = s390_tm_ccmode (XEXP (op0, 1), op1, 1);
449 if (ccmode != VOIDmode)
451 /* Relax CCTmode to CCZmode to allow fall-back to AND
452 if that turns out to be beneficial. */
453 return ccmode == CCTmode ? CCZmode : ccmode;
457 if (register_operand (op0, HImode)
458 && GET_CODE (op1) == CONST_INT
459 && (INTVAL (op1) == -1 || INTVAL (op1) == 65535))
460 return CCT3mode;
461 if (register_operand (op0, QImode)
462 && GET_CODE (op1) == CONST_INT
463 && (INTVAL (op1) == -1 || INTVAL (op1) == 255))
464 return CCT3mode;
466 return CCZmode;
468 case LE:
469 case LT:
470 case GE:
471 case GT:
472 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
473 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0, 1)), 'K', "K"))
475 if (INTVAL (XEXP((op0), 1)) < 0)
476 return CCANmode;
477 else
478 return CCAPmode;
480 case UNORDERED:
481 case ORDERED:
482 case UNEQ:
483 case UNLE:
484 case UNLT:
485 case UNGE:
486 case UNGT:
487 case LTGT:
488 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
489 && GET_CODE (op1) != CONST_INT)
490 return CCSRmode;
491 return CCSmode;
493 case LTU:
494 case GEU:
495 if (GET_CODE (op0) == PLUS
496 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
497 return CCL1mode;
499 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
500 && GET_CODE (op1) != CONST_INT)
501 return CCURmode;
502 return CCUmode;
504 case LEU:
505 case GTU:
506 if (GET_CODE (op0) == MINUS
507 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
508 return CCL2mode;
510 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
511 && GET_CODE (op1) != CONST_INT)
512 return CCURmode;
513 return CCUmode;
515 default:
516 abort ();
520 /* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
521 that we can implement more efficiently. */
523 void
524 s390_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
526 /* Convert ZERO_EXTRACT back to AND to enable TM patterns. */
527 if ((*code == EQ || *code == NE)
528 && *op1 == const0_rtx
529 && GET_CODE (*op0) == ZERO_EXTRACT
530 && GET_CODE (XEXP (*op0, 1)) == CONST_INT
531 && GET_CODE (XEXP (*op0, 2)) == CONST_INT
532 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0, 0))))
534 rtx inner = XEXP (*op0, 0);
535 HOST_WIDE_INT modesize = GET_MODE_BITSIZE (GET_MODE (inner));
536 HOST_WIDE_INT len = INTVAL (XEXP (*op0, 1));
537 HOST_WIDE_INT pos = INTVAL (XEXP (*op0, 2));
539 if (len > 0 && len < modesize
540 && pos >= 0 && pos + len <= modesize
541 && modesize <= HOST_BITS_PER_WIDE_INT)
543 unsigned HOST_WIDE_INT block;
544 block = ((unsigned HOST_WIDE_INT) 1 << len) - 1;
545 block <<= modesize - pos - len;
547 *op0 = gen_rtx_AND (GET_MODE (inner), inner,
548 gen_int_mode (block, GET_MODE (inner)));
552 /* Narrow AND of memory against immediate to enable TM. */
553 if ((*code == EQ || *code == NE)
554 && *op1 == const0_rtx
555 && GET_CODE (*op0) == AND
556 && GET_CODE (XEXP (*op0, 1)) == CONST_INT
557 && SCALAR_INT_MODE_P (GET_MODE (XEXP (*op0, 0))))
559 rtx inner = XEXP (*op0, 0);
560 rtx mask = XEXP (*op0, 1);
562 /* Ignore paradoxical SUBREGs if all extra bits are masked out. */
563 if (GET_CODE (inner) == SUBREG
564 && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (inner)))
565 && (GET_MODE_SIZE (GET_MODE (inner))
566 >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner))))
567 && ((INTVAL (mask)
568 & GET_MODE_MASK (GET_MODE (inner))
569 & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (inner))))
570 == 0))
571 inner = SUBREG_REG (inner);
573 /* Do not change volatile MEMs. */
574 if (MEM_P (inner) && !MEM_VOLATILE_P (inner))
576 int part = s390_single_part (XEXP (*op0, 1),
577 GET_MODE (inner), QImode, 0);
578 if (part >= 0)
580 mask = gen_int_mode (s390_extract_part (mask, QImode, 0), QImode);
581 inner = adjust_address_nv (inner, QImode, part);
582 *op0 = gen_rtx_AND (QImode, inner, mask);
587 /* Narrow comparisons against 0xffff to HImode if possible. */
589 if ((*code == EQ || *code == NE)
590 && GET_CODE (*op1) == CONST_INT
591 && INTVAL (*op1) == 0xffff
592 && SCALAR_INT_MODE_P (GET_MODE (*op0))
593 && (nonzero_bits (*op0, GET_MODE (*op0))
594 & ~(unsigned HOST_WIDE_INT) 0xffff) == 0)
596 *op0 = gen_lowpart (HImode, *op0);
597 *op1 = constm1_rtx;
601 /* Emit a compare instruction suitable to implement the comparison
602 OP0 CODE OP1. Return the correct condition RTL to be placed in
603 the IF_THEN_ELSE of the conditional branch testing the result. */
606 s390_emit_compare (enum rtx_code code, rtx op0, rtx op1)
608 enum machine_mode mode = s390_select_ccmode (code, op0, op1);
609 rtx cc = gen_rtx_REG (mode, CC_REGNUM);
611 emit_insn (gen_rtx_SET (VOIDmode, cc, gen_rtx_COMPARE (mode, op0, op1)));
612 return gen_rtx_fmt_ee (code, VOIDmode, cc, const0_rtx);
615 /* Emit a jump instruction to TARGET. If COND is NULL_RTX, emit an
616 unconditional jump, else a conditional jump under condition COND. */
618 void
619 s390_emit_jump (rtx target, rtx cond)
621 rtx insn;
623 target = gen_rtx_LABEL_REF (VOIDmode, target);
624 if (cond)
625 target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, target, pc_rtx);
627 insn = gen_rtx_SET (VOIDmode, pc_rtx, target);
628 emit_jump_insn (insn);
631 /* Return nonzero if OP is a valid comparison operator
632 for an ALC condition in mode MODE. */
635 s390_alc_comparison (rtx op, enum machine_mode mode)
637 if (mode != VOIDmode && mode != GET_MODE (op))
638 return 0;
640 while (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND)
641 op = XEXP (op, 0);
643 if (!COMPARISON_P (op))
644 return 0;
646 if (GET_CODE (XEXP (op, 0)) != REG
647 || REGNO (XEXP (op, 0)) != CC_REGNUM
648 || XEXP (op, 1) != const0_rtx)
649 return 0;
651 switch (GET_MODE (XEXP (op, 0)))
653 case CCL1mode:
654 return GET_CODE (op) == LTU;
656 case CCL2mode:
657 return GET_CODE (op) == LEU;
659 case CCL3mode:
660 return GET_CODE (op) == GEU;
662 case CCUmode:
663 return GET_CODE (op) == GTU;
665 case CCURmode:
666 return GET_CODE (op) == LTU;
668 case CCSmode:
669 return GET_CODE (op) == UNGT;
671 case CCSRmode:
672 return GET_CODE (op) == UNLT;
674 default:
675 return 0;
679 /* Return nonzero if OP is a valid comparison operator
680 for an SLB condition in mode MODE. */
683 s390_slb_comparison (rtx op, enum machine_mode mode)
685 if (mode != VOIDmode && mode != GET_MODE (op))
686 return 0;
688 while (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND)
689 op = XEXP (op, 0);
691 if (!COMPARISON_P (op))
692 return 0;
694 if (GET_CODE (XEXP (op, 0)) != REG
695 || REGNO (XEXP (op, 0)) != CC_REGNUM
696 || XEXP (op, 1) != const0_rtx)
697 return 0;
699 switch (GET_MODE (XEXP (op, 0)))
701 case CCL1mode:
702 return GET_CODE (op) == GEU;
704 case CCL2mode:
705 return GET_CODE (op) == GTU;
707 case CCL3mode:
708 return GET_CODE (op) == LTU;
710 case CCUmode:
711 return GET_CODE (op) == LEU;
713 case CCURmode:
714 return GET_CODE (op) == GEU;
716 case CCSmode:
717 return GET_CODE (op) == LE;
719 case CCSRmode:
720 return GET_CODE (op) == GE;
722 default:
723 return 0;
727 /* Return branch condition mask to implement a branch
728 specified by CODE. */
730 static int
731 s390_branch_condition_mask (rtx code)
733 const int CC0 = 1 << 3;
734 const int CC1 = 1 << 2;
735 const int CC2 = 1 << 1;
736 const int CC3 = 1 << 0;
738 if (GET_CODE (XEXP (code, 0)) != REG
739 || REGNO (XEXP (code, 0)) != CC_REGNUM
740 || XEXP (code, 1) != const0_rtx)
741 abort ();
743 switch (GET_MODE (XEXP (code, 0)))
745 case CCZmode:
746 switch (GET_CODE (code))
748 case EQ: return CC0;
749 case NE: return CC1 | CC2 | CC3;
750 default:
751 abort ();
753 break;
755 case CCT1mode:
756 switch (GET_CODE (code))
758 case EQ: return CC1;
759 case NE: return CC0 | CC2 | CC3;
760 default:
761 abort ();
763 break;
765 case CCT2mode:
766 switch (GET_CODE (code))
768 case EQ: return CC2;
769 case NE: return CC0 | CC1 | CC3;
770 default:
771 abort ();
773 break;
775 case CCT3mode:
776 switch (GET_CODE (code))
778 case EQ: return CC3;
779 case NE: return CC0 | CC1 | CC2;
780 default:
781 abort ();
783 break;
785 case CCLmode:
786 switch (GET_CODE (code))
788 case EQ: return CC0 | CC2;
789 case NE: return CC1 | CC3;
790 default:
791 abort ();
793 break;
795 case CCL1mode:
796 switch (GET_CODE (code))
798 case LTU: return CC2 | CC3; /* carry */
799 case GEU: return CC0 | CC1; /* no carry */
800 default:
801 abort ();
803 break;
805 case CCL2mode:
806 switch (GET_CODE (code))
808 case GTU: return CC0 | CC1; /* borrow */
809 case LEU: return CC2 | CC3; /* no borrow */
810 default:
811 abort ();
813 break;
815 case CCL3mode:
816 switch (GET_CODE (code))
818 case EQ: return CC0 | CC2;
819 case NE: return CC1 | CC3;
820 case LTU: return CC1;
821 case GTU: return CC3;
822 case LEU: return CC1 | CC2;
823 case GEU: return CC2 | CC3;
824 default:
825 abort ();
828 case CCUmode:
829 switch (GET_CODE (code))
831 case EQ: return CC0;
832 case NE: return CC1 | CC2 | CC3;
833 case LTU: return CC1;
834 case GTU: return CC2;
835 case LEU: return CC0 | CC1;
836 case GEU: return CC0 | CC2;
837 default:
838 abort ();
840 break;
842 case CCURmode:
843 switch (GET_CODE (code))
845 case EQ: return CC0;
846 case NE: return CC2 | CC1 | CC3;
847 case LTU: return CC2;
848 case GTU: return CC1;
849 case LEU: return CC0 | CC2;
850 case GEU: return CC0 | CC1;
851 default:
852 abort ();
854 break;
856 case CCAPmode:
857 switch (GET_CODE (code))
859 case EQ: return CC0;
860 case NE: return CC1 | CC2 | CC3;
861 case LT: return CC1 | CC3;
862 case GT: return CC2;
863 case LE: return CC0 | CC1 | CC3;
864 case GE: return CC0 | CC2;
865 default:
866 abort ();
868 break;
870 case CCANmode:
871 switch (GET_CODE (code))
873 case EQ: return CC0;
874 case NE: return CC1 | CC2 | CC3;
875 case LT: return CC1;
876 case GT: return CC2 | CC3;
877 case LE: return CC0 | CC1;
878 case GE: return CC0 | CC2 | CC3;
879 default:
880 abort ();
882 break;
884 case CCSmode:
885 switch (GET_CODE (code))
887 case EQ: return CC0;
888 case NE: return CC1 | CC2 | CC3;
889 case LT: return CC1;
890 case GT: return CC2;
891 case LE: return CC0 | CC1;
892 case GE: return CC0 | CC2;
893 case UNORDERED: return CC3;
894 case ORDERED: return CC0 | CC1 | CC2;
895 case UNEQ: return CC0 | CC3;
896 case UNLT: return CC1 | CC3;
897 case UNGT: return CC2 | CC3;
898 case UNLE: return CC0 | CC1 | CC3;
899 case UNGE: return CC0 | CC2 | CC3;
900 case LTGT: return CC1 | CC2;
901 default:
902 abort ();
904 break;
906 case CCSRmode:
907 switch (GET_CODE (code))
909 case EQ: return CC0;
910 case NE: return CC2 | CC1 | CC3;
911 case LT: return CC2;
912 case GT: return CC1;
913 case LE: return CC0 | CC2;
914 case GE: return CC0 | CC1;
915 case UNORDERED: return CC3;
916 case ORDERED: return CC0 | CC2 | CC1;
917 case UNEQ: return CC0 | CC3;
918 case UNLT: return CC2 | CC3;
919 case UNGT: return CC1 | CC3;
920 case UNLE: return CC0 | CC2 | CC3;
921 case UNGE: return CC0 | CC1 | CC3;
922 case LTGT: return CC2 | CC1;
923 default:
924 abort ();
926 break;
928 default:
929 abort ();
933 /* If INV is false, return assembler mnemonic string to implement
934 a branch specified by CODE. If INV is true, return mnemonic
935 for the corresponding inverted branch. */
937 static const char *
938 s390_branch_condition_mnemonic (rtx code, int inv)
940 static const char *const mnemonic[16] =
942 NULL, "o", "h", "nle",
943 "l", "nhe", "lh", "ne",
944 "e", "nlh", "he", "nl",
945 "le", "nh", "no", NULL
948 int mask = s390_branch_condition_mask (code);
950 if (inv)
951 mask ^= 15;
953 if (mask < 1 || mask > 14)
954 abort ();
956 return mnemonic[mask];
959 /* Return the part of op which has a value different from def.
960 The size of the part is determined by mode.
961 Use this function only if you already know that op really
962 contains such a part. */
964 unsigned HOST_WIDE_INT
965 s390_extract_part (rtx op, enum machine_mode mode, int def)
967 unsigned HOST_WIDE_INT value = 0;
968 int max_parts = HOST_BITS_PER_WIDE_INT / GET_MODE_BITSIZE (mode);
969 int part_bits = GET_MODE_BITSIZE (mode);
970 unsigned HOST_WIDE_INT part_mask = (1 << part_bits) - 1;
971 int i;
973 for (i = 0; i < max_parts; i++)
975 if (i == 0)
976 value = (unsigned HOST_WIDE_INT) INTVAL (op);
977 else
978 value >>= part_bits;
980 if ((value & part_mask) != (def & part_mask))
981 return value & part_mask;
984 abort ();
987 /* If OP is an integer constant of mode MODE with exactly one
988 part of mode PART_MODE unequal to DEF, return the number of that
989 part. Otherwise, return -1. */
992 s390_single_part (rtx op,
993 enum machine_mode mode,
994 enum machine_mode part_mode,
995 int def)
997 unsigned HOST_WIDE_INT value = 0;
998 int n_parts = GET_MODE_SIZE (mode) / GET_MODE_SIZE (part_mode);
999 unsigned HOST_WIDE_INT part_mask = (1 << GET_MODE_BITSIZE (part_mode)) - 1;
1000 int i, part = -1;
1002 if (GET_CODE (op) != CONST_INT)
1003 return -1;
1005 for (i = 0; i < n_parts; i++)
1007 if (i == 0)
1008 value = (unsigned HOST_WIDE_INT) INTVAL (op);
1009 else
1010 value >>= GET_MODE_BITSIZE (part_mode);
1012 if ((value & part_mask) != (def & part_mask))
1014 if (part != -1)
1015 return -1;
1016 else
1017 part = i;
1020 return part == -1 ? -1 : n_parts - 1 - part;
1023 /* Check whether we can (and want to) split a double-word
1024 move in mode MODE from SRC to DST into two single-word
1025 moves, moving the subword FIRST_SUBWORD first. */
1027 bool
1028 s390_split_ok_p (rtx dst, rtx src, enum machine_mode mode, int first_subword)
1030 /* Floating point registers cannot be split. */
1031 if (FP_REG_P (src) || FP_REG_P (dst))
1032 return false;
1034 /* We don't need to split if operands are directly accessible. */
1035 if (s_operand (src, mode) || s_operand (dst, mode))
1036 return false;
1038 /* Non-offsettable memory references cannot be split. */
1039 if ((GET_CODE (src) == MEM && !offsettable_memref_p (src))
1040 || (GET_CODE (dst) == MEM && !offsettable_memref_p (dst)))
1041 return false;
1043 /* Moving the first subword must not clobber a register
1044 needed to move the second subword. */
1045 if (register_operand (dst, mode))
1047 rtx subreg = operand_subword (dst, first_subword, 0, mode);
1048 if (reg_overlap_mentioned_p (subreg, src))
1049 return false;
1052 return true;
1056 /* Change optimizations to be performed, depending on the
1057 optimization level.
1059 LEVEL is the optimization level specified; 2 if `-O2' is
1060 specified, 1 if `-O' is specified, and 0 if neither is specified.
1062 SIZE is nonzero if `-Os' is specified and zero otherwise. */
1064 void
1065 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
1067 /* ??? There are apparently still problems with -fcaller-saves. */
1068 flag_caller_saves = 0;
1070 /* By default, always emit DWARF-2 unwind info. This allows debugging
1071 without maintaining a stack frame back-chain. */
1072 flag_asynchronous_unwind_tables = 1;
1075 void
1076 override_options (void)
1078 int i;
1079 static struct pta
1081 const char *const name; /* processor name or nickname. */
1082 const enum processor_type processor;
1083 const enum processor_flags flags;
1085 const processor_alias_table[] =
1087 {"g5", PROCESSOR_9672_G5, PF_IEEE_FLOAT},
1088 {"g6", PROCESSOR_9672_G6, PF_IEEE_FLOAT},
1089 {"z900", PROCESSOR_2064_Z900, PF_IEEE_FLOAT | PF_ZARCH},
1090 {"z990", PROCESSOR_2084_Z990, PF_IEEE_FLOAT | PF_ZARCH
1091 | PF_LONG_DISPLACEMENT},
1094 int const pta_size = ARRAY_SIZE (processor_alias_table);
1096 /* Acquire a unique set number for our register saves and restores. */
1097 s390_sr_alias_set = new_alias_set ();
1099 /* Set up function hooks. */
1100 init_machine_status = s390_init_machine_status;
1102 /* Architecture mode defaults according to ABI. */
1103 if (!(target_flags_explicit & MASK_ZARCH))
1105 if (TARGET_64BIT)
1106 target_flags |= MASK_ZARCH;
1107 else
1108 target_flags &= ~MASK_ZARCH;
1111 /* Determine processor architectural level. */
1112 if (!s390_arch_string)
1113 s390_arch_string = TARGET_ZARCH? "z900" : "g5";
1115 for (i = 0; i < pta_size; i++)
1116 if (! strcmp (s390_arch_string, processor_alias_table[i].name))
1118 s390_arch = processor_alias_table[i].processor;
1119 s390_arch_flags = processor_alias_table[i].flags;
1120 break;
1122 if (i == pta_size)
1123 error ("Unknown cpu used in -march=%s.", s390_arch_string);
1125 /* Determine processor to tune for. */
1126 if (!s390_tune_string)
1128 s390_tune = s390_arch;
1129 s390_tune_flags = s390_arch_flags;
1130 s390_tune_string = s390_arch_string;
1132 else
1134 for (i = 0; i < pta_size; i++)
1135 if (! strcmp (s390_tune_string, processor_alias_table[i].name))
1137 s390_tune = processor_alias_table[i].processor;
1138 s390_tune_flags = processor_alias_table[i].flags;
1139 break;
1141 if (i == pta_size)
1142 error ("Unknown cpu used in -mtune=%s.", s390_tune_string);
1145 /* Sanity checks. */
1146 if (TARGET_ZARCH && !(s390_arch_flags & PF_ZARCH))
1147 error ("z/Architecture mode not supported on %s.", s390_arch_string);
1148 if (TARGET_64BIT && !TARGET_ZARCH)
1149 error ("64-bit ABI not supported in ESA/390 mode.");
1152 /* Map for smallest class containing reg regno. */
1154 const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
1155 { GENERAL_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1156 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1157 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1158 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
1159 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1160 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1161 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1162 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1163 ADDR_REGS, NO_REGS, ADDR_REGS, ADDR_REGS
1166 /* Return attribute type of insn. */
1168 static enum attr_type
1169 s390_safe_attr_type (rtx insn)
1171 if (recog_memoized (insn) >= 0)
1172 return get_attr_type (insn);
1173 else
1174 return TYPE_NONE;
1177 /* Return true if OP a (const_int 0) operand.
1178 OP is the current operation.
1179 MODE is the current operation mode. */
1182 const0_operand (register rtx op, enum machine_mode mode)
1184 return op == CONST0_RTX (mode);
1187 /* Return true if OP is constant.
1188 OP is the current operation.
1189 MODE is the current operation mode. */
1192 consttable_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1194 return CONSTANT_P (op);
1197 /* Return true if the mode of operand OP matches MODE.
1198 If MODE is set to VOIDmode, set it to the mode of OP. */
1200 static int
1201 check_mode (register rtx op, enum machine_mode *mode)
1203 if (*mode == VOIDmode)
1204 *mode = GET_MODE (op);
1205 else
1207 if (GET_MODE (op) != VOIDmode && GET_MODE (op) != *mode)
1208 return 0;
1210 return 1;
1213 /* Return true if OP a valid operand for the LARL instruction.
1214 OP is the current operation.
1215 MODE is the current operation mode. */
1218 larl_operand (register rtx op, enum machine_mode mode)
1220 if (! check_mode (op, &mode))
1221 return 0;
1223 /* Allow labels and local symbols. */
1224 if (GET_CODE (op) == LABEL_REF)
1225 return 1;
1226 if (GET_CODE (op) == SYMBOL_REF)
1227 return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0
1228 && SYMBOL_REF_TLS_MODEL (op) == 0
1229 && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
1231 /* Everything else must have a CONST, so strip it. */
1232 if (GET_CODE (op) != CONST)
1233 return 0;
1234 op = XEXP (op, 0);
1236 /* Allow adding *even* in-range constants. */
1237 if (GET_CODE (op) == PLUS)
1239 if (GET_CODE (XEXP (op, 1)) != CONST_INT
1240 || (INTVAL (XEXP (op, 1)) & 1) != 0)
1241 return 0;
1242 #if HOST_BITS_PER_WIDE_INT > 32
1243 if (INTVAL (XEXP (op, 1)) >= (HOST_WIDE_INT)1 << 32
1244 || INTVAL (XEXP (op, 1)) < -((HOST_WIDE_INT)1 << 32))
1245 return 0;
1246 #endif
1247 op = XEXP (op, 0);
1250 /* Labels and local symbols allowed here as well. */
1251 if (GET_CODE (op) == LABEL_REF)
1252 return 1;
1253 if (GET_CODE (op) == SYMBOL_REF)
1254 return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0
1255 && SYMBOL_REF_TLS_MODEL (op) == 0
1256 && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
1258 /* Now we must have a @GOTENT offset or @PLT stub
1259 or an @INDNTPOFF TLS offset. */
1260 if (GET_CODE (op) == UNSPEC
1261 && XINT (op, 1) == UNSPEC_GOTENT)
1262 return 1;
1263 if (GET_CODE (op) == UNSPEC
1264 && XINT (op, 1) == UNSPEC_PLT)
1265 return 1;
1266 if (GET_CODE (op) == UNSPEC
1267 && XINT (op, 1) == UNSPEC_INDNTPOFF)
1268 return 1;
1270 return 0;
1273 /* Helper routine to implement s_operand and s_imm_operand.
1274 OP is the current operation.
1275 MODE is the current operation mode.
1276 ALLOW_IMMEDIATE specifies whether immediate operands should
1277 be accepted or not. */
1279 static int
1280 general_s_operand (register rtx op, enum machine_mode mode,
1281 int allow_immediate)
1283 struct s390_address addr;
1285 /* Call general_operand first, so that we don't have to
1286 check for many special cases. */
1287 if (!general_operand (op, mode))
1288 return 0;
1290 /* Just like memory_operand, allow (subreg (mem ...))
1291 after reload. */
1292 if (reload_completed
1293 && GET_CODE (op) == SUBREG
1294 && GET_CODE (SUBREG_REG (op)) == MEM)
1295 op = SUBREG_REG (op);
1297 switch (GET_CODE (op))
1299 /* Constants are OK as s-operand if ALLOW_IMMEDIATE
1300 is true and we are still before reload. */
1301 case CONST_INT:
1302 case CONST_DOUBLE:
1303 if (!allow_immediate || reload_completed)
1304 return 0;
1305 return 1;
1307 /* Memory operands are OK unless they already use an
1308 index register. */
1309 case MEM:
1310 if (!s390_decompose_address (XEXP (op, 0), &addr))
1311 return 0;
1312 if (addr.indx)
1313 return 0;
1314 /* Do not allow literal pool references unless ALLOW_IMMEDIATE
1315 is true. This prevents compares between two literal pool
1316 entries from being accepted. */
1317 if (!allow_immediate
1318 && addr.base && REGNO (addr.base) == BASE_REGNUM)
1319 return 0;
1320 return 1;
1322 default:
1323 break;
1326 return 0;
1329 /* Return true if OP is a valid S-type operand.
1330 OP is the current operation.
1331 MODE is the current operation mode. */
1334 s_operand (register rtx op, enum machine_mode mode)
1336 return general_s_operand (op, mode, 0);
1339 /* Return true if OP is a valid S-type operand or an immediate
1340 operand that can be addressed as S-type operand by forcing
1341 it into the literal pool.
1342 OP is the current operation.
1343 MODE is the current operation mode. */
1346 s_imm_operand (register rtx op, enum machine_mode mode)
1348 return general_s_operand (op, mode, 1);
1351 /* Return true if OP a valid shift count operand.
1352 OP is the current operation.
1353 MODE is the current operation mode. */
1356 shift_count_operand (rtx op, enum machine_mode mode)
1358 HOST_WIDE_INT offset = 0;
1360 if (! check_mode (op, &mode))
1361 return 0;
1363 /* We can have an integer constant, an address register,
1364 or a sum of the two. Note that reload already checks
1365 that any register present is an address register, so
1366 we just check for any register here. */
1367 if (GET_CODE (op) == CONST_INT)
1369 offset = INTVAL (op);
1370 op = NULL_RTX;
1372 if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
1374 offset = INTVAL (XEXP (op, 1));
1375 op = XEXP (op, 0);
1377 while (op && GET_CODE (op) == SUBREG)
1378 op = SUBREG_REG (op);
1379 if (op && GET_CODE (op) != REG)
1380 return 0;
1382 /* Unfortunately we have to reject constants that are invalid
1383 for an address, or else reload will get confused. */
1384 if (!DISP_IN_RANGE (offset))
1385 return 0;
1387 return 1;
1390 /* Return true if DISP is a valid short displacement. */
1392 static int
1393 s390_short_displacement (rtx disp)
1395 /* No displacement is OK. */
1396 if (!disp)
1397 return 1;
1399 /* Integer displacement in range. */
1400 if (GET_CODE (disp) == CONST_INT)
1401 return INTVAL (disp) >= 0 && INTVAL (disp) < 4096;
1403 /* GOT offset is not OK, the GOT can be large. */
1404 if (GET_CODE (disp) == CONST
1405 && GET_CODE (XEXP (disp, 0)) == UNSPEC
1406 && XINT (XEXP (disp, 0), 1) == UNSPEC_GOT)
1407 return 0;
1409 /* All other symbolic constants are literal pool references,
1410 which are OK as the literal pool must be small. */
1411 if (GET_CODE (disp) == CONST)
1412 return 1;
1414 return 0;
1417 /* Return true if OP is a valid operand for a C constraint. */
1420 s390_extra_constraint_str (rtx op, int c, const char * str)
1422 struct s390_address addr;
1424 if (c != str[0])
1425 abort ();
1427 switch (c)
1429 case 'Q':
1430 if (GET_CODE (op) != MEM)
1431 return 0;
1432 if (!s390_decompose_address (XEXP (op, 0), &addr))
1433 return 0;
1434 if (addr.indx)
1435 return 0;
1437 if (TARGET_LONG_DISPLACEMENT)
1439 if (!s390_short_displacement (addr.disp))
1440 return 0;
1442 break;
1444 case 'R':
1445 if (GET_CODE (op) != MEM)
1446 return 0;
1448 if (TARGET_LONG_DISPLACEMENT)
1450 if (!s390_decompose_address (XEXP (op, 0), &addr))
1451 return 0;
1452 if (!s390_short_displacement (addr.disp))
1453 return 0;
1455 break;
1457 case 'S':
1458 if (!TARGET_LONG_DISPLACEMENT)
1459 return 0;
1460 if (GET_CODE (op) != MEM)
1461 return 0;
1462 if (!s390_decompose_address (XEXP (op, 0), &addr))
1463 return 0;
1464 if (addr.indx)
1465 return 0;
1466 if (s390_short_displacement (addr.disp))
1467 return 0;
1468 break;
1470 case 'T':
1471 if (!TARGET_LONG_DISPLACEMENT)
1472 return 0;
1473 if (GET_CODE (op) != MEM)
1474 return 0;
1475 /* Any invalid address here will be fixed up by reload,
1476 so accept it for the most generic constraint. */
1477 if (s390_decompose_address (XEXP (op, 0), &addr)
1478 && s390_short_displacement (addr.disp))
1479 return 0;
1480 break;
1482 case 'U':
1483 if (TARGET_LONG_DISPLACEMENT)
1485 if (!s390_decompose_address (op, &addr))
1486 return 0;
1487 if (!s390_short_displacement (addr.disp))
1488 return 0;
1490 break;
1492 case 'W':
1493 if (!TARGET_LONG_DISPLACEMENT)
1494 return 0;
1495 /* Any invalid address here will be fixed up by reload,
1496 so accept it for the most generic constraint. */
1497 if (s390_decompose_address (op, &addr)
1498 && s390_short_displacement (addr.disp))
1499 return 0;
1500 break;
1502 case 'Y':
1503 return shift_count_operand (op, VOIDmode);
1505 default:
1506 return 0;
1509 return 1;
1512 /* Return true if VALUE matches the constraint STR. */
1515 s390_const_ok_for_constraint_p (HOST_WIDE_INT value,
1516 int c,
1517 const char * str)
1519 enum machine_mode mode, part_mode;
1520 int def;
1521 unsigned char part;
1523 if (c != str[0])
1524 abort ();
1526 switch (str[0])
1528 case 'I':
1529 return (unsigned int)value < 256;
1531 case 'J':
1532 return (unsigned int)value < 4096;
1534 case 'K':
1535 return value >= -32768 && value < 32768;
1537 case 'L':
1538 return (TARGET_LONG_DISPLACEMENT ?
1539 (value >= -524288 && value <= 524287)
1540 : (value >= 0 && value <= 4095));
1541 case 'M':
1542 return value == 2147483647;
1544 case 'N':
1545 part = str[1] - '0';
1547 switch (str[2])
1549 case 'H': part_mode = HImode; break;
1550 case 'Q': part_mode = QImode; break;
1551 default: return 0;
1554 switch (str[3])
1556 case 'H': mode = HImode; break;
1557 case 'S': mode = SImode; break;
1558 case 'D': mode = DImode; break;
1559 default: return 0;
1562 switch (str[4])
1564 case '0': def = 0; break;
1565 case 'F': def = -1; break;
1566 default: return 0;
1569 if (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (part_mode))
1570 return 0;
1572 if (s390_single_part (GEN_INT (value), mode, part_mode, def) != part)
1573 return 0;
1575 break;
1577 default:
1578 return 0;
1581 return 1;
1584 /* Compute a (partial) cost for rtx X. Return true if the complete
1585 cost has been computed, and false if subexpressions should be
1586 scanned. In either case, *TOTAL contains the cost result. */
1588 static bool
1589 s390_rtx_costs (rtx x, int code, int outer_code, int *total)
1591 switch (code)
1593 case CONST:
1594 if (GET_CODE (XEXP (x, 0)) == MINUS
1595 && GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
1596 *total = 1000;
1597 else
1598 *total = 0;
1599 return true;
1601 case CONST_INT:
1602 /* Force_const_mem does not work out of reload, because the
1603 saveable_obstack is set to reload_obstack, which does not
1604 live long enough. Because of this we cannot use force_const_mem
1605 in addsi3. This leads to problems with gen_add2_insn with a
1606 constant greater than a short. Because of that we give an
1607 addition of greater constants a cost of 3 (reload1.c 10096). */
1608 /* ??? saveable_obstack no longer exists. */
1609 if (outer_code == PLUS
1610 && (INTVAL (x) > 32767 || INTVAL (x) < -32768))
1611 *total = COSTS_N_INSNS (3);
1612 else
1613 *total = 0;
1614 return true;
1616 case LABEL_REF:
1617 case SYMBOL_REF:
1618 case CONST_DOUBLE:
1619 *total = 0;
1620 return true;
1622 case ASHIFT:
1623 case ASHIFTRT:
1624 case LSHIFTRT:
1625 case PLUS:
1626 case AND:
1627 case IOR:
1628 case XOR:
1629 case MINUS:
1630 case NEG:
1631 case NOT:
1632 *total = COSTS_N_INSNS (1);
1633 return true;
1635 case MULT:
1636 if (GET_MODE (XEXP (x, 0)) == DImode)
1637 *total = COSTS_N_INSNS (40);
1638 else
1639 *total = COSTS_N_INSNS (7);
1640 return true;
1642 case DIV:
1643 case UDIV:
1644 case MOD:
1645 case UMOD:
1646 *total = COSTS_N_INSNS (33);
1647 return true;
1649 default:
1650 return false;
1654 /* Return the cost of an address rtx ADDR. */
1656 static int
1657 s390_address_cost (rtx addr)
1659 struct s390_address ad;
1660 if (!s390_decompose_address (addr, &ad))
1661 return 1000;
1663 return ad.indx? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
1666 /* Return true if OP is a valid operand for the BRAS instruction.
1667 OP is the current operation.
1668 MODE is the current operation mode. */
1671 bras_sym_operand (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1673 register enum rtx_code code = GET_CODE (op);
1675 /* Allow SYMBOL_REFs. */
1676 if (code == SYMBOL_REF)
1677 return 1;
1679 /* Allow @PLT stubs. */
1680 if (code == CONST
1681 && GET_CODE (XEXP (op, 0)) == UNSPEC
1682 && XINT (XEXP (op, 0), 1) == UNSPEC_PLT)
1683 return 1;
1684 return 0;
1687 /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
1688 otherwise return 0. */
1691 tls_symbolic_operand (register rtx op)
1693 if (GET_CODE (op) != SYMBOL_REF)
1694 return 0;
1695 return SYMBOL_REF_TLS_MODEL (op);
1698 /* Return true if OP is a load multiple operation. It is known to be a
1699 PARALLEL and the first section will be tested.
1700 OP is the current operation.
1701 MODE is the current operation mode. */
1704 load_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1706 enum machine_mode elt_mode;
1707 int count = XVECLEN (op, 0);
1708 unsigned int dest_regno;
1709 rtx src_addr;
1710 int i, off;
1713 /* Perform a quick check so we don't blow up below. */
1714 if (count <= 1
1715 || GET_CODE (XVECEXP (op, 0, 0)) != SET
1716 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
1717 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
1718 return 0;
1720 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
1721 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
1722 elt_mode = GET_MODE (SET_DEST (XVECEXP (op, 0, 0)));
1724 /* Check, is base, or base + displacement. */
1726 if (GET_CODE (src_addr) == REG)
1727 off = 0;
1728 else if (GET_CODE (src_addr) == PLUS
1729 && GET_CODE (XEXP (src_addr, 0)) == REG
1730 && GET_CODE (XEXP (src_addr, 1)) == CONST_INT)
1732 off = INTVAL (XEXP (src_addr, 1));
1733 src_addr = XEXP (src_addr, 0);
1735 else
1736 return 0;
1738 for (i = 1; i < count; i++)
1740 rtx elt = XVECEXP (op, 0, i);
1742 if (GET_CODE (elt) != SET
1743 || GET_CODE (SET_DEST (elt)) != REG
1744 || GET_MODE (SET_DEST (elt)) != elt_mode
1745 || REGNO (SET_DEST (elt)) != dest_regno + i
1746 || GET_CODE (SET_SRC (elt)) != MEM
1747 || GET_MODE (SET_SRC (elt)) != elt_mode
1748 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
1749 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
1750 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
1751 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1))
1752 != off + i * GET_MODE_SIZE (elt_mode))
1753 return 0;
1756 return 1;
1759 /* Return true if OP is a store multiple operation. It is known to be a
1760 PARALLEL and the first section will be tested.
1761 OP is the current operation.
1762 MODE is the current operation mode. */
1765 store_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1767 enum machine_mode elt_mode;
1768 int count = XVECLEN (op, 0);
1769 unsigned int src_regno;
1770 rtx dest_addr;
1771 int i, off;
1773 /* Perform a quick check so we don't blow up below. */
1774 if (count <= 1
1775 || GET_CODE (XVECEXP (op, 0, 0)) != SET
1776 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
1777 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
1778 return 0;
1780 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
1781 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
1782 elt_mode = GET_MODE (SET_SRC (XVECEXP (op, 0, 0)));
1784 /* Check, is base, or base + displacement. */
1786 if (GET_CODE (dest_addr) == REG)
1787 off = 0;
1788 else if (GET_CODE (dest_addr) == PLUS
1789 && GET_CODE (XEXP (dest_addr, 0)) == REG
1790 && GET_CODE (XEXP (dest_addr, 1)) == CONST_INT)
1792 off = INTVAL (XEXP (dest_addr, 1));
1793 dest_addr = XEXP (dest_addr, 0);
1795 else
1796 return 0;
1798 for (i = 1; i < count; i++)
1800 rtx elt = XVECEXP (op, 0, i);
1802 if (GET_CODE (elt) != SET
1803 || GET_CODE (SET_SRC (elt)) != REG
1804 || GET_MODE (SET_SRC (elt)) != elt_mode
1805 || REGNO (SET_SRC (elt)) != src_regno + i
1806 || GET_CODE (SET_DEST (elt)) != MEM
1807 || GET_MODE (SET_DEST (elt)) != elt_mode
1808 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
1809 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
1810 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
1811 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1))
1812 != off + i * GET_MODE_SIZE (elt_mode))
1813 return 0;
1815 return 1;
1819 /* Return true if OP contains a symbol reference */
1822 symbolic_reference_mentioned_p (rtx op)
1824 register const char *fmt;
1825 register int i;
1827 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
1828 return 1;
1830 fmt = GET_RTX_FORMAT (GET_CODE (op));
1831 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
1833 if (fmt[i] == 'E')
1835 register int j;
1837 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
1838 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
1839 return 1;
1842 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
1843 return 1;
1846 return 0;
1849 /* Return true if OP contains a reference to a thread-local symbol. */
1852 tls_symbolic_reference_mentioned_p (rtx op)
1854 register const char *fmt;
1855 register int i;
1857 if (GET_CODE (op) == SYMBOL_REF)
1858 return tls_symbolic_operand (op);
1860 fmt = GET_RTX_FORMAT (GET_CODE (op));
1861 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
1863 if (fmt[i] == 'E')
1865 register int j;
1867 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
1868 if (tls_symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
1869 return 1;
1872 else if (fmt[i] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op, i)))
1873 return 1;
1876 return 0;
1880 /* Return true if OP is a legitimate general operand when
1881 generating PIC code. It is given that flag_pic is on
1882 and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
1885 legitimate_pic_operand_p (register rtx op)
1887 /* Accept all non-symbolic constants. */
1888 if (!SYMBOLIC_CONST (op))
1889 return 1;
1891 /* Reject everything else; must be handled
1892 via emit_symbolic_move. */
1893 return 0;
1896 /* Returns true if the constant value OP is a legitimate general operand.
1897 It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
1900 legitimate_constant_p (register rtx op)
1902 /* Accept all non-symbolic constants. */
1903 if (!SYMBOLIC_CONST (op))
1904 return 1;
1906 /* Accept immediate LARL operands. */
1907 if (TARGET_CPU_ZARCH && larl_operand (op, VOIDmode))
1908 return 1;
1910 /* Thread-local symbols are never legal constants. This is
1911 so that emit_call knows that computing such addresses
1912 might require a function call. */
1913 if (TLS_SYMBOLIC_CONST (op))
1914 return 0;
1916 /* In the PIC case, symbolic constants must *not* be
1917 forced into the literal pool. We accept them here,
1918 so that they will be handled by emit_symbolic_move. */
1919 if (flag_pic)
1920 return 1;
1922 /* All remaining non-PIC symbolic constants are
1923 forced into the literal pool. */
1924 return 0;
1927 /* Determine if it's legal to put X into the constant pool. This
1928 is not possible if X contains the address of a symbol that is
1929 not constant (TLS) or not known at final link time (PIC). */
1931 static bool
1932 s390_cannot_force_const_mem (rtx x)
1934 switch (GET_CODE (x))
1936 case CONST_INT:
1937 case CONST_DOUBLE:
1938 /* Accept all non-symbolic constants. */
1939 return false;
1941 case LABEL_REF:
1942 /* Labels are OK iff we are non-PIC. */
1943 return flag_pic != 0;
1945 case SYMBOL_REF:
1946 /* 'Naked' TLS symbol references are never OK,
1947 non-TLS symbols are OK iff we are non-PIC. */
1948 if (tls_symbolic_operand (x))
1949 return true;
1950 else
1951 return flag_pic != 0;
1953 case CONST:
1954 return s390_cannot_force_const_mem (XEXP (x, 0));
1955 case PLUS:
1956 case MINUS:
1957 return s390_cannot_force_const_mem (XEXP (x, 0))
1958 || s390_cannot_force_const_mem (XEXP (x, 1));
1960 case UNSPEC:
1961 switch (XINT (x, 1))
1963 /* Only lt-relative or GOT-relative UNSPECs are OK. */
1964 case UNSPEC_LTREL_OFFSET:
1965 case UNSPEC_GOT:
1966 case UNSPEC_GOTOFF:
1967 case UNSPEC_PLTOFF:
1968 case UNSPEC_TLSGD:
1969 case UNSPEC_TLSLDM:
1970 case UNSPEC_NTPOFF:
1971 case UNSPEC_DTPOFF:
1972 case UNSPEC_GOTNTPOFF:
1973 case UNSPEC_INDNTPOFF:
1974 return false;
1976 default:
1977 return true;
1979 break;
1981 default:
1982 abort ();
1986 /* Returns true if the constant value OP is a legitimate general
1987 operand during and after reload. The difference to
1988 legitimate_constant_p is that this function will not accept
1989 a constant that would need to be forced to the literal pool
1990 before it can be used as operand. */
1993 legitimate_reload_constant_p (register rtx op)
1995 /* Accept la(y) operands. */
1996 if (GET_CODE (op) == CONST_INT
1997 && DISP_IN_RANGE (INTVAL (op)))
1998 return 1;
2000 /* Accept l(g)hi operands. */
2001 if (GET_CODE (op) == CONST_INT
2002 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'K', "K"))
2003 return 1;
2005 /* Accept lliXX operands. */
2006 if (TARGET_ZARCH
2007 && s390_single_part (op, DImode, HImode, 0) >= 0)
2008 return 1;
2010 /* Accept larl operands. */
2011 if (TARGET_CPU_ZARCH
2012 && larl_operand (op, VOIDmode))
2013 return 1;
2015 /* Everything else cannot be handled without reload. */
2016 return 0;
2019 /* Given an rtx OP being reloaded into a reg required to be in class CLASS,
2020 return the class of reg to actually use. */
2022 enum reg_class
2023 s390_preferred_reload_class (rtx op, enum reg_class class)
2025 /* This can happen if a floating point constant is being
2026 reloaded into an integer register. Leave well alone. */
2027 if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT
2028 && class != FP_REGS)
2029 return class;
2031 switch (GET_CODE (op))
2033 /* Constants we cannot reload must be forced into the
2034 literal pool. */
2036 case CONST_DOUBLE:
2037 case CONST_INT:
2038 if (legitimate_reload_constant_p (op))
2039 return class;
2040 else
2041 return NO_REGS;
2043 /* If a symbolic constant or a PLUS is reloaded,
2044 it is most likely being used as an address, so
2045 prefer ADDR_REGS. If 'class' is not a superset
2046 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
2047 case PLUS:
2048 case LABEL_REF:
2049 case SYMBOL_REF:
2050 case CONST:
2051 if (reg_class_subset_p (ADDR_REGS, class))
2052 return ADDR_REGS;
2053 else
2054 return NO_REGS;
2056 default:
2057 break;
2060 return class;
2063 /* Return the register class of a scratch register needed to
2064 load IN into a register of class CLASS in MODE.
2066 We need a temporary when loading a PLUS expression which
2067 is not a legitimate operand of the LOAD ADDRESS instruction. */
2069 enum reg_class
2070 s390_secondary_input_reload_class (enum reg_class class ATTRIBUTE_UNUSED,
2071 enum machine_mode mode, rtx in)
2073 if (s390_plus_operand (in, mode))
2074 return ADDR_REGS;
2076 return NO_REGS;
2079 /* Return the register class of a scratch register needed to
2080 store a register of class CLASS in MODE into OUT:
2082 We need a temporary when storing a double-word to a
2083 non-offsettable memory address. */
2085 enum reg_class
2086 s390_secondary_output_reload_class (enum reg_class class,
2087 enum machine_mode mode, rtx out)
2089 if ((TARGET_64BIT ? mode == TImode
2090 : (mode == DImode || mode == DFmode))
2091 && reg_classes_intersect_p (GENERAL_REGS, class)
2092 && GET_CODE (out) == MEM
2093 && !offsettable_memref_p (out)
2094 && !s_operand (out, VOIDmode))
2095 return ADDR_REGS;
2097 return NO_REGS;
2100 /* Return true if OP is a PLUS that is not a legitimate
2101 operand for the LA instruction.
2102 OP is the current operation.
2103 MODE is the current operation mode. */
2106 s390_plus_operand (register rtx op, enum machine_mode mode)
2108 if (!check_mode (op, &mode) || mode != Pmode)
2109 return FALSE;
2111 if (GET_CODE (op) != PLUS)
2112 return FALSE;
2114 if (legitimate_la_operand_p (op))
2115 return FALSE;
2117 return TRUE;
2120 /* Generate code to load SRC, which is PLUS that is not a
2121 legitimate operand for the LA instruction, into TARGET.
2122 SCRATCH may be used as scratch register. */
2124 void
2125 s390_expand_plus_operand (register rtx target, register rtx src,
2126 register rtx scratch)
2128 rtx sum1, sum2;
2129 struct s390_address ad;
2131 /* src must be a PLUS; get its two operands. */
2132 if (GET_CODE (src) != PLUS || GET_MODE (src) != Pmode)
2133 abort ();
2135 /* Check if any of the two operands is already scheduled
2136 for replacement by reload. This can happen e.g. when
2137 float registers occur in an address. */
2138 sum1 = find_replacement (&XEXP (src, 0));
2139 sum2 = find_replacement (&XEXP (src, 1));
2140 src = gen_rtx_PLUS (Pmode, sum1, sum2);
2142 /* If the address is already strictly valid, there's nothing to do. */
2143 if (!s390_decompose_address (src, &ad)
2144 || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
2145 || (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
2147 /* Otherwise, one of the operands cannot be an address register;
2148 we reload its value into the scratch register. */
2149 if (true_regnum (sum1) < 1 || true_regnum (sum1) > 15)
2151 emit_move_insn (scratch, sum1);
2152 sum1 = scratch;
2154 if (true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
2156 emit_move_insn (scratch, sum2);
2157 sum2 = scratch;
2160 /* According to the way these invalid addresses are generated
2161 in reload.c, it should never happen (at least on s390) that
2162 *neither* of the PLUS components, after find_replacements
2163 was applied, is an address register. */
2164 if (sum1 == scratch && sum2 == scratch)
2166 debug_rtx (src);
2167 abort ();
2170 src = gen_rtx_PLUS (Pmode, sum1, sum2);
2173 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
2174 is only ever performed on addresses, so we can mark the
2175 sum as legitimate for LA in any case. */
2176 s390_load_address (target, src);
2180 /* Decompose a RTL expression ADDR for a memory address into
2181 its components, returned in OUT.
2183 Returns 0 if ADDR is not a valid memory address, nonzero
2184 otherwise. If OUT is NULL, don't return the components,
2185 but check for validity only.
2187 Note: Only addresses in canonical form are recognized.
2188 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
2189 canonical form so that they will be recognized. */
2191 static int
2192 s390_decompose_address (register rtx addr, struct s390_address *out)
2194 HOST_WIDE_INT offset = 0;
2195 rtx base = NULL_RTX;
2196 rtx indx = NULL_RTX;
2197 rtx disp = NULL_RTX;
2198 rtx orig_disp;
2199 int pointer = FALSE;
2200 int base_ptr = FALSE;
2201 int indx_ptr = FALSE;
2203 /* Decompose address into base + index + displacement. */
2205 if (GET_CODE (addr) == REG || GET_CODE (addr) == UNSPEC)
2206 base = addr;
2208 else if (GET_CODE (addr) == PLUS)
2210 rtx op0 = XEXP (addr, 0);
2211 rtx op1 = XEXP (addr, 1);
2212 enum rtx_code code0 = GET_CODE (op0);
2213 enum rtx_code code1 = GET_CODE (op1);
2215 if (code0 == REG || code0 == UNSPEC)
2217 if (code1 == REG || code1 == UNSPEC)
2219 indx = op0; /* index + base */
2220 base = op1;
2223 else
2225 base = op0; /* base + displacement */
2226 disp = op1;
2230 else if (code0 == PLUS)
2232 indx = XEXP (op0, 0); /* index + base + disp */
2233 base = XEXP (op0, 1);
2234 disp = op1;
2237 else
2239 return FALSE;
2243 else
2244 disp = addr; /* displacement */
2246 /* Extract integer part of displacement. */
2247 orig_disp = disp;
2248 if (disp)
2250 if (GET_CODE (disp) == CONST_INT)
2252 offset = INTVAL (disp);
2253 disp = NULL_RTX;
2255 else if (GET_CODE (disp) == CONST
2256 && GET_CODE (XEXP (disp, 0)) == PLUS
2257 && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT)
2259 offset = INTVAL (XEXP (XEXP (disp, 0), 1));
2260 disp = XEXP (XEXP (disp, 0), 0);
2264 /* Strip off CONST here to avoid special case tests later. */
2265 if (disp && GET_CODE (disp) == CONST)
2266 disp = XEXP (disp, 0);
2268 /* We can convert literal pool addresses to
2269 displacements by basing them off the base register. */
2270 if (disp && GET_CODE (disp) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (disp))
2272 /* Either base or index must be free to hold the base register. */
2273 if (!base)
2274 base = gen_rtx_REG (Pmode, BASE_REGNUM);
2275 else if (!indx)
2276 indx = gen_rtx_REG (Pmode, BASE_REGNUM);
2277 else
2278 return FALSE;
2280 /* Mark up the displacement. */
2281 disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp),
2282 UNSPEC_LTREL_OFFSET);
2285 /* Validate base register. */
2286 if (base)
2288 if (GET_CODE (base) == UNSPEC)
2289 switch (XINT (base, 1))
2291 case UNSPEC_LTREF:
2292 if (!disp)
2293 disp = gen_rtx_UNSPEC (Pmode,
2294 gen_rtvec (1, XVECEXP (base, 0, 0)),
2295 UNSPEC_LTREL_OFFSET);
2296 else
2297 return FALSE;
2299 base = gen_rtx_REG (Pmode, BASE_REGNUM);
2300 break;
2302 case UNSPEC_LTREL_BASE:
2303 base = gen_rtx_REG (Pmode, BASE_REGNUM);
2304 break;
2306 default:
2307 return FALSE;
2310 if (GET_CODE (base) != REG || GET_MODE (base) != Pmode)
2311 return FALSE;
2313 if (REGNO (base) == BASE_REGNUM
2314 || REGNO (base) == STACK_POINTER_REGNUM
2315 || REGNO (base) == FRAME_POINTER_REGNUM
2316 || ((reload_completed || reload_in_progress)
2317 && frame_pointer_needed
2318 && REGNO (base) == HARD_FRAME_POINTER_REGNUM)
2319 || REGNO (base) == ARG_POINTER_REGNUM
2320 || (flag_pic
2321 && REGNO (base) == PIC_OFFSET_TABLE_REGNUM))
2322 pointer = base_ptr = TRUE;
2325 /* Validate index register. */
2326 if (indx)
2328 if (GET_CODE (indx) == UNSPEC)
2329 switch (XINT (indx, 1))
2331 case UNSPEC_LTREF:
2332 if (!disp)
2333 disp = gen_rtx_UNSPEC (Pmode,
2334 gen_rtvec (1, XVECEXP (indx, 0, 0)),
2335 UNSPEC_LTREL_OFFSET);
2336 else
2337 return FALSE;
2339 indx = gen_rtx_REG (Pmode, BASE_REGNUM);
2340 break;
2342 case UNSPEC_LTREL_BASE:
2343 indx = gen_rtx_REG (Pmode, BASE_REGNUM);
2344 break;
2346 default:
2347 return FALSE;
2350 if (GET_CODE (indx) != REG || GET_MODE (indx) != Pmode)
2351 return FALSE;
2353 if (REGNO (indx) == BASE_REGNUM
2354 || REGNO (indx) == STACK_POINTER_REGNUM
2355 || REGNO (indx) == FRAME_POINTER_REGNUM
2356 || ((reload_completed || reload_in_progress)
2357 && frame_pointer_needed
2358 && REGNO (indx) == HARD_FRAME_POINTER_REGNUM)
2359 || REGNO (indx) == ARG_POINTER_REGNUM
2360 || (flag_pic
2361 && REGNO (indx) == PIC_OFFSET_TABLE_REGNUM))
2362 pointer = indx_ptr = TRUE;
2365 /* Prefer to use pointer as base, not index. */
2366 if (base && indx && !base_ptr
2367 && (indx_ptr || (!REG_POINTER (base) && REG_POINTER (indx))))
2369 rtx tmp = base;
2370 base = indx;
2371 indx = tmp;
2374 /* Validate displacement. */
2375 if (!disp)
2377 /* If the argument pointer or the return address pointer are involved,
2378 the displacement will change later anyway as the virtual registers get
2379 eliminated. This could make a valid displacement invalid, but it is
2380 more likely to make an invalid displacement valid, because we sometimes
2381 access the register save area via negative offsets to one of those
2382 registers.
2383 Thus we don't check the displacement for validity here. If after
2384 elimination the displacement turns out to be invalid after all,
2385 this is fixed up by reload in any case. */
2386 if (base != arg_pointer_rtx
2387 && indx != arg_pointer_rtx
2388 && base != return_address_pointer_rtx
2389 && indx != return_address_pointer_rtx)
2390 if (!DISP_IN_RANGE (offset))
2391 return FALSE;
2393 else
2395 /* All the special cases are pointers. */
2396 pointer = TRUE;
2398 /* In the small-PIC case, the linker converts @GOT
2399 and @GOTNTPOFF offsets to possible displacements. */
2400 if (GET_CODE (disp) == UNSPEC
2401 && (XINT (disp, 1) == UNSPEC_GOT
2402 || XINT (disp, 1) == UNSPEC_GOTNTPOFF)
2403 && offset == 0
2404 && flag_pic == 1)
2409 /* Accept chunkified literal pool symbol references. */
2410 else if (GET_CODE (disp) == MINUS
2411 && GET_CODE (XEXP (disp, 0)) == LABEL_REF
2412 && GET_CODE (XEXP (disp, 1)) == LABEL_REF)
2417 /* Accept literal pool references. */
2418 else if (GET_CODE (disp) == UNSPEC
2419 && XINT (disp, 1) == UNSPEC_LTREL_OFFSET)
2421 orig_disp = gen_rtx_CONST (Pmode, disp);
2422 if (offset)
2424 /* If we have an offset, make sure it does not
2425 exceed the size of the constant pool entry. */
2426 rtx sym = XVECEXP (disp, 0, 0);
2427 if (offset >= GET_MODE_SIZE (get_pool_mode (sym)))
2428 return FALSE;
2430 orig_disp = plus_constant (orig_disp, offset);
2434 else
2435 return FALSE;
2438 if (!base && !indx)
2439 pointer = TRUE;
2441 if (out)
2443 out->base = base;
2444 out->indx = indx;
2445 out->disp = orig_disp;
2446 out->pointer = pointer;
2449 return TRUE;
2452 /* Return nonzero if ADDR is a valid memory address.
2453 STRICT specifies whether strict register checking applies. */
2456 legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
2457 register rtx addr, int strict)
2459 struct s390_address ad;
2460 if (!s390_decompose_address (addr, &ad))
2461 return FALSE;
2463 if (strict)
2465 if (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
2466 return FALSE;
2467 if (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx))
2468 return FALSE;
2470 else
2472 if (ad.base && !REG_OK_FOR_BASE_NONSTRICT_P (ad.base))
2473 return FALSE;
2474 if (ad.indx && !REG_OK_FOR_INDEX_NONSTRICT_P (ad.indx))
2475 return FALSE;
2478 return TRUE;
2481 /* Return 1 if OP is a valid operand for the LA instruction.
2482 In 31-bit, we need to prove that the result is used as an
2483 address, as LA performs only a 31-bit addition. */
2486 legitimate_la_operand_p (register rtx op)
2488 struct s390_address addr;
2489 if (!s390_decompose_address (op, &addr))
2490 return FALSE;
2492 if (TARGET_64BIT || addr.pointer)
2493 return TRUE;
2495 return FALSE;
2498 /* Return 1 if OP is a valid operand for the LA instruction,
2499 and we prefer to use LA over addition to compute it. */
2502 preferred_la_operand_p (register rtx op)
2504 struct s390_address addr;
2505 if (!s390_decompose_address (op, &addr))
2506 return FALSE;
2508 if (!TARGET_64BIT && !addr.pointer)
2509 return FALSE;
2511 if (addr.pointer)
2512 return TRUE;
2514 if ((addr.base && REG_P (addr.base) && REG_POINTER (addr.base))
2515 || (addr.indx && REG_P (addr.indx) && REG_POINTER (addr.indx)))
2516 return TRUE;
2518 return FALSE;
2521 /* Emit a forced load-address operation to load SRC into DST.
2522 This will use the LOAD ADDRESS instruction even in situations
2523 where legitimate_la_operand_p (SRC) returns false. */
2525 void
2526 s390_load_address (rtx dst, rtx src)
2528 if (TARGET_64BIT)
2529 emit_move_insn (dst, src);
2530 else
2531 emit_insn (gen_force_la_31 (dst, src));
2534 /* Return a legitimate reference for ORIG (an address) using the
2535 register REG. If REG is 0, a new pseudo is generated.
2537 There are two types of references that must be handled:
2539 1. Global data references must load the address from the GOT, via
2540 the PIC reg. An insn is emitted to do this load, and the reg is
2541 returned.
2543 2. Static data references, constant pool addresses, and code labels
2544 compute the address as an offset from the GOT, whose base is in
2545 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
2546 differentiate them from global data objects. The returned
2547 address is the PIC reg + an unspec constant.
2549 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2550 reg also appears in the address. */
2553 legitimize_pic_address (rtx orig, rtx reg)
2555 rtx addr = orig;
2556 rtx new = orig;
2557 rtx base;
2559 if (GET_CODE (addr) == LABEL_REF
2560 || (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (addr)))
2562 /* This is a local symbol. */
2563 if (TARGET_CPU_ZARCH && larl_operand (addr, VOIDmode))
2565 /* Access local symbols PC-relative via LARL.
2566 This is the same as in the non-PIC case, so it is
2567 handled automatically ... */
2569 else
2571 /* Access local symbols relative to the GOT. */
2573 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2575 if (reload_in_progress || reload_completed)
2576 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2578 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
2579 addr = gen_rtx_CONST (Pmode, addr);
2580 addr = force_const_mem (Pmode, addr);
2581 emit_move_insn (temp, addr);
2583 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2584 if (reg != 0)
2586 emit_move_insn (reg, new);
2587 new = reg;
2591 else if (GET_CODE (addr) == SYMBOL_REF)
2593 if (reg == 0)
2594 reg = gen_reg_rtx (Pmode);
2596 if (flag_pic == 1)
2598 /* Assume GOT offset < 4k. This is handled the same way
2599 in both 31- and 64-bit code (@GOT). */
2601 if (reload_in_progress || reload_completed)
2602 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2604 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
2605 new = gen_rtx_CONST (Pmode, new);
2606 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
2607 new = gen_rtx_MEM (Pmode, new);
2608 MEM_READONLY_P (new) = 1;
2609 emit_move_insn (reg, new);
2610 new = reg;
2612 else if (TARGET_CPU_ZARCH)
2614 /* If the GOT offset might be >= 4k, we determine the position
2615 of the GOT entry via a PC-relative LARL (@GOTENT). */
2617 rtx temp = gen_reg_rtx (Pmode);
2619 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTENT);
2620 new = gen_rtx_CONST (Pmode, new);
2621 emit_move_insn (temp, new);
2623 new = gen_rtx_MEM (Pmode, temp);
2624 MEM_READONLY_P (new) = 1;
2625 emit_move_insn (reg, new);
2626 new = reg;
2628 else
2630 /* If the GOT offset might be >= 4k, we have to load it
2631 from the literal pool (@GOT). */
2633 rtx temp = gen_reg_rtx (Pmode);
2635 if (reload_in_progress || reload_completed)
2636 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2638 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
2639 addr = gen_rtx_CONST (Pmode, addr);
2640 addr = force_const_mem (Pmode, addr);
2641 emit_move_insn (temp, addr);
2643 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2644 new = gen_rtx_MEM (Pmode, new);
2645 MEM_READONLY_P (new) = 1;
2646 emit_move_insn (reg, new);
2647 new = reg;
2650 else
2652 if (GET_CODE (addr) == CONST)
2654 addr = XEXP (addr, 0);
2655 if (GET_CODE (addr) == UNSPEC)
2657 if (XVECLEN (addr, 0) != 1)
2658 abort ();
2659 switch (XINT (addr, 1))
2661 /* If someone moved a GOT-relative UNSPEC
2662 out of the literal pool, force them back in. */
2663 case UNSPEC_GOTOFF:
2664 case UNSPEC_PLTOFF:
2665 new = force_const_mem (Pmode, orig);
2666 break;
2668 /* @GOT is OK as is if small. */
2669 case UNSPEC_GOT:
2670 if (flag_pic == 2)
2671 new = force_const_mem (Pmode, orig);
2672 break;
2674 /* @GOTENT is OK as is. */
2675 case UNSPEC_GOTENT:
2676 break;
2678 /* @PLT is OK as is on 64-bit, must be converted to
2679 GOT-relative @PLTOFF on 31-bit. */
2680 case UNSPEC_PLT:
2681 if (!TARGET_CPU_ZARCH)
2683 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2685 if (reload_in_progress || reload_completed)
2686 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2688 addr = XVECEXP (addr, 0, 0);
2689 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
2690 UNSPEC_PLTOFF);
2691 addr = gen_rtx_CONST (Pmode, addr);
2692 addr = force_const_mem (Pmode, addr);
2693 emit_move_insn (temp, addr);
2695 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2696 if (reg != 0)
2698 emit_move_insn (reg, new);
2699 new = reg;
2702 break;
2704 /* Everything else cannot happen. */
2705 default:
2706 abort ();
2709 else if (GET_CODE (addr) != PLUS)
2710 abort ();
2712 if (GET_CODE (addr) == PLUS)
2714 rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
2715 /* Check first to see if this is a constant offset
2716 from a local symbol reference. */
2717 if ((GET_CODE (op0) == LABEL_REF
2718 || (GET_CODE (op0) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op0)))
2719 && GET_CODE (op1) == CONST_INT)
2721 if (TARGET_CPU_ZARCH && larl_operand (op0, VOIDmode))
2723 if (INTVAL (op1) & 1)
2725 /* LARL can't handle odd offsets, so emit a
2726 pair of LARL and LA. */
2727 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2729 if (!DISP_IN_RANGE (INTVAL (op1)))
2731 int even = INTVAL (op1) - 1;
2732 op0 = gen_rtx_PLUS (Pmode, op0, GEN_INT (even));
2733 op0 = gen_rtx_CONST (Pmode, op0);
2734 op1 = const1_rtx;
2737 emit_move_insn (temp, op0);
2738 new = gen_rtx_PLUS (Pmode, temp, op1);
2740 if (reg != 0)
2742 emit_move_insn (reg, new);
2743 new = reg;
2746 else
2748 /* If the offset is even, we can just use LARL.
2749 This will happen automatically. */
2752 else
2754 /* Access local symbols relative to the GOT. */
2756 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2758 if (reload_in_progress || reload_completed)
2759 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2761 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
2762 UNSPEC_GOTOFF);
2763 addr = gen_rtx_PLUS (Pmode, addr, op1);
2764 addr = gen_rtx_CONST (Pmode, addr);
2765 addr = force_const_mem (Pmode, addr);
2766 emit_move_insn (temp, addr);
2768 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2769 if (reg != 0)
2771 emit_move_insn (reg, new);
2772 new = reg;
2777 /* Now, check whether it is a GOT relative symbol plus offset
2778 that was pulled out of the literal pool. Force it back in. */
2780 else if (GET_CODE (op0) == UNSPEC
2781 && GET_CODE (op1) == CONST_INT
2782 && XINT (op0, 1) == UNSPEC_GOTOFF)
2784 if (XVECLEN (op0, 0) != 1)
2785 abort ();
2787 new = force_const_mem (Pmode, orig);
2790 /* Otherwise, compute the sum. */
2791 else
2793 base = legitimize_pic_address (XEXP (addr, 0), reg);
2794 new = legitimize_pic_address (XEXP (addr, 1),
2795 base == reg ? NULL_RTX : reg);
2796 if (GET_CODE (new) == CONST_INT)
2797 new = plus_constant (base, INTVAL (new));
2798 else
2800 if (GET_CODE (new) == PLUS && CONSTANT_P (XEXP (new, 1)))
2802 base = gen_rtx_PLUS (Pmode, base, XEXP (new, 0));
2803 new = XEXP (new, 1);
2805 new = gen_rtx_PLUS (Pmode, base, new);
2808 if (GET_CODE (new) == CONST)
2809 new = XEXP (new, 0);
2810 new = force_operand (new, 0);
2814 return new;
2817 /* Load the thread pointer into a register. */
2819 static rtx
2820 get_thread_pointer (void)
2822 rtx tp;
2824 tp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
2825 tp = force_reg (Pmode, tp);
2826 mark_reg_pointer (tp, BITS_PER_WORD);
2828 return tp;
2831 /* Emit a tls call insn. The call target is the SYMBOL_REF stored
2832 in s390_tls_symbol which always refers to __tls_get_offset.
2833 The returned offset is written to RESULT_REG and an USE rtx is
2834 generated for TLS_CALL. */
2836 static GTY(()) rtx s390_tls_symbol;
2838 static void
2839 s390_emit_tls_call_insn (rtx result_reg, rtx tls_call)
2841 rtx insn;
2843 if (!flag_pic)
2844 abort ();
2846 if (!s390_tls_symbol)
2847 s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset");
2849 insn = s390_emit_call (s390_tls_symbol, tls_call, result_reg,
2850 gen_rtx_REG (Pmode, RETURN_REGNUM));
2852 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), result_reg);
2853 CONST_OR_PURE_CALL_P (insn) = 1;
2856 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
2857 this (thread-local) address. REG may be used as temporary. */
2859 static rtx
2860 legitimize_tls_address (rtx addr, rtx reg)
2862 rtx new, tls_call, temp, base, r2, insn;
2864 if (GET_CODE (addr) == SYMBOL_REF)
2865 switch (tls_symbolic_operand (addr))
2867 case TLS_MODEL_GLOBAL_DYNAMIC:
2868 start_sequence ();
2869 r2 = gen_rtx_REG (Pmode, 2);
2870 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLSGD);
2871 new = gen_rtx_CONST (Pmode, tls_call);
2872 new = force_const_mem (Pmode, new);
2873 emit_move_insn (r2, new);
2874 s390_emit_tls_call_insn (r2, tls_call);
2875 insn = get_insns ();
2876 end_sequence ();
2878 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
2879 temp = gen_reg_rtx (Pmode);
2880 emit_libcall_block (insn, temp, r2, new);
2882 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2883 if (reg != 0)
2885 s390_load_address (reg, new);
2886 new = reg;
2888 break;
2890 case TLS_MODEL_LOCAL_DYNAMIC:
2891 start_sequence ();
2892 r2 = gen_rtx_REG (Pmode, 2);
2893 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM);
2894 new = gen_rtx_CONST (Pmode, tls_call);
2895 new = force_const_mem (Pmode, new);
2896 emit_move_insn (r2, new);
2897 s390_emit_tls_call_insn (r2, tls_call);
2898 insn = get_insns ();
2899 end_sequence ();
2901 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM_NTPOFF);
2902 temp = gen_reg_rtx (Pmode);
2903 emit_libcall_block (insn, temp, r2, new);
2905 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2906 base = gen_reg_rtx (Pmode);
2907 s390_load_address (base, new);
2909 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_DTPOFF);
2910 new = gen_rtx_CONST (Pmode, new);
2911 new = force_const_mem (Pmode, new);
2912 temp = gen_reg_rtx (Pmode);
2913 emit_move_insn (temp, new);
2915 new = gen_rtx_PLUS (Pmode, base, temp);
2916 if (reg != 0)
2918 s390_load_address (reg, new);
2919 new = reg;
2921 break;
2923 case TLS_MODEL_INITIAL_EXEC:
2924 if (flag_pic == 1)
2926 /* Assume GOT offset < 4k. This is handled the same way
2927 in both 31- and 64-bit code. */
2929 if (reload_in_progress || reload_completed)
2930 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2932 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
2933 new = gen_rtx_CONST (Pmode, new);
2934 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
2935 new = gen_rtx_MEM (Pmode, new);
2936 MEM_READONLY_P (new) = 1;
2937 temp = gen_reg_rtx (Pmode);
2938 emit_move_insn (temp, new);
2940 else if (TARGET_CPU_ZARCH)
2942 /* If the GOT offset might be >= 4k, we determine the position
2943 of the GOT entry via a PC-relative LARL. */
2945 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
2946 new = gen_rtx_CONST (Pmode, new);
2947 temp = gen_reg_rtx (Pmode);
2948 emit_move_insn (temp, new);
2950 new = gen_rtx_MEM (Pmode, temp);
2951 MEM_READONLY_P (new) = 1;
2952 temp = gen_reg_rtx (Pmode);
2953 emit_move_insn (temp, new);
2955 else if (flag_pic)
2957 /* If the GOT offset might be >= 4k, we have to load it
2958 from the literal pool. */
2960 if (reload_in_progress || reload_completed)
2961 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2963 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
2964 new = gen_rtx_CONST (Pmode, new);
2965 new = force_const_mem (Pmode, new);
2966 temp = gen_reg_rtx (Pmode);
2967 emit_move_insn (temp, new);
2969 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2970 new = gen_rtx_MEM (Pmode, new);
2971 MEM_READONLY_P (new) = 1;
2973 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new, addr), UNSPEC_TLS_LOAD);
2974 temp = gen_reg_rtx (Pmode);
2975 emit_insn (gen_rtx_SET (Pmode, temp, new));
2977 else
2979 /* In position-dependent code, load the absolute address of
2980 the GOT entry from the literal pool. */
2982 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
2983 new = gen_rtx_CONST (Pmode, new);
2984 new = force_const_mem (Pmode, new);
2985 temp = gen_reg_rtx (Pmode);
2986 emit_move_insn (temp, new);
2988 new = temp;
2989 new = gen_rtx_MEM (Pmode, new);
2990 MEM_READONLY_P (new) = 1;
2992 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new, addr), UNSPEC_TLS_LOAD);
2993 temp = gen_reg_rtx (Pmode);
2994 emit_insn (gen_rtx_SET (Pmode, temp, new));
2997 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2998 if (reg != 0)
3000 s390_load_address (reg, new);
3001 new = reg;
3003 break;
3005 case TLS_MODEL_LOCAL_EXEC:
3006 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
3007 new = gen_rtx_CONST (Pmode, new);
3008 new = force_const_mem (Pmode, new);
3009 temp = gen_reg_rtx (Pmode);
3010 emit_move_insn (temp, new);
3012 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
3013 if (reg != 0)
3015 s390_load_address (reg, new);
3016 new = reg;
3018 break;
3020 default:
3021 abort ();
3024 else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == UNSPEC)
3026 switch (XINT (XEXP (addr, 0), 1))
3028 case UNSPEC_INDNTPOFF:
3029 if (TARGET_CPU_ZARCH)
3030 new = addr;
3031 else
3032 abort ();
3033 break;
3035 default:
3036 abort ();
3040 else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == PLUS
3041 && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
3043 new = XEXP (XEXP (addr, 0), 0);
3044 if (GET_CODE (new) != SYMBOL_REF)
3045 new = gen_rtx_CONST (Pmode, new);
3047 new = legitimize_tls_address (new, reg);
3048 new = plus_constant (new, INTVAL (XEXP (XEXP (addr, 0), 1)));
3049 new = force_operand (new, 0);
3052 else
3053 abort (); /* for now ... */
3055 return new;
3058 /* Emit insns to move operands[1] into operands[0]. */
3060 void
3061 emit_symbolic_move (rtx *operands)
3063 rtx temp = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
3065 if (GET_CODE (operands[0]) == MEM)
3066 operands[1] = force_reg (Pmode, operands[1]);
3067 else if (TLS_SYMBOLIC_CONST (operands[1]))
3068 operands[1] = legitimize_tls_address (operands[1], temp);
3069 else if (flag_pic)
3070 operands[1] = legitimize_pic_address (operands[1], temp);
3073 /* Try machine-dependent ways of modifying an illegitimate address X
3074 to be legitimate. If we find one, return the new, valid address.
3076 OLDX is the address as it was before break_out_memory_refs was called.
3077 In some cases it is useful to look at this to decide what needs to be done.
3079 MODE is the mode of the operand pointed to by X.
3081 When -fpic is used, special handling is needed for symbolic references.
3082 See comments by legitimize_pic_address for details. */
3085 legitimize_address (register rtx x, register rtx oldx ATTRIBUTE_UNUSED,
3086 enum machine_mode mode ATTRIBUTE_UNUSED)
3088 rtx constant_term = const0_rtx;
3090 if (TLS_SYMBOLIC_CONST (x))
3092 x = legitimize_tls_address (x, 0);
3094 if (legitimate_address_p (mode, x, FALSE))
3095 return x;
3097 else if (flag_pic)
3099 if (SYMBOLIC_CONST (x)
3100 || (GET_CODE (x) == PLUS
3101 && (SYMBOLIC_CONST (XEXP (x, 0))
3102 || SYMBOLIC_CONST (XEXP (x, 1)))))
3103 x = legitimize_pic_address (x, 0);
3105 if (legitimate_address_p (mode, x, FALSE))
3106 return x;
3109 x = eliminate_constant_term (x, &constant_term);
3111 /* Optimize loading of large displacements by splitting them
3112 into the multiple of 4K and the rest; this allows the
3113 former to be CSE'd if possible.
3115 Don't do this if the displacement is added to a register
3116 pointing into the stack frame, as the offsets will
3117 change later anyway. */
3119 if (GET_CODE (constant_term) == CONST_INT
3120 && !TARGET_LONG_DISPLACEMENT
3121 && !DISP_IN_RANGE (INTVAL (constant_term))
3122 && !(REG_P (x) && REGNO_PTR_FRAME_P (REGNO (x))))
3124 HOST_WIDE_INT lower = INTVAL (constant_term) & 0xfff;
3125 HOST_WIDE_INT upper = INTVAL (constant_term) ^ lower;
3127 rtx temp = gen_reg_rtx (Pmode);
3128 rtx val = force_operand (GEN_INT (upper), temp);
3129 if (val != temp)
3130 emit_move_insn (temp, val);
3132 x = gen_rtx_PLUS (Pmode, x, temp);
3133 constant_term = GEN_INT (lower);
3136 if (GET_CODE (x) == PLUS)
3138 if (GET_CODE (XEXP (x, 0)) == REG)
3140 register rtx temp = gen_reg_rtx (Pmode);
3141 register rtx val = force_operand (XEXP (x, 1), temp);
3142 if (val != temp)
3143 emit_move_insn (temp, val);
3145 x = gen_rtx_PLUS (Pmode, XEXP (x, 0), temp);
3148 else if (GET_CODE (XEXP (x, 1)) == REG)
3150 register rtx temp = gen_reg_rtx (Pmode);
3151 register rtx val = force_operand (XEXP (x, 0), temp);
3152 if (val != temp)
3153 emit_move_insn (temp, val);
3155 x = gen_rtx_PLUS (Pmode, temp, XEXP (x, 1));
3159 if (constant_term != const0_rtx)
3160 x = gen_rtx_PLUS (Pmode, x, constant_term);
3162 return x;
3165 /* Emit code to move LEN bytes from DST to SRC. */
3167 void
3168 s390_expand_movmem (rtx dst, rtx src, rtx len)
3170 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
3172 if (INTVAL (len) > 0)
3173 emit_insn (gen_movmem_short (dst, src, GEN_INT (INTVAL (len) - 1)));
3176 else if (TARGET_MVCLE)
3178 emit_insn (gen_movmem_long (dst, src, convert_to_mode (Pmode, len, 1)));
3181 else
3183 rtx dst_addr, src_addr, count, blocks, temp;
3184 rtx loop_start_label = gen_label_rtx ();
3185 rtx loop_end_label = gen_label_rtx ();
3186 rtx end_label = gen_label_rtx ();
3187 enum machine_mode mode;
3189 mode = GET_MODE (len);
3190 if (mode == VOIDmode)
3191 mode = Pmode;
3193 dst_addr = gen_reg_rtx (Pmode);
3194 src_addr = gen_reg_rtx (Pmode);
3195 count = gen_reg_rtx (mode);
3196 blocks = gen_reg_rtx (mode);
3198 convert_move (count, len, 1);
3199 emit_cmp_and_jump_insns (count, const0_rtx,
3200 EQ, NULL_RTX, mode, 1, end_label);
3202 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
3203 emit_move_insn (src_addr, force_operand (XEXP (src, 0), NULL_RTX));
3204 dst = change_address (dst, VOIDmode, dst_addr);
3205 src = change_address (src, VOIDmode, src_addr);
3207 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3208 if (temp != count)
3209 emit_move_insn (count, temp);
3211 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
3212 if (temp != blocks)
3213 emit_move_insn (blocks, temp);
3215 emit_cmp_and_jump_insns (blocks, const0_rtx,
3216 EQ, NULL_RTX, mode, 1, loop_end_label);
3218 emit_label (loop_start_label);
3220 emit_insn (gen_movmem_short (dst, src, GEN_INT (255)));
3221 s390_load_address (dst_addr,
3222 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
3223 s390_load_address (src_addr,
3224 gen_rtx_PLUS (Pmode, src_addr, GEN_INT (256)));
3226 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3227 if (temp != blocks)
3228 emit_move_insn (blocks, temp);
3230 emit_cmp_and_jump_insns (blocks, const0_rtx,
3231 EQ, NULL_RTX, mode, 1, loop_end_label);
3233 emit_jump (loop_start_label);
3234 emit_label (loop_end_label);
3236 emit_insn (gen_movmem_short (dst, src,
3237 convert_to_mode (Pmode, count, 1)));
3238 emit_label (end_label);
3242 /* Emit code to clear LEN bytes at DST. */
3244 void
3245 s390_expand_clrmem (rtx dst, rtx len)
3247 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
3249 if (INTVAL (len) > 0)
3250 emit_insn (gen_clrmem_short (dst, GEN_INT (INTVAL (len) - 1)));
3253 else if (TARGET_MVCLE)
3255 emit_insn (gen_clrmem_long (dst, convert_to_mode (Pmode, len, 1)));
3258 else
3260 rtx dst_addr, src_addr, count, blocks, temp;
3261 rtx loop_start_label = gen_label_rtx ();
3262 rtx loop_end_label = gen_label_rtx ();
3263 rtx end_label = gen_label_rtx ();
3264 enum machine_mode mode;
3266 mode = GET_MODE (len);
3267 if (mode == VOIDmode)
3268 mode = Pmode;
3270 dst_addr = gen_reg_rtx (Pmode);
3271 src_addr = gen_reg_rtx (Pmode);
3272 count = gen_reg_rtx (mode);
3273 blocks = gen_reg_rtx (mode);
3275 convert_move (count, len, 1);
3276 emit_cmp_and_jump_insns (count, const0_rtx,
3277 EQ, NULL_RTX, mode, 1, end_label);
3279 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
3280 dst = change_address (dst, VOIDmode, dst_addr);
3282 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3283 if (temp != count)
3284 emit_move_insn (count, temp);
3286 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
3287 if (temp != blocks)
3288 emit_move_insn (blocks, temp);
3290 emit_cmp_and_jump_insns (blocks, const0_rtx,
3291 EQ, NULL_RTX, mode, 1, loop_end_label);
3293 emit_label (loop_start_label);
3295 emit_insn (gen_clrmem_short (dst, GEN_INT (255)));
3296 s390_load_address (dst_addr,
3297 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
3299 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3300 if (temp != blocks)
3301 emit_move_insn (blocks, temp);
3303 emit_cmp_and_jump_insns (blocks, const0_rtx,
3304 EQ, NULL_RTX, mode, 1, loop_end_label);
3306 emit_jump (loop_start_label);
3307 emit_label (loop_end_label);
3309 emit_insn (gen_clrmem_short (dst, convert_to_mode (Pmode, count, 1)));
3310 emit_label (end_label);
3314 /* Emit code to compare LEN bytes at OP0 with those at OP1,
3315 and return the result in TARGET. */
3317 void
3318 s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
3320 rtx (*gen_result) (rtx) =
3321 GET_MODE (target) == DImode ? gen_cmpint_di : gen_cmpint_si;
3323 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
3325 if (INTVAL (len) > 0)
3327 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (INTVAL (len) - 1)));
3328 emit_insn (gen_result (target));
3330 else
3331 emit_move_insn (target, const0_rtx);
3334 else /* if (TARGET_MVCLE) */
3336 emit_insn (gen_cmpmem_long (op0, op1, convert_to_mode (Pmode, len, 1)));
3337 emit_insn (gen_result (target));
3340 #if 0
3341 /* Deactivate for now as profile code cannot cope with
3342 CC being live across basic block boundaries. */
3343 else
3345 rtx addr0, addr1, count, blocks, temp;
3346 rtx loop_start_label = gen_label_rtx ();
3347 rtx loop_end_label = gen_label_rtx ();
3348 rtx end_label = gen_label_rtx ();
3349 enum machine_mode mode;
3351 mode = GET_MODE (len);
3352 if (mode == VOIDmode)
3353 mode = Pmode;
3355 addr0 = gen_reg_rtx (Pmode);
3356 addr1 = gen_reg_rtx (Pmode);
3357 count = gen_reg_rtx (mode);
3358 blocks = gen_reg_rtx (mode);
3360 convert_move (count, len, 1);
3361 emit_cmp_and_jump_insns (count, const0_rtx,
3362 EQ, NULL_RTX, mode, 1, end_label);
3364 emit_move_insn (addr0, force_operand (XEXP (op0, 0), NULL_RTX));
3365 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
3366 op0 = change_address (op0, VOIDmode, addr0);
3367 op1 = change_address (op1, VOIDmode, addr1);
3369 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3370 if (temp != count)
3371 emit_move_insn (count, temp);
3373 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
3374 if (temp != blocks)
3375 emit_move_insn (blocks, temp);
3377 emit_cmp_and_jump_insns (blocks, const0_rtx,
3378 EQ, NULL_RTX, mode, 1, loop_end_label);
3380 emit_label (loop_start_label);
3382 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (255)));
3383 temp = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCSmode, 33), const0_rtx);
3384 temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
3385 gen_rtx_LABEL_REF (VOIDmode, end_label), pc_rtx);
3386 temp = gen_rtx_SET (VOIDmode, pc_rtx, temp);
3387 emit_jump_insn (temp);
3389 s390_load_address (addr0,
3390 gen_rtx_PLUS (Pmode, addr0, GEN_INT (256)));
3391 s390_load_address (addr1,
3392 gen_rtx_PLUS (Pmode, addr1, GEN_INT (256)));
3394 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3395 if (temp != blocks)
3396 emit_move_insn (blocks, temp);
3398 emit_cmp_and_jump_insns (blocks, const0_rtx,
3399 EQ, NULL_RTX, mode, 1, loop_end_label);
3401 emit_jump (loop_start_label);
3402 emit_label (loop_end_label);
3404 emit_insn (gen_cmpmem_short (op0, op1,
3405 convert_to_mode (Pmode, count, 1)));
3406 emit_label (end_label);
3408 emit_insn (gen_result (target));
3410 #endif
3414 /* Expand conditional increment or decrement using alc/slb instructions.
3415 Should generate code setting DST to either SRC or SRC + INCREMENT,
3416 depending on the result of the comparison CMP_OP0 CMP_CODE CMP_OP1.
3417 Returns true if successful, false otherwise. */
3419 bool
3420 s390_expand_addcc (enum rtx_code cmp_code, rtx cmp_op0, rtx cmp_op1,
3421 rtx dst, rtx src, rtx increment)
3423 enum machine_mode cmp_mode;
3424 enum machine_mode cc_mode;
3425 rtx op_res;
3426 rtx insn;
3427 rtvec p;
3429 if ((GET_MODE (cmp_op0) == SImode || GET_MODE (cmp_op0) == VOIDmode)
3430 && (GET_MODE (cmp_op1) == SImode || GET_MODE (cmp_op1) == VOIDmode))
3431 cmp_mode = SImode;
3432 else if ((GET_MODE (cmp_op0) == DImode || GET_MODE (cmp_op0) == VOIDmode)
3433 && (GET_MODE (cmp_op1) == DImode || GET_MODE (cmp_op1) == VOIDmode))
3434 cmp_mode = DImode;
3435 else
3436 return false;
3438 /* Try ADD LOGICAL WITH CARRY. */
3439 if (increment == const1_rtx)
3441 /* Determine CC mode to use. */
3442 if (cmp_code == EQ || cmp_code == NE)
3444 if (cmp_op1 != const0_rtx)
3446 cmp_op0 = expand_simple_binop (cmp_mode, XOR, cmp_op0, cmp_op1,
3447 NULL_RTX, 0, OPTAB_WIDEN);
3448 cmp_op1 = const0_rtx;
3451 cmp_code = cmp_code == EQ ? LEU : GTU;
3454 if (cmp_code == LTU || cmp_code == LEU)
3456 rtx tem = cmp_op0;
3457 cmp_op0 = cmp_op1;
3458 cmp_op1 = tem;
3459 cmp_code = swap_condition (cmp_code);
3462 switch (cmp_code)
3464 case GTU:
3465 cc_mode = CCUmode;
3466 break;
3468 case GEU:
3469 cc_mode = CCL3mode;
3470 break;
3472 default:
3473 return false;
3476 /* Emit comparison instruction pattern. */
3477 if (!register_operand (cmp_op0, cmp_mode))
3478 cmp_op0 = force_reg (cmp_mode, cmp_op0);
3480 insn = gen_rtx_SET (VOIDmode, gen_rtx_REG (cc_mode, CC_REGNUM),
3481 gen_rtx_COMPARE (cc_mode, cmp_op0, cmp_op1));
3482 /* We use insn_invalid_p here to add clobbers if required. */
3483 if (insn_invalid_p (emit_insn (insn)))
3484 abort ();
3486 /* Emit ALC instruction pattern. */
3487 op_res = gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
3488 gen_rtx_REG (cc_mode, CC_REGNUM),
3489 const0_rtx);
3491 if (src != const0_rtx)
3493 if (!register_operand (src, GET_MODE (dst)))
3494 src = force_reg (GET_MODE (dst), src);
3496 src = gen_rtx_PLUS (GET_MODE (dst), src, const0_rtx);
3497 op_res = gen_rtx_PLUS (GET_MODE (dst), src, op_res);
3500 p = rtvec_alloc (2);
3501 RTVEC_ELT (p, 0) =
3502 gen_rtx_SET (VOIDmode, dst, op_res);
3503 RTVEC_ELT (p, 1) =
3504 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
3505 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
3507 return true;
3510 /* Try SUBTRACT LOGICAL WITH BORROW. */
3511 if (increment == constm1_rtx)
3513 /* Determine CC mode to use. */
3514 if (cmp_code == EQ || cmp_code == NE)
3516 if (cmp_op1 != const0_rtx)
3518 cmp_op0 = expand_simple_binop (cmp_mode, XOR, cmp_op0, cmp_op1,
3519 NULL_RTX, 0, OPTAB_WIDEN);
3520 cmp_op1 = const0_rtx;
3523 cmp_code = cmp_code == EQ ? LEU : GTU;
3526 if (cmp_code == GTU || cmp_code == GEU)
3528 rtx tem = cmp_op0;
3529 cmp_op0 = cmp_op1;
3530 cmp_op1 = tem;
3531 cmp_code = swap_condition (cmp_code);
3534 switch (cmp_code)
3536 case LEU:
3537 cc_mode = CCUmode;
3538 break;
3540 case LTU:
3541 cc_mode = CCL3mode;
3542 break;
3544 default:
3545 return false;
3548 /* Emit comparison instruction pattern. */
3549 if (!register_operand (cmp_op0, cmp_mode))
3550 cmp_op0 = force_reg (cmp_mode, cmp_op0);
3552 insn = gen_rtx_SET (VOIDmode, gen_rtx_REG (cc_mode, CC_REGNUM),
3553 gen_rtx_COMPARE (cc_mode, cmp_op0, cmp_op1));
3554 /* We use insn_invalid_p here to add clobbers if required. */
3555 if (insn_invalid_p (emit_insn (insn)))
3556 abort ();
3558 /* Emit SLB instruction pattern. */
3559 if (!register_operand (src, GET_MODE (dst)))
3560 src = force_reg (GET_MODE (dst), src);
3562 op_res = gen_rtx_MINUS (GET_MODE (dst),
3563 gen_rtx_MINUS (GET_MODE (dst), src, const0_rtx),
3564 gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
3565 gen_rtx_REG (cc_mode, CC_REGNUM),
3566 const0_rtx));
3567 p = rtvec_alloc (2);
3568 RTVEC_ELT (p, 0) =
3569 gen_rtx_SET (VOIDmode, dst, op_res);
3570 RTVEC_ELT (p, 1) =
3571 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
3572 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
3574 return true;
3577 return false;
3581 /* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
3582 We need to emit DTP-relative relocations. */
3584 void
3585 s390_output_dwarf_dtprel (FILE *file, int size, rtx x)
3587 switch (size)
3589 case 4:
3590 fputs ("\t.long\t", file);
3591 break;
3592 case 8:
3593 fputs ("\t.quad\t", file);
3594 break;
3595 default:
3596 abort ();
3598 output_addr_const (file, x);
3599 fputs ("@DTPOFF", file);
3602 /* In the name of slightly smaller debug output, and to cater to
3603 general assembler losage, recognize various UNSPEC sequences
3604 and turn them back into a direct symbol reference. */
3606 static rtx
3607 s390_delegitimize_address (rtx orig_x)
3609 rtx x = orig_x, y;
3611 if (GET_CODE (x) != MEM)
3612 return orig_x;
3614 x = XEXP (x, 0);
3615 if (GET_CODE (x) == PLUS
3616 && GET_CODE (XEXP (x, 1)) == CONST
3617 && GET_CODE (XEXP (x, 0)) == REG
3618 && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM)
3620 y = XEXP (XEXP (x, 1), 0);
3621 if (GET_CODE (y) == UNSPEC
3622 && XINT (y, 1) == UNSPEC_GOT)
3623 return XVECEXP (y, 0, 0);
3624 return orig_x;
3627 if (GET_CODE (x) == CONST)
3629 y = XEXP (x, 0);
3630 if (GET_CODE (y) == UNSPEC
3631 && XINT (y, 1) == UNSPEC_GOTENT)
3632 return XVECEXP (y, 0, 0);
3633 return orig_x;
3636 return orig_x;
3639 /* Output shift count operand OP to stdio stream FILE. */
3641 static void
3642 print_shift_count_operand (FILE *file, rtx op)
3644 HOST_WIDE_INT offset = 0;
3646 /* We can have an integer constant, an address register,
3647 or a sum of the two. */
3648 if (GET_CODE (op) == CONST_INT)
3650 offset = INTVAL (op);
3651 op = NULL_RTX;
3653 if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
3655 offset = INTVAL (XEXP (op, 1));
3656 op = XEXP (op, 0);
3658 while (op && GET_CODE (op) == SUBREG)
3659 op = SUBREG_REG (op);
3661 /* Sanity check. */
3662 if (op && (GET_CODE (op) != REG
3663 || REGNO (op) >= FIRST_PSEUDO_REGISTER
3664 || REGNO_REG_CLASS (REGNO (op)) != ADDR_REGS))
3665 abort ();
3667 /* Shift counts are truncated to the low six bits anyway. */
3668 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset & 63);
3669 if (op)
3670 fprintf (file, "(%s)", reg_names[REGNO (op)]);
3673 /* Locate some local-dynamic symbol still in use by this function
3674 so that we can print its name in local-dynamic base patterns. */
3676 static const char *
3677 get_some_local_dynamic_name (void)
3679 rtx insn;
3681 if (cfun->machine->some_ld_name)
3682 return cfun->machine->some_ld_name;
3684 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
3685 if (INSN_P (insn)
3686 && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
3687 return cfun->machine->some_ld_name;
3689 abort ();
3692 static int
3693 get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
3695 rtx x = *px;
3697 if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
3699 x = get_pool_constant (x);
3700 return for_each_rtx (&x, get_some_local_dynamic_name_1, 0);
3703 if (GET_CODE (x) == SYMBOL_REF
3704 && tls_symbolic_operand (x) == TLS_MODEL_LOCAL_DYNAMIC)
3706 cfun->machine->some_ld_name = XSTR (x, 0);
3707 return 1;
3710 return 0;
3713 /* Output machine-dependent UNSPECs occurring in address constant X
3714 in assembler syntax to stdio stream FILE. Returns true if the
3715 constant X could be recognized, false otherwise. */
3717 bool
3718 s390_output_addr_const_extra (FILE *file, rtx x)
3720 if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 1)
3721 switch (XINT (x, 1))
3723 case UNSPEC_GOTENT:
3724 output_addr_const (file, XVECEXP (x, 0, 0));
3725 fprintf (file, "@GOTENT");
3726 return true;
3727 case UNSPEC_GOT:
3728 output_addr_const (file, XVECEXP (x, 0, 0));
3729 fprintf (file, "@GOT");
3730 return true;
3731 case UNSPEC_GOTOFF:
3732 output_addr_const (file, XVECEXP (x, 0, 0));
3733 fprintf (file, "@GOTOFF");
3734 return true;
3735 case UNSPEC_PLT:
3736 output_addr_const (file, XVECEXP (x, 0, 0));
3737 fprintf (file, "@PLT");
3738 return true;
3739 case UNSPEC_PLTOFF:
3740 output_addr_const (file, XVECEXP (x, 0, 0));
3741 fprintf (file, "@PLTOFF");
3742 return true;
3743 case UNSPEC_TLSGD:
3744 output_addr_const (file, XVECEXP (x, 0, 0));
3745 fprintf (file, "@TLSGD");
3746 return true;
3747 case UNSPEC_TLSLDM:
3748 assemble_name (file, get_some_local_dynamic_name ());
3749 fprintf (file, "@TLSLDM");
3750 return true;
3751 case UNSPEC_DTPOFF:
3752 output_addr_const (file, XVECEXP (x, 0, 0));
3753 fprintf (file, "@DTPOFF");
3754 return true;
3755 case UNSPEC_NTPOFF:
3756 output_addr_const (file, XVECEXP (x, 0, 0));
3757 fprintf (file, "@NTPOFF");
3758 return true;
3759 case UNSPEC_GOTNTPOFF:
3760 output_addr_const (file, XVECEXP (x, 0, 0));
3761 fprintf (file, "@GOTNTPOFF");
3762 return true;
3763 case UNSPEC_INDNTPOFF:
3764 output_addr_const (file, XVECEXP (x, 0, 0));
3765 fprintf (file, "@INDNTPOFF");
3766 return true;
3769 return false;
3772 /* Output address operand ADDR in assembler syntax to
3773 stdio stream FILE. */
3775 void
3776 print_operand_address (FILE *file, rtx addr)
3778 struct s390_address ad;
3780 if (!s390_decompose_address (addr, &ad)
3781 || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
3782 || (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
3783 output_operand_lossage ("Cannot decompose address.");
3785 if (ad.disp)
3786 output_addr_const (file, ad.disp);
3787 else
3788 fprintf (file, "0");
3790 if (ad.base && ad.indx)
3791 fprintf (file, "(%s,%s)", reg_names[REGNO (ad.indx)],
3792 reg_names[REGNO (ad.base)]);
3793 else if (ad.base)
3794 fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
3797 /* Output operand X in assembler syntax to stdio stream FILE.
3798 CODE specified the format flag. The following format flags
3799 are recognized:
3801 'C': print opcode suffix for branch condition.
3802 'D': print opcode suffix for inverse branch condition.
3803 'J': print tls_load/tls_gdcall/tls_ldcall suffix
3804 'O': print only the displacement of a memory reference.
3805 'R': print only the base register of a memory reference.
3806 'N': print the second word of a DImode operand.
3807 'M': print the second word of a TImode operand.
3808 'Y': print shift count operand.
3810 'b': print integer X as if it's an unsigned byte.
3811 'x': print integer X as if it's an unsigned word.
3812 'h': print integer X as if it's a signed word.
3813 'i': print the first nonzero HImode part of X.
3814 'j': print the first HImode part unequal to 0xffff of X. */
3816 void
3817 print_operand (FILE *file, rtx x, int code)
3819 switch (code)
3821 case 'C':
3822 fprintf (file, s390_branch_condition_mnemonic (x, FALSE));
3823 return;
3825 case 'D':
3826 fprintf (file, s390_branch_condition_mnemonic (x, TRUE));
3827 return;
3829 case 'J':
3830 if (GET_CODE (x) == SYMBOL_REF)
3832 fprintf (file, "%s", ":tls_load:");
3833 output_addr_const (file, x);
3835 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD)
3837 fprintf (file, "%s", ":tls_gdcall:");
3838 output_addr_const (file, XVECEXP (x, 0, 0));
3840 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM)
3842 fprintf (file, "%s", ":tls_ldcall:");
3843 assemble_name (file, get_some_local_dynamic_name ());
3845 else
3846 abort ();
3847 return;
3849 case 'O':
3851 struct s390_address ad;
3853 if (GET_CODE (x) != MEM
3854 || !s390_decompose_address (XEXP (x, 0), &ad)
3855 || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
3856 || ad.indx)
3857 abort ();
3859 if (ad.disp)
3860 output_addr_const (file, ad.disp);
3861 else
3862 fprintf (file, "0");
3864 return;
3866 case 'R':
3868 struct s390_address ad;
3870 if (GET_CODE (x) != MEM
3871 || !s390_decompose_address (XEXP (x, 0), &ad)
3872 || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
3873 || ad.indx)
3874 abort ();
3876 if (ad.base)
3877 fprintf (file, "%s", reg_names[REGNO (ad.base)]);
3878 else
3879 fprintf (file, "0");
3881 return;
3883 case 'N':
3884 if (GET_CODE (x) == REG)
3885 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
3886 else if (GET_CODE (x) == MEM)
3887 x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 4));
3888 else
3889 abort ();
3890 break;
3892 case 'M':
3893 if (GET_CODE (x) == REG)
3894 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
3895 else if (GET_CODE (x) == MEM)
3896 x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 8));
3897 else
3898 abort ();
3899 break;
3901 case 'Y':
3902 print_shift_count_operand (file, x);
3903 return;
3906 switch (GET_CODE (x))
3908 case REG:
3909 fprintf (file, "%s", reg_names[REGNO (x)]);
3910 break;
3912 case MEM:
3913 output_address (XEXP (x, 0));
3914 break;
3916 case CONST:
3917 case CODE_LABEL:
3918 case LABEL_REF:
3919 case SYMBOL_REF:
3920 output_addr_const (file, x);
3921 break;
3923 case CONST_INT:
3924 if (code == 'b')
3925 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xff);
3926 else if (code == 'x')
3927 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffff);
3928 else if (code == 'h')
3929 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000);
3930 else if (code == 'i')
3931 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3932 s390_extract_part (x, HImode, 0));
3933 else if (code == 'j')
3934 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3935 s390_extract_part (x, HImode, -1));
3936 else
3937 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
3938 break;
3940 case CONST_DOUBLE:
3941 if (GET_MODE (x) != VOIDmode)
3942 abort ();
3943 if (code == 'b')
3944 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xff);
3945 else if (code == 'x')
3946 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xffff);
3947 else if (code == 'h')
3948 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((CONST_DOUBLE_LOW (x) & 0xffff) ^ 0x8000) - 0x8000);
3949 else
3950 abort ();
3951 break;
3953 default:
3954 fatal_insn ("UNKNOWN in print_operand !?", x);
3955 break;
3959 /* Target hook for assembling integer objects. We need to define it
3960 here to work a round a bug in some versions of GAS, which couldn't
3961 handle values smaller than INT_MIN when printed in decimal. */
3963 static bool
3964 s390_assemble_integer (rtx x, unsigned int size, int aligned_p)
3966 if (size == 8 && aligned_p
3967 && GET_CODE (x) == CONST_INT && INTVAL (x) < INT_MIN)
3969 fprintf (asm_out_file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n",
3970 INTVAL (x));
3971 return true;
3973 return default_assemble_integer (x, size, aligned_p);
3976 /* Returns true if register REGNO is used for forming
3977 a memory address in expression X. */
3979 static int
3980 reg_used_in_mem_p (int regno, rtx x)
3982 enum rtx_code code = GET_CODE (x);
3983 int i, j;
3984 const char *fmt;
3986 if (code == MEM)
3988 if (refers_to_regno_p (regno, regno+1,
3989 XEXP (x, 0), 0))
3990 return 1;
3992 else if (code == SET
3993 && GET_CODE (SET_DEST (x)) == PC)
3995 if (refers_to_regno_p (regno, regno+1,
3996 SET_SRC (x), 0))
3997 return 1;
4000 fmt = GET_RTX_FORMAT (code);
4001 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4003 if (fmt[i] == 'e'
4004 && reg_used_in_mem_p (regno, XEXP (x, i)))
4005 return 1;
4007 else if (fmt[i] == 'E')
4008 for (j = 0; j < XVECLEN (x, i); j++)
4009 if (reg_used_in_mem_p (regno, XVECEXP (x, i, j)))
4010 return 1;
4012 return 0;
4015 /* Returns true if expression DEP_RTX sets an address register
4016 used by instruction INSN to address memory. */
4018 static int
4019 addr_generation_dependency_p (rtx dep_rtx, rtx insn)
4021 rtx target, pat;
4023 if (GET_CODE (dep_rtx) == INSN)
4024 dep_rtx = PATTERN (dep_rtx);
4026 if (GET_CODE (dep_rtx) == SET)
4028 target = SET_DEST (dep_rtx);
4029 if (GET_CODE (target) == STRICT_LOW_PART)
4030 target = XEXP (target, 0);
4031 while (GET_CODE (target) == SUBREG)
4032 target = SUBREG_REG (target);
4034 if (GET_CODE (target) == REG)
4036 int regno = REGNO (target);
4038 if (s390_safe_attr_type (insn) == TYPE_LA)
4040 pat = PATTERN (insn);
4041 if (GET_CODE (pat) == PARALLEL)
4043 if (XVECLEN (pat, 0) != 2)
4044 abort();
4045 pat = XVECEXP (pat, 0, 0);
4047 if (GET_CODE (pat) == SET)
4048 return refers_to_regno_p (regno, regno+1, SET_SRC (pat), 0);
4049 else
4050 abort();
4052 else if (get_attr_atype (insn) == ATYPE_AGEN)
4053 return reg_used_in_mem_p (regno, PATTERN (insn));
4056 return 0;
4059 /* Return 1, if dep_insn sets register used in insn in the agen unit. */
4062 s390_agen_dep_p (rtx dep_insn, rtx insn)
4064 rtx dep_rtx = PATTERN (dep_insn);
4065 int i;
4067 if (GET_CODE (dep_rtx) == SET
4068 && addr_generation_dependency_p (dep_rtx, insn))
4069 return 1;
4070 else if (GET_CODE (dep_rtx) == PARALLEL)
4072 for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
4074 if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i), insn))
4075 return 1;
4078 return 0;
4081 /* Return the modified cost of the dependency of instruction INSN
4082 on instruction DEP_INSN through the link LINK. COST is the
4083 default cost of that dependency.
4085 Data dependencies are all handled without delay. However, if a
4086 register is modified and subsequently used as base or index
4087 register of a memory reference, at least 4 cycles need to pass
4088 between setting and using the register to avoid pipeline stalls.
4089 An exception is the LA instruction. An address generated by LA can
4090 be used by introducing only a one cycle stall on the pipeline. */
4092 static int
4093 s390_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
4095 /* If the dependence is an anti-dependence, there is no cost. For an
4096 output dependence, there is sometimes a cost, but it doesn't seem
4097 worth handling those few cases. */
4099 if (REG_NOTE_KIND (link) != 0)
4100 return 0;
4102 /* If we can't recognize the insns, we can't really do anything. */
4103 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
4104 return cost;
4106 /* Operand forward in case of lr, load and la. */
4107 if (s390_tune == PROCESSOR_2084_Z990
4108 && cost == 1
4109 && (s390_safe_attr_type (dep_insn) == TYPE_LA
4110 || s390_safe_attr_type (dep_insn) == TYPE_LR
4111 || s390_safe_attr_type (dep_insn) == TYPE_LOAD))
4112 return 0;
4113 return cost;
4116 /* A C statement (sans semicolon) to update the integer scheduling priority
4117 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
4118 reduce the priority to execute INSN later. Do not define this macro if
4119 you do not need to adjust the scheduling priorities of insns.
4121 A STD instruction should be scheduled earlier,
4122 in order to use the bypass. */
4124 static int
4125 s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
4127 if (! INSN_P (insn))
4128 return priority;
4130 if (s390_tune != PROCESSOR_2084_Z990)
4131 return priority;
4133 switch (s390_safe_attr_type (insn))
4135 case TYPE_FSTORED:
4136 case TYPE_FSTORES:
4137 priority = priority << 3;
4138 break;
4139 case TYPE_STORE:
4140 priority = priority << 1;
4141 break;
4142 default:
4143 break;
4145 return priority;
4148 /* The number of instructions that can be issued per cycle. */
4150 static int
4151 s390_issue_rate (void)
4153 if (s390_tune == PROCESSOR_2084_Z990)
4154 return 3;
4155 return 1;
4158 static int
4159 s390_first_cycle_multipass_dfa_lookahead (void)
4161 return 4;
4165 /* Split all branches that exceed the maximum distance.
4166 Returns true if this created a new literal pool entry. */
4168 static int
4169 s390_split_branches (void)
4171 rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
4172 int new_literal = 0;
4173 rtx insn, pat, tmp, target;
4174 rtx *label;
4176 /* We need correct insn addresses. */
4178 shorten_branches (get_insns ());
4180 /* Find all branches that exceed 64KB, and split them. */
4182 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4184 if (GET_CODE (insn) != JUMP_INSN)
4185 continue;
4187 pat = PATTERN (insn);
4188 if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
4189 pat = XVECEXP (pat, 0, 0);
4190 if (GET_CODE (pat) != SET || SET_DEST (pat) != pc_rtx)
4191 continue;
4193 if (GET_CODE (SET_SRC (pat)) == LABEL_REF)
4195 label = &SET_SRC (pat);
4197 else if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE)
4199 if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF)
4200 label = &XEXP (SET_SRC (pat), 1);
4201 else if (GET_CODE (XEXP (SET_SRC (pat), 2)) == LABEL_REF)
4202 label = &XEXP (SET_SRC (pat), 2);
4203 else
4204 continue;
4206 else
4207 continue;
4209 if (get_attr_length (insn) <= 4)
4210 continue;
4212 /* We are going to use the return register as scratch register,
4213 make sure it will be saved/restored by the prologue/epilogue. */
4214 cfun_frame_layout.save_return_addr_p = 1;
4216 if (!flag_pic)
4218 new_literal = 1;
4219 tmp = force_const_mem (Pmode, *label);
4220 tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, tmp), insn);
4221 INSN_ADDRESSES_NEW (tmp, -1);
4222 annotate_constant_pool_refs (&PATTERN (tmp));
4224 target = temp_reg;
4226 else
4228 new_literal = 1;
4229 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, *label),
4230 UNSPEC_LTREL_OFFSET);
4231 target = gen_rtx_CONST (Pmode, target);
4232 target = force_const_mem (Pmode, target);
4233 tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, target), insn);
4234 INSN_ADDRESSES_NEW (tmp, -1);
4235 annotate_constant_pool_refs (&PATTERN (tmp));
4237 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, XEXP (target, 0),
4238 cfun->machine->base_reg),
4239 UNSPEC_LTREL_BASE);
4240 target = gen_rtx_PLUS (Pmode, temp_reg, target);
4243 if (!validate_change (insn, label, target, 0))
4244 abort ();
4247 return new_literal;
4250 /* Annotate every literal pool reference in X by an UNSPEC_LTREF expression.
4251 Fix up MEMs as required. */
4253 static void
4254 annotate_constant_pool_refs (rtx *x)
4256 int i, j;
4257 const char *fmt;
4259 if (GET_CODE (*x) == SYMBOL_REF
4260 && CONSTANT_POOL_ADDRESS_P (*x))
4261 abort ();
4263 /* Literal pool references can only occur inside a MEM ... */
4264 if (GET_CODE (*x) == MEM)
4266 rtx memref = XEXP (*x, 0);
4268 if (GET_CODE (memref) == SYMBOL_REF
4269 && CONSTANT_POOL_ADDRESS_P (memref))
4271 rtx base = cfun->machine->base_reg;
4272 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, memref, base),
4273 UNSPEC_LTREF);
4275 *x = replace_equiv_address (*x, addr);
4276 return;
4279 if (GET_CODE (memref) == CONST
4280 && GET_CODE (XEXP (memref, 0)) == PLUS
4281 && GET_CODE (XEXP (XEXP (memref, 0), 1)) == CONST_INT
4282 && GET_CODE (XEXP (XEXP (memref, 0), 0)) == SYMBOL_REF
4283 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (memref, 0), 0)))
4285 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (memref, 0), 1));
4286 rtx sym = XEXP (XEXP (memref, 0), 0);
4287 rtx base = cfun->machine->base_reg;
4288 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, sym, base),
4289 UNSPEC_LTREF);
4291 *x = replace_equiv_address (*x, plus_constant (addr, off));
4292 return;
4296 /* ... or a load-address type pattern. */
4297 if (GET_CODE (*x) == SET)
4299 rtx addrref = SET_SRC (*x);
4301 if (GET_CODE (addrref) == SYMBOL_REF
4302 && CONSTANT_POOL_ADDRESS_P (addrref))
4304 rtx base = cfun->machine->base_reg;
4305 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, addrref, base),
4306 UNSPEC_LTREF);
4308 SET_SRC (*x) = addr;
4309 return;
4312 if (GET_CODE (addrref) == CONST
4313 && GET_CODE (XEXP (addrref, 0)) == PLUS
4314 && GET_CODE (XEXP (XEXP (addrref, 0), 1)) == CONST_INT
4315 && GET_CODE (XEXP (XEXP (addrref, 0), 0)) == SYMBOL_REF
4316 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (addrref, 0), 0)))
4318 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (addrref, 0), 1));
4319 rtx sym = XEXP (XEXP (addrref, 0), 0);
4320 rtx base = cfun->machine->base_reg;
4321 rtx addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, sym, base),
4322 UNSPEC_LTREF);
4324 SET_SRC (*x) = plus_constant (addr, off);
4325 return;
4329 /* Annotate LTREL_BASE as well. */
4330 if (GET_CODE (*x) == UNSPEC
4331 && XINT (*x, 1) == UNSPEC_LTREL_BASE)
4333 rtx base = cfun->machine->base_reg;
4334 *x = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, XVECEXP (*x, 0, 0), base),
4335 UNSPEC_LTREL_BASE);
4336 return;
4339 fmt = GET_RTX_FORMAT (GET_CODE (*x));
4340 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
4342 if (fmt[i] == 'e')
4344 annotate_constant_pool_refs (&XEXP (*x, i));
4346 else if (fmt[i] == 'E')
4348 for (j = 0; j < XVECLEN (*x, i); j++)
4349 annotate_constant_pool_refs (&XVECEXP (*x, i, j));
4355 /* Find an annotated literal pool symbol referenced in RTX X,
4356 and store it at REF. Will abort if X contains references to
4357 more than one such pool symbol; multiple references to the same
4358 symbol are allowed, however.
4360 The rtx pointed to by REF must be initialized to NULL_RTX
4361 by the caller before calling this routine. */
4363 static void
4364 find_constant_pool_ref (rtx x, rtx *ref)
4366 int i, j;
4367 const char *fmt;
4369 /* Ignore LTREL_BASE references. */
4370 if (GET_CODE (x) == UNSPEC
4371 && XINT (x, 1) == UNSPEC_LTREL_BASE)
4372 return;
4373 /* Likewise POOL_ENTRY insns. */
4374 if (GET_CODE (x) == UNSPEC_VOLATILE
4375 && XINT (x, 1) == UNSPECV_POOL_ENTRY)
4376 return;
4378 if (GET_CODE (x) == SYMBOL_REF
4379 && CONSTANT_POOL_ADDRESS_P (x))
4380 abort ();
4382 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_LTREF)
4384 rtx sym = XVECEXP (x, 0, 0);
4385 if (GET_CODE (sym) != SYMBOL_REF
4386 || !CONSTANT_POOL_ADDRESS_P (sym))
4387 abort ();
4389 if (*ref == NULL_RTX)
4390 *ref = sym;
4391 else if (*ref != sym)
4392 abort ();
4394 return;
4397 fmt = GET_RTX_FORMAT (GET_CODE (x));
4398 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4400 if (fmt[i] == 'e')
4402 find_constant_pool_ref (XEXP (x, i), ref);
4404 else if (fmt[i] == 'E')
4406 for (j = 0; j < XVECLEN (x, i); j++)
4407 find_constant_pool_ref (XVECEXP (x, i, j), ref);
4412 /* Replace every reference to the annotated literal pool
4413 symbol REF in X by its base plus OFFSET. */
4415 static void
4416 replace_constant_pool_ref (rtx *x, rtx ref, rtx offset)
4418 int i, j;
4419 const char *fmt;
4421 if (*x == ref)
4422 abort ();
4424 if (GET_CODE (*x) == UNSPEC
4425 && XINT (*x, 1) == UNSPEC_LTREF
4426 && XVECEXP (*x, 0, 0) == ref)
4428 *x = gen_rtx_PLUS (Pmode, XVECEXP (*x, 0, 1), offset);
4429 return;
4432 if (GET_CODE (*x) == PLUS
4433 && GET_CODE (XEXP (*x, 1)) == CONST_INT
4434 && GET_CODE (XEXP (*x, 0)) == UNSPEC
4435 && XINT (XEXP (*x, 0), 1) == UNSPEC_LTREF
4436 && XVECEXP (XEXP (*x, 0), 0, 0) == ref)
4438 rtx addr = gen_rtx_PLUS (Pmode, XVECEXP (XEXP (*x, 0), 0, 1), offset);
4439 *x = plus_constant (addr, INTVAL (XEXP (*x, 1)));
4440 return;
4443 fmt = GET_RTX_FORMAT (GET_CODE (*x));
4444 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
4446 if (fmt[i] == 'e')
4448 replace_constant_pool_ref (&XEXP (*x, i), ref, offset);
4450 else if (fmt[i] == 'E')
4452 for (j = 0; j < XVECLEN (*x, i); j++)
4453 replace_constant_pool_ref (&XVECEXP (*x, i, j), ref, offset);
4458 /* Check whether X contains an UNSPEC_LTREL_BASE.
4459 Return its constant pool symbol if found, NULL_RTX otherwise. */
4461 static rtx
4462 find_ltrel_base (rtx x)
4464 int i, j;
4465 const char *fmt;
4467 if (GET_CODE (x) == UNSPEC
4468 && XINT (x, 1) == UNSPEC_LTREL_BASE)
4469 return XVECEXP (x, 0, 0);
4471 fmt = GET_RTX_FORMAT (GET_CODE (x));
4472 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4474 if (fmt[i] == 'e')
4476 rtx fnd = find_ltrel_base (XEXP (x, i));
4477 if (fnd)
4478 return fnd;
4480 else if (fmt[i] == 'E')
4482 for (j = 0; j < XVECLEN (x, i); j++)
4484 rtx fnd = find_ltrel_base (XVECEXP (x, i, j));
4485 if (fnd)
4486 return fnd;
4491 return NULL_RTX;
4494 /* Replace any occurrence of UNSPEC_LTREL_BASE in X with its base. */
4496 static void
4497 replace_ltrel_base (rtx *x)
4499 int i, j;
4500 const char *fmt;
4502 if (GET_CODE (*x) == UNSPEC
4503 && XINT (*x, 1) == UNSPEC_LTREL_BASE)
4505 *x = XVECEXP (*x, 0, 1);
4506 return;
4509 fmt = GET_RTX_FORMAT (GET_CODE (*x));
4510 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
4512 if (fmt[i] == 'e')
4514 replace_ltrel_base (&XEXP (*x, i));
4516 else if (fmt[i] == 'E')
4518 for (j = 0; j < XVECLEN (*x, i); j++)
4519 replace_ltrel_base (&XVECEXP (*x, i, j));
4525 /* We keep a list of constants which we have to add to internal
4526 constant tables in the middle of large functions. */
4528 #define NR_C_MODES 7
4529 enum machine_mode constant_modes[NR_C_MODES] =
4531 TImode,
4532 DFmode, DImode,
4533 SFmode, SImode,
4534 HImode,
4535 QImode
4538 struct constant
4540 struct constant *next;
4541 rtx value;
4542 rtx label;
4545 struct constant_pool
4547 struct constant_pool *next;
4548 rtx first_insn;
4549 rtx pool_insn;
4550 bitmap insns;
4552 struct constant *constants[NR_C_MODES];
4553 rtx label;
4554 int size;
4557 static struct constant_pool * s390_mainpool_start (void);
4558 static void s390_mainpool_finish (struct constant_pool *);
4559 static void s390_mainpool_cancel (struct constant_pool *);
4561 static struct constant_pool * s390_chunkify_start (void);
4562 static void s390_chunkify_finish (struct constant_pool *);
4563 static void s390_chunkify_cancel (struct constant_pool *);
4565 static struct constant_pool *s390_start_pool (struct constant_pool **, rtx);
4566 static void s390_end_pool (struct constant_pool *, rtx);
4567 static void s390_add_pool_insn (struct constant_pool *, rtx);
4568 static struct constant_pool *s390_find_pool (struct constant_pool *, rtx);
4569 static void s390_add_constant (struct constant_pool *, rtx, enum machine_mode);
4570 static rtx s390_find_constant (struct constant_pool *, rtx, enum machine_mode);
4571 static rtx s390_dump_pool (struct constant_pool *, bool);
4572 static struct constant_pool *s390_alloc_pool (void);
4573 static void s390_free_pool (struct constant_pool *);
4575 /* Create new constant pool covering instructions starting at INSN
4576 and chain it to the end of POOL_LIST. */
4578 static struct constant_pool *
4579 s390_start_pool (struct constant_pool **pool_list, rtx insn)
4581 struct constant_pool *pool, **prev;
4583 pool = s390_alloc_pool ();
4584 pool->first_insn = insn;
4586 for (prev = pool_list; *prev; prev = &(*prev)->next)
4588 *prev = pool;
4590 return pool;
4593 /* End range of instructions covered by POOL at INSN and emit
4594 placeholder insn representing the pool. */
4596 static void
4597 s390_end_pool (struct constant_pool *pool, rtx insn)
4599 rtx pool_size = GEN_INT (pool->size + 8 /* alignment slop */);
4601 if (!insn)
4602 insn = get_last_insn ();
4604 pool->pool_insn = emit_insn_after (gen_pool (pool_size), insn);
4605 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
4608 /* Add INSN to the list of insns covered by POOL. */
4610 static void
4611 s390_add_pool_insn (struct constant_pool *pool, rtx insn)
4613 bitmap_set_bit (pool->insns, INSN_UID (insn));
4616 /* Return pool out of POOL_LIST that covers INSN. */
4618 static struct constant_pool *
4619 s390_find_pool (struct constant_pool *pool_list, rtx insn)
4621 struct constant_pool *pool;
4623 for (pool = pool_list; pool; pool = pool->next)
4624 if (bitmap_bit_p (pool->insns, INSN_UID (insn)))
4625 break;
4627 return pool;
4630 /* Add constant VAL of mode MODE to the constant pool POOL. */
4632 static void
4633 s390_add_constant (struct constant_pool *pool, rtx val, enum machine_mode mode)
4635 struct constant *c;
4636 int i;
4638 for (i = 0; i < NR_C_MODES; i++)
4639 if (constant_modes[i] == mode)
4640 break;
4641 if (i == NR_C_MODES)
4642 abort ();
4644 for (c = pool->constants[i]; c != NULL; c = c->next)
4645 if (rtx_equal_p (val, c->value))
4646 break;
4648 if (c == NULL)
4650 c = (struct constant *) xmalloc (sizeof *c);
4651 c->value = val;
4652 c->label = gen_label_rtx ();
4653 c->next = pool->constants[i];
4654 pool->constants[i] = c;
4655 pool->size += GET_MODE_SIZE (mode);
4659 /* Find constant VAL of mode MODE in the constant pool POOL.
4660 Return an RTX describing the distance from the start of
4661 the pool to the location of the new constant. */
4663 static rtx
4664 s390_find_constant (struct constant_pool *pool, rtx val,
4665 enum machine_mode mode)
4667 struct constant *c;
4668 rtx offset;
4669 int i;
4671 for (i = 0; i < NR_C_MODES; i++)
4672 if (constant_modes[i] == mode)
4673 break;
4674 if (i == NR_C_MODES)
4675 abort ();
4677 for (c = pool->constants[i]; c != NULL; c = c->next)
4678 if (rtx_equal_p (val, c->value))
4679 break;
4681 if (c == NULL)
4682 abort ();
4684 offset = gen_rtx_MINUS (Pmode, gen_rtx_LABEL_REF (Pmode, c->label),
4685 gen_rtx_LABEL_REF (Pmode, pool->label));
4686 offset = gen_rtx_CONST (Pmode, offset);
4687 return offset;
4690 /* Dump out the constants in POOL. If REMOTE_LABEL is true,
4691 do not emit the pool base label. */
4693 static rtx
4694 s390_dump_pool (struct constant_pool *pool, bool remote_label)
4696 struct constant *c;
4697 rtx insn;
4698 int i;
4700 /* Pool start insn switches to proper section
4701 and guarantees necessary alignment. */
4702 if (TARGET_CPU_ZARCH)
4703 insn = emit_insn_after (gen_pool_start_64 (), pool->pool_insn);
4704 else
4705 insn = emit_insn_after (gen_pool_start_31 (), pool->pool_insn);
4706 INSN_ADDRESSES_NEW (insn, -1);
4708 if (!remote_label)
4710 insn = emit_label_after (pool->label, insn);
4711 INSN_ADDRESSES_NEW (insn, -1);
4714 /* Dump constants in descending alignment requirement order,
4715 ensuring proper alignment for every constant. */
4716 for (i = 0; i < NR_C_MODES; i++)
4717 for (c = pool->constants[i]; c; c = c->next)
4719 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
4720 rtx value = c->value;
4721 if (GET_CODE (value) == CONST
4722 && GET_CODE (XEXP (value, 0)) == UNSPEC
4723 && XINT (XEXP (value, 0), 1) == UNSPEC_LTREL_OFFSET
4724 && XVECLEN (XEXP (value, 0), 0) == 1)
4726 value = gen_rtx_MINUS (Pmode, XVECEXP (XEXP (value, 0), 0, 0),
4727 gen_rtx_LABEL_REF (VOIDmode, pool->label));
4728 value = gen_rtx_CONST (VOIDmode, value);
4731 insn = emit_label_after (c->label, insn);
4732 INSN_ADDRESSES_NEW (insn, -1);
4734 value = gen_rtx_UNSPEC_VOLATILE (constant_modes[i],
4735 gen_rtvec (1, value),
4736 UNSPECV_POOL_ENTRY);
4737 insn = emit_insn_after (value, insn);
4738 INSN_ADDRESSES_NEW (insn, -1);
4741 /* Pool end insn switches back to previous section
4742 and guarantees necessary alignment. */
4743 if (TARGET_CPU_ZARCH)
4744 insn = emit_insn_after (gen_pool_end_64 (), insn);
4745 else
4746 insn = emit_insn_after (gen_pool_end_31 (), insn);
4747 INSN_ADDRESSES_NEW (insn, -1);
4749 insn = emit_barrier_after (insn);
4750 INSN_ADDRESSES_NEW (insn, -1);
4752 /* Remove placeholder insn. */
4753 remove_insn (pool->pool_insn);
4755 return insn;
4758 /* Allocate new constant_pool structure. */
4760 static struct constant_pool *
4761 s390_alloc_pool (void)
4763 struct constant_pool *pool;
4764 int i;
4766 pool = (struct constant_pool *) xmalloc (sizeof *pool);
4767 pool->next = NULL;
4768 for (i = 0; i < NR_C_MODES; i++)
4769 pool->constants[i] = NULL;
4771 pool->label = gen_label_rtx ();
4772 pool->first_insn = NULL_RTX;
4773 pool->pool_insn = NULL_RTX;
4774 pool->insns = BITMAP_XMALLOC ();
4775 pool->size = 0;
4777 return pool;
4780 /* Free all memory used by POOL. */
4782 static void
4783 s390_free_pool (struct constant_pool *pool)
4785 int i;
4787 for (i = 0; i < NR_C_MODES; i++)
4789 struct constant *c = pool->constants[i];
4790 while (c != NULL)
4792 struct constant *next = c->next;
4793 free (c);
4794 c = next;
4798 BITMAP_XFREE (pool->insns);
4799 free (pool);
4803 /* Collect main literal pool. Return NULL on overflow. */
4805 static struct constant_pool *
4806 s390_mainpool_start (void)
4808 struct constant_pool *pool;
4809 rtx insn;
4811 pool = s390_alloc_pool ();
4813 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4815 if (GET_CODE (insn) == INSN
4816 && GET_CODE (PATTERN (insn)) == SET
4817 && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC_VOLATILE
4818 && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPECV_MAIN_POOL)
4820 if (pool->pool_insn)
4821 abort ();
4822 pool->pool_insn = insn;
4825 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
4827 rtx pool_ref = NULL_RTX;
4828 find_constant_pool_ref (PATTERN (insn), &pool_ref);
4829 if (pool_ref)
4831 rtx constant = get_pool_constant (pool_ref);
4832 enum machine_mode mode = get_pool_mode (pool_ref);
4833 s390_add_constant (pool, constant, mode);
4838 if (!pool->pool_insn)
4839 abort ();
4841 if (pool->size >= 4096)
4843 /* We're going to chunkify the pool, so remove the main
4844 pool placeholder insn. */
4845 remove_insn (pool->pool_insn);
4847 s390_free_pool (pool);
4848 pool = NULL;
4851 return pool;
4854 /* POOL holds the main literal pool as collected by s390_mainpool_start.
4855 Modify the current function to output the pool constants as well as
4856 the pool register setup instruction. */
4858 static void
4859 s390_mainpool_finish (struct constant_pool *pool)
4861 rtx base_reg = SET_DEST (PATTERN (pool->pool_insn));
4862 rtx insn;
4864 /* If the pool is empty, we're done. */
4865 if (pool->size == 0)
4867 remove_insn (pool->pool_insn);
4868 s390_free_pool (pool);
4869 return;
4872 /* We need correct insn addresses. */
4873 shorten_branches (get_insns ());
4875 /* On zSeries, we use a LARL to load the pool register. The pool is
4876 located in the .rodata section, so we emit it after the function. */
4877 if (TARGET_CPU_ZARCH)
4879 insn = gen_main_base_64 (base_reg, pool->label);
4880 insn = emit_insn_after (insn, pool->pool_insn);
4881 INSN_ADDRESSES_NEW (insn, -1);
4882 remove_insn (pool->pool_insn);
4884 insn = get_last_insn ();
4885 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
4886 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
4888 s390_dump_pool (pool, 0);
4891 /* On S/390, if the total size of the function's code plus literal pool
4892 does not exceed 4096 bytes, we use BASR to set up a function base
4893 pointer, and emit the literal pool at the end of the function. */
4894 else if (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
4895 + pool->size + 8 /* alignment slop */ < 4096)
4897 insn = gen_main_base_31_small (base_reg, pool->label);
4898 insn = emit_insn_after (insn, pool->pool_insn);
4899 INSN_ADDRESSES_NEW (insn, -1);
4900 remove_insn (pool->pool_insn);
4902 insn = emit_label_after (pool->label, insn);
4903 INSN_ADDRESSES_NEW (insn, -1);
4905 insn = get_last_insn ();
4906 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
4907 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
4909 s390_dump_pool (pool, 1);
4912 /* Otherwise, we emit an inline literal pool and use BASR to branch
4913 over it, setting up the pool register at the same time. */
4914 else
4916 rtx pool_end = gen_label_rtx ();
4918 insn = gen_main_base_31_large (base_reg, pool->label, pool_end);
4919 insn = emit_insn_after (insn, pool->pool_insn);
4920 INSN_ADDRESSES_NEW (insn, -1);
4921 remove_insn (pool->pool_insn);
4923 insn = emit_label_after (pool->label, insn);
4924 INSN_ADDRESSES_NEW (insn, -1);
4926 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
4927 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
4929 insn = emit_label_after (pool_end, pool->pool_insn);
4930 INSN_ADDRESSES_NEW (insn, -1);
4932 s390_dump_pool (pool, 1);
4936 /* Replace all literal pool references. */
4938 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4940 if (INSN_P (insn))
4941 replace_ltrel_base (&PATTERN (insn));
4943 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
4945 rtx addr, pool_ref = NULL_RTX;
4946 find_constant_pool_ref (PATTERN (insn), &pool_ref);
4947 if (pool_ref)
4949 addr = s390_find_constant (pool, get_pool_constant (pool_ref),
4950 get_pool_mode (pool_ref));
4951 replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
4952 INSN_CODE (insn) = -1;
4958 /* Free the pool. */
4959 s390_free_pool (pool);
4962 /* POOL holds the main literal pool as collected by s390_mainpool_start.
4963 We have decided we cannot use this pool, so revert all changes
4964 to the current function that were done by s390_mainpool_start. */
4965 static void
4966 s390_mainpool_cancel (struct constant_pool *pool)
4968 /* We didn't actually change the instruction stream, so simply
4969 free the pool memory. */
4970 s390_free_pool (pool);
4974 /* Chunkify the literal pool. */
4976 #define S390_POOL_CHUNK_MIN 0xc00
4977 #define S390_POOL_CHUNK_MAX 0xe00
4979 static struct constant_pool *
4980 s390_chunkify_start (void)
4982 struct constant_pool *curr_pool = NULL, *pool_list = NULL;
4983 int extra_size = 0;
4984 bitmap far_labels;
4985 rtx pending_ltrel = NULL_RTX;
4986 rtx insn;
4988 rtx (*gen_reload_base) (rtx, rtx) =
4989 TARGET_CPU_ZARCH? gen_reload_base_64 : gen_reload_base_31;
4992 /* We need correct insn addresses. */
4994 shorten_branches (get_insns ());
4996 /* Scan all insns and move literals to pool chunks. */
4998 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5000 /* Check for pending LTREL_BASE. */
5001 if (INSN_P (insn))
5003 rtx ltrel_base = find_ltrel_base (PATTERN (insn));
5004 if (ltrel_base)
5006 if (ltrel_base == pending_ltrel)
5007 pending_ltrel = NULL_RTX;
5008 else
5009 abort ();
5013 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
5015 rtx pool_ref = NULL_RTX;
5016 find_constant_pool_ref (PATTERN (insn), &pool_ref);
5017 if (pool_ref)
5019 rtx constant = get_pool_constant (pool_ref);
5020 enum machine_mode mode = get_pool_mode (pool_ref);
5022 if (!curr_pool)
5023 curr_pool = s390_start_pool (&pool_list, insn);
5025 s390_add_constant (curr_pool, constant, mode);
5026 s390_add_pool_insn (curr_pool, insn);
5028 /* Don't split the pool chunk between a LTREL_OFFSET load
5029 and the corresponding LTREL_BASE. */
5030 if (GET_CODE (constant) == CONST
5031 && GET_CODE (XEXP (constant, 0)) == UNSPEC
5032 && XINT (XEXP (constant, 0), 1) == UNSPEC_LTREL_OFFSET)
5034 if (pending_ltrel)
5035 abort ();
5036 pending_ltrel = pool_ref;
5041 if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CODE_LABEL)
5043 if (curr_pool)
5044 s390_add_pool_insn (curr_pool, insn);
5045 /* An LTREL_BASE must follow within the same basic block. */
5046 if (pending_ltrel)
5047 abort ();
5050 if (!curr_pool
5051 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn)
5052 || INSN_ADDRESSES (INSN_UID (insn)) == -1)
5053 continue;
5055 if (TARGET_CPU_ZARCH)
5057 if (curr_pool->size < S390_POOL_CHUNK_MAX)
5058 continue;
5060 s390_end_pool (curr_pool, NULL_RTX);
5061 curr_pool = NULL;
5063 else
5065 int chunk_size = INSN_ADDRESSES (INSN_UID (insn))
5066 - INSN_ADDRESSES (INSN_UID (curr_pool->first_insn))
5067 + extra_size;
5069 /* We will later have to insert base register reload insns.
5070 Those will have an effect on code size, which we need to
5071 consider here. This calculation makes rather pessimistic
5072 worst-case assumptions. */
5073 if (GET_CODE (insn) == CODE_LABEL)
5074 extra_size += 6;
5076 if (chunk_size < S390_POOL_CHUNK_MIN
5077 && curr_pool->size < S390_POOL_CHUNK_MIN)
5078 continue;
5080 /* Pool chunks can only be inserted after BARRIERs ... */
5081 if (GET_CODE (insn) == BARRIER)
5083 s390_end_pool (curr_pool, insn);
5084 curr_pool = NULL;
5085 extra_size = 0;
5088 /* ... so if we don't find one in time, create one. */
5089 else if ((chunk_size > S390_POOL_CHUNK_MAX
5090 || curr_pool->size > S390_POOL_CHUNK_MAX))
5092 rtx label, jump, barrier;
5094 /* We can insert the barrier only after a 'real' insn. */
5095 if (GET_CODE (insn) != INSN && GET_CODE (insn) != CALL_INSN)
5096 continue;
5097 if (get_attr_length (insn) == 0)
5098 continue;
5100 /* Don't separate LTREL_BASE from the corresponding
5101 LTREL_OFFSET load. */
5102 if (pending_ltrel)
5103 continue;
5105 label = gen_label_rtx ();
5106 jump = emit_jump_insn_after (gen_jump (label), insn);
5107 barrier = emit_barrier_after (jump);
5108 insn = emit_label_after (label, barrier);
5109 JUMP_LABEL (jump) = label;
5110 LABEL_NUSES (label) = 1;
5112 INSN_ADDRESSES_NEW (jump, -1);
5113 INSN_ADDRESSES_NEW (barrier, -1);
5114 INSN_ADDRESSES_NEW (insn, -1);
5116 s390_end_pool (curr_pool, barrier);
5117 curr_pool = NULL;
5118 extra_size = 0;
5123 if (curr_pool)
5124 s390_end_pool (curr_pool, NULL_RTX);
5125 if (pending_ltrel)
5126 abort ();
5129 /* Find all labels that are branched into
5130 from an insn belonging to a different chunk. */
5132 far_labels = BITMAP_XMALLOC ();
5134 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5136 /* Labels marked with LABEL_PRESERVE_P can be target
5137 of non-local jumps, so we have to mark them.
5138 The same holds for named labels.
5140 Don't do that, however, if it is the label before
5141 a jump table. */
5143 if (GET_CODE (insn) == CODE_LABEL
5144 && (LABEL_PRESERVE_P (insn) || LABEL_NAME (insn)))
5146 rtx vec_insn = next_real_insn (insn);
5147 rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
5148 PATTERN (vec_insn) : NULL_RTX;
5149 if (!vec_pat
5150 || !(GET_CODE (vec_pat) == ADDR_VEC
5151 || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
5152 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (insn));
5155 /* If we have a direct jump (conditional or unconditional)
5156 or a casesi jump, check all potential targets. */
5157 else if (GET_CODE (insn) == JUMP_INSN)
5159 rtx pat = PATTERN (insn);
5160 if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
5161 pat = XVECEXP (pat, 0, 0);
5163 if (GET_CODE (pat) == SET)
5165 rtx label = JUMP_LABEL (insn);
5166 if (label)
5168 if (s390_find_pool (pool_list, label)
5169 != s390_find_pool (pool_list, insn))
5170 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
5173 else if (GET_CODE (pat) == PARALLEL
5174 && XVECLEN (pat, 0) == 2
5175 && GET_CODE (XVECEXP (pat, 0, 0)) == SET
5176 && GET_CODE (XVECEXP (pat, 0, 1)) == USE
5177 && GET_CODE (XEXP (XVECEXP (pat, 0, 1), 0)) == LABEL_REF)
5179 /* Find the jump table used by this casesi jump. */
5180 rtx vec_label = XEXP (XEXP (XVECEXP (pat, 0, 1), 0), 0);
5181 rtx vec_insn = next_real_insn (vec_label);
5182 rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
5183 PATTERN (vec_insn) : NULL_RTX;
5184 if (vec_pat
5185 && (GET_CODE (vec_pat) == ADDR_VEC
5186 || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
5188 int i, diff_p = GET_CODE (vec_pat) == ADDR_DIFF_VEC;
5190 for (i = 0; i < XVECLEN (vec_pat, diff_p); i++)
5192 rtx label = XEXP (XVECEXP (vec_pat, diff_p, i), 0);
5194 if (s390_find_pool (pool_list, label)
5195 != s390_find_pool (pool_list, insn))
5196 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
5203 /* Insert base register reload insns before every pool. */
5205 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
5207 rtx new_insn = gen_reload_base (cfun->machine->base_reg,
5208 curr_pool->label);
5209 rtx insn = curr_pool->first_insn;
5210 INSN_ADDRESSES_NEW (emit_insn_before (new_insn, insn), -1);
5213 /* Insert base register reload insns at every far label. */
5215 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5216 if (GET_CODE (insn) == CODE_LABEL
5217 && bitmap_bit_p (far_labels, CODE_LABEL_NUMBER (insn)))
5219 struct constant_pool *pool = s390_find_pool (pool_list, insn);
5220 if (pool)
5222 rtx new_insn = gen_reload_base (cfun->machine->base_reg,
5223 pool->label);
5224 INSN_ADDRESSES_NEW (emit_insn_after (new_insn, insn), -1);
5229 BITMAP_XFREE (far_labels);
5232 /* Recompute insn addresses. */
5234 init_insn_lengths ();
5235 shorten_branches (get_insns ());
5237 return pool_list;
5240 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
5241 After we have decided to use this list, finish implementing
5242 all changes to the current function as required. */
5244 static void
5245 s390_chunkify_finish (struct constant_pool *pool_list)
5247 struct constant_pool *curr_pool = NULL;
5248 rtx insn;
5251 /* Replace all literal pool references. */
5253 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5255 if (INSN_P (insn))
5256 replace_ltrel_base (&PATTERN (insn));
5258 curr_pool = s390_find_pool (pool_list, insn);
5259 if (!curr_pool)
5260 continue;
5262 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
5264 rtx addr, pool_ref = NULL_RTX;
5265 find_constant_pool_ref (PATTERN (insn), &pool_ref);
5266 if (pool_ref)
5268 addr = s390_find_constant (curr_pool, get_pool_constant (pool_ref),
5269 get_pool_mode (pool_ref));
5270 replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
5271 INSN_CODE (insn) = -1;
5276 /* Dump out all literal pools. */
5278 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
5279 s390_dump_pool (curr_pool, 0);
5281 /* Free pool list. */
5283 while (pool_list)
5285 struct constant_pool *next = pool_list->next;
5286 s390_free_pool (pool_list);
5287 pool_list = next;
5291 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
5292 We have decided we cannot use this list, so revert all changes
5293 to the current function that were done by s390_chunkify_start. */
5295 static void
5296 s390_chunkify_cancel (struct constant_pool *pool_list)
5298 struct constant_pool *curr_pool = NULL;
5299 rtx insn;
5301 /* Remove all pool placeholder insns. */
5303 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
5305 /* Did we insert an extra barrier? Remove it. */
5306 rtx barrier = PREV_INSN (curr_pool->pool_insn);
5307 rtx jump = barrier? PREV_INSN (barrier) : NULL_RTX;
5308 rtx label = NEXT_INSN (curr_pool->pool_insn);
5310 if (jump && GET_CODE (jump) == JUMP_INSN
5311 && barrier && GET_CODE (barrier) == BARRIER
5312 && label && GET_CODE (label) == CODE_LABEL
5313 && GET_CODE (PATTERN (jump)) == SET
5314 && SET_DEST (PATTERN (jump)) == pc_rtx
5315 && GET_CODE (SET_SRC (PATTERN (jump))) == LABEL_REF
5316 && XEXP (SET_SRC (PATTERN (jump)), 0) == label)
5318 remove_insn (jump);
5319 remove_insn (barrier);
5320 remove_insn (label);
5323 remove_insn (curr_pool->pool_insn);
5326 /* Remove all base register reload insns. */
5328 for (insn = get_insns (); insn; )
5330 rtx next_insn = NEXT_INSN (insn);
5332 if (GET_CODE (insn) == INSN
5333 && GET_CODE (PATTERN (insn)) == SET
5334 && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC
5335 && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPEC_RELOAD_BASE)
5336 remove_insn (insn);
5338 insn = next_insn;
5341 /* Free pool list. */
5343 while (pool_list)
5345 struct constant_pool *next = pool_list->next;
5346 s390_free_pool (pool_list);
5347 pool_list = next;
5352 /* Output the constant pool entry EXP in mode MODE with alignment ALIGN. */
5354 void
5355 s390_output_pool_entry (rtx exp, enum machine_mode mode, unsigned int align)
5357 REAL_VALUE_TYPE r;
5359 switch (GET_MODE_CLASS (mode))
5361 case MODE_FLOAT:
5362 if (GET_CODE (exp) != CONST_DOUBLE)
5363 abort ();
5365 REAL_VALUE_FROM_CONST_DOUBLE (r, exp);
5366 assemble_real (r, mode, align);
5367 break;
5369 case MODE_INT:
5370 assemble_integer (exp, GET_MODE_SIZE (mode), align, 1);
5371 break;
5373 default:
5374 abort ();
5379 /* Rework the prologue/epilogue to avoid saving/restoring
5380 registers unnecessarily. BASE_USED specifies whether
5381 the literal pool base register needs to be saved. */
5383 static void
5384 s390_optimize_prologue (bool base_used)
5386 rtx insn, new_insn, next_insn;
5388 /* Do a final recompute of the frame-related data. */
5390 s390_register_info (base_used, cfun_frame_layout.save_return_addr_p);
5391 regs_ever_live[BASE_REGNUM] = base_used;
5392 regs_ever_live[RETURN_REGNUM] = cfun_frame_layout.save_return_addr_p;
5393 regs_ever_live[STACK_POINTER_REGNUM] = cfun_frame_layout.frame_size > 0;
5395 /* If all special registers are in fact used, there's nothing we
5396 can do, so no point in walking the insn list. */
5398 if (cfun_frame_layout.first_save_gpr <= BASE_REGNUM
5399 && cfun_frame_layout.last_save_gpr >= BASE_REGNUM
5400 && (TARGET_CPU_ZARCH
5401 || (cfun_frame_layout.first_save_gpr <= RETURN_REGNUM
5402 && cfun_frame_layout.last_save_gpr >= RETURN_REGNUM)))
5403 return;
5405 /* Search for prologue/epilogue insns and replace them. */
5407 for (insn = get_insns (); insn; insn = next_insn)
5409 int first, last, off;
5410 rtx set, base, offset;
5412 next_insn = NEXT_INSN (insn);
5414 if (GET_CODE (insn) != INSN)
5415 continue;
5417 if (GET_CODE (PATTERN (insn)) == PARALLEL
5418 && store_multiple_operation (PATTERN (insn), VOIDmode))
5420 set = XVECEXP (PATTERN (insn), 0, 0);
5421 first = REGNO (SET_SRC (set));
5422 last = first + XVECLEN (PATTERN (insn), 0) - 1;
5423 offset = const0_rtx;
5424 base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
5425 off = INTVAL (offset);
5427 if (GET_CODE (base) != REG || off < 0)
5428 continue;
5429 if (REGNO (base) != STACK_POINTER_REGNUM
5430 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
5431 continue;
5432 if (first > BASE_REGNUM || last < BASE_REGNUM)
5433 continue;
5435 if (cfun_frame_layout.first_save_gpr != -1)
5437 new_insn = save_gprs (base,
5438 off + (cfun_frame_layout.first_save_gpr
5439 - first) * UNITS_PER_WORD,
5440 cfun_frame_layout.first_save_gpr,
5441 cfun_frame_layout.last_save_gpr);
5442 new_insn = emit_insn_before (new_insn, insn);
5443 INSN_ADDRESSES_NEW (new_insn, -1);
5446 remove_insn (insn);
5447 continue;
5450 if (GET_CODE (PATTERN (insn)) == SET
5451 && GET_CODE (SET_SRC (PATTERN (insn))) == REG
5452 && REGNO (SET_SRC (PATTERN (insn))) == BASE_REGNUM
5453 && GET_CODE (SET_DEST (PATTERN (insn))) == MEM)
5455 set = PATTERN (insn);
5456 offset = const0_rtx;
5457 base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
5458 off = INTVAL (offset);
5460 if (GET_CODE (base) != REG || off < 0)
5461 continue;
5462 if (REGNO (base) != STACK_POINTER_REGNUM
5463 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
5464 continue;
5465 if (cfun_frame_layout.first_save_gpr != -1)
5467 new_insn = save_gprs (base,
5468 off + (cfun_frame_layout.first_save_gpr
5469 - BASE_REGNUM) * UNITS_PER_WORD,
5470 cfun_frame_layout.first_save_gpr,
5471 cfun_frame_layout.last_save_gpr);
5472 new_insn = emit_insn_before (new_insn, insn);
5473 INSN_ADDRESSES_NEW (new_insn, -1);
5476 remove_insn (insn);
5477 continue;
5480 if (GET_CODE (PATTERN (insn)) == PARALLEL
5481 && load_multiple_operation (PATTERN (insn), VOIDmode))
5483 set = XVECEXP (PATTERN (insn), 0, 0);
5484 first = REGNO (SET_DEST (set));
5485 last = first + XVECLEN (PATTERN (insn), 0) - 1;
5486 offset = const0_rtx;
5487 base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
5488 off = INTVAL (offset);
5490 if (GET_CODE (base) != REG || off < 0)
5491 continue;
5492 if (REGNO (base) != STACK_POINTER_REGNUM
5493 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
5494 continue;
5495 if (first > BASE_REGNUM || last < BASE_REGNUM)
5496 continue;
5498 if (cfun_frame_layout.first_restore_gpr != -1)
5500 new_insn = restore_gprs (base,
5501 off + (cfun_frame_layout.first_restore_gpr
5502 - first) * UNITS_PER_WORD,
5503 cfun_frame_layout.first_restore_gpr,
5504 cfun_frame_layout.last_restore_gpr);
5505 new_insn = emit_insn_before (new_insn, insn);
5506 INSN_ADDRESSES_NEW (new_insn, -1);
5509 remove_insn (insn);
5510 continue;
5513 if (GET_CODE (PATTERN (insn)) == SET
5514 && GET_CODE (SET_DEST (PATTERN (insn))) == REG
5515 && REGNO (SET_DEST (PATTERN (insn))) == BASE_REGNUM
5516 && GET_CODE (SET_SRC (PATTERN (insn))) == MEM)
5518 set = PATTERN (insn);
5519 offset = const0_rtx;
5520 base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
5521 off = INTVAL (offset);
5523 if (GET_CODE (base) != REG || off < 0)
5524 continue;
5525 if (REGNO (base) != STACK_POINTER_REGNUM
5526 && REGNO (base) != HARD_FRAME_POINTER_REGNUM)
5527 continue;
5528 if (cfun_frame_layout.first_restore_gpr != -1)
5530 new_insn = restore_gprs (base,
5531 off + (cfun_frame_layout.first_restore_gpr
5532 - BASE_REGNUM) * UNITS_PER_WORD,
5533 cfun_frame_layout.first_restore_gpr,
5534 cfun_frame_layout.last_restore_gpr);
5535 new_insn = emit_insn_before (new_insn, insn);
5536 INSN_ADDRESSES_NEW (new_insn, -1);
5539 remove_insn (insn);
5540 continue;
5545 /* Perform machine-dependent processing. */
5547 static void
5548 s390_reorg (void)
5550 bool base_used = false;
5551 bool pool_overflow = false;
5553 /* Make sure all splits have been performed; splits after
5554 machine_dependent_reorg might confuse insn length counts. */
5555 split_all_insns_noflow ();
5558 /* Install the main literal pool and the associated base
5559 register load insns.
5561 In addition, there are two problematic situations we need
5562 to correct:
5564 - the literal pool might be > 4096 bytes in size, so that
5565 some of its elements cannot be directly accessed
5567 - a branch target might be > 64K away from the branch, so that
5568 it is not possible to use a PC-relative instruction.
5570 To fix those, we split the single literal pool into multiple
5571 pool chunks, reloading the pool base register at various
5572 points throughout the function to ensure it always points to
5573 the pool chunk the following code expects, and / or replace
5574 PC-relative branches by absolute branches.
5576 However, the two problems are interdependent: splitting the
5577 literal pool can move a branch further away from its target,
5578 causing the 64K limit to overflow, and on the other hand,
5579 replacing a PC-relative branch by an absolute branch means
5580 we need to put the branch target address into the literal
5581 pool, possibly causing it to overflow.
5583 So, we loop trying to fix up both problems until we manage
5584 to satisfy both conditions at the same time. Note that the
5585 loop is guaranteed to terminate as every pass of the loop
5586 strictly decreases the total number of PC-relative branches
5587 in the function. (This is not completely true as there
5588 might be branch-over-pool insns introduced by chunkify_start.
5589 Those never need to be split however.) */
5591 for (;;)
5593 struct constant_pool *pool = NULL;
5595 /* Collect the literal pool. */
5596 if (!pool_overflow)
5598 pool = s390_mainpool_start ();
5599 if (!pool)
5600 pool_overflow = true;
5603 /* If literal pool overflowed, start to chunkify it. */
5604 if (pool_overflow)
5605 pool = s390_chunkify_start ();
5607 /* Split out-of-range branches. If this has created new
5608 literal pool entries, cancel current chunk list and
5609 recompute it. zSeries machines have large branch
5610 instructions, so we never need to split a branch. */
5611 if (!TARGET_CPU_ZARCH && s390_split_branches ())
5613 if (pool_overflow)
5614 s390_chunkify_cancel (pool);
5615 else
5616 s390_mainpool_cancel (pool);
5618 continue;
5621 /* If we made it up to here, both conditions are satisfied.
5622 Finish up literal pool related changes. */
5623 if ((pool_overflow || pool->size > 0)
5624 && REGNO (cfun->machine->base_reg) == BASE_REGNUM)
5625 base_used = true;
5627 if (pool_overflow)
5628 s390_chunkify_finish (pool);
5629 else
5630 s390_mainpool_finish (pool);
5632 break;
5635 s390_optimize_prologue (base_used);
5639 /* Return an RTL expression representing the value of the return address
5640 for the frame COUNT steps up from the current frame. FRAME is the
5641 frame pointer of that frame. */
5644 s390_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
5646 int offset;
5647 rtx addr;
5649 /* Without backchain, we fail for all but the current frame. */
5651 if (!TARGET_BACKCHAIN && !TARGET_KERNEL_BACKCHAIN && count > 0)
5652 return NULL_RTX;
5654 /* For the current frame, we need to make sure the initial
5655 value of RETURN_REGNUM is actually saved. */
5657 if (count == 0)
5659 cfun_frame_layout.save_return_addr_p = true;
5660 return gen_rtx_MEM (Pmode, return_address_pointer_rtx);
5663 if (TARGET_BACKCHAIN)
5664 offset = RETURN_REGNUM * UNITS_PER_WORD;
5665 else
5666 offset = -2 * UNITS_PER_WORD;
5668 addr = plus_constant (frame, offset);
5669 addr = memory_address (Pmode, addr);
5670 return gen_rtx_MEM (Pmode, addr);
5673 /* Find first call clobbered register unused in a function.
5674 This could be used as base register in a leaf function
5675 or for holding the return address before epilogue. */
5677 static int
5678 find_unused_clobbered_reg (void)
5680 int i;
5681 for (i = 0; i < 6; i++)
5682 if (!regs_ever_live[i])
5683 return i;
5684 return 0;
5687 /* Determine the frame area which actually has to be accessed
5688 in the function epilogue. The values are stored at the
5689 given pointers AREA_BOTTOM (address of the lowest used stack
5690 address) and AREA_TOP (address of the first item which does
5691 not belong to the stack frame). */
5693 static void
5694 s390_frame_area (int *area_bottom, int *area_top)
5696 int b, t;
5697 int i;
5699 b = INT_MAX;
5700 t = INT_MIN;
5702 if (cfun_frame_layout.first_restore_gpr != -1)
5704 b = (cfun_frame_layout.gprs_offset
5705 + cfun_frame_layout.first_restore_gpr * UNITS_PER_WORD);
5706 t = b + (cfun_frame_layout.last_restore_gpr
5707 - cfun_frame_layout.first_restore_gpr + 1) * UNITS_PER_WORD;
5710 if (TARGET_64BIT && cfun_save_high_fprs_p)
5712 b = MIN (b, cfun_frame_layout.f8_offset);
5713 t = MAX (t, (cfun_frame_layout.f8_offset
5714 + cfun_frame_layout.high_fprs * 8));
5717 if (!TARGET_64BIT)
5718 for (i = 2; i < 4; i++)
5719 if (cfun_fpr_bit_p (i))
5721 b = MIN (b, cfun_frame_layout.f4_offset + (i - 2) * 8);
5722 t = MAX (t, cfun_frame_layout.f4_offset + (i - 1) * 8);
5725 *area_bottom = b;
5726 *area_top = t;
5729 /* Fill cfun->machine with info about register usage of current
5730 function. BASE_USED and RETURN_ADDR_USED specify whether we assume the
5731 base and return address register will need to be saved. */
5733 static void
5734 s390_register_info (int base_used, int return_addr_used)
5736 int live_regs[16];
5737 int i, j;
5739 /* fprs 8 - 15 are call saved for 64 Bit ABI. */
5740 cfun_frame_layout.fpr_bitmap = 0;
5741 cfun_frame_layout.high_fprs = 0;
5742 if (TARGET_64BIT)
5743 for (i = 24; i < 32; i++)
5744 if (regs_ever_live[i] && !global_regs[i])
5746 cfun_set_fpr_bit (i - 16);
5747 cfun_frame_layout.high_fprs++;
5750 /* Find first and last gpr to be saved. We trust regs_ever_live
5751 data, except that we don't save and restore global registers.
5753 Also, all registers with special meaning to the compiler need
5754 to be handled extra. */
5756 for (i = 0; i < 16; i++)
5757 live_regs[i] = regs_ever_live[i] && !global_regs[i];
5759 if (flag_pic)
5760 live_regs[PIC_OFFSET_TABLE_REGNUM] =
5761 regs_ever_live[PIC_OFFSET_TABLE_REGNUM];
5763 live_regs[BASE_REGNUM] = base_used;
5764 live_regs[RETURN_REGNUM] = return_addr_used;
5765 live_regs[STACK_POINTER_REGNUM] = (!current_function_is_leaf
5766 || TARGET_TPF_PROFILING
5767 || cfun_save_high_fprs_p
5768 || get_frame_size () > 0
5769 || current_function_calls_alloca
5770 || current_function_stdarg);
5772 for (i = 6; i < 16; i++)
5773 if (live_regs[i])
5774 break;
5775 for (j = 15; j > i; j--)
5776 if (live_regs[j])
5777 break;
5779 if (i == 16)
5781 /* Nothing to save/restore. */
5782 cfun_frame_layout.first_save_gpr = -1;
5783 cfun_frame_layout.first_restore_gpr = -1;
5784 cfun_frame_layout.last_save_gpr = -1;
5785 cfun_frame_layout.last_restore_gpr = -1;
5787 else
5789 /* Save / Restore from gpr i to j. */
5790 cfun_frame_layout.first_save_gpr = i;
5791 cfun_frame_layout.first_restore_gpr = i;
5792 cfun_frame_layout.last_save_gpr = j;
5793 cfun_frame_layout.last_restore_gpr = j;
5796 if (current_function_stdarg)
5798 /* Varargs functions need to save gprs 2 to 6. */
5799 if (cfun_frame_layout.first_save_gpr == -1
5800 || cfun_frame_layout.first_save_gpr > 2)
5801 cfun_frame_layout.first_save_gpr = 2;
5803 if (cfun_frame_layout.last_save_gpr == -1
5804 || cfun_frame_layout.last_save_gpr < 6)
5805 cfun_frame_layout.last_save_gpr = 6;
5807 /* Mark f0, f2 for 31 bit and f0-f4 for 64 bit to be saved. */
5808 for (i = 0; i < (TARGET_64BIT ? 4 : 2); i++)
5809 cfun_set_fpr_bit (i);
5812 if (!TARGET_64BIT)
5813 for (i = 2; i < 4; i++)
5814 if (regs_ever_live[i + 16] && !global_regs[i + 16])
5815 cfun_set_fpr_bit (i);
5818 /* Fill cfun->machine with info about frame of current
5819 function. BASE_USED and RETURN_ADDR_USED specify whether we assume the
5820 base and return address register will need to be saved. */
5822 static void
5823 s390_frame_info (int base_used, int return_addr_used)
5825 int i;
5827 cfun_frame_layout.frame_size = get_frame_size ();
5829 s390_register_info (base_used, return_addr_used);
5831 if (!TARGET_64BIT && cfun_frame_layout.frame_size > 0x7fff0000)
5832 fatal_error ("Total size of local variables exceeds architecture limit.");
5834 cfun_frame_layout.save_backchain_p = (TARGET_BACKCHAIN
5835 || TARGET_KERNEL_BACKCHAIN);
5837 if (TARGET_BACKCHAIN)
5839 cfun_frame_layout.backchain_offset = 0;
5840 cfun_frame_layout.f0_offset = 16 * UNITS_PER_WORD;
5841 cfun_frame_layout.f4_offset = cfun_frame_layout.f0_offset + 2 * 8;
5842 cfun_frame_layout.f8_offset = -cfun_frame_layout.high_fprs * 8;
5843 cfun_frame_layout.gprs_offset = (cfun_frame_layout.first_save_gpr
5844 * UNITS_PER_WORD);
5846 else if (TARGET_KERNEL_BACKCHAIN)
5848 cfun_frame_layout.backchain_offset = (STACK_POINTER_OFFSET
5849 - UNITS_PER_WORD);
5850 cfun_frame_layout.gprs_offset
5851 = (cfun_frame_layout.backchain_offset
5852 - (STACK_POINTER_REGNUM - cfun_frame_layout.first_save_gpr + 1)
5853 * UNITS_PER_WORD);
5855 if (TARGET_64BIT)
5857 cfun_frame_layout.f4_offset
5858 = (cfun_frame_layout.gprs_offset
5859 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
5861 cfun_frame_layout.f0_offset
5862 = (cfun_frame_layout.f4_offset
5863 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
5865 else
5867 cfun_frame_layout.f0_offset
5868 = (cfun_frame_layout.gprs_offset
5869 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
5871 cfun_frame_layout.f4_offset
5872 = (cfun_frame_layout.f0_offset
5873 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
5876 else /* no backchain */
5878 cfun_frame_layout.f4_offset
5879 = (STACK_POINTER_OFFSET
5880 - 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
5882 cfun_frame_layout.f0_offset
5883 = (cfun_frame_layout.f4_offset
5884 - 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
5886 cfun_frame_layout.gprs_offset
5887 = cfun_frame_layout.f0_offset - cfun_gprs_save_area_size;
5890 if (current_function_is_leaf
5891 && !TARGET_TPF_PROFILING
5892 && cfun_frame_layout.frame_size == 0
5893 && !cfun_save_high_fprs_p
5894 && !current_function_calls_alloca
5895 && !current_function_stdarg)
5896 return;
5898 if (TARGET_BACKCHAIN)
5899 cfun_frame_layout.frame_size += (STARTING_FRAME_OFFSET
5900 + cfun_frame_layout.high_fprs * 8);
5901 else
5903 cfun_frame_layout.frame_size += (cfun_frame_layout.save_backchain_p
5904 * UNITS_PER_WORD);
5906 cfun_frame_layout.f8_offset = (MIN (MIN (cfun_frame_layout.f0_offset,
5907 cfun_frame_layout.f4_offset),
5908 cfun_frame_layout.gprs_offset)
5909 - cfun_frame_layout.high_fprs * 8);
5911 cfun_frame_layout.frame_size += cfun_frame_layout.high_fprs * 8;
5913 for (i = 0; i < 8; i++)
5914 if (cfun_fpr_bit_p (i))
5915 cfun_frame_layout.frame_size += 8;
5917 cfun_frame_layout.frame_size += cfun_gprs_save_area_size;
5918 cfun_frame_layout.frame_size = ((cfun_frame_layout.frame_size +
5919 STACK_BOUNDARY / BITS_PER_UNIT - 1)
5920 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
5922 cfun_frame_layout.frame_size += current_function_outgoing_args_size;
5926 /* Return offset between argument pointer and frame pointer
5927 initially after prologue. */
5929 HOST_WIDE_INT
5930 s390_arg_frame_offset (void)
5932 /* See the comment in s390_emit_prologue about the assumptions we make
5933 whether or not the base and return address register need to be saved. */
5934 int return_addr_used = !current_function_is_leaf
5935 || TARGET_TPF_PROFILING
5936 || regs_ever_live[RETURN_REGNUM]
5937 || cfun_frame_layout.save_return_addr_p;
5939 s390_frame_info (1, !TARGET_CPU_ZARCH || return_addr_used);
5941 return cfun_frame_layout.frame_size + STACK_POINTER_OFFSET;
5944 /* Return offset between return address pointer (location of r14
5945 on the stack) and frame pointer initially after prologue. */
5947 HOST_WIDE_INT
5948 s390_return_address_offset (void)
5950 s390_frame_info (1, 1);
5952 if (cfun_frame_layout.last_save_gpr < RETURN_REGNUM)
5953 abort ();
5955 return (cfun_frame_layout.frame_size + cfun_frame_layout.gprs_offset
5956 + (RETURN_REGNUM - cfun_frame_layout.first_save_gpr) * UNITS_PER_WORD);
5959 /* Emit insn to save fpr REGNUM at offset OFFSET relative
5960 to register BASE. Return generated insn. */
5962 static rtx
5963 save_fpr (rtx base, int offset, int regnum)
5965 rtx addr;
5966 addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
5967 set_mem_alias_set (addr, s390_sr_alias_set);
5969 return emit_move_insn (addr, gen_rtx_REG (DFmode, regnum));
5972 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
5973 to register BASE. Return generated insn. */
5975 static rtx
5976 restore_fpr (rtx base, int offset, int regnum)
5978 rtx addr;
5979 addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
5980 set_mem_alias_set (addr, s390_sr_alias_set);
5982 return emit_move_insn (gen_rtx_REG (DFmode, regnum), addr);
5985 /* Generate insn to save registers FIRST to LAST into
5986 the register save area located at offset OFFSET
5987 relative to register BASE. */
5989 static rtx
5990 save_gprs (rtx base, int offset, int first, int last)
5992 rtx addr, insn, note;
5993 int i;
5995 addr = plus_constant (base, offset);
5996 addr = gen_rtx_MEM (Pmode, addr);
5997 set_mem_alias_set (addr, s390_sr_alias_set);
5999 /* Special-case single register. */
6000 if (first == last)
6002 if (TARGET_64BIT)
6003 insn = gen_movdi (addr, gen_rtx_REG (Pmode, first));
6004 else
6005 insn = gen_movsi (addr, gen_rtx_REG (Pmode, first));
6007 RTX_FRAME_RELATED_P (insn) = 1;
6008 return insn;
6012 insn = gen_store_multiple (addr,
6013 gen_rtx_REG (Pmode, first),
6014 GEN_INT (last - first + 1));
6017 /* We need to set the FRAME_RELATED flag on all SETs
6018 inside the store-multiple pattern.
6020 However, we must not emit DWARF records for registers 2..5
6021 if they are stored for use by variable arguments ...
6023 ??? Unfortunately, it is not enough to simply not the the
6024 FRAME_RELATED flags for those SETs, because the first SET
6025 of the PARALLEL is always treated as if it had the flag
6026 set, even if it does not. Therefore we emit a new pattern
6027 without those registers as REG_FRAME_RELATED_EXPR note. */
6029 if (first >= 6)
6031 rtx pat = PATTERN (insn);
6033 for (i = 0; i < XVECLEN (pat, 0); i++)
6034 if (GET_CODE (XVECEXP (pat, 0, i)) == SET)
6035 RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1;
6037 RTX_FRAME_RELATED_P (insn) = 1;
6039 else if (last >= 6)
6041 addr = plus_constant (base, offset + (6 - first) * UNITS_PER_WORD);
6042 note = gen_store_multiple (gen_rtx_MEM (Pmode, addr),
6043 gen_rtx_REG (Pmode, 6),
6044 GEN_INT (last - 6 + 1));
6045 note = PATTERN (note);
6047 REG_NOTES (insn) =
6048 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
6049 note, REG_NOTES (insn));
6051 for (i = 0; i < XVECLEN (note, 0); i++)
6052 if (GET_CODE (XVECEXP (note, 0, i)) == SET)
6053 RTX_FRAME_RELATED_P (XVECEXP (note, 0, i)) = 1;
6055 RTX_FRAME_RELATED_P (insn) = 1;
6058 return insn;
6061 /* Generate insn to restore registers FIRST to LAST from
6062 the register save area located at offset OFFSET
6063 relative to register BASE. */
6065 static rtx
6066 restore_gprs (rtx base, int offset, int first, int last)
6068 rtx addr, insn;
6070 addr = plus_constant (base, offset);
6071 addr = gen_rtx_MEM (Pmode, addr);
6072 set_mem_alias_set (addr, s390_sr_alias_set);
6074 /* Special-case single register. */
6075 if (first == last)
6077 if (TARGET_64BIT)
6078 insn = gen_movdi (gen_rtx_REG (Pmode, first), addr);
6079 else
6080 insn = gen_movsi (gen_rtx_REG (Pmode, first), addr);
6082 return insn;
6085 insn = gen_load_multiple (gen_rtx_REG (Pmode, first),
6086 addr,
6087 GEN_INT (last - first + 1));
6088 return insn;
6091 /* Return insn sequence to load the GOT register. */
6093 static GTY(()) rtx got_symbol;
6095 s390_load_got (void)
6097 rtx insns;
6099 if (!got_symbol)
6101 got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6102 SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
6105 start_sequence ();
6107 if (TARGET_CPU_ZARCH)
6109 emit_move_insn (pic_offset_table_rtx, got_symbol);
6111 else
6113 rtx offset;
6115 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got_symbol),
6116 UNSPEC_LTREL_OFFSET);
6117 offset = gen_rtx_CONST (Pmode, offset);
6118 offset = force_const_mem (Pmode, offset);
6120 emit_move_insn (pic_offset_table_rtx, offset);
6122 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (offset, 0)),
6123 UNSPEC_LTREL_BASE);
6124 offset = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, offset);
6126 emit_move_insn (pic_offset_table_rtx, offset);
6129 insns = get_insns ();
6130 end_sequence ();
6131 return insns;
6134 /* Expand the prologue into a bunch of separate insns. */
6136 void
6137 s390_emit_prologue (void)
6139 rtx insn, addr;
6140 rtx temp_reg;
6141 int i;
6142 int offset;
6143 int next_fpr = 0;
6145 /* At this point, we decide whether we'll need to save/restore the
6146 return address register. This decision is final on zSeries machines;
6147 on S/390 it can still be overridden in s390_split_branches. */
6149 if (!current_function_is_leaf
6150 || TARGET_TPF_PROFILING
6151 || regs_ever_live[RETURN_REGNUM])
6152 cfun_frame_layout.save_return_addr_p = 1;
6154 /* Decide which register to use as literal pool base. In small leaf
6155 functions, try to use an unused call-clobbered register as base
6156 register to avoid save/restore overhead. */
6158 if (current_function_is_leaf && !regs_ever_live[5])
6159 cfun->machine->base_reg = gen_rtx_REG (Pmode, 5);
6160 else
6161 cfun->machine->base_reg = gen_rtx_REG (Pmode, BASE_REGNUM);
6163 regs_ever_live[REGNO (cfun->machine->base_reg)] = 1;
6165 /* Compute frame info. Note that at this point, we assume the base
6166 register and -on S/390- the return register always need to be saved.
6167 This is done because the usage of these registers might change even
6168 after the prologue was emitted. If it turns out later that we really
6169 don't need them, the prologue/epilogue code is modified again. */
6171 s390_frame_info (1, !TARGET_CPU_ZARCH
6172 || cfun_frame_layout.save_return_addr_p);
6174 /* We need to update regs_ever_live to avoid data-flow problems. */
6176 regs_ever_live[BASE_REGNUM] = 1;
6177 regs_ever_live[RETURN_REGNUM] = (!TARGET_CPU_ZARCH
6178 || cfun_frame_layout.save_return_addr_p);
6179 regs_ever_live[STACK_POINTER_REGNUM] = cfun_frame_layout.frame_size > 0;
6181 /* Annotate all constant pool references to let the scheduler know
6182 they implicitly use the base register. */
6184 push_topmost_sequence ();
6186 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6187 if (INSN_P (insn))
6188 annotate_constant_pool_refs (&PATTERN (insn));
6190 pop_topmost_sequence ();
6192 /* Choose best register to use for temp use within prologue.
6193 See below for why TPF must use the register 1. */
6195 if (!current_function_is_leaf && !TARGET_TPF_PROFILING)
6196 temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
6197 else
6198 temp_reg = gen_rtx_REG (Pmode, 1);
6200 /* Save call saved gprs. */
6201 if (cfun_frame_layout.first_save_gpr != -1)
6202 insn = save_gprs (stack_pointer_rtx,
6203 cfun_frame_layout.gprs_offset,
6204 cfun_frame_layout.first_save_gpr,
6205 cfun_frame_layout.last_save_gpr);
6206 emit_insn (insn);
6208 /* Dummy insn to mark literal pool slot. */
6210 emit_insn (gen_main_pool (cfun->machine->base_reg));
6212 offset = cfun_frame_layout.f0_offset;
6214 /* Save f0 and f2. */
6215 for (i = 0; i < 2; i++)
6217 if (cfun_fpr_bit_p (i))
6219 save_fpr (stack_pointer_rtx, offset, i + 16);
6220 offset += 8;
6222 else if (TARGET_BACKCHAIN)
6223 offset += 8;
6226 /* Save f4 and f6. */
6227 offset = cfun_frame_layout.f4_offset;
6228 for (i = 2; i < 4; i++)
6230 if (cfun_fpr_bit_p (i))
6232 insn = save_fpr (stack_pointer_rtx, offset, i + 16);
6233 offset += 8;
6235 /* If f4 and f6 are call clobbered they are saved due to stdargs and
6236 therefore are not frame related. */
6237 if (!call_really_used_regs[i + 16])
6238 RTX_FRAME_RELATED_P (insn) = 1;
6240 else if (TARGET_BACKCHAIN)
6241 offset += 8;
6244 if (!TARGET_BACKCHAIN
6245 && cfun_save_high_fprs_p
6246 && cfun_frame_layout.f8_offset + cfun_frame_layout.high_fprs * 8 > 0)
6248 offset = (cfun_frame_layout.f8_offset
6249 + (cfun_frame_layout.high_fprs - 1) * 8);
6251 for (i = 15; i > 7 && offset >= 0; i--)
6252 if (cfun_fpr_bit_p (i))
6254 insn = save_fpr (stack_pointer_rtx, offset, i + 16);
6256 RTX_FRAME_RELATED_P (insn) = 1;
6257 offset -= 8;
6259 if (offset >= cfun_frame_layout.f8_offset)
6260 next_fpr = i + 16;
6263 if (TARGET_BACKCHAIN)
6264 next_fpr = cfun_save_high_fprs_p ? 31 : 0;
6266 /* Decrement stack pointer. */
6268 if (cfun_frame_layout.frame_size > 0)
6270 rtx frame_off = GEN_INT (-cfun_frame_layout.frame_size);
6272 /* Save incoming stack pointer into temp reg. */
6273 if (cfun_frame_layout.save_backchain_p || next_fpr)
6274 insn = emit_insn (gen_move_insn (temp_reg, stack_pointer_rtx));
6276 /* Subtract frame size from stack pointer. */
6278 if (DISP_IN_RANGE (INTVAL (frame_off)))
6280 insn = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
6281 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
6282 frame_off));
6283 insn = emit_insn (insn);
6285 else
6287 if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off), 'K', "K"))
6288 frame_off = force_const_mem (Pmode, frame_off);
6290 insn = emit_insn (gen_add2_insn (stack_pointer_rtx, frame_off));
6291 annotate_constant_pool_refs (&PATTERN (insn));
6294 RTX_FRAME_RELATED_P (insn) = 1;
6295 REG_NOTES (insn) =
6296 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
6297 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
6298 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
6299 GEN_INT (-cfun_frame_layout.frame_size))),
6300 REG_NOTES (insn));
6302 /* Set backchain. */
6304 if (cfun_frame_layout.save_backchain_p)
6306 if (cfun_frame_layout.backchain_offset)
6307 addr = gen_rtx_MEM (Pmode,
6308 plus_constant (stack_pointer_rtx,
6309 cfun_frame_layout.backchain_offset));
6310 else
6311 addr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
6312 set_mem_alias_set (addr, s390_sr_alias_set);
6313 insn = emit_insn (gen_move_insn (addr, temp_reg));
6316 /* If we support asynchronous exceptions (e.g. for Java),
6317 we need to make sure the backchain pointer is set up
6318 before any possibly trapping memory access. */
6320 if (cfun_frame_layout.save_backchain_p && flag_non_call_exceptions)
6322 addr = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
6323 emit_insn (gen_rtx_CLOBBER (VOIDmode, addr));
6327 /* Save fprs 8 - 15 (64 bit ABI). */
6329 if (cfun_save_high_fprs_p && next_fpr)
6331 insn = emit_insn (gen_add2_insn (temp_reg,
6332 GEN_INT (cfun_frame_layout.f8_offset)));
6334 offset = 0;
6336 for (i = 24; i <= next_fpr; i++)
6337 if (cfun_fpr_bit_p (i - 16))
6339 rtx addr = plus_constant (stack_pointer_rtx,
6340 cfun_frame_layout.frame_size
6341 + cfun_frame_layout.f8_offset
6342 + offset);
6344 insn = save_fpr (temp_reg, offset, i);
6345 offset += 8;
6346 RTX_FRAME_RELATED_P (insn) = 1;
6347 REG_NOTES (insn) =
6348 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
6349 gen_rtx_SET (VOIDmode,
6350 gen_rtx_MEM (DFmode, addr),
6351 gen_rtx_REG (DFmode, i)),
6352 REG_NOTES (insn));
6356 /* Set frame pointer, if needed. */
6358 if (frame_pointer_needed)
6360 insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
6361 RTX_FRAME_RELATED_P (insn) = 1;
6364 /* Set up got pointer, if needed. */
6366 if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
6368 rtx insns = s390_load_got ();
6370 for (insn = insns; insn; insn = NEXT_INSN (insn))
6372 annotate_constant_pool_refs (&PATTERN (insn));
6374 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
6375 REG_NOTES (insn));
6378 emit_insn (insns);
6381 if (TARGET_TPF_PROFILING)
6383 /* Generate a BAS instruction to serve as a function
6384 entry intercept to facilitate the use of tracing
6385 algorithms located at the branch target. */
6386 emit_insn (gen_prologue_tpf ());
6388 /* Emit a blockage here so that all code
6389 lies between the profiling mechanisms. */
6390 emit_insn (gen_blockage ());
6394 /* Expand the epilogue into a bunch of separate insns. */
6396 void
6397 s390_emit_epilogue (bool sibcall)
6399 rtx frame_pointer, return_reg;
6400 int area_bottom, area_top, offset = 0;
6401 int next_offset;
6402 rtvec p;
6403 int i;
6405 if (TARGET_TPF_PROFILING)
6408 /* Generate a BAS instruction to serve as a function
6409 entry intercept to facilitate the use of tracing
6410 algorithms located at the branch target. */
6412 /* Emit a blockage here so that all code
6413 lies between the profiling mechanisms. */
6414 emit_insn (gen_blockage ());
6416 emit_insn (gen_epilogue_tpf ());
6419 /* Check whether to use frame or stack pointer for restore. */
6421 frame_pointer = (frame_pointer_needed
6422 ? hard_frame_pointer_rtx : stack_pointer_rtx);
6424 s390_frame_area (&area_bottom, &area_top);
6426 /* Check whether we can access the register save area.
6427 If not, increment the frame pointer as required. */
6429 if (area_top <= area_bottom)
6431 /* Nothing to restore. */
6433 else if (DISP_IN_RANGE (cfun_frame_layout.frame_size + area_bottom)
6434 && DISP_IN_RANGE (cfun_frame_layout.frame_size + area_top - 1))
6436 /* Area is in range. */
6437 offset = cfun_frame_layout.frame_size;
6439 else
6441 rtx insn, frame_off;
6443 offset = area_bottom < 0 ? -area_bottom : 0;
6444 frame_off = GEN_INT (cfun_frame_layout.frame_size - offset);
6446 if (DISP_IN_RANGE (INTVAL (frame_off)))
6448 insn = gen_rtx_SET (VOIDmode, frame_pointer,
6449 gen_rtx_PLUS (Pmode, frame_pointer, frame_off));
6450 insn = emit_insn (insn);
6452 else
6454 if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off), 'K', "K"))
6455 frame_off = force_const_mem (Pmode, frame_off);
6457 insn = emit_insn (gen_add2_insn (frame_pointer, frame_off));
6458 annotate_constant_pool_refs (&PATTERN (insn));
6462 /* Restore call saved fprs. */
6464 if (TARGET_64BIT)
6466 if (cfun_save_high_fprs_p)
6468 next_offset = cfun_frame_layout.f8_offset;
6469 for (i = 24; i < 32; i++)
6471 if (cfun_fpr_bit_p (i - 16))
6473 restore_fpr (frame_pointer,
6474 offset + next_offset, i);
6475 next_offset += 8;
6481 else
6483 next_offset = cfun_frame_layout.f4_offset;
6484 for (i = 18; i < 20; i++)
6486 if (cfun_fpr_bit_p (i - 16))
6488 restore_fpr (frame_pointer,
6489 offset + next_offset, i);
6490 next_offset += 8;
6492 else if (TARGET_BACKCHAIN)
6493 next_offset += 8;
6498 /* Return register. */
6500 return_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
6502 /* Restore call saved gprs. */
6504 if (cfun_frame_layout.first_restore_gpr != -1)
6506 rtx insn, addr;
6507 int i;
6509 /* Check for global register and save them
6510 to stack location from where they get restored. */
6512 for (i = cfun_frame_layout.first_restore_gpr;
6513 i <= cfun_frame_layout.last_restore_gpr;
6514 i++)
6516 /* These registers are special and need to be
6517 restored in any case. */
6518 if (i == STACK_POINTER_REGNUM
6519 || i == RETURN_REGNUM
6520 || i == BASE_REGNUM
6521 || (flag_pic && i == (int)PIC_OFFSET_TABLE_REGNUM))
6522 continue;
6524 if (global_regs[i])
6526 addr = plus_constant (frame_pointer,
6527 offset + cfun_frame_layout.gprs_offset
6528 + (i - cfun_frame_layout.first_save_gpr)
6529 * UNITS_PER_WORD);
6530 addr = gen_rtx_MEM (Pmode, addr);
6531 set_mem_alias_set (addr, s390_sr_alias_set);
6532 emit_move_insn (addr, gen_rtx_REG (Pmode, i));
6536 if (! sibcall)
6538 /* Fetch return address from stack before load multiple,
6539 this will do good for scheduling. */
6541 if (cfun_frame_layout.save_return_addr_p
6542 || (cfun_frame_layout.first_restore_gpr < BASE_REGNUM
6543 && cfun_frame_layout.last_restore_gpr > RETURN_REGNUM))
6545 int return_regnum = find_unused_clobbered_reg();
6546 if (!return_regnum)
6547 return_regnum = 4;
6548 return_reg = gen_rtx_REG (Pmode, return_regnum);
6550 addr = plus_constant (frame_pointer,
6551 offset + cfun_frame_layout.gprs_offset
6552 + (RETURN_REGNUM
6553 - cfun_frame_layout.first_save_gpr)
6554 * UNITS_PER_WORD);
6555 addr = gen_rtx_MEM (Pmode, addr);
6556 set_mem_alias_set (addr, s390_sr_alias_set);
6557 emit_move_insn (return_reg, addr);
6561 insn = restore_gprs (frame_pointer,
6562 offset + cfun_frame_layout.gprs_offset
6563 + (cfun_frame_layout.first_restore_gpr
6564 - cfun_frame_layout.first_save_gpr)
6565 * UNITS_PER_WORD,
6566 cfun_frame_layout.first_restore_gpr,
6567 cfun_frame_layout.last_restore_gpr);
6568 emit_insn (insn);
6571 if (! sibcall)
6574 /* Return to caller. */
6576 p = rtvec_alloc (2);
6578 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
6579 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, return_reg);
6580 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
6585 /* Return the size in bytes of a function argument of
6586 type TYPE and/or mode MODE. At least one of TYPE or
6587 MODE must be specified. */
6589 static int
6590 s390_function_arg_size (enum machine_mode mode, tree type)
6592 if (type)
6593 return int_size_in_bytes (type);
6595 /* No type info available for some library calls ... */
6596 if (mode != BLKmode)
6597 return GET_MODE_SIZE (mode);
6599 /* If we have neither type nor mode, abort */
6600 abort ();
6603 /* Return true if a function argument of type TYPE and mode MODE
6604 is to be passed in a floating-point register, if available. */
6606 static bool
6607 s390_function_arg_float (enum machine_mode mode, tree type)
6609 int size = s390_function_arg_size (mode, type);
6610 if (size > 8)
6611 return false;
6613 /* Soft-float changes the ABI: no floating-point registers are used. */
6614 if (TARGET_SOFT_FLOAT)
6615 return false;
6617 /* No type info available for some library calls ... */
6618 if (!type)
6619 return mode == SFmode || mode == DFmode;
6621 /* The ABI says that record types with a single member are treated
6622 just like that member would be. */
6623 while (TREE_CODE (type) == RECORD_TYPE)
6625 tree field, single = NULL_TREE;
6627 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
6629 if (TREE_CODE (field) != FIELD_DECL)
6630 continue;
6632 if (single == NULL_TREE)
6633 single = TREE_TYPE (field);
6634 else
6635 return false;
6638 if (single == NULL_TREE)
6639 return false;
6640 else
6641 type = single;
6644 return TREE_CODE (type) == REAL_TYPE;
6647 /* Return true if a function argument of type TYPE and mode MODE
6648 is to be passed in an integer register, or a pair of integer
6649 registers, if available. */
6651 static bool
6652 s390_function_arg_integer (enum machine_mode mode, tree type)
6654 int size = s390_function_arg_size (mode, type);
6655 if (size > 8)
6656 return false;
6658 /* No type info available for some library calls ... */
6659 if (!type)
6660 return GET_MODE_CLASS (mode) == MODE_INT
6661 || (TARGET_SOFT_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT);
6663 /* We accept small integral (and similar) types. */
6664 if (INTEGRAL_TYPE_P (type)
6665 || POINTER_TYPE_P (type)
6666 || TREE_CODE (type) == OFFSET_TYPE
6667 || (TARGET_SOFT_FLOAT && TREE_CODE (type) == REAL_TYPE))
6668 return true;
6670 /* We also accept structs of size 1, 2, 4, 8 that are not
6671 passed in floating-point registers. */
6672 if (AGGREGATE_TYPE_P (type)
6673 && exact_log2 (size) >= 0
6674 && !s390_function_arg_float (mode, type))
6675 return true;
6677 return false;
6680 /* Return 1 if a function argument of type TYPE and mode MODE
6681 is to be passed by reference. The ABI specifies that only
6682 structures of size 1, 2, 4, or 8 bytes are passed by value,
6683 all other structures (and complex numbers) are passed by
6684 reference. */
6686 static bool
6687 s390_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
6688 enum machine_mode mode, tree type,
6689 bool named ATTRIBUTE_UNUSED)
6691 int size = s390_function_arg_size (mode, type);
6692 if (size > 8)
6693 return true;
6695 if (type)
6697 if (AGGREGATE_TYPE_P (type) && exact_log2 (size) < 0)
6698 return 1;
6700 if (TREE_CODE (type) == COMPLEX_TYPE
6701 || TREE_CODE (type) == VECTOR_TYPE)
6702 return 1;
6705 return 0;
6708 /* Update the data in CUM to advance over an argument of mode MODE and
6709 data type TYPE. (TYPE is null for libcalls where that information
6710 may not be available.). The boolean NAMED specifies whether the
6711 argument is a named argument (as opposed to an unnamed argument
6712 matching an ellipsis). */
6714 void
6715 s390_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
6716 tree type, int named ATTRIBUTE_UNUSED)
6718 if (s390_function_arg_float (mode, type))
6720 cum->fprs += 1;
6722 else if (s390_function_arg_integer (mode, type))
6724 int size = s390_function_arg_size (mode, type);
6725 cum->gprs += ((size + UNITS_PER_WORD-1) / UNITS_PER_WORD);
6727 else
6728 abort ();
6731 /* Define where to put the arguments to a function.
6732 Value is zero to push the argument on the stack,
6733 or a hard register in which to store the argument.
6735 MODE is the argument's machine mode.
6736 TYPE is the data type of the argument (as a tree).
6737 This is null for libcalls where that information may
6738 not be available.
6739 CUM is a variable of type CUMULATIVE_ARGS which gives info about
6740 the preceding args and about the function being called.
6741 NAMED is nonzero if this argument is a named parameter
6742 (otherwise it is an extra parameter matching an ellipsis).
6744 On S/390, we use general purpose registers 2 through 6 to
6745 pass integer, pointer, and certain structure arguments, and
6746 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
6747 to pass floating point arguments. All remaining arguments
6748 are pushed to the stack. */
6751 s390_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
6752 int named ATTRIBUTE_UNUSED)
6754 if (s390_function_arg_float (mode, type))
6756 if (cum->fprs + 1 > (TARGET_64BIT? 4 : 2))
6757 return 0;
6758 else
6759 return gen_rtx_REG (mode, cum->fprs + 16);
6761 else if (s390_function_arg_integer (mode, type))
6763 int size = s390_function_arg_size (mode, type);
6764 int n_gprs = (size + UNITS_PER_WORD-1) / UNITS_PER_WORD;
6766 if (cum->gprs + n_gprs > 5)
6767 return 0;
6768 else
6769 return gen_rtx_REG (mode, cum->gprs + 2);
6772 /* After the real arguments, expand_call calls us once again
6773 with a void_type_node type. Whatever we return here is
6774 passed as operand 2 to the call expanders.
6776 We don't need this feature ... */
6777 else if (type == void_type_node)
6778 return const0_rtx;
6780 abort ();
6783 /* Return true if return values of type TYPE should be returned
6784 in a memory buffer whose address is passed by the caller as
6785 hidden first argument. */
6787 static bool
6788 s390_return_in_memory (tree type, tree fundecl ATTRIBUTE_UNUSED)
6790 /* We accept small integral (and similar) types. */
6791 if (INTEGRAL_TYPE_P (type)
6792 || POINTER_TYPE_P (type)
6793 || TREE_CODE (type) == OFFSET_TYPE
6794 || TREE_CODE (type) == REAL_TYPE)
6795 return int_size_in_bytes (type) > 8;
6797 /* Aggregates and similar constructs are always returned
6798 in memory. */
6799 if (AGGREGATE_TYPE_P (type)
6800 || TREE_CODE (type) == COMPLEX_TYPE
6801 || TREE_CODE (type) == VECTOR_TYPE)
6802 return true;
6804 /* ??? We get called on all sorts of random stuff from
6805 aggregate_value_p. We can't abort, but it's not clear
6806 what's safe to return. Pretend it's a struct I guess. */
6807 return true;
6810 /* Define where to return a (scalar) value of type TYPE.
6811 If TYPE is null, define where to return a (scalar)
6812 value of mode MODE from a libcall. */
6815 s390_function_value (tree type, enum machine_mode mode)
6817 if (type)
6819 int unsignedp = TYPE_UNSIGNED (type);
6820 mode = promote_mode (type, TYPE_MODE (type), &unsignedp, 1);
6823 if (GET_MODE_CLASS (mode) != MODE_INT
6824 && GET_MODE_CLASS (mode) != MODE_FLOAT)
6825 abort ();
6826 if (GET_MODE_SIZE (mode) > 8)
6827 abort ();
6829 if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT)
6830 return gen_rtx_REG (mode, 16);
6831 else
6832 return gen_rtx_REG (mode, 2);
6836 /* Create and return the va_list datatype.
6838 On S/390, va_list is an array type equivalent to
6840 typedef struct __va_list_tag
6842 long __gpr;
6843 long __fpr;
6844 void *__overflow_arg_area;
6845 void *__reg_save_area;
6846 } va_list[1];
6848 where __gpr and __fpr hold the number of general purpose
6849 or floating point arguments used up to now, respectively,
6850 __overflow_arg_area points to the stack location of the
6851 next argument passed on the stack, and __reg_save_area
6852 always points to the start of the register area in the
6853 call frame of the current function. The function prologue
6854 saves all registers used for argument passing into this
6855 area if the function uses variable arguments. */
6857 static tree
6858 s390_build_builtin_va_list (void)
6860 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
6862 record = lang_hooks.types.make_type (RECORD_TYPE);
6864 type_decl =
6865 build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
6867 f_gpr = build_decl (FIELD_DECL, get_identifier ("__gpr"),
6868 long_integer_type_node);
6869 f_fpr = build_decl (FIELD_DECL, get_identifier ("__fpr"),
6870 long_integer_type_node);
6871 f_ovf = build_decl (FIELD_DECL, get_identifier ("__overflow_arg_area"),
6872 ptr_type_node);
6873 f_sav = build_decl (FIELD_DECL, get_identifier ("__reg_save_area"),
6874 ptr_type_node);
6876 DECL_FIELD_CONTEXT (f_gpr) = record;
6877 DECL_FIELD_CONTEXT (f_fpr) = record;
6878 DECL_FIELD_CONTEXT (f_ovf) = record;
6879 DECL_FIELD_CONTEXT (f_sav) = record;
6881 TREE_CHAIN (record) = type_decl;
6882 TYPE_NAME (record) = type_decl;
6883 TYPE_FIELDS (record) = f_gpr;
6884 TREE_CHAIN (f_gpr) = f_fpr;
6885 TREE_CHAIN (f_fpr) = f_ovf;
6886 TREE_CHAIN (f_ovf) = f_sav;
6888 layout_type (record);
6890 /* The correct type is an array type of one element. */
6891 return build_array_type (record, build_index_type (size_zero_node));
6894 /* Implement va_start by filling the va_list structure VALIST.
6895 STDARG_P is always true, and ignored.
6896 NEXTARG points to the first anonymous stack argument.
6898 The following global variables are used to initialize
6899 the va_list structure:
6901 current_function_args_info:
6902 holds number of gprs and fprs used for named arguments.
6903 current_function_arg_offset_rtx:
6904 holds the offset of the first anonymous stack argument
6905 (relative to the virtual arg pointer). */
6907 void
6908 s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
6910 HOST_WIDE_INT n_gpr, n_fpr;
6911 int off;
6912 tree f_gpr, f_fpr, f_ovf, f_sav;
6913 tree gpr, fpr, ovf, sav, t;
6915 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
6916 f_fpr = TREE_CHAIN (f_gpr);
6917 f_ovf = TREE_CHAIN (f_fpr);
6918 f_sav = TREE_CHAIN (f_ovf);
6920 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
6921 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
6922 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
6923 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
6924 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
6926 /* Count number of gp and fp argument registers used. */
6928 n_gpr = current_function_args_info.gprs;
6929 n_fpr = current_function_args_info.fprs;
6931 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
6932 build_int_cst (NULL_TREE, n_gpr, 0));
6933 TREE_SIDE_EFFECTS (t) = 1;
6934 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6936 t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
6937 build_int_cst (NULL_TREE, n_fpr, 0));
6938 TREE_SIDE_EFFECTS (t) = 1;
6939 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6941 /* Find the overflow area. */
6942 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
6944 off = INTVAL (current_function_arg_offset_rtx);
6945 off = off < 0 ? 0 : off;
6946 if (TARGET_DEBUG_ARG)
6947 fprintf (stderr, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
6948 (int)n_gpr, (int)n_fpr, off);
6950 t = build (PLUS_EXPR, TREE_TYPE (ovf), t, build_int_cst (NULL_TREE, off, 0));
6952 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
6953 TREE_SIDE_EFFECTS (t) = 1;
6954 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6956 /* Find the register save area. */
6957 t = make_tree (TREE_TYPE (sav), return_address_pointer_rtx);
6958 if (TARGET_KERNEL_BACKCHAIN)
6959 t = build (PLUS_EXPR, TREE_TYPE (sav), t,
6960 build_int_cst (NULL_TREE,
6961 -(RETURN_REGNUM - 2) * UNITS_PER_WORD
6962 - (TARGET_64BIT ? 4 : 2) * 8, -1));
6963 else
6964 t = build (PLUS_EXPR, TREE_TYPE (sav), t,
6965 build_int_cst (NULL_TREE, -RETURN_REGNUM * UNITS_PER_WORD, -1));
6967 t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
6968 TREE_SIDE_EFFECTS (t) = 1;
6969 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6972 /* Implement va_arg by updating the va_list structure
6973 VALIST as required to retrieve an argument of type
6974 TYPE, and returning that argument.
6976 Generates code equivalent to:
6978 if (integral value) {
6979 if (size <= 4 && args.gpr < 5 ||
6980 size > 4 && args.gpr < 4 )
6981 ret = args.reg_save_area[args.gpr+8]
6982 else
6983 ret = *args.overflow_arg_area++;
6984 } else if (float value) {
6985 if (args.fgpr < 2)
6986 ret = args.reg_save_area[args.fpr+64]
6987 else
6988 ret = *args.overflow_arg_area++;
6989 } else if (aggregate value) {
6990 if (args.gpr < 5)
6991 ret = *args.reg_save_area[args.gpr]
6992 else
6993 ret = **args.overflow_arg_area++;
6994 } */
6996 tree
6997 s390_gimplify_va_arg (tree valist, tree type, tree *pre_p,
6998 tree *post_p ATTRIBUTE_UNUSED)
7000 tree f_gpr, f_fpr, f_ovf, f_sav;
7001 tree gpr, fpr, ovf, sav, reg, t, u;
7002 int indirect_p, size, n_reg, sav_ofs, sav_scale, max_reg;
7003 tree lab_false, lab_over, addr;
7005 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
7006 f_fpr = TREE_CHAIN (f_gpr);
7007 f_ovf = TREE_CHAIN (f_fpr);
7008 f_sav = TREE_CHAIN (f_ovf);
7010 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
7011 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
7012 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
7013 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
7014 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
7016 size = int_size_in_bytes (type);
7018 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
7020 if (TARGET_DEBUG_ARG)
7022 fprintf (stderr, "va_arg: aggregate type");
7023 debug_tree (type);
7026 /* Aggregates are passed by reference. */
7027 indirect_p = 1;
7028 reg = gpr;
7029 n_reg = 1;
7030 sav_ofs = (TARGET_KERNEL_BACKCHAIN
7031 ? (TARGET_64BIT ? 4 : 2) * 8 : 2 * UNITS_PER_WORD);
7032 sav_scale = UNITS_PER_WORD;
7033 size = UNITS_PER_WORD;
7034 max_reg = 4;
7036 else if (s390_function_arg_float (TYPE_MODE (type), type))
7038 if (TARGET_DEBUG_ARG)
7040 fprintf (stderr, "va_arg: float type");
7041 debug_tree (type);
7044 /* FP args go in FP registers, if present. */
7045 indirect_p = 0;
7046 reg = fpr;
7047 n_reg = 1;
7048 sav_ofs = TARGET_KERNEL_BACKCHAIN ? 0 : 16 * UNITS_PER_WORD;
7049 sav_scale = 8;
7050 /* TARGET_64BIT has up to 4 parameter in fprs */
7051 max_reg = TARGET_64BIT ? 3 : 1;
7053 else
7055 if (TARGET_DEBUG_ARG)
7057 fprintf (stderr, "va_arg: other type");
7058 debug_tree (type);
7061 /* Otherwise into GP registers. */
7062 indirect_p = 0;
7063 reg = gpr;
7064 n_reg = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
7065 sav_ofs = TARGET_KERNEL_BACKCHAIN ?
7066 (TARGET_64BIT ? 4 : 2) * 8 : 2*UNITS_PER_WORD;
7068 if (size < UNITS_PER_WORD)
7069 sav_ofs += UNITS_PER_WORD - size;
7071 sav_scale = UNITS_PER_WORD;
7072 if (n_reg > 1)
7073 max_reg = 3;
7074 else
7075 max_reg = 4;
7078 /* Pull the value out of the saved registers ... */
7080 lab_false = create_artificial_label ();
7081 lab_over = create_artificial_label ();
7082 addr = create_tmp_var (ptr_type_node, "addr");
7084 t = fold_convert (TREE_TYPE (reg), size_int (max_reg));
7085 t = build2 (GT_EXPR, boolean_type_node, reg, t);
7086 u = build1 (GOTO_EXPR, void_type_node, lab_false);
7087 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
7088 gimplify_and_add (t, pre_p);
7090 t = build2 (PLUS_EXPR, ptr_type_node, sav,
7091 fold_convert (ptr_type_node, size_int (sav_ofs)));
7092 u = build2 (MULT_EXPR, TREE_TYPE (reg), reg,
7093 fold_convert (TREE_TYPE (reg), size_int (sav_scale)));
7094 t = build2 (PLUS_EXPR, ptr_type_node, t, fold_convert (ptr_type_node, u));
7096 t = build2 (MODIFY_EXPR, void_type_node, addr, t);
7097 gimplify_and_add (t, pre_p);
7099 t = build1 (GOTO_EXPR, void_type_node, lab_over);
7100 gimplify_and_add (t, pre_p);
7102 t = build1 (LABEL_EXPR, void_type_node, lab_false);
7103 append_to_statement_list (t, pre_p);
7106 /* ... Otherwise out of the overflow area. */
7108 t = ovf;
7109 if (size < UNITS_PER_WORD)
7110 t = build2 (PLUS_EXPR, ptr_type_node, t,
7111 fold_convert (ptr_type_node, size_int (UNITS_PER_WORD - size)));
7113 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
7115 u = build2 (MODIFY_EXPR, void_type_node, addr, t);
7116 gimplify_and_add (u, pre_p);
7118 t = build2 (PLUS_EXPR, ptr_type_node, t,
7119 fold_convert (ptr_type_node, size_int (size)));
7120 t = build2 (MODIFY_EXPR, ptr_type_node, ovf, t);
7121 gimplify_and_add (t, pre_p);
7123 t = build1 (LABEL_EXPR, void_type_node, lab_over);
7124 append_to_statement_list (t, pre_p);
7127 /* Increment register save count. */
7129 u = build2 (PREINCREMENT_EXPR, TREE_TYPE (reg), reg,
7130 fold_convert (TREE_TYPE (reg), size_int (n_reg)));
7131 gimplify_and_add (u, pre_p);
7133 if (indirect_p)
7135 t = build_pointer_type (build_pointer_type (type));
7136 addr = fold_convert (t, addr);
7137 addr = build_fold_indirect_ref (addr);
7139 else
7141 t = build_pointer_type (type);
7142 addr = fold_convert (t, addr);
7145 return build_fold_indirect_ref (addr);
7149 /* Builtins. */
7151 enum s390_builtin
7153 S390_BUILTIN_THREAD_POINTER,
7154 S390_BUILTIN_SET_THREAD_POINTER,
7156 S390_BUILTIN_max
7159 static unsigned int const code_for_builtin_64[S390_BUILTIN_max] = {
7160 CODE_FOR_get_tp_64,
7161 CODE_FOR_set_tp_64
7164 static unsigned int const code_for_builtin_31[S390_BUILTIN_max] = {
7165 CODE_FOR_get_tp_31,
7166 CODE_FOR_set_tp_31
7169 static void
7170 s390_init_builtins (void)
7172 tree ftype;
7174 ftype = build_function_type (ptr_type_node, void_list_node);
7175 lang_hooks.builtin_function ("__builtin_thread_pointer", ftype,
7176 S390_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
7177 NULL, NULL_TREE);
7179 ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
7180 lang_hooks.builtin_function ("__builtin_set_thread_pointer", ftype,
7181 S390_BUILTIN_SET_THREAD_POINTER, BUILT_IN_MD,
7182 NULL, NULL_TREE);
7185 /* Expand an expression EXP that calls a built-in function,
7186 with result going to TARGET if that's convenient
7187 (and in mode MODE if that's convenient).
7188 SUBTARGET may be used as the target for computing one of EXP's operands.
7189 IGNORE is nonzero if the value is to be ignored. */
7191 static rtx
7192 s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
7193 enum machine_mode mode ATTRIBUTE_UNUSED,
7194 int ignore ATTRIBUTE_UNUSED)
7196 #define MAX_ARGS 2
7198 unsigned int const *code_for_builtin =
7199 TARGET_64BIT ? code_for_builtin_64 : code_for_builtin_31;
7201 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7202 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7203 tree arglist = TREE_OPERAND (exp, 1);
7204 enum insn_code icode;
7205 rtx op[MAX_ARGS], pat;
7206 int arity;
7207 bool nonvoid;
7209 if (fcode >= S390_BUILTIN_max)
7210 internal_error ("bad builtin fcode");
7211 icode = code_for_builtin[fcode];
7212 if (icode == 0)
7213 internal_error ("bad builtin fcode");
7215 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
7217 for (arglist = TREE_OPERAND (exp, 1), arity = 0;
7218 arglist;
7219 arglist = TREE_CHAIN (arglist), arity++)
7221 const struct insn_operand_data *insn_op;
7223 tree arg = TREE_VALUE (arglist);
7224 if (arg == error_mark_node)
7225 return NULL_RTX;
7226 if (arity > MAX_ARGS)
7227 return NULL_RTX;
7229 insn_op = &insn_data[icode].operand[arity + nonvoid];
7231 op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, 0);
7233 if (!(*insn_op->predicate) (op[arity], insn_op->mode))
7234 op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
7237 if (nonvoid)
7239 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7240 if (!target
7241 || GET_MODE (target) != tmode
7242 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
7243 target = gen_reg_rtx (tmode);
7246 switch (arity)
7248 case 0:
7249 pat = GEN_FCN (icode) (target);
7250 break;
7251 case 1:
7252 if (nonvoid)
7253 pat = GEN_FCN (icode) (target, op[0]);
7254 else
7255 pat = GEN_FCN (icode) (op[0]);
7256 break;
7257 case 2:
7258 pat = GEN_FCN (icode) (target, op[0], op[1]);
7259 break;
7260 default:
7261 abort ();
7263 if (!pat)
7264 return NULL_RTX;
7265 emit_insn (pat);
7267 if (nonvoid)
7268 return target;
7269 else
7270 return const0_rtx;
7274 /* Output assembly code for the trampoline template to
7275 stdio stream FILE.
7277 On S/390, we use gpr 1 internally in the trampoline code;
7278 gpr 0 is used to hold the static chain. */
7280 void
7281 s390_trampoline_template (FILE *file)
7283 if (TARGET_64BIT)
7285 fprintf (file, "larl\t%s,0f\n", reg_names[1]);
7286 fprintf (file, "lg\t%s,0(%s)\n", reg_names[0], reg_names[1]);
7287 fprintf (file, "lg\t%s,8(%s)\n", reg_names[1], reg_names[1]);
7288 fprintf (file, "br\t%s\n", reg_names[1]);
7289 fprintf (file, "0:\t.quad\t0\n");
7290 fprintf (file, ".quad\t0\n");
7292 else
7294 fprintf (file, "basr\t%s,0\n", reg_names[1]);
7295 fprintf (file, "l\t%s,10(%s)\n", reg_names[0], reg_names[1]);
7296 fprintf (file, "l\t%s,14(%s)\n", reg_names[1], reg_names[1]);
7297 fprintf (file, "br\t%s\n", reg_names[1]);
7298 fprintf (file, ".long\t0\n");
7299 fprintf (file, ".long\t0\n");
7303 /* Emit RTL insns to initialize the variable parts of a trampoline.
7304 FNADDR is an RTX for the address of the function's pure code.
7305 CXT is an RTX for the static chain value for the function. */
7307 void
7308 s390_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
7310 emit_move_insn (gen_rtx_MEM (Pmode,
7311 memory_address (Pmode,
7312 plus_constant (addr, (TARGET_64BIT ? 20 : 12) ))), cxt);
7313 emit_move_insn (gen_rtx_MEM (Pmode,
7314 memory_address (Pmode,
7315 plus_constant (addr, (TARGET_64BIT ? 28 : 16) ))), fnaddr);
7318 /* Return rtx for 64-bit constant formed from the 32-bit subwords
7319 LOW and HIGH, independent of the host word size. */
7322 s390_gen_rtx_const_DI (int high, int low)
7324 #if HOST_BITS_PER_WIDE_INT >= 64
7325 HOST_WIDE_INT val;
7326 val = (HOST_WIDE_INT)high;
7327 val <<= 32;
7328 val |= (HOST_WIDE_INT)low;
7330 return GEN_INT (val);
7331 #else
7332 #if HOST_BITS_PER_WIDE_INT >= 32
7333 return immed_double_const ((HOST_WIDE_INT)low, (HOST_WIDE_INT)high, DImode);
7334 #else
7335 abort ();
7336 #endif
7337 #endif
7340 /* Output assembler code to FILE to increment profiler label # LABELNO
7341 for profiling a function entry. */
7343 void
7344 s390_function_profiler (FILE *file, int labelno)
7346 rtx op[7];
7348 char label[128];
7349 ASM_GENERATE_INTERNAL_LABEL (label, "LP", labelno);
7351 fprintf (file, "# function profiler \n");
7353 op[0] = gen_rtx_REG (Pmode, RETURN_REGNUM);
7354 op[1] = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
7355 op[1] = gen_rtx_MEM (Pmode, plus_constant (op[1], UNITS_PER_WORD));
7357 op[2] = gen_rtx_REG (Pmode, 1);
7358 op[3] = gen_rtx_SYMBOL_REF (Pmode, label);
7359 SYMBOL_REF_FLAGS (op[3]) = SYMBOL_FLAG_LOCAL;
7361 op[4] = gen_rtx_SYMBOL_REF (Pmode, "_mcount");
7362 if (flag_pic)
7364 op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), UNSPEC_PLT);
7365 op[4] = gen_rtx_CONST (Pmode, op[4]);
7368 if (TARGET_64BIT)
7370 output_asm_insn ("stg\t%0,%1", op);
7371 output_asm_insn ("larl\t%2,%3", op);
7372 output_asm_insn ("brasl\t%0,%4", op);
7373 output_asm_insn ("lg\t%0,%1", op);
7375 else if (!flag_pic)
7377 op[6] = gen_label_rtx ();
7379 output_asm_insn ("st\t%0,%1", op);
7380 output_asm_insn ("bras\t%2,%l6", op);
7381 output_asm_insn (".long\t%4", op);
7382 output_asm_insn (".long\t%3", op);
7383 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
7384 output_asm_insn ("l\t%0,0(%2)", op);
7385 output_asm_insn ("l\t%2,4(%2)", op);
7386 output_asm_insn ("basr\t%0,%0", op);
7387 output_asm_insn ("l\t%0,%1", op);
7389 else
7391 op[5] = gen_label_rtx ();
7392 op[6] = gen_label_rtx ();
7394 output_asm_insn ("st\t%0,%1", op);
7395 output_asm_insn ("bras\t%2,%l6", op);
7396 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[5]));
7397 output_asm_insn (".long\t%4-%l5", op);
7398 output_asm_insn (".long\t%3-%l5", op);
7399 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
7400 output_asm_insn ("lr\t%0,%2", op);
7401 output_asm_insn ("a\t%0,0(%2)", op);
7402 output_asm_insn ("a\t%2,4(%2)", op);
7403 output_asm_insn ("basr\t%0,%0", op);
7404 output_asm_insn ("l\t%0,%1", op);
7408 /* Select section for constant in constant pool. In 32-bit mode,
7409 constants go in the function section; in 64-bit mode in .rodata. */
7411 static void
7412 s390_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED,
7413 rtx x ATTRIBUTE_UNUSED,
7414 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
7416 if (TARGET_CPU_ZARCH)
7417 readonly_data_section ();
7418 else
7419 function_section (current_function_decl);
7422 /* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
7423 into its SYMBOL_REF_FLAGS. */
7425 static void
7426 s390_encode_section_info (tree decl, rtx rtl, int first)
7428 default_encode_section_info (decl, rtl, first);
7430 /* If a variable has a forced alignment to < 2 bytes, mark it with
7431 SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL operand. */
7432 if (TREE_CODE (decl) == VAR_DECL
7433 && DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) < 16)
7434 SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_ALIGN1;
7437 /* Output thunk to FILE that implements a C++ virtual function call (with
7438 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
7439 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
7440 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
7441 relative to the resulting this pointer. */
7443 static void
7444 s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
7445 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
7446 tree function)
7448 rtx op[10];
7449 int nonlocal = 0;
7451 /* Operand 0 is the target function. */
7452 op[0] = XEXP (DECL_RTL (function), 0);
7453 if (flag_pic && !SYMBOL_REF_LOCAL_P (op[0]))
7455 nonlocal = 1;
7456 op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]),
7457 TARGET_64BIT ? UNSPEC_PLT : UNSPEC_GOT);
7458 op[0] = gen_rtx_CONST (Pmode, op[0]);
7461 /* Operand 1 is the 'this' pointer. */
7462 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
7463 op[1] = gen_rtx_REG (Pmode, 3);
7464 else
7465 op[1] = gen_rtx_REG (Pmode, 2);
7467 /* Operand 2 is the delta. */
7468 op[2] = GEN_INT (delta);
7470 /* Operand 3 is the vcall_offset. */
7471 op[3] = GEN_INT (vcall_offset);
7473 /* Operand 4 is the temporary register. */
7474 op[4] = gen_rtx_REG (Pmode, 1);
7476 /* Operands 5 to 8 can be used as labels. */
7477 op[5] = NULL_RTX;
7478 op[6] = NULL_RTX;
7479 op[7] = NULL_RTX;
7480 op[8] = NULL_RTX;
7482 /* Operand 9 can be used for temporary register. */
7483 op[9] = NULL_RTX;
7485 /* Generate code. */
7486 if (TARGET_64BIT)
7488 /* Setup literal pool pointer if required. */
7489 if ((!DISP_IN_RANGE (delta)
7490 && !CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
7491 || (!DISP_IN_RANGE (vcall_offset)
7492 && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K")))
7494 op[5] = gen_label_rtx ();
7495 output_asm_insn ("larl\t%4,%5", op);
7498 /* Add DELTA to this pointer. */
7499 if (delta)
7501 if (CONST_OK_FOR_CONSTRAINT_P (delta, 'J', "J"))
7502 output_asm_insn ("la\t%1,%2(%1)", op);
7503 else if (DISP_IN_RANGE (delta))
7504 output_asm_insn ("lay\t%1,%2(%1)", op);
7505 else if (CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
7506 output_asm_insn ("aghi\t%1,%2", op);
7507 else
7509 op[6] = gen_label_rtx ();
7510 output_asm_insn ("agf\t%1,%6-%5(%4)", op);
7514 /* Perform vcall adjustment. */
7515 if (vcall_offset)
7517 if (DISP_IN_RANGE (vcall_offset))
7519 output_asm_insn ("lg\t%4,0(%1)", op);
7520 output_asm_insn ("ag\t%1,%3(%4)", op);
7522 else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K"))
7524 output_asm_insn ("lghi\t%4,%3", op);
7525 output_asm_insn ("ag\t%4,0(%1)", op);
7526 output_asm_insn ("ag\t%1,0(%4)", op);
7528 else
7530 op[7] = gen_label_rtx ();
7531 output_asm_insn ("llgf\t%4,%7-%5(%4)", op);
7532 output_asm_insn ("ag\t%4,0(%1)", op);
7533 output_asm_insn ("ag\t%1,0(%4)", op);
7537 /* Jump to target. */
7538 output_asm_insn ("jg\t%0", op);
7540 /* Output literal pool if required. */
7541 if (op[5])
7543 output_asm_insn (".align\t4", op);
7544 targetm.asm_out.internal_label (file, "L",
7545 CODE_LABEL_NUMBER (op[5]));
7547 if (op[6])
7549 targetm.asm_out.internal_label (file, "L",
7550 CODE_LABEL_NUMBER (op[6]));
7551 output_asm_insn (".long\t%2", op);
7553 if (op[7])
7555 targetm.asm_out.internal_label (file, "L",
7556 CODE_LABEL_NUMBER (op[7]));
7557 output_asm_insn (".long\t%3", op);
7560 else
7562 /* Setup base pointer if required. */
7563 if (!vcall_offset
7564 || (!DISP_IN_RANGE (delta)
7565 && !CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
7566 || (!DISP_IN_RANGE (delta)
7567 && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K")))
7569 op[5] = gen_label_rtx ();
7570 output_asm_insn ("basr\t%4,0", op);
7571 targetm.asm_out.internal_label (file, "L",
7572 CODE_LABEL_NUMBER (op[5]));
7575 /* Add DELTA to this pointer. */
7576 if (delta)
7578 if (CONST_OK_FOR_CONSTRAINT_P (delta, 'J', "J"))
7579 output_asm_insn ("la\t%1,%2(%1)", op);
7580 else if (DISP_IN_RANGE (delta))
7581 output_asm_insn ("lay\t%1,%2(%1)", op);
7582 else if (CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
7583 output_asm_insn ("ahi\t%1,%2", op);
7584 else
7586 op[6] = gen_label_rtx ();
7587 output_asm_insn ("a\t%1,%6-%5(%4)", op);
7591 /* Perform vcall adjustment. */
7592 if (vcall_offset)
7594 if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'J', "J"))
7596 output_asm_insn ("lg\t%4,0(%1)", op);
7597 output_asm_insn ("a\t%1,%3(%4)", op);
7599 else if (DISP_IN_RANGE (vcall_offset))
7601 output_asm_insn ("lg\t%4,0(%1)", op);
7602 output_asm_insn ("ay\t%1,%3(%4)", op);
7604 else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K"))
7606 output_asm_insn ("lhi\t%4,%3", op);
7607 output_asm_insn ("a\t%4,0(%1)", op);
7608 output_asm_insn ("a\t%1,0(%4)", op);
7610 else
7612 op[7] = gen_label_rtx ();
7613 output_asm_insn ("l\t%4,%7-%5(%4)", op);
7614 output_asm_insn ("a\t%4,0(%1)", op);
7615 output_asm_insn ("a\t%1,0(%4)", op);
7618 /* We had to clobber the base pointer register.
7619 Re-setup the base pointer (with a different base). */
7620 op[5] = gen_label_rtx ();
7621 output_asm_insn ("basr\t%4,0", op);
7622 targetm.asm_out.internal_label (file, "L",
7623 CODE_LABEL_NUMBER (op[5]));
7626 /* Jump to target. */
7627 op[8] = gen_label_rtx ();
7629 if (!flag_pic)
7630 output_asm_insn ("l\t%4,%8-%5(%4)", op);
7631 else if (!nonlocal)
7632 output_asm_insn ("a\t%4,%8-%5(%4)", op);
7633 /* We cannot call through .plt, since .plt requires %r12 loaded. */
7634 else if (flag_pic == 1)
7636 output_asm_insn ("a\t%4,%8-%5(%4)", op);
7637 output_asm_insn ("l\t%4,%0(%4)", op);
7639 else if (flag_pic == 2)
7641 op[9] = gen_rtx_REG (Pmode, 0);
7642 output_asm_insn ("l\t%9,%8-4-%5(%4)", op);
7643 output_asm_insn ("a\t%4,%8-%5(%4)", op);
7644 output_asm_insn ("ar\t%4,%9", op);
7645 output_asm_insn ("l\t%4,0(%4)", op);
7648 output_asm_insn ("br\t%4", op);
7650 /* Output literal pool. */
7651 output_asm_insn (".align\t4", op);
7653 if (nonlocal && flag_pic == 2)
7654 output_asm_insn (".long\t%0", op);
7655 if (nonlocal)
7657 op[0] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
7658 SYMBOL_REF_FLAGS (op[0]) = SYMBOL_FLAG_LOCAL;
7661 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[8]));
7662 if (!flag_pic)
7663 output_asm_insn (".long\t%0", op);
7664 else
7665 output_asm_insn (".long\t%0-%5", op);
7667 if (op[6])
7669 targetm.asm_out.internal_label (file, "L",
7670 CODE_LABEL_NUMBER (op[6]));
7671 output_asm_insn (".long\t%2", op);
7673 if (op[7])
7675 targetm.asm_out.internal_label (file, "L",
7676 CODE_LABEL_NUMBER (op[7]));
7677 output_asm_insn (".long\t%3", op);
7682 bool
7683 s390_valid_pointer_mode (enum machine_mode mode)
7685 return (mode == SImode || (TARGET_64BIT && mode == DImode));
7688 /* How to allocate a 'struct machine_function'. */
7690 static struct machine_function *
7691 s390_init_machine_status (void)
7693 return ggc_alloc_cleared (sizeof (struct machine_function));
7696 /* Checks whether the given ARGUMENT_LIST would use a caller
7697 saved register. This is used to decide whether sibling call
7698 optimization could be performed on the respective function
7699 call. */
7701 static bool
7702 s390_call_saved_register_used (tree argument_list)
7704 CUMULATIVE_ARGS cum;
7705 tree parameter;
7706 enum machine_mode mode;
7707 tree type;
7708 rtx parm_rtx;
7709 int reg;
7711 INIT_CUMULATIVE_ARGS (cum, NULL, NULL, 0, 0);
7713 while (argument_list)
7715 parameter = TREE_VALUE (argument_list);
7716 argument_list = TREE_CHAIN (argument_list);
7718 if (!parameter)
7719 abort();
7721 /* For an undeclared variable passed as parameter we will get
7722 an ERROR_MARK node here. */
7723 if (TREE_CODE (parameter) == ERROR_MARK)
7724 return true;
7726 if (! (type = TREE_TYPE (parameter)))
7727 abort();
7729 if (! (mode = TYPE_MODE (TREE_TYPE (parameter))))
7730 abort();
7732 if (pass_by_reference (&cum, mode, type, true))
7734 mode = Pmode;
7735 type = build_pointer_type (type);
7738 parm_rtx = s390_function_arg (&cum, mode, type, 0);
7740 s390_function_arg_advance (&cum, mode, type, 0);
7742 if (parm_rtx && REG_P (parm_rtx))
7744 for (reg = 0;
7745 reg < HARD_REGNO_NREGS (REGNO (parm_rtx), GET_MODE (parm_rtx));
7746 reg++)
7747 if (! call_used_regs[reg + REGNO (parm_rtx)])
7748 return true;
7751 return false;
7754 /* Return true if the given call expression can be
7755 turned into a sibling call.
7756 DECL holds the declaration of the function to be called whereas
7757 EXP is the call expression itself. */
7759 static bool
7760 s390_function_ok_for_sibcall (tree decl, tree exp)
7762 /* The TPF epilogue uses register 1. */
7763 if (TARGET_TPF_PROFILING)
7764 return false;
7766 /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
7767 which would have to be restored before the sibcall. */
7768 if (!TARGET_64BIT && flag_pic && decl && TREE_PUBLIC (decl))
7769 return false;
7771 /* Register 6 on s390 is available as an argument register but unfortunately
7772 "caller saved". This makes functions needing this register for arguments
7773 not suitable for sibcalls. */
7774 if (TREE_OPERAND (exp, 1)
7775 && s390_call_saved_register_used (TREE_OPERAND (exp, 1)))
7776 return false;
7778 return true;
7781 /* This function is used by the call expanders of the machine description.
7782 It emits the call insn itself together with the necessary operations
7783 to adjust the target address and returns the emitted insn.
7784 ADDR_LOCATION is the target address rtx
7785 TLS_CALL the location of the thread-local symbol
7786 RESULT_REG the register where the result of the call should be stored
7787 RETADDR_REG the register where the return address should be stored
7788 If this parameter is NULL_RTX the call is considered
7789 to be a sibling call. */
7792 s390_emit_call (rtx addr_location, rtx tls_call, rtx result_reg,
7793 rtx retaddr_reg)
7795 bool plt_call = false;
7796 rtx insn;
7797 rtx call;
7798 rtx clobber;
7799 rtvec vec;
7801 /* Direct function calls need special treatment. */
7802 if (GET_CODE (addr_location) == SYMBOL_REF)
7804 /* When calling a global routine in PIC mode, we must
7805 replace the symbol itself with the PLT stub. */
7806 if (flag_pic && !SYMBOL_REF_LOCAL_P (addr_location))
7808 addr_location = gen_rtx_UNSPEC (Pmode,
7809 gen_rtvec (1, addr_location),
7810 UNSPEC_PLT);
7811 addr_location = gen_rtx_CONST (Pmode, addr_location);
7812 plt_call = true;
7815 /* Unless we can use the bras(l) insn, force the
7816 routine address into a register. */
7817 if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
7819 if (flag_pic)
7820 addr_location = legitimize_pic_address (addr_location, 0);
7821 else
7822 addr_location = force_reg (Pmode, addr_location);
7826 /* If it is already an indirect call or the code above moved the
7827 SYMBOL_REF to somewhere else make sure the address can be found in
7828 register 1. */
7829 if (retaddr_reg == NULL_RTX
7830 && GET_CODE (addr_location) != SYMBOL_REF
7831 && !plt_call)
7833 emit_move_insn (gen_rtx_REG (Pmode, SIBCALL_REGNUM), addr_location);
7834 addr_location = gen_rtx_REG (Pmode, SIBCALL_REGNUM);
7837 addr_location = gen_rtx_MEM (QImode, addr_location);
7838 call = gen_rtx_CALL (VOIDmode, addr_location, const0_rtx);
7840 if (result_reg != NULL_RTX)
7841 call = gen_rtx_SET (VOIDmode, result_reg, call);
7843 if (retaddr_reg != NULL_RTX)
7845 clobber = gen_rtx_CLOBBER (VOIDmode, retaddr_reg);
7847 if (tls_call != NULL_RTX)
7848 vec = gen_rtvec (3, call, clobber,
7849 gen_rtx_USE (VOIDmode, tls_call));
7850 else
7851 vec = gen_rtvec (2, call, clobber);
7853 call = gen_rtx_PARALLEL (VOIDmode, vec);
7856 insn = emit_call_insn (call);
7858 /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
7859 if ((!TARGET_64BIT && plt_call) || tls_call != NULL_RTX)
7861 /* s390_function_ok_for_sibcall should
7862 have denied sibcalls in this case. */
7863 if (retaddr_reg == NULL_RTX)
7864 abort ();
7866 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
7868 return insn;
7871 /* Implement CONDITIONAL_REGISTER_USAGE. */
7873 void
7874 s390_conditional_register_usage (void)
7876 int i;
7878 if (flag_pic)
7880 fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
7881 call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
7883 if (TARGET_CPU_ZARCH)
7885 fixed_regs[RETURN_REGNUM] = 0;
7886 call_used_regs[RETURN_REGNUM] = 0;
7888 if (TARGET_64BIT)
7890 for (i = 24; i < 32; i++)
7891 call_used_regs[i] = call_really_used_regs[i] = 0;
7893 else
7895 for (i = 18; i < 20; i++)
7896 call_used_regs[i] = call_really_used_regs[i] = 0;
7901 #include "gt-s390.h"