This commit was manufactured by cvs2svn to create branch
[official-gcc.git] / gcc / config / s390 / s390.c
blobced0bf9010a238ae61cb35bf71e1261232814e4a
1 /* Subroutines used for code generation on IBM S/390 and zSeries
2 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
3 Free Software Foundation, Inc.
4 Contributed by Hartmut Penner (hpenner@de.ibm.com) and
5 Ulrich Weigand (uweigand@de.ibm.com).
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
12 version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to the Free
21 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 02111-1307, USA. */
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "tm_p.h"
31 #include "regs.h"
32 #include "hard-reg-set.h"
33 #include "real.h"
34 #include "insn-config.h"
35 #include "conditions.h"
36 #include "output.h"
37 #include "insn-attr.h"
38 #include "flags.h"
39 #include "except.h"
40 #include "function.h"
41 #include "recog.h"
42 #include "expr.h"
43 #include "reload.h"
44 #include "toplev.h"
45 #include "basic-block.h"
46 #include "integrate.h"
47 #include "ggc.h"
48 #include "target.h"
49 #include "target-def.h"
50 #include "debug.h"
51 #include "langhooks.h"
52 #include "optabs.h"
54 /* Machine-specific symbol_ref flags. */
55 #define SYMBOL_FLAG_ALIGN1 (SYMBOL_FLAG_MACH_DEP << 0)
58 static bool s390_assemble_integer (rtx, unsigned int, int);
59 static void s390_select_rtx_section (enum machine_mode, rtx,
60 unsigned HOST_WIDE_INT);
61 static void s390_encode_section_info (tree, rtx, int);
62 static bool s390_cannot_force_const_mem (rtx);
63 static rtx s390_delegitimize_address (rtx);
64 static bool s390_return_in_memory (tree, tree);
65 static void s390_init_builtins (void);
66 static rtx s390_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
67 static void s390_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
68 HOST_WIDE_INT, tree);
69 static enum attr_type s390_safe_attr_type (rtx);
71 static int s390_adjust_cost (rtx, rtx, rtx, int);
72 static int s390_adjust_priority (rtx, int);
73 static int s390_issue_rate (void);
74 static int s390_use_dfa_pipeline_interface (void);
75 static int s390_first_cycle_multipass_dfa_lookahead (void);
76 static int s390_sched_reorder2 (FILE *, int, rtx *, int *, int);
77 static bool s390_rtx_costs (rtx, int, int, int *);
78 static int s390_address_cost (rtx);
79 static void s390_reorg (void);
80 static bool s390_valid_pointer_mode (enum machine_mode);
81 static tree s390_build_builtin_va_list (void);
83 #undef TARGET_ASM_ALIGNED_HI_OP
84 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
85 #undef TARGET_ASM_ALIGNED_DI_OP
86 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
87 #undef TARGET_ASM_INTEGER
88 #define TARGET_ASM_INTEGER s390_assemble_integer
90 #undef TARGET_ASM_OPEN_PAREN
91 #define TARGET_ASM_OPEN_PAREN ""
93 #undef TARGET_ASM_CLOSE_PAREN
94 #define TARGET_ASM_CLOSE_PAREN ""
96 #undef TARGET_ASM_SELECT_RTX_SECTION
97 #define TARGET_ASM_SELECT_RTX_SECTION s390_select_rtx_section
99 #undef TARGET_ENCODE_SECTION_INFO
100 #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
102 #ifdef HAVE_AS_TLS
103 #undef TARGET_HAVE_TLS
104 #define TARGET_HAVE_TLS true
105 #endif
106 #undef TARGET_CANNOT_FORCE_CONST_MEM
107 #define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
109 #undef TARGET_DELEGITIMIZE_ADDRESS
110 #define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
112 #undef TARGET_RETURN_IN_MEMORY
113 #define TARGET_RETURN_IN_MEMORY s390_return_in_memory
115 #undef TARGET_INIT_BUILTINS
116 #define TARGET_INIT_BUILTINS s390_init_builtins
117 #undef TARGET_EXPAND_BUILTIN
118 #define TARGET_EXPAND_BUILTIN s390_expand_builtin
120 #undef TARGET_ASM_OUTPUT_MI_THUNK
121 #define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
122 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
123 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
125 #undef TARGET_SCHED_ADJUST_COST
126 #define TARGET_SCHED_ADJUST_COST s390_adjust_cost
127 #undef TARGET_SCHED_ADJUST_PRIORITY
128 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
129 #undef TARGET_SCHED_ISSUE_RATE
130 #define TARGET_SCHED_ISSUE_RATE s390_issue_rate
131 #undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
132 #define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE s390_use_dfa_pipeline_interface
133 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
134 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
135 #undef TARGET_SCHED_REORDER2
136 #define TARGET_SCHED_REORDER2 s390_sched_reorder2
138 #undef TARGET_RTX_COSTS
139 #define TARGET_RTX_COSTS s390_rtx_costs
140 #undef TARGET_ADDRESS_COST
141 #define TARGET_ADDRESS_COST s390_address_cost
143 #undef TARGET_MACHINE_DEPENDENT_REORG
144 #define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
146 #undef TARGET_VALID_POINTER_MODE
147 #define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
149 #undef TARGET_BUILD_BUILTIN_VA_LIST
150 #define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
152 struct gcc_target targetm = TARGET_INITIALIZER;
154 extern int reload_completed;
156 /* The alias set for prologue/epilogue register save/restore. */
157 static int s390_sr_alias_set = 0;
159 /* Save information from a "cmpxx" operation until the branch or scc is
160 emitted. */
161 rtx s390_compare_op0, s390_compare_op1;
163 /* Structure used to hold the components of a S/390 memory
164 address. A legitimate address on S/390 is of the general
165 form
166 base + index + displacement
167 where any of the components is optional.
169 base and index are registers of the class ADDR_REGS,
170 displacement is an unsigned 12-bit immediate constant. */
172 struct s390_address
174 rtx base;
175 rtx indx;
176 rtx disp;
177 int pointer;
180 /* Which cpu are we tuning for. */
181 enum processor_type s390_tune;
182 enum processor_flags s390_tune_flags;
183 /* Which instruction set architecture to use. */
184 enum processor_type s390_arch;
185 enum processor_flags s390_arch_flags;
187 /* Strings to hold which cpu and instruction set architecture to use. */
188 const char *s390_tune_string; /* for -mtune=<xxx> */
189 const char *s390_arch_string; /* for -march=<xxx> */
191 /* Define the structure for the machine field in struct function. */
193 struct machine_function GTY(())
195 /* Set, if some of the fprs 8-15 need to be saved (64 bit abi). */
196 int save_fprs_p;
198 /* Set if return address needs to be saved. */
199 bool save_return_addr_p;
201 /* Number of first and last gpr to be saved, restored. */
202 int first_save_gpr;
203 int first_restore_gpr;
204 int last_save_gpr;
206 /* Size of stack frame. */
207 HOST_WIDE_INT frame_size;
209 /* Some local-dynamic TLS symbol name. */
210 const char *some_ld_name;
213 static int s390_match_ccmode_set (rtx, enum machine_mode);
214 static int s390_branch_condition_mask (rtx);
215 static const char *s390_branch_condition_mnemonic (rtx, int);
216 static int check_mode (rtx, enum machine_mode *);
217 static int general_s_operand (rtx, enum machine_mode, int);
218 static int s390_short_displacement (rtx);
219 static int s390_decompose_address (rtx, struct s390_address *);
220 static rtx get_thread_pointer (void);
221 static rtx legitimize_tls_address (rtx, rtx);
222 static void print_shift_count_operand (FILE *, rtx);
223 static const char *get_some_local_dynamic_name (void);
224 static int get_some_local_dynamic_name_1 (rtx *, void *);
225 static int reg_used_in_mem_p (int, rtx);
226 static int addr_generation_dependency_p (rtx, rtx);
227 static int s390_split_branches (void);
228 static void find_constant_pool_ref (rtx, rtx *);
229 static void replace_constant_pool_ref (rtx *, rtx, rtx);
230 static rtx find_ltrel_base (rtx);
231 static void replace_ltrel_base (rtx *, rtx);
232 static void s390_optimize_prolog (bool);
233 static int find_unused_clobbered_reg (void);
234 static void s390_frame_info (void);
235 static rtx save_fpr (rtx, int, int);
236 static rtx restore_fpr (rtx, int, int);
237 static rtx save_gprs (rtx, int, int, int);
238 static rtx restore_gprs (rtx, int, int, int);
239 static int s390_function_arg_size (enum machine_mode, tree);
240 static bool s390_function_arg_float (enum machine_mode, tree);
241 static struct machine_function * s390_init_machine_status (void);
243 /* Check whether integer displacement is in range. */
244 #define DISP_IN_RANGE(d) \
245 (TARGET_LONG_DISPLACEMENT? ((d) >= -524288 && (d) <= 524287) \
246 : ((d) >= 0 && (d) <= 4095))
248 /* Return true if SET either doesn't set the CC register, or else
249 the source and destination have matching CC modes and that
250 CC mode is at least as constrained as REQ_MODE. */
252 static int
253 s390_match_ccmode_set (rtx set, enum machine_mode req_mode)
255 enum machine_mode set_mode;
257 if (GET_CODE (set) != SET)
258 abort ();
260 if (GET_CODE (SET_DEST (set)) != REG || !CC_REGNO_P (REGNO (SET_DEST (set))))
261 return 1;
263 set_mode = GET_MODE (SET_DEST (set));
264 switch (set_mode)
266 case CCSmode:
267 case CCSRmode:
268 case CCUmode:
269 case CCURmode:
270 case CCLmode:
271 case CCL1mode:
272 case CCL2mode:
273 case CCT1mode:
274 case CCT2mode:
275 case CCT3mode:
276 if (req_mode != set_mode)
277 return 0;
278 break;
280 case CCZmode:
281 if (req_mode != CCSmode && req_mode != CCUmode && req_mode != CCTmode
282 && req_mode != CCSRmode && req_mode != CCURmode)
283 return 0;
284 break;
286 case CCAPmode:
287 case CCANmode:
288 if (req_mode != CCAmode)
289 return 0;
290 break;
292 default:
293 abort ();
296 return (GET_MODE (SET_SRC (set)) == set_mode);
299 /* Return true if every SET in INSN that sets the CC register
300 has source and destination with matching CC modes and that
301 CC mode is at least as constrained as REQ_MODE.
302 If REQ_MODE is VOIDmode, always return false. */
305 s390_match_ccmode (rtx insn, enum machine_mode req_mode)
307 int i;
309 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
310 if (req_mode == VOIDmode)
311 return 0;
313 if (GET_CODE (PATTERN (insn)) == SET)
314 return s390_match_ccmode_set (PATTERN (insn), req_mode);
316 if (GET_CODE (PATTERN (insn)) == PARALLEL)
317 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
319 rtx set = XVECEXP (PATTERN (insn), 0, i);
320 if (GET_CODE (set) == SET)
321 if (!s390_match_ccmode_set (set, req_mode))
322 return 0;
325 return 1;
328 /* If a test-under-mask instruction can be used to implement
329 (compare (and ... OP1) OP2), return the CC mode required
330 to do that. Otherwise, return VOIDmode.
331 MIXED is true if the instruction can distinguish between
332 CC1 and CC2 for mixed selected bits (TMxx), it is false
333 if the instruction cannot (TM). */
335 enum machine_mode
336 s390_tm_ccmode (rtx op1, rtx op2, int mixed)
338 int bit0, bit1;
340 /* ??? Fixme: should work on CONST_DOUBLE as well. */
341 if (GET_CODE (op1) != CONST_INT || GET_CODE (op2) != CONST_INT)
342 return VOIDmode;
344 /* Selected bits all zero: CC0. */
345 if (INTVAL (op2) == 0)
346 return CCTmode;
348 /* Selected bits all one: CC3. */
349 if (INTVAL (op2) == INTVAL (op1))
350 return CCT3mode;
352 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. */
353 if (mixed)
355 bit1 = exact_log2 (INTVAL (op2));
356 bit0 = exact_log2 (INTVAL (op1) ^ INTVAL (op2));
357 if (bit0 != -1 && bit1 != -1)
358 return bit0 > bit1 ? CCT1mode : CCT2mode;
361 return VOIDmode;
364 /* Given a comparison code OP (EQ, NE, etc.) and the operands
365 OP0 and OP1 of a COMPARE, return the mode to be used for the
366 comparison. */
368 enum machine_mode
369 s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
371 switch (code)
373 case EQ:
374 case NE:
375 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
376 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0, 1)), 'K', "K"))
377 return CCAPmode;
378 if ((GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
379 || GET_CODE (op1) == NEG)
380 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
381 return CCLmode;
383 if (GET_CODE (op0) == AND)
385 /* Check whether we can potentially do it via TM. */
386 enum machine_mode ccmode;
387 ccmode = s390_tm_ccmode (XEXP (op0, 1), op1, 1);
388 if (ccmode != VOIDmode)
390 /* Relax CCTmode to CCZmode to allow fall-back to AND
391 if that turns out to be beneficial. */
392 return ccmode == CCTmode ? CCZmode : ccmode;
396 if (register_operand (op0, HImode)
397 && GET_CODE (op1) == CONST_INT
398 && (INTVAL (op1) == -1 || INTVAL (op1) == 65535))
399 return CCT3mode;
400 if (register_operand (op0, QImode)
401 && GET_CODE (op1) == CONST_INT
402 && (INTVAL (op1) == -1 || INTVAL (op1) == 255))
403 return CCT3mode;
405 return CCZmode;
407 case LE:
408 case LT:
409 case GE:
410 case GT:
411 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
412 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0, 1)), 'K', "K"))
414 if (INTVAL (XEXP((op0), 1)) < 0)
415 return CCANmode;
416 else
417 return CCAPmode;
419 case UNORDERED:
420 case ORDERED:
421 case UNEQ:
422 case UNLE:
423 case UNLT:
424 case UNGE:
425 case UNGT:
426 case LTGT:
427 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
428 && GET_CODE (op1) != CONST_INT)
429 return CCSRmode;
430 return CCSmode;
432 case LTU:
433 case GEU:
434 if (GET_CODE (op0) == PLUS
435 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
436 return CCL1mode;
438 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
439 && GET_CODE (op1) != CONST_INT)
440 return CCURmode;
441 return CCUmode;
443 case LEU:
444 case GTU:
445 if (GET_CODE (op0) == MINUS
446 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
447 return CCL2mode;
449 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
450 && GET_CODE (op1) != CONST_INT)
451 return CCURmode;
452 return CCUmode;
454 default:
455 abort ();
459 /* Return nonzero if OP is a valid comparison operator
460 for an ALC condition in mode MODE. */
463 s390_alc_comparison (rtx op, enum machine_mode mode)
465 if (mode != VOIDmode && mode != GET_MODE (op))
466 return 0;
468 if (GET_RTX_CLASS (GET_CODE (op)) != '<')
469 return 0;
471 if (GET_CODE (XEXP (op, 0)) != REG
472 || REGNO (XEXP (op, 0)) != CC_REGNUM
473 || XEXP (op, 1) != const0_rtx)
474 return 0;
476 switch (GET_MODE (XEXP (op, 0)))
478 case CCL1mode:
479 return GET_CODE (op) == LTU;
481 case CCL2mode:
482 return GET_CODE (op) == LEU;
484 case CCUmode:
485 return GET_CODE (op) == GTU;
487 case CCURmode:
488 return GET_CODE (op) == LTU;
490 case CCSmode:
491 return GET_CODE (op) == UNGT;
493 case CCSRmode:
494 return GET_CODE (op) == UNLT;
496 default:
497 return 0;
501 /* Return nonzero if OP is a valid comparison operator
502 for an SLB condition in mode MODE. */
505 s390_slb_comparison (rtx op, enum machine_mode mode)
507 if (mode != VOIDmode && mode != GET_MODE (op))
508 return 0;
510 if (GET_RTX_CLASS (GET_CODE (op)) != '<')
511 return 0;
513 if (GET_CODE (XEXP (op, 0)) != REG
514 || REGNO (XEXP (op, 0)) != CC_REGNUM
515 || XEXP (op, 1) != const0_rtx)
516 return 0;
518 switch (GET_MODE (XEXP (op, 0)))
520 case CCL1mode:
521 return GET_CODE (op) == GEU;
523 case CCL2mode:
524 return GET_CODE (op) == GTU;
526 case CCUmode:
527 return GET_CODE (op) == LEU;
529 case CCURmode:
530 return GET_CODE (op) == GEU;
532 case CCSmode:
533 return GET_CODE (op) == LE;
535 case CCSRmode:
536 return GET_CODE (op) == GE;
538 default:
539 return 0;
543 /* Return branch condition mask to implement a branch
544 specified by CODE. */
546 static int
547 s390_branch_condition_mask (rtx code)
549 const int CC0 = 1 << 3;
550 const int CC1 = 1 << 2;
551 const int CC2 = 1 << 1;
552 const int CC3 = 1 << 0;
554 if (GET_CODE (XEXP (code, 0)) != REG
555 || REGNO (XEXP (code, 0)) != CC_REGNUM
556 || XEXP (code, 1) != const0_rtx)
557 abort ();
559 switch (GET_MODE (XEXP (code, 0)))
561 case CCZmode:
562 switch (GET_CODE (code))
564 case EQ: return CC0;
565 case NE: return CC1 | CC2 | CC3;
566 default:
567 abort ();
569 break;
571 case CCT1mode:
572 switch (GET_CODE (code))
574 case EQ: return CC1;
575 case NE: return CC0 | CC2 | CC3;
576 default:
577 abort ();
579 break;
581 case CCT2mode:
582 switch (GET_CODE (code))
584 case EQ: return CC2;
585 case NE: return CC0 | CC1 | CC3;
586 default:
587 abort ();
589 break;
591 case CCT3mode:
592 switch (GET_CODE (code))
594 case EQ: return CC3;
595 case NE: return CC0 | CC1 | CC2;
596 default:
597 abort ();
599 break;
601 case CCLmode:
602 switch (GET_CODE (code))
604 case EQ: return CC0 | CC2;
605 case NE: return CC1 | CC3;
606 default:
607 abort ();
609 break;
611 case CCL1mode:
612 switch (GET_CODE (code))
614 case LTU: return CC2 | CC3; /* carry */
615 case GEU: return CC0 | CC1; /* no carry */
616 default:
617 abort ();
619 break;
621 case CCL2mode:
622 switch (GET_CODE (code))
624 case GTU: return CC0 | CC1; /* borrow */
625 case LEU: return CC2 | CC3; /* no borrow */
626 default:
627 abort ();
629 break;
631 case CCUmode:
632 switch (GET_CODE (code))
634 case EQ: return CC0;
635 case NE: return CC1 | CC2 | CC3;
636 case LTU: return CC1;
637 case GTU: return CC2;
638 case LEU: return CC0 | CC1;
639 case GEU: return CC0 | CC2;
640 default:
641 abort ();
643 break;
645 case CCURmode:
646 switch (GET_CODE (code))
648 case EQ: return CC0;
649 case NE: return CC2 | CC1 | CC3;
650 case LTU: return CC2;
651 case GTU: return CC1;
652 case LEU: return CC0 | CC2;
653 case GEU: return CC0 | CC1;
654 default:
655 abort ();
657 break;
659 case CCAPmode:
660 switch (GET_CODE (code))
662 case EQ: return CC0;
663 case NE: return CC1 | CC2 | CC3;
664 case LT: return CC1 | CC3;
665 case GT: return CC2;
666 case LE: return CC0 | CC1 | CC3;
667 case GE: return CC0 | CC2;
668 default:
669 abort ();
671 break;
673 case CCANmode:
674 switch (GET_CODE (code))
676 case EQ: return CC0;
677 case NE: return CC1 | CC2 | CC3;
678 case LT: return CC1;
679 case GT: return CC2 | CC3;
680 case LE: return CC0 | CC1;
681 case GE: return CC0 | CC2 | CC3;
682 default:
683 abort ();
685 break;
687 case CCSmode:
688 switch (GET_CODE (code))
690 case EQ: return CC0;
691 case NE: return CC1 | CC2 | CC3;
692 case LT: return CC1;
693 case GT: return CC2;
694 case LE: return CC0 | CC1;
695 case GE: return CC0 | CC2;
696 case UNORDERED: return CC3;
697 case ORDERED: return CC0 | CC1 | CC2;
698 case UNEQ: return CC0 | CC3;
699 case UNLT: return CC1 | CC3;
700 case UNGT: return CC2 | CC3;
701 case UNLE: return CC0 | CC1 | CC3;
702 case UNGE: return CC0 | CC2 | CC3;
703 case LTGT: return CC1 | CC2;
704 default:
705 abort ();
707 break;
709 case CCSRmode:
710 switch (GET_CODE (code))
712 case EQ: return CC0;
713 case NE: return CC2 | CC1 | CC3;
714 case LT: return CC2;
715 case GT: return CC1;
716 case LE: return CC0 | CC2;
717 case GE: return CC0 | CC1;
718 case UNORDERED: return CC3;
719 case ORDERED: return CC0 | CC2 | CC1;
720 case UNEQ: return CC0 | CC3;
721 case UNLT: return CC2 | CC3;
722 case UNGT: return CC1 | CC3;
723 case UNLE: return CC0 | CC2 | CC3;
724 case UNGE: return CC0 | CC1 | CC3;
725 case LTGT: return CC2 | CC1;
726 default:
727 abort ();
729 break;
731 default:
732 abort ();
736 /* If INV is false, return assembler mnemonic string to implement
737 a branch specified by CODE. If INV is true, return mnemonic
738 for the corresponding inverted branch. */
740 static const char *
741 s390_branch_condition_mnemonic (rtx code, int inv)
743 static const char *const mnemonic[16] =
745 NULL, "o", "h", "nle",
746 "l", "nhe", "lh", "ne",
747 "e", "nlh", "he", "nl",
748 "le", "nh", "no", NULL
751 int mask = s390_branch_condition_mask (code);
753 if (inv)
754 mask ^= 15;
756 if (mask < 1 || mask > 14)
757 abort ();
759 return mnemonic[mask];
762 /* Return the part of op which has a value different from def.
763 The size of the part is determined by mode.
764 Use this function only if you already know that op really
765 contains such a part. */
767 unsigned HOST_WIDE_INT
768 s390_extract_part (rtx op, enum machine_mode mode, int def)
770 unsigned HOST_WIDE_INT value = 0;
771 int max_parts = HOST_BITS_PER_WIDE_INT / GET_MODE_BITSIZE (mode);
772 int part_bits = GET_MODE_BITSIZE (mode);
773 unsigned HOST_WIDE_INT part_mask = (1 << part_bits) - 1;
774 int i;
776 for (i = 0; i < max_parts; i++)
778 if (i == 0)
779 value = (unsigned HOST_WIDE_INT) INTVAL (op);
780 else
781 value >>= part_bits;
783 if ((value & part_mask) != (def & part_mask))
784 return value & part_mask;
787 abort ();
790 /* If OP is an integer constant of mode MODE with exactly one
791 part of mode PART_MODE unequal to DEF, return the number of that
792 part. Otherwise, return -1. */
795 s390_single_part (rtx op,
796 enum machine_mode mode,
797 enum machine_mode part_mode,
798 int def)
800 unsigned HOST_WIDE_INT value = 0;
801 int n_parts = GET_MODE_SIZE (mode) / GET_MODE_SIZE (part_mode);
802 unsigned HOST_WIDE_INT part_mask = (1 << GET_MODE_BITSIZE (part_mode)) - 1;
803 int i, part = -1;
805 if (GET_CODE (op) != CONST_INT)
806 return -1;
808 for (i = 0; i < n_parts; i++)
810 if (i == 0)
811 value = (unsigned HOST_WIDE_INT) INTVAL (op);
812 else
813 value >>= GET_MODE_BITSIZE (part_mode);
815 if ((value & part_mask) != (def & part_mask))
817 if (part != -1)
818 return -1;
819 else
820 part = i;
823 return part == -1 ? -1 : n_parts - 1 - part;
826 /* Check whether we can (and want to) split a double-word
827 move in mode MODE from SRC to DST into two single-word
828 moves, moving the subword FIRST_SUBWORD first. */
830 bool
831 s390_split_ok_p (rtx dst, rtx src, enum machine_mode mode, int first_subword)
833 /* Floating point registers cannot be split. */
834 if (FP_REG_P (src) || FP_REG_P (dst))
835 return false;
837 /* We don't need to split if operands are directly accessible. */
838 if (s_operand (src, mode) || s_operand (dst, mode))
839 return false;
841 /* Non-offsettable memory references cannot be split. */
842 if ((GET_CODE (src) == MEM && !offsettable_memref_p (src))
843 || (GET_CODE (dst) == MEM && !offsettable_memref_p (dst)))
844 return false;
846 /* Moving the first subword must not clobber a register
847 needed to move the second subword. */
848 if (register_operand (dst, mode))
850 rtx subreg = operand_subword (dst, first_subword, 0, mode);
851 if (reg_overlap_mentioned_p (subreg, src))
852 return false;
855 return true;
859 /* Change optimizations to be performed, depending on the
860 optimization level.
862 LEVEL is the optimization level specified; 2 if `-O2' is
863 specified, 1 if `-O' is specified, and 0 if neither is specified.
865 SIZE is nonzero if `-Os' is specified and zero otherwise. */
867 void
868 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
870 /* ??? There are apparently still problems with -fcaller-saves. */
871 flag_caller_saves = 0;
873 /* By default, always emit DWARF-2 unwind info. This allows debugging
874 without maintaining a stack frame back-chain. */
875 flag_asynchronous_unwind_tables = 1;
878 void
879 override_options (void)
881 int i;
882 static struct pta
884 const char *const name; /* processor name or nickname. */
885 const enum processor_type processor;
886 const enum processor_flags flags;
888 const processor_alias_table[] =
890 {"g5", PROCESSOR_9672_G5, PF_IEEE_FLOAT},
891 {"g6", PROCESSOR_9672_G6, PF_IEEE_FLOAT},
892 {"z900", PROCESSOR_2064_Z900, PF_IEEE_FLOAT | PF_ZARCH},
893 {"z990", PROCESSOR_2084_Z990, PF_IEEE_FLOAT | PF_ZARCH
894 | PF_LONG_DISPLACEMENT},
897 int const pta_size = ARRAY_SIZE (processor_alias_table);
899 /* Acquire a unique set number for our register saves and restores. */
900 s390_sr_alias_set = new_alias_set ();
902 /* Set up function hooks. */
903 init_machine_status = s390_init_machine_status;
905 /* Architecture mode defaults according to ABI. */
906 if (!(target_flags_explicit & MASK_ZARCH))
908 if (TARGET_64BIT)
909 target_flags |= MASK_ZARCH;
910 else
911 target_flags &= ~MASK_ZARCH;
914 /* Determine processor architectural level. */
915 if (!s390_arch_string)
916 s390_arch_string = TARGET_ZARCH? "z900" : "g5";
918 for (i = 0; i < pta_size; i++)
919 if (! strcmp (s390_arch_string, processor_alias_table[i].name))
921 s390_arch = processor_alias_table[i].processor;
922 s390_arch_flags = processor_alias_table[i].flags;
923 break;
925 if (i == pta_size)
926 error ("Unknown cpu used in -march=%s.", s390_arch_string);
928 /* Determine processor to tune for. */
929 if (!s390_tune_string)
931 s390_tune = s390_arch;
932 s390_tune_flags = s390_arch_flags;
933 s390_tune_string = s390_arch_string;
935 else
937 for (i = 0; i < pta_size; i++)
938 if (! strcmp (s390_tune_string, processor_alias_table[i].name))
940 s390_tune = processor_alias_table[i].processor;
941 s390_tune_flags = processor_alias_table[i].flags;
942 break;
944 if (i == pta_size)
945 error ("Unknown cpu used in -mtune=%s.", s390_tune_string);
948 /* Sanity checks. */
949 if (TARGET_ZARCH && !(s390_arch_flags & PF_ZARCH))
950 error ("z/Architecture mode not supported on %s.", s390_arch_string);
951 if (TARGET_64BIT && !TARGET_ZARCH)
952 error ("64-bit ABI not supported in ESA/390 mode.");
955 /* Map for smallest class containing reg regno. */
957 const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
958 { GENERAL_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 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_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 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
966 ADDR_REGS, NO_REGS, ADDR_REGS
969 /* Return attribute type of insn. */
971 static enum attr_type
972 s390_safe_attr_type (rtx insn)
974 if (recog_memoized (insn) >= 0)
975 return get_attr_type (insn);
976 else
977 return TYPE_NONE;
980 /* Return true if OP a (const_int 0) operand.
981 OP is the current operation.
982 MODE is the current operation mode. */
985 const0_operand (register rtx op, enum machine_mode mode)
987 return op == CONST0_RTX (mode);
990 /* Return true if OP is constant.
991 OP is the current operation.
992 MODE is the current operation mode. */
995 consttable_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
997 return CONSTANT_P (op);
1000 /* Return true if the mode of operand OP matches MODE.
1001 If MODE is set to VOIDmode, set it to the mode of OP. */
1003 static int
1004 check_mode (register rtx op, enum machine_mode *mode)
1006 if (*mode == VOIDmode)
1007 *mode = GET_MODE (op);
1008 else
1010 if (GET_MODE (op) != VOIDmode && GET_MODE (op) != *mode)
1011 return 0;
1013 return 1;
1016 /* Return true if OP a valid operand for the LARL instruction.
1017 OP is the current operation.
1018 MODE is the current operation mode. */
1021 larl_operand (register rtx op, enum machine_mode mode)
1023 if (! check_mode (op, &mode))
1024 return 0;
1026 /* Allow labels and local symbols. */
1027 if (GET_CODE (op) == LABEL_REF)
1028 return 1;
1029 if (GET_CODE (op) == SYMBOL_REF)
1030 return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0
1031 && SYMBOL_REF_TLS_MODEL (op) == 0
1032 && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
1034 /* Everything else must have a CONST, so strip it. */
1035 if (GET_CODE (op) != CONST)
1036 return 0;
1037 op = XEXP (op, 0);
1039 /* Allow adding *even* in-range constants. */
1040 if (GET_CODE (op) == PLUS)
1042 if (GET_CODE (XEXP (op, 1)) != CONST_INT
1043 || (INTVAL (XEXP (op, 1)) & 1) != 0)
1044 return 0;
1045 #if HOST_BITS_PER_WIDE_INT > 32
1046 if (INTVAL (XEXP (op, 1)) >= (HOST_WIDE_INT)1 << 32
1047 || INTVAL (XEXP (op, 1)) < -((HOST_WIDE_INT)1 << 32))
1048 return 0;
1049 #endif
1050 op = XEXP (op, 0);
1053 /* Labels and local symbols allowed here as well. */
1054 if (GET_CODE (op) == LABEL_REF)
1055 return 1;
1056 if (GET_CODE (op) == SYMBOL_REF)
1057 return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0
1058 && SYMBOL_REF_TLS_MODEL (op) == 0
1059 && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
1061 /* Now we must have a @GOTENT offset or @PLT stub
1062 or an @INDNTPOFF TLS offset. */
1063 if (GET_CODE (op) == UNSPEC
1064 && XINT (op, 1) == UNSPEC_GOTENT)
1065 return 1;
1066 if (GET_CODE (op) == UNSPEC
1067 && XINT (op, 1) == UNSPEC_PLT)
1068 return 1;
1069 if (GET_CODE (op) == UNSPEC
1070 && XINT (op, 1) == UNSPEC_INDNTPOFF)
1071 return 1;
1073 return 0;
1076 /* Helper routine to implement s_operand and s_imm_operand.
1077 OP is the current operation.
1078 MODE is the current operation mode.
1079 ALLOW_IMMEDIATE specifies whether immediate operands should
1080 be accepted or not. */
1082 static int
1083 general_s_operand (register rtx op, enum machine_mode mode,
1084 int allow_immediate)
1086 struct s390_address addr;
1088 /* Call general_operand first, so that we don't have to
1089 check for many special cases. */
1090 if (!general_operand (op, mode))
1091 return 0;
1093 /* Just like memory_operand, allow (subreg (mem ...))
1094 after reload. */
1095 if (reload_completed
1096 && GET_CODE (op) == SUBREG
1097 && GET_CODE (SUBREG_REG (op)) == MEM)
1098 op = SUBREG_REG (op);
1100 switch (GET_CODE (op))
1102 /* Constants are OK as s-operand if ALLOW_IMMEDIATE
1103 is true and we are still before reload. */
1104 case CONST_INT:
1105 case CONST_DOUBLE:
1106 if (!allow_immediate || reload_completed)
1107 return 0;
1108 return 1;
1110 /* Memory operands are OK unless they already use an
1111 index register. */
1112 case MEM:
1113 if (GET_CODE (XEXP (op, 0)) == ADDRESSOF)
1114 return 1;
1115 if (!s390_decompose_address (XEXP (op, 0), &addr))
1116 return 0;
1117 if (addr.indx)
1118 return 0;
1119 /* Do not allow literal pool references unless ALLOW_IMMEDIATE
1120 is true. This prevents compares between two literal pool
1121 entries from being accepted. */
1122 if (!allow_immediate
1123 && addr.base && REGNO (addr.base) == BASE_REGISTER)
1124 return 0;
1125 return 1;
1127 default:
1128 break;
1131 return 0;
1134 /* Return true if OP is a valid S-type operand.
1135 OP is the current operation.
1136 MODE is the current operation mode. */
1139 s_operand (register rtx op, enum machine_mode mode)
1141 return general_s_operand (op, mode, 0);
1144 /* Return true if OP is a valid S-type operand or an immediate
1145 operand that can be addressed as S-type operand by forcing
1146 it into the literal pool.
1147 OP is the current operation.
1148 MODE is the current operation mode. */
1151 s_imm_operand (register rtx op, enum machine_mode mode)
1153 return general_s_operand (op, mode, 1);
1156 /* Return true if OP a valid shift count operand.
1157 OP is the current operation.
1158 MODE is the current operation mode. */
1161 shift_count_operand (rtx op, enum machine_mode mode)
1163 HOST_WIDE_INT offset = 0;
1165 if (! check_mode (op, &mode))
1166 return 0;
1168 /* We can have an integer constant, an address register,
1169 or a sum of the two. Note that reload already checks
1170 that any register present is an address register, so
1171 we just check for any register here. */
1172 if (GET_CODE (op) == CONST_INT)
1174 offset = INTVAL (op);
1175 op = NULL_RTX;
1177 if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
1179 offset = INTVAL (XEXP (op, 1));
1180 op = XEXP (op, 0);
1182 while (op && GET_CODE (op) == SUBREG)
1183 op = SUBREG_REG (op);
1184 if (op && GET_CODE (op) != REG)
1185 return 0;
1187 /* Unfortunately we have to reject constants that are invalid
1188 for an address, or else reload will get confused. */
1189 if (!DISP_IN_RANGE (offset))
1190 return 0;
1192 return 1;
1195 /* Return true if DISP is a valid short displacement. */
1197 static int
1198 s390_short_displacement (rtx disp)
1200 /* No displacement is OK. */
1201 if (!disp)
1202 return 1;
1204 /* Integer displacement in range. */
1205 if (GET_CODE (disp) == CONST_INT)
1206 return INTVAL (disp) >= 0 && INTVAL (disp) < 4096;
1208 /* GOT offset is not OK, the GOT can be large. */
1209 if (GET_CODE (disp) == CONST
1210 && GET_CODE (XEXP (disp, 0)) == UNSPEC
1211 && XINT (XEXP (disp, 0), 1) == UNSPEC_GOT)
1212 return 0;
1214 /* All other symbolic constants are literal pool references,
1215 which are OK as the literal pool must be small. */
1216 if (GET_CODE (disp) == CONST)
1217 return 1;
1219 return 0;
1222 /* Return true if OP is a valid operand for a C constraint. */
1225 s390_extra_constraint_str (rtx op, int c, const char * str)
1227 struct s390_address addr;
1229 if (c != str[0])
1230 abort ();
1232 switch (c)
1234 case 'Q':
1235 if (GET_CODE (op) != MEM)
1236 return 0;
1237 if (!s390_decompose_address (XEXP (op, 0), &addr))
1238 return 0;
1239 if (addr.indx)
1240 return 0;
1242 if (TARGET_LONG_DISPLACEMENT)
1244 if (!s390_short_displacement (addr.disp))
1245 return 0;
1247 break;
1249 case 'R':
1250 if (GET_CODE (op) != MEM)
1251 return 0;
1253 if (TARGET_LONG_DISPLACEMENT)
1255 if (!s390_decompose_address (XEXP (op, 0), &addr))
1256 return 0;
1257 if (!s390_short_displacement (addr.disp))
1258 return 0;
1260 break;
1262 case 'S':
1263 if (!TARGET_LONG_DISPLACEMENT)
1264 return 0;
1265 if (GET_CODE (op) != MEM)
1266 return 0;
1267 if (!s390_decompose_address (XEXP (op, 0), &addr))
1268 return 0;
1269 if (addr.indx)
1270 return 0;
1271 if (s390_short_displacement (addr.disp))
1272 return 0;
1273 break;
1275 case 'T':
1276 if (!TARGET_LONG_DISPLACEMENT)
1277 return 0;
1278 if (GET_CODE (op) != MEM)
1279 return 0;
1280 /* Any invalid address here will be fixed up by reload,
1281 so accept it for the most generic constraint. */
1282 if (s390_decompose_address (XEXP (op, 0), &addr)
1283 && s390_short_displacement (addr.disp))
1284 return 0;
1285 break;
1287 case 'U':
1288 if (TARGET_LONG_DISPLACEMENT)
1290 if (!s390_decompose_address (op, &addr))
1291 return 0;
1292 if (!s390_short_displacement (addr.disp))
1293 return 0;
1295 break;
1297 case 'W':
1298 if (!TARGET_LONG_DISPLACEMENT)
1299 return 0;
1300 /* Any invalid address here will be fixed up by reload,
1301 so accept it for the most generic constraint. */
1302 if (s390_decompose_address (op, &addr)
1303 && s390_short_displacement (addr.disp))
1304 return 0;
1305 break;
1307 case 'Y':
1308 return shift_count_operand (op, VOIDmode);
1310 default:
1311 return 0;
1314 return 1;
1317 /* Return true if VALUE matches the constraint STR. */
1320 s390_const_ok_for_constraint_p (HOST_WIDE_INT value,
1321 int c,
1322 const char * str)
1324 enum machine_mode mode, part_mode;
1325 int def;
1326 unsigned char part;
1328 if (c != str[0])
1329 abort ();
1331 switch (str[0])
1333 case 'I':
1334 return (unsigned int)value < 256;
1336 case 'J':
1337 return (unsigned int)value < 4096;
1339 case 'K':
1340 return value >= -32768 && value < 32768;
1342 case 'L':
1343 return (TARGET_LONG_DISPLACEMENT ?
1344 (value >= -524288 && value <= 524287)
1345 : (value >= 0 && value <= 4095));
1346 case 'M':
1347 return value == 2147483647;
1349 case 'N':
1350 part = str[1] - '0';
1352 switch (str[2])
1354 case 'H': part_mode = HImode; break;
1355 case 'Q': part_mode = QImode; break;
1356 default: return 0;
1359 switch (str[3])
1361 case 'H': mode = HImode; break;
1362 case 'S': mode = SImode; break;
1363 case 'D': mode = DImode; break;
1364 default: return 0;
1367 switch (str[4])
1369 case '0': def = 0; break;
1370 case 'F': def = -1; break;
1371 default: return 0;
1374 if (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (part_mode))
1375 return 0;
1377 if (s390_single_part (GEN_INT (value), mode, part_mode, def) != part)
1378 return 0;
1380 break;
1382 default:
1383 return 0;
1386 return 1;
1389 /* Compute a (partial) cost for rtx X. Return true if the complete
1390 cost has been computed, and false if subexpressions should be
1391 scanned. In either case, *TOTAL contains the cost result. */
1393 static bool
1394 s390_rtx_costs (rtx x, int code, int outer_code, int *total)
1396 switch (code)
1398 case CONST:
1399 if (GET_CODE (XEXP (x, 0)) == MINUS
1400 && GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
1401 *total = 1000;
1402 else
1403 *total = 0;
1404 return true;
1406 case CONST_INT:
1407 /* Force_const_mem does not work out of reload, because the
1408 saveable_obstack is set to reload_obstack, which does not
1409 live long enough. Because of this we cannot use force_const_mem
1410 in addsi3. This leads to problems with gen_add2_insn with a
1411 constant greater than a short. Because of that we give an
1412 addition of greater constants a cost of 3 (reload1.c 10096). */
1413 /* ??? saveable_obstack no longer exists. */
1414 if (outer_code == PLUS
1415 && (INTVAL (x) > 32767 || INTVAL (x) < -32768))
1416 *total = COSTS_N_INSNS (3);
1417 else
1418 *total = 0;
1419 return true;
1421 case LABEL_REF:
1422 case SYMBOL_REF:
1423 case CONST_DOUBLE:
1424 *total = 0;
1425 return true;
1427 case ASHIFT:
1428 case ASHIFTRT:
1429 case LSHIFTRT:
1430 case PLUS:
1431 case AND:
1432 case IOR:
1433 case XOR:
1434 case MINUS:
1435 case NEG:
1436 case NOT:
1437 *total = COSTS_N_INSNS (1);
1438 return true;
1440 case MULT:
1441 if (GET_MODE (XEXP (x, 0)) == DImode)
1442 *total = COSTS_N_INSNS (40);
1443 else
1444 *total = COSTS_N_INSNS (7);
1445 return true;
1447 case DIV:
1448 case UDIV:
1449 case MOD:
1450 case UMOD:
1451 *total = COSTS_N_INSNS (33);
1452 return true;
1454 default:
1455 return false;
1459 /* Return the cost of an address rtx ADDR. */
1461 static int
1462 s390_address_cost (rtx addr)
1464 struct s390_address ad;
1465 if (!s390_decompose_address (addr, &ad))
1466 return 1000;
1468 return ad.indx? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
1471 /* Return true if OP is a valid operand for the BRAS instruction.
1472 OP is the current operation.
1473 MODE is the current operation mode. */
1476 bras_sym_operand (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1478 register enum rtx_code code = GET_CODE (op);
1480 /* Allow SYMBOL_REFs. */
1481 if (code == SYMBOL_REF)
1482 return 1;
1484 /* Allow @PLT stubs. */
1485 if (code == CONST
1486 && GET_CODE (XEXP (op, 0)) == UNSPEC
1487 && XINT (XEXP (op, 0), 1) == UNSPEC_PLT)
1488 return 1;
1489 return 0;
1492 /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
1493 otherwise return 0. */
1496 tls_symbolic_operand (register rtx op)
1498 if (GET_CODE (op) != SYMBOL_REF)
1499 return 0;
1500 return SYMBOL_REF_TLS_MODEL (op);
1503 /* Return true if OP is a load multiple operation. It is known to be a
1504 PARALLEL and the first section will be tested.
1505 OP is the current operation.
1506 MODE is the current operation mode. */
1509 load_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1511 enum machine_mode elt_mode;
1512 int count = XVECLEN (op, 0);
1513 unsigned int dest_regno;
1514 rtx src_addr;
1515 int i, off;
1518 /* Perform a quick check so we don't blow up below. */
1519 if (count <= 1
1520 || GET_CODE (XVECEXP (op, 0, 0)) != SET
1521 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
1522 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
1523 return 0;
1525 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
1526 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
1527 elt_mode = GET_MODE (SET_DEST (XVECEXP (op, 0, 0)));
1529 /* Check, is base, or base + displacement. */
1531 if (GET_CODE (src_addr) == REG)
1532 off = 0;
1533 else if (GET_CODE (src_addr) == PLUS
1534 && GET_CODE (XEXP (src_addr, 0)) == REG
1535 && GET_CODE (XEXP (src_addr, 1)) == CONST_INT)
1537 off = INTVAL (XEXP (src_addr, 1));
1538 src_addr = XEXP (src_addr, 0);
1540 else
1541 return 0;
1543 if (src_addr == frame_pointer_rtx || src_addr == arg_pointer_rtx)
1544 return 0;
1546 for (i = 1; i < count; i++)
1548 rtx elt = XVECEXP (op, 0, i);
1550 if (GET_CODE (elt) != SET
1551 || GET_CODE (SET_DEST (elt)) != REG
1552 || GET_MODE (SET_DEST (elt)) != elt_mode
1553 || REGNO (SET_DEST (elt)) != dest_regno + i
1554 || GET_CODE (SET_SRC (elt)) != MEM
1555 || GET_MODE (SET_SRC (elt)) != elt_mode
1556 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
1557 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
1558 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
1559 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1))
1560 != off + i * GET_MODE_SIZE (elt_mode))
1561 return 0;
1564 return 1;
1567 /* Return true if OP is a store multiple operation. It is known to be a
1568 PARALLEL and the first section will be tested.
1569 OP is the current operation.
1570 MODE is the current operation mode. */
1573 store_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1575 enum machine_mode elt_mode;
1576 int count = XVECLEN (op, 0);
1577 unsigned int src_regno;
1578 rtx dest_addr;
1579 int i, off;
1581 /* Perform a quick check so we don't blow up below. */
1582 if (count <= 1
1583 || GET_CODE (XVECEXP (op, 0, 0)) != SET
1584 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
1585 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
1586 return 0;
1588 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
1589 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
1590 elt_mode = GET_MODE (SET_SRC (XVECEXP (op, 0, 0)));
1592 /* Check, is base, or base + displacement. */
1594 if (GET_CODE (dest_addr) == REG)
1595 off = 0;
1596 else if (GET_CODE (dest_addr) == PLUS
1597 && GET_CODE (XEXP (dest_addr, 0)) == REG
1598 && GET_CODE (XEXP (dest_addr, 1)) == CONST_INT)
1600 off = INTVAL (XEXP (dest_addr, 1));
1601 dest_addr = XEXP (dest_addr, 0);
1603 else
1604 return 0;
1606 if (dest_addr == frame_pointer_rtx || dest_addr == arg_pointer_rtx)
1607 return 0;
1609 for (i = 1; i < count; i++)
1611 rtx elt = XVECEXP (op, 0, i);
1613 if (GET_CODE (elt) != SET
1614 || GET_CODE (SET_SRC (elt)) != REG
1615 || GET_MODE (SET_SRC (elt)) != elt_mode
1616 || REGNO (SET_SRC (elt)) != src_regno + i
1617 || GET_CODE (SET_DEST (elt)) != MEM
1618 || GET_MODE (SET_DEST (elt)) != elt_mode
1619 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
1620 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
1621 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
1622 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1))
1623 != off + i * GET_MODE_SIZE (elt_mode))
1624 return 0;
1626 return 1;
1630 /* Return true if OP contains a symbol reference */
1633 symbolic_reference_mentioned_p (rtx op)
1635 register const char *fmt;
1636 register int i;
1638 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
1639 return 1;
1641 fmt = GET_RTX_FORMAT (GET_CODE (op));
1642 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
1644 if (fmt[i] == 'E')
1646 register int j;
1648 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
1649 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
1650 return 1;
1653 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
1654 return 1;
1657 return 0;
1660 /* Return true if OP contains a reference to a thread-local symbol. */
1663 tls_symbolic_reference_mentioned_p (rtx op)
1665 register const char *fmt;
1666 register int i;
1668 if (GET_CODE (op) == SYMBOL_REF)
1669 return tls_symbolic_operand (op);
1671 fmt = GET_RTX_FORMAT (GET_CODE (op));
1672 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
1674 if (fmt[i] == 'E')
1676 register int j;
1678 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
1679 if (tls_symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
1680 return 1;
1683 else if (fmt[i] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op, i)))
1684 return 1;
1687 return 0;
1691 /* Return true if OP is a legitimate general operand when
1692 generating PIC code. It is given that flag_pic is on
1693 and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
1696 legitimate_pic_operand_p (register rtx op)
1698 /* Accept all non-symbolic constants. */
1699 if (!SYMBOLIC_CONST (op))
1700 return 1;
1702 /* Reject everything else; must be handled
1703 via emit_symbolic_move. */
1704 return 0;
1707 /* Returns true if the constant value OP is a legitimate general operand.
1708 It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
1711 legitimate_constant_p (register rtx op)
1713 /* Accept all non-symbolic constants. */
1714 if (!SYMBOLIC_CONST (op))
1715 return 1;
1717 /* Accept immediate LARL operands. */
1718 if (TARGET_CPU_ZARCH && larl_operand (op, VOIDmode))
1719 return 1;
1721 /* Thread-local symbols are never legal constants. This is
1722 so that emit_call knows that computing such addresses
1723 might require a function call. */
1724 if (TLS_SYMBOLIC_CONST (op))
1725 return 0;
1727 /* In the PIC case, symbolic constants must *not* be
1728 forced into the literal pool. We accept them here,
1729 so that they will be handled by emit_symbolic_move. */
1730 if (flag_pic)
1731 return 1;
1733 /* All remaining non-PIC symbolic constants are
1734 forced into the literal pool. */
1735 return 0;
1738 /* Determine if it's legal to put X into the constant pool. This
1739 is not possible if X contains the address of a symbol that is
1740 not constant (TLS) or not known at final link time (PIC). */
1742 static bool
1743 s390_cannot_force_const_mem (rtx x)
1745 switch (GET_CODE (x))
1747 case CONST_INT:
1748 case CONST_DOUBLE:
1749 /* Accept all non-symbolic constants. */
1750 return false;
1752 case LABEL_REF:
1753 /* Labels are OK iff we are non-PIC. */
1754 return flag_pic != 0;
1756 case SYMBOL_REF:
1757 /* 'Naked' TLS symbol references are never OK,
1758 non-TLS symbols are OK iff we are non-PIC. */
1759 if (tls_symbolic_operand (x))
1760 return true;
1761 else
1762 return flag_pic != 0;
1764 case CONST:
1765 return s390_cannot_force_const_mem (XEXP (x, 0));
1766 case PLUS:
1767 case MINUS:
1768 return s390_cannot_force_const_mem (XEXP (x, 0))
1769 || s390_cannot_force_const_mem (XEXP (x, 1));
1771 case UNSPEC:
1772 switch (XINT (x, 1))
1774 /* Only lt-relative or GOT-relative UNSPECs are OK. */
1775 case UNSPEC_LTREL_OFFSET:
1776 case UNSPEC_GOT:
1777 case UNSPEC_GOTOFF:
1778 case UNSPEC_PLTOFF:
1779 case UNSPEC_TLSGD:
1780 case UNSPEC_TLSLDM:
1781 case UNSPEC_NTPOFF:
1782 case UNSPEC_DTPOFF:
1783 case UNSPEC_GOTNTPOFF:
1784 case UNSPEC_INDNTPOFF:
1785 return false;
1787 default:
1788 return true;
1790 break;
1792 default:
1793 abort ();
1797 /* Returns true if the constant value OP is a legitimate general
1798 operand during and after reload. The difference to
1799 legitimate_constant_p is that this function will not accept
1800 a constant that would need to be forced to the literal pool
1801 before it can be used as operand. */
1804 legitimate_reload_constant_p (register rtx op)
1806 /* Accept la(y) operands. */
1807 if (GET_CODE (op) == CONST_INT
1808 && DISP_IN_RANGE (INTVAL (op)))
1809 return 1;
1811 /* Accept l(g)hi operands. */
1812 if (GET_CODE (op) == CONST_INT
1813 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'K', "K"))
1814 return 1;
1816 /* Accept lliXX operands. */
1817 if (TARGET_ZARCH
1818 && s390_single_part (op, DImode, HImode, 0) >= 0)
1819 return 1;
1821 /* Accept larl operands. */
1822 if (TARGET_CPU_ZARCH
1823 && larl_operand (op, VOIDmode))
1824 return 1;
1826 /* Everything else cannot be handled without reload. */
1827 return 0;
1830 /* Given an rtx OP being reloaded into a reg required to be in class CLASS,
1831 return the class of reg to actually use. */
1833 enum reg_class
1834 s390_preferred_reload_class (rtx op, enum reg_class class)
1836 /* This can happen if a floating point constant is being
1837 reloaded into an integer register. Leave well alone. */
1838 if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT
1839 && class != FP_REGS)
1840 return class;
1842 switch (GET_CODE (op))
1844 /* Constants we cannot reload must be forced into the
1845 literal pool. */
1847 case CONST_DOUBLE:
1848 case CONST_INT:
1849 if (legitimate_reload_constant_p (op))
1850 return class;
1851 else
1852 return NO_REGS;
1854 /* If a symbolic constant or a PLUS is reloaded,
1855 it is most likely being used as an address, so
1856 prefer ADDR_REGS. If 'class' is not a superset
1857 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
1858 case PLUS:
1859 case LABEL_REF:
1860 case SYMBOL_REF:
1861 case CONST:
1862 if (reg_class_subset_p (ADDR_REGS, class))
1863 return ADDR_REGS;
1864 else
1865 return NO_REGS;
1867 default:
1868 break;
1871 return class;
1874 /* Return the register class of a scratch register needed to
1875 load IN into a register of class CLASS in MODE.
1877 We need a temporary when loading a PLUS expression which
1878 is not a legitimate operand of the LOAD ADDRESS instruction. */
1880 enum reg_class
1881 s390_secondary_input_reload_class (enum reg_class class ATTRIBUTE_UNUSED,
1882 enum machine_mode mode, rtx in)
1884 if (s390_plus_operand (in, mode))
1885 return ADDR_REGS;
1887 return NO_REGS;
1890 /* Return the register class of a scratch register needed to
1891 store a register of class CLASS in MODE into OUT:
1893 We need a temporary when storing a double-word to a
1894 non-offsettable memory address. */
1896 enum reg_class
1897 s390_secondary_output_reload_class (enum reg_class class,
1898 enum machine_mode mode, rtx out)
1900 if ((TARGET_64BIT ? mode == TImode
1901 : (mode == DImode || mode == DFmode))
1902 && reg_classes_intersect_p (GENERAL_REGS, class)
1903 && GET_CODE (out) == MEM
1904 && !offsettable_memref_p (out)
1905 && !s_operand (out, VOIDmode))
1906 return ADDR_REGS;
1908 return NO_REGS;
1911 /* Return true if OP is a PLUS that is not a legitimate
1912 operand for the LA instruction.
1913 OP is the current operation.
1914 MODE is the current operation mode. */
1917 s390_plus_operand (register rtx op, enum machine_mode mode)
1919 if (!check_mode (op, &mode) || mode != Pmode)
1920 return FALSE;
1922 if (GET_CODE (op) != PLUS)
1923 return FALSE;
1925 if (legitimate_la_operand_p (op))
1926 return FALSE;
1928 return TRUE;
1931 /* Generate code to load SRC, which is PLUS that is not a
1932 legitimate operand for the LA instruction, into TARGET.
1933 SCRATCH may be used as scratch register. */
1935 void
1936 s390_expand_plus_operand (register rtx target, register rtx src,
1937 register rtx scratch)
1939 rtx sum1, sum2;
1940 struct s390_address ad;
1942 /* src must be a PLUS; get its two operands. */
1943 if (GET_CODE (src) != PLUS || GET_MODE (src) != Pmode)
1944 abort ();
1946 /* Check if any of the two operands is already scheduled
1947 for replacement by reload. This can happen e.g. when
1948 float registers occur in an address. */
1949 sum1 = find_replacement (&XEXP (src, 0));
1950 sum2 = find_replacement (&XEXP (src, 1));
1951 src = gen_rtx_PLUS (Pmode, sum1, sum2);
1953 /* If the address is already strictly valid, there's nothing to do. */
1954 if (!s390_decompose_address (src, &ad)
1955 || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
1956 || (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
1958 /* Otherwise, one of the operands cannot be an address register;
1959 we reload its value into the scratch register. */
1960 if (true_regnum (sum1) < 1 || true_regnum (sum1) > 15)
1962 emit_move_insn (scratch, sum1);
1963 sum1 = scratch;
1965 if (true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
1967 emit_move_insn (scratch, sum2);
1968 sum2 = scratch;
1971 /* According to the way these invalid addresses are generated
1972 in reload.c, it should never happen (at least on s390) that
1973 *neither* of the PLUS components, after find_replacements
1974 was applied, is an address register. */
1975 if (sum1 == scratch && sum2 == scratch)
1977 debug_rtx (src);
1978 abort ();
1981 src = gen_rtx_PLUS (Pmode, sum1, sum2);
1984 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
1985 is only ever performed on addresses, so we can mark the
1986 sum as legitimate for LA in any case. */
1987 s390_load_address (target, src);
1991 /* Decompose a RTL expression ADDR for a memory address into
1992 its components, returned in OUT.
1994 Returns 0 if ADDR is not a valid memory address, nonzero
1995 otherwise. If OUT is NULL, don't return the components,
1996 but check for validity only.
1998 Note: Only addresses in canonical form are recognized.
1999 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
2000 canonical form so that they will be recognized. */
2002 static int
2003 s390_decompose_address (register rtx addr, struct s390_address *out)
2005 rtx base = NULL_RTX;
2006 rtx indx = NULL_RTX;
2007 rtx disp = NULL_RTX;
2008 int pointer = FALSE;
2009 int base_ptr = FALSE;
2010 int indx_ptr = FALSE;
2012 /* Decompose address into base + index + displacement. */
2014 if (GET_CODE (addr) == REG || GET_CODE (addr) == UNSPEC)
2015 base = addr;
2017 else if (GET_CODE (addr) == PLUS)
2019 rtx op0 = XEXP (addr, 0);
2020 rtx op1 = XEXP (addr, 1);
2021 enum rtx_code code0 = GET_CODE (op0);
2022 enum rtx_code code1 = GET_CODE (op1);
2024 if (code0 == REG || code0 == UNSPEC)
2026 if (code1 == REG || code1 == UNSPEC)
2028 indx = op0; /* index + base */
2029 base = op1;
2032 else
2034 base = op0; /* base + displacement */
2035 disp = op1;
2039 else if (code0 == PLUS)
2041 indx = XEXP (op0, 0); /* index + base + disp */
2042 base = XEXP (op0, 1);
2043 disp = op1;
2046 else
2048 return FALSE;
2052 else
2053 disp = addr; /* displacement */
2056 /* Validate base register. */
2057 if (base)
2059 if (GET_CODE (base) == UNSPEC)
2061 if (XVECLEN (base, 0) != 1 || XINT (base, 1) != UNSPEC_LTREL_BASE)
2062 return FALSE;
2063 base = gen_rtx_REG (Pmode, BASE_REGISTER);
2066 if (GET_CODE (base) != REG || GET_MODE (base) != Pmode)
2067 return FALSE;
2069 if (REGNO (base) == BASE_REGISTER
2070 || REGNO (base) == STACK_POINTER_REGNUM
2071 || REGNO (base) == FRAME_POINTER_REGNUM
2072 || ((reload_completed || reload_in_progress)
2073 && frame_pointer_needed
2074 && REGNO (base) == HARD_FRAME_POINTER_REGNUM)
2075 || REGNO (base) == ARG_POINTER_REGNUM
2076 || (flag_pic
2077 && REGNO (base) == PIC_OFFSET_TABLE_REGNUM))
2078 pointer = base_ptr = TRUE;
2081 /* Validate index register. */
2082 if (indx)
2084 if (GET_CODE (indx) == UNSPEC)
2086 if (XVECLEN (indx, 0) != 1 || XINT (indx, 1) != UNSPEC_LTREL_BASE)
2087 return FALSE;
2088 indx = gen_rtx_REG (Pmode, BASE_REGISTER);
2091 if (GET_CODE (indx) != REG || GET_MODE (indx) != Pmode)
2092 return FALSE;
2094 if (REGNO (indx) == BASE_REGISTER
2095 || REGNO (indx) == STACK_POINTER_REGNUM
2096 || REGNO (indx) == FRAME_POINTER_REGNUM
2097 || ((reload_completed || reload_in_progress)
2098 && frame_pointer_needed
2099 && REGNO (indx) == HARD_FRAME_POINTER_REGNUM)
2100 || REGNO (indx) == ARG_POINTER_REGNUM
2101 || (flag_pic
2102 && REGNO (indx) == PIC_OFFSET_TABLE_REGNUM))
2103 pointer = indx_ptr = TRUE;
2106 /* Prefer to use pointer as base, not index. */
2107 if (base && indx && !base_ptr
2108 && (indx_ptr || (!REG_POINTER (base) && REG_POINTER (indx))))
2110 rtx tmp = base;
2111 base = indx;
2112 indx = tmp;
2115 /* Validate displacement. */
2116 if (disp)
2118 /* Allow integer constant in range. */
2119 if (GET_CODE (disp) == CONST_INT)
2121 /* If the argument pointer is involved, the displacement will change
2122 later anyway as the argument pointer gets eliminated. This could
2123 make a valid displacement invalid, but it is more likely to make
2124 an invalid displacement valid, because we sometimes access the
2125 register save area via negative offsets to the arg pointer.
2126 Thus we don't check the displacement for validity here. If after
2127 elimination the displacement turns out to be invalid after all,
2128 this is fixed up by reload in any case. */
2129 if (base != arg_pointer_rtx && indx != arg_pointer_rtx)
2131 if (!DISP_IN_RANGE (INTVAL (disp)))
2132 return FALSE;
2136 /* In the small-PIC case, the linker converts @GOT
2137 and @GOTNTPOFF offsets to possible displacements. */
2138 else if (GET_CODE (disp) == CONST
2139 && GET_CODE (XEXP (disp, 0)) == UNSPEC
2140 && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOT
2141 || XINT (XEXP (disp, 0), 1) == UNSPEC_GOTNTPOFF))
2143 if (flag_pic != 1)
2144 return FALSE;
2146 pointer = TRUE;
2149 /* Accept chunkfied literal pool symbol references. */
2150 else if (GET_CODE (disp) == CONST
2151 && GET_CODE (XEXP (disp, 0)) == MINUS
2152 && GET_CODE (XEXP (XEXP (disp, 0), 0)) == LABEL_REF
2153 && GET_CODE (XEXP (XEXP (disp, 0), 1)) == LABEL_REF)
2155 pointer = TRUE;
2158 /* Likewise if a constant offset is present. */
2159 else if (GET_CODE (disp) == CONST
2160 && GET_CODE (XEXP (disp, 0)) == PLUS
2161 && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT
2162 && GET_CODE (XEXP (XEXP (disp, 0), 0)) == MINUS
2163 && GET_CODE (XEXP (XEXP (XEXP (disp, 0), 0), 0)) == LABEL_REF
2164 && GET_CODE (XEXP (XEXP (XEXP (disp, 0), 0), 1)) == LABEL_REF)
2166 pointer = TRUE;
2169 /* We can convert literal pool addresses to
2170 displacements by basing them off the base register. */
2171 else
2173 /* In some cases, we can accept an additional
2174 small constant offset. Split these off here. */
2176 unsigned int offset = 0;
2178 if (GET_CODE (disp) == CONST
2179 && GET_CODE (XEXP (disp, 0)) == PLUS
2180 && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT)
2182 offset = INTVAL (XEXP (XEXP (disp, 0), 1));
2183 disp = XEXP (XEXP (disp, 0), 0);
2186 /* Now we must have a literal pool address. */
2187 if (GET_CODE (disp) != SYMBOL_REF
2188 || !CONSTANT_POOL_ADDRESS_P (disp))
2189 return FALSE;
2191 /* If we have an offset, make sure it does not
2192 exceed the size of the constant pool entry. */
2193 if (offset && offset >= GET_MODE_SIZE (get_pool_mode (disp)))
2194 return FALSE;
2196 /* Either base or index must be free to
2197 hold the base register. */
2198 if (base && indx)
2199 return FALSE;
2201 /* Convert the address. */
2202 if (base)
2203 indx = gen_rtx_REG (Pmode, BASE_REGISTER);
2204 else
2205 base = gen_rtx_REG (Pmode, BASE_REGISTER);
2207 disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp),
2208 UNSPEC_LTREL_OFFSET);
2209 disp = gen_rtx_CONST (Pmode, disp);
2211 if (offset)
2212 disp = plus_constant (disp, offset);
2214 pointer = TRUE;
2218 if (!base && !indx)
2219 pointer = TRUE;
2221 if (out)
2223 out->base = base;
2224 out->indx = indx;
2225 out->disp = disp;
2226 out->pointer = pointer;
2229 return TRUE;
2232 /* Return nonzero if ADDR is a valid memory address.
2233 STRICT specifies whether strict register checking applies. */
2236 legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
2237 register rtx addr, int strict)
2239 struct s390_address ad;
2240 if (!s390_decompose_address (addr, &ad))
2241 return FALSE;
2243 if (strict)
2245 if (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
2246 return FALSE;
2247 if (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx))
2248 return FALSE;
2250 else
2252 if (ad.base && !REG_OK_FOR_BASE_NONSTRICT_P (ad.base))
2253 return FALSE;
2254 if (ad.indx && !REG_OK_FOR_INDEX_NONSTRICT_P (ad.indx))
2255 return FALSE;
2258 return TRUE;
2261 /* Return 1 if OP is a valid operand for the LA instruction.
2262 In 31-bit, we need to prove that the result is used as an
2263 address, as LA performs only a 31-bit addition. */
2266 legitimate_la_operand_p (register rtx op)
2268 struct s390_address addr;
2269 if (!s390_decompose_address (op, &addr))
2270 return FALSE;
2272 if (TARGET_64BIT || addr.pointer)
2273 return TRUE;
2275 return FALSE;
2278 /* Return 1 if OP is a valid operand for the LA instruction,
2279 and we prefer to use LA over addition to compute it. */
2282 preferred_la_operand_p (register rtx op)
2284 struct s390_address addr;
2285 if (!s390_decompose_address (op, &addr))
2286 return FALSE;
2288 if (!TARGET_64BIT && !addr.pointer)
2289 return FALSE;
2291 if (addr.pointer)
2292 return TRUE;
2294 if ((addr.base && REG_P (addr.base) && REG_POINTER (addr.base))
2295 || (addr.indx && REG_P (addr.indx) && REG_POINTER (addr.indx)))
2296 return TRUE;
2298 return FALSE;
2301 /* Emit a forced load-address operation to load SRC into DST.
2302 This will use the LOAD ADDRESS instruction even in situations
2303 where legitimate_la_operand_p (SRC) returns false. */
2305 void
2306 s390_load_address (rtx dst, rtx src)
2308 if (TARGET_64BIT)
2309 emit_move_insn (dst, src);
2310 else
2311 emit_insn (gen_force_la_31 (dst, src));
2314 /* Return a legitimate reference for ORIG (an address) using the
2315 register REG. If REG is 0, a new pseudo is generated.
2317 There are two types of references that must be handled:
2319 1. Global data references must load the address from the GOT, via
2320 the PIC reg. An insn is emitted to do this load, and the reg is
2321 returned.
2323 2. Static data references, constant pool addresses, and code labels
2324 compute the address as an offset from the GOT, whose base is in
2325 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
2326 differentiate them from global data objects. The returned
2327 address is the PIC reg + an unspec constant.
2329 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2330 reg also appears in the address. */
2333 legitimize_pic_address (rtx orig, rtx reg)
2335 rtx addr = orig;
2336 rtx new = orig;
2337 rtx base;
2339 if (GET_CODE (addr) == LABEL_REF
2340 || (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (addr)))
2342 /* This is a local symbol. */
2343 if (TARGET_CPU_ZARCH && larl_operand (addr, VOIDmode))
2345 /* Access local symbols PC-relative via LARL.
2346 This is the same as in the non-PIC case, so it is
2347 handled automatically ... */
2349 else
2351 /* Access local symbols relative to the GOT. */
2353 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2355 if (reload_in_progress || reload_completed)
2356 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2358 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
2359 addr = gen_rtx_CONST (Pmode, addr);
2360 addr = force_const_mem (Pmode, addr);
2361 emit_move_insn (temp, addr);
2363 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2364 if (reg != 0)
2366 emit_move_insn (reg, new);
2367 new = reg;
2371 else if (GET_CODE (addr) == SYMBOL_REF)
2373 if (reg == 0)
2374 reg = gen_reg_rtx (Pmode);
2376 if (flag_pic == 1)
2378 /* Assume GOT offset < 4k. This is handled the same way
2379 in both 31- and 64-bit code (@GOT). */
2381 if (reload_in_progress || reload_completed)
2382 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2384 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
2385 new = gen_rtx_CONST (Pmode, new);
2386 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
2387 new = gen_rtx_MEM (Pmode, new);
2388 RTX_UNCHANGING_P (new) = 1;
2389 emit_move_insn (reg, new);
2390 new = reg;
2392 else if (TARGET_CPU_ZARCH)
2394 /* If the GOT offset might be >= 4k, we determine the position
2395 of the GOT entry via a PC-relative LARL (@GOTENT). */
2397 rtx temp = gen_reg_rtx (Pmode);
2399 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTENT);
2400 new = gen_rtx_CONST (Pmode, new);
2401 emit_move_insn (temp, new);
2403 new = gen_rtx_MEM (Pmode, temp);
2404 RTX_UNCHANGING_P (new) = 1;
2405 emit_move_insn (reg, new);
2406 new = reg;
2408 else
2410 /* If the GOT offset might be >= 4k, we have to load it
2411 from the literal pool (@GOT). */
2413 rtx temp = gen_reg_rtx (Pmode);
2415 if (reload_in_progress || reload_completed)
2416 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2418 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
2419 addr = gen_rtx_CONST (Pmode, addr);
2420 addr = force_const_mem (Pmode, addr);
2421 emit_move_insn (temp, addr);
2423 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2424 new = gen_rtx_MEM (Pmode, new);
2425 RTX_UNCHANGING_P (new) = 1;
2426 emit_move_insn (reg, new);
2427 new = reg;
2430 else
2432 if (GET_CODE (addr) == CONST)
2434 addr = XEXP (addr, 0);
2435 if (GET_CODE (addr) == UNSPEC)
2437 if (XVECLEN (addr, 0) != 1)
2438 abort ();
2439 switch (XINT (addr, 1))
2441 /* If someone moved a GOT-relative UNSPEC
2442 out of the literal pool, force them back in. */
2443 case UNSPEC_GOTOFF:
2444 case UNSPEC_PLTOFF:
2445 new = force_const_mem (Pmode, orig);
2446 break;
2448 /* @GOT is OK as is if small. */
2449 case UNSPEC_GOT:
2450 if (flag_pic == 2)
2451 new = force_const_mem (Pmode, orig);
2452 break;
2454 /* @GOTENT is OK as is. */
2455 case UNSPEC_GOTENT:
2456 break;
2458 /* @PLT is OK as is on 64-bit, must be converted to
2459 GOT-relative @PLTOFF on 31-bit. */
2460 case UNSPEC_PLT:
2461 if (!TARGET_CPU_ZARCH)
2463 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2465 if (reload_in_progress || reload_completed)
2466 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2468 addr = XVECEXP (addr, 0, 0);
2469 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
2470 UNSPEC_PLTOFF);
2471 addr = gen_rtx_CONST (Pmode, addr);
2472 addr = force_const_mem (Pmode, addr);
2473 emit_move_insn (temp, addr);
2475 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2476 if (reg != 0)
2478 emit_move_insn (reg, new);
2479 new = reg;
2482 break;
2484 /* Everything else cannot happen. */
2485 default:
2486 abort ();
2489 else if (GET_CODE (addr) != PLUS)
2490 abort ();
2492 if (GET_CODE (addr) == PLUS)
2494 rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
2495 /* Check first to see if this is a constant offset
2496 from a local symbol reference. */
2497 if ((GET_CODE (op0) == LABEL_REF
2498 || (GET_CODE (op0) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op0)))
2499 && GET_CODE (op1) == CONST_INT)
2501 if (TARGET_CPU_ZARCH && larl_operand (op0, VOIDmode))
2503 if (INTVAL (op1) & 1)
2505 /* LARL can't handle odd offsets, so emit a
2506 pair of LARL and LA. */
2507 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2509 if (!DISP_IN_RANGE (INTVAL (op1)))
2511 int even = INTVAL (op1) - 1;
2512 op0 = gen_rtx_PLUS (Pmode, op0, GEN_INT (even));
2513 op0 = gen_rtx_CONST (Pmode, op0);
2514 op1 = GEN_INT (1);
2517 emit_move_insn (temp, op0);
2518 new = gen_rtx_PLUS (Pmode, temp, op1);
2520 if (reg != 0)
2522 emit_move_insn (reg, new);
2523 new = reg;
2526 else
2528 /* If the offset is even, we can just use LARL.
2529 This will happen automatically. */
2532 else
2534 /* Access local symbols relative to the GOT. */
2536 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2538 if (reload_in_progress || reload_completed)
2539 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2541 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
2542 UNSPEC_GOTOFF);
2543 addr = gen_rtx_PLUS (Pmode, addr, op1);
2544 addr = gen_rtx_CONST (Pmode, addr);
2545 addr = force_const_mem (Pmode, addr);
2546 emit_move_insn (temp, addr);
2548 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2549 if (reg != 0)
2551 emit_move_insn (reg, new);
2552 new = reg;
2557 /* Now, check whether it is a GOT relative symbol plus offset
2558 that was pulled out of the literal pool. Force it back in. */
2560 else if (GET_CODE (op0) == UNSPEC
2561 && GET_CODE (op1) == CONST_INT
2562 && XINT (op0, 1) == UNSPEC_GOTOFF)
2564 if (XVECLEN (op0, 0) != 1)
2565 abort ();
2567 new = force_const_mem (Pmode, orig);
2570 /* Otherwise, compute the sum. */
2571 else
2573 base = legitimize_pic_address (XEXP (addr, 0), reg);
2574 new = legitimize_pic_address (XEXP (addr, 1),
2575 base == reg ? NULL_RTX : reg);
2576 if (GET_CODE (new) == CONST_INT)
2577 new = plus_constant (base, INTVAL (new));
2578 else
2580 if (GET_CODE (new) == PLUS && CONSTANT_P (XEXP (new, 1)))
2582 base = gen_rtx_PLUS (Pmode, base, XEXP (new, 0));
2583 new = XEXP (new, 1);
2585 new = gen_rtx_PLUS (Pmode, base, new);
2588 if (GET_CODE (new) == CONST)
2589 new = XEXP (new, 0);
2590 new = force_operand (new, 0);
2594 return new;
2597 /* Load the thread pointer into a register. */
2599 static rtx
2600 get_thread_pointer (void)
2602 rtx tp;
2604 tp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
2605 tp = force_reg (Pmode, tp);
2606 mark_reg_pointer (tp, BITS_PER_WORD);
2608 return tp;
2611 /* Construct the SYMBOL_REF for the tls_get_offset function. */
2613 static GTY(()) rtx s390_tls_symbol;
2615 s390_tls_get_offset (void)
2617 if (!s390_tls_symbol)
2618 s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset");
2620 return s390_tls_symbol;
2623 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
2624 this (thread-local) address. REG may be used as temporary. */
2626 static rtx
2627 legitimize_tls_address (rtx addr, rtx reg)
2629 rtx new, tls_call, temp, base, r2, insn;
2631 if (GET_CODE (addr) == SYMBOL_REF)
2632 switch (tls_symbolic_operand (addr))
2634 case TLS_MODEL_GLOBAL_DYNAMIC:
2635 start_sequence ();
2636 r2 = gen_rtx_REG (Pmode, 2);
2637 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLSGD);
2638 new = gen_rtx_CONST (Pmode, tls_call);
2639 new = force_const_mem (Pmode, new);
2640 emit_move_insn (r2, new);
2641 emit_call_insn (gen_call_value_tls (r2, tls_call));
2642 insn = get_insns ();
2643 end_sequence ();
2645 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
2646 temp = gen_reg_rtx (Pmode);
2647 emit_libcall_block (insn, temp, r2, new);
2649 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2650 if (reg != 0)
2652 s390_load_address (reg, new);
2653 new = reg;
2655 break;
2657 case TLS_MODEL_LOCAL_DYNAMIC:
2658 start_sequence ();
2659 r2 = gen_rtx_REG (Pmode, 2);
2660 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM);
2661 new = gen_rtx_CONST (Pmode, tls_call);
2662 new = force_const_mem (Pmode, new);
2663 emit_move_insn (r2, new);
2664 emit_call_insn (gen_call_value_tls (r2, tls_call));
2665 insn = get_insns ();
2666 end_sequence ();
2668 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM_NTPOFF);
2669 temp = gen_reg_rtx (Pmode);
2670 emit_libcall_block (insn, temp, r2, new);
2672 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2673 base = gen_reg_rtx (Pmode);
2674 s390_load_address (base, new);
2676 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_DTPOFF);
2677 new = gen_rtx_CONST (Pmode, new);
2678 new = force_const_mem (Pmode, new);
2679 temp = gen_reg_rtx (Pmode);
2680 emit_move_insn (temp, new);
2682 new = gen_rtx_PLUS (Pmode, base, temp);
2683 if (reg != 0)
2685 s390_load_address (reg, new);
2686 new = reg;
2688 break;
2690 case TLS_MODEL_INITIAL_EXEC:
2691 if (flag_pic == 1)
2693 /* Assume GOT offset < 4k. This is handled the same way
2694 in both 31- and 64-bit code. */
2696 if (reload_in_progress || reload_completed)
2697 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2699 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
2700 new = gen_rtx_CONST (Pmode, new);
2701 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
2702 new = gen_rtx_MEM (Pmode, new);
2703 RTX_UNCHANGING_P (new) = 1;
2704 temp = gen_reg_rtx (Pmode);
2705 emit_move_insn (temp, new);
2707 else if (TARGET_CPU_ZARCH)
2709 /* If the GOT offset might be >= 4k, we determine the position
2710 of the GOT entry via a PC-relative LARL. */
2712 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
2713 new = gen_rtx_CONST (Pmode, new);
2714 temp = gen_reg_rtx (Pmode);
2715 emit_move_insn (temp, new);
2717 new = gen_rtx_MEM (Pmode, temp);
2718 RTX_UNCHANGING_P (new) = 1;
2719 temp = gen_reg_rtx (Pmode);
2720 emit_move_insn (temp, new);
2722 else if (flag_pic)
2724 /* If the GOT offset might be >= 4k, we have to load it
2725 from the literal pool. */
2727 if (reload_in_progress || reload_completed)
2728 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2730 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
2731 new = gen_rtx_CONST (Pmode, new);
2732 new = force_const_mem (Pmode, new);
2733 temp = gen_reg_rtx (Pmode);
2734 emit_move_insn (temp, new);
2736 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2737 new = gen_rtx_MEM (Pmode, new);
2738 RTX_UNCHANGING_P (new) = 1;
2740 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new, addr), UNSPEC_TLS_LOAD);
2741 temp = gen_reg_rtx (Pmode);
2742 emit_insn (gen_rtx_SET (Pmode, temp, new));
2744 else
2746 /* In position-dependent code, load the absolute address of
2747 the GOT entry from the literal pool. */
2749 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
2750 new = gen_rtx_CONST (Pmode, new);
2751 new = force_const_mem (Pmode, new);
2752 temp = gen_reg_rtx (Pmode);
2753 emit_move_insn (temp, new);
2755 new = temp;
2756 new = gen_rtx_MEM (Pmode, new);
2757 RTX_UNCHANGING_P (new) = 1;
2759 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new, addr), UNSPEC_TLS_LOAD);
2760 temp = gen_reg_rtx (Pmode);
2761 emit_insn (gen_rtx_SET (Pmode, temp, new));
2764 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2765 if (reg != 0)
2767 s390_load_address (reg, new);
2768 new = reg;
2770 break;
2772 case TLS_MODEL_LOCAL_EXEC:
2773 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
2774 new = gen_rtx_CONST (Pmode, new);
2775 new = force_const_mem (Pmode, new);
2776 temp = gen_reg_rtx (Pmode);
2777 emit_move_insn (temp, new);
2779 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2780 if (reg != 0)
2782 s390_load_address (reg, new);
2783 new = reg;
2785 break;
2787 default:
2788 abort ();
2791 else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == UNSPEC)
2793 switch (XINT (XEXP (addr, 0), 1))
2795 case UNSPEC_INDNTPOFF:
2796 if (TARGET_CPU_ZARCH)
2797 new = addr;
2798 else
2799 abort ();
2800 break;
2802 default:
2803 abort ();
2807 else
2808 abort (); /* for now ... */
2810 return new;
2813 /* Emit insns to move operands[1] into operands[0]. */
2815 void
2816 emit_symbolic_move (rtx *operands)
2818 rtx temp = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
2820 if (GET_CODE (operands[0]) == MEM)
2821 operands[1] = force_reg (Pmode, operands[1]);
2822 else if (TLS_SYMBOLIC_CONST (operands[1]))
2823 operands[1] = legitimize_tls_address (operands[1], temp);
2824 else if (flag_pic)
2825 operands[1] = legitimize_pic_address (operands[1], temp);
2828 /* Try machine-dependent ways of modifying an illegitimate address X
2829 to be legitimate. If we find one, return the new, valid address.
2831 OLDX is the address as it was before break_out_memory_refs was called.
2832 In some cases it is useful to look at this to decide what needs to be done.
2834 MODE is the mode of the operand pointed to by X.
2836 When -fpic is used, special handling is needed for symbolic references.
2837 See comments by legitimize_pic_address for details. */
2840 legitimize_address (register rtx x, register rtx oldx ATTRIBUTE_UNUSED,
2841 enum machine_mode mode ATTRIBUTE_UNUSED)
2843 rtx constant_term = const0_rtx;
2845 if (TLS_SYMBOLIC_CONST (x))
2847 x = legitimize_tls_address (x, 0);
2849 if (legitimate_address_p (mode, x, FALSE))
2850 return x;
2852 else if (flag_pic)
2854 if (SYMBOLIC_CONST (x)
2855 || (GET_CODE (x) == PLUS
2856 && (SYMBOLIC_CONST (XEXP (x, 0))
2857 || SYMBOLIC_CONST (XEXP (x, 1)))))
2858 x = legitimize_pic_address (x, 0);
2860 if (legitimate_address_p (mode, x, FALSE))
2861 return x;
2864 x = eliminate_constant_term (x, &constant_term);
2866 /* Optimize loading of large displacements by splitting them
2867 into the multiple of 4K and the rest; this allows the
2868 former to be CSE'd if possible.
2870 Don't do this if the displacement is added to a register
2871 pointing into the stack frame, as the offsets will
2872 change later anyway. */
2874 if (GET_CODE (constant_term) == CONST_INT
2875 && !TARGET_LONG_DISPLACEMENT
2876 && !DISP_IN_RANGE (INTVAL (constant_term))
2877 && !(REG_P (x) && REGNO_PTR_FRAME_P (REGNO (x))))
2879 HOST_WIDE_INT lower = INTVAL (constant_term) & 0xfff;
2880 HOST_WIDE_INT upper = INTVAL (constant_term) ^ lower;
2882 rtx temp = gen_reg_rtx (Pmode);
2883 rtx val = force_operand (GEN_INT (upper), temp);
2884 if (val != temp)
2885 emit_move_insn (temp, val);
2887 x = gen_rtx_PLUS (Pmode, x, temp);
2888 constant_term = GEN_INT (lower);
2891 if (GET_CODE (x) == PLUS)
2893 if (GET_CODE (XEXP (x, 0)) == REG)
2895 register rtx temp = gen_reg_rtx (Pmode);
2896 register rtx val = force_operand (XEXP (x, 1), temp);
2897 if (val != temp)
2898 emit_move_insn (temp, val);
2900 x = gen_rtx_PLUS (Pmode, XEXP (x, 0), temp);
2903 else if (GET_CODE (XEXP (x, 1)) == REG)
2905 register rtx temp = gen_reg_rtx (Pmode);
2906 register rtx val = force_operand (XEXP (x, 0), temp);
2907 if (val != temp)
2908 emit_move_insn (temp, val);
2910 x = gen_rtx_PLUS (Pmode, temp, XEXP (x, 1));
2914 if (constant_term != const0_rtx)
2915 x = gen_rtx_PLUS (Pmode, x, constant_term);
2917 return x;
2920 /* Emit code to move LEN bytes from DST to SRC. */
2922 void
2923 s390_expand_movstr (rtx dst, rtx src, rtx len)
2925 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
2927 if (INTVAL (len) > 0)
2928 emit_insn (gen_movstr_short (dst, src, GEN_INT (INTVAL (len) - 1)));
2931 else if (TARGET_MVCLE)
2933 emit_insn (gen_movstr_long (dst, src, convert_to_mode (Pmode, len, 1)));
2936 else
2938 rtx dst_addr, src_addr, count, blocks, temp;
2939 rtx end_label = gen_label_rtx ();
2940 enum machine_mode mode;
2941 tree type;
2943 mode = GET_MODE (len);
2944 if (mode == VOIDmode)
2945 mode = Pmode;
2947 type = lang_hooks.types.type_for_mode (mode, 1);
2948 if (!type)
2949 abort ();
2951 dst_addr = gen_reg_rtx (Pmode);
2952 src_addr = gen_reg_rtx (Pmode);
2953 count = gen_reg_rtx (mode);
2954 blocks = gen_reg_rtx (mode);
2956 convert_move (count, len, 1);
2957 emit_cmp_and_jump_insns (count, const0_rtx,
2958 EQ, NULL_RTX, mode, 1, end_label);
2960 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
2961 emit_move_insn (src_addr, force_operand (XEXP (src, 0), NULL_RTX));
2962 dst = change_address (dst, VOIDmode, dst_addr);
2963 src = change_address (src, VOIDmode, src_addr);
2965 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
2966 if (temp != count)
2967 emit_move_insn (count, temp);
2969 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
2970 if (temp != blocks)
2971 emit_move_insn (blocks, temp);
2973 expand_start_loop (1);
2974 expand_exit_loop_top_cond (0, build (NE_EXPR, type,
2975 make_tree (type, blocks),
2976 make_tree (type, const0_rtx)));
2978 emit_insn (gen_movstr_short (dst, src, GEN_INT (255)));
2979 s390_load_address (dst_addr,
2980 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
2981 s390_load_address (src_addr,
2982 gen_rtx_PLUS (Pmode, src_addr, GEN_INT (256)));
2984 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
2985 if (temp != blocks)
2986 emit_move_insn (blocks, temp);
2988 expand_end_loop ();
2990 emit_insn (gen_movstr_short (dst, src,
2991 convert_to_mode (Pmode, count, 1)));
2992 emit_label (end_label);
2996 /* Emit code to clear LEN bytes at DST. */
2998 void
2999 s390_expand_clrstr (rtx dst, rtx len)
3001 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
3003 if (INTVAL (len) > 0)
3004 emit_insn (gen_clrstr_short (dst, GEN_INT (INTVAL (len) - 1)));
3007 else if (TARGET_MVCLE)
3009 emit_insn (gen_clrstr_long (dst, convert_to_mode (Pmode, len, 1)));
3012 else
3014 rtx dst_addr, src_addr, count, blocks, temp;
3015 rtx end_label = gen_label_rtx ();
3016 enum machine_mode mode;
3017 tree type;
3019 mode = GET_MODE (len);
3020 if (mode == VOIDmode)
3021 mode = Pmode;
3023 type = lang_hooks.types.type_for_mode (mode, 1);
3024 if (!type)
3025 abort ();
3027 dst_addr = gen_reg_rtx (Pmode);
3028 src_addr = gen_reg_rtx (Pmode);
3029 count = gen_reg_rtx (mode);
3030 blocks = gen_reg_rtx (mode);
3032 convert_move (count, len, 1);
3033 emit_cmp_and_jump_insns (count, const0_rtx,
3034 EQ, NULL_RTX, mode, 1, end_label);
3036 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
3037 dst = change_address (dst, VOIDmode, dst_addr);
3039 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3040 if (temp != count)
3041 emit_move_insn (count, temp);
3043 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
3044 if (temp != blocks)
3045 emit_move_insn (blocks, temp);
3047 expand_start_loop (1);
3048 expand_exit_loop_top_cond (0, build (NE_EXPR, type,
3049 make_tree (type, blocks),
3050 make_tree (type, const0_rtx)));
3052 emit_insn (gen_clrstr_short (dst, GEN_INT (255)));
3053 s390_load_address (dst_addr,
3054 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
3056 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3057 if (temp != blocks)
3058 emit_move_insn (blocks, temp);
3060 expand_end_loop ();
3062 emit_insn (gen_clrstr_short (dst, convert_to_mode (Pmode, count, 1)));
3063 emit_label (end_label);
3067 /* Emit code to compare LEN bytes at OP0 with those at OP1,
3068 and return the result in TARGET. */
3070 void
3071 s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
3073 rtx (*gen_result) (rtx) =
3074 GET_MODE (target) == DImode ? gen_cmpint_di : gen_cmpint_si;
3076 op0 = protect_from_queue (op0, 0);
3077 op1 = protect_from_queue (op1, 0);
3078 len = protect_from_queue (len, 0);
3080 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
3082 if (INTVAL (len) > 0)
3084 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (INTVAL (len) - 1)));
3085 emit_insn (gen_result (target));
3087 else
3088 emit_move_insn (target, const0_rtx);
3091 else /* if (TARGET_MVCLE) */
3093 emit_insn (gen_cmpmem_long (op0, op1, convert_to_mode (Pmode, len, 1)));
3094 emit_insn (gen_result (target));
3097 #if 0
3098 /* Deactivate for now as profile code cannot cope with
3099 CC being live across basic block boundaries. */
3100 else
3102 rtx addr0, addr1, count, blocks, temp;
3103 rtx end_label = gen_label_rtx ();
3104 enum machine_mode mode;
3105 tree type;
3107 mode = GET_MODE (len);
3108 if (mode == VOIDmode)
3109 mode = Pmode;
3111 type = lang_hooks.types.type_for_mode (mode, 1);
3112 if (!type)
3113 abort ();
3115 addr0 = gen_reg_rtx (Pmode);
3116 addr1 = gen_reg_rtx (Pmode);
3117 count = gen_reg_rtx (mode);
3118 blocks = gen_reg_rtx (mode);
3120 convert_move (count, len, 1);
3121 emit_cmp_and_jump_insns (count, const0_rtx,
3122 EQ, NULL_RTX, mode, 1, end_label);
3124 emit_move_insn (addr0, force_operand (XEXP (op0, 0), NULL_RTX));
3125 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
3126 op0 = change_address (op0, VOIDmode, addr0);
3127 op1 = change_address (op1, VOIDmode, addr1);
3129 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3130 if (temp != count)
3131 emit_move_insn (count, temp);
3133 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
3134 if (temp != blocks)
3135 emit_move_insn (blocks, temp);
3137 expand_start_loop (1);
3138 expand_exit_loop_top_cond (0, build (NE_EXPR, type,
3139 make_tree (type, blocks),
3140 make_tree (type, const0_rtx)));
3142 emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (255)));
3143 temp = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCSmode, 33), const0_rtx);
3144 temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
3145 gen_rtx_LABEL_REF (VOIDmode, end_label), pc_rtx);
3146 temp = gen_rtx_SET (VOIDmode, pc_rtx, temp);
3147 emit_jump_insn (temp);
3149 s390_load_address (addr0,
3150 gen_rtx_PLUS (Pmode, addr0, GEN_INT (256)));
3151 s390_load_address (addr1,
3152 gen_rtx_PLUS (Pmode, addr1, GEN_INT (256)));
3154 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3155 if (temp != blocks)
3156 emit_move_insn (blocks, temp);
3158 expand_end_loop ();
3160 emit_insn (gen_cmpmem_short (op0, op1,
3161 convert_to_mode (Pmode, count, 1)));
3162 emit_label (end_label);
3164 emit_insn (gen_result (target));
3166 #endif
3169 /* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
3170 We need to emit DTP-relative relocations. */
3172 void
3173 s390_output_dwarf_dtprel (FILE *file, int size, rtx x)
3175 switch (size)
3177 case 4:
3178 fputs ("\t.long\t", file);
3179 break;
3180 case 8:
3181 fputs ("\t.quad\t", file);
3182 break;
3183 default:
3184 abort ();
3186 output_addr_const (file, x);
3187 fputs ("@DTPOFF", file);
3190 /* In the name of slightly smaller debug output, and to cater to
3191 general assembler losage, recognize various UNSPEC sequences
3192 and turn them back into a direct symbol reference. */
3194 static rtx
3195 s390_delegitimize_address (rtx orig_x)
3197 rtx x = orig_x, y;
3199 if (GET_CODE (x) != MEM)
3200 return orig_x;
3202 x = XEXP (x, 0);
3203 if (GET_CODE (x) == PLUS
3204 && GET_CODE (XEXP (x, 1)) == CONST
3205 && GET_CODE (XEXP (x, 0)) == REG
3206 && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM)
3208 y = XEXP (XEXP (x, 1), 0);
3209 if (GET_CODE (y) == UNSPEC
3210 && XINT (y, 1) == UNSPEC_GOT)
3211 return XVECEXP (y, 0, 0);
3212 return orig_x;
3215 if (GET_CODE (x) == CONST)
3217 y = XEXP (x, 0);
3218 if (GET_CODE (y) == UNSPEC
3219 && XINT (y, 1) == UNSPEC_GOTENT)
3220 return XVECEXP (y, 0, 0);
3221 return orig_x;
3224 return orig_x;
3227 /* Output shift count operand OP to stdio stream FILE. */
3229 static void
3230 print_shift_count_operand (FILE *file, rtx op)
3232 HOST_WIDE_INT offset = 0;
3234 /* We can have an integer constant, an address register,
3235 or a sum of the two. */
3236 if (GET_CODE (op) == CONST_INT)
3238 offset = INTVAL (op);
3239 op = NULL_RTX;
3241 if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
3243 offset = INTVAL (XEXP (op, 1));
3244 op = XEXP (op, 0);
3246 while (op && GET_CODE (op) == SUBREG)
3247 op = SUBREG_REG (op);
3249 /* Sanity check. */
3250 if (op && (GET_CODE (op) != REG
3251 || REGNO (op) >= FIRST_PSEUDO_REGISTER
3252 || REGNO_REG_CLASS (REGNO (op)) != ADDR_REGS))
3253 abort ();
3255 /* Shift counts are truncated to the low six bits anyway. */
3256 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset & 63);
3257 if (op)
3258 fprintf (file, "(%s)", reg_names[REGNO (op)]);
3261 /* Locate some local-dynamic symbol still in use by this function
3262 so that we can print its name in local-dynamic base patterns. */
3264 static const char *
3265 get_some_local_dynamic_name (void)
3267 rtx insn;
3269 if (cfun->machine->some_ld_name)
3270 return cfun->machine->some_ld_name;
3272 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
3273 if (INSN_P (insn)
3274 && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
3275 return cfun->machine->some_ld_name;
3277 abort ();
3280 static int
3281 get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
3283 rtx x = *px;
3285 if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
3287 x = get_pool_constant (x);
3288 return for_each_rtx (&x, get_some_local_dynamic_name_1, 0);
3291 if (GET_CODE (x) == SYMBOL_REF
3292 && tls_symbolic_operand (x) == TLS_MODEL_LOCAL_DYNAMIC)
3294 cfun->machine->some_ld_name = XSTR (x, 0);
3295 return 1;
3298 return 0;
3301 /* Output symbolic constant X in assembler syntax to
3302 stdio stream FILE. */
3304 void
3305 s390_output_symbolic_const (FILE *file, rtx x)
3307 switch (GET_CODE (x))
3309 case CONST:
3310 case ZERO_EXTEND:
3311 case SIGN_EXTEND:
3312 s390_output_symbolic_const (file, XEXP (x, 0));
3313 break;
3315 case PLUS:
3316 s390_output_symbolic_const (file, XEXP (x, 0));
3317 fprintf (file, "+");
3318 s390_output_symbolic_const (file, XEXP (x, 1));
3319 break;
3321 case MINUS:
3322 s390_output_symbolic_const (file, XEXP (x, 0));
3323 fprintf (file, "-");
3324 s390_output_symbolic_const (file, XEXP (x, 1));
3325 break;
3327 case CONST_INT:
3328 case LABEL_REF:
3329 case CODE_LABEL:
3330 case SYMBOL_REF:
3331 output_addr_const (file, x);
3332 break;
3334 case UNSPEC:
3335 if (XVECLEN (x, 0) != 1)
3336 output_operand_lossage ("invalid UNSPEC as operand (1)");
3337 switch (XINT (x, 1))
3339 case UNSPEC_GOTENT:
3340 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3341 fprintf (file, "@GOTENT");
3342 break;
3343 case UNSPEC_GOT:
3344 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3345 fprintf (file, "@GOT");
3346 break;
3347 case UNSPEC_GOTOFF:
3348 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3349 fprintf (file, "@GOTOFF");
3350 break;
3351 case UNSPEC_PLT:
3352 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3353 fprintf (file, "@PLT");
3354 break;
3355 case UNSPEC_PLTOFF:
3356 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3357 fprintf (file, "@PLTOFF");
3358 break;
3359 case UNSPEC_TLSGD:
3360 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3361 fprintf (file, "@TLSGD");
3362 break;
3363 case UNSPEC_TLSLDM:
3364 assemble_name (file, get_some_local_dynamic_name ());
3365 fprintf (file, "@TLSLDM");
3366 break;
3367 case UNSPEC_DTPOFF:
3368 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3369 fprintf (file, "@DTPOFF");
3370 break;
3371 case UNSPEC_NTPOFF:
3372 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3373 fprintf (file, "@NTPOFF");
3374 break;
3375 case UNSPEC_GOTNTPOFF:
3376 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3377 fprintf (file, "@GOTNTPOFF");
3378 break;
3379 case UNSPEC_INDNTPOFF:
3380 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3381 fprintf (file, "@INDNTPOFF");
3382 break;
3383 default:
3384 output_operand_lossage ("invalid UNSPEC as operand (2)");
3385 break;
3387 break;
3389 default:
3390 fatal_insn ("UNKNOWN in s390_output_symbolic_const !?", x);
3391 break;
3395 /* Output address operand ADDR in assembler syntax to
3396 stdio stream FILE. */
3398 void
3399 print_operand_address (FILE *file, rtx addr)
3401 struct s390_address ad;
3403 if (!s390_decompose_address (addr, &ad)
3404 || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
3405 || (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
3406 output_operand_lossage ("Cannot decompose address.");
3408 if (ad.disp)
3409 s390_output_symbolic_const (file, ad.disp);
3410 else
3411 fprintf (file, "0");
3413 if (ad.base && ad.indx)
3414 fprintf (file, "(%s,%s)", reg_names[REGNO (ad.indx)],
3415 reg_names[REGNO (ad.base)]);
3416 else if (ad.base)
3417 fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
3420 /* Output operand X in assembler syntax to stdio stream FILE.
3421 CODE specified the format flag. The following format flags
3422 are recognized:
3424 'C': print opcode suffix for branch condition.
3425 'D': print opcode suffix for inverse branch condition.
3426 'J': print tls_load/tls_gdcall/tls_ldcall suffix
3427 'O': print only the displacement of a memory reference.
3428 'R': print only the base register of a memory reference.
3429 'N': print the second word of a DImode operand.
3430 'M': print the second word of a TImode operand.
3431 'Y': print shift count operand.
3433 'b': print integer X as if it's an unsigned byte.
3434 'x': print integer X as if it's an unsigned word.
3435 'h': print integer X as if it's a signed word.
3436 'i': print the first nonzero HImode part of X.
3437 'j': print the first HImode part unequal to 0xffff of X. */
3439 void
3440 print_operand (FILE *file, rtx x, int code)
3442 switch (code)
3444 case 'C':
3445 fprintf (file, s390_branch_condition_mnemonic (x, FALSE));
3446 return;
3448 case 'D':
3449 fprintf (file, s390_branch_condition_mnemonic (x, TRUE));
3450 return;
3452 case 'J':
3453 if (GET_CODE (x) == SYMBOL_REF)
3455 fprintf (file, "%s", ":tls_load:");
3456 output_addr_const (file, x);
3458 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD)
3460 fprintf (file, "%s", ":tls_gdcall:");
3461 output_addr_const (file, XVECEXP (x, 0, 0));
3463 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM)
3465 fprintf (file, "%s", ":tls_ldcall:");
3466 assemble_name (file, get_some_local_dynamic_name ());
3468 else
3469 abort ();
3470 return;
3472 case 'O':
3474 struct s390_address ad;
3476 if (GET_CODE (x) != MEM
3477 || !s390_decompose_address (XEXP (x, 0), &ad)
3478 || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
3479 || ad.indx)
3480 abort ();
3482 if (ad.disp)
3483 s390_output_symbolic_const (file, ad.disp);
3484 else
3485 fprintf (file, "0");
3487 return;
3489 case 'R':
3491 struct s390_address ad;
3493 if (GET_CODE (x) != MEM
3494 || !s390_decompose_address (XEXP (x, 0), &ad)
3495 || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
3496 || ad.indx)
3497 abort ();
3499 if (ad.base)
3500 fprintf (file, "%s", reg_names[REGNO (ad.base)]);
3501 else
3502 fprintf (file, "0");
3504 return;
3506 case 'N':
3507 if (GET_CODE (x) == REG)
3508 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
3509 else if (GET_CODE (x) == MEM)
3510 x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 4));
3511 else
3512 abort ();
3513 break;
3515 case 'M':
3516 if (GET_CODE (x) == REG)
3517 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
3518 else if (GET_CODE (x) == MEM)
3519 x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 8));
3520 else
3521 abort ();
3522 break;
3524 case 'Y':
3525 print_shift_count_operand (file, x);
3526 return;
3529 switch (GET_CODE (x))
3531 case REG:
3532 fprintf (file, "%s", reg_names[REGNO (x)]);
3533 break;
3535 case MEM:
3536 output_address (XEXP (x, 0));
3537 break;
3539 case CONST:
3540 case CODE_LABEL:
3541 case LABEL_REF:
3542 case SYMBOL_REF:
3543 s390_output_symbolic_const (file, x);
3544 break;
3546 case CONST_INT:
3547 if (code == 'b')
3548 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xff);
3549 else if (code == 'x')
3550 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffff);
3551 else if (code == 'h')
3552 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000);
3553 else if (code == 'i')
3554 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3555 s390_extract_part (x, HImode, 0));
3556 else if (code == 'j')
3557 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3558 s390_extract_part (x, HImode, -1));
3559 else
3560 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
3561 break;
3563 case CONST_DOUBLE:
3564 if (GET_MODE (x) != VOIDmode)
3565 abort ();
3566 if (code == 'b')
3567 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xff);
3568 else if (code == 'x')
3569 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xffff);
3570 else if (code == 'h')
3571 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((CONST_DOUBLE_LOW (x) & 0xffff) ^ 0x8000) - 0x8000);
3572 else
3573 abort ();
3574 break;
3576 default:
3577 fatal_insn ("UNKNOWN in print_operand !?", x);
3578 break;
3582 /* Target hook for assembling integer objects. We need to define it
3583 here to work a round a bug in some versions of GAS, which couldn't
3584 handle values smaller than INT_MIN when printed in decimal. */
3586 static bool
3587 s390_assemble_integer (rtx x, unsigned int size, int aligned_p)
3589 if (size == 8 && aligned_p
3590 && GET_CODE (x) == CONST_INT && INTVAL (x) < INT_MIN)
3592 fprintf (asm_out_file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n",
3593 INTVAL (x));
3594 return true;
3596 return default_assemble_integer (x, size, aligned_p);
3599 /* Returns true if register REGNO is used for forming
3600 a memory address in expression X. */
3602 static int
3603 reg_used_in_mem_p (int regno, rtx x)
3605 enum rtx_code code = GET_CODE (x);
3606 int i, j;
3607 const char *fmt;
3609 if (code == MEM)
3611 if (refers_to_regno_p (regno, regno+1,
3612 XEXP (x, 0), 0))
3613 return 1;
3615 else if (code == SET
3616 && GET_CODE (SET_DEST (x)) == PC)
3618 if (refers_to_regno_p (regno, regno+1,
3619 SET_SRC (x), 0))
3620 return 1;
3623 fmt = GET_RTX_FORMAT (code);
3624 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3626 if (fmt[i] == 'e'
3627 && reg_used_in_mem_p (regno, XEXP (x, i)))
3628 return 1;
3630 else if (fmt[i] == 'E')
3631 for (j = 0; j < XVECLEN (x, i); j++)
3632 if (reg_used_in_mem_p (regno, XVECEXP (x, i, j)))
3633 return 1;
3635 return 0;
3638 /* Returns true if expression DEP_RTX sets an address register
3639 used by instruction INSN to address memory. */
3641 static int
3642 addr_generation_dependency_p (rtx dep_rtx, rtx insn)
3644 rtx target, pat;
3646 if (GET_CODE (dep_rtx) == INSN)
3647 dep_rtx = PATTERN (dep_rtx);
3649 if (GET_CODE (dep_rtx) == SET)
3651 target = SET_DEST (dep_rtx);
3652 if (GET_CODE (target) == STRICT_LOW_PART)
3653 target = XEXP (target, 0);
3654 while (GET_CODE (target) == SUBREG)
3655 target = SUBREG_REG (target);
3657 if (GET_CODE (target) == REG)
3659 int regno = REGNO (target);
3661 if (s390_safe_attr_type (insn) == TYPE_LA)
3663 pat = PATTERN (insn);
3664 if (GET_CODE (pat) == PARALLEL)
3666 if (XVECLEN (pat, 0) != 2)
3667 abort();
3668 pat = XVECEXP (pat, 0, 0);
3670 if (GET_CODE (pat) == SET)
3671 return refers_to_regno_p (regno, regno+1, SET_SRC (pat), 0);
3672 else
3673 abort();
3675 else if (get_attr_atype (insn) == ATYPE_AGEN)
3676 return reg_used_in_mem_p (regno, PATTERN (insn));
3679 return 0;
3682 /* Return 1, if dep_insn sets register used in insn in the agen unit. */
3685 s390_agen_dep_p (rtx dep_insn, rtx insn)
3687 rtx dep_rtx = PATTERN (dep_insn);
3688 int i;
3690 if (GET_CODE (dep_rtx) == SET
3691 && addr_generation_dependency_p (dep_rtx, insn))
3692 return 1;
3693 else if (GET_CODE (dep_rtx) == PARALLEL)
3695 for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
3697 if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i), insn))
3698 return 1;
3701 return 0;
3704 /* Return the modified cost of the dependency of instruction INSN
3705 on instruction DEP_INSN through the link LINK. COST is the
3706 default cost of that dependency.
3708 Data dependencies are all handled without delay. However, if a
3709 register is modified and subsequently used as base or index
3710 register of a memory reference, at least 4 cycles need to pass
3711 between setting and using the register to avoid pipeline stalls.
3712 An exception is the LA instruction. An address generated by LA can
3713 be used by introducing only a one cycle stall on the pipeline. */
3715 static int
3716 s390_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
3718 rtx dep_rtx;
3719 int i;
3721 /* If the dependence is an anti-dependence, there is no cost. For an
3722 output dependence, there is sometimes a cost, but it doesn't seem
3723 worth handling those few cases. */
3725 if (REG_NOTE_KIND (link) != 0)
3726 return 0;
3728 /* If we can't recognize the insns, we can't really do anything. */
3729 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
3730 return cost;
3732 /* DFA based scheduling checks address dependency in md file. */
3733 if (s390_use_dfa_pipeline_interface ())
3735 /* Operand forward in case of lr, load and la. */
3736 if (s390_tune == PROCESSOR_2084_Z990
3737 && cost == 1
3738 && (s390_safe_attr_type (dep_insn) == TYPE_LA
3739 || s390_safe_attr_type (dep_insn) == TYPE_LR
3740 || s390_safe_attr_type (dep_insn) == TYPE_LOAD))
3741 return 0;
3742 return cost;
3745 dep_rtx = PATTERN (dep_insn);
3747 if (GET_CODE (dep_rtx) == SET
3748 && addr_generation_dependency_p (dep_rtx, insn))
3749 cost += (s390_safe_attr_type (dep_insn) == TYPE_LA) ? 1 : 4;
3750 else if (GET_CODE (dep_rtx) == PARALLEL)
3752 for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
3754 if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i), insn))
3755 cost += (s390_safe_attr_type (dep_insn) == TYPE_LA) ? 1 : 4;
3759 return cost;
3761 /* A C statement (sans semicolon) to update the integer scheduling priority
3762 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
3763 reduce the priority to execute INSN later. Do not define this macro if
3764 you do not need to adjust the scheduling priorities of insns.
3766 A STD instruction should be scheduled earlier,
3767 in order to use the bypass. */
3769 static int
3770 s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
3772 if (! INSN_P (insn))
3773 return priority;
3775 if (s390_tune != PROCESSOR_2084_Z990)
3776 return priority;
3778 switch (s390_safe_attr_type (insn))
3780 case TYPE_FSTORED:
3781 case TYPE_FSTORES:
3782 priority = priority << 3;
3783 break;
3784 case TYPE_STORE:
3785 priority = priority << 1;
3786 break;
3787 default:
3788 break;
3790 return priority;
3793 /* The number of instructions that can be issued per cycle. */
3795 static int
3796 s390_issue_rate (void)
3798 if (s390_tune == PROCESSOR_2084_Z990)
3799 return 3;
3800 return 1;
3803 /* If the following function returns TRUE, we will use the the DFA
3804 insn scheduler. */
3806 static int
3807 s390_use_dfa_pipeline_interface (void)
3809 if (s390_tune == PROCESSOR_2064_Z900
3810 || s390_tune == PROCESSOR_2084_Z990)
3811 return 1;
3813 return 0;
3816 static int
3817 s390_first_cycle_multipass_dfa_lookahead (void)
3819 return s390_use_dfa_pipeline_interface () ? 4 : 0;
3822 /* Called after issuing each insn.
3823 Triggers default sort algorithm to better slot instructions. */
3825 static int
3826 s390_sched_reorder2 (FILE *dump ATTRIBUTE_UNUSED,
3827 int sched_verbose ATTRIBUTE_UNUSED,
3828 rtx *ready ATTRIBUTE_UNUSED,
3829 int *pn_ready ATTRIBUTE_UNUSED,
3830 int clock_var ATTRIBUTE_UNUSED)
3832 return s390_issue_rate();
3836 /* Split all branches that exceed the maximum distance.
3837 Returns true if this created a new literal pool entry. */
3839 static int
3840 s390_split_branches (void)
3842 rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
3843 int new_literal = 0;
3844 rtx insn, pat, tmp, target;
3845 rtx *label;
3847 /* We need correct insn addresses. */
3849 shorten_branches (get_insns ());
3851 /* Find all branches that exceed 64KB, and split them. */
3853 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
3855 if (GET_CODE (insn) != JUMP_INSN)
3856 continue;
3858 pat = PATTERN (insn);
3859 if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
3860 pat = XVECEXP (pat, 0, 0);
3861 if (GET_CODE (pat) != SET || SET_DEST (pat) != pc_rtx)
3862 continue;
3864 if (GET_CODE (SET_SRC (pat)) == LABEL_REF)
3866 label = &SET_SRC (pat);
3868 else if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE)
3870 if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF)
3871 label = &XEXP (SET_SRC (pat), 1);
3872 else if (GET_CODE (XEXP (SET_SRC (pat), 2)) == LABEL_REF)
3873 label = &XEXP (SET_SRC (pat), 2);
3874 else
3875 continue;
3877 else
3878 continue;
3880 if (get_attr_length (insn) <= 4)
3881 continue;
3883 /* We are going to use the return register as scratch register,
3884 make sure it will be saved/restored by the prologue/epilogue. */
3885 cfun->machine->save_return_addr_p = 1;
3887 if (!flag_pic)
3889 new_literal = 1;
3890 tmp = force_const_mem (Pmode, *label);
3891 tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, tmp), insn);
3892 INSN_ADDRESSES_NEW (tmp, -1);
3894 target = temp_reg;
3896 else
3898 new_literal = 1;
3899 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, *label),
3900 UNSPEC_LTREL_OFFSET);
3901 target = gen_rtx_CONST (Pmode, target);
3902 target = force_const_mem (Pmode, target);
3903 tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, target), insn);
3904 INSN_ADDRESSES_NEW (tmp, -1);
3906 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (target, 0)),
3907 UNSPEC_LTREL_BASE);
3908 target = gen_rtx_PLUS (Pmode, temp_reg, target);
3911 if (!validate_change (insn, label, target, 0))
3912 abort ();
3915 return new_literal;
3919 /* Find a literal pool symbol referenced in RTX X, and store
3920 it at REF. Will abort if X contains references to more than
3921 one such pool symbol; multiple references to the same symbol
3922 are allowed, however.
3924 The rtx pointed to by REF must be initialized to NULL_RTX
3925 by the caller before calling this routine. */
3927 static void
3928 find_constant_pool_ref (rtx x, rtx *ref)
3930 int i, j;
3931 const char *fmt;
3933 /* Ignore LTREL_BASE references. */
3934 if (GET_CODE (x) == UNSPEC
3935 && XINT (x, 1) == UNSPEC_LTREL_BASE)
3936 return;
3937 /* Likewise POOL_ENTRY insns. */
3938 if (GET_CODE (x) == UNSPEC_VOLATILE
3939 && XINT (x, 1) == UNSPECV_POOL_ENTRY)
3940 return;
3942 if (GET_CODE (x) == SYMBOL_REF
3943 && CONSTANT_POOL_ADDRESS_P (x))
3945 if (*ref == NULL_RTX)
3946 *ref = x;
3947 else if (*ref != x)
3948 abort();
3951 fmt = GET_RTX_FORMAT (GET_CODE (x));
3952 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
3954 if (fmt[i] == 'e')
3956 find_constant_pool_ref (XEXP (x, i), ref);
3958 else if (fmt[i] == 'E')
3960 for (j = 0; j < XVECLEN (x, i); j++)
3961 find_constant_pool_ref (XVECEXP (x, i, j), ref);
3966 /* Replace every reference to the literal pool symbol REF
3967 in X by the address ADDR. Fix up MEMs as required. */
3969 static void
3970 replace_constant_pool_ref (rtx *x, rtx ref, rtx addr)
3972 int i, j;
3973 const char *fmt;
3975 if (*x == ref)
3976 abort ();
3978 /* Literal pool references can only occur inside a MEM ... */
3979 if (GET_CODE (*x) == MEM)
3981 rtx memref = XEXP (*x, 0);
3983 if (memref == ref)
3985 *x = replace_equiv_address (*x, addr);
3986 return;
3989 if (GET_CODE (memref) == CONST
3990 && GET_CODE (XEXP (memref, 0)) == PLUS
3991 && GET_CODE (XEXP (XEXP (memref, 0), 1)) == CONST_INT
3992 && XEXP (XEXP (memref, 0), 0) == ref)
3994 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (memref, 0), 1));
3995 *x = replace_equiv_address (*x, plus_constant (addr, off));
3996 return;
4000 /* ... or a load-address type pattern. */
4001 if (GET_CODE (*x) == SET)
4003 rtx addrref = SET_SRC (*x);
4005 if (addrref == ref)
4007 SET_SRC (*x) = addr;
4008 return;
4011 if (GET_CODE (addrref) == CONST
4012 && GET_CODE (XEXP (addrref, 0)) == PLUS
4013 && GET_CODE (XEXP (XEXP (addrref, 0), 1)) == CONST_INT
4014 && XEXP (XEXP (addrref, 0), 0) == ref)
4016 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (addrref, 0), 1));
4017 SET_SRC (*x) = plus_constant (addr, off);
4018 return;
4022 fmt = GET_RTX_FORMAT (GET_CODE (*x));
4023 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
4025 if (fmt[i] == 'e')
4027 replace_constant_pool_ref (&XEXP (*x, i), ref, addr);
4029 else if (fmt[i] == 'E')
4031 for (j = 0; j < XVECLEN (*x, i); j++)
4032 replace_constant_pool_ref (&XVECEXP (*x, i, j), ref, addr);
4037 /* Check whether X contains an UNSPEC_LTREL_BASE.
4038 Return its constant pool symbol if found, NULL_RTX otherwise. */
4040 static rtx
4041 find_ltrel_base (rtx x)
4043 int i, j;
4044 const char *fmt;
4046 if (GET_CODE (x) == UNSPEC
4047 && XINT (x, 1) == UNSPEC_LTREL_BASE)
4048 return XVECEXP (x, 0, 0);
4050 fmt = GET_RTX_FORMAT (GET_CODE (x));
4051 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4053 if (fmt[i] == 'e')
4055 rtx fnd = find_ltrel_base (XEXP (x, i));
4056 if (fnd)
4057 return fnd;
4059 else if (fmt[i] == 'E')
4061 for (j = 0; j < XVECLEN (x, i); j++)
4063 rtx fnd = find_ltrel_base (XVECEXP (x, i, j));
4064 if (fnd)
4065 return fnd;
4070 return NULL_RTX;
4073 /* Replace any occurrence of UNSPEC_LTREL_BASE in X with BASE. */
4075 static void
4076 replace_ltrel_base (rtx *x, rtx base)
4078 int i, j;
4079 const char *fmt;
4081 if (GET_CODE (*x) == UNSPEC
4082 && XINT (*x, 1) == UNSPEC_LTREL_BASE)
4084 *x = base;
4085 return;
4088 fmt = GET_RTX_FORMAT (GET_CODE (*x));
4089 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
4091 if (fmt[i] == 'e')
4093 replace_ltrel_base (&XEXP (*x, i), base);
4095 else if (fmt[i] == 'E')
4097 for (j = 0; j < XVECLEN (*x, i); j++)
4098 replace_ltrel_base (&XVECEXP (*x, i, j), base);
4104 /* We keep a list of constants which we have to add to internal
4105 constant tables in the middle of large functions. */
4107 #define NR_C_MODES 7
4108 enum machine_mode constant_modes[NR_C_MODES] =
4110 TImode,
4111 DFmode, DImode,
4112 SFmode, SImode,
4113 HImode,
4114 QImode
4117 struct constant
4119 struct constant *next;
4120 rtx value;
4121 rtx label;
4124 struct constant_pool
4126 struct constant_pool *next;
4127 rtx first_insn;
4128 rtx pool_insn;
4129 bitmap insns;
4131 struct constant *constants[NR_C_MODES];
4132 rtx label;
4133 int size;
4136 static struct constant_pool * s390_mainpool_start (void);
4137 static void s390_mainpool_finish (struct constant_pool *, rtx base_reg);
4138 static void s390_mainpool_cancel (struct constant_pool *);
4140 static struct constant_pool * s390_chunkify_start (rtx base_reg);
4141 static void s390_chunkify_finish (struct constant_pool *, rtx base_reg);
4142 static void s390_chunkify_cancel (struct constant_pool *);
4144 static struct constant_pool *s390_start_pool (struct constant_pool **, rtx);
4145 static void s390_end_pool (struct constant_pool *, rtx);
4146 static void s390_add_pool_insn (struct constant_pool *, rtx);
4147 static struct constant_pool *s390_find_pool (struct constant_pool *, rtx);
4148 static void s390_add_constant (struct constant_pool *, rtx, enum machine_mode);
4149 static rtx s390_find_constant (struct constant_pool *, rtx, enum machine_mode);
4150 static rtx s390_dump_pool (struct constant_pool *, bool);
4151 static struct constant_pool *s390_alloc_pool (void);
4152 static void s390_free_pool (struct constant_pool *);
4154 /* Create new constant pool covering instructions starting at INSN
4155 and chain it to the end of POOL_LIST. */
4157 static struct constant_pool *
4158 s390_start_pool (struct constant_pool **pool_list, rtx insn)
4160 struct constant_pool *pool, **prev;
4162 pool = s390_alloc_pool ();
4163 pool->first_insn = insn;
4165 for (prev = pool_list; *prev; prev = &(*prev)->next)
4167 *prev = pool;
4169 return pool;
4172 /* End range of instructions covered by POOL at INSN and emit
4173 placeholder insn representing the pool. */
4175 static void
4176 s390_end_pool (struct constant_pool *pool, rtx insn)
4178 rtx pool_size = GEN_INT (pool->size + 8 /* alignment slop */);
4180 if (!insn)
4181 insn = get_last_insn ();
4183 pool->pool_insn = emit_insn_after (gen_pool (pool_size), insn);
4184 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
4187 /* Add INSN to the list of insns covered by POOL. */
4189 static void
4190 s390_add_pool_insn (struct constant_pool *pool, rtx insn)
4192 bitmap_set_bit (pool->insns, INSN_UID (insn));
4195 /* Return pool out of POOL_LIST that covers INSN. */
4197 static struct constant_pool *
4198 s390_find_pool (struct constant_pool *pool_list, rtx insn)
4200 struct constant_pool *pool;
4202 for (pool = pool_list; pool; pool = pool->next)
4203 if (bitmap_bit_p (pool->insns, INSN_UID (insn)))
4204 break;
4206 return pool;
4209 /* Add constant VAL of mode MODE to the constant pool POOL. */
4211 static void
4212 s390_add_constant (struct constant_pool *pool, rtx val, enum machine_mode mode)
4214 struct constant *c;
4215 int i;
4217 for (i = 0; i < NR_C_MODES; i++)
4218 if (constant_modes[i] == mode)
4219 break;
4220 if (i == NR_C_MODES)
4221 abort ();
4223 for (c = pool->constants[i]; c != NULL; c = c->next)
4224 if (rtx_equal_p (val, c->value))
4225 break;
4227 if (c == NULL)
4229 c = (struct constant *) xmalloc (sizeof *c);
4230 c->value = val;
4231 c->label = gen_label_rtx ();
4232 c->next = pool->constants[i];
4233 pool->constants[i] = c;
4234 pool->size += GET_MODE_SIZE (mode);
4238 /* Find constant VAL of mode MODE in the constant pool POOL.
4239 Return an RTX describing the distance from the start of
4240 the pool to the location of the new constant. */
4242 static rtx
4243 s390_find_constant (struct constant_pool *pool, rtx val,
4244 enum machine_mode mode)
4246 struct constant *c;
4247 rtx offset;
4248 int i;
4250 for (i = 0; i < NR_C_MODES; i++)
4251 if (constant_modes[i] == mode)
4252 break;
4253 if (i == NR_C_MODES)
4254 abort ();
4256 for (c = pool->constants[i]; c != NULL; c = c->next)
4257 if (rtx_equal_p (val, c->value))
4258 break;
4260 if (c == NULL)
4261 abort ();
4263 offset = gen_rtx_MINUS (Pmode, gen_rtx_LABEL_REF (Pmode, c->label),
4264 gen_rtx_LABEL_REF (Pmode, pool->label));
4265 offset = gen_rtx_CONST (Pmode, offset);
4266 return offset;
4269 /* Dump out the constants in POOL. If REMOTE_LABEL is true,
4270 do not emit the pool base label. */
4272 static rtx
4273 s390_dump_pool (struct constant_pool *pool, bool remote_label)
4275 struct constant *c;
4276 rtx insn;
4277 int i;
4279 /* Pool start insn switches to proper section
4280 and guarantees necessary alignment. */
4281 if (TARGET_CPU_ZARCH)
4282 insn = emit_insn_after (gen_pool_start_64 (), pool->pool_insn);
4283 else
4284 insn = emit_insn_after (gen_pool_start_31 (), pool->pool_insn);
4285 INSN_ADDRESSES_NEW (insn, -1);
4287 if (!remote_label)
4289 insn = emit_label_after (pool->label, insn);
4290 INSN_ADDRESSES_NEW (insn, -1);
4293 /* Dump constants in descending alignment requirement order,
4294 ensuring proper alignment for every constant. */
4295 for (i = 0; i < NR_C_MODES; i++)
4296 for (c = pool->constants[i]; c; c = c->next)
4298 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
4299 rtx value = c->value;
4300 if (GET_CODE (value) == CONST
4301 && GET_CODE (XEXP (value, 0)) == UNSPEC
4302 && XINT (XEXP (value, 0), 1) == UNSPEC_LTREL_OFFSET
4303 && XVECLEN (XEXP (value, 0), 0) == 1)
4305 value = gen_rtx_MINUS (Pmode, XVECEXP (XEXP (value, 0), 0, 0),
4306 gen_rtx_LABEL_REF (VOIDmode, pool->label));
4307 value = gen_rtx_CONST (VOIDmode, value);
4310 insn = emit_label_after (c->label, insn);
4311 INSN_ADDRESSES_NEW (insn, -1);
4313 value = gen_rtx_UNSPEC_VOLATILE (constant_modes[i],
4314 gen_rtvec (1, value),
4315 UNSPECV_POOL_ENTRY);
4316 insn = emit_insn_after (value, insn);
4317 INSN_ADDRESSES_NEW (insn, -1);
4320 /* Pool end insn switches back to previous section
4321 and guarantees necessary alignment. */
4322 if (TARGET_CPU_ZARCH)
4323 insn = emit_insn_after (gen_pool_end_64 (), insn);
4324 else
4325 insn = emit_insn_after (gen_pool_end_31 (), insn);
4326 INSN_ADDRESSES_NEW (insn, -1);
4328 insn = emit_barrier_after (insn);
4329 INSN_ADDRESSES_NEW (insn, -1);
4331 /* Remove placeholder insn. */
4332 remove_insn (pool->pool_insn);
4334 return insn;
4337 /* Allocate new constant_pool structure. */
4339 static struct constant_pool *
4340 s390_alloc_pool (void)
4342 struct constant_pool *pool;
4343 int i;
4345 pool = (struct constant_pool *) xmalloc (sizeof *pool);
4346 pool->next = NULL;
4347 for (i = 0; i < NR_C_MODES; i++)
4348 pool->constants[i] = NULL;
4350 pool->label = gen_label_rtx ();
4351 pool->first_insn = NULL_RTX;
4352 pool->pool_insn = NULL_RTX;
4353 pool->insns = BITMAP_XMALLOC ();
4354 pool->size = 0;
4356 return pool;
4359 /* Free all memory used by POOL. */
4361 static void
4362 s390_free_pool (struct constant_pool *pool)
4364 int i;
4366 for (i = 0; i < NR_C_MODES; i++)
4368 struct constant *c = pool->constants[i];
4369 while (c != NULL)
4371 struct constant *next = c->next;
4372 free (c);
4373 c = next;
4377 BITMAP_XFREE (pool->insns);
4378 free (pool);
4382 /* Collect main literal pool. Return NULL on overflow. */
4384 static struct constant_pool *
4385 s390_mainpool_start (void)
4387 struct constant_pool *pool;
4388 rtx insn;
4390 pool = s390_alloc_pool ();
4392 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4394 if (GET_CODE (insn) == INSN
4395 && GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
4396 && XINT (PATTERN (insn), 1) == UNSPECV_MAIN_POOL)
4398 if (pool->pool_insn)
4399 abort ();
4400 pool->pool_insn = insn;
4403 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
4405 rtx pool_ref = NULL_RTX;
4406 find_constant_pool_ref (PATTERN (insn), &pool_ref);
4407 if (pool_ref)
4409 rtx constant = get_pool_constant (pool_ref);
4410 enum machine_mode mode = get_pool_mode (pool_ref);
4411 s390_add_constant (pool, constant, mode);
4416 if (!pool->pool_insn)
4417 abort ();
4419 if (pool->size >= 4096)
4421 /* We're going to chunkify the pool, so remove the main
4422 pool placeholder insn. */
4423 remove_insn (pool->pool_insn);
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 /* Without backchain, we fail for all but the current frame. */
5264 if (!TARGET_BACKCHAIN && count > 0)
5265 return NULL_RTX;
5267 /* For the current frame, we need to make sure the initial
5268 value of RETURN_REGNUM is actually saved. */
5270 if (count == 0)
5271 cfun->machine->save_return_addr_p = true;
5273 /* To retrieve the return address we read the stack slot where the
5274 corresponding RETURN_REGNUM value was saved. */
5276 addr = plus_constant (frame, RETURN_REGNUM * UNITS_PER_WORD);
5277 addr = memory_address (Pmode, addr);
5278 return gen_rtx_MEM (Pmode, addr);
5281 /* Find first call clobbered register unsused in a function.
5282 This could be used as base register in a leaf function
5283 or for holding the return address before epilogue. */
5285 static int
5286 find_unused_clobbered_reg (void)
5288 int i;
5289 for (i = 0; i < 6; i++)
5290 if (!regs_ever_live[i])
5291 return i;
5292 return 0;
5295 /* Fill FRAME with info about frame of current function. */
5297 static void
5298 s390_frame_info (void)
5300 int i, j;
5301 HOST_WIDE_INT fsize = get_frame_size ();
5303 if (!TARGET_64BIT && fsize > 0x7fff0000)
5304 fatal_error ("Total size of local variables exceeds architecture limit.");
5306 /* fprs 8 - 15 are caller saved for 64 Bit ABI. */
5307 cfun->machine->save_fprs_p = 0;
5308 if (TARGET_64BIT)
5309 for (i = 24; i < 32; i++)
5310 if (regs_ever_live[i] && !global_regs[i])
5312 cfun->machine->save_fprs_p = 1;
5313 break;
5316 cfun->machine->frame_size = fsize + cfun->machine->save_fprs_p * 64;
5318 /* Does function need to setup frame and save area. */
5320 if (! current_function_is_leaf
5321 || cfun->machine->frame_size > 0
5322 || current_function_calls_alloca
5323 || current_function_stdarg)
5324 cfun->machine->frame_size += STARTING_FRAME_OFFSET;
5326 /* If we use the return register, we'll need to make sure
5327 it is going to be saved/restored. */
5329 if (!current_function_is_leaf
5330 || regs_ever_live[RETURN_REGNUM])
5331 cfun->machine->save_return_addr_p = 1;
5333 /* Find first and last gpr to be saved. Note that at this point,
5334 we assume the base register and -on S/390- the return register
5335 always need to be saved. This is done because the usage of these
5336 register might change even after the prolog was emitted.
5337 If it turns out later that we really don't need them, the
5338 prolog/epilog code is modified again. */
5340 regs_ever_live[BASE_REGISTER] = 1;
5341 if (!TARGET_CPU_ZARCH || cfun->machine->save_return_addr_p)
5342 regs_ever_live[RETURN_REGNUM] = 1;
5343 regs_ever_live[STACK_POINTER_REGNUM] = cfun->machine->frame_size > 0;
5345 for (i = 6; i < 16; i++)
5346 if (regs_ever_live[i])
5347 if (!global_regs[i]
5348 || i == STACK_POINTER_REGNUM
5349 || i == RETURN_REGNUM
5350 || i == BASE_REGISTER
5351 || (flag_pic && i == (int)PIC_OFFSET_TABLE_REGNUM))
5352 break;
5354 for (j = 15; j > i; j--)
5355 if (regs_ever_live[j])
5356 if (!global_regs[j]
5357 || j == STACK_POINTER_REGNUM
5358 || j == RETURN_REGNUM
5359 || j == BASE_REGISTER
5360 || (flag_pic && j == (int)PIC_OFFSET_TABLE_REGNUM))
5361 break;
5363 /* Save / Restore from gpr i to j. */
5364 cfun->machine->first_save_gpr = i;
5365 cfun->machine->first_restore_gpr = i;
5366 cfun->machine->last_save_gpr = j;
5368 /* Varargs functions need to save gprs 2 to 6. */
5369 if (current_function_stdarg)
5370 cfun->machine->first_save_gpr = 2;
5373 /* Return offset between argument pointer and frame pointer
5374 initially after prologue. */
5376 HOST_WIDE_INT
5377 s390_arg_frame_offset (void)
5379 HOST_WIDE_INT fsize = get_frame_size ();
5380 int save_fprs_p, i;
5382 /* fprs 8 - 15 are caller saved for 64 Bit ABI. */
5383 save_fprs_p = 0;
5384 if (TARGET_64BIT)
5385 for (i = 24; i < 32; i++)
5386 if (regs_ever_live[i] && !global_regs[i])
5388 save_fprs_p = 1;
5389 break;
5392 fsize = fsize + save_fprs_p * 64;
5394 /* Does function need to setup frame and save area. */
5396 if (! current_function_is_leaf
5397 || fsize > 0
5398 || current_function_calls_alloca
5399 || current_function_stdarg)
5400 fsize += STARTING_FRAME_OFFSET;
5401 return fsize + STACK_POINTER_OFFSET;
5404 /* Emit insn to save fpr REGNUM at offset OFFSET relative
5405 to register BASE. Return generated insn. */
5407 static rtx
5408 save_fpr (rtx base, int offset, int regnum)
5410 rtx addr;
5411 addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
5412 set_mem_alias_set (addr, s390_sr_alias_set);
5414 return emit_move_insn (addr, gen_rtx_REG (DFmode, regnum));
5417 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
5418 to register BASE. Return generated insn. */
5420 static rtx
5421 restore_fpr (rtx base, int offset, int regnum)
5423 rtx addr;
5424 addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
5425 set_mem_alias_set (addr, s390_sr_alias_set);
5427 return emit_move_insn (gen_rtx_REG (DFmode, regnum), addr);
5430 /* Generate insn to save registers FIRST to LAST into
5431 the register save area located at offset OFFSET
5432 relative to register BASE. */
5434 static rtx
5435 save_gprs (rtx base, int offset, int first, int last)
5437 rtx addr, insn, note;
5438 int i;
5440 addr = plus_constant (base, offset + first * UNITS_PER_WORD);
5441 addr = gen_rtx_MEM (Pmode, addr);
5442 set_mem_alias_set (addr, s390_sr_alias_set);
5444 /* Special-case single register. */
5445 if (first == last)
5447 if (TARGET_64BIT)
5448 insn = gen_movdi (addr, gen_rtx_REG (Pmode, first));
5449 else
5450 insn = gen_movsi (addr, gen_rtx_REG (Pmode, first));
5452 RTX_FRAME_RELATED_P (insn) = 1;
5453 return insn;
5457 insn = gen_store_multiple (addr,
5458 gen_rtx_REG (Pmode, first),
5459 GEN_INT (last - first + 1));
5462 /* We need to set the FRAME_RELATED flag on all SETs
5463 inside the store-multiple pattern.
5465 However, we must not emit DWARF records for registers 2..5
5466 if they are stored for use by variable arguments ...
5468 ??? Unfortunately, it is not enough to simply not the the
5469 FRAME_RELATED flags for those SETs, because the first SET
5470 of the PARALLEL is always treated as if it had the flag
5471 set, even if it does not. Therefore we emit a new pattern
5472 without those registers as REG_FRAME_RELATED_EXPR note. */
5474 if (first >= 6)
5476 rtx pat = PATTERN (insn);
5478 for (i = 0; i < XVECLEN (pat, 0); i++)
5479 if (GET_CODE (XVECEXP (pat, 0, i)) == SET)
5480 RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1;
5482 RTX_FRAME_RELATED_P (insn) = 1;
5484 else if (last >= 6)
5486 addr = plus_constant (base, offset + 6 * UNITS_PER_WORD);
5487 note = gen_store_multiple (gen_rtx_MEM (Pmode, addr),
5488 gen_rtx_REG (Pmode, 6),
5489 GEN_INT (last - 6 + 1));
5490 note = PATTERN (note);
5492 REG_NOTES (insn) =
5493 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
5494 note, REG_NOTES (insn));
5496 for (i = 0; i < XVECLEN (note, 0); i++)
5497 if (GET_CODE (XVECEXP (note, 0, i)) == SET)
5498 RTX_FRAME_RELATED_P (XVECEXP (note, 0, i)) = 1;
5500 RTX_FRAME_RELATED_P (insn) = 1;
5503 return insn;
5506 /* Generate insn to restore registers FIRST to LAST from
5507 the register save area located at offset OFFSET
5508 relative to register BASE. */
5510 static rtx
5511 restore_gprs (rtx base, int offset, int first, int last)
5513 rtx addr, insn;
5515 addr = plus_constant (base, offset + first * UNITS_PER_WORD);
5516 addr = gen_rtx_MEM (Pmode, addr);
5517 set_mem_alias_set (addr, s390_sr_alias_set);
5519 /* Special-case single register. */
5520 if (first == last)
5522 if (TARGET_64BIT)
5523 insn = gen_movdi (gen_rtx_REG (Pmode, first), addr);
5524 else
5525 insn = gen_movsi (gen_rtx_REG (Pmode, first), addr);
5527 return insn;
5530 insn = gen_load_multiple (gen_rtx_REG (Pmode, first),
5531 addr,
5532 GEN_INT (last - first + 1));
5533 return insn;
5536 /* Emit code to load the GOT register. If MAYBE_DEAD is true,
5537 annotate generated insns with REG_MAYBE_DEAD notes. */
5539 static GTY(()) rtx got_symbol;
5540 void
5541 s390_load_got (int maybe_dead)
5543 if (!got_symbol)
5545 got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5546 SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
5549 if (TARGET_CPU_ZARCH)
5551 rtx insn = emit_move_insn (pic_offset_table_rtx, got_symbol);
5552 if (maybe_dead)
5553 REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
5554 REG_NOTES (insn));
5556 else
5558 rtx offset, insn;
5560 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got_symbol),
5561 UNSPEC_LTREL_OFFSET);
5562 offset = gen_rtx_CONST (Pmode, offset);
5563 offset = force_const_mem (Pmode, offset);
5565 insn = emit_move_insn (pic_offset_table_rtx, offset);
5566 if (maybe_dead)
5567 REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
5568 REG_NOTES (insn));
5570 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (offset, 0)),
5571 UNSPEC_LTREL_BASE);
5572 offset = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, offset);
5574 insn = emit_move_insn (pic_offset_table_rtx, offset);
5575 if (maybe_dead)
5576 REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
5577 REG_NOTES (insn));
5581 /* Expand the prologue into a bunch of separate insns. */
5583 void
5584 s390_emit_prologue (void)
5586 rtx insn, addr;
5587 rtx temp_reg;
5588 int i;
5590 /* Compute frame_info. */
5592 s390_frame_info ();
5594 /* Choose best register to use for temp use within prologue.
5595 See below for why TPF must use the register 1. */
5597 if (!current_function_is_leaf
5598 && !TARGET_TPF)
5599 temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
5600 else
5601 temp_reg = gen_rtx_REG (Pmode, 1);
5603 /* Save call saved gprs. */
5605 insn = save_gprs (stack_pointer_rtx, 0,
5606 cfun->machine->first_save_gpr, cfun->machine->last_save_gpr);
5607 emit_insn (insn);
5609 /* Dummy insn to mark literal pool slot. */
5611 emit_insn (gen_main_pool ());
5613 /* Save fprs for variable args. */
5615 if (current_function_stdarg)
5616 for (i = 16; i < (TARGET_64BIT ? 20 : 18); i++)
5617 save_fpr (stack_pointer_rtx, 16*UNITS_PER_WORD + 8*(i-16), i);
5619 /* Save fprs 4 and 6 if used (31 bit ABI). */
5621 if (!TARGET_64BIT)
5622 for (i = 18; i < 20; i++)
5623 if (regs_ever_live[i] && !global_regs[i])
5625 insn = save_fpr (stack_pointer_rtx, 16*UNITS_PER_WORD + 8*(i-16), i);
5626 RTX_FRAME_RELATED_P (insn) = 1;
5629 /* Decrement stack pointer. */
5631 if (cfun->machine->frame_size > 0)
5633 rtx frame_off = GEN_INT (-cfun->machine->frame_size);
5635 /* Save incoming stack pointer into temp reg. */
5637 if (TARGET_BACKCHAIN || cfun->machine->save_fprs_p)
5639 insn = emit_insn (gen_move_insn (temp_reg, stack_pointer_rtx));
5642 /* Subtract frame size from stack pointer. */
5644 if (DISP_IN_RANGE (INTVAL (frame_off)))
5646 insn = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
5647 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
5648 frame_off));
5649 insn = emit_insn (insn);
5651 else
5653 if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off), 'K', "K"))
5654 frame_off = force_const_mem (Pmode, frame_off);
5656 insn = emit_insn (gen_add2_insn (stack_pointer_rtx, frame_off));
5659 RTX_FRAME_RELATED_P (insn) = 1;
5660 REG_NOTES (insn) =
5661 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
5662 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
5663 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
5664 GEN_INT (-cfun->machine->frame_size))),
5665 REG_NOTES (insn));
5667 /* Set backchain. */
5669 if (TARGET_BACKCHAIN)
5671 addr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
5672 set_mem_alias_set (addr, s390_sr_alias_set);
5673 insn = emit_insn (gen_move_insn (addr, temp_reg));
5676 /* If we support asynchronous exceptions (e.g. for Java),
5677 we need to make sure the backchain pointer is set up
5678 before any possibly trapping memory access. */
5680 if (TARGET_BACKCHAIN && flag_non_call_exceptions)
5682 addr = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
5683 emit_insn (gen_rtx_CLOBBER (VOIDmode, addr));
5687 /* Save fprs 8 - 15 (64 bit ABI). */
5689 if (cfun->machine->save_fprs_p)
5691 insn = emit_insn (gen_add2_insn (temp_reg, GEN_INT(-64)));
5693 for (i = 24; i < 32; i++)
5694 if (regs_ever_live[i] && !global_regs[i])
5696 rtx addr = plus_constant (stack_pointer_rtx,
5697 cfun->machine->frame_size - 64 + (i-24)*8);
5699 insn = save_fpr (temp_reg, (i-24)*8, i);
5700 RTX_FRAME_RELATED_P (insn) = 1;
5701 REG_NOTES (insn) =
5702 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
5703 gen_rtx_SET (VOIDmode,
5704 gen_rtx_MEM (DFmode, addr),
5705 gen_rtx_REG (DFmode, i)),
5706 REG_NOTES (insn));
5710 /* Set frame pointer, if needed. */
5712 if (frame_pointer_needed)
5714 insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
5715 RTX_FRAME_RELATED_P (insn) = 1;
5718 /* Set up got pointer, if needed. */
5720 if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
5721 s390_load_got(true);
5723 if (TARGET_TPF)
5725 /* Generate a BAS instruction to serve as a function
5726 entry intercept to facilitate the use of tracing
5727 algorithms located at the branch target.
5729 This must use register 1. */
5730 rtx addr;
5731 rtx unkn;
5732 rtx link;
5734 addr = GEN_INT (0xfe0);
5735 unkn = CONST0_RTX (SImode);
5736 link = gen_rtx_REG (Pmode, 1);
5738 emit_call_insn (gen_call_exp (gen_rtx_MEM (QImode, addr), unkn, link));
5740 /* Emit a blockage here so that all code
5741 lies between the profiling mechanisms. */
5742 emit_insn (gen_blockage ());
5746 /* Expand the epilogue into a bunch of separate insns. */
5748 void
5749 s390_emit_epilogue (void)
5751 rtx frame_pointer, return_reg;
5752 int area_bottom, area_top, offset = 0;
5753 rtvec p;
5754 int i;
5756 if (TARGET_TPF)
5759 /* Generate a BAS instruction to serve as a function
5760 entry intercept to facilitate the use of tracing
5761 algorithms located at the branch target.
5763 This must use register 1. */
5765 rtx addr;
5766 rtx unkn;
5767 rtx link;
5769 addr = GEN_INT (0xfe6);
5770 unkn = CONST0_RTX (SImode);
5771 link = gen_rtx_REG (Pmode, 1);
5773 /* Emit a blockage here so that all code
5774 lies between the profiling mechanisms. */
5775 emit_insn (gen_blockage ());
5777 emit_call_insn (gen_call_exp (gen_rtx_MEM (QImode, addr), unkn, link));
5780 /* Check whether to use frame or stack pointer for restore. */
5782 frame_pointer = frame_pointer_needed ?
5783 hard_frame_pointer_rtx : stack_pointer_rtx;
5785 /* Compute which parts of the save area we need to access. */
5787 if (cfun->machine->first_restore_gpr != -1)
5789 area_bottom = cfun->machine->first_restore_gpr * UNITS_PER_WORD;
5790 area_top = (cfun->machine->last_save_gpr + 1) * UNITS_PER_WORD;
5792 else
5794 area_bottom = INT_MAX;
5795 area_top = INT_MIN;
5798 if (TARGET_64BIT)
5800 if (cfun->machine->save_fprs_p)
5802 if (area_bottom > -64)
5803 area_bottom = -64;
5804 if (area_top < 0)
5805 area_top = 0;
5808 else
5810 for (i = 18; i < 20; i++)
5811 if (regs_ever_live[i] && !global_regs[i])
5813 if (area_bottom > 16*UNITS_PER_WORD + 8*(i-16))
5814 area_bottom = 16*UNITS_PER_WORD + 8*(i-16);
5815 if (area_top < 16*UNITS_PER_WORD + 8*(i-16) + 8)
5816 area_top = 16*UNITS_PER_WORD + 8*(i-16) + 8;
5820 /* Check whether we can access the register save area.
5821 If not, increment the frame pointer as required. */
5823 if (area_top <= area_bottom)
5825 /* Nothing to restore. */
5827 else if (DISP_IN_RANGE (cfun->machine->frame_size + area_bottom)
5828 && DISP_IN_RANGE (cfun->machine->frame_size + area_top-1))
5830 /* Area is in range. */
5831 offset = cfun->machine->frame_size;
5833 else
5835 rtx insn, frame_off;
5837 offset = area_bottom < 0 ? -area_bottom : 0;
5838 frame_off = GEN_INT (cfun->machine->frame_size - offset);
5840 if (DISP_IN_RANGE (INTVAL (frame_off)))
5842 insn = gen_rtx_SET (VOIDmode, frame_pointer,
5843 gen_rtx_PLUS (Pmode, frame_pointer, frame_off));
5844 insn = emit_insn (insn);
5846 else
5848 if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off), 'K', "K"))
5849 frame_off = force_const_mem (Pmode, frame_off);
5851 insn = emit_insn (gen_add2_insn (frame_pointer, frame_off));
5855 /* Restore call saved fprs. */
5857 if (TARGET_64BIT)
5859 if (cfun->machine->save_fprs_p)
5860 for (i = 24; i < 32; i++)
5861 if (regs_ever_live[i] && !global_regs[i])
5862 restore_fpr (frame_pointer,
5863 offset - 64 + (i-24) * 8, i);
5865 else
5867 for (i = 18; i < 20; i++)
5868 if (regs_ever_live[i] && !global_regs[i])
5869 restore_fpr (frame_pointer,
5870 offset + 16*UNITS_PER_WORD + 8*(i-16), i);
5873 /* Return register. */
5875 return_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
5877 /* Restore call saved gprs. */
5879 if (cfun->machine->first_restore_gpr != -1)
5881 rtx insn, addr;
5882 int i;
5884 /* Check for global register and save them
5885 to stack location from where they get restored. */
5887 for (i = cfun->machine->first_restore_gpr;
5888 i <= cfun->machine->last_save_gpr;
5889 i++)
5891 /* These registers are special and need to be
5892 restored in any case. */
5893 if (i == STACK_POINTER_REGNUM
5894 || i == RETURN_REGNUM
5895 || i == BASE_REGISTER
5896 || (flag_pic && i == (int)PIC_OFFSET_TABLE_REGNUM))
5897 continue;
5899 if (global_regs[i])
5901 addr = plus_constant (frame_pointer,
5902 offset + i * UNITS_PER_WORD);
5903 addr = gen_rtx_MEM (Pmode, addr);
5904 set_mem_alias_set (addr, s390_sr_alias_set);
5905 emit_move_insn (addr, gen_rtx_REG (Pmode, i));
5909 /* Fetch return address from stack before load multiple,
5910 this will do good for scheduling. */
5912 if (cfun->machine->save_return_addr_p
5913 || (cfun->machine->first_restore_gpr < BASE_REGISTER
5914 && cfun->machine->last_save_gpr > RETURN_REGNUM))
5916 int return_regnum = find_unused_clobbered_reg();
5917 if (!return_regnum)
5918 return_regnum = 4;
5919 return_reg = gen_rtx_REG (Pmode, return_regnum);
5921 addr = plus_constant (frame_pointer,
5922 offset + RETURN_REGNUM * UNITS_PER_WORD);
5923 addr = gen_rtx_MEM (Pmode, addr);
5924 set_mem_alias_set (addr, s390_sr_alias_set);
5925 emit_move_insn (return_reg, addr);
5928 /* ??? As references to the base register are not made
5929 explicit in insn RTX code, we have to add a barrier here
5930 to prevent incorrect scheduling. */
5932 emit_insn (gen_blockage());
5934 insn = restore_gprs (frame_pointer, offset,
5935 cfun->machine->first_restore_gpr,
5936 cfun->machine->last_save_gpr);
5937 emit_insn (insn);
5940 /* Return to caller. */
5942 p = rtvec_alloc (2);
5944 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
5945 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, return_reg);
5946 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
5950 /* Return the size in bytes of a function argument of
5951 type TYPE and/or mode MODE. At least one of TYPE or
5952 MODE must be specified. */
5954 static int
5955 s390_function_arg_size (enum machine_mode mode, tree type)
5957 if (type)
5958 return int_size_in_bytes (type);
5960 /* No type info available for some library calls ... */
5961 if (mode != BLKmode)
5962 return GET_MODE_SIZE (mode);
5964 /* If we have neither type nor mode, abort */
5965 abort ();
5968 /* Return true if a function argument of type TYPE and mode MODE
5969 is to be passed in a floating-point register, if available. */
5971 static bool
5972 s390_function_arg_float (enum machine_mode mode, tree type)
5974 int size = s390_function_arg_size (mode, type);
5975 if (size > 8)
5976 return false;
5978 /* Soft-float changes the ABI: no floating-point registers are used. */
5979 if (TARGET_SOFT_FLOAT)
5980 return false;
5982 /* No type info available for some library calls ... */
5983 if (!type)
5984 return mode == SFmode || mode == DFmode;
5986 /* The ABI says that record types with a single member are treated
5987 just like that member would be. */
5988 while (TREE_CODE (type) == RECORD_TYPE)
5990 tree field, single = NULL_TREE;
5992 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
5994 if (TREE_CODE (field) != FIELD_DECL)
5995 continue;
5997 if (single == NULL_TREE)
5998 single = TREE_TYPE (field);
5999 else
6000 return false;
6003 if (single == NULL_TREE)
6004 return false;
6005 else
6006 type = single;
6009 return TREE_CODE (type) == REAL_TYPE;
6012 /* Return true if a function argument of type TYPE and mode MODE
6013 is to be passed in an integer register, or a pair of integer
6014 registers, if available. */
6016 static bool
6017 s390_function_arg_integer (enum machine_mode mode, tree type)
6019 int size = s390_function_arg_size (mode, type);
6020 if (size > 8)
6021 return false;
6023 /* No type info available for some library calls ... */
6024 if (!type)
6025 return GET_MODE_CLASS (mode) == MODE_INT
6026 || (TARGET_SOFT_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT);
6028 /* We accept small integral (and similar) types. */
6029 if (INTEGRAL_TYPE_P (type)
6030 || POINTER_TYPE_P (type)
6031 || TREE_CODE (type) == OFFSET_TYPE
6032 || (TARGET_SOFT_FLOAT && TREE_CODE (type) == REAL_TYPE))
6033 return true;
6035 /* We also accept structs of size 1, 2, 4, 8 that are not
6036 passed in floating-point registers. */
6037 if (AGGREGATE_TYPE_P (type)
6038 && exact_log2 (size) >= 0
6039 && !s390_function_arg_float (mode, type))
6040 return true;
6042 return false;
6045 /* Return 1 if a function argument of type TYPE and mode MODE
6046 is to be passed by reference. The ABI specifies that only
6047 structures of size 1, 2, 4, or 8 bytes are passed by value,
6048 all other structures (and complex numbers) are passed by
6049 reference. */
6052 s390_function_arg_pass_by_reference (enum machine_mode mode, tree type)
6054 int size = s390_function_arg_size (mode, type);
6055 if (size > 8)
6056 return true;
6058 if (type)
6060 if (AGGREGATE_TYPE_P (type) && exact_log2 (size) < 0)
6061 return 1;
6063 if (TREE_CODE (type) == COMPLEX_TYPE
6064 || TREE_CODE (type) == VECTOR_TYPE)
6065 return 1;
6068 return 0;
6071 /* Update the data in CUM to advance over an argument of mode MODE and
6072 data type TYPE. (TYPE is null for libcalls where that information
6073 may not be available.). The boolean NAMED specifies whether the
6074 argument is a named argument (as opposed to an unnamed argument
6075 matching an ellipsis). */
6077 void
6078 s390_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
6079 tree type, int named ATTRIBUTE_UNUSED)
6081 if (s390_function_arg_pass_by_reference (mode, type))
6083 cum->gprs += 1;
6085 else if (s390_function_arg_float (mode, type))
6087 cum->fprs += 1;
6089 else if (s390_function_arg_integer (mode, type))
6091 int size = s390_function_arg_size (mode, type);
6092 cum->gprs += ((size + UNITS_PER_WORD-1) / UNITS_PER_WORD);
6094 else
6095 abort ();
6098 /* Define where to put the arguments to a function.
6099 Value is zero to push the argument on the stack,
6100 or a hard register in which to store the argument.
6102 MODE is the argument's machine mode.
6103 TYPE is the data type of the argument (as a tree).
6104 This is null for libcalls where that information may
6105 not be available.
6106 CUM is a variable of type CUMULATIVE_ARGS which gives info about
6107 the preceding args and about the function being called.
6108 NAMED is nonzero if this argument is a named parameter
6109 (otherwise it is an extra parameter matching an ellipsis).
6111 On S/390, we use general purpose registers 2 through 6 to
6112 pass integer, pointer, and certain structure arguments, and
6113 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
6114 to pass floating point arguments. All remaining arguments
6115 are pushed to the stack. */
6118 s390_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
6119 int named ATTRIBUTE_UNUSED)
6121 if (s390_function_arg_pass_by_reference (mode, type))
6122 return 0;
6124 if (s390_function_arg_float (mode, type))
6126 if (cum->fprs + 1 > (TARGET_64BIT? 4 : 2))
6127 return 0;
6128 else
6129 return gen_rtx (REG, mode, cum->fprs + 16);
6131 else if (s390_function_arg_integer (mode, type))
6133 int size = s390_function_arg_size (mode, type);
6134 int n_gprs = (size + UNITS_PER_WORD-1) / UNITS_PER_WORD;
6136 if (cum->gprs + n_gprs > 5)
6137 return 0;
6138 else
6139 return gen_rtx (REG, mode, cum->gprs + 2);
6142 /* After the real arguments, expand_call calls us once again
6143 with a void_type_node type. Whatever we return here is
6144 passed as operand 2 to the call expanders.
6146 We don't need this feature ... */
6147 else if (type == void_type_node)
6148 return const0_rtx;
6150 abort ();
6153 /* Return true if return values of type TYPE should be returned
6154 in a memory buffer whose address is passed by the caller as
6155 hidden first argument. */
6157 static bool
6158 s390_return_in_memory (tree type, tree fundecl ATTRIBUTE_UNUSED)
6160 /* We accept small integral (and similar) types. */
6161 if (INTEGRAL_TYPE_P (type)
6162 || POINTER_TYPE_P (type)
6163 || TREE_CODE (type) == OFFSET_TYPE
6164 || TREE_CODE (type) == REAL_TYPE)
6165 return int_size_in_bytes (type) > 8;
6167 /* Aggregates and similar constructs are always returned
6168 in memory. */
6169 if (AGGREGATE_TYPE_P (type)
6170 || TREE_CODE (type) == COMPLEX_TYPE
6171 || TREE_CODE (type) == VECTOR_TYPE)
6172 return true;
6174 /* ??? We get called on all sorts of random stuff from
6175 aggregate_value_p. We can't abort, but it's not clear
6176 what's safe to return. Pretend it's a struct I guess. */
6177 return true;
6180 /* Define where to return a (scalar) value of type TYPE.
6181 If TYPE is null, define where to return a (scalar)
6182 value of mode MODE from a libcall. */
6185 s390_function_value (tree type, enum machine_mode mode)
6187 if (type)
6189 int unsignedp = TREE_UNSIGNED (type);
6190 mode = promote_mode (type, TYPE_MODE (type), &unsignedp, 1);
6193 if (GET_MODE_CLASS (mode) != MODE_INT
6194 && GET_MODE_CLASS (mode) != MODE_FLOAT)
6195 abort ();
6196 if (GET_MODE_SIZE (mode) > 8)
6197 abort ();
6199 if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT)
6200 return gen_rtx_REG (mode, 16);
6201 else
6202 return gen_rtx_REG (mode, 2);
6206 /* Create and return the va_list datatype.
6208 On S/390, va_list is an array type equivalent to
6210 typedef struct __va_list_tag
6212 long __gpr;
6213 long __fpr;
6214 void *__overflow_arg_area;
6215 void *__reg_save_area;
6216 } va_list[1];
6218 where __gpr and __fpr hold the number of general purpose
6219 or floating point arguments used up to now, respectively,
6220 __overflow_arg_area points to the stack location of the
6221 next argument passed on the stack, and __reg_save_area
6222 always points to the start of the register area in the
6223 call frame of the current function. The function prologue
6224 saves all registers used for argument passing into this
6225 area if the function uses variable arguments. */
6227 static tree
6228 s390_build_builtin_va_list (void)
6230 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
6232 record = lang_hooks.types.make_type (RECORD_TYPE);
6234 type_decl =
6235 build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
6237 f_gpr = build_decl (FIELD_DECL, get_identifier ("__gpr"),
6238 long_integer_type_node);
6239 f_fpr = build_decl (FIELD_DECL, get_identifier ("__fpr"),
6240 long_integer_type_node);
6241 f_ovf = build_decl (FIELD_DECL, get_identifier ("__overflow_arg_area"),
6242 ptr_type_node);
6243 f_sav = build_decl (FIELD_DECL, get_identifier ("__reg_save_area"),
6244 ptr_type_node);
6246 DECL_FIELD_CONTEXT (f_gpr) = record;
6247 DECL_FIELD_CONTEXT (f_fpr) = record;
6248 DECL_FIELD_CONTEXT (f_ovf) = record;
6249 DECL_FIELD_CONTEXT (f_sav) = record;
6251 TREE_CHAIN (record) = type_decl;
6252 TYPE_NAME (record) = type_decl;
6253 TYPE_FIELDS (record) = f_gpr;
6254 TREE_CHAIN (f_gpr) = f_fpr;
6255 TREE_CHAIN (f_fpr) = f_ovf;
6256 TREE_CHAIN (f_ovf) = f_sav;
6258 layout_type (record);
6260 /* The correct type is an array type of one element. */
6261 return build_array_type (record, build_index_type (size_zero_node));
6264 /* Implement va_start by filling the va_list structure VALIST.
6265 STDARG_P is always true, and ignored.
6266 NEXTARG points to the first anonymous stack argument.
6268 The following global variables are used to initialize
6269 the va_list structure:
6271 current_function_args_info:
6272 holds number of gprs and fprs used for named arguments.
6273 current_function_arg_offset_rtx:
6274 holds the offset of the first anonymous stack argument
6275 (relative to the virtual arg pointer). */
6277 void
6278 s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
6280 HOST_WIDE_INT n_gpr, n_fpr;
6281 int off;
6282 tree f_gpr, f_fpr, f_ovf, f_sav;
6283 tree gpr, fpr, ovf, sav, t;
6285 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
6286 f_fpr = TREE_CHAIN (f_gpr);
6287 f_ovf = TREE_CHAIN (f_fpr);
6288 f_sav = TREE_CHAIN (f_ovf);
6290 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
6291 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
6292 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
6293 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
6294 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
6296 /* Count number of gp and fp argument registers used. */
6298 n_gpr = current_function_args_info.gprs;
6299 n_fpr = current_function_args_info.fprs;
6301 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, build_int_2 (n_gpr, 0));
6302 TREE_SIDE_EFFECTS (t) = 1;
6303 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6305 t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr, build_int_2 (n_fpr, 0));
6306 TREE_SIDE_EFFECTS (t) = 1;
6307 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6309 /* Find the overflow area. */
6310 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
6312 off = INTVAL (current_function_arg_offset_rtx);
6313 off = off < 0 ? 0 : off;
6314 if (TARGET_DEBUG_ARG)
6315 fprintf (stderr, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
6316 (int)n_gpr, (int)n_fpr, off);
6318 t = build (PLUS_EXPR, TREE_TYPE (ovf), t, build_int_2 (off, 0));
6320 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
6321 TREE_SIDE_EFFECTS (t) = 1;
6322 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6324 /* Find the register save area. */
6325 t = make_tree (TREE_TYPE (sav), virtual_incoming_args_rtx);
6326 t = build (PLUS_EXPR, TREE_TYPE (sav), t,
6327 build_int_2 (-STACK_POINTER_OFFSET, -1));
6328 t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
6329 TREE_SIDE_EFFECTS (t) = 1;
6330 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6333 /* Implement va_arg by updating the va_list structure
6334 VALIST as required to retrieve an argument of type
6335 TYPE, and returning that argument.
6337 Generates code equivalent to:
6339 if (integral value) {
6340 if (size <= 4 && args.gpr < 5 ||
6341 size > 4 && args.gpr < 4 )
6342 ret = args.reg_save_area[args.gpr+8]
6343 else
6344 ret = *args.overflow_arg_area++;
6345 } else if (float value) {
6346 if (args.fgpr < 2)
6347 ret = args.reg_save_area[args.fpr+64]
6348 else
6349 ret = *args.overflow_arg_area++;
6350 } else if (aggregate value) {
6351 if (args.gpr < 5)
6352 ret = *args.reg_save_area[args.gpr]
6353 else
6354 ret = **args.overflow_arg_area++;
6355 } */
6358 s390_va_arg (tree valist, tree type)
6360 tree f_gpr, f_fpr, f_ovf, f_sav;
6361 tree gpr, fpr, ovf, sav, reg, t, u;
6362 int indirect_p, size, n_reg, sav_ofs, sav_scale, max_reg;
6363 rtx lab_false, lab_over, addr_rtx, r;
6365 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
6366 f_fpr = TREE_CHAIN (f_gpr);
6367 f_ovf = TREE_CHAIN (f_fpr);
6368 f_sav = TREE_CHAIN (f_ovf);
6370 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
6371 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
6372 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
6373 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
6374 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
6376 size = int_size_in_bytes (type);
6378 if (s390_function_arg_pass_by_reference (TYPE_MODE (type), type))
6380 if (TARGET_DEBUG_ARG)
6382 fprintf (stderr, "va_arg: aggregate type");
6383 debug_tree (type);
6386 /* Aggregates are passed by reference. */
6387 indirect_p = 1;
6388 reg = gpr;
6389 n_reg = 1;
6390 sav_ofs = 2 * UNITS_PER_WORD;
6391 sav_scale = UNITS_PER_WORD;
6392 size = UNITS_PER_WORD;
6393 max_reg = 4;
6395 else if (s390_function_arg_float (TYPE_MODE (type), type))
6397 if (TARGET_DEBUG_ARG)
6399 fprintf (stderr, "va_arg: float type");
6400 debug_tree (type);
6403 /* FP args go in FP registers, if present. */
6404 indirect_p = 0;
6405 reg = fpr;
6406 n_reg = 1;
6407 sav_ofs = 16 * UNITS_PER_WORD;
6408 sav_scale = 8;
6409 /* TARGET_64BIT has up to 4 parameter in fprs */
6410 max_reg = TARGET_64BIT ? 3 : 1;
6412 else
6414 if (TARGET_DEBUG_ARG)
6416 fprintf (stderr, "va_arg: other type");
6417 debug_tree (type);
6420 /* Otherwise into GP registers. */
6421 indirect_p = 0;
6422 reg = gpr;
6423 n_reg = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6424 sav_ofs = 2 * UNITS_PER_WORD;
6426 if (size < UNITS_PER_WORD)
6427 sav_ofs += UNITS_PER_WORD - size;
6429 sav_scale = UNITS_PER_WORD;
6430 if (n_reg > 1)
6431 max_reg = 3;
6432 else
6433 max_reg = 4;
6436 /* Pull the value out of the saved registers ... */
6438 lab_false = gen_label_rtx ();
6439 lab_over = gen_label_rtx ();
6440 addr_rtx = gen_reg_rtx (Pmode);
6442 emit_cmp_and_jump_insns (expand_expr (reg, NULL_RTX, Pmode, EXPAND_NORMAL),
6443 GEN_INT (max_reg),
6444 GT, const1_rtx, Pmode, 0, lab_false);
6446 if (sav_ofs)
6447 t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
6448 else
6449 t = sav;
6451 u = build (MULT_EXPR, long_integer_type_node,
6452 reg, build_int_2 (sav_scale, 0));
6453 TREE_SIDE_EFFECTS (u) = 1;
6455 t = build (PLUS_EXPR, ptr_type_node, t, u);
6456 TREE_SIDE_EFFECTS (t) = 1;
6458 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
6459 if (r != addr_rtx)
6460 emit_move_insn (addr_rtx, r);
6463 emit_jump_insn (gen_jump (lab_over));
6464 emit_barrier ();
6465 emit_label (lab_false);
6467 /* ... Otherwise out of the overflow area. */
6469 t = save_expr (ovf);
6472 /* In 64 BIT for each argument on stack, a full 64 bit slot is allocated. */
6473 if (size < UNITS_PER_WORD)
6475 t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (UNITS_PER_WORD-size, 0));
6476 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
6477 TREE_SIDE_EFFECTS (t) = 1;
6478 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6480 t = save_expr (ovf);
6483 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
6484 if (r != addr_rtx)
6485 emit_move_insn (addr_rtx, r);
6487 t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (size, 0));
6488 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
6489 TREE_SIDE_EFFECTS (t) = 1;
6490 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6492 emit_label (lab_over);
6494 /* If less than max_regs a registers are retrieved out
6495 of register save area, increment. */
6497 u = build (PREINCREMENT_EXPR, TREE_TYPE (reg), reg,
6498 build_int_2 (n_reg, 0));
6499 TREE_SIDE_EFFECTS (u) = 1;
6500 expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
6502 if (indirect_p)
6504 r = gen_rtx_MEM (Pmode, addr_rtx);
6505 set_mem_alias_set (r, get_varargs_alias_set ());
6506 emit_move_insn (addr_rtx, r);
6510 return addr_rtx;
6514 /* Builtins. */
6516 enum s390_builtin
6518 S390_BUILTIN_THREAD_POINTER,
6519 S390_BUILTIN_SET_THREAD_POINTER,
6521 S390_BUILTIN_max
6524 static unsigned int const code_for_builtin_64[S390_BUILTIN_max] = {
6525 CODE_FOR_get_tp_64,
6526 CODE_FOR_set_tp_64
6529 static unsigned int const code_for_builtin_31[S390_BUILTIN_max] = {
6530 CODE_FOR_get_tp_31,
6531 CODE_FOR_set_tp_31
6534 static void
6535 s390_init_builtins (void)
6537 tree ftype;
6539 ftype = build_function_type (ptr_type_node, void_list_node);
6540 builtin_function ("__builtin_thread_pointer", ftype,
6541 S390_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
6542 NULL, NULL_TREE);
6544 ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
6545 builtin_function ("__builtin_set_thread_pointer", ftype,
6546 S390_BUILTIN_SET_THREAD_POINTER, BUILT_IN_MD,
6547 NULL, NULL_TREE);
6550 /* Expand an expression EXP that calls a built-in function,
6551 with result going to TARGET if that's convenient
6552 (and in mode MODE if that's convenient).
6553 SUBTARGET may be used as the target for computing one of EXP's operands.
6554 IGNORE is nonzero if the value is to be ignored. */
6556 static rtx
6557 s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
6558 enum machine_mode mode ATTRIBUTE_UNUSED,
6559 int ignore ATTRIBUTE_UNUSED)
6561 #define MAX_ARGS 2
6563 unsigned int const *code_for_builtin =
6564 TARGET_64BIT ? code_for_builtin_64 : code_for_builtin_31;
6566 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
6567 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
6568 tree arglist = TREE_OPERAND (exp, 1);
6569 enum insn_code icode;
6570 rtx op[MAX_ARGS], pat;
6571 int arity;
6572 bool nonvoid;
6574 if (fcode >= S390_BUILTIN_max)
6575 internal_error ("bad builtin fcode");
6576 icode = code_for_builtin[fcode];
6577 if (icode == 0)
6578 internal_error ("bad builtin fcode");
6580 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
6582 for (arglist = TREE_OPERAND (exp, 1), arity = 0;
6583 arglist;
6584 arglist = TREE_CHAIN (arglist), arity++)
6586 const struct insn_operand_data *insn_op;
6588 tree arg = TREE_VALUE (arglist);
6589 if (arg == error_mark_node)
6590 return NULL_RTX;
6591 if (arity > MAX_ARGS)
6592 return NULL_RTX;
6594 insn_op = &insn_data[icode].operand[arity + nonvoid];
6596 op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, 0);
6598 if (!(*insn_op->predicate) (op[arity], insn_op->mode))
6599 op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
6602 if (nonvoid)
6604 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6605 if (!target
6606 || GET_MODE (target) != tmode
6607 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
6608 target = gen_reg_rtx (tmode);
6611 switch (arity)
6613 case 0:
6614 pat = GEN_FCN (icode) (target);
6615 break;
6616 case 1:
6617 if (nonvoid)
6618 pat = GEN_FCN (icode) (target, op[0]);
6619 else
6620 pat = GEN_FCN (icode) (op[0]);
6621 break;
6622 case 2:
6623 pat = GEN_FCN (icode) (target, op[0], op[1]);
6624 break;
6625 default:
6626 abort ();
6628 if (!pat)
6629 return NULL_RTX;
6630 emit_insn (pat);
6632 if (nonvoid)
6633 return target;
6634 else
6635 return const0_rtx;
6639 /* Output assembly code for the trampoline template to
6640 stdio stream FILE.
6642 On S/390, we use gpr 1 internally in the trampoline code;
6643 gpr 0 is used to hold the static chain. */
6645 void
6646 s390_trampoline_template (FILE *file)
6648 if (TARGET_64BIT)
6650 fprintf (file, "larl\t%s,0f\n", reg_names[1]);
6651 fprintf (file, "lg\t%s,0(%s)\n", reg_names[0], reg_names[1]);
6652 fprintf (file, "lg\t%s,8(%s)\n", reg_names[1], reg_names[1]);
6653 fprintf (file, "br\t%s\n", reg_names[1]);
6654 fprintf (file, "0:\t.quad\t0\n");
6655 fprintf (file, ".quad\t0\n");
6657 else
6659 fprintf (file, "basr\t%s,0\n", reg_names[1]);
6660 fprintf (file, "l\t%s,10(%s)\n", reg_names[0], reg_names[1]);
6661 fprintf (file, "l\t%s,14(%s)\n", reg_names[1], reg_names[1]);
6662 fprintf (file, "br\t%s\n", reg_names[1]);
6663 fprintf (file, ".long\t0\n");
6664 fprintf (file, ".long\t0\n");
6668 /* Emit RTL insns to initialize the variable parts of a trampoline.
6669 FNADDR is an RTX for the address of the function's pure code.
6670 CXT is an RTX for the static chain value for the function. */
6672 void
6673 s390_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
6675 emit_move_insn (gen_rtx
6676 (MEM, Pmode,
6677 memory_address (Pmode,
6678 plus_constant (addr, (TARGET_64BIT ? 20 : 12) ))), cxt);
6679 emit_move_insn (gen_rtx
6680 (MEM, Pmode,
6681 memory_address (Pmode,
6682 plus_constant (addr, (TARGET_64BIT ? 28 : 16) ))), fnaddr);
6685 /* Return rtx for 64-bit constant formed from the 32-bit subwords
6686 LOW and HIGH, independent of the host word size. */
6689 s390_gen_rtx_const_DI (int high, int low)
6691 #if HOST_BITS_PER_WIDE_INT >= 64
6692 HOST_WIDE_INT val;
6693 val = (HOST_WIDE_INT)high;
6694 val <<= 32;
6695 val |= (HOST_WIDE_INT)low;
6697 return GEN_INT (val);
6698 #else
6699 #if HOST_BITS_PER_WIDE_INT >= 32
6700 return immed_double_const ((HOST_WIDE_INT)low, (HOST_WIDE_INT)high, DImode);
6701 #else
6702 abort ();
6703 #endif
6704 #endif
6707 /* Output assembler code to FILE to increment profiler label # LABELNO
6708 for profiling a function entry. */
6710 void
6711 s390_function_profiler (FILE *file, int labelno)
6713 rtx op[7];
6715 char label[128];
6716 ASM_GENERATE_INTERNAL_LABEL (label, "LP", labelno);
6718 fprintf (file, "# function profiler \n");
6720 op[0] = gen_rtx_REG (Pmode, RETURN_REGNUM);
6721 op[1] = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
6722 op[1] = gen_rtx_MEM (Pmode, plus_constant (op[1], UNITS_PER_WORD));
6724 op[2] = gen_rtx_REG (Pmode, 1);
6725 op[3] = gen_rtx_SYMBOL_REF (Pmode, label);
6726 SYMBOL_REF_FLAGS (op[3]) = SYMBOL_FLAG_LOCAL;
6728 op[4] = gen_rtx_SYMBOL_REF (Pmode, "_mcount");
6729 if (flag_pic)
6731 op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), UNSPEC_PLT);
6732 op[4] = gen_rtx_CONST (Pmode, op[4]);
6735 if (TARGET_64BIT)
6737 output_asm_insn ("stg\t%0,%1", op);
6738 output_asm_insn ("larl\t%2,%3", op);
6739 output_asm_insn ("brasl\t%0,%4", op);
6740 output_asm_insn ("lg\t%0,%1", op);
6742 else if (!flag_pic)
6744 op[6] = gen_label_rtx ();
6746 output_asm_insn ("st\t%0,%1", op);
6747 output_asm_insn ("bras\t%2,%l6", op);
6748 output_asm_insn (".long\t%4", op);
6749 output_asm_insn (".long\t%3", op);
6750 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
6751 output_asm_insn ("l\t%0,0(%2)", op);
6752 output_asm_insn ("l\t%2,4(%2)", op);
6753 output_asm_insn ("basr\t%0,%0", op);
6754 output_asm_insn ("l\t%0,%1", op);
6756 else
6758 op[5] = gen_label_rtx ();
6759 op[6] = gen_label_rtx ();
6761 output_asm_insn ("st\t%0,%1", op);
6762 output_asm_insn ("bras\t%2,%l6", op);
6763 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[5]));
6764 output_asm_insn (".long\t%4-%l5", op);
6765 output_asm_insn (".long\t%3-%l5", op);
6766 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
6767 output_asm_insn ("lr\t%0,%2", op);
6768 output_asm_insn ("a\t%0,0(%2)", op);
6769 output_asm_insn ("a\t%2,4(%2)", op);
6770 output_asm_insn ("basr\t%0,%0", op);
6771 output_asm_insn ("l\t%0,%1", op);
6775 /* Select section for constant in constant pool. In 32-bit mode,
6776 constants go in the function section; in 64-bit mode in .rodata. */
6778 static void
6779 s390_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED,
6780 rtx x ATTRIBUTE_UNUSED,
6781 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
6783 if (TARGET_CPU_ZARCH)
6784 readonly_data_section ();
6785 else
6786 function_section (current_function_decl);
6789 /* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
6790 into its SYMBOL_REF_FLAGS. */
6792 static void
6793 s390_encode_section_info (tree decl, rtx rtl, int first)
6795 default_encode_section_info (decl, rtl, first);
6797 /* If a variable has a forced alignment to < 2 bytes, mark it with
6798 SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL operand. */
6799 if (TREE_CODE (decl) == VAR_DECL
6800 && DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) < 16)
6801 SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_ALIGN1;
6804 /* Output thunk to FILE that implements a C++ virtual function call (with
6805 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
6806 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
6807 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
6808 relative to the resulting this pointer. */
6810 static void
6811 s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
6812 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
6813 tree function)
6815 rtx op[10];
6816 int nonlocal = 0;
6818 /* Operand 0 is the target function. */
6819 op[0] = XEXP (DECL_RTL (function), 0);
6820 if (flag_pic && !SYMBOL_REF_LOCAL_P (op[0]))
6822 nonlocal = 1;
6823 op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]),
6824 TARGET_64BIT ? UNSPEC_PLT : UNSPEC_GOT);
6825 op[0] = gen_rtx_CONST (Pmode, op[0]);
6828 /* Operand 1 is the 'this' pointer. */
6829 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
6830 op[1] = gen_rtx_REG (Pmode, 3);
6831 else
6832 op[1] = gen_rtx_REG (Pmode, 2);
6834 /* Operand 2 is the delta. */
6835 op[2] = GEN_INT (delta);
6837 /* Operand 3 is the vcall_offset. */
6838 op[3] = GEN_INT (vcall_offset);
6840 /* Operand 4 is the temporary register. */
6841 op[4] = gen_rtx_REG (Pmode, 1);
6843 /* Operands 5 to 8 can be used as labels. */
6844 op[5] = NULL_RTX;
6845 op[6] = NULL_RTX;
6846 op[7] = NULL_RTX;
6847 op[8] = NULL_RTX;
6849 /* Operand 9 can be used for temporary register. */
6850 op[9] = NULL_RTX;
6852 /* Generate code. */
6853 if (TARGET_64BIT)
6855 /* Setup literal pool pointer if required. */
6856 if ((!DISP_IN_RANGE (delta)
6857 && !CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
6858 || (!DISP_IN_RANGE (vcall_offset)
6859 && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K")))
6861 op[5] = gen_label_rtx ();
6862 output_asm_insn ("larl\t%4,%5", op);
6865 /* Add DELTA to this pointer. */
6866 if (delta)
6868 if (CONST_OK_FOR_CONSTRAINT_P (delta, 'J', "J"))
6869 output_asm_insn ("la\t%1,%2(%1)", op);
6870 else if (DISP_IN_RANGE (delta))
6871 output_asm_insn ("lay\t%1,%2(%1)", op);
6872 else if (CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
6873 output_asm_insn ("aghi\t%1,%2", op);
6874 else
6876 op[6] = gen_label_rtx ();
6877 output_asm_insn ("agf\t%1,%6-%5(%4)", op);
6881 /* Perform vcall adjustment. */
6882 if (vcall_offset)
6884 if (DISP_IN_RANGE (vcall_offset))
6886 output_asm_insn ("lg\t%4,0(%1)", op);
6887 output_asm_insn ("ag\t%1,%3(%4)", op);
6889 else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K"))
6891 output_asm_insn ("lghi\t%4,%3", op);
6892 output_asm_insn ("ag\t%4,0(%1)", op);
6893 output_asm_insn ("ag\t%1,0(%4)", op);
6895 else
6897 op[7] = gen_label_rtx ();
6898 output_asm_insn ("llgf\t%4,%7-%5(%4)", op);
6899 output_asm_insn ("ag\t%4,0(%1)", op);
6900 output_asm_insn ("ag\t%1,0(%4)", op);
6904 /* Jump to target. */
6905 output_asm_insn ("jg\t%0", op);
6907 /* Output literal pool if required. */
6908 if (op[5])
6910 output_asm_insn (".align\t4", op);
6911 targetm.asm_out.internal_label (file, "L",
6912 CODE_LABEL_NUMBER (op[5]));
6914 if (op[6])
6916 targetm.asm_out.internal_label (file, "L",
6917 CODE_LABEL_NUMBER (op[6]));
6918 output_asm_insn (".long\t%2", op);
6920 if (op[7])
6922 targetm.asm_out.internal_label (file, "L",
6923 CODE_LABEL_NUMBER (op[7]));
6924 output_asm_insn (".long\t%3", op);
6927 else
6929 /* Setup base pointer if required. */
6930 if (!vcall_offset
6931 || (!DISP_IN_RANGE (delta)
6932 && !CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
6933 || (!DISP_IN_RANGE (delta)
6934 && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K")))
6936 op[5] = gen_label_rtx ();
6937 output_asm_insn ("basr\t%4,0", op);
6938 targetm.asm_out.internal_label (file, "L",
6939 CODE_LABEL_NUMBER (op[5]));
6942 /* Add DELTA to this pointer. */
6943 if (delta)
6945 if (CONST_OK_FOR_CONSTRAINT_P (delta, 'J', "J"))
6946 output_asm_insn ("la\t%1,%2(%1)", op);
6947 else if (DISP_IN_RANGE (delta))
6948 output_asm_insn ("lay\t%1,%2(%1)", op);
6949 else if (CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
6950 output_asm_insn ("ahi\t%1,%2", op);
6951 else
6953 op[6] = gen_label_rtx ();
6954 output_asm_insn ("a\t%1,%6-%5(%4)", op);
6958 /* Perform vcall adjustment. */
6959 if (vcall_offset)
6961 if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'J', "J"))
6963 output_asm_insn ("lg\t%4,0(%1)", op);
6964 output_asm_insn ("a\t%1,%3(%4)", op);
6966 else if (DISP_IN_RANGE (vcall_offset))
6968 output_asm_insn ("lg\t%4,0(%1)", op);
6969 output_asm_insn ("ay\t%1,%3(%4)", op);
6971 else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K"))
6973 output_asm_insn ("lhi\t%4,%3", op);
6974 output_asm_insn ("a\t%4,0(%1)", op);
6975 output_asm_insn ("a\t%1,0(%4)", op);
6977 else
6979 op[7] = gen_label_rtx ();
6980 output_asm_insn ("l\t%4,%7-%5(%4)", op);
6981 output_asm_insn ("a\t%4,0(%1)", op);
6982 output_asm_insn ("a\t%1,0(%4)", op);
6985 /* We had to clobber the base pointer register.
6986 Re-setup the base pointer (with a different base). */
6987 op[5] = gen_label_rtx ();
6988 output_asm_insn ("basr\t%4,0", op);
6989 targetm.asm_out.internal_label (file, "L",
6990 CODE_LABEL_NUMBER (op[5]));
6993 /* Jump to target. */
6994 op[8] = gen_label_rtx ();
6996 if (!flag_pic)
6997 output_asm_insn ("l\t%4,%8-%5(%4)", op);
6998 else if (!nonlocal)
6999 output_asm_insn ("a\t%4,%8-%5(%4)", op);
7000 /* We cannot call through .plt, since .plt requires %r12 loaded. */
7001 else if (flag_pic == 1)
7003 output_asm_insn ("a\t%4,%8-%5(%4)", op);
7004 output_asm_insn ("l\t%4,%0(%4)", op);
7006 else if (flag_pic == 2)
7008 op[9] = gen_rtx_REG (Pmode, 0);
7009 output_asm_insn ("l\t%9,%8-4-%5(%4)", op);
7010 output_asm_insn ("a\t%4,%8-%5(%4)", op);
7011 output_asm_insn ("ar\t%4,%9", op);
7012 output_asm_insn ("l\t%4,0(%4)", op);
7015 output_asm_insn ("br\t%4", op);
7017 /* Output literal pool. */
7018 output_asm_insn (".align\t4", op);
7020 if (nonlocal && flag_pic == 2)
7021 output_asm_insn (".long\t%0", op);
7022 if (nonlocal)
7024 op[0] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
7025 SYMBOL_REF_FLAGS (op[0]) = SYMBOL_FLAG_LOCAL;
7028 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[8]));
7029 if (!flag_pic)
7030 output_asm_insn (".long\t%0", op);
7031 else
7032 output_asm_insn (".long\t%0-%5", op);
7034 if (op[6])
7036 targetm.asm_out.internal_label (file, "L",
7037 CODE_LABEL_NUMBER (op[6]));
7038 output_asm_insn (".long\t%2", op);
7040 if (op[7])
7042 targetm.asm_out.internal_label (file, "L",
7043 CODE_LABEL_NUMBER (op[7]));
7044 output_asm_insn (".long\t%3", op);
7049 bool
7050 s390_valid_pointer_mode (enum machine_mode mode)
7052 return (mode == SImode || (TARGET_64BIT && mode == DImode));
7055 /* How to allocate a 'struct machine_function'. */
7057 static struct machine_function *
7058 s390_init_machine_status (void)
7060 return ggc_alloc_cleared (sizeof (struct machine_function));
7063 #include "gt-s390.h"