* targhooks.c: New file.
[official-gcc.git] / gcc / config / s390 / s390.c
blob7086d5b69325acc6b0be8c39f281520b47f52a51
1 /* Subroutines used for code generation on IBM S/390 and zSeries
2 Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
3 Contributed by Hartmut Penner (hpenner@de.ibm.com) and
4 Ulrich Weigand (uweigand@de.ibm.com).
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "tree.h"
29 #include "tm_p.h"
30 #include "regs.h"
31 #include "hard-reg-set.h"
32 #include "real.h"
33 #include "insn-config.h"
34 #include "conditions.h"
35 #include "output.h"
36 #include "insn-attr.h"
37 #include "flags.h"
38 #include "except.h"
39 #include "function.h"
40 #include "recog.h"
41 #include "expr.h"
42 #include "reload.h"
43 #include "toplev.h"
44 #include "basic-block.h"
45 #include "integrate.h"
46 #include "ggc.h"
47 #include "target.h"
48 #include "target-def.h"
49 #include "debug.h"
50 #include "langhooks.h"
51 #include "optabs.h"
53 /* Machine-specific symbol_ref flags. */
54 #define SYMBOL_FLAG_ALIGN1 (SYMBOL_FLAG_MACH_DEP << 0)
57 static bool s390_assemble_integer (rtx, unsigned int, int);
58 static void s390_select_rtx_section (enum machine_mode, rtx,
59 unsigned HOST_WIDE_INT);
60 static void s390_encode_section_info (tree, rtx, int);
61 static bool s390_cannot_force_const_mem (rtx);
62 static rtx s390_delegitimize_address (rtx);
63 static void s390_init_builtins (void);
64 static rtx s390_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
65 static void s390_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
66 HOST_WIDE_INT, tree);
67 static enum attr_type s390_safe_attr_type (rtx);
69 static int s390_adjust_cost (rtx, rtx, rtx, int);
70 static int s390_adjust_priority (rtx, int);
71 static int s390_issue_rate (void);
72 static int s390_use_dfa_pipeline_interface (void);
73 static int s390_first_cycle_multipass_dfa_lookahead (void);
74 static int s390_sched_reorder2 (FILE *, int, rtx *, int *, int);
75 static bool s390_rtx_costs (rtx, int, int, int *);
76 static int s390_address_cost (rtx);
77 static void s390_reorg (void);
78 static bool s390_valid_pointer_mode (enum machine_mode);
80 #undef TARGET_ASM_ALIGNED_HI_OP
81 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
82 #undef TARGET_ASM_ALIGNED_DI_OP
83 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
84 #undef TARGET_ASM_INTEGER
85 #define TARGET_ASM_INTEGER s390_assemble_integer
87 #undef TARGET_ASM_OPEN_PAREN
88 #define TARGET_ASM_OPEN_PAREN ""
90 #undef TARGET_ASM_CLOSE_PAREN
91 #define TARGET_ASM_CLOSE_PAREN ""
93 #undef TARGET_ASM_SELECT_RTX_SECTION
94 #define TARGET_ASM_SELECT_RTX_SECTION s390_select_rtx_section
96 #undef TARGET_ENCODE_SECTION_INFO
97 #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
99 #ifdef HAVE_AS_TLS
100 #undef TARGET_HAVE_TLS
101 #define TARGET_HAVE_TLS true
102 #endif
103 #undef TARGET_CANNOT_FORCE_CONST_MEM
104 #define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
106 #undef TARGET_DELEGITIMIZE_ADDRESS
107 #define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
109 #undef TARGET_INIT_BUILTINS
110 #define TARGET_INIT_BUILTINS s390_init_builtins
111 #undef TARGET_EXPAND_BUILTIN
112 #define TARGET_EXPAND_BUILTIN s390_expand_builtin
114 #undef TARGET_ASM_OUTPUT_MI_THUNK
115 #define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
116 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
117 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
119 #undef TARGET_SCHED_ADJUST_COST
120 #define TARGET_SCHED_ADJUST_COST s390_adjust_cost
121 #undef TARGET_SCHED_ADJUST_PRIORITY
122 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
123 #undef TARGET_SCHED_ISSUE_RATE
124 #define TARGET_SCHED_ISSUE_RATE s390_issue_rate
125 #undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
126 #define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE s390_use_dfa_pipeline_interface
127 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
128 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
129 #undef TARGET_SCHED_REORDER2
130 #define TARGET_SCHED_REORDER2 s390_sched_reorder2
132 #undef TARGET_RTX_COSTS
133 #define TARGET_RTX_COSTS s390_rtx_costs
134 #undef TARGET_ADDRESS_COST
135 #define TARGET_ADDRESS_COST s390_address_cost
137 #undef TARGET_MACHINE_DEPENDENT_REORG
138 #define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
140 #undef TARGET_VALID_POINTER_MODE
141 #define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
143 struct gcc_target targetm = TARGET_INITIALIZER;
145 extern int reload_completed;
147 /* The alias set for prologue/epilogue register save/restore. */
148 static int s390_sr_alias_set = 0;
150 /* Save information from a "cmpxx" operation until the branch or scc is
151 emitted. */
152 rtx s390_compare_op0, s390_compare_op1;
154 /* Structure used to hold the components of a S/390 memory
155 address. A legitimate address on S/390 is of the general
156 form
157 base + index + displacement
158 where any of the components is optional.
160 base and index are registers of the class ADDR_REGS,
161 displacement is an unsigned 12-bit immediate constant. */
163 struct s390_address
165 rtx base;
166 rtx indx;
167 rtx disp;
168 int pointer;
171 /* Which cpu are we tuning for. */
172 enum processor_type s390_tune;
173 enum processor_flags s390_tune_flags;
174 /* Which instruction set architecture to use. */
175 enum processor_type s390_arch;
176 enum processor_flags s390_arch_flags;
178 /* Strings to hold which cpu and instruction set architecture to use. */
179 const char *s390_tune_string; /* for -mtune=<xxx> */
180 const char *s390_arch_string; /* for -march=<xxx> */
182 /* Define the structure for the machine field in struct function. */
184 struct machine_function GTY(())
186 /* Set, if some of the fprs 8-15 need to be saved (64 bit abi). */
187 int save_fprs_p;
189 /* Set if return address needs to be saved because the current
190 function uses __builtin_return_addr (0). */
191 bool save_return_addr_p;
193 /* Number of first and last gpr to be saved, restored. */
194 int first_save_gpr;
195 int first_restore_gpr;
196 int last_save_gpr;
198 /* Size of stack frame. */
199 HOST_WIDE_INT frame_size;
201 /* Some local-dynamic TLS symbol name. */
202 const char *some_ld_name;
205 static int s390_match_ccmode_set (rtx, enum machine_mode);
206 static int s390_branch_condition_mask (rtx);
207 static const char *s390_branch_condition_mnemonic (rtx, int);
208 static int check_mode (rtx, enum machine_mode *);
209 static int general_s_operand (rtx, enum machine_mode, int);
210 static int s390_short_displacement (rtx);
211 static int s390_decompose_address (rtx, struct s390_address *);
212 static rtx get_thread_pointer (void);
213 static rtx legitimize_tls_address (rtx, rtx);
214 static const char *get_some_local_dynamic_name (void);
215 static int get_some_local_dynamic_name_1 (rtx *, void *);
216 static int reg_used_in_mem_p (int, rtx);
217 static int addr_generation_dependency_p (rtx, rtx);
218 static int s390_split_branches (rtx, bool *);
219 static void find_constant_pool_ref (rtx, rtx *);
220 static void replace_constant_pool_ref (rtx *, rtx, rtx);
221 static rtx find_ltrel_base (rtx);
222 static void replace_ltrel_base (rtx *, rtx);
223 static void s390_optimize_prolog (bool, bool);
224 static int find_unused_clobbered_reg (void);
225 static void s390_frame_info (void);
226 static rtx save_fpr (rtx, int, int);
227 static rtx restore_fpr (rtx, int, int);
228 static rtx save_gprs (rtx, int, int, int);
229 static rtx restore_gprs (rtx, int, int, int);
230 static int s390_function_arg_size (enum machine_mode, tree);
231 static bool s390_function_arg_float (enum machine_mode, tree);
232 static struct machine_function * s390_init_machine_status (void);
234 /* Check whether integer displacement is in range. */
235 #define DISP_IN_RANGE(d) \
236 (TARGET_LONG_DISPLACEMENT? ((d) >= -524288 && (d) <= 524287) \
237 : ((d) >= 0 && (d) <= 4095))
239 /* Return true if SET either doesn't set the CC register, or else
240 the source and destination have matching CC modes and that
241 CC mode is at least as constrained as REQ_MODE. */
243 static int
244 s390_match_ccmode_set (rtx set, enum machine_mode req_mode)
246 enum machine_mode set_mode;
248 if (GET_CODE (set) != SET)
249 abort ();
251 if (GET_CODE (SET_DEST (set)) != REG || !CC_REGNO_P (REGNO (SET_DEST (set))))
252 return 1;
254 set_mode = GET_MODE (SET_DEST (set));
255 switch (set_mode)
257 case CCSmode:
258 case CCSRmode:
259 case CCUmode:
260 case CCURmode:
261 case CCLmode:
262 case CCL1mode:
263 case CCL2mode:
264 case CCT1mode:
265 case CCT2mode:
266 case CCT3mode:
267 if (req_mode != set_mode)
268 return 0;
269 break;
271 case CCZmode:
272 if (req_mode != CCSmode && req_mode != CCUmode && req_mode != CCTmode
273 && req_mode != CCSRmode && req_mode != CCURmode)
274 return 0;
275 break;
277 case CCAPmode:
278 case CCANmode:
279 if (req_mode != CCAmode)
280 return 0;
281 break;
283 default:
284 abort ();
287 return (GET_MODE (SET_SRC (set)) == set_mode);
290 /* Return true if every SET in INSN that sets the CC register
291 has source and destination with matching CC modes and that
292 CC mode is at least as constrained as REQ_MODE.
293 If REQ_MODE is VOIDmode, always return false. */
296 s390_match_ccmode (rtx insn, enum machine_mode req_mode)
298 int i;
300 /* s390_tm_ccmode returns VOIDmode to indicate failure. */
301 if (req_mode == VOIDmode)
302 return 0;
304 if (GET_CODE (PATTERN (insn)) == SET)
305 return s390_match_ccmode_set (PATTERN (insn), req_mode);
307 if (GET_CODE (PATTERN (insn)) == PARALLEL)
308 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
310 rtx set = XVECEXP (PATTERN (insn), 0, i);
311 if (GET_CODE (set) == SET)
312 if (!s390_match_ccmode_set (set, req_mode))
313 return 0;
316 return 1;
319 /* If a test-under-mask instruction can be used to implement
320 (compare (and ... OP1) OP2), return the CC mode required
321 to do that. Otherwise, return VOIDmode.
322 MIXED is true if the instruction can distinguish between
323 CC1 and CC2 for mixed selected bits (TMxx), it is false
324 if the instruction cannot (TM). */
326 enum machine_mode
327 s390_tm_ccmode (rtx op1, rtx op2, int mixed)
329 int bit0, bit1;
331 /* ??? Fixme: should work on CONST_DOUBLE as well. */
332 if (GET_CODE (op1) != CONST_INT || GET_CODE (op2) != CONST_INT)
333 return VOIDmode;
335 /* Selected bits all zero: CC0. */
336 if (INTVAL (op2) == 0)
337 return CCTmode;
339 /* Selected bits all one: CC3. */
340 if (INTVAL (op2) == INTVAL (op1))
341 return CCT3mode;
343 /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2. */
344 if (mixed)
346 bit1 = exact_log2 (INTVAL (op2));
347 bit0 = exact_log2 (INTVAL (op1) ^ INTVAL (op2));
348 if (bit0 != -1 && bit1 != -1)
349 return bit0 > bit1 ? CCT1mode : CCT2mode;
352 return VOIDmode;
355 /* Given a comparison code OP (EQ, NE, etc.) and the operands
356 OP0 and OP1 of a COMPARE, return the mode to be used for the
357 comparison. */
359 enum machine_mode
360 s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
362 switch (code)
364 case EQ:
365 case NE:
366 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
367 && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op0, 1)), 'K'))
368 return CCAPmode;
369 if ((GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
370 || GET_CODE (op1) == NEG)
371 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
372 return CCLmode;
374 if (GET_CODE (op0) == AND)
376 /* Check whether we can potentially do it via TM. */
377 enum machine_mode ccmode;
378 ccmode = s390_tm_ccmode (XEXP (op0, 1), op1, 1);
379 if (ccmode != VOIDmode)
381 /* Relax CCTmode to CCZmode to allow fall-back to AND
382 if that turns out to be beneficial. */
383 return ccmode == CCTmode ? CCZmode : ccmode;
387 if (register_operand (op0, HImode)
388 && GET_CODE (op1) == CONST_INT
389 && (INTVAL (op1) == -1 || INTVAL (op1) == 65535))
390 return CCT3mode;
391 if (register_operand (op0, QImode)
392 && GET_CODE (op1) == CONST_INT
393 && (INTVAL (op1) == -1 || INTVAL (op1) == 255))
394 return CCT3mode;
396 return CCZmode;
398 case LE:
399 case LT:
400 case GE:
401 case GT:
402 if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
403 && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op0, 1)), 'K'))
405 if (INTVAL (XEXP((op0), 1)) < 0)
406 return CCANmode;
407 else
408 return CCAPmode;
410 case UNORDERED:
411 case ORDERED:
412 case UNEQ:
413 case UNLE:
414 case UNLT:
415 case UNGE:
416 case UNGT:
417 case LTGT:
418 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
419 && GET_CODE (op1) != CONST_INT)
420 return CCSRmode;
421 return CCSmode;
423 case LTU:
424 case GEU:
425 if (GET_CODE (op0) == PLUS
426 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
427 return CCL1mode;
429 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
430 && GET_CODE (op1) != CONST_INT)
431 return CCURmode;
432 return CCUmode;
434 case LEU:
435 case GTU:
436 if (GET_CODE (op0) == MINUS
437 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
438 return CCL2mode;
440 if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
441 && GET_CODE (op1) != CONST_INT)
442 return CCURmode;
443 return CCUmode;
445 default:
446 abort ();
450 /* Return branch condition mask to implement a branch
451 specified by CODE. */
453 static int
454 s390_branch_condition_mask (rtx code)
456 const int CC0 = 1 << 3;
457 const int CC1 = 1 << 2;
458 const int CC2 = 1 << 1;
459 const int CC3 = 1 << 0;
461 if (GET_CODE (XEXP (code, 0)) != REG
462 || REGNO (XEXP (code, 0)) != CC_REGNUM
463 || XEXP (code, 1) != const0_rtx)
464 abort ();
466 switch (GET_MODE (XEXP (code, 0)))
468 case CCZmode:
469 switch (GET_CODE (code))
471 case EQ: return CC0;
472 case NE: return CC1 | CC2 | CC3;
473 default:
474 abort ();
476 break;
478 case CCT1mode:
479 switch (GET_CODE (code))
481 case EQ: return CC1;
482 case NE: return CC0 | CC2 | CC3;
483 default:
484 abort ();
486 break;
488 case CCT2mode:
489 switch (GET_CODE (code))
491 case EQ: return CC2;
492 case NE: return CC0 | CC1 | CC3;
493 default:
494 abort ();
496 break;
498 case CCT3mode:
499 switch (GET_CODE (code))
501 case EQ: return CC3;
502 case NE: return CC0 | CC1 | CC2;
503 default:
504 abort ();
506 break;
508 case CCLmode:
509 switch (GET_CODE (code))
511 case EQ: return CC0 | CC2;
512 case NE: return CC1 | CC3;
513 default:
514 abort ();
516 break;
518 case CCL1mode:
519 switch (GET_CODE (code))
521 case LTU: return CC2 | CC3; /* carry */
522 case GEU: return CC0 | CC1; /* no carry */
523 default:
524 abort ();
526 break;
528 case CCL2mode:
529 switch (GET_CODE (code))
531 case GTU: return CC0 | CC1; /* borrow */
532 case LEU: return CC2 | CC3; /* no borrow */
533 default:
534 abort ();
536 break;
538 case CCUmode:
539 switch (GET_CODE (code))
541 case EQ: return CC0;
542 case NE: return CC1 | CC2 | CC3;
543 case LTU: return CC1;
544 case GTU: return CC2;
545 case LEU: return CC0 | CC1;
546 case GEU: return CC0 | CC2;
547 default:
548 abort ();
550 break;
552 case CCURmode:
553 switch (GET_CODE (code))
555 case EQ: return CC0;
556 case NE: return CC2 | CC1 | CC3;
557 case LTU: return CC2;
558 case GTU: return CC1;
559 case LEU: return CC0 | CC2;
560 case GEU: return CC0 | CC1;
561 default:
562 abort ();
564 break;
566 case CCAPmode:
567 switch (GET_CODE (code))
569 case EQ: return CC0;
570 case NE: return CC1 | CC2 | CC3;
571 case LT: return CC1 | CC3;
572 case GT: return CC2;
573 case LE: return CC0 | CC1 | CC3;
574 case GE: return CC0 | CC2;
575 default:
576 abort ();
578 break;
580 case CCANmode:
581 switch (GET_CODE (code))
583 case EQ: return CC0;
584 case NE: return CC1 | CC2 | CC3;
585 case LT: return CC1;
586 case GT: return CC2 | CC3;
587 case LE: return CC0 | CC1;
588 case GE: return CC0 | CC2 | CC3;
589 default:
590 abort ();
592 break;
594 case CCSmode:
595 switch (GET_CODE (code))
597 case EQ: return CC0;
598 case NE: return CC1 | CC2 | CC3;
599 case LT: return CC1;
600 case GT: return CC2;
601 case LE: return CC0 | CC1;
602 case GE: return CC0 | CC2;
603 case UNORDERED: return CC3;
604 case ORDERED: return CC0 | CC1 | CC2;
605 case UNEQ: return CC0 | CC3;
606 case UNLT: return CC1 | CC3;
607 case UNGT: return CC2 | CC3;
608 case UNLE: return CC0 | CC1 | CC3;
609 case UNGE: return CC0 | CC2 | CC3;
610 case LTGT: return CC1 | CC2;
611 default:
612 abort ();
614 break;
616 case CCSRmode:
617 switch (GET_CODE (code))
619 case EQ: return CC0;
620 case NE: return CC2 | CC1 | CC3;
621 case LT: return CC2;
622 case GT: return CC1;
623 case LE: return CC0 | CC2;
624 case GE: return CC0 | CC1;
625 case UNORDERED: return CC3;
626 case ORDERED: return CC0 | CC2 | CC1;
627 case UNEQ: return CC0 | CC3;
628 case UNLT: return CC2 | CC3;
629 case UNGT: return CC1 | CC3;
630 case UNLE: return CC0 | CC2 | CC3;
631 case UNGE: return CC0 | CC1 | CC3;
632 case LTGT: return CC2 | CC1;
633 default:
634 abort ();
636 break;
638 default:
639 abort ();
643 /* If INV is false, return assembler mnemonic string to implement
644 a branch specified by CODE. If INV is true, return mnemonic
645 for the corresponding inverted branch. */
647 static const char *
648 s390_branch_condition_mnemonic (rtx code, int inv)
650 static const char *const mnemonic[16] =
652 NULL, "o", "h", "nle",
653 "l", "nhe", "lh", "ne",
654 "e", "nlh", "he", "nl",
655 "le", "nh", "no", NULL
658 int mask = s390_branch_condition_mask (code);
660 if (inv)
661 mask ^= 15;
663 if (mask < 1 || mask > 14)
664 abort ();
666 return mnemonic[mask];
669 /* If OP is an integer constant of mode MODE with exactly one
670 HImode subpart unequal to DEF, return the number of that
671 subpart. As a special case, all HImode subparts of OP are
672 equal to DEF, return zero. Otherwise, return -1. */
675 s390_single_hi (rtx op, enum machine_mode mode, int def)
677 if (GET_CODE (op) == CONST_INT)
679 unsigned HOST_WIDE_INT value = 0;
680 int n_parts = GET_MODE_SIZE (mode) / 2;
681 int i, part = -1;
683 for (i = 0; i < n_parts; i++)
685 if (i == 0)
686 value = (unsigned HOST_WIDE_INT) INTVAL (op);
687 else
688 value >>= 16;
690 if ((value & 0xffff) != (unsigned)(def & 0xffff))
692 if (part != -1)
693 return -1;
694 else
695 part = i;
699 return part == -1 ? 0 : (n_parts - 1 - part);
702 else if (GET_CODE (op) == CONST_DOUBLE
703 && GET_MODE (op) == VOIDmode)
705 unsigned HOST_WIDE_INT value = 0;
706 int n_parts = GET_MODE_SIZE (mode) / 2;
707 int i, part = -1;
709 for (i = 0; i < n_parts; i++)
711 if (i == 0)
712 value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
713 else if (i == HOST_BITS_PER_WIDE_INT / 16)
714 value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op);
715 else
716 value >>= 16;
718 if ((value & 0xffff) != (unsigned)(def & 0xffff))
720 if (part != -1)
721 return -1;
722 else
723 part = i;
727 return part == -1 ? 0 : (n_parts - 1 - part);
730 return -1;
733 /* Extract the HImode part number PART from integer
734 constant OP of mode MODE. */
737 s390_extract_hi (rtx op, enum machine_mode mode, int part)
739 int n_parts = GET_MODE_SIZE (mode) / 2;
740 if (part < 0 || part >= n_parts)
741 abort();
742 else
743 part = n_parts - 1 - part;
745 if (GET_CODE (op) == CONST_INT)
747 unsigned HOST_WIDE_INT value = (unsigned HOST_WIDE_INT) INTVAL (op);
748 return ((value >> (16 * part)) & 0xffff);
750 else if (GET_CODE (op) == CONST_DOUBLE
751 && GET_MODE (op) == VOIDmode)
753 unsigned HOST_WIDE_INT value;
754 if (part < HOST_BITS_PER_WIDE_INT / 16)
755 value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
756 else
757 value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op),
758 part -= HOST_BITS_PER_WIDE_INT / 16;
760 return ((value >> (16 * part)) & 0xffff);
763 abort ();
766 /* If OP is an integer constant of mode MODE with exactly one
767 QImode subpart unequal to DEF, return the number of that
768 subpart. As a special case, all QImode subparts of OP are
769 equal to DEF, return zero. Otherwise, return -1. */
772 s390_single_qi (rtx op, enum machine_mode mode, int def)
774 if (GET_CODE (op) == CONST_INT)
776 unsigned HOST_WIDE_INT value = 0;
777 int n_parts = GET_MODE_SIZE (mode);
778 int i, part = -1;
780 for (i = 0; i < n_parts; i++)
782 if (i == 0)
783 value = (unsigned HOST_WIDE_INT) INTVAL (op);
784 else
785 value >>= 8;
787 if ((value & 0xff) != (unsigned)(def & 0xff))
789 if (part != -1)
790 return -1;
791 else
792 part = i;
796 return part == -1 ? 0 : (n_parts - 1 - part);
799 else if (GET_CODE (op) == CONST_DOUBLE
800 && GET_MODE (op) == VOIDmode)
802 unsigned HOST_WIDE_INT value = 0;
803 int n_parts = GET_MODE_SIZE (mode);
804 int i, part = -1;
806 for (i = 0; i < n_parts; i++)
808 if (i == 0)
809 value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
810 else if (i == HOST_BITS_PER_WIDE_INT / 8)
811 value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op);
812 else
813 value >>= 8;
815 if ((value & 0xff) != (unsigned)(def & 0xff))
817 if (part != -1)
818 return -1;
819 else
820 part = i;
824 return part == -1 ? 0 : (n_parts - 1 - part);
827 return -1;
830 /* Extract the QImode part number PART from integer
831 constant OP of mode MODE. */
834 s390_extract_qi (rtx op, enum machine_mode mode, int part)
836 int n_parts = GET_MODE_SIZE (mode);
837 if (part < 0 || part >= n_parts)
838 abort();
839 else
840 part = n_parts - 1 - part;
842 if (GET_CODE (op) == CONST_INT)
844 unsigned HOST_WIDE_INT value = (unsigned HOST_WIDE_INT) INTVAL (op);
845 return ((value >> (8 * part)) & 0xff);
847 else if (GET_CODE (op) == CONST_DOUBLE
848 && GET_MODE (op) == VOIDmode)
850 unsigned HOST_WIDE_INT value;
851 if (part < HOST_BITS_PER_WIDE_INT / 8)
852 value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
853 else
854 value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op),
855 part -= HOST_BITS_PER_WIDE_INT / 8;
857 return ((value >> (8 * part)) & 0xff);
860 abort ();
863 /* Check whether we can (and want to) split a double-word
864 move in mode MODE from SRC to DST into two single-word
865 moves, moving the subword FIRST_SUBWORD first. */
867 bool
868 s390_split_ok_p (rtx dst, rtx src, enum machine_mode mode, int first_subword)
870 /* Floating point registers cannot be split. */
871 if (FP_REG_P (src) || FP_REG_P (dst))
872 return false;
874 /* We don't need to split if operands are directly accessible. */
875 if (s_operand (src, mode) || s_operand (dst, mode))
876 return false;
878 /* Non-offsettable memory references cannot be split. */
879 if ((GET_CODE (src) == MEM && !offsettable_memref_p (src))
880 || (GET_CODE (dst) == MEM && !offsettable_memref_p (dst)))
881 return false;
883 /* Moving the first subword must not clobber a register
884 needed to move the second subword. */
885 if (register_operand (dst, mode))
887 rtx subreg = operand_subword (dst, first_subword, 0, mode);
888 if (reg_overlap_mentioned_p (subreg, src))
889 return false;
892 return true;
896 /* Change optimizations to be performed, depending on the
897 optimization level.
899 LEVEL is the optimization level specified; 2 if `-O2' is
900 specified, 1 if `-O' is specified, and 0 if neither is specified.
902 SIZE is nonzero if `-Os' is specified and zero otherwise. */
904 void
905 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
907 /* ??? There are apparently still problems with -fcaller-saves. */
908 flag_caller_saves = 0;
910 /* By default, always emit DWARF-2 unwind info. This allows debugging
911 without maintaining a stack frame back-chain. */
912 flag_asynchronous_unwind_tables = 1;
915 void
916 override_options (void)
918 int i;
919 static struct pta
921 const char *const name; /* processor name or nickname. */
922 const enum processor_type processor;
923 const enum processor_flags flags;
925 const processor_alias_table[] =
927 {"g5", PROCESSOR_9672_G5, PF_IEEE_FLOAT},
928 {"g6", PROCESSOR_9672_G6, PF_IEEE_FLOAT},
929 {"z900", PROCESSOR_2064_Z900, PF_IEEE_FLOAT | PF_ZARCH},
930 {"z990", PROCESSOR_2084_Z990, PF_IEEE_FLOAT | PF_ZARCH
931 | PF_LONG_DISPLACEMENT},
934 int const pta_size = ARRAY_SIZE (processor_alias_table);
936 /* Acquire a unique set number for our register saves and restores. */
937 s390_sr_alias_set = new_alias_set ();
939 /* Set up function hooks. */
940 init_machine_status = s390_init_machine_status;
942 /* Architecture mode defaults according to ABI. */
943 if (!(target_flags_explicit & MASK_ZARCH))
945 if (TARGET_64BIT)
946 target_flags |= MASK_ZARCH;
947 else
948 target_flags &= ~MASK_ZARCH;
951 /* Determine processor architectural level. */
952 if (!s390_arch_string)
953 s390_arch_string = TARGET_ZARCH? "z900" : "g5";
955 for (i = 0; i < pta_size; i++)
956 if (! strcmp (s390_arch_string, processor_alias_table[i].name))
958 s390_arch = processor_alias_table[i].processor;
959 s390_arch_flags = processor_alias_table[i].flags;
960 break;
962 if (i == pta_size)
963 error ("Unknown cpu used in -march=%s.", s390_arch_string);
965 /* Determine processor to tune for. */
966 if (!s390_tune_string)
968 s390_tune = s390_arch;
969 s390_tune_flags = s390_arch_flags;
970 s390_tune_string = s390_arch_string;
972 else
974 for (i = 0; i < pta_size; i++)
975 if (! strcmp (s390_tune_string, processor_alias_table[i].name))
977 s390_tune = processor_alias_table[i].processor;
978 s390_tune_flags = processor_alias_table[i].flags;
979 break;
981 if (i == pta_size)
982 error ("Unknown cpu used in -mtune=%s.", s390_tune_string);
985 /* Sanity checks. */
986 if (TARGET_ZARCH && !(s390_arch_flags & PF_ZARCH))
987 error ("z/Architecture mode not supported on %s.", s390_arch_string);
988 if (TARGET_64BIT && !TARGET_ZARCH)
989 error ("64-bit ABI not supported in ESA/390 mode.");
992 /* Map for smallest class containing reg regno. */
994 const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
995 { GENERAL_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
996 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
997 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
998 ADDR_REGS, ADDR_REGS, ADDR_REGS, ADDR_REGS,
999 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1000 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1001 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1002 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
1003 ADDR_REGS, NO_REGS, ADDR_REGS
1006 /* Return attribute type of insn. */
1008 static enum attr_type
1009 s390_safe_attr_type (rtx insn)
1011 if (recog_memoized (insn) >= 0)
1012 return get_attr_type (insn);
1013 else
1014 return TYPE_NONE;
1017 /* Return true if OP a (const_int 0) operand.
1018 OP is the current operation.
1019 MODE is the current operation mode. */
1022 const0_operand (register rtx op, enum machine_mode mode)
1024 return op == CONST0_RTX (mode);
1027 /* Return true if OP is constant.
1028 OP is the current operation.
1029 MODE is the current operation mode. */
1032 consttable_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1034 return CONSTANT_P (op);
1037 /* Return true if the mode of operand OP matches MODE.
1038 If MODE is set to VOIDmode, set it to the mode of OP. */
1040 static int
1041 check_mode (register rtx op, enum machine_mode *mode)
1043 if (*mode == VOIDmode)
1044 *mode = GET_MODE (op);
1045 else
1047 if (GET_MODE (op) != VOIDmode && GET_MODE (op) != *mode)
1048 return 0;
1050 return 1;
1053 /* Return true if OP a valid operand for the LARL instruction.
1054 OP is the current operation.
1055 MODE is the current operation mode. */
1058 larl_operand (register rtx op, enum machine_mode mode)
1060 if (! check_mode (op, &mode))
1061 return 0;
1063 /* Allow labels and local symbols. */
1064 if (GET_CODE (op) == LABEL_REF)
1065 return 1;
1066 if (GET_CODE (op) == SYMBOL_REF)
1067 return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0
1068 && SYMBOL_REF_TLS_MODEL (op) == 0
1069 && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
1071 /* Everything else must have a CONST, so strip it. */
1072 if (GET_CODE (op) != CONST)
1073 return 0;
1074 op = XEXP (op, 0);
1076 /* Allow adding *even* in-range constants. */
1077 if (GET_CODE (op) == PLUS)
1079 if (GET_CODE (XEXP (op, 1)) != CONST_INT
1080 || (INTVAL (XEXP (op, 1)) & 1) != 0)
1081 return 0;
1082 #if HOST_BITS_PER_WIDE_INT > 32
1083 if (INTVAL (XEXP (op, 1)) >= (HOST_WIDE_INT)1 << 32
1084 || INTVAL (XEXP (op, 1)) < -((HOST_WIDE_INT)1 << 32))
1085 return 0;
1086 #endif
1087 op = XEXP (op, 0);
1090 /* Labels and local symbols allowed here as well. */
1091 if (GET_CODE (op) == LABEL_REF)
1092 return 1;
1093 if (GET_CODE (op) == SYMBOL_REF)
1094 return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0
1095 && SYMBOL_REF_TLS_MODEL (op) == 0
1096 && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
1098 /* Now we must have a @GOTENT offset or @PLT stub
1099 or an @INDNTPOFF TLS offset. */
1100 if (GET_CODE (op) == UNSPEC
1101 && XINT (op, 1) == UNSPEC_GOTENT)
1102 return 1;
1103 if (GET_CODE (op) == UNSPEC
1104 && XINT (op, 1) == UNSPEC_PLT)
1105 return 1;
1106 if (GET_CODE (op) == UNSPEC
1107 && XINT (op, 1) == UNSPEC_INDNTPOFF)
1108 return 1;
1110 return 0;
1113 /* Helper routine to implement s_operand and s_imm_operand.
1114 OP is the current operation.
1115 MODE is the current operation mode.
1116 ALLOW_IMMEDIATE specifies whether immediate operands should
1117 be accepted or not. */
1119 static int
1120 general_s_operand (register rtx op, enum machine_mode mode,
1121 int allow_immediate)
1123 struct s390_address addr;
1125 /* Call general_operand first, so that we don't have to
1126 check for many special cases. */
1127 if (!general_operand (op, mode))
1128 return 0;
1130 /* Just like memory_operand, allow (subreg (mem ...))
1131 after reload. */
1132 if (reload_completed
1133 && GET_CODE (op) == SUBREG
1134 && GET_CODE (SUBREG_REG (op)) == MEM)
1135 op = SUBREG_REG (op);
1137 switch (GET_CODE (op))
1139 /* Constants are OK as s-operand if ALLOW_IMMEDIATE
1140 is true and we are still before reload. */
1141 case CONST_INT:
1142 case CONST_DOUBLE:
1143 if (!allow_immediate || reload_completed)
1144 return 0;
1145 return 1;
1147 /* Memory operands are OK unless they already use an
1148 index register. */
1149 case MEM:
1150 if (GET_CODE (XEXP (op, 0)) == ADDRESSOF)
1151 return 1;
1152 if (!s390_decompose_address (XEXP (op, 0), &addr))
1153 return 0;
1154 if (addr.indx)
1155 return 0;
1156 /* Do not allow literal pool references unless ALLOW_IMMEDIATE
1157 is true. This prevents compares between two literal pool
1158 entries from being accepted. */
1159 if (!allow_immediate
1160 && addr.base && REGNO (addr.base) == BASE_REGISTER)
1161 return 0;
1162 return 1;
1164 default:
1165 break;
1168 return 0;
1171 /* Return true if OP is a valid S-type operand.
1172 OP is the current operation.
1173 MODE is the current operation mode. */
1176 s_operand (register rtx op, enum machine_mode mode)
1178 return general_s_operand (op, mode, 0);
1181 /* Return true if OP is a valid S-type operand or an immediate
1182 operand that can be addressed as S-type operand by forcing
1183 it into the literal pool.
1184 OP is the current operation.
1185 MODE is the current operation mode. */
1188 s_imm_operand (register rtx op, enum machine_mode mode)
1190 return general_s_operand (op, mode, 1);
1193 /* Return true if DISP is a valid short displacement. */
1195 static int
1196 s390_short_displacement (rtx disp)
1198 /* No displacement is OK. */
1199 if (!disp)
1200 return 1;
1202 /* Integer displacement in range. */
1203 if (GET_CODE (disp) == CONST_INT)
1204 return INTVAL (disp) >= 0 && INTVAL (disp) < 4096;
1206 /* GOT offset is not OK, the GOT can be large. */
1207 if (GET_CODE (disp) == CONST
1208 && GET_CODE (XEXP (disp, 0)) == UNSPEC
1209 && XINT (XEXP (disp, 0), 1) == UNSPEC_GOT)
1210 return 0;
1212 /* All other symbolic constants are literal pool references,
1213 which are OK as the literal pool must be small. */
1214 if (GET_CODE (disp) == CONST)
1215 return 1;
1217 return 0;
1220 /* Return true if OP is a valid operand for a C constraint. */
1223 s390_extra_constraint (rtx op, int c)
1225 struct s390_address addr;
1227 switch (c)
1229 case 'Q':
1230 if (GET_CODE (op) != MEM)
1231 return 0;
1232 if (!s390_decompose_address (XEXP (op, 0), &addr))
1233 return 0;
1234 if (addr.indx)
1235 return 0;
1237 if (TARGET_LONG_DISPLACEMENT)
1239 if (!s390_short_displacement (addr.disp))
1240 return 0;
1242 break;
1244 case 'R':
1245 if (GET_CODE (op) != MEM)
1246 return 0;
1248 if (TARGET_LONG_DISPLACEMENT)
1250 if (!s390_decompose_address (XEXP (op, 0), &addr))
1251 return 0;
1252 if (!s390_short_displacement (addr.disp))
1253 return 0;
1255 break;
1257 case 'S':
1258 if (!TARGET_LONG_DISPLACEMENT)
1259 return 0;
1260 if (GET_CODE (op) != MEM)
1261 return 0;
1262 if (!s390_decompose_address (XEXP (op, 0), &addr))
1263 return 0;
1264 if (addr.indx)
1265 return 0;
1266 if (s390_short_displacement (addr.disp))
1267 return 0;
1268 break;
1270 case 'T':
1271 if (!TARGET_LONG_DISPLACEMENT)
1272 return 0;
1273 if (GET_CODE (op) != MEM)
1274 return 0;
1275 /* Any invalid address here will be fixed up by reload,
1276 so accept it for the most generic constraint. */
1277 if (s390_decompose_address (XEXP (op, 0), &addr)
1278 && s390_short_displacement (addr.disp))
1279 return 0;
1280 break;
1282 case 'U':
1283 if (TARGET_LONG_DISPLACEMENT)
1285 if (!s390_decompose_address (op, &addr))
1286 return 0;
1287 if (!s390_short_displacement (addr.disp))
1288 return 0;
1290 break;
1292 case 'W':
1293 if (!TARGET_LONG_DISPLACEMENT)
1294 return 0;
1295 /* Any invalid address here will be fixed up by reload,
1296 so accept it for the most generic constraint. */
1297 if (s390_decompose_address (op, &addr)
1298 && s390_short_displacement (addr.disp))
1299 return 0;
1300 break;
1302 default:
1303 return 0;
1306 return 1;
1309 /* Compute a (partial) cost for rtx X. Return true if the complete
1310 cost has been computed, and false if subexpressions should be
1311 scanned. In either case, *TOTAL contains the cost result. */
1313 static bool
1314 s390_rtx_costs (rtx x, int code, int outer_code, int *total)
1316 switch (code)
1318 case CONST:
1319 if (GET_CODE (XEXP (x, 0)) == MINUS
1320 && GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
1321 *total = 1000;
1322 else
1323 *total = 0;
1324 return true;
1326 case CONST_INT:
1327 /* Force_const_mem does not work out of reload, because the
1328 saveable_obstack is set to reload_obstack, which does not
1329 live long enough. Because of this we cannot use force_const_mem
1330 in addsi3. This leads to problems with gen_add2_insn with a
1331 constant greater than a short. Because of that we give an
1332 addition of greater constants a cost of 3 (reload1.c 10096). */
1333 /* ??? saveable_obstack no longer exists. */
1334 if (outer_code == PLUS
1335 && (INTVAL (x) > 32767 || INTVAL (x) < -32768))
1336 *total = COSTS_N_INSNS (3);
1337 else
1338 *total = 0;
1339 return true;
1341 case LABEL_REF:
1342 case SYMBOL_REF:
1343 case CONST_DOUBLE:
1344 *total = 0;
1345 return true;
1347 case ASHIFT:
1348 case ASHIFTRT:
1349 case LSHIFTRT:
1350 case PLUS:
1351 case AND:
1352 case IOR:
1353 case XOR:
1354 case MINUS:
1355 case NEG:
1356 case NOT:
1357 *total = COSTS_N_INSNS (1);
1358 return true;
1360 case MULT:
1361 if (GET_MODE (XEXP (x, 0)) == DImode)
1362 *total = COSTS_N_INSNS (40);
1363 else
1364 *total = COSTS_N_INSNS (7);
1365 return true;
1367 case DIV:
1368 case UDIV:
1369 case MOD:
1370 case UMOD:
1371 *total = COSTS_N_INSNS (33);
1372 return true;
1374 default:
1375 return false;
1379 /* Return the cost of an address rtx ADDR. */
1381 static int
1382 s390_address_cost (rtx addr)
1384 struct s390_address ad;
1385 if (!s390_decompose_address (addr, &ad))
1386 return 1000;
1388 return ad.indx? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (1);
1391 /* Return true if OP is a valid operand for the BRAS instruction.
1392 OP is the current operation.
1393 MODE is the current operation mode. */
1396 bras_sym_operand (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1398 register enum rtx_code code = GET_CODE (op);
1400 /* Allow SYMBOL_REFs. */
1401 if (code == SYMBOL_REF)
1402 return 1;
1404 /* Allow @PLT stubs. */
1405 if (code == CONST
1406 && GET_CODE (XEXP (op, 0)) == UNSPEC
1407 && XINT (XEXP (op, 0), 1) == UNSPEC_PLT)
1408 return 1;
1409 return 0;
1412 /* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
1413 otherwise return 0. */
1416 tls_symbolic_operand (register rtx op)
1418 if (GET_CODE (op) != SYMBOL_REF)
1419 return 0;
1420 return SYMBOL_REF_TLS_MODEL (op);
1423 /* Return true if OP is a load multiple operation. It is known to be a
1424 PARALLEL and the first section will be tested.
1425 OP is the current operation.
1426 MODE is the current operation mode. */
1429 load_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1431 int count = XVECLEN (op, 0);
1432 unsigned int dest_regno;
1433 rtx src_addr;
1434 int i, off;
1437 /* Perform a quick check so we don't blow up below. */
1438 if (count <= 1
1439 || GET_CODE (XVECEXP (op, 0, 0)) != SET
1440 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
1441 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
1442 return 0;
1444 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
1445 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
1447 /* Check, is base, or base + displacement. */
1449 if (GET_CODE (src_addr) == REG)
1450 off = 0;
1451 else if (GET_CODE (src_addr) == PLUS
1452 && GET_CODE (XEXP (src_addr, 0)) == REG
1453 && GET_CODE (XEXP (src_addr, 1)) == CONST_INT)
1455 off = INTVAL (XEXP (src_addr, 1));
1456 src_addr = XEXP (src_addr, 0);
1458 else
1459 return 0;
1461 if (src_addr == frame_pointer_rtx || src_addr == arg_pointer_rtx)
1462 return 0;
1464 for (i = 1; i < count; i++)
1466 rtx elt = XVECEXP (op, 0, i);
1468 if (GET_CODE (elt) != SET
1469 || GET_CODE (SET_DEST (elt)) != REG
1470 || GET_MODE (SET_DEST (elt)) != Pmode
1471 || REGNO (SET_DEST (elt)) != dest_regno + i
1472 || GET_CODE (SET_SRC (elt)) != MEM
1473 || GET_MODE (SET_SRC (elt)) != Pmode
1474 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
1475 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
1476 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
1477 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1))
1478 != off + i * UNITS_PER_WORD)
1479 return 0;
1482 return 1;
1485 /* Return true if OP is a store multiple operation. It is known to be a
1486 PARALLEL and the first section will be tested.
1487 OP is the current operation.
1488 MODE is the current operation mode. */
1491 store_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1493 int count = XVECLEN (op, 0);
1494 unsigned int src_regno;
1495 rtx dest_addr;
1496 int i, off;
1498 /* Perform a quick check so we don't blow up below. */
1499 if (count <= 1
1500 || GET_CODE (XVECEXP (op, 0, 0)) != SET
1501 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
1502 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
1503 return 0;
1505 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
1506 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
1508 /* Check, is base, or base + displacement. */
1510 if (GET_CODE (dest_addr) == REG)
1511 off = 0;
1512 else if (GET_CODE (dest_addr) == PLUS
1513 && GET_CODE (XEXP (dest_addr, 0)) == REG
1514 && GET_CODE (XEXP (dest_addr, 1)) == CONST_INT)
1516 off = INTVAL (XEXP (dest_addr, 1));
1517 dest_addr = XEXP (dest_addr, 0);
1519 else
1520 return 0;
1522 if (dest_addr == frame_pointer_rtx || dest_addr == arg_pointer_rtx)
1523 return 0;
1525 for (i = 1; i < count; i++)
1527 rtx elt = XVECEXP (op, 0, i);
1529 if (GET_CODE (elt) != SET
1530 || GET_CODE (SET_SRC (elt)) != REG
1531 || GET_MODE (SET_SRC (elt)) != Pmode
1532 || REGNO (SET_SRC (elt)) != src_regno + i
1533 || GET_CODE (SET_DEST (elt)) != MEM
1534 || GET_MODE (SET_DEST (elt)) != Pmode
1535 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
1536 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
1537 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
1538 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1))
1539 != off + i * UNITS_PER_WORD)
1540 return 0;
1542 return 1;
1546 /* Return true if OP contains a symbol reference */
1549 symbolic_reference_mentioned_p (rtx op)
1551 register const char *fmt;
1552 register int i;
1554 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
1555 return 1;
1557 fmt = GET_RTX_FORMAT (GET_CODE (op));
1558 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
1560 if (fmt[i] == 'E')
1562 register int j;
1564 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
1565 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
1566 return 1;
1569 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
1570 return 1;
1573 return 0;
1576 /* Return true if OP contains a reference to a thread-local symbol. */
1579 tls_symbolic_reference_mentioned_p (rtx op)
1581 register const char *fmt;
1582 register int i;
1584 if (GET_CODE (op) == SYMBOL_REF)
1585 return tls_symbolic_operand (op);
1587 fmt = GET_RTX_FORMAT (GET_CODE (op));
1588 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
1590 if (fmt[i] == 'E')
1592 register int j;
1594 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
1595 if (tls_symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
1596 return 1;
1599 else if (fmt[i] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op, i)))
1600 return 1;
1603 return 0;
1607 /* Return true if OP is a legitimate general operand when
1608 generating PIC code. It is given that flag_pic is on
1609 and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
1612 legitimate_pic_operand_p (register rtx op)
1614 /* Accept all non-symbolic constants. */
1615 if (!SYMBOLIC_CONST (op))
1616 return 1;
1618 /* Reject everything else; must be handled
1619 via emit_symbolic_move. */
1620 return 0;
1623 /* Returns true if the constant value OP is a legitimate general operand.
1624 It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
1627 legitimate_constant_p (register rtx op)
1629 /* Accept all non-symbolic constants. */
1630 if (!SYMBOLIC_CONST (op))
1631 return 1;
1633 /* Accept immediate LARL operands. */
1634 if (TARGET_CPU_ZARCH && larl_operand (op, VOIDmode))
1635 return 1;
1637 /* Thread-local symbols are never legal constants. This is
1638 so that emit_call knows that computing such addresses
1639 might require a function call. */
1640 if (TLS_SYMBOLIC_CONST (op))
1641 return 0;
1643 /* In the PIC case, symbolic constants must *not* be
1644 forced into the literal pool. We accept them here,
1645 so that they will be handled by emit_symbolic_move. */
1646 if (flag_pic)
1647 return 1;
1649 /* All remaining non-PIC symbolic constants are
1650 forced into the literal pool. */
1651 return 0;
1654 /* Determine if it's legal to put X into the constant pool. This
1655 is not possible if X contains the address of a symbol that is
1656 not constant (TLS) or not known at final link time (PIC). */
1658 static bool
1659 s390_cannot_force_const_mem (rtx x)
1661 switch (GET_CODE (x))
1663 case CONST_INT:
1664 case CONST_DOUBLE:
1665 /* Accept all non-symbolic constants. */
1666 return false;
1668 case LABEL_REF:
1669 /* Labels are OK iff we are non-PIC. */
1670 return flag_pic != 0;
1672 case SYMBOL_REF:
1673 /* 'Naked' TLS symbol references are never OK,
1674 non-TLS symbols are OK iff we are non-PIC. */
1675 if (tls_symbolic_operand (x))
1676 return true;
1677 else
1678 return flag_pic != 0;
1680 case CONST:
1681 return s390_cannot_force_const_mem (XEXP (x, 0));
1682 case PLUS:
1683 case MINUS:
1684 return s390_cannot_force_const_mem (XEXP (x, 0))
1685 || s390_cannot_force_const_mem (XEXP (x, 1));
1687 case UNSPEC:
1688 switch (XINT (x, 1))
1690 /* Only lt-relative or GOT-relative UNSPECs are OK. */
1691 case UNSPEC_LTREL_OFFSET:
1692 case UNSPEC_GOT:
1693 case UNSPEC_GOTOFF:
1694 case UNSPEC_PLTOFF:
1695 case UNSPEC_TLSGD:
1696 case UNSPEC_TLSLDM:
1697 case UNSPEC_NTPOFF:
1698 case UNSPEC_DTPOFF:
1699 case UNSPEC_GOTNTPOFF:
1700 case UNSPEC_INDNTPOFF:
1701 return false;
1703 default:
1704 return true;
1706 break;
1708 default:
1709 abort ();
1713 /* Returns true if the constant value OP is a legitimate general
1714 operand during and after reload. The difference to
1715 legitimate_constant_p is that this function will not accept
1716 a constant that would need to be forced to the literal pool
1717 before it can be used as operand. */
1720 legitimate_reload_constant_p (register rtx op)
1722 /* Accept la(y) operands. */
1723 if (GET_CODE (op) == CONST_INT
1724 && DISP_IN_RANGE (INTVAL (op)))
1725 return 1;
1727 /* Accept l(g)hi operands. */
1728 if (GET_CODE (op) == CONST_INT
1729 && CONST_OK_FOR_LETTER_P (INTVAL (op), 'K'))
1730 return 1;
1732 /* Accept lliXX operands. */
1733 if (TARGET_ZARCH
1734 && s390_single_hi (op, DImode, 0) >= 0)
1735 return 1;
1737 /* Accept larl operands. */
1738 if (TARGET_CPU_ZARCH
1739 && larl_operand (op, VOIDmode))
1740 return 1;
1742 /* Everything else cannot be handled without reload. */
1743 return 0;
1746 /* Given an rtx OP being reloaded into a reg required to be in class CLASS,
1747 return the class of reg to actually use. */
1749 enum reg_class
1750 s390_preferred_reload_class (rtx op, enum reg_class class)
1752 /* This can happen if a floating point constant is being
1753 reloaded into an integer register. Leave well alone. */
1754 if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT
1755 && class != FP_REGS)
1756 return class;
1758 switch (GET_CODE (op))
1760 /* Constants we cannot reload must be forced into the
1761 literal pool. */
1763 case CONST_DOUBLE:
1764 case CONST_INT:
1765 if (legitimate_reload_constant_p (op))
1766 return class;
1767 else
1768 return NO_REGS;
1770 /* If a symbolic constant or a PLUS is reloaded,
1771 it is most likely being used as an address, so
1772 prefer ADDR_REGS. If 'class' is not a superset
1773 of ADDR_REGS, e.g. FP_REGS, reject this reload. */
1774 case PLUS:
1775 case LABEL_REF:
1776 case SYMBOL_REF:
1777 case CONST:
1778 if (reg_class_subset_p (ADDR_REGS, class))
1779 return ADDR_REGS;
1780 else
1781 return NO_REGS;
1783 default:
1784 break;
1787 return class;
1790 /* Return the register class of a scratch register needed to
1791 load IN into a register of class CLASS in MODE.
1793 We need a temporary when loading a PLUS expression which
1794 is not a legitimate operand of the LOAD ADDRESS instruction. */
1796 enum reg_class
1797 s390_secondary_input_reload_class (enum reg_class class ATTRIBUTE_UNUSED,
1798 enum machine_mode mode, rtx in)
1800 if (s390_plus_operand (in, mode))
1801 return ADDR_REGS;
1803 return NO_REGS;
1806 /* Return the register class of a scratch register needed to
1807 store a register of class CLASS in MODE into OUT:
1809 We need a temporary when storing a double-word to a
1810 non-offsettable memory address. */
1812 enum reg_class
1813 s390_secondary_output_reload_class (enum reg_class class,
1814 enum machine_mode mode, rtx out)
1816 if ((TARGET_64BIT ? mode == TImode
1817 : (mode == DImode || mode == DFmode))
1818 && reg_classes_intersect_p (GENERAL_REGS, class)
1819 && GET_CODE (out) == MEM
1820 && !offsettable_memref_p (out)
1821 && !s_operand (out, VOIDmode))
1822 return ADDR_REGS;
1824 return NO_REGS;
1827 /* Return true if OP is a PLUS that is not a legitimate
1828 operand for the LA instruction.
1829 OP is the current operation.
1830 MODE is the current operation mode. */
1833 s390_plus_operand (register rtx op, enum machine_mode mode)
1835 if (!check_mode (op, &mode) || mode != Pmode)
1836 return FALSE;
1838 if (GET_CODE (op) != PLUS)
1839 return FALSE;
1841 if (legitimate_la_operand_p (op))
1842 return FALSE;
1844 return TRUE;
1847 /* Generate code to load SRC, which is PLUS that is not a
1848 legitimate operand for the LA instruction, into TARGET.
1849 SCRATCH may be used as scratch register. */
1851 void
1852 s390_expand_plus_operand (register rtx target, register rtx src,
1853 register rtx scratch)
1855 rtx sum1, sum2;
1856 struct s390_address ad;
1858 /* src must be a PLUS; get its two operands. */
1859 if (GET_CODE (src) != PLUS || GET_MODE (src) != Pmode)
1860 abort ();
1862 /* Check if any of the two operands is already scheduled
1863 for replacement by reload. This can happen e.g. when
1864 float registers occur in an address. */
1865 sum1 = find_replacement (&XEXP (src, 0));
1866 sum2 = find_replacement (&XEXP (src, 1));
1867 src = gen_rtx_PLUS (Pmode, sum1, sum2);
1869 /* If the address is already strictly valid, there's nothing to do. */
1870 if (!s390_decompose_address (src, &ad)
1871 || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
1872 || (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
1874 /* Otherwise, one of the operands cannot be an address register;
1875 we reload its value into the scratch register. */
1876 if (true_regnum (sum1) < 1 || true_regnum (sum1) > 15)
1878 emit_move_insn (scratch, sum1);
1879 sum1 = scratch;
1881 if (true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
1883 emit_move_insn (scratch, sum2);
1884 sum2 = scratch;
1887 /* According to the way these invalid addresses are generated
1888 in reload.c, it should never happen (at least on s390) that
1889 *neither* of the PLUS components, after find_replacements
1890 was applied, is an address register. */
1891 if (sum1 == scratch && sum2 == scratch)
1893 debug_rtx (src);
1894 abort ();
1897 src = gen_rtx_PLUS (Pmode, sum1, sum2);
1900 /* Emit the LOAD ADDRESS pattern. Note that reload of PLUS
1901 is only ever performed on addresses, so we can mark the
1902 sum as legitimate for LA in any case. */
1903 s390_load_address (target, src);
1907 /* Decompose a RTL expression ADDR for a memory address into
1908 its components, returned in OUT.
1910 Returns 0 if ADDR is not a valid memory address, nonzero
1911 otherwise. If OUT is NULL, don't return the components,
1912 but check for validity only.
1914 Note: Only addresses in canonical form are recognized.
1915 LEGITIMIZE_ADDRESS should convert non-canonical forms to the
1916 canonical form so that they will be recognized. */
1918 static int
1919 s390_decompose_address (register rtx addr, struct s390_address *out)
1921 rtx base = NULL_RTX;
1922 rtx indx = NULL_RTX;
1923 rtx disp = NULL_RTX;
1924 int pointer = FALSE;
1925 int base_ptr = FALSE;
1926 int indx_ptr = FALSE;
1928 /* Decompose address into base + index + displacement. */
1930 if (GET_CODE (addr) == REG || GET_CODE (addr) == UNSPEC)
1931 base = addr;
1933 else if (GET_CODE (addr) == PLUS)
1935 rtx op0 = XEXP (addr, 0);
1936 rtx op1 = XEXP (addr, 1);
1937 enum rtx_code code0 = GET_CODE (op0);
1938 enum rtx_code code1 = GET_CODE (op1);
1940 if (code0 == REG || code0 == UNSPEC)
1942 if (code1 == REG || code1 == UNSPEC)
1944 indx = op0; /* index + base */
1945 base = op1;
1948 else
1950 base = op0; /* base + displacement */
1951 disp = op1;
1955 else if (code0 == PLUS)
1957 indx = XEXP (op0, 0); /* index + base + disp */
1958 base = XEXP (op0, 1);
1959 disp = op1;
1962 else
1964 return FALSE;
1968 else
1969 disp = addr; /* displacement */
1972 /* Validate base register. */
1973 if (base)
1975 if (GET_CODE (base) == UNSPEC)
1977 if (XVECLEN (base, 0) != 1 || XINT (base, 1) != UNSPEC_LTREL_BASE)
1978 return FALSE;
1979 base = gen_rtx_REG (Pmode, BASE_REGISTER);
1982 if (GET_CODE (base) != REG || GET_MODE (base) != Pmode)
1983 return FALSE;
1985 if (REGNO (base) == BASE_REGISTER
1986 || REGNO (base) == STACK_POINTER_REGNUM
1987 || REGNO (base) == FRAME_POINTER_REGNUM
1988 || ((reload_completed || reload_in_progress)
1989 && frame_pointer_needed
1990 && REGNO (base) == HARD_FRAME_POINTER_REGNUM)
1991 || REGNO (base) == ARG_POINTER_REGNUM
1992 || (REGNO (base) >= FIRST_VIRTUAL_REGISTER
1993 && REGNO (base) <= LAST_VIRTUAL_REGISTER)
1994 || (flag_pic
1995 && REGNO (base) == PIC_OFFSET_TABLE_REGNUM))
1996 pointer = base_ptr = TRUE;
1999 /* Validate index register. */
2000 if (indx)
2002 if (GET_CODE (indx) == UNSPEC)
2004 if (XVECLEN (indx, 0) != 1 || XINT (indx, 1) != UNSPEC_LTREL_BASE)
2005 return FALSE;
2006 indx = gen_rtx_REG (Pmode, BASE_REGISTER);
2009 if (GET_CODE (indx) != REG || GET_MODE (indx) != Pmode)
2010 return FALSE;
2012 if (REGNO (indx) == BASE_REGISTER
2013 || REGNO (indx) == STACK_POINTER_REGNUM
2014 || REGNO (indx) == FRAME_POINTER_REGNUM
2015 || ((reload_completed || reload_in_progress)
2016 && frame_pointer_needed
2017 && REGNO (indx) == HARD_FRAME_POINTER_REGNUM)
2018 || REGNO (indx) == ARG_POINTER_REGNUM
2019 || (REGNO (indx) >= FIRST_VIRTUAL_REGISTER
2020 && REGNO (indx) <= LAST_VIRTUAL_REGISTER)
2021 || (flag_pic
2022 && REGNO (indx) == PIC_OFFSET_TABLE_REGNUM))
2023 pointer = indx_ptr = TRUE;
2026 /* Prefer to use pointer as base, not index. */
2027 if (base && indx && !base_ptr
2028 && (indx_ptr || (!REG_POINTER (base) && REG_POINTER (indx))))
2030 rtx tmp = base;
2031 base = indx;
2032 indx = tmp;
2035 /* Validate displacement. */
2036 if (disp)
2038 /* Allow integer constant in range. */
2039 if (GET_CODE (disp) == CONST_INT)
2041 /* If the argument pointer is involved, the displacement will change
2042 later anyway as the argument pointer gets eliminated. This could
2043 make a valid displacement invalid, but it is more likely to make
2044 an invalid displacement valid, because we sometimes access the
2045 register save area via negative offsets to the arg pointer.
2046 Thus we don't check the displacement for validity here. If after
2047 elimination the displacement turns out to be invalid after all,
2048 this is fixed up by reload in any case. */
2049 if (base != arg_pointer_rtx && indx != arg_pointer_rtx)
2051 if (!DISP_IN_RANGE (INTVAL (disp)))
2052 return FALSE;
2056 /* In the small-PIC case, the linker converts @GOT
2057 and @GOTNTPOFF offsets to possible displacements. */
2058 else if (GET_CODE (disp) == CONST
2059 && GET_CODE (XEXP (disp, 0)) == UNSPEC
2060 && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOT
2061 || XINT (XEXP (disp, 0), 1) == UNSPEC_GOTNTPOFF))
2063 if (flag_pic != 1)
2064 return FALSE;
2066 pointer = TRUE;
2069 /* Accept chunkfied literal pool symbol references. */
2070 else if (GET_CODE (disp) == CONST
2071 && GET_CODE (XEXP (disp, 0)) == MINUS
2072 && GET_CODE (XEXP (XEXP (disp, 0), 0)) == LABEL_REF
2073 && GET_CODE (XEXP (XEXP (disp, 0), 1)) == LABEL_REF)
2075 pointer = TRUE;
2078 /* Likewise if a constant offset is present. */
2079 else if (GET_CODE (disp) == CONST
2080 && GET_CODE (XEXP (disp, 0)) == PLUS
2081 && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT
2082 && GET_CODE (XEXP (XEXP (disp, 0), 0)) == MINUS
2083 && GET_CODE (XEXP (XEXP (XEXP (disp, 0), 0), 0)) == LABEL_REF
2084 && GET_CODE (XEXP (XEXP (XEXP (disp, 0), 0), 1)) == LABEL_REF)
2086 pointer = TRUE;
2089 /* We can convert literal pool addresses to
2090 displacements by basing them off the base register. */
2091 else
2093 /* In some cases, we can accept an additional
2094 small constant offset. Split these off here. */
2096 unsigned int offset = 0;
2098 if (GET_CODE (disp) == CONST
2099 && GET_CODE (XEXP (disp, 0)) == PLUS
2100 && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT)
2102 offset = INTVAL (XEXP (XEXP (disp, 0), 1));
2103 disp = XEXP (XEXP (disp, 0), 0);
2106 /* Now we must have a literal pool address. */
2107 if (GET_CODE (disp) != SYMBOL_REF
2108 || !CONSTANT_POOL_ADDRESS_P (disp))
2109 return FALSE;
2111 /* If we have an offset, make sure it does not
2112 exceed the size of the constant pool entry. */
2113 if (offset && offset >= GET_MODE_SIZE (get_pool_mode (disp)))
2114 return FALSE;
2116 /* Either base or index must be free to
2117 hold the base register. */
2118 if (base && indx)
2119 return FALSE;
2121 /* Convert the address. */
2122 if (base)
2123 indx = gen_rtx_REG (Pmode, BASE_REGISTER);
2124 else
2125 base = gen_rtx_REG (Pmode, BASE_REGISTER);
2127 disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp),
2128 UNSPEC_LTREL_OFFSET);
2129 disp = gen_rtx_CONST (Pmode, disp);
2131 if (offset)
2132 disp = plus_constant (disp, offset);
2134 pointer = TRUE;
2138 if (!base && !indx)
2139 pointer = TRUE;
2141 if (out)
2143 out->base = base;
2144 out->indx = indx;
2145 out->disp = disp;
2146 out->pointer = pointer;
2149 return TRUE;
2152 /* Return nonzero if ADDR is a valid memory address.
2153 STRICT specifies whether strict register checking applies. */
2156 legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
2157 register rtx addr, int strict)
2159 struct s390_address ad;
2160 if (!s390_decompose_address (addr, &ad))
2161 return FALSE;
2163 if (strict)
2165 if (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
2166 return FALSE;
2167 if (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx))
2168 return FALSE;
2170 else
2172 if (ad.base && !REG_OK_FOR_BASE_NONSTRICT_P (ad.base))
2173 return FALSE;
2174 if (ad.indx && !REG_OK_FOR_INDEX_NONSTRICT_P (ad.indx))
2175 return FALSE;
2178 return TRUE;
2181 /* Return 1 if OP is a valid operand for the LA instruction.
2182 In 31-bit, we need to prove that the result is used as an
2183 address, as LA performs only a 31-bit addition. */
2186 legitimate_la_operand_p (register rtx op)
2188 struct s390_address addr;
2189 if (!s390_decompose_address (op, &addr))
2190 return FALSE;
2192 if (TARGET_64BIT || addr.pointer)
2193 return TRUE;
2195 return FALSE;
2198 /* Return 1 if OP is a valid operand for the LA instruction,
2199 and we prefer to use LA over addition to compute it. */
2202 preferred_la_operand_p (register rtx op)
2204 struct s390_address addr;
2205 if (!s390_decompose_address (op, &addr))
2206 return FALSE;
2208 if (!TARGET_64BIT && !addr.pointer)
2209 return FALSE;
2211 if (addr.pointer)
2212 return TRUE;
2214 if ((addr.base && REG_P (addr.base) && REG_POINTER (addr.base))
2215 || (addr.indx && REG_P (addr.indx) && REG_POINTER (addr.indx)))
2216 return TRUE;
2218 return FALSE;
2221 /* Emit a forced load-address operation to load SRC into DST.
2222 This will use the LOAD ADDRESS instruction even in situations
2223 where legitimate_la_operand_p (SRC) returns false. */
2225 void
2226 s390_load_address (rtx dst, rtx src)
2228 if (TARGET_64BIT)
2229 emit_move_insn (dst, src);
2230 else
2231 emit_insn (gen_force_la_31 (dst, src));
2234 /* Return a legitimate reference for ORIG (an address) using the
2235 register REG. If REG is 0, a new pseudo is generated.
2237 There are two types of references that must be handled:
2239 1. Global data references must load the address from the GOT, via
2240 the PIC reg. An insn is emitted to do this load, and the reg is
2241 returned.
2243 2. Static data references, constant pool addresses, and code labels
2244 compute the address as an offset from the GOT, whose base is in
2245 the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
2246 differentiate them from global data objects. The returned
2247 address is the PIC reg + an unspec constant.
2249 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2250 reg also appears in the address. */
2253 legitimize_pic_address (rtx orig, rtx reg)
2255 rtx addr = orig;
2256 rtx new = orig;
2257 rtx base;
2259 if (GET_CODE (addr) == LABEL_REF
2260 || (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (addr)))
2262 /* This is a local symbol. */
2263 if (TARGET_CPU_ZARCH && larl_operand (addr, VOIDmode))
2265 /* Access local symbols PC-relative via LARL.
2266 This is the same as in the non-PIC case, so it is
2267 handled automatically ... */
2269 else
2271 /* Access local symbols relative to the GOT. */
2273 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2275 if (reload_in_progress || reload_completed)
2276 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2278 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
2279 addr = gen_rtx_CONST (Pmode, addr);
2280 addr = force_const_mem (Pmode, addr);
2281 emit_move_insn (temp, addr);
2283 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2284 if (reg != 0)
2286 emit_move_insn (reg, new);
2287 new = reg;
2291 else if (GET_CODE (addr) == SYMBOL_REF)
2293 if (reg == 0)
2294 reg = gen_reg_rtx (Pmode);
2296 if (flag_pic == 1)
2298 /* Assume GOT offset < 4k. This is handled the same way
2299 in both 31- and 64-bit code (@GOT). */
2301 if (reload_in_progress || reload_completed)
2302 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2304 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
2305 new = gen_rtx_CONST (Pmode, new);
2306 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
2307 new = gen_rtx_MEM (Pmode, new);
2308 RTX_UNCHANGING_P (new) = 1;
2309 emit_move_insn (reg, new);
2310 new = reg;
2312 else if (TARGET_CPU_ZARCH)
2314 /* If the GOT offset might be >= 4k, we determine the position
2315 of the GOT entry via a PC-relative LARL (@GOTENT). */
2317 rtx temp = gen_reg_rtx (Pmode);
2319 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTENT);
2320 new = gen_rtx_CONST (Pmode, new);
2321 emit_move_insn (temp, new);
2323 new = gen_rtx_MEM (Pmode, temp);
2324 RTX_UNCHANGING_P (new) = 1;
2325 emit_move_insn (reg, new);
2326 new = reg;
2328 else
2330 /* If the GOT offset might be >= 4k, we have to load it
2331 from the literal pool (@GOT). */
2333 rtx temp = gen_reg_rtx (Pmode);
2335 if (reload_in_progress || reload_completed)
2336 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2338 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
2339 addr = gen_rtx_CONST (Pmode, addr);
2340 addr = force_const_mem (Pmode, addr);
2341 emit_move_insn (temp, addr);
2343 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2344 new = gen_rtx_MEM (Pmode, new);
2345 RTX_UNCHANGING_P (new) = 1;
2346 emit_move_insn (reg, new);
2347 new = reg;
2350 else
2352 if (GET_CODE (addr) == CONST)
2354 addr = XEXP (addr, 0);
2355 if (GET_CODE (addr) == UNSPEC)
2357 if (XVECLEN (addr, 0) != 1)
2358 abort ();
2359 switch (XINT (addr, 1))
2361 /* If someone moved a GOT-relative UNSPEC
2362 out of the literal pool, force them back in. */
2363 case UNSPEC_GOTOFF:
2364 case UNSPEC_PLTOFF:
2365 new = force_const_mem (Pmode, orig);
2366 break;
2368 /* @GOT is OK as is if small. */
2369 case UNSPEC_GOT:
2370 if (flag_pic == 2)
2371 new = force_const_mem (Pmode, orig);
2372 break;
2374 /* @GOTENT is OK as is. */
2375 case UNSPEC_GOTENT:
2376 break;
2378 /* @PLT is OK as is on 64-bit, must be converted to
2379 GOT-relative @PLTOFF on 31-bit. */
2380 case UNSPEC_PLT:
2381 if (!TARGET_CPU_ZARCH)
2383 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2385 if (reload_in_progress || reload_completed)
2386 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2388 addr = XVECEXP (addr, 0, 0);
2389 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
2390 UNSPEC_PLTOFF);
2391 addr = gen_rtx_CONST (Pmode, addr);
2392 addr = force_const_mem (Pmode, addr);
2393 emit_move_insn (temp, addr);
2395 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2396 if (reg != 0)
2398 emit_move_insn (reg, new);
2399 new = reg;
2402 break;
2404 /* Everything else cannot happen. */
2405 default:
2406 abort ();
2409 else if (GET_CODE (addr) != PLUS)
2410 abort ();
2412 if (GET_CODE (addr) == PLUS)
2414 rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
2415 /* Check first to see if this is a constant offset
2416 from a local symbol reference. */
2417 if ((GET_CODE (op0) == LABEL_REF
2418 || (GET_CODE (op0) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op0)))
2419 && GET_CODE (op1) == CONST_INT)
2421 if (TARGET_CPU_ZARCH && larl_operand (op0, VOIDmode))
2423 if (INTVAL (op1) & 1)
2425 /* LARL can't handle odd offsets, so emit a
2426 pair of LARL and LA. */
2427 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2429 if (!DISP_IN_RANGE (INTVAL (op1)))
2431 int even = INTVAL (op1) - 1;
2432 op0 = gen_rtx_PLUS (Pmode, op0, GEN_INT (even));
2433 op0 = gen_rtx_CONST (Pmode, op0);
2434 op1 = GEN_INT (1);
2437 emit_move_insn (temp, op0);
2438 new = gen_rtx_PLUS (Pmode, temp, op1);
2440 if (reg != 0)
2442 emit_move_insn (reg, new);
2443 new = reg;
2446 else
2448 /* If the offset is even, we can just use LARL.
2449 This will happen automatically. */
2452 else
2454 /* Access local symbols relative to the GOT. */
2456 rtx temp = reg? reg : gen_reg_rtx (Pmode);
2458 if (reload_in_progress || reload_completed)
2459 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2461 addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
2462 UNSPEC_GOTOFF);
2463 addr = gen_rtx_PLUS (Pmode, addr, op1);
2464 addr = gen_rtx_CONST (Pmode, addr);
2465 addr = force_const_mem (Pmode, addr);
2466 emit_move_insn (temp, addr);
2468 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2469 if (reg != 0)
2471 emit_move_insn (reg, new);
2472 new = reg;
2477 /* Now, check whether it is a GOT relative symbol plus offset
2478 that was pulled out of the literal pool. Force it back in. */
2480 else if (GET_CODE (op0) == UNSPEC
2481 && GET_CODE (op1) == CONST_INT)
2483 if (XVECLEN (op0, 0) != 1)
2484 abort ();
2485 if (XINT (op0, 1) != UNSPEC_GOTOFF)
2486 abort ();
2488 new = force_const_mem (Pmode, orig);
2491 /* Otherwise, compute the sum. */
2492 else
2494 base = legitimize_pic_address (XEXP (addr, 0), reg);
2495 new = legitimize_pic_address (XEXP (addr, 1),
2496 base == reg ? NULL_RTX : reg);
2497 if (GET_CODE (new) == CONST_INT)
2498 new = plus_constant (base, INTVAL (new));
2499 else
2501 if (GET_CODE (new) == PLUS && CONSTANT_P (XEXP (new, 1)))
2503 base = gen_rtx_PLUS (Pmode, base, XEXP (new, 0));
2504 new = XEXP (new, 1);
2506 new = gen_rtx_PLUS (Pmode, base, new);
2509 if (GET_CODE (new) == CONST)
2510 new = XEXP (new, 0);
2511 new = force_operand (new, 0);
2515 return new;
2518 /* Load the thread pointer into a register. */
2520 static rtx
2521 get_thread_pointer (void)
2523 rtx tp;
2525 tp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
2526 tp = force_reg (Pmode, tp);
2527 mark_reg_pointer (tp, BITS_PER_WORD);
2529 return tp;
2532 /* Construct the SYMBOL_REF for the tls_get_offset function. */
2534 static GTY(()) rtx s390_tls_symbol;
2536 s390_tls_get_offset (void)
2538 if (!s390_tls_symbol)
2539 s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset");
2541 return s390_tls_symbol;
2544 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
2545 this (thread-local) address. REG may be used as temporary. */
2547 static rtx
2548 legitimize_tls_address (rtx addr, rtx reg)
2550 rtx new, tls_call, temp, base, r2, insn;
2552 if (GET_CODE (addr) == SYMBOL_REF)
2553 switch (tls_symbolic_operand (addr))
2555 case TLS_MODEL_GLOBAL_DYNAMIC:
2556 start_sequence ();
2557 r2 = gen_rtx_REG (Pmode, 2);
2558 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLSGD);
2559 new = gen_rtx_CONST (Pmode, tls_call);
2560 new = force_const_mem (Pmode, new);
2561 emit_move_insn (r2, new);
2562 emit_call_insn (gen_call_value_tls (r2, tls_call));
2563 insn = get_insns ();
2564 end_sequence ();
2566 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
2567 temp = gen_reg_rtx (Pmode);
2568 emit_libcall_block (insn, temp, r2, new);
2570 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2571 if (reg != 0)
2573 s390_load_address (reg, new);
2574 new = reg;
2576 break;
2578 case TLS_MODEL_LOCAL_DYNAMIC:
2579 start_sequence ();
2580 r2 = gen_rtx_REG (Pmode, 2);
2581 tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM);
2582 new = gen_rtx_CONST (Pmode, tls_call);
2583 new = force_const_mem (Pmode, new);
2584 emit_move_insn (r2, new);
2585 emit_call_insn (gen_call_value_tls (r2, tls_call));
2586 insn = get_insns ();
2587 end_sequence ();
2589 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM_NTPOFF);
2590 temp = gen_reg_rtx (Pmode);
2591 emit_libcall_block (insn, temp, r2, new);
2593 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2594 base = gen_reg_rtx (Pmode);
2595 s390_load_address (base, new);
2597 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_DTPOFF);
2598 new = gen_rtx_CONST (Pmode, new);
2599 new = force_const_mem (Pmode, new);
2600 temp = gen_reg_rtx (Pmode);
2601 emit_move_insn (temp, new);
2603 new = gen_rtx_PLUS (Pmode, base, temp);
2604 if (reg != 0)
2606 s390_load_address (reg, new);
2607 new = reg;
2609 break;
2611 case TLS_MODEL_INITIAL_EXEC:
2612 if (flag_pic == 1)
2614 /* Assume GOT offset < 4k. This is handled the same way
2615 in both 31- and 64-bit code. */
2617 if (reload_in_progress || reload_completed)
2618 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2620 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
2621 new = gen_rtx_CONST (Pmode, new);
2622 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
2623 new = gen_rtx_MEM (Pmode, new);
2624 RTX_UNCHANGING_P (new) = 1;
2625 temp = gen_reg_rtx (Pmode);
2626 emit_move_insn (temp, new);
2628 else if (TARGET_CPU_ZARCH)
2630 /* If the GOT offset might be >= 4k, we determine the position
2631 of the GOT entry via a PC-relative LARL. */
2633 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
2634 new = gen_rtx_CONST (Pmode, new);
2635 temp = gen_reg_rtx (Pmode);
2636 emit_move_insn (temp, new);
2638 new = gen_rtx_MEM (Pmode, temp);
2639 RTX_UNCHANGING_P (new) = 1;
2640 temp = gen_reg_rtx (Pmode);
2641 emit_move_insn (temp, new);
2643 else if (flag_pic)
2645 /* If the GOT offset might be >= 4k, we have to load it
2646 from the literal pool. */
2648 if (reload_in_progress || reload_completed)
2649 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
2651 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
2652 new = gen_rtx_CONST (Pmode, new);
2653 new = force_const_mem (Pmode, new);
2654 temp = gen_reg_rtx (Pmode);
2655 emit_move_insn (temp, new);
2657 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
2658 new = gen_rtx_MEM (Pmode, new);
2659 RTX_UNCHANGING_P (new) = 1;
2661 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new, addr), UNSPEC_TLS_LOAD);
2662 temp = gen_reg_rtx (Pmode);
2663 emit_insn (gen_rtx_SET (Pmode, temp, new));
2665 else
2667 /* In position-dependent code, load the absolute address of
2668 the GOT entry from the literal pool. */
2670 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
2671 new = gen_rtx_CONST (Pmode, new);
2672 new = force_const_mem (Pmode, new);
2673 temp = gen_reg_rtx (Pmode);
2674 emit_move_insn (temp, new);
2676 new = temp;
2677 new = gen_rtx_MEM (Pmode, new);
2678 RTX_UNCHANGING_P (new) = 1;
2680 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new, addr), UNSPEC_TLS_LOAD);
2681 temp = gen_reg_rtx (Pmode);
2682 emit_insn (gen_rtx_SET (Pmode, temp, new));
2685 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2686 if (reg != 0)
2688 s390_load_address (reg, new);
2689 new = reg;
2691 break;
2693 case TLS_MODEL_LOCAL_EXEC:
2694 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
2695 new = gen_rtx_CONST (Pmode, new);
2696 new = force_const_mem (Pmode, new);
2697 temp = gen_reg_rtx (Pmode);
2698 emit_move_insn (temp, new);
2700 new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
2701 if (reg != 0)
2703 s390_load_address (reg, new);
2704 new = reg;
2706 break;
2708 default:
2709 abort ();
2712 else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == UNSPEC)
2714 switch (XINT (XEXP (addr, 0), 1))
2716 case UNSPEC_INDNTPOFF:
2717 if (TARGET_CPU_ZARCH)
2718 new = addr;
2719 else
2720 abort ();
2721 break;
2723 default:
2724 abort ();
2728 else
2729 abort (); /* for now ... */
2731 return new;
2734 /* Emit insns to move operands[1] into operands[0]. */
2736 void
2737 emit_symbolic_move (rtx *operands)
2739 rtx temp = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
2741 if (GET_CODE (operands[0]) == MEM)
2742 operands[1] = force_reg (Pmode, operands[1]);
2743 else if (TLS_SYMBOLIC_CONST (operands[1]))
2744 operands[1] = legitimize_tls_address (operands[1], temp);
2745 else if (flag_pic)
2746 operands[1] = legitimize_pic_address (operands[1], temp);
2749 /* Try machine-dependent ways of modifying an illegitimate address X
2750 to be legitimate. If we find one, return the new, valid address.
2752 OLDX is the address as it was before break_out_memory_refs was called.
2753 In some cases it is useful to look at this to decide what needs to be done.
2755 MODE is the mode of the operand pointed to by X.
2757 When -fpic is used, special handling is needed for symbolic references.
2758 See comments by legitimize_pic_address for details. */
2761 legitimize_address (register rtx x, register rtx oldx ATTRIBUTE_UNUSED,
2762 enum machine_mode mode ATTRIBUTE_UNUSED)
2764 rtx constant_term = const0_rtx;
2766 if (TLS_SYMBOLIC_CONST (x))
2768 x = legitimize_tls_address (x, 0);
2770 if (legitimate_address_p (mode, x, FALSE))
2771 return x;
2773 else if (flag_pic)
2775 if (SYMBOLIC_CONST (x)
2776 || (GET_CODE (x) == PLUS
2777 && (SYMBOLIC_CONST (XEXP (x, 0))
2778 || SYMBOLIC_CONST (XEXP (x, 1)))))
2779 x = legitimize_pic_address (x, 0);
2781 if (legitimate_address_p (mode, x, FALSE))
2782 return x;
2785 x = eliminate_constant_term (x, &constant_term);
2787 /* Optimize loading of large displacements by splitting them
2788 into the multiple of 4K and the rest; this allows the
2789 former to be CSE'd if possible.
2791 Don't do this if the displacement is added to a register
2792 pointing into the stack frame, as the offsets will
2793 change later anyway. */
2795 if (GET_CODE (constant_term) == CONST_INT
2796 && !TARGET_LONG_DISPLACEMENT
2797 && !DISP_IN_RANGE (INTVAL (constant_term))
2798 && !(REG_P (x) && REGNO_PTR_FRAME_P (REGNO (x))))
2800 HOST_WIDE_INT lower = INTVAL (constant_term) & 0xfff;
2801 HOST_WIDE_INT upper = INTVAL (constant_term) ^ lower;
2803 rtx temp = gen_reg_rtx (Pmode);
2804 rtx val = force_operand (GEN_INT (upper), temp);
2805 if (val != temp)
2806 emit_move_insn (temp, val);
2808 x = gen_rtx_PLUS (Pmode, x, temp);
2809 constant_term = GEN_INT (lower);
2812 if (GET_CODE (x) == PLUS)
2814 if (GET_CODE (XEXP (x, 0)) == REG)
2816 register rtx temp = gen_reg_rtx (Pmode);
2817 register rtx val = force_operand (XEXP (x, 1), temp);
2818 if (val != temp)
2819 emit_move_insn (temp, val);
2821 x = gen_rtx_PLUS (Pmode, XEXP (x, 0), temp);
2824 else if (GET_CODE (XEXP (x, 1)) == REG)
2826 register rtx temp = gen_reg_rtx (Pmode);
2827 register rtx val = force_operand (XEXP (x, 0), temp);
2828 if (val != temp)
2829 emit_move_insn (temp, val);
2831 x = gen_rtx_PLUS (Pmode, temp, XEXP (x, 1));
2835 if (constant_term != const0_rtx)
2836 x = gen_rtx_PLUS (Pmode, x, constant_term);
2838 return x;
2841 /* Emit code to move LEN bytes from DST to SRC. */
2843 void
2844 s390_expand_movstr (rtx dst, rtx src, rtx len)
2846 rtx (*gen_short) (rtx, rtx, rtx) =
2847 TARGET_64BIT ? gen_movstr_short_64 : gen_movstr_short_31;
2848 rtx (*gen_long) (rtx, rtx, rtx, rtx) =
2849 TARGET_64BIT ? gen_movstr_long_64 : gen_movstr_long_31;
2852 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
2854 if (INTVAL (len) > 0)
2855 emit_insn (gen_short (dst, src, GEN_INT (INTVAL (len) - 1)));
2858 else if (TARGET_MVCLE)
2860 enum machine_mode double_mode = TARGET_64BIT ? TImode : DImode;
2861 enum machine_mode single_mode = TARGET_64BIT ? DImode : SImode;
2862 rtx reg0 = gen_reg_rtx (double_mode);
2863 rtx reg1 = gen_reg_rtx (double_mode);
2865 emit_move_insn (gen_highpart (single_mode, reg0),
2866 force_operand (XEXP (dst, 0), NULL_RTX));
2867 emit_move_insn (gen_highpart (single_mode, reg1),
2868 force_operand (XEXP (src, 0), NULL_RTX));
2870 convert_move (gen_lowpart (single_mode, reg0), len, 1);
2871 convert_move (gen_lowpart (single_mode, reg1), len, 1);
2873 emit_insn (gen_long (reg0, reg1, reg0, reg1));
2876 else
2878 rtx dst_addr, src_addr, count, blocks, temp;
2879 rtx end_label = gen_label_rtx ();
2880 enum machine_mode mode;
2881 tree type;
2883 mode = GET_MODE (len);
2884 if (mode == VOIDmode)
2885 mode = word_mode;
2887 type = lang_hooks.types.type_for_mode (mode, 1);
2888 if (!type)
2889 abort ();
2891 dst_addr = gen_reg_rtx (Pmode);
2892 src_addr = gen_reg_rtx (Pmode);
2893 count = gen_reg_rtx (mode);
2894 blocks = gen_reg_rtx (mode);
2896 convert_move (count, len, 1);
2897 emit_cmp_and_jump_insns (count, const0_rtx,
2898 EQ, NULL_RTX, mode, 1, end_label);
2900 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
2901 emit_move_insn (src_addr, force_operand (XEXP (src, 0), NULL_RTX));
2902 dst = change_address (dst, VOIDmode, dst_addr);
2903 src = change_address (src, VOIDmode, src_addr);
2905 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
2906 if (temp != count)
2907 emit_move_insn (count, temp);
2909 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
2910 if (temp != blocks)
2911 emit_move_insn (blocks, temp);
2913 expand_start_loop (1);
2914 expand_exit_loop_top_cond (0, build (NE_EXPR, type,
2915 make_tree (type, blocks),
2916 make_tree (type, const0_rtx)));
2918 emit_insn (gen_short (dst, src, GEN_INT (255)));
2919 s390_load_address (dst_addr,
2920 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
2921 s390_load_address (src_addr,
2922 gen_rtx_PLUS (Pmode, src_addr, GEN_INT (256)));
2924 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
2925 if (temp != blocks)
2926 emit_move_insn (blocks, temp);
2928 expand_end_loop ();
2930 emit_insn (gen_short (dst, src, convert_to_mode (word_mode, count, 1)));
2931 emit_label (end_label);
2935 /* Emit code to clear LEN bytes at DST. */
2937 void
2938 s390_expand_clrstr (rtx dst, rtx len)
2940 rtx (*gen_short) (rtx, rtx) =
2941 TARGET_64BIT ? gen_clrstr_short_64 : gen_clrstr_short_31;
2942 rtx (*gen_long) (rtx, rtx, rtx) =
2943 TARGET_64BIT ? gen_clrstr_long_64 : gen_clrstr_long_31;
2946 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
2948 if (INTVAL (len) > 0)
2949 emit_insn (gen_short (dst, GEN_INT (INTVAL (len) - 1)));
2952 else if (TARGET_MVCLE)
2954 enum machine_mode double_mode = TARGET_64BIT ? TImode : DImode;
2955 enum machine_mode single_mode = TARGET_64BIT ? DImode : SImode;
2956 rtx reg0 = gen_reg_rtx (double_mode);
2957 rtx reg1 = gen_reg_rtx (double_mode);
2959 emit_move_insn (gen_highpart (single_mode, reg0),
2960 force_operand (XEXP (dst, 0), NULL_RTX));
2961 convert_move (gen_lowpart (single_mode, reg0), len, 1);
2963 emit_move_insn (gen_highpart (single_mode, reg1), const0_rtx);
2964 emit_move_insn (gen_lowpart (single_mode, reg1), const0_rtx);
2966 emit_insn (gen_long (reg0, reg1, reg0));
2969 else
2971 rtx dst_addr, src_addr, count, blocks, temp;
2972 rtx end_label = gen_label_rtx ();
2973 enum machine_mode mode;
2974 tree type;
2976 mode = GET_MODE (len);
2977 if (mode == VOIDmode)
2978 mode = word_mode;
2980 type = lang_hooks.types.type_for_mode (mode, 1);
2981 if (!type)
2982 abort ();
2984 dst_addr = gen_reg_rtx (Pmode);
2985 src_addr = gen_reg_rtx (Pmode);
2986 count = gen_reg_rtx (mode);
2987 blocks = gen_reg_rtx (mode);
2989 convert_move (count, len, 1);
2990 emit_cmp_and_jump_insns (count, const0_rtx,
2991 EQ, NULL_RTX, mode, 1, end_label);
2993 emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
2994 dst = change_address (dst, VOIDmode, dst_addr);
2996 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
2997 if (temp != count)
2998 emit_move_insn (count, temp);
3000 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
3001 if (temp != blocks)
3002 emit_move_insn (blocks, temp);
3004 expand_start_loop (1);
3005 expand_exit_loop_top_cond (0, build (NE_EXPR, type,
3006 make_tree (type, blocks),
3007 make_tree (type, const0_rtx)));
3009 emit_insn (gen_short (dst, GEN_INT (255)));
3010 s390_load_address (dst_addr,
3011 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
3013 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3014 if (temp != blocks)
3015 emit_move_insn (blocks, temp);
3017 expand_end_loop ();
3019 emit_insn (gen_short (dst, convert_to_mode (word_mode, count, 1)));
3020 emit_label (end_label);
3024 /* Emit code to compare LEN bytes at OP0 with those at OP1,
3025 and return the result in TARGET. */
3027 void
3028 s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
3030 rtx (*gen_short) (rtx, rtx, rtx) =
3031 TARGET_64BIT ? gen_cmpmem_short_64 : gen_cmpmem_short_31;
3032 rtx (*gen_long) (rtx, rtx, rtx, rtx) =
3033 TARGET_64BIT ? gen_cmpmem_long_64 : gen_cmpmem_long_31;
3034 rtx (*gen_result) (rtx) =
3035 GET_MODE (target) == DImode ? gen_cmpint_di : gen_cmpint_si;
3037 op0 = protect_from_queue (op0, 0);
3038 op1 = protect_from_queue (op1, 0);
3039 len = protect_from_queue (len, 0);
3041 if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
3043 if (INTVAL (len) > 0)
3045 emit_insn (gen_short (op0, op1, GEN_INT (INTVAL (len) - 1)));
3046 emit_insn (gen_result (target));
3048 else
3049 emit_move_insn (target, const0_rtx);
3052 else /* if (TARGET_MVCLE) */
3054 enum machine_mode double_mode = TARGET_64BIT ? TImode : DImode;
3055 enum machine_mode single_mode = TARGET_64BIT ? DImode : SImode;
3056 rtx reg0 = gen_reg_rtx (double_mode);
3057 rtx reg1 = gen_reg_rtx (double_mode);
3059 emit_move_insn (gen_highpart (single_mode, reg0),
3060 force_operand (XEXP (op0, 0), NULL_RTX));
3061 emit_move_insn (gen_highpart (single_mode, reg1),
3062 force_operand (XEXP (op1, 0), NULL_RTX));
3064 convert_move (gen_lowpart (single_mode, reg0), len, 1);
3065 convert_move (gen_lowpart (single_mode, reg1), len, 1);
3067 emit_insn (gen_long (reg0, reg1, reg0, reg1));
3068 emit_insn (gen_result (target));
3071 #if 0
3072 /* Deactivate for now as profile code cannot cope with
3073 CC being live across basic block boundaries. */
3074 else
3076 rtx addr0, addr1, count, blocks, temp;
3077 rtx end_label = gen_label_rtx ();
3078 enum machine_mode mode;
3079 tree type;
3081 mode = GET_MODE (len);
3082 if (mode == VOIDmode)
3083 mode = word_mode;
3085 type = lang_hooks.types.type_for_mode (mode, 1);
3086 if (!type)
3087 abort ();
3089 addr0 = gen_reg_rtx (Pmode);
3090 addr1 = gen_reg_rtx (Pmode);
3091 count = gen_reg_rtx (mode);
3092 blocks = gen_reg_rtx (mode);
3094 convert_move (count, len, 1);
3095 emit_cmp_and_jump_insns (count, const0_rtx,
3096 EQ, NULL_RTX, mode, 1, end_label);
3098 emit_move_insn (addr0, force_operand (XEXP (op0, 0), NULL_RTX));
3099 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
3100 op0 = change_address (op0, VOIDmode, addr0);
3101 op1 = change_address (op1, VOIDmode, addr1);
3103 temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
3104 if (temp != count)
3105 emit_move_insn (count, temp);
3107 temp = expand_binop (mode, ashr_optab, count, GEN_INT (8), blocks, 1, 0);
3108 if (temp != blocks)
3109 emit_move_insn (blocks, temp);
3111 expand_start_loop (1);
3112 expand_exit_loop_top_cond (0, build (NE_EXPR, type,
3113 make_tree (type, blocks),
3114 make_tree (type, const0_rtx)));
3116 emit_insn (gen_short (op0, op1, GEN_INT (255)));
3117 temp = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCSmode, 33), const0_rtx);
3118 temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
3119 gen_rtx_LABEL_REF (VOIDmode, end_label), pc_rtx);
3120 temp = gen_rtx_SET (VOIDmode, pc_rtx, temp);
3121 emit_jump_insn (temp);
3123 s390_load_address (addr0,
3124 gen_rtx_PLUS (Pmode, addr0, GEN_INT (256)));
3125 s390_load_address (addr1,
3126 gen_rtx_PLUS (Pmode, addr1, GEN_INT (256)));
3128 temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
3129 if (temp != blocks)
3130 emit_move_insn (blocks, temp);
3132 expand_end_loop ();
3134 emit_insn (gen_short (op0, op1, convert_to_mode (word_mode, count, 1)));
3135 emit_label (end_label);
3137 emit_insn (gen_result (target));
3139 #endif
3142 /* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
3143 We need to emit DTP-relative relocations. */
3145 void
3146 s390_output_dwarf_dtprel (FILE *file, int size, rtx x)
3148 switch (size)
3150 case 4:
3151 fputs ("\t.long\t", file);
3152 break;
3153 case 8:
3154 fputs ("\t.quad\t", file);
3155 break;
3156 default:
3157 abort ();
3159 output_addr_const (file, x);
3160 fputs ("@DTPOFF", file);
3163 /* In the name of slightly smaller debug output, and to cater to
3164 general assembler losage, recognize various UNSPEC sequences
3165 and turn them back into a direct symbol reference. */
3167 static rtx
3168 s390_delegitimize_address (rtx orig_x)
3170 rtx x = orig_x, y;
3172 if (GET_CODE (x) != MEM)
3173 return orig_x;
3175 x = XEXP (x, 0);
3176 if (GET_CODE (x) == PLUS
3177 && GET_CODE (XEXP (x, 1)) == CONST
3178 && GET_CODE (XEXP (x, 0)) == REG
3179 && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM)
3181 y = XEXP (XEXP (x, 1), 0);
3182 if (GET_CODE (y) == UNSPEC
3183 && XINT (y, 1) == UNSPEC_GOT)
3184 return XVECEXP (y, 0, 0);
3185 return orig_x;
3188 if (GET_CODE (x) == CONST)
3190 y = XEXP (x, 0);
3191 if (GET_CODE (y) == UNSPEC
3192 && XINT (y, 1) == UNSPEC_GOTENT)
3193 return XVECEXP (y, 0, 0);
3194 return orig_x;
3197 return orig_x;
3200 /* Locate some local-dynamic symbol still in use by this function
3201 so that we can print its name in local-dynamic base patterns. */
3203 static const char *
3204 get_some_local_dynamic_name (void)
3206 rtx insn;
3208 if (cfun->machine->some_ld_name)
3209 return cfun->machine->some_ld_name;
3211 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
3212 if (INSN_P (insn)
3213 && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
3214 return cfun->machine->some_ld_name;
3216 abort ();
3219 static int
3220 get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
3222 rtx x = *px;
3224 if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
3226 x = get_pool_constant (x);
3227 return for_each_rtx (&x, get_some_local_dynamic_name_1, 0);
3230 if (GET_CODE (x) == SYMBOL_REF
3231 && tls_symbolic_operand (x) == TLS_MODEL_LOCAL_DYNAMIC)
3233 cfun->machine->some_ld_name = XSTR (x, 0);
3234 return 1;
3237 return 0;
3240 /* Output symbolic constant X in assembler syntax to
3241 stdio stream FILE. */
3243 void
3244 s390_output_symbolic_const (FILE *file, rtx x)
3246 switch (GET_CODE (x))
3248 case CONST:
3249 case ZERO_EXTEND:
3250 case SIGN_EXTEND:
3251 s390_output_symbolic_const (file, XEXP (x, 0));
3252 break;
3254 case PLUS:
3255 s390_output_symbolic_const (file, XEXP (x, 0));
3256 fprintf (file, "+");
3257 s390_output_symbolic_const (file, XEXP (x, 1));
3258 break;
3260 case MINUS:
3261 s390_output_symbolic_const (file, XEXP (x, 0));
3262 fprintf (file, "-");
3263 s390_output_symbolic_const (file, XEXP (x, 1));
3264 break;
3266 case CONST_INT:
3267 case LABEL_REF:
3268 case CODE_LABEL:
3269 case SYMBOL_REF:
3270 output_addr_const (file, x);
3271 break;
3273 case UNSPEC:
3274 if (XVECLEN (x, 0) != 1)
3275 output_operand_lossage ("invalid UNSPEC as operand (1)");
3276 switch (XINT (x, 1))
3278 case UNSPEC_GOTENT:
3279 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3280 fprintf (file, "@GOTENT");
3281 break;
3282 case UNSPEC_GOT:
3283 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3284 fprintf (file, "@GOT");
3285 break;
3286 case UNSPEC_GOTOFF:
3287 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3288 fprintf (file, "@GOTOFF");
3289 break;
3290 case UNSPEC_PLT:
3291 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3292 fprintf (file, "@PLT");
3293 break;
3294 case UNSPEC_PLTOFF:
3295 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3296 fprintf (file, "@PLTOFF");
3297 break;
3298 case UNSPEC_TLSGD:
3299 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3300 fprintf (file, "@TLSGD");
3301 break;
3302 case UNSPEC_TLSLDM:
3303 assemble_name (file, get_some_local_dynamic_name ());
3304 fprintf (file, "@TLSLDM");
3305 break;
3306 case UNSPEC_DTPOFF:
3307 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3308 fprintf (file, "@DTPOFF");
3309 break;
3310 case UNSPEC_NTPOFF:
3311 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3312 fprintf (file, "@NTPOFF");
3313 break;
3314 case UNSPEC_GOTNTPOFF:
3315 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3316 fprintf (file, "@GOTNTPOFF");
3317 break;
3318 case UNSPEC_INDNTPOFF:
3319 s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
3320 fprintf (file, "@INDNTPOFF");
3321 break;
3322 default:
3323 output_operand_lossage ("invalid UNSPEC as operand (2)");
3324 break;
3326 break;
3328 default:
3329 fatal_insn ("UNKNOWN in s390_output_symbolic_const !?", x);
3330 break;
3334 /* Output address operand ADDR in assembler syntax to
3335 stdio stream FILE. */
3337 void
3338 print_operand_address (FILE *file, rtx addr)
3340 struct s390_address ad;
3342 if (!s390_decompose_address (addr, &ad)
3343 || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
3344 || (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
3345 output_operand_lossage ("Cannot decompose address.");
3347 if (ad.disp)
3348 s390_output_symbolic_const (file, ad.disp);
3349 else
3350 fprintf (file, "0");
3352 if (ad.base && ad.indx)
3353 fprintf (file, "(%s,%s)", reg_names[REGNO (ad.indx)],
3354 reg_names[REGNO (ad.base)]);
3355 else if (ad.base)
3356 fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
3359 /* Output operand X in assembler syntax to stdio stream FILE.
3360 CODE specified the format flag. The following format flags
3361 are recognized:
3363 'C': print opcode suffix for branch condition.
3364 'D': print opcode suffix for inverse branch condition.
3365 'J': print tls_load/tls_gdcall/tls_ldcall suffix
3366 'O': print only the displacement of a memory reference.
3367 'R': print only the base register of a memory reference.
3368 'N': print the second word of a DImode operand.
3369 'M': print the second word of a TImode operand.
3371 'b': print integer X as if it's an unsigned byte.
3372 'x': print integer X as if it's an unsigned word.
3373 'h': print integer X as if it's a signed word. */
3375 void
3376 print_operand (FILE *file, rtx x, int code)
3378 switch (code)
3380 case 'C':
3381 fprintf (file, s390_branch_condition_mnemonic (x, FALSE));
3382 return;
3384 case 'D':
3385 fprintf (file, s390_branch_condition_mnemonic (x, TRUE));
3386 return;
3388 case 'J':
3389 if (GET_CODE (x) == SYMBOL_REF)
3391 fprintf (file, "%s", ":tls_load:");
3392 output_addr_const (file, x);
3394 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD)
3396 fprintf (file, "%s", ":tls_gdcall:");
3397 output_addr_const (file, XVECEXP (x, 0, 0));
3399 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM)
3401 fprintf (file, "%s", ":tls_ldcall:");
3402 assemble_name (file, get_some_local_dynamic_name ());
3404 else
3405 abort ();
3406 return;
3408 case 'O':
3410 struct s390_address ad;
3412 if (GET_CODE (x) != MEM
3413 || !s390_decompose_address (XEXP (x, 0), &ad)
3414 || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
3415 || ad.indx)
3416 abort ();
3418 if (ad.disp)
3419 s390_output_symbolic_const (file, ad.disp);
3420 else
3421 fprintf (file, "0");
3423 return;
3425 case 'R':
3427 struct s390_address ad;
3429 if (GET_CODE (x) != MEM
3430 || !s390_decompose_address (XEXP (x, 0), &ad)
3431 || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
3432 || ad.indx)
3433 abort ();
3435 if (ad.base)
3436 fprintf (file, "%s", reg_names[REGNO (ad.base)]);
3437 else
3438 fprintf (file, "0");
3440 return;
3442 case 'N':
3443 if (GET_CODE (x) == REG)
3444 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
3445 else if (GET_CODE (x) == MEM)
3446 x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 4));
3447 else
3448 abort ();
3449 break;
3451 case 'M':
3452 if (GET_CODE (x) == REG)
3453 x = gen_rtx_REG (GET_MODE (x), REGNO (x) + 1);
3454 else if (GET_CODE (x) == MEM)
3455 x = change_address (x, VOIDmode, plus_constant (XEXP (x, 0), 8));
3456 else
3457 abort ();
3458 break;
3461 switch (GET_CODE (x))
3463 case REG:
3464 fprintf (file, "%s", reg_names[REGNO (x)]);
3465 break;
3467 case MEM:
3468 output_address (XEXP (x, 0));
3469 break;
3471 case CONST:
3472 case CODE_LABEL:
3473 case LABEL_REF:
3474 case SYMBOL_REF:
3475 s390_output_symbolic_const (file, x);
3476 break;
3478 case CONST_INT:
3479 if (code == 'b')
3480 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xff);
3481 else if (code == 'x')
3482 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffff);
3483 else if (code == 'h')
3484 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000);
3485 else
3486 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
3487 break;
3489 case CONST_DOUBLE:
3490 if (GET_MODE (x) != VOIDmode)
3491 abort ();
3492 if (code == 'b')
3493 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xff);
3494 else if (code == 'x')
3495 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x) & 0xffff);
3496 else if (code == 'h')
3497 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((CONST_DOUBLE_LOW (x) & 0xffff) ^ 0x8000) - 0x8000);
3498 else
3499 abort ();
3500 break;
3502 default:
3503 fatal_insn ("UNKNOWN in print_operand !?", x);
3504 break;
3508 /* Target hook for assembling integer objects. We need to define it
3509 here to work a round a bug in some versions of GAS, which couldn't
3510 handle values smaller than INT_MIN when printed in decimal. */
3512 static bool
3513 s390_assemble_integer (rtx x, unsigned int size, int aligned_p)
3515 if (size == 8 && aligned_p
3516 && GET_CODE (x) == CONST_INT && INTVAL (x) < INT_MIN)
3518 fprintf (asm_out_file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n",
3519 INTVAL (x));
3520 return true;
3522 return default_assemble_integer (x, size, aligned_p);
3525 /* Returns true if register REGNO is used for forming
3526 a memory address in expression X. */
3528 static int
3529 reg_used_in_mem_p (int regno, rtx x)
3531 enum rtx_code code = GET_CODE (x);
3532 int i, j;
3533 const char *fmt;
3535 if (code == MEM)
3537 if (refers_to_regno_p (regno, regno+1,
3538 XEXP (x, 0), 0))
3539 return 1;
3541 else if (code == SET
3542 && GET_CODE (SET_DEST (x)) == PC)
3544 if (refers_to_regno_p (regno, regno+1,
3545 SET_SRC (x), 0))
3546 return 1;
3549 fmt = GET_RTX_FORMAT (code);
3550 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3552 if (fmt[i] == 'e'
3553 && reg_used_in_mem_p (regno, XEXP (x, i)))
3554 return 1;
3556 else if (fmt[i] == 'E')
3557 for (j = 0; j < XVECLEN (x, i); j++)
3558 if (reg_used_in_mem_p (regno, XVECEXP (x, i, j)))
3559 return 1;
3561 return 0;
3564 /* Returns true if expression DEP_RTX sets an address register
3565 used by instruction INSN to address memory. */
3567 static int
3568 addr_generation_dependency_p (rtx dep_rtx, rtx insn)
3570 rtx target, pat;
3572 if (GET_CODE (dep_rtx) == INSN)
3573 dep_rtx = PATTERN (dep_rtx);
3575 if (GET_CODE (dep_rtx) == SET)
3577 target = SET_DEST (dep_rtx);
3578 if (GET_CODE (target) == STRICT_LOW_PART)
3579 target = XEXP (target, 0);
3580 while (GET_CODE (target) == SUBREG)
3581 target = SUBREG_REG (target);
3583 if (GET_CODE (target) == REG)
3585 int regno = REGNO (target);
3587 if (s390_safe_attr_type (insn) == TYPE_LA)
3589 pat = PATTERN (insn);
3590 if (GET_CODE (pat) == PARALLEL)
3592 if (XVECLEN (pat, 0) != 2)
3593 abort();
3594 pat = XVECEXP (pat, 0, 0);
3596 if (GET_CODE (pat) == SET)
3597 return refers_to_regno_p (regno, regno+1, SET_SRC (pat), 0);
3598 else
3599 abort();
3601 else if (get_attr_atype (insn) == ATYPE_AGEN)
3602 return reg_used_in_mem_p (regno, PATTERN (insn));
3605 return 0;
3608 /* Return 1, if dep_insn sets register used in insn in the agen unit. */
3611 s390_agen_dep_p (rtx dep_insn, rtx insn)
3613 rtx dep_rtx = PATTERN (dep_insn);
3614 int i;
3616 if (GET_CODE (dep_rtx) == SET
3617 && addr_generation_dependency_p (dep_rtx, insn))
3618 return 1;
3619 else if (GET_CODE (dep_rtx) == PARALLEL)
3621 for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
3623 if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i), insn))
3624 return 1;
3627 return 0;
3630 /* Return the modified cost of the dependency of instruction INSN
3631 on instruction DEP_INSN through the link LINK. COST is the
3632 default cost of that dependency.
3634 Data dependencies are all handled without delay. However, if a
3635 register is modified and subsequently used as base or index
3636 register of a memory reference, at least 4 cycles need to pass
3637 between setting and using the register to avoid pipeline stalls.
3638 An exception is the LA instruction. An address generated by LA can
3639 be used by introducing only a one cycle stall on the pipeline. */
3641 static int
3642 s390_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
3644 rtx dep_rtx;
3645 int i;
3647 /* If the dependence is an anti-dependence, there is no cost. For an
3648 output dependence, there is sometimes a cost, but it doesn't seem
3649 worth handling those few cases. */
3651 if (REG_NOTE_KIND (link) != 0)
3652 return 0;
3654 /* If we can't recognize the insns, we can't really do anything. */
3655 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
3656 return cost;
3658 /* DFA based scheduling checks address dependency in md file. */
3659 if (s390_use_dfa_pipeline_interface ())
3661 /* Operand forward in case of lr, load and la. */
3662 if (s390_tune == PROCESSOR_2084_Z990
3663 && cost == 1
3664 && (s390_safe_attr_type (dep_insn) == TYPE_LA
3665 || s390_safe_attr_type (dep_insn) == TYPE_LR
3666 || s390_safe_attr_type (dep_insn) == TYPE_LOAD))
3667 return 0;
3668 return cost;
3671 dep_rtx = PATTERN (dep_insn);
3673 if (GET_CODE (dep_rtx) == SET
3674 && addr_generation_dependency_p (dep_rtx, insn))
3675 cost += (s390_safe_attr_type (dep_insn) == TYPE_LA) ? 1 : 4;
3676 else if (GET_CODE (dep_rtx) == PARALLEL)
3678 for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
3680 if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i), insn))
3681 cost += (s390_safe_attr_type (dep_insn) == TYPE_LA) ? 1 : 4;
3685 return cost;
3687 /* A C statement (sans semicolon) to update the integer scheduling priority
3688 INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
3689 reduce the priority to execute INSN later. Do not define this macro if
3690 you do not need to adjust the scheduling priorities of insns.
3692 A STD instruction should be scheduled earlier,
3693 in order to use the bypass. */
3695 static int
3696 s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
3698 if (! INSN_P (insn))
3699 return priority;
3701 if (s390_tune != PROCESSOR_2084_Z990)
3702 return priority;
3704 switch (s390_safe_attr_type (insn))
3706 case TYPE_FSTORED:
3707 case TYPE_FSTORES:
3708 priority = priority << 3;
3709 break;
3710 case TYPE_STORE:
3711 priority = priority << 1;
3712 break;
3713 default:
3714 break;
3716 return priority;
3719 /* The number of instructions that can be issued per cycle. */
3721 static int
3722 s390_issue_rate (void)
3724 if (s390_tune == PROCESSOR_2084_Z990)
3725 return 3;
3726 return 1;
3729 /* If the following function returns TRUE, we will use the the DFA
3730 insn scheduler. */
3732 static int
3733 s390_use_dfa_pipeline_interface (void)
3735 if (s390_tune == PROCESSOR_2064_Z900
3736 || s390_tune == PROCESSOR_2084_Z990)
3737 return 1;
3739 return 0;
3742 static int
3743 s390_first_cycle_multipass_dfa_lookahead (void)
3745 return s390_use_dfa_pipeline_interface () ? 4 : 0;
3748 /* Called after issuing each insn.
3749 Triggers default sort algorithm to better slot instructions. */
3751 static int
3752 s390_sched_reorder2 (FILE *dump ATTRIBUTE_UNUSED,
3753 int sched_verbose ATTRIBUTE_UNUSED,
3754 rtx *ready ATTRIBUTE_UNUSED,
3755 int *pn_ready ATTRIBUTE_UNUSED,
3756 int clock_var ATTRIBUTE_UNUSED)
3758 return s390_issue_rate();
3762 /* Split all branches that exceed the maximum distance.
3763 Returns true if this created a new literal pool entry.
3765 Code generated by this routine is allowed to use
3766 TEMP_REG as temporary scratch register. If this is
3767 done, TEMP_USED is set to true. */
3769 static int
3770 s390_split_branches (rtx temp_reg, bool *temp_used)
3772 int new_literal = 0;
3773 rtx insn, pat, tmp, target;
3774 rtx *label;
3776 /* We need correct insn addresses. */
3778 shorten_branches (get_insns ());
3780 /* Find all branches that exceed 64KB, and split them. */
3782 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
3784 if (GET_CODE (insn) != JUMP_INSN)
3785 continue;
3787 pat = PATTERN (insn);
3788 if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
3789 pat = XVECEXP (pat, 0, 0);
3790 if (GET_CODE (pat) != SET || SET_DEST (pat) != pc_rtx)
3791 continue;
3793 if (GET_CODE (SET_SRC (pat)) == LABEL_REF)
3795 label = &SET_SRC (pat);
3797 else if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE)
3799 if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF)
3800 label = &XEXP (SET_SRC (pat), 1);
3801 else if (GET_CODE (XEXP (SET_SRC (pat), 2)) == LABEL_REF)
3802 label = &XEXP (SET_SRC (pat), 2);
3803 else
3804 continue;
3806 else
3807 continue;
3809 if (get_attr_length (insn) <= (TARGET_CPU_ZARCH ? 6 : 4))
3810 continue;
3812 *temp_used = 1;
3814 if (TARGET_CPU_ZARCH)
3816 tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, *label), insn);
3817 INSN_ADDRESSES_NEW (tmp, -1);
3819 target = temp_reg;
3821 else if (!flag_pic)
3823 new_literal = 1;
3824 tmp = force_const_mem (Pmode, *label);
3825 tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, tmp), insn);
3826 INSN_ADDRESSES_NEW (tmp, -1);
3828 target = temp_reg;
3830 else
3832 new_literal = 1;
3833 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, *label),
3834 UNSPEC_LTREL_OFFSET);
3835 target = gen_rtx_CONST (Pmode, target);
3836 target = force_const_mem (Pmode, target);
3837 tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, target), insn);
3838 INSN_ADDRESSES_NEW (tmp, -1);
3840 target = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (target, 0)),
3841 UNSPEC_LTREL_BASE);
3842 target = gen_rtx_PLUS (Pmode, temp_reg, target);
3845 if (!validate_change (insn, label, target, 0))
3846 abort ();
3849 return new_literal;
3853 /* Find a literal pool symbol referenced in RTX X, and store
3854 it at REF. Will abort if X contains references to more than
3855 one such pool symbol; multiple references to the same symbol
3856 are allowed, however.
3858 The rtx pointed to by REF must be initialized to NULL_RTX
3859 by the caller before calling this routine. */
3861 static void
3862 find_constant_pool_ref (rtx x, rtx *ref)
3864 int i, j;
3865 const char *fmt;
3867 /* Ignore LTREL_BASE references. */
3868 if (GET_CODE (x) == UNSPEC
3869 && XINT (x, 1) == UNSPEC_LTREL_BASE)
3870 return;
3871 /* Likewise POOL_ENTRY insns. */
3872 if (GET_CODE (x) == UNSPEC_VOLATILE
3873 && XINT (x, 1) == UNSPECV_POOL_ENTRY)
3874 return;
3876 if (GET_CODE (x) == SYMBOL_REF
3877 && CONSTANT_POOL_ADDRESS_P (x))
3879 if (*ref == NULL_RTX)
3880 *ref = x;
3881 else if (*ref != x)
3882 abort();
3885 fmt = GET_RTX_FORMAT (GET_CODE (x));
3886 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
3888 if (fmt[i] == 'e')
3890 find_constant_pool_ref (XEXP (x, i), ref);
3892 else if (fmt[i] == 'E')
3894 for (j = 0; j < XVECLEN (x, i); j++)
3895 find_constant_pool_ref (XVECEXP (x, i, j), ref);
3900 /* Replace every reference to the literal pool symbol REF
3901 in X by the address ADDR. Fix up MEMs as required. */
3903 static void
3904 replace_constant_pool_ref (rtx *x, rtx ref, rtx addr)
3906 int i, j;
3907 const char *fmt;
3909 if (*x == ref)
3910 abort ();
3912 /* Literal pool references can only occur inside a MEM ... */
3913 if (GET_CODE (*x) == MEM)
3915 rtx memref = XEXP (*x, 0);
3917 if (memref == ref)
3919 *x = replace_equiv_address (*x, addr);
3920 return;
3923 if (GET_CODE (memref) == CONST
3924 && GET_CODE (XEXP (memref, 0)) == PLUS
3925 && GET_CODE (XEXP (XEXP (memref, 0), 1)) == CONST_INT
3926 && XEXP (XEXP (memref, 0), 0) == ref)
3928 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (memref, 0), 1));
3929 *x = replace_equiv_address (*x, plus_constant (addr, off));
3930 return;
3934 /* ... or a load-address type pattern. */
3935 if (GET_CODE (*x) == SET)
3937 rtx addrref = SET_SRC (*x);
3939 if (addrref == ref)
3941 SET_SRC (*x) = addr;
3942 return;
3945 if (GET_CODE (addrref) == CONST
3946 && GET_CODE (XEXP (addrref, 0)) == PLUS
3947 && GET_CODE (XEXP (XEXP (addrref, 0), 1)) == CONST_INT
3948 && XEXP (XEXP (addrref, 0), 0) == ref)
3950 HOST_WIDE_INT off = INTVAL (XEXP (XEXP (addrref, 0), 1));
3951 SET_SRC (*x) = plus_constant (addr, off);
3952 return;
3956 fmt = GET_RTX_FORMAT (GET_CODE (*x));
3957 for (i = GET_RTX_LENGTH (GET_CODE (*x)) - 1; i >= 0; i--)
3959 if (fmt[i] == 'e')
3961 replace_constant_pool_ref (&XEXP (*x, i), ref, addr);
3963 else if (fmt[i] == 'E')
3965 for (j = 0; j < XVECLEN (*x, i); j++)
3966 replace_constant_pool_ref (&XVECEXP (*x, i, j), ref, addr);
3971 /* Check whether X contains an UNSPEC_LTREL_BASE.
3972 Return its constant pool symbol if found, NULL_RTX otherwise. */
3974 static rtx
3975 find_ltrel_base (rtx x)
3977 int i, j;
3978 const char *fmt;
3980 if (GET_CODE (x) == UNSPEC
3981 && XINT (x, 1) == UNSPEC_LTREL_BASE)
3982 return XVECEXP (x, 0, 0);
3984 fmt = GET_RTX_FORMAT (GET_CODE (x));
3985 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
3987 if (fmt[i] == 'e')
3989 rtx fnd = find_ltrel_base (XEXP (x, i));
3990 if (fnd)
3991 return fnd;
3993 else if (fmt[i] == 'E')
3995 for (j = 0; j < XVECLEN (x, i); j++)
3997 rtx fnd = find_ltrel_base (XVECEXP (x, i, j));
3998 if (fnd)
3999 return fnd;
4004 return NULL_RTX;
4007 /* Replace any occurrence of UNSPEC_LTREL_BASE in X with BASE. */
4009 static void
4010 replace_ltrel_base (rtx *x, rtx base)
4012 int i, j;
4013 const char *fmt;
4015 if (GET_CODE (*x) == UNSPEC
4016 && XINT (*x, 1) == UNSPEC_LTREL_BASE)
4018 *x = base;
4019 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_ltrel_base (&XEXP (*x, i), base);
4029 else if (fmt[i] == 'E')
4031 for (j = 0; j < XVECLEN (*x, i); j++)
4032 replace_ltrel_base (&XVECEXP (*x, i, j), base);
4038 /* We keep a list of constants which we have to add to internal
4039 constant tables in the middle of large functions. */
4041 #define NR_C_MODES 7
4042 enum machine_mode constant_modes[NR_C_MODES] =
4044 TImode,
4045 DFmode, DImode,
4046 SFmode, SImode,
4047 HImode,
4048 QImode
4051 struct constant
4053 struct constant *next;
4054 rtx value;
4055 rtx label;
4058 struct constant_pool
4060 struct constant_pool *next;
4061 rtx first_insn;
4062 rtx pool_insn;
4063 bitmap insns;
4065 struct constant *constants[NR_C_MODES];
4066 rtx label;
4067 int size;
4070 static struct constant_pool * s390_mainpool_start (void);
4071 static void s390_mainpool_finish (struct constant_pool *, rtx base_reg);
4072 static void s390_mainpool_cancel (struct constant_pool *);
4074 static struct constant_pool * s390_chunkify_start (rtx base_reg);
4075 static void s390_chunkify_finish (struct constant_pool *, rtx base_reg);
4076 static void s390_chunkify_cancel (struct constant_pool *);
4078 static struct constant_pool *s390_start_pool (struct constant_pool **, rtx);
4079 static void s390_end_pool (struct constant_pool *, rtx);
4080 static void s390_add_pool_insn (struct constant_pool *, rtx);
4081 static struct constant_pool *s390_find_pool (struct constant_pool *, rtx);
4082 static void s390_add_constant (struct constant_pool *, rtx, enum machine_mode);
4083 static rtx s390_find_constant (struct constant_pool *, rtx, enum machine_mode);
4084 static rtx s390_dump_pool (struct constant_pool *, bool);
4085 static struct constant_pool *s390_alloc_pool (void);
4086 static void s390_free_pool (struct constant_pool *);
4088 /* Create new constant pool covering instructions starting at INSN
4089 and chain it to the end of POOL_LIST. */
4091 static struct constant_pool *
4092 s390_start_pool (struct constant_pool **pool_list, rtx insn)
4094 struct constant_pool *pool, **prev;
4096 pool = s390_alloc_pool ();
4097 pool->first_insn = insn;
4099 for (prev = pool_list; *prev; prev = &(*prev)->next)
4101 *prev = pool;
4103 return pool;
4106 /* End range of instructions covered by POOL at INSN and emit
4107 placeholder insn representing the pool. */
4109 static void
4110 s390_end_pool (struct constant_pool *pool, rtx insn)
4112 rtx pool_size = GEN_INT (pool->size + 8 /* alignment slop */);
4114 if (!insn)
4115 insn = get_last_insn ();
4117 pool->pool_insn = emit_insn_after (gen_pool (pool_size), insn);
4118 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
4121 /* Add INSN to the list of insns covered by POOL. */
4123 static void
4124 s390_add_pool_insn (struct constant_pool *pool, rtx insn)
4126 bitmap_set_bit (pool->insns, INSN_UID (insn));
4129 /* Return pool out of POOL_LIST that covers INSN. */
4131 static struct constant_pool *
4132 s390_find_pool (struct constant_pool *pool_list, rtx insn)
4134 struct constant_pool *pool;
4136 for (pool = pool_list; pool; pool = pool->next)
4137 if (bitmap_bit_p (pool->insns, INSN_UID (insn)))
4138 break;
4140 return pool;
4143 /* Add constant VAL of mode MODE to the constant pool POOL. */
4145 static void
4146 s390_add_constant (struct constant_pool *pool, rtx val, enum machine_mode mode)
4148 struct constant *c;
4149 int i;
4151 for (i = 0; i < NR_C_MODES; i++)
4152 if (constant_modes[i] == mode)
4153 break;
4154 if (i == NR_C_MODES)
4155 abort ();
4157 for (c = pool->constants[i]; c != NULL; c = c->next)
4158 if (rtx_equal_p (val, c->value))
4159 break;
4161 if (c == NULL)
4163 c = (struct constant *) xmalloc (sizeof *c);
4164 c->value = val;
4165 c->label = gen_label_rtx ();
4166 c->next = pool->constants[i];
4167 pool->constants[i] = c;
4168 pool->size += GET_MODE_SIZE (mode);
4172 /* Find constant VAL of mode MODE in the constant pool POOL.
4173 Return an RTX describing the distance from the start of
4174 the pool to the location of the new constant. */
4176 static rtx
4177 s390_find_constant (struct constant_pool *pool, rtx val,
4178 enum machine_mode mode)
4180 struct constant *c;
4181 rtx offset;
4182 int i;
4184 for (i = 0; i < NR_C_MODES; i++)
4185 if (constant_modes[i] == mode)
4186 break;
4187 if (i == NR_C_MODES)
4188 abort ();
4190 for (c = pool->constants[i]; c != NULL; c = c->next)
4191 if (rtx_equal_p (val, c->value))
4192 break;
4194 if (c == NULL)
4195 abort ();
4197 offset = gen_rtx_MINUS (Pmode, gen_rtx_LABEL_REF (Pmode, c->label),
4198 gen_rtx_LABEL_REF (Pmode, pool->label));
4199 offset = gen_rtx_CONST (Pmode, offset);
4200 return offset;
4203 /* Dump out the constants in POOL. If REMOTE_LABEL is true,
4204 do not emit the pool base label. */
4206 static rtx
4207 s390_dump_pool (struct constant_pool *pool, bool remote_label)
4209 struct constant *c;
4210 rtx insn;
4211 int i;
4213 /* Pool start insn switches to proper section
4214 and guarantees necessary alignment. */
4215 if (TARGET_CPU_ZARCH)
4216 insn = emit_insn_after (gen_pool_start_64 (), pool->pool_insn);
4217 else
4218 insn = emit_insn_after (gen_pool_start_31 (), pool->pool_insn);
4219 INSN_ADDRESSES_NEW (insn, -1);
4221 if (!remote_label)
4223 insn = emit_label_after (pool->label, insn);
4224 INSN_ADDRESSES_NEW (insn, -1);
4227 /* Dump constants in descending alignment requirement order,
4228 ensuring proper alignment for every constant. */
4229 for (i = 0; i < NR_C_MODES; i++)
4230 for (c = pool->constants[i]; c; c = c->next)
4232 /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
4233 rtx value = c->value;
4234 if (GET_CODE (value) == CONST
4235 && GET_CODE (XEXP (value, 0)) == UNSPEC
4236 && XINT (XEXP (value, 0), 1) == UNSPEC_LTREL_OFFSET
4237 && XVECLEN (XEXP (value, 0), 0) == 1)
4239 value = gen_rtx_MINUS (Pmode, XVECEXP (XEXP (value, 0), 0, 0),
4240 gen_rtx_LABEL_REF (VOIDmode, pool->label));
4241 value = gen_rtx_CONST (VOIDmode, value);
4244 insn = emit_label_after (c->label, insn);
4245 INSN_ADDRESSES_NEW (insn, -1);
4247 value = gen_rtx_UNSPEC_VOLATILE (constant_modes[i],
4248 gen_rtvec (1, value),
4249 UNSPECV_POOL_ENTRY);
4250 insn = emit_insn_after (value, insn);
4251 INSN_ADDRESSES_NEW (insn, -1);
4254 /* Pool end insn switches back to previous section
4255 and guarantees necessary alignment. */
4256 if (TARGET_CPU_ZARCH)
4257 insn = emit_insn_after (gen_pool_end_64 (), insn);
4258 else
4259 insn = emit_insn_after (gen_pool_end_31 (), insn);
4260 INSN_ADDRESSES_NEW (insn, -1);
4262 insn = emit_barrier_after (insn);
4263 INSN_ADDRESSES_NEW (insn, -1);
4265 /* Remove placeholder insn. */
4266 remove_insn (pool->pool_insn);
4268 return insn;
4271 /* Allocate new constant_pool structure. */
4273 static struct constant_pool *
4274 s390_alloc_pool (void)
4276 struct constant_pool *pool;
4277 int i;
4279 pool = (struct constant_pool *) xmalloc (sizeof *pool);
4280 pool->next = NULL;
4281 for (i = 0; i < NR_C_MODES; i++)
4282 pool->constants[i] = NULL;
4284 pool->label = gen_label_rtx ();
4285 pool->first_insn = NULL_RTX;
4286 pool->pool_insn = NULL_RTX;
4287 pool->insns = BITMAP_XMALLOC ();
4288 pool->size = 0;
4290 return pool;
4293 /* Free all memory used by POOL. */
4295 static void
4296 s390_free_pool (struct constant_pool *pool)
4298 int i;
4300 for (i = 0; i < NR_C_MODES; i++)
4302 struct constant *c = pool->constants[i];
4303 while (c != NULL)
4305 struct constant *next = c->next;
4306 free (c);
4307 c = next;
4311 BITMAP_XFREE (pool->insns);
4312 free (pool);
4316 /* Collect main literal pool. Return NULL on overflow. */
4318 static struct constant_pool *
4319 s390_mainpool_start (void)
4321 struct constant_pool *pool;
4322 rtx insn;
4324 pool = s390_alloc_pool ();
4326 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4328 if (GET_CODE (insn) == INSN
4329 && GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
4330 && XINT (PATTERN (insn), 1) == UNSPECV_MAIN_POOL)
4332 if (pool->pool_insn)
4333 abort ();
4334 pool->pool_insn = insn;
4337 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
4339 rtx pool_ref = NULL_RTX;
4340 find_constant_pool_ref (PATTERN (insn), &pool_ref);
4341 if (pool_ref)
4343 rtx constant = get_pool_constant (pool_ref);
4344 enum machine_mode mode = get_pool_mode (pool_ref);
4345 s390_add_constant (pool, constant, mode);
4350 if (!pool->pool_insn)
4351 abort ();
4353 if (pool->size >= 4096)
4355 s390_free_pool (pool);
4356 pool = NULL;
4359 return pool;
4362 /* POOL holds the main literal pool as collected by s390_mainpool_start.
4363 Modify the current function to output the pool constants as well as
4364 the pool register setup instruction. BASE_REG is the register to
4365 be used as pool base register. */
4367 static void
4368 s390_mainpool_finish (struct constant_pool *pool, rtx base_reg)
4370 rtx insn;
4372 /* If the pool is empty, we're done. */
4373 if (pool->size == 0)
4375 remove_insn (pool->pool_insn);
4376 s390_free_pool (pool);
4377 return;
4380 /* We need correct insn addresses. */
4381 shorten_branches (get_insns ());
4383 /* On zSeries, we use a LARL to load the pool register. The pool is
4384 located in the .rodata section, so we emit it after the function. */
4385 if (TARGET_CPU_ZARCH)
4387 insn = gen_main_base_64 (base_reg, pool->label);
4388 insn = emit_insn_after (insn, pool->pool_insn);
4389 INSN_ADDRESSES_NEW (insn, -1);
4390 remove_insn (pool->pool_insn);
4392 insn = get_last_insn ();
4393 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
4394 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
4396 s390_dump_pool (pool, 0);
4399 /* On S/390, if the total size of the function's code plus literal pool
4400 does not exceed 4096 bytes, we use BASR to set up a function base
4401 pointer, and emit the literal pool at the end of the function. */
4402 else if (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
4403 + pool->size + 8 /* alignment slop */ < 4096)
4405 insn = gen_main_base_31_small (base_reg, pool->label);
4406 insn = emit_insn_after (insn, pool->pool_insn);
4407 INSN_ADDRESSES_NEW (insn, -1);
4408 remove_insn (pool->pool_insn);
4410 insn = emit_label_after (pool->label, insn);
4411 INSN_ADDRESSES_NEW (insn, -1);
4413 insn = get_last_insn ();
4414 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
4415 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
4417 s390_dump_pool (pool, 1);
4420 /* Otherwise, we emit an inline literal pool and use BASR to branch
4421 over it, setting up the pool register at the same time. */
4422 else
4424 rtx pool_end = gen_label_rtx ();
4426 insn = gen_main_base_31_large (base_reg, pool->label, pool_end);
4427 insn = emit_insn_after (insn, pool->pool_insn);
4428 INSN_ADDRESSES_NEW (insn, -1);
4429 remove_insn (pool->pool_insn);
4431 insn = emit_label_after (pool->label, insn);
4432 INSN_ADDRESSES_NEW (insn, -1);
4434 pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
4435 INSN_ADDRESSES_NEW (pool->pool_insn, -1);
4437 insn = emit_label_after (pool_end, pool->pool_insn);
4438 INSN_ADDRESSES_NEW (insn, -1);
4440 s390_dump_pool (pool, 1);
4444 /* Replace all literal pool references. */
4446 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4448 if (INSN_P (insn))
4449 replace_ltrel_base (&PATTERN (insn), base_reg);
4451 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
4453 rtx addr, pool_ref = NULL_RTX;
4454 find_constant_pool_ref (PATTERN (insn), &pool_ref);
4455 if (pool_ref)
4457 addr = s390_find_constant (pool, get_pool_constant (pool_ref),
4458 get_pool_mode (pool_ref));
4459 addr = gen_rtx_PLUS (Pmode, base_reg, addr);
4460 replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
4461 INSN_CODE (insn) = -1;
4467 /* Free the pool. */
4468 s390_free_pool (pool);
4471 /* POOL holds the main literal pool as collected by s390_mainpool_start.
4472 We have decided we cannot use this pool, so revert all changes
4473 to the current function that were done by s390_mainpool_start. */
4474 static void
4475 s390_mainpool_cancel (struct constant_pool *pool)
4477 /* We didn't actually change the instruction stream, so simply
4478 free the pool memory. */
4479 s390_free_pool (pool);
4483 /* Chunkify the literal pool. BASE_REG is to be used as pool
4484 register. */
4486 #define S390_POOL_CHUNK_MIN 0xc00
4487 #define S390_POOL_CHUNK_MAX 0xe00
4489 static struct constant_pool *
4490 s390_chunkify_start (rtx base_reg)
4492 struct constant_pool *curr_pool = NULL, *pool_list = NULL;
4493 int extra_size = 0;
4494 bitmap far_labels;
4495 rtx pending_ltrel = NULL_RTX;
4496 rtx insn;
4498 rtx (*gen_reload_base) (rtx, rtx) =
4499 TARGET_CPU_ZARCH? gen_reload_base_64 : gen_reload_base_31;
4502 /* We need correct insn addresses. */
4504 shorten_branches (get_insns ());
4506 /* Scan all insns and move literals to pool chunks. */
4508 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4510 /* Check for pending LTREL_BASE. */
4511 if (INSN_P (insn))
4513 rtx ltrel_base = find_ltrel_base (PATTERN (insn));
4514 if (ltrel_base)
4516 if (ltrel_base == pending_ltrel)
4517 pending_ltrel = NULL_RTX;
4518 else
4519 abort ();
4523 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
4525 rtx pool_ref = NULL_RTX;
4526 find_constant_pool_ref (PATTERN (insn), &pool_ref);
4527 if (pool_ref)
4529 rtx constant = get_pool_constant (pool_ref);
4530 enum machine_mode mode = get_pool_mode (pool_ref);
4532 if (!curr_pool)
4533 curr_pool = s390_start_pool (&pool_list, insn);
4535 s390_add_constant (curr_pool, constant, mode);
4536 s390_add_pool_insn (curr_pool, insn);
4538 /* Don't split the pool chunk between a LTREL_OFFSET load
4539 and the corresponding LTREL_BASE. */
4540 if (GET_CODE (constant) == CONST
4541 && GET_CODE (XEXP (constant, 0)) == UNSPEC
4542 && XINT (XEXP (constant, 0), 1) == UNSPEC_LTREL_OFFSET)
4544 if (pending_ltrel)
4545 abort ();
4546 pending_ltrel = pool_ref;
4551 if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CODE_LABEL)
4553 if (curr_pool)
4554 s390_add_pool_insn (curr_pool, insn);
4555 /* An LTREL_BASE must follow within the same basic block. */
4556 if (pending_ltrel)
4557 abort ();
4560 if (!curr_pool
4561 || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn)
4562 || INSN_ADDRESSES (INSN_UID (insn)) == -1)
4563 continue;
4565 if (TARGET_CPU_ZARCH)
4567 if (curr_pool->size < S390_POOL_CHUNK_MAX)
4568 continue;
4570 s390_end_pool (curr_pool, NULL_RTX);
4571 curr_pool = NULL;
4573 else
4575 int chunk_size = INSN_ADDRESSES (INSN_UID (insn))
4576 - INSN_ADDRESSES (INSN_UID (curr_pool->first_insn))
4577 + extra_size;
4579 /* We will later have to insert base register reload insns.
4580 Those will have an effect on code size, which we need to
4581 consider here. This calculation makes rather pessimistic
4582 worst-case assumptions. */
4583 if (GET_CODE (insn) == CODE_LABEL)
4584 extra_size += 6;
4586 if (chunk_size < S390_POOL_CHUNK_MIN
4587 && curr_pool->size < S390_POOL_CHUNK_MIN)
4588 continue;
4590 /* Pool chunks can only be inserted after BARRIERs ... */
4591 if (GET_CODE (insn) == BARRIER)
4593 s390_end_pool (curr_pool, insn);
4594 curr_pool = NULL;
4595 extra_size = 0;
4598 /* ... so if we don't find one in time, create one. */
4599 else if ((chunk_size > S390_POOL_CHUNK_MAX
4600 || curr_pool->size > S390_POOL_CHUNK_MAX))
4602 rtx label, jump, barrier;
4604 /* We can insert the barrier only after a 'real' insn. */
4605 if (GET_CODE (insn) != INSN && GET_CODE (insn) != CALL_INSN)
4606 continue;
4607 if (get_attr_length (insn) == 0)
4608 continue;
4610 /* Don't separate LTREL_BASE from the corresponding
4611 LTREL_OFFSET load. */
4612 if (pending_ltrel)
4613 continue;
4615 label = gen_label_rtx ();
4616 jump = emit_jump_insn_after (gen_jump (label), insn);
4617 barrier = emit_barrier_after (jump);
4618 insn = emit_label_after (label, barrier);
4619 JUMP_LABEL (jump) = label;
4620 LABEL_NUSES (label) = 1;
4622 INSN_ADDRESSES_NEW (jump, -1);
4623 INSN_ADDRESSES_NEW (barrier, -1);
4624 INSN_ADDRESSES_NEW (insn, -1);
4626 s390_end_pool (curr_pool, barrier);
4627 curr_pool = NULL;
4628 extra_size = 0;
4633 if (curr_pool)
4634 s390_end_pool (curr_pool, NULL_RTX);
4635 if (pending_ltrel)
4636 abort ();
4639 /* Find all labels that are branched into
4640 from an insn belonging to a different chunk. */
4642 far_labels = BITMAP_XMALLOC ();
4644 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4646 /* Labels marked with LABEL_PRESERVE_P can be target
4647 of non-local jumps, so we have to mark them.
4648 The same holds for named labels.
4650 Don't do that, however, if it is the label before
4651 a jump table. */
4653 if (GET_CODE (insn) == CODE_LABEL
4654 && (LABEL_PRESERVE_P (insn) || LABEL_NAME (insn)))
4656 rtx vec_insn = next_real_insn (insn);
4657 rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
4658 PATTERN (vec_insn) : NULL_RTX;
4659 if (!vec_pat
4660 || !(GET_CODE (vec_pat) == ADDR_VEC
4661 || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
4662 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (insn));
4665 /* If we have a direct jump (conditional or unconditional)
4666 or a casesi jump, check all potential targets. */
4667 else if (GET_CODE (insn) == JUMP_INSN)
4669 rtx pat = PATTERN (insn);
4670 if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
4671 pat = XVECEXP (pat, 0, 0);
4673 if (GET_CODE (pat) == SET)
4675 rtx label = JUMP_LABEL (insn);
4676 if (label)
4678 if (s390_find_pool (pool_list, label)
4679 != s390_find_pool (pool_list, insn))
4680 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
4683 else if (GET_CODE (pat) == PARALLEL
4684 && XVECLEN (pat, 0) == 2
4685 && GET_CODE (XVECEXP (pat, 0, 0)) == SET
4686 && GET_CODE (XVECEXP (pat, 0, 1)) == USE
4687 && GET_CODE (XEXP (XVECEXP (pat, 0, 1), 0)) == LABEL_REF)
4689 /* Find the jump table used by this casesi jump. */
4690 rtx vec_label = XEXP (XEXP (XVECEXP (pat, 0, 1), 0), 0);
4691 rtx vec_insn = next_real_insn (vec_label);
4692 rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
4693 PATTERN (vec_insn) : NULL_RTX;
4694 if (vec_pat
4695 && (GET_CODE (vec_pat) == ADDR_VEC
4696 || GET_CODE (vec_pat) == ADDR_DIFF_VEC))
4698 int i, diff_p = GET_CODE (vec_pat) == ADDR_DIFF_VEC;
4700 for (i = 0; i < XVECLEN (vec_pat, diff_p); i++)
4702 rtx label = XEXP (XVECEXP (vec_pat, diff_p, i), 0);
4704 if (s390_find_pool (pool_list, label)
4705 != s390_find_pool (pool_list, insn))
4706 bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
4713 /* Insert base register reload insns before every pool. */
4715 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
4717 rtx new_insn = gen_reload_base (base_reg, curr_pool->label);
4718 rtx insn = curr_pool->first_insn;
4719 INSN_ADDRESSES_NEW (emit_insn_before (new_insn, insn), -1);
4722 /* Insert base register reload insns at every far label. */
4724 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4725 if (GET_CODE (insn) == CODE_LABEL
4726 && bitmap_bit_p (far_labels, CODE_LABEL_NUMBER (insn)))
4728 struct constant_pool *pool = s390_find_pool (pool_list, insn);
4729 if (pool)
4731 rtx new_insn = gen_reload_base (base_reg, pool->label);
4732 INSN_ADDRESSES_NEW (emit_insn_after (new_insn, insn), -1);
4737 BITMAP_XFREE (far_labels);
4740 /* Recompute insn addresses. */
4742 init_insn_lengths ();
4743 shorten_branches (get_insns ());
4745 return pool_list;
4748 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
4749 After we have decided to use this list, finish implementing
4750 all changes to the current function as required. BASE_REG is
4751 to be used as pool base register. */
4753 static void
4754 s390_chunkify_finish (struct constant_pool *pool_list, rtx base_reg)
4756 struct constant_pool *curr_pool = NULL;
4757 rtx insn;
4760 /* Replace all literal pool references. */
4762 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4764 if (INSN_P (insn))
4765 replace_ltrel_base (&PATTERN (insn), base_reg);
4767 curr_pool = s390_find_pool (pool_list, insn);
4768 if (!curr_pool)
4769 continue;
4771 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
4773 rtx addr, pool_ref = NULL_RTX;
4774 find_constant_pool_ref (PATTERN (insn), &pool_ref);
4775 if (pool_ref)
4777 addr = s390_find_constant (curr_pool, get_pool_constant (pool_ref),
4778 get_pool_mode (pool_ref));
4779 addr = gen_rtx_PLUS (Pmode, base_reg, addr);
4780 replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
4781 INSN_CODE (insn) = -1;
4786 /* Dump out all literal pools. */
4788 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
4789 s390_dump_pool (curr_pool, 0);
4791 /* Free pool list. */
4793 while (pool_list)
4795 struct constant_pool *next = pool_list->next;
4796 s390_free_pool (pool_list);
4797 pool_list = next;
4801 /* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
4802 We have decided we cannot use this list, so revert all changes
4803 to the current function that were done by s390_chunkify_start. */
4805 static void
4806 s390_chunkify_cancel (struct constant_pool *pool_list)
4808 struct constant_pool *curr_pool = NULL;
4809 rtx insn;
4811 /* Remove all pool placeholder insns. */
4813 for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
4815 /* Did we insert an extra barrier? Remove it. */
4816 rtx barrier = PREV_INSN (curr_pool->pool_insn);
4817 rtx jump = barrier? PREV_INSN (barrier) : NULL_RTX;
4818 rtx label = NEXT_INSN (curr_pool->pool_insn);
4820 if (jump && GET_CODE (jump) == JUMP_INSN
4821 && barrier && GET_CODE (barrier) == BARRIER
4822 && label && GET_CODE (label) == CODE_LABEL
4823 && GET_CODE (PATTERN (jump)) == SET
4824 && SET_DEST (PATTERN (jump)) == pc_rtx
4825 && GET_CODE (SET_SRC (PATTERN (jump))) == LABEL_REF
4826 && XEXP (SET_SRC (PATTERN (jump)), 0) == label)
4828 remove_insn (jump);
4829 remove_insn (barrier);
4830 remove_insn (label);
4833 remove_insn (curr_pool->pool_insn);
4836 /* Remove all base register reload insns. */
4838 for (insn = get_insns (); insn; )
4840 rtx next_insn = NEXT_INSN (insn);
4842 if (GET_CODE (insn) == INSN
4843 && GET_CODE (PATTERN (insn)) == SET
4844 && GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC
4845 && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPEC_RELOAD_BASE)
4846 remove_insn (insn);
4848 insn = next_insn;
4851 /* Free pool list. */
4853 while (pool_list)
4855 struct constant_pool *next = pool_list->next;
4856 s390_free_pool (pool_list);
4857 pool_list = next;
4862 /* Output to FILE the constant pool entry EXP in mode MODE
4863 with alignment ALIGN. */
4865 void
4866 s390_output_pool_entry (FILE *file, rtx exp, enum machine_mode mode,
4867 unsigned int align)
4869 REAL_VALUE_TYPE r;
4871 switch (GET_MODE_CLASS (mode))
4873 case MODE_FLOAT:
4874 if (GET_CODE (exp) != CONST_DOUBLE)
4875 abort ();
4877 REAL_VALUE_FROM_CONST_DOUBLE (r, exp);
4878 assemble_real (r, mode, align);
4879 break;
4881 case MODE_INT:
4882 if (GET_CODE (exp) == CONST
4883 || GET_CODE (exp) == SYMBOL_REF
4884 || GET_CODE (exp) == LABEL_REF)
4886 fputs (integer_asm_op (GET_MODE_SIZE (mode), TRUE), file);
4887 s390_output_symbolic_const (file, exp);
4888 fputc ('\n', file);
4890 else
4892 assemble_integer (exp, GET_MODE_SIZE (mode), align, 1);
4894 break;
4896 default:
4897 abort ();
4902 /* Rework the prolog/epilog to avoid saving/restoring
4903 registers unnecessarily. BASE_USED specifies whether
4904 the literal pool base register needs to be saved,
4905 TEMP_USED specifies whether the return register needs
4906 to be saved. */
4908 static void
4909 s390_optimize_prolog (bool base_used, bool temp_used)
4911 int save_first, save_last, restore_first, restore_last;
4912 int i, j;
4913 rtx insn, new_insn, next_insn;
4915 /* Recompute regs_ever_live data for special registers. */
4916 regs_ever_live[BASE_REGISTER] = base_used;
4917 regs_ever_live[RETURN_REGNUM] = temp_used;
4918 regs_ever_live[STACK_POINTER_REGNUM] = cfun->machine->frame_size > 0;
4920 /* In non-leaf functions, the prolog/epilog code relies
4921 on RETURN_REGNUM being saved in any case. We also need
4922 to save the return register if __builtin_return_address (0)
4923 was used in the current function. */
4924 if (!current_function_is_leaf
4925 || cfun->machine->save_return_addr_p)
4926 regs_ever_live[RETURN_REGNUM] = 1;
4929 /* Find first and last gpr to be saved. */
4931 for (i = 6; i < 16; i++)
4932 if (regs_ever_live[i])
4933 if (!global_regs[i]
4934 || i == STACK_POINTER_REGNUM
4935 || i == RETURN_REGNUM
4936 || i == BASE_REGISTER
4937 || (flag_pic && i == (int)PIC_OFFSET_TABLE_REGNUM))
4938 break;
4940 for (j = 15; j > i; j--)
4941 if (regs_ever_live[j])
4942 if (!global_regs[j]
4943 || j == STACK_POINTER_REGNUM
4944 || j == RETURN_REGNUM
4945 || j == BASE_REGISTER
4946 || (flag_pic && j == (int)PIC_OFFSET_TABLE_REGNUM))
4947 break;
4949 if (i == 16)
4951 /* Nothing to save/restore. */
4952 save_first = restore_first = -1;
4953 save_last = restore_last = -1;
4955 else
4957 /* Save/restore from i to j. */
4958 save_first = restore_first = i;
4959 save_last = restore_last = j;
4962 /* Varargs functions need to save gprs 2 to 6. */
4963 if (current_function_stdarg)
4965 save_first = 2;
4966 if (save_last < 6)
4967 save_last = 6;
4971 /* If all special registers are in fact used, there's nothing we
4972 can do, so no point in walking the insn list. */
4973 if (i <= BASE_REGISTER && j >= BASE_REGISTER
4974 && i <= RETURN_REGNUM && j >= RETURN_REGNUM)
4975 return;
4978 /* Search for prolog/epilog insns and replace them. */
4980 for (insn = get_insns (); insn; insn = next_insn)
4982 int first, last, off;
4983 rtx set, base, offset;
4985 next_insn = NEXT_INSN (insn);
4987 if (GET_CODE (insn) != INSN)
4988 continue;
4989 if (GET_CODE (PATTERN (insn)) != PARALLEL)
4990 continue;
4992 if (store_multiple_operation (PATTERN (insn), VOIDmode))
4994 set = XVECEXP (PATTERN (insn), 0, 0);
4995 first = REGNO (SET_SRC (set));
4996 last = first + XVECLEN (PATTERN (insn), 0) - 1;
4997 offset = const0_rtx;
4998 base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
4999 off = INTVAL (offset) - first * UNITS_PER_WORD;
5001 if (GET_CODE (base) != REG || off < 0)
5002 continue;
5003 if (first > BASE_REGISTER && first > RETURN_REGNUM)
5004 continue;
5005 if (last < BASE_REGISTER && last < RETURN_REGNUM)
5006 continue;
5008 if (save_first != -1)
5010 new_insn = save_gprs (base, off, save_first, save_last);
5011 new_insn = emit_insn_before (new_insn, insn);
5012 INSN_ADDRESSES_NEW (new_insn, -1);
5015 remove_insn (insn);
5018 if (load_multiple_operation (PATTERN (insn), VOIDmode))
5020 set = XVECEXP (PATTERN (insn), 0, 0);
5021 first = REGNO (SET_DEST (set));
5022 last = first + XVECLEN (PATTERN (insn), 0) - 1;
5023 offset = const0_rtx;
5024 base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
5025 off = INTVAL (offset) - first * UNITS_PER_WORD;
5027 if (GET_CODE (base) != REG || off < 0)
5028 continue;
5029 if (first > BASE_REGISTER && first > RETURN_REGNUM)
5030 continue;
5031 if (last < BASE_REGISTER && last < RETURN_REGNUM)
5032 continue;
5034 if (restore_first != -1)
5036 new_insn = restore_gprs (base, off, restore_first, restore_last);
5037 new_insn = emit_insn_before (new_insn, insn);
5038 INSN_ADDRESSES_NEW (new_insn, -1);
5041 remove_insn (insn);
5046 /* Perform machine-dependent processing. */
5048 static void
5049 s390_reorg (void)
5051 rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
5052 rtx base_reg = gen_rtx_REG (Pmode, BASE_REGISTER);
5053 bool temp_used = false;
5054 bool base_used = false;
5055 bool pool_overflow = false;
5057 /* Make sure all splits have been performed; splits after
5058 machine_dependent_reorg might confuse insn length counts. */
5059 split_all_insns_noflow ();
5062 /* In small leaf functions, try to use an unused call-clobbered
5063 register as base register to avoid save/restore overhead. */
5064 if (current_function_is_leaf && !regs_ever_live[5])
5065 base_reg = gen_rtx_REG (Pmode, 5);
5068 /* Install the main literal pool and the associated base
5069 register load insns.
5071 In addition, there are two problematic situations we need
5072 to correct:
5074 - the literal pool might be > 4096 bytes in size, so that
5075 some of its elements cannot be directly accessed
5077 - a branch target might be > 64K away from the branch, so that
5078 it is not possible to use a PC-relative instruction.
5080 To fix those, we split the single literal pool into multiple
5081 pool chunks, reloading the pool base register at various
5082 points throughout the function to ensure it always points to
5083 the pool chunk the following code expects, and / or replace
5084 PC-relative branches by absolute branches.
5086 However, the two problems are interdependent: splitting the
5087 literal pool can move a branch further away from its target,
5088 causing the 64K limit to overflow, and on the other hand,
5089 replacing a PC-relative branch by an absolute branch means
5090 we need to put the branch target address into the literal
5091 pool, possibly causing it to overflow.
5093 So, we loop trying to fix up both problems until we manage
5094 to satisfy both conditions at the same time. Note that the
5095 loop is guaranteed to terminate as every pass of the loop
5096 strictly decreases the total number of PC-relative branches
5097 in the function. (This is not completely true as there
5098 might be branch-over-pool insns introduced by chunkify_start.
5099 Those never need to be split however.) */
5101 for (;;)
5103 struct constant_pool *pool = NULL;
5105 /* Collect the literal pool. */
5106 if (!pool_overflow)
5108 pool = s390_mainpool_start ();
5109 if (!pool)
5110 pool_overflow = true;
5113 /* If literal pool overflowed, start to chunkify it. */
5114 if (pool_overflow)
5115 pool = s390_chunkify_start (base_reg);
5117 /* Split out-of-range branches. If this has created new
5118 literal pool entries, cancel current chunk list and
5119 recompute it. */
5120 if (s390_split_branches (temp_reg, &temp_used))
5122 if (pool_overflow)
5123 s390_chunkify_cancel (pool);
5124 else
5125 s390_mainpool_cancel (pool);
5127 continue;
5130 /* If we made it up to here, both conditions are satisfied.
5131 Finish up literal pool related changes. */
5132 if ((pool_overflow || pool->size > 0)
5133 && REGNO (base_reg) == BASE_REGISTER)
5134 base_used = true;
5136 if (pool_overflow)
5137 s390_chunkify_finish (pool, base_reg);
5138 else
5139 s390_mainpool_finish (pool, base_reg);
5141 break;
5144 s390_optimize_prolog (base_used, temp_used);
5148 /* Return an RTL expression representing the value of the return address
5149 for the frame COUNT steps up from the current frame. FRAME is the
5150 frame pointer of that frame. */
5153 s390_return_addr_rtx (int count, rtx frame)
5155 rtx addr;
5157 /* For the current frame, we need to make sure the initial
5158 value of RETURN_REGNUM is actually saved. */
5160 if (count == 0)
5161 cfun->machine->save_return_addr_p = true;
5163 /* To retrieve the return address we read the stack slot where the
5164 corresponding RETURN_REGNUM value was saved. */
5166 addr = plus_constant (frame, RETURN_REGNUM * UNITS_PER_WORD);
5167 addr = memory_address (Pmode, addr);
5168 return gen_rtx_MEM (Pmode, addr);
5171 /* Find first call clobbered register unsused in a function.
5172 This could be used as base register in a leaf function
5173 or for holding the return address before epilogue. */
5175 static int
5176 find_unused_clobbered_reg (void)
5178 int i;
5179 for (i = 0; i < 6; i++)
5180 if (!regs_ever_live[i])
5181 return i;
5182 return 0;
5185 /* Fill FRAME with info about frame of current function. */
5187 static void
5188 s390_frame_info (void)
5190 char gprs_ever_live[16];
5191 int i, j;
5192 HOST_WIDE_INT fsize = get_frame_size ();
5194 if (fsize > 0x7fff0000)
5195 fatal_error ("Total size of local variables exceeds architecture limit.");
5197 /* fprs 8 - 15 are caller saved for 64 Bit ABI. */
5198 cfun->machine->save_fprs_p = 0;
5199 if (TARGET_64BIT)
5200 for (i = 24; i < 32; i++)
5201 if (regs_ever_live[i] && !global_regs[i])
5203 cfun->machine->save_fprs_p = 1;
5204 break;
5207 cfun->machine->frame_size = fsize + cfun->machine->save_fprs_p * 64;
5209 /* Does function need to setup frame and save area. */
5211 if (! current_function_is_leaf
5212 || cfun->machine->frame_size > 0
5213 || current_function_calls_alloca
5214 || current_function_stdarg)
5215 cfun->machine->frame_size += STARTING_FRAME_OFFSET;
5217 /* Find first and last gpr to be saved. Note that at this point,
5218 we assume the return register and the base register always
5219 need to be saved. This is done because the usage of these
5220 register might change even after the prolog was emitted.
5221 If it turns out later that we really don't need them, the
5222 prolog/epilog code is modified again. */
5224 for (i = 0; i < 16; i++)
5225 gprs_ever_live[i] = regs_ever_live[i] && !global_regs[i];
5227 if (flag_pic)
5228 gprs_ever_live[PIC_OFFSET_TABLE_REGNUM] =
5229 regs_ever_live[PIC_OFFSET_TABLE_REGNUM];
5230 gprs_ever_live[BASE_REGISTER] = 1;
5231 gprs_ever_live[RETURN_REGNUM] = 1;
5232 gprs_ever_live[STACK_POINTER_REGNUM] = cfun->machine->frame_size > 0;
5234 for (i = 6; i < 16; i++)
5235 if (gprs_ever_live[i])
5236 break;
5238 for (j = 15; j > i; j--)
5239 if (gprs_ever_live[j])
5240 break;
5243 /* Save / Restore from gpr i to j. */
5244 cfun->machine->first_save_gpr = i;
5245 cfun->machine->first_restore_gpr = i;
5246 cfun->machine->last_save_gpr = j;
5248 /* Varargs functions need to save gprs 2 to 6. */
5249 if (current_function_stdarg)
5250 cfun->machine->first_save_gpr = 2;
5253 /* Return offset between argument pointer and frame pointer
5254 initially after prologue. */
5257 s390_arg_frame_offset (void)
5259 HOST_WIDE_INT fsize = get_frame_size ();
5260 int save_fprs_p, i;
5262 /* fprs 8 - 15 are caller saved for 64 Bit ABI. */
5263 save_fprs_p = 0;
5264 if (TARGET_64BIT)
5265 for (i = 24; i < 32; i++)
5266 if (regs_ever_live[i] && !global_regs[i])
5268 save_fprs_p = 1;
5269 break;
5272 fsize = fsize + save_fprs_p * 64;
5274 /* Does function need to setup frame and save area. */
5276 if (! current_function_is_leaf
5277 || fsize > 0
5278 || current_function_calls_alloca
5279 || current_function_stdarg)
5280 fsize += STARTING_FRAME_OFFSET;
5281 return fsize + STACK_POINTER_OFFSET;
5284 /* Emit insn to save fpr REGNUM at offset OFFSET relative
5285 to register BASE. Return generated insn. */
5287 static rtx
5288 save_fpr (rtx base, int offset, int regnum)
5290 rtx addr;
5291 addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
5292 set_mem_alias_set (addr, s390_sr_alias_set);
5294 return emit_move_insn (addr, gen_rtx_REG (DFmode, regnum));
5297 /* Emit insn to restore fpr REGNUM from offset OFFSET relative
5298 to register BASE. Return generated insn. */
5300 static rtx
5301 restore_fpr (rtx base, int offset, int regnum)
5303 rtx addr;
5304 addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
5305 set_mem_alias_set (addr, s390_sr_alias_set);
5307 return emit_move_insn (gen_rtx_REG (DFmode, regnum), addr);
5310 /* Generate insn to save registers FIRST to LAST into
5311 the register save area located at offset OFFSET
5312 relative to register BASE. */
5314 static rtx
5315 save_gprs (rtx base, int offset, int first, int last)
5317 rtx addr, insn, note;
5318 int i;
5320 addr = plus_constant (base, offset + first * UNITS_PER_WORD);
5321 addr = gen_rtx_MEM (Pmode, addr);
5322 set_mem_alias_set (addr, s390_sr_alias_set);
5324 /* Special-case single register. */
5325 if (first == last)
5327 if (TARGET_64BIT)
5328 insn = gen_movdi (addr, gen_rtx_REG (Pmode, first));
5329 else
5330 insn = gen_movsi (addr, gen_rtx_REG (Pmode, first));
5332 RTX_FRAME_RELATED_P (insn) = 1;
5333 return insn;
5337 insn = gen_store_multiple (addr,
5338 gen_rtx_REG (Pmode, first),
5339 GEN_INT (last - first + 1));
5342 /* We need to set the FRAME_RELATED flag on all SETs
5343 inside the store-multiple pattern.
5345 However, we must not emit DWARF records for registers 2..5
5346 if they are stored for use by variable arguments ...
5348 ??? Unfortunately, it is not enough to simply not the the
5349 FRAME_RELATED flags for those SETs, because the first SET
5350 of the PARALLEL is always treated as if it had the flag
5351 set, even if it does not. Therefore we emit a new pattern
5352 without those registers as REG_FRAME_RELATED_EXPR note. */
5354 if (first >= 6)
5356 rtx pat = PATTERN (insn);
5358 for (i = 0; i < XVECLEN (pat, 0); i++)
5359 if (GET_CODE (XVECEXP (pat, 0, i)) == SET)
5360 RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1;
5362 RTX_FRAME_RELATED_P (insn) = 1;
5364 else if (last >= 6)
5366 addr = plus_constant (base, offset + 6 * UNITS_PER_WORD);
5367 note = gen_store_multiple (gen_rtx_MEM (Pmode, addr),
5368 gen_rtx_REG (Pmode, 6),
5369 GEN_INT (last - 6 + 1));
5370 note = PATTERN (note);
5372 REG_NOTES (insn) =
5373 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
5374 note, REG_NOTES (insn));
5376 for (i = 0; i < XVECLEN (note, 0); i++)
5377 if (GET_CODE (XVECEXP (note, 0, i)) == SET)
5378 RTX_FRAME_RELATED_P (XVECEXP (note, 0, i)) = 1;
5380 RTX_FRAME_RELATED_P (insn) = 1;
5383 return insn;
5386 /* Generate insn to restore registers FIRST to LAST from
5387 the register save area located at offset OFFSET
5388 relative to register BASE. */
5390 static rtx
5391 restore_gprs (rtx base, int offset, int first, int last)
5393 rtx addr, insn;
5395 addr = plus_constant (base, offset + first * UNITS_PER_WORD);
5396 addr = gen_rtx_MEM (Pmode, addr);
5397 set_mem_alias_set (addr, s390_sr_alias_set);
5399 /* Special-case single register. */
5400 if (first == last)
5402 if (TARGET_64BIT)
5403 insn = gen_movdi (gen_rtx_REG (Pmode, first), addr);
5404 else
5405 insn = gen_movsi (gen_rtx_REG (Pmode, first), addr);
5407 return insn;
5410 insn = gen_load_multiple (gen_rtx_REG (Pmode, first),
5411 addr,
5412 GEN_INT (last - first + 1));
5413 return insn;
5416 /* Emit code to load the GOT register. If MAYBE_DEAD is true,
5417 annotate generated insns with REG_MAYBE_DEAD notes. */
5419 static GTY(()) rtx got_symbol;
5420 void
5421 s390_load_got (int maybe_dead)
5423 if (!got_symbol)
5425 got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5426 SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
5429 if (TARGET_CPU_ZARCH)
5431 rtx insn = emit_move_insn (pic_offset_table_rtx, got_symbol);
5432 if (maybe_dead)
5433 REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
5434 REG_NOTES (insn));
5436 else
5438 rtx offset, insn;
5440 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got_symbol),
5441 UNSPEC_LTREL_OFFSET);
5442 offset = gen_rtx_CONST (Pmode, offset);
5443 offset = force_const_mem (Pmode, offset);
5445 insn = emit_move_insn (pic_offset_table_rtx, offset);
5446 if (maybe_dead)
5447 REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
5448 REG_NOTES (insn));
5450 offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (offset, 0)),
5451 UNSPEC_LTREL_BASE);
5452 offset = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, offset);
5454 insn = emit_move_insn (pic_offset_table_rtx, offset);
5455 if (maybe_dead)
5456 REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
5457 REG_NOTES (insn));
5461 /* Expand the prologue into a bunch of separate insns. */
5463 void
5464 s390_emit_prologue (void)
5466 rtx insn, addr;
5467 rtx temp_reg;
5468 int i;
5470 /* Compute frame_info. */
5472 s390_frame_info ();
5474 /* Choose best register to use for temp use within prologue.
5475 See below for why TPF must use the register 1. */
5477 if (!current_function_is_leaf
5478 && !TARGET_TPF)
5479 temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
5480 else
5481 temp_reg = gen_rtx_REG (Pmode, 1);
5483 /* Save call saved gprs. */
5485 insn = save_gprs (stack_pointer_rtx, 0,
5486 cfun->machine->first_save_gpr, cfun->machine->last_save_gpr);
5487 emit_insn (insn);
5489 /* Dummy insn to mark literal pool slot. */
5491 emit_insn (gen_main_pool ());
5493 /* Save fprs for variable args. */
5495 if (current_function_stdarg)
5497 /* Save fpr 0 and 2. */
5499 save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 32, 16);
5500 save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 24, 17);
5502 if (TARGET_64BIT)
5504 /* Save fpr 4 and 6. */
5506 save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 16, 18);
5507 save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 8, 19);
5511 /* Save fprs 4 and 6 if used (31 bit ABI). */
5513 if (!TARGET_64BIT)
5515 /* Save fpr 4 and 6. */
5516 if (regs_ever_live[18] && !global_regs[18])
5518 insn = save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 16, 18);
5519 RTX_FRAME_RELATED_P (insn) = 1;
5521 if (regs_ever_live[19] && !global_regs[19])
5523 insn = save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 8, 19);
5524 RTX_FRAME_RELATED_P (insn) = 1;
5528 /* Decrement stack pointer. */
5530 if (cfun->machine->frame_size > 0)
5532 rtx frame_off = GEN_INT (-cfun->machine->frame_size);
5534 /* Save incoming stack pointer into temp reg. */
5536 if (TARGET_BACKCHAIN || cfun->machine->save_fprs_p)
5538 insn = emit_insn (gen_move_insn (temp_reg, stack_pointer_rtx));
5541 /* Subtract frame size from stack pointer. */
5543 if (DISP_IN_RANGE (INTVAL (frame_off)))
5545 insn = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
5546 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
5547 frame_off));
5548 insn = emit_insn (insn);
5550 else
5552 if (!CONST_OK_FOR_LETTER_P (INTVAL (frame_off), 'K'))
5553 frame_off = force_const_mem (Pmode, frame_off);
5555 insn = emit_insn (gen_add2_insn (stack_pointer_rtx, frame_off));
5558 RTX_FRAME_RELATED_P (insn) = 1;
5559 REG_NOTES (insn) =
5560 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
5561 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
5562 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
5563 GEN_INT (-cfun->machine->frame_size))),
5564 REG_NOTES (insn));
5566 /* Set backchain. */
5568 if (TARGET_BACKCHAIN)
5570 addr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
5571 set_mem_alias_set (addr, s390_sr_alias_set);
5572 insn = emit_insn (gen_move_insn (addr, temp_reg));
5575 /* If we support asynchronous exceptions (e.g. for Java),
5576 we need to make sure the backchain pointer is set up
5577 before any possibly trapping memory access. */
5579 if (TARGET_BACKCHAIN && flag_non_call_exceptions)
5581 addr = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
5582 emit_insn (gen_rtx_CLOBBER (VOIDmode, addr));
5586 /* Save fprs 8 - 15 (64 bit ABI). */
5588 if (cfun->machine->save_fprs_p)
5590 insn = emit_insn (gen_add2_insn (temp_reg, GEN_INT(-64)));
5592 for (i = 24; i < 32; i++)
5593 if (regs_ever_live[i] && !global_regs[i])
5595 rtx addr = plus_constant (stack_pointer_rtx,
5596 cfun->machine->frame_size - 64 + (i-24)*8);
5598 insn = save_fpr (temp_reg, (i-24)*8, i);
5599 RTX_FRAME_RELATED_P (insn) = 1;
5600 REG_NOTES (insn) =
5601 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
5602 gen_rtx_SET (VOIDmode,
5603 gen_rtx_MEM (DFmode, addr),
5604 gen_rtx_REG (DFmode, i)),
5605 REG_NOTES (insn));
5609 /* Set frame pointer, if needed. */
5611 if (frame_pointer_needed)
5613 insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
5614 RTX_FRAME_RELATED_P (insn) = 1;
5617 /* Set up got pointer, if needed. */
5619 if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
5620 s390_load_got(true);
5622 if (TARGET_TPF)
5624 /* Generate a BAS instruction to serve as a function
5625 entry intercept to facilitate the use of tracing
5626 algorithms located at the branch target.
5628 This must use register 1. */
5629 rtx addr;
5630 rtx unkn;
5631 rtx link;
5633 addr = GEN_INT (0xfe0);
5634 unkn = CONST0_RTX (SImode);
5635 link = gen_rtx_REG (Pmode, 1);
5637 emit_call_insn (gen_call_exp (gen_rtx_MEM (QImode, addr), unkn, link));
5639 /* Emit a blockage here so that all code
5640 lies between the profiling mechanisms. */
5641 emit_insn (gen_blockage ());
5645 /* Expand the epilogue into a bunch of separate insns. */
5647 void
5648 s390_emit_epilogue (void)
5650 rtx frame_pointer, return_reg;
5651 int area_bottom, area_top, offset = 0;
5652 rtvec p;
5654 if (TARGET_TPF)
5657 /* Generate a BAS instruction to serve as a function
5658 entry intercept to facilitate the use of tracing
5659 algorithms located at the branch target.
5661 This must use register 1. */
5663 rtx addr;
5664 rtx unkn;
5665 rtx link;
5667 addr = GEN_INT (0xfe6);
5668 unkn = CONST0_RTX (SImode);
5669 link = gen_rtx_REG (Pmode, 1);
5671 /* Emit a blockage here so that all code
5672 lies between the profiling mechanisms. */
5673 emit_insn (gen_blockage ());
5675 emit_call_insn (gen_call_exp (gen_rtx_MEM (QImode, addr), unkn, link));
5678 /* Check whether to use frame or stack pointer for restore. */
5680 frame_pointer = frame_pointer_needed ?
5681 hard_frame_pointer_rtx : stack_pointer_rtx;
5683 /* Compute which parts of the save area we need to access. */
5685 if (cfun->machine->first_restore_gpr != -1)
5687 area_bottom = cfun->machine->first_restore_gpr * UNITS_PER_WORD;
5688 area_top = (cfun->machine->last_save_gpr + 1) * UNITS_PER_WORD;
5690 else
5692 area_bottom = INT_MAX;
5693 area_top = INT_MIN;
5696 if (TARGET_64BIT)
5698 if (cfun->machine->save_fprs_p)
5700 if (area_bottom > -64)
5701 area_bottom = -64;
5702 if (area_top < 0)
5703 area_top = 0;
5706 else
5708 if (regs_ever_live[18] && !global_regs[18])
5710 if (area_bottom > STACK_POINTER_OFFSET - 16)
5711 area_bottom = STACK_POINTER_OFFSET - 16;
5712 if (area_top < STACK_POINTER_OFFSET - 8)
5713 area_top = STACK_POINTER_OFFSET - 8;
5715 if (regs_ever_live[19] && !global_regs[19])
5717 if (area_bottom > STACK_POINTER_OFFSET - 8)
5718 area_bottom = STACK_POINTER_OFFSET - 8;
5719 if (area_top < STACK_POINTER_OFFSET)
5720 area_top = STACK_POINTER_OFFSET;
5724 /* Check whether we can access the register save area.
5725 If not, increment the frame pointer as required. */
5727 if (area_top <= area_bottom)
5729 /* Nothing to restore. */
5731 else if (DISP_IN_RANGE (cfun->machine->frame_size + area_bottom)
5732 && DISP_IN_RANGE (cfun->machine->frame_size + area_top-1))
5734 /* Area is in range. */
5735 offset = cfun->machine->frame_size;
5737 else
5739 rtx insn, frame_off;
5741 offset = area_bottom < 0 ? -area_bottom : 0;
5742 frame_off = GEN_INT (cfun->machine->frame_size - offset);
5744 if (DISP_IN_RANGE (INTVAL (frame_off)))
5746 insn = gen_rtx_SET (VOIDmode, frame_pointer,
5747 gen_rtx_PLUS (Pmode, frame_pointer, frame_off));
5748 insn = emit_insn (insn);
5750 else
5752 if (!CONST_OK_FOR_LETTER_P (INTVAL (frame_off), 'K'))
5753 frame_off = force_const_mem (Pmode, frame_off);
5755 insn = emit_insn (gen_add2_insn (frame_pointer, frame_off));
5759 /* Restore call saved fprs. */
5761 if (TARGET_64BIT)
5763 int i;
5765 if (cfun->machine->save_fprs_p)
5766 for (i = 24; i < 32; i++)
5767 if (regs_ever_live[i] && !global_regs[i])
5768 restore_fpr (frame_pointer,
5769 offset - 64 + (i-24) * 8, i);
5771 else
5773 if (regs_ever_live[18] && !global_regs[18])
5774 restore_fpr (frame_pointer, offset + STACK_POINTER_OFFSET - 16, 18);
5775 if (regs_ever_live[19] && !global_regs[19])
5776 restore_fpr (frame_pointer, offset + STACK_POINTER_OFFSET - 8, 19);
5779 /* Return register. */
5781 return_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
5783 /* Restore call saved gprs. */
5785 if (cfun->machine->first_restore_gpr != -1)
5787 rtx insn, addr;
5788 int i;
5790 /* Check for global register and save them
5791 to stack location from where they get restored. */
5793 for (i = cfun->machine->first_restore_gpr;
5794 i <= cfun->machine->last_save_gpr;
5795 i++)
5797 /* These registers are special and need to be
5798 restored in any case. */
5799 if (i == STACK_POINTER_REGNUM
5800 || i == RETURN_REGNUM
5801 || i == BASE_REGISTER
5802 || (flag_pic && i == (int)PIC_OFFSET_TABLE_REGNUM))
5803 continue;
5805 if (global_regs[i])
5807 addr = plus_constant (frame_pointer,
5808 offset + i * UNITS_PER_WORD);
5809 addr = gen_rtx_MEM (Pmode, addr);
5810 set_mem_alias_set (addr, s390_sr_alias_set);
5811 emit_move_insn (addr, gen_rtx_REG (Pmode, i));
5815 /* Fetch return address from stack before load multiple,
5816 this will do good for scheduling. */
5818 if (!current_function_is_leaf)
5820 int return_regnum = find_unused_clobbered_reg();
5821 if (!return_regnum)
5822 return_regnum = 4;
5823 return_reg = gen_rtx_REG (Pmode, return_regnum);
5825 addr = plus_constant (frame_pointer,
5826 offset + RETURN_REGNUM * UNITS_PER_WORD);
5827 addr = gen_rtx_MEM (Pmode, addr);
5828 set_mem_alias_set (addr, s390_sr_alias_set);
5829 emit_move_insn (return_reg, addr);
5832 /* ??? As references to the base register are not made
5833 explicit in insn RTX code, we have to add a barrier here
5834 to prevent incorrect scheduling. */
5836 emit_insn (gen_blockage());
5838 insn = restore_gprs (frame_pointer, offset,
5839 cfun->machine->first_restore_gpr,
5840 cfun->machine->last_save_gpr);
5841 emit_insn (insn);
5844 /* Return to caller. */
5846 p = rtvec_alloc (2);
5848 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
5849 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, return_reg);
5850 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
5854 /* Return the size in bytes of a function argument of
5855 type TYPE and/or mode MODE. At least one of TYPE or
5856 MODE must be specified. */
5858 static int
5859 s390_function_arg_size (enum machine_mode mode, tree type)
5861 if (type)
5862 return int_size_in_bytes (type);
5864 /* No type info available for some library calls ... */
5865 if (mode != BLKmode)
5866 return GET_MODE_SIZE (mode);
5868 /* If we have neither type nor mode, abort */
5869 abort ();
5872 /* Return true if a function argument of type TYPE and mode MODE
5873 is to be passed in a floating-point register, if available. */
5875 static bool
5876 s390_function_arg_float (enum machine_mode mode, tree type)
5878 /* Soft-float changes the ABI: no floating-point registers are used. */
5879 if (TARGET_SOFT_FLOAT)
5880 return false;
5882 /* No type info available for some library calls ... */
5883 if (!type)
5884 return mode == SFmode || mode == DFmode;
5886 /* The ABI says that record types with a single member are treated
5887 just like that member would be. */
5888 while (TREE_CODE (type) == RECORD_TYPE)
5890 tree field, single = NULL_TREE;
5892 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
5894 if (TREE_CODE (field) != FIELD_DECL)
5895 continue;
5897 if (single == NULL_TREE)
5898 single = TREE_TYPE (field);
5899 else
5900 return false;
5903 if (single == NULL_TREE)
5904 return false;
5905 else
5906 type = single;
5909 return TREE_CODE (type) == REAL_TYPE;
5912 /* Return 1 if a function argument of type TYPE and mode MODE
5913 is to be passed by reference. The ABI specifies that only
5914 structures of size 1, 2, 4, or 8 bytes are passed by value,
5915 all other structures (and complex numbers) are passed by
5916 reference. */
5919 s390_function_arg_pass_by_reference (enum machine_mode mode, tree type)
5921 int size = s390_function_arg_size (mode, type);
5923 if (type)
5925 if (AGGREGATE_TYPE_P (type) &&
5926 size != 1 && size != 2 && size != 4 && size != 8
5927 && !s390_function_arg_float (mode, type))
5928 return 1;
5930 if (TREE_CODE (type) == COMPLEX_TYPE)
5931 return 1;
5934 return 0;
5937 /* Update the data in CUM to advance over an argument of mode MODE and
5938 data type TYPE. (TYPE is null for libcalls where that information
5939 may not be available.). The boolean NAMED specifies whether the
5940 argument is a named argument (as opposed to an unnamed argument
5941 matching an ellipsis). */
5943 void
5944 s390_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5945 tree type, int named ATTRIBUTE_UNUSED)
5947 if (s390_function_arg_pass_by_reference (mode, type))
5949 cum->gprs += 1;
5951 else if (s390_function_arg_float (mode, type))
5953 cum->fprs += 1;
5955 else
5957 int size = s390_function_arg_size (mode, type);
5958 cum->gprs += ((size + UNITS_PER_WORD-1) / UNITS_PER_WORD);
5962 /* Define where to put the arguments to a function.
5963 Value is zero to push the argument on the stack,
5964 or a hard register in which to store the argument.
5966 MODE is the argument's machine mode.
5967 TYPE is the data type of the argument (as a tree).
5968 This is null for libcalls where that information may
5969 not be available.
5970 CUM is a variable of type CUMULATIVE_ARGS which gives info about
5971 the preceding args and about the function being called.
5972 NAMED is nonzero if this argument is a named parameter
5973 (otherwise it is an extra parameter matching an ellipsis).
5975 On S/390, we use general purpose registers 2 through 6 to
5976 pass integer, pointer, and certain structure arguments, and
5977 floating point registers 0 and 2 (0, 2, 4, and 6 on 64-bit)
5978 to pass floating point arguments. All remaining arguments
5979 are pushed to the stack. */
5982 s390_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
5983 int named ATTRIBUTE_UNUSED)
5985 if (s390_function_arg_pass_by_reference (mode, type))
5986 return 0;
5988 if (s390_function_arg_float (mode, type))
5990 if (cum->fprs + 1 > (TARGET_64BIT? 4 : 2))
5991 return 0;
5992 else
5993 return gen_rtx (REG, mode, cum->fprs + 16);
5995 else
5997 int size = s390_function_arg_size (mode, type);
5998 int n_gprs = (size + UNITS_PER_WORD-1) / UNITS_PER_WORD;
6000 if (cum->gprs + n_gprs > 5)
6001 return 0;
6002 else
6003 return gen_rtx (REG, mode, cum->gprs + 2);
6008 /* Create and return the va_list datatype.
6010 On S/390, va_list is an array type equivalent to
6012 typedef struct __va_list_tag
6014 long __gpr;
6015 long __fpr;
6016 void *__overflow_arg_area;
6017 void *__reg_save_area;
6019 } va_list[1];
6021 where __gpr and __fpr hold the number of general purpose
6022 or floating point arguments used up to now, respectively,
6023 __overflow_arg_area points to the stack location of the
6024 next argument passed on the stack, and __reg_save_area
6025 always points to the start of the register area in the
6026 call frame of the current function. The function prologue
6027 saves all registers used for argument passing into this
6028 area if the function uses variable arguments. */
6030 tree
6031 s390_build_va_list (void)
6033 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
6035 record = lang_hooks.types.make_type (RECORD_TYPE);
6037 type_decl =
6038 build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
6040 f_gpr = build_decl (FIELD_DECL, get_identifier ("__gpr"),
6041 long_integer_type_node);
6042 f_fpr = build_decl (FIELD_DECL, get_identifier ("__fpr"),
6043 long_integer_type_node);
6044 f_ovf = build_decl (FIELD_DECL, get_identifier ("__overflow_arg_area"),
6045 ptr_type_node);
6046 f_sav = build_decl (FIELD_DECL, get_identifier ("__reg_save_area"),
6047 ptr_type_node);
6049 DECL_FIELD_CONTEXT (f_gpr) = record;
6050 DECL_FIELD_CONTEXT (f_fpr) = record;
6051 DECL_FIELD_CONTEXT (f_ovf) = record;
6052 DECL_FIELD_CONTEXT (f_sav) = record;
6054 TREE_CHAIN (record) = type_decl;
6055 TYPE_NAME (record) = type_decl;
6056 TYPE_FIELDS (record) = f_gpr;
6057 TREE_CHAIN (f_gpr) = f_fpr;
6058 TREE_CHAIN (f_fpr) = f_ovf;
6059 TREE_CHAIN (f_ovf) = f_sav;
6061 layout_type (record);
6063 /* The correct type is an array type of one element. */
6064 return build_array_type (record, build_index_type (size_zero_node));
6067 /* Implement va_start by filling the va_list structure VALIST.
6068 STDARG_P is always true, and ignored.
6069 NEXTARG points to the first anonymous stack argument.
6071 The following global variables are used to initialize
6072 the va_list structure:
6074 current_function_args_info:
6075 holds number of gprs and fprs used for named arguments.
6076 current_function_arg_offset_rtx:
6077 holds the offset of the first anonymous stack argument
6078 (relative to the virtual arg pointer). */
6080 void
6081 s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
6083 HOST_WIDE_INT n_gpr, n_fpr;
6084 int off;
6085 tree f_gpr, f_fpr, f_ovf, f_sav;
6086 tree gpr, fpr, ovf, sav, t;
6088 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
6089 f_fpr = TREE_CHAIN (f_gpr);
6090 f_ovf = TREE_CHAIN (f_fpr);
6091 f_sav = TREE_CHAIN (f_ovf);
6093 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
6094 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
6095 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
6096 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
6097 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
6099 /* Count number of gp and fp argument registers used. */
6101 n_gpr = current_function_args_info.gprs;
6102 n_fpr = current_function_args_info.fprs;
6104 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, build_int_2 (n_gpr, 0));
6105 TREE_SIDE_EFFECTS (t) = 1;
6106 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6108 t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr, build_int_2 (n_fpr, 0));
6109 TREE_SIDE_EFFECTS (t) = 1;
6110 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6112 /* Find the overflow area. */
6113 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
6115 off = INTVAL (current_function_arg_offset_rtx);
6116 off = off < 0 ? 0 : off;
6117 if (TARGET_DEBUG_ARG)
6118 fprintf (stderr, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
6119 (int)n_gpr, (int)n_fpr, off);
6121 t = build (PLUS_EXPR, TREE_TYPE (ovf), t, build_int_2 (off, 0));
6123 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
6124 TREE_SIDE_EFFECTS (t) = 1;
6125 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6127 /* Find the register save area. */
6128 t = make_tree (TREE_TYPE (sav), virtual_incoming_args_rtx);
6129 t = build (PLUS_EXPR, TREE_TYPE (sav), t,
6130 build_int_2 (-STACK_POINTER_OFFSET, -1));
6131 t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
6132 TREE_SIDE_EFFECTS (t) = 1;
6133 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6136 /* Implement va_arg by updating the va_list structure
6137 VALIST as required to retrieve an argument of type
6138 TYPE, and returning that argument.
6140 Generates code equivalent to:
6142 if (integral value) {
6143 if (size <= 4 && args.gpr < 5 ||
6144 size > 4 && args.gpr < 4 )
6145 ret = args.reg_save_area[args.gpr+8]
6146 else
6147 ret = *args.overflow_arg_area++;
6148 } else if (float value) {
6149 if (args.fgpr < 2)
6150 ret = args.reg_save_area[args.fpr+64]
6151 else
6152 ret = *args.overflow_arg_area++;
6153 } else if (aggregate value) {
6154 if (args.gpr < 5)
6155 ret = *args.reg_save_area[args.gpr]
6156 else
6157 ret = **args.overflow_arg_area++;
6158 } */
6161 s390_va_arg (tree valist, tree type)
6163 tree f_gpr, f_fpr, f_ovf, f_sav;
6164 tree gpr, fpr, ovf, sav, reg, t, u;
6165 int indirect_p, size, n_reg, sav_ofs, sav_scale, max_reg;
6166 rtx lab_false, lab_over, addr_rtx, r;
6168 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
6169 f_fpr = TREE_CHAIN (f_gpr);
6170 f_ovf = TREE_CHAIN (f_fpr);
6171 f_sav = TREE_CHAIN (f_ovf);
6173 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
6174 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
6175 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
6176 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
6177 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
6179 size = int_size_in_bytes (type);
6181 if (s390_function_arg_pass_by_reference (TYPE_MODE (type), type))
6183 if (TARGET_DEBUG_ARG)
6185 fprintf (stderr, "va_arg: aggregate type");
6186 debug_tree (type);
6189 /* Aggregates are passed by reference. */
6190 indirect_p = 1;
6191 reg = gpr;
6192 n_reg = 1;
6193 sav_ofs = 2 * UNITS_PER_WORD;
6194 sav_scale = UNITS_PER_WORD;
6195 size = UNITS_PER_WORD;
6196 max_reg = 4;
6198 else if (s390_function_arg_float (TYPE_MODE (type), type))
6200 if (TARGET_DEBUG_ARG)
6202 fprintf (stderr, "va_arg: float type");
6203 debug_tree (type);
6206 /* FP args go in FP registers, if present. */
6207 indirect_p = 0;
6208 reg = fpr;
6209 n_reg = 1;
6210 sav_ofs = 16 * UNITS_PER_WORD;
6211 sav_scale = 8;
6212 /* TARGET_64BIT has up to 4 parameter in fprs */
6213 max_reg = TARGET_64BIT ? 3 : 1;
6215 else
6217 if (TARGET_DEBUG_ARG)
6219 fprintf (stderr, "va_arg: other type");
6220 debug_tree (type);
6223 /* Otherwise into GP registers. */
6224 indirect_p = 0;
6225 reg = gpr;
6226 n_reg = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6227 sav_ofs = 2 * UNITS_PER_WORD;
6229 if (size < UNITS_PER_WORD)
6230 sav_ofs += UNITS_PER_WORD - size;
6232 sav_scale = UNITS_PER_WORD;
6233 if (n_reg > 1)
6234 max_reg = 3;
6235 else
6236 max_reg = 4;
6239 /* Pull the value out of the saved registers ... */
6241 lab_false = gen_label_rtx ();
6242 lab_over = gen_label_rtx ();
6243 addr_rtx = gen_reg_rtx (Pmode);
6245 emit_cmp_and_jump_insns (expand_expr (reg, NULL_RTX, Pmode, EXPAND_NORMAL),
6246 GEN_INT (max_reg),
6247 GT, const1_rtx, Pmode, 0, lab_false);
6249 if (sav_ofs)
6250 t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
6251 else
6252 t = sav;
6254 u = build (MULT_EXPR, long_integer_type_node,
6255 reg, build_int_2 (sav_scale, 0));
6256 TREE_SIDE_EFFECTS (u) = 1;
6258 t = build (PLUS_EXPR, ptr_type_node, t, u);
6259 TREE_SIDE_EFFECTS (t) = 1;
6261 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
6262 if (r != addr_rtx)
6263 emit_move_insn (addr_rtx, r);
6266 emit_jump_insn (gen_jump (lab_over));
6267 emit_barrier ();
6268 emit_label (lab_false);
6270 /* ... Otherwise out of the overflow area. */
6272 t = save_expr (ovf);
6275 /* In 64 BIT for each argument on stack, a full 64 bit slot is allocated. */
6276 if (size < UNITS_PER_WORD)
6278 t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (UNITS_PER_WORD-size, 0));
6279 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
6280 TREE_SIDE_EFFECTS (t) = 1;
6281 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6283 t = save_expr (ovf);
6286 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
6287 if (r != addr_rtx)
6288 emit_move_insn (addr_rtx, r);
6290 t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (size, 0));
6291 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
6292 TREE_SIDE_EFFECTS (t) = 1;
6293 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6295 emit_label (lab_over);
6297 /* If less than max_regs a registers are retrieved out
6298 of register save area, increment. */
6300 u = build (PREINCREMENT_EXPR, TREE_TYPE (reg), reg,
6301 build_int_2 (n_reg, 0));
6302 TREE_SIDE_EFFECTS (u) = 1;
6303 expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
6305 if (indirect_p)
6307 r = gen_rtx_MEM (Pmode, addr_rtx);
6308 set_mem_alias_set (r, get_varargs_alias_set ());
6309 emit_move_insn (addr_rtx, r);
6313 return addr_rtx;
6317 /* Builtins. */
6319 enum s390_builtin
6321 S390_BUILTIN_THREAD_POINTER,
6322 S390_BUILTIN_SET_THREAD_POINTER,
6324 S390_BUILTIN_max
6327 static unsigned int const code_for_builtin_64[S390_BUILTIN_max] = {
6328 CODE_FOR_get_tp_64,
6329 CODE_FOR_set_tp_64
6332 static unsigned int const code_for_builtin_31[S390_BUILTIN_max] = {
6333 CODE_FOR_get_tp_31,
6334 CODE_FOR_set_tp_31
6337 static void
6338 s390_init_builtins (void)
6340 tree ftype;
6342 ftype = build_function_type (ptr_type_node, void_list_node);
6343 builtin_function ("__builtin_thread_pointer", ftype,
6344 S390_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
6345 NULL, NULL_TREE);
6347 ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
6348 builtin_function ("__builtin_set_thread_pointer", ftype,
6349 S390_BUILTIN_SET_THREAD_POINTER, BUILT_IN_MD,
6350 NULL, NULL_TREE);
6353 /* Expand an expression EXP that calls a built-in function,
6354 with result going to TARGET if that's convenient
6355 (and in mode MODE if that's convenient).
6356 SUBTARGET may be used as the target for computing one of EXP's operands.
6357 IGNORE is nonzero if the value is to be ignored. */
6359 static rtx
6360 s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
6361 enum machine_mode mode ATTRIBUTE_UNUSED,
6362 int ignore ATTRIBUTE_UNUSED)
6364 #define MAX_ARGS 2
6366 unsigned int const *code_for_builtin =
6367 TARGET_64BIT ? code_for_builtin_64 : code_for_builtin_31;
6369 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
6370 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
6371 tree arglist = TREE_OPERAND (exp, 1);
6372 enum insn_code icode;
6373 rtx op[MAX_ARGS], pat;
6374 int arity;
6375 bool nonvoid;
6377 if (fcode >= S390_BUILTIN_max)
6378 internal_error ("bad builtin fcode");
6379 icode = code_for_builtin[fcode];
6380 if (icode == 0)
6381 internal_error ("bad builtin fcode");
6383 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
6385 for (arglist = TREE_OPERAND (exp, 1), arity = 0;
6386 arglist;
6387 arglist = TREE_CHAIN (arglist), arity++)
6389 const struct insn_operand_data *insn_op;
6391 tree arg = TREE_VALUE (arglist);
6392 if (arg == error_mark_node)
6393 return NULL_RTX;
6394 if (arity > MAX_ARGS)
6395 return NULL_RTX;
6397 insn_op = &insn_data[icode].operand[arity + nonvoid];
6399 op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, 0);
6401 if (!(*insn_op->predicate) (op[arity], insn_op->mode))
6402 op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
6405 if (nonvoid)
6407 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6408 if (!target
6409 || GET_MODE (target) != tmode
6410 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
6411 target = gen_reg_rtx (tmode);
6414 switch (arity)
6416 case 0:
6417 pat = GEN_FCN (icode) (target);
6418 break;
6419 case 1:
6420 if (nonvoid)
6421 pat = GEN_FCN (icode) (target, op[0]);
6422 else
6423 pat = GEN_FCN (icode) (op[0]);
6424 break;
6425 case 2:
6426 pat = GEN_FCN (icode) (target, op[0], op[1]);
6427 break;
6428 default:
6429 abort ();
6431 if (!pat)
6432 return NULL_RTX;
6433 emit_insn (pat);
6435 if (nonvoid)
6436 return target;
6437 else
6438 return const0_rtx;
6442 /* Output assembly code for the trampoline template to
6443 stdio stream FILE.
6445 On S/390, we use gpr 1 internally in the trampoline code;
6446 gpr 0 is used to hold the static chain. */
6448 void
6449 s390_trampoline_template (FILE *file)
6451 if (TARGET_64BIT)
6453 fprintf (file, "larl\t%s,0f\n", reg_names[1]);
6454 fprintf (file, "lg\t%s,0(%s)\n", reg_names[0], reg_names[1]);
6455 fprintf (file, "lg\t%s,8(%s)\n", reg_names[1], reg_names[1]);
6456 fprintf (file, "br\t%s\n", reg_names[1]);
6457 fprintf (file, "0:\t.quad\t0\n");
6458 fprintf (file, ".quad\t0\n");
6460 else
6462 fprintf (file, "basr\t%s,0\n", reg_names[1]);
6463 fprintf (file, "l\t%s,10(%s)\n", reg_names[0], reg_names[1]);
6464 fprintf (file, "l\t%s,14(%s)\n", reg_names[1], reg_names[1]);
6465 fprintf (file, "br\t%s\n", reg_names[1]);
6466 fprintf (file, ".long\t0\n");
6467 fprintf (file, ".long\t0\n");
6471 /* Emit RTL insns to initialize the variable parts of a trampoline.
6472 FNADDR is an RTX for the address of the function's pure code.
6473 CXT is an RTX for the static chain value for the function. */
6475 void
6476 s390_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
6478 emit_move_insn (gen_rtx
6479 (MEM, Pmode,
6480 memory_address (Pmode,
6481 plus_constant (addr, (TARGET_64BIT ? 20 : 12) ))), cxt);
6482 emit_move_insn (gen_rtx
6483 (MEM, Pmode,
6484 memory_address (Pmode,
6485 plus_constant (addr, (TARGET_64BIT ? 28 : 16) ))), fnaddr);
6488 /* Return rtx for 64-bit constant formed from the 32-bit subwords
6489 LOW and HIGH, independent of the host word size. */
6492 s390_gen_rtx_const_DI (int high, int low)
6494 #if HOST_BITS_PER_WIDE_INT >= 64
6495 HOST_WIDE_INT val;
6496 val = (HOST_WIDE_INT)high;
6497 val <<= 32;
6498 val |= (HOST_WIDE_INT)low;
6500 return GEN_INT (val);
6501 #else
6502 #if HOST_BITS_PER_WIDE_INT >= 32
6503 return immed_double_const ((HOST_WIDE_INT)low, (HOST_WIDE_INT)high, DImode);
6504 #else
6505 abort ();
6506 #endif
6507 #endif
6510 /* Output assembler code to FILE to increment profiler label # LABELNO
6511 for profiling a function entry. */
6513 void
6514 s390_function_profiler (FILE *file, int labelno)
6516 rtx op[7];
6518 char label[128];
6519 ASM_GENERATE_INTERNAL_LABEL (label, "LP", labelno);
6521 fprintf (file, "# function profiler \n");
6523 op[0] = gen_rtx_REG (Pmode, RETURN_REGNUM);
6524 op[1] = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
6525 op[1] = gen_rtx_MEM (Pmode, plus_constant (op[1], UNITS_PER_WORD));
6527 op[2] = gen_rtx_REG (Pmode, 1);
6528 op[3] = gen_rtx_SYMBOL_REF (Pmode, label);
6529 SYMBOL_REF_FLAGS (op[3]) = SYMBOL_FLAG_LOCAL;
6531 op[4] = gen_rtx_SYMBOL_REF (Pmode, "_mcount");
6532 if (flag_pic)
6534 op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), UNSPEC_PLT);
6535 op[4] = gen_rtx_CONST (Pmode, op[4]);
6538 if (TARGET_64BIT)
6540 output_asm_insn ("stg\t%0,%1", op);
6541 output_asm_insn ("larl\t%2,%3", op);
6542 output_asm_insn ("brasl\t%0,%4", op);
6543 output_asm_insn ("lg\t%0,%1", op);
6545 else if (!flag_pic)
6547 op[6] = gen_label_rtx ();
6549 output_asm_insn ("st\t%0,%1", op);
6550 output_asm_insn ("bras\t%2,%l6", op);
6551 output_asm_insn (".long\t%4", op);
6552 output_asm_insn (".long\t%3", op);
6553 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
6554 output_asm_insn ("l\t%0,0(%2)", op);
6555 output_asm_insn ("l\t%2,4(%2)", op);
6556 output_asm_insn ("basr\t%0,%0", op);
6557 output_asm_insn ("l\t%0,%1", op);
6559 else
6561 op[5] = gen_label_rtx ();
6562 op[6] = gen_label_rtx ();
6564 output_asm_insn ("st\t%0,%1", op);
6565 output_asm_insn ("bras\t%2,%l6", op);
6566 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[5]));
6567 output_asm_insn (".long\t%4-%l5", op);
6568 output_asm_insn (".long\t%3-%l5", op);
6569 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
6570 output_asm_insn ("lr\t%0,%2", op);
6571 output_asm_insn ("a\t%0,0(%2)", op);
6572 output_asm_insn ("a\t%2,4(%2)", op);
6573 output_asm_insn ("basr\t%0,%0", op);
6574 output_asm_insn ("l\t%0,%1", op);
6578 /* Select section for constant in constant pool. In 32-bit mode,
6579 constants go in the function section; in 64-bit mode in .rodata. */
6581 static void
6582 s390_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED,
6583 rtx x ATTRIBUTE_UNUSED,
6584 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
6586 if (TARGET_CPU_ZARCH)
6587 readonly_data_section ();
6588 else
6589 function_section (current_function_decl);
6592 /* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
6593 into its SYMBOL_REF_FLAGS. */
6595 static void
6596 s390_encode_section_info (tree decl, rtx rtl, int first)
6598 default_encode_section_info (decl, rtl, first);
6600 /* If a variable has a forced alignment to < 2 bytes, mark it with
6601 SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL operand. */
6602 if (TREE_CODE (decl) == VAR_DECL
6603 && DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) < 16)
6604 SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_ALIGN1;
6607 /* Output thunk to FILE that implements a C++ virtual function call (with
6608 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
6609 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
6610 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
6611 relative to the resulting this pointer. */
6613 static void
6614 s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
6615 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
6616 tree function)
6618 rtx op[10];
6619 int nonlocal = 0;
6621 /* Operand 0 is the target function. */
6622 op[0] = XEXP (DECL_RTL (function), 0);
6623 if (flag_pic && !SYMBOL_REF_LOCAL_P (op[0]))
6625 nonlocal = 1;
6626 op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]),
6627 TARGET_64BIT ? UNSPEC_PLT : UNSPEC_GOT);
6628 op[0] = gen_rtx_CONST (Pmode, op[0]);
6631 /* Operand 1 is the 'this' pointer. */
6632 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
6633 op[1] = gen_rtx_REG (Pmode, 3);
6634 else
6635 op[1] = gen_rtx_REG (Pmode, 2);
6637 /* Operand 2 is the delta. */
6638 op[2] = GEN_INT (delta);
6640 /* Operand 3 is the vcall_offset. */
6641 op[3] = GEN_INT (vcall_offset);
6643 /* Operand 4 is the temporary register. */
6644 op[4] = gen_rtx_REG (Pmode, 1);
6646 /* Operands 5 to 8 can be used as labels. */
6647 op[5] = NULL_RTX;
6648 op[6] = NULL_RTX;
6649 op[7] = NULL_RTX;
6650 op[8] = NULL_RTX;
6652 /* Operand 9 can be used for temporary register. */
6653 op[9] = NULL_RTX;
6655 /* Generate code. */
6656 if (TARGET_64BIT)
6658 /* Setup literal pool pointer if required. */
6659 if ((!DISP_IN_RANGE (delta)
6660 && !CONST_OK_FOR_LETTER_P (delta, 'K'))
6661 || (!DISP_IN_RANGE (vcall_offset)
6662 && !CONST_OK_FOR_LETTER_P (vcall_offset, 'K')))
6664 op[5] = gen_label_rtx ();
6665 output_asm_insn ("larl\t%4,%5", op);
6668 /* Add DELTA to this pointer. */
6669 if (delta)
6671 if (CONST_OK_FOR_LETTER_P (delta, 'J'))
6672 output_asm_insn ("la\t%1,%2(%1)", op);
6673 else if (DISP_IN_RANGE (delta))
6674 output_asm_insn ("lay\t%1,%2(%1)", op);
6675 else if (CONST_OK_FOR_LETTER_P (delta, 'K'))
6676 output_asm_insn ("aghi\t%1,%2", op);
6677 else
6679 op[6] = gen_label_rtx ();
6680 output_asm_insn ("agf\t%1,%6-%5(%4)", op);
6684 /* Perform vcall adjustment. */
6685 if (vcall_offset)
6687 if (DISP_IN_RANGE (vcall_offset))
6689 output_asm_insn ("lg\t%4,0(%1)", op);
6690 output_asm_insn ("ag\t%1,%3(%4)", op);
6692 else if (CONST_OK_FOR_LETTER_P (vcall_offset, 'K'))
6694 output_asm_insn ("lghi\t%4,%3", op);
6695 output_asm_insn ("ag\t%4,0(%1)", op);
6696 output_asm_insn ("ag\t%1,0(%4)", op);
6698 else
6700 op[7] = gen_label_rtx ();
6701 output_asm_insn ("llgf\t%4,%7-%5(%4)", op);
6702 output_asm_insn ("ag\t%4,0(%1)", op);
6703 output_asm_insn ("ag\t%1,0(%4)", op);
6707 /* Jump to target. */
6708 output_asm_insn ("jg\t%0", op);
6710 /* Output literal pool if required. */
6711 if (op[5])
6713 output_asm_insn (".align\t4", op);
6714 targetm.asm_out.internal_label (file, "L",
6715 CODE_LABEL_NUMBER (op[5]));
6717 if (op[6])
6719 targetm.asm_out.internal_label (file, "L",
6720 CODE_LABEL_NUMBER (op[6]));
6721 output_asm_insn (".long\t%2", op);
6723 if (op[7])
6725 targetm.asm_out.internal_label (file, "L",
6726 CODE_LABEL_NUMBER (op[7]));
6727 output_asm_insn (".long\t%3", op);
6730 else
6732 /* Setup base pointer if required. */
6733 if (!vcall_offset
6734 || (!DISP_IN_RANGE (delta)
6735 && !CONST_OK_FOR_LETTER_P (delta, 'K'))
6736 || (!DISP_IN_RANGE (delta)
6737 && !CONST_OK_FOR_LETTER_P (vcall_offset, 'K')))
6739 op[5] = gen_label_rtx ();
6740 output_asm_insn ("basr\t%4,0", op);
6741 targetm.asm_out.internal_label (file, "L",
6742 CODE_LABEL_NUMBER (op[5]));
6745 /* Add DELTA to this pointer. */
6746 if (delta)
6748 if (CONST_OK_FOR_LETTER_P (delta, 'J'))
6749 output_asm_insn ("la\t%1,%2(%1)", op);
6750 else if (DISP_IN_RANGE (delta))
6751 output_asm_insn ("lay\t%1,%2(%1)", op);
6752 else if (CONST_OK_FOR_LETTER_P (delta, 'K'))
6753 output_asm_insn ("ahi\t%1,%2", op);
6754 else
6756 op[6] = gen_label_rtx ();
6757 output_asm_insn ("a\t%1,%6-%5(%4)", op);
6761 /* Perform vcall adjustment. */
6762 if (vcall_offset)
6764 if (CONST_OK_FOR_LETTER_P (vcall_offset, 'J'))
6766 output_asm_insn ("lg\t%4,0(%1)", op);
6767 output_asm_insn ("a\t%1,%3(%4)", op);
6769 else if (DISP_IN_RANGE (vcall_offset))
6771 output_asm_insn ("lg\t%4,0(%1)", op);
6772 output_asm_insn ("ay\t%1,%3(%4)", op);
6774 else if (CONST_OK_FOR_LETTER_P (vcall_offset, 'K'))
6776 output_asm_insn ("lhi\t%4,%3", op);
6777 output_asm_insn ("a\t%4,0(%1)", op);
6778 output_asm_insn ("a\t%1,0(%4)", op);
6780 else
6782 op[7] = gen_label_rtx ();
6783 output_asm_insn ("l\t%4,%7-%5(%4)", op);
6784 output_asm_insn ("a\t%4,0(%1)", op);
6785 output_asm_insn ("a\t%1,0(%4)", op);
6788 /* We had to clobber the base pointer register.
6789 Re-setup the base pointer (with a different base). */
6790 op[5] = gen_label_rtx ();
6791 output_asm_insn ("basr\t%4,0", op);
6792 targetm.asm_out.internal_label (file, "L",
6793 CODE_LABEL_NUMBER (op[5]));
6796 /* Jump to target. */
6797 op[8] = gen_label_rtx ();
6799 if (!flag_pic)
6800 output_asm_insn ("l\t%4,%8-%5(%4)", op);
6801 else if (!nonlocal)
6802 output_asm_insn ("a\t%4,%8-%5(%4)", op);
6803 /* We cannot call through .plt, since .plt requires %r12 loaded. */
6804 else if (flag_pic == 1)
6806 output_asm_insn ("a\t%4,%8-%5(%4)", op);
6807 output_asm_insn ("l\t%4,%0(%4)", op);
6809 else if (flag_pic == 2)
6811 op[9] = gen_rtx_REG (Pmode, 0);
6812 output_asm_insn ("l\t%9,%8-4-%5(%4)", op);
6813 output_asm_insn ("a\t%4,%8-%5(%4)", op);
6814 output_asm_insn ("ar\t%4,%9", op);
6815 output_asm_insn ("l\t%4,0(%4)", op);
6818 output_asm_insn ("br\t%4", op);
6820 /* Output literal pool. */
6821 output_asm_insn (".align\t4", op);
6823 if (nonlocal && flag_pic == 2)
6824 output_asm_insn (".long\t%0", op);
6825 if (nonlocal)
6827 op[0] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6828 SYMBOL_REF_FLAGS (op[0]) = SYMBOL_FLAG_LOCAL;
6831 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[8]));
6832 if (!flag_pic)
6833 output_asm_insn (".long\t%0", op);
6834 else
6835 output_asm_insn (".long\t%0-%5", op);
6837 if (op[6])
6839 targetm.asm_out.internal_label (file, "L",
6840 CODE_LABEL_NUMBER (op[6]));
6841 output_asm_insn (".long\t%2", op);
6843 if (op[7])
6845 targetm.asm_out.internal_label (file, "L",
6846 CODE_LABEL_NUMBER (op[7]));
6847 output_asm_insn (".long\t%3", op);
6852 bool
6853 s390_valid_pointer_mode (enum machine_mode mode)
6855 return (mode == SImode || (TARGET_64BIT && mode == DImode));
6858 /* How to allocate a 'struct machine_function'. */
6860 static struct machine_function *
6861 s390_init_machine_status (void)
6863 return ggc_alloc_cleared (sizeof (struct machine_function));
6866 #include "gt-s390.h"