2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / gcc / config / s390 / s390.c
blobb79a26759097631208a28e1c45b9714453d30028
1 /* Subroutines used for code generation on IBM S/390 and zSeries
2 Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
3 Contributed by Hartmut Penner (hpenner@de.ibm.com) and
4 Ulrich Weigand (uweigand@de.ibm.com).
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "tree.h"
29 #include "tm_p.h"
30 #include "regs.h"
31 #include "hard-reg-set.h"
32 #include "real.h"
33 #include "insn-config.h"
34 #include "conditions.h"
35 #include "output.h"
36 #include "insn-attr.h"
37 #include "flags.h"
38 #include "except.h"
39 #include "function.h"
40 #include "recog.h"
41 #include "expr.h"
42 #include "reload.h"
43 #include "toplev.h"
44 #include "basic-block.h"
45 #include "integrate.h"
46 #include "ggc.h"
47 #include "target.h"
48 #include "target-def.h"
49 #include "debug.h"
50 #include "langhooks.h"
51 #include "optabs.h"
53 /* Machine-specific symbol_ref flags. */
54 #define SYMBOL_FLAG_ALIGN1 (SYMBOL_FLAG_MACH_DEP << 0)
57 static bool s390_assemble_integer (rtx, unsigned int, int);
58 static void s390_select_rtx_section (enum machine_mode, rtx,
59 unsigned HOST_WIDE_INT);
60 static void s390_encode_section_info (tree, rtx, int);
61 static bool s390_cannot_force_const_mem (rtx);
62 static rtx s390_delegitimize_address (rtx);
63 static bool s390_return_in_memory (tree, tree);
64 static void s390_init_builtins (void);
65 static rtx s390_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
66 static void s390_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
67 HOST_WIDE_INT, tree);
68 static enum attr_type s390_safe_attr_type (rtx);
70 static int s390_adjust_cost (rtx, rtx, rtx, int);
71 static int s390_adjust_priority (rtx, int);
72 static int s390_issue_rate (void);
73 static int s390_use_dfa_pipeline_interface (void);
74 static int s390_first_cycle_multipass_dfa_lookahead (void);
75 static int s390_sched_reorder2 (FILE *, int, rtx *, int *, int);
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);
82 #undef TARGET_ASM_ALIGNED_HI_OP
83 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
84 #undef TARGET_ASM_ALIGNED_DI_OP
85 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
86 #undef TARGET_ASM_INTEGER
87 #define TARGET_ASM_INTEGER s390_assemble_integer
89 #undef TARGET_ASM_OPEN_PAREN
90 #define TARGET_ASM_OPEN_PAREN ""
92 #undef TARGET_ASM_CLOSE_PAREN
93 #define TARGET_ASM_CLOSE_PAREN ""
95 #undef TARGET_ASM_SELECT_RTX_SECTION
96 #define TARGET_ASM_SELECT_RTX_SECTION s390_select_rtx_section
98 #undef TARGET_ENCODE_SECTION_INFO
99 #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
101 #ifdef HAVE_AS_TLS
102 #undef TARGET_HAVE_TLS
103 #define TARGET_HAVE_TLS true
104 #endif
105 #undef TARGET_CANNOT_FORCE_CONST_MEM
106 #define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
108 #undef TARGET_DELEGITIMIZE_ADDRESS
109 #define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
111 #undef TARGET_RETURN_IN_MEMORY
112 #define TARGET_RETURN_IN_MEMORY s390_return_in_memory
114 #undef TARGET_INIT_BUILTINS
115 #define TARGET_INIT_BUILTINS s390_init_builtins
116 #undef TARGET_EXPAND_BUILTIN
117 #define TARGET_EXPAND_BUILTIN s390_expand_builtin
119 #undef TARGET_ASM_OUTPUT_MI_THUNK
120 #define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
121 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
122 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
124 #undef TARGET_SCHED_ADJUST_COST
125 #define TARGET_SCHED_ADJUST_COST s390_adjust_cost
126 #undef TARGET_SCHED_ADJUST_PRIORITY
127 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
128 #undef TARGET_SCHED_ISSUE_RATE
129 #define TARGET_SCHED_ISSUE_RATE s390_issue_rate
130 #undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
131 #define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE s390_use_dfa_pipeline_interface
132 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
133 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
134 #undef TARGET_SCHED_REORDER2
135 #define TARGET_SCHED_REORDER2 s390_sched_reorder2
137 #undef TARGET_RTX_COSTS
138 #define TARGET_RTX_COSTS s390_rtx_costs
139 #undef TARGET_ADDRESS_COST
140 #define TARGET_ADDRESS_COST s390_address_cost
142 #undef TARGET_MACHINE_DEPENDENT_REORG
143 #define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
145 #undef TARGET_VALID_POINTER_MODE
146 #define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
148 #undef TARGET_BUILD_BUILTIN_VA_LIST
149 #define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
151 struct gcc_target targetm = TARGET_INITIALIZER;
153 extern int reload_completed;
155 /* The alias set for prologue/epilogue register save/restore. */
156 static int s390_sr_alias_set = 0;
158 /* Save information from a "cmpxx" operation until the branch or scc is
159 emitted. */
160 rtx s390_compare_op0, s390_compare_op1;
162 /* Structure used to hold the components of a S/390 memory
163 address. A legitimate address on S/390 is of the general
164 form
165 base + index + displacement
166 where any of the components is optional.
168 base and index are registers of the class ADDR_REGS,
169 displacement is an unsigned 12-bit immediate constant. */
171 struct s390_address
173 rtx base;
174 rtx indx;
175 rtx disp;
176 int pointer;
179 /* Which cpu are we tuning for. */
180 enum processor_type s390_tune;
181 enum processor_flags s390_tune_flags;
182 /* Which instruction set architecture to use. */
183 enum processor_type s390_arch;
184 enum processor_flags s390_arch_flags;
186 /* Strings to hold which cpu and instruction set architecture to use. */
187 const char *s390_tune_string; /* for -mtune=<xxx> */
188 const char *s390_arch_string; /* for -march=<xxx> */
190 /* Define the structure for the machine field in struct function. */
192 struct machine_function GTY(())
194 /* Set, if some of the fprs 8-15 need to be saved (64 bit abi). */
195 int save_fprs_p;
197 /* Set if return address needs to be saved. */
198 bool save_return_addr_p;
200 /* Number of first and last gpr to be saved, restored. */
201 int first_save_gpr;
202 int first_restore_gpr;
203 int last_save_gpr;
205 /* Size of stack frame. */
206 HOST_WIDE_INT frame_size;
208 /* Some local-dynamic TLS symbol name. */
209 const char *some_ld_name;
212 static int s390_match_ccmode_set (rtx, enum machine_mode);
213 static int s390_branch_condition_mask (rtx);
214 static const char *s390_branch_condition_mnemonic (rtx, int);
215 static int check_mode (rtx, enum machine_mode *);
216 static int general_s_operand (rtx, enum machine_mode, int);
217 static int s390_short_displacement (rtx);
218 static int s390_decompose_address (rtx, struct s390_address *);
219 static rtx get_thread_pointer (void);
220 static rtx legitimize_tls_address (rtx, rtx);
221 static void print_shift_count_operand (FILE *, rtx);
222 static const char *get_some_local_dynamic_name (void);
223 static int get_some_local_dynamic_name_1 (rtx *, void *);
224 static int reg_used_in_mem_p (int, rtx);
225 static int addr_generation_dependency_p (rtx, rtx);
226 static int s390_split_branches (void);
227 static void find_constant_pool_ref (rtx, rtx *);
228 static void replace_constant_pool_ref (rtx *, rtx, rtx);
229 static rtx find_ltrel_base (rtx);
230 static void replace_ltrel_base (rtx *, rtx);
231 static void s390_optimize_prolog (bool);
232 static int find_unused_clobbered_reg (void);
233 static void s390_frame_info (void);
234 static rtx save_fpr (rtx, int, int);
235 static rtx restore_fpr (rtx, int, int);
236 static rtx save_gprs (rtx, int, int, int);
237 static rtx restore_gprs (rtx, int, int, int);
238 static int s390_function_arg_size (enum machine_mode, tree);
239 static bool s390_function_arg_float (enum machine_mode, tree);
240 static struct machine_function * s390_init_machine_status (void);
242 /* Check whether integer displacement is in range. */
243 #define DISP_IN_RANGE(d) \
244 (TARGET_LONG_DISPLACEMENT? ((d) >= -524288 && (d) <= 524287) \
245 : ((d) >= 0 && (d) <= 4095))
247 /* Return true if SET either doesn't set the CC register, or else
248 the source and destination have matching CC modes and that
249 CC mode is at least as constrained as REQ_MODE. */
251 static int
252 s390_match_ccmode_set (rtx set, enum machine_mode req_mode)
254 enum machine_mode set_mode;
256 if (GET_CODE (set) != SET)
257 abort ();
259 if (GET_CODE (SET_DEST (set)) != REG || !CC_REGNO_P (REGNO (SET_DEST (set))))
260 return 1;
262 set_mode = GET_MODE (SET_DEST (set));
263 switch (set_mode)
265 case CCSmode:
266 case CCSRmode:
267 case CCUmode:
268 case CCURmode:
269 case CCLmode:
270 case CCL1mode:
271 case CCL2mode:
272 case CCT1mode:
273 case CCT2mode:
274 case CCT3mode:
275 if (req_mode != set_mode)
276 return 0;
277 break;
279 case CCZmode:
280 if (req_mode != CCSmode && req_mode != CCUmode && req_mode != CCTmode
281 && req_mode != CCSRmode && req_mode != CCURmode)
282 return 0;
283 break;
285 case CCAPmode:
286 case CCANmode:
287 if (req_mode != CCAmode)
288 return 0;
289 break;
291 default:
292 abort ();
295 return (GET_MODE (SET_SRC (set)) == set_mode);
298 /* Return true if every SET in INSN that sets the CC register
299 has source and destination with matching CC modes and that
300 CC mode is at least as constrained as REQ_MODE.
301 If REQ_MODE is VOIDmode, always return false. */
304 s390_match_ccmode (rtx insn, enum machine_mode req_mode)
306 int i;
308 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
309 if (req_mode == VOIDmode)
310 return 0;
312 if (GET_CODE (PATTERN (insn)) == SET)
313 return s390_match_ccmode_set (PATTERN (insn), req_mode);
315 if (GET_CODE (PATTERN (insn)) == PARALLEL)
316 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
318 rtx set = XVECEXP (PATTERN (insn), 0, i);
319 if (GET_CODE (set) == SET)
320 if (!s390_match_ccmode_set (set, req_mode))
321 return 0;
324 return 1;
327 /* If a test-under-mask instruction can be used to implement
328 (compare (and ... OP1) OP2), return the CC mode required
329 to do that. Otherwise, return VOIDmode.
330 MIXED is true if the instruction can distinguish between
331 CC1 and CC2 for mixed selected bits (TMxx), it is false
332 if the instruction cannot (TM). */
334 enum machine_mode
335 s390_tm_ccmode (rtx op1, rtx op2, int mixed)
337 int bit0, bit1;
339 /* ??? Fixme: should work on CONST_DOUBLE as well. */
340 if (GET_CODE (op1) != CONST_INT || GET_CODE (op2) != CONST_INT)
341 return VOIDmode;
343 /* Selected bits all zero: CC0. */
344 if (INTVAL (op2) == 0)
345 return CCTmode;
347 /* Selected bits all one: CC3. */
348 if (INTVAL (op2) == INTVAL (op1))
349 return CCT3mode;
351 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. */
352 if (mixed)
354 bit1 = exact_log2 (INTVAL (op2));
355 bit0 = exact_log2 (INTVAL (op1) ^ INTVAL (op2));
356 if (bit0 != -1 && bit1 != -1)
357 return bit0 > bit1 ? CCT1mode : CCT2mode;
360 return VOIDmode;
363 /* Given a comparison code OP (EQ, NE, etc.) and the operands
364 OP0 and OP1 of a COMPARE, return the mode to be used for the
365 comparison. */
367 enum machine_mode
368 s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
370 switch (code)
372 case EQ:
373 case NE:
374 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
375 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0, 1)), 'K', "K"))
376 return CCAPmode;
377 if ((GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
378 || GET_CODE (op1) == NEG)
379 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
380 return CCLmode;
382 if (GET_CODE (op0) == AND)
384 /* Check whether we can potentially do it via TM. */
385 enum machine_mode ccmode;
386 ccmode = s390_tm_ccmode (XEXP (op0, 1), op1, 1);
387 if (ccmode != VOIDmode)
389 /* Relax CCTmode to CCZmode to allow fall-back to AND
390 if that turns out to be beneficial. */
391 return ccmode == CCTmode ? CCZmode : ccmode;
395 if (register_operand (op0, HImode)
396 && GET_CODE (op1) == CONST_INT
397 && (INTVAL (op1) == -1 || INTVAL (op1) == 65535))
398 return CCT3mode;
399 if (register_operand (op0, QImode)
400 && GET_CODE (op1) == CONST_INT
401 && (INTVAL (op1) == -1 || INTVAL (op1) == 255))
402 return CCT3mode;
404 return CCZmode;
406 case LE:
407 case LT:
408 case GE:
409 case GT:
410 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
411 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0, 1)), 'K', "K"))
413 if (INTVAL (XEXP((op0), 1)) < 0)
414 return CCANmode;
415 else
416 return CCAPmode;
418 case UNORDERED:
419 case ORDERED:
420 case UNEQ:
421 case UNLE:
422 case UNLT:
423 case UNGE:
424 case UNGT:
425 case LTGT:
426 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
427 && GET_CODE (op1) != CONST_INT)
428 return CCSRmode;
429 return CCSmode;
431 case LTU:
432 case GEU:
433 if (GET_CODE (op0) == PLUS
434 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
435 return CCL1mode;
437 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
438 && GET_CODE (op1) != CONST_INT)
439 return CCURmode;
440 return CCUmode;
442 case LEU:
443 case GTU:
444 if (GET_CODE (op0) == MINUS
445 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
446 return CCL2mode;
448 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
449 && GET_CODE (op1) != CONST_INT)
450 return CCURmode;
451 return CCUmode;
453 default:
454 abort ();
458 /* Return nonzero if OP is a valid comparison operator
459 for an ALC condition in mode MODE. */
462 s390_alc_comparison (rtx op, enum machine_mode mode)
464 if (mode != VOIDmode && mode != GET_MODE (op))
465 return 0;
467 if (GET_RTX_CLASS (GET_CODE (op)) != '<')
468 return 0;
470 if (GET_CODE (XEXP (op, 0)) != REG
471 || REGNO (XEXP (op, 0)) != CC_REGNUM
472 || XEXP (op, 1) != const0_rtx)
473 return 0;
475 switch (GET_MODE (XEXP (op, 0)))
477 case CCL1mode:
478 return GET_CODE (op) == LTU;
480 case CCL2mode:
481 return GET_CODE (op) == LEU;
483 case CCUmode:
484 return GET_CODE (op) == GTU;
486 case CCURmode:
487 return GET_CODE (op) == LTU;
489 case CCSmode:
490 return GET_CODE (op) == UNGT;
492 case CCSRmode:
493 return GET_CODE (op) == UNLT;
495 default:
496 return 0;
500 /* Return nonzero if OP is a valid comparison operator
501 for an SLB condition in mode MODE. */
504 s390_slb_comparison (rtx op, enum machine_mode mode)
506 if (mode != VOIDmode && mode != GET_MODE (op))
507 return 0;
509 if (GET_RTX_CLASS (GET_CODE (op)) != '<')
510 return 0;
512 if (GET_CODE (XEXP (op, 0)) != REG
513 || REGNO (XEXP (op, 0)) != CC_REGNUM
514 || XEXP (op, 1) != const0_rtx)
515 return 0;
517 switch (GET_MODE (XEXP (op, 0)))
519 case CCL1mode:
520 return GET_CODE (op) == GEU;
522 case CCL2mode:
523 return GET_CODE (op) == GTU;
525 case CCUmode:
526 return GET_CODE (op) == LEU;
528 case CCURmode:
529 return GET_CODE (op) == GEU;
531 case CCSmode:
532 return GET_CODE (op) == LE;
534 case CCSRmode:
535 return GET_CODE (op) == GE;
537 default:
538 return 0;
542 /* Return branch condition mask to implement a branch
543 specified by CODE. */
545 static int
546 s390_branch_condition_mask (rtx code)
548 const int CC0 = 1 << 3;
549 const int CC1 = 1 << 2;
550 const int CC2 = 1 << 1;
551 const int CC3 = 1 << 0;
553 if (GET_CODE (XEXP (code, 0)) != REG
554 || REGNO (XEXP (code, 0)) != CC_REGNUM
555 || XEXP (code, 1) != const0_rtx)
556 abort ();
558 switch (GET_MODE (XEXP (code, 0)))
560 case CCZmode:
561 switch (GET_CODE (code))
563 case EQ: return CC0;
564 case NE: return CC1 | CC2 | CC3;
565 default:
566 abort ();
568 break;
570 case CCT1mode:
571 switch (GET_CODE (code))
573 case EQ: return CC1;
574 case NE: return CC0 | CC2 | CC3;
575 default:
576 abort ();
578 break;
580 case CCT2mode:
581 switch (GET_CODE (code))
583 case EQ: return CC2;
584 case NE: return CC0 | CC1 | CC3;
585 default:
586 abort ();
588 break;
590 case CCT3mode:
591 switch (GET_CODE (code))
593 case EQ: return CC3;
594 case NE: return CC0 | CC1 | CC2;
595 default:
596 abort ();
598 break;
600 case CCLmode:
601 switch (GET_CODE (code))
603 case EQ: return CC0 | CC2;
604 case NE: return CC1 | CC3;
605 default:
606 abort ();
608 break;
610 case CCL1mode:
611 switch (GET_CODE (code))
613 case LTU: return CC2 | CC3; /* carry */
614 case GEU: return CC0 | CC1; /* no carry */
615 default:
616 abort ();
618 break;
620 case CCL2mode:
621 switch (GET_CODE (code))
623 case GTU: return CC0 | CC1; /* borrow */
624 case LEU: return CC2 | CC3; /* no borrow */
625 default:
626 abort ();
628 break;
630 case CCUmode:
631 switch (GET_CODE (code))
633 case EQ: return CC0;
634 case NE: return CC1 | CC2 | CC3;
635 case LTU: return CC1;
636 case GTU: return CC2;
637 case LEU: return CC0 | CC1;
638 case GEU: return CC0 | CC2;
639 default:
640 abort ();
642 break;
644 case CCURmode:
645 switch (GET_CODE (code))
647 case EQ: return CC0;
648 case NE: return CC2 | CC1 | CC3;
649 case LTU: return CC2;
650 case GTU: return CC1;
651 case LEU: return CC0 | CC2;
652 case GEU: return CC0 | CC1;
653 default:
654 abort ();
656 break;
658 case CCAPmode:
659 switch (GET_CODE (code))
661 case EQ: return CC0;
662 case NE: return CC1 | CC2 | CC3;
663 case LT: return CC1 | CC3;
664 case GT: return CC2;
665 case LE: return CC0 | CC1 | CC3;
666 case GE: return CC0 | CC2;
667 default:
668 abort ();
670 break;
672 case CCANmode:
673 switch (GET_CODE (code))
675 case EQ: return CC0;
676 case NE: return CC1 | CC2 | CC3;
677 case LT: return CC1;
678 case GT: return CC2 | CC3;
679 case LE: return CC0 | CC1;
680 case GE: return CC0 | CC2 | CC3;
681 default:
682 abort ();
684 break;
686 case CCSmode:
687 switch (GET_CODE (code))
689 case EQ: return CC0;
690 case NE: return CC1 | CC2 | CC3;
691 case LT: return CC1;
692 case GT: return CC2;
693 case LE: return CC0 | CC1;
694 case GE: return CC0 | CC2;
695 case UNORDERED: return CC3;
696 case ORDERED: return CC0 | CC1 | CC2;
697 case UNEQ: return CC0 | CC3;
698 case UNLT: return CC1 | CC3;
699 case UNGT: return CC2 | CC3;
700 case UNLE: return CC0 | CC1 | CC3;
701 case UNGE: return CC0 | CC2 | CC3;
702 case LTGT: return CC1 | CC2;
703 default:
704 abort ();
706 break;
708 case CCSRmode:
709 switch (GET_CODE (code))
711 case EQ: return CC0;
712 case NE: return CC2 | CC1 | CC3;
713 case LT: return CC2;
714 case GT: return CC1;
715 case LE: return CC0 | CC2;
716 case GE: return CC0 | CC1;
717 case UNORDERED: return CC3;
718 case ORDERED: return CC0 | CC2 | CC1;
719 case UNEQ: return CC0 | CC3;
720 case UNLT: return CC2 | CC3;
721 case UNGT: return CC1 | CC3;
722 case UNLE: return CC0 | CC2 | CC3;
723 case UNGE: return CC0 | CC1 | CC3;
724 case LTGT: return CC2 | CC1;
725 default:
726 abort ();
728 break;
730 default:
731 abort ();
735 /* If INV is false, return assembler mnemonic string to implement
736 a branch specified by CODE. If INV is true, return mnemonic
737 for the corresponding inverted branch. */
739 static const char *
740 s390_branch_condition_mnemonic (rtx code, int inv)
742 static const char *const mnemonic[16] =
744 NULL, "o", "h", "nle",
745 "l", "nhe", "lh", "ne",
746 "e", "nlh", "he", "nl",
747 "le", "nh", "no", NULL
750 int mask = s390_branch_condition_mask (code);
752 if (inv)
753 mask ^= 15;
755 if (mask < 1 || mask > 14)
756 abort ();
758 return mnemonic[mask];
761 /* Return the part of op which has a value different from def.
762 The size of the part is determined by mode.
763 Use this function only if you already know that op really
764 contains such a part. */
766 unsigned HOST_WIDE_INT
767 s390_extract_part (rtx op, enum machine_mode mode, int def)
769 unsigned HOST_WIDE_INT value = 0;
770 int max_parts = HOST_BITS_PER_WIDE_INT / GET_MODE_BITSIZE (mode);
771 int part_bits = GET_MODE_BITSIZE (mode);
772 unsigned HOST_WIDE_INT part_mask = (1 << part_bits) - 1;
773 int i;
775 for (i = 0; i < max_parts; i++)
777 if (i == 0)
778 value = (unsigned HOST_WIDE_INT) INTVAL (op);
779 else
780 value >>= part_bits;
782 if ((value & part_mask) != (def & part_mask))
783 return value & part_mask;
786 abort ();
789 /* If OP is an integer constant of mode MODE with exactly one
790 part of mode PART_MODE unequal to DEF, return the number of that
791 part. Otherwise, return -1. */
794 s390_single_part (rtx op,
795 enum machine_mode mode,
796 enum machine_mode part_mode,
797 int def)
799 unsigned HOST_WIDE_INT value = 0;
800 int n_parts = GET_MODE_SIZE (mode) / GET_MODE_SIZE (part_mode);
801 unsigned HOST_WIDE_INT part_mask = (1 << GET_MODE_BITSIZE (part_mode)) - 1;
802 int i, part = -1;
804 if (GET_CODE (op) != CONST_INT)
805 return -1;
807 for (i = 0; i < n_parts; i++)
809 if (i == 0)
810 value = (unsigned HOST_WIDE_INT) INTVAL (op);
811 else
812 value >>= GET_MODE_BITSIZE (part_mode);
814 if ((value & part_mask) != (def & part_mask))
816 if (part != -1)
817 return -1;
818 else
819 part = i;
822 return part == -1 ? -1 : n_parts - 1 - part;
825 /* Check whether we can (and want to) split a double-word
826 move in mode MODE from SRC to DST into two single-word
827 moves, moving the subword FIRST_SUBWORD first. */
829 bool
830 s390_split_ok_p (rtx dst, rtx src, enum machine_mode mode, int first_subword)
832 /* Floating point registers cannot be split. */
833 if (FP_REG_P (src) || FP_REG_P (dst))
834 return false;
836 /* We don't need to split if operands are directly accessible. */
837 if (s_operand (src, mode) || s_operand (dst, mode))
838 return false;
840 /* Non-offsettable memory references cannot be split. */
841 if ((GET_CODE (src) == MEM && !offsettable_memref_p (src))
842 || (GET_CODE (dst) == MEM && !offsettable_memref_p (dst)))
843 return false;
845 /* Moving the first subword must not clobber a register
846 needed to move the second subword. */
847 if (register_operand (dst, mode))
849 rtx subreg = operand_subword (dst, first_subword, 0, mode);
850 if (reg_overlap_mentioned_p (subreg, src))
851 return false;
854 return true;
858 /* Change optimizations to be performed, depending on the
859 optimization level.
861 LEVEL is the optimization level specified; 2 if `-O2' is
862 specified, 1 if `-O' is specified, and 0 if neither is specified.
864 SIZE is nonzero if `-Os' is specified and zero otherwise. */
866 void
867 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
869 /* ??? There are apparently still problems with -fcaller-saves. */
870 flag_caller_saves = 0;
872 /* By default, always emit DWARF-2 unwind info. This allows debugging
873 without maintaining a stack frame back-chain. */
874 flag_asynchronous_unwind_tables = 1;
877 void
878 override_options (void)
880 int i;
881 static struct pta
883 const char *const name; /* processor name or nickname. */
884 const enum processor_type processor;
885 const enum processor_flags flags;
887 const processor_alias_table[] =
889 {"g5", PROCESSOR_9672_G5, PF_IEEE_FLOAT},
890 {"g6", PROCESSOR_9672_G6, PF_IEEE_FLOAT},
891 {"z900", PROCESSOR_2064_Z900, PF_IEEE_FLOAT | PF_ZARCH},
892 {"z990", PROCESSOR_2084_Z990, PF_IEEE_FLOAT | PF_ZARCH
893 | PF_LONG_DISPLACEMENT},
896 int const pta_size = ARRAY_SIZE (processor_alias_table);
898 /* Acquire a unique set number for our register saves and restores. */
899 s390_sr_alias_set = new_alias_set ();
901 /* Set up function hooks. */
902 init_machine_status = s390_init_machine_status;
904 /* Architecture mode defaults according to ABI. */
905 if (!(target_flags_explicit & MASK_ZARCH))
907 if (TARGET_64BIT)
908 target_flags |= MASK_ZARCH;
909 else
910 target_flags &= ~MASK_ZARCH;
913 /* Determine processor architectural level. */
914 if (!s390_arch_string)
915 s390_arch_string = TARGET_ZARCH? "z900" : "g5";
917 for (i = 0; i < pta_size; i++)
918 if (! strcmp (s390_arch_string, processor_alias_table[i].name))
920 s390_arch = processor_alias_table[i].processor;
921 s390_arch_flags = processor_alias_table[i].flags;
922 break;
924 if (i == pta_size)
925 error ("Unknown cpu used in -march=%s.", s390_arch_string);
927 /* Determine processor to tune for. */
928 if (!s390_tune_string)
930 s390_tune = s390_arch;
931 s390_tune_flags = s390_arch_flags;
932 s390_tune_string = s390_arch_string;
934 else
936 for (i = 0; i < pta_size; i++)
937 if (! strcmp (s390_tune_string, processor_alias_table[i].name))
939 s390_tune = processor_alias_table[i].processor;
940 s390_tune_flags = processor_alias_table[i].flags;
941 break;
943 if (i == pta_size)
944 error ("Unknown cpu used in -mtune=%s.", s390_tune_string);
947 /* Sanity checks. */
948 if (TARGET_ZARCH && !(s390_arch_flags & PF_ZARCH))
949 error ("z/Architecture mode not supported on %s.", s390_arch_string);
950 if (TARGET_64BIT && !TARGET_ZARCH)
951 error ("64-bit ABI not supported in ESA/390 mode.");
954 /* Map for smallest class containing reg regno. */
956 const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
957 { GENERAL_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
958 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
959 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
960 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
961 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
962 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
963 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
964 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
965 ADDR_REGS, NO_REGS, ADDR_REGS
968 /* Return attribute type of insn. */
970 static enum attr_type
971 s390_safe_attr_type (rtx insn)
973 if (recog_memoized (insn) >= 0)
974 return get_attr_type (insn);
975 else
976 return TYPE_NONE;
979 /* Return true if OP a (const_int 0) operand.
980 OP is the current operation.
981 MODE is the current operation mode. */
984 const0_operand (register rtx op, enum machine_mode mode)
986 return op == CONST0_RTX (mode);
989 /* Return true if OP is constant.
990 OP is the current operation.
991 MODE is the current operation mode. */
994 consttable_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
996 return CONSTANT_P (op);
999 /* Return true if the mode of operand OP matches MODE.
1000 If MODE is set to VOIDmode, set it to the mode of OP. */
1002 static int
1003 check_mode (register rtx op, enum machine_mode *mode)
1005 if (*mode == VOIDmode)
1006 *mode = GET_MODE (op);
1007 else
1009 if (GET_MODE (op) != VOIDmode && GET_MODE (op) != *mode)
1010 return 0;
1012 return 1;
1015 /* Return true if OP a valid operand for the LARL instruction.
1016 OP is the current operation.
1017 MODE is the current operation mode. */
1020 larl_operand (register rtx op, enum machine_mode mode)
1022 if (! check_mode (op, &mode))
1023 return 0;
1025 /* Allow labels and local symbols. */
1026 if (GET_CODE (op) == LABEL_REF)
1027 return 1;
1028 if (GET_CODE (op) == SYMBOL_REF)
1029 return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0
1030 && SYMBOL_REF_TLS_MODEL (op) == 0
1031 && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
1033 /* Everything else must have a CONST, so strip it. */
1034 if (GET_CODE (op) != CONST)
1035 return 0;
1036 op = XEXP (op, 0);
1038 /* Allow adding *even* in-range constants. */
1039 if (GET_CODE (op) == PLUS)
1041 if (GET_CODE (XEXP (op, 1)) != CONST_INT
1042 || (INTVAL (XEXP (op, 1)) & 1) != 0)
1043 return 0;
1044 #if HOST_BITS_PER_WIDE_INT > 32
1045 if (INTVAL (XEXP (op, 1)) >= (HOST_WIDE_INT)1 << 32
1046 || INTVAL (XEXP (op, 1)) < -((HOST_WIDE_INT)1 << 32))
1047 return 0;
1048 #endif
1049 op = XEXP (op, 0);
1052 /* Labels and local symbols allowed here as well. */
1053 if (GET_CODE (op) == LABEL_REF)
1054 return 1;
1055 if (GET_CODE (op) == SYMBOL_REF)
1056 return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0
1057 && SYMBOL_REF_TLS_MODEL (op) == 0
1058 && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
1060 /* Now we must have a @GOTENT offset or @PLT stub
1061 or an @INDNTPOFF TLS offset. */
1062 if (GET_CODE (op) == UNSPEC
1063 && XINT (op, 1) == UNSPEC_GOTENT)
1064 return 1;
1065 if (GET_CODE (op) == UNSPEC
1066 && XINT (op, 1) == UNSPEC_PLT)
1067 return 1;
1068 if (GET_CODE (op) == UNSPEC
1069 && XINT (op, 1) == UNSPEC_INDNTPOFF)
1070 return 1;
1072 return 0;
1075 /* Helper routine to implement s_operand and s_imm_operand.
1076 OP is the current operation.
1077 MODE is the current operation mode.
1078 ALLOW_IMMEDIATE specifies whether immediate operands should
1079 be accepted or not. */
1081 static int
1082 general_s_operand (register rtx op, enum machine_mode mode,
1083 int allow_immediate)
1085 struct s390_address addr;
1087 /* Call general_operand first, so that we don't have to
1088 check for many special cases. */
1089 if (!general_operand (op, mode))
1090 return 0;
1092 /* Just like memory_operand, allow (subreg (mem ...))
1093 after reload. */
1094 if (reload_completed
1095 && GET_CODE (op) == SUBREG
1096 && GET_CODE (SUBREG_REG (op)) == MEM)
1097 op = SUBREG_REG (op);
1099 switch (GET_CODE (op))
1101 /* Constants are OK as s-operand if ALLOW_IMMEDIATE
1102 is true and we are still before reload. */
1103 case CONST_INT:
1104 case CONST_DOUBLE:
1105 if (!allow_immediate || reload_completed)
1106 return 0;
1107 return 1;
1109 /* Memory operands are OK unless they already use an
1110 index register. */
1111 case MEM:
1112 if (GET_CODE (XEXP (op, 0)) == ADDRESSOF)
1113 return 1;
1114 if (!s390_decompose_address (XEXP (op, 0), &addr))
1115 return 0;
1116 if (addr.indx)
1117 return 0;
1118 /* Do not allow literal pool references unless ALLOW_IMMEDIATE
1119 is true. This prevents compares between two literal pool
1120 entries from being accepted. */
1121 if (!allow_immediate
1122 && addr.base && REGNO (addr.base) == BASE_REGISTER)
1123 return 0;
1124 return 1;
1126 default:
1127 break;
1130 return 0;
1133 /* Return true if OP is a valid S-type operand.
1134 OP is the current operation.
1135 MODE is the current operation mode. */
1138 s_operand (register rtx op, enum machine_mode mode)
1140 return general_s_operand (op, mode, 0);
1143 /* Return true if OP is a valid S-type operand or an immediate
1144 operand that can be addressed as S-type operand by forcing
1145 it into the literal pool.
1146 OP is the current operation.
1147 MODE is the current operation mode. */
1150 s_imm_operand (register rtx op, enum machine_mode mode)
1152 return general_s_operand (op, mode, 1);
1155 /* Return true if OP a valid shift count operand.
1156 OP is the current operation.
1157 MODE is the current operation mode. */
1160 shift_count_operand (rtx op, enum machine_mode mode)
1162 HOST_WIDE_INT offset = 0;
1164 if (! check_mode (op, &mode))
1165 return 0;
1167 /* We can have an integer constant, an address register,
1168 or a sum of the two. Note that reload already checks
1169 that any register present is an address register, so
1170 we just check for any register here. */
1171 if (GET_CODE (op) == CONST_INT)
1173 offset = INTVAL (op);
1174 op = NULL_RTX;
1176 if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
1178 offset = INTVAL (XEXP (op, 1));
1179 op = XEXP (op, 0);
1181 while (op && GET_CODE (op) == SUBREG)
1182 op = SUBREG_REG (op);
1183 if (op && GET_CODE (op) != REG)
1184 return 0;
1186 /* Unfortunately we have to reject constants that are invalid
1187 for an address, or else reload will get confused. */
1188 if (!DISP_IN_RANGE (offset))
1189 return 0;
1191 return 1;
1194 /* Return true if DISP is a valid short displacement. */
1196 static int
1197 s390_short_displacement (rtx disp)
1199 /* No displacement is OK. */
1200 if (!disp)
1201 return 1;
1203 /* Integer displacement in range. */
1204 if (GET_CODE (disp) == CONST_INT)
1205 return INTVAL (disp) >= 0 && INTVAL (disp) < 4096;
1207 /* GOT offset is not OK, the GOT can be large. */
1208 if (GET_CODE (disp) == CONST
1209 && GET_CODE (XEXP (disp, 0)) == UNSPEC
1210 && XINT (XEXP (disp, 0), 1) == UNSPEC_GOT)
1211 return 0;
1213 /* All other symbolic constants are literal pool references,
1214 which are OK as the literal pool must be small. */
1215 if (GET_CODE (disp) == CONST)
1216 return 1;
1218 return 0;
1221 /* Return true if OP is a valid operand for a C constraint. */
1224 s390_extra_constraint_str (rtx op, int c, const char * str)
1226 struct s390_address addr;
1228 if (c != str[0])
1229 abort ();
1231 switch (c)
1233 case 'Q':
1234 if (GET_CODE (op) != MEM)
1235 return 0;
1236 if (!s390_decompose_address (XEXP (op, 0), &addr))
1237 return 0;
1238 if (addr.indx)
1239 return 0;
1241 if (TARGET_LONG_DISPLACEMENT)
1243 if (!s390_short_displacement (addr.disp))
1244 return 0;
1246 break;
1248 case 'R':
1249 if (GET_CODE (op) != MEM)
1250 return 0;
1252 if (TARGET_LONG_DISPLACEMENT)
1254 if (!s390_decompose_address (XEXP (op, 0), &addr))
1255 return 0;
1256 if (!s390_short_displacement (addr.disp))
1257 return 0;
1259 break;
1261 case 'S':
1262 if (!TARGET_LONG_DISPLACEMENT)
1263 return 0;
1264 if (GET_CODE (op) != MEM)
1265 return 0;
1266 if (!s390_decompose_address (XEXP (op, 0), &addr))
1267 return 0;
1268 if (addr.indx)
1269 return 0;
1270 if (s390_short_displacement (addr.disp))
1271 return 0;
1272 break;
1274 case 'T':
1275 if (!TARGET_LONG_DISPLACEMENT)
1276 return 0;
1277 if (GET_CODE (op) != MEM)
1278 return 0;
1279 /* Any invalid address here will be fixed up by reload,
1280 so accept it for the most generic constraint. */
1281 if (s390_decompose_address (XEXP (op, 0), &addr)
1282 && s390_short_displacement (addr.disp))
1283 return 0;
1284 break;
1286 case 'U':
1287 if (TARGET_LONG_DISPLACEMENT)
1289 if (!s390_decompose_address (op, &addr))
1290 return 0;
1291 if (!s390_short_displacement (addr.disp))
1292 return 0;
1294 break;
1296 case 'W':
1297 if (!TARGET_LONG_DISPLACEMENT)
1298 return 0;
1299 /* Any invalid address here will be fixed up by reload,
1300 so accept it for the most generic constraint. */
1301 if (s390_decompose_address (op, &addr)
1302 && s390_short_displacement (addr.disp))
1303 return 0;
1304 break;
1306 case 'Y':
1307 return shift_count_operand (op, VOIDmode);
1309 default:
1310 return 0;
1313 return 1;
1316 /* Return true if VALUE matches the constraint STR. */
1319 s390_const_ok_for_constraint_p (HOST_WIDE_INT value,
1320 int c,
1321 const char * str)
1323 enum machine_mode mode, part_mode;
1324 int def;
1325 unsigned char part;
1327 if (c != str[0])
1328 abort ();
1330 switch (str[0])
1332 case 'I':
1333 return (unsigned int)value < 256;
1335 case 'J':
1336 return (unsigned int)value < 4096;
1338 case 'K':
1339 return value >= -32768 && value < 32768;
1341 case 'L':
1342 return (TARGET_LONG_DISPLACEMENT ?
1343 (value >= -524288 && value <= 524287)
1344 : (value >= 0 && value <= 4095));
1345 case 'M':
1346 return value == 2147483647;
1348 case 'N':
1349 part = str[1] - '0';
1351 switch (str[2])
1353 case 'H': part_mode = HImode; break;
1354 case 'Q': part_mode = QImode; break;
1355 default: return 0;
1358 switch (str[3])
1360 case 'H': mode = HImode; break;
1361 case 'S': mode = SImode; break;
1362 case 'D': mode = DImode; break;
1363 default: return 0;
1366 switch (str[4])
1368 case '0': def = 0; break;
1369 case 'F': def = -1; break;
1370 default: return 0;
1373 if (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (part_mode))
1374 return 0;
1376 if (s390_single_part (GEN_INT (value), mode, part_mode, def) != part)
1377 return 0;
1379 break;
1381 default:
1382 return 0;
1385 return 1;
1388 /* Compute a (partial) cost for rtx X. Return true if the complete
1389 cost has been computed, and false if subexpressions should be
1390 scanned. In either case, *TOTAL contains the cost result. */
1392 static bool
1393 s390_rtx_costs (rtx x, int code, int outer_code, int *total)
1395 switch (code)
1397 case CONST:
1398 if (GET_CODE (XEXP (x, 0)) == MINUS
1399 && GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
1400 *total = 1000;
1401 else
1402 *total = 0;
1403 return true;
1405 case CONST_INT:
1406 /* Force_const_mem does not work out of reload, because the
1407 saveable_obstack is set to reload_obstack, which does not
1408 live long enough. Because of this we cannot use force_const_mem
1409 in addsi3. This leads to problems with gen_add2_insn with a
1410 constant greater than a short. Because of that we give an
1411 addition of greater constants a cost of 3 (reload1.c 10096). */
1412 /* ??? saveable_obstack no longer exists. */
1413 if (outer_code == PLUS
1414 && (INTVAL (x) > 32767 || INTVAL (x) < -32768))
1415 *total = COSTS_N_INSNS (3);
1416 else
1417 *total = 0;
1418 return true;
1420 case LABEL_REF:
1421 case SYMBOL_REF:
1422 case CONST_DOUBLE:
1423 *total = 0;
1424 return true;
1426 case ASHIFT:
1427 case ASHIFTRT:
1428 case LSHIFTRT:
1429 case PLUS:
1430 case AND:
1431 case IOR:
1432 case XOR:
1433 case MINUS:
1434 case NEG:
1435 case NOT:
1436 *total = COSTS_N_INSNS (1);
1437 return true;
1439 case MULT:
1440 if (GET_MODE (XEXP (x, 0)) == DImode)
1441 *total = COSTS_N_INSNS (40);
1442 else
1443 *total = COSTS_N_INSNS (7);
1444 return true;
1446 case DIV:
1447 case UDIV:
1448 case MOD:
1449 case UMOD:
1450 *total = COSTS_N_INSNS (33);
1451 return true;
1453 default:
1454 return false;
1458 /* Return the cost of an address rtx ADDR. */
1460 static int
1461 s390_address_cost (rtx addr)
1463 struct s390_address ad;
1464 if (!s390_decompose_address (addr, &ad))
1465 return 1000;
1467 return ad.indx? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
1470 /* Return true if OP is a valid operand for the BRAS instruction.
1471 OP is the current operation.
1472 MODE is the current operation mode. */
1475 bras_sym_operand (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1477 register enum rtx_code code = GET_CODE (op);
1479 /* Allow SYMBOL_REFs. */
1480 if (code == SYMBOL_REF)
1481 return 1;
1483 /* Allow @PLT stubs. */
1484 if (code == CONST
1485 && GET_CODE (XEXP (op, 0)) == UNSPEC
1486 && XINT (XEXP (op, 0), 1) == UNSPEC_PLT)
1487 return 1;
1488 return 0;
1491 /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
1492 otherwise return 0. */
1495 tls_symbolic_operand (register rtx op)
1497 if (GET_CODE (op) != SYMBOL_REF)
1498 return 0;
1499 return SYMBOL_REF_TLS_MODEL (op);
1502 /* Return true if OP is a load multiple operation. It is known to be a
1503 PARALLEL and the first section will be tested.
1504 OP is the current operation.
1505 MODE is the current operation mode. */
1508 load_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1510 enum machine_mode elt_mode;
1511 int count = XVECLEN (op, 0);
1512 unsigned int dest_regno;
1513 rtx src_addr;
1514 int i, off;
1517 /* Perform a quick check so we don't blow up below. */
1518 if (count <= 1
1519 || GET_CODE (XVECEXP (op, 0, 0)) != SET
1520 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
1521 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
1522 return 0;
1524 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
1525 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
1526 elt_mode = GET_MODE (SET_DEST (XVECEXP (op, 0, 0)));
1528 /* Check, is base, or base + displacement. */
1530 if (GET_CODE (src_addr) == REG)
1531 off = 0;
1532 else if (GET_CODE (src_addr) == PLUS
1533 && GET_CODE (XEXP (src_addr, 0)) == REG
1534 && GET_CODE (XEXP (src_addr, 1)) == CONST_INT)
1536 off = INTVAL (XEXP (src_addr, 1));
1537 src_addr = XEXP (src_addr, 0);
1539 else
1540 return 0;
1542 if (src_addr == frame_pointer_rtx || src_addr == arg_pointer_rtx)
1543 return 0;
1545 for (i = 1; i < count; i++)
1547 rtx elt = XVECEXP (op, 0, i);
1549 if (GET_CODE (elt) != SET
1550 || GET_CODE (SET_DEST (elt)) != REG
1551 || GET_MODE (SET_DEST (elt)) != elt_mode
1552 || REGNO (SET_DEST (elt)) != dest_regno + i
1553 || GET_CODE (SET_SRC (elt)) != MEM
1554 || GET_MODE (SET_SRC (elt)) != elt_mode
1555 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
1556 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
1557 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
1558 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1))
1559 != off + i * GET_MODE_SIZE (elt_mode))
1560 return 0;
1563 return 1;
1566 /* Return true if OP is a store multiple operation. It is known to be a
1567 PARALLEL and the first section will be tested.
1568 OP is the current operation.
1569 MODE is the current operation mode. */
1572 store_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1574 enum machine_mode elt_mode;
1575 int count = XVECLEN (op, 0);
1576 unsigned int src_regno;
1577 rtx dest_addr;
1578 int i, off;
1580 /* Perform a quick check so we don't blow up below. */
1581 if (count <= 1
1582 || GET_CODE (XVECEXP (op, 0, 0)) != SET
1583 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
1584 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
1585 return 0;
1587 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
1588 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
1589 elt_mode = GET_MODE (SET_SRC (XVECEXP (op, 0, 0)));
1591 /* Check, is base, or base + displacement. */
1593 if (GET_CODE (dest_addr) == REG)
1594 off = 0;
1595 else if (GET_CODE (dest_addr) == PLUS
1596 && GET_CODE (XEXP (dest_addr, 0)) == REG
1597 && GET_CODE (XEXP (dest_addr, 1)) == CONST_INT)
1599 off = INTVAL (XEXP (dest_addr, 1));
1600 dest_addr = XEXP (dest_addr, 0);
1602 else
1603 return 0;
1605 if (dest_addr == frame_pointer_rtx || dest_addr == arg_pointer_rtx)
1606 return 0;
1608 for (i = 1; i < count; i++)
1610 rtx elt = XVECEXP (op, 0, i);
1612 if (GET_CODE (elt) != SET
1613 || GET_CODE (SET_SRC (elt)) != REG
1614 || GET_MODE (SET_SRC (elt)) != elt_mode
1615 || REGNO (SET_SRC (elt)) != src_regno + i
1616 || GET_CODE (SET_DEST (elt)) != MEM
1617 || GET_MODE (SET_DEST (elt)) != elt_mode
1618 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
1619 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
1620 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
1621 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1))
1622 != off + i * GET_MODE_SIZE (elt_mode))
1623 return 0;
1625 return 1;
1629 /* Return true if OP contains a symbol reference */
1632 symbolic_reference_mentioned_p (rtx op)
1634 register const char *fmt;
1635 register int i;
1637 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
1638 return 1;
1640 fmt = GET_RTX_FORMAT (GET_CODE (op));
1641 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
1643 if (fmt[i] == 'E')
1645 register int j;
1647 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
1648 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
1649 return 1;
1652 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
1653 return 1;
1656 return 0;
1659 /* Return true if OP contains a reference to a thread-local symbol. */
1662 tls_symbolic_reference_mentioned_p (rtx op)
1664 register const char *fmt;
1665 register int i;
1667 if (GET_CODE (op) == SYMBOL_REF)
1668 return tls_symbolic_operand (op);
1670 fmt = GET_RTX_FORMAT (GET_CODE (op));
1671 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
1673 if (fmt[i] == 'E')
1675 register int j;
1677 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
1678 if (tls_symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
1679 return 1;
1682 else if (fmt[i] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op, i)))
1683 return 1;
1686 return 0;
1690 /* Return true if OP is a legitimate general operand when
1691 generating PIC code. It is given that flag_pic is on
1692 and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
1695 legitimate_pic_operand_p (register rtx op)
1697 /* Accept all non-symbolic constants. */
1698 if (!SYMBOLIC_CONST (op))
1699 return 1;
1701 /* Reject everything else; must be handled
1702 via emit_symbolic_move. */
1703 return 0;
1706 /* Returns true if the constant value OP is a legitimate general operand.
1707 It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
1710 legitimate_constant_p (register rtx op)
1712 /* Accept all non-symbolic constants. */
1713 if (!SYMBOLIC_CONST (op))
1714 return 1;
1716 /* Accept immediate LARL operands. */
1717 if (TARGET_CPU_ZARCH && larl_operand (op, VOIDmode))
1718 return 1;
1720 /* Thread-local symbols are never legal constants. This is
1721 so that emit_call knows that computing such addresses
1722 might require a function call. */
1723 if (TLS_SYMBOLIC_CONST (op))
1724 return 0;
1726 /* In the PIC case, symbolic constants must *not* be
1727 forced into the literal pool. We accept them here,
1728 so that they will be handled by emit_symbolic_move. */
1729 if (flag_pic)
1730 return 1;
1732 /* All remaining non-PIC symbolic constants are
1733 forced into the literal pool. */
1734 return 0;
1737 /* Determine if it's legal to put X into the constant pool. This
1738 is not possible if X contains the address of a symbol that is
1739 not constant (TLS) or not known at final link time (PIC). */
1741 static bool
1742 s390_cannot_force_const_mem (rtx x)
1744 switch (GET_CODE (x))
1746 case CONST_INT:
1747 case CONST_DOUBLE:
1748 /* Accept all non-symbolic constants. */
1749 return false;
1751 case LABEL_REF:
1752 /* Labels are OK iff we are non-PIC. */
1753 return flag_pic != 0;
1755 case SYMBOL_REF:
1756 /* 'Naked' TLS symbol references are never OK,
1757 non-TLS symbols are OK iff we are non-PIC. */
1758 if (tls_symbolic_operand (x))
1759 return true;
1760 else
1761 return flag_pic != 0;
1763 case CONST:
1764 return s390_cannot_force_const_mem (XEXP (x, 0));
1765 case PLUS:
1766 case MINUS:
1767 return s390_cannot_force_const_mem (XEXP (x, 0))
1768 || s390_cannot_force_const_mem (XEXP (x, 1));
1770 case UNSPEC:
1771 switch (XINT (x, 1))
1773 /* Only lt-relative or GOT-relative UNSPECs are OK. */
1774 case UNSPEC_LTREL_OFFSET:
1775 case UNSPEC_GOT:
1776 case UNSPEC_GOTOFF:
1777 case UNSPEC_PLTOFF:
1778 case UNSPEC_TLSGD:
1779 case UNSPEC_TLSLDM:
1780 case UNSPEC_NTPOFF:
1781 case UNSPEC_DTPOFF:
1782 case UNSPEC_GOTNTPOFF:
1783 case UNSPEC_INDNTPOFF:
1784 return false;
1786 default:
1787 return true;
1789 break;
1791 default:
1792 abort ();
1796 /* Returns true if the constant value OP is a legitimate general
1797 operand during and after reload. The difference to
1798 legitimate_constant_p is that this function will not accept
1799 a constant that would need to be forced to the literal pool
1800 before it can be used as operand. */
1803 legitimate_reload_constant_p (register rtx op)
1805 /* Accept la(y) operands. */
1806 if (GET_CODE (op) == CONST_INT
1807 && DISP_IN_RANGE (INTVAL (op)))
1808 return 1;
1810 /* Accept l(g)hi operands. */
1811 if (GET_CODE (op) == CONST_INT
1812 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'K', "K"))
1813 return 1;
1815 /* Accept lliXX operands. */
1816 if (TARGET_ZARCH
1817 && s390_single_part (op, DImode, HImode, 0) >= 0)
1818 return 1;
1820 /* Accept larl operands. */
1821 if (TARGET_CPU_ZARCH
1822 && larl_operand (op, VOIDmode))
1823 return 1;
1825 /* Everything else cannot be handled without reload. */
1826 return 0;
1829 /* Given an rtx OP being reloaded into a reg required to be in class CLASS,
1830 return the class of reg to actually use. */
1832 enum reg_class
1833 s390_preferred_reload_class (rtx op, enum reg_class class)
1835 /* This can happen if a floating point constant is being
1836 reloaded into an integer register. Leave well alone. */
1837 if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT
1838 && class != FP_REGS)
1839 return class;
1841 switch (GET_CODE (op))
1843 /* Constants we cannot reload must be forced into the
1844 literal pool. */
1846 case CONST_DOUBLE:
1847 case CONST_INT:
1848 if (legitimate_reload_constant_p (op))
1849 return class;
1850 else
1851 return NO_REGS;
1853 /* If a symbolic constant or a PLUS is reloaded,
1854 it is most likely being used as an address, so
1855 prefer ADDR_REGS. If 'class' is not a superset
1856 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
1857 case PLUS:
1858 case LABEL_REF:
1859 case SYMBOL_REF:
1860 case CONST:
1861 if (reg_class_subset_p (ADDR_REGS, class))
1862 return ADDR_REGS;
1863 else
1864 return NO_REGS;
1866 default:
1867 break;
1870 return class;
1873 /* Return the register class of a scratch register needed to
1874 load IN into a register of class CLASS in MODE.
1876 We need a temporary when loading a PLUS expression which
1877 is not a legitimate operand of the LOAD ADDRESS instruction. */
1879 enum reg_class
1880 s390_secondary_input_reload_class (enum reg_class class ATTRIBUTE_UNUSED,
1881 enum machine_mode mode, rtx in)
1883 if (s390_plus_operand (in, mode))
1884 return ADDR_REGS;
1886 return NO_REGS;
1889 /* Return the register class of a scratch register needed to
1890 store a register of class CLASS in MODE into OUT:
1892 We need a temporary when storing a double-word to a
1893 non-offsettable memory address. */
1895 enum reg_class
1896 s390_secondary_output_reload_class (enum reg_class class,
1897 enum machine_mode mode, rtx out)
1899 if ((TARGET_64BIT ? mode == TImode
1900 : (mode == DImode || mode == DFmode))
1901 && reg_classes_intersect_p (GENERAL_REGS, class)
1902 && GET_CODE (out) == MEM
1903 && !offsettable_memref_p (out)
1904 && !s_operand (out, VOIDmode))
1905 return ADDR_REGS;
1907 return NO_REGS;
1910 /* Return true if OP is a PLUS that is not a legitimate
1911 operand for the LA instruction.
1912 OP is the current operation.
1913 MODE is the current operation mode. */
1916 s390_plus_operand (register rtx op, enum machine_mode mode)
1918 if (!check_mode (op, &mode) || mode != Pmode)
1919 return FALSE;
1921 if (GET_CODE (op) != PLUS)
1922 return FALSE;
1924 if (legitimate_la_operand_p (op))
1925 return FALSE;
1927 return TRUE;
1930 /* Generate code to load SRC, which is PLUS that is not a
1931 legitimate operand for the LA instruction, into TARGET.
1932 SCRATCH may be used as scratch register. */
1934 void
1935 s390_expand_plus_operand (register rtx target, register rtx src,
1936 register rtx scratch)
1938 rtx sum1, sum2;
1939 struct s390_address ad;
1941 /* src must be a PLUS; get its two operands. */
1942 if (GET_CODE (src) != PLUS || GET_MODE (src) != Pmode)
1943 abort ();
1945 /* Check if any of the two operands is already scheduled
1946 for replacement by reload. This can happen e.g. when
1947 float registers occur in an address. */
1948 sum1 = find_replacement (&XEXP (src, 0));
1949 sum2 = find_replacement (&XEXP (src, 1));
1950 src = gen_rtx_PLUS (Pmode, sum1, sum2);
1952 /* If the address is already strictly valid, there's nothing to do. */
1953 if (!s390_decompose_address (src, &ad)
1954 || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
1955 || (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
1957 /* Otherwise, one of the operands cannot be an address register;
1958 we reload its value into the scratch register. */
1959 if (true_regnum (sum1) < 1 || true_regnum (sum1) > 15)
1961 emit_move_insn (scratch, sum1);
1962 sum1 = scratch;
1964 if (true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
1966 emit_move_insn (scratch, sum2);
1967 sum2 = scratch;
1970 /* According to the way these invalid addresses are generated
1971 in reload.c, it should never happen (at least on s390) that
1972 *neither* of the PLUS components, after find_replacements
1973 was applied, is an address register. */
1974 if (sum1 == scratch && sum2 == scratch)
1976 debug_rtx (src);
1977 abort ();
1980 src = gen_rtx_PLUS (Pmode, sum1, sum2);
1983 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
1984 is only ever performed on addresses, so we can mark the
1985 sum as legitimate for LA in any case. */
1986 s390_load_address (target, src);
1990 /* Decompose a RTL expression ADDR for a memory address into
1991 its components, returned in OUT.
1993 Returns 0 if ADDR is not a valid memory address, nonzero
1994 otherwise. If OUT is NULL, don't return the components,
1995 but check for validity only.
1997 Note: Only addresses in canonical form are recognized.
1998 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
1999 canonical form so that they will be recognized. */
2001 static int
2002 s390_decompose_address (register rtx addr, struct s390_address *out)
2004 rtx base = NULL_RTX;
2005 rtx indx = NULL_RTX;
2006 rtx disp = NULL_RTX;
2007 int pointer = FALSE;
2008 int base_ptr = FALSE;
2009 int indx_ptr = FALSE;
2011 /* Decompose address into base + index + displacement. */
2013 if (GET_CODE (addr) == REG || GET_CODE (addr) == UNSPEC)
2014 base = addr;
2016 else if (GET_CODE (addr) == PLUS)
2018 rtx op0 = XEXP (addr, 0);
2019 rtx op1 = XEXP (addr, 1);
2020 enum rtx_code code0 = GET_CODE (op0);
2021 enum rtx_code code1 = GET_CODE (op1);
2023 if (code0 == REG || code0 == UNSPEC)
2025 if (code1 == REG || code1 == UNSPEC)
2027 indx = op0; /* index + base */
2028 base = op1;
2031 else
2033 base = op0; /* base + displacement */
2034 disp = op1;
2038 else if (code0 == PLUS)
2040 indx = XEXP (op0, 0); /* index + base + disp */
2041 base = XEXP (op0, 1);
2042 disp = op1;
2045 else
2047 return FALSE;
2051 else
2052 disp = addr; /* displacement */
2055 /* Validate base register. */
2056 if (base)
2058 if (GET_CODE (base) == UNSPEC)
2060 if (XVECLEN (base, 0) != 1 || XINT (base, 1) != UNSPEC_LTREL_BASE)
2061 return FALSE;
2062 base = gen_rtx_REG (Pmode, BASE_REGISTER);
2065 if (GET_CODE (base) != REG || GET_MODE (base) != Pmode)
2066 return FALSE;
2068 if (REGNO (base) == BASE_REGISTER
2069 || REGNO (base) == STACK_POINTER_REGNUM
2070 || REGNO (base) == FRAME_POINTER_REGNUM
2071 || ((reload_completed || reload_in_progress)
2072 && frame_pointer_needed
2073 && REGNO (base) == HARD_FRAME_POINTER_REGNUM)
2074 || REGNO (base) == ARG_POINTER_REGNUM
2075 || (REGNO (base) >= FIRST_VIRTUAL_REGISTER
2076 && REGNO (base) <= LAST_VIRTUAL_REGISTER)
2077 || (flag_pic
2078 && REGNO (base) == PIC_OFFSET_TABLE_REGNUM))
2079 pointer = base_ptr = TRUE;
2082 /* Validate index register. */
2083 if (indx)
2085 if (GET_CODE (indx) == UNSPEC)
2087 if (XVECLEN (indx, 0) != 1 || XINT (indx, 1) != UNSPEC_LTREL_BASE)
2088 return FALSE;
2089 indx = gen_rtx_REG (Pmode, BASE_REGISTER);
2092 if (GET_CODE (indx) != REG || GET_MODE (indx) != Pmode)
2093 return FALSE;
2095 if (REGNO (indx) == BASE_REGISTER
2096 || REGNO (indx) == STACK_POINTER_REGNUM
2097 || REGNO (indx) == FRAME_POINTER_REGNUM
2098 || ((reload_completed || reload_in_progress)
2099 && frame_pointer_needed
2100 && REGNO (indx) == HARD_FRAME_POINTER_REGNUM)
2101 || REGNO (indx) == ARG_POINTER_REGNUM
2102 || (REGNO (indx) >= FIRST_VIRTUAL_REGISTER
2103 && REGNO (indx) <= LAST_VIRTUAL_REGISTER)
2104 || (flag_pic
2105 && REGNO (indx) == PIC_OFFSET_TABLE_REGNUM))
2106 pointer = indx_ptr = TRUE;
2109 /* Prefer to use pointer as base, not index. */
2110 if (base && indx && !base_ptr
2111 && (indx_ptr || (!REG_POINTER (base) && REG_POINTER (indx))))
2113 rtx tmp = base;
2114 base = indx;
2115 indx = tmp;
2118 /* Validate displacement. */
2119 if (disp)
2121 /* Allow integer constant in range. */
2122 if (GET_CODE (disp) == CONST_INT)
2124 /* If the argument pointer is involved, the displacement will change
2125 later anyway as the argument pointer gets eliminated. This could
2126 make a valid displacement invalid, but it is more likely to make
2127 an invalid displacement valid, because we sometimes access the
2128 register save area via negative offsets to the arg pointer.
2129 Thus we don't check the displacement for validity here. If after
2130 elimination the displacement turns out to be invalid after all,
2131 this is fixed up by reload in any case. */
2132 if (base != arg_pointer_rtx && indx != arg_pointer_rtx)
2134 if (!DISP_IN_RANGE (INTVAL (disp)))
2135 return FALSE;
2139 /* In the small-PIC case, the linker converts @GOT
2140 and @GOTNTPOFF offsets to possible displacements. */
2141 else if (GET_CODE (disp) == CONST
2142 && GET_CODE (XEXP (disp, 0)) == UNSPEC
2143 && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOT
2144 || XINT (XEXP (disp, 0), 1) == UNSPEC_GOTNTPOFF))
2146 if (flag_pic != 1)
2147 return FALSE;
2149 pointer = TRUE;
2152 /* Accept chunkfied literal pool symbol references. */
2153 else if (GET_CODE (disp) == CONST
2154 && GET_CODE (XEXP (disp, 0)) == MINUS
2155 && GET_CODE (XEXP (XEXP (disp, 0), 0)) == LABEL_REF
2156 && GET_CODE (XEXP (XEXP (disp, 0), 1)) == LABEL_REF)
2158 pointer = TRUE;
2161 /* Likewise if a constant offset is present. */
2162 else if (GET_CODE (disp) == CONST
2163 && GET_CODE (XEXP (disp, 0)) == PLUS
2164 && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT
2165 && GET_CODE (XEXP (XEXP (disp, 0), 0)) == MINUS
2166 && GET_CODE (XEXP (XEXP (XEXP (disp, 0), 0), 0)) == LABEL_REF
2167 && GET_CODE (XEXP (XEXP (XEXP (disp, 0), 0), 1)) == LABEL_REF)
2169 pointer = TRUE;
2172 /* We can convert literal pool addresses to
2173 displacements by basing them off the base register. */
2174 else
2176 /* In some cases, we can accept an additional
2177 small constant offset. Split these off here. */
2179 unsigned int offset = 0;
2181 if (GET_CODE (disp) == CONST
2182 && GET_CODE (XEXP (disp, 0)) == PLUS
2183 && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT)
2185 offset = INTVAL (XEXP (XEXP (disp, 0), 1));
2186 disp = XEXP (XEXP (disp, 0), 0);
2189 /* Now we must have a literal pool address. */
2190 if (GET_CODE (disp) != SYMBOL_REF
2191 || !CONSTANT_POOL_ADDRESS_P (disp))
2192 return FALSE;
2194 /* If we have an offset, make sure it does not
2195 exceed the size of the constant pool entry. */
2196 if (offset && offset >= GET_MODE_SIZE (get_pool_mode (disp)))
2197 return FALSE;
2199 /* Either base or index must be free to
2200 hold the base register. */
2201 if (base && indx)
2202 return FALSE;
2204 /* Convert the address. */
2205 if (base)
2206 indx = gen_rtx_REG (Pmode, BASE_REGISTER);
2207 else
2208 base = gen_rtx_REG (Pmode, BASE_REGISTER);
2210 disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp),
2211 UNSPEC_LTREL_OFFSET);
2212 disp = gen_rtx_CONST (Pmode, disp);
2214 if (offset)
2215 disp = plus_constant (disp, offset);
2217 pointer = TRUE;
2221 if (!base && !indx)
2222 pointer = TRUE;
2224 if (out)
2226 out->base = base;
2227 out->indx = indx;
2228 out->disp = disp;
2229 out->pointer = pointer;
2232 return TRUE;
2235 /* Return nonzero if ADDR is a valid memory address.
2236 STRICT specifies whether strict register checking applies. */
2239 legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
2240 register rtx addr, int strict)
2242 struct s390_address ad;
2243 if (!s390_decompose_address (addr, &ad))
2244 return FALSE;
2246 if (strict)
2248 if (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
2249 return FALSE;
2250 if (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx))
2251 return FALSE;
2253 else
2255 if (ad.base && !REG_OK_FOR_BASE_NONSTRICT_P (ad.base))
2256 return FALSE;
2257 if (ad.indx && !REG_OK_FOR_INDEX_NONSTRICT_P (ad.indx))
2258 return FALSE;
2261 return TRUE;
2264 /* Return 1 if OP is a valid operand for the LA instruction.
2265 In 31-bit, we need to prove that the result is used as an
2266 address, as LA performs only a 31-bit addition. */
2269 legitimate_la_operand_p (register rtx op)
2271 struct s390_address addr;
2272 if (!s390_decompose_address (op, &addr))
2273 return FALSE;
2275 if (TARGET_64BIT || addr.pointer)
2276 return TRUE;
2278 return FALSE;
2281 /* Return 1 if OP is a valid operand for the LA instruction,
2282 and we prefer to use LA over addition to compute it. */
2285 preferred_la_operand_p (register rtx op)
2287 struct s390_address addr;
2288 if (!s390_decompose_address (op, &addr))
2289 return FALSE;
2291 if (!TARGET_64BIT && !addr.pointer)
2292 return FALSE;
2294 if (addr.pointer)
2295 return TRUE;
2297 if ((addr.base && REG_P (addr.base) && REG_POINTER (addr.base))
2298 || (addr.indx && REG_P (addr.indx) && REG_POINTER (addr.indx)))
2299 return TRUE;
2301 return FALSE;
2304 /* Emit a forced load-address operation to load SRC into DST.
2305 This will use the LOAD ADDRESS instruction even in situations
2306 where legitimate_la_operand_p (SRC) returns false. */
2308 void
2309 s390_load_address (rtx dst, rtx src)
2311 if (TARGET_64BIT)
2312 emit_move_insn (dst, src);
2313 else
2314 emit_insn (gen_force_la_31 (dst, src));
2317 /* Return a legitimate reference for ORIG (an address) using the
2318 register REG. If REG is 0, a new pseudo is generated.
2320 There are two types of references that must be handled:
2322 1. Global data references must load the address from the GOT, via
2323 the PIC reg. An insn is emitted to do this load, and the reg is
2324 returned.
2326 2. Static data references, constant pool addresses, and code labels
2327 compute the address as an offset from the GOT, whose base is in
2328 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
2329 differentiate them from global data objects. The returned
2330 address is the PIC reg + an unspec constant.
2332 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2333 reg also appears in the address. */
2336 legitimize_pic_address (rtx orig, rtx reg)
2338 rtx addr = orig;
2339 rtx new = orig;
2340 rtx base;
2342 if (GET_CODE (addr) == LABEL_REF
2343 || (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (addr)))
2345 /* This is a local symbol. */
2346 if (TARGET_CPU_ZARCH && larl_operand (addr, VOIDmode))
2348 /* Access local symbols PC-relative via LARL.
2349 This is the same as in the non-PIC case, so it is
2350 handled automatically ... */
2352 else
2354 /* Access local symbols relative to the GOT. */
2356 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2358 if (reload_in_progress || reload_completed)
2359 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2361 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
2362 addr = gen_rtx_CONST (Pmode, addr);
2363 addr = force_const_mem (Pmode, addr);
2364 emit_move_insn (temp, addr);
2366 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2367 if (reg != 0)
2369 emit_move_insn (reg, new);
2370 new = reg;
2374 else if (GET_CODE (addr) == SYMBOL_REF)
2376 if (reg == 0)
2377 reg = gen_reg_rtx (Pmode);
2379 if (flag_pic == 1)
2381 /* Assume GOT offset < 4k. This is handled the same way
2382 in both 31- and 64-bit code (@GOT). */
2384 if (reload_in_progress || reload_completed)
2385 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2387 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
2388 new = gen_rtx_CONST (Pmode, new);
2389 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
2390 new = gen_rtx_MEM (Pmode, new);
2391 RTX_UNCHANGING_P (new) = 1;
2392 emit_move_insn (reg, new);
2393 new = reg;
2395 else if (TARGET_CPU_ZARCH)
2397 /* If the GOT offset might be >= 4k, we determine the position
2398 of the GOT entry via a PC-relative LARL (@GOTENT). */
2400 rtx temp = gen_reg_rtx (Pmode);
2402 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTENT);
2403 new = gen_rtx_CONST (Pmode, new);
2404 emit_move_insn (temp, new);
2406 new = gen_rtx_MEM (Pmode, temp);
2407 RTX_UNCHANGING_P (new) = 1;
2408 emit_move_insn (reg, new);
2409 new = reg;
2411 else
2413 /* If the GOT offset might be >= 4k, we have to load it
2414 from the literal pool (@GOT). */
2416 rtx temp = gen_reg_rtx (Pmode);
2418 if (reload_in_progress || reload_completed)
2419 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2421 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
2422 addr = gen_rtx_CONST (Pmode, addr);
2423 addr = force_const_mem (Pmode, addr);
2424 emit_move_insn (temp, addr);
2426 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2427 new = gen_rtx_MEM (Pmode, new);
2428 RTX_UNCHANGING_P (new) = 1;
2429 emit_move_insn (reg, new);
2430 new = reg;
2433 else
2435 if (GET_CODE (addr) == CONST)
2437 addr = XEXP (addr, 0);
2438 if (GET_CODE (addr) == UNSPEC)
2440 if (XVECLEN (addr, 0) != 1)
2441 abort ();
2442 switch (XINT (addr, 1))
2444 /* If someone moved a GOT-relative UNSPEC
2445 out of the literal pool, force them back in. */
2446 case UNSPEC_GOTOFF:
2447 case UNSPEC_PLTOFF:
2448 new = force_const_mem (Pmode, orig);
2449 break;
2451 /* @GOT is OK as is if small. */
2452 case UNSPEC_GOT:
2453 if (flag_pic == 2)
2454 new = force_const_mem (Pmode, orig);
2455 break;
2457 /* @GOTENT is OK as is. */
2458 case UNSPEC_GOTENT:
2459 break;
2461 /* @PLT is OK as is on 64-bit, must be converted to
2462 GOT-relative @PLTOFF on 31-bit. */
2463 case UNSPEC_PLT:
2464 if (!TARGET_CPU_ZARCH)
2466 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2468 if (reload_in_progress || reload_completed)
2469 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2471 addr = XVECEXP (addr, 0, 0);
2472 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
2473 UNSPEC_PLTOFF);
2474 addr = gen_rtx_CONST (Pmode, addr);
2475 addr = force_const_mem (Pmode, addr);
2476 emit_move_insn (temp, addr);
2478 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2479 if (reg != 0)
2481 emit_move_insn (reg, new);
2482 new = reg;
2485 break;
2487 /* Everything else cannot happen. */
2488 default:
2489 abort ();
2492 else if (GET_CODE (addr) != PLUS)
2493 abort ();
2495 if (GET_CODE (addr) == PLUS)
2497 rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
2498 /* Check first to see if this is a constant offset
2499 from a local symbol reference. */
2500 if ((GET_CODE (op0) == LABEL_REF
2501 || (GET_CODE (op0) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op0)))
2502 && GET_CODE (op1) == CONST_INT)
2504 if (TARGET_CPU_ZARCH && larl_operand (op0, VOIDmode))
2506 if (INTVAL (op1) & 1)
2508 /* LARL can't handle odd offsets, so emit a
2509 pair of LARL and LA. */
2510 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2512 if (!DISP_IN_RANGE (INTVAL (op1)))
2514 int even = INTVAL (op1) - 1;
2515 op0 = gen_rtx_PLUS (Pmode, op0, GEN_INT (even));
2516 op0 = gen_rtx_CONST (Pmode, op0);
2517 op1 = GEN_INT (1);
2520 emit_move_insn (temp, op0);
2521 new = gen_rtx_PLUS (Pmode, temp, op1);
2523 if (reg != 0)
2525 emit_move_insn (reg, new);
2526 new = reg;
2529 else
2531 /* If the offset is even, we can just use LARL.
2532 This will happen automatically. */
2535 else
2537 /* Access local symbols relative to the GOT. */
2539 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2541 if (reload_in_progress || reload_completed)
2542 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2544 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
2545 UNSPEC_GOTOFF);
2546 addr = gen_rtx_PLUS (Pmode, addr, op1);
2547 addr = gen_rtx_CONST (Pmode, addr);
2548 addr = force_const_mem (Pmode, addr);
2549 emit_move_insn (temp, addr);
2551 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2552 if (reg != 0)
2554 emit_move_insn (reg, new);
2555 new = reg;
2560 /* Now, check whether it is a GOT relative symbol plus offset
2561 that was pulled out of the literal pool. Force it back in. */
2563 else if (GET_CODE (op0) == UNSPEC
2564 && GET_CODE (op1) == CONST_INT)
2566 if (XVECLEN (op0, 0) != 1)
2567 abort ();
2568 if (XINT (op0, 1) != UNSPEC_GOTOFF)
2569 abort ();
2571 new = force_const_mem (Pmode, orig);
2574 /* Otherwise, compute the sum. */
2575 else
2577 base = legitimize_pic_address (XEXP (addr, 0), reg);
2578 new = legitimize_pic_address (XEXP (addr, 1),
2579 base == reg ? NULL_RTX : reg);
2580 if (GET_CODE (new) == CONST_INT)
2581 new = plus_constant (base, INTVAL (new));
2582 else
2584 if (GET_CODE (new) == PLUS && CONSTANT_P (XEXP (new, 1)))
2586 base = gen_rtx_PLUS (Pmode, base, XEXP (new, 0));
2587 new = XEXP (new, 1);
2589 new = gen_rtx_PLUS (Pmode, base, new);
2592 if (GET_CODE (new) == CONST)
2593 new = XEXP (new, 0);
2594 new = force_operand (new, 0);
2598 return new;
2601 /* Load the thread pointer into a register. */
2603 static rtx
2604 get_thread_pointer (void)
2606 rtx tp;
2608 tp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
2609 tp = force_reg (Pmode, tp);
2610 mark_reg_pointer (tp, BITS_PER_WORD);
2612 return tp;
2615 /* Construct the SYMBOL_REF for the tls_get_offset function. */
2617 static GTY(()) rtx s390_tls_symbol;
2619 s390_tls_get_offset (void)
2621 if (!s390_tls_symbol)
2622 s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset");
2624 return s390_tls_symbol;
2627 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
2628 this (thread-local) address. REG may be used as temporary. */
2630 static rtx
2631 legitimize_tls_address (rtx addr, rtx reg)
2633 rtx new, tls_call, temp, base, r2, insn;
2635 if (GET_CODE (addr) == SYMBOL_REF)
2636 switch (tls_symbolic_operand (addr))
2638 case TLS_MODEL_GLOBAL_DYNAMIC:
2639 start_sequence ();
2640 r2 = gen_rtx_REG (Pmode, 2);
2641 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLSGD);
2642 new = gen_rtx_CONST (Pmode, tls_call);
2643 new = force_const_mem (Pmode, new);
2644 emit_move_insn (r2, new);
2645 emit_call_insn (gen_call_value_tls (r2, tls_call));
2646 insn = get_insns ();
2647 end_sequence ();
2649 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
2650 temp = gen_reg_rtx (Pmode);
2651 emit_libcall_block (insn, temp, r2, new);
2653 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2654 if (reg != 0)
2656 s390_load_address (reg, new);
2657 new = reg;
2659 break;
2661 case TLS_MODEL_LOCAL_DYNAMIC:
2662 start_sequence ();
2663 r2 = gen_rtx_REG (Pmode, 2);
2664 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM);
2665 new = gen_rtx_CONST (Pmode, tls_call);
2666 new = force_const_mem (Pmode, new);
2667 emit_move_insn (r2, new);
2668 emit_call_insn (gen_call_value_tls (r2, tls_call));
2669 insn = get_insns ();
2670 end_sequence ();
2672 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM_NTPOFF);
2673 temp = gen_reg_rtx (Pmode);
2674 emit_libcall_block (insn, temp, r2, new);
2676 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2677 base = gen_reg_rtx (Pmode);
2678 s390_load_address (base, new);
2680 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_DTPOFF);
2681 new = gen_rtx_CONST (Pmode, new);
2682 new = force_const_mem (Pmode, new);
2683 temp = gen_reg_rtx (Pmode);
2684 emit_move_insn (temp, new);
2686 new = gen_rtx_PLUS (Pmode, base, temp);
2687 if (reg != 0)
2689 s390_load_address (reg, new);
2690 new = reg;
2692 break;
2694 case TLS_MODEL_INITIAL_EXEC:
2695 if (flag_pic == 1)
2697 /* Assume GOT offset < 4k. This is handled the same way
2698 in both 31- and 64-bit code. */
2700 if (reload_in_progress || reload_completed)
2701 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2703 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
2704 new = gen_rtx_CONST (Pmode, new);
2705 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
2706 new = gen_rtx_MEM (Pmode, new);
2707 RTX_UNCHANGING_P (new) = 1;
2708 temp = gen_reg_rtx (Pmode);
2709 emit_move_insn (temp, new);
2711 else if (TARGET_CPU_ZARCH)
2713 /* If the GOT offset might be >= 4k, we determine the position
2714 of the GOT entry via a PC-relative LARL. */
2716 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
2717 new = gen_rtx_CONST (Pmode, new);
2718 temp = gen_reg_rtx (Pmode);
2719 emit_move_insn (temp, new);
2721 new = gen_rtx_MEM (Pmode, temp);
2722 RTX_UNCHANGING_P (new) = 1;
2723 temp = gen_reg_rtx (Pmode);
2724 emit_move_insn (temp, new);
2726 else if (flag_pic)
2728 /* If the GOT offset might be >= 4k, we have to load it
2729 from the literal pool. */
2731 if (reload_in_progress || reload_completed)
2732 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2734 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
2735 new = gen_rtx_CONST (Pmode, new);
2736 new = force_const_mem (Pmode, new);
2737 temp = gen_reg_rtx (Pmode);
2738 emit_move_insn (temp, new);
2740 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2741 new = gen_rtx_MEM (Pmode, new);
2742 RTX_UNCHANGING_P (new) = 1;
2744 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new, addr), UNSPEC_TLS_LOAD);
2745 temp = gen_reg_rtx (Pmode);
2746 emit_insn (gen_rtx_SET (Pmode, temp, new));
2748 else
2750 /* In position-dependent code, load the absolute address of
2751 the GOT entry from the literal pool. */
2753 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
2754 new = gen_rtx_CONST (Pmode, new);
2755 new = force_const_mem (Pmode, new);
2756 temp = gen_reg_rtx (Pmode);
2757 emit_move_insn (temp, new);
2759 new = temp;
2760 new = gen_rtx_MEM (Pmode, new);
2761 RTX_UNCHANGING_P (new) = 1;
2763 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new, addr), UNSPEC_TLS_LOAD);
2764 temp = gen_reg_rtx (Pmode);
2765 emit_insn (gen_rtx_SET (Pmode, temp, new));
2768 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2769 if (reg != 0)
2771 s390_load_address (reg, new);
2772 new = reg;
2774 break;
2776 case TLS_MODEL_LOCAL_EXEC:
2777 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
2778 new = gen_rtx_CONST (Pmode, new);
2779 new = force_const_mem (Pmode, new);
2780 temp = gen_reg_rtx (Pmode);
2781 emit_move_insn (temp, new);
2783 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2784 if (reg != 0)
2786 s390_load_address (reg, new);
2787 new = reg;
2789 break;
2791 default:
2792 abort ();
2795 else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == UNSPEC)
2797 switch (XINT (XEXP (addr, 0), 1))
2799 case UNSPEC_INDNTPOFF:
2800 if (TARGET_CPU_ZARCH)
2801 new = addr;
2802 else
2803 abort ();
2804 break;
2806 default:
2807 abort ();
2811 else
2812 abort (); /* for now ... */
2814 return new;
2817 /* Emit insns to move operands[1] into operands[0]. */
2819 void
2820 emit_symbolic_move (rtx *operands)
2822 rtx temp = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
2824 if (GET_CODE (operands[0]) == MEM)
2825 operands[1] = force_reg (Pmode, operands[1]);
2826 else if (TLS_SYMBOLIC_CONST (operands[1]))
2827 operands[1] = legitimize_tls_address (operands[1], temp);
2828 else if (flag_pic)
2829 operands[1] = legitimize_pic_address (operands[1], temp);
2832 /* Try machine-dependent ways of modifying an illegitimate address X
2833 to be legitimate. If we find one, return the new, valid address.
2835 OLDX is the address as it was before break_out_memory_refs was called.
2836 In some cases it is useful to look at this to decide what needs to be done.
2838 MODE is the mode of the operand pointed to by X.
2840 When -fpic is used, special handling is needed for symbolic references.
2841 See comments by legitimize_pic_address for details. */
2844 legitimize_address (register rtx x, register rtx oldx ATTRIBUTE_UNUSED,
2845 enum machine_mode mode ATTRIBUTE_UNUSED)
2847 rtx constant_term = const0_rtx;
2849 if (TLS_SYMBOLIC_CONST (x))
2851 x = legitimize_tls_address (x, 0);
2853 if (legitimate_address_p (mode, x, FALSE))
2854 return x;
2856 else if (flag_pic)
2858 if (SYMBOLIC_CONST (x)
2859 || (GET_CODE (x) == PLUS
2860 && (SYMBOLIC_CONST (XEXP (x, 0))
2861 || SYMBOLIC_CONST (XEXP (x, 1)))))
2862 x = legitimize_pic_address (x, 0);
2864 if (legitimate_address_p (mode, x, FALSE))
2865 return x;
2868 x = eliminate_constant_term (x, &constant_term);
2870 /* Optimize loading of large displacements by splitting them
2871 into the multiple of 4K and the rest; this allows the
2872 former to be CSE'd if possible.
2874 Don't do this if the displacement is added to a register
2875 pointing into the stack frame, as the offsets will
2876 change later anyway. */
2878 if (GET_CODE (constant_term) == CONST_INT
2879 && !TARGET_LONG_DISPLACEMENT
2880 && !DISP_IN_RANGE (INTVAL (constant_term))
2881 && !(REG_P (x) && REGNO_PTR_FRAME_P (REGNO (x))))
2883 HOST_WIDE_INT lower = INTVAL (constant_term) & 0xfff;
2884 HOST_WIDE_INT upper = INTVAL (constant_term) ^ lower;
2886 rtx temp = gen_reg_rtx (Pmode);
2887 rtx val = force_operand (GEN_INT (upper), temp);
2888 if (val != temp)
2889 emit_move_insn (temp, val);
2891 x = gen_rtx_PLUS (Pmode, x, temp);
2892 constant_term = GEN_INT (lower);
2895 if (GET_CODE (x) == PLUS)
2897 if (GET_CODE (XEXP (x, 0)) == REG)
2899 register rtx temp = gen_reg_rtx (Pmode);
2900 register rtx val = force_operand (XEXP (x, 1), temp);
2901 if (val != temp)
2902 emit_move_insn (temp, val);
2904 x = gen_rtx_PLUS (Pmode, XEXP (x, 0), temp);
2907 else if (GET_CODE (XEXP (x, 1)) == REG)
2909 register rtx temp = gen_reg_rtx (Pmode);
2910 register rtx val = force_operand (XEXP (x, 0), temp);
2911 if (val != temp)
2912 emit_move_insn (temp, val);
2914 x = gen_rtx_PLUS (Pmode, temp, XEXP (x, 1));
2918 if (constant_term != const0_rtx)
2919 x = gen_rtx_PLUS (Pmode, x, constant_term);
2921 return x;
2924 /* Emit code to move LEN bytes from DST to SRC. */
2926 void
2927 s390_expand_movstr (rtx dst, rtx src, rtx len)
2929 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
2931 if (INTVAL (len) > 0)
2932 emit_insn (gen_movstr_short (dst, src, GEN_INT (INTVAL (len) - 1)));
2935 else if (TARGET_MVCLE)
2937 emit_insn (gen_movstr_long (dst, src, convert_to_mode (Pmode, len, 1)));
2940 else
2942 rtx dst_addr, src_addr, count, blocks, temp;
2943 rtx end_label = gen_label_rtx ();
2944 enum machine_mode mode;
2945 tree type;
2947 mode = GET_MODE (len);
2948 if (mode == VOIDmode)
2949 mode = Pmode;
2951 type = lang_hooks.types.type_for_mode (mode, 1);
2952 if (!type)
2953 abort ();
2955 dst_addr = gen_reg_rtx (Pmode);
2956 src_addr = gen_reg_rtx (Pmode);
2957 count = gen_reg_rtx (mode);
2958 blocks = gen_reg_rtx (mode);
2960 convert_move (count, len, 1);
2961 emit_cmp_and_jump_insns (count, const0_rtx,
2962 EQ, NULL_RTX, mode, 1, end_label);
2964 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
2965 emit_move_insn (src_addr, force_operand (XEXP (src, 0), NULL_RTX));
2966 dst = change_address (dst, VOIDmode, dst_addr);
2967 src = change_address (src, VOIDmode, src_addr);
2969 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
2970 if (temp != count)
2971 emit_move_insn (count, temp);
2973 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
2974 if (temp != blocks)
2975 emit_move_insn (blocks, temp);
2977 expand_start_loop (1);
2978 expand_exit_loop_top_cond (0, build (NE_EXPR, type,
2979 make_tree (type, blocks),
2980 make_tree (type, const0_rtx)));
2982 emit_insn (gen_movstr_short (dst, src, GEN_INT (255)));
2983 s390_load_address (dst_addr,
2984 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
2985 s390_load_address (src_addr,
2986 gen_rtx_PLUS (Pmode, src_addr, GEN_INT (256)));
2988 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
2989 if (temp != blocks)
2990 emit_move_insn (blocks, temp);
2992 expand_end_loop ();
2994 emit_insn (gen_movstr_short (dst, src,
2995 convert_to_mode (Pmode, count, 1)));
2996 emit_label (end_label);
3000 /* Emit code to clear LEN bytes at DST. */
3002 void
3003 s390_expand_clrstr (rtx dst, rtx len)
3005 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
3007 if (INTVAL (len) > 0)
3008 emit_insn (gen_clrstr_short (dst, GEN_INT (INTVAL (len) - 1)));
3011 else if (TARGET_MVCLE)
3013 emit_insn (gen_clrstr_long (dst, convert_to_mode (Pmode, len, 1)));
3016 else
3018 rtx dst_addr, src_addr, count, blocks, temp;
3019 rtx end_label = gen_label_rtx ();
3020 enum machine_mode mode;
3021 tree type;
3023 mode = GET_MODE (len);
3024 if (mode == VOIDmode)
3025 mode = Pmode;
3027 type = lang_hooks.types.type_for_mode (mode, 1);
3028 if (!type)
3029 abort ();
3031 dst_addr = gen_reg_rtx (Pmode);
3032 src_addr = gen_reg_rtx (Pmode);
3033 count = gen_reg_rtx (mode);
3034 blocks = gen_reg_rtx (mode);
3036 convert_move (count, len, 1);
3037 emit_cmp_and_jump_insns (count, const0_rtx,
3038 EQ, NULL_RTX, mode, 1, end_label);
3040 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
3041 dst = change_address (dst, VOIDmode, dst_addr);
3043 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3044 if (temp != count)
3045 emit_move_insn (count, temp);
3047 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
3048 if (temp != blocks)
3049 emit_move_insn (blocks, temp);
3051 expand_start_loop (1);
3052 expand_exit_loop_top_cond (0, build (NE_EXPR, type,
3053 make_tree (type, blocks),
3054 make_tree (type, const0_rtx)));
3056 emit_insn (gen_clrstr_short (dst, GEN_INT (255)));
3057 s390_load_address (dst_addr,
3058 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
3060 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3061 if (temp != blocks)
3062 emit_move_insn (blocks, temp);
3064 expand_end_loop ();
3066 emit_insn (gen_clrstr_short (dst, convert_to_mode (Pmode, count, 1)));
3067 emit_label (end_label);
3071 /* Emit code to compare LEN bytes at OP0 with those at OP1,
3072 and return the result in TARGET. */
3074 void
3075 s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
3077 rtx (*gen_result) (rtx) =
3078 GET_MODE (target) == DImode ? gen_cmpint_di : gen_cmpint_si;
3080 op0 = protect_from_queue (op0, 0);
3081 op1 = protect_from_queue (op1, 0);
3082 len = protect_from_queue (len, 0);
3084 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
3086 if (INTVAL (len) > 0)
3088 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (INTVAL (len) - 1)));
3089 emit_insn (gen_result (target));
3091 else
3092 emit_move_insn (target, const0_rtx);
3095 else /* if (TARGET_MVCLE) */
3097 emit_insn (gen_cmpmem_long (op0, op1, convert_to_mode (Pmode, len, 1)));
3098 emit_insn (gen_result (target));
3101 #if 0
3102 /* Deactivate for now as profile code cannot cope with
3103 CC being live across basic block boundaries. */
3104 else
3106 rtx addr0, addr1, count, blocks, temp;
3107 rtx end_label = gen_label_rtx ();
3108 enum machine_mode mode;
3109 tree type;
3111 mode = GET_MODE (len);
3112 if (mode == VOIDmode)
3113 mode = Pmode;
3115 type = lang_hooks.types.type_for_mode (mode, 1);
3116 if (!type)
3117 abort ();
3119 addr0 = gen_reg_rtx (Pmode);
3120 addr1 = gen_reg_rtx (Pmode);
3121 count = gen_reg_rtx (mode);
3122 blocks = gen_reg_rtx (mode);
3124 convert_move (count, len, 1);
3125 emit_cmp_and_jump_insns (count, const0_rtx,
3126 EQ, NULL_RTX, mode, 1, end_label);
3128 emit_move_insn (addr0, force_operand (XEXP (op0, 0), NULL_RTX));
3129 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
3130 op0 = change_address (op0, VOIDmode, addr0);
3131 op1 = change_address (op1, VOIDmode, addr1);
3133 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3134 if (temp != count)
3135 emit_move_insn (count, temp);
3137 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
3138 if (temp != blocks)
3139 emit_move_insn (blocks, temp);
3141 expand_start_loop (1);
3142 expand_exit_loop_top_cond (0, build (NE_EXPR, type,
3143 make_tree (type, blocks),
3144 make_tree (type, const0_rtx)));
3146 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (255)));
3147 temp = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCSmode, 33), const0_rtx);
3148 temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
3149 gen_rtx_LABEL_REF (VOIDmode, end_label), pc_rtx);
3150 temp = gen_rtx_SET (VOIDmode, pc_rtx, temp);
3151 emit_jump_insn (temp);
3153 s390_load_address (addr0,
3154 gen_rtx_PLUS (Pmode, addr0, GEN_INT (256)));
3155 s390_load_address (addr1,
3156 gen_rtx_PLUS (Pmode, addr1, GEN_INT (256)));
3158 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3159 if (temp != blocks)
3160 emit_move_insn (blocks, temp);
3162 expand_end_loop ();
3164 emit_insn (gen_cmpmem_short (op0, op1,
3165 convert_to_mode (Pmode, count, 1)));
3166 emit_label (end_label);
3168 emit_insn (gen_result (target));
3170 #endif
3173 /* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
3174 We need to emit DTP-relative relocations. */
3176 void
3177 s390_output_dwarf_dtprel (FILE *file, int size, rtx x)
3179 switch (size)
3181 case 4:
3182 fputs ("\t.long\t", file);
3183 break;
3184 case 8:
3185 fputs ("\t.quad\t", file);
3186 break;
3187 default:
3188 abort ();
3190 output_addr_const (file, x);
3191 fputs ("@DTPOFF", file);
3194 /* In the name of slightly smaller debug output, and to cater to
3195 general assembler losage, recognize various UNSPEC sequences
3196 and turn them back into a direct symbol reference. */
3198 static rtx
3199 s390_delegitimize_address (rtx orig_x)
3201 rtx x = orig_x, y;
3203 if (GET_CODE (x) != MEM)
3204 return orig_x;
3206 x = XEXP (x, 0);
3207 if (GET_CODE (x) == PLUS
3208 && GET_CODE (XEXP (x, 1)) == CONST
3209 && GET_CODE (XEXP (x, 0)) == REG
3210 && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM)
3212 y = XEXP (XEXP (x, 1), 0);
3213 if (GET_CODE (y) == UNSPEC
3214 && XINT (y, 1) == UNSPEC_GOT)
3215 return XVECEXP (y, 0, 0);
3216 return orig_x;
3219 if (GET_CODE (x) == CONST)
3221 y = XEXP (x, 0);
3222 if (GET_CODE (y) == UNSPEC
3223 && XINT (y, 1) == UNSPEC_GOTENT)
3224 return XVECEXP (y, 0, 0);
3225 return orig_x;
3228 return orig_x;
3231 /* Output shift count operand OP to stdio stream FILE. */
3233 static void
3234 print_shift_count_operand (FILE *file, rtx op)
3236 HOST_WIDE_INT offset = 0;
3238 /* We can have an integer constant, an address register,
3239 or a sum of the two. */
3240 if (GET_CODE (op) == CONST_INT)
3242 offset = INTVAL (op);
3243 op = NULL_RTX;
3245 if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
3247 offset = INTVAL (XEXP (op, 1));
3248 op = XEXP (op, 0);
3250 while (op && GET_CODE (op) == SUBREG)
3251 op = SUBREG_REG (op);
3253 /* Sanity check. */
3254 if (op && (GET_CODE (op) != REG
3255 || REGNO (op) >= FIRST_PSEUDO_REGISTER
3256 || REGNO_REG_CLASS (REGNO (op)) != ADDR_REGS))
3257 abort ();
3259 /* Shift counts are truncated to the low six bits anyway. */
3260 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset & 63);
3261 if (op)
3262 fprintf (file, "(%s)", reg_names[REGNO (op)]);
3265 /* Locate some local-dynamic symbol still in use by this function
3266 so that we can print its name in local-dynamic base patterns. */
3268 static const char *
3269 get_some_local_dynamic_name (void)
3271 rtx insn;
3273 if (cfun->machine->some_ld_name)
3274 return cfun->machine->some_ld_name;
3276 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
3277 if (INSN_P (insn)
3278 && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
3279 return cfun->machine->some_ld_name;
3281 abort ();
3284 static int
3285 get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
3287 rtx x = *px;
3289 if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
3291 x = get_pool_constant (x);
3292 return for_each_rtx (&x, get_some_local_dynamic_name_1, 0);
3295 if (GET_CODE (x) == SYMBOL_REF
3296 && tls_symbolic_operand (x) == TLS_MODEL_LOCAL_DYNAMIC)
3298 cfun->machine->some_ld_name = XSTR (x, 0);
3299 return 1;
3302 return 0;
3305 /* Output symbolic constant X in assembler syntax to
3306 stdio stream FILE. */
3308 void
3309 s390_output_symbolic_const (FILE *file, rtx x)
3311 switch (GET_CODE (x))
3313 case CONST:
3314 case ZERO_EXTEND:
3315 case SIGN_EXTEND:
3316 s390_output_symbolic_const (file, XEXP (x, 0));
3317 break;
3319 case PLUS:
3320 s390_output_symbolic_const (file, XEXP (x, 0));
3321 fprintf (file, "+");
3322 s390_output_symbolic_const (file, XEXP (x, 1));
3323 break;
3325 case MINUS:
3326 s390_output_symbolic_const (file, XEXP (x, 0));
3327 fprintf (file, "-");
3328 s390_output_symbolic_const (file, XEXP (x, 1));
3329 break;
3331 case CONST_INT:
3332 case LABEL_REF:
3333 case CODE_LABEL:
3334 case SYMBOL_REF:
3335 output_addr_const (file, x);
3336 break;
3338 case UNSPEC:
3339 if (XVECLEN (x, 0) != 1)
3340 output_operand_lossage ("invalid UNSPEC as operand (1)");
3341 switch (XINT (x, 1))
3343 case UNSPEC_GOTENT:
3344 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3345 fprintf (file, "@GOTENT");
3346 break;
3347 case UNSPEC_GOT:
3348 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3349 fprintf (file, "@GOT");
3350 break;
3351 case UNSPEC_GOTOFF:
3352 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3353 fprintf (file, "@GOTOFF");
3354 break;
3355 case UNSPEC_PLT:
3356 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3357 fprintf (file, "@PLT");
3358 break;
3359 case UNSPEC_PLTOFF:
3360 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3361 fprintf (file, "@PLTOFF");
3362 break;
3363 case UNSPEC_TLSGD:
3364 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3365 fprintf (file, "@TLSGD");
3366 break;
3367 case UNSPEC_TLSLDM:
3368 assemble_name (file, get_some_local_dynamic_name ());
3369 fprintf (file, "@TLSLDM");
3370 break;
3371 case UNSPEC_DTPOFF:
3372 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3373 fprintf (file, "@DTPOFF");
3374 break;
3375 case UNSPEC_NTPOFF:
3376 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3377 fprintf (file, "@NTPOFF");
3378 break;
3379 case UNSPEC_GOTNTPOFF:
3380 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3381 fprintf (file, "@GOTNTPOFF");
3382 break;
3383 case UNSPEC_INDNTPOFF:
3384 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3385 fprintf (file, "@INDNTPOFF");
3386 break;
3387 default:
3388 output_operand_lossage ("invalid UNSPEC as operand (2)");
3389 break;
3391 break;
3393 default:
3394 fatal_insn ("UNKNOWN in s390_output_symbolic_const !?", x);
3395 break;
3399 /* Output address operand ADDR in assembler syntax to
3400 stdio stream FILE. */
3402 void
3403 print_operand_address (FILE *file, rtx addr)
3405 struct s390_address ad;
3407 if (!s390_decompose_address (addr, &ad)
3408 || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
3409 || (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
3410 output_operand_lossage ("Cannot decompose address.");
3412 if (ad.disp)
3413 s390_output_symbolic_const (file, ad.disp);
3414 else
3415 fprintf (file, "0");
3417 if (ad.base && ad.indx)
3418 fprintf (file, "(%s,%s)", reg_names[REGNO (ad.indx)],
3419 reg_names[REGNO (ad.base)]);
3420 else if (ad.base)
3421 fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
3424 /* Output operand X in assembler syntax to stdio stream FILE.
3425 CODE specified the format flag. The following format flags
3426 are recognized:
3428 'C': print opcode suffix for branch condition.
3429 'D': print opcode suffix for inverse branch condition.
3430 'J': print tls_load/tls_gdcall/tls_ldcall suffix
3431 'O': print only the displacement of a memory reference.
3432 'R': print only the base register of a memory reference.
3433 'N': print the second word of a DImode operand.
3434 'M': print the second word of a TImode operand.
3435 'Y': print shift count operand.
3437 'b': print integer X as if it's an unsigned byte.
3438 'x': print integer X as if it's an unsigned word.
3439 'h': print integer X as if it's a signed word.
3440 'i': print the first nonzero HImode part of X.
3441 'j': print the first HImode part unequal to 0xffff of X. */
3443 void
3444 print_operand (FILE *file, rtx x, int code)
3446 switch (code)
3448 case 'C':
3449 fprintf (file, s390_branch_condition_mnemonic (x, FALSE));
3450 return;
3452 case 'D':
3453 fprintf (file, s390_branch_condition_mnemonic (x, TRUE));
3454 return;
3456 case 'J':
3457 if (GET_CODE (x) == SYMBOL_REF)
3459 fprintf (file, "%s", ":tls_load:");
3460 output_addr_const (file, x);
3462 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD)
3464 fprintf (file, "%s", ":tls_gdcall:");
3465 output_addr_const (file, XVECEXP (x, 0, 0));
3467 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM)
3469 fprintf (file, "%s", ":tls_ldcall:");
3470 assemble_name (file, get_some_local_dynamic_name ());
3472 else
3473 abort ();
3474 return;
3476 case 'O':
3478 struct s390_address ad;
3480 if (GET_CODE (x) != MEM
3481 || !s390_decompose_address (XEXP (x, 0), &ad)
3482 || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
3483 || ad.indx)
3484 abort ();
3486 if (ad.disp)
3487 s390_output_symbolic_const (file, ad.disp);
3488 else
3489 fprintf (file, "0");
3491 return;
3493 case 'R':
3495 struct s390_address ad;
3497 if (GET_CODE (x) != MEM
3498 || !s390_decompose_address (XEXP (x, 0), &ad)
3499 || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
3500 || ad.indx)
3501 abort ();
3503 if (ad.base)
3504 fprintf (file, "%s", reg_names[REGNO (ad.base)]);
3505 else
3506 fprintf (file, "0");
3508 return;
3510 case 'N':
3511 if (GET_CODE (x) == REG)
3512 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
3513 else if (GET_CODE (x) == MEM)
3514 x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 4));
3515 else
3516 abort ();
3517 break;
3519 case 'M':
3520 if (GET_CODE (x) == REG)
3521 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
3522 else if (GET_CODE (x) == MEM)
3523 x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 8));
3524 else
3525 abort ();
3526 break;
3528 case 'Y':
3529 print_shift_count_operand (file, x);
3530 return;
3533 switch (GET_CODE (x))
3535 case REG:
3536 fprintf (file, "%s", reg_names[REGNO (x)]);
3537 break;
3539 case MEM:
3540 output_address (XEXP (x, 0));
3541 break;
3543 case CONST:
3544 case CODE_LABEL:
3545 case LABEL_REF:
3546 case SYMBOL_REF:
3547 s390_output_symbolic_const (file, x);
3548 break;
3550 case CONST_INT:
3551 if (code == 'b')
3552 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xff);
3553 else if (code == 'x')
3554 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffff);
3555 else if (code == 'h')
3556 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000);
3557 else if (code == 'i')
3558 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3559 s390_extract_part (x, HImode, 0));
3560 else if (code == 'j')
3561 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3562 s390_extract_part (x, HImode, -1));
3563 else
3564 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
3565 break;
3567 case CONST_DOUBLE:
3568 if (GET_MODE (x) != VOIDmode)
3569 abort ();
3570 if (code == 'b')
3571 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xff);
3572 else if (code == 'x')
3573 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xffff);
3574 else if (code == 'h')
3575 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((CONST_DOUBLE_LOW (x) & 0xffff) ^ 0x8000) - 0x8000);
3576 else
3577 abort ();
3578 break;
3580 default:
3581 fatal_insn ("UNKNOWN in print_operand !?", x);
3582 break;
3586 /* Target hook for assembling integer objects. We need to define it
3587 here to work a round a bug in some versions of GAS, which couldn't
3588 handle values smaller than INT_MIN when printed in decimal. */
3590 static bool
3591 s390_assemble_integer (rtx x, unsigned int size, int aligned_p)
3593 if (size == 8 && aligned_p
3594 && GET_CODE (x) == CONST_INT && INTVAL (x) < INT_MIN)
3596 fprintf (asm_out_file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n",
3597 INTVAL (x));
3598 return true;
3600 return default_assemble_integer (x, size, aligned_p);
3603 /* Returns true if register REGNO is used for forming
3604 a memory address in expression X. */
3606 static int
3607 reg_used_in_mem_p (int regno, rtx x)
3609 enum rtx_code code = GET_CODE (x);
3610 int i, j;
3611 const char *fmt;
3613 if (code == MEM)
3615 if (refers_to_regno_p (regno, regno+1,
3616 XEXP (x, 0), 0))
3617 return 1;
3619 else if (code == SET
3620 && GET_CODE (SET_DEST (x)) == PC)
3622 if (refers_to_regno_p (regno, regno+1,
3623 SET_SRC (x), 0))
3624 return 1;
3627 fmt = GET_RTX_FORMAT (code);
3628 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3630 if (fmt[i] == 'e'
3631 && reg_used_in_mem_p (regno, XEXP (x, i)))
3632 return 1;
3634 else if (fmt[i] == 'E')
3635 for (j = 0; j < XVECLEN (x, i); j++)
3636 if (reg_used_in_mem_p (regno, XVECEXP (x, i, j)))
3637 return 1;
3639 return 0;
3642 /* Returns true if expression DEP_RTX sets an address register
3643 used by instruction INSN to address memory. */
3645 static int
3646 addr_generation_dependency_p (rtx dep_rtx, rtx insn)
3648 rtx target, pat;
3650 if (GET_CODE (dep_rtx) == INSN)
3651 dep_rtx = PATTERN (dep_rtx);
3653 if (GET_CODE (dep_rtx) == SET)
3655 target = SET_DEST (dep_rtx);
3656 if (GET_CODE (target) == STRICT_LOW_PART)
3657 target = XEXP (target, 0);
3658 while (GET_CODE (target) == SUBREG)
3659 target = SUBREG_REG (target);
3661 if (GET_CODE (target) == REG)
3663 int regno = REGNO (target);
3665 if (s390_safe_attr_type (insn) == TYPE_LA)
3667 pat = PATTERN (insn);
3668 if (GET_CODE (pat) == PARALLEL)
3670 if (XVECLEN (pat, 0) != 2)
3671 abort();
3672 pat = XVECEXP (pat, 0, 0);
3674 if (GET_CODE (pat) == SET)
3675 return refers_to_regno_p (regno, regno+1, SET_SRC (pat), 0);
3676 else
3677 abort();
3679 else if (get_attr_atype (insn) == ATYPE_AGEN)
3680 return reg_used_in_mem_p (regno, PATTERN (insn));
3683 return 0;
3686 /* Return 1, if dep_insn sets register used in insn in the agen unit. */
3689 s390_agen_dep_p (rtx dep_insn, rtx insn)
3691 rtx dep_rtx = PATTERN (dep_insn);
3692 int i;
3694 if (GET_CODE (dep_rtx) == SET
3695 && addr_generation_dependency_p (dep_rtx, insn))
3696 return 1;
3697 else if (GET_CODE (dep_rtx) == PARALLEL)
3699 for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
3701 if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i), insn))
3702 return 1;
3705 return 0;
3708 /* Return the modified cost of the dependency of instruction INSN
3709 on instruction DEP_INSN through the link LINK. COST is the
3710 default cost of that dependency.
3712 Data dependencies are all handled without delay. However, if a
3713 register is modified and subsequently used as base or index
3714 register of a memory reference, at least 4 cycles need to pass
3715 between setting and using the register to avoid pipeline stalls.
3716 An exception is the LA instruction. An address generated by LA can
3717 be used by introducing only a one cycle stall on the pipeline. */
3719 static int
3720 s390_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
3722 rtx dep_rtx;
3723 int i;
3725 /* If the dependence is an anti-dependence, there is no cost. For an
3726 output dependence, there is sometimes a cost, but it doesn't seem
3727 worth handling those few cases. */
3729 if (REG_NOTE_KIND (link) != 0)
3730 return 0;
3732 /* If we can't recognize the insns, we can't really do anything. */
3733 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
3734 return cost;
3736 /* DFA based scheduling checks address dependency in md file. */
3737 if (s390_use_dfa_pipeline_interface ())
3739 /* Operand forward in case of lr, load and la. */
3740 if (s390_tune == PROCESSOR_2084_Z990
3741 && cost == 1
3742 && (s390_safe_attr_type (dep_insn) == TYPE_LA
3743 || s390_safe_attr_type (dep_insn) == TYPE_LR
3744 || s390_safe_attr_type (dep_insn) == TYPE_LOAD))
3745 return 0;
3746 return cost;
3749 dep_rtx = PATTERN (dep_insn);
3751 if (GET_CODE (dep_rtx) == SET
3752 && addr_generation_dependency_p (dep_rtx, insn))
3753 cost += (s390_safe_attr_type (dep_insn) == TYPE_LA) ? 1 : 4;
3754 else if (GET_CODE (dep_rtx) == PARALLEL)
3756 for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
3758 if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i), insn))
3759 cost += (s390_safe_attr_type (dep_insn) == TYPE_LA) ? 1 : 4;
3763 return cost;
3765 /* A C statement (sans semicolon) to update the integer scheduling priority
3766 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
3767 reduce the priority to execute INSN later. Do not define this macro if
3768 you do not need to adjust the scheduling priorities of insns.
3770 A STD instruction should be scheduled earlier,
3771 in order to use the bypass. */
3773 static int
3774 s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
3776 if (! INSN_P (insn))
3777 return priority;
3779 if (s390_tune != PROCESSOR_2084_Z990)
3780 return priority;
3782 switch (s390_safe_attr_type (insn))
3784 case TYPE_FSTORED:
3785 case TYPE_FSTORES:
3786 priority = priority << 3;
3787 break;
3788 case TYPE_STORE:
3789 priority = priority << 1;
3790 break;
3791 default:
3792 break;
3794 return priority;
3797 /* The number of instructions that can be issued per cycle. */
3799 static int
3800 s390_issue_rate (void)
3802 if (s390_tune == PROCESSOR_2084_Z990)
3803 return 3;
3804 return 1;
3807 /* If the following function returns TRUE, we will use the the DFA
3808 insn scheduler. */
3810 static int
3811 s390_use_dfa_pipeline_interface (void)
3813 if (s390_tune == PROCESSOR_2064_Z900
3814 || s390_tune == PROCESSOR_2084_Z990)
3815 return 1;
3817 return 0;
3820 static int
3821 s390_first_cycle_multipass_dfa_lookahead (void)
3823 return s390_use_dfa_pipeline_interface () ? 4 : 0;
3826 /* Called after issuing each insn.
3827 Triggers default sort algorithm to better slot instructions. */
3829 static int
3830 s390_sched_reorder2 (FILE *dump ATTRIBUTE_UNUSED,
3831 int sched_verbose ATTRIBUTE_UNUSED,
3832 rtx *ready ATTRIBUTE_UNUSED,
3833 int *pn_ready ATTRIBUTE_UNUSED,
3834 int clock_var ATTRIBUTE_UNUSED)
3836 return s390_issue_rate();
3840 /* Split all branches that exceed the maximum distance.
3841 Returns true if this created a new literal pool entry. */
3843 static int
3844 s390_split_branches (void)
3846 rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
3847 int new_literal = 0;
3848 rtx insn, pat, tmp, target;
3849 rtx *label;
3851 /* We need correct insn addresses. */
3853 shorten_branches (get_insns ());
3855 /* Find all branches that exceed 64KB, and split them. */
3857 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
3859 if (GET_CODE (insn) != JUMP_INSN)
3860 continue;
3862 pat = PATTERN (insn);
3863 if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
3864 pat = XVECEXP (pat, 0, 0);
3865 if (GET_CODE (pat) != SET || SET_DEST (pat) != pc_rtx)
3866 continue;
3868 if (GET_CODE (SET_SRC (pat)) == LABEL_REF)
3870 label = &SET_SRC (pat);
3872 else if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE)
3874 if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF)
3875 label = &XEXP (SET_SRC (pat), 1);
3876 else if (GET_CODE (XEXP (SET_SRC (pat), 2)) == LABEL_REF)
3877 label = &XEXP (SET_SRC (pat), 2);
3878 else
3879 continue;
3881 else
3882 continue;
3884 if (get_attr_length (insn) <= 4)
3885 continue;
3887 /* We are going to use the return register as scratch register,
3888 make sure it will be saved/restored by the prologue/epilogue. */
3889 cfun->machine->save_return_addr_p = 1;
3891 if (!flag_pic)
3893 new_literal = 1;
3894 tmp = force_const_mem (Pmode, *label);
3895 tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, tmp), insn);
3896 INSN_ADDRESSES_NEW (tmp, -1);
3898 target = temp_reg;
3900 else
3902 new_literal = 1;
3903 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, *label),
3904 UNSPEC_LTREL_OFFSET);
3905 target = gen_rtx_CONST (Pmode, target);
3906 target = force_const_mem (Pmode, target);
3907 tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, target), insn);
3908 INSN_ADDRESSES_NEW (tmp, -1);
3910 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (target, 0)),
3911 UNSPEC_LTREL_BASE);
3912 target = gen_rtx_PLUS (Pmode, temp_reg, target);
3915 if (!validate_change (insn, label, target, 0))
3916 abort ();
3919 return new_literal;
3923 /* Find a literal pool symbol referenced in RTX X, and store
3924 it at REF. Will abort if X contains references to more than
3925 one such pool symbol; multiple references to the same symbol
3926 are allowed, however.
3928 The rtx pointed to by REF must be initialized to NULL_RTX
3929 by the caller before calling this routine. */
3931 static void
3932 find_constant_pool_ref (rtx x, rtx *ref)
3934 int i, j;
3935 const char *fmt;
3937 /* Ignore LTREL_BASE references. */
3938 if (GET_CODE (x) == UNSPEC
3939 && XINT (x, 1) == UNSPEC_LTREL_BASE)
3940 return;
3941 /* Likewise POOL_ENTRY insns. */
3942 if (GET_CODE (x) == UNSPEC_VOLATILE
3943 && XINT (x, 1) == UNSPECV_POOL_ENTRY)
3944 return;
3946 if (GET_CODE (x) == SYMBOL_REF
3947 && CONSTANT_POOL_ADDRESS_P (x))
3949 if (*ref == NULL_RTX)
3950 *ref = x;
3951 else if (*ref != x)
3952 abort();
3955 fmt = GET_RTX_FORMAT (GET_CODE (x));
3956 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
3958 if (fmt[i] == 'e')
3960 find_constant_pool_ref (XEXP (x, i), ref);
3962 else if (fmt[i] == 'E')
3964 for (j = 0; j < XVECLEN (x, i); j++)
3965 find_constant_pool_ref (XVECEXP (x, i, j), ref);
3970 /* Replace every reference to the literal pool symbol REF
3971 in X by the address ADDR. Fix up MEMs as required. */
3973 static void
3974 replace_constant_pool_ref (rtx *x, rtx ref, rtx addr)
3976 int i, j;
3977 const char *fmt;
3979 if (*x == ref)
3980 abort ();
3982 /* Literal pool references can only occur inside a MEM ... */
3983 if (GET_CODE (*x) == MEM)
3985 rtx memref = XEXP (*x, 0);
3987 if (memref == ref)
3989 *x = replace_equiv_address (*x, addr);
3990 return;
3993 if (GET_CODE (memref) == CONST
3994 && GET_CODE (XEXP (memref, 0)) == PLUS
3995 && GET_CODE (XEXP (XEXP (memref, 0), 1)) == CONST_INT
3996 && XEXP (XEXP (memref, 0), 0) == ref)
3998 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (memref, 0), 1));
3999 *x = replace_equiv_address (*x, plus_constant (addr, off));
4000 return;
4004 /* ... or a load-address type pattern. */
4005 if (GET_CODE (*x) == SET)
4007 rtx addrref = SET_SRC (*x);
4009 if (addrref == ref)
4011 SET_SRC (*x) = addr;
4012 return;
4015 if (GET_CODE (addrref) == CONST
4016 && GET_CODE (XEXP (addrref, 0)) == PLUS
4017 && GET_CODE (XEXP (XEXP (addrref, 0), 1)) == CONST_INT
4018 && XEXP (XEXP (addrref, 0), 0) == ref)
4020 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (addrref, 0), 1));
4021 SET_SRC (*x) = plus_constant (addr, off);
4022 return;
4026 fmt = GET_RTX_FORMAT (GET_CODE (*x));
4027 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
4029 if (fmt[i] == 'e')
4031 replace_constant_pool_ref (&XEXP (*x, i), ref, addr);
4033 else if (fmt[i] == 'E')
4035 for (j = 0; j < XVECLEN (*x, i); j++)
4036 replace_constant_pool_ref (&XVECEXP (*x, i, j), ref, addr);
4041 /* Check whether X contains an UNSPEC_LTREL_BASE.
4042 Return its constant pool symbol if found, NULL_RTX otherwise. */
4044 static rtx
4045 find_ltrel_base (rtx x)
4047 int i, j;
4048 const char *fmt;
4050 if (GET_CODE (x) == UNSPEC
4051 && XINT (x, 1) == UNSPEC_LTREL_BASE)
4052 return XVECEXP (x, 0, 0);
4054 fmt = GET_RTX_FORMAT (GET_CODE (x));
4055 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4057 if (fmt[i] == 'e')
4059 rtx fnd = find_ltrel_base (XEXP (x, i));
4060 if (fnd)
4061 return fnd;
4063 else if (fmt[i] == 'E')
4065 for (j = 0; j < XVECLEN (x, i); j++)
4067 rtx fnd = find_ltrel_base (XVECEXP (x, i, j));
4068 if (fnd)
4069 return fnd;
4074 return NULL_RTX;
4077 /* Replace any occurrence of UNSPEC_LTREL_BASE in X with BASE. */
4079 static void
4080 replace_ltrel_base (rtx *x, rtx base)
4082 int i, j;
4083 const char *fmt;
4085 if (GET_CODE (*x) == UNSPEC
4086 && XINT (*x, 1) == UNSPEC_LTREL_BASE)
4088 *x = base;
4089 return;
4092 fmt = GET_RTX_FORMAT (GET_CODE (*x));
4093 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
4095 if (fmt[i] == 'e')
4097 replace_ltrel_base (&XEXP (*x, i), base);
4099 else if (fmt[i] == 'E')
4101 for (j = 0; j < XVECLEN (*x, i); j++)
4102 replace_ltrel_base (&XVECEXP (*x, i, j), base);
4108 /* We keep a list of constants which we have to add to internal
4109 constant tables in the middle of large functions. */
4111 #define NR_C_MODES 7
4112 enum machine_mode constant_modes[NR_C_MODES] =
4114 TImode,
4115 DFmode, DImode,
4116 SFmode, SImode,
4117 HImode,
4118 QImode
4121 struct constant
4123 struct constant *next;
4124 rtx value;
4125 rtx label;
4128 struct constant_pool
4130 struct constant_pool *next;
4131 rtx first_insn;
4132 rtx pool_insn;
4133 bitmap insns;
4135 struct constant *constants[NR_C_MODES];
4136 rtx label;
4137 int size;
4140 static struct constant_pool * s390_mainpool_start (void);
4141 static void s390_mainpool_finish (struct constant_pool *, rtx base_reg);
4142 static void s390_mainpool_cancel (struct constant_pool *);
4144 static struct constant_pool * s390_chunkify_start (rtx base_reg);
4145 static void s390_chunkify_finish (struct constant_pool *, rtx base_reg);
4146 static void s390_chunkify_cancel (struct constant_pool *);
4148 static struct constant_pool *s390_start_pool (struct constant_pool **, rtx);
4149 static void s390_end_pool (struct constant_pool *, rtx);
4150 static void s390_add_pool_insn (struct constant_pool *, rtx);
4151 static struct constant_pool *s390_find_pool (struct constant_pool *, rtx);
4152 static void s390_add_constant (struct constant_pool *, rtx, enum machine_mode);
4153 static rtx s390_find_constant (struct constant_pool *, rtx, enum machine_mode);
4154 static rtx s390_dump_pool (struct constant_pool *, bool);
4155 static struct constant_pool *s390_alloc_pool (void);
4156 static void s390_free_pool (struct constant_pool *);
4158 /* Create new constant pool covering instructions starting at INSN
4159 and chain it to the end of POOL_LIST. */
4161 static struct constant_pool *
4162 s390_start_pool (struct constant_pool **pool_list, rtx insn)
4164 struct constant_pool *pool, **prev;
4166 pool = s390_alloc_pool ();
4167 pool->first_insn = insn;
4169 for (prev = pool_list; *prev; prev = &(*prev)->next)
4171 *prev = pool;
4173 return pool;
4176 /* End range of instructions covered by POOL at INSN and emit
4177 placeholder insn representing the pool. */
4179 static void
4180 s390_end_pool (struct constant_pool *pool, rtx insn)
4182 rtx pool_size = GEN_INT (pool->size + 8 /* alignment slop */);
4184 if (!insn)
4185 insn = get_last_insn ();
4187 pool->pool_insn = emit_insn_after (gen_pool (pool_size), insn);
4188 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
4191 /* Add INSN to the list of insns covered by POOL. */
4193 static void
4194 s390_add_pool_insn (struct constant_pool *pool, rtx insn)
4196 bitmap_set_bit (pool->insns, INSN_UID (insn));
4199 /* Return pool out of POOL_LIST that covers INSN. */
4201 static struct constant_pool *
4202 s390_find_pool (struct constant_pool *pool_list, rtx insn)
4204 struct constant_pool *pool;
4206 for (pool = pool_list; pool; pool = pool->next)
4207 if (bitmap_bit_p (pool->insns, INSN_UID (insn)))
4208 break;
4210 return pool;
4213 /* Add constant VAL of mode MODE to the constant pool POOL. */
4215 static void
4216 s390_add_constant (struct constant_pool *pool, rtx val, enum machine_mode mode)
4218 struct constant *c;
4219 int i;
4221 for (i = 0; i < NR_C_MODES; i++)
4222 if (constant_modes[i] == mode)
4223 break;
4224 if (i == NR_C_MODES)
4225 abort ();
4227 for (c = pool->constants[i]; c != NULL; c = c->next)
4228 if (rtx_equal_p (val, c->value))
4229 break;
4231 if (c == NULL)
4233 c = (struct constant *) xmalloc (sizeof *c);
4234 c->value = val;
4235 c->label = gen_label_rtx ();
4236 c->next = pool->constants[i];
4237 pool->constants[i] = c;
4238 pool->size += GET_MODE_SIZE (mode);
4242 /* Find constant VAL of mode MODE in the constant pool POOL.
4243 Return an RTX describing the distance from the start of
4244 the pool to the location of the new constant. */
4246 static rtx
4247 s390_find_constant (struct constant_pool *pool, rtx val,
4248 enum machine_mode mode)
4250 struct constant *c;
4251 rtx offset;
4252 int i;
4254 for (i = 0; i < NR_C_MODES; i++)
4255 if (constant_modes[i] == mode)
4256 break;
4257 if (i == NR_C_MODES)
4258 abort ();
4260 for (c = pool->constants[i]; c != NULL; c = c->next)
4261 if (rtx_equal_p (val, c->value))
4262 break;
4264 if (c == NULL)
4265 abort ();
4267 offset = gen_rtx_MINUS (Pmode, gen_rtx_LABEL_REF (Pmode, c->label),
4268 gen_rtx_LABEL_REF (Pmode, pool->label));
4269 offset = gen_rtx_CONST (Pmode, offset);
4270 return offset;
4273 /* Dump out the constants in POOL. If REMOTE_LABEL is true,
4274 do not emit the pool base label. */
4276 static rtx
4277 s390_dump_pool (struct constant_pool *pool, bool remote_label)
4279 struct constant *c;
4280 rtx insn;
4281 int i;
4283 /* Pool start insn switches to proper section
4284 and guarantees necessary alignment. */
4285 if (TARGET_CPU_ZARCH)
4286 insn = emit_insn_after (gen_pool_start_64 (), pool->pool_insn);
4287 else
4288 insn = emit_insn_after (gen_pool_start_31 (), pool->pool_insn);
4289 INSN_ADDRESSES_NEW (insn, -1);
4291 if (!remote_label)
4293 insn = emit_label_after (pool->label, insn);
4294 INSN_ADDRESSES_NEW (insn, -1);
4297 /* Dump constants in descending alignment requirement order,
4298 ensuring proper alignment for every constant. */
4299 for (i = 0; i < NR_C_MODES; i++)
4300 for (c = pool->constants[i]; c; c = c->next)
4302 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
4303 rtx value = c->value;
4304 if (GET_CODE (value) == CONST
4305 && GET_CODE (XEXP (value, 0)) == UNSPEC
4306 && XINT (XEXP (value, 0), 1) == UNSPEC_LTREL_OFFSET
4307 && XVECLEN (XEXP (value, 0), 0) == 1)
4309 value = gen_rtx_MINUS (Pmode, XVECEXP (XEXP (value, 0), 0, 0),
4310 gen_rtx_LABEL_REF (VOIDmode, pool->label));
4311 value = gen_rtx_CONST (VOIDmode, value);
4314 insn = emit_label_after (c->label, insn);
4315 INSN_ADDRESSES_NEW (insn, -1);
4317 value = gen_rtx_UNSPEC_VOLATILE (constant_modes[i],
4318 gen_rtvec (1, value),
4319 UNSPECV_POOL_ENTRY);
4320 insn = emit_insn_after (value, insn);
4321 INSN_ADDRESSES_NEW (insn, -1);
4324 /* Pool end insn switches back to previous section
4325 and guarantees necessary alignment. */
4326 if (TARGET_CPU_ZARCH)
4327 insn = emit_insn_after (gen_pool_end_64 (), insn);
4328 else
4329 insn = emit_insn_after (gen_pool_end_31 (), insn);
4330 INSN_ADDRESSES_NEW (insn, -1);
4332 insn = emit_barrier_after (insn);
4333 INSN_ADDRESSES_NEW (insn, -1);
4335 /* Remove placeholder insn. */
4336 remove_insn (pool->pool_insn);
4338 return insn;
4341 /* Allocate new constant_pool structure. */
4343 static struct constant_pool *
4344 s390_alloc_pool (void)
4346 struct constant_pool *pool;
4347 int i;
4349 pool = (struct constant_pool *) xmalloc (sizeof *pool);
4350 pool->next = NULL;
4351 for (i = 0; i < NR_C_MODES; i++)
4352 pool->constants[i] = NULL;
4354 pool->label = gen_label_rtx ();
4355 pool->first_insn = NULL_RTX;
4356 pool->pool_insn = NULL_RTX;
4357 pool->insns = BITMAP_XMALLOC ();
4358 pool->size = 0;
4360 return pool;
4363 /* Free all memory used by POOL. */
4365 static void
4366 s390_free_pool (struct constant_pool *pool)
4368 int i;
4370 for (i = 0; i < NR_C_MODES; i++)
4372 struct constant *c = pool->constants[i];
4373 while (c != NULL)
4375 struct constant *next = c->next;
4376 free (c);
4377 c = next;
4381 BITMAP_XFREE (pool->insns);
4382 free (pool);
4386 /* Collect main literal pool. Return NULL on overflow. */
4388 static struct constant_pool *
4389 s390_mainpool_start (void)
4391 struct constant_pool *pool;
4392 rtx insn;
4394 pool = s390_alloc_pool ();
4396 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4398 if (GET_CODE (insn) == INSN
4399 && GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
4400 && XINT (PATTERN (insn), 1) == UNSPECV_MAIN_POOL)
4402 if (pool->pool_insn)
4403 abort ();
4404 pool->pool_insn = insn;
4407 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
4409 rtx pool_ref = NULL_RTX;
4410 find_constant_pool_ref (PATTERN (insn), &pool_ref);
4411 if (pool_ref)
4413 rtx constant = get_pool_constant (pool_ref);
4414 enum machine_mode mode = get_pool_mode (pool_ref);
4415 s390_add_constant (pool, constant, mode);
4420 if (!pool->pool_insn)
4421 abort ();
4423 if (pool->size >= 4096)
4425 s390_free_pool (pool);
4426 pool = NULL;
4429 return pool;
4432 /* POOL holds the main literal pool as collected by s390_mainpool_start.
4433 Modify the current function to output the pool constants as well as
4434 the pool register setup instruction. BASE_REG is the register to
4435 be used as pool base register. */
4437 static void
4438 s390_mainpool_finish (struct constant_pool *pool, rtx base_reg)
4440 rtx insn;
4442 /* If the pool is empty, we're done. */
4443 if (pool->size == 0)
4445 remove_insn (pool->pool_insn);
4446 s390_free_pool (pool);
4447 return;
4450 /* We need correct insn addresses. */
4451 shorten_branches (get_insns ());
4453 /* On zSeries, we use a LARL to load the pool register. The pool is
4454 located in the .rodata section, so we emit it after the function. */
4455 if (TARGET_CPU_ZARCH)
4457 insn = gen_main_base_64 (base_reg, pool->label);
4458 insn = emit_insn_after (insn, pool->pool_insn);
4459 INSN_ADDRESSES_NEW (insn, -1);
4460 remove_insn (pool->pool_insn);
4462 insn = get_last_insn ();
4463 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
4464 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
4466 s390_dump_pool (pool, 0);
4469 /* On S/390, if the total size of the function's code plus literal pool
4470 does not exceed 4096 bytes, we use BASR to set up a function base
4471 pointer, and emit the literal pool at the end of the function. */
4472 else if (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
4473 + pool->size + 8 /* alignment slop */ < 4096)
4475 insn = gen_main_base_31_small (base_reg, pool->label);
4476 insn = emit_insn_after (insn, pool->pool_insn);
4477 INSN_ADDRESSES_NEW (insn, -1);
4478 remove_insn (pool->pool_insn);
4480 insn = emit_label_after (pool->label, insn);
4481 INSN_ADDRESSES_NEW (insn, -1);
4483 insn = get_last_insn ();
4484 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
4485 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
4487 s390_dump_pool (pool, 1);
4490 /* Otherwise, we emit an inline literal pool and use BASR to branch
4491 over it, setting up the pool register at the same time. */
4492 else
4494 rtx pool_end = gen_label_rtx ();
4496 insn = gen_main_base_31_large (base_reg, pool->label, pool_end);
4497 insn = emit_insn_after (insn, pool->pool_insn);
4498 INSN_ADDRESSES_NEW (insn, -1);
4499 remove_insn (pool->pool_insn);
4501 insn = emit_label_after (pool->label, insn);
4502 INSN_ADDRESSES_NEW (insn, -1);
4504 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
4505 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
4507 insn = emit_label_after (pool_end, pool->pool_insn);
4508 INSN_ADDRESSES_NEW (insn, -1);
4510 s390_dump_pool (pool, 1);
4514 /* Replace all literal pool references. */
4516 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4518 if (INSN_P (insn))
4519 replace_ltrel_base (&PATTERN (insn), base_reg);
4521 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
4523 rtx addr, pool_ref = NULL_RTX;
4524 find_constant_pool_ref (PATTERN (insn), &pool_ref);
4525 if (pool_ref)
4527 addr = s390_find_constant (pool, get_pool_constant (pool_ref),
4528 get_pool_mode (pool_ref));
4529 addr = gen_rtx_PLUS (Pmode, base_reg, addr);
4530 replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
4531 INSN_CODE (insn) = -1;
4537 /* Free the pool. */
4538 s390_free_pool (pool);
4541 /* POOL holds the main literal pool as collected by s390_mainpool_start.
4542 We have decided we cannot use this pool, so revert all changes
4543 to the current function that were done by s390_mainpool_start. */
4544 static void
4545 s390_mainpool_cancel (struct constant_pool *pool)
4547 /* We didn't actually change the instruction stream, so simply
4548 free the pool memory. */
4549 s390_free_pool (pool);
4553 /* Chunkify the literal pool. BASE_REG is to be used as pool
4554 register. */
4556 #define S390_POOL_CHUNK_MIN 0xc00
4557 #define S390_POOL_CHUNK_MAX 0xe00
4559 static struct constant_pool *
4560 s390_chunkify_start (rtx base_reg)
4562 struct constant_pool *curr_pool = NULL, *pool_list = NULL;
4563 int extra_size = 0;
4564 bitmap far_labels;
4565 rtx pending_ltrel = NULL_RTX;
4566 rtx insn;
4568 rtx (*gen_reload_base) (rtx, rtx) =
4569 TARGET_CPU_ZARCH? gen_reload_base_64 : gen_reload_base_31;
4572 /* We need correct insn addresses. */
4574 shorten_branches (get_insns ());
4576 /* Scan all insns and move literals to pool chunks. */
4578 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4580 /* Check for pending LTREL_BASE. */
4581 if (INSN_P (insn))
4583 rtx ltrel_base = find_ltrel_base (PATTERN (insn));
4584 if (ltrel_base)
4586 if (ltrel_base == pending_ltrel)
4587 pending_ltrel = NULL_RTX;
4588 else
4589 abort ();
4593 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
4595 rtx pool_ref = NULL_RTX;
4596 find_constant_pool_ref (PATTERN (insn), &pool_ref);
4597 if (pool_ref)
4599 rtx constant = get_pool_constant (pool_ref);
4600 enum machine_mode mode = get_pool_mode (pool_ref);
4602 if (!curr_pool)
4603 curr_pool = s390_start_pool (&pool_list, insn);
4605 s390_add_constant (curr_pool, constant, mode);
4606 s390_add_pool_insn (curr_pool, insn);
4608 /* Don't split the pool chunk between a LTREL_OFFSET load
4609 and the corresponding LTREL_BASE. */
4610 if (GET_CODE (constant) == CONST
4611 && GET_CODE (XEXP (constant, 0)) == UNSPEC
4612 && XINT (XEXP (constant, 0), 1) == UNSPEC_LTREL_OFFSET)
4614 if (pending_ltrel)
4615 abort ();
4616 pending_ltrel = pool_ref;
4621 if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CODE_LABEL)
4623 if (curr_pool)
4624 s390_add_pool_insn (curr_pool, insn);
4625 /* An LTREL_BASE must follow within the same basic block. */
4626 if (pending_ltrel)
4627 abort ();
4630 if (!curr_pool
4631 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn)
4632 || INSN_ADDRESSES (INSN_UID (insn)) == -1)
4633 continue;
4635 if (TARGET_CPU_ZARCH)
4637 if (curr_pool->size < S390_POOL_CHUNK_MAX)
4638 continue;
4640 s390_end_pool (curr_pool, NULL_RTX);
4641 curr_pool = NULL;
4643 else
4645 int chunk_size = INSN_ADDRESSES (INSN_UID (insn))
4646 - INSN_ADDRESSES (INSN_UID (curr_pool->first_insn))
4647 + extra_size;
4649 /* We will later have to insert base register reload insns.
4650 Those will have an effect on code size, which we need to
4651 consider here. This calculation makes rather pessimistic
4652 worst-case assumptions. */
4653 if (GET_CODE (insn) == CODE_LABEL)
4654 extra_size += 6;
4656 if (chunk_size < S390_POOL_CHUNK_MIN
4657 && curr_pool->size < S390_POOL_CHUNK_MIN)
4658 continue;
4660 /* Pool chunks can only be inserted after BARRIERs ... */
4661 if (GET_CODE (insn) == BARRIER)
4663 s390_end_pool (curr_pool, insn);
4664 curr_pool = NULL;
4665 extra_size = 0;
4668 /* ... so if we don't find one in time, create one. */
4669 else if ((chunk_size > S390_POOL_CHUNK_MAX
4670 || curr_pool->size > S390_POOL_CHUNK_MAX))
4672 rtx label, jump, barrier;
4674 /* We can insert the barrier only after a 'real' insn. */
4675 if (GET_CODE (insn) != INSN && GET_CODE (insn) != CALL_INSN)
4676 continue;
4677 if (get_attr_length (insn) == 0)
4678 continue;
4680 /* Don't separate LTREL_BASE from the corresponding
4681 LTREL_OFFSET load. */
4682 if (pending_ltrel)
4683 continue;
4685 label = gen_label_rtx ();
4686 jump = emit_jump_insn_after (gen_jump (label), insn);
4687 barrier = emit_barrier_after (jump);
4688 insn = emit_label_after (label, barrier);
4689 JUMP_LABEL (jump) = label;
4690 LABEL_NUSES (label) = 1;
4692 INSN_ADDRESSES_NEW (jump, -1);
4693 INSN_ADDRESSES_NEW (barrier, -1);
4694 INSN_ADDRESSES_NEW (insn, -1);
4696 s390_end_pool (curr_pool, barrier);
4697 curr_pool = NULL;
4698 extra_size = 0;
4703 if (curr_pool)
4704 s390_end_pool (curr_pool, NULL_RTX);
4705 if (pending_ltrel)
4706 abort ();
4709 /* Find all labels that are branched into
4710 from an insn belonging to a different chunk. */
4712 far_labels = BITMAP_XMALLOC ();
4714 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4716 /* Labels marked with LABEL_PRESERVE_P can be target
4717 of non-local jumps, so we have to mark them.
4718 The same holds for named labels.
4720 Don't do that, however, if it is the label before
4721 a jump table. */
4723 if (GET_CODE (insn) == CODE_LABEL
4724 && (LABEL_PRESERVE_P (insn) || LABEL_NAME (insn)))
4726 rtx vec_insn = next_real_insn (insn);
4727 rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
4728 PATTERN (vec_insn) : NULL_RTX;
4729 if (!vec_pat
4730 || !(GET_CODE (vec_pat) == ADDR_VEC
4731 || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
4732 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (insn));
4735 /* If we have a direct jump (conditional or unconditional)
4736 or a casesi jump, check all potential targets. */
4737 else if (GET_CODE (insn) == JUMP_INSN)
4739 rtx pat = PATTERN (insn);
4740 if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
4741 pat = XVECEXP (pat, 0, 0);
4743 if (GET_CODE (pat) == SET)
4745 rtx label = JUMP_LABEL (insn);
4746 if (label)
4748 if (s390_find_pool (pool_list, label)
4749 != s390_find_pool (pool_list, insn))
4750 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
4753 else if (GET_CODE (pat) == PARALLEL
4754 && XVECLEN (pat, 0) == 2
4755 && GET_CODE (XVECEXP (pat, 0, 0)) == SET
4756 && GET_CODE (XVECEXP (pat, 0, 1)) == USE
4757 && GET_CODE (XEXP (XVECEXP (pat, 0, 1), 0)) == LABEL_REF)
4759 /* Find the jump table used by this casesi jump. */
4760 rtx vec_label = XEXP (XEXP (XVECEXP (pat, 0, 1), 0), 0);
4761 rtx vec_insn = next_real_insn (vec_label);
4762 rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
4763 PATTERN (vec_insn) : NULL_RTX;
4764 if (vec_pat
4765 && (GET_CODE (vec_pat) == ADDR_VEC
4766 || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
4768 int i, diff_p = GET_CODE (vec_pat) == ADDR_DIFF_VEC;
4770 for (i = 0; i < XVECLEN (vec_pat, diff_p); i++)
4772 rtx label = XEXP (XVECEXP (vec_pat, diff_p, i), 0);
4774 if (s390_find_pool (pool_list, label)
4775 != s390_find_pool (pool_list, insn))
4776 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
4783 /* Insert base register reload insns before every pool. */
4785 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
4787 rtx new_insn = gen_reload_base (base_reg, curr_pool->label);
4788 rtx insn = curr_pool->first_insn;
4789 INSN_ADDRESSES_NEW (emit_insn_before (new_insn, insn), -1);
4792 /* Insert base register reload insns at every far label. */
4794 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4795 if (GET_CODE (insn) == CODE_LABEL
4796 && bitmap_bit_p (far_labels, CODE_LABEL_NUMBER (insn)))
4798 struct constant_pool *pool = s390_find_pool (pool_list, insn);
4799 if (pool)
4801 rtx new_insn = gen_reload_base (base_reg, pool->label);
4802 INSN_ADDRESSES_NEW (emit_insn_after (new_insn, insn), -1);
4807 BITMAP_XFREE (far_labels);
4810 /* Recompute insn addresses. */
4812 init_insn_lengths ();
4813 shorten_branches (get_insns ());
4815 return pool_list;
4818 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
4819 After we have decided to use this list, finish implementing
4820 all changes to the current function as required. BASE_REG is
4821 to be used as pool base register. */
4823 static void
4824 s390_chunkify_finish (struct constant_pool *pool_list, rtx base_reg)
4826 struct constant_pool *curr_pool = NULL;
4827 rtx insn;
4830 /* Replace all literal pool references. */
4832 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4834 if (INSN_P (insn))
4835 replace_ltrel_base (&PATTERN (insn), base_reg);
4837 curr_pool = s390_find_pool (pool_list, insn);
4838 if (!curr_pool)
4839 continue;
4841 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
4843 rtx addr, pool_ref = NULL_RTX;
4844 find_constant_pool_ref (PATTERN (insn), &pool_ref);
4845 if (pool_ref)
4847 addr = s390_find_constant (curr_pool, get_pool_constant (pool_ref),
4848 get_pool_mode (pool_ref));
4849 addr = gen_rtx_PLUS (Pmode, base_reg, addr);
4850 replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
4851 INSN_CODE (insn) = -1;
4856 /* Dump out all literal pools. */
4858 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
4859 s390_dump_pool (curr_pool, 0);
4861 /* Free pool list. */
4863 while (pool_list)
4865 struct constant_pool *next = pool_list->next;
4866 s390_free_pool (pool_list);
4867 pool_list = next;
4871 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
4872 We have decided we cannot use this list, so revert all changes
4873 to the current function that were done by s390_chunkify_start. */
4875 static void
4876 s390_chunkify_cancel (struct constant_pool *pool_list)
4878 struct constant_pool *curr_pool = NULL;
4879 rtx insn;
4881 /* Remove all pool placeholder insns. */
4883 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
4885 /* Did we insert an extra barrier? Remove it. */
4886 rtx barrier = PREV_INSN (curr_pool->pool_insn);
4887 rtx jump = barrier? PREV_INSN (barrier) : NULL_RTX;
4888 rtx label = NEXT_INSN (curr_pool->pool_insn);
4890 if (jump && GET_CODE (jump) == JUMP_INSN
4891 && barrier && GET_CODE (barrier) == BARRIER
4892 && label && GET_CODE (label) == CODE_LABEL
4893 && GET_CODE (PATTERN (jump)) == SET
4894 && SET_DEST (PATTERN (jump)) == pc_rtx
4895 && GET_CODE (SET_SRC (PATTERN (jump))) == LABEL_REF
4896 && XEXP (SET_SRC (PATTERN (jump)), 0) == label)
4898 remove_insn (jump);
4899 remove_insn (barrier);
4900 remove_insn (label);
4903 remove_insn (curr_pool->pool_insn);
4906 /* Remove all base register reload insns. */
4908 for (insn = get_insns (); insn; )
4910 rtx next_insn = NEXT_INSN (insn);
4912 if (GET_CODE (insn) == INSN
4913 && GET_CODE (PATTERN (insn)) == SET
4914 && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC
4915 && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPEC_RELOAD_BASE)
4916 remove_insn (insn);
4918 insn = next_insn;
4921 /* Free pool list. */
4923 while (pool_list)
4925 struct constant_pool *next = pool_list->next;
4926 s390_free_pool (pool_list);
4927 pool_list = next;
4932 /* Output to FILE the constant pool entry EXP in mode MODE
4933 with alignment ALIGN. */
4935 void
4936 s390_output_pool_entry (FILE *file, rtx exp, enum machine_mode mode,
4937 unsigned int align)
4939 REAL_VALUE_TYPE r;
4941 switch (GET_MODE_CLASS (mode))
4943 case MODE_FLOAT:
4944 if (GET_CODE (exp) != CONST_DOUBLE)
4945 abort ();
4947 REAL_VALUE_FROM_CONST_DOUBLE (r, exp);
4948 assemble_real (r, mode, align);
4949 break;
4951 case MODE_INT:
4952 if (GET_CODE (exp) == CONST
4953 || GET_CODE (exp) == SYMBOL_REF
4954 || GET_CODE (exp) == LABEL_REF)
4956 fputs (integer_asm_op (GET_MODE_SIZE (mode), TRUE), file);
4957 s390_output_symbolic_const (file, exp);
4958 fputc ('\n', file);
4960 else
4962 assemble_integer (exp, GET_MODE_SIZE (mode), align, 1);
4964 break;
4966 default:
4967 abort ();
4972 /* Rework the prolog/epilog to avoid saving/restoring
4973 registers unnecessarily. BASE_USED specifies whether
4974 the literal pool base register needs to be saved. */
4976 static void
4977 s390_optimize_prolog (bool base_used)
4979 int save_first, save_last, restore_first, restore_last;
4980 int i, j;
4981 rtx insn, new_insn, next_insn;
4983 /* Recompute regs_ever_live data for special registers. */
4984 regs_ever_live[BASE_REGISTER] = base_used;
4985 regs_ever_live[RETURN_REGNUM] = cfun->machine->save_return_addr_p;
4986 regs_ever_live[STACK_POINTER_REGNUM] = cfun->machine->frame_size > 0;
4989 /* Find first and last gpr to be saved. */
4991 for (i = 6; i < 16; i++)
4992 if (regs_ever_live[i])
4993 if (!global_regs[i]
4994 || i == STACK_POINTER_REGNUM
4995 || i == RETURN_REGNUM
4996 || i == BASE_REGISTER
4997 || (flag_pic && i == (int)PIC_OFFSET_TABLE_REGNUM))
4998 break;
5000 for (j = 15; j > i; j--)
5001 if (regs_ever_live[j])
5002 if (!global_regs[j]
5003 || j == STACK_POINTER_REGNUM
5004 || j == RETURN_REGNUM
5005 || j == BASE_REGISTER
5006 || (flag_pic && j == (int)PIC_OFFSET_TABLE_REGNUM))
5007 break;
5009 if (i == 16)
5011 /* Nothing to save/restore. */
5012 save_first = restore_first = -1;
5013 save_last = restore_last = -1;
5015 else
5017 /* Save/restore from i to j. */
5018 save_first = restore_first = i;
5019 save_last = restore_last = j;
5022 /* Varargs functions need to save gprs 2 to 6. */
5023 if (current_function_stdarg)
5025 save_first = 2;
5026 if (save_last < 6)
5027 save_last = 6;
5031 /* If all special registers are in fact used, there's nothing we
5032 can do, so no point in walking the insn list. */
5033 if (i <= BASE_REGISTER && j >= BASE_REGISTER
5034 && (TARGET_CPU_ZARCH || (i <= RETURN_REGNUM && j >= RETURN_REGNUM)))
5035 return;
5038 /* Search for prolog/epilog insns and replace them. */
5040 for (insn = get_insns (); insn; insn = next_insn)
5042 int first, last, off;
5043 rtx set, base, offset;
5045 next_insn = NEXT_INSN (insn);
5047 if (GET_CODE (insn) != INSN)
5048 continue;
5050 if (GET_CODE (PATTERN (insn)) == PARALLEL
5051 && store_multiple_operation (PATTERN (insn), VOIDmode))
5053 set = XVECEXP (PATTERN (insn), 0, 0);
5054 first = REGNO (SET_SRC (set));
5055 last = first + XVECLEN (PATTERN (insn), 0) - 1;
5056 offset = const0_rtx;
5057 base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
5058 off = INTVAL (offset) - first * UNITS_PER_WORD;
5060 if (GET_CODE (base) != REG || off < 0)
5061 continue;
5062 if (first > BASE_REGISTER || last < BASE_REGISTER)
5063 continue;
5065 if (save_first != -1)
5067 new_insn = save_gprs (base, off, save_first, save_last);
5068 new_insn = emit_insn_before (new_insn, insn);
5069 INSN_ADDRESSES_NEW (new_insn, -1);
5072 remove_insn (insn);
5073 continue;
5076 if (GET_CODE (PATTERN (insn)) == SET
5077 && GET_CODE (SET_SRC (PATTERN (insn))) == REG
5078 && REGNO (SET_SRC (PATTERN (insn))) == BASE_REGISTER
5079 && GET_CODE (SET_DEST (PATTERN (insn))) == MEM)
5081 set = PATTERN (insn);
5082 offset = const0_rtx;
5083 base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
5084 off = INTVAL (offset) - BASE_REGISTER * UNITS_PER_WORD;
5086 if (GET_CODE (base) != REG || off < 0)
5087 continue;
5089 if (save_first != -1)
5091 new_insn = save_gprs (base, off, save_first, save_last);
5092 new_insn = emit_insn_before (new_insn, insn);
5093 INSN_ADDRESSES_NEW (new_insn, -1);
5096 remove_insn (insn);
5097 continue;
5100 if (GET_CODE (PATTERN (insn)) == PARALLEL
5101 && load_multiple_operation (PATTERN (insn), VOIDmode))
5103 set = XVECEXP (PATTERN (insn), 0, 0);
5104 first = REGNO (SET_DEST (set));
5105 last = first + XVECLEN (PATTERN (insn), 0) - 1;
5106 offset = const0_rtx;
5107 base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
5108 off = INTVAL (offset) - first * UNITS_PER_WORD;
5110 if (GET_CODE (base) != REG || off < 0)
5111 continue;
5112 if (first > BASE_REGISTER || last < BASE_REGISTER)
5113 continue;
5115 if (restore_first != -1)
5117 new_insn = restore_gprs (base, off, restore_first, restore_last);
5118 new_insn = emit_insn_before (new_insn, insn);
5119 INSN_ADDRESSES_NEW (new_insn, -1);
5122 remove_insn (insn);
5123 continue;
5126 if (GET_CODE (PATTERN (insn)) == SET
5127 && GET_CODE (SET_DEST (PATTERN (insn))) == REG
5128 && REGNO (SET_DEST (PATTERN (insn))) == BASE_REGISTER
5129 && GET_CODE (SET_SRC (PATTERN (insn))) == MEM)
5131 set = PATTERN (insn);
5132 offset = const0_rtx;
5133 base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
5134 off = INTVAL (offset) - BASE_REGISTER * UNITS_PER_WORD;
5136 if (GET_CODE (base) != REG || off < 0)
5137 continue;
5139 if (restore_first != -1)
5141 new_insn = restore_gprs (base, off, restore_first, restore_last);
5142 new_insn = emit_insn_before (new_insn, insn);
5143 INSN_ADDRESSES_NEW (new_insn, -1);
5146 remove_insn (insn);
5147 continue;
5152 /* Perform machine-dependent processing. */
5154 static void
5155 s390_reorg (void)
5157 rtx base_reg = gen_rtx_REG (Pmode, BASE_REGISTER);
5158 bool base_used = false;
5159 bool pool_overflow = false;
5161 /* Make sure all splits have been performed; splits after
5162 machine_dependent_reorg might confuse insn length counts. */
5163 split_all_insns_noflow ();
5166 /* In small leaf functions, try to use an unused call-clobbered
5167 register as base register to avoid save/restore overhead. */
5168 if (current_function_is_leaf && !regs_ever_live[5])
5169 base_reg = gen_rtx_REG (Pmode, 5);
5172 /* Install the main literal pool and the associated base
5173 register load insns.
5175 In addition, there are two problematic situations we need
5176 to correct:
5178 - the literal pool might be > 4096 bytes in size, so that
5179 some of its elements cannot be directly accessed
5181 - a branch target might be > 64K away from the branch, so that
5182 it is not possible to use a PC-relative instruction.
5184 To fix those, we split the single literal pool into multiple
5185 pool chunks, reloading the pool base register at various
5186 points throughout the function to ensure it always points to
5187 the pool chunk the following code expects, and / or replace
5188 PC-relative branches by absolute branches.
5190 However, the two problems are interdependent: splitting the
5191 literal pool can move a branch further away from its target,
5192 causing the 64K limit to overflow, and on the other hand,
5193 replacing a PC-relative branch by an absolute branch means
5194 we need to put the branch target address into the literal
5195 pool, possibly causing it to overflow.
5197 So, we loop trying to fix up both problems until we manage
5198 to satisfy both conditions at the same time. Note that the
5199 loop is guaranteed to terminate as every pass of the loop
5200 strictly decreases the total number of PC-relative branches
5201 in the function. (This is not completely true as there
5202 might be branch-over-pool insns introduced by chunkify_start.
5203 Those never need to be split however.) */
5205 for (;;)
5207 struct constant_pool *pool = NULL;
5209 /* Collect the literal pool. */
5210 if (!pool_overflow)
5212 pool = s390_mainpool_start ();
5213 if (!pool)
5214 pool_overflow = true;
5217 /* If literal pool overflowed, start to chunkify it. */
5218 if (pool_overflow)
5219 pool = s390_chunkify_start (base_reg);
5221 /* Split out-of-range branches. If this has created new
5222 literal pool entries, cancel current chunk list and
5223 recompute it. zSeries machines have large branch
5224 instructions, so we never need to split a branch. */
5225 if (!TARGET_CPU_ZARCH && s390_split_branches ())
5227 if (pool_overflow)
5228 s390_chunkify_cancel (pool);
5229 else
5230 s390_mainpool_cancel (pool);
5232 continue;
5235 /* If we made it up to here, both conditions are satisfied.
5236 Finish up literal pool related changes. */
5237 if ((pool_overflow || pool->size > 0)
5238 && REGNO (base_reg) == BASE_REGISTER)
5239 base_used = true;
5241 if (pool_overflow)
5242 s390_chunkify_finish (pool, base_reg);
5243 else
5244 s390_mainpool_finish (pool, base_reg);
5246 break;
5249 s390_optimize_prolog (base_used);
5253 /* Return an RTL expression representing the value of the return address
5254 for the frame COUNT steps up from the current frame. FRAME is the
5255 frame pointer of that frame. */
5258 s390_return_addr_rtx (int count, rtx frame)
5260 rtx addr;
5262 /* For the current frame, we need to make sure the initial
5263 value of RETURN_REGNUM is actually saved. */
5265 if (count == 0)
5266 cfun->machine->save_return_addr_p = true;
5268 /* To retrieve the return address we read the stack slot where the
5269 corresponding RETURN_REGNUM value was saved. */
5271 addr = plus_constant (frame, RETURN_REGNUM * UNITS_PER_WORD);
5272 addr = memory_address (Pmode, addr);
5273 return gen_rtx_MEM (Pmode, addr);
5276 /* Find first call clobbered register unsused in a function.
5277 This could be used as base register in a leaf function
5278 or for holding the return address before epilogue. */
5280 static int
5281 find_unused_clobbered_reg (void)
5283 int i;
5284 for (i = 0; i < 6; i++)
5285 if (!regs_ever_live[i])
5286 return i;
5287 return 0;
5290 /* Fill FRAME with info about frame of current function. */
5292 static void
5293 s390_frame_info (void)
5295 int i, j;
5296 HOST_WIDE_INT fsize = get_frame_size ();
5298 if (fsize > 0x7fff0000)
5299 fatal_error ("Total size of local variables exceeds architecture limit.");
5301 /* fprs 8 - 15 are caller saved for 64 Bit ABI. */
5302 cfun->machine->save_fprs_p = 0;
5303 if (TARGET_64BIT)
5304 for (i = 24; i < 32; i++)
5305 if (regs_ever_live[i] && !global_regs[i])
5307 cfun->machine->save_fprs_p = 1;
5308 break;
5311 cfun->machine->frame_size = fsize + cfun->machine->save_fprs_p * 64;
5313 /* Does function need to setup frame and save area. */
5315 if (! current_function_is_leaf
5316 || cfun->machine->frame_size > 0
5317 || current_function_calls_alloca
5318 || current_function_stdarg)
5319 cfun->machine->frame_size += STARTING_FRAME_OFFSET;
5321 /* If we use the return register, we'll need to make sure
5322 it is going to be saved/restored. */
5324 if (!current_function_is_leaf
5325 || regs_ever_live[RETURN_REGNUM])
5326 cfun->machine->save_return_addr_p = 1;
5328 /* Find first and last gpr to be saved. Note that at this point,
5329 we assume the base register and -on S/390- the return register
5330 always need to be saved. This is done because the usage of these
5331 register might change even after the prolog was emitted.
5332 If it turns out later that we really don't need them, the
5333 prolog/epilog code is modified again. */
5335 regs_ever_live[BASE_REGISTER] = 1;
5336 if (!TARGET_CPU_ZARCH || cfun->machine->save_return_addr_p)
5337 regs_ever_live[RETURN_REGNUM] = 1;
5338 regs_ever_live[STACK_POINTER_REGNUM] = cfun->machine->frame_size > 0;
5340 for (i = 6; i < 16; i++)
5341 if (regs_ever_live[i])
5342 if (!global_regs[i]
5343 || i == STACK_POINTER_REGNUM
5344 || i == RETURN_REGNUM
5345 || i == BASE_REGISTER
5346 || (flag_pic && i == (int)PIC_OFFSET_TABLE_REGNUM))
5347 break;
5349 for (j = 15; j > i; j--)
5350 if (regs_ever_live[j])
5351 if (!global_regs[j]
5352 || j == STACK_POINTER_REGNUM
5353 || j == RETURN_REGNUM
5354 || j == BASE_REGISTER
5355 || (flag_pic && j == (int)PIC_OFFSET_TABLE_REGNUM))
5356 break;
5358 /* Save / Restore from gpr i to j. */
5359 cfun->machine->first_save_gpr = i;
5360 cfun->machine->first_restore_gpr = i;
5361 cfun->machine->last_save_gpr = j;
5363 /* Varargs functions need to save gprs 2 to 6. */
5364 if (current_function_stdarg)
5365 cfun->machine->first_save_gpr = 2;
5368 /* Return offset between argument pointer and frame pointer
5369 initially after prologue. */
5372 s390_arg_frame_offset (void)
5374 HOST_WIDE_INT fsize = get_frame_size ();
5375 int save_fprs_p, i;
5377 /* fprs 8 - 15 are caller saved for 64 Bit ABI. */
5378 save_fprs_p = 0;
5379 if (TARGET_64BIT)
5380 for (i = 24; i < 32; i++)
5381 if (regs_ever_live[i] && !global_regs[i])
5383 save_fprs_p = 1;
5384 break;
5387 fsize = fsize + save_fprs_p * 64;
5389 /* Does function need to setup frame and save area. */
5391 if (! current_function_is_leaf
5392 || fsize > 0
5393 || current_function_calls_alloca
5394 || current_function_stdarg)
5395 fsize += STARTING_FRAME_OFFSET;
5396 return fsize + STACK_POINTER_OFFSET;
5399 /* Emit insn to save fpr REGNUM at offset OFFSET relative
5400 to register BASE. Return generated insn. */
5402 static rtx
5403 save_fpr (rtx base, int offset, int regnum)
5405 rtx addr;
5406 addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
5407 set_mem_alias_set (addr, s390_sr_alias_set);
5409 return emit_move_insn (addr, gen_rtx_REG (DFmode, regnum));
5412 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
5413 to register BASE. Return generated insn. */
5415 static rtx
5416 restore_fpr (rtx base, int offset, int regnum)
5418 rtx addr;
5419 addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
5420 set_mem_alias_set (addr, s390_sr_alias_set);
5422 return emit_move_insn (gen_rtx_REG (DFmode, regnum), addr);
5425 /* Generate insn to save registers FIRST to LAST into
5426 the register save area located at offset OFFSET
5427 relative to register BASE. */
5429 static rtx
5430 save_gprs (rtx base, int offset, int first, int last)
5432 rtx addr, insn, note;
5433 int i;
5435 addr = plus_constant (base, offset + first * UNITS_PER_WORD);
5436 addr = gen_rtx_MEM (Pmode, addr);
5437 set_mem_alias_set (addr, s390_sr_alias_set);
5439 /* Special-case single register. */
5440 if (first == last)
5442 if (TARGET_64BIT)
5443 insn = gen_movdi (addr, gen_rtx_REG (Pmode, first));
5444 else
5445 insn = gen_movsi (addr, gen_rtx_REG (Pmode, first));
5447 RTX_FRAME_RELATED_P (insn) = 1;
5448 return insn;
5452 insn = gen_store_multiple (addr,
5453 gen_rtx_REG (Pmode, first),
5454 GEN_INT (last - first + 1));
5457 /* We need to set the FRAME_RELATED flag on all SETs
5458 inside the store-multiple pattern.
5460 However, we must not emit DWARF records for registers 2..5
5461 if they are stored for use by variable arguments ...
5463 ??? Unfortunately, it is not enough to simply not the the
5464 FRAME_RELATED flags for those SETs, because the first SET
5465 of the PARALLEL is always treated as if it had the flag
5466 set, even if it does not. Therefore we emit a new pattern
5467 without those registers as REG_FRAME_RELATED_EXPR note. */
5469 if (first >= 6)
5471 rtx pat = PATTERN (insn);
5473 for (i = 0; i < XVECLEN (pat, 0); i++)
5474 if (GET_CODE (XVECEXP (pat, 0, i)) == SET)
5475 RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1;
5477 RTX_FRAME_RELATED_P (insn) = 1;
5479 else if (last >= 6)
5481 addr = plus_constant (base, offset + 6 * UNITS_PER_WORD);
5482 note = gen_store_multiple (gen_rtx_MEM (Pmode, addr),
5483 gen_rtx_REG (Pmode, 6),
5484 GEN_INT (last - 6 + 1));
5485 note = PATTERN (note);
5487 REG_NOTES (insn) =
5488 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
5489 note, REG_NOTES (insn));
5491 for (i = 0; i < XVECLEN (note, 0); i++)
5492 if (GET_CODE (XVECEXP (note, 0, i)) == SET)
5493 RTX_FRAME_RELATED_P (XVECEXP (note, 0, i)) = 1;
5495 RTX_FRAME_RELATED_P (insn) = 1;
5498 return insn;
5501 /* Generate insn to restore registers FIRST to LAST from
5502 the register save area located at offset OFFSET
5503 relative to register BASE. */
5505 static rtx
5506 restore_gprs (rtx base, int offset, int first, int last)
5508 rtx addr, insn;
5510 addr = plus_constant (base, offset + first * UNITS_PER_WORD);
5511 addr = gen_rtx_MEM (Pmode, addr);
5512 set_mem_alias_set (addr, s390_sr_alias_set);
5514 /* Special-case single register. */
5515 if (first == last)
5517 if (TARGET_64BIT)
5518 insn = gen_movdi (gen_rtx_REG (Pmode, first), addr);
5519 else
5520 insn = gen_movsi (gen_rtx_REG (Pmode, first), addr);
5522 return insn;
5525 insn = gen_load_multiple (gen_rtx_REG (Pmode, first),
5526 addr,
5527 GEN_INT (last - first + 1));
5528 return insn;
5531 /* Emit code to load the GOT register. If MAYBE_DEAD is true,
5532 annotate generated insns with REG_MAYBE_DEAD notes. */
5534 static GTY(()) rtx got_symbol;
5535 void
5536 s390_load_got (int maybe_dead)
5538 if (!got_symbol)
5540 got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5541 SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
5544 if (TARGET_CPU_ZARCH)
5546 rtx insn = emit_move_insn (pic_offset_table_rtx, got_symbol);
5547 if (maybe_dead)
5548 REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
5549 REG_NOTES (insn));
5551 else
5553 rtx offset, insn;
5555 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got_symbol),
5556 UNSPEC_LTREL_OFFSET);
5557 offset = gen_rtx_CONST (Pmode, offset);
5558 offset = force_const_mem (Pmode, offset);
5560 insn = emit_move_insn (pic_offset_table_rtx, offset);
5561 if (maybe_dead)
5562 REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
5563 REG_NOTES (insn));
5565 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (offset, 0)),
5566 UNSPEC_LTREL_BASE);
5567 offset = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, offset);
5569 insn = emit_move_insn (pic_offset_table_rtx, offset);
5570 if (maybe_dead)
5571 REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
5572 REG_NOTES (insn));
5576 /* Expand the prologue into a bunch of separate insns. */
5578 void
5579 s390_emit_prologue (void)
5581 rtx insn, addr;
5582 rtx temp_reg;
5583 int i;
5585 /* Compute frame_info. */
5587 s390_frame_info ();
5589 /* Choose best register to use for temp use within prologue.
5590 See below for why TPF must use the register 1. */
5592 if (!current_function_is_leaf
5593 && !TARGET_TPF)
5594 temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
5595 else
5596 temp_reg = gen_rtx_REG (Pmode, 1);
5598 /* Save call saved gprs. */
5600 insn = save_gprs (stack_pointer_rtx, 0,
5601 cfun->machine->first_save_gpr, cfun->machine->last_save_gpr);
5602 emit_insn (insn);
5604 /* Dummy insn to mark literal pool slot. */
5606 emit_insn (gen_main_pool ());
5608 /* Save fprs for variable args. */
5610 if (current_function_stdarg)
5611 for (i = 16; i < (TARGET_64BIT ? 20 : 18); i++)
5612 save_fpr (stack_pointer_rtx, 16*UNITS_PER_WORD + 8*(i-16), i);
5614 /* Save fprs 4 and 6 if used (31 bit ABI). */
5616 if (!TARGET_64BIT)
5617 for (i = 18; i < 20; i++)
5618 if (regs_ever_live[i] && !global_regs[i])
5620 insn = save_fpr (stack_pointer_rtx, 16*UNITS_PER_WORD + 8*(i-16), i);
5621 RTX_FRAME_RELATED_P (insn) = 1;
5624 /* Decrement stack pointer. */
5626 if (cfun->machine->frame_size > 0)
5628 rtx frame_off = GEN_INT (-cfun->machine->frame_size);
5630 /* Save incoming stack pointer into temp reg. */
5632 if (TARGET_BACKCHAIN || cfun->machine->save_fprs_p)
5634 insn = emit_insn (gen_move_insn (temp_reg, stack_pointer_rtx));
5637 /* Subtract frame size from stack pointer. */
5639 if (DISP_IN_RANGE (INTVAL (frame_off)))
5641 insn = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
5642 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
5643 frame_off));
5644 insn = emit_insn (insn);
5646 else
5648 if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off), 'K', "K"))
5649 frame_off = force_const_mem (Pmode, frame_off);
5651 insn = emit_insn (gen_add2_insn (stack_pointer_rtx, frame_off));
5654 RTX_FRAME_RELATED_P (insn) = 1;
5655 REG_NOTES (insn) =
5656 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
5657 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
5658 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
5659 GEN_INT (-cfun->machine->frame_size))),
5660 REG_NOTES (insn));
5662 /* Set backchain. */
5664 if (TARGET_BACKCHAIN)
5666 addr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
5667 set_mem_alias_set (addr, s390_sr_alias_set);
5668 insn = emit_insn (gen_move_insn (addr, temp_reg));
5671 /* If we support asynchronous exceptions (e.g. for Java),
5672 we need to make sure the backchain pointer is set up
5673 before any possibly trapping memory access. */
5675 if (TARGET_BACKCHAIN && flag_non_call_exceptions)
5677 addr = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
5678 emit_insn (gen_rtx_CLOBBER (VOIDmode, addr));
5682 /* Save fprs 8 - 15 (64 bit ABI). */
5684 if (cfun->machine->save_fprs_p)
5686 insn = emit_insn (gen_add2_insn (temp_reg, GEN_INT(-64)));
5688 for (i = 24; i < 32; i++)
5689 if (regs_ever_live[i] && !global_regs[i])
5691 rtx addr = plus_constant (stack_pointer_rtx,
5692 cfun->machine->frame_size - 64 + (i-24)*8);
5694 insn = save_fpr (temp_reg, (i-24)*8, i);
5695 RTX_FRAME_RELATED_P (insn) = 1;
5696 REG_NOTES (insn) =
5697 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
5698 gen_rtx_SET (VOIDmode,
5699 gen_rtx_MEM (DFmode, addr),
5700 gen_rtx_REG (DFmode, i)),
5701 REG_NOTES (insn));
5705 /* Set frame pointer, if needed. */
5707 if (frame_pointer_needed)
5709 insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
5710 RTX_FRAME_RELATED_P (insn) = 1;
5713 /* Set up got pointer, if needed. */
5715 if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
5716 s390_load_got(true);
5718 if (TARGET_TPF)
5720 /* Generate a BAS instruction to serve as a function
5721 entry intercept to facilitate the use of tracing
5722 algorithms located at the branch target.
5724 This must use register 1. */
5725 rtx addr;
5726 rtx unkn;
5727 rtx link;
5729 addr = GEN_INT (0xfe0);
5730 unkn = CONST0_RTX (SImode);
5731 link = gen_rtx_REG (Pmode, 1);
5733 emit_call_insn (gen_call_exp (gen_rtx_MEM (QImode, addr), unkn, link));
5735 /* Emit a blockage here so that all code
5736 lies between the profiling mechanisms. */
5737 emit_insn (gen_blockage ());
5741 /* Expand the epilogue into a bunch of separate insns. */
5743 void
5744 s390_emit_epilogue (void)
5746 rtx frame_pointer, return_reg;
5747 int area_bottom, area_top, offset = 0;
5748 rtvec p;
5749 int i;
5751 if (TARGET_TPF)
5754 /* Generate a BAS instruction to serve as a function
5755 entry intercept to facilitate the use of tracing
5756 algorithms located at the branch target.
5758 This must use register 1. */
5760 rtx addr;
5761 rtx unkn;
5762 rtx link;
5764 addr = GEN_INT (0xfe6);
5765 unkn = CONST0_RTX (SImode);
5766 link = gen_rtx_REG (Pmode, 1);
5768 /* Emit a blockage here so that all code
5769 lies between the profiling mechanisms. */
5770 emit_insn (gen_blockage ());
5772 emit_call_insn (gen_call_exp (gen_rtx_MEM (QImode, addr), unkn, link));
5775 /* Check whether to use frame or stack pointer for restore. */
5777 frame_pointer = frame_pointer_needed ?
5778 hard_frame_pointer_rtx : stack_pointer_rtx;
5780 /* Compute which parts of the save area we need to access. */
5782 if (cfun->machine->first_restore_gpr != -1)
5784 area_bottom = cfun->machine->first_restore_gpr * UNITS_PER_WORD;
5785 area_top = (cfun->machine->last_save_gpr + 1) * UNITS_PER_WORD;
5787 else
5789 area_bottom = INT_MAX;
5790 area_top = INT_MIN;
5793 if (TARGET_64BIT)
5795 if (cfun->machine->save_fprs_p)
5797 if (area_bottom > -64)
5798 area_bottom = -64;
5799 if (area_top < 0)
5800 area_top = 0;
5803 else
5805 for (i = 18; i < 20; i++)
5806 if (regs_ever_live[i] && !global_regs[i])
5808 if (area_bottom > 16*UNITS_PER_WORD + 8*(i-16))
5809 area_bottom = 16*UNITS_PER_WORD + 8*(i-16);
5810 if (area_top < 16*UNITS_PER_WORD + 8*(i-16) + 8)
5811 area_top = 16*UNITS_PER_WORD + 8*(i-16) + 8;
5815 /* Check whether we can access the register save area.
5816 If not, increment the frame pointer as required. */
5818 if (area_top <= area_bottom)
5820 /* Nothing to restore. */
5822 else if (DISP_IN_RANGE (cfun->machine->frame_size + area_bottom)
5823 && DISP_IN_RANGE (cfun->machine->frame_size + area_top-1))
5825 /* Area is in range. */
5826 offset = cfun->machine->frame_size;
5828 else
5830 rtx insn, frame_off;
5832 offset = area_bottom < 0 ? -area_bottom : 0;
5833 frame_off = GEN_INT (cfun->machine->frame_size - offset);
5835 if (DISP_IN_RANGE (INTVAL (frame_off)))
5837 insn = gen_rtx_SET (VOIDmode, frame_pointer,
5838 gen_rtx_PLUS (Pmode, frame_pointer, frame_off));
5839 insn = emit_insn (insn);
5841 else
5843 if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off), 'K', "K"))
5844 frame_off = force_const_mem (Pmode, frame_off);
5846 insn = emit_insn (gen_add2_insn (frame_pointer, frame_off));
5850 /* Restore call saved fprs. */
5852 if (TARGET_64BIT)
5854 if (cfun->machine->save_fprs_p)
5855 for (i = 24; i < 32; i++)
5856 if (regs_ever_live[i] && !global_regs[i])
5857 restore_fpr (frame_pointer,
5858 offset - 64 + (i-24) * 8, i);
5860 else
5862 for (i = 18; i < 20; i++)
5863 if (regs_ever_live[i] && !global_regs[i])
5864 restore_fpr (frame_pointer,
5865 offset + 16*UNITS_PER_WORD + 8*(i-16), i);
5868 /* Return register. */
5870 return_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
5872 /* Restore call saved gprs. */
5874 if (cfun->machine->first_restore_gpr != -1)
5876 rtx insn, addr;
5877 int i;
5879 /* Check for global register and save them
5880 to stack location from where they get restored. */
5882 for (i = cfun->machine->first_restore_gpr;
5883 i <= cfun->machine->last_save_gpr;
5884 i++)
5886 /* These registers are special and need to be
5887 restored in any case. */
5888 if (i == STACK_POINTER_REGNUM
5889 || i == RETURN_REGNUM
5890 || i == BASE_REGISTER
5891 || (flag_pic && i == (int)PIC_OFFSET_TABLE_REGNUM))
5892 continue;
5894 if (global_regs[i])
5896 addr = plus_constant (frame_pointer,
5897 offset + i * UNITS_PER_WORD);
5898 addr = gen_rtx_MEM (Pmode, addr);
5899 set_mem_alias_set (addr, s390_sr_alias_set);
5900 emit_move_insn (addr, gen_rtx_REG (Pmode, i));
5904 /* Fetch return address from stack before load multiple,
5905 this will do good for scheduling. */
5907 if (cfun->machine->save_return_addr_p
5908 || (cfun->machine->first_restore_gpr < BASE_REGISTER
5909 && cfun->machine->last_save_gpr > RETURN_REGNUM))
5911 int return_regnum = find_unused_clobbered_reg();
5912 if (!return_regnum)
5913 return_regnum = 4;
5914 return_reg = gen_rtx_REG (Pmode, return_regnum);
5916 addr = plus_constant (frame_pointer,
5917 offset + RETURN_REGNUM * UNITS_PER_WORD);
5918 addr = gen_rtx_MEM (Pmode, addr);
5919 set_mem_alias_set (addr, s390_sr_alias_set);
5920 emit_move_insn (return_reg, addr);
5923 /* ??? As references to the base register are not made
5924 explicit in insn RTX code, we have to add a barrier here
5925 to prevent incorrect scheduling. */
5927 emit_insn (gen_blockage());
5929 insn = restore_gprs (frame_pointer, offset,
5930 cfun->machine->first_restore_gpr,
5931 cfun->machine->last_save_gpr);
5932 emit_insn (insn);
5935 /* Return to caller. */
5937 p = rtvec_alloc (2);
5939 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
5940 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, return_reg);
5941 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
5945 /* Return the size in bytes of a function argument of
5946 type TYPE and/or mode MODE. At least one of TYPE or
5947 MODE must be specified. */
5949 static int
5950 s390_function_arg_size (enum machine_mode mode, tree type)
5952 if (type)
5953 return int_size_in_bytes (type);
5955 /* No type info available for some library calls ... */
5956 if (mode != BLKmode)
5957 return GET_MODE_SIZE (mode);
5959 /* If we have neither type nor mode, abort */
5960 abort ();
5963 /* Return true if a function argument of type TYPE and mode MODE
5964 is to be passed in a floating-point register, if available. */
5966 static bool
5967 s390_function_arg_float (enum machine_mode mode, tree type)
5969 int size = s390_function_arg_size (mode, type);
5970 if (size > 8)
5971 return false;
5973 /* Soft-float changes the ABI: no floating-point registers are used. */
5974 if (TARGET_SOFT_FLOAT)
5975 return false;
5977 /* No type info available for some library calls ... */
5978 if (!type)
5979 return mode == SFmode || mode == DFmode;
5981 /* The ABI says that record types with a single member are treated
5982 just like that member would be. */
5983 while (TREE_CODE (type) == RECORD_TYPE)
5985 tree field, single = NULL_TREE;
5987 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
5989 if (TREE_CODE (field) != FIELD_DECL)
5990 continue;
5992 if (single == NULL_TREE)
5993 single = TREE_TYPE (field);
5994 else
5995 return false;
5998 if (single == NULL_TREE)
5999 return false;
6000 else
6001 type = single;
6004 return TREE_CODE (type) == REAL_TYPE;
6007 /* Return true if a function argument of type TYPE and mode MODE
6008 is to be passed in an integer register, or a pair of integer
6009 registers, if available. */
6011 static bool
6012 s390_function_arg_integer (enum machine_mode mode, tree type)
6014 int size = s390_function_arg_size (mode, type);
6015 if (size > 8)
6016 return false;
6018 /* No type info available for some library calls ... */
6019 if (!type)
6020 return GET_MODE_CLASS (mode) == MODE_INT
6021 || (TARGET_SOFT_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT);
6023 /* We accept small integral (and similar) types. */
6024 if (INTEGRAL_TYPE_P (type)
6025 || POINTER_TYPE_P (type)
6026 || TREE_CODE (type) == OFFSET_TYPE
6027 || (TARGET_SOFT_FLOAT && TREE_CODE (type) == REAL_TYPE))
6028 return true;
6030 /* We also accept structs of size 1, 2, 4, 8 that are not
6031 passed in floating-point registers. */
6032 if (AGGREGATE_TYPE_P (type)
6033 && exact_log2 (size) >= 0
6034 && !s390_function_arg_float (mode, type))
6035 return true;
6037 return false;
6040 /* Return 1 if a function argument of type TYPE and mode MODE
6041 is to be passed by reference. The ABI specifies that only
6042 structures of size 1, 2, 4, or 8 bytes are passed by value,
6043 all other structures (and complex numbers) are passed by
6044 reference. */
6047 s390_function_arg_pass_by_reference (enum machine_mode mode, tree type)
6049 int size = s390_function_arg_size (mode, type);
6050 if (size > 8)
6051 return true;
6053 if (type)
6055 if (AGGREGATE_TYPE_P (type) && exact_log2 (size) < 0)
6056 return 1;
6058 if (TREE_CODE (type) == COMPLEX_TYPE
6059 || TREE_CODE (type) == VECTOR_TYPE)
6060 return 1;
6063 return 0;
6066 /* Update the data in CUM to advance over an argument of mode MODE and
6067 data type TYPE. (TYPE is null for libcalls where that information
6068 may not be available.). The boolean NAMED specifies whether the
6069 argument is a named argument (as opposed to an unnamed argument
6070 matching an ellipsis). */
6072 void
6073 s390_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
6074 tree type, int named ATTRIBUTE_UNUSED)
6076 if (s390_function_arg_pass_by_reference (mode, type))
6078 cum->gprs += 1;
6080 else if (s390_function_arg_float (mode, type))
6082 cum->fprs += 1;
6084 else if (s390_function_arg_integer (mode, type))
6086 int size = s390_function_arg_size (mode, type);
6087 cum->gprs += ((size + UNITS_PER_WORD-1) / UNITS_PER_WORD);
6089 else
6090 abort ();
6093 /* Define where to put the arguments to a function.
6094 Value is zero to push the argument on the stack,
6095 or a hard register in which to store the argument.
6097 MODE is the argument's machine mode.
6098 TYPE is the data type of the argument (as a tree).
6099 This is null for libcalls where that information may
6100 not be available.
6101 CUM is a variable of type CUMULATIVE_ARGS which gives info about
6102 the preceding args and about the function being called.
6103 NAMED is nonzero if this argument is a named parameter
6104 (otherwise it is an extra parameter matching an ellipsis).
6106 On S/390, we use general purpose registers 2 through 6 to
6107 pass integer, pointer, and certain structure arguments, and
6108 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
6109 to pass floating point arguments. All remaining arguments
6110 are pushed to the stack. */
6113 s390_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
6114 int named ATTRIBUTE_UNUSED)
6116 if (s390_function_arg_pass_by_reference (mode, type))
6117 return 0;
6119 if (s390_function_arg_float (mode, type))
6121 if (cum->fprs + 1 > (TARGET_64BIT? 4 : 2))
6122 return 0;
6123 else
6124 return gen_rtx (REG, mode, cum->fprs + 16);
6126 else if (s390_function_arg_integer (mode, type))
6128 int size = s390_function_arg_size (mode, type);
6129 int n_gprs = (size + UNITS_PER_WORD-1) / UNITS_PER_WORD;
6131 if (cum->gprs + n_gprs > 5)
6132 return 0;
6133 else
6134 return gen_rtx (REG, mode, cum->gprs + 2);
6137 /* After the real arguments, expand_call calls us once again
6138 with a void_type_node type. Whatever we return here is
6139 passed as operand 2 to the call expanders.
6141 We don't need this feature ... */
6142 else if (type == void_type_node)
6143 return const0_rtx;
6145 abort ();
6148 /* Return true if return values of type TYPE should be returned
6149 in a memory buffer whose address is passed by the caller as
6150 hidden first argument. */
6152 static bool
6153 s390_return_in_memory (tree type, tree fundecl ATTRIBUTE_UNUSED)
6155 /* We accept small integral (and similar) types. */
6156 if (INTEGRAL_TYPE_P (type)
6157 || POINTER_TYPE_P (type)
6158 || TREE_CODE (type) == OFFSET_TYPE
6159 || TREE_CODE (type) == REAL_TYPE)
6160 return int_size_in_bytes (type) > 8;
6162 /* Aggregates and similar constructs are always returned
6163 in memory. */
6164 if (AGGREGATE_TYPE_P (type)
6165 || TREE_CODE (type) == COMPLEX_TYPE
6166 || TREE_CODE (type) == VECTOR_TYPE)
6167 return true;
6169 /* ??? We get called on all sorts of random stuff from
6170 aggregate_value_p. We can't abort, but it's not clear
6171 what's safe to return. Pretend it's a struct I guess. */
6172 return true;
6175 /* Define where to return a (scalar) value of type TYPE.
6176 If TYPE is null, define where to return a (scalar)
6177 value of mode MODE from a libcall. */
6180 s390_function_value (tree type, enum machine_mode mode)
6182 if (type)
6184 int unsignedp = TREE_UNSIGNED (type);
6185 mode = promote_mode (type, TYPE_MODE (type), &unsignedp, 1);
6188 if (GET_MODE_CLASS (mode) != MODE_INT
6189 && GET_MODE_CLASS (mode) != MODE_FLOAT)
6190 abort ();
6191 if (GET_MODE_SIZE (mode) > 8)
6192 abort ();
6194 if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT)
6195 return gen_rtx_REG (mode, 16);
6196 else
6197 return gen_rtx_REG (mode, 2);
6201 /* Create and return the va_list datatype.
6203 On S/390, va_list is an array type equivalent to
6205 typedef struct __va_list_tag
6207 long __gpr;
6208 long __fpr;
6209 void *__overflow_arg_area;
6210 void *__reg_save_area;
6211 } va_list[1];
6213 where __gpr and __fpr hold the number of general purpose
6214 or floating point arguments used up to now, respectively,
6215 __overflow_arg_area points to the stack location of the
6216 next argument passed on the stack, and __reg_save_area
6217 always points to the start of the register area in the
6218 call frame of the current function. The function prologue
6219 saves all registers used for argument passing into this
6220 area if the function uses variable arguments. */
6222 static tree
6223 s390_build_builtin_va_list (void)
6225 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
6227 record = lang_hooks.types.make_type (RECORD_TYPE);
6229 type_decl =
6230 build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
6232 f_gpr = build_decl (FIELD_DECL, get_identifier ("__gpr"),
6233 long_integer_type_node);
6234 f_fpr = build_decl (FIELD_DECL, get_identifier ("__fpr"),
6235 long_integer_type_node);
6236 f_ovf = build_decl (FIELD_DECL, get_identifier ("__overflow_arg_area"),
6237 ptr_type_node);
6238 f_sav = build_decl (FIELD_DECL, get_identifier ("__reg_save_area"),
6239 ptr_type_node);
6241 DECL_FIELD_CONTEXT (f_gpr) = record;
6242 DECL_FIELD_CONTEXT (f_fpr) = record;
6243 DECL_FIELD_CONTEXT (f_ovf) = record;
6244 DECL_FIELD_CONTEXT (f_sav) = record;
6246 TREE_CHAIN (record) = type_decl;
6247 TYPE_NAME (record) = type_decl;
6248 TYPE_FIELDS (record) = f_gpr;
6249 TREE_CHAIN (f_gpr) = f_fpr;
6250 TREE_CHAIN (f_fpr) = f_ovf;
6251 TREE_CHAIN (f_ovf) = f_sav;
6253 layout_type (record);
6255 /* The correct type is an array type of one element. */
6256 return build_array_type (record, build_index_type (size_zero_node));
6259 /* Implement va_start by filling the va_list structure VALIST.
6260 STDARG_P is always true, and ignored.
6261 NEXTARG points to the first anonymous stack argument.
6263 The following global variables are used to initialize
6264 the va_list structure:
6266 current_function_args_info:
6267 holds number of gprs and fprs used for named arguments.
6268 current_function_arg_offset_rtx:
6269 holds the offset of the first anonymous stack argument
6270 (relative to the virtual arg pointer). */
6272 void
6273 s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
6275 HOST_WIDE_INT n_gpr, n_fpr;
6276 int off;
6277 tree f_gpr, f_fpr, f_ovf, f_sav;
6278 tree gpr, fpr, ovf, sav, t;
6280 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
6281 f_fpr = TREE_CHAIN (f_gpr);
6282 f_ovf = TREE_CHAIN (f_fpr);
6283 f_sav = TREE_CHAIN (f_ovf);
6285 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
6286 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
6287 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
6288 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
6289 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
6291 /* Count number of gp and fp argument registers used. */
6293 n_gpr = current_function_args_info.gprs;
6294 n_fpr = current_function_args_info.fprs;
6296 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, build_int_2 (n_gpr, 0));
6297 TREE_SIDE_EFFECTS (t) = 1;
6298 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6300 t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr, build_int_2 (n_fpr, 0));
6301 TREE_SIDE_EFFECTS (t) = 1;
6302 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6304 /* Find the overflow area. */
6305 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
6307 off = INTVAL (current_function_arg_offset_rtx);
6308 off = off < 0 ? 0 : off;
6309 if (TARGET_DEBUG_ARG)
6310 fprintf (stderr, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
6311 (int)n_gpr, (int)n_fpr, off);
6313 t = build (PLUS_EXPR, TREE_TYPE (ovf), t, build_int_2 (off, 0));
6315 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
6316 TREE_SIDE_EFFECTS (t) = 1;
6317 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6319 /* Find the register save area. */
6320 t = make_tree (TREE_TYPE (sav), virtual_incoming_args_rtx);
6321 t = build (PLUS_EXPR, TREE_TYPE (sav), t,
6322 build_int_2 (-STACK_POINTER_OFFSET, -1));
6323 t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
6324 TREE_SIDE_EFFECTS (t) = 1;
6325 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6328 /* Implement va_arg by updating the va_list structure
6329 VALIST as required to retrieve an argument of type
6330 TYPE, and returning that argument.
6332 Generates code equivalent to:
6334 if (integral value) {
6335 if (size <= 4 && args.gpr < 5 ||
6336 size > 4 && args.gpr < 4 )
6337 ret = args.reg_save_area[args.gpr+8]
6338 else
6339 ret = *args.overflow_arg_area++;
6340 } else if (float value) {
6341 if (args.fgpr < 2)
6342 ret = args.reg_save_area[args.fpr+64]
6343 else
6344 ret = *args.overflow_arg_area++;
6345 } else if (aggregate value) {
6346 if (args.gpr < 5)
6347 ret = *args.reg_save_area[args.gpr]
6348 else
6349 ret = **args.overflow_arg_area++;
6350 } */
6353 s390_va_arg (tree valist, tree type)
6355 tree f_gpr, f_fpr, f_ovf, f_sav;
6356 tree gpr, fpr, ovf, sav, reg, t, u;
6357 int indirect_p, size, n_reg, sav_ofs, sav_scale, max_reg;
6358 rtx lab_false, lab_over, addr_rtx, r;
6360 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
6361 f_fpr = TREE_CHAIN (f_gpr);
6362 f_ovf = TREE_CHAIN (f_fpr);
6363 f_sav = TREE_CHAIN (f_ovf);
6365 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
6366 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
6367 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
6368 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
6369 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
6371 size = int_size_in_bytes (type);
6373 if (s390_function_arg_pass_by_reference (TYPE_MODE (type), type))
6375 if (TARGET_DEBUG_ARG)
6377 fprintf (stderr, "va_arg: aggregate type");
6378 debug_tree (type);
6381 /* Aggregates are passed by reference. */
6382 indirect_p = 1;
6383 reg = gpr;
6384 n_reg = 1;
6385 sav_ofs = 2 * UNITS_PER_WORD;
6386 sav_scale = UNITS_PER_WORD;
6387 size = UNITS_PER_WORD;
6388 max_reg = 4;
6390 else if (s390_function_arg_float (TYPE_MODE (type), type))
6392 if (TARGET_DEBUG_ARG)
6394 fprintf (stderr, "va_arg: float type");
6395 debug_tree (type);
6398 /* FP args go in FP registers, if present. */
6399 indirect_p = 0;
6400 reg = fpr;
6401 n_reg = 1;
6402 sav_ofs = 16 * UNITS_PER_WORD;
6403 sav_scale = 8;
6404 /* TARGET_64BIT has up to 4 parameter in fprs */
6405 max_reg = TARGET_64BIT ? 3 : 1;
6407 else
6409 if (TARGET_DEBUG_ARG)
6411 fprintf (stderr, "va_arg: other type");
6412 debug_tree (type);
6415 /* Otherwise into GP registers. */
6416 indirect_p = 0;
6417 reg = gpr;
6418 n_reg = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6419 sav_ofs = 2 * UNITS_PER_WORD;
6421 if (size < UNITS_PER_WORD)
6422 sav_ofs += UNITS_PER_WORD - size;
6424 sav_scale = UNITS_PER_WORD;
6425 if (n_reg > 1)
6426 max_reg = 3;
6427 else
6428 max_reg = 4;
6431 /* Pull the value out of the saved registers ... */
6433 lab_false = gen_label_rtx ();
6434 lab_over = gen_label_rtx ();
6435 addr_rtx = gen_reg_rtx (Pmode);
6437 emit_cmp_and_jump_insns (expand_expr (reg, NULL_RTX, Pmode, EXPAND_NORMAL),
6438 GEN_INT (max_reg),
6439 GT, const1_rtx, Pmode, 0, lab_false);
6441 if (sav_ofs)
6442 t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
6443 else
6444 t = sav;
6446 u = build (MULT_EXPR, long_integer_type_node,
6447 reg, build_int_2 (sav_scale, 0));
6448 TREE_SIDE_EFFECTS (u) = 1;
6450 t = build (PLUS_EXPR, ptr_type_node, t, u);
6451 TREE_SIDE_EFFECTS (t) = 1;
6453 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
6454 if (r != addr_rtx)
6455 emit_move_insn (addr_rtx, r);
6458 emit_jump_insn (gen_jump (lab_over));
6459 emit_barrier ();
6460 emit_label (lab_false);
6462 /* ... Otherwise out of the overflow area. */
6464 t = save_expr (ovf);
6467 /* In 64 BIT for each argument on stack, a full 64 bit slot is allocated. */
6468 if (size < UNITS_PER_WORD)
6470 t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (UNITS_PER_WORD-size, 0));
6471 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
6472 TREE_SIDE_EFFECTS (t) = 1;
6473 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6475 t = save_expr (ovf);
6478 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
6479 if (r != addr_rtx)
6480 emit_move_insn (addr_rtx, r);
6482 t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (size, 0));
6483 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
6484 TREE_SIDE_EFFECTS (t) = 1;
6485 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6487 emit_label (lab_over);
6489 /* If less than max_regs a registers are retrieved out
6490 of register save area, increment. */
6492 u = build (PREINCREMENT_EXPR, TREE_TYPE (reg), reg,
6493 build_int_2 (n_reg, 0));
6494 TREE_SIDE_EFFECTS (u) = 1;
6495 expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
6497 if (indirect_p)
6499 r = gen_rtx_MEM (Pmode, addr_rtx);
6500 set_mem_alias_set (r, get_varargs_alias_set ());
6501 emit_move_insn (addr_rtx, r);
6505 return addr_rtx;
6509 /* Builtins. */
6511 enum s390_builtin
6513 S390_BUILTIN_THREAD_POINTER,
6514 S390_BUILTIN_SET_THREAD_POINTER,
6516 S390_BUILTIN_max
6519 static unsigned int const code_for_builtin_64[S390_BUILTIN_max] = {
6520 CODE_FOR_get_tp_64,
6521 CODE_FOR_set_tp_64
6524 static unsigned int const code_for_builtin_31[S390_BUILTIN_max] = {
6525 CODE_FOR_get_tp_31,
6526 CODE_FOR_set_tp_31
6529 static void
6530 s390_init_builtins (void)
6532 tree ftype;
6534 ftype = build_function_type (ptr_type_node, void_list_node);
6535 builtin_function ("__builtin_thread_pointer", ftype,
6536 S390_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
6537 NULL, NULL_TREE);
6539 ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
6540 builtin_function ("__builtin_set_thread_pointer", ftype,
6541 S390_BUILTIN_SET_THREAD_POINTER, BUILT_IN_MD,
6542 NULL, NULL_TREE);
6545 /* Expand an expression EXP that calls a built-in function,
6546 with result going to TARGET if that's convenient
6547 (and in mode MODE if that's convenient).
6548 SUBTARGET may be used as the target for computing one of EXP's operands.
6549 IGNORE is nonzero if the value is to be ignored. */
6551 static rtx
6552 s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
6553 enum machine_mode mode ATTRIBUTE_UNUSED,
6554 int ignore ATTRIBUTE_UNUSED)
6556 #define MAX_ARGS 2
6558 unsigned int const *code_for_builtin =
6559 TARGET_64BIT ? code_for_builtin_64 : code_for_builtin_31;
6561 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
6562 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
6563 tree arglist = TREE_OPERAND (exp, 1);
6564 enum insn_code icode;
6565 rtx op[MAX_ARGS], pat;
6566 int arity;
6567 bool nonvoid;
6569 if (fcode >= S390_BUILTIN_max)
6570 internal_error ("bad builtin fcode");
6571 icode = code_for_builtin[fcode];
6572 if (icode == 0)
6573 internal_error ("bad builtin fcode");
6575 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
6577 for (arglist = TREE_OPERAND (exp, 1), arity = 0;
6578 arglist;
6579 arglist = TREE_CHAIN (arglist), arity++)
6581 const struct insn_operand_data *insn_op;
6583 tree arg = TREE_VALUE (arglist);
6584 if (arg == error_mark_node)
6585 return NULL_RTX;
6586 if (arity > MAX_ARGS)
6587 return NULL_RTX;
6589 insn_op = &insn_data[icode].operand[arity + nonvoid];
6591 op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, 0);
6593 if (!(*insn_op->predicate) (op[arity], insn_op->mode))
6594 op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
6597 if (nonvoid)
6599 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6600 if (!target
6601 || GET_MODE (target) != tmode
6602 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
6603 target = gen_reg_rtx (tmode);
6606 switch (arity)
6608 case 0:
6609 pat = GEN_FCN (icode) (target);
6610 break;
6611 case 1:
6612 if (nonvoid)
6613 pat = GEN_FCN (icode) (target, op[0]);
6614 else
6615 pat = GEN_FCN (icode) (op[0]);
6616 break;
6617 case 2:
6618 pat = GEN_FCN (icode) (target, op[0], op[1]);
6619 break;
6620 default:
6621 abort ();
6623 if (!pat)
6624 return NULL_RTX;
6625 emit_insn (pat);
6627 if (nonvoid)
6628 return target;
6629 else
6630 return const0_rtx;
6634 /* Output assembly code for the trampoline template to
6635 stdio stream FILE.
6637 On S/390, we use gpr 1 internally in the trampoline code;
6638 gpr 0 is used to hold the static chain. */
6640 void
6641 s390_trampoline_template (FILE *file)
6643 if (TARGET_64BIT)
6645 fprintf (file, "larl\t%s,0f\n", reg_names[1]);
6646 fprintf (file, "lg\t%s,0(%s)\n", reg_names[0], reg_names[1]);
6647 fprintf (file, "lg\t%s,8(%s)\n", reg_names[1], reg_names[1]);
6648 fprintf (file, "br\t%s\n", reg_names[1]);
6649 fprintf (file, "0:\t.quad\t0\n");
6650 fprintf (file, ".quad\t0\n");
6652 else
6654 fprintf (file, "basr\t%s,0\n", reg_names[1]);
6655 fprintf (file, "l\t%s,10(%s)\n", reg_names[0], reg_names[1]);
6656 fprintf (file, "l\t%s,14(%s)\n", reg_names[1], reg_names[1]);
6657 fprintf (file, "br\t%s\n", reg_names[1]);
6658 fprintf (file, ".long\t0\n");
6659 fprintf (file, ".long\t0\n");
6663 /* Emit RTL insns to initialize the variable parts of a trampoline.
6664 FNADDR is an RTX for the address of the function's pure code.
6665 CXT is an RTX for the static chain value for the function. */
6667 void
6668 s390_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
6670 emit_move_insn (gen_rtx
6671 (MEM, Pmode,
6672 memory_address (Pmode,
6673 plus_constant (addr, (TARGET_64BIT ? 20 : 12) ))), cxt);
6674 emit_move_insn (gen_rtx
6675 (MEM, Pmode,
6676 memory_address (Pmode,
6677 plus_constant (addr, (TARGET_64BIT ? 28 : 16) ))), fnaddr);
6680 /* Return rtx for 64-bit constant formed from the 32-bit subwords
6681 LOW and HIGH, independent of the host word size. */
6684 s390_gen_rtx_const_DI (int high, int low)
6686 #if HOST_BITS_PER_WIDE_INT >= 64
6687 HOST_WIDE_INT val;
6688 val = (HOST_WIDE_INT)high;
6689 val <<= 32;
6690 val |= (HOST_WIDE_INT)low;
6692 return GEN_INT (val);
6693 #else
6694 #if HOST_BITS_PER_WIDE_INT >= 32
6695 return immed_double_const ((HOST_WIDE_INT)low, (HOST_WIDE_INT)high, DImode);
6696 #else
6697 abort ();
6698 #endif
6699 #endif
6702 /* Output assembler code to FILE to increment profiler label # LABELNO
6703 for profiling a function entry. */
6705 void
6706 s390_function_profiler (FILE *file, int labelno)
6708 rtx op[7];
6710 char label[128];
6711 ASM_GENERATE_INTERNAL_LABEL (label, "LP", labelno);
6713 fprintf (file, "# function profiler \n");
6715 op[0] = gen_rtx_REG (Pmode, RETURN_REGNUM);
6716 op[1] = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
6717 op[1] = gen_rtx_MEM (Pmode, plus_constant (op[1], UNITS_PER_WORD));
6719 op[2] = gen_rtx_REG (Pmode, 1);
6720 op[3] = gen_rtx_SYMBOL_REF (Pmode, label);
6721 SYMBOL_REF_FLAGS (op[3]) = SYMBOL_FLAG_LOCAL;
6723 op[4] = gen_rtx_SYMBOL_REF (Pmode, "_mcount");
6724 if (flag_pic)
6726 op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), UNSPEC_PLT);
6727 op[4] = gen_rtx_CONST (Pmode, op[4]);
6730 if (TARGET_64BIT)
6732 output_asm_insn ("stg\t%0,%1", op);
6733 output_asm_insn ("larl\t%2,%3", op);
6734 output_asm_insn ("brasl\t%0,%4", op);
6735 output_asm_insn ("lg\t%0,%1", op);
6737 else if (!flag_pic)
6739 op[6] = gen_label_rtx ();
6741 output_asm_insn ("st\t%0,%1", op);
6742 output_asm_insn ("bras\t%2,%l6", op);
6743 output_asm_insn (".long\t%4", op);
6744 output_asm_insn (".long\t%3", op);
6745 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
6746 output_asm_insn ("l\t%0,0(%2)", op);
6747 output_asm_insn ("l\t%2,4(%2)", op);
6748 output_asm_insn ("basr\t%0,%0", op);
6749 output_asm_insn ("l\t%0,%1", op);
6751 else
6753 op[5] = gen_label_rtx ();
6754 op[6] = gen_label_rtx ();
6756 output_asm_insn ("st\t%0,%1", op);
6757 output_asm_insn ("bras\t%2,%l6", op);
6758 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[5]));
6759 output_asm_insn (".long\t%4-%l5", op);
6760 output_asm_insn (".long\t%3-%l5", op);
6761 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
6762 output_asm_insn ("lr\t%0,%2", op);
6763 output_asm_insn ("a\t%0,0(%2)", op);
6764 output_asm_insn ("a\t%2,4(%2)", op);
6765 output_asm_insn ("basr\t%0,%0", op);
6766 output_asm_insn ("l\t%0,%1", op);
6770 /* Select section for constant in constant pool. In 32-bit mode,
6771 constants go in the function section; in 64-bit mode in .rodata. */
6773 static void
6774 s390_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED,
6775 rtx x ATTRIBUTE_UNUSED,
6776 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
6778 if (TARGET_CPU_ZARCH)
6779 readonly_data_section ();
6780 else
6781 function_section (current_function_decl);
6784 /* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
6785 into its SYMBOL_REF_FLAGS. */
6787 static void
6788 s390_encode_section_info (tree decl, rtx rtl, int first)
6790 default_encode_section_info (decl, rtl, first);
6792 /* If a variable has a forced alignment to < 2 bytes, mark it with
6793 SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL operand. */
6794 if (TREE_CODE (decl) == VAR_DECL
6795 && DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) < 16)
6796 SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_ALIGN1;
6799 /* Output thunk to FILE that implements a C++ virtual function call (with
6800 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
6801 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
6802 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
6803 relative to the resulting this pointer. */
6805 static void
6806 s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
6807 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
6808 tree function)
6810 rtx op[10];
6811 int nonlocal = 0;
6813 /* Operand 0 is the target function. */
6814 op[0] = XEXP (DECL_RTL (function), 0);
6815 if (flag_pic && !SYMBOL_REF_LOCAL_P (op[0]))
6817 nonlocal = 1;
6818 op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]),
6819 TARGET_64BIT ? UNSPEC_PLT : UNSPEC_GOT);
6820 op[0] = gen_rtx_CONST (Pmode, op[0]);
6823 /* Operand 1 is the 'this' pointer. */
6824 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
6825 op[1] = gen_rtx_REG (Pmode, 3);
6826 else
6827 op[1] = gen_rtx_REG (Pmode, 2);
6829 /* Operand 2 is the delta. */
6830 op[2] = GEN_INT (delta);
6832 /* Operand 3 is the vcall_offset. */
6833 op[3] = GEN_INT (vcall_offset);
6835 /* Operand 4 is the temporary register. */
6836 op[4] = gen_rtx_REG (Pmode, 1);
6838 /* Operands 5 to 8 can be used as labels. */
6839 op[5] = NULL_RTX;
6840 op[6] = NULL_RTX;
6841 op[7] = NULL_RTX;
6842 op[8] = NULL_RTX;
6844 /* Operand 9 can be used for temporary register. */
6845 op[9] = NULL_RTX;
6847 /* Generate code. */
6848 if (TARGET_64BIT)
6850 /* Setup literal pool pointer if required. */
6851 if ((!DISP_IN_RANGE (delta)
6852 && !CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
6853 || (!DISP_IN_RANGE (vcall_offset)
6854 && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K")))
6856 op[5] = gen_label_rtx ();
6857 output_asm_insn ("larl\t%4,%5", op);
6860 /* Add DELTA to this pointer. */
6861 if (delta)
6863 if (CONST_OK_FOR_CONSTRAINT_P (delta, 'J', "J"))
6864 output_asm_insn ("la\t%1,%2(%1)", op);
6865 else if (DISP_IN_RANGE (delta))
6866 output_asm_insn ("lay\t%1,%2(%1)", op);
6867 else if (CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
6868 output_asm_insn ("aghi\t%1,%2", op);
6869 else
6871 op[6] = gen_label_rtx ();
6872 output_asm_insn ("agf\t%1,%6-%5(%4)", op);
6876 /* Perform vcall adjustment. */
6877 if (vcall_offset)
6879 if (DISP_IN_RANGE (vcall_offset))
6881 output_asm_insn ("lg\t%4,0(%1)", op);
6882 output_asm_insn ("ag\t%1,%3(%4)", op);
6884 else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K"))
6886 output_asm_insn ("lghi\t%4,%3", op);
6887 output_asm_insn ("ag\t%4,0(%1)", op);
6888 output_asm_insn ("ag\t%1,0(%4)", op);
6890 else
6892 op[7] = gen_label_rtx ();
6893 output_asm_insn ("llgf\t%4,%7-%5(%4)", op);
6894 output_asm_insn ("ag\t%4,0(%1)", op);
6895 output_asm_insn ("ag\t%1,0(%4)", op);
6899 /* Jump to target. */
6900 output_asm_insn ("jg\t%0", op);
6902 /* Output literal pool if required. */
6903 if (op[5])
6905 output_asm_insn (".align\t4", op);
6906 targetm.asm_out.internal_label (file, "L",
6907 CODE_LABEL_NUMBER (op[5]));
6909 if (op[6])
6911 targetm.asm_out.internal_label (file, "L",
6912 CODE_LABEL_NUMBER (op[6]));
6913 output_asm_insn (".long\t%2", op);
6915 if (op[7])
6917 targetm.asm_out.internal_label (file, "L",
6918 CODE_LABEL_NUMBER (op[7]));
6919 output_asm_insn (".long\t%3", op);
6922 else
6924 /* Setup base pointer if required. */
6925 if (!vcall_offset
6926 || (!DISP_IN_RANGE (delta)
6927 && !CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
6928 || (!DISP_IN_RANGE (delta)
6929 && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K")))
6931 op[5] = gen_label_rtx ();
6932 output_asm_insn ("basr\t%4,0", op);
6933 targetm.asm_out.internal_label (file, "L",
6934 CODE_LABEL_NUMBER (op[5]));
6937 /* Add DELTA to this pointer. */
6938 if (delta)
6940 if (CONST_OK_FOR_CONSTRAINT_P (delta, 'J', "J"))
6941 output_asm_insn ("la\t%1,%2(%1)", op);
6942 else if (DISP_IN_RANGE (delta))
6943 output_asm_insn ("lay\t%1,%2(%1)", op);
6944 else if (CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
6945 output_asm_insn ("ahi\t%1,%2", op);
6946 else
6948 op[6] = gen_label_rtx ();
6949 output_asm_insn ("a\t%1,%6-%5(%4)", op);
6953 /* Perform vcall adjustment. */
6954 if (vcall_offset)
6956 if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'J', "J"))
6958 output_asm_insn ("lg\t%4,0(%1)", op);
6959 output_asm_insn ("a\t%1,%3(%4)", op);
6961 else if (DISP_IN_RANGE (vcall_offset))
6963 output_asm_insn ("lg\t%4,0(%1)", op);
6964 output_asm_insn ("ay\t%1,%3(%4)", op);
6966 else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K"))
6968 output_asm_insn ("lhi\t%4,%3", op);
6969 output_asm_insn ("a\t%4,0(%1)", op);
6970 output_asm_insn ("a\t%1,0(%4)", op);
6972 else
6974 op[7] = gen_label_rtx ();
6975 output_asm_insn ("l\t%4,%7-%5(%4)", op);
6976 output_asm_insn ("a\t%4,0(%1)", op);
6977 output_asm_insn ("a\t%1,0(%4)", op);
6980 /* We had to clobber the base pointer register.
6981 Re-setup the base pointer (with a different base). */
6982 op[5] = gen_label_rtx ();
6983 output_asm_insn ("basr\t%4,0", op);
6984 targetm.asm_out.internal_label (file, "L",
6985 CODE_LABEL_NUMBER (op[5]));
6988 /* Jump to target. */
6989 op[8] = gen_label_rtx ();
6991 if (!flag_pic)
6992 output_asm_insn ("l\t%4,%8-%5(%4)", op);
6993 else if (!nonlocal)
6994 output_asm_insn ("a\t%4,%8-%5(%4)", op);
6995 /* We cannot call through .plt, since .plt requires %r12 loaded. */
6996 else if (flag_pic == 1)
6998 output_asm_insn ("a\t%4,%8-%5(%4)", op);
6999 output_asm_insn ("l\t%4,%0(%4)", op);
7001 else if (flag_pic == 2)
7003 op[9] = gen_rtx_REG (Pmode, 0);
7004 output_asm_insn ("l\t%9,%8-4-%5(%4)", op);
7005 output_asm_insn ("a\t%4,%8-%5(%4)", op);
7006 output_asm_insn ("ar\t%4,%9", op);
7007 output_asm_insn ("l\t%4,0(%4)", op);
7010 output_asm_insn ("br\t%4", op);
7012 /* Output literal pool. */
7013 output_asm_insn (".align\t4", op);
7015 if (nonlocal && flag_pic == 2)
7016 output_asm_insn (".long\t%0", op);
7017 if (nonlocal)
7019 op[0] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
7020 SYMBOL_REF_FLAGS (op[0]) = SYMBOL_FLAG_LOCAL;
7023 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[8]));
7024 if (!flag_pic)
7025 output_asm_insn (".long\t%0", op);
7026 else
7027 output_asm_insn (".long\t%0-%5", op);
7029 if (op[6])
7031 targetm.asm_out.internal_label (file, "L",
7032 CODE_LABEL_NUMBER (op[6]));
7033 output_asm_insn (".long\t%2", op);
7035 if (op[7])
7037 targetm.asm_out.internal_label (file, "L",
7038 CODE_LABEL_NUMBER (op[7]));
7039 output_asm_insn (".long\t%3", op);
7044 bool
7045 s390_valid_pointer_mode (enum machine_mode mode)
7047 return (mode == SImode || (TARGET_64BIT && mode == DImode));
7050 /* How to allocate a 'struct machine_function'. */
7052 static struct machine_function *
7053 s390_init_machine_status (void)
7055 return ggc_alloc_cleared (sizeof (struct machine_function));
7058 #include "gt-s390.h"